1 //Copyright Paul Reiche, Fred Ford. 1992-2002
2 
3 /*
4  *  This program is free software; you can redistribute it and/or modify
5  *  it under the terms of the GNU General Public License as published by
6  *  the Free Software Foundation; either version 2 of the License, or
7  *  (at your option) any later version.
8  *
9  *  This program is distributed in the hope that it will be useful,
10  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
11  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  *  GNU General Public License for more details.
13  *
14  *  You should have received a copy of the GNU General Public License
15  *  along with this program; if not, write to the Free Software
16  *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17  */
18 
19 #include "setup.h"
20 
21 #include "coderes.h"
22 #include "controls.h"
23 #include "options.h"
24 #include "nameref.h"
25 #ifdef NETPLAY
26 #	include "supermelee/netplay/netmelee.h"
27 #endif
28 #include "init.h"
29 #include "intel.h"
30 #include "status.h"
31 #include "resinst.h"
32 #include "sounds.h"
33 #include "libs/compiler.h"
34 #include "libs/uio.h"
35 #include "libs/file.h"
36 #include "libs/graphics/gfx_common.h"
37 #include "libs/sound/sound.h"
38 #include "libs/threadlib.h"
39 #include "libs/vidlib.h"
40 #include "libs/log.h"
41 #include "libs/misc.h"
42 
43 #include <assert.h>
44 #include <errno.h>
45 #include <string.h>
46 
47 
48 ACTIVITY LastActivity;
49 BYTE PlayerControl[NUM_PLAYERS];
50 
51 // XXX: These declarations should really go to the file they belong to.
52 RESOURCE_INDEX hResIndex;
53 CONTEXT ScreenContext;
54 CONTEXT SpaceContext;
55 CONTEXT StatusContext;
56 CONTEXT OffScreenContext;
57 SIZE screen_width, screen_height;
58 FRAME Screen;
59 FONT StarConFont;
60 FONT MicroFont;
61 FONT TinyFont;
62 QUEUE race_q[NUM_PLAYERS];
63 FRAME ActivityFrame;
64 FRAME StatusFrame;
65 FRAME FlagStatFrame;
66 FRAME MiscDataFrame;
67 FRAME FontGradFrame;
68 STRING GameStrings;
69 QUEUE disp_q;
70 
71 uio_Repository *repository;
72 uio_DirHandle *rootDir;
73 
74 BOOLEAN usingSpeech;
75 
76 
77 static void
InitPlayerInput(void)78 InitPlayerInput (void)
79 {
80 }
81 
82 void
UninitPlayerInput(void)83 UninitPlayerInput (void)
84 {
85 #if DEMO_MODE
86 	DestroyInputDevice (ReleaseInputDevice (DemoInput));
87 #endif /* DEMO_MODE */
88 }
89 
90 BOOLEAN
LoadKernel(int argc,char * argv[])91 LoadKernel (int argc, char *argv[])
92 {
93 	InitSound (argc, argv);
94 	InitVideoPlayer (TRUE);
95 
96 	ScreenContext = CreateContext ("ScreenContext");
97 	if (ScreenContext == NULL)
98 		return FALSE;
99 
100 	Screen = CaptureDrawable (CreateDisplay (WANT_MASK | WANT_PIXMAP,
101 				&screen_width, &screen_height));
102 	if (Screen == NULL)
103 		return FALSE;
104 
105 	SetContext (ScreenContext);
106 	SetContextFGFrame (Screen);
107 	SetContextOrigin (MAKE_POINT (0, 0));
108 
109 	hResIndex = (RESOURCE_INDEX) InitResourceSystem ();
110 	if (hResIndex == 0)
111 		return FALSE;
112 
113 	/* Load base content. */
114 	if (loadIndices (contentDir) == 0)
115 		return FALSE; // Must have at least one index in content dir
116 
117 	/* Load addons demanded by the current configuration. */
118 	if (opt3doMusic)
119 	{
120 		loadAddon ("3domusic");
121 	}
122 
123 	usingSpeech = optSpeech;
124 	if (optSpeech && !loadAddon ("3dovoice"))
125 	{
126 		usingSpeech = FALSE;
127 	}
128 
129 	if (optRemixMusic)
130 	{
131 		loadAddon ("remix");
132 	}
133 
134 	if (optWhichIntro == OPT_3DO)
135 	{
136 		loadAddon ("3dovideo");
137 	}
138 
139 	/* Now load the rest of the addons, in order. */
140 	prepareAddons (optAddons);
141 
142 	{
143 		COLORMAP ColorMapTab;
144 
145 		ColorMapTab = CaptureColorMap (LoadColorMap (STARCON_COLOR_MAP));
146 		if (ColorMapTab == NULL)
147 			return FALSE; // The most basic resource is missing
148 		SetColorMap (GetColorMapAddress (ColorMapTab));
149 		DestroyColorMap (ReleaseColorMap (ColorMapTab));
150 	}
151 
152 	InitPlayerInput ();
153 
154 	GLOBAL (CurrentActivity) = (ACTIVITY)~0;
155 	return TRUE;
156 }
157 
158 BOOLEAN
InitContexts(void)159 InitContexts (void)
160 {
161 	RECT r;
162 
163 	StatusContext = CreateContext ("StatusContext");
164 	if (StatusContext == NULL)
165 		return FALSE;
166 
167 	SetContext (StatusContext);
168 	SetContextFGFrame (Screen);
169 	r.corner.x = SPACE_WIDTH + SAFE_X;
170 	r.corner.y = SAFE_Y;
171 	r.extent.width = STATUS_WIDTH;
172 	r.extent.height = STATUS_HEIGHT;
173 	SetContextClipRect (&r);
174 
175 	SpaceContext = CreateContext ("SpaceContext");
176 	if (SpaceContext == NULL)
177 		return FALSE;
178 
179 	OffScreenContext = CreateContext ("OffScreenContext");
180 	if (OffScreenContext == NULL)
181 		return FALSE;
182 
183 	if (!InitQueue (&disp_q, MAX_DISPLAY_ELEMENTS, sizeof (ELEMENT)))
184 		return FALSE;
185 
186 	return TRUE;
187 }
188 
189 static BOOLEAN
InitKernel(void)190 InitKernel (void)
191 {
192 	COUNT counter;
193 
194 	for (counter = 0; counter < NUM_PLAYERS; ++counter)
195 		InitQueue (&race_q[counter], MAX_SHIPS_PER_SIDE, sizeof (STARSHIP));
196 
197 	StarConFont = LoadFont (STARCON_FONT);
198 	if (StarConFont == NULL)
199 		return FALSE;
200 
201 	TinyFont = LoadFont (TINY_FONT);
202 	if (TinyFont == NULL)
203 		return FALSE;
204 
205 	ActivityFrame = CaptureDrawable (LoadGraphic (ACTIVITY_ANIM));
206 	if (ActivityFrame == NULL)
207 		return FALSE;
208 
209 	StatusFrame = CaptureDrawable (LoadGraphic (STATUS_MASK_PMAP_ANIM));
210 	if (StatusFrame == NULL)
211 		return FALSE;
212 
213 	GameStrings = CaptureStringTable (LoadStringTable (STARCON_GAME_STRINGS));
214 	if (GameStrings == 0)
215 		return FALSE;
216 
217 	MicroFont = LoadFont (MICRO_FONT);
218 	if (MicroFont == NULL)
219 		return FALSE;
220 
221 	MenuSounds = CaptureSound (LoadSound (MENU_SOUNDS));
222 	if (MenuSounds == 0)
223 		return FALSE;
224 
225 	InitStatusOffsets ();
226 	InitSpace ();
227 
228 	return TRUE;
229 }
230 
231 BOOLEAN
InitGameKernel(void)232 InitGameKernel (void)
233 {
234 	if (ActivityFrame == 0)
235 	{
236 		InitKernel ();
237 		InitContexts ();
238 	}
239 	return TRUE;
240 }
241 
242 bool
SetPlayerInput(COUNT playerI)243 SetPlayerInput (COUNT playerI)
244 {
245 	assert (PlayerInput[playerI] == NULL);
246 
247 	switch (PlayerControl[playerI] & CONTROL_MASK) {
248 		case HUMAN_CONTROL:
249 			PlayerInput[playerI] =
250 					(InputContext *) HumanInputContext_new (playerI);
251 			break;
252 		case COMPUTER_CONTROL:
253 		case CYBORG_CONTROL:
254 			// COMPUTER_CONTROL is used in SuperMelee; the computer chooses
255 			// the ships and fights the battles.
256 			// CYBORG_CONTROL is used in the full game; the computer only
257 			// fights the battles. XXX: This will need to be handled
258 			// separately in the future if we want to remove the special
259 			// cases for ship selection with CYBORG_CONTROL from the
260 			// computer handlers.
261 			PlayerInput[playerI] =
262 					(InputContext *) ComputerInputContext_new (playerI);
263 			break;
264 #ifdef NETPLAY
265 		case NETWORK_CONTROL:
266 			PlayerInput[playerI] =
267 					(InputContext *) NetworkInputContext_new (playerI);
268 			break;
269 #endif
270 		default:
271 			log_add (log_Fatal,
272 					"Invalid control method in SetPlayerInput().");
273 			explode ();  /* Does not return */
274 	}
275 
276 	return PlayerInput[playerI] != NULL;
277 }
278 
279 bool
SetPlayerInputAll(void)280 SetPlayerInputAll (void)
281 {
282 	COUNT playerI;
283 	for (playerI = 0; playerI < NUM_PLAYERS; playerI++)
284 		if (!SetPlayerInput (playerI))
285 			return false;
286 	return true;
287 }
288 
289 void
ClearPlayerInput(COUNT playerI)290 ClearPlayerInput (COUNT playerI)
291 {
292 	if (PlayerInput[playerI] == NULL) {
293 		log_add (log_Debug, "ClearPlayerInput(): PlayerInput[%d] was NULL.",
294 				playerI);
295 		return;
296 	}
297 
298 	PlayerInput[playerI]->handlers->deleteContext (PlayerInput[playerI]);
299 	PlayerInput[playerI] = NULL;
300 }
301 
302 void
ClearPlayerInputAll(void)303 ClearPlayerInputAll (void)
304 {
305 	COUNT playerI;
306 	for (playerI = 0; playerI < NUM_PLAYERS; playerI++)
307 		ClearPlayerInput (playerI);
308 }
309 
310 int
initIO(void)311 initIO (void)
312 {
313 	uio_init ();
314 	repository = uio_openRepository (0);
315 
316 	rootDir = uio_openDir (repository, "/", 0);
317 	if (rootDir == NULL)
318 	{
319 		log_add (log_Fatal, "Could not open '/' dir.");
320 		return -1;
321 	}
322 	return 0;
323 }
324 
325 void
uninitIO(void)326 uninitIO (void)
327 {
328 	uio_closeDir (rootDir);
329 	uio_closeRepository (repository);
330 	uio_unInit ();
331 }
332 
333