#include #include #include "engine.h" #include "glfont.h" #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "gettext.h" bool mogltk::engine::inited = false, mogltk::engine::postsetuped = false; bool mogltk::engine::appactive = false, mogltk::engine::cursorvisible = false, mogltk::engine::quitrequest = false; int mogltk::engine::mx, mogltk::engine::my, mogltk::engine::mz = 0, mogltk::engine::mbuttons; int mogltk::engine::frames, mogltk::engine::locked = 0; double mogltk::engine::curfps = -1; Uint32 mogltk::engine::curticks; mogltk::widget * mogltk::engine::root = 0; mogltk::glbase * mogltk::engine::glbase_o = 0; mogltk::base * mogltk::engine::base_o = 0; mogltk::engine::keyevent * mogltk::engine::keyevent_h = 0; mogltk::engine::mouseevent * mogltk::engine::mouseevent_h = 0; #define UPDATERATE 1000 mogltk::engine::keyevent::keyevent() { new_handler = 0; if ((old_handler = getkeyevent())) old_handler->new_handler = this; setkeyevent(this); } mogltk::engine::keyevent::~keyevent() { if (new_handler) new_handler->old_handler = old_handler; if (old_handler) old_handler->new_handler = new_handler; if (getkeyevent() == this) setkeyevent(old_handler); } void mogltk::engine::keyevent::up(SDL_keysym) { printm(M_INFO, "Generic keyevent::up called\n"); } void mogltk::engine::keyevent::down(SDL_keysym) { printm(M_INFO, "Generic keyevent::down called\n"); } mogltk::engine::mouseevent::mouseevent() { new_handler = 0; old_handler = getmouseevent(); old_handler->new_handler = this; setmouseevent(this); } mogltk::engine::mouseevent::~mouseevent() { if (new_handler) new_handler->old_handler = old_handler; if (old_handler) old_handler->new_handler = new_handler; if (getmouseevent() == this) setmouseevent(old_handler); } void mogltk::engine::mouseevent::move(SDL_MouseMotionEvent) { printm(M_INFO, "Generic mouseevent::move called\n"); } void mogltk::engine::mouseevent::action(SDL_MouseButtonEvent) { printm(M_INFO, "Generic mouseevent::action called\n"); } int mogltk::engine::setup() throw(GeneralException) { if (inited) { printm(M_WARNING, FUNCNAME + _(" called twice, ignoring second call.\n")); return -1; } if (SDL_Init(0) < 0) { throw GeneralException(FUNCNAME + _(": Unable to start SDL base system")); } atexit(SDL_Quit); inited = true; return 0; } int mogltk::engine::postsetup() throw(GeneralException) { if (postsetuped) { printm(M_WARNING, FUNCNAME + _(" called twice, ignoring second call.\n")); return -1; } SDL_EnableUNICODE(1); curticks = SDL_GetTicks(); postsetuped = true; if (glbase_o) mogltk::SystemFont = new mogltk::glfont(&Input("font.bin")); else mogltk::SystemFont = new mogltk::font(&Input("font.bin")); return 0; } int mogltk::engine::GetInited() { return inited; } class embedRWops : public Base { public: embedRWops(Handle *); int seek(int, int); int read(void *, int, int); int write(const void *, int, int); private: Handle * h; }; embedRWops::embedRWops(Handle * ah) : h(ah) {} int embedRWops::seek(int offset, int whence) { return h->seek(offset, whence); } int embedRWops::read(void * ptr, int size, int num) { return h->read(ptr, size * num); } int embedRWops::write(const void * ptr, int size, int num) { return h->write(ptr, size * num); } static int embedRWseek(SDL_RWops * context, int offset, int whence) { if (context->hidden.unknown.data1) return ((embedRWops *)(context->hidden.unknown.data1))->seek(offset, whence); return -1; } static int embedRWread(SDL_RWops * context, void * ptr, int size, int num) { if (context->hidden.unknown.data1) return ((embedRWops *)(context->hidden.unknown.data1))->read(ptr, size, num); return -1; } static int embedRWwrite(SDL_RWops * context, const void * ptr, int size, int num) { if (context->hidden.unknown.data1) return ((embedRWops *)(context->hidden.unknown.data1))->write(ptr, size, num); return -1; } static int embedRWclose(SDL_RWops * context) { if (context->hidden.unknown.data1) { delete ((embedRWops *)(context->hidden.unknown.data1)); context->hidden.unknown.data1 = 0; return 0; } return -1; } SDL_RWops * mogltk::engine::RWFromHandle(Handle * h) throw (GeneralException) { SDL_RWops * r = 0; if (h) { if (!(r = SDL_AllocRW())) throw GeneralException(_("Couldn't allocate memory for SDL_RWops")); r->hidden.unknown.data1 = (void *) new embedRWops(h); r->seek = embedRWseek; r->read = embedRWread; r->write = embedRWwrite; r->close = embedRWclose; } return r; } void mogltk::engine::pollevents() throw (GeneralException) { SDL_Event event; bool hastoreturn = appactive; if (!postsetuped) postsetup(); if (appactive) { Uint32 ticks = SDL_GetTicks(); frames++; if (ticks - curticks > UPDATERATE) { curfps = (double) frames * 1000 / (ticks - curticks); frames = 0; curticks = ticks; } } else { curfps = -1; } while(true) { if (hastoreturn || quitrequest) if (!SDL_PollEvent(NULL)) { updatemouse(); return; } if (!SDL_WaitEvent(&event)) { throw GeneralException("Error polling for SDL Event"); } switch(event.type) { case SDL_ACTIVEEVENT: switch (event.active.state) { case SDL_APPMOUSEFOCUS: printm(M_INFO, String("Application ") + (event.active.gain ? "gained" : "loosed") + " mouse focus\n"); if (cursorvisible) hastoreturn = true; break; case SDL_APPINPUTFOCUS: printm(M_INFO, String("Application ") + (event.active.gain ? "gained" : "loosed") + " input focus\n"); if (cursorvisible) hastoreturn = true; break; case SDL_APPACTIVE: printm(M_INFO, String("Application was ") + (event.active.gain ? "restored" : "iconified")); if (cursorvisible) hastoreturn = true; break; } break; case SDL_KEYDOWN: case SDL_KEYUP: printm(M_INFO, String("Key ") + event.key.keysym.scancode + " on keyboard " + event.key.which + (event.key.state == SDL_PRESSED ? " pressed" : " released") + "\n"); printm(M_INFO, "SDL keysym: %i - Unicode: %04x = `%c`- modifiers: %04x\n", event.key.keysym.sym, event.key.keysym.unicode, event.key.keysym.unicode, event.key.keysym.mod); if (keyevent_h) { if (event.key.state == SDL_PRESSED) { keyevent_h->down(event.key.keysym); } else { keyevent_h->up(event.key.keysym); } } break; case SDL_MOUSEMOTION: printm(M_INFO, "Mouse slept over the screen - (%i, %i)\n", event.motion.x, event.motion.y); if (locked) { if (!((event.motion.x == mx) && (event.motion.y == my))) { SDL_WarpMouse(mx, my); } } if (cursorvisible) hastoreturn = true; if (mouseevent_h) { mouseevent_h->move(event.motion); } break; case SDL_MOUSEBUTTONDOWN: case SDL_MOUSEBUTTONUP: printm(M_INFO, String().set("Mouse button %02x ", event.button.button) + String((event.button.state == SDL_PRESSED ? "pressed" : "released")) + " at (" + event.button.x + ", " + event.button.y + ")\n"); if (event.button.state == SDL_PRESSED) { if (event.button.button == SDL_BUTTON_WHEELUP) { mz--; } if (event.button.button == SDL_BUTTON_WHEELDOWN) { mz++; } } if (mouseevent_h) { mouseevent_h->action(event.button); } break; case SDL_QUIT: printm(M_INFO, "Quit requested\n"); hastoreturn = quitrequest = true; break; case SDL_VIDEOEXPOSE: printm(M_INFO, "Needs to redraw\n"); hastoreturn = true; break; default: printm(M_INFO, "Unknow event: %i\n", event.type); break; } } } void mogltk::engine::setappactive(bool p) { appactive = p; } bool mogltk::engine::getappactive() { return appactive; } void mogltk::engine::setcursorvisible(bool p) { cursorvisible = p; } bool mogltk::engine::getcursorvisible() { return cursorvisible; } void mogltk::engine::quit() { quitrequest = true; } bool mogltk::engine::quitrequested() { return quitrequest; } void mogltk::engine::updatemouse() { mbuttons = SDL_GetMouseState(&mx, &my); } int mogltk::engine::mouseX() { return mx; } int mogltk::engine::mouseY() { return my; } int mogltk::engine::mouseZ() { return mz; } void mogltk::engine::setmouseX(int _mx) { mx = _mx; SDL_WarpMouse(mx, my); } void mogltk::engine::setmouseY(int _my) { my = _my; SDL_WarpMouse(mx, my); } void mogltk::engine::setmouseZ(int _mz) { mz = _mz; } int mogltk::engine::mousebuttons() { return mbuttons; } double mogltk::engine::FPS() { return curfps; } void mogltk::engine::lockmouse() { locked = 1; } void mogltk::engine::unlockmouse() { locked = 0; } void mogltk::engine::setkeyevent(keyevent * k) { keyevent_h = k; } void mogltk::engine::setmouseevent(mouseevent * m) { mouseevent_h = m; } mogltk::engine::keyevent * mogltk::engine::getkeyevent() { return keyevent_h; } mogltk::engine::mouseevent * mogltk::engine::getmouseevent() { return mouseevent_h; }