aboutsummaryrefslogtreecommitdiff
path: root/modules/libgrbase/g_grlib.c
diff options
context:
space:
mode:
Diffstat (limited to 'modules/libgrbase/g_grlib.c')
-rw-r--r--modules/libgrbase/g_grlib.c353
1 files changed, 353 insertions, 0 deletions
diff --git a/modules/libgrbase/g_grlib.c b/modules/libgrbase/g_grlib.c
new file mode 100644
index 0000000..fdb4fe5
--- /dev/null
+++ b/modules/libgrbase/g_grlib.c
@@ -0,0 +1,353 @@
+/*
+ * 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 <stdlib.h>
+#include <string.h>
+
+#include "libgrbase.h"
+#include "bitwise_map.h"
+
+/* --------------------------------------------------------------------------- */
+
+GRLIB * syslib = 0 ;
+
+static uint32_t * libs_bmp = NULL ;
+static int libs_allocated = 0 ;
+static int libs_last = 0;
+static GRLIB ** libs = NULL;
+
+/* --------------------------------------------------------------------------- */
+
+static GRLIB * grlib_create() ;
+
+/* --------------------------------------------------------------------------- */
+
+int grlib_newid()
+{
+ int n, nb, lim, ini ;
+
+ // Si tengo suficientes alocados, retorno el siguiente segun libs_last
+ if ( libs_last < libs_allocated )
+ {
+ if ( !bit_tst( libs_bmp, libs_last ) )
+ {
+ bit_set( libs_bmp, libs_last );
+ return libs_last++ ;
+ }
+ }
+
+ // Ya no tengo mas espacio, entonces busco alguno libre entre ~+32 desde el ultimo fijo y ~-32 del ultimo asignado
+
+ ini = ( libs_last < libs_allocated ) ? ( libs_last >> 5 ) : 0 ;
+ lim = ( libs_allocated >> 5 ) ;
+
+ while ( 1 )
+ {
+ for ( n = ini; n < lim ; n++ )
+ {
+ if ( libs_bmp[n] != ( uint32_t ) 0xFFFFFFFF ) // Aca hay 1 libre, busco cual es
+ {
+ for ( nb = 0; nb < 32; nb++ )
+ {
+ if ( !bit_tst( libs_bmp + n, nb ) )
+ {
+ libs_last = ( n << 5 ) + nb ;
+ bit_set( libs_bmp, libs_last );
+ return libs_last++ ;
+ }
+ }
+ }
+ }
+ if ( !ini ) break;
+ lim = ini;
+ ini = 0;
+ }
+
+ libs_last = libs_allocated ;
+
+ /* Increment space, no more slots availables
+ 256 new maps available for alloc */
+
+ libs_allocated += 256 ;
+ libs_bmp = ( uint32_t * ) realloc( libs_bmp, sizeof( uint32_t ) * ( libs_allocated >> 5 ) );
+ memset( &libs_bmp[( libs_last >> 5 )], 0, 32 ); /* 256 >> 5 = 8 * sizeof ( uint32_t ) = 8 * 4 = 32 */
+
+ libs = ( GRLIB ** ) realloc( libs, sizeof( GRLIB * ) * libs_allocated );
+ memset( &libs[ libs_last ], 0, sizeof( GRLIB * ) * 256 );
+
+ /* Devuelvo libs_last e incremento en 1, ya que ahora tengo BLOCK_INCR mas que antes */
+ bit_set( libs_bmp, libs_last );
+
+ return libs_last++ ;
+}
+
+/* --------------------------------------------------------------------------- */
+/*
+ * FUNCTION : grlib_new
+ *
+ * Create a new library
+ *
+ * PARAMS :
+ * None
+ *
+ * RETURN VALUE :
+ * ID of the new library or -1 if error
+ */
+
+int grlib_new()
+{
+ GRLIB * lib = grlib_create() ;
+ int i ;
+
+ if ( !lib ) return -1;
+
+ i = grlib_newid();
+ libs[ i ] = lib;
+
+ return ( i );
+}
+
+/* --------------------------------------------------------------------------- */
+/* Static convenience function */
+
+static GRLIB * grlib_create()
+{
+ GRLIB * lib ;
+
+ lib = ( GRLIB * ) malloc( sizeof( GRLIB ) ) ;
+ if ( !lib ) return 0 ;
+
+ lib->maps = ( GRAPH ** ) calloc( 32, sizeof( GRAPH * ) ) ;
+ if ( !lib->maps )
+ {
+ free( lib );
+ return 0 ;
+ }
+
+ lib->name[ 0 ] = 0 ;
+ lib->map_reserved = 32 ;
+
+ return lib ;
+}
+
+/* --------------------------------------------------------------------------- */
+/*
+ * FUNCTION : grlib_get
+ *
+ * Get a pointer to an library in memory given the internal ID
+ *
+ * PARAMS :
+ * libid Library code
+ *
+ * RETURN VALUE :
+ * Pointer to the object required or NULL if it does not exist
+ */
+
+GRLIB * grlib_get( int libid )
+{
+ if ( libid < 0 || libid >= libs_allocated ) return 0 ;
+ return libs[ libid ] ;
+}
+
+/* --------------------------------------------------------------------------- */
+/*
+ * FUNCTION : grlib_destroy
+ *
+ * Remove a library and all its maps from memory
+ *
+ * PARAMS :
+ * libid ID of the library
+ *
+ * RETURN VALUE :
+ * 0 if there wasn't a map with this code, 1 otherwise
+ */
+
+void grlib_destroy( int libid )
+{
+ int i ;
+ GRLIB * lib = grlib_get( libid ) ;
+ if ( !lib ) return ;
+
+ libs[ libid ] = 0 ;
+
+ for ( i = 0; i < lib->map_reserved; i++ ) bitmap_destroy( lib->maps[ i ] ) ;
+
+ free( lib->maps ) ;
+ free( lib ) ;
+
+ bit_clr( libs_bmp, libid );
+}
+
+/* --------------------------------------------------------------------------- */
+/*
+ * FUNCTION : grlib_unload_map
+ *
+ * Remove a map from a library, if present
+ *
+ * PARAMS :
+ * libid ID of the library
+ * mapcode ID of the map
+ *
+ * RETURN VALUE :
+ * 0 if there wasn't a map with this code, 1 otherwise
+ */
+
+int grlib_unload_map( int libid, int mapcode )
+{
+ GRLIB * lib ;
+
+ if ( mapcode < 1 || mapcode > 999 )
+ lib = syslib ;
+ else
+ lib = grlib_get( libid ) ;
+
+ if ( lib == NULL ) return 0 ;
+
+ if ( lib->map_reserved <= mapcode ) return 0 ;
+ if ( !lib->maps[ mapcode ] ) return 0 ;
+
+ bitmap_destroy( lib->maps[ mapcode ] ) ;
+ lib->maps[ mapcode ] = 0 ;
+ return 1 ;
+}
+
+/* --------------------------------------------------------------------------- */
+/*
+ * FUNCTION : grlib_add_map
+ *
+ * Add a map to a graphic library. If any map with the same code
+ * is in the library, it will be unload first
+ *
+ * PARAMS :
+ * lib Pointer to the library
+ * map Pointer to the graphic
+ * (fill map->code first!)
+ *
+ * RETURN VALUE :
+ * -1 if error, a number >= 0 otherwise
+ */
+
+int grlib_add_map( int libid, GRAPH * map )
+{
+ GRLIB * lib ;
+
+ if ( map->code < 1 || map->code > 999 )
+ lib = syslib ;
+ else
+ lib = grlib_get( libid ) ;
+
+ if ( !lib ) return -1 ;
+ if ( map->code < 0 ) return -1 ;
+
+ if ( map->code > 0 ) grlib_unload_map( libid, map->code ) ;
+
+ if ( lib->map_reserved <= map->code )
+ {
+ GRAPH ** lmaps;
+ int new_reserved = ( map->code & ~0x001F ) + 32 ;
+
+ lmaps = ( GRAPH ** ) realloc( lib->maps, sizeof( GRAPH* ) * new_reserved ) ;
+ if ( !lmaps ) return -1; // No memory
+ lib->maps = lmaps;
+
+ memset( lib->maps + lib->map_reserved, 0, ( new_reserved - lib->map_reserved ) * sizeof( GRAPH * ) ) ;
+ lib->map_reserved = new_reserved ;
+ }
+
+ lib->maps[ map->code ] = map ;
+
+ return map->code ;
+}
+
+/* --------------------------------------------------------------------------- */
+/*
+ * FUNCTION : bitmap_get
+ *
+ * Get a bitmap using the DIV syntax (libcode, mapcode)
+ *
+ * PARAMS :
+ * libid Library code or 0 for system/global bitmap
+ * mapcode Code of the bitmap
+ *
+ * RETURN VALUE :
+ * Pointer to the graphic required or NULL if not found
+ *
+ * (0, -1) gets the scrbitmap graphic (undocumented!)
+ * (0, 0) gets the background
+ *
+ */
+
+GRAPH * bitmap_get( int libid, int mapcode )
+{
+ GRLIB * lib = NULL ;
+
+ if ( !libid )
+ {
+ /* Using (0, 0) we can get the background map */
+ if ( !mapcode ) return background ;
+
+ /* Using (0, -1) we can get the screen bitmap (undocumented bug/feature) */
+ if ( mapcode == -1 ) return scrbitmap ;
+ }
+
+ /* Get the map from the system library
+ * (the only one that can have more than 1000 maps)
+ */
+ if ( mapcode > 999 ) lib = syslib ;
+
+ if ( !lib ) lib = grlib_get( libid ) ;
+
+ /* Get the map from a library */
+
+ if ( lib && lib->map_reserved > mapcode && mapcode >= 0 ) return lib->maps[ mapcode ] ;
+
+ return 0 ;
+}
+
+/* --------------------------------------------------------------------------- */
+/*
+ * FUNCTION : grlib_init
+ *
+ * Create the system library. This should be called at program startup.
+ *
+ * PARAMS :
+ * None
+ *
+ * RETURN VALUE :
+ * None
+ *
+ */
+
+void grlib_init()
+{
+ if ( !syslib ) syslib = grlib_create() ;
+}
+
+/* --------------------------------------------------------------------------- */