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 size_t size = strlen(s);
31
32 if (size == 0)
33 // No string at all
34 return 0;
35
36 if (toupper(s[size - 1]) != 'H')
37 // Standard decimal string
38 return atoi(s);
39
40 // Hexadecimal string
41 uint tmp = 0;
42 int read = sscanf(s, "%xh", &tmp);
43 if (read < 1)
44 error("strToInt failed on string \"%s\"", s);
45 return (int)tmp;
46 }
47
48 /*------------------------------------------------------------------------*/
49
Debugger(XeenEngine * vm)50 Debugger::Debugger(XeenEngine *vm) : GUI::Debugger(), _vm(vm),
51 _spellId(-1), _invincible(false), _intangible(false), _superStrength(false) {
52 registerCmd("continue", WRAP_METHOD(Debugger, cmdExit));
53 registerCmd("spell", WRAP_METHOD(Debugger, cmdSpell));
54 registerCmd("spells", WRAP_METHOD(Debugger, cmdSpells));
55 registerCmd("dump", WRAP_METHOD(Debugger, cmdDump));
56 registerCmd("gold", WRAP_METHOD(Debugger, cmdGold));
57 registerCmd("gems", WRAP_METHOD(Debugger, cmdGems));
58 registerCmd("map", WRAP_METHOD(Debugger, cmdMap));
59 registerCmd("pos", WRAP_METHOD(Debugger, cmdPos));
60 registerCmd("invincible", WRAP_METHOD(Debugger, cmdInvincible));
61 registerCmd("strength", WRAP_METHOD(Debugger, cmdSuperStrength));
62 registerCmd("intangible", WRAP_METHOD(Debugger, cmdIntangible));
63 }
64
onFrame()65 void Debugger::onFrame() {
66 if (_spellId != -1) {
67 // Cast any specified spell
68 MagicSpell spellId = (MagicSpell)_spellId;
69 _spellId = -1;
70 Character *c = &_vm->_party->_activeParty[0];
71 c->_currentSp = 99;
72 _vm->_spells->castSpell(c, spellId);
73 }
74
75 GUI::Debugger::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
121 size_t size = f.size();
122 byte *data = new byte[size];
123
124 if (f.read(data, size) == size) {
125 df.write(data, size);
126
127 } else {
128 debugPrintf("Failed to read %zu bytes from '%s'\n", size, argv[1]);
129 }
130
131 f.close();
132 df.close();
133 delete[] data;
134 debugPrintf("Saved\n");
135 } else {
136 debugPrintf("Could not find resource with that name\n");
137 }
138 }
139
140 return true;
141 }
142
cmdGold(int argc,const char ** argv)143 bool Debugger::cmdGold(int argc, const char **argv) {
144 Party &party = *_vm->_party;
145 if (argc == 1) {
146 debugPrintf("Current gold: %d, bank: %d\n", party._gold, party._bankGold);
147 } else {
148 party._gold = strToInt(argv[1]);
149 if (argc > 2)
150 party._bankGold = strToInt(argv[2]);
151 }
152
153 return true;
154 }
155
cmdGems(int argc,const char ** argv)156 bool Debugger::cmdGems(int argc, const char **argv) {
157 Party &party = *_vm->_party;
158 if (argc == 1) {
159 debugPrintf("Current gems: %d, bank: %d\n", party._gems, party._bankGems);
160 } else {
161 party._gems = strToInt(argv[1]);
162 if (argc > 2)
163 party._bankGems = strToInt(argv[2]);
164 }
165
166 return true;
167 }
168
cmdMap(int argc,const char ** argv)169 bool Debugger::cmdMap(int argc, const char **argv) {
170 if (argc < 2) {
171 debugPrintf("map mapId [ xp, yp ] [ sideNum ]\n");
172 return true;
173 } else {
174 Map &map = *g_vm->_map;
175 Party &party = *g_vm->_party;
176
177 int mapId = strToInt(argv[1]);
178 int x = argc < 3 ? 8 : strToInt(argv[2]);
179 int y = argc < 4 ? 8 : strToInt(argv[3]);
180
181 if (argc == 5)
182 map._loadCcNum = strToInt(argv[4]);
183 map.load(mapId);
184 party._mazePosition.x = x;
185 party._mazePosition.y = y;
186 party._mazeDirection = DIR_NORTH;
187 return false;
188 }
189 }
190
cmdPos(int argc,const char ** argv)191 bool Debugger::cmdPos(int argc, const char **argv) {
192 Party &party = *g_vm->_party;
193
194 if (argc < 3) {
195 debugPrintf("pos xp, yp\n");
196 return true;
197 } else {
198 party._mazePosition.x = strToInt(argv[1]);
199 party._mazePosition.y = strToInt(argv[2]);
200 party._stepped = true;
201 return false;
202 }
203 }
204
cmdInvincible(int argc,const char ** argv)205 bool Debugger::cmdInvincible(int argc, const char **argv) {
206 _invincible = (argc < 2) || strcmp(argv[1], "off");
207 debugPrintf("Invincibility is %s\n", _invincible ? "on" : "off");
208 return true;
209 }
210
cmdSuperStrength(int argc,const char ** argv)211 bool Debugger::cmdSuperStrength(int argc, const char **argv) {
212 _superStrength = (argc < 2) || strcmp(argv[1], "off");
213 debugPrintf("Super-powered attacks are %s\n", _superStrength ? "on" : "off");
214 return true;
215 }
216
cmdIntangible(int argc,const char ** argv)217 bool Debugger::cmdIntangible(int argc, const char **argv) {
218 _intangible = (argc < 2) || strcmp(argv[1], "off");
219 debugPrintf("Intangibility is %s\n", _intangible ? "on" : "off");
220 return true;
221 }
222
223 } // End of namespace Xeen
224