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