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