/* * 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" /* --------------------------------------------------------------------------- */