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