From: Daniel Karbach Date: Sat, 1 Sep 2012 17:01:50 +0000 (+0200) Subject: added hard support for path names in source files X-Git-Url: https://git.localhorst.tv/?a=commitdiff_plain;h=09e8cfd4d7b2d187fed0870ebdb2e9e3f77fe4b9;p=l2e.git added hard support for path names in source files --- diff --git a/src/loader/Interpreter.cpp b/src/loader/Interpreter.cpp index 7c26aaa..5d3b9fc 100644 --- a/src/loader/Interpreter.cpp +++ b/src/loader/Interpreter.cpp @@ -244,6 +244,19 @@ PartyLayout *Interpreter::GetPartyLayout(const std::string &name) { } } +const char *Interpreter::GetPath(const std::string &name) const { + map::const_iterator i(parsedDefinitions.find(name)); + if (i != parsedDefinitions.end()) { + if (i->second.type == PATH) { + return strings[i->second.index]; + } else { + throw Error("cannot cast " + i->second.dfn->TypeName() + " to Path"); + } + } else { + throw Error("access to undefined Path " + name); + } +} + Spell *Interpreter::GetSpell(const std::string &name) { map::const_iterator i(parsedDefinitions.find(name)); if (i != parsedDefinitions.end()) { @@ -273,7 +286,8 @@ Sprite *Interpreter::GetSprite(const std::string &name) { const char *Interpreter::GetString(const std::string &name) const { map::const_iterator i(parsedDefinitions.find(name)); if (i != parsedDefinitions.end()) { - if (i->second.type == STRING) { + // TODO: enable path to string casting some time + if (i->second.type == STRING /* || i->second.type == PATH */) { return strings[i->second.index]; } else { throw Error("cannot cast " + i->second.dfn->TypeName() + " to String"); @@ -348,6 +362,15 @@ void Interpreter::ReadLiteral(const Definition &dfn) { numbers.push_back(dfn.GetLiteral()->GetNumber()); parsedDefinitions.insert(make_pair(dfn.Identifier(), ParsedDefinition(&dfn, NUMBER, numbers.size() - 1))); break; + case Literal::PATH: + { + char *str(new char[dfn.GetLiteral()->GetString().size() + 1]); + std::memcpy(str, dfn.GetLiteral()->GetString().c_str(), dfn.GetLiteral()->GetString().size()); + str[dfn.GetLiteral()->GetString().size()] = '\0'; + strings.push_back(str); + } + parsedDefinitions.insert(make_pair(dfn.Identifier(), ParsedDefinition(&dfn, PATH, strings.size() - 1))); + break; case Literal::STRING: { char *str(new char[dfn.GetLiteral()->GetString().size() + 1]); @@ -451,10 +474,16 @@ Ikari *Interpreter::GetIkari(const Value &v) { } SDL_Surface *Interpreter::GetImage(const Value &v) { - const char *file(GetString(v)); - SDL_Surface *image(IMG_Load(file)); - images.push_back(image); - return image; + string path(GetPath(v)); + map::const_iterator i(imageCache.find(path)); + if (i == imageCache.end()) { + SDL_Surface *image(IMG_Load(path.c_str())); + images.push_back(image); + imageCache.insert(make_pair(path, image)); + return image; + } else { + return i->second; + } } Item *Interpreter::GetItem(const Value &v) { @@ -488,6 +517,15 @@ PartyLayout *Interpreter::GetPartyLayout(const Value &v) { } } +const char *Interpreter::GetPath(const Value &v) { + if (v.IsLiteral()) { + return v.GetLiteral().GetString().c_str(); + } else { + ReadDefinition(source.GetDefinition(v.GetIdentifier())); + return GetPath(v.GetIdentifier()); + } +} + const PropertyList *Interpreter::GetPropertyList(const Value &v) { if (v.IsLiteral()) { return v.GetLiteral().GetProperties(); diff --git a/src/loader/Interpreter.h b/src/loader/Interpreter.h index ffbad42..7755a1b 100644 --- a/src/loader/Interpreter.h +++ b/src/loader/Interpreter.h @@ -77,6 +77,7 @@ public: battle::Monster *GetMonster(const std::string &name); int GetNumber(const std::string &name) const; battle::PartyLayout *GetPartyLayout(const std::string &name); + const char *GetPath(const std::string &name) const; common::Spell *GetSpell(const std::string &name); graphics::Sprite *GetSprite(const std::string &name); const char *GetString(const std::string &name) const; @@ -121,6 +122,7 @@ private: battle::PartyLayout *GetPartyLayout(const Value &); const PropertyList *GetPropertyList(const Value &); const std::vector &GetPropertyListArray(const Value &); + const char *GetPath(const Value &); common::Spell *GetSpell(const Value &); graphics::Sprite *GetSprite(const Value &); const char *GetString(const Value &); @@ -159,6 +161,7 @@ private: MONSTER, NUMBER, PARTY_LAYOUT, + PATH, PROPERTY_LIST_ARRAY, SIMPLE_ANIMATION, SPELL, @@ -177,6 +180,8 @@ private: }; std::map parsedDefinitions; + std::map imageCache; + std::vector booleans; std::vector complexAnimations; std::vector fonts; diff --git a/src/loader/ParsedSource.cpp b/src/loader/ParsedSource.cpp index 13b1262..bceed08 100644 --- a/src/loader/ParsedSource.cpp +++ b/src/loader/ParsedSource.cpp @@ -7,6 +7,8 @@ #include "ParsedSource.h" +#include "utility.h" + #include #include @@ -209,6 +211,16 @@ Literal::Literal(int number) } +Literal::Literal(const string &dir, const string &path) +: props(0) +, str(CatPath(dir, path)) +, i1(0), i2(0) +, i3(0), i4(0) +, b(false) +, type(STRING) { + +} + Literal::Literal(const string &str) : props(0) , str(str) @@ -428,6 +440,9 @@ ostream &operator <<(ostream &out, const loader::Literal &l) { case loader::Literal::NUMBER: out << "number, " << l.GetNumber(); break; + case loader::Literal::PATH: + out << "path, \"" << l.GetString() << '"'; + break; case loader::Literal::STRING: out << "string, \"" << l.GetString() << '"'; break; diff --git a/src/loader/ParsedSource.h b/src/loader/ParsedSource.h index 36f3810..8401777 100644 --- a/src/loader/ParsedSource.h +++ b/src/loader/ParsedSource.h @@ -28,6 +28,7 @@ public: BOOLEAN, COLOR, NUMBER, + PATH, STRING, VECTOR, OBJECT @@ -39,6 +40,7 @@ public: explicit Literal(bool); Literal(int r, int g, int b, int a = 255); explicit Literal(int number); + Literal(const std::string &dir, const std::string &path); Literal(const std::string &); Literal(int x, int y); Literal(const std::string &typeName, PropertyList *properties); diff --git a/src/loader/Parser.cpp b/src/loader/Parser.cpp index bd65200..6e5cbe0 100644 --- a/src/loader/Parser.cpp +++ b/src/loader/Parser.cpp @@ -107,6 +107,7 @@ Declaration *Parser::ProbeDefinition() { bool Parser::BeginningOfLiteral(const Tokenizer::Token &t) const { switch (t.type) { case Tokenizer::Token::CHEVRON_OPEN: + case Tokenizer::Token::COLON: case Tokenizer::Token::BRACKET_OPEN: case Tokenizer::Token::PARENTHESIS_OPEN: case Tokenizer::Token::NUMBER: @@ -205,6 +206,10 @@ Literal *Parser::ParseLiteral() { case Tokenizer::Token::CHEVRON_OPEN: tok.Putback(t); return ParseVector(); + case Tokenizer::Token::COLON: + t = GetToken(); + AssertTokenType(t.type, Tokenizer::Token::STRING); + return new Literal(dirname, t.str); case Tokenizer::Token::BRACKET_OPEN: tok.Putback(t); return ParseArray(); diff --git a/test-data/items.l2s b/test-data/items.l2s index f1734a7..ac45d2a 100644 --- a/test-data/items.l2s +++ b/test-data/items.l2s @@ -1,66 +1,66 @@ export Sprite potionIcon { - image: "test-data/item-icons.png", + image: :"item-icons.png", size: <16,16> } export Sprite ballIcon { - image: "test-data/item-icons.png", + image: :"item-icons.png", size: <16,16>, offset: <0,16> } export Sprite crankIcon { - image: "test-data/item-icons.png", + image: :"item-icons.png", size: <16,16>, offset: <0,32> } export Sprite spearIcon { - image: "test-data/item-icons.png", + image: :"item-icons.png", size: <16,16>, offset: <0,48> } export Sprite swordIcon { - image: "test-data/item-icons.png", + image: :"item-icons.png", size: <16,16>, offset: <0,64> } export Sprite axIcon { - image: "test-data/item-icons.png", + image: :"item-icons.png", size: <16,16>, offset: <0,80> } export Sprite rodIcon { - image: "test-data/item-icons.png", + image: :"item-icons.png", size: <16,16>, offset: <0,96> } export Sprite armorIcon { - image: "test-data/item-icons.png", + image: :"item-icons.png", size: <16,16>, offset: <0,112> } export Sprite shieldIcon { - image: "test-data/item-icons.png", + image: :"item-icons.png", size: <16,16>, offset: <0,128> } export Sprite helmetIcon { - image: "test-data/item-icons.png", + image: :"item-icons.png", size: <16,16>, offset: <0,144> } export Sprite ringIcon { - image: "test-data/item-icons.png", + image: :"item-icons.png", size: <16,16>, offset: <0,160> } export Sprite jewelIcon { - image: "test-data/item-icons.png", + image: :"item-icons.png", size: <16,16>, offset: <0,176> } export SimpleAnimation swordAttackAnimation { sprite: Sprite { - image: "test-data/attack-sword.png", + image: :"attack-sword.png", size: <96,96> }, frametime: twoFramesTime, diff --git a/test-data/test.l2s b/test-data/test.l2s index 6b03e29..1547c8f 100644 --- a/test-data/test.l2s +++ b/test-data/test.l2s @@ -21,8 +21,7 @@ export PartyLayout heroesLayout { } Sprite lizardSprite { - // using pathes relative to project root until path resolution is implemented - image: "test-data/monster.png", + image: :"monster.png", size: <64,64> } @@ -54,7 +53,7 @@ export Monster lizard { }, meleeAnimation: SimpleAnimation { sprite: Sprite { - image: "test-data/attack-monster.png", + image: :"attack-monster.png", size: <96,64> }, frametime: frameTime, @@ -63,7 +62,7 @@ export Monster lizard { } Sprite maximSprite { - image: "test-data/maxim.png", + image: :"maxim.png", size: <64,64> } export Hero maxim { @@ -130,7 +129,7 @@ export Hero maxim { }, meleeAnimation: SimpleAnimation { sprite: Sprite { - image: "test-data/melee-maxim.png", + image: :"melee-maxim.png", size: <96,96> }, frametime: twoFramesTime, @@ -139,7 +138,7 @@ export Hero maxim { } Sprite selanSprite { - image: "test-data/selan.png", + image: :"selan.png", size: <64,64> } export Hero selan { @@ -200,7 +199,7 @@ export Hero selan { }, meleeAnimation: SimpleAnimation { sprite: Sprite { - image: "test-data/melee-selan.png", + image: :"melee-selan.png", size: <96,96> }, frametime: twoFramesTime, @@ -209,7 +208,7 @@ export Hero selan { } Sprite guySprite { - image: "test-data/guy.png", + image: :"guy.png", size: <64,64> } export Hero guy { @@ -253,7 +252,7 @@ export Hero guy { }, meleeAnimation: SimpleAnimation { sprite: Sprite { - image: "test-data/melee-guy.png", + image: :"melee-guy.png", size: <96,96> }, frametime: fourFramesTime, @@ -262,7 +261,7 @@ export Hero guy { } Sprite dekarSprite { - image: "test-data/dekar.png", + image: :"dekar.png", size: <64,64> } export Hero dekar { @@ -324,7 +323,7 @@ export Hero dekar { }, meleeAnimation: SimpleAnimation { sprite: Sprite { - image: "test-data/melee-dekar.png", + image: :"melee-dekar.png", size: <96,96> }, frametime: twoFramesTime, @@ -333,30 +332,30 @@ export Hero dekar { } export Sprite swapCursor { - image: "test-data/swap-cursor.png", + image: :"swap-cursor.png", size: <32,32> } export Sprite attackIcons { - image: "test-data/attack-type-icons.png", + image: :"attack-type-icons.png", size: <32,32> } export Sprite attackChoiceIcons { - image: "test-data/attack-choice-icons.png", + image: :"attack-choice-icons.png", size: <16,16> } export Sprite moveIcons { - image: "test-data/move-icons.png", + image: :"move-icons.png", size: <32,32> } export Frame titleFrame { - image: "test-data/title-frame.png", + image: :"title-frame.png", border: <16,16> } export Font largeFont { sprite: Sprite { - image: "test-data/large-font.png", + image: :"large-font.png", size: <16,32> }, rowoffset: -2 @@ -404,48 +403,48 @@ export ComplexAnimation numberAnimationPrototype { ] } export Sprite bigNumbers { - image: "test-data/big-numbers.png", + image: :"big-numbers.png", size: <16,32> } export Sprite bigGreenNumbers { - image: "test-data/big-green-numbers.png", + image: :"big-green-numbers.png", size: <16,32> } export Sprite heroTagLabels { - image: "test-data/hero-tag-sprites.png", + image: :"hero-tag-sprites.png", size: <32,16> } export Font heroTagFont { sprite: Sprite { - image: "test-data/numbers.png", + image: :"numbers.png", size: <16,16> }, rowoffset: -3 } export Frame activeHeroTagFrame { - image: "test-data/tag-frames.png", + image: :"tag-frames.png", border: <16,16> } export Frame heroTagFrame { - image: "test-data/tag-frames.png", + image: :"tag-frames.png", border: <16,16>, offset: < 0,33> } export Frame smallHeroTagFrame { - image: "test-data/small-tag-frame.png", + image: :"small-tag-frame.png", border: <8,16> } export Frame lastSmallHeroTagFrame { - image: "test-data/small-tag-frame.png", + image: :"small-tag-frame.png", border: <8,16>, offset: <0,33> } export Gauge healthGauge { - image: "test-data/gauges.png", + image: :"gauges.png", full: <0,16>, empty: <0, 0>, height: 16, @@ -454,7 +453,7 @@ export Gauge healthGauge { end: 6 } export Gauge manaGauge { - image: "test-data/gauges.png", + image: :"gauges.png", full: <0,32>, empty: <0, 0>, height: 16, @@ -463,7 +462,7 @@ export Gauge manaGauge { end: 6 } export Gauge ikariGauge { - image: "test-data/gauges.png", + image: :"gauges.png", full: <0,48>, empty: <0, 0>, height: 16, @@ -473,39 +472,39 @@ export Gauge ikariGauge { } export Frame selectFrame { - image: "test-data/select-frame.png", + image: :"select-frame.png", border: <16,16> } export Font normalFont { sprite: Sprite { - image: "test-data/normal-font.png", + image: :"normal-font.png", size: <16,16> }, rowoffset: -2 } export Font disabledFont { sprite: Sprite { - image: "test-data/disabled-font.png", + image: :"disabled-font.png", size: <16,16> }, rowoffset: -2 } export Sprite handCursor { - image: "test-data/cursor-hand.png", + image: :"cursor-hand.png", size: <32,32> } export Sprite weaponTargetCursor { - image: "test-data/targeting-icons.png", + image: :"targeting-icons.png", size: <32,32> } export Sprite magicTargetCursor { - image: "test-data/targeting-icons.png", + image: :"targeting-icons.png", size: <32,32>, offset: <0,32> } export Sprite itemTargetCursor { - image: "test-data/targeting-icons.png", + image: :"targeting-icons.png", size: <32,32>, offset: <0,64> }