Ejemplo n.º 1
0
static void AddCheatParam(uint32 A, uint64 V, unsigned int bytelen, bool bigendian)
{
 char name[256];

 CHEAT_printf("Name: ");
 GetString(name,256);

 CHEAT_printf("Address [$%08x]: ", A);
 A=GetUI(A);

 CHEAT_printf("Byte length [%d]: ", bytelen);
 bytelen = GetUI(bytelen);

 if(bytelen > 1)
 {
  CHEAT_printf("Big endian? [%c]: ", bigendian ? 'Y' : 'N');
  bigendian = GetYN(bigendian);
 }
 else
  bigendian = 0;

 CHEAT_printf("Value [%llu]: ", V);
 V=GetUI(V);

 CHEAT_printf("Add cheat \"%s\" for address $%08x with value %llu?",name,(unsigned int)A,(unsigned long long)V);
 if(GetYN(0))
 {
  if(MDFNI_AddCheat(name,A,V,0, 'R', bytelen, bigendian))
   CHEAT_puts("Cheat added.");
  else
   CHEAT_puts("Error adding cheat.");
 }
}
Ejemplo n.º 2
0
bool RRGameState::Join(String ip, int port /*= 33010*/)
{
	/// Start SIP session if needed?
	bool success = NetworkMan.StartSIPServer();
	if (!success)
		return false;
	// If not created, create and add the session to be handled by the network-manager.
	CreateSessionIfNeeded();
	/// Check if already connected.
	if (session->IsConnected())
	{
		NetworkLog("Already connected.");
		// Show lobby?
		QueueGraphics(new GMPushUI("gui/Lobby.gui", GetUI()));
		MesMan.QueueMessages("OnPlayersUpdated");
		return false;
	}
	/// Connect with our session.
	success = session->ConnectTo(ip, port);
	if (success)
	{
		NetworkLog("Connected successfully.");
		// Show lobby?
		QueueGraphics(new GMPushUI("gui/Lobby.gui", GetUI()));
		MesMan.QueueMessages("OnPlayersUpdated");
	}
	return success;
}
Ejemplo n.º 3
0
bool HKWidgetListbox::InputEvent(HKInputManager &manager, const HKInputManager::EventInfo &ev)
{
	// try and handle the input event in some standard ways...
	switch(ev.ev)
	{
		case HKInputManager::IE_Down:
		{
			// immediately stop the thing from scrolling
			velocity = 0.f;
			scrollOffset = MFFloor(scrollOffset);

			// if the down stroke is outside the listbox, we have triggered a non-click
			MFRect rect = { 0.f, 0.f, size.x, size.y };
			if(!MFTypes_PointInRect(ev.down.x, ev.down.y, &rect))
			{
				HKWidgetSelectEvent sel(this, -1);
				OnClicked(*this, sel);
			}
			break;
		}
		case HKInputManager::IE_Up:
		{
			if(bDragging)
			{
				bDragging = false;
				GetUI().SetFocus(ev.pSource, pOldFocus);
			}
			break;
		}
		case HKInputManager::IE_Drag:
		{
			// scroll the contents
			float delta = orientation == Horizontal ? ev.drag.deltaX : ev.drag.deltaY;
			scrollOffset += delta;

			const float smooth = 0.5f;
			velocity = velocity*smooth + (delta / MFSystem_GetTimeDelta())*(1.f-smooth);

			if(!bDragging)
			{
				bDragging = true;
				pOldFocus = GetUI().SetFocus(ev.pSource, this);
			}
			break;
		}
		default:
			break;
	}

	return HKWidget::InputEvent(manager, ev);
}
Ejemplo n.º 4
0
/// Hosts a game
bool RRGameState::Host(int port /*= 33010*/)
{
	// If not created, create and add the session to be handled by the network-manager.
	CreateSessionIfNeeded();
	bool success = session->Host(port);
	if (success)
	{
		// Show lobby gui!
		QueueGraphics(new GMPushUI("gui/Lobby.gui", GetUI()));
		MesMan.QueueMessages("OnPlayersUpdated");
		// Since host, push ui to select if game type: new or load a saved game.
		QueueGraphics(new GMPushUI("gui/GameType.gui", GetUI()));
	}
	return success;
}
Ejemplo n.º 5
0
 void GameStartState::Deactivate()
 {
     GetInput()->RemoveEventReceiver(this);
     GetAssetManager()->Unload(m_Font);
     GetAssetManager()->Unload(m_FontTexture);
     GetUI()->RemoveElement(m_ConsoleText);
     m_ConsoleText->Destroy();
 }
