diff --git a/CMakeLists.txt b/CMakeLists.txt index a55d9cf..e585edb 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -9,117 +9,148 @@ IF(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES) SET_PROPERTY(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS "Debug" "Release" "MinSizeRel" "RelWithDebInfo") ENDIF(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES) +# default to Desktop build +IF(NOT AVP_BUILD_TYPE) + SET(AVP_BUILD_TYPE DESKTOP CACHE STRING "Executable type; one of: DESKTOP WEB" FORCE) +ENDIF(NOT AVP_BUILD_TYPE) + +IF(NOT AVP_BUILD_TYPE STREQUAL "DESKTOP" AND NOT AVP_BUILD_TYPE STREQUAL "WEB") + MESSAGE(FATAL_ERROR "Invalid AVP_BUILD_TYPE setting ${AVP_BUILD_TYPE}; must be one of DESKTOP WEB") +ENDIF(NOT AVP_BUILD_TYPE STREQUAL "DESKTOP" AND NOT AVP_BUILD_TYPE STREQUAL "WEB") + +SET(AVP_WEB "NO") +IF(AVP_BUILD_TYPE STREQUAL "WEB") + SET(AVP_WEB "YES") +ENDIF(AVP_BUILD_TYPE STREQUAL "WEB") + PROJECT(avp) +IF(AVP_WEB) + IF(CMAKE_BUILD_TYPE STREQUAL "Debug") + SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -g -g4 -s USE_SDL=2 -s TOTAL_MEMORY=234881024 -s ASSERTIONS=2 -s SAFE_HEAP=1 -s STACK_OVERFLOW_CHECK=2 -s DEMANGLE_SUPPORT=1") + SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g -g4 -s USE_SDL=2 -s TOTAL_MEMORY=234881024 -s ASSERTIONS=2 -s SAFE_HEAP=1 -s STACK_OVERFLOW_CHECK=2 -s DEMANGLE_SUPPORT=1") + ELSE() + SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -s USE_SDL=2 -s TOTAL_MEMORY=234881024") + SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -s USE_SDL=2 -s TOTAL_MEMORY=234881024") + ENDIF() + + IF(AVP_WEB_WASM) + SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -s WASM=1") + SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -s WASM=1") + ENDIF() +ENDIF(AVP_WEB) + # required dependencies -INCLUDE(FindOpenGLES.cmake) -INCLUDE(FindOpenGLES2.cmake) -INCLUDE(FindSDL2.cmake) -INCLUDE(FindSDL) -INCLUDE(FindOpenGL) -INCLUDE(FindOpenAL) +IF(NOT AVP_WEB) + INCLUDE(FindOpenGLES2.cmake) + INCLUDE(FindSDL2.cmake) + INCLUDE(FindSDL) + INCLUDE(FindOpenGL) + INCLUDE(FindOpenAL) -# Use SDL 1.2 if it is installed, else use SDL 2.0. -IF(NOT SDL_TYPE) - SET(SDL_TYPE AUTO CACHE STRING "SDL Version; one of: AUTO SDL SDL2") - SET_PROPERTY(CACHE SDL_TYPE PROPERTY STRINGS "AUTO" "SDL" "SDL2") -ENDIF(NOT SDL_TYPE) + # Use SDL 1.2 if it is installed, else use SDL 2.0. + IF(NOT SDL_TYPE) + SET(SDL_TYPE AUTO CACHE STRING "SDL Version; one of: AUTO SDL SDL2") + SET_PROPERTY(CACHE SDL_TYPE PROPERTY STRINGS "AUTO" "SDL" "SDL2") + ENDIF(NOT SDL_TYPE) -IF(NOT SDL_TYPE STREQUAL "AUTO" AND NOT SDL_TYPE STREQUAL "SDL" AND NOT SDL_TYPE STREQUAL "SDL2") - 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(NOT SDL_TYPE STREQUAL "AUTO" AND NOT SDL_TYPE STREQUAL "SDL" AND NOT SDL_TYPE STREQUAL "SDL2") + 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.") - SET(SDL_TYPE "SDL") + 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) -ENDIF(SDL_TYPE STREQUAL "AUTO") -IF(SDL_TYPE STREQUAL "AUTO") - IF(SDL2_FOUND) - MESSAGE(STATUS "SDL 2.0 found; using that.") - SET(SDL_TYPE "SDL2") - ENDIF(SDL2_FOUND) -ENDIF(SDL_TYPE STREQUAL "AUTO") + IF(SDL_TYPE STREQUAL "AUTO") + IF(SDL_FOUND) + MESSAGE(STATUS "SDL 1.2 found; using that.") + SET(SDL_TYPE "SDL") + ENDIF(SDL_FOUND) + ENDIF(SDL_TYPE STREQUAL "AUTO") -IF(SDL_TYPE STREQUAL "AUTO") - MESSAGE(FATAL_ERROR "SDL 1.2 or SDL 2.0 is required but CMake couldn't find it.") -ENDIF(SDL_TYPE STREQUAL "AUTO") + IF(SDL_TYPE STREQUAL "AUTO") + IF(SDL2_FOUND) + MESSAGE(STATUS "SDL 2.0 found; using that.") + SET(SDL_TYPE "SDL2") + ENDIF(SDL2_FOUND) + ENDIF(SDL_TYPE STREQUAL "AUTO") -IF(SDL_TYPE STREQUAL "SDL") - IF(NOT SDL_FOUND) - MESSAGE(FATAL_ERROR "SDL 1.2 was requested but CMake couldn't find it.") - ENDIF(NOT SDL_FOUND) -ENDIF(SDL_TYPE STREQUAL "SDL") + IF(SDL_TYPE STREQUAL "AUTO") + MESSAGE(FATAL_ERROR "SDL 1.2 or SDL 2.0 is required but CMake couldn't find it.") + ENDIF(SDL_TYPE STREQUAL "AUTO") -IF(SDL_TYPE STREQUAL "SDL2") - IF(NOT SDL2_FOUND) - MESSAGE(FATAL_ERROR "SDL 2.0 was requested but CMake couldn't find it.") - ENDIF(NOT SDL2_FOUND) - MESSAGE(WARNING "SDL 2.0 support is EXPERIMENTAL and INCOMPLETE.") -ENDIF(SDL_TYPE STREQUAL "SDL2") + IF(SDL_TYPE STREQUAL "SDL") + IF(NOT SDL_FOUND) + MESSAGE(FATAL_ERROR "SDL 1.2 was requested but CMake couldn't find it.") + ENDIF(NOT SDL_FOUND) + ENDIF(SDL_TYPE STREQUAL "SDL") -# 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(SDL_TYPE STREQUAL "SDL2") + IF(NOT SDL2_FOUND) + MESSAGE(FATAL_ERROR "SDL 2.0 was requested but CMake couldn't find it.") + ENDIF(NOT SDL2_FOUND) + MESSAGE(WARNING "SDL 2.0 support is EXPERIMENTAL and INCOMPLETE.") + ENDIF(SDL_TYPE STREQUAL "SDL2") -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") + # Use Desktop OpenGL if it is available, else try OpenGL ES 2.0. + IF(NOT OPENGL_TYPE) + SET(OPENGL_TYPE AUTO CACHE STRING "OpenGL Version; one of: AUTO OPENGL OPENGLES2") + SET_PROPERTY(CACHE OPENGL_TYPE PROPERTY STRINGS "AUTO" "OPENGL" "OPENGLES2") + ENDIF(NOT OPENGL_TYPE) -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(NOT OPENGL_TYPE STREQUAL "AUTO" AND NOT OPENGL_TYPE STREQUAL "OPENGL" AND NOT OPENGL_TYPE STREQUAL "OPENGLES2") + MESSAGE(FATAL_ERROR "Invalid OPENGL_TYPE setting ${OPENGL_TYPE}; must be one of AUTO OPENGL OPENGLES2") + ENDIF(NOT OPENGL_TYPE STREQUAL "AUTO" AND NOT OPENGL_TYPE STREQUAL "OPENGL" AND NOT OPENGL_TYPE STREQUAL "OPENGLES2") -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") + 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") - MESSAGE(FATAL_ERROR "OpenGL is required but CMake couldn't find it.") -ENDIF(OPENGL_TYPE STREQUAL "AUTO") + IF(OPENGL_TYPE STREQUAL "AUTO") + IF(OPENGLES2_FOUND) + MESSAGE(STATUS "OpenGL ES 2.0 found; using that.") + SET(OPENGL_TYPE "OPENGLES2") + ENDIF(OPENGLES2_FOUND) + 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 "AUTO") + MESSAGE(FATAL_ERROR "OpenGL is required but CMake couldn't find it.") + ENDIF(OPENGL_TYPE STREQUAL "AUTO") -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") + 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") -# OpenAL -IF(NOT OPENAL_FOUND) - MESSAGE(FATAL_ERROR "OpenAL is required but CMake couldn't find it.") -ENDIF(NOT OPENAL_FOUND) + IF(OPENGL_TYPE STREQUAL "OPENGLES2") + IF(NOT OPENGLES2_FOUND) + MESSAGE(FATAL_ERROR "OpenGL ES 2.0 was requested but CMake couldn't find it.") + ENDIF(NOT OPENGLES2_FOUND) + IF(NOT SDL_TYPE STREQUAL "SDL2") + MESSAGE(FATAL_ERROR "OpenGL ES 2.0 support requires SDL2.") + ENDIF(NOT SDL_TYPE STREQUAL "SDL2") + ENDIF(OPENGL_TYPE STREQUAL "OPENGLES2") + + # OpenAL + IF(NOT OPENAL_FOUND) + MESSAGE(FATAL_ERROR "OpenAL is required but CMake couldn't find it.") + ENDIF(NOT OPENAL_FOUND) +ENDIF(NOT AVP_WEB) # required source files -LIST(APPEND source src/files.c) -LIST(APPEND source src/winapi.c) LIST(APPEND source src/stubs.c) LIST(APPEND source src/version.c) LIST(APPEND source src/mathline.c) @@ -339,18 +370,31 @@ LIST(APPEND source src/openal.c) LIST(APPEND source src/cdplayer.c) LIST(APPEND source src/menus.c) -IF(SDL_TYPE STREQUAL "SDL") - LIST(APPEND source src/main.c) +IF(WIN32) + LIST(APPEND source src/winfiles.c) +ELSE(WIN32) + LIST(APPEND source src/files.c) + LIST(APPEND source src/winapi.c) +ENDIF(WIN32) - # SDL 1.2 on OS X requires this support file - IF(APPLE AND ${CMAKE_SYSTEM_NAME} MATCHES "Darwin") - LIST(APPEND source src/sdl12/sdlmain.m) - ENDIF(APPLE AND ${CMAKE_SYSTEM_NAME} MATCHES "Darwin") -ENDIF(SDL_TYPE STREQUAL "SDL") +IF(AVP_WEB) + LIST(APPEND source src/main2.c) +ENDIF(AVP_WEB) -IF(SDL_TYPE STREQUAL "SDL2") - LIST(APPEND source src/main2.c) -ENDIF(SDL_TYPE STREQUAL "SDL2") +IF(NOT AVP_WEB) + IF(SDL_TYPE STREQUAL "SDL") + LIST(APPEND source src/main.c) + + # SDL 1.2 on OS X requires this support file + IF(APPLE AND ${CMAKE_SYSTEM_NAME} MATCHES "Darwin") + LIST(APPEND source src/sdl12/sdlmain.m) + ENDIF(APPLE AND ${CMAKE_SYSTEM_NAME} MATCHES "Darwin") + ENDIF(SDL_TYPE STREQUAL "SDL") + + IF(SDL_TYPE STREQUAL "SDL2") + LIST(APPEND source src/main2.c) + ENDIF(SDL_TYPE STREQUAL "SDL2") +ENDIF(NOT AVP_WEB) ### build all source as C++ ### (not normally used) @@ -366,44 +410,56 @@ INCLUDE_DIRECTORIES(${include}) # manually include src/include INCLUDE_DIRECTORIES(src/include) -ADD_EXECUTABLE(avp ${source}) +IF(AVP_WEB) + ADD_DEFINITIONS(-DUSE_OPENGL_ES=1) -# required dependencies -IF(SDL_TYPE STREQUAL "SDL") - INCLUDE_DIRECTORIES(${SDL_INCLUDE_DIR}) -ENDIF(SDL_TYPE STREQUAL "SDL") + ADD_EXECUTABLE(avp ${source}) +ENDIF(AVP_WEB) -IF(SDL_TYPE STREQUAL "SDL2") - INCLUDE_DIRECTORIES(${SDL2_INCLUDE_DIR}) -ENDIF(SDL_TYPE STREQUAL "SDL2") +IF(NOT AVP_WEB) + ADD_EXECUTABLE(avp ${source}) -IF(OPENGL_TYPE STREQUAL "OPENGL") - INCLUDE_DIRECTORIES(${OPENGL_INCLUDE_DIR}) -ENDIF(OPENGL_TYPE STREQUAL "OPENGL") + # required dependencies + IF(WIN32) + TARGET_LINK_LIBRARIES(avp winmm) + ENDIF(WIN32) -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") + IF(SDL_TYPE STREQUAL "SDL") + INCLUDE_DIRECTORIES(${SDL_INCLUDE_DIR}) + ENDIF(SDL_TYPE STREQUAL "SDL") -INCLUDE_DIRECTORIES(${OPENAL_INCLUDE_DIR}) + IF(SDL_TYPE STREQUAL "SDL2") + INCLUDE_DIRECTORIES(${SDL2_INCLUDE_DIR}) + ENDIF(SDL_TYPE STREQUAL "SDL2") -IF(SDL_TYPE STREQUAL "SDL") - TARGET_LINK_LIBRARIES(avp ${SDL_LIBRARY}) -ENDIF(SDL_TYPE STREQUAL "SDL") + IF(OPENGL_TYPE STREQUAL "OPENGL") + INCLUDE_DIRECTORIES(${OPENGL_INCLUDE_DIR}) + ENDIF(OPENGL_TYPE STREQUAL "OPENGL") -IF(SDL_TYPE STREQUAL "SDL2") - TARGET_LINK_LIBRARIES(avp ${SDL2_LIBRARY}) -ENDIF(SDL_TYPE STREQUAL "SDL2") + IF(OPENGL_TYPE STREQUAL "OPENGLES2") + ADD_DEFINITIONS(-DUSE_OPENGL_ES=1) + INCLUDE_DIRECTORIES(${OPENGLES2_INCLUDE_DIR}) + INCLUDE_DIRECTORIES(${EGL_INCLUDE_DIR}) + ENDIF(OPENGL_TYPE STREQUAL "OPENGLES2") -IF(OPENGL_TYPE STREQUAL "OPENGL") - TARGET_LINK_LIBRARIES(avp ${OPENGL_gl_LIBRARY}) -ENDIF(OPENGL_TYPE STREQUAL "OPENGL") + INCLUDE_DIRECTORIES(${OPENAL_INCLUDE_DIR}) -IF(OPENGL_TYPE STREQUAL "OPENGLES") - TARGET_LINK_LIBRARIES(avp ${OPENGLES_gl_LIBRARY}) - TARGET_LINK_LIBRARIES(avp ${EGL_LIBRARIES}) -ENDIF(OPENGL_TYPE STREQUAL "OPENGLES") + IF(SDL_TYPE STREQUAL "SDL") + TARGET_LINK_LIBRARIES(avp ${SDL_LIBRARY}) + ENDIF(SDL_TYPE STREQUAL "SDL") -TARGET_LINK_LIBRARIES(avp ${OPENAL_LIBRARY}) + IF(SDL_TYPE STREQUAL "SDL2") + TARGET_LINK_LIBRARIES(avp ${SDL2_LIBRARY}) + ENDIF(SDL_TYPE STREQUAL "SDL2") + + IF(OPENGL_TYPE STREQUAL "OPENGL") + TARGET_LINK_LIBRARIES(avp ${OPENGL_gl_LIBRARY}) + ENDIF(OPENGL_TYPE STREQUAL "OPENGL") + + IF(OPENGL_TYPE STREQUAL "OPENGLES2") + TARGET_LINK_LIBRARIES(avp ${OPENGLES2_gl_LIBRARY}) + TARGET_LINK_LIBRARIES(avp ${EGL_LIBRARIES}) + ENDIF(OPENGL_TYPE STREQUAL "OPENGLES2") + + TARGET_LINK_LIBRARIES(avp ${OPENAL_LIBRARY}) +ENDIF(NOT AVP_WEB) diff --git a/FindOpenGLES.cmake b/FindOpenGLES.cmake deleted file mode 100644 index 7ee2c07..0000000 --- a/FindOpenGLES.cmake +++ /dev/null @@ -1,94 +0,0 @@ -#------------------------------------------------------------------- -# 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/src/avp/hmodel.h b/src/avp/hmodel.h index 75f2586..86cfaf1 100644 --- a/src/avp/hmodel.h +++ b/src/avp/hmodel.h @@ -56,15 +56,13 @@ I'm going to try storing the quaternions as shorts within the keyframes , because there are loads of them. -Richard. */ -PACKED_PUSH typedef struct quat_short { short quatx; short quaty; short quatz; short quatw; -} PACKED QUAT_SHORT; -PACKED_POP +} QUAT_SHORT; /*A couple of conversion functions */ extern void CopyShortQuatToInt(QUAT_SHORT* qs_from,QUAT* q_to); @@ -74,21 +72,30 @@ extern void CopyIntQuatToShort(QUAT* q_from,QUAT_SHORT* qs_to); #define KEYFRAME_VECTOR_SHIFT 4 //make sure the keyframe structure packs as much as possible +// packing pragmas removed to fix alignment issues. -PACKED_PUSH typedef struct keyframe_data { short Offset_x; /*Offset values may need to be scaled*/ short Offset_y; /*In practice scaling should only be needed for 'placed' hierarchies*/ short Offset_z; - + /* Quats */ QUAT_SHORT QOrient; + + /* + These have been moved from the end to here + to reduce padding. + */ + unsigned short Sequence_Length; /* Time between these values and the next ones. */ + struct keyframe_data *Next_Frame; /*This is no longer Null for the last frame - look at the last_frame setting instead*/ + /* int oneoversinomega; Removed oneoversinomega , since I can save a far amount of memory by doing so , and the value is just calculated using a lookup table anyway. -Richard */ - int oneoversequencelength; + int oneoversequencelength; + unsigned short omega:12; /* Quats */ unsigned short slerp_to_negative_quat:1; /*Should the slerping use the negative version of the next quaternion*/ @@ -96,12 +103,7 @@ typedef struct keyframe_data { unsigned short shift_offset:1; /*does offset need to be scaled*/ unsigned short last_frame:1; /*Is this the last frame?*/ - - unsigned short Sequence_Length; /* Time between these values and the next ones. */ - struct keyframe_data *Next_Frame; /*This is no longer Null for the last frame - look at the last_frame setting instead*/ -} PACKED KEYFRAME_DATA; -PACKED_POP - +} KEYFRAME_DATA; /*Two functions for extracting and setting the key frame offset */ extern void GetKeyFrameOffset(KEYFRAME_DATA* frame,VECTORCH* output_vector); diff --git a/src/avp/scream.cpp b/src/avp/scream.cpp index 46ea5e6..49626bd 100644 --- a/src/avp/scream.cpp +++ b/src/avp/scream.cpp @@ -1,3 +1,4 @@ +#include "unaligned.h" #include "3dc.h" #include "ourasert.h" #include "psndplat.h" @@ -98,9 +99,9 @@ void CharacterSoundEffects::LoadSounds(const char* filename,const char* director char* bufpos=buffer+8; - num_voice_types=*(int*)bufpos; + num_voice_types=*(unaligned_s32*)bufpos; bufpos+=4; - num_voice_cats=*(int*)bufpos; + num_voice_cats=*(unaligned_s32*)bufpos; bufpos+=4; voice_types=(ScreamVoiceType*) PoolAllocateMem(num_voice_types * sizeof(ScreamVoiceType)); @@ -116,7 +117,7 @@ void CharacterSoundEffects::LoadSounds(const char* filename,const char* director { ScreamSoundCategory* cat=&voice_types[i].category[j]; cat->last_sound=SID_NOSOUND; - cat->num_sounds=*(int*)bufpos; + cat->num_sounds=*(unaligned_s32*)bufpos; bufpos+=4; if(cat->num_sounds) @@ -135,9 +136,9 @@ void CharacterSoundEffects::LoadSounds(const char* filename,const char* director strcpy(wavname,bufpos); bufpos+=strlen(bufpos)+1; - sound->pitch=*(int*)bufpos; + sound->pitch=*(unaligned_s32*)bufpos; bufpos+=4; - sound->volume=*(int*)bufpos; + sound->volume=*(unaligned_s32*)bufpos; bufpos+=4; sound->sound_loaded=GetSound(wavpath); diff --git a/src/avp/stratdef.h b/src/avp/stratdef.h index 67360a7..6d57340 100644 --- a/src/avp/stratdef.h +++ b/src/avp/stratdef.h @@ -1,6 +1,8 @@ #ifndef _stratdef_h_ #define _stratdef_h_ 1 +#include "unaligned.h" + #ifdef __cplusplus extern "C" { @@ -277,17 +279,17 @@ extern STRATEGYBLOCK *ActiveStBlockList[]; #define COPY_NAME(name1, name2) \ { \ GLOBALASSERT(SB_NAME_LENGTH == 8); \ - *(int*)name1 = *(int*)name2; \ - *((int*)name1 + 1) = *((int*)name2 + 1);\ + *(unaligned_s32*)name1 = *(unaligned_s32*)name2; \ + *((unaligned_s32*)name1 + 1) = *((unaligned_s32*)name2 + 1);\ } #define NAME_ISEQUAL(name1, name2) \ - ((*(int*)name1 == *(int*)name2) && \ - (*(((int*)name1) + 1) == *(((int*)name2) + 1))) + ((*(unaligned_s32*)name1 == *(unaligned_s32*)name2) && \ + (*(((unaligned_s32*)name1) + 1) == *(((unaligned_s32*)name2) + 1))) #define NAME_ISNULL(name1) \ - ((*(int*)name1 == '\0') && \ - (*(((int*)name1) + 1) == '\0')) + ((*(unaligned_s32*)name1 == '\0') && \ + (*(((unaligned_s32*)name1) + 1) == '\0')) #ifdef __cplusplus diff --git a/src/avp/win95/frontend/avp_menus.c b/src/avp/win95/frontend/avp_menus.c index 5831da6..f77ec80 100644 --- a/src/avp/win95/frontend/avp_menus.c +++ b/src/avp/win95/frontend/avp_menus.c @@ -227,6 +227,162 @@ static const char* MultiplayerConfigurationName=0; //ditto extern int DebuggingCommandsActive; +int AvP_MainMenus_Init(void) +{ + #if 0 + SaveDefaultPrimaryConfigs(); + #else + LoadDefaultPrimaryConfigs(); + #endif + + SoundSys_ResetFadeLevel(); + SoundSys_Management(); + + TimeScale = ONE_FIXED; + + + + if (!LobbiedGame) // Edmond + CheckForCredits(); + + TimeStampedMessage("start of menus"); + // open a 640x480x16 screen + SelectMenuDisplayMode(); + TimeStampedMessage("after SelectMenuDisplayMode"); + + + + + + InitialiseMenuGfx(); + TimeStampedMessage("after InitialiseMenuGfx"); + + // inform backdrop code + InitMainMenusBackdrop(); + TimeStampedMessage("after InitMainMenusBackdrop"); + + + #if PREDATOR_DEMO||MARINE_DEMO||ALIEN_DEMO + if (AvP.LevelCompleted) + { + Show_WinnerScreen(); + } + #endif + + LoadAllAvPMenuGfx(); + TimeStampedMessage("after LoadAllAvPMenuGfx"); + + + + ResetFrameCounter(); + + if (!LobbiedGame) // Edmond + PlayIntroSequence(); + + if (VideoModeNotAvailable) + { + LoadGameRequest = SAVELOAD_REQUEST_NONE; + DisplayVideoModeUnavailableScreen(); + } + VideoModeNotAvailable = 0; + + if(AvP.LevelCompleted && CheatMode_Active == CHEATMODE_NONACTIVE && !DebuggingCommandsActive) + { + HandlePostGameFMVs(); + OkayToPlayNextEpisode(); + AvP.LevelCompleted = 0; + AvPMenus.MenusState = MENUSSTATE_MAINMENUS; + } + else if(!LobbiedGame) + { + if (UserProfileNumber==-1) + { + SetupNewMenu(AVPMENU_USERPROFILESELECT); + } + else + { + SetupNewMenu(AVPMENU_MAIN); + } + AvPMenus.MenusState = MENUSSTATE_MAINMENUS; + } + else + { + SetupNewMenu(AVPMENU_USERPROFILESELECT); + //AvPMenus.MenusState = MENUSSTATE_STARTGAME; + + } + + CheatMode_Active = CHEATMODE_NONACTIVE; + + + TimeStampedMessage("starting general menus"); + + return 0; +} + +int AvP_MainMenus_Update(void) { + CheckForWindowsMessages(); + DrawMainMenusBackdrop(); + ReadUserInput(); + AvP_UpdateMenus(); +// BezierCurve(); + + ShowMenuFrameRate(); + + FlipBuffers(); + FrameCounterHandler(); + PlayMenuMusic(); + #if 0 + { + extern int EffectsSoundVolume; + SoundSys_ChangeVolume(EffectsSoundVolume); + } + #endif + SoundSys_Management(); + UpdateGammaSettings(); + + CheckForLoadGame(); + + return AvPMenus.MenusState == MENUSSTATE_MAINMENUS; +} + +int AvP_MainMenus_Deinit(void) { + if (AvPMenus.MenusState==MENUSSTATE_OUTSIDEMENUS) + { + //Don't bother showing credits if we are just exiting in order to start a game + //using mplayer. The credits will get shown later after the player has actually + //played the game + if(!LaunchingMplayer) + { + if (!LobbiedGame) // Edmond + DoCredits(); + } + } + TimeStampedMessage("ready to exit menus"); + + EndMenuMusic(); + EndMenuBackgroundBink(); + TimeStampedMessage("after EndMenuMusic"); + + #if PREDATOR_DEMO||MARINE_DEMO||ALIEN_DEMO + if ((AvPMenus.MenusState != MENUSSTATE_STARTGAME)) ShowSplashScreens(); + TimeStampedMessage("after ShowSplashScreens"); + #endif + ReleaseAllAvPMenuGfx(); + + TimeStampedMessage("after ReleaseAllAvPMenuGfx"); + + SoundSys_StopAll(); + SoundSys_Management(); + + if (CheatMode_Active == CHEATMODE_NONACTIVE) HandlePreGameFMVs(); + + HandleCheatModeFeatures(); + AvP.LevelCompleted = 0; + + return (AvPMenus.MenusState == MENUSSTATE_STARTGAME); +} + int AvP_MainMenus(void) { #if 0 diff --git a/src/avp/win95/progress_bar.cpp b/src/avp/win95/progress_bar.cpp index e20ba30..80a5075 100644 --- a/src/avp/win95/progress_bar.cpp +++ b/src/avp/win95/progress_bar.cpp @@ -228,7 +228,8 @@ void Game_Has_Loaded(void) int f = 65536; ResetFrameCounter(); - do +#warning Game_Has_Loaded commented out a blocking loop + //do { CheckForWindowsMessages(); ReadUserInput(); @@ -284,7 +285,7 @@ void Game_Has_Loaded(void) } } - while(!DebouncedGotAnyKey); +// while(!DebouncedGotAnyKey); FadingGameInAfterLoading=ONE_FIXED; diff --git a/src/fixer.h b/src/fixer.h index 3d39012..5164542 100644 --- a/src/fixer.h +++ b/src/fixer.h @@ -76,6 +76,8 @@ extern "C" { #define _snprintf snprintf +#define __inline inline + size_t _mbclen(const unsigned char *s); #define RGBA_MAKE(r, g, b, a) ((((a) << 24) | ((r) << 16) | ((g) << 8) | (b))) diff --git a/src/fmv.c b/src/fmv.c index eea329b..5d7239f 100644 --- a/src/fmv.c +++ b/src/fmv.c @@ -288,7 +288,7 @@ void SetupFMVTexture(FMVTEXTURE *ftPtr) { if (ftPtr->PalettedBuf == NULL) { - ftPtr->PalettedBuf = (unsigned char*) malloc(128*128*4); + ftPtr->PalettedBuf = (unsigned char*) calloc(1, 128*128+128*128*4); } if (ftPtr->RGBBuf == NULL) @@ -300,6 +300,10 @@ void SetupFMVTexture(FMVTEXTURE *ftPtr) ftPtr->RGBBuf = &ftPtr->PalettedBuf[128*128]; } + + pglBindTexture(GL_TEXTURE_2D, ftPtr->ImagePtr->D3DTexture->id); + pglTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 128, 128, GL_RGBA, GL_UNSIGNED_BYTE, &ftPtr->RGBBuf[0]); + } void UpdateFMVTexture(FMVTEXTURE *ftPtr) @@ -327,16 +331,20 @@ void UpdateFMVTexture(FMVTEXTURE *ftPtr) unsigned char source = (*srcPtr++); dstPtr[0] = ftPtr->SrcPalette[source].peRed; dstPtr[1] = ftPtr->SrcPalette[source].peGreen; - dstPtr[2] = ftPtr->SrcPalette[source].peBlue; + dstPtr[2] = ftPtr->SrcPalette[source].peBlue; + dstPtr[3] = 255; - dstPtr += 3; + dstPtr += 4; } while(--pixels); //#warning move this into opengl.c // update the opengl texture pglBindTexture(GL_TEXTURE_2D, ftPtr->ImagePtr->D3DTexture->id); - pglTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 128, 96, GL_RGB, GL_UNSIGNED_BYTE, &ftPtr->RGBBuf[0]); + pglTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 128, 96, GL_RGBA, GL_UNSIGNED_BYTE, &ftPtr->RGBBuf[0]); + + // if using mipmaps, they will need to be updated now + //pglGenerateMipmap(GL_TEXTURE_2D); } void ReleaseFMVTexture(FMVTEXTURE *ftPtr) diff --git a/src/main.c b/src/main.c index f2d4dfe..8cbbc75 100644 --- a/src/main.c +++ b/src/main.c @@ -620,8 +620,6 @@ int SetOGLVideoMode(int Width, int Height) pglDepthFunc(GL_LEQUAL); pglDepthMask(GL_TRUE); pglDepthRange(0.0, 1.0); - - pglEnable(GL_TEXTURE_2D); pglDisable(GL_CULL_FACE); @@ -640,7 +638,7 @@ int SetOGLVideoMode(int Width, int Height) load_ogl_functions(1); - InitOpenGL(); + InitOpenGL(1); return 0; } diff --git a/src/main2.c b/src/main2.c index 46b47d5..46efa51 100644 --- a/src/main2.c +++ b/src/main2.c @@ -45,6 +45,9 @@ #include "version.h" #include "fmv.h" +#if EMSCRIPTEN +#include +#endif #if defined(__IPHONEOS__) || defined(__ANDROID__) #define FIXED_WINDOW_SIZE 1 @@ -54,6 +57,13 @@ #define USE_OPENGL_ES 1 #endif +#warning WINDOW_SIZE_DEBUG is on in all builds +#if 1 //!defined(NDEBUG) +#define WINDOW_SIZE_DEBUG +#endif + +static void main_loop(void); + void RE_ENTRANT_QUEUE_WinProc_AddMessage_WM_CHAR(char Ch); void RE_ENTRANT_QUEUE_WinProc_AddMessage_WM_KEYDOWN(int wParam); @@ -83,11 +93,15 @@ SDL_Joystick *joy; JOYINFOEX JoystickData; JOYCAPS JoystickCaps; +static int main_loop_state = 0; + // Window configuration and state static int WindowWidth; static int WindowHeight; static int ViewportWidth; static int ViewportHeight; +static int DrawableWidth; +static int DrawableHeight; enum RENDERING_MODE { RENDERING_MODE_SOFTWARE, @@ -111,12 +125,21 @@ static int WantMouseGrab = 0; // Additional configuration int WantSound = 1; static int WantCDRom = 0; -static int WantJoystick = 0; +static int WantJoystick = 1; static GLuint FullscreenTexture; static GLsizei FullscreenTextureWidth; static GLsizei FullscreenTextureHeight; +static GLuint FullscreenArrayBuffer; +static GLuint FullscreenElementArrayBuffer; + +static GLuint FramebufferTexture; +static GLsizei FramebufferTextureWidth; +static GLsizei FramebufferTextureHeight; +static GLuint FramebufferObject; +static GLuint FramebufferDepthObject; + /* originally was "/usr/lib/libGL.so.1:/usr/lib/tls/libGL.so.1:/usr/X11R6/lib/libGL.so" */ static const char * opengl_library = NULL; @@ -213,14 +236,14 @@ unsigned char *GetScreenShot24(int *width, int *height) } if (RenderingMode == RENDERING_MODE_OPENGL) { - buf = (unsigned char *)malloc(ViewportWidth * ViewportHeight * 3); + buf = (unsigned char *)malloc(DrawableWidth * DrawableHeight * 3); - *width = ViewportWidth; - *height = ViewportHeight; + *width = DrawableWidth; + *height = DrawableHeight; pglPixelStorei(GL_PACK_ALIGNMENT, 1); pglPixelStorei(GL_UNPACK_ALIGNMENT, 1); - pglReadPixels(0, 0, ViewportWidth, ViewportHeight, GL_RGB, GL_UNSIGNED_BYTE, buf); + pglReadPixels(0, 0, DrawableWidth, DrawableHeight, GL_RGB, GL_UNSIGNED_BYTE, buf); } else { buf = (unsigned char *)malloc(surface->w * surface->h * 3); @@ -415,6 +438,11 @@ char *GetVideoModeDescription3() int InitSDL() { +#if EMSCRIPTEN + printf("Setting main loop...\n"); + emscripten_set_main_loop(main_loop, 0, 0); +#endif + if (SDL_Init(SDL_INIT_VIDEO) < 0) { fprintf(stderr, "SDL Init failed: %s\n", SDL_GetError()); exit(EXIT_FAILURE); @@ -531,7 +559,7 @@ int InitSDL() return 0; } -#if !defined(NDEBUG) +#if defined(WINDOW_SIZE_DEBUG) static void DumpVideoModeInfo(SDL_Window* w) { int numVideoDisplays; int displayIndex; @@ -599,18 +627,27 @@ static void DumpVideoModeInfo(SDL_Window* w) { mode.h, mode.refresh_rate); } + + int width, height; + SDL_GetWindowSize(w, &width, &height); + printf("Window size: %4d,%4d\n", width, height); + + SDL_GL_GetDrawableSize(w, &width, &height); + printf("Window drawable size: %4d,%4d\n", width, height); } } #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); +#if defined(WINDOW_SIZE_DEBUG) + printf("SetWindowSize(%d,%d,%d,%d); %d\n", PhysicalWidth, PhysicalHeight, VirtualWidth, VirtualHeight, CurrentVideoMode); #endif ViewportWidth = PhysicalWidth; ViewportHeight = PhysicalHeight; + DrawableWidth = ViewportWidth; + DrawableHeight = ViewportHeight; ScreenDescriptorBlock.SDB_Width = VirtualWidth; ScreenDescriptorBlock.SDB_Height = VirtualHeight; @@ -626,10 +663,11 @@ static void SetWindowSize(int PhysicalWidth, int PhysicalHeight, int VirtualWidt if (window != NULL) { SDL_SetWindowSize(window, PhysicalWidth, PhysicalHeight); - //pglViewport(0, 0, ViewportWidth, ViewportHeight); + SDL_GL_GetDrawableSize(window, &DrawableWidth, &DrawableHeight); + pglViewport(0, 0, DrawableWidth, DrawableHeight); } -#if !defined(NDEBUG) +#if defined(WINDOW_SIZE_DEBUG) DumpVideoModeInfo(window); #endif } @@ -708,6 +746,8 @@ static int InitSDLVideo(void) { static int SetOGLVideoMode(int Width, int Height) { + GLenum status; + int firsttime = 0; int oldflags; int flags; @@ -725,9 +765,11 @@ static int SetOGLVideoMode(int Width, int Height) #endif if (window == NULL) { + firsttime = 1; + load_ogl_functions(0); - flags = SDL_WINDOW_OPENGL; + flags = SDL_WINDOW_OPENGL|SDL_WINDOW_ALLOW_HIGHDPI; #if defined(FIXED_WINDOW_SIZE) flags |= SDL_WINDOW_BORDERLESS; @@ -751,8 +793,8 @@ static int SetOGLVideoMode(int Width, int Height) // 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); + SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 2); + SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 0); #else SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 2); SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 1); @@ -795,7 +837,10 @@ static int SetOGLVideoMode(int Width, int Height) load_ogl_functions(1); - SDL_GetWindowSize(window, &Width, &Height); + SDL_GL_GetDrawableSize(window, &Width, &Height); +#if defined(WINDOW_SIZE_DEBUG) + printf("glViewport(0, 0, %d, %d)\n", Width, Height); +#endif pglViewport(0, 0, Width, Height); // create fullscreen window texture @@ -808,17 +853,79 @@ static int SetOGLVideoMode(int Width, int Height) 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; + FullscreenTextureWidth = 640; + FullscreenTextureHeight = 480; pglTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, FullscreenTextureWidth, FullscreenTextureHeight, 0, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, NULL); + + // this should be deleted and rebuilt when the screen size changes + GLint maxRenderbufferSize; + GLint maxTextureSize; + GLint maxViewportDims; + GLint maxRenderSize; + + pglGetIntegerv(GL_MAX_RENDERBUFFER_SIZE, &maxRenderbufferSize); + pglGetIntegerv(GL_MAX_TEXTURE_SIZE, &maxTextureSize); + pglGetIntegerv(GL_MAX_VIEWPORT_DIMS, &maxViewportDims); + printf("DEBUG:%d,%d,%d\n", maxRenderbufferSize, maxTextureSize, maxViewportDims); + + FramebufferTextureWidth = Width * 2; + FramebufferTextureHeight = Height * 2; + printf("DEBUG2:%d,%d\n", FramebufferTextureWidth, FramebufferTextureHeight); + + maxRenderSize = maxRenderbufferSize; + if (maxRenderSize > maxTextureSize) { + maxRenderSize = maxTextureSize; + } + if (maxRenderSize > maxViewportDims) { + maxRenderSize = maxViewportDims; + } + + if (FramebufferTextureWidth > maxRenderSize) { + FramebufferTextureWidth = maxRenderSize; + } + if (FramebufferTextureHeight > maxRenderSize) { + FramebufferTextureHeight = maxRenderSize; + } + printf("DEBUG3:%d,%d\n", FramebufferTextureWidth, FramebufferTextureHeight); + + pglGenTextures(1, &FramebufferTexture); + pglGenFramebuffers(1, &FramebufferObject); + pglGenRenderbuffers(1, &FramebufferDepthObject); + + pglBindTexture(GL_TEXTURE_2D, FramebufferTexture); + pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + pglTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, FramebufferTextureWidth, FramebufferTextureHeight, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL); + + pglBindTexture(GL_TEXTURE_2D, 0); + pglBindFramebuffer(GL_FRAMEBUFFER, FramebufferObject); + pglFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, FramebufferTexture, 0); + pglBindRenderbuffer(GL_RENDERBUFFER, FramebufferDepthObject); + pglRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, FramebufferTextureWidth, FramebufferTextureHeight); + pglFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, FramebufferDepthObject); + + pglGenBuffers(1, &FullscreenArrayBuffer); + pglGenBuffers(1, &FullscreenElementArrayBuffer); + + check_for_errors(); + + status = pglCheckFramebufferStatus(GL_FRAMEBUFFER); + if (status != GL_FRAMEBUFFER_COMPLETE) { + fprintf(stderr, "Incomplete framebuffer, status:%04x\n", status); + } + + pglBindFramebuffer(GL_FRAMEBUFFER, 0); + pglBindRenderbuffer(GL_RENDERBUFFER, 0); } SDL_GetWindowSize(window, &Width, &Height); - + SetWindowSize(Width, Height, Width, Height); int NewWidth, NewHeight; - SDL_GetWindowSize(window, &Width, &Height); + SDL_GetWindowSize(window, &NewWidth, &NewHeight); if (Width != NewWidth || Height != NewHeight) { //printf("Failed to change size: %d,%d vs. %d,%d\n", Width, Height, NewWidth, NewHeight); //Width = NewWidth; @@ -833,15 +940,15 @@ static int SetOGLVideoMode(int Width, int Height) pglDepthFunc(GL_LEQUAL); pglDepthMask(GL_TRUE); pglDepthRange(0.0, 1.0); - - pglEnable(GL_TEXTURE_2D); pglDisable(GL_CULL_FACE); pglClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - InitOpenGL(); + InitOpenGL(firsttime); + check_for_errors(); + return 0; } @@ -861,6 +968,16 @@ int ExitWindowsSystem() } FullscreenTexture = 0; + if (FullscreenArrayBuffer != 0) { + pglDeleteBuffers(1, &FullscreenArrayBuffer); + } + FullscreenArrayBuffer = 0; + + if (FullscreenElementArrayBuffer != 0) { + pglDeleteBuffers(1, &FullscreenElementArrayBuffer); + } + FullscreenElementArrayBuffer = 0; + load_ogl_functions(0); if (surface != NULL) { @@ -1224,7 +1341,9 @@ void CheckForWindowsMessages() // disable mouse grab? break; case SDL_WINDOWEVENT_RESIZED: - //printf("test, %d,%d\n", event.window.data1, event.window.data2); +#if defined(WINDOW_SIZE_DEBUG) + printf("Window Resized %d,%d\n", event.window.data1, event.window.data2); +#endif WindowWidth = event.window.data1; WindowHeight = event.window.data2; if (RenderingMode == RENDERING_MODE_SOFTWARE) { @@ -1233,6 +1352,7 @@ void CheckForWindowsMessages() SetWindowSize(WindowWidth, WindowHeight, WindowWidth, WindowHeight); } if (pglViewport != NULL) { + SDL_GL_GetDrawableSize(window, &WindowWidth, &WindowHeight); pglViewport(0, 0, WindowWidth, WindowHeight); } break; @@ -1342,25 +1462,43 @@ void CheckForWindowsMessages() void InGameFlipBuffers() { +#if !defined(NDEBUG) + check_for_errors(); +#endif + + pglBindFramebuffer(GL_FRAMEBUFFER, 0); + pglBindRenderbuffer(GL_RENDERBUFFER, 0); + pglViewport(0, 0, DrawableWidth, DrawableHeight); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + DrawFullscreenTexture(FramebufferTexture); + #if !defined(NDEBUG) check_for_errors(); #endif SDL_GL_SwapWindow(window); + + pglBindFramebuffer(GL_FRAMEBUFFER, FramebufferObject); + pglBindRenderbuffer(GL_RENDERBUFFER, FramebufferDepthObject); + pglViewport(0, 0, FramebufferTextureWidth, FramebufferTextureHeight); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); } void FlipBuffers() { + pglBindFramebuffer(GL_FRAMEBUFFER, 0); + pglBindRenderbuffer(GL_RENDERBUFFER, 0); + + pglViewport(0, 0, DrawableWidth, DrawableHeight); pglClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - pglDisable(GL_ALPHA_TEST); pglDisable(GL_BLEND); pglDisable(GL_DEPTH_TEST); 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); GLfloat x0; @@ -1373,22 +1511,22 @@ void FlipBuffers() GLfloat t1; // figure out the best way to fit the 640x480 virtual window - GLfloat a = ViewportHeight * 640.0f / 480.0f; - GLfloat b = ViewportWidth * 480.0f / 640.0f; + GLfloat a = DrawableHeight * 640.0f / 480.0f; + GLfloat b = DrawableWidth * 480.0f / 640.0f; - if (a <= ViewportWidth) { - // a x ViewportHeight window + if (a <= DrawableWidth) { + // a x DrawableHeight window y0 = -1.0f; y1 = 1.0f; - x1 = 1.0 - (ViewportWidth - a) / ViewportWidth; + x1 = 1.0 - (DrawableWidth - a) / DrawableWidth; x0 = -x1; } else { - // ViewportWidth x b window + // DrawableWidth x b window x0 = -1.0f; x1 = 1.0f; - y1 = 1.0 - (ViewportHeight - b) / ViewportHeight; + y1 = 1.0 - (DrawableHeight - b) / DrawableHeight; y0 = -y1; } @@ -1424,16 +1562,18 @@ void FlipBuffers() s[4] = 2; s[5] = 3; - pglEnableClientState(GL_VERTEX_ARRAY); - pglVertexPointer(2, GL_FLOAT, sizeof(GLfloat) * 4, &v[0]); + SelectProgram(AVP_SHADER_PROGRAM_NO_COLOR_NO_DISCARD); - pglEnableClientState(GL_TEXTURE_COORD_ARRAY); - pglTexCoordPointer(2, GL_FLOAT, sizeof(GLfloat) * 4, &v[2]); + // slow webgl compatibility changes + pglBindBuffer(GL_ARRAY_BUFFER, FullscreenArrayBuffer); + pglBindBuffer(GL_ELEMENT_ARRAY_BUFFER, FullscreenElementArrayBuffer); + pglBufferData(GL_ARRAY_BUFFER, sizeof(v), v, GL_STREAM_DRAW); + pglBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(s), s, GL_STREAM_DRAW); - pglDisableClientState(GL_COLOR_ARRAY); + pglVertexAttribPointer(OPENGL_VERTEX_ATTRIB_INDEX, 2, GL_FLOAT, GL_FALSE, 4*sizeof(GLfloat), (const GLvoid*) 0); + pglVertexAttribPointer(OPENGL_TEXCOORD_ATTRIB_INDEX, 2, GL_FLOAT, GL_FALSE, 4*sizeof(GLfloat), (const GLvoid*) 8); - pglColor4f(1.0f, 1.0f, 1.0f, 1.0f); - pglDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, s); + pglDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, (const GLvoid*) 0); pglBindTexture(GL_TEXTURE_2D, 0); @@ -1478,6 +1618,10 @@ static const char *usage_string = " [-j | --nojoy] Do not access the joystick\n" " [-g | --withgl] [x] Use [x] instead of /usr/lib/libGL.so.1 for OpenGL\n" ; + +static int menusActive = 0; +static int thisLevelHasBeenCompleted = 0; + int main(int argc, char *argv[]) { @@ -1534,7 +1678,7 @@ int main(int argc, char *argv[]) LoadCDTrackList(); SetFastRandom(); - + #if MARINE_DEMO ffInit("fastfile/mffinfo.txt","fastfile/"); #elif ALIEN_DEMO @@ -1553,7 +1697,7 @@ int main(int argc, char *argv[]) /* Env_List can probably be removed */ Env_List[0]->main = LevelName; - + InitialiseSystem(); InitialiseRenderer(); @@ -1584,14 +1728,18 @@ int main(int argc, char *argv[]) SetLevelToLoad(AVP_ENVIRONMENT_INVASION); #endif + main_loop_state = 1; + return 0; + +#if 0 #if !(ALIEN_DEMO|PREDATOR_DEMO|MARINE_DEMO) while (AvP_MainMenus()) #else if (AvP_MainMenus()) #endif { - int menusActive = 0; - int thisLevelHasBeenCompleted = 0; + menusActive = 0; + thisLevelHasBeenCompleted = 0; /* turn off any special effects */ d3d_light_ctrl.ctrl = LCCM_NORMAL; @@ -1742,9 +1890,10 @@ if (AvP_MainMenus()) /* go back to menu mode */ #if !(ALIEN_DEMO|PREDATOR_DEMO|MARINE_DEMO) SetSoftVideoMode(640, 480, 16); -#endif +#endif } +#if !EMSCRIPTEN SoundSys_StopAll(); SoundSys_RemoveAll(); @@ -1752,6 +1901,241 @@ if (AvP_MainMenus()) CDDA_End(); ClearMemoryPool(); +#endif +#endif + return 0; +} + +int AvP_MainMenus_Init(void); +int AvP_MainMenus_Update(void); +int AvP_MainMenus_Deinit(void); + +static int MainGame_Init(void); +static int MainGame_Update(void); +static int MainGame_Deinit(void); + +static void main_loop(void) { + switch (main_loop_state) { + case 0: + return; + + case -1: + printf("You can't exit the game!\n"); + main_loop_state = 0; + return; + + case -999: + printf("Unimplemented!\n"); + main_loop_state = 0; + return; + + case 1: + AvP_MainMenus_Init(); + main_loop_state = 2; + // fallthrough + case 2: { + int cont = AvP_MainMenus_Update(); + if (cont != 0) { + return; + } + } + // fallthrough + + case 3: { + int cont = AvP_MainMenus_Deinit(); + if (cont != 0) { + main_loop_state = 4; + return; + } + } + main_loop_state = -1; + return; + + case 4: { + MainGame_Init(); + main_loop_state = 5; + // fallthrough + } + + case 5: { + int cont = MainGame_Update(); + if (cont != 0) { + return; + } + // fallthrough + } + + case 6: { + MainGame_Deinit(); + main_loop_state = 1; + } + + } +} + +static int MainGame_Init(void) { + menusActive = 0; + thisLevelHasBeenCompleted = 0; + + /* turn off any special effects */ + d3d_light_ctrl.ctrl = LCCM_NORMAL; + + SetOGLVideoMode(0, 0); + + InitialiseGammaSettings(RequestedGammaSetting); + + start_of_loaded_shapes = load_precompiled_shapes(); + + InitCharacter(); + + LoadRifFile(); /* sets up a map */ + + AssignAllSBNames(); + + StartGame(); + + ffcloseall(); + + AvP.MainLoopRunning = 1; + + ScanImagesForFMVs(); + + ResetFrameCounter(); + + Game_Has_Loaded(); + + ResetFrameCounter(); + + if(AvP.Network!=I_No_Network) + { + /*Need to choose a starting position for the player , but first we must look + through the network messages to find out which generator spots are currently clear*/ + netGameData.myGameState = NGS_Playing; + MinimalNetCollectMessages(); + TeleportNetPlayerToAStartingPosition(Player->ObStrategyBlock,1); + } + + IngameKeyboardInput_ClearBuffer(); + + return 0; +} + +static int MainGame_Update(void) { + if(AvP.MainLoopRunning) { + CheckForWindowsMessages(); + + switch(AvP.GameMode) { + case I_GM_Playing: + if ((!menusActive || (AvP.Network!=I_No_Network && !netGameData.skirmishMode)) && !AvP.LevelCompleted) { + /* TODO: print some debugging stuff */ + + DoAllShapeAnimations(); + + UpdateGame(); + + AvpShowViews(); + + MaintainHUD(); + + CheckCDAndChooseTrackIfNeeded(); + + if(InGameMenusAreRunning() && ( (AvP.Network!=I_No_Network && netGameData.skirmishMode) || (AvP.Network==I_No_Network)) ) { + SoundSys_StopAll(); + } + } else { + ReadUserInput(); + + SoundSys_Management(); + + FlushD3DZBuffer(); + + ThisFramesRenderingHasBegun(); + } + + menusActive = AvP_InGameMenus(); + if (AvP.RestartLevel) menusActive=0; + + if (AvP.LevelCompleted) { + SoundSys_FadeOutFast(); + DoCompletedLevelStatisticsScreen(); + thisLevelHasBeenCompleted = 1; + } + + ThisFramesRenderingHasFinished(); + + InGameFlipBuffers(); + + FrameCounterHandler(); + { + PLAYER_STATUS *playerStatusPtr = (PLAYER_STATUS *) (Player->ObStrategyBlock->SBdataptr); + + if (!menusActive && playerStatusPtr->IsAlive && !AvP.LevelCompleted) { + DealWithElapsedTime(); + } + } + break; + + case I_GM_Menus: + AvP.GameMode = I_GM_Playing; + break; + default: + fprintf(stderr, "AvP.MainLoopRunning: gamemode = %d\n", AvP.GameMode); + exit(EXIT_FAILURE); + } + + if (AvP.RestartLevel) { + AvP.RestartLevel = 0; + AvP.LevelCompleted = 0; + + FixCheatModesInUserProfile(UserProfilePtr); + + RestartLevel(); + } + } + + return AvP.MainLoopRunning; +} + +static int MainGame_Deinit(void) { + + AvP.LevelCompleted = thisLevelHasBeenCompleted; + + FixCheatModesInUserProfile(UserProfilePtr); + + ReleaseAllFMVTextures(); + + CONSBIND_WriteKeyBindingsToConfigFile(); + + DeInitialisePlayer(); + + DeallocatePlayersMirrorImage(); + + KillHUD(); + + Destroy_CurrentEnvironment(); + + DeallocateAllImages(); + + EndNPCs(); + + ExitGame(); + + SoundSys_StopAll(); + + SoundSys_ResetFadeLevel(); + + CDDA_Stop(); + + if (AvP.Network != I_No_Network) { + EndAVPNetGame(); + } + + ClearMemoryPool(); + +/* go back to menu mode */ +#if !(ALIEN_DEMO|PREDATOR_DEMO|MARINE_DEMO) + SetSoftVideoMode(640, 480, 16); +#endif return 0; } diff --git a/src/mathline.h b/src/mathline.h index b1620a5..0205e9f 100644 --- a/src/mathline.h +++ b/src/mathline.h @@ -31,7 +31,7 @@ them though. */ -static inline int MUL_FIXED(int a, int b) +static __inline int MUL_FIXED(int a, int b) { /* int retval; diff --git a/src/menus.c b/src/menus.c index 1679d00..6c862a2 100644 --- a/src/menus.c +++ b/src/menus.c @@ -374,7 +374,7 @@ int LengthOfMenuText(const char *textPtr) int width = 0; while (textPtr && *textPtr) { - width += IntroFont_Light.FontWidth[(unsigned int) *textPtr]; + width += IntroFont_Light.FontWidth[(unsigned char) *textPtr]; textPtr++; } @@ -386,7 +386,7 @@ int LengthOfSmallMenuText(char *textPtr) int width = 0; while (textPtr && *textPtr) { - width += AAFontWidths[(unsigned int) *textPtr]; + width += AAFontWidths[(unsigned char) *textPtr]; textPtr++; } @@ -445,7 +445,7 @@ int RenderMenuText(const char *textPtr, int sx, int sy, int alpha, enum AVPMENUF 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 width = IntroFont_Light.FontWidth[(unsigned char) c]; unsigned int remainder = 0; unsigned int stride = width; @@ -550,7 +550,7 @@ int RenderMenuText_Clipped(char *textPtr, int sx, int sy, int alpha, enum AVPMEN 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 width = IntroFont_Light.FontWidth[(unsigned char) c]; unsigned int remainder = 0; unsigned int stride = width; @@ -665,7 +665,7 @@ static int RenderSmallFontString(char *textPtr,int sx,int sy,int alpha, int red, } srcPtr += (image->w - HUD_FONT_WIDTH) * 4; } - sx += AAFontWidths[(unsigned int) c]; + sx += AAFontWidths[(unsigned char) c]; } } @@ -699,11 +699,11 @@ Determine area used by text , so we can draw it centrally int widthFromChars=0; while(*textPtr2 && *textPtr2==' ') { - widthFromSpaces+=AAFontWidths[(unsigned int) *textPtr2++]; + widthFromSpaces+=AAFontWidths[(unsigned char) *textPtr2++]; } while(*textPtr2 && *textPtr2!=' ') { - widthFromChars+=AAFontWidths[(unsigned int) *textPtr2++]; + widthFromChars+=AAFontWidths[(unsigned char) *textPtr2++]; } wordWidth=widthFromSpaces+widthFromChars; @@ -762,11 +762,11 @@ Determine area used by text , so we can draw it centrally wordWidth=0; while(*textPtr2 && *textPtr2==' ') { - wordWidth+=AAFontWidths[(unsigned int) *textPtr2++]; + wordWidth+=AAFontWidths[(unsigned char) *textPtr2++]; } while(*textPtr2 && *textPtr2!=' ') { - wordWidth+=AAFontWidths[(unsigned int) *textPtr2++]; + wordWidth+=AAFontWidths[(unsigned char) *textPtr2++]; } if(wordWidth> area->right-sx) { @@ -790,7 +790,7 @@ Determine area used by text , so we can draw it centrally } while(*textPtr && *textPtr==' ') { - sx+=AAFontWidths[(unsigned int) *textPtr++]; + sx+=AAFontWidths[(unsigned char) *textPtr++]; } if(sx>area->right) { @@ -804,7 +804,7 @@ Determine area used by text , so we can draw it centrally while(*textPtr && *textPtr!=' ') { char c = *textPtr++; - int letterWidth = AAFontWidths[(unsigned int) c]; + int letterWidth = AAFontWidths[(unsigned char) c]; if(sx+letterWidth>area->right) { sx=area->left; @@ -847,7 +847,7 @@ Determine area used by text , so we can draw it centrally } srcPtr += (image->w - HUD_FONT_WIDTH) * 4; } - sx += AAFontWidths[(unsigned int) c]; + sx += AAFontWidths[(unsigned char) c]; } } } @@ -876,7 +876,7 @@ int RenderSmallMenuText(char *textPtr, int x, int y, int alpha, enum AVPMENUFORM ptr = textPtr; while (*ptr) { - length+=AAFontWidths[(unsigned int) *ptr++]; + length+=AAFontWidths[(unsigned char) *ptr++]; } x -= length; @@ -886,7 +886,7 @@ int RenderSmallMenuText(char *textPtr, int x, int y, int alpha, enum AVPMENUFORM ptr = textPtr; while (*ptr) { - length+=AAFontWidths[(unsigned int) *ptr++]; + length+=AAFontWidths[(unsigned char) *ptr++]; } x -= length / 2; @@ -914,7 +914,7 @@ int RenderSmallMenuText_Coloured(char *textPtr, int x, int y, int alpha, enum AV ptr = textPtr; while (*ptr) { - length+=AAFontWidths[(unsigned int) *ptr++]; + length+=AAFontWidths[(unsigned char) *ptr++]; } x -= length; @@ -924,7 +924,7 @@ int RenderSmallMenuText_Coloured(char *textPtr, int x, int y, int alpha, enum AV ptr = textPtr; while (*ptr) { - length+=AAFontWidths[(unsigned int) *ptr++]; + length+=AAFontWidths[(unsigned char) *ptr++]; } x -= length / 2; diff --git a/src/oglfunc.c b/src/oglfunc.c index d1ada9a..fba8fe6 100644 --- a/src/oglfunc.c +++ b/src/oglfunc.c @@ -1,3 +1,4 @@ +#include #include #include @@ -5,51 +6,86 @@ #include "oglfunc.h" -PFNGLALPHAFUNCPROC pglAlphaFunc; -PFNGLBINDTEXTUREPROC pglBindTexture; -PFNGLBLENDFUNCPROC pglBlendFunc; -PFNGLCLEARPROC pglClear; -PFNGLCLEARCOLORPROC pglClearColor; -PFNGLCOLOR4FPROC pglColor4f; -PFNGLCOLORPOINTERPROC pglColorPointer; -PFNGLCULLFACEPROC pglCullFace; -PFNGLDELETETEXTURESPROC pglDeleteTextures; -PFNGLDEPTHFUNCPROC pglDepthFunc; -PFNGLDEPTHMASKPROC pglDepthMask; -PFNGLDEPTHRANGEPROC pglDepthRange; -PFNGLDISABLEPROC pglDisable; -PFNGLDISABLECLIENTSTATEPROC pglDisableClientState; -PFNGLDRAWELEMENTSPROC pglDrawElements; -PFNGLENABLEPROC pglEnable; -PFNGLENABLECLIENTSTATEPROC pglEnableClientState; -PFNGLFRONTFACEPROC pglFrontFace; -PFNGLGENTEXTURESPROC pglGenTextures; -PFNGLGETERRORPROC pglGetError; -PFNGLGETFLOATVPROC pglGetFloatv; -PFNGLGETINTEGERVPROC pglGetIntegerv; -PFNGLGETSTRINGPROC pglGetString; -PFNGLGETTEXPARAMETERFVPROC pglGetTexParameterfv; -PFNGLHINTPROC pglHint; -PFNGLPIXELSTOREIPROC pglPixelStorei; -PFNGLPOLYGONOFFSETPROC pglPolygonOffset; -PFNGLREADPIXELSPROC pglReadPixels; -PFNGLSHADEMODELPROC pglShadeModel; -PFNGLTEXCOORDPOINTERPROC pglTexCoordPointer; -PFNGLTEXENVFPROC pglTexEnvf; -PFNGLTEXENVFVPROC pglTexEnvfv; -PFNGLTEXENVIPROC pglTexEnvi; -PFNGLTEXIMAGE2DPROC pglTexImage2D; -PFNGLTEXPARAMETERFPROC pglTexParameterf; -PFNGLTEXPARAMETERIPROC pglTexParameteri; -PFNGLTEXSUBIMAGE2DPROC pglTexSubImage2D; -PFNGLVERTEXPOINTERPROC pglVertexPointer; -PFNGLVIEWPORTPROC pglViewport; +// Base OpenGL / OpenGL ES +avpPFNGLACTIVETEXTUREPROC pglActiveTexture; +avpPFNGLBINDTEXTUREPROC pglBindTexture; +avpPFNGLBLENDFUNCPROC pglBlendFunc; +avpPFNGLCLEARPROC pglClear; +avpPFNGLCLEARCOLORPROC pglClearColor; +avpPFNGLCULLFACEPROC pglCullFace; +avpPFNGLDELETETEXTURESPROC pglDeleteTextures; +avpPFNGLDEPTHFUNCPROC pglDepthFunc; +avpPFNGLDEPTHMASKPROC pglDepthMask; +avpPFNGLDEPTHRANGEPROC pglDepthRange; +avpPFNGLDISABLEPROC pglDisable; +avpPFNGLDRAWELEMENTSPROC pglDrawElements; +avpPFNGLENABLEPROC pglEnable; +avpPFNGLFRONTFACEPROC pglFrontFace; +avpPFNGLGENTEXTURESPROC pglGenTextures; +avpPFNGLGETERRORPROC pglGetError; +avpPFNGLGETFLOATVPROC pglGetFloatv; +avpPFNGLGETINTEGERVPROC pglGetIntegerv; +avpPFNGLGETSTRINGPROC pglGetString; +avpPFNGLGETTEXPARAMETERFVPROC pglGetTexParameterfv; +avpPFNGLHINTPROC pglHint; +avpPFNGLPIXELSTOREIPROC pglPixelStorei; +avpPFNGLPOLYGONOFFSETPROC pglPolygonOffset; +avpPFNGLREADPIXELSPROC pglReadPixels; +avpPFNGLTEXIMAGE2DPROC pglTexImage2D; +avpPFNGLTEXPARAMETERFPROC pglTexParameterf; +avpPFNGLTEXPARAMETERIPROC pglTexParameteri; +avpPFNGLTEXSUBIMAGE2DPROC pglTexSubImage2D; +avpPFNGLVIEWPORTPROC pglViewport; + +// OpenGL 2.1 / OpenGL ES 2.0 +avpPFNGLATTACHSHADERPROC pglAttachShader; +avpPFNGLBINDATTRIBLOCATIONPROC pglBindAttribLocation; +avpPFNGLBINDBUFFERPROC pglBindBuffer; +avpPFNGLBUFFERDATAPROC pglBufferData; +avpPFNGLBUFFERSUBDATAPROC pglBufferSubData; +avpPFNGLCREATEPROGRAMPROC pglCreateProgram; +avpPFNGLCREATESHADERPROC pglCreateShader; +avpPFNGLCOMPILESHADERPROC pglCompileShader; +avpPFNGLDELETEBUFFERSPROC pglDeleteBuffers; +avpPFNGLDELETEPROGRAMPROC pglDeleteProgram; +avpPFNGLDELETESHADERPROC pglDeleteShader; +avpPFNGLDISABLEVERTEXATTRIBARRAYPROC pglDisableVertexAttribArray; +avpPFNGLENABLEVERTEXATTRIBARRAYPROC pglEnableVertexAttribArray; +avpPFNGLGENBUFFERSPROC pglGenBuffers; +avpPFNGLGETATTRIBLOCATIONPROC pglGetAttribLocation; +avpPFNGLGETPROGRAMINFOLOGPROC pglGetProgramInfoLog; +avpPFNGLGETPROGRAMIVPROC pglGetProgramiv; +avpPFNGLGETSHADERINFOLOGPROC pglGetShaderInfoLog; +avpPFNGLGETSHADERIVPROC pglGetShaderiv; +avpPFNGLGETUNIFORMLOCATIONPROC pglGetUniformLocation; +avpPFNGLLINKPROGRAMPROC pglLinkProgram; +avpPFNGLSHADERSOURCEPROC pglShaderSource; +avpPFNGLVALIDATEPROGRAMPROC pglValidateProgram; +avpPFNGLVERTEXATTRIBPOINTERPROC pglVertexAttribPointer; +avpPFNGLUNIFORM1IPROC pglUniform1i; +avpPFNGLUNIFORMMATRIX4FVPROC pglUniformMatrix4fv; +avpPFNGLUSEPROGRAMPROC pglUseProgram; + +// GL_EXT_framebuffer_object / GL_ARB_framebuffer_object / OpenGL ES 2.0 +avpPFNGLBINDFRAMEBUFFERPROC pglBindFramebuffer; +avpPFNGLBINDRENDERBUFFERPROC pglBindRenderbuffer; +avpPFNGLCHECKFRAMEBUFFERSTATUSPROC pglCheckFramebufferStatus; +avpPFNGLDELETEFRAMEBUFFERSPROC pglDeleteFramebuffers; +avpPFNGLDELETERENDERBUFFERSPROC pglDeleteRenderbuffers; +avpPFNGLFRAMEBUFFERRENDERBUFFERPROC pglFramebufferRenderbuffer; +avpPFNGLFRAMEBUFFERTEXTURE2DPROC pglFramebufferTexture2D; +avpPFNGLGENERATEMIPMAPPROC pglGenerateMipmap; +avpPFNGLGENFRAMEBUFFERSPROC pglGenFramebuffers; +avpPFNGLGENRENDERBUFFERSPROC pglGenRenderbuffers; +avpPFNGLRENDERBUFFERSTORAGEPROC pglRenderbufferStorage; int ogl_have_multisample_filter_hint; int ogl_have_texture_filter_anisotropic; +int ogl_have_framebuffer_object; int ogl_use_multisample_filter_hint; int ogl_use_texture_filter_anisotropic; +int ogl_use_framebuffer_object; static void dummyfunc() { @@ -73,6 +109,20 @@ static void dummyfunc() LoadOGLProc_(type, func1, func2); \ } +#define LoadOGLExtProc(e, type, func) \ + if ((e)) { \ + LoadOGLProc(type, func); \ + } else { \ + p##func = NULL; \ + } + +#define LoadOGLExtProc2(e, type, func1, func2) \ + if ((e)) { \ + LoadOGLProc2(type, func1, func2); \ + } else { \ + p##func = NULL; \ + } + static int check_token(const char *string, const char *token) { const char *s = string; @@ -98,47 +148,71 @@ void load_ogl_functions(int mode) const char* ogl_missing_func; const char* ext; + int base_framebuffer_object; + int ext_framebuffer_object; + int arb_framebuffer_object; + ogl_missing_func = NULL; - LoadOGLProc(PFNGLALPHAFUNCPROC, glAlphaFunc); - LoadOGLProc(PFNGLBINDTEXTUREPROC, glBindTexture); - LoadOGLProc(PFNGLBLENDFUNCPROC, glBlendFunc); - LoadOGLProc(PFNGLCLEARPROC, glClear); - LoadOGLProc(PFNGLCLEARCOLORPROC, glClearColor); - LoadOGLProc(PFNGLCOLOR4FPROC, glColor4f); - LoadOGLProc(PFNGLCOLORPOINTERPROC, glColorPointer); - LoadOGLProc(PFNGLCULLFACEPROC, glCullFace); - LoadOGLProc(PFNGLDELETETEXTURESPROC, glDeleteTextures); - LoadOGLProc(PFNGLDEPTHFUNCPROC, glDepthFunc); - LoadOGLProc(PFNGLDEPTHMASKPROC, glDepthMask); - LoadOGLProc2(PFNGLDEPTHRANGEPROC, glDepthRange, glDepthRangef); - LoadOGLProc(PFNGLDISABLEPROC, glDisable); - LoadOGLProc(PFNGLDISABLECLIENTSTATEPROC, glDisableClientState); - LoadOGLProc(PFNGLDRAWELEMENTSPROC, glDrawElements); - LoadOGLProc(PFNGLENABLEPROC, glEnable); - LoadOGLProc(PFNGLENABLECLIENTSTATEPROC, glEnableClientState); - LoadOGLProc(PFNGLFRONTFACEPROC, glFrontFace); - LoadOGLProc(PFNGLGENTEXTURESPROC, glGenTextures); - LoadOGLProc(PFNGLGETERRORPROC, glGetError); - LoadOGLProc(PFNGLGETFLOATVPROC, glGetFloatv); - LoadOGLProc(PFNGLGETINTEGERVPROC, glGetIntegerv); - LoadOGLProc(PFNGLGETSTRINGPROC, glGetString); - LoadOGLProc(PFNGLGETTEXPARAMETERFVPROC, glGetTexParameterfv); - LoadOGLProc(PFNGLHINTPROC, glHint); - LoadOGLProc(PFNGLPIXELSTOREIPROC, glPixelStorei); - LoadOGLProc(PFNGLPOLYGONOFFSETPROC, glPolygonOffset); - LoadOGLProc(PFNGLREADPIXELSPROC, glReadPixels); - LoadOGLProc(PFNGLSHADEMODELPROC, glShadeModel); - LoadOGLProc(PFNGLTEXCOORDPOINTERPROC, glTexCoordPointer); - LoadOGLProc(PFNGLTEXENVFPROC, glTexEnvf); - LoadOGLProc(PFNGLTEXENVFVPROC, glTexEnvfv); - LoadOGLProc(PFNGLTEXENVIPROC, glTexEnvi); - LoadOGLProc(PFNGLTEXIMAGE2DPROC, glTexImage2D); - LoadOGLProc(PFNGLTEXPARAMETERFPROC, glTexParameterf); - LoadOGLProc(PFNGLTEXPARAMETERIPROC, glTexParameteri); - LoadOGLProc(PFNGLTEXSUBIMAGE2DPROC, glTexSubImage2D); - LoadOGLProc(PFNGLVERTEXPOINTERPROC, glVertexPointer); - LoadOGLProc(PFNGLVIEWPORTPROC, glViewport); + // Base OpenGL / OpenGL ES + LoadOGLProc(avpPFNGLACTIVETEXTUREPROC, glActiveTexture); + LoadOGLProc(avpPFNGLBINDTEXTUREPROC, glBindTexture); + LoadOGLProc(avpPFNGLBLENDFUNCPROC, glBlendFunc); + LoadOGLProc(avpPFNGLCLEARPROC, glClear); + LoadOGLProc(avpPFNGLCLEARCOLORPROC, glClearColor); + LoadOGLProc(avpPFNGLCULLFACEPROC, glCullFace); + LoadOGLProc(avpPFNGLDELETETEXTURESPROC, glDeleteTextures); + LoadOGLProc(avpPFNGLDEPTHFUNCPROC, glDepthFunc); + LoadOGLProc(avpPFNGLDEPTHMASKPROC, glDepthMask); + LoadOGLProc2(avpPFNGLDEPTHRANGEPROC, glDepthRange, glDepthRangef); + LoadOGLProc(avpPFNGLDISABLEPROC, glDisable); + LoadOGLProc(avpPFNGLDRAWELEMENTSPROC, glDrawElements); + LoadOGLProc(avpPFNGLENABLEPROC, glEnable); + LoadOGLProc(avpPFNGLFRONTFACEPROC, glFrontFace); + LoadOGLProc(avpPFNGLGENTEXTURESPROC, glGenTextures); + LoadOGLProc(avpPFNGLGETERRORPROC, glGetError); + LoadOGLProc(avpPFNGLGETFLOATVPROC, glGetFloatv); + LoadOGLProc(avpPFNGLGETINTEGERVPROC, glGetIntegerv); + LoadOGLProc(avpPFNGLGETSTRINGPROC, glGetString); + LoadOGLProc(avpPFNGLGETTEXPARAMETERFVPROC, glGetTexParameterfv); + LoadOGLProc(avpPFNGLHINTPROC, glHint); + LoadOGLProc(avpPFNGLPIXELSTOREIPROC, glPixelStorei); + LoadOGLProc(avpPFNGLPOLYGONOFFSETPROC, glPolygonOffset); + LoadOGLProc(avpPFNGLREADPIXELSPROC, glReadPixels); + LoadOGLProc(avpPFNGLTEXIMAGE2DPROC, glTexImage2D); + LoadOGLProc(avpPFNGLTEXPARAMETERFPROC, glTexParameterf); + LoadOGLProc(avpPFNGLTEXPARAMETERIPROC, glTexParameteri); + LoadOGLProc(avpPFNGLTEXSUBIMAGE2DPROC, glTexSubImage2D); + LoadOGLProc(avpPFNGLVIEWPORTPROC, glViewport); + + // OpenGL 2.1 / OpenGL ES 2.0 + LoadOGLProc(avpPFNGLATTACHSHADERPROC, glAttachShader); + LoadOGLProc(avpPFNGLBINDATTRIBLOCATIONPROC, glBindAttribLocation); + LoadOGLProc(avpPFNGLBINDBUFFERPROC, glBindBuffer); + LoadOGLProc(avpPFNGLBUFFERDATAPROC, glBufferData); + LoadOGLProc(avpPFNGLBUFFERSUBDATAPROC, glBufferSubData); + LoadOGLProc(avpPFNGLCREATEPROGRAMPROC, glCreateProgram); + LoadOGLProc(avpPFNGLCREATESHADERPROC, glCreateShader); + LoadOGLProc(avpPFNGLCOMPILESHADERPROC, glCompileShader); + LoadOGLProc(avpPFNGLDELETEBUFFERSPROC, glDeleteBuffers); + LoadOGLProc(avpPFNGLDELETEPROGRAMPROC, glDeleteProgram); + LoadOGLProc(avpPFNGLDELETESHADERPROC, glDeleteShader); + LoadOGLProc(avpPFNGLDISABLEVERTEXATTRIBARRAYPROC, glDisableVertexAttribArray); + LoadOGLProc(avpPFNGLENABLEVERTEXATTRIBARRAYPROC, glEnableVertexAttribArray); + LoadOGLProc(avpPFNGLGENBUFFERSPROC, glGenBuffers); + LoadOGLProc(avpPFNGLGETATTRIBLOCATIONPROC, glGetAttribLocation); + LoadOGLProc(avpPFNGLGETPROGRAMINFOLOGPROC, glGetProgramInfoLog); + LoadOGLProc(avpPFNGLGETPROGRAMIVPROC, glGetProgramiv); + LoadOGLProc(avpPFNGLGETSHADERINFOLOGPROC, glGetShaderInfoLog); + LoadOGLProc(avpPFNGLGETSHADERIVPROC, glGetShaderiv); + LoadOGLProc(avpPFNGLGETUNIFORMLOCATIONPROC, glGetUniformLocation); + LoadOGLProc(avpPFNGLLINKPROGRAMPROC, glLinkProgram); + LoadOGLProc(avpPFNGLSHADERSOURCEPROC, glShaderSource); + LoadOGLProc(avpPFNGLVALIDATEPROGRAMPROC, glValidateProgram); + LoadOGLProc(avpPFNGLVERTEXATTRIBPOINTERPROC, glVertexAttribPointer); + LoadOGLProc(avpPFNGLUNIFORM1IPROC, glUniform1i); + LoadOGLProc(avpPFNGLUNIFORMMATRIX4FVPROC, glUniformMatrix4fv); + LoadOGLProc(avpPFNGLUSEPROGRAMPROC, glUseProgram); if (!mode) { return; @@ -153,17 +227,74 @@ void load_ogl_functions(int mode) 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_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); + // GL_EXT_framebuffer_object / GL_ARB_framebuffer_object / OpenGL ES 2.0 + // figure out which version of framebuffer objects to use, if any + ext_framebuffer_object = check_token(ext, "GL_EXT_framebuffer_object"); + arb_framebuffer_object = check_token(ext, "GL_ARB_framebuffer_object"); + +#if defined(USE_OPENGL_ES) + // not quite right as ARB fbo includes functionality not present in ES2. + base_framebuffer_object = 1; +#else + base_framebuffer_object = arb_framebuffer_object; +#endif + + ogl_missing_func = NULL; + LoadOGLExtProc(base_framebuffer_object, avpPFNGLBINDFRAMEBUFFERPROC, glBindFramebuffer); + LoadOGLExtProc(base_framebuffer_object, avpPFNGLBINDRENDERBUFFERPROC, glBindRenderbuffer); + LoadOGLExtProc(base_framebuffer_object, avpPFNGLCHECKFRAMEBUFFERSTATUSPROC, glCheckFramebufferStatus); + LoadOGLExtProc(base_framebuffer_object, avpPFNGLDELETEFRAMEBUFFERSPROC, glDeleteFramebuffers); + LoadOGLExtProc(base_framebuffer_object, avpPFNGLDELETERENDERBUFFERSPROC, glDeleteRenderbuffers); + LoadOGLExtProc(base_framebuffer_object, avpPFNGLFRAMEBUFFERRENDERBUFFERPROC, glFramebufferRenderbuffer); + LoadOGLExtProc(base_framebuffer_object, avpPFNGLFRAMEBUFFERTEXTURE2DPROC, glFramebufferTexture2D); + LoadOGLExtProc(base_framebuffer_object, avpPFNGLGENERATEMIPMAPPROC, glGenerateMipmap); + LoadOGLExtProc(base_framebuffer_object, avpPFNGLGENFRAMEBUFFERSPROC, glGenFramebuffers); + LoadOGLExtProc(base_framebuffer_object, avpPFNGLGENRENDERBUFFERSPROC, glGenRenderbuffers); + LoadOGLExtProc(base_framebuffer_object, avpPFNGLRENDERBUFFERSTORAGEPROC, glRenderbufferStorage); + if (base_framebuffer_object != 0 && ogl_missing_func == NULL) { + ogl_have_framebuffer_object = 1; + +#if !defined(NDEBUG) + printf("ARB/ES2 framebuffer objects enabled.\n"); +#endif + } + + if (ext_framebuffer_object != 0 && ogl_have_framebuffer_object == 0) { + // try the EXT suffixed functions + ogl_missing_func = NULL; + LoadOGLProc_(avpPFNGLBINDFRAMEBUFFERPROC, glBindFramebuffer, glBindFramebufferEXT); + LoadOGLProc_(avpPFNGLBINDRENDERBUFFERPROC, glBindRenderbuffer, glBindRenderbufferEXT); + LoadOGLProc_(avpPFNGLCHECKFRAMEBUFFERSTATUSPROC, glCheckFramebufferStatus, glCheckFramebufferStatusEXT); + LoadOGLProc_(avpPFNGLDELETEFRAMEBUFFERSPROC, glDeleteFramebuffers, glDeleteFramebuffersEXT); + LoadOGLProc_(avpPFNGLDELETERENDERBUFFERSPROC, glDeleteRenderbuffers, glDeleteRenderbuffersEXT); + LoadOGLProc_(avpPFNGLFRAMEBUFFERRENDERBUFFERPROC, glFramebufferRenderbuffer, glFramebufferRenderbufferEXT); + LoadOGLProc_(avpPFNGLFRAMEBUFFERTEXTURE2DPROC, glFramebufferTexture2D, glFramebufferTexture2DEXT); + LoadOGLProc_(avpPFNGLGENERATEMIPMAPPROC, glGenerateMipmap, glGenerateMipmapEXT); + LoadOGLProc_(avpPFNGLGENFRAMEBUFFERSPROC, glGenFramebuffers, glGenFramebuffersEXT); + LoadOGLProc_(avpPFNGLGENRENDERBUFFERSPROC, glGenRenderbuffers, glGenRenderbuffersEXT); + LoadOGLProc_(avpPFNGLRENDERBUFFERSTORAGEPROC, glRenderbufferStorage, glRenderbufferStorageEXT); + if (ogl_missing_func == NULL) { + ogl_have_framebuffer_object = 1; + +#if !defined(NDEBUG) + printf("EXT framebuffer objects enabled.\n"); +#endif + } + } + + // other extensions ogl_have_multisample_filter_hint = check_token(ext, "GL_NV_multisample_filter_hint"); ogl_have_texture_filter_anisotropic = check_token(ext, "GL_EXT_texture_filter_anisotropic"); ogl_use_multisample_filter_hint = ogl_have_multisample_filter_hint; ogl_use_texture_filter_anisotropic = ogl_have_texture_filter_anisotropic; + ogl_use_framebuffer_object = ogl_have_framebuffer_object; } int check_for_errors_(const char *file, int line) diff --git a/src/oglfunc.h b/src/oglfunc.h index 93490d2..62622fb 100644 --- a/src/oglfunc.h +++ b/src/oglfunc.h @@ -5,8 +5,10 @@ #include #endif +#include "SDL_version.h" + #if defined(USE_OPENGL_ES) -#include "SDL_opengles.h" +#include "SDL_opengles2.h" // OpenGL compatibility typedef GLclampf GLclampd; @@ -25,91 +27,157 @@ typedef GLfloat GLdouble; #define APIENTRY #endif -typedef void (APIENTRY *PFNGLALPHAFUNCPROC)(GLenum, GLclampf); -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 *PFNGLCOLOR4FPROC)(GLfloat, GLfloat, GLfloat, GLfloat); -typedef void (APIENTRY *PFNGLCOLORPOINTERPROC)(GLint, GLenum, GLsizei, const GLvoid *); -typedef void (APIENTRY *PFNGLCULLFACEPROC)(GLenum); -typedef void (APIENTRY *PFNGLDELETETEXTURESPROC)(GLsizei,const GLuint*); -typedef void (APIENTRY *PFNGLDEPTHFUNCPROC)(GLenum); -typedef void (APIENTRY *PFNGLDEPTHMASKPROC)(GLboolean); -typedef void (APIENTRY *PFNGLDEPTHRANGEPROC)(GLclampd, GLclampd); -typedef void (APIENTRY *PFNGLDISABLEPROC)(GLenum); -typedef void (APIENTRY *PFNGLDISABLECLIENTSTATEPROC)(GLenum); -typedef void (APIENTRY *PFNGLDRAWELEMENTSPROC)(GLenum, GLsizei, GLenum, const GLvoid *); -typedef void (APIENTRY *PFNGLENABLEPROC)(GLenum); -typedef void (APIENTRY *PFNGLENABLECLIENTSTATEPROC)(GLenum); -typedef void (APIENTRY *PFNGLFRONTFACEPROC)(GLenum); -typedef void (APIENTRY *PFNGLGENTEXTURESPROC)(GLsizei,GLuint*); -typedef GLenum (APIENTRY *PFNGLGETERRORPROC)(void); -typedef void (APIENTRY *PFNGLGETFLOATVPROC)(GLenum, GLfloat *); -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 *PFNGLPIXELSTOREIPROC)(GLenum, GLint); -typedef void (APIENTRY *PFNGLPOLYGONOFFSETPROC)(GLfloat, GLfloat); -typedef void (APIENTRY *PFNGLREADPIXELSPROC)(GLint, GLint, GLsizei, GLsizei, GLenum, GLenum, GLvoid *); -typedef void (APIENTRY *PFNGLSHADEMODELPROC)(GLenum); -typedef void (APIENTRY *PFNGLTEXCOORDPOINTERPROC)(GLint, GLenum, GLsizei, const GLvoid *); -typedef void (APIENTRY *PFNGLTEXENVFPROC)(GLenum, GLenum, GLfloat); -typedef void (APIENTRY *PFNGLTEXENVFVPROC)(GLenum, GLenum, const GLfloat *); -typedef void (APIENTRY *PFNGLTEXENVIPROC)(GLenum, GLenum, GLint); -typedef void (APIENTRY *PFNGLTEXIMAGE2DPROC)(GLenum,GLint,GLint,GLsizei,GLsizei,GLint,GLenum,GLenum,const GLvoid*); -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 *PFNGLVERTEXPOINTERPROC)(GLint, GLenum, GLsizei, const GLvoid *); -typedef void (APIENTRY *PFNGLVIEWPORTPROC)(GLint, GLint, GLsizei, GLsizei); +// Base OpenGL / OpenGL ES +typedef void (APIENTRY *avpPFNGLACTIVETEXTUREPROC)(GLenum); +typedef void (APIENTRY *avpPFNGLBINDTEXTUREPROC)(GLenum, GLuint); +typedef void (APIENTRY *avpPFNGLBLENDFUNCPROC)(GLenum, GLenum); +typedef void (APIENTRY *avpPFNGLCLEARPROC)(GLbitfield); +typedef void (APIENTRY *avpPFNGLCLEARCOLORPROC)(GLclampf, GLclampf, GLclampf, GLclampf); +typedef void (APIENTRY *avpPFNGLCULLFACEPROC)(GLenum); +typedef void (APIENTRY *avpPFNGLDELETETEXTURESPROC)(GLsizei,const GLuint*); +typedef void (APIENTRY *avpPFNGLDEPTHFUNCPROC)(GLenum); +typedef void (APIENTRY *avpPFNGLDEPTHMASKPROC)(GLboolean); +typedef void (APIENTRY *avpPFNGLDEPTHRANGEPROC)(GLclampd, GLclampd); +typedef void (APIENTRY *avpPFNGLDISABLEPROC)(GLenum); +typedef void (APIENTRY *avpPFNGLDRAWELEMENTSPROC)(GLenum, GLsizei, GLenum, const GLvoid *); +typedef void (APIENTRY *avpPFNGLENABLEPROC)(GLenum); +typedef void (APIENTRY *avpPFNGLFRONTFACEPROC)(GLenum); +typedef void (APIENTRY *avpPFNGLGENTEXTURESPROC)(GLsizei,GLuint*); +typedef GLenum (APIENTRY *avpPFNGLGETERRORPROC)(void); +typedef void (APIENTRY *avpPFNGLGETFLOATVPROC)(GLenum, GLfloat *); +typedef void (APIENTRY *avpPFNGLGETINTEGERVPROC)(GLenum, GLint *); +typedef const GLubyte* (APIENTRY *avpPFNGLGETSTRINGPROC)(GLenum); +typedef void (APIENTRY *avpPFNGLGETTEXPARAMETERFVPROC)(GLenum, GLenum, GLfloat*); +typedef void (APIENTRY *avpPFNGLHINTPROC)(GLenum, GLenum); +typedef void (APIENTRY *avpPFNGLPIXELSTOREIPROC)(GLenum, GLint); +typedef void (APIENTRY *avpPFNGLPOLYGONOFFSETPROC)(GLfloat, GLfloat); +typedef void (APIENTRY *avpPFNGLREADPIXELSPROC)(GLint, GLint, GLsizei, GLsizei, GLenum, GLenum, GLvoid *); +typedef void (APIENTRY *avpPFNGLTEXIMAGE2DPROC)(GLenum,GLint,GLint,GLsizei,GLsizei,GLint,GLenum,GLenum,const GLvoid*); +typedef void (APIENTRY *avpPFNGLTEXPARAMETERFPROC)(GLenum, GLenum, GLfloat); +typedef void (APIENTRY *avpPFNGLTEXPARAMETERIPROC)(GLenum, GLenum, GLint); +typedef void (APIENTRY *avpPFNGLTEXSUBIMAGE2DPROC)(GLenum,GLint,GLint,GLint,GLsizei,GLsizei,GLenum,GLenum,const GLvoid*); +typedef void (APIENTRY *avpPFNGLVIEWPORTPROC)(GLint, GLint, GLsizei, GLsizei); + +extern avpPFNGLACTIVETEXTUREPROC pglActiveTexture; +extern avpPFNGLBINDTEXTUREPROC pglBindTexture; +extern avpPFNGLBLENDFUNCPROC pglBlendFunc; +extern avpPFNGLCLEARPROC pglClear; +extern avpPFNGLCLEARCOLORPROC pglClearColor; +extern avpPFNGLCULLFACEPROC pglCullFace; +extern avpPFNGLDELETETEXTURESPROC pglDeleteTextures; +extern avpPFNGLDEPTHFUNCPROC pglDepthFunc; +extern avpPFNGLDEPTHMASKPROC pglDepthMask; +extern avpPFNGLDEPTHRANGEPROC pglDepthRange; +extern avpPFNGLDISABLEPROC pglDisable; +extern avpPFNGLDRAWELEMENTSPROC pglDrawElements; +extern avpPFNGLENABLEPROC pglEnable; +extern avpPFNGLFRONTFACEPROC pglFrontFace; +extern avpPFNGLGENTEXTURESPROC pglGenTextures; +extern avpPFNGLGETERRORPROC pglGetError; +extern avpPFNGLGETFLOATVPROC pglGetFloatv; +extern avpPFNGLGETINTEGERVPROC pglGetIntegerv; +extern avpPFNGLGETSTRINGPROC pglGetString; +extern avpPFNGLGETTEXPARAMETERFVPROC pglGetTexParameterfv; +extern avpPFNGLHINTPROC pglHint; +extern avpPFNGLPIXELSTOREIPROC pglPixelStorei; +extern avpPFNGLPOLYGONOFFSETPROC pglPolygonOffset; +extern avpPFNGLREADPIXELSPROC pglReadPixels; +extern avpPFNGLTEXIMAGE2DPROC pglTexImage2D; +extern avpPFNGLTEXPARAMETERFPROC pglTexParameterf; +extern avpPFNGLTEXPARAMETERIPROC pglTexParameteri; +extern avpPFNGLTEXSUBIMAGE2DPROC pglTexSubImage2D; +extern avpPFNGLVIEWPORTPROC pglViewport; + +// OpenGL 2.1 / OpenGL ES 2.0 +typedef void (APIENTRY *avpPFNGLATTACHSHADERPROC)(GLuint, GLuint); +typedef void (APIENTRY *avpPFNGLBINDATTRIBLOCATIONPROC)(GLuint, GLuint, const GLchar*); +typedef void (APIENTRY *avpPFNGLBINDBUFFERPROC)(GLenum, GLuint); +typedef void (APIENTRY *avpPFNGLBUFFERDATAPROC)(GLenum, GLsizeiptr, const GLvoid*, GLenum); +typedef void (APIENTRY *avpPFNGLBUFFERSUBDATAPROC)(GLenum, GLintptr, GLsizeiptr, const GLvoid*); +typedef GLuint (APIENTRY *avpPFNGLCREATEPROGRAMPROC)(void); +typedef GLuint (APIENTRY *avpPFNGLCREATESHADERPROC)(GLenum); +typedef void (APIENTRY *avpPFNGLCOMPILESHADERPROC)(GLuint); +typedef void (APIENTRY *avpPFNGLDELETEBUFFERSPROC)(GLsizei, const GLuint*); +typedef void (APIENTRY *avpPFNGLDELETEPROGRAMPROC)(GLuint); +typedef void (APIENTRY *avpPFNGLDELETESHADERPROC)(GLuint); +typedef void (APIENTRY *avpPFNGLDISABLEVERTEXATTRIBARRAYPROC)(GLuint); +typedef void (APIENTRY *avpPFNGLENABLEVERTEXATTRIBARRAYPROC)(GLuint); +typedef void (APIENTRY *avpPFNGLGENBUFFERSPROC)(GLsizei, GLuint*); +typedef int (APIENTRY *avpPFNGLGETATTRIBLOCATIONPROC)(GLuint, const GLchar*); +typedef void (APIENTRY *avpPFNGLGETPROGRAMINFOLOGPROC)(GLuint, GLsizei, GLsizei*, GLchar*); +typedef void (APIENTRY *avpPFNGLGETPROGRAMIVPROC)(GLuint, GLenum, GLint*); +typedef void (APIENTRY *avpPFNGLGETSHADERINFOLOGPROC)(GLuint, GLsizei, GLsizei*, GLchar*); +typedef void (APIENTRY *avpPFNGLGETSHADERIVPROC)(GLuint, GLenum, GLint*); +typedef int (APIENTRY *avpPFNGLGETUNIFORMLOCATIONPROC)(GLuint, const GLchar*); +typedef void (APIENTRY *avpPFNGLLINKPROGRAMPROC)(GLuint); +typedef void (APIENTRY *avpPFNGLSHADERSOURCEPROC)(GLuint, GLsizei, const GLchar* const*, const GLint*); +typedef void (APIENTRY *avpPFNGLVALIDATEPROGRAMPROC)(GLuint); +typedef void (APIENTRY *avpPFNGLVERTEXATTRIBPOINTERPROC)(GLuint, GLint, GLenum, GLboolean, GLsizei, const GLvoid*); +typedef void (APIENTRY *avpPFNGLUNIFORM1IPROC)(GLint, GLint); +typedef void (APIENTRY *avpPFNGLUNIFORMMATRIX4FVPROC)(GLint, GLsizei, GLboolean, const GLfloat*); +typedef void (APIENTRY *avpPFNGLUSEPROGRAMPROC)(GLuint); + +extern avpPFNGLATTACHSHADERPROC pglAttachShader; +extern avpPFNGLBINDATTRIBLOCATIONPROC pglBindAttribLocation; +extern avpPFNGLBINDBUFFERPROC pglBindBuffer; +extern avpPFNGLBUFFERDATAPROC pglBufferData; +extern avpPFNGLBUFFERSUBDATAPROC pglBufferSubData; +extern avpPFNGLCREATEPROGRAMPROC pglCreateProgram; +extern avpPFNGLCREATESHADERPROC pglCreateShader; +extern avpPFNGLCOMPILESHADERPROC pglCompileShader; +extern avpPFNGLDELETEBUFFERSPROC pglDeleteBuffers; +extern avpPFNGLDELETEPROGRAMPROC pglDeleteProgram; +extern avpPFNGLDELETESHADERPROC pglDeleteShader; +extern avpPFNGLDISABLEVERTEXATTRIBARRAYPROC pglDisableVertexAttribArray; +extern avpPFNGLENABLEVERTEXATTRIBARRAYPROC pglEnableVertexAttribArray; +extern avpPFNGLGENBUFFERSPROC pglGenBuffers; +extern avpPFNGLGETATTRIBLOCATIONPROC pglGetAttribLocation; +extern avpPFNGLGETPROGRAMINFOLOGPROC pglGetProgramInfoLog; +extern avpPFNGLGETPROGRAMIVPROC pglGetProgramiv; +extern avpPFNGLGETSHADERINFOLOGPROC pglGetShaderInfoLog; +extern avpPFNGLGETSHADERIVPROC pglGetShaderiv; +extern avpPFNGLGETUNIFORMLOCATIONPROC pglGetUniformLocation; +extern avpPFNGLLINKPROGRAMPROC pglLinkProgram; +extern avpPFNGLSHADERSOURCEPROC pglShaderSource; +extern avpPFNGLVALIDATEPROGRAMPROC pglValidateProgram; +extern avpPFNGLVERTEXATTRIBPOINTERPROC pglVertexAttribPointer; +extern avpPFNGLUNIFORM1IPROC pglUniform1i; +extern avpPFNGLUNIFORMMATRIX4FVPROC pglUniformMatrix4fv; +extern avpPFNGLUSEPROGRAMPROC pglUseProgram; + +// GL_EXT_framebuffer_object / GL_ARB_framebuffer_object / OpenGL ES 2.0 +typedef void (APIENTRY *avpPFNGLBINDFRAMEBUFFERPROC)(GLenum, GLuint); +typedef void (APIENTRY *avpPFNGLBINDRENDERBUFFERPROC)(GLenum, GLuint); +typedef GLenum (APIENTRY *avpPFNGLCHECKFRAMEBUFFERSTATUSPROC)(GLenum); +typedef void (APIENTRY *avpPFNGLDELETEFRAMEBUFFERSPROC)(GLsizei, const GLuint*); +typedef void (APIENTRY *avpPFNGLDELETERENDERBUFFERSPROC)(GLsizei, const GLuint*); +typedef void (APIENTRY *avpPFNGLFRAMEBUFFERRENDERBUFFERPROC)(GLenum, GLenum, GLenum, GLuint); +typedef void (APIENTRY *avpPFNGLFRAMEBUFFERTEXTURE2DPROC)(GLenum, GLenum, GLenum, GLuint, GLint); +typedef void (APIENTRY *avpPFNGLGENERATEMIPMAPPROC)(GLenum); +typedef void (APIENTRY *avpPFNGLGENFRAMEBUFFERSPROC)(GLsizei, GLuint*); +typedef void (APIENTRY *avpPFNGLGENRENDERBUFFERSPROC)(GLsizei, GLuint*); +typedef void (APIENTRY *avpPFNGLRENDERBUFFERSTORAGEPROC)(GLenum, GLenum, GLsizei, GLsizei); + +extern avpPFNGLBINDFRAMEBUFFERPROC pglBindFramebuffer; +extern avpPFNGLBINDRENDERBUFFERPROC pglBindRenderbuffer; +extern avpPFNGLCHECKFRAMEBUFFERSTATUSPROC pglCheckFramebufferStatus; +extern avpPFNGLDELETEFRAMEBUFFERSPROC pglDeleteFramebuffers; +extern avpPFNGLDELETERENDERBUFFERSPROC pglDeleteRenderbuffers; +extern avpPFNGLFRAMEBUFFERRENDERBUFFERPROC pglFramebufferRenderbuffer; +extern avpPFNGLFRAMEBUFFERTEXTURE2DPROC pglFramebufferTexture2D; +extern avpPFNGLGENERATEMIPMAPPROC pglGenerateMipmap; +extern avpPFNGLGENFRAMEBUFFERSPROC pglGenFramebuffers; +extern avpPFNGLGENRENDERBUFFERSPROC pglGenRenderbuffers; +extern avpPFNGLRENDERBUFFERSTORAGEPROC pglRenderbufferStorage; -extern PFNGLALPHAFUNCPROC pglAlphaFunc; -extern PFNGLBINDTEXTUREPROC pglBindTexture; -extern PFNGLBLENDFUNCPROC pglBlendFunc; -extern PFNGLCLEARPROC pglClear; -extern PFNGLCLEARCOLORPROC pglClearColor; -extern PFNGLCOLOR4FPROC pglColor4f; -extern PFNGLCOLORPOINTERPROC pglColorPointer; -extern PFNGLCULLFACEPROC pglCullFace; -extern PFNGLDELETETEXTURESPROC pglDeleteTextures; -extern PFNGLDEPTHFUNCPROC pglDepthFunc; -extern PFNGLDEPTHMASKPROC pglDepthMask; -extern PFNGLDEPTHRANGEPROC pglDepthRange; -extern PFNGLDISABLEPROC pglDisable; -extern PFNGLDISABLECLIENTSTATEPROC pglDisableClientState; -extern PFNGLDRAWELEMENTSPROC pglDrawElements; -extern PFNGLENABLEPROC pglEnable; -extern PFNGLENABLECLIENTSTATEPROC pglEnableClientState; -extern PFNGLFRONTFACEPROC pglFrontFace; -extern PFNGLGENTEXTURESPROC pglGenTextures; -extern PFNGLGETERRORPROC pglGetError; -extern PFNGLGETFLOATVPROC pglGetFloatv; -extern PFNGLGETINTEGERVPROC pglGetIntegerv; -extern PFNGLGETSTRINGPROC pglGetString; -extern PFNGLGETTEXPARAMETERFVPROC pglGetTexParameterfv; -extern PFNGLHINTPROC pglHint; -extern PFNGLPIXELSTOREIPROC pglPixelStorei; -extern PFNGLPOLYGONOFFSETPROC pglPolygonOffset; -extern PFNGLREADPIXELSPROC pglReadPixels; -extern PFNGLSHADEMODELPROC pglShadeModel; -extern PFNGLTEXCOORDPOINTERPROC pglTexCoordPointer; -extern PFNGLTEXENVFPROC pglTexEnvf; -extern PFNGLTEXENVFVPROC pglTexEnvfv; -extern PFNGLTEXENVIPROC pglTexEnvi; -extern PFNGLTEXIMAGE2DPROC pglTexImage2D; -extern PFNGLTEXPARAMETERFPROC pglTexParameterf; -extern PFNGLTEXPARAMETERIPROC pglTexParameteri; -extern PFNGLTEXSUBIMAGE2DPROC pglTexSubImage2D; -extern PFNGLVERTEXPOINTERPROC pglVertexPointer; -extern PFNGLVIEWPORTPROC pglViewport; extern int ogl_have_multisample_filter_hint; extern int ogl_have_texture_filter_anisotropic; +extern int ogl_have_framebuffer_object; extern int ogl_use_multisample_filter_hint; extern int ogl_use_texture_filter_anisotropic; +extern int ogl_use_framebuffer_object; extern void load_ogl_functions(int mode); diff --git a/src/openal.c b/src/openal.c index 7018255..19bae84 100644 --- a/src/openal.c +++ b/src/openal.c @@ -3,8 +3,13 @@ #include #include +#if EMSCRIPTEN +#include +#include +#else #include "al.h" #include "alc.h" +#endif #include "fixer.h" @@ -19,7 +24,7 @@ #include "dynblock.h" #include "stratdef.h" -#if defined( _MSC_VER ) +#if defined( _MSC_VERx ) #include #endif @@ -47,7 +52,7 @@ static struct { unsigned int env_index; } SoundConfig; -#if defined(_MSC_VER) +#if defined(_MSC_VERx) // EAX1.0 #define EAX_REVERBMIX_USEDISTANCE -1.0F @@ -225,7 +230,7 @@ int PlatStartSoundSys() exit(1); } -#if defined(_MSC_VER) +#if defined(_MSC_VERx) EAX_pfPropSet = NULL; EAX_pfPropGet = NULL; @@ -870,7 +875,7 @@ void PlatUpdatePlayer() or[5] = -(float) ((Global_VDB_Ptr->VDB_Mat.mat32) / 65536.0F); } -#warning VELOCITY AND/OR OPENAL SETUP IS IN WRONG UNITS +#pragma message ("VELOCITY AND/OR OPENAL SETUP IS IN WRONG UNITS") static int useVel = 0; if (useVel!=0&&(AvP.PlayerType == I_Alien && DopplerShiftIsOn && NormalFrameTime)) { DYNAMICSBLOCK *dynPtr = Player->ObStrategyBlock->DynPtr; @@ -902,7 +907,7 @@ void PlatUpdatePlayer() alListenerfv (AL_POSITION, pos); } -#if defined( _MSC_VER ) +#if defined( _MSC_VERx ) if( SoundConfig.reverb_changed ) { // TODO: reverb handling } @@ -915,7 +920,7 @@ void PlatSetEnviroment(unsigned int env_index, float reverb_mix) fprintf(stderr, "OPENAL: PlatSetEnvironment(%d, %f)\n", env_index, reverb_mix); #endif -#if defined( _MSC_VER ) +#if defined( _MSC_VERx ) if( SoundConfig.env_index != env_index ) { // TODO: support the custom plain reverb diff --git a/src/opengl.c b/src/opengl.c index 4326fc0..dd89509 100644 --- a/src/opengl.c +++ b/src/opengl.c @@ -46,10 +46,13 @@ extern int CloakingPhase; static D3DTexture *CurrTextureHandle; +enum AVP_SHADER_PROGRAM CurrShaderProgram; + +GLuint DefaultTexture; static enum TRANSLUCENCY_TYPE CurrentTranslucencyMode = TRANSLUCENCY_OFF; static enum FILTERING_MODE_ID CurrentFilteringMode = FILTERING_BILINEAR_OFF; -static GLenum TextureMinFilter = GL_LINEAR_MIPMAP_LINEAR; +static GLenum TextureMinFilter = GL_LINEAR; //GL_LINEAR_MIPMAP_LINEAR; static D3DTexture *CurrentlyBoundTexture = NULL; #if defined(_MSC_VER) @@ -86,23 +89,17 @@ static VertexArray *varrp = varr; static TriangleArray *tarrp = tarr; static int varrc, tarrc; -static ALIGN16 TriangleArray starr[TA_MAXTRIANGLES]; -static TriangleArray *starrp = starr; -static int starrc; +static GLuint ElementArrayBuffer; +static GLuint ArrayBuffer; /* Do not call this directly! */ static void SetTranslucencyMode(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_SRC_ALPHA); - } else { - // alien tail hack - pglEnable(GL_ALPHA_TEST); - + } else { pglBlendFunc(GL_ONE, GL_ZERO); } break; @@ -130,101 +127,693 @@ static void SetTranslucencyMode(enum TRANSLUCENCY_TYPE mode) } } -static void SetSecondPassTranslucencyMode(enum TRANSLUCENCY_TYPE mode) -{ - pglDisable(GL_ALPHA_TEST); +#if defined(USE_OPENGL_ES) +#define SHADER_PRAGMAS "\n" +#define SHADER_VERSION "#version 100\n" +#else +#define SHADER_PRAGMAS "\n" +#define SHADER_VERSION "#version 120\n" +#endif - switch(mode) { - case TRANSLUCENCY_OFF: - if (TRIPTASTIC_CHEATMODE||MOTIONBLUR_CHEATMODE) { - pglBlendFunc(GL_ONE_MINUS_SRC_ALPHA, GL_ONE); +#if USE_OPENGL_ES + +#define SHADER_SETUP \ +"#define HIGHP highp\n" \ +"#define MEDIUMP mediump\n" \ +"#define LOWP lowp\n" + +#else + +#define SHADER_SETUP \ +"#ifdef GL_ES\n" \ +"#define HIGHP highp\n" \ +"#define MEDIUMP mediump\n" \ +"#define LOWP lowp\n" \ +"#else\n" \ +"#define HIGHP\n" \ +"#define MEDIUMP\n" \ +"#define LOWP\n" \ +"#endif\n" + +#endif + +static const char AVP_VERTEX_SHADER_SOURCE[] = + SHADER_VERSION + SHADER_PRAGMAS + SHADER_SETUP + "\n" + "attribute HIGHP vec4 aVertex;\n" + "attribute HIGHP vec2 aTexCoord;\n" + "attribute LOWP vec4 aColor0;\n" + "attribute LOWP vec4 aColor1;\n" + "\n" + "varying HIGHP vec2 vTexCoord;\n" + "varying LOWP vec4 vColor0;\n" + "varying LOWP vec4 vColor1;\n" + "\n" + "void main(void)\n" + "{\n" + " gl_Position = aVertex;\n" + " vTexCoord = aTexCoord;\n" + " vColor0 = aColor0;\n" + " vColor1 = aColor1;\n" + "}\n" + ; + +static const char AVP_VERTEX_SHADER_SOURCE_NO_SECONDARY[] = + SHADER_VERSION + SHADER_PRAGMAS + SHADER_SETUP + "\n" + "attribute HIGHP vec4 aVertex;\n" + "attribute HIGHP vec2 aTexCoord;\n" + "attribute LOWP vec4 aColor0;\n" + "\n" + "varying HIGHP vec2 vTexCoord;\n" + "varying LOWP vec4 vColor0;\n" + "\n" + "void main(void)\n" + "{\n" + " gl_Position = aVertex;\n" + " vTexCoord = aTexCoord;\n" + " vColor0 = aColor0;\n" + "}\n" + ; + +static const char AVP_VERTEX_SHADER_SOURCE_NO_TEXTURE[] = + SHADER_VERSION + SHADER_PRAGMAS + SHADER_SETUP + "\n" + "attribute HIGHP vec4 aVertex;\n" + "attribute LOWP vec4 aColor0;\n" + "\n" + "varying LOWP vec4 vColor0;\n" + "\n" + "void main(void)\n" + "{\n" + " gl_Position = aVertex;\n" + " vColor0 = aColor0;\n" + "}\n" + ; + +static const char AVP_VERTEX_SHADER_SOURCE_NO_COLOR[] = + SHADER_VERSION + SHADER_PRAGMAS + SHADER_SETUP + "\n" + "attribute HIGHP vec4 aVertex;\n" + "attribute HIGHP vec2 aTexCoord;\n" + "\n" + "varying HIGHP vec2 vTexCoord;\n" + "\n" + "void main(void)\n" + "{\n" + " gl_Position = aVertex;\n" + " vTexCoord = aTexCoord;\n" + "}\n" + ; + +static const char AVP_FRAGMENT_SHADER_SOURCE[] = + SHADER_VERSION + SHADER_PRAGMAS + SHADER_SETUP + "\n" + "uniform LOWP sampler2D uTexture;\n" + "\n" + "varying HIGHP vec2 vTexCoord;\n" + "varying LOWP vec4 vColor0;\n" + "varying LOWP vec4 vColor1;\n" + "\n" + "void main(void)\n" + "{\n" + "\n" + " MEDIUMP vec4 t = texture2D( uTexture, vTexCoord );\n" + " if (t.a == 0.0) discard;\n" + " gl_FragColor = t * vColor0 + vColor1;\n" + "}\n" + ; + +static const char AVP_FRAGMENT_SHADER_SOURCE_NO_SECONDARY[] = + SHADER_VERSION + SHADER_PRAGMAS + SHADER_SETUP + "\n" + "uniform LOWP sampler2D uTexture;\n" + "\n" + "varying HIGHP vec2 vTexCoord;\n" + "varying LOWP vec4 vColor0;\n" + "\n" + "void main(void)\n" + "{\n" + " MEDIUMP vec4 t = texture2D( uTexture, vTexCoord );\n" + " if (t.a == 0.0) discard;\n" + " gl_FragColor = t * vColor0;\n" + "}\n" + ; + +static const char AVP_FRAGMENT_SHADER_SOURCE_NO_TEXTURE[] = + SHADER_VERSION + SHADER_PRAGMAS + SHADER_SETUP + "\n" + "varying LOWP vec4 vColor0;\n" + "\n" + "void main(void)\n" + "{\n" + " gl_FragColor = vColor0;\n" + "}\n" + ; + +static const char AVP_FRAGMENT_SHADER_SOURCE_NO_DISCARD[] = + SHADER_VERSION + SHADER_PRAGMAS + SHADER_SETUP + "\n" + "uniform LOWP sampler2D uTexture;\n" + "\n" + "varying HIGHP vec2 vTexCoord;\n" + "varying LOWP vec4 vColor0;\n" + "varying LOWP vec4 vColor1;\n" + "\n" + "void main(void)\n" + "{\n" + " MEDIUMP vec4 t = texture2D( uTexture, vTexCoord );\n" + " gl_FragColor = t * vColor0 + vColor1;\n" + "}\n" + ; + +static const char AVP_FRAGMENT_SHADER_SOURCE_NO_SECONDARY_NO_DISCARD[] = + SHADER_VERSION + SHADER_PRAGMAS + SHADER_SETUP + "\n" + "uniform LOWP sampler2D uTexture;\n" + "\n" + "varying HIGHP vec2 vTexCoord;\n" + "varying LOWP vec4 vColor0;\n" + "\n" + "void main(void)\n" + "{\n" + " MEDIUMP vec4 t = texture2D( uTexture, vTexCoord );\n" + " gl_FragColor = t * vColor0;\n" + "}\n" + ; + +static const char AVP_FRAGMENT_SHADER_SOURCE_NO_COLOR_NO_DISCARD[] = + SHADER_VERSION + SHADER_PRAGMAS + SHADER_SETUP + "\n" + "uniform LOWP sampler2D uTexture;\n" + "\n" + "varying HIGHP vec2 vTexCoord;\n" + "\n" + "void main(void)\n" + "{\n" + " MEDIUMP vec4 t = texture2D( uTexture, vTexCoord );\n" + " gl_FragColor = t;\n" + "}\n" + ; + +enum AVP_VERTEX_SHADER { + AVP_VERTEX_SHADER_DEFAULT, + AVP_VERTEX_SHADER_NO_TEXTURE, + AVP_VERTEX_SHADER_NO_SECONDARY, + AVP_VERTEX_SHADER_NO_COLOR, + AVP_VERTEX_SHADER_MAX +}; + +enum AVP_FRAGMENT_SHADER { + AVP_FRAGMENT_SHADER_DEFAULT, + AVP_FRAGMENT_SHADER_NO_TEXTURE, + AVP_FRAGMENT_SHADER_NO_DISCARD, + AVP_FRAGMENT_SHADER_NO_SECONDARY, + AVP_FRAGMENT_SHADER_NO_SECONDARY_NO_DISCARD, + AVP_FRAGMENT_SHADER_NO_COLOR_NO_DISCARD, + AVP_FRAGMENT_SHADER_MAX +}; + +static const char* const AvpVertexShaderSources[AVP_VERTEX_SHADER_MAX] = { + AVP_VERTEX_SHADER_SOURCE, + AVP_VERTEX_SHADER_SOURCE_NO_TEXTURE, + AVP_VERTEX_SHADER_SOURCE_NO_SECONDARY, + AVP_VERTEX_SHADER_SOURCE_NO_COLOR +}; + +static const char* AvpFragmentShaderSources[AVP_FRAGMENT_SHADER_MAX] = { + AVP_FRAGMENT_SHADER_SOURCE, + AVP_FRAGMENT_SHADER_SOURCE_NO_TEXTURE, + AVP_FRAGMENT_SHADER_SOURCE_NO_DISCARD, + AVP_FRAGMENT_SHADER_SOURCE_NO_SECONDARY, + AVP_FRAGMENT_SHADER_SOURCE_NO_SECONDARY_NO_DISCARD, + AVP_FRAGMENT_SHADER_SOURCE_NO_COLOR_NO_DISCARD +}; + +struct AvpShaderProgramSource { + enum AVP_VERTEX_SHADER VertexShader; + enum AVP_FRAGMENT_SHADER FragmentShader; +}; + +struct AvpVertexShader { + int shaderObj; +}; + +struct AvpFragmentShader { + int shaderObj; +}; + +struct AvpShaderProgram { + int programObj; + + int uTexture; +}; + +static const struct AvpShaderProgramSource AvpShaderProgramSources[AVP_SHADER_PROGRAM_MAX] = { + // AVP_SHADER_PROGRAM_DEFAULT + { + AVP_VERTEX_SHADER_DEFAULT, + AVP_FRAGMENT_SHADER_DEFAULT + }, + // AVP_SHADER_PROGRAM_NO_SECONDARY + { + AVP_VERTEX_SHADER_NO_SECONDARY, + AVP_FRAGMENT_SHADER_NO_SECONDARY + }, + // AVP_SHADER_PROGRAM_NO_TEXTURE + { + AVP_VERTEX_SHADER_NO_TEXTURE, + AVP_FRAGMENT_SHADER_NO_TEXTURE + }, + // AVP_SHADER_PROGRAM_NO_DISCARD + { + AVP_VERTEX_SHADER_DEFAULT, + AVP_FRAGMENT_SHADER_NO_DISCARD + }, + // AVP_SHADER_PROGRAM_NO_SECONDARY_NO_DISCARD + { + AVP_VERTEX_SHADER_NO_SECONDARY, + AVP_FRAGMENT_SHADER_NO_SECONDARY_NO_DISCARD + }, + // AVP_SHADER_PROGRAM_NO_COLOR_NO_DISCARD + { + AVP_VERTEX_SHADER_NO_COLOR, + AVP_FRAGMENT_SHADER_NO_COLOR_NO_DISCARD + } +}; + +static const unsigned int AvpShaderProgramAttributes[AVP_SHADER_PROGRAM_MAX+1] = { + // AVP_SHADER_PROGRAM_DEFAULT + (1 << OPENGL_VERTEX_ATTRIB_INDEX) | (1 << OPENGL_TEXCOORD_ATTRIB_INDEX) | (1 << OPENGL_COLOR0_ATTRIB_INDEX) | (1 << OPENGL_COLOR1_ATTRIB_INDEX), + // AVP_SHADER_PROGRAM_NO_SECONDARY + (1 << OPENGL_VERTEX_ATTRIB_INDEX) | (1 << OPENGL_TEXCOORD_ATTRIB_INDEX) | (1 << OPENGL_COLOR0_ATTRIB_INDEX) | (0 << OPENGL_COLOR1_ATTRIB_INDEX), + // AVP_SHADER_PROGRAM_NO_TEXTURE + (1 << OPENGL_VERTEX_ATTRIB_INDEX) | (0 << OPENGL_TEXCOORD_ATTRIB_INDEX) | (1 << OPENGL_COLOR0_ATTRIB_INDEX) | (0 << OPENGL_COLOR1_ATTRIB_INDEX), + // AVP_SHADER_PROGRAM_NO_DISCARD + (1 << OPENGL_VERTEX_ATTRIB_INDEX) | (1 << OPENGL_TEXCOORD_ATTRIB_INDEX) | (1 << OPENGL_COLOR0_ATTRIB_INDEX) | (1 << OPENGL_COLOR1_ATTRIB_INDEX), + // AVP_SHADER_PROGRAM_NO_SECONDARY_NO_DISCARD + (1 << OPENGL_VERTEX_ATTRIB_INDEX) | (1 << OPENGL_TEXCOORD_ATTRIB_INDEX) | (1 << OPENGL_COLOR0_ATTRIB_INDEX) | (0 << OPENGL_COLOR1_ATTRIB_INDEX), + // AVP_SHADER_PROGRAM_NO_COLOR_NO_DISCARD + (1 << OPENGL_VERTEX_ATTRIB_INDEX) | (1 << OPENGL_TEXCOORD_ATTRIB_INDEX) | (0 << OPENGL_COLOR0_ATTRIB_INDEX) | (0 << OPENGL_COLOR1_ATTRIB_INDEX), + // AVP_SHADER_PROGRAM_MAX + 0 +}; + +static const char* AvpShaderProgramAttributeNames[4] = { + "aVertex", + "aTexCoord", + "aColor0", + "aColor1" +}; + +static struct AvpVertexShader AvpVertexShaders[AVP_FRAGMENT_SHADER_MAX]; +static struct AvpFragmentShader AvpFragmentShaders[AVP_FRAGMENT_SHADER_MAX]; +static struct AvpShaderProgram AvpShaderPrograms[AVP_SHADER_PROGRAM_MAX]; + +static int CompileShader(GLuint shader, const GLchar* shaderSource) { + GLint infoLogLength; + GLchar* infoLog; + GLint compileStatus; + + pglShaderSource(shader, 1, &shaderSource, NULL); + pglCompileShader(shader); + + pglGetShaderiv(shader, GL_INFO_LOG_LENGTH, &infoLogLength); + if (infoLogLength > 1) { + infoLog = (GLchar*) malloc((size_t) infoLogLength * sizeof(GLchar)); + if (infoLog == NULL) { + fprintf(stderr, "unable to allocate info log\n"); + return GL_FALSE; + } + + pglGetShaderInfoLog(shader, infoLogLength, NULL, infoLog); + printf("Shader:\n-------\n%s\n\nCompile Log:\n------------\n%s\n", shaderSource, infoLog); + + free(infoLog); + } + + pglGetShaderiv(shader, GL_COMPILE_STATUS, &compileStatus); + return compileStatus; +} + +static int LinkProgram(GLuint program) { + GLint infoLogLength; + GLchar* infoLog; + GLint compileStatus; + + pglLinkProgram(program); + pglGetProgramiv(program, GL_INFO_LOG_LENGTH, &infoLogLength); + + if (infoLogLength > 1) { + infoLog = (GLchar*) malloc((size_t) infoLogLength * sizeof(GLchar)); + if (infoLog == NULL) { + fprintf(stderr, "unable to allocate info log\n"); + return GL_FALSE; + } + + pglGetProgramInfoLog(program, infoLogLength, NULL, infoLog); + printf("Program Link Log:\n%s\n", infoLog); + + free(infoLog); + } + + pglGetProgramiv(program, GL_LINK_STATUS, &compileStatus); + return compileStatus; +} + +static int ValidateProgram(GLuint program) { + GLint infoLogLength; + GLchar* infoLog; + GLint compileStatus; + + pglValidateProgram(program); + + pglGetProgramiv(program, GL_INFO_LOG_LENGTH, &infoLogLength); + + if (infoLogLength > 1) { + infoLog = (GLchar*) malloc((size_t) infoLogLength * sizeof(GLchar)); + if (infoLog == NULL) { + fprintf(stderr, "unable to allocate info log\n"); + return GL_FALSE; + } + + pglGetProgramInfoLog(program, infoLogLength, NULL, infoLog); + printf("Program Validation Log:\n%s\n", infoLog); + + free(infoLog); + } + + pglGetProgramiv(program, GL_VALIDATE_STATUS, &compileStatus); + return compileStatus; +} + +static int CreateProgram(GLuint* pprogram, const GLchar* vertexShaderSource, const GLchar* fragmentShaderSource) { + GLuint program; + GLuint vertexShader; + GLuint fragmentShader; + + GLint compileStatus; + + // create program object + program = pglCreateProgram(); + + // vertex shader + vertexShader = pglCreateShader(GL_VERTEX_SHADER); + + compileStatus = CompileShader(vertexShader, vertexShaderSource); + + if (compileStatus == GL_FALSE) { + fprintf(stderr, "vertex shader compilation failed\n"); + + pglDeleteProgram(program); + return GL_FALSE; + } + + pglAttachShader(program, vertexShader); + pglDeleteShader(vertexShader); + + // fragment shader + fragmentShader = pglCreateShader(GL_FRAGMENT_SHADER); + + compileStatus = CompileShader(fragmentShader, fragmentShaderSource); + + if (compileStatus == GL_FALSE) { + fprintf(stderr, "fragment shader compilation failed\n"); + + pglDeleteProgram(program); + return GL_FALSE; + } + + pglAttachShader(program, fragmentShader); + pglDeleteShader(fragmentShader); + + // link the program + compileStatus = LinkProgram(program); + + if (compileStatus == GL_FALSE) { + fprintf(stderr, "program failed to link\n"); + + pglDeleteProgram(program); + return GL_FALSE; + } + + // validate the program for good measure + compileStatus = ValidateProgram(program); + + if (compileStatus == GL_FALSE) { + fprintf(stderr, "program failed to validate\n"); + + pglDeleteProgram(program); + return GL_FALSE; + } + + *pprogram = program; + return GL_TRUE; +} + +static int CreateProgram2(GLuint* pprogram, GLuint vertexShader, GLuint fragmentShader) { + GLuint program; + GLint compileStatus; + int i; + + // create program object + program = pglCreateProgram(); + + // vertex shader + pglAttachShader(program, vertexShader); + + // fragment shader + pglAttachShader(program, fragmentShader); + + // need to bind locations before linking + pglBindAttribLocation(program, OPENGL_VERTEX_ATTRIB_INDEX, "aVertex"); + pglBindAttribLocation(program, OPENGL_TEXCOORD_ATTRIB_INDEX, "aTexCoord"); + pglBindAttribLocation(program, OPENGL_COLOR0_ATTRIB_INDEX, "aColor0"); + pglBindAttribLocation(program, OPENGL_COLOR1_ATTRIB_INDEX, "aColor1"); + + // link the program + compileStatus = LinkProgram(program); + + if (compileStatus == GL_FALSE) { + fprintf(stderr, "program failed to link\n"); + + pglDeleteProgram(program); + return GL_FALSE; + } + + // validate the program for good measure + compileStatus = ValidateProgram(program); + + if (compileStatus == GL_FALSE) { + fprintf(stderr, "program failed to validate\n"); + + pglDeleteProgram(program); + return GL_FALSE; + } + + *pprogram = program; + return GL_TRUE; +} + +static int InitOpenGLPrograms(void) { + GLenum status; + int i; + + for (i = 0; i < AVP_VERTEX_SHADER_MAX; i++) { + GLuint vertexShader; + + vertexShader = pglCreateShader(GL_VERTEX_SHADER); + + status = CompileShader(vertexShader, AvpVertexShaderSources[i]); + + if (status == GL_FALSE) { + fprintf(stderr, "vertex shader compilation failed\n"); + return GL_FALSE; + } + + AvpVertexShaders[i].shaderObj = vertexShader; + } + + for (i = 0; i < AVP_FRAGMENT_SHADER_MAX; i++) { + GLuint fragmentShader; + + fragmentShader = pglCreateShader(GL_FRAGMENT_SHADER); + + status = CompileShader(fragmentShader, AvpFragmentShaderSources[i]); + + if (status == GL_FALSE) { + fprintf(stderr, "fragment shader compilation failed\n"); + return GL_FALSE; + } + + AvpFragmentShaders[i].shaderObj = fragmentShader; + } + + for (i = 0; i < AVP_SHADER_PROGRAM_MAX; i++) { + GLuint program; + GLuint vertexShader; + GLuint fragmentShader; + + vertexShader = AvpVertexShaders[AvpShaderProgramSources[i].VertexShader].shaderObj; + fragmentShader = AvpFragmentShaders[AvpShaderProgramSources[i].FragmentShader].shaderObj; + + status = CreateProgram2(&program, vertexShader, fragmentShader); + if (status == GL_FALSE) { + fprintf(stderr, "program compilation failed\n"); + return GL_FALSE; + } + + AvpShaderPrograms[i].programObj = program; + AvpShaderPrograms[i].uTexture = pglGetUniformLocation(program, "uTexture"); + } + + return GL_TRUE; +} + +void SelectProgram(enum AVP_SHADER_PROGRAM program) { + + if (CurrShaderProgram != program) { + // supposed to flush here + + unsigned int PrevAttribs = AvpShaderProgramAttributes[CurrShaderProgram]; + unsigned int NextAttribs = AvpShaderProgramAttributes[program]; + unsigned int DiffAttribs = PrevAttribs ^ NextAttribs; + int ShaderProgram = AvpShaderPrograms[program].programObj; + int TextureUniformIndex = AvpShaderPrograms[program].uTexture; + + CurrShaderProgram = program; + pglUseProgram(ShaderProgram); + + if ((DiffAttribs & OPENGL_VERTEX_ATTRIB_BITINDEX) != 0) { + if ((NextAttribs & OPENGL_VERTEX_ATTRIB_BITINDEX) != 0) { + pglEnableVertexAttribArray(OPENGL_VERTEX_ATTRIB_INDEX); } else { - pglBlendFunc(GL_ONE, GL_ONE); + pglDisableVertexAttribArray(OPENGL_VERTEX_ATTRIB_INDEX); } - 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; + if ((DiffAttribs & OPENGL_TEXCOORD_ATTRIB_BITINDEX) != 0) { + if ((NextAttribs & OPENGL_TEXCOORD_ATTRIB_BITINDEX) != 0) { + pglEnableVertexAttribArray(OPENGL_TEXCOORD_ATTRIB_INDEX); + } else { + pglDisableVertexAttribArray(OPENGL_TEXCOORD_ATTRIB_INDEX); + } + } + + if ((DiffAttribs & OPENGL_COLOR0_ATTRIB_BITINDEX) != 0) { + if ((NextAttribs & OPENGL_COLOR0_ATTRIB_BITINDEX) != 0) { + pglEnableVertexAttribArray(OPENGL_COLOR0_ATTRIB_INDEX); + } else { + pglDisableVertexAttribArray(OPENGL_COLOR0_ATTRIB_INDEX); + } + } + + if ((DiffAttribs & OPENGL_COLOR1_ATTRIB_BITINDEX) != 0) { + if ((NextAttribs & OPENGL_COLOR1_ATTRIB_BITINDEX) != 0) { + pglEnableVertexAttribArray(OPENGL_COLOR1_ATTRIB_INDEX); + } else { + pglDisableVertexAttribArray(OPENGL_COLOR1_ATTRIB_INDEX); + } + } + + if (TextureUniformIndex >= 0) { + pglUniform1i(TextureUniformIndex, 0); + } } } -/* -A few things: -- Vertices with a specular color are done twice. - Might want to try spitting apart the three arrays and using the same vertex - array for both passes. -- Fix code for separate color support. -*/ +static void InitOpenGLDefaultTexture(void) { + pglGenTextures(1, &DefaultTexture); -void InitOpenGL() + pglBindTexture(GL_TEXTURE_2D, DefaultTexture); + + pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + + pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); + pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); + + GLubyte defaultTexData[4] = { 255, 255, 255, 255 }; + pglTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, defaultTexData); +} + +void InitOpenGL(int firsttime) { - pglHint( GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST ); - pglHint( GL_GENERATE_MIPMAP_HINT, GL_NICEST ); + if (firsttime) { + InitOpenGLPrograms(); + check_for_errors(); + InitOpenGLDefaultTexture(); + check_for_errors(); + } + + 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 ); - } + if ( ogl_use_multisample_filter_hint ) + { + pglHint( GL_MULTISAMPLE_FILTER_HINT_NV, GL_NICEST ); + } #endif CurrentTranslucencyMode = TRANSLUCENCY_OFF; pglBlendFunc(GL_ONE, GL_ZERO); - pglAlphaFunc(GL_GREATER, 0.0f); - CurrentFilteringMode = FILTERING_BILINEAR_OFF; - pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - CurrentlyBoundTexture = NULL; pglBindTexture(GL_TEXTURE_2D, 0); - - pglEnableClientState(GL_VERTEX_ARRAY); - pglVertexPointer(4, GL_FLOAT, sizeof(varr[0]), varr[0].v); - - pglEnableClientState(GL_TEXTURE_COORD_ARRAY); - pglTexCoordPointer(2, GL_FLOAT, sizeof(varr[0]), varr[0].t); - - pglEnableClientState(GL_COLOR_ARRAY); - pglColorPointer(4, GL_UNSIGNED_BYTE, sizeof(varr[0]), varr[0].c); + + // create array and element array buffers, as required by WebGL + pglGenBuffers(1, &ArrayBuffer); + pglGenBuffers(1, &ElementArrayBuffer); + + pglBindBuffer(GL_ARRAY_BUFFER, ArrayBuffer); + pglBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ElementArrayBuffer); + + pglVertexAttribPointer(OPENGL_VERTEX_ATTRIB_INDEX, 4, GL_FLOAT, GL_FALSE, sizeof(varr[0]), (const GLvoid*) 0); + pglVertexAttribPointer(OPENGL_TEXCOORD_ATTRIB_INDEX, 2, GL_FLOAT, GL_FALSE, sizeof(varr[0]), (const GLvoid*) 16); + pglVertexAttribPointer(OPENGL_COLOR0_ATTRIB_INDEX, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(varr[0]), (const GLvoid*) 24); + pglVertexAttribPointer(OPENGL_COLOR1_ATTRIB_INDEX, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(varr[0]), (const GLvoid*) 28); + + CurrShaderProgram = AVP_SHADER_PROGRAM_MAX; + SelectProgram(AVP_SHADER_PROGRAM_DEFAULT); tarrc = 0; tarrp = tarr; varrc = 0; varrp = varr; - - starrc = 0; - starrp = starr; + + check_for_errors(); } static void FlushTriangleBuffers(int backup) { if (tarrc) { - pglDrawElements(GL_TRIANGLES, tarrc*3, GL_UNSIGNED_SHORT, tarr); + // not optimal but required by WebGL + pglBufferData(GL_ARRAY_BUFFER, varrc * sizeof(varr[0]), varr, GL_STREAM_DRAW); + pglBufferData(GL_ELEMENT_ARRAY_BUFFER, tarrc * sizeof(tarr[0]), tarr, GL_STREAM_DRAW); + + pglDrawElements(GL_TRIANGLES, tarrc*3, GL_UNSIGNED_SHORT, (const GLvoid*) 0); tarrc = 0; tarrp = tarr; @@ -232,57 +821,6 @@ static void FlushTriangleBuffers(int backup) varrc = 0; varrp = varr; } - - if (starrc) { - //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); - //} - - 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); - - //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; - } } static void CheckBoundTextureIsCorrect(D3DTexture *tex) @@ -293,7 +831,7 @@ static void CheckBoundTextureIsCorrect(D3DTexture *tex) FlushTriangleBuffers(1); if (tex == NULL) { - pglBindTexture(GL_TEXTURE_2D, 0); + pglBindTexture(GL_TEXTURE_2D, DefaultTexture); CurrentlyBoundTexture = NULL; @@ -302,6 +840,10 @@ static void CheckBoundTextureIsCorrect(D3DTexture *tex) pglBindTexture(GL_TEXTURE_2D, tex->id); + /*if (tex->hasAlpha != 0 || tex->hasChroma != 0) { + // modulate emulation? + }*/ + if (tex->filter != CurrentFilteringMode) { switch(CurrentFilteringMode) { case FILTERING_BILINEAR_OFF: @@ -310,7 +852,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, TextureMinFilter); + pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, tex->IsNpot ? GL_LINEAR : TextureMinFilter); break; default: break; @@ -336,7 +878,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, TextureMinFilter); + pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, CurrentlyBoundTexture->IsNpot ? GL_LINEAR : TextureMinFilter); break; default: break; @@ -358,7 +900,7 @@ static void CheckTranslucencyModeIsCorrect(enum TRANSLUCENCY_TYPE mode) CurrentTranslucencyMode = mode; } -static void CheckTriangleBuffer(int rver, int sver, int rtri, int stri, D3DTexture *tex, enum TRANSLUCENCY_TYPE mode, enum FILTERING_MODE_ID filter) +static void CheckTriangleBuffer(int rver, int rtri, D3DTexture *tex, enum TRANSLUCENCY_TYPE mode, enum FILTERING_MODE_ID filter) { if ((rver+varrc) >= TA_MAXVERTICES) { FlushTriangleBuffers(0); @@ -413,44 +955,6 @@ static void CheckTriangleBuffer(int rver, int sver, int rtri, int stri, D3DTextu } } #undef OUTPUT_TRIANGLE - -#define OUTPUT_TRIANGLE(x, y, z) \ -{ \ - starrp->a = varrc+(x); \ - starrp->b = varrc+(y); \ - starrp->c = varrc+(z); \ - \ - starrp++; \ - starrc++; \ -} - if (stri == 0) { - switch(sver) { - case 0: - break; - case 3: - OUTPUT_TRIANGLE(0, 2, 1); - break; - case 5: - OUTPUT_TRIANGLE(0, 1, 4); - OUTPUT_TRIANGLE(1, 3, 4); - OUTPUT_TRIANGLE(1, 2, 3); - break; - case 8: - OUTPUT_TRIANGLE(0, 6, 7); - case 7: - OUTPUT_TRIANGLE(0, 5, 6); - case 6: - OUTPUT_TRIANGLE(0, 4, 5); - OUTPUT_TRIANGLE(0, 3, 4); - case 4: - OUTPUT_TRIANGLE(0, 2, 3); - OUTPUT_TRIANGLE(0, 1, 2); - break; - default: - fprintf(stderr, "DrawTriangles_T2F_C4UB_V4F: vertices = %d\n", sver); - } - } -#undef OUTPUT_TRIANGLE } static unsigned int PowerOfTwo(unsigned int v) { @@ -513,34 +1017,26 @@ GLuint CreateOGLTexture(D3DTexture *tex, unsigned char *buf) 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); - if (tex->IsNpot) { - // OpenGL 1.x compatibility - tex->TexWidth = PotWidth; - tex->TexHeight = PotHeight; - - pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + if (tex->IsNpot) { 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); + pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + } else { + pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, TextureMinFilter); + pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); + pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); } - pglTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); + pglTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tex->w, tex->h, 0, GL_RGBA, GL_UNSIGNED_BYTE, buf); + + if (!tex->IsNpot && TextureMinFilter != GL_LINEAR) { + // generate mipmaps if needed + // OpenGL 3.0 / ES 2 feature -- need fbo extension support + //pglGenerateMipmap(GL_TEXTURE_2D); + } tex->buf = NULL; tex->id = h; @@ -660,7 +1156,8 @@ void D3D_Rectangle(int x0, int y0, int x1, int y1, int r, int g, int b, int a) if (y1 <= y0) return; - CheckTriangleBuffer(4, 0, 0, 0, NULL, TRANSLUCENCY_GLOWING, -1); + CheckTriangleBuffer(4, 0, NULL, TRANSLUCENCY_GLOWING, -1); + SelectProgram(AVP_SHADER_PROGRAM_NO_TEXTURE); x[0] = x0; x[0] = (x[0] - ScreenDescriptorBlock.SDB_CentreX)/ScreenDescriptorBlock.SDB_CentreX; @@ -730,8 +1227,9 @@ void D3D_ZBufferedGouraudTexturedPolygon_Output(POLYHEADER *inputPolyPtr, RENDER RecipW = TextureHandle->RecipW / 65536.0f; RecipH = TextureHandle->RecipH / 65536.0f; - CheckTriangleBuffer(RenderPolygon.NumberOfVertices, RenderPolygon.NumberOfVertices, 0, 0, TextureHandle, RenderPolygon.TranslucencyMode, -1); - + CheckTriangleBuffer(RenderPolygon.NumberOfVertices, 0, TextureHandle, RenderPolygon.TranslucencyMode, -1); + SelectProgram(AVP_SHADER_PROGRAM_DEFAULT); + for (i = 0; i < RenderPolygon.NumberOfVertices; i++) { RENDERVERTEX *vertices = &renderVerticesPtr[i]; GLfloat x, y, z; @@ -764,7 +1262,7 @@ void D3D_ZBufferedGouraudTexturedPolygon_Output(POLYHEADER *inputPolyPtr, RENDER varrp->s[0] = GammaValues[vertices->SpecularR]; varrp->s[1] = GammaValues[vertices->SpecularG]; varrp->s[2] = GammaValues[vertices->SpecularB]; - varrp->s[3] = vertices->A; + varrp->s[3] = 0; varrp++; varrc++; @@ -785,8 +1283,9 @@ void D3D_SkyPolygon_Output(POLYHEADER *inputPolyPtr, RENDERVERTEX *renderVertice RecipW = TextureHandle->RecipW / 65536.0f; RecipH = TextureHandle->RecipH / 65536.0f; - CheckTriangleBuffer(RenderPolygon.NumberOfVertices, 0, 0, 0, TextureHandle, RenderPolygon.TranslucencyMode, -1); - + CheckTriangleBuffer(RenderPolygon.NumberOfVertices, 0, TextureHandle, RenderPolygon.TranslucencyMode, -1); + SelectProgram(AVP_SHADER_PROGRAM_NO_SECONDARY); + for (i = 0; i < RenderPolygon.NumberOfVertices; i++) { RENDERVERTEX *vertices = &renderVerticesPtr[i]; GLfloat x, y, z; @@ -847,8 +1346,9 @@ void D3D_ZBufferedCloakedPolygon_Output(POLYHEADER *inputPolyPtr, RENDERVERTEX * RecipW = TextureHandle->RecipW / 65536.0f; RecipH = TextureHandle->RecipH / 65536.0f; - CheckTriangleBuffer(RenderPolygon.NumberOfVertices, 0, 0, 0, TextureHandle, TRANSLUCENCY_NORMAL, -1); - + CheckTriangleBuffer(RenderPolygon.NumberOfVertices, 0, TextureHandle, TRANSLUCENCY_NORMAL, -1); + SelectProgram(AVP_SHADER_PROGRAM_NO_SECONDARY); + for (i = 0; i < RenderPolygon.NumberOfVertices; i++) { RENDERVERTEX *vertices = &renderVerticesPtr[i]; @@ -943,8 +1443,9 @@ void D3D_Decal_Output(DECAL *decalPtr, RENDERVERTEX *renderVerticesPtr) a = decalDescPtr->Alpha; } - CheckTriangleBuffer(RenderPolygon.NumberOfVertices, 0, 0, 0, TextureHandle, decalDescPtr->TranslucencyType, -1); - + CheckTriangleBuffer(RenderPolygon.NumberOfVertices, 0, TextureHandle, decalDescPtr->TranslucencyType, -1); + SelectProgram(AVP_SHADER_PROGRAM_NO_SECONDARY); + for (i = 0; i < RenderPolygon.NumberOfVertices; i++) { RENDERVERTEX *vertices = &renderVerticesPtr[i]; @@ -1035,8 +1536,9 @@ void D3D_Particle_Output(PARTICLE *particlePtr, RENDERVERTEX *renderVerticesPtr) a = particleDescPtr->Alpha; } - CheckTriangleBuffer(RenderPolygon.NumberOfVertices, 0, 0, 0, TextureHandle, particleDescPtr->TranslucencyType, -1); - + CheckTriangleBuffer(RenderPolygon.NumberOfVertices, 0, TextureHandle, particleDescPtr->TranslucencyType, -1); + SelectProgram(AVP_SHADER_PROGRAM_NO_SECONDARY); + for (i = 0; i < RenderPolygon.NumberOfVertices; i++) { RENDERVERTEX *vertices = &renderVerticesPtr[i]; @@ -1087,8 +1589,9 @@ void D3D_PredatorThermalVisionPolygon_Output(POLYHEADER *inputPolyPtr, RENDERVER int i; ZNear = (float) (Global_VDB_Ptr->VDB_ClipZ * GlobalScale); - CheckTriangleBuffer(RenderPolygon.NumberOfVertices, 0, 0, 0, NULL, TRANSLUCENCY_OFF, -1); - + CheckTriangleBuffer(RenderPolygon.NumberOfVertices, 0, NULL, TRANSLUCENCY_OFF, -1); + SelectProgram(AVP_SHADER_PROGRAM_NO_TEXTURE); + for (i = 0; i < RenderPolygon.NumberOfVertices; i++) { RENDERVERTEX *vertices = &renderVerticesPtr[i]; @@ -1133,8 +1636,9 @@ void D3D_ZBufferedGouraudPolygon_Output(POLYHEADER *inputPolyPtr, RENDERVERTEX * flags = inputPolyPtr->PolyFlags; - CheckTriangleBuffer(RenderPolygon.NumberOfVertices, 0, 0, 0, NULL, RenderPolygon.TranslucencyMode, -1); - + CheckTriangleBuffer(RenderPolygon.NumberOfVertices, 0, NULL, RenderPolygon.TranslucencyMode, -1); + SelectProgram(AVP_SHADER_PROGRAM_NO_TEXTURE); + for (i = 0; i < RenderPolygon.NumberOfVertices; i++) { RENDERVERTEX *vertices = &renderVerticesPtr[i]; GLfloat x, y, z; @@ -1209,8 +1713,9 @@ void D3D_PlayerOnFireOverlay() s[3] = u; t[3] = v + 1.0f; - CheckTriangleBuffer(4, 0, 0, 0, TextureHandle, TRANSLUCENCY_GLOWING, FILTERING_BILINEAR_ON); - + CheckTriangleBuffer(4, 0, TextureHandle, TRANSLUCENCY_GLOWING, FILTERING_BILINEAR_ON); + SelectProgram(AVP_SHADER_PROGRAM_NO_SECONDARY); + for (i = 0; i < 4; i++) { varrp->v[0] = x[i]; varrp->v[1] = y[i]; @@ -1266,7 +1771,7 @@ void D3D_PlayerDamagedOverlay(int intensity) GLfloat x[4], y[4], s[4], t[4]; if (i == 0) { - CheckTriangleBuffer(4, 0, 0, 0, TextureHandle, TRANSLUCENCY_INVCOLOUR, FILTERING_BILINEAR_ON); + CheckTriangleBuffer(4, 0, TextureHandle, TRANSLUCENCY_INVCOLOUR, FILTERING_BILINEAR_ON); colour = 0xffffff - baseColour + (intensity<<24); @@ -1275,7 +1780,7 @@ void D3D_PlayerDamagedOverlay(int intensity) r = (colour >> 16) & 0xFF; a = (colour >> 24) & 0xFF; } else { - CheckTriangleBuffer(4, 0, 0, 0, TextureHandle, TRANSLUCENCY_GLOWING, FILTERING_BILINEAR_ON); + CheckTriangleBuffer(4, 0, TextureHandle, TRANSLUCENCY_GLOWING, FILTERING_BILINEAR_ON); colour = baseColour + (intensity<<24); @@ -1285,6 +1790,8 @@ void D3D_PlayerDamagedOverlay(int intensity) a = (colour >> 24) & 0xFF; } + SelectProgram(AVP_SHADER_PROGRAM_NO_SECONDARY); + float sin = (GetSin(theta[i]))/65536.0f/16.0f; float cos = (GetCos(theta[i]))/65536.0f/16.0f; @@ -1368,7 +1875,8 @@ void DrawNoiseOverlay(int tr) // changing the depth func manually, so flush now FlushTriangleBuffers(0); - CheckTriangleBuffer(4, 0, 0, 0, tex, TRANSLUCENCY_GLOWING, FILTERING_BILINEAR_ON); + CheckTriangleBuffer(4, 0, tex, TRANSLUCENCY_GLOWING, FILTERING_BILINEAR_ON); + SelectProgram(AVP_SHADER_PROGRAM_NO_SECONDARY); for (j = 0; j < 4; j++) { varrp->v[0] = x[j]; @@ -1414,11 +1922,13 @@ void D3D_ScreenInversionOverlay() GLfloat x[4], y[4], s[4], t[4]; if (i == 0) { - CheckTriangleBuffer(4, 0, 0, 0, tex, TRANSLUCENCY_DARKENINGCOLOUR, FILTERING_BILINEAR_ON); + CheckTriangleBuffer(4, 0, tex, TRANSLUCENCY_DARKENINGCOLOUR, FILTERING_BILINEAR_ON); } else { - CheckTriangleBuffer(4, 0, 0, 0, tex, TRANSLUCENCY_COLOUR, FILTERING_BILINEAR_ON); + CheckTriangleBuffer(4, 0, tex, TRANSLUCENCY_COLOUR, FILTERING_BILINEAR_ON); } + SelectProgram(AVP_SHADER_PROGRAM_NO_SECONDARY); + float sin = (GetSin(theta[i]))/65536.0f/16.0f; float cos = (GetCos(theta[i]))/65536.0f/16.0f; @@ -1470,8 +1980,9 @@ void D3D_PredatorScreenInversionOverlay() // changing the depth func manually, so flush now FlushTriangleBuffers(0); - CheckTriangleBuffer(4, 0, 0, 0, NULL, TRANSLUCENCY_DARKENINGCOLOUR, -1); - + CheckTriangleBuffer(4, 0, NULL, TRANSLUCENCY_DARKENINGCOLOUR, -1); + SelectProgram(AVP_SHADER_PROGRAM_NO_TEXTURE); + for (j = 0; j < 4; j++) { switch (j) { @@ -1554,7 +2065,8 @@ void DrawScanlinesOverlay(float level) // changing the depth func manually, so flush now FlushTriangleBuffers(0); - CheckTriangleBuffer(4, 0, 0, 0, tex, TRANSLUCENCY_NORMAL, FILTERING_BILINEAR_ON); + CheckTriangleBuffer(4, 0, tex, TRANSLUCENCY_NORMAL, FILTERING_BILINEAR_ON); + SelectProgram(AVP_SHADER_PROGRAM_NO_SECONDARY); for (j = 0; j < 4; j++) { varrp->v[0] = x[j]; @@ -1594,8 +2106,9 @@ void D3D_FadeDownScreen(int brightness, int colour) if (t<0) t = 0; colour = (t<<24)+colour; - CheckTriangleBuffer(4, 0, 0, 0, NULL, TRANSLUCENCY_NORMAL, -1); - + CheckTriangleBuffer(4, 0, NULL, TRANSLUCENCY_NORMAL, -1); + SelectProgram(AVP_SHADER_PROGRAM_NO_TEXTURE); + b = (colour >> 0) & 0xFF; g = (colour >> 8) & 0xFF; r = (colour >> 16) & 0xFF; @@ -1634,6 +2147,68 @@ void D3D_FadeDownScreen(int brightness, int colour) } } +void DrawFullscreenTexture(int texureObject) +{ + int j; + + // using a custom texture, so flush now + FlushTriangleBuffers(0); + CheckTriangleBuffer(4, 0, NULL, TRANSLUCENCY_OFF, -1); + SelectProgram(AVP_SHADER_PROGRAM_NO_COLOR_NO_DISCARD); + pglBindTexture(GL_TEXTURE_2D, texureObject); + pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + + for (j = 0; j < 4; j++) { + + switch (j) { + case 0: + varrp->v[0] = -1.0f; + varrp->v[1] = -1.0f; + varrp->t[0] = 0.0f; + varrp->t[1] = 0.0f; + break; + case 1: + varrp->v[0] = 1.0f; + varrp->v[1] = -1.0f; + varrp->t[0] = 1.0f; + varrp->t[1] = 0.0f; + break; + case 2: + varrp->v[0] = 1.0f; + varrp->v[1] = 1.0f; + varrp->t[0] = 1.0f; + varrp->t[1] = 1.0f; + break; + case 3: + varrp->v[0] = -1.0f; + varrp->v[1] = 1.0f; + varrp->t[0] = 0.0f; + varrp->t[1] = 1.0f; + break; + } + + varrp->v[2] = -1.0f; + varrp->v[3] = 1.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++; + } + + FlushTriangleBuffers(0); + pglBindTexture(GL_TEXTURE_2D, 0); +} + void D3D_HUD_Setup() { FlushTriangleBuffers(1); @@ -1653,8 +2228,9 @@ void D3D_HUDQuad_Output(int imageNumber, struct VertexTag *quadVerticesPtr, unsi /* possibly use polygon offset? (predator hud) */ - CheckTriangleBuffer(4, 0, 0, 0, tex, TRANSLUCENCY_GLOWING, -1); - + CheckTriangleBuffer(4, 0, tex, TRANSLUCENCY_GLOWING, -1); + SelectProgram(AVP_SHADER_PROGRAM_NO_SECONDARY); + RecipW = tex->RecipW / 65536.0f; RecipH = tex->RecipH / 65536.0f; @@ -1982,11 +2558,11 @@ int Hardware_RenderSmallMenuText(char *textPtr, int x, int y, int alpha, enum AV case AVPMENUFORMAT_RIGHTJUSTIFIED: { int length = 0; - signed char *ptr = (signed char*) textPtr; + char *ptr = textPtr; while(*ptr) { - length+=AAFontWidths[*ptr++]; + length+=AAFontWidths[(unsigned char) *ptr++]; } x -= length; @@ -1995,11 +2571,11 @@ int Hardware_RenderSmallMenuText(char *textPtr, int x, int y, int alpha, enum AV case AVPMENUFORMAT_CENTREJUSTIFIED: { int length = 0; - signed char *ptr = (signed char*) textPtr; + char *ptr = textPtr; while(*ptr) { - length+=AAFontWidths[*ptr++]; + length+=AAFontWidths[(unsigned char) *ptr++]; } x -= length/2; @@ -2034,11 +2610,11 @@ int Hardware_RenderSmallMenuText_Coloured(char *textPtr, int x, int y, int alpha case AVPMENUFORMAT_RIGHTJUSTIFIED: { int length = 0; - signed char *ptr = (signed char*) textPtr; + char *ptr = textPtr; while(*ptr) { - length+=AAFontWidths[*ptr++]; + length+=AAFontWidths[(unsigned char) *ptr++]; } x -= length; @@ -2047,11 +2623,11 @@ int Hardware_RenderSmallMenuText_Coloured(char *textPtr, int x, int y, int alpha case AVPMENUFORMAT_CENTREJUSTIFIED: { int length = 0; - signed char *ptr = (signed char*) textPtr; + char *ptr = textPtr; while(*ptr) { - length+=AAFontWidths[*ptr++]; + length+=AAFontWidths[(unsigned char) *ptr++]; } x -= length/2; @@ -2489,7 +3065,8 @@ void D3D_DrawColourBar(int yTop, int yBottom, int rScale, int gScale, int bScale int a; int start; - CheckTriangleBuffer(256*2, 0, 255*2, 0, NULL, TRANSLUCENCY_OFF, -1); + CheckTriangleBuffer(256*2, 255*2, NULL, TRANSLUCENCY_OFF, -1); + SelectProgram(AVP_SHADER_PROGRAM_NO_TEXTURE); start = varrc; @@ -2593,8 +3170,9 @@ void ColourFillBackBufferQuad(int FillColour, int x0, int y0, int x1, int y1) if (y1 <= y0) return; - CheckTriangleBuffer(4, 0, 0, 0, NULL, TRANSLUCENCY_OFF, -1); - + CheckTriangleBuffer(4, 0, NULL, TRANSLUCENCY_OFF, -1); + SelectProgram(AVP_SHADER_PROGRAM_NO_TEXTURE); + b = ((FillColour >> 0) & 0xFF); g = ((FillColour >> 8) & 0xFF); r = ((FillColour >> 16) & 0xFF); @@ -2741,7 +3319,8 @@ void BltImage(RECT *dest, DDSurface *image, RECT *src) s[3] = src->left * image->RecipW; t[3] = src->bottom * image->RecipH; - CheckTriangleBuffer(4, 0, 0, 0, image, TRANSLUCENCY_OFF, -1); + CheckTriangleBuffer(4, 0, image, TRANSLUCENCY_OFF, -1); + SelectProgram(AVP_SHADER_PROGRAM_NO_SECONDARY); for (i = 0; i < 4; i++) { varrp->v[0] = x[i]; @@ -2834,8 +3413,9 @@ void D3D_DrawParticle_Rain(PARTICLE *particlePtr,VECTORCH *prevPositionPtr) ZNear = (float) (Global_VDB_Ptr->VDB_ClipZ * GlobalScale); - CheckTriangleBuffer(3, 0, 0, 0, NULL, TRANSLUCENCY_NORMAL, -1); - + CheckTriangleBuffer(3, 0, NULL, TRANSLUCENCY_NORMAL, -1); + SelectProgram(AVP_SHADER_PROGRAM_NO_TEXTURE); + for (i = 0; i < 3; i++) { GLfloat xf, yf, zf; GLfloat w; @@ -2968,7 +3548,7 @@ void PostLandscapeRendering() MeshZScale/=2; CurrTextureHandle = ImageHeaderArray[ChromeImageNumber].D3DTexture; - CheckTriangleBuffer(0, 0, 0, 0, CurrTextureHandle, TRANSLUCENCY_NORMAL, -1); + CheckTriangleBuffer(0, 0, CurrTextureHandle, TRANSLUCENCY_NORMAL, -1); D3D_DrawWaterPatch(x, y, z); D3D_DrawWaterPatch(x+MeshXScale, y, z); @@ -3000,7 +3580,7 @@ void PostLandscapeRendering() MeshZScale/=2; CurrTextureHandle = ImageHeaderArray[ChromeImageNumber].D3DTexture; - CheckTriangleBuffer(0, 0, 0, 0, CurrTextureHandle, TRANSLUCENCY_NORMAL, -1); + CheckTriangleBuffer(0, 0, CurrTextureHandle, TRANSLUCENCY_NORMAL, -1); D3D_DrawWaterPatch(x, y, z); D3D_DrawWaterPatch(x+MeshXScale, y, z); @@ -3340,7 +3920,7 @@ void PostLandscapeRendering() MeshZScale/=2; CurrTextureHandle = ImageHeaderArray[ChromeImageNumber].D3DTexture; - CheckTriangleBuffer(0, 0, 0, 0, CurrTextureHandle, TRANSLUCENCY_NORMAL, -1); + CheckTriangleBuffer(0, 0, CurrTextureHandle, TRANSLUCENCY_NORMAL, -1); D3D_DrawWaterPatch(x, y, z); D3D_DrawWaterPatch(x+MeshXScale, y, z); D3D_DrawWaterPatch(x+MeshXScale*2, y, z); @@ -3369,7 +3949,7 @@ void PostLandscapeRendering() MeshZScale/=2; CurrTextureHandle = ImageHeaderArray[WaterShaftImageNumber].D3DTexture; - CheckTriangleBuffer(0, 0, 0, 0, CurrTextureHandle, TRANSLUCENCY_NORMAL, -1); + CheckTriangleBuffer(0, 0, CurrTextureHandle, TRANSLUCENCY_NORMAL, -1); D3D_DrawWaterPatch(x, y, z); D3D_DrawWaterPatch(x+MeshXScale, y, z); D3D_DrawWaterPatch(x+MeshXScale*2, y, z); @@ -3436,7 +4016,7 @@ void PostLandscapeRendering() MeshZScale/=2; CurrTextureHandle = ImageHeaderArray[ChromeImageNumber].D3DTexture; - CheckTriangleBuffer(0, 0, 0, 0, CurrTextureHandle, TRANSLUCENCY_NORMAL, -1); + CheckTriangleBuffer(0, 0, CurrTextureHandle, TRANSLUCENCY_NORMAL, -1); D3D_DrawWaterPatch(x, y, z); D3D_DrawWaterPatch(x+MeshXScale, y, z); D3D_DrawWaterPatch(x, y, z+MeshZScale); @@ -3518,7 +4098,7 @@ void D3D_DrawWaterTest(MODULE *testModulePtr) MeshZScale/=2; CurrTextureHandle = ImageHeaderArray[WaterShaftImageNumber].D3DTexture; - CheckTriangleBuffer(0, 0, 0, 0, CurrTextureHandle, TRANSLUCENCY_NORMAL, -1); + CheckTriangleBuffer(0, 0, CurrTextureHandle, TRANSLUCENCY_NORMAL, -1); D3D_DrawWaterPatch(x, y, z); D3D_DrawWaterPatch(x+MeshXScale, y, z); D3D_DrawWaterPatch(x, y, z+MeshZScale); @@ -4708,8 +5288,9 @@ void D3D_DrawMoltenMetalMesh_Unclipped(void) int i, x, y, z; int start; - CheckTriangleBuffer(256, 0, 450, 0, (D3DTexture *)-1, -1, -1); - + CheckTriangleBuffer(256, 450, (D3DTexture *)-1, -1, -1); + SelectProgram(AVP_SHADER_PROGRAM_NO_SECONDARY); + start = varrc; for (i=0; i<256; i++) { GLfloat xf, yf, zf; @@ -4807,7 +5388,8 @@ void D3D_DrawMoltenMetalMesh_Clipped(void) } } - CheckTriangleBuffer(256, 0, c, 0, (D3DTexture *)-1, -1, -1); + CheckTriangleBuffer(256, c, (D3DTexture *)-1, -1, -1); + SelectProgram(AVP_SHADER_PROGRAM_NO_SECONDARY); start = varrc; for (i=0; i<256; i++) diff --git a/src/opengl.h b/src/opengl.h index 91cce43..c5262be 100644 --- a/src/opengl.h +++ b/src/opengl.h @@ -3,7 +3,31 @@ #include "kshape.h" -void InitOpenGL(); + +#define OPENGL_VERTEX_ATTRIB_INDEX 0 +#define OPENGL_TEXCOORD_ATTRIB_INDEX 1 +#define OPENGL_COLOR0_ATTRIB_INDEX 2 +#define OPENGL_COLOR1_ATTRIB_INDEX 3 + +#define OPENGL_VERTEX_ATTRIB_BITINDEX (1 << OPENGL_VERTEX_ATTRIB_INDEX) +#define OPENGL_TEXCOORD_ATTRIB_BITINDEX (1 << OPENGL_TEXCOORD_ATTRIB_INDEX) +#define OPENGL_COLOR0_ATTRIB_BITINDEX (1 << OPENGL_COLOR0_ATTRIB_INDEX) +#define OPENGL_COLOR1_ATTRIB_BITINDEX (1 << OPENGL_COLOR1_ATTRIB_INDEX) + +enum AVP_SHADER_PROGRAM { + AVP_SHADER_PROGRAM_DEFAULT, + AVP_SHADER_PROGRAM_NO_SECONDARY, + AVP_SHADER_PROGRAM_NO_TEXTURE, + AVP_SHADER_PROGRAM_NO_DISCARD, + AVP_SHADER_PROGRAM_NO_SECONDARY_NO_DISCARD, + AVP_SHADER_PROGRAM_NO_COLOR_NO_DISCARD, + AVP_SHADER_PROGRAM_MAX +}; + +void SelectProgram(enum AVP_SHADER_PROGRAM program); +void DrawFullscreenTexture(int texureObject); + +void InitOpenGL(int firsttime); void ThisFramesRenderingHasBegun(); void ThisFramesRenderingHasFinished(); void D3D_SkyPolygon_Output(POLYHEADER *inputPolyPtr, RENDERVERTEX *renderVerticesPtr); diff --git a/src/unaligned.h b/src/unaligned.h new file mode 100644 index 0000000..a0a8594 --- /dev/null +++ b/src/unaligned.h @@ -0,0 +1,29 @@ +#ifndef UNALIGNED_H +#define UNALIGNED_H + +// Anything using these types is not alignment and endian clean. + +#if EMSCRIPTEN +#include + +typedef emscripten_align1_short unaligned_s16; +typedef emscripten_align1_int unaligned_s32; +typedef emscripten_align1_short unaligned_u16; +typedef emscripten_align1_int unaligned_u32; +typedef emscripten_align1_float unaligned_f32; +typedef emscripten_align1_double unaligned_f64; + +#else + +#include + +typedef int16_t unaligned_s16; +typedef int32_t unaligned_s32; +typedef uint16_t unaligned_u16; +typedef uint32_t unaligned_u32; +typedef float unaligned_f32; +typedef double unaligned_f64; + +#endif + +#endif diff --git a/src/win95/aw.h b/src/win95/aw.h index 8b9985c..4a4ecec 100644 --- a/src/win95/aw.h +++ b/src/win95/aw.h @@ -19,6 +19,9 @@ typedef struct DIRECTDRAWSURFACE float RecipW; float RecipH; + int hasAlpha; + int hasChroma; + int filter; } DIRECTDRAWSURFACE; diff --git a/src/win95/awtexld.cpp b/src/win95/awtexld.cpp index 64afca7..ac9d857 100644 --- a/src/win95/awtexld.cpp +++ b/src/win95/awtexld.cpp @@ -145,8 +145,7 @@ namespace AwTl DWORD memFlag; void * ddP; - } - driverDesc; + } driverDesc; /*************************************************************************/ /* Class used to hold all the parameters for the CreateTexture functions */ @@ -496,6 +495,9 @@ void AwBackupTexture::ChoosePixelFormat(AwTl::CreateTextureParms const & _parmsR #endif /* Just convert the texture to 32bpp */ + // may want to support paletted textures + // at some point; at which point, should + // push texture conversion into the opengl layer pixelFormat.palettizedB = 0; pixelFormat.alphaB = 1; @@ -540,7 +542,15 @@ AwTl::SurfUnion AwBackupTexture::CreateTexture(AwTl::CreateTextureParms const & fprintf(stderr, "AwBackupTexture::CreateTexture - chroma\n"); } + if (pixelFormat.texB && m_bTranspMask) { + //fprintf(stderr, "AwBackupTexture::CreateTexture - transparency\n"); + } + // convert asset to 32-bit rgba + // may want to support paletted textures + // at some point; at which point, should + // push texture conversion into the opengl layer + unsigned char *buf = (unsigned char *)malloc(m_nWidth * m_nHeight * 4); Colour * paletteP = m_nPaletteSize ? GetPalette() : NULL; @@ -591,6 +601,8 @@ AwTl::SurfUnion AwBackupTexture::CreateTexture(AwTl::CreateTextureParms const & Tex->w = m_nWidth; Tex->h = m_nHeight; + Tex->hasAlpha = m_bTranspMask; + Tex->hasChroma = m_fFlags & AW_TLF_CHROMAKEY; if (pixelFormat.texB) { CreateOGLTexture(Tex, buf); diff --git a/src/win95/db.c b/src/win95/db.c index ed3cd57..61b2155 100644 --- a/src/win95/db.c +++ b/src/win95/db.c @@ -387,6 +387,10 @@ void db_print_fired(int x, int y, const char *strP) */ void db_log_fired(const char *strP) { +#if EMSCRIPTEN + printf("%s\n", strP); + return; +#else /* Have we intialised the file? */ if(!InitialisedLog) db_log_init(); { @@ -398,6 +402,7 @@ void db_log_fired(const char *strP) fprintf(fP, "%s\n", strP); fclose(fP); } +#endif } void db_log_init(void) diff --git a/src/win95/iff.hpp b/src/win95/iff.hpp index c8060e6..f2dbd9c 100644 --- a/src/win95/iff.hpp +++ b/src/win95/iff.hpp @@ -158,16 +158,19 @@ namespace IFF UBYTE b; }; - union ID + struct ID { UINT32 m_nID; - char m_sID[4]; - inline ID(){} - inline ID(char const * pszID) { m_nID = *reinterpret_cast(pszID); } + inline ID() : m_nID(0) {} + inline ID(char const * pszID) { + m_nID = (pszID[0] << 0) + | (pszID[1] << 8) + | (pszID[2] << 16) + | (pszID[3] << 24); + } inline ID(UINT32 nID) : m_nID(nID) {} inline operator UINT32 () const { return m_nID; } - inline operator char const * () const { return &m_sID[0]; } inline bool operator == (ID const & rId) const { return !m_nID || !rId.m_nID || m_nID == rId.m_nID; } inline bool operator != (ID const & rId) const { return ! operator == (rId); } inline bool operator ! () const { return !m_nID; } @@ -717,8 +720,13 @@ namespace IFF m_nBytesRemaining -= 4; if (m_nBytesRemaining >= 0) { - // cast pointer to pointer to 4 byte data type to force 4 byte 'fast' read - ::MediaRead(m_pMedium, reinterpret_cast(&n.m_sID[0])); + + UBYTE b0, b1, b2, b3; + ::MediaRead(m_pMedium, &b0); + ::MediaRead(m_pMedium, &b1); + ::MediaRead(m_pMedium, &b2); + ::MediaRead(m_pMedium, &b3); + n.m_nID = b0 | (b1 << 8) | (b2 << 16) | (b3 << 24); if (m_pMedium->m_fError) m_bError = true; } else m_bError = true; diff --git a/src/win95/media.hpp b/src/win95/media.hpp index 916e5e6..83035b3 100644 --- a/src/win95/media.hpp +++ b/src/win95/media.hpp @@ -4,24 +4,14 @@ #include #include #include - -class MediaMedium; -// use this to read in simple data types -// note especially that if the size of TYPE is greater than the -// default buffer size, then the operation will fail -// and the virtual end of file error flag will be set -// - use ReadBlock instead -template -void MediaRead(MediaMedium * pThis, TYPE * p); - -// use this to write simple data types -// note especially that if the size of TYPE is greater than the -// default buffer size, then the operation will fail -// and the virtual end of file error flag will be set -// - use WriteBlock instead -template -void MediaWrite(MediaMedium * pThis, TYPE d); +// type names that do not conflcit with anything else +typedef signed char S8; +typedef unsigned char U8; +typedef signed short int S16; +typedef unsigned short int U16; +typedef signed int S32; +typedef unsigned int U32; class MediaMedium { @@ -270,62 +260,13 @@ class MediaMedium virtual void DoSetPos(unsigned nPos) = 0; friend class MediaSection; - - friend class _Media_CompilerHack; -}; -class _Media_CompilerHack -{ - public: - template - static inline void MediaRead(MediaMedium * pThis, TYPE * p) - { - if (pThis->m_nReadBufPos + sizeof(TYPE) <= pThis->m_nBufSize) - { - *p = *reinterpret_cast(static_cast(pThis->m_pReadBuffer) + pThis->m_nReadBufPos/sizeof(char)); - - pThis->m_nReadBufPos += sizeof(TYPE); - } - else - { - pThis->Flush(); - pThis->m_pReadBuffer = pThis->GetReadBuffer(&pThis->m_nBufSize,pThis->m_nDefBufSize); - if (sizeof(TYPE) <= pThis->m_nBufSize) - { - *p = *static_cast(pThis->m_pReadBuffer); - pThis->m_nReadBufPos = sizeof(TYPE); - } - else - { - pThis->m_fError |= MediaMedium::MME_VEOFMET; - } - } - } - - template - static inline void MediaWrite(MediaMedium * pThis, TYPE d) - { - if (pThis->m_nWriteBufPos + sizeof(TYPE) <= pThis->m_nBufSize) - { - *reinterpret_cast(static_cast(pThis->m_pWriteBuffer) + pThis->m_nWriteBufPos/sizeof(char)) = d; - - pThis->m_nWriteBufPos += sizeof(TYPE); - } - else - { - pThis->Flush(); - pThis->m_pWriteBuffer = pThis->GetWriteBuffer(&pThis->m_nBufSize,pThis->m_nDefBufSize); - if (sizeof(TYPE) <= pThis->m_nBufSize) - { - *static_cast(pThis->m_pWriteBuffer) = d; - pThis->m_nWriteBufPos = sizeof(TYPE); - } - else - { - pThis->m_fError |= MediaMedium::MME_VEOFMET; - } - } - } + friend void MediaRead(MediaMedium * pThis, S8 * p); + friend void MediaRead(MediaMedium * pThis, U8 * p); + friend void MediaRead(MediaMedium * pThis, S16 * p); + friend void MediaRead(MediaMedium * pThis, U16 * p); + friend void MediaRead(MediaMedium * pThis, S32 * p); + friend void MediaRead(MediaMedium * pThis, U32 * p); }; // use this to read in simple data types @@ -333,21 +274,86 @@ class _Media_CompilerHack // default buffer size, then the operation will fail // and the virtual end of file error flag will be set // - use ReadBlock instead -template -inline void MediaRead(MediaMedium * pThis, TYPE * p) +inline void MediaRead(MediaMedium * pThis, S8 * p) { - _Media_CompilerHack::MediaRead(pThis,p); + if (pThis->m_nReadBufPos + sizeof(S8) <= pThis->m_nBufSize) + { + *p = static_cast(pThis->m_pReadBuffer)[pThis->m_nReadBufPos]; + pThis->m_nReadBufPos += sizeof(S8); + } + else + { + pThis->Flush(); + pThis->m_pReadBuffer = pThis->GetReadBuffer(&pThis->m_nBufSize,pThis->m_nDefBufSize); + if (sizeof(S8) <= pThis->m_nBufSize) + { + *p = *static_cast(pThis->m_pReadBuffer); + pThis->m_nReadBufPos = sizeof(S8); + } + else + { + pThis->m_fError |= MediaMedium::MME_VEOFMET; + } + } } -// use this to write simple data types -// note especially that if the size of TYPE is greater than the -// default buffer size, then the operation will fail -// and the virtual end of file error flag will be set -// - use WriteBlock instead -template -inline void MediaWrite(MediaMedium * pThis, TYPE d) +inline void MediaRead(MediaMedium * pThis, U8 * p) { - _Media_CompilerHack::MediaWrite(pThis,d); + if (pThis->m_nReadBufPos + sizeof(U8) <= pThis->m_nBufSize) + { + *p = static_cast(pThis->m_pReadBuffer)[pThis->m_nReadBufPos]; + pThis->m_nReadBufPos += sizeof(U8); + } + else + { + pThis->Flush(); + pThis->m_pReadBuffer = pThis->GetReadBuffer(&pThis->m_nBufSize,pThis->m_nDefBufSize); + if (sizeof(U8) <= pThis->m_nBufSize) + { + *p = *static_cast(pThis->m_pReadBuffer); + pThis->m_nReadBufPos = sizeof(U8); + } + else + { + pThis->m_fError |= MediaMedium::MME_VEOFMET; + } + } +} + +inline void MediaRead(MediaMedium * pThis, S16 * p) +{ + S8 b0, b1; + ::MediaRead(pThis, &b0); + ::MediaRead(pThis, &b1); + *p = (b0 << 0) | (b1 << 8); +} + +inline void MediaRead(MediaMedium * pThis, U16 * p) +{ + U8 b0, b1; + ::MediaRead(pThis, &b0); + ::MediaRead(pThis, &b1); + *p = (b0 << 0) | (b1 << 8); +} + +inline void MediaRead(MediaMedium * pThis, S32 * p) +{ + S8 b0, b1, b2, b3; + ::MediaRead(pThis, &b0); + ::MediaRead(pThis, &b1); + ::MediaRead(pThis, &b2); + ::MediaRead(pThis, &b3); + *p = (b0 << 0) | (b1 << 8) | (b2 << 16) | (b3 << 24); +} + +inline void MediaRead(MediaMedium * pThis, U32 * p) +{ + U8 b0, b1, b2, b3; + ::MediaRead(pThis, &b0); + ::MediaRead(pThis, &b1); + ::MediaRead(pThis, &b2); + ::MediaRead(pThis, &b3); + *p = (b0 << 0) | (b1 << 8) | (b2 << 16) | (b3 << 24); } #ifdef _MEDIA_WIN_TARGET diff --git a/src/win95/shpchunk.cpp b/src/win95/shpchunk.cpp index 779045b..341e5e7 100644 --- a/src/win95/shpchunk.cpp +++ b/src/win95/shpchunk.cpp @@ -1,5 +1,5 @@ #include - +#include "unaligned.h" #include "chunk.hpp" #include "chnktype.hpp" #include "shpchunk.hpp" @@ -1610,9 +1610,9 @@ Shape_External_Filename_Chunk::Shape_External_Filename_Chunk(Chunk_With_Children Shape_External_Filename_Chunk::Shape_External_Filename_Chunk (Chunk_With_Children * parent, const char *fdata, size_t /*fsize*/) : Chunk (parent, "SHPEXTFN") { - rescale = *((double *) fdata); + rescale = *((unaligned_f64 *) fdata); fdata += 8; - version_no = *((int *) fdata); + version_no = *((unaligned_s32 *) fdata); fdata += 4; file_name = new char [strlen(fdata)+1]; strcpy (file_name, fdata); diff --git a/src/winfiles.c b/src/winfiles.c index 798210d..38ebfe3 100644 --- a/src/winfiles.c +++ b/src/winfiles.c @@ -762,10 +762,8 @@ static const char* GetGlobalDirectory(const char* argv0) /* Game-specific initialization */ -extern "C" { - extern char const *SecondTex_Directory; - extern char const *SecondSoundDir; -} +extern char const *SecondTex_Directory; +extern char const *SecondSoundDir; void InitGameDirectories(char *argv0) {