diff --git a/CMakeLists.txt b/CMakeLists.txt index 168f85f..a55d9cf 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -12,6 +12,8 @@ ENDIF(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES) PROJECT(avp) # required dependencies +INCLUDE(FindOpenGLES.cmake) +INCLUDE(FindOpenGLES2.cmake) INCLUDE(FindSDL2.cmake) INCLUDE(FindSDL) INCLUDE(FindOpenGL) @@ -27,6 +29,18 @@ IF(NOT SDL_TYPE STREQUAL "AUTO" AND NOT SDL_TYPE STREQUAL "SDL" AND NOT SDL_TYPE MESSAGE(FATAL_ERROR "Invalid SDL_TYPE setting ${SDL_TYPE}; must be one of AUTO SDL SDL2") ENDIF(NOT SDL_TYPE STREQUAL "AUTO" AND NOT SDL_TYPE STREQUAL "SDL" AND NOT SDL_TYPE STREQUAL "SDL2") +IF(SDL_FOUND) + IF(SDL_VERSION_STRING VERSION_LESS "1.2.0") + MESSAGE(WARNING "SDL 1.2 was claimed to be found with version ${SDL_VERSION_STRING}, ignoring...") + UNSET(SDL_FOUND) + ENDIF(SDL_VERSION_STRING VERSION_LESS "1.2.0") + + IF(SDL_VERSION_STRING VERSION_GREATER "1.2.99") + MESSAGE(WARNING "SDL 1.2 was claimed to be found with version ${SDL_VERSION_STRING}, ignoring...") + UNSET(SDL_FOUND) + ENDIF(SDL_VERSION_STRING VERSION_GREATER "1.2.99") +ENDIF(SDL_FOUND) + IF(SDL_TYPE STREQUAL "AUTO") IF(SDL_FOUND) MESSAGE(STATUS "SDL 1.2 found; using that.") @@ -58,12 +72,49 @@ IF(SDL_TYPE STREQUAL "SDL2") MESSAGE(WARNING "SDL 2.0 support is EXPERIMENTAL and INCOMPLETE.") ENDIF(SDL_TYPE STREQUAL "SDL2") -IF(NOT OPENGL_FOUND) - MESSAGE(FATAL_ERROR "OpenGL is required but CMake couldn't find it") -ENDIF(NOT OPENGL_FOUND) +# Use Desktop OpenGL if it is available, else try OpenGL ES. +IF(NOT OPENGL_TYPE) + SET(OPENGL_TYPE AUTO CACHE STRING "OpenGL Version; one of: AUTO OPENGL OPENGLES") + SET_PROPERTY(CACHE OPENGL_TYPE PROPERTY STRINGS "AUTO" "OPENGL" "OPENGLES") +ENDIF(NOT OPENGL_TYPE) +IF(NOT OPENGL_TYPE STREQUAL "AUTO" AND NOT OPENGL_TYPE STREQUAL "OPENGL" AND NOT OPENGL_TYPE STREQUAL "OPENGLES") + MESSAGE(FATAL_ERROR "Invalid OPENGL_TYPE setting ${OPENGL_TYPE}; must be one of AUTO OPENGL OPENGLES") +ENDIF(NOT OPENGL_TYPE STREQUAL "AUTO" AND NOT OPENGL_TYPE STREQUAL "OPENGL" AND NOT OPENGL_TYPE STREQUAL "OPENGLES") + +IF(OPENGL_TYPE STREQUAL "AUTO") + IF(OPENGL_FOUND) + MESSAGE(STATUS "OpenGL found; using that.") + SET(OPENGL_TYPE "OPENGL") + ENDIF(OPENGL_FOUND) +ENDIF(OPENGL_TYPE STREQUAL "AUTO") + +IF(OPENGL_TYPE STREQUAL "AUTO") + IF(OPENGLES_FOUND) + MESSAGE(STATUS "OpenGL ES found; using that.") + SET(OPENGL_TYPE "OPENGLES") + ENDIF(OPENGLES_FOUND) +ENDIF(OPENGL_TYPE STREQUAL "AUTO") + +IF(OPENGL_TYPE STREQUAL "AUTO") + MESSAGE(FATAL_ERROR "OpenGL is required but CMake couldn't find it.") +ENDIF(OPENGL_TYPE STREQUAL "AUTO") + +IF(OPENGL_TYPE STREQUAL "OPENGL") + IF(NOT OPENGL_FOUND) + MESAGE(FATAL_ERROR "OpenGL was requested but CMake couldn't find it.") + ENDIF(NOT OPENGL_FOUND) +ENDIF(OPENGL_TYPE STREQUAL "OPENGL") + +IF(OPENGL_TYPE STREQUAL "OPENGLES") + IF(NOT OPENGLES_FOUND) + MESSAGE(FATAL_ERROR "OpenGL ES was requested but CMake couldn't find it.") + ENDIF(NOT OPENGLES_FOUND) +ENDIF(OPENGL_TYPE STREQUAL "OPENGLES") + +# OpenAL IF(NOT OPENAL_FOUND) - MESSAGE(FATAL_ERROR "OpenAL is required but CMake couldn't find it") + MESSAGE(FATAL_ERROR "OpenAL is required but CMake couldn't find it.") ENDIF(NOT OPENAL_FOUND) # required source files @@ -307,7 +358,7 @@ ENDIF(SDL_TYPE STREQUAL "SDL2") # auto-include directories with source files FOREACH(sourcefile IN LISTS source) - GET_FILENAME_COMPONENT(includedir ${sourcefile} DIRECTORY) + GET_FILENAME_COMPONENT(includedir ${sourcefile} PATH) # newer CMake uses DIRECTORY LIST(APPEND include ${includedir}) ENDFOREACH(sourcefile) INCLUDE_DIRECTORIES(${include}) @@ -326,7 +377,16 @@ IF(SDL_TYPE STREQUAL "SDL2") INCLUDE_DIRECTORIES(${SDL2_INCLUDE_DIR}) ENDIF(SDL_TYPE STREQUAL "SDL2") -INCLUDE_DIRECTORIES(${OPENGL_INCLUDE_DIR}) +IF(OPENGL_TYPE STREQUAL "OPENGL") + INCLUDE_DIRECTORIES(${OPENGL_INCLUDE_DIR}) +ENDIF(OPENGL_TYPE STREQUAL "OPENGL") + +IF(OPENGL_TYPE STREQUAL "OPENGLES") + ADD_DEFINITIONS(-DUSE_OPENGL_ES=1) + INCLUDE_DIRECTORIES(${OPENGLES_INCLUDE_DIR}) + INCLUDE_DIRECTORIES(${EGL_INCLUDE_DIR}) +ENDIF(OPENGL_TYPE STREQUAL "OPENGLES") + INCLUDE_DIRECTORIES(${OPENAL_INCLUDE_DIR}) IF(SDL_TYPE STREQUAL "SDL") @@ -337,5 +397,13 @@ IF(SDL_TYPE STREQUAL "SDL2") TARGET_LINK_LIBRARIES(avp ${SDL2_LIBRARY}) ENDIF(SDL_TYPE STREQUAL "SDL2") -TARGET_LINK_LIBRARIES(avp ${OPENGL_gl_LIBRARY}) +IF(OPENGL_TYPE STREQUAL "OPENGL") + TARGET_LINK_LIBRARIES(avp ${OPENGL_gl_LIBRARY}) +ENDIF(OPENGL_TYPE STREQUAL "OPENGL") + +IF(OPENGL_TYPE STREQUAL "OPENGLES") + TARGET_LINK_LIBRARIES(avp ${OPENGLES_gl_LIBRARY}) + TARGET_LINK_LIBRARIES(avp ${EGL_LIBRARIES}) +ENDIF(OPENGL_TYPE STREQUAL "OPENGLES") + TARGET_LINK_LIBRARIES(avp ${OPENAL_LIBRARY}) diff --git a/FindOpenGLES.cmake b/FindOpenGLES.cmake new file mode 100644 index 0000000..7ee2c07 --- /dev/null +++ b/FindOpenGLES.cmake @@ -0,0 +1,94 @@ +#------------------------------------------------------------------- +# This file is part of the CMake build system for OGRE +# (Object-oriented Graphics Rendering Engine) +# For the latest info, see http://www.ogre3d.org/ +# +# The contents of this file are placed in the public domain. Feel +# free to make use of it in any way you like. +#------------------------------------------------------------------- + +# - Try to find OpenGLES +# Once done this will define +# +# OPENGLES_FOUND - system has OpenGLES +# OPENGLES_INCLUDE_DIR - the GL include directory +# OPENGLES_LIBRARIES - Link these to use OpenGLES + +IF (WIN32) + IF (CYGWIN) + + FIND_PATH(OPENGLES_INCLUDE_DIR GLES/gl.h ) + + FIND_LIBRARY(OPENGLES_gl_LIBRARY libgles_cm ) + + ELSE (CYGWIN) + + IF(BORLAND) + SET (OPENGLES_gl_LIBRARY import32 CACHE STRING "OpenGL ES 1.x library for win32") + ELSE(BORLAND) + #MS compiler - todo - fix the following line: + SET (OPENGLES_gl_LIBRARY ${OGRE_SOURCE_DIR}/Dependencies/lib/release/libgles_cm.lib CACHE STRING "OpenGL ES 1.x library for win32") + ENDIF(BORLAND) + + ENDIF (CYGWIN) + +ELSE (WIN32) + + IF (APPLE) + + #create_search_paths(/Developer/Platforms) + #findpkg_framework(OpenGLES) + #set(OPENGLES_gl_LIBRARY "-framework OpenGLES") + + ELSE(APPLE) + + FIND_PATH(OPENGLES_INCLUDE_DIR GLES/gl.h + /opt/vc/include + /opt/graphics/OpenGL/include + /usr/openwin/share/include + /usr/X11R6/include + /usr/include + ) + + FIND_LIBRARY(OPENGLES_gl_LIBRARY + NAMES GLES_CM GLESv1_CM + PATHS /opt/vc/lib + /opt/graphics/OpenGL/lib + /usr/openwin/lib + /usr/shlib /usr/X11R6/lib + /usr/lib + ) + + # On Unix OpenGL most certainly always requires X11. + # Feel free to tighten up these conditions if you don't + # think this is always true. + + #IF (OPENGLES_gl_LIBRARY) + # IF(NOT X11_FOUND) + # INCLUDE(FindX11) + # ENDIF(NOT X11_FOUND) + # IF (X11_FOUND) + # SET (OPENGLES_LIBRARIES ${X11_LIBRARIES}) + # ENDIF (X11_FOUND) + #ENDIF (OPENGLES_gl_LIBRARY) + + ENDIF(APPLE) +ENDIF (WIN32) + +SET( OPENGLES_FOUND "NO" ) +IF(OPENGLES_gl_LIBRARY) + + SET( OPENGLES_LIBRARIES ${OPENGLES_gl_LIBRARY} ${OPENGLES_LIBRARIES}) + + SET( OPENGLES_FOUND "YES" ) + +ENDIF(OPENGLES_gl_LIBRARY) + +MARK_AS_ADVANCED( + OPENGLES_INCLUDE_DIR + OPENGLES_gl_LIBRARY +) + +INCLUDE(FindPackageHandleStandardArgs) + +FIND_PACKAGE_HANDLE_STANDARD_ARGS(OPENGLES REQUIRED_VARS OPENGLES_LIBRARIES OPENGLES_INCLUDE_DIR) diff --git a/FindOpenGLES2.cmake b/FindOpenGLES2.cmake new file mode 100644 index 0000000..136e761 --- /dev/null +++ b/FindOpenGLES2.cmake @@ -0,0 +1,170 @@ +#------------------------------------------------------------------- +# This file is part of the CMake build system for OGRE +# (Object-oriented Graphics Rendering Engine) +# For the latest info, see http://www.ogre3d.org/ +# +# The contents of this file are placed in the public domain. Feel +# free to make use of it in any way you like. +#------------------------------------------------------------------- + +# - Try to find OpenGLES and EGL +# If using ARM Mali emulation you can specify the parent directory that contains the bin and include directories by +# setting the MALI_SDK_ROOT variable in the environment. +# +# For AMD emulation use the AMD_SDK_ROOT variable +# +# Once done this will define +# +# OPENGLES2_FOUND - system has OpenGLES +# OPENGLES2_INCLUDE_DIR - the GL include directory +# OPENGLES2_LIBRARIES - Link these to use OpenGLES +# +# EGL_FOUND - system has EGL +# EGL_INCLUDE_DIR - the EGL include directory +# EGL_LIBRARIES - Link these to use EGL + +#include(FindPkgMacros) + +IF (WIN32) + IF (CYGWIN) + + FIND_PATH(OPENGLES2_INCLUDE_DIR GLES2/gl2.h ) + + FIND_LIBRARY(OPENGLES2_gl_LIBRARY libGLESv2 ) + + ELSE (CYGWIN) + + IF(BORLAND) + SET (OPENGLES2_gl_LIBRARY import32 CACHE STRING "OpenGL ES 2.x library for win32") + ELSE(BORLAND) + #getenv_path(AMD_SDK_ROOT) + #getenv_path(MALI_SDK_ROOT) + + SET(POWERVR_SDK_PATH "C:/Imagination/PowerVR/GraphicsSDK/SDK_3.1/Builds") + FIND_PATH(OPENGLES2_INCLUDE_DIR GLES2/gl2.h + ${ENV_AMD_SDK_ROOT}/include + ${ENV_MALI_SDK_ROOT}/include + ${POWERVR_SDK_PATH}/Include + "C:/Imagination Technologies/PowerVR Insider SDK/OGLES2_WINDOWS_X86EMULATION_2.10/Builds/OGLES2/Include" + ) + + FIND_PATH(EGL_INCLUDE_DIR EGL/egl.h + ${ENV_AMD_SDK_ROOT}/include + ${ENV_MALI_SDK_ROOT}/include + ${POWERVR_SDK_PATH}/Include + "C:/Imagination Technologies/PowerVR Insider SDK/OGLES2_WINDOWS_X86EMULATION_2.10/Builds/OGLES2/Include" + ) + + FIND_LIBRARY(OPENGLES2_gl_LIBRARY + NAMES libGLESv2 + PATHS ${ENV_AMD_SDK_ROOT}/x86 + ${ENV_MALI_SDK_ROOT}/bin + ${POWERVR_SDK_PATH}/Windows/x86_32/Lib + "C:/Imagination Technologies/PowerVR Insider SDK/OGLES2_WINDOWS_X86EMULATION_2.10/Builds/OGLES2/WindowsX86/Lib" + ) + + FIND_LIBRARY(EGL_egl_LIBRARY + NAMES libEGL + PATHS ${ENV_AMD_SDK_ROOT}/x86 + ${ENV_MALI_SDK_ROOT}/bin + ${POWERVR_SDK_PATH}/Windows/x86_32/Lib + "C:/Imagination Technologies/PowerVR Insider SDK/OGLES2_WINDOWS_X86EMULATION_2.10/Builds/OGLES2/WindowsX86/Lib" + ) + ENDIF(BORLAND) + + ENDIF (CYGWIN) + +ELSE (WIN32) + + IF (APPLE) + + #create_search_paths(/Developer/Platforms) + #findpkg_framework(OpenGLES2) + #set(OPENGLES2_gl_LIBRARY "-framework OpenGLES") + + ELSE(APPLE) + #getenv_path(AMD_SDK_ROOT) + #getenv_path(MALI_SDK_ROOT) + + FIND_PATH(OPENGLES2_INCLUDE_DIR GLES2/gl2.h + ${ENV_AMD_SDK_ROOT}/include + ${ENV_MALI_SDK_ROOT}/include + /opt/Imagination/PowerVR/GraphicsSDK/SDK_3.1/Builds/Include + /opt/vc/include + /usr/openwin/share/include + /opt/graphics/OpenGL/include /usr/X11R6/include + /usr/include + ) + + FIND_LIBRARY(OPENGLES2_gl_LIBRARY + NAMES GLESv2 + PATHS ${ENV_AMD_SDK_ROOT}/x86 + ${ENV_MALI_SDK_ROOT}/bin + /opt/Imagination/PowerVR/GraphicsSDK/SDK_3.1/Builds/Linux/x86_32/Lib + /opt/vc/lib + /opt/graphics/OpenGL/lib + /usr/openwin/lib + /usr/shlib /usr/X11R6/lib + /usr/lib + ) + + FIND_PATH(EGL_INCLUDE_DIR EGL/egl.h + ${ENV_AMD_SDK_ROOT}/include + ${ENV_MALI_SDK_ROOT}/include + /opt/Imagination/PowerVR/GraphicsSDK/SDK_3.1/Builds/Include + /opt/vc/include + /usr/openwin/share/include + /opt/graphics/OpenGL/include /usr/X11R6/include + /usr/include + ) + + FIND_LIBRARY(EGL_egl_LIBRARY + NAMES EGL + PATHS ${ENV_AMD_SDK_ROOT}/x86 + ${ENV_MALI_SDK_ROOT}/bin + /opt/Imagination/PowerVR/GraphicsSDK/SDK_3.1/Builds/Linux/x86_32/Lib + /opt/vc/lib + /opt/graphics/OpenGL/lib + /usr/openwin/lib + /usr/shlib /usr/X11R6/lib + /usr/lib + ) + + # On Unix OpenGL most certainly always requires X11. + # Feel free to tighten up these conditions if you don't + # think this is always true. + # It's not true on OSX. + + #IF (OPENGLES2_gl_LIBRARY) + # IF(NOT X11_FOUND) + # INCLUDE(FindX11) + # ENDIF(NOT X11_FOUND) + # IF (X11_FOUND) + # IF (NOT APPLE) + # SET (OPENGLES2_LIBRARIES ${X11_LIBRARIES}) + # ENDIF (NOT APPLE) + # ENDIF (X11_FOUND) + #ENDIF (OPENGLES2_gl_LIBRARY) + + ENDIF(APPLE) +ENDIF (WIN32) + +SET( OPENGLES2_FOUND "YES" ) +IF(OPENGLES2_gl_LIBRARY AND EGL_egl_LIBRARY) + + SET( OPENGLES2_LIBRARIES ${OPENGLES2_gl_LIBRARY} ${OPENGLES2_LIBRARIES}) + SET( EGL_LIBRARIES ${EGL_egl_LIBRARY} ${EGL_LIBRARIES}) + SET( OPENGLES2_FOUND "YES" ) + +ENDIF(OPENGLES2_gl_LIBRARY AND EGL_egl_LIBRARY) + +MARK_AS_ADVANCED( + OPENGLES2_INCLUDE_DIR + OPENGLES2_gl_LIBRARY + EGL_INCLUDE_DIR + EGL_egl_LIBRARY +) + +INCLUDE(FindPackageHandleStandardArgs) + +FIND_PACKAGE_HANDLE_STANDARD_ARGS(OPENGLES2 REQUIRED_VARS OPENGLES2_LIBRARIES OPENGLES2_INCLUDE_DIR) diff --git a/README b/README index 5bdd578..4a62f7a 100644 --- a/README +++ b/README @@ -7,7 +7,8 @@ Table of Contents: 3. Compilation 4. Installation 5. Credits -a. Gold edition MD5s +a. Change History +b. Gold edition MD5s Part 1: Introduction @@ -71,8 +72,20 @@ Chuck Mason, initial OpenAL implementation For everything else, there's http://community.ioquake.org/c/avp +Appendix A: Change History +-------------------------- -Appendix A: Gold edition MD5s +20150214: +OpenGL ES 1.1 compatibility +SDL2 support progress + +20141225: +CMake build system +x86_64 support +Beginnings of SDL2 support + + +Appendix B: Gold edition MD5s ----------------------------- A proper install of the Gold edition should look similar to this: diff --git a/src/avp/cdtrackselection.cpp b/src/avp/cdtrackselection.cpp index 5440bbd..173be98 100644 --- a/src/avp/cdtrackselection.cpp +++ b/src/avp/cdtrackselection.cpp @@ -130,6 +130,7 @@ void LoadCDTrackList() //copy the file contents into a buffer buffer=new char[file_size+1]; fread(buffer, 1, file_size, file); + buffer[file_size]='\0'; fclose(file); char* bufferptr=buffer; diff --git a/src/avp/hud.c b/src/avp/hud.c index bc945a1..066f831 100644 --- a/src/avp/hud.c +++ b/src/avp/hud.c @@ -2121,12 +2121,7 @@ int Fast3dMagnitude(VECTORCH *v) } } -#define ZOOM_SCALE_0 1.0f -#define ZOOM_SCALE_1 0.4f -#define ZOOM_SCALE_2 0.1f -#define ZOOM_SCALE_3 0.02f - -static float ZoomLevels[] = {1.0f,0.4f,0.1f,0.02f}; +static const float ZoomLevels[] = {1.0f,0.4f,0.1f,0.02f}; void MaintainZoomingLevel(void) { @@ -2173,18 +2168,3 @@ void MaintainZoomingLevel(void) } - - - - - - - - - - - - - - - diff --git a/src/avp/langenum.h b/src/avp/langenum.h index 28832ae..479221f 100644 --- a/src/avp/langenum.h +++ b/src/avp/langenum.h @@ -1362,7 +1362,15 @@ enum TEXTSTRING_ID TEXTSTRING_CUSTOM_LEVEL, TEXTSTRING_MULTIPLAYER_OPERATETORESPAWN, TEXTSTRING_MULTIPLAYER_OPERATETOOBSERVE, - MAX_NO_OF_TEXTSTRINGS + MAX_NO_OF_TEXTSTRINGS, + + // Not good. + // These strings do not exist in data. + MIN_NEW_TEXTSTRINGS, + TEXTSTRING_MAINMENU_EXITGAME_HELP_NEW, + TEXTSTRING_MAINMENU_CREDITS_NEW, + TEXTSTRING_MAINMENU_CREDITS_HELP_NEW, + MAX_NEW_TEXTSTRINGS }; #endif diff --git a/src/avp/language.c b/src/avp/language.c index 4387099..49bf319 100644 --- a/src/avp/language.c +++ b/src/avp/language.c @@ -78,8 +78,13 @@ void InitTextStrings(void) for (i=1; i MIN_NEW_TEXTSTRINGS && stringID < MAX_NEW_TEXTSTRINGS) { + switch (stringID) { + case TEXTSTRING_MAINMENU_EXITGAME_HELP_NEW: return "Exit the game."; + case TEXTSTRING_MAINMENU_CREDITS_NEW: return "Credits"; + case TEXTSTRING_MAINMENU_CREDITS_HELP_NEW: return "View the credits."; + default: break; + } + } + LOCALASSERT(stringIDMemoryLeft) { + MemoryWasted += MemoryLeft; + CurrentMemoryBlock++; GLOBALASSERT(CurrentMemoryBlock= MAX_NUM_MEMORY_BLOCK) @@ -49,7 +55,14 @@ void* PoolAllocateMem(unsigned int amount) MemoryLeft=MEMORY_BLOCK_SIZE; MemoryPoolPtr=MemoryBlocks[CurrentMemoryBlock]; } - + + if (amount > LargestRequest) { + LargestRequest = amount; + } + + MemoryRequested+=amount; + AllocationCount++; + retval=MemoryPoolPtr; MemoryLeft-=amount; MemoryPoolPtr+=amount; @@ -62,6 +75,11 @@ void ClearMemoryPool() { int i; +#if !defined(NDEBUG) + printf("%d blocks in use, %u bytes left in current block\n", CurrentMemoryBlock + 1, MemoryLeft); + printf("%zu requests, %zu bytes requested, %zu bytes wasted, %zu largest request\n", AllocationCount, MemoryRequested, MemoryWasted, LargestRequest); +#endif + for(i=0;i<=CurrentMemoryBlock;i++) { DeallocateMem(MemoryBlocks[i]); @@ -70,8 +88,11 @@ void ClearMemoryPool() CurrentMemoryBlock=-1; MemoryPoolPtr=0; MemoryLeft=0; + + MemoryRequested = 0; + MemoryWasted = 0; + LargestRequest = 0; + AllocationCount = 0; } - - #endif diff --git a/src/avp/win95/frontend/avp_menudata.c b/src/avp/win95/frontend/avp_menudata.c index 7fbd927..06630ed 100644 --- a/src/avp/win95/frontend/avp_menudata.c +++ b/src/avp/win95/frontend/avp_menudata.c @@ -100,7 +100,7 @@ static AVPMENU_ELEMENT AvPMenu_MainMenu[] = {AVPMENU_ELEMENT_GOTOMENU, {TEXTSTRING_MAINMENU_GAMEPLAYOPTIONS}, {AVPMENU_OPTIONS},{0},{0}, TEXTSTRING_MAINMENU_GAMEPLAYOPTIONS_HELP}, {AVPMENU_ELEMENT_GOTOMENU, {TEXTSTRING_AVOPTIONS_TITLE}, {AVPMENU_MAINMENUAVOPTIONS},{0},{0}, TEXTSTRING_AVOPTIONS_TITLE_HELP}, {AVPMENU_ELEMENT_GOTOMENU, {TEXTSTRING_MAINMENU_CHANGEUSERPROFILE}, {AVPMENU_USERPROFILESELECT},{0},{0}, TEXTSTRING_MAINMENU_CHANGEUSERPROFILE_HELP}, - {AVPMENU_ELEMENT_QUITGAME, {TEXTSTRING_MAINMENU_EXITGAME}, {0}, {0}, {0}, TEXTSTRING_MAINMENU_EXITGAME_HELP}, + {AVPMENU_ELEMENT_QUITGAME, {TEXTSTRING_MAINMENU_EXITGAME}, {0}, {0}, {0}, TEXTSTRING_MAINMENU_EXITGAME_HELP_NEW}, {AVPMENU_ELEMENT_ENDOFMENU} }; #endif @@ -116,7 +116,7 @@ static AVPMENU_ELEMENT AvPMenu_MainMenu_WithCheats[] = {AVPMENU_ELEMENT_GOTOMENU, {TEXTSTRING_AVOPTIONS_TITLE}, {AVPMENU_MAINMENUAVOPTIONS},{0},{0}, TEXTSTRING_AVOPTIONS_TITLE_HELP}, {AVPMENU_ELEMENT_GOTOMENU, {TEXTSTRING_MAINMENU_CHANGEUSERPROFILE}, {AVPMENU_USERPROFILESELECT},{0},{0}, TEXTSTRING_MAINMENU_CHANGEUSERPROFILE_HELP}, {AVPMENU_ELEMENT_GOTOMENU, {TEXTSTRING_MAINMENU_CHEATOPTIONS}, {AVPMENU_CHEATOPTIONS},{0},{0}, TEXTSTRING_MAINMENU_CHEATOPTIONS_HELP}, - {AVPMENU_ELEMENT_QUITGAME, {TEXTSTRING_MAINMENU_EXITGAME}, {0}, {0}, {0}, TEXTSTRING_MAINMENU_EXITGAME_HELP}, + {AVPMENU_ELEMENT_QUITGAME, {TEXTSTRING_MAINMENU_EXITGAME}, {0}, {0}, {0}, TEXTSTRING_MAINMENU_EXITGAME_HELP_NEW}, {AVPMENU_ELEMENT_ENDOFMENU} }; static AVPMENU_ELEMENT AvPMenu_Debug_MainMenu[] = @@ -129,7 +129,7 @@ static AVPMENU_ELEMENT AvPMenu_Debug_MainMenu[] = {AVPMENU_ELEMENT_GOTOMENU, {TEXTSTRING_MAINMENU_GAMEPLAYOPTIONS}, {AVPMENU_OPTIONS},{0},{0}, TEXTSTRING_MAINMENU_GAMEPLAYOPTIONS_HELP}, {AVPMENU_ELEMENT_GOTOMENU, {TEXTSTRING_AVOPTIONS_TITLE}, {AVPMENU_MAINMENUAVOPTIONS},{0},{0}, TEXTSTRING_AVOPTIONS_TITLE_HELP}, {AVPMENU_ELEMENT_GOTOMENU, {TEXTSTRING_MAINMENU_CHANGEUSERPROFILE}, {AVPMENU_USERPROFILESELECT},{0},{0}, TEXTSTRING_MAINMENU_CHANGEUSERPROFILE_HELP}, - {AVPMENU_ELEMENT_QUITGAME, {TEXTSTRING_MAINMENU_EXITGAME}, {0}, {0}, {0}, TEXTSTRING_MAINMENU_EXITGAME_HELP}, + {AVPMENU_ELEMENT_QUITGAME, {TEXTSTRING_MAINMENU_EXITGAME}, {0}, {0}, {0}, TEXTSTRING_MAINMENU_EXITGAME_HELP_NEW}, {AVPMENU_ELEMENT_ENDOFMENU} }; static AVPMENU_ELEMENT AvPMenu_Debug_MainMenu_WithCheats[] = @@ -143,7 +143,7 @@ static AVPMENU_ELEMENT AvPMenu_Debug_MainMenu_WithCheats[] = {AVPMENU_ELEMENT_GOTOMENU, {TEXTSTRING_AVOPTIONS_TITLE}, {AVPMENU_MAINMENUAVOPTIONS},{0},{0}, TEXTSTRING_AVOPTIONS_TITLE_HELP}, {AVPMENU_ELEMENT_GOTOMENU, {TEXTSTRING_MAINMENU_CHANGEUSERPROFILE}, {AVPMENU_USERPROFILESELECT},{0},{0}, TEXTSTRING_MAINMENU_CHANGEUSERPROFILE_HELP}, {AVPMENU_ELEMENT_GOTOMENU, {TEXTSTRING_MAINMENU_CHEATOPTIONS}, {AVPMENU_CHEATOPTIONS},{0},{0}, TEXTSTRING_MAINMENU_CHEATOPTIONS_HELP}, - {AVPMENU_ELEMENT_QUITGAME, {TEXTSTRING_MAINMENU_EXITGAME}, {0}, {0}, {0}, TEXTSTRING_MAINMENU_EXITGAME_HELP}, + {AVPMENU_ELEMENT_QUITGAME, {TEXTSTRING_MAINMENU_EXITGAME}, {0}, {0}, {0}, TEXTSTRING_MAINMENU_EXITGAME_HELP_NEW}, {AVPMENU_ELEMENT_ENDOFMENU} }; diff --git a/src/avp/win95/progress_bar.cpp b/src/avp/win95/progress_bar.cpp index 2b2c3a9..e20ba30 100644 --- a/src/avp/win95/progress_bar.cpp +++ b/src/avp/win95/progress_bar.cpp @@ -14,12 +14,10 @@ extern "C" #include "language.h" #include "avp_menus.h" extern SCREENDESCRIPTORBLOCK ScreenDescriptorBlock; -//extern LPDIRECTDRAWSURFACE lpDDSBack; // DirectDraw back surface extern int DebouncedGotAnyKey; extern void MinimalNetCollectMessages(void); extern void NetSendMessages(void); -extern void RenderGrabbedScreen(void); extern void ThisFramesRenderingHasBegun(void); extern void ThisFramesRenderingHasFinished(void); @@ -29,28 +27,58 @@ extern int FadingGameInAfterLoading; extern void InGameFlipBuffers(); +extern void RenderStringCentred(char *stringPtr, int centreX, int y, int colour); + extern void BltImage(RECT *dest, DDSurface *image, RECT *src); +extern int CreateOGLTexture(D3DTexture *, unsigned char *); +extern int CreateIMGSurface(D3DTexture *, unsigned char *); }; -static int CurrentPosition=0; -static int BarLeft; -static int BarRight; -static int BarTop; -static int BarBottom; - -static const char* Loading_Image_Name="Menus\\Loading.rim"; static const char* Loading_Bar_Empty_Image_Name="Menus\\Loadingbar_empty.rim"; static const char* Loading_Bar_Full_Image_Name="Menus\\Loadingbar_full.rim"; -DDSurface *LoadingBarEmpty; -DDSurface *LoadingBarFull; -RECT LoadingBarEmpty_DestRect; -RECT LoadingBarEmpty_SrcRect; -RECT LoadingBarFull_DestRect; -RECT LoadingBarFull_SrcRect; +static DDSurface* LoadingBarEmpty; +static DDSurface* LoadingBarFull; +static RECT LoadingBarEmpty_DestRect; +static RECT LoadingBarEmpty_SrcRect; +static RECT LoadingBarFull_DestRect; +static RECT LoadingBarFull_SrcRect; + +static int CurrentPosition=0; +static int LoadingInProgress=0; + +static void Draw_Progress_Bar(void) { + + ThisFramesRenderingHasBegun(); + + ColourFillBackBuffer(0); + + if (LoadingInProgress != 0 && LoadingBarEmpty != NULL) { + BltImage(&LoadingBarEmpty_DestRect,LoadingBarEmpty,&LoadingBarEmpty_SrcRect); + } + + if (LoadingBarFull != NULL) { + BltImage(&LoadingBarFull_DestRect,LoadingBarFull,&LoadingBarFull_SrcRect); + } + + FlushD3DZBuffer(); + + RenderBriefingText(ScreenDescriptorBlock.SDB_Height/2, ONE_FIXED); + + if (LoadingInProgress == 0) { + RenderStringCentred(GetTextString(TEXTSTRING_INGAME_PRESSANYKEYTOCONTINUE), ScreenDescriptorBlock.SDB_Width/2, (ScreenDescriptorBlock.SDB_Height*23)/24-9, 0xffffffff); + } + + ThisFramesRenderingHasFinished(); + + InGameFlipBuffers(); +} void Start_Progress_Bar() { + LoadingBarEmpty = NULL; + LoadingBarFull = NULL; + AAFontImageNumber = CL_LoadImageOnce("Common\\aa_font.RIM",LIO_D3DTEXTURE|LIO_RELATIVEPATH|LIO_RESTORABLE); /* load other graphics */ @@ -114,47 +142,11 @@ void Start_Progress_Bar() ); } } - DDSurface* image=0; + + CreateOGLTexture(LoadingBarEmpty, NULL); + CreateOGLTexture(LoadingBarFull, NULL); - //set progress bar dimensions - BarLeft=ScreenDescriptorBlock.SDB_Width/6; - BarRight=(ScreenDescriptorBlock.SDB_Width*5)/6; - BarTop=(ScreenDescriptorBlock.SDB_Height*19)/22; - BarBottom=(ScreenDescriptorBlock.SDB_Height*21)/22; - - //load background image for bar - char buffer[100]; - CL_GetImageFileName(buffer, 100,Loading_Image_Name, LIO_RELATIVEPATH); - - - //see if graphic can be found in fast file - size_t fastFileLength; - void const * pFastFileData = ffreadbuf(buffer,&fastFileLength); - - if(pFastFileData) - { - //load from fast file - image = AwCreateSurface - ( - "pxf", - pFastFileData, - fastFileLength, - 0 - ); - } - else - { - //load graphic from rim file - image = AwCreateSurface - ( - "sf", - buffer, - 0 - ); - } - //draw initial progress bar - LoadingBarEmpty_SrcRect.left=0; LoadingBarEmpty_SrcRect.right=639; LoadingBarEmpty_SrcRect.top=0; @@ -163,47 +155,28 @@ void Start_Progress_Bar() LoadingBarEmpty_DestRect.right=ScreenDescriptorBlock.SDB_Width-1; LoadingBarEmpty_DestRect.top=(ScreenDescriptorBlock.SDB_Height *11)/12; LoadingBarEmpty_DestRect.bottom=ScreenDescriptorBlock.SDB_Height-1; - - for (int i=0; i<2; i++) - { - ColourFillBackBuffer(0); - if (LoadingBarEmpty) BltImage(&LoadingBarEmpty_DestRect,LoadingBarEmpty,&LoadingBarEmpty_SrcRect); - - FlushD3DZBuffer(); - - ThisFramesRenderingHasBegun(); - - RenderBriefingText(ScreenDescriptorBlock.SDB_Height/2, ONE_FIXED); - - ThisFramesRenderingHasFinished(); - -/* FlipBuffers(); */ - InGameFlipBuffers(); - } - - if(image) - { - ReleaseDDSurface(image); - } - if (LoadingBarEmpty) - { - ReleaseDDSurface(LoadingBarEmpty); - } + LoadingBarFull_SrcRect.left=0; + LoadingBarFull_SrcRect.right=0; + LoadingBarFull_SrcRect.top=0; + LoadingBarFull_SrcRect.bottom=39; + LoadingBarFull_DestRect.left=0; + LoadingBarFull_DestRect.right=0; + LoadingBarFull_DestRect.top=(ScreenDescriptorBlock.SDB_Height *11)/12; + LoadingBarFull_DestRect.bottom=ScreenDescriptorBlock.SDB_Height-1; CurrentPosition=0; + LoadingInProgress=1; - + Draw_Progress_Bar(); } void Set_Progress_Bar_Position(int pos) { -// int NewPosition=((BarRight-BarLeft)*pos)/PBAR_LENGTH; int NewPosition = DIV_FIXED(pos,PBAR_LENGTH); if(NewPosition>CurrentPosition) { CurrentPosition=NewPosition; -// ColourFillBackBufferQuad(GetSingleColourForPrimary(0xff0000),BarLeft,BarTop,BarLeft+CurrentPosition,BarBottom); LoadingBarFull_SrcRect.left=0; LoadingBarFull_SrcRect.right=MUL_FIXED(639,NewPosition); LoadingBarFull_SrcRect.top=0; @@ -212,11 +185,8 @@ void Set_Progress_Bar_Position(int pos) LoadingBarFull_DestRect.right=MUL_FIXED(ScreenDescriptorBlock.SDB_Width-1,NewPosition); LoadingBarFull_DestRect.top=(ScreenDescriptorBlock.SDB_Height *11)/12; LoadingBarFull_DestRect.bottom=ScreenDescriptorBlock.SDB_Height-1; - - if (LoadingBarFull) BltImage(&LoadingBarFull_DestRect,LoadingBarFull,&LoadingBarFull_SrcRect); -/* FlipBuffers(); */ - InGameFlipBuffers(); + Draw_Progress_Bar(); /* If this is a network game , then check the received network messages from @@ -250,12 +220,12 @@ extern "C" void Game_Has_Loaded(void) { extern int NormalFrameTime; - extern void RenderStringCentred(char *stringPtr, int centreX, int y, int colour); - SoundSys_StopAll(); SoundSys_Management(); + LoadingInProgress = 0; + int f = 65536; ResetFrameCounter(); do @@ -285,28 +255,23 @@ void Game_Has_Loaded(void) LoadingBarFull_DestRect.top=(ScreenDescriptorBlock.SDB_Height *11)/12+h; LoadingBarFull_DestRect.bottom=ScreenDescriptorBlock.SDB_Height-1-h; - if (LoadingBarFull) BltImage(&LoadingBarFull_DestRect,LoadingBarFull,&LoadingBarFull_SrcRect); - f-=NormalFrameTime; if (f<0) f=0; - } - { - extern void ThisFramesRenderingHasBegun(void); - ThisFramesRenderingHasBegun(); - } - RenderStringCentred(GetTextString(TEXTSTRING_INGAME_PRESSANYKEYTOCONTINUE), ScreenDescriptorBlock.SDB_Width/2, (ScreenDescriptorBlock.SDB_Height*23)/24-9, 0xffffffff); - { - /* after this call, no more graphics can be drawn until the next frame */ - extern void ThisFramesRenderingHasFinished(void); - ThisFramesRenderingHasFinished(); + } else { + LoadingBarFull_SrcRect.left=0; + LoadingBarFull_SrcRect.right=0; + LoadingBarFull_SrcRect.top=0; + LoadingBarFull_SrcRect.bottom=0; + LoadingBarFull_DestRect.left=0; + LoadingBarFull_DestRect.right=0; + LoadingBarFull_DestRect.top=0; + LoadingBarFull_DestRect.bottom=0; } -/* FlipBuffers(); */ - InGameFlipBuffers(); - + Draw_Progress_Bar(); + FrameCounterHandler(); - /* If in a network game then we may as well check the network messages while waiting*/ if(AvP.Network != I_No_Network) { @@ -321,13 +286,16 @@ void Game_Has_Loaded(void) } while(!DebouncedGotAnyKey); - while (0); - FadingGameInAfterLoading=ONE_FIXED; - if (LoadingBarFull) - { + if (LoadingBarFull != NULL) { ReleaseDDSurface(LoadingBarFull); + LoadingBarFull = NULL; + } + + if (LoadingBarEmpty != NULL) { + ReleaseDDSurface(LoadingBarEmpty); + LoadingBarEmpty = NULL; } } diff --git a/src/main.c b/src/main.c index 20b8e97..f2d4dfe 100644 --- a/src/main.c +++ b/src/main.c @@ -612,11 +612,6 @@ int SetOGLVideoMode(int Width, int Height) SDL_ShowCursor(0); pglViewport(0, 0, Width, Height); - - pglMatrixMode(GL_PROJECTION); - pglLoadIdentity(); - pglMatrixMode(GL_MODELVIEW); - pglLoadIdentity(); pglEnable(GL_BLEND); pglBlendFunc(GL_SRC_ALPHA, GL_ONE); @@ -628,8 +623,6 @@ int SetOGLVideoMode(int Width, int Height) pglEnable(GL_TEXTURE_2D); - pglPolygonMode(GL_FRONT, GL_FILL); - pglPolygonMode(GL_BACK, GL_FILL); pglDisable(GL_CULL_FACE); pglClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); diff --git a/src/main2.c b/src/main2.c index cdc353c..46b47d5 100644 --- a/src/main2.c +++ b/src/main2.c @@ -45,9 +45,20 @@ #include "version.h" #include "fmv.h" + +#if defined(__IPHONEOS__) || defined(__ANDROID__) +#define FIXED_WINDOW_SIZE 1 +#endif + +#if defined(__IPHONEOS__) || defined(__ANDROID__) +#define USE_OPENGL_ES 1 +#endif + void RE_ENTRANT_QUEUE_WinProc_AddMessage_WM_CHAR(char Ch); void RE_ENTRANT_QUEUE_WinProc_AddMessage_WM_KEYDOWN(int wParam); +static int SDLCALL SDLEventFilter(void* userData, SDL_Event* event); + char LevelName[] = {"predbit6\0QuiteALongNameActually"}; /* the real way to load levels */ int DebouncedGotAnyKey; @@ -72,15 +83,39 @@ SDL_Joystick *joy; JOYINFOEX JoystickData; JOYCAPS JoystickCaps; -/* defaults */ +// Window configuration and state +static int WindowWidth; +static int WindowHeight; +static int ViewportWidth; +static int ViewportHeight; + +enum RENDERING_MODE { + RENDERING_MODE_SOFTWARE, + RENDERING_MODE_OPENGL +}; + +enum RENDERING_MODE RenderingMode; + +#if defined(FIXED_WINDOW_SIZE) +static int WantFullscreen = 1; +static int WantFullscreenToggle = 0; +static int WantResolutionChange = 0; +static int WantMouseGrab = 1; +#else static int WantFullscreen = 0; +static int WantFullscreenToggle = 1; +static int WantResolutionChange = 1; static int WantMouseGrab = 0; +#endif + +// Additional configuration int WantSound = 1; static int WantCDRom = 0; static int WantJoystick = 0; -static int ViewportWidth; -static int ViewportHeight; +static GLuint FullscreenTexture; +static GLsizei FullscreenTextureWidth; +static GLsizei FullscreenTextureHeight; /* originally was "/usr/lib/libGL.so.1:/usr/lib/tls/libGL.so.1:/usr/X11R6/lib/libGL.so" */ static const char * opengl_library = NULL; @@ -171,21 +206,24 @@ void ReadJoysticks() unsigned char *GetScreenShot24(int *width, int *height) { -#if 0//REVIEW unsigned char *buf; -// Uint16 redtable[256], greentable[256], bluetable[256]; - + if (surface == NULL) { return NULL; } - - buf = (unsigned char *)malloc(surface->w * surface->h * 3); - - if (surface->flags & SDL_WINDOW_OPENGL) { + + if (RenderingMode == RENDERING_MODE_OPENGL) { + buf = (unsigned char *)malloc(ViewportWidth * ViewportHeight * 3); + + *width = ViewportWidth; + *height = ViewportHeight; + pglPixelStorei(GL_PACK_ALIGNMENT, 1); pglPixelStorei(GL_UNPACK_ALIGNMENT, 1); - pglReadPixels(0, 0, surface->w, surface->h, GL_RGB, GL_UNSIGNED_BYTE, buf); + pglReadPixels(0, 0, ViewportWidth, ViewportHeight, GL_RGB, GL_UNSIGNED_BYTE, buf); } else { + buf = (unsigned char *)malloc(surface->w * surface->h * 3); + unsigned char *ptrd; unsigned short int *ptrs; int x, y; @@ -213,15 +251,17 @@ unsigned char *GetScreenShot24(int *width, int *height) } } + *width = surface->w; + *height = surface->h; + if (SDL_MUSTLOCK(surface)) { SDL_UnlockSurface(surface); } } - - *width = surface->w; - *height = surface->h; -#if 0 +#if 0 + Uint16 redtable[256], greentable[256], bluetable[256]; + if (SDL_GetGammaRamp(redtable, greentable, bluetable) != -1) { unsigned char *ptr; int i; @@ -234,10 +274,9 @@ unsigned char *GetScreenShot24(int *width, int *height) ptr += 3; } } -#endif - return buf; #endif - return NULL; + + return buf; } /* ** */ @@ -279,6 +318,16 @@ void LoadDeviceAndVideoModePreferences() fp = OpenGameFile("AvP_TempVideo.cfg", FILEMODE_READONLY, FILETYPE_CONFIG); if (fp != NULL) { + // fullscreen mode (0=window,1=fullscreen,2=fullscreen desktop) + // window width + // window height + // fullscreen width + // fullscreen height + // fullscreen desktop aspect ratio n + // fullscreen desktop aspect ratio d + // fullscreen desktop scale n + // fullscreen desktop scale d + // multisample number of samples (0/2/4) if (fscanf(fp, "%d", &mode) == 1) { fclose(fp); @@ -373,6 +422,8 @@ int InitSDL() atexit(SDL_Quit); + SDL_AddEventWatch(SDLEventFilter, NULL); + #if 0 SDL_Rect **SDL_AvailableVideoModes; SDL_AvailableVideoModes = SDL_ListModes(NULL, SDL_WINDOW_FULLSCREEN | SDL_WINDOW_OPENGL); @@ -480,10 +531,128 @@ int InitSDL() return 0; } +#if !defined(NDEBUG) +static void DumpVideoModeInfo(SDL_Window* w) { + int numVideoDisplays; + int displayIndex; + int numDisplayModes; + int modeIndex; + const char* displayName; + numVideoDisplays = SDL_GetNumVideoDisplays(); + if (numVideoDisplays > 0) { + for (displayIndex = 0; displayIndex < numVideoDisplays; displayIndex++) { + displayName = SDL_GetDisplayName(displayIndex); + printf("%d: %s\n", displayIndex, displayName); + + SDL_Rect bounds; + SDL_DisplayMode mode; + + if (SDL_GetDisplayBounds(displayIndex, &bounds) == 0) { + printf("\tbounds: %4d,%4d,%4d,%4d\n", + bounds.x, + bounds.y, + bounds.w, + bounds.h); + } + + if (SDL_GetDesktopDisplayMode(displayIndex, &mode) == 0) { + printf("\tdesktop: %08x,%4d,%4d,%d\n", + mode.format, + mode.w, + mode.h, + mode.refresh_rate); + } + + if (SDL_GetCurrentDisplayMode(displayIndex, &mode) == 0) { + printf("\tcurrent: %08x,%4d,%4d,%d\n", + mode.format, + mode.w, + mode.h, + mode.refresh_rate); + } + + numDisplayModes = SDL_GetNumDisplayModes(displayIndex); + for (modeIndex = 0; modeIndex < numDisplayModes; modeIndex++) { + if (SDL_GetDisplayMode(displayIndex, modeIndex, &mode) == 0) { + printf("\t%2d: %08x,%4d,%4d,%d\n", + modeIndex, + mode.format, + mode.w, + mode.h, + mode.refresh_rate); + } + } + } + } + + if (w != NULL) { + int displayIndex; + SDL_DisplayMode mode; + + displayIndex = SDL_GetWindowDisplayIndex(w); + + printf("Window display index: %d\n", displayIndex); + if (SDL_GetWindowDisplayMode(w, &mode) == 0) { + printf("Window display mode: %08x,%4d,%4d,%d\n", + mode.format, + mode.w, + mode.h, + mode.refresh_rate); + } + } +} +#endif + +static void SetWindowSize(int PhysicalWidth, int PhysicalHeight, int VirtualWidth, int VirtualHeight) +{ +#if !defined(NDEBUG) + fprintf(stderr, "SetWindowSize(%d,%d,%d,%d); %d\n", PhysicalWidth, PhysicalHeight, VirtualWidth, VirtualHeight, CurrentVideoMode); +#endif + + ViewportWidth = PhysicalWidth; + ViewportHeight = PhysicalHeight; + + ScreenDescriptorBlock.SDB_Width = VirtualWidth; + ScreenDescriptorBlock.SDB_Height = VirtualHeight; + ScreenDescriptorBlock.SDB_CentreX = VirtualWidth/2; + ScreenDescriptorBlock.SDB_CentreY = VirtualHeight/2; + ScreenDescriptorBlock.SDB_ProjX = VirtualWidth/2; + ScreenDescriptorBlock.SDB_ProjY = VirtualHeight/2; + ScreenDescriptorBlock.SDB_ClipLeft = 0; + ScreenDescriptorBlock.SDB_ClipRight = VirtualWidth; + ScreenDescriptorBlock.SDB_ClipUp = 0; + ScreenDescriptorBlock.SDB_ClipDown = VirtualHeight; + + if (window != NULL) { + SDL_SetWindowSize(window, PhysicalWidth, PhysicalHeight); + + //pglViewport(0, 0, ViewportWidth, ViewportHeight); + } + +#if !defined(NDEBUG) + DumpVideoModeInfo(window); +#endif +} + +static int SetSoftVideoMode(int Width, int Height, int Depth) +{ + //TODO: clear surface + + RenderingMode = RENDERING_MODE_SOFTWARE; + ScanDrawMode = ScanDrawD3DHardwareRGB; + GotMouse = 1; + + // reset input + IngameKeyboardInput_ClearBuffer(); + + SetWindowSize(ViewportWidth, ViewportHeight, Width, Height); + + return 0; +} + /* ** */ static void load_opengl_library(const char *lib) { -#if 0//REVIEW char tmppath[PATH_MAX]; size_t len, copylen; @@ -499,9 +668,9 @@ static void load_opengl_library(const char *lib) while (lib != NULL && *lib) { len = strcspn(lib, ":"); - + copylen = min(len, PATH_MAX-1); - + strncpy(tmppath, lib, copylen); tmppath[copylen] = 0; @@ -516,33 +685,9 @@ static void load_opengl_library(const char *lib) fprintf(stderr, "ERROR: unable to initialize opengl library: %s\n", SDL_GetError()); exit(EXIT_FAILURE); -#endif -} - -int SetSoftVideoMode(int Width, int Height, int Depth) -{ - //TODO: clear surface - - ScanDrawMode = ScanDrawD3DHardwareRGB; - GotMouse = 1; - - // reset input - IngameKeyboardInput_ClearBuffer(); - - ScreenDescriptorBlock.SDB_Width = Width; - ScreenDescriptorBlock.SDB_Height = Height; - ScreenDescriptorBlock.SDB_CentreX = Width/2; - ScreenDescriptorBlock.SDB_CentreY = Height/2; - ScreenDescriptorBlock.SDB_ProjX = Width/2; - ScreenDescriptorBlock.SDB_ProjY = Height/2; - ScreenDescriptorBlock.SDB_ClipLeft = 0; - ScreenDescriptorBlock.SDB_ClipRight = Width; - ScreenDescriptorBlock.SDB_ClipUp = 0; - ScreenDescriptorBlock.SDB_ClipDown = Height; - - return 0; } +/* ** */ static int SDLCALL SDLEventFilter(void* userData, SDL_Event* event) { (void) userData; @@ -557,30 +702,45 @@ static int SDLCALL SDLEventFilter(void* userData, SDL_Event* event) { return 1; } -int SetOGLVideoMode(int Width, int Height) +static int InitSDLVideo(void) { + return 0; +} + +static int SetOGLVideoMode(int Width, int Height) { int oldflags; int flags; + RenderingMode = RENDERING_MODE_OPENGL; ScanDrawMode = ScanDrawD3DHardwareRGB; GotMouse = 1; +#if defined(FIXED_WINDOW_SIZE) + // force the game to use the full desktop + SDL_DisplayMode dm; + if (SDL_GetDesktopDisplayMode(0, &dm) == 0) { + Width = dm.w; + Height = dm.h; + } +#endif + if (window == NULL) { load_ogl_functions(0); - /* - if (window != NULL) { - oldflags = SDL_GetWindowFlags(window); - - SDL_DestroyWindow(window); - } - - */ flags = SDL_WINDOW_OPENGL; + +#if defined(FIXED_WINDOW_SIZE) + flags |= SDL_WINDOW_BORDERLESS; + flags |= SDL_WINDOW_FULLSCREEN_DESKTOP; +#else if (WantFullscreen) { - flags |= SDL_WINDOW_FULLSCREEN; + flags |= (WantResolutionChange != 0 ? SDL_WINDOW_FULLSCREEN : SDL_WINDOW_FULLSCREEN_DESKTOP); } + // the game doesn't properly support window resizing + //flags |= SDL_WINDOW_RESIZABLE; +#endif + // reset input IngameKeyboardInput_ClearBuffer(); @@ -588,27 +748,35 @@ int SetOGLVideoMode(int Width, int Height) SDL_QuitSubSystem(SDL_INIT_VIDEO); SDL_InitSubSystem(SDL_INIT_VIDEO); - load_opengl_library(opengl_library); - + // set OpenGL attributes first +#if defined(USE_OPENGL_ES) + SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_ES); + SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 1); + SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 1); +#else SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 2); SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 1); - +#endif + // These should be configurable video options. + // If user requests 8bpp, try that, else fall back to 5. + // Same with depth. Try 32, 24, 16. SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 5); SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 5); SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 5); SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 16); SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); + load_opengl_library(opengl_library); + // These should be configurable video options. //SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 1); //SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, 4); - SDL_GL_SetSwapInterval(1); - + window = SDL_CreateWindow("Aliens vs Predator", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, - Width, - Height, + WindowWidth, + WindowHeight, flags); if (window == NULL) { fprintf(stderr, "(OpenGL) SDL SDL_CreateWindow failed: %s\n", SDL_GetError()); @@ -622,27 +790,41 @@ int SetOGLVideoMode(int Width, int Height) } SDL_GL_MakeCurrent(window, context); - SDL_AddEventWatch(SDLEventFilter, NULL); //TODO move this to startup? + // These should be configurable video options. + SDL_GL_SetSwapInterval(1); load_ogl_functions(1); - ///* this is for supporting keyboard input processing with little hassle */ - //SDL_EnableKeyRepeat(SDL_DEFAULT_REPEAT_DELAY, SDL_DEFAULT_REPEAT_INTERVAL); - - //SDL_SetRelativeMouseMode(isgrab); + SDL_GetWindowSize(window, &Width, &Height); + pglViewport(0, 0, Width, Height); + + // create fullscreen window texture + pglGenTextures(1, &FullscreenTexture); + + pglBindTexture(GL_TEXTURE_2D, FullscreenTexture); + + pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + + FullscreenTextureWidth = 1024; + FullscreenTextureHeight = 512; + pglTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, FullscreenTextureWidth, FullscreenTextureHeight, 0, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, NULL); } + + SDL_GetWindowSize(window, &Width, &Height); - ViewportWidth = Width; - ViewportHeight = Height; - - SDL_SetWindowSize(window, Width, Height); - - pglViewport(0, 0, Width, Height); - - pglMatrixMode(GL_PROJECTION); - pglLoadIdentity(); - pglMatrixMode(GL_MODELVIEW); - pglLoadIdentity(); + SetWindowSize(Width, Height, Width, Height); + + int NewWidth, NewHeight; + SDL_GetWindowSize(window, &Width, &Height); + if (Width != NewWidth || Height != NewHeight) { + //printf("Failed to change size: %d,%d vs. %d,%d\n", Width, Height, NewWidth, NewHeight); + //Width = NewWidth; + //Height = NewHeight; + //SetWindowSize(Width, Height, Width, Height); + } pglEnable(GL_BLEND); pglBlendFunc(GL_SRC_ALPHA, GL_ONE); @@ -654,22 +836,9 @@ int SetOGLVideoMode(int Width, int Height) pglEnable(GL_TEXTURE_2D); - pglPolygonMode(GL_FRONT, GL_FILL); - pglPolygonMode(GL_BACK, GL_FILL); pglDisable(GL_CULL_FACE); pglClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - - ScreenDescriptorBlock.SDB_Width = Width; - ScreenDescriptorBlock.SDB_Height = Height; - ScreenDescriptorBlock.SDB_CentreX = Width/2; - ScreenDescriptorBlock.SDB_CentreY = Height/2; - ScreenDescriptorBlock.SDB_ProjX = Width/2; - ScreenDescriptorBlock.SDB_ProjY = Height/2; - ScreenDescriptorBlock.SDB_ClipLeft = 0; - ScreenDescriptorBlock.SDB_ClipRight = Width; - ScreenDescriptorBlock.SDB_ClipUp = 0; - ScreenDescriptorBlock.SDB_ClipDown = Height; InitOpenGL(); @@ -687,6 +856,11 @@ int ExitWindowsSystem() SDL_JoystickClose(joy); } + if (FullscreenTexture != 0) { + pglDeleteTextures(1, &FullscreenTexture); + } + FullscreenTexture = 0; + load_ogl_functions(0); if (surface != NULL) { @@ -941,6 +1115,9 @@ static void handle_keypress(int key, int unicode, int press) if (press) { switch(key) { + case KEY_CR: + RE_ENTRANT_QUEUE_WinProc_AddMessage_WM_CHAR('\r'); + break; case KEY_BACKSPACE: RE_ENTRANT_QUEUE_WinProc_AddMessage_WM_KEYDOWN(VK_BACK); break; @@ -986,33 +1163,6 @@ static void handle_keypress(int key, int unicode, int press) KeyboardInput[key] = press; } -static void handle_buttonpress(int button, int press) -{ - int key; - - switch(button) { - case 4: /* mouse wheel up */ - key = KEY_MOUSEWHEELUP; - break; - case 5: /* mouse wheel down */ - key = KEY_MOUSEWHEELDOWN; - break; - default: /* other buttons are handled elsewhere */ - return; - } - - /* since this currently only handles wheel up/down */ - if (press == 0) - return; - - if (press && !KeyboardInput[key]) { - DebouncedKeyboardInput[key] = 1; - } - - GotAnyKey = 1; - KeyboardInput[key] = press; -} - void CheckForWindowsMessages() { SDL_Event event; @@ -1022,52 +1172,77 @@ void CheckForWindowsMessages() DebouncedGotAnyKey = 0; memset(DebouncedKeyboardInput, 0, sizeof(DebouncedKeyboardInput)); - wantmouse = 0; //(surface->flags & SDL_FULLSCREEN) || - //(SDL_WM_GrabInput(SDL_GRAB_QUERY) == SDL_GRAB_ON); + wantmouse = (SDL_GetRelativeMouseMode() == SDL_TRUE); + // "keyboard" events that don't have an up event KeyboardInput[KEY_MOUSEWHEELUP] = 0; KeyboardInput[KEY_MOUSEWHEELDOWN] = 0; - if (SDL_PollEvent(&event)) { - do { - switch(event.type) { - case SDL_MOUSEBUTTONDOWN: - if (wantmouse) - handle_buttonpress(event.button.button, 1); - break; - case SDL_MOUSEBUTTONUP: - break; - case SDL_TEXTINPUT: { - int unicode = event.text.text[0]; //TODO convert to utf-32 - if (unicode && !(unicode & 0xFF80)) { - RE_ENTRANT_QUEUE_WinProc_AddMessage_WM_CHAR(unicode); - KeyboardEntryQueue_Add(unicode); + while (SDL_PollEvent(&event)) { + switch(event.type) { + case SDL_MOUSEBUTTONDOWN: + break; + case SDL_MOUSEBUTTONUP: + break; + case SDL_MOUSEWHEEL: + if (wantmouse) { + if (event.wheel.y < 0) { + handle_keypress(KEY_MOUSEWHEELDOWN, 0, 1); + } else if (event.wheel.y > 0) { + handle_keypress(KEY_MOUSEWHEELUP, 0, 1); + } + } + break; + case SDL_TEXTINPUT: { + int unicode = event.text.text[0]; //TODO convert to utf-32 + if (unicode && !(unicode & 0xFF80)) { + RE_ENTRANT_QUEUE_WinProc_AddMessage_WM_CHAR(unicode); + KeyboardEntryQueue_Add(unicode); + } + } + break; + case SDL_KEYDOWN: + if (event.key.keysym.sym == SDLK_PRINTSCREEN) { + if (HavePrintScn == 0) + GotPrintScn = 1; + HavePrintScn = 1; + } else { + handle_keypress(KeySymToKey(event.key.keysym.sym), 0, 1); + } + break; + case SDL_KEYUP: + if (event.key.keysym.sym == SDLK_PRINTSCREEN) { + GotPrintScn = 0; + HavePrintScn = 0; + } else { + handle_keypress(KeySymToKey(event.key.keysym.sym), 0, 0); + } + break; + case SDL_WINDOWEVENT: + switch (event.window.event) { + case SDL_WINDOWEVENT_FOCUS_LOST: + // disable mouse grab? + break; + case SDL_WINDOWEVENT_RESIZED: + //printf("test, %d,%d\n", event.window.data1, event.window.data2); + WindowWidth = event.window.data1; + WindowHeight = event.window.data2; + if (RenderingMode == RENDERING_MODE_SOFTWARE) { + SetWindowSize(WindowWidth, WindowHeight, 640, 480); + } else { + SetWindowSize(WindowWidth, WindowHeight, WindowWidth, WindowHeight); } - } - break; - case SDL_KEYDOWN: - if (event.key.keysym.sym == SDLK_PRINTSCREEN) { - if (HavePrintScn == 0) - GotPrintScn = 1; - HavePrintScn = 1; - } else { - handle_keypress(KeySymToKey(event.key.keysym.sym), 0, 1); - } - break; - case SDL_KEYUP: - if (event.key.keysym.sym == SDLK_PRINTSCREEN) { - GotPrintScn = 0; - HavePrintScn = 0; - } else { - handle_keypress(KeySymToKey(event.key.keysym.sym), 0, 0); - } - break; - case SDL_QUIT: - AvP.MainLoopRunning = 0; /* TODO */ - exit(0); //TODO - break; - } - } while (SDL_PollEvent(&event)); + if (pglViewport != NULL) { + pglViewport(0, 0, WindowWidth, WindowHeight); + } + break; + } + break; + case SDL_QUIT: + AvP.MainLoopRunning = 0; /* TODO */ + exit(0); //TODO + break; + } } buttons = SDL_GetRelativeMouseState(&x, &y); @@ -1085,7 +1260,7 @@ void CheckForWindowsMessages() handle_keypress(KEY_RMOUSE, 0, 1); else handle_keypress(KEY_RMOUSE, 0, 0); - + MouseVelX = DIV_FIXED(x, NormalFrameTime); MouseVelY = DIV_FIXED(y, NormalFrameTime); } else { @@ -1117,31 +1292,47 @@ void CheckForWindowsMessages() } } +//#warning Redo WantX, need to split it out better so fullscreen can temporary set relative without clobbering user setting if ((KeyboardInput[KEY_LEFTALT]||KeyboardInput[KEY_RIGHTALT]) && DebouncedKeyboardInput[KEY_CR]) { - //SDL_GrabMode gm; - // - //SDL_WM_ToggleFullScreen(surface); - // - //gm = SDL_WM_GrabInput(SDL_GRAB_QUERY); - //if (gm == SDL_GRAB_OFF && !(surface->flags & SDL_FULLSCREEN)) - // SDL_ShowCursor(1); - //else - // SDL_ShowCursor(0); + if (WantFullscreenToggle != 0) { + int displayMode = SDL_GetWindowFlags(window); + //printf("Current window mode:%08x\n", displayMode); + if ((displayMode & (SDL_WINDOW_FULLSCREEN|SDL_WINDOW_FULLSCREEN_DESKTOP)) != 0) { + SDL_SetWindowFullscreen(window, 0); + } else { + SDL_SetWindowFullscreen(window, WantResolutionChange ? SDL_WINDOW_FULLSCREEN : SDL_WINDOW_FULLSCREEN_DESKTOP); + } + + displayMode = SDL_GetWindowFlags(window); + //printf("New window mode:%08x\n", displayMode); + if ((displayMode & (SDL_WINDOW_FULLSCREEN|SDL_WINDOW_FULLSCREEN_DESKTOP)) != 0) { + SDL_SetRelativeMouseMode(SDL_TRUE); + WantFullscreen = 1; + } else { + SDL_SetRelativeMouseMode(WantMouseGrab ? SDL_TRUE : SDL_FALSE); + WantFullscreen = 0; + } + } } if (KeyboardInput[KEY_LEFTCTRL] && DebouncedKeyboardInput[KEY_G]) { - //SDL_GrabMode gm; - // - //gm = SDL_WM_GrabInput(SDL_GRAB_QUERY); - //SDL_WM_GrabInput((gm == SDL_GRAB_ON) ? SDL_GRAB_OFF : SDL_GRAB_ON); - // - //gm = SDL_WM_GrabInput(SDL_GRAB_QUERY); - //if (gm == SDL_GRAB_OFF && !(surface->flags & SDL_FULLSCREEN)) - // SDL_ShowCursor(1); - //else - // SDL_ShowCursor(0); + int IsWindowed = (SDL_GetWindowFlags(window) & (SDL_WINDOW_FULLSCREEN|SDL_WINDOW_FULLSCREEN_DESKTOP)) == 0; + + if (IsWindowed) { + WantMouseGrab = WantMouseGrab != 0 ? 0 : 1; + if (WantMouseGrab != 0) { + SDL_SetRelativeMouseMode(SDL_TRUE); + } else { + SDL_SetRelativeMouseMode(SDL_FALSE); + } + WantMouseGrab = (SDL_GetRelativeMouseMode() == SDL_TRUE); + } } - + + // a second reset of relative mouse state because + // enabling relative mouse mode moves the mouse + SDL_GetRelativeMouseState(NULL, NULL); + if (GotPrintScn) { GotPrintScn = 0; @@ -1151,45 +1342,24 @@ void CheckForWindowsMessages() void InGameFlipBuffers() { - if (window != NULL) { - SDL_GL_SwapWindow(window); - } +#if !defined(NDEBUG) + check_for_errors(); +#endif + + SDL_GL_SwapWindow(window); } void FlipBuffers() { - // TODO: move this to init - static GLuint t; - - if (t == 0) { - pglGenTextures(1, &t); - - pglBindTexture(GL_TEXTURE_2D, t); - - pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); - pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); - - pglTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 640, 480, 0, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, NULL); - } - - pglDisableClientState(GL_VERTEX_ARRAY); - pglDisableClientState(GL_TEXTURE_COORD_ARRAY); - pglDisableClientState(GL_COLOR_ARRAY); - pglClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - pglMatrixMode(GL_PROJECTION); - pglLoadIdentity(); - pglMatrixMode(GL_MODELVIEW); - pglLoadIdentity(); - pglDisable(GL_ALPHA_TEST); pglDisable(GL_BLEND); pglDisable(GL_DEPTH_TEST); - pglBindTexture(GL_TEXTURE_2D, t); + pglBindTexture(GL_TEXTURE_2D, FullscreenTexture); + pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); pglTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); pglTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 640, 480, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, surface->pixels); @@ -1197,6 +1367,10 @@ void FlipBuffers() GLfloat x1; GLfloat y0; GLfloat y1; + GLfloat s0; + GLfloat s1; + GLfloat t0; + GLfloat t1; // figure out the best way to fit the 640x480 virtual window GLfloat a = ViewportHeight * 640.0f / 480.0f; @@ -1218,24 +1392,55 @@ void FlipBuffers() y0 = -y1; } - pglBegin(GL_QUADS); + s0 = 0.0f; + s1 = 640.0f / (float) FullscreenTextureWidth; + t0 = 0.0f; + t1 = 480.0f / (float) FullscreenTextureHeight; - pglTexCoord2f(0.0, 1.0); - pglVertex3f(x0, y0, -1.0); + GLfloat v[4*4]; + GLshort s[6]; - pglTexCoord2f(1.0, 1.0); - pglVertex3f(x1, y0, -1.0); + v[0+0*4] = x0; + v[1+0*4] = y0; + v[2+0*4] = s0; + v[3+0*4] = t1; + v[0+1*4] = x1; + v[1+1*4] = y0; + v[2+1*4] = s1; + v[3+1*4] = t1; + v[0+2*4] = x1; + v[1+2*4] = y1; + v[2+2*4] = s1; + v[3+2*4] = t0; + v[0+3*4] = x0; + v[1+3*4] = y1; + v[2+3*4] = s0; + v[3+3*4] = t0; - pglTexCoord2f(1.0, 0.0); - pglVertex3f(x1, y1, -1.0); + s[0] = 0; + s[1] = 1; + s[2] = 2; + s[3] = 0; + s[4] = 2; + s[5] = 3; - pglTexCoord2f(0.0, 0.0); - pglVertex3f(x0, y1, -1.0); + pglEnableClientState(GL_VERTEX_ARRAY); + pglVertexPointer(2, GL_FLOAT, sizeof(GLfloat) * 4, &v[0]); - pglEnd(); + pglEnableClientState(GL_TEXTURE_COORD_ARRAY); + pglTexCoordPointer(2, GL_FLOAT, sizeof(GLfloat) * 4, &v[2]); + + pglDisableClientState(GL_COLOR_ARRAY); + + pglColor4f(1.0f, 1.0f, 1.0f, 1.0f); + pglDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, s); pglBindTexture(GL_TEXTURE_2D, 0); +#if !defined(NDEBUG) + check_for_errors(); +#endif + SDL_GL_SwapWindow(window); } @@ -1339,10 +1544,9 @@ int main(int argc, char *argv[]) #endif InitGame(); - //NEW - SetOGLVideoMode(VideoModeList[1].w, VideoModeList[1].h); - //NEW - + WindowWidth = VideoModeList[CurrentVideoMode].w; + WindowHeight = VideoModeList[CurrentVideoMode].h; + SetOGLVideoMode(0, 0); SetSoftVideoMode(640, 480, 16); InitialVideoMode(); @@ -1391,16 +1595,8 @@ if (AvP_MainMenus()) /* turn off any special effects */ d3d_light_ctrl.ctrl = LCCM_NORMAL; - - //NEW - //TODO - // need to watch for CurrentVideoMode to change in all cases - // the menu will always render in a 640x480 virtual window - // game will render in a user-specified virtual window - // real window will be which ever size is available - //TODO - //NEW - SetOGLVideoMode(VideoModeList[CurrentVideoMode].w, VideoModeList[CurrentVideoMode].h); + + SetOGLVideoMode(0, 0); InitialiseGammaSettings(RequestedGammaSetting); diff --git a/src/mathline.c b/src/mathline.c index a7ca296..a0eeac6 100644 --- a/src/mathline.c +++ b/src/mathline.c @@ -1,6 +1,7 @@ #include #include "3dc.h" +#include "mathline.h" void ADD_LL(LONGLONGCH *a, LONGLONGCH *b, LONGLONGCH *c); void ADD_LL_PP(LONGLONGCH *c, LONGLONGCH *a); @@ -12,21 +13,13 @@ void EQUALS_LL(LONGLONGCH *a, LONGLONGCH *b); void NEG_LL(LONGLONGCH *a); void ASR_LL(LONGLONGCH *a, int shift); void IntToLL(LONGLONGCH *a, int *b); -int MUL_FIXED(int a, int b); int DIV_FIXED(int a, int b); -#define DIV_INT(a, b) ((a) / (b)) - int NarrowDivide(LONGLONGCH *a, int b); int WideMulNarrowDiv(int a, int b, int c); void RotateVector_ASM(VECTORCH *v, MATRIXCH *m); void RotateAndCopyVector_ASM(VECTORCH *v1, VECTORCH *v2, MATRIXCH *m); -#if 0 -int FloatToInt(float); -#define f2i(a, b) { a = FloatToInt(b); } -#endif - #undef ASM386 #if !defined(ASM386) @@ -450,63 +443,10 @@ __asm__("movl 0(%%esi), %%eax \n\t" #endif } -/* - - Fixed Point Multiply. - - - 16.16 * 16.16 -> 16.16 - or - 16.16 * 0.32 -> 0.32 - - A proper version of this function ought to read - 16.16 * 16.16 -> 32.16 - but this would require a __int64 result - - Algorithm: - - Take the mid 32 bits of the 64 bit result - -*/ - -/* - These functions have been checked for suitability for - a Pentium and look as if they would work adequately. - Might be worth a more detailed look at optimising - them though. -*/ - -int MUL_FIXED(int a, int b) -{ -/* - int retval; - _asm - { - mov eax,a - imul b - shrd eax,edx,16 - mov retval,eax - } -*/ - -#if defined(ASM386) - int retval; -__asm__("imull %2 \n\t" - "shrdl $16, %%edx, %%eax \n\t" - : "=a" (retval) - : "0" (a), "m" (b) - : "%edx", "cc" - ); - return retval; -#else - __int64 aa = (__int64) a; - __int64 bb = (__int64) b; - - __int64 cc = aa * bb; - - return (int) ((cc >> 16) & 0xffffffff); -#endif -} +// +// Fixed Point Multiply - MUL_FIXED +// See mathline.h +// /* @@ -561,17 +501,6 @@ __asm__("cdq \n\t" */ - -/* - - 32/32 division - - This macro is a function on some other platforms - -*/ - -#define DIV_INT(a, b) ((a) / (b)) - /* A Narrowing 64/32 Division @@ -687,31 +616,7 @@ __asm__ volatile return sqrt_temp; #else - return (int) sqrt( (float)A ); -#endif -} - -/* - - This may look ugly (it is) but it is a MUCH faster way to convert "float" into "int" than - the function call "CHP" used by the WATCOM compiler. - -*/ - -volatile float fti_fptmp; -volatile int fti_itmp; - -void FloatToInt() -{ -#if defined(ASM386) -__asm__ volatile - ("flds fti_fptmp \n\t" - "fistpl fti_itmp \n\t" - : - : - : "memory", "cc" - ); -#else - fti_itmp = (int)fti_fptmp; + float fA = A; + return lrintf(sqrtf(fA)); #endif } diff --git a/src/mathline.h b/src/mathline.h new file mode 100644 index 0000000..b1620a5 --- /dev/null +++ b/src/mathline.h @@ -0,0 +1,66 @@ +#ifndef MATHLINE_H +#define MATHLINE_H + +#include + +#define f2i(a, b) a = lrintf(b) + +/* + + Fixed Point Multiply. + + + 16.16 * 16.16 -> 16.16 + or + 16.16 * 0.32 -> 0.32 + + A proper version of this function ought to read + 16.16 * 16.16 -> 32.16 + but this would require a __int64 result + + Algorithm: + + Take the mid 32 bits of the 64 bit result + +*/ + +/* + These functions have been checked for suitability for + a Pentium and look as if they would work adequately. + Might be worth a more detailed look at optimising + them though. +*/ + +static inline int MUL_FIXED(int a, int b) +{ +/* + int retval; + _asm + { + mov eax,a + imul b + shrd eax,edx,16 + mov retval,eax + } +*/ + +#if defined(ASM386) + int retval; +__asm__("imull %2 \n\t" + "shrdl $16, %%edx, %%eax \n\t" + : "=a" (retval) + : "0" (a), "m" (b) + : "%edx", "cc" + ); + return retval; +#else + __int64 aa = (__int64) a; + __int64 bb = (__int64) b; + + __int64 cc = aa * bb; + + return (int) ((cc >> 16) & 0xffffffff); +#endif +} + +#endif diff --git a/src/menus.c b/src/menus.c index 25e98ae..1679d00 100644 --- a/src/menus.c +++ b/src/menus.c @@ -115,13 +115,6 @@ AVPMENUGFX AvPMenuGfxStorage[MAX_NO_OF_AVPMENUGFXS] = #endif }; -int CreateIMGSurface(D3DTexture *tex, unsigned char *buf) -{ - tex->id = 0; - - return 0; -} - static void DrawAvPMenuGlowyBar(int topleftX, int topleftY, int alpha, int length) { enum AVPMENUGFX_ID menuGfxID = AVPMENUGFX_GLOWY_MIDDLE; @@ -449,17 +442,25 @@ int RenderMenuText(const char *textPtr, int sx, int sy, int alpha, enum AVPMENUF char c = *textPtr++; if (c>=' ') { - int topLeftU = 1; - int topLeftV = 1+(c-32)*33; - int x, y; - int width = IntroFont_Light.FontWidth[(unsigned int) c]; - + unsigned int topLeftU = 0; + unsigned int topLeftV = 1+(c-32)*33; + unsigned int x, y; + unsigned int width = IntroFont_Light.FontWidth[(unsigned int) c]; + unsigned int remainder = 0; + unsigned int stride = width; + + if (image->w > width) { + remainder = image->w - width; + } else { + stride = image->w; + } + srcPtr = &image->buf[(topLeftU+topLeftV*image->w)*4]; - + for (y=sy; y<33+sy; y++) { destPtr = (unsigned short *)(((unsigned char *)surface->pixels)+y*surface->pitch) + sx; - for (x=width; x>0; x--) { + for (x=stride; x>0; x--) { if (srcPtr[0] || srcPtr[1] || srcPtr[2]) { unsigned int destR, destG, destB; @@ -484,7 +485,7 @@ int RenderMenuText(const char *textPtr, int sx, int sy, int alpha, enum AVPMENUF srcPtr += 4; destPtr++; } - srcPtr += (image->w - width) * 4; + srcPtr += remainder * 4; } sx += width; } @@ -546,18 +547,26 @@ int RenderMenuText_Clipped(char *textPtr, int sx, int sy, int alpha, enum AVPMEN char c = *textPtr++; if (c>=' ') { - int topLeftU = 1; - int topLeftV = 1+(c-32)*33; - int x, y; - int width = IntroFont_Light.FontWidth[(unsigned int) c]; - + unsigned int topLeftU = 0; + unsigned int topLeftV = 1+(c-32)*33; + unsigned int x, y; + unsigned int width = IntroFont_Light.FontWidth[(unsigned int) c]; + unsigned int remainder = 0; + unsigned int stride = width; + + if (image->w > width) { + remainder = image->w - width; + } else { + stride = image->w; + } + srcPtr = &image->buf[(topLeftU+topLeftV*image->w)*4]; - + for (y=sy; y<33+sy; y++) { if(y>=topY && y<=bottomY) { destPtr = (unsigned short *)(((unsigned char *)surface->pixels)+y*surface->pitch) + sx; - for (x=width; x>0; x--) { + for (x=stride; x>0; x--) { if (srcPtr[0] || srcPtr[1] || srcPtr[2]) { unsigned int destR, destG, destB; @@ -582,7 +591,7 @@ int RenderMenuText_Clipped(char *textPtr, int sx, int sy, int alpha, enum AVPMEN srcPtr += 4; destPtr++; } - srcPtr += (image->w - width) * 4; + srcPtr += remainder * 4; } else { srcPtr += image->w * 4; } diff --git a/src/oglfunc.c b/src/oglfunc.c index c5ec48e..d1ada9a 100644 --- a/src/oglfunc.c +++ b/src/oglfunc.c @@ -6,20 +6,11 @@ #include "oglfunc.h" PFNGLALPHAFUNCPROC pglAlphaFunc; -PFNGLARRAYELEMENTPROC pglArrayElement; -PFNGLBEGINPROC pglBegin; PFNGLBINDTEXTUREPROC pglBindTexture; PFNGLBLENDFUNCPROC pglBlendFunc; PFNGLCLEARPROC pglClear; PFNGLCLEARCOLORPROC pglClearColor; -PFNGLCOLOR3FPROC pglColor3f; -PFNGLCOLOR3FVPROC pglColor3fv; -PFNGLCOLOR3UBPROC pglColor3ub; -PFNGLCOLOR3UBVPROC pglColor3ubv; PFNGLCOLOR4FPROC pglColor4f; -PFNGLCOLOR4FVPROC pglColor4fv; -PFNGLCOLOR4UBPROC pglColor4ub; -PFNGLCOLOR4UBVPROC pglColor4ubv; PFNGLCOLORPOINTERPROC pglColorPointer; PFNGLCULLFACEPROC pglCullFace; PFNGLDELETETEXTURESPROC pglDeleteTextures; @@ -28,15 +19,10 @@ PFNGLDEPTHMASKPROC pglDepthMask; PFNGLDEPTHRANGEPROC pglDepthRange; PFNGLDISABLEPROC pglDisable; PFNGLDISABLECLIENTSTATEPROC pglDisableClientState; -PFNGLDRAWBUFFERPROC pglDrawBuffer; PFNGLDRAWELEMENTSPROC pglDrawElements; -PFNGLDRAWPIXELSPROC pglDrawPixels; -PFNGLDRAWRANGEELEMENTSPROC pglDrawRangeElements; PFNGLENABLEPROC pglEnable; PFNGLENABLECLIENTSTATEPROC pglEnableClientState; -PFNGLENDPROC pglEnd; PFNGLFRONTFACEPROC pglFrontFace; -PFNGLFRUSTUMPROC pglFrustum; PFNGLGENTEXTURESPROC pglGenTextures; PFNGLGETERRORPROC pglGetError; PFNGLGETFLOATVPROC pglGetFloatv; @@ -44,34 +30,10 @@ PFNGLGETINTEGERVPROC pglGetIntegerv; PFNGLGETSTRINGPROC pglGetString; PFNGLGETTEXPARAMETERFVPROC pglGetTexParameterfv; PFNGLHINTPROC pglHint; -PFNGLLOADIDENTITYPROC pglLoadIdentity; -PFNGLLOADMATRIXFPROC pglLoadMatrixf; -PFNGLMATRIXMODEPROC pglMatrixMode; -PFNGLMULTMATRIXFPROC pglMultMatrixf; -PFNGLNORMALPOINTERPROC pglNormalPointer; -PFNGLORTHOPROC pglOrtho; PFNGLPIXELSTOREIPROC pglPixelStorei; -PFNGLPIXELZOOMPROC pglPixelZoom; -PFNGLPOLYGONMODEPROC pglPolygonMode; PFNGLPOLYGONOFFSETPROC pglPolygonOffset; -PFNGLPOPATTRIBPROC pglPopAttrib; -PFNGLPOPCLIENTATTRIBPROC pglPopClientAttrib; -PFNGLPOPMATRIXPROC pglPopMatrix; -PFNGLPUSHATTRIBPROC pglPushAttrib; -PFNGLPUSHCLIENTATTRIBPROC pglPushClientAttrib; -PFNGLPUSHMATRIXPROC pglPushMatrix; -PFNGLRASTERPOS2IPROC pglRasterPos2i; -PFNGLREADBUFFERPROC pglReadBuffer; PFNGLREADPIXELSPROC pglReadPixels; -PFNGLROTATEFPROC pglRotatef; -PFNGLSCALEFPROC pglScalef; PFNGLSHADEMODELPROC pglShadeModel; -PFNGLTEXCOORD2FPROC pglTexCoord2f; -PFNGLTEXCOORD2FVPROC pglTexCoord2fv; -PFNGLTEXCOORD3FPROC pglTexCoord3f; -PFNGLTEXCOORD3FVPROC pglTexCoord3fv; -PFNGLTEXCOORD4FPROC pglTexCoord4f; -PFNGLTEXCOORD4FVPROC pglTexCoord4fv; PFNGLTEXCOORDPOINTERPROC pglTexCoordPointer; PFNGLTEXENVFPROC pglTexEnvf; PFNGLTEXENVFVPROC pglTexEnvfv; @@ -80,50 +42,37 @@ PFNGLTEXIMAGE2DPROC pglTexImage2D; PFNGLTEXPARAMETERFPROC pglTexParameterf; PFNGLTEXPARAMETERIPROC pglTexParameteri; PFNGLTEXSUBIMAGE2DPROC pglTexSubImage2D; -PFNGLTRANSLATEFPROC pglTranslatef; -PFNGLVERTEX2FPROC pglVertex2f; -PFNGLVERTEX2FVPROC pglVertex2fv; -PFNGLVERTEX3FPROC pglVertex3f; -PFNGLVERTEX3FVPROC pglVertex3fv; -PFNGLVERTEX4FPROC pglVertex4f; -PFNGLVERTEX4FVPROC pglVertex4fv; PFNGLVERTEXPOINTERPROC pglVertexPointer; PFNGLVIEWPORTPROC pglViewport; -// GL_EXT_paletted_texture -PFNGLCOLORTABLEEXTPROC pglColorTableEXT; -PFNGLGETCOLORTABLEPARAMETERIVEXTPROC pglGetColorTableParameterivEXT; - -// GL_EXT_secondary_color -PFNGLSECONDARYCOLOR3FEXTPROC pglSecondaryColor3fEXT; -PFNGLSECONDARYCOLOR3FVEXTPROC pglSecondaryColor3fvEXT; -PFNGLSECONDARYCOLOR3UBEXTPROC pglSecondaryColor3ubEXT; -PFNGLSECONDARYCOLOR3UBVEXTPROC pglSecondaryColor3ubvEXT; -PFNGLSECONDARYCOLORPOINTEREXTPROC pglSecondaryColorPointerEXT; - int ogl_have_multisample_filter_hint; -int ogl_have_paletted_texture; -int ogl_have_secondary_color; int ogl_have_texture_filter_anisotropic; int ogl_use_multisample_filter_hint; -int ogl_use_paletted_texture; -int ogl_use_secondary_color; int ogl_use_texture_filter_anisotropic; static void dummyfunc() { } -#define LoadOGLProc(type, func) \ -{ \ +#define LoadOGLProc_(type, func, name) { \ if (!mode) p##func = (type) dummyfunc; else \ - p##func = (type) SDL_GL_GetProcAddress(#func); \ + p##func = (type) SDL_GL_GetProcAddress(#name); \ if (p##func == NULL) { \ if (!ogl_missing_func) ogl_missing_func = #func; \ } \ } +#define LoadOGLProc(type, func) \ + LoadOGLProc_(type, func, func) + +#define LoadOGLProc2(type, func1, func2) \ + LoadOGLProc_(type, func1, func1); \ + if (p##func1 == NULL) { \ + ogl_missing_func = NULL; \ + LoadOGLProc_(type, func1, func2); \ + } + static int check_token(const char *string, const char *token) { const char *s = string; @@ -152,37 +101,23 @@ void load_ogl_functions(int mode) ogl_missing_func = NULL; LoadOGLProc(PFNGLALPHAFUNCPROC, glAlphaFunc); - LoadOGLProc(PFNGLARRAYELEMENTPROC, glArrayElement); - LoadOGLProc(PFNGLBEGINPROC, glBegin); LoadOGLProc(PFNGLBINDTEXTUREPROC, glBindTexture); LoadOGLProc(PFNGLBLENDFUNCPROC, glBlendFunc); LoadOGLProc(PFNGLCLEARPROC, glClear); LoadOGLProc(PFNGLCLEARCOLORPROC, glClearColor); - LoadOGLProc(PFNGLCOLOR3FPROC, glColor3f); - LoadOGLProc(PFNGLCOLOR3FVPROC, glColor3fv); - LoadOGLProc(PFNGLCOLOR3UBPROC, glColor3ub); - LoadOGLProc(PFNGLCOLOR3UBVPROC, glColor3ubv); LoadOGLProc(PFNGLCOLOR4FPROC, glColor4f); - LoadOGLProc(PFNGLCOLOR4FVPROC, glColor4fv); - LoadOGLProc(PFNGLCOLOR4UBPROC, glColor4ub); - LoadOGLProc(PFNGLCOLOR4UBVPROC, glColor4ubv); LoadOGLProc(PFNGLCOLORPOINTERPROC, glColorPointer); LoadOGLProc(PFNGLCULLFACEPROC, glCullFace); LoadOGLProc(PFNGLDELETETEXTURESPROC, glDeleteTextures); LoadOGLProc(PFNGLDEPTHFUNCPROC, glDepthFunc); LoadOGLProc(PFNGLDEPTHMASKPROC, glDepthMask); - LoadOGLProc(PFNGLDEPTHRANGEPROC, glDepthRange); + LoadOGLProc2(PFNGLDEPTHRANGEPROC, glDepthRange, glDepthRangef); LoadOGLProc(PFNGLDISABLEPROC, glDisable); LoadOGLProc(PFNGLDISABLECLIENTSTATEPROC, glDisableClientState); - LoadOGLProc(PFNGLDRAWBUFFERPROC, glDrawBuffer); LoadOGLProc(PFNGLDRAWELEMENTSPROC, glDrawElements); - LoadOGLProc(PFNGLDRAWPIXELSPROC, glDrawPixels); - LoadOGLProc(PFNGLDRAWRANGEELEMENTSPROC, glDrawRangeElements); LoadOGLProc(PFNGLENABLEPROC, glEnable); LoadOGLProc(PFNGLENABLECLIENTSTATEPROC, glEnableClientState); - LoadOGLProc(PFNGLENDPROC, glEnd); LoadOGLProc(PFNGLFRONTFACEPROC, glFrontFace); - LoadOGLProc(PFNGLFRUSTUMPROC, glFrustum); LoadOGLProc(PFNGLGENTEXTURESPROC, glGenTextures); LoadOGLProc(PFNGLGETERRORPROC, glGetError); LoadOGLProc(PFNGLGETFLOATVPROC, glGetFloatv); @@ -190,34 +125,10 @@ void load_ogl_functions(int mode) LoadOGLProc(PFNGLGETSTRINGPROC, glGetString); LoadOGLProc(PFNGLGETTEXPARAMETERFVPROC, glGetTexParameterfv); LoadOGLProc(PFNGLHINTPROC, glHint); - LoadOGLProc(PFNGLLOADIDENTITYPROC, glLoadIdentity); - LoadOGLProc(PFNGLLOADMATRIXFPROC, glLoadMatrixf); - LoadOGLProc(PFNGLMATRIXMODEPROC, glMatrixMode); - LoadOGLProc(PFNGLMULTMATRIXFPROC, glMultMatrixf); - LoadOGLProc(PFNGLNORMALPOINTERPROC, glNormalPointer); - LoadOGLProc(PFNGLORTHOPROC, glOrtho); LoadOGLProc(PFNGLPIXELSTOREIPROC, glPixelStorei); - LoadOGLProc(PFNGLPIXELZOOMPROC, glPixelZoom); - LoadOGLProc(PFNGLPOLYGONMODEPROC, glPolygonMode); LoadOGLProc(PFNGLPOLYGONOFFSETPROC, glPolygonOffset); - LoadOGLProc(PFNGLPOPATTRIBPROC, glPopAttrib); - LoadOGLProc(PFNGLPOPCLIENTATTRIBPROC, glPopClientAttrib); - LoadOGLProc(PFNGLPOPMATRIXPROC, glPopMatrix); - LoadOGLProc(PFNGLPUSHATTRIBPROC, glPushAttrib); - LoadOGLProc(PFNGLPUSHCLIENTATTRIBPROC, glPushClientAttrib); - LoadOGLProc(PFNGLPUSHMATRIXPROC, glPushMatrix); - LoadOGLProc(PFNGLRASTERPOS2IPROC, glRasterPos2i); - LoadOGLProc(PFNGLREADBUFFERPROC, glReadBuffer); LoadOGLProc(PFNGLREADPIXELSPROC, glReadPixels); - LoadOGLProc(PFNGLROTATEFPROC, glRotatef); - LoadOGLProc(PFNGLSCALEFPROC, glScalef); LoadOGLProc(PFNGLSHADEMODELPROC, glShadeModel); - LoadOGLProc(PFNGLTEXCOORD2FPROC, glTexCoord2f); - LoadOGLProc(PFNGLTEXCOORD2FVPROC, glTexCoord2fv); - LoadOGLProc(PFNGLTEXCOORD3FPROC, glTexCoord3f); - LoadOGLProc(PFNGLTEXCOORD3FVPROC, glTexCoord3fv); - LoadOGLProc(PFNGLTEXCOORD4FPROC, glTexCoord4f); - LoadOGLProc(PFNGLTEXCOORD4FVPROC, glTexCoord4fv); LoadOGLProc(PFNGLTEXCOORDPOINTERPROC, glTexCoordPointer); LoadOGLProc(PFNGLTEXENVFPROC, glTexEnvf); LoadOGLProc(PFNGLTEXENVFVPROC, glTexEnvfv); @@ -226,23 +137,10 @@ void load_ogl_functions(int mode) LoadOGLProc(PFNGLTEXPARAMETERFPROC, glTexParameterf); LoadOGLProc(PFNGLTEXPARAMETERIPROC, glTexParameteri); LoadOGLProc(PFNGLTEXSUBIMAGE2DPROC, glTexSubImage2D); - LoadOGLProc(PFNGLTRANSLATEFPROC, glTranslatef); - LoadOGLProc(PFNGLVERTEX2FPROC, glVertex2f); - LoadOGLProc(PFNGLVERTEX2FVPROC, glVertex2fv); - LoadOGLProc(PFNGLVERTEX3FPROC, glVertex3f); - LoadOGLProc(PFNGLVERTEX3FVPROC, glVertex3fv); - LoadOGLProc(PFNGLVERTEX4FPROC, glVertex4f); - LoadOGLProc(PFNGLVERTEX4FVPROC, glVertex4fv); LoadOGLProc(PFNGLVERTEXPOINTERPROC, glVertexPointer); LoadOGLProc(PFNGLVIEWPORTPROC, glViewport); if (!mode) { - ogl_have_paletted_texture = 0; - ogl_have_secondary_color = 0; - - ogl_use_paletted_texture = 0; - ogl_use_secondary_color = 0; - return; } @@ -251,67 +149,24 @@ void load_ogl_functions(int mode) exit(EXIT_FAILURE); } +#if !defined(NDEBUG) + printf("GL_VENDOR: %s\n", pglGetString(GL_VENDOR)); + printf("GL_RENDERER: %s\n", pglGetString(GL_RENDERER)); + printf("GL_VERSION: %s\n", pglGetString(GL_VERSION)); + //printf("GL_SHADING_LANGUAGE_VERSION: %s\n", pglGetString(GL_SHADING_LANGUAGE_VERSION)); + printf("GL_EXTENSIONS: %s\n", pglGetString(GL_EXTENSIONS)); +#endif + ext = (const char *) pglGetString(GL_EXTENSIONS); ogl_have_multisample_filter_hint = check_token(ext, "GL_NV_multisample_filter_hint"); - ogl_have_paletted_texture = check_token(ext, "GL_EXT_paletted_texture"); - ogl_have_secondary_color = check_token(ext, "GL_EXT_secondary_color"); ogl_have_texture_filter_anisotropic = check_token(ext, "GL_EXT_texture_filter_anisotropic"); -#ifndef GL_COLOR_TABLE_WIDTH_EXT -#define GL_COLOR_TABLE_WIDTH_EXT GL_COLOR_TABLE_WIDTH -#endif - - if (ogl_have_paletted_texture) { - ogl_missing_func = NULL; - - LoadOGLProc(PFNGLCOLORTABLEEXTPROC, glColorTableEXT); - LoadOGLProc(PFNGLGETCOLORTABLEPARAMETERIVEXTPROC, glGetColorTableParameterivEXT); - - if (!ogl_missing_func) { - GLint size; - - pglColorTableEXT(GL_PROXY_TEXTURE_2D, GL_RGBA, 256, GL_BGRA_EXT, GL_UNSIGNED_BYTE, NULL); - pglGetColorTableParameterivEXT(GL_PROXY_TEXTURE_2D, GL_COLOR_TABLE_WIDTH_EXT, &size); - - if (size != 256) { - ogl_have_paletted_texture = 0; - } - } else { - ogl_have_paletted_texture = 0; - } - } - - if (ogl_have_secondary_color) { - ogl_missing_func = NULL; - - LoadOGLProc(PFNGLSECONDARYCOLOR3FEXTPROC, glSecondaryColor3fEXT); - LoadOGLProc(PFNGLSECONDARYCOLOR3FVEXTPROC, glSecondaryColor3fvEXT); - LoadOGLProc(PFNGLSECONDARYCOLOR3UBEXTPROC, glSecondaryColor3ubEXT); - LoadOGLProc(PFNGLSECONDARYCOLOR3UBVEXTPROC, glSecondaryColor3ubvEXT); - LoadOGLProc(PFNGLSECONDARYCOLORPOINTEREXTPROC, glSecondaryColorPointerEXT); - - if (ogl_missing_func) { - ogl_have_secondary_color = 0; - } - } - ogl_use_multisample_filter_hint = ogl_have_multisample_filter_hint; - ogl_use_paletted_texture = ogl_have_paletted_texture; - ogl_use_secondary_color = ogl_have_secondary_color; ogl_use_texture_filter_anisotropic = ogl_have_texture_filter_anisotropic; - -#if 0 - fprintf(stderr, "RENDER DEBUG: pal:%d sec:%d mfh:%d tfa:%d\n", - ogl_use_paletted_texture, - ogl_use_secondary_color, - ogl_use_multisample_filter_hint, - ogl_use_texture_filter_anisotropic - ); -#endif } -int check_for_errors(const char *file, int line) +int check_for_errors_(const char *file, int line) { GLenum error; int diderror = 0; diff --git a/src/oglfunc.h b/src/oglfunc.h index a55fc1f..93490d2 100644 --- a/src/oglfunc.h +++ b/src/oglfunc.h @@ -5,25 +5,32 @@ #include #endif +#if defined(USE_OPENGL_ES) +#include "SDL_opengles.h" + +// OpenGL compatibility +typedef GLclampf GLclampd; +typedef GLfloat GLdouble; + +#else #include "SDL_opengl.h" -//#include -//#include +#endif + +#if !defined(GL_CLAMP_TO_EDGE) +// Originally added by GL_SGIS_texture_edge_clamp; part of OpenGL 1.2 core. +#define GL_CLAMP_TO_EDGE 0x812F +#endif + +#if !defined(APIENTRY) +#define APIENTRY +#endif typedef void (APIENTRY *PFNGLALPHAFUNCPROC)(GLenum, GLclampf); -typedef void (APIENTRY *PFNGLARRAYELEMENTPROC)(GLint); -typedef void (APIENTRY *PFNGLBEGINPROC)(GLenum); typedef void (APIENTRY *PFNGLBINDTEXTUREPROC)(GLenum, GLuint); typedef void (APIENTRY *PFNGLBLENDFUNCPROC)(GLenum, GLenum); typedef void (APIENTRY *PFNGLCLEARPROC)(GLbitfield); typedef void (APIENTRY *PFNGLCLEARCOLORPROC)(GLclampf, GLclampf, GLclampf, GLclampf); -typedef void (APIENTRY *PFNGLCOLOR3FPROC)(GLfloat, GLfloat, GLfloat); -typedef void (APIENTRY *PFNGLCOLOR3FVPROC)(const GLfloat *); -typedef void (APIENTRY *PFNGLCOLOR3UBPROC)(GLubyte, GLubyte, GLubyte); -typedef void (APIENTRY *PFNGLCOLOR3UBVPROC)(const GLubyte *); typedef void (APIENTRY *PFNGLCOLOR4FPROC)(GLfloat, GLfloat, GLfloat, GLfloat); -typedef void (APIENTRY *PFNGLCOLOR4FVPROC)(const GLfloat *); -typedef void (APIENTRY *PFNGLCOLOR4UBPROC)(GLubyte, GLubyte, GLubyte, GLubyte); -typedef void (APIENTRY *PFNGLCOLOR4UBVPROC)(const GLubyte *); typedef void (APIENTRY *PFNGLCOLORPOINTERPROC)(GLint, GLenum, GLsizei, const GLvoid *); typedef void (APIENTRY *PFNGLCULLFACEPROC)(GLenum); typedef void (APIENTRY *PFNGLDELETETEXTURESPROC)(GLsizei,const GLuint*); @@ -32,15 +39,10 @@ typedef void (APIENTRY *PFNGLDEPTHMASKPROC)(GLboolean); typedef void (APIENTRY *PFNGLDEPTHRANGEPROC)(GLclampd, GLclampd); typedef void (APIENTRY *PFNGLDISABLEPROC)(GLenum); typedef void (APIENTRY *PFNGLDISABLECLIENTSTATEPROC)(GLenum); -typedef void (APIENTRY *PFNGLDRAWBUFFERPROC)(GLenum); typedef void (APIENTRY *PFNGLDRAWELEMENTSPROC)(GLenum, GLsizei, GLenum, const GLvoid *); -typedef void (APIENTRY *PFNGLDRAWPIXELSPROC)(GLsizei, GLsizei, GLenum, GLenum, const GLvoid *); -typedef void (APIENTRY *PFNGLDRAWRANGEELEMENTSPROC)(GLenum, GLuint, GLuint, GLsizei, GLenum, const GLvoid *); typedef void (APIENTRY *PFNGLENABLEPROC)(GLenum); typedef void (APIENTRY *PFNGLENABLECLIENTSTATEPROC)(GLenum); -typedef void (APIENTRY *PFNGLENDPROC)(GLvoid); typedef void (APIENTRY *PFNGLFRONTFACEPROC)(GLenum); -typedef void (APIENTRY *PFNGLFRUSTUMPROC)(GLdouble, GLdouble, GLdouble, GLdouble, GLdouble, GLdouble); typedef void (APIENTRY *PFNGLGENTEXTURESPROC)(GLsizei,GLuint*); typedef GLenum (APIENTRY *PFNGLGETERRORPROC)(void); typedef void (APIENTRY *PFNGLGETFLOATVPROC)(GLenum, GLfloat *); @@ -48,34 +50,10 @@ typedef void (APIENTRY *PFNGLGETINTEGERVPROC)(GLenum, GLint *); typedef const GLubyte* (APIENTRY *PFNGLGETSTRINGPROC)(GLenum); typedef void (APIENTRY *PFNGLGETTEXPARAMETERFVPROC)(GLenum, GLenum, GLfloat*); typedef void (APIENTRY *PFNGLHINTPROC)(GLenum, GLenum); -typedef void (APIENTRY *PFNGLLOADIDENTITYPROC)(void); -typedef void (APIENTRY *PFNGLLOADMATRIXFPROC)(const GLfloat *); -typedef void (APIENTRY *PFNGLMATRIXMODEPROC)(GLenum); -typedef void (APIENTRY *PFNGLMULTMATRIXFPROC)(const GLfloat *); -typedef void (APIENTRY *PFNGLNORMALPOINTERPROC)(GLenum, GLsizei, const GLvoid *); -typedef void (APIENTRY *PFNGLORTHOPROC)(GLdouble, GLdouble, GLdouble, GLdouble, GLdouble, GLdouble); typedef void (APIENTRY *PFNGLPIXELSTOREIPROC)(GLenum, GLint); -typedef void (APIENTRY *PFNGLPIXELZOOMPROC)(GLfloat, GLfloat); -typedef void (APIENTRY *PFNGLPOLYGONMODEPROC)(GLenum, GLenum); typedef void (APIENTRY *PFNGLPOLYGONOFFSETPROC)(GLfloat, GLfloat); -typedef void (APIENTRY *PFNGLPOPATTRIBPROC)(void); -typedef void (APIENTRY *PFNGLPOPCLIENTATTRIBPROC)(void); -typedef void (APIENTRY *PFNGLPOPMATRIXPROC)(void); -typedef void (APIENTRY *PFNGLPUSHATTRIBPROC)(GLbitfield); -typedef void (APIENTRY *PFNGLPUSHCLIENTATTRIBPROC)(GLbitfield); -typedef void (APIENTRY *PFNGLPUSHMATRIXPROC)(void); -typedef void (APIENTRY *PFNGLRASTERPOS2IPROC)(GLint, GLint); -typedef void (APIENTRY *PFNGLREADBUFFERPROC)(GLenum); typedef void (APIENTRY *PFNGLREADPIXELSPROC)(GLint, GLint, GLsizei, GLsizei, GLenum, GLenum, GLvoid *); -typedef void (APIENTRY *PFNGLROTATEFPROC)(GLfloat, GLfloat, GLfloat, GLfloat); -typedef void (APIENTRY *PFNGLSCALEFPROC)(GLfloat,GLfloat,GLfloat); typedef void (APIENTRY *PFNGLSHADEMODELPROC)(GLenum); -typedef void (APIENTRY *PFNGLTEXCOORD2FPROC)(GLfloat, GLfloat); -typedef void (APIENTRY *PFNGLTEXCOORD2FVPROC)(const GLfloat *); -typedef void (APIENTRY *PFNGLTEXCOORD3FPROC)(GLfloat, GLfloat, GLfloat); -typedef void (APIENTRY *PFNGLTEXCOORD3FVPROC)(const GLfloat *); -typedef void (APIENTRY *PFNGLTEXCOORD4FPROC)(GLfloat, GLfloat, GLfloat); -typedef void (APIENTRY *PFNGLTEXCOORD4FVPROC)(const GLfloat *); typedef void (APIENTRY *PFNGLTEXCOORDPOINTERPROC)(GLint, GLenum, GLsizei, const GLvoid *); typedef void (APIENTRY *PFNGLTEXENVFPROC)(GLenum, GLenum, GLfloat); typedef void (APIENTRY *PFNGLTEXENVFVPROC)(GLenum, GLenum, const GLfloat *); @@ -84,60 +62,15 @@ typedef void (APIENTRY *PFNGLTEXIMAGE2DPROC)(GLenum,GLint,GLint,GLsizei,GLsizei, typedef void (APIENTRY *PFNGLTEXPARAMETERFPROC)(GLenum, GLenum, GLfloat); typedef void (APIENTRY *PFNGLTEXPARAMETERIPROC)(GLenum, GLenum, GLint); typedef void (APIENTRY *PFNGLTEXSUBIMAGE2DPROC)(GLenum,GLint,GLint,GLint,GLsizei,GLsizei,GLenum,GLenum,const GLvoid*); -typedef void (APIENTRY *PFNGLTRANSLATEFPROC)(GLfloat, GLfloat, GLfloat); -typedef void (APIENTRY *PFNGLVERTEX2FPROC)(GLfloat, GLfloat); -typedef void (APIENTRY *PFNGLVERTEX2FVPROC)(const GLfloat *); -typedef void (APIENTRY *PFNGLVERTEX3FPROC)(GLfloat, GLfloat, GLfloat); -typedef void (APIENTRY *PFNGLVERTEX3FVPROC)(const GLfloat *); -typedef void (APIENTRY *PFNGLVERTEX4FPROC)(GLfloat, GLfloat, GLfloat, GLfloat); -typedef void (APIENTRY *PFNGLVERTEX4FVPROC)(const GLfloat *); typedef void (APIENTRY *PFNGLVERTEXPOINTERPROC)(GLint, GLenum, GLsizei, const GLvoid *); typedef void (APIENTRY *PFNGLVIEWPORTPROC)(GLint, GLint, GLsizei, GLsizei); -/* -typedef void (APIENTRY * PFNGLCOLORTABLEEXTPROC) (GLenum target, GLenum internalFormat, GLsizei width, GLenum format, GLenum type, const GLvoid *table); -typedef void (APIENTRY * PFNGLGETCOLORTABLEEXTPROC) (GLenum target, GLenum format, GLenum type, GLvoid *data); -typedef void (APIENTRY * PFNGLGETCOLORTABLEPARAMETERIVEXTPROC) (GLenum target, GLenum pname, GLint *params); -typedef void (APIENTRY * PFNGLGETCOLORTABLEPARAMETERFVEXTPROC) (GLenum target, GLenum pname, GLfloat *params); -*/ - -#if defined(_MSC_VER) -typedef void (APIENTRY * PFNGLSECONDARYCOLOR3BEXTPROC) (GLbyte red, GLbyte green, GLbyte blue); -typedef void (APIENTRY * PFNGLSECONDARYCOLOR3BVEXTPROC) (const GLbyte *v); -typedef void (APIENTRY * PFNGLSECONDARYCOLOR3DEXTPROC) (GLdouble red, GLdouble green, GLdouble blue); -typedef void (APIENTRY * PFNGLSECONDARYCOLOR3DVEXTPROC) (const GLdouble *v); -typedef void (APIENTRY * PFNGLSECONDARYCOLOR3FEXTPROC) (GLfloat red, GLfloat green, GLfloat blue); -typedef void (APIENTRY * PFNGLSECONDARYCOLOR3FVEXTPROC) (const GLfloat *v); -typedef void (APIENTRY * PFNGLSECONDARYCOLOR3IEXTPROC) (GLint red, GLint green, GLint blue); -typedef void (APIENTRY * PFNGLSECONDARYCOLOR3IVEXTPROC) (const GLint *v); -typedef void (APIENTRY * PFNGLSECONDARYCOLOR3SEXTPROC) (GLshort red, GLshort green, GLshort blue); -typedef void (APIENTRY * PFNGLSECONDARYCOLOR3SVEXTPROC) (const GLshort *v); -typedef void (APIENTRY * PFNGLSECONDARYCOLOR3UBEXTPROC) (GLubyte red, GLubyte green, GLubyte blue); -typedef void (APIENTRY * PFNGLSECONDARYCOLOR3UBVEXTPROC) (const GLubyte *v); -typedef void (APIENTRY * PFNGLSECONDARYCOLOR3UIEXTPROC) (GLuint red, GLuint green, GLuint blue); -typedef void (APIENTRY * PFNGLSECONDARYCOLOR3UIVEXTPROC) (const GLuint *v); -typedef void (APIENTRY * PFNGLSECONDARYCOLOR3USEXTPROC) (GLushort red, GLushort green, GLushort blue); -typedef void (APIENTRY * PFNGLSECONDARYCOLOR3USVEXTPROC) (const GLushort *v); -typedef void (APIENTRY * PFNGLSECONDARYCOLORPOINTEREXTPROC) (GLint size, GLenum type, GLsizei stride, const GLvoid *pointer); -#endif - -typedef void (APIENTRY *PFNGLXSWAPINTERVALSGIPROC)(int interval); - extern PFNGLALPHAFUNCPROC pglAlphaFunc; -extern PFNGLARRAYELEMENTPROC pglArrayElement; -extern PFNGLBEGINPROC pglBegin; extern PFNGLBINDTEXTUREPROC pglBindTexture; extern PFNGLBLENDFUNCPROC pglBlendFunc; extern PFNGLCLEARPROC pglClear; extern PFNGLCLEARCOLORPROC pglClearColor; -extern PFNGLCOLOR3FPROC pglColor3f; -extern PFNGLCOLOR3FVPROC pglColor3fv; -extern PFNGLCOLOR3UBPROC pglColor3ub; -extern PFNGLCOLOR3UBVPROC pglColor3ubv; extern PFNGLCOLOR4FPROC pglColor4f; -extern PFNGLCOLOR4FVPROC pglColor4fv; -extern PFNGLCOLOR4UBPROC pglColor4ub; -extern PFNGLCOLOR4UBVPROC pglColor4ubv; extern PFNGLCOLORPOINTERPROC pglColorPointer; extern PFNGLCULLFACEPROC pglCullFace; extern PFNGLDELETETEXTURESPROC pglDeleteTextures; @@ -146,15 +79,10 @@ extern PFNGLDEPTHMASKPROC pglDepthMask; extern PFNGLDEPTHRANGEPROC pglDepthRange; extern PFNGLDISABLEPROC pglDisable; extern PFNGLDISABLECLIENTSTATEPROC pglDisableClientState; -extern PFNGLDRAWBUFFERPROC pglDrawBuffer; extern PFNGLDRAWELEMENTSPROC pglDrawElements; -extern PFNGLDRAWPIXELSPROC pglDrawPixels; -extern PFNGLDRAWRANGEELEMENTSPROC pglDrawRangeElements; extern PFNGLENABLEPROC pglEnable; extern PFNGLENABLECLIENTSTATEPROC pglEnableClientState; -extern PFNGLENDPROC pglEnd; extern PFNGLFRONTFACEPROC pglFrontFace; -extern PFNGLFRUSTUMPROC pglFrustum; extern PFNGLGENTEXTURESPROC pglGenTextures; extern PFNGLGETERRORPROC pglGetError; extern PFNGLGETFLOATVPROC pglGetFloatv; @@ -162,34 +90,10 @@ extern PFNGLGETINTEGERVPROC pglGetIntegerv; extern PFNGLGETSTRINGPROC pglGetString; extern PFNGLGETTEXPARAMETERFVPROC pglGetTexParameterfv; extern PFNGLHINTPROC pglHint; -extern PFNGLLOADIDENTITYPROC pglLoadIdentity; -extern PFNGLLOADMATRIXFPROC pglLoadMatrixf; -extern PFNGLMATRIXMODEPROC pglMatrixMode; -extern PFNGLMULTMATRIXFPROC pglMultMatrixf; -extern PFNGLNORMALPOINTERPROC pglNormalPointer; -extern PFNGLORTHOPROC pglOrtho; extern PFNGLPIXELSTOREIPROC pglPixelStorei; -extern PFNGLPIXELZOOMPROC pglPixelZoom; -extern PFNGLPOLYGONMODEPROC pglPolygonMode; extern PFNGLPOLYGONOFFSETPROC pglPolygonOffset; -extern PFNGLPOPATTRIBPROC pglPopAttrib; -extern PFNGLPOPCLIENTATTRIBPROC pglPopClientAttrib; -extern PFNGLPOPMATRIXPROC pglPopMatrix; -extern PFNGLPUSHATTRIBPROC pglPushAttrib; -extern PFNGLPUSHCLIENTATTRIBPROC pglPushClientAttrib; -extern PFNGLPUSHMATRIXPROC pglPushMatrix; -extern PFNGLRASTERPOS2IPROC pglRasterPos2i; -extern PFNGLREADBUFFERPROC pglReadBuffer; extern PFNGLREADPIXELSPROC pglReadPixels; -extern PFNGLROTATEFPROC pglRotatef; -extern PFNGLSCALEFPROC pglScalef; extern PFNGLSHADEMODELPROC pglShadeModel; -extern PFNGLTEXCOORD2FPROC pglTexCoord2f; -extern PFNGLTEXCOORD2FVPROC pglTexCoord2fv; -extern PFNGLTEXCOORD3FPROC pglTexCoord3f; -extern PFNGLTEXCOORD3FVPROC pglTexCoord3fv; -extern PFNGLTEXCOORD4FPROC pglTexCoord4f; -extern PFNGLTEXCOORD4FVPROC pglTexCoord4fv; extern PFNGLTEXCOORDPOINTERPROC pglTexCoordPointer; extern PFNGLTEXENVFPROC pglTexEnvf; extern PFNGLTEXENVFVPROC pglTexEnvfv; @@ -198,38 +102,18 @@ extern PFNGLTEXIMAGE2DPROC pglTexImage2D; extern PFNGLTEXPARAMETERFPROC pglTexParameterf; extern PFNGLTEXPARAMETERIPROC pglTexParameteri; extern PFNGLTEXSUBIMAGE2DPROC pglTexSubImage2D; -extern PFNGLTRANSLATEFPROC pglTranslatef; -extern PFNGLVERTEX2FPROC pglVertex2f; -extern PFNGLVERTEX2FVPROC pglVertex2fv; -extern PFNGLVERTEX3FPROC pglVertex3f; -extern PFNGLVERTEX3FVPROC pglVertex3fv; -extern PFNGLVERTEX4FPROC pglVertex4f; -extern PFNGLVERTEX4FVPROC pglVertex4fv; extern PFNGLVERTEXPOINTERPROC pglVertexPointer; extern PFNGLVIEWPORTPROC pglViewport; -// GL_EXT_paletted_texture -extern PFNGLCOLORTABLEEXTPROC pglColorTableEXT; -extern PFNGLGETCOLORTABLEPARAMETERIVEXTPROC pglGetColorTableParameterivEXT; - -// GL_EXT_secondary_color -extern PFNGLSECONDARYCOLOR3FEXTPROC pglSecondaryColor3fEXT; -extern PFNGLSECONDARYCOLOR3FVEXTPROC pglSecondaryColor3fvEXT; -extern PFNGLSECONDARYCOLOR3UBEXTPROC pglSecondaryColor3ubEXT; -extern PFNGLSECONDARYCOLOR3UBVEXTPROC pglSecondaryColor3ubvEXT; -extern PFNGLSECONDARYCOLORPOINTEREXTPROC pglSecondaryColorPointerEXT; - extern int ogl_have_multisample_filter_hint; -extern int ogl_have_paletted_texture; -extern int ogl_have_secondary_color; extern int ogl_have_texture_filter_anisotropic; extern int ogl_use_multisample_filter_hint; -extern int ogl_use_paletted_texture; -extern int ogl_use_secondary_color; extern int ogl_use_texture_filter_anisotropic; extern void load_ogl_functions(int mode); -extern int check_for_errors(const char *file, int line); + +extern int check_for_errors_(const char *file, int line); +#define check_for_errors() check_for_errors_(__FILE__, __LINE__) #endif diff --git a/src/opengl.c b/src/opengl.c index 15195cd..4326fc0 100644 --- a/src/opengl.c +++ b/src/opengl.c @@ -49,18 +49,28 @@ static D3DTexture *CurrTextureHandle; static enum TRANSLUCENCY_TYPE CurrentTranslucencyMode = TRANSLUCENCY_OFF; static enum FILTERING_MODE_ID CurrentFilteringMode = FILTERING_BILINEAR_OFF; +static GLenum TextureMinFilter = GL_LINEAR_MIPMAP_LINEAR; static D3DTexture *CurrentlyBoundTexture = NULL; +#if defined(_MSC_VER) +#define ALIGN16 __declspec(align(16)) +#else +#define ALIGN16 __attribute__((__aligned__(16))) +#endif + +// need to look into this again at some point +// everything but the hud rendering used an offset +#define TEXCOORD_FIXED(s, r) (((float)((s)+(0<<15))) * (r)) + #define TA_MAXVERTICES 2048 #define TA_MAXTRIANGLES 2048 typedef struct VertexArray { GLfloat v[4]; - - GLfloat t[3]; /* 3rd float is padding */ - + GLfloat t[2]; GLubyte c[4]; + GLubyte s[4]; } VertexArray; typedef struct TriangleArray @@ -70,19 +80,19 @@ typedef struct TriangleArray unsigned short c; } TriangleArray; -static VertexArray varr[TA_MAXVERTICES*2]; -static TriangleArray tarr[TA_MAXTRIANGLES*2]; +static ALIGN16 VertexArray varr[TA_MAXVERTICES]; +static ALIGN16 TriangleArray tarr[TA_MAXTRIANGLES]; static VertexArray *varrp = varr; static TriangleArray *tarrp = tarr; static int varrc, tarrc; -static VertexArray *svarr = &varr[TA_MAXVERTICES], *svarrp = &varr[TA_MAXVERTICES]; -static TriangleArray *starr = &tarr[TA_MAXTRIANGLES], *starrp = &tarr[TA_MAXTRIANGLES]; -static int svarrc, starrc; +static ALIGN16 TriangleArray starr[TA_MAXTRIANGLES]; +static TriangleArray *starrp = starr; +static int starrc; /* Do not call this directly! */ static void SetTranslucencyMode(enum TRANSLUCENCY_TYPE mode) -{ +{ pglDisable(GL_ALPHA_TEST); switch(mode) { @@ -90,7 +100,9 @@ static void SetTranslucencyMode(enum TRANSLUCENCY_TYPE mode) if (TRIPTASTIC_CHEATMODE||MOTIONBLUR_CHEATMODE) { pglBlendFunc(GL_ONE_MINUS_SRC_ALPHA, GL_SRC_ALPHA); } else { + // alien tail hack pglEnable(GL_ALPHA_TEST); + pglBlendFunc(GL_ONE, GL_ZERO); } break; @@ -113,8 +125,48 @@ static void SetTranslucencyMode(enum TRANSLUCENCY_TYPE mode) pglBlendFunc(GL_ZERO, GL_ONE); break; default: - fprintf(stderr, "RenderPolygon.TranslucencyMode: invalid %d\n", RenderPolygon.TranslucencyMode); - return; + fprintf(stderr, "SetTranslucencyMode: invalid blend mode %d\n", mode); + break; + } +} + +static void SetSecondPassTranslucencyMode(enum TRANSLUCENCY_TYPE mode) +{ + pglDisable(GL_ALPHA_TEST); + + switch(mode) { + case TRANSLUCENCY_OFF: + if (TRIPTASTIC_CHEATMODE||MOTIONBLUR_CHEATMODE) { + pglBlendFunc(GL_ONE_MINUS_SRC_ALPHA, GL_ONE); + } else { + pglBlendFunc(GL_ONE, GL_ONE); + } + break; + case TRANSLUCENCY_NORMAL: + pglBlendFunc(GL_SRC_ALPHA, GL_ONE); + break; + case TRANSLUCENCY_GLOWING: + pglBlendFunc(GL_SRC_ALPHA, GL_ONE); + break; + case TRANSLUCENCY_COLOUR: + //fprintf(stderr, "SetSecondPassTranslucencyMode: unsupported blend mode %d\n", mode); + // can't easily emulate this one + pglBlendFunc(GL_DST_COLOR, GL_ONE); + break; + case TRANSLUCENCY_INVCOLOUR: + //fprintf(stderr, "SetSecondPassTranslucencyMode: unsupported blend mode %d\n", mode); + // can't easily emulate this one + pglBlendFunc(GL_ONE_MINUS_DST_COLOR, GL_ONE); + break; + + case TRANSLUCENCY_DARKENINGCOLOUR: + case TRANSLUCENCY_JUSTSETZ: + fprintf(stderr, "SetSecondPassTranslucencyMode: unsupported blend mode %d\n", mode); + pglBlendFunc(GL_SRC_ALPHA, GL_ONE); + break; + default: + fprintf(stderr, "SetSecondPassTranslucencyMode: invalid blend mode %d\n", mode); + break; } } @@ -131,10 +183,12 @@ void InitOpenGL() pglHint( GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST ); pglHint( GL_GENERATE_MIPMAP_HINT, GL_NICEST ); +#if GL_NV_multisample_filter_hint if ( ogl_use_multisample_filter_hint ) { pglHint( GL_MULTISAMPLE_FILTER_HINT_NV, GL_NICEST ); } +#endif CurrentTranslucencyMode = TRANSLUCENCY_OFF; pglBlendFunc(GL_ONE, GL_ZERO); @@ -157,17 +211,6 @@ void InitOpenGL() pglEnableClientState(GL_COLOR_ARRAY); pglColorPointer(4, GL_UNSIGNED_BYTE, sizeof(varr[0]), varr[0].c); -#if 0 -#if GL_EXT_secondary_color - if (ogl_use_secondary_color) { - pglEnableClientState(GL_SEPARATE_COLOR_ARRAY_EXT); - pglSecondaryColorPointerEXT(4, GL_UNSIGNED_BYTE, sizeof(svarr[0]), svarr[0].c); - } else { - pglDisableClientState(GL_SEPARATE_COLOR_ARRAY_EXT); - } -#endif -#endif - tarrc = 0; tarrp = tarr; @@ -176,9 +219,6 @@ void InitOpenGL() starrc = 0; starrp = starr; - - svarrc = 0; - svarrp = svarr; } static void FlushTriangleBuffers(int backup) @@ -194,42 +234,55 @@ static void FlushTriangleBuffers(int backup) } if (starrc) { - if (CurrentlyBoundTexture != NULL) { - if (!backup) CurrentlyBoundTexture = NULL; - pglBindTexture(GL_TEXTURE_2D, 0); - } + //if (CurrentlyBoundTexture != NULL) { + // if (!backup) CurrentlyBoundTexture = NULL; + // pglBindTexture(GL_TEXTURE_2D, 0); + //} - if (CurrentTranslucencyMode != TRANSLUCENCY_GLOWING) { - if (!backup) CurrentTranslucencyMode = TRANSLUCENCY_GLOWING; - SetTranslucencyMode(TRANSLUCENCY_GLOWING); - //if (CurrentTranslucencyMode == TRANSLUCENCY_OFF) - // pglEnable(GL_BLEND); - //glBlendFunc(GL_SRC_ALPHA, GL_ONE); - } + //if (CurrentTranslucencyMode != TRANSLUCENCY_GLOWING) { + // if (!backup) CurrentTranslucencyMode = TRANSLUCENCY_GLOWING; + // SetTranslucencyMode(TRANSLUCENCY_GLOWING); + // //if (CurrentTranslucencyMode == TRANSLUCENCY_OFF) + // // pglEnable(GL_BLEND); + // //glBlendFunc(GL_SRC_ALPHA, GL_ONE); + //} - pglDisableClientState(GL_TEXTURE_COORD_ARRAY); + SetSecondPassTranslucencyMode(CurrentTranslucencyMode); + + pglTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE); + pglTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_REPLACE); + pglTexEnvi(GL_TEXTURE_ENV, GL_SRC0_RGB, GL_PRIMARY_COLOR); + pglTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB, GL_SRC_COLOR); + pglTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_MODULATE); + pglTexEnvi(GL_TEXTURE_ENV, GL_SRC0_ALPHA, GL_TEXTURE); + pglTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA, GL_SRC_ALPHA); + pglTexEnvi(GL_TEXTURE_ENV, GL_SRC1_ALPHA, GL_PRIMARY_COLOR); + pglTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_ALPHA, GL_SRC_ALPHA); + + //pglDisableClientState(GL_TEXTURE_COORD_ARRAY); + pglColorPointer(4, GL_UNSIGNED_BYTE, sizeof(varr[0]), varr[0].s); pglDrawElements(GL_TRIANGLES, starrc*3, GL_UNSIGNED_SHORT, starr); + + //pglEnableClientState(GL_TEXTURE_COORD_ARRAY); + pglColorPointer(4, GL_UNSIGNED_BYTE, sizeof(varr[0]), varr[0].c); - pglEnableClientState(GL_TEXTURE_COORD_ARRAY); - - if (backup) { - if (CurrentlyBoundTexture) - pglBindTexture(GL_TEXTURE_2D, CurrentlyBoundTexture->id); - if (CurrentTranslucencyMode != TRANSLUCENCY_GLOWING) - SetTranslucencyMode(CurrentTranslucencyMode); - } else { - CurrentlyBoundTexture = NULL; - CurrentTranslucencyMode = TRANSLUCENCY_GLOWING; - } + //if (backup) { + // //if (CurrentlyBoundTexture) + // // pglBindTexture(GL_TEXTURE_2D, CurrentlyBoundTexture->id); + // if (CurrentTranslucencyMode != TRANSLUCENCY_GLOWING) + // SetTranslucencyMode(CurrentTranslucencyMode); + //} else { + // //CurrentlyBoundTexture = NULL; + // CurrentTranslucencyMode = TRANSLUCENCY_GLOWING; + //} + + SetTranslucencyMode(CurrentTranslucencyMode); + pglTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); starrc = 0; starrp = starr; - - svarrc = 0; - svarrp = svarr; - } - + } } static void CheckBoundTextureIsCorrect(D3DTexture *tex) @@ -257,7 +310,7 @@ static void CheckBoundTextureIsCorrect(D3DTexture *tex) break; case FILTERING_BILINEAR_ON: pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, TextureMinFilter); break; default: break; @@ -283,7 +336,7 @@ static void CheckFilteringModeIsCorrect(enum FILTERING_MODE_ID filter) break; case FILTERING_BILINEAR_ON: pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, TextureMinFilter); break; default: break; @@ -309,16 +362,10 @@ static void CheckTriangleBuffer(int rver, int sver, int rtri, int stri, D3DTextu { if ((rver+varrc) >= TA_MAXVERTICES) { FlushTriangleBuffers(0); - } else if ((sver+svarrc) >= TA_MAXVERTICES) { - FlushTriangleBuffers(0); } else if (rtri == 0 && ((rver-2+tarrc) >= TA_MAXTRIANGLES)) { FlushTriangleBuffers(0); } else if (rtri && ((rtri+tarrc) >= TA_MAXTRIANGLES)) { FlushTriangleBuffers(0); - } else if (stri == 0 && ((sver-2+starrc) >= TA_MAXTRIANGLES)) { - FlushTriangleBuffers(0); - } else if (stri && ((stri+starrc) >= TA_MAXTRIANGLES)) { - FlushTriangleBuffers(0); } if ((intptr_t)tex != -1) @@ -359,7 +406,7 @@ static void CheckTriangleBuffer(int rver, int sver, int rtri, int stri, D3DTextu OUTPUT_TRIANGLE(0, 3, 4); case 4: OUTPUT_TRIANGLE(0, 2, 3); - OUTPUT_TRIANGLE(0, 1, 2); + OUTPUT_TRIANGLE(0, 1, 2); break; default: fprintf(stderr, "DrawTriangles_T2F_C4UB_V4F: vertices = %d\n", rver); @@ -369,9 +416,9 @@ static void CheckTriangleBuffer(int rver, int sver, int rtri, int stri, D3DTextu #define OUTPUT_TRIANGLE(x, y, z) \ { \ - starrp->a = TA_MAXVERTICES+svarrc+(x); \ - starrp->b = TA_MAXVERTICES+svarrc+(y); \ - starrp->c = TA_MAXVERTICES+svarrc+(z); \ + starrp->a = varrc+(x); \ + starrp->b = varrc+(y); \ + starrp->c = varrc+(z); \ \ starrp++; \ starrc++; \ @@ -404,61 +451,108 @@ static void CheckTriangleBuffer(int rver, int sver, int rtri, int stri, D3DTextu } } #undef OUTPUT_TRIANGLE - } -static void SelectPolygonBeginType(int points) -{ - if (tarrc || starrc) - FlushTriangleBuffers(1); - - switch(points) { - case 3: - pglBegin(GL_TRIANGLES); - break; - case 4: - case 5: - case 6: - case 7: - case 8: - pglBegin(GL_TRIANGLE_FAN); - break; - default: - fprintf(stderr, "SelectPolygonBeginType: points = %d\n", points); - break; - } +static unsigned int PowerOfTwo(unsigned int v) { + v--; + v |= v >> 1; + v |= v >> 2; + v |= v >> 4; + v |= v >> 8; + v |= v >> 16; + return v + 1; } GLuint CreateOGLTexture(D3DTexture *tex, unsigned char *buf) { + if (buf == NULL) { + // converting DDSurface to D3DTexture + buf = tex->buf; + } + if (buf == NULL) { + fprintf(stderr, "CreateOGLTexture - null buffer\n"); + return 0; + } + + int i; + int l = tex->w * tex->h; + for (i = 0; i < l; i++) { + int o = i*4; + int r = buf[o+0]; + int g = buf[o+1]; + int b = buf[o+2]; + int a = buf[o+3]; + + // kinda pre-multiplied alpha; + // texels with zero alpha shouldn't + // be visible. + if (a == 0) { + r = 0; + g = 0; + b = 0; + } + + buf[o+0] = r; + buf[o+1] = g; + buf[o+2] = b; + buf[o+3] = a; + } + + tex->TexWidth = tex->w; + tex->TexHeight = tex->h; + + int PotWidth = PowerOfTwo(tex->TexWidth); + int PotHeight = PowerOfTwo(tex->TexHeight); + tex->IsNpot = (PotWidth != tex->TexWidth) || (PotHeight != tex->TexHeight); + GLuint h; GLfloat max_anisotropy; FlushTriangleBuffers(1); - + pglGenTextures(1, &h); pglBindTexture(GL_TEXTURE_2D, h); pglTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, GL_TRUE); - + pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); - - pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); - - pglTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tex->w, tex->h, 0, GL_RGBA, GL_UNSIGNED_BYTE, buf); - + + if (tex->IsNpot) { + // OpenGL 1.x compatibility + tex->TexWidth = PotWidth; + tex->TexHeight = PotHeight; + + pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + + pglTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tex->TexWidth, tex->TexHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); + pglTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, tex->w, tex->h, GL_RGBA, GL_UNSIGNED_BYTE, buf); + } else { + pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + + if (tex->IsNpot) { + pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + } else { + pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, TextureMinFilter); + } + + pglTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tex->w, tex->h, 0, GL_RGBA, GL_UNSIGNED_BYTE, buf); + } + pglTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); - + + tex->buf = NULL; tex->id = h; tex->filter = FILTERING_BILINEAR_ON; + tex->RecipW = 1.0f / (float) tex->TexWidth; + tex->RecipH = 1.0f / (float) tex->TexHeight; if ( ogl_use_texture_filter_anisotropic ) { - pglGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &max_anisotropy); - pglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, max_anisotropy); - } + pglGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &max_anisotropy); + pglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, max_anisotropy); + } if ( CurrentlyBoundTexture != NULL ) { @@ -466,6 +560,8 @@ GLuint CreateOGLTexture(D3DTexture *tex, unsigned char *buf) pglBindTexture(GL_TEXTURE_2D, CurrentlyBoundTexture->id); } + free(buf); + return h; } @@ -473,11 +569,36 @@ void ReleaseD3DTexture(void *tex) { D3DTexture *TextureHandle = (D3DTexture *)tex; - pglDeleteTextures(1, (GLuint*) &(TextureHandle->id)); + if (TextureHandle == NULL) { + return; + } + + if (TextureHandle->id != 0) { + pglDeleteTextures(1, (GLuint*) &(TextureHandle->id)); + TextureHandle->id = 0; + } + + if (TextureHandle->buf != NULL) { + free(TextureHandle->buf); + TextureHandle->buf = NULL; + } free(TextureHandle); } +int CreateIMGSurface(D3DTexture *tex, unsigned char *buf) +{ + tex->buf = buf; + tex->id = 0; + + return 0; +} + +void ReleaseDDSurface(void* DDSurface) +{ + ReleaseD3DTexture(DDSurface); +} + /* ** */ void ThisFramesRenderingHasBegun() @@ -534,14 +655,12 @@ void D3D_DecalSystem_End() void D3D_Rectangle(int x0, int y0, int x1, int y1, int r, int g, int b, int a) { GLfloat x[4], y[4]; - + int i; + if (y1 <= y0) return; - - CheckTranslucencyModeIsCorrect(TRANSLUCENCY_GLOWING); - CheckBoundTextureIsCorrect(NULL); - - pglColor4ub(r, g, b, a); + + CheckTriangleBuffer(4, 0, 0, 0, NULL, TRANSLUCENCY_GLOWING, -1); x[0] = x0; x[0] = (x[0] - ScreenDescriptorBlock.SDB_CentreX)/ScreenDescriptorBlock.SDB_CentreX; @@ -563,17 +682,28 @@ void D3D_Rectangle(int x0, int y0, int x1, int y1, int r, int g, int b, int a) y[3] = y1 - 1; y[3] = -(y[3] - ScreenDescriptorBlock.SDB_CentreY)/ScreenDescriptorBlock.SDB_CentreY; - SelectPolygonBeginType(3); /* triangles */ - - pglVertex3f(x[0], y[0], -1.0f); - pglVertex3f(x[1], y[1], -1.0f); - pglVertex3f(x[3], y[3], -1.0f); - - pglVertex3f(x[1], y[1], -1.0f); - pglVertex3f(x[2], y[2], -1.0f); - pglVertex3f(x[3], y[3], -1.0f); - - pglEnd(); + for (i = 0; i < 4; i++) { + varrp->v[0] = x[i]; + varrp->v[1] = y[i]; + varrp->v[2] = -1.0f; + varrp->v[3] = 1.0f; + + varrp->t[0] = 0.0f; + varrp->t[1] = 0.0f; + + varrp->c[0] = r; + varrp->c[1] = g; + varrp->c[2] = b; + varrp->c[3] = a; + + varrp->s[0] = 0; + varrp->s[1] = 0; + varrp->s[2] = 0; + varrp->s[3] = 0; + + varrp++; + varrc++; + } } /* ** */ @@ -597,19 +727,9 @@ void D3D_ZBufferedGouraudTexturedPolygon_Output(POLYHEADER *inputPolyPtr, RENDER TextureHandle = CurrTextureHandle; } - if (TextureHandle->w == 128) { - RecipW = (1.0f / 128.0f) / 65536.0f; - } else { - float width = TextureHandle->w; - RecipW = (1.0f / width) / 65536.0f; - } - if (TextureHandle->h == 128) { - RecipH = (1.0f / 128.0f) / 65536.0f; - } else { - float height = TextureHandle->h; - RecipH = (1.0f / height) / 65536.0f; - } - + RecipW = TextureHandle->RecipW / 65536.0f; + RecipH = TextureHandle->RecipH / 65536.0f; + CheckTriangleBuffer(RenderPolygon.NumberOfVertices, RenderPolygon.NumberOfVertices, 0, 0, TextureHandle, RenderPolygon.TranslucencyMode, -1); for (i = 0; i < RenderPolygon.NumberOfVertices; i++) { @@ -619,8 +739,8 @@ void D3D_ZBufferedGouraudTexturedPolygon_Output(POLYHEADER *inputPolyPtr, RENDER GLfloat w = (float)vertices->Z; GLfloat zvalue; - s = ((float)vertices->U) * RecipW + (1.0f/256.0f); - t = ((float)vertices->V) * RecipH + (1.0f/256.0f); + s = TEXCOORD_FIXED(vertices->U, RecipW); + t = TEXCOORD_FIXED(vertices->V, RecipH); x = ((float)vertices->X*((float)Global_VDB_Ptr->VDB_ProjX+1.0f))/((float)vertices->Z*(float)ScreenDescriptorBlock.SDB_CentreX); y = -((float)vertices->Y*((float)Global_VDB_Ptr->VDB_ProjY+1.0f))/((float)vertices->Z*(float)ScreenDescriptorBlock.SDB_CentreY); @@ -628,28 +748,26 @@ void D3D_ZBufferedGouraudTexturedPolygon_Output(POLYHEADER *inputPolyPtr, RENDER zvalue = vertices->Z+HeadUpDisplayZOffset; z = 1.0f - 2.0f*ZNear/zvalue; - varrp->v[0] = svarrp->v[0] = x*w; - varrp->v[1] = svarrp->v[1] = y*w; - varrp->v[2] = svarrp->v[2] = z*w; - varrp->v[3] = svarrp->v[3] = w; + varrp->v[0] = x*w; + varrp->v[1] = y*w; + varrp->v[2] = z*w; + varrp->v[3] = w; - varrp->t[0] = /**/ svarrp->t[0] = /**/ s; - varrp->t[1] = /**/ svarrp->t[1] = /**/ t; + varrp->t[0] = s; + varrp->t[1] = t; varrp->c[0] = GammaValues[vertices->R]; varrp->c[1] = GammaValues[vertices->G]; varrp->c[2] = GammaValues[vertices->B]; varrp->c[3] = vertices->A; - svarrp->c[0] = GammaValues[vertices->SpecularR]; - svarrp->c[1] = GammaValues[vertices->SpecularG]; - svarrp->c[2] = GammaValues[vertices->SpecularB]; - svarrp->c[3] = 255; + varrp->s[0] = GammaValues[vertices->SpecularR]; + varrp->s[1] = GammaValues[vertices->SpecularG]; + varrp->s[2] = GammaValues[vertices->SpecularB]; + varrp->s[3] = vertices->A; varrp++; varrc++; - svarrp++; - svarrc++; } } @@ -664,18 +782,8 @@ void D3D_SkyPolygon_Output(POLYHEADER *inputPolyPtr, RENDERVERTEX *renderVertice TextureHandle = (void *)ImageHeaderArray[texoffset].D3DTexture; CurrTextureHandle = TextureHandle; - if (TextureHandle->w == 128) { - RecipW = (1.0f / 128.0f) / 65536.0f; - } else { - float width = TextureHandle->w; - RecipW = (1.0f / width) / 65536.0f; - } - if (TextureHandle->h == 128) { - RecipH = (1.0f / 128.0f) / 65536.0f; - } else { - float height = TextureHandle->h; - RecipH = (1.0f / height) / 65536.0f; - } + RecipW = TextureHandle->RecipW / 65536.0f; + RecipH = TextureHandle->RecipH / 65536.0f; CheckTriangleBuffer(RenderPolygon.NumberOfVertices, 0, 0, 0, TextureHandle, RenderPolygon.TranslucencyMode, -1); @@ -687,8 +795,8 @@ void D3D_SkyPolygon_Output(POLYHEADER *inputPolyPtr, RENDERVERTEX *renderVertice w = (float)vertices->Z; - s = ((float)vertices->U) * RecipW + (1.0f/256.0f); - t = ((float)vertices->V) * RecipH + (1.0f/256.0f); + s = TEXCOORD_FIXED(vertices->U, RecipW); + t = TEXCOORD_FIXED(vertices->V, RecipH); x = ((float)vertices->X*((float)Global_VDB_Ptr->VDB_ProjX+1.0f))/((float)vertices->Z*(float)ScreenDescriptorBlock.SDB_CentreX); y = -((float)vertices->Y*((float)Global_VDB_Ptr->VDB_ProjY+1.0f))/((float)vertices->Z*(float)ScreenDescriptorBlock.SDB_CentreY); @@ -708,6 +816,11 @@ void D3D_SkyPolygon_Output(POLYHEADER *inputPolyPtr, RENDERVERTEX *renderVertice varrp->c[2] = vertices->B; varrp->c[3] = vertices->A; + varrp->s[0] = 0; + varrp->s[1] = 0; + varrp->s[2] = 0; + varrp->s[3] = 0; + varrp++; varrc++; } @@ -731,19 +844,8 @@ void D3D_ZBufferedCloakedPolygon_Output(POLYHEADER *inputPolyPtr, RENDERVERTEX * TextureHandle = ImageHeaderArray[texoffset].D3DTexture; CurrTextureHandle = TextureHandle; - if (TextureHandle->w == 128) { - RecipW = 1.0f / 128.0f; - } else { - float width = (float) TextureHandle->w; - RecipW = 1.0f / width; - } - - if (TextureHandle->h == 128) { - RecipH = 1.0f / 128.0f; - } else { - float height = (float) TextureHandle->h; - RecipH = 1.0f / height; - } + RecipW = TextureHandle->RecipW / 65536.0f; + RecipH = TextureHandle->RecipH / 65536.0f; CheckTriangleBuffer(RenderPolygon.NumberOfVertices, 0, 0, 0, TextureHandle, TRANSLUCENCY_NORMAL, -1); @@ -757,9 +859,9 @@ void D3D_ZBufferedCloakedPolygon_Output(POLYHEADER *inputPolyPtr, RENDERVERTEX * w = (float)vertices->Z; - s = (((float)vertices->U/65536.0f)+0.5) * RecipW; - t = (((float)vertices->V/65536.0f)+0.5) * RecipH; - + s = TEXCOORD_FIXED(vertices->U, RecipW); + t = TEXCOORD_FIXED(vertices->V, RecipH); + x = ((float)vertices->X*((float)Global_VDB_Ptr->VDB_ProjX+1.0f))/((float)vertices->Z*(float)ScreenDescriptorBlock.SDB_CentreX); y = -((float)vertices->Y*((float)Global_VDB_Ptr->VDB_ProjY+1.0f))/((float)vertices->Z*(float)ScreenDescriptorBlock.SDB_CentreY); @@ -778,7 +880,12 @@ void D3D_ZBufferedCloakedPolygon_Output(POLYHEADER *inputPolyPtr, RENDERVERTEX * varrp->c[1] = vertices->G; varrp->c[2] = vertices->B; varrp->c[3] = vertices->A; - + + varrp->s[0] = 0; + varrp->s[1] = 0; + varrp->s[2] = 0; + varrp->s[3] = 0; + varrp++; varrc++; } @@ -811,19 +918,8 @@ void D3D_Decal_Output(DECAL *decalPtr, RENDERVERTEX *renderVerticesPtr) TextureHandle = ImageHeaderArray[texoffset].D3DTexture; - if (TextureHandle->w == 256) { - RecipW = 1.0 / 256.0; - } else { - float width = (float) TextureHandle->w; - RecipW = 1.0 / width; - } - - if (TextureHandle->h == 256) { - RecipH = 1.0 / 256.0; - } else { - float height = (float) TextureHandle->h; - RecipH = 1.0 / height; - } + RecipW = TextureHandle->RecipW / 65536.0f; + RecipH = TextureHandle->RecipH / 65536.0f; } if (decalDescPtr->IsLit) { @@ -861,8 +957,8 @@ void D3D_Decal_Output(DECAL *decalPtr, RENDERVERTEX *renderVerticesPtr) x = ((float)vertices->X*((float)Global_VDB_Ptr->VDB_ProjX+1.0f))/((float)vertices->Z*(float)ScreenDescriptorBlock.SDB_CentreX); y = -((float)vertices->Y*((float)Global_VDB_Ptr->VDB_ProjY+1.0f))/((float)vertices->Z*(float)ScreenDescriptorBlock.SDB_CentreY); - s = ((float)(vertices->U/65536.0f)+0.5f) * RecipW; - t = ((float)(vertices->V/65536.0f)+0.5f) * RecipH; + s = TEXCOORD_FIXED(vertices->U, RecipW); + t = TEXCOORD_FIXED(vertices->V, RecipH); zvalue = vertices->Z+HeadUpDisplayZOffset; z = 1.0f - 2.0f*ZNear/zvalue; @@ -879,7 +975,12 @@ void D3D_Decal_Output(DECAL *decalPtr, RENDERVERTEX *renderVerticesPtr) varrp->c[1] = g; varrp->c[2] = b; varrp->c[3] = a; - + + varrp->s[0] = 0; + varrp->s[1] = 0; + varrp->s[2] = 0; + varrp->s[3] = 0; + varrp++; varrc++; } @@ -901,21 +1002,8 @@ void D3D_Particle_Output(PARTICLE *particlePtr, RENDERVERTEX *renderVerticesPtr) TextureHandle = ImageHeaderArray[texoffset].D3DTexture; - if (TextureHandle->w == 256) { - RecipW = 1.0 / 256.0; - } else { - float width = (float) TextureHandle->w; - - RecipW = (1.0 / width); - } - - if (TextureHandle->h == 256) { - RecipH = 1.0 / 256.0; - } else { - float height = (float) TextureHandle->h; - - RecipH = (1.0 / height); - } + RecipW = TextureHandle->RecipW / 65536.0f; + RecipH = TextureHandle->RecipH / 65536.0f; if (particleDescPtr->IsLit && !(particlePtr->ParticleID==PARTICLE_ALIEN_BLOOD && CurrentVisionMode==VISION_MODE_PRED_SEEALIENS) ) { @@ -956,8 +1044,8 @@ void D3D_Particle_Output(PARTICLE *particlePtr, RENDERVERTEX *renderVerticesPtr) GLfloat s, t; GLfloat w = (float)vertices->Z; - s = ((float)(vertices->U>>16)+.5) * RecipW; - t = ((float)(vertices->V>>16)+.5) * RecipH; + s = TEXCOORD_FIXED(vertices->U, RecipW); + t = TEXCOORD_FIXED(vertices->V, RecipH); x = ((float)vertices->X*((float)Global_VDB_Ptr->VDB_ProjX+1.0f))/((float)vertices->Z*(float)ScreenDescriptorBlock.SDB_CentreX); y = -((float)vertices->Y*((float)Global_VDB_Ptr->VDB_ProjY+1.0f))/((float)vertices->Z*(float)ScreenDescriptorBlock.SDB_CentreY); @@ -982,7 +1070,12 @@ void D3D_Particle_Output(PARTICLE *particlePtr, RENDERVERTEX *renderVerticesPtr) varrp->c[1] = g; varrp->c[2] = b; varrp->c[3] = a; - + + varrp->s[0] = 0; + varrp->s[1] = 0; + varrp->s[2] = 0; + varrp->s[3] = 0; + varrp++; varrc++; } @@ -1020,7 +1113,12 @@ void D3D_PredatorThermalVisionPolygon_Output(POLYHEADER *inputPolyPtr, RENDERVER varrp->c[1] = vertices->G; varrp->c[2] = vertices->B; varrp->c[3] = vertices->A; - + + varrp->s[0] = 0; + varrp->s[1] = 0; + varrp->s[2] = 0; + varrp->s[3] = 0; + varrp++; varrc++; } @@ -1064,6 +1162,11 @@ void D3D_ZBufferedGouraudPolygon_Output(POLYHEADER *inputPolyPtr, RENDERVERTEX * else varrp->c[3] = 255; + varrp->s[0] = 0; + varrp->s[1] = 0; + varrp->s[2] = 0; + varrp->s[3] = 0; + varrp++; varrc++; } @@ -1077,6 +1180,7 @@ void D3D_PlayerOnFireOverlay() float u, v; int r, g, b, a; D3DTexture *TextureHandle; + int i; b = (colour >> 0) & 0xFF; g = (colour >> 8) & 0xFF; @@ -1085,12 +1189,6 @@ void D3D_PlayerOnFireOverlay() TextureHandle = ImageHeaderArray[BurningImageNumber].D3DTexture; - CheckTranslucencyModeIsCorrect(TRANSLUCENCY_GLOWING); - CheckBoundTextureIsCorrect(TextureHandle); - CheckFilteringModeIsCorrect(FILTERING_BILINEAR_ON); - - pglColor4ub(r, g, b, a); - u = (FastRandom()&255)/256.0f; v = (FastRandom()&255)/256.0f; @@ -1111,23 +1209,30 @@ void D3D_PlayerOnFireOverlay() s[3] = u; t[3] = v + 1.0f; - SelectPolygonBeginType(3); /* triangles */ + CheckTriangleBuffer(4, 0, 0, 0, TextureHandle, TRANSLUCENCY_GLOWING, FILTERING_BILINEAR_ON); - pglTexCoord2f(s[0], t[0]); - pglVertex3f(x[0], y[0], -1.0f); - pglTexCoord2f(s[1], t[1]); - pglVertex3f(x[1], y[1], -1.0f); - pglTexCoord2f(s[3], t[3]); - pglVertex3f(x[3], y[3], -1.0f); - - pglTexCoord2f(s[1], t[1]); - pglVertex3f(x[1], y[1], -1.0f); - pglTexCoord2f(s[2], t[2]); - pglVertex3f(x[2], y[2], -1.0f); - pglTexCoord2f(s[3], t[3]); - pglVertex3f(x[3], y[3], -1.0f); - - pglEnd(); + for (i = 0; i < 4; i++) { + varrp->v[0] = x[i]; + varrp->v[1] = y[i]; + varrp->v[2] = -1.0f; + varrp->v[3] = 1.0f; + + varrp->t[0] = s[i]; + varrp->t[1] = t[i]; + + varrp->c[0] = r; + varrp->c[1] = g; + varrp->c[2] = b; + varrp->c[3] = a; + + varrp->s[0] = 0; + varrp->s[1] = 0; + varrp->s[2] = 0; + varrp->s[3] = 0; + + varrp++; + varrc++; + } } void D3D_PlayerDamagedOverlay(int intensity) @@ -1137,7 +1242,8 @@ void D3D_PlayerDamagedOverlay(int intensity) int colour, baseColour; int r, g, b, a; int i; - + int j; + theta[0] = (CloakingPhase/8)&4095; theta[1] = (800-CloakingPhase/8)&4095; @@ -1155,23 +1261,30 @@ void D3D_PlayerDamagedOverlay(int intensity) baseColour = 0x00ff00; break; } - - CheckBoundTextureIsCorrect(TextureHandle); - CheckFilteringModeIsCorrect(FILTERING_BILINEAR_ON); - - colour = 0xffffff - baseColour + (intensity<<24); - - b = (colour >> 0) & 0xFF; - g = (colour >> 8) & 0xFF; - r = (colour >> 16) & 0xFF; - a = (colour >> 24) & 0xFF; - - pglColor4ub(r, g, b, a); - - CheckTranslucencyModeIsCorrect(TRANSLUCENCY_INVCOLOUR); + for (i = 0; i < 2; i++) { GLfloat x[4], y[4], s[4], t[4]; + if (i == 0) { + CheckTriangleBuffer(4, 0, 0, 0, TextureHandle, TRANSLUCENCY_INVCOLOUR, FILTERING_BILINEAR_ON); + + colour = 0xffffff - baseColour + (intensity<<24); + + b = (colour >> 0) & 0xFF; + g = (colour >> 8) & 0xFF; + r = (colour >> 16) & 0xFF; + a = (colour >> 24) & 0xFF; + } else { + CheckTriangleBuffer(4, 0, 0, 0, TextureHandle, TRANSLUCENCY_GLOWING, FILTERING_BILINEAR_ON); + + colour = baseColour + (intensity<<24); + + b = (colour >> 0) & 0xFF; + g = (colour >> 8) & 0xFF; + r = (colour >> 16) & 0xFF; + a = (colour >> 24) & 0xFF; + } + float sin = (GetSin(theta[i]))/65536.0f/16.0f; float cos = (GetCos(theta[i]))/65536.0f/16.0f; @@ -1191,35 +1304,29 @@ void D3D_PlayerDamagedOverlay(int intensity) y[3] = 1.0f; s[3] = 0.875f + (cos*(-1) - sin*(+1)); t[3] = 0.375f + (sin*(-1) + cos*(+1)); - - SelectPolygonBeginType(3); /* triangles */ - - pglTexCoord2f(s[0], t[0]); - pglVertex3f(x[0], y[0], -1.0f); - pglTexCoord2f(s[1], t[1]); - pglVertex3f(x[1], y[1], -1.0f); - pglTexCoord2f(s[3], t[3]); - pglVertex3f(x[3], y[3], -1.0f); - - pglTexCoord2f(s[1], t[1]); - pglVertex3f(x[1], y[1], -1.0f); - pglTexCoord2f(s[2], t[2]); - pglVertex3f(x[2], y[2], -1.0f); - pglTexCoord2f(s[3], t[3]); - pglVertex3f(x[3], y[3], -1.0f); - - pglEnd(); - - colour = baseColour + (intensity<<24); - - b = (colour >> 0) & 0xFF; - g = (colour >> 8) & 0xFF; - r = (colour >> 16) & 0xFF; - a = (colour >> 24) & 0xFF; - - pglColor4ub(r, g, b, a); - - CheckTranslucencyModeIsCorrect(TRANSLUCENCY_GLOWING); + + for (j = 0; j < 4; j++) { + varrp->v[0] = x[j]; + varrp->v[1] = y[j]; + varrp->v[2] = -1.0f; + varrp->v[3] = 1.0f; + + varrp->t[0] = s[j]; + varrp->t[1] = t[j]; + + varrp->c[0] = r; + varrp->c[1] = g; + varrp->c[2] = b; + varrp->c[3] = a; + + varrp->s[0] = 0; + varrp->s[1] = 0; + varrp->s[2] = 0; + varrp->s[3] = 0; + + varrp++; + varrc++; + } } } @@ -1229,23 +1336,19 @@ void DrawNoiseOverlay(int tr) int r, g, b; D3DTexture *tex; int size; - + int j; + r = 255; g = 255; b = 255; - + size = 256; - + tex = ImageHeaderArray[StaticImageNumber].D3DTexture; - - CheckTranslucencyModeIsCorrect(TRANSLUCENCY_GLOWING); - CheckBoundTextureIsCorrect(tex); - CheckFilteringModeIsCorrect(FILTERING_BILINEAR_ON); - pglDepthFunc(GL_ALWAYS); - + u = FastRandom()&255; v = FastRandom()&255; - + x[0] = -1.0f; y[0] = -1.0f; s[0] = u / 256.0f; @@ -1262,26 +1365,36 @@ void DrawNoiseOverlay(int tr) y[3] = 1.0f; s[3] = u / 256.0f; t[3] = (v + size) / 256.0f; - - SelectPolygonBeginType(3); /* triangles */ - pglColor4ub(r, g, b, tr); - - pglTexCoord2f(s[0], t[0]); - pglVertex3f(x[0], y[0], 1.0f); - pglTexCoord2f(s[1], t[1]); - pglVertex3f(x[1], y[1], 1.0f); - pglTexCoord2f(s[3], t[3]); - pglVertex3f(x[3], y[3], 1.0f); - - pglTexCoord2f(s[1], t[1]); - pglVertex3f(x[1], y[1], 1.0f); - pglTexCoord2f(s[2], t[2]); - pglVertex3f(x[2], y[2], 1.0f); - pglTexCoord2f(s[3], t[3]); - pglVertex3f(x[3], y[3], 1.0f); - - pglEnd(); - + + // changing the depth func manually, so flush now + FlushTriangleBuffers(0); + CheckTriangleBuffer(4, 0, 0, 0, tex, TRANSLUCENCY_GLOWING, FILTERING_BILINEAR_ON); + + for (j = 0; j < 4; j++) { + varrp->v[0] = x[j]; + varrp->v[1] = y[j]; + varrp->v[2] = 1.0f; + varrp->v[3] = 1.0f; + + varrp->t[0] = s[j]; + varrp->t[1] = t[j]; + + varrp->c[0] = r; + varrp->c[1] = g; + varrp->c[2] = b; + varrp->c[3] = tr; + + varrp->s[0] = 0; + varrp->s[1] = 0; + varrp->s[2] = 0; + varrp->s[3] = 0; + + varrp++; + varrc++; + } + + pglDepthFunc(GL_ALWAYS); + FlushTriangleBuffers(0); pglDepthFunc(GL_LEQUAL); } @@ -1290,21 +1403,22 @@ void D3D_ScreenInversionOverlay() D3DTexture *tex; int theta[2]; int i; - + int j; + theta[0] = (CloakingPhase/8)&4095; theta[1] = (800-CloakingPhase/8)&4095; tex = ImageHeaderArray[SpecialFXImageNumber].D3DTexture; - - CheckTranslucencyModeIsCorrect(TRANSLUCENCY_DARKENINGCOLOUR); - CheckBoundTextureIsCorrect(tex); - CheckFilteringModeIsCorrect(FILTERING_BILINEAR_ON); - pglColor4f(1.0f, 1.0f, 1.0f, 1.0f); - for (i = 0; i < 2; i++) { GLfloat x[4], y[4], s[4], t[4]; + if (i == 0) { + CheckTriangleBuffer(4, 0, 0, 0, tex, TRANSLUCENCY_DARKENINGCOLOUR, FILTERING_BILINEAR_ON); + } else { + CheckTriangleBuffer(4, 0, 0, 0, tex, TRANSLUCENCY_COLOUR, FILTERING_BILINEAR_ON); + } + float sin = (GetSin(theta[i]))/65536.0f/16.0f; float cos = (GetCos(theta[i]))/65536.0f/16.0f; @@ -1325,47 +1439,82 @@ void D3D_ScreenInversionOverlay() s[3] = 0.375f + (cos*(-1) - sin*(+1)); t[3] = 0.375f + (sin*(-1) + cos*(+1)); - SelectPolygonBeginType(3); /* triangles */ - - pglTexCoord2f(s[0], t[0]); - pglVertex3f(x[0], y[0], -1.0f); - pglTexCoord2f(s[1], t[1]); - pglVertex3f(x[1], y[1], -1.0f); - pglTexCoord2f(s[3], t[3]); - pglVertex3f(x[3], y[3], -1.0f); - - pglTexCoord2f(s[1], t[1]); - pglVertex3f(x[1], y[1], -1.0f); - pglTexCoord2f(s[2], t[2]); - pglVertex3f(x[2], y[2], -1.0f); - pglTexCoord2f(s[3], t[3]); - pglVertex3f(x[3], y[3], -1.0f); - - pglEnd(); - - CheckTranslucencyModeIsCorrect(TRANSLUCENCY_COLOUR); + for (j = 0; j < 4; j++) { + varrp->v[0] = x[j]; + varrp->v[1] = y[j]; + varrp->v[2] = -1.0f; + varrp->v[3] = 1.0f; + + varrp->t[0] = s[j]; + varrp->t[1] = t[j]; + + varrp->c[0] = 255; + varrp->c[1] = 255; + varrp->c[2] = 255; + varrp->c[3] = 255; + + varrp->s[0] = 0; + varrp->s[1] = 0; + varrp->s[2] = 0; + varrp->s[3] = 0; + + varrp++; + varrc++; + } } } void D3D_PredatorScreenInversionOverlay() { - CheckTranslucencyModeIsCorrect(TRANSLUCENCY_DARKENINGCOLOUR); - CheckBoundTextureIsCorrect(NULL); + int j; + + // changing the depth func manually, so flush now + FlushTriangleBuffers(0); + CheckTriangleBuffer(4, 0, 0, 0, NULL, TRANSLUCENCY_DARKENINGCOLOUR, -1); + + for (j = 0; j < 4; j++) { + + switch (j) { + case 0: + varrp->v[0] = -1.0f; + varrp->v[1] = -1.0f; + break; + case 1: + varrp->v[0] = 1.0f; + varrp->v[1] = -1.0f; + break; + case 2: + varrp->v[0] = 1.0f; + varrp->v[1] = 1.0f; + break; + case 3: + varrp->v[0] = -1.0f; + varrp->v[1] = 1.0f; + break; + } + + varrp->v[2] = 1.0f; + varrp->v[3] = 1.0f; + + varrp->t[0] = 0.0f; + varrp->t[1] = 0.0f; + + varrp->c[0] = 255; + varrp->c[1] = 255; + varrp->c[2] = 255; + varrp->c[3] = 255; + + varrp->s[0] = 0; + varrp->s[1] = 0; + varrp->s[2] = 0; + varrp->s[3] = 0; + + varrp++; + varrc++; + } + pglDepthFunc(GL_ALWAYS); - - SelectPolygonBeginType(3); /* triangles */ - pglColor4f(1.0f, 1.0f, 1.0f, 1.0f); - - pglVertex3f(-1.0f, -1.0f, 1.0f); - pglVertex3f( 1.0f, -1.0f, 1.0f); - pglVertex3f(-1.0f, 1.0f, 1.0f); - - pglVertex3f( 1.0f, -1.0f, 1.0f); - pglVertex3f( 1.0f, 1.0f, 1.0f); - pglVertex3f(-1.0f, 1.0f, 1.0f); - - pglEnd(); - + FlushTriangleBuffers(0); pglDepthFunc(GL_LEQUAL); } @@ -1376,21 +1525,15 @@ void DrawScanlinesOverlay(float level) float v, size; int c; int a; + int j; tex = ImageHeaderArray[PredatorNumbersImageNumber].D3DTexture; - - CheckTranslucencyModeIsCorrect(TRANSLUCENCY_NORMAL); - CheckBoundTextureIsCorrect(tex); - CheckFilteringModeIsCorrect(FILTERING_BILINEAR_ON); - pglDepthFunc(GL_ALWAYS); - + c = 255; a = 64.0f+level*64.0f; v = 128.0f; size = 128.0f*(1.0f-level*0.8f); - - pglColor4ub(c, c, c, a); x[0] = -1.0f; y[0] = -1.0f; @@ -1409,23 +1552,35 @@ void DrawScanlinesOverlay(float level) s[3] = (v + size) / 256.0f; t[3] = 1.0f; - SelectPolygonBeginType(3); /* triangles */ + // changing the depth func manually, so flush now + FlushTriangleBuffers(0); + CheckTriangleBuffer(4, 0, 0, 0, tex, TRANSLUCENCY_NORMAL, FILTERING_BILINEAR_ON); + + for (j = 0; j < 4; j++) { + varrp->v[0] = x[j]; + varrp->v[1] = y[j]; + varrp->v[2] = 1.0f; + varrp->v[3] = 1.0f; - pglTexCoord2f(s[0], t[0]); - pglVertex3f(x[0], y[0], 1.0f); - pglTexCoord2f(s[1], t[1]); - pglVertex3f(x[1], y[1], 1.0f); - pglTexCoord2f(s[3], t[3]); - pglVertex3f(x[3], y[3], 1.0f); - - pglTexCoord2f(s[1], t[1]); - pglVertex3f(x[1], y[1], 1.0f); - pglTexCoord2f(s[2], t[2]); - pglVertex3f(x[2], y[2], 1.0f); - pglTexCoord2f(s[3], t[3]); - pglVertex3f(x[3], y[3], 1.0f); - - pglEnd(); + varrp->t[0] = s[j]; + varrp->t[1] = t[j]; + + varrp->c[0] = c; + varrp->c[1] = c; + varrp->c[2] = c; + varrp->c[3] = a; + + varrp->s[0] = 0; + varrp->s[1] = 0; + varrp->s[2] = 0; + varrp->s[3] = 0; + + varrp++; + varrc++; + } + + pglDepthFunc(GL_ALWAYS); + FlushTriangleBuffers(0); pglDepthFunc(GL_LEQUAL); } @@ -1433,21 +1588,19 @@ void D3D_FadeDownScreen(int brightness, int colour) { int t, r, g, b, a; GLfloat x[4], y[4]; - + int i; + t = 255 - (brightness>>8); if (t<0) t = 0; colour = (t<<24)+colour; - CheckTranslucencyModeIsCorrect(TRANSLUCENCY_NORMAL); - CheckBoundTextureIsCorrect(NULL); + CheckTriangleBuffer(4, 0, 0, 0, NULL, TRANSLUCENCY_NORMAL, -1); b = (colour >> 0) & 0xFF; g = (colour >> 8) & 0xFF; r = (colour >> 16) & 0xFF; a = (colour >> 24) & 0xFF; - - pglColor4ub(r, g, b, a); - + x[0] = -1.0f; y[0] = -1.0f; x[1] = 1.0f; @@ -1456,18 +1609,29 @@ void D3D_FadeDownScreen(int brightness, int colour) y[2] = 1.0f; x[3] = -1.0f; y[3] = 1.0f; - - SelectPolygonBeginType(3); /* triangles */ - - pglVertex3f(x[0], y[0], -1.0f); - pglVertex3f(x[1], y[1], -1.0f); - pglVertex3f(x[3], y[3], -1.0f); - - pglVertex3f(x[1], y[1], -1.0f); - pglVertex3f(x[2], y[2], -1.0f); - pglVertex3f(x[3], y[3], -1.0f); - - pglEnd(); + + for (i = 0; i < 4; i++) { + varrp->v[0] = x[i]; + varrp->v[1] = y[i]; + varrp->v[2] = -1.0f; + varrp->v[3] = 1.0f; + + varrp->t[0] = 0.0f; + varrp->t[1] = 0.0f; + + varrp->c[0] = r; + varrp->c[1] = g; + varrp->c[2] = b; + varrp->c[3] = a; + + varrp->s[0] = 0; + varrp->s[1] = 0; + varrp->s[2] = 0; + varrp->s[3] = 0; + + varrp++; + varrc++; + } } void D3D_HUD_Setup() @@ -1484,62 +1648,51 @@ void D3D_HUDQuad_Output(int imageNumber, struct VertexTag *quadVerticesPtr, unsi float RecipW, RecipH; int i; D3DTexture *tex = ImageHeaderArray[imageNumber].D3DTexture; - GLfloat x[4], y[4], s[4], t[4]; + GLfloat x, y, s, t; int r, g, b, a; /* possibly use polygon offset? (predator hud) */ - CheckTranslucencyModeIsCorrect(TRANSLUCENCY_GLOWING); - CheckBoundTextureIsCorrect(tex); + CheckTriangleBuffer(4, 0, 0, 0, tex, TRANSLUCENCY_GLOWING, -1); - if (tex->w == 128) { - RecipW = 1.0f / 128.0f; - } else { - float width = (float) tex->w; - RecipW = 1.0f / width; - } - - if (tex->h == 128) { - RecipH = 1.0f / 128.0f; - } else { - float height = (float) tex->h; - RecipH = 1.0f / height; - } + RecipW = tex->RecipW / 65536.0f; + RecipH = tex->RecipH / 65536.0f; b = (colour >> 0) & 0xFF; g = (colour >> 8) & 0xFF; r = (colour >> 16) & 0xFF; a = (colour >> 24) & 0xFF; - - pglColor4ub(r, g, b, a); - + for (i = 0; i < 4; i++) { - x[i] = quadVerticesPtr[i].X; - x[i] = (x[i] - ScreenDescriptorBlock.SDB_CentreX)/ScreenDescriptorBlock.SDB_CentreX; - y[i] = quadVerticesPtr[i].Y; - y[i] = -(y[i] - ScreenDescriptorBlock.SDB_CentreY)/ScreenDescriptorBlock.SDB_CentreY; + x = quadVerticesPtr[i].X; + x = (x - ScreenDescriptorBlock.SDB_CentreX)/ScreenDescriptorBlock.SDB_CentreX; + y = quadVerticesPtr[i].Y; + y = -(y - ScreenDescriptorBlock.SDB_CentreY)/ScreenDescriptorBlock.SDB_CentreY; + + s = TEXCOORD_FIXED(quadVerticesPtr[i].U<<16, RecipW); + t = TEXCOORD_FIXED(quadVerticesPtr[i].V<<16, RecipH); + + varrp->v[0] = x; + varrp->v[1] = y; + varrp->v[2] = -1.0f; + varrp->v[3] = 1.0f; - s[i] = ((float)quadVerticesPtr[i].U)*RecipW; - t[i] = ((float)quadVerticesPtr[i].V)*RecipH; + varrp->t[0] = s; + varrp->t[1] = t; + + varrp->c[0] = r; + varrp->c[1] = g; + varrp->c[2] = b; + varrp->c[3] = a; + + varrp->s[0] = 0; + varrp->s[1] = 0; + varrp->s[2] = 0; + varrp->s[3] = 0; + + varrp++; + varrc++; } - - SelectPolygonBeginType(3); /* triangles */ - - pglTexCoord2f(s[0], t[0]); - pglVertex3f(x[0], y[0], -1.0f); - pglTexCoord2f(s[1], t[1]); - pglVertex3f(x[1], y[1], -1.0f); - pglTexCoord2f(s[3], t[3]); - pglVertex3f(x[3], y[3], -1.0f); - - pglTexCoord2f(s[1], t[1]); - pglVertex3f(x[1], y[1], -1.0f); - pglTexCoord2f(s[2], t[2]); - pglVertex3f(x[2], y[2], -1.0f); - pglTexCoord2f(s[3], t[3]); - pglVertex3f(x[3], y[3], -1.0f); - - pglEnd(); } void D3D_RenderHUDNumber_Centred(unsigned int number,int x,int y,int colour) @@ -2328,60 +2481,99 @@ void D3D_DrawRectangle(int x, int y, int w, int h, int alpha) void D3D_DrawColourBar(int yTop, int yBottom, int rScale, int gScale, int bScale) { extern unsigned char GammaValues[256]; - GLfloat x[4], y[4]; + GLfloat x[2], y[2]; int i; - - CheckTranslucencyModeIsCorrect(TRANSLUCENCY_OFF); - CheckBoundTextureIsCorrect(NULL); - - SelectPolygonBeginType(3); /* triangles */ - - for (i = 0; i < 255; ) { + int r; + int g; + int b; + int a; + int start; + + CheckTriangleBuffer(256*2, 0, 255*2, 0, NULL, TRANSLUCENCY_OFF, -1); + + start = varrc; + + for (i = 0; i < 256; i++) { unsigned int c; c = GammaValues[i]; - pglColor4ub(MUL_FIXED(c,rScale), MUL_FIXED(c,gScale), MUL_FIXED(c,bScale), 255); - + r = MUL_FIXED(c,rScale); + g = MUL_FIXED(c,gScale); + b = MUL_FIXED(c,bScale); + a = 255; + x[0] = (Global_VDB_Ptr->VDB_ClipRight*i)/255; x[0] = (x[0] - ScreenDescriptorBlock.SDB_CentreX)/ScreenDescriptorBlock.SDB_CentreX; y[0] = yTop; y[0] = -(y[0] - ScreenDescriptorBlock.SDB_CentreY)/ScreenDescriptorBlock.SDB_CentreY; - x[1] = (Global_VDB_Ptr->VDB_ClipRight*i)/255; - x[1] = (x[1] - ScreenDescriptorBlock.SDB_CentreX)/ScreenDescriptorBlock.SDB_CentreX; + x[1] = x[0]; y[1] = yBottom; y[1] = -(y[1] - ScreenDescriptorBlock.SDB_CentreY)/ScreenDescriptorBlock.SDB_CentreY; + + varrp->v[0] = x[0]; + varrp->v[1] = y[0]; + varrp->v[2] = -1.0f; + varrp->v[3] = 1.0f; - i++; - c = GammaValues[i]; - pglColor4ub(MUL_FIXED(c,rScale), MUL_FIXED(c,gScale), MUL_FIXED(c,bScale), 255); - x[2] = (Global_VDB_Ptr->VDB_ClipRight*i)/255; - x[2] = (x[2] - ScreenDescriptorBlock.SDB_CentreX)/ScreenDescriptorBlock.SDB_CentreX; - y[2] = yBottom; - y[2] = -(y[2] - ScreenDescriptorBlock.SDB_CentreY)/ScreenDescriptorBlock.SDB_CentreY; + varrp->t[0] = 0.0f; + varrp->t[1] = 0.0f; - x[3] = (Global_VDB_Ptr->VDB_ClipRight*i)/255; - x[3] = (x[3] - ScreenDescriptorBlock.SDB_CentreX)/ScreenDescriptorBlock.SDB_CentreX; - y[3] = yTop; - y[3] = -(y[3] - ScreenDescriptorBlock.SDB_CentreY)/ScreenDescriptorBlock.SDB_CentreY; + varrp->c[0] = r; + varrp->c[1] = g; + varrp->c[2] = b; + varrp->c[3] = a; + + varrp->s[0] = 0; + varrp->s[1] = 0; + varrp->s[2] = 0; + varrp->s[3] = 0; + + varrp++; + varrc++; + varrp->v[0] = x[1]; + varrp->v[1] = y[1]; + varrp->v[2] = -1.0f; + varrp->v[3] = 1.0f; - pglVertex3f(x[0], y[0], -1.0f); - pglVertex3f(x[1], y[1], -1.0f); - pglVertex3f(x[3], y[3], -1.0f); - - pglVertex3f(x[1], y[1], -1.0f); - pglVertex3f(x[2], y[2], -1.0f); - pglVertex3f(x[3], y[3], -1.0f); + varrp->t[0] = 0.0f; + varrp->t[1] = 0.0f; + + varrp->c[0] = r; + varrp->c[1] = g; + varrp->c[2] = b; + varrp->c[3] = a; + + varrp->s[0] = 0; + varrp->s[1] = 0; + varrp->s[2] = 0; + varrp->s[3] = 0; + + varrp++; + varrc++; + } + + for (i = 0; i < 255; i++) { + tarrp->a = start+(i+0)*2+0; + tarrp->b = start+(i+0)*2+1; + tarrp->c = start+(i+1)*2+0; + tarrp++; + tarrc++; + tarrp->a = start+(i+0)*2+1; + tarrp->b = start+(i+1)*2+1; + tarrp->c = start+(i+1)*2+0; + tarrp++; + tarrc++; } - - pglEnd(); } void ColourFillBackBuffer(int FillColour) { float r, g, b, a; - + + FlushTriangleBuffers(1); + b = ((FillColour >> 0) & 0xFF) / 255.0f; g = ((FillColour >> 8) & 0xFF) / 255.0f; r = ((FillColour >> 16) & 0xFF) / 255.0f; @@ -2396,20 +2588,18 @@ void ColourFillBackBufferQuad(int FillColour, int x0, int y0, int x1, int y1) { GLfloat x[4], y[4]; int r, g, b, a; + int i; if (y1 <= y0) return; - CheckTranslucencyModeIsCorrect(TRANSLUCENCY_OFF); - CheckBoundTextureIsCorrect(NULL); + CheckTriangleBuffer(4, 0, 0, 0, NULL, TRANSLUCENCY_OFF, -1); b = ((FillColour >> 0) & 0xFF); g = ((FillColour >> 8) & 0xFF); r = ((FillColour >> 16) & 0xFF); a = ((FillColour >> 24) & 0xFF); - pglColor4ub(r, g, b, 255); - x[0] = x0; x[0] = (x[0] - ScreenDescriptorBlock.SDB_CentreX)/ScreenDescriptorBlock.SDB_CentreX; y[0] = y0; @@ -2430,17 +2620,28 @@ void ColourFillBackBufferQuad(int FillColour, int x0, int y0, int x1, int y1) y[3] = y1 - 1; y[3] = -(y[3] - ScreenDescriptorBlock.SDB_CentreY)/ScreenDescriptorBlock.SDB_CentreY; - SelectPolygonBeginType(3); /* triangles */ - - pglVertex3f(x[0], y[0], -1.0f); - pglVertex3f(x[1], y[1], -1.0f); - pglVertex3f(x[3], y[3], -1.0f); - - pglVertex3f(x[1], y[1], -1.0f); - pglVertex3f(x[2], y[2], -1.0f); - pglVertex3f(x[3], y[3], -1.0f); - - pglEnd(); + for (i = 0; i < 4; i++) { + varrp->v[0] = x[i]; + varrp->v[1] = y[i]; + varrp->v[2] = -1.0f; + varrp->v[3] = 1.0f; + + varrp->t[0] = 0.0f; + varrp->t[1] = 0.0f; + + varrp->c[0] = r; + varrp->c[1] = g; + varrp->c[2] = b; + varrp->c[3] = a; + + varrp->s[0] = 0; + varrp->s[1] = 0; + varrp->s[2] = 0; + varrp->s[3] = 0; + + varrp++; + varrc++; + } } void D3D_DrawBackdrop() @@ -2502,39 +2703,68 @@ void D3D_DrawBackdrop() void BltImage(RECT *dest, DDSurface *image, RECT *src) { - int width1, width; - int height1, height; + float x[4]; + float y[4]; + float s[4]; + float t[4]; + int i; - width = dest->right - dest->left + 1; - width1 = src->right - src->left + 1; - height = dest->bottom - dest->top + 1; - height1 = src->bottom - src->top + 1; - - pglPushAttrib(GL_COLOR_BUFFER_BIT | GL_PIXEL_MODE_BIT | GL_DEPTH_BUFFER_BIT | GL_ENABLE_BIT); - pglPushClientAttrib(GL_CLIENT_PIXEL_STORE_BIT); - - pglDisable(GL_BLEND); - pglDisable(GL_DEPTH_TEST); - pglDisable(GL_TEXTURE_2D); - pglDisable(GL_ALPHA_TEST); - - pglPixelStorei(GL_UNPACK_ALIGNMENT, 1); - pglPixelStorei(GL_UNPACK_ROW_LENGTH, image->w); - pglPixelZoom((double)width/(double)width1, (double)height/(double)height1); - - pglMatrixMode(GL_PROJECTION); - pglPushMatrix(); - pglLoadIdentity(); - - pglOrtho(0.0, ScreenDescriptorBlock.SDB_Width, 0.0, ScreenDescriptorBlock.SDB_Height, -1.0, 1.0); - pglRasterPos2i(dest->left, ScreenDescriptorBlock.SDB_Height-dest->bottom); - - pglDrawPixels(width1, height1, GL_RGBA, GL_UNSIGNED_BYTE, image->buf); - - pglPopMatrix(); - - pglPopClientAttrib(); - pglPopAttrib();; + x[0] = dest->left; + x[0] = (x[0] - ScreenDescriptorBlock.SDB_CentreX)/ScreenDescriptorBlock.SDB_CentreX; + y[0] = dest->top; + y[0] = -(y[0] - ScreenDescriptorBlock.SDB_CentreY)/ScreenDescriptorBlock.SDB_CentreY; + + x[1] = dest->right; + x[1] = (x[1] - ScreenDescriptorBlock.SDB_CentreX)/ScreenDescriptorBlock.SDB_CentreX; + y[1] = dest->top; + y[1] = -(y[1] - ScreenDescriptorBlock.SDB_CentreY)/ScreenDescriptorBlock.SDB_CentreY; + + x[2] = dest->right; + x[2] = (x[2] - ScreenDescriptorBlock.SDB_CentreX)/ScreenDescriptorBlock.SDB_CentreX; + y[2] = dest->bottom; + y[2] = -(y[2] - ScreenDescriptorBlock.SDB_CentreY)/ScreenDescriptorBlock.SDB_CentreY; + + x[3] = dest->left; + x[3] = (x[3] - ScreenDescriptorBlock.SDB_CentreX)/ScreenDescriptorBlock.SDB_CentreX; + y[3] = dest->bottom; + y[3] = -(y[3] - ScreenDescriptorBlock.SDB_CentreY)/ScreenDescriptorBlock.SDB_CentreY; + + s[0] = src->left * image->RecipW; + t[0] = src->top * image->RecipH; + + s[1] = src->right * image->RecipW; + t[1] = src->top * image->RecipH; + + s[2] = src->right * image->RecipW; + t[2] = src->bottom * image->RecipH; + + s[3] = src->left * image->RecipW; + t[3] = src->bottom * image->RecipH; + + CheckTriangleBuffer(4, 0, 0, 0, image, TRANSLUCENCY_OFF, -1); + + for (i = 0; i < 4; i++) { + varrp->v[0] = x[i]; + varrp->v[1] = y[i]; + varrp->v[2] = -1.0f; + varrp->v[3] = 1.0f; + + varrp->t[0] = s[i]; + varrp->t[1] = t[i]; + + varrp->c[0] = 255; + varrp->c[1] = 255; + varrp->c[2] = 255; + varrp->c[3] = 255; + + varrp->s[0] = 0; + varrp->s[1] = 0; + varrp->s[2] = 0; + varrp->s[3] = 0; + + varrp++; + varrc++; + } } /* ** */ @@ -2620,7 +2850,7 @@ void D3D_DrawParticle_Rain(PARTICLE *particlePtr,VECTORCH *prevPositionPtr) varrp->v[1] = yf*w; varrp->v[2] = zf*w; varrp->v[3] = w; - + if (i == 0) { varrp->c[0] = 0; varrp->c[1] = 255; @@ -2632,6 +2862,12 @@ void D3D_DrawParticle_Rain(PARTICLE *particlePtr,VECTORCH *prevPositionPtr) varrp->c[2] = 255; varrp->c[3] = 32; } + + varrp->s[0] = 0; + varrp->s[1] = 0; + varrp->s[2] = 0; + varrp->s[3] = 0; + varrp++; varrc++; } @@ -4512,6 +4748,11 @@ void D3D_DrawMoltenMetalMesh_Unclipped(void) varrp->c[2] = b; varrp->c[3] = a; + varrp->s[0] = 0; + varrp->s[1] = 0; + varrp->s[2] = 0; + varrp->s[3] = 0; + varrp++; varrc++; @@ -4620,7 +4861,12 @@ void D3D_DrawMoltenMetalMesh_Clipped(void) varrp->c[1] = g; varrp->c[2] = b; varrp->c[3] = a; - + + varrp->s[0] = 0; + varrp->s[1] = 0; + varrp->s[2] = 0; + varrp->s[3] = 0; + varrp++; varrc++; diff --git a/src/stubs.c b/src/stubs.c index b1be586..8733c41 100644 --- a/src/stubs.c +++ b/src/stubs.c @@ -167,25 +167,6 @@ void UnlockSurface() fprintf(stderr, "UnlockSurface()\n"); } -void ReleaseDDSurface(void* DDSurface) -{ -/* - fprintf(stderr, "ReleaseDDSurface(%p)\n", DDSurface); -*/ - D3DTexture *t = (D3DTexture *)DDSurface; - - if (t->id > 0) { - fprintf(stderr, "ReleaseDDSurface(%p) - OpenGL Object (tex = %d, %d, %d)\n", DDSurface, t->id, t->w, t->h); - } else { - if (t->buf) { - free(t->buf); - } else { - fprintf(stderr, "ReleaseDDSurface(%p) - What is This? (tex = %d, %d, %d)\n", DDSurface, t->id, t->w, t->h); - } - } - - free(t); -} BOOL ChangeDirectDrawObject() { diff --git a/src/win95/aw.h b/src/win95/aw.h index 0a7ac4b..8b9985c 100644 --- a/src/win95/aw.h +++ b/src/win95/aw.h @@ -4,31 +4,28 @@ struct AwBackupTexture; typedef struct AwBackupTexture * AW_BACKUPTEXTUREHANDLE; +// fake type used by opengl.c typedef struct DIRECTDRAWSURFACE { unsigned char *buf; int id; - - int w; - int h; - + + unsigned int w; + unsigned int h; + + unsigned int IsNpot; + unsigned int TexWidth; + unsigned int TexHeight; + float RecipW; + float RecipH; + int filter; } DIRECTDRAWSURFACE; typedef DIRECTDRAWSURFACE * LPDIRECTDRAWSURFACE; typedef DIRECTDRAWSURFACE DDSurface; -typedef struct DIRECT3DTEXTURE -{ - unsigned char *buf; - int id; - - int w; - int h; - - int filter; -} DIRECT3DTEXTURE; - +typedef DIRECTDRAWSURFACE DIRECT3DTEXTURE; typedef DIRECT3DTEXTURE * LPDIRECT3DTEXTURE; typedef DIRECT3DTEXTURE D3DTexture; diff --git a/src/win95/awtexld.cpp b/src/win95/awtexld.cpp index 03ef1db..64afca7 100644 --- a/src/win95/awtexld.cpp +++ b/src/win95/awtexld.cpp @@ -386,7 +386,7 @@ AwTl::SurfUnion AwBackupTexture::Restore(AwTl::CreateTextureParms const & rParam if (!pixelFormat.validB) db_log3("AwCreateGraphic(): ERROR: pixel format not valid"); - if (!driverDesc.ddP || !driverDesc.validB && rParams.loadTextureB) + if (!driverDesc.ddP || (!driverDesc.validB && rParams.loadTextureB)) db_log3("AwCreateGraphic(): ERROR: driver description not valid"); awTlLastErr = pixelFormat.validB && driverDesc.ddP && (driverDesc.validB || !rParams.loadTextureB) ? AW_TLE_OK : AW_TLE_NOINIT; @@ -426,13 +426,13 @@ void AwBackupTexture::ChoosePixelFormat(AwTl::CreateTextureParms const & _parmsR unsigned fMyFlags = _parmsR.flags & AW_TLF_PREVSRCALL ? db_assert1(_parmsR.restoreH), m_fFlags : _parmsR.flags & AW_TLF_PREVSRC ? db_assert1(_parmsR.restoreH), - _parmsR.flags & ~AW_TLF_TRANSP | m_fFlags & AW_TLF_TRANSP + ((_parmsR.flags & ~AW_TLF_TRANSP) | (m_fFlags & AW_TLF_TRANSP)) : _parmsR.flags; // transparency? m_bTranspMask = HasTransparentMask(fMyFlags & AW_TLF_TRANSP ? true : false); - if (_parmsR.loadTextureB || fMyFlags & AW_TLF_TEXTURE) + if (_parmsR.loadTextureB || (fMyFlags & AW_TLF_TEXTURE)) { #if 0 // use a texture format @@ -521,13 +521,26 @@ AwTl::SurfUnion AwBackupTexture::CreateTexture(AwTl::CreateTextureParms const & { using namespace AwTl; -// fprintf(stderr, "AwBackupTexture::CreateTexture(...) This is where we could convert the image to RGB/RGBA, and so on\n"); + // which flags to use? + unsigned fMyFlags = + (_parmsR.flags & AW_TLF_PREVSRCALL) ? db_assert1(_parmsR.restoreH), + (_parmsR.flags & (AW_TLF_CHECKLOST|AW_TLF_SKIPNOTLOST)) | (m_fFlags & ~(AW_TLF_CHECKLOST|AW_TLF_SKIPNOTLOST)) + : (_parmsR.flags & AW_TLF_PREVSRC) ? db_assert1(_parmsR.restoreH), + ((_parmsR.flags & ~AW_TLF_TRANSP) | (m_fFlags & AW_TLF_TRANSP)) + : _parmsR.flags; if (_parmsR.originalWidthP) *_parmsR.originalWidthP = m_nWidth; if (_parmsR.originalHeightP) *_parmsR.originalHeightP = m_nHeight; - D3DTexture *Tex = (D3DTexture *)malloc(sizeof(D3DTexture)); + if (_parmsR.rectA != NULL) { + fprintf(stderr, "AwBackupTexture::CreateTexture - rectangle cutouts?\n"); + } + if (pixelFormat.texB && (m_bTranspMask && (!pixelFormat.alphaB || fMyFlags & AW_TLF_CHROMAKEY))) { + fprintf(stderr, "AwBackupTexture::CreateTexture - chroma\n"); + } + + // convert asset to 32-bit rgba unsigned char *buf = (unsigned char *)malloc(m_nWidth * m_nHeight * 4); Colour * paletteP = m_nPaletteSize ? GetPalette() : NULL; @@ -573,19 +586,20 @@ AwTl::SurfUnion AwBackupTexture::CreateTexture(AwTl::CreateTextureParms const & } -/* temp junk */ + // convert to texture + D3DTexture *Tex = (D3DTexture *)calloc(1, sizeof(D3DTexture)); + Tex->w = m_nWidth; Tex->h = m_nHeight; + if (pixelFormat.texB) { - Tex->buf = NULL; /* not used */ - CreateOGLTexture(Tex, buf); /* this will set the id */ - free(buf); + CreateOGLTexture(Tex, buf); } else { - Tex->buf = buf; /* hey, I need this! */ CreateIMGSurface(Tex, buf); } - + return static_cast(Tex); + #if 0 // which flags to use? diff --git a/src/win95/awtexld.hpp b/src/win95/awtexld.hpp index e9c70fb..b3b7f32 100644 --- a/src/win95/awtexld.hpp +++ b/src/win95/awtexld.hpp @@ -130,8 +130,7 @@ namespace AwTl { DDSurface * surfaceP; void * voidP; SurfUnion(){} - SurfUnion(D3DTexture * p) : textureP(p){} - SurfUnion(DDSurface * p) : surfaceP(p){} + SurfUnion(void * p) : voidP(p){} }; union PtrUnion diff --git a/src/win95/inline.h b/src/win95/inline.h index 8b162c8..dcb9dff 100644 --- a/src/win95/inline.h +++ b/src/win95/inline.h @@ -581,6 +581,10 @@ a = itmp;} #else +// parts of mathline.c that have been re-inlined. +// MUL_FIXED, f2i +#include "mathline.h" + /* inline assembly has been moved to mathline.c */ void ADD_LL(LONGLONGCH *a, LONGLONGCH *b, LONGLONGCH *c); void ADD_LL_PP(LONGLONGCH *c, LONGLONGCH *a); @@ -592,7 +596,6 @@ void EQUALS_LL(LONGLONGCH *a, LONGLONGCH *b); void NEG_LL(LONGLONGCH *a); void ASR_LL(LONGLONGCH *a, int shift); void IntToLL(LONGLONGCH *a, int *b); -int MUL_FIXED(int a, int b); int DIV_FIXED(int a, int b); #define DIV_INT(a, b) ((a) / (b)) @@ -602,20 +605,7 @@ int WideMulNarrowDiv(int a, int b, int c); void RotateVector_ASM(VECTORCH *v, MATRIXCH *m); void RotateAndCopyVector_ASM(VECTORCH *v1, VECTORCH *v2, MATRIXCH *m); -/* -int FloatToInt(float); -#define f2i(a, b) { a = FloatToInt(b); } -*/ - int SqRoot32(int A); -void FloatToInt(); -extern float fti_fptmp; -extern int fti_itmp; - -#define f2i(a, b) { \ -fti_fptmp = (b); \ -FloatToInt(); \ -a = fti_itmp;} #endif