/* Static convenience function */ static int gr_read_lib( file * fp ) { char header[8] ; short int px, py ; int bpp, libid, code; uint32_t y ; unsigned c; GRLIB * lib ; GRAPH * gr ; PALETTE * pal = NULL ; int st = 0; libid = grlib_new() ; if ( libid < 0 ) return -1 ; lib = grlib_get( libid ); if ( !lib ) { grlib_destroy( libid ) ; return -1 ; } file_read( fp, header, 8 ) ; if ( strcmp( header, F32_MAGIC ) == 0 ) bpp = 32 ; else if ( strcmp( header, F16_MAGIC ) == 0 ) bpp = 16 ; else if ( strcmp( header, FPG_MAGIC ) == 0 ) bpp = 8 ; else if ( strcmp( header, F01_MAGIC ) == 0 ) bpp = 1 ; else { grlib_destroy( libid ) ; return -1 ; } if ( bpp == 8 && !( pal = gr_read_pal_with_gamma( fp ) ) ) { grlib_destroy( libid ) ; return -1 ; } while ( !file_eof( fp ) ) { if ( !file_read( fp, &chunk, 64 ) ) break ; ARRANGE_DWORD( &chunk.code ) ; ARRANGE_DWORD( &chunk.regsize ) ; ARRANGE_DWORD( &chunk.width ) ; ARRANGE_DWORD( &chunk.height ) ; ARRANGE_DWORD( &chunk.flags ) ; /* Cabecera del gráfico */ gr = bitmap_new( chunk.code, chunk.width, chunk.height, bpp ) ; if ( !gr ) { grlib_destroy( libid ) ; if ( bpp == 8 ) pal_destroy( pal ) ; // Elimino la instancia inicial return -1 ; } memcpy( gr->name, chunk.name, 32 ) ; gr->name[31] = 0 ; gr->ncpoints = chunk.flags ; gr->modified = 2 ; // bitmap_analize( gr ); /* Puntos de control */ if ( gr->ncpoints ) { gr->cpoints = ( CPOINT * ) malloc( gr->ncpoints * sizeof( CPOINT ) ) ; if ( !gr->cpoints ) { bitmap_destroy( gr ) ; grlib_destroy( libid ) ; if ( bpp == 8 ) pal_destroy( pal ) ; return -1 ; } for ( c = 0 ; c < gr->ncpoints ; c++ ) { file_readSint16( fp, &px ) ; file_readSint16( fp, &py ) ; if ( px == -1 && py == -1 ) { gr->cpoints[c].x = CPOINT_UNDEFINED ; gr->cpoints[c].y = CPOINT_UNDEFINED ; } else { gr->cpoints[c].x = px ; gr->cpoints[c].y = py ; } } } else gr->cpoints = 0 ; /* Datos del gráfico */ for ( y = 0 ; y < gr->height ; y++ ) { uint8_t * line = ( uint8_t * )gr->data + gr->pitch * y; switch ( bpp ) { case 32: st = file_readUint32A( fp, ( uint32_t * ) line, gr->width ); break; case 16: st = file_readUint16A( fp, ( uint16_t * ) line, gr->width ); break; case 8: case 1: st = file_read( fp, line, gr->widthb ); break; } if ( !st ) { bitmap_destroy( gr ); grlib_destroy( libid ) ; if ( bpp == 8 ) pal_destroy( pal ); return -1 ; } } code = grlib_add_map( libid, gr ) ; if ( bpp == 8 ) pal_map_assign( libid, code, pal ) ; } if ( bpp == 8 ) pal_destroy( pal ) ; // Elimino la instancia inicial return libid ; }
static int gr_font_loadfrom( file * fp ) { char header[8]; int bpp; int types, i, id; uint32_t y; FONT * f; PALETTE * pal = NULL; struct { int width ; int height ; int yoffset ; int fileoffset ; } oldchardata[256]; _chardata chardata[256] ; if ( font_count == MAX_FONTS ) return -1 ; /* Read the file header */ if ( !file_read( fp, header, 8 ) ) return -1; if ( memcmp( header, FNT_MAGIC, 7 ) != 0 && memcmp( header, FNX_MAGIC, 7 ) != 0 ) { return -1; } bpp = header[7]; if ( bpp == 0 ) bpp = 8; /* Read or ignore the palette */ if ( bpp == 8 && !( pal = gr_read_pal_with_gamma( fp ) ) ) return -1 ; /* Read the character data (detect old format) */ if ( header[2] == 'x' ) { if ( !file_readSint32( fp, &types ) ) { pal_destroy( pal ); return -1 ; } if ( !file_read( fp, chardata, sizeof( chardata ) ) ) { pal_destroy( pal ); return -1 ; } for ( i = 0 ; i < 256 ; i++ ) { ARRANGE_DWORD( &chardata[i].width ); ARRANGE_DWORD( &chardata[i].height ); ARRANGE_DWORD( &chardata[i].xadvance ); ARRANGE_DWORD( &chardata[i].yadvance ); ARRANGE_DWORD( &chardata[i].xoffset ); ARRANGE_DWORD( &chardata[i].yoffset ); ARRANGE_DWORD( &chardata[i].fileoffset ); } } else { if ( !file_readSint32( fp, &types ) ) { pal_destroy( pal ); return -1 ; } if ( !file_read( fp, oldchardata, sizeof( oldchardata ) ) ) { pal_destroy( pal ); return -1 ; } for ( i = 0 ; i < 256 ; i++ ) { ARRANGE_DWORD( &oldchardata[i].width ); ARRANGE_DWORD( &oldchardata[i].height ); ARRANGE_DWORD( &oldchardata[i].yoffset ); ARRANGE_DWORD( &oldchardata[i].fileoffset ); chardata[i].width = oldchardata[i].width; chardata[i].height = oldchardata[i].height; chardata[i].xoffset = 0; chardata[i].yoffset = oldchardata[i].yoffset; chardata[i].xadvance = oldchardata[i].width; chardata[i].yadvance = oldchardata[i].height + oldchardata[i].yoffset; chardata[i].fileoffset = oldchardata[i].fileoffset; } } /* Create the font */ if ( header[2] == 'x' ) id = gr_font_new( types, header[7] ) ; else id = gr_font_new( CHARSET_CP850, 8 ) ; if ( id == -1 ) { pal_destroy( pal ); return -1 ; } f = fonts[id]; if ( !f ) { gr_font_destroy( id ); pal_destroy( pal ); return -1 ; } /* Load the character bitmaps */ for ( i = 0 ; i < 256 ; i++ ) { GRAPH * gr; uint8_t * ptr; f->glyph[i].xadvance = chardata[i].xadvance ; f->glyph[i].yadvance = chardata[i].yadvance ; if ( chardata[i].fileoffset == 0 || chardata[i].width == 0 || chardata[i].height == 0 ) continue ; f->glyph[i].xoffset = chardata[i].xoffset ; f->glyph[i].yoffset = chardata[i].yoffset ; file_seek( fp, chardata[i].fileoffset, SEEK_SET ) ; f->glyph[i].bitmap = gr = bitmap_new( i, chardata[i].width, chardata[i].height, f->bpp ) ; if ( !gr ) { gr_font_destroy( id ); pal_destroy( pal ); return -1 ; } bitmap_add_cpoint( gr, 0, 0 ) ; gr->format->palette = pal; pal_use( pal ); for ( y = 0, ptr = gr->data; y < gr->height; y++, ptr += gr->pitch ) { if ( !file_read( fp, ptr, gr->widthb ) ) break ; if ( gr->format->depth == 16 ) { ARRANGE_WORDS( ptr, ( int )gr->width ); } else if ( gr->format->depth == 32 ) { ARRANGE_DWORDS( ptr, ( int )gr->width ); } } f->glyph[i].yoffset = chardata[i].yoffset ; } if ( f->glyph[32].xadvance == 0 ) f->glyph[32].xadvance = f->glyph['j'].xadvance ; pal_destroy( pal ); // Elimino la instancia inicial return id ; }
int main( int argc, char *argv[] ) { char * filename = NULL, dcbname[ __MAX_PATH ], *ptr, *arg0, *ext ; int i, j, ret = -1; file * fp = NULL; INSTANCE * mainproc_running; dcb_signature dcb_signature; /* disable stdout buffering */ setvbuf( stdout, NULL, _IONBF, BUFSIZ ); /* get my executable name */ #ifdef _WIN32 if ( strlen( argv[0] ) < 4 || strncmpi( &argv[0][strlen( argv[0] ) - 4], ".exe", 4 ) ) { arg0 = malloc( strlen( argv[0] ) + 5 ); sprintf( arg0, "%s.exe", argv[0] ); } else { #endif arg0 = strdup( argv[0] ); #ifdef _WIN32 } #endif ptr = arg0 + strlen( arg0 ); while ( ptr > arg0 && ptr[-1] != '\\' && ptr[-1] != '/' ) ptr-- ; appexename = strdup( ptr ); /* get executable full pathname */ fp = NULL; appexefullpath = getfullpath( arg0 ); if ( ( !strchr( arg0, '\\' ) && !strchr( arg0, '/' ) ) ) { struct stat st; if ( stat( appexefullpath, &st ) || !S_ISREG( st.st_mode ) ) { char *p = whereis( appexename ); if ( p ) { char * tmp = calloc( 1, strlen( p ) + strlen( appexename ) + 2 ); free( appexefullpath ); sprintf( tmp, "%s/%s", p, appexename ); appexefullpath = getfullpath( tmp ); free( tmp ); } } } /* get pathname of executable */ ptr = strstr( appexefullpath, appexename ); appexepath = calloc( 1, ptr - appexefullpath + 1 ); strncpy( appexepath, appexefullpath, ptr - appexefullpath ); standalone = ( strncmpi( appexename, "bgdi", 4 ) == 0 ) ; /* add binary path */ file_addp( appexepath ); #ifdef TARGET_WII // Initialize the Wii FAT filesystem, check stuff if (!fatInitDefault()) { printf("Sorry, I cannot access the FAT filesystem on your card :(\n"); exit(1); } #endif if ( !standalone ) { /* Hand-made interpreter: search for DCB at EOF */ fp = file_open( appexefullpath, "rb0" ); if ( fp ) { file_seek( fp, -( int )sizeof( dcb_signature ), SEEK_END ); file_read( fp, &dcb_signature, sizeof( dcb_signature ) ); if ( strcmp( dcb_signature.magic, DCB_STUB_MAGIC ) == 0 ) { ARRANGE_DWORD( &dcb_signature.dcb_offset ); embedded = 1; } } filename = appexefullpath; } if ( standalone ) { /* Calling BGDI.EXE so we must get all command line params */ for ( i = 1 ; i < argc ; i++ ) { if ( argv[i][0] == '-' ) { j = 1 ; while ( argv[i][j] ) { if ( argv[i][j] == 'd' ) debug++; if ( argv[i][j] == 'i' ) { if ( argv[i][j+1] == 0 ) { if ( i == argc - 1 ) { fprintf( stderr, "You must provide a directory" ) ; exit( 0 ); } file_addp( argv[i+1] ); i++ ; break ; } file_addp( &argv[i][j + 1] ) ; break ; } j++ ; } } else { if ( !filename ) { filename = argv[i] ; if ( i < argc - 1 ) memmove( &argv[i], &argv[i+1], sizeof( char* ) * ( argc - i - 1 ) ) ; argc-- ; i-- ; } } } if ( !filename ) { printf( BGDI_VERSION "\n" "Bennu Game Development Interpreter\n" "\n" "Copyright (c) 2006-2012 SplinterGU (Fenix/BennuGD)\n" "Copyright (c) 2002-2006 Fenix Team (Fenix)\n" "Copyright (c) 1999-2002 José Luis Cebrián Pagüe (Fenix)\n" "\n" "Usage: %s [options] <data code block file>[.dcb]\n" "\n" " -d Activate DEBUG mode (several -d for increment debug level)\n" " -i dir Adds the directory to the PATH\n" "\n" "This software is provided 'as-is', without any express or implied\n" "warranty. In no event will the authors be held liable for any damages\n" "arising from the use of this software.\n" "\n" "Permission is granted to anyone to use this software for any purpose,\n" "including commercial applications, and to alter it and redistribute it\n" "freely, subject to the following restrictions:\n" "\n" " 1. The origin of this software must not be misrepresented; you must not\n" " claim that you wrote the original software. If you use this software\n" " in a product, an acknowledgment in the product documentation would be\n" " appreciated but is not required.\n" "\n" " 2. Altered source versions must be plainly marked as such, and must not be\n" " misrepresented as being the original software.\n" "\n" " 3. This notice may not be removed or altered from any source\n" " distribution.\n" , appexename ) ; return -1 ; } } /* Initialization (modules needed before dcb_load) */ string_init() ; init_c_type() ; /* Init application title for windowed modes */ strcpy( dcbname, filename ) ; ptr = filename + strlen( filename ); while ( ptr > filename && ptr[-1] != '\\' && ptr[-1] != '/' ) ptr-- ; appname = strdup( ptr ) ; if ( strlen( appname ) > 3 ) { char ** dcbext = dcb_exts, *ext = &appname[ strlen( appname ) - 4 ]; #ifdef _WIN32 if ( !strncmpi( ext, ".exe", 4 ) ) { *ext = '\0'; } else #endif while ( dcbext && *dcbext ) { if ( !strncmpi( ext, *dcbext, 4 ) ) { *ext = '\0'; break; } dcbext++; } } #ifdef __DEBUG__ printf( "appname %s\n", appname); printf( "appexename %s\n", appexename); printf( "appexepath %s\n", appexepath); printf( "appexefullpath %s\n", appexefullpath); printf( "dcbname %s\n", dcbname); fflush(stdout); #endif if ( !embedded ) { /* First try to load directly (we expect myfile.dcb) */ if ( !dcb_load( dcbname ) ) { char ** dcbext = dcb_exts; int dcbloaded = 0; while ( dcbext && *dcbext ) { strcpy( dcbname, appname ) ; strcat( dcbname, *dcbext ) ; if (( dcbloaded = dcb_load( dcbname ) ) ) break; dcbext++; } if ( !dcbloaded ) { printf( "%s: doesn't exist or isn't version %d DCB compatible\n", filename, DCB_VERSION >> 8 ) ; return -1 ; } }
int gr_font_save( int fontid, const char * filename ) { if ( !filename ) return 0; file * file; int n; uint32_t y; long offset; uint8_t * block = NULL ; uint8_t * lineptr; FONT * font; uint8_t header[8]; _chardata chardata[256] ; int palette_saved = 0; if ( fontid < 0 || fontid > MAX_FONTS || !fonts[fontid] ) return 0; font = fonts[fontid]; /* Open the file */ file = file_open( filename, "wb0" ); if ( !file ) return 0; /* Write the header */ strcpy( ( char * ) header, FNX_MAGIC ); header[7] = font->bpp; file_write( file, &header, 8 ); /* Write the character information */ memset( chardata, 0, sizeof( chardata ) ); offset = 8 + 4 + (( font->bpp == 8 ) ? 576 + 768 : 0 ) + sizeof( chardata ); for ( n = 0 ; n < 256 ; n++ ) { chardata[n].xadvance = font->glyph[n].xadvance; chardata[n].yadvance = font->glyph[n].yadvance; if ( font->glyph[n].bitmap ) { /* Write the palette */ if ( !palette_saved && font->bpp == 8 ) { uint8_t colors[256][3]; uint8_t * block = calloc( 576, 1 ) ; rgb_component * gpal = NULL; int k; if ( font->glyph[n].bitmap->format->palette ) gpal = font->glyph[n].bitmap->format->palette->rgb; else if ( sys_pixel_format->palette ) gpal = sys_pixel_format->palette->rgb; else gpal = ( rgb_component * ) default_palette; /* Generate palette info */ for ( k = 0 ; k < 256 ; k++ ) { colors[k][0] = gpal[k].r >> 2 ; colors[k][1] = gpal[k].g >> 2 ; colors[k][2] = gpal[k].b >> 2 ; } file_write( file, &colors, sizeof(colors) ) ; file_write( file, block, 576 ) ; free( block ) ; palette_saved = 1; } chardata[n].width = font->glyph[n].bitmap->width; chardata[n].height = font->glyph[n].bitmap->height; chardata[n].xadvance = font->glyph[n].xadvance; chardata[n].yadvance = font->glyph[n].yadvance; chardata[n].xoffset = font->glyph[n].xoffset; chardata[n].yoffset = font->glyph[n].yoffset; chardata[n].fileoffset = offset; offset += font->glyph[n].bitmap->widthb * chardata[n].height; } ARRANGE_DWORD( &chardata[n].xadvance ); ARRANGE_DWORD( &chardata[n].yadvance ); ARRANGE_DWORD( &chardata[n].width ); ARRANGE_DWORD( &chardata[n].width ); ARRANGE_DWORD( &chardata[n].xoffset ); ARRANGE_DWORD( &chardata[n].yoffset ); ARRANGE_DWORD( &chardata[n].fileoffset ); }