raze-gles/source/build/src/sdlayer.cpp

407 lines
8.6 KiB
C++
Raw Normal View History

// SDL interface layer for the Build Engine
// Use SDL 1.2 or 2.0 from http://www.libsdl.org
#include <Windows.h>
#include <CommCtrl.h>
#include <signal.h>
#include <string>
#include <stdexcept>
# include "gl_load.h"
#include "a.h"
#include "build.h"
2019-09-19 21:02:57 +00:00
#include "common.h"
#include "compat.h"
#include "engine_priv.h"
#include "osd.h"
#include "palette.h"
#include "renderlayer.h"
#include "sdl_inc.h"
#include "softsurface.h"
#include "m_argv.h"
2019-09-25 21:00:10 +00:00
#include "mmulti.h"
#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"
#include "i_specialpaths.h"
2019-10-28 00:12:31 +00:00
#include "inputstate.h"
#include "c_cvars.h"
2019-11-04 19:29:07 +00:00
#include "i_time.h"
2019-11-05 19:07:16 +00:00
#include "c_dispatch.h"
2019-11-07 19:31:16 +00:00
#include "d_gui.h"
#include "menu.h"
2019-11-07 19:31:16 +00:00
#include "utf8.h"
#include "imgui.h"
#include "imgui_impl_sdl.h"
#include "imgui_impl_opengl3.h"
#ifndef NETCODE_DISABLE
#include "enet.h"
#endif
#include "../../glbackend/glbackend.h"
#ifdef USE_OPENGL
# include "glbuild.h"
# include "glsurface.h"
#endif
#if defined HAVE_GTK2
# include "gtkbits.h"
#endif
2019-09-10 17:06:20 +00:00
#if defined __APPLE__
# include "osxbits.h"
# include <mach/mach.h>
# include <mach/mach_time.h>
#endif
FString progdir;
CVAR(Int, r_displayindex, 0, CVAR_ARCHIVE | CVAR_VIDEOCONFIG)
CVAR(Int, r_borderless, 2, CVAR_ARCHIVE | CVAR_VIDEOCONFIG)
CVAR(Int, maxrefreshfreq, 0, CVAR_ARCHIVE | CVAR_VIDEOCONFIG)
CVAR(Int, windowpos, 0, CVAR_ARCHIVE | CVAR_VIDEOCONFIG)
CVAR(Int, windowx, -1, CVAR_ARCHIVE | CVAR_VIDEOCONFIG)
CVAR(Int, windowy, -1, CVAR_ARCHIVE | CVAR_VIDEOCONFIG)
#if SDL_MAJOR_VERSION != 1
static SDL_version linked;
#endif
double g_beforeSwapTime;
GameInterface* gi;
void buildkeytranslationtable();;
2019-09-25 21:00:10 +00:00
int myconnectindex, numplayers;
int connecthead, connectpoint2[MAXMULTIPLAYERS];
unsigned char syncstate;
/// 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)
#define SURFACE_FLAGS (SDL_SWSURFACE|SDL_HWPALETTE|SDL_HWACCEL)
// undefine to restrict windowed resolutions to conventional sizes
#define ANY_WINDOWED_SIZE
// fix for mousewheel
int32_t inputchecked = 0;
bool screenshot_requested;
char appactive=1, novideo=0;
// video
static SDL_Surface *sdl_surface/*=NULL*/;
#if SDL_MAJOR_VERSION==2
2019-11-07 19:31:16 +00:00
SDL_Window *sdl_window=NULL;
SDL_GLContext sdl_context=NULL;
#endif
2019-11-07 19:31:16 +00:00
void ImGui_Init_Backend()
{
ImGui_ImplSDL2_InitForOpenGL(sdl_window, sdl_context);
}
void ImGui_Begin_Frame()
{
ImGui_ImplOpenGL3_NewFrame();
ImGui_ImplSDL2_NewFrame(sdl_window);
ImGui::NewFrame();
}
int32_t xres=-1, yres=-1, bpp=0, fullscreen=0, bytesperline, refreshfreq=-1;
intptr_t frameplace=0;
int32_t lockcount=0;
char modechange=1;
char offscreenrendering=0;
char videomodereset = 0;
static uint16_t sysgamma[3][256];
#ifdef USE_OPENGL
// OpenGL stuff
char nogl=0;
#endif
static int32_t vsync_renderlayer;
// last gamma, contrast, brightness
//#define KEY_PRINT_DEBUG
static SDL_Surface *appicon = NULL;
#if !defined __APPLE__ && !defined EDUKE32_TOUCH_DEVICES
static SDL_Surface *loadappicon(void);
#endif
// Joystick dead and saturation zones
uint16_t joydead[9], joysatur[9];
#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);
vsnprintf(errortext, MAX_ERRORTEXT, error, argptr);
va_end(argptr);
#ifdef _WIN32
OutputDebugStringA(errortext);
#endif
throw std::runtime_error(errortext);
}
void I_FatalError(const char* error, ...)
{
va_list argptr;
char errortext[MAX_ERRORTEXT];
va_start(argptr, error);
vsnprintf(errortext, MAX_ERRORTEXT, error, argptr);
va_end(argptr);
#ifdef _WIN32
OutputDebugStringA(errortext);
#endif
throw std::runtime_error(errortext);
}
#ifdef _WIN32
# if SDL_MAJOR_VERSION != 1
//
// win_gethwnd() -- gets the window handle
//
HWND win_gethwnd(void)
{
struct SDL_SysWMinfo wmInfo;
SDL_VERSION(&wmInfo.version);
if (SDL_GetWindowWMInfo(sdl_window, &wmInfo) != SDL_TRUE)
return 0;
if (wmInfo.subsystem == SDL_SYSWM_WINDOWS)
return wmInfo.info.win.window;
initprintf("win_gethwnd: Unknown WM subsystem?!\n");
return 0;
}
# endif
//
// 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)
{
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);
}
#endif
int32_t wm_msgbox(const char *name, const char *fmt, ...)
{
char buf[2048];
va_list va;
UNREFERENCED_PARAMETER(name);
va_start(va,fmt);
vsnprintf(buf,sizeof(buf),fmt,va);
va_end(va);
#if defined EDUKE32_OSX
return osx_msgbox(name, buf);
#elif defined _WIN32
MessageBoxA(win_gethwnd(),buf,name,MB_OK|MB_TASKMODAL);
return 0;
#elif defined EDUKE32_TOUCH_DEVICES
initprintf("wm_msgbox called. Message: %s: %s",name,buf);
return 0;
#elif defined GEKKO
puts(buf);
return 0;
#else
# 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
puts(buf);
puts(" (press Return or Enter to continue)");
getchar();
return 0;
# endif
#endif
}
void videoResetMode(void)
{
videomodereset = 1;
}
//
// begindrawing() -- locks the framebuffer for drawing
//
void videoBeginDrawing(void)
{
if (bpp > 8)
{
if (offscreenrendering) return;
frameplace = 0;
bytesperline = 0;
modechange = 0;
return;
}
// lock the frame
if (lockcount++ > 0)
return;
static intptr_t backupFrameplace = 0;
if (inpreparemirror)
{
//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;
}
frameplace = (intptr_t)mirrorBuffer;
if (offscreenrendering)
return;
}
else if (offscreenrendering)
{
if (backupFrameplace)
{
frameplace = backupFrameplace;
backupFrameplace = 0;
}
return;
}
else
#ifdef USE_OPENGL
if (!nogl)
{
frameplace = (intptr_t)glsurface_getBuffer();
}
else
#endif
{
frameplace = (intptr_t)softsurface_getBuffer();
}
if (modechange)
{
bytesperline = xdim;
calc_ylookup(bytesperline, ydim);
modechange=0;
}
}
//
// enddrawing() -- unlocks the framebuffer
//
void videoEndDrawing(void)
{
if (bpp > 8)
{
if (!offscreenrendering) frameplace = 0;
return;
}
if (!frameplace) return;
if (lockcount > 1) { lockcount--; return; }
if (!offscreenrendering) frameplace = 0;
if (lockcount == 0) return;
lockcount = 0;
}
//
// showframe() -- update the display
//
#if !defined __APPLE__ && !defined EDUKE32_TOUCH_DEVICES
extern struct sdlappicon sdlappicon;
static inline SDL_Surface *loadappicon(void)
{
SDL_Surface *surf = SDL_CreateRGBSurfaceFrom((void *)sdlappicon.pixels, sdlappicon.width, sdlappicon.height, 32,
sdlappicon.width * 4, 0xffl, 0xff00l, 0xff0000l, 0xff000000l);
return surf;
}
#endif
//
//
// ---------------------------------------
//
// Miscellany
//
// ---------------------------------------
//
//
auto vsnprintfptr = vsnprintf; // This is an inline in Visual Studio but we need an address for it to satisfy the MinGW compiled libraries.
2019-11-20 19:07:33 +00:00
//
// debugprintf() -- sends a debug string to the debugger
//
void debugprintf(const char* f, ...)
{
va_list va;
char buf[1024];
if (!IsDebuggerPresent()) return;
va_start(va, f);
Bvsnprintf(buf, 1024, f, va);
va_end(va);
OutputDebugStringA(buf);
}