rnd-20100216-1-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
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 fiGraphic[] =
203 {
204   aniSpace,
205   aniZonk,
206   aniBase,
207   aniMurphy,
208   aniInfotron,
209   aniRAM,
210   aniHardWare,
211   aniExit,
212   aniOrangeDisk,
213   aniPortRight,
214   aniPortDown,
215   aniPortLeft,
216   aniPortUp,
217   aniSpPortRight,
218   aniSpPortDown,
219   aniSpPortLeft,
220   aniSpPortUp,
221   aniSnikSnak,
222   aniYellowDisk,
223   aniTerminal,
224   aniRedDisk,
225   aniPortUpAndDown,
226   aniPortLeftAndRight,
227   aniPortAllDirections,
228   aniElectron,
229   aniBug,
230   aniRAMLeft,
231   aniRAMRight,
232   aniHW0,
233   aniHW1,
234   aniHW2,
235   aniHW3,
236   aniHW4,
237   aniHW5,
238   aniHW6,
239   aniHW7,
240   aniHW8,
241   aniHW9,
242   aniRAMTop,
243   aniRAMBottom,
244   aniWallSpace
245 };
246
247 int getSequenceLength(int sequence)
248 {
249   switch (sequence)
250   {
251     case aniBug:
252       return 14;
253
254     case aniElectron:
255     case aniExplosion:
256       return 9;
257
258     case aniTouchInfotron:
259       return 7;
260
261     case aniMurphyExit:
262       return 40;
263
264     case aniRedDisk:
265       return 1;
266
267     default:
268       return 8;
269   }
270 }
271
272 boolean isSnappingSequence(int sequence)
273 {
274   switch (sequence)
275   {
276     case aniTouchBase:
277     case aniTouchInfotron:
278     case aniTouchRedDisk:
279       return TRUE;
280
281     default:
282       return FALSE;
283   }
284 }
285
286 #endif
287
288 void InitGlobals()
289 {
290 #if 0
291   aniBug = Array(74, 75, 76, 77, 78, 77, 76, 77, 78, 77, 76, 75, 74, 25);
292   aniZonkRollRight = Array(198, 197, 196, 195, 194, 193, 192, 1, -1);
293   aniZonkRollLeft = Array(192, 193, 194, 195, 196, 197, 198, 1, -1);
294   aniInfotronRollRight = Array(206, 205, 204, 203, 202, 201, 200, 4);
295   aniInfotronRollLeft = Array(200, 201, 202, 203, 204, 205, 206, 4);
296   aniSnikSnak = Array(121, 122, 123, 124, 125, 126, 127, 120, 121);
297   aniElectron = Array(144, 145, 146, 147, 148, 149, 150, 151, 144);
298   aniExplosion = Array(3, 103, 104, 105, 106, 107, 108, 109, 0);
299   aniTouchBase = Array(80, 81, 82, 83, 84, 85, 86, 0, -1);
300   aniTouchInfotron = Array(87, 88, 89, 91, 92, 93, 0, -1); // Only seven frames!!!!
301   aniTouchRedDisk = Array(96, 97, 98, 99, 100, 101, 102, 0, -1);
302   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);
303   aniMurphyEatLeft = Array(176, 177, 178, 179, 180, 181, 182, 183, -1);
304   aniMurphyEatRight = Array(184, 185, 186, 187, 188, 189, 190, 191, -1);
305   aniMurphyEatUpLeft = Array(183, 182, 181, 180, 179, 178, 177, 176, -1);
306   aniMurphyEatUpRight = Array(191, 190, 189, 188, 187, 186, 185, 184, -1);
307   // aniMurphyEatRightRedDisk = Array(184, 184, 185, 186, 187, 188, 189, 190, 191, -1) '9 frames!
308   aniEatInfotronLeft = Array(209, 211, 213, 215, 217, 219, 221, 223, -1);
309   aniEatInfotronRight = Array(224, 226, 228, 230, 232, 234, 236, 238, -1);
310   aniSplitUpDown = Array(3, 3, 3, 3, 3, 3, 3, 3, -1);
311   aniYellowDisk = Array(18, 18, 18, 18, 18, 18, 18, 18, -1);
312   aniOrangeDisk = Array(8, 8, 8, 8, 8, 8, 8, 8, -1);
313   aniRedDisk = Array(20, -1);
314 #endif
315
316   InitPseudoCompileFlags();
317   UserDragFlag = False;
318   AutoScrollFlag = True;
319   FreezeZonks = 0;
320   BlockingSpeed = False;
321   LevelLoaded = False;
322   FieldWidth = 60;
323   FieldHeight = 24;
324   HeaderSize = 96;
325   FieldMax = (FieldWidth * FieldHeight) + HeaderSize - 1;
326   LevelMax = (FieldWidth * FieldHeight) - 1;
327   Let_ModifiedFlag(False);
328   bPlaying = False;
329   gSignature = "";
330   bSignatureAvailable = False;
331   FirstDemoByte = 0x81;
332   MySignature = "";
333   InitErrorReporting();
334 }
335
336 void InitPseudoCompileFlags()
337 {
338   Cracked = 1;       // If protection Then crack it
339   Level_Arg = 1;     // :number is cmd line option
340   // Level_Arg  = 0     ' Remove Level cmd line option
341   EGA_Arg = 1;       // EGA is command line option
342   Record_Fix = 1;      // Assemble with fixed Demo rec
343   SpeedKeys = 0;     // Remove Speed Keys fix
344   Level_Fix = 1;     // Assemble with Level Fix
345   Dead_Code = 0;     // Remove dead code
346   Redundant = 0;     // Remove redundant code
347   Alignments = 1;      // Assemble with alignments
348   Ctrl_Alt_Fix = 1;      // Assemble with Ctrl/Alt fix
349   Protection = 0;      // Remove protection code,do HP
350   // EP added by EP for version 5.
351   EP_ENHANCE = 1;      // Some more nice things (EP)
352   EP_DEMO = 1;       // Use .SP files for demos (EP)
353   // Including record demo!
354   EP_DEBUG = 0;      // little cmdline debugging
355   EXTRASPEED = 1;      // '@' option, superfast!
356   TIMINGFIX = 1;     // "Fixed" the timing problem..
357   // Inactive If DemoRecordFix Then1
358   SafeRecord = 1;      // skip debug keys in recording
359   Norm_Time = 1;     // force automatic speed test,
360   // save result and then do as
361   // requested from cmd line.
362   EP_OLD8 = 1;       // call old int8 from current.
363   SAVEGAME = 1;      // Allow saving to SUPAPLEX.SAV
364   HP_DEMO = 1;       // Use fixed demo routines 5.5
365   ScreenFix = 1;     // No menu-write to gamy field
366   DemoRecordFix = 1;     // Demo record timing fix on
367   DebugSwitch = 1;     // Allow Ctrl/Alt-ScrollLock
368   Ver62 = 1;       // Version 6.2 stuff
369   Ver62test = 0;     // Version 6.2 test stuff
370   Ver63 = 1;       // Version 6.3 stuff
371   Ver64 = 1;       // Version 6.4 stuff
372
373 }
374
375 int GetSI(int X, int Y)
376 {
377   int GetSI;
378
379   GetSI = Y * FieldWidth + X;
380
381   return GetSI;
382 }
383
384 int GetX(int si)
385 {
386   int GetX;
387
388   GetX = si % FieldWidth;
389
390   return GetX;
391 }
392
393 int GetY(int si)
394 {
395   int GetY;
396
397   GetY = si / FieldWidth;
398
399   return GetY;
400 }
401
402 int GetStretchX(int si)
403 {
404   int GetStretchX;
405
406   GetStretchX = StretchWidth * (si % FieldWidth);
407
408   return GetStretchX;
409 }
410
411 int GetStretchY(int si)
412 {
413   int GetStretchY;
414
415   GetStretchY = StretchWidth * (si / FieldWidth);
416
417   return GetStretchY;
418 }
419
420 void OLD_ReadLevel()
421 {
422 #if 1
423   static char CurPathTEST[1024];
424 #endif
425
426   // int FNum;
427   FILE *FNum;
428   long i;
429   // byte T;
430
431 #if 1
432   // CurPath = "/home/aeglos/projects/rocksndiamonds/levels/TEST_supaplex/supaplex/levels.dat";
433
434 #if 0
435   CurPath = "/home/aeglos/projects/rocksndiamonds/supaplex_demo_JENS0001.sp";
436   LevelNumber = 1;
437 #else
438
439 #if 0
440   // sprintf(CurPathTEST, "/home/aeglos/projects/rocksndiamonds/levels/TEST_supaplex/test_solutions/%03d.sp", level_nr);
441
442   sprintf(CurPathTEST, "/home/aeglos/projects/Level_Stuff/SUPAPLEX/SUPAPLEX_LEVELS/Set77/77S%03d.SP", level_nr);
443 #else
444   sprintf(CurPathTEST, "/home/aeglos/projects/Level_Stuff/SUPAPLEX/SUPAPLEX_LEVELS/solve00/JENS%04d.SP", level_nr);
445 #endif
446
447   CurPath = CurPathTEST;
448   LevelNumber = level_nr;
449 #endif
450
451 #endif
452
453   DemoAvailable = False;
454
455   if (STRING_IS_LIKE(CurPath, "*.mpx") ||
456       STRING_IS_LIKE(CurPath, "*.MPX"))
457   {
458     printf("::: reading MPX file ...\n");
459
460     ReadMPX();
461     return;
462   }
463
464   if (STRING_IS_LIKE(CurPath, "*.sp") ||
465       STRING_IS_LIKE(CurPath, "*.SP"))
466   {
467     printf("::: reading SP file ...\n");
468
469     ReadDemo();
470     return;
471   }
472
473   if (DemoFlag != 0)
474   {
475     printf("::: reading demo file ...\n");
476
477     ReadDemo();
478     return;
479   }
480
481   printf("::: reading level file ...\n");
482
483   FileMax = 0;
484   FieldWidth = 60;
485   FieldHeight = 24;
486   HeaderSize = 96;
487
488   FieldMax = (FieldWidth * FieldHeight) + HeaderSize - 1;
489   LevelMax = (FieldWidth * FieldHeight) - 1;
490
491   PlayField8 = REDIM_1D(sizeof(byte), 0, FieldMax + 1 - 1);
492   DisPlayField = REDIM_1D(sizeof(byte), 0, FieldMax + 1 - 1);
493
494   // FNum = FreeFile();
495
496   // --- On Error GoTo ReadLevelEH
497
498   printf("::: '%s', %d\n", CurPath, LevelNumber);
499
500   FNum = fopen(CurPath, "rb");
501
502   i = (LevelNumber - 1) * ((long)(FieldMax) + 1) + 1;
503 #if 1
504   FILE_GET(FNum, i, PlayField8, FieldMax + 1);
505 #else
506   FILE_GET(FNum, i, &PlayField8, sizeof(PlayField8));
507 #endif
508
509   i = (LevelNumber) * ((long)(FieldMax) + 1) + 1 - HeaderSize;
510   FILE_GET(FNum, i, &LInfo, sizeof(LInfo)); // store level info in an extra structure
511
512   fclose(FNum);
513
514   // --- On Error GoTo 0
515
516   if (FieldMax < FileMax)
517     DemoAvailable = True;
518
519   ReadSignature();
520
521   PlayField16 = REDIM_1D(sizeof(int), -FieldWidth, FieldMax);
522
523   for (i = 0; i <= FieldMax; i++)
524   {
525     PlayField16[i]  = PlayField8[i];
526     DisPlayField[i] = PlayField8[i];
527     PlayField8[i] = 0;
528   }
529
530 #if 0
531  {
532    int x, y;
533
534    for (x = 0; x < 60; x++)
535      printf("%02d.", x);
536    printf("\n");
537
538    for (x = 0; x < 60; x++)
539      printf("...");
540    printf("\n");
541
542    for (y = 0; y < 24; y++)
543    {
544      for (x = 0; x < 60; x++)
545      {
546        printf("%02d.", PlayField16[y * 60 + x]);
547      }
548
549      printf("\n");
550    }
551  }
552 #endif
553
554   AnimationPosTable = REDIM_1D(sizeof(int), 0, LevelMax - 2 * FieldWidth);
555   AnimationSubTable = REDIM_1D(sizeof(byte), 0, LevelMax - 2 * FieldWidth);
556   TerminalState = REDIM_1D(sizeof(byte), FieldWidth, LevelMax - FieldWidth);
557
558   GravityFlag = LInfo.InitialGravity;
559   FreezeZonks = LInfo.InitialFreezeZonks;
560
561   subRandomize();
562
563   LevelLoaded = True;
564
565   return;
566
567 #if 0
568 ReadLevelEH:
569   Close();
570 #endif
571 }
572
573 static void ReadDemo()
574 {
575   // int FNum, i;
576   FILE *FNum;
577   int i;
578   // byte T;
579
580   int RecordNumber = LevelNumber;
581
582 #if 1
583   RecordNumber = 1;     // always "1" for "*.sp" style one level/demo files
584 #endif
585
586   FieldWidth = 60;
587   FieldHeight = 24;
588   HeaderSize = 96;
589
590   FieldMax = (FieldWidth * FieldHeight) + HeaderSize - 1;
591   LevelMax = (FieldWidth * FieldHeight) - 1;
592
593   // --- On Error GoTo ReadDemoEH
594
595   FileMax = FileLen(CurPath) - 1;
596
597   PlayField8 = REDIM_1D(sizeof(byte), 0, FileMax + 1 - 1);
598   DisPlayField = REDIM_1D(sizeof(byte), 0, FieldMax + 1 - 1);
599
600   // FNum = FreeFile();
601
602   FNum = fopen(CurPath, "rb");
603
604   i = (RecordNumber - 1) * ((long)(FieldMax) + 1) + 1;
605 #if 1
606   FILE_GET(FNum, i, PlayField8, FileMax + 1);
607 #else
608   FILE_GET(FNum, i, &PlayField8, sizeof(PlayField8));
609 #endif
610
611   i = (RecordNumber) * ((long)(FieldMax) + 1) + 1 - HeaderSize;
612   FILE_GET(FNum, i, &LInfo, sizeof(LInfo)); // store level info in an extra structure
613
614   fclose(FNum);
615
616   // --- On Error GoTo 0
617
618   if (FieldMax < FileMax)
619     DemoAvailable = True;
620
621   ReadSignature();
622
623   PlayField16 = REDIM_1D(sizeof(int), -FieldWidth, FieldMax);
624
625   for (i = 0; i <= FieldMax; i++)
626   {
627     PlayField16[i] = PlayField8[i];
628     DisPlayField[i] = PlayField8[i];
629     PlayField8[i] = 0;
630   }
631
632   AnimationPosTable = REDIM_1D(sizeof(int), 0, LevelMax - 2 * FieldWidth);
633   AnimationSubTable = REDIM_1D(sizeof(byte), 0, LevelMax - 2 * FieldWidth);
634   TerminalState = REDIM_1D(sizeof(byte), 0, FieldMax + 1 - 1);
635
636   DemoPointer = FieldMax + 1;
637   DemoOffset = DemoPointer;
638   DemoKeyRepeatCounter = 0;
639
640   // DemoFlag = 1
641   // DemoAvailable = True
642
643   GravityFlag = LInfo.InitialGravity;
644   FreezeZonks = LInfo.InitialFreezeZonks;
645
646 #if 0
647   printf("::: Globals.c: ReadDemo(): %d / %d\n", GravityFlag, FreezeZonks);
648 #endif
649
650
651
652 #if 0
653   /* !!! TESTING BIG / LITTLE ENDIAN STUFF !!! */
654   LInfo.DemoRandomSeed =
655     LowByte(LInfo.DemoRandomSeed) << 8 |
656     HighByte(LInfo.DemoRandomSeed);
657   for (i = 0; i < 10; i++)
658     LInfo.SpecialPort[i].PortLocation =
659       LowByte(LInfo.SpecialPort[i].PortLocation) << 8 |
660       HighByte(LInfo.SpecialPort[i].PortLocation);
661
662   printf("::: swapping file bytes for DemoRandomSeed etc.\n");
663 #else
664   printf("::: keeping file bytes in (maybe wrong) 'native' order.\n");
665 #endif
666
667 #if 1
668   printf("::: LInfo.DemoRandomSeed == %d\n", LInfo.DemoRandomSeed);
669 #endif
670
671 #if 0
672   printf("::: LInfo.SpecialPortCount == %d\n", LInfo.SpecialPortCount);
673   for (i = 0; i < LInfo.SpecialPortCount; i++)
674   {
675     int port_x = (LInfo.SpecialPort[i].PortLocation / 2) % FieldWidth;
676     int port_y = (LInfo.SpecialPort[i].PortLocation / 2) / FieldWidth;
677
678     printf("::: %d: port_location == %d => (%d, %d)\n",
679            i, LInfo.SpecialPort[i].PortLocation, port_x, port_y);
680   }
681 #endif
682
683   RandomSeed = LInfo.DemoRandomSeed;
684
685 #if 0
686   printf("::: SpeedByte == %d\n", LInfo.SpeedByte);
687   printf("::: CheckSumByte == %d\n", LInfo.CheckSumByte);
688   printf("::: RandomSeed == %d\n", RandomSeed);
689
690 #if 0
691   {
692     int i;
693
694     for (i = 0; i < 10; i++)
695       printf("::: TEST random number: %d\n", subGetRandomNumber());
696   }
697 #endif
698
699 #endif
700
701   LevelLoaded = True;
702
703   return;
704
705 #if 0
706 ReadDemoEH:
707   Close();
708 #endif
709 }
710
711 void ReadLevel()
712 {
713 #if 0
714   OLD_ReadLevel();
715
716   // return;
717 #endif
718
719   copyInternalEngineVars_SP();
720
721 #if 1
722   SetDisplayRegion();
723   SetScrollEdges();
724 #endif
725
726   LevelNumber = level_nr;
727
728 #if 0
729   if (!DemoFlag || !DemoAvailable)
730     subRandomize();
731 #endif
732
733   LevelLoaded = True;
734 }