//------------------------------------------------------------------------------------- // // JGE++ is a hardware accelerated 2D game SDK for PSP/Windows. // // Licensed under the BSD license, see LICENSE in JGE root for details. // // Copyright (c) 2007 James Hui (a.k.a. Dr.Watson) // //------------------------------------------------------------------------------------- #include #include #include #include "../include/JGE.h" #include "../include/JApp.h" #include "../include/JRenderer.h" #include "../include/JSoundSystem.h" #include "../include/Vector2D.h" #include "../include/JResourceManager.h" #include "../include/JFileSystem.h" //#include "../include/JParticleSystem.h" ////////////////////////////////////////////////////////////////////////// #if defined (WIN32) // WIN32 specific code #include "../../Dependencies/include/png.h" #include "../../Dependencies/include/fmod.h" u8 JGE::GetAnalogX() { if (GetButtonState(JGE_BTN_LEFT)) return 0; if (GetButtonState(JGE_BTN_RIGHT)) return 0xff; return 0x80; } u8 JGE::GetAnalogY() { if (GetButtonState(JGE_BTN_UP)) return 0; if (GetButtonState(JGE_BTN_DOWN)) return 0xff; return 0x80; } #elif defined (LINUX) // Unix specific code #include #include "png.h" #include "../Dependencies/include/fmod.h" u8 JGE::GetAnalogX() { /* FIXME if (JGEGetKeyState(VK_LEFT)) return 0; if (JGEGetKeyState(VK_RIGHT)) return 0xff; */ return 0x80; } u8 JGE::GetAnalogY() { /* FIXME if (JGEGetKeyState(VK_UP)) return 0; if (JGEGetKeyState(VK_DOWN)) return 0xff; */ return 0x80; } #endif static map holds; static map oldHolds; #define REPEAT_DELAY 0.5 #define REPEAT_PERIOD 0.07 void JGE::PressKey(const LocalKeySym sym) { const pair rng = keyBinds.equal_range(sym); if (rng.first == rng.second) keyBuffer.push(make_pair(sym, JGE_BTN_NONE)); else for (keycodes_it it = rng.first; it != rng.second; ++it) keyBuffer.push(*it); } void JGE::PressKey(const JButton sym) { keyBuffer.push(make_pair(LOCAL_NO_KEY, sym)); } void JGE::HoldKey(const LocalKeySym sym) { const pair rng = keyBinds.equal_range(sym); if (rng.first == rng.second) keyBuffer.push(make_pair(sym, JGE_BTN_NONE)); else for (keycodes_it it = rng.first; it != rng.second; ++it) { keyBuffer.push(*it); if (holds.end() == holds.find(it->second)) holds[it->second] = REPEAT_DELAY; } } void JGE::HoldKey_NoRepeat(const LocalKeySym sym) { const pair rng = keyBinds.equal_range(sym); if (rng.first == rng.second) keyBuffer.push(make_pair(sym, JGE_BTN_NONE)); else for (keycodes_it it = rng.first; it != rng.second; ++it) { keyBuffer.push(*it); if (holds.end() == holds.find(it->second)) holds[it->second] = std::numeric_limits::quiet_NaN(); } } void JGE::HoldKey(const JButton sym) { keyBuffer.push(make_pair(LOCAL_NO_KEY, sym)); if (holds.end() == holds.find(sym)) holds[sym] = REPEAT_DELAY; } void JGE::HoldKey_NoRepeat(const JButton sym) { keyBuffer.push(make_pair(LOCAL_NO_KEY, sym)); if (holds.end() == holds.find(sym)) holds[sym] = std::numeric_limits::quiet_NaN(); } void JGE::ReleaseKey(const LocalKeySym sym) { const pair rng = keyBinds.equal_range(sym); for (keycodes_it it = rng.first; it != rng.second; ++it) holds.erase(it->second); } void JGE::ReleaseKey(const JButton sym) { holds.erase(sym); } void JGE::Update(float dt) { for (map::iterator it = holds.begin(); it != holds.end(); ++it) { if (it->second < 0) { keyBuffer.push(make_pair(LOCAL_NO_KEY, it->first)); it->second = REPEAT_PERIOD; } it->second -= dt; } if (mApp != NULL) mApp->Update(); oldHolds = holds; } bool JGE::GetButtonState(JButton button) { return (holds.end() != holds.find(button)); } bool JGE::GetButtonClick(JButton button) { return ((holds.end() != holds.find(button)) && (oldHolds.end() == oldHolds.find(button))); } JButton JGE::ReadButton() { if (keyBuffer.empty()) return JGE_BTN_NONE; JButton val = keyBuffer.front().second; keyBuffer.pop(); return val; } LocalKeySym JGE::ReadLocalKey() { if (keyBuffer.empty()) return LOCAL_NO_KEY; LocalKeySym val = keyBuffer.front().first; keyBuffer.pop(); return val; } u32 JGE::BindKey(LocalKeySym sym, JButton button) { keyBinds.insert(make_pair(sym, button)); return keyBinds.size(); } u32 JGE::UnbindKey(LocalKeySym sym, JButton button) { for (keycodes_it it = keyBinds.begin(); it != keyBinds.end(); ) if (sym == it->first && button == it->second) { keycodes_it er = it; ++it; keyBinds.erase(er); } else ++it; return keyBinds.size(); } u32 JGE::UnbindKey(LocalKeySym sym) { pair rng = keyBinds.equal_range(sym); keyBinds.erase(rng.first, rng.second); return keyBinds.size(); } void JGE::ClearBindings() { keyBinds.clear(); } void JGE::ResetBindings() { keyBinds.clear(); JGECreateDefaultBindings(); } JGE::keybindings_it JGE::KeyBindings_begin() { return keyBinds.begin(); } JGE::keybindings_it JGE::KeyBindings_end() { return keyBinds.end(); } void JGE::ResetInput() { while (!keyBuffer.empty()) keyBuffer.pop(); holds.clear(); } JGE::JGE() { mApp = NULL; #if defined (WIN32) || defined (LINUX) strcpy(mDebuggingMsg, ""); mCurrentMusic = NULL; #endif Init(); } JGE::~JGE() { JRenderer::Destroy(); JFileSystem::Destroy(); JSoundSystem::Destroy(); } #if defined (WIN32) || defined (LINUX) // Non-PSP code void JGE::Init() { mDone = false; mPaused = false; mCriticalAssert = false; JRenderer::GetInstance(); JFileSystem::GetInstance(); JSoundSystem::GetInstance(); } void JGE::SetDelta(float delta) { mDeltaTime = (float)delta; } float JGE::GetDelta() { return mDeltaTime; } float JGE::GetFPS() { return 0.0f; } ////////////////////////////////////////////////////////////////////////// #else ///// PSP specific code void JGE::Init() { #ifdef DEBUG_PRINT mDebug = true; #else mDebug = false; #endif #if defined (WIN32) || defined (LINUX) tickFrequency = 120; #else tickFrequency = sceRtcGetTickResolution(); #endif if (mDebug) pspDebugScreenInit(); // do this so that we can use pspDebugScreenPrintf strcpy(mDebuggingMsg, ""); sceCtrlSetSamplingCycle(0); sceCtrlSetSamplingMode(PSP_CTRL_MODE_ANALOG); JRenderer::GetInstance(); JFileSystem::GetInstance(); JSoundSystem::GetInstance(); mDone = false; mPaused = false; mCriticalAssert = false; } float JGE::GetDelta() { return mDelta; } float JGE::GetFPS() { return 1.0f / mDelta; } u8 JGE::GetAnalogX() { return JGEGetAnalogX(); } u8 JGE::GetAnalogY() { return JGEGetAnalogY(); } /* bool JGE::GetButtonState(u32 button) { return (mCtrlPad.Buttons&button)==button; } bool JGE::GetButtonClick(u32 button) { return (mCtrlPad.Buttons&button)==button && (mVeryOldButtons&button)!=button; } u32 JGE::ReadButton() { if (gKeyBuffer.empty()) return 0; u32 val = gKeyBuffer.front(); gHolds &= ~val; gKeyBuffer.pop(); return val; } void JGE::ResetInput() { while (!gKeyBuffer.empty()) gKeyBuffer.pop(); } */ #endif ///// PSP specific code ////////////////////////////////////////////////////////////////////////// JGE* JGE::mInstance = NULL; //static int gCount = 0; // returns number of milliseconds since game started int JGE::GetTime() { return JGEGetTime(); } JGE* JGE::GetInstance() { if (mInstance == NULL) { mInstance = new JGE(); } //gCount++; return mInstance; } void JGE::Destroy() { //gCount--; if (mInstance) { delete mInstance; mInstance = NULL; } } void JGE::SetApp(JApp *app) { mApp = app; } void JGE::Render() { JRenderer* renderer = JRenderer::GetInstance(); renderer->BeginScene(); if (mApp != NULL) mApp->Render(); renderer->EndScene(); } void JGE::End() { mDone = true; } void JGE::printf(const char *format, ...) { va_list list; va_start(list, format); vsprintf(mDebuggingMsg, format, list); va_end(list); } void JGE::Pause() { if (mPaused) return; mPaused = true; if (mApp != NULL) mApp->Pause(); } void JGE::Resume() { if (mPaused) { mPaused = false; if (mApp != NULL) mApp->Resume(); } } void JGE::Assert(const char *filename, long lineNumber) { mAssertFile = filename; mAssertLine = lineNumber; mCriticalAssert = true; } std::queue< pair > JGE::keyBuffer; std::multimap JGE::keyBinds;