From ea1947ffcc606d757357398b24e74a3f4ecefa07 Mon Sep 17 00:00:00 2001 From: neonloop Date: Wed, 20 Oct 2021 14:54:27 +0000 Subject: Initial commit from steward-fu release --- modules/librender/g_rects.c | 207 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 207 insertions(+) create mode 100644 modules/librender/g_rects.c (limited to 'modules/librender/g_rects.c') diff --git a/modules/librender/g_rects.c b/modules/librender/g_rects.c new file mode 100644 index 0000000..8b6ef4c --- /dev/null +++ b/modules/librender/g_rects.c @@ -0,0 +1,207 @@ +/* + * 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 "librender.h" +#include "fmath.h" + +/* --------------------------------------------------------------------------- */ + +//uint8_t zonearray[ 128 / 8 ]; +#ifdef __USE_BIT_MASK +static uint32_t zonearray[ /* DIRTYROWS * */ DIRTYCOLS ]; +#else +static uint32_t zonearray[ DIRTYROWS ][ DIRTYCOLS ]; +#endif + +/* --------------------------------------------------------------------------- */ + +void gr_rects_clear() +{ + memset( zonearray, 0, sizeof( zonearray ) ); +} + +/* --------------------------------------------------------------------------- */ +/* + * FUNCTION : gr_mark_rect + * + * Updates the given rectangle as a dirty zone at the 128-bits array + * + * PARAMS : + * x, y Top-left coordinate + * width Width in pixels + * height Height in pixels + * + * RETURN VALUE : + * None + */ + +void gr_mark_rect( int x, int y, int width, int height ) +{ +#ifdef __USE_BIT_MASK + int cx, cy; + int w, h; + int iy, lx, ly; + + w = scr_width / DIRTYCOLS; + h = scr_height / DIRTYROWS; + + width = ABS( width ) - 1; + height = ABS( height ) - 1; + + x = MIN( x, x + width ); + y = MIN( y, y + height ); + + iy = MAX( y / h, 0 ); + + lx = MIN(( x + width ) / w, DIRTYCOLS - 1 ); + ly = MIN(( y + height ) / h, DIRTYROWS - 1 ); + + for ( cx = MAX( x / w, 0 ); cx <= lx; cx++ ) + for ( cy = iy; cy <= ly; cy++ ) + zonearray[ cx ] |= ( 1 << cy ); +#else + int cx, cy; + int w, h; + int iy, lx, ly; + + w = scr_width / DIRTYCOLS; + h = scr_height / DIRTYROWS; + + if ( w * DIRTYCOLS != scr_width ) w++; + if ( h * DIRTYROWS != scr_height ) h++; + + width = ABS( width ) - 1; + height = ABS( height ) - 1; + + x = MIN( x, x + width ); + y = MIN( y, y + height ); + + iy = MAX( y / h, 0 ); + + lx = MIN(( x + width ) / w, DIRTYCOLS - 1 ); + ly = MIN(( y + height ) / h, DIRTYROWS - 1 ); + + for ( cx = MAX( x / w, 0 ); cx <= lx; cx++ ) + for ( cy = iy; cy <= ly; cy++ ) + zonearray[ cy ][ cx ] = 1; +#endif +} + +/* --------------------------------------------------------------------------- */ +/* + * FUNCTION : gr_mark_rects + * + * Given a 128-bits array of dirty screen zones, create an array of SDL_Rect regions + * + * PARAMS : + * zonearray Pointer to a 128-bits array with dirty screen zones = 1 + * rects Pointer to a 128 REGION array + * + * RETURN VALUE : + * Number of rects filled + */ + +int gr_mark_rects( REGION * rects ) +{ + int count = 0, x, y; + int w, h, cw, ch, x2; + + w = scr_width / DIRTYCOLS; + h = scr_height / DIRTYROWS; + + if ( w * DIRTYCOLS != scr_width ) w++; + if ( h * DIRTYROWS != scr_height ) h++; + + for ( x = 0; x < DIRTYCOLS; x++ ) + { +#ifdef __USE_BIT_MASK + if ( zonearray[ x ] ) + { + for ( y = 0; y < DIRTYROWS; y++ ) + { + if ( zonearray[ x ] & ( 1 << y ) ) + { + zonearray[ x ] &= ~( 1 << y ); + for ( cw = x + 1; ( cw < DIRTYCOLS ) && ( zonearray[ cw ] & ( 1 << y ) ); cw++ ) + zonearray[ cw ] &= ~( 1 << y ); + + for ( ch = y + 1; ch < DIRTYROWS; ch++ ) + { + /* Si hay algun hueco en el ancho de las siguiente lineas, corto aca, + y deja esta linea para otra recta */ + for ( x2 = x; ( x2 < cw ) && ( zonearray[ x2 ] & ( 1 << ch ) ); x2++ ); + + if ( x2 < cw ) break; + + /* Limpio bitmap de la recta actual */ + for ( x2 = x; x2 < cw; x2++ ) + zonearray[ x2 ] &= ~( 1 << ch ); + } + rects[ count ].x = w * x; + rects[ count ].y = h * y; + rects[ count ].x2 = w * cw - 1 /* + rects[ count ].x */; + rects[ count ].y2 = h * ch - 1 /* + rects[ count ].y */; + count++; + } + } + } +#else + for ( y = 0; y < DIRTYROWS; y++ ) + { + if ( zonearray[ y ][ x ] ) + { + zonearray[ y ][ x ] = 0; + for ( cw = x + 1; ( cw < DIRTYCOLS ) && ( zonearray[ y ][ cw ] ); cw++ ) zonearray[ y ][ cw ] = 0; + + for ( ch = y + 1; ch < DIRTYROWS; ch++ ) + { + /* Si hay algun hueco en el ancho de las siguiente lineas, corto aca, + y deja esta linea para otra recta */ + for ( x2 = x; ( x2 < cw ) && ( zonearray[ ch ][ x2 ] ); x2++ ); + + if ( x2 < cw ) break; + + /* Limpio bitmap de la recta actual */ + for ( x2 = x; x2 < cw; x2++ ) zonearray[ ch ][ x2 ] = 0; + } + + rects[ count ].x = w * x; + rects[ count ].y = h * y; + rects[ count ].x2 = MIN( w * cw - 1, scr_width - 1 ); + rects[ count ].y2 = MIN( h * ch - 1, scr_height - 1 ); + + count++; + } + } +#endif + } + + return count; +} + +/* --------------------------------------------------------------------------- */ -- cgit v1.2.3