aboutsummaryrefslogtreecommitdiff
path: root/modules/mod_map/file_fpg.c
diff options
context:
space:
mode:
Diffstat (limited to 'modules/mod_map/file_fpg.c')
-rw-r--r--modules/mod_map/file_fpg.c349
1 files changed, 349 insertions, 0 deletions
diff --git a/modules/mod_map/file_fpg.c b/modules/mod_map/file_fpg.c
new file mode 100644
index 0000000..1115b18
--- /dev/null
+++ b/modules/mod_map/file_fpg.c
@@ -0,0 +1,349 @@
+/*
+ * Copyright © 2006-2016 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 "mod_map.h"
+
+/* --------------------------------------------------------------------------- */
+
+struct
+{
+ int code ;
+ int regsize ;
+ char name[32] ;
+ char fpname[12] ;
+ int width ;
+ int height ;
+ int flags ;
+} chunk ;
+
+/* --------------------------------------------------------------------------- */
+
+/* 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 ;
+ }
+
+ if ( file_read( fp, header, sizeof( header ) ) != sizeof( header ) ) {
+ grlib_destroy( libid ) ;
+ return -1 ;
+ }
+
+ 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, sizeof( chunk ) ) != sizeof( chunk ) ) break ;
+
+ ARRANGE_DWORD( &chunk.code ) ;
+ if ( chunk.code < 0 || chunk.code > 999 ) break;
+ 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, sizeof( chunk.name ) ) ;
+ 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:
+ if ( ( st = file_read( fp, line, gr->widthb ) ) != gr->widthb ) st = 0;
+ 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 ;
+}
+
+/* --------------------------------------------------------------------------- */
+/*
+ * FUNCTION : gr_load_fpg
+ *
+ * Load a FPG file
+ *
+ * PARAMS :
+ * libname Name of the file
+ *
+ * RETURN VALUE :
+ * Internal ID of the library or -1 if invalid file
+ *
+ */
+
+int gr_load_fpg( const char * libname )
+{
+ int libid ;
+ file * fp = file_open( libname, "rb" ) ;
+ if ( !fp ) return -1 ;
+ libid = gr_read_lib( fp ) ;
+ file_close( fp ) ;
+ return libid ;
+}
+
+/* --------------------------------------------------------------------------- */
+
+/*
+ * FUNCTION : gr_save_fpg
+ *
+ * Save a FPG file
+ *
+ * PARAMS :
+ * filename Name of the file
+ *
+ * RETURN VALUE :
+ * 1 if succeded
+ * >= 0 error
+ *
+ */
+
+int gr_save_fpg( int libid, const char * filename )
+{
+ file * fp;
+ GRLIB * lib;
+ uint8_t * block = NULL;
+ int n, y, c;
+ int bpp;
+ int nmaps;
+ uint8_t header[8];
+ rgb_component * palette = NULL;
+
+ /* Get the library and open the file */
+/*
+ if ( !libid )
+ lib = syslib ;
+ else
+*/
+ lib = grlib_get( libid );
+
+ if ( !lib ) return 0;
+
+ /* Guess the FPG depth */
+
+ nmaps = lib->map_reserved < 1000 ? lib->map_reserved : 1000;
+
+ for ( bpp = n = 0 ; n < nmaps ; n++ ) {
+ if ( lib->maps[n] ) {
+ if ( bpp && lib->maps[n]->format->depth != bpp ) return 0; /* save_fpg: don't allow save maps with differents bpp */
+ bpp = lib->maps[n]->format->depth;
+ if ( !palette && bpp == 8 && lib->maps[n]->format->palette ) palette = lib->maps[n]->format->palette->rgb;
+ }
+ }
+
+ if ( bpp == 32 ) strcpy( ( char * ) header, F32_MAGIC );
+ else if ( bpp == 16 ) strcpy( ( char * ) header, F16_MAGIC );
+ else if ( bpp == 8 ) strcpy( ( char * ) header, FPG_MAGIC );
+ else if ( bpp == 1 ) strcpy( ( char * ) header, F01_MAGIC );
+ else return 0; /* No maps for save */
+
+ /* Create fpg */
+
+ fp = file_open( filename, "wb" );
+ if ( !fp ) return 0;
+
+ /* Write the header */
+
+ header[7] = 0x00; /* Version */
+ file_write( fp, header, sizeof( header ) );
+
+ /* Write the color palette */
+
+ if ( bpp == 8 ) {
+ uint8_t colors[256][3] ;
+ uint8_t gamma[576];
+
+ if ( !palette ) {
+ if ( sys_pixel_format->palette )
+ palette = sys_pixel_format->palette->rgb;
+ else
+ palette = ( rgb_component * ) default_palette;
+ }
+
+ for ( n = 0 ; n < 256 ; n++ ) {
+ colors[n][0] = palette[n].r >> 2 ;
+ colors[n][1] = palette[n].g >> 2 ;
+ colors[n][2] = palette[n].b >> 2 ;
+ }
+
+ file_write( fp, &colors, 768 ) ;
+ memset( gamma, '\0', sizeof( gamma ) );
+ file_write( fp, gamma, sizeof( gamma ) ) ;
+ }
+
+ /* Write each map */
+
+ for ( n = 0 ; n < nmaps ; n++ ) {
+ GRAPH * gr = lib->maps[n];
+
+ if ( gr ) {
+ /* Write the bitmap header */
+
+ chunk.code = n;
+ chunk.regsize = 0;
+ chunk.width = gr->width;
+ chunk.height = gr->height;
+ chunk.flags = gr->ncpoints;
+ chunk.fpname[0] = 0;
+ strncpy( chunk.name, gr->name, sizeof( chunk.name ) );
+
+ ARRANGE_DWORD( &chunk.code );
+ ARRANGE_DWORD( &chunk.regsize );
+ ARRANGE_DWORD( &chunk.width );
+ ARRANGE_DWORD( &chunk.height );
+ ARRANGE_DWORD( &chunk.flags );
+
+ file_write( fp, &chunk, sizeof( chunk ) );
+
+ /* Write the control points */
+
+ for ( c = 0 ; c < gr->ncpoints ; c++ ) {
+ file_writeSint16( fp, &gr->cpoints[c].x );
+ file_writeSint16( fp, &gr->cpoints[c].y );
+ }
+
+ /* Write the bitmap pixel data */
+
+ if ( bpp > 8 ) {
+ if ( !( block = malloc( gr->widthb ) ) ) {
+ file_close( fp );
+ return 0; /* No memory */
+ }
+ }
+
+ for ( y = 0 ; y < gr->height ; y++ ) {
+ if ( bpp > 8 ) {
+ memcpy( block, ( uint8_t * )gr->data + gr->pitch*y, gr->widthb );
+ if ( bpp == 16 ) {
+/* gr_convert16_ScreenTo565(( uint16_t * )block, gr->width ); */
+ file_writeUint16A( fp, ( uint16_t * ) block, gr->width );
+ } else
+ file_writeUint32A( fp, ( uint32_t * ) block, gr->width );
+ } else {
+ file_write( fp, ( uint8_t * )gr->data + gr->pitch*y, gr->widthb );
+ }
+ }
+
+ if ( bpp > 8 ) free( block );
+ }
+ }
+
+ file_close( fp );
+ return 1;
+}
+
+/* --------------------------------------------------------------------------- */