Ejemplo n.º 6
0
// Stop hosting this game. 
bool RRGameState::CancelGame()
{
	assert(session);
	if (!session)
		return false;
	session->Stop();
	NetworkLog("Game canceled");
	// Remove lobby if it is up.
	QueueGraphics(new GMPopUI("gui/Lobby.gui", GetUI(), true));
	return true;
}
Ejemplo n.º 7
0
void Game::Init(const std::map<std::string, std::string>& options)
{
	//register filthy global (for lua api)
	p3::game = this;

	OS::NotifyLoadBegin();
	FileSystem::Init();
	FileSystem::userFiles.MakeDirectory(""); // ensure the config directory exists
	m_config.reset(new GameConfig(options));
	if (m_config->Int("RedirectStdio"))
		OS::RedirectStdio();
	KeyBindings::InitBindings();
	ModManager::Init();
	Lang::Resource res(Lang::GetResource("core", GetConfig()->String("Lang")));
	Lang::MakeCore(res);
	Uint32 sdlInitFlags = SDL_INIT_VIDEO | SDL_INIT_JOYSTICK;
#if defined(DEBUG) || defined(_DEBUG)
	sdlInitFlags |= SDL_INIT_NOPARACHUTE;
#endif
	if (SDL_Init(sdlInitFlags) < 0)
		Error("SDL initialization failed: %s\n", SDL_GetError());

	m_rng.seed(time(0));

	Graphics::Settings vs = ReadVideoSettings(GetConfig());
	vs.title = "P3";
	m_renderer.reset(Graphics::Init(vs));

	EnumStrings::Init();

	Lua::Init();

	m_ui.Reset(new UI::Context(Lua::manager,
	                           GetRenderer(),
	                           GetRenderer()->GetWindow()->GetWidth(),
	                           GetRenderer()->GetWindow()->GetHeight()));

	InitLua();

	m_modelCache.reset(new ModelCache(GetRenderer()));

	//init some graphics
	LaserBoltGraphic::InitResources(GetRenderer());

	Galaxy::Init();

	m_console.reset(new LuaConsole(GetUI()));
	KeyBindings::toggleLuaConsole.onPress.connect(sigc::mem_fun(m_console.get(), &LuaConsole::Toggle));

	OS::NotifyLoadEnd();
}
Ejemplo n.º 8
0
static void DoSearch(void* data)
{
 static int v1=0,v2=0;
 static int method=0;

 const char *m[6]={"O==V1 && C==V2","O==V1 && |O-C|==V2","|O-C|==V2","O!=C","Value decreased","Value increased"};
 CHEAT_puts("");
 CHEAT_printf("Search Filter:");

 method = ShowShortList(m,6,method);

 if(method<=1)
 {
  CHEAT_printf("V1 [%03d]: ",v1);
  v1=GetUI(v1);
 }

 if(method<=2)
 {
  CHEAT_printf("V2 [%03d]: ",v2);
  v2=GetUI(v2);
 }

 CHEAT_printf("Byte length(1-8)[%1d]: ", searchbytelen);
 searchbytelen = GetUI(searchbytelen);

 if(searchbytelen > 1)
 {
  CHEAT_printf("Big endian? [%c]: ", searchbigendian ? 'Y' : 'N');
  searchbigendian = GetYN(searchbigendian);
 }
 else
  searchbigendian = 0;

 MDFNI_CheatSearchEnd(method, v1, v2, searchbytelen, searchbigendian);
 CHEAT_puts("Search completed.");
}
Ejemplo n.º 9
0
void DebugCameraController::Update(float timeStep)
{
    // Do not move if the UI has a focused element
    if (GetUI()->GetFocusElement())
        return;

    // Do not move if interacting with UI controls
    if (GetSystemUI()->IsAnyItemActive())
        return;

    Input* input = GetInput();

    // Movement speed as world units per second
    float moveSpeed_ = speed_;
    if (input->GetKeyDown(KEY_SHIFT))
    {
        moveSpeed_ *= 2;

        if (input->GetKeyPress(KEY_KP_PLUS))
            speed_ += 1.f;
        else if (input->GetKeyPress(KEY_KP_MINUS))
            speed_ -= 1.f;
    }

    if (input->GetMouseButtonDown(MOUSEB_RIGHT))
    {
        IntVector2 delta = input->GetMouseMove();

        if (input->IsMouseVisible() && delta != IntVector2::ZERO)
            input->SetMouseVisible(false);

        auto yaw = GetNode()->GetRotation().EulerAngles().x_;
        if ((yaw > -90.f && yaw < 90.f) || (yaw <= -90.f && delta.y_ > 0) || (yaw >= 90.f && delta.y_ < 0))
            GetNode()->RotateAround(Vector3::ZERO, Quaternion(mouseSensitivity_ * delta.y_, Vector3::RIGHT), TS_LOCAL);
        GetNode()->RotateAround(GetNode()->GetPosition(), Quaternion(mouseSensitivity_ * delta.x_, Vector3::UP), TS_WORLD);
    }
    else if (!input->IsMouseVisible())
        input->SetMouseVisible(true);

    // Read WASD keys and move the camera scene node to the corresponding direction if they are pressed
    if (input->GetKeyDown(KEY_W))
        GetNode()->Translate(Vector3::FORWARD * moveSpeed_ * timeStep);
    if (input->GetKeyDown(KEY_S))
        GetNode()->Translate(Vector3::BACK * moveSpeed_ * timeStep);
    if (input->GetKeyDown(KEY_A))
        GetNode()->Translate(Vector3::LEFT * moveSpeed_ * timeStep);
    if (input->GetKeyDown(KEY_D))
        GetNode()->Translate(Vector3::RIGHT * moveSpeed_ * timeStep);
}
Ejemplo n.º 10
0
void HKWidgetListbox::AddView(HKWidget *pView)
{
	// it might be better to write a custom ListItem widget here, Frame might be a bit heavy for the purpose...
	HKWidgetLayoutFrame *pFrame = GetUI().CreateWidget<HKWidgetLayoutFrame>();
	pFrame->AddChild(pView, true);
	pFrame->SetClickable(true);
	pFrame->SetHoverable(true);

	// make child clickable
	pFrame->OnDown += fastdelegate::MakeDelegate(this, &HKWidgetListbox::OnItemDown);
	pFrame->OnTap += fastdelegate::MakeDelegate(this, &HKWidgetListbox::OnItemClick);
	pFrame->OnHoverOver += fastdelegate::MakeDelegate(this, &HKWidgetListbox::OnItemOver);
	pFrame->OnHoverOut += fastdelegate::MakeDelegate(this, &HKWidgetListbox::OnItemOut);

	AddChild(pFrame, true);
}
Ejemplo n.º 11
0
/*
============
sdUIMarquee::CalcOffsets
============
*/
void sdUIMarquee::CalcOffsets() {
	if ( textWidth == 0 || textHeight == 0 ) {
		return;
	}

	float textSize;
	float rectSize;
	int index;

	switch( static_cast< eScrollOrientation >( idMath::FtoiFast( orientation ) ) ) {
		case SO_HORIZONTAL:
			textSize = textWidth;
			rectSize = cachedClientRect.z;
			scrollOffset[ 1 ] = 0.0f;
			index = 0;
			break;		
		case SO_VERTICAL:
			textSize = textHeight;
			rectSize = cachedClientRect.w;
			scrollOffset[ 0 ] = 0.0f;
			index = 1;
			break;
		default:
			gameLocal.Warning( "sdUIMarquee::CalcOffsets: unknown orientation '%i'", idMath::Ftoi( orientation ) );
			scrollStartTime = 0;
			scrollTargetTime = 0;
			return;
	}

	const int now = GetUI()->GetCurrentTime();

	float ratio = textSize / rectSize;
	if ( ratio < 1.0f ) {
		ratio = 1.0f;
	}

	if ( now >= scrollTargetTime || scrollStartTime == scrollTargetTime || now < scrollStartTime ) {
		scrollStartTime = now;
	}
	scrollTargetTime = scrollStartTime + SEC2MS( speed * ratio );

	float totalTime = static_cast< float >( scrollTargetTime - scrollStartTime );
	float percent = static_cast< float >( now - scrollStartTime ) / totalTime;	

	scrollOffset[ index ] = rectSize - percent * ( rectSize + textSize );
}
Ejemplo n.º 12
0
void DebugCameraController2D::Update(float timeStep)
{
    // Do not move if the UI has a focused element
    if (GetUI()->GetFocusElement())
        return;

    // Do not move if interacting with UI controls
    if (GetSystemUI()->IsAnyItemActive())
        return;

    Input* input = GetInput();

    // Movement speed as world units per second
    float moveSpeed_ = speed_;
    if (input->GetKeyDown(KEY_SHIFT))
    {
        moveSpeed_ *= 2;

        if (input->GetKeyPress(KEY_KP_PLUS))
            speed_ += 1.f;
        else if (input->GetKeyPress(KEY_KP_MINUS))
            speed_ -= 1.f;
    }

    if (input->GetMouseButtonDown(MOUSEB_RIGHT))
    {
        IntVector2 delta = input->GetMouseMove();

        if (input->IsMouseVisible() && delta != IntVector2::ZERO)
            input->SetMouseVisible(false);
        GetNode()->Translate2D(Vector2{(float)delta.x_ * -1.f, (float)delta.y_} * moveSpeed_ * timeStep);
    }
    else if (!input->IsMouseVisible())
        input->SetMouseVisible(true);

    // Read WASD keys and move the camera scene node to the corresponding direction if they are pressed
    if (input->GetKeyDown(KEY_W))
        GetNode()->Translate(Vector3::UP * moveSpeed_ * timeStep);
    if (input->GetKeyDown(KEY_S))
        GetNode()->Translate(Vector3::DOWN * moveSpeed_ * timeStep);
    if (input->GetKeyDown(KEY_A))
        GetNode()->Translate(Vector3::LEFT * moveSpeed_ * timeStep);
    if (input->GetKeyDown(KEY_D))
        GetNode()->Translate(Vector3::RIGHT * moveSpeed_ * timeStep);
}
Ejemplo n.º 13
0
static MemoryPatch GetCheatFields(const MemoryPatch &pin)
{
 MemoryPatch patch = pin;
 char buf[256];
 const bool support_read_subst = CurGame->InstallReadPatch && CurGame->RemoveReadPatches;

 CHEAT_printf("Name [%s]: ", patch.name.c_str());
 GetString(buf, 256);
 if(buf[0] != 0)
  patch.name = std::string(buf);

 CHEAT_printf("Available types:");
 CHEAT_printf(" R - Replace/RAM write(high-level).");
 CHEAT_printf(" A - Addition/RAM read->add->write(high-level).");
 CHEAT_printf(" T - Transfer/RAM copy(high-level).");

 if(support_read_subst)
 {
  CHEAT_printf(" S - Subsitute on reads.");
  CHEAT_printf(" C - Substitute on reads, with compare.");
 }

 for(;;)
 {
  CHEAT_printf("Type [%c]: ", patch.type);
  patch.type = toupper(CHEAT_getchar(patch.type));

  if(patch.type == 'R' || patch.type == 'A' || patch.type == 'T')
   break;

  if(support_read_subst && (patch.type == 'S' || patch.type == 'C'))
   break;
 }

 if(patch.type == 'T')
 {
  CHEAT_printf("Source address [$%08x]: ", (unsigned int)patch.copy_src_addr);
  patch.copy_src_addr = GetUI(patch.copy_src_addr);

  CHEAT_printf("Source address inc [%u]: ", patch.copy_src_addr_inc);
  patch.copy_src_addr_inc = GetUI(patch.copy_src_addr_inc);

  CHEAT_printf("Dest address [$%08x]: ", (unsigned int)patch.addr);
  patch.addr = GetUI(patch.addr);  

  CHEAT_printf("Dest address inc [%u]: ", patch.mltpl_addr_inc);
  patch.mltpl_addr_inc = GetUI(patch.mltpl_addr_inc);

  CHEAT_printf("Count [%u]: ", patch.mltpl_count);
  patch.mltpl_count = GetUI(patch.mltpl_count);

 }
 else
 {
  CHEAT_printf("Address [$%08x]: ", (unsigned int)patch.addr);
  patch.addr = GetUI(patch.addr);
 }

 if(patch.type == 'S' || patch.type == 'C')
  patch.length = 1;	// TODO in the future for GBA: support lengths other than 1 in core.
 else
 {
  do
  {
   if(patch.type == 'T')
   {
    //if(patch.length == 1 && patch.copy_src_addr_inc == 1 && patch.mltpl_addr_inc == 1)
    // break;

    //if((patch.copy_src_addr_inc == patch.mltpl_addr_inc) && patch.copy_src_addr_inc >= 1 && patch.copy_src_addr_inc <= 8)
    // CHEAT_printf("Transfer unit byte length should probably be \"%u\".", patch.copy_src_addr_inc);

    CHEAT_printf("Transfer unit byte length(1-8) [%u]: ", patch.length);
   }
   else 
    CHEAT_printf("Byte length(1-8) [%u]: ", patch.length);
   patch.length = GetUI(patch.length);
  } while(patch.length < 1 || patch.length > 8);
 }

 if(patch.length > 1 && (patch.type != 'S' && patch.type != 'C'))
 {
  CHEAT_printf("Big endian? [%c]: ", patch.bigendian ? 'Y' : 'N');
  patch.bigendian = GetYN(patch.bigendian);
 }
 else
  patch.bigendian = false;

 if(patch.type != 'T')
 {
  CHEAT_printf("Value [%03llu]: ", (unsigned long long)patch.val);
  patch.val = GetUI(patch.val);
 }

 // T type loop stuff is handled up above.
 if((patch.type != 'C' && patch.type != 'S' && patch.type != 'T') && patch.mltpl_count != 1)
 {
  CHEAT_printf("Loop count [%u]: ", patch.mltpl_count);
  patch.mltpl_count = GetUI(patch.mltpl_count);

  CHEAT_printf("Loop address inc [%u]: ", patch.mltpl_addr_inc);
  patch.mltpl_addr_inc = GetUI(patch.mltpl_addr_inc);

  CHEAT_printf("Loop value inc [%u]: ", patch.mltpl_val_inc);
  patch.mltpl_val_inc = GetUI(patch.mltpl_val_inc);
 }


 if(patch.type == 'C')
 {
  CHEAT_printf("Compare [%03lld]: ", patch.compare);
  patch.compare = GetUI(patch.compare);
 }

 if((patch.type != 'C' && patch.type != 'S') && patch.conditions.size())
 {
  CHEAT_printf("Conditions: %s", patch.conditions.c_str());	// Just informational for now.
  //CHEAT_printf("Conditions [%s]: ", );
  //patch.conditions = GetString();
 }

 CHEAT_printf("Enable? ");
 patch.status = GetYN(patch.status);

 return(patch);
}
Ejemplo n.º 14
0
static void ModifyCheat(int num)
{
 char *name;
 char buf[256];
 uint32 A;
 uint64 V;
 uint64 compare;
 char type;
 int status;
 unsigned int bytelen;
 bool bigendian;

 MDFNI_GetCheat(num, &name, &A, &V, &compare, &status, &type, &bytelen, &bigendian);

 CHEAT_printf("Name [%s]: ",name);
 GetString(buf,256);

 /* This obviously doesn't allow for cheats with no names.  Bah.  Who wants
    nameless cheats anyway... 
 */

 if(buf[0])
  name=buf;	// Change name when MDFNI_SetCheat() is called.
 else
  name=0;	// Don't change name when MDFNI_SetCheat() is called.

 CHEAT_printf("Address [$%08x]: ",(unsigned int)A);
 A=GetUI(A);

 CHEAT_printf("Byte length [%d]: ", bytelen);
 bytelen = GetUI(bytelen);

 if(bytelen > 1)
 {
  CHEAT_printf("Big endian? [%c]: ", bigendian ? 'Y' : 'N');
  bigendian = GetYN(bigendian);
 }
 else
  bigendian = 0;

 CHEAT_printf("Value [%03lld]: ",(unsigned int)V);
 V=GetUI(V);

 
 do
 {
  CHEAT_printf("Type('R'=replace,'S'=Read Substitute(or 'C' with compare)) [%c]: ",type);
  type = toupper(CHEAT_getchar(type));
 } while(type != 'R' && type !='S' && type !='C');

 if(type == 'C')
 {
  CHEAT_printf("Compare [%03lld]: ",compare);
  compare = GetUI(compare);
 }

 CHEAT_printf("Enable? ");
 status = GetYN(status);

 MDFNI_SetCheat(num, name, A, V, compare, status, type, bytelen, bigendian);
}
Ejemplo n.º 15
0
void Game::Run()
{
	const Uint32 MAX_PHYSICS_TICKS = Clamp(GetConfig()->Int("MaxPhysicsCyclesPerRender"), 0, 4);

	GetUI()->DropAllLayers();
	m_fpsLabel = GetUI()->Label("16.67");
	GetUI()->GetTopLayer()->SetInnerWidget(m_fpsLabel);

	m_sim = new Sim();
	LuaEvent::Queue("onGameStart");
	LuaEvent::Emit();

	//http://gafferongames.com/game-physics/fix-your-timestep/
	double currentTime = 0.001 * double(SDL_GetTicks());
	double accumulator = m_sim->GetTimeStep();
	double gameTickAlpha = 0.0;
	double frameTime = 0.0;

	//frame timing
	double lastStatsTime = currentTime;
	Uint32 frameCount = 0;

	while (m_sim->IsRunning()) {
		double newTime = 0.001 * double(SDL_GetTicks());
		frameTime = newTime - currentTime;
		if (frameTime > 0.25)
			frameTime = 0.25;
		currentTime = newTime;
		accumulator += frameTime * m_sim->GetTimeAccelRate();

		frameCount++;

		const double step = m_sim->GetTimeStep();
		if (step > 0.0) { //pause check
			Uint32 physTicks = 0;
			while (accumulator >= step) {
				if (++physTicks >= MAX_PHYSICS_TICKS) {
					accumulator = 0.0;
					break;
				}

				//run physics and game simulation
				m_sim->Execute(step);
				accumulator -= step;
			}

			gameTickAlpha = accumulator / step;
		} else {
			//possible paused updates
		}

		m_sim->InterpolatePositions(gameTickAlpha);

		HandleEvents();
		m_ui->Update();

		//render
		m_renderer->BeginFrame();
		m_sim->GetScene()->Render();
		m_ui->Draw();
		m_renderer->EndFrame();
		m_renderer->SwapBuffers();

		//if (Pi::game->UpdateTimeAccel())
		//	accumulator = 0; // fix for huge pauses 10000x -> 1x

		if (newTime - lastStatsTime > 1.0) {
			m_fpsLabel->SetText(stringf("%0{f.2}", 1000.f / frameCount));
			frameCount = 0;
			if (newTime - lastStatsTime > 1.2)
				lastStatsTime = newTime;
			else
				lastStatsTime += 1.0;
		}
	}

	delete m_sim;
}
Ejemplo n.º 16
0
void Game::HandleEvents()
{
	SDL_Event event;

	// XXX for most keypresses SDL will generate KEYUP/KEYDOWN and TEXTINPUT
	// events. keybindings run off KEYUP/KEYDOWN. the console is opened/closed
	// via keybinding. the console TextInput widget uses TEXTINPUT events. thus
	// after switching the console, the stray TEXTINPUT event causes the
	// console key (backtick) to appear in the text entry field. we hack around
	// this by setting this flag if the console was switched. if its set, we
	// swallow the TEXTINPUT event this hack must remain until we have a
	// unified input system
	bool skipTextInput = false;

	Mouse::motion[0] = Mouse::motion[1] = 0;
	while (SDL_PollEvent(&event)) {
		if (event.type == SDL_QUIT) {
			if (m_sim)
				m_sim->End();
		}

		if (skipTextInput && event.type == SDL_TEXTINPUT) {
			skipTextInput = false;
			continue;
		}
		if (GetUI()->DispatchSDLEvent(event))
			continue;

		bool consoleActive = m_console->IsActive();
		if (!consoleActive)
			KeyBindings::DispatchSDLEvent(&event);
		else
			KeyBindings::toggleLuaConsole.CheckSDLEventAndDispatch(&event);
		if (consoleActive != m_console->IsActive()) {
			skipTextInput = true;
			continue;
		}

		if (m_console->IsActive())
			continue;

		switch (event.type) {
		case SDL_KEYDOWN:
			if (event.key.keysym.sym == SDLK_ESCAPE) {
				if (m_sim)
					m_sim->End();
				break;
			}
			Keyboard::state[event.key.keysym.sym] = true;
			Keyboard::modState = event.key.keysym.mod;
			break;
		case SDL_KEYUP:
			Keyboard::state[event.key.keysym.sym] = false;
			Keyboard::modState = event.key.keysym.mod;
			break;
		case SDL_MOUSEBUTTONDOWN:
			if (event.button.button < COUNTOF(Mouse::button))
				Mouse::button[event.button.button] = 1;
			break;
		case SDL_MOUSEBUTTONUP:
			if (event.button.button < COUNTOF(Mouse::button))
				Mouse::button[event.button.button] = 0;
			break;
		case SDL_MOUSEWHEEL:
			Mouse::onWheel.emit(event.wheel.y > 0); // true = up
			break;
		case SDL_MOUSEMOTION:
			Mouse::motion[0] += event.motion.xrel;
			Mouse::motion[1] += event.motion.yrel;
			break;
		}
	}
}