diff --git a/actor.cpp b/actor.cpp index 6acb0de0642..f8e9fa3765c 100644 --- a/actor.cpp +++ b/actor.cpp @@ -46,6 +46,7 @@ Actor::Actor(const char *name) : _constrain = false; _talkSoundName = ""; + strcpy(_colormap, DEFAULT_COLORMAP); for (int i = 0; i < 10; i++) { _talkCostume[i] = NULL; _talkChore[i] = -1; @@ -358,6 +359,8 @@ void Actor::shutUp() { void Actor::pushCostume(const char *name) { Costume *newCost = g_resourceloader->loadCostume(name, currentCostume()); + + newCost->setColormap(_colormap); _costumeStack.push_back(newCost); } diff --git a/actor.h b/actor.h index 6e90d0759bb..4bd11f5797e 100644 --- a/actor.h +++ b/actor.h @@ -26,6 +26,8 @@ #include #include +#define DEFAULT_COLORMAP "item.cmp" + class Costume; class LipSynch; class TextObject; @@ -71,6 +73,9 @@ public: void turn(int dir); void sayLine(const char *msg, const char *msgId); + // When we clean all text objects we don't want the actors to clean their + // objects again since they're already freed + void lineCleanup() { _sayLineText = NULL; } void shutUp(); bool talking(); @@ -80,6 +85,9 @@ public: void setTalkChore(int index, int choreNumber, Costume *cost); void setMumbleChore(int choreNumber, Costume *cost); + void setColormap(const char *map) { + strcpy(_colormap, map); + } void pushCostume(const char *name); void setCostume(const char *name); void popCostume(); @@ -125,6 +133,7 @@ private: Vector3d _pos; float _pitch, _yaw, _roll; float _walkRate, _turnRate; + char _colormap[256]; bool _constrain; // Constrain to walkboxes float _reflectionAngle; // Maximum angle to turn by at walls diff --git a/bitmap.cpp b/bitmap.cpp index 7aadb01b7e1..d3b6434b787 100644 --- a/bitmap.cpp +++ b/bitmap.cpp @@ -30,8 +30,10 @@ static void decompress_codec3(const char *compressed, char *result); Bitmap::Bitmap(const char *filename, const char *data, int len) : Resource(filename) { - if (len < 8 || memcmp(data, "BM F\0\0\0", 8) != 0) - error("Invalid magic loading bitmap\n"); + if (len < 8 || memcmp(data, "BM F\0\0\0", 8) != 0) { + if (debugLevel == DEBUG_BITMAPS || debugLevel == DEBUG_ERROR || debugLevel == DEBUG_ALL) + error("Invalid magic loading bitmap\n"); + } strcpy(_filename, filename); @@ -79,6 +81,8 @@ Bitmap::Bitmap(const char *filename, const char *data, int len) : Bitmap::Bitmap(const char *data, int width, int height, const char *filename) : Resource(filename) { + if (debugLevel == DEBUG_BITMAPS || debugLevel == DEBUG_NORMAL || debugLevel == DEBUG_ALL) + printf("New bitmap loaded: %s\n", filename); strcpy(_filename, filename); _currImage = 1; _numImages = 1; diff --git a/costume.cpp b/costume.cpp index 36ce9dce9ff..891752e983a 100644 --- a/costume.cpp +++ b/costume.cpp @@ -93,8 +93,8 @@ class BitmapComponent : public Costume::Component { public: - BitmapComponent(Costume::Component *parent, int parentID, const char *filename); - + BitmapComponent(Costume::Component *parent, int parentID, const char *filename, char *tag); + void setMapName(char *map) { } void setKey(int val); private: @@ -103,8 +103,19 @@ private: class ModelComponent : public Costume::Component { public: - ModelComponent(Costume::Component *parent, int parentID, const char *filename); + ModelComponent(Costume::Component *parent, int parentID, const char *filename, char *tag); void init(); + CMap *cmap() { return _cmap; } + char *colormap() { return _colormap; } + void setMapName(char *map) { + if (!strcmp(map, DEFAULT_COLORMAP) || !strcmp(map, _colormap)) + return; + _colormap = map; + if (_obj != NULL) { + _cmap = g_resourceloader->loadColormap(_colormap); + _obj->reload(*_cmap); + } + } void setKey(int val); void update(); void reset(); @@ -116,6 +127,7 @@ public: void draw(); protected: + char *_colormap; std::string _filename; ResPtr _obj; ResPtr _cmap; @@ -125,8 +137,8 @@ protected: class MainModelComponent : public ModelComponent { public: - MainModelComponent(Costume::Component *parent, int parentID, const char *filename); - MainModelComponent(const char *filename, Model *prevObj, Model::HierNode *prevHier); + MainModelComponent(Costume::Component *parent, int parentID, const char *filename, char *tag); + MainModelComponent(const char *filename, Model *prevObj, Model::HierNode *prevHier, char *tag); void init(); void update(); void reset(); @@ -140,8 +152,10 @@ private: class MeshComponent : public Costume::Component { public: - MeshComponent(Costume::Component *parent, int parentID, const char *name); + MeshComponent(Costume::Component *parent, int parentID, const char *name, char *tag); void init(); + CMap *cmap() { return ((ModelComponent *) _parent)->cmap();} + void setMapName(char *) { } void setKey(int val); void update(); void reset(); @@ -152,36 +166,76 @@ public: Model::HierNode *node() { return _node; } private: + std::string _name; int _num; Model::HierNode *_node; Matrix4 _matrix; }; -BitmapComponent::BitmapComponent(Costume::Component *parent, int parentID, const char *filename) : - Costume::Component(parent, parentID), _filename(filename) { +BitmapComponent::BitmapComponent(Costume::Component *parent, int parentID, const char *filename, char *tag) : + Costume::Component(parent, parentID, tag), _filename(filename) { } void BitmapComponent::setKey(int val) { - ObjectState *state = g_engine->currScene()->findState(_filename.c_str()); + const char *bitmap = _filename.c_str(); + ObjectState *state = g_engine->currScene()->findState(bitmap); - if (state != NULL) + if (state != NULL) { state->setNumber(val); - else - warning("Couldn't find bitmap %s in current scene\n", _filename.c_str()); + return; + } + // Complain that we couldn't find the bitmap. This means we probably + // didn't handle something correctly. Example: Before the tube-switcher + // bitmaps were not loading with the scene. This was because they were requested + // as a different case then they were stored (tu_0_dorcu_door_open versus + // TU_0_DORCU_door_open), which was causing problems in the string comparison. + if(debugLevel == DEBUG_BITMAPS || debugLevel == DEBUG_WARN || debugLevel == DEBUG_ALL) + warning("Missing scene bitmap: %s\n", bitmap); + +/* In case you feel like drawing the missing bitmap anyway... + // Assume that all objects the scene file forgot about are OBJSTATE_STATE class + state = new ObjectState(0, ObjectState::OBJSTATE_STATE, bitmap, NULL, true); + if (state == NULL) { + if (debugLevel == DEBUG_BITMAPS || debugLevel == DEBUG_WARN || debugLevel == DEBUG_ALL) + warning("Couldn't find bitmap %s in current scene\n", _filename.c_str()); + return; + } + g_engine->currScene()->addObjectState(state); + state->setNumber(val); +*/ } -ModelComponent::ModelComponent(Costume::Component *parent, int parentID, const char *filename) : - Costume::Component(parent, parentID), _filename(filename), _obj(NULL), _cmap(NULL), _hier(NULL) { +ModelComponent::ModelComponent(Costume::Component *parent, int parentID, const char *filename, char *tag) : + Costume::Component(parent, parentID, tag), _filename(filename), _obj(NULL), _cmap(NULL), + _colormap(DEFAULT_COLORMAP), _hier(NULL) { } void ModelComponent::init() { + // Skip loading if it was initialized + // by the sharing MainModelComponent + // constructor before if (_obj == NULL) { - // Skip loading if it was initialized - // by the sharing MainModelComponent - // constructor before + // Special case for climbing the rope (it's screwed up) + // TODO: Find out a real fix for this + if(!strcmp(_filename.c_str(), "ma_climb_suit.3do")) + _colormap = "suit.cmp"; + + // If we don't have the necessary color data, check to see + // if the parent object does (for painting faces) + if (_cmap == NULL && _parent != NULL) { + MeshComponent *parent = dynamic_cast(_parent); + CMap *cmap = parent->cmap(); + + if (cmap != NULL) + _cmap = cmap; + } + + // Get the colormap if (_cmap == NULL) { - warning("No colormap specified for %s\n", _filename.c_str()); - _cmap = g_resourceloader->loadColormap("item.cmp"); + if (_colormap == DEFAULT_COLORMAP && (debugLevel == DEBUG_MODEL || debugLevel == DEBUG_WARN || debugLevel == DEBUG_ALL)) + warning("No colormap specified for %s, using %s\n", _filename.c_str(), _colormap); + + _cmap = g_resourceloader->loadColormap(_colormap); } _obj = g_resourceloader->loadModel(_filename.c_str(), *_cmap); _hier = _obj->copyHierarchy(); @@ -192,9 +246,10 @@ void ModelComponent::init() { // parent object's tree. if (_parent != NULL) { MeshComponent *mc = dynamic_cast(_parent); + if (mc != NULL) mc->node()->addChild(_hier); - else + else if (debugLevel == DEBUG_MODEL || debugLevel == DEBUG_WARN || debugLevel == DEBUG_ALL) warning("Parent of model %s wasn't a mesh\n", _filename.c_str()); } } @@ -222,6 +277,8 @@ void ModelComponent::reset() { void ModelComponent::setColormap(CMap *c) { _cmap = c; + if (_obj != NULL && _cmap != NULL) + _obj->reload(*_cmap); } ModelComponent::~ModelComponent() { @@ -238,13 +295,14 @@ void ModelComponent::draw() { _hier->draw(); } -MainModelComponent::MainModelComponent(Costume::Component *parent, int parentID, const char *filename) : - ModelComponent(parent, parentID, filename), _hierShared(false) { +MainModelComponent::MainModelComponent(Costume::Component *parent, int parentID, const char *filename, char *tag) : + ModelComponent(parent, parentID, filename, tag), _hierShared(false) { } // Constructor used if sharing the main model with the previous costume -MainModelComponent::MainModelComponent(const char *filename, Model *prevObj, Model::HierNode *prevHier) : - ModelComponent(NULL, -1, filename), _hierShared(true) { +MainModelComponent::MainModelComponent(const char *filename, Model *prevObj, Model::HierNode *prevHier, char *tag) : + ModelComponent(NULL, -1, filename, tag), _hierShared(true) { + _obj = prevObj; _hier = prevHier; } @@ -273,30 +331,32 @@ MainModelComponent::~MainModelComponent() { class ColormapComponent : public Costume::Component { public: - ColormapComponent(Costume::Component *parent, int parentID, const char *filename); + ColormapComponent(Costume::Component *parent, int parentID, const char *filename, char *tag); ColormapComponent *copy(Costume::Component *newParent); + void setMapName(char *) { } ~ColormapComponent(); private: ResPtr _cmap; }; -ColormapComponent::ColormapComponent(Costume::Component *parent, int parentID, const char *filename) : - Costume::Component(parent, parentID) { +ColormapComponent::ColormapComponent(Costume::Component *parent, int parentID, const char *filename, char *tag) : + Costume::Component(parent, parentID, tag) { _cmap = g_resourceloader->loadColormap(filename); - + ModelComponent *mc = dynamic_cast(parent); if (mc != NULL) mc->setColormap(_cmap); - } +} ColormapComponent::~ColormapComponent() { } class KeyframeComponent : public Costume::Component { public: - KeyframeComponent(Costume::Component *parent, int parentID, const char *filename); + KeyframeComponent(Costume::Component *parent, int parentID, const char *filename, char *tag); void init(); + void setMapName(char *) { } void setKey(int val); void update(); void reset(); @@ -311,8 +371,8 @@ private: int _currTime; }; -KeyframeComponent::KeyframeComponent(Costume::Component *parent, int parentID, const char *filename) : - Costume::Component(parent, parentID), _priority1(1), _priority2(5), _hier(NULL), _active(false) { +KeyframeComponent::KeyframeComponent(Costume::Component *parent, int parentID, const char *filename, char *tag) : + Costume::Component(parent, parentID, tag), _priority1(1), _priority2(5), _hier(NULL), _active(false) { const char *comma = std::strchr(filename, ','); if (comma != NULL) { std::string realName(filename, comma); @@ -338,7 +398,8 @@ void KeyframeComponent::setKey(int val) { _active = false; break; default: - warning("Unknown key %d for keyframe %s\n", val, _keyf->filename()); + if (debugLevel == DEBUG_MODEL || debugLevel == DEBUG_WARN || debugLevel == DEBUG_ALL) + warning("Unknown key %d for keyframe %s\n", val, _keyf->filename()); } } @@ -372,7 +433,8 @@ void KeyframeComponent::update() { _currTime = animLength; break; default: - warning("Unknown repeat mode %d for keyframe %s\n", _repeatMode, _keyf->filename()); + if (debugLevel == DEBUG_MODEL || debugLevel == DEBUG_WARN || debugLevel == DEBUG_ALL) + warning("Unknown repeat mode %d for keyframe %s\n", _repeatMode, _keyf->filename()); } } _keyf->animate(_hier, _currTime / 1000.0, _priority1, _priority2); @@ -383,15 +445,17 @@ void KeyframeComponent::init() { if (mc != NULL) _hier = mc->hierarchy(); else { - warning("Parent of %s was not a model\n", _keyf->filename()); + if (debugLevel == DEBUG_MODEL || debugLevel == DEBUG_WARN || debugLevel == DEBUG_ALL) + warning("Parent of %s was not a model\n", _keyf->filename()); _hier = NULL; } } -MeshComponent::MeshComponent(Costume::Component *parent, int parentID, const char *name) : - Costume::Component(parent, parentID), _node(NULL) { +MeshComponent::MeshComponent(Costume::Component *parent, int parentID, const char *name, char *tag) : + Costume::Component(parent, parentID, tag), _name(name), _node(NULL) { if (std::sscanf(name, "mesh %d", &_num) < 1) error("Couldn't parse mesh name %s\n", name); + } void MeshComponent::init() { @@ -399,7 +463,8 @@ void MeshComponent::init() { if (mc != NULL) _node = mc->hierarchy() + _num; else { - warning("Parent of mesh %d was not a model\n", _num); + if (debugLevel == DEBUG_MODEL || debugLevel == DEBUG_WARN || debugLevel == DEBUG_ALL) + warning("Parent of mesh %d was not a model\n", _num); _node = NULL; } } @@ -419,9 +484,10 @@ void MeshComponent::update() { class MaterialComponent : public Costume::Component { public: - MaterialComponent(Costume::Component *parent, int parentID, const char *filename); + MaterialComponent(Costume::Component *parent, int parentID, const char *filename, char *tag); void init(); void setKey(int val); + void setMapName(char *) { } void setupTexture(); void reset(); ~MaterialComponent() { } @@ -429,20 +495,35 @@ public: private: ResPtr _mat; std::string _filename; + char *_colormap; int _num; }; -MaterialComponent::MaterialComponent(Costume::Component *parent, int parentID, const char *filename) : - Costume::Component(parent, parentID), _filename(filename), _num(0) { - warning("Constructing MaterialComponent %s\n", filename); +MaterialComponent::MaterialComponent(Costume::Component *parent, int parentID, const char *filename, char *tag) : + Costume::Component(parent, parentID, tag), _filename(filename), _colormap(DEFAULT_COLORMAP), + _num(0) { + + if (debugLevel == DEBUG_MODEL || debugLevel == DEBUG_WARN || debugLevel == DEBUG_ALL) + warning("Constructing MaterialComponent %s\n", filename); } void MaterialComponent::init() { - warning("MaterialComponent::init on %s\n", _filename.c_str()); - // The parent model and thus all its textures should have been - // loaded by now, so passing an arbitrary colormap here - // shouldn't cause problems. - ResPtr cmap = g_resourceloader->loadColormap("item.cmp"); + ModelComponent *mc = dynamic_cast(_parent); + ResPtr cmap; + + // If the object doesn't have a colormap then get the parent's colormap + // this happens a lot with actor heads, the first head "object" will have + // a colormap but the other objects (different facial expressions) will not + if (_colormap == DEFAULT_COLORMAP && mc != NULL) + cmap = mc->cmap(); + + if (cmap == NULL) { + // Use the default colormap if we're still drawing a blank + if (_colormap == DEFAULT_COLORMAP && (debugLevel == DEBUG_MODEL || debugLevel == DEBUG_WARN || debugLevel == DEBUG_ALL)) + warning("MaterialComponent::init on %s\n", _filename.c_str()); + + cmap = g_resourceloader->loadColormap(_colormap); + } _mat = g_resourceloader->loadMaterial(_filename.c_str(), *cmap); } @@ -460,7 +541,8 @@ void MaterialComponent::reset() { class LuaVarComponent : public Costume::Component { public: - LuaVarComponent(Costume::Component *parent, int parentID, const char *name); + LuaVarComponent(Costume::Component *parent, int parentID, const char *name, char *tag); + void setMapName(char *) { } void setKey(int val); ~LuaVarComponent() { } @@ -468,8 +550,8 @@ private: std::string _name; }; -LuaVarComponent::LuaVarComponent(Costume::Component *parent, int parentID, const char *name) : - Costume::Component(parent, parentID), _name(name) { +LuaVarComponent::LuaVarComponent(Costume::Component *parent, int parentID, const char *name, char *tag) : + Costume::Component(parent, parentID, tag), _name(name) { } void LuaVarComponent::setKey(int val) { @@ -479,7 +561,8 @@ void LuaVarComponent::setKey(int val) { class SoundComponent : public Costume::Component { public: - SoundComponent(Costume::Component *parent, int parentID, const char *name); + SoundComponent(Costume::Component *parent, int parentID, const char *name, char *tag); + void setMapName(char *) { } void setKey(int val); void reset(); ~SoundComponent() { } @@ -488,8 +571,8 @@ private: std::string _soundName; }; -SoundComponent::SoundComponent(Costume::Component *parent, int parentID, const char *filename) : - Costume::Component(parent, parentID) { +SoundComponent::SoundComponent(Costume::Component *parent, int parentID, const char *filename, char *tag) : + Costume::Component(parent, parentID, tag) { const char *comma = std::strchr(filename, ','); if (comma != NULL) { _soundName = std::string(filename, comma); @@ -518,7 +601,8 @@ void SoundComponent::setKey(int val) { g_imuse->setHookId(_soundName.c_str(), 0x80); break; default: - warning("Unknown key %d for sound %s\n", val, _soundName.c_str()); + if (debugLevel == DEBUG_MODEL || debugLevel == DEBUG_WARN || debugLevel == DEBUG_ALL) + warning("Unknown key %d for sound %s\n", val, _soundName.c_str()); } } @@ -527,8 +611,9 @@ void SoundComponent::reset() { } Costume::Costume(const char *filename, const char *data, int len, Costume *prevCost) : - _fname(filename) { + _fname(filename), _colormap(DEFAULT_COLORMAP) { TextSplitter ts(data, len); + ts.expectString("costume v0.1"); ts.expectString("section tags"); int numTags; @@ -557,7 +642,7 @@ Costume::Costume(const char *filename, const char *data, int len, Costume *prevC if (id == 0 && prevCost != NULL && std::memcmp(tags[tagID], "mmdl", 4) == 0) { MainModelComponent *mmc = dynamic_cast(prevCost->_components[0]); if (mmc != NULL && mmc->_filename == std::string(line + namePos)) { - _components[id] = new MainModelComponent(line + namePos, mmc->_obj, mmc->_hier); + _components[id] = new MainModelComponent(line + namePos, mmc->_obj, mmc->_hier, "mmdl"); continue; } } @@ -565,6 +650,11 @@ Costume::Costume(const char *filename, const char *data, int len, Costume *prevC _components[id] = loadComponent(tags[tagID], parentID == -1 ? NULL : _components[parentID], parentID, line + namePos); } + for (int i = 0; i < _numComponents; i++) { + if (_components[i] != NULL) + _components[i]->setCostume(this); + } + delete[] tags; for (int i = 0; i < _numComponents; i++) @@ -581,7 +671,8 @@ Costume::Costume(const char *filename, const char *data, int len, Costume *prevC _chores[id]._length = length; _chores[id]._numTracks = tracks; std::memcpy(_chores[id]._name, name, 32); - printf("Loaded chore: %s\n", name); + if(debugLevel == DEBUG_ALL || debugLevel == DEBUG_CHORES) + printf("Loaded chore: %s\n", name); } ts.expectString("section keys"); @@ -599,9 +690,11 @@ Costume::~Costume() { delete[] _chores; } -Costume::Component::Component(Component *parent, int parentID) { +Costume::Component::Component(Component *parent, int parentID, char *tag) { _parentID = parentID; + _cost = NULL; setParent(parent); + memcpy(_tag, tag, 4); } void Costume::Component::setParent(Component *newParent) { @@ -675,6 +768,20 @@ void Costume::Chore::setKeys(int startTime, int stopTime) { } } +void Costume::Chore::setLastFrame() { + // If the chore has already played then don't set it to the end + // Example: This executing would result in Glottis being + // choppy when he hands Manny the work order + if (_hasPlayed) + return; + _currTime = _length; + _playing = false; + _hasPlayed = true; + _looping = false; + setKeys(-1, _currTime); + _currTime = -1; +} + void Costume::Chore::update() { if (!_playing) return; @@ -702,23 +809,23 @@ void Costume::Chore::update() { Costume::Component *Costume::loadComponent (char tag[4], Costume::Component *parent, int parentID, const char *name) { if (std::memcmp(tag, "mmdl", 4) == 0) - return new MainModelComponent(parent, parentID, name); + return new MainModelComponent(parent, parentID, name, tag); else if (std::memcmp(tag, "modl", 4) == 0) - return new ModelComponent(parent, parentID, name); + return new ModelComponent(parent, parentID, name, tag); else if (std::memcmp(tag, "cmap", 4) == 0) - return new ColormapComponent(parent, parentID, name); + return new ColormapComponent(parent, parentID, name, tag); else if (std::memcmp(tag, "keyf", 4) == 0) - return new KeyframeComponent(parent, parentID, name); + return new KeyframeComponent(parent, parentID, name, tag); else if (std::memcmp(tag, "mesh", 4) == 0) - return new MeshComponent(parent, parentID, name); + return new MeshComponent(parent, parentID, name, tag); else if (std::memcmp(tag, "luav", 4) == 0) - return new LuaVarComponent(parent, parentID, name); + return new LuaVarComponent(parent, parentID, name, tag); else if (std::memcmp(tag, "imls", 4) == 0) - return new SoundComponent(parent, parentID, name); + return new SoundComponent(parent, parentID, name, tag); else if (std::memcmp(tag, "bknd", 4) == 0) - return new BitmapComponent(parent, parentID, name); + return new BitmapComponent(parent, parentID, name, tag); else if (std::memcmp(tag, "mat ", 4) == 0) - return new MaterialComponent(parent, parentID, name); + return new MaterialComponent(parent, parentID, name, tag); else if (std::memcmp(tag, "sprt", 4) == 0) return NULL;// new SpriteComponent(parent, parentID, name); diff --git a/costume.h b/costume.h index 30af52e9f50..88c8276805d 100644 --- a/costume.h +++ b/costume.h @@ -35,8 +35,25 @@ public: void playChore(int num) { _chores[num].play(); } void playChoreLooping(int num) { _chores[num].playLooping(); } + void setChoreLastFrame(int num) { _chores[num].setLastFrame(); } void setChoreLooping(int num, bool val) { _chores[num].setLooping(val); } void stopChore(int num) { _chores[num].stop(); } + char *getColormap() { return _colormap; } + void setColormap(char *map) { + _colormap = map; + for(int i=0;i<_numComponents;i++) { + if (_components[i] == NULL) + continue; + // Needs to handle Main Models (pigeons) and normal Models + // (when Manny climbs the rope) + if ( +std::memcmp(_components[i]->tag(), "mmdl", 4) == 0 + || +std::memcmp(_components[i]->tag(), "mat ", 4) == 0 +) + _components[i]->setMapName(_colormap); + } + } void stopChores(); int isChoring(int num, bool excludeLooping); int isChoring(bool excludeLooping); @@ -50,11 +67,13 @@ public: class Component { public: - Component(Component *parent, int parentID); + Component(Component *parent, int parentID, char *tag); + char *tag() { return _tag; } virtual void setMatrix(Matrix4) { }; virtual void init() { } virtual void setKey(int) { } + virtual void setMapName(char *) { } virtual void update() { } virtual void setupTexture() { } virtual void draw() { } @@ -62,9 +81,12 @@ public: virtual ~Component() { } protected: + char _tag[4]; int _parentID; Component *_parent, *_child, *_sibling; Matrix4 _matrix; + Costume *_cost; + void setCostume(Costume *cost) { _cost = cost; } void setParent(Component *newParent); friend class Costume; @@ -72,9 +94,9 @@ public: private: Component *loadComponent(char tag[4], Component *parent, int parentID, const char *name); - + char *_colormap; std::string _fname; - + int _numComponents; Component **_components; @@ -105,6 +127,7 @@ private: void setLooping(bool val) { _looping = val; } void stop(); void update(); + void setLastFrame(); private: Costume *_owner; diff --git a/debug.h b/debug.h index 84635b5c5c5..f339d31fbeb 100644 --- a/debug.h +++ b/debug.h @@ -20,6 +20,46 @@ #ifndef DEBUG_H #define DEBUG_H +enum enDebugLevels { + DEBUG_NONE, + DEBUG_NORMAL, + DEBUG_WARN, + DEBUG_ERROR, + DEBUG_FUNC, + DEBUG_BITMAPS, + DEBUG_MODEL, + DEBUG_STUB, + DEBUG_SMUSH, + DEBUG_CHORES, + DEBUG_ALL +}; +extern enDebugLevels debugLevel; +static const char *debug_levels[] = { + "NONE", + "NORMAL", + "WARN", + "ERROR", + "FUNC", + "BITMAP", + "MODEL", + "STUB", + "SMUSH", + "CHORE", + "ALL" +}; +static const char *debug_descriptions[] = { + "No debug messages will be printed (default)", + "\"Normal\" debug messages will be printed", + "Warning debug messages will be printed", + "Error debug messages will be printed", + "Function (normal and stub) debug messages will be printed", + "Bitmap debug messages will be printed", + "Model debug messages will be printed", + "Stub (missing function) debug messages will be printed", + "SMUSH debug messages will be printed", + "Chore debug messages will be printed", + "All debug messages will be printed", +}; // Hacky toggles for experimental / debug code (defined/set in main.cpp) extern bool ZBUFFER_GLOBAL, SHOWFPS_GLOBAL; diff --git a/driver_gl.cpp b/driver_gl.cpp index b2660b09e61..b5df29db254 100644 --- a/driver_gl.cpp +++ b/driver_gl.cpp @@ -117,9 +117,14 @@ void DriverGL::finishActorDraw() { void DriverGL::set3DMode() { glMatrixMode(GL_MODELVIEW); glEnable(GL_DEPTH_TEST); + glDepthFunc(GL_LESS); } void DriverGL::drawModelFace(const Model::Face *face, float *vertices, float *vertNormals, float *textureVerts) { + // Support transparency in actor objects, such as the message tube + // in Manny's Office + glAlphaFunc(GL_GREATER, 0.5); + glEnable(GL_ALPHA_TEST); glNormal3fv(face->_normal._coords); glBegin(GL_POLYGON); for (int i = 0; i < face->_numVertices; i++) { @@ -131,6 +136,8 @@ void DriverGL::drawModelFace(const Model::Face *face, float *vertices, float *ve glVertex3fv(vertices + 3 * face->_vertices[i]); } glEnd(); + // Done with transparency-capable objects + glDisable( GL_ALPHA_TEST ); } void DriverGL::drawHierachyNode(const Model::HierNode *node) { @@ -428,7 +435,6 @@ void DriverGL::drawDepthBitmap(int x, int y, int w, int h, char *data) { // if (num != 0) { // warning("Animation not handled yet in GL texture path !\n"); // } - if (y + h == 480) { glRasterPos2i(x, _screenHeight - 1); glBitmap(0, 0, 0, 0, 0, -1, NULL); diff --git a/engine.cpp b/engine.cpp index 33069558855..76b49cbfa7c 100644 --- a/engine.cpp +++ b/engine.cpp @@ -152,6 +152,8 @@ void Engine::mainLoop() { lua_endblock(); } if (event.type == SDL_KEYDOWN) { + if (event.key.keysym.sym == SDLK_z) + g_resourceloader->loadKeyframe("ma_card_hold.key"); if ((event.key.keysym.sym == SDLK_RETURN || event.key.keysym.sym == SDLK_KP_ENTER) && (event.key.keysym.mod & KMOD_ALT)) @@ -197,6 +199,20 @@ void Engine::mainLoop() { _currScene->drawBackground(); } + // Draw underlying scene components + if (_currScene != NULL) { + _currScene->drawBitmaps(ObjectState::OBJSTATE_UNDERLAY); + // State objects are drawn on top of other things, such as the flag + // on Manny's message tube + _currScene->drawBitmaps(ObjectState::OBJSTATE_STATE); + } + + // Play SMUSH Animations + // This should occur on top of all underlying scene objects, + // a good example is the tube switcher room where some state objects + // need to render underneath the animation or you can't see what's going on + // This should not occur on top of everything though or Manny gets covered + // up when he's next to Glottis's service room if (g_smush->isPlaying()) { _movieTime = g_smush->getMovieTime(); if (g_smush->isUpdateNeeded()) { @@ -207,12 +223,6 @@ void Engine::mainLoop() { g_driver->drawSmushFrame(g_smush->getX(), g_smush->getY()); } - if (_currScene != NULL) { - _currScene->drawBitmaps(ObjectState::OBJSTATE_UNDERLAY); - _currScene->drawBitmaps(ObjectState::OBJSTATE_STATE); - _currScene->drawBitmaps(ObjectState::OBJSTATE_OVERLAY); - } - if (SHOWFPS_GLOBAL) g_driver->drawEmergString(550, 25, fps, Color(255, 255, 255)); @@ -234,6 +244,14 @@ void Engine::mainLoop() { if (_currScene != NULL) a->undraw(a->inSet(_currScene->name()) && a->visible()); } + + // Draw overlying scene components + if (_currScene != NULL) { + // The overlay objects should be drawn on top of everything else, + // including 3D objects such as Manny and the message tube + _currScene->drawBitmaps(ObjectState::OBJSTATE_OVERLAY); + } + } // Draw Primitives @@ -433,15 +451,57 @@ void Engine::savegameCallback() { lua_endblock(); } +Scene *Engine::findScene(const char *name) { + // Find scene object + for (SceneListType::const_iterator i = scenesBegin(); i != scenesEnd(); i++) { + if(!strcmp((char *) (*i)->name(), (char *) name)) + return *i; + } + return NULL; +} + +void Engine::setSceneLock(const char *name, bool lockStatus) { + Scene *scene = findScene(name); + + if (scene == NULL) { + if (debugLevel == DEBUG_WARN || debugLevel == DEBUG_ALL) + warning("Scene object '%s' not found in list!", name); + return; + } + // Change the locking status + scene->locked = lockStatus; +} + void Engine::setScene(const char *name) { + Scene *scene = findScene(name); + + // If the scene already exists then use the existing data + if (scene != NULL) { + setScene(scene); + return; + } Block *b = g_resourceloader->getFileBlock(name); if (b == NULL) warning("Could not find scene file %s\n", name); - delete _currScene; + if (_currScene != NULL && !_currScene->locked) { + removeScene(_currScene); + delete _currScene; + } _currScene = new Scene(name, b->data(), b->len()); + registerScene(_currScene); _currScene->setSoundParameters(20, 127); delete b; } + +void Engine::setScene(Scene *scene) { + if (_currScene != NULL && !_currScene->locked) { + removeScene(_currScene); + delete _currScene; + } + _currScene = scene; + _currScene->setSoundParameters(20, 127); +} + void Engine::setTextSpeed(int speed) { if (speed < 1) _textSpeed = 1; diff --git a/engine.h b/engine.h index afd078bd95c..588a32186a6 100644 --- a/engine.h +++ b/engine.h @@ -111,12 +111,27 @@ public: void enableControl(int num) { _controlsEnabled[num] = true; } void disableControl(int num) { _controlsEnabled[num] = false; } - void registerActor(Actor *a) { _actors.push_back(a); } - + Scene *findScene(const char *name); + void setSceneLock(const char *name, bool lockStatus); void setScene(const char *name); + void setScene(Scene *scene); Scene *currScene() { return _currScene; } const char *sceneName() const { return _currScene->name(); } + // Scene registration + typedef std::list SceneListType; + SceneListType::const_iterator scenesBegin() const { + return _scenes.begin(); + } + SceneListType::const_iterator scenesEnd() const { + return _scenes.end(); + } + void registerScene(Scene *a) { _scenes.push_back(a); } + void removeScene(Scene *a) { + _scenes.remove(a); + } + + // Actor registration typedef std::list ActorListType; ActorListType::const_iterator actorsBegin() const { return _actors.begin(); @@ -124,7 +139,7 @@ public: ActorListType::const_iterator actorsEnd() const { return _actors.end(); } - + void registerActor(Actor *a) { _actors.push_back(a); } void setSelectedActor(Actor *a) { _selectedActor = a; } Actor *selectedActor() { return _selectedActor; } @@ -194,6 +209,7 @@ private: bool _controlsEnabled[SDLK_EXTRA_LAST]; + SceneListType _scenes; ActorListType _actors; Actor *_selectedActor; TextListType _textObjects; diff --git a/keyframe.cpp b/keyframe.cpp index 4f65edad5e3..c1ac93d04e2 100644 --- a/keyframe.cpp +++ b/keyframe.cpp @@ -25,6 +25,7 @@ KeyframeAnim::KeyframeAnim(const char *filename, const char *data, int len) : Resource(filename) { + if (len >= 4 && std::memcmp(data, "FYEK", 4) == 0) loadBinary(data, len); else { @@ -52,7 +53,20 @@ void KeyframeAnim::loadBinary(const char *data, int len) { const char *dataEnd = data + len; data += 180; while (data < dataEnd) { + // ma_card_hold.key crashes at this part without checking + // to make sure nodeNum is valid, unfortunately I believe + // whatever data we're losing from this file is what prevents + // the game from continuing after Manny reads the message + // + // TODO: Find out what really goes wrong when we read + // the data in ma_card_hold.key and fix it int nodeNum = READ_LE_UINT32(data + 32); + if (nodeNum >= _numJoints) { + if (debugLevel == DEBUG_WARN || debugLevel == DEBUG_ALL) { + warning("A node number was greater than the maximum number of nodes (%d/%d)", nodeNum, _numJoints); + } + return; + } _nodes[nodeNum] = new KeyframeNode; _nodes[nodeNum]->loadBinary(data); } diff --git a/localize.cpp b/localize.cpp index 58f40109a58..1016167b0d6 100644 --- a/localize.cpp +++ b/localize.cpp @@ -30,7 +30,7 @@ Localizer::Localizer() { const char *namesToTry[] = { "/GRIM.TAB", "/Grim.tab", "/grim.tab" }; for (unsigned i = 0; i < sizeof(namesToTry) / sizeof(namesToTry[0]); i++) { - const char *datadir = g_registry->get("DataDir"); + const char *datadir = g_registry->get("DataDir", NULL); std::string fname = (datadir != NULL ? datadir : "."); fname += namesToTry[i]; f = std::fopen(fname.c_str(), "rb"); diff --git a/lua.cpp b/lua.cpp index a331e355541..5d9858680c1 100644 --- a/lua.cpp +++ b/lua.cpp @@ -28,6 +28,7 @@ #include "smush.h" #include "textobject.h" #include "objectstate.h" +#include "colormap.h" #include "font.h" #include "imuse/imuse.h" @@ -41,7 +42,9 @@ extern Imuse *g_imuse; #define strmatch(src, dst) (strlen(src) == strlen(dst) && strcmp(src, dst) == 0) +#define DEBUG_FUNCTION() debugFunction("Function", __FUNCTION__) +static void debugFunction(char *debugMessage, const char *funcName); static void stubWarning(char *funcName); static inline bool isObject(int num) { @@ -171,11 +174,11 @@ static Costume *get_costume(Actor *a, int param, char *called_from) { Costume *result; if (lua_isnil(lua_getparam(param))) { result = a->currentCostume(); - if (result == NULL) + if (result == NULL && (debugLevel == DEBUG_WARN || debugLevel == DEBUG_ALL)) warning("Actor %s has no costume [%s]\n", a->name(), called_from); } else { result = a->findCostume(luaL_check_string(param)); - if (result == NULL) + if (result == NULL && (debugLevel == DEBUG_WARN || debugLevel == DEBUG_ALL)) warning("Actor %s has no costume %s [%s]\n", a->name(), lua_getstring(lua_getparam(param)), called_from); } return result; @@ -191,13 +194,34 @@ static void new_dofile() { // Debugging message functions static void PrintDebug() { - char *msg_str = luaL_check_string(1); - std::fputs(msg_str, stderr); + DEBUG_FUNCTION(); + if (debugLevel == DEBUG_NORMAL || debugLevel == DEBUG_ALL) { + std::string msg = luaL_check_string(1); + + msg.insert(0, "Debug: "); + std::fputs(msg.c_str(), stderr); + } +} + +static void PrintError() { + DEBUG_FUNCTION(); + if (debugLevel == DEBUG_ERROR || debugLevel == DEBUG_ALL) { + std::string msg = luaL_check_string(1); + + msg.insert(0, "Error: "); + // don't do 'error()' so we can stay alive if possible + std::fputs(msg.c_str(), stderr); + } } static void PrintWarning() { - char *msg = luaL_check_string(1); - warning(msg); + DEBUG_FUNCTION(); + if (debugLevel == DEBUG_WARN || debugLevel == DEBUG_ALL) { + std::string msg = luaL_check_string(1); + + msg.insert(0, "Warning: "); + warning(msg.c_str()); + } } static void FunctionName() { @@ -206,6 +230,7 @@ static void FunctionName() { char *filename; int line; + DEBUG_FUNCTION(); if (!lua_isfunction(lua_getparam(1))) { sprintf(buf, "function InvalidArgsToFunctionName"); lua_pushstring(buf); @@ -244,6 +269,8 @@ static void FunctionName() { static void CheckForFile() { char *filename = luaL_check_string(1); + + DEBUG_FUNCTION(); pushbool(g_resourceloader->fileExists(filename)); } @@ -259,12 +286,18 @@ static unsigned char clamp_color(int c) { } static void MakeColor() { - Color *c = new Color (clamp_color(check_int(1)), clamp_color(check_int(2)), clamp_color(check_int(3))); + Color *c; + + DEBUG_FUNCTION(); + c = new Color (clamp_color(check_int(1)), clamp_color(check_int(2)), clamp_color(check_int(3))); lua_pushusertag(c, MKID('COLR')); } static void GetColorComponents() { - Color *c = check_color(1); + Color *c; + + DEBUG_FUNCTION(); + c = check_color(1); lua_pushnumber(c->red()); lua_pushnumber(c->green()); lua_pushnumber(c->blue()); @@ -273,14 +306,22 @@ static void GetColorComponents() { // Registry functions static void ReadRegistryValue() { - char *key = luaL_check_string(1); - const char *val = g_registry->get(key); + char *key; + const char *val; + + DEBUG_FUNCTION(); + key = luaL_check_string(1); + val = g_registry->get(key, NULL); lua_pushstring(const_cast(val)); } static void WriteRegistryValue() { - char *key = luaL_check_string(1); - char *val = luaL_check_string(2); + char *key; + char *val; + + DEBUG_FUNCTION(); + key = luaL_check_string(1); + val = luaL_check_string(2); g_registry->set(key, val); } @@ -288,6 +329,8 @@ static void WriteRegistryValue() { static void LoadActor() { const char *name; + + DEBUG_FUNCTION(); if (lua_isnil(lua_getparam(1))) name = ""; else @@ -296,22 +339,27 @@ static void LoadActor() { } static void GetActorTimeScale() { - stubWarning("GetActorTimeScale"); + DEBUG_FUNCTION(); // return 1 so the game doesn't halt when Manny attempts // to pick up the fire extinguisher lua_pushnumber(1); } static void SetSelectedActor() { - Actor *act = check_actor(1); + Actor *act; + + DEBUG_FUNCTION(); + act = check_actor(1); g_engine->setSelectedActor(act); } static void SetSayLineDefaults() { char *key_text = NULL; - lua_Object table_obj = lua_getparam(1); + lua_Object table_obj; lua_Object key; + DEBUG_FUNCTION(); + table_obj = lua_getparam(1); for (;;) { lua_pushobject(table_obj); if (key_text) @@ -333,22 +381,32 @@ static void SetSayLineDefaults() { } static void SetActorTalkColor() { - Actor *act = check_actor(1); - Color *c = check_color(2); + Actor *act; + Color *c; + + DEBUG_FUNCTION(); + act = check_actor(1); + c = check_color(2); act->setTalkColor(*c); } static void GetActorTalkColor() { - Actor *act = check_actor(1); - Color *c = new Color(act->talkColor()); + Actor *act; + Color *c; + + DEBUG_FUNCTION(); + act = check_actor(1); + c = new Color(act->talkColor()); lua_pushusertag(c, MKID('COLR')); } static void SetActorRestChore() { - Actor *act = check_actor(1); + Actor *act; int chore; Costume *costume; + DEBUG_FUNCTION(); + act = check_actor(1); if (lua_isnil(lua_getparam(2))) { chore = -1; costume = NULL; @@ -361,27 +419,39 @@ static void SetActorRestChore() { } static void SetActorWalkChore() { - Actor *act = check_actor(1); - int chore = check_int(2); - Costume *costume = get_costume(act, 3, "SetActorWalkChore"); + Actor *act; + int chore; + Costume *costume; + DEBUG_FUNCTION(); + act = check_actor(1); + chore = check_int(2); + costume = get_costume(act, 3, "SetActorWalkChore"); act->setWalkChore(chore, costume); } static void SetActorTurnChores() { - Actor *act = check_actor(1); - int left_chore = check_int(2); - int right_chore = check_int(3); - Costume *costume = get_costume(act, 4, "SetActorTurnChores"); + Actor *act; + int left_chore; + int right_chore; + Costume *costume; + DEBUG_FUNCTION(); + act = check_actor(1); + left_chore = check_int(2); + right_chore = check_int(3); + costume = get_costume(act, 4, "SetActorTurnChores"); act->setTurnChores(left_chore, right_chore, costume); } static void SetActorTalkChore() { - Actor *act = check_actor(1); - int index = check_int(2); + Actor *act; + int index; int chore; + DEBUG_FUNCTION(); + act = check_actor(1); + index = check_int(2); if (lua_isnumber(lua_getparam(3))) chore = check_int(3); else @@ -393,42 +463,64 @@ static void SetActorTalkChore() { } static void SetActorMumblechore() { - Actor *act = check_actor(1); - int chore = check_int(2); - Costume *costume = get_costume(act, 3, "SetActorMumblechore"); + Actor *act; + int chore; + Costume *costume; + DEBUG_FUNCTION(); + act = check_actor(1); + chore = check_int(2); + costume = get_costume(act, 3, "SetActorMumblechore"); act->setMumbleChore(chore, costume); } static void SetActorVisibility() { - Actor *act = check_actor(1); - bool val = getbool(2); + Actor *act; + bool val; + + DEBUG_FUNCTION(); + act = check_actor(1); + val = getbool(2); act->setVisibility(val); } static void PutActorAt() { - Actor *act = check_actor(1); - float x = luaL_check_number(2); - float y = luaL_check_number(3); - float z = luaL_check_number(4); + Actor *act; - act->setPos(Vector3d(x, y, z)); + DEBUG_FUNCTION(); + act = check_actor(1); + act->setPos(Vector3d(luaL_check_number(2), luaL_check_number(3), luaL_check_number(4))); } static void GetActorPos() { - Actor *act = check_actor(1); - Vector3d pos = act->pos(); + Actor *act; + Vector3d pos; + + DEBUG_FUNCTION(); + act = check_actor(1); + pos = act->pos(); lua_pushnumber(pos.x()); lua_pushnumber(pos.y()); lua_pushnumber(pos.z()); } static void SetActorRot() { - Actor *act = check_actor(1); - float pitch = luaL_check_number(2); - float yaw = luaL_check_number(3); - float roll = luaL_check_number(4); + float pitch, yaw, roll; + lua_Object param3; + Actor *act; + DEBUG_FUNCTION(); + param3 = lua_getparam(3); + act = check_actor(1); + pitch = luaL_check_number(2); + // param3 can be nil, the tube-switcher scene appears + // to call SetActorRot will nil for param3 intentionally + if (lua_isnil(param3)) + yaw = 0; + else + yaw = luaL_check_number(3); + + roll = luaL_check_number(4); if (getbool(5)) act->turnTo(pitch, yaw, roll); else @@ -436,97 +528,155 @@ static void SetActorRot() { } static void GetActorRot() { - Actor *act = check_actor(1); + Actor *act; + + DEBUG_FUNCTION(); + act = check_actor(1); lua_pushnumber(act->pitch()); lua_pushnumber(act->yaw()); lua_pushnumber(act->roll()); } static void IsActorTurning() { - Actor *act = check_actor(1); + Actor *act; + + DEBUG_FUNCTION(); + act = check_actor(1); pushbool(act->isTurning()); } static void GetAngleBetweenActors() { - Actor *act1 = check_actor(1); - Actor *act2 = check_actor(2); + Actor *act1; + Actor *act2; + + DEBUG_FUNCTION(); + act1 = check_actor(1); + act2 = check_actor(2); lua_pushnumber(act1->angleTo(*act2)); } static void GetActorYawToPoint() { - Actor *act = check_actor(1); - double x = luaL_check_number(2); - double y = luaL_check_number(3); - double z = luaL_check_number(4); + lua_Object param2; + float x, y, z; + Actor *act; + + DEBUG_FUNCTION(); + act = check_actor(1); + param2 = lua_getparam(2); + // when this gets called by the tube-switcher guy it's sending + // only two things: an actor and a table with components x, y, z + if (lua_isnumber(param2)) { + x = luaL_check_number(2); + y = luaL_check_number(3); + z = luaL_check_number(4); + } else if (lua_istable(param2)) { + x = lua_getnumber(getTableValue(param2, "x")); + y = lua_getnumber(getTableValue(param2, "y")); + z = lua_getnumber(getTableValue(param2, "z")); + } else { + if (debugLevel == DEBUG_ERROR || debugLevel == DEBUG_ALL) + error("Unhandled data type for GetActorYawToPoint!"); + return; + } lua_pushnumber(act->yawTo(Vector3d(x, y, z))); } static void PutActorInSet() { - Actor *act = check_actor(1); const char *set = ""; + Actor *act; + + DEBUG_FUNCTION(); + act = check_actor(1); if (!lua_isnil(lua_getparam(2))) set = luaL_check_string(2); act->putInSet(set); } static void SetActorWalkRate() { - Actor *act = check_actor(1); - float rate = luaL_check_number(2); + Actor *act; + float rate; + DEBUG_FUNCTION(); + act = check_actor(1); + rate = luaL_check_number(2); act->setWalkRate(rate); } static void GetActorWalkRate() { - Actor *act = check_actor(1); + Actor *act; + + DEBUG_FUNCTION(); + act = check_actor(1); lua_pushnumber(act->walkRate()); } static void SetActorTurnRate() { - Actor *act = check_actor(1); - float rate = luaL_check_number(2); + Actor *act; + float rate; + + DEBUG_FUNCTION(); + act = check_actor(1); + rate = luaL_check_number(2); act->setTurnRate(rate); } static void WalkActorForward() { - Actor *act = check_actor(1); + Actor *act; + + DEBUG_FUNCTION(); + act = check_actor(1); act->walkForward(); } static void SetActorReflection() { - Actor *act = check_actor(1); - float angle = luaL_check_number(2); + Actor *act; + float angle; + + DEBUG_FUNCTION(); + act = check_actor(1); + angle = luaL_check_number(2); act->setReflection(angle); } static void GetActorPuckVector() { - Actor *act = check_actor(1); - Vector3d result = act->puckVector(); + Actor *act; + Vector3d result; + + DEBUG_FUNCTION(); + act = check_actor(1); + result = act->puckVector(); lua_pushnumber(result.x()); lua_pushnumber(result.y()); lua_pushnumber(result.z()); } static void WalkActorTo() { - Actor *act = check_actor(1); - float x = luaL_check_number(2); - float y = luaL_check_number(3); - float z = luaL_check_number(4); + Actor *act; - act->walkTo(Vector3d(x, y, z)); + DEBUG_FUNCTION(); + act = check_actor(1); + act->walkTo(Vector3d(luaL_check_number(2), luaL_check_number(3), luaL_check_number(4))); } static void IsActorMoving() { - Actor *act = check_actor(1); + Actor *act; + + DEBUG_FUNCTION(); + act = check_actor(1); pushbool(act->isWalking()); } static void Is3DHardwareEnabled() { + DEBUG_FUNCTION(); pushbool(g_driver->isHardwareAccelerated()); } static void SetHardwareState() { // changing only in config setup (software/hardware rendering) - bool accel = getbool(1); + bool accel; + + DEBUG_FUNCTION(); + accel = getbool(1); if (accel) g_registry->set("soft", "FALSE"); else @@ -535,18 +685,25 @@ static void SetHardwareState() { } static void SetVideoDevices() { - int devId = check_int(1); - int modeId = check_int(2); + int devId; + int modeId; + + DEBUG_FUNCTION(); + devId = check_int(1); + modeId = check_int(2); // ignore setting video devices } static void GetVideoDevices() { + DEBUG_FUNCTION(); lua_pushnumber(0.0); lua_pushnumber(-1.0); } static void EnumerateVideoDevices() { lua_Object result = lua_createtable(); + + DEBUG_FUNCTION(); lua_pushobject(result); lua_pushnumber(0.0); // id of device lua_pushstring("SDL Video Device"); // name of device @@ -555,8 +712,11 @@ static void EnumerateVideoDevices() { } static void Enumerate3DDevices() { - int num = check_int(1); lua_Object result = lua_createtable(); + int num; + + DEBUG_FUNCTION(); + num = check_int(1); lua_pushobject(result); lua_pushnumber(-1.0); if (g_driver->isHardwareAccelerated()) { @@ -569,24 +729,56 @@ static void Enumerate3DDevices() { } static void IsActorResting() { - Actor *act = check_actor(1); + Actor *act; + + DEBUG_FUNCTION(); + act = check_actor(1); pushbool(!(act->isWalking() || act->isTurning())); } +static void TurnActorTo() { +stubWarning("TurnActorTo"); +} +static void PointActorAt() { +stubWarning("PointActorAt"); +} +static void SetActorColormap() { + char *mapname; + CMap *_cmap; + Actor *act; + + DEBUG_FUNCTION(); + act = check_actor(1); + mapname = luaL_check_string(2); + _cmap = g_resourceloader->loadColormap(mapname); + act->setColormap(mapname); +} + static void TurnActor() { - Actor *act = check_actor(1); - int dir = check_int(2); + Actor *act; + int dir; + + DEBUG_FUNCTION(); + act = check_actor(1); + dir = check_int(2); act->turn(dir); } static void PushActorCostume() { - Actor *act = check_actor(1); - const char *costumeName = luaL_check_string(2); + Actor *act; + const char *costumeName; + + DEBUG_FUNCTION(); + act = check_actor(1); + costumeName = luaL_check_string(2); act->pushCostume(costumeName); } static void SetActorCostume() { - Actor *act = check_actor(1); + Actor *act; + + DEBUG_FUNCTION(); + act = check_actor(1); if (lua_isnil(lua_getparam(2))) act->clearCostumes(); else { @@ -596,8 +788,12 @@ static void SetActorCostume() { } static void GetActorCostume() { - Actor *act = check_actor(1); - Costume *c = act->currentCostume(); + Actor *act; + Costume *c; + + DEBUG_FUNCTION(); + act = check_actor(1); + c = act->currentCostume(); if (c == NULL) lua_pushnil(); else @@ -605,31 +801,75 @@ static void GetActorCostume() { } static void PopActorCostume() { - Actor *act = check_actor(1); + Actor *act; + + DEBUG_FUNCTION(); + act = check_actor(1); act->popCostume(); } static void GetActorCostumeDepth() { - Actor *act = check_actor(1); + Actor *act; + + DEBUG_FUNCTION(); + act = check_actor(1); lua_pushnumber(act->costumeStackDepth()); } static void PlayActorChore() { - Actor *act = check_actor(1); - int num = check_int(2); - Costume *cost = get_costume(act, 3, "playActorChore"); + Actor *act; + int num; + Costume *cost; - if (!cost) + DEBUG_FUNCTION(); + act = check_actor(1); + num = check_int(2); + cost = get_costume(act, 3, "playActorChore"); + if (!cost) { + if (debugLevel == DEBUG_CHORES || debugLevel == DEBUG_WARN || debugLevel == DEBUG_ALL) + warning("Actor costume not found, unable to perform chore."); return; + } cost->playChore(num); } -static void PlayActorChoreLooping() { - Actor *act = check_actor(1); - int num = check_int(2); - Costume *cost = get_costume(act, 3, "playActorChoreLooping"); +static void CompleteActorChore() { + Costume *cost; + Actor *act; + int num; + // CompleteActorChore appears to be an alias for PlayActorChore + // Except that we should jump to the last frame of the chore + // + // Example: When Manny puts the message tube back in his office + // the animation automatically puts the tube back into place + // and then calls this function to show the closed graphic + // + // Note: This does not appear to function entirely as it should + // TODO: Make this operation work better + + DEBUG_FUNCTION(); + act = check_actor(1); + num = check_int(2); + cost = get_costume(act, 3, "completeActorChore"); + if (!cost) { + if (debugLevel == DEBUG_CHORES || debugLevel == DEBUG_WARN || debugLevel == DEBUG_ALL) + warning("Actor costume not found, unable to perform chore."); + return; + } + cost->setChoreLastFrame(num); +} + +static void PlayActorChoreLooping() { + Actor *act; + int num; + Costume *cost; + + DEBUG_FUNCTION(); + act = check_actor(1); + num = check_int(2); + cost = get_costume(act, 3, "playActorChoreLooping"); if (!cost) return; @@ -637,11 +877,16 @@ static void PlayActorChoreLooping() { } static void SetActorChoreLooping() { - Actor *act = check_actor(1); - int num = check_int(2); - bool val = getbool(3); - Costume *cost = get_costume(act, 4, "setActorChoreLooping"); + Actor *act; + int num; + bool val; + Costume *cost; + DEBUG_FUNCTION(); + act = check_actor(1); + num = check_int(2); + val = getbool(3); + cost = get_costume(act, 4, "setActorChoreLooping"); if (!cost) return; @@ -649,9 +894,12 @@ static void SetActorChoreLooping() { } static void StopActorChore() { - Actor *act = check_actor(1); - Costume *cost = get_costume(act, 3, "stopActorChore"); + Actor *act; + Costume *cost; + DEBUG_FUNCTION(); + act = check_actor(1); + cost = get_costume(act, 3, "stopActorChore"); if (!cost) return; @@ -662,11 +910,15 @@ static void StopActorChore() { } static void IsActorChoring() { - Actor *act = check_actor(1); - bool excludeLooping = getbool(3); - Costume *cost = get_costume(act, 4, "isActorChoring"); + Actor *act; + bool excludeLooping; + Costume *cost; int result; + DEBUG_FUNCTION(); + act = check_actor(1); + excludeLooping = getbool(3); + cost = get_costume(act, 4, "isActorChoring"); if (!cost) { lua_pushnil(); return; @@ -684,12 +936,15 @@ static void IsActorChoring() { } static void ActorLookAt() { - Actor *act = check_actor(1); - lua_Object x = lua_getparam(2); - lua_Object y = lua_getparam(3); - lua_Object z = lua_getparam(4); - lua_Object rate = lua_getparam(5); + lua_Object x, y, z, rate; + Actor *act; + DEBUG_FUNCTION(); + act = check_actor(1); + x = lua_getparam(2); + y = lua_getparam(3); + z = lua_getparam(4); + rate = lua_getparam(5); if (lua_isnumber(rate)) act->setLookAtRate(luaL_check_number(5)); @@ -733,38 +988,54 @@ static void ActorLookAt() { if (lua_isnumber(y)) act->setLookAtRate(luaL_check_number(3)); - } + } else if (debugLevel == DEBUG_WARN || debugLevel == DEBUG_ALL) + warning("ActorLookAt: Don't know what to look at!"); act->setLooking(true); + // Fixes random bug when changing scenes (?) after we've done a jump + // (this function is close to the failure point) + lua_pushnil(); } static void SetActorLookRate() { - Actor *act = check_actor(1); - float rate = luaL_check_number(2); + Actor *act; + float rate; + DEBUG_FUNCTION(); + act = check_actor(1); + rate = luaL_check_number(2); act->setLookAtRate(rate); } static void GetActorLookRate() { - Actor *act = check_actor(1); + Actor *act; + DEBUG_FUNCTION(); + act = check_actor(1); lua_pushnumber(act->lookAtRate()); } static void SetActorHead() { - Actor *act = check_actor(1); - int joint1 = check_int(2); - int joint2 = check_int(3); - int joint3 = check_int(4); - float maxRoll = luaL_check_number(5); // Yaz: recheck to see if it's really roll - float maxPitch = luaL_check_number(6); - float maxYaw = luaL_check_number(7); + float maxRoll, maxPitch, maxYaw; + int joint1, joint2, joint3; + Actor *act; + DEBUG_FUNCTION(); + act = check_actor(1); + joint1 = check_int(2); + joint2 = check_int(3); + joint3 = check_int(4); + maxRoll = luaL_check_number(5); // Yaz: recheck to see if it's really roll + maxPitch = luaL_check_number(6); + maxYaw = luaL_check_number(7); act->setHead(joint1, joint2, joint3, maxRoll, maxPitch, maxYaw); } static void PutActorAtInterest() { - Actor *act = check_actor(1); + Actor *act; + + DEBUG_FUNCTION(); + act = check_actor(1); if (!g_engine->currScene()) return; @@ -772,10 +1043,14 @@ static void PutActorAtInterest() { } static void SetActorFollowBoxes() { - Actor *act = check_actor(1); - bool mode = !lua_isnil(lua_getparam(2)); + Actor *act; + bool mode; - warning("SetActorFollowBoxes() not implemented"); + DEBUG_FUNCTION(); + act = check_actor(1); + mode = !lua_isnil(lua_getparam(2)); + if (debugLevel == DEBUG_WARN || debugLevel == DEBUG_ALL) + warning("SetActorFollowBoxes() not implemented"); // that is not walkbox walking, but temporary hack // act->enableWalkbox(mode); act->setConstrain(mode); @@ -788,11 +1063,15 @@ static void SetActorConstrain() { // that below should be enabled, but for now it's disabled realated to // above func SetActorFollowBoxes. // act->setConstrain(constrain); + stubWarning("SetActorConstrain"); } static void GetVisibleThings() { lua_Object result = lua_createtable(); - Actor *sel = g_engine->selectedActor(); + Actor *sel; + + DEBUG_FUNCTION(); + sel = g_engine->selectedActor(); for (Engine::ActorListType::const_iterator i = g_engine->actorsBegin(); i != g_engine->actorsEnd(); i++) { if (!(*i)->inSet(g_engine->sceneName())) continue; @@ -837,8 +1116,12 @@ std::string parseMsgText(const char *msg, char *msgId) { static void TextFileGetLine() { char textBuf[512]; textBuf[0] = 0; - char *filename = luaL_check_string(1); - FILE *file = fopen(filename, "r"); + char *filename; + FILE *file; + + DEBUG_FUNCTION(); + filename = luaL_check_string(1); + file = fopen(filename, "r"); if (!file) { lua_pushnil(); return; @@ -854,8 +1137,12 @@ static void TextFileGetLine() { static void TextFileGetLineCount() { char textBuf[512]; - char *filename = luaL_check_string(1); - FILE *file = fopen(filename, "r"); + char *filename; + FILE *file; + + DEBUG_FUNCTION(); + filename = luaL_check_string(1); + file = fopen(filename, "r"); if (!file) { lua_pushnil(); return; @@ -887,23 +1174,24 @@ static void TextFileGetLineCount() { // Localization function static void LocalizeString() { - char msgId[32]; - char buf[640]; - - char *str = luaL_check_string(1); + char msgId[32], buf[640], *str; + + DEBUG_FUNCTION(); + str = luaL_check_string(1); std::string msg = parseMsgText(str, msgId); sprintf(buf, "/%s/%s", msgId, msg.c_str()); lua_pushstring(const_cast(buf)); } static void SayLine() { + int pan = 64, param_number = 2; char msgId[32], *str; - int pan = 64; - - Actor *act = check_actor(1); - - int param_number = 2; - lua_Object param2 = lua_getparam(param_number++); + lua_Object param2; + Actor *act; + + DEBUG_FUNCTION(); + act = check_actor(1); + param2 = lua_getparam(param_number++); if (!lua_isnil(param2)) { do { if (lua_isstring(param2)) { @@ -925,7 +1213,7 @@ static void InputDialog() { int c, i = 0; char buf[512]; - stubWarning("InputDialog"); + DEBUG_FUNCTION(); fprintf(stderr, "%s %s: ", luaL_check_string(1), luaL_check_string(2)); while (i < 512 && (c = fgetc(stdin)) != EOF && c != '\n') buf[i++] = c; @@ -936,6 +1224,8 @@ static void InputDialog() { static void IsMessageGoing() { Actor *act; + + DEBUG_FUNCTION(); if (lua_getparam(1) == LUA_NOOBJECT) { pushbool(g_imuse->isVoicePlaying()); } else { @@ -945,16 +1235,22 @@ static void IsMessageGoing() { } static void ShutUpActor() { - Actor *act = check_actor(1); + Actor *act; + + DEBUG_FUNCTION(); + act = check_actor(1); if (act) act->shutUp(); } // Sector functions static void GetActorSector(void) { - Actor *act = check_actor(1); - int sectorType = check_int(2); + Actor *act; + int sectorType; + DEBUG_FUNCTION(); + act = check_actor(1); + sectorType = check_int(2); Sector *result = g_engine->currScene()->findPointSector(act->pos(), sectorType); if (result != NULL) { lua_pushnumber(result->id()); @@ -968,10 +1264,14 @@ static void GetActorSector(void) { } static void IsActorInSector(void) { - Actor *act = check_actor(1); - const char *name = luaL_check_string(2); - int i, numSectors = g_engine->currScene()->getSectorCount(); + int i, numSectors; + const char *name; + Actor *act; + DEBUG_FUNCTION(); + act = check_actor(1); + name = luaL_check_string(2); + numSectors = g_engine->currScene()->getSectorCount(); for (i = 0; i < numSectors; i++) { Sector *sector = g_engine->currScene()->getSectorBase(i); @@ -988,12 +1288,15 @@ static void IsActorInSector(void) { } static void MakeSectorActive(void) { - lua_Object sectorName = lua_getparam(1); - bool visible = !lua_isnil(lua_getparam(2)); + lua_Object sectorName; + bool visible; int i = 0, numSectors; + DEBUG_FUNCTION(); + sectorName = lua_getparam(1); + visible = !lua_isnil(lua_getparam(2)); // FIXME: This happens on initial load. Are we initting something in the wrong order? - if (!g_engine->currScene()) { + if (!g_engine->currScene() && (debugLevel == DEBUG_WARN || debugLevel == DEBUG_ALL)) { warning("!!!! Trying to call MakeSectorActive without a scene!"); return; } @@ -1020,23 +1323,48 @@ static void MakeSectorActive(void) { return; } } - } else { + } else if (debugLevel == DEBUG_WARN || debugLevel == DEBUG_ALL){ warning("MakeSectorActive Parameter is not a sector ID or Name"); return; - } + } else + return; } // Scene functions +static void LockSet() { + const char *name; + + DEBUG_FUNCTION(); + name = luaL_check_string(1); + // We should lock the set so it isn't destroyed + g_engine->setSceneLock(name, true); +} + +static void UnLockSet() { + const char *name; + + DEBUG_FUNCTION(); + name = luaL_check_string(1); + // We should unlock the set so it can be destroyed again + g_engine->setSceneLock(name, false); +} static void MakeCurrentSet() { - const char *name = luaL_check_string(1); + const char *name; + + DEBUG_FUNCTION(); + name = luaL_check_string(1); + if (debugLevel == DEBUG_NORMAL || debugLevel == DEBUG_ALL) + printf("Entered new scene '%s'.\n", name); g_engine->setScene(name); } static void MakeCurrentSetup() { - int num = check_int(1); - int prevSetup = g_engine->currScene()->setup(); + int num, prevSetup; + DEBUG_FUNCTION(); + num = check_int(1); + prevSetup = g_engine->currScene()->setup(); g_engine->currScene()->setSetup(num); lua_beginblock(); @@ -1058,23 +1386,30 @@ static void MakeCurrentSetup() { } static void GetCurrentSetup() { - const char *name = luaL_check_string(1); + const char *name; + + DEBUG_FUNCTION(); + name = luaL_check_string(1); if (std::strcmp(name, g_engine->sceneName()) == 0) lua_pushnumber(g_engine->currScene()->setup()); else lua_pushnil(); } +// FIXME: Function only spits back what it's given static void GetShrinkPos() { - // FIXME - double x = luaL_check_number(1); - double y = luaL_check_number(2); - double z = luaL_check_number(3); - double r = luaL_check_number(4); + double x, y, z, r; + + DEBUG_FUNCTION(); + x = luaL_check_number(1); + y = luaL_check_number(2); + z = luaL_check_number(3); + r = luaL_check_number(4); lua_pushnumber(x); lua_pushnumber(y); lua_pushnumber(z); - warning("Stub function GetShrinkPos(%g,%g,%g,%g) called", x, y, z, r); + if (debugLevel == DEBUG_WARN || debugLevel == DEBUG_ALL) + warning("Stub function GetShrinkPos(%g,%g,%g,%g) called", x, y, z, r); } // Sound functions @@ -1089,10 +1424,13 @@ enum ImuseParam { }; static void ImStartSound() { - char *soundName = luaL_check_string(1); - int priority = check_int(2); - int group = check_int(3); + int priority, group; + char *soundName; + DEBUG_FUNCTION(); + soundName = luaL_check_string(1); + priority = check_int(2); + group = check_int(3); if (g_imuse->startSound(soundName, group, 0, 127, 0, priority)) { lua_pushstring(soundName); } else { @@ -1101,56 +1439,75 @@ static void ImStartSound() { } static void ImStopSound() { - char *soundName = luaL_check_string(1); + char *soundName; + + DEBUG_FUNCTION(); + soundName = luaL_check_string(1); g_imuse->stopSound(soundName); } static void ImStopAllSounds() { + DEBUG_FUNCTION(); g_imuse->stopAllSounds(); } static void ImPause() { + DEBUG_FUNCTION(); g_imuse->pause(true); } static void ImResume() { + DEBUG_FUNCTION(); g_imuse->pause(false); } static void ImSetVoiceEffect() { - char *effectName = luaL_check_string(1); - warning("ImSetVoiceEffect(%s) Voice effects are not yet supported", effectName); + char *effectName; + + DEBUG_FUNCTION(); + effectName = luaL_check_string(1); + if (debugLevel == DEBUG_WARN || debugLevel == DEBUG_ALL) + warning("ImSetVoiceEffect(%s) Voice effects are not yet supported", effectName); } static void ImSetMusicVol() { + DEBUG_FUNCTION(); g_imuse->setGroupMusicVolume(check_int(1)); } static void ImGetMusicVol() { + DEBUG_FUNCTION(); lua_pushnumber(g_imuse->getGroupMusicVolume()); } static void ImSetVoiceVol() { + DEBUG_FUNCTION(); g_imuse->setGroupVoiceVolume(check_int(1)); } static void ImGetVoiceVol() { + DEBUG_FUNCTION(); lua_pushnumber(g_imuse->getGroupVoiceVolume()); } static void ImSetSfxVol() { + DEBUG_FUNCTION(); g_imuse->setGroupSfxVolume(check_int(1)); } static void ImGetSfxVol() { + DEBUG_FUNCTION(); lua_pushnumber(g_imuse->getGroupSfxVolume()); } static void ImSetParam() { - char *soundName = luaL_check_string(1); - int param = check_int(2); - int value = check_int(3); + int param, value; + char *soundName; + DEBUG_FUNCTION(); + soundName = luaL_check_string(1); + param = check_int(2); + value = check_int(3); switch (param) { case IM_SOUND_VOL: g_imuse->setVolume(soundName, value); @@ -1160,14 +1517,18 @@ static void ImSetParam() { break; default: lua_pushnil(); - warning("ImSetParam() Unimplemented %d, %d\n", param, value); + if (debugLevel == DEBUG_WARN || debugLevel == DEBUG_ALL) + warning("ImSetParam() Unimplemented %d, %d\n", param, value); } } void ImGetParam() { - char *soundName = luaL_check_string(1); - int param = check_int(2); + char *soundName; + int param; + DEBUG_FUNCTION(); + soundName = luaL_check_string(1); + param = check_int(2); switch (param) { case IM_SOUND_PLAY_COUNT: lua_pushnumber(g_imuse->getCountPlayedTracks(soundName)); @@ -1177,16 +1538,20 @@ void ImGetParam() { break; default: lua_pushnil(); - warning("ImGetParam() Unimplemented %d\n", param); + if (debugLevel == DEBUG_WARN || debugLevel == DEBUG_ALL) + warning("ImGetParam() Unimplemented %d\n", param); } } static void ImFadeParam() { - char *soundName = luaL_check_string(1); - int opcode = check_int(2); - int value = check_int(3); - int duration = check_int(4); + int opcode, value, duration; + char *soundName; + DEBUG_FUNCTION(); + soundName = luaL_check_string(1); + opcode = check_int(2); + value = check_int(3); + duration = check_int(4); switch (opcode) { case IM_SOUND_PAN: g_imuse->setFadePan(soundName, value, duration); @@ -1198,28 +1563,36 @@ static void ImFadeParam() { } static void ImSetState() { - int state = check_int(1); - g_imuseState = state; + DEBUG_FUNCTION(); + g_imuseState = check_int(1); } static void ImSetSequence() { - int state = check_int(1); + int state; + + DEBUG_FUNCTION(); + state = check_int(1); lua_pushnumber(g_imuse->setMusicSequence(state)); } static void SaveIMuse() { - error("SaveIMuse() is not yet supported"); + DEBUG_FUNCTION(); + if(debugLevel == DEBUG_ERROR || debugLevel == DEBUG_ALL) + error("SaveIMuse() is not yet supported"); } static void RestoreIMuse() { - error("RestoreIMuse() is not yet supported"); + DEBUG_FUNCTION(); + if(debugLevel == DEBUG_ERROR || debugLevel == DEBUG_ALL) + error("RestoreIMuse() is not yet supported"); } static void SetSoundPosition() { Vector3d pos; int minVolume = 10; int maxVolume = 127; - + + DEBUG_FUNCTION(); if (g_engine->currScene()) { g_engine->currScene()->getSoundParameters(&minVolume, &maxVolume); } @@ -1249,13 +1622,16 @@ static void SetSoundPosition() { static void IsSoundPlaying() { // dummy + DEBUG_FUNCTION(); } static void PlaySoundAt() { // dummy + DEBUG_FUNCTION(); } static void FileFindDispose() { + DEBUG_FUNCTION(); if (g_searchFile) { #ifdef _WIN32 FindClose(g_searchFile); @@ -1271,7 +1647,8 @@ static void luaFileFindNext() { #ifndef _WIN32 dirent *de; #endif - + + DEBUG_FUNCTION(); if (g_searchFile) { #ifdef _WIN32 if (g_firstFind) { @@ -1310,10 +1687,12 @@ static void luaFileFindNext() { } static void luaFileFindFirst() { - char path[255]; - char *extension = luaL_check_string(1); - lua_Object pathObj = lua_getparam(2); + char path[255], *extension; + lua_Object pathObj; + DEBUG_FUNCTION(); + extension = luaL_check_string(1); + pathObj = lua_getparam(2); FileFindDispose(); if (!lua_isnil(pathObj)) { @@ -1354,24 +1733,34 @@ void setMovieTime(float movieTime) { } void PerSecond() { - float rate = luaL_check_number(1); + float rate; + + DEBUG_FUNCTION(); + rate = luaL_check_number(1); lua_pushnumber(g_engine->perSecond(rate)); } void EnableControl() { - stubWarning("EnableControl"); - int num = check_control(1); + int num; + + DEBUG_FUNCTION(); + num = check_control(1); g_engine->enableControl(num); } void DisableControl() { - stubWarning("DisableControl"); - int num = check_control(1); + int num; + + DEBUG_FUNCTION(); + num = check_control(1); g_engine->disableControl(num); } void GetControlState() { - int num = check_control(1); + int num; + + DEBUG_FUNCTION(); + num = check_control(1); if (num >= SDLK_JOY1_B1 && num <= SDLK_MOUSE_B4) lua_pushnil(); else if (num >= SDLK_AXIS_JOY1_X && num <= SDLK_AXIS_MOUSE_Z) @@ -1383,14 +1772,19 @@ void GetControlState() { } static void GetImage() { - char *bitmapName = luaL_check_string(1); + char *bitmapName; + + DEBUG_FUNCTION(); + bitmapName = luaL_check_string(1); Bitmap *image = g_resourceloader->loadBitmap(bitmapName); lua_pushusertag(image, MKID('VBUF')); } static void FreeImage() { - Bitmap *bitmap = check_bitmapobject(1); + Bitmap *bitmap; + DEBUG_FUNCTION(); + bitmap = check_bitmapobject(1); for (Engine::PrimitiveListType::const_iterator i = g_engine->primitivesBegin(); i != g_engine->primitivesEnd(); i++) { PrimitiveObject *p = *i; if (p->isBitmap() && p->getBitmapHandle() == bitmap) { @@ -1403,12 +1797,16 @@ static void FreeImage() { } static void BlastImage() { - Bitmap *bitmap = check_bitmapobject(1); - int x = check_int(2); - int y = check_int(3); - bool transparent = getbool(4); - PrimitiveObject *p = new PrimitiveObject(); + bool transparent; + Bitmap *bitmap; + int x, y; + + DEBUG_FUNCTION(); + bitmap = check_bitmapobject(1); + x = check_int(2); + y = check_int(3); + transparent = getbool(4); p->createBitmap(bitmap, x, y, transparent); g_engine->registerPrimitiveObject(p); lua_pushusertag(p, MKID('PRIM')); @@ -1417,7 +1815,8 @@ static void BlastImage() { void getTextObjectParams(TextObject *textObject, lua_Object table_obj) { char *key_text = NULL; lua_Object key; - + + DEBUG_FUNCTION(); for (;;) { lua_pushobject(table_obj); if (key_text) @@ -1462,8 +1861,12 @@ void getTextObjectParams(TextObject *textObject, lua_Object table_obj) { * this is known to be used when changing between menus */ static void CleanBuffer() { + DEBUG_FUNCTION(); g_engine->killPrimitiveObjects(); g_engine->killTextObjects(); + // Cleanup references to deleted text objects + for (Engine::ActorListType::const_iterator i = g_engine->actorsBegin(); i != g_engine->actorsEnd(); i++) + (*i)->lineCleanup(); } /* Check to see if the menu item at a specific index has @@ -1498,14 +1901,15 @@ char *itemText(lua_Object itemTable, int menuItem) { * handling that has been observed */ static void menuHandler() { - lua_Object menuTable = lua_getparam(1); - lua_Object keycode = lua_getparam(2); - lua_Object pushcode = lua_getparam(3); - lua_Object itemTable/*, item*/; - int sliderValue = 0; + lua_Object menuTable, keycode, pushcode, itemTable/*, item*/; + int menuItem = 1, menuItems = 1, sliderValue = 0; int key, operation; - int menuItem = 1, menuItems = 1; + DEBUG_FUNCTION(); + menuTable = lua_getparam(1); + keycode = lua_getparam(2); + pushcode = lua_getparam(3); + if (!lua_isnumber(keycode) || !lua_istable(menuTable)) return; if (lua_isnil(pushcode)) @@ -1631,6 +2035,7 @@ static void menuHandler() { /* Clean the requested menu */ static void destroyMenu() { + DEBUG_FUNCTION(); CleanBuffer(); lua_Object system_table = lua_getglobal("system"); setTableValue(system_table, "menuHandler", (lua_Object) 0); @@ -1642,7 +2047,8 @@ static void destroyMenu() { */ TextObject *TextObjectExists(char *name) { TextObject *modifyObject = NULL; - + + DEBUG_FUNCTION(); for (Engine::TextListType::const_iterator i = g_engine->textsBegin(); i != g_engine->textsEnd(); i++) { TextObject *textO = *i; if (strlen(name) == strlen(textO->name()) && strcmp(textO->name(), name) == 0) { @@ -1659,7 +2065,8 @@ TextObject *TextObjectExists(char *name) { */ static void KillTextObject() { TextObject *textObjectParm, *delText; - + + DEBUG_FUNCTION(); if (lua_isnil(lua_getparam(1))) { error("KillTextObject(NULL)"); return; @@ -1676,9 +2083,11 @@ static void KillTextObject() { * in the table in the LUA parameter 2. */ static void ChangeTextObject() { - TextObject *modifyObject, *textObject = check_textobject(1); + TextObject *modifyObject, *textObject; lua_Object tableObj; + DEBUG_FUNCTION(); + textObject = check_textobject(1); // when called in certain instances (such as don's computer) // the second parameter is the string and the third is the table if (lua_isstring(lua_getparam(2))) @@ -1688,13 +2097,14 @@ static void ChangeTextObject() { modifyObject = TextObjectExists((char *)textObject->name()); if (!modifyObject) { - warning("ChangeTextObject(): Cannot find active text object"); + if (debugLevel == DEBUG_WARN || debugLevel == DEBUG_ALL) + warning("ChangeTextObject(): Cannot find active text object"); return; } if (lua_istable(tableObj)) getTextObjectParams(modifyObject, tableObj); - else + else if (debugLevel == DEBUG_WARN || debugLevel == DEBUG_ALL) warning("Expecting table parameter!"); // to modify current bitmap it need recreate it @@ -1710,11 +2120,15 @@ static void ChangeTextObject() { * we're not currently using the value */ static void GetTextSpeed() { + DEBUG_FUNCTION(); lua_pushnumber(g_engine->getTextSpeed()); } static void SetTextSpeed() { - int speed = check_int(1); + int speed; + + DEBUG_FUNCTION(); + speed = check_int(1); g_engine->setTextSpeed(speed); } @@ -1725,12 +2139,14 @@ static void SetTextSpeed() { * (otherwise we'll get identically named menu objects) */ static void MakeTextObject() { - TextObject *textObject; - char *line = lua_getstring(lua_getparam(1)); - std::string text = line; - lua_Object tableObj = lua_getparam(2); + TextObject *textObject = new TextObject(); + lua_Object tableObj; + char *line; - textObject = new TextObject(); + DEBUG_FUNCTION(); + line = lua_getstring(lua_getparam(1)); + std::string text = line; + tableObj = lua_getparam(2); textObject->setDefaults(&textObjectDefaults); if (lua_istable(tableObj)) @@ -1751,26 +2167,38 @@ static void MakeTextObject() { } static void GetTextObjectDimensions() { - TextObject *textObjectParam = check_textobject(1); + TextObject *textObjectParam; + + DEBUG_FUNCTION(); + textObjectParam = check_textobject(1); lua_pushnumber(textObjectParam->getBitmapWidth()); lua_pushnumber(textObjectParam->getBitmapHeight()); } static void ExpireText() { + DEBUG_FUNCTION(); for (Engine::TextListType::const_iterator i = g_engine->textsBegin(); i != g_engine->textsEnd(); i++) { TextObject *textO = *i; g_engine->killTextObject(textO); delete textO; } + // Cleanup references to deleted text objects + for (Engine::ActorListType::const_iterator i = g_engine->actorsBegin(); i != g_engine->actorsEnd(); i++) + (*i)->lineCleanup(); } static void GetTextCharPosition() { - TextObject *textObjectParam = check_textobject(1); - int pos = (int)lua_getnumber(lua_getparam(2)); + TextObject *textObjectParam; + int pos; + + DEBUG_FUNCTION(); + textObjectParam = check_textobject(1); + pos = (int)lua_getnumber(lua_getparam(2)); lua_pushnumber((double)textObjectParam->getTextCharPosition(pos)); } static void BlastText() { + DEBUG_FUNCTION(); // there is some diffrence to MakeTextObject // it draw directly to gfx buffer from here, not from main loop MakeTextObject(); @@ -1782,27 +2210,38 @@ static void SetOffscreenTextPos() { } static void SetSpeechMode() { - int mode = check_int(1); + int mode; + + DEBUG_FUNCTION(); + mode = check_int(1); if ((mode >= 1) && (mode <= 3)) g_engine->setSpeechMode(mode); } static void GetSpeechMode() { - int mode = g_engine->getSpeechMode(); + int mode; + + DEBUG_FUNCTION(); + mode = g_engine->getSpeechMode(); lua_pushnumber(mode); } static void StartFullscreenMovie() { - /*bool mode = */getbool(2); + /*bool mode = getbool(2);*/ + DEBUG_FUNCTION(); + // Clean out any text objects on the display before running the + // movie, otherwise things like Bruno's "Nice bathrobe." will stay + // on-screen the whole movie + CleanBuffer(); g_engine->setMode(ENGINE_MODE_SMUSH); pushbool(g_smush->play(luaL_check_string(1), 0, 0)); } static void StartMovie() { - /*bool mode = */getbool(2); - int x = 0; - int y = 0; + /*bool mode = getbool(2);*/ + int x = 0, y = 0; + DEBUG_FUNCTION(); if (!lua_isnil(lua_getparam(3))) x = check_int(3); @@ -1814,22 +2253,27 @@ static void StartMovie() { } static void IsFullscreenMoviePlaying() { + DEBUG_FUNCTION(); pushbool(g_smush->isPlaying()); } static void IsMoviePlaying() { + DEBUG_FUNCTION(); pushbool(g_smush->isPlaying()); } static void StopMovie() { + DEBUG_FUNCTION(); g_smush->stop(); } static void PauseMovie() { + DEBUG_FUNCTION(); g_smush->pause(lua_isnil(lua_getparam(1)) != 0); } static void PurgePrimitiveQueue() { + DEBUG_FUNCTION(); g_engine->killPrimitiveObjects(); } @@ -1838,12 +2282,16 @@ static void DrawPolygon() { } static void DrawLine() { - int x1 = check_int(1); - int y1 = check_int(2); - int x2 = check_int(3); - int y2 = check_int(4); - lua_Object tableObj = lua_getparam(5); + int x1, y1, x2, y2; + lua_Object tableObj; Color color; + + DEBUG_FUNCTION(); + x1 = check_int(1); + y1 = check_int(2); + x2 = check_int(3); + y2 = check_int(4); + tableObj = lua_getparam(5); color._vals[0] = 255; color._vals[1] = 255; color._vals[2] = 255; @@ -1865,9 +2313,11 @@ static void DrawLine() { static void ChangePrimitive() { PrimitiveObject *psearch, *pmodify = NULL; - lua_Object tableObj = lua_getparam(2); + lua_Object tableObj; Color color; + DEBUG_FUNCTION(); + tableObj = lua_getparam(2); color._vals[0] = 255; color._vals[1] = 255; color._vals[2] = 255; @@ -1903,12 +2353,16 @@ static void ChangePrimitive() { } static void DrawRectangle() { - int x1 = check_int(1); - int y1 = check_int(2); - int x2 = check_int(3); - int y2 = check_int(4); - lua_Object tableObj = lua_getparam(5); + int x1, y1, x2, y2; + lua_Object tableObj; Color color; + + DEBUG_FUNCTION(); + x1 = check_int(1); + y1 = check_int(2); + x2 = check_int(3); + y2 = check_int(4); + tableObj = lua_getparam(5); color._vals[0] = 255; color._vals[1] = 255; color._vals[2] = 255; @@ -1936,6 +2390,7 @@ static void DrawRectangle() { } static void BlastRect() { + DEBUG_FUNCTION(); // BlastRect is specifically for the menu thread; // however, we don't need to handle the menu in a // separate thread so this works fine @@ -1943,10 +2398,13 @@ static void BlastRect() { } static void DimScreen() { - warning("DimScreen()"); + DEBUG_FUNCTION(); + if (debugLevel == DEBUG_WARN || debugLevel == DEBUG_ALL) + warning("DimScreen()"); } static void GetDiskFreeSpace() { + DEBUG_FUNCTION(); // amount of free space in MB, used for creating saves lua_pushnumber(50); } @@ -1958,15 +2416,18 @@ static void NewObjectState() { OBJSTATE_OVERLAY = 2, OBJSTATE_STATE = 3 }; - ObjectState *state = NULL; + ObjectState::Position pos; + char *bitmap, *zbitmap; + bool visible; + int setupID; - int setupID = check_int(1); // Setup ID - ObjectState::Position pos = check_objstate_pos(2); // When to draw - char *bitmap = luaL_check_string(3); // Bitmap - char *zbitmap = NULL; // Zbuffer Bitmap - bool visible = getbool(5); // Starts visible? - + DEBUG_FUNCTION(); + setupID = check_int(1); // Setup ID + pos = check_objstate_pos(2); // When to draw + bitmap = luaL_check_string(3); // Bitmap + zbitmap = NULL; // Zbuffer Bitmap + visible = getbool(5); // Starts visible? if (!lua_isnil(lua_getparam(4))) zbitmap = luaL_check_string(4); @@ -1976,13 +2437,18 @@ static void NewObjectState() { } static void FreeObjectState() { - ObjectState *state = check_object(1); + ObjectState *state; + + DEBUG_FUNCTION(); + state = check_object(1); g_engine->currScene()->deleteObjectState(state); } static void SendObjectToBack() { - stubWarning("VERIFY: SendObjectToBack"); - lua_Object param = lua_getparam(1); + lua_Object param; + + DEBUG_FUNCTION(); + param = lua_getparam(1); if (lua_isuserdata(param) && lua_tag(param) == MKID('STAT')) { ObjectState *state = static_cast(lua_getuserdata(param)); // moving object to top in list ? @@ -1991,8 +2457,10 @@ static void SendObjectToBack() { } static void SendObjectToFront() { - stubWarning("VERIFY: SendObjectToFront"); - lua_Object param = lua_getparam(1); + lua_Object param; + + DEBUG_FUNCTION(); + param = lua_getparam(1); if (lua_isuserdata(param) && lua_tag(param) == MKID('STAT')) { ObjectState *state = static_cast(lua_getuserdata(param)); // moving object to last in list ? @@ -2001,19 +2469,26 @@ static void SendObjectToFront() { } static void SetObjectType() { - ObjectState *state = check_object(1); - ObjectState::Position pos = check_objstate_pos(2); + ObjectState::Position pos; + ObjectState *state; + + DEBUG_FUNCTION(); + state = check_object(1); + pos = check_objstate_pos(2); state->setPos(pos); } static void GetCurrentScript() { + DEBUG_FUNCTION(); current_script(); } static void ScreenShot() { - int width = check_int(1); - int height = check_int(2); - + int width, height; + + DEBUG_FUNCTION(); + width = check_int(1); + height = check_int(2); Bitmap *screenshot = g_driver->getScreenshot(width, height); if (screenshot) { lua_pushusertag(screenshot, MKID('VBUF')); @@ -2023,12 +2498,13 @@ static void ScreenShot() { } static void SubmitSaveGameData() { - lua_Object table = lua_getparam(1); - lua_Object table2; + lua_Object table, table2; int dataSize = 0; int count = 0; char *str; - + + DEBUG_FUNCTION(); + table = lua_getparam(1); for (;;) { lua_pushobject(table); lua_pushnumber(count); @@ -2061,9 +2537,13 @@ static void SubmitSaveGameData() { static void GetSaveGameData() { lua_Object result; + char *filename; int dataSize; - char *filename = luaL_check_string(1); - gzFile file = gzopen(filename, "rb"); + gzFile file; + + DEBUG_FUNCTION(); + filename = luaL_check_string(1); + file = gzopen(filename, "rb"); if (!file) return; @@ -2094,41 +2574,54 @@ static void GetSaveGameData() { } static void Load() { - lua_Object fileName = lua_getparam(1); + lua_Object fileName; + + DEBUG_FUNCTION(); + fileName = lua_getparam(1); if (lua_isnil(fileName)) { g_engine->_savegameFileName = NULL; } else if (lua_isstring(fileName)) { g_engine->_savegameFileName = lua_getstring(fileName); } else { - warning("Load() fileName is wrong"); + if (debugLevel == DEBUG_WARN || debugLevel == DEBUG_ALL) + warning("Load() fileName is wrong"); return; } g_engine->_savegameLoadRequest = true; } static void Save() { - lua_Object fileName = lua_getparam(1); + lua_Object fileName; + + DEBUG_FUNCTION(); + fileName = lua_getparam(1); if (lua_isnil(fileName)) { g_engine->_savegameFileName = NULL; } else if (lua_isstring(fileName)) { g_engine->_savegameFileName = lua_getstring(fileName); } else { - warning("Save() fileName is wrong"); + if (debugLevel == DEBUG_WARN || debugLevel == DEBUG_ALL) + warning("Save() fileName is wrong"); return; } g_engine->_savegameSaveRequest = true; } static int SaveCallback(int /*tag*/, int value, SaveRestoreFunc /*saveFunc*/) { + DEBUG_FUNCTION(); return value; } static int RestoreCallback(int /*tag*/, int value, SaveRestoreFunc /*saveFunc*/) { + DEBUG_FUNCTION(); return value; } static void LockFont() { - lua_Object param1 = lua_getparam(1); + lua_Object param1; + + DEBUG_FUNCTION(); + param1 = lua_getparam(1); if (lua_isstring(param1)) { char *fontName = lua_getstring(param1); Font *result = g_resourceloader->loadFont(fontName); @@ -2139,15 +2632,20 @@ static void LockFont() { } static void EnableDebugKeys() { + DEBUG_FUNCTION(); // in residual all keys are handled/enabled } static void LightMgrSetChange() { + DEBUG_FUNCTION(); // that seems only used when some control panel is opened } static void SetAmbientLight() { - int mode = check_int(1); + int mode; + + DEBUG_FUNCTION(); + mode = check_int(1); if (mode == 0) { if (g_engine->currScene() != NULL) { g_engine->currScene()->setLightEnableState(true); @@ -2162,10 +2660,12 @@ static void SetAmbientLight() { } static void RenderModeUser() { - stubWarning("RenderModeUser"); // it enable/disable updating display - lua_Object param1 = lua_getparam(1); + lua_Object param1; bool mode; + + DEBUG_FUNCTION(); + param1 = lua_getparam(1); if (lua_isnumber(param1)) { mode = check_int(1) != 0; } else if (lua_isnil(param1)) { @@ -2174,15 +2674,20 @@ static void RenderModeUser() { error("RenderModeUser() Unknown type of param"); } g_engine->setMenuMode(mode); - if (mode) - printf("RenderModeUser() Enable\n"); - else - printf("RenderModeUser() Disable\n"); + if (debugLevel == DEBUG_NORMAL || debugLevel == DEBUG_ALL) + { + if (mode) + printf("RenderModeUser() Enable\n"); + else + printf("RenderModeUser() Disable\n"); + } } static void Display() { - stubWarning("Display"); - lua_Object system_table = lua_getglobal("system"); + lua_Object system_table; + + DEBUG_FUNCTION(); + system_table = lua_getglobal("system"); // Install Menu Destroy Handler lua_pushobject(system_table); lua_pushstring(const_cast("userPaintHandler")); @@ -2198,9 +2703,12 @@ static void Display() { } static void EngineDisplay() { - // it enable/disable updating display - lua_Object param1 = lua_getparam(1); + lua_Object param1; bool mode; + + // it enable/disable updating display + DEBUG_FUNCTION(); + param1 = lua_getparam(1); if (lua_isnumber(param1)) { mode = check_int(1) != 0; } else if (lua_isnil(param1)) { @@ -2208,61 +2716,99 @@ static void EngineDisplay() { } else { error("EngineDisplay() Unknown type of param"); } - if (mode) - printf("EngineDisplay() Enable\n"); - else - printf("EngineDisplay() Disable\n"); + if (debugLevel == DEBUG_NORMAL || debugLevel == DEBUG_ALL) { + if (mode) + printf("EngineDisplay() Enable\n"); + else + printf("EngineDisplay() Disable\n"); + } } static void JustLoaded() { - error("OPCODE USAGE VERIFICATION: JustLoaded"); + DEBUG_FUNCTION(); + if(debugLevel == DEBUG_ERROR || debugLevel == DEBUG_ALL) + error("OPCODE USAGE VERIFICATION: JustLoaded"); } static void PlaySound() { - error("OPCODE USAGE VERIFICATION: PlaySound"); + DEBUG_FUNCTION(); + if(debugLevel == DEBUG_ERROR || debugLevel == DEBUG_ALL) + error("OPCODE USAGE VERIFICATION: PlaySound"); } static void SetEmergencyFont() { - error("OPCODE USAGE VERIFICATION: SetEmergencyFont"); + DEBUG_FUNCTION(); + if(debugLevel == DEBUG_ERROR || debugLevel == DEBUG_ALL) + error("OPCODE USAGE VERIFICATION: SetEmergencyFont"); } -// Stub function for builtin functions not yet implemented - -static void stubWarning(char *funcName) { - fprintf(stderr, "WARNING: Stub function %s(", funcName); +/* Generate debug information for all functions + * + * When the debug flag is set to debug everything or "Functions" + * then this will be called to print out the information on a + * function. This is useful for finding problems in a LUA script + * that are due to a few function calls leading up to a failure. + * + * This function is also used by the "Stub" handler which will + * generate warnings about missing functions when the debug flag + * is set to "Stub", warnings, or everything. + */ +static void debugFunction(char *debugMessage, const char *funcName) { + bool stubFn = strcmp(debugMessage, "WARNING: Stub function") == 0; + FILE *output; + + if (!stubFn && debugLevel != DEBUG_FUNC + && debugLevel != DEBUG_ALL) + return; + + if (stubFn) + output = stderr; + else + output = stdout; + fprintf(output, "%s %s(", debugMessage, funcName); for (int i = 1; ; i++) { if (lua_getparam(i) == LUA_NOOBJECT) break; if (lua_isnil(lua_getparam(i))) - fprintf(stderr, "nil"); + fprintf(output, "nil"); else if (lua_istable(lua_getparam(i))) - fprintf(stderr, "{...}"); + fprintf(output, "{...}"); else if (lua_isuserdata(lua_getparam(i))) { if (lua_tag(lua_getparam(i)) == MKID('ACTR')) { Actor *a = check_actor(i); - fprintf(stderr, "", a->name()); + fprintf(output, "", a->name()); } else if (lua_tag(lua_getparam(i)) == MKID('COLR')) { Color *c = check_color(i); - fprintf(stderr, "", c->red(), c->green(), c->blue()); + fprintf(output, "", c->red(), c->green(), c->blue()); } else - fprintf(stderr, "", lua_getuserdata(lua_getparam(i))); + fprintf(output, "", lua_getuserdata(lua_getparam(i))); } else if (lua_isfunction(lua_getparam(i))) - fprintf(stderr, ""); + fprintf(output, ""); else if (lua_isnumber(lua_getparam(i))) - fprintf(stderr, "%g", lua_getnumber(lua_getparam(i))); + fprintf(output, "%g", lua_getnumber(lua_getparam(i))); else if (lua_isstring(lua_getparam(i))) - fprintf(stderr, "\"%s\"", lua_getstring(lua_getparam(i))); + fprintf(output, "\"%s\"", lua_getstring(lua_getparam(i))); else - fprintf(stderr, ""); + fprintf(output, ""); if (lua_getparam(i+1) != LUA_NOOBJECT) - fprintf(stderr, ", "); + fprintf(output, ", "); } - fprintf(stderr, ") called\n"); + fprintf(output, ") called\n"); #if 0 lua_call("print_stack"); #endif } +// Stub function for builtin functions not yet implemented +static void stubWarning(char *funcName) { + // If the user doesn't want these debug messages then don't print them + if(debugLevel != DEBUG_WARN && debugLevel != DEBUG_STUB && debugLevel != DEBUG_FUNC + && debugLevel != DEBUG_ALL) + return; + + debugFunction("WARNING: Stub function", funcName); +} + #define STUB_FUNC(name) static void name() { stubWarning(#name); } STUB_FUNC(SetActorInvClipNode) STUB_FUNC(NukeResources) @@ -2298,8 +2844,6 @@ STUB_FUNC(SetLightIntensity) STUB_FUNC(SetLightPosition) STUB_FUNC(TurnLightOn) STUB_FUNC(GetAngleBetweenVectors) -STUB_FUNC(TurnActorTo) -STUB_FUNC(PointActorAt) STUB_FUNC(GetCameraLookVector) STUB_FUNC(SetCameraRoll) STUB_FUNC(SetCameraInterest) @@ -2312,10 +2856,7 @@ STUB_FUNC(PreRender) STUB_FUNC(GetSectorOppositeEdge) STUB_FUNC(PreviousSetup) STUB_FUNC(NextSetup) -STUB_FUNC(UnLockSet) -STUB_FUNC(LockSet) STUB_FUNC(WorldToScreen) -STUB_FUNC(CompleteActorChore) STUB_FUNC(SetActorRoll) STUB_FUNC(SetActorPitch) STUB_FUNC(GetPointSector) @@ -2329,7 +2870,6 @@ STUB_FUNC(GetActorRect) STUB_FUNC(GetActorNodeLocation) STUB_FUNC(SetActorTimeScale) STUB_FUNC(SetActorScale) -STUB_FUNC(SetActorColormap) STUB_FUNC(GetTranslationMode) STUB_FUNC(SetTranslationMode) STUB_FUNC(PrintLine) @@ -2337,7 +2877,6 @@ STUB_FUNC(KillPrimitive) STUB_FUNC(WalkActorToAvoiding) STUB_FUNC(GetActorChores) STUB_FUNC(Exit) -STUB_FUNC(PrintError) STUB_FUNC(SetCameraPosition) STUB_FUNC(GetCameraFOV) STUB_FUNC(SetCameraFOV) @@ -3037,7 +3576,7 @@ int bundle_dofile(const char *filename) { delete b; // Don't print warnings on Scripts\foo.lua, // d:\grimFandango\Scripts\foo.lua - if (std::strstr(filename, "Scripts\\") == NULL) + if (std::strstr(filename, "Scripts\\") == NULL && (debugLevel == DEBUG_WARN || debugLevel == DEBUG_ALL)) warning("Cannot find script %s\n", filename); return 2; @@ -3066,7 +3605,8 @@ lua_Object getTableFunction(lua_Object table, char *name) { } if (!lua_isfunction(handler)) { - warning("Invalid event handler %s", name); + if (debugLevel == DEBUG_WARN || debugLevel == DEBUG_ALL) + warning("Invalid event handler %s", name); return LUA_NOOBJECT; } diff --git a/main.cpp b/main.cpp index 9b7f107fe24..94df59bbc83 100644 --- a/main.cpp +++ b/main.cpp @@ -37,6 +37,7 @@ // Hacky global toggles for experimental/debug code bool ZBUFFER_GLOBAL, SHOWFPS_GLOBAL, TINYGL_GLOBAL; +enDebugLevels debugLevel = DEBUG_NONE; #ifdef __MINGW32__ int PASCAL WinMain(HINSTANCE /*hInst*/, HINSTANCE /*hPrevInst*/, LPSTR /*lpCmdLine*/, int /*iShowCmd*/) { @@ -45,7 +46,6 @@ int PASCAL WinMain(HINSTANCE /*hInst*/, HINSTANCE /*hPrevInst*/, LPSTR /*lpCmdL #endif static bool g_lua_initialized = false; - Driver *g_driver = NULL; static bool parseBoolStr(const char *val) { @@ -86,10 +86,10 @@ int main(int argc, char *argv[]) { g_registry = new Registry(); // Parse command line - ZBUFFER_GLOBAL = parseBoolStr(g_registry->get("zbuffer")); - SHOWFPS_GLOBAL = parseBoolStr(g_registry->get("fps")); - TINYGL_GLOBAL = parseBoolStr(g_registry->get("soft")); - bool fullscreen = parseBoolStr(g_registry->get("fullscreen")); + ZBUFFER_GLOBAL = parseBoolStr(g_registry->get("zbuffer", "TRUE")); + SHOWFPS_GLOBAL = parseBoolStr(g_registry->get("fps", "FALSE")); + TINYGL_GLOBAL = parseBoolStr(g_registry->get("soft", "FALSE")); + bool fullscreen = parseBoolStr(g_registry->get("fullscreen", "FALSE")); for (i = 1; i < argc; i++) { if (strcmp(argv[i], "-zbuffer") == 0) ZBUFFER_GLOBAL = true; @@ -107,14 +107,48 @@ int main(int argc, char *argv[]) { TINYGL_GLOBAL = true; else if (strcmp(argv[i], "-nosoft") == 0) TINYGL_GLOBAL = false; - else { + else if (strncmp(argv[i], "-debug=", 7) == 0) { + bool numeric = true; + char debugtxt[20]; + unsigned int j; + int level; + + sscanf(argv[i], "%*[^=]%*1s%s", debugtxt); + for(j=0;j DEBUG_ALL) + goto needshelp; + } else { + level = -1; + for(j=0;j<=DEBUG_ALL;j++) + { + if(!strcasecmp(debugtxt, debug_levels[j])) { + level = j; + break; + } + } + if(level == -1) + goto needshelp; + } + debugLevel = (enDebugLevels) level; + printf("Debug level set to: %s\n", debug_levels[debugLevel]); + } else { + int j; +needshelp: printf("Residual CVS Version\n"); printf("--------------------\n"); printf("Recognised options:\n"); printf("\t-[no]zbuffer\t\tEnable/disable ZBuffers (Very slow on older cards)\n"); printf("\t-[no]fps\t\tEnable/disable fps display in upper right corner\n"); - printf("\t-[no]fullscreen\tEnable/disable fullscreen mode at startup\n"); + printf("\t-[no]fullscreen\t\tEnable/disable fullscreen mode at startup\n"); printf("\t-[no]soft\t\tEnable/disable software renderer\n"); + printf("\t-debug=[level]\t\tSet debug to [level], valid levels:\n"); + for(j=0;j<=DEBUG_ALL;j++) + printf("\t\t%-8s (%d): %s.\n", debug_levels[j], j, debug_descriptions[j]); exit(-1); } } diff --git a/material.cpp b/material.cpp index 398b19fa4df..0fe4b56631f 100644 --- a/material.cpp +++ b/material.cpp @@ -23,7 +23,7 @@ #include "driver.h" Material::Material(const char *filename, const char *data, int len, const CMap &cmap) : - Resource(filename) { + Resource(filename), _cmap((CMap *) &cmap) { if (len < 4 || memcmp(data, "MAT ", 4) != 0) error("invalid magic loading texture\n"); @@ -33,7 +33,8 @@ Material::Material(const char *filename, const char *data, int len, const CMap & _height = READ_LE_UINT32(data + 80 + _numImages * 40); if ((_width == 0) || (_height == 0)) { - warning("skip load texture: bad texture size (%dx%d) for texture %s\n", _width, _height, filename); + if (debugLevel == DEBUG_WARN || debugLevel == DEBUG_ALL) + warning("skip load texture: bad texture size (%dx%d) for texture %s\n", _width, _height, filename); return; } diff --git a/material.h b/material.h index b74d7c7cecf..9058e57d1ee 100644 --- a/material.h +++ b/material.h @@ -43,6 +43,7 @@ public: ~Material(); //private: + CMap *_cmap; int _numImages, _currImage; int _width, _height; void *_textures; diff --git a/model.cpp b/model.cpp index a06baedd494..676cf95d1fe 100644 --- a/model.cpp +++ b/model.cpp @@ -27,7 +27,9 @@ #include #include -Model::Model(const char *filename, const char *data, int len, const CMap &cmap) : Resource(filename) { +Model::Model(const char *filename, const char *data, int len, const CMap &cmap) : + Resource(filename), _numMaterials(0), _numGeosets(0) { + if (len >= 4 && std::memcmp(data, "LDOM", 4) == 0) loadBinary(data, cmap); else { @@ -36,12 +38,22 @@ Model::Model(const char *filename, const char *data, int len, const CMap &cmap) } } +void Model::reload(const CMap &cmap) { + // Load the new colormap + for (int i = 0; i < _numMaterials; i++) + _materials[i] = g_resourceloader->loadMaterial(_materialNames[i], cmap); + for (int i = 0; i < _numGeosets; i++) + _geosets[i].changeMaterials(_materials); +} + void Model::loadBinary(const char *data, const CMap &cmap) { _numMaterials = READ_LE_UINT32(data + 4); data += 8; _materials = new ResPtr[_numMaterials]; + _materialNames = new char[_numMaterials][32]; for (int i = 0; i < _numMaterials; i++) { - _materials[i] = g_resourceloader->loadMaterial(data, cmap); + strcpy(_materialNames[i], data); + _materials[i] = g_resourceloader->loadMaterial(_materialNames[i], cmap); data += 32; } data += 32; // skip name @@ -61,6 +73,7 @@ void Model::loadBinary(const char *data, const CMap &cmap) { Model::~Model() { delete[] _materials; + delete[] _materialNames; delete[] _geosets; delete[] _rootHierNode; } @@ -104,8 +117,9 @@ void Model::Mesh::loadBinary(const char *&data, ResPtr *materials) { } data += _numVertices * 4; _faces = new Face[_numFaces]; + _materialid = new int[_numFaces]; for (int i = 0; i < _numFaces; i++) - _faces[i].loadBinary(data, materials); + _materialid[i] = _faces[i].loadBinary(data, materials); _vertNormals = new float[3 * _numVertices]; for (int i = 0; i < 3 * _numVertices; i++) { _vertNormals[i] = get_float(data); @@ -127,7 +141,11 @@ Model::Mesh::~Mesh() { void Model::Mesh::update() { } -void Model::Face::loadBinary(const char *&data, ResPtr *materials) { +void Model::Face::changeMaterial(ResPtr material) { + _material = material; +} + +int Model::Face::loadBinary(const char *&data, ResPtr *materials) { _type = READ_LE_UINT32(data + 4); _geo = READ_LE_UINT32(data + 8); _light = READ_LE_UINT32(data + 12); @@ -157,8 +175,10 @@ void Model::Face::loadBinary(const char *&data, ResPtr *materials) { _material = 0; else { _material = materials[READ_LE_UINT32(data)]; + materialPtr = READ_LE_UINT32(data); data += 4; } + return materialPtr; } Model::Face::~Face() { @@ -241,11 +261,12 @@ void Model::loadText(TextSplitter &ts, const CMap &cmap) { ts.expectString("section: modelresource"); ts.scanString("materials %d", 1, &_numMaterials); _materials = new ResPtr[_numMaterials]; + _materialNames = new char[_numMaterials][32]; for (int i = 0; i < _numMaterials; i++) { int num; - char name[32]; - ts.scanString("%d: %32s", 2, &num, name); - _materials[num] = g_resourceloader->loadMaterial(name, cmap); + + ts.scanString("%d: %32s", 2, &num, _materialNames[num]); + _materials[num] = g_resourceloader->loadMaterial(_materialNames[num], cmap); } ts.expectString("section: geometrydef"); @@ -302,10 +323,15 @@ void Model::loadText(TextSplitter &ts, const CMap &cmap) { _rootHierNode[num]._totalWeight = 1; } - if (!ts.eof()) + if (!ts.eof() && (debugLevel == DEBUG_WARN || debugLevel == DEBUG_ALL)) warning("Unexpected junk at end of model text\n"); } +void Model::Geoset::changeMaterials(ResPtr *materials) { + for (int i = 0; i < _numMeshes; i++) + _meshes[i].changeMaterials(materials); +} + void Model::Geoset::loadText(TextSplitter &ts, ResPtr *materials) { ts.scanString("meshes %d", 1, &_numMeshes); _meshes = new Mesh[_numMeshes]; @@ -316,6 +342,11 @@ void Model::Geoset::loadText(TextSplitter &ts, ResPtr *materials) { } } +void Model::Mesh::changeMaterials(ResPtr *materials) { + for (int i = 0; i < _numFaces; i++) + _faces[i].changeMaterial(materials[_materialid[i]]); +} + void Model::Mesh::loadText(TextSplitter &ts, ResPtr *materials) { ts.scanString("name %32s", 1, _name); ts.scanString("radius %f", 1, &_radius); @@ -323,7 +354,8 @@ void Model::Mesh::loadText(TextSplitter &ts, ResPtr *materials) { // In data001/rope_scale.3do, the shadow line is missing if (std::sscanf(ts.currentLine(), "shadow %d", &_shadow) < 1) { _shadow = 0; - warning("Missing shadow directive in model\n"); + if (debugLevel == DEBUG_WARN || debugLevel == DEBUG_ALL) + warning("Missing shadow directive in model\n"); } else ts.nextLine(); ts.scanString("geometrymode %d", 1, &_geometryMode); @@ -367,18 +399,19 @@ void Model::Mesh::loadText(TextSplitter &ts, ResPtr *materials) { ts.scanString("faces %d", 1, &_numFaces); _faces = new Face[_numFaces]; + _materialid = new int[_numFaces]; for (int i = 0; i < _numFaces; i++) { - int num, material, type, geo, light, tex, verts; + int num, type, geo, light, tex, verts; float extralight; int readlen; if (ts.eof()) error("Expected face data, got EOF\n"); - if (std::sscanf(ts.currentLine(), " %d: %d %i %d %d %d %f %d%n", &num, &material, &type, &geo, &light, &tex, &extralight, &verts, &readlen) < 8) + if (std::sscanf(ts.currentLine(), " %d: %d %i %d %d %d %f %d%n", &num, &_materialid[num], &type, &geo, &light, &tex, &extralight, &verts, &readlen) < 8) error("Expected face data, got `%s'\n", ts.currentLine()); - _faces[num]._material = materials[material]; + _faces[num]._material = materials[_materialid[num]]; _faces[num]._type = type; _faces[num]._geo = geo; _faces[num]._light = light; diff --git a/model.h b/model.h index 865fccaa156..40ac8726d01 100644 --- a/model.h +++ b/model.h @@ -34,7 +34,7 @@ public: Model(const char *filename, const char *data, int len, const CMap &cmap); void loadBinary(const char *data, const CMap &cmap); void loadText(TextSplitter &ts, const CMap &cmap); - + void reload(const CMap &cmap); void draw() const; ~Model(); @@ -70,8 +70,9 @@ public: //private: struct Face { - void loadBinary(const char *&data, ResPtr *materials); + int loadBinary(const char *&data, ResPtr *materials); void draw(float *vertices, float *vertNormals, float *textureVerts) const; + void changeMaterial(ResPtr materials); ~Face(); Material *_material; @@ -85,8 +86,10 @@ public: struct Mesh { void loadBinary(const char *&data, ResPtr *materials); void loadText(TextSplitter &ts, ResPtr *materials); + void changeMaterials(ResPtr *materials); void draw() const; void update(); + Mesh() : _numFaces(0) { } ~Mesh(); char _name[32]; @@ -94,6 +97,7 @@ public: int _shadow, _geometryMode, _lightingMode, _textureMode; int _numVertices; + int *_materialid; float *_vertices; // sets of 3 float *_verticesI; float *_vertNormals; // sets of 3 @@ -109,6 +113,8 @@ public: struct Geoset { void loadBinary(const char *&data, ResPtr *materials); void loadText(TextSplitter &ts, ResPtr *materials); + void changeMaterials(ResPtr *materials); + Geoset() : _numMeshes(0) { } ~Geoset(); int _numMeshes; @@ -116,6 +122,7 @@ public: }; int _numMaterials; + char (*_materialNames)[32]; ResPtr *_materials; Vector3d _insertOffset; int _numGeosets; diff --git a/registry.cpp b/registry.cpp index cd000dba1f1..8e33d2fcfa0 100644 --- a/registry.cpp +++ b/registry.cpp @@ -48,10 +48,10 @@ Registry::Registry() : _dirty(false) { } } -const char *Registry::get(const char *key) const { +const char *Registry::get(const char *key, const char *defval) const { Group::const_iterator i = _settings.find(key); if (i == _settings.end()) - return NULL; + return defval; else return i->second.c_str(); } diff --git a/registry.h b/registry.h index 3cf2b076a6f..e999b7ef2c8 100644 --- a/registry.h +++ b/registry.h @@ -23,7 +23,7 @@ class Registry { public: - const char *get(const char *key) const; + const char *get(const char *key, const char *defval) const; void set(const char *key, const char *val); void save(); diff --git a/resource.cpp b/resource.cpp index 4ea4b23ef49..46659f01789 100644 --- a/resource.cpp +++ b/resource.cpp @@ -40,7 +40,7 @@ static void makeLower(std::string& s) { ResourceLoader *g_resourceloader = NULL; ResourceLoader::ResourceLoader() { - const char *directory = g_registry->get("DataDir"); + const char *directory = g_registry->get("DataDir", NULL); std::string dir_str = (directory != NULL ? directory : "."); dir_str += '/'; int lab_counter = 0; @@ -148,7 +148,8 @@ Bitmap *ResourceLoader::loadBitmap(const char *filename) { Block *b = getFileBlock(filename); if (b == NULL) { // Grim sometimes asks for non-existant bitmaps (eg, ha_overhead) - warning("Could not find bitmap %s\n", filename); + if (debugLevel == DEBUG_WARN || debugLevel == DEBUG_ALL) + warning("Could not find bitmap %s\n", filename); return NULL; } @@ -233,7 +234,8 @@ LipSynch *ResourceLoader::loadLipSynch(const char *filename) { Block *b = getFileBlock(filename); if (b == NULL) { - warning("Could not find lipsynch file %s\n", filename); + if (debugLevel == DEBUG_WARN || debugLevel == DEBUG_ALL) + warning("Could not find lipsynch file %s\n", filename); result = NULL; } else { result = new LipSynch(filename, b->data(), b->len()); @@ -249,7 +251,12 @@ Material *ResourceLoader::loadMaterial(const char *filename, const CMap &c) { makeLower(fname); CacheType::iterator i = _cache.find(fname); if (i != _cache.end()) { - return dynamic_cast(i->second); + Material *material = dynamic_cast(i->second); + + // if the colormap has changed then we need to reload the material! + if (material->_cmap == &c) + return material; + _cache.erase(i, i); } Block *b = getFileBlock(filename); diff --git a/resource.h b/resource.h index 8138a7f57d2..4c5d32b6fa5 100644 --- a/resource.h +++ b/resource.h @@ -104,13 +104,13 @@ public: ResourceLoader(); ResourceLoader(const ResourceLoader &); ~ResourceLoader() { } - + const Lab *findFile(const char *filename) const; private: typedef std::list LabList; LabList _labs; - const Lab *findFile(const char *filename) const; +// const Lab *findFile(const char *filename) const; typedef std::map CacheType; CacheType _cache; diff --git a/scene.cpp b/scene.cpp index 430ffd522b5..a539a8e1570 100644 --- a/scene.cpp +++ b/scene.cpp @@ -31,7 +31,7 @@ #include Scene::Scene(const char *name, const char *buf, int len) : - _name(name) { + _name(name), locked(false) { TextSplitter ts(buf, len); char tempBuf[256]; @@ -48,7 +48,7 @@ Scene::Scene(const char *name, const char *buf, int len) : ts.scanString(" numsetups %d", 1, &_numSetups); _setups = new Setup[_numSetups]; for (int i = 0; i < _numSetups; i++) - _setups[i].load(ts); + _setups[i].load(ts); _currSetup = _setups; _numSectors = -1; @@ -111,6 +111,8 @@ void Scene::Setup::load(TextSplitter &ts) { ts.scanString(" background %256s", 1, buf); _bkgndBm = g_resourceloader->loadBitmap(buf); + if(debugLevel == DEBUG_BITMAPS || debugLevel == DEBUG_NORMAL || debugLevel == DEBUG_ALL) + printf("Loading scene bitmap: %s\n", buf); // ZBuffer is optional if (!ts.checkString("zbuffer")) { @@ -118,6 +120,8 @@ void Scene::Setup::load(TextSplitter &ts) { } else { ts.scanString(" zbuffer %256s", 1, buf); _bkgndZBm = g_resourceloader->loadBitmap(buf); + if(debugLevel == DEBUG_BITMAPS || debugLevel == DEBUG_NORMAL || debugLevel == DEBUG_ALL) + printf("Loading scene z-buffer bitmap: %s\n", buf); } ts.scanString(" position %f %f %f", 3, &_pos.x(), &_pos.y(), &_pos.z()); @@ -228,9 +232,17 @@ void Scene::findClosestSector(Vector3d p, Sector **sect, Vector3d *closestPt) { } ObjectState *Scene::findState(const char *filename) { + // Check the different state objects for the bitmap for (StateList::iterator i = _states.begin(); i != _states.end(); i++) { - if (strcmp((*i)->bitmapFilename(), filename) == 0) + const char *file = (*i)->bitmapFilename(); + + if (strcmp(file, filename) == 0) return *i; + if (strcasecmp(file, filename) == 0) { + if (debugLevel == DEBUG_WARN || debugLevel == DEBUG_ALL) + warning("State object request '%s' matches object '%s' but is the wrong case!", filename, file); + return *i; + } } return NULL; } diff --git a/scene.h b/scene.h index 831ec6e1dda..ddceafab97c 100644 --- a/scene.h +++ b/scene.h @@ -73,7 +73,12 @@ public: int setup() const { return _currSetup - _setups; } // Sector access functions - int getSectorCount() { return _numSectors; } + int getSectorCount() { + // TODO: Find where this is called before we're initialized + if (this == NULL) + return 0; + return _numSectors; + } Sector *getSectorBase(int id) { if ((_numSectors >= 0) && (id < _numSectors)) return &_sectors[id]; @@ -114,6 +119,8 @@ public: float _intensity, _umbraangle, _penumbraangle; }; + bool locked; + private: std::string _name; diff --git a/smush.cpp b/smush.cpp index 8b8d293da63..5947071834b 100644 --- a/smush.cpp +++ b/smush.cpp @@ -129,6 +129,7 @@ void Smush::handleFrame() { tag = _file.readUint32BE(); if (tag == MKID_BE('ANNO')) { +printf("Announcement!\n"); size = _file.readUint32BE(); for (int l = 0; l < size; l++) _file.readByte(); @@ -146,12 +147,14 @@ void Smush::handleFrame() { pos += READ_BE_UINT32(frame + pos + 4) + 8; } else if (READ_BE_UINT32(frame + pos) == MKID_BE('Wave')) { int decompressed_size = READ_BE_UINT32(frame + pos + 8); + if (decompressed_size < 0) handleWave(frame + pos + 8 + 4 + 8, READ_BE_UINT32(frame + pos + 8 + 8)); else + handleWave(frame + pos + 8 + 4, decompressed_size); pos += READ_BE_UINT32(frame + pos + 4) + 8; - } else { + } else if (debugLevel == DEBUG_SMUSH || debugLevel == DEBUG_ERROR || debugLevel == DEBUG_ALL) { error("Smush::handleFrame() unknown tag"); } } while (pos < size); @@ -187,7 +190,7 @@ void Smush::handleFramesHeader() { _freq = READ_LE_UINT32(f_header + pos + 8); _channels = READ_LE_UINT32(f_header + pos + 12); pos += 20; - } else { + } else if (debugLevel == DEBUG_SMUSH || debugLevel == DEBUG_ERROR || debugLevel == DEBUG_ALL){ error("Smush::handleFramesHeader() unknown tag"); } } while (pos < size); @@ -262,7 +265,8 @@ bool zlibFile::open(const char *filename) { _inBuf = (char *)calloc(1, 16385); if (_handle) { - warning("zlibFile::open() File %s already opened", filename); + if (debugLevel == DEBUG_SMUSH || debugLevel == DEBUG_WARN || debugLevel == DEBUG_ALL) + warning("zlibFile::open() File %s already opened", filename); return false; } @@ -271,7 +275,8 @@ bool zlibFile::open(const char *filename) { _handle = g_resourceloader->openNewStream(filename); if (!_handle) { - warning("zlibFile::open() zlibFile %s not found", filename); + if (debugLevel == DEBUG_SMUSH || debugLevel == DEBUG_WARN || debugLevel == DEBUG_ALL) + warning("zlibFile::open() zlibFile %s not found", filename); return false; } @@ -281,7 +286,8 @@ bool zlibFile::open(const char *filename) { fread(_inBuf, 1, sizeof(char), _handle); flags = _inBuf[0]; // Flags fread(_inBuf, 6, sizeof(char), _handle); // XFlags - if (((flags & 0x04) != 0) || ((flags & 0x10) != 0)) // Xtra & Comment + // Xtra & Comment + if (((((flags & 0x04) != 0) || ((flags & 0x10) != 0))) && (debugLevel == DEBUG_SMUSH || debugLevel == DEBUG_ERROR || debugLevel == DEBUG_ALL)) error("zlibFile::open() Unsupported header flag"); if ((flags & 0x08) != 0) { // Orig. Name @@ -298,7 +304,7 @@ bool zlibFile::open(const char *filename) { _stream.zfree = NULL; _stream.opaque = Z_NULL; - if (inflateInit2(&_stream, -15) != Z_OK) + if (inflateInit2(&_stream, -15) != Z_OK && (debugLevel == DEBUG_SMUSH || debugLevel == DEBUG_ERROR || debugLevel == DEBUG_ALL)) error("zlibFile::open() inflateInit2 failed"); _stream.next_in = NULL; @@ -330,7 +336,8 @@ uint32 zlibFile::read(void *ptr, uint32 len) { bool fileEOF = false; if (_handle == NULL) { - error("zlibFile::read() File is not open!"); + if (debugLevel == DEBUG_SMUSH || debugLevel == DEBUG_ERROR || debugLevel == DEBUG_ALL) + error("zlibFile::read() File is not open!"); return 0; } @@ -353,17 +360,20 @@ uint32 zlibFile::read(void *ptr, uint32 len) { result = inflate(&_stream, Z_NO_FLUSH); if (result == Z_STREAM_END) { // EOF - warning("zlibFile::read() Stream ended"); + if (debugLevel == DEBUG_SMUSH || debugLevel == DEBUG_WARN || debugLevel == DEBUG_ALL) + warning("zlibFile::read() Stream ended"); _fileDone = true; break; } if (result == Z_DATA_ERROR) { - warning("zlibFile::read() Decompression error"); + if (debugLevel == DEBUG_SMUSH || debugLevel == DEBUG_WARN || debugLevel == DEBUG_ALL) + warning("zlibFile::read() Decompression error"); _fileDone = true; break; } if (result != Z_OK || fileEOF) { - warning("zlibFile::read() Unknown decomp result: %d/%d\n", result, fileEOF); + if (debugLevel == DEBUG_SMUSH || debugLevel == DEBUG_WARN || debugLevel == DEBUG_ALL) + warning("zlibFile::read() Unknown decomp result: %d/%d\n", result, fileEOF); _fileDone = true; break; } diff --git a/textobject.cpp b/textobject.cpp index cfe82e90d4f..12d89b6540b 100644 --- a/textobject.cpp +++ b/textobject.cpp @@ -228,7 +228,7 @@ void TextObject::draw() { x = 0; g_driver->drawTextBitmap(x, height + _y, _textObjectHandle[i]); - } else + } else if (debugLevel == DEBUG_WARN || debugLevel == DEBUG_ALL) warning("TextObject::draw: Unknown justification code (%d)!", _justify); height += _bitmapHeightPtr[i]; diff --git a/timer.cpp b/timer.cpp index 5a2f29d7ab7..d609970312b 100644 --- a/timer.cpp +++ b/timer.cpp @@ -104,7 +104,8 @@ bool Timer::installTimerProc(TimerProc procedure, int32 interval, void *refCon) } } - warning("Couldn't find free timer slot!"); + if (debugLevel == DEBUG_WARN || debugLevel == DEBUG_ALL) + warning("Couldn't find free timer slot!"); return false; } diff --git a/walkplane.cpp b/walkplane.cpp index 21c1fac2fba..70442107163 100644 --- a/walkplane.cpp +++ b/walkplane.cpp @@ -58,7 +58,7 @@ void Sector::load0(TextSplitter &ts, char *name, int id) { _type = 0x4000; else if (strstr(buf, "chernobyl")) _type = 0x8000; - else + else if (debugLevel == DEBUG_ERROR || debugLevel == DEBUG_ALL) error("Unknown sector type '%s' in room setup", buf); ts.scanString(" default visibility %256s", 1, buf);