2009-11-17 14:27:39 +00:00
/*
*
* OGL video functions . - Added 9 / 15 / 99 Matthew Mueller
*
*/
2006-03-20 16:43:15 +00:00
2007-06-11 15:54:09 +00:00
# define DECLARE_VARS
2006-03-20 16:43:15 +00:00
# include <stdlib.h>
# include <stdio.h>
# include <string.h>
2009-11-17 14:27:39 +00:00
# ifdef _MSC_VER
2006-03-20 16:43:15 +00:00
# include <windows.h>
# endif
2009-11-17 14:27:39 +00:00
# if !defined(_MSC_VER) && !defined(macintosh)
2006-03-20 16:43:15 +00:00
# include <unistd.h>
2009-01-14 19:54:45 +00:00
# endif
2009-11-17 14:27:39 +00:00
# if !defined(macintosh)
2006-03-20 16:43:15 +00:00
# include <sys/types.h>
# include <sys/stat.h>
# include <fcntl.h>
2008-01-03 10:31:02 +00:00
# endif
2009-11-17 14:27:39 +00:00
2006-03-20 16:43:15 +00:00
# include <errno.h>
2008-04-19 19:11:32 +00:00
# include <SDL/SDL.h>
2006-03-20 16:43:15 +00:00
# include "hudmsg.h"
# include "game.h"
# include "text.h"
# include "gr.h"
# include "gamefont.h"
# include "grdef.h"
# include "palette.h"
# include "u_mem.h"
# include "error.h"
# include "inferno.h"
# include "screens.h"
# include "strutil.h"
# include "args.h"
# include "key.h"
2008-01-23 17:25:09 +00:00
# include "physfsx.h"
2009-11-17 14:27:39 +00:00
# include "internal.h"
# include "render.h"
2008-04-06 20:23:28 +00:00
# include "console.h"
2009-11-17 14:27:39 +00:00
# include "config.h"
# include "playsave.h"
# include "vers_id.h"
# include "game.h"
2008-01-03 10:31:02 +00:00
# if defined(__APPLE__) && defined(__MACH__)
# include <OpenGL/glu.h>
# else
2006-03-20 16:43:15 +00:00
# include <GL/glu.h>
2008-01-03 10:31:02 +00:00
# endif
2006-03-20 16:43:15 +00:00
int gr_installed = 0 ;
int gl_initialized = 0 ;
int ogl_fullscreen = 0 ;
2008-04-19 19:11:32 +00:00
static int curx = - 1 , cury = - 1 , curfull = 0 ;
2008-11-09 14:31:30 +00:00
int linedotscale = 1 ; // scalar of glLinewidth and glPointSize - only calculated once when resolution changes
2008-04-19 19:11:32 +00:00
void ogl_swap_buffers_internal ( void )
{
SDL_GL_SwapBuffers ( ) ;
}
int ogl_init_window ( int x , int y )
{
if ( gl_initialized ) {
if ( x = = curx & & y = = cury & & curfull = = ogl_fullscreen )
return 0 ;
2008-11-09 14:31:30 +00:00
ogl_smash_texture_list_internal ( ) ; //if we are or were fullscreen, changing vid mode will invalidate current textures
2008-04-19 19:11:32 +00:00
}
2008-11-09 14:31:30 +00:00
SDL_WM_SetCaption ( DESCENT_VERSION , " Descent " ) ;
2010-08-21 17:08:53 +00:00
SDL_WM_SetIcon ( SDL_LoadBMP ( " d1x-rebirth.bmp " ) , NULL ) ;
2010-01-29 21:53:17 +00:00
if ( ! SDL_SetVideoMode ( x , y , GameArg . DbgBpp , SDL_OPENGL | ( ogl_fullscreen ? SDL_FULLSCREEN : 0 ) ) )
2008-04-19 19:11:32 +00:00
{
2010-01-29 21:53:17 +00:00
Error ( " Could not set %dx%dx%d opengl video mode: %s \n " , x , y , GameArg . DbgBpp , SDL_GetError ( ) ) ;
2008-04-19 19:11:32 +00:00
}
SDL_ShowCursor ( 0 ) ;
curx = x ; cury = y ; curfull = ogl_fullscreen ;
2009-11-17 14:27:39 +00:00
2008-11-09 14:31:30 +00:00
linedotscale = ( ( x / 640 < y / 480 ? x / 640 : y / 480 ) < 1 ? 1 : ( x / 640 < y / 480 ? x / 640 : y / 480 ) ) ;
2008-04-19 19:11:32 +00:00
2008-11-09 14:31:30 +00:00
gl_initialized = 1 ;
2008-04-19 19:11:32 +00:00
return 0 ;
}
2006-03-20 16:43:15 +00:00
2008-04-19 19:11:32 +00:00
int gr_check_fullscreen ( void )
{
2006-03-20 16:43:15 +00:00
return ogl_fullscreen ;
}
2008-04-19 19:11:32 +00:00
void gr_do_fullscreen ( int f )
{
2008-04-06 20:23:28 +00:00
ogl_fullscreen = f ;
2008-04-19 19:11:32 +00:00
if ( gl_initialized )
{
2010-01-29 21:53:17 +00:00
if ( ! SDL_VideoModeOK ( curx , cury , GameArg . DbgBpp , SDL_OPENGL | ( ogl_fullscreen ? SDL_FULLSCREEN : 0 ) ) )
2008-04-19 19:11:32 +00:00
{
con_printf ( CON_URGENT , " Cannot set %ix%i. Fallback to 640x480 \n " , curx , cury ) ;
curx = 640 ;
cury = 480 ;
Game_screen_mode = SM ( curx , cury ) ;
}
2010-06-24 09:29:11 +00:00
2008-04-19 19:11:32 +00:00
ogl_init_window ( curx , cury ) ;
2006-03-20 16:43:15 +00:00
}
}
2008-04-19 19:11:32 +00:00
int gr_toggle_fullscreen ( void )
{
2006-03-20 16:43:15 +00:00
gr_do_fullscreen ( ! ogl_fullscreen ) ;
2007-05-09 09:44:45 +00:00
2010-07-29 20:19:52 +00:00
if ( gl_initialized ) // update viewing values for menus
2007-05-09 09:44:45 +00:00
{
glMatrixMode ( GL_PROJECTION ) ;
glLoadIdentity ( ) ;
glOrtho ( 0.0 , 1.0 , 0.0 , 1.0 , - 1.0 , 1.0 ) ;
glMatrixMode ( GL_MODELVIEW ) ;
glLoadIdentity ( ) ; //clear matrix
glEnable ( GL_BLEND ) ;
glBlendFunc ( GL_SRC_ALPHA , GL_ONE_MINUS_SRC_ALPHA ) ;
}
2008-10-19 12:53:30 +00:00
GameCfg . WindowMode = ! ogl_fullscreen ;
2006-03-20 16:43:15 +00:00
return ogl_fullscreen ;
}
2007-03-22 14:15:46 +00:00
extern void ogl_init_pixel_buffers ( int w , int h ) ;
2009-11-17 14:27:39 +00:00
extern void ogl_close_pixel_buffers ( void ) ;
2007-03-22 14:15:46 +00:00
2008-04-19 19:11:32 +00:00
void ogl_init_state ( void )
{
2006-03-20 16:43:15 +00:00
/* select clearing (background) color */
glClearColor ( 0.0 , 0.0 , 0.0 , 0.0 ) ;
/* initialize viewing values */
glMatrixMode ( GL_PROJECTION ) ;
glLoadIdentity ( ) ;
glOrtho ( 0.0 , 1.0 , 0.0 , 1.0 , - 1.0 , 1.0 ) ;
2007-03-22 14:15:46 +00:00
glMatrixMode ( GL_MODELVIEW ) ;
glLoadIdentity ( ) ; //clear matrix
glEnable ( GL_BLEND ) ;
glBlendFunc ( GL_SRC_ALPHA , GL_ONE_MINUS_SRC_ALPHA ) ;
gr_palette_step_up ( 0 , 0 , 0 ) ; //in case its left over from in game
2009-11-17 14:27:39 +00:00
2007-01-09 01:23:49 +00:00
ogl_init_pixel_buffers ( grd_curscreen - > sc_w , grd_curscreen - > sc_h ) ;
2006-03-20 16:43:15 +00:00
}
2007-03-22 14:15:46 +00:00
// Set the buffer to draw to. 0 is front, 1 is back
void gr_set_draw_buffer ( int buf )
{
glDrawBuffer ( ( buf = = 0 ) ? GL_FRONT : GL_BACK ) ;
}
2009-11-17 14:27:39 +00:00
const char * gl_vendor , * gl_renderer , * gl_version , * gl_extensions ;
2007-07-23 18:13:49 +00:00
2008-04-19 19:11:32 +00:00
void ogl_get_verinfo ( void )
{
2009-11-17 14:27:39 +00:00
gl_vendor = ( const char * ) glGetString ( GL_VENDOR ) ;
gl_renderer = ( const char * ) glGetString ( GL_RENDERER ) ;
gl_version = ( const char * ) glGetString ( GL_VERSION ) ;
gl_extensions = ( const char * ) glGetString ( GL_EXTENSIONS ) ;
2006-03-20 16:43:15 +00:00
2008-05-01 21:40:34 +00:00
con_printf ( CON_VERBOSE , " OpenGL: vendor: %s \n OpenGL: renderer: %s \n OpenGL: version: %s \n " , gl_vendor , gl_renderer , gl_version ) ;
2006-03-20 16:43:15 +00:00
2008-04-06 20:23:28 +00:00
# ifdef _WIN32
2006-03-20 16:43:15 +00:00
dglMultiTexCoord2fARB = ( glMultiTexCoord2fARB_fp ) wglGetProcAddress ( " glMultiTexCoord2fARB " ) ;
dglActiveTextureARB = ( glActiveTextureARB_fp ) wglGetProcAddress ( " glActiveTextureARB " ) ;
dglMultiTexCoord2fSGIS = ( glMultiTexCoord2fSGIS_fp ) wglGetProcAddress ( " glMultiTexCoord2fSGIS " ) ;
dglSelectTextureSGIS = ( glSelectTextureSGIS_fp ) wglGetProcAddress ( " glSelectTextureSGIS " ) ;
# endif
//add driver specific hacks here. whee.
2008-04-19 19:11:32 +00:00
if ( ( stricmp ( gl_renderer , " Mesa NVIDIA RIVA 1.0 \n " ) = = 0 | | stricmp ( gl_renderer , " Mesa NVIDIA RIVA 1.2 \n " ) = = 0 ) & & stricmp ( gl_version , " 1.2 Mesa 3.0 " ) = = 0 )
{
2007-07-23 18:13:49 +00:00
GameArg . DbgGlIntensity4Ok = 0 ; //ignores alpha, always black background instead of transparent.
GameArg . DbgGlReadPixelsOk = 0 ; //either just returns all black, or kills the X server entirely
GameArg . DbgGlGetTexLevelParamOk = 0 ; //returns random data..
2006-10-10 23:41:12 +00:00
}
2009-11-17 14:27:39 +00:00
if ( stricmp ( gl_vendor , " Matrox Graphics Inc. " ) = = 0 )
{
//displays garbage. reported by
// redomen@crcwnet.com (render="Matrox G400" version="1.1.3 5.52.015")
// orulz (Matrox G200)
GameArg . DbgGlIntensity4Ok = 0 ;
}
2008-01-03 10:31:02 +00:00
# ifdef macintosh
2008-04-19 19:11:32 +00:00
if ( stricmp ( gl_renderer , " 3dfx Voodoo 3 " ) = = 0 ) // strangely, includes Voodoo 2
2008-01-03 10:31:02 +00:00
GameArg . DbgGlGetTexLevelParamOk = 0 ; // Always returns 0
# endif
2006-10-08 23:18:07 +00:00
# ifndef NDEBUG
2008-04-06 20:23:28 +00:00
con_printf ( CON_VERBOSE , " gl_intensity4:%i gl_luminance4_alpha4:%i gl_rgba2:%i gl_readpixels:%i gl_gettexlevelparam:%i \n " , GameArg . DbgGlIntensity4Ok , GameArg . DbgGlLuminance4Alpha4Ok , GameArg . DbgGlRGBA2Ok , GameArg . DbgGlReadPixelsOk , GameArg . DbgGlGetTexLevelParamOk ) ;
2006-10-08 23:18:07 +00:00
# endif
2006-03-20 16:43:15 +00:00
}
2010-06-24 09:29:11 +00:00
// returns possible (fullscreen) resolutions if any.
int gr_list_modes ( u_int32_t gsmodes [ ] )
{
SDL_Rect * * modes ;
int i = 0 , modesnum = 0 ;
int sdl_check_flags = SDL_OPENGL | SDL_FULLSCREEN ; // always use Fullscreen as lead.
modes = SDL_ListModes ( NULL , sdl_check_flags ) ;
if ( modes = = ( SDL_Rect * * ) 0 ) // check if we get any modes - if not, return 0
return 0 ;
if ( modes = = ( SDL_Rect * * ) - 1 )
{
return 0 ; // can obviously use any resolution... strange!
}
else
{
for ( i = 0 ; modes [ i ] ; + + i )
{
2010-07-25 00:49:33 +00:00
if ( modes [ i ] - > w > 0xFFF0 | | modes [ i ] - > h > 0xFFF0 // resolutions saved in 32bits. so skip bigger ones (unrealistic in 2010) (kreatordxx - made 0xFFF0 to kill warning)
2010-06-24 09:29:11 +00:00
| | modes [ i ] - > w < 320 | | modes [ i ] - > h < 200 ) // also skip everything smaller than 320x200
continue ;
gsmodes [ modesnum ] = SM ( modes [ i ] - > w , modes [ i ] - > h ) ;
modesnum + + ;
if ( modesnum > = 50 ) // that really seems to be enough big boy.
break ;
}
return modesnum ;
}
}
2009-11-17 14:27:39 +00:00
int gr_check_mode ( u_int32_t mode )
{
unsigned int w , h ;
2010-06-24 09:29:11 +00:00
2009-11-17 14:27:39 +00:00
w = SM_W ( mode ) ;
h = SM_H ( mode ) ;
2010-06-24 09:29:11 +00:00
2010-01-29 21:53:17 +00:00
return SDL_VideoModeOK ( w , h , GameArg . DbgBpp , SDL_OPENGL | ( ogl_fullscreen ? SDL_FULLSCREEN : 0 ) ) ;
2009-11-17 14:27:39 +00:00
}
2006-03-20 16:43:15 +00:00
int gr_set_mode ( u_int32_t mode )
{
2006-10-08 23:18:07 +00:00
unsigned int w , h ;
2006-03-20 16:43:15 +00:00
char * gr_bm_data ;
if ( mode < = 0 )
return 0 ;
w = SM_W ( mode ) ;
h = SM_H ( mode ) ;
2008-04-19 19:11:32 +00:00
2010-01-29 21:53:17 +00:00
if ( ! SDL_VideoModeOK ( w , h , GameArg . DbgBpp , SDL_OPENGL | ( ogl_fullscreen ? SDL_FULLSCREEN : 0 ) ) )
2008-04-19 19:11:32 +00:00
{
con_printf ( CON_URGENT , " Cannot set %ix%i. Fallback to 640x480 \n " , w , h ) ;
w = 640 ;
h = 480 ;
Game_screen_mode = mode = SM ( w , h ) ;
}
2006-10-08 23:18:07 +00:00
gr_bm_data = ( char * ) grd_curscreen - > sc_canvas . cv_bitmap . bm_data ; //since we use realloc, we want to keep this pointer around.
2006-03-20 16:43:15 +00:00
memset ( grd_curscreen , 0 , sizeof ( grs_screen ) ) ;
grd_curscreen - > sc_mode = mode ;
grd_curscreen - > sc_w = w ;
grd_curscreen - > sc_h = h ;
2008-04-06 20:23:28 +00:00
grd_curscreen - > sc_aspect = fixdiv ( grd_curscreen - > sc_w * GameCfg . AspectX , grd_curscreen - > sc_h * GameCfg . AspectY ) ;
2006-03-20 16:43:15 +00:00
grd_curscreen - > sc_canvas . cv_bitmap . bm_x = 0 ;
grd_curscreen - > sc_canvas . cv_bitmap . bm_y = 0 ;
grd_curscreen - > sc_canvas . cv_bitmap . bm_w = w ;
grd_curscreen - > sc_canvas . cv_bitmap . bm_h = h ;
grd_curscreen - > sc_canvas . cv_bitmap . bm_rowsize = w ;
grd_curscreen - > sc_canvas . cv_bitmap . bm_type = BM_OGL ;
2008-01-23 17:25:09 +00:00
grd_curscreen - > sc_canvas . cv_bitmap . bm_data = d_realloc ( gr_bm_data , w * h ) ;
2006-03-20 16:43:15 +00:00
gr_set_current_canvas ( NULL ) ;
2008-04-19 19:11:32 +00:00
2006-03-20 16:43:15 +00:00
ogl_init_window ( w , h ) ; //platform specific code
ogl_get_verinfo ( ) ;
OGL_VIEWPORT ( 0 , 0 , w , h ) ;
2007-03-22 14:15:46 +00:00
ogl_init_state ( ) ;
2008-02-24 14:41:27 +00:00
gamefont_choose_game_font ( w , h ) ;
2010-06-24 09:29:11 +00:00
2006-03-20 16:43:15 +00:00
return 0 ;
}
# define GLstrcmptestr(a,b) if (stricmp(a,#b)==0 || stricmp(a,"GL_" #b)==0)return GL_ ## b;
2008-04-19 19:11:32 +00:00
int ogl_atotexfilti ( char * a , int min )
{
2006-03-20 16:43:15 +00:00
GLstrcmptestr ( a , NEAREST ) ;
GLstrcmptestr ( a , LINEAR ) ;
2008-04-19 19:11:32 +00:00
if ( min )
{ //mipmaps are valid only for the min filter
2006-03-20 16:43:15 +00:00
GLstrcmptestr ( a , NEAREST_MIPMAP_NEAREST ) ;
GLstrcmptestr ( a , NEAREST_MIPMAP_LINEAR ) ;
GLstrcmptestr ( a , LINEAR_MIPMAP_NEAREST ) ;
GLstrcmptestr ( a , LINEAR_MIPMAP_LINEAR ) ;
}
Error ( " unknown/invalid texture filter %s \n " , a ) ;
}
2006-09-08 23:31:06 +00:00
2008-04-19 19:11:32 +00:00
int ogl_testneedmipmaps ( int i )
{
switch ( i )
{
2006-03-20 16:43:15 +00:00
case GL_NEAREST :
case GL_LINEAR :
return 0 ;
case GL_NEAREST_MIPMAP_NEAREST :
case GL_NEAREST_MIPMAP_LINEAR :
case GL_LINEAR_MIPMAP_NEAREST :
case GL_LINEAR_MIPMAP_LINEAR :
return 1 ;
}
Error ( " unknown texture filter %x \n " , i ) ;
}
2007-07-18 20:13:17 +00:00
2008-04-06 20:23:28 +00:00
# ifdef _WIN32
2006-03-20 16:43:15 +00:00
char * OglLibPath = " opengl32.dll " ;
int ogl_rt_loaded = 0 ;
int ogl_init_load_library ( void )
{
int retcode = 0 ;
2008-04-19 19:11:32 +00:00
if ( ! ogl_rt_loaded )
{
2006-03-20 16:43:15 +00:00
retcode = OpenGL_LoadLibrary ( true ) ;
if ( retcode )
{
if ( ! glEnd )
{
Error ( " Opengl: Functions not imported \n " ) ;
}
2008-04-19 19:11:32 +00:00
}
else
{
2009-11-17 14:27:39 +00:00
Error ( " Opengl: error loading %s \n " , OglLibPath ) ;
2006-03-20 16:43:15 +00:00
}
ogl_rt_loaded = 1 ;
}
return retcode ;
}
# endif
2008-04-22 08:29:29 +00:00
void gr_set_attributes ( void )
2006-03-20 16:43:15 +00:00
{
2008-04-06 20:23:28 +00:00
switch ( GameCfg . TexFilt )
{
case 2 :
OglTexMagFilt = GL_LINEAR ;
OglTexMinFilt = GL_LINEAR_MIPMAP_LINEAR ;
break ;
case 1 :
OglTexMagFilt = GL_LINEAR ;
OglTexMinFilt = GL_LINEAR_MIPMAP_NEAREST ;
break ;
default :
OglTexMagFilt = GL_NEAREST ;
OglTexMinFilt = GL_NEAREST ;
break ;
}
2007-06-10 16:21:53 +00:00
2008-04-06 20:23:28 +00:00
GL_needmipmaps = ogl_testneedmipmaps ( OglTexMinFilt ) ;
2007-06-10 16:21:53 +00:00
2008-04-19 19:11:32 +00:00
SDL_GL_SetAttribute ( SDL_GL_DEPTH_SIZE , 16 ) ;
SDL_GL_SetAttribute ( SDL_GL_STENCIL_SIZE , 0 ) ;
SDL_GL_SetAttribute ( SDL_GL_ACCUM_RED_SIZE , 0 ) ;
SDL_GL_SetAttribute ( SDL_GL_ACCUM_GREEN_SIZE , 0 ) ;
SDL_GL_SetAttribute ( SDL_GL_ACCUM_BLUE_SIZE , 0 ) ;
SDL_GL_SetAttribute ( SDL_GL_ACCUM_ALPHA_SIZE , 0 ) ;
SDL_GL_SetAttribute ( SDL_GL_DOUBLEBUFFER , 1 ) ;
2008-04-21 18:39:49 +00:00
SDL_GL_SetAttribute ( SDL_GL_SWAP_CONTROL , GameCfg . VSync ) ;
2008-04-22 08:29:29 +00:00
if ( GameCfg . Multisample )
{
SDL_GL_SetAttribute ( SDL_GL_MULTISAMPLEBUFFERS , 1 ) ;
SDL_GL_SetAttribute ( SDL_GL_MULTISAMPLESAMPLES , 4 ) ;
}
else
{
SDL_GL_SetAttribute ( SDL_GL_MULTISAMPLEBUFFERS , 0 ) ;
SDL_GL_SetAttribute ( SDL_GL_MULTISAMPLESAMPLES , 0 ) ;
}
ogl_smash_texture_list_internal ( ) ;
}
int gr_init ( int mode )
{
int retcode ;
// Only do this function once!
if ( gr_installed = = 1 )
return - 1 ;
# ifdef _WIN32
ogl_init_load_library ( ) ;
# endif
if ( ! GameCfg . WindowMode & & ! GameArg . SysWindow )
gr_toggle_fullscreen ( ) ;
gr_set_attributes ( ) ;
2006-03-20 16:43:15 +00:00
ogl_init_texture_list_internal ( ) ;
2008-04-22 08:29:29 +00:00
2006-03-20 16:43:15 +00:00
MALLOC ( grd_curscreen , grs_screen , 1 ) ;
memset ( grd_curscreen , 0 , sizeof ( grs_screen ) ) ;
grd_curscreen - > sc_canvas . cv_bitmap . bm_data = NULL ;
// Set the mode.
if ( ( retcode = gr_set_mode ( mode ) ) )
return retcode ;
2008-04-19 19:11:32 +00:00
2006-03-20 16:43:15 +00:00
grd_curscreen - > sc_canvas . cv_color = 0 ;
grd_curscreen - > sc_canvas . cv_drawmode = 0 ;
grd_curscreen - > sc_canvas . cv_font = NULL ;
grd_curscreen - > sc_canvas . cv_font_fg_color = 0 ;
grd_curscreen - > sc_canvas . cv_font_bg_color = 0 ;
gr_set_current_canvas ( & grd_curscreen - > sc_canvas ) ;
2007-01-09 01:23:49 +00:00
ogl_init_pixel_buffers ( 256 , 128 ) ; // for gamefont_init
2006-03-20 16:43:15 +00:00
gr_installed = 1 ;
2010-06-24 09:29:11 +00:00
2006-03-20 16:43:15 +00:00
return 0 ;
}
void gr_close ( )
{
2008-01-13 13:27:58 +00:00
ogl_brightness_r = ogl_brightness_g = ogl_brightness_b = 0 ;
2008-04-19 19:11:32 +00:00
if ( gl_initialized )
{
ogl_smash_texture_list_internal ( ) ;
SDL_ShowCursor ( 1 ) ;
}
if ( grd_curscreen )
{
2006-03-20 16:43:15 +00:00
if ( grd_curscreen - > sc_canvas . cv_bitmap . bm_data )
2008-01-23 17:25:09 +00:00
d_free ( grd_curscreen - > sc_canvas . cv_bitmap . bm_data ) ;
d_free ( grd_curscreen ) ;
2006-03-20 16:43:15 +00:00
}
2007-01-09 01:23:49 +00:00
ogl_close_pixel_buffers ( ) ;
2008-04-06 20:23:28 +00:00
# ifdef _WIN32
2006-03-20 16:43:15 +00:00
if ( ogl_rt_loaded )
OpenGL_LoadLibrary ( false ) ;
# endif
}
2007-06-10 16:21:53 +00:00
2006-03-20 16:43:15 +00:00
extern int r_upixelc ;
2008-04-19 19:11:32 +00:00
void ogl_upixelc ( int x , int y , int c )
{
2006-03-20 16:43:15 +00:00
r_upixelc + + ;
2006-09-08 23:31:06 +00:00
OGL_DISABLE ( TEXTURE_2D ) ;
2008-11-09 14:31:30 +00:00
glPointSize ( linedotscale ) ;
2006-09-08 23:31:06 +00:00
glBegin ( GL_POINTS ) ;
glColor3f ( CPAL2Tr ( c ) , CPAL2Tg ( c ) , CPAL2Tb ( c ) ) ;
2009-11-17 14:27:39 +00:00
glVertex2f ( ( x + grd_curcanv - > cv_bitmap . bm_x + 0.5 ) / ( float ) last_width , 1.0 - ( y + grd_curcanv - > cv_bitmap . bm_y + 0.5 ) / ( float ) last_height ) ;
2006-09-08 23:31:06 +00:00
glEnd ( ) ;
2006-03-20 16:43:15 +00:00
}
2006-09-08 23:31:06 +00:00
2008-04-19 19:11:32 +00:00
void ogl_urect ( int left , int top , int right , int bot )
{
2006-03-20 16:43:15 +00:00
GLfloat xo , yo , xf , yf ;
int c = COLOR ;
2010-06-24 09:29:11 +00:00
2006-03-20 16:43:15 +00:00
xo = ( left + grd_curcanv - > cv_bitmap . bm_x ) / ( float ) last_width ;
2006-09-08 23:31:06 +00:00
xf = ( right + 1 + grd_curcanv - > cv_bitmap . bm_x ) / ( float ) last_width ;
2006-03-20 16:43:15 +00:00
yo = 1.0 - ( top + grd_curcanv - > cv_bitmap . bm_y ) / ( float ) last_height ;
2006-09-08 23:31:06 +00:00
yf = 1.0 - ( bot + 1 + grd_curcanv - > cv_bitmap . bm_y ) / ( float ) last_height ;
2006-03-20 16:43:15 +00:00
OGL_DISABLE ( TEXTURE_2D ) ;
2006-09-08 23:31:06 +00:00
if ( Gr_scanline_darkening_level > = GR_FADE_LEVELS )
glColor3f ( CPAL2Tr ( c ) , CPAL2Tg ( c ) , CPAL2Tb ( c ) ) ;
else
glColor4f ( CPAL2Tr ( c ) , CPAL2Tg ( c ) , CPAL2Tb ( c ) , 1.0 - ( float ) Gr_scanline_darkening_level / ( ( float ) GR_FADE_LEVELS - 1.0 ) ) ;
2006-03-20 16:43:15 +00:00
glBegin ( GL_QUADS ) ;
glVertex2f ( xo , yo ) ;
glVertex2f ( xo , yf ) ;
glVertex2f ( xf , yf ) ;
glVertex2f ( xf , yo ) ;
glEnd ( ) ;
}
2006-09-08 23:31:06 +00:00
2008-04-19 19:11:32 +00:00
void ogl_ulinec ( int left , int top , int right , int bot , int c )
{
2006-03-20 16:43:15 +00:00
GLfloat xo , yo , xf , yf ;
2007-10-18 14:44:02 +00:00
xo = ( left + grd_curcanv - > cv_bitmap . bm_x + 0.5 ) / ( float ) last_width ;
xf = ( right + grd_curcanv - > cv_bitmap . bm_x + 0.5 ) / ( float ) last_width ;
yo = 1.0 - ( top + grd_curcanv - > cv_bitmap . bm_y + 0.5 ) / ( float ) last_height ;
yf = 1.0 - ( bot + grd_curcanv - > cv_bitmap . bm_y + 0.5 ) / ( float ) last_height ;
2006-03-20 16:43:15 +00:00
OGL_DISABLE ( TEXTURE_2D ) ;
glColor3f ( CPAL2Tr ( c ) , CPAL2Tg ( c ) , CPAL2Tb ( c ) ) ;
glBegin ( GL_LINES ) ;
glVertex2f ( xo , yo ) ;
glVertex2f ( xf , yf ) ;
glEnd ( ) ;
}
GLfloat last_r = 0 , last_g = 0 , last_b = 0 ;
int do_pal_step = 0 ;
2006-09-08 23:31:06 +00:00
2008-04-19 19:11:32 +00:00
void ogl_do_palfx ( void )
{
2006-03-20 16:43:15 +00:00
OGL_DISABLE ( TEXTURE_2D ) ;
2008-03-20 23:23:46 +00:00
2008-04-19 19:11:32 +00:00
if ( do_pal_step )
{
2008-03-20 23:23:46 +00:00
glEnable ( GL_BLEND ) ;
glBlendFunc ( GL_ONE , GL_ONE ) ;
glColor3f ( last_r , last_g , last_b ) ;
2008-04-19 19:11:32 +00:00
}
else
2008-03-20 23:23:46 +00:00
return ;
2007-06-10 16:21:53 +00:00
2006-03-20 16:43:15 +00:00
glBegin ( GL_QUADS ) ;
glVertex2f ( 0 , 0 ) ;
glVertex2f ( 0 , 1 ) ;
glVertex2f ( 1 , 1 ) ;
glVertex2f ( 1 , 0 ) ;
glEnd ( ) ;
2010-06-24 09:29:11 +00:00
glEnable ( GL_BLEND ) ;
2006-03-20 16:43:15 +00:00
glBlendFunc ( GL_SRC_ALPHA , GL_ONE_MINUS_SRC_ALPHA ) ;
}
2006-10-10 23:41:12 +00:00
int ogl_brightness_ok = 0 ;
int ogl_brightness_r = 0 , ogl_brightness_g = 0 , ogl_brightness_b = 0 ;
static int old_b_r = 0 , old_b_g = 0 , old_b_b = 0 ;
2006-03-20 16:43:15 +00:00
2009-11-17 14:27:39 +00:00
void gr_palette_step_up ( int r , int g , int b )
2006-03-20 16:43:15 +00:00
{
2006-10-10 23:41:12 +00:00
old_b_r = ogl_brightness_r ;
old_b_g = ogl_brightness_g ;
old_b_b = ogl_brightness_b ;
2006-03-20 16:43:15 +00:00
2006-10-10 23:41:12 +00:00
ogl_brightness_r = max ( r + gr_palette_gamma , 0 ) ;
ogl_brightness_g = max ( g + gr_palette_gamma , 0 ) ;
ogl_brightness_b = max ( b + gr_palette_gamma , 0 ) ;
2008-01-13 13:27:58 +00:00
if ( ! ogl_brightness_ok )
2006-10-10 23:41:12 +00:00
{
last_r = ogl_brightness_r / 63.0 ;
last_g = ogl_brightness_g / 63.0 ;
last_b = ogl_brightness_b / 63.0 ;
do_pal_step = ( r | | g | | b | | gr_palette_gamma ) ;
}
else
{
do_pal_step = 0 ;
}
2006-03-20 16:43:15 +00:00
}
# undef min
static inline int min ( int x , int y ) { return x < y ? x : y ; }
2008-04-19 19:11:32 +00:00
void gr_palette_load ( ubyte * pal )
2006-03-20 16:43:15 +00:00
{
2007-06-10 16:21:53 +00:00
int i ;
2009-11-17 14:27:39 +00:00
2008-04-19 19:11:32 +00:00
for ( i = 0 ; i < 768 ; i + + )
{
2006-09-08 23:31:06 +00:00
gr_current_pal [ i ] = pal [ i ] ;
2008-04-19 19:11:32 +00:00
if ( gr_current_pal [ i ] > 63 )
gr_current_pal [ i ] = 63 ;
2006-09-08 23:31:06 +00:00
}
2006-03-20 16:43:15 +00:00
2006-10-10 23:41:12 +00:00
gr_palette_step_up ( 0 , 0 , 0 ) ; // make ogl_setbrightness_internal get run so that menus get brightened too.
2006-09-08 23:31:06 +00:00
init_computed_colors ( ) ;
2006-03-20 16:43:15 +00:00
}
void gr_palette_read ( ubyte * pal )
{
int i ;
2008-04-19 19:11:32 +00:00
for ( i = 0 ; i < 768 ; i + + )
{
2006-03-20 16:43:15 +00:00
pal [ i ] = gr_current_pal [ i ] ;
2008-04-19 19:11:32 +00:00
if ( pal [ i ] > 63 )
pal [ i ] = 63 ;
2006-03-20 16:43:15 +00:00
}
}
# define GL_BGR_EXT 0x80E0
2008-04-19 19:11:32 +00:00
typedef struct
{
2006-03-20 16:43:15 +00:00
unsigned char TGAheader [ 12 ] ;
unsigned char header [ 6 ] ;
} TGA_header ;
//writes out an uncompressed RGB .tga file
//if we got really spiffy, we could optionally link in libpng or something, and use that.
2008-04-19 19:11:32 +00:00
void write_bmp ( char * savename , int w , int h , unsigned char * buf )
{
2008-01-23 17:25:09 +00:00
PHYSFS_file * TGAFile ;
2006-03-20 16:43:15 +00:00
TGA_header TGA ;
GLbyte HeightH , HeightL , WidthH , WidthL ;
2008-02-24 14:41:27 +00:00
buf = ( unsigned char * ) d_calloc ( w * h * 3 , sizeof ( unsigned char ) ) ;
2006-03-20 16:43:15 +00:00
glReadPixels ( 0 , 0 , w , h , GL_BGR_EXT , GL_UNSIGNED_BYTE , buf ) ;
2009-01-16 00:12:04 +00:00
if ( ! ( TGAFile = PHYSFSX_openWriteBuffered ( savename ) ) )
{
con_printf ( CON_URGENT , " Could not create TGA file to dump screenshot! " ) ;
d_free ( buf ) ;
2009-01-17 11:02:59 +00:00
return ;
2009-01-16 00:12:04 +00:00
}
2006-03-20 16:43:15 +00:00
HeightH = ( GLbyte ) ( h / 256 ) ;
HeightL = ( GLbyte ) ( h % 256 ) ;
WidthH = ( GLbyte ) ( w / 256 ) ;
WidthL = ( GLbyte ) ( w % 256 ) ;
// Write TGA Header
TGA . TGAheader [ 0 ] = 0 ;
TGA . TGAheader [ 1 ] = 0 ;
TGA . TGAheader [ 2 ] = 2 ;
TGA . TGAheader [ 3 ] = 0 ;
TGA . TGAheader [ 4 ] = 0 ;
TGA . TGAheader [ 5 ] = 0 ;
TGA . TGAheader [ 6 ] = 0 ;
TGA . TGAheader [ 7 ] = 0 ;
TGA . TGAheader [ 8 ] = 0 ;
TGA . TGAheader [ 9 ] = 0 ;
TGA . TGAheader [ 10 ] = 0 ;
TGA . TGAheader [ 11 ] = 0 ;
TGA . header [ 0 ] = ( GLbyte ) WidthL ;
TGA . header [ 1 ] = ( GLbyte ) WidthH ;
TGA . header [ 2 ] = ( GLbyte ) HeightL ;
TGA . header [ 3 ] = ( GLbyte ) HeightH ;
TGA . header [ 4 ] = ( GLbyte ) 24 ;
TGA . header [ 5 ] = 0 ;
2008-01-23 17:25:09 +00:00
PHYSFS_write ( TGAFile , & TGA , sizeof ( TGA_header ) , 1 ) ;
PHYSFS_write ( TGAFile , buf , w * h * 3 * sizeof ( unsigned char ) , 1 ) ;
PHYSFS_close ( TGAFile ) ;
d_free ( buf ) ;
2006-03-20 16:43:15 +00:00
}
void save_screen_shot ( int automap_flag )
{
char message [ 100 ] ;
static int savenum = 0 ;
2007-01-25 09:56:05 +00:00
char savename [ 13 + sizeof ( SCRNS_DIR ) ] ;
2006-03-20 16:43:15 +00:00
unsigned char * buf ;
2010-06-24 09:29:11 +00:00
2008-05-21 13:58:27 +00:00
if ( ! GameArg . DbgGlReadPixelsOk ) {
2006-03-20 16:43:15 +00:00
if ( ! automap_flag )
2010-07-13 06:35:25 +00:00
HUD_init_message ( HM_DEFAULT , " glReadPixels not supported on your configuration " ) ;
2006-03-20 16:43:15 +00:00
return ;
}
stop_time ( ) ;
2007-01-25 09:56:05 +00:00
if ( ! cfexist ( SCRNS_DIR ) )
2008-01-23 17:25:09 +00:00
PHYSFS_mkdir ( SCRNS_DIR ) ; //try making directory
2007-01-25 09:56:05 +00:00
2008-01-23 17:25:09 +00:00
do
2006-03-20 16:43:15 +00:00
{
2008-01-23 17:25:09 +00:00
sprintf ( savename , " %sscrn%04d.tga " , SCRNS_DIR , savenum + + ) ;
} while ( PHYSFS_exists ( savename ) ) ;
2008-05-21 13:58:27 +00:00
sprintf ( message , " %s 'scrn%04d.tga' " , TXT_DUMPING_SCREEN , savenum - 1 ) ;
2006-03-20 16:43:15 +00:00
2008-01-23 17:25:09 +00:00
if ( ! automap_flag )
2010-07-13 06:35:25 +00:00
HUD_init_message ( HM_DEFAULT , message ) ;
2007-10-18 14:44:02 +00:00
2008-10-28 17:04:35 +00:00
glReadBuffer ( GL_FRONT ) ;
2008-05-21 21:59:16 +00:00
2008-01-23 17:25:09 +00:00
buf = d_malloc ( grd_curscreen - > sc_w * grd_curscreen - > sc_h * 3 ) ;
2006-03-20 16:43:15 +00:00
write_bmp ( savename , grd_curscreen - > sc_w , grd_curscreen - > sc_h , buf ) ;
2008-01-23 17:25:09 +00:00
d_free ( buf ) ;
2006-03-20 16:43:15 +00:00
key_flush ( ) ;
start_time ( ) ;
2006-09-08 23:31:06 +00:00
}