From 891b3da1038a0a3cb759e39678881d480c2bed82 Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Thu, 7 Aug 2014 22:43:23 -0500 Subject: [PATCH 01/46] Remove extra magnitude from magic texture mapping values - These used to be fixed point, but now they're floating point, so the excess magnitude is unneeded. --- src/r_bsp.cpp | 24 ++++++++++++------------ src/r_main.cpp | 4 +--- src/r_main.h | 1 - 3 files changed, 13 insertions(+), 16 deletions(-) diff --git a/src/r_bsp.cpp b/src/r_bsp.cpp index c56255888..146ea5673 100644 --- a/src/r_bsp.cpp +++ b/src/r_bsp.cpp @@ -809,17 +809,17 @@ void FWallTmapVals::InitFromWallCoords(const FWallCoords *wallc) { if (MirrorFlags & RF_XFLIP) { - UoverZorg = (float)wallc->tx2 * WallTMapScale; - UoverZstep = (float)(-wallc->ty2) * 32.f; - InvZorg = (float)(wallc->tx2 - wallc->tx1) * WallTMapScale; - InvZstep = (float)(wallc->ty1 - wallc->ty2) * 32.f; + UoverZorg = (float)wallc->tx2 * centerx; + UoverZstep = (float)(-wallc->ty2); + InvZorg = (float)(wallc->tx2 - wallc->tx1) * centerx; + InvZstep = (float)(wallc->ty1 - wallc->ty2); } else { - UoverZorg = (float)wallc->tx1 * WallTMapScale; - UoverZstep = (float)(-wallc->ty1) * 32.f; - InvZorg = (float)(wallc->tx1 - wallc->tx2) * WallTMapScale; - InvZstep = (float)(wallc->ty2 - wallc->ty1) * 32.f; + UoverZorg = (float)wallc->tx1 * centerx; + UoverZstep = (float)(-wallc->ty1); + InvZorg = (float)(wallc->tx1 - wallc->tx2) * centerx; + InvZstep = (float)(wallc->ty2 - wallc->ty1); } InitDepth(); } @@ -837,10 +837,10 @@ void FWallTmapVals::InitFromLine(int tx1, int ty1, int tx2, int ty2) fullx2 = -fullx2; } - UoverZorg = (float)fullx1 * WallTMapScale; - UoverZstep = (float)(-fully1) * 32.f; - InvZorg = (float)(fullx1 - fullx2) * WallTMapScale; - InvZstep = (float)(fully2 - fully1) * 32.f; + UoverZorg = (float)fullx1 * centerx; + UoverZstep = (float)(-fully1); + InvZorg = (float)(fullx1 - fullx2) * centerx; + InvZstep = (float)(fully2 - fully1); InitDepth(); } diff --git a/src/r_main.cpp b/src/r_main.cpp index bc3c4c7c0..dbf4cbeb5 100644 --- a/src/r_main.cpp +++ b/src/r_main.cpp @@ -117,7 +117,6 @@ FDynamicColormap*basecolormap; // [RH] colormap currently drawing with int fixedlightlev; lighttable_t *fixedcolormap; FSpecialColormap *realfixedcolormap; -float WallTMapScale; float WallTMapScale2; @@ -386,8 +385,7 @@ void R_SWRSetWindow(int windowSize, int fullWidth, int fullHeight, int stHeight, iyaspectmulfloat = (float)virtwidth * r_Yaspect / 320.f / (float)virtheight; InvZtoScale = yaspectmul * centerx; - WallTMapScale = (float)centerx * 32.f; - WallTMapScale2 = iyaspectmulfloat * 2.f / (float)centerx; + WallTMapScale2 = iyaspectmulfloat * 64.f / (float)centerx; // psprite scales pspritexscale = (centerxwide << FRACBITS) / 160; diff --git a/src/r_main.h b/src/r_main.h index 0126d3906..715a60610 100644 --- a/src/r_main.h +++ b/src/r_main.h @@ -42,7 +42,6 @@ extern fixed_t FocalLengthX, FocalLengthY; extern float FocalLengthXfloat; extern fixed_t InvZtoScale; -extern float WallTMapScale; extern float WallTMapScale2; extern int viewwindowx; From bf0856aef5e55c7b10eac2cb7ac4e9d0489a163b Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Thu, 7 Aug 2014 22:58:11 -0500 Subject: [PATCH 02/46] Remove DepthScale and DepthOrg from FWallTmapVals --- src/r_bsp.cpp | 8 -------- src/r_bsp.h | 2 -- src/r_segs.cpp | 4 +++- 3 files changed, 3 insertions(+), 11 deletions(-) diff --git a/src/r_bsp.cpp b/src/r_bsp.cpp index 146ea5673..bf0ac910f 100644 --- a/src/r_bsp.cpp +++ b/src/r_bsp.cpp @@ -821,7 +821,6 @@ void FWallTmapVals::InitFromWallCoords(const FWallCoords *wallc) InvZorg = (float)(wallc->tx1 - wallc->tx2) * centerx; InvZstep = (float)(wallc->ty2 - wallc->ty1); } - InitDepth(); } void FWallTmapVals::InitFromLine(int tx1, int ty1, int tx2, int ty2) @@ -841,13 +840,6 @@ void FWallTmapVals::InitFromLine(int tx1, int ty1, int tx2, int ty2) UoverZstep = (float)(-fully1); InvZorg = (float)(fullx1 - fullx2) * centerx; InvZstep = (float)(fully2 - fully1); - InitDepth(); -} - -void FWallTmapVals::InitDepth() -{ - DepthScale = InvZstep * WallTMapScale2; - DepthOrg = -UoverZstep * WallTMapScale2; } // diff --git a/src/r_bsp.h b/src/r_bsp.h index 1b5af9805..acd519c62 100644 --- a/src/r_bsp.h +++ b/src/r_bsp.h @@ -44,13 +44,11 @@ struct FWallCoords struct FWallTmapVals { - float DepthOrg, DepthScale; float UoverZorg, UoverZstep; float InvZorg, InvZstep; void InitFromWallCoords(const FWallCoords *wallc); void InitFromLine(int x1, int y1, int x2, int y2); - void InitDepth(); }; extern FWallCoords WallC; diff --git a/src/r_segs.cpp b/src/r_segs.cpp index 15f736c93..cf00abc45 100644 --- a/src/r_segs.cpp +++ b/src/r_segs.cpp @@ -2893,6 +2893,8 @@ void PrepWall (fixed_t *swall, fixed_t *lwall, fixed_t walxrepeat, int x1, int x { // swall = scale, lwall = texturecolumn double top, bot, i; double xrepeat = fabs((double)walxrepeat); + double depth_scale = WallT.InvZstep * WallTMapScale2; + double depth_org = -WallT.UoverZstep * WallTMapScale2; i = x1 - centerx; top = WallT.UoverZorg + WallT.UoverZstep * i; @@ -2909,7 +2911,7 @@ void PrepWall (fixed_t *swall, fixed_t *lwall, fixed_t walxrepeat, int x1, int x { lwall[x] = xs_RoundToInt(frac * xrepeat); } - swall[x] = xs_RoundToInt(frac * WallT.DepthScale + WallT.DepthOrg); + swall[x] = xs_RoundToInt(frac * depth_scale + depth_org); top += WallT.UoverZstep; bot += WallT.InvZstep; } From d625caf03c7d5a7cc673af432a8b6d32787c3bf1 Mon Sep 17 00:00:00 2001 From: Braden Obrzut Date: Mon, 8 Dec 2014 18:46:10 -0500 Subject: [PATCH 03/46] - Ported SDL backend to SDL 2.0. Still needs a little bit of polish, but it works. --- FindSDL2.cmake | 180 +++++++++++++++++++++++++++++++++++++ src/CMakeLists.txt | 9 +- src/sdl/i_gui.cpp | 54 +++--------- src/sdl/i_input.cpp | 196 ++++++++++++++--------------------------- src/sdl/i_joystick.cpp | 2 +- src/sdl/i_main.cpp | 17 +--- src/sdl/sdlvideo.cpp | 99 ++++++++++++++------- 7 files changed, 331 insertions(+), 226 deletions(-) create mode 100644 FindSDL2.cmake diff --git a/FindSDL2.cmake b/FindSDL2.cmake new file mode 100644 index 000000000..614426ccc --- /dev/null +++ b/FindSDL2.cmake @@ -0,0 +1,180 @@ +# Locate SDL2 library +# This module defines +# SDL2_LIBRARY, the name of the library to link against +# SDL2_FOUND, if false, do not try to link to SDL2 +# SDL2_INCLUDE_DIR, where to find SDL.h +# +# This module responds to the the flag: +# SDL2_BUILDING_LIBRARY +# If this is defined, then no SDL2_main will be linked in because +# only applications need main(). +# Otherwise, it is assumed you are building an application and this +# module will attempt to locate and set the the proper link flags +# as part of the returned SDL2_LIBRARY variable. +# +# Don't forget to include SDL2main.h and SDL2main.m your project for the +# OS X framework based version. (Other versions link to -lSDL2main which +# this module will try to find on your behalf.) Also for OS X, this +# module will automatically add the -framework Cocoa on your behalf. +# +# +# Additional Note: If you see an empty SDL2_LIBRARY_TEMP in your configuration +# and no SDL2_LIBRARY, it means CMake did not find your SDL2 library +# (SDL2.dll, libsdl2.so, SDL2.framework, etc). +# Set SDL2_LIBRARY_TEMP to point to your SDL2 library, and configure again. +# Similarly, if you see an empty SDL2MAIN_LIBRARY, you should set this value +# as appropriate. These values are used to generate the final SDL2_LIBRARY +# variable, but when these values are unset, SDL2_LIBRARY does not get created. +# +# +# $SDL2DIR is an environment variable that would +# correspond to the ./configure --prefix=$SDL2DIR +# used in building SDL2. +# l.e.galup 9-20-02 +# +# Modified by Eric Wing. +# Added code to assist with automated building by using environmental variables +# and providing a more controlled/consistent search behavior. +# Added new modifications to recognize OS X frameworks and +# additional Unix paths (FreeBSD, etc). +# Also corrected the header search path to follow "proper" SDL2 guidelines. +# Added a search for SDL2main which is needed by some platforms. +# Added a search for threads which is needed by some platforms. +# Added needed compile switches for MinGW. +# +# On OSX, this will prefer the Framework version (if found) over others. +# People will have to manually change the cache values of +# SDL2_LIBRARY to override this selection or set the CMake environment +# CMAKE_INCLUDE_PATH to modify the search paths. +# +# Note that the header path has changed from SDL2/SDL.h to just SDL.h +# This needed to change because "proper" SDL2 convention +# is #include "SDL.h", not . This is done for portability +# reasons because not all systems place things in SDL2/ (see FreeBSD). +# +# Ported by Johnny Patterson. This is a literal port for SDL2 of the FindSDL.cmake +# module with the minor edit of changing "SDL" to "SDL2" where necessary. This +# was not created for redistribution, and exists temporarily pending official +# SDL2 CMake modules. + +#============================================================================= +# Copyright 2003-2009 Kitware, Inc. +# +# Distributed under the OSI-approved BSD License (the "License"); +# see accompanying file Copyright.txt for details. +# +# This software is distributed WITHOUT ANY WARRANTY; without even the +# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +# See the License for more information. +#============================================================================= +# (To distribute this file outside of CMake, substitute the full +# License text for the above reference.) + +FIND_PATH(SDL2_INCLUDE_DIR SDL.h + HINTS + $ENV{SDL2DIR} + PATH_SUFFIXES include/SDL2 include + PATHS + ~/Library/Frameworks + /Library/Frameworks + /usr/local/include/SDL2 + /usr/include/SDL2 + /sw # Fink + /opt/local # DarwinPorts + /opt/csw # Blastwave + /opt +) +#MESSAGE("SDL2_INCLUDE_DIR is ${SDL2_INCLUDE_DIR}") + +FIND_LIBRARY(SDL2_LIBRARY_TEMP + NAMES SDL2 + HINTS + $ENV{SDL2DIR} + PATH_SUFFIXES lib64 lib + PATHS + /sw + /opt/local + /opt/csw + /opt +) + +#MESSAGE("SDL2_LIBRARY_TEMP is ${SDL2_LIBRARY_TEMP}") + +IF(NOT SDL2_BUILDING_LIBRARY) + IF(NOT ${SDL2_INCLUDE_DIR} MATCHES ".framework") + # Non-OS X framework versions expect you to also dynamically link to + # SDL2main. This is mainly for Windows and OS X. Other (Unix) platforms + # seem to provide SDL2main for compatibility even though they don't + # necessarily need it. + FIND_LIBRARY(SDL2MAIN_LIBRARY + NAMES SDL2main + HINTS + $ENV{SDL2DIR} + PATH_SUFFIXES lib64 lib + PATHS + /sw + /opt/local + /opt/csw + /opt + ) + ENDIF(NOT ${SDL2_INCLUDE_DIR} MATCHES ".framework") +ENDIF(NOT SDL2_BUILDING_LIBRARY) + +# SDL2 may require threads on your system. +# The Apple build may not need an explicit flag because one of the +# frameworks may already provide it. +# But for non-OSX systems, I will use the CMake Threads package. +IF(NOT APPLE) + FIND_PACKAGE(Threads) +ENDIF(NOT APPLE) + +# MinGW needs an additional library, mwindows +# It's total link flags should look like -lmingw32 -lSDL2main -lSDL2 -lmwindows +# (Actually on second look, I think it only needs one of the m* libraries.) +IF(MINGW) + SET(MINGW32_LIBRARY mingw32 CACHE STRING "mwindows for MinGW") +ENDIF(MINGW) + +SET(SDL2_FOUND "NO") +IF(SDL2_LIBRARY_TEMP) + # For SDL2main + IF(NOT SDL2_BUILDING_LIBRARY) + IF(SDL2MAIN_LIBRARY) + SET(SDL2_LIBRARY_TEMP ${SDL2MAIN_LIBRARY} ${SDL2_LIBRARY_TEMP}) + ENDIF(SDL2MAIN_LIBRARY) + ENDIF(NOT SDL2_BUILDING_LIBRARY) + + # For OS X, SDL2 uses Cocoa as a backend so it must link to Cocoa. + # CMake doesn't display the -framework Cocoa string in the UI even + # though it actually is there if I modify a pre-used variable. + # I think it has something to do with the CACHE STRING. + # So I use a temporary variable until the end so I can set the + # "real" variable in one-shot. + IF(APPLE) + SET(SDL2_LIBRARY_TEMP ${SDL2_LIBRARY_TEMP} "-framework Cocoa") + ENDIF(APPLE) + + # For threads, as mentioned Apple doesn't need this. + # In fact, there seems to be a problem if I used the Threads package + # and try using this line, so I'm just skipping it entirely for OS X. + IF(NOT APPLE) + SET(SDL2_LIBRARY_TEMP ${SDL2_LIBRARY_TEMP} ${CMAKE_THREAD_LIBS_INIT}) + ENDIF(NOT APPLE) + + # For MinGW library + IF(MINGW) + SET(SDL2_LIBRARY_TEMP ${MINGW32_LIBRARY} ${SDL2_LIBRARY_TEMP}) + ENDIF(MINGW) + + # Set the final string here so the GUI reflects the final state. + SET(SDL2_LIBRARY ${SDL2_LIBRARY_TEMP} CACHE STRING "Where the SDL2 Library can be found") + # Set the temp variable to INTERNAL so it is not seen in the CMake GUI + SET(SDL2_LIBRARY_TEMP "${SDL2_LIBRARY_TEMP}" CACHE INTERNAL "") + + SET(SDL2_FOUND "YES") +ENDIF(SDL2_LIBRARY_TEMP) + +INCLUDE(FindPackageHandleStandardArgs) + +FIND_PACKAGE_HANDLE_STANDARD_ARGS(SDL2 + REQUIRED_VARS SDL2_LIBRARY SDL2_INCLUDE_DIR) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 07c13c20c..8838dea05 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -210,14 +210,11 @@ else( WIN32 ) endif( NO_GTK ) # Non-Windows version also needs SDL - find_package( SDL ) - if( NOT SDL_FOUND ) - message( SEND_ERROR "SDL is required for building." ) - endif( NOT SDL_FOUND ) + find_package( SDL2 REQUIRED ) if( NOT APPLE OR NOT OSX_COCOA_BACKEND ) - set( ZDOOM_LIBS ${ZDOOM_LIBS} "${SDL_LIBRARY}" ) + set( ZDOOM_LIBS ${ZDOOM_LIBS} "${SDL2_LIBRARY}" ) endif( NOT APPLE OR NOT OSX_COCOA_BACKEND ) - include_directories( "${SDL_INCLUDE_DIR}" ) + include_directories( "${SDL2_INCLUDE_DIR}" ) find_path( FPU_CONTROL_DIR fpu_control.h ) if( FPU_CONTROL_DIR ) diff --git a/src/sdl/i_gui.cpp b/src/sdl/i_gui.cpp index b40fb7517..39b66c085 100644 --- a/src/sdl/i_gui.cpp +++ b/src/sdl/i_gui.cpp @@ -9,9 +9,6 @@ #include "v_palette.h" #include "textures.h" -extern SDL_Surface *cursorSurface; -extern SDL_Rect cursorBlit; - #ifdef USE_XCURSOR // Xlib has its own GC, so don't let it interfere. #define GC XGC @@ -22,40 +19,6 @@ bool UseXCursor; SDL_Cursor *X11Cursor; SDL_Cursor *FirstCursor; -// Hack! Hack! SDL does not provide a clean way to get the XDisplay. -// On the other hand, there are no more planned updates for SDL 1.2, -// so we should be fine making assumptions. -struct SDL_PrivateVideoData -{ - int local_X11; - Display *X11_Display; -}; - -struct SDL_VideoDevice -{ - const char *name; - int (*functions[9])(); - SDL_VideoInfo info; - SDL_PixelFormat *displayformatalphapixel; - int (*morefuncs[9])(); - Uint16 *gamma; - int (*somefuncs[9])(); - unsigned int texture; // Only here if SDL was compiled with OpenGL support. Ack! - int is_32bit; - int (*itsafuncs[13])(); - SDL_Surface *surfaces[3]; - SDL_Palette *physpal; - SDL_Color *gammacols; - char *wm_strings[2]; - int offsets[2]; - SDL_GrabMode input_grab; - int handles_any_size; - SDL_PrivateVideoData *hidden; // Why did they have to bury this so far in? -}; - -extern SDL_VideoDevice *current_video; -#define SDL_Display (current_video->hidden->X11_Display) - SDL_Cursor *CreateColorCursor(FTexture *cursorpic) { return NULL; @@ -64,6 +27,9 @@ SDL_Cursor *CreateColorCursor(FTexture *cursorpic) bool I_SetCursor(FTexture *cursorpic) { + static SDL_Cursor *cursor; + static SDL_Surface *cursorSurface; + if (cursorpic != NULL && cursorpic->UseType != FTexture::TEX_Null) { // Must be no larger than 32x32. @@ -90,7 +56,6 @@ bool I_SetCursor(FTexture *cursorpic) if (cursorSurface == NULL) cursorSurface = SDL_CreateRGBSurface (0, 32, 32, 32, MAKEARGB(0,255,0,0), MAKEARGB(0,0,255,0), MAKEARGB(0,0,0,255), MAKEARGB(255,0,0,0)); - SDL_ShowCursor(0); SDL_LockSurface(cursorSurface); BYTE buffer[32*32*4]; memset(buffer, 0, 32*32*4); @@ -98,11 +63,20 @@ bool I_SetCursor(FTexture *cursorpic) cursorpic->CopyTrueColorPixels(&bmp, 0, 0); memcpy(cursorSurface->pixels, bmp.GetPixels(), 32*32*4); SDL_UnlockSurface(cursorSurface); + + if (cursor) + SDL_FreeCursor (cursor); + cursor = SDL_CreateColorCursor (cursorSurface, 0, 0); + SDL_SetCursor (cursor); } else { - SDL_ShowCursor(1); - + if (cursor) + { + SDL_SetCursor (NULL); + SDL_FreeCursor (cursor); + cursor = NULL; + } if (cursorSurface != NULL) { SDL_FreeSurface(cursorSurface); diff --git a/src/sdl/i_input.cpp b/src/sdl/i_input.cpp index bf676db70..722345cb2 100644 --- a/src/sdl/i_input.cpp +++ b/src/sdl/i_input.cpp @@ -29,19 +29,16 @@ extern int paused; CVAR (Bool, use_mouse, true, CVAR_ARCHIVE|CVAR_GLOBALCONFIG) CVAR (Bool, m_noprescale, false, CVAR_ARCHIVE|CVAR_GLOBALCONFIG) CVAR (Bool, m_filter, false, CVAR_ARCHIVE|CVAR_GLOBALCONFIG) -CVAR (Bool, sdl_nokeyrepeat, false, CVAR_ARCHIVE|CVAR_GLOBALCONFIG) EXTERN_CVAR (Bool, fullscreen) extern int WaitingForKey, chatmodeon; extern constate_e ConsoleState; -extern SDL_Surface *cursorSurface; -extern SDL_Rect cursorBlit; +static TMap KeySymToDIK; +static bool DownState[SDL_NUM_SCANCODES]; -static BYTE KeySymToDIK[SDLK_LAST], DownState[SDLK_LAST]; - -static WORD DIKToKeySym[256] = +static SDL_Keycode DIKToKeySym[256] = { 0, SDLK_ESCAPE, '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '-', '=', SDLK_BACKSPACE, SDLK_TAB, @@ -51,9 +48,9 @@ static WORD DIKToKeySym[256] = '\'', '`', SDLK_LSHIFT, '\\', 'z', 'x', 'c', 'v', 'b', 'n', 'm', ',', '.', '/', SDLK_RSHIFT, SDLK_KP_MULTIPLY, SDLK_LALT, ' ', SDLK_CAPSLOCK, SDLK_F1, SDLK_F2, SDLK_F3, SDLK_F4, SDLK_F5, - SDLK_F6, SDLK_F7, SDLK_F8, SDLK_F9, SDLK_F10, SDLK_NUMLOCK, SDLK_SCROLLOCK, SDLK_KP7, - SDLK_KP8, SDLK_KP9, SDLK_KP_MINUS, SDLK_KP4, SDLK_KP5, SDLK_KP6, SDLK_KP_PLUS, SDLK_KP1, - SDLK_KP2, SDLK_KP3, SDLK_KP0, SDLK_KP_PERIOD, 0, 0, 0, SDLK_F11, + SDLK_F6, SDLK_F7, SDLK_F8, SDLK_F9, SDLK_F10, SDLK_NUMLOCKCLEAR, SDLK_SCROLLLOCK, SDLK_KP_7, + SDLK_KP_8, SDLK_KP_9, SDLK_KP_MINUS, SDLK_KP_4, SDLK_KP_5, SDLK_KP_6, SDLK_KP_PLUS, SDLK_KP_1, + SDLK_KP_2, SDLK_KP_3, SDLK_KP_0, SDLK_KP_PERIOD, 0, 0, 0, SDLK_F11, SDLK_F12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, SDLK_F13, SDLK_F14, SDLK_F15, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -70,7 +67,7 @@ static WORD DIKToKeySym[256] = 0, 0, 0, 0, 0, SDLK_PAUSE, 0, SDLK_HOME, SDLK_UP, SDLK_PAGEUP, 0, SDLK_LEFT, 0, SDLK_RIGHT, 0, SDLK_END, SDLK_DOWN, SDLK_PAGEDOWN, SDLK_INSERT, SDLK_DELETE, 0, 0, 0, 0, - 0, 0, 0, SDLK_LSUPER, SDLK_RSUPER, SDLK_MENU, SDLK_POWER, 0, + 0, 0, 0, SDLK_LGUI, SDLK_RGUI, SDLK_MENU, SDLK_POWER, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -92,16 +89,12 @@ static void InitKeySymMap () KeySymToDIK[SDLK_RCTRL] = DIK_LCONTROL; KeySymToDIK[SDLK_RALT] = DIK_LMENU; // Depending on your Linux flavor, you may get SDLK_PRINT or SDLK_SYSREQ - KeySymToDIK[SDLK_PRINT] = DIK_SYSRQ; + KeySymToDIK[SDLK_PRINTSCREEN] = DIK_SYSRQ; } static void I_CheckGUICapture () { bool wantCapt; - bool repeat; - int oldrepeat, interval; - - SDL_GetKeyRepeat(&oldrepeat, &interval); if (menuactive == MENU_Off) { @@ -117,56 +110,20 @@ static void I_CheckGUICapture () GUICapture = wantCapt; if (wantCapt) { - int x, y; - SDL_GetMouseState (&x, &y); - cursorBlit.x = x; - cursorBlit.y = y; - FlushDIKState (); memset (DownState, 0, sizeof(DownState)); - repeat = !sdl_nokeyrepeat; - SDL_EnableUNICODE (1); - } - else - { - repeat = false; - SDL_EnableUNICODE (0); - } - } - if (wantCapt) - { - repeat = !sdl_nokeyrepeat; - } - else - { - repeat = false; - } - if (repeat != (oldrepeat != 0)) - { - if (repeat) - { - SDL_EnableKeyRepeat (SDL_DEFAULT_REPEAT_DELAY, SDL_DEFAULT_REPEAT_INTERVAL); - } - else - { - SDL_EnableKeyRepeat (0, 0); } } } void I_SetMouseCapture() { + SDL_SetRelativeMouseMode (SDL_TRUE); } void I_ReleaseMouseCapture() { -} - -static void CenterMouse () -{ - SDL_WarpMouse (screen->GetWidth()/2, screen->GetHeight()/2); - SDL_PumpEvents (); - SDL_GetRelativeMouseState (NULL, NULL); + SDL_SetRelativeMouseMode (SDL_FALSE); } static void PostMouseMove (int x, int y) @@ -210,33 +167,10 @@ static void MouseRead () } if (x | y) { - CenterMouse (); PostMouseMove (x, -y); } } -static void WheelMoved(event_t *event) -{ - if (GUICapture) - { - if (event->type != EV_KeyUp) - { - SDLMod mod = SDL_GetModState(); - event->type = EV_GUI_Event; - event->subtype = event->data1 == KEY_MWHEELUP ? EV_GUI_WheelUp : EV_GUI_WheelDown; - event->data1 = 0; - event->data3 = ((mod & KMOD_SHIFT) ? GKM_SHIFT : 0) | - ((mod & KMOD_CTRL) ? GKM_CTRL : 0) | - ((mod & KMOD_ALT) ? GKM_ALT : 0); - D_PostEvent(event); - } - } - else - { - D_PostEvent(event); - } -} - CUSTOM_CVAR(Int, mouse_capturemode, 1, CVAR_GLOBALCONFIG|CVAR_ARCHIVE) { if (self < 0) self = 0; @@ -259,26 +193,20 @@ static bool inGame() static void I_CheckNativeMouse () { - bool focus = (SDL_GetAppState() & (SDL_APPINPUTFOCUS|SDL_APPACTIVE)) - == (SDL_APPINPUTFOCUS|SDL_APPACTIVE); - bool fs = (SDL_GetVideoSurface ()->flags & SDL_FULLSCREEN) != 0; + bool focus = SDL_GetMouseFocus() != NULL; + bool fs = screen->IsFullscreen(); bool wantNative = !focus || (!use_mouse || GUICapture || paused || demoplayback || !inGame()); if (wantNative != NativeMouse) { NativeMouse = wantNative; - SDL_ShowCursor (wantNative ? cursorSurface == NULL : 0); + SDL_ShowCursor (wantNative); + SDL_SetRelativeMouseMode (wantNative ? SDL_FALSE : SDL_TRUE); if (wantNative) { - SDL_WM_GrabInput (SDL_GRAB_OFF); FlushDIKState (KEY_MOUSE1, KEY_MOUSE8); } - else - { - SDL_WM_GrabInput (SDL_GRAB_ON); - CenterMouse (); - } } } @@ -293,14 +221,17 @@ void MessagePump (const SDL_Event &sev) case SDL_QUIT: exit (0); - case SDL_ACTIVEEVENT: - if (sev.active.state == SDL_APPINPUTFOCUS) + case SDL_WINDOWEVENT: + switch (sev.window.event) { - if (sev.active.gain == 0) - { // kill focus - FlushDIKState (); - } - S_SetSoundPaused(sev.active.gain); + case SDL_WINDOWEVENT_FOCUS_GAINED: + case SDL_WINDOWEVENT_FOCUS_LOST: + if (sev.window.event == SDL_WINDOWEVENT_FOCUS_LOST) + { // kill focus + FlushDIKState (); + } + S_SetSoundPaused(sev.window.event == SDL_WINDOWEVENT_FOCUS_GAINED); + break; } break; @@ -320,32 +251,20 @@ void MessagePump (const SDL_Event &sev) */ switch (sev.button.button) { - case 1: event.data1 = KEY_MOUSE1; break; - case 2: event.data1 = KEY_MOUSE3; break; - case 3: event.data1 = KEY_MOUSE2; break; - case 4: event.data1 = KEY_MWHEELUP; break; - case 5: event.data1 = KEY_MWHEELDOWN; break; - case 6: event.data1 = KEY_MOUSE4; break; /* dunno; not generated by my mouse */ - case 7: event.data1 = KEY_MOUSE5; break; /* ditto */ - case 8: event.data1 = KEY_MOUSE4; break; + case SDL_BUTTON_LEFT: event.data1 = KEY_MOUSE1; break; + case SDL_BUTTON_MIDDLE: event.data1 = KEY_MOUSE3; break; + case SDL_BUTTON_RIGHT: event.data1 = KEY_MOUSE2; break; + case 8: event.data1 = KEY_MOUSE4; break; // For whatever reason my side mouse buttons are here. case 9: event.data1 = KEY_MOUSE5; break; - case 10: event.data1 = KEY_MOUSE6; break; - case 11: event.data1 = KEY_MOUSE7; break; - case 12: event.data1 = KEY_MOUSE8; break; + case SDL_BUTTON_X1: event.data1 = KEY_MOUSE6; break; // And these don't exist + case SDL_BUTTON_X2: event.data1 = KEY_MOUSE7; break; + case 6: event.data1 = KEY_MOUSE8; break; default: printf("SDL mouse button %s %d\n", sev.type == SDL_MOUSEBUTTONDOWN ? "down" : "up", sev.button.button); break; } if (event.data1 != 0) { - //DIKState[ActiveDIKState][event.data1] = (event.type == EV_KeyDown); - if (event.data1 == KEY_MWHEELUP || event.data1 == KEY_MWHEELDOWN) - { - WheelMoved(&event); - } - else - { - D_PostEvent(&event); - } + D_PostEvent(&event); } } } @@ -354,8 +273,8 @@ void MessagePump (const SDL_Event &sev) int x, y; SDL_GetMouseState (&x, &y); - cursorBlit.x = event.data1 = x; - cursorBlit.y = event.data2 = y; + event.data1 = x; + event.data2 = y; event.type = EV_GUI_Event; if(sev.type == SDL_MOUSEMOTION) event.subtype = EV_GUI_MouseMove; @@ -368,11 +287,25 @@ void MessagePump (const SDL_Event &sev) } break; + case SDL_MOUSEWHEEL: + if (GUICapture) + { + event.type = EV_GUI_Event; + event.subtype = sev.wheel.y > 0 ? EV_GUI_WheelUp : EV_GUI_WheelDown; + D_PostEvent (&event); + } + else + { + event.type = EV_KeyDown; + event.data1 = sev.wheel.y > 0 ? KEY_MWHEELUP : KEY_MWHEELDOWN; + D_PostEvent (&event); + event.type = EV_KeyUp; + D_PostEvent (&event); + } + break; + case SDL_KEYDOWN: case SDL_KEYUP: - if (sev.key.keysym.sym >= SDLK_LAST) - break; - if (!GUICapture) { event.type = sev.type == SDL_KEYDOWN ? EV_KeyDown : EV_KeyUp; @@ -394,19 +327,19 @@ void MessagePump (const SDL_Event &sev) ((sev.key.keysym.mod & KMOD_CTRL) ? GKM_CTRL : 0) | ((sev.key.keysym.mod & KMOD_ALT) ? GKM_ALT : 0); - if (sev.key.keysym.sym < SDLK_LAST) + //if (sev.key.keysym.sym < SDLK_LAST) { if (event.subtype == EV_GUI_KeyDown) { - if (DownState[sev.key.keysym.sym]) + if (DownState[sev.key.keysym.scancode]) { event.subtype = EV_GUI_KeyRepeat; } - DownState[sev.key.keysym.sym] = 1; + DownState[sev.key.keysym.scancode] = 1; } else { - DownState[sev.key.keysym.sym] = 0; + DownState[sev.key.keysym.scancode] = 0; } } @@ -442,20 +375,21 @@ void MessagePump (const SDL_Event &sev) } break; } - event.data2 = sev.key.keysym.unicode & 0xff; if (event.data1 < 128) { event.data1 = toupper(event.data1); D_PostEvent (&event); } - if (!iscntrl(event.data2) && event.subtype != EV_GUI_KeyUp) - { - event.subtype = EV_GUI_Char; - event.data1 = event.data2; - event.data2 = sev.key.keysym.mod & KMOD_ALT; - event.data3 = 0; - D_PostEvent (&event); - } + } + break; + + case SDL_TEXTINPUT: + if (GUICapture) + { + event.type = EV_GUI_Event; + event.subtype = EV_GUI_Char; + event.data1 = sev.text.text[0]; + D_PostEvent (&event); } break; diff --git a/src/sdl/i_joystick.cpp b/src/sdl/i_joystick.cpp index 7a529861f..9b1d326ae 100644 --- a/src/sdl/i_joystick.cpp +++ b/src/sdl/i_joystick.cpp @@ -35,7 +35,7 @@ public: FString GetName() { - return SDL_JoystickName(DeviceIndex); + return SDL_JoystickName(Device); } float GetSensitivity() { diff --git a/src/sdl/i_main.cpp b/src/sdl/i_main.cpp index 7a18fb05f..a928b7e7c 100644 --- a/src/sdl/i_main.cpp +++ b/src/sdl/i_main.cpp @@ -278,22 +278,11 @@ int main (int argc, char **argv) } atterm (SDL_Quit); - { - char viddriver[80]; - - if (SDL_VideoDriverName(viddriver, sizeof(viddriver)) != NULL) - { - printf("Using video driver %s\n", viddriver); + printf("Using video driver %s\n", SDL_GetCurrentVideoDriver()); #ifdef USE_XCURSOR - UseXCursor = (strcmp(viddriver, "x11") == 0); + UseXCursor = (strcmp(SDL_GetCurrentVideoDriver(), "x11") == 0); #endif - } - printf("\n"); - } - - char caption[100]; - mysnprintf(caption, countof(caption), GAMESIG " %s (%s)", GetVersionString(), GetGitTime()); - SDL_WM_SetCaption(caption, caption); + printf("\n"); #ifdef __APPLE__ diff --git a/src/sdl/sdlvideo.cpp b/src/sdl/sdlvideo.cpp index e4222633d..838c082b4 100644 --- a/src/sdl/sdlvideo.cpp +++ b/src/sdl/sdlvideo.cpp @@ -12,6 +12,7 @@ #include "v_palette.h" #include "sdlvideo.h" #include "r_swrenderer.h" +#include "version.h" #include @@ -56,13 +57,15 @@ private: int FlashAmount; float Gamma; bool UpdatePending; - - SDL_Surface *Screen; - + + SDL_Window *Screen; + SDL_Renderer *Renderer; + SDL_Texture *Texture; + bool NeedPalUpdate; bool NeedGammaUpdate; bool NotPaletted; - + void UpdateColors (); SDLFB () {} @@ -83,9 +86,6 @@ struct MiniModeInfo extern IVideo *Video; extern bool GUICapture; -SDL_Surface *cursorSurface = NULL; -SDL_Rect cursorBlit = {0, 0, 32, 32}; - EXTERN_CVAR (Float, Gamma) EXTERN_CVAR (Int, vid_maxfps) EXTERN_CVAR (Bool, cl_capfps) @@ -93,6 +93,8 @@ EXTERN_CVAR (Bool, vid_vsync) // PUBLIC DATA DEFINITIONS ------------------------------------------------- +CVAR (Int, vid_adapter, 0, CVAR_ARCHIVE|CVAR_GLOBALCONFIG) + CVAR (Int, vid_displaybits, 8, CVAR_ARCHIVE|CVAR_GLOBALCONFIG) // vid_asyncblit needs a restart to work. SDL doesn't seem to change if the @@ -204,14 +206,19 @@ bool SDLVideo::NextMode (int *width, int *height, bool *letterbox) } else { - SDL_Rect **modes = SDL_ListModes (NULL, SDL_FULLSCREEN|SDL_HWSURFACE); - if (modes != NULL && modes[IteratorMode] != NULL) + SDL_DisplayMode mode = {}, oldmode = {}; + if(IteratorMode != 0) + SDL_GetDisplayMode(vid_adapter, IteratorMode-1, &oldmode); + do { - *width = modes[IteratorMode]->w; - *height = modes[IteratorMode]->h; + if (SDL_GetDisplayMode(vid_adapter, IteratorMode, &mode) != 0) + return false; ++IteratorMode; - return true; - } + } while(mode.w == oldmode.w && mode.h == oldmode.h); + + *width = mode.w; + *height = mode.h; + return true; } return false; } @@ -230,11 +237,11 @@ DFrameBuffer *SDLVideo::CreateFrameBuffer (int width, int height, bool fullscree if (fb->Width == width && fb->Height == height) { - bool fsnow = (fb->Screen->flags & SDL_FULLSCREEN) != 0; + bool fsnow = (SDL_GetWindowFlags (fb->Screen) & SDL_WINDOW_FULLSCREEN_DESKTOP) != 0; if (fsnow != fullscreen) { - SDL_WM_ToggleFullScreen (fb->Screen); + SDL_SetWindowFullscreen (fb->Screen, fullscreen ? SDL_WINDOW_FULLSCREEN_DESKTOP : 0); } return old; } @@ -313,24 +320,37 @@ SDLFB::SDLFB (int width, int height, bool fullscreen) UpdatePending = false; NotPaletted = false; FlashAmount = 0; - Screen = SDL_SetVideoMode (width, height, vid_displaybits, - (vid_asyncblit ? SDL_ASYNCBLIT : 0)|SDL_HWSURFACE|SDL_HWPALETTE|SDL_DOUBLEBUF|SDL_ANYFORMAT| - (fullscreen ? SDL_FULLSCREEN : 0)); + + FString caption; + caption.Format(GAMESIG " %s (%s)", GetVersionString(), GetGitTime()); + Screen = SDL_CreateWindow (caption, + SDL_WINDOWPOS_UNDEFINED_DISPLAY(vid_adapter), SDL_WINDOWPOS_UNDEFINED_DISPLAY(vid_adapter), + width, height, (fullscreen ? SDL_WINDOW_FULLSCREEN_DESKTOP : 0)); if (Screen == NULL) return; + Renderer = SDL_CreateRenderer (Screen, -1, SDL_RENDERER_ACCELERATED|SDL_RENDERER_TARGETTEXTURE); + if (Renderer == NULL) + return; + + Texture = SDL_CreateTexture (Renderer, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_STREAMING, width, height); + for (i = 0; i < 256; i++) { GammaTable[0][i] = GammaTable[1][i] = GammaTable[2][i] = i; } - if (Screen->format->palette == NULL) + //if (Screen->format->palette == NULL) { NotPaletted = true; - GPfx.SetFormat (Screen->format->BitsPerPixel, - Screen->format->Rmask, - Screen->format->Gmask, - Screen->format->Bmask); + + Uint32 format; + SDL_QueryTexture(Texture, &format, NULL, NULL, NULL); + + Uint32 Rmask, Gmask, Bmask, Amask; + int bpp; + SDL_PixelFormatEnumToMasks(format, &bpp, &Rmask, &Gmask, &Bmask, &Amask); + GPfx.SetFormat (bpp, Rmask, Gmask, Bmask); } memcpy (SourcePalette, GPalette.BaseColors, sizeof(PalEntry)*256); UpdateColors (); @@ -339,6 +359,16 @@ SDLFB::SDLFB (int width, int height, bool fullscreen) SDLFB::~SDLFB () { + if(Screen) + { + if (Renderer) + { + if (Texture) + SDL_DestroyTexture (Texture); + SDL_DestroyRenderer (Renderer); + } + SDL_DestroyWindow (Screen); + } } bool SDLFB::IsValid () @@ -403,15 +433,18 @@ void SDLFB::Update () SDLFlipCycles.Reset(); BlitCycles.Clock(); - if (SDL_LockSurface (Screen) == -1) + void *pixels; + int pitch; + if (SDL_LockTexture (Texture, NULL, &pixels, &pitch)) return; if (NotPaletted) { GPfx.Convert (MemBuffer, Pitch, - Screen->pixels, Screen->pitch, Width, Height, + pixels, pitch, Width, Height, FRACUNIT, FRACUNIT, 0, 0); } +#if 0 else { if (Screen->pitch == Pitch) @@ -426,17 +459,13 @@ void SDLFB::Update () } } } - - SDL_UnlockSurface (Screen); +#endif - if (cursorSurface != NULL && GUICapture) - { - // SDL requires us to draw a surface to get true color cursors. - SDL_BlitSurface(cursorSurface, NULL, Screen, &cursorBlit); - } + SDL_UnlockTexture (Texture); SDLFlipCycles.Clock(); - SDL_Flip (Screen); + SDL_RenderCopy(Renderer, Texture, NULL, NULL); + SDL_RenderPresent(Renderer); SDLFlipCycles.Unclock(); BlitCycles.Unclock(); @@ -478,6 +507,7 @@ void SDLFB::UpdateColors () } GPfx.SetPalette (palette); } +#if 0 else { SDL_Color colors[256]; @@ -496,6 +526,7 @@ void SDLFB::UpdateColors () } SDL_SetPalette (Screen, SDL_LOGPAL|SDL_PHYSPAL, colors, 0, 256); } +#endif } PalEntry *SDLFB::GetPalette () @@ -541,7 +572,7 @@ void SDLFB::GetFlashedPalette (PalEntry pal[256]) bool SDLFB::IsFullscreen () { - return (Screen->flags & SDL_FULLSCREEN) != 0; + return (SDL_GetWindowFlags (Screen) & SDL_WINDOW_FULLSCREEN_DESKTOP) != 0; } void SDLFB::SetVSync (bool vsync) From 4aef69600733e6d0dd15e702c0a7057546412e55 Mon Sep 17 00:00:00 2001 From: Braden Obrzut Date: Mon, 8 Dec 2014 22:47:40 -0500 Subject: [PATCH 04/46] - Enabled vid_vsync for SDL2 although just turning it on doesn't perform right. - Improved fullscreen a bit. --- src/sdl/sdlvideo.cpp | 94 +++++++++++++++++++++++++++++++++++--------- 1 file changed, 76 insertions(+), 18 deletions(-) diff --git a/src/sdl/sdlvideo.cpp b/src/sdl/sdlvideo.cpp index 838c082b4..71a534f04 100644 --- a/src/sdl/sdlvideo.cpp +++ b/src/sdl/sdlvideo.cpp @@ -43,6 +43,7 @@ public: bool SetGamma (float gamma); bool SetFlash (PalEntry rgb, int amount); void GetFlash (PalEntry &rgb, int &amount); + void SetFullscreen (bool fullscreen); int GetPageCount (); bool IsFullscreen (); @@ -61,12 +62,14 @@ private: SDL_Window *Screen; SDL_Renderer *Renderer; SDL_Texture *Texture; + SDL_Rect UpdateRect; bool NeedPalUpdate; bool NeedGammaUpdate; bool NotPaletted; void UpdateColors (); + void ResetSDLRenderer (); SDLFB () {} }; @@ -241,7 +244,7 @@ DFrameBuffer *SDLVideo::CreateFrameBuffer (int width, int height, bool fullscree if (fsnow != fullscreen) { - SDL_SetWindowFullscreen (fb->Screen, fullscreen ? SDL_WINDOW_FULLSCREEN_DESKTOP : 0); + fb->SetFullscreen (fullscreen); } return old; } @@ -323,6 +326,7 @@ SDLFB::SDLFB (int width, int height, bool fullscreen) FString caption; caption.Format(GAMESIG " %s (%s)", GetVersionString(), GetGitTime()); + Screen = SDL_CreateWindow (caption, SDL_WINDOWPOS_UNDEFINED_DISPLAY(vid_adapter), SDL_WINDOWPOS_UNDEFINED_DISPLAY(vid_adapter), width, height, (fullscreen ? SDL_WINDOW_FULLSCREEN_DESKTOP : 0)); @@ -330,33 +334,24 @@ SDLFB::SDLFB (int width, int height, bool fullscreen) if (Screen == NULL) return; - Renderer = SDL_CreateRenderer (Screen, -1, SDL_RENDERER_ACCELERATED|SDL_RENDERER_TARGETTEXTURE); - if (Renderer == NULL) - return; - - Texture = SDL_CreateTexture (Renderer, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_STREAMING, width, height); + Renderer = NULL; + Texture = NULL; + ResetSDLRenderer (); for (i = 0; i < 256; i++) { GammaTable[0][i] = GammaTable[1][i] = GammaTable[2][i] = i; } - //if (Screen->format->palette == NULL) - { - NotPaletted = true; - Uint32 format; - SDL_QueryTexture(Texture, &format, NULL, NULL, NULL); - - Uint32 Rmask, Gmask, Bmask, Amask; - int bpp; - SDL_PixelFormatEnumToMasks(format, &bpp, &Rmask, &Gmask, &Bmask, &Amask); - GPfx.SetFormat (bpp, Rmask, Gmask, Bmask); - } memcpy (SourcePalette, GPalette.BaseColors, sizeof(PalEntry)*256); UpdateColors (); + +#ifdef __APPLE__ SetVSync (vid_vsync); +#endif } + SDLFB::~SDLFB () { if(Screen) @@ -464,7 +459,7 @@ void SDLFB::Update () SDL_UnlockTexture (Texture); SDLFlipCycles.Clock(); - SDL_RenderCopy(Renderer, Texture, NULL, NULL); + SDL_RenderCopy(Renderer, Texture, NULL, &UpdateRect); SDL_RenderPresent(Renderer); SDLFlipCycles.Unclock(); @@ -570,11 +565,72 @@ void SDLFB::GetFlashedPalette (PalEntry pal[256]) } } +void SDLFB::SetFullscreen (bool fullscreen) +{ + SDL_SetWindowFullscreen (Screen, fullscreen ? SDL_WINDOW_FULLSCREEN_DESKTOP : 0); + if (!fullscreen) + { + // Restore proper window size + SDL_SetWindowSize (Screen, Width, Height); + } + + ResetSDLRenderer (); +} + bool SDLFB::IsFullscreen () { return (SDL_GetWindowFlags (Screen) & SDL_WINDOW_FULLSCREEN_DESKTOP) != 0; } +void SDLFB::ResetSDLRenderer () +{ + if (Renderer) + { + if (Texture) + SDL_DestroyTexture (Texture); + SDL_DestroyRenderer (Renderer); + } + + Renderer = SDL_CreateRenderer (Screen, -1,SDL_RENDERER_ACCELERATED|SDL_RENDERER_TARGETTEXTURE| + (vid_vsync ? SDL_RENDERER_PRESENTVSYNC : 0)); + if (!Renderer) + return; + + Texture = SDL_CreateTexture (Renderer, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_STREAMING, Width, Height); + + //if (Screen->format->palette == NULL) + { + NotPaletted = true; + + Uint32 format; + SDL_QueryTexture(Texture, &format, NULL, NULL, NULL); + + Uint32 Rmask, Gmask, Bmask, Amask; + int bpp; + SDL_PixelFormatEnumToMasks(format, &bpp, &Rmask, &Gmask, &Bmask, &Amask); + GPfx.SetFormat (bpp, Rmask, Gmask, Bmask); + } + + // Calculate update rectangle + if (IsFullscreen ()) + { + int w, h; + SDL_GetWindowSize (Screen, &w, &h); + UpdateRect.w = w; + UpdateRect.h = w*Height/Width; + UpdateRect.x = 0; + UpdateRect.y = (h - UpdateRect.h)/2; + } + else + { + // In windowed mode we just update the whole window. + UpdateRect.x = 0; + UpdateRect.y = 0; + UpdateRect.w = Width; + UpdateRect.h = Height; + } +} + void SDLFB::SetVSync (bool vsync) { #ifdef __APPLE__ @@ -592,6 +648,8 @@ void SDLFB::SetVSync (bool vsync) const GLint value = vsync ? 1 : 0; CGLSetParameter(context, kCGLCPSwapInterval, &value); } +#else + ResetSDLRenderer (); #endif // __APPLE__ } From a7b33a8ce3fd644f27a408b9747a5e1049464c95 Mon Sep 17 00:00:00 2001 From: Braden Obrzut Date: Wed, 10 Dec 2014 01:53:22 -0500 Subject: [PATCH 05/46] - Removed XCursor code since SDL2 has proper color cursor support. - Improved international keyboard support by falling back to scan codes if we don't recognize a keycode. - Clear out any residual mouse movement when entering relative mouse mode. --- src/CMakeLists.txt | 13 ----- src/sdl/i_gui.cpp | 39 ------------- src/sdl/i_input.cpp | 134 +++++++++++++++++++++++++++++-------------- src/sdl/i_main.cpp | 7 --- src/sdl/sdlvideo.cpp | 5 +- 5 files changed, 93 insertions(+), 105 deletions(-) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 8838dea05..38e399ef1 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -189,19 +189,6 @@ else( WIN32 ) set( NO_GTK ON ) endif( GTK2_FOUND ) endif( NOT NO_GTK ) - - # Check for Xcursor library and header files - find_library( XCURSOR_LIB Xcursor ) - if( XCURSOR_LIB ) - find_file( XCURSOR_HEADER "X11/Xcursor/Xcursor.h" ) - if( XCURSOR_HEADER ) - add_definitions( -DUSE_XCURSOR=1 ) - message( STATUS "Found Xcursor at ${XCURSOR_LIB}" ) - set( ZDOOM_LIBS ${ZDOOM_LIBS} ${XCURSOR_LIB} ) - else( XCURSOR_HEADER ) - unset( XCURSOR_LIB ) - endif( XCURSOR_HEADER ) - endif( XCURSOR_LIB ) endif( APPLE ) set( NASM_NAMES nasm ) diff --git a/src/sdl/i_gui.cpp b/src/sdl/i_gui.cpp index 39b66c085..c2b91b39c 100644 --- a/src/sdl/i_gui.cpp +++ b/src/sdl/i_gui.cpp @@ -9,22 +9,6 @@ #include "v_palette.h" #include "textures.h" -#ifdef USE_XCURSOR -// Xlib has its own GC, so don't let it interfere. -#define GC XGC -#include -#undef GC - -bool UseXCursor; -SDL_Cursor *X11Cursor; -SDL_Cursor *FirstCursor; - -SDL_Cursor *CreateColorCursor(FTexture *cursorpic) -{ - return NULL; -} -#endif - bool I_SetCursor(FTexture *cursorpic) { static SDL_Cursor *cursor; @@ -38,21 +22,6 @@ bool I_SetCursor(FTexture *cursorpic) return false; } -#ifdef USE_XCURSOR - if (UseXCursor) - { - if (FirstCursor == NULL) - { - FirstCursor = SDL_GetCursor(); - } - X11Cursor = CreateColorCursor(cursorpic); - if (X11Cursor != NULL) - { - SDL_SetCursor(X11Cursor); - return true; - } - } -#endif if (cursorSurface == NULL) cursorSurface = SDL_CreateRGBSurface (0, 32, 32, 32, MAKEARGB(0,255,0,0), MAKEARGB(0,0,255,0), MAKEARGB(0,0,0,255), MAKEARGB(255,0,0,0)); @@ -82,14 +51,6 @@ bool I_SetCursor(FTexture *cursorpic) SDL_FreeSurface(cursorSurface); cursorSurface = NULL; } -#ifdef USE_XCURSOR - if (X11Cursor != NULL) - { - SDL_SetCursor(FirstCursor); - SDL_FreeCursor(X11Cursor); - X11Cursor = NULL; - } -#endif } return true; } diff --git a/src/sdl/i_input.cpp b/src/sdl/i_input.cpp index 722345cb2..ea877e204 100644 --- a/src/sdl/i_input.cpp +++ b/src/sdl/i_input.cpp @@ -35,19 +35,18 @@ EXTERN_CVAR (Bool, fullscreen) extern int WaitingForKey, chatmodeon; extern constate_e ConsoleState; -static TMap KeySymToDIK; static bool DownState[SDL_NUM_SCANCODES]; -static SDL_Keycode DIKToKeySym[256] = +static const SDL_Keycode DIKToKeySym[256] = { - 0, SDLK_ESCAPE, '1', '2', '3', '4', '5', '6', - '7', '8', '9', '0', '-', '=', SDLK_BACKSPACE, SDLK_TAB, - 'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', - 'o', 'p', '[', ']', SDLK_RETURN, SDLK_LCTRL, 'a', 's', - 'd', 'f', 'g', 'h', 'j', 'k', 'l', SDLK_SEMICOLON, - '\'', '`', SDLK_LSHIFT, '\\', 'z', 'x', 'c', 'v', - 'b', 'n', 'm', ',', '.', '/', SDLK_RSHIFT, SDLK_KP_MULTIPLY, - SDLK_LALT, ' ', SDLK_CAPSLOCK, SDLK_F1, SDLK_F2, SDLK_F3, SDLK_F4, SDLK_F5, + 0, SDLK_ESCAPE, SDLK_1, SDLK_2, SDLK_3, SDLK_4, SDLK_5, SDLK_6, + SDLK_7, SDLK_8, SDLK_9, SDLK_0,SDLK_MINUS, SDLK_EQUALS, SDLK_BACKSPACE, SDLK_TAB, + SDLK_q, SDLK_w, SDLK_e, SDLK_r, SDLK_t, SDLK_y, SDLK_u, SDLK_i, + SDLK_o, SDLK_p, SDLK_LEFTBRACKET, SDLK_RIGHTBRACKET, SDLK_RETURN, SDLK_LCTRL, SDLK_a, SDLK_s, + SDLK_d, SDLK_f, SDLK_g, SDLK_h, SDLK_j, SDLK_k, SDLK_l, SDLK_SEMICOLON, + SDLK_QUOTE, SDLK_BACKQUOTE, SDLK_LSHIFT, SDLK_BACKSLASH, SDLK_z, SDLK_x, SDLK_c, SDLK_v, + SDLK_b, SDLK_n, SDLK_m, SDLK_COMMA, SDLK_PERIOD, SDLK_SLASH, SDLK_RSHIFT, SDLK_KP_MULTIPLY, + SDLK_LALT, SDLK_SPACE, SDLK_CAPSLOCK, SDLK_F1, SDLK_F2, SDLK_F3, SDLK_F4, SDLK_F5, SDLK_F6, SDLK_F7, SDLK_F8, SDLK_F9, SDLK_F10, SDLK_NUMLOCKCLEAR, SDLK_SCROLLLOCK, SDLK_KP_7, SDLK_KP_8, SDLK_KP_9, SDLK_KP_MINUS, SDLK_KP_4, SDLK_KP_5, SDLK_KP_6, SDLK_KP_PLUS, SDLK_KP_1, SDLK_KP_2, SDLK_KP_3, SDLK_KP_0, SDLK_KP_PERIOD, 0, 0, 0, SDLK_F11, @@ -62,24 +61,58 @@ static SDL_Keycode DIKToKeySym[256] = 0, 0, 0, 0, SDLK_KP_ENTER, SDLK_RCTRL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, SDLK_KP_DIVIDE, 0, SDLK_SYSREQ, + 0, 0, 0, SDLK_KP_COMMA, 0, SDLK_KP_DIVIDE, 0, SDLK_SYSREQ, SDLK_RALT, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, SDLK_PAUSE, 0, SDLK_HOME, SDLK_UP, SDLK_PAGEUP, 0, SDLK_LEFT, 0, SDLK_RIGHT, 0, SDLK_END, SDLK_DOWN, SDLK_PAGEDOWN, SDLK_INSERT, SDLK_DELETE, 0, 0, 0, 0, - 0, 0, 0, SDLK_LGUI, SDLK_RGUI, SDLK_MENU, SDLK_POWER, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, SDLK_LGUI, SDLK_RGUI, SDLK_MENU, SDLK_POWER, SDLK_SLEEP, + 0, 0, 0, 0, 0, SDLK_AC_SEARCH, SDLK_AC_BOOKMARKS, SDLK_AC_REFRESH, + SDLK_AC_STOP, SDLK_AC_FORWARD, SDLK_AC_BACK, SDLK_COMPUTER, SDLK_MAIL, SDLK_MEDIASELECT, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; -static void FlushDIKState (int low=0, int high=NUM_KEYS-1) +static const SDL_Scancode DIKToKeyScan[256] = { -} + SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_ESCAPE, SDL_SCANCODE_1, SDL_SCANCODE_2, SDL_SCANCODE_3, SDL_SCANCODE_4, SDL_SCANCODE_5, SDL_SCANCODE_6, + SDL_SCANCODE_7, SDL_SCANCODE_8, SDL_SCANCODE_9, SDL_SCANCODE_0 ,SDL_SCANCODE_MINUS, SDL_SCANCODE_EQUALS, SDL_SCANCODE_BACKSPACE, SDL_SCANCODE_TAB, + SDL_SCANCODE_Q, SDL_SCANCODE_W, SDL_SCANCODE_E, SDL_SCANCODE_R, SDL_SCANCODE_T, SDL_SCANCODE_Y, SDL_SCANCODE_U, SDL_SCANCODE_I, + SDL_SCANCODE_O, SDL_SCANCODE_P, SDL_SCANCODE_LEFTBRACKET, SDL_SCANCODE_RIGHTBRACKET, SDL_SCANCODE_RETURN, SDL_SCANCODE_LCTRL, SDL_SCANCODE_A, SDL_SCANCODE_S, + SDL_SCANCODE_D, SDL_SCANCODE_F, SDL_SCANCODE_G, SDL_SCANCODE_H, SDL_SCANCODE_J, SDL_SCANCODE_K, SDL_SCANCODE_L, SDL_SCANCODE_SEMICOLON, + SDL_SCANCODE_APOSTROPHE, SDL_SCANCODE_GRAVE, SDL_SCANCODE_LSHIFT, SDL_SCANCODE_BACKSLASH, SDL_SCANCODE_Z, SDL_SCANCODE_X, SDL_SCANCODE_C, SDL_SCANCODE_V, + SDL_SCANCODE_B, SDL_SCANCODE_N, SDL_SCANCODE_M, SDL_SCANCODE_COMMA, SDL_SCANCODE_PERIOD, SDL_SCANCODE_SLASH, SDL_SCANCODE_RSHIFT, SDL_SCANCODE_KP_MULTIPLY, + SDL_SCANCODE_LALT, SDL_SCANCODE_SPACE, SDL_SCANCODE_CAPSLOCK, SDL_SCANCODE_F1, SDL_SCANCODE_F2, SDL_SCANCODE_F3, SDL_SCANCODE_F4, SDL_SCANCODE_F5, + SDL_SCANCODE_F6, SDL_SCANCODE_F7, SDL_SCANCODE_F8, SDL_SCANCODE_F9, SDL_SCANCODE_F10, SDL_SCANCODE_NUMLOCKCLEAR, SDL_SCANCODE_SCROLLLOCK, SDL_SCANCODE_KP_7, + SDL_SCANCODE_KP_8, SDL_SCANCODE_KP_9, SDL_SCANCODE_KP_MINUS, SDL_SCANCODE_KP_4, SDL_SCANCODE_KP_5, SDL_SCANCODE_KP_6, SDL_SCANCODE_KP_PLUS, SDL_SCANCODE_KP_1, + SDL_SCANCODE_KP_2, SDL_SCANCODE_KP_3, SDL_SCANCODE_KP_0, SDL_SCANCODE_KP_PERIOD, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_F11, + SDL_SCANCODE_F12, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, + SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_F13, SDL_SCANCODE_F14, SDL_SCANCODE_F15, SDL_SCANCODE_UNKNOWN, + SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, + SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, + SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, + SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, + SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_KP_EQUALS, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, + SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, + SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_KP_ENTER, SDL_SCANCODE_RCTRL, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, + SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, + SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, + SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_KP_COMMA, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_KP_DIVIDE, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_SYSREQ, + SDL_SCANCODE_RALT, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, + SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_PAUSE, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_HOME, + SDL_SCANCODE_UP, SDL_SCANCODE_PAGEUP, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_LEFT, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_RIGHT, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_END, + SDL_SCANCODE_DOWN, SDL_SCANCODE_PAGEDOWN, SDL_SCANCODE_INSERT, SDL_SCANCODE_DELETE, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, + SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_LGUI, SDL_SCANCODE_RGUI, SDL_SCANCODE_MENU, SDL_SCANCODE_POWER, SDL_SCANCODE_SLEEP, + SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_AC_SEARCH, SDL_SCANCODE_AC_BOOKMARKS, SDL_SCANCODE_AC_REFRESH, + SDL_SCANCODE_AC_STOP, SDL_SCANCODE_AC_FORWARD, SDL_SCANCODE_AC_BACK, SDL_SCANCODE_COMPUTER, SDL_SCANCODE_MAIL, SDL_SCANCODE_MEDIASELECT, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, + SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, + SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN +}; -static void InitKeySymMap () +static TMap InitKeySymMap () { + TMap KeySymToDIK; + for (int i = 0; i < 256; ++i) { KeySymToDIK[DIKToKeySym[i]] = i; @@ -90,7 +123,23 @@ static void InitKeySymMap () KeySymToDIK[SDLK_RALT] = DIK_LMENU; // Depending on your Linux flavor, you may get SDLK_PRINT or SDLK_SYSREQ KeySymToDIK[SDLK_PRINTSCREEN] = DIK_SYSRQ; + + return KeySymToDIK; } +static const TMap KeySymToDIK(InitKeySymMap()); + +static TMap InitKeyScanMap () +{ + TMap KeyScanToDIK; + + for (int i = 0; i < 256; ++i) + { + KeyScanToDIK[DIKToKeyScan[i]] = i; + } + + return KeyScanToDIK; +} +static const TMap KeyScanToDIK(InitKeyScanMap()); static void I_CheckGUICapture () { @@ -110,7 +159,6 @@ static void I_CheckGUICapture () GUICapture = wantCapt; if (wantCapt) { - FlushDIKState (); memset (DownState, 0, sizeof(DownState)); } } @@ -118,6 +166,8 @@ static void I_CheckGUICapture () void I_SetMouseCapture() { + // Clear out any mouse movement. + SDL_GetRelativeMouseState (NULL, NULL); SDL_SetRelativeMouseMode (SDL_TRUE); } @@ -193,7 +243,7 @@ static bool inGame() static void I_CheckNativeMouse () { - bool focus = SDL_GetMouseFocus() != NULL; + bool focus = SDL_GetKeyboardFocus() != NULL; bool fs = screen->IsFullscreen(); bool wantNative = !focus || (!use_mouse || GUICapture || paused || demoplayback || !inGame()); @@ -202,11 +252,10 @@ static void I_CheckNativeMouse () { NativeMouse = wantNative; SDL_ShowCursor (wantNative); - SDL_SetRelativeMouseMode (wantNative ? SDL_FALSE : SDL_TRUE); if (wantNative) - { - FlushDIKState (KEY_MOUSE1, KEY_MOUSE8); - } + I_ReleaseMouseCapture (); + else + I_SetMouseCapture (); } } @@ -226,10 +275,6 @@ void MessagePump (const SDL_Event &sev) { case SDL_WINDOWEVENT_FOCUS_GAINED: case SDL_WINDOWEVENT_FOCUS_LOST: - if (sev.window.event == SDL_WINDOWEVENT_FOCUS_LOST) - { // kill focus - FlushDIKState (); - } S_SetSoundPaused(sev.window.event == SDL_WINDOWEVENT_FOCUS_GAINED); break; } @@ -309,7 +354,16 @@ void MessagePump (const SDL_Event &sev) if (!GUICapture) { event.type = sev.type == SDL_KEYDOWN ? EV_KeyDown : EV_KeyUp; - event.data1 = KeySymToDIK[sev.key.keysym.sym]; + + // Try to look up our key mapped key for conversion to DirectInput. + // If that fails, then we'll do a lookup against the scan code, + // which may not return the right key, but at least the key should + // work in the game. + if (const BYTE *dik = KeySymToDIK.CheckKey (sev.key.keysym.sym)) + event.data1 = *dik; + else if (const BYTE *dik = KeyScanToDIK.CheckKey (sev.key.keysym.scancode)) + event.data1 = *dik; + if (event.data1) { if (sev.key.keysym.sym < 256) @@ -327,20 +381,17 @@ void MessagePump (const SDL_Event &sev) ((sev.key.keysym.mod & KMOD_CTRL) ? GKM_CTRL : 0) | ((sev.key.keysym.mod & KMOD_ALT) ? GKM_ALT : 0); - //if (sev.key.keysym.sym < SDLK_LAST) + if (event.subtype == EV_GUI_KeyDown) { - if (event.subtype == EV_GUI_KeyDown) + if (DownState[sev.key.keysym.scancode]) { - if (DownState[sev.key.keysym.scancode]) - { - event.subtype = EV_GUI_KeyRepeat; - } - DownState[sev.key.keysym.scancode] = 1; - } - else - { - DownState[sev.key.keysym.scancode] = 0; + event.subtype = EV_GUI_KeyRepeat; } + DownState[sev.key.keysym.scancode] = 1; + } + else + { + DownState[sev.key.keysym.scancode] = 0; } switch (sev.key.keysym.sym) @@ -430,10 +481,5 @@ void I_StartTic () void I_ProcessJoysticks (); void I_StartFrame () { - if (KeySymToDIK[SDLK_BACKSPACE] == 0) - { - InitKeySymMap (); - } - I_ProcessJoysticks(); } diff --git a/src/sdl/i_main.cpp b/src/sdl/i_main.cpp index a928b7e7c..85be7dcef 100644 --- a/src/sdl/i_main.cpp +++ b/src/sdl/i_main.cpp @@ -85,10 +85,6 @@ void Mac_I_FatalError(const char* errortext); // EXTERNAL DATA DECLARATIONS ---------------------------------------------- -#ifdef USE_XCURSOR -extern bool UseXCursor; -#endif - // PUBLIC DATA DEFINITIONS ------------------------------------------------- #ifndef NO_GTK @@ -279,9 +275,6 @@ int main (int argc, char **argv) atterm (SDL_Quit); printf("Using video driver %s\n", SDL_GetCurrentVideoDriver()); -#ifdef USE_XCURSOR - UseXCursor = (strcmp(SDL_GetCurrentVideoDriver(), "x11") == 0); -#endif printf("\n"); #ifdef __APPLE__ diff --git a/src/sdl/sdlvideo.cpp b/src/sdl/sdlvideo.cpp index 71a534f04..a47e2a813 100644 --- a/src/sdl/sdlvideo.cpp +++ b/src/sdl/sdlvideo.cpp @@ -361,7 +361,8 @@ SDLFB::~SDLFB () if (Texture) SDL_DestroyTexture (Texture); SDL_DestroyRenderer (Renderer); - } + } + SDL_DestroyWindow (Screen); } } @@ -657,6 +658,6 @@ ADD_STAT (blit) { FString out; out.Format ("blit=%04.1f ms flip=%04.1f ms", - BlitCycles.Time() * 1e-3, SDLFlipCycles.TimeMS()); + BlitCycles.TimeMS(), SDLFlipCycles.TimeMS()); return out; } From 965d602d26167fdec3e6d5c5f6d7f12063d22128 Mon Sep 17 00:00:00 2001 From: Braden Obrzut Date: Thu, 11 Dec 2014 01:35:27 -0500 Subject: [PATCH 06/46] - Improve letterboxing in fullscreen by taking into account animorphic ratio settings. - Added more resolutions to the hard coded table (up to 5K). - Since we're using scaling for fullscreen, we should probably just use the hard coded table for fullscreen resolutions as well. - Fixed: Resolution menu used fake aspect ratio to determine which aspect to file a resolution under. - Added a way to use SDL surface blitting instead of accelerated textures. --- src/menu/videomenu.cpp | 6 +- src/sdl/i_input.cpp | 29 +++++++ src/sdl/sdlvideo.cpp | 185 +++++++++++++++++++++++++++-------------- src/sdl/sdlvideo.h | 1 - 4 files changed, 156 insertions(+), 65 deletions(-) diff --git a/src/menu/videomenu.cpp b/src/menu/videomenu.cpp index 1d1d02383..5e44bbfd4 100644 --- a/src/menu/videomenu.cpp +++ b/src/menu/videomenu.cpp @@ -247,8 +247,12 @@ static void BuildModesList (int hiwidth, int hiheight, int hi_bits) if (Video != NULL) { while ((haveMode = Video->NextMode (&width, &height, &letterbox)) && - (ratiomatch >= 0 && CheckRatio (width, height) != ratiomatch)) + ratiomatch >= 0) { + int ratio; + CheckRatio (width, height, &ratio); + if (ratio == ratiomatch) + break; } } diff --git a/src/sdl/i_input.cpp b/src/sdl/i_input.cpp index ea877e204..210cf2e2c 100644 --- a/src/sdl/i_input.cpp +++ b/src/sdl/i_input.cpp @@ -18,6 +18,8 @@ #include "templates.h" #include "s_sound.h" +void ScaleWithAspect (int &w, int &h, int Width, int Height); + static void I_CheckGUICapture (); static void I_CheckNativeMouse (); @@ -318,6 +320,33 @@ void MessagePump (const SDL_Event &sev) int x, y; SDL_GetMouseState (&x, &y); + // Detect if we're doing scaling in the Window and adjust the mouse + // coordinates accordingly. This could be more efficent, but I + // don't think performance is an issue in the menus. + SDL_Window *focus; + if (screen->IsFullscreen() && (focus = SDL_GetMouseFocus ())) + { + int w, h; + SDL_GetWindowSize (focus, &w, &h); + int realw = w, realh = h; + ScaleWithAspect (realw, realh, SCREENWIDTH, SCREENHEIGHT); + if (realw != SCREENWIDTH || realh != SCREENHEIGHT) + { + double xratio = (double)SCREENWIDTH/realw; + double yratio = (double)SCREENHEIGHT/realh; + if (realw < w) + { + x = (x - (w - realw)/2)*xratio; + y *= yratio; + } + else + { + y = (y - (h - realh)/2)*yratio; + x *= xratio; + } + } + } + event.data1 = x; event.data2 = y; event.type = EV_GUI_Event; diff --git a/src/sdl/sdlvideo.cpp b/src/sdl/sdlvideo.cpp index a47e2a813..5b96389a5 100644 --- a/src/sdl/sdlvideo.cpp +++ b/src/sdl/sdlvideo.cpp @@ -61,9 +61,14 @@ private: SDL_Window *Screen; SDL_Renderer *Renderer; - SDL_Texture *Texture; + union + { + SDL_Texture *Texture; + SDL_Surface *Surface; + }; SDL_Rect UpdateRect; + bool UsingRenderer; bool NeedPalUpdate; bool NeedGammaUpdate; bool NotPaletted; @@ -98,11 +103,9 @@ EXTERN_CVAR (Bool, vid_vsync) CVAR (Int, vid_adapter, 0, CVAR_ARCHIVE|CVAR_GLOBALCONFIG) -CVAR (Int, vid_displaybits, 8, CVAR_ARCHIVE|CVAR_GLOBALCONFIG) +CVAR (Int, vid_displaybits, 32, CVAR_ARCHIVE|CVAR_GLOBALCONFIG) -// vid_asyncblit needs a restart to work. SDL doesn't seem to change if the -// frame buffer is changed at run time. -CVAR (Bool, vid_asyncblit, 1, CVAR_NOINITCALL|CVAR_ARCHIVE|CVAR_GLOBALCONFIG) +CVAR (Bool, vid_forcesurface, false, CVAR_ARCHIVE|CVAR_GLOBALCONFIG) CUSTOM_CVAR (Float, rgamma, 1.f, CVAR_ARCHIVE|CVAR_GLOBALCONFIG) { @@ -151,6 +154,7 @@ static MiniModeInfo WinModes[] = { 960, 600 }, // 16:10 { 960, 720 }, { 1024, 576 }, // 16:9 + { 1024, 600 }, // 17:10 { 1024, 640 }, // 16:10 { 1024, 768 }, { 1088, 612 }, // 16:9 @@ -160,6 +164,7 @@ static MiniModeInfo WinModes[] = { 1280, 720 }, // 16:9 { 1280, 800 }, // 16:10 { 1280, 960 }, + { 1280, 1024 }, // 5:4 { 1360, 768 }, // 16:9 { 1400, 787 }, // 16:9 { 1400, 875 }, // 16:10 @@ -168,6 +173,13 @@ static MiniModeInfo WinModes[] = { 1600, 1000 }, // 16:10 { 1600, 1200 }, { 1920, 1080 }, + { 1920, 1200 }, + { 2048, 1536 }, + { 2560, 1440 }, + { 2560, 1600 }, + { 2880, 1800 }, + { 3840, 2160 }, + { 5120, 2880 } }; static cycle_t BlitCycles; @@ -175,10 +187,34 @@ static cycle_t SDLFlipCycles; // CODE -------------------------------------------------------------------- +void ScaleWithAspect (int &w, int &h, int Width, int Height) +{ + int resRatio = CheckRatio (Width, Height); + int screenRatio; + CheckRatio (w, h, &screenRatio); + if (resRatio == screenRatio) + return; + + double yratio; + switch(resRatio) + { + case 0: yratio = 4./3.; break; + case 1: yratio = 16./9.; break; + case 2: yratio = 16./10.; break; + case 3: yratio = 17./10.; break; + case 4: yratio = 5./4.; break; + default: return; + } + double y = w/yratio; + if (y > h) + w = h*yratio; + else + h = y; +} + SDLVideo::SDLVideo (int parm) { IteratorBits = 0; - IteratorFS = false; } SDLVideo::~SDLVideo () @@ -189,38 +225,18 @@ void SDLVideo::StartModeIterator (int bits, bool fs) { IteratorMode = 0; IteratorBits = bits; - IteratorFS = fs; } bool SDLVideo::NextMode (int *width, int *height, bool *letterbox) { if (IteratorBits != 8) return false; - - if (!IteratorFS) - { - if ((unsigned)IteratorMode < sizeof(WinModes)/sizeof(WinModes[0])) - { - *width = WinModes[IteratorMode].Width; - *height = WinModes[IteratorMode].Height; - ++IteratorMode; - return true; - } - } - else - { - SDL_DisplayMode mode = {}, oldmode = {}; - if(IteratorMode != 0) - SDL_GetDisplayMode(vid_adapter, IteratorMode-1, &oldmode); - do - { - if (SDL_GetDisplayMode(vid_adapter, IteratorMode, &mode) != 0) - return false; - ++IteratorMode; - } while(mode.w == oldmode.w && mode.h == oldmode.h); - *width = mode.w; - *height = mode.h; + if ((unsigned)IteratorMode < sizeof(WinModes)/sizeof(WinModes[0])) + { + *width = WinModes[IteratorMode].Width; + *height = WinModes[IteratorMode].Height; + ++IteratorMode; return true; } return false; @@ -431,8 +447,19 @@ void SDLFB::Update () void *pixels; int pitch; - if (SDL_LockTexture (Texture, NULL, &pixels, &pitch)) - return; + if (UsingRenderer) + { + if (SDL_LockTexture (Texture, NULL, &pixels, &pitch)) + return; + } + else + { + if (SDL_LockSurface (Surface)) + return; + + pixels = Surface->pixels; + pitch = Surface->pitch; + } if (NotPaletted) { @@ -440,29 +467,38 @@ void SDLFB::Update () pixels, pitch, Width, Height, FRACUNIT, FRACUNIT, 0, 0); } -#if 0 else { - if (Screen->pitch == Pitch) + if (pitch == Pitch) { - memcpy (Screen->pixels, MemBuffer, Width*Height); + memcpy (pixels, MemBuffer, Width*Height); } else { for (int y = 0; y < Height; ++y) { - memcpy ((BYTE *)Screen->pixels+y*Screen->pitch, MemBuffer+y*Pitch, Width); + memcpy ((BYTE *)pixels+y*pitch, MemBuffer+y*Pitch, Width); } } } -#endif - SDL_UnlockTexture (Texture); + if (UsingRenderer) + { + SDL_UnlockTexture (Texture); - SDLFlipCycles.Clock(); - SDL_RenderCopy(Renderer, Texture, NULL, &UpdateRect); - SDL_RenderPresent(Renderer); - SDLFlipCycles.Unclock(); + SDLFlipCycles.Clock(); + SDL_RenderCopy(Renderer, Texture, NULL, &UpdateRect); + SDL_RenderPresent(Renderer); + SDLFlipCycles.Unclock(); + } + else + { + SDL_UnlockSurface (Surface); + + SDLFlipCycles.Clock(); + SDL_UpdateWindowSurface (Screen); + SDLFlipCycles.Unclock(); + } BlitCycles.Unclock(); @@ -503,7 +539,6 @@ void SDLFB::UpdateColors () } GPfx.SetPalette (palette); } -#if 0 else { SDL_Color colors[256]; @@ -520,9 +555,8 @@ void SDLFB::UpdateColors () 256, GammaTable[2][Flash.b], GammaTable[1][Flash.g], GammaTable[0][Flash.r], FlashAmount); } - SDL_SetPalette (Screen, SDL_LOGPAL|SDL_PHYSPAL, colors, 0, 256); + SDL_SetPaletteColors (Surface->format->palette, colors, 0, 256); } -#endif } PalEntry *SDLFB::GetPalette () @@ -592,24 +626,48 @@ void SDLFB::ResetSDLRenderer () SDL_DestroyRenderer (Renderer); } - Renderer = SDL_CreateRenderer (Screen, -1,SDL_RENDERER_ACCELERATED|SDL_RENDERER_TARGETTEXTURE| - (vid_vsync ? SDL_RENDERER_PRESENTVSYNC : 0)); - if (!Renderer) - return; - - Texture = SDL_CreateTexture (Renderer, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_STREAMING, Width, Height); - - //if (Screen->format->palette == NULL) + UsingRenderer = !vid_forcesurface; + if (UsingRenderer) { - NotPaletted = true; + Renderer = SDL_CreateRenderer (Screen, -1,SDL_RENDERER_ACCELERATED|SDL_RENDERER_TARGETTEXTURE| + (vid_vsync ? SDL_RENDERER_PRESENTVSYNC : 0)); + if (!Renderer) + return; - Uint32 format; - SDL_QueryTexture(Texture, &format, NULL, NULL, NULL); + Uint32 fmt; + switch(vid_displaybits) + { + default: fmt = SDL_PIXELFORMAT_ARGB8888; break; + case 30: fmt = SDL_PIXELFORMAT_ARGB2101010; break; + case 24: fmt = SDL_PIXELFORMAT_RGB888; break; + case 16: fmt = SDL_PIXELFORMAT_RGB565; break; + case 15: fmt = SDL_PIXELFORMAT_ARGB1555; break; + } + Texture = SDL_CreateTexture (Renderer, fmt, SDL_TEXTUREACCESS_STREAMING, Width, Height); - Uint32 Rmask, Gmask, Bmask, Amask; - int bpp; - SDL_PixelFormatEnumToMasks(format, &bpp, &Rmask, &Gmask, &Bmask, &Amask); - GPfx.SetFormat (bpp, Rmask, Gmask, Bmask); + { + NotPaletted = true; + + Uint32 format; + SDL_QueryTexture(Texture, &format, NULL, NULL, NULL); + + Uint32 Rmask, Gmask, Bmask, Amask; + int bpp; + SDL_PixelFormatEnumToMasks(format, &bpp, &Rmask, &Gmask, &Bmask, &Amask); + GPfx.SetFormat (bpp, Rmask, Gmask, Bmask); + } + } + else + { + Surface = SDL_GetWindowSurface (Screen); + + if (Surface->format->palette == NULL) + { + NotPaletted = true; + GPfx.SetFormat (Surface->format->BitsPerPixel, Surface->format->Rmask, Surface->format->Gmask, Surface->format->Bmask); + } + else + NotPaletted = false; } // Calculate update rectangle @@ -618,8 +676,9 @@ void SDLFB::ResetSDLRenderer () int w, h; SDL_GetWindowSize (Screen, &w, &h); UpdateRect.w = w; - UpdateRect.h = w*Height/Width; - UpdateRect.x = 0; + UpdateRect.h = h; + ScaleWithAspect (UpdateRect.w, UpdateRect.h, Width, Height); + UpdateRect.x = (w - UpdateRect.w)/2; UpdateRect.y = (h - UpdateRect.h)/2; } else diff --git a/src/sdl/sdlvideo.h b/src/sdl/sdlvideo.h index 3cd38a140..8869f6fa7 100644 --- a/src/sdl/sdlvideo.h +++ b/src/sdl/sdlvideo.h @@ -18,5 +18,4 @@ class SDLVideo : public IVideo private: int IteratorMode; int IteratorBits; - bool IteratorFS; }; From da8f2185d8fb69df6e012c24add8b01dba2a1f59 Mon Sep 17 00:00:00 2001 From: Braden Obrzut Date: Thu, 11 Dec 2014 16:54:38 -0500 Subject: [PATCH 07/46] - Adapt SDL2 changes for the Mac (both using SDL2 backend and Cocoa). --- src/CMakeLists.txt | 7 +- src/cocoa/i_backend_cocoa.mm | 204 ++++++++++++++++++------- src/{sdl => cocoa}/i_system_cocoa.mm | 0 src/{sdl => cocoa}/iwadpicker_cocoa.mm | 0 src/sdl/i_main.cpp | 18 ++- 5 files changed, 159 insertions(+), 70 deletions(-) rename src/{sdl => cocoa}/i_system_cocoa.mm (100%) rename src/{sdl => cocoa}/iwadpicker_cocoa.mm (100%) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 38e399ef1..61fea294d 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -560,8 +560,8 @@ set( PLAT_SDL_SPECIAL_SOURCES sdl/i_joystick.cpp sdl/i_timer.cpp ) set( PLAT_MAC_SOURCES - sdl/iwadpicker_cocoa.mm - sdl/i_system_cocoa.mm ) + cocoa/iwadpicker_cocoa.mm + cocoa/i_system_cocoa.mm ) set( PLAT_COCOA_SOURCES cocoa/HID_Config_Utilities.c cocoa/HID_Error_Handler.c @@ -581,8 +581,9 @@ if( APPLE ) if( OSX_COCOA_BACKEND ) set( PLAT_MAC_SOURCES ${PLAT_MAC_SOURCES} ${PLAT_COCOA_SOURCES} ) + add_definitions( -DUSE_NATIVE_COCOA ) else( OSX_COCOA_BACKEND ) - set( PLAT_MAC_SOURCES ${PLAT_MAC_SOURCES} ${PLAT_SDL_SPECIAL_SOURCES} sdl/SDLMain.m ) + set( PLAT_MAC_SOURCES ${PLAT_MAC_SOURCES} ${PLAT_SDL_SPECIAL_SOURCES} ) endif( OSX_COCOA_BACKEND ) set_source_files_properties( cocoa/zdoom.icns PROPERTIES MACOSX_PACKAGE_LOCATION Resources ) diff --git a/src/cocoa/i_backend_cocoa.mm b/src/cocoa/i_backend_cocoa.mm index bd3dc3115..df2a1f450 100644 --- a/src/cocoa/i_backend_cocoa.mm +++ b/src/cocoa/i_backend_cocoa.mm @@ -1702,37 +1702,27 @@ void SDL_Quit() } -char* SDL_GetError() +const char* SDL_GetError() { static char empty[] = {0}; return empty; } -char* SDL_VideoDriverName(char* namebuf, int maxlen) +const char* SDL_GetCurrentVideoDriver() { - return strncpy(namebuf, "Native OpenGL", maxlen); + return "Native OpenGL"; } -const SDL_VideoInfo* SDL_GetVideoInfo() +int SDL_GetDesktopDisplayMode(int displayIndex, SDL_DisplayMode *mode) { - // NOTE: Only required fields are assigned - - static SDL_PixelFormat pixelFormat; - memset(&pixelFormat, 0, sizeof(pixelFormat)); - - pixelFormat.BitsPerPixel = 32; - - static SDL_VideoInfo videoInfo; - memset(&videoInfo, 0, sizeof(videoInfo)); - + // NOTE: Only required fields are assigned const NSRect displayRect = [[NSScreen mainScreen] frame]; - videoInfo.current_w = displayRect.size.width; - videoInfo.current_h = displayRect.size.height; - videoInfo.vfmt = &pixelFormat; + mode->w = displayRect.size.width; + mode->h = displayRect.size.height; - return &videoInfo; + return 0; } SDL_Rect** SDL_ListModes(SDL_PixelFormat* format, Uint32 flags) @@ -1820,73 +1810,151 @@ static SDL_PixelFormat* GetPixelFormat() result.Rmask = 0x000000FF; result.Gmask = 0x0000FF00; result.Bmask = 0x00FF0000; - result.Amask = 0xFF000000; - result.colorkey = 0; - result.alpha = 0xFF; + result.Amask = 0xFF000000; return &result; } - -SDL_Surface* SDL_SetVideoMode(int width, int height, int, Uint32 flags) +SDL_bool SDL_PixelFormatEnumToMasks(Uint32 format, int* bpp, Uint32* Rmask, Uint32* Gmask, Uint32* Bmask, Uint32* Amask) { - [appCtrl changeVideoResolution:(SDL_FULLSCREEN & flags) + assert(format == SDL_PIXELFORMAT_ABGR8888); + + *bpp = 32; + *Rmask = 0x000000FF; + *Gmask = 0x0000FF00; + *Bmask = 0x00FF0000; + *Amask = 0xFF000000; + + return SDL_TRUE; +} + +struct SDL_Window +{ + Uint32 flags; + int w, h; + int pitch; + void *pixels; +}; + +struct SDL_Renderer { SDL_Window *window; }; +struct SDL_Texture { SDL_Window *window; }; + +SDL_Window* SDL_CreateWindow(const char* title, int x, int y, int width, int height, Uint32 flags) +{ + [appCtrl changeVideoResolution:(SDL_WINDOW_FULLSCREEN_DESKTOP & flags) width:width height:height useHiDPI:vid_hidpi]; - static SDL_Surface result; + static SDL_Window result; - if (!(SDL_OPENGL & flags)) + if (!(SDL_WINDOW_OPENGL & flags)) { [appCtrl setupSoftwareRenderingWithWidth:width height:height]; } result.flags = flags; - result.format = GetPixelFormat(); result.w = width; result.h = height; result.pitch = width * BYTES_PER_PIXEL; result.pixels = [appCtrl softwareRenderingBuffer]; - result.refcount = 1; - - result.clip_rect.x = 0; - result.clip_rect.y = 0; - result.clip_rect.w = width; - result.clip_rect.h = height; - + return &result; } - - -void SDL_WM_SetCaption(const char* title, const char* icon) +void SDL_DestroyWindow(SDL_Window *window) { - ZD_UNUSED(title); - ZD_UNUSED(icon); - - // Window title is set in SDL_SetVideoMode() + ZD_UNUSED(window); } -int SDL_WM_ToggleFullScreen(SDL_Surface* surface) +Uint32 SDL_GetWindowFlags(SDL_Window *window) { - if (surface->flags & SDL_FULLSCREEN) + return window->flags; +} + +SDL_Surface *SDL_GetWindowSurface(SDL_Window *window) +{ + ZD_UNUSED(window); + return NULL; +} + +void SDL_GetWindowSize(SDL_Window *window, int *w, int *h) +{ + *w = window->w; + *h = window->h; +} + +void SDL_SetWindowSize(SDL_Window *window, int w, int h) +{ + // Currently this is used for handling the fullscreen->windowed transition. + // We can just no-op this for now. + ZD_UNUSED(window); + ZD_UNUSED(w); + ZD_UNUSED(h); +} + +int SDL_SetWindowFullscreen(SDL_Window* window, Uint32 flags) +{ + if ((window->flags & SDL_WINDOW_FULLSCREEN_DESKTOP) == (flags & SDL_WINDOW_FULLSCREEN_DESKTOP)) + return 0; + + if (window->flags & SDL_WINDOW_FULLSCREEN_DESKTOP) { - surface->flags &= ~SDL_FULLSCREEN; + window->flags &= ~SDL_WINDOW_FULLSCREEN_DESKTOP; } else { - surface->flags |= SDL_FULLSCREEN; + window->flags |= SDL_WINDOW_FULLSCREEN_DESKTOP; } - [appCtrl changeVideoResolution:(SDL_FULLSCREEN & surface->flags) - width:surface->w - height:surface->h + [appCtrl changeVideoResolution:(SDL_WINDOW_FULLSCREEN_DESKTOP & flags) + width:window->w + height:window->h useHiDPI:vid_hidpi]; - return 1; + return 0; } +SDL_Renderer *SDL_CreateRenderer(SDL_Window *window, int index, Uint32 flags) +{ + ZD_UNUSED(index); + ZD_UNUSED(flags); + + static SDL_Renderer result; + result.window = window; + + return &result; +} +void SDL_DestroyRenderer(SDL_Renderer *renderer) +{ + ZD_UNUSED(renderer); +} + +SDL_Texture *SDL_CreateTexture(SDL_Renderer *renderer, Uint32 format, int access, int w, int h) +{ + ZD_UNUSED(format); + ZD_UNUSED(access); + ZD_UNUSED(w); + ZD_UNUSED(h); + + static SDL_Texture result; + result.window = renderer->window; + + return &result; +} +void SDL_DestroyTexture(SDL_Texture *texture) +{ + ZD_UNUSED(texture); +} + +int SDL_QueryTexture(SDL_Texture *texture, Uint32* format, int* access, int* w, int* h) +{ + if(format) *format = SDL_PIXELFORMAT_ABGR8888; + if(access) *access = SDL_TEXTUREACCESS_STREAMING; + if(w) *w = texture->window->w; + if(h) *h = texture->window->h; + return 0; +} void SDL_GL_SwapBuffers() { @@ -1918,18 +1986,22 @@ void SDL_UnlockSurface(SDL_Surface* surface) ZD_UNUSED(surface); } -int SDL_BlitSurface(SDL_Surface* src, SDL_Rect* srcrect, SDL_Surface* dst, SDL_Rect* dstrect) +int SDL_LockTexture(SDL_Texture* texture, const SDL_Rect *rect, void** pixels, int *pitch) { - ZD_UNUSED(src); - ZD_UNUSED(srcrect); - ZD_UNUSED(dst); - ZD_UNUSED(dstrect); - + assert(NULL == rect); + + *pixels = texture->window->pixels; + *pitch = texture->window->pitch; + return 0; } +void SDL_UnlockTexture(SDL_Texture *texture) +{ + ZD_UNUSED(texture); +} -int SDL_Flip(SDL_Surface* screen) +int SDL_UpdateWindowSurface(SDL_Window *screen) { assert(NULL != screen); @@ -1976,10 +2048,24 @@ int SDL_Flip(SDL_Surface* screen) return 0; } -int SDL_SetPalette(SDL_Surface* surface, int flags, SDL_Color* colors, int firstcolor, int ncolors) +int SDL_RenderCopy(SDL_Renderer *renderer, SDL_Texture *texture, const SDL_Rect *srcrect, const SDL_Rect *dstrect) { - ZD_UNUSED(surface); - ZD_UNUSED(flags); + ZD_UNUSED(renderer); + ZD_UNUSED(texture); + ZD_UNUSED(srcrect); + ZD_UNUSED(dstrect); + + return 0; +} + +void SDL_RenderPresent(SDL_Renderer *renderer) +{ + SDL_UpdateWindowSurface(renderer->window); +} + +int SDL_SetPaletteColors(SDL_Palette* palette, const SDL_Color* colors, int firstcolor, int ncolors) +{ + ZD_UNUSED(palette); ZD_UNUSED(colors); ZD_UNUSED(firstcolor); ZD_UNUSED(ncolors); diff --git a/src/sdl/i_system_cocoa.mm b/src/cocoa/i_system_cocoa.mm similarity index 100% rename from src/sdl/i_system_cocoa.mm rename to src/cocoa/i_system_cocoa.mm diff --git a/src/sdl/iwadpicker_cocoa.mm b/src/cocoa/iwadpicker_cocoa.mm similarity index 100% rename from src/sdl/iwadpicker_cocoa.mm rename to src/cocoa/iwadpicker_cocoa.mm diff --git a/src/sdl/i_main.cpp b/src/sdl/i_main.cpp index 85be7dcef..33395e0f1 100644 --- a/src/sdl/i_main.cpp +++ b/src/sdl/i_main.cpp @@ -237,7 +237,11 @@ void I_ShutdownJoysticks(); const char* I_GetBackEndName(); +#ifdef USE_NATIVE_COCOA +int SDL_main (int argc, char **argv) +#else int main (int argc, char **argv) +#endif { #if !defined (__APPLE__) { @@ -278,9 +282,9 @@ int main (int argc, char **argv) printf("\n"); #ifdef __APPLE__ - - const SDL_VideoInfo* videoInfo = SDL_GetVideoInfo(); - if ( NULL != videoInfo ) + EXTERN_CVAR( Int, vid_adapter ) + SDL_DisplayMode videoInfo = {}; + if ( SDL_GetDesktopDisplayMode (vid_adapter, &videoInfo) == 0 ) { EXTERN_CVAR( Int, vid_defwidth ) EXTERN_CVAR( Int, vid_defheight ) @@ -288,13 +292,11 @@ int main (int argc, char **argv) EXTERN_CVAR( Bool, vid_vsync ) EXTERN_CVAR( Bool, fullscreen ) - vid_defwidth = videoInfo->current_w; - vid_defheight = videoInfo->current_h; - vid_defbits = videoInfo->vfmt->BitsPerPixel; + vid_defwidth = videoInfo.w; + vid_defheight = videoInfo.h; vid_vsync = true; fullscreen = true; - } - + } #endif // __APPLE__ try From 6241f047a89e3064d99e84969671f5b45181e0dd Mon Sep 17 00:00:00 2001 From: "alexey.lysiuk" Date: Sat, 13 Dec 2014 12:32:20 +0200 Subject: [PATCH 08/46] Removed no longer used SDL wrapper functions from OS X native backend --- src/cocoa/i_backend_cocoa.mm | 70 ------------------------------------ 1 file changed, 70 deletions(-) diff --git a/src/cocoa/i_backend_cocoa.mm b/src/cocoa/i_backend_cocoa.mm index df2a1f450..6abf1b7d1 100644 --- a/src/cocoa/i_backend_cocoa.mm +++ b/src/cocoa/i_backend_cocoa.mm @@ -1725,72 +1725,6 @@ int SDL_GetDesktopDisplayMode(int displayIndex, SDL_DisplayMode *mode) return 0; } -SDL_Rect** SDL_ListModes(SDL_PixelFormat* format, Uint32 flags) -{ - ZD_UNUSED(format); - ZD_UNUSED(flags); - - static std::vector resolutions; - - if (resolutions.empty()) - { -#define DEFINE_RESOLUTION(WIDTH, HEIGHT) \ - static SDL_Rect resolution_##WIDTH##_##HEIGHT = { 0, 0, WIDTH, HEIGHT }; \ - resolutions.push_back(&resolution_##WIDTH##_##HEIGHT); - - DEFINE_RESOLUTION( 640, 480); - DEFINE_RESOLUTION( 720, 480); - DEFINE_RESOLUTION( 800, 480); - DEFINE_RESOLUTION( 800, 600); - DEFINE_RESOLUTION(1024, 600); - DEFINE_RESOLUTION(1024, 640); - DEFINE_RESOLUTION(1024, 768); - DEFINE_RESOLUTION(1152, 720); - DEFINE_RESOLUTION(1152, 864); - DEFINE_RESOLUTION(1280, 720); - DEFINE_RESOLUTION(1280, 768); - DEFINE_RESOLUTION(1280, 800); - DEFINE_RESOLUTION(1280, 854); - DEFINE_RESOLUTION(1280, 960); - DEFINE_RESOLUTION(1280, 1024); - DEFINE_RESOLUTION(1366, 768); - DEFINE_RESOLUTION(1400, 1050); - DEFINE_RESOLUTION(1440, 900); - DEFINE_RESOLUTION(1440, 960); - DEFINE_RESOLUTION(1440, 1080); - DEFINE_RESOLUTION(1600, 900); - DEFINE_RESOLUTION(1600, 1200); - DEFINE_RESOLUTION(1680, 1050); - DEFINE_RESOLUTION(1920, 1080); - DEFINE_RESOLUTION(1920, 1200); - DEFINE_RESOLUTION(2048, 1080); - DEFINE_RESOLUTION(2048, 1536); - DEFINE_RESOLUTION(2560, 1080); - DEFINE_RESOLUTION(2560, 1440); - DEFINE_RESOLUTION(2560, 1600); - DEFINE_RESOLUTION(2560, 2048); - DEFINE_RESOLUTION(2880, 1800); - DEFINE_RESOLUTION(3200, 1800); - DEFINE_RESOLUTION(3440, 1440); - DEFINE_RESOLUTION(3840, 2160); - DEFINE_RESOLUTION(3840, 2400); - DEFINE_RESOLUTION(4096, 2160); - DEFINE_RESOLUTION(5120, 2880); - -#undef DEFINE_RESOLUTION - - resolutions.push_back(NULL); - } - - return &resolutions[0]; -} - -int SDL_ShowCursor(int) -{ - // Does nothing - return 0; -} - static SDL_PixelFormat* GetPixelFormat() { @@ -2205,10 +2139,6 @@ DarwinVersion GetDarwinVersion() const DarwinVersion darwinVersion = GetDarwinVersion(); -#ifdef main -#undef main -#endif // main - int main(int argc, char** argv) { gettimeofday(&s_startTicks, NULL); From 9837721d7f882ed2e86206f36e7b10cd5352a79c Mon Sep 17 00:00:00 2001 From: "alexey.lysiuk" Date: Sat, 13 Dec 2014 12:32:29 +0200 Subject: [PATCH 09/46] Added several missing video resolutions All feasible display dimensions are in the list except with 21:9 aspect ratio --- src/sdl/sdlvideo.cpp | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/sdl/sdlvideo.cpp b/src/sdl/sdlvideo.cpp index 5b96389a5..e477df526 100644 --- a/src/sdl/sdlvideo.cpp +++ b/src/sdl/sdlvideo.cpp @@ -148,6 +148,7 @@ static MiniModeInfo WinModes[] = { 720, 480 }, // 16:10 { 720, 540 }, { 800, 450 }, // 16:9 + { 800, 480 }, { 800, 500 }, // 16:10 { 800, 600 }, { 848, 480 }, // 16:9 @@ -162,13 +163,18 @@ static MiniModeInfo WinModes[] = { 1152, 720 }, // 16:10 { 1152, 864 }, { 1280, 720 }, // 16:9 + { 1280, 854 }, { 1280, 800 }, // 16:10 { 1280, 960 }, { 1280, 1024 }, // 5:4 { 1360, 768 }, // 16:9 + { 1366, 768 }, { 1400, 787 }, // 16:9 { 1400, 875 }, // 16:10 { 1400, 1050 }, + { 1440, 900 }, + { 1440, 960 }, + { 1440, 1080 }, { 1600, 900 }, // 16:9 { 1600, 1000 }, // 16:10 { 1600, 1200 }, @@ -177,8 +183,12 @@ static MiniModeInfo WinModes[] = { 2048, 1536 }, { 2560, 1440 }, { 2560, 1600 }, + { 2560, 2048 }, { 2880, 1800 }, + { 3200, 1800 }, { 3840, 2160 }, + { 3840, 2400 }, + { 4096, 2160 }, { 5120, 2880 } }; From 8d16c2e3c0d4e90cd45702ed81e12f2200347721 Mon Sep 17 00:00:00 2001 From: "alexey.lysiuk" Date: Sun, 14 Dec 2014 11:29:28 +0200 Subject: [PATCH 10/46] OS X native backend no longer use files from src/sdl directly Cocoa backend is compiling but failed to link Some files are referenced using symbolic links Apple's HID Utilities were moved to own directory --- src/CMakeLists.txt | 72 +++++++++++--------- src/cocoa/critsec.cpp | 62 +++++++++++++++++ src/cocoa/critsec.h | 53 ++++++++++++++ src/cocoa/dikeys.h | 1 + src/cocoa/hardware.h | 1 + src/cocoa/{ => hid}/HID_Config_Utilities.c | 0 src/cocoa/{ => hid}/HID_Error_Handler.c | 0 src/cocoa/{ => hid}/HID_Name_Lookup.c | 0 src/cocoa/{ => hid}/HID_Queue_Utilities.c | 0 src/cocoa/{ => hid}/HID_Utilities.c | 0 src/cocoa/{ => hid}/HID_Utilities_External.h | 0 src/cocoa/{ => hid}/IOHIDDevice_.c | 0 src/cocoa/{ => hid}/IOHIDDevice_.h | 0 src/cocoa/{ => hid}/IOHIDElement_.c | 0 src/cocoa/{ => hid}/IOHIDElement_.h | 0 src/cocoa/{ => hid}/IOHIDLib_.h | 0 src/cocoa/{ => hid}/ImmrHIDUtilAddOn.c | 0 src/cocoa/{ => hid}/ImmrHIDUtilAddOn.h | 0 src/cocoa/i_backend_cocoa.mm | 42 ------------ src/cocoa/i_cd.cpp | 1 + src/cocoa/i_input.h | 1 + src/cocoa/i_joystick.cpp | 2 +- src/cocoa/i_movie.cpp | 1 + src/cocoa/i_system.h | 1 + src/cocoa/st_start.cpp | 1 + 25 files changed, 161 insertions(+), 77 deletions(-) create mode 100644 src/cocoa/critsec.cpp create mode 100644 src/cocoa/critsec.h create mode 120000 src/cocoa/dikeys.h create mode 120000 src/cocoa/hardware.h rename src/cocoa/{ => hid}/HID_Config_Utilities.c (100%) rename src/cocoa/{ => hid}/HID_Error_Handler.c (100%) rename src/cocoa/{ => hid}/HID_Name_Lookup.c (100%) rename src/cocoa/{ => hid}/HID_Queue_Utilities.c (100%) rename src/cocoa/{ => hid}/HID_Utilities.c (100%) rename src/cocoa/{ => hid}/HID_Utilities_External.h (100%) rename src/cocoa/{ => hid}/IOHIDDevice_.c (100%) rename src/cocoa/{ => hid}/IOHIDDevice_.h (100%) rename src/cocoa/{ => hid}/IOHIDElement_.c (100%) rename src/cocoa/{ => hid}/IOHIDElement_.h (100%) rename src/cocoa/{ => hid}/IOHIDLib_.h (100%) rename src/cocoa/{ => hid}/ImmrHIDUtilAddOn.c (100%) rename src/cocoa/{ => hid}/ImmrHIDUtilAddOn.h (100%) create mode 120000 src/cocoa/i_cd.cpp create mode 120000 src/cocoa/i_input.h create mode 120000 src/cocoa/i_movie.cpp create mode 120000 src/cocoa/i_system.h create mode 120000 src/cocoa/st_start.cpp diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 61fea294d..2e6bb59f5 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -545,7 +545,7 @@ set( PLAT_WIN32_SOURCES win32/i_system.cpp win32/st_start.cpp win32/win32video.cpp ) -set( PLAT_SDL_SYSTEM_SOURCES +set( PLAT_SDL_SOURCES sdl/crashcatcher.c sdl/hardware.cpp sdl/i_cd.cpp @@ -553,8 +553,7 @@ set( PLAT_SDL_SYSTEM_SOURCES sdl/i_movie.cpp sdl/i_system.cpp sdl/sdlvideo.cpp - sdl/st_start.cpp ) -set( PLAT_SDL_SPECIAL_SOURCES + sdl/st_start.cpp sdl/i_gui.cpp sdl/i_input.cpp sdl/i_joystick.cpp @@ -563,39 +562,27 @@ set( PLAT_MAC_SOURCES cocoa/iwadpicker_cocoa.mm cocoa/i_system_cocoa.mm ) set( PLAT_COCOA_SOURCES - cocoa/HID_Config_Utilities.c - cocoa/HID_Error_Handler.c - cocoa/HID_Name_Lookup.c - cocoa/HID_Queue_Utilities.c - cocoa/HID_Utilities.c - cocoa/IOHIDDevice_.c - cocoa/IOHIDElement_.c - cocoa/ImmrHIDUtilAddOn.c + cocoa/hid/HID_Config_Utilities.c + cocoa/hid/HID_Error_Handler.c + cocoa/hid/HID_Name_Lookup.c + cocoa/hid/HID_Queue_Utilities.c + cocoa/hid/HID_Utilities.c + cocoa/hid/IOHIDDevice_.c + cocoa/hid/IOHIDElement_.c + cocoa/hid/ImmrHIDUtilAddOn.c + cocoa/critsec.cpp cocoa/i_backend_cocoa.mm + cocoa/i_cd.cpp cocoa/i_joystick.cpp + cocoa/i_movie.cpp + cocoa/st_start.cpp cocoa/i_timer.cpp cocoa/zdoom.icns ) -if( APPLE ) - set( PLAT_SDL_SOURCES ${PLAT_SDL_SYSTEM_SOURCES} "${FMOD_LIBRARY}" ) - - if( OSX_COCOA_BACKEND ) - set( PLAT_MAC_SOURCES ${PLAT_MAC_SOURCES} ${PLAT_COCOA_SOURCES} ) - add_definitions( -DUSE_NATIVE_COCOA ) - else( OSX_COCOA_BACKEND ) - set( PLAT_MAC_SOURCES ${PLAT_MAC_SOURCES} ${PLAT_SDL_SPECIAL_SOURCES} ) - endif( OSX_COCOA_BACKEND ) - - set_source_files_properties( cocoa/zdoom.icns PROPERTIES MACOSX_PACKAGE_LOCATION Resources ) - set_source_files_properties( "${FMOD_LIBRARY}" PROPERTIES MACOSX_PACKAGE_LOCATION Frameworks ) -else( APPLE ) - set( PLAT_SDL_SOURCES ${PLAT_SDL_SYSTEM_SOURCES} ${PLAT_SDL_SPECIAL_SOURCES} ) -endif( APPLE ) - if( WIN32 ) set( SYSTEM_SOURCES_DIR win32 ) set( SYSTEM_SOURCES ${PLAT_WIN32_SOURCES} ) - set( OTHER_SYSTEM_SOURCES ${PLAT_SDL_SOURCES} ${PLAT_MAC_SOURCES} ) + set( OTHER_SYSTEM_SOURCES ${PLAT_SDL_SOURCES} ${PLAT_MAC_SOURCES} ${PLAT_COCOA_SOURCES} ) if( ZD_CMAKE_COMPILER_IS_GNUCXX_COMPATIBLE ) # CMake is not set up to compile and link rc files with GCC. :( @@ -606,15 +593,25 @@ if( WIN32 ) else( ZD_CMAKE_COMPILER_IS_GNUCXX_COMPATIBLE ) set( SYSTEM_SOURCES ${SYSTEM_SOURCES} win32/zdoom.rc ) endif( ZD_CMAKE_COMPILER_IS_GNUCXX_COMPATIBLE ) +elseif( APPLE ) + if( OSX_COCOA_BACKEND ) + set( SYSTEM_SOURCES_DIR cocoa ) + set( SYSTEM_SOURCES ${PLAT_COCOA_SOURCES} ) + set( OTHER_SYSTEM_SOURCES ${PLAT_WIN32_SOURCES} ${PLAT_SDL_SOURCES} ) + else( OSX_COCOA_BACKEND ) + set( SYSTEM_SOURCES_DIR sdl ) + set( SYSTEM_SOURCES ${PLAT_SDL_SOURCES} ) + set( OTHER_SYSTEM_SOURCES ${PLAT_WIN32_SOURCES} ${PLAT_COCOA_SOURCES} ) + endif( OSX_COCOA_BACKEND ) + + set( SYSTEM_SOURCES ${SYSTEM_SOURCES} ${PLAT_MAC_SOURCES} "${FMOD_LIBRARY}" ) + + set_source_files_properties( cocoa/zdoom.icns PROPERTIES MACOSX_PACKAGE_LOCATION Resources ) + set_source_files_properties( "${FMOD_LIBRARY}" PROPERTIES MACOSX_PACKAGE_LOCATION Frameworks ) else( WIN32 ) set( SYSTEM_SOURCES_DIR sdl ) set( SYSTEM_SOURCES ${PLAT_SDL_SOURCES} ) - if( APPLE ) - set( SYSTEM_SOURCES ${SYSTEM_SOURCES} ${PLAT_MAC_SOURCES} ) - set( OTHER_SYSTEM_SOURCES ${PLAT_WIN32_SOURCES} ) - else( APPLE ) - set( OTHER_SYSTEM_SOURCES ${PLAT_WIN32_SOURCES} ${PLAT_MAC_SOURCES} ) - endif( APPLE ) + set( OTHER_SYSTEM_SOURCES ${PLAT_WIN32_SOURCES} ${PLAT_MAC_SOURCES} ${PLAT_COCOA_SOURCES} ) endif( WIN32 ) if( NOT ASM_SOURCES ) @@ -672,11 +669,18 @@ endif( DYN_FLUIDSYNTH ) # there's generally a new cpp for every header so this file will get changed if( WIN32 ) set( EXTRA_HEADER_DIRS win32/*.h ) +elseif( APPLE ) + if( OSX_COCOA_BACKEND ) + set( EXTRA_HEADER_DIRS cocoa/*.h ) + else( OSX_COCOA_BACKEND ) + set( EXTRA_HEADER_DIRS sdl/*.h ) + endif( OSX_COCOA_BACKEND ) else( WIN32 ) set( EXTRA_HEADER_DIRS sdl/*.h ) endif( WIN32 ) file( GLOB HEADER_FILES ${EXTRA_HEADER_DIRS} + cocoa/*.h fragglescript/*.h g_doom/*.h g_heretic/*.h diff --git a/src/cocoa/critsec.cpp b/src/cocoa/critsec.cpp new file mode 100644 index 000000000..97bc2251c --- /dev/null +++ b/src/cocoa/critsec.cpp @@ -0,0 +1,62 @@ +/* + ** critsec.cpp + ** + **--------------------------------------------------------------------------- + ** Copyright 2014 Alexey Lysiuk + ** All rights reserved. + ** + ** Redistribution and use in source and binary forms, with or without + ** modification, are permitted provided that the following conditions + ** are met: + ** + ** 1. Redistributions of source code must retain the above copyright + ** notice, this list of conditions and the following disclaimer. + ** 2. Redistributions in binary form must reproduce the above copyright + ** notice, this list of conditions and the following disclaimer in the + ** documentation and/or other materials provided with the distribution. + ** 3. The name of the author may not be used to endorse or promote products + ** derived from this software without specific prior written permission. + ** + ** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + ** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + ** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + ** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + ** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + ** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + ** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + ** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + ** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + ** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + **--------------------------------------------------------------------------- + ** + */ + +#include "critsec.h" + +// TODO: add error handling + +FCriticalSection::FCriticalSection() +{ + pthread_mutexattr_t attributes; + pthread_mutexattr_init(&attributes); + pthread_mutexattr_settype(&attributes, PTHREAD_MUTEX_RECURSIVE); + + pthread_mutex_init(&m_mutex, &attributes); + + pthread_mutexattr_destroy(&attributes); +} + +FCriticalSection::~FCriticalSection() +{ + pthread_mutex_destroy(&m_mutex); +} + +void FCriticalSection::Enter() +{ + pthread_mutex_lock(&m_mutex); +} + +void FCriticalSection::Leave() +{ + pthread_mutex_unlock(&m_mutex); +} diff --git a/src/cocoa/critsec.h b/src/cocoa/critsec.h new file mode 100644 index 000000000..20c476ae3 --- /dev/null +++ b/src/cocoa/critsec.h @@ -0,0 +1,53 @@ +/* + ** critsec.h + ** + **--------------------------------------------------------------------------- + ** Copyright 2014 Alexey Lysiuk + ** All rights reserved. + ** + ** Redistribution and use in source and binary forms, with or without + ** modification, are permitted provided that the following conditions + ** are met: + ** + ** 1. Redistributions of source code must retain the above copyright + ** notice, this list of conditions and the following disclaimer. + ** 2. Redistributions in binary form must reproduce the above copyright + ** notice, this list of conditions and the following disclaimer in the + ** documentation and/or other materials provided with the distribution. + ** 3. The name of the author may not be used to endorse or promote products + ** derived from this software without specific prior written permission. + ** + ** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + ** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + ** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + ** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + ** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + ** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + ** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + ** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + ** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + ** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + **--------------------------------------------------------------------------- + ** + */ + +#ifndef CRITSEC_H +#define CRITSEC_H + +#include + +class FCriticalSection +{ +public: + FCriticalSection(); + ~FCriticalSection(); + + void Enter(); + void Leave(); + +private: + pthread_mutex_t m_mutex; + +}; + +#endif diff --git a/src/cocoa/dikeys.h b/src/cocoa/dikeys.h new file mode 120000 index 000000000..011f85acb --- /dev/null +++ b/src/cocoa/dikeys.h @@ -0,0 +1 @@ +../sdl/dikeys.h \ No newline at end of file diff --git a/src/cocoa/hardware.h b/src/cocoa/hardware.h new file mode 120000 index 000000000..4261b9477 --- /dev/null +++ b/src/cocoa/hardware.h @@ -0,0 +1 @@ +../sdl/hardware.h \ No newline at end of file diff --git a/src/cocoa/HID_Config_Utilities.c b/src/cocoa/hid/HID_Config_Utilities.c similarity index 100% rename from src/cocoa/HID_Config_Utilities.c rename to src/cocoa/hid/HID_Config_Utilities.c diff --git a/src/cocoa/HID_Error_Handler.c b/src/cocoa/hid/HID_Error_Handler.c similarity index 100% rename from src/cocoa/HID_Error_Handler.c rename to src/cocoa/hid/HID_Error_Handler.c diff --git a/src/cocoa/HID_Name_Lookup.c b/src/cocoa/hid/HID_Name_Lookup.c similarity index 100% rename from src/cocoa/HID_Name_Lookup.c rename to src/cocoa/hid/HID_Name_Lookup.c diff --git a/src/cocoa/HID_Queue_Utilities.c b/src/cocoa/hid/HID_Queue_Utilities.c similarity index 100% rename from src/cocoa/HID_Queue_Utilities.c rename to src/cocoa/hid/HID_Queue_Utilities.c diff --git a/src/cocoa/HID_Utilities.c b/src/cocoa/hid/HID_Utilities.c similarity index 100% rename from src/cocoa/HID_Utilities.c rename to src/cocoa/hid/HID_Utilities.c diff --git a/src/cocoa/HID_Utilities_External.h b/src/cocoa/hid/HID_Utilities_External.h similarity index 100% rename from src/cocoa/HID_Utilities_External.h rename to src/cocoa/hid/HID_Utilities_External.h diff --git a/src/cocoa/IOHIDDevice_.c b/src/cocoa/hid/IOHIDDevice_.c similarity index 100% rename from src/cocoa/IOHIDDevice_.c rename to src/cocoa/hid/IOHIDDevice_.c diff --git a/src/cocoa/IOHIDDevice_.h b/src/cocoa/hid/IOHIDDevice_.h similarity index 100% rename from src/cocoa/IOHIDDevice_.h rename to src/cocoa/hid/IOHIDDevice_.h diff --git a/src/cocoa/IOHIDElement_.c b/src/cocoa/hid/IOHIDElement_.c similarity index 100% rename from src/cocoa/IOHIDElement_.c rename to src/cocoa/hid/IOHIDElement_.c diff --git a/src/cocoa/IOHIDElement_.h b/src/cocoa/hid/IOHIDElement_.h similarity index 100% rename from src/cocoa/IOHIDElement_.h rename to src/cocoa/hid/IOHIDElement_.h diff --git a/src/cocoa/IOHIDLib_.h b/src/cocoa/hid/IOHIDLib_.h similarity index 100% rename from src/cocoa/IOHIDLib_.h rename to src/cocoa/hid/IOHIDLib_.h diff --git a/src/cocoa/ImmrHIDUtilAddOn.c b/src/cocoa/hid/ImmrHIDUtilAddOn.c similarity index 100% rename from src/cocoa/ImmrHIDUtilAddOn.c rename to src/cocoa/hid/ImmrHIDUtilAddOn.c diff --git a/src/cocoa/ImmrHIDUtilAddOn.h b/src/cocoa/hid/ImmrHIDUtilAddOn.h similarity index 100% rename from src/cocoa/ImmrHIDUtilAddOn.h rename to src/cocoa/hid/ImmrHIDUtilAddOn.h diff --git a/src/cocoa/i_backend_cocoa.mm b/src/cocoa/i_backend_cocoa.mm index 6abf1b7d1..be2d14276 100644 --- a/src/cocoa/i_backend_cocoa.mm +++ b/src/cocoa/i_backend_cocoa.mm @@ -1625,48 +1625,6 @@ const char* I_GetBackEndName() extern "C" { -struct SDL_mutex -{ - pthread_mutex_t mutex; -}; - - -SDL_mutex* SDL_CreateMutex() -{ - pthread_mutexattr_t attributes; - pthread_mutexattr_init(&attributes); - pthread_mutexattr_settype(&attributes, PTHREAD_MUTEX_RECURSIVE); - - SDL_mutex* result = new SDL_mutex; - - if (0 != pthread_mutex_init(&result->mutex, &attributes)) - { - delete result; - result = NULL; - } - - pthread_mutexattr_destroy(&attributes); - - return result; -} - -int SDL_mutexP(SDL_mutex* mutex) -{ - return pthread_mutex_lock(&mutex->mutex); -} - -int SDL_mutexV(SDL_mutex* mutex) -{ - return pthread_mutex_unlock(&mutex->mutex); -} - -void SDL_DestroyMutex(SDL_mutex* mutex) -{ - pthread_mutex_destroy(&mutex->mutex); - delete mutex; -} - - static timeval s_startTicks; uint32_t SDL_GetTicks() diff --git a/src/cocoa/i_cd.cpp b/src/cocoa/i_cd.cpp new file mode 120000 index 000000000..5573d7e1e --- /dev/null +++ b/src/cocoa/i_cd.cpp @@ -0,0 +1 @@ +../sdl/i_cd.cpp \ No newline at end of file diff --git a/src/cocoa/i_input.h b/src/cocoa/i_input.h new file mode 120000 index 000000000..208b03106 --- /dev/null +++ b/src/cocoa/i_input.h @@ -0,0 +1 @@ +../sdl/i_input.h \ No newline at end of file diff --git a/src/cocoa/i_joystick.cpp b/src/cocoa/i_joystick.cpp index 56db8f815..234f94c8e 100644 --- a/src/cocoa/i_joystick.cpp +++ b/src/cocoa/i_joystick.cpp @@ -37,7 +37,7 @@ #if MAC_OS_X_VERSION_MAX_ALLOWED >= 1050 -#include "HID_Utilities_External.h" +#include "hid/HID_Utilities_External.h" #include "d_event.h" #include "doomdef.h" diff --git a/src/cocoa/i_movie.cpp b/src/cocoa/i_movie.cpp new file mode 120000 index 000000000..04258f3e5 --- /dev/null +++ b/src/cocoa/i_movie.cpp @@ -0,0 +1 @@ +../sdl/i_movie.cpp \ No newline at end of file diff --git a/src/cocoa/i_system.h b/src/cocoa/i_system.h new file mode 120000 index 000000000..ced516311 --- /dev/null +++ b/src/cocoa/i_system.h @@ -0,0 +1 @@ +../sdl/i_system.h \ No newline at end of file diff --git a/src/cocoa/st_start.cpp b/src/cocoa/st_start.cpp new file mode 120000 index 000000000..38ce4fa1c --- /dev/null +++ b/src/cocoa/st_start.cpp @@ -0,0 +1 @@ +../sdl/st_start.cpp \ No newline at end of file From 9d135a05866d26d6ee03f513ef7aeafb5fdfb9f4 Mon Sep 17 00:00:00 2001 From: "alexey.lysiuk" Date: Sun, 14 Dec 2014 13:20:39 +0200 Subject: [PATCH 11/46] Get rid of SDL in more parts of native OS X backend --- src/CMakeLists.txt | 19 +-- src/cocoa/i_backend_cocoa.mm | 232 ++++++++++++++++++++++++++++++----- src/cocoa/i_system.cpp | 1 + src/cocoa/i_timer.cpp | 41 ++++--- src/sdl/i_gui.cpp | 5 - src/sdl/i_main.cpp | 28 +---- src/sdl/i_system.cpp | 1 - 7 files changed, 238 insertions(+), 89 deletions(-) create mode 120000 src/cocoa/i_system.cpp diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 2e6bb59f5..67f7d405b 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -549,18 +549,17 @@ set( PLAT_SDL_SOURCES sdl/crashcatcher.c sdl/hardware.cpp sdl/i_cd.cpp - sdl/i_main.cpp - sdl/i_movie.cpp - sdl/i_system.cpp - sdl/sdlvideo.cpp - sdl/st_start.cpp sdl/i_gui.cpp sdl/i_input.cpp sdl/i_joystick.cpp - sdl/i_timer.cpp ) + sdl/i_main.cpp + sdl/i_movie.cpp + sdl/i_system.cpp + sdl/i_timer.cpp + sdl/sdlvideo.cpp + sdl/st_start.cpp ) set( PLAT_MAC_SOURCES - cocoa/iwadpicker_cocoa.mm - cocoa/i_system_cocoa.mm ) + cocoa/iwadpicker_cocoa.mm ) set( PLAT_COCOA_SOURCES cocoa/hid/HID_Config_Utilities.c cocoa/hid/HID_Error_Handler.c @@ -575,8 +574,9 @@ set( PLAT_COCOA_SOURCES cocoa/i_cd.cpp cocoa/i_joystick.cpp cocoa/i_movie.cpp - cocoa/st_start.cpp + cocoa/i_system.cpp cocoa/i_timer.cpp + cocoa/st_start.cpp cocoa/zdoom.icns ) if( WIN32 ) @@ -601,6 +601,7 @@ elseif( APPLE ) else( OSX_COCOA_BACKEND ) set( SYSTEM_SOURCES_DIR sdl ) set( SYSTEM_SOURCES ${PLAT_SDL_SOURCES} ) + set( PLAT_MAC_SOURCES ${PLAT_MAC_SOURCES} cocoa/i_system_cocoa.mm ) set( OTHER_SYSTEM_SOURCES ${PLAT_WIN32_SOURCES} ${PLAT_COCOA_SOURCES} ) endif( OSX_COCOA_BACKEND ) diff --git a/src/cocoa/i_backend_cocoa.mm b/src/cocoa/i_backend_cocoa.mm index be2d14276..3f4574e04 100644 --- a/src/cocoa/i_backend_cocoa.mm +++ b/src/cocoa/i_backend_cocoa.mm @@ -56,15 +56,19 @@ #include "cmdlib.h" #include "d_event.h" #include "d_gui.h" +#include "d_main.h" #include "dikeys.h" #include "doomdef.h" +#include "doomerrors.h" #include "doomstat.h" +#include "m_argv.h" #include "s_sound.h" #include "textures.h" #include "v_video.h" #include "version.h" #include "i_rbopts.h" #include "i_osversion.h" +#include "i_system.h" #undef Class @@ -190,8 +194,12 @@ typedef NSInteger NSApplicationActivationPolicy; RenderBufferOptions rbOpts; -EXTERN_CVAR(Bool, fullscreen) -EXTERN_CVAR(Bool, vid_hidpi) +EXTERN_CVAR(Bool, fullscreen ) +EXTERN_CVAR(Bool, vid_hidpi ) +EXTERN_CVAR(Bool, vid_vsync ) +EXTERN_CVAR(Int, vid_adapter ) +EXTERN_CVAR(Int, vid_defwidth ) +EXTERN_CVAR(Int, vid_defheight) CVAR(Bool, use_mouse, true, CVAR_ARCHIVE | CVAR_GLOBALCONFIG) CVAR(Bool, m_noprescale, false, CVAR_ARCHIVE | CVAR_GLOBALCONFIG) @@ -217,9 +225,90 @@ extern constate_e ConsoleState; EXTERN_CVAR(Int, m_use_mouse); +void I_StartupJoysticks(); void I_ShutdownJoysticks(); +// --------------------------------------------------------------------------- + + +DArgs *Args; // command line arguments + +namespace +{ + +// The maximum number of functions that can be registered with atterm. +static const size_t MAX_TERMS = 64; + +static void (*TermFuncs[MAX_TERMS])(); +static const char *TermNames[MAX_TERMS]; +static size_t NumTerms; + +void call_terms() +{ + while (NumTerms > 0) + { + TermFuncs[--NumTerms](); + } +} + +} // unnamed namespace + + +void addterm(void (*func)(), const char *name) +{ + // Make sure this function wasn't already registered. + + for (size_t i = 0; i < NumTerms; ++i) + { + if (TermFuncs[i] == func) + { + return; + } + } + + if (NumTerms == MAX_TERMS) + { + func(); + I_FatalError("Too many exit functions registered."); + } + + TermNames[NumTerms] = name; + TermFuncs[NumTerms] = func; + + ++NumTerms; +} + +void popterm() +{ + if (NumTerms) + { + --NumTerms; + } +} + + +void I_SetMainWindowVisible(bool); + +void Mac_I_FatalError(const char* const message) +{ + I_SetMainWindowVisible(false); + + const CFStringRef errorString = CFStringCreateWithCStringNoCopy(kCFAllocatorDefault, + message, kCFStringEncodingASCII, kCFAllocatorNull); + + if (NULL != errorString) + { + CFOptionFlags dummy; + + CFUserNotificationDisplayAlert( 0, kCFUserNotificationStopAlertLevel, NULL, NULL, NULL, + CFSTR("Fatal Error"), errorString, CFSTR("Exit"), NULL, NULL, &dummy); + + CFRelease(errorString); + } +} + + namespace { @@ -241,6 +330,112 @@ size_t s_skipMouseMoves; NSCursor* s_cursor; +void NewFailure() +{ + I_FatalError("Failed to allocate memory from system heap"); +} + + +int OriginalMain(int argc, char** argv) +{ + printf(GAMENAME" %s - %s - Cocoa version\nCompiled on %s\n", + GetVersionString(), GetGitTime(), __DATE__); + + seteuid(getuid()); + std::set_new_handler(NewFailure); + + // Set LC_NUMERIC environment variable in case some library decides to + // clear the setlocale call at least this will be correct. + // Note that the LANG environment variable is overridden by LC_* + setenv("LC_NUMERIC", "C", 1); + setlocale(LC_ALL, "C"); + + if (SDL_Init (SDL_INIT_VIDEO|SDL_INIT_TIMER|SDL_INIT_NOPARACHUTE|SDL_INIT_JOYSTICK) == -1) + { + fprintf (stderr, "Could not initialize SDL:\n%s\n", SDL_GetError()); + return -1; + } + atterm(SDL_Quit); + + printf("\n"); + + SDL_DisplayMode videoInfo = {}; + + if (0 == SDL_GetDesktopDisplayMode(vid_adapter, &videoInfo)) + { + vid_defwidth = videoInfo.w; + vid_defheight = videoInfo.h; + vid_vsync = true; + fullscreen = true; + } + + try + { + Args = new DArgs(argc, argv); + + /* + killough 1/98: + + This fixes some problems with exit handling + during abnormal situations. + + The old code called I_Quit() to end program, + while now I_Quit() is installed as an exit + handler and exit() is called to exit, either + normally or abnormally. Seg faults are caught + and the error handler is used, to prevent + being left in graphics mode or having very + loud SFX noise because the sound card is + left in an unstable state. + */ + + atexit (call_terms); + atterm (I_Quit); + + // Should we even be doing anything with progdir on Unix systems? + char program[PATH_MAX]; + if (realpath (argv[0], program) == NULL) + strcpy (program, argv[0]); + char *slash = strrchr (program, '/'); + if (slash != NULL) + { + *(slash + 1) = '\0'; + progdir = program; + } + else + { + progdir = "./"; + } + + I_StartupJoysticks(); + C_InitConsole(80 * 8, 25 * 8, false); + D_DoomMain(); + } + catch(const CDoomError& error) + { + const char* const message = error.GetMessage(); + + if (NULL != message) + { + fprintf(stderr, "%s\n", message); + Mac_I_FatalError(message); + } + + exit(-1); + } + catch(...) + { + call_terms(); + throw; + } + + return 0; +} + + +// --------------------------------------------------------------------------- + + void CheckGUICapture() { const bool wantCapture = (MENU_Off == menuactive) @@ -1131,7 +1326,7 @@ static bool s_fullscreenNewAPI; [[NSRunLoop currentRunLoop] addTimer:timer forMode:NSDefaultRunLoopMode]; - exit(SDL_main(s_argc, s_argv)); + exit(OriginalMain(s_argc, s_argv)); } @@ -1613,33 +1808,9 @@ bool I_SetCursor(FTexture* cursorpic) // --------------------------------------------------------------------------- -const char* I_GetBackEndName() -{ - return "Native Cocoa"; -} - - -// --------------------------------------------------------------------------- - - extern "C" { -static timeval s_startTicks; - -uint32_t SDL_GetTicks() -{ - timeval now; - gettimeofday(&now, NULL); - - const uint32_t ticks = - (now.tv_sec - s_startTicks.tv_sec ) * 1000 - + (now.tv_usec - s_startTicks.tv_usec) / 1000; - - return ticks; -} - - int SDL_Init(Uint32 flags) { ZD_UNUSED(flags); @@ -1667,11 +1838,6 @@ const char* SDL_GetError() } -const char* SDL_GetCurrentVideoDriver() -{ - return "Native OpenGL"; -} - int SDL_GetDesktopDisplayMode(int displayIndex, SDL_DisplayMode *mode) { // NOTE: Only required fields are assigned @@ -2099,8 +2265,6 @@ const DarwinVersion darwinVersion = GetDarwinVersion(); int main(int argc, char** argv) { - gettimeofday(&s_startTicks, NULL); - for (int i = 0; i <= argc; ++i) { const char* const argument = argv[i]; diff --git a/src/cocoa/i_system.cpp b/src/cocoa/i_system.cpp new file mode 120000 index 000000000..b95185a13 --- /dev/null +++ b/src/cocoa/i_system.cpp @@ -0,0 +1 @@ +../sdl/i_system.cpp \ No newline at end of file diff --git a/src/cocoa/i_timer.cpp b/src/cocoa/i_timer.cpp index 0699a9967..c63561077 100644 --- a/src/cocoa/i_timer.cpp +++ b/src/cocoa/i_timer.cpp @@ -4,8 +4,6 @@ #include #include -#include - #include "basictypes.h" #include "basicinlines.h" #include "doomdef.h" @@ -13,23 +11,36 @@ #include "templates.h" +static timeval s_startTicks; + + unsigned int I_MSTime() { - return SDL_GetTicks(); + timeval now; + gettimeofday(&now, NULL); + + const uint32_t ticks = + (now.tv_sec - s_startTicks.tv_sec ) * 1000 + + (now.tv_usec - s_startTicks.tv_usec) / 1000; + + return ticks; } unsigned int I_FPSTime() { - return SDL_GetTicks(); + timeval now; + gettimeofday(&now, NULL); + + return static_cast( + (now.tv_sec) * 1000 + (now.tv_usec) / 1000); } -bool g_isTicFrozen; - - namespace { +bool s_isTicFrozen; + timespec GetNextTickTime() { static const long MILLISECONDS_IN_SECOND = 1000; @@ -91,7 +102,7 @@ void* TimerThreadFunc(void*) pthread_mutex_lock(&s_timerMutex); pthread_cond_timedwait(&s_timerEvent, &s_timerMutex, &timeToNextTick); - if (!g_isTicFrozen) + if (!s_isTicFrozen) { // The following GCC/Clang intrinsic can be used instead of OS X specific function: // __sync_add_and_fetch(&s_tics, 1); @@ -101,7 +112,7 @@ void* TimerThreadFunc(void*) OSAtomicIncrement32(&s_tics); } - s_timerStart = SDL_GetTicks(); + s_timerStart = I_MSTime(); pthread_cond_broadcast(&s_timerEvent); pthread_mutex_unlock(&s_timerMutex); @@ -122,7 +133,7 @@ int GetTimeThreaded(bool saveMS) int WaitForTicThreaded(int prevTic) { - assert(!g_isTicFrozen); + assert(!s_isTicFrozen); while (s_tics <= prevTic) { @@ -136,7 +147,7 @@ int WaitForTicThreaded(int prevTic) void FreezeTimeThreaded(bool frozen) { - g_isTicFrozen = frozen; + s_isTicFrozen = frozen; } } // unnamed namespace @@ -144,7 +155,7 @@ void FreezeTimeThreaded(bool frozen) fixed_t I_GetTimeFrac(uint32* ms) { - const uint32_t now = SDL_GetTicks(); + const uint32_t now = I_MSTime(); if (NULL != ms) { @@ -157,11 +168,13 @@ fixed_t I_GetTimeFrac(uint32* ms) } -void I_InitTimer () +void I_InitTimer() { assert(!s_timerInitialized); s_timerInitialized = true; + gettimeofday(&s_startTicks, NULL); + pthread_cond_init (&s_timerEvent, NULL); pthread_mutex_init(&s_timerMutex, NULL); @@ -172,7 +185,7 @@ void I_InitTimer () I_FreezeTime = FreezeTimeThreaded; } -void I_ShutdownTimer () +void I_ShutdownTimer() { if (!s_timerInitialized) { diff --git a/src/sdl/i_gui.cpp b/src/sdl/i_gui.cpp index c2b91b39c..f9e6714b4 100644 --- a/src/sdl/i_gui.cpp +++ b/src/sdl/i_gui.cpp @@ -59,8 +59,3 @@ void I_SetMainWindowVisible(bool visible) { } - -const char* I_GetBackEndName() -{ - return "SDL"; -} diff --git a/src/sdl/i_main.cpp b/src/sdl/i_main.cpp index 33395e0f1..10a9b8c75 100644 --- a/src/sdl/i_main.cpp +++ b/src/sdl/i_main.cpp @@ -235,13 +235,7 @@ static void unprotect_rtext() void I_StartupJoysticks(); void I_ShutdownJoysticks(); -const char* I_GetBackEndName(); - -#ifdef USE_NATIVE_COCOA -int SDL_main (int argc, char **argv) -#else int main (int argc, char **argv) -#endif { #if !defined (__APPLE__) { @@ -250,8 +244,8 @@ int main (int argc, char **argv) } #endif // !__APPLE__ - printf(GAMENAME" %s - %s - %s version\nCompiled on %s\n", - GetVersionString(), GetGitTime(), I_GetBackEndName(), __DATE__); + printf(GAMENAME" %s - %s - SDL version\nCompiled on %s\n", + GetVersionString(), GetGitTime(), __DATE__); seteuid (getuid ()); std::set_new_handler (NewFailure); @@ -280,24 +274,6 @@ int main (int argc, char **argv) printf("Using video driver %s\n", SDL_GetCurrentVideoDriver()); printf("\n"); - -#ifdef __APPLE__ - EXTERN_CVAR( Int, vid_adapter ) - SDL_DisplayMode videoInfo = {}; - if ( SDL_GetDesktopDisplayMode (vid_adapter, &videoInfo) == 0 ) - { - EXTERN_CVAR( Int, vid_defwidth ) - EXTERN_CVAR( Int, vid_defheight ) - EXTERN_CVAR( Int, vid_defbits ) - EXTERN_CVAR( Bool, vid_vsync ) - EXTERN_CVAR( Bool, fullscreen ) - - vid_defwidth = videoInfo.w; - vid_defheight = videoInfo.h; - vid_vsync = true; - fullscreen = true; - } -#endif // __APPLE__ try { diff --git a/src/sdl/i_system.cpp b/src/sdl/i_system.cpp index 41fdef323..c2ce4aa9f 100644 --- a/src/sdl/i_system.cpp +++ b/src/sdl/i_system.cpp @@ -41,7 +41,6 @@ #include "doomerrors.h" #include -#include "SDL.h" #include "doomtype.h" #include "doomstat.h" #include "version.h" From ce70a7c66e7aaf76ba3671bbd5f2dbd400fa6ae9 Mon Sep 17 00:00:00 2001 From: "alexey.lysiuk" Date: Sun, 14 Dec 2014 17:08:47 +0200 Subject: [PATCH 12/46] Video part of native OS X backend as a copy-paste of SDL one Dependency from SDL still exists, pending major refactoring --- src/cocoa/i_backend_cocoa.mm | 874 ++++++++++++++++++++++++++++++++++- 1 file changed, 873 insertions(+), 1 deletion(-) diff --git a/src/cocoa/i_backend_cocoa.mm b/src/cocoa/i_backend_cocoa.mm index 3f4574e04..442a7192a 100644 --- a/src/cocoa/i_backend_cocoa.mm +++ b/src/cocoa/i_backend_cocoa.mm @@ -61,9 +61,16 @@ #include "doomdef.h" #include "doomerrors.h" #include "doomstat.h" +#include "hardware.h" #include "m_argv.h" +#include "r_renderer.h" +#include "r_swrenderer.h" #include "s_sound.h" +#include "stats.h" #include "textures.h" +#include "v_palette.h" +#include "v_pfx.h" +#include "v_text.h" #include "v_video.h" #include "version.h" #include "i_rbopts.h" @@ -194,7 +201,7 @@ typedef NSInteger NSApplicationActivationPolicy; RenderBufferOptions rbOpts; -EXTERN_CVAR(Bool, fullscreen ) +EXTERN_CVAR(Bool, ticker ) EXTERN_CVAR(Bool, vid_hidpi ) EXTERN_CVAR(Bool, vid_vsync ) EXTERN_CVAR(Int, vid_adapter ) @@ -232,6 +239,37 @@ void I_ShutdownJoysticks(); // --------------------------------------------------------------------------- +extern int NewWidth, NewHeight, NewBits, DisplayBits; + + +CUSTOM_CVAR(Bool, fullscreen, false, CVAR_ARCHIVE | CVAR_GLOBALCONFIG) +{ + NewWidth = screen->GetWidth(); + NewHeight = screen->GetHeight(); + NewBits = DisplayBits; + setmodeneeded = true; +} + +CUSTOM_CVAR(Float, vid_winscale, 1.f, CVAR_ARCHIVE | CVAR_GLOBALCONFIG) +{ + if (self < 1.f) + { + self = 1.f; + } + else if (Video) + { + Video->SetWindowedScale (self); + NewWidth = screen->GetWidth(); + NewHeight = screen->GetHeight(); + NewBits = DisplayBits; + setmodeneeded = true; + } +} + + +// --------------------------------------------------------------------------- + + DArgs *Args; // command line arguments namespace @@ -2134,6 +2172,840 @@ int SDL_SetPaletteColors(SDL_Palette* palette, const SDL_Color* colors, int firs } // extern "C" +// --------------------------------------------------------------------------- + + +class CocoaVideo : public IVideo +{ +public: + CocoaVideo(int parm); + ~CocoaVideo(); + + EDisplayType GetDisplayType () { return DISPLAY_Both; } + void SetWindowedScale (float scale); + + DFrameBuffer *CreateFrameBuffer (int width, int height, bool fs, DFrameBuffer *old); + + void StartModeIterator (int bits, bool fs); + bool NextMode (int *width, int *height, bool *letterbox); + +private: + int IteratorMode; + int IteratorBits; +}; + +class CocoaFrameBuffer : public DFrameBuffer +{ +public: + CocoaFrameBuffer (int width, int height, bool fullscreen); + ~CocoaFrameBuffer (); + + bool Lock (bool buffer); + void Unlock (); + bool Relock (); + void ForceBuffering (bool force); + bool IsValid (); + void Update (); + PalEntry *GetPalette (); + void GetFlashedPalette (PalEntry pal[256]); + void UpdatePalette (); + bool SetGamma (float gamma); + bool SetFlash (PalEntry rgb, int amount); + void GetFlash (PalEntry &rgb, int &amount); + void SetFullscreen (bool fullscreen); + int GetPageCount (); + bool IsFullscreen (); + + friend class CocoaVideo; + + virtual void SetVSync (bool vsync); + +private: + PalEntry SourcePalette[256]; + BYTE GammaTable[3][256]; + PalEntry Flash; + int FlashAmount; + float Gamma; + bool UpdatePending; + + SDL_Window *Screen; + SDL_Renderer *Renderer; + union + { + SDL_Texture *Texture; + SDL_Surface *Surface; + }; + SDL_Rect UpdateRect; + + bool NeedPalUpdate; + bool NeedGammaUpdate; + bool NotPaletted; + + void UpdateColors (); + void ResetSDLRenderer (); + + CocoaFrameBuffer () {} +}; + +struct MiniModeInfo +{ + WORD Width, Height; +}; + + +EXTERN_CVAR (Float, Gamma) + +CVAR (Int, vid_adapter, 0, CVAR_ARCHIVE|CVAR_GLOBALCONFIG) + +CVAR (Int, vid_displaybits, 32, CVAR_ARCHIVE|CVAR_GLOBALCONFIG) + +CVAR (Bool, vid_forcesurface, false, CVAR_ARCHIVE|CVAR_GLOBALCONFIG) + +CUSTOM_CVAR (Float, rgamma, 1.f, CVAR_ARCHIVE|CVAR_GLOBALCONFIG) +{ + if (screen != NULL) + { + screen->SetGamma (Gamma); + } +} +CUSTOM_CVAR (Float, ggamma, 1.f, CVAR_ARCHIVE|CVAR_GLOBALCONFIG) +{ + if (screen != NULL) + { + screen->SetGamma (Gamma); + } +} +CUSTOM_CVAR (Float, bgamma, 1.f, CVAR_ARCHIVE|CVAR_GLOBALCONFIG) +{ + if (screen != NULL) + { + screen->SetGamma (Gamma); + } +} + +static MiniModeInfo WinModes[] = +{ + { 320, 200 }, + { 320, 240 }, + { 400, 225 }, // 16:9 + { 400, 300 }, + { 480, 270 }, // 16:9 + { 480, 360 }, + { 512, 288 }, // 16:9 + { 512, 384 }, + { 640, 360 }, // 16:9 + { 640, 400 }, + { 640, 480 }, + { 720, 480 }, // 16:10 + { 720, 540 }, + { 800, 450 }, // 16:9 + { 800, 480 }, + { 800, 500 }, // 16:10 + { 800, 600 }, + { 848, 480 }, // 16:9 + { 960, 600 }, // 16:10 + { 960, 720 }, + { 1024, 576 }, // 16:9 + { 1024, 600 }, // 17:10 + { 1024, 640 }, // 16:10 + { 1024, 768 }, + { 1088, 612 }, // 16:9 + { 1152, 648 }, // 16:9 + { 1152, 720 }, // 16:10 + { 1152, 864 }, + { 1280, 720 }, // 16:9 + { 1280, 854 }, + { 1280, 800 }, // 16:10 + { 1280, 960 }, + { 1280, 1024 }, // 5:4 + { 1360, 768 }, // 16:9 + { 1366, 768 }, + { 1400, 787 }, // 16:9 + { 1400, 875 }, // 16:10 + { 1400, 1050 }, + { 1440, 900 }, + { 1440, 960 }, + { 1440, 1080 }, + { 1600, 900 }, // 16:9 + { 1600, 1000 }, // 16:10 + { 1600, 1200 }, + { 1920, 1080 }, + { 1920, 1200 }, + { 2048, 1536 }, + { 2560, 1440 }, + { 2560, 1600 }, + { 2560, 2048 }, + { 2880, 1800 }, + { 3200, 1800 }, + { 3840, 2160 }, + { 3840, 2400 }, + { 4096, 2160 }, + { 5120, 2880 } +}; + +static cycle_t BlitCycles; +static cycle_t SDLFlipCycles; + +// CODE -------------------------------------------------------------------- + +void ScaleWithAspect (int &w, int &h, int Width, int Height) +{ + int resRatio = CheckRatio (Width, Height); + int screenRatio; + CheckRatio (w, h, &screenRatio); + if (resRatio == screenRatio) + return; + + double yratio; + switch(resRatio) + { + case 0: yratio = 4./3.; break; + case 1: yratio = 16./9.; break; + case 2: yratio = 16./10.; break; + case 3: yratio = 17./10.; break; + case 4: yratio = 5./4.; break; + default: return; + } + double y = w/yratio; + if (y > h) + w = h*yratio; + else + h = y; +} + +CocoaVideo::CocoaVideo (int parm) +{ + IteratorBits = 0; +} + +CocoaVideo::~CocoaVideo () +{ +} + +void CocoaVideo::StartModeIterator (int bits, bool fs) +{ + IteratorMode = 0; + IteratorBits = bits; +} + +bool CocoaVideo::NextMode (int *width, int *height, bool *letterbox) +{ + if (IteratorBits != 8) + return false; + + if ((unsigned)IteratorMode < sizeof(WinModes)/sizeof(WinModes[0])) + { + *width = WinModes[IteratorMode].Width; + *height = WinModes[IteratorMode].Height; + ++IteratorMode; + return true; + } + return false; +} + +DFrameBuffer *CocoaVideo::CreateFrameBuffer (int width, int height, bool fullscreen, DFrameBuffer *old) +{ + static int retry = 0; + static int owidth, oheight; + + PalEntry flashColor; + int flashAmount; + + if (old != NULL) + { // Reuse the old framebuffer if its attributes are the same + CocoaFrameBuffer *fb = static_cast (old); + if (fb->Width == width && + fb->Height == height) + { + bool fsnow = (SDL_GetWindowFlags (fb->Screen) & SDL_WINDOW_FULLSCREEN_DESKTOP) != 0; + + if (fsnow != fullscreen) + { + fb->SetFullscreen (fullscreen); + } + return old; + } + old->GetFlash (flashColor, flashAmount); + old->ObjectFlags |= OF_YesReallyDelete; + if (screen == old) screen = NULL; + delete old; + } + else + { + flashColor = 0; + flashAmount = 0; + } + + CocoaFrameBuffer *fb = new CocoaFrameBuffer (width, height, fullscreen); + retry = 0; + + // If we could not create the framebuffer, try again with slightly + // different parameters in this order: + // 1. Try with the closest size + // 2. Try in the opposite screen mode with the original size + // 3. Try in the opposite screen mode with the closest size + // This is a somewhat confusing mass of recursion here. + + while (fb == NULL || !fb->IsValid ()) + { + if (fb != NULL) + { + delete fb; + } + + switch (retry) + { + case 0: + owidth = width; + oheight = height; + case 2: + // Try a different resolution. Hopefully that will work. + I_ClosestResolution (&width, &height, 8); + break; + + case 1: + // Try changing fullscreen mode. Maybe that will work. + width = owidth; + height = oheight; + fullscreen = !fullscreen; + break; + + default: + // I give up! + I_FatalError ("Could not create new screen (%d x %d)", owidth, oheight); + } + + ++retry; + fb = static_cast(CreateFrameBuffer (width, height, fullscreen, NULL)); + } + + fb->SetFlash (flashColor, flashAmount); + + return fb; +} + +void CocoaVideo::SetWindowedScale (float scale) +{ +} + + +CocoaFrameBuffer::CocoaFrameBuffer (int width, int height, bool fullscreen) +: DFrameBuffer (width, height) +{ + int i; + + NeedPalUpdate = false; + NeedGammaUpdate = false; + UpdatePending = false; + NotPaletted = false; + FlashAmount = 0; + + FString caption; + caption.Format(GAMESIG " %s (%s)", GetVersionString(), GetGitTime()); + + Screen = SDL_CreateWindow (caption, + SDL_WINDOWPOS_UNDEFINED_DISPLAY(vid_adapter), SDL_WINDOWPOS_UNDEFINED_DISPLAY(vid_adapter), + width, height, (fullscreen ? SDL_WINDOW_FULLSCREEN_DESKTOP : 0)); + + if (Screen == NULL) + return; + + Renderer = NULL; + Texture = NULL; + ResetSDLRenderer (); + + for (i = 0; i < 256; i++) + { + GammaTable[0][i] = GammaTable[1][i] = GammaTable[2][i] = i; + } + + memcpy (SourcePalette, GPalette.BaseColors, sizeof(PalEntry)*256); + UpdateColors (); + + SetVSync (vid_vsync); +} + + +CocoaFrameBuffer::~CocoaFrameBuffer () +{ + if(Screen) + { + if (Renderer) + { + if (Texture) + SDL_DestroyTexture (Texture); + SDL_DestroyRenderer (Renderer); + } + + SDL_DestroyWindow (Screen); + } +} + +bool CocoaFrameBuffer::IsValid () +{ + return DFrameBuffer::IsValid() && Screen != NULL; +} + +int CocoaFrameBuffer::GetPageCount () +{ + return 1; +} + +bool CocoaFrameBuffer::Lock (bool buffered) +{ + return DSimpleCanvas::Lock (); +} + +bool CocoaFrameBuffer::Relock () +{ + return DSimpleCanvas::Lock (); +} + +void CocoaFrameBuffer::Unlock () +{ + if (UpdatePending && LockCount == 1) + { + Update (); + } + else if (--LockCount <= 0) + { + Buffer = NULL; + LockCount = 0; + } +} + +void CocoaFrameBuffer::Update () +{ + if (LockCount != 1) + { + if (LockCount > 0) + { + UpdatePending = true; + --LockCount; + } + return; + } + + DrawRateStuff (); + + Buffer = NULL; + LockCount = 0; + UpdatePending = false; + + BlitCycles.Reset(); + SDLFlipCycles.Reset(); + BlitCycles.Clock(); + + void *pixels; + int pitch; + + if (SDL_LockTexture (Texture, NULL, &pixels, &pitch)) + return; + + if (NotPaletted) + { + GPfx.Convert (MemBuffer, Pitch, + pixels, pitch, Width, Height, + FRACUNIT, FRACUNIT, 0, 0); + } + else + { + if (pitch == Pitch) + { + memcpy (pixels, MemBuffer, Width*Height); + } + else + { + for (int y = 0; y < Height; ++y) + { + memcpy ((BYTE *)pixels+y*pitch, MemBuffer+y*Pitch, Width); + } + } + } + + SDL_UnlockTexture (Texture); + + SDLFlipCycles.Clock(); + SDL_RenderCopy(Renderer, Texture, NULL, &UpdateRect); + SDL_RenderPresent(Renderer); + SDLFlipCycles.Unclock(); + + BlitCycles.Unclock(); + + if (NeedGammaUpdate) + { + bool Windowed = false; + NeedGammaUpdate = false; + CalcGamma ((Windowed || rgamma == 0.f) ? Gamma : (Gamma * rgamma), GammaTable[0]); + CalcGamma ((Windowed || ggamma == 0.f) ? Gamma : (Gamma * ggamma), GammaTable[1]); + CalcGamma ((Windowed || bgamma == 0.f) ? Gamma : (Gamma * bgamma), GammaTable[2]); + NeedPalUpdate = true; + } + + if (NeedPalUpdate) + { + NeedPalUpdate = false; + UpdateColors (); + } +} + +void CocoaFrameBuffer::UpdateColors () +{ + if (NotPaletted) + { + PalEntry palette[256]; + + for (int i = 0; i < 256; ++i) + { + palette[i].r = GammaTable[0][SourcePalette[i].r]; + palette[i].g = GammaTable[1][SourcePalette[i].g]; + palette[i].b = GammaTable[2][SourcePalette[i].b]; + } + if (FlashAmount) + { + DoBlending (palette, palette, + 256, GammaTable[0][Flash.r], GammaTable[1][Flash.g], GammaTable[2][Flash.b], + FlashAmount); + } + GPfx.SetPalette (palette); + } + else + { + SDL_Color colors[256]; + + for (int i = 0; i < 256; ++i) + { + colors[i].r = GammaTable[0][SourcePalette[i].r]; + colors[i].g = GammaTable[1][SourcePalette[i].g]; + colors[i].b = GammaTable[2][SourcePalette[i].b]; + } + if (FlashAmount) + { + DoBlending ((PalEntry *)colors, (PalEntry *)colors, + 256, GammaTable[2][Flash.b], GammaTable[1][Flash.g], GammaTable[0][Flash.r], + FlashAmount); + } + SDL_SetPaletteColors (Surface->format->palette, colors, 0, 256); + } +} + +PalEntry *CocoaFrameBuffer::GetPalette () +{ + return SourcePalette; +} + +void CocoaFrameBuffer::UpdatePalette () +{ + NeedPalUpdate = true; +} + +bool CocoaFrameBuffer::SetGamma (float gamma) +{ + Gamma = gamma; + NeedGammaUpdate = true; + return true; +} + +bool CocoaFrameBuffer::SetFlash (PalEntry rgb, int amount) +{ + Flash = rgb; + FlashAmount = amount; + NeedPalUpdate = true; + return true; +} + +void CocoaFrameBuffer::GetFlash (PalEntry &rgb, int &amount) +{ + rgb = Flash; + amount = FlashAmount; +} + +// Q: Should I gamma adjust the returned palette? +void CocoaFrameBuffer::GetFlashedPalette (PalEntry pal[256]) +{ + memcpy (pal, SourcePalette, 256*sizeof(PalEntry)); + if (FlashAmount) + { + DoBlending (pal, pal, 256, Flash.r, Flash.g, Flash.b, FlashAmount); + } +} + +void CocoaFrameBuffer::SetFullscreen (bool fullscreen) +{ + SDL_SetWindowFullscreen (Screen, fullscreen ? SDL_WINDOW_FULLSCREEN_DESKTOP : 0); + if (!fullscreen) + { + // Restore proper window size + SDL_SetWindowSize (Screen, Width, Height); + } + + ResetSDLRenderer (); +} + +bool CocoaFrameBuffer::IsFullscreen () +{ + return (SDL_GetWindowFlags (Screen) & SDL_WINDOW_FULLSCREEN_DESKTOP) != 0; +} + +void CocoaFrameBuffer::ResetSDLRenderer () +{ + if (Renderer) + { + if (Texture) + SDL_DestroyTexture (Texture); + SDL_DestroyRenderer (Renderer); + } + + Renderer = SDL_CreateRenderer (Screen, -1,SDL_RENDERER_ACCELERATED|SDL_RENDERER_TARGETTEXTURE| + (vid_vsync ? SDL_RENDERER_PRESENTVSYNC : 0)); + if (!Renderer) + return; + + Uint32 fmt; + switch(vid_displaybits) + { + default: fmt = SDL_PIXELFORMAT_ARGB8888; break; + case 30: fmt = SDL_PIXELFORMAT_ARGB2101010; break; + case 24: fmt = SDL_PIXELFORMAT_RGB888; break; + case 16: fmt = SDL_PIXELFORMAT_RGB565; break; + case 15: fmt = SDL_PIXELFORMAT_ARGB1555; break; + } + Texture = SDL_CreateTexture (Renderer, fmt, SDL_TEXTUREACCESS_STREAMING, Width, Height); + + { + NotPaletted = true; + + Uint32 format; + SDL_QueryTexture(Texture, &format, NULL, NULL, NULL); + + Uint32 Rmask, Gmask, Bmask, Amask; + int bpp; + SDL_PixelFormatEnumToMasks(format, &bpp, &Rmask, &Gmask, &Bmask, &Amask); + GPfx.SetFormat (bpp, Rmask, Gmask, Bmask); + } + + // Calculate update rectangle + if (IsFullscreen ()) + { + int w, h; + SDL_GetWindowSize (Screen, &w, &h); + UpdateRect.w = w; + UpdateRect.h = h; + ScaleWithAspect (UpdateRect.w, UpdateRect.h, Width, Height); + UpdateRect.x = (w - UpdateRect.w)/2; + UpdateRect.y = (h - UpdateRect.h)/2; + } + else + { + // In windowed mode we just update the whole window. + UpdateRect.x = 0; + UpdateRect.y = 0; + UpdateRect.w = Width; + UpdateRect.h = Height; + } +} + +void CocoaFrameBuffer::SetVSync (bool vsync) +{ + if (CGLContextObj context = CGLGetCurrentContext()) + { +#if MAC_OS_X_VERSION_MAX_ALLOWED < 1050 + // Inconsistency between 10.4 and 10.5 SDKs: + // third argument of CGLSetParameter() is const long* on 10.4 and const GLint* on 10.5 + // So, GLint typedef'ed to long instead of int to workaround this issue + typedef long GLint; +#endif // prior to 10.5 + + const GLint value = vsync ? 1 : 0; + CGLSetParameter(context, kCGLCPSwapInterval, &value); + } +} + +ADD_STAT (blit) +{ + FString out; + out.Format ("blit=%04.1f ms flip=%04.1f ms", + BlitCycles.TimeMS(), SDLFlipCycles.TimeMS()); + return out; +} + + +IVideo *Video; + + +void I_ShutdownGraphics () +{ + if (screen) + { + DFrameBuffer *s = screen; + screen = NULL; + s->ObjectFlags |= OF_YesReallyDelete; + delete s; + } + if (Video) + delete Video, Video = NULL; +} + +void I_InitGraphics () +{ + UCVarValue val; + + val.Bool = !!Args->CheckParm ("-devparm"); + ticker.SetGenericRepDefault (val, CVAR_Bool); + + Video = new CocoaVideo (0); + if (Video == NULL) + I_FatalError ("Failed to initialize display"); + + atterm (I_ShutdownGraphics); + + Video->SetWindowedScale (vid_winscale); +} + +static void I_DeleteRenderer() +{ + if (Renderer != NULL) delete Renderer; +} + +void I_CreateRenderer() +{ + if (Renderer == NULL) + { + Renderer = new FSoftwareRenderer; + atterm(I_DeleteRenderer); + } +} + + +DFrameBuffer *I_SetMode (int &width, int &height, DFrameBuffer *old) +{ + bool fs = false; + switch (Video->GetDisplayType ()) + { + case DISPLAY_WindowOnly: + fs = false; + break; + case DISPLAY_FullscreenOnly: + fs = true; + break; + case DISPLAY_Both: + fs = fullscreen; + break; + } + + return Video->CreateFrameBuffer (width, height, fs, old); +} + +bool I_CheckResolution (int width, int height, int bits) +{ + int twidth, theight; + + Video->StartModeIterator (bits, screen ? screen->IsFullscreen() : fullscreen); + while (Video->NextMode (&twidth, &theight, NULL)) + { + if (width == twidth && height == theight) + return true; + } + return false; +} + +void I_ClosestResolution (int *width, int *height, int bits) +{ + int twidth, theight; + int cwidth = 0, cheight = 0; + int iteration; + DWORD closest = 4294967295u; + + for (iteration = 0; iteration < 2; iteration++) + { + Video->StartModeIterator (bits, screen ? screen->IsFullscreen() : fullscreen); + while (Video->NextMode (&twidth, &theight, NULL)) + { + if (twidth == *width && theight == *height) + return; + + if (iteration == 0 && (twidth < *width || theight < *height)) + continue; + + DWORD dist = (twidth - *width) * (twidth - *width) + + (theight - *height) * (theight - *height); + + if (dist < closest) + { + closest = dist; + cwidth = twidth; + cheight = theight; + } + } + if (closest != 4294967295u) + { + *width = cwidth; + *height = cheight; + return; + } + } +} + + +EXTERN_CVAR(Int, vid_maxfps); +EXTERN_CVAR(Bool, cl_capfps); + +// So Apple doesn't support POSIX timers and I can't find a good substitute short of +// having Objective-C Cocoa events or something like that. +void I_SetFPSLimit(int limit) +{ +} + +CUSTOM_CVAR (Int, vid_maxfps, 200, CVAR_ARCHIVE | CVAR_GLOBALCONFIG) +{ + if (vid_maxfps < TICRATE && vid_maxfps != 0) + { + vid_maxfps = TICRATE; + } + else if (vid_maxfps > 1000) + { + vid_maxfps = 1000; + } + else if (cl_capfps == 0) + { + I_SetFPSLimit(vid_maxfps); + } +} + + +CCMD (vid_listmodes) +{ + static const char *ratios[5] = { "", " - 16:9", " - 16:10", "", " - 5:4" }; + int width, height, bits; + bool letterbox; + + if (Video == NULL) + { + return; + } + for (bits = 1; bits <= 32; bits++) + { + Video->StartModeIterator (bits, screen->IsFullscreen()); + while (Video->NextMode (&width, &height, &letterbox)) + { + bool thisMode = (width == DisplayWidth && height == DisplayHeight && bits == DisplayBits); + int ratio = CheckRatio (width, height); + Printf (thisMode ? PRINT_BOLD : PRINT_HIGH, + "%s%4d x%5d x%3d%s%s\n", + thisMode || !(ratio & 3) ? "" : TEXTCOLOR_GOLD, + width, height, bits, + ratios[ratio], + thisMode || !letterbox ? "" : TEXTCOLOR_BROWN " LB"); + } + } +} + +CCMD (vid_currentmode) +{ + Printf ("%dx%dx%d\n", DisplayWidth, DisplayHeight, DisplayBits); +} + + namespace { From 8bc890c99565732d8dfe707301ebaedfedbf6345 Mon Sep 17 00:00:00 2001 From: "alexey.lysiuk" Date: Mon, 15 Dec 2014 17:40:30 +0200 Subject: [PATCH 13/46] Rearranged files to avoid usage of symbolic links --- src/CMakeLists.txt | 34 +- src/cocoa/dikeys.h | 1 - src/cocoa/hardware.h | 1 - src/cocoa/i_cd.cpp | 1 - src/cocoa/i_input.h | 1 - src/cocoa/i_movie.cpp | 1 - src/cocoa/i_system.cpp | 1 - src/cocoa/i_system.h | 1 - src/cocoa/st_start.cpp | 1 - src/{sdl => posix}/dikeys.h | 310 ++++++------ src/{sdl => posix}/hardware.h | 192 ++++---- src/{sdl => posix}/i_cd.cpp | 308 ++++++------ src/{sdl => posix}/i_input.h | 20 +- src/{sdl => posix}/i_movie.cpp | 14 +- src/{sdl => posix}/i_system.cpp | 0 src/{sdl => posix}/i_system.h | 332 ++++++------- src/{sdl => posix}/st_start.cpp | 708 +++++++++++++-------------- src/{cocoa => sdl}/i_system_cocoa.mm | 0 18 files changed, 958 insertions(+), 968 deletions(-) delete mode 120000 src/cocoa/dikeys.h delete mode 120000 src/cocoa/hardware.h delete mode 120000 src/cocoa/i_cd.cpp delete mode 120000 src/cocoa/i_input.h delete mode 120000 src/cocoa/i_movie.cpp delete mode 120000 src/cocoa/i_system.cpp delete mode 120000 src/cocoa/i_system.h delete mode 120000 src/cocoa/st_start.cpp rename src/{sdl => posix}/dikeys.h (96%) rename src/{sdl => posix}/hardware.h (97%) rename src/{sdl => posix}/i_cd.cpp (95%) rename src/{sdl => posix}/i_input.h (95%) rename src/{sdl => posix}/i_movie.cpp (92%) rename src/{sdl => posix}/i_system.cpp (100%) rename src/{sdl => posix}/i_system.h (96%) rename src/{sdl => posix}/st_start.cpp (96%) rename src/{cocoa => sdl}/i_system_cocoa.mm (100%) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 67f7d405b..207094fb6 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -545,19 +545,20 @@ set( PLAT_WIN32_SOURCES win32/i_system.cpp win32/st_start.cpp win32/win32video.cpp ) +set( PLAT_POSIX_SOURCES + posix/i_cd.cpp + posix/i_movie.cpp + posix/i_system.cpp + posix/st_start.cpp ) set( PLAT_SDL_SOURCES sdl/crashcatcher.c sdl/hardware.cpp - sdl/i_cd.cpp sdl/i_gui.cpp sdl/i_input.cpp sdl/i_joystick.cpp sdl/i_main.cpp - sdl/i_movie.cpp - sdl/i_system.cpp sdl/i_timer.cpp - sdl/sdlvideo.cpp - sdl/st_start.cpp ) + sdl/sdlvideo.cpp ) set( PLAT_MAC_SOURCES cocoa/iwadpicker_cocoa.mm ) set( PLAT_COCOA_SOURCES @@ -571,18 +572,14 @@ set( PLAT_COCOA_SOURCES cocoa/hid/ImmrHIDUtilAddOn.c cocoa/critsec.cpp cocoa/i_backend_cocoa.mm - cocoa/i_cd.cpp cocoa/i_joystick.cpp - cocoa/i_movie.cpp - cocoa/i_system.cpp cocoa/i_timer.cpp - cocoa/st_start.cpp cocoa/zdoom.icns ) if( WIN32 ) set( SYSTEM_SOURCES_DIR win32 ) set( SYSTEM_SOURCES ${PLAT_WIN32_SOURCES} ) - set( OTHER_SYSTEM_SOURCES ${PLAT_SDL_SOURCES} ${PLAT_MAC_SOURCES} ${PLAT_COCOA_SOURCES} ) + set( OTHER_SYSTEM_SOURCES ${PLAT_POSIX_SOURCES} ${PLAT_SDL_SOURCES} ${PLAT_MAC_SOURCES} ${PLAT_COCOA_SOURCES} ) if( ZD_CMAKE_COMPILER_IS_GNUCXX_COMPATIBLE ) # CMake is not set up to compile and link rc files with GCC. :( @@ -595,23 +592,23 @@ if( WIN32 ) endif( ZD_CMAKE_COMPILER_IS_GNUCXX_COMPATIBLE ) elseif( APPLE ) if( OSX_COCOA_BACKEND ) - set( SYSTEM_SOURCES_DIR cocoa ) + set( SYSTEM_SOURCES_DIR posix cocoa ) set( SYSTEM_SOURCES ${PLAT_COCOA_SOURCES} ) set( OTHER_SYSTEM_SOURCES ${PLAT_WIN32_SOURCES} ${PLAT_SDL_SOURCES} ) else( OSX_COCOA_BACKEND ) - set( SYSTEM_SOURCES_DIR sdl ) + set( SYSTEM_SOURCES_DIR posix sdl ) set( SYSTEM_SOURCES ${PLAT_SDL_SOURCES} ) set( PLAT_MAC_SOURCES ${PLAT_MAC_SOURCES} cocoa/i_system_cocoa.mm ) set( OTHER_SYSTEM_SOURCES ${PLAT_WIN32_SOURCES} ${PLAT_COCOA_SOURCES} ) endif( OSX_COCOA_BACKEND ) - set( SYSTEM_SOURCES ${SYSTEM_SOURCES} ${PLAT_MAC_SOURCES} "${FMOD_LIBRARY}" ) + set( SYSTEM_SOURCES ${SYSTEM_SOURCES} ${PLAT_POSIX_SOURCES} ${PLAT_MAC_SOURCES} "${FMOD_LIBRARY}" ) set_source_files_properties( cocoa/zdoom.icns PROPERTIES MACOSX_PACKAGE_LOCATION Resources ) set_source_files_properties( "${FMOD_LIBRARY}" PROPERTIES MACOSX_PACKAGE_LOCATION Frameworks ) else( WIN32 ) - set( SYSTEM_SOURCES_DIR sdl ) - set( SYSTEM_SOURCES ${PLAT_SDL_SOURCES} ) + set( SYSTEM_SOURCES_DIR posix sdl ) + set( SYSTEM_SOURCES ${PLAT_POSIX_SOURCES} ${PLAT_SDL_SOURCES} ) set( OTHER_SYSTEM_SOURCES ${PLAT_WIN32_SOURCES} ${PLAT_MAC_SOURCES} ${PLAT_COCOA_SOURCES} ) endif( WIN32 ) @@ -672,12 +669,12 @@ if( WIN32 ) set( EXTRA_HEADER_DIRS win32/*.h ) elseif( APPLE ) if( OSX_COCOA_BACKEND ) - set( EXTRA_HEADER_DIRS cocoa/*.h ) + set( EXTRA_HEADER_DIRS posix/*.h cocoa/*.h ) else( OSX_COCOA_BACKEND ) - set( EXTRA_HEADER_DIRS sdl/*.h ) + set( EXTRA_HEADER_DIRS posix/*.h sdl/*.h ) endif( OSX_COCOA_BACKEND ) else( WIN32 ) - set( EXTRA_HEADER_DIRS sdl/*.h ) + set( EXTRA_HEADER_DIRS posix/*.h sdl/*.h ) endif( WIN32 ) file( GLOB HEADER_FILES ${EXTRA_HEADER_DIRS} @@ -693,6 +690,7 @@ file( GLOB HEADER_FILES menu/*.h oplsynth/*.h oplsynth/dosbox/*.h + posix/*.h r_data/*.h resourcefiles/*.h sdl/*.h diff --git a/src/cocoa/dikeys.h b/src/cocoa/dikeys.h deleted file mode 120000 index 011f85acb..000000000 --- a/src/cocoa/dikeys.h +++ /dev/null @@ -1 +0,0 @@ -../sdl/dikeys.h \ No newline at end of file diff --git a/src/cocoa/hardware.h b/src/cocoa/hardware.h deleted file mode 120000 index 4261b9477..000000000 --- a/src/cocoa/hardware.h +++ /dev/null @@ -1 +0,0 @@ -../sdl/hardware.h \ No newline at end of file diff --git a/src/cocoa/i_cd.cpp b/src/cocoa/i_cd.cpp deleted file mode 120000 index 5573d7e1e..000000000 --- a/src/cocoa/i_cd.cpp +++ /dev/null @@ -1 +0,0 @@ -../sdl/i_cd.cpp \ No newline at end of file diff --git a/src/cocoa/i_input.h b/src/cocoa/i_input.h deleted file mode 120000 index 208b03106..000000000 --- a/src/cocoa/i_input.h +++ /dev/null @@ -1 +0,0 @@ -../sdl/i_input.h \ No newline at end of file diff --git a/src/cocoa/i_movie.cpp b/src/cocoa/i_movie.cpp deleted file mode 120000 index 04258f3e5..000000000 --- a/src/cocoa/i_movie.cpp +++ /dev/null @@ -1 +0,0 @@ -../sdl/i_movie.cpp \ No newline at end of file diff --git a/src/cocoa/i_system.cpp b/src/cocoa/i_system.cpp deleted file mode 120000 index b95185a13..000000000 --- a/src/cocoa/i_system.cpp +++ /dev/null @@ -1 +0,0 @@ -../sdl/i_system.cpp \ No newline at end of file diff --git a/src/cocoa/i_system.h b/src/cocoa/i_system.h deleted file mode 120000 index ced516311..000000000 --- a/src/cocoa/i_system.h +++ /dev/null @@ -1 +0,0 @@ -../sdl/i_system.h \ No newline at end of file diff --git a/src/cocoa/st_start.cpp b/src/cocoa/st_start.cpp deleted file mode 120000 index 38ce4fa1c..000000000 --- a/src/cocoa/st_start.cpp +++ /dev/null @@ -1 +0,0 @@ -../sdl/st_start.cpp \ No newline at end of file diff --git a/src/sdl/dikeys.h b/src/posix/dikeys.h similarity index 96% rename from src/sdl/dikeys.h rename to src/posix/dikeys.h index 8ce9e95bb..4541b0ffd 100644 --- a/src/sdl/dikeys.h +++ b/src/posix/dikeys.h @@ -1,155 +1,155 @@ -// ZDoom bases its keycodes on DirectInput's scan codes -// Why? Because it was Win32-only before porting to anything else, -// so this made sense. AFAIK, it's primarily used under Win32 now, -// so it still makes sense. -// -// Actually, these key codes may only be used for key bindings now, -// in which case they're not really necessary--if we tweaked c_bind.cpp. - -enum -{ - DIK_ESCAPE = 1, - DIK_1, - DIK_2, - DIK_3, - DIK_4, - DIK_5, - DIK_6, - DIK_7, - DIK_8, - DIK_9, - DIK_0, - DIK_MINUS, /* - on main keyboard */ - DIK_EQUALS, - DIK_BACK, /* backspace */ - DIK_TAB, - DIK_Q, - DIK_W, - DIK_E, - DIK_R, - DIK_T, - DIK_Y, - DIK_U, - DIK_I, - DIK_O, - DIK_P, - DIK_LBRACKET, - DIK_RBRACKET, - DIK_RETURN, /* Enter on main keyboard */ - DIK_LCONTROL, - DIK_A, - DIK_S, - DIK_D, - DIK_F, - DIK_G, - DIK_H, - DIK_J, - DIK_K, - DIK_L, - DIK_SEMICOLON, - DIK_APOSTROPHE, - DIK_GRAVE, /* accent grave */ - DIK_LSHIFT, - DIK_BACKSLASH, - DIK_Z, - DIK_X, - DIK_C, - DIK_V, - DIK_B, - DIK_N, - DIK_M, - DIK_COMMA, - DIK_PERIOD, /* . on main keyboard */ - DIK_SLASH, /* / on main keyboard */ - DIK_RSHIFT, - DIK_MULTIPLY, /* * on numeric keypad */ - DIK_LMENU, /* left Alt */ - DIK_SPACE, - DIK_CAPITAL, - DIK_F1, - DIK_F2, - DIK_F3, - DIK_F4, - DIK_F5, - DIK_F6, - DIK_F7, - DIK_F8, - DIK_F9, - DIK_F10, - DIK_NUMLOCK, - DIK_SCROLL, /* Scroll Lock */ - DIK_NUMPAD7, - DIK_NUMPAD8, - DIK_NUMPAD9, - DIK_SUBTRACT, /* - on numeric keypad */ - DIK_NUMPAD4, - DIK_NUMPAD5, - DIK_NUMPAD6, - DIK_ADD, /* + on numeric keypad */ - DIK_NUMPAD1, - DIK_NUMPAD2, - DIK_NUMPAD3, - DIK_NUMPAD0, - DIK_DECIMAL, /* . on numeric keypad */ - DIK_OEM_102 = 0x56, /* < > | on UK/Germany keyboards */ - DIK_F11, - DIK_F12, - DIK_F13 = 0x64, /* (NEC PC98) */ - DIK_F14, /* (NEC PC98) */ - DIK_F15, /* (NEC PC98) */ - DIK_KANA = 0x70, /* (Japanese keyboard) */ - DIK_ABNT_C1 = 0x73, /* / ? on Portugese (Brazilian) keyboards */ - DIK_CONVERT = 0x79, /* (Japanese keyboard) */ - DIK_NOCONVERT = 0x7B, /* (Japanese keyboard) */ - DIK_YEN = 0x7D, /* (Japanese keyboard) */ - DIK_ABNT_C2 = 0x7E, /* Numpad . on Portugese (Brazilian) keyboards */ - DIK_NUMPAD_EQUALS = 0x8D, /* = on numeric keypad (NEC PC98) */ - DIK_PREVTRACK = 0x90, /* Previous Track (DIK_CIRCUMFLEX on Japanese keyboard) */ - DIK_AT, /* (NEC PC98) */ - DIK_COLON, /* (NEC PC98) */ - DIK_UNDERLINE, /* (NEC PC98) */ - DIK_KANJI, /* (Japanese keyboard) */ - DIK_STOP, /* (NEC PC98) */ - DIK_AX, /* (Japan AX) */ - DIK_UNLABELED, /* (J3100) */ - DIK_NEXTTRACK = 0x99, /* Next Track */ - DIK_NUMPADENTER = 0x9C, /* Enter on numeric keypad */ - DIK_RCONTROL = 0x9D, - DIK_MUTE = 0xA0, /* Mute */ - DIK_CALCULATOR = 0xA1, /* Calculator */ - DIK_PLAYPAUSE = 0xA2, /* Play / Pause */ - DIK_MEDIASTOP = 0xA4, /* Media Stop */ - DIK_VOLUMEDOWN = 0xAE, /* Volume - */ - DIK_VOLUMEUP = 0xB0, /* Volume + */ - DIK_WEBHOME = 0xB2, /* Web home */ - DIK_NUMPADCOMMA = 0xB3, /* , on numeric keypad (NEC PC98) */ - DIK_DIVIDE = 0xB5, /* / on numeric keypad */ - DIK_SYSRQ = 0xB7, - DIK_RMENU = 0xB8, /* right Alt */ - DIK_PAUSE = 0xC5, /* Pause */ - DIK_HOME = 0xC7, /* Home on arrow keypad */ - DIK_UP = 0xC8, /* UpArrow on arrow keypad */ - DIK_PRIOR = 0xC9, /* PgUp on arrow keypad */ - DIK_LEFT = 0xCB, /* LeftArrow on arrow keypad */ - DIK_RIGHT = 0xCD, /* RightArrow on arrow keypad */ - DIK_END = 0xCF, /* End on arrow keypad */ - DIK_DOWN = 0xD0, /* DownArrow on arrow keypad */ - DIK_NEXT = 0xD1, /* PgDn on arrow keypad */ - DIK_INSERT = 0xD2, /* Insert on arrow keypad */ - DIK_DELETE = 0xD3, /* Delete on arrow keypad */ - DIK_LWIN = 0xDB, /* Left Windows key */ - DIK_RWIN = 0xDC, /* Right Windows key */ - DIK_APPS = 0xDD, /* AppMenu key */ - DIK_POWER = 0xDE, /* System Power */ - DIK_SLEEP = 0xDF, /* System Sleep */ - DIK_WAKE = 0xE3, /* System Wake */ - DIK_WEBSEARCH = 0xE5, /* Web Search */ - DIK_WEBFAVORITES = 0xE6, /* Web Favorites */ - DIK_WEBREFRESH = 0xE7, /* Web Refresh */ - DIK_WEBSTOP = 0xE8, /* Web Stop */ - DIK_WEBFORWARD = 0xE9, /* Web Forward */ - DIK_WEBBACK = 0xEA, /* Web Back */ - DIK_MYCOMPUTER = 0xEB, /* My Computer */ - DIK_MAIL = 0xEC, /* Mail */ - DIK_MEDIASELECT = 0xED /* Media Select */ -}; +// ZDoom bases its keycodes on DirectInput's scan codes +// Why? Because it was Win32-only before porting to anything else, +// so this made sense. AFAIK, it's primarily used under Win32 now, +// so it still makes sense. +// +// Actually, these key codes may only be used for key bindings now, +// in which case they're not really necessary--if we tweaked c_bind.cpp. + +enum +{ + DIK_ESCAPE = 1, + DIK_1, + DIK_2, + DIK_3, + DIK_4, + DIK_5, + DIK_6, + DIK_7, + DIK_8, + DIK_9, + DIK_0, + DIK_MINUS, /* - on main keyboard */ + DIK_EQUALS, + DIK_BACK, /* backspace */ + DIK_TAB, + DIK_Q, + DIK_W, + DIK_E, + DIK_R, + DIK_T, + DIK_Y, + DIK_U, + DIK_I, + DIK_O, + DIK_P, + DIK_LBRACKET, + DIK_RBRACKET, + DIK_RETURN, /* Enter on main keyboard */ + DIK_LCONTROL, + DIK_A, + DIK_S, + DIK_D, + DIK_F, + DIK_G, + DIK_H, + DIK_J, + DIK_K, + DIK_L, + DIK_SEMICOLON, + DIK_APOSTROPHE, + DIK_GRAVE, /* accent grave */ + DIK_LSHIFT, + DIK_BACKSLASH, + DIK_Z, + DIK_X, + DIK_C, + DIK_V, + DIK_B, + DIK_N, + DIK_M, + DIK_COMMA, + DIK_PERIOD, /* . on main keyboard */ + DIK_SLASH, /* / on main keyboard */ + DIK_RSHIFT, + DIK_MULTIPLY, /* * on numeric keypad */ + DIK_LMENU, /* left Alt */ + DIK_SPACE, + DIK_CAPITAL, + DIK_F1, + DIK_F2, + DIK_F3, + DIK_F4, + DIK_F5, + DIK_F6, + DIK_F7, + DIK_F8, + DIK_F9, + DIK_F10, + DIK_NUMLOCK, + DIK_SCROLL, /* Scroll Lock */ + DIK_NUMPAD7, + DIK_NUMPAD8, + DIK_NUMPAD9, + DIK_SUBTRACT, /* - on numeric keypad */ + DIK_NUMPAD4, + DIK_NUMPAD5, + DIK_NUMPAD6, + DIK_ADD, /* + on numeric keypad */ + DIK_NUMPAD1, + DIK_NUMPAD2, + DIK_NUMPAD3, + DIK_NUMPAD0, + DIK_DECIMAL, /* . on numeric keypad */ + DIK_OEM_102 = 0x56, /* < > | on UK/Germany keyboards */ + DIK_F11, + DIK_F12, + DIK_F13 = 0x64, /* (NEC PC98) */ + DIK_F14, /* (NEC PC98) */ + DIK_F15, /* (NEC PC98) */ + DIK_KANA = 0x70, /* (Japanese keyboard) */ + DIK_ABNT_C1 = 0x73, /* / ? on Portugese (Brazilian) keyboards */ + DIK_CONVERT = 0x79, /* (Japanese keyboard) */ + DIK_NOCONVERT = 0x7B, /* (Japanese keyboard) */ + DIK_YEN = 0x7D, /* (Japanese keyboard) */ + DIK_ABNT_C2 = 0x7E, /* Numpad . on Portugese (Brazilian) keyboards */ + DIK_NUMPAD_EQUALS = 0x8D, /* = on numeric keypad (NEC PC98) */ + DIK_PREVTRACK = 0x90, /* Previous Track (DIK_CIRCUMFLEX on Japanese keyboard) */ + DIK_AT, /* (NEC PC98) */ + DIK_COLON, /* (NEC PC98) */ + DIK_UNDERLINE, /* (NEC PC98) */ + DIK_KANJI, /* (Japanese keyboard) */ + DIK_STOP, /* (NEC PC98) */ + DIK_AX, /* (Japan AX) */ + DIK_UNLABELED, /* (J3100) */ + DIK_NEXTTRACK = 0x99, /* Next Track */ + DIK_NUMPADENTER = 0x9C, /* Enter on numeric keypad */ + DIK_RCONTROL = 0x9D, + DIK_MUTE = 0xA0, /* Mute */ + DIK_CALCULATOR = 0xA1, /* Calculator */ + DIK_PLAYPAUSE = 0xA2, /* Play / Pause */ + DIK_MEDIASTOP = 0xA4, /* Media Stop */ + DIK_VOLUMEDOWN = 0xAE, /* Volume - */ + DIK_VOLUMEUP = 0xB0, /* Volume + */ + DIK_WEBHOME = 0xB2, /* Web home */ + DIK_NUMPADCOMMA = 0xB3, /* , on numeric keypad (NEC PC98) */ + DIK_DIVIDE = 0xB5, /* / on numeric keypad */ + DIK_SYSRQ = 0xB7, + DIK_RMENU = 0xB8, /* right Alt */ + DIK_PAUSE = 0xC5, /* Pause */ + DIK_HOME = 0xC7, /* Home on arrow keypad */ + DIK_UP = 0xC8, /* UpArrow on arrow keypad */ + DIK_PRIOR = 0xC9, /* PgUp on arrow keypad */ + DIK_LEFT = 0xCB, /* LeftArrow on arrow keypad */ + DIK_RIGHT = 0xCD, /* RightArrow on arrow keypad */ + DIK_END = 0xCF, /* End on arrow keypad */ + DIK_DOWN = 0xD0, /* DownArrow on arrow keypad */ + DIK_NEXT = 0xD1, /* PgDn on arrow keypad */ + DIK_INSERT = 0xD2, /* Insert on arrow keypad */ + DIK_DELETE = 0xD3, /* Delete on arrow keypad */ + DIK_LWIN = 0xDB, /* Left Windows key */ + DIK_RWIN = 0xDC, /* Right Windows key */ + DIK_APPS = 0xDD, /* AppMenu key */ + DIK_POWER = 0xDE, /* System Power */ + DIK_SLEEP = 0xDF, /* System Sleep */ + DIK_WAKE = 0xE3, /* System Wake */ + DIK_WEBSEARCH = 0xE5, /* Web Search */ + DIK_WEBFAVORITES = 0xE6, /* Web Favorites */ + DIK_WEBREFRESH = 0xE7, /* Web Refresh */ + DIK_WEBSTOP = 0xE8, /* Web Stop */ + DIK_WEBFORWARD = 0xE9, /* Web Forward */ + DIK_WEBBACK = 0xEA, /* Web Back */ + DIK_MYCOMPUTER = 0xEB, /* My Computer */ + DIK_MAIL = 0xEC, /* Mail */ + DIK_MEDIASELECT = 0xED /* Media Select */ +}; diff --git a/src/sdl/hardware.h b/src/posix/hardware.h similarity index 97% rename from src/sdl/hardware.h rename to src/posix/hardware.h index 6544f1498..618941fe5 100644 --- a/src/sdl/hardware.h +++ b/src/posix/hardware.h @@ -1,96 +1,96 @@ -/* -** hardware.h -** -**--------------------------------------------------------------------------- -** Copyright 1998-2006 Randy Heit -** All rights reserved. -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** -** 1. Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** 2. Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in the -** documentation and/or other materials provided with the distribution. -** 3. The name of the author may not be used to endorse or promote products -** derived from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR -** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES -** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. -** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, -** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT -** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF -** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -**--------------------------------------------------------------------------- -** -*/ - -#ifndef __HARDWARE_H__ -#define __HARDWARE_H__ - -#include "i_video.h" -#include "v_video.h" - -// Semaphores -#ifdef __APPLE__ -#include -#include -#include -typedef semaphore_t Semaphore; -#define SEMAPHORE_WAIT(sem) \ - while(semaphore_wait(sem) != KERN_SUCCESS){} -#define SEMAPHORE_SIGNAL(sem) \ - semaphore_signal(sem); -#define SEMAPHORE_INIT(sem, shared, value) \ - semaphore_create(mach_task_self(), &sem, shared, value); -#else -#include -typedef sem_t Semaphore; -#define SEMAPHORE_WAIT(sem) \ - do { \ - while(sem_wait(&sem) != 0); \ - int semValue; \ - sem_getvalue(&sem, &semValue); \ - if(semValue < 1) \ - break; \ - } while(true); -#define SEMAPHORE_SIGNAL(sem) \ - sem_post(&sem); -#define SEMAPHORE_INIT(sem, shared, value) \ - sem_init(&sem, shared, value); -#endif - -class IVideo -{ - public: - virtual ~IVideo () {} - - virtual EDisplayType GetDisplayType () = 0; - virtual void SetWindowedScale (float scale) = 0; - - virtual DFrameBuffer *CreateFrameBuffer (int width, int height, bool fs, DFrameBuffer *old) = 0; - - virtual void StartModeIterator (int bits, bool fs) = 0; - virtual bool NextMode (int *width, int *height, bool *letterbox) = 0; - - virtual bool SetResolution (int width, int height, int bits); - - virtual void DumpAdapters(); -}; - -void I_InitGraphics (); -void I_ShutdownGraphics (); -void I_CreateRenderer(); - -extern Semaphore FPSLimitSemaphore; -void I_SetFPSLimit(int limit); - -extern IVideo *Video; - -#endif // __HARDWARE_H__ +/* +** hardware.h +** +**--------------------------------------------------------------------------- +** Copyright 1998-2006 Randy Heit +** All rights reserved. +** +** Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions +** are met: +** +** 1. Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** 2. Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in the +** documentation and/or other materials provided with the distribution. +** 3. The name of the author may not be used to endorse or promote products +** derived from this software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR +** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, +** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +**--------------------------------------------------------------------------- +** +*/ + +#ifndef __HARDWARE_H__ +#define __HARDWARE_H__ + +#include "i_video.h" +#include "v_video.h" + +// Semaphores +#ifdef __APPLE__ +#include +#include +#include +typedef semaphore_t Semaphore; +#define SEMAPHORE_WAIT(sem) \ + while(semaphore_wait(sem) != KERN_SUCCESS){} +#define SEMAPHORE_SIGNAL(sem) \ + semaphore_signal(sem); +#define SEMAPHORE_INIT(sem, shared, value) \ + semaphore_create(mach_task_self(), &sem, shared, value); +#else +#include +typedef sem_t Semaphore; +#define SEMAPHORE_WAIT(sem) \ + do { \ + while(sem_wait(&sem) != 0); \ + int semValue; \ + sem_getvalue(&sem, &semValue); \ + if(semValue < 1) \ + break; \ + } while(true); +#define SEMAPHORE_SIGNAL(sem) \ + sem_post(&sem); +#define SEMAPHORE_INIT(sem, shared, value) \ + sem_init(&sem, shared, value); +#endif + +class IVideo +{ + public: + virtual ~IVideo () {} + + virtual EDisplayType GetDisplayType () = 0; + virtual void SetWindowedScale (float scale) = 0; + + virtual DFrameBuffer *CreateFrameBuffer (int width, int height, bool fs, DFrameBuffer *old) = 0; + + virtual void StartModeIterator (int bits, bool fs) = 0; + virtual bool NextMode (int *width, int *height, bool *letterbox) = 0; + + virtual bool SetResolution (int width, int height, int bits); + + virtual void DumpAdapters(); +}; + +void I_InitGraphics (); +void I_ShutdownGraphics (); +void I_CreateRenderer(); + +extern Semaphore FPSLimitSemaphore; +void I_SetFPSLimit(int limit); + +extern IVideo *Video; + +#endif // __HARDWARE_H__ diff --git a/src/sdl/i_cd.cpp b/src/posix/i_cd.cpp similarity index 95% rename from src/sdl/i_cd.cpp rename to src/posix/i_cd.cpp index 83f1e8c89..96b59934c 100644 --- a/src/sdl/i_cd.cpp +++ b/src/posix/i_cd.cpp @@ -1,154 +1,154 @@ -#include "i_cd.h" - -//========================================================================== -// -// CD_Init -// -//========================================================================== - -bool CD_Init () -{ - return false; -} - -bool CD_Init (int device) -{ - return false; -} - -//========================================================================== -// -// CD_InitID -// -//========================================================================== - -bool CD_InitID (unsigned int id, int guess) -{ - return false; -} - -//========================================================================== -// -// CD_Close -// -//========================================================================== - -void CD_Close () -{ -} - -//========================================================================== -// -// CD_Eject -// -//========================================================================== - -void CD_Eject () -{ -} - -//========================================================================== -// -// CD_UnEject -// -//========================================================================== - -bool CD_UnEject () -{ - return false; -} - -//========================================================================== -// -// CD_Stop -// -//========================================================================== - -void CD_Stop () -{ -} - -//========================================================================== -// -// CD_Play -// -//========================================================================== - -bool CD_Play (int track, bool looping) -{ - return false; -} - -//========================================================================== -// -// CD_PlayNoWait -// -//========================================================================== - -void CD_PlayNoWait (int track, bool looping) -{ -} - -//========================================================================== -// -// CD_PlayCD -// -//========================================================================== - -bool CD_PlayCD (bool looping) -{ - return false; -} - -//========================================================================== -// -// CD_PlayCDNoWait -// -//========================================================================== - -void CD_PlayCDNoWait (bool looping) -{ -} - -//========================================================================== -// -// CD_Pause -// -//========================================================================== - -void CD_Pause () -{ -} - -//========================================================================== -// -// CD_Resume -// -//========================================================================== - -bool CD_Resume () -{ - return false; -} - -//========================================================================== -// -// CD_GetMode -// -//========================================================================== - -ECDModes CD_GetMode () -{ - return CDMode_Unknown; -} - -//========================================================================== -// -// CD_CheckTrack -// -//========================================================================== - -bool CD_CheckTrack (int track) -{ - return false; -} +#include "i_cd.h" + +//========================================================================== +// +// CD_Init +// +//========================================================================== + +bool CD_Init () +{ + return false; +} + +bool CD_Init (int device) +{ + return false; +} + +//========================================================================== +// +// CD_InitID +// +//========================================================================== + +bool CD_InitID (unsigned int id, int guess) +{ + return false; +} + +//========================================================================== +// +// CD_Close +// +//========================================================================== + +void CD_Close () +{ +} + +//========================================================================== +// +// CD_Eject +// +//========================================================================== + +void CD_Eject () +{ +} + +//========================================================================== +// +// CD_UnEject +// +//========================================================================== + +bool CD_UnEject () +{ + return false; +} + +//========================================================================== +// +// CD_Stop +// +//========================================================================== + +void CD_Stop () +{ +} + +//========================================================================== +// +// CD_Play +// +//========================================================================== + +bool CD_Play (int track, bool looping) +{ + return false; +} + +//========================================================================== +// +// CD_PlayNoWait +// +//========================================================================== + +void CD_PlayNoWait (int track, bool looping) +{ +} + +//========================================================================== +// +// CD_PlayCD +// +//========================================================================== + +bool CD_PlayCD (bool looping) +{ + return false; +} + +//========================================================================== +// +// CD_PlayCDNoWait +// +//========================================================================== + +void CD_PlayCDNoWait (bool looping) +{ +} + +//========================================================================== +// +// CD_Pause +// +//========================================================================== + +void CD_Pause () +{ +} + +//========================================================================== +// +// CD_Resume +// +//========================================================================== + +bool CD_Resume () +{ + return false; +} + +//========================================================================== +// +// CD_GetMode +// +//========================================================================== + +ECDModes CD_GetMode () +{ + return CDMode_Unknown; +} + +//========================================================================== +// +// CD_CheckTrack +// +//========================================================================== + +bool CD_CheckTrack (int track) +{ + return false; +} diff --git a/src/sdl/i_input.h b/src/posix/i_input.h similarity index 95% rename from src/sdl/i_input.h rename to src/posix/i_input.h index 124c2ca85..07ee1115d 100644 --- a/src/sdl/i_input.h +++ b/src/posix/i_input.h @@ -1,10 +1,10 @@ -#ifndef __I_INPUT_H__ -#define __I_INPUT_H__ - -void I_PutInClipboard (const char *str); -FString I_GetFromClipboard (bool use_primary_selection); -void I_SetMouseCapture(); -void I_ReleaseMouseCapture(); - -#endif - +#ifndef __I_INPUT_H__ +#define __I_INPUT_H__ + +void I_PutInClipboard (const char *str); +FString I_GetFromClipboard (bool use_primary_selection); +void I_SetMouseCapture(); +void I_ReleaseMouseCapture(); + +#endif + diff --git a/src/sdl/i_movie.cpp b/src/posix/i_movie.cpp similarity index 92% rename from src/sdl/i_movie.cpp rename to src/posix/i_movie.cpp index 020541516..8aea4b500 100644 --- a/src/sdl/i_movie.cpp +++ b/src/posix/i_movie.cpp @@ -1,7 +1,7 @@ -#include "i_movie.h" - -int I_PlayMovie (const char *movie) -{ - return MOVIE_Failed; -} - +#include "i_movie.h" + +int I_PlayMovie (const char *movie) +{ + return MOVIE_Failed; +} + diff --git a/src/sdl/i_system.cpp b/src/posix/i_system.cpp similarity index 100% rename from src/sdl/i_system.cpp rename to src/posix/i_system.cpp diff --git a/src/sdl/i_system.h b/src/posix/i_system.h similarity index 96% rename from src/sdl/i_system.h rename to src/posix/i_system.h index a3341f4c5..f0d399930 100644 --- a/src/sdl/i_system.h +++ b/src/posix/i_system.h @@ -1,166 +1,166 @@ -// Emacs style mode select -*- C++ -*- -//----------------------------------------------------------------------------- -// -// $Id:$ -// -// Copyright (C) 1993-1996 by id Software, Inc. -// -// This source is available for distribution and/or modification -// only under the terms of the DOOM Source Code License as -// published by id Software. All rights reserved. -// -// The source is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// FITNESS FOR A PARTICULAR PURPOSE. See the DOOM Source Code License -// for more details. -// -// DESCRIPTION: -// System specific interface stuff. -// -//----------------------------------------------------------------------------- - - -#ifndef __I_SYSTEM__ -#define __I_SYSTEM__ - -#include -#include - -#include "doomtype.h" - -struct ticcmd_t; -struct WadStuff; - -#ifndef SHARE_DIR -#define SHARE_DIR "/usr/local/share/" -#endif - -// Index values into the LanguageIDs array -enum -{ - LANGIDX_UserPreferred, - LANGIDX_UserDefault, - LANGIDX_SysPreferred, - LANGIDX_SysDefault -}; -extern DWORD LanguageIDs[4]; -extern void SetLanguageIDs (); - -// Called by DoomMain. -void I_Init (void); - -// Called by D_DoomLoop, -// returns current time in tics. -extern int (*I_GetTime) (bool saveMS); - -// like I_GetTime, except it waits for a new tic before returning -extern int (*I_WaitForTic) (int); - -// Freezes tic counting temporarily. While frozen, calls to I_GetTime() -// will always return the same value. This does not affect I_MSTime(). -// You must also not call I_WaitForTic() while freezing time, since the -// tic will never arrive (unless it's the current one). -extern void (*I_FreezeTime) (bool frozen); - -fixed_t I_GetTimeFrac (uint32 *ms); - -// Return a seed value for the RNG. -unsigned int I_MakeRNGSeed(); - - -// -// Called by D_DoomLoop, -// called before processing any tics in a frame -// (just after displaying a frame). -// Time consuming syncronous operations -// are performed here (joystick reading). -// Can call D_PostEvent. -// -void I_StartFrame (void); - - -// -// Called by D_DoomLoop, -// called before processing each tic in a frame. -// Quick syncronous operations are performed here. -// Can call D_PostEvent. -void I_StartTic (void); - -// Asynchronous interrupt functions should maintain private queues -// that are read by the synchronous functions -// to be converted into events. - -// Either returns a null ticcmd, -// or calls a loadable driver to build it. -// This ticcmd will then be modified by the gameloop -// for normal input. -ticcmd_t *I_BaseTiccmd (void); - - -// Called by M_Responder when quit is selected. -// Clean exit, displays sell blurb. -void I_Quit (void); - - -void I_Tactile (int on, int off, int total); - -void STACK_ARGS I_Error (const char *error, ...) GCCPRINTF(1,2); -void STACK_ARGS I_FatalError (const char *error, ...) GCCPRINTF(1,2); - -void addterm (void (*func)(void), const char *name); -#define atterm(t) addterm (t, #t) -void popterm (); - -// Print a console string -void I_PrintStr (const char *str); - -// Set the title string of the startup window -void I_SetIWADInfo (); - -// Pick from multiple IWADs to use -int I_PickIWad (WadStuff *wads, int numwads, bool queryiwad, int defaultiwad); - -// The ini could not be saved at exit -bool I_WriteIniFailed (); - -// [RH] Returns millisecond-accurate time -unsigned int I_MSTime (void); -unsigned int I_FPSTime(); - -class FTexture; -bool I_SetCursor(FTexture *); - -// Directory searching routines - -struct findstate_t -{ - int count; - struct dirent **namelist; - int current; -}; - -void *I_FindFirst (const char *filespec, findstate_t *fileinfo); -int I_FindNext (void *handle, findstate_t *fileinfo); -int I_FindClose (void *handle); -int I_FindAttr (findstate_t *fileinfo); - -#define I_FindName(a) ((a)->namelist[(a)->current]->d_name) - -#define FA_RDONLY 1 -#define FA_HIDDEN 2 -#define FA_SYSTEM 4 -#define FA_DIREC 8 -#define FA_ARCH 16 - -static inline char *strlwr(char *str) -{ - char *ptr = str; - while(*ptr) - { - *ptr = tolower(*ptr); - ++ptr; - } - return str; -} - -#endif +// Emacs style mode select -*- C++ -*- +//----------------------------------------------------------------------------- +// +// $Id:$ +// +// Copyright (C) 1993-1996 by id Software, Inc. +// +// This source is available for distribution and/or modification +// only under the terms of the DOOM Source Code License as +// published by id Software. All rights reserved. +// +// The source is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// FITNESS FOR A PARTICULAR PURPOSE. See the DOOM Source Code License +// for more details. +// +// DESCRIPTION: +// System specific interface stuff. +// +//----------------------------------------------------------------------------- + + +#ifndef __I_SYSTEM__ +#define __I_SYSTEM__ + +#include +#include + +#include "doomtype.h" + +struct ticcmd_t; +struct WadStuff; + +#ifndef SHARE_DIR +#define SHARE_DIR "/usr/local/share/" +#endif + +// Index values into the LanguageIDs array +enum +{ + LANGIDX_UserPreferred, + LANGIDX_UserDefault, + LANGIDX_SysPreferred, + LANGIDX_SysDefault +}; +extern DWORD LanguageIDs[4]; +extern void SetLanguageIDs (); + +// Called by DoomMain. +void I_Init (void); + +// Called by D_DoomLoop, +// returns current time in tics. +extern int (*I_GetTime) (bool saveMS); + +// like I_GetTime, except it waits for a new tic before returning +extern int (*I_WaitForTic) (int); + +// Freezes tic counting temporarily. While frozen, calls to I_GetTime() +// will always return the same value. This does not affect I_MSTime(). +// You must also not call I_WaitForTic() while freezing time, since the +// tic will never arrive (unless it's the current one). +extern void (*I_FreezeTime) (bool frozen); + +fixed_t I_GetTimeFrac (uint32 *ms); + +// Return a seed value for the RNG. +unsigned int I_MakeRNGSeed(); + + +// +// Called by D_DoomLoop, +// called before processing any tics in a frame +// (just after displaying a frame). +// Time consuming syncronous operations +// are performed here (joystick reading). +// Can call D_PostEvent. +// +void I_StartFrame (void); + + +// +// Called by D_DoomLoop, +// called before processing each tic in a frame. +// Quick syncronous operations are performed here. +// Can call D_PostEvent. +void I_StartTic (void); + +// Asynchronous interrupt functions should maintain private queues +// that are read by the synchronous functions +// to be converted into events. + +// Either returns a null ticcmd, +// or calls a loadable driver to build it. +// This ticcmd will then be modified by the gameloop +// for normal input. +ticcmd_t *I_BaseTiccmd (void); + + +// Called by M_Responder when quit is selected. +// Clean exit, displays sell blurb. +void I_Quit (void); + + +void I_Tactile (int on, int off, int total); + +void STACK_ARGS I_Error (const char *error, ...) GCCPRINTF(1,2); +void STACK_ARGS I_FatalError (const char *error, ...) GCCPRINTF(1,2); + +void addterm (void (*func)(void), const char *name); +#define atterm(t) addterm (t, #t) +void popterm (); + +// Print a console string +void I_PrintStr (const char *str); + +// Set the title string of the startup window +void I_SetIWADInfo (); + +// Pick from multiple IWADs to use +int I_PickIWad (WadStuff *wads, int numwads, bool queryiwad, int defaultiwad); + +// The ini could not be saved at exit +bool I_WriteIniFailed (); + +// [RH] Returns millisecond-accurate time +unsigned int I_MSTime (void); +unsigned int I_FPSTime(); + +class FTexture; +bool I_SetCursor(FTexture *); + +// Directory searching routines + +struct findstate_t +{ + int count; + struct dirent **namelist; + int current; +}; + +void *I_FindFirst (const char *filespec, findstate_t *fileinfo); +int I_FindNext (void *handle, findstate_t *fileinfo); +int I_FindClose (void *handle); +int I_FindAttr (findstate_t *fileinfo); + +#define I_FindName(a) ((a)->namelist[(a)->current]->d_name) + +#define FA_RDONLY 1 +#define FA_HIDDEN 2 +#define FA_SYSTEM 4 +#define FA_DIREC 8 +#define FA_ARCH 16 + +static inline char *strlwr(char *str) +{ + char *ptr = str; + while(*ptr) + { + *ptr = tolower(*ptr); + ++ptr; + } + return str; +} + +#endif diff --git a/src/sdl/st_start.cpp b/src/posix/st_start.cpp similarity index 96% rename from src/sdl/st_start.cpp rename to src/posix/st_start.cpp index 33a5abe0b..060548b53 100644 --- a/src/sdl/st_start.cpp +++ b/src/posix/st_start.cpp @@ -1,354 +1,354 @@ -/* -** st_start.cpp -** Handles the startup screen. -** -**--------------------------------------------------------------------------- -** Copyright 2006-2007 Randy Heit -** All rights reserved. -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** -** 1. Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** 2. Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in the -** documentation and/or other materials provided with the distribution. -** 3. The name of the author may not be used to endorse or promote products -** derived from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR -** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES -** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. -** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, -** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT -** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF -** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -**--------------------------------------------------------------------------- -** -*/ - -// HEADER FILES ------------------------------------------------------------ - -#include -#include -#include -#include - -#include "st_start.h" -#include "doomdef.h" -#include "i_system.h" -#include "c_cvars.h" - -// MACROS ------------------------------------------------------------------ - -// TYPES ------------------------------------------------------------------- - -class FTTYStartupScreen : public FStartupScreen -{ - public: - FTTYStartupScreen(int max_progress); - ~FTTYStartupScreen(); - - void Progress(); - void NetInit(const char *message, int num_players); - void NetProgress(int count); - void NetMessage(const char *format, ...); // cover for printf - void NetDone(); - bool NetLoop(bool (*timer_callback)(void *), void *userdata); - protected: - bool DidNetInit; - int NetMaxPos, NetCurPos; - const char *TheNetMessage; - termios OldTermIOS; -}; - -// EXTERNAL FUNCTION PROTOTYPES -------------------------------------------- - -// PUBLIC FUNCTION PROTOTYPES ---------------------------------------------- - -void I_ShutdownJoysticks(); - -// PRIVATE FUNCTION PROTOTYPES --------------------------------------------- - -static void DeleteStartupScreen(); - -// EXTERNAL DATA DECLARATIONS ---------------------------------------------- - -// PUBLIC DATA DEFINITIONS ------------------------------------------------- - -FStartupScreen *StartScreen; - -CUSTOM_CVAR(Int, showendoom, 0, CVAR_ARCHIVE|CVAR_GLOBALCONFIG) -{ - if (self < 0) self = 0; - else if (self > 2) self=2; -} - -// PRIVATE DATA DEFINITIONS ------------------------------------------------ - -static const char SpinnyProgressChars[4] = { '|', '/', '-', '\\' }; - -// CODE -------------------------------------------------------------------- - -//========================================================================== -// -// FStartupScreen :: CreateInstance -// -// Initializes the startup screen for the detected game. -// Sets the size of the progress bar and displays the startup screen. -// -//========================================================================== - -FStartupScreen *FStartupScreen::CreateInstance(int max_progress) -{ - atterm(DeleteStartupScreen); - return new FTTYStartupScreen(max_progress); -} - -//=========================================================================== -// -// DeleteStartupScreen -// -// Makes sure the startup screen has been deleted before quitting. -// -//=========================================================================== - -void DeleteStartupScreen() -{ - if (StartScreen != NULL) - { - delete StartScreen; - StartScreen = NULL; - } -} - -//=========================================================================== -// -// FTTYStartupScreen Constructor -// -// Sets the size of the progress bar and displays the startup screen. -// -//=========================================================================== - -FTTYStartupScreen::FTTYStartupScreen(int max_progress) - : FStartupScreen(max_progress) -{ - DidNetInit = false; - NetMaxPos = 0; - NetCurPos = 0; - TheNetMessage = NULL; -} - -//=========================================================================== -// -// FTTYStartupScreen Destructor -// -// Called just before entering graphics mode to deconstruct the startup -// screen. -// -//=========================================================================== - -FTTYStartupScreen::~FTTYStartupScreen() -{ - NetDone(); // Just in case it wasn't called yet and needs to be. -} - -//=========================================================================== -// -// FTTYStartupScreen :: Progress -// -// If there was a progress bar, this would move it. But the basic TTY -// startup screen doesn't have one, so this function does nothing. -// -//=========================================================================== - -void FTTYStartupScreen::Progress() -{ -} - -//=========================================================================== -// -// FTTYStartupScreen :: NetInit -// -// Sets stdin for unbuffered I/O, displays the given message, and shows -// a progress meter. -// -//=========================================================================== - -void FTTYStartupScreen::NetInit(const char *message, int numplayers) -{ - if (!DidNetInit) - { - termios rawtermios; - - fprintf (stderr, "Press 'Q' to abort network game synchronization."); - // Set stdin to raw mode so we can get keypresses in ST_CheckNetAbort() - // immediately without waiting for an EOL. - tcgetattr (STDIN_FILENO, &OldTermIOS); - rawtermios = OldTermIOS; - rawtermios.c_lflag &= ~(ICANON | ECHO); - tcsetattr (STDIN_FILENO, TCSANOW, &rawtermios); - DidNetInit = true; - } - if (numplayers == 1) - { - // Status message without any real progress info. - fprintf (stderr, "\n%s.", message); - } - else - { - fprintf (stderr, "\n%s: ", message); - } - fflush (stderr); - TheNetMessage = message; - NetMaxPos = numplayers; - NetCurPos = 0; - NetProgress(1); // You always know about yourself -} - -//=========================================================================== -// -// FTTYStartupScreen :: NetDone -// -// Restores the old stdin tty settings. -// -//=========================================================================== - -void FTTYStartupScreen::NetDone() -{ - // Restore stdin settings - if (DidNetInit) - { - tcsetattr (STDIN_FILENO, TCSANOW, &OldTermIOS); - printf ("\n"); - DidNetInit = false; - } -} - -//=========================================================================== -// -// FTTYStartupScreen :: NetMessage -// -// Call this between NetInit() and NetDone() instead of Printf() to -// display messages, because the progress meter is mixed in the same output -// stream as normal messages. -// -//=========================================================================== - -void FTTYStartupScreen::NetMessage(const char *format, ...) -{ - FString str; - va_list argptr; - - va_start (argptr, format); - str.VFormat (format, argptr); - va_end (argptr); - fprintf (stderr, "\r%-40s\n", str.GetChars()); -} - -//=========================================================================== -// -// FTTYStartupScreen :: NetProgress -// -// Sets the network progress meter. If count is 0, it gets bumped by 1. -// Otherwise, it is set to count. -// -//=========================================================================== - -void FTTYStartupScreen::NetProgress(int count) -{ - int i; - - if (count == 0) - { - NetCurPos++; - } - else if (count > 0) - { - NetCurPos = count; - } - if (NetMaxPos == 0) - { - // Spinny-type progress meter, because we're a guest waiting for the host. - fprintf (stderr, "\r%s: %c", TheNetMessage, SpinnyProgressChars[NetCurPos & 3]); - fflush (stderr); - } - else if (NetMaxPos > 1) - { - // Dotty-type progress meter. - fprintf (stderr, "\r%s: ", TheNetMessage); - for (i = 0; i < NetCurPos; ++i) - { - fputc ('.', stderr); - } - fprintf (stderr, "%*c[%2d/%2d]", NetMaxPos + 1 - NetCurPos, ' ', NetCurPos, NetMaxPos); - fflush (stderr); - } -} - -//=========================================================================== -// -// FTTYStartupScreen :: NetLoop -// -// The timer_callback function is called at least two times per second -// and passed the userdata value. It should return true to stop the loop and -// return control to the caller or false to continue the loop. -// -// ST_NetLoop will return true if the loop was halted by the callback and -// false if the loop was halted because the user wants to abort the -// network synchronization. -// -//=========================================================================== - -bool FTTYStartupScreen::NetLoop(bool (*timer_callback)(void *), void *userdata) -{ - fd_set rfds; - struct timeval tv; - int retval; - char k; - - for (;;) - { - // Don't flood the network with packets on startup. - tv.tv_sec = 0; - tv.tv_usec = 500000; - - FD_ZERO (&rfds); - FD_SET (STDIN_FILENO, &rfds); - - retval = select (1, &rfds, NULL, NULL, &tv); - - if (retval == -1) - { - // Error - } - else if (retval == 0) - { - if (timer_callback (userdata)) - { - fputc ('\n', stderr); - return true; - } - } - else if (read (STDIN_FILENO, &k, 1) == 1) - { - // Check input on stdin - if (k == 'q' || k == 'Q') - { - fprintf (stderr, "\nNetwork game synchronization aborted."); - return false; - } - } - } -} - -void ST_Endoom() -{ - I_ShutdownJoysticks(); - exit(0); -} +/* +** st_start.cpp +** Handles the startup screen. +** +**--------------------------------------------------------------------------- +** Copyright 2006-2007 Randy Heit +** All rights reserved. +** +** Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions +** are met: +** +** 1. Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** 2. Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in the +** documentation and/or other materials provided with the distribution. +** 3. The name of the author may not be used to endorse or promote products +** derived from this software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR +** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, +** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +**--------------------------------------------------------------------------- +** +*/ + +// HEADER FILES ------------------------------------------------------------ + +#include +#include +#include +#include + +#include "st_start.h" +#include "doomdef.h" +#include "i_system.h" +#include "c_cvars.h" + +// MACROS ------------------------------------------------------------------ + +// TYPES ------------------------------------------------------------------- + +class FTTYStartupScreen : public FStartupScreen +{ + public: + FTTYStartupScreen(int max_progress); + ~FTTYStartupScreen(); + + void Progress(); + void NetInit(const char *message, int num_players); + void NetProgress(int count); + void NetMessage(const char *format, ...); // cover for printf + void NetDone(); + bool NetLoop(bool (*timer_callback)(void *), void *userdata); + protected: + bool DidNetInit; + int NetMaxPos, NetCurPos; + const char *TheNetMessage; + termios OldTermIOS; +}; + +// EXTERNAL FUNCTION PROTOTYPES -------------------------------------------- + +// PUBLIC FUNCTION PROTOTYPES ---------------------------------------------- + +void I_ShutdownJoysticks(); + +// PRIVATE FUNCTION PROTOTYPES --------------------------------------------- + +static void DeleteStartupScreen(); + +// EXTERNAL DATA DECLARATIONS ---------------------------------------------- + +// PUBLIC DATA DEFINITIONS ------------------------------------------------- + +FStartupScreen *StartScreen; + +CUSTOM_CVAR(Int, showendoom, 0, CVAR_ARCHIVE|CVAR_GLOBALCONFIG) +{ + if (self < 0) self = 0; + else if (self > 2) self=2; +} + +// PRIVATE DATA DEFINITIONS ------------------------------------------------ + +static const char SpinnyProgressChars[4] = { '|', '/', '-', '\\' }; + +// CODE -------------------------------------------------------------------- + +//========================================================================== +// +// FStartupScreen :: CreateInstance +// +// Initializes the startup screen for the detected game. +// Sets the size of the progress bar and displays the startup screen. +// +//========================================================================== + +FStartupScreen *FStartupScreen::CreateInstance(int max_progress) +{ + atterm(DeleteStartupScreen); + return new FTTYStartupScreen(max_progress); +} + +//=========================================================================== +// +// DeleteStartupScreen +// +// Makes sure the startup screen has been deleted before quitting. +// +//=========================================================================== + +void DeleteStartupScreen() +{ + if (StartScreen != NULL) + { + delete StartScreen; + StartScreen = NULL; + } +} + +//=========================================================================== +// +// FTTYStartupScreen Constructor +// +// Sets the size of the progress bar and displays the startup screen. +// +//=========================================================================== + +FTTYStartupScreen::FTTYStartupScreen(int max_progress) + : FStartupScreen(max_progress) +{ + DidNetInit = false; + NetMaxPos = 0; + NetCurPos = 0; + TheNetMessage = NULL; +} + +//=========================================================================== +// +// FTTYStartupScreen Destructor +// +// Called just before entering graphics mode to deconstruct the startup +// screen. +// +//=========================================================================== + +FTTYStartupScreen::~FTTYStartupScreen() +{ + NetDone(); // Just in case it wasn't called yet and needs to be. +} + +//=========================================================================== +// +// FTTYStartupScreen :: Progress +// +// If there was a progress bar, this would move it. But the basic TTY +// startup screen doesn't have one, so this function does nothing. +// +//=========================================================================== + +void FTTYStartupScreen::Progress() +{ +} + +//=========================================================================== +// +// FTTYStartupScreen :: NetInit +// +// Sets stdin for unbuffered I/O, displays the given message, and shows +// a progress meter. +// +//=========================================================================== + +void FTTYStartupScreen::NetInit(const char *message, int numplayers) +{ + if (!DidNetInit) + { + termios rawtermios; + + fprintf (stderr, "Press 'Q' to abort network game synchronization."); + // Set stdin to raw mode so we can get keypresses in ST_CheckNetAbort() + // immediately without waiting for an EOL. + tcgetattr (STDIN_FILENO, &OldTermIOS); + rawtermios = OldTermIOS; + rawtermios.c_lflag &= ~(ICANON | ECHO); + tcsetattr (STDIN_FILENO, TCSANOW, &rawtermios); + DidNetInit = true; + } + if (numplayers == 1) + { + // Status message without any real progress info. + fprintf (stderr, "\n%s.", message); + } + else + { + fprintf (stderr, "\n%s: ", message); + } + fflush (stderr); + TheNetMessage = message; + NetMaxPos = numplayers; + NetCurPos = 0; + NetProgress(1); // You always know about yourself +} + +//=========================================================================== +// +// FTTYStartupScreen :: NetDone +// +// Restores the old stdin tty settings. +// +//=========================================================================== + +void FTTYStartupScreen::NetDone() +{ + // Restore stdin settings + if (DidNetInit) + { + tcsetattr (STDIN_FILENO, TCSANOW, &OldTermIOS); + printf ("\n"); + DidNetInit = false; + } +} + +//=========================================================================== +// +// FTTYStartupScreen :: NetMessage +// +// Call this between NetInit() and NetDone() instead of Printf() to +// display messages, because the progress meter is mixed in the same output +// stream as normal messages. +// +//=========================================================================== + +void FTTYStartupScreen::NetMessage(const char *format, ...) +{ + FString str; + va_list argptr; + + va_start (argptr, format); + str.VFormat (format, argptr); + va_end (argptr); + fprintf (stderr, "\r%-40s\n", str.GetChars()); +} + +//=========================================================================== +// +// FTTYStartupScreen :: NetProgress +// +// Sets the network progress meter. If count is 0, it gets bumped by 1. +// Otherwise, it is set to count. +// +//=========================================================================== + +void FTTYStartupScreen::NetProgress(int count) +{ + int i; + + if (count == 0) + { + NetCurPos++; + } + else if (count > 0) + { + NetCurPos = count; + } + if (NetMaxPos == 0) + { + // Spinny-type progress meter, because we're a guest waiting for the host. + fprintf (stderr, "\r%s: %c", TheNetMessage, SpinnyProgressChars[NetCurPos & 3]); + fflush (stderr); + } + else if (NetMaxPos > 1) + { + // Dotty-type progress meter. + fprintf (stderr, "\r%s: ", TheNetMessage); + for (i = 0; i < NetCurPos; ++i) + { + fputc ('.', stderr); + } + fprintf (stderr, "%*c[%2d/%2d]", NetMaxPos + 1 - NetCurPos, ' ', NetCurPos, NetMaxPos); + fflush (stderr); + } +} + +//=========================================================================== +// +// FTTYStartupScreen :: NetLoop +// +// The timer_callback function is called at least two times per second +// and passed the userdata value. It should return true to stop the loop and +// return control to the caller or false to continue the loop. +// +// ST_NetLoop will return true if the loop was halted by the callback and +// false if the loop was halted because the user wants to abort the +// network synchronization. +// +//=========================================================================== + +bool FTTYStartupScreen::NetLoop(bool (*timer_callback)(void *), void *userdata) +{ + fd_set rfds; + struct timeval tv; + int retval; + char k; + + for (;;) + { + // Don't flood the network with packets on startup. + tv.tv_sec = 0; + tv.tv_usec = 500000; + + FD_ZERO (&rfds); + FD_SET (STDIN_FILENO, &rfds); + + retval = select (1, &rfds, NULL, NULL, &tv); + + if (retval == -1) + { + // Error + } + else if (retval == 0) + { + if (timer_callback (userdata)) + { + fputc ('\n', stderr); + return true; + } + } + else if (read (STDIN_FILENO, &k, 1) == 1) + { + // Check input on stdin + if (k == 'q' || k == 'Q') + { + fprintf (stderr, "\nNetwork game synchronization aborted."); + return false; + } + } + } +} + +void ST_Endoom() +{ + I_ShutdownJoysticks(); + exit(0); +} diff --git a/src/cocoa/i_system_cocoa.mm b/src/sdl/i_system_cocoa.mm similarity index 100% rename from src/cocoa/i_system_cocoa.mm rename to src/sdl/i_system_cocoa.mm From b9d83e88c908518b2104e14db353a38748a7eba2 Mon Sep 17 00:00:00 2001 From: "alexey.lysiuk" Date: Tue, 16 Dec 2014 22:46:24 +0200 Subject: [PATCH 14/46] Added missing #include --- src/posix/i_steam.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/posix/i_steam.cpp b/src/posix/i_steam.cpp index be0be227b..9819bc09e 100644 --- a/src/posix/i_steam.cpp +++ b/src/posix/i_steam.cpp @@ -34,6 +34,10 @@ #include +#ifdef __APPLE__ +#include +#endif // __APPLE__ + #include "doomerrors.h" #include "d_main.h" #include "zstring.h" From 7d231c30089c3549ff58376c63b8325287199078 Mon Sep 17 00:00:00 2001 From: "alexey.lysiuk" Date: Tue, 16 Dec 2014 22:56:09 +0200 Subject: [PATCH 15/46] Removed unnecessary SDL #include's --- src/sound/i_music.cpp | 1 - src/sound/i_musicinterns.h | 1 - src/tempfiles.h | 2 ++ 3 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/sound/i_music.cpp b/src/sound/i_music.cpp index 93802c8e8..84d1d8101 100644 --- a/src/sound/i_music.cpp +++ b/src/sound/i_music.cpp @@ -37,7 +37,6 @@ #include #include #else -#include #include #include #include diff --git a/src/sound/i_musicinterns.h b/src/sound/i_musicinterns.h index fa04cfa51..2133e07c6 100644 --- a/src/sound/i_musicinterns.h +++ b/src/sound/i_musicinterns.h @@ -13,7 +13,6 @@ #include #include #else -#include #define FALSE 0 #define TRUE 1 #endif diff --git a/src/tempfiles.h b/src/tempfiles.h index beeb2bc1d..406c54153 100644 --- a/src/tempfiles.h +++ b/src/tempfiles.h @@ -38,6 +38,8 @@ #pragma once #endif +#include + // Returns a file name suitable for use as a temp file. // If you create a file with this name (and presumably you // will), it will be deleted automatically by this class's From 9f01384bc54aacaff4950f15a8f42219c2b3e8d5 Mon Sep 17 00:00:00 2001 From: "alexey.lysiuk" Date: Tue, 16 Dec 2014 22:58:39 +0200 Subject: [PATCH 16/46] No more SDL dependency in native OS X backend --- src/cocoa/i_backend_cocoa.mm | 337 ++++++++++++++++++++--------------- 1 file changed, 192 insertions(+), 145 deletions(-) diff --git a/src/cocoa/i_backend_cocoa.mm b/src/cocoa/i_backend_cocoa.mm index 442a7192a..571c3847b 100644 --- a/src/cocoa/i_backend_cocoa.mm +++ b/src/cocoa/i_backend_cocoa.mm @@ -36,7 +36,6 @@ #include #include -#include #include #include @@ -45,8 +44,6 @@ #include #include -#include - // Avoid collision between DObject class and Objective-C #define Class ObjectClass @@ -361,7 +358,7 @@ bool s_restartedFromWADPicker; bool s_nativeMouse = true; - + // TODO: remove this magic! size_t s_skipMouseMoves; @@ -376,8 +373,8 @@ void NewFailure() int OriginalMain(int argc, char** argv) { - printf(GAMENAME" %s - %s - Cocoa version\nCompiled on %s\n", - GetVersionString(), GetGitTime(), __DATE__); + printf(GAMENAME" %s - %s - Cocoa version\nCompiled on %s\n\n", + GetVersionString(), GetGitTime(), __DATE__); seteuid(getuid()); std::set_new_handler(NewFailure); @@ -388,24 +385,12 @@ int OriginalMain(int argc, char** argv) setenv("LC_NUMERIC", "C", 1); setlocale(LC_ALL, "C"); - if (SDL_Init (SDL_INIT_VIDEO|SDL_INIT_TIMER|SDL_INIT_NOPARACHUTE|SDL_INIT_JOYSTICK) == -1) - { - fprintf (stderr, "Could not initialize SDL:\n%s\n", SDL_GetError()); - return -1; - } - atterm(SDL_Quit); - - printf("\n"); - - SDL_DisplayMode videoInfo = {}; - - if (0 == SDL_GetDesktopDisplayMode(vid_adapter, &videoInfo)) - { - vid_defwidth = videoInfo.w; - vid_defheight = videoInfo.h; - vid_vsync = true; - fullscreen = true; - } + // Set reasonable default values for video settings + const NSSize screenSize = [[NSScreen mainScreen] frame].size; + vid_defwidth = static_cast(screenSize.width); + vid_defheight = static_cast(screenSize.height); + vid_vsync = true; + fullscreen = true; try { @@ -458,7 +443,7 @@ int OriginalMain(int argc, char** argv) fprintf(stderr, "%s\n", message); Mac_I_FatalError(message); } - + exit(-1); } catch(...) @@ -466,7 +451,7 @@ int OriginalMain(int argc, char** argv) call_terms(); throw; } - + return 0; } @@ -479,7 +464,7 @@ void CheckGUICapture() const bool wantCapture = (MENU_Off == menuactive) ? (c_down == ConsoleState || c_falling == ConsoleState || chatmodeon) : (menuactive == MENU_On || menuactive == MENU_OnNoPause); - + if (wantCapture != GUICapture) { GUICapture = wantCapture; @@ -499,9 +484,9 @@ void CenterCursor() const NSRect displayRect = [[window screen] frame]; const NSRect windowRect = [window frame]; const CGPoint centerPoint = CGPointMake(NSMidX(windowRect), displayRect.size.height - NSMidY(windowRect)); - + CGEventSourceRef eventSource = CGEventSourceCreate(kCGEventSourceStateCombinedSessionState); - + if (NULL != eventSource) { CGEventRef mouseMoveEvent = CGEventCreateMouseEvent(eventSource, @@ -512,10 +497,10 @@ void CenterCursor() CGEventPost(kCGHIDEventTap, mouseMoveEvent); CFRelease(mouseMoveEvent); } - + CFRelease(eventSource); } - + // TODO: remove this magic! s_skipMouseMoves = 2; } @@ -528,10 +513,10 @@ bool IsInGame() default: case 0: return gamestate == GS_LEVEL; - + case 1: return gamestate == GS_LEVEL || gamestate == GS_INTERMISSION || gamestate == GS_FINALE; - + case 2: return true; } @@ -547,7 +532,7 @@ void SetNativeMouse(bool wantNative) { CenterCursor(); } - + CGAssociateMouseAndMouseCursorPosition(wantNative); if (wantNative) @@ -565,7 +550,7 @@ void CheckNativeMouse() { bool windowed = (NULL == screen) || !screen->IsFullscreen(); bool wantNative; - + if (windowed) { if (![NSApp isActive] || !use_mouse) @@ -588,7 +573,7 @@ void CheckNativeMouse() wantNative = m_use_mouse && (MENU_On == menuactive || MENU_OnNoPause == menuactive); } - + SetNativeMouse(wantNative); } @@ -608,7 +593,7 @@ void I_StartTic() { CheckGUICapture(); CheckNativeMouse(); - + I_ProcessJoysticks(); I_GetEvent(); } @@ -621,12 +606,12 @@ void I_StartFrame() void I_SetMouseCapture() { - + } void I_ReleaseMouseCapture() { - + } @@ -1104,7 +1089,7 @@ void ProcessMouseWheelEvent(NSEvent* theEvent) } -const Uint16 BYTES_PER_PIXEL = 4; +const size_t BYTES_PER_PIXEL = 4; } // unnamed namespace @@ -1770,7 +1755,7 @@ CUSTOM_CVAR(Bool, vid_hidpi, true, CVAR_ARCHIVE | CVAR_GLOBALCONFIG) void I_SetMainWindowVisible(bool visible) { [appCtrl setMainWindowVisible:visible]; - + SetNativeMouse(!visible); } @@ -1849,71 +1834,150 @@ bool I_SetCursor(FTexture* cursorpic) extern "C" { -int SDL_Init(Uint32 flags) -{ - ZD_UNUSED(flags); - - return 0; -} - -void SDL_Quit() -{ - if (NULL != appCtrl) + typedef enum { - [NSApp setDelegate:nil]; - [NSApp deactivate]; + SDL_FALSE = 0, + SDL_TRUE = 1 + } SDL_bool; - [appCtrl release]; - appCtrl = NULL; - } -} +typedef int8_t Sint8; +typedef uint8_t Uint8; +typedef int16_t Sint16; +typedef uint16_t Uint16; +typedef int32_t Sint32; +typedef uint32_t Uint32; + + typedef enum + { + SDL_WINDOW_FULLSCREEN = 0x00000001, /**< fullscreen window */ + SDL_WINDOW_OPENGL = 0x00000002, /**< window usable with OpenGL context */ + SDL_WINDOW_SHOWN = 0x00000004, /**< window is visible */ + SDL_WINDOW_HIDDEN = 0x00000008, /**< window is not visible */ + SDL_WINDOW_BORDERLESS = 0x00000010, /**< no window decoration */ + SDL_WINDOW_RESIZABLE = 0x00000020, /**< window can be resized */ + SDL_WINDOW_MINIMIZED = 0x00000040, /**< window is minimized */ + SDL_WINDOW_MAXIMIZED = 0x00000080, /**< window is maximized */ + SDL_WINDOW_INPUT_GRABBED = 0x00000100, /**< window has grabbed input focus */ + SDL_WINDOW_INPUT_FOCUS = 0x00000200, /**< window has input focus */ + SDL_WINDOW_MOUSE_FOCUS = 0x00000400, /**< window has mouse focus */ + SDL_WINDOW_FULLSCREEN_DESKTOP = ( SDL_WINDOW_FULLSCREEN | 0x00001000 ), + SDL_WINDOW_FOREIGN = 0x00000800, /**< window not created by SDL */ + SDL_WINDOW_ALLOW_HIGHDPI = 0x00002000 /**< window should be created in high-DPI mode if supported */ + } SDL_WindowFlags; -const char* SDL_GetError() -{ - static char empty[] = {0}; - return empty; -} + typedef struct SDL_Rect { + Sint16 x, y; + Uint16 w, h; + } SDL_Rect; + + typedef struct SDL_Color { + Uint8 r; + Uint8 g; + Uint8 b; + Uint8 unused; + } SDL_Color; -int SDL_GetDesktopDisplayMode(int displayIndex, SDL_DisplayMode *mode) -{ - // NOTE: Only required fields are assigned - const NSRect displayRect = [[NSScreen mainScreen] frame]; - - mode->w = displayRect.size.width; - mode->h = displayRect.size.height; - - return 0; -} + typedef struct SDL_Palette { + int ncolors; + SDL_Color *colors; + } SDL_Palette; + + typedef struct SDL_PixelFormat { + SDL_Palette *palette; + Uint8 BitsPerPixel; + Uint8 BytesPerPixel; + Uint8 Rloss; + Uint8 Gloss; + Uint8 Bloss; + Uint8 Aloss; + Uint8 Rshift; + Uint8 Gshift; + Uint8 Bshift; + Uint8 Ashift; + Uint32 Rmask; + Uint32 Gmask; + Uint32 Bmask; + Uint32 Amask; + + /** RGB color key information */ + Uint32 colorkey; + /** Alpha value information (per-surface alpha) */ + Uint8 alpha; + } SDL_PixelFormat; + + /** This structure should be treated as read-only, except for 'pixels', + * which, if not NULL, contains the raw pixel data for the surface. + */ + typedef struct SDL_Surface { + Uint32 flags; /**< Read-only */ + SDL_PixelFormat *format; /**< Read-only */ + int w, h; /**< Read-only */ + Uint16 pitch; /**< Read-only */ + void *pixels; /**< Read-write */ + int offset; /**< Private */ + + /** Hardware-specific surface info */ + struct private_hwdata *hwdata; + + /** clipping information */ + SDL_Rect clip_rect; /**< Read-only */ + Uint32 unused1; /**< for binary compatibility */ + + /** Allow recursive locks */ + Uint32 locked; /**< Private */ + + /** info for fast blit mapping to other surfaces */ + struct SDL_BlitMap *map; /**< Private */ + + /** format version, bumped at every change to invalidate blit maps */ + unsigned int format_version; /**< Private */ + + /** Reference count -- used when freeing surface */ + int refcount; /**< Read-mostly */ + } SDL_Surface; + + typedef enum + { + SDL_RENDERER_SOFTWARE = 0x00000001, /**< The renderer is a software fallback */ + SDL_RENDERER_ACCELERATED = 0x00000002, /**< The renderer uses hardware + acceleration */ + SDL_RENDERER_PRESENTVSYNC = 0x00000004, /**< Present is synchronized + with the refresh rate */ + SDL_RENDERER_TARGETTEXTURE = 0x00000008 /**< The renderer supports + rendering to texture */ + } SDL_RendererFlags; + + /** + * \brief Information on the capabilities of a render driver or context. + */ + typedef struct SDL_RendererInfo + { + const char *name; /**< The name of the renderer */ + Uint32 flags; /**< Supported ::SDL_RendererFlags */ + Uint32 num_texture_formats; /**< The number of available texture formats */ + Uint32 texture_formats[16]; /**< The available texture formats */ + int max_texture_width; /**< The maximimum texture width */ + int max_texture_height; /**< The maximimum texture height */ + } SDL_RendererInfo; + + /** + * \brief The access pattern allowed for a texture. + */ + typedef enum + { + SDL_TEXTUREACCESS_STATIC, /**< Changes rarely, not lockable */ + SDL_TEXTUREACCESS_STREAMING, /**< Changes frequently, lockable */ + SDL_TEXTUREACCESS_TARGET /**< Texture can be used as a render target */ + } SDL_TextureAccess; + -static SDL_PixelFormat* GetPixelFormat() -{ - static SDL_PixelFormat result; - - result.palette = NULL; - result.BitsPerPixel = BYTES_PER_PIXEL * 8; - result.BytesPerPixel = BYTES_PER_PIXEL; - result.Rloss = 0; - result.Gloss = 0; - result.Bloss = 0; - result.Aloss = 8; - result.Rshift = 8; - result.Gshift = 16; - result.Bshift = 24; - result.Ashift = 0; - result.Rmask = 0x000000FF; - result.Gmask = 0x0000FF00; - result.Bmask = 0x00FF0000; - result.Amask = 0xFF000000; - - return &result; -} SDL_bool SDL_PixelFormatEnumToMasks(Uint32 format, int* bpp, Uint32* Rmask, Uint32* Gmask, Uint32* Bmask, Uint32* Amask) { - assert(format == SDL_PIXELFORMAT_ABGR8888); + //assert(format == SDL_PIXELFORMAT_ABGR8888); *bpp = 32; *Rmask = 0x000000FF; @@ -2045,42 +2109,13 @@ void SDL_DestroyTexture(SDL_Texture *texture) int SDL_QueryTexture(SDL_Texture *texture, Uint32* format, int* access, int* w, int* h) { - if(format) *format = SDL_PIXELFORMAT_ABGR8888; + if(format) *format = 0; //SDL_PIXELFORMAT_ABGR8888; if(access) *access = SDL_TEXTUREACCESS_STREAMING; if(w) *w = texture->window->w; if(h) *h = texture->window->h; return 0; } -void SDL_GL_SwapBuffers() -{ - [[NSOpenGLContext currentContext] flushBuffer]; -} - -int SDL_GL_SetAttribute(SDL_GLattr attr, int value) -{ - if (SDL_GL_MULTISAMPLESAMPLES == attr) - { - [appCtrl setMultisample:value]; - } - - // Not interested in other attributes - - return 0; -} - - -int SDL_LockSurface(SDL_Surface* surface) -{ - ZD_UNUSED(surface); - - return 0; -} - -void SDL_UnlockSurface(SDL_Surface* surface) -{ - ZD_UNUSED(surface); -} int SDL_LockTexture(SDL_Texture* texture, const SDL_Rect *rect, void** pixels, int *pitch) { @@ -2100,7 +2135,7 @@ void SDL_UnlockTexture(SDL_Texture *texture) int SDL_UpdateWindowSurface(SDL_Window *screen) { assert(NULL != screen); - + if (rbOpts.dirty) { glViewport(rbOpts.shiftX, rbOpts.shiftY, rbOpts.width, rbOpts.height); @@ -2112,7 +2147,7 @@ int SDL_UpdateWindowSurface(SDL_Window *screen) rbOpts.dirty = false; } - + const int width = screen->w; const int height = screen->h; @@ -2138,10 +2173,10 @@ int SDL_UpdateWindowSurface(SDL_Window *screen) glEnd(); glFlush(); - - SDL_GL_SwapBuffers(); - - return 0; + + [[NSOpenGLContext currentContext] flushBuffer]; + + return 0; } int SDL_RenderCopy(SDL_Renderer *renderer, SDL_Texture *texture, const SDL_Rect *srcrect, const SDL_Rect *dstrect) @@ -2348,7 +2383,7 @@ static cycle_t SDLFlipCycles; // CODE -------------------------------------------------------------------- -void ScaleWithAspect (int &w, int &h, int Width, int Height) +void ScaleWithAspect (Uint16 &w, Uint16 &h, Uint16 Width, Uint16 Height) { int resRatio = CheckRatio (Width, Height); int screenRatio; @@ -2503,9 +2538,8 @@ CocoaFrameBuffer::CocoaFrameBuffer (int width, int height, bool fullscreen) FString caption; caption.Format(GAMESIG " %s (%s)", GetVersionString(), GetGitTime()); - Screen = SDL_CreateWindow (caption, - SDL_WINDOWPOS_UNDEFINED_DISPLAY(vid_adapter), SDL_WINDOWPOS_UNDEFINED_DISPLAY(vid_adapter), - width, height, (fullscreen ? SDL_WINDOW_FULLSCREEN_DESKTOP : 0)); + Screen = SDL_CreateWindow (caption, 0, 0, + width, height, (fullscreen ? SDL_WINDOW_FULLSCREEN_DESKTOP : 0)); if (Screen == NULL) return; @@ -2761,15 +2795,15 @@ void CocoaFrameBuffer::ResetSDLRenderer () if (!Renderer) return; - Uint32 fmt; - switch(vid_displaybits) - { - default: fmt = SDL_PIXELFORMAT_ARGB8888; break; - case 30: fmt = SDL_PIXELFORMAT_ARGB2101010; break; - case 24: fmt = SDL_PIXELFORMAT_RGB888; break; - case 16: fmt = SDL_PIXELFORMAT_RGB565; break; - case 15: fmt = SDL_PIXELFORMAT_ARGB1555; break; - } + Uint32 fmt = 0; +// switch(vid_displaybits) +// { +// default: fmt = SDL_PIXELFORMAT_ARGB8888; break; +// case 30: fmt = SDL_PIXELFORMAT_ARGB2101010; break; +// case 24: fmt = SDL_PIXELFORMAT_RGB888; break; +// case 16: fmt = SDL_PIXELFORMAT_RGB565; break; +// case 15: fmt = SDL_PIXELFORMAT_ARGB1555; break; +// } Texture = SDL_CreateTexture (Renderer, fmt, SDL_TEXTUREACCESS_STREAMING, Width, Height); { @@ -3129,6 +3163,18 @@ DarwinVersion GetDarwinVersion() return result; } +void ReleaseApplicationController() +{ + if (NULL != appCtrl) + { + [NSApp setDelegate:nil]; + [NSApp deactivate]; + + [appCtrl release]; + appCtrl = NULL; + } +} + } // unnamed namespace @@ -3170,9 +3216,10 @@ int main(int argc, char** argv) CreateMenu(); + atterm(ReleaseApplicationController); + appCtrl = [ApplicationController new]; [NSApp setDelegate:appCtrl]; - [NSApp run]; [pool release]; From 3c76e5689a668ed96d5e634ae048c90d703e2f02 Mon Sep 17 00:00:00 2001 From: "alexey.lysiuk" Date: Tue, 16 Dec 2014 23:20:14 +0200 Subject: [PATCH 17/46] Fixed path to SDL specific Obj-C++ file --- src/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 0855f1de2..a294352f5 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -601,7 +601,7 @@ elseif( APPLE ) else( OSX_COCOA_BACKEND ) set( SYSTEM_SOURCES_DIR posix sdl ) set( SYSTEM_SOURCES ${PLAT_SDL_SOURCES} ) - set( PLAT_MAC_SOURCES ${PLAT_MAC_SOURCES} cocoa/i_system_cocoa.mm ) + set( PLAT_MAC_SOURCES ${PLAT_MAC_SOURCES} sdl/i_system_cocoa.mm ) set( OTHER_SYSTEM_SOURCES ${PLAT_WIN32_SOURCES} ${PLAT_COCOA_SOURCES} ) endif( OSX_COCOA_BACKEND ) From 84b12d23b54e8f485a9978849068bcf786d4793a Mon Sep 17 00:00:00 2001 From: "alexey.lysiuk" Date: Tue, 16 Dec 2014 23:20:54 +0200 Subject: [PATCH 18/46] Native OS X backend no longer requires SDL --- src/CMakeLists.txt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index a294352f5..e03593e6e 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -198,12 +198,12 @@ else( WIN32 ) add_definitions( -DNO_GTK=1 ) endif( NO_GTK ) - # Non-Windows version also needs SDL - find_package( SDL2 REQUIRED ) + # Non-Windows version also needs SDL except native OS X backend if( NOT APPLE OR NOT OSX_COCOA_BACKEND ) + find_package( SDL2 REQUIRED ) + include_directories( "${SDL2_INCLUDE_DIR}" ) set( ZDOOM_LIBS ${ZDOOM_LIBS} "${SDL2_LIBRARY}" ) endif( NOT APPLE OR NOT OSX_COCOA_BACKEND ) - include_directories( "${SDL2_INCLUDE_DIR}" ) find_path( FPU_CONTROL_DIR fpu_control.h ) if( FPU_CONTROL_DIR ) From 1433bf3f7800f5ce003f6860deba09c104a567d8 Mon Sep 17 00:00:00 2001 From: "alexey.lysiuk" Date: Thu, 18 Dec 2014 11:52:29 +0200 Subject: [PATCH 19/46] Put all non-Windows source code into posix directory and its subdirectories --- src/CMakeLists.txt | 80 +- src/{ => posix}/cocoa/critsec.cpp | 124 +- src/{ => posix}/cocoa/critsec.h | 106 +- .../cocoa/hid/HID_Config_Utilities.c | 0 src/{ => posix}/cocoa/hid/HID_Error_Handler.c | 0 src/{ => posix}/cocoa/hid/HID_Name_Lookup.c | 0 .../cocoa/hid/HID_Queue_Utilities.c | 0 src/{ => posix}/cocoa/hid/HID_Utilities.c | 0 .../cocoa/hid/HID_Utilities_External.h | 0 src/{ => posix}/cocoa/hid/IOHIDDevice_.c | 0 src/{ => posix}/cocoa/hid/IOHIDDevice_.h | 0 src/{ => posix}/cocoa/hid/IOHIDElement_.c | 0 src/{ => posix}/cocoa/hid/IOHIDElement_.h | 0 src/{ => posix}/cocoa/hid/IOHIDLib_.h | 0 src/{ => posix}/cocoa/hid/ImmrHIDUtilAddOn.c | 0 src/{ => posix}/cocoa/hid/ImmrHIDUtilAddOn.h | 0 src/{ => posix}/cocoa/i_backend_cocoa.mm | 0 src/{ => posix}/cocoa/i_joystick.cpp | 0 src/{ => posix}/cocoa/i_osversion.h | 0 src/{ => posix}/cocoa/i_rbopts.h | 0 src/{ => posix}/cocoa/i_timer.cpp | 0 src/{cocoa => posix/osx}/iwadpicker_cocoa.mm | 0 src/{cocoa => posix/osx}/zdoom-info.plist | 0 src/{cocoa => posix/osx}/zdoom.icns | Bin src/posix/readme.md | 6 + src/{ => posix}/sdl/crashcatcher.c | 858 +++++----- src/{ => posix}/sdl/critsec.h | 96 +- src/{ => posix}/sdl/hardware.cpp | 660 ++++---- src/{ => posix}/sdl/i_gui.cpp | 0 src/{ => posix}/sdl/i_input.cpp | 1028 ++++++------ src/{ => posix}/sdl/i_joystick.cpp | 0 src/{ => posix}/sdl/i_main.cpp | 676 ++++---- .../sdl/i_system.mm} | 0 src/{ => posix}/sdl/i_timer.cpp | 0 src/{ => posix}/sdl/sdlvideo.cpp | 1464 ++++++++--------- src/{ => posix}/sdl/sdlvideo.h | 42 +- src/sdl/SDLMain.m | 387 ----- 37 files changed, 2574 insertions(+), 2953 deletions(-) rename src/{ => posix}/cocoa/critsec.cpp (97%) rename src/{ => posix}/cocoa/critsec.h (97%) rename src/{ => posix}/cocoa/hid/HID_Config_Utilities.c (100%) rename src/{ => posix}/cocoa/hid/HID_Error_Handler.c (100%) rename src/{ => posix}/cocoa/hid/HID_Name_Lookup.c (100%) rename src/{ => posix}/cocoa/hid/HID_Queue_Utilities.c (100%) rename src/{ => posix}/cocoa/hid/HID_Utilities.c (100%) rename src/{ => posix}/cocoa/hid/HID_Utilities_External.h (100%) rename src/{ => posix}/cocoa/hid/IOHIDDevice_.c (100%) rename src/{ => posix}/cocoa/hid/IOHIDDevice_.h (100%) rename src/{ => posix}/cocoa/hid/IOHIDElement_.c (100%) rename src/{ => posix}/cocoa/hid/IOHIDElement_.h (100%) rename src/{ => posix}/cocoa/hid/IOHIDLib_.h (100%) rename src/{ => posix}/cocoa/hid/ImmrHIDUtilAddOn.c (100%) rename src/{ => posix}/cocoa/hid/ImmrHIDUtilAddOn.h (100%) rename src/{ => posix}/cocoa/i_backend_cocoa.mm (100%) rename src/{ => posix}/cocoa/i_joystick.cpp (100%) rename src/{ => posix}/cocoa/i_osversion.h (100%) mode change 100755 => 100644 rename src/{ => posix}/cocoa/i_rbopts.h (100%) rename src/{ => posix}/cocoa/i_timer.cpp (100%) rename src/{cocoa => posix/osx}/iwadpicker_cocoa.mm (100%) rename src/{cocoa => posix/osx}/zdoom-info.plist (100%) rename src/{cocoa => posix/osx}/zdoom.icns (100%) create mode 100644 src/posix/readme.md rename src/{ => posix}/sdl/crashcatcher.c (95%) rename src/{ => posix}/sdl/critsec.h (94%) rename src/{ => posix}/sdl/hardware.cpp (96%) rename src/{ => posix}/sdl/i_gui.cpp (100%) rename src/{ => posix}/sdl/i_input.cpp (97%) rename src/{ => posix}/sdl/i_joystick.cpp (100%) rename src/{ => posix}/sdl/i_main.cpp (96%) rename src/{sdl/i_system_cocoa.mm => posix/sdl/i_system.mm} (100%) rename src/{ => posix}/sdl/i_timer.cpp (100%) rename src/{ => posix}/sdl/sdlvideo.cpp (95%) rename src/{ => posix}/sdl/sdlvideo.h (95%) delete mode 100644 src/sdl/SDLMain.m diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index e03593e6e..dd2568f7d 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -554,35 +554,35 @@ set( PLAT_POSIX_SOURCES posix/i_system.cpp posix/st_start.cpp ) set( PLAT_SDL_SOURCES - sdl/crashcatcher.c - sdl/hardware.cpp - sdl/i_gui.cpp - sdl/i_input.cpp - sdl/i_joystick.cpp - sdl/i_main.cpp - sdl/i_timer.cpp - sdl/sdlvideo.cpp ) -set( PLAT_MAC_SOURCES - cocoa/iwadpicker_cocoa.mm ) + posix/sdl/crashcatcher.c + posix/sdl/hardware.cpp + posix/sdl/i_gui.cpp + posix/sdl/i_input.cpp + posix/sdl/i_joystick.cpp + posix/sdl/i_main.cpp + posix/sdl/i_timer.cpp + posix/sdl/sdlvideo.cpp ) +set( PLAT_OSX_SOURCES + posix/osx/iwadpicker_cocoa.mm + posix/osx/zdoom.icns ) set( PLAT_COCOA_SOURCES - cocoa/hid/HID_Config_Utilities.c - cocoa/hid/HID_Error_Handler.c - cocoa/hid/HID_Name_Lookup.c - cocoa/hid/HID_Queue_Utilities.c - cocoa/hid/HID_Utilities.c - cocoa/hid/IOHIDDevice_.c - cocoa/hid/IOHIDElement_.c - cocoa/hid/ImmrHIDUtilAddOn.c - cocoa/critsec.cpp - cocoa/i_backend_cocoa.mm - cocoa/i_joystick.cpp - cocoa/i_timer.cpp - cocoa/zdoom.icns ) + posix/cocoa/hid/HID_Config_Utilities.c + posix/cocoa/hid/HID_Error_Handler.c + posix/cocoa/hid/HID_Name_Lookup.c + posix/cocoa/hid/HID_Queue_Utilities.c + posix/cocoa/hid/HID_Utilities.c + posix/cocoa/hid/IOHIDDevice_.c + posix/cocoa/hid/IOHIDElement_.c + posix/cocoa/hid/ImmrHIDUtilAddOn.c + posix/cocoa/critsec.cpp + posix/cocoa/i_backend_cocoa.mm + posix/cocoa/i_joystick.cpp + posix/cocoa/i_timer.cpp ) if( WIN32 ) set( SYSTEM_SOURCES_DIR win32 ) set( SYSTEM_SOURCES ${PLAT_WIN32_SOURCES} ) - set( OTHER_SYSTEM_SOURCES ${PLAT_POSIX_SOURCES} ${PLAT_SDL_SOURCES} ${PLAT_MAC_SOURCES} ${PLAT_COCOA_SOURCES} ) + set( OTHER_SYSTEM_SOURCES ${PLAT_POSIX_SOURCES} ${PLAT_SDL_SOURCES} ${PLAT_OSX_SOURCES} ${PLAT_COCOA_SOURCES} ) if( ZD_CMAKE_COMPILER_IS_GNUCXX_COMPATIBLE ) # CMake is not set up to compile and link rc files with GCC. :( @@ -595,24 +595,24 @@ if( WIN32 ) endif( ZD_CMAKE_COMPILER_IS_GNUCXX_COMPATIBLE ) elseif( APPLE ) if( OSX_COCOA_BACKEND ) - set( SYSTEM_SOURCES_DIR posix cocoa ) + set( SYSTEM_SOURCES_DIR posix posix/cocoa ) set( SYSTEM_SOURCES ${PLAT_COCOA_SOURCES} ) set( OTHER_SYSTEM_SOURCES ${PLAT_WIN32_SOURCES} ${PLAT_SDL_SOURCES} ) else( OSX_COCOA_BACKEND ) - set( SYSTEM_SOURCES_DIR posix sdl ) + set( SYSTEM_SOURCES_DIR posix posix/sdl ) set( SYSTEM_SOURCES ${PLAT_SDL_SOURCES} ) - set( PLAT_MAC_SOURCES ${PLAT_MAC_SOURCES} sdl/i_system_cocoa.mm ) + set( PLAT_OSX_SOURCES ${PLAT_OSX_SOURCES} posix/sdl/i_system.mm ) set( OTHER_SYSTEM_SOURCES ${PLAT_WIN32_SOURCES} ${PLAT_COCOA_SOURCES} ) endif( OSX_COCOA_BACKEND ) - set( SYSTEM_SOURCES ${SYSTEM_SOURCES} ${PLAT_POSIX_SOURCES} ${PLAT_MAC_SOURCES} "${FMOD_LIBRARY}" ) + set( SYSTEM_SOURCES ${SYSTEM_SOURCES} ${PLAT_POSIX_SOURCES} ${PLAT_OSX_SOURCES} "${FMOD_LIBRARY}" ) - set_source_files_properties( cocoa/zdoom.icns PROPERTIES MACOSX_PACKAGE_LOCATION Resources ) + set_source_files_properties( posix/osx/zdoom.icns PROPERTIES MACOSX_PACKAGE_LOCATION Resources ) set_source_files_properties( "${FMOD_LIBRARY}" PROPERTIES MACOSX_PACKAGE_LOCATION Frameworks ) else( WIN32 ) - set( SYSTEM_SOURCES_DIR posix sdl ) + set( SYSTEM_SOURCES_DIR posix posix/sdl ) set( SYSTEM_SOURCES ${PLAT_POSIX_SOURCES} ${PLAT_SDL_SOURCES} ) - set( OTHER_SYSTEM_SOURCES ${PLAT_WIN32_SOURCES} ${PLAT_MAC_SOURCES} ${PLAT_COCOA_SOURCES} ) + set( OTHER_SYSTEM_SOURCES ${PLAT_WIN32_SOURCES} ${PLAT_OSX_SOURCES} ${PLAT_COCOA_SOURCES} ) endif( WIN32 ) if( NOT ASM_SOURCES ) @@ -672,16 +672,15 @@ if( WIN32 ) set( EXTRA_HEADER_DIRS win32/*.h ) elseif( APPLE ) if( OSX_COCOA_BACKEND ) - set( EXTRA_HEADER_DIRS posix/*.h cocoa/*.h ) + set( EXTRA_HEADER_DIRS posix/*.h posix/cocoa/*.h ) else( OSX_COCOA_BACKEND ) - set( EXTRA_HEADER_DIRS posix/*.h sdl/*.h ) + set( EXTRA_HEADER_DIRS posix/*.h posix/sdl/*.h ) endif( OSX_COCOA_BACKEND ) else( WIN32 ) - set( EXTRA_HEADER_DIRS posix/*.h sdl/*.h ) + set( EXTRA_HEADER_DIRS posix/*.h posix/sdl/*.h ) endif( WIN32 ) file( GLOB HEADER_FILES ${EXTRA_HEADER_DIRS} - cocoa/*.h fragglescript/*.h g_doom/*.h g_heretic/*.h @@ -694,9 +693,10 @@ file( GLOB HEADER_FILES oplsynth/*.h oplsynth/dosbox/*.h posix/*.h + posix/cocoa/*.h + posix/sdl/*.h r_data/*.h resourcefiles/*.h - sdl/*.h sfmt/*.h sound/*.h textures/*.h @@ -1195,7 +1195,7 @@ endif( ZD_CMAKE_COMPILER_IS_GNUCXX_COMPATIBLE ) if( APPLE ) set_target_properties(zdoom PROPERTIES LINK_FLAGS "-framework Carbon -framework Cocoa -framework IOKit -framework OpenGL" - MACOSX_BUNDLE_INFO_PLIST "${CMAKE_CURRENT_SOURCE_DIR}/cocoa/zdoom-info.plist" ) + MACOSX_BUNDLE_INFO_PLIST "${CMAKE_CURRENT_SOURCE_DIR}/posix/osx/zdoom-info.plist" ) # Fix fmod link so that it can be found in the app bundle. find_program( OTOOL otool HINTS "/usr/bin" "${OSX_DEVELOPER_ROOT}/usr/bin" ) @@ -1218,7 +1218,6 @@ source_group("Audio Files\\OPL Synth" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURC source_group("Audio Files\\OPL Synth\\DOSBox" FILES oplsynth/dosbox/opl.cpp oplsynth/dosbox/opl.h) source_group("Audio Files\\Timidity\\Headers" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/timidity/.+\\.h$") source_group("Audio Files\\Timidity\\Source" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/timidity/.+\\.cpp$") -source_group("Cocoa Files" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/cocoa/.+") source_group("Decorate++" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/thingdef/.+") source_group("FraggleScript" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/fragglescript/.+") source_group("Games\\Doom Game" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/g_doom/.+") @@ -1235,7 +1234,10 @@ source_group("Render Data\\Resource Sources" REGULAR_EXPRESSION "^${CMAKE_CURREN source_group("Render Data\\Textures" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/textures/.+") source_group("Render Interface" FILES r_defs.h r_renderer.h r_sky.cpp r_sky.h r_state.h r_utility.cpp r_utility.h) source_group("Resource Files" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/resourcefiles/.+") -source_group("SDL Files" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/sdl/.+") +source_group("POSIX Files" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/posix/.+") +source_group("Cocoa Files" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/posix/cocoa/.+") +source_group("OS X Files" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/posix/osx/.+") +source_group("SDL Files" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/posix/sdl/.+") source_group("SFMT" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/sfmt/.+") source_group("Shared Game" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/g_shared/.+") source_group("Versioning" FILES version.h win32/zdoom.rc) diff --git a/src/cocoa/critsec.cpp b/src/posix/cocoa/critsec.cpp similarity index 97% rename from src/cocoa/critsec.cpp rename to src/posix/cocoa/critsec.cpp index 97bc2251c..cbf112491 100644 --- a/src/cocoa/critsec.cpp +++ b/src/posix/cocoa/critsec.cpp @@ -1,62 +1,62 @@ -/* - ** critsec.cpp - ** - **--------------------------------------------------------------------------- - ** Copyright 2014 Alexey Lysiuk - ** All rights reserved. - ** - ** Redistribution and use in source and binary forms, with or without - ** modification, are permitted provided that the following conditions - ** are met: - ** - ** 1. Redistributions of source code must retain the above copyright - ** notice, this list of conditions and the following disclaimer. - ** 2. Redistributions in binary form must reproduce the above copyright - ** notice, this list of conditions and the following disclaimer in the - ** documentation and/or other materials provided with the distribution. - ** 3. The name of the author may not be used to endorse or promote products - ** derived from this software without specific prior written permission. - ** - ** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - ** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - ** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - ** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - ** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - ** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - ** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - ** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - ** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - ** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - **--------------------------------------------------------------------------- - ** - */ - -#include "critsec.h" - -// TODO: add error handling - -FCriticalSection::FCriticalSection() -{ - pthread_mutexattr_t attributes; - pthread_mutexattr_init(&attributes); - pthread_mutexattr_settype(&attributes, PTHREAD_MUTEX_RECURSIVE); - - pthread_mutex_init(&m_mutex, &attributes); - - pthread_mutexattr_destroy(&attributes); -} - -FCriticalSection::~FCriticalSection() -{ - pthread_mutex_destroy(&m_mutex); -} - -void FCriticalSection::Enter() -{ - pthread_mutex_lock(&m_mutex); -} - -void FCriticalSection::Leave() -{ - pthread_mutex_unlock(&m_mutex); -} +/* + ** critsec.cpp + ** + **--------------------------------------------------------------------------- + ** Copyright 2014 Alexey Lysiuk + ** All rights reserved. + ** + ** Redistribution and use in source and binary forms, with or without + ** modification, are permitted provided that the following conditions + ** are met: + ** + ** 1. Redistributions of source code must retain the above copyright + ** notice, this list of conditions and the following disclaimer. + ** 2. Redistributions in binary form must reproduce the above copyright + ** notice, this list of conditions and the following disclaimer in the + ** documentation and/or other materials provided with the distribution. + ** 3. The name of the author may not be used to endorse or promote products + ** derived from this software without specific prior written permission. + ** + ** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + ** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + ** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + ** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + ** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + ** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + ** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + ** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + ** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + ** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + **--------------------------------------------------------------------------- + ** + */ + +#include "critsec.h" + +// TODO: add error handling + +FCriticalSection::FCriticalSection() +{ + pthread_mutexattr_t attributes; + pthread_mutexattr_init(&attributes); + pthread_mutexattr_settype(&attributes, PTHREAD_MUTEX_RECURSIVE); + + pthread_mutex_init(&m_mutex, &attributes); + + pthread_mutexattr_destroy(&attributes); +} + +FCriticalSection::~FCriticalSection() +{ + pthread_mutex_destroy(&m_mutex); +} + +void FCriticalSection::Enter() +{ + pthread_mutex_lock(&m_mutex); +} + +void FCriticalSection::Leave() +{ + pthread_mutex_unlock(&m_mutex); +} diff --git a/src/cocoa/critsec.h b/src/posix/cocoa/critsec.h similarity index 97% rename from src/cocoa/critsec.h rename to src/posix/cocoa/critsec.h index 20c476ae3..7940dfe32 100644 --- a/src/cocoa/critsec.h +++ b/src/posix/cocoa/critsec.h @@ -1,53 +1,53 @@ -/* - ** critsec.h - ** - **--------------------------------------------------------------------------- - ** Copyright 2014 Alexey Lysiuk - ** All rights reserved. - ** - ** Redistribution and use in source and binary forms, with or without - ** modification, are permitted provided that the following conditions - ** are met: - ** - ** 1. Redistributions of source code must retain the above copyright - ** notice, this list of conditions and the following disclaimer. - ** 2. Redistributions in binary form must reproduce the above copyright - ** notice, this list of conditions and the following disclaimer in the - ** documentation and/or other materials provided with the distribution. - ** 3. The name of the author may not be used to endorse or promote products - ** derived from this software without specific prior written permission. - ** - ** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - ** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - ** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - ** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - ** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - ** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - ** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - ** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - ** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - ** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - **--------------------------------------------------------------------------- - ** - */ - -#ifndef CRITSEC_H -#define CRITSEC_H - -#include - -class FCriticalSection -{ -public: - FCriticalSection(); - ~FCriticalSection(); - - void Enter(); - void Leave(); - -private: - pthread_mutex_t m_mutex; - -}; - -#endif +/* + ** critsec.h + ** + **--------------------------------------------------------------------------- + ** Copyright 2014 Alexey Lysiuk + ** All rights reserved. + ** + ** Redistribution and use in source and binary forms, with or without + ** modification, are permitted provided that the following conditions + ** are met: + ** + ** 1. Redistributions of source code must retain the above copyright + ** notice, this list of conditions and the following disclaimer. + ** 2. Redistributions in binary form must reproduce the above copyright + ** notice, this list of conditions and the following disclaimer in the + ** documentation and/or other materials provided with the distribution. + ** 3. The name of the author may not be used to endorse or promote products + ** derived from this software without specific prior written permission. + ** + ** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + ** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + ** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + ** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + ** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + ** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + ** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + ** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + ** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + ** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + **--------------------------------------------------------------------------- + ** + */ + +#ifndef CRITSEC_H +#define CRITSEC_H + +#include + +class FCriticalSection +{ +public: + FCriticalSection(); + ~FCriticalSection(); + + void Enter(); + void Leave(); + +private: + pthread_mutex_t m_mutex; + +}; + +#endif diff --git a/src/cocoa/hid/HID_Config_Utilities.c b/src/posix/cocoa/hid/HID_Config_Utilities.c similarity index 100% rename from src/cocoa/hid/HID_Config_Utilities.c rename to src/posix/cocoa/hid/HID_Config_Utilities.c diff --git a/src/cocoa/hid/HID_Error_Handler.c b/src/posix/cocoa/hid/HID_Error_Handler.c similarity index 100% rename from src/cocoa/hid/HID_Error_Handler.c rename to src/posix/cocoa/hid/HID_Error_Handler.c diff --git a/src/cocoa/hid/HID_Name_Lookup.c b/src/posix/cocoa/hid/HID_Name_Lookup.c similarity index 100% rename from src/cocoa/hid/HID_Name_Lookup.c rename to src/posix/cocoa/hid/HID_Name_Lookup.c diff --git a/src/cocoa/hid/HID_Queue_Utilities.c b/src/posix/cocoa/hid/HID_Queue_Utilities.c similarity index 100% rename from src/cocoa/hid/HID_Queue_Utilities.c rename to src/posix/cocoa/hid/HID_Queue_Utilities.c diff --git a/src/cocoa/hid/HID_Utilities.c b/src/posix/cocoa/hid/HID_Utilities.c similarity index 100% rename from src/cocoa/hid/HID_Utilities.c rename to src/posix/cocoa/hid/HID_Utilities.c diff --git a/src/cocoa/hid/HID_Utilities_External.h b/src/posix/cocoa/hid/HID_Utilities_External.h similarity index 100% rename from src/cocoa/hid/HID_Utilities_External.h rename to src/posix/cocoa/hid/HID_Utilities_External.h diff --git a/src/cocoa/hid/IOHIDDevice_.c b/src/posix/cocoa/hid/IOHIDDevice_.c similarity index 100% rename from src/cocoa/hid/IOHIDDevice_.c rename to src/posix/cocoa/hid/IOHIDDevice_.c diff --git a/src/cocoa/hid/IOHIDDevice_.h b/src/posix/cocoa/hid/IOHIDDevice_.h similarity index 100% rename from src/cocoa/hid/IOHIDDevice_.h rename to src/posix/cocoa/hid/IOHIDDevice_.h diff --git a/src/cocoa/hid/IOHIDElement_.c b/src/posix/cocoa/hid/IOHIDElement_.c similarity index 100% rename from src/cocoa/hid/IOHIDElement_.c rename to src/posix/cocoa/hid/IOHIDElement_.c diff --git a/src/cocoa/hid/IOHIDElement_.h b/src/posix/cocoa/hid/IOHIDElement_.h similarity index 100% rename from src/cocoa/hid/IOHIDElement_.h rename to src/posix/cocoa/hid/IOHIDElement_.h diff --git a/src/cocoa/hid/IOHIDLib_.h b/src/posix/cocoa/hid/IOHIDLib_.h similarity index 100% rename from src/cocoa/hid/IOHIDLib_.h rename to src/posix/cocoa/hid/IOHIDLib_.h diff --git a/src/cocoa/hid/ImmrHIDUtilAddOn.c b/src/posix/cocoa/hid/ImmrHIDUtilAddOn.c similarity index 100% rename from src/cocoa/hid/ImmrHIDUtilAddOn.c rename to src/posix/cocoa/hid/ImmrHIDUtilAddOn.c diff --git a/src/cocoa/hid/ImmrHIDUtilAddOn.h b/src/posix/cocoa/hid/ImmrHIDUtilAddOn.h similarity index 100% rename from src/cocoa/hid/ImmrHIDUtilAddOn.h rename to src/posix/cocoa/hid/ImmrHIDUtilAddOn.h diff --git a/src/cocoa/i_backend_cocoa.mm b/src/posix/cocoa/i_backend_cocoa.mm similarity index 100% rename from src/cocoa/i_backend_cocoa.mm rename to src/posix/cocoa/i_backend_cocoa.mm diff --git a/src/cocoa/i_joystick.cpp b/src/posix/cocoa/i_joystick.cpp similarity index 100% rename from src/cocoa/i_joystick.cpp rename to src/posix/cocoa/i_joystick.cpp diff --git a/src/cocoa/i_osversion.h b/src/posix/cocoa/i_osversion.h old mode 100755 new mode 100644 similarity index 100% rename from src/cocoa/i_osversion.h rename to src/posix/cocoa/i_osversion.h diff --git a/src/cocoa/i_rbopts.h b/src/posix/cocoa/i_rbopts.h similarity index 100% rename from src/cocoa/i_rbopts.h rename to src/posix/cocoa/i_rbopts.h diff --git a/src/cocoa/i_timer.cpp b/src/posix/cocoa/i_timer.cpp similarity index 100% rename from src/cocoa/i_timer.cpp rename to src/posix/cocoa/i_timer.cpp diff --git a/src/cocoa/iwadpicker_cocoa.mm b/src/posix/osx/iwadpicker_cocoa.mm similarity index 100% rename from src/cocoa/iwadpicker_cocoa.mm rename to src/posix/osx/iwadpicker_cocoa.mm diff --git a/src/cocoa/zdoom-info.plist b/src/posix/osx/zdoom-info.plist similarity index 100% rename from src/cocoa/zdoom-info.plist rename to src/posix/osx/zdoom-info.plist diff --git a/src/cocoa/zdoom.icns b/src/posix/osx/zdoom.icns similarity index 100% rename from src/cocoa/zdoom.icns rename to src/posix/osx/zdoom.icns diff --git a/src/posix/readme.md b/src/posix/readme.md new file mode 100644 index 000000000..ce66dab2c --- /dev/null +++ b/src/posix/readme.md @@ -0,0 +1,6 @@ +This directory contains files required to support POSIX-compatible OSes, like GNU/Linux, OS X or BSD. + +Common files are placed in this directory directly. +SDL backend files are in `sdl` subdirectory. +Native OS X backend files are in `cocoa` subdirectory. +Shared files for both OS X backends are in `osx` subdirectory. diff --git a/src/sdl/crashcatcher.c b/src/posix/sdl/crashcatcher.c similarity index 95% rename from src/sdl/crashcatcher.c rename to src/posix/sdl/crashcatcher.c index a4f68d9a3..4754a369a 100644 --- a/src/sdl/crashcatcher.c +++ b/src/posix/sdl/crashcatcher.c @@ -1,429 +1,429 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#ifdef __linux__ -#include -#ifndef PR_SET_PTRACER -#define PR_SET_PTRACER 0x59616d61 -#endif -#elif defined (__APPLE__) -#include -#endif - - -static const char crash_switch[] = "--cc-handle-crash"; - -static const char fatal_err[] = "\n\n*** Fatal Error ***\n"; -static const char pipe_err[] = "!!! Failed to create pipe\n"; -static const char fork_err[] = "!!! Failed to fork debug process\n"; -static const char exec_err[] = "!!! Failed to exec debug process\n"; - -static char argv0[PATH_MAX]; - -static char altstack[SIGSTKSZ]; - - -static struct { - int signum; - pid_t pid; - int has_siginfo; - siginfo_t siginfo; - char buf[1024]; -} crash_info; - - -static const struct { - const char *name; - int signum; -} signals[] = { - { "Segmentation fault", SIGSEGV }, - { "Illegal instruction", SIGILL }, - { "FPU exception", SIGFPE }, - { "System BUS error", SIGBUS }, - { NULL, 0 } -}; - -static const struct { - int code; - const char *name; -} sigill_codes[] = { -#ifndef __FreeBSD__ - { ILL_ILLOPC, "Illegal opcode" }, - { ILL_ILLOPN, "Illegal operand" }, - { ILL_ILLADR, "Illegal addressing mode" }, - { ILL_ILLTRP, "Illegal trap" }, - { ILL_PRVOPC, "Privileged opcode" }, - { ILL_PRVREG, "Privileged register" }, - { ILL_COPROC, "Coprocessor error" }, - { ILL_BADSTK, "Internal stack error" }, -#endif - { 0, NULL } -}; - -static const struct { - int code; - const char *name; -} sigfpe_codes[] = { - { FPE_INTDIV, "Integer divide by zero" }, - { FPE_INTOVF, "Integer overflow" }, - { FPE_FLTDIV, "Floating point divide by zero" }, - { FPE_FLTOVF, "Floating point overflow" }, - { FPE_FLTUND, "Floating point underflow" }, - { FPE_FLTRES, "Floating point inexact result" }, - { FPE_FLTINV, "Floating point invalid operation" }, - { FPE_FLTSUB, "Subscript out of range" }, - { 0, NULL } -}; - -static const struct { - int code; - const char *name; -} sigsegv_codes[] = { -#ifndef __FreeBSD__ - { SEGV_MAPERR, "Address not mapped to object" }, - { SEGV_ACCERR, "Invalid permissions for mapped object" }, -#endif - { 0, NULL } -}; - -static const struct { - int code; - const char *name; -} sigbus_codes[] = { -#ifndef __FreeBSD__ - { BUS_ADRALN, "Invalid address alignment" }, - { BUS_ADRERR, "Non-existent physical address" }, - { BUS_OBJERR, "Object specific hardware error" }, -#endif - { 0, NULL } -}; - -static int (*cc_user_info)(char*, char*); - - -static void gdb_info(pid_t pid) -{ - char respfile[64]; - char cmd_buf[128]; - FILE *f; - int fd; - - /* Create a temp file to put gdb commands into */ - strcpy(respfile, "gdb-respfile-XXXXXX"); - if((fd=mkstemp(respfile)) >= 0 && (f=fdopen(fd, "w")) != NULL) - { - fprintf(f, "attach %d\n" - "shell echo \"\"\n" - "shell echo \"* Loaded Libraries\"\n" - "info sharedlibrary\n" - "shell echo \"\"\n" - "shell echo \"* Threads\"\n" - "info threads\n" - "shell echo \"\"\n" - "shell echo \"* FPU Status\"\n" - "info float\n" - "shell echo \"\"\n" - "shell echo \"* Registers\"\n" - "info registers\n" - "shell echo \"\"\n" - "shell echo \"* Backtrace\"\n" - "thread apply all backtrace full\n" - "detach\n" - "quit\n", pid); - fclose(f); - - /* Run gdb and print process info. */ - snprintf(cmd_buf, sizeof(cmd_buf), "gdb --quiet --batch --command=%s", respfile); - printf("Executing: %s\n", cmd_buf); - fflush(stdout); - - system(cmd_buf); - /* Clean up */ - remove(respfile); - } - else - { - /* Error creating temp file */ - if(fd >= 0) - { - close(fd); - remove(respfile); - } - printf("!!! Could not create gdb command file\n"); - } - fflush(stdout); -} - -static void sys_info(void) -{ -#ifdef __unix__ - system("echo \"System: `uname -a`\""); - putchar('\n'); - fflush(stdout); -#endif -} - - -static size_t safe_write(int fd, const void *buf, size_t len) -{ - size_t ret = 0; - while(ret < len) - { - ssize_t rem; - if((rem=write(fd, (const char*)buf+ret, len-ret)) == -1) - { - if(errno == EINTR) - continue; - break; - } - ret += rem; - } - return ret; -} - -static void crash_catcher(int signum, siginfo_t *siginfo, void *context) -{ - //ucontext_t *ucontext = (ucontext_t*)context; - pid_t dbg_pid; - int fd[2]; - - /* Make sure the effective uid is the real uid */ - if(getuid() != geteuid()) - { - raise(signum); - return; - } - - safe_write(STDERR_FILENO, fatal_err, sizeof(fatal_err)-1); - if(pipe(fd) == -1) - { - safe_write(STDERR_FILENO, pipe_err, sizeof(pipe_err)-1); - raise(signum); - return; - } - - crash_info.signum = signum; - crash_info.pid = getpid(); - crash_info.has_siginfo = !!siginfo; - if(siginfo) - crash_info.siginfo = *siginfo; - if(cc_user_info) - cc_user_info(crash_info.buf, crash_info.buf+sizeof(crash_info.buf)); - - /* Fork off to start a crash handler */ - switch((dbg_pid=fork())) - { - /* Error */ - case -1: - safe_write(STDERR_FILENO, fork_err, sizeof(fork_err)-1); - raise(signum); - return; - - case 0: - dup2(fd[0], STDIN_FILENO); - close(fd[0]); - close(fd[1]); - - execl(argv0, argv0, crash_switch, NULL); - - safe_write(STDERR_FILENO, exec_err, sizeof(exec_err)-1); - _exit(1); - - default: -#ifdef __linux__ - prctl(PR_SET_PTRACER, dbg_pid, 0, 0, 0); -#endif - safe_write(fd[1], &crash_info, sizeof(crash_info)); - close(fd[0]); - close(fd[1]); - - /* Wait; we'll be killed when gdb is done */ - do { - int status; - if(waitpid(dbg_pid, &status, 0) == dbg_pid && - (WIFEXITED(status) || WIFSIGNALED(status))) - { - /* The debug process died before it could kill us */ - raise(signum); - break; - } - } while(1); - } -} - -static void crash_handler(const char *logfile) -{ - const char *sigdesc = ""; - int i; - - if(fread(&crash_info, sizeof(crash_info), 1, stdin) != 1) - { - fprintf(stderr, "!!! Failed to retrieve info from crashed process\n"); - exit(1); - } - - /* Get the signal description */ - for(i = 0;signals[i].name;++i) - { - if(signals[i].signum == crash_info.signum) - { - sigdesc = signals[i].name; - break; - } - } - - if(crash_info.has_siginfo) - { - switch(crash_info.signum) - { - case SIGSEGV: - for(i = 0;sigsegv_codes[i].name;++i) - { - if(sigsegv_codes[i].code == crash_info.siginfo.si_code) - { - sigdesc = sigsegv_codes[i].name; - break; - } - } - break; - - case SIGFPE: - for(i = 0;sigfpe_codes[i].name;++i) - { - if(sigfpe_codes[i].code == crash_info.siginfo.si_code) - { - sigdesc = sigfpe_codes[i].name; - break; - } - } - break; - - case SIGILL: - for(i = 0;sigill_codes[i].name;++i) - { - if(sigill_codes[i].code == crash_info.siginfo.si_code) - { - sigdesc = sigill_codes[i].name; - break; - } - } - break; - - case SIGBUS: - for(i = 0;sigbus_codes[i].name;++i) - { - if(sigbus_codes[i].code == crash_info.siginfo.si_code) - { - sigdesc = sigbus_codes[i].name; - break; - } - } - break; - } - } - fprintf(stderr, "%s (signal %i)\n", sigdesc, crash_info.signum); - if(crash_info.has_siginfo) - fprintf(stderr, "Address: %p\n", crash_info.siginfo.si_addr); - fputc('\n', stderr); - - if(logfile) - { - /* Create crash log file and redirect shell output to it */ - if(freopen(logfile, "wa", stdout) != stdout) - { - fprintf(stderr, "!!! Could not create %s following signal\n", logfile); - exit(1); - } - fprintf(stderr, "Generating %s and killing process %d, please wait... ", logfile, crash_info.pid); - - printf("*** Fatal Error ***\n" - "%s (signal %i)\n", sigdesc, crash_info.signum); - if(crash_info.has_siginfo) - printf("Address: %p\n", crash_info.siginfo.si_addr); - fputc('\n', stdout); - fflush(stdout); - } - - sys_info(); - - crash_info.buf[sizeof(crash_info.buf)-1] = '\0'; - printf("%s\n", crash_info.buf); - fflush(stdout); - - if(crash_info.pid > 0) - { - gdb_info(crash_info.pid); - kill(crash_info.pid, SIGKILL); - } - - if(logfile) - { - const char *str; - char buf[512]; - - if((str=getenv("KDE_FULL_SESSION")) && strcmp(str, "true") == 0) - snprintf(buf, sizeof(buf), "kdialog --title \"Very Fatal Error\" --textbox \"%s\" 800 600", logfile); - else if((str=getenv("GNOME_DESKTOP_SESSION_ID")) && str[0] != '\0') - snprintf(buf, sizeof(buf), "gxmessage -buttons \"Okay:0\" -geometry 800x600 -title \"Very Fatal Error\" -center -file \"%s\"", logfile); - else - snprintf(buf, sizeof(buf), "xmessage -buttons \"Okay:0\" -center -file \"%s\"", logfile); - - system(buf); - } - exit(0); -} - -int cc_install_handlers(int argc, char **argv, int num_signals, int *signals, const char *logfile, int (*user_info)(char*, char*)) -{ - struct sigaction sa; - stack_t altss; - int retval; - - if(argc == 2 && strcmp(argv[1], crash_switch) == 0) - crash_handler(logfile); - - cc_user_info = user_info; - - if(argv[0][0] == '/') - snprintf(argv0, sizeof(argv0), "%s", argv[0]); - else - { - getcwd(argv0, sizeof(argv0)); - retval = strlen(argv0); - snprintf(argv0+retval, sizeof(argv0)-retval, "/%s", argv[0]); - } - - /* Set an alternate signal stack so SIGSEGVs caused by stack overflows - * still run */ - altss.ss_sp = altstack; - altss.ss_flags = 0; - altss.ss_size = sizeof(altstack); - sigaltstack(&altss, NULL); - - memset(&sa, 0, sizeof(sa)); - sa.sa_sigaction = crash_catcher; - sa.sa_flags = SA_RESETHAND | SA_NODEFER | SA_SIGINFO | SA_ONSTACK; - sigemptyset(&sa.sa_mask); - - retval = 0; - while(num_signals--) - { - if((*signals != SIGSEGV && *signals != SIGILL && *signals != SIGFPE && - *signals != SIGBUS) || sigaction(*signals, &sa, NULL) == -1) - { - *signals = 0; - retval = -1; - } - ++signals; - } - return retval; -} +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef __linux__ +#include +#ifndef PR_SET_PTRACER +#define PR_SET_PTRACER 0x59616d61 +#endif +#elif defined (__APPLE__) +#include +#endif + + +static const char crash_switch[] = "--cc-handle-crash"; + +static const char fatal_err[] = "\n\n*** Fatal Error ***\n"; +static const char pipe_err[] = "!!! Failed to create pipe\n"; +static const char fork_err[] = "!!! Failed to fork debug process\n"; +static const char exec_err[] = "!!! Failed to exec debug process\n"; + +static char argv0[PATH_MAX]; + +static char altstack[SIGSTKSZ]; + + +static struct { + int signum; + pid_t pid; + int has_siginfo; + siginfo_t siginfo; + char buf[1024]; +} crash_info; + + +static const struct { + const char *name; + int signum; +} signals[] = { + { "Segmentation fault", SIGSEGV }, + { "Illegal instruction", SIGILL }, + { "FPU exception", SIGFPE }, + { "System BUS error", SIGBUS }, + { NULL, 0 } +}; + +static const struct { + int code; + const char *name; +} sigill_codes[] = { +#ifndef __FreeBSD__ + { ILL_ILLOPC, "Illegal opcode" }, + { ILL_ILLOPN, "Illegal operand" }, + { ILL_ILLADR, "Illegal addressing mode" }, + { ILL_ILLTRP, "Illegal trap" }, + { ILL_PRVOPC, "Privileged opcode" }, + { ILL_PRVREG, "Privileged register" }, + { ILL_COPROC, "Coprocessor error" }, + { ILL_BADSTK, "Internal stack error" }, +#endif + { 0, NULL } +}; + +static const struct { + int code; + const char *name; +} sigfpe_codes[] = { + { FPE_INTDIV, "Integer divide by zero" }, + { FPE_INTOVF, "Integer overflow" }, + { FPE_FLTDIV, "Floating point divide by zero" }, + { FPE_FLTOVF, "Floating point overflow" }, + { FPE_FLTUND, "Floating point underflow" }, + { FPE_FLTRES, "Floating point inexact result" }, + { FPE_FLTINV, "Floating point invalid operation" }, + { FPE_FLTSUB, "Subscript out of range" }, + { 0, NULL } +}; + +static const struct { + int code; + const char *name; +} sigsegv_codes[] = { +#ifndef __FreeBSD__ + { SEGV_MAPERR, "Address not mapped to object" }, + { SEGV_ACCERR, "Invalid permissions for mapped object" }, +#endif + { 0, NULL } +}; + +static const struct { + int code; + const char *name; +} sigbus_codes[] = { +#ifndef __FreeBSD__ + { BUS_ADRALN, "Invalid address alignment" }, + { BUS_ADRERR, "Non-existent physical address" }, + { BUS_OBJERR, "Object specific hardware error" }, +#endif + { 0, NULL } +}; + +static int (*cc_user_info)(char*, char*); + + +static void gdb_info(pid_t pid) +{ + char respfile[64]; + char cmd_buf[128]; + FILE *f; + int fd; + + /* Create a temp file to put gdb commands into */ + strcpy(respfile, "gdb-respfile-XXXXXX"); + if((fd=mkstemp(respfile)) >= 0 && (f=fdopen(fd, "w")) != NULL) + { + fprintf(f, "attach %d\n" + "shell echo \"\"\n" + "shell echo \"* Loaded Libraries\"\n" + "info sharedlibrary\n" + "shell echo \"\"\n" + "shell echo \"* Threads\"\n" + "info threads\n" + "shell echo \"\"\n" + "shell echo \"* FPU Status\"\n" + "info float\n" + "shell echo \"\"\n" + "shell echo \"* Registers\"\n" + "info registers\n" + "shell echo \"\"\n" + "shell echo \"* Backtrace\"\n" + "thread apply all backtrace full\n" + "detach\n" + "quit\n", pid); + fclose(f); + + /* Run gdb and print process info. */ + snprintf(cmd_buf, sizeof(cmd_buf), "gdb --quiet --batch --command=%s", respfile); + printf("Executing: %s\n", cmd_buf); + fflush(stdout); + + system(cmd_buf); + /* Clean up */ + remove(respfile); + } + else + { + /* Error creating temp file */ + if(fd >= 0) + { + close(fd); + remove(respfile); + } + printf("!!! Could not create gdb command file\n"); + } + fflush(stdout); +} + +static void sys_info(void) +{ +#ifdef __unix__ + system("echo \"System: `uname -a`\""); + putchar('\n'); + fflush(stdout); +#endif +} + + +static size_t safe_write(int fd, const void *buf, size_t len) +{ + size_t ret = 0; + while(ret < len) + { + ssize_t rem; + if((rem=write(fd, (const char*)buf+ret, len-ret)) == -1) + { + if(errno == EINTR) + continue; + break; + } + ret += rem; + } + return ret; +} + +static void crash_catcher(int signum, siginfo_t *siginfo, void *context) +{ + //ucontext_t *ucontext = (ucontext_t*)context; + pid_t dbg_pid; + int fd[2]; + + /* Make sure the effective uid is the real uid */ + if(getuid() != geteuid()) + { + raise(signum); + return; + } + + safe_write(STDERR_FILENO, fatal_err, sizeof(fatal_err)-1); + if(pipe(fd) == -1) + { + safe_write(STDERR_FILENO, pipe_err, sizeof(pipe_err)-1); + raise(signum); + return; + } + + crash_info.signum = signum; + crash_info.pid = getpid(); + crash_info.has_siginfo = !!siginfo; + if(siginfo) + crash_info.siginfo = *siginfo; + if(cc_user_info) + cc_user_info(crash_info.buf, crash_info.buf+sizeof(crash_info.buf)); + + /* Fork off to start a crash handler */ + switch((dbg_pid=fork())) + { + /* Error */ + case -1: + safe_write(STDERR_FILENO, fork_err, sizeof(fork_err)-1); + raise(signum); + return; + + case 0: + dup2(fd[0], STDIN_FILENO); + close(fd[0]); + close(fd[1]); + + execl(argv0, argv0, crash_switch, NULL); + + safe_write(STDERR_FILENO, exec_err, sizeof(exec_err)-1); + _exit(1); + + default: +#ifdef __linux__ + prctl(PR_SET_PTRACER, dbg_pid, 0, 0, 0); +#endif + safe_write(fd[1], &crash_info, sizeof(crash_info)); + close(fd[0]); + close(fd[1]); + + /* Wait; we'll be killed when gdb is done */ + do { + int status; + if(waitpid(dbg_pid, &status, 0) == dbg_pid && + (WIFEXITED(status) || WIFSIGNALED(status))) + { + /* The debug process died before it could kill us */ + raise(signum); + break; + } + } while(1); + } +} + +static void crash_handler(const char *logfile) +{ + const char *sigdesc = ""; + int i; + + if(fread(&crash_info, sizeof(crash_info), 1, stdin) != 1) + { + fprintf(stderr, "!!! Failed to retrieve info from crashed process\n"); + exit(1); + } + + /* Get the signal description */ + for(i = 0;signals[i].name;++i) + { + if(signals[i].signum == crash_info.signum) + { + sigdesc = signals[i].name; + break; + } + } + + if(crash_info.has_siginfo) + { + switch(crash_info.signum) + { + case SIGSEGV: + for(i = 0;sigsegv_codes[i].name;++i) + { + if(sigsegv_codes[i].code == crash_info.siginfo.si_code) + { + sigdesc = sigsegv_codes[i].name; + break; + } + } + break; + + case SIGFPE: + for(i = 0;sigfpe_codes[i].name;++i) + { + if(sigfpe_codes[i].code == crash_info.siginfo.si_code) + { + sigdesc = sigfpe_codes[i].name; + break; + } + } + break; + + case SIGILL: + for(i = 0;sigill_codes[i].name;++i) + { + if(sigill_codes[i].code == crash_info.siginfo.si_code) + { + sigdesc = sigill_codes[i].name; + break; + } + } + break; + + case SIGBUS: + for(i = 0;sigbus_codes[i].name;++i) + { + if(sigbus_codes[i].code == crash_info.siginfo.si_code) + { + sigdesc = sigbus_codes[i].name; + break; + } + } + break; + } + } + fprintf(stderr, "%s (signal %i)\n", sigdesc, crash_info.signum); + if(crash_info.has_siginfo) + fprintf(stderr, "Address: %p\n", crash_info.siginfo.si_addr); + fputc('\n', stderr); + + if(logfile) + { + /* Create crash log file and redirect shell output to it */ + if(freopen(logfile, "wa", stdout) != stdout) + { + fprintf(stderr, "!!! Could not create %s following signal\n", logfile); + exit(1); + } + fprintf(stderr, "Generating %s and killing process %d, please wait... ", logfile, crash_info.pid); + + printf("*** Fatal Error ***\n" + "%s (signal %i)\n", sigdesc, crash_info.signum); + if(crash_info.has_siginfo) + printf("Address: %p\n", crash_info.siginfo.si_addr); + fputc('\n', stdout); + fflush(stdout); + } + + sys_info(); + + crash_info.buf[sizeof(crash_info.buf)-1] = '\0'; + printf("%s\n", crash_info.buf); + fflush(stdout); + + if(crash_info.pid > 0) + { + gdb_info(crash_info.pid); + kill(crash_info.pid, SIGKILL); + } + + if(logfile) + { + const char *str; + char buf[512]; + + if((str=getenv("KDE_FULL_SESSION")) && strcmp(str, "true") == 0) + snprintf(buf, sizeof(buf), "kdialog --title \"Very Fatal Error\" --textbox \"%s\" 800 600", logfile); + else if((str=getenv("GNOME_DESKTOP_SESSION_ID")) && str[0] != '\0') + snprintf(buf, sizeof(buf), "gxmessage -buttons \"Okay:0\" -geometry 800x600 -title \"Very Fatal Error\" -center -file \"%s\"", logfile); + else + snprintf(buf, sizeof(buf), "xmessage -buttons \"Okay:0\" -center -file \"%s\"", logfile); + + system(buf); + } + exit(0); +} + +int cc_install_handlers(int argc, char **argv, int num_signals, int *signals, const char *logfile, int (*user_info)(char*, char*)) +{ + struct sigaction sa; + stack_t altss; + int retval; + + if(argc == 2 && strcmp(argv[1], crash_switch) == 0) + crash_handler(logfile); + + cc_user_info = user_info; + + if(argv[0][0] == '/') + snprintf(argv0, sizeof(argv0), "%s", argv[0]); + else + { + getcwd(argv0, sizeof(argv0)); + retval = strlen(argv0); + snprintf(argv0+retval, sizeof(argv0)-retval, "/%s", argv[0]); + } + + /* Set an alternate signal stack so SIGSEGVs caused by stack overflows + * still run */ + altss.ss_sp = altstack; + altss.ss_flags = 0; + altss.ss_size = sizeof(altstack); + sigaltstack(&altss, NULL); + + memset(&sa, 0, sizeof(sa)); + sa.sa_sigaction = crash_catcher; + sa.sa_flags = SA_RESETHAND | SA_NODEFER | SA_SIGINFO | SA_ONSTACK; + sigemptyset(&sa.sa_mask); + + retval = 0; + while(num_signals--) + { + if((*signals != SIGSEGV && *signals != SIGILL && *signals != SIGFPE && + *signals != SIGBUS) || sigaction(*signals, &sa, NULL) == -1) + { + *signals = 0; + retval = -1; + } + ++signals; + } + return retval; +} diff --git a/src/sdl/critsec.h b/src/posix/sdl/critsec.h similarity index 94% rename from src/sdl/critsec.h rename to src/posix/sdl/critsec.h index daaf30f7d..a3d6210af 100644 --- a/src/sdl/critsec.h +++ b/src/posix/sdl/critsec.h @@ -1,48 +1,48 @@ -// Wraps an SDL mutex object. (A critical section is a Windows synchronization -// object similar to a mutex but optimized for access by threads belonging to -// only one process, hence the class name.) - -#ifndef CRITSEC_H -#define CRITSEC_H - -#include "SDL.h" -#include "SDL_thread.h" -#include "i_system.h" - -class FCriticalSection -{ -public: - FCriticalSection() - { - CritSec = SDL_CreateMutex(); - if (CritSec == NULL) - { - I_FatalError("Failed to create a critical section mutex."); - } - } - ~FCriticalSection() - { - if (CritSec != NULL) - { - SDL_DestroyMutex(CritSec); - } - } - void Enter() - { - if (SDL_mutexP(CritSec) != 0) - { - I_FatalError("Failed entering a critical section."); - } - } - void Leave() - { - if (SDL_mutexV(CritSec) != 0) - { - I_FatalError("Failed to leave a critical section."); - } - } -private: - SDL_mutex *CritSec; -}; - -#endif +// Wraps an SDL mutex object. (A critical section is a Windows synchronization +// object similar to a mutex but optimized for access by threads belonging to +// only one process, hence the class name.) + +#ifndef CRITSEC_H +#define CRITSEC_H + +#include "SDL.h" +#include "SDL_thread.h" +#include "i_system.h" + +class FCriticalSection +{ +public: + FCriticalSection() + { + CritSec = SDL_CreateMutex(); + if (CritSec == NULL) + { + I_FatalError("Failed to create a critical section mutex."); + } + } + ~FCriticalSection() + { + if (CritSec != NULL) + { + SDL_DestroyMutex(CritSec); + } + } + void Enter() + { + if (SDL_mutexP(CritSec) != 0) + { + I_FatalError("Failed entering a critical section."); + } + } + void Leave() + { + if (SDL_mutexV(CritSec) != 0) + { + I_FatalError("Failed to leave a critical section."); + } + } +private: + SDL_mutex *CritSec; +}; + +#endif diff --git a/src/sdl/hardware.cpp b/src/posix/sdl/hardware.cpp similarity index 96% rename from src/sdl/hardware.cpp rename to src/posix/sdl/hardware.cpp index 352fe8558..25e19ff21 100644 --- a/src/sdl/hardware.cpp +++ b/src/posix/sdl/hardware.cpp @@ -1,330 +1,330 @@ -/* -** hardware.cpp -** Somewhat OS-independant interface to the screen, mouse, keyboard, and stick -** -**--------------------------------------------------------------------------- -** Copyright 1998-2006 Randy Heit -** All rights reserved. -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** -** 1. Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** 2. Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in the -** documentation and/or other materials provided with the distribution. -** 3. The name of the author may not be used to endorse or promote products -** derived from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR -** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES -** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. -** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, -** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT -** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF -** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -**--------------------------------------------------------------------------- -** -*/ - -#include -#include -#include - -#include "hardware.h" -#include "i_video.h" -#include "i_system.h" -#include "c_console.h" -#include "c_cvars.h" -#include "c_dispatch.h" -#include "sdlvideo.h" -#include "v_text.h" -#include "doomstat.h" -#include "m_argv.h" -#include "r_renderer.h" -#include "r_swrenderer.h" - -EXTERN_CVAR (Bool, ticker) -EXTERN_CVAR (Bool, fullscreen) -EXTERN_CVAR (Float, vid_winscale) - -IVideo *Video; - -void I_ShutdownGraphics () -{ - if (screen) - { - DFrameBuffer *s = screen; - screen = NULL; - s->ObjectFlags |= OF_YesReallyDelete; - delete s; - } - if (Video) - delete Video, Video = NULL; -} - -void I_InitGraphics () -{ - UCVarValue val; - - val.Bool = !!Args->CheckParm ("-devparm"); - ticker.SetGenericRepDefault (val, CVAR_Bool); - - Video = new SDLVideo (0); - if (Video == NULL) - I_FatalError ("Failed to initialize display"); - - atterm (I_ShutdownGraphics); - - Video->SetWindowedScale (vid_winscale); -} - -static void I_DeleteRenderer() -{ - if (Renderer != NULL) delete Renderer; -} - -void I_CreateRenderer() -{ - if (Renderer == NULL) - { - Renderer = new FSoftwareRenderer; - atterm(I_DeleteRenderer); - } -} - - -/** Remaining code is common to Win32 and Linux **/ - -// VIDEO WRAPPERS --------------------------------------------------------- - -DFrameBuffer *I_SetMode (int &width, int &height, DFrameBuffer *old) -{ - bool fs = false; - switch (Video->GetDisplayType ()) - { - case DISPLAY_WindowOnly: - fs = false; - break; - case DISPLAY_FullscreenOnly: - fs = true; - break; - case DISPLAY_Both: - fs = fullscreen; - break; - } - DFrameBuffer *res = Video->CreateFrameBuffer (width, height, fs, old); - - /* Right now, CreateFrameBuffer cannot return NULL - if (res == NULL) - { - I_FatalError ("Mode %dx%d is unavailable\n", width, height); - } - */ - return res; -} - -bool I_CheckResolution (int width, int height, int bits) -{ - int twidth, theight; - - Video->StartModeIterator (bits, screen ? screen->IsFullscreen() : fullscreen); - while (Video->NextMode (&twidth, &theight, NULL)) - { - if (width == twidth && height == theight) - return true; - } - return false; -} - -void I_ClosestResolution (int *width, int *height, int bits) -{ - int twidth, theight; - int cwidth = 0, cheight = 0; - int iteration; - DWORD closest = 4294967295u; - - for (iteration = 0; iteration < 2; iteration++) - { - Video->StartModeIterator (bits, screen ? screen->IsFullscreen() : fullscreen); - while (Video->NextMode (&twidth, &theight, NULL)) - { - if (twidth == *width && theight == *height) - return; - - if (iteration == 0 && (twidth < *width || theight < *height)) - continue; - - DWORD dist = (twidth - *width) * (twidth - *width) - + (theight - *height) * (theight - *height); - - if (dist < closest) - { - closest = dist; - cwidth = twidth; - cheight = theight; - } - } - if (closest != 4294967295u) - { - *width = cwidth; - *height = cheight; - return; - } - } -} - -//========================================================================== -// -// SetFPSLimit -// -// Initializes an event timer to fire at a rate of /sec. The video -// update will wait for this timer to trigger before updating. -// -// Pass 0 as the limit for unlimited. -// Pass a negative value for the limit to use the value of vid_maxfps. -// -//========================================================================== - -EXTERN_CVAR(Int, vid_maxfps); -EXTERN_CVAR(Bool, cl_capfps); - -#ifndef __APPLE__ -Semaphore FPSLimitSemaphore; - -static void FPSLimitNotify(sigval val) -{ - SEMAPHORE_SIGNAL(FPSLimitSemaphore) -} - -void I_SetFPSLimit(int limit) -{ - static sigevent FPSLimitEvent; - static timer_t FPSLimitTimer; - static bool FPSLimitTimerEnabled = false; - static bool EventSetup = false; - if(!EventSetup) - { - EventSetup = true; - FPSLimitEvent.sigev_notify = SIGEV_THREAD; - FPSLimitEvent.sigev_signo = 0; - FPSLimitEvent.sigev_value.sival_int = 0; - FPSLimitEvent.sigev_notify_function = FPSLimitNotify; - FPSLimitEvent.sigev_notify_attributes = NULL; - - SEMAPHORE_INIT(FPSLimitSemaphore, 0, 0) - } - - if (limit < 0) - { - limit = vid_maxfps; - } - // Kill any leftover timer. - if (FPSLimitTimerEnabled) - { - timer_delete(FPSLimitTimer); - FPSLimitTimerEnabled = false; - } - if (limit == 0) - { // no limit - DPrintf("FPS timer disabled\n"); - } - else - { - FPSLimitTimerEnabled = true; - if(timer_create(CLOCK_REALTIME, &FPSLimitEvent, &FPSLimitTimer) == -1) - Printf("Failed to create FPS limitter event\n"); - itimerspec period = { {0, 0}, {0, 0} }; - period.it_value.tv_nsec = period.it_interval.tv_nsec = 1000000000 / limit; - if(timer_settime(FPSLimitTimer, 0, &period, NULL) == -1) - Printf("Failed to set FPS limitter timer\n"); - DPrintf("FPS timer set to %u ms\n", (unsigned int) period.it_interval.tv_nsec / 1000000); - } -} -#else -// So Apple doesn't support POSIX timers and I can't find a good substitute short of -// having Objective-C Cocoa events or something like that. -void I_SetFPSLimit(int limit) -{ -} -#endif - -CUSTOM_CVAR (Int, vid_maxfps, 200, CVAR_ARCHIVE | CVAR_GLOBALCONFIG) -{ - if (vid_maxfps < TICRATE && vid_maxfps != 0) - { - vid_maxfps = TICRATE; - } - else if (vid_maxfps > 1000) - { - vid_maxfps = 1000; - } - else if (cl_capfps == 0) - { - I_SetFPSLimit(vid_maxfps); - } -} - -extern int NewWidth, NewHeight, NewBits, DisplayBits; - -CUSTOM_CVAR (Bool, fullscreen, false, CVAR_ARCHIVE|CVAR_GLOBALCONFIG) -{ - NewWidth = screen->GetWidth(); - NewHeight = screen->GetHeight(); - NewBits = DisplayBits; - setmodeneeded = true; -} - -CUSTOM_CVAR (Float, vid_winscale, 1.f, CVAR_ARCHIVE|CVAR_GLOBALCONFIG) -{ - if (self < 1.f) - { - self = 1.f; - } - else if (Video) - { - Video->SetWindowedScale (self); - NewWidth = screen->GetWidth(); - NewHeight = screen->GetHeight(); - NewBits = DisplayBits; - setmodeneeded = true; - } -} - -CCMD (vid_listmodes) -{ - static const char *ratios[5] = { "", " - 16:9", " - 16:10", "", " - 5:4" }; - int width, height, bits; - bool letterbox; - - if (Video == NULL) - { - return; - } - for (bits = 1; bits <= 32; bits++) - { - Video->StartModeIterator (bits, screen->IsFullscreen()); - while (Video->NextMode (&width, &height, &letterbox)) - { - bool thisMode = (width == DisplayWidth && height == DisplayHeight && bits == DisplayBits); - int ratio = CheckRatio (width, height); - Printf (thisMode ? PRINT_BOLD : PRINT_HIGH, - "%s%4d x%5d x%3d%s%s\n", - thisMode || !(ratio & 3) ? "" : TEXTCOLOR_GOLD, - width, height, bits, - ratios[ratio], - thisMode || !letterbox ? "" : TEXTCOLOR_BROWN " LB" - ); - } - } -} - -CCMD (vid_currentmode) -{ - Printf ("%dx%dx%d\n", DisplayWidth, DisplayHeight, DisplayBits); -} +/* +** hardware.cpp +** Somewhat OS-independant interface to the screen, mouse, keyboard, and stick +** +**--------------------------------------------------------------------------- +** Copyright 1998-2006 Randy Heit +** All rights reserved. +** +** Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions +** are met: +** +** 1. Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** 2. Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in the +** documentation and/or other materials provided with the distribution. +** 3. The name of the author may not be used to endorse or promote products +** derived from this software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR +** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, +** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +**--------------------------------------------------------------------------- +** +*/ + +#include +#include +#include + +#include "hardware.h" +#include "i_video.h" +#include "i_system.h" +#include "c_console.h" +#include "c_cvars.h" +#include "c_dispatch.h" +#include "sdlvideo.h" +#include "v_text.h" +#include "doomstat.h" +#include "m_argv.h" +#include "r_renderer.h" +#include "r_swrenderer.h" + +EXTERN_CVAR (Bool, ticker) +EXTERN_CVAR (Bool, fullscreen) +EXTERN_CVAR (Float, vid_winscale) + +IVideo *Video; + +void I_ShutdownGraphics () +{ + if (screen) + { + DFrameBuffer *s = screen; + screen = NULL; + s->ObjectFlags |= OF_YesReallyDelete; + delete s; + } + if (Video) + delete Video, Video = NULL; +} + +void I_InitGraphics () +{ + UCVarValue val; + + val.Bool = !!Args->CheckParm ("-devparm"); + ticker.SetGenericRepDefault (val, CVAR_Bool); + + Video = new SDLVideo (0); + if (Video == NULL) + I_FatalError ("Failed to initialize display"); + + atterm (I_ShutdownGraphics); + + Video->SetWindowedScale (vid_winscale); +} + +static void I_DeleteRenderer() +{ + if (Renderer != NULL) delete Renderer; +} + +void I_CreateRenderer() +{ + if (Renderer == NULL) + { + Renderer = new FSoftwareRenderer; + atterm(I_DeleteRenderer); + } +} + + +/** Remaining code is common to Win32 and Linux **/ + +// VIDEO WRAPPERS --------------------------------------------------------- + +DFrameBuffer *I_SetMode (int &width, int &height, DFrameBuffer *old) +{ + bool fs = false; + switch (Video->GetDisplayType ()) + { + case DISPLAY_WindowOnly: + fs = false; + break; + case DISPLAY_FullscreenOnly: + fs = true; + break; + case DISPLAY_Both: + fs = fullscreen; + break; + } + DFrameBuffer *res = Video->CreateFrameBuffer (width, height, fs, old); + + /* Right now, CreateFrameBuffer cannot return NULL + if (res == NULL) + { + I_FatalError ("Mode %dx%d is unavailable\n", width, height); + } + */ + return res; +} + +bool I_CheckResolution (int width, int height, int bits) +{ + int twidth, theight; + + Video->StartModeIterator (bits, screen ? screen->IsFullscreen() : fullscreen); + while (Video->NextMode (&twidth, &theight, NULL)) + { + if (width == twidth && height == theight) + return true; + } + return false; +} + +void I_ClosestResolution (int *width, int *height, int bits) +{ + int twidth, theight; + int cwidth = 0, cheight = 0; + int iteration; + DWORD closest = 4294967295u; + + for (iteration = 0; iteration < 2; iteration++) + { + Video->StartModeIterator (bits, screen ? screen->IsFullscreen() : fullscreen); + while (Video->NextMode (&twidth, &theight, NULL)) + { + if (twidth == *width && theight == *height) + return; + + if (iteration == 0 && (twidth < *width || theight < *height)) + continue; + + DWORD dist = (twidth - *width) * (twidth - *width) + + (theight - *height) * (theight - *height); + + if (dist < closest) + { + closest = dist; + cwidth = twidth; + cheight = theight; + } + } + if (closest != 4294967295u) + { + *width = cwidth; + *height = cheight; + return; + } + } +} + +//========================================================================== +// +// SetFPSLimit +// +// Initializes an event timer to fire at a rate of /sec. The video +// update will wait for this timer to trigger before updating. +// +// Pass 0 as the limit for unlimited. +// Pass a negative value for the limit to use the value of vid_maxfps. +// +//========================================================================== + +EXTERN_CVAR(Int, vid_maxfps); +EXTERN_CVAR(Bool, cl_capfps); + +#ifndef __APPLE__ +Semaphore FPSLimitSemaphore; + +static void FPSLimitNotify(sigval val) +{ + SEMAPHORE_SIGNAL(FPSLimitSemaphore) +} + +void I_SetFPSLimit(int limit) +{ + static sigevent FPSLimitEvent; + static timer_t FPSLimitTimer; + static bool FPSLimitTimerEnabled = false; + static bool EventSetup = false; + if(!EventSetup) + { + EventSetup = true; + FPSLimitEvent.sigev_notify = SIGEV_THREAD; + FPSLimitEvent.sigev_signo = 0; + FPSLimitEvent.sigev_value.sival_int = 0; + FPSLimitEvent.sigev_notify_function = FPSLimitNotify; + FPSLimitEvent.sigev_notify_attributes = NULL; + + SEMAPHORE_INIT(FPSLimitSemaphore, 0, 0) + } + + if (limit < 0) + { + limit = vid_maxfps; + } + // Kill any leftover timer. + if (FPSLimitTimerEnabled) + { + timer_delete(FPSLimitTimer); + FPSLimitTimerEnabled = false; + } + if (limit == 0) + { // no limit + DPrintf("FPS timer disabled\n"); + } + else + { + FPSLimitTimerEnabled = true; + if(timer_create(CLOCK_REALTIME, &FPSLimitEvent, &FPSLimitTimer) == -1) + Printf("Failed to create FPS limitter event\n"); + itimerspec period = { {0, 0}, {0, 0} }; + period.it_value.tv_nsec = period.it_interval.tv_nsec = 1000000000 / limit; + if(timer_settime(FPSLimitTimer, 0, &period, NULL) == -1) + Printf("Failed to set FPS limitter timer\n"); + DPrintf("FPS timer set to %u ms\n", (unsigned int) period.it_interval.tv_nsec / 1000000); + } +} +#else +// So Apple doesn't support POSIX timers and I can't find a good substitute short of +// having Objective-C Cocoa events or something like that. +void I_SetFPSLimit(int limit) +{ +} +#endif + +CUSTOM_CVAR (Int, vid_maxfps, 200, CVAR_ARCHIVE | CVAR_GLOBALCONFIG) +{ + if (vid_maxfps < TICRATE && vid_maxfps != 0) + { + vid_maxfps = TICRATE; + } + else if (vid_maxfps > 1000) + { + vid_maxfps = 1000; + } + else if (cl_capfps == 0) + { + I_SetFPSLimit(vid_maxfps); + } +} + +extern int NewWidth, NewHeight, NewBits, DisplayBits; + +CUSTOM_CVAR (Bool, fullscreen, false, CVAR_ARCHIVE|CVAR_GLOBALCONFIG) +{ + NewWidth = screen->GetWidth(); + NewHeight = screen->GetHeight(); + NewBits = DisplayBits; + setmodeneeded = true; +} + +CUSTOM_CVAR (Float, vid_winscale, 1.f, CVAR_ARCHIVE|CVAR_GLOBALCONFIG) +{ + if (self < 1.f) + { + self = 1.f; + } + else if (Video) + { + Video->SetWindowedScale (self); + NewWidth = screen->GetWidth(); + NewHeight = screen->GetHeight(); + NewBits = DisplayBits; + setmodeneeded = true; + } +} + +CCMD (vid_listmodes) +{ + static const char *ratios[5] = { "", " - 16:9", " - 16:10", "", " - 5:4" }; + int width, height, bits; + bool letterbox; + + if (Video == NULL) + { + return; + } + for (bits = 1; bits <= 32; bits++) + { + Video->StartModeIterator (bits, screen->IsFullscreen()); + while (Video->NextMode (&width, &height, &letterbox)) + { + bool thisMode = (width == DisplayWidth && height == DisplayHeight && bits == DisplayBits); + int ratio = CheckRatio (width, height); + Printf (thisMode ? PRINT_BOLD : PRINT_HIGH, + "%s%4d x%5d x%3d%s%s\n", + thisMode || !(ratio & 3) ? "" : TEXTCOLOR_GOLD, + width, height, bits, + ratios[ratio], + thisMode || !letterbox ? "" : TEXTCOLOR_BROWN " LB" + ); + } + } +} + +CCMD (vid_currentmode) +{ + Printf ("%dx%dx%d\n", DisplayWidth, DisplayHeight, DisplayBits); +} diff --git a/src/sdl/i_gui.cpp b/src/posix/sdl/i_gui.cpp similarity index 100% rename from src/sdl/i_gui.cpp rename to src/posix/sdl/i_gui.cpp diff --git a/src/sdl/i_input.cpp b/src/posix/sdl/i_input.cpp similarity index 97% rename from src/sdl/i_input.cpp rename to src/posix/sdl/i_input.cpp index 210cf2e2c..6fff2d2a9 100644 --- a/src/sdl/i_input.cpp +++ b/src/posix/sdl/i_input.cpp @@ -1,514 +1,514 @@ -#include -#include -#include "doomtype.h" -#include "c_dispatch.h" -#include "doomdef.h" -#include "doomstat.h" -#include "m_argv.h" -#include "i_input.h" -#include "v_video.h" - -#include "d_main.h" -#include "d_event.h" -#include "d_gui.h" -#include "c_console.h" -#include "c_cvars.h" -#include "i_system.h" -#include "dikeys.h" -#include "templates.h" -#include "s_sound.h" - -void ScaleWithAspect (int &w, int &h, int Width, int Height); - -static void I_CheckGUICapture (); -static void I_CheckNativeMouse (); - -bool GUICapture; -static bool NativeMouse = true; - -extern int paused; - -CVAR (Bool, use_mouse, true, CVAR_ARCHIVE|CVAR_GLOBALCONFIG) -CVAR (Bool, m_noprescale, false, CVAR_ARCHIVE|CVAR_GLOBALCONFIG) -CVAR (Bool, m_filter, false, CVAR_ARCHIVE|CVAR_GLOBALCONFIG) - -EXTERN_CVAR (Bool, fullscreen) - -extern int WaitingForKey, chatmodeon; -extern constate_e ConsoleState; - -static bool DownState[SDL_NUM_SCANCODES]; - -static const SDL_Keycode DIKToKeySym[256] = -{ - 0, SDLK_ESCAPE, SDLK_1, SDLK_2, SDLK_3, SDLK_4, SDLK_5, SDLK_6, - SDLK_7, SDLK_8, SDLK_9, SDLK_0,SDLK_MINUS, SDLK_EQUALS, SDLK_BACKSPACE, SDLK_TAB, - SDLK_q, SDLK_w, SDLK_e, SDLK_r, SDLK_t, SDLK_y, SDLK_u, SDLK_i, - SDLK_o, SDLK_p, SDLK_LEFTBRACKET, SDLK_RIGHTBRACKET, SDLK_RETURN, SDLK_LCTRL, SDLK_a, SDLK_s, - SDLK_d, SDLK_f, SDLK_g, SDLK_h, SDLK_j, SDLK_k, SDLK_l, SDLK_SEMICOLON, - SDLK_QUOTE, SDLK_BACKQUOTE, SDLK_LSHIFT, SDLK_BACKSLASH, SDLK_z, SDLK_x, SDLK_c, SDLK_v, - SDLK_b, SDLK_n, SDLK_m, SDLK_COMMA, SDLK_PERIOD, SDLK_SLASH, SDLK_RSHIFT, SDLK_KP_MULTIPLY, - SDLK_LALT, SDLK_SPACE, SDLK_CAPSLOCK, SDLK_F1, SDLK_F2, SDLK_F3, SDLK_F4, SDLK_F5, - SDLK_F6, SDLK_F7, SDLK_F8, SDLK_F9, SDLK_F10, SDLK_NUMLOCKCLEAR, SDLK_SCROLLLOCK, SDLK_KP_7, - SDLK_KP_8, SDLK_KP_9, SDLK_KP_MINUS, SDLK_KP_4, SDLK_KP_5, SDLK_KP_6, SDLK_KP_PLUS, SDLK_KP_1, - SDLK_KP_2, SDLK_KP_3, SDLK_KP_0, SDLK_KP_PERIOD, 0, 0, 0, SDLK_F11, - SDLK_F12, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, SDLK_F13, SDLK_F14, SDLK_F15, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, SDLK_KP_EQUALS, 0, 0, - 0, SDLK_AT, SDLK_COLON, 0, 0, 0, 0, 0, - 0, 0, 0, 0, SDLK_KP_ENTER, SDLK_RCTRL, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, SDLK_KP_COMMA, 0, SDLK_KP_DIVIDE, 0, SDLK_SYSREQ, - SDLK_RALT, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, SDLK_PAUSE, 0, SDLK_HOME, - SDLK_UP, SDLK_PAGEUP, 0, SDLK_LEFT, 0, SDLK_RIGHT, 0, SDLK_END, - SDLK_DOWN, SDLK_PAGEDOWN, SDLK_INSERT, SDLK_DELETE, 0, 0, 0, 0, - 0, 0, 0, SDLK_LGUI, SDLK_RGUI, SDLK_MENU, SDLK_POWER, SDLK_SLEEP, - 0, 0, 0, 0, 0, SDLK_AC_SEARCH, SDLK_AC_BOOKMARKS, SDLK_AC_REFRESH, - SDLK_AC_STOP, SDLK_AC_FORWARD, SDLK_AC_BACK, SDLK_COMPUTER, SDLK_MAIL, SDLK_MEDIASELECT, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0 -}; - -static const SDL_Scancode DIKToKeyScan[256] = -{ - SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_ESCAPE, SDL_SCANCODE_1, SDL_SCANCODE_2, SDL_SCANCODE_3, SDL_SCANCODE_4, SDL_SCANCODE_5, SDL_SCANCODE_6, - SDL_SCANCODE_7, SDL_SCANCODE_8, SDL_SCANCODE_9, SDL_SCANCODE_0 ,SDL_SCANCODE_MINUS, SDL_SCANCODE_EQUALS, SDL_SCANCODE_BACKSPACE, SDL_SCANCODE_TAB, - SDL_SCANCODE_Q, SDL_SCANCODE_W, SDL_SCANCODE_E, SDL_SCANCODE_R, SDL_SCANCODE_T, SDL_SCANCODE_Y, SDL_SCANCODE_U, SDL_SCANCODE_I, - SDL_SCANCODE_O, SDL_SCANCODE_P, SDL_SCANCODE_LEFTBRACKET, SDL_SCANCODE_RIGHTBRACKET, SDL_SCANCODE_RETURN, SDL_SCANCODE_LCTRL, SDL_SCANCODE_A, SDL_SCANCODE_S, - SDL_SCANCODE_D, SDL_SCANCODE_F, SDL_SCANCODE_G, SDL_SCANCODE_H, SDL_SCANCODE_J, SDL_SCANCODE_K, SDL_SCANCODE_L, SDL_SCANCODE_SEMICOLON, - SDL_SCANCODE_APOSTROPHE, SDL_SCANCODE_GRAVE, SDL_SCANCODE_LSHIFT, SDL_SCANCODE_BACKSLASH, SDL_SCANCODE_Z, SDL_SCANCODE_X, SDL_SCANCODE_C, SDL_SCANCODE_V, - SDL_SCANCODE_B, SDL_SCANCODE_N, SDL_SCANCODE_M, SDL_SCANCODE_COMMA, SDL_SCANCODE_PERIOD, SDL_SCANCODE_SLASH, SDL_SCANCODE_RSHIFT, SDL_SCANCODE_KP_MULTIPLY, - SDL_SCANCODE_LALT, SDL_SCANCODE_SPACE, SDL_SCANCODE_CAPSLOCK, SDL_SCANCODE_F1, SDL_SCANCODE_F2, SDL_SCANCODE_F3, SDL_SCANCODE_F4, SDL_SCANCODE_F5, - SDL_SCANCODE_F6, SDL_SCANCODE_F7, SDL_SCANCODE_F8, SDL_SCANCODE_F9, SDL_SCANCODE_F10, SDL_SCANCODE_NUMLOCKCLEAR, SDL_SCANCODE_SCROLLLOCK, SDL_SCANCODE_KP_7, - SDL_SCANCODE_KP_8, SDL_SCANCODE_KP_9, SDL_SCANCODE_KP_MINUS, SDL_SCANCODE_KP_4, SDL_SCANCODE_KP_5, SDL_SCANCODE_KP_6, SDL_SCANCODE_KP_PLUS, SDL_SCANCODE_KP_1, - SDL_SCANCODE_KP_2, SDL_SCANCODE_KP_3, SDL_SCANCODE_KP_0, SDL_SCANCODE_KP_PERIOD, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_F11, - SDL_SCANCODE_F12, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, - SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_F13, SDL_SCANCODE_F14, SDL_SCANCODE_F15, SDL_SCANCODE_UNKNOWN, - SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, - SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, - SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, - SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, - SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_KP_EQUALS, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, - SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, - SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_KP_ENTER, SDL_SCANCODE_RCTRL, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, - SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, - SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, - SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_KP_COMMA, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_KP_DIVIDE, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_SYSREQ, - SDL_SCANCODE_RALT, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, - SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_PAUSE, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_HOME, - SDL_SCANCODE_UP, SDL_SCANCODE_PAGEUP, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_LEFT, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_RIGHT, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_END, - SDL_SCANCODE_DOWN, SDL_SCANCODE_PAGEDOWN, SDL_SCANCODE_INSERT, SDL_SCANCODE_DELETE, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, - SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_LGUI, SDL_SCANCODE_RGUI, SDL_SCANCODE_MENU, SDL_SCANCODE_POWER, SDL_SCANCODE_SLEEP, - SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_AC_SEARCH, SDL_SCANCODE_AC_BOOKMARKS, SDL_SCANCODE_AC_REFRESH, - SDL_SCANCODE_AC_STOP, SDL_SCANCODE_AC_FORWARD, SDL_SCANCODE_AC_BACK, SDL_SCANCODE_COMPUTER, SDL_SCANCODE_MAIL, SDL_SCANCODE_MEDIASELECT, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, - SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, - SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN -}; - -static TMap InitKeySymMap () -{ - TMap KeySymToDIK; - - for (int i = 0; i < 256; ++i) - { - KeySymToDIK[DIKToKeySym[i]] = i; - } - KeySymToDIK[0] = 0; - KeySymToDIK[SDLK_RSHIFT] = DIK_LSHIFT; - KeySymToDIK[SDLK_RCTRL] = DIK_LCONTROL; - KeySymToDIK[SDLK_RALT] = DIK_LMENU; - // Depending on your Linux flavor, you may get SDLK_PRINT or SDLK_SYSREQ - KeySymToDIK[SDLK_PRINTSCREEN] = DIK_SYSRQ; - - return KeySymToDIK; -} -static const TMap KeySymToDIK(InitKeySymMap()); - -static TMap InitKeyScanMap () -{ - TMap KeyScanToDIK; - - for (int i = 0; i < 256; ++i) - { - KeyScanToDIK[DIKToKeyScan[i]] = i; - } - - return KeyScanToDIK; -} -static const TMap KeyScanToDIK(InitKeyScanMap()); - -static void I_CheckGUICapture () -{ - bool wantCapt; - - if (menuactive == MENU_Off) - { - wantCapt = ConsoleState == c_down || ConsoleState == c_falling || chatmodeon; - } - else - { - wantCapt = (menuactive == MENU_On || menuactive == MENU_OnNoPause); - } - - if (wantCapt != GUICapture) - { - GUICapture = wantCapt; - if (wantCapt) - { - memset (DownState, 0, sizeof(DownState)); - } - } -} - -void I_SetMouseCapture() -{ - // Clear out any mouse movement. - SDL_GetRelativeMouseState (NULL, NULL); - SDL_SetRelativeMouseMode (SDL_TRUE); -} - -void I_ReleaseMouseCapture() -{ - SDL_SetRelativeMouseMode (SDL_FALSE); -} - -static void PostMouseMove (int x, int y) -{ - static int lastx = 0, lasty = 0; - event_t ev = { 0,0,0,0,0,0,0 }; - - if (m_filter) - { - ev.x = (x + lastx) / 2; - ev.y = (y + lasty) / 2; - } - else - { - ev.x = x; - ev.y = y; - } - lastx = x; - lasty = y; - if (ev.x | ev.y) - { - ev.type = EV_Mouse; - D_PostEvent (&ev); - } -} - -static void MouseRead () -{ - int x, y; - - if (NativeMouse) - { - return; - } - - SDL_GetRelativeMouseState (&x, &y); - if (!m_noprescale) - { - x *= 3; - y *= 2; - } - if (x | y) - { - PostMouseMove (x, -y); - } -} - -CUSTOM_CVAR(Int, mouse_capturemode, 1, CVAR_GLOBALCONFIG|CVAR_ARCHIVE) -{ - if (self < 0) self = 0; - else if (self > 2) self = 2; -} - -static bool inGame() -{ - switch (mouse_capturemode) - { - default: - case 0: - return gamestate == GS_LEVEL; - case 1: - return gamestate == GS_LEVEL || gamestate == GS_INTERMISSION || gamestate == GS_FINALE; - case 2: - return true; - } -} - -static void I_CheckNativeMouse () -{ - bool focus = SDL_GetKeyboardFocus() != NULL; - bool fs = screen->IsFullscreen(); - - bool wantNative = !focus || (!use_mouse || GUICapture || paused || demoplayback || !inGame()); - - if (wantNative != NativeMouse) - { - NativeMouse = wantNative; - SDL_ShowCursor (wantNative); - if (wantNative) - I_ReleaseMouseCapture (); - else - I_SetMouseCapture (); - } -} - -void MessagePump (const SDL_Event &sev) -{ - static int lastx = 0, lasty = 0; - int x, y; - event_t event = { 0,0,0,0,0,0,0 }; - - switch (sev.type) - { - case SDL_QUIT: - exit (0); - - case SDL_WINDOWEVENT: - switch (sev.window.event) - { - case SDL_WINDOWEVENT_FOCUS_GAINED: - case SDL_WINDOWEVENT_FOCUS_LOST: - S_SetSoundPaused(sev.window.event == SDL_WINDOWEVENT_FOCUS_GAINED); - break; - } - break; - - case SDL_MOUSEBUTTONDOWN: - case SDL_MOUSEBUTTONUP: - case SDL_MOUSEMOTION: - if (!GUICapture || sev.button.button == 4 || sev.button.button == 5) - { - if(sev.type != SDL_MOUSEMOTION) - { - event.type = sev.type == SDL_MOUSEBUTTONDOWN ? EV_KeyDown : EV_KeyUp; - /* These button mappings work with my Gentoo system using the - * evdev driver and a Logitech MX510 mouse. Whether or not they - * carry over to other Linux systems, I have no idea, but I sure - * hope so. (Though buttons 11 and 12 are kind of useless, since - * they also trigger buttons 4 and 5.) - */ - switch (sev.button.button) - { - case SDL_BUTTON_LEFT: event.data1 = KEY_MOUSE1; break; - case SDL_BUTTON_MIDDLE: event.data1 = KEY_MOUSE3; break; - case SDL_BUTTON_RIGHT: event.data1 = KEY_MOUSE2; break; - case 8: event.data1 = KEY_MOUSE4; break; // For whatever reason my side mouse buttons are here. - case 9: event.data1 = KEY_MOUSE5; break; - case SDL_BUTTON_X1: event.data1 = KEY_MOUSE6; break; // And these don't exist - case SDL_BUTTON_X2: event.data1 = KEY_MOUSE7; break; - case 6: event.data1 = KEY_MOUSE8; break; - default: printf("SDL mouse button %s %d\n", - sev.type == SDL_MOUSEBUTTONDOWN ? "down" : "up", sev.button.button); break; - } - if (event.data1 != 0) - { - D_PostEvent(&event); - } - } - } - else if (sev.type == SDL_MOUSEMOTION || (sev.button.button >= 1 && sev.button.button <= 3)) - { - int x, y; - SDL_GetMouseState (&x, &y); - - // Detect if we're doing scaling in the Window and adjust the mouse - // coordinates accordingly. This could be more efficent, but I - // don't think performance is an issue in the menus. - SDL_Window *focus; - if (screen->IsFullscreen() && (focus = SDL_GetMouseFocus ())) - { - int w, h; - SDL_GetWindowSize (focus, &w, &h); - int realw = w, realh = h; - ScaleWithAspect (realw, realh, SCREENWIDTH, SCREENHEIGHT); - if (realw != SCREENWIDTH || realh != SCREENHEIGHT) - { - double xratio = (double)SCREENWIDTH/realw; - double yratio = (double)SCREENHEIGHT/realh; - if (realw < w) - { - x = (x - (w - realw)/2)*xratio; - y *= yratio; - } - else - { - y = (y - (h - realh)/2)*yratio; - x *= xratio; - } - } - } - - event.data1 = x; - event.data2 = y; - event.type = EV_GUI_Event; - if(sev.type == SDL_MOUSEMOTION) - event.subtype = EV_GUI_MouseMove; - else - { - event.subtype = sev.type == SDL_MOUSEBUTTONDOWN ? EV_GUI_LButtonDown : EV_GUI_LButtonUp; - event.subtype += (sev.button.button - 1) * 3; - } - D_PostEvent(&event); - } - break; - - case SDL_MOUSEWHEEL: - if (GUICapture) - { - event.type = EV_GUI_Event; - event.subtype = sev.wheel.y > 0 ? EV_GUI_WheelUp : EV_GUI_WheelDown; - D_PostEvent (&event); - } - else - { - event.type = EV_KeyDown; - event.data1 = sev.wheel.y > 0 ? KEY_MWHEELUP : KEY_MWHEELDOWN; - D_PostEvent (&event); - event.type = EV_KeyUp; - D_PostEvent (&event); - } - break; - - case SDL_KEYDOWN: - case SDL_KEYUP: - if (!GUICapture) - { - event.type = sev.type == SDL_KEYDOWN ? EV_KeyDown : EV_KeyUp; - - // Try to look up our key mapped key for conversion to DirectInput. - // If that fails, then we'll do a lookup against the scan code, - // which may not return the right key, but at least the key should - // work in the game. - if (const BYTE *dik = KeySymToDIK.CheckKey (sev.key.keysym.sym)) - event.data1 = *dik; - else if (const BYTE *dik = KeyScanToDIK.CheckKey (sev.key.keysym.scancode)) - event.data1 = *dik; - - if (event.data1) - { - if (sev.key.keysym.sym < 256) - { - event.data2 = sev.key.keysym.sym; - } - D_PostEvent (&event); - } - } - else - { - event.type = EV_GUI_Event; - event.subtype = sev.type == SDL_KEYDOWN ? EV_GUI_KeyDown : EV_GUI_KeyUp; - event.data3 = ((sev.key.keysym.mod & KMOD_SHIFT) ? GKM_SHIFT : 0) | - ((sev.key.keysym.mod & KMOD_CTRL) ? GKM_CTRL : 0) | - ((sev.key.keysym.mod & KMOD_ALT) ? GKM_ALT : 0); - - if (event.subtype == EV_GUI_KeyDown) - { - if (DownState[sev.key.keysym.scancode]) - { - event.subtype = EV_GUI_KeyRepeat; - } - DownState[sev.key.keysym.scancode] = 1; - } - else - { - DownState[sev.key.keysym.scancode] = 0; - } - - switch (sev.key.keysym.sym) - { - case SDLK_KP_ENTER: event.data1 = GK_RETURN; break; - case SDLK_PAGEUP: event.data1 = GK_PGUP; break; - case SDLK_PAGEDOWN: event.data1 = GK_PGDN; break; - case SDLK_END: event.data1 = GK_END; break; - case SDLK_HOME: event.data1 = GK_HOME; break; - case SDLK_LEFT: event.data1 = GK_LEFT; break; - case SDLK_RIGHT: event.data1 = GK_RIGHT; break; - case SDLK_UP: event.data1 = GK_UP; break; - case SDLK_DOWN: event.data1 = GK_DOWN; break; - case SDLK_DELETE: event.data1 = GK_DEL; break; - case SDLK_ESCAPE: event.data1 = GK_ESCAPE; break; - case SDLK_F1: event.data1 = GK_F1; break; - case SDLK_F2: event.data1 = GK_F2; break; - case SDLK_F3: event.data1 = GK_F3; break; - case SDLK_F4: event.data1 = GK_F4; break; - case SDLK_F5: event.data1 = GK_F5; break; - case SDLK_F6: event.data1 = GK_F6; break; - case SDLK_F7: event.data1 = GK_F7; break; - case SDLK_F8: event.data1 = GK_F8; break; - case SDLK_F9: event.data1 = GK_F9; break; - case SDLK_F10: event.data1 = GK_F10; break; - case SDLK_F11: event.data1 = GK_F11; break; - case SDLK_F12: event.data1 = GK_F12; break; - default: - if (sev.key.keysym.sym < 256) - { - event.data1 = sev.key.keysym.sym; - } - break; - } - if (event.data1 < 128) - { - event.data1 = toupper(event.data1); - D_PostEvent (&event); - } - } - break; - - case SDL_TEXTINPUT: - if (GUICapture) - { - event.type = EV_GUI_Event; - event.subtype = EV_GUI_Char; - event.data1 = sev.text.text[0]; - D_PostEvent (&event); - } - break; - - case SDL_JOYBUTTONDOWN: - case SDL_JOYBUTTONUP: - if (!GUICapture) - { - event.type = sev.type == SDL_JOYBUTTONDOWN ? EV_KeyDown : EV_KeyUp; - event.data1 = KEY_FIRSTJOYBUTTON + sev.jbutton.button; - if(event.data1 != 0) - D_PostEvent(&event); - } - break; - } -} - -void I_GetEvent () -{ - SDL_Event sev; - - while (SDL_PollEvent (&sev)) - { - MessagePump (sev); - } - if (use_mouse) - { - MouseRead (); - } -} - -void I_StartTic () -{ - I_CheckGUICapture (); - I_CheckNativeMouse (); - I_GetEvent (); -} - -void I_ProcessJoysticks (); -void I_StartFrame () -{ - I_ProcessJoysticks(); -} +#include +#include +#include "doomtype.h" +#include "c_dispatch.h" +#include "doomdef.h" +#include "doomstat.h" +#include "m_argv.h" +#include "i_input.h" +#include "v_video.h" + +#include "d_main.h" +#include "d_event.h" +#include "d_gui.h" +#include "c_console.h" +#include "c_cvars.h" +#include "i_system.h" +#include "dikeys.h" +#include "templates.h" +#include "s_sound.h" + +void ScaleWithAspect (int &w, int &h, int Width, int Height); + +static void I_CheckGUICapture (); +static void I_CheckNativeMouse (); + +bool GUICapture; +static bool NativeMouse = true; + +extern int paused; + +CVAR (Bool, use_mouse, true, CVAR_ARCHIVE|CVAR_GLOBALCONFIG) +CVAR (Bool, m_noprescale, false, CVAR_ARCHIVE|CVAR_GLOBALCONFIG) +CVAR (Bool, m_filter, false, CVAR_ARCHIVE|CVAR_GLOBALCONFIG) + +EXTERN_CVAR (Bool, fullscreen) + +extern int WaitingForKey, chatmodeon; +extern constate_e ConsoleState; + +static bool DownState[SDL_NUM_SCANCODES]; + +static const SDL_Keycode DIKToKeySym[256] = +{ + 0, SDLK_ESCAPE, SDLK_1, SDLK_2, SDLK_3, SDLK_4, SDLK_5, SDLK_6, + SDLK_7, SDLK_8, SDLK_9, SDLK_0,SDLK_MINUS, SDLK_EQUALS, SDLK_BACKSPACE, SDLK_TAB, + SDLK_q, SDLK_w, SDLK_e, SDLK_r, SDLK_t, SDLK_y, SDLK_u, SDLK_i, + SDLK_o, SDLK_p, SDLK_LEFTBRACKET, SDLK_RIGHTBRACKET, SDLK_RETURN, SDLK_LCTRL, SDLK_a, SDLK_s, + SDLK_d, SDLK_f, SDLK_g, SDLK_h, SDLK_j, SDLK_k, SDLK_l, SDLK_SEMICOLON, + SDLK_QUOTE, SDLK_BACKQUOTE, SDLK_LSHIFT, SDLK_BACKSLASH, SDLK_z, SDLK_x, SDLK_c, SDLK_v, + SDLK_b, SDLK_n, SDLK_m, SDLK_COMMA, SDLK_PERIOD, SDLK_SLASH, SDLK_RSHIFT, SDLK_KP_MULTIPLY, + SDLK_LALT, SDLK_SPACE, SDLK_CAPSLOCK, SDLK_F1, SDLK_F2, SDLK_F3, SDLK_F4, SDLK_F5, + SDLK_F6, SDLK_F7, SDLK_F8, SDLK_F9, SDLK_F10, SDLK_NUMLOCKCLEAR, SDLK_SCROLLLOCK, SDLK_KP_7, + SDLK_KP_8, SDLK_KP_9, SDLK_KP_MINUS, SDLK_KP_4, SDLK_KP_5, SDLK_KP_6, SDLK_KP_PLUS, SDLK_KP_1, + SDLK_KP_2, SDLK_KP_3, SDLK_KP_0, SDLK_KP_PERIOD, 0, 0, 0, SDLK_F11, + SDLK_F12, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, SDLK_F13, SDLK_F14, SDLK_F15, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, SDLK_KP_EQUALS, 0, 0, + 0, SDLK_AT, SDLK_COLON, 0, 0, 0, 0, 0, + 0, 0, 0, 0, SDLK_KP_ENTER, SDLK_RCTRL, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, SDLK_KP_COMMA, 0, SDLK_KP_DIVIDE, 0, SDLK_SYSREQ, + SDLK_RALT, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, SDLK_PAUSE, 0, SDLK_HOME, + SDLK_UP, SDLK_PAGEUP, 0, SDLK_LEFT, 0, SDLK_RIGHT, 0, SDLK_END, + SDLK_DOWN, SDLK_PAGEDOWN, SDLK_INSERT, SDLK_DELETE, 0, 0, 0, 0, + 0, 0, 0, SDLK_LGUI, SDLK_RGUI, SDLK_MENU, SDLK_POWER, SDLK_SLEEP, + 0, 0, 0, 0, 0, SDLK_AC_SEARCH, SDLK_AC_BOOKMARKS, SDLK_AC_REFRESH, + SDLK_AC_STOP, SDLK_AC_FORWARD, SDLK_AC_BACK, SDLK_COMPUTER, SDLK_MAIL, SDLK_MEDIASELECT, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0 +}; + +static const SDL_Scancode DIKToKeyScan[256] = +{ + SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_ESCAPE, SDL_SCANCODE_1, SDL_SCANCODE_2, SDL_SCANCODE_3, SDL_SCANCODE_4, SDL_SCANCODE_5, SDL_SCANCODE_6, + SDL_SCANCODE_7, SDL_SCANCODE_8, SDL_SCANCODE_9, SDL_SCANCODE_0 ,SDL_SCANCODE_MINUS, SDL_SCANCODE_EQUALS, SDL_SCANCODE_BACKSPACE, SDL_SCANCODE_TAB, + SDL_SCANCODE_Q, SDL_SCANCODE_W, SDL_SCANCODE_E, SDL_SCANCODE_R, SDL_SCANCODE_T, SDL_SCANCODE_Y, SDL_SCANCODE_U, SDL_SCANCODE_I, + SDL_SCANCODE_O, SDL_SCANCODE_P, SDL_SCANCODE_LEFTBRACKET, SDL_SCANCODE_RIGHTBRACKET, SDL_SCANCODE_RETURN, SDL_SCANCODE_LCTRL, SDL_SCANCODE_A, SDL_SCANCODE_S, + SDL_SCANCODE_D, SDL_SCANCODE_F, SDL_SCANCODE_G, SDL_SCANCODE_H, SDL_SCANCODE_J, SDL_SCANCODE_K, SDL_SCANCODE_L, SDL_SCANCODE_SEMICOLON, + SDL_SCANCODE_APOSTROPHE, SDL_SCANCODE_GRAVE, SDL_SCANCODE_LSHIFT, SDL_SCANCODE_BACKSLASH, SDL_SCANCODE_Z, SDL_SCANCODE_X, SDL_SCANCODE_C, SDL_SCANCODE_V, + SDL_SCANCODE_B, SDL_SCANCODE_N, SDL_SCANCODE_M, SDL_SCANCODE_COMMA, SDL_SCANCODE_PERIOD, SDL_SCANCODE_SLASH, SDL_SCANCODE_RSHIFT, SDL_SCANCODE_KP_MULTIPLY, + SDL_SCANCODE_LALT, SDL_SCANCODE_SPACE, SDL_SCANCODE_CAPSLOCK, SDL_SCANCODE_F1, SDL_SCANCODE_F2, SDL_SCANCODE_F3, SDL_SCANCODE_F4, SDL_SCANCODE_F5, + SDL_SCANCODE_F6, SDL_SCANCODE_F7, SDL_SCANCODE_F8, SDL_SCANCODE_F9, SDL_SCANCODE_F10, SDL_SCANCODE_NUMLOCKCLEAR, SDL_SCANCODE_SCROLLLOCK, SDL_SCANCODE_KP_7, + SDL_SCANCODE_KP_8, SDL_SCANCODE_KP_9, SDL_SCANCODE_KP_MINUS, SDL_SCANCODE_KP_4, SDL_SCANCODE_KP_5, SDL_SCANCODE_KP_6, SDL_SCANCODE_KP_PLUS, SDL_SCANCODE_KP_1, + SDL_SCANCODE_KP_2, SDL_SCANCODE_KP_3, SDL_SCANCODE_KP_0, SDL_SCANCODE_KP_PERIOD, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_F11, + SDL_SCANCODE_F12, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, + SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_F13, SDL_SCANCODE_F14, SDL_SCANCODE_F15, SDL_SCANCODE_UNKNOWN, + SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, + SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, + SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, + SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, + SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_KP_EQUALS, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, + SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, + SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_KP_ENTER, SDL_SCANCODE_RCTRL, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, + SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, + SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, + SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_KP_COMMA, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_KP_DIVIDE, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_SYSREQ, + SDL_SCANCODE_RALT, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, + SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_PAUSE, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_HOME, + SDL_SCANCODE_UP, SDL_SCANCODE_PAGEUP, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_LEFT, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_RIGHT, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_END, + SDL_SCANCODE_DOWN, SDL_SCANCODE_PAGEDOWN, SDL_SCANCODE_INSERT, SDL_SCANCODE_DELETE, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, + SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_LGUI, SDL_SCANCODE_RGUI, SDL_SCANCODE_MENU, SDL_SCANCODE_POWER, SDL_SCANCODE_SLEEP, + SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_AC_SEARCH, SDL_SCANCODE_AC_BOOKMARKS, SDL_SCANCODE_AC_REFRESH, + SDL_SCANCODE_AC_STOP, SDL_SCANCODE_AC_FORWARD, SDL_SCANCODE_AC_BACK, SDL_SCANCODE_COMPUTER, SDL_SCANCODE_MAIL, SDL_SCANCODE_MEDIASELECT, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, + SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, + SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN +}; + +static TMap InitKeySymMap () +{ + TMap KeySymToDIK; + + for (int i = 0; i < 256; ++i) + { + KeySymToDIK[DIKToKeySym[i]] = i; + } + KeySymToDIK[0] = 0; + KeySymToDIK[SDLK_RSHIFT] = DIK_LSHIFT; + KeySymToDIK[SDLK_RCTRL] = DIK_LCONTROL; + KeySymToDIK[SDLK_RALT] = DIK_LMENU; + // Depending on your Linux flavor, you may get SDLK_PRINT or SDLK_SYSREQ + KeySymToDIK[SDLK_PRINTSCREEN] = DIK_SYSRQ; + + return KeySymToDIK; +} +static const TMap KeySymToDIK(InitKeySymMap()); + +static TMap InitKeyScanMap () +{ + TMap KeyScanToDIK; + + for (int i = 0; i < 256; ++i) + { + KeyScanToDIK[DIKToKeyScan[i]] = i; + } + + return KeyScanToDIK; +} +static const TMap KeyScanToDIK(InitKeyScanMap()); + +static void I_CheckGUICapture () +{ + bool wantCapt; + + if (menuactive == MENU_Off) + { + wantCapt = ConsoleState == c_down || ConsoleState == c_falling || chatmodeon; + } + else + { + wantCapt = (menuactive == MENU_On || menuactive == MENU_OnNoPause); + } + + if (wantCapt != GUICapture) + { + GUICapture = wantCapt; + if (wantCapt) + { + memset (DownState, 0, sizeof(DownState)); + } + } +} + +void I_SetMouseCapture() +{ + // Clear out any mouse movement. + SDL_GetRelativeMouseState (NULL, NULL); + SDL_SetRelativeMouseMode (SDL_TRUE); +} + +void I_ReleaseMouseCapture() +{ + SDL_SetRelativeMouseMode (SDL_FALSE); +} + +static void PostMouseMove (int x, int y) +{ + static int lastx = 0, lasty = 0; + event_t ev = { 0,0,0,0,0,0,0 }; + + if (m_filter) + { + ev.x = (x + lastx) / 2; + ev.y = (y + lasty) / 2; + } + else + { + ev.x = x; + ev.y = y; + } + lastx = x; + lasty = y; + if (ev.x | ev.y) + { + ev.type = EV_Mouse; + D_PostEvent (&ev); + } +} + +static void MouseRead () +{ + int x, y; + + if (NativeMouse) + { + return; + } + + SDL_GetRelativeMouseState (&x, &y); + if (!m_noprescale) + { + x *= 3; + y *= 2; + } + if (x | y) + { + PostMouseMove (x, -y); + } +} + +CUSTOM_CVAR(Int, mouse_capturemode, 1, CVAR_GLOBALCONFIG|CVAR_ARCHIVE) +{ + if (self < 0) self = 0; + else if (self > 2) self = 2; +} + +static bool inGame() +{ + switch (mouse_capturemode) + { + default: + case 0: + return gamestate == GS_LEVEL; + case 1: + return gamestate == GS_LEVEL || gamestate == GS_INTERMISSION || gamestate == GS_FINALE; + case 2: + return true; + } +} + +static void I_CheckNativeMouse () +{ + bool focus = SDL_GetKeyboardFocus() != NULL; + bool fs = screen->IsFullscreen(); + + bool wantNative = !focus || (!use_mouse || GUICapture || paused || demoplayback || !inGame()); + + if (wantNative != NativeMouse) + { + NativeMouse = wantNative; + SDL_ShowCursor (wantNative); + if (wantNative) + I_ReleaseMouseCapture (); + else + I_SetMouseCapture (); + } +} + +void MessagePump (const SDL_Event &sev) +{ + static int lastx = 0, lasty = 0; + int x, y; + event_t event = { 0,0,0,0,0,0,0 }; + + switch (sev.type) + { + case SDL_QUIT: + exit (0); + + case SDL_WINDOWEVENT: + switch (sev.window.event) + { + case SDL_WINDOWEVENT_FOCUS_GAINED: + case SDL_WINDOWEVENT_FOCUS_LOST: + S_SetSoundPaused(sev.window.event == SDL_WINDOWEVENT_FOCUS_GAINED); + break; + } + break; + + case SDL_MOUSEBUTTONDOWN: + case SDL_MOUSEBUTTONUP: + case SDL_MOUSEMOTION: + if (!GUICapture || sev.button.button == 4 || sev.button.button == 5) + { + if(sev.type != SDL_MOUSEMOTION) + { + event.type = sev.type == SDL_MOUSEBUTTONDOWN ? EV_KeyDown : EV_KeyUp; + /* These button mappings work with my Gentoo system using the + * evdev driver and a Logitech MX510 mouse. Whether or not they + * carry over to other Linux systems, I have no idea, but I sure + * hope so. (Though buttons 11 and 12 are kind of useless, since + * they also trigger buttons 4 and 5.) + */ + switch (sev.button.button) + { + case SDL_BUTTON_LEFT: event.data1 = KEY_MOUSE1; break; + case SDL_BUTTON_MIDDLE: event.data1 = KEY_MOUSE3; break; + case SDL_BUTTON_RIGHT: event.data1 = KEY_MOUSE2; break; + case 8: event.data1 = KEY_MOUSE4; break; // For whatever reason my side mouse buttons are here. + case 9: event.data1 = KEY_MOUSE5; break; + case SDL_BUTTON_X1: event.data1 = KEY_MOUSE6; break; // And these don't exist + case SDL_BUTTON_X2: event.data1 = KEY_MOUSE7; break; + case 6: event.data1 = KEY_MOUSE8; break; + default: printf("SDL mouse button %s %d\n", + sev.type == SDL_MOUSEBUTTONDOWN ? "down" : "up", sev.button.button); break; + } + if (event.data1 != 0) + { + D_PostEvent(&event); + } + } + } + else if (sev.type == SDL_MOUSEMOTION || (sev.button.button >= 1 && sev.button.button <= 3)) + { + int x, y; + SDL_GetMouseState (&x, &y); + + // Detect if we're doing scaling in the Window and adjust the mouse + // coordinates accordingly. This could be more efficent, but I + // don't think performance is an issue in the menus. + SDL_Window *focus; + if (screen->IsFullscreen() && (focus = SDL_GetMouseFocus ())) + { + int w, h; + SDL_GetWindowSize (focus, &w, &h); + int realw = w, realh = h; + ScaleWithAspect (realw, realh, SCREENWIDTH, SCREENHEIGHT); + if (realw != SCREENWIDTH || realh != SCREENHEIGHT) + { + double xratio = (double)SCREENWIDTH/realw; + double yratio = (double)SCREENHEIGHT/realh; + if (realw < w) + { + x = (x - (w - realw)/2)*xratio; + y *= yratio; + } + else + { + y = (y - (h - realh)/2)*yratio; + x *= xratio; + } + } + } + + event.data1 = x; + event.data2 = y; + event.type = EV_GUI_Event; + if(sev.type == SDL_MOUSEMOTION) + event.subtype = EV_GUI_MouseMove; + else + { + event.subtype = sev.type == SDL_MOUSEBUTTONDOWN ? EV_GUI_LButtonDown : EV_GUI_LButtonUp; + event.subtype += (sev.button.button - 1) * 3; + } + D_PostEvent(&event); + } + break; + + case SDL_MOUSEWHEEL: + if (GUICapture) + { + event.type = EV_GUI_Event; + event.subtype = sev.wheel.y > 0 ? EV_GUI_WheelUp : EV_GUI_WheelDown; + D_PostEvent (&event); + } + else + { + event.type = EV_KeyDown; + event.data1 = sev.wheel.y > 0 ? KEY_MWHEELUP : KEY_MWHEELDOWN; + D_PostEvent (&event); + event.type = EV_KeyUp; + D_PostEvent (&event); + } + break; + + case SDL_KEYDOWN: + case SDL_KEYUP: + if (!GUICapture) + { + event.type = sev.type == SDL_KEYDOWN ? EV_KeyDown : EV_KeyUp; + + // Try to look up our key mapped key for conversion to DirectInput. + // If that fails, then we'll do a lookup against the scan code, + // which may not return the right key, but at least the key should + // work in the game. + if (const BYTE *dik = KeySymToDIK.CheckKey (sev.key.keysym.sym)) + event.data1 = *dik; + else if (const BYTE *dik = KeyScanToDIK.CheckKey (sev.key.keysym.scancode)) + event.data1 = *dik; + + if (event.data1) + { + if (sev.key.keysym.sym < 256) + { + event.data2 = sev.key.keysym.sym; + } + D_PostEvent (&event); + } + } + else + { + event.type = EV_GUI_Event; + event.subtype = sev.type == SDL_KEYDOWN ? EV_GUI_KeyDown : EV_GUI_KeyUp; + event.data3 = ((sev.key.keysym.mod & KMOD_SHIFT) ? GKM_SHIFT : 0) | + ((sev.key.keysym.mod & KMOD_CTRL) ? GKM_CTRL : 0) | + ((sev.key.keysym.mod & KMOD_ALT) ? GKM_ALT : 0); + + if (event.subtype == EV_GUI_KeyDown) + { + if (DownState[sev.key.keysym.scancode]) + { + event.subtype = EV_GUI_KeyRepeat; + } + DownState[sev.key.keysym.scancode] = 1; + } + else + { + DownState[sev.key.keysym.scancode] = 0; + } + + switch (sev.key.keysym.sym) + { + case SDLK_KP_ENTER: event.data1 = GK_RETURN; break; + case SDLK_PAGEUP: event.data1 = GK_PGUP; break; + case SDLK_PAGEDOWN: event.data1 = GK_PGDN; break; + case SDLK_END: event.data1 = GK_END; break; + case SDLK_HOME: event.data1 = GK_HOME; break; + case SDLK_LEFT: event.data1 = GK_LEFT; break; + case SDLK_RIGHT: event.data1 = GK_RIGHT; break; + case SDLK_UP: event.data1 = GK_UP; break; + case SDLK_DOWN: event.data1 = GK_DOWN; break; + case SDLK_DELETE: event.data1 = GK_DEL; break; + case SDLK_ESCAPE: event.data1 = GK_ESCAPE; break; + case SDLK_F1: event.data1 = GK_F1; break; + case SDLK_F2: event.data1 = GK_F2; break; + case SDLK_F3: event.data1 = GK_F3; break; + case SDLK_F4: event.data1 = GK_F4; break; + case SDLK_F5: event.data1 = GK_F5; break; + case SDLK_F6: event.data1 = GK_F6; break; + case SDLK_F7: event.data1 = GK_F7; break; + case SDLK_F8: event.data1 = GK_F8; break; + case SDLK_F9: event.data1 = GK_F9; break; + case SDLK_F10: event.data1 = GK_F10; break; + case SDLK_F11: event.data1 = GK_F11; break; + case SDLK_F12: event.data1 = GK_F12; break; + default: + if (sev.key.keysym.sym < 256) + { + event.data1 = sev.key.keysym.sym; + } + break; + } + if (event.data1 < 128) + { + event.data1 = toupper(event.data1); + D_PostEvent (&event); + } + } + break; + + case SDL_TEXTINPUT: + if (GUICapture) + { + event.type = EV_GUI_Event; + event.subtype = EV_GUI_Char; + event.data1 = sev.text.text[0]; + D_PostEvent (&event); + } + break; + + case SDL_JOYBUTTONDOWN: + case SDL_JOYBUTTONUP: + if (!GUICapture) + { + event.type = sev.type == SDL_JOYBUTTONDOWN ? EV_KeyDown : EV_KeyUp; + event.data1 = KEY_FIRSTJOYBUTTON + sev.jbutton.button; + if(event.data1 != 0) + D_PostEvent(&event); + } + break; + } +} + +void I_GetEvent () +{ + SDL_Event sev; + + while (SDL_PollEvent (&sev)) + { + MessagePump (sev); + } + if (use_mouse) + { + MouseRead (); + } +} + +void I_StartTic () +{ + I_CheckGUICapture (); + I_CheckNativeMouse (); + I_GetEvent (); +} + +void I_ProcessJoysticks (); +void I_StartFrame () +{ + I_ProcessJoysticks(); +} diff --git a/src/sdl/i_joystick.cpp b/src/posix/sdl/i_joystick.cpp similarity index 100% rename from src/sdl/i_joystick.cpp rename to src/posix/sdl/i_joystick.cpp diff --git a/src/sdl/i_main.cpp b/src/posix/sdl/i_main.cpp similarity index 96% rename from src/sdl/i_main.cpp rename to src/posix/sdl/i_main.cpp index 10a9b8c75..ff700eff4 100644 --- a/src/sdl/i_main.cpp +++ b/src/posix/sdl/i_main.cpp @@ -1,338 +1,338 @@ -/* -** i_main.cpp -** System-specific startup code. Eventually calls D_DoomMain. -** -**--------------------------------------------------------------------------- -** Copyright 1998-2007 Randy Heit -** All rights reserved. -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** -** 1. Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** 2. Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in the -** documentation and/or other materials provided with the distribution. -** 3. The name of the author may not be used to endorse or promote products -** derived from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR -** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES -** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. -** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, -** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT -** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF -** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -**--------------------------------------------------------------------------- -** -*/ - -// HEADER FILES ------------------------------------------------------------ - -#include -#include -#include -#include -#include -#include -#ifndef NO_GTK -#include -#endif -#include -#if defined(__MACH__) && !defined(NOASM) -#include -#include -#endif - -#include "doomerrors.h" -#include "m_argv.h" -#include "d_main.h" -#include "i_system.h" -#include "i_video.h" -#include "c_console.h" -#include "errors.h" -#include "version.h" -#include "w_wad.h" -#include "g_level.h" -#include "r_state.h" -#include "cmdlib.h" -#include "r_utility.h" -#include "doomstat.h" - -// MACROS ------------------------------------------------------------------ - -// The maximum number of functions that can be registered with atterm. -#define MAX_TERMS 64 - -// TYPES ------------------------------------------------------------------- - -// EXTERNAL FUNCTION PROTOTYPES -------------------------------------------- - -extern "C" int cc_install_handlers(int, char**, int, int*, const char*, int(*)(char*, char*)); - -#ifdef __APPLE__ -void Mac_I_FatalError(const char* errortext); -#endif - -// PUBLIC FUNCTION PROTOTYPES ---------------------------------------------- - -// PRIVATE FUNCTION PROTOTYPES --------------------------------------------- - -// EXTERNAL DATA DECLARATIONS ---------------------------------------------- - -// PUBLIC DATA DEFINITIONS ------------------------------------------------- - -#ifndef NO_GTK -bool GtkAvailable; -#endif - -// The command line arguments. -DArgs *Args; - -// PRIVATE DATA DEFINITIONS ------------------------------------------------ - -static void (*TermFuncs[MAX_TERMS]) (); -static const char *TermNames[MAX_TERMS]; -static int NumTerms; - -// CODE -------------------------------------------------------------------- - -void addterm (void (*func) (), const char *name) -{ - // Make sure this function wasn't already registered. - for (int i = 0; i < NumTerms; ++i) - { - if (TermFuncs[i] == func) - { - return; - } - } - if (NumTerms == MAX_TERMS) - { - func (); - I_FatalError ( - "Too many exit functions registered.\n" - "Increase MAX_TERMS in i_main.cpp"); - } - TermNames[NumTerms] = name; - TermFuncs[NumTerms++] = func; -} - -void popterm () -{ - if (NumTerms) - NumTerms--; -} - -void STACK_ARGS call_terms () -{ - while (NumTerms > 0) - { -// printf ("term %d - %s\n", NumTerms, TermNames[NumTerms-1]); - TermFuncs[--NumTerms] (); - } -} - -static void STACK_ARGS NewFailure () -{ - I_FatalError ("Failed to allocate memory from system heap"); -} - -static int DoomSpecificInfo (char *buffer, char *end) -{ - const char *arg; - int size = end-buffer-2; - int i, p; - - p = 0; - p += snprintf (buffer+p, size-p, GAMENAME" version %s (%s)\n", GetVersionString(), GetGitHash()); -#ifdef __VERSION__ - p += snprintf (buffer+p, size-p, "Compiler version: %s\n", __VERSION__); -#endif - p += snprintf (buffer+p, size-p, "\nCommand line:"); - for (i = 0; i < Args->NumArgs(); ++i) - { - p += snprintf (buffer+p, size-p, " %s", Args->GetArg(i)); - } - p += snprintf (buffer+p, size-p, "\n"); - - for (i = 0; (arg = Wads.GetWadName (i)) != NULL; ++i) - { - p += snprintf (buffer+p, size-p, "\nWad %d: %s", i, arg); - } - - if (gamestate != GS_LEVEL && gamestate != GS_TITLELEVEL) - { - p += snprintf (buffer+p, size-p, "\n\nNot in a level."); - } - else - { - p += snprintf (buffer+p, size-p, "\n\nCurrent map: %s", level.MapName.GetChars()); - - if (!viewactive) - { - p += snprintf (buffer+p, size-p, "\n\nView not active."); - } - else - { - p += snprintf (buffer+p, size-p, "\n\nviewx = %d", (int)viewx); - p += snprintf (buffer+p, size-p, "\nviewy = %d", (int)viewy); - p += snprintf (buffer+p, size-p, "\nviewz = %d", (int)viewz); - p += snprintf (buffer+p, size-p, "\nviewangle = %x", (unsigned int)viewangle); - } - } - buffer[p++] = '\n'; - buffer[p++] = '\0'; - - return p; -} - -#if defined(__MACH__) && !defined(NOASM) -// NASM won't let us create custom sections for Mach-O. Whether that's a limitation of NASM -// or of Mach-O, I don't know, but since we're using NASM for the assembly, it doesn't much -// matter. -extern "C" -{ - extern void *rtext_a_start, *rtext_a_end; - extern void *rtext_tmap_start, *rtext_tmap_end; - extern void *rtext_tmap2_start, *rtext_tmap2_end; - extern void *rtext_tmap3_start, *rtext_tmap3_end; -}; - -static void unprotect_pages(long pagesize, void *start, void *end) -{ - char *page = (char *)((intptr_t)start & ~(pagesize - 1)); - size_t len = (char *)end - (char *)start; - if (mprotect(page, len, PROT_READ|PROT_WRITE|PROT_EXEC) != 0) - { - fprintf(stderr, "mprotect failed\n"); - exit(1); - } -} - -static void unprotect_rtext() -{ - static void *const pages[] = - { - rtext_a_start, rtext_a_end, - rtext_tmap_start, rtext_tmap_end, - rtext_tmap2_start, rtext_tmap2_end, - rtext_tmap3_start, rtext_tmap3_end - }; - long pagesize = sysconf(_SC_PAGESIZE); - for (void *const *p = pages; p < &pages[countof(pages)]; p += 2) - { - unprotect_pages(pagesize, p[0], p[1]); - } -} -#endif - -void I_StartupJoysticks(); -void I_ShutdownJoysticks(); - -int main (int argc, char **argv) -{ -#if !defined (__APPLE__) - { - int s[4] = { SIGSEGV, SIGILL, SIGFPE, SIGBUS }; - cc_install_handlers(argc, argv, 4, s, "zdoom-crash.log", DoomSpecificInfo); - } -#endif // !__APPLE__ - - printf(GAMENAME" %s - %s - SDL version\nCompiled on %s\n", - GetVersionString(), GetGitTime(), __DATE__); - - seteuid (getuid ()); - std::set_new_handler (NewFailure); - -#if defined(__MACH__) && !defined(NOASM) - unprotect_rtext(); -#endif - - // Set LC_NUMERIC environment variable in case some library decides to - // clear the setlocale call at least this will be correct. - // Note that the LANG environment variable is overridden by LC_* - setenv ("LC_NUMERIC", "C", 1); - -#ifndef NO_GTK - GtkAvailable = gtk_init_check (&argc, &argv); -#endif - - setlocale (LC_ALL, "C"); - - if (SDL_Init (SDL_INIT_VIDEO|SDL_INIT_TIMER|SDL_INIT_NOPARACHUTE|SDL_INIT_JOYSTICK) == -1) - { - fprintf (stderr, "Could not initialize SDL:\n%s\n", SDL_GetError()); - return -1; - } - atterm (SDL_Quit); - - printf("Using video driver %s\n", SDL_GetCurrentVideoDriver()); - printf("\n"); - - try - { - Args = new DArgs(argc, argv); - - /* - killough 1/98: - - This fixes some problems with exit handling - during abnormal situations. - - The old code called I_Quit() to end program, - while now I_Quit() is installed as an exit - handler and exit() is called to exit, either - normally or abnormally. Seg faults are caught - and the error handler is used, to prevent - being left in graphics mode or having very - loud SFX noise because the sound card is - left in an unstable state. - */ - - atexit (call_terms); - atterm (I_Quit); - - // Should we even be doing anything with progdir on Unix systems? - char program[PATH_MAX]; - if (realpath (argv[0], program) == NULL) - strcpy (program, argv[0]); - char *slash = strrchr (program, '/'); - if (slash != NULL) - { - *(slash + 1) = '\0'; - progdir = program; - } - else - { - progdir = "./"; - } - - I_StartupJoysticks(); - C_InitConsole (80*8, 25*8, false); - D_DoomMain (); - } - catch (class CDoomError &error) - { - I_ShutdownJoysticks(); - if (error.GetMessage ()) - fprintf (stderr, "%s\n", error.GetMessage ()); - -#ifdef __APPLE__ - Mac_I_FatalError(error.GetMessage()); -#endif // __APPLE__ - - exit (-1); - } - catch (...) - { - call_terms (); - throw; - } - return 0; -} +/* +** i_main.cpp +** System-specific startup code. Eventually calls D_DoomMain. +** +**--------------------------------------------------------------------------- +** Copyright 1998-2007 Randy Heit +** All rights reserved. +** +** Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions +** are met: +** +** 1. Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** 2. Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in the +** documentation and/or other materials provided with the distribution. +** 3. The name of the author may not be used to endorse or promote products +** derived from this software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR +** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, +** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +**--------------------------------------------------------------------------- +** +*/ + +// HEADER FILES ------------------------------------------------------------ + +#include +#include +#include +#include +#include +#include +#ifndef NO_GTK +#include +#endif +#include +#if defined(__MACH__) && !defined(NOASM) +#include +#include +#endif + +#include "doomerrors.h" +#include "m_argv.h" +#include "d_main.h" +#include "i_system.h" +#include "i_video.h" +#include "c_console.h" +#include "errors.h" +#include "version.h" +#include "w_wad.h" +#include "g_level.h" +#include "r_state.h" +#include "cmdlib.h" +#include "r_utility.h" +#include "doomstat.h" + +// MACROS ------------------------------------------------------------------ + +// The maximum number of functions that can be registered with atterm. +#define MAX_TERMS 64 + +// TYPES ------------------------------------------------------------------- + +// EXTERNAL FUNCTION PROTOTYPES -------------------------------------------- + +extern "C" int cc_install_handlers(int, char**, int, int*, const char*, int(*)(char*, char*)); + +#ifdef __APPLE__ +void Mac_I_FatalError(const char* errortext); +#endif + +// PUBLIC FUNCTION PROTOTYPES ---------------------------------------------- + +// PRIVATE FUNCTION PROTOTYPES --------------------------------------------- + +// EXTERNAL DATA DECLARATIONS ---------------------------------------------- + +// PUBLIC DATA DEFINITIONS ------------------------------------------------- + +#ifndef NO_GTK +bool GtkAvailable; +#endif + +// The command line arguments. +DArgs *Args; + +// PRIVATE DATA DEFINITIONS ------------------------------------------------ + +static void (*TermFuncs[MAX_TERMS]) (); +static const char *TermNames[MAX_TERMS]; +static int NumTerms; + +// CODE -------------------------------------------------------------------- + +void addterm (void (*func) (), const char *name) +{ + // Make sure this function wasn't already registered. + for (int i = 0; i < NumTerms; ++i) + { + if (TermFuncs[i] == func) + { + return; + } + } + if (NumTerms == MAX_TERMS) + { + func (); + I_FatalError ( + "Too many exit functions registered.\n" + "Increase MAX_TERMS in i_main.cpp"); + } + TermNames[NumTerms] = name; + TermFuncs[NumTerms++] = func; +} + +void popterm () +{ + if (NumTerms) + NumTerms--; +} + +void STACK_ARGS call_terms () +{ + while (NumTerms > 0) + { +// printf ("term %d - %s\n", NumTerms, TermNames[NumTerms-1]); + TermFuncs[--NumTerms] (); + } +} + +static void STACK_ARGS NewFailure () +{ + I_FatalError ("Failed to allocate memory from system heap"); +} + +static int DoomSpecificInfo (char *buffer, char *end) +{ + const char *arg; + int size = end-buffer-2; + int i, p; + + p = 0; + p += snprintf (buffer+p, size-p, GAMENAME" version %s (%s)\n", GetVersionString(), GetGitHash()); +#ifdef __VERSION__ + p += snprintf (buffer+p, size-p, "Compiler version: %s\n", __VERSION__); +#endif + p += snprintf (buffer+p, size-p, "\nCommand line:"); + for (i = 0; i < Args->NumArgs(); ++i) + { + p += snprintf (buffer+p, size-p, " %s", Args->GetArg(i)); + } + p += snprintf (buffer+p, size-p, "\n"); + + for (i = 0; (arg = Wads.GetWadName (i)) != NULL; ++i) + { + p += snprintf (buffer+p, size-p, "\nWad %d: %s", i, arg); + } + + if (gamestate != GS_LEVEL && gamestate != GS_TITLELEVEL) + { + p += snprintf (buffer+p, size-p, "\n\nNot in a level."); + } + else + { + p += snprintf (buffer+p, size-p, "\n\nCurrent map: %s", level.MapName.GetChars()); + + if (!viewactive) + { + p += snprintf (buffer+p, size-p, "\n\nView not active."); + } + else + { + p += snprintf (buffer+p, size-p, "\n\nviewx = %d", (int)viewx); + p += snprintf (buffer+p, size-p, "\nviewy = %d", (int)viewy); + p += snprintf (buffer+p, size-p, "\nviewz = %d", (int)viewz); + p += snprintf (buffer+p, size-p, "\nviewangle = %x", (unsigned int)viewangle); + } + } + buffer[p++] = '\n'; + buffer[p++] = '\0'; + + return p; +} + +#if defined(__MACH__) && !defined(NOASM) +// NASM won't let us create custom sections for Mach-O. Whether that's a limitation of NASM +// or of Mach-O, I don't know, but since we're using NASM for the assembly, it doesn't much +// matter. +extern "C" +{ + extern void *rtext_a_start, *rtext_a_end; + extern void *rtext_tmap_start, *rtext_tmap_end; + extern void *rtext_tmap2_start, *rtext_tmap2_end; + extern void *rtext_tmap3_start, *rtext_tmap3_end; +}; + +static void unprotect_pages(long pagesize, void *start, void *end) +{ + char *page = (char *)((intptr_t)start & ~(pagesize - 1)); + size_t len = (char *)end - (char *)start; + if (mprotect(page, len, PROT_READ|PROT_WRITE|PROT_EXEC) != 0) + { + fprintf(stderr, "mprotect failed\n"); + exit(1); + } +} + +static void unprotect_rtext() +{ + static void *const pages[] = + { + rtext_a_start, rtext_a_end, + rtext_tmap_start, rtext_tmap_end, + rtext_tmap2_start, rtext_tmap2_end, + rtext_tmap3_start, rtext_tmap3_end + }; + long pagesize = sysconf(_SC_PAGESIZE); + for (void *const *p = pages; p < &pages[countof(pages)]; p += 2) + { + unprotect_pages(pagesize, p[0], p[1]); + } +} +#endif + +void I_StartupJoysticks(); +void I_ShutdownJoysticks(); + +int main (int argc, char **argv) +{ +#if !defined (__APPLE__) + { + int s[4] = { SIGSEGV, SIGILL, SIGFPE, SIGBUS }; + cc_install_handlers(argc, argv, 4, s, "zdoom-crash.log", DoomSpecificInfo); + } +#endif // !__APPLE__ + + printf(GAMENAME" %s - %s - SDL version\nCompiled on %s\n", + GetVersionString(), GetGitTime(), __DATE__); + + seteuid (getuid ()); + std::set_new_handler (NewFailure); + +#if defined(__MACH__) && !defined(NOASM) + unprotect_rtext(); +#endif + + // Set LC_NUMERIC environment variable in case some library decides to + // clear the setlocale call at least this will be correct. + // Note that the LANG environment variable is overridden by LC_* + setenv ("LC_NUMERIC", "C", 1); + +#ifndef NO_GTK + GtkAvailable = gtk_init_check (&argc, &argv); +#endif + + setlocale (LC_ALL, "C"); + + if (SDL_Init (SDL_INIT_VIDEO|SDL_INIT_TIMER|SDL_INIT_NOPARACHUTE|SDL_INIT_JOYSTICK) == -1) + { + fprintf (stderr, "Could not initialize SDL:\n%s\n", SDL_GetError()); + return -1; + } + atterm (SDL_Quit); + + printf("Using video driver %s\n", SDL_GetCurrentVideoDriver()); + printf("\n"); + + try + { + Args = new DArgs(argc, argv); + + /* + killough 1/98: + + This fixes some problems with exit handling + during abnormal situations. + + The old code called I_Quit() to end program, + while now I_Quit() is installed as an exit + handler and exit() is called to exit, either + normally or abnormally. Seg faults are caught + and the error handler is used, to prevent + being left in graphics mode or having very + loud SFX noise because the sound card is + left in an unstable state. + */ + + atexit (call_terms); + atterm (I_Quit); + + // Should we even be doing anything with progdir on Unix systems? + char program[PATH_MAX]; + if (realpath (argv[0], program) == NULL) + strcpy (program, argv[0]); + char *slash = strrchr (program, '/'); + if (slash != NULL) + { + *(slash + 1) = '\0'; + progdir = program; + } + else + { + progdir = "./"; + } + + I_StartupJoysticks(); + C_InitConsole (80*8, 25*8, false); + D_DoomMain (); + } + catch (class CDoomError &error) + { + I_ShutdownJoysticks(); + if (error.GetMessage ()) + fprintf (stderr, "%s\n", error.GetMessage ()); + +#ifdef __APPLE__ + Mac_I_FatalError(error.GetMessage()); +#endif // __APPLE__ + + exit (-1); + } + catch (...) + { + call_terms (); + throw; + } + return 0; +} diff --git a/src/sdl/i_system_cocoa.mm b/src/posix/sdl/i_system.mm similarity index 100% rename from src/sdl/i_system_cocoa.mm rename to src/posix/sdl/i_system.mm diff --git a/src/sdl/i_timer.cpp b/src/posix/sdl/i_timer.cpp similarity index 100% rename from src/sdl/i_timer.cpp rename to src/posix/sdl/i_timer.cpp diff --git a/src/sdl/sdlvideo.cpp b/src/posix/sdl/sdlvideo.cpp similarity index 95% rename from src/sdl/sdlvideo.cpp rename to src/posix/sdl/sdlvideo.cpp index e477df526..7a04ce901 100644 --- a/src/sdl/sdlvideo.cpp +++ b/src/posix/sdl/sdlvideo.cpp @@ -1,732 +1,732 @@ - -// HEADER FILES ------------------------------------------------------------ - -#include "doomtype.h" - -#include "templates.h" -#include "i_system.h" -#include "i_video.h" -#include "v_video.h" -#include "v_pfx.h" -#include "stats.h" -#include "v_palette.h" -#include "sdlvideo.h" -#include "r_swrenderer.h" -#include "version.h" - -#include - -#ifdef __APPLE__ -#include -#endif // __APPLE__ - -// MACROS ------------------------------------------------------------------ - -// TYPES ------------------------------------------------------------------- - -class SDLFB : public DFrameBuffer -{ - DECLARE_CLASS(SDLFB, DFrameBuffer) -public: - SDLFB (int width, int height, bool fullscreen); - ~SDLFB (); - - bool Lock (bool buffer); - void Unlock (); - bool Relock (); - void ForceBuffering (bool force); - bool IsValid (); - void Update (); - PalEntry *GetPalette (); - void GetFlashedPalette (PalEntry pal[256]); - void UpdatePalette (); - bool SetGamma (float gamma); - bool SetFlash (PalEntry rgb, int amount); - void GetFlash (PalEntry &rgb, int &amount); - void SetFullscreen (bool fullscreen); - int GetPageCount (); - bool IsFullscreen (); - - friend class SDLVideo; - - virtual void SetVSync (bool vsync); - -private: - PalEntry SourcePalette[256]; - BYTE GammaTable[3][256]; - PalEntry Flash; - int FlashAmount; - float Gamma; - bool UpdatePending; - - SDL_Window *Screen; - SDL_Renderer *Renderer; - union - { - SDL_Texture *Texture; - SDL_Surface *Surface; - }; - SDL_Rect UpdateRect; - - bool UsingRenderer; - bool NeedPalUpdate; - bool NeedGammaUpdate; - bool NotPaletted; - - void UpdateColors (); - void ResetSDLRenderer (); - - SDLFB () {} -}; -IMPLEMENT_CLASS(SDLFB) - -struct MiniModeInfo -{ - WORD Width, Height; -}; - -// PUBLIC FUNCTION PROTOTYPES ---------------------------------------------- - -// PRIVATE FUNCTION PROTOTYPES --------------------------------------------- - -// EXTERNAL DATA DECLARATIONS ---------------------------------------------- - -extern IVideo *Video; -extern bool GUICapture; - -EXTERN_CVAR (Float, Gamma) -EXTERN_CVAR (Int, vid_maxfps) -EXTERN_CVAR (Bool, cl_capfps) -EXTERN_CVAR (Bool, vid_vsync) - -// PUBLIC DATA DEFINITIONS ------------------------------------------------- - -CVAR (Int, vid_adapter, 0, CVAR_ARCHIVE|CVAR_GLOBALCONFIG) - -CVAR (Int, vid_displaybits, 32, CVAR_ARCHIVE|CVAR_GLOBALCONFIG) - -CVAR (Bool, vid_forcesurface, false, CVAR_ARCHIVE|CVAR_GLOBALCONFIG) - -CUSTOM_CVAR (Float, rgamma, 1.f, CVAR_ARCHIVE|CVAR_GLOBALCONFIG) -{ - if (screen != NULL) - { - screen->SetGamma (Gamma); - } -} -CUSTOM_CVAR (Float, ggamma, 1.f, CVAR_ARCHIVE|CVAR_GLOBALCONFIG) -{ - if (screen != NULL) - { - screen->SetGamma (Gamma); - } -} -CUSTOM_CVAR (Float, bgamma, 1.f, CVAR_ARCHIVE|CVAR_GLOBALCONFIG) -{ - if (screen != NULL) - { - screen->SetGamma (Gamma); - } -} - -// PRIVATE DATA DEFINITIONS ------------------------------------------------ - -// Dummy screen sizes to pass when windowed -static MiniModeInfo WinModes[] = -{ - { 320, 200 }, - { 320, 240 }, - { 400, 225 }, // 16:9 - { 400, 300 }, - { 480, 270 }, // 16:9 - { 480, 360 }, - { 512, 288 }, // 16:9 - { 512, 384 }, - { 640, 360 }, // 16:9 - { 640, 400 }, - { 640, 480 }, - { 720, 480 }, // 16:10 - { 720, 540 }, - { 800, 450 }, // 16:9 - { 800, 480 }, - { 800, 500 }, // 16:10 - { 800, 600 }, - { 848, 480 }, // 16:9 - { 960, 600 }, // 16:10 - { 960, 720 }, - { 1024, 576 }, // 16:9 - { 1024, 600 }, // 17:10 - { 1024, 640 }, // 16:10 - { 1024, 768 }, - { 1088, 612 }, // 16:9 - { 1152, 648 }, // 16:9 - { 1152, 720 }, // 16:10 - { 1152, 864 }, - { 1280, 720 }, // 16:9 - { 1280, 854 }, - { 1280, 800 }, // 16:10 - { 1280, 960 }, - { 1280, 1024 }, // 5:4 - { 1360, 768 }, // 16:9 - { 1366, 768 }, - { 1400, 787 }, // 16:9 - { 1400, 875 }, // 16:10 - { 1400, 1050 }, - { 1440, 900 }, - { 1440, 960 }, - { 1440, 1080 }, - { 1600, 900 }, // 16:9 - { 1600, 1000 }, // 16:10 - { 1600, 1200 }, - { 1920, 1080 }, - { 1920, 1200 }, - { 2048, 1536 }, - { 2560, 1440 }, - { 2560, 1600 }, - { 2560, 2048 }, - { 2880, 1800 }, - { 3200, 1800 }, - { 3840, 2160 }, - { 3840, 2400 }, - { 4096, 2160 }, - { 5120, 2880 } -}; - -static cycle_t BlitCycles; -static cycle_t SDLFlipCycles; - -// CODE -------------------------------------------------------------------- - -void ScaleWithAspect (int &w, int &h, int Width, int Height) -{ - int resRatio = CheckRatio (Width, Height); - int screenRatio; - CheckRatio (w, h, &screenRatio); - if (resRatio == screenRatio) - return; - - double yratio; - switch(resRatio) - { - case 0: yratio = 4./3.; break; - case 1: yratio = 16./9.; break; - case 2: yratio = 16./10.; break; - case 3: yratio = 17./10.; break; - case 4: yratio = 5./4.; break; - default: return; - } - double y = w/yratio; - if (y > h) - w = h*yratio; - else - h = y; -} - -SDLVideo::SDLVideo (int parm) -{ - IteratorBits = 0; -} - -SDLVideo::~SDLVideo () -{ -} - -void SDLVideo::StartModeIterator (int bits, bool fs) -{ - IteratorMode = 0; - IteratorBits = bits; -} - -bool SDLVideo::NextMode (int *width, int *height, bool *letterbox) -{ - if (IteratorBits != 8) - return false; - - if ((unsigned)IteratorMode < sizeof(WinModes)/sizeof(WinModes[0])) - { - *width = WinModes[IteratorMode].Width; - *height = WinModes[IteratorMode].Height; - ++IteratorMode; - return true; - } - return false; -} - -DFrameBuffer *SDLVideo::CreateFrameBuffer (int width, int height, bool fullscreen, DFrameBuffer *old) -{ - static int retry = 0; - static int owidth, oheight; - - PalEntry flashColor; - int flashAmount; - - if (old != NULL) - { // Reuse the old framebuffer if its attributes are the same - SDLFB *fb = static_cast (old); - if (fb->Width == width && - fb->Height == height) - { - bool fsnow = (SDL_GetWindowFlags (fb->Screen) & SDL_WINDOW_FULLSCREEN_DESKTOP) != 0; - - if (fsnow != fullscreen) - { - fb->SetFullscreen (fullscreen); - } - return old; - } - old->GetFlash (flashColor, flashAmount); - old->ObjectFlags |= OF_YesReallyDelete; - if (screen == old) screen = NULL; - delete old; - } - else - { - flashColor = 0; - flashAmount = 0; - } - - SDLFB *fb = new SDLFB (width, height, fullscreen); - retry = 0; - - // If we could not create the framebuffer, try again with slightly - // different parameters in this order: - // 1. Try with the closest size - // 2. Try in the opposite screen mode with the original size - // 3. Try in the opposite screen mode with the closest size - // This is a somewhat confusing mass of recursion here. - - while (fb == NULL || !fb->IsValid ()) - { - if (fb != NULL) - { - delete fb; - } - - switch (retry) - { - case 0: - owidth = width; - oheight = height; - case 2: - // Try a different resolution. Hopefully that will work. - I_ClosestResolution (&width, &height, 8); - break; - - case 1: - // Try changing fullscreen mode. Maybe that will work. - width = owidth; - height = oheight; - fullscreen = !fullscreen; - break; - - default: - // I give up! - I_FatalError ("Could not create new screen (%d x %d)", owidth, oheight); - } - - ++retry; - fb = static_cast(CreateFrameBuffer (width, height, fullscreen, NULL)); - } - - fb->SetFlash (flashColor, flashAmount); - - return fb; -} - -void SDLVideo::SetWindowedScale (float scale) -{ -} - -// FrameBuffer implementation ----------------------------------------------- - -SDLFB::SDLFB (int width, int height, bool fullscreen) - : DFrameBuffer (width, height) -{ - int i; - - NeedPalUpdate = false; - NeedGammaUpdate = false; - UpdatePending = false; - NotPaletted = false; - FlashAmount = 0; - - FString caption; - caption.Format(GAMESIG " %s (%s)", GetVersionString(), GetGitTime()); - - Screen = SDL_CreateWindow (caption, - SDL_WINDOWPOS_UNDEFINED_DISPLAY(vid_adapter), SDL_WINDOWPOS_UNDEFINED_DISPLAY(vid_adapter), - width, height, (fullscreen ? SDL_WINDOW_FULLSCREEN_DESKTOP : 0)); - - if (Screen == NULL) - return; - - Renderer = NULL; - Texture = NULL; - ResetSDLRenderer (); - - for (i = 0; i < 256; i++) - { - GammaTable[0][i] = GammaTable[1][i] = GammaTable[2][i] = i; - } - - memcpy (SourcePalette, GPalette.BaseColors, sizeof(PalEntry)*256); - UpdateColors (); - -#ifdef __APPLE__ - SetVSync (vid_vsync); -#endif -} - - -SDLFB::~SDLFB () -{ - if(Screen) - { - if (Renderer) - { - if (Texture) - SDL_DestroyTexture (Texture); - SDL_DestroyRenderer (Renderer); - } - - SDL_DestroyWindow (Screen); - } -} - -bool SDLFB::IsValid () -{ - return DFrameBuffer::IsValid() && Screen != NULL; -} - -int SDLFB::GetPageCount () -{ - return 1; -} - -bool SDLFB::Lock (bool buffered) -{ - return DSimpleCanvas::Lock (); -} - -bool SDLFB::Relock () -{ - return DSimpleCanvas::Lock (); -} - -void SDLFB::Unlock () -{ - if (UpdatePending && LockCount == 1) - { - Update (); - } - else if (--LockCount <= 0) - { - Buffer = NULL; - LockCount = 0; - } -} - -void SDLFB::Update () -{ - if (LockCount != 1) - { - if (LockCount > 0) - { - UpdatePending = true; - --LockCount; - } - return; - } - - DrawRateStuff (); - -#ifndef __APPLE__ - if(vid_maxfps && !cl_capfps) - { - SEMAPHORE_WAIT(FPSLimitSemaphore) - } -#endif - - Buffer = NULL; - LockCount = 0; - UpdatePending = false; - - BlitCycles.Reset(); - SDLFlipCycles.Reset(); - BlitCycles.Clock(); - - void *pixels; - int pitch; - if (UsingRenderer) - { - if (SDL_LockTexture (Texture, NULL, &pixels, &pitch)) - return; - } - else - { - if (SDL_LockSurface (Surface)) - return; - - pixels = Surface->pixels; - pitch = Surface->pitch; - } - - if (NotPaletted) - { - GPfx.Convert (MemBuffer, Pitch, - pixels, pitch, Width, Height, - FRACUNIT, FRACUNIT, 0, 0); - } - else - { - if (pitch == Pitch) - { - memcpy (pixels, MemBuffer, Width*Height); - } - else - { - for (int y = 0; y < Height; ++y) - { - memcpy ((BYTE *)pixels+y*pitch, MemBuffer+y*Pitch, Width); - } - } - } - - if (UsingRenderer) - { - SDL_UnlockTexture (Texture); - - SDLFlipCycles.Clock(); - SDL_RenderCopy(Renderer, Texture, NULL, &UpdateRect); - SDL_RenderPresent(Renderer); - SDLFlipCycles.Unclock(); - } - else - { - SDL_UnlockSurface (Surface); - - SDLFlipCycles.Clock(); - SDL_UpdateWindowSurface (Screen); - SDLFlipCycles.Unclock(); - } - - BlitCycles.Unclock(); - - if (NeedGammaUpdate) - { - bool Windowed = false; - NeedGammaUpdate = false; - CalcGamma ((Windowed || rgamma == 0.f) ? Gamma : (Gamma * rgamma), GammaTable[0]); - CalcGamma ((Windowed || ggamma == 0.f) ? Gamma : (Gamma * ggamma), GammaTable[1]); - CalcGamma ((Windowed || bgamma == 0.f) ? Gamma : (Gamma * bgamma), GammaTable[2]); - NeedPalUpdate = true; - } - - if (NeedPalUpdate) - { - NeedPalUpdate = false; - UpdateColors (); - } -} - -void SDLFB::UpdateColors () -{ - if (NotPaletted) - { - PalEntry palette[256]; - - for (int i = 0; i < 256; ++i) - { - palette[i].r = GammaTable[0][SourcePalette[i].r]; - palette[i].g = GammaTable[1][SourcePalette[i].g]; - palette[i].b = GammaTable[2][SourcePalette[i].b]; - } - if (FlashAmount) - { - DoBlending (palette, palette, - 256, GammaTable[0][Flash.r], GammaTable[1][Flash.g], GammaTable[2][Flash.b], - FlashAmount); - } - GPfx.SetPalette (palette); - } - else - { - SDL_Color colors[256]; - - for (int i = 0; i < 256; ++i) - { - colors[i].r = GammaTable[0][SourcePalette[i].r]; - colors[i].g = GammaTable[1][SourcePalette[i].g]; - colors[i].b = GammaTable[2][SourcePalette[i].b]; - } - if (FlashAmount) - { - DoBlending ((PalEntry *)colors, (PalEntry *)colors, - 256, GammaTable[2][Flash.b], GammaTable[1][Flash.g], GammaTable[0][Flash.r], - FlashAmount); - } - SDL_SetPaletteColors (Surface->format->palette, colors, 0, 256); - } -} - -PalEntry *SDLFB::GetPalette () -{ - return SourcePalette; -} - -void SDLFB::UpdatePalette () -{ - NeedPalUpdate = true; -} - -bool SDLFB::SetGamma (float gamma) -{ - Gamma = gamma; - NeedGammaUpdate = true; - return true; -} - -bool SDLFB::SetFlash (PalEntry rgb, int amount) -{ - Flash = rgb; - FlashAmount = amount; - NeedPalUpdate = true; - return true; -} - -void SDLFB::GetFlash (PalEntry &rgb, int &amount) -{ - rgb = Flash; - amount = FlashAmount; -} - -// Q: Should I gamma adjust the returned palette? -void SDLFB::GetFlashedPalette (PalEntry pal[256]) -{ - memcpy (pal, SourcePalette, 256*sizeof(PalEntry)); - if (FlashAmount) - { - DoBlending (pal, pal, 256, Flash.r, Flash.g, Flash.b, FlashAmount); - } -} - -void SDLFB::SetFullscreen (bool fullscreen) -{ - SDL_SetWindowFullscreen (Screen, fullscreen ? SDL_WINDOW_FULLSCREEN_DESKTOP : 0); - if (!fullscreen) - { - // Restore proper window size - SDL_SetWindowSize (Screen, Width, Height); - } - - ResetSDLRenderer (); -} - -bool SDLFB::IsFullscreen () -{ - return (SDL_GetWindowFlags (Screen) & SDL_WINDOW_FULLSCREEN_DESKTOP) != 0; -} - -void SDLFB::ResetSDLRenderer () -{ - if (Renderer) - { - if (Texture) - SDL_DestroyTexture (Texture); - SDL_DestroyRenderer (Renderer); - } - - UsingRenderer = !vid_forcesurface; - if (UsingRenderer) - { - Renderer = SDL_CreateRenderer (Screen, -1,SDL_RENDERER_ACCELERATED|SDL_RENDERER_TARGETTEXTURE| - (vid_vsync ? SDL_RENDERER_PRESENTVSYNC : 0)); - if (!Renderer) - return; - - Uint32 fmt; - switch(vid_displaybits) - { - default: fmt = SDL_PIXELFORMAT_ARGB8888; break; - case 30: fmt = SDL_PIXELFORMAT_ARGB2101010; break; - case 24: fmt = SDL_PIXELFORMAT_RGB888; break; - case 16: fmt = SDL_PIXELFORMAT_RGB565; break; - case 15: fmt = SDL_PIXELFORMAT_ARGB1555; break; - } - Texture = SDL_CreateTexture (Renderer, fmt, SDL_TEXTUREACCESS_STREAMING, Width, Height); - - { - NotPaletted = true; - - Uint32 format; - SDL_QueryTexture(Texture, &format, NULL, NULL, NULL); - - Uint32 Rmask, Gmask, Bmask, Amask; - int bpp; - SDL_PixelFormatEnumToMasks(format, &bpp, &Rmask, &Gmask, &Bmask, &Amask); - GPfx.SetFormat (bpp, Rmask, Gmask, Bmask); - } - } - else - { - Surface = SDL_GetWindowSurface (Screen); - - if (Surface->format->palette == NULL) - { - NotPaletted = true; - GPfx.SetFormat (Surface->format->BitsPerPixel, Surface->format->Rmask, Surface->format->Gmask, Surface->format->Bmask); - } - else - NotPaletted = false; - } - - // Calculate update rectangle - if (IsFullscreen ()) - { - int w, h; - SDL_GetWindowSize (Screen, &w, &h); - UpdateRect.w = w; - UpdateRect.h = h; - ScaleWithAspect (UpdateRect.w, UpdateRect.h, Width, Height); - UpdateRect.x = (w - UpdateRect.w)/2; - UpdateRect.y = (h - UpdateRect.h)/2; - } - else - { - // In windowed mode we just update the whole window. - UpdateRect.x = 0; - UpdateRect.y = 0; - UpdateRect.w = Width; - UpdateRect.h = Height; - } -} - -void SDLFB::SetVSync (bool vsync) -{ -#ifdef __APPLE__ - if (CGLContextObj context = CGLGetCurrentContext()) - { - // Apply vsync for native backend only (where OpenGL context is set) - -#if MAC_OS_X_VERSION_MAX_ALLOWED < 1050 - // Inconsistency between 10.4 and 10.5 SDKs: - // third argument of CGLSetParameter() is const long* on 10.4 and const GLint* on 10.5 - // So, GLint typedef'ed to long instead of int to workaround this issue - typedef long GLint; -#endif // prior to 10.5 - - const GLint value = vsync ? 1 : 0; - CGLSetParameter(context, kCGLCPSwapInterval, &value); - } -#else - ResetSDLRenderer (); -#endif // __APPLE__ -} - -ADD_STAT (blit) -{ - FString out; - out.Format ("blit=%04.1f ms flip=%04.1f ms", - BlitCycles.TimeMS(), SDLFlipCycles.TimeMS()); - return out; -} + +// HEADER FILES ------------------------------------------------------------ + +#include "doomtype.h" + +#include "templates.h" +#include "i_system.h" +#include "i_video.h" +#include "v_video.h" +#include "v_pfx.h" +#include "stats.h" +#include "v_palette.h" +#include "sdlvideo.h" +#include "r_swrenderer.h" +#include "version.h" + +#include + +#ifdef __APPLE__ +#include +#endif // __APPLE__ + +// MACROS ------------------------------------------------------------------ + +// TYPES ------------------------------------------------------------------- + +class SDLFB : public DFrameBuffer +{ + DECLARE_CLASS(SDLFB, DFrameBuffer) +public: + SDLFB (int width, int height, bool fullscreen); + ~SDLFB (); + + bool Lock (bool buffer); + void Unlock (); + bool Relock (); + void ForceBuffering (bool force); + bool IsValid (); + void Update (); + PalEntry *GetPalette (); + void GetFlashedPalette (PalEntry pal[256]); + void UpdatePalette (); + bool SetGamma (float gamma); + bool SetFlash (PalEntry rgb, int amount); + void GetFlash (PalEntry &rgb, int &amount); + void SetFullscreen (bool fullscreen); + int GetPageCount (); + bool IsFullscreen (); + + friend class SDLVideo; + + virtual void SetVSync (bool vsync); + +private: + PalEntry SourcePalette[256]; + BYTE GammaTable[3][256]; + PalEntry Flash; + int FlashAmount; + float Gamma; + bool UpdatePending; + + SDL_Window *Screen; + SDL_Renderer *Renderer; + union + { + SDL_Texture *Texture; + SDL_Surface *Surface; + }; + SDL_Rect UpdateRect; + + bool UsingRenderer; + bool NeedPalUpdate; + bool NeedGammaUpdate; + bool NotPaletted; + + void UpdateColors (); + void ResetSDLRenderer (); + + SDLFB () {} +}; +IMPLEMENT_CLASS(SDLFB) + +struct MiniModeInfo +{ + WORD Width, Height; +}; + +// PUBLIC FUNCTION PROTOTYPES ---------------------------------------------- + +// PRIVATE FUNCTION PROTOTYPES --------------------------------------------- + +// EXTERNAL DATA DECLARATIONS ---------------------------------------------- + +extern IVideo *Video; +extern bool GUICapture; + +EXTERN_CVAR (Float, Gamma) +EXTERN_CVAR (Int, vid_maxfps) +EXTERN_CVAR (Bool, cl_capfps) +EXTERN_CVAR (Bool, vid_vsync) + +// PUBLIC DATA DEFINITIONS ------------------------------------------------- + +CVAR (Int, vid_adapter, 0, CVAR_ARCHIVE|CVAR_GLOBALCONFIG) + +CVAR (Int, vid_displaybits, 32, CVAR_ARCHIVE|CVAR_GLOBALCONFIG) + +CVAR (Bool, vid_forcesurface, false, CVAR_ARCHIVE|CVAR_GLOBALCONFIG) + +CUSTOM_CVAR (Float, rgamma, 1.f, CVAR_ARCHIVE|CVAR_GLOBALCONFIG) +{ + if (screen != NULL) + { + screen->SetGamma (Gamma); + } +} +CUSTOM_CVAR (Float, ggamma, 1.f, CVAR_ARCHIVE|CVAR_GLOBALCONFIG) +{ + if (screen != NULL) + { + screen->SetGamma (Gamma); + } +} +CUSTOM_CVAR (Float, bgamma, 1.f, CVAR_ARCHIVE|CVAR_GLOBALCONFIG) +{ + if (screen != NULL) + { + screen->SetGamma (Gamma); + } +} + +// PRIVATE DATA DEFINITIONS ------------------------------------------------ + +// Dummy screen sizes to pass when windowed +static MiniModeInfo WinModes[] = +{ + { 320, 200 }, + { 320, 240 }, + { 400, 225 }, // 16:9 + { 400, 300 }, + { 480, 270 }, // 16:9 + { 480, 360 }, + { 512, 288 }, // 16:9 + { 512, 384 }, + { 640, 360 }, // 16:9 + { 640, 400 }, + { 640, 480 }, + { 720, 480 }, // 16:10 + { 720, 540 }, + { 800, 450 }, // 16:9 + { 800, 480 }, + { 800, 500 }, // 16:10 + { 800, 600 }, + { 848, 480 }, // 16:9 + { 960, 600 }, // 16:10 + { 960, 720 }, + { 1024, 576 }, // 16:9 + { 1024, 600 }, // 17:10 + { 1024, 640 }, // 16:10 + { 1024, 768 }, + { 1088, 612 }, // 16:9 + { 1152, 648 }, // 16:9 + { 1152, 720 }, // 16:10 + { 1152, 864 }, + { 1280, 720 }, // 16:9 + { 1280, 854 }, + { 1280, 800 }, // 16:10 + { 1280, 960 }, + { 1280, 1024 }, // 5:4 + { 1360, 768 }, // 16:9 + { 1366, 768 }, + { 1400, 787 }, // 16:9 + { 1400, 875 }, // 16:10 + { 1400, 1050 }, + { 1440, 900 }, + { 1440, 960 }, + { 1440, 1080 }, + { 1600, 900 }, // 16:9 + { 1600, 1000 }, // 16:10 + { 1600, 1200 }, + { 1920, 1080 }, + { 1920, 1200 }, + { 2048, 1536 }, + { 2560, 1440 }, + { 2560, 1600 }, + { 2560, 2048 }, + { 2880, 1800 }, + { 3200, 1800 }, + { 3840, 2160 }, + { 3840, 2400 }, + { 4096, 2160 }, + { 5120, 2880 } +}; + +static cycle_t BlitCycles; +static cycle_t SDLFlipCycles; + +// CODE -------------------------------------------------------------------- + +void ScaleWithAspect (int &w, int &h, int Width, int Height) +{ + int resRatio = CheckRatio (Width, Height); + int screenRatio; + CheckRatio (w, h, &screenRatio); + if (resRatio == screenRatio) + return; + + double yratio; + switch(resRatio) + { + case 0: yratio = 4./3.; break; + case 1: yratio = 16./9.; break; + case 2: yratio = 16./10.; break; + case 3: yratio = 17./10.; break; + case 4: yratio = 5./4.; break; + default: return; + } + double y = w/yratio; + if (y > h) + w = h*yratio; + else + h = y; +} + +SDLVideo::SDLVideo (int parm) +{ + IteratorBits = 0; +} + +SDLVideo::~SDLVideo () +{ +} + +void SDLVideo::StartModeIterator (int bits, bool fs) +{ + IteratorMode = 0; + IteratorBits = bits; +} + +bool SDLVideo::NextMode (int *width, int *height, bool *letterbox) +{ + if (IteratorBits != 8) + return false; + + if ((unsigned)IteratorMode < sizeof(WinModes)/sizeof(WinModes[0])) + { + *width = WinModes[IteratorMode].Width; + *height = WinModes[IteratorMode].Height; + ++IteratorMode; + return true; + } + return false; +} + +DFrameBuffer *SDLVideo::CreateFrameBuffer (int width, int height, bool fullscreen, DFrameBuffer *old) +{ + static int retry = 0; + static int owidth, oheight; + + PalEntry flashColor; + int flashAmount; + + if (old != NULL) + { // Reuse the old framebuffer if its attributes are the same + SDLFB *fb = static_cast (old); + if (fb->Width == width && + fb->Height == height) + { + bool fsnow = (SDL_GetWindowFlags (fb->Screen) & SDL_WINDOW_FULLSCREEN_DESKTOP) != 0; + + if (fsnow != fullscreen) + { + fb->SetFullscreen (fullscreen); + } + return old; + } + old->GetFlash (flashColor, flashAmount); + old->ObjectFlags |= OF_YesReallyDelete; + if (screen == old) screen = NULL; + delete old; + } + else + { + flashColor = 0; + flashAmount = 0; + } + + SDLFB *fb = new SDLFB (width, height, fullscreen); + retry = 0; + + // If we could not create the framebuffer, try again with slightly + // different parameters in this order: + // 1. Try with the closest size + // 2. Try in the opposite screen mode with the original size + // 3. Try in the opposite screen mode with the closest size + // This is a somewhat confusing mass of recursion here. + + while (fb == NULL || !fb->IsValid ()) + { + if (fb != NULL) + { + delete fb; + } + + switch (retry) + { + case 0: + owidth = width; + oheight = height; + case 2: + // Try a different resolution. Hopefully that will work. + I_ClosestResolution (&width, &height, 8); + break; + + case 1: + // Try changing fullscreen mode. Maybe that will work. + width = owidth; + height = oheight; + fullscreen = !fullscreen; + break; + + default: + // I give up! + I_FatalError ("Could not create new screen (%d x %d)", owidth, oheight); + } + + ++retry; + fb = static_cast(CreateFrameBuffer (width, height, fullscreen, NULL)); + } + + fb->SetFlash (flashColor, flashAmount); + + return fb; +} + +void SDLVideo::SetWindowedScale (float scale) +{ +} + +// FrameBuffer implementation ----------------------------------------------- + +SDLFB::SDLFB (int width, int height, bool fullscreen) + : DFrameBuffer (width, height) +{ + int i; + + NeedPalUpdate = false; + NeedGammaUpdate = false; + UpdatePending = false; + NotPaletted = false; + FlashAmount = 0; + + FString caption; + caption.Format(GAMESIG " %s (%s)", GetVersionString(), GetGitTime()); + + Screen = SDL_CreateWindow (caption, + SDL_WINDOWPOS_UNDEFINED_DISPLAY(vid_adapter), SDL_WINDOWPOS_UNDEFINED_DISPLAY(vid_adapter), + width, height, (fullscreen ? SDL_WINDOW_FULLSCREEN_DESKTOP : 0)); + + if (Screen == NULL) + return; + + Renderer = NULL; + Texture = NULL; + ResetSDLRenderer (); + + for (i = 0; i < 256; i++) + { + GammaTable[0][i] = GammaTable[1][i] = GammaTable[2][i] = i; + } + + memcpy (SourcePalette, GPalette.BaseColors, sizeof(PalEntry)*256); + UpdateColors (); + +#ifdef __APPLE__ + SetVSync (vid_vsync); +#endif +} + + +SDLFB::~SDLFB () +{ + if(Screen) + { + if (Renderer) + { + if (Texture) + SDL_DestroyTexture (Texture); + SDL_DestroyRenderer (Renderer); + } + + SDL_DestroyWindow (Screen); + } +} + +bool SDLFB::IsValid () +{ + return DFrameBuffer::IsValid() && Screen != NULL; +} + +int SDLFB::GetPageCount () +{ + return 1; +} + +bool SDLFB::Lock (bool buffered) +{ + return DSimpleCanvas::Lock (); +} + +bool SDLFB::Relock () +{ + return DSimpleCanvas::Lock (); +} + +void SDLFB::Unlock () +{ + if (UpdatePending && LockCount == 1) + { + Update (); + } + else if (--LockCount <= 0) + { + Buffer = NULL; + LockCount = 0; + } +} + +void SDLFB::Update () +{ + if (LockCount != 1) + { + if (LockCount > 0) + { + UpdatePending = true; + --LockCount; + } + return; + } + + DrawRateStuff (); + +#ifndef __APPLE__ + if(vid_maxfps && !cl_capfps) + { + SEMAPHORE_WAIT(FPSLimitSemaphore) + } +#endif + + Buffer = NULL; + LockCount = 0; + UpdatePending = false; + + BlitCycles.Reset(); + SDLFlipCycles.Reset(); + BlitCycles.Clock(); + + void *pixels; + int pitch; + if (UsingRenderer) + { + if (SDL_LockTexture (Texture, NULL, &pixels, &pitch)) + return; + } + else + { + if (SDL_LockSurface (Surface)) + return; + + pixels = Surface->pixels; + pitch = Surface->pitch; + } + + if (NotPaletted) + { + GPfx.Convert (MemBuffer, Pitch, + pixels, pitch, Width, Height, + FRACUNIT, FRACUNIT, 0, 0); + } + else + { + if (pitch == Pitch) + { + memcpy (pixels, MemBuffer, Width*Height); + } + else + { + for (int y = 0; y < Height; ++y) + { + memcpy ((BYTE *)pixels+y*pitch, MemBuffer+y*Pitch, Width); + } + } + } + + if (UsingRenderer) + { + SDL_UnlockTexture (Texture); + + SDLFlipCycles.Clock(); + SDL_RenderCopy(Renderer, Texture, NULL, &UpdateRect); + SDL_RenderPresent(Renderer); + SDLFlipCycles.Unclock(); + } + else + { + SDL_UnlockSurface (Surface); + + SDLFlipCycles.Clock(); + SDL_UpdateWindowSurface (Screen); + SDLFlipCycles.Unclock(); + } + + BlitCycles.Unclock(); + + if (NeedGammaUpdate) + { + bool Windowed = false; + NeedGammaUpdate = false; + CalcGamma ((Windowed || rgamma == 0.f) ? Gamma : (Gamma * rgamma), GammaTable[0]); + CalcGamma ((Windowed || ggamma == 0.f) ? Gamma : (Gamma * ggamma), GammaTable[1]); + CalcGamma ((Windowed || bgamma == 0.f) ? Gamma : (Gamma * bgamma), GammaTable[2]); + NeedPalUpdate = true; + } + + if (NeedPalUpdate) + { + NeedPalUpdate = false; + UpdateColors (); + } +} + +void SDLFB::UpdateColors () +{ + if (NotPaletted) + { + PalEntry palette[256]; + + for (int i = 0; i < 256; ++i) + { + palette[i].r = GammaTable[0][SourcePalette[i].r]; + palette[i].g = GammaTable[1][SourcePalette[i].g]; + palette[i].b = GammaTable[2][SourcePalette[i].b]; + } + if (FlashAmount) + { + DoBlending (palette, palette, + 256, GammaTable[0][Flash.r], GammaTable[1][Flash.g], GammaTable[2][Flash.b], + FlashAmount); + } + GPfx.SetPalette (palette); + } + else + { + SDL_Color colors[256]; + + for (int i = 0; i < 256; ++i) + { + colors[i].r = GammaTable[0][SourcePalette[i].r]; + colors[i].g = GammaTable[1][SourcePalette[i].g]; + colors[i].b = GammaTable[2][SourcePalette[i].b]; + } + if (FlashAmount) + { + DoBlending ((PalEntry *)colors, (PalEntry *)colors, + 256, GammaTable[2][Flash.b], GammaTable[1][Flash.g], GammaTable[0][Flash.r], + FlashAmount); + } + SDL_SetPaletteColors (Surface->format->palette, colors, 0, 256); + } +} + +PalEntry *SDLFB::GetPalette () +{ + return SourcePalette; +} + +void SDLFB::UpdatePalette () +{ + NeedPalUpdate = true; +} + +bool SDLFB::SetGamma (float gamma) +{ + Gamma = gamma; + NeedGammaUpdate = true; + return true; +} + +bool SDLFB::SetFlash (PalEntry rgb, int amount) +{ + Flash = rgb; + FlashAmount = amount; + NeedPalUpdate = true; + return true; +} + +void SDLFB::GetFlash (PalEntry &rgb, int &amount) +{ + rgb = Flash; + amount = FlashAmount; +} + +// Q: Should I gamma adjust the returned palette? +void SDLFB::GetFlashedPalette (PalEntry pal[256]) +{ + memcpy (pal, SourcePalette, 256*sizeof(PalEntry)); + if (FlashAmount) + { + DoBlending (pal, pal, 256, Flash.r, Flash.g, Flash.b, FlashAmount); + } +} + +void SDLFB::SetFullscreen (bool fullscreen) +{ + SDL_SetWindowFullscreen (Screen, fullscreen ? SDL_WINDOW_FULLSCREEN_DESKTOP : 0); + if (!fullscreen) + { + // Restore proper window size + SDL_SetWindowSize (Screen, Width, Height); + } + + ResetSDLRenderer (); +} + +bool SDLFB::IsFullscreen () +{ + return (SDL_GetWindowFlags (Screen) & SDL_WINDOW_FULLSCREEN_DESKTOP) != 0; +} + +void SDLFB::ResetSDLRenderer () +{ + if (Renderer) + { + if (Texture) + SDL_DestroyTexture (Texture); + SDL_DestroyRenderer (Renderer); + } + + UsingRenderer = !vid_forcesurface; + if (UsingRenderer) + { + Renderer = SDL_CreateRenderer (Screen, -1,SDL_RENDERER_ACCELERATED|SDL_RENDERER_TARGETTEXTURE| + (vid_vsync ? SDL_RENDERER_PRESENTVSYNC : 0)); + if (!Renderer) + return; + + Uint32 fmt; + switch(vid_displaybits) + { + default: fmt = SDL_PIXELFORMAT_ARGB8888; break; + case 30: fmt = SDL_PIXELFORMAT_ARGB2101010; break; + case 24: fmt = SDL_PIXELFORMAT_RGB888; break; + case 16: fmt = SDL_PIXELFORMAT_RGB565; break; + case 15: fmt = SDL_PIXELFORMAT_ARGB1555; break; + } + Texture = SDL_CreateTexture (Renderer, fmt, SDL_TEXTUREACCESS_STREAMING, Width, Height); + + { + NotPaletted = true; + + Uint32 format; + SDL_QueryTexture(Texture, &format, NULL, NULL, NULL); + + Uint32 Rmask, Gmask, Bmask, Amask; + int bpp; + SDL_PixelFormatEnumToMasks(format, &bpp, &Rmask, &Gmask, &Bmask, &Amask); + GPfx.SetFormat (bpp, Rmask, Gmask, Bmask); + } + } + else + { + Surface = SDL_GetWindowSurface (Screen); + + if (Surface->format->palette == NULL) + { + NotPaletted = true; + GPfx.SetFormat (Surface->format->BitsPerPixel, Surface->format->Rmask, Surface->format->Gmask, Surface->format->Bmask); + } + else + NotPaletted = false; + } + + // Calculate update rectangle + if (IsFullscreen ()) + { + int w, h; + SDL_GetWindowSize (Screen, &w, &h); + UpdateRect.w = w; + UpdateRect.h = h; + ScaleWithAspect (UpdateRect.w, UpdateRect.h, Width, Height); + UpdateRect.x = (w - UpdateRect.w)/2; + UpdateRect.y = (h - UpdateRect.h)/2; + } + else + { + // In windowed mode we just update the whole window. + UpdateRect.x = 0; + UpdateRect.y = 0; + UpdateRect.w = Width; + UpdateRect.h = Height; + } +} + +void SDLFB::SetVSync (bool vsync) +{ +#ifdef __APPLE__ + if (CGLContextObj context = CGLGetCurrentContext()) + { + // Apply vsync for native backend only (where OpenGL context is set) + +#if MAC_OS_X_VERSION_MAX_ALLOWED < 1050 + // Inconsistency between 10.4 and 10.5 SDKs: + // third argument of CGLSetParameter() is const long* on 10.4 and const GLint* on 10.5 + // So, GLint typedef'ed to long instead of int to workaround this issue + typedef long GLint; +#endif // prior to 10.5 + + const GLint value = vsync ? 1 : 0; + CGLSetParameter(context, kCGLCPSwapInterval, &value); + } +#else + ResetSDLRenderer (); +#endif // __APPLE__ +} + +ADD_STAT (blit) +{ + FString out; + out.Format ("blit=%04.1f ms flip=%04.1f ms", + BlitCycles.TimeMS(), SDLFlipCycles.TimeMS()); + return out; +} diff --git a/src/sdl/sdlvideo.h b/src/posix/sdl/sdlvideo.h similarity index 95% rename from src/sdl/sdlvideo.h rename to src/posix/sdl/sdlvideo.h index 8869f6fa7..072167b5a 100644 --- a/src/sdl/sdlvideo.h +++ b/src/posix/sdl/sdlvideo.h @@ -1,21 +1,21 @@ -#include "hardware.h" -#include "v_video.h" - -class SDLVideo : public IVideo -{ - public: - SDLVideo (int parm); - ~SDLVideo (); - - EDisplayType GetDisplayType () { return DISPLAY_Both; } - void SetWindowedScale (float scale); - - DFrameBuffer *CreateFrameBuffer (int width, int height, bool fs, DFrameBuffer *old); - - void StartModeIterator (int bits, bool fs); - bool NextMode (int *width, int *height, bool *letterbox); - -private: - int IteratorMode; - int IteratorBits; -}; +#include "hardware.h" +#include "v_video.h" + +class SDLVideo : public IVideo +{ + public: + SDLVideo (int parm); + ~SDLVideo (); + + EDisplayType GetDisplayType () { return DISPLAY_Both; } + void SetWindowedScale (float scale); + + DFrameBuffer *CreateFrameBuffer (int width, int height, bool fs, DFrameBuffer *old); + + void StartModeIterator (int bits, bool fs); + bool NextMode (int *width, int *height, bool *letterbox); + +private: + int IteratorMode; + int IteratorBits; +}; diff --git a/src/sdl/SDLMain.m b/src/sdl/SDLMain.m deleted file mode 100644 index 78c4e3d2b..000000000 --- a/src/sdl/SDLMain.m +++ /dev/null @@ -1,387 +0,0 @@ -/* SDLMain.m - main entry point for our Cocoa-ized SDL app - Initial Version: Darrell Walisser - Non-NIB-Code & other changes: Max Horn - - Feel free to customize this file to suit your needs -*/ - -#import "SDL.h" -#import -#import /* for MAXPATHLEN */ -#import - -@interface SDLMain : NSObject -@end - -/* For some reaon, Apple removed setAppleMenu from the headers in 10.4, - but the method still is there and works. To avoid warnings, we declare - it ourselves here. */ -@interface NSApplication(SDL_Missing_Methods) -- (void)setAppleMenu:(NSMenu *)menu; -@end - -/* Use this flag to determine whether we use SDLMain.nib or not */ -#define SDL_USE_NIB_FILE 0 - -/* Use this flag to determine whether we use CPS (docking) or not */ -#define SDL_USE_CPS 1 -#ifdef SDL_USE_CPS -/* Portions of CPS.h */ -typedef struct CPSProcessSerNum -{ - UInt32 lo; - UInt32 hi; -} CPSProcessSerNum; - -extern OSErr CPSGetCurrentProcess( CPSProcessSerNum *psn); -extern OSErr CPSEnableForegroundOperation( CPSProcessSerNum *psn, UInt32 _arg2, UInt32 _arg3, UInt32 _arg4, UInt32 _arg5); -extern OSErr CPSSetFrontProcess( CPSProcessSerNum *psn); - -#endif /* SDL_USE_CPS */ - -static int gArgc; -static char **gArgv; -static BOOL gFinderLaunch; -static BOOL gCalledAppMainline = FALSE; - -static NSString *getApplicationName(void) -{ - NSDictionary *dict; - NSString *appName = 0; - - /* Determine the application name */ - dict = (NSDictionary *)CFBundleGetInfoDictionary(CFBundleGetMainBundle()); - if (dict) - appName = [dict objectForKey: @"CFBundleName"]; - - if (![appName length]) - appName = [[NSProcessInfo processInfo] processName]; - - return appName; -} - -#if SDL_USE_NIB_FILE -/* A helper category for NSString */ -@interface NSString (ReplaceSubString) -- (NSString *)stringByReplacingRange:(NSRange)aRange with:(NSString *)aString; -@end -#endif - -@interface SDLApplication : NSApplication -@end - -@implementation SDLApplication -/* Invoked from the Quit menu item */ -- (void)terminate:(id)sender -{ - /* Post a SDL_QUIT event */ - SDL_Event event; - event.type = SDL_QUIT; - SDL_PushEvent(&event); -} -@end - -/* The main class of the application, the application's delegate */ -@implementation SDLMain - -/* Set the working directory to the .app's parent directory */ -- (void) setupWorkingDirectory:(BOOL)shouldChdir -{ - if (shouldChdir) - { - char parentdir[MAXPATHLEN]; - CFURLRef url = CFBundleCopyBundleURL(CFBundleGetMainBundle()); - CFURLRef url2 = CFURLCreateCopyDeletingLastPathComponent(0, url); - if (CFURLGetFileSystemRepresentation(url2, true, (UInt8 *)parentdir, MAXPATHLEN)) { - assert ( chdir (parentdir) == 0 ); /* chdir to the binary app's parent */ - } - CFRelease(url); - CFRelease(url2); - } - -} - -#if SDL_USE_NIB_FILE - -/* Fix menu to contain the real app name instead of "SDL App" */ -- (void)fixMenu:(NSMenu *)aMenu withAppName:(NSString *)appName -{ - NSRange aRange; - NSEnumerator *enumerator; - NSMenuItem *menuItem; - - aRange = [[aMenu title] rangeOfString:@"SDL App"]; - if (aRange.length != 0) - [aMenu setTitle: [[aMenu title] stringByReplacingRange:aRange with:appName]]; - - enumerator = [[aMenu itemArray] objectEnumerator]; - while ((menuItem = [enumerator nextObject])) - { - aRange = [[menuItem title] rangeOfString:@"SDL App"]; - if (aRange.length != 0) - [menuItem setTitle: [[menuItem title] stringByReplacingRange:aRange with:appName]]; - if ([menuItem hasSubmenu]) - [self fixMenu:[menuItem submenu] withAppName:appName]; - } - [ aMenu sizeToFit ]; -} - -#else - -static void setApplicationMenu(void) -{ - /* warning: this code is very odd */ - NSMenu *appleMenu; - NSMenuItem *menuItem; - NSString *title; - NSString *appName; - - appName = getApplicationName(); - appleMenu = [[NSMenu alloc] initWithTitle:@""]; - - /* Add menu items */ - title = [@"About " stringByAppendingString:appName]; - [appleMenu addItemWithTitle:title action:@selector(orderFrontStandardAboutPanel:) keyEquivalent:@""]; - - [appleMenu addItem:[NSMenuItem separatorItem]]; - - title = [@"Hide " stringByAppendingString:appName]; - [appleMenu addItemWithTitle:title action:@selector(hide:) keyEquivalent:@"h"]; - - menuItem = (NSMenuItem *)[appleMenu addItemWithTitle:@"Hide Others" action:@selector(hideOtherApplications:) keyEquivalent:@"h"]; - [menuItem setKeyEquivalentModifierMask:(NSAlternateKeyMask|NSCommandKeyMask)]; - - [appleMenu addItemWithTitle:@"Show All" action:@selector(unhideAllApplications:) keyEquivalent:@""]; - - [appleMenu addItem:[NSMenuItem separatorItem]]; - - title = [@"Quit " stringByAppendingString:appName]; - [appleMenu addItemWithTitle:title action:@selector(terminate:) keyEquivalent:@"q"]; - - - /* Put menu into the menubar */ - menuItem = [[NSMenuItem alloc] initWithTitle:@"" action:nil keyEquivalent:@""]; - [menuItem setSubmenu:appleMenu]; - [[NSApp mainMenu] addItem:menuItem]; - - /* Tell the application object that this is now the application menu */ - [NSApp setAppleMenu:appleMenu]; - - /* Finally give up our references to the objects */ - [appleMenu release]; - [menuItem release]; -} - -/* Create a window menu */ -static void setupWindowMenu(void) -{ - NSMenu *windowMenu; - NSMenuItem *windowMenuItem; - NSMenuItem *menuItem; - - windowMenu = [[NSMenu alloc] initWithTitle:@"Window"]; - - /* "Minimize" item */ - menuItem = [[NSMenuItem alloc] initWithTitle:@"Minimize" action:@selector(performMiniaturize:) keyEquivalent:@"m"]; - [windowMenu addItem:menuItem]; - [menuItem release]; - - /* Put menu into the menubar */ - windowMenuItem = [[NSMenuItem alloc] initWithTitle:@"Window" action:nil keyEquivalent:@""]; - [windowMenuItem setSubmenu:windowMenu]; - [[NSApp mainMenu] addItem:windowMenuItem]; - - /* Tell the application object that this is now the window menu */ - [NSApp setWindowsMenu:windowMenu]; - - /* Finally give up our references to the objects */ - [windowMenu release]; - [windowMenuItem release]; -} - -/* Replacement for NSApplicationMain */ -static void CustomApplicationMain (int argc, char **argv) -{ - NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; - SDLMain *sdlMain; - - /* Ensure the application object is initialised */ - [SDLApplication sharedApplication]; - -#ifdef SDL_USE_CPS - { - CPSProcessSerNum PSN; - /* Tell the dock about us */ - if (!CPSGetCurrentProcess(&PSN)) - if (!CPSEnableForegroundOperation(&PSN,0x03,0x3C,0x2C,0x1103)) - if (!CPSSetFrontProcess(&PSN)) - [SDLApplication sharedApplication]; - } -#endif /* SDL_USE_CPS */ - - /* Set up the menubar */ - [NSApp setMainMenu:[[NSMenu alloc] init]]; - setApplicationMenu(); - setupWindowMenu(); - - /* Create SDLMain and make it the app delegate */ - sdlMain = [[SDLMain alloc] init]; - [NSApp setDelegate:sdlMain]; - - /* Start the main event loop */ - [NSApp run]; - - [sdlMain release]; - [pool release]; -} - -#endif - - -/* - * Catch document open requests...this lets us notice files when the app - * was launched by double-clicking a document, or when a document was - * dragged/dropped on the app's icon. You need to have a - * CFBundleDocumentsType section in your Info.plist to get this message, - * apparently. - * - * Files are added to gArgv, so to the app, they'll look like command line - * arguments. Previously, apps launched from the finder had nothing but - * an argv[0]. - * - * This message may be received multiple times to open several docs on launch. - * - * This message is ignored once the app's mainline has been called. - */ -- (BOOL)application:(NSApplication *)theApplication openFile:(NSString *)filename -{ - const char *temparg; - size_t arglen; - char *arg; - char **newargv; - - if (!gFinderLaunch) /* MacOS is passing command line args. */ - return FALSE; - - if (gCalledAppMainline) /* app has started, ignore this document. */ - return FALSE; - - temparg = [filename UTF8String]; - arglen = SDL_strlen(temparg) + 1; - arg = (char *) SDL_malloc(arglen); - if (arg == NULL) - return FALSE; - - newargv = (char **) realloc(gArgv, sizeof (char *) * (gArgc + 2)); - if (newargv == NULL) - { - SDL_free(arg); - return FALSE; - } - gArgv = newargv; - - SDL_strlcpy(arg, temparg, arglen); - gArgv[gArgc++] = arg; - gArgv[gArgc] = NULL; - return TRUE; -} - - -/* Called when the internal event loop has just started running */ -- (void) applicationDidFinishLaunching: (NSNotification *) note -{ - int status; - - /* Set the working directory to the .app's parent directory */ - [self setupWorkingDirectory:gFinderLaunch]; - -#if SDL_USE_NIB_FILE - /* Set the main menu to contain the real app name instead of "SDL App" */ - [self fixMenu:[NSApp mainMenu] withAppName:getApplicationName()]; -#endif - - /* Hand off to main application code */ - gCalledAppMainline = TRUE; - status = SDL_main (gArgc, gArgv); - - /* We're done, thank you for playing */ - exit(status); -} -@end - - -@implementation NSString (ReplaceSubString) - -- (NSString *)stringByReplacingRange:(NSRange)aRange with:(NSString *)aString -{ - unsigned int bufferSize; - unsigned int selfLen = [self length]; - unsigned int aStringLen = [aString length]; - unichar *buffer; - NSRange localRange; - NSString *result; - - bufferSize = selfLen + aStringLen - aRange.length; - buffer = NSAllocateMemoryPages(bufferSize*sizeof(unichar)); - - /* Get first part into buffer */ - localRange.location = 0; - localRange.length = aRange.location; - [self getCharacters:buffer range:localRange]; - - /* Get middle part into buffer */ - localRange.location = 0; - localRange.length = aStringLen; - [aString getCharacters:(buffer+aRange.location) range:localRange]; - - /* Get last part into buffer */ - localRange.location = aRange.location + aRange.length; - localRange.length = selfLen - localRange.location; - [self getCharacters:(buffer+aRange.location+aStringLen) range:localRange]; - - /* Build output string */ - result = [NSString stringWithCharacters:buffer length:bufferSize]; - - NSDeallocateMemoryPages(buffer, bufferSize); - - return result; -} - -@end - - - -#ifdef main -# undef main -#endif - - -/* Main entry point to executable - should *not* be SDL_main! */ -int main (int argc, char **argv) -{ - /* Copy the arguments into a global variable */ - /* This is passed if we are launched by double-clicking */ - if ( argc >= 2 && strncmp (argv[1], "-psn", 4) == 0 ) { - gArgv = (char **) SDL_malloc(sizeof (char *) * 2); - gArgv[0] = argv[0]; - gArgv[1] = NULL; - gArgc = 1; - gFinderLaunch = YES; - } else { - int i; - gArgc = argc; - gArgv = (char **) SDL_malloc(sizeof (char *) * (argc+1)); - for (i = 0; i <= argc; i++) - gArgv[i] = argv[i]; - gFinderLaunch = NO; - } - -#if SDL_USE_NIB_FILE - [SDLApplication poseAsClass:[NSApplication class]]; - NSApplicationMain (argc, argv); -#else - CustomApplicationMain (argc, argv); -#endif - return 0; -} - From 195ed09c5efd6c40820b5b14a03e1b7ca28a7861 Mon Sep 17 00:00:00 2001 From: "alexey.lysiuk" Date: Thu, 18 Dec 2014 11:53:04 +0200 Subject: [PATCH 20/46] Fixed build of SDL output plug-in --- output_sdl/CMakeLists.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/output_sdl/CMakeLists.txt b/output_sdl/CMakeLists.txt index 289f6f48d..cc3614656 100644 --- a/output_sdl/CMakeLists.txt +++ b/output_sdl/CMakeLists.txt @@ -1,7 +1,7 @@ cmake_minimum_required( VERSION 2.4 ) add_library( output_sdl MODULE output_sdl.c ) -include_directories( ${FMOD_INCLUDE_DIR} ${SDL_INCLUDE_DIR} ) -target_link_libraries( output_sdl SDL ) +include_directories( ${FMOD_INCLUDE_DIR} ${SDL2_INCLUDE_DIR} ) +target_link_libraries( output_sdl ${SDL2_LIBRARY} ) FILE( WRITE ${CMAKE_CURRENT_BINARY_DIR}/link-make "if [ ! -e ${ZDOOM_OUTPUT_DIR}/liboutput_sdl.so ]; then ln -sf output_sdl/liboutput_sdl.so ${ZDOOM_OUTPUT_DIR}/liboutput_sdl.so; fi" ) add_custom_command( TARGET output_sdl POST_BUILD From 41c949f8ac84b1969d548edd7827f34c4c080569 Mon Sep 17 00:00:00 2001 From: "alexey.lysiuk" Date: Sat, 20 Dec 2014 13:18:47 +0200 Subject: [PATCH 21/46] Cleanup video part of native OS X backend, phase 1 --- src/posix/cocoa/i_backend_cocoa.mm | 291 +++++++---------------------- 1 file changed, 67 insertions(+), 224 deletions(-) diff --git a/src/posix/cocoa/i_backend_cocoa.mm b/src/posix/cocoa/i_backend_cocoa.mm index 571c3847b..76ec0e322 100644 --- a/src/posix/cocoa/i_backend_cocoa.mm +++ b/src/posix/cocoa/i_backend_cocoa.mm @@ -247,22 +247,6 @@ CUSTOM_CVAR(Bool, fullscreen, false, CVAR_ARCHIVE | CVAR_GLOBALCONFIG) setmodeneeded = true; } -CUSTOM_CVAR(Float, vid_winscale, 1.f, CVAR_ARCHIVE | CVAR_GLOBALCONFIG) -{ - if (self < 1.f) - { - self = 1.f; - } - else if (Video) - { - Video->SetWindowedScale (self); - NewWidth = screen->GetWidth(); - NewHeight = screen->GetHeight(); - NewBits = DisplayBits; - setmodeneeded = true; - } -} - // --------------------------------------------------------------------------- @@ -2117,21 +2101,6 @@ int SDL_QueryTexture(SDL_Texture *texture, Uint32* format, int* access, int* w, } -int SDL_LockTexture(SDL_Texture* texture, const SDL_Rect *rect, void** pixels, int *pitch) -{ - assert(NULL == rect); - - *pixels = texture->window->pixels; - *pitch = texture->window->pitch; - - return 0; -} - -void SDL_UnlockTexture(SDL_Texture *texture) -{ - ZD_UNUSED(texture); -} - int SDL_UpdateWindowSurface(SDL_Window *screen) { assert(NULL != screen); @@ -2179,31 +2148,11 @@ int SDL_UpdateWindowSurface(SDL_Window *screen) return 0; } -int SDL_RenderCopy(SDL_Renderer *renderer, SDL_Texture *texture, const SDL_Rect *srcrect, const SDL_Rect *dstrect) -{ - ZD_UNUSED(renderer); - ZD_UNUSED(texture); - ZD_UNUSED(srcrect); - ZD_UNUSED(dstrect); - - return 0; -} - void SDL_RenderPresent(SDL_Renderer *renderer) { SDL_UpdateWindowSurface(renderer->window); } -int SDL_SetPaletteColors(SDL_Palette* palette, const SDL_Color* colors, int firstcolor, int ncolors) -{ - ZD_UNUSED(palette); - ZD_UNUSED(colors); - ZD_UNUSED(firstcolor); - ZD_UNUSED(ncolors); - - return 0; -} - } // extern "C" @@ -2213,27 +2162,25 @@ int SDL_SetPaletteColors(SDL_Palette* palette, const SDL_Color* colors, int firs class CocoaVideo : public IVideo { public: - CocoaVideo(int parm); - ~CocoaVideo(); + explicit CocoaVideo(int dummy); - EDisplayType GetDisplayType () { return DISPLAY_Both; } - void SetWindowedScale (float scale); + virtual EDisplayType GetDisplayType() { return DISPLAY_Both; } + virtual void SetWindowedScale(float scale); - DFrameBuffer *CreateFrameBuffer (int width, int height, bool fs, DFrameBuffer *old); + virtual DFrameBuffer* CreateFrameBuffer(int width, int height, bool fs, DFrameBuffer* old); - void StartModeIterator (int bits, bool fs); - bool NextMode (int *width, int *height, bool *letterbox); + virtual void StartModeIterator(int bits, bool fs); + virtual bool NextMode(int* width, int* height, bool* letterbox); private: - int IteratorMode; - int IteratorBits; + size_t m_modeIterator; }; class CocoaFrameBuffer : public DFrameBuffer { public: - CocoaFrameBuffer (int width, int height, bool fullscreen); - ~CocoaFrameBuffer (); + CocoaFrameBuffer(int width, int height, bool fullscreen); + ~CocoaFrameBuffer(); bool Lock (bool buffer); void Unlock (); @@ -2270,11 +2217,9 @@ private: SDL_Texture *Texture; SDL_Surface *Surface; }; - SDL_Rect UpdateRect; bool NeedPalUpdate; bool NeedGammaUpdate; - bool NotPaletted; void UpdateColors (); void ResetSDLRenderer (); @@ -2379,66 +2324,40 @@ static MiniModeInfo WinModes[] = }; static cycle_t BlitCycles; -static cycle_t SDLFlipCycles; +static cycle_t FlipCycles; -// CODE -------------------------------------------------------------------- -void ScaleWithAspect (Uint16 &w, Uint16 &h, Uint16 Width, Uint16 Height) +CocoaVideo::CocoaVideo(int dummy) +: m_modeIterator(0) { - int resRatio = CheckRatio (Width, Height); - int screenRatio; - CheckRatio (w, h, &screenRatio); - if (resRatio == screenRatio) - return; + ZD_UNUSED(dummy); +} - double yratio; - switch(resRatio) +void CocoaVideo::StartModeIterator(int bits, bool fs) +{ + ZD_UNUSED(bits); + ZD_UNUSED(fs); + + m_modeIterator = 0; +} + +bool CocoaVideo::NextMode(int* width, int* height, bool* letterbox) +{ + ZD_UNUSED(letterbox); + + if (m_modeIterator < sizeof(WinModes) / sizeof(WinModes[0])) { - case 0: yratio = 4./3.; break; - case 1: yratio = 16./9.; break; - case 2: yratio = 16./10.; break; - case 3: yratio = 17./10.; break; - case 4: yratio = 5./4.; break; - default: return; - } - double y = w/yratio; - if (y > h) - w = h*yratio; - else - h = y; -} + *width = WinModes[m_modeIterator].Width; + *height = WinModes[m_modeIterator].Height; -CocoaVideo::CocoaVideo (int parm) -{ - IteratorBits = 0; -} - -CocoaVideo::~CocoaVideo () -{ -} - -void CocoaVideo::StartModeIterator (int bits, bool fs) -{ - IteratorMode = 0; - IteratorBits = bits; -} - -bool CocoaVideo::NextMode (int *width, int *height, bool *letterbox) -{ - if (IteratorBits != 8) - return false; - - if ((unsigned)IteratorMode < sizeof(WinModes)/sizeof(WinModes[0])) - { - *width = WinModes[IteratorMode].Width; - *height = WinModes[IteratorMode].Height; - ++IteratorMode; + ++m_modeIterator; return true; } + return false; } -DFrameBuffer *CocoaVideo::CreateFrameBuffer (int width, int height, bool fullscreen, DFrameBuffer *old) +DFrameBuffer *CocoaVideo::CreateFrameBuffer(int width, int height, bool fullscreen, DFrameBuffer* old) { static int retry = 0; static int owidth, oheight; @@ -2525,16 +2444,13 @@ void CocoaVideo::SetWindowedScale (float scale) CocoaFrameBuffer::CocoaFrameBuffer (int width, int height, bool fullscreen) -: DFrameBuffer (width, height) +: DFrameBuffer(width, height) +, FlashAmount(0) +, Gamma(0.0f) +, UpdatePending(false) +, NeedPalUpdate(false) +, NeedGammaUpdate(false) { - int i; - - NeedPalUpdate = false; - NeedGammaUpdate = false; - UpdatePending = false; - NotPaletted = false; - FlashAmount = 0; - FString caption; caption.Format(GAMESIG " %s (%s)", GetVersionString(), GetGitTime()); @@ -2548,7 +2464,7 @@ CocoaFrameBuffer::CocoaFrameBuffer (int width, int height, bool fullscreen) Texture = NULL; ResetSDLRenderer (); - for (i = 0; i < 256; i++) + for (size_t i = 0; i < 256; ++i) { GammaTable[0][i] = GammaTable[1][i] = GammaTable[2][i] = i; } @@ -2627,42 +2543,15 @@ void CocoaFrameBuffer::Update () UpdatePending = false; BlitCycles.Reset(); - SDLFlipCycles.Reset(); + FlipCycles.Reset(); BlitCycles.Clock(); - void *pixels; - int pitch; + GPfx.Convert(MemBuffer, Pitch, Texture->window->pixels, Texture->window->pitch, + Width, Height, FRACUNIT, FRACUNIT, 0, 0); - if (SDL_LockTexture (Texture, NULL, &pixels, &pitch)) - return; - - if (NotPaletted) - { - GPfx.Convert (MemBuffer, Pitch, - pixels, pitch, Width, Height, - FRACUNIT, FRACUNIT, 0, 0); - } - else - { - if (pitch == Pitch) - { - memcpy (pixels, MemBuffer, Width*Height); - } - else - { - for (int y = 0; y < Height; ++y) - { - memcpy ((BYTE *)pixels+y*pitch, MemBuffer+y*Pitch, Width); - } - } - } - - SDL_UnlockTexture (Texture); - - SDLFlipCycles.Clock(); - SDL_RenderCopy(Renderer, Texture, NULL, &UpdateRect); + FlipCycles.Clock(); SDL_RenderPresent(Renderer); - SDLFlipCycles.Unclock(); + FlipCycles.Unclock(); BlitCycles.Unclock(); @@ -2685,42 +2574,23 @@ void CocoaFrameBuffer::Update () void CocoaFrameBuffer::UpdateColors () { - if (NotPaletted) - { - PalEntry palette[256]; + PalEntry palette[256]; - for (int i = 0; i < 256; ++i) - { - palette[i].r = GammaTable[0][SourcePalette[i].r]; - palette[i].g = GammaTable[1][SourcePalette[i].g]; - palette[i].b = GammaTable[2][SourcePalette[i].b]; - } - if (FlashAmount) - { - DoBlending (palette, palette, - 256, GammaTable[0][Flash.r], GammaTable[1][Flash.g], GammaTable[2][Flash.b], - FlashAmount); - } - GPfx.SetPalette (palette); - } - else + for (size_t i = 0; i < 256; ++i) { - SDL_Color colors[256]; - - for (int i = 0; i < 256; ++i) - { - colors[i].r = GammaTable[0][SourcePalette[i].r]; - colors[i].g = GammaTable[1][SourcePalette[i].g]; - colors[i].b = GammaTable[2][SourcePalette[i].b]; - } - if (FlashAmount) - { - DoBlending ((PalEntry *)colors, (PalEntry *)colors, - 256, GammaTable[2][Flash.b], GammaTable[1][Flash.g], GammaTable[0][Flash.r], - FlashAmount); - } - SDL_SetPaletteColors (Surface->format->palette, colors, 0, 256); + palette[i].r = GammaTable[0][SourcePalette[i].r]; + palette[i].g = GammaTable[1][SourcePalette[i].g]; + palette[i].b = GammaTable[2][SourcePalette[i].b]; } + + if (FlashAmount) + { + DoBlending(palette, palette, 256, + GammaTable[0][Flash.r], GammaTable[1][Flash.g], GammaTable[2][Flash.b], + FlashAmount); + } + + GPfx.SetPalette (palette); } PalEntry *CocoaFrameBuffer::GetPalette () @@ -2728,7 +2598,7 @@ PalEntry *CocoaFrameBuffer::GetPalette () return SourcePalette; } -void CocoaFrameBuffer::UpdatePalette () +void CocoaFrameBuffer::UpdatePalette() { NeedPalUpdate = true; } @@ -2806,37 +2676,13 @@ void CocoaFrameBuffer::ResetSDLRenderer () // } Texture = SDL_CreateTexture (Renderer, fmt, SDL_TEXTUREACCESS_STREAMING, Width, Height); - { - NotPaletted = true; + Uint32 format; + SDL_QueryTexture(Texture, &format, NULL, NULL, NULL); - Uint32 format; - SDL_QueryTexture(Texture, &format, NULL, NULL, NULL); - - Uint32 Rmask, Gmask, Bmask, Amask; - int bpp; - SDL_PixelFormatEnumToMasks(format, &bpp, &Rmask, &Gmask, &Bmask, &Amask); - GPfx.SetFormat (bpp, Rmask, Gmask, Bmask); - } - - // Calculate update rectangle - if (IsFullscreen ()) - { - int w, h; - SDL_GetWindowSize (Screen, &w, &h); - UpdateRect.w = w; - UpdateRect.h = h; - ScaleWithAspect (UpdateRect.w, UpdateRect.h, Width, Height); - UpdateRect.x = (w - UpdateRect.w)/2; - UpdateRect.y = (h - UpdateRect.h)/2; - } - else - { - // In windowed mode we just update the whole window. - UpdateRect.x = 0; - UpdateRect.y = 0; - UpdateRect.w = Width; - UpdateRect.h = Height; - } + Uint32 Rmask, Gmask, Bmask, Amask; + int bpp; + SDL_PixelFormatEnumToMasks(format, &bpp, &Rmask, &Gmask, &Bmask, &Amask); + GPfx.SetFormat (bpp, Rmask, Gmask, Bmask); } void CocoaFrameBuffer::SetVSync (bool vsync) @@ -2855,11 +2701,10 @@ void CocoaFrameBuffer::SetVSync (bool vsync) } } -ADD_STAT (blit) +ADD_STAT(blit) { FString out; - out.Format ("blit=%04.1f ms flip=%04.1f ms", - BlitCycles.TimeMS(), SDLFlipCycles.TimeMS()); + out.Format("blit=%04.1f ms flip=%04.1f ms", BlitCycles.TimeMS(), FlipCycles.TimeMS()); return out; } @@ -2892,8 +2737,6 @@ void I_InitGraphics () I_FatalError ("Failed to initialize display"); atterm (I_ShutdownGraphics); - - Video->SetWindowedScale (vid_winscale); } static void I_DeleteRenderer() From 797cf624df2d401fe8f9a5f996489329ace36fa4 Mon Sep 17 00:00:00 2001 From: "alexey.lysiuk" Date: Sat, 20 Dec 2014 15:03:36 +0200 Subject: [PATCH 22/46] Cleanup video part of native OS X backend, phase 2 --- src/posix/cocoa/i_backend_cocoa.mm | 364 +++++++++-------------------- 1 file changed, 115 insertions(+), 249 deletions(-) diff --git a/src/posix/cocoa/i_backend_cocoa.mm b/src/posix/cocoa/i_backend_cocoa.mm index 76ec0e322..a4ad1a4b8 100644 --- a/src/posix/cocoa/i_backend_cocoa.mm +++ b/src/posix/cocoa/i_backend_cocoa.mm @@ -201,7 +201,6 @@ RenderBufferOptions rbOpts; EXTERN_CVAR(Bool, ticker ) EXTERN_CVAR(Bool, vid_hidpi ) EXTERN_CVAR(Bool, vid_vsync ) -EXTERN_CVAR(Int, vid_adapter ) EXTERN_CVAR(Int, vid_defwidth ) EXTERN_CVAR(Int, vid_defheight) @@ -1957,21 +1956,6 @@ typedef uint32_t Uint32; } SDL_TextureAccess; - - -SDL_bool SDL_PixelFormatEnumToMasks(Uint32 format, int* bpp, Uint32* Rmask, Uint32* Gmask, Uint32* Bmask, Uint32* Amask) -{ - //assert(format == SDL_PIXELFORMAT_ABGR8888); - - *bpp = 32; - *Rmask = 0x000000FF; - *Gmask = 0x0000FF00; - *Bmask = 0x00FF0000; - *Amask = 0xFF000000; - - return SDL_TRUE; -} - struct SDL_Window { Uint32 flags; @@ -2016,27 +2000,6 @@ Uint32 SDL_GetWindowFlags(SDL_Window *window) return window->flags; } -SDL_Surface *SDL_GetWindowSurface(SDL_Window *window) -{ - ZD_UNUSED(window); - return NULL; -} - -void SDL_GetWindowSize(SDL_Window *window, int *w, int *h) -{ - *w = window->w; - *h = window->h; -} - -void SDL_SetWindowSize(SDL_Window *window, int w, int h) -{ - // Currently this is used for handling the fullscreen->windowed transition. - // We can just no-op this for now. - ZD_UNUSED(window); - ZD_UNUSED(w); - ZD_UNUSED(h); -} - int SDL_SetWindowFullscreen(SDL_Window* window, Uint32 flags) { if ((window->flags & SDL_WINDOW_FULLSCREEN_DESKTOP) == (flags & SDL_WINDOW_FULLSCREEN_DESKTOP)) @@ -2059,48 +2022,6 @@ int SDL_SetWindowFullscreen(SDL_Window* window, Uint32 flags) return 0; } -SDL_Renderer *SDL_CreateRenderer(SDL_Window *window, int index, Uint32 flags) -{ - ZD_UNUSED(index); - ZD_UNUSED(flags); - - static SDL_Renderer result; - result.window = window; - - return &result; -} -void SDL_DestroyRenderer(SDL_Renderer *renderer) -{ - ZD_UNUSED(renderer); -} - -SDL_Texture *SDL_CreateTexture(SDL_Renderer *renderer, Uint32 format, int access, int w, int h) -{ - ZD_UNUSED(format); - ZD_UNUSED(access); - ZD_UNUSED(w); - ZD_UNUSED(h); - - static SDL_Texture result; - result.window = renderer->window; - - return &result; -} -void SDL_DestroyTexture(SDL_Texture *texture) -{ - ZD_UNUSED(texture); -} - -int SDL_QueryTexture(SDL_Texture *texture, Uint32* format, int* access, int* w, int* h) -{ - if(format) *format = 0; //SDL_PIXELFORMAT_ABGR8888; - if(access) *access = SDL_TEXTUREACCESS_STREAMING; - if(w) *w = texture->window->w; - if(h) *h = texture->window->h; - return 0; -} - - int SDL_UpdateWindowSurface(SDL_Window *screen) { assert(NULL != screen); @@ -2176,31 +2097,34 @@ private: size_t m_modeIterator; }; + class CocoaFrameBuffer : public DFrameBuffer { public: CocoaFrameBuffer(int width, int height, bool fullscreen); ~CocoaFrameBuffer(); - bool Lock (bool buffer); - void Unlock (); - bool Relock (); - void ForceBuffering (bool force); - bool IsValid (); - void Update (); - PalEntry *GetPalette (); - void GetFlashedPalette (PalEntry pal[256]); - void UpdatePalette (); - bool SetGamma (float gamma); - bool SetFlash (PalEntry rgb, int amount); - void GetFlash (PalEntry &rgb, int &amount); - void SetFullscreen (bool fullscreen); - int GetPageCount (); - bool IsFullscreen (); + virtual bool IsValid(); - friend class CocoaVideo; + virtual bool Lock(bool buffer); + virtual void Unlock(); + virtual void Update(); + + virtual PalEntry* GetPalette(); + virtual void GetFlashedPalette(PalEntry pal[256]); + virtual void UpdatePalette(); + + virtual bool SetGamma(float gamma); + virtual bool SetFlash(PalEntry rgb, int amount); + virtual void GetFlash(PalEntry &rgb, int &amount); - virtual void SetVSync (bool vsync); + virtual int GetPageCount(); + + virtual bool IsFullscreen(); + + virtual void SetVSync(bool vsync); + + void SetFullscreen(bool fullscreen); private: PalEntry SourcePalette[256]; @@ -2211,102 +2135,96 @@ private: bool UpdatePending; SDL_Window *Screen; - SDL_Renderer *Renderer; - union - { - SDL_Texture *Texture; - SDL_Surface *Surface; - }; bool NeedPalUpdate; bool NeedGammaUpdate; - void UpdateColors (); - void ResetSDLRenderer (); - - CocoaFrameBuffer () {} + void UpdateColors(); }; -struct MiniModeInfo -{ - WORD Width, Height; -}; + +// --------------------------------------------------------------------------- EXTERN_CVAR (Float, Gamma) -CVAR (Int, vid_adapter, 0, CVAR_ARCHIVE|CVAR_GLOBALCONFIG) - -CVAR (Int, vid_displaybits, 32, CVAR_ARCHIVE|CVAR_GLOBALCONFIG) - -CVAR (Bool, vid_forcesurface, false, CVAR_ARCHIVE|CVAR_GLOBALCONFIG) - -CUSTOM_CVAR (Float, rgamma, 1.f, CVAR_ARCHIVE|CVAR_GLOBALCONFIG) +CUSTOM_CVAR (Float, rgamma, 1.0f, CVAR_ARCHIVE | CVAR_GLOBALCONFIG) { - if (screen != NULL) + if (NULL != screen) { - screen->SetGamma (Gamma); - } -} -CUSTOM_CVAR (Float, ggamma, 1.f, CVAR_ARCHIVE|CVAR_GLOBALCONFIG) -{ - if (screen != NULL) - { - screen->SetGamma (Gamma); - } -} -CUSTOM_CVAR (Float, bgamma, 1.f, CVAR_ARCHIVE|CVAR_GLOBALCONFIG) -{ - if (screen != NULL) - { - screen->SetGamma (Gamma); + screen->SetGamma(Gamma); } } -static MiniModeInfo WinModes[] = +CUSTOM_CVAR (Float, ggamma, 1.0f, CVAR_ARCHIVE | CVAR_GLOBALCONFIG) { - { 320, 200 }, - { 320, 240 }, - { 400, 225 }, // 16:9 - { 400, 300 }, - { 480, 270 }, // 16:9 - { 480, 360 }, - { 512, 288 }, // 16:9 - { 512, 384 }, - { 640, 360 }, // 16:9 - { 640, 400 }, - { 640, 480 }, - { 720, 480 }, // 16:10 - { 720, 540 }, - { 800, 450 }, // 16:9 - { 800, 480 }, - { 800, 500 }, // 16:10 - { 800, 600 }, - { 848, 480 }, // 16:9 - { 960, 600 }, // 16:10 - { 960, 720 }, - { 1024, 576 }, // 16:9 - { 1024, 600 }, // 17:10 - { 1024, 640 }, // 16:10 - { 1024, 768 }, - { 1088, 612 }, // 16:9 - { 1152, 648 }, // 16:9 - { 1152, 720 }, // 16:10 - { 1152, 864 }, - { 1280, 720 }, // 16:9 - { 1280, 854 }, - { 1280, 800 }, // 16:10 - { 1280, 960 }, + if (NULL != screen) + { + screen->SetGamma(Gamma); + } +} + +CUSTOM_CVAR (Float, bgamma, 1.0f, CVAR_ARCHIVE | CVAR_GLOBALCONFIG) +{ + if (NULL != screen) + { + screen->SetGamma(Gamma); + } +} + + +// --------------------------------------------------------------------------- + + +static const struct MiniModeInfo +{ + uint16_t width; + uint16_t height; +} +VideoModes[] = +{ + { 320, 200 }, + { 320, 240 }, + { 400, 225 }, // 16:9 + { 400, 300 }, + { 480, 270 }, // 16:9 + { 480, 360 }, + { 512, 288 }, // 16:9 + { 512, 384 }, + { 640, 360 }, // 16:9 + { 640, 400 }, + { 640, 480 }, + { 720, 480 }, // 16:10 + { 720, 540 }, + { 800, 450 }, // 16:9 + { 800, 480 }, + { 800, 500 }, // 16:10 + { 800, 600 }, + { 848, 480 }, // 16:9 + { 960, 600 }, // 16:10 + { 960, 720 }, + { 1024, 576 }, // 16:9 + { 1024, 600 }, // 17:10 + { 1024, 640 }, // 16:10 + { 1024, 768 }, + { 1088, 612 }, // 16:9 + { 1152, 648 }, // 16:9 + { 1152, 720 }, // 16:10 + { 1152, 864 }, + { 1280, 720 }, // 16:9 + { 1280, 854 }, + { 1280, 800 }, // 16:10 + { 1280, 960 }, { 1280, 1024 }, // 5:4 - { 1360, 768 }, // 16:9 - { 1366, 768 }, - { 1400, 787 }, // 16:9 - { 1400, 875 }, // 16:10 + { 1360, 768 }, // 16:9 + { 1366, 768 }, + { 1400, 787 }, // 16:9 + { 1400, 875 }, // 16:10 { 1400, 1050 }, - { 1440, 900 }, - { 1440, 960 }, + { 1440, 900 }, + { 1440, 960 }, { 1440, 1080 }, - { 1600, 900 }, // 16:9 + { 1600, 900 }, // 16:9 { 1600, 1000 }, // 16:10 { 1600, 1200 }, { 1920, 1080 }, @@ -2323,10 +2241,14 @@ static MiniModeInfo WinModes[] = { 5120, 2880 } }; + static cycle_t BlitCycles; static cycle_t FlipCycles; +// --------------------------------------------------------------------------- + + CocoaVideo::CocoaVideo(int dummy) : m_modeIterator(0) { @@ -2345,10 +2267,10 @@ bool CocoaVideo::NextMode(int* width, int* height, bool* letterbox) { ZD_UNUSED(letterbox); - if (m_modeIterator < sizeof(WinModes) / sizeof(WinModes[0])) + if (m_modeIterator < sizeof(VideoModes) / sizeof(VideoModes[0])) { - *width = WinModes[m_modeIterator].Width; - *height = WinModes[m_modeIterator].Height; + *width = VideoModes[m_modeIterator].width; + *height = VideoModes[m_modeIterator].height; ++m_modeIterator; return true; @@ -2357,7 +2279,7 @@ bool CocoaVideo::NextMode(int* width, int* height, bool* letterbox) return false; } -DFrameBuffer *CocoaVideo::CreateFrameBuffer(int width, int height, bool fullscreen, DFrameBuffer* old) +DFrameBuffer* CocoaVideo::CreateFrameBuffer(int width, int height, bool fullscreen, DFrameBuffer* old) { static int retry = 0; static int owidth, oheight; @@ -2368,15 +2290,14 @@ DFrameBuffer *CocoaVideo::CreateFrameBuffer(int width, int height, bool fullscre if (old != NULL) { // Reuse the old framebuffer if its attributes are the same CocoaFrameBuffer *fb = static_cast (old); - if (fb->Width == width && - fb->Height == height) + if (fb->GetWidth() == width && + fb->GetHeight() == height) { - bool fsnow = (SDL_GetWindowFlags (fb->Screen) & SDL_WINDOW_FULLSCREEN_DESKTOP) != 0; - - if (fsnow != fullscreen) + if (fb->IsFullscreen() != fullscreen) { fb->SetFullscreen (fullscreen); } + return old; } old->GetFlash (flashColor, flashAmount); @@ -2460,19 +2381,17 @@ CocoaFrameBuffer::CocoaFrameBuffer (int width, int height, bool fullscreen) if (Screen == NULL) return; - Renderer = NULL; - Texture = NULL; - ResetSDLRenderer (); + GPfx.SetFormat(32, 0x000000FF, 0x0000FF00, 0x00FF0000); for (size_t i = 0; i < 256; ++i) { GammaTable[0][i] = GammaTable[1][i] = GammaTable[2][i] = i; } - memcpy (SourcePalette, GPalette.BaseColors, sizeof(PalEntry)*256); - UpdateColors (); + memcpy(SourcePalette, GPalette.BaseColors, sizeof(PalEntry) * 256); + UpdateColors(); - SetVSync (vid_vsync); + SetVSync(vid_vsync); } @@ -2480,13 +2399,6 @@ CocoaFrameBuffer::~CocoaFrameBuffer () { if(Screen) { - if (Renderer) - { - if (Texture) - SDL_DestroyTexture (Texture); - SDL_DestroyRenderer (Renderer); - } - SDL_DestroyWindow (Screen); } } @@ -2506,11 +2418,6 @@ bool CocoaFrameBuffer::Lock (bool buffered) return DSimpleCanvas::Lock (); } -bool CocoaFrameBuffer::Relock () -{ - return DSimpleCanvas::Lock (); -} - void CocoaFrameBuffer::Unlock () { if (UpdatePending && LockCount == 1) @@ -2546,11 +2453,11 @@ void CocoaFrameBuffer::Update () FlipCycles.Reset(); BlitCycles.Clock(); - GPfx.Convert(MemBuffer, Pitch, Texture->window->pixels, Texture->window->pitch, + GPfx.Convert(MemBuffer, Pitch, [appCtrl softwareRenderingBuffer], Width * BYTES_PER_PIXEL, Width, Height, FRACUNIT, FRACUNIT, 0, 0); FlipCycles.Clock(); - SDL_RenderPresent(Renderer); + SDL_UpdateWindowSurface(Screen); FlipCycles.Unclock(); BlitCycles.Unclock(); @@ -2559,20 +2466,20 @@ void CocoaFrameBuffer::Update () { bool Windowed = false; NeedGammaUpdate = false; - CalcGamma ((Windowed || rgamma == 0.f) ? Gamma : (Gamma * rgamma), GammaTable[0]); - CalcGamma ((Windowed || ggamma == 0.f) ? Gamma : (Gamma * ggamma), GammaTable[1]); - CalcGamma ((Windowed || bgamma == 0.f) ? Gamma : (Gamma * bgamma), GammaTable[2]); + CalcGamma((Windowed || rgamma == 0.f) ? Gamma : (Gamma * rgamma), GammaTable[0]); + CalcGamma((Windowed || ggamma == 0.f) ? Gamma : (Gamma * ggamma), GammaTable[1]); + CalcGamma((Windowed || bgamma == 0.f) ? Gamma : (Gamma * bgamma), GammaTable[2]); NeedPalUpdate = true; } if (NeedPalUpdate) { NeedPalUpdate = false; - UpdateColors (); + UpdateColors(); } } -void CocoaFrameBuffer::UpdateColors () +void CocoaFrameBuffer::UpdateColors() { PalEntry palette[256]; @@ -2590,7 +2497,7 @@ void CocoaFrameBuffer::UpdateColors () FlashAmount); } - GPfx.SetPalette (palette); + GPfx.SetPalette(palette); } PalEntry *CocoaFrameBuffer::GetPalette () @@ -2637,13 +2544,6 @@ void CocoaFrameBuffer::GetFlashedPalette (PalEntry pal[256]) void CocoaFrameBuffer::SetFullscreen (bool fullscreen) { SDL_SetWindowFullscreen (Screen, fullscreen ? SDL_WINDOW_FULLSCREEN_DESKTOP : 0); - if (!fullscreen) - { - // Restore proper window size - SDL_SetWindowSize (Screen, Width, Height); - } - - ResetSDLRenderer (); } bool CocoaFrameBuffer::IsFullscreen () @@ -2651,40 +2551,6 @@ bool CocoaFrameBuffer::IsFullscreen () return (SDL_GetWindowFlags (Screen) & SDL_WINDOW_FULLSCREEN_DESKTOP) != 0; } -void CocoaFrameBuffer::ResetSDLRenderer () -{ - if (Renderer) - { - if (Texture) - SDL_DestroyTexture (Texture); - SDL_DestroyRenderer (Renderer); - } - - Renderer = SDL_CreateRenderer (Screen, -1,SDL_RENDERER_ACCELERATED|SDL_RENDERER_TARGETTEXTURE| - (vid_vsync ? SDL_RENDERER_PRESENTVSYNC : 0)); - if (!Renderer) - return; - - Uint32 fmt = 0; -// switch(vid_displaybits) -// { -// default: fmt = SDL_PIXELFORMAT_ARGB8888; break; -// case 30: fmt = SDL_PIXELFORMAT_ARGB2101010; break; -// case 24: fmt = SDL_PIXELFORMAT_RGB888; break; -// case 16: fmt = SDL_PIXELFORMAT_RGB565; break; -// case 15: fmt = SDL_PIXELFORMAT_ARGB1555; break; -// } - Texture = SDL_CreateTexture (Renderer, fmt, SDL_TEXTUREACCESS_STREAMING, Width, Height); - - Uint32 format; - SDL_QueryTexture(Texture, &format, NULL, NULL, NULL); - - Uint32 Rmask, Gmask, Bmask, Amask; - int bpp; - SDL_PixelFormatEnumToMasks(format, &bpp, &Rmask, &Gmask, &Bmask, &Amask); - GPfx.SetFormat (bpp, Rmask, Gmask, Bmask); -} - void CocoaFrameBuffer::SetVSync (bool vsync) { if (CGLContextObj context = CGLGetCurrentContext()) From ebc0916bc6008856809eab54091308dd8ce53e55 Mon Sep 17 00:00:00 2001 From: "alexey.lysiuk" Date: Sat, 20 Dec 2014 17:20:45 +0200 Subject: [PATCH 23/46] Cleanup video part of native OS X backend, phase 3 --- src/posix/cocoa/i_backend_cocoa.mm | 160 ++--------------------------- 1 file changed, 10 insertions(+), 150 deletions(-) diff --git a/src/posix/cocoa/i_backend_cocoa.mm b/src/posix/cocoa/i_backend_cocoa.mm index a4ad1a4b8..b15c4b0ca 100644 --- a/src/posix/cocoa/i_backend_cocoa.mm +++ b/src/posix/cocoa/i_backend_cocoa.mm @@ -1817,157 +1817,22 @@ bool I_SetCursor(FTexture* cursorpic) extern "C" { - typedef enum - { - SDL_FALSE = 0, - SDL_TRUE = 1 - } SDL_bool; - -typedef int8_t Sint8; -typedef uint8_t Uint8; -typedef int16_t Sint16; -typedef uint16_t Uint16; -typedef int32_t Sint32; -typedef uint32_t Uint32; - - typedef enum - { - SDL_WINDOW_FULLSCREEN = 0x00000001, /**< fullscreen window */ - SDL_WINDOW_OPENGL = 0x00000002, /**< window usable with OpenGL context */ - SDL_WINDOW_SHOWN = 0x00000004, /**< window is visible */ - SDL_WINDOW_HIDDEN = 0x00000008, /**< window is not visible */ - SDL_WINDOW_BORDERLESS = 0x00000010, /**< no window decoration */ - SDL_WINDOW_RESIZABLE = 0x00000020, /**< window can be resized */ - SDL_WINDOW_MINIMIZED = 0x00000040, /**< window is minimized */ - SDL_WINDOW_MAXIMIZED = 0x00000080, /**< window is maximized */ - SDL_WINDOW_INPUT_GRABBED = 0x00000100, /**< window has grabbed input focus */ - SDL_WINDOW_INPUT_FOCUS = 0x00000200, /**< window has input focus */ - SDL_WINDOW_MOUSE_FOCUS = 0x00000400, /**< window has mouse focus */ - SDL_WINDOW_FULLSCREEN_DESKTOP = ( SDL_WINDOW_FULLSCREEN | 0x00001000 ), - SDL_WINDOW_FOREIGN = 0x00000800, /**< window not created by SDL */ - SDL_WINDOW_ALLOW_HIGHDPI = 0x00002000 /**< window should be created in high-DPI mode if supported */ - } SDL_WindowFlags; - - - typedef struct SDL_Rect { - Sint16 x, y; - Uint16 w, h; - } SDL_Rect; - - typedef struct SDL_Color { - Uint8 r; - Uint8 g; - Uint8 b; - Uint8 unused; - } SDL_Color; - - - typedef struct SDL_Palette { - int ncolors; - SDL_Color *colors; - } SDL_Palette; - - typedef struct SDL_PixelFormat { - SDL_Palette *palette; - Uint8 BitsPerPixel; - Uint8 BytesPerPixel; - Uint8 Rloss; - Uint8 Gloss; - Uint8 Bloss; - Uint8 Aloss; - Uint8 Rshift; - Uint8 Gshift; - Uint8 Bshift; - Uint8 Ashift; - Uint32 Rmask; - Uint32 Gmask; - Uint32 Bmask; - Uint32 Amask; - - /** RGB color key information */ - Uint32 colorkey; - /** Alpha value information (per-surface alpha) */ - Uint8 alpha; - } SDL_PixelFormat; - - /** This structure should be treated as read-only, except for 'pixels', - * which, if not NULL, contains the raw pixel data for the surface. - */ - typedef struct SDL_Surface { - Uint32 flags; /**< Read-only */ - SDL_PixelFormat *format; /**< Read-only */ - int w, h; /**< Read-only */ - Uint16 pitch; /**< Read-only */ - void *pixels; /**< Read-write */ - int offset; /**< Private */ - - /** Hardware-specific surface info */ - struct private_hwdata *hwdata; - - /** clipping information */ - SDL_Rect clip_rect; /**< Read-only */ - Uint32 unused1; /**< for binary compatibility */ - - /** Allow recursive locks */ - Uint32 locked; /**< Private */ - - /** info for fast blit mapping to other surfaces */ - struct SDL_BlitMap *map; /**< Private */ - - /** format version, bumped at every change to invalidate blit maps */ - unsigned int format_version; /**< Private */ - - /** Reference count -- used when freeing surface */ - int refcount; /**< Read-mostly */ - } SDL_Surface; - - typedef enum - { - SDL_RENDERER_SOFTWARE = 0x00000001, /**< The renderer is a software fallback */ - SDL_RENDERER_ACCELERATED = 0x00000002, /**< The renderer uses hardware - acceleration */ - SDL_RENDERER_PRESENTVSYNC = 0x00000004, /**< Present is synchronized - with the refresh rate */ - SDL_RENDERER_TARGETTEXTURE = 0x00000008 /**< The renderer supports - rendering to texture */ - } SDL_RendererFlags; - - /** - * \brief Information on the capabilities of a render driver or context. - */ - typedef struct SDL_RendererInfo - { - const char *name; /**< The name of the renderer */ - Uint32 flags; /**< Supported ::SDL_RendererFlags */ - Uint32 num_texture_formats; /**< The number of available texture formats */ - Uint32 texture_formats[16]; /**< The available texture formats */ - int max_texture_width; /**< The maximimum texture width */ - int max_texture_height; /**< The maximimum texture height */ - } SDL_RendererInfo; - - /** - * \brief The access pattern allowed for a texture. - */ - typedef enum - { - SDL_TEXTUREACCESS_STATIC, /**< Changes rarely, not lockable */ - SDL_TEXTUREACCESS_STREAMING, /**< Changes frequently, lockable */ - SDL_TEXTUREACCESS_TARGET /**< Texture can be used as a render target */ - } SDL_TextureAccess; - +typedef enum +{ + SDL_WINDOW_FULLSCREEN = 0x00000001, /**< fullscreen window */ + SDL_WINDOW_OPENGL = 0x00000002, /**< window usable with OpenGL context */ + SDL_WINDOW_FULLSCREEN_DESKTOP = ( SDL_WINDOW_FULLSCREEN | 0x00001000 ), +} SDL_WindowFlags; struct SDL_Window { - Uint32 flags; + uint32_t flags; int w, h; int pitch; void *pixels; }; -struct SDL_Renderer { SDL_Window *window; }; -struct SDL_Texture { SDL_Window *window; }; - -SDL_Window* SDL_CreateWindow(const char* title, int x, int y, int width, int height, Uint32 flags) +SDL_Window* SDL_CreateWindow(const char* title, int x, int y, int width, int height, uint32_t flags) { [appCtrl changeVideoResolution:(SDL_WINDOW_FULLSCREEN_DESKTOP & flags) width:width @@ -1995,12 +1860,12 @@ void SDL_DestroyWindow(SDL_Window *window) ZD_UNUSED(window); } -Uint32 SDL_GetWindowFlags(SDL_Window *window) +uint32_t SDL_GetWindowFlags(SDL_Window *window) { return window->flags; } -int SDL_SetWindowFullscreen(SDL_Window* window, Uint32 flags) +int SDL_SetWindowFullscreen(SDL_Window* window, uint32_t flags) { if ((window->flags & SDL_WINDOW_FULLSCREEN_DESKTOP) == (flags & SDL_WINDOW_FULLSCREEN_DESKTOP)) return 0; @@ -2069,11 +1934,6 @@ int SDL_UpdateWindowSurface(SDL_Window *screen) return 0; } -void SDL_RenderPresent(SDL_Renderer *renderer) -{ - SDL_UpdateWindowSurface(renderer->window); -} - } // extern "C" From e5a41a135821d48e65f460979b6f566c02ccc2fd Mon Sep 17 00:00:00 2001 From: MajorCooke Date: Sat, 20 Dec 2014 16:57:00 -0600 Subject: [PATCH 24/46] - Added name filtering to all A_Damage/Kill/Remove functions. - A_DamageChildren(20,"Normal",0,"DoomImp") for example will only target actors of DoomImp specifically. --- src/thingdef/thingdef_codeptr.cpp | 158 +++++++++++++++++++++++------- wadsrc/static/actors/actor.txt | 34 +++---- 2 files changed, 138 insertions(+), 54 deletions(-) diff --git a/src/thingdef/thingdef_codeptr.cpp b/src/thingdef/thingdef_codeptr.cpp index 98451795b..23fe031c7 100644 --- a/src/thingdef/thingdef_codeptr.cpp +++ b/src/thingdef/thingdef_codeptr.cpp @@ -5068,12 +5068,15 @@ static void DoDamage(AActor *dmgtarget, AActor *self, int amount, FName DamageTy //=========================================================================== DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_DamageSelf) { - ACTION_PARAM_START(3); + ACTION_PARAM_START(4); ACTION_PARAM_INT(amount, 0); ACTION_PARAM_NAME(DamageType, 1); ACTION_PARAM_INT(flags, 2); + ACTION_PARAM_CLASS(filter, 3); - DoDamage(self, self, amount, DamageType, flags); + const PClass *c1 = self->GetClass(); + if (!(filter) || (filter == NULL) || (filter && (c1 == filter))) + DoDamage(self, self, amount, DamageType, flags); } //=========================================================================== @@ -5083,12 +5086,18 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_DamageSelf) //=========================================================================== DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_DamageTarget) { - ACTION_PARAM_START(3); + ACTION_PARAM_START(4); ACTION_PARAM_INT(amount, 0); ACTION_PARAM_NAME(DamageType, 1); ACTION_PARAM_INT(flags, 2); + ACTION_PARAM_CLASS(filter, 3); - if (self->target != NULL) DoDamage(self->target, self, amount, DamageType, flags); + if (self->target != NULL) + { + const PClass *c1 = self->target->GetClass(); + if (!(filter) || (filter == NULL) || (filter && (c1 == filter))) + DoDamage(self->target, self, amount, DamageType, flags); + } } //=========================================================================== @@ -5098,12 +5107,18 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_DamageTarget) //=========================================================================== DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_DamageTracer) { - ACTION_PARAM_START(3); + ACTION_PARAM_START(4); ACTION_PARAM_INT(amount, 0); ACTION_PARAM_NAME(DamageType, 1); ACTION_PARAM_INT(flags, 2); + ACTION_PARAM_CLASS(filter, 3); - if (self->tracer != NULL) DoDamage(self->tracer, self, amount, DamageType, flags); + if (self->tracer != NULL) + { + const PClass *c1 = self->tracer->GetClass(); + if (!(filter) || (filter == NULL) || (filter && (c1 == filter))) + DoDamage(self->tracer, self, amount, DamageType, flags); + } } //=========================================================================== @@ -5113,12 +5128,18 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_DamageTracer) //=========================================================================== DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_DamageMaster) { - ACTION_PARAM_START(3); + ACTION_PARAM_START(4); ACTION_PARAM_INT(amount, 0); ACTION_PARAM_NAME(DamageType, 1); ACTION_PARAM_INT(flags, 2); + ACTION_PARAM_CLASS(filter, 3); - if (self->master != NULL) DoDamage(self->master, self, amount, DamageType, flags); + if (self->master != NULL) + { + const PClass *c1 = self->master->GetClass(); + if (!(filter) || (filter == NULL) || (filter && (c1 == filter))) + DoDamage(self->master, self, amount, DamageType, flags); + } } //=========================================================================== @@ -5128,17 +5149,23 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_DamageMaster) //=========================================================================== DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_DamageChildren) { - ACTION_PARAM_START(3); + ACTION_PARAM_START(4); ACTION_PARAM_INT(amount, 0); ACTION_PARAM_NAME(DamageType, 1); ACTION_PARAM_INT(flags, 2); + ACTION_PARAM_CLASS(filter, 3); TThinkerIterator it; AActor * mo; while ( (mo = it.Next()) ) { - if (mo->master == self) DoDamage(mo, self, amount, DamageType, flags); + if (mo->master == self) + { + const PClass *c1 = mo->GetClass(); + if (!(filter) || (filter == NULL) || (filter && (c1 == filter))) + DoDamage(mo, self, amount, DamageType, flags); + } } } @@ -5149,10 +5176,11 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_DamageChildren) //=========================================================================== DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_DamageSiblings) { - ACTION_PARAM_START(3); + ACTION_PARAM_START(4); ACTION_PARAM_INT(amount, 0); ACTION_PARAM_NAME(DamageType, 1); ACTION_PARAM_INT(flags, 2); + ACTION_PARAM_CLASS(filter, 3); TThinkerIterator it; AActor * mo; @@ -5161,7 +5189,12 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_DamageSiblings) { while ((mo = it.Next())) { - if (mo->master == self->master && mo != self) DoDamage(mo, self, amount, DamageType, flags); + if (mo->master == self->master && mo != self) + { + const PClass *c1 = mo->GetClass(); + if (!(filter) || (filter == NULL) || (filter && (c1 == filter))) + DoDamage(mo, self, amount, DamageType, flags); + } } } } @@ -5214,11 +5247,17 @@ static void DoKill(AActor *killtarget, AActor *self, FName damagetype, int flags //=========================================================================== DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_KillTarget) { - ACTION_PARAM_START(2); + ACTION_PARAM_START(3); ACTION_PARAM_NAME(damagetype, 0); ACTION_PARAM_INT(flags, 1); + ACTION_PARAM_CLASS(filter, 2); - if (self->target != NULL) DoKill(self->target, self, damagetype, flags); + if (self->target != NULL) + { + const PClass *c1 = self->target->GetClass(); + if (!(filter) || (filter == NULL) || (filter && (c1 == filter))) + DoKill(self->target, self, damagetype, flags); + } } //=========================================================================== @@ -5228,11 +5267,17 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_KillTarget) //=========================================================================== DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_KillTracer) { - ACTION_PARAM_START(2); + ACTION_PARAM_START(3); ACTION_PARAM_NAME(damagetype, 0); ACTION_PARAM_INT(flags, 1); + ACTION_PARAM_CLASS(filter, 2); - if (self->tracer != NULL) DoKill(self->tracer, self, damagetype, flags); + if (self->tracer != NULL) + { + const PClass *c1 = self->tracer->GetClass(); + if (!(filter) || (filter == NULL) || (filter && (c1 == filter))) + DoKill(self->tracer, self, damagetype, flags); + } } //=========================================================================== @@ -5242,11 +5287,17 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_KillTracer) //=========================================================================== DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_KillMaster) { - ACTION_PARAM_START(2); + ACTION_PARAM_START(3); ACTION_PARAM_NAME(damagetype, 0); ACTION_PARAM_INT(flags, 1); + ACTION_PARAM_CLASS(filter, 2); - if (self->master != NULL) DoKill(self->master, self, damagetype, flags); + if (self->master != NULL) + { + const PClass *c1 = self->master->GetClass(); + if (!(filter) || (filter == NULL) || (filter && (c1 == filter))) + DoKill(self->master, self, damagetype, flags); + } } //=========================================================================== @@ -5256,16 +5307,22 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_KillMaster) //=========================================================================== DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_KillChildren) { - ACTION_PARAM_START(2); + ACTION_PARAM_START(3); ACTION_PARAM_NAME(damagetype, 0); ACTION_PARAM_INT(flags, 1); + ACTION_PARAM_CLASS(filter, 2); TThinkerIterator it; AActor *mo; while ( (mo = it.Next()) ) { - if (mo->master == self) DoKill(mo, self, damagetype, flags); + if (mo->master == self) + { + const PClass *c1 = mo->GetClass(); + if (!(filter) || (filter == NULL) || (filter && (c1 == filter))) + DoKill(mo, self, damagetype, flags); + } } } @@ -5276,9 +5333,10 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_KillChildren) //=========================================================================== DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_KillSiblings) { - ACTION_PARAM_START(2); + ACTION_PARAM_START(3); ACTION_PARAM_NAME(damagetype, 0); ACTION_PARAM_INT(flags, 1); + ACTION_PARAM_CLASS(filter, 2); TThinkerIterator it; AActor *mo; @@ -5287,7 +5345,12 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_KillSiblings) { while ( (mo = it.Next()) ) { - if (mo->master == self->master && mo != self) DoKill(mo, self, damagetype, flags); + if (mo->master == self->master && mo != self) + { + const PClass *c1 = mo->GetClass(); + if (!(filter) || (filter == NULL) || (filter && (c1 == filter))) + DoKill(mo, self, damagetype, flags); + } } } } @@ -5333,11 +5396,15 @@ static void DoRemove(AActor *removetarget, int flags) //=========================================================================== DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_RemoveTarget) { - ACTION_PARAM_START(1); + ACTION_PARAM_START(2); ACTION_PARAM_INT(flags, 0); - if (self->master != NULL) + ACTION_PARAM_CLASS(filter, 1); + + if (self->target != NULL) { - DoRemove(self->target, flags); + const PClass *c1 = self->target->GetClass(); + if ((filter && (c1 == filter)) || (filter == NULL) || !(filter)) + DoRemove(self->target, flags); } } @@ -5348,11 +5415,15 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_RemoveTarget) //=========================================================================== DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_RemoveTracer) { - ACTION_PARAM_START(1); + ACTION_PARAM_START(2); ACTION_PARAM_INT(flags, 0); - if (self->master != NULL) + ACTION_PARAM_CLASS(filter, 1); + + if (self->tracer != NULL) { - DoRemove(self->tracer, flags); + const PClass *c1 = self->tracer->GetClass(); + if ((filter && (c1 == filter)) || (filter == NULL) || !(filter)) + DoRemove(self->tracer, flags); } } @@ -5363,11 +5434,15 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_RemoveTracer) //=========================================================================== DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_RemoveMaster) { - ACTION_PARAM_START(1); + ACTION_PARAM_START(2); ACTION_PARAM_INT(flags, 0); + ACTION_PARAM_CLASS(filter, 1); + if (self->master != NULL) { - DoRemove(self->master, flags); + const PClass *c1 = self->master->GetClass(); + if ((filter && (c1 == filter)) || (filter == NULL) || !(filter)) + DoRemove(self->master, flags); } } @@ -5380,15 +5455,19 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_RemoveChildren) { TThinkerIterator it; AActor *mo; - ACTION_PARAM_START(2); + ACTION_PARAM_START(3); ACTION_PARAM_BOOL(removeall, 0); ACTION_PARAM_INT(flags, 1); + ACTION_PARAM_CLASS(filter, 2); + while ((mo = it.Next()) != NULL) { if (mo->master == self && (mo->health <= 0 || removeall)) { - DoRemove(mo, flags); + const PClass *c1 = mo->GetClass(); + if (!(filter) || (filter == NULL) || (filter && (c1 == filter))) + DoRemove(mo, flags); } } } @@ -5402,9 +5481,10 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_RemoveSiblings) { TThinkerIterator it; AActor *mo; - ACTION_PARAM_START(2); + ACTION_PARAM_START(3); ACTION_PARAM_BOOL(removeall, 0); ACTION_PARAM_INT(flags, 1); + ACTION_PARAM_CLASS(filter, 2); if (self->master != NULL) { @@ -5412,7 +5492,9 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_RemoveSiblings) { if (mo->master == self->master && mo != self && (mo->health <= 0 || removeall)) { - DoRemove(mo, flags); + const PClass *c1 = mo->GetClass(); + if (!(filter) || (filter == NULL) || (filter && (c1 == filter))) + DoRemove(mo, flags); } } } @@ -5425,15 +5507,17 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_RemoveSiblings) //=========================================================================== DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_Remove) { - ACTION_PARAM_START(2); + ACTION_PARAM_START(3); ACTION_PARAM_INT(removee, 0); ACTION_PARAM_INT(flags, 1); + ACTION_PARAM_CLASS(filter, 2); AActor *reference = COPY_AAPTR(self, removee); - if (reference != NULL) { - DoRemove(reference, flags); + const PClass *c1 = reference->GetClass(); + if (!(filter) || (filter == NULL) || (filter && (c1 == filter))) + DoRemove(reference, flags); } } diff --git a/wadsrc/static/actors/actor.txt b/wadsrc/static/actors/actor.txt index cd718b1c0..910bd0778 100644 --- a/wadsrc/static/actors/actor.txt +++ b/wadsrc/static/actors/actor.txt @@ -237,12 +237,6 @@ ACTOR Actor native //: Thinker action native A_ChangeFlag(string flagname, bool value); action native A_CheckFlag(string flagname, state label, int check_pointer = AAPTR_DEFAULT); action native A_JumpIf(bool expression, state label); - action native A_RemoveMaster(int flags = 0); - action native A_RemoveChildren(bool removeall = false, int flags = 0); - action native A_RemoveSiblings(bool removeall = false, int flags = 0); - action native A_KillMaster(name damagetype = "none", int flags = 0); - action native A_KillChildren(name damagetype = "none", int flags = 0); - action native A_KillSiblings(name damagetype = "none", int flags = 0); action native A_RaiseMaster(bool copy = 0); action native A_RaiseChildren(bool copy = 0); action native A_RaiseSiblings(bool copy = 0); @@ -278,9 +272,6 @@ ACTOR Actor native //: Thinker action native A_CheckLOF(state jump, int flags = 0, float range = 0, float minrange = 0, float angle = 0, float pitch = 0, float offsetheight = 0, float offsetwidth = 0, int ptr_target = AAPTR_DEFAULT); action native A_JumpIfTargetInLOS (state label, float fov = 0, int flags = 0, float dist_max = 0, float dist_close = 0); action native A_JumpIfInTargetLOS (state label, float fov = 0, int flags = 0, float dist_max = 0, float dist_close = 0); - action native A_DamageMaster(int amount, name damagetype = "none", int flags = 0); - action native A_DamageChildren(int amount, name damagetype = "none", int flags = 0); - action native A_DamageSiblings(int amount, name damagetype = "none", int flags = 0); action native A_SelectWeapon(class whichweapon); action native A_Punch(); action native A_Feathers(); @@ -307,14 +298,23 @@ ACTOR Actor native //: Thinker action native A_SetDamageType(name damagetype); action native A_DropItem(class item, int dropamount = -1, int chance = 256); action native A_SetSpeed(float speed); - action native A_DamageSelf(int amount, name damagetype = "none", int flags = 0); - action native A_DamageTarget(int amount, name damagetype = "none", int flags = 0); - action native A_DamageTracer(int amount, name damagetype = "none", int flags = 0); - action native A_KillTarget(name damagetype = "none", int flags = 0); - action native A_KillTracer(name damagetype = "none", int flags = 0); - action native A_RemoveTarget(int flags = 0); - action native A_RemoveTracer(int flags = 0); - action native A_Remove(int removee, int flags = 0); + action native A_DamageSelf(int amount, name damagetype = "none", int flags = 0, class filter); + action native A_DamageTarget(int amount, name damagetype = "none", int flags = 0, class filter); + action native A_DamageMaster(int amount, name damagetype = "none", int flags = 0, class filter); + action native A_DamageTracer(int amount, name damagetype = "none", int flags = 0, class filter); + action native A_DamageChildren(int amount, name damagetype = "none", int flags = 0, class filter); + action native A_DamageSiblings(int amount, name damagetype = "none", int flags = 0, class filter); + action native A_KillTarget(name damagetype = "none", int flags = 0, class filter); + action native A_KillMaster(name damagetype = "none", int flags = 0, class filter); + action native A_KillTracer(name damagetype = "none", int flags = 0, class filter); + action native A_KillChildren(name damagetype = "none", int flags = 0, class filter); + action native A_KillSiblings(name damagetype = "none", int flags = 0, class filter); + action native A_RemoveTarget(int flags = 0, class filter); + action native A_RemoveMaster(int flags = 0, class filter); + action native A_RemoveTracer(int flags = 0, class filter); + action native A_RemoveChildren(bool removeall = false, int flags = 0, class filter); + action native A_RemoveSiblings(bool removeall = false, int flags = 0, class filter); + action native A_Remove(int removee, int flags = 0, class filter); action native A_GiveToChildren(class itemtype, int amount = 0); action native A_GiveToSiblings(class itemtype, int amount = 0); action native A_TakeFromChildren(class itemtype, int amount = 0); From c168761edacc5aa69bf89f21e3eeb8e769c91c61 Mon Sep 17 00:00:00 2001 From: MajorCooke Date: Sat, 20 Dec 2014 22:51:43 -0600 Subject: [PATCH 25/46] - Couple additional fixes: - The wiki said the minimum distance to teleport defaults to 0, actor.txt on the other hand said otherwise. I was wondering why it was still broken somewhat... - Prevent stickiness from happening, a.k.a. getting stuck in ceiling or floor and letting the engine unstick the actor. This caused velocity loss. --- src/thingdef/thingdef_codeptr.cpp | 21 ++++++++++++++------- wadsrc/static/actors/actor.txt | 2 +- 2 files changed, 15 insertions(+), 8 deletions(-) diff --git a/src/thingdef/thingdef_codeptr.cpp b/src/thingdef/thingdef_codeptr.cpp index 23fe031c7..485db3d86 100644 --- a/src/thingdef/thingdef_codeptr.cpp +++ b/src/thingdef/thingdef_codeptr.cpp @@ -4199,16 +4199,23 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_Teleport) fixed_t prevX = self->x; fixed_t prevY = self->y; fixed_t prevZ = self->z; + fixed_t aboveFloor = spot->z - spot->floorz; + fixed_t finalz = spot->floorz + aboveFloor; + + if (spot->z + self->height > spot->ceilingz) + finalz = spot->ceilingz - self->height; + else if (spot->z < spot->floorz) + finalz = spot->floorz; + //Take precedence and cooperate with telefragging first. - bool teleResult = P_TeleportMove(self, spot->x, spot->y, spot->z, Flags & TF_TELEFRAG); - - if ((!(teleResult)) && (Flags & TF_FORCED)) - { - //If for some reason the original move didn't work, regardless of telefrag, force it to move. - self->SetOrigin(spot->x, spot->y, spot->z); - teleResult = true; + bool teleResult = P_TeleportMove(self, spot->x, spot->y, finalz, Flags & TF_TELEFRAG); + if (Flags & TF_FORCED) + { + //If for some reason the original move didn't work, regardless of telefrag, force it to move. + self->SetOrigin(spot->x, spot->y, finalz); + teleResult = true; } if (teleResult) diff --git a/wadsrc/static/actors/actor.txt b/wadsrc/static/actors/actor.txt index 910bd0778..7bc6b8df4 100644 --- a/wadsrc/static/actors/actor.txt +++ b/wadsrc/static/actors/actor.txt @@ -244,7 +244,7 @@ ACTOR Actor native //: Thinker action native A_CheckCeiling(state label); action native A_PlayerSkinCheck(state label); action native A_BasicAttack(int meleedamage, sound meleesound, class missiletype, float missileheight); - action native A_Teleport(state teleportstate = "", class targettype = "BossSpot", class fogtype = "TeleportFog", int flags = 0, float mindist = 128, float maxdist = 0); + action native A_Teleport(state teleportstate = "", class targettype = "BossSpot", class fogtype = "TeleportFog", int flags = 0, float mindist = 0, float maxdist = 0); action native A_Warp(int ptr_destination, float xofs = 0, float yofs = 0, float zofs = 0, float angle = 0, int flags = 0, state success_state = ""); action native A_ThrowGrenade(class itemtype, float zheight = 0, float xyvel = 0, float zvel = 0, bool useammo = true); action native A_Weave(int xspeed, int yspeed, float xdist, float ydist); From 18c7709007b32bdbc84c98a9f66e3ca24a9626d4 Mon Sep 17 00:00:00 2001 From: "alexey.lysiuk" Date: Sun, 21 Dec 2014 12:35:43 +0200 Subject: [PATCH 26/46] Cleanup video part of native OS X backend, phase 4 --- src/posix/cocoa/i_backend_cocoa.mm | 146 ++++++++++++++--------------- 1 file changed, 69 insertions(+), 77 deletions(-) diff --git a/src/posix/cocoa/i_backend_cocoa.mm b/src/posix/cocoa/i_backend_cocoa.mm index b15c4b0ca..b1d737912 100644 --- a/src/posix/cocoa/i_backend_cocoa.mm +++ b/src/posix/cocoa/i_backend_cocoa.mm @@ -414,6 +414,8 @@ int OriginalMain(int argc, char** argv) } I_StartupJoysticks(); + atterm(I_ShutdownJoysticks); + C_InitConsole(80 * 8, 25 * 8, false); D_DoomMain(); } @@ -1166,8 +1168,6 @@ namespace - (void)applicationDidFinishLaunching:(NSNotification*)aNotification; -- (void)applicationWillTerminate:(NSNotification*)aNotification; - - (BOOL)application:(NSApplication*)theApplication openFile:(NSString*)filename; - (int)multisample; @@ -1371,17 +1371,6 @@ static bool s_fullscreenNewAPI; } -- (void)applicationWillTerminate:(NSNotification*)aNotification -{ - ZD_UNUSED(aNotification); - - // Hide window as nothing will be rendered at this point - [m_window orderOut:nil]; - - I_ShutdownJoysticks(); -} - - - (int)multisample { return m_multisample; @@ -1975,7 +1964,7 @@ public: virtual void UpdatePalette(); virtual bool SetGamma(float gamma); - virtual bool SetFlash(PalEntry rgb, int amount); + virtual bool SetFlash(PalEntry rgb, int amount); virtual void GetFlash(PalEntry &rgb, int &amount); virtual int GetPageCount(); @@ -1987,18 +1976,20 @@ public: void SetFullscreen(bool fullscreen); private: - PalEntry SourcePalette[256]; - BYTE GammaTable[3][256]; - PalEntry Flash; - int FlashAmount; - float Gamma; - bool UpdatePending; + PalEntry m_palette[256]; + bool m_needPaletteUpdate; + + BYTE m_gammaTable[3][256]; + float m_gamma; + bool m_needGammaUpdate; + + PalEntry m_flashColor; + int m_flashAmount; + + bool m_isUpdatePending; SDL_Window *Screen; - bool NeedPalUpdate; - bool NeedGammaUpdate; - void UpdateColors(); }; @@ -2036,7 +2027,7 @@ CUSTOM_CVAR (Float, bgamma, 1.0f, CVAR_ARCHIVE | CVAR_GLOBALCONFIG) // --------------------------------------------------------------------------- -static const struct MiniModeInfo +static const struct { uint16_t width; uint16_t height; @@ -2125,6 +2116,8 @@ void CocoaVideo::StartModeIterator(int bits, bool fs) bool CocoaVideo::NextMode(int* width, int* height, bool* letterbox) { + assert(NULL != width); + assert(NULL != height); ZD_UNUSED(letterbox); if (m_modeIterator < sizeof(VideoModes) / sizeof(VideoModes[0])) @@ -2226,11 +2219,11 @@ void CocoaVideo::SetWindowedScale (float scale) CocoaFrameBuffer::CocoaFrameBuffer (int width, int height, bool fullscreen) : DFrameBuffer(width, height) -, FlashAmount(0) -, Gamma(0.0f) -, UpdatePending(false) -, NeedPalUpdate(false) -, NeedGammaUpdate(false) +, m_needPaletteUpdate(false) +, m_gamma(0.0f) +, m_needGammaUpdate(false) +, m_flashAmount(0) +, m_isUpdatePending(false) { FString caption; caption.Format(GAMESIG " %s (%s)", GetVersionString(), GetGitTime()); @@ -2245,10 +2238,10 @@ CocoaFrameBuffer::CocoaFrameBuffer (int width, int height, bool fullscreen) for (size_t i = 0; i < 256; ++i) { - GammaTable[0][i] = GammaTable[1][i] = GammaTable[2][i] = i; + m_gammaTable[0][i] = m_gammaTable[1][i] = m_gammaTable[2][i] = i; } - memcpy(SourcePalette, GPalette.BaseColors, sizeof(PalEntry) * 256); + memcpy(m_palette, GPalette.BaseColors, sizeof(PalEntry) * 256); UpdateColors(); SetVSync(vid_vsync); @@ -2280,7 +2273,7 @@ bool CocoaFrameBuffer::Lock (bool buffered) void CocoaFrameBuffer::Unlock () { - if (UpdatePending && LockCount == 1) + if (m_isUpdatePending && LockCount == 1) { Update (); } @@ -2297,7 +2290,7 @@ void CocoaFrameBuffer::Update () { if (LockCount > 0) { - UpdatePending = true; + m_isUpdatePending = true; --LockCount; } return; @@ -2307,7 +2300,7 @@ void CocoaFrameBuffer::Update () Buffer = NULL; LockCount = 0; - UpdatePending = false; + m_isUpdatePending = false; BlitCycles.Reset(); FlipCycles.Reset(); @@ -2322,19 +2315,19 @@ void CocoaFrameBuffer::Update () BlitCycles.Unclock(); - if (NeedGammaUpdate) + if (m_needGammaUpdate) { bool Windowed = false; - NeedGammaUpdate = false; - CalcGamma((Windowed || rgamma == 0.f) ? Gamma : (Gamma * rgamma), GammaTable[0]); - CalcGamma((Windowed || ggamma == 0.f) ? Gamma : (Gamma * ggamma), GammaTable[1]); - CalcGamma((Windowed || bgamma == 0.f) ? Gamma : (Gamma * bgamma), GammaTable[2]); - NeedPalUpdate = true; + m_needGammaUpdate = false; + CalcGamma((Windowed || rgamma == 0.f) ? m_gamma : (m_gamma * rgamma), m_gammaTable[0]); + CalcGamma((Windowed || ggamma == 0.f) ? m_gamma : (m_gamma * ggamma), m_gammaTable[1]); + CalcGamma((Windowed || bgamma == 0.f) ? m_gamma : (m_gamma * bgamma), m_gammaTable[2]); + m_needPaletteUpdate = true; } - if (NeedPalUpdate) + if (m_needPaletteUpdate) { - NeedPalUpdate = false; + m_needPaletteUpdate = false; UpdateColors(); } } @@ -2345,16 +2338,16 @@ void CocoaFrameBuffer::UpdateColors() for (size_t i = 0; i < 256; ++i) { - palette[i].r = GammaTable[0][SourcePalette[i].r]; - palette[i].g = GammaTable[1][SourcePalette[i].g]; - palette[i].b = GammaTable[2][SourcePalette[i].b]; + palette[i].r = m_gammaTable[0][m_palette[i].r]; + palette[i].g = m_gammaTable[1][m_palette[i].g]; + palette[i].b = m_gammaTable[2][m_palette[i].b]; } - if (FlashAmount) + if (m_flashAmount) { DoBlending(palette, palette, 256, - GammaTable[0][Flash.r], GammaTable[1][Flash.g], GammaTable[2][Flash.b], - FlashAmount); + m_gammaTable[0][m_flashColor.r], m_gammaTable[1][m_flashColor.g], m_gammaTable[2][m_flashColor.b], + m_flashAmount); } GPfx.SetPalette(palette); @@ -2362,42 +2355,44 @@ void CocoaFrameBuffer::UpdateColors() PalEntry *CocoaFrameBuffer::GetPalette () { - return SourcePalette; + return m_palette; } void CocoaFrameBuffer::UpdatePalette() { - NeedPalUpdate = true; + m_needPaletteUpdate = true; } -bool CocoaFrameBuffer::SetGamma (float gamma) +bool CocoaFrameBuffer::SetGamma(float gamma) { - Gamma = gamma; - NeedGammaUpdate = true; + m_gamma = gamma; + m_needGammaUpdate = true; + return true; } -bool CocoaFrameBuffer::SetFlash (PalEntry rgb, int amount) +bool CocoaFrameBuffer::SetFlash(PalEntry rgb, int amount) { - Flash = rgb; - FlashAmount = amount; - NeedPalUpdate = true; + m_flashColor = rgb; + m_flashAmount = amount; + m_needPaletteUpdate = true; + return true; } -void CocoaFrameBuffer::GetFlash (PalEntry &rgb, int &amount) +void CocoaFrameBuffer::GetFlash(PalEntry &rgb, int &amount) { - rgb = Flash; - amount = FlashAmount; + rgb = m_flashColor; + amount = m_flashAmount; } -// Q: Should I gamma adjust the returned palette? -void CocoaFrameBuffer::GetFlashedPalette (PalEntry pal[256]) +void CocoaFrameBuffer::GetFlashedPalette(PalEntry pal[256]) { - memcpy (pal, SourcePalette, 256*sizeof(PalEntry)); - if (FlashAmount) + memcpy(pal, m_palette, sizeof m_palette); + + if (0 != m_flashAmount) { - DoBlending (pal, pal, 256, Flash.r, Flash.g, Flash.b, FlashAmount); + DoBlending (pal, pal, 256, m_flashColor.r, m_flashColor.g, m_flashColor.b, m_flashAmount); } } @@ -2413,25 +2408,22 @@ bool CocoaFrameBuffer::IsFullscreen () void CocoaFrameBuffer::SetVSync (bool vsync) { - if (CGLContextObj context = CGLGetCurrentContext()) - { #if MAC_OS_X_VERSION_MAX_ALLOWED < 1050 - // Inconsistency between 10.4 and 10.5 SDKs: - // third argument of CGLSetParameter() is const long* on 10.4 and const GLint* on 10.5 - // So, GLint typedef'ed to long instead of int to workaround this issue - typedef long GLint; + const long value = vsync ? 1 : 0; +#else // 10.5 or newer + const GLint value = vsync ? 1 : 0; #endif // prior to 10.5 - const GLint value = vsync ? 1 : 0; - CGLSetParameter(context, kCGLCPSwapInterval, &value); - } + [[NSOpenGLContext currentContext] setValues:&value + forParameter:NSOpenGLCPSwapInterval]; } + ADD_STAT(blit) { - FString out; - out.Format("blit=%04.1f ms flip=%04.1f ms", BlitCycles.TimeMS(), FlipCycles.TimeMS()); - return out; + FString result; + result.Format("blit=%04.1f ms flip=%04.1f ms", BlitCycles.TimeMS(), FlipCycles.TimeMS()); + return result; } From 5a472e815b9df50079bebbc38c157d3256ace894 Mon Sep 17 00:00:00 2001 From: MajorCooke Date: Sun, 21 Dec 2014 09:31:24 -0600 Subject: [PATCH 27/46] - Added species checking. - Added two more flags for each of the functions, EXFILTER and EXSPECIES. - Stands for "exclude filter/species" and makes the function not take them into account. - Cleaned up the code and placed all the checking in their own subfunctions. --- src/thingdef/thingdef_codeptr.cpp | 213 ++++++++++++++++------------- wadsrc/static/actors/actor.txt | 34 ++--- wadsrc/static/actors/constants.txt | 6 + 3 files changed, 138 insertions(+), 115 deletions(-) diff --git a/src/thingdef/thingdef_codeptr.cpp b/src/thingdef/thingdef_codeptr.cpp index 485db3d86..e61f33ea4 100644 --- a/src/thingdef/thingdef_codeptr.cpp +++ b/src/thingdef/thingdef_codeptr.cpp @@ -5023,6 +5023,18 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_SetSpeed) self->Speed = speed; } +static bool DoCheckSpecies(AActor *mo, FName species, bool exclude) +{ + FName spec = mo->Species; + return (!(species) || !(stricmp(species, "")) || (species && ((exclude) ? (spec != species) : (spec == species)))); +} + +static bool DoCheckFilter(AActor *mo, const PClass *filter, bool exclude) +{ + const PClass *c1 = mo->GetClass(); + return (!(filter) || (filter == NULL) || (filter && ((exclude) ? (c1 != filter) : (c1 == filter)))); +} + //=========================================================================== // // Common A_Damage handler @@ -5040,9 +5052,11 @@ enum DMSS DMSS_NOFACTOR = 8, DMSS_FOILBUDDHA = 16, DMSS_NOPROTECT = 32, + DMSS_EXFILTER = 64, + DMSS_EXSPECIES = 128, }; -static void DoDamage(AActor *dmgtarget, AActor *self, int amount, FName DamageType, int flags) +static void DoDamage(AActor *dmgtarget, AActor *self, int amount, FName DamageType, int flags, const PClass *filter, FName species) { int dmgFlags = 0; if (flags & DMSS_FOILINVUL) @@ -5058,13 +5072,19 @@ static void DoDamage(AActor *dmgtarget, AActor *self, int amount, FName DamageTy if (flags & DMSS_NOPROTECT) //Ignore PowerProtection. dmgFlags += DMG_NO_PROTECT; - if (amount > 0) - P_DamageMobj(dmgtarget, self, self, amount, DamageType, dmgFlags); //Should wind up passing them through just fine. - - else if (amount < 0) + bool filterpass = DoCheckFilter(dmgtarget, filter, (flags & DMSS_EXFILTER) ? true : false), + speciespass = DoCheckSpecies(dmgtarget, species, (flags & DMSS_EXSPECIES) ? true : false); + + if (filterpass && speciespass) { - amount = -amount; - P_GiveBody(dmgtarget, amount); + if (amount > 0) + P_DamageMobj(dmgtarget, self, self, amount, DamageType, dmgFlags); //Should wind up passing them through just fine. + + else if (amount < 0) + { + amount = -amount; + P_GiveBody(dmgtarget, amount); + } } } @@ -5075,15 +5095,14 @@ static void DoDamage(AActor *dmgtarget, AActor *self, int amount, FName DamageTy //=========================================================================== DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_DamageSelf) { - ACTION_PARAM_START(4); + ACTION_PARAM_START(5); ACTION_PARAM_INT(amount, 0); ACTION_PARAM_NAME(DamageType, 1); ACTION_PARAM_INT(flags, 2); ACTION_PARAM_CLASS(filter, 3); + ACTION_PARAM_NAME(species, 4); - const PClass *c1 = self->GetClass(); - if (!(filter) || (filter == NULL) || (filter && (c1 == filter))) - DoDamage(self, self, amount, DamageType, flags); + DoDamage(self, self, amount, DamageType, flags, filter, species); } //=========================================================================== @@ -5093,17 +5112,16 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_DamageSelf) //=========================================================================== DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_DamageTarget) { - ACTION_PARAM_START(4); + ACTION_PARAM_START(5); ACTION_PARAM_INT(amount, 0); ACTION_PARAM_NAME(DamageType, 1); ACTION_PARAM_INT(flags, 2); ACTION_PARAM_CLASS(filter, 3); + ACTION_PARAM_NAME(species, 4); if (self->target != NULL) { - const PClass *c1 = self->target->GetClass(); - if (!(filter) || (filter == NULL) || (filter && (c1 == filter))) - DoDamage(self->target, self, amount, DamageType, flags); + DoDamage(self->target, self, amount, DamageType, flags, filter, species); } } @@ -5114,17 +5132,16 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_DamageTarget) //=========================================================================== DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_DamageTracer) { - ACTION_PARAM_START(4); + ACTION_PARAM_START(5); ACTION_PARAM_INT(amount, 0); ACTION_PARAM_NAME(DamageType, 1); ACTION_PARAM_INT(flags, 2); ACTION_PARAM_CLASS(filter, 3); + ACTION_PARAM_NAME(species, 4); if (self->tracer != NULL) { - const PClass *c1 = self->tracer->GetClass(); - if (!(filter) || (filter == NULL) || (filter && (c1 == filter))) - DoDamage(self->tracer, self, amount, DamageType, flags); + DoDamage(self->tracer, self, amount, DamageType, flags, filter, species); } } @@ -5135,17 +5152,16 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_DamageTracer) //=========================================================================== DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_DamageMaster) { - ACTION_PARAM_START(4); + ACTION_PARAM_START(5); ACTION_PARAM_INT(amount, 0); ACTION_PARAM_NAME(DamageType, 1); ACTION_PARAM_INT(flags, 2); ACTION_PARAM_CLASS(filter, 3); + ACTION_PARAM_NAME(species, 4); if (self->master != NULL) { - const PClass *c1 = self->master->GetClass(); - if (!(filter) || (filter == NULL) || (filter && (c1 == filter))) - DoDamage(self->master, self, amount, DamageType, flags); + DoDamage(self->master, self, amount, DamageType, flags, filter, species); } } @@ -5156,11 +5172,12 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_DamageMaster) //=========================================================================== DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_DamageChildren) { - ACTION_PARAM_START(4); + ACTION_PARAM_START(5); ACTION_PARAM_INT(amount, 0); ACTION_PARAM_NAME(DamageType, 1); ACTION_PARAM_INT(flags, 2); ACTION_PARAM_CLASS(filter, 3); + ACTION_PARAM_NAME(species, 4); TThinkerIterator it; AActor * mo; @@ -5169,9 +5186,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_DamageChildren) { if (mo->master == self) { - const PClass *c1 = mo->GetClass(); - if (!(filter) || (filter == NULL) || (filter && (c1 == filter))) - DoDamage(mo, self, amount, DamageType, flags); + DoDamage(mo, self, amount, DamageType, flags, filter, species); } } } @@ -5183,11 +5198,12 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_DamageChildren) //=========================================================================== DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_DamageSiblings) { - ACTION_PARAM_START(4); + ACTION_PARAM_START(5); ACTION_PARAM_INT(amount, 0); ACTION_PARAM_NAME(DamageType, 1); ACTION_PARAM_INT(flags, 2); ACTION_PARAM_CLASS(filter, 3); + ACTION_PARAM_NAME(species, 4); TThinkerIterator it; AActor * mo; @@ -5198,9 +5214,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_DamageSiblings) { if (mo->master == self->master && mo != self) { - const PClass *c1 = mo->GetClass(); - if (!(filter) || (filter == NULL) || (filter && (c1 == filter))) - DoDamage(mo, self, amount, DamageType, flags); + DoDamage(mo, self, amount, DamageType, flags, filter, species); } } } @@ -5218,9 +5232,11 @@ enum KILS KILS_KILLMISSILES = 1 << 1, KILS_NOMONSTERS = 1 << 2, KILS_FOILBUDDHA = 1 << 3, + KILS_EXFILTER = 1 << 4, + KILS_EXSPECIES = 1 << 5, }; -static void DoKill(AActor *killtarget, AActor *self, FName damagetype, int flags) +static void DoKill(AActor *killtarget, AActor *self, FName damagetype, int flags, const PClass *filter, FName species) { int dmgFlags = DMG_NO_ARMOR + DMG_NO_FACTOR; @@ -5229,20 +5245,25 @@ static void DoKill(AActor *killtarget, AActor *self, FName damagetype, int flags if (KILS_FOILBUDDHA) dmgFlags += DMG_FOILBUDDHA; - if ((killtarget->flags & MF_MISSILE) && (flags & KILS_KILLMISSILES)) + bool filterpass = DoCheckFilter(killtarget, filter, (flags & KILS_EXFILTER) ? true : false), + speciespass = DoCheckSpecies(killtarget, species, (flags & KILS_EXSPECIES) ? true : false); + if (filterpass && speciespass) //Check this first. I think it'll save the engine a lot more time this way. { - //[MC] Now that missiles can set masters, lets put in a check to properly destroy projectiles. BUT FIRST! New feature~! - //Check to see if it's invulnerable. Disregarded if foilinvul is on, but never works on a missile with NODAMAGE - //since that's the whole point of it. - if ((!(killtarget->flags2 & MF2_INVULNERABLE) || (flags & KILS_FOILINVUL)) && - (!(killtarget->flags2 & MF7_BUDDHA) || (flags & KILS_FOILBUDDHA)) && !(killtarget->flags5 & MF5_NODAMAGE)) + if ((killtarget->flags & MF_MISSILE) && (flags & KILS_KILLMISSILES)) { - P_ExplodeMissile(killtarget, NULL, NULL); + //[MC] Now that missiles can set masters, lets put in a check to properly destroy projectiles. BUT FIRST! New feature~! + //Check to see if it's invulnerable. Disregarded if foilinvul is on, but never works on a missile with NODAMAGE + //since that's the whole point of it. + if ((!(killtarget->flags2 & MF2_INVULNERABLE) || (flags & KILS_FOILINVUL)) && + (!(killtarget->flags2 & MF7_BUDDHA) || (flags & KILS_FOILBUDDHA)) && !(killtarget->flags5 & MF5_NODAMAGE)) + { + P_ExplodeMissile(killtarget, NULL, NULL); + } } - } - if (!(flags & KILS_NOMONSTERS)) - { + if (!(flags & KILS_NOMONSTERS)) + { P_DamageMobj(killtarget, self, self, killtarget->health, damagetype, dmgFlags); + } } } @@ -5254,16 +5275,15 @@ static void DoKill(AActor *killtarget, AActor *self, FName damagetype, int flags //=========================================================================== DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_KillTarget) { - ACTION_PARAM_START(3); + ACTION_PARAM_START(4); ACTION_PARAM_NAME(damagetype, 0); ACTION_PARAM_INT(flags, 1); ACTION_PARAM_CLASS(filter, 2); + ACTION_PARAM_NAME(species, 3); if (self->target != NULL) { - const PClass *c1 = self->target->GetClass(); - if (!(filter) || (filter == NULL) || (filter && (c1 == filter))) - DoKill(self->target, self, damagetype, flags); + DoKill(self->target, self, damagetype, flags, filter, species); } } @@ -5274,16 +5294,15 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_KillTarget) //=========================================================================== DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_KillTracer) { - ACTION_PARAM_START(3); + ACTION_PARAM_START(4); ACTION_PARAM_NAME(damagetype, 0); ACTION_PARAM_INT(flags, 1); ACTION_PARAM_CLASS(filter, 2); + ACTION_PARAM_NAME(species, 3); if (self->tracer != NULL) { - const PClass *c1 = self->tracer->GetClass(); - if (!(filter) || (filter == NULL) || (filter && (c1 == filter))) - DoKill(self->tracer, self, damagetype, flags); + DoKill(self->tracer, self, damagetype, flags, filter, species); } } @@ -5294,16 +5313,15 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_KillTracer) //=========================================================================== DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_KillMaster) { - ACTION_PARAM_START(3); + ACTION_PARAM_START(4); ACTION_PARAM_NAME(damagetype, 0); ACTION_PARAM_INT(flags, 1); ACTION_PARAM_CLASS(filter, 2); + ACTION_PARAM_NAME(species, 3); if (self->master != NULL) { - const PClass *c1 = self->master->GetClass(); - if (!(filter) || (filter == NULL) || (filter && (c1 == filter))) - DoKill(self->master, self, damagetype, flags); + DoKill(self->master, self, damagetype, flags, filter, species); } } @@ -5314,10 +5332,11 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_KillMaster) //=========================================================================== DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_KillChildren) { - ACTION_PARAM_START(3); + ACTION_PARAM_START(4); ACTION_PARAM_NAME(damagetype, 0); ACTION_PARAM_INT(flags, 1); ACTION_PARAM_CLASS(filter, 2); + ACTION_PARAM_NAME(species, 3); TThinkerIterator it; AActor *mo; @@ -5326,9 +5345,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_KillChildren) { if (mo->master == self) { - const PClass *c1 = mo->GetClass(); - if (!(filter) || (filter == NULL) || (filter && (c1 == filter))) - DoKill(mo, self, damagetype, flags); + DoKill(mo, self, damagetype, flags, filter, species); } } } @@ -5340,10 +5357,11 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_KillChildren) //=========================================================================== DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_KillSiblings) { - ACTION_PARAM_START(3); + ACTION_PARAM_START(4); ACTION_PARAM_NAME(damagetype, 0); ACTION_PARAM_INT(flags, 1); ACTION_PARAM_CLASS(filter, 2); + ACTION_PARAM_NAME(species, 3); TThinkerIterator it; AActor *mo; @@ -5354,9 +5372,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_KillSiblings) { if (mo->master == self->master && mo != self) { - const PClass *c1 = mo->GetClass(); - if (!(filter) || (filter == NULL) || (filter && (c1 == filter))) - DoKill(mo, self, damagetype, flags); + DoKill(mo, self, damagetype, flags, filter, species); } } } @@ -5374,25 +5390,32 @@ enum RMVF_flags RMVF_NOMONSTERS = 1 << 1, RMVF_MISC = 1 << 2, RMVF_EVERYTHING = 1 << 3, + RMVF_EXFILTER = 1 << 4, + RMVF_EXSPECIES = 1 << 5, }; -static void DoRemove(AActor *removetarget, int flags) +static void DoRemove(AActor *removetarget, int flags, const PClass *filter, FName species) { - if ((flags & RMVF_EVERYTHING)) + bool filterpass = DoCheckFilter(removetarget, filter, (flags & RMVF_EXFILTER) ? true : false), + speciespass = DoCheckSpecies(removetarget, species, (flags & RMVF_EXSPECIES) ? true : false); + if (filterpass && speciespass) { - P_RemoveThing(removetarget); - } - if ((flags & RMVF_MISC) && !((removetarget->flags3 & MF3_ISMONSTER) && (removetarget->flags & MF_MISSILE))) - { - P_RemoveThing(removetarget); - } - if ((removetarget->flags3 & MF3_ISMONSTER) && !(flags & RMVF_NOMONSTERS)) - { - P_RemoveThing(removetarget); - } - if ((removetarget->flags & MF_MISSILE) && (flags & RMVF_MISSILES)) - { - P_RemoveThing(removetarget); + if ((flags & RMVF_EVERYTHING)) + { + P_RemoveThing(removetarget); + } + if ((flags & RMVF_MISC) && !((removetarget->flags3 & MF3_ISMONSTER) && (removetarget->flags & MF_MISSILE))) + { + P_RemoveThing(removetarget); + } + if ((removetarget->flags3 & MF3_ISMONSTER) && !(flags & RMVF_NOMONSTERS)) + { + P_RemoveThing(removetarget); + } + if ((removetarget->flags & MF_MISSILE) && (flags & RMVF_MISSILES)) + { + P_RemoveThing(removetarget); + } } } @@ -5406,12 +5429,11 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_RemoveTarget) ACTION_PARAM_START(2); ACTION_PARAM_INT(flags, 0); ACTION_PARAM_CLASS(filter, 1); + ACTION_PARAM_NAME(species, 2); if (self->target != NULL) { - const PClass *c1 = self->target->GetClass(); - if ((filter && (c1 == filter)) || (filter == NULL) || !(filter)) - DoRemove(self->target, flags); + DoRemove(self->target, flags, filter, species); } } @@ -5425,12 +5447,11 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_RemoveTracer) ACTION_PARAM_START(2); ACTION_PARAM_INT(flags, 0); ACTION_PARAM_CLASS(filter, 1); + ACTION_PARAM_NAME(species, 2); if (self->tracer != NULL) { - const PClass *c1 = self->tracer->GetClass(); - if ((filter && (c1 == filter)) || (filter == NULL) || !(filter)) - DoRemove(self->tracer, flags); + DoRemove(self->tracer, flags, filter, species); } } @@ -5444,12 +5465,11 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_RemoveMaster) ACTION_PARAM_START(2); ACTION_PARAM_INT(flags, 0); ACTION_PARAM_CLASS(filter, 1); + ACTION_PARAM_NAME(species, 2); if (self->master != NULL) { - const PClass *c1 = self->master->GetClass(); - if ((filter && (c1 == filter)) || (filter == NULL) || !(filter)) - DoRemove(self->master, flags); + DoRemove(self->master, flags, filter, species); } } @@ -5462,19 +5482,18 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_RemoveChildren) { TThinkerIterator it; AActor *mo; - ACTION_PARAM_START(3); + ACTION_PARAM_START(4); ACTION_PARAM_BOOL(removeall, 0); ACTION_PARAM_INT(flags, 1); ACTION_PARAM_CLASS(filter, 2); + ACTION_PARAM_NAME(species, 3); while ((mo = it.Next()) != NULL) { if (mo->master == self && (mo->health <= 0 || removeall)) { - const PClass *c1 = mo->GetClass(); - if (!(filter) || (filter == NULL) || (filter && (c1 == filter))) - DoRemove(mo, flags); + DoRemove(mo, flags, filter, species); } } } @@ -5488,10 +5507,11 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_RemoveSiblings) { TThinkerIterator it; AActor *mo; - ACTION_PARAM_START(3); + ACTION_PARAM_START(4); ACTION_PARAM_BOOL(removeall, 0); ACTION_PARAM_INT(flags, 1); ACTION_PARAM_CLASS(filter, 2); + ACTION_PARAM_NAME(species, 3); if (self->master != NULL) { @@ -5499,9 +5519,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_RemoveSiblings) { if (mo->master == self->master && mo != self && (mo->health <= 0 || removeall)) { - const PClass *c1 = mo->GetClass(); - if (!(filter) || (filter == NULL) || (filter && (c1 == filter))) - DoRemove(mo, flags); + DoRemove(mo, flags, filter, species); } } } @@ -5514,17 +5532,16 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_RemoveSiblings) //=========================================================================== DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_Remove) { - ACTION_PARAM_START(3); + ACTION_PARAM_START(4); ACTION_PARAM_INT(removee, 0); ACTION_PARAM_INT(flags, 1); ACTION_PARAM_CLASS(filter, 2); + ACTION_PARAM_NAME(species, 3); AActor *reference = COPY_AAPTR(self, removee); if (reference != NULL) { - const PClass *c1 = reference->GetClass(); - if (!(filter) || (filter == NULL) || (filter && (c1 == filter))) - DoRemove(reference, flags); + DoRemove(reference, flags, filter, species); } } diff --git a/wadsrc/static/actors/actor.txt b/wadsrc/static/actors/actor.txt index 7bc6b8df4..19260ae7e 100644 --- a/wadsrc/static/actors/actor.txt +++ b/wadsrc/static/actors/actor.txt @@ -298,23 +298,23 @@ ACTOR Actor native //: Thinker action native A_SetDamageType(name damagetype); action native A_DropItem(class item, int dropamount = -1, int chance = 256); action native A_SetSpeed(float speed); - action native A_DamageSelf(int amount, name damagetype = "none", int flags = 0, class filter); - action native A_DamageTarget(int amount, name damagetype = "none", int flags = 0, class filter); - action native A_DamageMaster(int amount, name damagetype = "none", int flags = 0, class filter); - action native A_DamageTracer(int amount, name damagetype = "none", int flags = 0, class filter); - action native A_DamageChildren(int amount, name damagetype = "none", int flags = 0, class filter); - action native A_DamageSiblings(int amount, name damagetype = "none", int flags = 0, class filter); - action native A_KillTarget(name damagetype = "none", int flags = 0, class filter); - action native A_KillMaster(name damagetype = "none", int flags = 0, class filter); - action native A_KillTracer(name damagetype = "none", int flags = 0, class filter); - action native A_KillChildren(name damagetype = "none", int flags = 0, class filter); - action native A_KillSiblings(name damagetype = "none", int flags = 0, class filter); - action native A_RemoveTarget(int flags = 0, class filter); - action native A_RemoveMaster(int flags = 0, class filter); - action native A_RemoveTracer(int flags = 0, class filter); - action native A_RemoveChildren(bool removeall = false, int flags = 0, class filter); - action native A_RemoveSiblings(bool removeall = false, int flags = 0, class filter); - action native A_Remove(int removee, int flags = 0, class filter); + action native A_DamageSelf(int amount, name damagetype = "none", int flags = 0, class filter, name species); + action native A_DamageTarget(int amount, name damagetype = "none", int flags = 0, class filter, name species); + action native A_DamageMaster(int amount, name damagetype = "none", int flags = 0, class filter, name species); + action native A_DamageTracer(int amount, name damagetype = "none", int flags = 0, class filter, name species); + action native A_DamageChildren(int amount, name damagetype = "none", int flags = 0, class filter, name species); + action native A_DamageSiblings(int amount, name damagetype = "none", int flags = 0, class filter, name species); + action native A_KillTarget(name damagetype = "none", int flags = 0, class filter, name species); + action native A_KillMaster(name damagetype = "none", int flags = 0, class filter, name species); + action native A_KillTracer(name damagetype = "none", int flags = 0, class filter, name species); + action native A_KillChildren(name damagetype = "none", int flags = 0, class filter, name species); + action native A_KillSiblings(name damagetype = "none", int flags = 0, class filter, name species); + action native A_RemoveTarget(int flags = 0, class filter, name species); + action native A_RemoveMaster(int flags = 0, class filter, name species); + action native A_RemoveTracer(int flags = 0, class filter, name species); + action native A_RemoveChildren(bool removeall = false, int flags = 0, class filter, name species); + action native A_RemoveSiblings(bool removeall = false, int flags = 0, class filter, name species); + action native A_Remove(int removee, int flags = 0, class filter, name species); action native A_GiveToChildren(class itemtype, int amount = 0); action native A_GiveToSiblings(class itemtype, int amount = 0); action native A_TakeFromChildren(class itemtype, int amount = 0); diff --git a/wadsrc/static/actors/constants.txt b/wadsrc/static/actors/constants.txt index 756fae981..1d4252188 100644 --- a/wadsrc/static/actors/constants.txt +++ b/wadsrc/static/actors/constants.txt @@ -401,6 +401,8 @@ const int KILS_FOILINVUL = 1; const int KILS_KILLMISSILES = 2; const int KILS_NOMONSTERS = 4; const int KILS_FOILBUDDHA = 8; +const int KILS_EXFILTER = 16; +const int KILS_EXSPECIES = 32; // Flags for A_Damage (Master/Target/Tracer/Children/Siblings/Self) series const int DMSS_FOILINVUL = 1; @@ -409,6 +411,8 @@ const int DMSS_KILL = 4; const int DMSS_NOFACTOR = 8; const int DMSS_FOILBUDDHA = 16; const int DMSS_NOPROTECT = 32; +const int DMSS_EXFILTER = 64; +const int DMSS_EXSPECIES = 128; // Flags for A_AlertMonsters const int AMF_TARGETEMITTER = 1; @@ -422,6 +426,8 @@ enum RMVF_NOMONSTERS = 1 << 1, RMVF_MISC = 1 << 2, RMVF_EVERYTHING = 1 << 3, + RMVF_EXFILTER = 1 << 4, + RMVF_EXSPECIES = 1 << 5, }; // Flags for A_Fade* From 2c7a3f2ebaa542364a90ed0ad7836e0cbe10a790 Mon Sep 17 00:00:00 2001 From: MajorCooke Date: Sun, 21 Dec 2014 10:38:51 -0600 Subject: [PATCH 28/46] - Optimized DoDamage and DoKill. - Do a filter and species check first to save time. - Added DMSS/KILS/RMVF_EITHER, which means if the actor is of type or species, it counts. - A_DamageTarget(20,"Normal",DMSS_EITHER,"DoomImp","CyberdemonSpecies") - This affects actor DoomImp, and anything that's of species CyberdemonSpecies. - Added a little more documentation via comments. --- src/thingdef/thingdef_codeptr.cpp | 102 ++++++++++++++++------------- wadsrc/static/actors/constants.txt | 50 ++++++++------ 2 files changed, 85 insertions(+), 67 deletions(-) diff --git a/src/thingdef/thingdef_codeptr.cpp b/src/thingdef/thingdef_codeptr.cpp index e61f33ea4..1edfc4f32 100644 --- a/src/thingdef/thingdef_codeptr.cpp +++ b/src/thingdef/thingdef_codeptr.cpp @@ -5039,44 +5039,51 @@ static bool DoCheckFilter(AActor *mo, const PClass *filter, bool exclude) // // Common A_Damage handler // -// A_Damage* (int amount, str damagetype, int flags) +// A_Damage* (int amount, str damagetype, int flags, str filter, str species) // Damages the specified actor by the specified amount. Negative values heal. +// Flags: See below. +// Filter: Specified actor is the only type allowed to be affected. +// Species: Specified species is the only type allowed to be affected. +// +// Examples: +// A_Damage(20,"Normal",DMSS_FOILINVUL,0,"DemonicSpecies") <--Only actors +// with a species "DemonicSpecies" will be affected. Use 0 to not filter by actor. // //=========================================================================== enum DMSS { - DMSS_FOILINVUL = 1, - DMSS_AFFECTARMOR = 2, - DMSS_KILL = 4, - DMSS_NOFACTOR = 8, - DMSS_FOILBUDDHA = 16, - DMSS_NOPROTECT = 32, - DMSS_EXFILTER = 64, - DMSS_EXSPECIES = 128, + DMSS_FOILINVUL = 1, //Foil invulnerability + DMSS_AFFECTARMOR = 2, //Make it affect armor + DMSS_KILL = 4, //Damages them for their current health + DMSS_NOFACTOR = 8, //Ignore DamageFactors + DMSS_FOILBUDDHA = 16, //Can kill actors with Buddha flag, except the player. + DMSS_NOPROTECT = 32, //Ignores PowerProtection entirely + DMSS_EXFILTER = 64, //Changes filter into a blacklisted class instead of whitelisted. + DMSS_EXSPECIES = 128, // ^ but with species instead. + DMSS_EITHER = 256, //Allow either type or species to be affected. }; static void DoDamage(AActor *dmgtarget, AActor *self, int amount, FName DamageType, int flags, const PClass *filter, FName species) { - int dmgFlags = 0; - if (flags & DMSS_FOILINVUL) - dmgFlags += DMG_FOILINVUL; - if (flags & DMSS_FOILBUDDHA) - dmgFlags += DMG_FOILBUDDHA; - if ((flags & DMSS_KILL) || (flags & DMSS_NOFACTOR)) //Kill implies NoFactor - dmgFlags += DMG_NO_FACTOR; - if (!(flags & DMSS_AFFECTARMOR) || (flags & DMSS_KILL)) //Kill overrides AffectArmor - dmgFlags += DMG_NO_ARMOR; - if (flags & DMSS_KILL) //Kill adds the value of the damage done to it. Allows for more controlled extreme death types. - amount += dmgtarget->health; - if (flags & DMSS_NOPROTECT) //Ignore PowerProtection. - dmgFlags += DMG_NO_PROTECT; - bool filterpass = DoCheckFilter(dmgtarget, filter, (flags & DMSS_EXFILTER) ? true : false), speciespass = DoCheckSpecies(dmgtarget, species, (flags & DMSS_EXSPECIES) ? true : false); - - if (filterpass && speciespass) + if ((flags & DMSS_EITHER) ? (filterpass || speciespass) : (filterpass && speciespass)) { + int dmgFlags = 0; + if (flags & DMSS_FOILINVUL) + dmgFlags += DMG_FOILINVUL; + if (flags & DMSS_FOILBUDDHA) + dmgFlags += DMG_FOILBUDDHA; + if ((flags & DMSS_KILL) || (flags & DMSS_NOFACTOR)) //Kill implies NoFactor + dmgFlags += DMG_NO_FACTOR; + if (!(flags & DMSS_AFFECTARMOR) || (flags & DMSS_KILL)) //Kill overrides AffectArmor + dmgFlags += DMG_NO_ARMOR; + if (flags & DMSS_KILL) //Kill adds the value of the damage done to it. Allows for more controlled extreme death types. + amount += dmgtarget->health; + if (flags & DMSS_NOPROTECT) //Ignore PowerProtection. + dmgFlags += DMG_NO_PROTECT; + if (amount > 0) P_DamageMobj(dmgtarget, self, self, amount, DamageType, dmgFlags); //Should wind up passing them through just fine. @@ -5228,27 +5235,29 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_DamageSiblings) //=========================================================================== enum KILS { - KILS_FOILINVUL = 1 << 0, - KILS_KILLMISSILES = 1 << 1, - KILS_NOMONSTERS = 1 << 2, - KILS_FOILBUDDHA = 1 << 3, - KILS_EXFILTER = 1 << 4, - KILS_EXSPECIES = 1 << 5, + KILS_FOILINVUL = 1 << 0, + KILS_KILLMISSILES = 1 << 1, + KILS_NOMONSTERS = 1 << 2, + KILS_FOILBUDDHA = 1 << 3, + KILS_EXFILTER = 1 << 4, + KILS_EXSPECIES = 1 << 5, + KILS_EITHER = 1 << 6, }; static void DoKill(AActor *killtarget, AActor *self, FName damagetype, int flags, const PClass *filter, FName species) { - int dmgFlags = DMG_NO_ARMOR + DMG_NO_FACTOR; - - if (KILS_FOILINVUL) - dmgFlags += DMG_FOILINVUL; - if (KILS_FOILBUDDHA) - dmgFlags += DMG_FOILBUDDHA; - bool filterpass = DoCheckFilter(killtarget, filter, (flags & KILS_EXFILTER) ? true : false), speciespass = DoCheckSpecies(killtarget, species, (flags & KILS_EXSPECIES) ? true : false); - if (filterpass && speciespass) //Check this first. I think it'll save the engine a lot more time this way. + if ((flags & KILS_EITHER) ? (filterpass || speciespass) : (filterpass && speciespass)) //Check this first. I think it'll save the engine a lot more time this way. { + int dmgFlags = DMG_NO_ARMOR + DMG_NO_FACTOR; + + if (KILS_FOILINVUL) + dmgFlags += DMG_FOILINVUL; + if (KILS_FOILBUDDHA) + dmgFlags += DMG_FOILBUDDHA; + + if ((killtarget->flags & MF_MISSILE) && (flags & KILS_KILLMISSILES)) { //[MC] Now that missiles can set masters, lets put in a check to properly destroy projectiles. BUT FIRST! New feature~! @@ -5386,19 +5395,20 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_KillSiblings) enum RMVF_flags { - RMVF_MISSILES = 1 << 0, - RMVF_NOMONSTERS = 1 << 1, - RMVF_MISC = 1 << 2, - RMVF_EVERYTHING = 1 << 3, - RMVF_EXFILTER = 1 << 4, - RMVF_EXSPECIES = 1 << 5, + RMVF_MISSILES = 1 << 0, + RMVF_NOMONSTERS = 1 << 1, + RMVF_MISC = 1 << 2, + RMVF_EVERYTHING = 1 << 3, + RMVF_EXFILTER = 1 << 4, + RMVF_EXSPECIES = 1 << 5, + RMVF_EITHER = 1 << 6, }; static void DoRemove(AActor *removetarget, int flags, const PClass *filter, FName species) { bool filterpass = DoCheckFilter(removetarget, filter, (flags & RMVF_EXFILTER) ? true : false), speciespass = DoCheckSpecies(removetarget, species, (flags & RMVF_EXSPECIES) ? true : false); - if (filterpass && speciespass) + if ((flags & RMVF_EITHER) ? (filterpass || speciespass) : (filterpass && speciespass)) { if ((flags & RMVF_EVERYTHING)) { diff --git a/wadsrc/static/actors/constants.txt b/wadsrc/static/actors/constants.txt index 1d4252188..e8ba15d46 100644 --- a/wadsrc/static/actors/constants.txt +++ b/wadsrc/static/actors/constants.txt @@ -396,23 +396,30 @@ enum }; // Flags for A_Kill (Master/Target/Tracer/Children/Siblings) series - -const int KILS_FOILINVUL = 1; -const int KILS_KILLMISSILES = 2; -const int KILS_NOMONSTERS = 4; -const int KILS_FOILBUDDHA = 8; -const int KILS_EXFILTER = 16; -const int KILS_EXSPECIES = 32; +enum +{ + KILS_FOILINVUL = 0x00000001, + KILS_KILLMISSILES = 0x00000002, + KILS_NOMONSTERS = 0x00000004, + KILS_FOILBUDDHA = 0x00000008, + KILS_EXFILTER = 0x00000010, + KILS_EXSPECIES = 0x00000020, + KILS_EITHER = 0x00000040, +}; // Flags for A_Damage (Master/Target/Tracer/Children/Siblings/Self) series -const int DMSS_FOILINVUL = 1; -const int DMSS_AFFECTARMOR = 2; -const int DMSS_KILL = 4; -const int DMSS_NOFACTOR = 8; -const int DMSS_FOILBUDDHA = 16; -const int DMSS_NOPROTECT = 32; -const int DMSS_EXFILTER = 64; -const int DMSS_EXSPECIES = 128; +enum +{ + DMSS_FOILINVUL = 0x00000001, + DMSS_AFFECTARMOR = 0x00000002, + DMSS_KILL = 0x00000004, + DMSS_NOFACTOR = 0x00000008, + DMSS_FOILBUDDHA = 0x00000010, + DMSS_NOPROTECT = 0x00000020, + DMSS_EXFILTER = 0x00000040, + DMSS_EXSPECIES = 0x00000080, + DMSS_EITHER = 0x00000100, +}; // Flags for A_AlertMonsters const int AMF_TARGETEMITTER = 1; @@ -422,12 +429,13 @@ const int AMF_EMITFROMTARGET = 4; // Flags for A_Remove* enum { - RMVF_MISSILES = 1 << 0, - RMVF_NOMONSTERS = 1 << 1, - RMVF_MISC = 1 << 2, - RMVF_EVERYTHING = 1 << 3, - RMVF_EXFILTER = 1 << 4, - RMVF_EXSPECIES = 1 << 5, + RMVF_MISSILES = 0x00000001, + RMVF_NOMONSTERS = 0x00000002, + RMVF_MISC = 0x00000004, + RMVF_EVERYTHING = 0x00000008, + RMVF_EXFILTER = 0x00000010, + RMVF_EXSPECIES = 0x00000020, + RMVF_EITHER = 0x00000040, }; // Flags for A_Fade* From 91bfe4cceb8648b0c1c84622d212f4e03a4988e1 Mon Sep 17 00:00:00 2001 From: MajorCooke Date: Sun, 21 Dec 2014 12:29:19 -0600 Subject: [PATCH 29/46] - Added pointers for A_CustomMissile and A_CustomBulletAttack. --- src/p_enemy.h | 2 ++ src/thingdef/thingdef_codeptr.cpp | 25 ++++++++++++++++++------- wadsrc/static/actors/actor.txt | 4 ++-- 3 files changed, 22 insertions(+), 9 deletions(-) diff --git a/src/p_enemy.h b/src/p_enemy.h index ff40c7003..8c5516ead 100644 --- a/src/p_enemy.h +++ b/src/p_enemy.h @@ -73,6 +73,8 @@ DECLARE_ACTION(A_BossDeath) void A_Chase(AActor *self); void A_FaceTarget (AActor *actor, angle_t max_turn = 0, angle_t max_pitch = ANGLE_270); +void A_FaceMaster(AActor *actor, angle_t max_turn = 0, angle_t max_pitch = ANGLE_270); +void A_FaceTracer(AActor *actor, angle_t max_turn = 0, angle_t max_pitch = ANGLE_270); bool A_RaiseMobj (AActor *, fixed_t speed); bool A_SinkMobj (AActor *, fixed_t speed); diff --git a/src/thingdef/thingdef_codeptr.cpp b/src/thingdef/thingdef_codeptr.cpp index 98451795b..0f37efa18 100644 --- a/src/thingdef/thingdef_codeptr.cpp +++ b/src/thingdef/thingdef_codeptr.cpp @@ -907,20 +907,23 @@ enum CM_Flags DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_CustomMissile) { - ACTION_PARAM_START(6); + ACTION_PARAM_START(7); ACTION_PARAM_CLASS(ti, 0); ACTION_PARAM_FIXED(SpawnHeight, 1); ACTION_PARAM_INT(Spawnofs_XY, 2); ACTION_PARAM_ANGLE(Angle, 3); ACTION_PARAM_INT(flags, 4); ACTION_PARAM_ANGLE(pitch, 5); + ACTION_PARAM_INT(ptr, 6); + + AActor *ref = COPY_AAPTR(self, ptr); int aimmode = flags & CMF_AIMMODE; AActor * targ; AActor * missile; - if (self->target != NULL || aimmode==2) + if (ref != NULL || aimmode==2) { if (ti) { @@ -937,14 +940,14 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_CustomMissile) self->x += x; self->y += y; self->z += z; - missile = P_SpawnMissileXYZ(self->x, self->y, self->z + 32*FRACUNIT, self, self->target, ti, false); + missile = P_SpawnMissileXYZ(self->x, self->y, self->z + 32*FRACUNIT, self, ref, ti, false); self->x -= x; self->y -= y; self->z -= z; break; case 1: - missile = P_SpawnMissileXYZ(self->x+x, self->y+y, self->z + self->GetBobOffset() + SpawnHeight, self, self->target, ti, false); + missile = P_SpawnMissileXYZ(self->x+x, self->y+y, self->z + self->GetBobOffset() + SpawnHeight, self, ref, ti, false); break; case 2: @@ -1056,7 +1059,7 @@ enum CBA_Flags DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_CustomBulletAttack) { - ACTION_PARAM_START(7); + ACTION_PARAM_START(8); ACTION_PARAM_ANGLE(Spread_XY, 0); ACTION_PARAM_ANGLE(Spread_Z, 1); ACTION_PARAM_INT(NumBullets, 2); @@ -1064,6 +1067,9 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_CustomBulletAttack) ACTION_PARAM_CLASS(pufftype, 4); ACTION_PARAM_FIXED(Range, 5); ACTION_PARAM_INT(Flags, 6); + ACTION_PARAM_INT(ptr, 7); + + AActor *ref = COPY_AAPTR(self, ptr); if(Range==0) Range=MISSILERANGE; @@ -1072,9 +1078,14 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_CustomBulletAttack) int bslope = 0; int laflags = (Flags & CBAF_NORANDOMPUFFZ)? LAF_NORANDOMPUFFZ : 0; - if (self->target || (Flags & CBAF_AIMFACING)) + if (ref || (Flags & CBAF_AIMFACING)) { - if (!(Flags & CBAF_AIMFACING)) A_FaceTarget (self); + if (!(Flags & CBAF_AIMFACING)) + { + if (ref == self->target) A_FaceTarget(self); + else if (ref == self->master) A_FaceMaster(self); + else if (ref == self->tracer) A_FaceTracer(self); + } bangle = self->angle; if (!pufftype) pufftype = PClass::FindClass(NAME_BulletPuff); diff --git a/wadsrc/static/actors/actor.txt b/wadsrc/static/actors/actor.txt index cd718b1c0..17b762d68 100644 --- a/wadsrc/static/actors/actor.txt +++ b/wadsrc/static/actors/actor.txt @@ -204,8 +204,8 @@ ACTOR Actor native //: Thinker action native A_StopSoundEx(coerce name slot); action native A_SeekerMissile(int threshold, int turnmax, int flags = 0, int chance = 50, int distance = 10); action native A_Jump(int chance = 256, state label, ...); - action native A_CustomMissile(class missiletype, float spawnheight = 32, int spawnofs_xy = 0, float angle = 0, int flags = 0, float pitch = 0); - action native A_CustomBulletAttack(float spread_xy, float spread_z, int numbullets, int damageperbullet, class pufftype = "BulletPuff", float range = 0, int flags = 0); + action native A_CustomMissile(class missiletype, float spawnheight = 32, int spawnofs_xy = 0, float angle = 0, int flags = 0, float pitch = 0, int ptr = AAPTR_TARGET); + action native A_CustomBulletAttack(float spread_xy, float spread_z, int numbullets, int damageperbullet, class pufftype = "BulletPuff", float range = 0, int flags = 0, int ptr = AAPTR_TARGET); action native A_CustomRailgun(int damage, int spawnofs_xy = 0, color color1 = "", color color2 = "", int flags = 0, bool aim = false, float maxdiff = 0, class pufftype = "BulletPuff", float spread_xy = 0, float spread_z = 0, float range = 0, int duration = 0, float sparsity = 1.0, float driftspeed = 1.0, class spawnclass = "none", float spawnofs_z = 0); action native A_JumpIfHealthLower(int health, state label, int ptr_selector = AAPTR_DEFAULT); action native A_JumpIfCloser(float distance, state label); From aebf0e75262e1f658f582453c2c8be08300a4740 Mon Sep 17 00:00:00 2001 From: ChillyDoom Date: Sun, 21 Dec 2014 19:21:51 +0000 Subject: [PATCH 30/46] - Fixed: Adding multiple bots at the same time could cause the game to crash if there were too few bots defined. - The 'loaded_bots' variable no longer needs to be stored. --- src/b_bot.h | 5 ++-- src/b_game.cpp | 62 +++++++++++++++++++++++++++----------------------- 2 files changed, 36 insertions(+), 31 deletions(-) diff --git a/src/b_bot.h b/src/b_bot.h index 69a2f7774..25689a9be 100644 --- a/src/b_bot.h +++ b/src/b_bot.h @@ -130,7 +130,6 @@ private: protected: bool ctf; - int loaded_bots; int t_join; bool observer; //Consoleplayer is observer. }; @@ -188,12 +187,12 @@ public: fixed_t oldy; private: - //(B_think.cpp) + //(b_think.cpp) void Think (); void ThinkForMove (ticcmd_t *cmd); void Set_enemy (); - //(B_func.cpp) + //(b_func.cpp) bool Reachable (AActor *target); void Dofire (ticcmd_t *cmd); AActor *Choose_Mate (); diff --git a/src/b_game.cpp b/src/b_game.cpp index 44aff03fa..9c222f464 100644 --- a/src/b_game.cpp +++ b/src/b_game.cpp @@ -216,19 +216,16 @@ bool FCajunMaster::SpawnBot (const char *name, int color) "\\color\\cf df 90" //10 = Bleached Bone }; - botinfo_t *thebot; - int botshift; + botinfo_t *thebot = botinfo; + int botshift = 0; if (name) { - thebot = botinfo; - // Check if exist or already in the game. - botshift = 0; while (thebot && stricmp (name, thebot->name)) { - thebot = thebot->next; botshift++; + thebot = thebot->next; } if (thebot == NULL) @@ -246,27 +243,36 @@ bool FCajunMaster::SpawnBot (const char *name, int color) return false; } } - else if (botnum < loaded_bots) - { - bool vacant = false; //Spawn a random bot from bots.cfg if no name given. - while (!vacant) - { - int rnum = (pr_botspawn() % loaded_bots); - thebot = botinfo; - botshift = 0; - while (rnum) - { - --rnum, thebot = thebot->next; - botshift++; - } - if (thebot->inuse == BOTINUSE_No) - vacant = true; - } - } else { - Printf ("Couldn't spawn bot; no bot left in %s\n", BOTFILENAME); - return false; + //Spawn a random bot from bots.cfg if no name given. + TArray BotInfoAvailable; + + while (thebot) + { + if (thebot->inuse == BOTINUSE_No) + BotInfoAvailable.Push (thebot); + + thebot = thebot->next; + } + + if (BotInfoAvailable.Size () == 0) + { + Printf ("Couldn't spawn bot; no bot left in %s\n", BOTFILENAME); + return false; + } + + thebot = BotInfoAvailable[pr_botspawn() % BotInfoAvailable.Size ()]; + + botinfo_t *thebot2 = botinfo; + while (thebot2) + { + if (thebot == thebot2) + break; + + botshift++; + thebot2 = thebot2->next; + } } thebot->inuse = BOTINUSE_Waiting; @@ -478,7 +484,6 @@ void FCajunMaster::ForgetBots () } botinfo = NULL; - loaded_bots = 0; } bool FCajunMaster::LoadBots () @@ -486,6 +491,7 @@ bool FCajunMaster::LoadBots () FScanner sc; FString tmp; bool gotteam = false; + int loaded_bots = 0; bglobal.ForgetBots (); tmp = M_GetCajunPath(BOTFILENAME); @@ -602,9 +608,9 @@ bool FCajunMaster::LoadBots () newinfo->next = bglobal.botinfo; newinfo->lastteam = TEAM_NONE; bglobal.botinfo = newinfo; - bglobal.loaded_bots++; + loaded_bots++; } - Printf ("%d bots read from %s\n", bglobal.loaded_bots, BOTFILENAME); + Printf ("%d bots read from %s\n", loaded_bots, BOTFILENAME); return true; } From 2b323d01edbd6c7c56ff818dd80218270ab7ead4 Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Sun, 21 Dec 2014 21:22:14 -0600 Subject: [PATCH 31/46] Reorder pick parsing to require one parameter. - This function is pointless without any parameters, so don't allow that. --- src/thingdef/thingdef_exp.cpp | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/src/thingdef/thingdef_exp.cpp b/src/thingdef/thingdef_exp.cpp index daa7f1a9c..2ad741294 100644 --- a/src/thingdef/thingdef_exp.cpp +++ b/src/thingdef/thingdef_exp.cpp @@ -390,16 +390,14 @@ static FxExpression *ParseExpression0 (FScanner &sc, const PClass *cls) } sc.MustGetToken('('); - while (!(sc.CheckToken(')'))) + for (;;) { - FxExpression *min = ParseExpressionM(sc, cls); - list.Push(min); + FxExpression *expr = ParseExpressionM(sc, cls); + list.Push(expr); if (sc.CheckToken(')')) break; - else - sc.MustGetToken(','); + sc.MustGetToken(','); } - return new FxPick(rng, list, sc); } else if (sc.CheckToken(TK_FRandom)) From f7405a1d245bf7938704dc73cb17b58accd0fbbe Mon Sep 17 00:00:00 2001 From: ChillyDoom Date: Mon, 22 Dec 2014 20:48:27 +0000 Subject: [PATCH 32/46] - Changed two loops from using doomcom.numnodes back to MAXPLAYERS as nodeingame[i] is not necessarily the same as playeringame[playerfornode[i]]. --- src/d_net.cpp | 27 +++++++++++++++------------ 1 file changed, 15 insertions(+), 12 deletions(-) diff --git a/src/d_net.cpp b/src/d_net.cpp index 02ca8c0c4..0e3ae262e 100644 --- a/src/d_net.cpp +++ b/src/d_net.cpp @@ -1064,16 +1064,16 @@ void NetUpdate (void) if (consoleplayer == Net_Arbitrator) { - for (j = 0; j < doomcom.numnodes; j++) - { - if (nodeingame[j] && NetMode == NET_PacketServer) - { - count++; - } - } - if (NetMode == NET_PacketServer) { + for (j = 0; j < MAXPLAYERS; j++) + { + if (playeringame[j] && players[j].Bot == NULL) + { + count++; + } + } + // The loop above added the local player to the count a second time, // and it also added the player being sent the packet to the count. count -= 2; @@ -1203,12 +1203,15 @@ void NetUpdate (void) netbuffer[0] |= NCMD_MULTI; netbuffer[k++] = count; - for (l = 1, j = 0; j < doomcom.numnodes; j++) + if (NetMode == NET_PacketServer) { - if (nodeingame[j] && j != i && j != nodeforplayer[consoleplayer] && NetMode == NET_PacketServer) + for (l = 1, j = 0; j < MAXPLAYERS; j++) { - playerbytes[l++] = playerfornode[j]; - netbuffer[k++] = playerfornode[j]; + if (playeringame[j] && players[j].Bot == NULL && j != playerfornode[i] && j != consoleplayer) + { + playerbytes[l++] = j; + netbuffer[k++] = j; + } } } } From b24f173d03653d449301b6476a77c4ac563677e2 Mon Sep 17 00:00:00 2001 From: Edward Richardson Date: Tue, 23 Dec 2014 22:20:39 +1300 Subject: [PATCH 33/46] Allow players to be popped in packet-server --- src/d_net.cpp | 44 ++++++++++++++++++++++++++++---------------- 1 file changed, 28 insertions(+), 16 deletions(-) diff --git a/src/d_net.cpp b/src/d_net.cpp index 02ca8c0c4..4f56a32a9 100644 --- a/src/d_net.cpp +++ b/src/d_net.cpp @@ -669,25 +669,38 @@ void PlayerIsGone (int netnode, int netconsole) { int i; - if (!nodeingame[netnode]) - return; + if (nodeingame[netnode]) + { + for (i = netnode + 1; i < doomcom.numnodes; ++i) + { + if (nodeingame[i]) + break; + } + if (i == doomcom.numnodes) + { + doomcom.numnodes = netnode; + } - for (i = netnode + 1; i < doomcom.numnodes; ++i) - { - if (nodeingame[i]) - break; + if (playeringame[netconsole]) + { + players[netconsole].playerstate = PST_GONE; + } + nodeingame[netnode] = false; + nodejustleft[netnode] = false; } - if (i == doomcom.numnodes) + else if (nodejustleft[netnode]) // Packet Server { - doomcom.numnodes = netnode; + if (netnode + 1 == doomcom.numnodes) + { + doomcom.numnodes = netnode; + } + if (playeringame[netconsole]) + { + players[netconsole].playerstate = PST_GONE; + } + nodejustleft[netnode] = false; } - - if (playeringame[netconsole]) - { - players[netconsole].playerstate = PST_GONE; - } - nodeingame[netnode] = false; - nodejustleft[netnode] = false; + else return; if (netconsole == Net_Arbitrator) { @@ -790,7 +803,6 @@ void GetPackets (void) else { nodeingame[netnode] = false; - playeringame[netconsole] = false; nodejustleft[netnode] = true; } continue; From dfa6a44402bcd8a4ae47c9e1fa68c3ed68b6a3ef Mon Sep 17 00:00:00 2001 From: Edward Richardson Date: Tue, 23 Dec 2014 22:38:12 +1300 Subject: [PATCH 34/46] Ignore 0 length chat messages - There is no reason to send empty messages, and they just produced strange output anyway --- src/ct_chat.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/ct_chat.cpp b/src/ct_chat.cpp index c0b73d3c0..10ff2bffb 100644 --- a/src/ct_chat.cpp +++ b/src/ct_chat.cpp @@ -343,6 +343,9 @@ static void CT_ClearChatMessage () static void ShoveChatStr (const char *str, BYTE who) { + if (strlen(str) < 1) // Don't send empty messages + return; + FString substBuff; if (str[0] == '/' && From d7d022144e10bd0ff447b5d1f7533646c69be9b4 Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Tue, 23 Dec 2014 21:30:24 -0600 Subject: [PATCH 35/46] Call A_Face() directly from A_CustomBullletAttack --- src/p_enemy.h | 5 ++--- src/thingdef/thingdef_codeptr.cpp | 4 +--- 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/src/p_enemy.h b/src/p_enemy.h index 8c5516ead..f5cc387dd 100644 --- a/src/p_enemy.h +++ b/src/p_enemy.h @@ -72,9 +72,8 @@ DECLARE_ACTION(A_FreezeDeathChunks) DECLARE_ACTION(A_BossDeath) void A_Chase(AActor *self); -void A_FaceTarget (AActor *actor, angle_t max_turn = 0, angle_t max_pitch = ANGLE_270); -void A_FaceMaster(AActor *actor, angle_t max_turn = 0, angle_t max_pitch = ANGLE_270); -void A_FaceTracer(AActor *actor, angle_t max_turn = 0, angle_t max_pitch = ANGLE_270); +void A_FaceTarget(AActor *actor, angle_t max_turn = 0, angle_t max_pitch = ANGLE_270); +void A_Face(AActor *self, AActor *other, angle_t max_turn = 0, angle_t max_pitch = ANGLE_270); bool A_RaiseMobj (AActor *, fixed_t speed); bool A_SinkMobj (AActor *, fixed_t speed); diff --git a/src/thingdef/thingdef_codeptr.cpp b/src/thingdef/thingdef_codeptr.cpp index 0f37efa18..9fdc14a28 100644 --- a/src/thingdef/thingdef_codeptr.cpp +++ b/src/thingdef/thingdef_codeptr.cpp @@ -1082,9 +1082,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_CustomBulletAttack) { if (!(Flags & CBAF_AIMFACING)) { - if (ref == self->target) A_FaceTarget(self); - else if (ref == self->master) A_FaceMaster(self); - else if (ref == self->tracer) A_FaceTracer(self); + A_Face(self, ref); } bangle = self->angle; From 5caadeba4c349c6c7de82d667eb161007869f558 Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Tue, 23 Dec 2014 21:33:47 -0600 Subject: [PATCH 36/46] Use a null check instead of strlen in ShoveChatStr --- src/ct_chat.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/ct_chat.cpp b/src/ct_chat.cpp index 10ff2bffb..78efab9d0 100644 --- a/src/ct_chat.cpp +++ b/src/ct_chat.cpp @@ -343,7 +343,8 @@ static void CT_ClearChatMessage () static void ShoveChatStr (const char *str, BYTE who) { - if (strlen(str) < 1) // Don't send empty messages + // Don't send empty messages + if (str == NULL || str[0] == '\0') return; FString substBuff; From 3fb9e754f1e1f0fbcd267712aa44386987487e54 Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Tue, 23 Dec 2014 21:46:27 -0600 Subject: [PATCH 37/46] Rename 'Pick' to 'RandomPick' ... because 'pick' is way too generic a name to spend a keyword on. --- src/sc_man_scanner.re | 2 +- src/sc_man_tokens.h | 2 +- src/thingdef/thingdef_exp.cpp | 4 ++-- src/thingdef/thingdef_exp.h | 6 +++--- src/thingdef/thingdef_expression.cpp | 8 ++++---- 5 files changed, 11 insertions(+), 11 deletions(-) diff --git a/src/sc_man_scanner.re b/src/sc_man_scanner.re index 3a7f717a8..52a5d9f61 100644 --- a/src/sc_man_scanner.re +++ b/src/sc_man_scanner.re @@ -158,7 +158,7 @@ std2: 'random' { RET(TK_Random); } 'random2' { RET(TK_Random2); } 'frandom' { RET(TK_FRandom); } - 'pick' { RET(TK_Pick); } + 'randompick' { RET(TK_RandomPick); } L (L|D)* { RET(TK_Identifier); } diff --git a/src/sc_man_tokens.h b/src/sc_man_tokens.h index 1c22046c9..22f6e9cd4 100644 --- a/src/sc_man_tokens.h +++ b/src/sc_man_tokens.h @@ -122,5 +122,5 @@ xx(TK_Array, "'array'") xx(TK_In, "'in'") xx(TK_SizeOf, "'sizeof'") xx(TK_AlignOf, "'alignof'") -xx(TK_Pick, "'pick'") +xx(TK_RandomPick, "'randompick'") #undef xx diff --git a/src/thingdef/thingdef_exp.cpp b/src/thingdef/thingdef_exp.cpp index 2ad741294..7bd10b38d 100644 --- a/src/thingdef/thingdef_exp.cpp +++ b/src/thingdef/thingdef_exp.cpp @@ -371,7 +371,7 @@ static FxExpression *ParseExpression0 (FScanner &sc, const PClass *cls) return new FxRandom(rng, min, max, sc); } - else if (sc.CheckToken(TK_Pick)) + else if (sc.CheckToken(TK_RandomPick)) { FRandom *rng; TArray list; @@ -398,7 +398,7 @@ static FxExpression *ParseExpression0 (FScanner &sc, const PClass *cls) break; sc.MustGetToken(','); } - return new FxPick(rng, list, sc); + return new FxRandomPick(rng, list, sc); } else if (sc.CheckToken(TK_FRandom)) { diff --git a/src/thingdef/thingdef_exp.h b/src/thingdef/thingdef_exp.h index 0e03c661f..807ffcd87 100644 --- a/src/thingdef/thingdef_exp.h +++ b/src/thingdef/thingdef_exp.h @@ -559,7 +559,7 @@ public: // //========================================================================== -class FxPick : public FxExpression +class FxRandomPick : public FxExpression { protected: FRandom * rng; @@ -567,8 +567,8 @@ protected: public: - FxPick(FRandom *, TArray mi, const FScriptPosition &pos); - ~FxPick(); + FxRandomPick(FRandom *, TArray mi, const FScriptPosition &pos); + ~FxRandomPick(); FxExpression *Resolve(FCompileContext&); ExpVal EvalExpression(AActor *self); diff --git a/src/thingdef/thingdef_expression.cpp b/src/thingdef/thingdef_expression.cpp index 913079bd2..d1c2eba9e 100644 --- a/src/thingdef/thingdef_expression.cpp +++ b/src/thingdef/thingdef_expression.cpp @@ -1696,7 +1696,7 @@ ExpVal FxRandom::EvalExpression (AActor *self) // // //========================================================================== -FxPick::FxPick(FRandom * r, TArray mi, const FScriptPosition &pos) +FxRandomPick::FxRandomPick(FRandom * r, TArray mi, const FScriptPosition &pos) : FxExpression(pos) { for (unsigned int index = 0; index < mi.Size(); index++) @@ -1713,7 +1713,7 @@ FxPick::FxPick(FRandom * r, TArray mi, const FScriptPosition &pos // //========================================================================== -FxPick::~FxPick() +FxRandomPick::~FxRandomPick() { } @@ -1723,7 +1723,7 @@ FxPick::~FxPick() // //========================================================================== -FxExpression *FxPick::Resolve(FCompileContext &ctx) +FxExpression *FxRandomPick::Resolve(FCompileContext &ctx) { CHECKRESOLVED(); for (unsigned int index = 0; index < min.Size(); index++) @@ -1741,7 +1741,7 @@ FxExpression *FxPick::Resolve(FCompileContext &ctx) // //========================================================================== -ExpVal FxPick::EvalExpression(AActor *self) +ExpVal FxRandomPick::EvalExpression(AActor *self) { ExpVal val; val.Type = VAL_Int; From 62a4945ca4e1264c74670ad00d9f67d76a880953 Mon Sep 17 00:00:00 2001 From: MajorCooke Date: Tue, 23 Dec 2014 23:30:00 -0600 Subject: [PATCH 38/46] - Fixed: CAUSEPAIN didn't work with A_Explode calls featuring no damage. --- src/p_map.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/p_map.cpp b/src/p_map.cpp index 496abbf0d..0b86aa41e 100644 --- a/src/p_map.cpp +++ b/src/p_map.cpp @@ -4765,7 +4765,7 @@ void P_RadiusAttack(AActor *bombspot, AActor *bombsource, int bombdamage, int bo points *= thing->GetClass()->Meta.GetMetaFixed(AMETA_RDFactor, FRACUNIT) / (double)FRACUNIT; // points and bombdamage should be the same sign - if ((points * bombdamage) > 0 && P_CheckSight(thing, bombspot, SF_IGNOREVISIBILITY | SF_IGNOREWATERBOUNDARY)) + if (((bombspot->flags7 & MF7_CAUSEPAIN) || (points * bombdamage) > 0) && P_CheckSight(thing, bombspot, SF_IGNOREVISIBILITY | SF_IGNOREWATERBOUNDARY)) { // OK to damage; target is in direct path double velz; double thrust; From 7d628a8c034ce073ef4797ae59f2a2b9327942ba Mon Sep 17 00:00:00 2001 From: ChillyDoom Date: Wed, 24 Dec 2014 19:41:49 +0000 Subject: [PATCH 39/46] - Fixed: FCajunMaster::End() was missing a bot check. --- src/b_game.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/b_game.cpp b/src/b_game.cpp index 9c222f464..e136f3f29 100644 --- a/src/b_game.cpp +++ b/src/b_game.cpp @@ -178,7 +178,10 @@ void FCajunMaster::End () { for (i = 0; i < MAXPLAYERS; i++) { - getspawned.Push(players[i].userinfo.GetName()); + if (players[i].Bot != NULL) + { + getspawned.Push(players[i].userinfo.GetName()); + } } wanted_botnum = botnum; From d94be8f57bc0d59d0cfb2666438aefa792252e6e Mon Sep 17 00:00:00 2001 From: MajorCooke Date: Wed, 24 Dec 2014 17:15:21 -0600 Subject: [PATCH 40/46] - Reverted back and set filter to "None" instead. --- wadsrc/static/actors/actor.txt | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/wadsrc/static/actors/actor.txt b/wadsrc/static/actors/actor.txt index 7faf389e7..fcc8d5ded 100644 --- a/wadsrc/static/actors/actor.txt +++ b/wadsrc/static/actors/actor.txt @@ -298,23 +298,23 @@ ACTOR Actor native //: Thinker action native A_SetDamageType(name damagetype); action native A_DropItem(class item, int dropamount = -1, int chance = 256); action native A_SetSpeed(float speed); - action native A_DamageSelf(int amount, name damagetype = "none", int flags = 0, class filter, name species); - action native A_DamageTarget(int amount, name damagetype = "none", int flags = 0, class filter, name species); - action native A_DamageMaster(int amount, name damagetype = "none", int flags = 0, class filter, name species); - action native A_DamageTracer(int amount, name damagetype = "none", int flags = 0, class filter, name species); - action native A_DamageChildren(int amount, name damagetype = "none", int flags = 0, class filter, name species); - action native A_DamageSiblings(int amount, name damagetype = "none", int flags = 0, class filter, name species); - action native A_KillTarget(name damagetype = "none", int flags = 0, class filter, name species); - action native A_KillMaster(name damagetype = "none", int flags = 0, class filter, name species); - action native A_KillTracer(name damagetype = "none", int flags = 0, class filter, name species); - action native A_KillChildren(name damagetype = "none", int flags = 0, class filter, name species); - action native A_KillSiblings(name damagetype = "none", int flags = 0, class filter, name species); - action native A_RemoveTarget(int flags = 0, class filter, name species); - action native A_RemoveMaster(int flags = 0, class filter, name species); - action native A_RemoveTracer(int flags = 0, class filter, name species); - action native A_RemoveChildren(bool removeall = false, int flags = 0, class filter, name species); - action native A_RemoveSiblings(bool removeall = false, int flags = 0, class filter, name species); - action native A_Remove(int removee, int flags = 0, class filter, name species); + action native A_DamageSelf(int amount, name damagetype = "none", int flags = 0, class filter = "None", name species); + action native A_DamageTarget(int amount, name damagetype = "none", int flags = 0, class filter = "None", name species); + action native A_DamageMaster(int amount, name damagetype = "none", int flags = 0, class filter = "None", name species); + action native A_DamageTracer(int amount, name damagetype = "none", int flags = 0, class filter = "None", name species); + action native A_DamageChildren(int amount, name damagetype = "none", int flags = 0, class filter = "None", name species); + action native A_DamageSiblings(int amount, name damagetype = "none", int flags = 0, class filter = "None", name species); + action native A_KillTarget(name damagetype = "none", int flags = 0, class filter = "None", name species); + action native A_KillMaster(name damagetype = "none", int flags = 0, class filter = "None", name species); + action native A_KillTracer(name damagetype = "none", int flags = 0, class filter = "None", name species); + action native A_KillChildren(name damagetype = "none", int flags = 0, class filter = "None", name species); + action native A_KillSiblings(name damagetype = "none", int flags = 0, class filter = "None", name species); + action native A_RemoveTarget(int flags = 0, class filter = "None", name species); + action native A_RemoveMaster(int flags = 0, class filter = "None", name species); + action native A_RemoveTracer(int flags = 0, class filter = "None", name species); + action native A_RemoveChildren(bool removeall = false, int flags = 0, class filter = "None", name species); + action native A_RemoveSiblings(bool removeall = false, int flags = 0, class filter = "None", name species); + action native A_Remove(int removee, int flags = 0, class filter = "None", name species); action native A_GiveToChildren(class itemtype, int amount = 0); action native A_GiveToSiblings(class itemtype, int amount = 0); action native A_TakeFromChildren(class itemtype, int amount = 0); From f2551dceda96d4fc3f73b3c353fbbb9baa54264a Mon Sep 17 00:00:00 2001 From: MajorCooke Date: Wed, 24 Dec 2014 17:49:58 -0600 Subject: [PATCH 41/46] - Corrected the species checking. --- src/thingdef/thingdef_codeptr.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/thingdef/thingdef_codeptr.cpp b/src/thingdef/thingdef_codeptr.cpp index c5e0b860a..50969ce85 100644 --- a/src/thingdef/thingdef_codeptr.cpp +++ b/src/thingdef/thingdef_codeptr.cpp @@ -5034,8 +5034,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_SetSpeed) static bool DoCheckSpecies(AActor *mo, FName species, bool exclude) { - FName spec = mo->Species; - return (!(species) || !(stricmp(species, "")) || (species && ((exclude) ? (spec != species) : (spec == species)))); + return (!(species) || mo->Species == NAME_None || (species && ((exclude) ? (mo->Species != species) : (mo->Species == species)))); } static bool DoCheckFilter(AActor *mo, const PClass *filter, bool exclude) From 15cd0debc1a618d4cdfc69c1dea6bc759f04719d Mon Sep 17 00:00:00 2001 From: MajorCooke Date: Thu, 25 Dec 2014 09:23:59 -0600 Subject: [PATCH 42/46] - Fixed: Species was not defined in actor.txt. --- wadsrc/static/actors/actor.txt | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/wadsrc/static/actors/actor.txt b/wadsrc/static/actors/actor.txt index fcc8d5ded..73a5e0e4d 100644 --- a/wadsrc/static/actors/actor.txt +++ b/wadsrc/static/actors/actor.txt @@ -298,23 +298,23 @@ ACTOR Actor native //: Thinker action native A_SetDamageType(name damagetype); action native A_DropItem(class item, int dropamount = -1, int chance = 256); action native A_SetSpeed(float speed); - action native A_DamageSelf(int amount, name damagetype = "none", int flags = 0, class filter = "None", name species); - action native A_DamageTarget(int amount, name damagetype = "none", int flags = 0, class filter = "None", name species); - action native A_DamageMaster(int amount, name damagetype = "none", int flags = 0, class filter = "None", name species); - action native A_DamageTracer(int amount, name damagetype = "none", int flags = 0, class filter = "None", name species); - action native A_DamageChildren(int amount, name damagetype = "none", int flags = 0, class filter = "None", name species); - action native A_DamageSiblings(int amount, name damagetype = "none", int flags = 0, class filter = "None", name species); - action native A_KillTarget(name damagetype = "none", int flags = 0, class filter = "None", name species); - action native A_KillMaster(name damagetype = "none", int flags = 0, class filter = "None", name species); - action native A_KillTracer(name damagetype = "none", int flags = 0, class filter = "None", name species); - action native A_KillChildren(name damagetype = "none", int flags = 0, class filter = "None", name species); - action native A_KillSiblings(name damagetype = "none", int flags = 0, class filter = "None", name species); - action native A_RemoveTarget(int flags = 0, class filter = "None", name species); - action native A_RemoveMaster(int flags = 0, class filter = "None", name species); - action native A_RemoveTracer(int flags = 0, class filter = "None", name species); - action native A_RemoveChildren(bool removeall = false, int flags = 0, class filter = "None", name species); - action native A_RemoveSiblings(bool removeall = false, int flags = 0, class filter = "None", name species); - action native A_Remove(int removee, int flags = 0, class filter = "None", name species); + action native A_DamageSelf(int amount, name damagetype = "none", int flags = 0, class filter = "None", name species = "None"); + action native A_DamageTarget(int amount, name damagetype = "none", int flags = 0, class filter = "None", name species = "None"); + action native A_DamageMaster(int amount, name damagetype = "none", int flags = 0, class filter = "None", name species = "None"); + action native A_DamageTracer(int amount, name damagetype = "none", int flags = 0, class filter = "None", name species = "None"); + action native A_DamageChildren(int amount, name damagetype = "none", int flags = 0, class filter = "None", name species = "None"); + action native A_DamageSiblings(int amount, name damagetype = "none", int flags = 0, class filter = "None", name species = "None"); + action native A_KillTarget(name damagetype = "none", int flags = 0, class filter = "None", name species = "None"); + action native A_KillMaster(name damagetype = "none", int flags = 0, class filter = "None", name species = "None"); + action native A_KillTracer(name damagetype = "none", int flags = 0, class filter = "None", name species = "None"); + action native A_KillChildren(name damagetype = "none", int flags = 0, class filter = "None", name species = "None"); + action native A_KillSiblings(name damagetype = "none", int flags = 0, class filter = "None", name species = "None"); + action native A_RemoveTarget(int flags = 0, class filter = "None", name species = "None"); + action native A_RemoveMaster(int flags = 0, class filter = "None", name species = "None"); + action native A_RemoveTracer(int flags = 0, class filter = "None", name species = "None"); + action native A_RemoveChildren(bool removeall = false, int flags = 0, class filter = "None", name species = "None"); + action native A_RemoveSiblings(bool removeall = false, int flags = 0, class filter = "None", name species = "None"); + action native A_Remove(int removee, int flags = 0, class filter = "None", name species = "None"); action native A_GiveToChildren(class itemtype, int amount = 0); action native A_GiveToSiblings(class itemtype, int amount = 0); action native A_TakeFromChildren(class itemtype, int amount = 0); From 6fd70ff32018bdd8c1e1182954390a312f7bf705 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Thu, 25 Dec 2014 18:46:50 +0100 Subject: [PATCH 43/46] - fixed: Trying to rotate a polyobject into its actual position during loading of a savegame still inflicted damage on all touching actors - including incomplete player pawns - and also got blocked by them. Similar code already existed for the MovePolyobj function but apparently was overlooked here. --- src/p_saveg.cpp | 2 +- src/po_man.cpp | 30 +++++++++++++++++------------- src/po_man.h | 2 +- 3 files changed, 19 insertions(+), 15 deletions(-) diff --git a/src/p_saveg.cpp b/src/p_saveg.cpp index a677420f5..67297d800 100644 --- a/src/p_saveg.cpp +++ b/src/p_saveg.cpp @@ -566,7 +566,7 @@ void P_SerializePolyobjs (FArchive &arc) I_Error ("UnarchivePolyobjs: Invalid polyobj tag"); } arc << angle; - po->RotatePolyobj (angle); + po->RotatePolyobj (angle, false); arc << deltaX << deltaY << po->interpolation; deltaX -= po->StartSpot.x; deltaY -= po->StartSpot.y; diff --git a/src/po_man.cpp b/src/po_man.cpp index e19acc53a..c6e273a0f 100644 --- a/src/po_man.cpp +++ b/src/po_man.cpp @@ -1051,7 +1051,7 @@ static void RotatePt (int an, fixed_t *x, fixed_t *y, fixed_t startSpotX, fixed_ // //========================================================================== -bool FPolyObj::RotatePolyobj (angle_t angle) +bool FPolyObj::RotatePolyobj (angle_t angle, bool fromsave) { int an; bool blocked; @@ -1073,23 +1073,27 @@ bool FPolyObj::RotatePolyobj (angle_t angle) validcount++; UpdateBBox(); - for(unsigned i=0;i < Sidedefs.Size(); i++) + // If we are loading a savegame we do not really want to damage actors and be blocked by them. This can also cause crashes when trying to damage incompletely deserialized player pawns. + if (!fromsave) { - if (CheckMobjBlocking(Sidedefs[i])) + for (unsigned i = 0; i < Sidedefs.Size(); i++) { - blocked = true; + if (CheckMobjBlocking(Sidedefs[i])) + { + blocked = true; + } } - } - if (blocked) - { - for(unsigned i=0;i < Vertices.Size(); i++) + if (blocked) { - Vertices[i]->x = PrevPts[i].x; - Vertices[i]->y = PrevPts[i].y; + for(unsigned i=0;i < Vertices.Size(); i++) + { + Vertices[i]->x = PrevPts[i].x; + Vertices[i]->y = PrevPts[i].y; + } + UpdateBBox(); + LinkPolyobj(); + return false; } - UpdateBBox(); - LinkPolyobj(); - return false; } this->angle += angle; LinkPolyobj(); diff --git a/src/po_man.h b/src/po_man.h index 70ab9d360..9e81cc266 100644 --- a/src/po_man.h +++ b/src/po_man.h @@ -74,7 +74,7 @@ struct FPolyObj int GetMirror(); bool MovePolyobj (int x, int y, bool force = false); - bool RotatePolyobj (angle_t angle); + bool RotatePolyobj (angle_t angle, bool fromsave = false); void ClosestPoint(fixed_t fx, fixed_t fy, fixed_t &ox, fixed_t &oy, side_t **side) const; void LinkPolyobj (); void RecalcActorFloorCeil(FBoundingBox bounds) const; From 1a39ac9243b340cdb38a0fb7a0b07a07c8d561d6 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Thu, 25 Dec 2014 19:56:38 +0100 Subject: [PATCH 44/46] - forgot to save this before committing... --- src/p_saveg.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/p_saveg.cpp b/src/p_saveg.cpp index 67297d800..119d92a9c 100644 --- a/src/p_saveg.cpp +++ b/src/p_saveg.cpp @@ -566,7 +566,7 @@ void P_SerializePolyobjs (FArchive &arc) I_Error ("UnarchivePolyobjs: Invalid polyobj tag"); } arc << angle; - po->RotatePolyobj (angle, false); + po->RotatePolyobj (angle, true); arc << deltaX << deltaY << po->interpolation; deltaX -= po->StartSpot.x; deltaY -= po->StartSpot.y; From a5a17e45cf5377c794dc0ad65581cc1d69ee8aca Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Thu, 25 Dec 2014 20:43:40 +0100 Subject: [PATCH 45/46] - fixed: Checking the terrain for any texture that was created after initializing the terrain data either returned random garbage or could even create an access violation. Added a range check to the array access function to prevent this. --- src/p_terrain.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/p_terrain.h b/src/p_terrain.h index d2933b687..9f00d07bc 100644 --- a/src/p_terrain.h +++ b/src/p_terrain.h @@ -49,11 +49,13 @@ public: WORD operator [](FTextureID tex) const { + if ((unsigned)tex.GetIndex() >= Types.Size()) return DefaultTerrainType; WORD type = Types[tex.GetIndex()]; return type == 0xffff? DefaultTerrainType : type; } WORD operator [](int texnum) const { + if ((unsigned)texnum >= Types.Size()) return DefaultTerrainType; WORD type = Types[texnum]; return type == 0xffff? DefaultTerrainType : type; } From 14d7b8b777bae47f81a80f14c2c2646d5c8eeb44 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Thu, 25 Dec 2014 21:08:31 +0100 Subject: [PATCH 46/46] - fixed: Since no DrawText calls actually use the non-functional DTA_DestWidth, DTA_DestHeight or DTA_Translation and GCC cannot handle the fudging of the varargs, these will now trigger an assertion. No need to try to make something work that's always a programming error. --- src/v_text.cpp | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/src/v_text.cpp b/src/v_text.cpp index 64b95c041..cad9bb5d2 100644 --- a/src/v_text.cpp +++ b/src/v_text.cpp @@ -128,7 +128,6 @@ void DCanvas::DrawTextV(FFont *font, int normalcolor, int x, int y, const char * { va_list *more_p; DWORD data; - void *ptrval; switch (tag) { @@ -150,15 +149,9 @@ void DCanvas::DrawTextV(FFont *font, int normalcolor, int x, int y, const char * // We don't handle these. :( case DTA_DestWidth: case DTA_DestHeight: - *(DWORD *)tags = TAG_IGNORE; - data = va_arg (tags, DWORD); - break; - - // Translation is specified explicitly by the text. case DTA_Translation: - *(DWORD *)tags = TAG_IGNORE; - ptrval = va_arg (tags, void*); - break; + assert("Bad parameter for DrawText" && false); + return; case DTA_CleanNoMove_1: boolval = va_arg (tags, INTBOOL);