apps,nesemu2: remove most libc calls and run on x86-nemu and mips32-nemu
* riscv32-nemu needs __clzsi2() and __ctzsi2() to run * there is still a render bug for x86-nemu
This commit is contained in:
parent
0e56568ad0
commit
1e85b4390c
|
@ -20,15 +20,17 @@ for (root, dirs, files) in os.walk('gen'):
|
|||
def h_file():
|
||||
for name in roms:
|
||||
yield 'extern unsigned char rom_%s_nes[];' % (name)
|
||||
yield 'extern unsigned int rom_%s_nes_len;' % (name)
|
||||
yield '''
|
||||
struct rom {
|
||||
const char *name;
|
||||
void *body;
|
||||
unsigned int *size;
|
||||
};
|
||||
|
||||
struct rom roms[] = {'''
|
||||
for name in roms:
|
||||
yield ' { .name = "%s", .body = rom_%s_nes, },' % (name, name)
|
||||
yield ' { .name = "%s", .body = rom_%s_nes, .size = &rom_%s_nes_len, },' % (name, name, name)
|
||||
yield '};'
|
||||
|
||||
yield 'int nroms = %d;' % (len(roms))
|
||||
|
|
|
@ -1,6 +1,9 @@
|
|||
NAME := nesemu2
|
||||
SRCS := $(shell find -L ./src/ -name "*.c")
|
||||
|
||||
CFLAGS += -DCPU_UNDOC -DQUICK_SPRITES -DSDL -DLINUX -DRELEASE -Isrc
|
||||
CFLAGS += -DCPU_UNDOC -DQUICK_SPRITES -DSDL -DLINUX -DRELEASE -DNO_FILE_SYSTEM -Isrc
|
||||
|
||||
include $(AM_HOME)/Makefile.app
|
||||
|
||||
.PHONY: rom
|
||||
rom:
|
||||
@cd src/roms && python3 build-roms.py
|
||||
|
|
|
@ -18,9 +18,11 @@
|
|||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
|
||||
***************************************************************************/
|
||||
|
||||
#include "cartdb/cartdb.h"
|
||||
|
||||
#if 0
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
#include "cartdb/cartdb.h"
|
||||
#include "cartdb/parser.h"
|
||||
#include "misc/memutil.h"
|
||||
#include "misc/strutil.h"
|
||||
|
@ -31,7 +33,6 @@
|
|||
#include "mappers/mapperid.h"
|
||||
|
||||
static xml_t *cartxml = 0;
|
||||
|
||||
int cartdb_init()
|
||||
{
|
||||
char filename[1024];
|
||||
|
@ -500,3 +501,8 @@ int cartdb_find(cart_t *cart)
|
|||
log_printf("cartdb_find: cart not found in database.\n");
|
||||
return(1);
|
||||
}
|
||||
#endif
|
||||
|
||||
int cartdb_init() { return 0; }
|
||||
void cartdb_kill() { }
|
||||
int cartdb_find(cart_t *cart) { return 1; }
|
||||
|
|
|
@ -1,92 +0,0 @@
|
|||
/* Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd
|
||||
See the file COPYING for copying permission.
|
||||
*/
|
||||
|
||||
#define ASCII_A 0x41
|
||||
#define ASCII_B 0x42
|
||||
#define ASCII_C 0x43
|
||||
#define ASCII_D 0x44
|
||||
#define ASCII_E 0x45
|
||||
#define ASCII_F 0x46
|
||||
#define ASCII_G 0x47
|
||||
#define ASCII_H 0x48
|
||||
#define ASCII_I 0x49
|
||||
#define ASCII_J 0x4A
|
||||
#define ASCII_K 0x4B
|
||||
#define ASCII_L 0x4C
|
||||
#define ASCII_M 0x4D
|
||||
#define ASCII_N 0x4E
|
||||
#define ASCII_O 0x4F
|
||||
#define ASCII_P 0x50
|
||||
#define ASCII_Q 0x51
|
||||
#define ASCII_R 0x52
|
||||
#define ASCII_S 0x53
|
||||
#define ASCII_T 0x54
|
||||
#define ASCII_U 0x55
|
||||
#define ASCII_V 0x56
|
||||
#define ASCII_W 0x57
|
||||
#define ASCII_X 0x58
|
||||
#define ASCII_Y 0x59
|
||||
#define ASCII_Z 0x5A
|
||||
|
||||
#define ASCII_a 0x61
|
||||
#define ASCII_b 0x62
|
||||
#define ASCII_c 0x63
|
||||
#define ASCII_d 0x64
|
||||
#define ASCII_e 0x65
|
||||
#define ASCII_f 0x66
|
||||
#define ASCII_g 0x67
|
||||
#define ASCII_h 0x68
|
||||
#define ASCII_i 0x69
|
||||
#define ASCII_j 0x6A
|
||||
#define ASCII_k 0x6B
|
||||
#define ASCII_l 0x6C
|
||||
#define ASCII_m 0x6D
|
||||
#define ASCII_n 0x6E
|
||||
#define ASCII_o 0x6F
|
||||
#define ASCII_p 0x70
|
||||
#define ASCII_q 0x71
|
||||
#define ASCII_r 0x72
|
||||
#define ASCII_s 0x73
|
||||
#define ASCII_t 0x74
|
||||
#define ASCII_u 0x75
|
||||
#define ASCII_v 0x76
|
||||
#define ASCII_w 0x77
|
||||
#define ASCII_x 0x78
|
||||
#define ASCII_y 0x79
|
||||
#define ASCII_z 0x7A
|
||||
|
||||
#define ASCII_0 0x30
|
||||
#define ASCII_1 0x31
|
||||
#define ASCII_2 0x32
|
||||
#define ASCII_3 0x33
|
||||
#define ASCII_4 0x34
|
||||
#define ASCII_5 0x35
|
||||
#define ASCII_6 0x36
|
||||
#define ASCII_7 0x37
|
||||
#define ASCII_8 0x38
|
||||
#define ASCII_9 0x39
|
||||
|
||||
#define ASCII_TAB 0x09
|
||||
#define ASCII_SPACE 0x20
|
||||
#define ASCII_EXCL 0x21
|
||||
#define ASCII_QUOT 0x22
|
||||
#define ASCII_AMP 0x26
|
||||
#define ASCII_APOS 0x27
|
||||
#define ASCII_MINUS 0x2D
|
||||
#define ASCII_PERIOD 0x2E
|
||||
#define ASCII_COLON 0x3A
|
||||
#define ASCII_SEMI 0x3B
|
||||
#define ASCII_LT 0x3C
|
||||
#define ASCII_EQUALS 0x3D
|
||||
#define ASCII_GT 0x3E
|
||||
#define ASCII_LSQB 0x5B
|
||||
#define ASCII_RSQB 0x5D
|
||||
#define ASCII_UNDERSCORE 0x5F
|
||||
#define ASCII_LPAREN 0x28
|
||||
#define ASCII_RPAREN 0x29
|
||||
#define ASCII_FF 0x0C
|
||||
#define ASCII_SLASH 0x2F
|
||||
#define ASCII_HASH 0x23
|
||||
#define ASCII_PIPE 0x7C
|
||||
#define ASCII_COMMA 0x2C
|
|
@ -1,36 +0,0 @@
|
|||
/* Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd
|
||||
See the file COPYING for copying permission.
|
||||
*/
|
||||
|
||||
/* 0x00 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML,
|
||||
/* 0x04 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML,
|
||||
/* 0x08 */ BT_NONXML, BT_S, BT_LF, BT_NONXML,
|
||||
/* 0x0C */ BT_NONXML, BT_CR, BT_NONXML, BT_NONXML,
|
||||
/* 0x10 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML,
|
||||
/* 0x14 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML,
|
||||
/* 0x18 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML,
|
||||
/* 0x1C */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML,
|
||||
/* 0x20 */ BT_S, BT_EXCL, BT_QUOT, BT_NUM,
|
||||
/* 0x24 */ BT_OTHER, BT_PERCNT, BT_AMP, BT_APOS,
|
||||
/* 0x28 */ BT_LPAR, BT_RPAR, BT_AST, BT_PLUS,
|
||||
/* 0x2C */ BT_COMMA, BT_MINUS, BT_NAME, BT_SOL,
|
||||
/* 0x30 */ BT_DIGIT, BT_DIGIT, BT_DIGIT, BT_DIGIT,
|
||||
/* 0x34 */ BT_DIGIT, BT_DIGIT, BT_DIGIT, BT_DIGIT,
|
||||
/* 0x38 */ BT_DIGIT, BT_DIGIT, BT_COLON, BT_SEMI,
|
||||
/* 0x3C */ BT_LT, BT_EQUALS, BT_GT, BT_QUEST,
|
||||
/* 0x40 */ BT_OTHER, BT_HEX, BT_HEX, BT_HEX,
|
||||
/* 0x44 */ BT_HEX, BT_HEX, BT_HEX, BT_NMSTRT,
|
||||
/* 0x48 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
|
||||
/* 0x4C */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
|
||||
/* 0x50 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
|
||||
/* 0x54 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
|
||||
/* 0x58 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_LSQB,
|
||||
/* 0x5C */ BT_OTHER, BT_RSQB, BT_OTHER, BT_NMSTRT,
|
||||
/* 0x60 */ BT_OTHER, BT_HEX, BT_HEX, BT_HEX,
|
||||
/* 0x64 */ BT_HEX, BT_HEX, BT_HEX, BT_NMSTRT,
|
||||
/* 0x68 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
|
||||
/* 0x6C */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
|
||||
/* 0x70 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
|
||||
/* 0x74 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
|
||||
/* 0x78 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_OTHER,
|
||||
/* 0x7C */ BT_VERBAR, BT_OTHER, BT_OTHER, BT_OTHER,
|
File diff suppressed because it is too large
Load Diff
|
@ -1,115 +0,0 @@
|
|||
/* Copyright (c) 1998, 1999, 2000 Thai Open Source Software Center Ltd
|
||||
See the file COPYING for copying permission.
|
||||
*/
|
||||
|
||||
#ifndef Expat_External_INCLUDED
|
||||
#define Expat_External_INCLUDED 1
|
||||
|
||||
/* External API definitions */
|
||||
|
||||
#if defined(_MSC_EXTENSIONS) && !defined(__BEOS__) && !defined(__CYGWIN__)
|
||||
#define XML_USE_MSC_EXTENSIONS 1
|
||||
#endif
|
||||
|
||||
/* Expat tries very hard to make the API boundary very specifically
|
||||
defined. There are two macros defined to control this boundary;
|
||||
each of these can be defined before including this header to
|
||||
achieve some different behavior, but doing so it not recommended or
|
||||
tested frequently.
|
||||
|
||||
XMLCALL - The calling convention to use for all calls across the
|
||||
"library boundary." This will default to cdecl, and
|
||||
try really hard to tell the compiler that's what we
|
||||
want.
|
||||
|
||||
XMLIMPORT - Whatever magic is needed to note that a function is
|
||||
to be imported from a dynamically loaded library
|
||||
(.dll, .so, or .sl, depending on your platform).
|
||||
|
||||
The XMLCALL macro was added in Expat 1.95.7. The only one which is
|
||||
expected to be directly useful in client code is XMLCALL.
|
||||
|
||||
Note that on at least some Unix versions, the Expat library must be
|
||||
compiled with the cdecl calling convention as the default since
|
||||
system headers may assume the cdecl convention.
|
||||
*/
|
||||
#ifndef XMLCALL
|
||||
#if defined(_MSC_VER)
|
||||
#define XMLCALL __cdecl
|
||||
#elif defined(__GNUC__) && defined(__i386) && !defined(__INTEL_COMPILER)
|
||||
#define XMLCALL __attribute__((cdecl))
|
||||
#else
|
||||
/* For any platform which uses this definition and supports more than
|
||||
one calling convention, we need to extend this definition to
|
||||
declare the convention used on that platform, if it's possible to
|
||||
do so.
|
||||
|
||||
If this is the case for your platform, please file a bug report
|
||||
with information on how to identify your platform via the C
|
||||
pre-processor and how to specify the same calling convention as the
|
||||
platform's malloc() implementation.
|
||||
*/
|
||||
#define XMLCALL
|
||||
#endif
|
||||
#endif /* not defined XMLCALL */
|
||||
|
||||
|
||||
#if !defined(XML_STATIC) && !defined(XMLIMPORT)
|
||||
#ifndef XML_BUILDING_EXPAT
|
||||
/* using Expat from an application */
|
||||
|
||||
#ifdef XML_USE_MSC_EXTENSIONS
|
||||
#define XMLIMPORT __declspec(dllimport)
|
||||
#endif
|
||||
|
||||
#endif
|
||||
#endif /* not defined XML_STATIC */
|
||||
|
||||
|
||||
/* If we didn't define it above, define it away: */
|
||||
#ifndef XMLIMPORT
|
||||
#define XMLIMPORT
|
||||
#endif
|
||||
|
||||
|
||||
#define XMLPARSEAPI(type) XMLIMPORT type XMLCALL
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifdef XML_UNICODE_WCHAR_T
|
||||
#define XML_UNICODE
|
||||
#endif
|
||||
|
||||
#ifdef XML_UNICODE /* Information is UTF-16 encoded. */
|
||||
#ifdef XML_UNICODE_WCHAR_T
|
||||
typedef wchar_t XML_Char;
|
||||
typedef wchar_t XML_LChar;
|
||||
#else
|
||||
typedef unsigned short XML_Char;
|
||||
typedef char XML_LChar;
|
||||
#endif /* XML_UNICODE_WCHAR_T */
|
||||
#else /* Information is UTF-8 encoded. */
|
||||
typedef char XML_Char;
|
||||
typedef char XML_LChar;
|
||||
#endif /* XML_UNICODE */
|
||||
|
||||
#ifdef XML_LARGE_SIZE /* Use large integers for file/stream positions. */
|
||||
#if defined(XML_USE_MSC_EXTENSIONS) && _MSC_VER < 1400
|
||||
typedef __int64 XML_Index;
|
||||
typedef unsigned __int64 XML_Size;
|
||||
#else
|
||||
typedef long long XML_Index;
|
||||
typedef unsigned long long XML_Size;
|
||||
#endif
|
||||
#else
|
||||
typedef long XML_Index;
|
||||
typedef unsigned long XML_Size;
|
||||
#endif /* XML_LARGE_SIZE */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* not Expat_External_INCLUDED */
|
|
@ -1,37 +0,0 @@
|
|||
/* Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd
|
||||
See the file COPYING for copying permission.
|
||||
*/
|
||||
|
||||
/* Like asciitab.h, except that 0xD has code BT_S rather than BT_CR */
|
||||
/* 0x00 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML,
|
||||
/* 0x04 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML,
|
||||
/* 0x08 */ BT_NONXML, BT_S, BT_LF, BT_NONXML,
|
||||
/* 0x0C */ BT_NONXML, BT_S, BT_NONXML, BT_NONXML,
|
||||
/* 0x10 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML,
|
||||
/* 0x14 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML,
|
||||
/* 0x18 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML,
|
||||
/* 0x1C */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML,
|
||||
/* 0x20 */ BT_S, BT_EXCL, BT_QUOT, BT_NUM,
|
||||
/* 0x24 */ BT_OTHER, BT_PERCNT, BT_AMP, BT_APOS,
|
||||
/* 0x28 */ BT_LPAR, BT_RPAR, BT_AST, BT_PLUS,
|
||||
/* 0x2C */ BT_COMMA, BT_MINUS, BT_NAME, BT_SOL,
|
||||
/* 0x30 */ BT_DIGIT, BT_DIGIT, BT_DIGIT, BT_DIGIT,
|
||||
/* 0x34 */ BT_DIGIT, BT_DIGIT, BT_DIGIT, BT_DIGIT,
|
||||
/* 0x38 */ BT_DIGIT, BT_DIGIT, BT_COLON, BT_SEMI,
|
||||
/* 0x3C */ BT_LT, BT_EQUALS, BT_GT, BT_QUEST,
|
||||
/* 0x40 */ BT_OTHER, BT_HEX, BT_HEX, BT_HEX,
|
||||
/* 0x44 */ BT_HEX, BT_HEX, BT_HEX, BT_NMSTRT,
|
||||
/* 0x48 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
|
||||
/* 0x4C */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
|
||||
/* 0x50 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
|
||||
/* 0x54 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
|
||||
/* 0x58 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_LSQB,
|
||||
/* 0x5C */ BT_OTHER, BT_RSQB, BT_OTHER, BT_NMSTRT,
|
||||
/* 0x60 */ BT_OTHER, BT_HEX, BT_HEX, BT_HEX,
|
||||
/* 0x64 */ BT_HEX, BT_HEX, BT_HEX, BT_NMSTRT,
|
||||
/* 0x68 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
|
||||
/* 0x6C */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
|
||||
/* 0x70 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
|
||||
/* 0x74 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
|
||||
/* 0x78 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_OTHER,
|
||||
/* 0x7C */ BT_VERBAR, BT_OTHER, BT_OTHER, BT_OTHER,
|
|
@ -1,19 +0,0 @@
|
|||
#ifndef INTCONFIG_H
|
||||
#define INTCONFIG_H
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#define XML_NS 1
|
||||
#define XML_DTD 1
|
||||
#define XML_CONTEXT_BYTES 1024
|
||||
|
||||
#ifdef USE_LSB
|
||||
#define BYTEORDER 1234
|
||||
#else
|
||||
#define BYTEORDER 4321
|
||||
#endif
|
||||
|
||||
#define HAVE_MEMMOVE
|
||||
|
||||
#endif
|
|
@ -1,73 +0,0 @@
|
|||
/* internal.h
|
||||
|
||||
Internal definitions used by Expat. This is not needed to compile
|
||||
client code.
|
||||
|
||||
The following calling convention macros are defined for frequently
|
||||
called functions:
|
||||
|
||||
FASTCALL - Used for those internal functions that have a simple
|
||||
body and a low number of arguments and local variables.
|
||||
|
||||
PTRCALL - Used for functions called though function pointers.
|
||||
|
||||
PTRFASTCALL - Like PTRCALL, but for low number of arguments.
|
||||
|
||||
inline - Used for selected internal functions for which inlining
|
||||
may improve performance on some platforms.
|
||||
|
||||
Note: Use of these macros is based on judgement, not hard rules,
|
||||
and therefore subject to change.
|
||||
*/
|
||||
|
||||
#if defined(__GNUC__) && defined(__i386__) && !defined(__MINGW32__)
|
||||
/* We'll use this version by default only where we know it helps.
|
||||
|
||||
regparm() generates warnings on Solaris boxes. See SF bug #692878.
|
||||
|
||||
Instability reported with egcs on a RedHat Linux 7.3.
|
||||
Let's comment out:
|
||||
#define FASTCALL __attribute__((stdcall, regparm(3)))
|
||||
and let's try this:
|
||||
*/
|
||||
#define FASTCALL __attribute__((regparm(3)))
|
||||
#define PTRFASTCALL __attribute__((regparm(3)))
|
||||
#endif
|
||||
|
||||
/* Using __fastcall seems to have an unexpected negative effect under
|
||||
MS VC++, especially for function pointers, so we won't use it for
|
||||
now on that platform. It may be reconsidered for a future release
|
||||
if it can be made more effective.
|
||||
Likely reason: __fastcall on Windows is like stdcall, therefore
|
||||
the compiler cannot perform stack optimizations for call clusters.
|
||||
*/
|
||||
|
||||
/* Make sure all of these are defined if they aren't already. */
|
||||
|
||||
#ifndef FASTCALL
|
||||
#define FASTCALL
|
||||
#endif
|
||||
|
||||
#ifndef PTRCALL
|
||||
#define PTRCALL
|
||||
#endif
|
||||
|
||||
#ifndef PTRFASTCALL
|
||||
#define PTRFASTCALL
|
||||
#endif
|
||||
|
||||
#ifndef XML_MIN_SIZE
|
||||
#if !defined(__cplusplus) && !defined(inline)
|
||||
#ifdef __GNUC__
|
||||
#define inline __inline
|
||||
#endif /* __GNUC__ */
|
||||
#endif
|
||||
#endif /* XML_MIN_SIZE */
|
||||
|
||||
#ifdef __cplusplus
|
||||
#define inline inline
|
||||
#else
|
||||
#ifndef inline
|
||||
#define inline
|
||||
#endif
|
||||
#endif
|
|
@ -1,36 +0,0 @@
|
|||
/* Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd
|
||||
See the file COPYING for copying permission.
|
||||
*/
|
||||
|
||||
/* 0x80 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER,
|
||||
/* 0x84 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER,
|
||||
/* 0x88 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER,
|
||||
/* 0x8C */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER,
|
||||
/* 0x90 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER,
|
||||
/* 0x94 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER,
|
||||
/* 0x98 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER,
|
||||
/* 0x9C */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER,
|
||||
/* 0xA0 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER,
|
||||
/* 0xA4 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER,
|
||||
/* 0xA8 */ BT_OTHER, BT_OTHER, BT_NMSTRT, BT_OTHER,
|
||||
/* 0xAC */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER,
|
||||
/* 0xB0 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER,
|
||||
/* 0xB4 */ BT_OTHER, BT_NMSTRT, BT_OTHER, BT_NAME,
|
||||
/* 0xB8 */ BT_OTHER, BT_OTHER, BT_NMSTRT, BT_OTHER,
|
||||
/* 0xBC */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER,
|
||||
/* 0xC0 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
|
||||
/* 0xC4 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
|
||||
/* 0xC8 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
|
||||
/* 0xCC */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
|
||||
/* 0xD0 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
|
||||
/* 0xD4 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_OTHER,
|
||||
/* 0xD8 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
|
||||
/* 0xDC */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
|
||||
/* 0xE0 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
|
||||
/* 0xE4 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
|
||||
/* 0xE8 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
|
||||
/* 0xEC */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
|
||||
/* 0xF0 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
|
||||
/* 0xF4 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_OTHER,
|
||||
/* 0xF8 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
|
||||
/* 0xFC */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
|
|
@ -1,150 +0,0 @@
|
|||
static const unsigned namingBitmap[] = {
|
||||
0x00000000, 0x00000000, 0x00000000, 0x00000000,
|
||||
0x00000000, 0x00000000, 0x00000000, 0x00000000,
|
||||
0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
|
||||
0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
|
||||
0x00000000, 0x04000000, 0x87FFFFFE, 0x07FFFFFE,
|
||||
0x00000000, 0x00000000, 0xFF7FFFFF, 0xFF7FFFFF,
|
||||
0xFFFFFFFF, 0x7FF3FFFF, 0xFFFFFDFE, 0x7FFFFFFF,
|
||||
0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFE00F, 0xFC31FFFF,
|
||||
0x00FFFFFF, 0x00000000, 0xFFFF0000, 0xFFFFFFFF,
|
||||
0xFFFFFFFF, 0xF80001FF, 0x00000003, 0x00000000,
|
||||
0x00000000, 0x00000000, 0x00000000, 0x00000000,
|
||||
0xFFFFD740, 0xFFFFFFFB, 0x547F7FFF, 0x000FFFFD,
|
||||
0xFFFFDFFE, 0xFFFFFFFF, 0xDFFEFFFF, 0xFFFFFFFF,
|
||||
0xFFFF0003, 0xFFFFFFFF, 0xFFFF199F, 0x033FCFFF,
|
||||
0x00000000, 0xFFFE0000, 0x027FFFFF, 0xFFFFFFFE,
|
||||
0x0000007F, 0x00000000, 0xFFFF0000, 0x000707FF,
|
||||
0x00000000, 0x07FFFFFE, 0x000007FE, 0xFFFE0000,
|
||||
0xFFFFFFFF, 0x7CFFFFFF, 0x002F7FFF, 0x00000060,
|
||||
0xFFFFFFE0, 0x23FFFFFF, 0xFF000000, 0x00000003,
|
||||
0xFFF99FE0, 0x03C5FDFF, 0xB0000000, 0x00030003,
|
||||
0xFFF987E0, 0x036DFDFF, 0x5E000000, 0x001C0000,
|
||||
0xFFFBAFE0, 0x23EDFDFF, 0x00000000, 0x00000001,
|
||||
0xFFF99FE0, 0x23CDFDFF, 0xB0000000, 0x00000003,
|
||||
0xD63DC7E0, 0x03BFC718, 0x00000000, 0x00000000,
|
||||
0xFFFDDFE0, 0x03EFFDFF, 0x00000000, 0x00000003,
|
||||
0xFFFDDFE0, 0x03EFFDFF, 0x40000000, 0x00000003,
|
||||
0xFFFDDFE0, 0x03FFFDFF, 0x00000000, 0x00000003,
|
||||
0x00000000, 0x00000000, 0x00000000, 0x00000000,
|
||||
0xFFFFFFFE, 0x000D7FFF, 0x0000003F, 0x00000000,
|
||||
0xFEF02596, 0x200D6CAE, 0x0000001F, 0x00000000,
|
||||
0x00000000, 0x00000000, 0xFFFFFEFF, 0x000003FF,
|
||||
0x00000000, 0x00000000, 0x00000000, 0x00000000,
|
||||
0x00000000, 0x00000000, 0x00000000, 0x00000000,
|
||||
0x00000000, 0xFFFFFFFF, 0xFFFF003F, 0x007FFFFF,
|
||||
0x0007DAED, 0x50000000, 0x82315001, 0x002C62AB,
|
||||
0x40000000, 0xF580C900, 0x00000007, 0x02010800,
|
||||
0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
|
||||
0x0FFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x03FFFFFF,
|
||||
0x3F3FFFFF, 0xFFFFFFFF, 0xAAFF3F3F, 0x3FFFFFFF,
|
||||
0xFFFFFFFF, 0x5FDFFFFF, 0x0FCF1FDC, 0x1FDC1FFF,
|
||||
0x00000000, 0x00004C40, 0x00000000, 0x00000000,
|
||||
0x00000007, 0x00000000, 0x00000000, 0x00000000,
|
||||
0x00000080, 0x000003FE, 0xFFFFFFFE, 0xFFFFFFFF,
|
||||
0x001FFFFF, 0xFFFFFFFE, 0xFFFFFFFF, 0x07FFFFFF,
|
||||
0xFFFFFFE0, 0x00001FFF, 0x00000000, 0x00000000,
|
||||
0x00000000, 0x00000000, 0x00000000, 0x00000000,
|
||||
0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
|
||||
0xFFFFFFFF, 0x0000003F, 0x00000000, 0x00000000,
|
||||
0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
|
||||
0xFFFFFFFF, 0x0000000F, 0x00000000, 0x00000000,
|
||||
0x00000000, 0x07FF6000, 0x87FFFFFE, 0x07FFFFFE,
|
||||
0x00000000, 0x00800000, 0xFF7FFFFF, 0xFF7FFFFF,
|
||||
0x00FFFFFF, 0x00000000, 0xFFFF0000, 0xFFFFFFFF,
|
||||
0xFFFFFFFF, 0xF80001FF, 0x00030003, 0x00000000,
|
||||
0xFFFFFFFF, 0xFFFFFFFF, 0x0000003F, 0x00000003,
|
||||
0xFFFFD7C0, 0xFFFFFFFB, 0x547F7FFF, 0x000FFFFD,
|
||||
0xFFFFDFFE, 0xFFFFFFFF, 0xDFFEFFFF, 0xFFFFFFFF,
|
||||
0xFFFF007B, 0xFFFFFFFF, 0xFFFF199F, 0x033FCFFF,
|
||||
0x00000000, 0xFFFE0000, 0x027FFFFF, 0xFFFFFFFE,
|
||||
0xFFFE007F, 0xBBFFFFFB, 0xFFFF0016, 0x000707FF,
|
||||
0x00000000, 0x07FFFFFE, 0x0007FFFF, 0xFFFF03FF,
|
||||
0xFFFFFFFF, 0x7CFFFFFF, 0xFFEF7FFF, 0x03FF3DFF,
|
||||
0xFFFFFFEE, 0xF3FFFFFF, 0xFF1E3FFF, 0x0000FFCF,
|
||||
0xFFF99FEE, 0xD3C5FDFF, 0xB080399F, 0x0003FFCF,
|
||||
0xFFF987E4, 0xD36DFDFF, 0x5E003987, 0x001FFFC0,
|
||||
0xFFFBAFEE, 0xF3EDFDFF, 0x00003BBF, 0x0000FFC1,
|
||||
0xFFF99FEE, 0xF3CDFDFF, 0xB0C0398F, 0x0000FFC3,
|
||||
0xD63DC7EC, 0xC3BFC718, 0x00803DC7, 0x0000FF80,
|
||||
0xFFFDDFEE, 0xC3EFFDFF, 0x00603DDF, 0x0000FFC3,
|
||||
0xFFFDDFEC, 0xC3EFFDFF, 0x40603DDF, 0x0000FFC3,
|
||||
0xFFFDDFEC, 0xC3FFFDFF, 0x00803DCF, 0x0000FFC3,
|
||||
0x00000000, 0x00000000, 0x00000000, 0x00000000,
|
||||
0xFFFFFFFE, 0x07FF7FFF, 0x03FF7FFF, 0x00000000,
|
||||
0xFEF02596, 0x3BFF6CAE, 0x03FF3F5F, 0x00000000,
|
||||
0x03000000, 0xC2A003FF, 0xFFFFFEFF, 0xFFFE03FF,
|
||||
0xFEBF0FDF, 0x02FE3FFF, 0x00000000, 0x00000000,
|
||||
0x00000000, 0x00000000, 0x00000000, 0x00000000,
|
||||
0x00000000, 0x00000000, 0x1FFF0000, 0x00000002,
|
||||
0x000000A0, 0x003EFFFE, 0xFFFFFFFE, 0xFFFFFFFF,
|
||||
0x661FFFFF, 0xFFFFFFFE, 0xFFFFFFFF, 0x77FFFFFF,
|
||||
};
|
||||
static const unsigned char nmstrtPages[] = {
|
||||
0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x00,
|
||||
0x00, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
|
||||
0x10, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x13,
|
||||
0x00, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x15, 0x16, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01,
|
||||
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
|
||||
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
|
||||
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
|
||||
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
|
||||
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
|
||||
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
|
||||
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
|
||||
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
|
||||
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
|
||||
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x17,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01,
|
||||
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
|
||||
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
|
||||
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
|
||||
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
|
||||
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x18,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
};
|
||||
static const unsigned char namePages[] = {
|
||||
0x19, 0x03, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x00,
|
||||
0x00, 0x1F, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25,
|
||||
0x10, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x13,
|
||||
0x26, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x27, 0x16, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01,
|
||||
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
|
||||
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
|
||||
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
|
||||
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
|
||||
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
|
||||
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
|
||||
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
|
||||
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
|
||||
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
|
||||
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x17,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01,
|
||||
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
|
||||
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
|
||||
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
|
||||
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
|
||||
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x18,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
};
|
|
@ -1,37 +0,0 @@
|
|||
/* Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd
|
||||
See the file COPYING for copying permission.
|
||||
*/
|
||||
|
||||
|
||||
/* 0x80 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
|
||||
/* 0x84 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
|
||||
/* 0x88 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
|
||||
/* 0x8C */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
|
||||
/* 0x90 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
|
||||
/* 0x94 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
|
||||
/* 0x98 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
|
||||
/* 0x9C */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
|
||||
/* 0xA0 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
|
||||
/* 0xA4 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
|
||||
/* 0xA8 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
|
||||
/* 0xAC */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
|
||||
/* 0xB0 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
|
||||
/* 0xB4 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
|
||||
/* 0xB8 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
|
||||
/* 0xBC */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
|
||||
/* 0xC0 */ BT_LEAD2, BT_LEAD2, BT_LEAD2, BT_LEAD2,
|
||||
/* 0xC4 */ BT_LEAD2, BT_LEAD2, BT_LEAD2, BT_LEAD2,
|
||||
/* 0xC8 */ BT_LEAD2, BT_LEAD2, BT_LEAD2, BT_LEAD2,
|
||||
/* 0xCC */ BT_LEAD2, BT_LEAD2, BT_LEAD2, BT_LEAD2,
|
||||
/* 0xD0 */ BT_LEAD2, BT_LEAD2, BT_LEAD2, BT_LEAD2,
|
||||
/* 0xD4 */ BT_LEAD2, BT_LEAD2, BT_LEAD2, BT_LEAD2,
|
||||
/* 0xD8 */ BT_LEAD2, BT_LEAD2, BT_LEAD2, BT_LEAD2,
|
||||
/* 0xDC */ BT_LEAD2, BT_LEAD2, BT_LEAD2, BT_LEAD2,
|
||||
/* 0xE0 */ BT_LEAD3, BT_LEAD3, BT_LEAD3, BT_LEAD3,
|
||||
/* 0xE4 */ BT_LEAD3, BT_LEAD3, BT_LEAD3, BT_LEAD3,
|
||||
/* 0xE8 */ BT_LEAD3, BT_LEAD3, BT_LEAD3, BT_LEAD3,
|
||||
/* 0xEC */ BT_LEAD3, BT_LEAD3, BT_LEAD3, BT_LEAD3,
|
||||
/* 0xF0 */ BT_LEAD4, BT_LEAD4, BT_LEAD4, BT_LEAD4,
|
||||
/* 0xF4 */ BT_LEAD4, BT_NONXML, BT_NONXML, BT_NONXML,
|
||||
/* 0xF8 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML,
|
||||
/* 0xFC */ BT_NONXML, BT_NONXML, BT_MALFORM, BT_MALFORM,
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -1,114 +0,0 @@
|
|||
/* Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd
|
||||
See the file COPYING for copying permission.
|
||||
*/
|
||||
|
||||
#ifndef XmlRole_INCLUDED
|
||||
#define XmlRole_INCLUDED 1
|
||||
|
||||
#ifdef __VMS
|
||||
/* 0 1 2 3 0 1 2 3
|
||||
1234567890123456789012345678901 1234567890123456789012345678901 */
|
||||
#define XmlPrologStateInitExternalEntity XmlPrologStateInitExternalEnt
|
||||
#endif
|
||||
|
||||
#include "xmltok.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
enum {
|
||||
XML_ROLE_ERROR = -1,
|
||||
XML_ROLE_NONE = 0,
|
||||
XML_ROLE_XML_DECL,
|
||||
XML_ROLE_INSTANCE_START,
|
||||
XML_ROLE_DOCTYPE_NONE,
|
||||
XML_ROLE_DOCTYPE_NAME,
|
||||
XML_ROLE_DOCTYPE_SYSTEM_ID,
|
||||
XML_ROLE_DOCTYPE_PUBLIC_ID,
|
||||
XML_ROLE_DOCTYPE_INTERNAL_SUBSET,
|
||||
XML_ROLE_DOCTYPE_CLOSE,
|
||||
XML_ROLE_GENERAL_ENTITY_NAME,
|
||||
XML_ROLE_PARAM_ENTITY_NAME,
|
||||
XML_ROLE_ENTITY_NONE,
|
||||
XML_ROLE_ENTITY_VALUE,
|
||||
XML_ROLE_ENTITY_SYSTEM_ID,
|
||||
XML_ROLE_ENTITY_PUBLIC_ID,
|
||||
XML_ROLE_ENTITY_COMPLETE,
|
||||
XML_ROLE_ENTITY_NOTATION_NAME,
|
||||
XML_ROLE_NOTATION_NONE,
|
||||
XML_ROLE_NOTATION_NAME,
|
||||
XML_ROLE_NOTATION_SYSTEM_ID,
|
||||
XML_ROLE_NOTATION_NO_SYSTEM_ID,
|
||||
XML_ROLE_NOTATION_PUBLIC_ID,
|
||||
XML_ROLE_ATTRIBUTE_NAME,
|
||||
XML_ROLE_ATTRIBUTE_TYPE_CDATA,
|
||||
XML_ROLE_ATTRIBUTE_TYPE_ID,
|
||||
XML_ROLE_ATTRIBUTE_TYPE_IDREF,
|
||||
XML_ROLE_ATTRIBUTE_TYPE_IDREFS,
|
||||
XML_ROLE_ATTRIBUTE_TYPE_ENTITY,
|
||||
XML_ROLE_ATTRIBUTE_TYPE_ENTITIES,
|
||||
XML_ROLE_ATTRIBUTE_TYPE_NMTOKEN,
|
||||
XML_ROLE_ATTRIBUTE_TYPE_NMTOKENS,
|
||||
XML_ROLE_ATTRIBUTE_ENUM_VALUE,
|
||||
XML_ROLE_ATTRIBUTE_NOTATION_VALUE,
|
||||
XML_ROLE_ATTLIST_NONE,
|
||||
XML_ROLE_ATTLIST_ELEMENT_NAME,
|
||||
XML_ROLE_IMPLIED_ATTRIBUTE_VALUE,
|
||||
XML_ROLE_REQUIRED_ATTRIBUTE_VALUE,
|
||||
XML_ROLE_DEFAULT_ATTRIBUTE_VALUE,
|
||||
XML_ROLE_FIXED_ATTRIBUTE_VALUE,
|
||||
XML_ROLE_ELEMENT_NONE,
|
||||
XML_ROLE_ELEMENT_NAME,
|
||||
XML_ROLE_CONTENT_ANY,
|
||||
XML_ROLE_CONTENT_EMPTY,
|
||||
XML_ROLE_CONTENT_PCDATA,
|
||||
XML_ROLE_GROUP_OPEN,
|
||||
XML_ROLE_GROUP_CLOSE,
|
||||
XML_ROLE_GROUP_CLOSE_REP,
|
||||
XML_ROLE_GROUP_CLOSE_OPT,
|
||||
XML_ROLE_GROUP_CLOSE_PLUS,
|
||||
XML_ROLE_GROUP_CHOICE,
|
||||
XML_ROLE_GROUP_SEQUENCE,
|
||||
XML_ROLE_CONTENT_ELEMENT,
|
||||
XML_ROLE_CONTENT_ELEMENT_REP,
|
||||
XML_ROLE_CONTENT_ELEMENT_OPT,
|
||||
XML_ROLE_CONTENT_ELEMENT_PLUS,
|
||||
XML_ROLE_PI,
|
||||
XML_ROLE_COMMENT,
|
||||
#ifdef XML_DTD
|
||||
XML_ROLE_TEXT_DECL,
|
||||
XML_ROLE_IGNORE_SECT,
|
||||
XML_ROLE_INNER_PARAM_ENTITY_REF,
|
||||
#endif /* XML_DTD */
|
||||
XML_ROLE_PARAM_ENTITY_REF
|
||||
};
|
||||
|
||||
typedef struct prolog_state {
|
||||
int (PTRCALL *handler) (struct prolog_state *state,
|
||||
int tok,
|
||||
const char *ptr,
|
||||
const char *end,
|
||||
const ENCODING *enc);
|
||||
unsigned level;
|
||||
int role_none;
|
||||
#ifdef XML_DTD
|
||||
unsigned includeLevel;
|
||||
int documentEntity;
|
||||
int inEntityValue;
|
||||
#endif /* XML_DTD */
|
||||
} PROLOG_STATE;
|
||||
|
||||
void XmlPrologStateInit(PROLOG_STATE *);
|
||||
#ifdef XML_DTD
|
||||
void XmlPrologStateInitExternalEntity(PROLOG_STATE *);
|
||||
#endif /* XML_DTD */
|
||||
|
||||
#define XmlTokenRole(state, tok, ptr, end, enc) \
|
||||
(((state)->handler)(state, tok, ptr, end, enc))
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* not XmlRole_INCLUDED */
|
File diff suppressed because it is too large
Load Diff
|
@ -1,316 +0,0 @@
|
|||
/* Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd
|
||||
See the file COPYING for copying permission.
|
||||
*/
|
||||
|
||||
#ifndef XmlTok_INCLUDED
|
||||
#define XmlTok_INCLUDED 1
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* The following token may be returned by XmlContentTok */
|
||||
#define XML_TOK_TRAILING_RSQB -5 /* ] or ]] at the end of the scan; might be
|
||||
start of illegal ]]> sequence */
|
||||
/* The following tokens may be returned by both XmlPrologTok and
|
||||
XmlContentTok.
|
||||
*/
|
||||
#define XML_TOK_NONE -4 /* The string to be scanned is empty */
|
||||
#define XML_TOK_TRAILING_CR -3 /* A CR at the end of the scan;
|
||||
might be part of CRLF sequence */
|
||||
#define XML_TOK_PARTIAL_CHAR -2 /* only part of a multibyte sequence */
|
||||
#define XML_TOK_PARTIAL -1 /* only part of a token */
|
||||
#define XML_TOK_INVALID 0
|
||||
|
||||
/* The following tokens are returned by XmlContentTok; some are also
|
||||
returned by XmlAttributeValueTok, XmlEntityTok, XmlCdataSectionTok.
|
||||
*/
|
||||
#define XML_TOK_START_TAG_WITH_ATTS 1
|
||||
#define XML_TOK_START_TAG_NO_ATTS 2
|
||||
#define XML_TOK_EMPTY_ELEMENT_WITH_ATTS 3 /* empty element tag <e/> */
|
||||
#define XML_TOK_EMPTY_ELEMENT_NO_ATTS 4
|
||||
#define XML_TOK_END_TAG 5
|
||||
#define XML_TOK_DATA_CHARS 6
|
||||
#define XML_TOK_DATA_NEWLINE 7
|
||||
#define XML_TOK_CDATA_SECT_OPEN 8
|
||||
#define XML_TOK_ENTITY_REF 9
|
||||
#define XML_TOK_CHAR_REF 10 /* numeric character reference */
|
||||
|
||||
/* The following tokens may be returned by both XmlPrologTok and
|
||||
XmlContentTok.
|
||||
*/
|
||||
#define XML_TOK_PI 11 /* processing instruction */
|
||||
#define XML_TOK_XML_DECL 12 /* XML decl or text decl */
|
||||
#define XML_TOK_COMMENT 13
|
||||
#define XML_TOK_BOM 14 /* Byte order mark */
|
||||
|
||||
/* The following tokens are returned only by XmlPrologTok */
|
||||
#define XML_TOK_PROLOG_S 15
|
||||
#define XML_TOK_DECL_OPEN 16 /* <!foo */
|
||||
#define XML_TOK_DECL_CLOSE 17 /* > */
|
||||
#define XML_TOK_NAME 18
|
||||
#define XML_TOK_NMTOKEN 19
|
||||
#define XML_TOK_POUND_NAME 20 /* #name */
|
||||
#define XML_TOK_OR 21 /* | */
|
||||
#define XML_TOK_PERCENT 22
|
||||
#define XML_TOK_OPEN_PAREN 23
|
||||
#define XML_TOK_CLOSE_PAREN 24
|
||||
#define XML_TOK_OPEN_BRACKET 25
|
||||
#define XML_TOK_CLOSE_BRACKET 26
|
||||
#define XML_TOK_LITERAL 27
|
||||
#define XML_TOK_PARAM_ENTITY_REF 28
|
||||
#define XML_TOK_INSTANCE_START 29
|
||||
|
||||
/* The following occur only in element type declarations */
|
||||
#define XML_TOK_NAME_QUESTION 30 /* name? */
|
||||
#define XML_TOK_NAME_ASTERISK 31 /* name* */
|
||||
#define XML_TOK_NAME_PLUS 32 /* name+ */
|
||||
#define XML_TOK_COND_SECT_OPEN 33 /* <![ */
|
||||
#define XML_TOK_COND_SECT_CLOSE 34 /* ]]> */
|
||||
#define XML_TOK_CLOSE_PAREN_QUESTION 35 /* )? */
|
||||
#define XML_TOK_CLOSE_PAREN_ASTERISK 36 /* )* */
|
||||
#define XML_TOK_CLOSE_PAREN_PLUS 37 /* )+ */
|
||||
#define XML_TOK_COMMA 38
|
||||
|
||||
/* The following token is returned only by XmlAttributeValueTok */
|
||||
#define XML_TOK_ATTRIBUTE_VALUE_S 39
|
||||
|
||||
/* The following token is returned only by XmlCdataSectionTok */
|
||||
#define XML_TOK_CDATA_SECT_CLOSE 40
|
||||
|
||||
/* With namespace processing this is returned by XmlPrologTok for a
|
||||
name with a colon.
|
||||
*/
|
||||
#define XML_TOK_PREFIXED_NAME 41
|
||||
|
||||
#ifdef XML_DTD
|
||||
#define XML_TOK_IGNORE_SECT 42
|
||||
#endif /* XML_DTD */
|
||||
|
||||
#ifdef XML_DTD
|
||||
#define XML_N_STATES 4
|
||||
#else /* not XML_DTD */
|
||||
#define XML_N_STATES 3
|
||||
#endif /* not XML_DTD */
|
||||
|
||||
#define XML_PROLOG_STATE 0
|
||||
#define XML_CONTENT_STATE 1
|
||||
#define XML_CDATA_SECTION_STATE 2
|
||||
#ifdef XML_DTD
|
||||
#define XML_IGNORE_SECTION_STATE 3
|
||||
#endif /* XML_DTD */
|
||||
|
||||
#define XML_N_LITERAL_TYPES 2
|
||||
#define XML_ATTRIBUTE_VALUE_LITERAL 0
|
||||
#define XML_ENTITY_VALUE_LITERAL 1
|
||||
|
||||
/* The size of the buffer passed to XmlUtf8Encode must be at least this. */
|
||||
#define XML_UTF8_ENCODE_MAX 4
|
||||
/* The size of the buffer passed to XmlUtf16Encode must be at least this. */
|
||||
#define XML_UTF16_ENCODE_MAX 2
|
||||
|
||||
typedef struct position {
|
||||
/* first line and first column are 0 not 1 */
|
||||
XML_Size lineNumber;
|
||||
XML_Size columnNumber;
|
||||
} POSITION;
|
||||
|
||||
typedef struct {
|
||||
const char *name;
|
||||
const char *valuePtr;
|
||||
const char *valueEnd;
|
||||
char normalized;
|
||||
} ATTRIBUTE;
|
||||
|
||||
struct encoding;
|
||||
typedef struct encoding ENCODING;
|
||||
|
||||
typedef int (PTRCALL *SCANNER)(const ENCODING *,
|
||||
const char *,
|
||||
const char *,
|
||||
const char **);
|
||||
|
||||
struct encoding {
|
||||
SCANNER scanners[XML_N_STATES];
|
||||
SCANNER literalScanners[XML_N_LITERAL_TYPES];
|
||||
int (PTRCALL *sameName)(const ENCODING *,
|
||||
const char *,
|
||||
const char *);
|
||||
int (PTRCALL *nameMatchesAscii)(const ENCODING *,
|
||||
const char *,
|
||||
const char *,
|
||||
const char *);
|
||||
int (PTRFASTCALL *nameLength)(const ENCODING *, const char *);
|
||||
const char *(PTRFASTCALL *skipS)(const ENCODING *, const char *);
|
||||
int (PTRCALL *getAtts)(const ENCODING *enc,
|
||||
const char *ptr,
|
||||
int attsMax,
|
||||
ATTRIBUTE *atts);
|
||||
int (PTRFASTCALL *charRefNumber)(const ENCODING *enc, const char *ptr);
|
||||
int (PTRCALL *predefinedEntityName)(const ENCODING *,
|
||||
const char *,
|
||||
const char *);
|
||||
void (PTRCALL *updatePosition)(const ENCODING *,
|
||||
const char *ptr,
|
||||
const char *end,
|
||||
POSITION *);
|
||||
int (PTRCALL *isPublicId)(const ENCODING *enc,
|
||||
const char *ptr,
|
||||
const char *end,
|
||||
const char **badPtr);
|
||||
void (PTRCALL *utf8Convert)(const ENCODING *enc,
|
||||
const char **fromP,
|
||||
const char *fromLim,
|
||||
char **toP,
|
||||
const char *toLim);
|
||||
void (PTRCALL *utf16Convert)(const ENCODING *enc,
|
||||
const char **fromP,
|
||||
const char *fromLim,
|
||||
unsigned short **toP,
|
||||
const unsigned short *toLim);
|
||||
int minBytesPerChar;
|
||||
char isUtf8;
|
||||
char isUtf16;
|
||||
};
|
||||
|
||||
/* Scan the string starting at ptr until the end of the next complete
|
||||
token, but do not scan past eptr. Return an integer giving the
|
||||
type of token.
|
||||
|
||||
Return XML_TOK_NONE when ptr == eptr; nextTokPtr will not be set.
|
||||
|
||||
Return XML_TOK_PARTIAL when the string does not contain a complete
|
||||
token; nextTokPtr will not be set.
|
||||
|
||||
Return XML_TOK_INVALID when the string does not start a valid
|
||||
token; nextTokPtr will be set to point to the character which made
|
||||
the token invalid.
|
||||
|
||||
Otherwise the string starts with a valid token; nextTokPtr will be
|
||||
set to point to the character following the end of that token.
|
||||
|
||||
Each data character counts as a single token, but adjacent data
|
||||
characters may be returned together. Similarly for characters in
|
||||
the prolog outside literals, comments and processing instructions.
|
||||
*/
|
||||
|
||||
|
||||
#define XmlTok(enc, state, ptr, end, nextTokPtr) \
|
||||
(((enc)->scanners[state])(enc, ptr, end, nextTokPtr))
|
||||
|
||||
#define XmlPrologTok(enc, ptr, end, nextTokPtr) \
|
||||
XmlTok(enc, XML_PROLOG_STATE, ptr, end, nextTokPtr)
|
||||
|
||||
#define XmlContentTok(enc, ptr, end, nextTokPtr) \
|
||||
XmlTok(enc, XML_CONTENT_STATE, ptr, end, nextTokPtr)
|
||||
|
||||
#define XmlCdataSectionTok(enc, ptr, end, nextTokPtr) \
|
||||
XmlTok(enc, XML_CDATA_SECTION_STATE, ptr, end, nextTokPtr)
|
||||
|
||||
#ifdef XML_DTD
|
||||
|
||||
#define XmlIgnoreSectionTok(enc, ptr, end, nextTokPtr) \
|
||||
XmlTok(enc, XML_IGNORE_SECTION_STATE, ptr, end, nextTokPtr)
|
||||
|
||||
#endif /* XML_DTD */
|
||||
|
||||
/* This is used for performing a 2nd-level tokenization on the content
|
||||
of a literal that has already been returned by XmlTok.
|
||||
*/
|
||||
#define XmlLiteralTok(enc, literalType, ptr, end, nextTokPtr) \
|
||||
(((enc)->literalScanners[literalType])(enc, ptr, end, nextTokPtr))
|
||||
|
||||
#define XmlAttributeValueTok(enc, ptr, end, nextTokPtr) \
|
||||
XmlLiteralTok(enc, XML_ATTRIBUTE_VALUE_LITERAL, ptr, end, nextTokPtr)
|
||||
|
||||
#define XmlEntityValueTok(enc, ptr, end, nextTokPtr) \
|
||||
XmlLiteralTok(enc, XML_ENTITY_VALUE_LITERAL, ptr, end, nextTokPtr)
|
||||
|
||||
#define XmlSameName(enc, ptr1, ptr2) (((enc)->sameName)(enc, ptr1, ptr2))
|
||||
|
||||
#define XmlNameMatchesAscii(enc, ptr1, end1, ptr2) \
|
||||
(((enc)->nameMatchesAscii)(enc, ptr1, end1, ptr2))
|
||||
|
||||
#define XmlNameLength(enc, ptr) \
|
||||
(((enc)->nameLength)(enc, ptr))
|
||||
|
||||
#define XmlSkipS(enc, ptr) \
|
||||
(((enc)->skipS)(enc, ptr))
|
||||
|
||||
#define XmlGetAttributes(enc, ptr, attsMax, atts) \
|
||||
(((enc)->getAtts)(enc, ptr, attsMax, atts))
|
||||
|
||||
#define XmlCharRefNumber(enc, ptr) \
|
||||
(((enc)->charRefNumber)(enc, ptr))
|
||||
|
||||
#define XmlPredefinedEntityName(enc, ptr, end) \
|
||||
(((enc)->predefinedEntityName)(enc, ptr, end))
|
||||
|
||||
#define XmlUpdatePosition(enc, ptr, end, pos) \
|
||||
(((enc)->updatePosition)(enc, ptr, end, pos))
|
||||
|
||||
#define XmlIsPublicId(enc, ptr, end, badPtr) \
|
||||
(((enc)->isPublicId)(enc, ptr, end, badPtr))
|
||||
|
||||
#define XmlUtf8Convert(enc, fromP, fromLim, toP, toLim) \
|
||||
(((enc)->utf8Convert)(enc, fromP, fromLim, toP, toLim))
|
||||
|
||||
#define XmlUtf16Convert(enc, fromP, fromLim, toP, toLim) \
|
||||
(((enc)->utf16Convert)(enc, fromP, fromLim, toP, toLim))
|
||||
|
||||
typedef struct {
|
||||
ENCODING initEnc;
|
||||
const ENCODING **encPtr;
|
||||
} INIT_ENCODING;
|
||||
|
||||
int XmlParseXmlDecl(int isGeneralTextEntity,
|
||||
const ENCODING *enc,
|
||||
const char *ptr,
|
||||
const char *end,
|
||||
const char **badPtr,
|
||||
const char **versionPtr,
|
||||
const char **versionEndPtr,
|
||||
const char **encodingNamePtr,
|
||||
const ENCODING **namedEncodingPtr,
|
||||
int *standalonePtr);
|
||||
|
||||
int XmlInitEncoding(INIT_ENCODING *, const ENCODING **, const char *name);
|
||||
const ENCODING *XmlGetUtf8InternalEncoding(void);
|
||||
const ENCODING *XmlGetUtf16InternalEncoding(void);
|
||||
int FASTCALL XmlUtf8Encode(int charNumber, char *buf);
|
||||
int FASTCALL XmlUtf16Encode(int charNumber, unsigned short *buf);
|
||||
int XmlSizeOfUnknownEncoding(void);
|
||||
|
||||
|
||||
typedef int (XMLCALL *CONVERTER) (void *userData, const char *p);
|
||||
|
||||
ENCODING *
|
||||
XmlInitUnknownEncoding(void *mem,
|
||||
int *table,
|
||||
CONVERTER convert,
|
||||
void *userData);
|
||||
|
||||
int XmlParseXmlDeclNS(int isGeneralTextEntity,
|
||||
const ENCODING *enc,
|
||||
const char *ptr,
|
||||
const char *end,
|
||||
const char **badPtr,
|
||||
const char **versionPtr,
|
||||
const char **versionEndPtr,
|
||||
const char **encodingNamePtr,
|
||||
const ENCODING **namedEncodingPtr,
|
||||
int *standalonePtr);
|
||||
|
||||
int XmlInitEncodingNS(INIT_ENCODING *, const ENCODING **, const char *name);
|
||||
const ENCODING *XmlGetUtf8InternalEncodingNS(void);
|
||||
const ENCODING *XmlGetUtf16InternalEncodingNS(void);
|
||||
ENCODING *
|
||||
XmlInitUnknownEncodingNS(void *mem,
|
||||
int *table,
|
||||
CONVERTER convert,
|
||||
void *userData);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* not XmlTok_INCLUDED */
|
File diff suppressed because it is too large
Load Diff
|
@ -1,46 +0,0 @@
|
|||
/*
|
||||
Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd
|
||||
See the file COPYING for copying permission.
|
||||
*/
|
||||
|
||||
enum {
|
||||
BT_NONXML,
|
||||
BT_MALFORM,
|
||||
BT_LT,
|
||||
BT_AMP,
|
||||
BT_RSQB,
|
||||
BT_LEAD2,
|
||||
BT_LEAD3,
|
||||
BT_LEAD4,
|
||||
BT_TRAIL,
|
||||
BT_CR,
|
||||
BT_LF,
|
||||
BT_GT,
|
||||
BT_QUOT,
|
||||
BT_APOS,
|
||||
BT_EQUALS,
|
||||
BT_QUEST,
|
||||
BT_EXCL,
|
||||
BT_SOL,
|
||||
BT_SEMI,
|
||||
BT_NUM,
|
||||
BT_LSQB,
|
||||
BT_S,
|
||||
BT_NMSTRT,
|
||||
BT_COLON,
|
||||
BT_HEX,
|
||||
BT_DIGIT,
|
||||
BT_NAME,
|
||||
BT_MINUS,
|
||||
BT_OTHER, /* known not to be a name or name start character */
|
||||
BT_NONASCII, /* might be a name or name start character */
|
||||
BT_PERCNT,
|
||||
BT_LPAR,
|
||||
BT_RPAR,
|
||||
BT_AST,
|
||||
BT_PLUS,
|
||||
BT_COMMA,
|
||||
BT_VERBAR
|
||||
};
|
||||
|
||||
#include <stddef.h>
|
|
@ -1,115 +0,0 @@
|
|||
/* Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd
|
||||
See the file COPYING for copying permission.
|
||||
*/
|
||||
|
||||
/* This file is included! */
|
||||
#ifdef XML_TOK_NS_C
|
||||
|
||||
const ENCODING *
|
||||
NS(XmlGetUtf8InternalEncoding)(void)
|
||||
{
|
||||
return &ns(internal_utf8_encoding).enc;
|
||||
}
|
||||
|
||||
const ENCODING *
|
||||
NS(XmlGetUtf16InternalEncoding)(void)
|
||||
{
|
||||
#if BYTEORDER == 1234
|
||||
return &ns(internal_little2_encoding).enc;
|
||||
#elif BYTEORDER == 4321
|
||||
return &ns(internal_big2_encoding).enc;
|
||||
#else
|
||||
const short n = 1;
|
||||
return (*(const char *)&n
|
||||
? &ns(internal_little2_encoding).enc
|
||||
: &ns(internal_big2_encoding).enc);
|
||||
#endif
|
||||
}
|
||||
|
||||
static const ENCODING * const NS(encodings)[] = {
|
||||
&ns(latin1_encoding).enc,
|
||||
&ns(ascii_encoding).enc,
|
||||
&ns(utf8_encoding).enc,
|
||||
&ns(big2_encoding).enc,
|
||||
&ns(big2_encoding).enc,
|
||||
&ns(little2_encoding).enc,
|
||||
&ns(utf8_encoding).enc /* NO_ENC */
|
||||
};
|
||||
|
||||
static int PTRCALL
|
||||
NS(initScanProlog)(const ENCODING *enc, const char *ptr, const char *end,
|
||||
const char **nextTokPtr)
|
||||
{
|
||||
return initScan(NS(encodings), (const INIT_ENCODING *)enc,
|
||||
XML_PROLOG_STATE, ptr, end, nextTokPtr);
|
||||
}
|
||||
|
||||
static int PTRCALL
|
||||
NS(initScanContent)(const ENCODING *enc, const char *ptr, const char *end,
|
||||
const char **nextTokPtr)
|
||||
{
|
||||
return initScan(NS(encodings), (const INIT_ENCODING *)enc,
|
||||
XML_CONTENT_STATE, ptr, end, nextTokPtr);
|
||||
}
|
||||
|
||||
int
|
||||
NS(XmlInitEncoding)(INIT_ENCODING *p, const ENCODING **encPtr,
|
||||
const char *name)
|
||||
{
|
||||
int i = getEncodingIndex(name);
|
||||
if (i == UNKNOWN_ENC)
|
||||
return 0;
|
||||
SET_INIT_ENC_INDEX(p, i);
|
||||
p->initEnc.scanners[XML_PROLOG_STATE] = NS(initScanProlog);
|
||||
p->initEnc.scanners[XML_CONTENT_STATE] = NS(initScanContent);
|
||||
p->initEnc.updatePosition = initUpdatePosition;
|
||||
p->encPtr = encPtr;
|
||||
*encPtr = &(p->initEnc);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static const ENCODING *
|
||||
NS(findEncoding)(const ENCODING *enc, const char *ptr, const char *end)
|
||||
{
|
||||
#define ENCODING_MAX 128
|
||||
char buf[ENCODING_MAX];
|
||||
char *p = buf;
|
||||
int i;
|
||||
XmlUtf8Convert(enc, &ptr, end, &p, p + ENCODING_MAX - 1);
|
||||
if (ptr != end)
|
||||
return 0;
|
||||
*p = 0;
|
||||
if (streqci(buf, KW_UTF_16) && enc->minBytesPerChar == 2)
|
||||
return enc;
|
||||
i = getEncodingIndex(buf);
|
||||
if (i == UNKNOWN_ENC)
|
||||
return 0;
|
||||
return NS(encodings)[i];
|
||||
}
|
||||
|
||||
int
|
||||
NS(XmlParseXmlDecl)(int isGeneralTextEntity,
|
||||
const ENCODING *enc,
|
||||
const char *ptr,
|
||||
const char *end,
|
||||
const char **badPtr,
|
||||
const char **versionPtr,
|
||||
const char **versionEndPtr,
|
||||
const char **encodingName,
|
||||
const ENCODING **encoding,
|
||||
int *standalone)
|
||||
{
|
||||
return doParseXmlDecl(NS(findEncoding),
|
||||
isGeneralTextEntity,
|
||||
enc,
|
||||
ptr,
|
||||
end,
|
||||
badPtr,
|
||||
versionPtr,
|
||||
versionEndPtr,
|
||||
encodingName,
|
||||
encoding,
|
||||
standalone);
|
||||
}
|
||||
|
||||
#endif /* XML_TOK_NS_C */
|
|
@ -1,313 +0,0 @@
|
|||
/***************************************************************************
|
||||
* Copyright (C) 2013 by James Holodnak *
|
||||
* jamesholodnak@gmail.com *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with this program; if not, write to the *
|
||||
* Free Software Foundation, Inc., *
|
||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
|
||||
***************************************************************************/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "cartdb/parser.h"
|
||||
#include "misc/log.h"
|
||||
|
||||
#define BUFSIZE 4096
|
||||
|
||||
static int num_malloc = 0;
|
||||
static int num_malloc_str = 0;
|
||||
static int num_malloc_node = 0;
|
||||
static int num_malloc_attr = 0;
|
||||
static int num_free = 0;
|
||||
static int num_free_str = 0;
|
||||
static int num_free_node = 0;
|
||||
static int num_free_attr = 0;
|
||||
size_t num_bytes = 0;
|
||||
|
||||
void *mem_malloc(size_t sz)
|
||||
{
|
||||
num_malloc++;
|
||||
num_bytes += sz;
|
||||
return(malloc(sz));
|
||||
}
|
||||
|
||||
void *mem_malloc_str(size_t sz)
|
||||
{
|
||||
num_malloc_str++;
|
||||
return(mem_malloc(sz));
|
||||
}
|
||||
|
||||
void *mem_malloc_node(size_t sz)
|
||||
{
|
||||
num_malloc_node++;
|
||||
return(mem_malloc(sz));
|
||||
}
|
||||
|
||||
void *mem_malloc_attr(size_t sz)
|
||||
{
|
||||
num_malloc_attr++;
|
||||
return(mem_malloc(sz));
|
||||
}
|
||||
|
||||
void mem_free(void *ptr)
|
||||
{
|
||||
num_free++;
|
||||
free(ptr);
|
||||
}
|
||||
|
||||
void mem_free_str(void *ptr)
|
||||
{
|
||||
num_free_str++;
|
||||
mem_free(ptr);
|
||||
}
|
||||
|
||||
void mem_free_node(void *ptr)
|
||||
{
|
||||
num_free_node++;
|
||||
mem_free(ptr);
|
||||
}
|
||||
|
||||
void mem_free_attr(void *ptr)
|
||||
{
|
||||
num_free_attr++;
|
||||
mem_free(ptr);
|
||||
}
|
||||
|
||||
static char *copystr(const char *str)
|
||||
{
|
||||
char *ret;
|
||||
size_t sz;
|
||||
|
||||
sz = strlen(str);
|
||||
ret = mem_malloc_str(sz + 1);
|
||||
memset(ret,0,sz + 1);
|
||||
memcpy(ret,str,sz);
|
||||
return(ret);
|
||||
}
|
||||
|
||||
static node_t *create_node(const char *name)
|
||||
{
|
||||
node_t *ret = 0;
|
||||
|
||||
ret = (node_t*)mem_malloc_node(sizeof(node_t));
|
||||
memset(ret,0,sizeof(node_t));
|
||||
ret->name = copystr(name);
|
||||
return(ret);
|
||||
}
|
||||
|
||||
static attribute_t *create_attribute(const char *name,const char *data)
|
||||
{
|
||||
attribute_t *ret = 0;
|
||||
|
||||
ret = (attribute_t*)mem_malloc_attr(sizeof(attribute_t));
|
||||
memset(ret,0,sizeof(attribute_t));
|
||||
ret->name = copystr(name);
|
||||
ret->data = copystr(data);
|
||||
return(ret);
|
||||
}
|
||||
|
||||
static void destroy_node(node_t *node)
|
||||
{
|
||||
mem_free_str(node->name);
|
||||
mem_free_node(node);
|
||||
}
|
||||
|
||||
static void destroy_attribute(attribute_t *attr)
|
||||
{
|
||||
mem_free_str(attr->name);
|
||||
mem_free_str(attr->data);
|
||||
mem_free_attr(attr);
|
||||
}
|
||||
|
||||
static node_t *add_child(node_t *parent,const char *name)
|
||||
{
|
||||
node_t *ret = 0;
|
||||
node_t *node;
|
||||
|
||||
ret = create_node(name);
|
||||
ret->parent = parent;
|
||||
if(parent->child == 0) {
|
||||
parent->child = ret;
|
||||
}
|
||||
else {
|
||||
node = parent->child;
|
||||
while(node->next) {
|
||||
node = node->next;
|
||||
}
|
||||
node->next = ret;
|
||||
}
|
||||
return(ret);
|
||||
}
|
||||
|
||||
static void free_attributes(attribute_t *attr)
|
||||
{
|
||||
attribute_t *a;
|
||||
|
||||
while(attr) {
|
||||
a = attr;
|
||||
attr = attr->next;
|
||||
destroy_attribute(a);
|
||||
}
|
||||
}
|
||||
|
||||
static void free_nodes(node_t *node)
|
||||
{
|
||||
node_t *n;
|
||||
|
||||
while(node) {
|
||||
if(node->child)
|
||||
free_nodes(node->child);
|
||||
n = node;
|
||||
node = node->next;
|
||||
free_attributes(n->attributes);
|
||||
destroy_node(n);
|
||||
}
|
||||
}
|
||||
|
||||
static void XMLCALL start(void *data,const char *el,const char **attr)
|
||||
{
|
||||
xml_t *xmlinfo = (xml_t*)data;
|
||||
int i;
|
||||
|
||||
if(xmlinfo->root == 0) {
|
||||
xmlinfo->root = create_node(el);
|
||||
xmlinfo->cur = xmlinfo->root;
|
||||
}
|
||||
else {
|
||||
xmlinfo->cur = add_child(xmlinfo->cur,el);
|
||||
}
|
||||
for(i=0;attr[i];i+=2) {
|
||||
attribute_t *at;
|
||||
|
||||
at = create_attribute(attr[i],attr[i+1]);
|
||||
at->next = xmlinfo->cur->attributes;
|
||||
xmlinfo->cur->attributes = at;
|
||||
}
|
||||
}
|
||||
|
||||
static void XMLCALL end(void *data,const char *el)
|
||||
{
|
||||
xml_t *xmlinfo = (xml_t*)data;
|
||||
|
||||
xmlinfo->cur = xmlinfo->cur->parent;
|
||||
}
|
||||
|
||||
xml_t *parser_load(char *filename)
|
||||
{
|
||||
FILE *fp;
|
||||
char *buf;
|
||||
int filelen,len;
|
||||
xml_t *xml = 0;
|
||||
|
||||
//open xml file
|
||||
if((fp = fopen(filename,"rb")) == 0) {
|
||||
log_printf("parser_loadxml: error opening file '%s'\n",filename);
|
||||
return(0);
|
||||
}
|
||||
|
||||
//get size of xml file
|
||||
fseek(fp,0,SEEK_END);
|
||||
filelen = ftell(fp);
|
||||
fseek(fp,0,SEEK_SET);
|
||||
|
||||
//allocate temporary buffer
|
||||
buf = mem_malloc(BUFSIZE + 1);
|
||||
|
||||
//initialize xml struct
|
||||
xml = (xml_t*)mem_malloc(sizeof(xml_t));
|
||||
memset(xml,0,sizeof(xml_t));
|
||||
xml->parser = XML_ParserCreate(NULL);
|
||||
xml->root = xml->cur = 0;
|
||||
|
||||
//setup expat
|
||||
XML_SetElementHandler(xml->parser,start,end);
|
||||
XML_SetUserData(xml->parser,(void*)xml);
|
||||
|
||||
//help expat parse the xml file
|
||||
while(filelen) {
|
||||
if(BUFSIZE > filelen) {
|
||||
fread(buf,1,filelen,fp);
|
||||
len = filelen;
|
||||
}
|
||||
else {
|
||||
fread(buf,1,BUFSIZE,fp);
|
||||
len = BUFSIZE;
|
||||
}
|
||||
filelen -= len;
|
||||
XML_Parse(xml->parser,buf,len,0);
|
||||
}
|
||||
XML_Parse(xml->parser,"",0,1);
|
||||
|
||||
//cleanup
|
||||
XML_ParserFree(xml->parser);
|
||||
xml->parser = 0;
|
||||
mem_free(buf);
|
||||
fclose(fp);
|
||||
|
||||
//we are done
|
||||
return(xml);
|
||||
}
|
||||
|
||||
void parser_free(xml_t *xml)
|
||||
{
|
||||
free_nodes(xml->root);
|
||||
mem_free(xml);
|
||||
}
|
||||
|
||||
void parser_merge(xml_t *dest,xml_t **src)
|
||||
{
|
||||
node_t *node;
|
||||
|
||||
//ensure we are working with the same types
|
||||
if(strcmp(dest->root->name,(*src)->root->name) != 0) {
|
||||
log_printf("parser_merge: different root element names, cannot merge\n");
|
||||
return;
|
||||
}
|
||||
|
||||
//find the last node
|
||||
node = dest->root->child;
|
||||
while(node->next) {
|
||||
node = node->next;
|
||||
}
|
||||
|
||||
//move nodes to the dest xml struct
|
||||
node->next = (*src)->root->child;
|
||||
(*src)->root->child = 0;
|
||||
|
||||
//free the rest of the src xml struct
|
||||
parser_free(*src);
|
||||
*src = 0;
|
||||
}
|
||||
|
||||
#define IS_OK(cc) ((cc) ? "OK" : "Bad!")
|
||||
|
||||
void parser_verifymemory()
|
||||
{
|
||||
int result;
|
||||
|
||||
result = num_malloc_str - num_free_str;
|
||||
result += num_malloc_node - num_free_node;
|
||||
result += num_malloc_attr - num_free_attr;
|
||||
result += num_malloc - num_free;
|
||||
if(result) {
|
||||
log_printf("xml memory verification:\n");
|
||||
log_printf("------------------------\n");
|
||||
log_printf(" str mallocs: %d, frees %d (%s)\n",num_malloc_str,num_free_str,IS_OK(num_malloc_str == num_free_str));
|
||||
log_printf(" node mallocs: %d, frees %d (%s)\n",num_malloc_node,num_free_node,IS_OK(num_malloc_node == num_free_node));
|
||||
log_printf(" attr mallocs: %d, frees %d (%s)\n",num_malloc_attr,num_free_attr,IS_OK(num_malloc_attr == num_free_attr));
|
||||
log_printf(" total mallocs: %d, frees %d (%s)\n",num_malloc,num_free,IS_OK(num_malloc == num_free));
|
||||
}
|
||||
log_printf("total bytes used by xml: %.3fmb\n",(double)num_bytes / 1024.0f / 1024.0f);
|
||||
}
|
|
@ -1,48 +0,0 @@
|
|||
/***************************************************************************
|
||||
* Copyright (C) 2013 by James Holodnak *
|
||||
* jamesholodnak@gmail.com *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with this program; if not, write to the *
|
||||
* Free Software Foundation, Inc., *
|
||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef __cartdb__parser_h__
|
||||
#define __cartdb__parser_h__
|
||||
|
||||
#include "cartdb/expat/expat.h"
|
||||
|
||||
typedef struct attribute_s {
|
||||
struct attribute_s *next;
|
||||
char *name,*data;
|
||||
} attribute_t;
|
||||
|
||||
typedef struct node_s {
|
||||
struct node_s *next;
|
||||
struct node_s *parent,*child;
|
||||
attribute_t *attributes;
|
||||
char *name,*data;
|
||||
} node_t;
|
||||
|
||||
typedef struct xml_s {
|
||||
XML_Parser parser;
|
||||
node_t *root,*cur;
|
||||
} xml_t;
|
||||
|
||||
xml_t *parser_load(char *filename);
|
||||
void parser_free(xml_t *xml);
|
||||
void parser_merge(xml_t *dest,xml_t **src);
|
||||
void parser_verifymemory();
|
||||
|
||||
#endif
|
|
@ -160,12 +160,19 @@ int emu_mainloop()
|
|||
video_endframe();
|
||||
total += system_gettick() - t;
|
||||
frames++;
|
||||
|
||||
if (total > 1000) {
|
||||
int fps = frames * system_getfrequency() / total;
|
||||
log_printf("fps: %d\n", fps);
|
||||
total = 0;
|
||||
frames = 0;
|
||||
}
|
||||
}
|
||||
log_printf("fps: %f (%d frames)\n",(double)frames / (double)total * system_getfrequency(),frames);
|
||||
mem_free(line);
|
||||
return(0);
|
||||
}
|
||||
|
||||
#if 0
|
||||
int emu_mainloop_test(char *script)
|
||||
{
|
||||
u64 t,total,frames;
|
||||
|
@ -228,3 +235,4 @@ int emu_mainloop_test(char *script)
|
|||
memfile_close(file);
|
||||
return(0);
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -146,6 +146,7 @@ int emu_event(int id,void *data)
|
|||
case E_DUMPDISK:
|
||||
if(nes->cart == 0)
|
||||
break;
|
||||
#if 0
|
||||
if((nes->cart->mapperid & B_TYPEMASK) == B_FDS) {
|
||||
FILE *fp;
|
||||
|
||||
|
@ -155,6 +156,7 @@ int emu_event(int id,void *data)
|
|||
fclose(fp);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
|
||||
case E_TOGGLERUNNING:
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
#include "inputdev.h"
|
||||
#include "system/video.h"
|
||||
#include "system/input.h"
|
||||
#include <klib.h>
|
||||
|
||||
static u8 portdata;
|
||||
static u8 counter,buttons,strobe;
|
||||
|
@ -59,8 +60,9 @@ static u8 read()
|
|||
break;
|
||||
if((Y == (int)nes->ppu.scanline) && (X >= (int)nes->ppu.linecycles))
|
||||
break;
|
||||
if(video_zapperhit(X,Y))
|
||||
hits++;
|
||||
assert(0);
|
||||
//if(video_zapperhit(X,Y))
|
||||
// hits++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -33,7 +33,7 @@ static void sync()
|
|||
static void write(u32 addr,u8 data)
|
||||
{
|
||||
reg = data & 3;
|
||||
printf("205 write $%04X = $%02X\n",addr,data);
|
||||
printf("205 write $%04lX = $%02X\n",addr,data);
|
||||
sync();
|
||||
}
|
||||
|
||||
|
|
|
@ -20,10 +20,11 @@
|
|||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
#include "mappers/fds/calls.h"
|
||||
#include "mappers/fds/hle.h"
|
||||
|
||||
u32 uptime();
|
||||
|
||||
//nmi vector
|
||||
HLECALL(nmi)
|
||||
{
|
||||
|
@ -162,7 +163,8 @@ HLECALL(reset)
|
|||
{
|
||||
//u8 m102,m103;
|
||||
|
||||
srand((u32)time(0));
|
||||
//srand((u32)time(0));
|
||||
srand(uptime());
|
||||
// showdisasm = 1;
|
||||
|
||||
//flag setup
|
||||
|
|
|
@ -20,7 +20,6 @@
|
|||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
#include "mappers/fds/fds.h"
|
||||
#include "mappers/fds/calls.h"
|
||||
#include "nes/nes.h"
|
||||
|
|
|
@ -159,14 +159,14 @@ static void write_bios(u32 addr,u8 data)
|
|||
//playspeed low
|
||||
case 0x3410:
|
||||
playspeed = (playspeed & 0xFF00) | data;
|
||||
irqlatch = (u32)(1786840.0f * (double)playspeed / 1000000.0f);
|
||||
irqlatch = (u32)((u64)178684 * playspeed / 100000);
|
||||
log_printf("irqlatch = %d (playspeed = %d)\n",irqlatch,playspeed);
|
||||
break;
|
||||
|
||||
//playspeed high
|
||||
case 0x3411:
|
||||
playspeed = (playspeed & 0x00FF) | (data << 8);
|
||||
irqlatch = (u32)(1786840.0f * (double)playspeed / 1000000.0f);
|
||||
irqlatch = (u32)((u64)178684 * playspeed / 100000);
|
||||
log_printf("irqlatch = %d (playspeed = %d)\n",irqlatch,playspeed);
|
||||
break;
|
||||
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
* $Id: s_FDS.c 376 2008-06-29 20:58:13Z Quietust $
|
||||
*/
|
||||
|
||||
#if 0
|
||||
//#include "..\..\interface.h"
|
||||
#include <math.h>
|
||||
#include <string.h>
|
||||
|
@ -323,3 +324,12 @@ int FDSsound_SaveLoad (int mode, int x, unsigned char *data)
|
|||
{
|
||||
return x;
|
||||
}
|
||||
#endif
|
||||
|
||||
void FDSsound_Load (void) { }
|
||||
void FDSsound_Reset (void) { }
|
||||
void FDSsound_Unload (void) { }
|
||||
int FDSsound_Read (int Addr) { return -1; }
|
||||
void FDSsound_Write (int Addr, int Val) { }
|
||||
int FDSsound_Get (int numCycles) { return 0; }
|
||||
int FDSsound_SaveLoad (int mode, int x, unsigned char *data) { return x; }
|
||||
|
|
|
@ -53,6 +53,7 @@
|
|||
YM2143 data sheet
|
||||
|
||||
**************************************************************************************/
|
||||
#if 0
|
||||
#include "misc/log.h"
|
||||
#include "s_VRC7.h"
|
||||
#include <stdio.h>
|
||||
|
@ -1486,3 +1487,11 @@ int VRC7sound_SaveLoad (int mode, int x, unsigned char *data)
|
|||
else MessageBox(hWnd,_T("Invalid save/load type!"),_T(__FILE__),MB_OK);
|
||||
*/ return x;
|
||||
}
|
||||
#endif
|
||||
|
||||
void VRC7sound_Load (void) { }
|
||||
void VRC7sound_Reset (void) { }
|
||||
void VRC7sound_Unload (void) { }
|
||||
void VRC7sound_Write (int Addr, int Val) { }
|
||||
int VRC7sound_Get (int numCycles) { return 0; }
|
||||
int VRC7sound_SaveLoad (int mode, int x, unsigned char *data) { return x; }
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
|
||||
#include <string.h>
|
||||
#include "mapperinc.h"
|
||||
#include "misc/slre/slre.h"
|
||||
//#include "misc/slre/slre.h"
|
||||
|
||||
struct unif_board_s {
|
||||
const char *name;
|
||||
|
@ -175,15 +175,16 @@ int mapper_get_mapperid_unif(char *str)
|
|||
{
|
||||
int ret,i;
|
||||
const char *err;
|
||||
char tmpstr[4][256];
|
||||
//char tmpstr[4][256];
|
||||
|
||||
ret = B_UNSUPPORTED;
|
||||
for(i=0;boards[i].boardid != -1;i++) {
|
||||
err = slre_match(SLRE_CASE_INSENSITIVE,boards[i].name,str,strlen(str),
|
||||
SLRE_STRING,sizeof(tmpstr[0]),tmpstr[0],
|
||||
SLRE_STRING,sizeof(tmpstr[1]),tmpstr[1],
|
||||
SLRE_STRING,sizeof(tmpstr[2]),tmpstr[2],
|
||||
SLRE_STRING,sizeof(tmpstr[3]),tmpstr[3]);
|
||||
//err = slre_match(SLRE_CASE_INSENSITIVE,boards[i].name,str,strlen(str),
|
||||
// SLRE_STRING,sizeof(tmpstr[0]),tmpstr[0],
|
||||
// SLRE_STRING,sizeof(tmpstr[1]),tmpstr[1],
|
||||
// SLRE_STRING,sizeof(tmpstr[2]),tmpstr[2],
|
||||
// SLRE_STRING,sizeof(tmpstr[3]),tmpstr[3]);
|
||||
err = NULL;
|
||||
if(err == NULL) {
|
||||
if(ret != B_UNSUPPORTED)
|
||||
log_printf("mapper_get_mapperid_unif: duplicate match for board '%s'\n",str);
|
||||
|
|
|
@ -32,10 +32,10 @@
|
|||
|
||||
static vars_t *configvars = 0;
|
||||
|
||||
#if 0
|
||||
//this path stuff needs to be moved
|
||||
static void mkdirr(char *path)
|
||||
{
|
||||
#if 0
|
||||
char *tmp = mem_strdup(path);
|
||||
char *p = tmp;
|
||||
int num = 0;
|
||||
|
@ -64,7 +64,6 @@ static void mkdirr(char *path)
|
|||
|
||||
//free tmp string
|
||||
mem_free(tmp);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void makepath(char *str)
|
||||
|
@ -130,12 +129,13 @@ static int findconfig(char *dest)
|
|||
|
||||
return(1);
|
||||
}
|
||||
#endif
|
||||
|
||||
//initialize the configuration defaults
|
||||
static vars_t *config_get_defaults()
|
||||
{
|
||||
vars_t *ret = vars_create();
|
||||
char *str;
|
||||
//char *str;
|
||||
|
||||
vars_set_int (ret,F_CONFIG,"video.framelimit", 1);
|
||||
vars_set_int (ret,F_CONFIG,"video.fullscreen", 0);
|
||||
|
@ -207,8 +207,8 @@ static vars_t *config_get_defaults()
|
|||
|
||||
vars_set_string(ret,0,"version",VERSION);
|
||||
vars_set_string(ret,0,"exepath",exepath);
|
||||
if((str = getenv("HOME")) != 0)
|
||||
vars_set_string(ret,0,"home",str);
|
||||
//if((str = getenv("HOME")) != 0)
|
||||
// vars_set_string(ret,0,"home",str);
|
||||
|
||||
return(ret);
|
||||
}
|
||||
|
@ -216,13 +216,13 @@ static vars_t *config_get_defaults()
|
|||
int config_init()
|
||||
{
|
||||
vars_t *v;
|
||||
char tmp[1024];
|
||||
//char tmp[1024];
|
||||
|
||||
//find configuration file
|
||||
if(findconfig(configfilename) == 0)
|
||||
log_printf("main: found configuration at '%s'\n",configfilename);
|
||||
else
|
||||
log_printf("main: creating new configuration at '%s'\n",configfilename);
|
||||
//if(findconfig(configfilename) == 0)
|
||||
// log_printf("main: found configuration at '%s'\n",configfilename);
|
||||
//else
|
||||
// log_printf("main: creating new configuration at '%s'\n",configfilename);
|
||||
|
||||
configvars = config_get_defaults();
|
||||
if((v = vars_load(configfilename)) == 0) {
|
||||
|
@ -237,10 +237,10 @@ int config_init()
|
|||
}
|
||||
|
||||
//make the directories
|
||||
makepath(config_get_eval_string(tmp,"path.user"));
|
||||
makepath(config_get_eval_string(tmp,"path.save"));
|
||||
makepath(config_get_eval_string(tmp,"path.state"));
|
||||
makepath(config_get_eval_string(tmp,"path.cheat"));
|
||||
//makepath(config_get_eval_string(tmp,"path.user"));
|
||||
//makepath(config_get_eval_string(tmp,"path.save"));
|
||||
//makepath(config_get_eval_string(tmp,"path.state"));
|
||||
//makepath(config_get_eval_string(tmp,"path.cheat"));
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
|
|
@ -36,9 +36,10 @@
|
|||
|
||||
#define LOGFILENAME "nesemu2.log"
|
||||
|
||||
#if 0
|
||||
static void (*loghook)(char*) = 0;
|
||||
static FILE *logfd = 0;
|
||||
static char logfilename[MAX_PATH] = "";
|
||||
static void (*loghook)(char*) = 0;
|
||||
static history_t history = {0,0};
|
||||
|
||||
int log_init()
|
||||
|
@ -94,10 +95,14 @@ void log_kill()
|
|||
fclose(logfd);
|
||||
logfd = 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
int log_init() { return 0; }
|
||||
void log_kill() { }
|
||||
|
||||
void log_sethook(void (*hook)(char*))
|
||||
{
|
||||
loghook = hook;
|
||||
//loghook = hook;
|
||||
}
|
||||
|
||||
void log_print(char *str)
|
||||
|
@ -105,6 +110,7 @@ void log_print(char *str)
|
|||
//output message to stdout
|
||||
printf("%s",str);
|
||||
|
||||
#if 0
|
||||
//output message to hook function
|
||||
if(loghook) {
|
||||
loghook(str);
|
||||
|
@ -121,6 +127,7 @@ void log_print(char *str)
|
|||
|
||||
//flush file
|
||||
fflush(logfd);
|
||||
#endif
|
||||
}
|
||||
|
||||
void log_printf(char *str,...)
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
#include "misc/memfile.h"
|
||||
#include "misc/memutil.h"
|
||||
#include "misc/log.h"
|
||||
#include <assert.h>
|
||||
|
||||
memfile_t *memfile_create()
|
||||
{
|
||||
|
@ -36,6 +37,7 @@ memfile_t *memfile_create()
|
|||
return(ret);
|
||||
}
|
||||
|
||||
#ifndef NO_FILE_SYSTEM
|
||||
memfile_t *memfile_open(char *filename,char *mode)
|
||||
{
|
||||
FILE *fp;
|
||||
|
@ -83,16 +85,6 @@ memfile_t *memfile_open(char *filename,char *mode)
|
|||
return(ret);
|
||||
}
|
||||
|
||||
memfile_t *memfile_open_memory(u8 *data,u32 size)
|
||||
{
|
||||
memfile_t *ret;
|
||||
|
||||
ret = memfile_create();
|
||||
ret->size = size;
|
||||
ret->data = (u8*)mem_dup(data,size);
|
||||
return(ret);
|
||||
}
|
||||
|
||||
void memfile_close(memfile_t *mf)
|
||||
{
|
||||
FILE *fp = (FILE*)mf->handle;
|
||||
|
@ -114,6 +106,41 @@ void memfile_close(memfile_t *mf)
|
|||
mem_free(mf->data);
|
||||
mem_free(mf);
|
||||
}
|
||||
#else
|
||||
#include "roms/gen/roms.h"
|
||||
|
||||
memfile_t *memfile_open(char *filename,char *mode) {
|
||||
struct rom *rom = &roms[0];
|
||||
for (int i = 1; i < nroms; i++) {
|
||||
struct rom *cur = &roms[i];
|
||||
if (strcmp(cur->name, filename) == 0) {
|
||||
rom = cur;
|
||||
}
|
||||
}
|
||||
|
||||
printf("Using ROM: %s\n", rom->name);
|
||||
|
||||
memfile_t *mf = memfile_open_memory(rom->body, *(rom->size));
|
||||
|
||||
return mf;
|
||||
}
|
||||
|
||||
void memfile_close(memfile_t *mf) {
|
||||
if(mf->data)
|
||||
mem_free(mf->data);
|
||||
mem_free(mf);
|
||||
}
|
||||
#endif
|
||||
|
||||
memfile_t *memfile_open_memory(u8 *data,u32 size)
|
||||
{
|
||||
memfile_t *ret;
|
||||
|
||||
ret = memfile_create();
|
||||
ret->size = size;
|
||||
ret->data = (u8*)mem_dup(data,size);
|
||||
return(ret);
|
||||
}
|
||||
|
||||
u32 memfile_size(memfile_t *mf)
|
||||
{
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
#include <string.h>
|
||||
#include "misc/memutil.h"
|
||||
#include "misc/log.h"
|
||||
#include <klib.h>
|
||||
|
||||
#define MAX_CHUNKS 1024
|
||||
|
||||
|
@ -46,13 +47,7 @@ static size_t num_bytes;
|
|||
static char *bytestr(size_t sz)
|
||||
{
|
||||
static char str[64];
|
||||
|
||||
if(sz < 1024)
|
||||
sprintf(str,"%ub",sz);
|
||||
else if(sz < 1024 * 1024)
|
||||
sprintf(str,"%.2fkb",(double)sz / 1024.0f);
|
||||
else if(sz < 1024 * 1024 * 1024)
|
||||
sprintf(str,"%.2fmb",(double)sz / 1024.0f / 1024.0f);
|
||||
sprintf(str,"%ub",sz);
|
||||
return(str);
|
||||
}
|
||||
|
||||
|
@ -142,7 +137,7 @@ void *memutil_alloc(size_t size,char *file,int line)
|
|||
checkinited();
|
||||
if ((ret = malloc(size)) == 0) {
|
||||
log_printf("memutil_alloc: unable to alloc %d bytes\n", size);
|
||||
exit(-1);
|
||||
assert(0);
|
||||
}
|
||||
memset(ret,0,size);
|
||||
num_alloc++;
|
||||
|
@ -167,13 +162,13 @@ void *memutil_alloc(size_t size,char *file,int line)
|
|||
|
||||
void *memutil_realloc(void *ptr,size_t size,char *file,int line)
|
||||
{
|
||||
void *ret;
|
||||
int i;
|
||||
|
||||
checkinited();
|
||||
if(ptr == 0)
|
||||
return(memutil_alloc(size,file,line));
|
||||
ret = realloc(ptr,size);
|
||||
assert(0);
|
||||
#if 0
|
||||
void *ret = realloc(ptr,size);
|
||||
int i;
|
||||
num_realloc++;
|
||||
for(i=0;i<MAX_CHUNKS;i++) {
|
||||
if(chunks[i].ptr == ptr) {
|
||||
|
@ -192,6 +187,7 @@ void *memutil_realloc(void *ptr,size_t size,char *file,int line)
|
|||
}
|
||||
memutil_count();
|
||||
return(ret);
|
||||
#endif
|
||||
}
|
||||
|
||||
void memutil_free(void *ptr,char *file,int line)
|
||||
|
|
|
@ -39,6 +39,7 @@ char *paths_normalize(char *str)
|
|||
return(str);
|
||||
}
|
||||
|
||||
#if 0
|
||||
void paths_makestatefilename(char *romfilename,char *dest,int len)
|
||||
{
|
||||
char *p,*tmp = mem_strdup(romfilename);
|
||||
|
@ -70,3 +71,6 @@ void paths_makestatefilename(char *romfilename,char *dest,int len)
|
|||
//free the temporary string
|
||||
mem_free(tmp);
|
||||
}
|
||||
#endif
|
||||
|
||||
void paths_makestatefilename(char *romfilename,char *dest,int len) { }
|
||||
|
|
|
@ -1,879 +0,0 @@
|
|||
// Copyright (c) 2004-2012 Sergey Lyubka <valenok@gmail.com>
|
||||
// All rights reserved
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
#include <stdio.h>
|
||||
#include <assert.h>
|
||||
#include <ctype.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
//#include <errno.h>
|
||||
|
||||
#include "slre.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
#define snprintf _snprintf
|
||||
#endif
|
||||
|
||||
// Compiled regular expression
|
||||
struct slre {
|
||||
unsigned char code[256];
|
||||
unsigned char data[256];
|
||||
int code_size;
|
||||
int data_size;
|
||||
int num_caps; // Number of bracket pairs
|
||||
int anchored; // Must match from string start
|
||||
enum slre_option options;
|
||||
const char *error_string; // Error string
|
||||
};
|
||||
|
||||
// Captured substring
|
||||
struct cap {
|
||||
const char *ptr; // Pointer to the substring
|
||||
int len; // Substring length
|
||||
};
|
||||
|
||||
enum {
|
||||
END, BRANCH, ANY, EXACT, ANYOF, ANYBUT, OPEN, CLOSE, BOL, EOL, STAR, PLUS,
|
||||
STARQ, PLUSQ, QUEST, SPACE, NONSPACE, DIGIT
|
||||
};
|
||||
|
||||
// Commands and operands are all unsigned char (1 byte long). All code offsets
|
||||
// are relative to current address, and positive (always point forward). Data
|
||||
// offsets are absolute. Commands with operands:
|
||||
//
|
||||
// BRANCH offset1 offset2
|
||||
// Try to match the code block that follows the BRANCH instruction
|
||||
// (code block ends with END). If no match, try to match code block that
|
||||
// starts at offset1. If either of these match, jump to offset2.
|
||||
//
|
||||
// EXACT data_offset data_length
|
||||
// Try to match exact string. String is recorded in data section from
|
||||
// data_offset, and has length data_length.
|
||||
//
|
||||
// OPEN capture_number
|
||||
// CLOSE capture_number
|
||||
// If the user have passed 'struct cap' array for captures, OPEN
|
||||
// records the beginning of the matched substring (cap->ptr), CLOSE
|
||||
// sets the length (cap->len) for respective capture_number.
|
||||
//
|
||||
// STAR code_offset
|
||||
// PLUS code_offset
|
||||
// QUEST code_offset
|
||||
// *, +, ?, respectively. Try to gobble as much as possible from the
|
||||
// matched buffer while code block that follows these instructions
|
||||
// matches. When the longest possible string is matched,
|
||||
// jump to code_offset
|
||||
//
|
||||
// STARQ, PLUSQ are non-greedy versions of STAR and PLUS.
|
||||
|
||||
static const char *meta_characters = "|.^$*+?()[\\";
|
||||
static const char *error_no_match = "No match";
|
||||
|
||||
static void set_jump_offset(struct slre *r, int pc, int offset) {
|
||||
assert(offset < r->code_size);
|
||||
if (r->code_size - offset > 0xff) {
|
||||
r->error_string = "Jump offset is too big";
|
||||
} else {
|
||||
r->code[pc] = (unsigned char) (r->code_size - offset);
|
||||
}
|
||||
}
|
||||
|
||||
static void emit(struct slre *r, int code) {
|
||||
if (r->code_size >= (int) (sizeof(r->code) / sizeof(r->code[0]))) {
|
||||
r->error_string = "RE is too long (code overflow)";
|
||||
} else {
|
||||
r->code[r->code_size++] = (unsigned char) code;
|
||||
}
|
||||
}
|
||||
|
||||
static void store_char_in_data(struct slre *r, int ch) {
|
||||
if (r->data_size >= (int) sizeof(r->data)) {
|
||||
r->error_string = "RE is too long (data overflow)";
|
||||
} else {
|
||||
r->data[r->data_size++] = ch;
|
||||
}
|
||||
}
|
||||
|
||||
static void exact(struct slre *r, const char **re) {
|
||||
int old_data_size = r->data_size;
|
||||
|
||||
while (**re != '\0' && (strchr(meta_characters, **re)) == NULL) {
|
||||
store_char_in_data(r, *(*re)++);
|
||||
}
|
||||
|
||||
emit(r, EXACT);
|
||||
emit(r, old_data_size);
|
||||
emit(r, r->data_size - old_data_size);
|
||||
}
|
||||
|
||||
static int get_escape_char(const char **re) {
|
||||
int res;
|
||||
|
||||
switch (*(*re)++) {
|
||||
case 'n': res = '\n'; break;
|
||||
case 'r': res = '\r'; break;
|
||||
case 't': res = '\t'; break;
|
||||
case '0': res = 0; break;
|
||||
case 'S': res = NONSPACE << 8; break;
|
||||
case 's': res = SPACE << 8; break;
|
||||
case 'd': res = DIGIT << 8; break;
|
||||
default: res = (*re)[-1]; break;
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
static void anyof(struct slre *r, const char **re) {
|
||||
int esc, old_data_size = r->data_size, op = ANYOF;
|
||||
|
||||
if (**re == '^') {
|
||||
op = ANYBUT;
|
||||
(*re)++;
|
||||
}
|
||||
|
||||
while (**re != '\0')
|
||||
|
||||
switch (*(*re)++) {
|
||||
case ']':
|
||||
emit(r, op);
|
||||
emit(r, old_data_size);
|
||||
emit(r, r->data_size - old_data_size);
|
||||
return;
|
||||
// NOTREACHED
|
||||
break;
|
||||
case '\\':
|
||||
esc = get_escape_char(re);
|
||||
if ((esc & 0xff) == 0) {
|
||||
store_char_in_data(r, 0);
|
||||
store_char_in_data(r, esc >> 8);
|
||||
} else {
|
||||
store_char_in_data(r, esc);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
store_char_in_data(r, (*re)[-1]);
|
||||
break;
|
||||
}
|
||||
|
||||
r->error_string = "No closing ']' bracket";
|
||||
}
|
||||
|
||||
static void relocate(struct slre *r, int begin, int shift) {
|
||||
emit(r, END);
|
||||
memmove(r->code + begin + shift, r->code + begin, r->code_size - begin);
|
||||
r->code_size += shift;
|
||||
}
|
||||
|
||||
static void quantifier(struct slre *r, int prev, int op) {
|
||||
if (r->code[prev] == EXACT && r->code[prev + 2] > 1) {
|
||||
r->code[prev + 2]--;
|
||||
emit(r, EXACT);
|
||||
emit(r, r->code[prev + 1] + r->code[prev + 2]);
|
||||
emit(r, 1);
|
||||
prev = r->code_size - 3;
|
||||
}
|
||||
relocate(r, prev, 2);
|
||||
r->code[prev] = op;
|
||||
set_jump_offset(r, prev + 1, prev);
|
||||
}
|
||||
|
||||
static void exact_one_char(struct slre *r, int ch) {
|
||||
emit(r, EXACT);
|
||||
emit(r, r->data_size);
|
||||
emit(r, 1);
|
||||
store_char_in_data(r, ch);
|
||||
}
|
||||
|
||||
static void fixup_branch(struct slre *r, int fixup) {
|
||||
if (fixup > 0) {
|
||||
emit(r, END);
|
||||
set_jump_offset(r, fixup, fixup - 2);
|
||||
}
|
||||
}
|
||||
|
||||
static void compile(struct slre *r, const char **re) {
|
||||
int op, esc, branch_start, last_op, fixup, cap_no, level;
|
||||
|
||||
fixup = 0;
|
||||
level = r->num_caps;
|
||||
branch_start = last_op = r->code_size;
|
||||
|
||||
for (;;)
|
||||
switch (*(*re)++) {
|
||||
|
||||
case '\0':
|
||||
(*re)--;
|
||||
return;
|
||||
// NOTREACHED
|
||||
break;
|
||||
|
||||
case '^':
|
||||
emit(r, BOL);
|
||||
break;
|
||||
|
||||
case '$':
|
||||
emit(r, EOL);
|
||||
break;
|
||||
|
||||
case '.':
|
||||
last_op = r->code_size;
|
||||
emit(r, ANY);
|
||||
break;
|
||||
|
||||
case '[':
|
||||
last_op = r->code_size;
|
||||
anyof(r, re);
|
||||
break;
|
||||
|
||||
case '\\':
|
||||
last_op = r->code_size;
|
||||
esc = get_escape_char(re);
|
||||
if (esc & 0xff00) {
|
||||
emit(r, esc >> 8);
|
||||
} else {
|
||||
exact_one_char(r, esc);
|
||||
}
|
||||
break;
|
||||
|
||||
case '(':
|
||||
last_op = r->code_size;
|
||||
cap_no = ++r->num_caps;
|
||||
emit(r, OPEN);
|
||||
emit(r, cap_no);
|
||||
|
||||
compile(r, re);
|
||||
if (*(*re)++ != ')') {
|
||||
r->error_string = "No closing bracket";
|
||||
return;
|
||||
}
|
||||
|
||||
emit(r, CLOSE);
|
||||
emit(r, cap_no);
|
||||
break;
|
||||
|
||||
case ')':
|
||||
(*re)--;
|
||||
fixup_branch(r, fixup);
|
||||
if (level == 0) {
|
||||
r->error_string = "Unbalanced brackets";
|
||||
return;
|
||||
}
|
||||
return;
|
||||
// NOTREACHED
|
||||
break;
|
||||
|
||||
case '+':
|
||||
case '*':
|
||||
op = (*re)[-1] == '*' ? STAR: PLUS;
|
||||
if (**re == '?') {
|
||||
(*re)++;
|
||||
op = op == STAR ? STARQ : PLUSQ;
|
||||
}
|
||||
quantifier(r, last_op, op);
|
||||
break;
|
||||
|
||||
case '?':
|
||||
quantifier(r, last_op, QUEST);
|
||||
break;
|
||||
|
||||
case '|':
|
||||
fixup_branch(r, fixup);
|
||||
relocate(r, branch_start, 3);
|
||||
r->code[branch_start] = BRANCH;
|
||||
set_jump_offset(r, branch_start + 1, branch_start);
|
||||
fixup = branch_start + 2;
|
||||
r->code[fixup] = 0xff;
|
||||
break;
|
||||
|
||||
default:
|
||||
(*re)--;
|
||||
last_op = r->code_size;
|
||||
exact(r, re);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Compile regular expression. If success, 1 is returned.
|
||||
// If error, 0 is returned and slre.error_string points to the error message.
|
||||
static const char *compile2(struct slre *r, const char *re) {
|
||||
r->error_string = NULL;
|
||||
r->code_size = r->data_size = r->num_caps = r->anchored = 0;
|
||||
|
||||
if (*re == '^') {
|
||||
r->anchored++;
|
||||
}
|
||||
|
||||
emit(r, OPEN); // This will capture what matches full RE
|
||||
emit(r, 0);
|
||||
|
||||
while (*re != '\0') {
|
||||
compile(r, &re);
|
||||
}
|
||||
|
||||
if (r->code[2] == BRANCH) {
|
||||
fixup_branch(r, 4);
|
||||
}
|
||||
|
||||
emit(r, CLOSE);
|
||||
emit(r, 0);
|
||||
emit(r, END);
|
||||
|
||||
#if 0
|
||||
static void dump(const struct slre *, FILE *);
|
||||
dump(r, stdout);
|
||||
#endif
|
||||
|
||||
return r->error_string;
|
||||
}
|
||||
|
||||
static const char *match(const struct slre *, int, const char *, int, int *,
|
||||
struct cap *, int caps_size);
|
||||
|
||||
static void loop_greedy(const struct slre *r, int pc, const char *s, int len,
|
||||
int *ofs) {
|
||||
int saved_offset, matched_offset;
|
||||
|
||||
saved_offset = matched_offset = *ofs;
|
||||
|
||||
while (!match(r, pc + 2, s, len, ofs, NULL, 0)) {
|
||||
saved_offset = *ofs;
|
||||
if (!match(r, pc + r->code[pc + 1], s, len, ofs, NULL, 0)) {
|
||||
matched_offset = saved_offset;
|
||||
}
|
||||
*ofs = saved_offset;
|
||||
}
|
||||
|
||||
*ofs = matched_offset;
|
||||
}
|
||||
|
||||
static void loop_non_greedy(const struct slre *r, int pc, const char *s,
|
||||
int len, int *ofs) {
|
||||
int saved_offset = *ofs;
|
||||
|
||||
while (!match(r, pc + 2, s, len, ofs, NULL, 0)) {
|
||||
saved_offset = *ofs;
|
||||
if (!match(r, pc + r->code[pc + 1], s, len, ofs, NULL, 0))
|
||||
break;
|
||||
}
|
||||
|
||||
*ofs = saved_offset;
|
||||
}
|
||||
|
||||
static int is_any_of(const unsigned char *p, int len, const char *s, int *ofs) {
|
||||
int i, ch;
|
||||
|
||||
ch = s[*ofs];
|
||||
|
||||
for (i = 0; i < len; i++)
|
||||
if (p[i] == ch) {
|
||||
(*ofs)++;
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int is_any_but(const unsigned char *p, int len, const char *s,
|
||||
int *ofs) {
|
||||
int i, ch;
|
||||
|
||||
ch = s[*ofs];
|
||||
|
||||
for (i = 0; i < len; i++)
|
||||
if (p[i] == ch) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
(*ofs)++;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int lowercase(const char *s) {
|
||||
return tolower(* (const unsigned char *) s);
|
||||
}
|
||||
|
||||
static int casecmp(const void *p1, const void *p2, size_t len) {
|
||||
const char *s1 = p1, *s2 = p2;
|
||||
int diff = 0;
|
||||
|
||||
if (len > 0)
|
||||
do {
|
||||
diff = lowercase(s1++) - lowercase(s2++);
|
||||
} while (diff == 0 && s1[-1] != '\0' && --len > 0);
|
||||
|
||||
return diff;
|
||||
}
|
||||
|
||||
static const char *match(const struct slre *r, int pc, const char *s, int len,
|
||||
int *ofs, struct cap *caps, int caps_size) {
|
||||
int n, saved_offset;
|
||||
const char *error_string = NULL;
|
||||
int (*cmp)(const void *string1, const void *string2, size_t len);
|
||||
|
||||
while (error_string == NULL && r->code[pc] != END) {
|
||||
|
||||
assert(pc < r->code_size);
|
||||
assert(pc < (int) (sizeof(r->code) / sizeof(r->code[0])));
|
||||
|
||||
switch (r->code[pc]) {
|
||||
case BRANCH:
|
||||
saved_offset = *ofs;
|
||||
error_string = match(r, pc + 3, s, len, ofs, caps, caps_size);
|
||||
if (error_string != NULL) {
|
||||
*ofs = saved_offset;
|
||||
error_string = match(r, pc + r->code[pc + 1], s, len, ofs, caps,
|
||||
caps_size);
|
||||
}
|
||||
pc += r->code[pc + 2];
|
||||
break;
|
||||
|
||||
case EXACT:
|
||||
error_string = error_no_match;
|
||||
n = r->code[pc + 2]; // String length
|
||||
cmp = r->options & SLRE_CASE_INSENSITIVE ? casecmp : memcmp;
|
||||
if (n <= len - *ofs && !cmp(s + *ofs, r->data + r->code[pc + 1], n)) {
|
||||
(*ofs) += n;
|
||||
error_string = NULL;
|
||||
}
|
||||
pc += 3;
|
||||
break;
|
||||
|
||||
case QUEST:
|
||||
error_string = NULL;
|
||||
saved_offset = *ofs;
|
||||
if (match(r, pc + 2, s, len, ofs, caps, caps_size) != NULL) {
|
||||
*ofs = saved_offset;
|
||||
}
|
||||
pc += r->code[pc + 1];
|
||||
break;
|
||||
|
||||
case STAR:
|
||||
error_string = NULL;
|
||||
loop_greedy(r, pc, s, len, ofs);
|
||||
pc += r->code[pc + 1];
|
||||
break;
|
||||
|
||||
case STARQ:
|
||||
error_string = NULL;
|
||||
loop_non_greedy(r, pc, s, len, ofs);
|
||||
pc += r->code[pc + 1];
|
||||
break;
|
||||
|
||||
case PLUS:
|
||||
if ((error_string = match(r, pc + 2, s, len, ofs,
|
||||
caps, caps_size)) != NULL) {
|
||||
break;
|
||||
}
|
||||
loop_greedy(r, pc, s, len, ofs);
|
||||
pc += r->code[pc + 1];
|
||||
break;
|
||||
|
||||
case PLUSQ:
|
||||
if ((error_string = match(r, pc + 2, s, len, ofs,
|
||||
caps, caps_size)) != NULL) {
|
||||
break;
|
||||
}
|
||||
loop_non_greedy(r, pc, s, len, ofs);
|
||||
pc += r->code[pc + 1];
|
||||
break;
|
||||
|
||||
case SPACE:
|
||||
error_string = error_no_match;
|
||||
if (*ofs < len && isspace(((unsigned char *)s)[*ofs])) {
|
||||
(*ofs)++;
|
||||
error_string = NULL;
|
||||
}
|
||||
pc++;
|
||||
break;
|
||||
|
||||
case NONSPACE:
|
||||
error_string = error_no_match;
|
||||
if (*ofs <len && !isspace(((unsigned char *)s)[*ofs])) {
|
||||
(*ofs)++;
|
||||
error_string = NULL;
|
||||
}
|
||||
pc++;
|
||||
break;
|
||||
|
||||
case DIGIT:
|
||||
error_string = error_no_match;
|
||||
if (*ofs < len && isdigit(((unsigned char *)s)[*ofs])) {
|
||||
(*ofs)++;
|
||||
error_string = NULL;
|
||||
}
|
||||
pc++;
|
||||
break;
|
||||
|
||||
case ANY:
|
||||
error_string = error_no_match;
|
||||
if (*ofs < len) {
|
||||
(*ofs)++;
|
||||
error_string = NULL;
|
||||
}
|
||||
pc++;
|
||||
break;
|
||||
|
||||
case ANYOF:
|
||||
error_string = error_no_match;
|
||||
if (*ofs < len)
|
||||
error_string = is_any_of(r->data + r->code[pc + 1], r->code[pc + 2],
|
||||
s, ofs) ? NULL : error_no_match;
|
||||
pc += 3;
|
||||
break;
|
||||
|
||||
case ANYBUT:
|
||||
error_string = error_no_match;
|
||||
if (*ofs < len)
|
||||
error_string = is_any_but(r->data + r->code[pc + 1], r->code[pc + 2],
|
||||
s, ofs) ? NULL : error_no_match;
|
||||
pc += 3;
|
||||
break;
|
||||
|
||||
case BOL:
|
||||
error_string = *ofs == 0 ? NULL : error_no_match;
|
||||
pc++;
|
||||
break;
|
||||
|
||||
case EOL:
|
||||
error_string = *ofs == len ? NULL : error_no_match;
|
||||
pc++;
|
||||
break;
|
||||
|
||||
case OPEN:
|
||||
if (caps != NULL) {
|
||||
if (caps_size - 2 < r->code[pc + 1]) {
|
||||
error_string = "Too many brackets";
|
||||
} else {
|
||||
caps[r->code[pc + 1]].ptr = s + *ofs;
|
||||
}
|
||||
}
|
||||
pc += 2;
|
||||
break;
|
||||
|
||||
case CLOSE:
|
||||
if (caps != NULL) {
|
||||
assert(r->code[pc + 1] >= 0);
|
||||
assert(r->code[pc + 1] < caps_size);
|
||||
caps[r->code[pc + 1]].len = (s + *ofs) -
|
||||
caps[r->code[pc + 1]].ptr;
|
||||
}
|
||||
pc += 2;
|
||||
break;
|
||||
|
||||
case END:
|
||||
pc++;
|
||||
break;
|
||||
|
||||
default:
|
||||
printf("unknown cmd (%d) at %d\n", r->code[pc], pc);
|
||||
assert(0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return error_string;
|
||||
}
|
||||
|
||||
// Return 1 if match, 0 if no match.
|
||||
// If `captured_substrings' array is not NULL, then it is filled with the
|
||||
// values of captured substrings. captured_substrings[0] element is always
|
||||
// a full matched substring. The round bracket captures start from
|
||||
// captured_substrings[1].
|
||||
// It is assumed that the size of captured_substrings array is enough to
|
||||
// hold all captures. The caller function must make sure it is! So, the
|
||||
// array_size = number_of_round_bracket_pairs + 1
|
||||
static const char *match2(const struct slre *r, const char *buf, int len,
|
||||
struct cap *caps, int caps_size) {
|
||||
int i, ofs = 0;
|
||||
const char *error_string = error_no_match;
|
||||
|
||||
if (caps != NULL) {
|
||||
memset(caps, 0, caps_size * sizeof(caps[0]));
|
||||
}
|
||||
|
||||
if (r->anchored) {
|
||||
error_string = match(r, 0, buf, len, &ofs, caps, caps_size);
|
||||
} else {
|
||||
for (i = 0; i < len && error_string != NULL; i++) {
|
||||
ofs = i;
|
||||
error_string = match(r, 0, buf, len, &ofs, caps, caps_size);
|
||||
}
|
||||
}
|
||||
|
||||
return error_string;
|
||||
}
|
||||
|
||||
static const char *capture_float(const struct cap *cap, void *p, size_t len) {
|
||||
const char *fmt;
|
||||
char buf[20];
|
||||
|
||||
switch (len) {
|
||||
case sizeof(float): fmt = "f"; break;
|
||||
case sizeof(double): fmt = "lf"; break;
|
||||
default: return "SLRE_FLOAT: unsupported size";
|
||||
}
|
||||
|
||||
snprintf(buf, sizeof(buf), "%%%d%s", cap->len, fmt);
|
||||
return sscanf(cap->ptr, buf, p) == 1 ? NULL : "SLRE_FLOAT: capture failed";
|
||||
}
|
||||
|
||||
static const char *capture_string(const struct cap *cap, void *p, size_t len) {
|
||||
if ((int) len <= cap->len) {
|
||||
return "SLRE_STRING: buffer size too small";
|
||||
}
|
||||
memcpy(p, cap->ptr, cap->len);
|
||||
((char *) p)[cap->len] = '\0';
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static const char *capture_int(const struct cap *cap, void *p, size_t len) {
|
||||
const char *fmt;
|
||||
char buf[20];
|
||||
|
||||
switch (len) {
|
||||
case sizeof(char): fmt = "hh"; break;
|
||||
case sizeof(short): fmt = "h"; break;
|
||||
case sizeof(int): fmt = "d"; break;
|
||||
case sizeof(long long int): fmt = "lld"; break;
|
||||
default: return "SLRE_INT: unsupported size";
|
||||
}
|
||||
|
||||
snprintf(buf, sizeof(buf), "%%%d%s", cap->len, fmt);
|
||||
return sscanf(cap->ptr, buf, p) == 1 ? NULL : "SLRE_INT: capture failed";
|
||||
}
|
||||
|
||||
static const char *capture(const struct cap *caps, int num_caps, va_list ap) {
|
||||
int i, type;
|
||||
size_t size;
|
||||
void *p;
|
||||
const char *err = NULL;
|
||||
|
||||
for (i = 0; i < num_caps; i++) {
|
||||
type = va_arg(ap, int);
|
||||
size = va_arg(ap, size_t);
|
||||
p = va_arg(ap, void *);
|
||||
switch (type) {
|
||||
case SLRE_INT: err = capture_int(&caps[i], p, size); break;
|
||||
case SLRE_FLOAT: err = capture_float(&caps[i], p, size); break;
|
||||
case SLRE_STRING: err = capture_string(&caps[i], p, size); break;
|
||||
default: err = "Unknown type, expected SLRE_(INT|FLOAT|STRING)"; break;
|
||||
}
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
const char *slre_match(enum slre_option options, const char *re,
|
||||
const char *buf, int buf_len, ...) {
|
||||
struct slre slre = {};
|
||||
struct cap caps[20];
|
||||
va_list ap;
|
||||
const char *error_string = NULL;
|
||||
|
||||
slre.options = options;
|
||||
if ((error_string = compile2(&slre, re)) == NULL &&
|
||||
(error_string = match2(&slre, buf, buf_len, caps,
|
||||
sizeof(caps) / sizeof(caps[0]))) == NULL) {
|
||||
va_start(ap, buf_len);
|
||||
error_string = capture(caps + 1, slre.num_caps, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
|
||||
return error_string;
|
||||
}
|
||||
|
||||
#if defined(SLRE_UNIT_TEST)
|
||||
static struct {
|
||||
const char *name;
|
||||
int narg;
|
||||
const char *flags;
|
||||
} opcodes[] = {
|
||||
{"END", 0, "" }, // End of code block or program
|
||||
{"BRANCH", 2, "oo"}, // Alternative operator, "|"
|
||||
{"ANY", 0, "" }, // Match any character, "."
|
||||
{"EXACT", 2, "d" }, // Match exact string
|
||||
{"ANYOF", 2, "D" }, // Match any from set, "[]"
|
||||
{"ANYBUT", 2, "D" }, // Match any but from set, "[^]"
|
||||
{"OPEN ", 1, "i" }, // Capture start, "("
|
||||
{"CLOSE", 1, "i" }, // Capture end, ")"
|
||||
{"BOL", 0, "" }, // Beginning of string, "^"
|
||||
{"EOL", 0, "" }, // End of string, "$"
|
||||
{"STAR", 1, "o" }, // Match zero or more times "*"
|
||||
{"PLUS", 1, "o" }, // Match one or more times, "+"
|
||||
{"STARQ", 1, "o" }, // Non-greedy STAR, "*?"
|
||||
{"PLUSQ", 1, "o" }, // Non-greedy PLUS, "+?"
|
||||
{"QUEST", 1, "o" }, // Match zero or one time, "?"
|
||||
{"SPACE", 0, "" }, // Match whitespace, "\s"
|
||||
{"NONSPACE", 0, "" }, // Match non-space, "\S"
|
||||
{"DIGIT", 0, "" } // Match digit, "\d"
|
||||
};
|
||||
|
||||
static void print_character_set(FILE *fp, const unsigned char *p, int len) {
|
||||
int i;
|
||||
|
||||
for (i = 0; i < len; i++) {
|
||||
if (i > 0)
|
||||
(void) fputc(',', fp);
|
||||
if (p[i] == 0) {
|
||||
i++;
|
||||
if (p[i] == 0)
|
||||
(void) fprintf(fp, "\\x%02x", p[i]);
|
||||
else
|
||||
(void) fprintf(fp, "%s", opcodes[p[i]].name);
|
||||
} else if (isprint(p[i])) {
|
||||
(void) fputc(p[i], fp);
|
||||
} else {
|
||||
(void) fprintf(fp,"\\x%02x", p[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void dump(const struct slre *r, FILE *fp) {
|
||||
int i, j, ch, op, pc;
|
||||
|
||||
for (pc = 0; pc < r->code_size; pc++) {
|
||||
|
||||
op = r->code[pc];
|
||||
(void) fprintf(fp, "%3d %s ", pc, opcodes[op].name);
|
||||
|
||||
for (i = 0; opcodes[op].flags[i] != '\0'; i++)
|
||||
switch (opcodes[op].flags[i]) {
|
||||
case 'i':
|
||||
fprintf(fp, "%d ", r->code[pc + 1]);
|
||||
pc++;
|
||||
break;
|
||||
case 'o':
|
||||
fprintf(fp, "%d ", pc + r->code[pc + 1] - i);
|
||||
pc++;
|
||||
break;
|
||||
case 'D':
|
||||
print_character_set(fp, r->data +
|
||||
r->code[pc + 1], r->code[pc + 2]);
|
||||
pc += 2;
|
||||
break;
|
||||
case 'd':
|
||||
(void) fputc('"', fp);
|
||||
for (j = 0; j < r->code[pc + 2]; j++) {
|
||||
ch = r->data[r->code[pc + 1] + j];
|
||||
if (isprint(ch))
|
||||
fputc(ch, fp);
|
||||
else
|
||||
fprintf(fp,"\\x%02x",ch);
|
||||
}
|
||||
(void) fputc('"', fp);
|
||||
pc += 2;
|
||||
break;
|
||||
}
|
||||
|
||||
fputc('\n', fp);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int main(void) {
|
||||
static const struct { const char *str, *regex, *msg; } tests[] = {
|
||||
{"aa", ".+", NULL},
|
||||
{"aa", ".", NULL},
|
||||
{"", ".", "No match"},
|
||||
{" cc 1234", "c.\\s\\d+", NULL},
|
||||
};
|
||||
char buf[20];
|
||||
int int_value;
|
||||
const char *msg, *str, *re;
|
||||
size_t i;
|
||||
|
||||
char method[10], uri[100];
|
||||
int http_version_minor, http_version_major;
|
||||
const char *error;
|
||||
const char *request = " \tGET /index.html HTTP/1.0\r\n\r\n";
|
||||
|
||||
error = slre_match(0, "^\\s*(GET|POST)\\s+(\\S+)\\s+HTTP/(\\d)\\.(\\d)",
|
||||
request, strlen(request),
|
||||
SLRE_STRING, sizeof(method), method,
|
||||
SLRE_STRING, sizeof(uri), uri,
|
||||
SLRE_INT, sizeof(http_version_major), &http_version_major,
|
||||
SLRE_INT, sizeof(http_version_minor), &http_version_minor);
|
||||
|
||||
if (error != NULL) {
|
||||
printf("Error parsing HTTP request: %s\n", error);
|
||||
} else {
|
||||
printf("Requested URI: %s\n", uri);
|
||||
}
|
||||
|
||||
for (i = 0; i < sizeof(tests) / sizeof(tests[0]); i++) {
|
||||
msg = slre_match(0, tests[i].regex, tests[i].str,
|
||||
strlen(tests[i].str), NULL);
|
||||
if ((msg != NULL && tests[i].msg == NULL) ||
|
||||
(msg != NULL && strcmp(msg, tests[i].msg) != 0)) {
|
||||
printf("Test %d failed: [%s] [%s] -> [%s]\n", (int) i, tests[i].str,
|
||||
tests[i].regex, msg ? msg : "(null)");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
assert(slre_match(0, "a (\\d+)4\\s*(\\S+)", "aa 1234 xy\nz", 12,
|
||||
SLRE_INT, sizeof(int_value), &int_value,
|
||||
SLRE_STRING, sizeof(buf), buf) == NULL);
|
||||
assert(int_value == 123);
|
||||
assert(!strcmp(buf, "xy"));
|
||||
|
||||
str = "Hello превед!";
|
||||
re = "^hello (\\S+)";
|
||||
assert(strcmp(error_no_match, slre_match(0, re, str, strlen(str), SLRE_STRING,
|
||||
sizeof(buf), buf)) == 0);
|
||||
assert(slre_match(SLRE_CASE_INSENSITIVE, re, str, strlen(str),
|
||||
SLRE_STRING, sizeof(buf), buf) == NULL);
|
||||
assert(!strcmp(buf, "превед!"));
|
||||
|
||||
assert(strcmp(error_no_match, slre_match(0, "bC", "aBc", 3)) == 0);
|
||||
assert(slre_match(SLRE_CASE_INSENSITIVE, "bC", "aBc", 3) == NULL);
|
||||
assert(slre_match(0, "3?9", "9", 1) == NULL);
|
||||
|
||||
// TODO: fix this!
|
||||
//assert(slre_match(0, "9?9", "9", 1) == NULL);
|
||||
|
||||
{
|
||||
struct slre slre;
|
||||
struct cap caps[10];
|
||||
char a[10], b[10];
|
||||
|
||||
memset(caps, 'x', sizeof(caps));
|
||||
slre.options = 0;
|
||||
assert(compile2(&slre, "(\\d(\\d)?)") == NULL);
|
||||
assert(!strcmp(match2(&slre, "1", 1, caps, 2), "Too many brackets"));
|
||||
assert(match2(&slre, "1", 1, caps, 3) == NULL);
|
||||
assert(slre.num_caps == 2);
|
||||
assert(caps[1].len == 1);
|
||||
assert(caps[2].len == 0);
|
||||
assert(caps[1].ptr[0] == '1');
|
||||
|
||||
a[0] = b[0] = 'x';
|
||||
assert(slre_match(0, "(\\d(\\d)?)", "1", 1,
|
||||
SLRE_STRING, sizeof(a), a,
|
||||
SLRE_STRING, sizeof(b), b) == NULL);
|
||||
assert(!strcmp(a, "1"));
|
||||
assert(b[0] == '\0');
|
||||
}
|
||||
|
||||
printf("%s\n", "All tests passed");
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
#endif // SLRE_UNIT_TEST
|
|
@ -1,94 +0,0 @@
|
|||
// Copyright (c) 2004-2012 Sergey Lyubka <valenok@gmail.com>
|
||||
// All rights reserved
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
#ifndef SLRE_HEADER_DEFINED
|
||||
#define SLRE_HEADER_DEFINED
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
// This is a regular expression library that implements a subset of Perl RE.
|
||||
// Please refer to http://slre.googlecode.com for detailed description.
|
||||
//
|
||||
// Supported syntax:
|
||||
// ^ Match beginning of a buffer
|
||||
// $ Match end of a buffer
|
||||
// () Grouping and substring capturing
|
||||
// [...] Match any character from set
|
||||
// [^...] Match any character but ones from set
|
||||
// \s Match whitespace
|
||||
// \S Match non-whitespace
|
||||
// \d Match decimal digit
|
||||
// \r Match carriage return
|
||||
// \n Match newline
|
||||
// + Match one or more times (greedy)
|
||||
// +? Match one or more times (non-greedy)
|
||||
// * Match zero or more times (greedy)
|
||||
// *? Match zero or more times (non-greedy)
|
||||
// ? Match zero or once
|
||||
// \xDD Match byte with hex value 0xDD
|
||||
// \meta Match one of the meta character: ^$().[*+\?
|
||||
|
||||
// Match string buffer "buf" of length "buf_len" against "regexp", which should
|
||||
// conform the syntax outlined above. "options" could be either 0 or
|
||||
// SLRE_CASE_INSENSITIVE for case-insensitive match. If regular expression
|
||||
// "regexp" contains brackets, slre_match() will capture the respective
|
||||
// substring into the passed placeholder. Thus, each opening parenthesis
|
||||
// should correspond to three arguments passed:
|
||||
// placeholder_type, placeholder_size, placeholder_address
|
||||
//
|
||||
// Usage example: parsing HTTP request line.
|
||||
//
|
||||
// char method[10], uri[100];
|
||||
// int http_version_minor, http_version_major;
|
||||
// const char *error;
|
||||
// const char *request = " \tGET /index.html HTTP/1.0\r\n\r\n";
|
||||
|
||||
// error = slre_match(0, "^\\s*(GET|POST)\\s+(\\S+)\\s+HTTP/(\\d)\\.(\\d)",
|
||||
// request, strlen(request),
|
||||
// SLRE_STRING, sizeof(method), method,
|
||||
// SLRE_STRING, sizeof(uri), uri,
|
||||
// SLRE_INT,sizeof(http_version_major),&http_version_major,
|
||||
// SLRE_INT,sizeof(http_version_minor),&http_version_minor);
|
||||
//
|
||||
// if (error != NULL) {
|
||||
// printf("Error parsing HTTP request: %s\n", error);
|
||||
// } else {
|
||||
// printf("Requested URI: %s\n", uri);
|
||||
// }
|
||||
//
|
||||
//
|
||||
// Return:
|
||||
// NULL: string matched and all captures successfully made
|
||||
// non-NULL: in this case, the return value is an error string
|
||||
|
||||
enum slre_option {SLRE_CASE_INSENSITIVE = 1};
|
||||
enum slre_capture {SLRE_STRING, SLRE_INT, SLRE_FLOAT};
|
||||
|
||||
const char *slre_match(enum slre_option options, const char *regexp,
|
||||
const char *buf, int buf_len, ...);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif // __cplusplus
|
||||
|
||||
#endif // SLRE_HEADER_DEFINED
|
|
@ -25,12 +25,13 @@ vars_add_var is able to add another var with the same name
|
|||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
//#include <stdlib.h>
|
||||
//#include <string.h>
|
||||
#include "misc/memutil.h"
|
||||
#include "misc/strutil.h"
|
||||
#include "misc/vars.h"
|
||||
#include "misc/log.h"
|
||||
#include <klib.h>
|
||||
|
||||
vars_t *vars_create()
|
||||
{
|
||||
|
@ -47,6 +48,7 @@ void vars_destroy(vars_t *vs)
|
|||
mem_free(vs);
|
||||
}
|
||||
|
||||
#if 0
|
||||
vars_t *vars_load(char *filename)
|
||||
{
|
||||
vars_t *ret = 0;
|
||||
|
@ -113,6 +115,10 @@ int vars_save(vars_t *vs,char *filename)
|
|||
vs->changed = 0;
|
||||
return(0);
|
||||
}
|
||||
#endif
|
||||
|
||||
vars_t *vars_load(char *filename) { return NULL; }
|
||||
int vars_save(vars_t *vs,char *filename) { return 1; }
|
||||
|
||||
void vars_merge(vars_t *dest,vars_t *src)
|
||||
{
|
||||
|
@ -220,8 +226,11 @@ int vars_get_bool(vars_t *vs,char *name,int def)
|
|||
|
||||
double vars_get_double(vars_t *vs,char *name,double def)
|
||||
{
|
||||
#if 0
|
||||
sprintf(tmpstr,"%f",def);
|
||||
return(atof(vars_get_string(vs,name,tmpstr)));
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
var_t *vars_set_string(vars_t *vs,int flags,char *name,char *data)
|
||||
|
|
|
@ -28,6 +28,7 @@
|
|||
#include "misc/strutil.h"
|
||||
#include "mappers/mapperid.h"
|
||||
|
||||
#if 0
|
||||
static int loadbios(cart_t *ret,char *filename)
|
||||
{
|
||||
FILE *fp;
|
||||
|
@ -81,6 +82,9 @@ static int loadbios(cart_t *ret,char *filename)
|
|||
//success
|
||||
return(0);
|
||||
}
|
||||
#endif
|
||||
|
||||
static int loadbios(cart_t *ret,char *filename) { return -1; }
|
||||
|
||||
//makes the size a multiple of 4096 for padding
|
||||
//static u32 padsize(u32 size)
|
||||
|
|
|
@ -37,7 +37,7 @@ typedef struct codedata_s {
|
|||
} codedata_t;
|
||||
|
||||
//ines ident for determining if the genie rom has ines header
|
||||
static u8 inesident[4] = {'N','E','S',0x1A};
|
||||
//static u8 inesident[4] = {'N','E','S',0x1A};
|
||||
|
||||
//genie rom image (prg + chr)
|
||||
static u8 *genierom = 0;
|
||||
|
@ -132,6 +132,7 @@ static void genie_write(u32 addr,u8 data)
|
|||
}
|
||||
}
|
||||
|
||||
#if 0
|
||||
int genie_loadrom(char *filename)
|
||||
{
|
||||
FILE *fp;
|
||||
|
@ -192,6 +193,9 @@ int genie_loadrom(char *filename)
|
|||
log_printf("genie_load: loaded game genie rom '%s' (%d bytes)\n",filename,len);
|
||||
return(0);
|
||||
}
|
||||
#endif
|
||||
|
||||
int genie_loadrom(char *filename) { return 1; }
|
||||
|
||||
int genie_load()
|
||||
{
|
||||
|
|
|
@ -21,7 +21,7 @@
|
|||
#ifndef __state_h__
|
||||
#define __state_h__
|
||||
|
||||
#include <stdio.h>
|
||||
#include <klib.h>
|
||||
#include "nes/state/block.h"
|
||||
|
||||
#define STATE_LOAD 0 //load state
|
||||
|
|
|
@ -1,171 +0,0 @@
|
|||
/***************************************************************************
|
||||
* Copyright (C) 2013 by James Holodnak *
|
||||
* jamesholodnak@gmail.com *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with this program; if not, write to the *
|
||||
* Free Software Foundation, Inc., *
|
||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
|
||||
***************************************************************************/
|
||||
|
||||
//palette generator borrowed from nintendulator
|
||||
|
||||
#include <math.h>
|
||||
#include "palette/palette.h"
|
||||
|
||||
#ifndef M_PI
|
||||
#define M_PI 3.14159f
|
||||
#endif
|
||||
|
||||
#define CLIP(x,min,max) (((x) > (max)) ? (max) : (((x) < (min)) ? (min) : (x)))
|
||||
|
||||
static int getPhase (double *wave)
|
||||
{
|
||||
double max = -999, min = 999;
|
||||
double amp, offset;
|
||||
double angle = 0, base;
|
||||
int i, j, k;
|
||||
for (i = 0; i < 12; i++)
|
||||
{
|
||||
if (wave[i] > max)
|
||||
max = wave[i];
|
||||
if (wave[i] < min)
|
||||
min = wave[i];
|
||||
}
|
||||
amp = (max - min) / 2;
|
||||
offset = (max + min) / 2;
|
||||
|
||||
for (k = 0; k < 3; k++)
|
||||
{
|
||||
double error[12], curerror = 0;
|
||||
double segsize = 360;
|
||||
for (i = 0; i <= k; i++)
|
||||
segsize /= 12.0;
|
||||
|
||||
for (j = 0; j < 12; j++)
|
||||
{
|
||||
error[j] = 0;
|
||||
for (i = 0; i < 12; i++)
|
||||
error[j] += fabs((amp * sin((i * 30 + j * segsize + angle) * M_PI / 180.0) + offset) - wave[i]);
|
||||
curerror += error[j];
|
||||
}
|
||||
base = 0;
|
||||
for (j = 0; j < 12; j++)
|
||||
{
|
||||
if (error[j] < curerror)
|
||||
{
|
||||
base = j * segsize;
|
||||
curerror = error[j];
|
||||
}
|
||||
}
|
||||
angle += base;
|
||||
}
|
||||
|
||||
return (int)angle;
|
||||
}
|
||||
|
||||
static void GenerateNTSC(palette_t *palette,int hue,int sat)
|
||||
{
|
||||
const double black = 0.519;
|
||||
const double white = 1.443;
|
||||
const double voltage[2][4] = {{1.094,1.506,1.962,1.962},{0.350,0.519,0.962,1.550}};
|
||||
|
||||
const char phases[12][12] = {
|
||||
{1,1,1,1,1,1,0,0,0,0,0,0},
|
||||
{1,1,1,1,1,0,0,0,0,0,0,1}, // blue
|
||||
{1,1,1,1,0,0,0,0,0,0,1,1},
|
||||
{1,1,1,0,0,0,0,0,0,1,1,1}, // magenta
|
||||
{1,1,0,0,0,0,0,0,1,1,1,1},
|
||||
{1,0,0,0,0,0,0,1,1,1,1,1}, // red
|
||||
{0,0,0,0,0,0,1,1,1,1,1,1},
|
||||
{0,0,0,0,0,1,1,1,1,1,1,0}, // yellow
|
||||
{0,0,0,0,1,1,1,1,1,1,0,0},
|
||||
{0,0,0,1,1,1,1,1,1,0,0,0}, // green
|
||||
{0,0,1,1,1,1,1,1,0,0,0,0},
|
||||
{0,1,1,1,1,1,1,0,0,0,0,0}, // cyan
|
||||
};
|
||||
const char emphasis[8][12] = {
|
||||
{0,0,0,0,0,0,0,0,0,0,0,0}, // none
|
||||
{0,1,1,1,1,1,1,0,0,0,0,0}, // red
|
||||
{1,1,1,0,0,0,0,0,0,1,1,1}, // green
|
||||
{1,1,1,1,1,1,1,0,0,1,1,1}, // yellow
|
||||
{0,0,0,0,0,1,1,1,1,1,1,0}, // blue
|
||||
{0,1,1,1,1,1,1,1,1,1,1,0}, // magenta
|
||||
{1,1,1,0,0,1,1,1,1,1,1,1}, // cyan
|
||||
{1,1,1,1,1,1,1,1,1,1,1,1} // all
|
||||
};
|
||||
|
||||
int i, x, y, z;
|
||||
for (x = 0; x < 8; x++)
|
||||
{
|
||||
for (y = 0; y < 4; y++)
|
||||
{
|
||||
for (z = 0; z < 16; z++)
|
||||
{
|
||||
double wave[12];
|
||||
double Y, I, Q;
|
||||
double R, G, B;
|
||||
|
||||
double H = 0, S = 0;
|
||||
|
||||
for (i = 0; i < 12; i++)
|
||||
{
|
||||
if (z == 0)
|
||||
wave[i] = voltage[0][y];
|
||||
else if (z < 13)
|
||||
wave[i] = phases[z-1][i] ? voltage[0][y] : voltage[1][y];
|
||||
else if (z == 13)
|
||||
wave[i] = voltage[1][y];
|
||||
else wave[i] = black;
|
||||
if ((emphasis[x][i]) && (z < 14))
|
||||
wave[i] = wave[i] * 0.75;
|
||||
}
|
||||
|
||||
Y = 0.0; S = 0;
|
||||
for (i = 0; i < 12; i++)
|
||||
Y += wave[i] / 12.0;
|
||||
for (i = 0; i < 12; i++)
|
||||
S += (wave[i] - Y) * (wave[i] - Y);
|
||||
Y = (Y - black) / white;
|
||||
S = S / white; // don't remove black offset, since this is already relative
|
||||
S = sqrt(S / 12.0) * sat / 50.0;
|
||||
|
||||
H = M_PI * (270 + getPhase(wave) + hue) / 180.0;
|
||||
|
||||
I = S * sin(H);
|
||||
Q = S * cos(H);
|
||||
|
||||
R = Y + 0.956 * I + 0.621 * Q;
|
||||
G = Y - 0.272 * I - 0.647 * Q;
|
||||
B = Y - 1.107 * I + 1.705 * Q;
|
||||
|
||||
R *= 256;
|
||||
G *= 256;
|
||||
B *= 256;
|
||||
|
||||
palette->pal[x][(y << 4) | z].r = (unsigned char)CLIP(R,0,255);
|
||||
palette->pal[x][(y << 4) | z].g = (unsigned char)CLIP(G,0,255);
|
||||
palette->pal[x][(y << 4) | z].b = (unsigned char)CLIP(B,0,255);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
palette_t *palette_generate(int hue,int sat) //generate nes palette
|
||||
{
|
||||
palette_t *ret = 0;
|
||||
|
||||
ret = palette_create();
|
||||
GenerateNTSC(ret,hue,sat);
|
||||
return(ret);
|
||||
}
|
|
@ -1,28 +0,0 @@
|
|||
/***************************************************************************
|
||||
* Copyright (C) 2013 by James Holodnak *
|
||||
* jamesholodnak@gmail.com *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with this program; if not, write to the *
|
||||
* Free Software Foundation, Inc., *
|
||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef __generator_h__
|
||||
#define __generator_h__
|
||||
|
||||
#include "palette/palette.h"
|
||||
|
||||
palette_t *palette_generate(int hue,int sat);
|
||||
|
||||
#endif
|
|
@ -18,20 +18,104 @@
|
|||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
|
||||
***************************************************************************/
|
||||
|
||||
#include "palette/palette.h"
|
||||
#include <stdio.h>
|
||||
#include "system/video.h"
|
||||
#if 0
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "misc/memutil.h"
|
||||
#include "misc/strutil.h"
|
||||
#include "misc/log.h"
|
||||
#include "misc/config.h"
|
||||
#include "palette/palette.h"
|
||||
#include "palette/generator.h"
|
||||
#include "system/video.h"
|
||||
#include "misc/paths.h"
|
||||
#endif
|
||||
|
||||
static palette_t *pal = 0;
|
||||
static palette_t pal = {{
|
||||
{
|
||||
0x00666666,0x00723700,0x00a51d00,0x00ad003d,0x00850060,0x00420073,0x00000571,0x00001d5a,
|
||||
0x00003634,0x00004b0a,0x00005500,0x00055200,0x002b4b00,0x00000000,0x00000000,0x00000000,
|
||||
0x00afafaf,0x00e6600f,0x00ff3e41,0x00ff2378,0x00d815a7,0x007f1ac1,0x001c2ebe,0x00004e9f,
|
||||
0x0000706d,0x00008c36,0x00009907,0x002f9500,0x00618c00,0x00000000,0x00000000,0x00000000,
|
||||
0x00ffffff,0x00ffc14b,0x00ff9e75,0x00ff72c9,0x00ff64f8,0x00cf68ff,0x009d71ff,0x00169ef0,
|
||||
0x0000c0be,0x0000dc85,0x0024e956,0x007ee53c,0x00e3d03f,0x004e4e4e,0x00000000,0x00000000,
|
||||
0x00ffffff,0x00ffe6b5,0x00ffd7c7,0x00ffcadd,0x00ffc1f3,0x00ecc1ff,0x00d7c5ff,0x00afd0ff,
|
||||
0x008ce5e4,0x008becd9,0x0098f5c2,0x00caf5af,0x00dff1ae,0x00b6b6b6,0x00000000,0x00000000,
|
||||
},
|
||||
{
|
||||
0x004a3f6b,0x00660f00,0x008a000e,0x00890037,0x00760052,0x0039006d,0x00000072,0x00000461,
|
||||
0x0000114a,0x00002523,0x00003200,0x00003300,0x00281f00,0x00000000,0x00000000,0x00000000,
|
||||
0x008979b6,0x00b1370f,0x00dd1f3b,0x00dd0b6f,0x00c50394,0x007306b9,0x004010c5,0x00002ca8,
|
||||
0x00003e89,0x00005855,0x00006921,0x00006a00,0x003c5600,0x00000002,0x00000000,0x00000000,
|
||||
0x00cfbaff,0x00fa785f,0x00ff569f,0x00ff4ac2,0x00ff43e0,0x00bd46ff,0x00854fff,0x001d6cfb,
|
||||
0x000083d5,0x00009f9c,0x0000a284,0x0031ae41,0x00809744,0x00362c53,0x00000000,0x00000000,
|
||||
0x00cfbaff,0x00e99cc4,0x00f093d9,0x00fe8ee2,0x00d08dfc,0x00d589ff,0x00b08eff,0x008b99ff,
|
||||
0x0070a4f2,0x0061afde,0x0066b3ce,0x0071bab8,0x00afabb8,0x00907fbe,0x00000000,0x00000000,
|
||||
},
|
||||
{
|
||||
0x00215e3d,0x003d3000,0x006b1600,0x00790009,0x00490031,0x0017004a,0x0000004d,0x0000153b,
|
||||
0x00002927,0x00004300,0x00005300,0x00004d00,0x00004300,0x00000000,0x00000000,0x00000000,
|
||||
0x0050a577,0x00776600,0x00b44401,0x00c71f37,0x00850d67,0x003e1089,0x0000248c,0x00004375,
|
||||
0x00005d5b,0x00008024,0x00009600,0x00008e00,0x00238100,0x00000000,0x00000000,0x00000000,
|
||||
0x0084f2b7,0x00c0ae23,0x00cf9d32,0x00ff6878,0x00cf5c9a,0x00735bcb,0x00097bc0,0x000091b3,
|
||||
0x0000a5a2,0x0000cb67,0x0000e42d,0x001ddb20,0x0066cb18,0x0011482a,0x00000000,0x00000000,
|
||||
0x0084f2b7,0x009dd877,0x00abce7f,0x00c6bf8e,0x00a3b4ab,0x0078b3c3,0x0059bebd,0x0047c3c1,
|
||||
0x003cd89f,0x002fde9e,0x0050ee78,0x0058e87c,0x007be176,0x0055ac7d,0x00000000,0x00000000,
|
||||
},
|
||||
{
|
||||
0x001a3f47,0x00371700,0x00620200,0x00690018,0x004b0031,0x0021004a,0x0000004d,0x0000053d,
|
||||
0x00001d1b,0x0000240e,0x00002f00,0x00003100,0x00082300,0x00000000,0x00000000,0x00000000,
|
||||
0x00417e7d,0x006e4400,0x00a8280b,0x00b00946,0x008a0067,0x00520088,0x0000198c,0x00002d77,
|
||||
0x00004c4a,0x00005639,0x00006517,0x00006800,0x00295600,0x00000000,0x00000000,0x00000000,
|
||||
0x0071c0bf,0x00978925,0x00e5674b,0x00e6458e,0x00c73fa5,0x00933ccb,0x000d5bcd,0x00006cbb,
|
||||
0x00008d8a,0x00009974,0x0000a854,0x001ca922,0x00569723,0x00082f2f,0x00000000,0x00000000,
|
||||
0x0071c0bf,0x00aba678,0x00d3938d,0x00d086a7,0x00b484b7,0x007e87ca,0x004896c6,0x003a9fba,
|
||||
0x002eaaa9,0x002eaaa9,0x002cb398,0x0050b77d,0x0077ae7c,0x004b808b,0x00000000,0x00000000,
|
||||
},
|
||||
{
|
||||
0x007d4b40,0x008b2000,0x00ac1500,0x00b2001e,0x009d0032,0x006c004b,0x002a0053,0x00000045,
|
||||
0x00001716,0x00002e00,0x00003b00,0x000f3a00,0x00433500,0x00000000,0x00000000,0x00000000,
|
||||
0x00cf8a7b,0x00e15200,0x00ff4214,0x00ff1d4e,0x00f90f69,0x00b7048a,0x005e0a95,0x0000237f,
|
||||
0x00004544,0x00006514,0x00007400,0x003a7400,0x00806d00,0x000b0000,0x00000000,0x00000000,
|
||||
0x00ffd0bc,0x00ff9839,0x00ff7275,0x00ff628e,0x00ff50b2,0x00ff47d4,0x00d94ad0,0x004667c4,
|
||||
0x001a8887,0x0010ab53,0x0061b729,0x0097b81e,0x00cab61c,0x0063372d,0x00000000,0x00000000,
|
||||
0x00ffd0bc,0x00ffbe82,0x00ffb291,0x00ffa4a6,0x00ff9bb9,0x00ff96c7,0x00ff97ca,0x00dc9acd,
|
||||
0x00bdafac,0x00b2c38c,0x00cfc682,0x00d6cc79,0x00ffbc86,0x00d79181,0x00000000,0x00000000,
|
||||
},
|
||||
{
|
||||
0x005e3049,0x00610e00,0x008f0009,0x00890022,0x007a0034,0x0051004a,0x00270054,0x00000041,
|
||||
0x00000922,0x00001908,0x00002a00,0x00002700,0x00261c00,0x00000000,0x00000000,0x00000000,
|
||||
0x00a56688,0x00a73900,0x00e51532,0x00dc0554,0x00ab007f,0x00920089,0x005a0096,0x00001d7c,
|
||||
0x00003057,0x00004731,0x00005d00,0x00115a00,0x00584b00,0x00000000,0x00000000,0x00000000,
|
||||
0x00f3a0cd,0x00eb7833,0x00ff4d7a,0x00ff4195,0x00f334c3,0x00d333d0,0x009c38dc,0x002157c1,
|
||||
0x0006689d,0x00007f7d,0x00139b35,0x00649522,0x00978925,0x00481f35,0x00000000,0x00000000,
|
||||
0x00f3a0cd,0x00f28e90,0x00ff7daf,0x00fc78bc,0x00e775ca,0x00e775ca,0x00ce75d4,0x009282cd,
|
||||
0x007890b6,0x005da1a0,0x0061ab8a,0x0093ab76,0x00b6a27a,0x00ac6b8e,0x00000000,0x00000000,
|
||||
},
|
||||
{
|
||||
0x00494528,0x00492100,0x006d1200,0x007f000c,0x005f0024,0x003d0037,0x00010040,0x0000012d,
|
||||
0x00001412,0x00002900,0x00003900,0x00003600,0x00123000,0x00000000,0x00000000,0x00000000,
|
||||
0x007a8658,0x00885200,0x00b83e00,0x00cf1136,0x00a70452,0x0077006f,0x0027087b,0x00002861,
|
||||
0x0000403e,0x00005d16,0x00007200,0x00116d00,0x006c5a00,0x00000000,0x00000000,0x00000000,
|
||||
0x00bbcb8f,0x00d39119,0x00ff7d2d,0x00ff526f,0x00eb4787,0x00c73fa5,0x006648b8,0x00006d97,
|
||||
0x00007f7d,0x00009e54,0x001fb516,0x004db10d,0x007ea80b,0x002c3417,0x00000000,0x00000000,
|
||||
0x00bbcb8f,0x00beb360,0x00d9ab67,0x00ec9585,0x00d68b9c,0x00c284b2,0x009e86bb,0x006698ac,
|
||||
0x005ba39b,0x005eb974,0x0084bf5e,0x009ebb5d,0x00a1ba5d,0x00808d5e,0x00000000,0x00000000,
|
||||
},
|
||||
{
|
||||
0x00353535,0x00540900,0x006e0000,0x006b0016,0x004c0031,0x001a003f,0x0000003e,0x00000037,
|
||||
0x00001210,0x00002100,0x00002900,0x00002600,0x00092100,0x00000000,0x00000000,0x00000000,
|
||||
0x006c6c6c,0x00953100,0x00b71719,0x00b30343,0x008b0066,0x00480079,0x00000c77,0x00002360,
|
||||
0x00003d3b,0x00005211,0x00005c00,0x000c5800,0x00325200,0x00000000,0x00000000,0x00000000,
|
||||
0x00a8a8a8,0x00b67a21,0x00e86041,0x00f8476a,0x00e13793,0x008437b6,0x005e3eb8,0x00005f9d,
|
||||
0x00007977,0x00008e4d,0x00049829,0x00489516,0x006e8e14,0x00232323,0x00000000,0x00000000,
|
||||
0x00a8a8a8,0x00ae9571,0x00c38a7e,0x00c9808f,0x00c07a9f,0x00a878ab,0x008a7daf,0x006c85a9,
|
||||
0x0057909c,0x00549e83,0x005ba07b,0x0072a26f,0x00a09a6d,0x00727272,0x00000000,0x00000000,
|
||||
}
|
||||
}};
|
||||
|
||||
#if 0
|
||||
/* measurement by Quietust */
|
||||
static const double emphasis_factor[8][3]={
|
||||
{1.00, 1.00, 1.00},
|
||||
|
@ -57,15 +141,6 @@ static void generate_emphasis(palette_t *p)
|
|||
}
|
||||
}
|
||||
|
||||
palette_t *palette_create()
|
||||
{
|
||||
palette_t *ret = 0;
|
||||
|
||||
ret = (palette_t*)mem_alloc(sizeof(palette_t));
|
||||
memset(ret,0,sizeof(palette_t));
|
||||
return(ret);
|
||||
}
|
||||
|
||||
void palette_destroy(palette_t *p)
|
||||
{
|
||||
mem_free(p);
|
||||
|
@ -107,6 +182,20 @@ int palette_save(char *filename,palette_t *p)
|
|||
return(1);
|
||||
}
|
||||
|
||||
void palette_kill()
|
||||
{
|
||||
palette_destroy(pal);
|
||||
}
|
||||
|
||||
palette_t *palette_create()
|
||||
{
|
||||
palette_t *ret = 0;
|
||||
|
||||
ret = (palette_t*)mem_alloc(sizeof(palette_t));
|
||||
memset(ret,0,sizeof(palette_t));
|
||||
return(ret);
|
||||
}
|
||||
|
||||
int palette_init()
|
||||
{
|
||||
char file[1024];
|
||||
|
@ -129,11 +218,17 @@ int palette_init()
|
|||
if(pal == 0) {
|
||||
pal = palette_generate(config_get_int("palette.hue"),config_get_int("palette.saturation"));
|
||||
}
|
||||
video_setpalette(pal);
|
||||
video_setpalette(&pal);
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
void palette_kill()
|
||||
{
|
||||
palette_destroy(pal);
|
||||
#endif
|
||||
|
||||
palette_t *palette_load(char *filename) { return NULL; }
|
||||
int palette_save(char *filename,palette_t *p) {return 1; }
|
||||
int palette_init() {
|
||||
video_setpalette(&pal);
|
||||
return 0;
|
||||
}
|
||||
void palette_kill() { }
|
||||
|
|
|
@ -23,12 +23,15 @@
|
|||
|
||||
#include "types.h"
|
||||
|
||||
typedef struct palentry_s {
|
||||
u8 r,g,b;
|
||||
typedef union palentry_s {
|
||||
struct {
|
||||
u8 r,g,b;
|
||||
};
|
||||
u32 val;
|
||||
} palentry_t;
|
||||
|
||||
typedef struct palette_s {
|
||||
palentry_t pal[8][64];
|
||||
u32 pal[8][64];
|
||||
} palette_t;
|
||||
|
||||
palette_t *palette_create();
|
||||
|
|
|
@ -0,0 +1,2 @@
|
|||
*.c
|
||||
*.h
|
|
@ -0,0 +1 @@
|
|||
../../../litenes/src/roms/build-roms.py
|
|
@ -0,0 +1 @@
|
|||
../../../litenes/src/roms/rom
|
|
@ -1,192 +0,0 @@
|
|||
/* NES NTSC video filter */
|
||||
|
||||
/* nes_ntsc 0.2.2 */
|
||||
#ifndef NES_NTSC_H
|
||||
#define NES_NTSC_H
|
||||
|
||||
#include "nes_ntsc_config.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Image parameters, ranging from -1.0 to 1.0. Actual internal values shown
|
||||
in parenthesis and should remain fairly stable in future versions. */
|
||||
typedef struct nes_ntsc_setup_t
|
||||
{
|
||||
/* Basic parameters */
|
||||
double hue; /* -1 = -180 degrees +1 = +180 degrees */
|
||||
double saturation; /* -1 = grayscale (0.0) +1 = oversaturated colors (2.0) */
|
||||
double contrast; /* -1 = dark (0.5) +1 = light (1.5) */
|
||||
double brightness; /* -1 = dark (0.5) +1 = light (1.5) */
|
||||
double sharpness; /* edge contrast enhancement/blurring */
|
||||
|
||||
/* Advanced parameters */
|
||||
double gamma; /* -1 = dark (1.5) +1 = light (0.5) */
|
||||
double resolution; /* image resolution */
|
||||
double artifacts; /* artifacts caused by color changes */
|
||||
double fringing; /* color artifacts caused by brightness changes */
|
||||
double bleed; /* color bleed (color resolution reduction) */
|
||||
int merge_fields; /* if 1, merges even and odd fields together to reduce flicker */
|
||||
float const* decoder_matrix; /* optional RGB decoder matrix, 6 elements */
|
||||
|
||||
unsigned char* palette_out; /* optional RGB palette out, 3 bytes per color */
|
||||
|
||||
/* You can replace the standard NES color generation with an RGB palette. The
|
||||
first replaces all color generation, while the second replaces only the core
|
||||
64-color generation and does standard color emphasis calculations on it. */
|
||||
unsigned char const* palette;/* optional 512-entry RGB palette in, 3 bytes per color */
|
||||
unsigned char const* base_palette;/* optional 64-entry RGB palette in, 3 bytes per color */
|
||||
} nes_ntsc_setup_t;
|
||||
|
||||
/* Video format presets */
|
||||
extern nes_ntsc_setup_t const nes_ntsc_composite; /* color bleeding + artifacts */
|
||||
extern nes_ntsc_setup_t const nes_ntsc_svideo; /* color bleeding only */
|
||||
extern nes_ntsc_setup_t const nes_ntsc_rgb; /* crisp image */
|
||||
extern nes_ntsc_setup_t const nes_ntsc_monochrome;/* desaturated + artifacts */
|
||||
|
||||
#ifdef NES_NTSC_EMPHASIS
|
||||
enum { nes_ntsc_palette_size = 64 * 8 };
|
||||
#else
|
||||
enum { nes_ntsc_palette_size = 64 };
|
||||
#endif
|
||||
|
||||
/* Initializes and adjusts parameters. Can be called multiple times on the same
|
||||
nes_ntsc_t object. Can pass NULL for either parameter. */
|
||||
typedef struct nes_ntsc_t nes_ntsc_t;
|
||||
void nes_ntsc_init( nes_ntsc_t* ntsc, nes_ntsc_setup_t const* setup );
|
||||
|
||||
/* Filters one or more rows of pixels. Input pixels are 6/9-bit palette indicies.
|
||||
In_row_width is the number of pixels to get to the next input row. Out_pitch
|
||||
is the number of *bytes* to get to the next output row. Output pixel format
|
||||
is set by NES_NTSC_OUT_DEPTH (defaults to 16-bit RGB). */
|
||||
void nes_ntsc_blit( nes_ntsc_t const* ntsc, NES_NTSC_IN_T const* nes_in,
|
||||
long in_row_width, int burst_phase, int in_width, int in_height,
|
||||
void* rgb_out, long out_pitch );
|
||||
|
||||
/* Number of output pixels written by blitter for given input width. Width might
|
||||
be rounded down slightly; use NES_NTSC_IN_WIDTH() on result to find rounded
|
||||
value. Guaranteed not to round 256 down at all. */
|
||||
#define NES_NTSC_OUT_WIDTH( in_width ) \
|
||||
((((in_width) - 1) / nes_ntsc_in_chunk + 1) * nes_ntsc_out_chunk)
|
||||
|
||||
/* Number of input pixels that will fit within given output width. Might be
|
||||
rounded down slightly; use NES_NTSC_OUT_WIDTH() on result to find rounded
|
||||
value. */
|
||||
#define NES_NTSC_IN_WIDTH( out_width ) \
|
||||
(((out_width) / nes_ntsc_out_chunk - 1) * nes_ntsc_in_chunk + 1)
|
||||
|
||||
|
||||
/* Interface for user-defined custom blitters */
|
||||
|
||||
enum { nes_ntsc_in_chunk = 3 }; /* number of input pixels read per chunk */
|
||||
enum { nes_ntsc_out_chunk = 7 }; /* number of output pixels generated per chunk */
|
||||
enum { nes_ntsc_black = 15 }; /* palette index for black */
|
||||
enum { nes_ntsc_burst_count = 3 }; /* burst phase cycles through 0, 1, and 2 */
|
||||
|
||||
/* Begins outputting row and starts three pixels. First pixel will be cut off a bit.
|
||||
Use nes_ntsc_black for unused pixels. Declares variables, so must be before first
|
||||
statement in a block (unless you're using C++). */
|
||||
#define NES_NTSC_BEGIN_ROW( ntsc, burst, pixel0, pixel1, pixel2 ) \
|
||||
char const* const ktable = \
|
||||
(char const*) (ntsc)->table [0] + burst * (nes_ntsc_burst_size * sizeof (nes_ntsc_rgb_t));\
|
||||
NES_NTSC_BEGIN_ROW_6_( pixel0, pixel1, pixel2, NES_NTSC_ENTRY_, ktable )
|
||||
|
||||
/* Begins input pixel */
|
||||
#define NES_NTSC_COLOR_IN( in_index, color_in ) \
|
||||
NES_NTSC_COLOR_IN_( in_index, color_in, NES_NTSC_ENTRY_, ktable )
|
||||
|
||||
/* Generates output pixel. Bits can be 24, 16, 15, 32 (treated as 24), or 0:
|
||||
24: RRRRRRRR GGGGGGGG BBBBBBBB (8-8-8 RGB)
|
||||
16: RRRRRGGG GGGBBBBB (5-6-5 RGB)
|
||||
15: RRRRRGG GGGBBBBB (5-5-5 RGB)
|
||||
0: xxxRRRRR RRRxxGGG GGGGGxxB BBBBBBBx (native internal format; x = junk bits) */
|
||||
#define NES_NTSC_RGB_OUT( index, rgb_out, bits ) \
|
||||
NES_NTSC_RGB_OUT_14_( index, rgb_out, bits, 0 )
|
||||
|
||||
|
||||
/* private */
|
||||
enum { nes_ntsc_entry_size = 128 };
|
||||
typedef unsigned long nes_ntsc_rgb_t;
|
||||
struct nes_ntsc_t {
|
||||
nes_ntsc_rgb_t table [nes_ntsc_palette_size] [nes_ntsc_entry_size];
|
||||
};
|
||||
enum { nes_ntsc_burst_size = nes_ntsc_entry_size / nes_ntsc_burst_count };
|
||||
|
||||
#define NES_NTSC_ENTRY_( ktable, n ) \
|
||||
(nes_ntsc_rgb_t const*) (ktable + (n) * (nes_ntsc_entry_size * sizeof (nes_ntsc_rgb_t)))
|
||||
|
||||
/* deprecated */
|
||||
#define NES_NTSC_RGB24_OUT( x, out ) NES_NTSC_RGB_OUT( x, out, 24 )
|
||||
#define NES_NTSC_RGB16_OUT( x, out ) NES_NTSC_RGB_OUT( x, out, 16 )
|
||||
#define NES_NTSC_RGB15_OUT( x, out ) NES_NTSC_RGB_OUT( x, out, 15 )
|
||||
#define NES_NTSC_RAW_OUT( x, out ) NES_NTSC_RGB_OUT( x, out, 0 )
|
||||
|
||||
enum { nes_ntsc_min_in_width = 256 };
|
||||
enum { nes_ntsc_min_out_width = NES_NTSC_OUT_WIDTH( nes_ntsc_min_in_width ) };
|
||||
|
||||
enum { nes_ntsc_640_in_width = 271 };
|
||||
enum { nes_ntsc_640_out_width = NES_NTSC_OUT_WIDTH( nes_ntsc_640_in_width ) };
|
||||
enum { nes_ntsc_640_overscan_left = 8 };
|
||||
enum { nes_ntsc_640_overscan_right = nes_ntsc_640_in_width - 256 - nes_ntsc_640_overscan_left };
|
||||
|
||||
enum { nes_ntsc_full_in_width = 283 };
|
||||
enum { nes_ntsc_full_out_width = NES_NTSC_OUT_WIDTH( nes_ntsc_full_in_width ) };
|
||||
enum { nes_ntsc_full_overscan_left = 16 };
|
||||
enum { nes_ntsc_full_overscan_right = nes_ntsc_full_in_width - 256 - nes_ntsc_full_overscan_left };
|
||||
|
||||
/* common 3->7 ntsc macros */
|
||||
#define NES_NTSC_BEGIN_ROW_6_( pixel0, pixel1, pixel2, ENTRY, table ) \
|
||||
unsigned const nes_ntsc_pixel0_ = (pixel0);\
|
||||
nes_ntsc_rgb_t const* kernel0 = ENTRY( table, nes_ntsc_pixel0_ );\
|
||||
unsigned const nes_ntsc_pixel1_ = (pixel1);\
|
||||
nes_ntsc_rgb_t const* kernel1 = ENTRY( table, nes_ntsc_pixel1_ );\
|
||||
unsigned const nes_ntsc_pixel2_ = (pixel2);\
|
||||
nes_ntsc_rgb_t const* kernel2 = ENTRY( table, nes_ntsc_pixel2_ );\
|
||||
nes_ntsc_rgb_t const* kernelx0;\
|
||||
nes_ntsc_rgb_t const* kernelx1 = kernel0;\
|
||||
nes_ntsc_rgb_t const* kernelx2 = kernel0
|
||||
|
||||
#define NES_NTSC_RGB_OUT_14_( x, rgb_out, bits, shift ) {\
|
||||
nes_ntsc_rgb_t raw_ =\
|
||||
kernel0 [x ] + kernel1 [(x+12)%7+14] + kernel2 [(x+10)%7+28] +\
|
||||
kernelx0 [(x+7)%14] + kernelx1 [(x+ 5)%7+21] + kernelx2 [(x+ 3)%7+35];\
|
||||
NES_NTSC_CLAMP_( raw_, shift );\
|
||||
NES_NTSC_RGB_OUT_( rgb_out, bits, shift );\
|
||||
}
|
||||
|
||||
/* common ntsc macros */
|
||||
#define nes_ntsc_rgb_builder ((1L << 21) | (1 << 11) | (1 << 1))
|
||||
#define nes_ntsc_clamp_mask (nes_ntsc_rgb_builder * 3 / 2)
|
||||
#define nes_ntsc_clamp_add (nes_ntsc_rgb_builder * 0x101)
|
||||
#define NES_NTSC_CLAMP_( io, shift ) {\
|
||||
nes_ntsc_rgb_t sub = (io) >> (9-(shift)) & nes_ntsc_clamp_mask;\
|
||||
nes_ntsc_rgb_t clamp = nes_ntsc_clamp_add - sub;\
|
||||
io |= clamp;\
|
||||
clamp -= sub;\
|
||||
io &= clamp;\
|
||||
}
|
||||
|
||||
#define NES_NTSC_COLOR_IN_( index, color, ENTRY, table ) {\
|
||||
unsigned color_;\
|
||||
kernelx##index = kernel##index;\
|
||||
kernel##index = (color_ = (color), ENTRY( table, color_ ));\
|
||||
}
|
||||
|
||||
/* x is always zero except in snes_ntsc library */
|
||||
#define NES_NTSC_RGB_OUT_( rgb_out, bits, x ) {\
|
||||
if ( bits == 16 )\
|
||||
rgb_out = (raw_>>(13-x)& 0xF800)|(raw_>>(8-x)&0x07E0)|(raw_>>(4-x)&0x001F);\
|
||||
if ( bits == 24 || bits == 32 )\
|
||||
rgb_out = (raw_>>(5-x)&0xFF0000)|(raw_>>(3-x)&0xFF00)|(raw_>>(1-x)&0xFF);\
|
||||
if ( bits == 15 )\
|
||||
rgb_out = (raw_>>(14-x)& 0x7C00)|(raw_>>(9-x)&0x03E0)|(raw_>>(4-x)&0x001F);\
|
||||
if ( bits == 0 )\
|
||||
rgb_out = raw_ << x;\
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -1,289 +0,0 @@
|
|||
/* nes_ntsc 0.2.2. http://www.slack.net/~ant/ */
|
||||
|
||||
#include "nes_ntsc.h"
|
||||
|
||||
/* Copyright (C) 2006-2007 Shay Green. This module is free software; you
|
||||
can redistribute it and/or modify it under the terms of the GNU Lesser
|
||||
General Public License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version. This
|
||||
module is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
|
||||
details. You should have received a copy of the GNU Lesser General Public
|
||||
License along with this module; if not, write to the Free Software Foundation,
|
||||
Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
|
||||
|
||||
nes_ntsc_setup_t const nes_ntsc_monochrome = { 0,-1, 0, 0,.2, 0,.2,-.2,-.2,-1, 1, 0, 0, 0, 0 };
|
||||
nes_ntsc_setup_t const nes_ntsc_composite = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0 };
|
||||
nes_ntsc_setup_t const nes_ntsc_svideo = { 0, 0, 0, 0,.2, 0,.2, -1, -1, 0, 1, 0, 0, 0, 0 };
|
||||
nes_ntsc_setup_t const nes_ntsc_rgb = { 0, 0, 0, 0,.2, 0,.7, -1, -1,-1, 1, 0, 0, 0, 0 };
|
||||
|
||||
#define alignment_count 3
|
||||
#define burst_count 3
|
||||
#define rescale_in 8
|
||||
#define rescale_out 7
|
||||
|
||||
#define artifacts_mid 1.0f
|
||||
#define fringing_mid 1.0f
|
||||
#define std_decoder_hue -15
|
||||
|
||||
#define STD_HUE_CONDITION( setup ) !(setup->base_palette || setup->palette)
|
||||
|
||||
#include "nes_ntsc_impl.h"
|
||||
|
||||
/* 3 input pixels -> 8 composite samples */
|
||||
pixel_info_t const nes_ntsc_pixels [alignment_count] = {
|
||||
{ PIXEL_OFFSET( -4, -9 ), { 1, 1, .6667f, 0 } },
|
||||
{ PIXEL_OFFSET( -2, -7 ), { .3333f, 1, 1, .3333f } },
|
||||
{ PIXEL_OFFSET( 0, -5 ), { 0, .6667f, 1, 1 } },
|
||||
};
|
||||
|
||||
static void merge_kernel_fields( nes_ntsc_rgb_t* io )
|
||||
{
|
||||
int n;
|
||||
for ( n = burst_size; n; --n )
|
||||
{
|
||||
nes_ntsc_rgb_t p0 = io [burst_size * 0] + rgb_bias;
|
||||
nes_ntsc_rgb_t p1 = io [burst_size * 1] + rgb_bias;
|
||||
nes_ntsc_rgb_t p2 = io [burst_size * 2] + rgb_bias;
|
||||
/* merge colors without losing precision */
|
||||
io [burst_size * 0] =
|
||||
((p0 + p1 - ((p0 ^ p1) & nes_ntsc_rgb_builder)) >> 1) - rgb_bias;
|
||||
io [burst_size * 1] =
|
||||
((p1 + p2 - ((p1 ^ p2) & nes_ntsc_rgb_builder)) >> 1) - rgb_bias;
|
||||
io [burst_size * 2] =
|
||||
((p2 + p0 - ((p2 ^ p0) & nes_ntsc_rgb_builder)) >> 1) - rgb_bias;
|
||||
++io;
|
||||
}
|
||||
}
|
||||
|
||||
static void correct_errors( nes_ntsc_rgb_t color, nes_ntsc_rgb_t* out )
|
||||
{
|
||||
int n;
|
||||
for ( n = burst_count; n; --n )
|
||||
{
|
||||
unsigned i;
|
||||
for ( i = 0; i < rgb_kernel_size / 2; i++ )
|
||||
{
|
||||
nes_ntsc_rgb_t error = color -
|
||||
out [i ] - out [(i+12)%14+14] - out [(i+10)%14+28] -
|
||||
out [i + 7] - out [i + 5 +14] - out [i + 3 +28];
|
||||
DISTRIBUTE_ERROR( i+3+28, i+5+14, i+7 );
|
||||
}
|
||||
out += alignment_count * rgb_kernel_size;
|
||||
}
|
||||
}
|
||||
|
||||
void nes_ntsc_init( nes_ntsc_t* ntsc, nes_ntsc_setup_t const* setup )
|
||||
{
|
||||
int merge_fields;
|
||||
int entry;
|
||||
init_t impl;
|
||||
float gamma_factor;
|
||||
|
||||
if ( !setup )
|
||||
setup = &nes_ntsc_composite;
|
||||
init( &impl, setup );
|
||||
|
||||
/* setup fast gamma */
|
||||
{
|
||||
float gamma = (float) setup->gamma * -0.5f;
|
||||
if ( STD_HUE_CONDITION( setup ) )
|
||||
gamma += 0.1333f;
|
||||
|
||||
gamma_factor = (float) pow( (float) fabs( gamma ), 0.73f );
|
||||
if ( gamma < 0 )
|
||||
gamma_factor = -gamma_factor;
|
||||
}
|
||||
|
||||
merge_fields = setup->merge_fields;
|
||||
if ( setup->artifacts <= -1 && setup->fringing <= -1 )
|
||||
merge_fields = 1;
|
||||
|
||||
for ( entry = 0; entry < nes_ntsc_palette_size; entry++ )
|
||||
{
|
||||
/* Base 64-color generation */
|
||||
static float const lo_levels [4] = { -0.12f, 0.00f, 0.31f, 0.72f };
|
||||
static float const hi_levels [4] = { 0.40f, 0.68f, 1.00f, 1.00f };
|
||||
int level = entry >> 4 & 0x03;
|
||||
float lo = lo_levels [level];
|
||||
float hi = hi_levels [level];
|
||||
|
||||
int color = entry & 0x0F;
|
||||
if ( color == 0 )
|
||||
lo = hi;
|
||||
if ( color == 0x0D )
|
||||
hi = lo;
|
||||
if ( color > 0x0D )
|
||||
hi = lo = 0.0f;
|
||||
|
||||
{
|
||||
/* phases [i] = cos( i * PI / 6 ) */
|
||||
static float const phases [0x10 + 3] = {
|
||||
-1.0f, -0.866025f, -0.5f, 0.0f, 0.5f, 0.866025f,
|
||||
1.0f, 0.866025f, 0.5f, 0.0f, -0.5f, -0.866025f,
|
||||
-1.0f, -0.866025f, -0.5f, 0.0f, 0.5f, 0.866025f,
|
||||
1.0f
|
||||
};
|
||||
#define TO_ANGLE_SIN( color ) phases [color]
|
||||
#define TO_ANGLE_COS( color ) phases [(color) + 3]
|
||||
|
||||
/* Convert raw waveform to YIQ */
|
||||
float sat = (hi - lo) * 0.5f;
|
||||
float i = TO_ANGLE_SIN( color ) * sat;
|
||||
float q = TO_ANGLE_COS( color ) * sat;
|
||||
float y = (hi + lo) * 0.5f;
|
||||
|
||||
/* Optionally use base palette instead */
|
||||
if ( setup->base_palette )
|
||||
{
|
||||
unsigned char const* in = &setup->base_palette [(entry & 0x3F) * 3];
|
||||
static float const to_float = 1.0f / 0xFF;
|
||||
float r = to_float * in [0];
|
||||
float g = to_float * in [1];
|
||||
float b = to_float * in [2];
|
||||
q = RGB_TO_YIQ( r, g, b, y, i );
|
||||
}
|
||||
|
||||
/* Apply color emphasis */
|
||||
#ifdef NES_NTSC_EMPHASIS
|
||||
{
|
||||
int tint = entry >> 6 & 7;
|
||||
if ( tint && color <= 0x0D )
|
||||
{
|
||||
static float const atten_mul = 0.79399f;
|
||||
static float const atten_sub = 0.0782838f;
|
||||
|
||||
if ( tint == 7 )
|
||||
{
|
||||
y = y * (atten_mul * 1.13f) - (atten_sub * 1.13f);
|
||||
}
|
||||
else
|
||||
{
|
||||
static unsigned char const tints [8] = { 0, 6, 10, 8, 2, 4, 0, 0 };
|
||||
int const tint_color = tints [tint];
|
||||
float sat = hi * (0.5f - atten_mul * 0.5f) + atten_sub * 0.5f;
|
||||
y -= sat * 0.5f;
|
||||
if ( tint >= 3 && tint != 4 )
|
||||
{
|
||||
/* combined tint bits */
|
||||
sat *= 0.6f;
|
||||
y -= sat;
|
||||
}
|
||||
i += TO_ANGLE_SIN( tint_color ) * sat;
|
||||
q += TO_ANGLE_COS( tint_color ) * sat;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Optionally use palette instead */
|
||||
if ( setup->palette )
|
||||
{
|
||||
unsigned char const* in = &setup->palette [entry * 3];
|
||||
static float const to_float = 1.0f / 0xFF;
|
||||
float r = to_float * in [0];
|
||||
float g = to_float * in [1];
|
||||
float b = to_float * in [2];
|
||||
q = RGB_TO_YIQ( r, g, b, y, i );
|
||||
}
|
||||
|
||||
/* Apply brightness, contrast, and gamma */
|
||||
y *= (float) setup->contrast * 0.5f + 1;
|
||||
/* adjustment reduces error when using input palette */
|
||||
y += (float) setup->brightness * 0.5f - 0.5f / 256;
|
||||
|
||||
{
|
||||
float r, g, b = YIQ_TO_RGB( y, i, q, default_decoder, float, r, g );
|
||||
|
||||
/* fast approximation of n = pow( n, gamma ) */
|
||||
r = (r * gamma_factor - gamma_factor) * r + r;
|
||||
g = (g * gamma_factor - gamma_factor) * g + g;
|
||||
b = (b * gamma_factor - gamma_factor) * b + b;
|
||||
|
||||
q = RGB_TO_YIQ( r, g, b, y, i );
|
||||
}
|
||||
|
||||
i *= rgb_unit;
|
||||
q *= rgb_unit;
|
||||
y *= rgb_unit;
|
||||
y += rgb_offset;
|
||||
|
||||
/* Generate kernel */
|
||||
{
|
||||
int r, g, b = YIQ_TO_RGB( y, i, q, impl.to_rgb, int, r, g );
|
||||
/* blue tends to overflow, so clamp it */
|
||||
nes_ntsc_rgb_t rgb = PACK_RGB( r, g, (b < 0x3E0 ? b: 0x3E0) );
|
||||
|
||||
if ( setup->palette_out )
|
||||
RGB_PALETTE_OUT( rgb, &setup->palette_out [entry * 3] );
|
||||
|
||||
if ( ntsc )
|
||||
{
|
||||
nes_ntsc_rgb_t* kernel = ntsc->table [entry];
|
||||
gen_kernel( &impl, y, i, q, kernel );
|
||||
if ( merge_fields )
|
||||
merge_kernel_fields( kernel );
|
||||
correct_errors( rgb, kernel );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef NES_NTSC_NO_BLITTERS
|
||||
|
||||
void nes_ntsc_blit( nes_ntsc_t const* ntsc, NES_NTSC_IN_T const* input, long in_row_width,
|
||||
int burst_phase, int in_width, int in_height, void* rgb_out, long out_pitch )
|
||||
{
|
||||
int chunk_count = (in_width - 1) / nes_ntsc_in_chunk;
|
||||
for ( ; in_height; --in_height )
|
||||
{
|
||||
NES_NTSC_IN_T const* line_in = input;
|
||||
NES_NTSC_BEGIN_ROW( ntsc, burst_phase,
|
||||
nes_ntsc_black, nes_ntsc_black, NES_NTSC_ADJ_IN( *line_in ) );
|
||||
nes_ntsc_out_t* restrict line_out = (nes_ntsc_out_t*) rgb_out;
|
||||
int n;
|
||||
++line_in;
|
||||
|
||||
for ( n = chunk_count; n; --n )
|
||||
{
|
||||
/* order of input and output pixels must not be altered */
|
||||
NES_NTSC_COLOR_IN( 0, NES_NTSC_ADJ_IN( line_in [0] ) );
|
||||
NES_NTSC_RGB_OUT( 0, line_out [0], NES_NTSC_OUT_DEPTH );
|
||||
NES_NTSC_RGB_OUT( 1, line_out [1], NES_NTSC_OUT_DEPTH );
|
||||
|
||||
NES_NTSC_COLOR_IN( 1, NES_NTSC_ADJ_IN( line_in [1] ) );
|
||||
NES_NTSC_RGB_OUT( 2, line_out [2], NES_NTSC_OUT_DEPTH );
|
||||
NES_NTSC_RGB_OUT( 3, line_out [3], NES_NTSC_OUT_DEPTH );
|
||||
|
||||
NES_NTSC_COLOR_IN( 2, NES_NTSC_ADJ_IN( line_in [2] ) );
|
||||
NES_NTSC_RGB_OUT( 4, line_out [4], NES_NTSC_OUT_DEPTH );
|
||||
NES_NTSC_RGB_OUT( 5, line_out [5], NES_NTSC_OUT_DEPTH );
|
||||
NES_NTSC_RGB_OUT( 6, line_out [6], NES_NTSC_OUT_DEPTH );
|
||||
|
||||
line_in += 3;
|
||||
line_out += 7;
|
||||
}
|
||||
|
||||
/* finish final pixels */
|
||||
NES_NTSC_COLOR_IN( 0, nes_ntsc_black );
|
||||
NES_NTSC_RGB_OUT( 0, line_out [0], NES_NTSC_OUT_DEPTH );
|
||||
NES_NTSC_RGB_OUT( 1, line_out [1], NES_NTSC_OUT_DEPTH );
|
||||
|
||||
NES_NTSC_COLOR_IN( 1, nes_ntsc_black );
|
||||
NES_NTSC_RGB_OUT( 2, line_out [2], NES_NTSC_OUT_DEPTH );
|
||||
NES_NTSC_RGB_OUT( 3, line_out [3], NES_NTSC_OUT_DEPTH );
|
||||
|
||||
NES_NTSC_COLOR_IN( 2, nes_ntsc_black );
|
||||
NES_NTSC_RGB_OUT( 4, line_out [4], NES_NTSC_OUT_DEPTH );
|
||||
NES_NTSC_RGB_OUT( 5, line_out [5], NES_NTSC_OUT_DEPTH );
|
||||
NES_NTSC_RGB_OUT( 6, line_out [6], NES_NTSC_OUT_DEPTH );
|
||||
|
||||
burst_phase = (burst_phase + 1) % nes_ntsc_burst_count;
|
||||
input += in_row_width;
|
||||
rgb_out = (char*) rgb_out + out_pitch;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
|
@ -1,27 +0,0 @@
|
|||
/* Configure library by modifying this file */
|
||||
|
||||
#ifndef NES_NTSC_CONFIG_H
|
||||
#define NES_NTSC_CONFIG_H
|
||||
|
||||
/* Uncomment to enable emphasis support and use a 512 color palette instead
|
||||
of the base 64 color palette. */
|
||||
#define NES_NTSC_EMPHASIS 1
|
||||
|
||||
/* The following affect the built-in blitter only; a custom blitter can
|
||||
handle things however it wants. */
|
||||
|
||||
/* Bits per pixel of output. Can be 15, 16, 32, or 24 (same as 32). */
|
||||
#define NES_NTSC_OUT_DEPTH 32
|
||||
|
||||
/* Type of input pixel values. You'll probably use unsigned short
|
||||
if you enable emphasis above. */
|
||||
#define NES_NTSC_IN_T unsigned char
|
||||
|
||||
/* Each raw pixel input value is passed through this. You might want to mask
|
||||
the pixel index if you use the high bits as flags, etc. */
|
||||
#define NES_NTSC_ADJ_IN( in ) in
|
||||
|
||||
/* For each pixel, this is the basic operation:
|
||||
output_color = color_palette [NES_NTSC_ADJ_IN( NES_NTSC_IN_T )] */
|
||||
|
||||
#endif
|
|
@ -1,439 +0,0 @@
|
|||
/* nes_ntsc 0.2.2. http://www.slack.net/~ant/ */
|
||||
|
||||
/* Common implementation of NTSC filters */
|
||||
|
||||
#include <assert.h>
|
||||
#include <math.h>
|
||||
|
||||
/* Copyright (C) 2006 Shay Green. This module is free software; you
|
||||
can redistribute it and/or modify it under the terms of the GNU Lesser
|
||||
General Public License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version. This
|
||||
module is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
|
||||
details. You should have received a copy of the GNU Lesser General Public
|
||||
License along with this module; if not, write to the Free Software Foundation,
|
||||
Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
|
||||
|
||||
#define DISABLE_CORRECTION 0
|
||||
|
||||
#undef PI
|
||||
#define PI 3.14159265358979323846f
|
||||
|
||||
#ifndef LUMA_CUTOFF
|
||||
#define LUMA_CUTOFF 0.20
|
||||
#endif
|
||||
#ifndef gamma_size
|
||||
#define gamma_size 1
|
||||
#endif
|
||||
#ifndef rgb_bits
|
||||
#define rgb_bits 8
|
||||
#endif
|
||||
#ifndef artifacts_max
|
||||
#define artifacts_max (artifacts_mid * 1.5f)
|
||||
#endif
|
||||
#ifndef fringing_max
|
||||
#define fringing_max (fringing_mid * 2)
|
||||
#endif
|
||||
#ifndef STD_HUE_CONDITION
|
||||
#define STD_HUE_CONDITION( setup ) 1
|
||||
#endif
|
||||
|
||||
#define ext_decoder_hue (std_decoder_hue + 15)
|
||||
#define rgb_unit (1 << rgb_bits)
|
||||
#define rgb_offset (rgb_unit * 2 + 0.5f)
|
||||
|
||||
enum { burst_size = nes_ntsc_entry_size / burst_count };
|
||||
enum { kernel_half = 16 };
|
||||
enum { kernel_size = kernel_half * 2 + 1 };
|
||||
|
||||
typedef struct init_t
|
||||
{
|
||||
float to_rgb [burst_count * 6];
|
||||
float to_float [gamma_size];
|
||||
float contrast;
|
||||
float brightness;
|
||||
float artifacts;
|
||||
float fringing;
|
||||
float kernel [rescale_out * kernel_size * 2];
|
||||
} init_t;
|
||||
|
||||
#define ROTATE_IQ( i, q, sin_b, cos_b ) {\
|
||||
float t;\
|
||||
t = i * cos_b - q * sin_b;\
|
||||
q = i * sin_b + q * cos_b;\
|
||||
i = t;\
|
||||
}
|
||||
|
||||
static void init_filters( init_t* impl, nes_ntsc_setup_t const* setup )
|
||||
{
|
||||
#if rescale_out > 1
|
||||
float kernels [kernel_size * 2];
|
||||
#else
|
||||
float* const kernels = impl->kernel;
|
||||
#endif
|
||||
|
||||
/* generate luma (y) filter using sinc kernel */
|
||||
{
|
||||
/* sinc with rolloff (dsf) */
|
||||
float const rolloff = 1 + (float) setup->sharpness * (float) 0.032;
|
||||
float const maxh = 32;
|
||||
float const pow_a_n = (float) pow( rolloff, maxh );
|
||||
float sum;
|
||||
int i;
|
||||
/* quadratic mapping to reduce negative (blurring) range */
|
||||
float to_angle = (float) setup->resolution + 1;
|
||||
to_angle = PI / maxh * (float) LUMA_CUTOFF * (to_angle * to_angle + 1);
|
||||
|
||||
kernels [kernel_size * 3 / 2] = maxh; /* default center value */
|
||||
for ( i = 0; i < kernel_half * 2 + 1; i++ )
|
||||
{
|
||||
int x = i - kernel_half;
|
||||
float angle = x * to_angle;
|
||||
/* instability occurs at center point with rolloff very close to 1.0 */
|
||||
if ( x || pow_a_n > (float) 1.056 || pow_a_n < (float) 0.981 )
|
||||
{
|
||||
float rolloff_cos_a = rolloff * (float) cos( angle );
|
||||
float num = 1 - rolloff_cos_a -
|
||||
pow_a_n * (float) cos( maxh * angle ) +
|
||||
pow_a_n * rolloff * (float) cos( (maxh - 1) * angle );
|
||||
float den = 1 - rolloff_cos_a - rolloff_cos_a + rolloff * rolloff;
|
||||
float dsf = num / den;
|
||||
kernels [kernel_size * 3 / 2 - kernel_half + i] = dsf - (float) 0.5;
|
||||
}
|
||||
}
|
||||
|
||||
/* apply blackman window and find sum */
|
||||
sum = 0;
|
||||
for ( i = 0; i < kernel_half * 2 + 1; i++ )
|
||||
{
|
||||
float x = PI * 2 / (kernel_half * 2) * i;
|
||||
float blackman = 0.42f - 0.5f * (float) cos( x ) + 0.08f * (float) cos( x * 2 );
|
||||
sum += (kernels [kernel_size * 3 / 2 - kernel_half + i] *= blackman);
|
||||
}
|
||||
|
||||
/* normalize kernel */
|
||||
sum = 1.0f / sum;
|
||||
for ( i = 0; i < kernel_half * 2 + 1; i++ )
|
||||
{
|
||||
int x = kernel_size * 3 / 2 - kernel_half + i;
|
||||
kernels [x] *= sum;
|
||||
assert( kernels [x] == kernels [x] ); /* catch numerical instability */
|
||||
}
|
||||
}
|
||||
|
||||
/* generate chroma (iq) filter using gaussian kernel */
|
||||
{
|
||||
float const cutoff_factor = -0.03125f;
|
||||
float cutoff = (float) setup->bleed;
|
||||
int i;
|
||||
|
||||
if ( cutoff < 0 )
|
||||
{
|
||||
/* keep extreme value accessible only near upper end of scale (1.0) */
|
||||
cutoff *= cutoff;
|
||||
cutoff *= cutoff;
|
||||
cutoff *= cutoff;
|
||||
cutoff *= -30.0f / 0.65f;
|
||||
}
|
||||
cutoff = cutoff_factor - 0.65f * cutoff_factor * cutoff;
|
||||
|
||||
for ( i = -kernel_half; i <= kernel_half; i++ )
|
||||
kernels [kernel_size / 2 + i] = (float) exp( i * i * cutoff );
|
||||
|
||||
/* normalize even and odd phases separately */
|
||||
for ( i = 0; i < 2; i++ )
|
||||
{
|
||||
float sum = 0;
|
||||
int x;
|
||||
for ( x = i; x < kernel_size; x += 2 )
|
||||
sum += kernels [x];
|
||||
|
||||
sum = 1.0f / sum;
|
||||
for ( x = i; x < kernel_size; x += 2 )
|
||||
{
|
||||
kernels [x] *= sum;
|
||||
assert( kernels [x] == kernels [x] ); /* catch numerical instability */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
printf( "luma:\n" );
|
||||
for ( i = kernel_size; i < kernel_size * 2; i++ )
|
||||
printf( "%f\n", kernels [i] );
|
||||
printf( "chroma:\n" );
|
||||
for ( i = 0; i < kernel_size; i++ )
|
||||
printf( "%f\n", kernels [i] );
|
||||
*/
|
||||
|
||||
/* generate linear rescale kernels */
|
||||
#if rescale_out > 1
|
||||
{
|
||||
float weight = 1.0f;
|
||||
float* out = impl->kernel;
|
||||
int n = rescale_out;
|
||||
do
|
||||
{
|
||||
float remain = 0;
|
||||
int i;
|
||||
weight -= 1.0f / rescale_in;
|
||||
for ( i = 0; i < kernel_size * 2; i++ )
|
||||
{
|
||||
float cur = kernels [i];
|
||||
float m = cur * weight;
|
||||
*out++ = m + remain;
|
||||
remain = cur - m;
|
||||
}
|
||||
}
|
||||
while ( --n );
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
static float const default_decoder [6] =
|
||||
{ 0.956f, 0.621f, -0.272f, -0.647f, -1.105f, 1.702f };
|
||||
|
||||
static void init( init_t* impl, nes_ntsc_setup_t const* setup )
|
||||
{
|
||||
impl->brightness = (float) setup->brightness * (0.5f * rgb_unit) + rgb_offset;
|
||||
impl->contrast = (float) setup->contrast * (0.5f * rgb_unit) + rgb_unit;
|
||||
#ifdef default_palette_contrast
|
||||
if ( !setup->palette )
|
||||
impl->contrast *= default_palette_contrast;
|
||||
#endif
|
||||
|
||||
impl->artifacts = (float) setup->artifacts;
|
||||
if ( impl->artifacts > 0 )
|
||||
impl->artifacts *= artifacts_max - artifacts_mid;
|
||||
impl->artifacts = impl->artifacts * artifacts_mid + artifacts_mid;
|
||||
|
||||
impl->fringing = (float) setup->fringing;
|
||||
if ( impl->fringing > 0 )
|
||||
impl->fringing *= fringing_max - fringing_mid;
|
||||
impl->fringing = impl->fringing * fringing_mid + fringing_mid;
|
||||
|
||||
init_filters( impl, setup );
|
||||
|
||||
/* generate gamma table */
|
||||
if ( gamma_size > 1 )
|
||||
{
|
||||
float const to_float = 1.0f / (gamma_size - (gamma_size > 1));
|
||||
float const gamma = 1.1333f - (float) setup->gamma * 0.5f;
|
||||
/* match common PC's 2.2 gamma to TV's 2.65 gamma */
|
||||
int i;
|
||||
for ( i = 0; i < gamma_size; i++ )
|
||||
impl->to_float [i] =
|
||||
(float) pow( i * to_float, gamma ) * impl->contrast + impl->brightness;
|
||||
}
|
||||
|
||||
/* setup decoder matricies */
|
||||
{
|
||||
float hue = (float) setup->hue * PI + PI / 180 * ext_decoder_hue;
|
||||
float sat = (float) setup->saturation + 1;
|
||||
float const* decoder = setup->decoder_matrix;
|
||||
if ( !decoder )
|
||||
{
|
||||
decoder = default_decoder;
|
||||
if ( STD_HUE_CONDITION( setup ) )
|
||||
hue += PI / 180 * (std_decoder_hue - ext_decoder_hue);
|
||||
}
|
||||
|
||||
{
|
||||
float s = (float) sin( hue ) * sat;
|
||||
float c = (float) cos( hue ) * sat;
|
||||
float* out = impl->to_rgb;
|
||||
int n;
|
||||
|
||||
n = burst_count;
|
||||
do
|
||||
{
|
||||
float const* in = decoder;
|
||||
int n = 3;
|
||||
do
|
||||
{
|
||||
float i = *in++;
|
||||
float q = *in++;
|
||||
*out++ = i * c - q * s;
|
||||
*out++ = i * s + q * c;
|
||||
}
|
||||
while ( --n );
|
||||
if ( burst_count <= 1 )
|
||||
break;
|
||||
ROTATE_IQ( s, c, 0.866025f, -0.5f ); /* +120 degrees */
|
||||
}
|
||||
while ( --n );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* kernel generation */
|
||||
|
||||
#define RGB_TO_YIQ( r, g, b, y, i ) (\
|
||||
(y = (r) * 0.299f + (g) * 0.587f + (b) * 0.114f),\
|
||||
(i = (r) * 0.596f - (g) * 0.275f - (b) * 0.321f),\
|
||||
((r) * 0.212f - (g) * 0.523f + (b) * 0.311f)\
|
||||
)
|
||||
|
||||
#define YIQ_TO_RGB( y, i, q, to_rgb, type, r, g ) (\
|
||||
r = (type) (y + to_rgb [0] * i + to_rgb [1] * q),\
|
||||
g = (type) (y + to_rgb [2] * i + to_rgb [3] * q),\
|
||||
(type) (y + to_rgb [4] * i + to_rgb [5] * q)\
|
||||
)
|
||||
|
||||
#define PACK_RGB( r, g, b ) ((r) << 21 | (g) << 11 | (b) << 1)
|
||||
|
||||
enum { rgb_kernel_size = burst_size / alignment_count };
|
||||
enum { rgb_bias = rgb_unit * 2 * nes_ntsc_rgb_builder };
|
||||
|
||||
typedef struct pixel_info_t
|
||||
{
|
||||
int offset;
|
||||
float negate;
|
||||
float kernel [4];
|
||||
} pixel_info_t;
|
||||
|
||||
#if rescale_in > 1
|
||||
#define PIXEL_OFFSET_( ntsc, scaled ) \
|
||||
(kernel_size / 2 + ntsc + (scaled != 0) + (rescale_out - scaled) % rescale_out + \
|
||||
(kernel_size * 2 * scaled))
|
||||
|
||||
#define PIXEL_OFFSET( ntsc, scaled ) \
|
||||
PIXEL_OFFSET_( ((ntsc) - (scaled) / rescale_out * rescale_in),\
|
||||
(((scaled) + rescale_out * 10) % rescale_out) ),\
|
||||
(1.0f - (((ntsc) + 100) & 2))
|
||||
#else
|
||||
#define PIXEL_OFFSET( ntsc, scaled ) \
|
||||
(kernel_size / 2 + (ntsc) - (scaled)),\
|
||||
(1.0f - (((ntsc) + 100) & 2))
|
||||
#endif
|
||||
|
||||
extern pixel_info_t const nes_ntsc_pixels [alignment_count];
|
||||
|
||||
/* Generate pixel at all burst phases and column alignments */
|
||||
static void gen_kernel( init_t* impl, float y, float i, float q, nes_ntsc_rgb_t* out )
|
||||
{
|
||||
/* generate for each scanline burst phase */
|
||||
float const* to_rgb = impl->to_rgb;
|
||||
int burst_remain = burst_count;
|
||||
y -= rgb_offset;
|
||||
do
|
||||
{
|
||||
/* Encode yiq into *two* composite signals (to allow control over artifacting).
|
||||
Convolve these with kernels which: filter respective components, apply
|
||||
sharpening, and rescale horizontally. Convert resulting yiq to rgb and pack
|
||||
into integer. Based on algorithm by NewRisingSun. */
|
||||
pixel_info_t const* pixel = nes_ntsc_pixels;
|
||||
int alignment_remain = alignment_count;
|
||||
do
|
||||
{
|
||||
/* negate is -1 when composite starts at odd multiple of 2 */
|
||||
float const yy = y * impl->fringing * pixel->negate;
|
||||
float const ic0 = (i + yy) * pixel->kernel [0];
|
||||
float const qc1 = (q + yy) * pixel->kernel [1];
|
||||
float const ic2 = (i - yy) * pixel->kernel [2];
|
||||
float const qc3 = (q - yy) * pixel->kernel [3];
|
||||
|
||||
float const factor = impl->artifacts * pixel->negate;
|
||||
float const ii = i * factor;
|
||||
float const yc0 = (y + ii) * pixel->kernel [0];
|
||||
float const yc2 = (y - ii) * pixel->kernel [2];
|
||||
|
||||
float const qq = q * factor;
|
||||
float const yc1 = (y + qq) * pixel->kernel [1];
|
||||
float const yc3 = (y - qq) * pixel->kernel [3];
|
||||
|
||||
float const* k = &impl->kernel [pixel->offset];
|
||||
int n;
|
||||
++pixel;
|
||||
for ( n = rgb_kernel_size; n; --n )
|
||||
{
|
||||
float i = k[0]*ic0 + k[2]*ic2;
|
||||
float q = k[1]*qc1 + k[3]*qc3;
|
||||
float y = k[kernel_size+0]*yc0 + k[kernel_size+1]*yc1 +
|
||||
k[kernel_size+2]*yc2 + k[kernel_size+3]*yc3 + rgb_offset;
|
||||
if ( rescale_out <= 1 )
|
||||
k--;
|
||||
else if ( k < &impl->kernel [kernel_size * 2 * (rescale_out - 1)] )
|
||||
k += kernel_size * 2 - 1;
|
||||
else
|
||||
k -= kernel_size * 2 * (rescale_out - 1) + 2;
|
||||
{
|
||||
int r, g, b = YIQ_TO_RGB( y, i, q, to_rgb, int, r, g );
|
||||
*out++ = PACK_RGB( r, g, b ) - rgb_bias;
|
||||
}
|
||||
}
|
||||
}
|
||||
while ( alignment_count > 1 && --alignment_remain );
|
||||
|
||||
if ( burst_count <= 1 )
|
||||
break;
|
||||
|
||||
to_rgb += 6;
|
||||
|
||||
ROTATE_IQ( i, q, -0.866025f, -0.5f ); /* -120 degrees */
|
||||
}
|
||||
while ( --burst_remain );
|
||||
}
|
||||
|
||||
static void correct_errors( nes_ntsc_rgb_t color, nes_ntsc_rgb_t* out );
|
||||
|
||||
#if DISABLE_CORRECTION
|
||||
#define CORRECT_ERROR( a ) { out [i] += rgb_bias; }
|
||||
#define DISTRIBUTE_ERROR( a, b, c ) { out [i] += rgb_bias; }
|
||||
#else
|
||||
#define CORRECT_ERROR( a ) { out [a] += error; }
|
||||
#define DISTRIBUTE_ERROR( a, b, c ) {\
|
||||
nes_ntsc_rgb_t fourth = (error + 2 * nes_ntsc_rgb_builder) >> 2;\
|
||||
fourth &= (rgb_bias >> 1) - nes_ntsc_rgb_builder;\
|
||||
fourth -= rgb_bias >> 2;\
|
||||
out [a] += fourth;\
|
||||
out [b] += fourth;\
|
||||
out [c] += fourth;\
|
||||
out [i] += error - (fourth * 3);\
|
||||
}
|
||||
#endif
|
||||
|
||||
#define RGB_PALETTE_OUT( rgb, out_ )\
|
||||
{\
|
||||
unsigned char* out = (out_);\
|
||||
nes_ntsc_rgb_t clamped = (rgb);\
|
||||
NES_NTSC_CLAMP_( clamped, (8 - rgb_bits) );\
|
||||
out [0] = (unsigned char) (clamped >> 21);\
|
||||
out [1] = (unsigned char) (clamped >> 11);\
|
||||
out [2] = (unsigned char) (clamped >> 1);\
|
||||
}
|
||||
|
||||
/* blitter related */
|
||||
|
||||
#ifndef restrict
|
||||
#if defined (__GNUC__)
|
||||
#define restrict __restrict__
|
||||
#elif defined (_MSC_VER) && _MSC_VER > 1300
|
||||
#define restrict __restrict
|
||||
#else
|
||||
/* no support for restricted pointers */
|
||||
#define restrict
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#include <limits.h>
|
||||
|
||||
#if NES_NTSC_OUT_DEPTH <= 16
|
||||
#if USHRT_MAX == 0xFFFF
|
||||
typedef unsigned short nes_ntsc_out_t;
|
||||
#else
|
||||
#error "Need 16-bit int type"
|
||||
#endif
|
||||
|
||||
#else
|
||||
#if UINT_MAX == 0xFFFFFFFF
|
||||
typedef unsigned int nes_ntsc_out_t;
|
||||
#elif ULONG_MAX == 0xFFFFFFFF
|
||||
typedef unsigned long nes_ntsc_out_t;
|
||||
#else
|
||||
#error "Need 32-bit int type"
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -18,9 +18,11 @@
|
|||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
|
||||
***************************************************************************/
|
||||
|
||||
#include "ntsc.h"
|
||||
|
||||
#if 0
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include "ntsc.h"
|
||||
#include "nes_ntsc/nes_ntsc.h"
|
||||
#include "misc/memutil.h"
|
||||
#include "system/video.h"
|
||||
|
@ -91,6 +93,7 @@ void ntsc2x(void *d,u32 dst_slice,void *s,u32 src_slice,u32 width,u32 height)
|
|||
u32 *dst = (u32*)d;
|
||||
u8 *pal = nes->ppu.palette;
|
||||
|
||||
assert(0);
|
||||
for(h=0;h<240;h++) {
|
||||
u32 *dststart = dst;
|
||||
|
||||
|
@ -133,6 +136,12 @@ void ntsc2x(void *d,u32 dst_slice,void *s,u32 src_slice,u32 width,u32 height)
|
|||
dst = (u32*)((u8*)d + dst_slice * (h * 2));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
int ntsc_init() { return 0; }
|
||||
void ntsc_kill() { }
|
||||
void ntsc_palette_changed() { }
|
||||
void ntsc2x(void *d,u32 dst_slice,void *s,u32 src_slice,u32 width,u32 height) { }
|
||||
|
||||
void ntsc3x(void *dst,u32 dst_slice,void *src,u32 src_slice,u32 width,u32 height)
|
||||
{
|
||||
|
|
|
@ -21,9 +21,11 @@
|
|||
#ifndef __SCALE2X_H
|
||||
#define __SCALE2X_H
|
||||
|
||||
typedef unsigned char scale2x_uint8;
|
||||
typedef unsigned short scale2x_uint16;
|
||||
typedef unsigned scale2x_uint32;
|
||||
#include "types.h"
|
||||
|
||||
typedef u8 scale2x_uint8;
|
||||
typedef u16 scale2x_uint16;
|
||||
typedef u32 scale2x_uint32;
|
||||
|
||||
void scale2x_8_def(scale2x_uint8* dst0, scale2x_uint8* dst1, const scale2x_uint8* src0, const scale2x_uint8* src1, const scale2x_uint8* src2, unsigned count);
|
||||
void scale2x_16_def(scale2x_uint16* dst0, scale2x_uint16* dst1, const scale2x_uint16* src0, const scale2x_uint16* src1, const scale2x_uint16* src2, unsigned count);
|
||||
|
|
|
@ -21,9 +21,11 @@
|
|||
#ifndef __SCALE3X_H
|
||||
#define __SCALE3X_H
|
||||
|
||||
typedef unsigned char scale3x_uint8;
|
||||
typedef unsigned short scale3x_uint16;
|
||||
typedef unsigned scale3x_uint32;
|
||||
#include "types.h"
|
||||
|
||||
typedef u8 scale3x_uint8;
|
||||
typedef u16 scale3x_uint16;
|
||||
typedef u32 scale3x_uint32;
|
||||
|
||||
void scale3x_8_def(scale3x_uint8* dst0, scale3x_uint8* dst1, scale3x_uint8* dst2, const scale3x_uint8* src0, const scale3x_uint8* src1, const scale3x_uint8* src2, unsigned count);
|
||||
void scale3x_16_def(scale3x_uint16* dst0, scale3x_uint16* dst1, scale3x_uint16* dst2, const scale3x_uint16* src0, const scale3x_uint16* src1, const scale3x_uint16* src2, unsigned count);
|
||||
|
|
|
@ -33,6 +33,7 @@
|
|||
* - derivative works of the program are allowed.
|
||||
*/
|
||||
|
||||
#if 0
|
||||
#if HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
@ -514,3 +515,12 @@ void scale(unsigned scale, void* void_dst, unsigned dst_slice, const void* void_
|
|||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#include "types.h"
|
||||
|
||||
void scale(unsigned scale, void* void_dst, u32 dst_slice, void* void_src, u32 src_slice, u32 width, u32 height) { }
|
||||
|
||||
void scale2x(void* void_dst, u32 dst_slice, void* void_src, u32 src_slice, u32 width, u32 height) { }
|
||||
void scale3x(void* void_dst, u32 dst_slice, void* void_src, u32 src_slice, u32 width, u32 height) { }
|
||||
void scale4x(void* void_dst, u32 dst_slice, void* void_src, u32 src_slice, u32 width, u32 height) { }
|
||||
|
|
|
@ -41,10 +41,11 @@ extern "C" {
|
|||
#endif
|
||||
|
||||
int scale_precondition(unsigned scale, unsigned pixel, unsigned width, unsigned height);
|
||||
void scale(unsigned scale, void* void_dst, unsigned dst_slice, const void* void_src, unsigned src_slice, unsigned width, unsigned height);
|
||||
void scale2x(void* void_dst, unsigned dst_slice, void* void_src, unsigned src_slice, unsigned width, unsigned height);
|
||||
void scale3x(void* void_dst, unsigned dst_slice, void* void_src, unsigned src_slice, unsigned width, unsigned height);
|
||||
void scale4x(void* void_dst, unsigned dst_slice, void* void_src, unsigned src_slice, unsigned width, unsigned height);
|
||||
void scale(unsigned scale, void* void_dst, u32 dst_slice, void* void_src, u32 src_slice, u32 width, u32 height);
|
||||
|
||||
void scale2x(void* void_dst, u32 dst_slice, void* void_src, u32 src_slice, u32 width, u32 height);
|
||||
void scale3x(void* void_dst, u32 dst_slice, void* void_src, u32 src_slice, u32 width, u32 height);
|
||||
void scale4x(void* void_dst, u32 dst_slice, void* void_src, u32 src_slice, u32 width, u32 height);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
#include <ctype.h>
|
||||
static inline char tolower(char c) {
|
||||
return (c >= 'A' && c <= 'Z' ? c + 'a' - 'A' : c);
|
||||
}
|
||||
|
||||
int stricmp(char *s1,char *s2)
|
||||
{
|
||||
|
|
|
@ -18,7 +18,6 @@
|
|||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
|
||||
***************************************************************************/
|
||||
|
||||
//#include <SDL/SDL.h>
|
||||
#include <stdio.h>
|
||||
#include "version.h"
|
||||
#include "emu/emu.h"
|
||||
|
@ -34,7 +33,7 @@
|
|||
#include "system/video.h"
|
||||
#include "system/input.h"
|
||||
#include "palette/palette.h"
|
||||
#include "palette/generator.h"
|
||||
//#include "palette/generator.h"
|
||||
#include "system/sdl/console/console.h"
|
||||
|
||||
#include <am.h>
|
||||
|
@ -44,87 +43,30 @@
|
|||
char configfilename[1024] = CONFIG_FILENAME;
|
||||
char exepath[1024] = "";
|
||||
|
||||
#if 0
|
||||
static void usage(char *argv0)
|
||||
{
|
||||
printf("\nnesemu2 v%s - Copyright 2013 James Holodnak\n\n",VERSION);
|
||||
printf("Usage: %s [options] filename\n\n",argv0);
|
||||
printf("Supported ROM formats: iNES, NES 2.0, UNIF, FDS, NSF\n\n");
|
||||
printf("Options:\n\n");
|
||||
printf(" --help : Show this message and exit.\n");
|
||||
printf(" --mappers : Show supported mappers and exit.\n");
|
||||
printf(" --config <file> : Use 'file' as configuration file.\n");
|
||||
printf(" --patch <file> : Specify patch file for ROM.\n");
|
||||
printf(" --movie <file> : Specify movie file.\n");
|
||||
printf(" --record : After loading rom, start recording movie (used with --movie).\n");
|
||||
printf(" --recordtest : After loading rom, start recording test (used with --movie).\n");
|
||||
printf(" --test <file> : Specify automated testing script.\n");
|
||||
printf("\n");
|
||||
}
|
||||
#endif
|
||||
|
||||
//todo: this is getting ugly
|
||||
int main(int argc,char *argv[])
|
||||
int main(const char *romfilename)
|
||||
{
|
||||
//int i;
|
||||
int ret;
|
||||
int recordmovie = 0;
|
||||
//int recordmovie = 0;
|
||||
//char *p;
|
||||
char romfilename[1024] = "";
|
||||
char patchfilename[1024] = "";
|
||||
char moviefilename[1024] = "";
|
||||
char testfilename[1024] = "";
|
||||
//char romfilename[1024] = "";
|
||||
//char patchfilename[1024] = "";
|
||||
//char moviefilename[1024] = "";
|
||||
//char testfilename[1024] = "";
|
||||
|
||||
_ioe_init();
|
||||
|
||||
//clear the tmp strings and configfile string
|
||||
memset(romfilename,0,1024);
|
||||
memset(patchfilename,0,1024);
|
||||
memset(moviefilename,0,1024);
|
||||
memset(configfilename,0,1024);
|
||||
memset(testfilename,0,1024);
|
||||
//memset(romfilename,0,1024);
|
||||
//memset(patchfilename,0,1024);
|
||||
//memset(moviefilename,0,1024);
|
||||
//memset(configfilename,0,1024);
|
||||
//memset(testfilename,0,1024);
|
||||
|
||||
#if 0
|
||||
//make the exe path variable
|
||||
strcpy(exepath,argv[0]);
|
||||
if((p = strrchr(exepath,PATH_SEPERATOR)) != 0) {
|
||||
*p = 0;
|
||||
}
|
||||
|
||||
//process the command line
|
||||
for(i=1;i<argc;i++) {
|
||||
if(strcmp("--mappers",argv[i]) == 0) {
|
||||
command_execute("mappers");
|
||||
return(0);
|
||||
}
|
||||
else if(strcmp("--help",argv[i]) == 0) {
|
||||
usage(argv[0]);
|
||||
return(0);
|
||||
}
|
||||
else if(strcmp("--record",argv[i]) == 0) {
|
||||
recordmovie = 1;
|
||||
}
|
||||
else if(strcmp("--recordtest",argv[i]) == 0) {
|
||||
recordmovie = 2;
|
||||
}
|
||||
else if(strcmp("--config",argv[i]) == 0) {
|
||||
strcpy(configfilename,argv[++i]);
|
||||
}
|
||||
else if(strcmp("--patch",argv[i]) == 0) {
|
||||
strcpy(patchfilename,argv[++i]);
|
||||
}
|
||||
else if(strcmp("--movie",argv[i]) == 0) {
|
||||
strcpy(moviefilename,argv[++i]);
|
||||
}
|
||||
else if(strcmp("--test",argv[i]) == 0) {
|
||||
strcpy(testfilename,argv[++i]);
|
||||
}
|
||||
else
|
||||
strcpy(romfilename,argv[i]);
|
||||
}
|
||||
#endif
|
||||
|
||||
strcpy(romfilename,"mario.nes");
|
||||
//strcpy(romfilename,"mario");
|
||||
//strcpy(romfilename,"roms/lunar_pool.nes");
|
||||
//strcpy(romfilename,"roms/sky_destroyer.nes");
|
||||
|
||||
//add extra subsystems
|
||||
emu_addsubsystem("console",console_init,console_kill);
|
||||
|
@ -136,39 +78,39 @@ int main(int argc,char *argv[])
|
|||
}
|
||||
|
||||
//load rom specified by arguments
|
||||
if(strcmp(romfilename,"") != 0) {
|
||||
//if(strcmp(romfilename,"") != 0) {
|
||||
emu_event(E_LOADROM,(void*)romfilename);
|
||||
}
|
||||
//}
|
||||
|
||||
//load patch
|
||||
if(strcmp(patchfilename,"") != 0) {
|
||||
emu_event(E_LOADPATCH,(void*)patchfilename);
|
||||
}
|
||||
//if(strcmp(patchfilename,"") != 0) {
|
||||
// emu_event(E_LOADPATCH,(void*)patchfilename);
|
||||
//}
|
||||
|
||||
//see what we need to do with the movie
|
||||
if(strcmp(moviefilename,"") != 0) {
|
||||
if(recordmovie) {
|
||||
if(nes->cart == 0)
|
||||
log_printf("main: cannot record movie without rom loaded.\n");
|
||||
else {
|
||||
emu_event(E_SAVEMOVIE,(void*)moviefilename);
|
||||
emu_event(E_RECORDMOVIE,0);
|
||||
nes->movie.mode |= (recordmovie > 1) ? MOVIE_TEST : 0;
|
||||
}
|
||||
}
|
||||
else {
|
||||
emu_event(E_LOADMOVIE,(void*)moviefilename);
|
||||
emu_event(E_PLAYMOVIE,0);
|
||||
}
|
||||
}
|
||||
//if(strcmp(moviefilename,"") != 0) {
|
||||
// if(recordmovie) {
|
||||
// if(nes->cart == 0)
|
||||
// log_printf("main: cannot record movie without rom loaded.\n");
|
||||
// else {
|
||||
// emu_event(E_SAVEMOVIE,(void*)moviefilename);
|
||||
// emu_event(E_RECORDMOVIE,0);
|
||||
// nes->movie.mode |= (recordmovie > 1) ? MOVIE_TEST : 0;
|
||||
// }
|
||||
// }
|
||||
// else {
|
||||
// emu_event(E_LOADMOVIE,(void*)moviefilename);
|
||||
// emu_event(E_PLAYMOVIE,0);
|
||||
// }
|
||||
//}
|
||||
|
||||
//begin automated tests
|
||||
if(strcmp(testfilename,"") != 0)
|
||||
ret = emu_mainloop_test(testfilename);
|
||||
//if(strcmp(testfilename,"") != 0)
|
||||
// ret = emu_mainloop_test(testfilename);
|
||||
|
||||
//or begin the main loop
|
||||
else
|
||||
ret = emu_mainloop();
|
||||
//else
|
||||
ret = emu_mainloop();
|
||||
|
||||
//destroy emulator
|
||||
emu_kill();
|
||||
|
|
|
@ -18,29 +18,11 @@
|
|||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
|
||||
***************************************************************************/
|
||||
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <stdint.h>
|
||||
|
||||
uint32_t uptime();
|
||||
|
||||
#ifndef _MAX_PATH
|
||||
#define _MAX_PATH 4096
|
||||
#endif
|
||||
#include <klib.h>
|
||||
|
||||
int system_init() { return 0; }
|
||||
void system_kill() { }
|
||||
|
||||
void system_checkevents() { }
|
||||
|
||||
char *system_getcwd()
|
||||
{
|
||||
static char buf[_MAX_PATH];
|
||||
|
||||
if(getcwd(buf,_MAX_PATH) == NULL)
|
||||
memset(buf,0,_MAX_PATH);
|
||||
return(buf);
|
||||
}
|
||||
|
||||
char *system_getcwd() { return ""; }
|
||||
uint64_t system_gettick() { return uptime(); }
|
||||
uint64_t system_getfrequency() { return 1000; }
|
||||
|
|
|
@ -47,7 +47,7 @@ static u32 palettecache32[256];
|
|||
static u8 palettecache[32];
|
||||
|
||||
//for frame limiting
|
||||
static double interval = 0;
|
||||
static int interval = 0;
|
||||
static u64 lasttime = 0;
|
||||
|
||||
//pointer to scree and copy of the nes screen
|
||||
|
@ -94,7 +94,7 @@ int video_init()
|
|||
nesscreen = (u8*)mem_alloc(256 * (240 + 16));
|
||||
|
||||
//setup timer to limit frames
|
||||
interval = (double)system_getfrequency() / 60.0f;
|
||||
interval = system_getfrequency() / 60;
|
||||
lasttime = system_gettick();
|
||||
|
||||
//clear palette caches
|
||||
|
@ -158,13 +158,14 @@ void video_endframe()
|
|||
|
||||
//draw everything
|
||||
draw_rect(screen, 0, 0, 256, 240);
|
||||
draw_sync();
|
||||
console_draw(screen, 256*4,screenh);
|
||||
|
||||
//simple frame limiter
|
||||
if(config_get_bool("video.framelimit")) {
|
||||
do {
|
||||
t = system_gettick();
|
||||
} while((double)(t - lasttime) < interval);
|
||||
} while(t - lasttime < interval);
|
||||
lasttime = t;
|
||||
}
|
||||
}
|
||||
|
@ -220,20 +221,20 @@ void video_updatepalette(u8 addr,u8 data)
|
|||
void video_setpalette(palette_t *p)
|
||||
{
|
||||
int i,j;
|
||||
palentry_t *e;
|
||||
palentry_t e;
|
||||
|
||||
for(j=0;j<8;j++) {
|
||||
for(i=0;i<64;i++) {
|
||||
palette[j][(i * 3) + 0] = p->pal[j][i].r;
|
||||
palette[j][(i * 3) + 1] = p->pal[j][i].g;
|
||||
palette[j][(i * 3) + 2] = p->pal[j][i].b;
|
||||
}
|
||||
}
|
||||
//for(j=0;j<8;j++) {
|
||||
// for(i=0;i<64;i++) {
|
||||
// palette[j][(i * 3) + 0] = p->pal[j][i].r;
|
||||
// palette[j][(i * 3) + 1] = p->pal[j][i].g;
|
||||
// palette[j][(i * 3) + 2] = p->pal[j][i].b;
|
||||
// }
|
||||
//}
|
||||
|
||||
for(j=0;j<8;j++) {
|
||||
for(i=0;i<256;i++) {
|
||||
e = &p->pal[j][i & 0x3F];
|
||||
palette32[j][i] = (e->r << rshift) | (e->g << gshift) | (e->b << bshift);
|
||||
e.val = p->pal[j][i & 0x3F];
|
||||
palette32[j][i] = (e.r << rshift) | (e.g << gshift) | (e.b << bshift);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -254,6 +255,7 @@ int video_zapperhit(int x,int y)
|
|||
|
||||
color = palettecache[nesscreen[x + y * 256]];
|
||||
e = &palette[(color >> 5) & 7][(color & 0x3F) * 3];
|
||||
assert(0);
|
||||
ret += (int)(e[0] * 0.299f);
|
||||
ret += (int)(e[1] * 0.587f);
|
||||
ret += (int)(e[2] * 0.114f);
|
||||
|
|
|
@ -21,29 +21,29 @@
|
|||
#ifndef __types_h__
|
||||
#define __types_h__
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#define int64 __int64
|
||||
#define INLINE __inline
|
||||
#elif defined(__GNUC__)
|
||||
#define int64 long long
|
||||
#define INLINE inline
|
||||
#else
|
||||
#error unknown compiler. please #define int64.
|
||||
#endif
|
||||
#include <am.h>
|
||||
#define int64 long long
|
||||
#define INLINE inline
|
||||
|
||||
typedef signed char s8;
|
||||
typedef signed short s16;
|
||||
typedef signed int s32;
|
||||
typedef signed int64 s64;
|
||||
typedef int8_t s8;
|
||||
typedef int16_t s16;
|
||||
typedef int32_t s32;
|
||||
typedef int64_t s64;
|
||||
|
||||
typedef unsigned char u8;
|
||||
typedef unsigned short u16;
|
||||
typedef unsigned int u32;
|
||||
typedef unsigned int64 u64;
|
||||
typedef uint8_t u8;
|
||||
typedef uint16_t u16;
|
||||
typedef uint32_t u32;
|
||||
typedef uint64_t u64;
|
||||
|
||||
typedef u8 (*readfunc_t)(u32);
|
||||
typedef void (*writefunc_t)(u32,u8);
|
||||
|
||||
int stricmp(char *s1,char *s2);
|
||||
|
||||
// these are symbols conflicted with glibc
|
||||
#define sync my_sync
|
||||
#define read my_read
|
||||
#define write my_write
|
||||
#define select my_select
|
||||
|
||||
#endif
|
||||
|
|
|
@ -24,6 +24,8 @@
|
|||
#define vsprintf my_vsprintf
|
||||
#define sprintf my_sprintf
|
||||
#define snprintf my_snprintf
|
||||
#define malloc my_malloc
|
||||
#define free my_free
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
@ -53,7 +55,7 @@ int strcmp(const char* s1, const char* s2);
|
|||
int strncmp(const char* s1, const char* s2, size_t n);
|
||||
char* strtok(char* s,const char* delim);
|
||||
char *strstr(const char *, const char *);
|
||||
const char *strchr(const char *s, int c);
|
||||
char *strchr(const char *s, int c);
|
||||
|
||||
// stdlib.h
|
||||
int atoi(const char* nptr);
|
||||
|
@ -61,6 +63,8 @@ int abs(int x);
|
|||
unsigned long time();
|
||||
void srand(unsigned int seed);
|
||||
int rand();
|
||||
void *malloc(size_t size);
|
||||
void free(void *ptr);
|
||||
|
||||
// stdio.h
|
||||
int printf(const char* fmt, ...);
|
||||
|
|
|
@ -1,3 +1,6 @@
|
|||
#include "klib.h"
|
||||
|
||||
#if !defined(__ISA_NATIVE__) || defined(__NATIVE_USE_KLIB__)
|
||||
static unsigned long int next = 1;
|
||||
|
||||
int rand(void) {
|
||||
|
@ -9,3 +12,38 @@ int rand(void) {
|
|||
void srand(unsigned int seed) {
|
||||
next = seed;
|
||||
}
|
||||
|
||||
int abs(int x) {
|
||||
return (x < 0 ? -x : x);
|
||||
}
|
||||
|
||||
int atoi(const char* nptr) {
|
||||
int x = 0;
|
||||
while (*nptr != '\0') {
|
||||
x = x * 10 + *nptr - '0';
|
||||
nptr ++;
|
||||
}
|
||||
return x;
|
||||
}
|
||||
|
||||
void *malloc(size_t size) {
|
||||
static void *head = NULL;
|
||||
if (head == NULL) {
|
||||
head = _heap.start;
|
||||
printf("heap start = %x\n", head);
|
||||
}
|
||||
|
||||
// aligning
|
||||
size = (size + sizeof(uintptr_t) - 1) & ~(sizeof(uintptr_t) - 1);
|
||||
|
||||
if (head + size >= _heap.end) return NULL;
|
||||
printf("malloc: size = %d\n", size);
|
||||
void *ret = head;
|
||||
head += size;
|
||||
return ret;
|
||||
}
|
||||
|
||||
void free(void *ptr) {
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -170,4 +170,14 @@ int memcmp(const void* s1, const void* s2, size_t n){
|
|||
return (int)(*t1-*t2);
|
||||
}
|
||||
|
||||
char *strchr(const char *s, int c) {
|
||||
assert(0);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
char *strrchr(const char *s, int c) {
|
||||
assert(0);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
Loading…
Reference in New Issue