[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Pingus-CVS] r2641 - in branches/pingus_sdl/src: . lisp math physfs
From: |
grumbel at BerliOS |
Subject: |
[Pingus-CVS] r2641 - in branches/pingus_sdl/src: . lisp math physfs |
Date: |
Sun, 14 Jan 2007 00:42:26 +0100 |
Author: grumbel
Date: 2007-01-14 00:42:24 +0100 (Sun, 14 Jan 2007)
New Revision: 2641
Added:
branches/pingus_sdl/src/lisp/
branches/pingus_sdl/src/lisp/getters.cpp
branches/pingus_sdl/src/lisp/getters.hpp
branches/pingus_sdl/src/lisp/lexer.cpp
branches/pingus_sdl/src/lisp/lexer.hpp
branches/pingus_sdl/src/lisp/lisp.cpp
branches/pingus_sdl/src/lisp/lisp.hpp
branches/pingus_sdl/src/lisp/parser.cpp
branches/pingus_sdl/src/lisp/parser.hpp
branches/pingus_sdl/src/lisp/properties.cpp
branches/pingus_sdl/src/lisp/properties.hpp
branches/pingus_sdl/src/lisp/property_iterator.hpp
branches/pingus_sdl/src/lisp/writer.cpp
branches/pingus_sdl/src/lisp/writer.hpp
branches/pingus_sdl/src/math/vector2i.cpp
branches/pingus_sdl/src/physfs/
branches/pingus_sdl/src/physfs/physfs_sdl.cpp
branches/pingus_sdl/src/physfs/physfs_sdl.hpp
branches/pingus_sdl/src/physfs/physfs_stream.cpp
branches/pingus_sdl/src/physfs/physfs_stream.hpp
Modified:
branches/pingus_sdl/src/SConscript
branches/pingus_sdl/src/math/vector2i.hpp
branches/pingus_sdl/src/sprite.cpp
Log:
- commit some additional libraries
Modified: branches/pingus_sdl/src/SConscript
===================================================================
--- branches/pingus_sdl/src/SConscript 2007-01-13 21:37:11 UTC (rev 2640)
+++ branches/pingus_sdl/src/SConscript 2007-01-13 23:42:24 UTC (rev 2641)
@@ -43,7 +43,7 @@
# clanMikMod-0.8 ">=" 0.8.0')
env.ParseConfig('sdl-config --cflags --libs')
-env['LIBS'] += ['SDL_image']
+env['LIBS'] += ['SDL_image', 'physfs']
# sdl_env.ParseConfig('sdl-config --cflags --libs')
# sdl_env['LIBS'] += ['SDL_image']
@@ -164,6 +164,13 @@
'gui/screen_ptr.cxx',
'gui/surface_button.cxx',
+'lisp/getters.cpp',
+'lisp/lexer.cpp',
+'lisp/lisp.cpp',
+'lisp/parser.cpp',
+'lisp/properties.cpp',
+'lisp/writer.cpp',
+
# # 'input/axes/button_axis.cxx',
# # 'input/axes/inverted_axis.cxx',
# # 'input/axes/joystick_axis.cxx',
@@ -246,7 +253,9 @@
'tinygettext/tinygettext.cxx',
# 'true_server.cxx',
'math/vector2f.cpp',
-'math/vector3f.cpp',
+'math/vector3f.cpp',
+'physfs/physfs_sdl.cpp',
+'physfs/physfs_stream.cpp',
# 'world.cxx',
# 'worldmap/dot.cxx',
# 'worldmap/dot_factory.cxx',
Added: branches/pingus_sdl/src/lisp/getters.cpp
===================================================================
--- branches/pingus_sdl/src/lisp/getters.cpp 2007-01-13 21:37:11 UTC (rev
2640)
+++ branches/pingus_sdl/src/lisp/getters.cpp 2007-01-13 23:42:24 UTC (rev
2641)
@@ -0,0 +1,42 @@
+#include <config.h>
+#include "getters.hpp"
+
+namespace lisp
+{
+
+bool get(const Lisp* lisp, bool& val)
+{
+ if(lisp->get_type() != Lisp::TYPE_BOOL)
+ return false;
+ val = lisp->get_bool();
+ return true;
+}
+
+bool get(const Lisp* lisp, float& val)
+{
+ if(lisp->get_type() == Lisp::TYPE_INT)
+ val = lisp->get_int();
+ else if(lisp->get_type() == Lisp::TYPE_FLOAT)
+ val = lisp->get_float();
+ else
+ return false;
+ return true;
+}
+
+bool get(const Lisp* lisp, int& val)
+{
+ if(lisp->get_type() != Lisp::TYPE_INT)
+ return false;
+ val = lisp->get_int();
+ return true;
+}
+
+bool get(const Lisp* lisp, std::string& val)
+{
+ if(lisp->get_type() != Lisp::TYPE_STRING)
+ return false;
+ val = lisp->get_string();
+ return true;
+}
+
+}
Added: branches/pingus_sdl/src/lisp/getters.hpp
===================================================================
--- branches/pingus_sdl/src/lisp/getters.hpp 2007-01-13 21:37:11 UTC (rev
2640)
+++ branches/pingus_sdl/src/lisp/getters.hpp 2007-01-13 23:42:24 UTC (rev
2641)
@@ -0,0 +1,60 @@
+/** This header defines functions that assign the value of Lisp objects to
+ * normal C++ datatypes.
+ *
+ * The get function is overloaded for a set of default datatypes. You can add
+ * further overloads in your own code. The get functions return true if the
+ * value could be converted and false otherwise.
+ *
+ * The property_get function expect a list whose values 1-n are transformed to
a
+ * C++ object. This is typically used from the code in the Properties class.
You
+ * can also write custom overloads in your code.
+ */
+#ifndef __GETTERS_HPP__
+#define __GETTERS_HPP__
+
+#include "lisp.hpp"
+
+namespace lisp
+{
+
+bool get(const Lisp* lisp, bool& val);
+bool get(const Lisp* lisp, float& val);
+bool get(const Lisp* lisp, int& val);
+bool get(const Lisp* lisp, std::string& val);
+bool get(const Lisp* lisp, const Lisp*& val);
+
+template<typename T>
+static inline bool property_get(const Lisp* lisp, T& val)
+{
+ if(lisp->get_list_size() != 2)
+ return false;
+
+ const Lisp* el = lisp->get_list_elem(1);
+ return get(el, val);
+}
+
+static inline bool property_get(const Lisp* lisp, const Lisp*& val)
+{
+ val = lisp;
+ return true;
+}
+
+template<typename T>
+static inline bool property_get(const Lisp* lisp, std::vector<T>& list)
+{
+ list.clear();
+ for(size_t n = 1; n < lisp->get_list_size(); ++n) {
+ T val;
+ if(get(lisp->get_list_elem(n), val) == false) {
+ list.clear();
+ return false;
+ }
+ list.push_back(val);
+ }
+ return true;
+}
+
+}
+
+#endif
+
Added: branches/pingus_sdl/src/lisp/lexer.cpp
===================================================================
--- branches/pingus_sdl/src/lisp/lexer.cpp 2007-01-13 21:37:11 UTC (rev
2640)
+++ branches/pingus_sdl/src/lisp/lexer.cpp 2007-01-13 23:42:24 UTC (rev
2641)
@@ -0,0 +1,217 @@
+// $Id: lexer.cpp 2379 2005-05-01 19:02:16Z matzebraun $
+//
+// Copyright (C) 2004 Matthias Braun <address@hidden>
+// code in this file based on lispreader from Mark Probst
+//
+// This program 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 2
+// of the License, or (at your option) any later version.
+//
+// This program 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 this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#include <config.h>
+
+#include <sstream>
+#include <stdexcept>
+#include <iostream>
+
+#include "lexer.hpp"
+
+namespace lisp
+{
+
+class EOFException
+{
+};
+
+Lexer::Lexer(std::istream& newstream)
+ : stream(newstream), eof(false), linenumber(0)
+{
+ try {
+ // trigger a refill of the buffer
+ c = 0;
+ bufend = 0;
+ nextChar();
+ } catch(EOFException& e) {
+ }
+}
+
+Lexer::~Lexer()
+{
+}
+
+void
+Lexer::nextChar()
+{
+ ++c;
+ if(c >= bufend) {
+ if(eof)
+ throw EOFException();
+ stream.read(buffer, BUFFER_SIZE);
+ size_t bytes_read = stream.gcount();
+
+ c = buffer;
+ bufend = buffer + bytes_read;
+
+ // the following is a hack that appends an additional ' ' at the end of
+ // the file to avoid problems when parsing symbols/elements and a sudden
+ // EOF. This is faster than relying on unget and IMO also nicer.
+ if(bytes_read == 0 || stream.eof()) {
+ eof = true;
+ *bufend = ' ';
+ ++bufend;
+ }
+ }
+}
+
+Lexer::TokenType
+Lexer::getNextToken()
+{
+ static const char* delims = "\"();";
+
+ try {
+ while(isspace(*c)) {
+ if(*c == '\n')
+ ++linenumber;
+ nextChar();
+ };
+
+ token_length = 0;
+
+ switch(*c) {
+ case ';': // comment
+ while(true) {
+ nextChar();
+ if(*c == '\n') {
+ ++linenumber;
+ break;
+ }
+ }
+ return getNextToken(); // and again
+ case '(':
+ nextChar();
+ return TOKEN_OPEN_PAREN;
+ case ')':
+ nextChar();
+ return TOKEN_CLOSE_PAREN;
+ case '"': { // string
+ int startline = linenumber;
+ try {
+ while(1) {
+ nextChar();
+ if(*c == '"')
+ break;
+ else if(*c == '\n')
+ linenumber++;
+ else if(*c == '\\') {
+ nextChar();
+ switch(*c) {
+ case 'n':
+ *c = '\n';
+ break;
+ case 't':
+ *c = '\t';
+ break;
+ }
+ }
+ if(token_length < MAX_TOKEN_LENGTH)
+ token_string[token_length++] = *c;
+ }
+ token_string[token_length] = 0;
+ } catch(EOFException& ) {
+ std::stringstream msg;
+ msg << "Parse error in line " << startline << ": "
+ << "EOF while parsing string.";
+ throw std::runtime_error(msg.str());
+ }
+ nextChar();
+ return TOKEN_STRING;
+ }
+ case '#': // constant
+ try {
+ nextChar();
+
+ while(isalnum(*c) || *c == '_') {
+ if(token_length < MAX_TOKEN_LENGTH)
+ token_string[token_length++] = *c;
+ nextChar();
+ }
+ token_string[token_length] = 0;
+ } catch(EOFException& ) {
+ std::stringstream msg;
+ msg << "Parse Error in line " << linenumber << ": "
+ << "EOF while parsing constant.";
+ throw std::runtime_error(msg.str());
+ }
+
+ if(strcmp(token_string, "t") == 0)
+ return TOKEN_TRUE;
+ if(strcmp(token_string, "f") == 0)
+ return TOKEN_FALSE;
+
+ // we only handle #t and #f constants at the moment...
+
+ {
+ std::stringstream msg;
+ msg << "Parse Error in line " << linenumber << ": "
+ << "Unknown constant '" << token_string << "'.";
+ throw std::runtime_error(msg.str());
+ }
+
+ default:
+ if(isdigit(*c) || *c == '-' || *c == '.') {
+ bool have_nondigits = false;
+ bool have_digits = false;
+ int have_floating_point = 0;
+
+ do {
+ if(isdigit(*c))
+ have_digits = true;
+ else if(*c == '.')
+ ++have_floating_point;
+ else if(isalnum(*c) || *c == '_')
+ have_nondigits = true;
+
+ if(token_length < MAX_TOKEN_LENGTH)
+ token_string[token_length++] = *c;
+
+ nextChar();
+ } while(!isspace(*c) && !strchr(delims, *c));
+
+ token_string[token_length] = 0;
+
+ // no nextChar
+
+ if(have_nondigits || !have_digits || have_floating_point > 1)
+ return TOKEN_SYMBOL;
+ else if(have_floating_point == 1)
+ return TOKEN_REAL;
+ else
+ return TOKEN_INTEGER;
+ } else {
+ do {
+ if(token_length < MAX_TOKEN_LENGTH)
+ token_string[token_length++] = *c;
+ nextChar();
+ } while(!isspace(*c) && !strchr(delims, *c));
+ token_string[token_length] = 0;
+
+ // no nextChar
+
+ return TOKEN_SYMBOL;
+ }
+ }
+ } catch(EOFException& ) {
+ return TOKEN_EOF;
+ }
+}
+
+} // end of namespace lisp
+
Added: branches/pingus_sdl/src/lisp/lexer.hpp
===================================================================
--- branches/pingus_sdl/src/lisp/lexer.hpp 2007-01-13 21:37:11 UTC (rev
2640)
+++ branches/pingus_sdl/src/lisp/lexer.hpp 2007-01-13 23:42:24 UTC (rev
2641)
@@ -0,0 +1,70 @@
+// $Id: lexer.h 2379 2005-05-01 19:02:16Z matzebraun $
+//
+// Copyright (C) 2004 Matthias Braun <address@hidden>
+// code in this file based on lispreader from Mark Probst
+//
+// This program 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 2
+// of the License, or (at your option) any later version.
+//
+// This program 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 this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#ifndef __LISPLEXER_H__
+#define __LISPLEXER_H__
+
+namespace lisp
+{
+
+class Lexer
+{
+public:
+ enum TokenType {
+ TOKEN_EOF,
+ TOKEN_OPEN_PAREN,
+ TOKEN_CLOSE_PAREN,
+ TOKEN_SYMBOL,
+ TOKEN_STRING,
+ TOKEN_INTEGER,
+ TOKEN_REAL,
+ TOKEN_TRUE,
+ TOKEN_FALSE
+ };
+
+ Lexer(std::istream& stream);
+ ~Lexer();
+
+ TokenType getNextToken();
+ const char* getString() const
+ { return token_string; }
+ int getLineNumber() const
+ { return linenumber; }
+
+private:
+ enum {
+ MAX_TOKEN_LENGTH = 16384,
+ BUFFER_SIZE = 1024
+ };
+
+ inline void nextChar();
+
+ std::istream& stream;
+ bool eof;
+ int linenumber;
+ char buffer[BUFFER_SIZE+1];
+ char* bufend;
+ char* c;
+ char token_string[MAX_TOKEN_LENGTH + 1];
+ int token_length;
+};
+
+} // end of namespace lisp
+
+#endif
+
Added: branches/pingus_sdl/src/lisp/lisp.cpp
===================================================================
--- branches/pingus_sdl/src/lisp/lisp.cpp 2007-01-13 21:37:11 UTC (rev
2640)
+++ branches/pingus_sdl/src/lisp/lisp.cpp 2007-01-13 23:42:24 UTC (rev
2641)
@@ -0,0 +1,111 @@
+// $Id: lisp.cpp 2379 2005-05-01 19:02:16Z matzebraun $
+//
+// TuxKart - a fun racing game with go-kart
+// Copyright (C) 2004 Matthias Braun <address@hidden>
+// code in this file based on lispreader from Mark Probst
+//
+// This program 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 2
+// of the License, or (at your option) any later version.
+//
+// This program 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 this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#include <config.h>
+#include <assert.h>
+#include "lisp.hpp"
+
+namespace lisp
+{
+
+Lisp::Lisp(int val)
+ : type(TYPE_INT)
+{
+ v.int_ = val;
+}
+
+Lisp::Lisp(float val)
+ : type(TYPE_FLOAT)
+{
+ v.float_ = val;
+}
+
+Lisp::Lisp(bool val)
+ : type(TYPE_BOOL)
+{
+ v.bool_ = val;
+}
+
+Lisp::Lisp(LispType newtype, const std::string& str)
+ : type(newtype)
+{
+ assert(newtype == TYPE_SYMBOL || type == TYPE_STRING);
+ v.string = new char[str.size()+1];
+ memcpy(v.string, str.c_str(), str.size()+1);
+}
+
+Lisp::Lisp(const std::vector<Lisp*>& list_elements)
+ : type(TYPE_LIST)
+{
+ v.list.size = list_elements.size();
+ v.list.entries = new Lisp* [v.list.size];
+ for(size_t i = 0; i < v.list.size; ++i) {
+ v.list.entries[i] = list_elements[i];
+ }
+}
+
+Lisp::~Lisp()
+{
+ if(type == TYPE_SYMBOL || type == TYPE_STRING) {
+ delete[] v.string;
+ } else if(type == TYPE_LIST) {
+ for(size_t i = 0; i < v.list.size; ++i)
+ delete v.list.entries[i];
+ delete[] v.list.entries;
+ }
+}
+
+void
+Lisp::print(std::ostream& out, int indent) const
+{
+ for(int i = 0; i < indent; ++i)
+ out << ' ';
+
+ switch(type) {
+ case TYPE_LIST:
+ out << "(\n";
+ for(size_t i = 0; i < v.list.size; ++i)
+ v.list.entries[i]->print(out, indent+2);
+ for(int i = 0; i < indent; ++i)
+ out << ' ';
+ out << ")";
+ break;
+ case TYPE_STRING:
+ out << '\'' << v.string << '\'';
+ break;
+ case TYPE_INT:
+ out << v.int_;
+ break;
+ case TYPE_FLOAT:
+ out << v.float_;
+ break;
+ case TYPE_SYMBOL:
+ out << v.string;
+ break;
+ case TYPE_BOOL:
+ out << (v.bool_ ? "true" : "false");
+ break;
+ default:
+ out << "UNKNOWN?!?";
+ break;
+ }
+ out << '\n';
+}
+
+} // end of namespace lisp
Added: branches/pingus_sdl/src/lisp/lisp.hpp
===================================================================
--- branches/pingus_sdl/src/lisp/lisp.hpp 2007-01-13 21:37:11 UTC (rev
2640)
+++ branches/pingus_sdl/src/lisp/lisp.hpp 2007-01-13 23:42:24 UTC (rev
2641)
@@ -0,0 +1,120 @@
+// $Id: lisp.h 2419 2005-05-06 19:08:24Z matzebraun $
+//
+// Copyright (C) 2004 Matthias Braun <address@hidden>
+// code in this file based on lispreader from Mark Probst
+//
+// This program 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 2
+// of the License, or (at your option) any later version.
+//
+// This program 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 this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#ifndef __LISP_HPP__
+#define __LISP_HPP__
+
+#include <string>
+#include <vector>
+#include <iostream>
+#include <sstream>
+#include <stdexcept>
+#include <assert.h>
+
+namespace lisp
+{
+
+class Lisp
+{
+public:
+ enum LispType {
+ TYPE_LIST,
+ TYPE_SYMBOL,
+ TYPE_INT,
+ TYPE_STRING,
+ TYPE_FLOAT,
+ TYPE_BOOL
+ };
+
+ /// construct a new Lisp object symbol or string object
+ Lisp(LispType newtype, const std::string& value);
+ Lisp(const std::vector<Lisp*>& list_elements);
+ Lisp(int val);
+ Lisp(float val);
+ Lisp(bool val);
+ ~Lisp();
+
+ LispType get_type() const
+ { return type; }
+
+ size_t get_list_size() const
+ {
+ return v.list.size;
+ }
+ Lisp* get_list_elem(size_t i) const
+ {
+ assert(i < v.list.size);
+ return v.list.entries[i];
+ }
+
+ const char* get_string() const
+ {
+ if(type != TYPE_STRING)
+ throw std::runtime_error("Lisp is not a string");
+ return v.string;
+ }
+
+ const char* get_symbol() const
+ {
+ if(type != TYPE_SYMBOL)
+ throw std::runtime_error("Lisp is not a symbol");
+ return v.string;
+ }
+
+ int get_int() const
+ {
+ if(type != TYPE_INT)
+ throw std::runtime_error("Lisp is not an int");
+ return v.int_;
+ }
+
+ float get_float() const
+ {
+ if(type != TYPE_FLOAT)
+ throw std::runtime_error("Lisp is not a float");
+ return v.float_;
+ }
+
+ bool get_bool() const
+ {
+ if(type != TYPE_BOOL)
+ throw std::runtime_error("Lisp is not a bool");
+ return v.bool_;
+ }
+
+ void print(std::ostream& out = std::cout, int indent = 0) const;
+
+private:
+ union
+ {
+ struct {
+ Lisp** entries;
+ size_t size;
+ } list;
+ char* string;
+ int int_;
+ bool bool_;
+ float float_;
+ } v;
+ LispType type;
+};
+
+} // end of namespace lisp
+
+#endif
+
Added: branches/pingus_sdl/src/lisp/parser.cpp
===================================================================
--- branches/pingus_sdl/src/lisp/parser.cpp 2007-01-13 21:37:11 UTC (rev
2640)
+++ branches/pingus_sdl/src/lisp/parser.cpp 2007-01-13 23:42:24 UTC (rev
2641)
@@ -0,0 +1,196 @@
+// $Id: parser.cpp 2575 2005-06-07 15:59:27Z matzebraun $
+//
+// TuxKart - a fun racing game with go-kart
+// Copyright (C) 2004 Matthias Braun <address@hidden>
+// code in this file based on lispreader from Mark Probst
+//
+// This program 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 2
+// of the License, or (at your option) any later version.
+//
+// This program 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 this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#include <config.h>
+
+#include <sstream>
+#include <cassert>
+#include <iostream>
+#include <string>
+#include <exception>
+
+#include "../tinygettext/tinygettext.hxx"
+#include "physfs/physfs_stream.hpp"
+#include "parser.hpp"
+#include "lisp.hpp"
+
+namespace lisp
+{
+
+class ParseError : public std::exception
+{
+public:
+ ParseError(const Parser* parser, const std::string& message) throw()
+ {
+ std::ostringstream msg;
+ msg << "Parse error in file '" << parser->filename << "' line "
+ << parser->lexer->getLineNumber() << ": " << message;
+ string = msg.str();
+ }
+ ~ParseError() throw()
+ {}
+
+ const char* what() const throw()
+ {
+ return string.c_str();
+ }
+
+private:
+ std::string string;
+};
+
+Parser::Parser()
+ : lexer(0), dictionary_manager(0), dictionary(0)
+{
+ dictionary_manager = new TinyGetText::DictionaryManager();
+ dictionary_manager->set_charset("UTF-8");
+}
+
+Parser::~Parser()
+{
+ delete lexer;
+ delete dictionary_manager;
+}
+
+static std::string dirname(std::string filename)
+{
+ std::string::size_type p = filename.find_last_of('/');
+ if(p == std::string::npos)
+ return "";
+
+ return filename.substr(0, p+1);
+}
+
+Lisp*
+Parser::parse(const std::string& filename)
+{
+ IFileStream in(filename);
+ if(!in.good()) {
+ std::stringstream msg;
+ msg << "Parser problem: Couldn't open file '" << filename << "'.";
+ throw std::runtime_error(msg.str());
+ }
+
+ return parse(in, filename);
+}
+
+Lisp*
+Parser::parse(std::istream& stream, const std::string& filename)
+{
+ std::auto_ptr<Parser> parser (new Parser());
+
+ parser->filename = filename;
+ parser->dictionary_manager->add_directory(dirname(filename));
+ parser->dictionary = & (parser->dictionary_manager->get_dictionary());
+ parser->lexer = new Lexer(stream);
+
+ parser->token = parser->lexer->getNextToken();
+ if(parser->token != Lexer::TOKEN_OPEN_PAREN)
+ throw ParseError(parser.get(), "file doesn't start with '('");
+
+ std::auto_ptr<Lisp> result (parser->parse());
+ if(parser->token != Lexer::TOKEN_EOF) {
+ if(parser->token == Lexer::TOKEN_CLOSE_PAREN)
+ throw ParseError(parser.get(), "too many ')'");
+ else
+ throw ParseError(parser.get(), "extra tokens at end of file");
+ }
+
+ return result.release();
+}
+
+Lisp*
+Parser::parse()
+{
+ std::vector<Lisp*> entries;
+ try {
+ while(token != Lexer::TOKEN_CLOSE_PAREN && token != Lexer::TOKEN_EOF) {
+ switch(token) {
+ case Lexer::TOKEN_OPEN_PAREN:
+ token = lexer->getNextToken();
+
+ // Handle (_ "blup") strings that need to be translated
+ if(token == Lexer::TOKEN_SYMBOL
+ && strcmp(lexer->getString(), "_") == 0) {
+ token = lexer->getNextToken();
+ if(token != Lexer::TOKEN_STRING)
+ throw ParseError(this, "Expected string after '(_' sequence");
+ if(dictionary) {
+ std::string translation =
dictionary->translate(lexer->getString());
+ entries.push_back(new Lisp(Lisp::TYPE_STRING, translation));
+ } else {
+ entries.push_back(new Lisp(Lisp::TYPE_STRING,
lexer->getString()));
+ }
+
+ token = lexer->getNextToken();
+ if(token != Lexer::TOKEN_CLOSE_PAREN)
+ throw ParseError(this, "Expected ')' after '(_ ""' sequence");
+ break;
+ }
+
+ entries.push_back(parse());
+ if(token != Lexer::TOKEN_CLOSE_PAREN) {
+ if(token == Lexer::TOKEN_EOF)
+ throw ParseError(this, "Expected ')' token, got EOF");
+ else
+ throw ParseError(this, "Expected ')' token");
+ }
+ break;
+ case Lexer::TOKEN_SYMBOL:
+ entries.push_back(new Lisp(Lisp::TYPE_SYMBOL, lexer->getString()));
+ break;
+ case Lexer::TOKEN_STRING:
+ entries.push_back(new Lisp(Lisp::TYPE_STRING, lexer->getString()));
+ break;
+ case Lexer::TOKEN_INTEGER: {
+ int val;
+ sscanf(lexer->getString(), "%d", &val);
+ entries.push_back(new Lisp(val));
+ break;
+ }
+ case Lexer::TOKEN_REAL: {
+ float val;
+ sscanf(lexer->getString(), "%f", &val);
+ entries.push_back(new Lisp(val));
+ break;
+ }
+ case Lexer::TOKEN_TRUE:
+ entries.push_back(new Lisp(true));
+ break;
+ case Lexer::TOKEN_FALSE:
+ entries.push_back(new Lisp(false));
+ break;
+ default:
+ // this should never happen
+ assert(false);
+ }
+
+ token = lexer->getNextToken();
+ }
+ } catch(...) {
+ for(std::vector<Lisp*>::iterator i = entries.begin();
+ i != entries.end(); ++i)
+ delete *i;
+ throw;
+ }
+
+ return new Lisp(entries);
+}
+
+} // end of namespace lisp
Added: branches/pingus_sdl/src/lisp/parser.hpp
===================================================================
--- branches/pingus_sdl/src/lisp/parser.hpp 2007-01-13 21:37:11 UTC (rev
2640)
+++ branches/pingus_sdl/src/lisp/parser.hpp 2007-01-13 23:42:24 UTC (rev
2641)
@@ -0,0 +1,59 @@
+// $Id: parser.h 2379 2005-05-01 19:02:16Z matzebraun $
+//
+// TuxKart - a fun racing game with go-kart
+// Copyright (C) 2004 Matthias Braun <address@hidden>
+//
+// This program 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 2
+// of the License, or (at your option) any later version.
+//
+// This program 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 this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#ifndef __LISPPARSER_H__
+#define __LISPPARSER_H__
+
+#include <string>
+#include "lexer.hpp"
+
+namespace TinyGetText {
+class Dictionary;
+class DictionaryManager;
+}
+
+namespace lisp
+{
+
+class Lisp;
+
+class Parser
+{
+public:
+ ~Parser();
+ static Lisp* parse(const std::string& filename);
+ static Lisp* parse(std::istream& stream, const std::string& filename = "");
+
+private:
+ friend class ParseError;
+
+ Parser();
+
+ Lisp* parse();
+
+ std::string filename;
+ Lexer* lexer;
+ TinyGetText::DictionaryManager* dictionary_manager;
+ TinyGetText::Dictionary* dictionary;
+ Lexer::TokenType token;
+};
+
+} // end of namespace lisp
+
+#endif
+
Added: branches/pingus_sdl/src/lisp/properties.cpp
===================================================================
--- branches/pingus_sdl/src/lisp/properties.cpp 2007-01-13 21:37:11 UTC (rev
2640)
+++ branches/pingus_sdl/src/lisp/properties.cpp 2007-01-13 23:42:24 UTC (rev
2641)
@@ -0,0 +1,51 @@
+#include <config.h>
+
+#include "lisp.hpp"
+#include "properties.hpp"
+
+namespace lisp
+{
+
+Properties::Properties(const Lisp* lisp)
+{
+ if (lisp)
+ {
+ if(lisp->get_type() != Lisp::TYPE_LIST)
+ throw std::runtime_error("Lisp is not a list");
+
+ for(size_t i = 0; i < lisp->get_list_size(); ++i) {
+ const Lisp* child = lisp->get_list_elem(i);
+ if(i == 0 && child->get_type() == Lisp::TYPE_SYMBOL)
+ continue;
+ if(child->get_type() != Lisp::TYPE_LIST)
+ throw std::runtime_error("child of properties lisp is not a list");
+ if(child->get_list_size() > 1)
+ {
+ const Lisp* name = child->get_list_elem(0);
+ if(name->get_type() != Lisp::TYPE_SYMBOL)
+ throw std::runtime_error("property has no symbol as name");
+ properties.insert(std::make_pair(
+ std::string(name->get_symbol()),
ListEntry(child)));
+ }
+ }
+ }
+}
+
+Properties::~Properties()
+{
+}
+
+void
+Properties::print_unused_warnings(const std::string& context) const
+{
+ for(PropertyMap::const_iterator i = properties.begin();
+ i != properties.end(); ++i) {
+ if(i->second.used)
+ continue;
+
+ std::cout << "Warning: property '" << i->first << "' not used (in "
+ << context << ")\n";
+ }
+}
+
+}
Added: branches/pingus_sdl/src/lisp/properties.hpp
===================================================================
--- branches/pingus_sdl/src/lisp/properties.hpp 2007-01-13 21:37:11 UTC (rev
2640)
+++ branches/pingus_sdl/src/lisp/properties.hpp 2007-01-13 23:42:24 UTC (rev
2641)
@@ -0,0 +1,85 @@
+#ifndef __PROPERTIES_HPP__
+#define __PROPERTIES_HPP__
+
+#include <vector>
+#include "getters.hpp"
+#include "property_iterator.hpp"
+
+namespace lisp
+{
+
+class Properties
+{
+public:
+ Properties(const lisp::Lisp* lisp);
+ ~Properties();
+
+ /**
+ * fetches the value of a property. returns true if the property was defined
+ * and could be converted into the target type, false otherwise.
+ * You have to define get() or property_get() functions to support new
+ * datatypes. See getters.hpp for details
+ */
+ template<typename T>
+ bool get(const std::string& name, T& val)
+ {
+ PropertyMap::iterator i = properties.find(name);
+ if(i == properties.end())
+ return false;
+ if(property_get(i->second.lisp, val) == false)
+ return false;
+ i->second.used = true;
+ return true;
+ }
+
+ /**
+ * Ignore a property so that it doesn't give a warning, usefull for
+ * example if some tags are only used by the editor but not by the
+ * game.
+ */
+ void ignore(const std::string& name)
+ {
+ PropertyMap::iterator i = properties.find(name);
+ if(i != properties.end())
+ i->second.used = true;
+ }
+
+ /**
+ * returns an iterator over all properties with a certain name
+ */
+ template<typename T>
+ bool get_iter(const std::string& name, PropertyIterator<T>& iter)
+ {
+ PropertyMap::iterator beg = properties.lower_bound(name);
+ if(beg == properties.end() || beg->first != name) {
+ iter = PropertyIterator<T>(properties.end(), properties.end());
+ return false;
+ }
+ PropertyMap::iterator end = properties.upper_bound(name);
+
+ iter = PropertyIterator<T>(beg, end);
+ return true;
+ }
+
+ /**
+ * returns an iterator over all properties
+ */
+ PropertyIterator<const Lisp*> get_iter()
+ {
+ return PropertyIterator<const Lisp*>(properties.begin(), properties.end());
+ }
+
+ /**
+ * Prints a warning for properties that have not been accessed. This
typically
+ * indicates typos that the user should know about
+ */
+ void print_unused_warnings(const std::string& context) const;
+
+private:
+ PropertyMap properties;
+};
+
+}
+
+#endif
+
Added: branches/pingus_sdl/src/lisp/property_iterator.hpp
===================================================================
--- branches/pingus_sdl/src/lisp/property_iterator.hpp 2007-01-13 21:37:11 UTC
(rev 2640)
+++ branches/pingus_sdl/src/lisp/property_iterator.hpp 2007-01-13 23:42:24 UTC
(rev 2641)
@@ -0,0 +1,74 @@
+#ifndef __PROPERTY_ITERATOR_HPP__
+#define __PROPERTY_ITERATOR_HPP__
+
+#include <map>
+#include <string>
+
+namespace lisp
+{
+
+struct ListEntry {
+ ListEntry(const lisp::Lisp* lisp)
+ : lisp(lisp), used(false)
+ {}
+
+ const Lisp* lisp;
+ bool used;
+};
+typedef std::multimap<std::string, ListEntry> PropertyMap;
+
+template<typename T>
+class PropertyIterator
+{
+public:
+ PropertyIterator()
+ {
+ end = i;
+ }
+
+ T* operator ->() const
+ {
+ return ¤tval;
+ }
+ T operator*() const
+ {
+ return currentval;
+ }
+ bool next() {
+ bool res;
+ do {
+ if(i == end)
+ return false;
+ res = property_get(i->second.lisp, currentval);
+ if(res) {
+ i->second.used = true;
+ current_item = i->first;
+ }
+ ++i;
+ if(res)
+ return true;
+ } while(true);
+ }
+
+ const std::string& item() const
+ {
+ return current_item;
+ }
+
+private:
+ friend class Properties;
+
+ PropertyIterator(PropertyMap::iterator begin, PropertyMap::iterator end)
+ : i(begin), end(end)
+ {
+ }
+
+ PropertyMap::iterator i;
+ PropertyMap::iterator end;
+ std::string current_item;
+ T currentval;
+};
+
+}
+
+#endif
Added: branches/pingus_sdl/src/lisp/writer.cpp
===================================================================
--- branches/pingus_sdl/src/lisp/writer.cpp 2007-01-13 21:37:11 UTC (rev
2640)
+++ branches/pingus_sdl/src/lisp/writer.cpp 2007-01-13 23:42:24 UTC (rev
2641)
@@ -0,0 +1,152 @@
+// $Id: writer.cpp 2575 2005-06-07 15:59:27Z matzebraun $
+//
+// SuperTux - A Jump'n Run
+// Copyright (C) 2004 Matthias Braun <address@hidden
+//
+// This program 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 2
+// of the License, or (at your option) any later version.
+//
+// This program 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 this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+#include <config.h>
+
+#include <iostream>
+
+#include "writer.hpp"
+#include "physfs/physfs_stream.hpp"
+
+namespace lisp
+{
+
+Writer::Writer(const std::string& filename)
+{
+ out = new OFileStream(filename);
+ out_owned = true;
+ indent_depth = 0;
+}
+
+Writer::Writer(std::ostream* newout)
+{
+ out = newout;
+ out_owned = false;
+ indent_depth = 0;
+}
+
+Writer::~Writer()
+{
+ if(lists.size() > 0) {
+ std::cerr << "Warning: Not all sections closed in lispwriter!\n";
+ }
+ if(out_owned)
+ delete out;
+}
+
+void
+Writer::write_comment(const std::string& comment)
+{
+ *out << "; " << comment << "\n";
+}
+
+void
+Writer::start_list(const std::string& listname)
+{
+ indent();
+ *out << '(' << listname << '\n';
+ indent_depth += 2;
+
+ lists.push_back(listname);
+}
+
+void
+Writer::end_list(const std::string& listname)
+{
+ if(lists.size() == 0) {
+ std::cerr << "Trying to close list '" << listname
+ << "', which is not open.\n";
+ return;
+ }
+ if(lists.back() != listname) {
+ std::cerr << "Warning: trying to close list '" << listname
+ << "' while list '" << lists.back() << "' is open.\n";
+ return;
+ }
+ lists.pop_back();
+
+ indent_depth -= 2;
+ indent();
+ *out << ")\n";
+}
+
+void
+Writer::write_int(const std::string& name, int value)
+{
+ indent();
+ *out << '(' << name << ' ' << value << ")\n";
+}
+
+void
+Writer::write_float(const std::string& name, float value)
+{
+ indent();
+ *out << '(' << name << ' ' << value << ")\n";
+}
+
+void
+Writer::write_string(const std::string& name, const std::string& value,
+ bool translatable)
+{
+ indent();
+ *out << '(' << name;
+ if(translatable) {
+ *out << " (_ \"" << value << "\"))\n";
+ } else {
+ *out << " \"" << value << "\")\n";
+ }
+}
+
+void
+Writer::write_bool(const std::string& name, bool value)
+{
+ indent();
+ *out << '(' << name << ' ' << (value ? "#t" : "#f") << ")\n";
+}
+
+void
+Writer::write_int_vector(const std::string& name,
+ const std::vector<int>& value)
+{
+ indent();
+ *out << '(' << name;
+ for(std::vector<int>::const_iterator i = value.begin(); i != value.end();
++i)
+ *out << " " << *i;
+ *out << ")\n";
+}
+
+void
+Writer::write_int_vector(const std::string& name,
+ const std::vector<unsigned int>& value)
+{
+ indent();
+ *out << '(' << name;
+ for(std::vector<unsigned int>::const_iterator i = value.begin(); i !=
value.end(); ++i)
+ *out << " " << *i;
+ *out << ")\n";
+}
+
+void
+Writer::indent()
+{
+ for(int i = 0; i<indent_depth; ++i)
+ *out << ' ';
+}
+
+} // end of namespace lisp
Added: branches/pingus_sdl/src/lisp/writer.hpp
===================================================================
--- branches/pingus_sdl/src/lisp/writer.hpp 2007-01-13 21:37:11 UTC (rev
2640)
+++ branches/pingus_sdl/src/lisp/writer.hpp 2007-01-13 23:42:24 UTC (rev
2641)
@@ -0,0 +1,64 @@
+// $Id: writer.h 2575 2005-06-07 15:59:27Z matzebraun $
+//
+// SuperTux - A Jump'n Run
+// Copyright (C) 2004 Matthias Braun <address@hidden
+//
+// This program 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 2
+// of the License, or (at your option) any later version.
+//
+// This program 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 this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+#ifndef SUPERTUX_LISPWRITER_H
+#define SUPERTUX_LISPWRITER_H
+
+#include <iostream>
+#include <string>
+#include <vector>
+
+namespace lisp
+{
+
+ class Writer
+ {
+ public:
+ Writer(const std::string& filename);
+ Writer(std::ostream* out);
+ ~Writer();
+
+ void write_comment(const std::string& comment);
+
+ void start_list(const std::string& listname);
+
+ void write_int(const std::string& name, int value);
+ void write_float(const std::string& name, float value);
+ void write_string(const std::string& name, const std::string& value,
+ bool translatable = false);
+ void write_bool(const std::string& name, bool value);
+ void write_int_vector(const std::string& name, const std::vector<int>&
value);
+ void write_int_vector(const std::string& name, const std::vector<unsigned
int>& value);
+ // add more write-functions when needed...
+
+ void end_list(const std::string& listname);
+
+ private:
+ void indent();
+
+ std::ostream* out;
+ bool out_owned;
+ int indent_depth;
+ std::vector<std::string> lists;
+ };
+
+} //namespace lisp
+
+#endif //SUPERTUX_LISPWRITER_H
+
Added: branches/pingus_sdl/src/math/vector2i.cpp
===================================================================
--- branches/pingus_sdl/src/math/vector2i.cpp 2007-01-13 21:37:11 UTC (rev
2640)
+++ branches/pingus_sdl/src/math/vector2i.cpp 2007-01-13 23:42:24 UTC (rev
2641)
@@ -0,0 +1,67 @@
+/* $Id$
+** __ __ __ ___ __ __ __ __
+** / \ / \__| ____ __| _/_______/ |_|__| | | | ____
+** \ \/\/ / |/ \ / __ |/ ___/\ __\ | | | | _/ __ \
+** \ /| | | \/ /_/ |\___ \ | | | | |_| |_\ ___/
+** \__/\ / |__|___| /\____ /____ > |__| |__|____/____/\___ >
+** \/ \/ \/ \/ \/
+** Copyright (C) 2005 Ingo Ruhnke <address@hidden>
+**
+** This program 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 2
+** of the License, or (at your option) any later version.
+**
+** This program 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 this program; if not, write to the Free Software
+** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+** 02111-1307, USA.
+*/
+
+#include "vector2i.hpp"
+
+Vector2i
+Vector2i::operator+ (const Vector2i& add) const
+{
+ return Vector2i(x + sub.x, y + sub.y);
+}
+
+Vector2i
+Vector2i::operator- (const Vector2i& sub) const
+{
+ return Vector2i(x - sub.x, y - sub.y);
+}
+
+Vector2i
+Vector2i::operator* (int mul) const
+{
+ return Vector2i(x * mul, y * mul);
+}
+
+Vector2i&
+Vector2i::operator+= (const Vector2i& add)
+{
+ x += sub.x;
+ y += sub.y;
+}
+
+Vector2i&
+Vector2i::operator-= (const Vector2i& sub)
+{
+ x -= sub.x;
+ y -= sub.y;
+}
+
+Vector2i&
+Vector2i::operator*= (int mul)
+{
+ x *= mul;
+ y *= mul;
+}
+
+/* EOF */
Modified: branches/pingus_sdl/src/math/vector2i.hpp
===================================================================
--- branches/pingus_sdl/src/math/vector2i.hpp 2007-01-13 21:37:11 UTC (rev
2640)
+++ branches/pingus_sdl/src/math/vector2i.hpp 2007-01-13 23:42:24 UTC (rev
2641)
@@ -27,9 +27,21 @@
int x;
int y;
+ Vector2i()
+ : x(0), y(0) {}
+
Vector2i(int x_, int y_)
: x(x_), y(y_) {}
+ Vector2i operator- () const;
+
+ Vector2i operator+ (const Vector2i& add) const;
+ Vector2i operator- (const Vector2i& sub) const;
+ Vector2i operator* (int mul) const;
+
+ Vector2i& operator+= (const Vector2i& add);
+ Vector2i& operator-= (const Vector2i& sub);
+ Vector2i& operator*= (int mul);
};
#endif
Added: branches/pingus_sdl/src/physfs/physfs_sdl.cpp
===================================================================
--- branches/pingus_sdl/src/physfs/physfs_sdl.cpp 2007-01-13 21:37:11 UTC
(rev 2640)
+++ branches/pingus_sdl/src/physfs/physfs_sdl.cpp 2007-01-13 23:42:24 UTC
(rev 2641)
@@ -0,0 +1,93 @@
+/*
+Copyright (C) 2005 Matthias Braun <address@hidden>
+
+This program 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 2 of the License, or
+(at your option) any later version.
+
+This program 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 this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+#include <config.h>
+
+#include "physfs_sdl.hpp"
+
+#include <physfs.h>
+
+#include <stdexcept>
+#include <sstream>
+#include <iostream>
+
+#include <assert.h>
+
+static int func_seek(struct SDL_RWops* context, int offset, int whence)
+{
+ PHYSFS_file* file = (PHYSFS_file*) context->hidden.unknown.data1;
+ int res;
+ switch(whence) {
+ case SEEK_SET:
+ res = PHYSFS_seek(file, offset);
+ break;
+ case SEEK_CUR:
+ res = PHYSFS_seek(file, PHYSFS_tell(file) + offset);
+ break;
+ case SEEK_END:
+ res = PHYSFS_seek(file, PHYSFS_fileLength(file) + offset);
+ break;
+ default:
+ res = 0;
+ assert(false);
+ break;
+ }
+ if(res == 0) {
+ std::cerr << "Error seeking in file: " << PHYSFS_getLastError() <<
"\n";
+ return -1;
+ }
+
+ return (int) PHYSFS_tell(file);
+}
+
+static int func_read(struct SDL_RWops* context, void* ptr, int size, int
maxnum)
+{
+ PHYSFS_file* file = (PHYSFS_file*) context->hidden.unknown.data1;
+
+ int res = PHYSFS_read(file, ptr, size, maxnum);
+ return res;
+}
+
+static int func_close(struct SDL_RWops* context)
+{
+ PHYSFS_file* file = (PHYSFS_file*) context->hidden.unknown.data1;
+
+ PHYSFS_close(file);
+ delete context;
+
+ return 0;
+}
+
+SDL_RWops* get_physfs_SDLRWops(const std::string& filename)
+{
+ PHYSFS_file* file = (PHYSFS_file*) PHYSFS_openRead(filename.c_str());
+ if(!file) {
+ std::stringstream msg;
+ msg << "Couldn't open '" << filename << "': "
+ << PHYSFS_getLastError();
+ throw std::runtime_error(msg.str());
+ }
+
+ SDL_RWops* ops = new SDL_RWops();
+ ops->type = 0;
+ ops->hidden.unknown.data1 = file;
+ ops->seek = func_seek;
+ ops->read = func_read;
+ ops->write = 0;
+ ops->close = func_close;
+ return ops;
+}
Added: branches/pingus_sdl/src/physfs/physfs_sdl.hpp
===================================================================
--- branches/pingus_sdl/src/physfs/physfs_sdl.hpp 2007-01-13 21:37:11 UTC
(rev 2640)
+++ branches/pingus_sdl/src/physfs/physfs_sdl.hpp 2007-01-13 23:42:24 UTC
(rev 2641)
@@ -0,0 +1,27 @@
+/*
+Copyright (C) 2005 Matthias Braun <address@hidden>
+
+This program 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 2 of the License, or
+(at your option) any later version.
+
+This program 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 this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+#ifndef __PHYSFSSDL_HPP__
+#define __PHYSFSSDL_HPP__
+
+#include <SDL.h>
+#include <string>
+
+SDL_RWops* get_physfs_SDLRWops(const std::string& filename);
+
+#endif
+
Added: branches/pingus_sdl/src/physfs/physfs_stream.cpp
===================================================================
--- branches/pingus_sdl/src/physfs/physfs_stream.cpp 2007-01-13 21:37:11 UTC
(rev 2640)
+++ branches/pingus_sdl/src/physfs/physfs_stream.cpp 2007-01-13 23:42:24 UTC
(rev 2641)
@@ -0,0 +1,173 @@
+/*
+Copyright (C) 2005 Matthias Braun <address@hidden>
+
+This program 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 2 of the License, or
+(at your option) any later version.
+
+This program 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 this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+#include <config.h>
+
+#include "physfs_stream.hpp"
+
+#include <assert.h>
+#include <physfs.h>
+#include <stdexcept>
+#include <sstream>
+
+IFileStreambuf::IFileStreambuf(const std::string& filename)
+{
+ file = PHYSFS_openRead(filename.c_str());
+ if(file == 0) {
+ std::stringstream msg;
+ msg << "Couldn't open file '" << filename << "': "
+ << PHYSFS_getLastError();
+ throw std::runtime_error(msg.str());
+ }
+}
+
+IFileStreambuf::~IFileStreambuf()
+{
+ PHYSFS_close(file);
+}
+
+int
+IFileStreambuf::underflow()
+{
+ if(PHYSFS_eof(file)) {
+ return traits_type::eof();
+ }
+
+ PHYSFS_sint64 bytesread = PHYSFS_read(file, buf, 1, sizeof(buf));
+ if(bytesread <= 0) {
+ return traits_type::eof();
+ }
+ setg(buf, buf, buf + bytesread);
+
+ // without the conversation some characters (255?) would be
+ // handled like EOF
+ return traits_type::to_int_type(buf[0]);
+}
+
+IFileStreambuf::pos_type
+IFileStreambuf::seekpos(pos_type pos, std::ios_base::openmode)
+{
+ if(PHYSFS_seek(file, static_cast<PHYSFS_uint64> (pos)) == 0) {
+ return pos_type(off_type(-1));
+ }
+
+ // the seek invalidated the buffer
+ setg(buf, buf, buf);
+ return pos;
+}
+
+IFileStreambuf::pos_type
+IFileStreambuf::seekoff(off_type off, std::ios_base::seekdir dir,
+ std::ios_base::openmode mode)
+{
+ off_type pos = off;
+ PHYSFS_sint64 ptell = PHYSFS_tell(file);
+
+ switch(dir) {
+ case std::ios_base::beg:
+ break;
+ case std::ios_base::cur:
+ if(off == 0)
+ return static_cast<pos_type> (ptell) - static_cast<pos_type> (egptr()
- gptr());
+ pos += static_cast<off_type> (ptell) - static_cast<off_type> (egptr() -
gptr());
+ break;
+ case std::ios_base::end:
+ pos += static_cast<off_type> (PHYSFS_fileLength(file));
+ break;
+ default:
+#ifdef DEBUG
+ assert(false);
+#else
+ return pos_type(off_type(-1));
+#endif
+ }
+
+ return seekpos(static_cast<pos_type> (pos), mode);
+}
+
+//---------------------------------------------------------------------------
+
+OFileStreambuf::OFileStreambuf(const std::string& filename)
+{
+ file = PHYSFS_openWrite(filename.c_str());
+ if(file == 0) {
+ std::stringstream msg;
+ msg << "Couldn't open file '" << filename << "': "
+ << PHYSFS_getLastError();
+ throw std::runtime_error(msg.str());
+ }
+
+ setp(buf, buf+sizeof(buf));
+}
+
+OFileStreambuf::~OFileStreambuf()
+{
+ sync();
+ PHYSFS_close(file);
+}
+
+int
+OFileStreambuf::overflow(int c)
+{
+ if(pbase() == pptr())
+ return 0;
+
+ size_t size = pptr() - pbase();
+ PHYSFS_sint64 res = PHYSFS_write(file, pbase(), 1, size);
+ if(res <= 0)
+ return traits_type::eof();
+
+ if(c != traits_type::eof()) {
+ PHYSFS_sint64 res = PHYSFS_write(file, &c, 1, 1);
+ if(res <= 0)
+ return traits_type::eof();
+ }
+
+ setp(buf, buf + res);
+ return 0;
+}
+
+int
+OFileStreambuf::sync()
+{
+ return overflow(traits_type::eof());
+}
+
+//---------------------------------------------------------------------------
+
+IFileStream::IFileStream(const std::string& filename)
+ : std::istream(new IFileStreambuf(filename))
+{
+}
+
+IFileStream::~IFileStream()
+{
+ delete rdbuf();
+}
+
+//---------------------------------------------------------------------------
+
+OFileStream::OFileStream(const std::string& filename)
+ : std::ostream(new OFileStreambuf(filename))
+{
+}
+
+OFileStream::~OFileStream()
+{
+ delete rdbuf();
+}
+
Added: branches/pingus_sdl/src/physfs/physfs_stream.hpp
===================================================================
--- branches/pingus_sdl/src/physfs/physfs_stream.hpp 2007-01-13 21:37:11 UTC
(rev 2640)
+++ branches/pingus_sdl/src/physfs/physfs_stream.hpp 2007-01-13 23:42:24 UTC
(rev 2641)
@@ -0,0 +1,77 @@
+/*
+Copyright (C) 2004 by Matthias Braun <address@hidden>
+
+This program 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 2 of the License, or
+(at your option) any later version.
+
+This program 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 this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+#ifndef __PHYSFSSTREAM_HPP__
+#define __PHYSFSSTREAM_HPP__
+
+#include <stdio.h>
+#include <physfs.h>
+#include <string>
+#include <streambuf>
+#include <iostream>
+
+/** This class implements a C++ streambuf object for physfs files.
+ * So that you can use normal istream operations on them
+ */
+class IFileStreambuf : public std::streambuf
+{
+public:
+ IFileStreambuf(const std::string& filename);
+ ~IFileStreambuf();
+
+protected:
+ virtual int underflow();
+ virtual pos_type seekoff(off_type pos, std::ios_base::seekdir,
+ std::ios_base::openmode);
+ virtual pos_type seekpos(pos_type pos, std::ios_base::openmode);
+
+private:
+ PHYSFS_file* file;
+ char buf[1024];
+};
+
+class OFileStreambuf : public std::streambuf
+{
+public:
+ OFileStreambuf(const std::string& filename);
+ ~OFileStreambuf();
+
+protected:
+ virtual int overflow(int c);
+ virtual int sync();
+
+private:
+ PHYSFS_file* file;
+ char buf[1024];
+};
+
+class IFileStream : public std::istream
+{
+public:
+ IFileStream(const std::string& filename);
+ ~IFileStream();
+};
+
+class OFileStream : public std::ostream
+{
+public:
+ OFileStream(const std::string& filename);
+ ~OFileStream();
+};
+
+#endif
+
Modified: branches/pingus_sdl/src/sprite.cpp
===================================================================
--- branches/pingus_sdl/src/sprite.cpp 2007-01-13 21:37:11 UTC (rev 2640)
+++ branches/pingus_sdl/src/sprite.cpp 2007-01-13 23:42:24 UTC (rev 2641)
@@ -27,6 +27,8 @@
#include <sstream>
#include <assert.h>
#include "SDL.h"
+#include "origin.hpp"
+#include "math/vector2i.hpp"
#include "SDL_image.h"
#include "sprite.hpp"
@@ -34,6 +36,8 @@
{
public:
SDL_Surface* surface;
+ Vector2i offset;
+ Origin origin;
SpriteImpl(const std::string& name)
{
@@ -50,7 +54,27 @@
{
std::cout << "Loaded sprite: " << name << std::endl;
}
+
+ //offset.x = surface->w/2;
+ //offset.y = surface->h/2;
}
+
+ ~SpriteImpl()
+ {
+ SDL_FreeSurface(surface);
+ }
+
+ void draw(float x, float y, SDL_Surface* target)
+ {
+ SDL_Rect pos;
+
+ pos.x = (Sint16)(x - offset.x);
+ pos.y = (Sint16)(y - offset.y);
+ pos.w = 0;
+ pos.h = 0;
+
+ SDL_BlitSurface(surface, NULL, target, &pos);
+ }
};
Sprite::Sprite()
@@ -71,12 +95,7 @@
Sprite::draw(float x, float y, SDL_Surface* target)
{
//std::cout << "Sprite: draw; " << x << ", " << y << std::endl;
- SDL_Rect pos;
- pos.x = (Sint16)x;
- pos.y = (Sint16)y;
- pos.w = 0;
- pos.h = 0;
- SDL_BlitSurface(impl->surface, NULL, target, &pos);
+ impl->draw(x, y, target);
}
int
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [Pingus-CVS] r2641 - in branches/pingus_sdl/src: . lisp math physfs,
grumbel at BerliOS <=