rnd-20100315-2-src
[rocksndiamonds.git] / src / game_sp / Globals.c
1 // ----------------------------------------------------------------------------
2 // Globals.c
3 // ----------------------------------------------------------------------------
4
5 #include "Globals.h"
6
7 static void ReadDemo();
8 void ReadLevel();
9
10 // static char *VB_Name = "modGlobals";
11
12 // --- Option Explicit
13 // --- Option Compare Text
14 // --- Option Base 0
15
16 // --- const long StretchWidth = 16;
17 // --- const long StretchWidth2 = StretchWidth / 2;
18 // --- const long BaseWidth = 16;
19 // --- const int TwoPixels = 2;
20
21 boolean Original;
22 boolean Cracked;
23 boolean Level_Arg;
24 boolean EGA_Arg;
25 boolean Record_Fix;
26 boolean SpeedKeys;
27 boolean Level_Fix;
28 boolean Dead_Code;
29 boolean Redundant;
30 boolean Alignments;
31 boolean Ctrl_Alt_Fix;
32 boolean Protection;
33 boolean EP_ENHANCE;
34 boolean EP_DEMO;
35 boolean EP_DEBUG;
36 boolean EXTRASPEED;
37 boolean TIMINGFIX;
38 boolean SafeRecord;
39 boolean Norm_Time;
40 boolean EP_OLD8;
41 boolean SAVEGAME;
42 boolean HP_DEMO;
43 boolean ScreenFix;
44 boolean DemoRecordFix;
45 boolean DebugSwitch;
46 boolean Ver62;
47 boolean Ver62test;
48 boolean Ver63;
49 boolean Ver64;
50
51 int LevelNumber;
52 char *CurPath, *OrigPath, *TmpPath;
53 boolean LevelLoaded;
54 long SignatureDelay;
55 boolean bSignatureAvailable;
56
57 boolean bCapturePane;
58
59 int FieldWidth; // = 60
60 int FieldHeight; // = 24
61 int HeaderSize; // = 96
62 int FieldMax, LevelMax;
63 long FileMax;
64 int *PlayField16;
65 byte *PlayField8;
66 byte *DisPlayField;
67
68 // Public DisplayMin%, DisplayMax%, DisplayWidth%, DisplayHeight%
69
70 int TimerVar;
71 #if 1
72 short RandomSeed;
73 #else
74 int RandomSeed;
75 #endif
76 currency DeltaT; // Interval between two frames (in ms)
77 long DeltaTPlay, DeltaTDemo;
78 boolean BlockingSpeed;
79
80 // --- const int posFrameCorner = 55;
81 // --- const int posFrameVertical = 110;
82 // --- const int posFrameHorizontal = 111;
83
84 int FreezeZonks;
85
86 // constants for  Fixed Fields:
87 // --- const int fiSpace = 0; // &H00  space(28 = wall space ...)
88 // --- const int fiZonk = 1; // &H01  zonk
89 // --- const int fiBase = 2; // &H02  base
90 // --- const int fiMurphy = 3; // &H03  Murphy
91 // --- const int fiInfotron = 4; // &H04  infotron
92 // --- const int fiRAM = 5; // &H05  small RAM chip
93 // --- const int fiHardWare = 6; // &H06  hardware (square, standard pyramid shape)
94 // --- const int fiExit = 7; // &H07  exit
95 // --- const int fiOrangeDisk = 8; // &H08  brown/orange utility disk
96 // --- const int fiPortRight = 9; // &H09  port 1 left to right
97 // --- const int fiPortDown = 10; // &H0A  port 1 up to down
98 // --- const int fiPortLeft = 11; // &H0B  port 1 right to left
99 // --- const int fiPortUp = 12; // &H0C  port 1 down to up
100 // --- const int fiSpPortRight = 13; // &H0D  port 2 left to right (gravity change)
101 // --- const int fiSpPortDown = 14; // &H0E  port 2 up to down     (gravity change)
102 // --- const int fiSpPortLeft = 15; // &H0F  port 2 right to left (gravity change)
103 // --- const int fiSpPortUp = 16; // &H10  port 2 down to up     (gravity change)
104 // --- const int fiSnikSnak = 17; // &H11  snik snak
105 // --- const int fiYellowDisk = 18; // &H12  yellow utility disk
106 // --- const int fiTerminal = 19; // &H13  terminal
107 // --- const int fiRedDisk = 20; // &H14  red utility disk
108 // --- const int fiPortUpAndDown = 21; // &H15  vertical port
109 // --- const int fiPortLeftAndRight = 22; // &H16  horizontal port
110 // --- const int fiPortAllDirections = 23; // &H17  horizontal + vertical port
111 // --- const int fiElectron = 24; // &H18  electron
112 // --- const int fiBug = 25; // &H19  bug
113 // --- const int fiRAMLeft = 26; // &H1A  horizontal RAM chip, left (pin 1)
114 // --- const int fiRAMRight = 27; // &H1B  horizontal RAM chip, right
115 // --- const int fiHWFirst = 28; // &H1C  hardware (radial blue circular cap + coloured shapes)
116
117 // Public Const fiHW1% = 29               '  29 = 1D  hardware (green signal lamp)
118 // Public Const fiHW2% = 30               '  30 = 1E  hardware (blue signal lamp)
119 // Public Const fiHW3% = 31               '  31 = 1F  hardware (red signal lamp)
120 // Public Const fiHW4% = 32               '  32 = 20  hardware (yellow/black diagonal stripes)
121 // Public Const fiHW5% = 33               '  33 = 21  hardware (yellow resistor + blue + red shapes)
122 // Public Const fiHW6% = 34               '  34 = 22  hardware (horizontal red capacitor + smd shape)
123 // Public Const fiHW7% = 35               '  35 = 23  hardware (red + yellow + blue horizontal resistors)
124 // Public Const fiHW8% = 36               '  36 = 24  hardware (3 red vertical resistors)
125 // --- const int fiHWLast = 37;             //  37 = 25  hardware (3 yellow horizontal resistors)
126 // --- const int fiRAMTop = 38;             //  38 = 26  vertical RAM chip, top (pin 1)
127 // --- const int fiRAMBottom = 39;          //  39 = 27  vertical RAM chip, bottom
128
129 // Specials to experiment with ...
130 // --- const int fiWallSpace = 40;          //  40 = 28  invisible wall (can explode, zonks don't roll off)
131 // --- const int fiHWTrash1 = 41;           //  41 = 29  hardware trash
132 // --- const int fiHWTrash2 = 42;           //  42 = 2A  hardware trash
133 // --- const int fiHWMurphy = 43;           //  43 = 2B  hardware inverted Murphy ... (maybe nice for use?)
134
135 // --- const int fiExplosion = 0x1F;
136
137 // --- const int keyNone = 0;
138 // --- const int keyUp = 1;
139 // --- const int keyLeft = 2;
140 // --- const int keyDown = 3;
141 // --- const int keyRight = 4;
142 // --- const int keySpaceUp = 5;
143 // --- const int keySpaceLeft = 6;
144 // --- const int keySpaceDown = 7;
145 // --- const int keySpaceRight = 8;
146 // --- const int keySpace = 9;
147
148 #if 0
149 int *aniBug, *aniZonkRollRight, *aniZonkRollLeft;
150 int *aniInfotronRollRight, *aniInfotronRollLeft;
151 int *aniSnikSnak, *aniElectron, *aniExplosion;
152 int *aniTouchBase, *aniTouchInfotron, *aniTouchRedDisk;
153 // --- const int aniExplosionInfo = 111;
154 // --- const int aniSnikSnakUp = 159;
155 // --- const int aniSnikSnakDown = 167;
156 // --- const int aniSnikSnakLeft = 239;
157 // --- const int aniSnikSnakRight = 247;
158 // --- const int aniMurphyYawn = 56;
159 // --- const int aniMurphySleepLeft = 71;
160 // --- const int aniMurphySleepRight = 68;
161 int *aniMurphyExit; // , aniMurphyFaceLeft%, aniMurphyFaceRight%
162 int *aniMurphyEatLeft, *aniMurphyEatRight; // , aniMurphyEatRightRedDisk
163 int *aniMurphyEatUpLeft, *aniMurphyEatUpRight, *aniSplitUpDown;
164 int *aniYellowDisk, *aniOrangeDisk, *aniRedDisk;
165 // --- const int aniMurphyTouchUp = 46;
166 // --- const int aniMurphyTouchLeft = 95;
167 // --- const int aniMurphyTouchDown = 47;
168 // --- const int aniMurphyTouchRight = 94;
169 int *aniEatInfotronLeft, *aniEatInfotronRight;
170 // --- const int aniPushLeft = 45;
171 // --- const int aniPushRight = 44;
172 // --- const int aniPushUpDown = 79;
173 #endif
174
175 #if 1
176 int aniFramesBug[] = { 74, 75, 76, 77, 78, 77, 76, 77, 78, 77, 76, 75, 74, 25 };
177 int aniFramesZonkRollRight[] = { 198, 197, 196, 195, 194, 193, 192, 1, -1 };
178 int aniFramesZonkRollLeft[] = { 192, 193, 194, 195, 196, 197, 198, 1, -1 };
179 int aniFramesInfotronRollRight[] = { 206, 205, 204, 203, 202, 201, 200, 4 };
180 int aniFramesInfotronRollLeft[] = { 200, 201, 202, 203, 204, 205, 206, 4 };
181 int aniFramesSnikSnak[] = { 121, 122, 123, 124, 125, 126, 127, 120, 121 };
182 int aniFramesElectron[] = { 144, 145, 146, 147, 148, 149, 150, 151, 144 };
183 int aniFramesExplosion[] = { 3, 103, 104, 105, 106, 107, 108, 109, 0 };
184 int aniFramesTouchBase[] = { 80, 81, 82, 83, 84, 85, 86, 0, -1 };
185 int aniFramesTouchInfotron[] = { 87, 88, 89, 91, 92, 93, 0, -1 }; // Only seven frames!!!!
186 int aniFramesTouchRedDisk[] = { 96, 97, 98, 99, 100, 101, 102, 0, -1 };
187 int aniFramesMurphyExit[] = { 46, 46, 46, 46, 47, 47, 47, 47, 48, 48, 48, 48, 49, 49, 49, 49, 50, 50, 50, 50, 51, 51, 51, 51, 52, 52, 52, 52, 53, 53, 53, 53, 54, 54, 54, 54, 0, 0, 0, 0, -1 };
188 int aniFramesMurphyEatLeft[] = { 176, 177, 178, 179, 180, 181, 182, 183, -1 };
189 int aniFramesMurphyEatRight[] = { 184, 185, 186, 187, 188, 189, 190, 191, -1 };
190 int aniFramesMurphyEatUpLeft[] = { 183, 182, 181, 180, 179, 178, 177, 176, -1 };
191 int aniFramesMurphyEatUpRight[] = { 191, 190, 189, 188, 187, 186, 185, 184, -1 };
192   // aniFramesMurphyEatRightRedDisk = { 184, 184, 185, 186, 187, 188, 189, 190, 191, -1) '9 frames!
193 int aniFramesEatInfotronLeft[] = { 209, 211, 213, 215, 217, 219, 221, 223, -1 };
194 int aniFramesEatInfotronRight[] = { 224, 226, 228, 230, 232, 234, 236, 238, -1 };
195 int aniFramesSplitUpDown[] = { 3, 3, 3, 3, 3, 3, 3, 3, -1 };
196 int aniFramesYellowDisk[] = { 18, 18, 18, 18, 18, 18, 18, 18, -1 };
197 int aniFramesOrangeDisk[] = { 8, 8, 8, 8, 8, 8, 8, 8, -1 };
198 int aniFramesRedDisk[] = { 20, -1 };
199 #endif
200
201 #if 1
202
203 int fiGraphic[] =
204 {
205   aniSpace,
206   aniZonk,
207   aniBase,
208   aniMurphy,
209   aniInfotron,
210   aniRAM,
211   aniHardWare,
212   aniExit,
213   aniOrangeDisk,
214   aniPortRight,
215   aniPortDown,
216   aniPortLeft,
217   aniPortUp,
218   aniSpPortRight,
219   aniSpPortDown,
220   aniSpPortLeft,
221   aniSpPortUp,
222   aniSnikSnak,
223   aniYellowDisk,
224   aniTerminal,
225   aniRedDisk,
226   aniPortUpAndDown,
227   aniPortLeftAndRight,
228   aniPortAllDirections,
229   aniElectron,
230   aniBug,
231   aniRAMLeft,
232   aniRAMRight,
233   aniHW0,
234   aniHW1,
235   aniHW2,
236   aniHW3,
237   aniHW4,
238   aniHW5,
239   aniHW6,
240   aniHW7,
241   aniHW8,
242   aniHW9,
243   aniRAMTop,
244   aniRAMBottom,
245   aniWallSpace
246 };
247
248 int aniSnikSnakTurningLeft[] =
249 {
250   aniSnikSnakTurnUpToLeft,
251   aniSnikSnakTurnLeftToDown,
252   aniSnikSnakTurnDownToRight,
253   aniSnikSnakTurnRightToUp
254 };
255
256 int aniSnikSnakTurningRight[] =
257 {
258   aniSnikSnakTurnUpToRight,
259   aniSnikSnakTurnRightToDown,
260   aniSnikSnakTurnDownToLeft,
261   aniSnikSnakTurnLeftToUp
262 };
263
264
265 int getSequenceLength(int sequence)
266 {
267   switch (sequence)
268   {
269     case aniBug:
270       return 14;
271
272     case aniElectron:
273     case aniExplosion:
274       return 9;
275
276     case aniTouchInfotron:
277       return 7;
278
279     case aniMurphyExit:
280       return 40;
281
282     case aniRedDisk:
283       return 1;
284
285     default:
286       return 8;
287   }
288 }
289
290 boolean isSnappingSequence(int sequence)
291 {
292   switch (sequence)
293   {
294     case aniTouchBase:
295     case aniTouchInfotron:
296     case aniTouchRedDisk:
297       return TRUE;
298
299     default:
300       return FALSE;
301   }
302 }
303
304 #endif
305
306 void InitGlobals()
307 {
308 #if 0
309   aniBug = Array(74, 75, 76, 77, 78, 77, 76, 77, 78, 77, 76, 75, 74, 25);
310   aniZonkRollRight = Array(198, 197, 196, 195, 194, 193, 192, 1, -1);
311   aniZonkRollLeft = Array(192, 193, 194, 195, 196, 197, 198, 1, -1);
312   aniInfotronRollRight = Array(206, 205, 204, 203, 202, 201, 200, 4);
313   aniInfotronRollLeft = Array(200, 201, 202, 203, 204, 205, 206, 4);
314   aniSnikSnak = Array(121, 122, 123, 124, 125, 126, 127, 120, 121);
315   aniElectron = Array(144, 145, 146, 147, 148, 149, 150, 151, 144);
316   aniExplosion = Array(3, 103, 104, 105, 106, 107, 108, 109, 0);
317   aniTouchBase = Array(80, 81, 82, 83, 84, 85, 86, 0, -1);
318   aniTouchInfotron = Array(87, 88, 89, 91, 92, 93, 0, -1); // Only seven frames!!!!
319   aniTouchRedDisk = Array(96, 97, 98, 99, 100, 101, 102, 0, -1);
320   aniMurphyExit = Array(46, 46, 46, 46, 47, 47, 47, 47, 48, 48, 48, 48, 49, 49, 49, 49, 50, 50, 50, 50, 51, 51, 51, 51, 52, 52, 52, 52, 53, 53, 53, 53, 54, 54, 54, 54, 0, 0, 0, 0, -1);
321   aniMurphyEatLeft = Array(176, 177, 178, 179, 180, 181, 182, 183, -1);
322   aniMurphyEatRight = Array(184, 185, 186, 187, 188, 189, 190, 191, -1);
323   aniMurphyEatUpLeft = Array(183, 182, 181, 180, 179, 178, 177, 176, -1);
324   aniMurphyEatUpRight = Array(191, 190, 189, 188, 187, 186, 185, 184, -1);
325   // aniMurphyEatRightRedDisk = Array(184, 184, 185, 186, 187, 188, 189, 190, 191, -1) '9 frames!
326   aniEatInfotronLeft = Array(209, 211, 213, 215, 217, 219, 221, 223, -1);
327   aniEatInfotronRight = Array(224, 226, 228, 230, 232, 234, 236, 238, -1);
328   aniSplitUpDown = Array(3, 3, 3, 3, 3, 3, 3, 3, -1);
329   aniYellowDisk = Array(18, 18, 18, 18, 18, 18, 18, 18, -1);
330   aniOrangeDisk = Array(8, 8, 8, 8, 8, 8, 8, 8, -1);
331   aniRedDisk = Array(20, -1);
332 #endif
333
334   InitPseudoCompileFlags();
335   UserDragFlag = False;
336   AutoScrollFlag = True;
337   FreezeZonks = 0;
338   BlockingSpeed = False;
339   LevelLoaded = False;
340   FieldWidth = 60;
341   FieldHeight = 24;
342   HeaderSize = 96;
343   FieldMax = (FieldWidth * FieldHeight) + HeaderSize - 1;
344   LevelMax = (FieldWidth * FieldHeight) - 1;
345   Let_ModifiedFlag(False);
346   bPlaying = False;
347   gSignature = "";
348   bSignatureAvailable = False;
349   FirstDemoByte = 0x81;
350   MySignature = "";
351 }
352
353 void InitPseudoCompileFlags()
354 {
355   Cracked = 1;       // If protection Then crack it
356   Level_Arg = 1;     // :number is cmd line option
357   // Level_Arg  = 0     ' Remove Level cmd line option
358   EGA_Arg = 1;       // EGA is command line option
359   Record_Fix = 1;      // Assemble with fixed Demo rec
360   SpeedKeys = 0;     // Remove Speed Keys fix
361   Level_Fix = 1;     // Assemble with Level Fix
362   Dead_Code = 0;     // Remove dead code
363   Redundant = 0;     // Remove redundant code
364   Alignments = 1;      // Assemble with alignments
365   Ctrl_Alt_Fix = 1;      // Assemble with Ctrl/Alt fix
366   Protection = 0;      // Remove protection code,do HP
367   // EP added by EP for version 5.
368   EP_ENHANCE = 1;      // Some more nice things (EP)
369   EP_DEMO = 1;       // Use .SP files for demos (EP)
370   // Including record demo!
371   EP_DEBUG = 0;      // little cmdline debugging
372   EXTRASPEED = 1;      // '@' option, superfast!
373   TIMINGFIX = 1;     // "Fixed" the timing problem..
374   // Inactive If DemoRecordFix Then1
375   SafeRecord = 1;      // skip debug keys in recording
376   Norm_Time = 1;     // force automatic speed test,
377   // save result and then do as
378   // requested from cmd line.
379   EP_OLD8 = 1;       // call old int8 from current.
380   SAVEGAME = 1;      // Allow saving to SUPAPLEX.SAV
381   HP_DEMO = 1;       // Use fixed demo routines 5.5
382   ScreenFix = 1;     // No menu-write to gamy field
383   DemoRecordFix = 1;     // Demo record timing fix on
384   DebugSwitch = 1;     // Allow Ctrl/Alt-ScrollLock
385   Ver62 = 1;       // Version 6.2 stuff
386   Ver62test = 0;     // Version 6.2 test stuff
387   Ver63 = 1;       // Version 6.3 stuff
388   Ver64 = 1;       // Version 6.4 stuff
389
390 }
391
392 int GetSI(int X, int Y)
393 {
394   int GetSI;
395
396   GetSI = Y * FieldWidth + X;
397
398   return GetSI;
399 }
400
401 int GetX(int si)
402 {
403   int GetX;
404
405   GetX = si % FieldWidth;
406
407   return GetX;
408 }
409
410 int GetY(int si)
411 {
412   int GetY;
413
414   GetY = si / FieldWidth;
415
416   return GetY;
417 }
418
419 int GetStretchX(int si)
420 {
421   int GetStretchX;
422
423   GetStretchX = StretchWidth * (si % FieldWidth);
424
425   return GetStretchX;
426 }
427
428 int GetStretchY(int si)
429 {
430   int GetStretchY;
431
432   GetStretchY = StretchWidth * (si / FieldWidth);
433
434   return GetStretchY;
435 }
436
437 void OLD_ReadLevel()
438 {
439 #if 1
440   static char CurPathTEST[1024];
441 #endif
442
443   // int FNum;
444   FILE *FNum;
445   long i;
446   // byte T;
447
448 #if 1
449   // CurPath = "/home/aeglos/projects/rocksndiamonds/levels/TEST_supaplex/supaplex/levels.dat";
450
451 #if 0
452   CurPath = "/home/aeglos/projects/rocksndiamonds/supaplex_demo_JENS0001.sp";
453   LevelNumber = 1;
454 #else
455
456 #if 0
457   // sprintf(CurPathTEST, "/home/aeglos/projects/rocksndiamonds/levels/TEST_supaplex/test_solutions/%03d.sp", level_nr);
458
459   sprintf(CurPathTEST, "/home/aeglos/projects/Level_Stuff/SUPAPLEX/SUPAPLEX_LEVELS/Set77/77S%03d.SP", level_nr);
460 #else
461   sprintf(CurPathTEST, "/home/aeglos/projects/Level_Stuff/SUPAPLEX/SUPAPLEX_LEVELS/solve00/JENS%04d.SP", level_nr);
462 #endif
463
464   CurPath = CurPathTEST;
465   LevelNumber = level_nr;
466 #endif
467
468 #endif
469
470   DemoAvailable = False;
471
472   if (STRING_IS_LIKE(CurPath, "*.mpx") ||
473       STRING_IS_LIKE(CurPath, "*.MPX"))
474   {
475     printf("::: reading MPX file ...\n");
476
477     ReadMPX();
478     return;
479   }
480
481   if (STRING_IS_LIKE(CurPath, "*.sp") ||
482       STRING_IS_LIKE(CurPath, "*.SP"))
483   {
484     printf("::: reading SP file ...\n");
485
486     ReadDemo();
487     return;
488   }
489
490   if (DemoFlag != 0)
491   {
492     printf("::: reading demo file ...\n");
493
494     ReadDemo();
495     return;
496   }
497
498   printf("::: reading level file ...\n");
499
500   FileMax = 0;
501   FieldWidth = 60;
502   FieldHeight = 24;
503   HeaderSize = 96;
504
505   FieldMax = (FieldWidth * FieldHeight) + HeaderSize - 1;
506   LevelMax = (FieldWidth * FieldHeight) - 1;
507
508   PlayField8 = REDIM_1D(sizeof(byte), 0, FieldMax + 1 - 1);
509   DisPlayField = REDIM_1D(sizeof(byte), 0, FieldMax + 1 - 1);
510
511   // FNum = FreeFile();
512
513   // --- On Error GoTo ReadLevelEH
514
515   printf("::: '%s', %d\n", CurPath, LevelNumber);
516
517   FNum = fopen(CurPath, "rb");
518
519   i = (LevelNumber - 1) * ((long)(FieldMax) + 1) + 1;
520 #if 1
521   FILE_GET(FNum, i, PlayField8, FieldMax + 1);
522 #else
523   FILE_GET(FNum, i, &PlayField8, sizeof(PlayField8));
524 #endif
525
526   i = (LevelNumber) * ((long)(FieldMax) + 1) + 1 - HeaderSize;
527   FILE_GET(FNum, i, &LInfo, sizeof(LInfo)); // store level info in an extra structure
528
529   fclose(FNum);
530
531   // --- On Error GoTo 0
532
533   if (FieldMax < FileMax)
534     DemoAvailable = True;
535
536   ReadSignature();
537
538   PlayField16 = REDIM_1D(sizeof(int), -FieldWidth, FieldMax);
539
540   for (i = 0; i <= FieldMax; i++)
541   {
542     PlayField16[i]  = PlayField8[i];
543     DisPlayField[i] = PlayField8[i];
544     PlayField8[i] = 0;
545   }
546
547 #if 0
548  {
549    int x, y;
550
551    for (x = 0; x < 60; x++)
552      printf("%02d.", x);
553    printf("\n");
554
555    for (x = 0; x < 60; x++)
556      printf("...");
557    printf("\n");
558
559    for (y = 0; y < 24; y++)
560    {
561      for (x = 0; x < 60; x++)
562      {
563        printf("%02d.", PlayField16[y * 60 + x]);
564      }
565
566      printf("\n");
567    }
568  }
569 #endif
570
571   AnimationPosTable = REDIM_1D(sizeof(int), 0, LevelMax - 2 * FieldWidth);
572   AnimationSubTable = REDIM_1D(sizeof(byte), 0, LevelMax - 2 * FieldWidth);
573   TerminalState = REDIM_1D(sizeof(byte), FieldWidth, LevelMax - FieldWidth);
574
575   GravityFlag = LInfo.InitialGravity;
576   FreezeZonks = LInfo.InitialFreezeZonks;
577
578   subRandomize();
579
580   LevelLoaded = True;
581
582   return;
583
584 #if 0
585 ReadLevelEH:
586   Close();
587 #endif
588 }
589
590 static void ReadDemo()
591 {
592   // int FNum, i;
593   FILE *FNum;
594   int i;
595   // byte T;
596
597   int RecordNumber = LevelNumber;
598
599 #if 1
600   RecordNumber = 1;     // always "1" for "*.sp" style one level/demo files
601 #endif
602
603   FieldWidth = 60;
604   FieldHeight = 24;
605   HeaderSize = 96;
606
607   FieldMax = (FieldWidth * FieldHeight) + HeaderSize - 1;
608   LevelMax = (FieldWidth * FieldHeight) - 1;
609
610   // --- On Error GoTo ReadDemoEH
611
612   FileMax = FileLen(CurPath) - 1;
613
614   PlayField8 = REDIM_1D(sizeof(byte), 0, FileMax + 1 - 1);
615   DisPlayField = REDIM_1D(sizeof(byte), 0, FieldMax + 1 - 1);
616
617   // FNum = FreeFile();
618
619   FNum = fopen(CurPath, "rb");
620
621   i = (RecordNumber - 1) * ((long)(FieldMax) + 1) + 1;
622 #if 1
623   FILE_GET(FNum, i, PlayField8, FileMax + 1);
624 #else
625   FILE_GET(FNum, i, &PlayField8, sizeof(PlayField8));
626 #endif
627
628   i = (RecordNumber) * ((long)(FieldMax) + 1) + 1 - HeaderSize;
629   FILE_GET(FNum, i, &LInfo, sizeof(LInfo)); // store level info in an extra structure
630
631   fclose(FNum);
632
633   // --- On Error GoTo 0
634
635   if (FieldMax < FileMax)
636     DemoAvailable = True;
637
638   ReadSignature();
639
640   PlayField16 = REDIM_1D(sizeof(int), -FieldWidth, FieldMax);
641
642   for (i = 0; i <= FieldMax; i++)
643   {
644     PlayField16[i] = PlayField8[i];
645     DisPlayField[i] = PlayField8[i];
646     PlayField8[i] = 0;
647   }
648
649   AnimationPosTable = REDIM_1D(sizeof(int), 0, LevelMax - 2 * FieldWidth);
650   AnimationSubTable = REDIM_1D(sizeof(byte), 0, LevelMax - 2 * FieldWidth);
651   TerminalState = REDIM_1D(sizeof(byte), 0, FieldMax + 1 - 1);
652
653   DemoPointer = FieldMax + 1;
654   DemoOffset = DemoPointer;
655   DemoKeyRepeatCounter = 0;
656
657   // DemoFlag = 1
658   // DemoAvailable = True
659
660   GravityFlag = LInfo.InitialGravity;
661   FreezeZonks = LInfo.InitialFreezeZonks;
662
663 #if 0
664   printf("::: Globals.c: ReadDemo(): %d / %d\n", GravityFlag, FreezeZonks);
665 #endif
666
667
668
669 #if 0
670   /* !!! TESTING BIG / LITTLE ENDIAN STUFF !!! */
671   LInfo.DemoRandomSeed =
672     LowByte(LInfo.DemoRandomSeed) << 8 |
673     HighByte(LInfo.DemoRandomSeed);
674   for (i = 0; i < 10; i++)
675     LInfo.SpecialPort[i].PortLocation =
676       LowByte(LInfo.SpecialPort[i].PortLocation) << 8 |
677       HighByte(LInfo.SpecialPort[i].PortLocation);
678
679   printf("::: swapping file bytes for DemoRandomSeed etc.\n");
680 #else
681   printf("::: keeping file bytes in (maybe wrong) 'native' order.\n");
682 #endif
683
684 #if 1
685   printf("::: LInfo.DemoRandomSeed == %d\n", LInfo.DemoRandomSeed);
686 #endif
687
688 #if 0
689   printf("::: LInfo.SpecialPortCount == %d\n", LInfo.SpecialPortCount);
690   for (i = 0; i < LInfo.SpecialPortCount; i++)
691   {
692     int port_x = (LInfo.SpecialPort[i].PortLocation / 2) % FieldWidth;
693     int port_y = (LInfo.SpecialPort[i].PortLocation / 2) / FieldWidth;
694
695     printf("::: %d: port_location == %d => (%d, %d)\n",
696            i, LInfo.SpecialPort[i].PortLocation, port_x, port_y);
697   }
698 #endif
699
700   RandomSeed = LInfo.DemoRandomSeed;
701
702 #if 0
703   printf("::: SpeedByte == %d\n", LInfo.SpeedByte);
704   printf("::: CheckSumByte == %d\n", LInfo.CheckSumByte);
705   printf("::: RandomSeed == %d\n", RandomSeed);
706
707 #if 0
708   {
709     int i;
710
711     for (i = 0; i < 10; i++)
712       printf("::: TEST random number: %d\n", subGetRandomNumber());
713   }
714 #endif
715
716 #endif
717
718   LevelLoaded = True;
719
720   return;
721
722 #if 0
723 ReadDemoEH:
724   Close();
725 #endif
726 }
727
728 void ReadLevel()
729 {
730 #if 0
731   OLD_ReadLevel();
732
733   // return;
734 #endif
735
736   copyInternalEngineVars_SP();
737
738 #if 1
739   SetDisplayRegion();
740   SetScrollEdges();
741 #endif
742
743   LevelNumber = level_nr;
744
745 #if 0
746   if (!DemoFlag || !DemoAvailable)
747     subRandomize();
748 #endif
749
750   LevelLoaded = True;
751 }
752
753 void Trace(char *Source, char *Message)
754 {
755   printf("::: Trace: Source == '%s', Message == '%s'\n", Source, Message);
756 }
757
758 void ReportError(char *Source, char *Message)
759 {
760   printf("::: ReportError: Source == '%s', Message == '%s'\n", Source, Message);
761 }
762
763 int Min(int A, int B)
764 {
765   int Min;
766
767   if (A < B)
768     Min = A;
769   else
770     Min = B;
771
772   return Min;
773 }
774
775 int Max(int A, int B)
776 {
777   int Max;
778
779   if (A < B)
780     Max = B;
781   else
782     Max = A;
783
784   return Max;
785 }