1 /* ScummVM - Graphic Adventure Engine
2  *
3  * ScummVM is the legal property of its developers, whose names
4  * are too numerous to list here. Please refer to the COPYRIGHT
5  * file distributed with this source distribution.
6  *
7  * This program is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License
9  * as published by the Free Software Foundation; either version 2
10  * of the License, or (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20  *
21  */
22 
23 #include "common/file.h"
24 #include "xeen/xeen.h"
25 #include "xeen/debugger.h"
26 
27 namespace Xeen {
28 
strToInt(const char * s)29 static int strToInt(const char *s) {
30 	if (!*s)
31 		// No string at all
32 		return 0;
33 	else if (toupper(s[strlen(s) - 1]) != 'H')
34 		// Standard decimal string
35 		return atoi(s);
36 
37 	// Hexadecimal string
38 	uint tmp = 0;
39 	int read = sscanf(s, "%xh", &tmp);
40 	if (read < 1)
41 		error("strToInt failed on string \"%s\"", s);
42 	return (int)tmp;
43 }
44 
45 /*------------------------------------------------------------------------*/
46 
Debugger(XeenEngine * vm)47 Debugger::Debugger(XeenEngine *vm) : GUI::Debugger(), _vm(vm),
48 		_spellId(-1), _invincible(false), _intangible(false), _superStrength(false) {
49 	registerCmd("continue", WRAP_METHOD(Debugger, cmdExit));
50 	registerCmd("spell", WRAP_METHOD(Debugger, cmdSpell));
51 	registerCmd("spells", WRAP_METHOD(Debugger, cmdSpells));
52 	registerCmd("dump", WRAP_METHOD(Debugger, cmdDump));
53 	registerCmd("gold", WRAP_METHOD(Debugger, cmdGold));
54 	registerCmd("gems", WRAP_METHOD(Debugger, cmdGems));
55 	registerCmd("map", WRAP_METHOD(Debugger, cmdMap));
56 	registerCmd("pos", WRAP_METHOD(Debugger, cmdPos));
57 	registerCmd("invincible", WRAP_METHOD(Debugger, cmdInvincible));
58 	registerCmd("strength", WRAP_METHOD(Debugger, cmdSuperStrength));
59 	registerCmd("intangible", WRAP_METHOD(Debugger, cmdIntangible));
60 }
61 
update()62 void Debugger::update() {
63 	Party &party = *_vm->_party;
64 	Spells &spells = *_vm->_spells;
65 
66 	if (_spellId != -1) {
67 		// Cast any specified spell
68 		MagicSpell spellId = (MagicSpell)_spellId;
69 		_spellId = -1;
70 		Character *c = &party._activeParty[0];
71 		c->_currentSp = 99;
72 		spells.castSpell(c, spellId);
73 	}
74 
75 	onFrame();
76 }
77 
cmdSpell(int argc,const char ** argv)78 bool Debugger::cmdSpell(int argc, const char **argv) {
79 	if (argc != 2) {
80 		debugPrintf("Format: spell <spell-id>");
81 		return true;
82 	} else {
83 		int spellId = strToInt(argv[1]);
84 		if (spellId >= MS_AcidSpray && spellId <= MS_WizardEye) {
85 			_spellId = spellId;
86 			return false;
87 		}
88 	}
89 
90 	return true;
91 }
92 
cmdSpells(int argc,const char ** argv)93 bool Debugger::cmdSpells(int argc, const char **argv) {
94 	Party &party = *_vm->_party;
95 
96 	for (uint charIdx = 0; charIdx < party._activeParty.size(); ++charIdx) {
97 		Character &c = party._activeParty[charIdx];
98 		Common::fill(c._spells, c._spells + SPELLS_PER_CLASS, true);
99 		c._currentSp = 9999;
100 	}
101 
102 	party._gems += 1000;
103 
104 	debugPrintf("Spells given to party.\n");
105 	return true;
106 }
107 
cmdDump(int argc,const char ** argv)108 bool Debugger::cmdDump(int argc, const char **argv) {
109 	File f;
110 
111 	if (argc < 2) {
112 		debugPrintf("Format: dump <resource name>\n");
113 	} else {
114 		if (argc == 2)
115 			f.open(argv[1]);
116 
117 		if (f.isOpen()) {
118 			Common::DumpFile df;
119 			df.open(argv[1]);
120 			byte *data = new byte[f.size()];
121 			f.read(data, f.size());
122 			df.write(data, f.size());
123 
124 			f.close();
125 			df.close();
126 			delete[] data;
127 			debugPrintf("Saved\n");
128 		} else {
129 			debugPrintf("Could not find resource with that name\n");
130 		}
131 	}
132 
133 	return true;
134 }
135 
cmdGold(int argc,const char ** argv)136 bool Debugger::cmdGold(int argc, const char **argv) {
137 	Party &party = *_vm->_party;
138 	if (argc == 1) {
139 		debugPrintf("Current gold: %d, bank: %d\n", party._gold, party._bankGold);
140 	} else {
141 		party._gold = strToInt(argv[1]);
142 		if (argc > 2)
143 			party._bankGold = strToInt(argv[2]);
144 	}
145 
146 	return true;
147 }
148 
cmdGems(int argc,const char ** argv)149 bool Debugger::cmdGems(int argc, const char **argv) {
150 	Party &party = *_vm->_party;
151 	if (argc == 1) {
152 		debugPrintf("Current gems: %d, bank: %d\n", party._gems, party._bankGems);
153 	} else {
154 		party._gems = strToInt(argv[1]);
155 		if (argc > 2)
156 			party._bankGems = strToInt(argv[2]);
157 	}
158 
159 	return true;
160 }
161 
cmdMap(int argc,const char ** argv)162 bool Debugger::cmdMap(int argc, const char **argv) {
163 	Map &map = *g_vm->_map;
164 	Party &party = *g_vm->_party;
165 
166 	if (argc < 2) {
167 		debugPrintf("map mapId [ xp, yp ] [ sideNum ]\n");
168 		return true;
169 	} else {
170 		int mapId = strToInt(argv[1]);
171 		int x = argc < 3 ? 8 : strToInt(argv[2]);
172 		int y = argc < 4 ? 8 : strToInt(argv[3]);
173 
174 		if (argc == 5)
175 			map._loadCcNum = strToInt(argv[4]);
176 		map.load(mapId);
177 		party._mazePosition.x = x;
178 		party._mazePosition.y = y;
179 		party._mazeDirection = DIR_NORTH;
180 		return false;
181 	}
182 }
183 
cmdPos(int argc,const char ** argv)184 bool Debugger::cmdPos(int argc, const char **argv) {
185 	Party &party = *g_vm->_party;
186 
187 	if (argc < 3) {
188 		debugPrintf("pos xp, yp\n");
189 		return true;
190 	} else {
191 		party._mazePosition.x = strToInt(argv[1]);
192 		party._mazePosition.y = strToInt(argv[2]);
193 		party._stepped = true;
194 		return false;
195 	}
196 }
197 
cmdInvincible(int argc,const char ** argv)198 bool Debugger::cmdInvincible(int argc, const char **argv) {
199 	_invincible = (argc < 2) || strcmp(argv[1], "off");
200 	debugPrintf("Invincibility is %s\n", _invincible ? "on" : "off");
201 	return true;
202 }
203 
cmdSuperStrength(int argc,const char ** argv)204 bool Debugger::cmdSuperStrength(int argc, const char **argv) {
205 	_superStrength = (argc < 2) || strcmp(argv[1], "off");
206 	debugPrintf("Super-powered attacks are %s\n", _superStrength ? "on" : "off");
207 	return true;
208 }
209 
cmdIntangible(int argc,const char ** argv)210 bool Debugger::cmdIntangible(int argc, const char **argv) {
211 	_intangible = (argc < 2) || strcmp(argv[1], "off");
212 	debugPrintf("Intangibility is %s\n", _intangible ? "on" : "off");
213 	return true;
214 }
215 
216 } // End of namespace Xeen
217