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 "startrek/console.h"
24 #include "gui/debugger.h"
25 #include "startrek/room.h"
26 #include "startrek/startrek.h"
27
28 namespace StarTrek {
29
Console(StarTrekEngine * vm)30 Console::Console(StarTrekEngine *vm) : GUI::Debugger(), _vm(vm) {
31 registerCmd("room", WRAP_METHOD(Console, Cmd_Room));
32 registerCmd("actions", WRAP_METHOD(Console, Cmd_Actions));
33 registerCmd("text", WRAP_METHOD(Console, Cmd_Text));
34 }
35
~Console()36 Console::~Console() {
37 }
38
Cmd_Room(int argc,const char ** argv)39 bool Console::Cmd_Room(int argc, const char **argv) {
40 if (argc < 3) {
41 debugPrintf("Current room: %s\n", _vm->getScreenName().c_str());
42 debugPrintf("Use room <mission> <room> to teleport\n");
43 debugPrintf("Valid missions are: DEMON, TUG, LOVE, MUDD, FEATHER, TRIAL, SINS, VENG\n");
44 return true;
45 }
46
47 _vm->_missionToLoad = argv[1];
48 _vm->_missionToLoad.toUppercase();
49 _vm->_roomIndexToLoad = atoi(argv[2]);
50 _vm->runAwayMission();
51
52 return false;
53 }
54
Cmd_Actions(int argc,const char ** argv)55 bool Console::Cmd_Actions(int argc, const char **argv) {
56 Common::String screenName = _vm->getScreenName();
57
58 if (argc == 3) {
59 Common::String missionName = argv[1];
60 missionName.toUppercase();
61 int roomIndex = atoi(argv[2]);
62
63 screenName = missionName + (char)(roomIndex + '0');
64 }
65
66 Common::MemoryReadStreamEndian *rdfFile = _vm->loadFile(screenName + ".RDF");
67 rdfFile->seek(14);
68
69 uint16 startOffset = rdfFile->readUint16LE();
70 uint16 endOffset = rdfFile->readUint16LE();
71 uint16 offset = startOffset;
72
73 while (offset < endOffset) {
74 rdfFile->seek(offset);
75
76 uint32 action = rdfFile->readUint32LE();
77 uint16 nextOffset = rdfFile->readUint16LE();
78
79 debugPrintf("Offset %d: %s\n", offset, EventToString(action).c_str());
80 offset = nextOffset;
81 }
82
83 delete rdfFile;
84
85 return true;
86 }
87
Cmd_Text(int argc,const char ** argv)88 bool Console::Cmd_Text(int argc, const char **argv) {
89 typedef Common::HashMap<int, Common::String>::iterator MessageIterator;
90
91 debugPrintf("\nLook messages\n");
92 debugPrintf("-------------\n");
93 for (MessageIterator i = _vm->_room->_lookMessages.begin(); i != _vm->_room->_lookMessages.end(); ++i) {
94 debugPrintf("%i: %s\n", i->_key, i->_value.c_str());
95 }
96
97 debugPrintf("\nLook with talker messages\n");
98 debugPrintf("-------------------------\n");
99 for (MessageIterator i = _vm->_room->_lookWithTalkerMessages.begin(); i != _vm->_room->_lookWithTalkerMessages.end(); ++i) {
100 debugPrintf("%i: %s\n", i->_key, i->_value.c_str());
101 }
102
103 debugPrintf("\nTalk messages\n");
104 debugPrintf("-------------\n");
105 for (MessageIterator i = _vm->_room->_talkMessages.begin(); i != _vm->_room->_talkMessages.end(); ++i) {
106 debugPrintf("%i: %s\n", i->_key, i->_value.c_str());
107 }
108
109 return true;
110 }
111
EventToString(uint32 action)112 Common::String Console::EventToString(uint32 action) {
113 const char *actions[] = {
114 "Tick",
115 "Walk",
116 "Use",
117 "Get",
118 "Look",
119 "Talk"
120 };
121
122 byte verb = action & 0xff;
123 byte subject = (action >> 8) & 0xff;
124 byte b2 = (action >> 16) & 0xff;
125 byte b3 = (action >> 24) & 0xff;
126
127 String retString;
128 switch (verb) {
129 case 0: // Tick
130 retString = Common::String::format("Tick %d", (subject | (b2 << 8)));
131 break;
132 case 2: // Use
133 retString = Common::String(actions[verb]) + " " + ItemToString(subject) + ", " + ItemToString(b2);
134 break;
135 case 1: // Walk
136 case 3: // Get
137 case 4: // Look
138 case 5: // Talk
139 retString = Common::String(actions[verb]) + " " + ItemToString(subject);
140 break;
141 case 6: // Warp touched
142 retString = Common::String::format("Touched warp %d", subject);
143 break;
144 case 7: // Hotspot touched
145 retString = Common::String::format("Touched hotspot %d", subject);
146 break;
147 case 8: // Timer expired
148 retString = Common::String::format("Timer %d expired", subject);
149 break;
150 case 10: // Animation finished
151 retString = Common::String::format("Finished animation (%d)", subject);
152 break;
153 case 12: // Walking finished
154 retString = Common::String::format("Finished walking (%d)", subject);
155 break;
156 default:
157 retString = Common::String::format("%x%x%x%x", verb, subject, b2, b3);
158 break;
159 }
160
161 // Check for actions using bytes they're not expected to use
162 if (b3 != 0)
163 debugPrintf("WARNING: b3 nonzero in action: %s\n", retString.c_str());
164 if (b2 != 0 && verb != 0 && verb != 2)
165 debugPrintf("WARNING: b2 nonzero in action: %s\n", retString.c_str());
166
167 return retString;
168 }
169
170 const char *itemNames[] = {
171 "IPHASERS",
172 "IPHASERK",
173 "IHAND",
174 "IROCK",
175 "ISTRICOR",
176 "IMTRICOR",
177 "IDEADGUY",
178 "ICOMM",
179 "IPBC",
180 "IRLG",
181 "IWRENCH",
182 "IINSULAT",
183 "ISAMPLE",
184 "ICURE",
185 "IDISHES",
186 "IRT",
187 "IRTWB",
188 "ICOMBBIT",
189 "IJNKMETL",
190 "IWIRING",
191 "IWIRSCRP",
192 "IPWF",
193 "IPWE",
194 "IDEADPH",
195 "IBOMB",
196 "IMETAL",
197 "ISKULL",
198 "IMINERAL",
199 "IMETEOR",
200 "ISHELLS",
201 "IDEGRIME",
202 "ILENSES",
203 "IDISKS",
204 "IANTIGRA",
205 "IN2GAS",
206 "IO2GAS",
207 "IH2GAS",
208 "IN2O",
209 "INH3",
210 "IH2O",
211 "IWROD",
212 "IIROD",
213 "IREDGEM_A",
214 "IREDGEM_B",
215 "IREDGEM_C",
216 "IGRNGEM_A",
217 "IGRNGEM_B",
218 "IGRNGEM_C",
219 "IBLUGEM_A",
220 "IBLUGEM_B",
221 "IBLUGEM_C",
222 "ICONECT",
223 "IS8ROCKS",
224 "IIDCARD",
225 "ISNAKE",
226 "IFERN",
227 "ICRYSTAL",
228 "IKNIFE",
229 "IDETOXIN",
230 "IBERRY",
231 "IDOOVER",
232 "IALIENDV",
233 "ICAPSULE",
234 "IMEDKIT",
235 "IBEAM",
236 "IDRILL",
237 "IHYPO",
238 "IFUSION",
239 "ICABLE1",
240 "ICABLE2",
241 "ILMD",
242 "IDECK",
243 "ITECH"
244 };
245
ItemToString(byte index)246 Common::String Console::ItemToString(byte index) {
247 if (index == 0)
248 return "KIRK";
249 else if (index == 1)
250 return "SPOCK";
251 else if (index == 2)
252 return "MCCOY";
253 else if (index == 3)
254 return "REDSHIRT";
255 else if (index >= 0x40 && (index - 0x40) < ARRAYSIZE(itemNames))
256 return itemNames[index - 0x40];
257 return Common::String(Common::String::format("0x%02x:", index)); // TODO
258 }
259
260 } // End of namespace StarTrek
261