diff options
author | neonloop | 2021-10-20 14:54:27 +0000 |
---|---|---|
committer | neonloop | 2021-10-20 14:54:27 +0000 |
commit | ea1947ffcc606d757357398b24e74a3f4ecefa07 (patch) | |
tree | 2031b8d4fc4c61063c710a7148378f57e662efbd /modules/librender/g_instance.c | |
download | bennugd-main.tar.gz bennugd-main.tar.bz2 bennugd-main.zip |
Initial commit from steward-fu releasemain
Diffstat (limited to 'modules/librender/g_instance.c')
-rw-r--r-- | modules/librender/g_instance.c | 409 |
1 files changed, 409 insertions, 0 deletions
diff --git a/modules/librender/g_instance.c b/modules/librender/g_instance.c new file mode 100644 index 0000000..62c1635 --- /dev/null +++ b/modules/librender/g_instance.c @@ -0,0 +1,409 @@ +/* + * 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 <stdio.h> +#include <stdlib.h> +#include <string.h> + +/* --------------------------------------------------------------------------- */ + +#ifdef __GNUC__ +#define _inline inline +#endif + +/* --------------------------------------------------------------------------- */ + +#include "librender.h" +#include "resolution.h" + +#include "sysprocs_st.h" + +/* --------------------------------------------------------------------------- */ +/* + * FUNCTION : instance_graph + * + * Returns the instance graphic or NULL if there is none + * + * PARAMS : + * i Pointer to the instance + * + * RETURN VALUE : + * Pointer to the graphic or NULL if none + */ + +GRAPH * instance_graph( INSTANCE * i ) +{ + int * xgraph, c, a ; + + if (( xgraph = ( int * ) LOCDWORD( librender, i, XGRAPH ) ) ) // Get offset of XGRAPH table + { + c = *xgraph++; // Get number of graphs ids in XGRAPH table + if ( c ) + { + // Normalize ANGLE + a = LOCINT32( librender, i, ANGLE ) % 360000 ; + if ( a < 0 ) a += 360000 ; + + // Get graph id in XGRAPH table to draw + c = xgraph[a * c / 360000] ; + + // If graph id value is negative, then graphic must be mirrored + if ( c < 0 ) + { + c = -c; + LOCDWORD( librender, i, XGRAPH_FLAGS ) = B_HMIRROR; + } + else + { + LOCDWORD( librender, i, XGRAPH_FLAGS ) = 0; + } + + // Get GRAPH * to draw + return bitmap_get( LOCDWORD( librender, i, FILEID ), c ) ; + } + } + + // Get GRAPH * to draw + if (( c = LOCDWORD( librender, i, GRAPHID ) ) ) + { + return bitmap_get( LOCDWORD( librender, i, FILEID ), c ) ; + } + + return 0 ; // No graph to draw +} + +void instance_get_bbox( INSTANCE * i, GRAPH * gr, REGION * dest ) +{ + REGION *region; + int x, y, r ; + int scalex, scaley ; + + r = LOCINT32( librender, i, REGIONID ) ; + if ( r > 0 && r < 32 ) + region = ®ions[ r ] ; + else + region = ®ions[ 0 ]; + + x = LOCINT32( librender, i, COORDX ) ; + y = LOCINT32( librender, i, COORDY ) ; + + RESOLXY( librender, i, x, y ); + + scalex = LOCINT32( librender, i, GRAPHSIZEX ); + scaley = LOCINT32( librender, i, GRAPHSIZEY ); + + if ( scalex == 100 && scaley == 100 ) scalex = scaley = LOCINT32( librender, i, GRAPHSIZE ); + + gr_get_bbox( dest, + region, + x, + y, + LOCDWORD( librender, i, FLAGS ) ^ LOCDWORD( librender, i, XGRAPH_FLAGS ), + LOCDWORD( librender, i, XGRAPH ) ? 0 : LOCINT32( librender, i, ANGLE ), + scalex, + scaley, + gr + ) ; +} + +/* ---------------------------------------------------------------------- */ + +void draw_instance_at( INSTANCE * i, REGION * region, int x, int y, GRAPH * dest ) +{ + GRAPH * map ; + int16_t * blend_table = NULL ; + int flags ; + int scalex, scaley ; + int alpha ; + int blendop; + PALETTE * palette = NULL; + int paletteid; + + map = instance_graph( i ) ; + if ( !map ) return ; + + flags = ( LOCDWORD( librender, i, FLAGS ) ^ LOCDWORD( librender, i, XGRAPH_FLAGS ) ); + + if (( alpha = LOCDWORD( librender, i, ALPHA ) ) != 255 ) + { + if ( alpha <= 0 ) return ; + else if ( alpha < 255 ) + flags |= B_ALPHA | ( alpha << B_ALPHA_SHIFT ); + } + + scalex = LOCINT32( librender, i, GRAPHSIZEX ); + scaley = LOCINT32( librender, i, GRAPHSIZEY ); + if ( scalex == 100 && scaley == 100 ) scalex = scaley = LOCINT32( librender, i, GRAPHSIZE ); + + if (( blendop = LOCDWORD( librender, i, BLENDOP ) ) ) + { + blend_table = map->blend_table; + map->blend_table = ( int16_t * ) blendop; + } + + if (( paletteid = LOCDWORD( librender, i, PALETTEID ) ) ) + { + palette = map->format->palette ; + map->format->palette = ( PALETTE * ) paletteid; + } + + /* XGRAPH does not rotate destination graphic. + WARNING: don't remove "scalex != 100 || scaley != 100 ||" from begin the next condition */ + if ( scalex != 100 || scaley != 100 || ( LOCINT32( librender, i, ANGLE ) && !LOCDWORD( librender, i, XGRAPH ) ) ) + gr_rotated_blit( dest, region, x, y, flags, LOCDWORD( librender, i, XGRAPH ) ? 0 : LOCINT32( librender, i, ANGLE ), scalex, scaley, map ) ; + else + gr_blit( dest, region, x, y, flags, map ) ; + + if ( paletteid ) map->format->palette = palette; + if ( blendop ) map->blend_table = blend_table; + +} + +/* --------------------------------------------------------------------------- */ +/* Rutinas gráficas de alto nivel */ + +void draw_instance( INSTANCE * i, REGION * clip ) +{ + GRAPH * map ; + int16_t * blend_table = NULL ; + int flags; + int scalex, scaley; + REGION region; + int alpha ; + int blendop = 0 ; + PALETTE * palette = NULL ; + int paletteid; + + /* Difference with draw_instance_at from here */ + int x, y, r ; + /* Difference with draw_instance_at to here */ + +// map = instance_graph( i ) ; + map = ( GRAPH * ) LOCDWORD( librender, i, GRAPHPTR ); + if ( !map ) return ; + + flags = ( LOCDWORD( librender, i, FLAGS ) ^ LOCDWORD( librender, i, XGRAPH_FLAGS ) ); + + if (( alpha = LOCDWORD( librender, i, ALPHA ) ) != 255 ) + { + if ( alpha <= 0 ) return ; + else if ( alpha < 255 ) + flags |= B_ALPHA | ( alpha << B_ALPHA_SHIFT ); + } + + scalex = LOCINT32( librender, i, GRAPHSIZEX ); + scaley = LOCINT32( librender, i, GRAPHSIZEY ); + if ( scalex == 100 && scaley == 100 ) scalex = scaley = LOCINT32( librender, i, GRAPHSIZE ); + + if (( blendop = LOCDWORD( librender, i, BLENDOP ) ) ) + { + blend_table = map->blend_table; + map->blend_table = ( int16_t * ) blendop; + } + + if (( paletteid = LOCDWORD( librender, i, PALETTEID ) ) ) + { + palette = map->format->palette ; + map->format->palette = ( PALETTE * ) paletteid; + } + + /* Difference with draw_instance_at from here */ + + x = LOCINT32( librender, i, COORDX ) ; + y = LOCINT32( librender, i, COORDY ) ; + + RESOLXY( librender, i, x, y ); + + r = LOCINT32( librender, i, REGIONID ) ; + if ( r > 0 && r < 32 ) + region = regions[ r ] ; + else + region = regions[ 0 ]; + + if ( clip ) region_union( ®ion, clip ); + /* Difference with draw_instance_at to here */ + + /* XGRAPH does not rotate destination graphic. + WARNING: don't remove "scalex != 100 || scaley != 100 ||" from begin the next condition */ + if ( scalex != 100 || scaley != 100 || ( LOCINT32( librender, i, ANGLE ) && !LOCDWORD( librender, i, XGRAPH ) ) ) + gr_rotated_blit( 0, ®ion, x, y, flags, LOCDWORD( librender, i, XGRAPH ) ? 0 : LOCINT32( librender, i, ANGLE ), scalex, scaley, map ) ; + else + gr_blit( 0, ®ion, x, y, flags, map ) ; + + if ( paletteid ) map->format->palette = palette; + if ( blendop ) map->blend_table = blend_table; + + if ( map->modified ) map->modified = 0; +} + +/* --------------------------------------------------------------------------- */ +/* + * FUNCTION : draw_instance_info + * + * Compares the internal position variables of the instance with its + * currents values, and returns 1 if there is any difference. Used + * to detect changes in a visible process's aspect or position. + * + * PARAMS : + * i Pointer to the instance + * + * RETURN VALUE : + * 1 if there is any change, 0 otherwise + */ + +int draw_instance_info( INSTANCE * i, REGION * region, int * z, int * drawme ) +{ + GRAPH * graph; + + * drawme = 0; + + LOCDWORD( librender, i, GRAPHPTR ) = ( int )( graph = instance_graph( i ) ); + if ( !graph ) + { + /* + region->x = -2; region->y = -2; + region->x2 = -2; region->y2 = -2; + */ + return 0; + } + + int changed; + int status; + int coordz, coordx, coordy; + + status = ( LOCDWORD( librender, i, STATUS ) & ~STATUS_WAITING_MASK ) ; + + coordz = LOCINT32( librender, i, COORDZ ); + + /* Si tiene grafico o xgraph o (ctype == 0 y esta corriendo o congelado) */ + + if ( LOCDWORD( librender, i, CTYPE ) == C_SCREEN && ( status == STATUS_RUNNING || status == STATUS_FROZEN ) ) + * drawme = 1; + + + coordx = LOCINT32( librender, i, COORDX ); + coordy = LOCINT32( librender, i, COORDY ); + + RESOLXY( librender, i, coordx, coordy ); + + changed = + graph->modified || + LOCINT32( librender, i, SAVED_COORDX ) != coordx || + LOCINT32( librender, i, SAVED_COORDY ) != coordy || + LOCINT32( librender, i, SAVED_COORDZ ) != coordz || + LOCDWORD( librender, i, SAVED_GRAPHID ) != LOCDWORD( librender, i, GRAPHID ) || + LOCINT32( librender, i, SAVED_ANGLE ) != LOCINT32( librender, i, ANGLE ) || + LOCDWORD( librender, i, SAVED_ALPHA ) != LOCDWORD( librender, i, ALPHA ) || + LOCDWORD( librender, i, SAVED_BLENDOP ) != LOCDWORD( librender, i, BLENDOP ) || + LOCINT32( librender, i, SAVED_GRAPHSIZE ) != LOCINT32( librender, i, GRAPHSIZE ) || + LOCINT32( librender, i, SAVED_GRAPHSIZEX ) != LOCINT32( librender, i, GRAPHSIZEX ) || + LOCINT32( librender, i, SAVED_GRAPHSIZEY ) != LOCINT32( librender, i, GRAPHSIZEY ) || + LOCDWORD( librender, i, SAVED_FLAGS ) != LOCDWORD( librender, i, FLAGS ) || + LOCDWORD( librender, i, SAVED_FILEID ) != LOCDWORD( librender, i, FILEID ) || + LOCDWORD( librender, i, SAVED_XGRAPH ) != LOCDWORD( librender, i, XGRAPH ) || + ( + graph->ncpoints && + ( + LOCDWORD( librender, i, SAVED_CENTERX ) != graph->cpoints[0].x || + LOCDWORD( librender, i, SAVED_CENTERY ) != graph->cpoints[0].y + ) + ) + ; + + if ( changed ) + { + /* Update key */ + + * z = coordz; + + LOCINT32( librender, i, SAVED_COORDX ) = coordx; + LOCINT32( librender, i, SAVED_COORDY ) = coordy; + LOCINT32( librender, i, SAVED_COORDZ ) = coordz; + LOCDWORD( librender, i, SAVED_GRAPHID ) = LOCDWORD( librender, i, GRAPHID ); + LOCINT32( librender, i, SAVED_ANGLE ) = LOCINT32( librender, i, ANGLE ); + LOCDWORD( librender, i, SAVED_ALPHA ) = LOCDWORD( librender, i, ALPHA ); + LOCDWORD( librender, i, SAVED_BLENDOP ) = LOCDWORD( librender, i, BLENDOP ); + LOCINT32( librender, i, SAVED_GRAPHSIZE ) = LOCINT32( librender, i, GRAPHSIZE ); + LOCINT32( librender, i, SAVED_GRAPHSIZEX ) = LOCINT32( librender, i, GRAPHSIZEX ); + LOCINT32( librender, i, SAVED_GRAPHSIZEY ) = LOCINT32( librender, i, GRAPHSIZEY ); + LOCDWORD( librender, i, SAVED_FLAGS ) = LOCDWORD( librender, i, FLAGS ); + LOCDWORD( librender, i, SAVED_FILEID ) = LOCDWORD( librender, i, FILEID ); + LOCDWORD( librender, i, SAVED_XGRAPH ) = LOCDWORD( librender, i, XGRAPH ); + if ( graph->ncpoints ) + { + LOCDWORD( librender, i, SAVED_CENTERX ) = graph->cpoints[0].x; + LOCDWORD( librender, i, SAVED_CENTERY ) = graph->cpoints[0].y; + } + else + { + LOCDWORD( librender, i, SAVED_CENTERX ) = CPOINT_UNDEFINED; + LOCDWORD( librender, i, SAVED_CENTERY ) = CPOINT_UNDEFINED; + } + + instance_get_bbox( i, graph, region ); + return 1; + } + + return changed; +} + + +/* ---------------------------------------------------------------------- + Dlls Hooks + ---------------------------------------------------------------------- */ + +/* + * FUNCTION : instance_create_hook + * + * PARAMS : + * r Pointer to the instance + * + * RETURN VALUE : + * None + */ + +void __bgdexport( librender, instance_create_hook )( INSTANCE * r ) +{ + /* COORZ is 0 when a new instance is created */ + LOCDWORD( librender, r, OBJECTID ) = gr_new_object( /* LOCINT32( librender, r, COORDZ ) */ 0, draw_instance_info, draw_instance, r ); +} + +/* + * FUNCTION : instance_destroy_hook + * + * PARAMS : + * r Pointer to the instance + * + * RETURN VALUE : + * None + */ + +void __bgdexport( librender, instance_destroy_hook )( INSTANCE * r ) +{ + if ( LOCDWORD( librender, r, OBJECTID ) ) gr_destroy_object( LOCDWORD( librender, r, OBJECTID ) ); +} |