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/libvideo/g_video.c | 601 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 601 insertions(+) create mode 100644 modules/libvideo/g_video.c (limited to 'modules/libvideo/g_video.c') diff --git a/modules/libvideo/g_video.c b/modules/libvideo/g_video.c new file mode 100644 index 0000000..ac791d9 --- /dev/null +++ b/modules/libvideo/g_video.c @@ -0,0 +1,601 @@ +/* + * 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 +#include + +#include "bgdrtm.h" + +#include "bgddl.h" +#include "dlvaracc.h" + +#include "libvideo.h" + +#ifdef _WIN32 +#include +#include "ddraw.h" +#endif + +/* --------------------------------------------------------------------------- */ + +GRAPH * icon = NULL ; + +SDL_Surface * screen = NULL ; +SDL_Surface * scale_screen = NULL ; + +char * apptitle = NULL ; + +int scr_width = 0 ; +int scr_height = 0 ; + +int scr_initialized = 0 ; + +int enable_16bits = 0 ; +int enable_32bits = 0 ; +int enable_scale = 0 ; +int full_screen = 0 ; +int double_buffer = 0 ; +int hardware_scr = 0 ; +int grab_input = 0 ; +int frameless = 0 ; +int scale_mode = SCALE_NONE ; +int waitvsync = 0 ; + +int scale_resolution = -1 ; +int * scale_resolution_table_w = NULL; +int * scale_resolution_table_h = NULL; +int scale_resolution_aspectratio = 0; +int scale_resolution_orientation = 0; + +int scale_resolution_aspectratio_offx = 0; +int scale_resolution_aspectratio_offy = 0; + +/* --------------------------------------------------------------------------- */ + +enum { + GRAPH_MODE = 0, + SCALE_MODE, + FULL_SCREEN, + SCALE_RESOLUTION, + SCALE_RESOLUTION_ASPECTRATIO, + SCALE_RESOLUTION_ORIENTATION +}; + +/* --------------------------------------------------------------------------- */ +/* Son las variables que se desea acceder. */ +/* El interprete completa esta estructura, si la variable existe. */ +/* (usada en tiempo de ejecucion) */ + +DLVARFIXUP __bgdexport( libvideo, globals_fixup )[] = +{ + /* Nombre de variable global, puntero al dato, tama�o del elemento, cantidad de elementos */ + { "graph_mode" , NULL, -1, -1 }, + { "scale_mode" , NULL, -1, -1 }, + { "full_screen" , NULL, -1, -1 }, + { "scale_resolution", NULL, -1, -1 }, + + /* new vars for use with scale_resolution */ + { "scale_resolution_aspectratio", NULL, -1, -1 }, + { "scale_resolution_orientation", NULL, -1, -1 }, + + { NULL , NULL, -1, -1 } +}; + +/* --------------------------------------------------------------------------- */ + +#ifdef _WIN32 +/* Based allegro */ + +LPDIRECTDRAW2 directdraw = NULL; +DDCAPS ddcaps; + +HRESULT WINAPI( *_DirectDrawCreate )( GUID FAR *lpGUID, LPDIRECTDRAW FAR *lplpDD, IUnknown FAR *pUnkOuter ); + +/* --------------------------------------------------------------------------- */ + +int init_dx( void ) +{ + HINSTANCE handle; + LPDIRECTDRAW directdraw1; + HRESULT hr; + LPVOID temp; + + handle = LoadLibrary( "DDRAW.DLL" ); + if ( handle == NULL ) return -1; + + _DirectDrawCreate = GetProcAddress( handle, "DirectDrawCreate" ); + + hr = _DirectDrawCreate( NULL, &directdraw1, NULL ); + if ( FAILED( hr ) ) return -1; + + hr = IDirectDraw_QueryInterface( directdraw1, &IID_IDirectDraw2, &directdraw ); + if ( FAILED( hr ) ) return -1; + + IDirectDraw_Release( directdraw1 ); + + hr = IDirectDraw2_SetCooperativeLevel( directdraw, NULL, DDSCL_NORMAL ); + if ( FAILED( hr ) ) return -1; + + /* get capabilities */ + ddcaps.dwSize = sizeof( ddcaps ); + hr = IDirectDraw2_GetCaps( directdraw, &ddcaps, NULL ); + if ( FAILED( hr ) ) return -1; + + return 0; +} +#endif + +/* --------------------------------------------------------------------------- */ + +void gr_wait_vsync() +{ +#ifdef _WIN32 + if ( directdraw ) IDirectDraw2_WaitForVerticalBlank( directdraw, DDWAITVB_BLOCKBEGIN, NULL ); +#endif +} + +/* --------------------------------------------------------------------------- */ + +void gr_set_caption( char * title ) +{ + SDL_WM_SetCaption( apptitle = title, "" ) ; +} + +/* --------------------------------------------------------------------------- */ + +int gr_set_icon( GRAPH * map ) +{ + if (( icon = map )) + { + SDL_Surface *ico = NULL; + if ( icon->format->depth == 8 ) + { + SDL_Color palette[256]; + if ( sys_pixel_format && sys_pixel_format->palette ) + { + int n ; + for ( n = 0 ; n < 256 ; n++ ) + { + palette[ n ].r = sys_pixel_format->palette->rgb[ n ].r; + palette[ n ].g = sys_pixel_format->palette->rgb[ n ].g; + palette[ n ].b = sys_pixel_format->palette->rgb[ n ].b; + } + } + + ico = SDL_CreateRGBSurfaceFrom( icon->data, 32, 32, 8, 32, 0x00, 0x00, 0x00, 0x00 ) ; + SDL_SetPalette( ico, SDL_LOGPAL, palette, 0, 256 ); + } + else + { + ico = SDL_CreateRGBSurfaceFrom( icon->data, 32, 32, icon->format->depth, icon->pitch, icon->format->Rmask, icon->format->Gmask, icon->format->Bmask, icon->format->Amask ) ; + } + + SDL_SetColorKey( ico, SDL_SRCCOLORKEY, SDL_MapRGB( ico->format, 0, 0, 0 ) ) ; + SDL_WM_SetIcon( ico, NULL ); + SDL_FreeSurface( ico ) ; + } + + return 1 ; +} + +/* --------------------------------------------------------------------------- */ + +int gr_set_mode( int width, int height, int depth ) +{ + int n ; + int sdl_flags = 0; + int surface_width = width; + int surface_height = height; + char * e; + + enable_scale = ( GLODWORD( libvideo, GRAPH_MODE ) & MODE_2XSCALE ) ? 1 : 0 ; + full_screen = ( GLODWORD( libvideo, GRAPH_MODE ) & MODE_FULLSCREEN ) ? 1 : 0 ; + double_buffer = ( GLODWORD( libvideo, GRAPH_MODE ) & MODE_DOUBLEBUFFER ) ? 1 : 0 ; + hardware_scr = ( GLODWORD( libvideo, GRAPH_MODE ) & MODE_HARDWARE ) ? 1 : 0 ; + grab_input = ( GLODWORD( libvideo, GRAPH_MODE ) & MODE_MODAL ) ? 1 : 0 ; + frameless = ( GLODWORD( libvideo, GRAPH_MODE ) & MODE_FRAMELESS ) ? 1 : 0 ; + waitvsync = ( GLODWORD( libvideo, GRAPH_MODE ) & MODE_WAITVSYNC ) ? 1 : 0 ; + scale_mode = GLODWORD( libvideo, SCALE_MODE ); + full_screen |= GLODWORD( libvideo, FULL_SCREEN ); + + scale_resolution = GLODWORD( libvideo, SCALE_RESOLUTION ); + + if ( GLOEXISTS( libvideo, SCALE_RESOLUTION_ASPECTRATIO ) ) scale_resolution_aspectratio = GLODWORD( libvideo, SCALE_RESOLUTION_ASPECTRATIO ); + if ( GLOEXISTS( libvideo, SCALE_RESOLUTION_ORIENTATION ) ) scale_resolution_orientation = GLODWORD( libvideo, SCALE_RESOLUTION_ORIENTATION ); + + /* Overwrite all params */ + + if ( ( e = getenv( "SCALE_RESOLUTION" ) ) ) scale_resolution = atol( e ); + if ( ( e = getenv( "SCALE_RESOLUTION_ASPECTRATIO" ) ) ) scale_resolution_aspectratio = atol( e ); + if ( ( e = getenv( "SCALE_RESOLUTION_ORIENTATION" ) ) ) scale_resolution_orientation = atol( e ); + + if ( scale_resolution_orientation < 0 || scale_resolution_orientation > 4 ) scale_resolution_orientation = 0; + + if ( !depth ) + { + enable_32bits = ( GLODWORD( libvideo, GRAPH_MODE ) & MODE_32BITS ) ? 1 : 0 ; + if ( !enable_32bits ) + enable_16bits = ( GLODWORD( libvideo, GRAPH_MODE ) & MODE_16BITS ) ? 1 : 0 ; + else + enable_16bits = 0; + depth = enable_32bits ? 32 : ( enable_16bits ? 16 : 8 ); + } + else if ( depth == 16 ) + { + enable_16bits = 1; + enable_32bits = 0; + } + else if ( depth == 32 ) + { + enable_16bits = 0; + enable_32bits = 1; + } + + if ( scale_resolution_table_w ) + { + free( scale_resolution_table_w ); + scale_resolution_table_w = NULL; + } + + if ( scale_resolution_table_h ) + { + free( scale_resolution_table_h ); + scale_resolution_table_h = NULL; + } + + if ( scale_resolution != -1 ) + { + surface_width = scale_resolution / 10000 ; + surface_height = scale_resolution % 10000 ; + } + else + { + if ( scale_mode != SCALE_NONE ) enable_scale = 1; + if ( enable_scale && scale_mode == SCALE_NONE ) scale_mode = SCALE_SCALE2X; + + if ( enable_scale ) + { + enable_16bits = 1; + depth = 16; + + surface_width *= 2; + surface_height *= 2; + } + } + + /* Inicializa el modo gr�fico */ + + if ( scrbitmap ) + { + bitmap_destroy( scrbitmap ) ; + scrbitmap = NULL ; + } + + /* Setup the SDL Video Mode */ + + sdl_flags = SDL_HWPALETTE; + if ( double_buffer ) sdl_flags |= SDL_DOUBLEBUF; + if ( full_screen ) sdl_flags |= SDL_FULLSCREEN; + if ( frameless ) sdl_flags |= SDL_NOFRAME; + + sdl_flags |= hardware_scr ? SDL_HWSURFACE : SDL_SWSURFACE; + + if ( scale_screen ) + { + SDL_FreeSurface( scale_screen ); + scale_screen = NULL; + } + if ( screen ) + { + SDL_FreeSurface( screen ); + screen = NULL; + } + + if ( scale_resolution != -1 ) + { + switch ( scale_resolution_orientation ) + { + case SRO_LEFT: + case SRO_RIGHT: + { + int aux = surface_width; + surface_width = surface_height; + surface_height = aux; + break; + } + } + + scale_screen = SDL_SetVideoMode( surface_width, surface_height, depth, sdl_flags ); + + if ( !scale_screen ) return -1; + + if ( !width && !height ) + { + width = scale_screen->w; + height = scale_screen->h; + } + + screen = SDL_CreateRGBSurface( sdl_flags, + width, + height, + scale_screen->format->BitsPerPixel, + scale_screen->format->Rmask, + scale_screen->format->Gmask, + scale_screen->format->Bmask, + scale_screen->format->Amask + ); + + /* scale tables */ + + int lim_w = 0, lim_h = 0, pitch_w = 0, pitch_h = 0; + double fw = 0.0, fh = 0.0, fx = 0.0, fy = 0.0; + int h, w; + int start_w = 0, start_h = 0, fix = 1; + + scale_resolution_aspectratio_offx = 0; + scale_resolution_aspectratio_offy = 0; + + switch ( scale_resolution_orientation ) + { + case SRO_NORMAL: + case SRO_DOWN: + lim_w = screen->w; + lim_h = screen->h; + + pitch_w = 1; + pitch_h = screen->pitch; + + fw = (double)screen->w / (double)scale_screen->w; + fh = (double)screen->h / (double)scale_screen->h; + break; + + case SRO_LEFT: + case SRO_RIGHT: + lim_w = screen->h; + lim_h = screen->w; + + pitch_w = screen->pitch; + pitch_h = 1; + + fh = (double)screen->w / (double)scale_screen->h; + fw = (double)screen->h / (double)scale_screen->w; + break; + } + + switch ( scale_resolution_orientation ) + { + case SRO_NORMAL: + case SRO_LEFT: + start_w = 0; + start_h = 0; + fix = -1; + break; + + case SRO_DOWN: + case SRO_RIGHT: + start_w = scale_screen->w - 1; + start_h = scale_screen->h - 1; + fix = 1; + break; + } + + if ( scale_resolution_aspectratio == SRA_PRESERVE ) + { + if ( scale_screen->w > scale_screen->h ) + { + fw = fh; + scale_resolution_aspectratio_offx = ( scale_screen->w - lim_w / fw ) / 2 ; + scale_resolution_aspectratio_offy = 0; + } + else + { + fh = fw; + scale_resolution_aspectratio_offx = 0; + scale_resolution_aspectratio_offy = ( scale_screen->h - lim_h / fh ) / 2 ; + } + } + + if ( !( scale_resolution_table_w = malloc( scale_screen->w * sizeof( int ) ) ) ) return -1; + if ( !( scale_resolution_table_h = malloc( scale_screen->h * sizeof( int ) ) ) ) return -1; + + for ( w = 0; w < scale_screen->w; w++ ) + { + if ( w < scale_resolution_aspectratio_offx ) + scale_resolution_table_w[ start_w - w * fix ] = -1; + else + { + scale_resolution_table_w[ start_w - w * fix ] = ( fx < lim_w ) ? pitch_w * ( int ) fx : -1 ; + fx += fw; + } + } + + for ( h = 0; h < scale_screen->h; h++ ) + { + if ( h < scale_resolution_aspectratio_offy ) + scale_resolution_table_h[ start_h - h * fix ] = -1; + else + { + scale_resolution_table_h[ start_h - h * fix ] = ( fy < lim_h ) ? pitch_h * ( int ) fy : -1 ; + fy += fh; + } + } + } + else + { + screen = SDL_SetVideoMode( surface_width, surface_height, depth, sdl_flags ); + } + + if ( !screen ) return -1; + + SDL_WM_GrabInput( grab_input ? SDL_GRAB_ON : SDL_GRAB_OFF ) ; + + /* Set window title */ + gr_set_caption( apptitle ) ; + + if ( !sys_pixel_format ) + { + sys_pixel_format = bitmap_create_format( depth ); + } + else + { + PALETTE * p = sys_pixel_format->palette; + + free( sys_pixel_format ); + sys_pixel_format = bitmap_create_format( depth ); + + if ( p ) + { + sys_pixel_format->palette = p; + pal_refresh( sys_pixel_format->palette ) ; + } + } + + if ( sys_pixel_format->depth == 16 ) + { + for ( n = 0 ; n < 65536 ; n++ ) + { + colorghost[ n ] = + ((( n & screen->format->Rmask ) >> 1 ) & screen->format->Rmask ) + + ((( n & screen->format->Gmask ) >> 1 ) & screen->format->Gmask ) + + ((( n & screen->format->Bmask ) >> 1 ) & screen->format->Bmask ) ; + } +// bitmap_16bits_conversion(); + } + + scr_initialized = 1 ; + + SDL_ShowCursor( 0 ) ; + + pal_refresh( NULL ) ; + palette_changed = 1 ; + +// gr_make_trans_table(); +/* + if ( scale_resolution == -1 && enable_scale ) + { + surface_width = screen->w * 2; + surface_height = screen->h * 2; + } +*/ + /* Bitmaps de fondo */ + + scr_width = screen->w / ( scale_mode != 0 ? 2 : 1 ) ; + scr_height = screen->h / ( scale_mode != 0 ? 2 : 1 ) ; + + /* Only allow background with same properties that video mode */ + if ( + !background || + scr_width != screen->w || scr_height != screen->h || + sys_pixel_format->depth != background->format->depth ) + { + if ( background ) bitmap_destroy( background ); + background = bitmap_new( 0, scr_width, scr_height, sys_pixel_format->depth ) ; + if ( background ) + { + gr_clear( background ) ; + bitmap_add_cpoint( background, 0, 0 ) ; + } + } + + regions[0].x = 0 ; + regions[0].y = 0 ; + regions[0].x2 = scr_width - 1 ; + regions[0].y2 = scr_height - 1 ; + + // Finalmente seteamos icono de aplicacion + // Necesitamos crear una surface a partir de un MAP generico de 16x16... + gr_set_icon( icon ); + + if ( background ) background->modified = 1; + +// gr_rects_clear(); + + return 0; +} + +/* --------------------------------------------------------------------------- */ + +int gr_init( int width, int height ) +{ + return gr_set_mode( width, height, 0 ); +} + +/* --------------------------------------------------------------------------- */ + +void __bgdexport( libvideo, module_initialize )() +{ + char * e; + + GLODWORD( libvideo, SCALE_RESOLUTION ) = -1; // hack for backward compatibility + + if ( !SDL_WasInit( SDL_INIT_VIDEO ) ) SDL_InitSubSystem( SDL_INIT_VIDEO ); + +#ifdef _WIN32 + if ( !directdraw ) init_dx(); +#endif + apptitle = appname; + + if ( ( e = getenv( "VIDEO_WIDTH" ) ) ) scr_width = atoi(e); + if ( ( e = getenv( "VIDEO_HEIGHT" ) ) ) scr_height = atoi(e); + if ( ( e = getenv( "VIDEO_DEPTH" ) ) ) + GLODWORD( libvideo, GRAPH_MODE ) = atoi(e); + else + GLODWORD( libvideo, GRAPH_MODE ) = MODE_16BITS; + if ( ( e = getenv( "VIDEO_FULLSCREEN" ) ) ) GLODWORD( libvideo, GRAPH_MODE ) |= atoi(e) ? MODE_FULLSCREEN : 0; + + gr_init( scr_width, scr_height ) ; +} + +/* --------------------------------------------------------------------------- */ + +void __bgdexport( libvideo, module_finalize )() +{ +#ifdef _WIN32 + if ( directdraw ) + { + /* set cooperative level back to normal */ + IDirectDraw2_SetCooperativeLevel( directdraw, NULL, DDSCL_NORMAL ); + + /* release DirectDraw interface */ + IDirectDraw2_Release( directdraw ); + + directdraw = NULL; + } +#endif + if ( SDL_WasInit( SDL_INIT_VIDEO ) ) SDL_QuitSubSystem( SDL_INIT_VIDEO ); +} + +/* --------------------------------------------------------------------------- */ +/* exports */ +/* --------------------------------------------------------------------------- */ + +#include "libvideo_exports.h" + +/* --------------------------------------------------------------------------- */ -- cgit v1.2.3