Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Implement mass indicators

Implement MassIndicator and MassIndicatorGraphic. The former holds the
logic, the latter the graphic.

Add the GuiElement and HudElement subclasses of ScreenElement to
properly distinguish the two.

Create Character::getMass(). Use this when updating the correlated mass
indicator text.

Implement horizontal functionality and perpendicular offset for
PositionModifier. Use this to distribute the MassIndicatorGraphics
horizontally at the bottom of the screen.

Implement CharacterGraphic::getColourModifier(). Use CharacterGraphic's
ColorModifier as the correlated MassIndicatorGraphic's ColorModifier.

Free Label's surface so that we don't leak.

Handle OpenGL colours correctly in Label::doDraw().
  • Loading branch information...
commit c0906fd0130178f05b4f10551aa3214026d9d3c0 1 parent e500ec2
@alexander-b alexander-b authored
View
1  Makefile.am
@@ -50,6 +50,7 @@ bin_PROGRAMS = limbs-off
limbs_off_SOURCES = \
src/config_parser.hxx \
src/config_parser.cxx \
+ src/get_font.hxx \
src/step_timer.hxx \
src/step_timer.cxx \
src/template_math.hxx \
View
9 src/character.cxx
@@ -75,6 +75,11 @@ double Character::getVel() {
return vel_;
}
+phys_t Character::getMass() {
+ return body_.getMass();
+}
+
+
state2p Character::getState() {
return body_.getState();
}
@@ -274,3 +279,7 @@ CharacterGraphic::CharacterGraphic(Character* c) :
addGraphic(&footFront_);
addGraphic(&handFront_);
}
+
+ColorModifier* CharacterGraphic::getColourModifier() {
+ return &bodyColor_;
+}
View
2  src/character.hxx
@@ -40,6 +40,7 @@ public:
Character(state2p state, phys_t orientation);
void addToUniverse(GameUniverse* u);
bool isDead();
+ phys_t getMass();
double getVel();
state2p getState();
void crouch(bool state);
@@ -74,6 +75,7 @@ private:
class CharacterGraphic: public StackGraphic {
public:
CharacterGraphic(Character* c);
+ ColorModifier* getColourModifier();
private:
Character* c_;
GraphicFixture bodyFixture_, headFixture_, footBackFixture_,
View
5 src/game.hxx
@@ -24,6 +24,7 @@
#include "graphics/game_graphics_gl.hxx"
#include "physics/game_physics.hxx"
#include "player.hxx"
+#include "screen_element.hxx"
class Game : public EventHandler {
public:
@@ -64,8 +65,12 @@ private:
GameUniverse* universe_;
GLuint tex_;
GraphicFixture* planetFixture_;
+ std::vector<Label*> massIndicatorLabels_;
+ std::vector<MassIndicator*> massIndicators_;
+ std::vector<MassIndicatorGraphic*> massIndicatorGfx_;
Circle<phys_t>* planetCircle_;
std::vector<Player*> players_;
+ std::vector<PositionModifier*> massIndicatorPosMods_;
Screen* screen_;
StackGraphic* scene_, * foreground_;
Sprite* backgroundSprite_;
View
39 src/game/game.cxx
@@ -24,6 +24,7 @@
#include <SDL/SDL.h>
#include "game.hxx"
+#include "get_font.hxx"
#include "menu.hxx"
#include "config_parser.hxx"
@@ -97,6 +98,10 @@ Game::Game(Screen* screen) :
foreground_->addGraphic(*i);
foreground_->addModifier(camera_);
scene_->addGraphic(foreground_);
+ for (std::vector<MassIndicatorGraphic*>::const_iterator i =
+ massIndicatorGfx_.begin();
+ i != massIndicatorGfx_.end(); ++i)
+ scene_->addGraphic(*i);
}
Game::~Game() {
@@ -109,6 +114,19 @@ Game::~Game() {
for (std::vector<CharacterGraphic*>::const_iterator i =
characterGraphics_.begin(); i != characterGraphics_.end(); ++i)
delete (*i);
+ for (std::vector<Label*>::const_iterator i = massIndicatorLabels_.begin();
+ i != massIndicatorLabels_.end(); ++i)
+ delete (*i);
+ for (std::vector<MassIndicator*>::const_iterator i =
+ massIndicators_.begin(); i != massIndicators_.end(); ++i)
+ delete (*i);
+ for (std::vector<MassIndicatorGraphic*>::const_iterator i =
+ massIndicatorGfx_.begin(); i != massIndicatorGfx_.end(); ++i)
+ delete (*i);
+ for (std::vector<PositionModifier*>::iterator i =
+ massIndicatorPosMods_.begin(); i != massIndicatorPosMods_.end();
+ ++i)
+ delete (*i);
delete planetCircle_;
for (std::vector<AstroBody*>::const_iterator i = planets_.begin();
i != planets_.end(); ++i)
@@ -133,6 +151,20 @@ void Game::conceive() {
characters_.push_back(new Character(state2p()(pos, vel), i * angle));
players_.push_back(new Player(characters_[i]));
characterGraphics_.push_back(new CharacterGraphic(characters_[i]));
+ char font[256];
+ getFont(font, sizeof(font));
+ char mass [4];
+ snprintf(mass, sizeof(mass), "%.0f", characters_[i]->getMass());
+ massIndicatorLabels_.push_back(new Label(font, mass, 74, .05,
+ .02));
+ massIndicators_.push_back(new MassIndicator(i));
+ massIndicatorGfx_.push_back(new MassIndicatorGraphic(0.05f, 0.02f,
+ massIndicators_[i], massIndicatorLabels_[i]));
+ massIndicatorPosMods_.push_back(new PositionModifier(i + 1,
+ NUM_PLAYERS, true, -0.9));
+ massIndicatorGfx_[i]->addModifier(massIndicatorPosMods_[i]);
+ massIndicatorGfx_[i]->addModifier(
+ characterGraphics_[i]->getColourModifier());
pos.rotate(a);
vel.rotate(a);
}
@@ -207,5 +239,12 @@ void Game::updateCamera(GLfloat dt) {
void Game::draw() {
scene_->draw();
+ int i = 0;
+ char mass [4];
+ for (std::vector<Character*>::const_iterator it = characters_.begin();
+ it != characters_.end(); ++it, ++i) {
+ snprintf(mass, sizeof(mass), "%.0f", (*it)->getMass());
+ massIndicatorLabels_[i]->setText(mass);
+ }
}
View
50 src/get_font.hxx
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2012 Alexander Berntsen <alexander@plaimi.net>
+ *
+ * This file is part of Limbs Off.
+ *
+ * Limbs Off is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Limbs Off is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Limbs Off. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GET_FONT_HXX_
+#define GET_FONT_HXX_
+
+#include <fontconfig/fontconfig.h>
+#include <string.h>
+
+void getFont(char* result, size_t size,
+ const char* fontFamily = "Anonymous Pro",
+ const char* fontStyle = "Bold", const char* fontSpacing = "Monospace");
+
+inline void getFont(char* result, size_t size, const char* fontFamily,
+ const char* fontStyle, const char* fontSpacing) {
+ char* font;
+ FcPattern* fontPattern = FcPatternCreate();
+ FcResult fontResult = FcResultMatch;
+ FcPatternAddString(fontPattern, FC_FAMILY,
+ (const FcChar8*) fontFamily);
+ FcPatternAddDouble(fontPattern, FC_SIZE, 74);
+ FcPatternAddString(fontPattern, FC_SPACING,
+ (const FcChar8*) fontSpacing);
+ FcPatternAddString(fontPattern, FC_STYLE,
+ (const FcChar8*) fontStyle);
+ FcDefaultSubstitute(fontPattern);
+ FcPattern* fontMatch = FcFontMatch(NULL, fontPattern, &fontResult);
+ FcPatternGetString(fontMatch, FC_FILE, 0, (FcChar8**) &font);
+ strncpy(result, font, size);
+ FcPatternDestroy(fontMatch);
+ FcPatternDestroy(fontPattern);
+}
+
+#endif /*GET_FONT_HXX_*/
View
15 src/graphics/game_graphics_gl.hxx
@@ -64,11 +64,14 @@ private:
class PositionModifier: public GraphicModifier {
public:
- PositionModifier(int position, int num);
+ PositionModifier(int position, int num, bool horizontalP,
+ float offset = 0.0);
void begin();
void end();
private:
+ bool horizontalP_;
int position_, num_;
+ float offset_;
};
class SizeModifier: public GraphicModifier {
@@ -137,8 +140,6 @@ private:
int size_;
/** The font colour. */
SDL_Color colour_;
- /** The surface the text is rendered to. */
- SDL_Surface* surface_;
/** The actual TTF_Font. */
TTF_Font* font_;
};
@@ -163,6 +164,14 @@ private:
Disk disk_, square_;
};
+class MassIndicatorGraphic: public ScreenGraphic {
+public:
+ MassIndicatorGraphic(GLfloat width, GLfloat height, MassIndicator* logic,
+ Label* label = NULL);
+ Label* const label;
+ void doDraw();
+};
+
class ButtonGraphic: public ScreenGraphic {
public:
ButtonGraphic(GLfloat width, GLfloat height, Button* logic,
View
105 src/graphics/game_graphics_gl/graphic.cxx
@@ -19,7 +19,7 @@
*/
#include <math.h>
-#include <fontconfig/fontconfig.h>
+#include "get_font.hxx"
#include "graphics/game_graphics_gl.hxx"
#include "geometry.hxx"
@@ -69,15 +69,19 @@ void BackgroundModifier::end() {
glPopMatrix();
}
-PositionModifier::PositionModifier(int position, int num) :
- position_(position),
- num_(num) {
+PositionModifier::PositionModifier(int position, int num, bool horizontalP,
+ float offset) :
+ position_(position), num_(num), horizontalP_(horizontalP), offset_(offset) {
}
void PositionModifier::begin() {
glPushMatrix();
- GLfloat f = 2. / num_ * ((1. + num_) / 2. - position_);
- glTranslatef(.0, f, .0);
+ // Evenly distribute the elements horizontally or vertically
+ GLfloat f = 2.0 / num_ * ((1.0 + num_) / 2.0 - position_);
+ if (horizontalP_)
+ glTranslatef(-f, offset_, 0.0);
+ else
+ glTranslatef(offset_, f, 0.0);
}
void PositionModifier::end() {
@@ -157,14 +161,16 @@ void ScreenGraphic::setSize(GLfloat w, GLfloat h) {
Label::Label(const char* face, const char* text, int size, GLfloat width,
GLfloat height) :
- size_(size),
- width_(width),
- height_(height) {
- face_ = (char*) malloc(strlen(face) + 1);
- strcpy(face_, face);
+ face_(NULL), size_(size), width_(width), height_(height), font_(NULL) {
+ TTF_Init();
+ if (!TTF_WasInit() && TTF_Init() == -1) {
+ printf("error initialising fontconfig: %s\n", TTF_GetError());
+ exit(1);
+ }
text_ = (char*) malloc(strlen(text) + 1);
strcpy(text_, text);
- make();
+ texture_ = 0;
+ setFace(face);
}
Label::~Label() {
@@ -186,7 +192,8 @@ GLfloat Label::getWidth() {
void Label::doDraw() {
Screen::getInstance()->setDrawingMode(0, Screen::DM_PREMUL);
- glColor3f(.0, .0, .0);
+ glPushAttrib(GL_CURRENT_BIT | GL_LIGHTING_BIT);
+ glColor3f(0.0, 0.0, 0.0);
glBindTexture(GL_TEXTURE_2D, texture_);
glBegin(GL_QUADS);
glTexCoord2f(.0, 1.);
@@ -199,30 +206,36 @@ void Label::doDraw() {
glVertex2f(-width_, height_);
glEnd();
glBindTexture(GL_TEXTURE_2D, 0);
- glColor3f(1.0, 1.0, 1.0);
+ glPopAttrib();
}
void Label::make() {
- TTF_Init();
- font_ = TTF_OpenFont(face_, size_);
- if (!font_)
+ if (font_ == NULL)
+ font_ = TTF_OpenFont(face_, size_);
+ if (font_ == NULL)
printf("error opening font: %s\n", TTF_GetError());
// Doesn't matter
SDL_Color bg = {0, 0, 0};
- surface_ = TTF_RenderText_Shaded(font_, text_, bg, bg);
+ SDL_Surface* surface = TTF_RenderText_Shaded(font_, text_, bg, bg);
+ if (texture_)
+ glDeleteTextures(1, &texture_);
glGenTextures(1, &texture_);
glBindTexture(GL_TEXTURE_2D, texture_);
- glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA8, surface_->w, surface_->h, 0,
- GL_ALPHA, GL_UNSIGNED_BYTE, surface_->pixels);
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA8, surface->w, surface->h, 0,
+ GL_ALPHA, GL_UNSIGNED_BYTE, surface->pixels);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glBindTexture(GL_TEXTURE_2D, 0);
+ SDL_FreeSurface(surface);
}
void Label::setFace(const char* face) {
- free(face_);
+ if (face_ != NULL)
+ free(face_);
face_ = (char*) malloc(strlen(face) + 1);
strcpy(face_, face);
+ TTF_CloseFont(font_);
+ font_ == NULL;
make();
}
@@ -232,7 +245,10 @@ void Label::setSize(int size) {
}
void Label::setText(const char* text) {
- free(text_);
+ if (strcmp(text_, text) == 0)
+ return;
+ if (text_ != NULL)
+ free(text_);
text_ = (char*) malloc(strlen(text) + 1);
strcpy(text_, text);
make();
@@ -284,6 +300,26 @@ Disk* TestDisk::getSquare() {
return &square_;
}
+MassIndicatorGraphic::MassIndicatorGraphic(GLfloat width, GLfloat height,
+ MassIndicator* logic, Label* label) :
+ label(label) {
+ setSize(width, height);
+ logic_ = logic;
+}
+
+void MassIndicatorGraphic::doDraw() {
+ // This draws front to back
+ if (label) {
+ label->draw();
+ }
+ glBegin(GL_QUADS);
+ glVertex2f(width_, -height_);
+ glVertex2f(-width_, -height_);
+ glVertex2f(-width_, height_);
+ glVertex2f(width_, height_);
+ glEnd();
+}
+
ButtonGraphic::ButtonGraphic(GLfloat width, GLfloat height, Button* logic,
Label* label, bool selected) :
label(label) {
@@ -299,7 +335,7 @@ void ButtonGraphic::doDraw() {
if (label) {
label->draw();
}
- if (logic_->isSelected())
+ if (((Button*)logic_)->isSelected())
glColor4f(0.f, 1.f, 0.f, 1.f);
else
glColor4f(1.f, 0.f, 0.f, 1.f);
@@ -332,7 +368,7 @@ void SubmenuGraphic::addButton(Button* logic, Label* label,
// Create a PositionModifier
positionModifiers_.push_back(new PositionModifier(
buttonGraphics_.back()->getLogic()->getPosition(),
- submenu_->buttons.size()));
+ submenu_->buttons.size(), false));
// Add the ButtonGraphic to graphics_
addGraphic(buttonGraphics_.back());
// Pair up the ButtonGraphic with the PositionModifier
@@ -341,32 +377,17 @@ void SubmenuGraphic::addButton(Button* logic, Label* label,
MenuGraphic::MenuGraphic(Menu* menu) :
menu_(menu) {
- const char* fontFamily = "Anonymous Pro";
- const char* fontStyle = "Bold";
- const char* fontSpacing = "Monospace";
- char* font;
- FcPattern* fontPattern = FcPatternCreate();
- FcResult fontResult = FcResultMatch;
- int fontSize = 74;
- FcPatternAddString(fontPattern, FC_FAMILY,
- (const FcChar8*) fontFamily);
- FcPatternAddDouble(fontPattern, FC_SIZE, fontSize);
- FcPatternAddString(fontPattern, FC_SPACING,
- (const FcChar8*) fontSpacing);
- FcPatternAddString(fontPattern, FC_STYLE,
- (const FcChar8*) fontStyle);
- FcDefaultSubstitute(fontPattern);
- FcPattern* fontMatch = FcFontMatch(NULL, fontPattern, &fontResult);
- FcPatternGetString(fontMatch, FC_FILE, 0, (FcChar8**) &font);
for (int i = 0; i < Menu::NUM_MENU; ++i) {
// Create a new SubmenuGraphic for each Submenu
menuGraphics_[i] = new SubmenuGraphic(menu->getMenu(i));
Submenu* submenu = menu->getMenu(i);
// Add buttons and labels
+ char font[256];
+ getFont(font, sizeof(font));
for (std::vector<Button*>::iterator j =
submenu->buttons.begin(); j < submenu->buttons.end(); ++j) {
labels_.push_back(new Label(font, ((Button*) (*j))->getText(),
- fontSize, .5, .1));
+ 74, .5, .1));
menuGraphics_[i]->addButton((*j), labels_.back(),
(*j)->isSelected());
}
View
9 src/menu.hxx
@@ -48,12 +48,11 @@ public:
int getActiveMenu();
Submenu* getMenu(int menu);
private:
- ScreenElement* getScreenElement(std::vector<ScreenElement*> vector,
- int position);
- ScreenElement* getSelected();
+ Button* getButton(std::vector<Button*> vector, int position);
+ Button* getSelected();
void raiseEvent(EVENT_ID id);
- void setSelected(ScreenElement* selected);
- ScreenElement* activeElement_;
+ void setSelected(Button* selected);
+ Button* activeElement_;
int activeMenu_;
/** Menus are hardcoded. */
Submenu* menus_[NUM_MENU];
View
2  src/menu/menu.cxx
@@ -101,7 +101,7 @@ void Menu::raiseEvent(EVENT_ID id) {
SDL_PushEvent(&event);
}
-void Menu::setSelected(ScreenElement* selected) {
+void Menu::setSelected(Button* selected) {
activeElement_->setSelected(false);
activeElement_ = selected;
activeElement_->setSelected(true);
View
14 src/screen_element.cxx
@@ -21,10 +21,6 @@
#include <stdlib.h>
#include <string.h>
-bool ScreenElement::isSelected() {
- return selected_;
-}
-
int ScreenElement::getPosition() {
return position_;
}
@@ -33,7 +29,11 @@ void ScreenElement::setPosition(int pos) {
position_ = pos;
}
-void ScreenElement::setSelected(bool selected) {
+bool GuiElement::isSelected() {
+ return selected_;
+}
+
+void GuiElement::setSelected(bool selected) {
selected_ = selected;
}
@@ -52,6 +52,6 @@ char* Button::getText() {
return text_;
}
-int Button::getPosition() {
- return position_;
+MassIndicator::MassIndicator(int position) {
+ setPosition(position);
}
View
21 src/screen_element.hxx
@@ -22,25 +22,36 @@
class ScreenElement {
public:
- bool isSelected();
int getPosition();
void setPosition(int pos);
+protected:
+ int position_;
+};
+
+class GuiElement: public ScreenElement {
+public:
+ bool isSelected();
void setSelected(bool selected);
protected:
bool selected_;
- int position_;
};
-class Button: public ScreenElement {
+class Button: public GuiElement {
public:
Button(const char* text, int position, bool selected = false);
~Button();
char* getText();
- int getPosition();
private:
bool selected_;
char* text_;
- int position_;
+};
+
+class HudElement: public ScreenElement {
+};
+
+class MassIndicator: public HudElement {
+public:
+ MassIndicator(int position);
};
#endif /*SCREEN_ELEMENT_H_*/
Please sign in to comment.
Something went wrong with that request. Please try again.