#include "GameView.hh"
#include "Graphics.hh"
#include <cassert>
namespace graphics
{
GameView::GameView (GameState &state, LocalPlayer *player) :
View(PixelArea(0, 0, graphics->display.get_width(), graphics->display.get_height())),
state(state), player(NULL), info_view(NULL), message_view(getMessageViewArea()),
flags(0)
{
// have player?
if (player)
setPlayer(player);
// insert message
message_view.add_message(CL_Color::white, "Hello World!");
// enable GUI input
slots.connect(graphics->input.gui.sig_input(), this, &GameView::handleInput);
graphics->input.gui.enable();
}
void GameView::setPlayer (LocalPlayer *player) {
assert(!this->player && player);
// remember it
this->player = player;
// build the info_view as well
info_view = new PlayerInfoView(getInfoViewArea(), player);
// enable player input
slots.connect(graphics->input.player.sig_input(), player, &LocalPlayer::handleInput);
graphics->input.player.enable();
}
void GameView::handleInput (GuiInput flags, TimeMS dt) {
// ignore timing info
(void) dt;
// update our flags
this->flags = flags;
// quit?
if (flags & GUI_INPUT_QUIT) {
graphics->engine.stop();
return;
}
// dump player debug info on stderr
if ((flags & GUI_INPUT_DEBUG_PLAYER) && player) {
player->printDebugInfo();
message_view.add_message(CL_Color::green, "...");
}
// toggle fullscreen?
if (flags & GUI_INPUT_TOGGLE_FULLSCREEN)
graphics->display.toggleFullscreen();
}
/*
* Helper function for Camera
*/
static PixelDimension value_between (PixelDimension low, PixelDimension value, PixelDimension high) {
if (high < low)
return (high + low) / 2;
else if (value < low)
return low;
else if (value > high)
return high;
else
return value;
}
void GameView::draw (Display &display) {
CL_GraphicContext *gc = display.get_gc();
// calculate camera
PixelCoordinate camera(0, 0);
// ...to track our local player
if (player != NULL) {
// display resolution
PixelCoordinate resolution = display.getResolution();
// try and center the screen on the player
PixelCoordinate target = player->getCoordinate() - PixelCoordinate(resolution.x / 2, (resolution.y - 100) / 2);
// ...but keep the world in view
PixelCoordinate max = state.terrain.getDimensions() - resolution + PixelCoordinate(0, 100);
// ...by limiting the value to 0...max
camera = PixelCoordinate(
value_between(0, target.x, max.x),
value_between(0, target.y, max.y)
);
}
// Black background
gc->clear(CL_Color::black);
// Draw the game
state.draw(display, camera, flags & GUI_INPUT_DISPLAY_WEAPON);
// draw info view?
if (info_view)
info_view->draw(display);
// draw messages
message_view.draw(display);
}
void GameView::resize (const PixelArea &new_area) {
View::resize(new_area);
// resize subcomponents
if (info_view)
info_view->resize(getInfoViewArea());
message_view.resize(getMessageViewArea());
// log message
message_view.add_message(CL_Color::yellow, CL_String::format("[ Resized window to %1 x %2 ]", (int) getWidth(), (int) getHeight()));
}
}