2018-04-12 21:02:51 +00:00
// SDL interface layer for the Build Engine
2013-10-06 07:49:53 +00:00
// Use SDL 1.2 or 2.0 from http://www.libsdl.org
2006-04-13 20:47:06 +00:00
2019-09-21 21:45:57 +00:00
# include <Windows.h>
2019-09-22 21:15:46 +00:00
# include <CommCtrl.h>
2009-08-03 22:15:53 +00:00
# include <signal.h>
2019-10-03 22:26:13 +00:00
# include <string>
2019-10-23 23:20:58 +00:00
# include <stdexcept>
2019-10-05 11:57:26 +00:00
# include "glad / glad.h"
2018-11-18 18:09:48 +00:00
2006-04-13 20:47:06 +00:00
# include "a.h"
# include "build.h"
2018-11-18 18:09:48 +00:00
# include "cache1d.h"
2019-09-19 21:02:57 +00:00
# include "common.h"
2018-11-18 18:09:48 +00:00
# include "compat.h"
2015-01-11 04:52:15 +00:00
# include "engine_priv.h"
2018-11-18 18:09:48 +00:00
# include "osd.h"
2016-06-21 00:33:06 +00:00
# include "palette.h"
2018-11-18 18:09:48 +00:00
# include "renderlayer.h"
# include "sdl_inc.h"
2018-07-14 21:36:44 +00:00
# include "softsurface.h"
2019-09-23 17:29:25 +00:00
# include "m_argv.h"
2019-09-25 21:00:10 +00:00
# include "mmulti.h"
2019-10-03 22:26:13 +00:00
# include "scriptfile.h"
# include "zstring.h"
2019-10-26 11:16:32 +00:00
# include "gameconfigfile.h"
# include "gamecontrol.h"
# include "resourcefile.h"
# include "sc_man.h"
2019-10-26 11:41:42 +00:00
# include "i_specialpaths.h"
2019-09-23 21:33:59 +00:00
# include "../../glbackend/glbackend.h"
2018-11-18 18:09:48 +00:00
2006-04-13 20:47:06 +00:00
# ifdef USE_OPENGL
# include "glbuild.h"
2018-06-13 19:15:16 +00:00
# include "glsurface.h"
2006-04-13 20:47:06 +00:00
# endif
2014-07-22 11:19:45 +00:00
# if defined HAVE_GTK2
2006-04-13 20:47:06 +00:00
# include "gtkbits.h"
2014-07-22 11:19:45 +00:00
# endif
2018-11-18 18:09:48 +00:00
2019-09-10 17:06:20 +00:00
# if defined __APPLE__
2018-11-18 18:09:48 +00:00
# include "osxbits.h"
# include <mach / mach.h>
# include <mach / mach_time.h>
# elif defined _WIN32
2019-09-25 20:38:47 +00:00
# include "win32 / winbits.h"
2014-12-17 13:01:13 +00:00
# endif
2011-07-20 23:04:20 +00:00
2019-03-01 08:51:50 +00:00
# include "vfs.h"
2016-12-26 06:01:44 +00:00
# if SDL_MAJOR_VERSION != 1
2016-10-20 06:26:17 +00:00
static SDL_version linked ;
2016-12-26 06:01:44 +00:00
# endif
2016-10-20 06:26:17 +00:00
2019-09-21 20:53:00 +00:00
GameInterface * gi ;
2019-09-23 17:29:25 +00:00
FArgs * Args ;
2019-09-21 20:53:00 +00:00
2014-10-20 07:37:29 +00:00
# if !defined STARTUP_SETUP_WINDOW
2009-01-09 09:29:17 +00:00
int32_t startwin_open ( void ) { return 0 ; }
int32_t startwin_close ( void ) { return 0 ; }
2011-12-09 19:08:29 +00:00
int32_t startwin_puts ( const char * s ) { UNREFERENCED_PARAMETER ( s ) ; return 0 ; }
int32_t startwin_idle ( void * s ) { UNREFERENCED_PARAMETER ( s ) ; return 0 ; }
int32_t startwin_settitle ( const char * s ) { UNREFERENCED_PARAMETER ( s ) ; return 0 ; }
2014-11-26 04:39:23 +00:00
int32_t startwin_run ( void ) { return 0 ; }
2019-09-21 20:53:00 +00:00
# else
int32_t startwin_open ( void ) { return gi - > startwin_open ( ) ; }
int32_t startwin_close ( void ) { return gi - > startwin_close ( ) ; }
int32_t startwin_puts ( const char * s ) { return gi - > startwin_puts ( s ) ; }
int32_t startwin_idle ( void * s ) { return gi - > startwin_idle ( s ) ; }
int32_t startwin_settitle ( const char * s ) { return gi - > startwin_settitle ( s ) ; }
int32_t startwin_run ( void ) { return gi - > startwin_run ( ) ; }
2006-04-13 20:47:06 +00:00
# endif
2019-09-25 21:00:10 +00:00
int myconnectindex , numplayers ;
int connecthead , connectpoint2 [ MAXMULTIPLAYERS ] ;
unsigned char syncstate ;
2010-05-18 05:14:17 +00:00
/// These can be useful for debugging sometimes...
//#define SDL_WM_GrabInput(x) SDL_WM_GrabInput(SDL_GRAB_OFF)
//#define SDL_ShowCursor(x) SDL_ShowCursor(SDL_ENABLE)
2006-04-13 20:47:06 +00:00
# define SURFACE_FLAGS (SDL_SWSURFACE|SDL_HWPALETTE|SDL_HWACCEL)
// undefine to restrict windowed resolutions to conventional sizes
# define ANY_WINDOWED_SIZE
2006-08-07 06:18:57 +00:00
// fix for mousewheel
2013-12-20 07:24:09 +00:00
int32_t inputchecked = 0 ;
2006-08-07 06:18:57 +00:00
2011-01-16 02:50:27 +00:00
char quitevent = 0 , appactive = 1 , novideo = 0 ;
2006-04-13 20:47:06 +00:00
// video
2013-10-08 09:59:59 +00:00
static SDL_Surface * sdl_surface /*=NULL*/ ;
2014-04-12 08:45:26 +00:00
Add prototypical SDL 2.X support.
Doesn't work: indexed-color modes, gamma (at least for X11), mouse wheel,
special keys like ENTER or BACKSPACE in the OSD, probably more...
In build/Makefile.shared, we now have logic to autodetect an SDL2 installed
in /usr/local, however OS X and Wii builds follow other Makefile code paths,
it seems. Note that the matching SDL2_mixer must be used then, too.
In source/jaudiolib/src/driver_sdl.c, change the #includes from <SDL/SDL_xxx.h>
to "SDL_xxx.h". SDL wiki says this is the most portable way, hopefully this
doesn't break builds for anyone.
git-svn-id: https://svn.eduke32.com/eduke32@2777 1a8010ca-5511-0410-912e-c29ae57300e0
2012-06-22 21:39:53 +00:00
# if SDL_MAJOR_VERSION==2
2013-10-08 09:59:59 +00:00
static SDL_Window * sdl_window = NULL ;
static SDL_GLContext sdl_context = NULL ;
Add prototypical SDL 2.X support.
Doesn't work: indexed-color modes, gamma (at least for X11), mouse wheel,
special keys like ENTER or BACKSPACE in the OSD, probably more...
In build/Makefile.shared, we now have logic to autodetect an SDL2 installed
in /usr/local, however OS X and Wii builds follow other Makefile code paths,
it seems. Note that the matching SDL2_mixer must be used then, too.
In source/jaudiolib/src/driver_sdl.c, change the #includes from <SDL/SDL_xxx.h>
to "SDL_xxx.h". SDL wiki says this is the most portable way, hopefully this
doesn't break builds for anyone.
git-svn-id: https://svn.eduke32.com/eduke32@2777 1a8010ca-5511-0410-912e-c29ae57300e0
2012-06-22 21:39:53 +00:00
# endif
2014-04-12 08:45:26 +00:00
2019-08-27 13:39:54 +00:00
int32_t xres = - 1 , yres = - 1 , bpp = 0 , fullscreen = 0 , bytesperline , refreshfreq = - 1 ;
2008-02-16 22:27:08 +00:00
intptr_t frameplace = 0 ;
2009-01-09 09:29:17 +00:00
int32_t lockcount = 0 ;
2006-04-13 20:47:06 +00:00
char modechange = 1 ;
char offscreenrendering = 0 ;
char videomodereset = 0 ;
2009-01-09 09:29:17 +00:00
static uint16_t sysgamma [ 3 ] [ 256 ] ;
2006-04-13 20:47:06 +00:00
# ifdef USE_OPENGL
// OpenGL stuff
2008-08-26 19:50:34 +00:00
char nogl = 0 ;
2013-10-13 09:08:31 +00:00
# endif
2016-12-26 06:01:48 +00:00
static int32_t vsync_renderlayer ;
2016-02-13 21:06:12 +00:00
int32_t maxrefreshfreq = 0 ;
2006-04-13 20:47:06 +00:00
2011-12-28 20:34:57 +00:00
// last gamma, contrast, brightness
2011-11-25 09:50:07 +00:00
//#define KEY_PRINT_DEBUG
2017-02-01 10:20:54 +00:00
# include "sdlkeytrans.cpp"
2006-04-13 20:47:06 +00:00
2011-01-16 02:50:27 +00:00
static SDL_Surface * appicon = NULL ;
2014-12-27 18:36:14 +00:00
# if !defined __APPLE__ && !defined EDUKE32_TOUCH_DEVICES
2011-01-16 02:50:27 +00:00
static SDL_Surface * loadappicon ( void ) ;
2014-10-16 21:03:24 +00:00
# endif
2006-04-13 20:47:06 +00:00
2010-06-22 21:50:01 +00:00
static mutex_t m_initprintf ;
2010-10-21 02:20:40 +00:00
// Joystick dead and saturation zones
2019-08-13 09:15:49 +00:00
uint16_t joydead [ 9 ] , joysatur [ 9 ] ;
2010-10-21 02:20:40 +00:00
2019-10-23 23:20:58 +00:00
# define MAX_ERRORTEXT 4096
//==========================================================================
//
// I_Error
//
// Throw an error that will send us to the console if we are far enough
// along in the startup process.
//
//==========================================================================
void I_Error ( const char * error , . . . )
{
va_list argptr ;
char errortext [ MAX_ERRORTEXT ] ;
va_start ( argptr , error ) ;
snprintf ( errortext , MAX_ERRORTEXT , error , argptr ) ;
va_end ( argptr ) ;
# ifdef _WIN32
OutputDebugStringA ( errortext ) ;
# endif
throw std : : runtime_error ( errortext ) ;
}
2012-11-24 09:13:29 +00:00
# ifdef _WIN32
2014-11-29 03:07:33 +00:00
# if SDL_MAJOR_VERSION != 1
2012-11-24 09:13:29 +00:00
//
2013-10-07 10:05:03 +00:00
// win_gethwnd() -- gets the window handle
//
HWND win_gethwnd ( void )
{
struct SDL_SysWMinfo wmInfo ;
SDL_VERSION ( & wmInfo . version ) ;
2014-04-12 08:45:26 +00:00
if ( SDL_GetWindowWMInfo ( sdl_window , & wmInfo ) ! = SDL_TRUE )
return 0 ;
2013-10-07 10:05:03 +00:00
if ( wmInfo . subsystem = = SDL_SYSWM_WINDOWS )
return wmInfo . info . win . window ;
initprintf ( " win_gethwnd: Unknown WM subsystem?! \n " ) ;
return 0 ;
}
2014-11-29 03:07:33 +00:00
# endif
2013-10-07 10:05:03 +00:00
//
2012-11-24 09:13:29 +00:00
// win_gethinstance() -- gets the application instance
//
Win64 support! (Meaning it works, not that we recommend it for everyday use.)
This includes a complete Windows header and library refresh, including the addition of 64-bit compiled libs:
*libogg 1.3.0
*libvorbis 1.3.3
*zlib 1.2.7
*libpng 1.5.13
*libvpx 9a3de881c0e681ba1a79a166a86308bbc84b4acd
*SDL_mixer 1.2.12 (for RENDERTYPE=SDL)
*DirectX import libraries: dsound and dxguid (now included)
To build in 64-bit, you essentially need MinGW's MSYS (but not MinGW itself) and MinGW-w64 at the top of your PATH. The target is automatically detected using `$(CC) -dumpmachine`. The EDukeWiki will get detailed instrucitons.
All compiler and linker warnings when building in 64-bit mode have been fixed.
Remaining 64-bit to-do:
- The ebacktrace dll does not build under 64-bit. It uses code specific to the format of 32-bit executables and will have to be ported to work with 64-bit executables. A future 64-bit version will be named ebacktrace1-64.dll.
- RENDERTYPE=SDL crashes in SDL_mixer's Mix_Linked_Version().
- DirectInput gives an error and does not function. This only affects joysticks, and the error never happens without any plugged in.
- Port the classic renderer ASM to 64-bit. (Just kidding, this is way out of my league.)
This commit includes a fair bit of Makefile development spanning all platforms, including simplifying the SDLCONFIG code, fixing build on Mac OS X (thanks rhoenie!), globally factoring Apple brew/port inclusion, enforcing that all -L come before all -l, and ensuring that $(shell ) is always :='d.
In addition, I have resurrected the old GCC_MAJOR and GCC_MINOR detection using `$(CC) -dumpversion`, but I have made it failsafe in case the command fails or the version is manually specified. I have applied this new fine-grained detection where applicable, including allowing LTO, and restraining -W's to versions that support them.
git-svn-id: https://svn.eduke32.com/eduke32@3278 1a8010ca-5511-0410-912e-c29ae57300e0
2012-12-13 02:37:20 +00:00
HINSTANCE win_gethinstance ( void )
2012-11-24 09:13:29 +00:00
{
Win64 support! (Meaning it works, not that we recommend it for everyday use.)
This includes a complete Windows header and library refresh, including the addition of 64-bit compiled libs:
*libogg 1.3.0
*libvorbis 1.3.3
*zlib 1.2.7
*libpng 1.5.13
*libvpx 9a3de881c0e681ba1a79a166a86308bbc84b4acd
*SDL_mixer 1.2.12 (for RENDERTYPE=SDL)
*DirectX import libraries: dsound and dxguid (now included)
To build in 64-bit, you essentially need MinGW's MSYS (but not MinGW itself) and MinGW-w64 at the top of your PATH. The target is automatically detected using `$(CC) -dumpmachine`. The EDukeWiki will get detailed instrucitons.
All compiler and linker warnings when building in 64-bit mode have been fixed.
Remaining 64-bit to-do:
- The ebacktrace dll does not build under 64-bit. It uses code specific to the format of 32-bit executables and will have to be ported to work with 64-bit executables. A future 64-bit version will be named ebacktrace1-64.dll.
- RENDERTYPE=SDL crashes in SDL_mixer's Mix_Linked_Version().
- DirectInput gives an error and does not function. This only affects joysticks, and the error never happens without any plugged in.
- Port the classic renderer ASM to 64-bit. (Just kidding, this is way out of my league.)
This commit includes a fair bit of Makefile development spanning all platforms, including simplifying the SDLCONFIG code, fixing build on Mac OS X (thanks rhoenie!), globally factoring Apple brew/port inclusion, enforcing that all -L come before all -l, and ensuring that $(shell ) is always :='d.
In addition, I have resurrected the old GCC_MAJOR and GCC_MINOR detection using `$(CC) -dumpversion`, but I have made it failsafe in case the command fails or the version is manually specified. I have applied this new fine-grained detection where applicable, including allowing LTO, and restraining -W's to versions that support them.
git-svn-id: https://svn.eduke32.com/eduke32@3278 1a8010ca-5511-0410-912e-c29ae57300e0
2012-12-13 02:37:20 +00:00
return ( HINSTANCE ) GetModuleHandle ( NULL ) ;
2012-11-24 09:13:29 +00:00
}
# endif
2014-05-17 12:35:03 +00:00
2014-07-28 06:43:16 +00:00
int32_t wm_msgbox ( const char * name , const char * fmt , . . . )
2006-04-13 20:47:06 +00:00
{
2006-09-21 20:10:51 +00:00
char buf [ 2048 ] ;
2006-04-24 19:04:22 +00:00
va_list va ;
2006-04-13 20:47:06 +00:00
2008-03-25 09:21:18 +00:00
UNREFERENCED_PARAMETER ( name ) ;
2006-04-24 19:04:22 +00:00
va_start ( va , fmt ) ;
2013-10-27 21:12:25 +00:00
vsnprintf ( buf , sizeof ( buf ) , fmt , va ) ;
2006-04-24 19:04:22 +00:00
va_end ( va ) ;
2006-04-13 20:47:06 +00:00
2015-01-25 12:16:10 +00:00
# if defined EDUKE32_OSX
2006-04-24 19:04:22 +00:00
return osx_msgbox ( name , buf ) ;
2014-01-12 14:06:15 +00:00
# elif defined _WIN32
2019-09-22 21:15:46 +00:00
MessageBoxA ( win_gethwnd ( ) , buf , name , MB_OK | MB_TASKMODAL ) ;
2014-01-12 14:06:15 +00:00
return 0 ;
2014-12-27 18:36:14 +00:00
# elif defined EDUKE32_TOUCH_DEVICES
2014-04-15 19:02:48 +00:00
initprintf ( " wm_msgbox called. Message: %s: %s " , name , buf ) ;
return 0 ;
2014-12-18 18:15:26 +00:00
# elif defined GEKKO
puts ( buf ) ;
return 0 ;
2016-12-26 06:02:06 +00:00
# else
2016-12-29 02:57:33 +00:00
# if defined HAVE_GTK2
if ( gtkbuild_msgbox ( name , buf ) > = 0 )
return 0 ;
# endif
# if SDL_MAJOR_VERSION > 1
# if !defined _WIN32
// Replace all tab chars with spaces because the hand-rolled SDL message
// box diplays the former as N/L instead of whitespace.
for ( size_t i = 0 ; i < sizeof ( buf ) ; i + + )
if ( buf [ i ] = = ' \t ' )
buf [ i ] = ' ' ;
# endif
return SDL_ShowSimpleMessageBox ( SDL_MESSAGEBOX_INFORMATION , name , buf , NULL ) ;
# else
2006-04-24 19:04:22 +00:00
puts ( buf ) ;
puts ( " (press Return or Enter to continue) " ) ;
getchar ( ) ;
2006-04-13 20:47:06 +00:00
2006-04-24 19:04:22 +00:00
return 0 ;
2016-12-29 02:57:33 +00:00
# endif
2016-12-26 06:02:06 +00:00
# endif
2006-04-13 20:47:06 +00:00
}
2014-07-28 06:43:16 +00:00
int32_t wm_ynbox ( const char * name , const char * fmt , . . . )
2006-04-13 20:47:06 +00:00
{
2006-09-21 20:10:51 +00:00
char buf [ 2048 ] ;
2006-04-24 19:04:22 +00:00
va_list va ;
2008-03-25 09:21:18 +00:00
UNREFERENCED_PARAMETER ( name ) ;
2006-04-13 20:47:06 +00:00
2006-04-24 19:04:22 +00:00
va_start ( va , fmt ) ;
2016-12-29 02:57:33 +00:00
vsnprintf ( buf , sizeof ( buf ) , fmt , va ) ;
2006-04-24 19:04:22 +00:00
va_end ( va ) ;
2006-04-13 20:47:06 +00:00
2015-01-25 12:16:10 +00:00
# if defined EDUKE32_OSX
2006-04-24 19:04:22 +00:00
return osx_ynbox ( name , buf ) ;
2014-01-12 14:06:15 +00:00
# elif defined _WIN32
2019-09-22 21:15:46 +00:00
return ( MessageBoxA ( win_gethwnd ( ) , buf , name , MB_YESNO | MB_ICONQUESTION | MB_TASKMODAL ) = = IDYES ) ;
2014-12-27 18:36:14 +00:00
# elif defined EDUKE32_TOUCH_DEVICES
2014-04-15 19:02:48 +00:00
initprintf ( " wm_ynbox called, this is bad! Message: %s: %s " , name , buf ) ;
initprintf ( " Returning false.. " ) ;
return 0 ;
2016-12-29 02:57:33 +00:00
# elif defined GEKKO
puts ( buf ) ;
puts ( " Assuming yes... " ) ;
return 1 ;
2014-11-22 12:33:47 +00:00
# else
2016-12-29 02:57:33 +00:00
# if defined HAVE_GTK2
int ret = gtkbuild_ynbox ( name , buf ) ;
if ( ret > = 0 )
return ret ;
# endif
# if SDL_MAJOR_VERSION > 1
int r = - 1 ;
const SDL_MessageBoxButtonData buttons [ ] = {
{
SDL_MESSAGEBOX_BUTTON_ESCAPEKEY_DEFAULT ,
0 ,
" No "
} , {
SDL_MESSAGEBOX_BUTTON_RETURNKEY_DEFAULT ,
1 ,
" Yes "
} ,
} ;
SDL_MessageBoxData data = {
SDL_MESSAGEBOX_INFORMATION ,
NULL , /* no parent window */
name ,
buf ,
2 ,
buttons ,
NULL /* Default color scheme */
} ;
SDL_ShowMessageBox ( & data , & r ) ;
return r ;
# else
char c ;
puts ( buf ) ;
puts ( " (type 'Y' or 'N', and press Return or Enter to continue) " ) ;
do c = getchar ( ) ; while ( c ! = ' Y ' & & c ! = ' y ' & & c ! = ' N ' & & c ! = ' n ' ) ;
return c = = ' Y ' | | c = = ' y ' ;
# endif
2006-04-13 20:47:06 +00:00
# endif
}
2014-07-28 06:43:16 +00:00
void wm_setapptitle ( const char * name )
2006-04-13 20:47:06 +00:00
{
2014-12-27 18:36:14 +00:00
# ifndef EDUKE32_TOUCH_DEVICES
2014-11-22 12:33:47 +00:00
if ( name ! = apptitle )
2012-03-28 19:43:21 +00:00
Bstrncpyz ( apptitle , name , sizeof ( apptitle ) ) ;
2006-04-13 20:47:06 +00:00
2014-11-22 12:33:47 +00:00
# if !defined(__APPLE__)
2014-11-29 03:07:33 +00:00
if ( ! appicon )
appicon = loadappicon ( ) ;
2014-11-22 12:33:47 +00:00
# endif
Add prototypical SDL 2.X support.
Doesn't work: indexed-color modes, gamma (at least for X11), mouse wheel,
special keys like ENTER or BACKSPACE in the OSD, probably more...
In build/Makefile.shared, we now have logic to autodetect an SDL2 installed
in /usr/local, however OS X and Wii builds follow other Makefile code paths,
it seems. Note that the matching SDL2_mixer must be used then, too.
In source/jaudiolib/src/driver_sdl.c, change the #includes from <SDL/SDL_xxx.h>
to "SDL_xxx.h". SDL wiki says this is the most portable way, hopefully this
doesn't break builds for anyone.
git-svn-id: https://svn.eduke32.com/eduke32@2777 1a8010ca-5511-0410-912e-c29ae57300e0
2012-06-22 21:39:53 +00:00
# if SDL_MAJOR_VERSION == 1
2006-04-24 19:04:22 +00:00
SDL_WM_SetCaption ( apptitle , NULL ) ;
2014-11-22 12:33:47 +00:00
2014-11-29 03:07:33 +00:00
if ( appicon & & sdl_surface )
2014-11-22 12:33:47 +00:00
SDL_WM_SetIcon ( appicon , 0 ) ;
Add prototypical SDL 2.X support.
Doesn't work: indexed-color modes, gamma (at least for X11), mouse wheel,
special keys like ENTER or BACKSPACE in the OSD, probably more...
In build/Makefile.shared, we now have logic to autodetect an SDL2 installed
in /usr/local, however OS X and Wii builds follow other Makefile code paths,
it seems. Note that the matching SDL2_mixer must be used then, too.
In source/jaudiolib/src/driver_sdl.c, change the #includes from <SDL/SDL_xxx.h>
to "SDL_xxx.h". SDL wiki says this is the most portable way, hopefully this
doesn't break builds for anyone.
git-svn-id: https://svn.eduke32.com/eduke32@2777 1a8010ca-5511-0410-912e-c29ae57300e0
2012-06-22 21:39:53 +00:00
# else
2016-10-20 06:26:20 +00:00
if ( sdl_window )
{
SDL_SetWindowTitle ( sdl_window , apptitle ) ;
2014-11-22 12:33:47 +00:00
2016-10-20 06:26:20 +00:00
if ( appicon )
{
# if defined _WIN32
if ( ! EDUKE32_SDL_LINKED_PREREQ ( linked , 2 , 0 , 5 ) )
# endif
SDL_SetWindowIcon ( sdl_window , appicon ) ;
}
}
Add prototypical SDL 2.X support.
Doesn't work: indexed-color modes, gamma (at least for X11), mouse wheel,
special keys like ENTER or BACKSPACE in the OSD, probably more...
In build/Makefile.shared, we now have logic to autodetect an SDL2 installed
in /usr/local, however OS X and Wii builds follow other Makefile code paths,
it seems. Note that the matching SDL2_mixer must be used then, too.
In source/jaudiolib/src/driver_sdl.c, change the #includes from <SDL/SDL_xxx.h>
to "SDL_xxx.h". SDL wiki says this is the most portable way, hopefully this
doesn't break builds for anyone.
git-svn-id: https://svn.eduke32.com/eduke32@2777 1a8010ca-5511-0410-912e-c29ae57300e0
2012-06-22 21:39:53 +00:00
# endif
2006-04-13 20:47:06 +00:00
2006-07-01 01:40:18 +00:00
startwin_settitle ( apptitle ) ;
2014-12-27 18:36:14 +00:00
# else
UNREFERENCED_PARAMETER ( name ) ;
2014-11-22 12:33:47 +00:00
# endif
2006-04-13 20:47:06 +00:00
}
//
//
// ---------------------------------------
//
// System
//
// ---------------------------------------
//
//
2014-11-22 12:33:47 +00:00
/* XXX: libexecinfo could be used on systems without gnu libc. */
2014-12-27 18:36:14 +00:00
# if !defined _WIN32 && defined __GNUC__ && !defined __OpenBSD__ && !(defined __APPLE__ && defined __BIG_ENDIAN__) && !defined GEKKO && !defined EDUKE32_TOUCH_DEVICES && !defined __OPENDINGUX__
2014-11-22 12:33:47 +00:00
# define PRINTSTACKONSEGV 1
# include <execinfo.h>
# endif
static inline char grabmouse_low ( char a ) ;
2016-03-28 05:15:32 +00:00
# ifndef __ANDROID__
static void attach_debugger_here ( void ) { }
2014-11-22 12:33:47 +00:00
static void sighandler ( int signum )
{
UNREFERENCED_PARAMETER ( signum ) ;
// if (signum==SIGSEGV)
{
grabmouse_low ( 0 ) ;
# if PRINTSTACKONSEGV
{
void * addr [ 32 ] ;
int32_t errfd = fileno ( stderr ) ;
int32_t n = backtrace ( addr , ARRAY_SIZE ( addr ) ) ;
backtrace_symbols_fd ( addr , n , errfd ) ;
}
// This is useful for attaching the debugger post-mortem. For those pesky
// cases where the program runs through happily when inspected from the start.
// usleep(15000000);
2014-07-28 06:42:28 +00:00
# endif
2014-11-22 12:33:47 +00:00
attach_debugger_here ( ) ;
2019-09-21 20:53:00 +00:00
gi - > app_crashhandler ( ) ;
2014-11-22 12:33:47 +00:00
uninitsystem ( ) ;
2019-10-19 23:45:24 +00:00
Bexit ( EXIT_FAILURE ) ;
2014-11-22 12:33:47 +00:00
}
}
2016-03-28 05:15:32 +00:00
# endif
2014-07-28 06:42:28 +00:00
2016-05-02 18:29:38 +00:00
2015-02-11 05:21:50 +00:00
# ifdef _WIN32
2019-09-21 21:45:57 +00:00
2019-10-19 23:14:48 +00:00
FString currentGame ; // Currently there is no global state for the current game. This is a temporary workaround because the video init code needs to do a few things based on the active game.
2019-09-21 21:45:57 +00:00
namespace Duke
{
extern GameInterface Interface ;
}
2019-09-22 21:15:46 +00:00
namespace Redneck
{
extern GameInterface Interface ;
}
namespace Blood
{
extern GameInterface Interface ;
}
2019-10-09 18:14:04 +00:00
namespace ShadowWarrior
{
extern GameInterface Interface ;
}
2019-09-21 21:45:57 +00:00
2019-10-03 22:26:13 +00:00
GameInterface * CheckFrontend ( )
{
FILE * f = fopen ( " blood.rff " , " rb " ) ;
if ( f )
{
2019-10-19 23:14:48 +00:00
currentGame = " Blood " ;
2019-10-03 22:26:13 +00:00
fclose ( f ) ;
return & Blood : : Interface ;
}
else
{
f = fopen ( " redneck.grp " , " rb " ) ;
if ( f )
{
2019-10-22 21:31:46 +00:00
currentGame = " Redneck " ;
fseek ( f , 0 , SEEK_END ) ;
auto pos = ftell ( f ) ;
// Quick hack to distinguish these two. This won't survive until production but for testing it's sufficient.
if ( pos > 190'000'000 ) currentGame = " RedneckRides " ;
2019-10-03 22:26:13 +00:00
fclose ( f ) ;
return & Redneck : : Interface ;
}
else
2019-10-09 18:14:04 +00:00
{
f = fopen ( " sw.grp " , " rb " ) ;
2019-10-19 23:14:48 +00:00
if ( f )
{
currentGame = " ShadowWarrior " ;
fclose ( f ) ;
return & ShadowWarrior : : Interface ;
}
f = fopen ( " fury.grp " , " rb " ) ;
if ( f )
{
2019-10-22 21:31:46 +00:00
currentGame = " IonFury " ;
2019-10-19 23:14:48 +00:00
fclose ( f ) ;
2019-10-22 21:31:46 +00:00
return & Duke : : Interface ;
}
f = fopen ( " nam.grp " , " rb " ) ;
if ( f )
{
currentGame = " Nam " ;
fclose ( f ) ;
return & Duke : : Interface ;
}
f = fopen ( " ww2gi.grp " , " rb " ) ;
if ( f )
{
currentGame = " WW2GI " ;
fclose ( f ) ;
return & Duke : : Interface ;
}
else
{
currentGame = " Duke " ;
2019-10-19 23:14:48 +00:00
}
2019-10-03 22:26:13 +00:00
return & Duke : : Interface ;
2019-10-09 18:14:04 +00:00
}
2019-10-03 22:26:13 +00:00
}
}
2019-09-21 21:45:57 +00:00
void ChooseGame ( )
{
2019-10-03 22:26:13 +00:00
auto dir = Args - > CheckValue ( " -game " ) ;
if ( dir & & ! chdir ( dir ) )
{
gi = CheckFrontend ( ) ;
return ;
}
TArray < FString > paths ;
std : : vector < std : : wstring > wgames ;
TArray < TASKDIALOG_BUTTON > buttons ;
char * token ;
2019-10-26 11:16:32 +00:00
FileReader fr ;
if ( fr . OpenFile ( " ./games.list " ) )
2019-10-03 22:26:13 +00:00
{
2019-10-26 11:16:32 +00:00
auto filedata = fr . ReadPadded ( 1 ) ;
auto script = scriptfile_fromstring ( ( char * ) filedata . Data ( ) ) ;
int id = 1000 ;
while ( ! scriptfile_eof ( script ) )
2019-10-03 22:26:13 +00:00
{
2019-10-26 11:16:32 +00:00
scriptfile_getstring ( script , & token ) ;
if ( scriptfile_eof ( script ) )
{
break ;
}
FString game = token ;
scriptfile_getstring ( script , & token ) ;
paths . Push ( token ) ;
FStringf display ( " %s \n %s " , game . GetChars ( ) , token ) ;
wgames . push_back ( display . WideString ( ) ) ;
buttons . Push ( { id + + , wgames . back ( ) . c_str ( ) } ) ;
2019-10-03 22:26:13 +00:00
}
}
if ( paths . Size ( ) = = 0 )
{
exit ( 1 ) ;
}
2019-09-21 21:45:57 +00:00
int nResult = 0 ;
TASKDIALOGCONFIG stTaskConfig ;
ZeroMemory ( & stTaskConfig , sizeof ( stTaskConfig ) ) ;
stTaskConfig . cbSize = sizeof ( TASKDIALOGCONFIG ) ;
stTaskConfig . hwndParent = NULL ;
stTaskConfig . hInstance = NULL ;
2019-10-03 22:26:13 +00:00
stTaskConfig . dwFlags = TDF_ALLOW_DIALOG_CANCELLATION | TDF_USE_COMMAND_LINKS ;
2019-09-21 21:45:57 +00:00
2019-09-23 16:17:36 +00:00
if ( ! gi )
2019-09-21 21:45:57 +00:00
{
2019-10-03 22:26:13 +00:00
// Open a popup to select the game.
// The entire startup code just doesn't work right if this isn't checked as the very first thing.
2019-09-23 16:17:36 +00:00
stTaskConfig . pszWindowTitle = L " Demolition " ;
stTaskConfig . pszMainInstruction = L " Choose your game " ;
stTaskConfig . pszContent = L " " ;
2019-10-03 22:26:13 +00:00
stTaskConfig . cButtons = buttons . Size ( ) ;
stTaskConfig . pButtons = buttons . Data ( ) ;
2019-09-23 16:17:36 +00:00
stTaskConfig . nDefaultButton = 1000 ;
if ( SUCCEEDED ( TaskDialogIndirect ( & stTaskConfig , & nResult , NULL , NULL ) ) )
2019-09-21 21:45:57 +00:00
{
2019-10-19 11:27:09 +00:00
if ( nResult > = 1000 & & nResult < 1000 + ( int ) buttons . Size ( ) )
{
nResult - = 1000 ;
chdir ( paths [ nResult ] ) ;
gi = CheckFrontend ( ) ;
}
2019-09-21 21:45:57 +00:00
}
2019-09-23 16:17:36 +00:00
if ( gi = = nullptr ) exit ( 1 ) ;
2019-09-21 21:45:57 +00:00
}
}
2019-10-22 21:31:46 +00:00
2019-09-23 17:29:25 +00:00
int WINAPI WinMain ( HINSTANCE , HINSTANCE , LPSTR , int )
2015-02-11 05:21:50 +00:00
# else
2017-01-01 13:23:35 +00:00
int main ( int argc , char * argv [ ] )
2015-02-11 05:21:50 +00:00
# endif
2006-04-13 20:47:06 +00:00
{
2019-09-23 16:17:36 +00:00
# ifdef _WIN32
char * argvbuf ;
2019-09-25 20:38:47 +00:00
int32_t buildargc = win_buildargs ( & argvbuf ) ;
2019-09-23 16:17:36 +00:00
const char * * buildargv = ( const char * * ) Xmalloc ( sizeof ( char * ) * ( buildargc + 1 ) ) ;
char * wp = argvbuf ;
for ( bssize_t i = 0 ; i < buildargc ; i + + , wp + + )
{
buildargv [ i ] = wp ;
while ( * wp ) wp + + ;
}
buildargv [ buildargc ] = NULL ;
# else
auto buildargc = argc ;
auto buildargv = argv ;
# endif
2019-09-23 17:29:25 +00:00
Args = new FArgs ( buildargc , buildargv ) ;
2019-10-03 22:26:13 +00:00
ChooseGame ( ) ;
2019-09-23 16:17:36 +00:00
2016-10-20 06:26:14 +00:00
# if defined _WIN32 && defined SDL_HINT_WINDOWS_DISABLE_THREAD_NAMING
// Thread naming interferes with debugging using MinGW-w64's GDB.
SDL_SetHint ( SDL_HINT_WINDOWS_DISABLE_THREAD_NAMING , " 1 " ) ;
# endif
2009-01-09 09:29:17 +00:00
int32_t r ;
2014-11-22 12:33:47 +00:00
2019-10-23 19:11:37 +00:00
2017-09-21 04:32:14 +00:00
# ifndef _WIN32
setenv ( " __GL_THREADED_OPTIMIZATIONS " , " 1 " , 0 ) ;
2014-07-28 06:42:28 +00:00
# endif
2006-04-24 19:04:22 +00:00
buildkeytranslationtable ( ) ;
2019-09-23 17:29:25 +00:00
# ifndef _WIN32 // catching signals is not really helpful on Windows.
2014-11-22 12:33:47 +00:00
signal ( SIGSEGV , sighandler ) ;
signal ( SIGILL , sighandler ) ; /* clang -fcatch-undefined-behavior uses an ill. insn */
signal ( SIGABRT , sighandler ) ;
signal ( SIGFPE , sighandler ) ;
2015-02-11 05:22:29 +00:00
# endif
2014-04-19 02:51:33 +00:00
2015-02-11 05:21:50 +00:00
2019-09-23 17:29:25 +00:00
# if defined(HAVE_GTK2)
2014-11-22 12:33:47 +00:00
// Pre-initialize SDL video system in order to make sure XInitThreads() is called
// before GTK starts talking to X11.
2018-02-26 14:46:52 +00:00
uint32_t inited = SDL_WasInit ( SDL_INIT_VIDEO ) ;
if ( inited = = 0 )
SDL_Init ( SDL_INIT_VIDEO ) ;
else if ( ! ( inited & SDL_INIT_VIDEO ) )
SDL_InitSubSystem ( SDL_INIT_VIDEO ) ;
2006-04-24 19:04:22 +00:00
gtkbuild_init ( & argc , & argv ) ;
2006-04-13 20:47:06 +00:00
# endif
2014-11-22 12:33:47 +00:00
startwin_open ( ) ;
2019-09-22 23:28:18 +00:00
2019-10-26 08:30:08 +00:00
try
{
2019-10-26 11:41:42 +00:00
// Write to the DOCUMENTS directory, not the game directory
FString logpath = M_GetDocumentsPath ( ) + " demolition.log " ;
OSD_SetLogFile ( logpath ) ;
2019-10-26 11:16:32 +00:00
// Startup dialog must be presented here so that everything can be set up before reading the keybinds.
2019-10-26 08:30:08 +00:00
G_LoadConfig ( currentGame ) ;
2019-10-26 11:16:32 +00:00
CONFIG_Init ( ) ;
2019-10-26 08:30:08 +00:00
r = gi - > app_main ( buildargc , ( const char * * ) buildargv ) ;
2019-10-23 23:20:58 +00:00
}
2019-10-26 08:30:08 +00:00
catch ( const std : : runtime_error & err )
2019-10-23 23:20:58 +00:00
{
wm_msgbox ( " Error " , " %s " , err . what ( ) ) ;
return 3 ;
}
2019-10-26 08:30:08 +00:00
catch ( const ExitEvent & exit )
{
// Just let the rest of the function execute.
r = exit . Reason ( ) ;
}
G_SaveConfig ( ) ;
startwin_close ( ) ;
2012-11-25 04:26:37 +00:00
2019-10-26 08:30:08 +00:00
# if defined(HAVE_GTK2)
gtkbuild_exit ( r ) ;
# endif
return r ;
2006-04-13 20:47:06 +00:00
}
2016-11-15 21:55:30 +00:00
2019-10-26 11:16:32 +00:00
std : : unique_ptr < FResourceFile > engine_res ;
// The resourge manager in cache1d is far too broken to add some arbitrary file without some adjustment.
// For now, keep this file here, until the resource management can be redone in a more workable fashion.
extern FString progdir ;
void InitBaseRes ( )
{
if ( ! engine_res )
{
// If we get here for the first time, load the engine-internal data.
FString baseres = progdir + " demolition.pk3 " ;
engine_res . reset ( FResourceFile : : OpenResourceFile ( baseres , true , true ) ) ;
if ( ! engine_res )
{
I_Error ( " Engine resources (%s) not found " , baseres . GetChars ( ) ) ;
}
}
}
FileReader openFromBaseResource ( const char * fn )
{
InitBaseRes ( ) ;
auto lump = engine_res - > FindLump ( fn ) ;
if ( lump ) return lump - > NewReader ( ) ;
// Also look in game filtered directories.
FStringf filtername ( " filter/game-%s/%s " , currentGame . GetChars ( ) , fn ) ;
lump = engine_res - > FindLump ( filtername ) ;
if ( lump ) return lump - > NewReader ( ) ;
return FileReader ( nullptr ) ;
}
2014-11-28 08:30:31 +00:00
# if SDL_MAJOR_VERSION != 1
2018-04-12 21:02:51 +00:00
int32_t videoSetVsync ( int32_t newSync )
2008-07-22 21:03:09 +00:00
{
2016-12-26 06:01:36 +00:00
if ( vsync_renderlayer = = newSync )
2016-11-15 21:55:30 +00:00
return newSync ;
2013-10-13 09:08:31 +00:00
2016-11-15 21:55:30 +00:00
# ifdef USE_OPENGL
2013-10-08 10:00:25 +00:00
if ( sdl_context )
2016-11-15 21:55:30 +00:00
{
int result = SDL_GL_SetSwapInterval ( newSync ) ;
if ( result = = - 1 )
{
if ( newSync = = - 1 )
{
newSync = 1 ;
result = SDL_GL_SetSwapInterval ( newSync ) ;
}
if ( result = = - 1 )
{
newSync = 0 ;
OSD_Printf ( " Unable to enable VSync! \n " ) ;
}
}
2016-12-26 06:01:36 +00:00
vsync_renderlayer = newSync ;
2016-11-15 21:55:30 +00:00
}
else
2008-07-22 21:03:09 +00:00
# endif
2016-11-15 21:55:30 +00:00
{
2019-09-23 21:33:59 +00:00
/*
2016-12-26 06:01:36 +00:00
vsync_renderlayer = newSync ;
2016-11-15 21:55:30 +00:00
2018-04-12 21:02:51 +00:00
videoResetMode ( ) ;
2018-07-14 21:36:44 +00:00
if ( videoSetGameMode ( fullscreen , xres , yres , bpp , upscalefactor ) )
2016-11-15 21:55:30 +00:00
OSD_Printf ( " restartvid: Reset failed... \n " ) ;
2019-09-23 21:33:59 +00:00
*/
2016-11-15 21:55:30 +00:00
}
2016-12-26 06:01:40 +00:00
return newSync ;
2016-11-15 21:55:30 +00:00
}
2014-11-28 08:30:31 +00:00
# endif
2006-04-13 20:47:06 +00:00
2014-11-28 08:12:40 +00:00
int32_t sdlayer_checkversion ( void ) ;
# if SDL_MAJOR_VERSION != 1
2014-11-22 12:33:47 +00:00
int32_t sdlayer_checkversion ( void )
{
SDL_version compiled ;
2013-07-20 03:36:54 +00:00
2015-02-07 17:29:14 +00:00
SDL_GetVersion ( & linked ) ;
2014-11-22 12:33:47 +00:00
SDL_VERSION ( & compiled ) ;
2010-10-17 14:49:39 +00:00
2016-01-11 05:05:16 +00:00
if ( ! Bmemcmp ( & compiled , & linked , sizeof ( SDL_version ) ) )
initprintf ( " Initializing SDL %d.%d.%d \n " ,
compiled . major , compiled . minor , compiled . patch ) ;
else
initprintf ( " Initializing SDL %d.%d.%d "
2016-05-29 21:11:21 +00:00
" (built against SDL version %d.%d.%d) \n " ,
2016-01-11 05:05:16 +00:00
linked . major , linked . minor , linked . patch , compiled . major , compiled . minor , compiled . patch ) ;
2013-10-08 09:59:59 +00:00
2015-02-07 17:29:14 +00:00
if ( SDL_VERSIONNUM ( linked . major , linked . minor , linked . patch ) < SDL_REQUIREDVERSION )
2009-08-03 22:15:53 +00:00
{
2014-11-22 12:33:47 +00:00
/*reject running under SDL versions older than what is stated in sdl_inc.h */
initprintf ( " You need at least v%d.%d.%d of SDL to run this game \n " , SDL_MIN_X , SDL_MIN_Y , SDL_MIN_Z ) ;
return - 1 ;
2009-08-03 22:15:53 +00:00
}
2014-11-22 12:33:47 +00:00
return 0 ;
2009-08-03 22:15:53 +00:00
}
2006-04-13 20:47:06 +00:00
//
// initsystem() -- init SDL systems
//
2009-01-09 09:29:17 +00:00
int32_t initsystem ( void )
2006-04-13 20:47:06 +00:00
{
2014-11-22 12:33:47 +00:00
const int sdlinitflags = SDL_INIT_VIDEO ;
2006-04-13 20:47:06 +00:00
2010-06-22 21:50:01 +00:00
mutex_init ( & m_initprintf ) ;
2012-11-25 04:26:37 +00:00
# ifdef _WIN32
win_init ( ) ;
# endif
2014-11-22 12:33:47 +00:00
if ( sdlayer_checkversion ( ) )
2008-04-25 01:46:19 +00:00
return - 1 ;
2006-04-13 20:47:06 +00:00
2018-02-26 14:46:52 +00:00
int32_t err = 0 ;
uint32_t inited = SDL_WasInit ( sdlinitflags ) ;
if ( inited = = 0 )
err = SDL_Init ( sdlinitflags ) ;
else if ( ( inited & sdlinitflags ) ! = sdlinitflags )
err = SDL_InitSubSystem ( sdlinitflags & ~ inited ) ;
if ( err )
2006-11-17 05:05:16 +00:00
{
2011-01-16 02:50:27 +00:00
initprintf ( " Initialization failed! (%s) \n Non-interactive mode enabled \n " , SDL_GetError ( ) ) ;
2011-02-27 22:11:39 +00:00
novideo = 1 ;
# ifdef USE_OPENGL
nogl = 1 ;
# endif
2006-04-24 19:04:22 +00:00
}
2006-04-13 20:47:06 +00:00
2016-12-26 06:02:41 +00:00
# if SDL_MAJOR_VERSION > 1
SDL_StopTextInput ( ) ;
# endif
2006-04-24 19:04:22 +00:00
atexit ( uninitsystem ) ;
2006-04-13 20:47:06 +00:00
2006-04-24 19:04:22 +00:00
frameplace = 0 ;
lockcount = 0 ;
2006-04-13 20:47:06 +00:00
2011-01-16 02:50:27 +00:00
if ( ! novideo )
{
2014-11-22 12:33:47 +00:00
# ifdef USE_OPENGL
2018-02-16 06:38:21 +00:00
if ( SDL_GL_LoadLibrary ( 0 ) )
Add prototypical SDL 2.X support.
Doesn't work: indexed-color modes, gamma (at least for X11), mouse wheel,
special keys like ENTER or BACKSPACE in the OSD, probably more...
In build/Makefile.shared, we now have logic to autodetect an SDL2 installed
in /usr/local, however OS X and Wii builds follow other Makefile code paths,
it seems. Note that the matching SDL2_mixer must be used then, too.
In source/jaudiolib/src/driver_sdl.c, change the #includes from <SDL/SDL_xxx.h>
to "SDL_xxx.h". SDL wiki says this is the most portable way, hopefully this
doesn't break builds for anyone.
git-svn-id: https://svn.eduke32.com/eduke32@2777 1a8010ca-5511-0410-912e-c29ae57300e0
2012-06-22 21:39:53 +00:00
{
2018-02-16 06:38:21 +00:00
initprintf ( " Failed loading OpenGL Driver. GL modes will be unavailable. Error: %s \n " , SDL_GetError ( ) ) ;
2014-11-22 12:33:47 +00:00
nogl = 1 ;
Add prototypical SDL 2.X support.
Doesn't work: indexed-color modes, gamma (at least for X11), mouse wheel,
special keys like ENTER or BACKSPACE in the OSD, probably more...
In build/Makefile.shared, we now have logic to autodetect an SDL2 installed
in /usr/local, however OS X and Wii builds follow other Makefile code paths,
it seems. Note that the matching SDL2_mixer must be used then, too.
In source/jaudiolib/src/driver_sdl.c, change the #includes from <SDL/SDL_xxx.h>
to "SDL_xxx.h". SDL wiki says this is the most portable way, hopefully this
doesn't break builds for anyone.
git-svn-id: https://svn.eduke32.com/eduke32@2777 1a8010ca-5511-0410-912e-c29ae57300e0
2012-06-22 21:39:53 +00:00
}
2006-04-13 20:47:06 +00:00
# endif
2016-01-11 05:05:16 +00:00
# ifndef _WIN32
const char * drvname = SDL_GetVideoDriver ( 0 ) ;
Add prototypical SDL 2.X support.
Doesn't work: indexed-color modes, gamma (at least for X11), mouse wheel,
special keys like ENTER or BACKSPACE in the OSD, probably more...
In build/Makefile.shared, we now have logic to autodetect an SDL2 installed
in /usr/local, however OS X and Wii builds follow other Makefile code paths,
it seems. Note that the matching SDL2_mixer must be used then, too.
In source/jaudiolib/src/driver_sdl.c, change the #includes from <SDL/SDL_xxx.h>
to "SDL_xxx.h". SDL wiki says this is the most portable way, hopefully this
doesn't break builds for anyone.
git-svn-id: https://svn.eduke32.com/eduke32@2777 1a8010ca-5511-0410-912e-c29ae57300e0
2012-06-22 21:39:53 +00:00
if ( drvname )
initprintf ( " Using \" %s \" video driver \n " , drvname ) ;
2016-01-11 05:05:16 +00:00
# endif
2014-11-22 12:33:47 +00:00
wm_setapptitle ( apptitle ) ;
Add prototypical SDL 2.X support.
Doesn't work: indexed-color modes, gamma (at least for X11), mouse wheel,
special keys like ENTER or BACKSPACE in the OSD, probably more...
In build/Makefile.shared, we now have logic to autodetect an SDL2 installed
in /usr/local, however OS X and Wii builds follow other Makefile code paths,
it seems. Note that the matching SDL2_mixer must be used then, too.
In source/jaudiolib/src/driver_sdl.c, change the #includes from <SDL/SDL_xxx.h>
to "SDL_xxx.h". SDL wiki says this is the most portable way, hopefully this
doesn't break builds for anyone.
git-svn-id: https://svn.eduke32.com/eduke32@2777 1a8010ca-5511-0410-912e-c29ae57300e0
2012-06-22 21:39:53 +00:00
}
2006-04-13 20:47:06 +00:00
2006-04-24 19:04:22 +00:00
return 0 ;
2006-04-13 20:47:06 +00:00
}
2014-11-28 08:12:40 +00:00
# endif
2006-04-13 20:47:06 +00:00
//
// uninitsystem() -- uninit SDL systems
//
void uninitsystem ( void )
{
2006-04-24 19:04:22 +00:00
uninitinput ( ) ;
2018-04-12 21:02:51 +00:00
timerUninit ( ) ;
2006-04-13 20:47:06 +00:00
2009-11-18 01:17:56 +00:00
if ( appicon )
2009-12-05 09:22:43 +00:00
{
2009-11-18 01:17:56 +00:00
SDL_FreeSurface ( appicon ) ;
2009-12-05 09:22:43 +00:00
appicon = NULL ;
}
2009-11-18 01:17:56 +00:00
2006-04-24 19:04:22 +00:00
SDL_Quit ( ) ;
2006-04-13 20:47:06 +00:00
# ifdef USE_OPENGL
2018-07-14 21:36:44 +00:00
# if SDL_MAJOR_VERSION!=1
2018-02-16 06:38:21 +00:00
SDL_GL_UnloadLibrary ( ) ;
2018-07-14 21:36:44 +00:00
# endif
2006-04-13 20:47:06 +00:00
# endif
}
2013-10-08 10:00:25 +00:00
//
// system_getcvars() -- propagate any cvars that are read post-initialization
//
void system_getcvars ( void )
{
2019-10-23 19:11:37 +00:00
vid_vsync = videoSetVsync ( vid_vsync ) ;
2013-10-08 10:00:25 +00:00
}
2006-04-13 20:47:06 +00:00
//
2014-07-24 14:01:44 +00:00
// initprintf() -- prints a formatted string to the intitialization window
2006-04-13 20:47:06 +00:00
//
void initprintf ( const char * f , . . . )
{
2006-04-24 19:04:22 +00:00
va_list va ;
2010-06-27 10:08:58 +00:00
char buf [ 2048 ] ;
2006-04-24 19:04:22 +00:00
va_start ( va , f ) ;
2010-06-27 10:08:58 +00:00
Bvsnprintf ( buf , sizeof ( buf ) , f , va ) ;
2006-04-24 19:04:22 +00:00
va_end ( va ) ;
2009-01-06 06:59:18 +00:00
2019-10-15 18:02:37 +00:00
# ifdef _WIN32
if ( IsDebuggerPresent ( ) )
OutputDebugStringA ( buf ) ;
# endif
2014-07-24 14:01:44 +00:00
initputs ( buf ) ;
}
//
// initputs() -- prints a string to the intitialization window
//
void initputs ( const char * buf )
{
static char dabuf [ 2048 ] ;
2014-04-15 19:02:48 +00:00
# ifdef __ANDROID__
__android_log_print ( ANDROID_LOG_INFO , " DUKE " , " %s " , buf ) ;
# endif
2014-07-24 14:01:44 +00:00
OSD_Puts ( buf ) ;
2011-01-16 02:50:27 +00:00
// Bprintf("%s", buf);
2006-04-13 20:47:06 +00:00
2019-08-08 22:49:39 +00:00
mutex_lock ( & m_initprintf ) ;
2009-01-06 06:59:18 +00:00
if ( Bstrlen ( dabuf ) + Bstrlen ( buf ) > 1022 )
{
startwin_puts ( dabuf ) ;
Bmemset ( dabuf , 0 , sizeof ( dabuf ) ) ;
}
Bstrcat ( dabuf , buf ) ;
2006-04-13 20:47:06 +00:00
2018-04-12 21:02:31 +00:00
if ( g_logFlushWindow | | Bstrlen ( dabuf ) > 768 )
2009-01-06 06:59:18 +00:00
{
startwin_puts ( dabuf ) ;
2012-11-24 09:13:29 +00:00
# ifndef _WIN32
2009-01-06 06:59:18 +00:00
startwin_idle ( NULL ) ;
2013-10-07 10:05:41 +00:00
# else
handleevents ( ) ;
2012-11-24 09:13:29 +00:00
# endif
2009-01-06 06:59:18 +00:00
Bmemset ( dabuf , 0 , sizeof ( dabuf ) ) ;
}
2019-08-08 22:49:39 +00:00
mutex_unlock ( & m_initprintf ) ;
2009-01-06 06:59:18 +00:00
}
2006-04-13 20:47:06 +00:00
//
2014-07-24 14:01:44 +00:00
// debugprintf() -- prints a formatted debug string to stderr
2006-04-13 20:47:06 +00:00
//
void debugprintf ( const char * f , . . . )
{
2011-07-20 23:04:20 +00:00
# if defined DEBUGGINGAIDS && !(defined __APPLE__ && defined __BIG_ENDIAN__)
2006-04-24 19:04:22 +00:00
va_list va ;
2006-04-13 20:47:06 +00:00
2006-04-24 19:04:22 +00:00
va_start ( va , f ) ;
Bvfprintf ( stderr , f , va ) ;
va_end ( va ) ;
2008-03-26 04:11:26 +00:00
# else
UNREFERENCED_PARAMETER ( f ) ;
2006-04-13 20:47:06 +00:00
# endif
}
//
//
// ---------------------------------------
//
// All things Input
//
// ---------------------------------------
//
//
2009-01-09 09:29:17 +00:00
// static int32_t joyblast=0;
2006-04-13 20:47:06 +00:00
static SDL_Joystick * joydev = NULL ;
2019-08-12 15:23:15 +00:00
# if SDL_MAJOR_VERSION >= 2
static SDL_GameController * controller = NULL ;
static void LoadSDLControllerDB ( )
{
2019-10-20 22:13:17 +00:00
auto fh = fopenFileReader ( " gamecontrollerdb.txt " , 0 ) ;
if ( ! fh . isOpen ( ) )
2019-08-12 15:23:15 +00:00
return ;
2019-10-20 22:13:17 +00:00
int flen = fh . GetLength ( ) ;
2019-08-12 15:23:15 +00:00
if ( flen < = 0 )
{
return ;
}
char * dbuf = ( char * ) malloc ( flen + 1 ) ;
if ( ! dbuf )
{
return ;
}
2019-10-20 22:13:17 +00:00
if ( fh . Read ( dbuf , flen ) ! = flen )
2019-08-12 15:23:15 +00:00
{
free ( dbuf ) ;
return ;
}
dbuf [ flen ] = ' \0 ' ;
SDL_RWops * rwops = SDL_RWFromConstMem ( dbuf , flen ) ;
if ( ! rwops )
{
free ( dbuf ) ;
return ;
}
2019-10-19 23:42:24 +00:00
int i = SDL_GameControllerAddMappingsFromRW ( rwops , 1 ) ;
2019-08-12 15:23:15 +00:00
if ( i = = - 1 )
buildprintf ( " Failed loading game controller database: %s \n " , SDL_GetError ( ) ) ;
else
buildputs ( " Loaded game controller database \n " ) ;
free ( dbuf ) ;
}
# endif
2006-04-13 20:47:06 +00:00
2019-08-14 03:03:52 +00:00
void joyScanDevices ( )
{
inputdevices & = ~ 4 ;
if ( controller )
{
SDL_GameControllerClose ( controller ) ;
controller = nullptr ;
}
if ( joydev )
{
SDL_JoystickClose ( joydev ) ;
joydev = nullptr ;
}
2019-08-14 15:28:59 +00:00
int numjoysticks = SDL_NumJoysticks ( ) ;
2019-08-14 03:03:52 +00:00
if ( numjoysticks < 1 )
{
buildputs ( " No game controllers found \n " ) ;
}
else
{
buildputs ( " Game controllers: \n " ) ;
for ( int i = 0 ; i < numjoysticks ; i + + )
{
const char * name ;
# if SDL_MAJOR_VERSION >= 2
if ( SDL_IsGameController ( i ) )
name = SDL_GameControllerNameForIndex ( i ) ;
else
# endif
name = SDL_JoystickNameForIndex ( i ) ;
buildprintf ( " %d. %s \n " , i + 1 , name ) ;
}
# if SDL_MAJOR_VERSION >= 2
for ( int i = 0 ; i < numjoysticks ; i + + )
{
if ( ( controller = SDL_GameControllerOpen ( i ) ) )
{
buildprintf ( " Using controller %s \n " , SDL_GameControllerName ( controller ) ) ;
joystick . numAxes = SDL_CONTROLLER_AXIS_MAX ;
joystick . numButtons = SDL_CONTROLLER_BUTTON_MAX ;
joystick . numHats = 0 ;
joystick . isGameController = 1 ;
Xfree ( joystick . pAxis ) ;
joystick . pAxis = ( int32_t * ) Xcalloc ( joystick . numAxes , sizeof ( int32_t ) ) ;
Xfree ( joystick . pHat ) ;
joystick . pHat = nullptr ;
inputdevices | = 4 ;
return ;
}
}
# endif
for ( int i = 0 ; i < numjoysticks ; i + + )
{
if ( ( joydev = SDL_JoystickOpen ( i ) ) )
{
buildprintf ( " Using joystick %s \n " , SDL_JoystickName ( joydev ) ) ;
// KEEPINSYNC duke3d/src/gamedefs.h, mact/include/_control.h
joystick . numAxes = min ( 9 , SDL_JoystickNumAxes ( joydev ) ) ;
joystick . numButtons = min ( 32 , SDL_JoystickNumButtons ( joydev ) ) ;
joystick . numHats = min ( ( 36 - joystick . numButtons ) / 4 , SDL_JoystickNumHats ( joydev ) ) ;
joystick . isGameController = 0 ;
initprintf ( " Joystick %d has %d axes, %d buttons, and %d hat(s). \n " , i + 1 , joystick . numAxes , joystick . numButtons , joystick . numHats ) ;
Xfree ( joystick . pAxis ) ;
joystick . pAxis = ( int32_t * ) Xcalloc ( joystick . numAxes , sizeof ( int32_t ) ) ;
Xfree ( joystick . pHat ) ;
if ( joystick . numHats )
joystick . pHat = ( int32_t * ) Xcalloc ( joystick . numHats , sizeof ( int32_t ) ) ;
else
joystick . pHat = nullptr ;
for ( int j = 0 ; j < joystick . numHats ; j + + )
joystick . pHat [ j ] = - 1 ; // center
SDL_JoystickEventState ( SDL_ENABLE ) ;
inputdevices | = 4 ;
return ;
}
}
buildputs ( " No controllers are usable \n " ) ;
}
}
2006-04-13 20:47:06 +00:00
//
// initinput() -- init input system
//
2019-08-14 15:28:59 +00:00
int32_t initinput ( void )
2006-04-13 20:47:06 +00:00
{
2018-10-07 05:23:44 +00:00
int32_t i ;
2006-04-24 19:04:22 +00:00
2014-05-24 15:27:53 +00:00
2015-04-28 21:30:42 +00:00
# if defined EDUKE32_OSX
2006-04-24 19:04:22 +00:00
// force OS X to operate in >1 button mouse mode so that LMB isn't adulterated
2014-11-22 12:33:47 +00:00
if ( ! getenv ( " SDL_HAS3BUTTONMOUSE " ) )
2018-10-07 05:23:44 +00:00
{
static char sdl_has3buttonmouse [ ] = " SDL_HAS3BUTTONMOUSE=1 " ;
2016-01-12 10:30:48 +00:00
putenv ( sdl_has3buttonmouse ) ;
2018-10-07 05:23:44 +00:00
}
2006-04-13 20:47:06 +00:00
# endif
2014-11-22 12:33:47 +00:00
inputdevices = 1 | 2 ; // keyboard (1) and mouse (2)
2018-04-12 21:02:31 +00:00
g_mouseGrabbed = 0 ;
2006-04-24 19:04:22 +00:00
2018-04-12 21:02:31 +00:00
memset ( g_keyNameTable , 0 , sizeof ( g_keyNameTable ) ) ;
2014-04-12 08:45:26 +00:00
2014-11-22 12:33:47 +00:00
for ( i = SDL_NUM_SCANCODES - 1 ; i > = 0 ; i - - )
2008-10-20 12:33:29 +00:00
{
2014-11-22 12:33:47 +00:00
if ( ! keytranslation [ i ] )
continue ;
2018-10-25 23:29:04 +00:00
Bstrncpyz ( g_keyNameTable [ keytranslation [ i ] ] , SDL_GetKeyName ( SDL_SCANCODE_TO_KEYCODE ( i ) ) , sizeof ( g_keyNameTable [ 0 ] ) ) ;
2014-04-12 08:45:26 +00:00
}
2006-04-24 19:04:22 +00:00
2019-08-12 15:23:15 +00:00
if ( ! SDL_InitSubSystem ( SDL_INIT_GAMECONTROLLER ) )
2006-11-17 05:05:16 +00:00
{
2019-08-12 15:23:15 +00:00
LoadSDLControllerDB ( ) ;
2019-08-14 03:03:52 +00:00
joyScanDevices ( ) ;
2006-04-24 19:04:22 +00:00
}
return 0 ;
2006-04-13 20:47:06 +00:00
}
//
// uninitinput() -- uninit input system
//
void uninitinput ( void )
{
2018-04-12 21:02:31 +00:00
mouseUninit ( ) ;
2006-04-13 20:47:06 +00:00
2019-08-12 15:23:15 +00:00
if ( controller )
{
SDL_GameControllerClose ( controller ) ;
controller = NULL ;
}
2006-11-17 05:05:16 +00:00
if ( joydev )
{
2006-04-24 19:04:22 +00:00
SDL_JoystickClose ( joydev ) ;
joydev = NULL ;
}
2006-04-13 20:47:06 +00:00
}
2018-04-12 21:02:31 +00:00
const char * joyGetName ( int32_t what , int32_t num )
2006-04-13 20:47:06 +00:00
{
2006-04-24 19:04:22 +00:00
static char tmp [ 64 ] ;
2006-11-17 05:05:16 +00:00
switch ( what )
{
2014-11-22 12:33:47 +00:00
case 0 : // axis
2018-04-12 21:02:31 +00:00
if ( ( unsigned ) num > ( unsigned ) joystick . numAxes )
2014-11-22 12:33:47 +00:00
return NULL ;
2019-08-12 15:23:15 +00:00
if ( controller )
{
static char const * axisStrings [ ] =
{
" Left Stick X-Axis " ,
" Left Stick Y-Axis " ,
" Right Stick X-Axis " ,
" Right Stick Y-Axis " ,
" Left Trigger " ,
" Right Trigger " ,
NULL
} ;
return axisStrings [ num ] ;
}
2014-11-22 12:33:47 +00:00
Bsprintf ( tmp , " Axis %d " , num ) ;
return ( char * ) tmp ;
case 1 : // button
2018-04-12 21:02:31 +00:00
if ( ( unsigned ) num > ( unsigned ) joystick . numButtons )
2014-11-22 12:33:47 +00:00
return NULL ;
2019-08-12 15:23:15 +00:00
if ( controller )
{
static char const * buttonStrings [ ] =
{
" A " ,
" B " ,
" X " ,
" Y " ,
" Back " ,
" Guide " ,
" Start " ,
" Left Stick " ,
" Right Stick " ,
" Left Shoulder " ,
" Right Shoulder " ,
" D-Pad Up " ,
" D-Pad Down " ,
" D-Pad Left " ,
" D-Pad Right " ,
NULL
} ;
return buttonStrings [ num ] ;
}
2014-11-22 12:33:47 +00:00
Bsprintf ( tmp , " Button %d " , num ) ;
return ( char * ) tmp ;
case 2 : // hat
2018-04-12 21:02:31 +00:00
if ( ( unsigned ) num > ( unsigned ) joystick . numHats )
2014-11-22 12:33:47 +00:00
return NULL ;
Bsprintf ( tmp , " Hat %d " , num ) ;
return ( char * ) tmp ;
default : return NULL ;
2012-05-01 12:38:43 +00:00
}
}
2006-04-13 20:47:06 +00:00
//
// initmouse() -- init mouse input
//
2018-11-18 18:08:53 +00:00
void mouseInit ( void )
2006-04-13 20:47:06 +00:00
{
2018-11-18 18:08:53 +00:00
mouseGrabInput ( g_mouseEnabled = g_mouseLockedToWindow ) ; // FIXME - SA
2006-04-13 20:47:06 +00:00
}
//
// uninitmouse() -- uninit mouse input
//
2018-04-12 21:02:31 +00:00
void mouseUninit ( void )
2006-04-13 20:47:06 +00:00
{
2018-04-12 21:02:31 +00:00
mouseGrabInput ( 0 ) ;
g_mouseEnabled = 0 ;
2006-04-13 20:47:06 +00:00
}
2013-10-08 09:59:59 +00:00
//
// grabmouse_low() -- show/hide mouse cursor, lower level (doesn't check state).
// furthermore return 0 if successful.
//
static inline char grabmouse_low ( char a )
{
/* FIXME: Maybe it's better to make sure that grabmouse_low
is called only when a window is ready ? */
if ( sdl_window )
SDL_SetWindowGrab ( sdl_window , a ? SDL_TRUE : SDL_FALSE ) ;
return SDL_SetRelativeMouseMode ( a ? SDL_TRUE : SDL_FALSE ) ;
}
2006-04-13 20:47:06 +00:00
//
// grabmouse() -- show/hide mouse cursor
//
2018-04-23 06:35:52 +00:00
void mouseGrabInput ( bool grab )
2006-04-13 20:47:06 +00:00
{
2018-04-12 21:02:31 +00:00
if ( appactive & & g_mouseEnabled )
2006-11-17 05:05:16 +00:00
{
2018-04-23 06:35:52 +00:00
if ( ( grab ! = g_mouseGrabbed ) & & ! grabmouse_low ( grab ) )
g_mouseGrabbed = grab ;
2006-11-17 05:05:16 +00:00
}
else
2018-04-23 06:35:52 +00:00
g_mouseGrabbed = grab ;
2014-11-22 12:33:47 +00:00
2018-04-12 21:02:31 +00:00
g_mousePos . x = g_mousePos . y = 0 ;
2014-11-17 07:39:12 +00:00
}
2018-04-12 21:02:31 +00:00
void mouseLockToWindow ( char a )
2014-11-17 07:39:12 +00:00
{
2015-01-12 01:54:18 +00:00
if ( ! ( a & 2 ) )
{
2018-04-12 21:02:31 +00:00
mouseGrabInput ( a ) ;
g_mouseLockedToWindow = g_mouseGrabbed ;
2015-01-12 01:54:18 +00:00
}
SDL_ShowCursor ( ( osd & & osd - > flags & OSD_CAPTURE ) ? SDL_ENABLE : SDL_DISABLE ) ;
2006-04-13 20:47:06 +00:00
}
2019-09-19 20:02:45 +00:00
void mouseMoveToCenter ( void )
{
if ( sdl_window )
2019-09-14 14:33:22 +00:00
{
g_mouseAbs = { xdim > > 1 , ydim > > 1 } ;
SDL_WarpMouseInWindow ( sdl_window , g_mouseAbs . x , g_mouseAbs . y ) ;
}
2019-09-19 20:02:45 +00:00
}
2006-04-13 20:47:06 +00:00
//
// setjoydeadzone() -- sets the dead and saturation zones for the joystick
//
2018-04-12 21:02:31 +00:00
void joySetDeadZone ( int32_t axis , uint16_t dead , uint16_t satur )
2008-03-23 00:06:42 +00:00
{
2010-10-21 02:20:40 +00:00
joydead [ axis ] = dead ;
joysatur [ axis ] = satur ;
2008-03-23 00:06:42 +00:00
}
2006-04-13 20:47:06 +00:00
//
// getjoydeadzone() -- gets the dead and saturation zones for the joystick
//
2018-04-12 21:02:31 +00:00
void joyGetDeadZone ( int32_t axis , uint16_t * dead , uint16_t * satur )
2006-04-13 20:47:06 +00:00
{
2010-10-21 02:20:40 +00:00
* dead = joydead [ axis ] ;
* satur = joysatur [ axis ] ;
2006-04-13 20:47:06 +00:00
}
//
//
// ---------------------------------------
//
// All things Video
//
// ---------------------------------------
//
2006-04-24 19:04:22 +00:00
//
2006-04-13 20:47:06 +00:00
//
// getvalidmodes() -- figure out what video modes are available
//
2013-09-21 13:38:44 +00:00
static int sortmodes ( const void * a_ , const void * b_ )
2006-04-13 20:47:06 +00:00
{
2019-08-08 01:49:00 +00:00
auto a = ( const struct validmode_t * ) b_ ;
auto b = ( const struct validmode_t * ) a_ ;
2018-11-18 18:07:10 +00:00
int x ;
2013-09-21 13:38:44 +00:00
2006-04-24 19:04:22 +00:00
if ( ( x = a - > fs - b - > fs ) ! = 0 ) return x ;
if ( ( x = a - > bpp - b - > bpp ) ! = 0 ) return x ;
if ( ( x = a - > xdim - b - > xdim ) ! = 0 ) return x ;
if ( ( x = a - > ydim - b - > ydim ) ! = 0 ) return x ;
2006-04-13 20:47:06 +00:00
2006-04-24 19:04:22 +00:00
return 0 ;
2006-04-13 20:47:06 +00:00
}
2014-04-12 08:45:26 +00:00
2006-04-13 20:47:06 +00:00
static char modeschecked = 0 ;
2014-04-12 08:45:26 +00:00
2014-11-22 12:33:47 +00:00
# if SDL_MAJOR_VERSION != 1
2018-04-12 21:02:51 +00:00
void videoGetModes ( void )
2006-04-13 20:47:06 +00:00
{
2014-11-22 12:33:47 +00:00
int32_t i , maxx = 0 , maxy = 0 ;
SDL_DisplayMode dispmode ;
2019-08-29 20:06:31 +00:00
int const display = r_displayindex < SDL_GetNumVideoDisplays ( ) ? r_displayindex : 0 ;
2006-04-13 20:47:06 +00:00
2014-11-22 12:33:47 +00:00
if ( modeschecked | | novideo )
return ;
2006-04-13 20:47:06 +00:00
2014-11-22 12:33:47 +00:00
validmodecnt = 0 ;
2014-04-12 08:45:26 +00:00
// initprintf("Detecting video modes:\n");
2006-04-13 20:47:06 +00:00
2006-04-24 19:04:22 +00:00
// do fullscreen modes first
2019-08-29 20:06:31 +00:00
for ( i = 0 ; i < SDL_GetNumDisplayModes ( display ) ; i + + )
2013-10-08 09:59:59 +00:00
{
2019-08-29 20:06:31 +00:00
SDL_GetDisplayMode ( display , i , & dispmode ) ;
2017-08-27 10:20:41 +00:00
if ( ! SDL_CHECKMODE ( dispmode . w , dispmode . h ) | |
2016-02-13 21:06:12 +00:00
( maxrefreshfreq & & ( dispmode . refresh_rate > maxrefreshfreq ) ) )
2014-11-22 12:33:47 +00:00
continue ;
2013-10-08 09:59:59 +00:00
// HACK: 8-bit == Software, 32-bit == OpenGL
2014-11-22 12:33:47 +00:00
SDL_ADDMODE ( dispmode . w , dispmode . h , 8 , 1 ) ;
2013-10-08 09:59:59 +00:00
# ifdef USE_OPENGL
if ( ! nogl )
2014-11-22 12:33:47 +00:00
SDL_ADDMODE ( dispmode . w , dispmode . h , 32 , 1 ) ;
2013-10-08 09:59:59 +00:00
# endif
2014-11-22 12:33:47 +00:00
if ( ( dispmode . w > maxx ) | | ( dispmode . h > maxy ) )
2013-10-08 09:59:59 +00:00
{
maxx = dispmode . w ;
maxy = dispmode . h ;
}
}
2014-11-22 12:33:47 +00:00
SDL_CHECKFSMODES ( maxx , maxy ) ;
2006-04-24 19:04:22 +00:00
// add windowed modes next
2018-10-25 23:32:00 +00:00
// SDL sorts display modes largest to smallest, so we can just compare with mode 0
// to make sure we aren't adding modes that are larger than the actual screen res
2019-08-29 20:06:31 +00:00
SDL_GetDisplayMode ( display , 0 , & dispmode ) ;
2018-10-25 23:32:00 +00:00
2018-04-12 21:02:31 +00:00
for ( i = 0 ; g_defaultVideoModes [ i ] . x ; i + + )
2014-04-12 08:45:26 +00:00
{
2018-10-25 23:32:00 +00:00
auto const & mode = g_defaultVideoModes [ i ] ;
if ( mode . x > dispmode . w | | mode . y > dispmode . h | | ! SDL_CHECKMODE ( mode . x , mode . y ) )
2014-11-22 12:33:47 +00:00
continue ;
2018-10-25 23:32:00 +00:00
// 8-bit == Software, 32-bit == OpenGL
SDL_ADDMODE ( mode . x , mode . y , 8 , 0 ) ;
2014-11-22 12:33:47 +00:00
2013-10-08 09:59:59 +00:00
# ifdef USE_OPENGL
2014-11-22 12:33:47 +00:00
if ( nogl )
continue ;
2018-10-25 23:32:00 +00:00
SDL_ADDMODE ( mode . x , mode . y , 32 , 0 ) ;
2013-10-08 09:59:59 +00:00
# endif
2014-04-12 08:45:26 +00:00
}
2006-04-13 20:47:06 +00:00
2014-11-22 12:33:47 +00:00
qsort ( ( void * ) validmode , validmodecnt , sizeof ( struct validmode_t ) , & sortmodes ) ;
2006-04-13 20:47:06 +00:00
2014-11-22 12:33:47 +00:00
modeschecked = 1 ;
2006-04-13 20:47:06 +00:00
}
2014-04-12 08:45:26 +00:00
# endif
2006-04-13 20:47:06 +00:00
//
// checkvideomode() -- makes sure the video mode passed is legal
//
2018-04-12 21:02:51 +00:00
int32_t videoCheckMode ( int32_t * x , int32_t * y , int32_t c , int32_t fs , int32_t forced )
2006-04-13 20:47:06 +00:00
{
2009-01-09 09:29:17 +00:00
int32_t i , nearest = - 1 , dx , dy , odx = 9999 , ody = 9999 ;
2006-04-13 20:47:06 +00:00
2018-04-12 21:02:51 +00:00
videoGetModes ( ) ;
2006-04-13 20:47:06 +00:00
2006-04-24 19:04:22 +00:00
if ( c > 8
2006-04-13 20:47:06 +00:00
# ifdef USE_OPENGL
2006-04-24 19:04:22 +00:00
& & nogl
2006-04-13 20:47:06 +00:00
# endif
2006-04-24 19:04:22 +00:00
) return - 1 ;
// fix up the passed resolution values to be multiples of 8
// and at least 320x200 or at most MAXXDIMxMAXYDIM
2014-11-22 12:33:47 +00:00
* x = clamp ( * x , 320 , MAXXDIM ) ;
* y = clamp ( * y , 200 , MAXYDIM ) ;
2006-04-24 19:04:22 +00:00
2014-11-22 12:33:47 +00:00
for ( i = 0 ; i < validmodecnt ; i + + )
2006-11-17 05:05:16 +00:00
{
2014-11-22 12:33:47 +00:00
if ( validmode [ i ] . bpp ! = c | | validmode [ i ] . fs ! = fs )
continue ;
2006-04-24 19:04:22 +00:00
dx = klabs ( validmode [ i ] . xdim - * x ) ;
dy = klabs ( validmode [ i ] . ydim - * y ) ;
2014-11-22 12:33:47 +00:00
2006-11-17 05:05:16 +00:00
if ( ! ( dx | dy ) )
2007-12-12 17:42:14 +00:00
{
// perfect match
2006-04-24 19:04:22 +00:00
nearest = i ;
break ;
}
2014-11-22 12:33:47 +00:00
2006-11-17 05:05:16 +00:00
if ( ( dx < = odx ) & & ( dy < = ody ) )
{
2006-04-24 19:04:22 +00:00
nearest = i ;
2014-11-22 12:33:47 +00:00
odx = dx ;
ody = dy ;
2006-04-24 19:04:22 +00:00
}
}
2006-11-13 23:12:47 +00:00
# ifdef ANY_WINDOWED_SIZE
2006-07-01 01:40:18 +00:00
if ( ! forced & & ( fs & 1 ) = = 0 & & ( nearest < 0 | | ( validmode [ nearest ] . xdim ! = * x | | validmode [ nearest ] . ydim ! = * y ) ) )
2006-04-24 19:04:22 +00:00
return 0x7fffffffl ;
2006-11-13 23:12:47 +00:00
# endif
2006-04-13 20:47:06 +00:00
2006-11-17 05:05:16 +00:00
if ( nearest < 0 )
2006-04-24 19:04:22 +00:00
return - 1 ;
2006-04-13 20:47:06 +00:00
2006-04-24 19:04:22 +00:00
* x = validmode [ nearest ] . xdim ;
* y = validmode [ nearest ] . ydim ;
2006-04-13 20:47:06 +00:00
2014-11-22 12:33:47 +00:00
return nearest ;
2006-04-13 20:47:06 +00:00
}
2013-10-08 09:59:59 +00:00
static void destroy_window_resources ( )
Add prototypical SDL 2.X support.
Doesn't work: indexed-color modes, gamma (at least for X11), mouse wheel,
special keys like ENTER or BACKSPACE in the OSD, probably more...
In build/Makefile.shared, we now have logic to autodetect an SDL2 installed
in /usr/local, however OS X and Wii builds follow other Makefile code paths,
it seems. Note that the matching SDL2_mixer must be used then, too.
In source/jaudiolib/src/driver_sdl.c, change the #includes from <SDL/SDL_xxx.h>
to "SDL_xxx.h". SDL wiki says this is the most portable way, hopefully this
doesn't break builds for anyone.
git-svn-id: https://svn.eduke32.com/eduke32@2777 1a8010ca-5511-0410-912e-c29ae57300e0
2012-06-22 21:39:53 +00:00
{
2014-11-22 12:33:47 +00:00
/* We should NOT destroy the window surface. This is done automatically
when SDL_DestroyWindow or SDL_SetVideoMode is called . */
# if SDL_MAJOR_VERSION == 2
if ( sdl_context )
SDL_GL_DeleteContext ( sdl_context ) ;
sdl_context = NULL ;
if ( sdl_window )
SDL_DestroyWindow ( sdl_window ) ;
sdl_window = NULL ;
2013-10-07 10:06:09 +00:00
# endif
Add prototypical SDL 2.X support.
Doesn't work: indexed-color modes, gamma (at least for X11), mouse wheel,
special keys like ENTER or BACKSPACE in the OSD, probably more...
In build/Makefile.shared, we now have logic to autodetect an SDL2 installed
in /usr/local, however OS X and Wii builds follow other Makefile code paths,
it seems. Note that the matching SDL2_mixer must be used then, too.
In source/jaudiolib/src/driver_sdl.c, change the #includes from <SDL/SDL_xxx.h>
to "SDL_xxx.h". SDL wiki says this is the most portable way, hopefully this
doesn't break builds for anyone.
git-svn-id: https://svn.eduke32.com/eduke32@2777 1a8010ca-5511-0410-912e-c29ae57300e0
2012-06-22 21:39:53 +00:00
}
2006-04-13 20:47:06 +00:00
2014-11-22 12:33:47 +00:00
void sdlayer_setvideomode_opengl ( void )
{
2018-06-13 19:15:16 +00:00
glsurface_destroy ( ) ;
2014-11-22 12:33:47 +00:00
polymost_glreset ( ) ;
2019-09-23 21:33:59 +00:00
GLInterface . Deinit ( ) ;
GLInterface . Init ( ) ;
2019-10-10 19:05:10 +00:00
GLInterface . InitGLState ( 4 , glmultisample ) ;
2019-10-19 23:14:48 +00:00
// I have no idea how to get this info from the lookup tables. Fortunately it is consistent per game.
if ( ! currentGame . Compare ( " Blood " ) ) GLInterface . SetShadeDiv ( 62 ) ;
2019-10-22 21:31:46 +00:00
else if ( ! currentGame . Compare ( " IonFury " ) ) GLInterface . SetShadeDiv ( 30 ) ;
2019-10-19 23:14:48 +00:00
else GLInterface . SetShadeDiv ( 26 ) ;
2019-10-23 19:11:37 +00:00
GLInterface . mSamplers - > SetTextureFilterMode ( hw_texfilter , hw_anisotropy ) ;
2019-09-23 21:33:59 +00:00
2014-11-22 12:33:47 +00:00
}
2006-04-13 20:47:06 +00:00
//
// setvideomode() -- set SDL video mode
//
2014-11-22 12:33:47 +00:00
int32_t setvideomode_sdlcommon ( int32_t * x , int32_t * y , int32_t c , int32_t fs , int32_t * regrab )
2006-04-13 20:47:06 +00:00
{
2014-11-22 12:33:47 +00:00
if ( ( fs = = fullscreen ) & & ( * x = = xres ) & & ( * y = = yres ) & & ( c = = bpp ) & & ! videomodereset )
2006-04-24 19:04:22 +00:00
return 0 ;
2018-04-12 21:02:51 +00:00
if ( videoCheckMode ( x , y , c , fs , 0 ) < 0 )
2014-11-22 12:33:47 +00:00
return - 1 ;
2006-04-13 20:47:06 +00:00
2006-07-01 01:40:18 +00:00
startwin_close ( ) ;
2006-04-13 20:47:06 +00:00
2018-04-12 21:02:31 +00:00
if ( g_mouseGrabbed )
2006-11-17 05:05:16 +00:00
{
2014-11-22 12:33:47 +00:00
* regrab = 1 ;
2018-04-12 21:02:31 +00:00
mouseGrabInput ( 0 ) ;
2006-04-24 19:04:22 +00:00
}
2006-04-13 20:47:06 +00:00
2018-04-12 21:02:51 +00:00
while ( lockcount ) videoEndDrawing ( ) ;
2006-04-13 20:47:06 +00:00
2018-06-13 19:15:16 +00:00
if ( sdl_surface )
{
if ( bpp > 8 )
polymost_glreset ( ) ;
2018-07-14 21:36:34 +00:00
}
if ( ! nogl )
{
if ( bpp = = 8 )
2018-06-13 19:15:16 +00:00
glsurface_destroy ( ) ;
2018-07-14 21:36:34 +00:00
if ( ( fs = = fullscreen ) & & ( * x = = xres ) & & ( * y = = yres ) & & ( bpp ! = 0 ) & & ! videomodereset )
return 0 ;
2018-06-13 19:15:16 +00:00
}
2018-07-14 21:36:44 +00:00
else
{
softsurface_destroy ( ) ;
}
2006-04-13 20:47:06 +00:00
2014-11-22 12:33:47 +00:00
return 1 ;
}
void setvideomode_sdlcommonpost ( int32_t x , int32_t y , int32_t c , int32_t fs , int32_t regrab )
{
wm_setapptitle ( apptitle ) ;
# ifdef USE_OPENGL
2018-06-13 19:15:16 +00:00
if ( ! nogl )
2014-11-22 12:33:47 +00:00
sdlayer_setvideomode_opengl ( ) ;
# endif
xres = x ;
yres = y ;
bpp = c ;
fullscreen = fs ;
// bytesperline = sdl_surface->pitch;
numpages = c > 8 ? 2 : 1 ;
frameplace = 0 ;
lockcount = 0 ;
modechange = 1 ;
videomodereset = 0 ;
2018-04-12 21:03:12 +00:00
videoFadePalette ( palfadergb . r , palfadergb . g , palfadergb . b , palfadedelta ) ;
2014-11-22 12:33:47 +00:00
if ( regrab )
2018-04-12 21:02:31 +00:00
mouseGrabInput ( g_mouseLockedToWindow ) ;
2014-11-22 12:33:47 +00:00
}
# if SDL_MAJOR_VERSION!=1
2016-02-13 21:06:12 +00:00
void setrefreshrate ( void )
{
2019-08-29 20:06:31 +00:00
int const display = r_displayindex < SDL_GetNumVideoDisplays ( ) ? r_displayindex : 0 ;
2016-02-13 21:06:12 +00:00
SDL_DisplayMode dispmode ;
2019-08-29 20:06:31 +00:00
SDL_GetCurrentDisplayMode ( display , & dispmode ) ;
2016-02-13 21:06:12 +00:00
dispmode . refresh_rate = maxrefreshfreq ;
SDL_DisplayMode newmode ;
2019-08-29 20:06:31 +00:00
SDL_GetClosestDisplayMode ( display , & dispmode , & newmode ) ;
2016-02-13 21:06:12 +00:00
2019-08-27 13:39:54 +00:00
char error = 0 ;
2016-02-13 21:06:12 +00:00
if ( dispmode . refresh_rate ! = newmode . refresh_rate )
{
initprintf ( " Refresh rate: %dHz \n " , newmode . refresh_rate ) ;
2019-08-27 13:39:54 +00:00
error = SDL_SetWindowDisplayMode ( sdl_window , & newmode ) ;
2016-02-13 21:06:12 +00:00
}
2018-02-22 23:25:56 +00:00
2018-04-12 21:04:07 +00:00
if ( ! newmode . refresh_rate )
newmode . refresh_rate = 60 ;
2019-08-27 13:39:54 +00:00
refreshfreq = error ? - 1 : newmode . refresh_rate ;
2016-02-13 21:06:12 +00:00
}
2019-09-23 21:33:59 +00:00
int called = 0 ;
2018-04-12 21:02:51 +00:00
int32_t videoSetMode ( int32_t x , int32_t y , int32_t c , int32_t fs )
2014-11-22 12:33:47 +00:00
{
int32_t regrab = 0 , ret ;
2006-04-24 19:04:22 +00:00
2019-09-23 21:33:59 +00:00
if ( called + + )
{
assert ( 0 ) ;
}
2014-11-22 12:33:47 +00:00
ret = setvideomode_sdlcommon ( & x , & y , c , fs , & regrab ) ;
2018-07-14 21:36:34 +00:00
if ( ret ! = 1 )
{
if ( ret = = 0 )
{
setvideomode_sdlcommonpost ( x , y , c , fs , regrab ) ;
}
return ret ;
}
2014-11-22 12:33:47 +00:00
2013-10-08 09:59:59 +00:00
// deinit
destroy_window_resources ( ) ;
2014-11-22 12:33:47 +00:00
initprintf ( " Setting video mode %dx%d (%d-bpp %s) \n " , x , y , c , ( ( fs & 1 ) ? " fullscreen " : " windowed " ) ) ;
2019-08-29 20:06:31 +00:00
int const display = r_displayindex < SDL_GetNumVideoDisplays ( ) ? r_displayindex : 0 ;
2018-11-18 18:11:38 +00:00
SDL_DisplayMode desktopmode ;
2019-08-29 20:06:31 +00:00
SDL_GetDesktopDisplayMode ( display , & desktopmode ) ;
2018-11-18 18:11:38 +00:00
2019-08-29 19:00:52 +00:00
int const matchedResolution = ( desktopmode . w = = x & & desktopmode . h = = y ) ;
2019-08-29 20:06:31 +00:00
int const borderless = ( r_borderless = = 1 | | ( r_borderless = = 2 & & matchedResolution ) ) ? SDL_WINDOW_BORDERLESS : 0 ;
2011-03-04 08:50:58 +00:00
# ifdef USE_OPENGL
2018-06-13 19:15:16 +00:00
if ( c > 8 | | ! nogl )
2006-11-17 05:05:16 +00:00
{
2018-10-07 05:23:44 +00:00
int32_t i ;
2015-02-11 05:22:48 +00:00
int32_t multisamplecheck = ( glmultisample > 0 ) ;
2014-11-22 12:33:47 +00:00
if ( nogl )
return - 1 ;
2006-04-24 19:04:22 +00:00
2014-11-22 18:37:16 +00:00
struct glattribs
{
SDL_GLattr attr ;
int32_t value ;
2015-02-11 05:22:29 +00:00
} sdlayer_gl_attributes [ ] =
2014-11-22 18:37:16 +00:00
{
2015-02-11 05:22:29 +00:00
{ SDL_GL_DOUBLEBUFFER , 1 } ,
{ SDL_GL_MULTISAMPLEBUFFERS , glmultisample > 0 } ,
{ SDL_GL_MULTISAMPLESAMPLES , glmultisample } ,
2019-08-16 15:57:16 +00:00
{ SDL_GL_STENCIL_SIZE , 1 } ,
2015-02-11 05:22:29 +00:00
{ SDL_GL_ACCELERATED_VISUAL , 1 } ,
} ;
2012-11-25 04:26:37 +00:00
2006-11-17 05:05:16 +00:00
do
{
2014-11-22 12:33:47 +00:00
SDL_GL_ATTRIBUTES ( i , sdlayer_gl_attributes ) ;
2006-04-24 19:04:22 +00:00
2008-07-22 21:56:28 +00:00
/* HACK: changing SDL GL attribs only works before surface creation,
so we have to create a new surface in a different format first
to force the surface we WANT to be recreated instead of reused . */
2019-08-29 19:00:52 +00:00
2019-08-29 20:06:31 +00:00
sdl_window = SDL_CreateWindow ( " " , windowpos ? windowx : ( int ) SDL_WINDOWPOS_CENTERED_DISPLAY ( display ) ,
windowpos ? windowy : ( int ) SDL_WINDOWPOS_CENTERED_DISPLAY ( display ) , x , y ,
2019-08-29 19:00:52 +00:00
SDL_WINDOW_OPENGL | borderless ) ;
Add prototypical SDL 2.X support.
Doesn't work: indexed-color modes, gamma (at least for X11), mouse wheel,
special keys like ENTER or BACKSPACE in the OSD, probably more...
In build/Makefile.shared, we now have logic to autodetect an SDL2 installed
in /usr/local, however OS X and Wii builds follow other Makefile code paths,
it seems. Note that the matching SDL2_mixer must be used then, too.
In source/jaudiolib/src/driver_sdl.c, change the #includes from <SDL/SDL_xxx.h>
to "SDL_xxx.h". SDL wiki says this is the most portable way, hopefully this
doesn't break builds for anyone.
git-svn-id: https://svn.eduke32.com/eduke32@2777 1a8010ca-5511-0410-912e-c29ae57300e0
2012-06-22 21:39:53 +00:00
2014-11-22 12:33:47 +00:00
if ( sdl_window )
sdl_context = SDL_GL_CreateContext ( sdl_window ) ;
Add prototypical SDL 2.X support.
Doesn't work: indexed-color modes, gamma (at least for X11), mouse wheel,
special keys like ENTER or BACKSPACE in the OSD, probably more...
In build/Makefile.shared, we now have logic to autodetect an SDL2 installed
in /usr/local, however OS X and Wii builds follow other Makefile code paths,
it seems. Note that the matching SDL2_mixer must be used then, too.
In source/jaudiolib/src/driver_sdl.c, change the #includes from <SDL/SDL_xxx.h>
to "SDL_xxx.h". SDL wiki says this is the most portable way, hopefully this
doesn't break builds for anyone.
git-svn-id: https://svn.eduke32.com/eduke32@2777 1a8010ca-5511-0410-912e-c29ae57300e0
2012-06-22 21:39:53 +00:00
2014-11-22 12:33:47 +00:00
if ( ! sdl_window | | ! sdl_context )
2013-10-08 09:59:59 +00:00
{
2014-11-22 12:33:47 +00:00
initprintf ( " Unable to set video mode: %s failed: %s \n " , sdl_window ? " SDL_GL_CreateContext " : " SDL_GL_CreateWindow " , SDL_GetError ( ) ) ;
2019-08-29 19:00:52 +00:00
nogl = 1 ;
2013-10-08 09:59:59 +00:00
destroy_window_resources ( ) ;
Add prototypical SDL 2.X support.
Doesn't work: indexed-color modes, gamma (at least for X11), mouse wheel,
special keys like ENTER or BACKSPACE in the OSD, probably more...
In build/Makefile.shared, we now have logic to autodetect an SDL2 installed
in /usr/local, however OS X and Wii builds follow other Makefile code paths,
it seems. Note that the matching SDL2_mixer must be used then, too.
In source/jaudiolib/src/driver_sdl.c, change the #includes from <SDL/SDL_xxx.h>
to "SDL_xxx.h". SDL wiki says this is the most portable way, hopefully this
doesn't break builds for anyone.
git-svn-id: https://svn.eduke32.com/eduke32@2777 1a8010ca-5511-0410-912e-c29ae57300e0
2012-06-22 21:39:53 +00:00
return - 1 ;
2013-10-08 09:59:59 +00:00
}
2014-11-22 12:33:47 +00:00
2018-02-16 06:38:21 +00:00
gladLoadGLLoader ( SDL_GL_GetProcAddress ) ;
2018-06-13 19:15:22 +00:00
if ( GLVersion . major < 2 )
{
initprintf ( " Your computer does not support OpenGL version 2 or greater. GL modes are unavailable. \n " ) ;
nogl = 1 ;
destroy_window_resources ( ) ;
return - 1 ;
}
2018-02-26 14:46:36 +00:00
2019-08-29 19:00:52 +00:00
SDL_SetWindowFullscreen ( sdl_window , ( ( fs & 1 ) ? ( matchedResolution ? SDL_WINDOW_FULLSCREEN_DESKTOP : SDL_WINDOW_FULLSCREEN ) : 0 ) ) ;
2016-12-26 06:01:36 +00:00
SDL_GL_SetSwapInterval ( vsync_renderlayer ) ;
2013-10-08 09:59:59 +00:00
2016-02-13 21:06:12 +00:00
setrefreshrate ( ) ;
2014-11-22 12:33:47 +00:00
} while ( multisamplecheck - - ) ;
2006-11-17 05:05:16 +00:00
}
else
2011-09-10 15:44:53 +00:00
# endif // defined USE_OPENGL
2006-04-24 19:04:22 +00:00
{
Add prototypical SDL 2.X support.
Doesn't work: indexed-color modes, gamma (at least for X11), mouse wheel,
special keys like ENTER or BACKSPACE in the OSD, probably more...
In build/Makefile.shared, we now have logic to autodetect an SDL2 installed
in /usr/local, however OS X and Wii builds follow other Makefile code paths,
it seems. Note that the matching SDL2_mixer must be used then, too.
In source/jaudiolib/src/driver_sdl.c, change the #includes from <SDL/SDL_xxx.h>
to "SDL_xxx.h". SDL wiki says this is the most portable way, hopefully this
doesn't break builds for anyone.
git-svn-id: https://svn.eduke32.com/eduke32@2777 1a8010ca-5511-0410-912e-c29ae57300e0
2012-06-22 21:39:53 +00:00
// init
2019-08-29 20:06:31 +00:00
sdl_window = SDL_CreateWindow ( " " , windowpos ? windowx : ( int ) SDL_WINDOWPOS_CENTERED_DISPLAY ( display ) ,
windowpos ? windowy : ( int ) SDL_WINDOWPOS_CENTERED_DISPLAY ( display ) , x , y ,
2019-08-29 19:00:52 +00:00
borderless ) ;
2013-10-08 09:59:59 +00:00
if ( ! sdl_window )
2014-04-12 08:45:26 +00:00
SDL2_VIDEO_ERR ( " SDL_CreateWindow " ) ;
Add prototypical SDL 2.X support.
Doesn't work: indexed-color modes, gamma (at least for X11), mouse wheel,
special keys like ENTER or BACKSPACE in the OSD, probably more...
In build/Makefile.shared, we now have logic to autodetect an SDL2 installed
in /usr/local, however OS X and Wii builds follow other Makefile code paths,
it seems. Note that the matching SDL2_mixer must be used then, too.
In source/jaudiolib/src/driver_sdl.c, change the #includes from <SDL/SDL_xxx.h>
to "SDL_xxx.h". SDL wiki says this is the most portable way, hopefully this
doesn't break builds for anyone.
git-svn-id: https://svn.eduke32.com/eduke32@2777 1a8010ca-5511-0410-912e-c29ae57300e0
2012-06-22 21:39:53 +00:00
2016-02-13 21:06:12 +00:00
setrefreshrate ( ) ;
2014-01-12 14:05:56 +00:00
if ( ! sdl_surface )
{
sdl_surface = SDL_GetWindowSurface ( sdl_window ) ;
2014-11-22 12:33:47 +00:00
if ( ! sdl_surface )
SDL2_VIDEO_ERR ( " SDL_GetWindowSurface " ) ;
}
2006-04-24 19:04:22 +00:00
2019-08-29 19:00:52 +00:00
SDL_SetWindowFullscreen ( sdl_window , ( ( fs & 1 ) ? ( matchedResolution ? SDL_WINDOW_FULLSCREEN_DESKTOP : SDL_WINDOW_FULLSCREEN ) : 0 ) ) ;
2014-11-22 12:33:47 +00:00
}
2017-12-09 02:56:17 +00:00
SDL_SetHint ( SDL_HINT_VIDEO_HIGHDPI_DISABLED , " 1 " ) ;
2014-11-22 12:33:47 +00:00
setvideomode_sdlcommonpost ( x , y , c , fs , regrab ) ;
2006-04-24 19:04:22 +00:00
return 0 ;
2006-04-13 20:47:06 +00:00
}
2014-11-22 12:33:47 +00:00
# endif
2006-04-13 20:47:06 +00:00
//
// resetvideomode() -- resets the video system
//
2018-04-12 21:02:51 +00:00
void videoResetMode ( void )
2006-04-13 20:47:06 +00:00
{
2006-04-24 19:04:22 +00:00
videomodereset = 1 ;
modeschecked = 0 ;
2006-04-13 20:47:06 +00:00
}
//
// begindrawing() -- locks the framebuffer for drawing
//
2015-07-25 17:23:21 +00:00
2018-04-12 21:02:51 +00:00
void videoBeginDrawing ( void )
2006-04-13 20:47:06 +00:00
{
2006-11-17 05:05:16 +00:00
if ( bpp > 8 )
{
2006-04-24 19:04:22 +00:00
if ( offscreenrendering ) return ;
frameplace = 0 ;
bytesperline = 0 ;
modechange = 0 ;
return ;
}
2018-06-13 19:15:16 +00:00
2018-06-28 02:00:42 +00:00
// lock the frame
if ( lockcount + + > 0 )
return ;
2019-08-01 00:08:02 +00:00
static intptr_t backupFrameplace = 0 ;
2018-06-28 02:00:42 +00:00
2019-06-25 18:35:05 +00:00
if ( inpreparemirror )
{
2019-08-01 00:08:02 +00:00
//POGO: if we are offscreenrendering and we need to render a mirror
// or we are rendering a mirror and we start offscreenrendering,
// backup our offscreen target so we can restore it later
// (but only allow one level deep,
// i.e. no viewscreen showing a camera showing a mirror that reflects the same viewscreen and recursing)
if ( offscreenrendering )
{
if ( ! backupFrameplace )
backupFrameplace = frameplace ;
else if ( frameplace ! = ( intptr_t ) mirrorBuffer & &
frameplace ! = backupFrameplace )
return ;
}
2019-06-25 18:35:05 +00:00
frameplace = ( intptr_t ) mirrorBuffer ;
2019-08-01 00:08:02 +00:00
if ( offscreenrendering )
return ;
}
else if ( offscreenrendering )
{
if ( backupFrameplace )
{
frameplace = backupFrameplace ;
backupFrameplace = 0 ;
}
return ;
2019-06-25 18:35:05 +00:00
}
else
2018-07-14 21:36:44 +00:00
# ifdef USE_OPENGL
2018-06-28 02:00:42 +00:00
if ( ! nogl )
{
2018-06-13 19:15:16 +00:00
frameplace = ( intptr_t ) glsurface_getBuffer ( ) ;
}
2019-06-25 18:35:05 +00:00
else
2018-07-14 21:36:44 +00:00
# endif
2019-06-25 18:35:05 +00:00
{
frameplace = ( intptr_t ) softsurface_getBuffer ( ) ;
}
2006-04-24 19:04:22 +00:00
2018-07-14 21:36:44 +00:00
if ( modechange )
2006-11-17 05:05:16 +00:00
{
2018-07-14 21:36:44 +00:00
bytesperline = xdim ;
2012-12-14 19:28:17 +00:00
calc_ylookup ( bytesperline , ydim ) ;
2006-04-24 19:04:22 +00:00
modechange = 0 ;
}
2006-04-13 20:47:06 +00:00
}
//
// enddrawing() -- unlocks the framebuffer
//
2018-04-12 21:02:51 +00:00
void videoEndDrawing ( void )
2006-04-13 20:47:06 +00:00
{
2018-06-28 02:00:42 +00:00
if ( bpp > 8 )
2006-11-17 05:05:16 +00:00
{
2006-04-24 19:04:22 +00:00
if ( ! offscreenrendering ) frameplace = 0 ;
return ;
}
2006-04-13 20:47:06 +00:00
2006-04-24 19:04:22 +00:00
if ( ! frameplace ) return ;
2007-12-12 17:42:14 +00:00
if ( lockcount > 1 ) { lockcount - - ; return ; }
2006-04-24 19:04:22 +00:00
if ( ! offscreenrendering ) frameplace = 0 ;
if ( lockcount = = 0 ) return ;
lockcount = 0 ;
2006-04-13 20:47:06 +00:00
}
//
// showframe() -- update the display
//
2014-11-22 12:33:47 +00:00
# if SDL_MAJOR_VERSION != 1
2015-02-11 05:22:29 +00:00
2018-04-12 21:02:51 +00:00
void videoShowFrame ( int32_t w )
2006-04-13 20:47:06 +00:00
{
2008-03-23 00:06:42 +00:00
UNREFERENCED_PARAMETER ( w ) ;
2006-04-13 20:47:06 +00:00
2015-02-11 05:22:29 +00:00
2006-04-13 20:47:06 +00:00
# ifdef USE_OPENGL
2018-06-13 19:15:16 +00:00
if ( ! nogl )
2006-11-17 05:05:16 +00:00
{
2018-06-13 19:15:16 +00:00
if ( bpp > 8 )
{
if ( palfadedelta )
fullscreen_tint_gl ( palfadergb . r , palfadergb . g , palfadergb . b , palfadedelta ) ;
2019-09-19 21:02:57 +00:00
if ( playing_blood )
fullscreen_tint_gl_blood ( ) ;
2006-04-24 19:04:22 +00:00
2018-06-13 19:15:16 +00:00
}
else
{
2018-06-25 14:53:46 +00:00
glsurface_blitBuffer ( ) ;
2018-06-13 19:15:16 +00:00
}
2018-02-26 14:46:36 +00:00
2019-09-13 19:43:05 +00:00
static uint32_t lastSwapTime = 0 ;
# ifdef TIMING
cycle_t clock ;
clock . Reset ( ) ;
clock . Clock ( ) ;
# endif
glFinish ( ) ;
# ifdef TIMING
clock . Unclock ( ) ;
OSD_Printf ( " glfinish time: %2.3f \n " , clock . TimeMS ( ) ) ;
# endif
2013-10-07 10:04:02 +00:00
SDL_GL_SwapWindow ( sdl_window ) ;
2019-08-13 14:44:09 +00:00
2019-09-13 19:43:05 +00:00
lastSwapTime = SDL_GetTicks ( ) ;
2006-04-24 19:04:22 +00:00
return ;
}
2006-04-13 20:47:06 +00:00
# endif
2006-04-24 19:04:22 +00:00
if ( offscreenrendering ) return ;
2006-04-13 20:47:06 +00:00
2006-11-17 05:05:16 +00:00
if ( lockcount )
{
2007-12-12 17:42:14 +00:00
printf ( " Frame still locked %d times when showframe() called. \n " , lockcount ) ;
2018-04-12 21:02:51 +00:00
while ( lockcount ) videoEndDrawing ( ) ;
2006-04-24 19:04:22 +00:00
}
2018-07-14 21:36:44 +00:00
if ( SDL_MUSTLOCK ( sdl_surface ) ) SDL_LockSurface ( sdl_surface ) ;
softsurface_blitBuffer ( ( uint32_t * ) sdl_surface - > pixels , sdl_surface - > format - > BitsPerPixel ) ;
if ( SDL_MUSTLOCK ( sdl_surface ) ) SDL_UnlockSurface ( sdl_surface ) ;
2011-12-28 20:34:41 +00:00
2018-07-14 21:36:44 +00:00
if ( SDL_UpdateWindowSurface ( sdl_window ) )
2013-10-08 09:59:59 +00:00
{
// If a fullscreen X11 window is minimized then this may be required.
// FIXME: What to do if this fails...
sdl_surface = SDL_GetWindowSurface ( sdl_window ) ;
SDL_UpdateWindowSurface ( sdl_window ) ;
}
2006-04-13 20:47:06 +00:00
}
2014-11-22 12:33:47 +00:00
# endif
2006-04-13 20:47:06 +00:00
//
// setpalette() -- set palette values
//
2018-04-12 21:02:51 +00:00
int32_t videoUpdatePalette ( int32_t start , int32_t num )
2006-04-13 20:47:06 +00:00
{
2018-07-14 21:36:44 +00:00
UNREFERENCED_PARAMETER ( start ) ;
UNREFERENCED_PARAMETER ( num ) ;
2014-11-22 12:33:47 +00:00
if ( bpp > 8 )
return 0 ; // no palette in opengl
2006-04-24 19:04:22 +00:00
2018-07-14 21:36:44 +00:00
# ifdef USE_OPENGL
if ( ! nogl )
glsurface_setPalette ( curpalettefaded ) ;
else
2013-10-06 07:49:53 +00:00
# endif
2018-07-14 21:36:44 +00:00
{
if ( sdl_surface )
softsurface_setPalette ( curpalettefaded ,
sdl_surface - > format - > Rmask ,
sdl_surface - > format - > Gmask ,
sdl_surface - > format - > Bmask ) ;
}
2011-01-16 02:50:27 +00:00
2011-12-28 20:34:41 +00:00
return 0 ;
2006-04-13 20:47:06 +00:00
}
//
// setgamma
//
2018-04-12 21:02:51 +00:00
int32_t videoSetGamma ( void )
2006-04-13 20:47:06 +00:00
{
2018-04-12 21:02:51 +00:00
if ( novideo )
return 0 ;
2014-04-15 19:02:48 +00:00
2019-10-05 19:59:03 +00:00
return 1 ;
2006-04-13 20:47:06 +00:00
}
2014-12-27 18:36:14 +00:00
# if !defined __APPLE__ && !defined EDUKE32_TOUCH_DEVICES
2019-09-22 21:15:46 +00:00
extern struct sdlappicon sdlappicon ;
2014-11-22 12:34:29 +00:00
static inline SDL_Surface * loadappicon ( void )
2006-04-13 20:47:06 +00:00
{
2014-11-22 12:34:29 +00:00
SDL_Surface * surf = SDL_CreateRGBSurfaceFrom ( ( void * ) sdlappicon . pixels , sdlappicon . width , sdlappicon . height , 32 ,
sdlappicon . width * 4 , 0xffl , 0xff00l , 0xff0000l , 0xff000000l ) ;
2006-04-24 19:04:22 +00:00
return surf ;
2006-04-13 20:47:06 +00:00
}
# endif
//
//
// ---------------------------------------
//
// Miscellany
//
// ---------------------------------------
//
2006-04-24 19:04:22 +00:00
//
2006-04-13 20:47:06 +00:00
2012-09-15 15:28:30 +00:00
int32_t handleevents_peekkeys ( void )
{
SDL_PumpEvents ( ) ;
2014-11-22 12:33:47 +00:00
2013-10-06 07:49:53 +00:00
return SDL_PeepEvents ( NULL , 1 , SDL_PEEKEVENT , SDL_KEYDOWN , SDL_KEYDOWN ) ;
2012-09-15 15:28:30 +00:00
}
2014-12-27 18:36:43 +00:00
void handleevents_updatemousestate ( uint8_t state )
{
2018-04-12 21:02:31 +00:00
g_mouseClickState = state = = SDL_RELEASED ? MOUSE_RELEASED : MOUSE_PRESSED ;
2014-12-27 18:36:43 +00:00
}
2006-04-13 20:47:06 +00:00
//
// handleevents() -- process the SDL message queue
// returns !0 if there was an important event worth checking (like quitting)
//
2010-01-23 22:12:02 +00:00
2014-11-22 12:33:47 +00:00
int32_t handleevents_sdlcommon ( SDL_Event * ev )
2006-04-13 20:47:06 +00:00
{
2014-11-22 12:33:47 +00:00
switch ( ev - > type )
2006-11-17 05:05:16 +00:00
{
2014-11-22 12:33:47 +00:00
case SDL_MOUSEMOTION :
2018-04-12 21:02:31 +00:00
g_mouseAbs . x = ev - > motion . x ;
g_mouseAbs . y = ev - > motion . y ;
2014-11-22 12:33:47 +00:00
// SDL <VER> doesn't handle relative mouse movement correctly yet as the cursor still clips to the
// screen edges
// so, we call SDL_WarpMouse() to center the cursor and ignore the resulting motion event that occurs
// <VER> is 1.3 for PK, 1.2 for tueidj
2018-04-12 21:02:31 +00:00
if ( appactive & & g_mouseGrabbed )
2008-10-20 12:33:29 +00:00
{
{
2018-04-12 21:02:31 +00:00
g_mousePos . x + = ev - > motion . xrel ;
g_mousePos . y + = ev - > motion . yrel ;
2006-04-24 19:04:22 +00:00
}
}
break ;
case SDL_MOUSEBUTTONDOWN :
case SDL_MOUSEBUTTONUP :
2015-04-28 21:30:42 +00:00
{
int32_t j ;
2016-06-05 04:46:28 +00:00
2014-11-22 12:33:47 +00:00
// some of these get reordered to match winlayer
switch ( ev - > button . button )
2006-11-17 05:05:16 +00:00
{
2014-11-22 12:33:47 +00:00
default : j = - 1 ; break ;
2014-12-27 18:36:43 +00:00
case SDL_BUTTON_LEFT : j = 0 ; handleevents_updatemousestate ( ev - > button . state ) ; break ;
2014-11-22 12:33:47 +00:00
case SDL_BUTTON_RIGHT : j = 1 ; break ;
case SDL_BUTTON_MIDDLE : j = 2 ; break ;
2013-12-01 18:28:03 +00:00
2014-11-22 18:37:16 +00:00
/* Thumb buttons. */
2019-08-21 03:18:23 +00:00
// On SDL2/Windows and SDL >= 2.0.?/Linux, everything is as it should be.
// If anyone cares about old versions of SDL2 on Linux, patches welcome.
2014-11-22 12:33:47 +00:00
case SDL_BUTTON_X1 : j = 3 ; break ;
case SDL_BUTTON_X2 : j = 6 ; break ;
2006-04-24 19:04:22 +00:00
}
2014-11-22 12:33:47 +00:00
if ( j < 0 )
break ;
if ( ev - > button . state = = SDL_PRESSED )
2018-04-12 21:02:31 +00:00
g_mouseBits | = ( 1 < < j ) ;
2006-11-17 05:05:16 +00:00
else
2019-09-10 17:06:20 +00:00
g_mouseBits & = ~ ( 1 < < j ) ;
2006-04-24 19:04:22 +00:00
2018-04-12 21:02:31 +00:00
if ( g_mouseCallback )
g_mouseCallback ( j + 1 , ev - > button . state = = SDL_PRESSED ) ;
2006-04-24 19:04:22 +00:00
break ;
2015-04-28 21:30:42 +00:00
}
2019-08-14 15:28:59 +00:00
2006-04-24 19:04:22 +00:00
case SDL_JOYAXISMOTION :
2019-08-12 15:23:15 +00:00
# if SDL_MAJOR_VERSION >= 2
if ( joystick . isGameController )
break ;
fallthrough__ ;
case SDL_CONTROLLERAXISMOTION :
# endif
2018-04-12 21:02:31 +00:00
if ( appactive & & ev - > jaxis . axis < joystick . numAxes )
2010-10-21 02:20:40 +00:00
{
2019-08-12 15:23:07 +00:00
joystick . pAxis [ ev - > jaxis . axis ] = ev - > jaxis . value ;
int32_t const scaledValue = ev - > jaxis . value * 10000 / 32767 ;
if ( ( scaledValue < joydead [ ev - > jaxis . axis ] ) & &
( scaledValue > - joydead [ ev - > jaxis . axis ] ) )
2018-04-12 21:02:31 +00:00
joystick . pAxis [ ev - > jaxis . axis ] = 0 ;
2019-08-12 15:23:07 +00:00
else if ( scaledValue > = joysatur [ ev - > jaxis . axis ] )
joystick . pAxis [ ev - > jaxis . axis ] = 32767 ;
else if ( scaledValue < = - joysatur [ ev - > jaxis . axis ] )
joystick . pAxis [ ev - > jaxis . axis ] = - 32767 ;
2010-10-21 02:20:40 +00:00
else
2018-04-12 21:02:31 +00:00
joystick . pAxis [ ev - > jaxis . axis ] = joystick . pAxis [ ev - > jaxis . axis ] * 10000 / joysatur [ ev - > jaxis . axis ] ;
2010-10-21 02:20:40 +00:00
}
2006-04-24 19:04:22 +00:00
break ;
2006-11-17 05:05:16 +00:00
case SDL_JOYHATMOTION :
{
2014-11-22 12:33:47 +00:00
int32_t hatvals [ 16 ] = {
- 1 , // centre
0 , // up 1
9000 , // right 2
4500 , // up+right 3
18000 , // down 4
- 1 , // down+up!! 5
13500 , // down+right 6
- 1 , // down+right+up!! 7
27000 , // left 8
27500 , // left+up 9
- 1 , // left+right!! 10
- 1 , // left+right+up!! 11
22500 , // left+down 12
- 1 , // left+down+up!! 13
- 1 , // left+down+right!! 14
- 1 , // left+down+right+up!! 15
2007-12-12 17:42:14 +00:00
} ;
2018-04-12 21:02:31 +00:00
if ( appactive & & ev - > jhat . hat < joystick . numHats )
joystick . pHat [ ev - > jhat . hat ] = hatvals [ ev - > jhat . value & 15 ] ;
2006-11-13 23:12:47 +00:00
break ;
}
2006-04-24 19:04:22 +00:00
case SDL_JOYBUTTONDOWN :
case SDL_JOYBUTTONUP :
2019-08-12 15:23:15 +00:00
# if SDL_MAJOR_VERSION >= 2
if ( joystick . isGameController )
break ;
fallthrough__ ;
case SDL_CONTROLLERBUTTONDOWN :
case SDL_CONTROLLERBUTTONUP :
# endif
2018-04-12 21:02:31 +00:00
if ( appactive & & ev - > jbutton . button < joystick . numButtons )
2006-11-17 05:05:16 +00:00
{
2014-11-22 12:33:47 +00:00
if ( ev - > jbutton . state = = SDL_PRESSED )
2018-04-12 21:02:31 +00:00
joystick . bits | = 1 < < ev - > jbutton . button ;
2006-04-24 19:04:22 +00:00
else
2018-04-12 21:02:31 +00:00
joystick . bits & = ~ ( 1 < < ev - > jbutton . button ) ;
2014-12-27 18:36:43 +00:00
2006-04-24 19:04:22 +00:00
}
break ;
case SDL_QUIT :
quitevent = 1 ;
2014-11-22 12:33:47 +00:00
return - 1 ;
2006-04-24 19:04:22 +00:00
}
2014-11-22 12:33:47 +00:00
return 0 ;
}
2010-05-18 05:14:17 +00:00
2014-11-28 08:12:40 +00:00
int32_t handleevents_pollsdl ( void ) ;
2014-11-22 12:33:47 +00:00
# if SDL_MAJOR_VERSION != 1
// SDL 2.0 specific event handling
int32_t handleevents_pollsdl ( void )
{
int32_t code , rv = 0 , j ;
SDL_Event ev ;
2006-08-07 06:18:57 +00:00
2014-11-22 12:33:47 +00:00
while ( SDL_PollEvent ( & ev ) )
{
switch ( ev . type )
{
case SDL_TEXTINPUT :
j = 0 ;
do
{
code = ev . text . text [ j ] ;
2018-04-12 21:02:31 +00:00
if ( code ! = g_keyAsciiTable [ OSD_OSDKey ( ) ] & & ! keyBufferFull ( ) )
2014-11-22 12:33:47 +00:00
{
if ( OSD_HandleChar ( code ) )
2018-04-12 21:02:31 +00:00
keyBufferInsert ( code ) ;
2014-11-22 12:33:47 +00:00
}
2018-10-25 23:29:04 +00:00
} while ( j < SDL_TEXTINPUTEVENT_TEXT_SIZE - 1 & & ev . text . text [ + + j ] ) ;
2014-11-22 12:33:47 +00:00
break ;
case SDL_KEYDOWN :
case SDL_KEYUP :
2015-08-09 09:58:45 +00:00
{
2018-11-18 18:07:10 +00:00
auto const & sc = ev . key . keysym . scancode ;
2015-08-09 09:58:45 +00:00
code = keytranslation [ sc ] ;
2014-11-22 12:33:47 +00:00
2016-07-04 14:09:06 +00:00
// Modifiers that have to be held down to be effective
// (excludes KMOD_NUM, for example).
static const int MODIFIERS =
KMOD_LSHIFT | KMOD_RSHIFT | KMOD_LCTRL | KMOD_RCTRL |
KMOD_LALT | KMOD_RALT | KMOD_LGUI | KMOD_RGUI ;
2014-11-22 12:33:47 +00:00
// XXX: see osd.c, OSD_HandleChar(), there are more...
2018-04-12 21:02:31 +00:00
if ( ev . key . type = = SDL_KEYDOWN & & ! keyBufferFull ( ) & &
2015-08-09 09:58:45 +00:00
( sc = = SDL_SCANCODE_RETURN | | sc = = SDL_SCANCODE_KP_ENTER | |
sc = = SDL_SCANCODE_ESCAPE | |
sc = = SDL_SCANCODE_BACKSPACE | |
sc = = SDL_SCANCODE_TAB | |
2016-07-04 14:09:06 +00:00
( ( ( ev . key . keysym . mod ) & MODIFIERS ) = = KMOD_LCTRL & &
2015-08-09 09:58:45 +00:00
( sc > = SDL_SCANCODE_A & & sc < = SDL_SCANCODE_Z ) ) ) )
2014-11-22 12:33:47 +00:00
{
char keyvalue ;
2015-08-09 09:58:45 +00:00
switch ( sc )
2014-11-22 12:33:47 +00:00
{
case SDL_SCANCODE_RETURN : case SDL_SCANCODE_KP_ENTER : keyvalue = ' \r ' ; break ;
case SDL_SCANCODE_ESCAPE : keyvalue = 27 ; break ;
case SDL_SCANCODE_BACKSPACE : keyvalue = ' \b ' ; break ;
case SDL_SCANCODE_TAB : keyvalue = ' \t ' ; break ;
2015-08-09 09:58:45 +00:00
default : keyvalue = sc - SDL_SCANCODE_A + 1 ; break ; // Ctrl+A --> 1, etc.
2014-11-22 12:33:47 +00:00
}
if ( OSD_HandleChar ( keyvalue ) )
2018-04-12 21:02:31 +00:00
keyBufferInsert ( keyvalue ) ;
2014-11-22 12:33:47 +00:00
}
2017-01-23 11:20:17 +00:00
else if ( ev . key . type = = SDL_KEYDOWN & &
2018-04-12 21:02:31 +00:00
ev . key . keysym . sym ! = g_keyAsciiTable [ OSD_OSDKey ( ) ] & & ! keyBufferFull ( ) & &
2016-12-26 06:02:38 +00:00
! SDL_IsTextInputActive ( ) )
{
/*
Necessary for Duke 3 D ' s method of entering cheats to work without showing IMEs .
SDL_TEXTINPUT is preferable overall , but with bitmap fonts it has no advantage .
*/
2017-01-23 11:20:17 +00:00
SDL_Keycode keyvalue = ev . key . keysym . sym ;
2016-12-26 06:02:38 +00:00
if ( ' a ' < = keyvalue & & keyvalue < = ' z ' )
{
if ( ! ! ( ev . key . keysym . mod & KMOD_SHIFT ) ^ ! ! ( ev . key . keysym . mod & KMOD_CAPS ) )
keyvalue - = ' a ' - ' A ' ;
}
else if ( ev . key . keysym . mod & KMOD_SHIFT )
{
switch ( keyvalue )
{
case ' \' ' : keyvalue = ' " ' ; break ;
case ' , ' : keyvalue = ' < ' ; break ;
case ' - ' : keyvalue = ' _ ' ; break ;
case ' . ' : keyvalue = ' > ' ; break ;
case ' / ' : keyvalue = ' ? ' ; break ;
case ' 0 ' : keyvalue = ' ) ' ; break ;
case ' 1 ' : keyvalue = ' ! ' ; break ;
case ' 2 ' : keyvalue = ' @ ' ; break ;
case ' 3 ' : keyvalue = ' # ' ; break ;
case ' 4 ' : keyvalue = ' $ ' ; break ;
case ' 5 ' : keyvalue = ' % ' ; break ;
case ' 6 ' : keyvalue = ' ^ ' ; break ;
case ' 7 ' : keyvalue = ' & ' ; break ;
case ' 8 ' : keyvalue = ' * ' ; break ;
case ' 9 ' : keyvalue = ' ( ' ; break ;
case ' ; ' : keyvalue = ' : ' ; break ;
case ' = ' : keyvalue = ' + ' ; break ;
case ' [ ' : keyvalue = ' { ' ; break ;
case ' \\ ' : keyvalue = ' | ' ; break ;
case ' ] ' : keyvalue = ' } ' ; break ;
case ' ` ' : keyvalue = ' ~ ' ; break ;
}
}
2017-01-23 11:20:17 +00:00
else if ( ev . key . keysym . mod & KMOD_NUM ) // && !(ev.key.keysym.mod & KMOD_SHIFT)
{
switch ( keyvalue )
{
case SDLK_KP_1 : keyvalue = ' 1 ' ; break ;
case SDLK_KP_2 : keyvalue = ' 2 ' ; break ;
case SDLK_KP_3 : keyvalue = ' 3 ' ; break ;
case SDLK_KP_4 : keyvalue = ' 4 ' ; break ;
case SDLK_KP_5 : keyvalue = ' 5 ' ; break ;
case SDLK_KP_6 : keyvalue = ' 6 ' ; break ;
case SDLK_KP_7 : keyvalue = ' 7 ' ; break ;
case SDLK_KP_8 : keyvalue = ' 8 ' ; break ;
case SDLK_KP_9 : keyvalue = ' 9 ' ; break ;
case SDLK_KP_0 : keyvalue = ' 0 ' ; break ;
case SDLK_KP_PERIOD : keyvalue = ' . ' ; break ;
case SDLK_KP_COMMA : keyvalue = ' , ' ; break ;
}
}
2016-12-26 06:02:38 +00:00
2017-01-23 11:20:17 +00:00
switch ( keyvalue )
{
case SDLK_KP_DIVIDE : keyvalue = ' / ' ; break ;
case SDLK_KP_MULTIPLY : keyvalue = ' * ' ; break ;
case SDLK_KP_MINUS : keyvalue = ' - ' ; break ;
case SDLK_KP_PLUS : keyvalue = ' + ' ; break ;
}
if ( ( unsigned ) keyvalue < = 0x7Fu )
{
if ( OSD_HandleChar ( keyvalue ) )
2018-04-12 21:02:31 +00:00
keyBufferInsert ( keyvalue ) ;
2017-01-23 11:20:17 +00:00
}
2016-12-26 06:02:38 +00:00
}
2014-11-22 12:33:47 +00:00
// initprintf("SDL2: got key %d, %d, %u\n", ev.key.keysym.scancode, code, ev.key.type);
// hook in the osd
if ( ( j = OSD_HandleScanCode ( code , ( ev . key . type = = SDL_KEYDOWN ) ) ) < = 0 )
{
if ( j = = - 1 ) // osdkey
2018-11-18 18:07:10 +00:00
{
2018-04-12 21:02:31 +00:00
for ( j = 0 ; j < NUMKEYS ; + + j )
2018-11-18 18:07:10 +00:00
{
2018-04-12 21:02:31 +00:00
if ( keyGetState ( j ) )
2014-11-22 12:33:47 +00:00
{
if ( keypresscallback )
keypresscallback ( j , 0 ) ;
}
2019-09-19 20:02:45 +00:00
keySetState ( j , 0 ) ;
2018-11-18 18:07:10 +00:00
}
}
2014-11-22 12:33:47 +00:00
break ;
}
if ( ev . key . type = = SDL_KEYDOWN )
{
2018-04-12 21:02:31 +00:00
if ( ! keyGetState ( code ) )
2014-11-22 12:33:47 +00:00
{
if ( keypresscallback )
keypresscallback ( code , 1 ) ;
}
2019-09-19 20:02:45 +00:00
keySetState ( code , 1 ) ;
2014-11-22 12:33:47 +00:00
}
else
{
# if 1
// The pause key generates a release event right after
// the pressing one. As a result, it gets unseen
// by the game most of the time.
if ( code = = 0x59 ) // pause
break ;
# endif
2018-04-12 21:02:31 +00:00
keySetState ( code , 0 ) ;
2014-11-22 12:33:47 +00:00
if ( keypresscallback )
keypresscallback ( code , 0 ) ;
}
break ;
2015-08-09 09:58:45 +00:00
}
2014-11-22 12:33:47 +00:00
case SDL_MOUSEWHEEL :
// initprintf("wheel y %d\n",ev.wheel.y);
if ( ev . wheel . y > 0 )
{
2018-04-12 21:02:31 +00:00
g_mouseBits | = 16 ;
if ( g_mouseCallback )
g_mouseCallback ( 5 , 1 ) ;
2014-11-22 12:33:47 +00:00
}
if ( ev . wheel . y < 0 )
{
2018-04-12 21:02:31 +00:00
g_mouseBits | = 32 ;
if ( g_mouseCallback )
g_mouseCallback ( 6 , 1 ) ;
2014-11-22 12:33:47 +00:00
}
break ;
case SDL_WINDOWEVENT :
switch ( ev . window . event )
{
case SDL_WINDOWEVENT_FOCUS_GAINED :
case SDL_WINDOWEVENT_FOCUS_LOST :
appactive = ( ev . window . event = = SDL_WINDOWEVENT_FOCUS_GAINED ) ;
2018-04-12 21:02:31 +00:00
if ( g_mouseGrabbed & & g_mouseEnabled )
2014-11-22 12:33:47 +00:00
grabmouse_low ( appactive ) ;
break ;
case SDL_WINDOWEVENT_MOVED :
2019-08-29 20:06:31 +00:00
{
2014-11-22 12:33:47 +00:00
if ( windowpos )
{
windowx = ev . window . data1 ;
windowy = ev . window . data2 ;
}
2019-08-29 20:06:31 +00:00
r_displayindex = SDL_GetWindowDisplayIndex ( sdl_window ) ;
modeschecked = 0 ;
videoGetModes ( ) ;
2014-11-22 12:33:47 +00:00
break ;
2019-08-29 20:06:31 +00:00
}
2014-11-22 12:34:46 +00:00
case SDL_WINDOWEVENT_ENTER :
2018-04-12 21:02:31 +00:00
g_mouseInsideWindow = 1 ;
2014-11-22 12:34:46 +00:00
break ;
case SDL_WINDOWEVENT_LEAVE :
2018-04-12 21:02:31 +00:00
g_mouseInsideWindow = 0 ;
2014-11-22 12:34:46 +00:00
break ;
2014-11-22 12:33:47 +00:00
}
2019-08-29 20:06:31 +00:00
2014-11-22 12:33:47 +00:00
break ;
2006-04-13 20:47:06 +00:00
2014-11-22 12:33:47 +00:00
default :
rv = handleevents_sdlcommon ( & ev ) ;
break ;
}
}
2006-04-13 20:47:06 +00:00
2006-04-24 19:04:22 +00:00
return rv ;
2006-04-13 20:47:06 +00:00
}
2014-11-22 12:33:47 +00:00
# endif
2006-04-13 20:47:06 +00:00
2014-11-22 12:33:47 +00:00
int32_t handleevents ( void )
2010-05-18 05:14:17 +00:00
{
2014-11-22 12:33:47 +00:00
int32_t rv ;
2010-05-18 05:14:17 +00:00
2018-04-12 21:02:31 +00:00
if ( inputchecked & & g_mouseEnabled )
2011-01-16 02:50:27 +00:00
{
2018-04-12 21:02:31 +00:00
if ( g_mouseCallback )
2011-01-16 02:50:27 +00:00
{
2018-04-12 21:02:31 +00:00
if ( g_mouseBits & 16 )
g_mouseCallback ( 5 , 0 ) ;
if ( g_mouseBits & 32 )
g_mouseCallback ( 6 , 0 ) ;
2010-05-18 05:14:17 +00:00
}
2018-04-12 21:02:31 +00:00
g_mouseBits & = ~ ( 16 | 32 ) ;
2010-05-18 05:14:17 +00:00
}
2014-11-22 12:33:47 +00:00
rv = handleevents_pollsdl ( ) ;
inputchecked = 0 ;
2019-10-19 23:43:35 +00:00
timerUpdateClock ( ) ;
2014-11-22 12:33:47 +00:00
# ifndef _WIN32
startwin_idle ( NULL ) ;
2010-05-18 05:14:17 +00:00
# endif
2014-11-22 12:33:47 +00:00
return rv ;
}
2019-09-22 21:15:46 +00:00
auto vsnprintfptr = vsnprintf ; // This is an inline in Visual Studio but we need an address for it to satisfy the MinGW compiled libraries.