├── Makefile.am ├── src ├── Makefile.am ├── blocks │ ├── TRNS.hpp │ ├── SOU.hpp │ ├── NLSC.hpp │ ├── RMIH.hpp │ ├── SOUN.hpp │ ├── GMD.hpp │ ├── OBNA.hpp │ ├── VCTL.hpp │ ├── ENCD.hpp │ ├── EXCD.hpp │ ├── OFFS.hpp │ ├── VERB.hpp │ ├── RMIM.hpp │ ├── LSCR.hpp │ ├── RMHD.hpp │ ├── SCRP.hpp │ ├── PALS.hpp │ ├── OBIM.hpp │ ├── DCHR.hpp │ ├── DROO.hpp │ ├── DSCR.hpp │ ├── BOXM.hpp │ ├── OBCD.hpp │ ├── SOU2.hpp │ ├── AARY.hpp │ ├── APAL.hpp │ ├── DCOS.hpp │ ├── DSOU.hpp │ ├── IMxx.hpp │ ├── WRAP.hpp │ ├── LOFF.hpp │ ├── RNAM.hpp │ ├── ZPxx.hpp │ ├── DOBJ.hpp │ ├── SOU.cpp │ ├── LECF.hpp │ ├── SOUN.cpp │ ├── SCAL.hpp │ ├── RMIH.cpp │ ├── CDHD.hpp │ ├── SMAP.hpp │ ├── PALS.cpp │ ├── VOC.hpp │ ├── OBNA.cpp │ ├── NLSC.cpp │ ├── IMHD.hpp │ ├── CYCL.hpp │ ├── ENCD.cpp │ ├── EXCD.cpp │ ├── SCRP.cpp │ ├── VERB.cpp │ ├── VCTL.cpp │ ├── RMIM.cpp │ ├── TRNS.cpp │ ├── BOXD.hpp │ ├── GMD.cpp │ ├── LSCR.cpp │ ├── OBCD.cpp │ ├── ROOM.hpp │ ├── WRAP.cpp │ ├── LECF.cpp │ ├── OFFS.cpp │ ├── OBIM.cpp │ ├── APAL.cpp │ ├── DROO.cpp │ ├── CHAR.hpp │ ├── MAXS.hpp │ ├── DCHR.cpp │ ├── DSCR.cpp │ ├── IMxx.cpp │ ├── SOU2.cpp │ ├── RMHD.cpp │ ├── SCAL.cpp │ ├── RNAM.cpp │ ├── DCOS.cpp │ ├── DSOU.cpp │ ├── AARY.cpp │ ├── BOXM.cpp │ ├── LFLF.hpp │ ├── CDHD.cpp │ ├── LOFF.cpp │ ├── DOBJ.cpp │ ├── SMAP.cpp │ ├── VOC.cpp │ ├── COST.hpp │ ├── IMHD.cpp │ ├── ZPxx.cpp │ ├── CYCL.cpp │ ├── Makefile.am │ ├── BOXD.cpp │ ├── LFLF.cpp │ ├── MAXS.cpp │ ├── ROOM.cpp │ └── CHAR.cpp ├── util │ ├── Makefile.am │ ├── MIDFile.hpp │ ├── WAVFile.hpp │ ├── Log.hpp │ ├── MIDFile.cpp │ ├── BMPFile.hpp │ ├── Log.cpp │ ├── IO.hpp │ ├── XMLFile.hpp │ ├── WAVFile.cpp │ ├── BMPFile.cpp │ ├── IO.cpp │ └── XMLFile.cpp ├── grammar │ ├── Declaration.cpp │ ├── Makefile.am │ ├── Declaration.hpp │ ├── Function.hpp │ ├── Context.hpp │ ├── Function.cpp │ ├── lexer.ll │ ├── Expression.hpp │ └── Statement.hpp ├── types │ ├── Midi.hpp │ ├── Makefile.am │ ├── Script.hpp │ ├── Voice.hpp │ ├── Image.hpp │ ├── Charset.hpp │ ├── Object.hpp │ ├── Midi.cpp │ ├── Map.hpp │ ├── Room.hpp │ ├── Voice.cpp │ ├── Script.cpp │ ├── Costume.hpp │ ├── Charset.cpp │ ├── Palette.hpp │ ├── Image.cpp │ ├── Game.hpp │ └── Map.cpp ├── libscumm │ ├── Sound.sgc │ ├── vars.sgc │ ├── Verb.sgc │ ├── Script.sgc │ ├── Object.sgc │ ├── Room.sgc │ ├── Util.sgc │ └── Interface.sgc └── main.cpp └── configure.ac /Makefile.am: -------------------------------------------------------------------------------- 1 | SUBDIRS = src 2 | -------------------------------------------------------------------------------- /src/Makefile.am: -------------------------------------------------------------------------------- 1 | SUBDIRS = blocks \ 2 | grammar \ 3 | types \ 4 | util 5 | 6 | bin_PROGRAMS = scummgen 7 | scummgen_SOURCES = main.cpp 8 | scummgen_LDADD = types/libtypes.la blocks/libblocks.la grammar/libgrammar.la util/libutil.la @XML_LIBS@ 9 | -------------------------------------------------------------------------------- /src/blocks/TRNS.hpp: -------------------------------------------------------------------------------- 1 | #ifndef _TRNS_BLOCK_HPP_ 2 | #define _TRNS_BLOCK_HPP_ 3 | 4 | #include 5 | #include 6 | using namespace std; 7 | 8 | class TRNS 9 | { 10 | private: 11 | static const uint8_t TRANSPARENT_INDEX; 12 | public: 13 | TRNS(); 14 | uint32_t getSize(); 15 | void write(fstream &f); 16 | ~TRNS(); 17 | }; 18 | 19 | #endif 20 | 21 | -------------------------------------------------------------------------------- /src/blocks/SOU.hpp: -------------------------------------------------------------------------------- 1 | #ifndef _SOU_BLOCK_HPP_ 2 | #define _SOU_BLOCK_HPP_ 3 | 4 | #include 5 | #include 6 | using namespace std; 7 | 8 | class Midi; 9 | class GMD; 10 | 11 | class SOU 12 | { 13 | private: 14 | GMD *_gmd; 15 | public: 16 | SOU(Midi *midi); 17 | uint32_t getSize(); 18 | void write(fstream &f); 19 | ~SOU(); 20 | }; 21 | 22 | #endif 23 | -------------------------------------------------------------------------------- /src/blocks/NLSC.hpp: -------------------------------------------------------------------------------- 1 | #ifndef _NLSC_BLOCK_HPP_ 2 | #define _NLSC_BLOCK_HPP_ 3 | 4 | #include 5 | #include 6 | using namespace std; 7 | 8 | class Room; 9 | 10 | class NLSC 11 | { 12 | private: 13 | uint8_t _nLocalScripts; 14 | public: 15 | NLSC(Room *room); 16 | uint32_t getSize(); 17 | void write(fstream &f); 18 | ~NLSC(); 19 | }; 20 | 21 | #endif 22 | 23 | -------------------------------------------------------------------------------- /src/blocks/RMIH.hpp: -------------------------------------------------------------------------------- 1 | #ifndef _RMIH_BLOCK_HPP_ 2 | #define _RMIH_BLOCK_HPP_ 3 | 4 | #include 5 | #include 6 | using namespace std; 7 | 8 | class Image; 9 | 10 | class RMIH 11 | { 12 | private: 13 | uint16_t _nZPlanes; 14 | public: 15 | RMIH(Image *image); 16 | uint32_t getSize(); 17 | void write(fstream &f); 18 | ~RMIH(); 19 | }; 20 | 21 | #endif 22 | 23 | -------------------------------------------------------------------------------- /src/blocks/SOUN.hpp: -------------------------------------------------------------------------------- 1 | #ifndef _SOUN_BLOCK_HPP_ 2 | #define _SOUN_BLOCK_HPP_ 3 | 4 | #include 5 | #include 6 | using namespace std; 7 | 8 | class Midi; 9 | class SOU; 10 | 11 | class SOUN 12 | { 13 | private: 14 | SOU *_sou; 15 | public: 16 | SOUN(Midi *midi); 17 | uint32_t getSize(); 18 | void write(fstream &f); 19 | ~SOUN(); 20 | }; 21 | 22 | #endif 23 | -------------------------------------------------------------------------------- /src/util/Makefile.am: -------------------------------------------------------------------------------- 1 | noinst_LTLIBRARIES = libutil.la 2 | libutil_la_SOURCES = BMPFile.cpp BMPFile.hpp \ 3 | IO.cpp IO.hpp \ 4 | Log.cpp Log.hpp \ 5 | MIDFile.cpp MIDFile.hpp \ 6 | WAVFile.cpp WAVFile.hpp \ 7 | XMLFile.cpp XMLFile.hpp 8 | libutil_la_CPPFLAGS = -I$(top_srcdir)/src @XML_CFLAGS@ 9 | -------------------------------------------------------------------------------- /src/blocks/GMD.hpp: -------------------------------------------------------------------------------- 1 | #ifndef _GMD_BLOCK_HPP_ 2 | #define _GMD_BLOCK_HPP_ 3 | 4 | #include 5 | #include 6 | #include 7 | using namespace std; 8 | 9 | class Midi; 10 | 11 | class GMD 12 | { 13 | private: 14 | vector _dataBytes; 15 | public: 16 | GMD(Midi *midi); 17 | uint32_t getSize(); 18 | void write(fstream &f); 19 | ~GMD(); 20 | }; 21 | 22 | #endif 23 | -------------------------------------------------------------------------------- /src/blocks/OBNA.hpp: -------------------------------------------------------------------------------- 1 | #ifndef _OBNA_BLOCK_HPP_ 2 | #define _OBNA_BLOCK_HPP_ 3 | 4 | #include 5 | #include 6 | #include 7 | using namespace std; 8 | 9 | class Object; 10 | 11 | class OBNA 12 | { 13 | private: 14 | string _name; 15 | public: 16 | OBNA(Object *object); 17 | uint32_t getSize(); 18 | void write(fstream &f); 19 | ~OBNA(); 20 | }; 21 | 22 | #endif 23 | 24 | -------------------------------------------------------------------------------- /src/blocks/VCTL.hpp: -------------------------------------------------------------------------------- 1 | #ifndef _VCTL_BLOCK_HPP_ 2 | #define _VCTL_BLOCK_HPP_ 3 | 4 | #include 5 | #include 6 | #include 7 | using namespace std; 8 | 9 | class Voice; 10 | 11 | class VCTL 12 | { 13 | private: 14 | vector _syncTimes; 15 | public: 16 | VCTL(Voice *voice); 17 | uint32_t getSize(); 18 | void write(fstream &f); 19 | ~VCTL(); 20 | }; 21 | 22 | #endif 23 | 24 | -------------------------------------------------------------------------------- /src/blocks/ENCD.hpp: -------------------------------------------------------------------------------- 1 | #ifndef _ENCD_BLOCK_HPP_ 2 | #define _ENCD_BLOCK_HPP_ 3 | 4 | #include 5 | #include 6 | #include 7 | using namespace std; 8 | 9 | class Function; 10 | 11 | class ENCD 12 | { 13 | private: 14 | vector _bytes; 15 | public: 16 | ENCD(Function *function); 17 | uint32_t getSize(); 18 | void write(fstream &f); 19 | ~ENCD(); 20 | }; 21 | 22 | #endif 23 | 24 | -------------------------------------------------------------------------------- /src/blocks/EXCD.hpp: -------------------------------------------------------------------------------- 1 | #ifndef _EXCD_BLOCK_HPP_ 2 | #define _EXCD_BLOCK_HPP_ 3 | 4 | #include 5 | #include 6 | #include 7 | using namespace std; 8 | 9 | class Function; 10 | 11 | class EXCD 12 | { 13 | private: 14 | vector _bytes; 15 | public: 16 | EXCD(Function *function); 17 | uint32_t getSize(); 18 | void write(fstream &f); 19 | ~EXCD(); 20 | }; 21 | 22 | #endif 23 | 24 | -------------------------------------------------------------------------------- /src/blocks/OFFS.hpp: -------------------------------------------------------------------------------- 1 | #ifndef _OFFS_BLOCK_HPP_ 2 | #define _OFFS_BLOCK_HPP_ 3 | 4 | #include 5 | #include 6 | #include 7 | using namespace std; 8 | 9 | class APAL; 10 | 11 | class OFFS 12 | { 13 | private: 14 | vector _offsets; 15 | public: 16 | OFFS(vector apals); 17 | uint32_t getSize(); 18 | void write(fstream &f); 19 | ~OFFS(); 20 | }; 21 | 22 | #endif 23 | 24 | -------------------------------------------------------------------------------- /src/blocks/VERB.hpp: -------------------------------------------------------------------------------- 1 | #ifndef _VERB_BLOCK_HPP_ 2 | #define _VERB_BLOCK_HPP_ 3 | 4 | #include 5 | #include 6 | #include 7 | using namespace std; 8 | 9 | class Function; 10 | 11 | class VERB 12 | { 13 | private: 14 | vector _bytes; 15 | public: 16 | VERB(Function *function); 17 | uint32_t getSize(); 18 | void write(fstream &f); 19 | ~VERB(); 20 | }; 21 | 22 | #endif 23 | 24 | -------------------------------------------------------------------------------- /src/blocks/RMIM.hpp: -------------------------------------------------------------------------------- 1 | #ifndef _RMIM_BLOCK_HPP_ 2 | #define _RMIM_BLOCK_HPP_ 3 | 4 | #include 5 | #include 6 | using namespace std; 7 | 8 | class Image; 9 | class RMIH; 10 | class IMxx; 11 | 12 | class RMIM 13 | { 14 | private: 15 | RMIH *_rmih; 16 | IMxx *_im00; 17 | public: 18 | RMIM(Image *roomImage); 19 | uint32_t getSize(); 20 | void write(fstream &f); 21 | ~RMIM(); 22 | }; 23 | 24 | #endif 25 | 26 | -------------------------------------------------------------------------------- /src/blocks/LSCR.hpp: -------------------------------------------------------------------------------- 1 | #ifndef _LSCR_BLOCK_HPP_ 2 | #define _LSCR_BLOCK_HPP_ 3 | 4 | #include 5 | #include 6 | #include 7 | using namespace std; 8 | 9 | class Function; 10 | 11 | class LSCR 12 | { 13 | private: 14 | uint8_t _id; 15 | vector _bytes; 16 | public: 17 | LSCR(Function *function); 18 | uint32_t getSize(); 19 | void write(fstream &f); 20 | ~LSCR(); 21 | }; 22 | 23 | #endif 24 | 25 | -------------------------------------------------------------------------------- /src/blocks/RMHD.hpp: -------------------------------------------------------------------------------- 1 | #ifndef _RMHD_BLOCK_HPP_ 2 | #define _RMHD_BLOCK_HPP_ 3 | 4 | #include 5 | #include 6 | using namespace std; 7 | 8 | class Game; 9 | 10 | class RMHD 11 | { 12 | private: 13 | uint16_t _width; 14 | uint16_t _height; 15 | uint16_t _nObjects; 16 | public: 17 | RMHD(Game *game, uint8_t roomIndex); 18 | uint32_t getSize(); 19 | void write(fstream &f); 20 | ~RMHD(); 21 | }; 22 | 23 | #endif 24 | -------------------------------------------------------------------------------- /src/blocks/SCRP.hpp: -------------------------------------------------------------------------------- 1 | #ifndef _SCRP_BLOCK_HPP_ 2 | #define _SCRP_BLOCK_HPP_ 3 | 4 | #include 5 | #include 6 | #include 7 | using namespace std; 8 | 9 | class Function; 10 | 11 | class SCRP 12 | { 13 | private: 14 | uint32_t _size; 15 | vector _bytes; 16 | public: 17 | SCRP(Function *function); 18 | uint32_t getSize(); 19 | void write(fstream &f); 20 | ~SCRP(); 21 | }; 22 | 23 | #endif 24 | 25 | -------------------------------------------------------------------------------- /src/blocks/PALS.hpp: -------------------------------------------------------------------------------- 1 | #ifndef _PALS_BLOCK_HPP_ 2 | #define _PALS_BLOCK_HPP_ 3 | 4 | #include 5 | #include 6 | #include 7 | using namespace std; 8 | 9 | class Palette; 10 | class WRAP; 11 | 12 | class PALS 13 | { 14 | private: 15 | WRAP *_wrap; 16 | public: 17 | PALS(Palette *globalPalette, Palette *localPalette); 18 | uint32_t getSize(); 19 | void write(fstream &f); 20 | ~PALS(); 21 | }; 22 | 23 | #endif 24 | 25 | -------------------------------------------------------------------------------- /src/blocks/OBIM.hpp: -------------------------------------------------------------------------------- 1 | #ifndef _OBIM_BLOCK_HPP_ 2 | #define _OBIM_BLOCK_HPP_ 3 | 4 | #include 5 | #include 6 | #include 7 | using namespace std; 8 | 9 | class Object; 10 | class IMHD; 11 | class IMxx; 12 | 13 | class OBIM 14 | { 15 | private: 16 | IMHD *_imhd; 17 | vector _imxxs; 18 | public: 19 | OBIM(Object *object); 20 | uint32_t getSize(); 21 | void write(fstream &f); 22 | ~OBIM(); 23 | }; 24 | 25 | #endif 26 | 27 | -------------------------------------------------------------------------------- /src/blocks/DCHR.hpp: -------------------------------------------------------------------------------- 1 | #ifndef _DCHR_BLOCK_HPP_ 2 | #define _DCHR_BLOCK_HPP_ 3 | 4 | #include 5 | #include 6 | #include 7 | using namespace std; 8 | 9 | class LFLF; 10 | 11 | class DCHR 12 | { 13 | private: 14 | uint16_t _nItems; 15 | vector _ids; 16 | vector _offsets; 17 | 18 | uint32_t getSize(); 19 | public: 20 | DCHR(LFLF *lflf); 21 | void write(fstream &f); 22 | ~DCHR(); 23 | }; 24 | 25 | #endif 26 | 27 | -------------------------------------------------------------------------------- /src/blocks/DROO.hpp: -------------------------------------------------------------------------------- 1 | #ifndef _DROO_BLOCK_HPP_ 2 | #define _DROO_BLOCK_HPP_ 3 | 4 | #include 5 | #include 6 | #include 7 | using namespace std; 8 | 9 | class Game; 10 | 11 | class DROO 12 | { 13 | private: 14 | uint16_t _nItems; 15 | vector _ids; 16 | vector _offsets; 17 | 18 | uint32_t getSize(); 19 | public: 20 | DROO(Game *game); 21 | void write(fstream &f); 22 | ~DROO(); 23 | }; 24 | 25 | #endif 26 | 27 | -------------------------------------------------------------------------------- /src/blocks/DSCR.hpp: -------------------------------------------------------------------------------- 1 | #ifndef _DSCR_BLOCK_HPP_ 2 | #define _DSCR_BLOCK_HPP_ 3 | 4 | #include 5 | #include 6 | #include 7 | using namespace std; 8 | 9 | class LFLF; 10 | 11 | class DSCR 12 | { 13 | private: 14 | uint16_t _nItems; 15 | vector _ids; 16 | vector _offsets; 17 | 18 | uint32_t getSize(); 19 | public: 20 | DSCR(LFLF *lflf); 21 | void write(fstream &f); 22 | ~DSCR(); 23 | }; 24 | 25 | #endif 26 | 27 | -------------------------------------------------------------------------------- /src/grammar/Declaration.cpp: -------------------------------------------------------------------------------- 1 | #include "Declaration.hpp" 2 | 3 | Declaration::Declaration(DeclarationType type, string name) 4 | { 5 | _type = type; 6 | _name = name; 7 | _fixedAddress = false; 8 | } 9 | 10 | Declaration::Declaration(DeclarationType type, string name, uint32_t value) 11 | { 12 | _type = type; 13 | _name = name; 14 | _value = value; 15 | _fixedAddress = (type == DECLARATION_VAR); 16 | } 17 | 18 | Declaration::~Declaration() 19 | { 20 | } 21 | -------------------------------------------------------------------------------- /src/blocks/BOXM.hpp: -------------------------------------------------------------------------------- 1 | #ifndef _BOXM_BLOCK_HPP_ 2 | #define _BOXM_BLOCK_HPP_ 3 | 4 | #include 5 | #include 6 | #include 7 | using namespace std; 8 | 9 | class BOXM 10 | { 11 | private: 12 | static const uint8_t BOX_END; 13 | 14 | vector > _from; 15 | vector > _to; 16 | vector > _dests; 17 | public: 18 | BOXM(); 19 | uint32_t getSize(); 20 | void write(fstream &f); 21 | ~BOXM(); 22 | }; 23 | 24 | #endif 25 | -------------------------------------------------------------------------------- /src/blocks/OBCD.hpp: -------------------------------------------------------------------------------- 1 | #ifndef _OBCD_BLOCK_HPP_ 2 | #define _OBCD_BLOCK_HPP_ 3 | 4 | #include 5 | #include 6 | #include 7 | using namespace std; 8 | 9 | class Object; 10 | class CDHD; 11 | class VERB; 12 | class OBNA; 13 | 14 | class OBCD 15 | { 16 | private: 17 | CDHD *_cdhd; 18 | VERB *_verb; 19 | OBNA *_obna; 20 | public: 21 | OBCD(Object *object); 22 | uint32_t getSize(); 23 | void write(fstream &f); 24 | ~OBCD(); 25 | }; 26 | 27 | #endif 28 | 29 | -------------------------------------------------------------------------------- /src/blocks/SOU2.hpp: -------------------------------------------------------------------------------- 1 | #ifndef _SOU2_BLOCK_HPP_ 2 | #define _SOU2_BLOCK_HPP_ 3 | 4 | #include 5 | #include 6 | #include 7 | using namespace std; 8 | 9 | class Game; 10 | class VCTL; 11 | class VOC; 12 | 13 | class SOU2 14 | { 15 | private: 16 | uint16_t _nVoices; 17 | vector _vctls; 18 | vector _vocs; 19 | public: 20 | SOU2(Game *game); 21 | uint32_t getSize(); 22 | void write(fstream &f); 23 | ~SOU2(); 24 | }; 25 | 26 | #endif 27 | 28 | -------------------------------------------------------------------------------- /src/util/MIDFile.hpp: -------------------------------------------------------------------------------- 1 | #ifndef _MIDFILE_HPP_ 2 | #define _MIDFILE_HPP_ 3 | 4 | #include 5 | #include 6 | #include 7 | using namespace std; 8 | 9 | class MIDFile 10 | { 11 | private: 12 | vector _dataBytes; 13 | public: 14 | MIDFile(); 15 | bool open(string fileName); 16 | uint32_t getNumberOfDataBytes() { return _dataBytes.size(); } 17 | uint8_t getDataByte(uint32_t index) { return _dataBytes[index]; } 18 | ~MIDFile(); 19 | }; 20 | 21 | #endif 22 | -------------------------------------------------------------------------------- /src/blocks/AARY.hpp: -------------------------------------------------------------------------------- 1 | #ifndef _AARY_BLOCK_HPP_ 2 | #define _AARY_BLOCK_HPP_ 3 | 4 | #include 5 | #include 6 | #include 7 | using namespace std; 8 | 9 | class Game; 10 | 11 | class AARY 12 | { 13 | private: 14 | vector _varNumbers; 15 | vector _dimAs; 16 | vector _dimBs; 17 | vector _types; 18 | public: 19 | AARY(Game *game); 20 | uint32_t getSize(); 21 | void write(fstream &f); 22 | ~AARY(); 23 | }; 24 | 25 | #endif 26 | -------------------------------------------------------------------------------- /src/blocks/APAL.hpp: -------------------------------------------------------------------------------- 1 | #ifndef _APAL_BLOCK_HPP_ 2 | #define _APAL_BLOCK_HPP_ 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include "util/BMPFile.hpp" 9 | using namespace std; 10 | 11 | class Palette; 12 | 13 | class APAL 14 | { 15 | private: 16 | vector _colors; 17 | public: 18 | APAL(Palette *globalPalette, Palette *localPalette); 19 | uint32_t getSize(); 20 | void write(fstream &f); 21 | ~APAL(); 22 | }; 23 | 24 | #endif 25 | 26 | -------------------------------------------------------------------------------- /src/blocks/DCOS.hpp: -------------------------------------------------------------------------------- 1 | #ifndef _DCOS_BLOCK_HPP_ 2 | #define _DCOS_BLOCK_HPP_ 3 | 4 | #include 5 | #include 6 | #include 7 | using namespace std; 8 | 9 | class Game; 10 | class LECF; 11 | 12 | class DCOS 13 | { 14 | private: 15 | uint16_t _nItems; 16 | vector _ids; 17 | vector _offsets; 18 | 19 | uint32_t getSize(); 20 | public: 21 | DCOS(Game *game, LECF *lecf); 22 | void write(fstream &f); 23 | ~DCOS(); 24 | }; 25 | 26 | #endif 27 | 28 | -------------------------------------------------------------------------------- /src/blocks/DSOU.hpp: -------------------------------------------------------------------------------- 1 | #ifndef _DSOU_BLOCK_HPP_ 2 | #define _DSOU_BLOCK_HPP_ 3 | 4 | #include 5 | #include 6 | #include 7 | using namespace std; 8 | 9 | class Game; 10 | class LECF; 11 | 12 | class DSOU 13 | { 14 | private: 15 | uint16_t _nItems; 16 | vector _ids; 17 | vector _offsets; 18 | 19 | uint32_t getSize(); 20 | public: 21 | DSOU(Game *game, LECF *lecf); 22 | void write(fstream &f); 23 | ~DSOU(); 24 | }; 25 | 26 | #endif 27 | 28 | -------------------------------------------------------------------------------- /src/blocks/IMxx.hpp: -------------------------------------------------------------------------------- 1 | #ifndef _IMXX_BLOCK_HPP_ 2 | #define _IMXX_BLOCK_HPP_ 3 | 4 | #include 5 | #include 6 | #include 7 | using namespace std; 8 | 9 | class Image; 10 | class SMAP; 11 | class ZPxx; 12 | 13 | class IMxx 14 | { 15 | private: 16 | uint8_t _index; 17 | SMAP *_smap; 18 | vector _zpxxs; 19 | public: 20 | IMxx(Image *image, uint8_t index); 21 | uint32_t getSize(); 22 | void write(fstream &f); 23 | ~IMxx(); 24 | }; 25 | 26 | #endif 27 | 28 | -------------------------------------------------------------------------------- /src/blocks/WRAP.hpp: -------------------------------------------------------------------------------- 1 | #ifndef _WRAP_BLOCK_HPP_ 2 | #define _WRAP_BLOCK_HPP_ 3 | 4 | #include 5 | #include 6 | #include 7 | using namespace std; 8 | 9 | class Palette; 10 | class OFFS; 11 | class APAL; 12 | 13 | class WRAP 14 | { 15 | private: 16 | OFFS *_offs; 17 | vector _apals; 18 | public: 19 | WRAP(Palette *globalPalette, Palette *localPalette); 20 | uint32_t getSize(); 21 | void write(fstream &f); 22 | ~WRAP(); 23 | }; 24 | 25 | #endif 26 | 27 | -------------------------------------------------------------------------------- /src/blocks/LOFF.hpp: -------------------------------------------------------------------------------- 1 | #ifndef _LOFF_BLOCK_HPP_ 2 | #define _LOFF_BLOCK_HPP_ 3 | 4 | #include 5 | #include 6 | #include 7 | using namespace std; 8 | 9 | class Game; 10 | class LFLF; 11 | 12 | class LOFF 13 | { 14 | private: 15 | uint8_t _nRooms; 16 | vector _roomIDs; 17 | vector _roomOffsets; 18 | public: 19 | LOFF(Game *game, vector lflfs); 20 | uint32_t getSize(); 21 | void write(fstream &f); 22 | ~LOFF(); 23 | }; 24 | 25 | #endif 26 | 27 | -------------------------------------------------------------------------------- /src/blocks/RNAM.hpp: -------------------------------------------------------------------------------- 1 | #ifndef _RNAM_BLOCK_HPP_ 2 | #define _RNAM_BLOCK_HPP_ 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | using namespace std; 9 | 10 | class Game; 11 | 12 | class RNAM 13 | { 14 | private: 15 | static const uint8_t N_CHARS; 16 | static const uint8_t XOR_VALUE; 17 | 18 | vector _roomIDs; 19 | vector _roomNames; 20 | 21 | uint32_t getSize(); 22 | public: 23 | RNAM(Game *game); 24 | void write(fstream &f); 25 | ~RNAM(); 26 | }; 27 | 28 | #endif 29 | -------------------------------------------------------------------------------- /src/blocks/ZPxx.hpp: -------------------------------------------------------------------------------- 1 | #ifndef _ZPxx_BLOCK_HPP_ 2 | #define _ZPxx_BLOCK_HPP_ 3 | 4 | #include 5 | #include 6 | #include 7 | using namespace std; 8 | 9 | class ZPxx 10 | { 11 | private: 12 | static const uint8_t STRIP_WIDTH; 13 | static const uint8_t MAX_BYTES; 14 | 15 | uint8_t _index; 16 | vector > _strips; 17 | vector _offsets; 18 | public: 19 | ZPxx(string filePath, uint8_t index); 20 | uint32_t getSize(); 21 | void write(fstream &f); 22 | ~ZPxx(); 23 | }; 24 | 25 | #endif 26 | 27 | -------------------------------------------------------------------------------- /src/blocks/DOBJ.hpp: -------------------------------------------------------------------------------- 1 | #ifndef _DOBJ_BLOCK_HPP_ 2 | #define _DOBJ_BLOCK_HPP_ 3 | 4 | #include 5 | #include 6 | #include 7 | using namespace std; 8 | 9 | class Game; 10 | 11 | class DOBJ 12 | { 13 | private: 14 | static const uint8_t OWNER_AND_STATE; 15 | static const uint32_t CLASS_DATA; 16 | 17 | uint16_t _nItems; 18 | vector _ownersAndStates; 19 | vector _classData; 20 | 21 | uint32_t getSize(); 22 | public: 23 | DOBJ(Game *game); 24 | void write(fstream &f); 25 | ~DOBJ(); 26 | }; 27 | 28 | #endif 29 | -------------------------------------------------------------------------------- /src/blocks/SOU.cpp: -------------------------------------------------------------------------------- 1 | #include "SOU.hpp" 2 | #include "util/IO.hpp" 3 | #include "GMD.hpp" 4 | 5 | SOU::SOU(Midi *midi) 6 | { 7 | _gmd = new GMD(midi); 8 | } 9 | 10 | uint32_t SOU::getSize() 11 | { 12 | uint32_t size = 0; 13 | size += 4 * sizeof(uint8_t); // identifier 14 | size += sizeof(uint32_t); // size 15 | size += _gmd->getSize(); // gmd 16 | return size; 17 | } 18 | 19 | void SOU::write(fstream &f) 20 | { 21 | IO::writeString(f, "SOU "); 22 | IO::writeU32BE(f, getSize()); 23 | _gmd->write(f); 24 | } 25 | 26 | SOU::~SOU() 27 | { 28 | delete _gmd; 29 | } 30 | -------------------------------------------------------------------------------- /src/util/WAVFile.hpp: -------------------------------------------------------------------------------- 1 | #ifndef _WAVFILE_HPP_ 2 | #define _WAVFILE_HPP_ 3 | 4 | #include 5 | #include 6 | #include 7 | using namespace std; 8 | 9 | class WAVFile 10 | { 11 | private: 12 | uint32_t _sampleRate; 13 | vector _dataBytes; 14 | public: 15 | WAVFile(); 16 | bool open(string fileName); 17 | uint32_t getSampleRate() { return _sampleRate; } 18 | uint32_t getNumberOfDataBytes() { return _dataBytes.size(); } 19 | uint8_t getDataByte(uint32_t index) { return _dataBytes[index]; } 20 | ~WAVFile(); 21 | }; 22 | 23 | #endif 24 | -------------------------------------------------------------------------------- /src/blocks/LECF.hpp: -------------------------------------------------------------------------------- 1 | #ifndef _LECF_BLOCK_HPP_ 2 | #define _LECF_BLOCK_HPP_ 3 | 4 | #include 5 | #include 6 | #include 7 | using namespace std; 8 | 9 | class Game; 10 | class LOFF; 11 | class LFLF; 12 | 13 | class LECF 14 | { 15 | private: 16 | LOFF *_loff; 17 | vector _lflfs; 18 | 19 | uint32_t getSize(); 20 | public: 21 | LECF(Game *game); 22 | uint8_t getNumberOfLFLFs() { return _lflfs.size(); } 23 | LFLF *getLFLF(uint8_t index) { return _lflfs[index]; } 24 | void write(fstream &f); 25 | ~LECF(); 26 | }; 27 | 28 | #endif 29 | 30 | -------------------------------------------------------------------------------- /src/blocks/SOUN.cpp: -------------------------------------------------------------------------------- 1 | #include "SOUN.hpp" 2 | #include "util/IO.hpp" 3 | #include "SOU.hpp" 4 | 5 | SOUN::SOUN(Midi *midi) 6 | { 7 | _sou = new SOU(midi); 8 | } 9 | 10 | uint32_t SOUN::getSize() 11 | { 12 | uint32_t size = 0; 13 | size += 4 * sizeof(uint8_t); // identifier 14 | size += sizeof(uint32_t); // size 15 | size += _sou->getSize(); // sou 16 | return size; 17 | } 18 | 19 | void SOUN::write(fstream &f) 20 | { 21 | IO::writeString(f, "SOUN"); 22 | IO::writeU32BE(f, getSize()); 23 | _sou->write(f); 24 | } 25 | 26 | SOUN::~SOUN() 27 | { 28 | delete _sou; 29 | } 30 | -------------------------------------------------------------------------------- /src/types/Midi.hpp: -------------------------------------------------------------------------------- 1 | #ifndef _MIDI_HPP_ 2 | #define _MIDI_HPP_ 3 | 4 | #include 5 | #include 6 | using namespace std; 7 | 8 | class Midi 9 | { 10 | private: 11 | static const string XML_FILE_NAME; 12 | 13 | uint16_t _id; 14 | string _name; 15 | string _midiPath; 16 | public: 17 | Midi(); 18 | void load(string dirPath); 19 | void save(string dirPath); 20 | uint16_t getID() { return _id; } 21 | void setID(uint16_t id) { _id = id; } 22 | string getName() { return _name; } 23 | string getMidiPath() { return _midiPath; } 24 | ~Midi(); 25 | }; 26 | 27 | #endif 28 | -------------------------------------------------------------------------------- /src/blocks/SCAL.hpp: -------------------------------------------------------------------------------- 1 | #ifndef _SCAL_BLOCK_HPP_ 2 | #define _SCAL_BLOCK_HPP_ 3 | 4 | #include 5 | #include 6 | #include 7 | using namespace std; 8 | 9 | class Map; 10 | 11 | class SCAL 12 | { 13 | private: 14 | static const uint8_t DEFAULT_SCALE; 15 | static const uint8_t DEFAULT_Y1; 16 | static const uint8_t DEFAULT_Y2; 17 | 18 | vector _s1s; 19 | vector _y1s; 20 | vector _s2s; 21 | vector _y2s; 22 | public: 23 | SCAL(Map *map); 24 | uint32_t getSize(); 25 | void write(fstream &f); 26 | ~SCAL(); 27 | }; 28 | 29 | #endif 30 | -------------------------------------------------------------------------------- /src/blocks/RMIH.cpp: -------------------------------------------------------------------------------- 1 | #include "RMIH.hpp" 2 | #include "util/IO.hpp" 3 | #include "types/Image.hpp" 4 | 5 | RMIH::RMIH(Image *image) 6 | { 7 | _nZPlanes = image->getNumberOfZPlanePaths(); 8 | } 9 | 10 | uint32_t RMIH::getSize() 11 | { 12 | uint32_t size = 0; 13 | size += 4 * sizeof(uint8_t); // identifier 14 | size += sizeof(uint32_t); // size 15 | size += sizeof(uint16_t); // nZPlanes 16 | return size; 17 | } 18 | 19 | void RMIH::write(fstream &f) 20 | { 21 | IO::writeString(f, "RMIH"); 22 | IO::writeU32BE(f, getSize()); 23 | IO::writeU16LE(f, _nZPlanes); 24 | } 25 | 26 | RMIH::~RMIH() 27 | { 28 | } 29 | -------------------------------------------------------------------------------- /src/blocks/CDHD.hpp: -------------------------------------------------------------------------------- 1 | #ifndef _CDHD_BLOCK_HPP_ 2 | #define _CDHD_BLOCK_HPP_ 3 | 4 | #include 5 | #include 6 | using namespace std; 7 | 8 | class Object; 9 | 10 | class CDHD 11 | { 12 | private: 13 | static const uint16_t UNKNOWN_1; 14 | static const uint16_t UNKNOWN_2; 15 | static const uint8_t FLAGS; 16 | static const uint8_t PARENT; 17 | 18 | uint16_t _id; 19 | uint16_t _x; 20 | uint16_t _y; 21 | uint16_t _width; 22 | uint16_t _height; 23 | uint8_t _actorDir; 24 | public: 25 | CDHD(Object *object); 26 | uint32_t getSize(); 27 | void write(fstream &f); 28 | ~CDHD(); 29 | }; 30 | 31 | #endif 32 | -------------------------------------------------------------------------------- /src/blocks/SMAP.hpp: -------------------------------------------------------------------------------- 1 | #ifndef _SMAP_BLOCK_HPP_ 2 | #define _SMAP_BLOCK_HPP_ 3 | 4 | #include 5 | #include 6 | #include 7 | using namespace std; 8 | 9 | class Image; 10 | 11 | class SMAP 12 | { 13 | private: 14 | static const uint8_t STRIP_WIDTH; 15 | static const uint8_t CID_NO_COMPRESSION_OPAQUE; 16 | static const uint8_t CID_NO_COMPRESSION_TRANSPARENT; 17 | 18 | uint16_t _height; 19 | vector > _strips; 20 | vector _offsets; 21 | public: 22 | SMAP(Image *image); 23 | uint32_t getSize(); 24 | void write(fstream &f); 25 | ~SMAP(); 26 | }; 27 | 28 | #endif 29 | 30 | -------------------------------------------------------------------------------- /src/util/Log.hpp: -------------------------------------------------------------------------------- 1 | #ifndef _LOG_HPP_ 2 | #define _LOG_HPP_ 3 | 4 | #include 5 | #include 6 | #include 7 | using namespace std; 8 | 9 | typedef enum 10 | { 11 | LOG_INFO, 12 | LOG_WARNING, 13 | LOG_ERROR 14 | } LogType; 15 | 16 | class Log 17 | { 18 | private: 19 | static const uint8_t INDENT_WIDTH; 20 | 21 | static uint8_t _indent; 22 | static ofstream _output; 23 | public: 24 | static void reset(); 25 | static void indent() { _indent++; } 26 | static void unIndent() { _indent--; } 27 | static void write(LogType type, const char *s, ...); 28 | static void close(); 29 | }; 30 | 31 | #endif 32 | -------------------------------------------------------------------------------- /src/grammar/Makefile.am: -------------------------------------------------------------------------------- 1 | BUILT_SOURCES = parser.hh 2 | AM_YFLAGS = -d 3 | AM_LFLAGS = -o$(LEX_OUTPUT_ROOT).c 4 | 5 | noinst_LTLIBRARIES = libgrammar.la 6 | libgrammar_la_SOURCES = Context.cpp Context.hpp \ 7 | Declaration.cpp Declaration.hpp \ 8 | Expression.cpp Expression.hpp \ 9 | Function.cpp Function.hpp \ 10 | Instruction.cpp Instruction.hpp \ 11 | lexer.ll \ 12 | parser.yy \ 13 | Statement.cpp Statement.hpp 14 | libgrammar_la_CPPFLAGS = -I$(top_srcdir)/src @XML_CFLAGS@ 15 | -------------------------------------------------------------------------------- /src/types/Makefile.am: -------------------------------------------------------------------------------- 1 | noinst_LTLIBRARIES = libtypes.la 2 | libtypes_la_SOURCES = Charset.cpp Charset.hpp \ 3 | Costume.cpp Costume.hpp \ 4 | Game.cpp Game.hpp \ 5 | Image.cpp Image.hpp \ 6 | Map.cpp Map.hpp \ 7 | Midi.cpp Midi.hpp \ 8 | Object.cpp Object.hpp \ 9 | Palette.cpp Palette.hpp \ 10 | Room.cpp Room.hpp \ 11 | Script.cpp Script.hpp \ 12 | Voice.cpp Voice.hpp 13 | libtypes_la_CPPFLAGS = -I$(top_srcdir)/src @XML_CFLAGS@ 14 | -------------------------------------------------------------------------------- /src/blocks/PALS.cpp: -------------------------------------------------------------------------------- 1 | #include "PALS.hpp" 2 | #include "util/IO.hpp" 3 | #include "WRAP.hpp" 4 | 5 | PALS::PALS(Palette *globalPalette, Palette *localPalette) 6 | { 7 | _wrap = new WRAP(globalPalette, localPalette); 8 | } 9 | 10 | uint32_t PALS::getSize() 11 | { 12 | uint32_t size = 0; 13 | size += 4 * sizeof(uint8_t); // identifier 14 | size += sizeof(uint32_t); // size 15 | size += _wrap->getSize(); // wrap 16 | return size; 17 | } 18 | 19 | void PALS::write(fstream &f) 20 | { 21 | IO::writeString(f, "PALS"); 22 | IO::writeU32BE(f, getSize()); 23 | _wrap->write(f); 24 | } 25 | 26 | PALS::~PALS() 27 | { 28 | delete _wrap; 29 | } 30 | 31 | -------------------------------------------------------------------------------- /src/blocks/VOC.hpp: -------------------------------------------------------------------------------- 1 | #ifndef _VOC_BLOCK_HPP_ 2 | #define _VOC_BLOCK_HPP_ 3 | 4 | #include 5 | #include 6 | #include 7 | using namespace std; 8 | 9 | class Voice; 10 | 11 | class VOC 12 | { 13 | private: 14 | static const int HEADER_SIZE; 15 | static const int FILE_VERSION; 16 | static const int MAGIC_NUMBER; 17 | static const int TERMINATOR_BLOCK_ID; 18 | static const int SOUND_DATA_BLOCK_ID; 19 | static const int PCM_CODEC_ID; 20 | 21 | uint8_t _freqDivisor; 22 | vector _dataBytes; 23 | public: 24 | VOC(Voice *voice); 25 | uint32_t getSize(); 26 | void write(fstream &f); 27 | ~VOC(); 28 | }; 29 | 30 | #endif 31 | 32 | -------------------------------------------------------------------------------- /src/blocks/OBNA.cpp: -------------------------------------------------------------------------------- 1 | #include "OBNA.hpp" 2 | #include "util/IO.hpp" 3 | #include "types/Object.hpp" 4 | 5 | OBNA::OBNA(Object *object) 6 | { 7 | _name = object->getDisplayName(); 8 | } 9 | 10 | uint32_t OBNA::getSize() 11 | { 12 | uint32_t size = 0; 13 | size += 4 * sizeof(uint8_t); // identifier 14 | size += sizeof(uint32_t); // size 15 | size += _name.length() * sizeof(uint8_t); // name 16 | size += sizeof(uint8_t); // 0 17 | return size; 18 | } 19 | 20 | void OBNA::write(fstream &f) 21 | { 22 | IO::writeString(f, "OBNA"); 23 | IO::writeU32BE(f, getSize()); 24 | IO::writeString(f, _name); 25 | IO::writeU8(f, 0); 26 | } 27 | 28 | OBNA::~OBNA() 29 | { 30 | } 31 | 32 | -------------------------------------------------------------------------------- /src/blocks/NLSC.cpp: -------------------------------------------------------------------------------- 1 | #include "NLSC.hpp" 2 | #include "util/IO.hpp" 3 | #include "types/Room.hpp" 4 | 5 | NLSC::NLSC(Room *room) 6 | { 7 | _nLocalScripts = room->getNumberOfFunctions(); 8 | } 9 | 10 | uint32_t NLSC::getSize() 11 | { 12 | uint32_t size = 0; 13 | size += 4 * sizeof(uint8_t); // identifier 14 | size += sizeof(uint32_t); // size 15 | size += sizeof(uint8_t); // nLocalScripts 16 | size += sizeof(uint8_t); // 0 17 | return size; 18 | } 19 | 20 | void NLSC::write(fstream &f) 21 | { 22 | IO::writeString(f, "NLSC"); 23 | IO::writeU32BE(f, getSize()); 24 | IO::writeU8(f, _nLocalScripts); 25 | IO::writeU8(f, 0); 26 | } 27 | 28 | NLSC::~NLSC() 29 | { 30 | } 31 | 32 | -------------------------------------------------------------------------------- /src/blocks/IMHD.hpp: -------------------------------------------------------------------------------- 1 | #ifndef _IMHD_BLOCK_HPP_ 2 | #define _IMHD_BLOCK_HPP_ 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | using namespace std; 9 | 10 | class Object; 11 | 12 | class IMHD 13 | { 14 | private: 15 | static const uint16_t UNKNOWN; 16 | static const uint16_t X; 17 | static const uint16_t Y; 18 | 19 | uint16_t _id; 20 | uint16_t _nImages; 21 | uint32_t _nZPlanesPerImage; 22 | uint16_t _width; 23 | uint16_t _height; 24 | vector _hotspotXs; 25 | vector _hotspotYs; 26 | public: 27 | IMHD(Object *object); 28 | uint32_t getSize(); 29 | void write(fstream &f); 30 | ~IMHD(); 31 | }; 32 | 33 | #endif 34 | -------------------------------------------------------------------------------- /src/types/Script.hpp: -------------------------------------------------------------------------------- 1 | #ifndef _SCRIPT_HPP_ 2 | #define _SCRIPT_HPP_ 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | using namespace std; 9 | 10 | class Declaration; 11 | class Function; 12 | 13 | class Script 14 | { 15 | private: 16 | static const string XML_FILE_NAME; 17 | 18 | string _name; 19 | string _scriptPath; 20 | public: 21 | Script(string scriptPath = ""); 22 | void load(string dirPath); 23 | void save(string dirPath); 24 | void parse(vector &declarations, vector &functions); 25 | string getName() { return _name; } 26 | string getScriptPath() { return _scriptPath; } 27 | ~Script(); 28 | }; 29 | 30 | #endif 31 | -------------------------------------------------------------------------------- /src/blocks/CYCL.hpp: -------------------------------------------------------------------------------- 1 | #ifndef _CYCL_BLOCK_HPP_ 2 | #define _CYCL_BLOCK_HPP_ 3 | 4 | #include 5 | #include 6 | #include 7 | using namespace std; 8 | 9 | class Palette; 10 | 11 | class CYCL 12 | { 13 | private: 14 | static const uint16_t FREQUENCY; 15 | static const uint16_t FORWARD; 16 | static const uint16_t BACKWARD; 17 | static const uint16_t UNKNOWN; 18 | 19 | vector _ids; 20 | vector _freqs; 21 | vector _flags; 22 | vector _starts; 23 | vector _ends; 24 | public: 25 | CYCL(Palette *globalPalette, Palette *localPalette); 26 | uint32_t getSize(); 27 | void write(fstream &f); 28 | ~CYCL(); 29 | }; 30 | 31 | #endif 32 | 33 | -------------------------------------------------------------------------------- /src/blocks/ENCD.cpp: -------------------------------------------------------------------------------- 1 | #include "ENCD.hpp" 2 | #include "util/IO.hpp" 3 | #include "grammar/Function.hpp" 4 | 5 | ENCD::ENCD(Function *function) 6 | { 7 | for (int i = 0; i < function->getNumberOfBytes(); i++) 8 | _bytes.push_back(function->getByte(i)); 9 | } 10 | 11 | uint32_t ENCD::getSize() 12 | { 13 | uint32_t size = 0; 14 | size += 4 * sizeof(uint8_t); // identifier 15 | size += sizeof(uint32_t); // size 16 | size += _bytes.size() * sizeof(uint8_t); // bytes 17 | return size; 18 | } 19 | 20 | void ENCD::write(fstream &f) 21 | { 22 | IO::writeString(f, "ENCD"); 23 | IO::writeU32BE(f, getSize()); 24 | for (int i = 0; i < _bytes.size(); i++) 25 | IO::writeU8(f, _bytes[i]); 26 | } 27 | 28 | ENCD::~ENCD() 29 | { 30 | } 31 | 32 | -------------------------------------------------------------------------------- /src/blocks/EXCD.cpp: -------------------------------------------------------------------------------- 1 | #include "EXCD.hpp" 2 | #include "util/IO.hpp" 3 | #include "grammar/Function.hpp" 4 | 5 | EXCD::EXCD(Function *function) 6 | { 7 | for (int i = 0; i < function->getNumberOfBytes(); i++) 8 | _bytes.push_back(function->getByte(i)); 9 | } 10 | 11 | uint32_t EXCD::getSize() 12 | { 13 | uint32_t size = 0; 14 | size += 4 * sizeof(uint8_t); // identifier 15 | size += sizeof(uint32_t); // size 16 | size += _bytes.size() * sizeof(uint8_t); // bytes 17 | return size; 18 | } 19 | 20 | void EXCD::write(fstream &f) 21 | { 22 | IO::writeString(f, "EXCD"); 23 | IO::writeU32BE(f, getSize()); 24 | for (int i = 0; i < _bytes.size(); i++) 25 | IO::writeU8(f, _bytes[i]); 26 | } 27 | 28 | EXCD::~EXCD() 29 | { 30 | } 31 | 32 | -------------------------------------------------------------------------------- /src/blocks/SCRP.cpp: -------------------------------------------------------------------------------- 1 | #include "SCRP.hpp" 2 | #include "util/IO.hpp" 3 | #include "grammar/Function.hpp" 4 | 5 | SCRP::SCRP(Function *function) 6 | { 7 | for (int i = 0; i < function->getNumberOfBytes(); i++) 8 | _bytes.push_back(function->getByte(i)); 9 | } 10 | 11 | uint32_t SCRP::getSize() 12 | { 13 | uint32_t size = 0; 14 | size += 4 * sizeof(uint8_t); // identifier 15 | size += sizeof(uint32_t); // size 16 | size += _bytes.size() * sizeof(uint8_t); // bytes 17 | return size; 18 | } 19 | 20 | void SCRP::write(fstream &f) 21 | { 22 | IO::writeString(f, "SCRP"); 23 | IO::writeU32BE(f, getSize()); 24 | for (int i = 0; i < _bytes.size(); i++) 25 | IO::writeU8(f, _bytes[i]); 26 | } 27 | 28 | SCRP::~SCRP() 29 | { 30 | } 31 | 32 | -------------------------------------------------------------------------------- /src/blocks/VERB.cpp: -------------------------------------------------------------------------------- 1 | #include "VERB.hpp" 2 | #include "util/IO.hpp" 3 | #include "grammar/Function.hpp" 4 | 5 | VERB::VERB(Function *function) 6 | { 7 | for (int i = 0; i < function->getNumberOfBytes(); i++) 8 | _bytes.push_back(function->getByte(i)); 9 | } 10 | 11 | uint32_t VERB::getSize() 12 | { 13 | uint32_t size = 0; 14 | size += sizeof(uint32_t); // identifier 15 | size += sizeof(uint32_t); // size 16 | size += _bytes.size() * sizeof(uint8_t); // bytes 17 | return size; 18 | } 19 | 20 | void VERB::write(fstream &f) 21 | { 22 | IO::writeString(f, "VERB"); 23 | IO::writeU32BE(f, getSize()); 24 | for (int i = 0; i < _bytes.size(); i++) 25 | IO::writeU8(f, _bytes[i]); 26 | } 27 | 28 | VERB::~VERB() 29 | { 30 | } 31 | 32 | -------------------------------------------------------------------------------- /src/blocks/VCTL.cpp: -------------------------------------------------------------------------------- 1 | #include "VCTL.hpp" 2 | #include "util/IO.hpp" 3 | #include "types/Voice.hpp" 4 | 5 | VCTL::VCTL(Voice *voice) 6 | { 7 | for (int i = 0; i < voice->getNumberOfSyncTimes(); i++) 8 | _syncTimes.push_back(voice->getSyncTime(i)); 9 | } 10 | 11 | uint32_t VCTL::getSize() 12 | { 13 | uint32_t size = 0; 14 | size += 4 * sizeof(uint8_t); // identifier 15 | size += sizeof(uint32_t); // size 16 | size += _syncTimes.size() * sizeof(uint16_t); // syncTimes 17 | return size; 18 | } 19 | 20 | void VCTL::write(fstream &f) 21 | { 22 | IO::writeString(f, "VCTL"); 23 | IO::writeU32BE(f, getSize()); 24 | for (int i = 0; i < _syncTimes.size(); i++) 25 | IO::writeU16BE(f, _syncTimes[i]); 26 | } 27 | 28 | VCTL::~VCTL() 29 | { 30 | } 31 | -------------------------------------------------------------------------------- /src/blocks/RMIM.cpp: -------------------------------------------------------------------------------- 1 | #include "RMIM.hpp" 2 | #include "util/IO.hpp" 3 | #include "types/Image.hpp" 4 | #include "RMIH.hpp" 5 | #include "IMxx.hpp" 6 | 7 | RMIM::RMIM(Image *image) 8 | { 9 | _rmih = new RMIH(image); 10 | _im00 = new IMxx(image, 0); 11 | } 12 | 13 | uint32_t RMIM::getSize() 14 | { 15 | uint32_t size = 0; 16 | size += 4 * sizeof(uint8_t); // identifier 17 | size += sizeof(uint32_t); // size 18 | size += _rmih->getSize(); // rmih 19 | size += _im00->getSize(); // im00 20 | return size; 21 | } 22 | 23 | void RMIM::write(fstream &f) 24 | { 25 | IO::writeString(f, "RMIM"); 26 | IO::writeU32BE(f, getSize()); 27 | _rmih->write(f); 28 | _im00->write(f); 29 | } 30 | 31 | RMIM::~RMIM() 32 | { 33 | delete _rmih; 34 | delete _im00; 35 | } 36 | 37 | -------------------------------------------------------------------------------- /src/blocks/TRNS.cpp: -------------------------------------------------------------------------------- 1 | #include "TRNS.hpp" 2 | #include "util/IO.hpp" 3 | 4 | const uint8_t TRNS::TRANSPARENT_INDEX = 0; 5 | 6 | TRNS::TRNS() 7 | { 8 | } 9 | 10 | uint32_t TRNS::getSize() 11 | { 12 | uint32_t size = 0; 13 | size += 4 * sizeof(uint8_t); // identifier 14 | size += sizeof(uint32_t); // size 15 | size += sizeof(uint8_t); // transparentIndex 16 | size += sizeof(uint8_t); // 0 17 | return size; 18 | } 19 | 20 | void TRNS::write(fstream &f) 21 | { 22 | // Identifier 23 | IO::writeString(f, "TRNS"); 24 | 25 | // Block size 26 | IO::writeU32BE(f, getSize()); 27 | 28 | // Transparent index 29 | IO::writeU8(f, TRANSPARENT_INDEX); 30 | 31 | // End the block with 0 32 | IO::writeU8(f, 0); 33 | } 34 | 35 | TRNS::~TRNS() 36 | { 37 | } 38 | 39 | -------------------------------------------------------------------------------- /src/blocks/BOXD.hpp: -------------------------------------------------------------------------------- 1 | #ifndef _BOXD_BLOCK_HPP_ 2 | #define _BOXD_BLOCK_HPP_ 3 | 4 | #include 5 | #include 6 | #include 7 | using namespace std; 8 | 9 | class Map; 10 | 11 | class BOXD 12 | { 13 | private: 14 | static const uint16_t FAKE_VALUE; 15 | static const uint8_t FAKE_MASK; 16 | static const uint8_t FAKE_FLAGS; 17 | static const uint8_t FAKE_SCALE; 18 | 19 | uint8_t _nBoxes; 20 | vector _ulxs, _ulys; 21 | vector _urxs, _urys; 22 | vector _lrxs, _lrys; 23 | vector _llxs, _llys; 24 | vector _masks; 25 | vector _flags; 26 | vector _scales; 27 | public: 28 | BOXD(Map *map); 29 | uint32_t getSize(); 30 | void write(fstream &f); 31 | ~BOXD(); 32 | }; 33 | 34 | #endif 35 | 36 | -------------------------------------------------------------------------------- /src/types/Voice.hpp: -------------------------------------------------------------------------------- 1 | #ifndef _VOICE_HPP_ 2 | #define _VOICE_HPP_ 3 | 4 | #include 5 | #include 6 | #include 7 | using namespace std; 8 | 9 | class Voice 10 | { 11 | private: 12 | static const string XML_FILE_NAME; 13 | 14 | uint32_t _id; 15 | string _name; 16 | string _wavePath; 17 | vector _syncTimes; 18 | public: 19 | Voice(); 20 | void load(string dirPath); 21 | void save(string dirPath); 22 | uint32_t getID() { return _id; } 23 | void setID(uint32_t id) { _id = id; } 24 | string getName() { return _name; } 25 | string getWavePath() { return _wavePath; } 26 | uint8_t getNumberOfSyncTimes() { return _syncTimes.size(); } 27 | uint16_t getSyncTime(uint8_t index) { return _syncTimes[index]; } 28 | ~Voice(); 29 | }; 30 | 31 | #endif 32 | -------------------------------------------------------------------------------- /src/util/MIDFile.cpp: -------------------------------------------------------------------------------- 1 | #include "MIDFile.hpp" 2 | #include 3 | #include "IO.hpp" 4 | #include "Log.hpp" 5 | 6 | MIDFile::MIDFile() 7 | { 8 | } 9 | 10 | bool MIDFile::open(string fileName) 11 | { 12 | // We open the file 13 | fstream file(fileName.c_str(), ios::in | ios::binary); 14 | if (!file.is_open()) 15 | { 16 | Log::write(LOG_WARNING, "Could not open file \"%s\" !\n", fileName.c_str()); 17 | return false; 18 | } 19 | 20 | // This only works with MIDI format 2 21 | // TODO: convert format 1 to format 2 22 | file.seekg(0, ios::end); 23 | uint32_t fileSize = file.tellg(); 24 | file.seekp(0, ios::beg); 25 | for (int i = 0; i < fileSize; i++) 26 | _dataBytes.push_back(IO::readU8(file)); 27 | 28 | return true; 29 | } 30 | 31 | MIDFile::~MIDFile() 32 | { 33 | } 34 | -------------------------------------------------------------------------------- /src/blocks/GMD.cpp: -------------------------------------------------------------------------------- 1 | #include "GMD.hpp" 2 | #include "util/IO.hpp" 3 | #include "util/MIDFile.hpp" 4 | #include "types/Midi.hpp" 5 | 6 | GMD::GMD(Midi *midi) 7 | { 8 | MIDFile midFile; 9 | midFile.open(midi->getMidiPath()); 10 | for (int i = 0; i < midFile.getNumberOfDataBytes(); i++) 11 | _dataBytes.push_back(midFile.getDataByte(i)); 12 | } 13 | 14 | uint32_t GMD::getSize() 15 | { 16 | uint32_t size = 0; 17 | size += 4 * sizeof(uint8_t); // identifier 18 | size += sizeof(uint32_t); // size 19 | size += _dataBytes.size(); // data 20 | return size; 21 | } 22 | 23 | void GMD::write(fstream &f) 24 | { 25 | IO::writeString(f, "GMD "); 26 | IO::writeU32BE(f, getSize()); 27 | for (int i = 0; i < _dataBytes.size(); i++) 28 | IO::writeU8(f, _dataBytes[i]); 29 | } 30 | 31 | GMD::~GMD() 32 | { 33 | } 34 | -------------------------------------------------------------------------------- /src/libscumm/Sound.sgc: -------------------------------------------------------------------------------- 1 | inline function Sound_isRunning(var sound) 2 | { 3 | var running; 4 | asm 5 | { 6 | pushWordVar .word sound 7 | isSoundRunning 8 | writeWordVar .word running 9 | } 10 | return running; 11 | } 12 | 13 | // TODO 14 | inline function Sound_kludge() 15 | { 16 | } 17 | 18 | inline function Sound_startMusic(var music) 19 | { 20 | asm 21 | { 22 | pushWordVar .word music 23 | startMusic 24 | } 25 | } 26 | 27 | inline function Sound_stopMusic() 28 | { 29 | asm 30 | { 31 | stopMusic 32 | } 33 | } 34 | 35 | inline function Sound_startSound(var sound) 36 | { 37 | asm 38 | { 39 | pushWordVar .word sound 40 | startSound 41 | } 42 | } 43 | 44 | inline function Sound_stopSound(var sound) 45 | { 46 | asm 47 | { 48 | pushWordVar .word sound 49 | stopSound 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /configure.ac: -------------------------------------------------------------------------------- 1 | m4_define(scummgen_version_major, 0) 2 | m4_define(scummgen_version_minor, 1) 3 | m4_define(scummgen_version_micro, 0) 4 | 5 | AC_INIT([ScummGEN], scummgen_version_major.scummgen_version_minor.scummgen_version_micro) 6 | AC_CONFIG_AUX_DIR([build]) 7 | AM_INIT_AUTOMAKE([-Wall -Werror foreign]) 8 | 9 | AC_PROG_CXX 10 | AC_PROG_LEX 11 | AC_PROG_YACC 12 | AC_PROG_LIBTOOL 13 | AM_PROG_AR 14 | 15 | PKG_CHECK_MODULES(XML, [libxml-2.0]) 16 | AC_SUBST(XML_CFLAGS) 17 | AC_SUBST(XML_LIBS) 18 | 19 | AC_CONFIG_SRCDIR([src/main.cpp]) 20 | AC_CONFIG_HEADERS([config.h]) 21 | AC_CONFIG_FILES([Makefile \ 22 | src/Makefile \ 23 | src/blocks/Makefile \ 24 | src/grammar/Makefile \ 25 | src/types/Makefile \ 26 | src/util/Makefile]) 27 | 28 | AC_OUTPUT 29 | -------------------------------------------------------------------------------- /src/blocks/LSCR.cpp: -------------------------------------------------------------------------------- 1 | #include "LSCR.hpp" 2 | #include "util/IO.hpp" 3 | #include "grammar/Function.hpp" 4 | 5 | LSCR::LSCR(Function *function) 6 | { 7 | _id = function->getID(); 8 | for (int i = 0; i < function->getNumberOfBytes(); i++) 9 | _bytes.push_back(function->getByte(i)); 10 | } 11 | 12 | uint32_t LSCR::getSize() 13 | { 14 | uint32_t size = 0; 15 | size += 4 * sizeof(uint8_t); // identifier 16 | size += sizeof(uint32_t); // size 17 | size += sizeof(uint8_t); // id 18 | size += _bytes.size() * sizeof(uint8_t); // bytes 19 | return size; 20 | } 21 | 22 | void LSCR::write(fstream &f) 23 | { 24 | IO::writeString(f, "LSCR"); 25 | IO::writeU32BE(f, getSize()); 26 | IO::writeU8(f, _id); 27 | for (int i = 0; i < _bytes.size(); i++) 28 | IO::writeU8(f, _bytes[i]); 29 | } 30 | 31 | LSCR::~LSCR() 32 | { 33 | } 34 | 35 | -------------------------------------------------------------------------------- /src/grammar/Declaration.hpp: -------------------------------------------------------------------------------- 1 | #ifndef _DECLARATION_HPP_ 2 | #define _DECLARATION_HPP_ 3 | 4 | #include 5 | #include 6 | using namespace std; 7 | 8 | typedef enum 9 | { 10 | DECLARATION_CONST, 11 | DECLARATION_VAR, 12 | DECLARATION_ACTOR, 13 | DECLARATION_VERB, 14 | DECLARATION_CLASS 15 | } DeclarationType; 16 | 17 | class Declaration 18 | { 19 | private: 20 | DeclarationType _type; 21 | string _name; 22 | uint32_t _value; 23 | bool _fixedAddress; 24 | public: 25 | Declaration(DeclarationType type, string name); 26 | Declaration(DeclarationType type, string name, uint32_t value); 27 | DeclarationType getType() { return _type; } 28 | string getName() { return _name; } 29 | uint32_t getValue() { return _value; } 30 | bool hasFixedAddress() { return _fixedAddress; } 31 | ~Declaration(); 32 | }; 33 | 34 | #endif 35 | 36 | -------------------------------------------------------------------------------- /src/blocks/OBCD.cpp: -------------------------------------------------------------------------------- 1 | #include "OBCD.hpp" 2 | #include "util/IO.hpp" 3 | #include "types/Object.hpp" 4 | #include "CDHD.hpp" 5 | #include "OBNA.hpp" 6 | #include "VERB.hpp" 7 | 8 | OBCD::OBCD(Object *object) 9 | { 10 | _cdhd = new CDHD(object); 11 | _verb = new VERB(object->getFunction()); 12 | _obna = new OBNA(object); 13 | } 14 | 15 | uint32_t OBCD::getSize() 16 | { 17 | uint32_t size = 0; 18 | size += sizeof(uint32_t); // identifier 19 | size += sizeof(uint32_t); // size 20 | size += _cdhd->getSize(); // cdhd 21 | size += _verb->getSize(); // verb 22 | size += _obna->getSize(); // obna 23 | return size; 24 | } 25 | 26 | void OBCD::write(fstream &f) 27 | { 28 | IO::writeString(f, "OBCD"); 29 | IO::writeU32BE(f, getSize()); 30 | _cdhd->write(f); 31 | _verb->write(f); 32 | _obna->write(f); 33 | } 34 | 35 | OBCD::~OBCD() 36 | { 37 | delete _cdhd; 38 | delete _verb; 39 | delete _obna; 40 | } 41 | -------------------------------------------------------------------------------- /src/util/BMPFile.hpp: -------------------------------------------------------------------------------- 1 | #ifndef _BMPFILE_HPP_ 2 | #define _BMPFILE_HPP_ 3 | 4 | #include 5 | #include 6 | #include 7 | using namespace std; 8 | 9 | typedef struct 10 | { 11 | uint8_t r; 12 | uint8_t g; 13 | uint8_t b; 14 | } Color; 15 | 16 | class BMPFile 17 | { 18 | private: 19 | static const uint8_t BI_RGB; 20 | 21 | uint32_t _width; 22 | uint32_t _height; 23 | uint16_t _bpp; 24 | vector _colors; 25 | vector > _pixels; 26 | public: 27 | BMPFile(); 28 | bool open(string fileName); 29 | uint32_t getWidth() { return _width; } 30 | uint32_t getHeight() { return _height; } 31 | uint16_t getBPP() { return _bpp; } 32 | uint32_t getNumberOfColors() { return _colors.size(); } 33 | Color getColor(uint32_t index) { return _colors[index]; } 34 | uint8_t getPixel(uint32_t x, uint32_t y) { return _pixels[x][y]; } 35 | ~BMPFile(); 36 | }; 37 | 38 | #endif 39 | 40 | -------------------------------------------------------------------------------- /src/blocks/ROOM.hpp: -------------------------------------------------------------------------------- 1 | #ifndef _ROOM_BLOCK_HPP_ 2 | #define _ROOM_BLOCK_HPP_ 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | using namespace std; 9 | 10 | class Game; 11 | class Room; 12 | class RMHD; 13 | class CYCL; 14 | class TRNS; 15 | class PALS; 16 | class RMIM; 17 | class OBIM; 18 | class OBCD; 19 | class EXCD; 20 | class ENCD; 21 | class NLSC; 22 | class LSCR; 23 | class BOXD; 24 | class BOXM; 25 | class SCAL; 26 | 27 | class ROOM 28 | { 29 | private: 30 | RMHD *_rmhd; 31 | CYCL *_cycl; 32 | TRNS *_trns; 33 | PALS *_pals; 34 | RMIM *_rmim; 35 | vector _obims; 36 | vector _obcds; 37 | EXCD *_excd; 38 | ENCD *_encd; 39 | NLSC *_nlsc; 40 | vector _lscrs; 41 | BOXD *_boxd; 42 | BOXM *_boxm; 43 | SCAL *_scal; 44 | public: 45 | ROOM(Game *game, uint8_t roomIndex); 46 | uint32_t getSize(); 47 | void write(fstream &f); 48 | ~ROOM(); 49 | }; 50 | 51 | #endif 52 | 53 | -------------------------------------------------------------------------------- /src/blocks/WRAP.cpp: -------------------------------------------------------------------------------- 1 | #include "WRAP.hpp" 2 | #include "util/IO.hpp" 3 | #include "OFFS.hpp" 4 | #include "APAL.hpp" 5 | 6 | WRAP::WRAP(Palette *globalPalette, Palette *localPalette) 7 | { 8 | _apals.push_back(new APAL(globalPalette, localPalette)); 9 | _offs = new OFFS(_apals); 10 | } 11 | 12 | uint32_t WRAP::getSize() 13 | { 14 | uint32_t size = 0; 15 | size += 4 * sizeof(uint8_t); // identifier 16 | size += sizeof(uint32_t); // size 17 | size += _offs->getSize(); // offs 18 | for (int i = 0; i < _apals.size(); i++) // apals 19 | size += _apals[i]->getSize(); 20 | return size; 21 | } 22 | 23 | void WRAP::write(fstream &f) 24 | { 25 | IO::writeString(f, "WRAP"); 26 | IO::writeU32BE(f, getSize()); 27 | _offs->write(f); 28 | for (int i = 0; i < _apals.size(); i++) 29 | _apals[i]->write(f); 30 | } 31 | 32 | WRAP::~WRAP() 33 | { 34 | delete _offs; 35 | 36 | for (int i = 0; i < _apals.size(); i++) 37 | delete _apals[i]; 38 | } 39 | 40 | -------------------------------------------------------------------------------- /src/blocks/LECF.cpp: -------------------------------------------------------------------------------- 1 | #include "LECF.hpp" 2 | #include "util/IO.hpp" 3 | #include "types/Game.hpp" 4 | #include "LOFF.hpp" 5 | #include "LFLF.hpp" 6 | 7 | LECF::LECF(Game *game) 8 | { 9 | for (int i = 0; i < game->getNumberOfRooms(); i++) 10 | _lflfs.push_back(new LFLF(game, i)); 11 | _loff = new LOFF(game, _lflfs); 12 | } 13 | 14 | uint32_t LECF::getSize() 15 | { 16 | uint32_t size = 0; 17 | size += 4 * sizeof(uint8_t); // identifier 18 | size += sizeof(uint32_t); // size 19 | size += _loff->getSize(); // loff 20 | for (int i = 0; i < _lflfs.size(); i++) // lflfs 21 | size += _lflfs[i]->getSize(); 22 | return size; 23 | } 24 | 25 | void LECF::write(fstream &f) 26 | { 27 | IO::writeString(f, "LECF"); 28 | IO::writeU32BE(f, getSize()); 29 | _loff->write(f); 30 | for (int i = 0; i < _lflfs.size(); i++) // lflfs 31 | _lflfs[i]->write(f); 32 | } 33 | 34 | LECF::~LECF() 35 | { 36 | delete _loff; 37 | for (int i = 0; i < _lflfs.size(); i++) 38 | delete _lflfs[i]; 39 | } 40 | 41 | -------------------------------------------------------------------------------- /src/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include "util/Log.hpp" 5 | #include "types/Game.hpp" 6 | using namespace std; 7 | 8 | string getProgramDirPath(string programPath) 9 | { 10 | size_t pos = programPath.find_last_of("/\\"); 11 | if (pos != string::npos) 12 | return programPath.substr(0, pos + 1); 13 | return ""; 14 | } 15 | 16 | int main(int argc, char **argv) 17 | { 18 | cout << PACKAGE_STRING << endl; 19 | 20 | // Check arguments 21 | if (argc != 2) 22 | { 23 | cout << "Usage: " << argv[0] << " \n"; 24 | return 0; 25 | } 26 | 27 | Log::reset(); 28 | 29 | // Load and build the game directory passed as an argument 30 | try 31 | { 32 | Game game; 33 | game.load(argv[1]); 34 | game.build(getProgramDirPath(argv[0]), ""); 35 | } 36 | catch (int e) 37 | { 38 | Log::close(); 39 | return e; 40 | } 41 | 42 | Log::close(); 43 | cout << "Game generated successfully !\n"; 44 | 45 | return 0; 46 | } 47 | -------------------------------------------------------------------------------- /src/blocks/OFFS.cpp: -------------------------------------------------------------------------------- 1 | #include "OFFS.hpp" 2 | #include "util/IO.hpp" 3 | #include "APAL.hpp" 4 | 5 | OFFS::OFFS(vector apals) 6 | { 7 | uint32_t firstOffset = 0; 8 | firstOffset += 4 * sizeof(uint8_t); // OFFS identifier 9 | firstOffset += sizeof(uint32_t); // OFFS size 10 | firstOffset += apals.size() * sizeof(uint32_t); // APAL offsets 11 | _offsets.push_back(firstOffset); 12 | for (int i = 1; i < apals.size(); i++) 13 | _offsets.push_back(_offsets[i - 1] + apals[i - 1]->getSize()); 14 | } 15 | 16 | uint32_t OFFS::getSize() 17 | { 18 | uint32_t size = 0; 19 | size += 4 * sizeof(uint8_t); // identifier 20 | size += sizeof(uint32_t); // size 21 | size += _offsets.size() * sizeof(uint32_t); // offsets 22 | return size; 23 | } 24 | 25 | void OFFS::write(fstream &f) 26 | { 27 | IO::writeString(f, "OFFS"); 28 | IO::writeU32BE(f, getSize()); 29 | for (int i = 0; i < _offsets.size(); i++) 30 | IO::writeU32LE(f, _offsets[i]); 31 | } 32 | 33 | OFFS::~OFFS() 34 | { 35 | } 36 | 37 | -------------------------------------------------------------------------------- /src/blocks/OBIM.cpp: -------------------------------------------------------------------------------- 1 | #include "OBIM.hpp" 2 | #include "util/IO.hpp" 3 | #include "types/Object.hpp" 4 | #include "IMHD.hpp" 5 | #include "IMxx.hpp" 6 | 7 | OBIM::OBIM(Object *object) 8 | { 9 | _imhd = new IMHD(object); 10 | for (int i = 0; i < object->getNumberOfImages(); i++) 11 | _imxxs.push_back(new IMxx(object->getImage(i), i + 1)); 12 | } 13 | 14 | uint32_t OBIM::getSize() 15 | { 16 | uint32_t size = 0; 17 | size += 4 * sizeof(uint8_t); // identifier 18 | size += sizeof(uint32_t); // size 19 | size += _imhd->getSize(); // imhd 20 | for (int i = 0; i < _imxxs.size(); i++) // imxxs 21 | size += _imxxs[i]->getSize(); 22 | return size; 23 | } 24 | 25 | void OBIM::write(fstream &f) 26 | { 27 | IO::writeString(f, "OBIM"); 28 | IO::writeU32BE(f, getSize()); 29 | _imhd->write(f); 30 | for (int i = 0; i < _imxxs.size(); i++) 31 | _imxxs[i]->write(f); 32 | } 33 | 34 | OBIM::~OBIM() 35 | { 36 | delete _imhd; 37 | for (int i = 0; i < _imxxs.size(); i++) 38 | delete _imxxs[i]; 39 | } 40 | 41 | -------------------------------------------------------------------------------- /src/blocks/APAL.cpp: -------------------------------------------------------------------------------- 1 | #include "APAL.hpp" 2 | #include "util/IO.hpp" 3 | #include "types/Palette.hpp" 4 | 5 | APAL::APAL(Palette *globalPalette, Palette *localPalette) 6 | { 7 | _colors.resize(Palette::MAX_COLORS); 8 | for (int i = 0; i < localPalette->getCursor(); i++) 9 | _colors[i] = localPalette->getColor(i); 10 | for (int i = Palette::MAX_COLORS - 1; i >= globalPalette->getCursor(); i--) 11 | _colors[i] = globalPalette->getColor(i); 12 | } 13 | 14 | uint32_t APAL::getSize() 15 | { 16 | uint32_t size = 0; 17 | size += 4 * sizeof(uint8_t); // identifier 18 | size += sizeof(uint32_t); // size 19 | size += _colors.size() * 3 * sizeof(uint8_t); // colors 20 | return size; 21 | } 22 | 23 | void APAL::write(fstream &f) 24 | { 25 | IO::writeString(f, "APAL"); 26 | IO::writeU32BE(f, getSize()); 27 | for (int i = 0; i < _colors.size(); i++) 28 | { 29 | IO::writeU8(f, _colors[i].r); 30 | IO::writeU8(f, _colors[i].g); 31 | IO::writeU8(f, _colors[i].b); 32 | } 33 | } 34 | 35 | APAL::~APAL() 36 | { 37 | } 38 | 39 | -------------------------------------------------------------------------------- /src/blocks/DROO.cpp: -------------------------------------------------------------------------------- 1 | #include "DROO.hpp" 2 | #include "util/IO.hpp" 3 | #include "types/Game.hpp" 4 | 5 | DROO::DROO(Game *game) 6 | { 7 | _ids.push_back(0); 8 | _offsets.push_back(0); 9 | 10 | for (int i = 0; i < game->getNumberOfRooms(); i++) 11 | { 12 | _ids.push_back(1); 13 | _offsets.push_back(0); 14 | } 15 | 16 | _nItems = _ids.size(); 17 | } 18 | 19 | uint32_t DROO::getSize() 20 | { 21 | uint32_t size = 0; 22 | size += 4 * sizeof(uint8_t); // identifier 23 | size += sizeof(uint32_t); // size 24 | size += sizeof(uint16_t); // nItems 25 | size += _ids.size() * sizeof(uint8_t); // ids 26 | size += _offsets.size() * sizeof(uint32_t); // offsets 27 | return size; 28 | } 29 | 30 | void DROO::write(fstream &f) 31 | { 32 | IO::writeString(f, "DROO"); 33 | IO::writeU32BE(f, getSize()); 34 | IO::writeU16LE(f, _nItems); 35 | for (int i = 0; i < _nItems; i++) 36 | IO::writeU8(f, _ids[i]); 37 | for (int i = 0; i < _nItems; i++) 38 | IO::writeU32LE(f, _offsets[i]); 39 | } 40 | 41 | DROO::~DROO() 42 | { 43 | } 44 | 45 | -------------------------------------------------------------------------------- /src/blocks/CHAR.hpp: -------------------------------------------------------------------------------- 1 | #ifndef _CHAR_BLOCK_HPP_ 2 | #define _CHAR_BLOCK_HPP_ 3 | 4 | #include 5 | #include 6 | #include 7 | using namespace std; 8 | 9 | class Char; 10 | class Charset; 11 | class BMPFile; 12 | 13 | class CHAR 14 | { 15 | private: 16 | static const int N_COLORS; 17 | static const int MAGIC_NUMBER_SIZE; 18 | static const int MAGIC_NUMBER_UNKNOWN; 19 | 20 | vector _palette; 21 | uint8_t _bpp; 22 | uint8_t _fontHeight; 23 | uint16_t _nChars; 24 | vector _offsets; 25 | vector _widths; 26 | vector _heights; 27 | vector _xOffsets; 28 | vector _yOffsets; 29 | vector > _dataBytes; 30 | 31 | void getFrames(Charset *charset, BMPFile *bmpFile); 32 | void calculateOffsets(Charset *charset); 33 | void getDataBytes(Charset *charset, Char *chr, BMPFile *bmpFile, vector &dataBytes); 34 | public: 35 | CHAR(Charset *charset); 36 | uint32_t getSize(); 37 | void write(fstream &f); 38 | ~CHAR(); 39 | }; 40 | 41 | #endif 42 | 43 | -------------------------------------------------------------------------------- /src/blocks/MAXS.hpp: -------------------------------------------------------------------------------- 1 | #ifndef _MAXS_BLOCK_HPP_ 2 | #define _MAXS_BLOCK_HPP_ 3 | 4 | #include 5 | #include 6 | #include 7 | using namespace std; 8 | 9 | class Game; 10 | 11 | class MAXS 12 | { 13 | private: 14 | static const uint8_t UNKNOWN1; 15 | static const uint16_t N_BIT_VARIABLES; 16 | static const uint8_t N_LOCAL_OBJECTS; 17 | static const uint8_t N_ARRAYS; 18 | static const uint8_t UNKNOWN2; 19 | static const uint8_t N_VERBS; 20 | static const uint8_t N_FL_OBJECTS; 21 | static const uint8_t N_INVENTORIES; 22 | 23 | uint16_t _nVariables; 24 | uint16_t _nBitVariables; 25 | uint16_t _nLocalObjects; 26 | uint16_t _nArrays; 27 | uint16_t _nVerbs; 28 | uint16_t _nFlObjects; 29 | uint16_t _nInventories; 30 | uint16_t _nRooms; 31 | uint16_t _nScripts; 32 | uint16_t _nSounds; 33 | uint16_t _nCharsets; 34 | uint16_t _nCostumes; 35 | uint16_t _nGlobalObjects; 36 | 37 | uint32_t getSize(); 38 | public: 39 | MAXS(Game *game); 40 | void write(fstream &f); 41 | ~MAXS(); 42 | }; 43 | 44 | #endif 45 | 46 | -------------------------------------------------------------------------------- /src/blocks/DCHR.cpp: -------------------------------------------------------------------------------- 1 | #include "DCHR.hpp" 2 | #include "util/IO.hpp" 3 | #include "LFLF.hpp" 4 | 5 | DCHR::DCHR(LFLF *lflf) 6 | { 7 | _ids.push_back(0); 8 | _offsets.push_back(0); 9 | 10 | for (int i = 0; i < lflf->getNumberOfCHAROffsets(); i++) 11 | { 12 | _ids.push_back(1); // Charsets are in the first room 13 | _offsets.push_back(lflf->getCHAROffset(i)); 14 | } 15 | 16 | _nItems = _ids.size(); 17 | } 18 | 19 | uint32_t DCHR::getSize() 20 | { 21 | uint32_t size = 0; 22 | size += 4 * sizeof(uint8_t); // identifier 23 | size += sizeof(uint32_t); // size 24 | size += sizeof(uint16_t); // nItems 25 | size += _ids.size() * sizeof(uint8_t); // ids 26 | size += _offsets.size() * sizeof(uint32_t); // offsets 27 | return size; 28 | } 29 | 30 | void DCHR::write(fstream &f) 31 | { 32 | IO::writeString(f, "DCHR"); 33 | IO::writeU32BE(f, getSize()); 34 | IO::writeU16LE(f, _nItems); 35 | for (int i = 0; i < _nItems; i++) 36 | IO::writeU8(f, _ids[i]); 37 | for (int i = 0; i < _nItems; i++) 38 | IO::writeU32LE(f, _offsets[i]); 39 | } 40 | 41 | DCHR::~DCHR() 42 | { 43 | } 44 | 45 | -------------------------------------------------------------------------------- /src/blocks/DSCR.cpp: -------------------------------------------------------------------------------- 1 | #include "DSCR.hpp" 2 | #include "util/IO.hpp" 3 | #include "LFLF.hpp" 4 | 5 | DSCR::DSCR(LFLF *lflf) 6 | { 7 | _ids.push_back(0); 8 | _offsets.push_back(0); 9 | 10 | for (int i = 0; i < lflf->getNumberOfSCRPOffsets(); i++) 11 | { 12 | _ids.push_back(1); // Global scripts are in the first room 13 | _offsets.push_back(lflf->getSCRPOffset(i)); 14 | } 15 | 16 | _nItems = _ids.size(); 17 | } 18 | 19 | uint32_t DSCR::getSize() 20 | { 21 | uint32_t size = 0; 22 | size += 4 * sizeof(uint8_t); // identifier 23 | size += sizeof(uint32_t); // size 24 | size += sizeof(uint16_t); // nItems 25 | size += _ids.size() * sizeof(uint8_t); // ids 26 | size += _offsets.size() * sizeof(uint32_t); // offsets 27 | return size; 28 | } 29 | 30 | void DSCR::write(fstream &f) 31 | { 32 | IO::writeString(f, "DSCR"); 33 | IO::writeU32BE(f, getSize()); 34 | IO::writeU16LE(f, _nItems); 35 | for (int i = 0; i < _nItems; i++) 36 | IO::writeU8(f, _ids[i]); 37 | for (int i = 0; i < _nItems; i++) 38 | IO::writeU32LE(f, _offsets[i]); 39 | } 40 | 41 | DSCR::~DSCR() 42 | { 43 | } 44 | 45 | -------------------------------------------------------------------------------- /src/types/Image.hpp: -------------------------------------------------------------------------------- 1 | #ifndef _IMAGE_HPP_ 2 | #define _IMAGE_HPP_ 3 | 4 | #include 5 | #include 6 | #include 7 | using namespace std; 8 | 9 | class Palette; 10 | class PaletteData; 11 | class XMLNode; 12 | 13 | class Image 14 | { 15 | private: 16 | static const string XML_FILE_NAME; 17 | 18 | string _name; 19 | bool _transparent; 20 | string _bitmapPath; 21 | vector _zPlanePaths; 22 | uint32_t _width; 23 | uint32_t _height; 24 | vector > _pixels; 25 | public: 26 | Image(); 27 | void load(string dirPath); 28 | void save(string dirPath); 29 | void prepare(Palette *palette, PaletteData *paletteData); 30 | string getName() { return _name; } 31 | bool isTransparent() { return _transparent; } 32 | uint16_t getNumberOfZPlanePaths() { return _zPlanePaths.size(); } 33 | string getZPlanePath(uint16_t index) { return _zPlanePaths[index]; } 34 | uint32_t getWidth() { return _width; } 35 | uint32_t getHeight() { return _height; } 36 | uint32_t getPixel(uint32_t x, uint32_t y) { return _pixels[x][y]; } 37 | ~Image(); 38 | }; 39 | 40 | #endif 41 | -------------------------------------------------------------------------------- /src/blocks/IMxx.cpp: -------------------------------------------------------------------------------- 1 | #include "IMxx.hpp" 2 | #include "util/IO.hpp" 3 | #include "types/Image.hpp" 4 | #include "SMAP.hpp" 5 | #include "ZPxx.hpp" 6 | 7 | IMxx::IMxx(Image *image, uint8_t index) 8 | { 9 | _index = index; 10 | _smap = new SMAP(image); 11 | for (int i = 0; i < image->getNumberOfZPlanePaths(); i++) 12 | _zpxxs.push_back(new ZPxx(image->getZPlanePath(i), i + 1)); 13 | } 14 | 15 | uint32_t IMxx::getSize() 16 | { 17 | uint32_t size = 0; 18 | size += 4 * sizeof(uint8_t); // identifier 19 | size += sizeof(uint32_t); // size 20 | size += _smap->getSize(); // smap 21 | for (int i = 0; i < _zpxxs.size(); i++) // zpxxs 22 | size += _zpxxs[i]->getSize(); 23 | return size; 24 | } 25 | 26 | void IMxx::write(fstream &f) 27 | { 28 | char identifier[5]; 29 | snprintf(identifier, 5, "IM%02u", _index); 30 | IO::writeString(f, identifier); 31 | IO::writeU32BE(f, getSize()); 32 | _smap->write(f); 33 | for (int i = 0; i < _zpxxs.size(); i++) 34 | _zpxxs[i]->write(f); 35 | } 36 | 37 | IMxx::~IMxx() 38 | { 39 | delete _smap; 40 | for (int i = 0; i < _zpxxs.size(); i++) 41 | delete _zpxxs[i]; 42 | } 43 | -------------------------------------------------------------------------------- /src/blocks/SOU2.cpp: -------------------------------------------------------------------------------- 1 | #include "SOU2.hpp" 2 | #include "util/IO.hpp" 3 | #include "types/Game.hpp" 4 | #include "VCTL.hpp" 5 | #include "VOC.hpp" 6 | 7 | SOU2::SOU2(Game *game) 8 | { 9 | for (int i = 0; i < game->getNumberOfVoices(); i++) 10 | { 11 | _vctls.push_back(new VCTL(game->getVoice(i))); 12 | _vocs.push_back(new VOC(game->getVoice(i))); 13 | } 14 | } 15 | 16 | uint32_t SOU2::getSize() 17 | { 18 | uint32_t size = 0; 19 | size += 4 * sizeof(uint8_t); // identifier 20 | size += sizeof(uint32_t); // 0 21 | for (int i = 0; i < _vctls.size(); i++) // vctls 22 | size += _vctls[i]->getSize(); 23 | for (int i = 0; i < _vocs.size(); i++) // vocs 24 | size += _vocs[i]->getSize(); 25 | return size; 26 | } 27 | 28 | void SOU2::write(fstream &f) 29 | { 30 | IO::writeString(f, "SOU "); 31 | IO::writeU32BE(f, 0); 32 | for (int i = 0; i < _vctls.size(); i++) 33 | { 34 | _vctls[i]->write(f); 35 | _vocs[i]->write(f); 36 | } 37 | } 38 | 39 | SOU2::~SOU2() 40 | { 41 | for (int i = 0; i < _vctls.size(); i++) 42 | delete _vctls[i]; 43 | for (int i = 0; i < _vocs.size(); i++) 44 | delete _vocs[i]; 45 | } 46 | -------------------------------------------------------------------------------- /src/util/Log.cpp: -------------------------------------------------------------------------------- 1 | #include "Log.hpp" 2 | #include 3 | #include 4 | #include 5 | using namespace std; 6 | 7 | const uint8_t Log::INDENT_WIDTH = 4; 8 | 9 | uint8_t Log::_indent = 0; 10 | ofstream Log::_output; 11 | 12 | void Log::reset() 13 | { 14 | if (_output.is_open()) 15 | _output.close(); 16 | _output.open("log.txt", ios::out); 17 | } 18 | 19 | void Log::write(LogType type, const char *s, ...) 20 | { 21 | char buf[1024]; 22 | va_list va; 23 | 24 | va_start(va, s); 25 | vsnprintf(buf, 1024, s, va); 26 | va_end(va); 27 | 28 | // Spaces for indentation 29 | for (int i = 0; i < _indent * INDENT_WIDTH; i++) 30 | _output << ' '; 31 | 32 | switch (type) 33 | { 34 | case LOG_INFO: 35 | _output << buf << flush; 36 | break; 37 | case LOG_WARNING: 38 | _output << "WARNING : " << buf << flush; 39 | break; 40 | case LOG_ERROR: 41 | _output << "ERROR : " << buf << flush; 42 | cout << "ScummGEN encountered an error - see log for more details.\n"; 43 | throw 1; 44 | } 45 | } 46 | 47 | void Log::close() 48 | { 49 | if (_output.is_open()) 50 | _output.close(); 51 | } 52 | -------------------------------------------------------------------------------- /src/blocks/RMHD.cpp: -------------------------------------------------------------------------------- 1 | #include "RMHD.hpp" 2 | #include "util/IO.hpp" 3 | #include "types/Game.hpp" 4 | #include "types/Room.hpp" 5 | #include "types/Image.hpp" 6 | 7 | RMHD::RMHD(Game *game, uint8_t roomIndex) 8 | { 9 | Room *room = game->getRoom(roomIndex); 10 | 11 | _width = room->getBackground()->getWidth(); 12 | _height = room->getBackground()->getHeight(); 13 | _nObjects = room->getNumberOfObjects(); 14 | 15 | // In case we're in the first room, we have to consider the global objects also 16 | if (room->getID() == 1) 17 | _nObjects += game->getNumberOfObjects(); 18 | } 19 | 20 | uint32_t RMHD::getSize() 21 | { 22 | uint32_t size = 0; 23 | size += 4 * sizeof(uint8_t); // identifier 24 | size += sizeof(uint32_t); // size 25 | size += sizeof(uint16_t); // width 26 | size += sizeof(uint16_t); // height 27 | size += sizeof(uint16_t); // nObjects 28 | return size; 29 | } 30 | 31 | void RMHD::write(fstream &f) 32 | { 33 | IO::writeString(f, "RMHD"); 34 | IO::writeU32BE(f, getSize()); 35 | IO::writeU16LE(f, _width); 36 | IO::writeU16LE(f, _height); 37 | IO::writeU16LE(f, _nObjects); 38 | } 39 | 40 | RMHD::~RMHD() 41 | { 42 | } 43 | -------------------------------------------------------------------------------- /src/blocks/SCAL.cpp: -------------------------------------------------------------------------------- 1 | #include "SCAL.hpp" 2 | #include "util/IO.hpp" 3 | #include "types/Map.hpp" 4 | 5 | SCAL::SCAL(Map *map) 6 | { 7 | for (int i = 0; i < map->getNumberOfScales(); i++) 8 | { 9 | _s1s.push_back(map->getScale(i)->getS1()); 10 | _y1s.push_back(map->getScale(i)->getY1()); 11 | _s2s.push_back(map->getScale(i)->getS2()); 12 | _y2s.push_back(map->getScale(i)->getY2()); 13 | } 14 | } 15 | 16 | uint32_t SCAL::getSize() 17 | { 18 | uint32_t size = 0; 19 | size += 4 * sizeof(uint8_t); // identifier 20 | size += sizeof(uint32_t); // size 21 | size += Map::N_SLOTS * sizeof(uint16_t); // s1s 22 | size += _y1s.size() * sizeof(uint16_t); // y1s 23 | size += _s2s.size() * sizeof(uint16_t); // s2s 24 | size += _y2s.size() * sizeof(uint16_t); // y2s 25 | return size; 26 | } 27 | 28 | void SCAL::write(fstream &f) 29 | { 30 | IO::writeString(f, "SCAL"); 31 | IO::writeU32BE(f, getSize()); 32 | for (int i = 0; i < Map::N_SLOTS; i++) 33 | { 34 | IO::writeU16LE(f, _s1s[i]); 35 | IO::writeU16LE(f, _y1s[i]); 36 | IO::writeU16LE(f, _s2s[i]); 37 | IO::writeU16LE(f, _y2s[i]); 38 | } 39 | } 40 | 41 | SCAL::~SCAL() 42 | { 43 | } 44 | -------------------------------------------------------------------------------- /src/blocks/RNAM.cpp: -------------------------------------------------------------------------------- 1 | #include "RNAM.hpp" 2 | #include "util/IO.hpp" 3 | #include "types/Game.hpp" 4 | #include "types/Room.hpp" 5 | 6 | const uint8_t RNAM::N_CHARS = 9; 7 | const uint8_t RNAM::XOR_VALUE = 0xFF; 8 | 9 | RNAM::RNAM(Game *game) 10 | { 11 | for (int i = 0; i < game->getNumberOfRooms(); i++) 12 | { 13 | _roomIDs.push_back(game->getRoom(i)->getID()); 14 | string roomName = game->getRoom(i)->getName(); 15 | roomName.resize(N_CHARS, ' '); 16 | for (int i = 0; i < N_CHARS; i++) 17 | roomName[i] ^= XOR_VALUE; 18 | _roomNames.push_back(roomName); 19 | } 20 | } 21 | 22 | uint32_t RNAM::getSize() 23 | { 24 | uint32_t size = 0; 25 | size += 4 * sizeof(uint8_t); // identifier 26 | size += sizeof(uint32_t); // size 27 | size += _roomIDs.size() * sizeof(uint8_t); // roomIDs 28 | size += _roomNames.size() * N_CHARS * sizeof(uint8_t); // roomNames 29 | size += sizeof(uint8_t); // 0 30 | return size; 31 | } 32 | 33 | void RNAM::write(fstream &f) 34 | { 35 | IO::writeString(f, "RNAM"); 36 | IO::writeU32BE(f, getSize()); 37 | for (int i = 0; i < _roomIDs.size(); i++) 38 | { 39 | IO::writeU8(f, _roomIDs[i]); 40 | IO::writeString(f, _roomNames[i]); 41 | } 42 | IO::writeU8(f, 0); 43 | } 44 | 45 | RNAM::~RNAM() 46 | { 47 | } 48 | 49 | -------------------------------------------------------------------------------- /src/blocks/DCOS.cpp: -------------------------------------------------------------------------------- 1 | #include "DCOS.hpp" 2 | #include "util/IO.hpp" 3 | #include "types/Game.hpp" 4 | #include "types/Room.hpp" 5 | #include "LECF.hpp" 6 | #include "LFLF.hpp" 7 | 8 | DCOS::DCOS(Game *game, LECF *lecf) 9 | { 10 | _ids.push_back(0); 11 | _offsets.push_back(0); 12 | 13 | for (int i = 0; i < lecf->getNumberOfLFLFs(); i++) 14 | for (int j = 0; j < lecf->getLFLF(i)->getNumberOfCOSTOffsets(); j++) 15 | { 16 | _ids.push_back(game->getRoom(i)->getID()); 17 | _offsets.push_back(lecf->getLFLF(i)->getCOSTOffset(j)); 18 | } 19 | 20 | _nItems = _ids.size(); 21 | } 22 | 23 | uint32_t DCOS::getSize() 24 | { 25 | uint32_t size = 0; 26 | size += 4 * sizeof(uint8_t); // identifier 27 | size += sizeof(uint32_t); // size 28 | size += sizeof(uint16_t); // nItems 29 | size += _ids.size() * sizeof(uint8_t); // ids 30 | size += _offsets.size() * sizeof(uint32_t); // offsets 31 | return size; 32 | } 33 | 34 | void DCOS::write(fstream &f) 35 | { 36 | IO::writeString(f, "DCOS"); 37 | IO::writeU32BE(f, getSize()); 38 | IO::writeU16LE(f, _nItems); 39 | for (int i = 0; i < _nItems; i++) 40 | IO::writeU8(f, _ids[i]); 41 | for (int i = 0; i < _nItems; i++) 42 | IO::writeU32LE(f, _offsets[i]); 43 | } 44 | 45 | DCOS::~DCOS() 46 | { 47 | } 48 | 49 | -------------------------------------------------------------------------------- /src/blocks/DSOU.cpp: -------------------------------------------------------------------------------- 1 | #include "DSOU.hpp" 2 | #include "util/IO.hpp" 3 | #include "types/Game.hpp" 4 | #include "types/Room.hpp" 5 | #include "LECF.hpp" 6 | #include "LFLF.hpp" 7 | 8 | DSOU::DSOU(Game *game, LECF *lecf) 9 | { 10 | _ids.push_back(0); 11 | _offsets.push_back(0); 12 | 13 | for (int i = 0; i < lecf->getNumberOfLFLFs(); i++) 14 | for (int j = 0; j < lecf->getLFLF(i)->getNumberOfSOUNOffsets(); j++) 15 | { 16 | _ids.push_back(game->getRoom(i)->getID()); 17 | _offsets.push_back(lecf->getLFLF(i)->getSOUNOffset(j)); 18 | } 19 | 20 | _nItems = _ids.size(); 21 | } 22 | 23 | uint32_t DSOU::getSize() 24 | { 25 | uint32_t size = 0; 26 | size += 4 * sizeof(uint8_t); // identifier 27 | size += sizeof(uint32_t); // size 28 | size += sizeof(uint16_t); // nItems 29 | size += _ids.size() * sizeof(uint8_t); // ids 30 | size += _offsets.size() * sizeof(uint32_t); // offsets 31 | return size; 32 | } 33 | 34 | void DSOU::write(fstream &f) 35 | { 36 | IO::writeString(f, "DSOU"); 37 | IO::writeU32BE(f, getSize()); 38 | IO::writeU16LE(f, _nItems); 39 | for (int i = 0; i < _nItems; i++) 40 | IO::writeU8(f, _ids[i]); 41 | for (int i = 0; i < _nItems; i++) 42 | IO::writeU32LE(f, _offsets[i]); 43 | } 44 | 45 | DSOU::~DSOU() 46 | { 47 | } 48 | 49 | -------------------------------------------------------------------------------- /src/blocks/AARY.cpp: -------------------------------------------------------------------------------- 1 | #include "AARY.hpp" 2 | #include "util/IO.hpp" 3 | #include "types/Game.hpp" 4 | 5 | AARY::AARY(Game *game) 6 | { 7 | for (int i = 0; i < game->getNumberOfArrays(); i++) 8 | { 9 | _varNumbers.push_back(game->getArray(i)->getVarNumber()); 10 | _dimAs.push_back(game->getArray(i)->getDimA()); 11 | _dimBs.push_back(game->getArray(i)->getDimB()); 12 | _types.push_back(game->getArray(i)->getType()); 13 | } 14 | } 15 | 16 | uint32_t AARY::getSize() 17 | { 18 | uint32_t size = 0; 19 | size += 4 * sizeof(uint8_t); // identifier 20 | size += sizeof(uint32_t); // size 21 | size += _varNumbers.size() * sizeof(uint16_t); // varNumbers 22 | size += _dimAs.size() * sizeof(uint16_t); // dimAs 23 | size += _dimBs.size() * sizeof(uint16_t); // dimBs 24 | size += _types.size() * sizeof(uint16_t); // types 25 | size += sizeof(uint16_t); // 0 26 | return size; 27 | } 28 | 29 | void AARY::write(fstream &f) 30 | { 31 | IO::writeString(f, "AARY"); 32 | IO::writeU32BE(f, getSize()); 33 | for (int i = 0; i < _varNumbers.size(); i++) 34 | { 35 | IO::writeU16LE(f, _varNumbers[i]); 36 | IO::writeU16LE(f, _dimAs[i]); 37 | IO::writeU16LE(f, _dimBs[i]); 38 | IO::writeU16LE(f, _types[i]); 39 | } 40 | IO::writeU16LE(f, 0); 41 | } 42 | 43 | AARY::~AARY() 44 | { 45 | } 46 | -------------------------------------------------------------------------------- /src/blocks/BOXM.cpp: -------------------------------------------------------------------------------- 1 | #include "BOXM.hpp" 2 | #include "util/IO.hpp" 3 | 4 | const uint8_t BOXM::BOX_END = 0xFF; 5 | 6 | BOXM::BOXM() 7 | { 8 | vector from; 9 | vector to; 10 | vector dests; 11 | 12 | // Add fake box entries 13 | from.push_back(0); 14 | to.push_back(0); 15 | dests.push_back(0); 16 | _from.push_back(from); 17 | _to.push_back(to); 18 | _dests.push_back(dests); 19 | } 20 | 21 | uint32_t BOXM::getSize() 22 | { 23 | uint32_t size = 0; 24 | size += 4 * sizeof(uint8_t); // identifier 25 | size += sizeof(uint32_t); // size 26 | for (int i = 0; i < _from.size(); i++) 27 | { 28 | size += _from[i].size() * sizeof(uint8_t); // from 29 | size += _dests[i].size() * sizeof(uint8_t); // to 30 | size += _dests[i].size() * sizeof(uint8_t); // dest 31 | } 32 | size += _from.size() * sizeof(uint8_t); // BOX_END 33 | return size; 34 | } 35 | 36 | void BOXM::write(fstream &f) 37 | { 38 | IO::writeString(f, "BOXM"); 39 | IO::writeU32BE(f, getSize()); 40 | for (int i = 0; i < _from.size(); i++) 41 | { 42 | for (int j = 0; j < _from[i].size(); j++) 43 | { 44 | IO::writeU8(f, _from[i][j]); 45 | IO::writeU8(f, _to[i][j]); 46 | IO::writeU8(f, _dests[i][j]); 47 | } 48 | IO::writeU8(f, BOX_END); 49 | } 50 | } 51 | 52 | BOXM::~BOXM() 53 | { 54 | } 55 | -------------------------------------------------------------------------------- /src/util/IO.hpp: -------------------------------------------------------------------------------- 1 | #ifndef _IO_HPP_ 2 | #define _IO_HPP_ 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | using namespace std; 9 | 10 | class IO 11 | { 12 | private: 13 | static uint8_t _key; 14 | public: 15 | static void setKey(uint8_t key) { _key = key; } 16 | static string readString(fstream &f, uint8_t length); 17 | static uint8_t readU8(fstream &f); 18 | static uint16_t readU16LE(fstream &f); 19 | static uint16_t readU16BE(fstream &f); 20 | static uint32_t readU32LE(fstream &f); 21 | static uint32_t readU32BE(fstream &f); 22 | static uint32_t readBits(fstream &f, uint8_t &byte, uint8_t &bitPos, uint8_t nBits); 23 | static void writeString(fstream &f, string s); 24 | static void writeU8(fstream &f, uint8_t data); 25 | static void writeU16LE(fstream &f, uint16_t data); 26 | static void writeU16BE(fstream &f, uint16_t data); 27 | static void writeU24LE(fstream &f, uint32_t data); 28 | static void writeU24BE(fstream &f, uint32_t data); 29 | static void writeU32LE(fstream &f, uint32_t data); 30 | static void writeU32BE(fstream &f, uint32_t data); 31 | static void writeBits(vector &v, uint8_t byte, uint32_t &bytePos, uint8_t &bitPos, uint8_t nBits); 32 | static bool copyFile(string srcFileName, string destFileName); 33 | static bool createDirectory(string dirPath); 34 | }; 35 | 36 | #endif 37 | -------------------------------------------------------------------------------- /src/blocks/LFLF.hpp: -------------------------------------------------------------------------------- 1 | #ifndef _LFLF_BLOCK_HPP_ 2 | #define _LFLF_BLOCK_HPP_ 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | using namespace std; 9 | 10 | class Game; 11 | class ROOM; 12 | class SCRP; 13 | class SOUN; 14 | class COST; 15 | class CHAR; 16 | 17 | class LFLF 18 | { 19 | private: 20 | uint32_t _size; 21 | ROOM *_room; 22 | vector _scrps; 23 | vector _souns; 24 | vector _costs; 25 | vector _chars; 26 | vector _scrpOffsets; 27 | vector _sounOffsets; 28 | vector _costOffsets; 29 | vector _charOffsets; 30 | public: 31 | LFLF(Game *game, uint8_t roomIndex); 32 | uint32_t getSize(); 33 | uint32_t getNumberOfSCRPOffsets() { return _scrpOffsets.size(); } 34 | uint32_t getSCRPOffset(uint32_t index) { return _scrpOffsets[index]; } 35 | uint32_t getNumberOfSOUNOffsets() { return _sounOffsets.size(); } 36 | uint32_t getSOUNOffset(uint32_t index) { return _sounOffsets[index]; } 37 | uint32_t getNumberOfCOSTOffsets() { return _costOffsets.size(); } 38 | uint32_t getCOSTOffset(uint32_t index) { return _costOffsets[index]; } 39 | uint32_t getNumberOfCHAROffsets() { return _charOffsets.size(); } 40 | uint32_t getCHAROffset(uint32_t index) { return _charOffsets[index]; } 41 | void write(fstream &f); 42 | ~LFLF(); 43 | }; 44 | 45 | #endif 46 | 47 | -------------------------------------------------------------------------------- /src/util/XMLFile.hpp: -------------------------------------------------------------------------------- 1 | #ifndef _XMLFILE_HPP_ 2 | #define _XMLFILE_HPP_ 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | using namespace std; 9 | 10 | class XMLNode 11 | { 12 | private: 13 | string _name; 14 | string _content; 15 | vector _children; 16 | public: 17 | XMLNode(string name, string content = ""); 18 | XMLNode(string name, int content); 19 | XMLNode(string name, bool content); 20 | uint32_t getNumberOfChildren() { return _children.size(); } 21 | XMLNode *getChild(uint32_t index) { return _children[index]; } 22 | XMLNode *getChild(string name, uint32_t index = 0); 23 | void addChild(XMLNode *child) { _children.push_back(child); } 24 | string getName() { return _name; } 25 | string getStringContent() { return _content; } 26 | int getIntegerContent() { return atoi(_content.c_str()); } 27 | bool getBooleanContent() { return (_content == "true"); } 28 | ~XMLNode(); 29 | }; 30 | 31 | class XMLFile 32 | { 33 | private: 34 | XMLNode *_rootNode; 35 | 36 | void read(xmlNode *srcNode, XMLNode *&destNode); 37 | void write(XMLNode *srcNode, xmlNode *&destNode, uint8_t indent); 38 | public: 39 | XMLFile(); 40 | bool open(string fileName); 41 | bool save(string fileName); 42 | XMLNode *getRootNode() { return _rootNode; } 43 | void setRootNode(XMLNode *rootNode) { _rootNode = rootNode; } 44 | ~XMLFile(); 45 | }; 46 | 47 | #endif 48 | 49 | -------------------------------------------------------------------------------- /src/types/Charset.hpp: -------------------------------------------------------------------------------- 1 | #ifndef _CHARSET_HPP_ 2 | #define _CHARSET_HPP_ 3 | 4 | #include 5 | #include 6 | #include 7 | using namespace std; 8 | 9 | class XMLNode; 10 | 11 | class Char 12 | { 13 | private: 14 | uint16_t _id; 15 | uint16_t _x; 16 | uint16_t _y; 17 | uint8_t _width; 18 | uint8_t _height; 19 | int8_t _xOffset; 20 | int8_t _yOffset; 21 | public: 22 | Char(); 23 | void load(XMLNode *node); 24 | void save(XMLNode *node); 25 | uint16_t getID() { return _id; } 26 | uint16_t getX() { return _x; } 27 | uint16_t getY() { return _y; } 28 | uint8_t getWidth() { return _width; } 29 | uint8_t getHeight() { return _height; } 30 | int8_t getXOffset() { return _xOffset; } 31 | int8_t getYOffset() { return _yOffset; } 32 | }; 33 | 34 | class Charset 35 | { 36 | private: 37 | static const string XML_FILE_NAME; 38 | 39 | uint16_t _id; 40 | string _name; 41 | string _bitmapPath; 42 | uint8_t _fontHeight; 43 | vector_chars; 44 | public: 45 | Charset(); 46 | void load(string dirPath); 47 | void save(string dirPath); 48 | uint16_t getID() { return _id; } 49 | void setID(uint16_t id) { _id = id; } 50 | string getName() { return _name; } 51 | string getBitmapPath() { return _bitmapPath; } 52 | uint8_t getFontHeight() { return _fontHeight; } 53 | uint16_t getNumberOfChars() { return _chars.size(); } 54 | Char *getChar(uint16_t index) { return _chars[index]; } 55 | ~Charset(); 56 | }; 57 | 58 | #endif 59 | -------------------------------------------------------------------------------- /src/blocks/CDHD.cpp: -------------------------------------------------------------------------------- 1 | #include "CDHD.hpp" 2 | #include "util/IO.hpp" 3 | #include "types/Object.hpp" 4 | 5 | const uint16_t CDHD::UNKNOWN_1 = 0; 6 | const uint16_t CDHD::UNKNOWN_2 = 0; 7 | const uint8_t CDHD::FLAGS = 0; 8 | const uint8_t CDHD::PARENT = 0; 9 | 10 | CDHD::CDHD(Object *object) 11 | { 12 | _id = object->getID(); 13 | _x = object->getX(); 14 | _y = object->getY(); 15 | _width = object->getWidth(); 16 | _height = object->getHeight(); 17 | _actorDir = object->getActorDir(); 18 | } 19 | 20 | uint32_t CDHD::getSize() 21 | { 22 | uint32_t size = 0; 23 | size += 4 * sizeof(uint8_t); // identifier 24 | size += sizeof(uint32_t); // size 25 | size += sizeof(uint16_t); // id 26 | size += sizeof(uint16_t); // x 27 | size += sizeof(uint16_t); // y 28 | size += sizeof(uint16_t); // width 29 | size += sizeof(uint16_t); // height 30 | size += sizeof(uint8_t); // flags 31 | size += sizeof(uint8_t); // parent 32 | size += sizeof(uint16_t); // unknown 33 | size += sizeof(uint16_t); // unknown 34 | size += sizeof(uint8_t); // actorDir 35 | return size; 36 | } 37 | 38 | void CDHD::write(fstream &f) 39 | { 40 | IO::writeString(f, "CDHD"); 41 | IO::writeU32BE(f, getSize()); 42 | IO::writeU16LE(f, _id); 43 | IO::writeU16LE(f, _x); 44 | IO::writeU16LE(f, _y); 45 | IO::writeU16LE(f, _width); 46 | IO::writeU16LE(f, _height); 47 | IO::writeU8(f, FLAGS); 48 | IO::writeU8(f, PARENT); 49 | IO::writeU16LE(f, UNKNOWN_1); 50 | IO::writeU16LE(f, UNKNOWN_2); 51 | IO::writeU8(f, _actorDir); 52 | } 53 | 54 | CDHD::~CDHD() 55 | { 56 | } 57 | -------------------------------------------------------------------------------- /src/util/WAVFile.cpp: -------------------------------------------------------------------------------- 1 | #include "WAVFile.hpp" 2 | #include 3 | #include "IO.hpp" 4 | #include "Log.hpp" 5 | 6 | WAVFile::WAVFile() 7 | { 8 | } 9 | 10 | bool WAVFile::open(string fileName) 11 | { 12 | // We open the file, which should be an 8bit PCM Wave file 13 | fstream file(fileName.c_str(), ios::in | ios::binary); 14 | if (!file.is_open()) 15 | { 16 | Log::write(LOG_WARNING, "Could not open file \"%s\" !\n", fileName.c_str()); 17 | return false; 18 | } 19 | 20 | IO::readU32LE(file); // "RIFF" block 21 | IO::readU32LE(file); // chunkSize 22 | IO::readU32LE(file); // format 23 | IO::readU32LE(file); // "fmt " block 24 | IO::readU32LE(file); // chunkSize 25 | 26 | uint16_t audioFormat = IO::readU16LE(file); 27 | // Only PCM is supported 28 | if (audioFormat != 1) 29 | { 30 | file.close(); 31 | Log::write(LOG_WARNING, "Audio format not supported !\n"); 32 | return false; 33 | } 34 | 35 | IO::readU16LE(file); // nChannels 36 | _sampleRate = IO::readU32LE(file); 37 | IO::readU32LE(file); // byteRate 38 | IO::readU16LE(file); // blockAlign 39 | 40 | uint16_t bitsPerSample = IO::readU16LE(file); 41 | // Only 8bit is supported 42 | if (bitsPerSample != 8) 43 | { 44 | file.close(); 45 | Log::write(LOG_WARNING, "Bits per sample not supported !\n"); 46 | return false; 47 | } 48 | 49 | IO::readU32LE(file); // "data" block 50 | 51 | uint32_t nDataBytes = IO::readU32LE(file); 52 | for (int i = 0; i < nDataBytes; i++) 53 | _dataBytes.push_back(IO::readU8(file)); 54 | 55 | file.close(); 56 | 57 | return true; 58 | } 59 | 60 | WAVFile::~WAVFile() 61 | { 62 | } 63 | -------------------------------------------------------------------------------- /src/grammar/Function.hpp: -------------------------------------------------------------------------------- 1 | #ifndef _FUNCTION_HPP_ 2 | #define _FUNCTION_HPP_ 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | using namespace std; 9 | 10 | class BlockStatement; 11 | class Declaration; 12 | class Instruction; 13 | 14 | typedef enum 15 | { 16 | FUNCTION_NORMAL, 17 | FUNCTION_THREAD, 18 | FUNCTION_INLINED 19 | } FunctionType; 20 | 21 | class Function 22 | { 23 | private: 24 | FunctionType _type; 25 | string _name; 26 | uint16_t _id; 27 | vector _arguments; 28 | BlockStatement *_blockStatement; 29 | vector _instructions; 30 | map _localSymbols; 31 | vector _byteCode; 32 | 33 | void removeLabels(); 34 | void displayAssembly(); 35 | public: 36 | Function(FunctionType type, string name, BlockStatement *blockS); 37 | void compile(); 38 | FunctionType getType() { return _type; } 39 | string getName() { return _name; } 40 | uint16_t getID() { return _id; } 41 | void setID(uint16_t id) { _id = id; } 42 | void addArgument(Declaration *d) { _arguments.push_back(d); } 43 | uint8_t getNumberOfArguments() { return _arguments.size(); } 44 | Declaration *getArgument(uint8_t index) { return _arguments[index]; } 45 | BlockStatement *getBlockStatement() { return _blockStatement; } 46 | uint32_t getNumberOfInstructions() { return _instructions.size(); } 47 | Instruction *getInstruction(uint32_t index) { return _instructions[index]; } 48 | uint32_t getNumberOfBytes() { return _byteCode.size(); } 49 | uint8_t getByte(uint32_t index) { return _byteCode[index]; } 50 | ~Function(); 51 | }; 52 | 53 | #endif 54 | -------------------------------------------------------------------------------- /src/blocks/LOFF.cpp: -------------------------------------------------------------------------------- 1 | #include "LOFF.hpp" 2 | #include "util/IO.hpp" 3 | #include "types/Game.hpp" 4 | #include "types/Room.hpp" 5 | #include "LFLF.hpp" 6 | 7 | LOFF::LOFF(Game *game, vector lflfs) 8 | { 9 | _nRooms = game->getNumberOfRooms(); 10 | for (int i = 0; i < _nRooms; i++) 11 | _roomIDs.push_back(game->getRoom(i)->getID()); 12 | uint32_t firstOffset = 0; 13 | firstOffset += 4 * sizeof(uint8_t); // LECF identifier 14 | firstOffset += sizeof(uint32_t); // LECF size 15 | firstOffset += 4 * sizeof(uint8_t); // LOFF identifier 16 | firstOffset += sizeof(uint32_t); // LOFF size 17 | firstOffset += sizeof(uint8_t); // LOFF nRooms 18 | firstOffset += _nRooms * sizeof(uint8_t); // LOFF roomIDs 19 | firstOffset += _nRooms * sizeof(uint32_t); // LOFF roomOffsets 20 | firstOffset += 4 * sizeof(uint8_t); // LFLF identifier 21 | firstOffset += sizeof(uint32_t); // LFLF size 22 | _roomOffsets.push_back(firstOffset); 23 | for (int i = 1; i < _nRooms; i++) 24 | _roomOffsets.push_back(_roomOffsets[i - 1] + lflfs[i - 1]->getSize()); 25 | } 26 | 27 | uint32_t LOFF::getSize() 28 | { 29 | uint32_t size = 0; 30 | size += 4 * sizeof(uint8_t); // identifier 31 | size += sizeof(uint32_t); // size 32 | size += sizeof(uint8_t); // nRooms 33 | size += _roomIDs.size() * sizeof(uint8_t); // roomIDs 34 | size += _roomOffsets.size() * sizeof(uint32_t); // roomOffsets 35 | return size; 36 | } 37 | 38 | void LOFF::write(fstream &f) 39 | { 40 | IO::writeString(f, "LOFF"); 41 | IO::writeU32BE(f, getSize()); 42 | IO::writeU8(f, _nRooms); 43 | for (int i = 0; i < _nRooms; i++) 44 | { 45 | IO::writeU8(f, _roomIDs[i]); 46 | IO::writeU32LE(f, _roomOffsets[i]); 47 | } 48 | } 49 | 50 | LOFF::~LOFF() 51 | { 52 | } 53 | 54 | -------------------------------------------------------------------------------- /src/types/Object.hpp: -------------------------------------------------------------------------------- 1 | #ifndef _OBJECT_HPP_ 2 | #define _OBJECT_HPP_ 3 | 4 | #include 5 | #include 6 | #include 7 | using namespace std; 8 | 9 | class Image; 10 | class Palette; 11 | class PaletteData; 12 | class Function; 13 | 14 | class Object 15 | { 16 | private: 17 | static const string XML_FILE_NAME; 18 | static const uint8_t ACTOR_DIR_WEST; 19 | static const uint8_t ACTOR_DIR_EAST; 20 | static const uint8_t ACTOR_DIR_SOUTH; 21 | static const uint8_t ACTOR_DIR_NORTH; 22 | 23 | uint16_t _id; 24 | string _name; 25 | string _displayName; 26 | vector _images; 27 | int16_t _hotspotX; 28 | int16_t _hotspotY; 29 | uint16_t _x; 30 | uint16_t _y; 31 | uint16_t _width; 32 | uint16_t _height; 33 | uint8_t _actorDir; 34 | PaletteData *_paletteData; 35 | Function *_function; 36 | public: 37 | Object(); 38 | void load(string dirName); 39 | void save(string dirName); 40 | void prepare(Palette *palette); 41 | void compile(); 42 | uint16_t getID() { return _id; } 43 | void setID(uint16_t id) { _id = id; } 44 | string getName() { return _name; } 45 | string getDisplayName() { return _displayName; } 46 | uint16_t getNumberOfImages() { return _images.size(); } 47 | Image *getImage(uint16_t index) { return _images[index]; } 48 | int16_t getHotspotX() { return _hotspotX; } 49 | int16_t getHotspotY() { return _hotspotY; } 50 | uint16_t getX() { return _x; } 51 | uint16_t getY() { return _y; } 52 | uint16_t getWidth() { return _width; } 53 | uint16_t getHeight() { return _height; } 54 | uint8_t getActorDir() { return _actorDir; } 55 | Function *getFunction() { return _function; } 56 | void setFunction(Function *function) { _function = function; } 57 | ~Object(); 58 | }; 59 | 60 | #endif 61 | -------------------------------------------------------------------------------- /src/blocks/DOBJ.cpp: -------------------------------------------------------------------------------- 1 | #include "DOBJ.hpp" 2 | #include "util/IO.hpp" 3 | #include "types/Game.hpp" 4 | #include "types/Room.hpp" 5 | #include "types/Object.hpp" 6 | 7 | const uint8_t DOBJ::OWNER_AND_STATE = 0; 8 | const uint32_t DOBJ::CLASS_DATA = 0; 9 | 10 | DOBJ::DOBJ(Game *game) 11 | { 12 | _ownersAndStates.push_back(OWNER_AND_STATE); 13 | _classData.push_back(CLASS_DATA); 14 | 15 | // Actor objects 16 | for (int i = 0; i < Game::N_DEFAULT_ACTORS; i++) 17 | { 18 | _ownersAndStates.push_back(OWNER_AND_STATE); 19 | _classData.push_back(CLASS_DATA); 20 | } 21 | 22 | // Game global objects 23 | for (int i = 0; i < game->getNumberOfObjects(); i++) 24 | { 25 | _ownersAndStates.push_back(OWNER_AND_STATE); 26 | _classData.push_back(CLASS_DATA); 27 | } 28 | 29 | // Room objects 30 | for (int i = 0; i < game->getNumberOfRooms(); i++) 31 | for (int j = 0; j < game->getRoom(i)->getNumberOfObjects(); j++) 32 | { 33 | _ownersAndStates.push_back(OWNER_AND_STATE); 34 | _classData.push_back(CLASS_DATA); 35 | } 36 | 37 | _nItems = _ownersAndStates.size(); 38 | } 39 | 40 | uint32_t DOBJ::getSize() 41 | { 42 | uint32_t size = 0; 43 | size += 4 * sizeof(uint8_t); // identifier 44 | size += sizeof(uint32_t); // size 45 | size += sizeof(uint16_t); // nitems 46 | size += _ownersAndStates.size() * sizeof(uint8_t); // ownersAndStates 47 | size += _classData.size() * sizeof(uint32_t); // classData 48 | return size; 49 | } 50 | 51 | void DOBJ::write(fstream &f) 52 | { 53 | IO::writeString(f, "DOBJ"); 54 | IO::writeU32BE(f, getSize()); 55 | IO::writeU16LE(f, _nItems); 56 | for (int i = 0; i < _ownersAndStates.size(); i++) 57 | IO::writeU8(f, _ownersAndStates[i]); 58 | for (int i = 0; i < _classData.size(); i++) 59 | IO::writeU32LE(f, _classData[i]); 60 | } 61 | 62 | DOBJ::~DOBJ() 63 | { 64 | } 65 | -------------------------------------------------------------------------------- /src/blocks/SMAP.cpp: -------------------------------------------------------------------------------- 1 | #include "SMAP.hpp" 2 | #include "util/IO.hpp" 3 | #include "types/Image.hpp" 4 | 5 | const uint8_t SMAP::STRIP_WIDTH = 8; 6 | const uint8_t SMAP::CID_NO_COMPRESSION_OPAQUE = 1; 7 | const uint8_t SMAP::CID_NO_COMPRESSION_TRANSPARENT = 149; 8 | 9 | SMAP::SMAP(Image *image) 10 | { 11 | // Set compression ID 12 | uint8_t cid = image->isTransparent() ? CID_NO_COMPRESSION_TRANSPARENT : CID_NO_COMPRESSION_OPAQUE; 13 | 14 | for (int i = 0; i < image->getWidth() / STRIP_WIDTH; i++) 15 | { 16 | vector strip; 17 | strip.push_back(cid); 18 | for (int j = 0; j < image->getHeight(); j++) 19 | for (int k = 0; k < STRIP_WIDTH; k++) 20 | { 21 | uint8_t pixel = image->getPixel(i * STRIP_WIDTH + k, j); 22 | strip.push_back(pixel); 23 | } 24 | _strips.push_back(strip); 25 | } 26 | uint32_t firstOffset = 0; 27 | firstOffset += 4 * sizeof(uint8_t); // identifier 28 | firstOffset += sizeof(uint32_t); // size 29 | firstOffset += _strips.size() * sizeof(uint32_t); // offsets 30 | _offsets.push_back(firstOffset); 31 | for (int i = 1; i < _strips.size(); i++) 32 | _offsets.push_back(_offsets[i - 1] + _strips[i - 1].size()); 33 | } 34 | 35 | uint32_t SMAP::getSize() 36 | { 37 | uint32_t size = 0; 38 | size += 4 * sizeof(uint8_t); // identifier 39 | size += sizeof(uint32_t); // size 40 | size += _offsets.size() * sizeof(uint32_t); // offsets 41 | for (int i = 0; i < _strips.size(); i++) // strips 42 | size += _strips[i].size() * sizeof(uint8_t); 43 | return size; 44 | } 45 | 46 | void SMAP::write(fstream &f) 47 | { 48 | IO::writeString(f, "SMAP"); 49 | IO::writeU32BE(f, getSize()); 50 | for (int i = 0; i < _offsets.size(); i++) 51 | IO::writeU32LE(f, _offsets[i]); 52 | for (int i = 0; i < _strips.size(); i++) 53 | for (int j = 0; j < _strips[i].size(); j++) 54 | IO::writeU8(f, _strips[i][j]); 55 | } 56 | 57 | SMAP::~SMAP() 58 | { 59 | } 60 | -------------------------------------------------------------------------------- /src/blocks/VOC.cpp: -------------------------------------------------------------------------------- 1 | #include "VOC.hpp" 2 | #include "util/IO.hpp" 3 | #include "util/WAVFile.hpp" 4 | #include "types/Voice.hpp" 5 | 6 | const int VOC::HEADER_SIZE = 26; 7 | const int VOC::FILE_VERSION = 0x10A; 8 | const int VOC::MAGIC_NUMBER = 0x1234; 9 | const int VOC::TERMINATOR_BLOCK_ID = 0; 10 | const int VOC::SOUND_DATA_BLOCK_ID = 1; 11 | const int VOC::PCM_CODEC_ID = 0; 12 | 13 | VOC::VOC(Voice *voice) 14 | { 15 | WAVFile wavFile; 16 | wavFile.open(voice->getWavePath()); 17 | _freqDivisor = 256 - 1000000 / wavFile.getSampleRate(); 18 | for (int i = 0; i < wavFile.getNumberOfDataBytes(); i++) 19 | _dataBytes.push_back(wavFile.getDataByte(i)); 20 | } 21 | 22 | uint32_t VOC::getSize() 23 | { 24 | uint32_t size = 0; 25 | size += 19 * sizeof(uint8_t); // identifier 26 | size += sizeof(uint8_t); // EOF 27 | size += sizeof(uint16_t); // HEADER_SIZE 28 | size += sizeof(uint16_t); // FILE_VERSION 29 | size += sizeof(uint16_t); // ~VERSION + MAGIC_NUMBER 30 | size += sizeof(uint8_t); // SOUND_DATA_BLOCK_ID 31 | size += 3 * sizeof(uint8_t); // 2 + _nDataBytes 32 | size += sizeof(uint8_t); // freqDivisor 33 | size += sizeof(uint8_t); // PCM_CODEC_ID 34 | size += _dataBytes.size() * sizeof(uint8_t); // dataBytes 35 | size += sizeof(uint8_t); // TERMINATOR_BLOCK_ID 36 | return size; 37 | } 38 | 39 | void VOC::write(fstream &f) 40 | { 41 | // First, we write the header, beginning with the identifier 42 | IO::writeString(f, "Creative Voice File"); 43 | IO::writeU8(f, 0x1A); 44 | IO::writeU16LE(f, HEADER_SIZE); 45 | IO::writeU16LE(f, FILE_VERSION); 46 | IO::writeU16LE(f, ~FILE_VERSION + MAGIC_NUMBER); 47 | IO::writeU8(f, SOUND_DATA_BLOCK_ID); 48 | IO::writeU24LE(f, 2 + _dataBytes.size()); 49 | IO::writeU8(f, _freqDivisor); 50 | IO::writeU8(f, PCM_CODEC_ID); 51 | for (int i = 0; i < _dataBytes.size(); i++) 52 | IO::writeU8(f, _dataBytes[i]); 53 | IO::writeU8(f, TERMINATOR_BLOCK_ID); 54 | } 55 | 56 | VOC::~VOC() 57 | { 58 | } 59 | -------------------------------------------------------------------------------- /src/blocks/COST.hpp: -------------------------------------------------------------------------------- 1 | #ifndef _COST_BLOCK_HPP_ 2 | #define _COST_BLOCK_HPP_ 3 | 4 | #include 5 | #include 6 | #include 7 | using namespace std; 8 | 9 | class Costume; 10 | class Frame; 11 | 12 | class COST 13 | { 14 | private: 15 | static const uint8_t DEFAULT_FORMAT; 16 | static const uint32_t UNKNOWN; 17 | static const uint8_t N_LIMBS; 18 | static const uint16_t LIMB_MASK; 19 | static const uint8_t REDIR_LIMB; 20 | static const uint8_t REDIR_PICT; 21 | static const int16_t X_INC; 22 | static const int16_t Y_INC; 23 | static const uint8_t SHIFT_16; 24 | static const uint8_t SHIFT_32; 25 | 26 | uint8_t _format; 27 | vector _palette; 28 | uint16_t _animCmdsOffset; 29 | vector _limbsOffsets; 30 | vector _animsOffsets; 31 | vector _animStarts; 32 | vector _animNoLoopAndEndOffsets; 33 | vector _animCmds; 34 | vector _pictOffsets; 35 | vector _pictWidths; 36 | vector _pictHeights; 37 | vector _pictXs; 38 | vector _pictYs; 39 | vector > _dataBytes; 40 | 41 | void calculateAnimCmdsOffset(Costume *costume); 42 | void calculateLimbOffsets(Costume *costume); 43 | void calculateAnimOffsets(Costume *costume); 44 | void calculateAnimStarts(Costume *costume); 45 | void calculateAnimNoLoopAndEndOffsets(Costume *costume); 46 | void getAnimCmds(Costume *costume); 47 | void getFrames(Costume *costume); 48 | void calculatePictOffsets(Costume *costume); 49 | void getDataBytes(Costume *costume, Frame *frame, vector &dataBytes); 50 | void addPixel(uint8_t pixel, uint8_t &lastPixel, uint32_t &repCount, vector &pixels, vector &repCounts); 51 | void writeRLEData(vector &dataBytes, uint8_t shift, vector *colors, vector *repCounts); 52 | public: 53 | COST(Costume *costume); 54 | uint32_t getSize(); 55 | void write(fstream &f); 56 | ~COST(); 57 | }; 58 | 59 | #endif 60 | -------------------------------------------------------------------------------- /src/types/Midi.cpp: -------------------------------------------------------------------------------- 1 | #include "Midi.hpp" 2 | #include 3 | #include "util/IO.hpp" 4 | #include "util/Log.hpp" 5 | #include "util/XMLFile.hpp" 6 | 7 | const string Midi::XML_FILE_NAME = "midi.xml"; 8 | 9 | Midi::Midi(): 10 | _id(0), 11 | _name(""), 12 | _midiPath("") 13 | { 14 | } 15 | 16 | void Midi::load(string dirPath) 17 | { 18 | Log::write(LOG_INFO, "Midi\n"); 19 | Log::indent(); 20 | 21 | XMLFile xmlFile; 22 | xmlFile.open(dirPath + XML_FILE_NAME); 23 | XMLNode *rootNode = xmlFile.getRootNode(); 24 | 25 | _name = rootNode->getChild("name")->getStringContent(); 26 | Log::write(LOG_INFO, "name: %s\n", _name.c_str()); 27 | 28 | _midiPath = dirPath + rootNode->getChild("midiName")->getStringContent(); 29 | Log::write(LOG_INFO, "midiPath: %s\n", _midiPath.c_str()); 30 | 31 | Log::unIndent(); 32 | } 33 | 34 | void Midi::save(string dirPath) 35 | { 36 | Log::write(LOG_INFO, "Midi\n"); 37 | Log::indent(); 38 | 39 | if (!IO::createDirectory(dirPath)) 40 | Log::write(LOG_ERROR, "Could not create directory \"%s\" !\n", dirPath.c_str()); 41 | 42 | XMLFile xmlFile; 43 | XMLNode *rootNode = new XMLNode("midi"); 44 | xmlFile.setRootNode(rootNode); 45 | 46 | rootNode->addChild(new XMLNode("name", _name)); 47 | Log::write(LOG_INFO, "name: %s\n", _name.c_str()); 48 | 49 | string midiName = _midiPath.substr(_midiPath.find_last_of('/') + 1); 50 | rootNode->addChild(new XMLNode("midiName", midiName)); 51 | string newMidiPath = dirPath + midiName; 52 | if (_midiPath != newMidiPath) 53 | { 54 | if (!IO::copyFile(_midiPath, newMidiPath)) 55 | Log::write(LOG_ERROR, "Could not copy file \"%s\" to \"%s\" !\n", _midiPath.c_str(), newMidiPath.c_str()); 56 | _midiPath = newMidiPath; 57 | } 58 | Log::write(LOG_INFO, "midiPath: %s\n", _midiPath.c_str()); 59 | 60 | if (!xmlFile.save(dirPath + XML_FILE_NAME)) 61 | Log::write(LOG_ERROR, "Couldn't save midi to the specified directory !\n"); 62 | 63 | Log::unIndent(); 64 | } 65 | 66 | Midi::~Midi() 67 | { 68 | } 69 | -------------------------------------------------------------------------------- /src/types/Map.hpp: -------------------------------------------------------------------------------- 1 | #ifndef _MAP_HPP_ 2 | #define _MAP_HPP_ 3 | 4 | #include 5 | #include 6 | #include 7 | using namespace std; 8 | 9 | class XMLNode; 10 | 11 | class Box 12 | { 13 | private: 14 | string _name; 15 | uint8_t _id; 16 | int16_t _ulx, _uly; 17 | int16_t _urx, _ury; 18 | int16_t _lrx, _lry; 19 | int16_t _llx, _lly; 20 | uint8_t _mask; 21 | uint8_t _flags; 22 | uint16_t _scale; 23 | public: 24 | Box(); 25 | void load(XMLNode *node); 26 | void save(XMLNode *node); 27 | string getName() { return _name; } 28 | uint8_t getID() { return _id; } 29 | uint8_t setID(uint8_t id) { _id = id; } 30 | int16_t getULX() { return _ulx; } 31 | int16_t getULY() { return _uly; } 32 | int16_t getURX() { return _urx; } 33 | int16_t getURY() { return _ury; } 34 | int16_t getLRX() { return _lrx; } 35 | int16_t getLRY() { return _lry; } 36 | int16_t getLLX() { return _llx; } 37 | int16_t getLLY() { return _lly; } 38 | uint8_t getMask() { return _mask; } 39 | uint8_t getFlags() { return _flags; } 40 | uint16_t getScale() { return _scale; } 41 | ~Box(); 42 | }; 43 | 44 | class Scale 45 | { 46 | private: 47 | uint16_t _s1; 48 | uint16_t _y1; 49 | uint16_t _s2; 50 | uint16_t _y2; 51 | public: 52 | Scale(); 53 | void load(XMLNode *node); 54 | void save(XMLNode *node); 55 | uint16_t getS1() { return _s1; } 56 | uint16_t getY1() { return _y1; } 57 | uint16_t getS2() { return _s2; } 58 | uint16_t getY2() { return _y2; } 59 | ~Scale(); 60 | }; 61 | 62 | class Map 63 | { 64 | private: 65 | static const string XML_FILE_NAME; 66 | 67 | vector _boxes; 68 | vector _scales; 69 | public: 70 | static const uint8_t N_SLOTS; 71 | 72 | Map(); 73 | void load(string dirName); 74 | void save(string dirName); 75 | void prepare(); 76 | uint8_t getNumberOfBoxes() { return _boxes.size(); } 77 | Box *getBox(uint8_t index) { return _boxes[index]; } 78 | uint8_t getNumberOfScales() { return _scales.size(); } 79 | Scale *getScale(uint8_t index) { return _scales[index]; } 80 | ~Map(); 81 | }; 82 | 83 | #endif 84 | -------------------------------------------------------------------------------- /src/blocks/IMHD.cpp: -------------------------------------------------------------------------------- 1 | #include "IMHD.hpp" 2 | #include "util/IO.hpp" 3 | #include "types/Object.hpp" 4 | #include "types/Image.hpp" 5 | 6 | const uint16_t IMHD::UNKNOWN = 0; 7 | const uint16_t IMHD::X = 0; 8 | const uint16_t IMHD::Y = 0; 9 | 10 | IMHD::IMHD(Object *object) 11 | { 12 | _id = object->getID(); 13 | _nImages = object->getNumberOfImages(); 14 | _nZPlanesPerImage = _nImages == 0 ? 0 : object->getImage(0)->getNumberOfZPlanePaths(); 15 | 16 | if (_nImages == 0) 17 | { 18 | _width = 0; 19 | _height = 0; 20 | } 21 | else 22 | { 23 | _width = object->getImage(0)->getWidth(); 24 | _height = object->getImage(0)->getHeight(); 25 | } 26 | 27 | // Only one hotspot is now supported 28 | _hotspotXs.push_back(object->getHotspotX()); 29 | _hotspotYs.push_back(object->getHotspotY()); 30 | } 31 | 32 | uint32_t IMHD::getSize() 33 | { 34 | uint32_t size = 0; 35 | size += 4 * sizeof(uint8_t); // identifier 36 | size += sizeof(uint32_t); // size 37 | size += sizeof(uint16_t); // id 38 | size += sizeof(uint16_t); // nImages 39 | size += sizeof(uint16_t); // nZPlanesPerImage 40 | size += sizeof(uint16_t); // unknown 41 | size += sizeof(uint16_t); // x 42 | size += sizeof(uint16_t); // y 43 | size += sizeof(uint16_t); // width 44 | size += sizeof(uint16_t); // height 45 | size += sizeof(uint16_t); // nHotspots 46 | size += _hotspotXs.size() * sizeof(int16_t); // hotspotXs 47 | size += _hotspotYs.size() * sizeof(int16_t); // hotspotYs 48 | return size; 49 | } 50 | 51 | void IMHD::write(fstream &f) 52 | { 53 | IO::writeString(f, "IMHD"); 54 | IO::writeU32BE(f, getSize()); 55 | IO::writeU16LE(f, _id); 56 | IO::writeU16LE(f, _nImages); 57 | IO::writeU16LE(f, _nZPlanesPerImage); 58 | IO::writeU16LE(f, UNKNOWN); 59 | IO::writeU16LE(f, X); 60 | IO::writeU16LE(f, Y); 61 | IO::writeU16LE(f, _width); 62 | IO::writeU16LE(f, _height); 63 | IO::writeU16LE(f, _hotspotXs.size()); 64 | for (int i = 0; i < _hotspotXs.size(); i++) 65 | { 66 | IO::writeU16LE(f, _hotspotXs[i]); 67 | IO::writeU16LE(f, _hotspotYs[i]); 68 | } 69 | } 70 | 71 | IMHD::~IMHD() 72 | { 73 | } 74 | -------------------------------------------------------------------------------- /src/blocks/ZPxx.cpp: -------------------------------------------------------------------------------- 1 | #include "ZPxx.hpp" 2 | #include "util/BMPFile.hpp" 3 | #include "util/IO.hpp" 4 | #include "types/Image.hpp" 5 | 6 | const uint8_t ZPxx::STRIP_WIDTH = 8; 7 | const uint8_t ZPxx::MAX_BYTES = 0x7F; 8 | 9 | ZPxx::ZPxx(string filePath, uint8_t index) 10 | { 11 | BMPFile bmpFile; 12 | bmpFile.open(filePath); 13 | _index = index; 14 | for (int i = 0; i < bmpFile.getWidth() / STRIP_WIDTH; i++) 15 | { 16 | vector strip; 17 | uint16_t h = bmpFile.getHeight(); 18 | while (h > 0) 19 | { 20 | uint8_t nBytes = h > MAX_BYTES ? MAX_BYTES : h; 21 | strip.push_back(nBytes); 22 | for (int j = 0; j < nBytes; j++) 23 | { 24 | uint8_t byte = 0; 25 | for (int k = 0; k < STRIP_WIDTH; k++) 26 | byte |= bmpFile.getPixel(i * STRIP_WIDTH + k, bmpFile.getHeight() - h) << (STRIP_WIDTH - 1 - k); 27 | strip.push_back(byte); 28 | h--; 29 | } 30 | } 31 | _strips.push_back(strip); 32 | } 33 | uint16_t firstOffset = 0; 34 | firstOffset += 4 * sizeof(uint8_t); // identifier 35 | firstOffset += sizeof(uint32_t); // size 36 | firstOffset += _strips.size() * sizeof(uint16_t); // offsets 37 | _offsets.push_back(firstOffset); 38 | for (int i = 1; i < _strips.size(); i++) 39 | _offsets.push_back(_offsets[i - 1] + _strips[i - 1].size()); 40 | } 41 | 42 | uint32_t ZPxx::getSize() 43 | { 44 | uint32_t size = 0; 45 | size += 4 * sizeof(uint8_t); // identifier 46 | size += sizeof(uint32_t); // size 47 | size += _offsets.size() * sizeof(uint16_t); // offsets 48 | for (int i = 0; i < _strips.size(); i++) // strips 49 | size += _strips[i].size() * sizeof(uint8_t); 50 | return size; 51 | } 52 | 53 | void ZPxx::write(fstream &f) 54 | { 55 | char identifier[5]; 56 | snprintf(identifier, 5, "ZP%02u", _index); 57 | IO::writeString(f, identifier); 58 | IO::writeU32BE(f, getSize()); 59 | for (int i = 0; i < _offsets.size(); i++) 60 | IO::writeU16LE(f, _offsets[i]); 61 | for (int i = 0; i < _strips.size(); i++) 62 | for (int j = 0; j < _strips[i].size(); j++) 63 | IO::writeU8(f, _strips[i][j]); 64 | } 65 | 66 | ZPxx::~ZPxx() 67 | { 68 | } 69 | -------------------------------------------------------------------------------- /src/types/Room.hpp: -------------------------------------------------------------------------------- 1 | #ifndef _ROOM_HPP_ 2 | #define _ROOM_HPP_ 3 | 4 | #include 5 | #include 6 | #include 7 | using namespace std; 8 | 9 | class XMLNode; 10 | class Image; 11 | class PaletteData; 12 | class Palette; 13 | class Object; 14 | class Map; 15 | class Costume; 16 | class Script; 17 | class Declaration; 18 | class Function; 19 | 20 | class Room 21 | { 22 | private: 23 | static const string XML_FILE_NAME; 24 | static const uint8_t MIN_LOCAL_SCRIPT_ID; 25 | 26 | uint8_t _id; 27 | string _name; 28 | PaletteData *_paletteData; 29 | Palette *_palette; 30 | Image *_background; 31 | Map *_map; 32 | Script *_script; 33 | vector _objects; 34 | vector _costumes; 35 | vector _declarations; 36 | vector _functions; 37 | Function *_entryFunction; 38 | Function *_exitFunction; 39 | 40 | void loadObjects(string dirPath, XMLNode *node); 41 | void loadCostumes(string dirPath, XMLNode *node); 42 | void saveObjects(string dirPath, XMLNode *node); 43 | void saveCostumes(string dirPath, XMLNode *node); 44 | public: 45 | Room(); 46 | void load(string dirPath); 47 | void save(string dirPath); 48 | void prepare(); 49 | void parse(vector &declarations); 50 | void compile(); 51 | uint8_t getID() { return _id; } 52 | void setID(uint8_t id) { _id = id; } 53 | string getName() { return _name; } 54 | Palette *getPalette() { return _palette; } 55 | void setPalette(Palette *palette) { _palette = palette; } 56 | Image *getBackground() { return _background; } 57 | Map *getMap() { return _map; } 58 | uint16_t getNumberOfObjects() { return _objects.size(); } 59 | Object *getObject(uint16_t index) { return _objects[index]; } 60 | uint16_t getNumberOfCostumes() { return _costumes.size(); } 61 | Costume *getCostume(uint16_t index) { return _costumes[index]; } 62 | Function *getEntryFunction() { return _entryFunction; } 63 | Function *getExitFunction() { return _exitFunction; } 64 | uint8_t getNumberOfFunctions() { return _functions.size(); } 65 | Function *getFunction(uint8_t index) { return _functions[index]; } 66 | ~Room(); 67 | }; 68 | 69 | #endif 70 | -------------------------------------------------------------------------------- /src/blocks/CYCL.cpp: -------------------------------------------------------------------------------- 1 | #include "CYCL.hpp" 2 | #include "util/IO.hpp" 3 | #include "types/Palette.hpp" 4 | 5 | const uint16_t CYCL::FREQUENCY = 0x4000; 6 | const uint16_t CYCL::FORWARD = 0x0000; 7 | const uint16_t CYCL::BACKWARD = 0x0002; 8 | const uint16_t CYCL::UNKNOWN = 0; 9 | 10 | CYCL::CYCL(Palette *globalPalette, Palette *localPalette) 11 | { 12 | for (int i = 0; i < globalPalette->getNumberOfCycles(); i++) 13 | { 14 | _ids.push_back(globalPalette->getCycle(i)->getID()); 15 | _freqs.push_back(globalPalette->getCycle(i)->getDelay() != 0 ? FREQUENCY / globalPalette->getCycle(i)->getDelay() : 0); 16 | _flags.push_back(globalPalette->getCycle(i)->isForward() ? FORWARD : BACKWARD); 17 | _starts.push_back(globalPalette->getCycle(i)->getStart()); 18 | _ends.push_back(globalPalette->getCycle(i)->getEnd()); 19 | } 20 | for (int i = 0; i < localPalette->getNumberOfCycles(); i++) 21 | { 22 | _ids.push_back(localPalette->getCycle(i)->getID()); 23 | _freqs.push_back(localPalette->getCycle(i)->getDelay() != 0 ? FREQUENCY / localPalette->getCycle(i)->getDelay() : 0); 24 | _flags.push_back(localPalette->getCycle(i)->isForward() ? FORWARD : BACKWARD); 25 | _starts.push_back(localPalette->getCycle(i)->getStart()); 26 | _ends.push_back(localPalette->getCycle(i)->getEnd()); 27 | } 28 | } 29 | 30 | uint32_t CYCL::getSize() 31 | { 32 | uint32_t size = 0; 33 | size += 4 * sizeof(uint8_t); // identifier 34 | size += sizeof(uint32_t); // size 35 | size += _ids.size() * sizeof(uint8_t); // ids 36 | size += _ids.size() * sizeof(uint16_t); // unknown 37 | size += _freqs.size() * sizeof(uint16_t); // freqs 38 | size += _flags.size() * sizeof(uint16_t); // flags 39 | size += _starts.size() * sizeof(uint8_t); // starts 40 | size += _ends.size() * sizeof(uint8_t); // ends 41 | size += sizeof(uint8_t); // 0 42 | return size; 43 | } 44 | 45 | void CYCL::write(fstream &f) 46 | { 47 | IO::writeString(f, "CYCL"); 48 | IO::writeU32BE(f, getSize()); 49 | for (int i = 0; i < _ids.size(); i++) 50 | { 51 | IO::writeU8(f, _ids[i]); 52 | IO::writeU16LE(f, UNKNOWN); 53 | IO::writeU16BE(f, _freqs[i]); 54 | IO::writeU16BE(f, _flags[i]); 55 | IO::writeU8(f, _starts[i]); 56 | IO::writeU8(f, _ends[i]); 57 | } 58 | IO::writeU8(f, 0); 59 | } 60 | 61 | CYCL::~CYCL() 62 | { 63 | } 64 | 65 | -------------------------------------------------------------------------------- /src/blocks/Makefile.am: -------------------------------------------------------------------------------- 1 | noinst_LTLIBRARIES = libblocks.la 2 | libblocks_la_SOURCES = AARY.cpp AARY.hpp \ 3 | APAL.cpp APAL.hpp \ 4 | BOXD.cpp BOXD.hpp \ 5 | BOXM.cpp BOXM.hpp \ 6 | CDHD.cpp CDHD.hpp \ 7 | CHAR.cpp CHAR.hpp \ 8 | COST.cpp COST.hpp \ 9 | CYCL.cpp CYCL.hpp \ 10 | DCHR.cpp DCHR.hpp \ 11 | DCOS.cpp DCOS.hpp \ 12 | DOBJ.cpp DOBJ.hpp \ 13 | DROO.cpp DROO.hpp \ 14 | DSCR.cpp DSCR.hpp \ 15 | DSOU.cpp DSOU.hpp \ 16 | ENCD.cpp ENCD.hpp \ 17 | EXCD.cpp EXCD.hpp \ 18 | GMD.cpp GMD.hpp \ 19 | IMHD.cpp IMHD.hpp \ 20 | IMxx.cpp IMxx.hpp \ 21 | LECF.cpp LECF.hpp \ 22 | LFLF.cpp LFLF.hpp \ 23 | LOFF.cpp LOFF.hpp \ 24 | LSCR.cpp LSCR.hpp \ 25 | MAXS.cpp MAXS.hpp \ 26 | NLSC.cpp NLSC.hpp \ 27 | OBCD.cpp OBCD.hpp \ 28 | OBIM.cpp OBIM.hpp \ 29 | OBNA.cpp OBNA.hpp \ 30 | OFFS.cpp OFFS.hpp \ 31 | PALS.cpp PALS.hpp \ 32 | RMHD.cpp RMHD.hpp \ 33 | RMIH.cpp RMIH.hpp \ 34 | RMIM.cpp RMIM.hpp \ 35 | RNAM.cpp RNAM.hpp \ 36 | ROOM.cpp ROOM.hpp \ 37 | SCAL.cpp SCAL.hpp \ 38 | SCRP.cpp SCRP.hpp \ 39 | SMAP.cpp SMAP.hpp \ 40 | SOU.cpp SOU.hpp \ 41 | SOU2.cpp SOU2.hpp \ 42 | SOUN.cpp SOUN.hpp \ 43 | TRNS.cpp TRNS.hpp \ 44 | VCTL.cpp VCTL.hpp \ 45 | VERB.cpp VERB.hpp \ 46 | VOC.cpp VOC.hpp \ 47 | WRAP.cpp WRAP.hpp \ 48 | ZPxx.cpp ZPxx.hpp 49 | libblocks_la_CPPFLAGS = -I$(top_srcdir)/src @XML_CFLAGS@ 50 | -------------------------------------------------------------------------------- /src/grammar/Context.hpp: -------------------------------------------------------------------------------- 1 | #ifndef _CONTEXT_HPP_ 2 | #define _CONTEXT_HPP_ 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include "Function.hpp" 9 | using namespace std; 10 | 11 | class Declaration; 12 | class Function; 13 | 14 | typedef enum 15 | { 16 | CONTEXT_GAME, 17 | CONTEXT_ROOM, 18 | CONTEXT_FUNCTION, 19 | CONTEXT_THREAD, 20 | CONTEXT_INLINED, 21 | CONTEXT_BLOCK, 22 | CONTEXT_SWITCH, 23 | CONTEXT_VERB, 24 | CONTEXT_FOR, 25 | CONTEXT_WHILE, 26 | CONTEXT_DO_WHILE 27 | } ContextType; 28 | 29 | typedef enum 30 | { 31 | SYMBOL_CONSTANT, 32 | SYMBOL_VARIABLE, 33 | SYMBOL_FUNCTION 34 | } SymbolType; 35 | 36 | class Context 37 | { 38 | private: 39 | static const uint16_t MIN_ACTOR; 40 | static const uint16_t MIN_VERB; 41 | static const uint16_t MIN_CLASS; 42 | static const uint16_t MAX_CLASSES; 43 | 44 | static vector _instances; 45 | static uint16_t _currentActor; 46 | static uint16_t _currentVerb; 47 | static uint16_t _currentClass; 48 | 49 | ContextType _type; 50 | vector *_declarations; 51 | vector *_functions; 52 | int32_t _continueLabel; 53 | int32_t _breakLabel; 54 | int32_t _returnLabel; 55 | map _constantSymbols; 56 | map _variableSymbols; 57 | map _functionSymbols; 58 | 59 | static bool symbolExists(string name); 60 | static bool isAddressUsed(uint32_t address); 61 | 62 | void setConstantSymbols(); 63 | void setVariableSymbols(bool fixedAddresses); 64 | void setFunctionSymbols(); 65 | void displaySymbols(); 66 | public: 67 | static const uint16_t LOCAL_VARIABLE_MASK; 68 | 69 | static uint32_t labelCounter; 70 | static uint32_t currentAddress; 71 | 72 | static void pushContext(Context *context); 73 | static void popContext(); 74 | static bool resolveSymbol(string symbol, uint32_t &value, SymbolType &type); 75 | static Function* getFunction(string functionName); 76 | static int32_t getContinueLabel(); 77 | static int32_t getBreakLabel(); 78 | static int32_t getReturnLabel(); 79 | static FunctionType getFunctionType(); 80 | 81 | Context(ContextType type, vector *declarations, vector *functions, int32_t continueLabel, int32_t breakLabel, int32_t returnLabel); 82 | ~Context(); 83 | }; 84 | 85 | #endif 86 | -------------------------------------------------------------------------------- /src/types/Voice.cpp: -------------------------------------------------------------------------------- 1 | #include "Voice.hpp" 2 | #include "util/IO.hpp" 3 | #include "util/Log.hpp" 4 | #include "util/XMLFile.hpp" 5 | 6 | const string Voice::XML_FILE_NAME = "voice.xml"; 7 | 8 | Voice::Voice(): 9 | _name(""), 10 | _wavePath("") 11 | { 12 | } 13 | 14 | void Voice::load(string dirPath) 15 | { 16 | Log::write(LOG_INFO, "Voice\n"); 17 | Log::indent(); 18 | 19 | XMLFile xmlFile; 20 | xmlFile.open(dirPath + XML_FILE_NAME); 21 | XMLNode *rootNode = xmlFile.getRootNode(); 22 | 23 | _name = rootNode->getChild("name")->getStringContent(); 24 | Log::write(LOG_INFO, "name: %s\n", _name.c_str()); 25 | 26 | _wavePath = dirPath + rootNode->getChild("waveName")->getStringContent(); 27 | Log::write(LOG_INFO, "wavePath: %s\n", _wavePath.c_str()); 28 | 29 | int i = 0; 30 | XMLNode *child; 31 | while ((child = rootNode->getChild("syncTime", i)) != NULL) 32 | { 33 | _syncTimes.push_back(child->getIntegerContent()); 34 | Log::write(LOG_INFO, "syncTime: %u\n", _syncTimes[i]); 35 | i++; 36 | } 37 | 38 | Log::unIndent(); 39 | } 40 | 41 | void Voice::save(string dirPath) 42 | { 43 | Log::write(LOG_INFO, "Voice\n"); 44 | Log::indent(); 45 | 46 | if (!IO::createDirectory(dirPath)) 47 | Log::write(LOG_ERROR, "Could not create directory \"%s\" !\n", dirPath.c_str()); 48 | 49 | XMLFile xmlFile; 50 | XMLNode *rootNode = new XMLNode("voice"); 51 | xmlFile.setRootNode(rootNode); 52 | 53 | rootNode->addChild(new XMLNode("name", _name)); 54 | Log::write(LOG_INFO, "name: %s\n", _name.c_str()); 55 | 56 | string waveName = _wavePath.substr(_wavePath.find_last_of('/') + 1); 57 | rootNode->addChild(new XMLNode("waveName", waveName)); 58 | string newWavePath = dirPath + waveName; 59 | if (_wavePath != newWavePath) 60 | { 61 | if (!IO::copyFile(_wavePath, newWavePath)) 62 | Log::write(LOG_ERROR, "Could not copy file \"%s\" to \"%s\" !\n", _wavePath.c_str(), newWavePath.c_str()); 63 | _wavePath = newWavePath; 64 | } 65 | Log::write(LOG_INFO, "wavePath: %s\n", _wavePath.c_str()); 66 | 67 | for (int i = 0; i < _syncTimes.size(); i++) 68 | { 69 | rootNode->addChild(new XMLNode("syncTime", _syncTimes[i])); 70 | Log::write(LOG_INFO, "syncTime: %u\n", _syncTimes[i]); 71 | } 72 | 73 | if (!xmlFile.save(dirPath + XML_FILE_NAME)) 74 | Log::write(LOG_ERROR, "Couldn't save voice to the specified directory !\n"); 75 | 76 | Log::unIndent(); 77 | } 78 | 79 | Voice::~Voice() 80 | { 81 | } 82 | -------------------------------------------------------------------------------- /src/util/BMPFile.cpp: -------------------------------------------------------------------------------- 1 | #include "BMPFile.hpp" 2 | #include 3 | #include "IO.hpp" 4 | #include "Log.hpp" 5 | 6 | const uint8_t BMPFile::BI_RGB = 0; 7 | 8 | BMPFile::BMPFile() 9 | { 10 | } 11 | 12 | bool BMPFile::open(string fileName) 13 | { 14 | // We open the file, which should be an indexed BMP file 15 | fstream file(fileName.c_str(), ios::in | ios::binary); 16 | if (!file.is_open()) 17 | { 18 | Log::write(LOG_WARNING, "Could not open file \"%s\" !\n", fileName.c_str()); 19 | return false; 20 | } 21 | 22 | uint16_t identifier = IO::readU16LE(file); 23 | uint32_t fileSize = IO::readU32LE(file); 24 | uint32_t reserved = IO::readU32LE(file); 25 | 26 | uint32_t bitmapDataOffset = IO::readU32LE(file); 27 | uint32_t bitmapHeaderSize = IO::readU32LE(file); 28 | 29 | _width = IO::readU32LE(file); 30 | _height = IO::readU32LE(file); 31 | 32 | uint16_t nPlanes = IO::readU16LE(file); 33 | 34 | // The number of bits per pixel cannot be above 8 35 | _bpp = IO::readU16LE(file); 36 | if (_bpp > 8) 37 | { 38 | file.close(); 39 | Log::write(LOG_WARNING, "Bits per pixel not supported !\n"); 40 | return false; 41 | } 42 | 43 | // Only non-encoded BMP files are supported 44 | uint32_t compression = IO::readU32LE(file); 45 | if (compression != BI_RGB) 46 | { 47 | file.close(); 48 | Log::write(LOG_WARNING, "Compression format not supported !\n"); 49 | return false; 50 | } 51 | 52 | uint32_t bitmapDataSize = IO::readU32LE(file); 53 | uint32_t hResolution = IO::readU32LE(file); 54 | uint32_t vResolution = IO::readU32LE(file); 55 | uint32_t nColors = IO::readU32LE(file); 56 | uint32_t nImportantColors = IO::readU32LE(file); 57 | 58 | Color color; 59 | for (int i = 0; i < nColors; i++) 60 | { 61 | color.b = IO::readU8(file); 62 | color.g = IO::readU8(file); 63 | color.r = IO::readU8(file); 64 | IO::readU8(file); 65 | _colors.push_back(color); 66 | } 67 | 68 | for (int i = 0; i < _width; i++) 69 | { 70 | vector pixelColumn; 71 | for (int j = 0; j < _height; j++) 72 | pixelColumn.push_back(0); 73 | _pixels.push_back(pixelColumn); 74 | } 75 | 76 | // Decoding pixel data 77 | uint8_t padding = 32 - (_width * _bpp) % 32; 78 | if (padding == 32) 79 | padding = 0; 80 | for (int i = _height - 1; i >= 0; i--) 81 | { 82 | uint8_t byte; 83 | uint8_t bitPos = 0; 84 | for (int j = 0; j < _width; j++) 85 | _pixels[j][i] = IO::readBits(file, byte, bitPos, _bpp); 86 | IO::readBits(file, byte, bitPos, padding); 87 | } 88 | 89 | file.close(); 90 | return true; 91 | } 92 | 93 | BMPFile::~BMPFile() 94 | { 95 | } 96 | -------------------------------------------------------------------------------- /src/blocks/BOXD.cpp: -------------------------------------------------------------------------------- 1 | #include "BOXD.hpp" 2 | #include "util/IO.hpp" 3 | #include "types/Map.hpp" 4 | 5 | const uint16_t BOXD::FAKE_VALUE = 0x8300; 6 | const uint8_t BOXD::FAKE_MASK = 0; 7 | const uint8_t BOXD::FAKE_FLAGS = 0; 8 | const uint8_t BOXD::FAKE_SCALE = 255; 9 | 10 | BOXD::BOXD(Map *map) 11 | { 12 | // Add fake box 13 | _ulxs.push_back(FAKE_VALUE); 14 | _ulys.push_back(FAKE_VALUE); 15 | _urxs.push_back(FAKE_VALUE); 16 | _urys.push_back(FAKE_VALUE); 17 | _lrxs.push_back(FAKE_VALUE); 18 | _lrys.push_back(FAKE_VALUE); 19 | _llxs.push_back(FAKE_VALUE); 20 | _llys.push_back(FAKE_VALUE); 21 | _masks.push_back(FAKE_MASK); 22 | _flags.push_back(FAKE_MASK); 23 | _scales.push_back(FAKE_SCALE); 24 | 25 | for (int i = 0; i < map->getNumberOfBoxes(); i++) 26 | { 27 | _ulxs.push_back(map->getBox(i)->getULX()); 28 | _ulys.push_back(map->getBox(i)->getULY()); 29 | _urxs.push_back(map->getBox(i)->getURX()); 30 | _urys.push_back(map->getBox(i)->getURY()); 31 | _lrxs.push_back(map->getBox(i)->getLRX()); 32 | _lrys.push_back(map->getBox(i)->getLRY()); 33 | _llxs.push_back(map->getBox(i)->getLLX()); 34 | _llys.push_back(map->getBox(i)->getLLY()); 35 | _masks.push_back(map->getBox(i)->getMask()); 36 | _flags.push_back(map->getBox(i)->getFlags()); 37 | _scales.push_back(map->getBox(i)->getScale()); 38 | } 39 | 40 | _nBoxes = map->getNumberOfBoxes() + 1; 41 | } 42 | 43 | uint32_t BOXD::getSize() 44 | { 45 | uint32_t size = 0; 46 | size += 4 * sizeof(uint8_t); // identifier 47 | size += sizeof(uint32_t); // size 48 | size += sizeof(uint16_t); // _nBoxes 49 | size += _nBoxes * sizeof(int16_t); // ulxs 50 | size += _nBoxes * sizeof(int16_t); // ulys 51 | size += _nBoxes * sizeof(int16_t); // urxs 52 | size += _nBoxes * sizeof(int16_t); // urys 53 | size += _nBoxes * sizeof(int16_t); // lrxs 54 | size += _nBoxes * sizeof(int16_t); // lrys 55 | size += _nBoxes * sizeof(int16_t); // llxs 56 | size += _nBoxes * sizeof(int16_t); // llys 57 | size += _nBoxes * sizeof(uint8_t); // masks 58 | size += _nBoxes * sizeof(uint8_t); // flags 59 | size += _nBoxes * sizeof(uint16_t); // scales 60 | return size; 61 | } 62 | 63 | void BOXD::write(fstream &f) 64 | { 65 | IO::writeString(f, "BOXD"); 66 | IO::writeU32BE(f, getSize()); 67 | IO::writeU16LE(f, _nBoxes); // Only the lower 8 bits 68 | for (int i = 0; i < _nBoxes; i++) 69 | { 70 | IO::writeU16LE(f, _ulxs[i]); 71 | IO::writeU16LE(f, _ulys[i]); 72 | IO::writeU16LE(f, _urxs[i]); 73 | IO::writeU16LE(f, _urys[i]); 74 | IO::writeU16LE(f, _lrxs[i]); 75 | IO::writeU16LE(f, _lrys[i]); 76 | IO::writeU16LE(f, _llxs[i]); 77 | IO::writeU16LE(f, _llys[i]); 78 | IO::writeU8(f, _masks[i]); 79 | IO::writeU8(f, _flags[i]); 80 | IO::writeU16LE(f, _scales[i]); 81 | } 82 | } 83 | 84 | BOXD::~BOXD() 85 | { 86 | } 87 | -------------------------------------------------------------------------------- /src/blocks/LFLF.cpp: -------------------------------------------------------------------------------- 1 | #include "LFLF.hpp" 2 | #include "util/IO.hpp" 3 | #include "types/Game.hpp" 4 | #include "types/Room.hpp" 5 | #include "grammar/Function.hpp" 6 | #include "ROOM.hpp" 7 | #include "SCRP.hpp" 8 | #include "SOUN.hpp" 9 | #include "COST.hpp" 10 | #include "CHAR.hpp" 11 | 12 | LFLF::LFLF(Game *game, uint8_t roomIndex) 13 | { 14 | _room = new ROOM(game, roomIndex); 15 | 16 | // Add global resources to the first room 17 | if (game->getRoom(roomIndex)->getID() == 1) 18 | { 19 | for (int i = 0; i < game->getNumberOfFunctions(); i++) 20 | if (game->getFunction(i)->getType() != FUNCTION_INLINED) 21 | _scrps.push_back(new SCRP(game->getFunction(i))); 22 | 23 | for (int i = 0; i < game->getNumberOfMidis(); i++) 24 | _souns.push_back(new SOUN(game->getMidi(i))); 25 | 26 | for (int i = 0; i < game->getNumberOfCostumes(); i++) 27 | _costs.push_back(new COST(game->getCostume(i))); 28 | 29 | for (int i = 0; i < game->getNumberOfCharsets(); i++) 30 | _chars.push_back(new CHAR(game->getCharset(i))); 31 | } 32 | 33 | for (int i = 0; i < game->getRoom(roomIndex)->getNumberOfCostumes(); i++) 34 | _costs.push_back(new COST(game->getRoom(roomIndex)->getCostume(i))); 35 | } 36 | 37 | uint32_t LFLF::getSize() 38 | { 39 | uint32_t size = 0; 40 | size += 4 * sizeof(uint8_t); // identifier 41 | size += sizeof(uint32_t); // size 42 | size += _room->getSize(); // room 43 | for (int i = 0; i < _scrps.size(); i++) // scrps 44 | size += _scrps[i]->getSize(); 45 | for (int i = 0; i < _souns.size(); i++) // souns 46 | size += _souns[i]->getSize(); 47 | for (int i = 0; i < _costs.size(); i++) // costs 48 | size += _costs[i]->getSize(); 49 | for (int i = 0; i < _chars.size(); i++) // chars 50 | size += _chars[i]->getSize(); 51 | return size; 52 | } 53 | 54 | void LFLF::write(fstream &f) 55 | { 56 | IO::writeString(f, "LFLF"); 57 | IO::writeU32BE(f, getSize()); 58 | uint32_t roomOffset = (uint32_t)f.tellp(); 59 | _room->write(f); 60 | for (int i = 0; i < _scrps.size(); i++) 61 | { 62 | _scrpOffsets.push_back((uint32_t)f.tellp() - roomOffset); 63 | _scrps[i]->write(f); 64 | } 65 | for (int i = 0; i < _souns.size(); i++) 66 | { 67 | _sounOffsets.push_back((uint32_t)f.tellp() - roomOffset); 68 | _souns[i]->write(f); 69 | } 70 | for (int i = 0; i < _costs.size(); i++) 71 | { 72 | _costOffsets.push_back((uint32_t)f.tellp() - roomOffset); 73 | _costs[i]->write(f); 74 | } 75 | for (int i = 0; i < _chars.size(); i++) 76 | { 77 | _charOffsets.push_back((uint32_t)f.tellp() - roomOffset); 78 | _chars[i]->write(f); 79 | } 80 | } 81 | 82 | LFLF::~LFLF() 83 | { 84 | delete _room; 85 | for (int i = 0; i < _scrps.size(); i++) 86 | delete _scrps[i]; 87 | for (int i = 0; i < _souns.size(); i++) 88 | delete _souns[i]; 89 | for (int i = 0; i < _costs.size(); i++) 90 | delete _costs[i]; 91 | for (int i = 0; i < _chars.size(); i++) 92 | delete _chars[i]; 93 | } 94 | -------------------------------------------------------------------------------- /src/types/Script.cpp: -------------------------------------------------------------------------------- 1 | #include "Script.hpp" 2 | #include "util/IO.hpp" 3 | #include "util/Log.hpp" 4 | #include "util/XMLFile.hpp" 5 | #include "grammar/Declaration.hpp" 6 | #include "grammar/Function.hpp" 7 | 8 | const string Script::XML_FILE_NAME = "script.xml"; 9 | 10 | // External flex/bison declarations 11 | extern FILE *yyin; 12 | extern int yyparse(vector &declarations, vector &functions); 13 | extern int yylex(); 14 | extern int yylineno; 15 | 16 | Script::Script(string scriptPath): 17 | _scriptPath(scriptPath) 18 | { 19 | } 20 | 21 | void Script::load(string dirPath) 22 | { 23 | Log::write(LOG_INFO, "Script\n"); 24 | Log::indent(); 25 | 26 | XMLFile xmlFile; 27 | xmlFile.open(dirPath + XML_FILE_NAME); 28 | XMLNode *rootNode = xmlFile.getRootNode(); 29 | 30 | _name = rootNode->getChild("name")->getStringContent(); 31 | Log::write(LOG_INFO, "name: %s\n", _name.c_str()); 32 | 33 | _scriptPath = dirPath + rootNode->getChild("scriptName")->getStringContent(); 34 | Log::write(LOG_INFO, "scriptPath: %s\n", _scriptPath.c_str()); 35 | 36 | Log::unIndent(); 37 | } 38 | 39 | void Script::save(string dirPath) 40 | { 41 | Log::write(LOG_INFO, "Script\n"); 42 | Log::indent(); 43 | 44 | if (!IO::createDirectory(dirPath)) 45 | Log::write(LOG_ERROR, "Could not create directory \"%s\" !\n", dirPath.c_str()); 46 | 47 | XMLFile xmlFile; 48 | XMLNode *rootNode = new XMLNode("script"); 49 | xmlFile.setRootNode(rootNode); 50 | 51 | rootNode->addChild(new XMLNode("name", _name)); 52 | Log::write(LOG_INFO, "name: %s\n", _name.c_str()); 53 | 54 | string scriptName = _scriptPath.substr(_scriptPath.find_last_of('/') + 1); 55 | rootNode->addChild(new XMLNode("scriptName", scriptName)); 56 | string newScriptPath = dirPath + scriptName; 57 | if (_scriptPath != newScriptPath) 58 | { 59 | if (!IO::copyFile(_scriptPath, newScriptPath)) 60 | Log::write(LOG_ERROR, "Could not copy file \"%s\" to \"%s\" !\n", _scriptPath.c_str(), newScriptPath.c_str()); 61 | _scriptPath = newScriptPath; 62 | } 63 | Log::write(LOG_INFO, "scriptPath: %s\n", _scriptPath.c_str()); 64 | 65 | if (!xmlFile.save(dirPath + XML_FILE_NAME)) 66 | Log::write(LOG_ERROR, "Couldn't save script to the specified directory !\n"); 67 | 68 | Log::unIndent(); 69 | } 70 | 71 | void Script::parse(vector &declarations, vector &functions) 72 | { 73 | Log::write(LOG_INFO, "Parsing \"%s\"...\n", _scriptPath.c_str()); 74 | 75 | yyin = fopen(_scriptPath.c_str(), "r"); 76 | if (yyin == NULL) 77 | Log::write(LOG_ERROR, "Could not open script \"%s\" !\n", _scriptPath.c_str()); 78 | 79 | yylineno = 1; 80 | if (yyparse(declarations, functions)) 81 | { 82 | fclose(yyin); 83 | for (int j = 0; j < functions.size(); j++) 84 | delete functions[j]; 85 | Log::write(LOG_ERROR, "Parsing error !\n"); 86 | } 87 | else 88 | fclose(yyin); 89 | } 90 | 91 | Script::~Script() 92 | { 93 | } 94 | -------------------------------------------------------------------------------- /src/blocks/MAXS.cpp: -------------------------------------------------------------------------------- 1 | #include "MAXS.hpp" 2 | #include "util/IO.hpp" 3 | #include "types/Game.hpp" 4 | #include "types/Room.hpp" 5 | #include "grammar/Function.hpp" 6 | 7 | const uint8_t MAXS::UNKNOWN1 = 0; 8 | const uint16_t MAXS::N_BIT_VARIABLES = 2048; 9 | const uint8_t MAXS::N_LOCAL_OBJECTS = 200; 10 | const uint8_t MAXS::N_ARRAYS = 50; 11 | const uint8_t MAXS::UNKNOWN2 = 0; 12 | const uint8_t MAXS::N_VERBS = 50; 13 | const uint8_t MAXS::N_FL_OBJECTS = 5; 14 | const uint8_t MAXS::N_INVENTORIES = 80; 15 | 16 | MAXS::MAXS(Game *game) 17 | { 18 | _nVariables = Game::MAX_WORD_VARIABLES; 19 | _nBitVariables = N_BIT_VARIABLES; 20 | _nLocalObjects = N_LOCAL_OBJECTS; 21 | _nArrays = N_ARRAYS; 22 | _nVerbs = N_VERBS; 23 | _nFlObjects = N_FL_OBJECTS; 24 | _nInventories = N_INVENTORIES; 25 | _nRooms = game->getNumberOfRooms() + 1; 26 | _nScripts = 1; 27 | for (int i = 0; i < game->getNumberOfFunctions(); i++) 28 | if (game->getFunction(i)->getType() != FUNCTION_INLINED) 29 | _nScripts++; 30 | _nSounds = game->getNumberOfMidis() + 1; 31 | _nCharsets = game->getNumberOfCharsets() + 1; 32 | _nCostumes = game->getNumberOfCostumes() + 1; 33 | for (int i = 0; i < game->getNumberOfRooms(); i++) 34 | _nCostumes += game->getRoom(i)->getNumberOfCostumes(); 35 | _nGlobalObjects = Game::N_DEFAULT_ACTORS + game->getNumberOfObjects() + 1; 36 | for (int i = 0; i < game->getNumberOfRooms(); i++) 37 | _nGlobalObjects += game->getRoom(i)->getNumberOfObjects(); 38 | } 39 | 40 | uint32_t MAXS::getSize() 41 | { 42 | uint32_t size = 0; 43 | size += 4 * sizeof(uint8_t); // identifier 44 | size += sizeof(uint32_t); // size 45 | size += sizeof(uint16_t); // nVariables 46 | size += sizeof(uint16_t); // unknown 47 | size += sizeof(uint16_t); // nBitVariables 48 | size += sizeof(uint16_t); // nLocalObjects 49 | size += sizeof(uint16_t); // nArrays 50 | size += sizeof(uint16_t); // unknown 51 | size += sizeof(uint16_t); // nVerbs 52 | size += sizeof(uint16_t); // nFlObjects 53 | size += sizeof(uint16_t); // nInventories 54 | size += sizeof(uint16_t); // nRooms 55 | size += sizeof(uint16_t); // nScripts 56 | size += sizeof(uint16_t); // nSounds 57 | size += sizeof(uint16_t); // nCharsets 58 | size += sizeof(uint16_t); // nCostumes 59 | size += sizeof(uint16_t); // nGlobalObjects 60 | return size; 61 | } 62 | 63 | void MAXS::write(fstream &f) 64 | { 65 | IO::writeString(f, "MAXS"); 66 | IO::writeU32BE(f, getSize()); 67 | IO::writeU16LE(f, _nVariables); 68 | IO::writeU16LE(f, UNKNOWN1); 69 | IO::writeU16LE(f, _nBitVariables); 70 | IO::writeU16LE(f, _nLocalObjects); 71 | IO::writeU16LE(f, _nArrays); 72 | IO::writeU16LE(f, UNKNOWN2); 73 | IO::writeU16LE(f, _nVerbs); 74 | IO::writeU16LE(f, _nFlObjects); 75 | IO::writeU16LE(f, _nInventories); 76 | IO::writeU16LE(f, _nRooms); 77 | IO::writeU16LE(f, _nScripts); 78 | IO::writeU16LE(f, _nSounds); 79 | IO::writeU16LE(f, _nCharsets); 80 | IO::writeU16LE(f, _nCostumes); 81 | IO::writeU16LE(f, _nGlobalObjects); 82 | } 83 | 84 | MAXS::~MAXS() 85 | { 86 | } 87 | -------------------------------------------------------------------------------- /src/libscumm/vars.sgc: -------------------------------------------------------------------------------- 1 | var VAR_KEYPRESS @ 0; 2 | var VAR_EGO @ 1; 3 | var VAR_CAMERA_POS_X @ 2; 4 | var VAR_HAVE_MSG @ 3; 5 | var VAR_ROOM @ 4; 6 | var VAR_OVERRIDE @ 5; 7 | var VAR_MACHINE_SPEED @ 6; 8 | var VAR_ME @ 7; 9 | var VAR_NUM_ACTOR @ 8; 10 | var VAR_CURRENTDRIVE @ 10; 11 | var VAR_TMR_1 @ 11; 12 | var VAR_TMR_2 @ 12; 13 | var VAR_TMR_3 @ 13; 14 | var VAR_MUSIC_TIMER @ 14; 15 | var VAR_ACTOR_RANGE_MIN @ 15; 16 | var VAR_ACTOR_RANGE_MAX @ 16; 17 | var VAR_CAMERA_MIN_X @ 17; 18 | var VAR_CAMERA_MAX_X @ 18; 19 | var VAR_TIMER_NEXT @ 19; 20 | var VAR_VIRT_MOUSE_X @ 20; 21 | var VAR_VIRT_MOUSE_Y @ 21; 22 | var VAR_ROOM_RESOURCE @ 22; 23 | var VAR_LAST_SOUND @ 23; 24 | var VAR_CUTSCENEEXIT_KEY @ 24; 25 | var VAR_TALK_ACTOR @ 25; 26 | var VAR_CAMERA_FAST_X @ 26; 27 | var VAR_SCROLL_SCRIPT @ 27; 28 | var VAR_ENTRY_SCRIPT @ 28; 29 | var VAR_ENTRY_SCRIPT2 @ 29; 30 | var VAR_EXIT_SCRIPT @ 30; 31 | var VAR_EXIT_SCRIPT2 @ 31; 32 | var VAR_VERB_SCRIPT @ 32; 33 | var VAR_SENTENCE_SCRIPT @ 33; 34 | var VAR_INVENTORY_SCRIPT @ 34; 35 | var VAR_CUTSCENE_START_SCRIPT @ 35; 36 | var VAR_CUTSCENE_END_SCRIPT @ 36; 37 | var VAR_CHARINC @ 37; 38 | var VAR_WALKTO_OBJ @ 38; 39 | var VAR_DEBUGMODE @ 39; 40 | var VAR_HEAPSPACE @ 40; 41 | var VAR_RESTART_KEY @ 42; 42 | var VAR_PAUSE_KEY @ 43; 43 | var VAR_MOUSE_X @ 44; 44 | var VAR_MOUSE_Y @ 45; 45 | var VAR_TIMER @ 46; 46 | var VAR_TIMER_TOTAL @ 47; 47 | var VAR_SOUNDCARD @ 48; 48 | var VAR_VIDEOMODE @ 49; 49 | var VAR_ROOM_WIDTH @ 41; 50 | var VAR_MAINMENU_KEY @ 50; 51 | var VAR_FIXEDDISK @ 51; 52 | var VAR_CURSORSTATE @ 52; 53 | var VAR_USERPUT @ 53; 54 | var VAR_ROOM_HEIGHT @ 54; 55 | var VAR_SOUNDRESULT @ 56; 56 | var VAR_TALKSTOP_KEY @ 57; 57 | var VAR_FADE_DELAY @ 59; 58 | var VAR_VOICE_MODE @ 60; 59 | var VAR_SAVELOAD_SCRIPT @ 61; 60 | var VAR_SAVELOAD_SCRIPT2 @ 62; 61 | var VAR_SOUNDPARAM @ 64; 62 | var VAR_SOUNDPARAM2 @ 65; 63 | var VAR_SOUNDPARAM3 @ 66; 64 | var VAR_INPUTMODE @ 67; 65 | var VAR_MEMORY_PERFORMANCE @ 68; 66 | var VAR_VIDEO_PERFORMANCE @ 69; 67 | var VAR_ROOM_FLAG @ 70; 68 | var VAR_GAME_LOADED @ 71; 69 | var VAR_NEW_ROOM @ 72; 70 | var VAR_LEFTBTN_HOLD @ 74; 71 | var VAR_RIGHTBTN_HOLD @ 75; 72 | var VAR_V6_EMSSPACE @ 76; 73 | var VAR_INSERT_DISK_MSG @ 90; 74 | var VAR_ERROR_FINDING_DISK_MSG @ 91; 75 | var VAR_ERROR_READING_DISK_MSG @ 92; 76 | var VAR_PAUSE_MSG @ 93; 77 | var VAR_RESTART_MSG @ 94; 78 | var VAR_QUIT_MSG @ 95; 79 | var VAR_SAVE_BTN_STR @ 96; 80 | var VAR_LOAD_BTN_STR @ 97; 81 | var VAR_PLAY_BTN_STR @ 98; 82 | var VAR_CANCEL_BTN_STR @ 99; 83 | var VAR_QUIT_BTN_STR @ 100; 84 | var VAR_OK_BTN_STR @ 101; 85 | var VAR_INSERT_DISK_MENU_STR @ 102; 86 | var VAR_ERROR_ENTERING_NAME_MSG @ 103; 87 | var VAR_ERROR_SAVING_FILE_MSG @ 104; 88 | var VAR_ERROR_LOADING_FILE_MSG @ 105; 89 | var VAR_SAVING_MSG @ 106; 90 | var VAR_LOADING_MSG @ 107; 91 | var VAR_SAVE_MENU_STR @ 108; 92 | var VAR_LOAD_MENU_STR @ 109; 93 | var VAR_HELP_MSG @ 117; 94 | var VAR_RANDOM_NR @ 118; 95 | var VAR_TIMEDATE_YEAR @ 119; 96 | var VAR_TIMEDATE_HOUR @ 125; 97 | var VAR_TIMEDATE_MINUTE @ 126; 98 | var VAR_TIMEDATE_DAY @ 128; 99 | var VAR_TIMEDATE_MONTH @ 129; 100 | -------------------------------------------------------------------------------- /src/types/Costume.hpp: -------------------------------------------------------------------------------- 1 | #ifndef _COSTUME_HPP_ 2 | #define _COSTUME_HPP_ 3 | 4 | #include 5 | #include 6 | #include 7 | using namespace std; 8 | 9 | class Palette; 10 | class PaletteData; 11 | class XMLNode; 12 | 13 | typedef enum 14 | { 15 | ANIM_WEST, 16 | ANIM_EAST, 17 | ANIM_SOUTH, 18 | ANIM_NORTH 19 | } AnimDirection; 20 | 21 | class Anim 22 | { 23 | private: 24 | uint8_t _id; 25 | string _name; 26 | bool _loop; 27 | vector > _commands; 28 | 29 | void loadSubAnim(XMLNode *node, AnimDirection direction); 30 | void saveSubAnim(XMLNode *node, AnimDirection direction); 31 | public: 32 | static const uint8_t N_DIRECTIONS; 33 | 34 | Anim(); 35 | void load(XMLNode *node); 36 | void save(XMLNode *node); 37 | uint8_t getID() { return _id; } 38 | void setID(uint8_t id) { _id = id; } 39 | string getName() { return _name; } 40 | bool isLoop() { return _loop; } 41 | uint16_t getNumberOfCommands(AnimDirection direction) { return _commands[(int)direction].size(); } 42 | uint8_t getCommand(AnimDirection direction, uint16_t index) { return _commands[(int)direction][index]; } 43 | ~Anim(); 44 | }; 45 | 46 | class Frame 47 | { 48 | private: 49 | string _bitmapPath; 50 | uint16_t _x; 51 | uint16_t _y; 52 | uint16_t _width; 53 | uint16_t _height; 54 | int16_t _xOffset; 55 | int16_t _yOffset; 56 | vector > _pixels; 57 | public: 58 | Frame(); 59 | void load(XMLNode *node, string dirPath); 60 | void save(XMLNode *node, string dirPath); 61 | void prepare(Palette *palette, PaletteData *paletteData, vector &redirectionPalette); 62 | uint16_t getX() { return _x; } 63 | uint16_t getY() { return _y; } 64 | uint16_t getWidth() { return _width; } 65 | uint16_t getHeight() { return _height; } 66 | int16_t getXOffset() { return _xOffset; } 67 | int16_t getYOffset() { return _yOffset; } 68 | uint32_t getPixel(uint32_t x, uint32_t y) { return _pixels[x][y]; } 69 | ~Frame(); 70 | }; 71 | 72 | class Costume 73 | { 74 | private: 75 | static const string XML_FILE_NAME; 76 | 77 | uint16_t _id; 78 | string _name; 79 | uint16_t _width; 80 | uint16_t _height; 81 | bool _mirror; 82 | vector _anims; 83 | vector _frames; 84 | vector _redirectionPalette; 85 | PaletteData *_paletteData; 86 | public: 87 | Costume(); 88 | void load(string dirPath); 89 | void save(string dirPath); 90 | void prepare(Palette *palette); 91 | uint16_t getID() { return _id; } 92 | void setID(uint16_t id) { _id = id; } 93 | string getName() { return _name; } 94 | uint16_t getWidth() { return _width; } 95 | uint16_t getHeight() { return _height; } 96 | bool isMirror() { return _mirror; } 97 | uint32_t getNumberOfAnims() { return _anims.size(); } 98 | Anim *getAnim(uint32_t index) { return _anims[index]; } 99 | uint8_t getNumberOfFrames() { return _frames.size(); } 100 | Frame *getFrame(uint8_t index) { return _frames[index]; } 101 | uint8_t getNumberOfColors() { return _redirectionPalette.size(); } 102 | uint8_t getColor(uint8_t index) { return _redirectionPalette[index]; } 103 | ~Costume(); 104 | }; 105 | 106 | #endif 107 | -------------------------------------------------------------------------------- /src/grammar/Function.cpp: -------------------------------------------------------------------------------- 1 | #include "Function.hpp" 2 | #include 3 | #include "util/Log.hpp" 4 | #include "Context.hpp" 5 | #include "Declaration.hpp" 6 | #include "Instruction.hpp" 7 | #include "Statement.hpp" 8 | 9 | Function::Function(FunctionType type, string name, BlockStatement *blockS) 10 | { 11 | _type = type; 12 | _name = name; 13 | _blockStatement = blockS; 14 | _id = 0; // This member is filled later 15 | } 16 | 17 | void Function::removeLabels() 18 | { 19 | // First, we get the label instruction addresses and remove the corresponding instructions 20 | map labelAddresses; 21 | vector::iterator iterator = _instructions.begin(); 22 | while (iterator != _instructions.end()) 23 | if ((*iterator)->getType() == INSTRUCTION_LABEL) 24 | { 25 | labelAddresses[(*iterator)->getLabel()] = (*iterator)->getAddress(); 26 | delete (*iterator); 27 | iterator = _instructions.erase(iterator); 28 | } 29 | else 30 | iterator++; 31 | 32 | // Then, we replace labels by relative offsets 33 | for (int i = 0; i < _instructions.size(); i++) 34 | if (_instructions[i]->getType() == INSTRUCTION_VALUE && _instructions[i]->getValue().substr(0, 6) == "LABEL_") 35 | { 36 | uint32_t label; 37 | istringstream iss(_instructions[i]->getValue().substr(6)); 38 | iss >> label; 39 | // The magic 2 in this statement is because SCUMM jump/if/ifNot instructions 40 | // don't take the offset following them into account 41 | int32_t offset = (int32_t)labelAddresses[label] - (int32_t)_instructions[i]->getAddress() - 2; 42 | ostringstream oss; 43 | oss << offset; 44 | _instructions[i]->setValue(oss.str()); 45 | } 46 | } 47 | 48 | void Function::displayAssembly() 49 | { 50 | Log::write(LOG_INFO, "Function \"%s\" (id n°%u) assembly:\n", _name.c_str(), _id); 51 | Log::indent(); 52 | for (int i = 0; i < _instructions.size(); i++) 53 | Log::write(LOG_INFO, "%s\n", _instructions[i]->toString().c_str()); 54 | Log::unIndent(); 55 | } 56 | 57 | void Function::compile() 58 | { 59 | Log::write(LOG_INFO, "Compiling function \"%s\"...\n", _name.c_str()); 60 | Log::indent(); 61 | 62 | ContextType contextType; 63 | switch (_type) 64 | { 65 | case FUNCTION_NORMAL: 66 | contextType = CONTEXT_FUNCTION; 67 | break; 68 | case FUNCTION_THREAD: 69 | contextType = CONTEXT_THREAD; 70 | break; 71 | case FUNCTION_INLINED: 72 | Log::write(LOG_ERROR, "Can't compile inline functions !"); 73 | } 74 | 75 | Context context(contextType, &_arguments, NULL, -1, -1, 0); 76 | Context::pushContext(&context); 77 | 78 | // Prepare labels first 79 | Context::labelCounter++; 80 | 81 | // Compile block statement 82 | _blockStatement->compile(_instructions); 83 | 84 | // Return label (should always be LABEL_0) 85 | _instructions.push_back(new Instruction(0)); 86 | 87 | Context::popContext(); 88 | 89 | // stopObjectCode instruction 90 | _instructions.push_back(new Instruction("stopObjectCode")); 91 | 92 | displayAssembly(); 93 | 94 | // Replace labels by relative offsets 95 | removeLabels(); 96 | 97 | // Assemble instructions 98 | for (int i = 0; i < _instructions.size(); i++) 99 | _instructions[i]->assemble(_byteCode); 100 | 101 | Log::unIndent(); 102 | } 103 | 104 | Function::~Function() 105 | { 106 | for (int i = 0; i < _arguments.size(); i++) 107 | delete _arguments[i]; 108 | delete _blockStatement; 109 | for (int i = 0; i < _instructions.size(); i++) 110 | delete _instructions[i]; 111 | } 112 | 113 | -------------------------------------------------------------------------------- /src/libscumm/Verb.sgc: -------------------------------------------------------------------------------- 1 | inline function Verb_activate(var activate) 2 | { 3 | if (activate) 4 | asm 5 | { 6 | verbOps verbOn 7 | } 8 | else 9 | asm 10 | { 11 | verbOps verbOff 12 | } 13 | } 14 | 15 | inline function Verb_center() 16 | { 17 | asm 18 | { 19 | verbOps verbCenter 20 | } 21 | } 22 | 23 | inline function Verb_delete() 24 | { 25 | asm 26 | { 27 | verbOps verbDelete 28 | } 29 | } 30 | 31 | inline function Verb_dim() 32 | { 33 | asm 34 | { 35 | verbOps verbDim 36 | } 37 | } 38 | 39 | inline function Verb_doSentence(var vrb, var objA, var objB) 40 | { 41 | asm 42 | { 43 | pushWordVar .word vrb 44 | pushWordVar .word objA 45 | pushByte .byte 0 46 | pushWordVar .word objB 47 | doSentence 48 | } 49 | } 50 | 51 | inline function Verb_draw() 52 | { 53 | asm 54 | { 55 | verbOps verbDraw 56 | } 57 | } 58 | 59 | inline function Verb_getEntryPoint(var obj, var entry) 60 | { 61 | var entryPoint; 62 | asm 63 | { 64 | pushWordVar .word obj 65 | pushWordVar .word entry 66 | getVerbEntryPoint 67 | writeWordVar .word entryPoint 68 | } 69 | return entryPoint; 70 | } 71 | 72 | inline function Verb_getFromXY(var x, var y) 73 | { 74 | var over; 75 | asm 76 | { 77 | pushWordVar .word x 78 | pushWordVar .word y 79 | getVerbFromXY 80 | writeWordVar .word over 81 | } 82 | return over; 83 | } 84 | 85 | inline function Verb_new() 86 | { 87 | asm 88 | { 89 | verbOps verbNew 90 | } 91 | } 92 | 93 | inline function Verb_restore(var from, var to, var id) 94 | { 95 | asm 96 | { 97 | pushWordVar .word from 98 | pushWordVar .word to 99 | pushWordVar .word id 100 | saveRestoreVerbs restoreVerbs 101 | } 102 | } 103 | 104 | inline function Verb_save(var from, var to, var id) 105 | { 106 | asm 107 | { 108 | pushWordVar .word from 109 | pushWordVar .word to 110 | pushWordVar .word id 111 | saveRestoreVerbs saveVerbs 112 | } 113 | } 114 | 115 | inline function Verb_setBackColor(var color) 116 | { 117 | asm 118 | { 119 | pushWordVar .word color 120 | verbOps verbBackColor 121 | } 122 | } 123 | 124 | inline function Verb_setColor(var color) 125 | { 126 | asm 127 | { 128 | pushWordVar .word color 129 | verbOps verbColor 130 | } 131 | } 132 | 133 | inline function Verb_setCurrent(var vrb) 134 | { 135 | asm 136 | { 137 | pushWordVar .word vrb 138 | verbOps verbSetCurrent 139 | } 140 | } 141 | 142 | inline function Verb_setDimColor(var color) 143 | { 144 | asm 145 | { 146 | pushWordVar .word color 147 | verbOps verbDimColor 148 | } 149 | } 150 | 151 | inline function Verb_setHiColor(var color) 152 | { 153 | asm 154 | { 155 | pushWordVar .word color 156 | verbOps verbHiColor 157 | } 158 | } 159 | 160 | inline function Verb_setImageInCurrentRoom(var obj) 161 | { 162 | asm 163 | { 164 | pushWordVar .word obj 165 | verbOps verbImage 166 | } 167 | } 168 | 169 | inline function Verb_setImage(var obj) 170 | { 171 | const ROOM = 1; // Verb images should always be in room 1 172 | asm 173 | { 174 | pushWordVar .word obj 175 | pushWord .word ROOM 176 | verbOps verbImageInRoom 177 | } 178 | } 179 | 180 | inline function Verb_setKey(var key) 181 | { 182 | asm 183 | { 184 | pushWordVar .word key 185 | verbOps verbKey 186 | } 187 | } 188 | 189 | inline function Verb_setNameString(var name) 190 | { 191 | asm 192 | { 193 | pushWordVar .word name 194 | verbOps verbNameStr 195 | } 196 | } 197 | 198 | inline function Verb_setPos(var left, var top) 199 | { 200 | asm 201 | { 202 | pushWordVar .word left 203 | pushWordVar .word top 204 | verbOps verbAt 205 | } 206 | } 207 | 208 | inline function Verb_stopSentence() 209 | { 210 | asm 211 | { 212 | stopSentence 213 | } 214 | } 215 | -------------------------------------------------------------------------------- /src/blocks/ROOM.cpp: -------------------------------------------------------------------------------- 1 | #include "ROOM.hpp" 2 | #include "util/IO.hpp" 3 | #include "types/Game.hpp" 4 | #include "types/Room.hpp" 5 | #include "grammar/Function.hpp" 6 | #include "RMHD.hpp" 7 | #include "CYCL.hpp" 8 | #include "TRNS.hpp" 9 | #include "PALS.hpp" 10 | #include "RMIM.hpp" 11 | #include "OBIM.hpp" 12 | #include "OBCD.hpp" 13 | #include "EXCD.hpp" 14 | #include "ENCD.hpp" 15 | #include "NLSC.hpp" 16 | #include "LSCR.hpp" 17 | #include "BOXD.hpp" 18 | #include "BOXM.hpp" 19 | #include "SCAL.hpp" 20 | 21 | ROOM::ROOM(Game *game, uint8_t roomIndex) 22 | { 23 | Room *room = game->getRoom(roomIndex); 24 | 25 | _rmhd = new RMHD(game, roomIndex); 26 | _cycl = new CYCL(game->getPalette(), room->getPalette()); 27 | _trns = new TRNS(); 28 | _pals = new PALS(game->getPalette(), room->getPalette()); 29 | _rmim = new RMIM(room->getBackground()); 30 | 31 | // Add global objects to the first room 32 | if (room->getID() == 1) 33 | { 34 | for (int i = 0; i < game->getNumberOfObjects(); i++) 35 | _obims.push_back(new OBIM(game->getObject(i))); 36 | for (int i = 0; i < game->getNumberOfObjects(); i++) 37 | _obcds.push_back(new OBCD(game->getObject(i))); 38 | } 39 | 40 | for (int i = 0; i < room->getNumberOfObjects(); i++) 41 | _obims.push_back(new OBIM(room->getObject(i))); 42 | for (int i = 0; i < room->getNumberOfObjects(); i++) 43 | _obcds.push_back(new OBCD(room->getObject(i))); 44 | 45 | _excd = new EXCD(room->getExitFunction()); 46 | _encd = new ENCD(room->getEntryFunction()); 47 | _nlsc = new NLSC(room); 48 | for (int i = 0; i < room->getNumberOfFunctions(); i++) 49 | if (room->getFunction(i)->getType() != FUNCTION_INLINED) 50 | _lscrs.push_back(new LSCR(room->getFunction(i))); 51 | _boxd = new BOXD(room->getMap()); 52 | _boxm = new BOXM(); 53 | _scal = new SCAL(room->getMap()); 54 | } 55 | 56 | uint32_t ROOM::getSize() 57 | { 58 | uint32_t size = 0; 59 | size += 4 * sizeof(uint8_t); // identifier 60 | size += sizeof(uint32_t); // size 61 | size += _rmhd->getSize(); // rmhd 62 | size += _cycl->getSize(); // cycl 63 | size += _trns->getSize(); // trns 64 | size += _pals->getSize(); // pals 65 | size += _rmim->getSize(); // rmim 66 | for (int i = 0; i < _obims.size(); i++) // obims 67 | size += _obims[i]->getSize(); 68 | for (int i = 0; i < _obcds.size(); i++) // obcds 69 | size += _obcds[i]->getSize(); 70 | size += _excd->getSize(); // encd 71 | size += _encd->getSize(); // excd 72 | size += _nlsc->getSize(); // nlsc 73 | for (int i = 0; i < _lscrs.size(); i++) // lscrs 74 | size += _lscrs[i]->getSize(); 75 | size += _boxd->getSize(); // boxd 76 | size += _boxm->getSize(); // boxm 77 | size += _scal->getSize(); // scal 78 | return size; 79 | } 80 | 81 | void ROOM::write(fstream &f) 82 | { 83 | IO::writeString(f, "ROOM"); 84 | IO::writeU32BE(f, getSize()); 85 | _rmhd->write(f); 86 | _cycl->write(f); 87 | _trns->write(f); 88 | _pals->write(f); 89 | _rmim->write(f); 90 | for (int i = 0; i < _obims.size(); i++) 91 | _obims[i]->write(f); 92 | for (int i = 0; i < _obcds.size(); i++) 93 | _obcds[i]->write(f); 94 | _excd->write(f); 95 | _encd->write(f); 96 | _nlsc->write(f); 97 | for (int i = 0; i < _lscrs.size(); i++) 98 | _lscrs[i]->write(f); 99 | _boxd->write(f); 100 | _boxm->write(f); 101 | _scal->write(f); 102 | } 103 | 104 | ROOM::~ROOM() 105 | { 106 | delete _rmhd; 107 | delete _cycl; 108 | delete _trns; 109 | delete _pals; 110 | delete _rmim; 111 | for (int i = 0; i < _obims.size(); i++) 112 | delete _obims[i]; 113 | for (int i = 0; i < _obcds.size(); i++) 114 | delete _obcds[i]; 115 | delete _excd; 116 | delete _encd; 117 | delete _nlsc; 118 | for (int i = 0; i < _lscrs.size(); i++) 119 | delete _lscrs[i]; 120 | delete _boxd; 121 | delete _boxm; 122 | delete _scal; 123 | } 124 | -------------------------------------------------------------------------------- /src/libscumm/Script.sgc: -------------------------------------------------------------------------------- 1 | inline function Script_break() 2 | { 3 | asm 4 | { 5 | breakHere 6 | } 7 | } 8 | 9 | inline function Script_delay(var ticks) 10 | { 11 | asm 12 | { 13 | pushWordVar .word ticks 14 | delay 15 | } 16 | } 17 | 18 | inline function Script_delayFrames(var count) 19 | { 20 | asm 21 | { 22 | pushWordVar .word count 23 | delayFrames 24 | } 25 | } 26 | 27 | inline function Script_delayMinutes(var minutes) 28 | { 29 | asm 30 | { 31 | pushWordVar .word minutes 32 | delayMinutes 33 | } 34 | } 35 | 36 | inline function Script_delaySeconds(var seconds) 37 | { 38 | asm 39 | { 40 | pushWordVar .word seconds 41 | delaySeconds 42 | } 43 | } 44 | 45 | inline function Script_freeze(var flag) 46 | { 47 | asm 48 | { 49 | pushWordVar .word flag 50 | freezeUnfreeze 51 | } 52 | } 53 | 54 | inline function Script_isRoomScriptRunning(var obj) 55 | { 56 | var running; 57 | asm 58 | { 59 | pushWordVar .word obj 60 | isRoomScriptRunning 61 | writeWordVar .word running 62 | } 63 | return running; 64 | } 65 | 66 | inline function Script_isRunning(var script) 67 | { 68 | var running; 69 | asm 70 | { 71 | pushWordVar .word script 72 | isScriptRunning 73 | writeWordVar .word running 74 | } 75 | return running; 76 | } 77 | 78 | // TODO 79 | inline function Script_jumpTo() 80 | { 81 | } 82 | 83 | // TODO 84 | inline function Script_start() 85 | { 86 | } 87 | 88 | // TODO 89 | inline function Script_startObjectScript() 90 | { 91 | } 92 | 93 | inline function Script_startObjectScriptQuick(var obj, var vrb, var argv, var argc) 94 | { 95 | var i; 96 | var arg; 97 | asm 98 | { 99 | pushWordVar .word obj 100 | pushWordVar .word vrb 101 | } 102 | for (i = 0; i < argc; i++) 103 | { 104 | arg = argv[i]; 105 | asm 106 | { 107 | pushWordVar .word arg 108 | } 109 | } 110 | asm 111 | { 112 | pushWordVar .word argc 113 | startObjectQuick 114 | } 115 | } 116 | 117 | inline function Script_startQuick(var script, var args, var nArgs) 118 | { 119 | var i; 120 | var arg; 121 | 122 | // Push script 123 | asm 124 | { 125 | pushWordVar .word script 126 | } 127 | 128 | // Push arguments 129 | for (i = 0; i < nArgs; i++) 130 | { 131 | arg = args[i]; 132 | asm 133 | { 134 | pushWordVar .word arg 135 | } 136 | } 137 | 138 | // Push number of arguments and call opcode 139 | asm 140 | { 141 | pushWordVar .word nArgs 142 | startScriptQuick 143 | } 144 | } 145 | 146 | // TODO 147 | inline function Script_startQuick2() 148 | { 149 | } 150 | 151 | inline function Script_stop(var script) 152 | { 153 | asm 154 | { 155 | pushWordVar .word script 156 | stopScript 157 | } 158 | } 159 | 160 | inline function Script_stopObjectScript(var obj) 161 | { 162 | asm 163 | { 164 | pushWordVar .word obj 165 | stopObjectScript 166 | } 167 | } 168 | 169 | inline function Script_waitForActor(var act) 170 | { 171 | const OFFSET = 0xFFF9; 172 | asm 173 | { 174 | pushWordVar .word act 175 | wait waitForActor 176 | .word OFFSET 177 | } 178 | } 179 | 180 | inline function Script_waitForAnimation(var act) 181 | { 182 | const OFFSET = 0xFFF9; 183 | asm 184 | { 185 | pushWordVar .word act 186 | wait waitForAnimation 187 | .word OFFSET 188 | } 189 | } 190 | 191 | inline function Script_waitForCamera() 192 | { 193 | asm 194 | { 195 | wait waitForCamera 196 | } 197 | } 198 | 199 | inline function Script_waitForMessage() 200 | { 201 | asm 202 | { 203 | wait waitForMessage 204 | } 205 | } 206 | 207 | inline function Script_waitForSentence() 208 | { 209 | asm 210 | { 211 | wait waitForSentence 212 | } 213 | } 214 | 215 | inline function Script_waitForTurn(var act) 216 | { 217 | const OFFSET = 0xFFF9; 218 | asm 219 | { 220 | pushWordVar .word act 221 | wait waitForTurn 222 | .word OFFSET 223 | } 224 | } 225 | -------------------------------------------------------------------------------- /src/types/Charset.cpp: -------------------------------------------------------------------------------- 1 | #include "Charset.hpp" 2 | #include "util/IO.hpp" 3 | #include "util/Log.hpp" 4 | #include "util/XMLFile.hpp" 5 | 6 | const string Charset::XML_FILE_NAME = "charset.xml"; 7 | 8 | Char::Char(): 9 | _id(0), 10 | _x(0), 11 | _y(0), 12 | _width(0), 13 | _height(0), 14 | _xOffset(0), 15 | _yOffset(0) 16 | { 17 | } 18 | 19 | void Char::load(XMLNode *node) 20 | { 21 | _id = node->getChild("id")->getIntegerContent(); 22 | _x = node->getChild("x")->getIntegerContent(); 23 | _y = node->getChild("y")->getIntegerContent(); 24 | _width = node->getChild("width")->getIntegerContent(); 25 | _height = node->getChild("height")->getIntegerContent(); 26 | _xOffset = node->getChild("xOffset")->getIntegerContent(); 27 | _yOffset = node->getChild("yOffset")->getIntegerContent(); 28 | } 29 | 30 | void Char::save(XMLNode *node) 31 | { 32 | node->addChild(new XMLNode("id", _id)); 33 | node->addChild(new XMLNode("x", _x)); 34 | node->addChild(new XMLNode("y", _y)); 35 | node->addChild(new XMLNode("width", _width)); 36 | node->addChild(new XMLNode("height", _height)); 37 | node->addChild(new XMLNode("xOffset", _xOffset)); 38 | node->addChild(new XMLNode("yOffset", _yOffset)); 39 | } 40 | 41 | Charset::Charset(): 42 | _id(0), 43 | _name(""), 44 | _bitmapPath(""), 45 | _fontHeight(0) 46 | { 47 | } 48 | 49 | void Charset::load(string dirPath) 50 | { 51 | Log::write(LOG_INFO, "Charset\n"); 52 | Log::indent(); 53 | 54 | XMLFile xmlFile; 55 | xmlFile.open(dirPath + XML_FILE_NAME); 56 | XMLNode *rootNode = xmlFile.getRootNode(); 57 | 58 | _name = rootNode->getChild("name")->getStringContent(); 59 | Log::write(LOG_INFO, "name: %s\n", _name.c_str()); 60 | 61 | _bitmapPath = dirPath + rootNode->getChild("bitmapName")->getStringContent(); 62 | Log::write(LOG_INFO, "bitmapPath: %s\n", _bitmapPath.c_str()); 63 | 64 | _fontHeight = rootNode->getChild("fontHeight")->getIntegerContent(); 65 | Log::write(LOG_INFO, "fontHeight: %u\n", _fontHeight); 66 | 67 | int i = 0; 68 | XMLNode *child; 69 | while ((child = rootNode->getChild("char", i++)) != NULL) 70 | { 71 | Char *chr = new Char(); 72 | chr->load(child); 73 | _chars.push_back(chr); 74 | } 75 | 76 | Log::unIndent(); 77 | } 78 | 79 | void Charset::save(string dirPath) 80 | { 81 | Log::write(LOG_INFO, "Charset\n"); 82 | Log::indent(); 83 | 84 | if (!IO::createDirectory(dirPath)) 85 | Log::write(LOG_ERROR, "Could not create directory \"%s\" !\n", dirPath.c_str()); 86 | 87 | XMLFile xmlFile; 88 | XMLNode *rootNode = new XMLNode("charset"); 89 | xmlFile.setRootNode(rootNode); 90 | 91 | rootNode->addChild(new XMLNode("name", _name)); 92 | Log::write(LOG_INFO, "name: %s\n", _name.c_str()); 93 | 94 | string bitmapName = _bitmapPath.substr(_bitmapPath.find_last_of('/') + 1); 95 | rootNode->addChild(new XMLNode("bitmapName", bitmapName)); 96 | string newBitmapPath = dirPath + bitmapName; 97 | if (_bitmapPath != newBitmapPath) 98 | { 99 | if (!IO::copyFile(_bitmapPath, newBitmapPath)) 100 | Log::write(LOG_ERROR, "Could not copy file \"%s\" to \"%s\" !\n", _bitmapPath.c_str(), newBitmapPath.c_str()); 101 | _bitmapPath = newBitmapPath; 102 | } 103 | Log::write(LOG_INFO, "bitmapPath: %s\n", _bitmapPath.c_str()); 104 | 105 | 106 | rootNode->addChild(new XMLNode("fontHeight", _fontHeight)); 107 | Log::write(LOG_INFO, "fontHeight: %u\n", _fontHeight); 108 | 109 | for (int i = 0; i < _chars.size(); i++) 110 | { 111 | XMLNode *child = new XMLNode("char"); 112 | rootNode->addChild(child); 113 | _chars[i]->save(child); 114 | } 115 | 116 | if (!xmlFile.save(dirPath + XML_FILE_NAME)) 117 | Log::write(LOG_ERROR, "Couldn't save charset to the specified directory !\n"); 118 | 119 | Log::unIndent(); 120 | } 121 | 122 | Charset::~Charset() 123 | { 124 | for (int i = 0; i < _chars.size(); i++) 125 | delete _chars[i]; 126 | } 127 | -------------------------------------------------------------------------------- /src/types/Palette.hpp: -------------------------------------------------------------------------------- 1 | #ifndef _PALETTE_HPP_ 2 | #define _PALETTE_HPP_ 3 | 4 | #include 5 | #include 6 | #include 7 | #include "util/BMPFile.hpp" 8 | using namespace std; 9 | 10 | class XMLNode; 11 | 12 | class Area 13 | { 14 | private: 15 | string _name; 16 | uint8_t _start; 17 | uint8_t _end; 18 | public: 19 | Area(); 20 | void load(XMLNode *node); 21 | void save(XMLNode *node); 22 | string getName() { return _name; } 23 | void setName(string name) { _name = name; } 24 | uint8_t getStart() { return _start; } 25 | void setStart(uint8_t start) { _start = start; } 26 | uint8_t getEnd() { return _end; } 27 | void setEnd(uint8_t end) { _end = end; } 28 | ~Area(); 29 | }; 30 | 31 | class Cycle 32 | { 33 | private: 34 | uint8_t _id; 35 | string _name; 36 | uint8_t _start; 37 | uint8_t _end; 38 | uint8_t _delay; 39 | bool _forward; 40 | public: 41 | Cycle(); 42 | void load(XMLNode *node); 43 | void save(XMLNode *node); 44 | uint8_t getID() { return _id; } 45 | void setID(uint8_t id) { _id = id; } 46 | string getName() { return _name; } 47 | void setName(string name) { _name = name; } 48 | uint8_t getStart() { return _start; } 49 | void setStart(uint8_t start) { _start = start; } 50 | uint8_t getEnd() { return _end; } 51 | void setEnd(uint8_t end) { _end = end; } 52 | uint8_t getDelay() { return _delay; } 53 | void setDelay(uint8_t delay) { _delay = delay; } 54 | bool isForward() { return _forward; } 55 | void setForward(bool forward) { _forward = forward; } 56 | ~Cycle(); 57 | }; 58 | 59 | class PaletteData 60 | { 61 | private: 62 | static const string XML_FILE_NAME; 63 | 64 | bool _transparent; 65 | vector _areas; 66 | vector _cycles; 67 | public: 68 | PaletteData(); 69 | void load(string dirName); 70 | void save(string dirName); 71 | bool isTransparent() { return _transparent; } 72 | uint8_t getNumberOfAreas() { return _areas.size(); } 73 | Area *getArea(uint8_t index) { return _areas[index]; } 74 | uint8_t getNumberOfCycles() { return _cycles.size(); } 75 | Cycle *getCycle(uint8_t index) { return _cycles[index]; } 76 | ~PaletteData(); 77 | }; 78 | 79 | class Palette 80 | { 81 | private: 82 | static const string XML_FILE_NAME; 83 | static const uint8_t MAX_CYCLES; 84 | static const uint8_t N_EGA_COLORS; 85 | static const Color COLOR_BLACK; 86 | static const Color COLOR_DARK_BLUE; 87 | static const Color COLOR_JAPANESE_LAUREL; 88 | static const Color COLOR_PERSIAN_GREEN; 89 | static const Color COLOR_BRIGHT_RED; 90 | static const Color COLOR_FLIRT; 91 | static const Color COLOR_CHELSEA_GEM; 92 | static const Color COLOR_SILVER_CHALICE; 93 | static const Color COLOR_SCORPION; 94 | static const Color COLOR_DODGER_BLUE; 95 | static const Color COLOR_SCREAMIN_GREEN; 96 | static const Color COLOR_AQUAMARINE; 97 | static const Color COLOR_PERSIMMON; 98 | static const Color COLOR_PINK_FLAMINGO; 99 | static const Color COLOR_GORSE; 100 | static const Color COLOR_WHITE; 101 | 102 | bool _local; 103 | vector _colors; 104 | vector _areas; 105 | vector _cycles; 106 | uint16_t _cursor; 107 | vector _reserved; 108 | 109 | uint8_t addColor(Color *c, bool reserved); 110 | int16_t findColor(Color *c); 111 | public: 112 | static const uint16_t MAX_COLORS; 113 | 114 | Palette(bool local); 115 | void prepare(); 116 | void add(vector *colors, vector > &pixels, PaletteData *paletteData); 117 | Color getColor(uint8_t index) { return _colors[index]; } 118 | uint8_t getNumberOfAreas() { return _areas.size(); } 119 | Area *getArea(uint8_t index) { return _areas[index]; } 120 | uint8_t getNumberOfCycles() { return _cycles.size(); } 121 | Cycle *getCycle(uint8_t index) { return _cycles[index]; } 122 | uint16_t getCursor() { return _cursor; } 123 | ~Palette(); 124 | }; 125 | 126 | #endif 127 | -------------------------------------------------------------------------------- /src/grammar/lexer.ll: -------------------------------------------------------------------------------- 1 | %{ 2 | #include "types/Script.hpp" 3 | #include "util/Log.hpp" 4 | #include "Declaration.hpp" 5 | #include "Expression.hpp" 6 | #include "Function.hpp" 7 | #include "Statement.hpp" 8 | #include "parser.hh" 9 | 10 | // Local declarations 11 | int commentCaller; 12 | int parseString(); 13 | %} 14 | 15 | %option yylineno 16 | %option nounput 17 | %option noyywrap 18 | 19 | %x SINGLE_LINE_COMMENT 20 | %x MULTIPLE_LINES_COMMENT 21 | %x ASSEMBLY 22 | 23 | %% 24 | 25 | /* Common expressions */ 26 | "//" { commentCaller = INITIAL; BEGIN SINGLE_LINE_COMMENT; } 27 | "/*" { commentCaller = INITIAL; BEGIN MULTIPLE_LINES_COMMENT; } 28 | \" return parseString(); 29 | "const" return T_CONST; 30 | "var" return T_VAR; 31 | "enum" return T_ENUM; 32 | "actor" return T_ACTOR; 33 | "verb" return T_VERB; 34 | "class" return T_CLASS; 35 | "function" return T_FUNCTION; 36 | "inline" return T_INLINE; 37 | "thread" return T_THREAD; 38 | "if" return T_IF; 39 | "else" return T_ELSE; 40 | "switch" return T_SWITCH; 41 | "action" return T_ACTION; 42 | "case" return T_CASE; 43 | "default" return T_DEFAULT; 44 | "for" return T_FOR; 45 | "while" return T_WHILE; 46 | "do" return T_DO; 47 | "continue" return T_CONTINUE; 48 | "break" return T_BREAK; 49 | "return" return T_RETURN; 50 | "cutscene" return T_CUTSCENE; 51 | "try" return T_TRY; 52 | "catch" return T_CATCH; 53 | "finally" return T_FINALLY; 54 | "asm" { BEGIN ASSEMBLY; return T_ASSEMBLY; } 55 | ">=" return T_GE; 56 | "<=" return T_LE; 57 | "==" return T_EQ; 58 | "!=" return T_NE; 59 | "&&" return T_LAND; 60 | "||" return T_LOR; 61 | "+=" return T_INC; 62 | "-=" return T_DEC; 63 | "++" return T_UNI_INC; 64 | "--" return T_UNI_DEC; 65 | [-+()<>=*/;{},!&|@:\[\]] return *yytext; 66 | [0-9]+ { yylval.number = atoi(yytext); return T_NUMBER; } 67 | "0x"[a-fA-F0-9]+ { yylval.number = strtol(yytext, NULL, 16); return T_NUMBER; } 68 | [a-zA-Z_]+[a-zA-Z0-9_]* { strncpy(yylval.string, yytext, STRING_LENGTH); yylval.string[STRING_LENGTH - 1] = 0; return T_IDENTIFIER; } 69 | [ \n\t]|. ; 70 | 71 | /* Assembly expressions */ 72 | "//" { commentCaller = ASSEMBLY; BEGIN SINGLE_LINE_COMMENT; } 73 | "/*" { commentCaller = ASSEMBLY; BEGIN MULTIPLE_LINES_COMMENT; } 74 | "{" return *yytext; 75 | "}" { BEGIN INITIAL; return *yytext; } 76 | \" return parseString(); 77 | [-+]*[0-9]+ { sprintf(yylval.string, "%d", atoi(yytext)); return T_STRING; } 78 | "0x"[a-fA-F0-9]+ { sprintf(yylval.string, "%u", strtol(yytext, NULL, 16)); return T_STRING; } 79 | \'.\' { sprintf(yylval.string, "%u", (int)yytext[1]); return T_STRING; } 80 | \.*[a-zA-Z0-9_]+ { strncpy(yylval.string, yytext, STRING_LENGTH); yylval.string[STRING_LENGTH - 1] = 0; return T_STRING; } 81 | [ \n\t]|. ; 82 | 83 | /* Single line comments */ 84 | \n BEGIN commentCaller; 85 | . ; 86 | 87 | /* Multiple line comments */ 88 | "*/" BEGIN commentCaller; 89 | .|\n ; 90 | 91 | %% 92 | 93 | int parseString() 94 | { 95 | int lineNumber = yylineno; 96 | uint16_t i = 0; 97 | char c; 98 | char previous = 0; 99 | 100 | while ((i < STRING_LENGTH - 1) && (c = yyinput())) 101 | { 102 | if (c == '"' && previous != '\\') 103 | { 104 | yylval.string[i] = 0; 105 | return T_STRING; 106 | } 107 | 108 | // Add character to the resulting string 109 | yylval.string[i++] = c; 110 | previous = c; 111 | } 112 | if (c != '\"') 113 | Log::write(LOG_INFO, "Line %u: string length too long !\n", lineNumber); 114 | 115 | yylval.string[STRING_LENGTH - 1] = 0; 116 | return T_STRING; 117 | } 118 | -------------------------------------------------------------------------------- /src/types/Image.cpp: -------------------------------------------------------------------------------- 1 | #include "Image.hpp" 2 | #include "util/BMPFile.hpp" 3 | #include "util/IO.hpp" 4 | #include "util/Log.hpp" 5 | #include "util/XMLFile.hpp" 6 | #include "Palette.hpp" 7 | 8 | const string Image::XML_FILE_NAME = "image.xml"; 9 | 10 | Image::Image(): 11 | _name(""), 12 | _transparent(false), 13 | _bitmapPath(""), 14 | _width(0), 15 | _height(0) 16 | { 17 | } 18 | 19 | void Image::load(string dirPath) 20 | { 21 | Log::write(LOG_INFO, "Image\n"); 22 | Log::indent(); 23 | 24 | XMLFile xmlFile; 25 | xmlFile.open(dirPath + XML_FILE_NAME); 26 | XMLNode *rootNode = xmlFile.getRootNode(); 27 | 28 | _name = rootNode->getChild("name")->getStringContent(); 29 | Log::write(LOG_INFO, "name: %s\n", _name.c_str()); 30 | 31 | _bitmapPath = dirPath + rootNode->getChild("bitmapName")->getStringContent(); 32 | Log::write(LOG_INFO, "bitmapPath: %s\n", _bitmapPath.c_str()); 33 | 34 | int i = 0; 35 | XMLNode *child; 36 | while ((child = rootNode->getChild("zPlaneName", i++)) != NULL) 37 | _zPlanePaths.push_back(dirPath + child->getStringContent()); 38 | 39 | // Get width and height from bitmap 40 | BMPFile bmpFile; 41 | bmpFile.open(_bitmapPath); 42 | _width = bmpFile.getWidth(); 43 | _height = bmpFile.getHeight(); 44 | 45 | Log::unIndent(); 46 | } 47 | 48 | void Image::save(string dirPath) 49 | { 50 | Log::write(LOG_INFO, "Image\n"); 51 | Log::indent(); 52 | 53 | if (!IO::createDirectory(dirPath)) 54 | Log::write(LOG_ERROR, "Could not create directory \"%s\" !\n", dirPath.c_str()); 55 | 56 | XMLFile xmlFile; 57 | XMLNode *rootNode = new XMLNode("image"); 58 | xmlFile.setRootNode(rootNode); 59 | 60 | rootNode->addChild(new XMLNode("name", _name)); 61 | Log::write(LOG_INFO, "name: %s\n", _name.c_str()); 62 | 63 | string bitmapName = _bitmapPath.substr(_bitmapPath.find_last_of('/') + 1); 64 | rootNode->addChild(new XMLNode("bitmapName", bitmapName)); 65 | string newBitmapPath = dirPath + bitmapName; 66 | if (_bitmapPath != newBitmapPath) 67 | { 68 | if (!IO::copyFile(_bitmapPath, newBitmapPath)) 69 | Log::write(LOG_ERROR, "Could not copy file \"%s\" to \"%s\" !\n", _bitmapPath.c_str(), newBitmapPath.c_str()); 70 | _bitmapPath = newBitmapPath; 71 | } 72 | Log::write(LOG_INFO, "bitmapPath: %s\n", _bitmapPath.c_str()); 73 | 74 | for (int i = 0; i < _zPlanePaths.size(); i++) 75 | { 76 | string zPlaneName = _zPlanePaths[i].substr(_zPlanePaths[i].find_last_of('/') + 1); 77 | rootNode->addChild(new XMLNode("zPlaneName", zPlaneName)); 78 | string newZPlanePath = dirPath + zPlaneName; 79 | if (_zPlanePaths[i] != newZPlanePath) 80 | { 81 | if (!IO::copyFile(_zPlanePaths[i], newZPlanePath)) 82 | Log::write(LOG_ERROR, "Could not copy file \"%s\" to \"%s\" !\n", _zPlanePaths[i].c_str(), newZPlanePath.c_str()); 83 | _zPlanePaths[i] = newZPlanePath; 84 | } 85 | } 86 | 87 | if (!xmlFile.save(dirPath + XML_FILE_NAME)) 88 | Log::write(LOG_ERROR, "Couldn't save image to the specified directory !\n"); 89 | 90 | Log::unIndent(); 91 | } 92 | 93 | void Image::prepare(Palette *palette, PaletteData *paletteData) 94 | { 95 | Log::write(LOG_INFO, "Preparing image \"%s\"...\n", _name.c_str()); 96 | Log::indent(); 97 | 98 | // Set transparency 99 | _transparent = paletteData->isTransparent(); 100 | 101 | // Open original bitmap 102 | BMPFile bmpFile; 103 | bmpFile.open(_bitmapPath); 104 | 105 | // Get original palette from bitmap 106 | vector colors; 107 | for (int i = 0; i < bmpFile.getNumberOfColors(); i++) 108 | colors.push_back(bmpFile.getColor(i)); 109 | 110 | // Clear our pixel array 111 | _pixels.clear(); 112 | 113 | // Get pixels from bitmap 114 | for (int x = 0; x < _width; x++) 115 | { 116 | vector pixelColumn; 117 | for (int y = 0; y < _height; y++) 118 | pixelColumn.push_back(bmpFile.getPixel(x, y)); 119 | _pixels.push_back(pixelColumn); 120 | } 121 | 122 | // Add colors to palette (and update pixels) 123 | palette->add(&colors, _pixels, paletteData); 124 | 125 | Log::write(LOG_INFO, "Palette cursor: %u\n", palette->getCursor()); 126 | Log::unIndent(); 127 | } 128 | 129 | Image::~Image() 130 | { 131 | } 132 | -------------------------------------------------------------------------------- /src/util/IO.cpp: -------------------------------------------------------------------------------- 1 | #include "IO.hpp" 2 | #include 3 | #include 4 | #include 5 | 6 | uint8_t IO::_key; 7 | 8 | string IO::readString(fstream &f, uint8_t length) 9 | { 10 | string s(length, 0); 11 | for (int i = 0; i < length; i++) 12 | f.read(&s[i], 1); 13 | return s; 14 | } 15 | 16 | uint8_t IO::readU8(fstream &f) 17 | { 18 | uint8_t u8; 19 | f.read((char *)&u8, 1); 20 | return u8; 21 | } 22 | 23 | uint16_t IO::readU16LE(fstream &f) 24 | { 25 | uint16_t u16; 26 | f.read((char *)&u16, 2); 27 | return u16; 28 | } 29 | 30 | uint16_t IO::readU16BE(fstream &f) 31 | { 32 | uint16_t u16; 33 | uint8_t u8; 34 | f.read((char *)&u8, 1); 35 | u16 = u8 << 8; 36 | f.read((char *)&u8, 1); 37 | u16 |= u8; 38 | return u16; 39 | } 40 | 41 | uint32_t IO::readU32LE(fstream &f) 42 | { 43 | uint32_t u32; 44 | f.read((char *)&u32, 4); 45 | return u32; 46 | } 47 | 48 | uint32_t IO::readU32BE(fstream &f) 49 | { 50 | uint32_t u32; 51 | uint8_t u8; 52 | f.read((char *)&u8, 1); 53 | u32 = u8 << 24; 54 | f.read((char *)&u8, 1); 55 | u32 |= u8 << 16; 56 | f.read((char *)&u8, 1); 57 | u32 |= u8 << 8; 58 | f.read((char *)&u8, 1); 59 | u32 |= u8; 60 | return u32; 61 | } 62 | 63 | uint32_t IO::readBits(fstream &f, uint8_t &byte, uint8_t &bitPos, uint8_t nBits) 64 | { 65 | uint32_t result = 0; 66 | for (int i = nBits - 1; i >= 0; i--) 67 | { 68 | if (bitPos == 0) 69 | f.read((char *)&byte, 1); 70 | result |= ((byte >> (7 - bitPos)) & 0x01) << i; 71 | if (++bitPos == 8) 72 | bitPos = 0; 73 | } 74 | return result; 75 | } 76 | 77 | void IO::writeString(fstream &f, string s) 78 | { 79 | uint8_t data; 80 | for (int i = 0; i < s.length(); i++) 81 | { 82 | data = s[i] ^ _key; 83 | f.write((char *)&data, 1); 84 | } 85 | } 86 | 87 | void IO::writeU8(fstream &f, uint8_t data) 88 | { 89 | data ^= _key; 90 | f.write((char *)&data, 1); 91 | } 92 | 93 | void IO::writeU16LE(fstream &f, uint16_t data) 94 | { 95 | data ^= (_key << 8) | _key; 96 | f.write((char *)&data, 2); 97 | } 98 | 99 | void IO::writeU16BE(fstream &f, uint16_t data) 100 | { 101 | uint8_t u8; 102 | u8 = (data >> 8) ^ _key; 103 | f.write((char *)&u8, 1); 104 | u8 = data ^ _key; 105 | f.write((char *)&u8, 1); 106 | } 107 | 108 | void IO::writeU24LE(fstream &f, uint32_t data) 109 | { 110 | uint8_t u8; 111 | u8 = data ^ _key; 112 | f.write((char *)&u8, 1); 113 | u8 = (data >> 8) ^ _key; 114 | f.write((char *)&u8, 1); 115 | u8 = (data >> 16) ^ _key; 116 | f.write((char *)&u8, 1); 117 | } 118 | 119 | void IO::writeU24BE(fstream &f, uint32_t data) 120 | { 121 | uint8_t u8; 122 | u8 = (data >> 16) ^ _key; 123 | f.write((char *)&u8, 1); 124 | u8 = (data >> 8) ^ _key; 125 | f.write((char *)&u8, 1); 126 | u8 = data ^ _key; 127 | f.write((char *)&u8, 1); 128 | } 129 | 130 | void IO::writeU32LE(fstream &f, uint32_t data) 131 | { 132 | data ^= (_key << 24) | (_key << 16) | (_key << 8) | _key; 133 | f.write((char *)&data, 4); 134 | } 135 | 136 | void IO::writeU32BE(fstream &f, uint32_t data) 137 | { 138 | uint8_t u8; 139 | u8 = (data >> 24) ^ _key; 140 | f.write((char *)&u8, 1); 141 | u8 = (data >> 16) ^ _key; 142 | f.write((char *)&u8, 1); 143 | u8 = (data >> 8) ^ _key; 144 | f.write((char *)&u8, 1); 145 | u8 = data ^ _key; 146 | f.write((char *)&u8, 1); 147 | } 148 | 149 | void IO::writeBits(vector &v, uint8_t byte, uint32_t &bytePos, uint8_t &bitPos, uint8_t nBits) 150 | { 151 | for (int i = nBits - 1; i >= 0; i--) 152 | { 153 | if (bitPos == 0) 154 | v.push_back(0); 155 | v[bytePos] |= ((byte >> i) & 0x01) << (7 - bitPos); 156 | if (++bitPos == 8) 157 | { 158 | bytePos++; 159 | bitPos = 0; 160 | } 161 | } 162 | } 163 | 164 | bool IO::copyFile(string srcFileName, string destFileName) 165 | { 166 | ifstream ifs(srcFileName.c_str(), ios::in | ios::binary); 167 | if (!ifs.is_open()) 168 | return false; 169 | 170 | ofstream ofs(destFileName.c_str(), ios::out | ios::binary | ios::trunc); 171 | if (!ofs.is_open()) 172 | return false; 173 | 174 | ofs << ifs.rdbuf(); 175 | 176 | ifs.close(); 177 | ofs.close(); 178 | return true; 179 | } 180 | 181 | bool IO::createDirectory(string dirPath) 182 | { 183 | umask(0); 184 | return !(mkdir(dirPath.c_str(), 0777) != 0 && errno != EEXIST); 185 | } 186 | -------------------------------------------------------------------------------- /src/util/XMLFile.cpp: -------------------------------------------------------------------------------- 1 | #include "XMLFile.hpp" 2 | #include 3 | #include 4 | #include 5 | #include "Log.hpp" 6 | using namespace std; 7 | 8 | XMLNode::XMLNode(string name, string content) 9 | { 10 | _name = name; 11 | _content = content; 12 | } 13 | 14 | XMLNode::XMLNode(string name, int content) 15 | { 16 | _name = name; 17 | ostringstream oss; 18 | oss << content; 19 | _content = oss.str(); 20 | } 21 | 22 | XMLNode::XMLNode(string name, bool content) 23 | { 24 | _name = name; 25 | _content = content ? "true" : "false"; 26 | } 27 | 28 | XMLNode *XMLNode::getChild(string name, uint32_t index) 29 | { 30 | uint32_t childIndex = 0; 31 | for (int i = 0; i < _children.size(); i++) 32 | if (name == _children[i]->getName() && childIndex++ == index) 33 | return _children[i]; 34 | 35 | return NULL; 36 | } 37 | 38 | XMLNode::~XMLNode() 39 | { 40 | for (int i = 0; i < _children.size(); i++) 41 | delete _children[i]; 42 | } 43 | 44 | XMLFile::XMLFile(): 45 | _rootNode(NULL) 46 | { 47 | LIBXML_TEST_VERSION 48 | } 49 | 50 | void XMLFile::read(xmlNode *srcNode, XMLNode *&destNode) 51 | { 52 | string content = ""; 53 | if (srcNode->children != NULL && srcNode->children->content != NULL) 54 | content = (char *)srcNode->children->content; 55 | destNode = new XMLNode((char *)srcNode->name, content); 56 | 57 | for (xmlNode *childNode = srcNode->children; childNode != NULL; childNode = childNode->next) 58 | if (childNode->type == XML_ELEMENT_NODE) 59 | { 60 | XMLNode *node; 61 | read(childNode, node); 62 | destNode->addChild(node); 63 | } 64 | } 65 | 66 | void XMLFile::write(XMLNode *srcNode, xmlNode *&destNode, uint8_t indent) 67 | { 68 | string space; 69 | 70 | // Create new node 71 | destNode = xmlNewNode(NULL, (const xmlChar *)srcNode->getName().c_str()); 72 | xmlNode *childTextNode = xmlNewText((const xmlChar *)srcNode->getStringContent().c_str()); 73 | xmlAddChild(destNode, childTextNode); 74 | 75 | for (int i = 0; i < srcNode->getNumberOfChildren(); i++) 76 | { 77 | // Add new line if the current child is not the last one 78 | space = '\n'; 79 | for (int j = 0; j < (indent + 1); j++) 80 | space += '\t'; 81 | childTextNode = xmlNewText((const xmlChar *)space.c_str()); 82 | xmlAddChild(destNode, childTextNode); 83 | 84 | // Add child 85 | xmlNode *node; 86 | write(srcNode->getChild(i), node, indent + 1); 87 | node->type = XML_ELEMENT_NODE; 88 | xmlAddChild(destNode, node); 89 | } 90 | 91 | // Add new line if the node has children 92 | if (srcNode->getNumberOfChildren() > 0) 93 | { 94 | space = '\n'; 95 | for (int i = 0; i < indent; i++) 96 | space += '\t'; 97 | childTextNode = xmlNewText((const xmlChar *)space.c_str()); 98 | xmlAddChild(destNode, childTextNode); 99 | } 100 | } 101 | 102 | bool XMLFile::open(string fileName) 103 | { 104 | // Check if file exists 105 | ifstream f(fileName.c_str(), ios::in); 106 | if (!f.is_open()) 107 | { 108 | Log::write(LOG_WARNING, "Could not open file \"%s\" !\n", fileName.c_str()); 109 | f.close(); 110 | return false; 111 | } 112 | f.close(); 113 | 114 | // Read XML file 115 | xmlDocPtr doc = xmlParseFile(fileName.c_str()); 116 | 117 | // Read the root node and fill our own data types 118 | read(xmlDocGetRootElement(doc), _rootNode); 119 | 120 | xmlFreeDoc(doc); 121 | 122 | return true; 123 | } 124 | 125 | bool XMLFile::save(string fileName) 126 | { 127 | // Check the root node is valid 128 | if (_rootNode == NULL) 129 | { 130 | Log::write(LOG_WARNING, "Root node has not been created !\n"); 131 | return false; 132 | } 133 | 134 | // Create document and root node 135 | xmlDocPtr doc = xmlNewDoc((const xmlChar *)"1.0"); 136 | xmlNode *rootNode; 137 | 138 | // Read our own data types and fill the root node 139 | write(_rootNode, rootNode, 0); 140 | xmlDocSetRootElement(doc, rootNode); 141 | 142 | // Write XML File 143 | if (xmlSaveFile(fileName.c_str(), doc) == -1) 144 | { 145 | Log::write(LOG_WARNING, "Could not open file \"%s\" for writing !\n", fileName.c_str()); 146 | return false; 147 | } 148 | 149 | xmlFreeDoc(doc); 150 | 151 | return true; 152 | } 153 | 154 | XMLFile::~XMLFile() 155 | { 156 | if (_rootNode != NULL) 157 | delete _rootNode; 158 | 159 | xmlCleanupParser(); 160 | } 161 | -------------------------------------------------------------------------------- /src/libscumm/Object.sgc: -------------------------------------------------------------------------------- 1 | // Global constants 2 | const OBJECT_CLASS_NEVER_CLIP = 20; 3 | const OBJECT_CLASS_ALWAYS_CLIP = 21; 4 | const OBJECT_CLASS_IGNORE_BOXES= 22; 5 | const OBJECT_CLASS_Y_FLIP = 29; 6 | const OBJECT_CLASS_X_FLIP = 30; 7 | const OBJECT_CLASS_PLAYER = 31; 8 | const OBJECT_STATE_DISABLED = 0; 9 | const OBJECT_STATE_PICKABLE = 1; 10 | const OBJECT_STATE_UNTOUCHABLE = 2; 11 | const OBJECT_STATE_LOCKED = 4; 12 | const OBJECT_STATE_08 = 8; 13 | const OBJECT_OWNER_ROOM = 0xF; 14 | 15 | inline function Object_draw(var obj, var state) 16 | { 17 | asm 18 | { 19 | pushWordVar .word obj 20 | pushWordVar .word state 21 | drawObject 22 | } 23 | } 24 | 25 | inline function Object_drawAt(var obj, var x, var y) 26 | { 27 | asm 28 | { 29 | pushWordVar .word obj 30 | pushWordVar .word x 31 | pushByte .byte 8 32 | div 33 | pushWordVar .word y 34 | pushByte .byte 8 35 | div 36 | drawObjectAt 37 | } 38 | } 39 | 40 | inline function Object_drawBlast(var obj, var x, var y, var width, var height) 41 | { 42 | asm 43 | { 44 | pushWordVar .word obj 45 | pushWordVar .word x 46 | pushWordVar .word y 47 | pushWordVar .word width 48 | pushWordVar .word height 49 | drawBlastObject 50 | } 51 | } 52 | 53 | inline function Object_find(var x, var y) 54 | { 55 | var obj; 56 | asm 57 | { 58 | pushWordVar .word x 59 | pushWordVar .word y 60 | findObject 61 | writeWordVar .word obj 62 | } 63 | return obj; 64 | } 65 | 66 | inline function Object_findAll(var room) 67 | { 68 | var array; 69 | asm 70 | { 71 | pushWordVar .word room 72 | findAllObjects 73 | writeWordVar .word array 74 | } 75 | return array; 76 | } 77 | 78 | inline function Object_getNewDir(var obj) 79 | { 80 | var dir; 81 | asm 82 | { 83 | pushWordVar .word obj 84 | getObjectNewDir 85 | writeWordVar .word dir 86 | } 87 | return dir; 88 | } 89 | 90 | inline function Object_getOldDir(var obj) 91 | { 92 | var dir; 93 | asm 94 | { 95 | pushWordVar .word obj 96 | getObjectOldDir 97 | writeWordVar .word dir 98 | } 99 | return dir; 100 | } 101 | 102 | inline function Object_getOwner(var obj) 103 | { 104 | var owner; 105 | asm 106 | { 107 | pushWordVar .word obj 108 | getOwner 109 | writeWordVar .word owner 110 | } 111 | return owner; 112 | } 113 | 114 | inline function Object_getState(var obj) 115 | { 116 | var state; 117 | asm 118 | { 119 | pushWordVar .word obj 120 | getState 121 | writeWordVar .word state 122 | } 123 | return state; 124 | } 125 | 126 | inline function Object_getX(var obj) 127 | { 128 | var x; 129 | asm 130 | { 131 | pushWordVar .word obj 132 | getObjectX 133 | writeWordVar .word x 134 | } 135 | return x; 136 | } 137 | 138 | inline function Object_getY(var obj) 139 | { 140 | var y; 141 | asm 142 | { 143 | pushWordVar .word obj 144 | getObjectY 145 | writeWordVar .word y 146 | } 147 | return y; 148 | } 149 | 150 | 151 | inline function Object_isClassOf(var obj, var cls) 152 | { 153 | const SET_FLAG = 0x80; 154 | var res; 155 | cls += SET_FLAG; 156 | asm 157 | { 158 | pushWordVar .word obj 159 | pushWordVar .word cls 160 | pushByte .byte 1 161 | ifClassOfIs 162 | writeWordVar .word res 163 | } 164 | return res; 165 | } 166 | 167 | inline function Object_load(var obj, var room) 168 | { 169 | asm 170 | { 171 | pushWordVar .word obj 172 | pushWordVar .word room 173 | resourceRoutines loadObject 174 | } 175 | } 176 | 177 | inline function Object_setClass(var obj, var cls, var set) 178 | { 179 | const SET_FLAG = 0x80; 180 | if (set) 181 | cls += SET_FLAG; 182 | asm 183 | { 184 | pushWordVar .word obj 185 | pushWordVar .word cls 186 | pushByte .byte 1 187 | setClass 188 | } 189 | 190 | } 191 | 192 | inline function Object_setOwner(var obj, var owner) 193 | { 194 | asm 195 | { 196 | pushWordVar .word obj 197 | pushWordVar .word owner 198 | setOwner 199 | } 200 | } 201 | 202 | inline function Object_setState(var obj, var state) 203 | { 204 | asm 205 | { 206 | pushWordVar .word obj 207 | pushWordVar .word state 208 | setState 209 | } 210 | } 211 | 212 | inline function Object_stamp(var obj, var x, var y, var state) 213 | { 214 | asm 215 | { 216 | pushWordVar .word obj 217 | pushWordVar .word x 218 | pushWordVar .word y 219 | pushWordVar .word state 220 | stampObject 221 | } 222 | } 223 | -------------------------------------------------------------------------------- /src/types/Game.hpp: -------------------------------------------------------------------------------- 1 | #ifndef _GAME_HPP_ 2 | #define _GAME_HPP_ 3 | 4 | #include 5 | #include 6 | #include 7 | using namespace std; 8 | 9 | class XMLNode; 10 | class Palette; 11 | class Room; 12 | class Object; 13 | class Midi; 14 | class Costume; 15 | class Charset; 16 | class Voice; 17 | class Script; 18 | class Declaration; 19 | class Function; 20 | 21 | class Array 22 | { 23 | private: 24 | uint16_t _varNumber; 25 | uint16_t _dimA; 26 | uint16_t _dimB; 27 | uint16_t _type; 28 | public: 29 | Array(); 30 | void load(XMLNode *node); 31 | void save(XMLNode *node); 32 | uint16_t getVarNumber() { return _varNumber; } 33 | uint16_t getDimA() { return _dimA; } 34 | uint16_t getDimB() { return _dimB; } 35 | uint16_t getType() { return _type; } 36 | ~Array(); 37 | }; 38 | 39 | class Game 40 | { 41 | private: 42 | static const string XML_FILE_NAME; 43 | static const char *INDEX_FILE_EXTENSION; 44 | static const char *RESOURCE_FILE_EXTENSION; 45 | static const char *VOICE_FILE_NAME; 46 | static const string LIB_SCUMM_DIR_PATH; 47 | static const string ACTOR_SCRIPT_NAME; 48 | static const string INTERFACE_SCRIPT_NAME; 49 | static const string OBJECT_SCRIPT_NAME; 50 | static const string ROOM_SCRIPT_NAME; 51 | static const string SCRIPT_SCRIPT_NAME; 52 | static const string SOUND_SCRIPT_NAME; 53 | static const string UTIL_SCRIPT_NAME; 54 | static const string VARS_SCRIPT_NAME; 55 | static const string VERB_SCRIPT_NAME; 56 | 57 | string _name; 58 | string _description; 59 | uint8_t _key; 60 | Palette *_palette; 61 | vector _arrays; 62 | vector _rooms; 63 | vector _objects; 64 | vector