# HG changeset patch # User John Tsiombikas # Date 1337747143 -10800 # Node ID 369b51c9e4a8b5bdeecdfe4784ca9b965fff2114 # Parent 55a43e27339a8a9b2f780965fe04bd5f0c3793f2 foo diff -r 55a43e27339a -r 369b51c9e4a8 Makefile --- a/Makefile Tue May 22 05:02:00 2012 +0300 +++ b/Makefile Wed May 23 07:25:43 2012 +0300 @@ -4,14 +4,15 @@ dep = $(obj:.o=.d) bin = strat -incdir = -Isrc -Ilevel/src +incdir = -Isrc -Ilevel/src -Icommon/src liblevel = level/liblevel.a -slibs = $(liblevel) +libcommon = common/libcommon.a +slibs = $(liblevel) $(libcommon) CFLAGS = -pedantic -Wall -g $(incdir) CXXFLAGS = -std=c++0x $(CFLAGS) -LDFLAGS = $(libdir) $(slibs) $(libgl) -limtk +LDFLAGS = $(libdir) $(slibs) $(libgl) -limtk -limago -lvmath ifeq ($(shell uname -s), Darwin) CC = clang diff -r 55a43e27339a -r 369b51c9e4a8 common/Makefile --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/common/Makefile Wed May 23 07:25:43 2012 +0300 @@ -0,0 +1,23 @@ +ccsrc = $(wildcard src/*.cc) +obj = $(ccsrc:.cc=.o) +dep = $(obj:.o=.d) +lib_a = libcommon.a + +CXXFLAGS = -std=c++0x -pedantic -Wall -g + +ifeq ($(shell uname -s), Darwin) + CC = clang + CXX = clang++ +endif + +$(lib_a): $(obj) + $(AR) rcs $@ $(obj) + +-include $(dep) + +%.d: %.cc + @$(CPP) $(CXXFLAGS) $< -MM -MT $(@:.d=.o) >$@ + +.PHONY: clean +clean: + rm -f $(obj) $(bin) $(dep) diff -r 55a43e27339a -r 369b51c9e4a8 common/src/datapath.cc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/common/src/datapath.cc Wed May 23 07:25:43 2012 +0300 @@ -0,0 +1,81 @@ +#include +#include +#include +#include +#ifdef _MSC_VER +#include +#else +#include +#endif +#include "datapath.h" + +using namespace std; + +static vector first; +static stack> dpath_stack; + +static void init() +{ + if(dpath_stack.empty()) { + dpath_stack.push(first); + } +} + +void reset_data_path() +{ + init(); + + dpath_stack.top().clear(); +} + +void push_data_path() +{ + init(); + + dpath_stack.push(dpath_stack.top()); +} + +void pop_data_path() +{ + init(); + + dpath_stack.pop(); +} + +void add_data_path(const char *path) +{ + init(); + + char *tmp = (char*)alloca(strlen(path) + 1); + strcpy(tmp, path); + + char *endp = strrchr(tmp, '/'); + if(endp) { + *endp = 0; + } + + dpath_stack.top().push_back(tmp); +} + +bool find_file(const char *fname, char *path) +{ + FILE *fp; + + init(); + + for(size_t i=0; i #include #include "level.h" +#include "datapath.h" + +using namespace tinyxml2; Level::Level() { @@ -12,14 +15,162 @@ bool Level::load(const char *fname) { - if(!xml.LoadFile(fname)) { + push_data_path(); + add_data_path(fname); + + if(xml.LoadFile(fname) != 0) { fprintf(stderr, "failed to load level: %s\n", fname); + pop_data_path(); return false; } if(strcmp(xml.RootElement()->Name(), "level") != 0) { fprintf(stderr, "invalid level file: %s\n", fname); + pop_data_path(); return false; } + + XMLNode *node = xml.RootElement()->FirstChild(); + do { + XMLElement *elem = node->ToElement(); + if(elem) { + if(strcmp(elem->Name(), "map") == 0) { + LevelMap map; + + if(!map.load(elem)) { + pop_data_path(); + return false; + } + levelmaps[map.get_name()] = std::move(map); + + } else { + fprintf(stderr, "ignoring unrecognized element: %s\n", elem->Name()); + } + } + } while((node = node->NextSibling())); + + pop_data_path(); + return true; +} + + +LevelMap::LevelMap() +{ + init(); +} + +void LevelMap::init() +{ + scale = 1.0f; + img_init(&img); + name = 0; +} + +LevelMap::~LevelMap() +{ + destroy(); +} + +void LevelMap::destroy() +{ + if(img.pixels) { + img_destroy(&img); + } + delete [] name; +} + +// copy +LevelMap::LevelMap(const LevelMap &map) +{ + init(); + *this = map; +} + +LevelMap &LevelMap::operator =(const LevelMap &map) +{ + if(this != &map) { + destroy(); + + scale = map.scale; + img_init(&img); + img_copy(&img, (img_pixmap*)&map.img); + + name = new char[strlen(map.name) + 1]; + strcpy(name, map.name); + } + return *this; +} + +// move semantics +LevelMap::LevelMap(LevelMap &&map) +{ + init(); + *this = std::move(map); +} + +LevelMap &LevelMap::operator =(LevelMap &&map) +{ + if(this != &map) { + destroy(); + + scale = map.scale; + + img = map.img; + map.img.pixels = 0; + map.img.name = 0; + + name = map.name; + map.name = 0; + } + + return *this; +} + +bool LevelMap::load(XMLElement *xelem) +{ + char fname[PATH_MAX]; + + const char *attr = xelem->Attribute("type"); + if(!attr) { + fprintf(stderr, "map element without a type attribute\n"); + return false; + } + name = new char[strlen(attr) + 1]; + strcpy(name, attr); + + attr = xelem->Attribute("file"); + if(!attr) { + fprintf(stderr, "map element without a file attribute\n"); + return false; + } + if(!find_file(attr, fname)) { + fprintf(stderr, "failed to locate image: %s\n", attr); + return false; + } + + if(img_load(&img, fname) == -1) { + fprintf(stderr, "failed to load image: %s\n", fname); + return false; + } + + float val; + if(xelem->QueryFloatAttribute("scale", &val) == 0) { + scale = val; + } return true; } + +float LevelMap::get_scale() const +{ + return scale; +} + +const img_pixmap *LevelMap::get_pixmap() const +{ + return &img; +} + +const char *LevelMap::get_name() const +{ + return name; +} diff -r 55a43e27339a -r 369b51c9e4a8 level/src/level.h --- a/level/src/level.h Tue May 22 05:02:00 2012 +0300 +++ b/level/src/level.h Wed May 23 07:25:43 2012 +0300 @@ -1,11 +1,17 @@ #ifndef LEVEL_H_ #define LEVEL_H_ +#include +#include +#include #include "tinyxml2.h" +class LevelMap; + class Level { private: tinyxml2::XMLDocument xml; + std::map levelmaps; public: Level(); @@ -14,9 +20,31 @@ bool load(const char *fname); }; -class Map { +class LevelMap { +private: + float scale; + img_pixmap img; + char *name; + + void init(); + void destroy(); + public: - bool load(tinyxml2::XMLNode *xml); + LevelMap(); + ~LevelMap(); + + LevelMap(const LevelMap &map); + LevelMap &operator =(const LevelMap &map); + + // move constructor/op= + LevelMap(LevelMap &&map); + LevelMap &operator =(LevelMap &&map); + + bool load(tinyxml2::XMLElement *xelem); + + float get_scale() const; + const img_pixmap *get_pixmap() const; + const char *get_name() const; }; #endif // LEVEL_H_ diff -r 55a43e27339a -r 369b51c9e4a8 src/game_part.cc --- a/src/game_part.cc Tue May 22 05:02:00 2012 +0300 +++ b/src/game_part.cc Wed May 23 07:25:43 2012 +0300 @@ -4,6 +4,14 @@ Game::~Game() {} +bool Game::init() +{ + if(!level.load("data/test.level")) { + return false; + } + return true; +} + void Game::draw() const { glClear(GL_COLOR_BUFFER_BIT); diff -r 55a43e27339a -r 369b51c9e4a8 src/game_part.h --- a/src/game_part.h Tue May 22 05:02:00 2012 +0300 +++ b/src/game_part.h Wed May 23 07:25:43 2012 +0300 @@ -6,10 +6,12 @@ class Game : public Part { private: - Level *level; + Level level; public: ~Game(); + bool init(); + void draw() const; void key(int key, bool pressed); }; diff -r 55a43e27339a -r 369b51c9e4a8 src/main.cc --- a/src/main.cc Tue May 22 05:02:00 2012 +0300 +++ b/src/main.cc Wed May 23 07:25:43 2012 +0300 @@ -53,9 +53,16 @@ glewInit(); menu_part = new MainMenu; + if(!menu_part->init()) { + return false; + } + game_part = new Game; + if(!game_part->init()) { + return false; + } + cur_part = menu_part; - return true; } diff -r 55a43e27339a -r 369b51c9e4a8 src/part.cc --- a/src/part.cc Tue May 22 05:02:00 2012 +0300 +++ b/src/part.cc Wed May 23 07:25:43 2012 +0300 @@ -8,6 +8,11 @@ current_time = 0; } +bool Part::init() +{ + return true; +} + void Part::update(unsigned long msec) { current_time = msec; diff -r 55a43e27339a -r 369b51c9e4a8 src/part.h --- a/src/part.h Tue May 22 05:02:00 2012 +0300 +++ b/src/part.h Wed May 23 07:25:43 2012 +0300 @@ -13,6 +13,8 @@ public: virtual ~Part(); + virtual bool init(); + virtual void update(unsigned long msec); virtual void draw() const = 0;