1 /*
2
3 Copyright (C) 2015-2018 Night Dive Studios, LLC.
4
5 This program is free software: you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation, either version 3 of the License, or
8 (at your option) any later version.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>.
17
18 */
19 //====================================================================================
20 //
21 // System Shock - ©1994-1995 Looking Glass Technologies, Inc.
22 //
23 // InitMac.c - Initialize Mac toolbox managers and setup the application's globals.
24 //
25 //====================================================================================
26
27
28 //--------------------
29 // Includes
30 //--------------------
31 //#include <Carbon/Carbon.h>
32 //#include "OldCarbonLibraries.h"
33 //#include <Palettes.h>
34 //#include <GestaltEqu.h>
35 //#include <Movies.h>
36 //#include <Timer.h>
37
38 #include "Shock.h"
39 #include "InitMac.h"
40 #include "ShockBitmap.h"
41
42 //QDGlobals qd;
43
44 //--------------------
45 // Globals
46 //--------------------
47 /*Handle gExtraMemory = nil;
48 ColorSpec *gOriginalColors;
49 unsigned long gRandSeed;
50 short gMainVRef;
51 //CursHandle gWatchCurs;
52 short gOriginalDepth = -1;
53 short gLastAlertDepth = -1;
54 short gStartupDepth;
55 Ptr gScreenAddress;
56 long gScreenRowbytes;
57 short gScreenWide, gScreenHigh;
58 short gActiveWide, gActiveHigh;
59 short gActiveLeft, gActiveTop;
60 Rect gActiveArea, gOffActiveArea;
61 Boolean gIsPowerPC = false;
62 long gDataDirID;
63 short gDataVref;
64 long gAlogDirID;
65 short gAlogVref;
66 long gBarkDirID;
67 short gBarkVref;*/
68
69 //---------------------------
70 // Time Manager routines and globals
71 //---------------------------
72 /*typedef struct
73 {
74 TMTask task; // The actual TimeManager task structure
75 long appA5; // We need this silly thing for 68K programs
76 }
77 ShockTask, *ShockTaskPtr;*/
78
79 /*#define kShockTicksFreq -3571
80 TimerUPP pShockTicksPtr; // Globals for the Shock "tickcount" TM task.
81 ShockTask pShockTicksTask; // It increments gShockTicks 280 times per second.
82 long gShockTicks;
83 long *tmd_ticks;*/
84
85
86
87 //------------------------------------------------------------------------------------
88 // Initialize the Macintosh managers.
89 //------------------------------------------------------------------------------------
InitMac(void)90 void InitMac(void)
91 {
92 short i;
93
94 //InitGraf(&qd.thePort);
95 /*InitFonts();
96 InitWindows();
97 InitMenus();
98 TEInit();
99 InitDialogs(nil);
100 InitCursor();
101
102 MaxApplZone();
103 for (i=0; i<10; i++) // Get some room for more handles
104 MoreMasters();
105
106 // Allocate memory for various things, initialize others
107
108 gExtraMemory = NewHandle(16384L); // Some extra room in case we have to die
109
110 FailNIL(gOriginalColors = (ColorSpec *)malloc(256 * sizeof(ColorSpec))); // Original palette
111
112 GetDateTime(&gRandSeed); // Start off with a random seed
113 gRandSeed += TickCount()<<8;
114
115 GetVol(nil, &gMainVRef); // Where was I launched from?
116 */
117
118 //gWatchCurs = GetCursor(watchCursor);
119 //HNoPurge((Handle)gWatchCurs);
120
121 // EnterMovies();
122 // InstallShockTimers();
123 }
124
125 //------------------------------------------------------------------------------------
126 // Make sure the game can run on this mo-sheen.
127 //------------------------------------------------------------------------------------
CheckConfig(void)128 void CheckConfig(void)
129 {
130 /*OSErr err;
131 long resp;
132 int depth;
133 GDHandle devhandle;
134 PixMapHandle pmhan;
135
136 // Check for System 7
137 err = Gestalt(gestaltSystemVersion, &resp);
138 if (err || (!err && resp < 0x0700))
139 ErrorDie(2);
140
141 // Check for 32-bit mode
142 err = Gestalt(gestaltAddressingModeAttr, &resp);
143 if (err || (!err && (resp & (1 << gestalt32BitAddressing) == 0)))
144 ErrorDie(8);
145
146 // Check for Color QD
147 err = Gestalt(gestaltQuickdrawFeatures, &resp);
148 if (!err && (resp & (1 << gestaltHasColor)))
149 {
150 devhandle = GetMainDevice();
151 pmhan = (*devhandle)->gdPMap;
152 depth = (*pmhan)->pixelSize;
153
154 // if we're in 8 bit, save off the color table. If not, check to see if it is available
155 // and switch to it if we can. Also save the original color depth.
156
157 if (depth == 8)
158 BlockMove((**((*pmhan)->pmTable)).ctTable, gOriginalColors, 256*sizeof(ColorSpec));
159 else
160 {
161 if (HasDepth(devhandle,8,0,0))
162 {
163 InitCursor();
164 if (StopAlert(1002, nil) == 1)
165 {
166 gOriginalDepth = depth; // Save original depth so we can switch back
167 SetDepth(devhandle,8,0,0);
168 devhandle = GetMainDevice();
169 pmhan = (*devhandle)->gdPMap;
170 depth = (*pmhan)->pixelSize;
171 }
172 else
173 CleanupAndExit();
174 }
175 else
176 ErrorDie(4);
177 }
178 }
179 else
180 ErrorDie(4);
181
182 // Check for QuickTime 2.0
183 err = Gestalt(gestaltQuickTime, &resp);
184 if (err || (!err && resp < 0x02000000))
185 ErrorDie(6);
186
187 // Check for Sound Manager 3.0. We do this by checking for multiple channel support, which is only
188 // available with SM 3.0. If it returns an error, then die.
189 err = Gestalt(gestaltSoundAttr, &resp);
190 if (err || (!err && (resp & (1 << gestaltMultiChannels) == 0)))
191 ErrorDie(7);
192
193 // Record info about the main monitor size.
194 gStartupDepth = depth;
195 gScreenRowbytes = (long)((*pmhan)->rowBytes & 0x7FFF);
196 gScreenAddress = (*pmhan)->baseAddr;
197 gScreenWide = (*pmhan)->bounds.right - (*pmhan)->bounds.left;
198 gScreenHigh = (*pmhan)->bounds.bottom - (*pmhan)->bounds.top;
199
200 // If the screen is larger than 640x480, then center the "active" area in the screen.
201 if (gScreenWide >= 640 && gScreenHigh >= 480)
202 {
203 gActiveWide = screenMaxX;
204 gActiveHigh = screenMaxY;
205 }
206 else
207 ErrorDie(11);
208
209 gActiveLeft = ((gScreenWide>>1) - (gActiveWide>>1)) & 0x7FFE; // put it on even byte
210 gActiveTop = ((gScreenHigh - GetMBarHeight()) >> 1) - (gActiveHigh>>1);
211
212 if (gActiveTop < GetMBarHeight())
213 gActiveTop = 0;
214 gActiveTop += GetMBarHeight();
215 SetRect(&gActiveArea, gActiveLeft, gActiveTop, gActiveWide+gActiveLeft, gActiveHigh+gActiveTop);
216 SetRect(&gOffActiveArea, 0, 0, gActiveWide, gActiveHigh);
217
218 // Fix up ScreenAddress (so it really points to the first address of the active area)
219 gScreenAddress += (gScreenRowbytes * (long)gActiveTop);
220 gScreenAddress += gActiveLeft;
221
222 // Check to see if we're running on a PowerPC
223 err = Gestalt(gestaltSysArchitecture, &resp);
224 if (!err && (resp & (1 << gestaltPowerPC)))
225 gIsPowerPC = true;*/
226 }
227
228 //------------------------------------------------------------------------------------
229 // Make a color window the size of the main screen, and black it out.
230 //------------------------------------------------------------------------------------
SetupWindows(WindowPtr * mainWind)231 void SetupWindows(WindowPtr *mainWind)
232 {
233 /*FailNIL(*mainWind = GetNewCWindow(1000, 0L, (WindowPtr)-1L));
234
235 SizeWindow(*mainWind, gScreenWide, gScreenHigh, false);
236 MoveWindow(*mainWind, 0, 0, true);
237
238 SetPort(*mainWind);
239 SetOrigin(-gActiveLeft, -gActiveTop); // Set the main window's origin
240 OffsetRect(&gActiveArea, -gActiveLeft, -gActiveTop);
241
242 ShowWindow(*mainWind);*/
243 //PaintRect(&(*mainWind)->portRect); // black it out
244 }
245
246 //------------------------------------------------------------------------------------
247 // Load and install the standard menus.
248 //------------------------------------------------------------------------------------
249 /*void SetUpMenus(MenuHandle *theMenus, short numMenus)
250 {
251 short i;
252
253 for (i=0; i<numMenus; i++)
254 FailNIL(theMenus[i] = GetMenu(128+i)); // get menu resources
255
256 AddResMenu(theMenus[0],'DRVR'); // add the apple menu items
257
258 for (i=0; i<numMenus; i++)
259 InsertMenu(theMenus[i], 0); // Insert apple, file, edit, etc.
260
261 DrawMenuBar();
262 }*/
263
264 //------------------------------------------------------------------------------------
265 // Get the dirID and Vref for any folders Shock uses.
266 //------------------------------------------------------------------------------------
GetFolders(void)267 void GetFolders(void)
268 {
269 /*long temp;
270 HParamBlockRec hpb;
271 OSErr err;
272
273 // Get the location of our current working directory.
274
275 hpb.ioParam.ioCompletion = 0L;
276 hpb.fileParam.ioFDirIndex = 0;
277 GetWDInfo(gMainVRef, &hpb.fileParam.ioVRefNum, &hpb.fileParam.ioDirID, &temp);
278
279 // Now get info on the "Data" directory.
280
281 hpb.fileParam.ioNamePtr = "Data";
282 err = PBGetCatInfo((CInfoPBPtr)&hpb, false);
283
284 // If we found it, then set our globals, otherwise die.
285
286 if (err == noErr)
287 {
288 gDataVref = hpb.fileParam.ioVRefNum;
289 gDataDirID = hpb.fileParam.ioDirID;
290 }
291 else
292 ErrorDie(12); // No "Data" folder.
293
294 // Now go into the data folder and get the "Alogs" and "Barks" folders.
295
296 hpb.fileParam.ioNamePtr = "Alogs";
297 err = PBGetCatInfo((CInfoPBPtr)&hpb, false);
298 if (err == noErr)
299 {
300 gAlogVref = hpb.fileParam.ioVRefNum;
301 gAlogDirID = hpb.fileParam.ioDirID;
302 }
303 else
304 ErrorDie(13); // No "Alogs" folder.
305
306 hpb.fileParam.ioVRefNum = gDataVref;
307 hpb.fileParam.ioDirID = gDataDirID;
308 hpb.fileParam.ioNamePtr = "Barks";
309 err = PBGetCatInfo((CInfoPBPtr)&hpb, false);
310 if (err == noErr)
311 {
312 gBarkVref = hpb.fileParam.ioVRefNum;
313 gBarkDirID = hpb.fileParam.ioDirID;
314 }
315 else
316 ErrorDie(14); // No "Barks" folder.
317
318 */
319 }
320
321 //------------------------------------------------------------------------------------
322 // Check a memory address (handle or pointer) to see if its NIL, and wasn't allocated.
323 // If it was, we have to fail out of the program.
324 //------------------------------------------------------------------------------------
FailNIL(void * memory)325 void FailNIL(void *memory)
326 {
327 /*if (!memory)
328 {
329 if (gExtraMemory)
330 DisposHandle(gExtraMemory);
331
332 ErrorDie(1);
333 }*/
334 }
335
336 //------------------------------------------------------------------------------------
337 // Get a resource and fail correctly if it can't be loaded.
338 //------------------------------------------------------------------------------------
GetResourceFail(long id,short num)339 Handle GetResourceFail(long id, short num)
340 {
341 /*Handle h;
342
343 h = GetResource(id, num);
344 if (h) return(h);
345
346 // At this point GetResource failed, figure out why.
347 SetResLoad(false);
348 h = GetResource(id, num);
349 SetResLoad(true);
350
351 if (gExtraMemory)
352 DisposHandle(gExtraMemory);
353
354 if (h)
355 ErrorDie(1); // resource is there, must be a memory problem
356 else
357 ErrorDie(3); // resource not there, somethings bad
358
359 return (nil);*/
360 }
361
362
363 //------------------------------------------------------------------------------------
364 // Startup the SystemShock timer.
365 //------------------------------------------------------------------------------------
InstallShockTimers(void)366 void InstallShockTimers(void)
367 {
368 /*gShockTicks = 0;
369 tmd_ticks = &gShockTicks;
370
371 //pShockTicksPtr = NewTimerProc(ShockTicksProc); // Make a UPP for the TM task
372 pShockTicksTask.task.tmAddr = pShockTicksPtr; // Insert the Shock ticks TM task
373 pShockTicksTask.task.tmWakeUp = 0;
374 pShockTicksTask.task.tmReserved = 0;
375 #ifndef __powerc
376 //pShockTicksTask.appA5 = SetCurrentA5();
377 #endif
378 InsTime((QElemPtr)&pShockTicksTask);
379 PrimeTime((QElemPtr)&pShockTicksTask, kShockTicksFreq); // Increment 280 times a second*/
380 }
381
382
383 //------------------------------------------------------------------------------------
384 // Remove the SystemShock timer.
385 //------------------------------------------------------------------------------------
RemoveShockTimers(void)386 void RemoveShockTimers(void)
387 {
388 /*RmvTime((QElemPtr)&pShockTicksTask); // Stop the Shock ticks task
389 DisposeRoutineDescriptor(pShockTicksPtr); // Dispose its UPP*/;
390 }
391
392
393 //------------------------------------------------------------------------------------
394 // Display an alert using the str# resource with index strignum, then die.
395 //------------------------------------------------------------------------------------
ErrorDie(short stringnum)396 void ErrorDie(short stringnum)
397 {
398 /*if (gExtraMemory)
399 DisposHandle(gExtraMemory); // free our extra space
400
401 StringAlert(stringnum);
402 CleanupAndExit();*/
403 }
404
405 //------------------------------------------------------------------------------------
406 // Display an alert using the str# resource with index strignum
407 //------------------------------------------------------------------------------------
StringAlert(short stringnum)408 void StringAlert(short stringnum)
409 {
410 /*Str255 message, explain;
411
412 InitCursor();
413 GetIndString(message, 1000, stringnum);
414 GetIndString(explain, 1001, stringnum);
415 ParamText(message, explain, "", "");
416
417 if (*explain)
418 StopAlert(1001, nil);
419 else
420 StopAlert(1000, nil);*/
421 }
422
423 //------------------------------------------------------------------------------------
424 // Close all our resources, then quit.
425 //------------------------------------------------------------------------------------
CleanupAndExit(void)426 void CleanupAndExit(void)
427 {
428 /*GDHandle devhandle;
429
430
431 if (gOriginalDepth != -1) // If color depth was changed at beginning of app,
432 { // then switch it back to the original.
433 devhandle = GetMainDevice();
434 if (devhandle)
435 if (HasDepth(devhandle, gOriginalDepth, 0, 0))
436 SetDepth(devhandle, gOriginalDepth, 0, 0);
437 }
438 else
439 CleanupPalette(); // Else switch back to original 8-bit palette.
440
441 // ExitMovies();
442
443 ExitToShell();*/
444 }
445