aboutsummaryrefslogtreecommitdiff
path: root/core/common
diff options
context:
space:
mode:
Diffstat (limited to 'core/common')
-rw-r--r--core/common/b_crypt.c136
-rw-r--r--core/common/debug.c311
-rw-r--r--core/common/files.c901
-rw-r--r--core/common/xctype.c185
4 files changed, 1533 insertions, 0 deletions
diff --git a/core/common/b_crypt.c b/core/common/b_crypt.c
new file mode 100644
index 0000000..649a0b7
--- /dev/null
+++ b/core/common/b_crypt.c
@@ -0,0 +1,136 @@
+/*
+ * Copyright © 2006-2013 SplinterGU (Fenix/Bennugd)
+ *
+ * This file is part of Bennu - Game Development
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty. In no event will the authors be held liable for any damages
+ * arising from the use of this software.
+ *
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to the following restrictions:
+ *
+ * 1. The origin of this software must not be misrepresented; you must not
+ * claim that you wrote the original software. If you use this software
+ * in a product, an acknowledgment in the product documentation would be
+ * appreciated but is not required.
+ *
+ * 2. Altered source versions must be plainly marked as such, and must not be
+ * misrepresented as being the original software.
+ *
+ * 3. This notice may not be removed or altered from any source
+ * distribution.
+ *
+ */
+
+/* ------------------------------------------------------------------------- */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "b_crypt.h"
+
+/* ------------------------------------------------------------------------- */
+
+crypt_handle * crypt_create( int method, char * key )
+{
+ crypt_handle * ch = calloc( sizeof( crypt_handle ), 1 );
+ if ( !ch ) return NULL;
+
+ ch->method = method;
+
+ switch ( method )
+ {
+ case CRYPT_DES :
+#ifdef USE_LIBDES
+ if ( !DES_key_sched( ( DES_cblock * ) key, ch->ks[KEY0] ) ) return ch;
+#else
+ if ( !DES_key_sched( ( DES_cblock * ) key, &ch->ks[KEY0] ) ) return ch;
+#endif
+ break;
+
+ case CRYPT_3DES :
+#ifdef USE_LIBDES
+ if ( DES_key_sched( ( DES_cblock * ) key, ch->ks[KEY0] ) ) { free( ch ); return NULL; }
+ if ( DES_key_sched( ( DES_cblock * ) ( 8 + key ), ch->ks[KEY1] ) ) { free( ch ); return NULL; }
+ if ( !DES_key_sched( ( DES_cblock * ) ( 16 + key ), ch->ks[KEY2] ) ) return ch;
+#else
+ if ( DES_key_sched( ( DES_cblock * ) key, &ch->ks[KEY0] ) ) { free( ch ); return NULL; }
+ if ( DES_key_sched( ( DES_cblock * ) ( 8 + key ), &ch->ks[KEY1] ) ) { free( ch ); return NULL; }
+ if ( !DES_key_sched( ( DES_cblock * ) ( 16 + key ), &ch->ks[KEY2] ) ) return ch;
+#endif
+ break;
+ }
+
+ free( ch );
+ return NULL;
+}
+
+/* ------------------------------------------------------------------------- */
+
+void crypt_destroy( crypt_handle * ch )
+{
+ if ( ch ) free( ch );
+}
+
+/* ------------------------------------------------------------------------- */
+
+int crypt_data( crypt_handle * ch, char * in, char * out, int size, int enc )
+{
+ DES_cblock aux;
+
+ if ( !ch || ( size < 1 || size > 8 ) ) return -1;
+
+ if ( enc && size < 8 ) memset( &in[size], '\0', 8 - size );
+
+ switch( ch->method )
+ {
+ case CRYPT_DES :
+ if ( enc )
+#ifdef USE_LIBDES
+ DES_ecb_encrypt( ( DES_cblock * ) in, ( DES_cblock * ) out, ch->ks[KEY0], DES_ENCRYPT );
+#else
+ DES_ecb_encrypt( ( DES_cblock * ) in, ( DES_cblock * ) out, &ch->ks[KEY0], DES_ENCRYPT );
+#endif
+ else
+#ifdef USE_LIBDES
+ DES_ecb_encrypt( ( DES_cblock * ) in, ( DES_cblock * ) out, ch->ks[KEY0], DES_DECRYPT );
+#else
+ DES_ecb_encrypt( ( DES_cblock * ) in, ( DES_cblock * ) out, &ch->ks[KEY0], DES_DECRYPT );
+#endif
+ break;
+
+ case CRYPT_3DES :
+ if ( enc )
+ {
+#ifdef USE_LIBDES
+ DES_ecb_encrypt( ( DES_cblock * ) in, ( DES_cblock * ) out, ch->ks[KEY0], DES_ENCRYPT );
+ DES_ecb_encrypt( ( DES_cblock * ) out, ( DES_cblock * ) &aux, ch->ks[KEY1], DES_DECRYPT );
+ DES_ecb_encrypt( ( DES_cblock * ) &aux, ( DES_cblock * ) out, ch->ks[KEY2], DES_ENCRYPT );
+#else
+ DES_ecb_encrypt( ( DES_cblock * ) in, ( DES_cblock * ) out, &ch->ks[KEY0], DES_ENCRYPT );
+ DES_ecb_encrypt( ( DES_cblock * ) out, ( DES_cblock * ) &aux, &ch->ks[KEY1], DES_DECRYPT );
+ DES_ecb_encrypt( ( DES_cblock * ) &aux, ( DES_cblock * ) out, &ch->ks[KEY2], DES_ENCRYPT );
+#endif
+ }
+ else
+ {
+#ifdef USE_LIBDES
+ DES_ecb_encrypt( ( DES_cblock * ) in, ( DES_cblock * ) out, ch->ks[KEY2], DES_DECRYPT );
+ DES_ecb_encrypt( ( DES_cblock * ) out, ( DES_cblock * ) &aux, ch->ks[KEY1], DES_ENCRYPT );
+ DES_ecb_encrypt( ( DES_cblock * ) &aux, ( DES_cblock * ) out, ch->ks[KEY0], DES_DECRYPT );
+#else
+ DES_ecb_encrypt( ( DES_cblock * ) in, ( DES_cblock * ) out, &ch->ks[KEY2], DES_DECRYPT );
+ DES_ecb_encrypt( ( DES_cblock * ) out, ( DES_cblock * ) &aux, &ch->ks[KEY1], DES_ENCRYPT );
+ DES_ecb_encrypt( ( DES_cblock * ) &aux, ( DES_cblock * ) out, &ch->ks[KEY0], DES_DECRYPT );
+#endif
+ }
+ break;
+ }
+
+ return ( enc ? 8 : size );
+}
+
+/* ------------------------------------------------------------------------- */
diff --git a/core/common/debug.c b/core/common/debug.c
new file mode 100644
index 0000000..edbd767
--- /dev/null
+++ b/core/common/debug.c
@@ -0,0 +1,311 @@
+/*
+ * Copyright © 2006-2013 SplinterGU (Fenix/Bennugd)
+ * Copyright © 2002-2006 Fenix Team (Fenix)
+ * Copyright © 1999-2002 José Luis Cebrián Pagüe (Fenix)
+ *
+ * This file is part of Bennu - Game Development
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty. In no event will the authors be held liable for any damages
+ * arising from the use of this software.
+ *
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to the following restrictions:
+ *
+ * 1. The origin of this software must not be misrepresented; you must not
+ * claim that you wrote the original software. If you use this software
+ * in a product, an acknowledgment in the product documentation would be
+ * appreciated but is not required.
+ *
+ * 2. Altered source versions must be plainly marked as such, and must not be
+ * misrepresented as being the original software.
+ *
+ * 3. This notice may not be removed or altered from any source
+ * distribution.
+ *
+ */
+
+#include <stdio.h>
+
+#include "pslang.h"
+#include "dcb.h"
+#include "xstrings.h"
+
+#ifndef __BGDRTM__
+#include "bgdc.h"
+#include "identifiers.h"
+#else
+#include "sysprocs_p.h"
+#include "i_procdef.h"
+#endif
+
+/* ---------------------------------------------------------------------- */
+/* Este módulo contiene funciones que muestran el equivalente */
+/* en texto de una instrucción o mnemónico */
+/* ---------------------------------------------------------------------- */
+
+struct
+{
+ char * name;
+ int code;
+ int params ;
+}
+mnemonics[] =
+{
+ { "ARRAY" , MN_ARRAY , 1 },
+ { "GET_PRIVATE" , MN_GET_PRIV , 1 },
+ { "GET_REMOTE" , MN_GET_REMOTE , 1 },
+ { "GET_LOCAL" , MN_GET_LOCAL , 1 },
+ { "GET_GLOBAL" , MN_GET_GLOBAL , 1 },
+ { "PRIVATE" , MN_PRIVATE , 1 },
+ { "REMOTE" , MN_REMOTE , 1 },
+ { "LOCAL" , MN_LOCAL , 1 },
+ { "GLOBAL" , MN_GLOBAL , 1 },
+ { "DUP" , MN_DUP , 0 },
+ { "PUSH" , MN_PUSH , 1 },
+ { "POP" , MN_POP , 0 },
+ { "INDEX" , MN_INDEX , 1 },
+ { "NEG" , MN_NEG , 0 },
+ { "NOT" , MN_NOT , 0 },
+ { "CALL" , MN_CALL , 1 },
+ { "PROCESS" , MN_PROC , 1 },
+ { "SYSCALL" , MN_SYSCALL , 1 },
+ { "SYSPROC" , MN_SYSPROC , 1 },
+ { "CLONE" , MN_CLONE , 1 },
+ { "END" , MN_END , 0 },
+ { "RETURN" , MN_RETURN , 0 },
+ { "FRAME" , MN_FRAME , 0 },
+ { "TYPE" , MN_TYPE , 1 },
+
+ { "MUL" , MN_MUL , 0 },
+ { "DIV" , MN_DIV , 0 },
+ { "ADD" , MN_ADD , 0 },
+ { "SUB" , MN_SUB , 0 },
+ { "MOD" , MN_MOD , 0 },
+ { "ROR" , MN_ROR , 0 },
+ { "ROL" , MN_ROL , 0 },
+ { "AND" , MN_AND , 0 },
+ { "OR" , MN_OR , 0 },
+ { "XOR" , MN_XOR , 0 },
+
+ { "BNOT" , MN_BNOT , 0 },
+ { "BAND" , MN_BAND , 0 },
+ { "BOR" , MN_BOR , 0 },
+ { "BXOR" , MN_BXOR , 0 },
+
+ { "EQ" , MN_EQ , 0 },
+ { "NE" , MN_NE , 0 },
+ { "GT" , MN_GT , 0 },
+ { "LT" , MN_LT , 0 },
+ { "GTE" , MN_GTE , 0 },
+ { "LTE" , MN_LTE , 0 },
+
+ { "FLOAT2INT" , MN_FLOAT2INT , 1 },
+ { "INT2FLOAT" , MN_INT2FLOAT , 1 },
+ { "INT2WORD" , MN_INT2WORD , 1 },
+ { "INT2BYTE" , MN_INT2BYTE , 1 },
+
+ { "POSTINC" , MN_POSTINC , 1 },
+ { "POSTDEC" , MN_POSTDEC , 1 },
+ { "INC" , MN_INC , 1 },
+ { "DEC" , MN_DEC , 1 },
+ { "VARADD" , MN_VARADD , 0 },
+ { "VARSUB" , MN_VARSUB , 0 },
+ { "VARMUL" , MN_VARMUL , 0 },
+ { "VARDIV" , MN_VARDIV , 0 },
+ { "VARMOD" , MN_VARMOD , 0 },
+ { "VARXOR" , MN_VARXOR , 0 },
+ { "VARAND" , MN_VARAND , 0 },
+ { "VAROR" , MN_VAROR , 0 },
+ { "VARROR" , MN_VARROR , 0 },
+ { "VARROL" , MN_VARROL , 0 },
+ { "LET" , MN_LET , 0 },
+ { "LETNP" , MN_LETNP , 0 },
+
+ { "REPEAT" , MN_REPEAT , 1 },
+ { "BREAK" , MN_BREAK , 1 },
+ { "BRFALSE" , MN_BRFALSE , 1 },
+ { "RETRUE" , MN_RETRUE , 1 },
+ { "REFALSE" , MN_REFALSE , 1 },
+ { "JUMP" , MN_JUMP , 1 },
+ { "JFALSE" , MN_JFALSE , 1 },
+ { "JTRUE" , MN_JTRUE , 1 },
+ { "JTFALSE" , MN_JTFALSE , 1 },
+ { "JTTRUE" , MN_JTTRUE , 1 },
+ { "PTR" , MN_PTR , 0 },
+
+ { "SWITCH" , MN_SWITCH , 0 },
+ { "CASE" , MN_CASE , 0 },
+ { "CASE_R" , MN_CASE_R , 0 },
+ { "JNOCASE" , MN_JNOCASE , 1 },
+
+ { "STRI2CHR" , MN_STRI2CHR , 0 },
+ { "SUBSTR" , MN_SUBSTR , 1 },
+
+ { "STR2INT" , MN_STR2INT , 1 },
+ { "STR2CHR" , MN_STR2CHR , 1 },
+ { "INT2STR" , MN_INT2STR , 1 },
+ { "CHR2STR" , MN_CHR2STR , 1 },
+ { "STR2FLOAT" , MN_STR2FLOAT , 1 },
+ { "FLOAT2STR" , MN_FLOAT2STR , 1 },
+ { "POINTER2STR" , MN_POINTER2STR , 1 },
+
+ { "A2STR" , MN_A2STR , 0 },
+ { "STR2A" , MN_STR2A , 0 },
+ { "STRACAT" , MN_STRACAT , 0 },
+
+ { "MN_NCALL" , MN_NCALL , 1 },
+
+ { "MN_EXITHNDLR" , MN_EXITHNDLR , 1 },
+ { "MN_ERRHNDLR" , MN_ERRHNDLR , 1 },
+ { "MN_RESUME" , MN_RESUME , 1 },
+ { "MN_RESUMEGOTO" , MN_RESUMEGOTO , 1 },
+
+ { "DEBUG" , MN_DEBUG , 1 },
+ { "" , MN_SENTENCE , 1 },
+
+ { "PUBLIC" , MN_PUBLIC , 1 },
+ { "GET_PUBLIC" , MN_GET_PUBLIC , 1 },
+
+ { "REMOTE_PUBLIC" , MN_REMOTE_PUBLIC , 1 },
+ { "GET_REMOTE_PUBLIC" , MN_GET_REMOTE_PUBLIC , 1 },
+
+ { 0 , -1 , 0 }
+} ;
+
+/* ---------------------------------------------------------------------- */
+
+#ifdef __BGDRTM__
+extern int debug;
+#endif
+
+static int mnemonics_inited = 0;
+
+struct
+{
+ char name[21];
+ int params ;
+}
+mnemonics_sorted[256];
+
+/* ---------------------------------------------------------------------- */
+
+void mnemonic_dump( int i, int param )
+{
+ int n = 0 ;
+
+ if ( !mnemonics_inited )
+ {
+ while ( mnemonics[n].name )
+ {
+ sprintf( mnemonics_sorted[mnemonics[n].code & MN_MASK].name, "%-20s", mnemonics[n].name );
+ mnemonics_sorted[mnemonics[n].code & MN_MASK].params = mnemonics[n].params;
+ n++ ;
+ }
+ mnemonics_inited = 1;
+ }
+
+ n = i & MN_MASK ;
+
+#ifdef __BGDRTM__
+ if ( debug > 1 )
+ {
+#endif
+ if ( MN_PARAMS( i ) ) printf( "%08X %08X " , i, param );
+ else printf( "%08X ", i );
+#ifdef __BGDRTM__
+ }
+#endif
+
+ if ( mnemonics_sorted[ n ].name )
+ {
+#ifdef __BGDRTM__
+ if ( debug > 1 )
+ {
+#endif
+ switch ( MN_TYPEOF( i ) )
+ {
+ case MN_UNSIGNED:
+ printf( "UNSIGNED " ) ;
+ break ;
+
+ case MN_WORD:
+ printf( "SHORT " ) ;
+ break ;
+
+ case MN_WORD | MN_UNSIGNED:
+ printf( "WORD " ) ;
+ break ;
+
+ case MN_BYTE:
+ printf( "CHAR " ) ;
+ break ;
+
+ case MN_BYTE | MN_UNSIGNED:
+ printf( "BYTE " ) ;
+ break ;
+
+ case MN_FLOAT:
+ printf( "FLOAT " ) ;
+ break ;
+
+ case MN_STRING:
+ printf( "STRING " ) ;
+ break ;
+
+ default:
+ printf( " " ) ;
+ break ;
+ }
+
+ printf( "%s", mnemonics_sorted[n].name ) ;
+
+ if ( i == MN_SYSCALL || i == MN_SYSPROC )
+ {
+ printf( "%s (%d)\n", sysproc_name( param ), param ) ;
+ }
+ else if ( i == MN_CALL || i == MN_PROC || i == MN_TYPE )
+ {
+#ifndef __BGDRTM__
+ if ( libmode ) printf( "%s (%d)\n", identifier_name( (procdef_search(param))->identifier ), param ) ;
+ else printf( "%s (%d)\n", identifier_name( (procdef_get(param))->identifier ), param ) ;
+#else
+ printf( "%s (%d)\n", procdef_get(param)->name, param ) ;
+#endif
+ }
+ else if ( i != MN_SENTENCE )
+ {
+ switch ( MN_PARAMS( i ) )
+ {
+ case 1:
+ printf( "%d", param ) ;
+ break;
+
+ }
+ printf( "\n" ) ;
+ }
+
+#ifdef __BGDRTM__
+ }
+#endif
+
+ if ( i == MN_SENTENCE )
+ {
+#ifdef __BGDRTM__
+ if ( dcb.sourcecount[param >> 24] )
+ {
+ if ( dcb.data.Version == 0x0700 ) printf( "%s:%-10d %s\n", dcb.sourcefiles[param >> 24], param & 0xFFFFFF, dcb.sourcelines[param >> 24] [( param & 0xFFFFFF )-1] ) ;
+ else printf( "%s:%-10d %s\n", dcb.sourcefiles[param >> 20], param & 0xFFFFF , dcb.sourcelines[param >> 20] [( param & 0xFFFFF )-1] ) ;
+ }
+#else
+ printf( "%s:%-10d\n", files[param>>20], param&(( 1 << 20 ) - 1 ) ) ;
+#endif
+ }
+ }
+#ifdef __BGDRTM__
+ else if ( debug > 1 )
+#endif
+ printf( "\n" );
+
+}
diff --git a/core/common/files.c b/core/common/files.c
new file mode 100644
index 0000000..8c3be7d
--- /dev/null
+++ b/core/common/files.c
@@ -0,0 +1,901 @@
+/*
+ * Copyright � 2006-2013 SplinterGU (Fenix/Bennugd)
+ * Copyright � 2002-2006 Fenix Team (Fenix)
+ * Copyright � 1999-2002 Jos� Luis Cebri�n Pag�e (Fenix)
+ *
+ * This file is part of Bennu - Game Development
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty. In no event will the authors be held liable for any damages
+ * arising from the use of this software.
+ *
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to the following restrictions:
+ *
+ * 1. The origin of this software must not be misrepresented; you must not
+ * claim that you wrote the original software. If you use this software
+ * in a product, an acknowledgment in the product documentation would be
+ * appreciated but is not required.
+ *
+ * 2. Altered source versions must be plainly marked as such, and must not be
+ * misrepresented as being the original software.
+ *
+ * 3. This notice may not be removed or altered from any source
+ * distribution.
+ *
+ */
+
+#ifdef _WIN32
+#include <windows.h>
+#endif
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+#ifdef TARGET_BEOS
+#include <posix/assert.h>
+#else
+#include <assert.h>
+#endif
+
+#include <stdint.h>
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+
+#include "files.h"
+
+#define MAX_POSSIBLE_PATHS 128
+
+char * possible_paths[MAX_POSSIBLE_PATHS] = { NULL } ;
+
+int opened_files = 0;
+
+typedef struct
+{
+ char * stubname ;
+ char * name ;
+ int offset ;
+ int size ;
+ FILE * fp ;
+}
+XFILE ;
+
+XFILE * x_file = NULL ;
+int max_x_files = 0;
+
+int x_files_count = 0 ;
+
+/* Add new file to PATH */
+
+void xfile_init( int maxfiles )
+{
+ x_file = ( XFILE * ) calloc( sizeof( XFILE ), maxfiles );
+ max_x_files = maxfiles;
+}
+
+void file_add_xfile( file * fp, char * stubname, long offset, char * name, int size )
+{
+ char * ptr ;
+
+ assert( x_files_count < max_x_files ) ;
+ assert( fp->type == F_FILE ) ;
+
+ x_file[x_files_count].stubname = strdup( stubname );
+ x_file[x_files_count].fp = fp->fp ;
+ x_file[x_files_count].offset = offset ;
+ x_file[x_files_count].size = size ;
+ x_file[x_files_count].name = strdup( name ) ;
+
+ ptr = x_file[x_files_count].name;
+ while ( *ptr )
+ {
+ if ( *ptr == '\\' ) *ptr = '/'; /* Unix style */
+ ptr++;
+ }
+
+ x_files_count++ ;
+}
+
+/* Read a datablock from file */
+
+int file_read( file * fp, void * buffer, int len )
+{
+ assert( len != 0 );
+
+ if ( fp->type == F_XFILE )
+ {
+ XFILE * xf ;
+ int result ;
+
+ xf = &x_file[fp->n] ;
+
+ if (( len + fp->pos ) > ( xf->offset + xf->size ) )
+ {
+ fp->eof = 1 ;
+ len = xf->size + xf->offset - fp->pos ;
+ }
+
+ fseek( fp->fp, fp->pos, SEEK_SET ) ;
+ result = fread( buffer, 1, len, fp->fp ) ;
+
+ fp->pos = ftell( fp->fp ) ;
+ return result ;
+ }
+
+#ifndef NO_ZLIB
+ if ( fp->type == F_GZFILE )
+ {
+ int result = gzread( fp->gz, buffer, len ) ;
+ fp->error = ( result < len );
+ if ( result < 0 ) result = 0;
+ return result ;
+ }
+#endif
+
+ return fread( buffer, 1, len, fp->fp ) ;
+}
+
+/* Save a unquoted string to a file */
+
+int file_qputs( file * fp, char * buffer )
+{
+ char dest[1024], * optr ;
+ const char * ptr ;
+
+ ptr = buffer ;
+ optr = dest ;
+ while ( *ptr )
+ {
+ if ( optr > dest + 1000 )
+ {
+ *optr++ = '\\' ;
+ *optr++ = '\n' ;
+ *optr = 0 ;
+ file_write( fp, dest, optr - dest ) ;
+ optr = dest ;
+ }
+ if ( *ptr == '\n' )
+ {
+ *optr++ = '\\' ;
+ *optr++ = 'n' ;
+ ptr++ ;
+ continue ;
+ }
+ if ( *ptr == '\\' )
+ {
+ *optr++ = '\\' ;
+ *optr++ = *ptr++ ;
+ continue ;
+ }
+ *optr++ = *ptr++ ;
+ }
+ *optr++ = '\n' ;
+ return file_write( fp, dest, optr - dest ) ;
+}
+
+/* Load a string from a file and unquoted it */
+
+int file_qgets( file * fp, char * buffer, int len )
+{
+ char * ptr, * result = NULL ;
+
+ if ( fp->type == F_XFILE )
+ {
+ XFILE * xf ;
+ int l = 0;
+ char * ptr = result = buffer ;
+
+ xf = &x_file[fp->n] ;
+
+ fseek( fp->fp, fp->pos, SEEK_SET ) ;
+ while ( l < len )
+ {
+ if ( fp->pos >= xf->offset + xf->size )
+ {
+ fp->eof = 1 ;
+ break ;
+ }
+ fread( ptr, 1, 1, fp->fp ) ;
+ l++ ;
+ fp->pos++ ;
+ if ( *ptr++ == '\n' ) break ;
+ }
+ *ptr = 0 ;
+ fp->pos = ftell( fp->fp ) ;
+
+ if ( l == 0 ) return 0 ;
+ }
+#ifndef NO_ZLIB
+ else if ( fp->type == F_GZFILE )
+ {
+ result = gzgets( fp->gz, buffer, len ) ;
+ }
+#endif
+ else
+ {
+ result = fgets( buffer, len, fp->fp );
+ }
+
+ if ( result == NULL )
+ {
+ buffer[0] = 0 ; return 0 ;
+ }
+
+ ptr = buffer ;
+ while ( *ptr )
+ {
+ if ( *ptr == '\\' )
+ {
+ if ( ptr[1] == 'n' ) ptr[1] = '\n' ;
+ strcpy( ptr, ptr + 1 ) ;
+ ptr++ ;
+ continue ;
+ }
+ if ( *ptr == '\n' )
+ {
+ *ptr = 0 ;
+ break ;
+ }
+ ptr++ ;
+ }
+ return strlen( buffer ) ;
+}
+
+/* Save a string to file */
+
+int file_puts( file * fp, char * buffer )
+{
+ return file_write( fp, buffer, strlen( buffer ) ) ;
+}
+
+/* Load a string from a file and unquoted it */
+
+int file_gets( file * fp, char * buffer, int len )
+{
+ char * result = NULL ;
+
+ if ( fp->type == F_XFILE )
+ {
+ XFILE * xf ;
+ int l = 0;
+ char * ptr = result = buffer ;
+
+ xf = &x_file[fp->n] ;
+
+ fseek( fp->fp, fp->pos, SEEK_SET ) ;
+ while ( l < len )
+ {
+ if ( fp->pos >= xf->offset + xf->size )
+ {
+ fp->eof = 1 ;
+ break ;
+ }
+ fread( ptr, 1, 1, fp->fp ) ;
+ l++ ;
+ fp->pos++ ;
+ if ( *ptr++ == '\n' ) break ;
+ }
+ *ptr = 0 ;
+ fp->pos = ftell( fp->fp ) ;
+
+ if ( l == 0 ) return 0 ;
+ }
+#ifndef NO_ZLIB
+ else if ( fp->type == F_GZFILE )
+ {
+ result = gzgets( fp->gz, buffer, len ) ;
+ }
+#endif
+ else
+ {
+ result = fgets( buffer, len, fp->fp );
+ }
+
+ if ( result == NULL )
+ {
+ buffer[0] = 0 ;
+ return 0 ;
+ }
+
+ return strlen( buffer ) ;
+}
+
+/* Save an int data to a binary file */
+
+int file_writeSint8( file * fp, int8_t * buffer )
+{
+ return file_write( fp, buffer, sizeof( uint8_t ) );
+}
+
+int file_writeUint8( file * fp, uint8_t * buffer )
+{
+ return file_write( fp, buffer, sizeof( uint8_t ) );
+}
+
+int file_writeSint16( file * fp, int16_t * buffer )
+{
+#if __BYTEORDER == __LIL_ENDIAN
+ return file_write( fp, buffer, sizeof( int16_t ) );
+#else
+ file_write( fp, ( uint8_t * )buffer + 1, 1 );
+ return file_write( fp, ( uint8_t * )buffer, 1 );
+#endif
+}
+
+int file_writeUint16( file * fp, uint16_t * buffer )
+{
+ return file_writeSint16( fp, ( int16_t * ) buffer );
+}
+
+int file_writeSint32( file * fp, int32_t * buffer )
+{
+#if __BYTEORDER == __LIL_ENDIAN
+ return file_write( fp, buffer, sizeof( int32_t ) );
+#else
+ file_write( fp, ( uint8_t * )buffer + 3, 1 );
+ file_write( fp, ( uint8_t * )buffer + 2, 1 );
+ file_write( fp, ( uint8_t * )buffer + 1, 1 );
+ return file_write( fp, ( uint8_t * )buffer, 1 );
+#endif
+}
+
+int file_writeUint32( file * fp, uint32_t * buffer )
+{
+ return file_writeSint32( fp, ( int32_t * )buffer );
+}
+
+/* Save an array to a binary file */
+
+int file_writeSint8A( file * fp, int8_t * buffer, int n )
+{
+ return file_write( fp, buffer, n );
+}
+
+int file_writeUint8A( file * fp, uint8_t * buffer, int n )
+{
+ return file_write( fp, buffer, n );
+}
+
+int file_writeSint16A( file * fp, int16_t * buffer, int n )
+{
+#if __BYTEORDER == __LIL_ENDIAN
+ return file_write( fp, buffer, n << 1 ) >> 1 ;
+#else
+ int i;
+ for ( i = 0; i < n; i++ )
+ if ( !file_writeSint16( fp, ( int16_t * )buffer++ ) ) break;
+ return i;
+#endif
+}
+
+int file_writeUint16A( file * fp, uint16_t * buffer, int n )
+{
+ return file_writeSint16A( fp, ( int16_t * )buffer, n );
+}
+
+int file_writeSint32A( file * fp, int32_t * buffer, int n )
+{
+#if __BYTEORDER == __LIL_ENDIAN
+ return file_write( fp, buffer, n << 2 ) >> 2;
+#else
+ int i;
+ for ( i = 0; i < n; i++ )
+ if ( !file_writeSint32( fp, ( int32_t * )buffer++ ) ) break;
+ return i;
+#endif
+}
+
+int file_writeUint32A( file * fp, uint32_t * buffer, int n )
+{
+ return file_writeSint32A( fp, ( int32_t * )buffer, n );
+}
+
+/* Read an int data from a binary file */
+
+int file_readSint8( file * fp, int8_t * buffer )
+{
+ return file_read( fp, buffer, sizeof( int8_t ) );
+}
+
+int file_readUint8( file * fp, uint8_t * buffer )
+{
+ return file_read( fp, buffer, sizeof( int8_t ) );
+}
+
+int file_readSint16( file * fp, int16_t * buffer )
+{
+#if __BYTEORDER == __LIL_ENDIAN
+ return file_read( fp, buffer, sizeof( int16_t ) );
+#else
+ file_read( fp, ( uint8_t * )buffer + 1, 1 );
+ return file_read( fp, ( uint8_t * )buffer, 1 );
+#endif
+}
+
+int file_readUint16( file * fp, uint16_t * buffer )
+{
+ return file_readSint16( fp, (int16_t *)buffer );
+}
+
+int file_readSint32( file * fp, int32_t * buffer )
+{
+#if __BYTEORDER == __LIL_ENDIAN
+ return file_read( fp, buffer, sizeof( int32_t ) );
+#else
+ file_read( fp, ( uint8_t * )buffer + 3, 1 );
+ file_read( fp, ( uint8_t * )buffer + 2, 1 );
+ file_read( fp, ( uint8_t * )buffer + 1, 1 );
+ return file_read( fp, ( uint8_t * )buffer, 1 );
+#endif
+}
+
+int file_readUint32( file * fp, uint32_t * buffer )
+{
+ return file_readSint32( fp, ( int32_t * )buffer );
+}
+
+/* Read an array from a binary file */
+
+int file_readSint8A( file * fp, int8_t * buffer, int n )
+{
+ return file_read( fp, buffer, n );
+}
+
+int file_readUint8A( file * fp, uint8_t * buffer, int n )
+{
+ return file_read( fp, buffer, n );
+}
+
+int file_readSint16A( file * fp, int16_t * buffer, int n )
+{
+#if __BYTEORDER == __LIL_ENDIAN
+ return file_read( fp, buffer, n << 1 ) >> 1;
+#else
+ int i;
+ for ( i = 0; i < n; i++ )
+ if ( !file_readSint16( fp, ( int16_t * )buffer++ ) ) break;
+ return i;
+#endif
+}
+
+int file_readUint16A( file * fp, uint16_t * buffer, int n )
+{
+ return file_readSint16A( fp, ( int16_t * )buffer, n );
+}
+
+int file_readSint32A( file * fp, int32_t * buffer, int n )
+{
+#if __BYTEORDER == __LIL_ENDIAN
+ return file_read( fp, buffer, n << 2 ) >> 2;
+#else
+ int i;
+ for ( i = 0; i < n; i++ )
+ if ( !file_readSint32( fp, ( int32_t * )buffer++ ) ) break;
+ return i;
+#endif
+}
+
+int file_readUint32A( file * fp, uint32_t * buffer, int n )
+{
+ return file_readSint32A( fp, ( int32_t * )buffer, n );
+}
+
+
+/* Write a datablock to a file */
+
+int file_write( file * fp, void * buffer, int len )
+{
+ if ( fp->type == F_XFILE )
+ {
+ XFILE * xf ;
+ int result ;
+
+ xf = &x_file[fp->n] ;
+
+ if (( len + fp->pos ) > ( xf->offset + xf->size ) )
+ {
+ fp->eof = 1 ;
+ len = xf->size + xf->offset - fp->pos ;
+ }
+ fseek( fp->fp, fp->pos, SEEK_SET ) ;
+ result = fwrite( buffer, 1, len, fp->fp ) ;
+ fp->pos = ftell( fp->fp ) ;
+ return result ;
+ }
+
+#ifndef NO_ZLIB
+ if ( fp->type == F_GZFILE )
+ {
+ int result = gzwrite( fp->gz, buffer, len ) ;
+ if (( fp->error = ( result < 0 ) ) != 0 ) result = 0 ;
+ return ( result < len ) ? 0 : len ;
+ }
+#endif
+
+ return fwrite( buffer, 1, len, fp->fp ) ;
+}
+
+/* Return file size */
+
+int file_size( file * fp )
+{
+ long pos, size ;
+
+ if ( fp->type == F_XFILE ) return x_file[fp->n].size ;
+
+ pos = file_pos( fp );
+#ifndef NO_ZLIB
+ if ( fp->type == F_GZFILE )
+ {
+ char buffer[8192];
+ size = pos;
+ while ( !file_eof( fp ) ) size += file_read( fp, buffer, sizeof(buffer) );
+ }
+ else
+#endif
+ {
+ file_seek(fp, 0, SEEK_END ) ;
+ size = file_pos( fp ) ;
+ }
+ file_seek(fp, pos, SEEK_SET ) ;
+
+ return size ;
+}
+
+/* Get current file pointer position */
+
+int file_pos( file * fp )
+{
+ if ( fp->type == F_XFILE ) return fp->pos - x_file[fp->n].offset ;
+
+#ifndef NO_ZLIB
+ if ( fp->type == F_GZFILE ) return gztell( fp->gz ) ;
+#endif
+
+ return ftell( fp->fp ) ;
+}
+
+int file_flush( file * fp )
+{
+ if ( fp->type == F_XFILE ) return 0 ;
+
+#ifndef NO_ZLIB
+ if ( fp->type == F_GZFILE ) return 0 ;
+#endif
+
+ return fflush( fp->fp ) ;
+}
+
+/* Set current file pointer position */
+
+int file_seek( file * fp, int pos, int where )
+{
+ assert( fp );
+ if ( fp->type == F_XFILE )
+ {
+ if ( where == SEEK_END )
+ pos = x_file[fp->n].size - pos + 1 ;
+ else if ( where == SEEK_CUR )
+ pos += ( fp->pos - x_file[fp->n].offset );
+
+ if ( x_file[fp->n].size < pos ) pos = x_file[fp->n].size ;
+
+ if ( pos < 0 ) pos = 0 ;
+
+ fp->pos = pos + x_file[fp->n].offset ;
+ return pos ;
+ }
+
+#ifndef NO_ZLIB
+ if ( fp->type == F_GZFILE )
+ {
+ assert( fp->gz );
+ return gzseek( fp->gz, pos, where ) ;
+ }
+#endif
+
+ assert( fp->fp );
+ return fseek( fp->fp, pos, where ) ;
+}
+
+void file_rewind( file * fp )
+{
+ fp->error = 0;
+
+ switch ( fp->type )
+ {
+ case F_XFILE:
+ fp->pos = x_file[fp->n].offset ;
+ break;
+
+#ifndef NO_ZLIB
+ case F_GZFILE:
+ gzrewind( fp->gz ) ;
+ break;
+#endif
+
+ default:
+ rewind( fp->fp ) ;
+ }
+}
+
+/* Open file */
+
+static int open_raw( file * f, const char * filename, const char * mode )
+{
+ char _mode[5];
+ char *p;
+
+#ifndef NO_ZLIB
+ if ( !strchr( mode, '0' ) )
+ {
+ f->type = F_GZFILE ;
+ f->gz = gzopen( filename, mode ) ;
+ f->eof = 0 ;
+ if ( f->gz ) return 1 ;
+ }
+#endif
+
+ p = _mode;
+ while ( *mode )
+ {
+ if ( *mode != '0' )
+ {
+ *p = *mode;
+ p++;
+ }
+ mode++;
+ }
+ *p = '\0';
+
+ f->eof = 0 ;
+ f->type = F_FILE ;
+ f->fp = fopen( filename, _mode ) ;
+ if ( f->fp ) return 1 ;
+ return 0 ;
+}
+
+file * file_open( const char * filename, char * mode )
+{
+ char work [__MAX_PATH];
+ char here [__MAX_PATH];
+
+ char * name = NULL ;
+ char * p, c ;
+ int i;
+
+ file * f ;
+
+ f = ( file * ) calloc( 1, sizeof( file ) ) ;
+ assert( f ) ;
+
+ p = f->name;
+ while ( *filename )
+ {
+ *p++ = *filename++;
+ if ( p[-1] == '\\' ) p[-1] = '/'; /* Unix style */
+ }
+ p[0] = '\0';
+
+ filename = f->name;
+
+ if ( open_raw( f, filename, mode ) )
+ {
+ opened_files++;
+ return f ;
+ }
+
+
+ /* if real file don't exists in disk */
+ if ( strchr( mode, 'r' ) && strchr( mode, 'b' ) && /* Only read-only files */
+ !strchr( mode, '+' ) && !strchr( mode, 'w' ) )
+ {
+ for ( i = 0 ; i < x_files_count ; i++ )
+ {
+ if ( strcmp( filename, x_file[i].name ) == 0 )
+ {
+ f->eof = 0;
+ f->pos = x_file[i].offset;
+ f->type = F_XFILE;
+ f->n = i;
+ f->fp = fopen( x_file[i].stubname, "rb" );
+
+ opened_files++;
+ return f ;
+ }
+ }
+ }
+
+ p = name = work;
+ while (( c = *filename ) )
+ {
+ if ( c == '\\' || c == '/' )
+ {
+ c = 0;
+ name = p + 1;
+ }
+ *p++ = c;
+ filename++;
+ }
+ *p = '\0';
+
+ /* Use file extension for search in a directory named as it (for example: FPG dir for .FPG files) */
+ if ( strchr( name, '.' ) )
+ {
+ strcpy( here, strrchr( name, '.' ) + 1 ) ;
+ strcat( here, PATH_SEP ) ;
+ strcat( here, name ) ;
+ if ( open_raw( f, here, mode ) )
+ {
+ opened_files++;
+ return f ;
+ }
+ }
+
+ for ( i = 0 ; possible_paths[i] ; i++ )
+ {
+ strcpy( here, possible_paths[i] ) ;
+ strcat( here, name ) ;
+ if ( open_raw( f, here, mode ) )
+ {
+ opened_files++;
+ return f ;
+ }
+ }
+
+ free( f ) ;
+ return 0 ;
+}
+
+/* Close file */
+
+void file_close( file * fp )
+{
+ if ( fp == NULL ) return;
+ if ( fp->type == F_FILE ) fclose( fp->fp ) ;
+ if ( fp->type == F_XFILE ) fclose( fp->fp ) ;
+#ifndef NO_ZLIB
+ if ( fp->type == F_GZFILE ) gzclose( fp->gz ) ;
+#endif
+ opened_files--;
+ free( fp ) ;
+}
+
+/* Add a new dir to PATH */
+
+void file_addp( const char * path )
+{
+ char truepath[__MAX_PATH];
+ int n ;
+
+ if ( !path || !*path ) return;
+
+ strcpy( truepath, path ) ;
+
+ for ( n = 0 ; truepath[n] ; n++ ) if ( truepath[n] == '\\' ) truepath[n] = '/' ;
+ if ( truepath[strlen( truepath )-1] != '/' ) strcat( truepath, "/" ) ;
+
+ for ( n = 0 ; n < MAX_POSSIBLE_PATHS - 1 && possible_paths[n] ; n++ ) ;
+
+ possible_paths[n] = strdup( truepath ) ;
+ possible_paths[n+1] = NULL ;
+}
+
+/* --- */
+
+int file_remove( const char * filename )
+{
+ return ( remove( filename ) );
+}
+
+/* --- */
+
+int file_move( const char * source_file, const char * target_file )
+{
+ return ( rename( source_file, target_file ) );
+}
+
+/* Check for file exists */
+
+int file_exists( const char * filename )
+{
+ file * fp ;
+
+ fp = file_open( filename, "rb" ) ;
+ if ( fp )
+ {
+ file_close( fp ) ;
+ return 1 ;
+ }
+ return 0 ;
+}
+
+/* Check for file end is reached */
+
+int file_eof( file * fp )
+{
+ if ( fp->type == F_XFILE )
+ {
+ return fp->eof ? 1 : 0;
+ }
+
+#ifndef NO_ZLIB
+ if ( fp->type == F_GZFILE )
+ {
+ if ( fp->error ) return 1 ;
+ return gzeof( fp->gz ) ? 1 : 0;
+ }
+#endif
+
+ return feof( fp->fp ) ? 1 : 0;
+}
+
+/* Get the FILE * of the file */
+
+FILE * file_fp( file * f )
+{
+ if ( f->type == F_XFILE )
+ {
+// XFILE * xf = &x_file[f->n] ;
+ fseek( f->fp, f->pos, SEEK_SET ) ;
+ return f->fp ;
+ }
+
+ return f->fp ;
+}
+
+/* ------------------------------------------------------------------------------------ */
+
+char * getfullpath( char *rel_path )
+{
+ char fullpath[ __MAX_PATH ] = "";
+#ifdef _WIN32
+ GetFullPathName( rel_path, sizeof( fullpath ), fullpath, NULL );
+#else
+ realpath( rel_path, fullpath );
+#endif
+ if ( *fullpath ) return strdup( fullpath );
+ return NULL;
+}
+
+/* ------------------------------------------------------------------------------------ */
+
+#ifdef _WIN32
+ #define ENV_PATH_SEP ';'
+#else
+ #define ENV_PATH_SEP ':'
+#endif
+
+char * whereis( char *file )
+{
+ char * path = getenv( "PATH" ), *pact = path, *p;
+ char fullname[ __MAX_PATH ];
+
+ while ( pact && *pact )
+ {
+ struct stat st;
+
+ if ( ( p = strchr( pact, ENV_PATH_SEP ) ) ) *p = '\0';
+ sprintf( fullname, "%s%s%s", pact, ( pact[ strlen( pact ) - 1 ] == ENV_PATH_SEP ) ? "" : PATH_SEP, file );
+
+ if ( !stat( fullname, &st ) && S_ISREG( st.st_mode ) )
+ {
+ pact = strdup( pact );
+ if ( p ) *p = ENV_PATH_SEP;
+ return ( pact );
+ }
+
+ if ( !p ) break;
+
+ *p = ENV_PATH_SEP;
+ pact = p + 1;
+ }
+
+ return NULL;
+}
+
+/* ------------------------------------------------------------------------------------ */
diff --git a/core/common/xctype.c b/core/common/xctype.c
new file mode 100644
index 0000000..1c5bf8f
--- /dev/null
+++ b/core/common/xctype.c
@@ -0,0 +1,185 @@
+/*
+ * Copyright © 2006-2013 SplinterGU (Fenix/Bennugd)
+ * Copyright © 2002-2006 Fenix Team (Fenix)
+ * Copyright © 1999-2002 José Luis Cebrián Pagüe (Fenix)
+ *
+ * This file is part of Bennu - Game Development
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty. In no event will the authors be held liable for any damages
+ * arising from the use of this software.
+ *
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to the following restrictions:
+ *
+ * 1. The origin of this software must not be misrepresented; you must not
+ * claim that you wrote the original software. If you use this software
+ * in a product, an acknowledgment in the product documentation would be
+ * appreciated but is not required.
+ *
+ * 2. Altered source versions must be plainly marked as such, and must not be
+ * misrepresented as being the original software.
+ *
+ * 3. This notice may not be removed or altered from any source
+ * distribution.
+ *
+ */
+
+#include <ctype.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "xctype.h"
+
+/* Tabla de conversión de caracteres MS-DOS a Windows */
+
+int dos_chars = 0 ;
+
+unsigned char dos_to_win[256] = {
+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
+ 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
+ 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
+ 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
+ 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
+ 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95,
+ 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111,
+112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127,
+199, 252, 233, 226, 228, 224, 229, 231, 234, 235, 232, 239, 238, 236, 196, 197,
+201, 230, 198, 244, 246, 242, 251, 249, 255, 214, 220, 248, 163, 216, 215, 131,
+225, 237, 243, 250, 241, 209, 170, 186, 191, 174, 172, 189, 188, 161, 171, 187,
+166, 166, 166, 166, 166, 193, 194, 192, 169, 166, 166, 43, 43, 162, 165, 43,
+ 43, 45, 45, 43, 45, 43, 227, 195, 43, 43, 45, 45, 166, 45, 43, 164,
+240, 208, 202, 203, 200, 105, 205, 206, 207, 43, 43, 166, 95, 166, 204, 175,
+211, 223, 212, 210, 245, 213, 181, 254, 222, 218, 219, 217, 253, 221, 175, 180,
+173, 177, 61, 190, 182, 167, 247, 184, 176, 168, 183, 185, 179, 178, 166, 160
+} ;
+
+/* Tabla de conversión de caracteres Windows a MS-DOS */
+
+unsigned char win_to_dos[256] =
+{
+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
+ 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
+ 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
+ 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
+ 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
+ 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95,
+ 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111,
+ 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127,
+ 128, 129, 130, 159, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143,
+ 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159,
+ 255, 173, 189, 156, 207, 190, 254, 245, 249, 184, 166, 174, 170, 240, 169, 238,
+ 248, 241, 253, 252, 239, 230, 244, 250, 247, 251, 167, 175, 172, 171, 243, 168,
+ 183, 181, 182, 199, 142, 143, 146, 128, 212, 144, 210, 211, 222, 214, 215, 216,
+ 209, 165, 227, 224, 226, 229, 153, 158, 157, 235, 233, 234, 154, 237, 232, 225,
+ 133, 160, 131, 198, 132, 134, 145, 135, 138, 130, 136, 137, 141, 161, 140, 139,
+ 208, 164, 149, 162, 147, 228, 148, 246, 155, 151, 163, 150, 129, 236, 231, 152
+} ;
+
+/* Tipos de caracter */
+
+char c_type[256] ;
+unsigned char c_upper[256] ;
+unsigned char c_lower[256] ;
+
+int c_type_initialized = 0 ;
+
+unsigned char convert (unsigned char c)
+{
+ return dos_chars ? c : win_to_dos[c] ;
+}
+
+static void set_c_range (int first, int last, int type)
+{
+ while (first <= last) c_type[first++] |= type ;
+}
+
+static void set_c_from (const unsigned char * chars, int type)
+{
+ if (dos_chars)
+ while (*chars) c_type[win_to_dos[*chars++]] |= type ;
+ else
+ while (*chars) c_type[*chars++] |= type ;
+}
+
+static void set_c_as (int prev_type, int type)
+{
+ int n ;
+
+ for (n = 0 ; n < 256 ; n++)
+ {
+ if (c_type[n] & prev_type)
+ c_type[n] |= type ;
+ }
+}
+
+static void set_c_upper (const unsigned char * from, const unsigned char * to)
+{
+ if (dos_chars)
+ while (*from) c_upper[win_to_dos[*from++]] = win_to_dos[*to++] ;
+ else
+ while (*from) c_upper[*from++] = *to++ ;
+}
+
+static void set_c_lower (const unsigned char * from, const unsigned char * to)
+{
+ if (dos_chars)
+ while (*from) c_lower[win_to_dos[*from++]] = win_to_dos[*to++] ;
+ else
+ while (*from) c_lower[*from++] = *to++ ;
+}
+
+void init_c_type ()
+{
+ int c ;
+
+ memset (c_type, 0, sizeof(c_type)) ;
+
+ if (dos_chars)
+ for (c = 0 ; c < 256 ; c++)
+ c_lower[c] = c_upper[c] = win_to_dos[c] ;
+ else
+ for (c = 0 ; c < 256 ; c++)
+ c_lower[c] = c_upper[c] = c ;
+
+ set_c_upper ((const unsigned char *)"abcdefghijklmnopqrstuvwxyz",
+ (const unsigned char *)"ABCDEFGHIJKLMNOPQRSTUVWXYZ") ;
+ set_c_lower ((const unsigned char *)"ABCDEFGHIJKLMNOPQRSTUVWXYZ",
+ (const unsigned char *)"abcdefghijklmnopqrstuvwxyz") ;
+#ifdef RESPETAR_ACENTOS
+ set_c_upper ((const unsigned char *)"áéíóúñçàèìòùäëïöüýâêîôûæãåõ",
+ (const unsigned char *)"ÁÉÍÓÚÑÇÀÈÌÒÙÄËÏÖÜÝÂÊÎÔÛÆÃÅÕ") ;
+ set_c_lower ((const unsigned char *)"ÁÉÍÓÚÑÇÀÈÌÒÙÄËÏÖÜÝÂÊÎÔÛÆÃÅÕ",
+ (const unsigned char *)"áéíóúñçàèìòùäëïöüýâêîôûæãåõ") ;
+#else
+ set_c_upper ((const unsigned char *)"áéíóúñÑçÇàèìòùäëïöüýâêîôûæãåõÁÉÍÓÚ",
+ (const unsigned char *)"AEIOUNNCCAEIOUAEIOUYAEIOUÆAAOAEIOU") ;
+ set_c_lower ((const unsigned char *)"áéíóúñÑçÇàèìòùäëïöüýâêîôûæãåõÁÉÍÓÚ",
+ (const unsigned char *)"aeiounnccaeiouaeiouyaeiouÆaaoaeiou") ;
+#endif
+
+ set_c_from ((const unsigned char *)" \t\n\r", CTYPE_SPACE) ;
+
+ set_c_range ('0', '9', CTYPE_NUM) ;
+
+ set_c_range ('0', '9', CTYPE_ALNUM) ;
+ set_c_range ('A', 'F', CTYPE_ALNUM) ;
+ set_c_range ('a', 'f', CTYPE_ALNUM) ;
+
+ set_c_range ('A', 'Z', CTYPE_ALPHA) ;
+ set_c_range ('a', 'z', CTYPE_ALPHA) ;
+ set_c_from ((const unsigned char *)"áéíóúÁÉÍÓÚñÑçÇàèìòùÀÈÌÒÙäëïöüÄËÏÖÜÿýâêîôûÂÊÎÔÛ"
+ "æÆãåðõªºÃÅÐÕØ", CTYPE_ALPHA) ;
+
+ set_c_as (CTYPE_ALPHA, CTYPE_WORDCHAR) ;
+ set_c_from ((const unsigned char *)"_", CTYPE_WORDCHAR) ;
+ set_c_as (CTYPE_WORDCHAR, CTYPE_WORDFIRST) ;
+
+ set_c_range ('0', '9', CTYPE_WORDCHAR) ;
+
+ c_type_initialized = 1 ;
+}
+
+