/*
** 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 ...