start using CL_ResourceManager, change most draw methods to take a Graphics*, implment even better input handling, and draw weapon names
Binary file data/share/font1.tga has changed
Binary file data/share/font2.tga has changed
Binary file data/share/font3.tga has changed
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/data/share/resources.xml Sat Dec 06 22:47:08 2008 +0000
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="iso-8859-1"?>
+<resources>
+ <sprite name="font_glyph1">
+ <image file="font1.tga"><alpha /></image>
+ <image file="font2.tga"><alpha /></image>
+ </sprite>
+
+ <sprite name="font_glyph2">
+ <image file="font3.tga"><alpha /></image>
+ </sprite>
+
+ <font name="Font1">
+ <bitmap glyphs="font_glyph1" letters="!~#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^`abcdefghijklmnopqrstuvwxyz{|}" />
+ </font>
+
+ <font name="Font2">
+ <bitmap glyphs="font_glyph2" spacelen="4" letters="AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZzĈĉĜĝĊċ0123456789[]()!#$&%/\=-+~'`".,:;*?" />
+ </font>
+</resources>
--- a/src/Config.hh Sat Dec 06 22:36:38 2008 +0000
+++ b/src/Config.hh Sat Dec 06 22:47:08 2008 +0000
@@ -46,7 +46,8 @@
const CL_Color COLOR_DIRT(144, 82, 23);
const CL_Color COLOR_ROCK(132, 136, 135);
-// Drawing
+// Data paths
const std::string PLAYER_SKIN_PATH = (PROJECT_DATA_DIR "/skin.png");
+const std::string RESOURCE_XML_PATH = (PROJECT_DATA_DIR "/resources.xml");
#endif
--- a/src/Engine.cc Sat Dec 06 22:36:38 2008 +0000
+++ b/src/Engine.cc Sat Dec 06 22:47:08 2008 +0000
@@ -4,18 +4,15 @@
#include <iostream>
-bool Engine::_graphicsEnabled = false;
-
-Engine::Engine (void) : is_running(true) {
-
+Engine::Engine (const std::string resource_xml_path) :
+ is_running(true), resources(resource_xml_path)
+{
+
}
void Engine::setupGraphics (void) {
// create the graphics
graphics = new Graphics(*this, game_state);
-
- // set enabled
- Engine::_graphicsEnabled = true;
}
void Engine::setupNetworkServer (const std::string &listen_port) {
@@ -55,8 +52,8 @@
}
}
-bool Engine::graphicsEnabled (void) {
- return Engine::_graphicsEnabled;
+CL_ResourceManager* Engine::getResourceManager (void) {
+ return &resources;
}
Logger Engine::log (enum LogLevel level, const char *type) {
--- a/src/Engine.hh Sat Dec 06 22:36:38 2008 +0000
+++ b/src/Engine.hh Sat Dec 06 22:47:08 2008 +0000
@@ -26,12 +26,12 @@
// to exit the mainloop
bool is_running;
- // global...
- static bool _graphicsEnabled;
+ // ClanLib resources
+ CL_ResourceManager resources;
public:
// default constructor
- Engine (void);
+ Engine (const std::string resource_xml_path = RESOURCE_XML_PATH);
// setup graphics
void setupGraphics (void);
@@ -49,8 +49,8 @@
void stop (void);
public:
- // avoid loading resources for graphics if we're not going to use them
- static bool graphicsEnabled (void);
+ // get a pointer to our resource manager
+ CL_ResourceManager* getResourceManager (void);
// logging utility
static Logger log (enum LogLevel level, const char *type);
--- a/src/GameState.cc Sat Dec 06 22:36:38 2008 +0000
+++ b/src/GameState.cc Sat Dec 06 22:47:08 2008 +0000
@@ -9,10 +9,6 @@
projectiles.push_back(projectile);
}
-void GameState::addRope (Rope *rope) {
- ropes.push_back(rope);
-}
-
LocalPlayer *GameState::getLocalPlayer (void) {
return local_player;
}
@@ -34,22 +30,24 @@
player_list.remove(player);
}
-void GameState::draw(CL_GraphicContext *gc) {
+void GameState::draw(Graphics *g, bool displayWeapon) {
// Draw world/terrain
- world.draw(gc);
+ world.draw(g->get_gc());
// Draw players
for (std::list<Player*>::iterator it = player_list.begin(); it != player_list.end(); it++) {
- (*it)->draw(gc);
+ Player *p = *it;
+
+ // our LocalPlayer has it's own draw method
+ if (p == local_player)
+ local_player->draw(g, displayWeapon);
+ else
+ p->draw(g);
}
+
// Draw projectiles
for (std::list<Projectile*>::iterator it = projectiles.begin(); it != projectiles.end(); it++) {
- (*it)->draw(gc);
- }
- // Draw ropes
- for (std::list<Rope*>::iterator it = ropes.begin(); it != ropes.end(); it++) {
- if ((*it)->getState() != FOLDED)
- (*it)->draw(gc);
+ (*it)->draw(g);
}
}
--- a/src/GameState.hh Sat Dec 06 22:36:38 2008 +0000
+++ b/src/GameState.hh Sat Dec 06 22:47:08 2008 +0000
@@ -8,6 +8,7 @@
#include "Projectile.hh"
#include "Rope.hh"
#include "Input.hh"
+#include "GraphicsPointer.hh"
#include "Config.hh"
#include <list>
@@ -18,7 +19,6 @@
public:
std::list<Player*> player_list;
std::list<Projectile*> projectiles;
- std::list<Rope*> ropes;
PhysicsWorld world;
// only one local player is supported
@@ -27,7 +27,6 @@
GameState (void);
void addProjectile(Projectile *projectile);
- void addRope(Rope *rope);
/*
* This will return NULL if we don't have a local player - yet
@@ -39,8 +38,7 @@
void removePlayer (Player *player);
- virtual void draw(CL_GraphicContext *gc);
-
+ virtual void draw (Graphics *g, bool displayWeapon);
};
#endif
--- a/src/Graphics.cc Sat Dec 06 22:36:38 2008 +0000
+++ b/src/Graphics.cc Sat Dec 06 22:47:08 2008 +0000
@@ -4,11 +4,13 @@
#include <cmath>
Graphics::Graphics (Engine &engine, GameState &state) :
+ CL_DisplayWindow(GRAPHICS_WINDOW_TITLE, GRAPHICS_RESOLUTION_WIDTH, GRAPHICS_RESOLUTION_HEIGHT),
engine(engine),
state(state),
update_timer(GRAPHICS_UPDATE_INTERVAL_MS),
- win(GRAPHICS_WINDOW_TITLE, GRAPHICS_RESOLUTION_WIDTH, GRAPHICS_RESOLUTION_HEIGHT),
- keyboard(win.get_ic()->get_keyboard()) {
+ keyboard(get_ic()->get_keyboard()),
+ simple_font("Font2", engine.getResourceManager())
+{
// connect timer signal
slots.connect(update_timer.sig_tick(), this, &Graphics::on_update);
@@ -21,40 +23,43 @@
LocalPlayer *player;
PlayerInput input_mask = 0;
- // stop on escape
- if (keyboard.get_keycode(CL_KEY_ESCAPE)) {
+ // update gui flags
+ this->flags = handleGuiInput(keyboard);
+
+ // quit?
+ if (flags & GUI_INPUT_QUIT) {
engine.stop();
return;
}
- // ignore if we don't have a local player
+ // stop here if we don't have a local player
if ((player = state.getLocalPlayer()) == NULL)
return;
// dump debug info on stderr
- if (keyboard.get_keycode(CL_KEY_I))
+ if (flags & GUI_INPUT_DEBUG_PLAYER)
player->printDebugInfo();
// build input_mask
- input_mask = handleInputDevice(keyboard);
+ input_mask = handlePlayerInput(keyboard);
- // apply input if applicable
+ // apply input if there was any
if (input_mask)
player->handleInput(input_mask);
}
void Graphics::do_redraw (void) {
- CL_GraphicContext *gc = win.get_gc();
+ CL_GraphicContext *gc = get_gc();
// White background
gc->clear(CL_Color::white);
- // Draw terrain
- state.draw(gc);
+ // Draw the game
+ state.draw(this, flags & GUI_INPUT_DISPLAY_WEAPON);
// Flip window buffer, sync
- win.flip(1);
+ flip(1);
}
void Graphics::on_update (TimeMS tick_length) {
--- a/src/Graphics.hh Sat Dec 06 22:36:38 2008 +0000
+++ b/src/Graphics.hh Sat Dec 06 22:47:08 2008 +0000
@@ -1,10 +1,10 @@
#ifndef GRAPHICS_HH
#define GRAPHICS_HH
-// XXX: forward-declare for Engine
-class Graphics;
+#include "GraphicsPointer.hh"
#include "GameState.hh"
+#include "Input.hh"
#include "Timer.hh"
#include "Engine.hh"
@@ -17,7 +17,7 @@
const uint32_t GRAPHICS_RESOLUTION_HEIGHT = 600;
const uint16_t GRAPHICS_UPDATE_INTERVAL_MS = 20;
-class Graphics {
+class Graphics : public CL_DisplayWindow {
private:
Engine &engine;
GameState &state;
@@ -26,11 +26,18 @@
Timer update_timer;
- CL_DisplayWindow win;
CL_InputDevice &keyboard;
+
+ // current GUI input state
+ GuiInput flags;
+ // basic fonts
+ CL_Font simple_font;
+
public:
Graphics (Engine &engine, GameState &state);
+
+ CL_Font& getSimpleFont (void) { return simple_font; }
private:
void check_input (void);
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/GraphicsPointer.hh Sat Dec 06 22:47:08 2008 +0000
@@ -0,0 +1,9 @@
+#ifndef GRAPHICS_POINTER_HH
+#define GRAPHICS_POINTER_HH
+
+/*
+ * Break our #include-loop dependancy
+ */
+class Graphics;
+
+#endif
--- a/src/Input.cc Sat Dec 06 22:36:38 2008 +0000
+++ b/src/Input.cc Sat Dec 06 22:47:08 2008 +0000
@@ -3,26 +3,33 @@
#include "Input.hh"
-static InputKeymapEntry INPUT_KEYMAP[] = {
- { -CL_KEY_ENTER, CL_KEY_UP, INPUT_AIM_UP },
- { -CL_KEY_ENTER, CL_KEY_DOWN, INPUT_AIM_DOWN },
- { -CL_KEY_ENTER, CL_KEY_LEFT, INPUT_MOVE_LEFT },
- { -CL_KEY_ENTER, CL_KEY_RIGHT, INPUT_MOVE_RIGHT },
- { -CL_KEY_ENTER, CL_KEY_RSHIFT, INPUT_JUMP },
- { CL_KEY_LEFT, CL_KEY_RIGHT, INPUT_DIG },
- { CL_KEY_RCONTROL, 0, INPUT_SHOOT },
- { CL_KEY_ENTER, CL_KEY_LEFT, INPUT_CHANGE },
- { CL_KEY_ENTER, CL_KEY_RIGHT, INPUT_CHANGE },
- { CL_KEY_ENTER, CL_KEY_RSHIFT, INPUT_ROPE },
- { -CL_KEY_ENTER, CL_KEY_RSHIFT, INPUT_UNROPE },
- { CL_KEY_ENTER, CL_KEY_UP, INPUT_ROPE_UP },
- { CL_KEY_ENTER, CL_KEY_DOWN, INPUT_ROPE_DOWN },
- { 0, 0, (_PlayerInput) 0 }
+template <typename BitEnumType> struct InputKeymapEntry {
+ BitEnumType input;
+ int keycode1, keycode2;
};
-InputKeymapEntry* getGlobalInputKeymap (void) {
- return INPUT_KEYMAP;
-}
+InputKeymapEntry<PlayerInputBit> INPUT_PLAYER_KEYMAP[] = {
+ { INPUT_AIM_UP, -CL_KEY_ENTER, CL_KEY_UP },
+ { INPUT_AIM_DOWN, -CL_KEY_ENTER, CL_KEY_DOWN },
+ { INPUT_MOVE_LEFT, -CL_KEY_ENTER, CL_KEY_LEFT },
+ { INPUT_MOVE_RIGHT, -CL_KEY_ENTER, CL_KEY_RIGHT },
+ { INPUT_JUMP, -CL_KEY_ENTER, CL_KEY_RSHIFT },
+ { INPUT_DIG, CL_KEY_LEFT, CL_KEY_RIGHT },
+ { INPUT_SHOOT, CL_KEY_RCONTROL },
+ { INPUT_CHANGE, CL_KEY_ENTER, CL_KEY_LEFT },
+ { INPUT_CHANGE, CL_KEY_ENTER, CL_KEY_RIGHT },
+ { INPUT_ROPE, CL_KEY_ENTER, CL_KEY_RSHIFT },
+ { INPUT_UNROPE, -CL_KEY_ENTER, CL_KEY_RSHIFT },
+ { INPUT_ROPE_UP, CL_KEY_ENTER, CL_KEY_UP },
+ { INPUT_ROPE_DOWN, CL_KEY_ENTER, CL_KEY_DOWN },
+ { INPUT_NONE, }
+};
+
+InputKeymapEntry<GuiInputBit> INPUT_GUI_KEYMAP[] = {
+ { GUI_INPUT_QUIT, CL_KEY_ESCAPE },
+ { GUI_INPUT_DISPLAY_WEAPON, CL_KEY_ENTER },
+ { GUI_INPUT_DEBUG_PLAYER, CL_KEY_I },
+};
static bool _checkInput (CL_InputDevice &keyboard, int keycode) {
if (keycode > 0)
@@ -35,13 +42,24 @@
return true;
}
-PlayerInput handleInputDevice (CL_InputDevice &keyboard) {
- PlayerInput input = 0;
+template <typename BitEnumType, typename BitMaskType> BitMaskType _buildMask (CL_InputDevice &keyboard,
+ InputKeymapEntry<BitEnumType> *keymap)
+{
+ BitMaskType input_mask = 0;
- for (InputKeymapEntry *e = getGlobalInputKeymap(); (e->keycode1 || e->keycode2) && e->input; e++) {
+ for (InputKeymapEntry<BitEnumType> *e = keymap; (e->keycode1 || e->keycode2) && e->input; e++) {
if (_checkInput(keyboard, e->keycode1) && _checkInput(keyboard, e->keycode2))
- input |= e->input;
+ input_mask |= e->input;
}
- return input;
+ return input_mask;
}
+
+PlayerInput handlePlayerInput (CL_InputDevice &keyboard) {
+ return _buildMask<PlayerInputBit, PlayerInput>(keyboard, INPUT_PLAYER_KEYMAP);
+}
+
+GuiInput handleGuiInput (CL_InputDevice &keyboard) {
+ return _buildMask<GuiInputBit, GuiInput>(keyboard, INPUT_GUI_KEYMAP);
+}
+
--- a/src/Input.hh Sat Dec 06 22:36:38 2008 +0000
+++ b/src/Input.hh Sat Dec 06 22:47:08 2008 +0000
@@ -7,7 +7,9 @@
// const uint16_t INPUT_INTERVAL_MS = 20;
-enum _PlayerInput {
+enum PlayerInputBit {
+ INPUT_NONE = 0x0000,
+
INPUT_AIM_UP = 0x0001,
INPUT_AIM_DOWN = 0x0002,
@@ -24,21 +26,19 @@
INPUT_ROPE_DOWN = 0x0800,
};
-typedef uint16_t PlayerInput;
-
-struct InputKeymapEntry {
- int keycode1, keycode2;
- enum _PlayerInput input;
+enum GuiInputBit {
+ GUI_INPUT_QUIT = 0x0001,
+ GUI_INPUT_DISPLAY_WEAPON = 0x0002,
+ GUI_INPUT_DEBUG_PLAYER = 0x0004,
};
-/*
- * Get the global input keymap
- */
-InputKeymapEntry* getGlobalInputKeymap (void);
+typedef uint16_t PlayerInput;
+typedef uint16_t GuiInput;
/*
* Handle keycodes
*/
-PlayerInput handleInputDevice (CL_InputDevice &keyboard);
+PlayerInput handlePlayerInput (CL_InputDevice &keyboard);
+GuiInput handleGuiInput (CL_InputDevice &keyboard);
#endif
--- a/src/Player.cc Sat Dec 06 22:36:38 2008 +0000
+++ b/src/Player.cc Sat Dec 06 22:47:08 2008 +0000
@@ -1,6 +1,7 @@
+#include "Player.hh"
#include "Engine.hh"
-#include "Player.hh"
+#include "Graphics.hh"
#include <cstdlib>
#include <ClanLib/display.h>
@@ -139,17 +140,10 @@
// XXX: currently not network safe
if (input & INPUT_CHANGE) {
- if (changing) {
+ selectedWeapon = (selectedWeapon + 1) % arsenal.size();
+ Engine::log(DEBUG, "player.input ") << "changed weapon to " << selectedWeapon;
+ }
- } else {
- changing = true;
- selectedWeapon = (selectedWeapon + 1) % arsenal.size();
- Engine::log(DEBUG, "Player.cc:input ") << "changed weapon " << selectedWeapon;
- }
- } else {
- changing = false;
- }
-
// validate shoot events, and then outsource to handleShoot so Network can intercept it
if (input & INPUT_SHOOT && getWeapon().canShoot())
fireWeapon(getWeapon());
@@ -183,7 +177,9 @@
return arsenal[selectedWeapon % arsenal.size()];
}
-void Player::draw (CL_GraphicContext *gc) {
+void Player::draw (Graphics *g) {
+ CL_GraphicContext *gc = g->get_gc();
+
int aim_img_idx = (int)((1 - (getAim()+KG_PI/2)/KG_PI)*img_num_aim);
int step_img_idx = animation_step%img_num_step;
@@ -228,6 +224,21 @@
y - std::sin(aim)*chlen,
CL_Color::black);
}
+
+ rope.draw(g);
}
+void LocalPlayer::draw (Graphics *g, bool displayWeapon) {
+ // superclass draw
+ Player::draw(g);
+ // display weapon name?
+ if (displayWeapon) {
+ g->getSimpleFont().draw(
+ position.x - g->getSimpleFont().get_width(getWeapon().getName()) / 2,
+ position.y + 10,
+ getWeapon().getName(),
+ g->get_gc()
+ );
+ }
+}
--- a/src/Player.hh Sat Dec 06 22:36:38 2008 +0000
+++ b/src/Player.hh Sat Dec 06 22:47:08 2008 +0000
@@ -5,11 +5,12 @@
class LocalPlayer;
class RemotePlayer;
+#include "Weapon.hh"
#include "GameState.hh"
#include "PhysicsObject.hh"
#include "Input.hh"
-#include "Weapon.hh"
#include "Rope.hh"
+#include "GraphicsPointer.hh"
#include <vector>
class Player : public PhysicsObject {
@@ -56,7 +57,7 @@
*/
static bool skin_loaded;
static CL_Surface skin_surface;
- virtual void draw(CL_GraphicContext* gc);
+ virtual void draw (Graphics *g);
};
class LocalPlayer : public virtual Player {
@@ -70,6 +71,11 @@
* NetworkClientLocalPlayer overrides this to send the input to the server, which then handles it
*/
virtual void handleInput (PlayerInput input);
+
+ /*
+ * As Player, but also draws the current weapon name if displayWeapon
+ */
+ virtual void draw (Graphics *g, bool displayWeapon);
};
class RemotePlayer : public virtual Player {
--- a/src/Projectile.cc Sat Dec 06 22:36:38 2008 +0000
+++ b/src/Projectile.cc Sat Dec 06 22:47:08 2008 +0000
@@ -1,4 +1,5 @@
#include "Projectile.hh"
+#include "Graphics.hh"
#include "Timer.hh"
Projectile::Projectile(GameState &state, Vector position, Vector velocity, bool visible, float radius, TickCount age) :
@@ -42,7 +43,9 @@
PhysicsObject::tick(dt);
}
-void Projectile::draw(CL_GraphicContext *gc) const {
+void Projectile::draw(Graphics *g) const {
+ CL_GraphicContext *gc = g->get_gc();
+
if (visible) {
CL_Quad projectile(
--- a/src/Projectile.hh Sat Dec 06 22:36:38 2008 +0000
+++ b/src/Projectile.hh Sat Dec 06 22:47:08 2008 +0000
@@ -6,6 +6,7 @@
#include "GameState.hh"
#include "PhysicsObject.hh"
#include "Timer.hh"
+#include "GraphicsPointer.hh"
class Projectile : public PhysicsObject {
protected:
@@ -21,7 +22,7 @@
Projectile (GameState &state, Vector position, Vector velocity, bool visible, float radius, TickCount age=1000000000);
virtual ~Projectile (void);
- virtual void draw (CL_GraphicContext *gc) const;
+ virtual void draw (Graphics *g) const;
protected:
/*
--- a/src/Rope.cc Sat Dec 06 22:36:38 2008 +0000
+++ b/src/Rope.cc Sat Dec 06 22:47:08 2008 +0000
@@ -1,6 +1,7 @@
#include "Player.hh"
#include "Rope.hh"
#include "Engine.hh"
+#include "Graphics.hh"
#include <math.h>
Rope::Rope(Player &climber) : PhysicsObject(climber.state.world, PLAYER_MASS, Vector(0,0), Vector(0,0), false), pl(climber), rs(FOLDED) {
@@ -24,7 +25,6 @@
this->inAir = true;
enable();
- pl.state.addRope(this);
}
void Rope::onCollision() {
@@ -67,8 +67,14 @@
return 0;
}
-void Rope::draw (CL_GraphicContext *gc) const {
- gc->draw_line((int)(this->pl.getPosition().x), (int)(this->pl.getPosition().y)
- , (int)(this->position.x), (int)(this->position.y), CL_Color::black);
+void Rope::draw (Graphics *g) const {
+ if (rs == FOLDED)
+ return;
+
+ g->get_gc()->draw_line(
+ pl.getPosition().x, pl.getPosition().y,
+ position.x, position.y,
+ CL_Color::black
+ );
}
--- a/src/Rope.hh Sat Dec 06 22:36:38 2008 +0000
+++ b/src/Rope.hh Sat Dec 06 22:47:08 2008 +0000
@@ -7,6 +7,7 @@
#include "Player.hh"
#include "PhysicsObject.hh"
+#include "GraphicsPointer.hh"
enum RopeState { FOLDED, FLYING, FIXED };
@@ -28,7 +29,7 @@
void release (void);
void changeLength (bool shorten);
RopeState getState (void);
- virtual void draw(CL_GraphicContext *gc) const;
+ virtual void draw (Graphics *c) const;
};
#endif
--- a/src/Weapon.hh Sat Dec 06 22:36:38 2008 +0000
+++ b/src/Weapon.hh Sat Dec 06 22:47:08 2008 +0000
@@ -35,6 +35,7 @@
bool canShoot (void);
// get weapon parameters
+ std::string getName (void) { return name; }
float getVelocity (void) { return velocity; }
float getExplosionRadius (void) { return explosionRadius; }
TickCount getExpireTicks (void) { return age; }