summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/avp/hmodel.h26
-rw-r--r--src/avp/scream.cpp11
-rw-r--r--src/avp/stratdef.h14
-rw-r--r--src/avp/win95/frontend/avp_menus.c156
-rw-r--r--src/avp/win95/progress_bar.cpp5
-rw-r--r--src/fixer.h2
-rw-r--r--src/fmv.c16
-rw-r--r--src/main.c4
-rw-r--r--src/main2.c470
-rw-r--r--src/mathline.h2
-rw-r--r--src/menus.c32
-rw-r--r--src/oglfunc.c289
-rw-r--r--src/oglfunc.h226
-rw-r--r--src/openal.c17
-rw-r--r--src/opengl.c1068
-rw-r--r--src/opengl.h26
-rw-r--r--src/unaligned.h29
-rw-r--r--src/win95/aw.h3
-rw-r--r--src/win95/awtexld.cpp16
-rw-r--r--src/win95/db.c5
-rw-r--r--src/win95/iff.hpp22
-rw-r--r--src/win95/media.hpp172
-rw-r--r--src/win95/shpchunk.cpp6
-rw-r--r--src/winfiles.c6
24 files changed, 2024 insertions, 599 deletions
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 <emscripten.h>
+#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;
@@ -1346,21 +1466,39 @@ void InGameFlipBuffers()
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 <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -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 <windows.h>
#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 <string.h>
#include <math.h>
+#if EMSCRIPTEN
+#include <AL/al.h>
+#include <AL/alc.h>
+#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 <AL/eax.h>
#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,35 +1017,27 @@ 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);
+ 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);
+ }
- 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);
- 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);
}
- pglTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
-
tex->buf = NULL;
tex->id = h;
tex->filter = FILTERING_BILINEAR_ON;
@@ -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 <emscripten.h>
+
+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 <stdint.h>
+
+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<UINT32 const *>(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<UINT32 *>(&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 <stdio.h>
#include <limits.h>
#include <string.h>
-
-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 <class TYPE>
-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 <class TYPE>
-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 <class TYPE>
- static inline void MediaRead(MediaMedium * pThis, TYPE * p)
- {
- if (pThis->m_nReadBufPos + sizeof(TYPE) <= pThis->m_nBufSize)
- {
- *p = *reinterpret_cast<TYPE const *>(static_cast<char const *>(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<TYPE const *>(pThis->m_pReadBuffer);
- pThis->m_nReadBufPos = sizeof(TYPE);
- }
- else
- {
- pThis->m_fError |= MediaMedium::MME_VEOFMET;
- }
- }
- }
-
- template <class TYPE>
- static inline void MediaWrite(MediaMedium * pThis, TYPE d)
- {
- if (pThis->m_nWriteBufPos + sizeof(TYPE) <= pThis->m_nBufSize)
- {
- *reinterpret_cast<TYPE *>(static_cast<char *>(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<TYPE *>(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 <class TYPE>
-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<S8 const *>(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<S8 const *>(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 <class TYPE>
-inline void MediaWrite(MediaMedium * pThis, TYPE d)
+inline void MediaRead(MediaMedium * pThis, U8 * p)
+{
+ if (pThis->m_nReadBufPos + sizeof(U8) <= pThis->m_nBufSize)
+ {
+ *p = static_cast<U8 const *>(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<U8 const *>(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)
{
- _Media_CompilerHack::MediaWrite(pThis,d);
+ 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 <math.h>
-
+#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)
{