1 /* ResidualVM - A 3D game interpreter
2  *
3  * ResidualVM is the legal property of its developers, whose names
4  * are too numerous to list here. Please refer to the AUTHORS
5  * file distributed with this source distribution.
6  *
7  * Additional copyright for this file:
8  * Copyright (C) 1999-2000 Revolution Software Ltd.
9  * This code is based on source code created by Revolution Software,
10  * used with permission.
11  *
12  * This program is free software; you can redistribute it and/or
13  * modify it under the terms of the GNU General Public License
14  * as published by the Free Software Foundation; either version 2
15  * of the License, or (at your option) any later version.
16  *
17  * This program is distributed in the hope that it will be useful,
18  * but WITHOUT ANY WARRANTY; without even the implied warranty of
19  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20  * GNU General Public License for more details.
21  *
22  * You should have received a copy of the GNU General Public License
23  * along with this program; if not, write to the Free Software
24  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
25  *
26  */
27 
28 #include "engines/icb/p4.h"
29 #include "engines/icb/keyboard.h"
30 #include "engines/icb/mouse.h"
31 #include "engines/icb/debug.h"
32 #include "engines/icb/res_man.h"
33 #include "engines/icb/direct_input.h"
34 #include "engines/icb/main_menu.h"
35 #include "engines/icb/gameover.h"
36 #include "engines/icb/common/px_common.h"
37 #include "engines/icb/stage_view.h"
38 #include "engines/icb/game_script.h"
39 #include "engines/icb/global_switches.h"
40 #include "engines/icb/movie_pc.h"
41 #include "engines/icb/options_manager_pc.h"
42 #include "engines/icb/mission.h"
43 
44 #include "common/keyboard.h"
45 #include "common/textconsole.h"
46 
47 namespace ICB {
48 
49 // Res_open will compute the hash value and store it
50 uint32 font_cluster_hash = NULL_HASH;
51 // Res_open will compute the hash value and store it
52 uint32 sys_font_hash = NULL_HASH;
53 
54 int32 gameCycle; // holds current game cycle - ticks up one each cycle
55 
56 // The PSX specific code is in p4_psx.cpp
57 // PC specific code is in p4_pc.cpp
58 
_stub()59 _stub::_stub() {
60 	// setup the stub object
61 
62 	Zdebug("+constructing stub+");
63 
64 	// set to level 0
65 	stub = 0;
66 
67 	mode[0] = __no_stub_mode; // engine MUST set a real mode depending upon environment
68 
69 	Timer_on();
70 	cycle_speed = 100;
71 }
72 
~_stub()73 _stub::~_stub() {
74 	// kill the stub object
75 
76 	Zdebug("*destructing stub*");
77 }
78 
Reset(__stub_modes new_mode)79 void _stub::Reset(__stub_modes new_mode) {
80 	stub = 0;
81 	mode[stub] = new_mode;
82 }
83 
Set_current_stub_mode(__stub_modes new_mode)84 void _stub::Set_current_stub_mode(__stub_modes new_mode) {
85 	// force current mode
86 
87 	mode[stub] = new_mode;
88 }
89 
Process_stub()90 void _stub::Process_stub() {
91 	// call the mode!
92 
93 	// Check for pause key .... moved from player::UpdateInputStates so the pause
94 	// menu is reachable regardless of the players state (ie in conversation)
95 	if (mode[stub] == __mission_and_console) {
96 		{
97 			if (Read_DI_once_keys(pause_key)) {
98 				if (!g_theOptionsManager->HasControl())
99 					g_theOptionsManager->StartInGameOptions();
100 				return;
101 			}
102 		}
103 	}
104 
105 	// reset the time equaliser
106 	Reset_timer();
107 
108 	switch (mode[stub]) {
109 	case __no_stub_mode:
110 		Fatal_error("no stub mode set!");
111 		break; // should never happen, all this
112 
113 	case __toe_on_door:
114 		Main_menu();
115 		break;
116 
117 	case __mission_and_console:
118 
119 		Mission_and_console();
120 
121 		Fix_time();
122 		Update_screen();
123 		break;
124 
125 	case __game_script:
126 
127 		gs.Process_game_script();
128 		break;
129 
130 	case __shift_mode:
131 
132 		Headup_debug_switcher();
133 		Update_screen();
134 		break;
135 
136 	case __troute:
137 
138 		break;
139 
140 	case __set_test:
141 
142 		break;
143 
144 	case __font_test:
145 
146 		break;
147 
148 	case __stage_view:
149 		// REMOVED
150 		break;
151 
152 	case __sequence:
153 
154 		// Ask to bink to display a frame of the movie
155 		int32 ret;
156 		ret = g_theSequenceManager->drawFrame();
157 
158 		// Actions on return value
159 		if (ret == NOMOVIE) {
160 			// No movie registered (illegal use of this stub mode)
161 			Fatal_error("Can't draw movie frame when when no movie registered!");
162 		} else if (ret == FINISHED) {
163 			// Set any sounds active again
164 			g_TimerOn = TRUE8;
165 			UnpauseSounds();
166 
167 			// All done so return to whatever was being done previously
168 			Pop_stub_mode();
169 		} else if (ret == WAITING) {
170 			// This smooths the playback framerate
171 			Fix_time();
172 		}
173 		Update_screen();
174 		break;
175 
176 	case __pause_menu:
177 
178 		Pause_menu();
179 		break;
180 
181 	case __gameover_menu:
182 
183 		Gameover_menu();
184 		break;
185 
186 	case __options_menu:
187 
188 		Fatal_error("__options_menu stub not supported on PC");
189 
190 		break;
191 
192 	case __load_save_menu:
193 
194 		Fatal_error("__load_save_menu stub not supported on PC");
195 
196 		break;
197 
198 	case __credits:
199 
200 		Credits();
201 		break;
202 
203 	case __scrolling_text:
204 
205 		ScrollingText();
206 		break;
207 
208 	default:
209 
210 		Fatal_error("unsupported stub mode");
211 		break;
212 	}
213 }
214 
Update_screen()215 void _stub::Update_screen() {
216 	// had to be split off to stop screen updates between stub cycles - i.e. sequence to game...
217 
218 	// Record the next frame of the video if any
219 	static uint32 frameNumber = 0;
220 	if (g_px->recordingVideo)
221 		surface_manager->RecordFrame(pxVString("icb%05d.bmp", frameNumber++));
222 
223 	// Grab screen shots if required
224 	if (Read_DI_keys(Common::KEYCODE_LCTRL) || Read_DI_keys(Common::KEYCODE_RCTRL)) {
225 		if (Read_DI_keys(Common::KEYCODE_s)) {
226 			// Take a screen grab
227 			surface_manager->RecordFrame(pxVString("ScreenShot_%08d.bmp", g_system->getMillis()));
228 		}
229 	}
230 
231 	g_icb_mission->flip_time = GetMicroTimer();
232 	// FLIP
233 	surface_manager->Flip();
234 	g_icb_mission->flip_time = GetMicroTimer() - g_icb_mission->flip_time;
235 }
236 
Push_stub_mode(__stub_modes new_mode)237 void _stub::Push_stub_mode(__stub_modes new_mode) {
238 	// push mode
239 
240 	stub++;
241 	if (stub >= TOTAL_STUBS) {
242 		Message_box("Push_stub gone too far %d MAX %d", stub, TOTAL_STUBS);
243 		stub = TOTAL_STUBS - 1;
244 	}
245 	mode[stub] = new_mode;
246 }
247 
Pop_stub_mode()248 void _stub::Pop_stub_mode() {
249 	// pop mode
250 
251 	if (stub)
252 		stub--;
253 }
254 
Return_current_stub()255 __stub_modes _stub::Return_current_stub() {
256 	// return the mode
257 	// brother jake will know if in floors mode
258 
259 	return (mode[stub]);
260 }
261 
Reset_timer()262 void _stub::Reset_timer() {
263 	stub_timer_time = g_system->getMillis();
264 }
265 
Timer_off()266 void _stub::Timer_off() {
267 	// switch the frame fixer off
268 
269 	timer = FALSE8;
270 }
271 
Timer_on()272 void _stub::Timer_on() {
273 	// switch the frame fixer on
274 
275 	timer = TRUE8;
276 }
277 
Return_timer_status()278 bool8 _stub::Return_timer_status() {
279 	// return on/off status
280 
281 	return (timer);
282 }
283 
284 } // End of namespace ICB
285