aboutsummaryrefslogtreecommitdiff
path: root/archive/hge/system.cpp
diff options
context:
space:
mode:
authorGravatar Chris Xiong <chirs241097@gmail.com> 2015-10-26 22:52:36 +0800
committerGravatar Chris Xiong <chirs241097@gmail.com> 2015-10-26 22:52:36 +0800
commit3bd383baf6a17e734329e1fc677c7e86283db772 (patch)
tree69a9148087577f797624ceb9c71323a2563d6bb4 /archive/hge/system.cpp
parent543e4f570be9b279ba558ca61cc02cda251af384 (diff)
downloadbullet-lab-remix-3bd383baf6a17e734329e1fc677c7e86283db772.tar.xz
Added support for relative line numbers.
Added instructions for, brk and cont. (They are still untested...) Parser code cleanup. Removed garbage output to stderr. Reorganize the repository structure. Updated BLR2 code move it into archive. Added BLR1 files.
Diffstat (limited to 'archive/hge/system.cpp')
-rw-r--r--archive/hge/system.cpp933
1 files changed, 933 insertions, 0 deletions
diff --git a/archive/hge/system.cpp b/archive/hge/system.cpp
new file mode 100644
index 0000000..b32783b
--- /dev/null
+++ b/archive/hge/system.cpp
@@ -0,0 +1,933 @@
+/*
+** Haaf's Game Engine 1.8
+** Copyright (C) 2003-2007, Relish Games
+** hge.relishgames.com
+**
+** Core system functions for Unix.
+*/
+
+
+#include "hge_impl.h"
+
+#if PLATFORM_MACOSX
+#include <Carbon/Carbon.h>
+#include <sys/types.h>
+#include <sys/sysctl.h>
+#endif
+
+#define LOWORDINT(n) ((int)((signed short)(LOWORD(n))))
+#define HIWORDINT(n) ((int)((signed short)(HIWORD(n))))
+static const char* SYSTEM_SRC_FN="hge/system.cpp";
+int nRef=0;
+HGE_Impl* pHGE=0;
+
+HGE* CALL hgeCreate(int ver)
+{
+ if(ver==HGE_VERSION)
+ return (HGE*)HGE_Impl::_Interface_Get();
+ else
+ return 0;
+}
+
+
+HGE_Impl* HGE_Impl::_Interface_Get()
+{
+ if(!pHGE) pHGE=new HGE_Impl();
+
+ nRef++;
+
+ return pHGE;
+}
+
+
+void CALL HGE_Impl::Release()
+{
+ nRef--;
+
+ if(!nRef)
+ {
+ if(pHGE->hwnd) pHGE->System_Shutdown();
+ Resource_RemoveAllPacks();
+ delete pHGE;
+ pHGE=0;
+ }
+}
+
+
+bool CALL HGE_Impl::System_Initiate()
+{
+
+ // Log system info
+
+ System_Log("%s: HGE Started...",SYSTEM_SRC_FN);
+
+ System_Log("%s: hge-unix version: %X.%X", SYSTEM_SRC_FN, HGE_VERSION>>8, HGE_VERSION & 0xFF);
+
+ time_t t = time(NULL);
+ System_Log("%s: Date: %s",SYSTEM_SRC_FN, asctime(localtime(&t)));
+
+ System_Log("%s: Application: %s",SYSTEM_SRC_FN,szWinTitle);
+
+ MacOSXVersion = 0x0000;
+
+#if PLATFORM_MACOSX
+ SInt32 ver = 0x0000;
+ char verbuf[16] = { '\0' };
+ if (Gestalt(gestaltSystemVersion, &ver) == noErr)
+ {
+ SInt32 macver_minor = ((ver & 0xF0) >> 4);
+ SInt32 macver_patch = (ver & 0xF);
+ SInt32 macver_major = ((ver & 0xFF00) >> 8);
+ macver_major = (((macver_major / 16) * 10) + (macver_major % 16));
+ MacOSXVersion = ver;
+ if (ver >= 0x1030)
+ {
+ Gestalt(gestaltSystemVersionMajor, &macver_major);
+ Gestalt(gestaltSystemVersionMinor, &macver_minor);
+ Gestalt(gestaltSystemVersionBugFix, &macver_patch);
+ }
+ snprintf(verbuf, sizeof (verbuf), "%d.%d.%d",
+ (int) macver_major, (int) macver_minor, (int) macver_patch);
+ }
+
+ System_Log("OS: Mac OS X%s", verbuf);
+
+ unsigned long phys = 0;
+ size_t len = sizeof (phys);
+ int mib[2] = { CTL_HW, HW_PHYSMEM };
+ if ((sysctl(mib, 2, &phys, &len, NULL, 0) != 0) || (len != sizeof (phys)))
+ phys = 0; // oh well.
+ phys /= 1024;
+ System_Log("Memory: %ldK total",phys);
+
+ // !!! FIXME: we shouldn't force this here, really, but the game I'm working
+ // !!! FIXME: on eats _hundreds_ of megabytes of texture memory. You'll basically
+ // !!! FIXME: lock the system up, swapping, if you don't force s3tc on low-memory boxes...
+ bForceTextureCompression = false; //((phys/1024) <= 512);
+ if (bForceTextureCompression)
+ {
+ System_Log("WARNING: we'll have to force texture compression for this system.");
+ System_Log("WARNING: adding more memory will make the game look better!");
+ }
+
+#else
+ system("uname -svm > os.out");
+ char osv[100];FILE* a=fopen("os.out","r");fgets(osv,50,a);fclose(a);
+ osv[strlen(osv)-1]='\0';
+ System_Log("%s: OS: %s",SYSTEM_SRC_FN,osv);
+ system("rm os.out");
+ a=fopen("/proc/meminfo","r");
+ unsigned totalm,freem;
+ fscanf(a,"MemTotal: %d kB\n",&totalm);
+ fscanf(a,"MemFree: %d kB\n",&freem);
+ System_Log("%s: Memory: %ukB total, %ukB free\n",SYSTEM_SRC_FN,totalm,freem);
+ fclose(a);
+#endif
+
+ if (SDL_Init(SDL_INIT_VIDEO) == -1) {
+ char buffer[1024];
+ snprintf(buffer, sizeof (buffer), "%s: SDL_Init() failed: %s\n",SYSTEM_SRC_FN,SDL_GetError());
+ _PostError(buffer);
+ return false;
+ }
+
+ if (SDL_GL_LoadLibrary(NULL) == -1) {
+ char buffer[1024];
+ snprintf(buffer, sizeof (buffer), "%s: SDL_GL_LoadLibrary() failed: %s\n",SYSTEM_SRC_FN,SDL_GetError());
+ _PostError(buffer);
+ SDL_Quit();
+ return false;
+ }
+
+ const SDL_VideoInfo *vidinfo = SDL_GetVideoInfo();
+ nOrigScreenWidth = vidinfo->current_w;
+ nOrigScreenHeight = vidinfo->current_h;
+ System_Log("%s: Screen: %dx%d\n",SYSTEM_SRC_FN,nOrigScreenWidth,nOrigScreenHeight);
+
+ // Create window
+ SDL_WM_SetCaption(szWinTitle, szWinTitle);
+ SDL_GL_SetAttribute(SDL_GL_RED_SIZE, nScreenBPP >= 32 ? 8 : 4);
+ SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, nScreenBPP >= 32 ? 8 : 4);
+ SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, nScreenBPP >= 32 ? 8 : 4);
+ SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, nScreenBPP >= 32 ? 8 : 4);
+ SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, bZBuffer ? 16 : 0);
+ SDL_GL_SetAttribute(SDL_GL_ACCELERATED_VISUAL, 1);
+ SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
+ SDL_GL_SetAttribute(SDL_GL_SWAP_CONTROL, bVsync ? 1 : 0);
+ Uint32 flags = SDL_OPENGL;
+ if (!bWindowed)
+ flags |= SDL_FULLSCREEN;
+ hwnd = SDL_SetVideoMode(nScreenWidth, nScreenHeight, nScreenBPP, flags);
+ if (!hwnd)
+ {
+ char buffer[1024];
+ snprintf(buffer, sizeof (buffer), "SDL_SetVideoMode() failed: %s\n", SDL_GetError());
+ _PostError(buffer);
+ SDL_Quit();
+ return false;
+ }
+
+ if (!bWindowed)
+ {
+ bMouseOver = true;
+ if (!pHGE->bActive)
+ pHGE->_FocusChange(true);
+ }
+
+ SDL_ShowCursor(bHideMouse ? SDL_DISABLE : SDL_ENABLE);
+
+#if !PLATFORM_MACOSX
+ SDL_Surface *icon = SDL_LoadBMP("hgeicon.bmp"); // HACK.
+ if (icon)
+ {
+ SDL_SetColorKey(icon, SDL_SRCCOLORKEY, SDL_MapRGB(icon->format, 255, 0, 255));
+ SDL_WM_SetIcon(icon, NULL);
+ SDL_FreeSurface(icon);
+ }
+#endif
+
+ // Init subsystems
+
+ Random_Seed();
+ _InitPowerStatus();
+ _InputInit();
+ if(!_GfxInit()) { System_Shutdown(); return false; }
+ if(!_SoundInit()) { System_Shutdown(); return false; }
+
+ System_Log("%s: Init done.\n",SYSTEM_SRC_FN);
+
+ fTime=0.0f;
+ t0=t0fps=SDL_GetTicks();
+ dt=cfps=0;
+ nFPS=0;
+ nFPSf=0.0f;
+ Fcnt=0;
+ fUpdateFPSDelay=0.0f;
+
+ // Show splash
+
+//#ifdef DEMO
+
+ bool (*func)();
+ bool (*rfunc)();
+ HWND hwndTmp;
+
+ if(/*pHGE->bDMO*/true)
+ {
+ SDL_Delay(200);
+ func=(bool(*)())pHGE->System_GetStateFunc(HGE_FRAMEFUNC);
+ rfunc=(bool(*)())pHGE->System_GetStateFunc(HGE_RENDERFUNC);
+ hwndTmp=hwndParent; hwndParent=0;
+ pHGE->System_SetStateFunc(HGE_FRAMEFUNC, DFrame);
+ pHGE->System_SetStateFunc(HGE_RENDERFUNC, 0);
+ DInit();
+ pHGE->System_Start();
+ DDone();
+ hwndParent=hwndTmp;
+ pHGE->System_SetStateFunc(HGE_FRAMEFUNC, func);
+ pHGE->System_SetStateFunc(HGE_RENDERFUNC, rfunc);
+ }
+
+//#endif
+
+ // Done
+
+ return true;
+}
+
+void CALL HGE_Impl::System_Shutdown()
+{
+ System_Log("\n%s: Closing session..",SYSTEM_SRC_FN);
+
+ if(hSearch) { closedir(hSearch); hSearch=0; }
+ _ClearQueue();
+ _SoundDone();
+ _GfxDone();
+ _DonePowerStatus();
+
+ SDL_Quit();
+ hwnd=0;
+
+ System_Log("%s: Session ended.",SYSTEM_SRC_FN);
+}
+
+
+bool CALL HGE_Impl::System_Start()
+{
+ if(!hwnd)
+ {
+ _PostError("System_Start: System_Initiate wasn't called");
+ return false;
+ }
+
+ if(!procFrameFunc) {
+ _PostError("System_Start: No frame function defined");
+ return false;
+ }
+
+ bActive=true;
+
+ // MAIN LOOP
+ for(;;)
+ {
+ SDL_Event e;
+ bool keep_going = true;
+ while (SDL_PollEvent(&e) && keep_going)
+ keep_going = _ProcessSDLEvent(e);
+
+ if (!keep_going)
+ break;
+
+ // Check if mouse is over HGE window for Input_IsMouseOver
+
+ _UpdateMouse();
+
+ // If HGE window is focused or we have the "don't suspend" state - process the main loop
+
+ if(bActive || bDontSuspend)
+ {
+ Uint32 sdlticks;
+ // Ensure we have at least 1ms time step
+ // to not confuse user's code with 0
+
+ do { sdlticks=SDL_GetTicks(); dt = sdlticks - t0; } while(dt < 1);
+
+ // If we reached the time for the next frame
+ // or we just run in unlimited FPS mode, then
+ // do the stuff
+
+ if(dt >= nFixedDelta)
+ {
+ // fDeltaTime = time step in seconds returned by Timer_GetDelta
+
+ fDeltaTime=dt/1000.0f;
+
+ // Cap too large time steps usually caused by lost focus to avoid jerks
+
+ if(fDeltaTime > 0.2f)
+ {
+ fDeltaTime = nFixedDelta ? nFixedDelta/1000.0f : 0.01f;
+ }
+
+ // Update time counter returned Timer_GetTime
+
+ fTime += fDeltaTime;
+
+ // Store current time for the next frame
+ // and count FPS
+
+ t0=sdlticks;
+ if(t0-t0fps <= 1000) cfps++;
+ else
+ {
+ nFPS=cfps; cfps=0; t0fps=t0;
+ _UpdatePowerStatus();
+ }
+ ++Fcnt;fUpdateFPSDelay+=fDeltaTime;
+ if(fUpdateFPSDelay>1)
+ {
+ nFPSf=Fcnt/fUpdateFPSDelay;
+ fUpdateFPSDelay=0.0f;
+ Fcnt=0;
+ }
+
+ // Do user's stuff
+
+ if(procFrameFunc()) break;
+ if(procRenderFunc) procRenderFunc();
+
+ // If if "child mode" - return after processing single frame
+
+ if(hwndParent) break;
+
+ // Clean up input events that were generated by
+ // WindowProc and weren't handled by user's code
+ for (int i=1;i<=255;++i)
+ keylast[i]=Input_GetKeyState(i);
+ _ClearQueue();
+
+ // If we use VSYNC - we could afford a little
+ // sleep to lower CPU usage
+
+ // if(!bWindowed && nHGEFPS==HGEFPS_VSYNC) Sleep(1);
+ }
+
+ // If we have a fixed frame rate and the time
+ // for the next frame isn't too close, sleep a bit
+
+ else
+ {
+ if(nFixedDelta && dt+3 < nFixedDelta) SDL_Delay(1);
+ }
+ }
+
+ // If main loop is suspended - just sleep a bit
+ // (though not too much to allow instant window
+ // redraw if requested by OS)
+
+ else SDL_Delay(1);
+ }
+
+ _ClearQueue();
+
+ bActive=false;
+
+ return true;
+}
+
+void CALL HGE_Impl::System_SetStateBool(hgeBoolState state, bool value)
+{
+ switch(state)
+ {
+ case HGE_WINDOWED: if(VertArray || hwndParent) break;
+ if(pOpenGLDevice && bWindowed != value)
+ {
+ STUBBED("backbuffer format");
+ //if(d3dppW.BackBufferFormat==D3DFMT_UNKNOWN || d3dppFS.BackBufferFormat==D3DFMT_UNKNOWN) break;
+
+ bWindowed=value;
+
+ //if(_format_id(d3dpp->BackBufferFormat) < 4) nScreenBPP=16;
+ //else nScreenBPP=32;
+
+ Uint32 flags = SDL_OPENGL;
+ if (!bWindowed)
+ flags |= SDL_FULLSCREEN;
+ hwnd = SDL_SetVideoMode(nScreenWidth, nScreenHeight, nScreenBPP, flags);
+ _GfxRestore();
+ if (!bWindowed)
+ {
+ bMouseOver = true;
+ if (!pHGE->bActive)
+ pHGE->_FocusChange(true);
+ }
+ }
+ else bWindowed=value;
+ break;
+
+ case HGE_ZBUFFER: if(!pOpenGLDevice) bZBuffer=value;
+ break;
+
+ case HGE_TEXTUREFILTER: if (bTextureFilter==value) break;
+ if(pOpenGLDevice)
+ _render_batch();
+ bTextureFilter=value;
+ _SetTextureFilter();
+ break;
+
+ case HGE_USESOUND: if(bUseSound!=value)
+ {
+ bUseSound=value;
+ if(bUseSound) _SoundInit();
+ if(!bUseSound) _SoundDone();
+ }
+ break;
+
+ case HGE_HIDEMOUSE: bHideMouse=value; if (pHGE->hwnd) SDL_ShowCursor(bHideMouse ? SDL_DISABLE : SDL_ENABLE); break;
+
+ case HGE_DONTSUSPEND: bDontSuspend=value; break;
+
+ #ifdef DEMO
+ case HGE_SHOWSPLASH: bDMO=value; break;
+ #endif
+ default:break;
+ }
+}
+
+void CALL HGE_Impl::System_SetStateFunc(hgeFuncState state, hgeCallback value)
+{
+ switch(state)
+ {
+ case HGE_FRAMEFUNC: procFrameFunc=value; break;
+ case HGE_RENDERFUNC: procRenderFunc=value; break;
+ case HGE_FOCUSLOSTFUNC: procFocusLostFunc=value; break;
+ case HGE_FOCUSGAINFUNC: procFocusGainFunc=value; break;
+ case HGE_GFXRESTOREFUNC: procGfxRestoreFunc=value; break;
+ case HGE_EXITFUNC: procExitFunc=value; break;
+ default:break;
+ }
+}
+
+void CALL HGE_Impl::System_SetStateHwnd(hgeHwndState state, HWND value)
+{
+ switch(state)
+ {
+ case HGE_HWNDPARENT:
+ if (value != 0) {
+ System_Log("WARNING: Trying to set HGE_HWNDPARENT is unsupported!\n");
+ System_Log("WARNING: You will not get the behaviour you expect\n");
+ }
+ if(!hwnd)
+ hwndParent=value;
+ break;
+ default:break;
+ }
+}
+
+void CALL HGE_Impl::System_SetStateInt(hgeIntState state, int value)
+{
+ switch(state)
+ {
+ case HGE_SCREENWIDTH: if(!pOpenGLDevice) nScreenWidth=value; break;
+
+ case HGE_SCREENHEIGHT: if(!pOpenGLDevice) nScreenHeight=value; break;
+
+ case HGE_SCREENBPP: if(!pOpenGLDevice) nScreenBPP=value; break;
+
+ case HGE_SAMPLERATE: if((!hOpenAL) && (!hBass)) nSampleRate=value;
+ break;
+
+ case HGE_FXVOLUME: nFXVolume=value;
+ _SetFXVolume(nFXVolume);
+ break;
+
+ case HGE_MUSVOLUME: nMusVolume=value;
+ _SetMusVolume(nMusVolume);
+ break;
+
+ case HGE_STREAMVOLUME: nStreamVolume=value;
+ _SetStreamVolume(nStreamVolume);
+ break;
+
+ case HGE_FPS: bVsync = (value==HGEFPS_VSYNC);
+ if(pOpenGLDevice) SDL_GL_SetAttribute(SDL_GL_SWAP_CONTROL, bVsync ? 1 : 0);
+ nHGEFPS=value;
+ if(nHGEFPS>0) nFixedDelta=int(1000.0f/value);
+ else nFixedDelta=0;
+ break;
+ default:break;
+ }
+}
+
+void CALL HGE_Impl::System_SetStateString(hgeStringState state, const char *value)
+{
+ FILE *hf;
+
+ switch(state)
+ {
+ case HGE_ICON: szIcon=value;
+ STUBBED("icon");
+ //if(pHGE->hwnd) SetClassLong(pHGE->hwnd, GCL_HICON, (LONG)LoadIcon(pHGE->hInstance, szIcon));
+ break;
+ case HGE_TITLE: strcpy(szWinTitle,value);
+ if(pHGE->hwnd) SDL_WM_SetCaption(value, value);
+ break;
+ case HGE_INIFILE: if(value) { strcpy(szIniFile,Resource_MakePath(value)); _LoadIniFile(szIniFile); }
+ else szIniFile[0]=0;
+ break;
+ case HGE_LOGFILE: if(value)
+ {
+ strcpy(szLogFile,Resource_MakePath(value));
+ hf=fopen(szLogFile, "w");
+ if(!hf) szLogFile[0]=0;
+ else fclose(hf);
+ }
+ else szLogFile[0]=0;
+ break;
+ default:break;
+ }
+}
+
+bool CALL HGE_Impl::System_GetStateBool(hgeBoolState state)
+{
+ switch(state)
+ {
+ case HGE_WINDOWED: return bWindowed;
+ case HGE_ZBUFFER: return bZBuffer;
+ case HGE_TEXTUREFILTER: return bTextureFilter;
+ case HGE_USESOUND: return bUseSound;
+ case HGE_DONTSUSPEND: return bDontSuspend;
+ case HGE_HIDEMOUSE: return bHideMouse;
+
+ #ifdef DEMO
+ case HGE_SHOWSPLASH: return bDMO;
+ #endif
+ default:break;
+ }
+
+ return false;
+}
+
+hgeCallback CALL HGE_Impl::System_GetStateFunc(hgeFuncState state)
+{
+ switch(state)
+ {
+ case HGE_FRAMEFUNC: return procFrameFunc;
+ case HGE_RENDERFUNC: return procRenderFunc;
+ case HGE_FOCUSLOSTFUNC: return procFocusLostFunc;
+ case HGE_FOCUSGAINFUNC: return procFocusGainFunc;
+ case HGE_EXITFUNC: return procExitFunc;
+ default:break;
+ }
+
+ return NULL;
+}
+
+HWND CALL HGE_Impl::System_GetStateHwnd(hgeHwndState state)
+{
+ switch(state)
+ {
+ case HGE_HWND: return hwnd;
+ case HGE_HWNDPARENT: return hwndParent;
+ default:break;
+ }
+
+ return 0;
+}
+
+int CALL HGE_Impl::System_GetStateInt(hgeIntState state)
+{
+ switch(state)
+ {
+ case HGE_ORIGSCREENWIDTH: return nOrigScreenWidth;
+ case HGE_ORIGSCREENHEIGHT: return nOrigScreenHeight;
+ case HGE_SCREENWIDTH: return nScreenWidth;
+ case HGE_SCREENHEIGHT: return nScreenHeight;
+ case HGE_SCREENBPP: return nScreenBPP;
+ case HGE_SAMPLERATE: return nSampleRate;
+ case HGE_FXVOLUME: return nFXVolume;
+ case HGE_MUSVOLUME: return nMusVolume;
+ case HGE_STREAMVOLUME: return nStreamVolume;
+ case HGE_FPS: return nHGEFPS;
+ case HGE_POWERSTATUS: return nPowerStatus;
+ default:break;
+ }
+
+ return 0;
+}
+
+const char* CALL HGE_Impl::System_GetStateString(hgeStringState state) {
+ switch(state) {
+ case HGE_ICON: return szIcon;
+ case HGE_TITLE: return szWinTitle;
+ case HGE_INIFILE: if(szIniFile[0]) return szIniFile;
+ else return 0;
+ case HGE_LOGFILE: if(szLogFile[0]) return szLogFile;
+ else return 0;
+ default:break;
+ }
+
+ return NULL;
+}
+
+const char* CALL HGE_Impl::System_GetErrorMessage()
+{
+ return szError;
+}
+
+void CALL HGE_Impl::System_Log(const char *szFormat, ...)
+{
+ FILE *hf = NULL;
+ va_list ap;
+
+ if(!szLogFile[0]) return;
+
+ hf = fopen(szLogFile, "a");
+ if(!hf) return;
+
+ va_start(ap, szFormat);
+ vfprintf(hf, szFormat, ap);
+ va_end(ap);
+ va_start(ap, szFormat);
+ vfprintf(stderr, szFormat, ap);
+ va_end(ap);
+ fprintf(hf, "\n");
+ fprintf(stderr, "\n");
+
+ fclose(hf);
+}
+
+bool CALL HGE_Impl::System_Launch(const char *url)
+{
+#if PLATFORM_MACOSX
+ CFURLRef cfurl = CFURLCreateWithBytes(NULL, (const UInt8 *) url,
+ strlen(url), kCFStringEncodingUTF8, NULL);
+ const OSStatus err = LSOpenCFURLRef(cfurl, NULL);
+ CFRelease(cfurl);
+ return (err == noErr);
+#else
+ char command[1024];sprintf(command,"xdg-open %s",url);
+ system(command);
+ return false;
+#endif
+}
+
+void CALL HGE_Impl::System_Snapshot(const char *filename)
+{
+ char *shotname, tempname[_MAX_PATH];
+ int i;
+
+ if(!filename)
+ {
+ i=0;
+ shotname=Resource_EnumFiles("shot???.bmp");
+ while(shotname)
+ {
+ i++;
+ shotname=Resource_EnumFiles();
+ }
+ sprintf(tempname, "shot%03d.bmp", i);
+ filename=Resource_MakePath(tempname);
+ }
+
+ if(pOpenGLDevice)
+ {
+ #if SDL_BYTEORDER == SDL_BIG_ENDIAN
+ const Uint32 rmask = 0xFF0000;
+ const Uint32 gmask = 0x00FF00;
+ const Uint32 bmask = 0x0000FF;
+ #else
+ const Uint32 rmask = 0x0000FF;
+ const Uint32 gmask = 0x00FF00;
+ const Uint32 bmask = 0xFF0000;
+ #endif
+
+ pOpenGLDevice->glFinish(); // make sure screenshot is ready.
+ SDL_Surface *screen = SDL_GetVideoSurface();
+ SDL_Surface *surface = SDL_CreateRGBSurface(SDL_SWSURFACE, screen->w, screen->h, 24, rmask, gmask, bmask, 0);
+ pOpenGLDevice->glReadPixels(0, 0, screen->w, screen->h, GL_RGB, GL_UNSIGNED_BYTE, surface->pixels);
+ //flip the image so that it won't be upside down...
+ _flipSDLSurface(surface->pitch,surface->h,surface->pixels);
+ SDL_SaveBMP(surface, filename);
+ SDL_FreeSurface(surface);
+ }
+}
+
+//////// Implementation ////////
+
+
+HGE_Impl::HGE_Impl()
+{
+ CurTexture=0;
+
+ //hInstance=GetModuleHandle(0);
+ hwnd=0;
+ bActive=false;
+ szError[0]=0;
+
+ pOpenGLDevice=0;
+ pTargets=0;
+ pCurTarget=0;
+ //pScreenSurf=0;
+ //pScreenDepth=0;
+ pVB=0;
+ pIB=0;
+ VertArray=0;
+ textures=0;
+
+ hBass=0;
+ hOpenAL=0;
+ bSilent=false;
+ streams=0;
+
+ hSearch=0;
+ res=0;
+
+ queue=0;
+ Char=VKey=Zpos=0;
+ Xpos=Ypos=0.0f;
+ bMouseOver=true;
+ bCaptured=false;
+
+ nHGEFPS=HGEFPS_UNLIMITED;
+ fTime=0.0f;
+ fUpdateFPSDelay=0.0f;
+ fDeltaTime=0.0f;
+ nFPS=0;
+ nFPSf=0.0f;
+ Fcnt=0;
+
+ procFrameFunc=0;
+ procRenderFunc=0;
+ procFocusLostFunc=0;
+ procFocusGainFunc=0;
+ procGfxRestoreFunc=0;
+ procExitFunc=0;
+ szIcon=0;
+ strcpy(szWinTitle,"HGE");
+ nOrigScreenWidth=800;
+ nOrigScreenHeight=600;
+ nScreenWidth=800;
+ nScreenHeight=600;
+ nScreenBPP=32;
+ bWindowed=false;
+ bVsync=false;
+ bZBuffer=false;
+ bTextureFilter=true;
+ szLogFile[0]=0;
+ szIniFile[0]=0;
+ bUseSound=true;
+ nSampleRate=44100;
+ nFXVolume=100;
+ nMusVolume=100;
+ nStreamVolume=100;
+ nFixedDelta=0;
+ bHideMouse=true;
+ bDontSuspend=false;
+ hwndParent=0;
+ keymods=KMOD_NONE;
+
+ nPowerStatus=HGEPWR_UNSUPPORTED;
+
+#ifdef DEMO
+ bDMO=true;
+#endif
+
+ bForceTextureCompression = false;
+
+ STUBBED("get basedir");
+// GetModuleFileName(GetModuleHandle(NULL), szAppPath, sizeof(szAppPath));
+ szAppPath[0] = '\0';
+ int i;
+ for(i=strlen(szAppPath)-1; i>0; i--) if(szAppPath[i]=='/') break;
+ szAppPath[i+1]=0;
+}
+
+void HGE_Impl::_PostError(const char *error)
+{
+ System_Log(error);
+ strcpy(szError,error);
+}
+
+void HGE_Impl::_FocusChange(bool bAct)
+{
+ bActive=bAct;
+
+ if(bActive)
+ {
+ if(procFocusGainFunc) procFocusGainFunc();
+ }
+ else
+ {
+ if(procFocusLostFunc) procFocusLostFunc();
+ }
+}
+
+bool HGE_Impl::_ProcessSDLEvent(const SDL_Event &e)
+{
+ switch(e.type)
+ {
+ case SDL_VIDEOEXPOSE:
+ if(pHGE->procRenderFunc && pHGE->bWindowed) procRenderFunc();
+ break;
+
+ case SDL_QUIT:
+ if(pHGE->procExitFunc && !pHGE->procExitFunc()) break;
+ return false;
+
+ case SDL_ACTIVEEVENT: {
+ const bool bActivating = (e.active.gain != 0);
+ if (e.active.state & SDL_APPINPUTFOCUS) {
+ if(pHGE->bActive != bActivating) pHGE->_FocusChange(bActivating);
+ }
+ if (e.active.state & SDL_APPMOUSEFOCUS) {
+ bMouseOver = bActivating;
+ }
+ break;
+ }
+
+ case SDL_KEYDOWN:
+ keymods = e.key.keysym.mod;
+
+ #if PLATFORM_MACOSX // handle Apple-Q hotkey, etc.
+ if (keymods & KMOD_META) {
+ if (e.key.keysym.sym == SDLK_q) {
+ if(pHGE->procExitFunc && !pHGE->procExitFunc()) break;
+ return false;
+ } else if (e.key.keysym.sym == SDLK_m) {
+ _MacMinimizeWindow();
+ break;
+ } else if (e.key.keysym.sym == SDLK_h) {
+ if (keymods & KMOD_ALT)
+ _MacHideOtherWindows();
+ else
+ _MacHideWindow();
+ break;
+ }
+ }
+ #endif
+
+ //#if 0 // (my app handles this, actually.)
+ // hotkey to toggle fullscreen/windowed mode.
+ if ( (keymods & KMOD_ALT) && ((e.key.keysym.sym == SDLK_RETURN) || (e.key.keysym.sym == SDLK_KP_ENTER)) ) {
+ System_SetStateBool(HGE_WINDOWED, !bWindowed);
+ break;
+ }
+ //#endif
+
+ pHGE->_BuildEvent(INPUT_KEYDOWN, e.key.keysym.sym, 0, 0 /*(lparam & 0x40000000) ? HGEINP_REPEAT:0*/, -1, -1);
+ break;
+
+ case SDL_KEYUP:
+ keymods = e.key.keysym.mod;
+ pHGE->_BuildEvent(INPUT_KEYUP, e.key.keysym.sym, 0, 0, -1, -1);
+ break;
+
+ case SDL_MOUSEBUTTONDOWN:
+ if (e.button.button == SDL_BUTTON_LEFT)
+ pHGE->_BuildEvent(INPUT_MBUTTONDOWN, HGEK_LBUTTON, 0, 0, e.button.x, e.button.y);
+ else if (e.button.button == SDL_BUTTON_RIGHT)
+ pHGE->_BuildEvent(INPUT_MBUTTONDOWN, HGEK_RBUTTON, 0, 0, e.button.x, e.button.y);
+ else if (e.button.button == SDL_BUTTON_MIDDLE)
+ pHGE->_BuildEvent(INPUT_MBUTTONDOWN, HGEK_MBUTTON, 0, 0, e.button.x, e.button.y);
+ else if (e.button.button == SDL_BUTTON_WHEELUP)
+ pHGE->_BuildEvent(INPUT_MOUSEWHEEL, 1, 0, 0, e.button.x, e.button.y);
+ else if (e.button.button == SDL_BUTTON_WHEELDOWN)
+ pHGE->_BuildEvent(INPUT_MOUSEWHEEL, -1, 0, 0, e.button.x, e.button.y);
+ break;
+
+#if 0
+ case WM_LBUTTONDBLCLK:
+ pHGE->_BuildEvent(INPUT_MBUTTONDOWN, HGEK_LBUTTON, 0, HGEINP_REPEAT, LOWORDINT(lparam), HIWORDINT(lparam));
+ return FALSE;
+ case WM_MBUTTONDBLCLK:
+ pHGE->_BuildEvent(INPUT_MBUTTONDOWN, HGEK_MBUTTON, 0, HGEINP_REPEAT, LOWORDINT(lparam), HIWORDINT(lparam));
+ return FALSE;
+ case WM_RBUTTONDBLCLK:
+ pHGE->_BuildEvent(INPUT_MBUTTONDOWN, HGEK_RBUTTON, 0, HGEINP_REPEAT, LOWORDINT(lparam), HIWORDINT(lparam));
+ return FALSE;
+#endif
+
+ case SDL_MOUSEBUTTONUP:
+ if (e.button.button == SDL_BUTTON_LEFT)
+ pHGE->_BuildEvent(INPUT_MBUTTONUP, HGEK_LBUTTON, 0, 0, e.button.x, e.button.y);
+ else if (e.button.button == SDL_BUTTON_RIGHT)
+ pHGE->_BuildEvent(INPUT_MBUTTONUP, HGEK_RBUTTON, 0, 0, e.button.x, e.button.y);
+ else if (e.button.button == SDL_BUTTON_MIDDLE)
+ pHGE->_BuildEvent(INPUT_MBUTTONUP, HGEK_MBUTTON, 0, 0, e.button.x, e.button.y);
+ break;
+
+ case SDL_MOUSEMOTION:
+ pHGE->_BuildEvent(INPUT_MOUSEMOVE, 0, 0, 0, e.motion.x, e.motion.y);
+ break;
+
+
+#if 0 // !!! FIXME
+ case WM_SIZE:
+ if(pHGE->pD3D && wparam==SIZE_RESTORED) pHGE->_Resize(LOWORD(lparam), HIWORD(lparam));
+ //return FALSE;
+ break;
+#endif
+ }
+
+ return true;
+}
+int HGE_Impl::_flipSDLSurface(int pitch, int height, void* image_pixels)
+{
+ int index;
+ void* temp_row;
+ int height_div_2;
+
+ temp_row=(void *)malloc(pitch);
+ assert(temp_row);
+ height_div_2 = (int) (height * .5);
+ for(index = 0; index < height_div_2; index++)
+ {
+ memcpy((Uint8 *)temp_row,(Uint8 *)(image_pixels)+pitch*index,pitch);
+ memcpy((Uint8 *)(image_pixels)+pitch*index,(Uint8 *)(image_pixels)+pitch*(height-index-1),pitch);
+ memcpy((Uint8 *)(image_pixels)+pitch*(height-index-1),temp_row,pitch);
+ }
+ free(temp_row);
+ return 0;
+}
+// end of system_unix.cpp ...