rnd-20091028-1-src
[rocksndiamonds.git] / src / game_sp / MainForm.c
1 // ----------------------------------------------------------------------------
2 // MainForm.c
3 // ----------------------------------------------------------------------------
4
5 #include "MainForm.h"
6
7 #if 1
8
9 static void DrawFrame(int Delta);
10 static void ReStretch(float NewStretch);
11 static void picPane_Paint();
12 static void picViewPort_Resize();
13 static void menBorder_Click();
14
15 #else
16
17 static void CleanTempDir(char *TmpDir);
18 static void CountDown(long HalfSeconds, int bDisplayBar);
19 static void DrawFrame(int Delta);
20 static void DrawPauseLayer(long Layer);
21 static void FillFileList(char *Path);
22 static void FillLevelList(char *Path, int LevelIndex);
23 static void FocusTim_Timer();
24 static void Form_KeyDown(int KeyCode, int Shift);
25 static void Form_KeyUp(int KeyCode, int Shift);
26 static void Form_Paint();
27 static int GetFileNameToSave();
28 static long GetHwndFromTempFileName(char *TmpFile);
29 static char * GetMyTempFileName();
30 static void GetSettings();
31 static char * GetSpeedDescriptionFPS(currency FrameDelayUS);
32 static int GetSpeedIndex(long DelayUS);
33 static char * GetValidTempPath();
34 static long Get_LastOpenFilter();
35 static long Get_LastSaveFilter();
36 static int InitSpeeds();
37 static boolean InstanceStillRunning(char *TmpFile);
38 static void Let_LastOpenFilter(long NewVal);
39 static void Let_LastSaveFilter(long NewVal);
40 static void LoadKeyIndicators();
41 static void LoadMenus();
42 static void PanelTim_Timer();
43 static void ReStretch(float NewStretch);
44 static void RestoreFrame();
45 static boolean SaveAs();
46 static void SaveSettings();
47 static void SetScrollEdges();
48 static void UpdateDeltaT();
49 static void cmbFile_Click();
50 static void cmbFile_KeyDown(int KeyCode, int Shift);
51 static void cmbFile_KeyUp(int KeyCode, int Shift);
52 static void cmbLevel_Click();
53 static void cmbLevel_KeyUp(int KeyCode, int Shift);
54 static void cmblevel_KeyDown(int KeyCode, int Shift);
55 static void cmdPause_Click();
56 static void cmdPause_MouseUp(int Button, int Shift, float X, float Y);
57 static void cmdPlayAll_Click();
58 static void cmdPlayAll_MouseUp(int Button, int Shift, float X, float Y);
59 static void cmdPlayDemo_Click();
60 static void cmdPlayDemo_MouseUp(int Button, int Shift, float X, float Y);
61 static void cmdPlay_Click();
62 static void cmdPlay_MouseUp(int Button, int Shift, float X, float Y);
63 static void cmdRecordDemo_Click();
64 static void cmdRecordDemo_MouseUp(int Button, int Shift, float X, float Y);
65 static void cmdStop_Click();
66 static void cmdStop_MouseUp(int Button, int Shift, float X, float Y);
67 static void fpsTim_Timer();
68 static void menAbout_Click();
69 static void menAutoScroll_Click();
70 static void menBorder_Click();
71 static void menCopy_Click();
72 static void menEnOff_Click();
73 static void menEnOn_Click();
74 static void menExit_Click();
75 static void menFaster_Click();
76 static void menGravOff_Click();
77 static void menGravOn_Click();
78 static void menNewStd_Click();
79 static void menNew_Click();
80 static void menOpen_Click();
81 static void menOptions_Click();
82 static void menPanel_Click();
83 static void menPaste_Click();
84 static void menPause_Click();
85 static void menPlayAll_Click();
86 static void menPlayDemo_Click();
87 static void menPlay_Click();
88 static void menReRecordDemo_Click();
89 static void menRec_Click();
90 static void menRemSP_Click();
91 static void menRestoreBorder_Click();
92 static void menSaveAs_Click();
93 static void menSave_Click();
94 static void menSelectAll_Click();
95 static void menShowLInfo_Click();
96 static void menSlower_Click();
97 static void menSoundFX_Click();
98 static void menStretch_Click(int Index);
99 static void menToolTips_Click();
100 static void menTrim_Click();
101 static void menZonkOff_Click();
102 static void menZonkOn_Click();
103 static void picKeys_MouseUp(int Button, int Shift, float X, float Y);
104 static void picMenu_Click();
105 static void picPane_KeyDown(int KeyCode, int Shift);
106 static void picPane_KeyUp(int KeyCode, int Shift);
107 static void picPane_MouseDown(int Button, int Shift, float X, float Y);
108 static void picPane_MouseMove(int Button, int Shift, float X, float Y);
109 static void picPane_MouseUp(int Button, int Shift, float X, float Y);
110 static void picPane_Paint();
111 static void picViewPort_MouseUp(int Button, int Shift, float X, float Y);
112 static void picViewPort_Paint();
113 static void picViewPort_Resize();
114
115 #endif
116
117 void DrawField(int X, int Y);
118 void DrawFieldAnimated(int X, int Y);
119 void DrawFieldNoAnimated(int X, int Y);
120
121 // --- VERSION 5.00
122 // --- Object = "{F9043C88-F6F2-101A-A3C9-08002B2F49FB}#1.2#0"; "COMDLG32.OCX"
123 // --- Begin VB.Form MainForm 
124 // ---    AutoRedraw      =   -1  'True  // True
125 // ---    Caption         =   "MegaPlex"
126 // ---    ClientHeight    =   5850
127 // ---    ClientLeft      =   2580
128 // ---    ClientTop       =   2205
129 // ---    ClientWidth     =   9285
130 // ---    Icon            =   "MainForm.frx":0000
131 // ---    LinkTopic       =   "Form1"
132 // ---    ScaleHeight     =   390
133 // ---    ScaleMode       =   3  'Pixel  // Pixel
134 // ---    ScaleWidth      =   619
135 // ---    Begin VB.Timer fpsTim 
136 // ---       Enabled         =   0   'False   // False
137 // ---       Interval        =   200
138 // ---       Left            =   1380
139 // ---       Top             =   2940
140 // ---    End
141 // ---    Begin VB.Timer FocusTim 
142 // ---       Interval        =   50
143 // ---       Left            =   1920
144 // ---       Top             =   2940
145 // ---    End
146 // ---    Begin MSComDlg.CommonDialog cmDlg 
147 // ---       Left            =   240
148 // ---       Top             =   2880
149 // ---       _ExtentX        =   847
150 // ---       _ExtentY        =   847
151 // ---       _Version        =   393216
152 // ---       CancelError     =   -1  'True  // True
153 // ---    End
154 // ---    Begin VB.Timer PanelTim 
155 // ---       Enabled         =   0   'False   // False
156 // ---       Interval        =   5
157 // ---       Left            =   840
158 // ---       Top             =   2940
159 // ---    End
160 // ---    Begin VB.Frame Panel 
161 // ---       Height          =   1140
162 // ---       Left            =   180
163 // ---       TabIndex        =   2
164 // ---       Top             =   3540
165 // ---       Width           =   9015
166 // ---       Begin VB.CommandButton cmdPlay 
167 // ---          DisabledPicture =   "MainForm.frx":0442
168 // ---          DownPicture     =   "MainForm.frx":058C
169 // ---          Height          =   345
170 // ---          Left            =   5820
171 // ---          Picture         =   "MainForm.frx":06D6
172 // ---          Style           =   1  'Graphical  // Graphical
173 // ---          TabIndex        =   16
174 // ---          TabStop         =   0   'False   // False
175 // ---          Top             =   240
176 // ---          Width           =   495
177 // ---       End
178 // ---       Begin VB.CommandButton cmdStop 
179 // ---          DisabledPicture =   "MainForm.frx":0820
180 // ---          DownPicture     =   "MainForm.frx":096A
181 // ---          Enabled         =   0   'False   // False
182 // ---          Height          =   345
183 // ---          Left            =   7020
184 // ---          Picture         =   "MainForm.frx":0AB4
185 // ---          Style           =   1  'Graphical  // Graphical
186 // ---          TabIndex        =   15
187 // ---          TabStop         =   0   'False   // False
188 // ---          Top             =   240
189 // ---          Width           =   495
190 // ---       End
191 // ---       Begin VB.CommandButton cmdPlayDemo 
192 // ---          DisabledPicture =   "MainForm.frx":0BFE
193 // ---          DownPicture     =   "MainForm.frx":0D48
194 // ---          Enabled         =   0   'False   // False
195 // ---          Height          =   345
196 // ---          Left            =   7740
197 // ---          Picture         =   "MainForm.frx":0E92
198 // ---          Style           =   1  'Graphical  // Graphical
199 // ---          TabIndex        =   14
200 // ---          TabStop         =   0   'False   // False
201 // ---          Top             =   240
202 // ---          Width           =   495
203 // ---       End
204 // ---       Begin VB.CommandButton cmdPause 
205 // ---          DisabledPicture =   "MainForm.frx":0FDC
206 // ---          DownPicture     =   "MainForm.frx":1126
207 // ---          Enabled         =   0   'False   // False
208 // ---          Height          =   345
209 // ---          Left            =   6420
210 // ---          Picture         =   "MainForm.frx":1270
211 // ---          Style           =   1  'Graphical  // Graphical
212 // ---          TabIndex        =   13
213 // ---          TabStop         =   0   'False   // False
214 // ---          Top             =   240
215 // ---          Width           =   495
216 // ---       End
217 // ---       Begin VB.CommandButton cmdRecordDemo 
218 // ---          DisabledPicture =   "MainForm.frx":13BA
219 // ---          DownPicture     =   "MainForm.frx":1504
220 // ---          Height          =   345
221 // ---          Left            =   8340
222 // ---          Picture         =   "MainForm.frx":164E
223 // ---          Style           =   1  'Graphical  // Graphical
224 // ---          TabIndex        =   12
225 // ---          TabStop         =   0   'False   // False
226 // ---          Top             =   240
227 // ---          Width           =   495
228 // ---       End
229 // ---       Begin VB.ComboBox cmbFile 
230 // ---          BackColor       =   &H00000000&
231 // ---          BeginProperty Font 
232 // ---             Name            =   "Fixedsys"
233 // ---             Size            =   9
234 // ---             Charset         =   0
235 // ---             Weight          =   400
236 // ---             Underline       =   0   'False   // False
237 // ---             Italic          =   0   'False   // False
238 // ---             Strikethrough   =   0   'False   // False
239 // ---          EndProperty
240 // ---          ForeColor       =   &H00FF8080&
241 // ---          Height          =   345
242 // ---          Left            =   120
243 // ---          Sorted          =   -1  'True  // True
244 // ---          Style           =   2  'Dropdown List  // Dropdown List
245 // ---          TabIndex        =   9
246 // ---          Top             =   240
247 // ---          Width           =   3015
248 // ---       End
249 // ---       Begin VB.ComboBox cmbLevel 
250 // ---          BackColor       =   &H00000000&
251 // ---          BeginProperty Font 
252 // ---             Name            =   "Fixedsys"
253 // ---             Size            =   9
254 // ---             Charset         =   0
255 // ---             Weight          =   400
256 // ---             Underline       =   0   'False   // False
257 // ---             Italic          =   0   'False   // False
258 // ---             Strikethrough   =   0   'False   // False
259 // ---          EndProperty
260 // ---          ForeColor       =   &H00FF8080&
261 // ---          Height          =   345
262 // ---          Left            =   840
263 // ---          Sorted          =   -1  'True  // True
264 // ---          Style           =   2  'Dropdown List  // Dropdown List
265 // ---          TabIndex        =   5
266 // ---          Top             =   660
267 // ---          Width           =   4035
268 // ---       End
269 // ---       Begin VB.PictureBox picKeys 
270 // ---          BackColor       =   &H00008080&
271 // ---          BorderStyle     =   0  'None  // None
272 // ---          Height          =   330
273 // ---          Left            =   5400
274 // ---          ScaleHeight     =   22
275 // ---          ScaleMode       =   3  'Pixel  // Pixel
276 // ---          ScaleWidth      =   22
277 // ---          TabIndex        =   4
278 // ---          TabStop         =   0   'False   // False
279 // ---          Top             =   240
280 // ---          Width           =   330
281 // ---          Begin VB.Shape shpKey 
282 // ---             FillColor       =   &H00008000&
283 // ---             FillStyle       =   0  'Solid  // Solid
284 // ---             Height          =   120
285 // ---             Index           =   1
286 // ---             Left            =   0
287 // ---             Shape           =   5  'Rounded Square  // Rounded Square
288 // ---             Top             =   0
289 // ---             Width           =   120
290 // ---          End
291 // ---       End
292 // ---       Begin VB.CommandButton cmdPlayAll 
293 // ---          Caption         =   "Play All Demos"
294 // ---          Enabled         =   0   'False   // False
295 // ---          Height          =   345
296 // ---          Left            =   7380
297 // ---          TabIndex        =   3
298 // ---          TabStop         =   0   'False   // False
299 // ---          Top             =   960
300 // ---          Visible         =   0   'False   // False
301 // ---          Width           =   1395
302 // ---       End
303 // ---       Begin VB.Shape shpProgress 
304 // ---          BackColor       =   &H00800000&
305 // ---          BackStyle       =   1  'Opaque  // Opaque
306 // ---          Height          =   75
307 // ---          Left            =   120
308 // ---          Top             =   1020
309 // ---          Visible         =   0   'False   // False
310 // ---          Width           =   7515
311 // ---       End
312 // ---       Begin VB.Label lblStatus 
313 // ---          Alignment       =   2  'Center  // Center
314 // ---          BorderStyle     =   1  'Fixed Single  // Fixed Single
315 // ---          Caption         =   "MegaPlex"
316 // ---          BeginProperty Font 
317 // ---             Name            =   "Fixedsys"
318 // ---             Size            =   9
319 // ---             Charset         =   0
320 // ---             Weight          =   400
321 // ---             Underline       =   0   'False   // False
322 // ---             Italic          =   0   'False   // False
323 // ---             Strikethrough   =   0   'False   // False
324 // ---          EndProperty
325 // ---          Height          =   345
326 // ---          Left            =   3240
327 // ---          TabIndex        =   11
328 // ---          Top             =   240
329 // ---          Width           =   2055
330 // ---       End
331 // ---       Begin VB.Image Image2 
332 // ---          Height          =   240
333 // ---          Left            =   6780
334 // ---          Picture         =   "MainForm.frx":1BD8
335 // ---          Top             =   720
336 // ---          Width           =   240
337 // ---       End
338 // ---       Begin VB.Image Image1 
339 // ---          Height          =   240
340 // ---          Left            =   5880
341 // ---          Picture         =   "MainForm.frx":1D22
342 // ---          Top             =   720
343 // ---          Width           =   240
344 // ---       End
345 // ---       Begin VB.Label lblFps 
346 // ---          Alignment       =   2  'Center  // Center
347 // ---          BackColor       =   &H00000000&
348 // ---          BorderStyle     =   1  'Fixed Single  // Fixed Single
349 // ---          BeginProperty Font 
350 // ---             Name            =   "Fixedsys"
351 // ---             Size            =   9
352 // ---             Charset         =   0
353 // ---             Weight          =   400
354 // ---             Underline       =   0   'False   // False
355 // ---             Italic          =   0   'False   // False
356 // ---             Strikethrough   =   0   'False   // False
357 // ---          EndProperty
358 // ---          ForeColor       =   &H0000C0C0&
359 // ---          Height          =   345
360 // ---          Left            =   120
361 // ---          TabIndex        =   10
362 // ---          Top             =   660
363 // ---          Width           =   615
364 // ---       End
365 // ---       Begin VB.Label lblInfoCount 
366 // ---          Alignment       =   2  'Center  // Center
367 // ---          BackColor       =   &H00000000&
368 // ---          BorderStyle     =   1  'Fixed Single  // Fixed Single
369 // ---          BeginProperty Font 
370 // ---             Name            =   "Fixedsys"
371 // ---             Size            =   9
372 // ---             Charset         =   0
373 // ---             Weight          =   400
374 // ---             Underline       =   0   'False   // False
375 // ---             Italic          =   0   'False   // False
376 // ---             Strikethrough   =   0   'False   // False
377 // ---          EndProperty
378 // ---          ForeColor       =   &H00FF8080&
379 // ---          Height          =   345
380 // ---          Left            =   5040
381 // ---          TabIndex        =   8
382 // ---          Top             =   660
383 // ---          Width           =   795
384 // ---       End
385 // ---       Begin VB.Label lblRedDiskCount 
386 // ---          Alignment       =   2  'Center  // Center
387 // ---          BackColor       =   &H00000000&
388 // ---          BorderStyle     =   1  'Fixed Single  // Fixed Single
389 // ---          BeginProperty Font 
390 // ---             Name            =   "Fixedsys"
391 // ---             Size            =   9
392 // ---             Charset         =   0
393 // ---             Weight          =   400
394 // ---             Underline       =   0   'False   // False
395 // ---             Italic          =   0   'False   // False
396 // ---             Strikethrough   =   0   'False   // False
397 // ---          EndProperty
398 // ---          ForeColor       =   &H000000FF&
399 // ---          Height          =   345
400 // ---          Left            =   6240
401 // ---          TabIndex        =   7
402 // ---          Top             =   660
403 // ---          Width           =   495
404 // ---       End
405 // ---       Begin VB.Label lblFrameCount 
406 // ---          Alignment       =   2  'Center  // Center
407 // ---          BorderStyle     =   1  'Fixed Single  // Fixed Single
408 // ---          Caption         =   "0"
409 // ---          BeginProperty Font 
410 // ---             Name            =   "Fixedsys"
411 // ---             Size            =   9
412 // ---             Charset         =   0
413 // ---             Weight          =   400
414 // ---             Underline       =   0   'False   // False
415 // ---             Italic          =   0   'False   // False
416 // ---             Strikethrough   =   0   'False   // False
417 // ---          EndProperty
418 // ---          Height          =   345
419 // ---          Left            =   7200
420 // ---          TabIndex        =   6
421 // ---          Top             =   660
422 // ---          Width           =   1635
423 // ---       End
424 // ---    End
425 // ---    Begin VB.PictureBox picViewPort 
426 // ---       BorderStyle     =   0  'None  // None
427 // ---       Height          =   2535
428 // ---       Left            =   180
429 // ---       ScaleHeight     =   169
430 // ---       ScaleMode       =   3  'Pixel  // Pixel
431 // ---       ScaleWidth      =   265
432 // ---       TabIndex        =   0
433 // ---       TabStop         =   0   'False   // False
434 // ---       Top             =   180
435 // ---       Width           =   3975
436 // ---       Begin VB.PictureBox picPane 
437 // ---          AutoSize        =   -1  'True  // True
438 // ---          BackColor       =   &H00000000&
439 // ---          BorderStyle     =   0  'None  // None
440 // ---          DrawWidth       =   3
441 // ---          Height          =   1635
442 // ---          Left            =   240
443 // ---          ScaleHeight     =   109
444 // ---          ScaleMode       =   3  'Pixel  // Pixel
445 // ---          ScaleWidth      =   129
446 // ---          TabIndex        =   1
447 // ---          Top             =   180
448 // ---          Width           =   1935
449 // ---       End
450 // ---       Begin VB.PictureBox picFrame 
451 // ---          Height          =   915
452 // ---          Left            =   1320
453 // ---          ScaleHeight     =   57
454 // ---          ScaleMode       =   3  'Pixel  // Pixel
455 // ---          ScaleWidth      =   81
456 // ---          TabIndex        =   17
457 // ---          TabStop         =   0   'False   // False
458 // ---          Top             =   1200
459 // ---          Width           =   1275
460 // ---       End
461 // ---    End
462 // ---    Begin VB.Menu menFile 
463 // ---       Caption         =   "&File"
464 // ---       Begin VB.Menu menNewStd 
465 // ---          Caption         =   "New S&tandard Level"
466 // ---       End
467 // ---       Begin VB.Menu menNew 
468 // ---          Caption         =   "&New Level"
469 // ---       End
470 // ---       Begin VB.Menu menDash5 
471 // ---          Caption         =   "-"
472 // ---       End
473 // ---       Begin VB.Menu menOpen 
474 // ---          Caption         =   "&Open"
475 // ---       End
476 // ---       Begin VB.Menu menSave 
477 // ---          Caption         =   "&Save"
478 // ---          Shortcut        =   ^S
479 // ---       End
480 // ---       Begin VB.Menu menSaveAs 
481 // ---          Caption         =   "Save &As ..."
482 // ---       End
483 // ---       Begin VB.Menu menDash4 
484 // ---          Caption         =   "-"
485 // ---       End
486 // ---       Begin VB.Menu menExit 
487 // ---          Caption         =   "E&xit"
488 // ---          Shortcut        =   ^Q
489 // ---       End
490 // ---    End
491 // ---    Begin VB.Menu menEditMain 
492 // ---       Caption         =   "&Edit"
493 // ---       Begin VB.Menu menEdit 
494 // ---          Caption         =   "&Edit Level"
495 // ---       End
496 // ---       Begin VB.Menu menDash3 
497 // ---          Caption         =   "-"
498 // ---       End
499 // ---       Begin VB.Menu menCopy 
500 // ---          Caption         =   "&Copy"
501 // ---          Shortcut        =   ^C
502 // ---       End
503 // ---       Begin VB.Menu menPaste 
504 // ---          Caption         =   "&Paste"
505 // ---          Shortcut        =   ^V
506 // ---       End
507 // ---       Begin VB.Menu menTrim 
508 // ---          Caption         =   "&Trim"
509 // ---          Shortcut        =   ^T
510 // ---       End
511 // ---       Begin VB.Menu menDash8 
512 // ---          Caption         =   "-"
513 // ---          Index           =   1
514 // ---       End
515 // ---       Begin VB.Menu menSelectAll 
516 // ---          Caption         =   "Select &All"
517 // ---          Shortcut        =   ^A
518 // ---       End
519 // ---       Begin VB.Menu menDash6 
520 // ---          Caption         =   "-"
521 // ---       End
522 // ---       Begin VB.Menu menRestoreBorder 
523 // ---          Caption         =   "Restore &border"
524 // ---          Shortcut        =   ^B
525 // ---       End
526 // ---       Begin VB.Menu menSp 
527 // ---          Caption         =   "Special Port"
528 // ---          Begin VB.Menu menGravOn 
529 // ---             Caption         =   "&Gravity On"
530 // ---          End
531 // ---          Begin VB.Menu menZonkOn 
532 // ---             Caption         =   "Freeze &Zonks On"
533 // ---          End
534 // ---          Begin VB.Menu menEnOn 
535 // ---             Caption         =   "Freeze &Enemies On"
536 // ---          End
537 // ---          Begin VB.Menu menDash7 
538 // ---             Caption         =   "-"
539 // ---          End
540 // ---          Begin VB.Menu menGravOff 
541 // ---             Caption         =   "Gravity &Off"
542 // ---          End
543 // ---          Begin VB.Menu menZonkOff 
544 // ---             Caption         =   "Freeze Zon&ks Off"
545 // ---          End
546 // ---          Begin VB.Menu menEnOff 
547 // ---             Caption         =   "Freeze E&nemies Off"
548 // ---          End
549 // ---          Begin VB.Menu menDash10 
550 // ---             Caption         =   "-"
551 // ---          End
552 // ---          Begin VB.Menu menRemSP 
553 // ---             Caption         =   "&Remove (Make Normal Port)"
554 // ---          End
555 // ---       End
556 // ---    End
557 // ---    Begin VB.Menu menView 
558 // ---       Caption         =   "&View"
559 // ---       Begin VB.Menu menZoom 
560 // ---          Caption         =   "&Zoom"
561 // ---          Begin VB.Menu menStretch 
562 // ---             Caption         =   "0.25 : 1"
563 // ---             Index           =   1
564 // ---          End
565 // ---       End
566 // ---       Begin VB.Menu menBorder 
567 // ---          Caption         =   "Show &Border"
568 // ---          Checked         =   -1  'True  // True
569 // ---       End
570 // ---       Begin VB.Menu menPanel 
571 // ---          Caption         =   "Show &Panel"
572 // ---          Checked         =   -1  'True  // True
573 // ---       End
574 // ---       Begin VB.Menu menAutoScroll 
575 // ---          Caption         =   "&Autoscroll"
576 // ---          Checked         =   -1  'True  // True
577 // ---       End
578 // ---       Begin VB.Menu menDash9 
579 // ---          Caption         =   "-"
580 // ---       End
581 // ---       Begin VB.Menu menShowLInfo 
582 // ---          Caption         =   "Show Level &Info"
583 // ---       End
584 // ---    End
585 // ---    Begin VB.Menu menSound 
586 // ---       Caption         =   "&Sound"
587 // ---       Begin VB.Menu menSoundFX 
588 // ---          Caption         =   "&FX"
589 // ---       End
590 // ---       Begin VB.Menu menMusic 
591 // ---          Caption         =   "&Music"
592 // ---          Enabled         =   0   'False   // False
593 // ---       End
594 // ---    End
595 // ---    Begin VB.Menu menSpeed 
596 // ---       Caption         =   "Speed"
597 // ---       Begin VB.Menu menSpeedPlay 
598 // ---          Caption         =   "Game play"
599 // ---          Index           =   11
600 // ---          Begin VB.Menu menPlaySpeed 
601 // ---             Caption         =   "1"
602 // ---             Index           =   1
603 // ---          End
604 // ---       End
605 // ---       Begin VB.Menu menSpeedDemo 
606 // ---          Caption         =   "Demo playback"
607 // ---          Begin VB.Menu menDemoSpeed 
608 // ---             Caption         =   "1"
609 // ---             Index           =   1
610 // ---          End
611 // ---       End
612 // ---       Begin VB.Menu menSpeedDash 
613 // ---          Caption         =   "-"
614 // ---       End
615 // ---       Begin VB.Menu menFaster 
616 // ---          Caption         =   "Faster (Pg Up)"
617 // ---       End
618 // ---       Begin VB.Menu menSlower 
619 // ---          Caption         =   "Slower (Pg Down)"
620 // ---       End
621 // ---    End
622 // ---    Begin VB.Menu menRun 
623 // ---       Caption         =   "&Play"
624 // ---       Begin VB.Menu menPlay 
625 // ---          Caption         =   "P&lay Game    (Space)"
626 // ---       End
627 // ---       Begin VB.Menu menPause 
628 // ---          Caption         =   "&Pause    (P)"
629 // ---          Enabled         =   0   'False   // False
630 // ---       End
631 // ---       Begin VB.Menu menStop 
632 // ---          Caption         =   "&Stop    (Q)"
633 // ---          Enabled         =   0   'False   // False
634 // ---       End
635 // ---       Begin VB.Menu menDash0 
636 // ---          Caption         =   "-"
637 // ---       End
638 // ---       Begin VB.Menu menRec 
639 // ---          Caption         =   "&Record Demo    (Ctrl+R)"
640 // ---       End
641 // ---       Begin VB.Menu menPlayDemo 
642 // ---          Caption         =   "Play &Demo    (Ctrl+Space)"
643 // ---       End
644 // ---       Begin VB.Menu menPlayAll 
645 // ---          Caption         =   "Play &All Demos"
646 // ---       End
647 // ---    End
648 // ---    Begin VB.Menu menOptionsMain 
649 // ---       Caption         =   "&Options"
650 // ---       Begin VB.Menu menOptions 
651 // ---          Caption         =   "&Options ..."
652 // ---       End
653 // ---    End
654 // ---    Begin VB.Menu menHelp 
655 // ---       Caption         =   "Help"
656 // ---       Begin VB.Menu menToolTips 
657 // ---          Caption         =   "Show &ToolTips"
658 // ---       End
659 // ---       Begin VB.Menu menDash1 
660 // ---          Caption         =   "-"
661 // ---       End
662 // ---       Begin VB.Menu menAbout 
663 // ---          Caption         =   "&About MegaPlex"
664 // ---       End
665 // ---    End
666 // --- End
667
668 // static char *VB_Name = "MainForm";
669 // static boolean VB_GlobalNameSpace = False;
670 // static boolean VB_Creatable = False;
671 // static boolean VB_PredeclaredId = True;
672 // static boolean VB_Exposed = False;
673
674 // --- Option Explicit
675 // --- Option Compare Text
676
677 long SetParent(long hWndChild, long hWndNewParent);
678 long SetWindowLong(long hWnd, long nIndex, long dwNewLong);
679 long GetWindowLong(long hWnd, long nIndex);
680 long GetTempPath(long nBufferLength, char *lpBuffer);
681 long GetWindowText(long hWnd, char *lpString, long cch);
682
683 #define GWL_STYLE                       ((-16))
684 #define WS_CHILD                        (0x40000000)
685 #define WS_POPUP                        (0x80000000)
686
687 // [UNCOMMENTED] Dim StretchWidth2&
688
689 char *MpxBmp;
690 int OldPointer;
691 long OSX, OSY, MDX, MDY;
692 int MouseButton;
693
694 int PanelSeq;
695
696 boolean Loaded, DemosAvailable;
697
698 #define nSpeedCount                     (17)
699 int SpeedsByDelayUS[nSpeedCount + 1];
700 #define DefaultSpeedIndex                       (12)
701
702 currency LastTick, LastFrame;
703 TickCountObject T;
704
705 const char *AppTitle = "MegaPlex";
706
707 #if 0
708
709 static char *GetSpeedDescriptionFPS(currency FrameDelayUS)
710 {
711   static char *GetSpeedDescriptionFPS;
712
713   long FPS;
714
715   if (FrameDelayUS == 0)
716   {
717     GetSpeedDescriptionFPS = "Fastest possible";
718     return GetSpeedDescriptionFPS;
719   }
720
721   if (FrameDelayUS < 0)
722   {
723     GetSpeedDescriptionFPS = "! display (even faster)";
724     return GetSpeedDescriptionFPS;
725   }
726
727   FPS = 1000000 / FrameDelayUS;
728   GetSpeedDescriptionFPS = CAT(INT_TO_STR(FPS), " fps");
729   if (35 == FPS)
730     GetSpeedDescriptionFPS = CAT(GetSpeedDescriptionFPS, "(Default)");
731
732   return GetSpeedDescriptionFPS;
733 }
734
735 static int InitSpeeds()
736 {
737   static int InitSpeeds;
738
739   SpeedsByDelayUS[1] = -1;  // no display
740   SpeedsByDelayUS[2] = 0; // fastest possible
741   SpeedsByDelayUS[3] = 1000000 / 700; // 700 fps
742   SpeedsByDelayUS[4] = 1000000 / 500; // 500 fps
743   SpeedsByDelayUS[5] = 1000000 / 350; // 350 fps
744   SpeedsByDelayUS[6] = 1000000 / 250; // 250 fps
745   SpeedsByDelayUS[7] = 1000000 / 200; // etc.
746   SpeedsByDelayUS[8] = 1000000 / 150;
747   SpeedsByDelayUS[9] = 1000000 / 100;
748   SpeedsByDelayUS[10] = 1000000 / 70;
749   SpeedsByDelayUS[11] = 1000000 / 50;
750   SpeedsByDelayUS[12] = 1000000 / 35; // default
751   SpeedsByDelayUS[13] = 1000000 / 25;
752   SpeedsByDelayUS[14] = 1000000 / 20;
753   SpeedsByDelayUS[15] = 1000000 / 10;
754   SpeedsByDelayUS[16] = 1000000 / 5;
755   SpeedsByDelayUS[17] = 1000000 / 1;
756
757   return InitSpeeds;
758 }
759
760 static int GetSpeedIndex(long DelayUS)
761 {
762   static int GetSpeedIndex;
763
764   int i;
765   long Diff, MinDiff;
766   int MinIdx;
767
768   MinIdx = DefaultSpeedIndex;
769   MinDiff = 1000000;
770   for (i = 1; i <= nSpeedCount; i++)
771   {
772     Diff = Abs(DelayUS - SpeedsByDelayUS[i]);
773     if (Diff < MinDiff)
774     {
775       MinDiff = Diff;
776       MinIdx = i;
777     }
778   }
779
780   GetSpeedIndex = MinIdx;
781
782   return GetSpeedIndex;
783 }
784
785 static long Get_LastOpenFilter()
786 {
787   static long LastOpenFilter;
788
789   SettingsObject s;
790
791   LastOpenFilter = s.Read("LastOpenFilter", 1);
792
793   return LastOpenFilter;
794 }
795
796 static void Let_LastOpenFilter(long NewVal)
797 {
798   SettingsObject s;
799
800   SettingsObject_Save("LastOpenFilter", NewVal);
801 }
802
803 static long Get_LastSaveFilter()
804 {
805   static long LastSaveFilter;
806
807   SettingsObject s;
808
809   LastSaveFilter = s.Read("LastSaveFilter", 1);
810
811   return LastSaveFilter;
812 }
813
814 static void Let_LastSaveFilter(long NewVal)
815 {
816   SettingsObject s;
817
818   SettingsObject_Save("LastSaveFilter", NewVal);
819 }
820
821 #endif
822
823 static void CountDown(long HalfSeconds, int bDisplayBar)
824 {
825
826 #if 0
827
828   long i;
829   int k;
830   long dT, Delta;
831   long LeftPos, TopPos, RightPos, MaxWidth; // , MaxHeight&
832
833   dT = HalfSeconds * 500;
834   Delta = dT / 200;
835   LeftPos = cmbFile.left;
836   TopPos = cmbFile.top - shpProgress.Height - cmbFile.top / 8;
837   RightPos = lblFrameCount.left + lblFrameCount.Width;
838   MaxWidth = RightPos - LeftPos;
839   // MaxHeight = lblFrameCount.Top - TopPos + lblFrameCount.Height + 4
840   if (bDisplayBar)
841   {
842     shpProgress.Move(LeftPos, TopPos, 0); // , MaxHeight
843     shpProgress.Visible = True;
844   }
845
846   for (i = 1; i <= 200; i++)
847   {
848     // lblFrameCount = i
849     if (bDisplayBar)
850     {
851       if (i < 101)
852       {
853         shpProgress.Width = MaxWidth * i / 100;
854       }
855       else
856       {
857         k = MaxWidth * (i - 100) / 100;
858         shpProgress.Move(k, TopPos, RightPos - k);
859       }
860     }
861
862     T.DelayMS(Delta, False);
863   }
864
865   shpProgress.Visible = False;
866   // lblFrameCount = 0
867
868 #endif
869
870 }
871
872 #if 0
873
874 static char *GetValidTempPath()
875 {
876   static char *GetValidTempPath;
877
878   char *TP;
879   long nSize, L;
880
881   GetValidTempPath = "";
882   nSize = 255;
883   TP = String(nSize, Chr(32));
884   L = GetTempPath(nSize, TP);
885   if (nSize < L)
886   {
887     // buffer was too small, retry with a properly sized buffer:
888     nSize = L;
889     TP = String(nSize, Chr(32));
890     L = GetTempPath(nSize, TP);
891   }
892
893   TP = SlashLess(left(TP, L));
894   if ((0 == L) || (! IsDir(TP)))
895   {
896     // no valid temp path can be retrieved from the system --> create our own
897     TP = CAT(WithSlash(App.Path), "Temp");
898     if (! IsDir(TP))
899     {
900
901       // --- On Error Resume Next
902       MkDir(TP);
903       if (! IS_NOTHING(&Err, sizeof(Err)))
904       {
905         MESSAGE_BOX("an error occured"); // MsgBox "cannot create directory for temporary files " & TP, vbCritical, "MegaPlex - Error";
906         return GetValidTempPath;
907       }
908
909       // --- On Error GoTo 0
910
911     }
912   }
913
914   if (IsDir(TP))
915     GetValidTempPath = TP;
916
917   return GetValidTempPath;
918 }
919
920 static char *GetMyTempFileName()
921 {
922   static char *GetMyTempFileName;
923
924   char *T;
925
926   (char *)T = Hex(hWnd);
927   while (Len(T) < 8)
928   {
929     T = CAT("0", T);
930   }
931
932   GetMyTempFileName = CAT("tmp0x", CAT((char *)T, ".mpx"));
933
934   return GetMyTempFileName;
935 }
936
937 static long GetHwndFromTempFileName(char *TmpFile)
938 {
939   static long GetHwndFromTempFileName;
940
941   char *FN;
942   long LP;
943   int L;
944   char *NumString;
945
946   GetHwndFromTempFileName = 0;
947   FN = StripFileName(TmpFile);
948   LP = Len("tmp0x");
949   L = Len(TmpFile);
950   if (LP < L)
951     return GetHwndFromTempFileName;
952
953   L = L - LP;
954   NumString = right(FN, L - LP);
955   if (8 < L)
956     NumString = left(NumString, 8);
957
958   NumString = CAT("&H", NumString);
959   GetHwndFromTempFileName = Val(NumString);
960
961   return GetHwndFromTempFileName;
962 }
963
964 static void CleanTempDir(char *TmpDir)
965 {
966   char *FN, *MFN;
967
968   MFN = GetMyTempFileName();
969   MayKill(CAT(WithSlash(TmpDir), MFN));
970   FN = Dir(CAT(WithSlash(TmpDir), "tmp0x*.mpx"));
971   while (FN != "")
972   {
973     if (STRING_IS_LIKE(FN, "tmp0x*.mpx"))
974     {
975       if (! InstanceStillRunning(FN))
976         MayKill(CAT(WithSlash(TmpDir), FN));
977     }
978
979     FN = Dir_Without_Args();
980   }
981 }
982
983 static boolean InstanceStillRunning(char *TmpFile)
984 {
985   static boolean InstanceStillRunning;
986
987   long OtherHwnd, nSize, L;
988   char *Cap;
989
990   InstanceStillRunning = False;
991   OtherHwnd = GetHwndFromTempFileName(TmpFile);
992   nSize = 255;
993   Cap = String(nSize, Chr(32));
994   L = GetWindowText(OtherHwnd, Cap, nSize);
995   if ((L == 0) || (nSize < L))
996     return InstanceStillRunning;
997
998   if (STRING_IS_LIKE(Cap, CAT(AppTitle, "*")))
999     InstanceStillRunning = True;
1000
1001   return InstanceStillRunning;
1002 }
1003
1004 #endif
1005
1006 void DisplayLevel()
1007 {
1008   int X, Y;
1009
1010 #if 0
1011   printf("::: MainForm.c: DisplayLevel(): %d, %d, %d\n",
1012          Loaded, LevelLoaded, bPlaying);
1013 #endif
1014
1015   if (! Loaded)
1016     return;
1017
1018   if (! LevelLoaded)
1019     return;
1020
1021 #if 1
1022   SetDisplayRegion();
1023 #endif
1024
1025   DrawFrame(0);
1026
1027 #if 0
1028   if (! menBorder.Checked)
1029     DrawFrame(1);
1030 #endif
1031
1032   if (bPlaying)
1033   {
1034 #if 0
1035     printf("::: MainForm.c: DisplayLevel(): [%ld, %ld, %ld, %ld] [%d, %d]...\n",
1036            DisplayMinX, DisplayMinY, DisplayMaxX, DisplayMaxY,
1037            FieldWidth, FieldHeight);
1038 #endif
1039
1040     for (Y = DisplayMinY; Y <= DisplayMaxY; Y++)
1041     {
1042       for (X = DisplayMinX; X <= DisplayMaxX; X++)
1043       {
1044         DrawFieldNoAnimated(X, Y);
1045       }
1046     }
1047
1048     for (Y = DisplayMinY; Y <= DisplayMaxY; Y++)
1049     {
1050       for (X = DisplayMinX; X <= DisplayMaxX; X++)
1051       {
1052         DrawFieldAnimated(X, Y);
1053       }
1054     }
1055
1056   }
1057   else
1058   {
1059     for (Y = DisplayMinY; Y <= DisplayMaxY; Y++)
1060     {
1061       for (X = DisplayMinX; X <= DisplayMaxX; X++)
1062       {
1063         DrawField(X, Y);
1064       }
1065     }
1066   }
1067 }
1068
1069 #if 0
1070
1071 static void cmbFile_Click()
1072 {
1073   CurPath = CAT(StripDir(OrigPath), CAT("/", cmbFile.List(cmbFile.ListIndex)));
1074   OrigPath = CurPath;
1075   FillLevelList(CurPath, LevelNumber);
1076   if (STRING_IS_LIKE(OrigPath, "*.mpx") || STRING_IS_LIKE(OrigPath, "*.sp"))
1077   {
1078     menSave.Enabled = True;
1079   }
1080   else
1081   {
1082     menSave.Enabled = False;
1083   }
1084 }
1085
1086 static void cmbFile_KeyDown(int KeyCode, int Shift)
1087 {
1088   picPane_KeyDown(KeyCode, Shift);
1089 }
1090
1091 static void cmbFile_KeyUp(int KeyCode, int Shift)
1092 {
1093   picPane_KeyUp(KeyCode, Shift);
1094 }
1095
1096 static int GetFileNameToSave()
1097 {
1098   static int GetFileNameToSave;
1099
1100   char *T;
1101
1102   (char *)T = StripFileName(OrigPath);
1103   if (STRING_IS_LIKE(T, "*.dat") || STRING_IS_LIKE(T, "*.d##"))
1104   {
1105     T = "Level" & Format(LevelNumber, "#000");
1106   }
1107
1108   GetFileNameToSave = T;
1109
1110   return GetFileNameToSave;
1111 }
1112
1113 static void cmbLevel_Click()
1114 {
1115   long InfoCount;
1116   boolean Oldflag;
1117   int Msg;
1118   static long LastIndex = 0;
1119   static boolean bBlock = False;
1120
1121   if (bBlock)
1122     return;
1123
1124   // //////////////////////////////////////////////////////////////////
1125   if (ModifiedFlag)
1126   {
1127     VbMsgBoxResult Res;
1128
1129     Msg = "Save changes to " & GetFileNameToSave() & " ?";
1130     Res = MsgBox(Msg, vbYesNoCancel, AppTitle & " - close level");
1131     if (Res == vbCancel) // fallback
1132     {
1133       bBlock = True;
1134
1135       // --- On Error Resume Next
1136       cmbLevel.ListIndex = LastIndex;
1137       // --- On Error GoTo 0
1138
1139       bBlock = False;
1140       Debug.Assert cmbLevel.ListIndex = LastIndex;
1141       return;
1142     }
1143
1144     if (Res == vbYes)
1145     {
1146       // Dim oldCurPath$
1147       // oldCurPath = CurPath
1148       if (FileExists(OrigPath) && menSave.Enabled)
1149       {
1150         menSave_Click();
1151       }
1152       else
1153       {
1154         if (! SaveAs()) // fallback
1155         {
1156           bBlock = True;
1157
1158           // --- On Error Resume Next
1159           cmbLevel.ListIndex = LastIndex;
1160           // --- On Error GoTo 0
1161
1162           bBlock = False;
1163           Debug.Assert cmbLevel.ListIndex = LastIndex;
1164           return;
1165         }
1166       }
1167
1168       // CurPath = oldCurPath
1169     }
1170
1171     Let_ModifiedFlag(False);
1172     CurPath = OrigPath;
1173   }
1174
1175   // //////////////////////////////////////////////////////////////////
1176   {
1177     LevelNumber = cmbLevel.ListIndex + 1;
1178     DemoFlag = False;
1179     if (Loaded)
1180     {
1181       Oldflag = NoDisplayFlag;
1182       NoDisplayFlag = False;
1183       subFetchAndInitLevel();
1184       if ((0 < SignatureDelay) && ! (WindowState == vbMinimized))
1185       {
1186         Msg = LInfo.LevelTitle & vbNewLine & "(" & FieldWidth & " x " & FieldHeight & ")";
1187         if (DemoAvailable && bSignatureAvailable)
1188           Msg = Msg & vbNewLine & vbNewLine & gSignature;
1189
1190         SignatureForm.Signature = Msg;
1191         SignatureForm.DelayMS = SignatureDelay;
1192         int X, Y;
1193
1194         X = left + (Width - SignatureForm.Width) / 2;
1195         Y = top + (Height - SignatureForm.Height) / 2;
1196         SignatureForm.Move X, Y;
1197         SignatureForm.Show vbModeless, Me;
1198         Me.SetFocus;
1199       }
1200
1201       lblStatus = "MegaPlex";
1202       lblFrameCount = GetTotalFramesOfDemo();
1203       if (EditFlag)
1204         EdAll();
1205
1206       ReStretch(Stretch);
1207       // picPane_Paint
1208       Stage.Blt();
1209       NoDisplayFlag = Oldflag;
1210       LastIndex = cmbLevel.ListIndex;
1211     }
1212
1213   }
1214   menPlayDemo.Enabled = DemoAvailable;
1215   cmdPlayDemo.Enabled = DemoAvailable;
1216 }
1217
1218 static void cmblevel_KeyDown(int KeyCode, int Shift)
1219 {
1220   if (GameLoopRunning != 0)
1221     return;
1222
1223   switch (KeyCode)
1224   {
1225     case vbKeySpace:
1226       if (menPlay.Enabled == True)
1227         menPlay_Click();
1228
1229       break;
1230
1231     default:
1232       picPane_KeyDown(KeyCode, Shift);
1233       break;
1234   }
1235 }
1236
1237 static void cmbLevel_KeyUp(int KeyCode, int Shift)
1238 {
1239   picPane_KeyUp(KeyCode, Shift);
1240 }
1241
1242 static void cmdPause_Click()
1243 {
1244   menPause_Click();
1245 }
1246
1247 static void cmdPause_MouseUp(int Button, int Shift, float X, float Y)
1248 {
1249   FocusTim.Enabled = True;
1250 }
1251
1252 static void cmdPlay_Click()
1253 {
1254   if (menPlay.Enabled)
1255     menPlay_Click();
1256 }
1257
1258 static void cmdPlay_MouseUp(int Button, int Shift, float X, float Y)
1259 {
1260   FocusTim.Enabled = True;
1261 }
1262
1263 static void cmdPlayAll_Click()
1264 {
1265   menPlayAll_Click();
1266 }
1267
1268 static void cmdPlayAll_MouseUp(int Button, int Shift, float X, float Y)
1269 {
1270   FocusTim.Enabled = True;
1271 }
1272
1273 static void cmdPlayDemo_Click()
1274 {
1275   menPlayDemo_Click();
1276 }
1277
1278 static void cmdPlayDemo_MouseUp(int Button, int Shift, float X, float Y)
1279 {
1280   FocusTim.Enabled = True;
1281 }
1282
1283 static void cmdRecordDemo_Click()
1284 {
1285   if (menRec.Enabled)
1286     menRec_Click();
1287 }
1288
1289 static void cmdRecordDemo_MouseUp(int Button, int Shift, float X, float Y)
1290 {
1291   FocusTim.Enabled = True;
1292 }
1293
1294 static void cmdStop_Click()
1295 {
1296   if (menStop.Enabled)
1297     menStop_Click();
1298 }
1299
1300 static void cmdStop_MouseUp(int Button, int Shift, float X, float Y)
1301 {
1302   FocusTim.Enabled = True;
1303 }
1304
1305 static void FocusTim_Timer()
1306 {
1307   FocusTim.Enabled = False;
1308
1309   // --- On Error Resume Next
1310   picPane.SetFocus;
1311 }
1312
1313 static void Form_KeyDown(int KeyCode, int Shift)
1314 {
1315   picPane_KeyDown(KeyCode, Shift);
1316 }
1317
1318 static void Form_KeyUp(int KeyCode, int Shift)
1319 {
1320   picPane_KeyUp(KeyCode, Shift);
1321 }
1322
1323 #endif
1324
1325 void Form_Load()
1326 {
1327 #if 0
1328
1329   long i;
1330   SettingsObject s;
1331
1332 #endif
1333
1334   Loaded = False;
1335   DemoFlag = 0;
1336   PanelSeq = 0;
1337   EditFlag = False;
1338   EditMode = edMove;
1339   // FMark = New MarkerObject; // (handle this later, if needed)
1340
1341   InitGlobals();
1342
1343 #if 0
1344
1345   LoadMenus();
1346
1347   TmpPath = GetValidTempPath();
1348   if (TmpPath == "")
1349     exit(-1);
1350
1351   CleanTempDir(TmpPath);
1352   TmpPath = CAT(WithSlash(TmpPath), GetMyTempFileName());
1353   GetSettings();
1354   ShowPanel = 1;
1355
1356   InitDirectX(hWnd, picPane.hWnd);
1357
1358   //  AllowRedDiskCheat = 1
1359   MpxBmp = CAT(App.Path, "/mpx.bmp");
1360   // // Set NormalSprites = New DDSpriteBuffer // (handle this later, if needed)
1361   // NormalSprites.CreateFromFile MPXBMP, 16, 16
1362
1363   Field = REDIM_2D(sizeof(int), 0, 2 + 1 - 1, 0, 2 + 1 - 1);
1364
1365   picViewPort.ScaleMode = vbPixels;
1366
1367 #endif
1368
1369   PauseMode = 0;
1370   //  BaseWidth = 16
1371
1372   menBorder_Click();
1373
1374   Loaded = True;
1375
1376   ReStretch(Stretch);
1377
1378 #if 0
1379
1380   LoadKeyIndicators();
1381
1382   Show();
1383
1384   FillFileList(CurPath);
1385   if (s.Read("ShowSplash", True))
1386   {
1387     // frmSplash.EnableTimer
1388     frmSplash.Show vbModal, Me;
1389   }
1390
1391 #endif
1392 }
1393
1394 #if 0
1395
1396 static void FillLevelList(char *Path, int LevelIndex)
1397 {
1398   long FNum, LevLen, i, iMax;
1399   char *TFile;
1400
1401   cmbLevel.Clear;
1402   if (! FileExists(Path))
1403     return;
1404
1405   if ((STRING_IS_LIKE(Path, "*.D??")) || (STRING_IS_LIKE(Path, "*.sp")))
1406   {
1407     FNum = FreeFile();
1408     LevLen = 1536;
1409     FNum = fopen(Path, "rb");
1410     {
1411       i = 0;
1412       FILE_GET(FNum, (long)1441 + i * LevLen, &LInfo, sizeof(LInfo));
1413       cmbLevel.AddItem Format(i + 1, "#000") & "   " & LInfo.LevelTitle, i;
1414       if (STRING_IS_LIKE(Path, "*.D??"))
1415       {
1416         while (!(EOF(FNum)))
1417         {
1418           i = i + 1;
1419           FILE_GET(FNum, (long)1441 + i * LevLen, &LInfo, sizeof(LInfo));
1420           if (EOF(FNum))
1421             break;
1422
1423           cmbLevel.AddItem Format(i + 1, "#000") & "   " & LInfo.LevelTitle, i;
1424         }
1425       }
1426
1427       if (LevelIndex <= i && 0 < LevelIndex)
1428         i = LevelIndex - 1;
1429       else
1430         i = 0;
1431
1432       cmbLevel.ListIndex = i;
1433     }
1434     fclose(FNum);
1435   }
1436   else if (STRING_IS_LIKE(Path, "*.mpx"))
1437   {
1438     FNum = FreeFile();
1439     LevLen = 1536;
1440     FNum = fopen(Path, "rb");
1441     {
1442       i = 0;
1443       if (MpxOpen(Path))
1444       {
1445         for (i = 1; i <= LevelCount; i++)
1446         {
1447           if (! MpxLoadLInfo(CInt(i)))
1448             break;
1449
1450           cmbLevel.AddItem Format(i, "#000") & "   " & LInfo.LevelTitle, i - 1;
1451         }
1452
1453         MpxClose();
1454       }
1455
1456       if (LevelIndex < i && 0 < LevelIndex)
1457         i = LevelIndex - 1;
1458       else
1459         i = 0;
1460
1461       if (i < cmbLevel.ListCount)
1462         cmbLevel.ListIndex = i;
1463
1464     }
1465     fclose(FNum);
1466   }
1467 }
1468
1469 static void FillFileList(char *Path)
1470 {
1471   long FNum, LevLen, i;
1472   int nDemoCount;
1473   char *TFile, *TPath, *OFile;
1474
1475   cmbFile.Clear;
1476   i = 0;
1477   nDemoCount = 0;
1478   TPath = WithSlash(StripDir(Path));
1479   OFile = StripFileName(Path);
1480   TFile = Dir(TPath & "*.D??");
1481   while (TFile != "")
1482   {
1483     if (FileLen(TPath & TFile) == 170496)
1484     {
1485       cmbFile.AddItem TFile;
1486     }
1487
1488     TFile = Dir;
1489   }
1490
1491   TFile = Dir(TPath & "*.SP");
1492   while (TFile != "")
1493   {
1494     nDemoCount = nDemoCount + 1;
1495     cmbFile.AddItem TFile;
1496     TFile = Dir;
1497   }
1498
1499   TFile = Dir(TPath & "*.mpx");
1500   while (TFile != "")
1501   {
1502     nDemoCount = nDemoCount + 1;
1503     cmbFile.AddItem TFile;
1504     TFile = Dir;
1505   }
1506
1507   i = cmbFile.ListCount - 1;
1508   if (0 < cmbFile.ListCount)
1509   {
1510     do
1511     {
1512       if ((cmbFile.List(i) Like OFile) || i == 0)
1513         break;
1514
1515       i = i - 1;
1516     }
1517     while (!(i < 1));
1518
1519     cmbFile.ListIndex = i;
1520   }
1521
1522   DemosAvailable = (1 < nDemoCount);
1523   menPlayAll.Enabled = DemosAvailable;
1524   cmdPlayAll.Enabled = DemosAvailable;
1525 }
1526
1527 static void LoadMenus()
1528 {
1529   long i;
1530
1531   // speeds
1532   menFaster.Enabled = False;
1533   menSlower.Enabled = False;
1534   InitSpeeds();
1535   for (i = 1; i <= nSpeedCount; i++)
1536   {
1537     if (1 < i)
1538     {
1539       Load menPlaySpeed(i);
1540       Load menDemoSpeed(i);
1541     }
1542
1543     menPlaySpeed(i).Caption = GetSpeedDescriptionFPS(SpeedsByDelayUS[i]);
1544     menDemoSpeed(i).Caption = GetSpeedDescriptionFPS(SpeedsByDelayUS[i]);
1545   }
1546
1547   // zoom
1548   menStretch(1).Caption = Format(0.25, "#0.00") & ";
1549   1";
1550   if (Stretch == 0.25)
1551     menStretch(1).Checked = True;
1552
1553   for (i = 2; i <= 20; i++)
1554   {
1555     Load menStretch(i);
1556     menStretch(i).Caption = Format(0.25 * i, "#0.00") & ";
1557     1";
1558     menStretch(i).Checked = ((i * 0.25) == Stretch);
1559   }
1560
1561   menSp.Enabled = False;
1562 }
1563
1564 //
1565 // Function DisplayShift&()
1566 // Dim X&, Y&, A&, B&, iX&, iiX&, LD&
1567 // Dim Sprite&
1568 //  DisplayShift = 0
1569 //    For A = 0 To picPane.ScaleWidth
1570 //      For Y = DisplayMinY To DisplayMaxY
1571 //        For X = DisplayMinX To DisplayMaxX
1572 //          iX = StretchWidth * X + A
1573 //          Sprite = Field(X, Y).SpritePos
1574 //          If picPane.ScaleWidth < (iX + 1) Then
1575 //            iX = iX - picPane.ScaleWidth
1576 //          Else
1577 //            If picPane.ScaleWidth < (iX + 1 + BaseWidth) Then
1578 //              iiX = iX - picPane.ScaleWidth
1579 //              Sprites.BitBltSprite picPane.hdc, iiX, StretchWidth * Y, Sprite
1580 //            End If
1581 //          End If
1582 //          Sprites.BitBltSprite picPane.hdc, iX, StretchWidth * Y, Sprite
1583 //        Next X
1584 //      Next Y
1585 //      DisplayShift = DisplayShift + 1
1586 //      'DoEvents
1587 //    Next A
1588 // End Function
1589
1590 static void Form_Paint()
1591 {
1592   // Debug.Print "Form_Paint()"
1593 }
1594
1595 static void Form_Resize()
1596 {
1597   long Space, NW, NH;
1598   int Tmp;
1599
1600   if (WindowState == vbMinimized || ! Loaded)
1601     return;
1602
1603   Space = Panel.left;
1604   //  NW = ScaleWidth - 2 * Space: If NW < 0 Then NW = 0
1605   //  NH = ScaleHeight - 3 * Space - cmbLevel.Height: If NH < 0 Then NH = 0
1606   //  picViewPort.Move Space, Space, NW, NH
1607   Tmp = (ShowPanel != 0 ? ScaleHeight - Panel.Height : ScaleHeight);
1608   if (Tmp < 0)
1609     Tmp = 0;
1610
1611   picViewPort.Move 0, 0, ScaleWidth, Tmp;
1612   //  Tmp = 2 * Space + picViewPort.Height
1613   Panel.top = Tmp;
1614   Panel.left = (ScaleWidth - Panel.Width) / 2;
1615   //  'cmdNormal.Top = 2 * Space + picViewPort.Height
1616   //  cmbLevel.Top = Tmp
1617   //  lblRedDiskCount.Top = Tmp
1618   //  lblInfoCount.Top = Tmp
1619   //  picKeys.Top = Tmp
1620   //  lblFrameCount.Top = Tmp
1621   //  cmdPlayAll.Top = Tmp
1622 }
1623
1624 #endif
1625
1626 static void DrawFrame(int Delta)
1627 {
1628   int i, LX, tY, RX, BY;
1629
1630   LX = -1 + Delta;
1631   tY = -1 + Delta;
1632   RX = FieldWidth - Delta;
1633   BY = FieldHeight - Delta;
1634   DrawSprite(LX, tY, posFrameCorner);
1635   DrawSprite(LX, BY, posFrameCorner);
1636   DrawSprite(RX, tY, posFrameCorner);
1637   DrawSprite(RX, BY, posFrameCorner);
1638   for (i = LX + 1; i <= RX - 1; i++)
1639   {
1640     DrawSprite(i, tY, posFrameHorizontal);
1641     DrawSprite(i, BY, posFrameHorizontal);
1642   }
1643
1644   for (i = tY + 1; i <= BY - 1; i++)
1645   {
1646     DrawSprite(LX, i, posFrameVertical);
1647     DrawSprite(RX, i, posFrameVertical);
1648   }
1649 }
1650
1651 static void RestoreFrame()
1652 {
1653   int i, LX, tY, RX, BY;
1654
1655   LX = 0;
1656   tY = 0;
1657   RX = FieldWidth - 1;
1658   BY = FieldHeight - 1;
1659   for (i = LX; i <= RX; i++)
1660   {
1661     DrawField(i, tY);
1662     DrawField(i, BY);
1663   }
1664
1665   for (i = tY + 1; i <= BY - 1; i++)
1666   {
1667     DrawField(LX, i);
1668     DrawField(RX, i);
1669   }
1670 }
1671
1672 #if 0
1673
1674 static void Form_Unload(int Cancel)
1675 {
1676   EndFlag = True;
1677   ExitToMenuFlag = 1;
1678   if (cmdPlayAll.STRING_IS_LIKE(Caption, "Quit*"))
1679   {
1680     cmdPlayAll_Click();
1681   }
1682
1683   if (menEdit.Checked)
1684     menEdit_Click();
1685
1686   if (ModifiedFlag)
1687   {
1688     char *Msg;
1689     VbMsgBoxResult Res;
1690
1691     Msg = "Save changes to " & GetFileNameToSave() & " ?";
1692     Res = MsgBox(Msg, vbYesNoCancel, AppTitle & " - closing");
1693     if (Res == vbCancel)
1694     {
1695       Cancel = -1;
1696       return;
1697     }
1698
1699     if (Res == vbYes)
1700     {
1701       if (FileExists(OrigPath) && menSave.Enabled)
1702       {
1703         menSave_Click();
1704       }
1705       else
1706       {
1707         menSaveAs_Click();
1708       }
1709     }
1710   }
1711
1712   if (FileExists(TmpPath) || ModifiedFlag)
1713   {
1714     MayKill(TmpPath);
1715     CurPath = OrigPath;
1716   }
1717
1718   ReleaseDirectDraw();
1719   SaveSettings();
1720   End;
1721 }
1722
1723 static void fpsTim_Timer()
1724 {
1725   currency TickDiff;
1726   static int count5 = 0;
1727
1728   count5 = count5 + 1;
1729   if (4 < count5)
1730   {
1731     TickDiff = T.TickDiffUS(LastTick);
1732     lblFps.Caption = CLng(Round((1000000 * (TimerVar - LastFrame)) / (TickDiff), 0));
1733     LastFrame = TimerVar;
1734     LastTick = T.TickNow();
1735     count5 = 0;
1736   }
1737
1738   // If NoDisplayFlag Then lblFrameCount = TimerVar
1739   lblFrameCount = TimerVar;
1740 }
1741
1742 static void menAbout_Click()
1743 {
1744   frmSplash.Show vbModal, Me;
1745 }
1746
1747 static void menAutoScroll_Click()
1748 {
1749   {
1750     menAutoScroll.Checked = ! menAutoScroll.Checked;
1751     AutoScrollFlag = menAutoScroll.Checked;
1752   }
1753 }
1754
1755 #endif
1756
1757 static void menBorder_Click()
1758 {
1759   if (menBorder.Checked)
1760   {
1761     menBorder.Checked = False;
1762     DisplayMinX = 1;
1763     DisplayMaxX = FieldWidth - 2;
1764     DisplayWidth = FieldWidth;
1765     DisplayMinY = 1;
1766     DisplayMaxY = FieldHeight - 2;
1767     DisplayHeight = FieldHeight;
1768
1769     if (Loaded && LevelLoaded)
1770       DrawFrame(1);
1771
1772   }
1773   else
1774   {
1775     menBorder.Checked = True;
1776     DisplayMinX = 0;
1777     DisplayMaxX = FieldWidth - 1;
1778     DisplayWidth = FieldWidth + 2;
1779     DisplayMinY = 0;
1780     DisplayMaxY = FieldHeight - 1;
1781     DisplayHeight = FieldHeight + 2;
1782
1783     if (Loaded && LevelLoaded)
1784       RestoreFrame();
1785   }
1786
1787   ReStretch(Stretch);
1788   // DisplayLevel True
1789 }
1790
1791 void SetDisplayRegion()
1792 {
1793   if (! menBorder.Checked)
1794   {
1795     DisplayMinX = 1;
1796     DisplayMaxX = FieldWidth - 2;
1797     DisplayWidth = FieldWidth;
1798     DisplayMinY = 1;
1799     DisplayMaxY = FieldHeight - 2;
1800     DisplayHeight = FieldHeight;
1801
1802     if (LevelLoaded)
1803       DrawFrame(1);
1804
1805   }
1806   else
1807   {
1808     DisplayMinX = 0;
1809     DisplayMaxX = FieldWidth - 1;
1810     DisplayWidth = FieldWidth + 2;
1811     DisplayMinY = 0;
1812     DisplayMaxY = FieldHeight - 1;
1813     DisplayHeight = FieldHeight + 2;
1814
1815     if (LevelLoaded)
1816       RestoreFrame();
1817   }
1818 }
1819
1820 #if 0
1821
1822 static void menCopy_Click()
1823 {
1824   FMark.Copy;
1825 }
1826
1827 void menEdit_Click()
1828 {
1829   long L;
1830
1831   if (menEdit.Checked)
1832   {
1833     menEdit.Checked = False;
1834     // leave edit mode
1835     if (EditFlag)
1836       Unload ToolBox;
1837
1838     EditFlag = False;
1839     UnEdAll();
1840     FMark.ShowMarker False;
1841     picViewPort.MousePointer = 0;
1842     if (ModifiedFlag)
1843     {
1844       if (! STRING_IS_LIKE(CurPath, TmpPath))
1845       {
1846         OrigPath = CurPath;
1847         CurPath = TmpPath;
1848       }
1849
1850       SaveMPX(TmpPath);
1851     }
1852
1853     DisplayLevel();
1854     Stage.Blt();
1855   }
1856   else
1857   {
1858     if (! LevelLoaded)
1859     {
1860       Beep();
1861       return;
1862     }
1863
1864     if (ModifiedFlag)
1865     {
1866       if (! STRING_IS_LIKE(CurPath, TmpPath))
1867       {
1868         OrigPath = CurPath;
1869         CurPath = TmpPath;
1870       }
1871
1872       SaveMPX(TmpPath);
1873     }
1874
1875     subFetchAndInitLevel();
1876     menEdit.Checked = True;
1877     // enter edit mode
1878     EditFlag = True;
1879     // ScaleMode = vbTwips
1880     ToolBox.Move (Width - ToolBox.Width) / 2, Height - ToolBox.Height;
1881     // ScaleMode = vbPixels
1882     //    L = GetWindowLong(ToolBox.hWnd, GWL_STYLE)
1883     //    L = L And (Not WS_POPUP)
1884     //    L = L Or WS_CHILD
1885     //    SetWindowLong ToolBox.hWnd, GWL_STYLE, L
1886     //    SetParent ToolBox.hWnd, hWnd
1887     ToolBox.Show vbModeless, Me;
1888     EdAll();
1889     DisplayLevel();
1890     Stage.Blt();
1891     FMark.ShowMarker True;
1892   }
1893 }
1894
1895 static void menEnOff_Click()
1896 {
1897   menEnOn.Checked = False;
1898   menEnOff.Checked = True;
1899   SpSaveMenu();
1900   SpLoadMenu();
1901 }
1902
1903 static void menEnOn_Click()
1904 {
1905   menEnOn.Checked = True;
1906   menEnOff.Checked = False;
1907   SpSaveMenu();
1908   SpLoadMenu();
1909 }
1910
1911 static void menExit_Click()
1912 {
1913   Unload Me;
1914 }
1915
1916 static void menFaster_Click()
1917 {
1918   int i;
1919
1920   if (! bPlaying)
1921   {
1922     Debug.Assert(False);
1923     return;
1924   }
1925
1926   if (DemoFlag != 0) // demoplayback
1927   {
1928     i = GetSpeedIndex(DeltaTDemo);
1929     i = i - 1;
1930     If i < 2 Then i = 2;
1931     menDemoSpeed_Click (i);
1932   }
1933   else
1934   {
1935     i = GetSpeedIndex(DeltaTPlay);
1936     i = i - 1;
1937     If i < 2 Then i = 2;
1938     menPlaySpeed_Click (i);
1939   }
1940 }
1941
1942 static void menSlower_Click()
1943 {
1944   int i;
1945
1946   if (! bPlaying)
1947   {
1948     Debug.Assert(False);
1949     return;
1950   }
1951
1952   if (DemoFlag != 0) // demoplayback
1953   {
1954     i = GetSpeedIndex(DeltaTDemo);
1955     i = i + 1;
1956     If nSpeedCount < i Then i = nSpeedCount;
1957     menDemoSpeed_Click (i);
1958   }
1959   else
1960   {
1961     i = GetSpeedIndex(DeltaTPlay);
1962     i = i + 1;
1963     If nSpeedCount < i Then i = nSpeedCount;
1964     menPlaySpeed_Click (i);
1965   }
1966 }
1967
1968 void menPlaySpeed_Click(int Index)
1969 {
1970   int i;
1971
1972   //  If NoDisplayFlag And (GameLoopRunning <> 0) Then
1973   //    NoDisplayFlag = False
1974   //    DisplayLevel
1975   //  End If
1976   //  NoDisplayFlag = False
1977   for (i = menPlaySpeed.LBound; i <= menPlaySpeed.UBound; i++)
1978   {
1979     {
1980       menPlaySpeed(i).Checked = (Index == i);
1981     }
1982   }
1983
1984   BlockingSpeed = False;
1985   DeltaTPlay = SpeedsByDelayUS[Index];
1986   UpdateDeltaT();
1987   //  If DeltaTPlay < 0 Then
1988   //    Stage.Blt
1989   //    DeltaT = 0
1990   //    NoDisplayFlag = True
1991   //  End If
1992 }
1993
1994 void menDemoSpeed_Click(int Index)
1995 {
1996   int i;
1997
1998   //  If NoDisplayFlag And (GameLoopRunning <> 0) Then
1999   //    NoDisplayFlag = False
2000   //    DisplayLevel
2001   //  End If
2002   NoDisplayFlag = False;
2003   for (i = menDemoSpeed.LBound; i <= menDemoSpeed.UBound; i++)
2004   {
2005     {
2006       menDemoSpeed(i).Checked = (Index == i);
2007     }
2008   }
2009
2010   BlockingSpeed = False;
2011   DeltaTDemo = SpeedsByDelayUS[Index];
2012   UpdateDeltaT();
2013   //  If DeltaTPlay < 0 Then
2014   //    Stage.Blt
2015   //    DeltaT = 0
2016   //    NoDisplayFlag = True
2017   //  End If
2018 }
2019
2020 static void UpdateDeltaT()
2021 {
2022   if (! bPlaying)
2023     return;
2024
2025   DeltaT = (DemoFlag != 0 ? DeltaTDemo : DeltaTPlay);
2026   if (DeltaT < 0)
2027   {
2028     Stage.Blt();
2029     DeltaT = 0;
2030     NoDisplayFlag = True;
2031   }
2032   else
2033   {
2034     if (NoDisplayFlag && GameLoopRunning != 0)
2035     {
2036       NoDisplayFlag = False;
2037       DisplayLevel();
2038     }
2039     else
2040     {
2041       NoDisplayFlag = False;
2042     }
2043   }
2044 }
2045
2046 static void menGravOff_Click()
2047 {
2048   menGravOn.Checked = False;
2049   menGravOff.Checked = True;
2050   SpSaveMenu();
2051   SpLoadMenu();
2052 }
2053
2054 static void menGravOn_Click()
2055 {
2056   menGravOn.Checked = True;
2057   menGravOff.Checked = False;
2058   SpSaveMenu();
2059   SpLoadMenu();
2060 }
2061
2062 static void menNew_Click()
2063 {
2064   NewForm.Show vbModal, Me;
2065   CreateLevel(FieldWidth, FieldHeight);
2066   ReStretch(Stretch);
2067 }
2068
2069 static void menNewStd_Click()
2070 {
2071   CreateLevel(60, 24);
2072   ReStretch(Stretch);
2073 }
2074
2075 static void menOpen_Click()
2076 {
2077   long LFilt;
2078
2079   {
2080     // cmDlg.DefaultExt = "sp"
2081
2082     /*
2083
2084     (prevent compiler warning here due to suspected use of trigraph)
2085
2086     cmDlg.Filter = "All Levels (*.DAT;*.D??;*.sp;*.mpx)|*.DAT;*.D??;*.sp;*.mpx|MegaPlex Levels (*.mpx)|*.mpx" & "|Supaplex Level Sets (*.DAT;*.D??)|*.DAT;*.D??|SpeedFix Demos (*.sp)|*.sp";
2087     */
2088
2089     LFilt = LastOpenFilter;
2090     cmDlg.FilterIndex = (0 < LFilt & LFilt < 5 ? LFilt : 1);
2091     if (FileExists(CurPath))
2092       cmDlg.InitDir = WithSlash(StripDir(CurPath));
2093
2094     cmDlg.flags = cdlOFNHideReadOnly | cdlOFNLongNames;
2095   }
2096
2097   // --- On Error GoTo menOpenEH
2098   cmDlg.ShowOpen;
2099   // --- On Error GoTo 0
2100
2101   LFilt = cmDlg.FilterIndex;
2102   LastOpenFilter = LFilt;
2103   CurPath = cmDlg.FileName;
2104   OrigPath = CurPath;
2105   FillFileList (CurPath);
2106
2107 menOpenEH:
2108 }
2109
2110 static void menOptions_Click()
2111 {
2112   OptionsForm oFrm;
2113
2114   oFrm.Show vbModal, Me;
2115   SaveSettings();
2116   picViewPort_Resize();
2117 }
2118
2119 static void menPanel_Click()
2120 {
2121   {
2122     PanelVisible = ! menPanel.Checked;
2123   }
2124 }
2125
2126 void Let_PanelVisible(boolean NewVal)
2127 {
2128   static boolean HidePanel = False;
2129
2130   if (HidePanel != NewVal)
2131     return;
2132
2133   HidePanel = ! NewVal;
2134   PanelTim.Enabled = True;
2135 }
2136
2137 static void DrawPauseLayer(long Layer)
2138 {
2139   DirectDrawPalette Pal;
2140   PALETTEENTRY *Val;
2141   long i;
2142
2143   // Dim X&, Y&
2144   //  For Y = 0 To bmpStage.Height Step BaseWidth
2145   //    For X = 0 To bmpStage.Width Step BaseWidth
2146   //      Pause.TransparentDraw bmpStageHDC, X, Y, Layer
2147   //    Next X
2148   //  Next Y
2149   //  With Stage.Surface
2150   //    Set Pal = .GetPalette
2151   //    for i=1 to pal.GetEntries(
2152   //  Stage.Surface.SetPalette
2153 }
2154
2155 static void menPaste_Click()
2156 {
2157   FMark.Paste;
2158   DisplayLevel();
2159   Stage.Blt();
2160 }
2161
2162 static void menPause_Click()
2163 {
2164   static StdPicture OldPic;
2165   static char *OldText = 0;
2166
2167   PauseMode = (PauseMode != 0 ? 0 : 1);
2168   if (PauseMode != 0)
2169   {
2170     if (IS_NOTHING(&OldPic, sizeof(OldPic)))
2171       OldPic = cmdPause.Picture;
2172
2173     cmdPause.Picture = cmdPause.DownPicture;
2174     OldText = lblStatus.Caption;
2175     lblStatus = "Paused ...";
2176   }
2177   else
2178   {
2179     cmdPause.Picture = OldPic;
2180     lblStatus.Caption = OldText;
2181   }
2182 }
2183
2184 static void menPlayAll_Click()
2185 {
2186   long iMin, iMax, i;
2187   int FNum;
2188   char *LogPath, *OutStr, *ReRecPath, *SPPath;
2189   boolean bEqual;
2190   static boolean QuitFlag = False;
2191
2192   if (cmdPlayAll.STRING_IS_LIKE(Caption, "Play) All Demos")
2193   {
2194     cmdPlayAll.Caption = "Quit All";
2195     menPlayAll.Caption = "Quit All";
2196     FocusTim.Enabled = True;
2197     QuitFlag = False;
2198     iMin = 0;
2199     iMax = cmbFile.ListCount - 1;
2200     LogPath = StripDir(CurPath) & "/Error.Log";
2201     if (Dir(LogPath) != "")
2202       Kill(LogPath);
2203
2204     for (i = iMin; i <= iMax; i++)
2205     {
2206       cmbFile.ListIndex = i;
2207       //      If CurPath Like "*.sp" Or CurPath Like "*.mpx" Then
2208       if (DemoAvailable)
2209       {
2210         SPPath = CurPath;
2211         ReRecPath = SPPath & ".ReRec";
2212         menPlayDemo_Click();
2213         // SaveSP ReRecPath
2214         // bEqual = FilesEqual(ReRecPath, SPPath)
2215         // If bEqual Then MayKill ReRecPath
2216         bEqual = True;
2217         OutStr = cmbFile.List(i) & " -> ";
2218         //
2219         if (Val(lblFrameCount) != GetTotalFramesOfDemo())
2220         {
2221           OutStr = OutStr & "Error in GetTotalFramesOfDemo()! ";
2222           Debug.Assert(False);
2223         }
2224
2225         //
2226         if ((LevelStatus == 1) && bEqual)
2227         {
2228           OutStr = OutStr & "Success";
2229         }
2230         else if (QuitFlag)
2231         {
2232           OutStr = OutStr & "All Demos (float)Canceled";
2233         }
2234         else
2235         {
2236           if (LevelStatus != 1)
2237           {
2238             OutStr = OutStr & "### Level Failed ### (TimerVar == " & TimerVar & ")";
2239           }
2240
2241           if (! bEqual)
2242           {
2243             OutStr = OutStr & "### ReRecording is binary different ###";
2244           }
2245         }
2246
2247         FNum = FreeFile();
2248         FNum = fopen(LogPath, "ab");
2249         Print #FNum, OutStr;
2250         fclose(FNum);
2251         if (QuitFlag)
2252           break;
2253       }
2254     }
2255
2256     cmdPlayAll.Caption = "Play All Demos";
2257     menPlayAll.Caption = "Play All Demos";
2258     SettingsObject Settings;
2259
2260     MySignature = Settings.Read("MySignature", "");
2261     FirstDemoByte = 0x81;
2262   }
2263   else
2264   {
2265     QuitFlag = True;
2266     if (menStop.Enabled)
2267       menStop_Click();
2268   }
2269 }
2270
2271 static void menRemSP_Click()
2272 {
2273   RemoveSP();
2274   SpLoadMenu();
2275 }
2276
2277 static void menRestoreBorder_Click()
2278 {
2279   RestoreBorder();
2280 }
2281
2282 static void menSave_Click()
2283 {
2284   if (! ModifiedFlag)
2285     return;
2286
2287   if (STRING_IS_LIKE(CurPath, TmpPath))
2288     CurPath = OrigPath;
2289
2290   if (STRING_IS_LIKE(CurPath, "") || STRING_IS_LIKE(CurPath, "*.dat"))
2291   {
2292     menSaveAs_Click();
2293     return;
2294   }
2295
2296   if (STRING_IS_LIKE(CurPath, "*.sp"))
2297   {
2298     menSaveAs_Click();
2299     return;
2300   }
2301
2302   if (! FileExists(CurPath) || STRING_IS_LIKE(CurPath, "Untitled"))
2303   {
2304     menSaveAs_Click();
2305     return;
2306   }
2307
2308   SaveMPX(CurPath);
2309   Let_ModifiedFlag(False);
2310 }
2311
2312 static void menSaveAs_Click()
2313 {
2314   if (SaveAs())
2315     FillFileList (CurPath);
2316 }
2317
2318 static boolean SaveAs()
2319 {
2320   static boolean SaveAs;
2321
2322   char *FN;
2323   SettingsObject s;
2324
2325   SaveAs = False;
2326   {
2327     // cmDlg.DefaultExt = "sp"
2328     cmDlg.Filter = "MegaPlex Level (*.mpx)|*.mpx|SpeedFix Demo (*.sp)|*.sp";
2329     cmDlg.FilterIndex = LastSaveFilter;
2330     // If OrigPath Like "*.sp" Then cmDlg.FilterIndex = 1 Else cmDlg.FilterIndex = 0
2331     if (FileExists(OrigPath))
2332     {
2333       cmDlg.InitDir = WithSlash(StripDir(OrigPath));
2334       cmDlg.InitDir = s.Read("LastSaveDir", cmDlg.InitDir);
2335       cmDlg.FileName = StripExtensionlessFileName(GetFileNameToSave());
2336     }
2337
2338     cmDlg.flags = cdlOFNHideReadOnly | cdlOFNLongNames;
2339   }
2340
2341   // --- On Error GoTo SaveAsEH
2342   cmDlg.ShowSave;
2343   // --- On Error GoTo 0
2344
2345   LastSaveFilter = cmDlg.FilterIndex;
2346   FN = cmDlg.FileName;
2347   SettingsObject_Save("LastSaveDir", WithSlash(StripDir(FN)));
2348   if (STRING_IS_LIKE(FN, "*.sp"))
2349   {
2350     SaveSP(FN);
2351   }
2352   else if (STRING_IS_LIKE(FN, "*.mpx"))
2353   {
2354     SaveMPX(FN);
2355   }
2356
2357   Let_ModifiedFlag(False);
2358   SaveAs = True;
2359
2360 SaveAsEH:
2361
2362   return SaveAs;
2363 }
2364
2365 static void menSelectAll_Click()
2366 {
2367   FMark.SetPoint1 0, 0;
2368   FMark.SetPoint2 FieldWidth - 1, FieldHeight - 1;
2369 }
2370
2371 static void menShowLInfo_Click()
2372 {
2373   char *Msg;
2374
2375   Msg = LInfo.LevelTitle & vbNewLine & "(" & FieldWidth & " x " & FieldHeight & ")";
2376   if (DemoAvailable && bSignatureAvailable)
2377     Msg = Msg & vbNewLine & vbNewLine & gSignature;
2378
2379   SignatureForm.Signature = Msg;
2380   SignatureForm.DelayMS = 5000;
2381   int X, Y;
2382
2383   X = left + (Width - SignatureForm.Width) / 2;
2384   Y = top + (Height - SignatureForm.Height) / 2;
2385   SignatureForm.Move X, Y;
2386   SignatureForm.Show vbModeless, Me;
2387   Me.SetFocus;
2388 }
2389
2390 static void menSoundFX_Click()
2391 {
2392   {
2393     menSoundFX.Checked = ! menSoundFX.Checked;
2394     FXOnFlag = (menSoundFX.Checked ? -1 : 0);
2395   }
2396 }
2397
2398 #endif
2399
2400 // static void menPlay_Click()
2401 void menPlay_Click()
2402 {
2403 #if 0
2404
2405   boolean OldEditFlag;
2406
2407   // Trace "MainForm", "--> menPlay_Click()"
2408   if (! LevelLoaded)
2409   {
2410     Beep();
2411     return;
2412   }
2413
2414   SignatureForm.DelayMS = 1;
2415   menPlay.Enabled = False;
2416   menPause.Enabled = True;
2417   menStop.Enabled = True;
2418   cmdPlay.Enabled = False;
2419   cmdPause.Enabled = True;
2420   cmdStop.Enabled = True;
2421   cmdPlayDemo.Enabled = False;
2422   menPlayDemo.Enabled = False;
2423   cmdRecordDemo.Enabled = False;
2424   menRec.Enabled = False;
2425   menFaster.Enabled = True;
2426   menSlower.Enabled = True;
2427   if (cmdPlayAll.STRING_IS_LIKE(Caption, "Play*"))
2428   {
2429     cmdPlayAll.Enabled = False;
2430     menPlayAll.Enabled = False;
2431   }
2432
2433   cmbFile.Enabled = False;
2434   cmbLevel.Enabled = False;
2435   OldEditFlag = EditFlag;
2436   if (EditFlag)
2437     menEdit_Click();
2438
2439   menEditMain.Enabled = False;
2440   if (DemoFlag == 0 && RecordDemoFlag == 0)
2441     lblStatus = "Playing";
2442
2443   lblFrameCount = 0;
2444
2445 #endif
2446
2447   LastFrame = 0;
2448
2449 #if 0
2450   LastTick = T.TickNow();
2451 #endif
2452
2453 #if 0
2454   fpsTim.Enabled = True;
2455 #endif
2456
2457   // DimPrimary 100
2458   bPlaying = True;
2459
2460 #if 0
2461   UpdateDeltaT();
2462 #endif
2463
2464 #if 0
2465   printf("::: MainForm.c: menPlay_Click(): subFetchAndInitLevelB(): ...\n");
2466 #endif
2467
2468   subFetchAndInitLevelB();
2469
2470 #if 0
2471   printf("::: MainForm.c: menPlay_Click(): subFetchAndInitLevelB(): done\n");
2472 #endif
2473
2474   ReStretch(Stretch);
2475
2476   // Trace "MainForm", "CountDown 1"
2477   CountDown(2, (0 == DemoFlag));
2478   // Trace "MainForm", "Call GoPlay"
2479
2480   GoPlay();
2481
2482   // Trace "MainForm", "GoPlay returned"
2483
2484 #if 0
2485
2486   if (LevelStatus == 1)
2487   {
2488     lblStatus = "(float)Success";
2489   }
2490   else
2491   {
2492     lblStatus = "Try (float)again";
2493   }
2494
2495 #endif
2496
2497   // Trace "MainForm", "CountDown 1"
2498   CountDown(1, False);
2499   RecordDemoFlag = 0;
2500
2501 #if 0
2502   ShowKey(0);
2503 #endif
2504
2505   bPlaying = False;
2506   // Trace "MainForm", "Call subFetchAndInitLevel"
2507
2508   subFetchAndInitLevel();
2509
2510   // Trace "MainForm", "subFetchAndInitLevel returned"
2511
2512 #if 0
2513   Stage.Blt();
2514 #endif
2515
2516 #if 0
2517
2518   menEditMain.Enabled = True;
2519   if (OldEditFlag)
2520     menEdit_Click();
2521
2522   // Trace "MainForm", "<-- menPlay_Click()"
2523
2524 #endif
2525 }
2526
2527 #if 1
2528
2529 // static void menPlayDemo_Click()
2530 void menPlayDemo_Click()
2531 {
2532   DemoFlag = 1;
2533   RecordDemoFlag = 0;
2534
2535 #if 0
2536   lblStatus = "Demo Playback";
2537 #endif
2538
2539   menPlay_Click();
2540
2541 #if 1
2542   return;       /* return after initialization phase */
2543 #endif
2544
2545 #if 0
2546   if (LevelStatus != 1)
2547     lblStatus = "Demo Failed";
2548 #endif
2549
2550   DemoFlag = 0;
2551 }
2552
2553 #else
2554
2555 // static void menPlayDemo_Click()
2556 void menPlayDemo_Click()
2557 {
2558   DemoFlag = 1;
2559   RecordDemoFlag = 0;
2560
2561 #if 0
2562   lblStatus = "Demo Playback";
2563 #endif
2564
2565   menPlay_Click();
2566
2567 #if 0
2568   if (LevelStatus != 1)
2569     lblStatus = "Demo Failed";
2570 #endif
2571
2572   DemoFlag = 0;
2573 }
2574
2575 #endif
2576
2577 #if 0
2578
2579 static void menRec_Click()
2580 {
2581   Trace("MainForm", "--> menRec_Click()");
2582   if (! LevelLoaded)
2583   {
2584     Beep();
2585     return;
2586   }
2587
2588   RecordDemoFlag = 1;
2589   DemoFlag = 0;
2590   lblStatus.ForeColor = vbRed;
2591   lblStatus = "Recording Demo";
2592   // DemoBuffer = New DemoBufferObject; // (handle this later, if needed)
2593   Debug.Assert(! IS_NOTHING(&DemoBuffer, sizeof(DemoBuffer)));
2594   Trace("MainForm", "Call menPlayClick");
2595   menPlay_Click();
2596   Trace("MainForm", "menPlayClick returned");
2597
2598   lblStatus.ForeColor = vbButtonText;
2599   RecordDemoFlag = 0;
2600   Let_ModifiedFlag(True);
2601   if (! STRING_IS_LIKE(CurPath, TmpPath))
2602   {
2603     OrigPath = CurPath;
2604     CurPath = TmpPath;
2605   }
2606
2607   LInfo.DemoRandomSeed = RecDemoRandomSeed;
2608   Trace("MainForm", "Call SaveMPX(TmpPath)");
2609   SaveMPX(TmpPath);
2610   Trace("MainForm", "Set DemoBuffer == Nothing");
2611   SET_TO_NOTHING(&DemoBuffer, sizeof(DemoBuffer));
2612   Trace("MainForm", "Call subFetchAndInitLevel");
2613   subFetchAndInitLevel();
2614   cmdPlayDemo.Enabled = DemoAvailable;
2615   Trace("MainForm", "<-- menRec_Click()");
2616 }
2617
2618 static void menReRecordDemo_Click()
2619 {
2620   if (! LevelLoaded)
2621   {
2622     Beep();
2623     return;
2624   }
2625
2626   RecordDemoFlag = 1;
2627   DemoFlag = 1;
2628   lblStatus.ForeColor = vbRed;
2629   lblStatus = "ReRecording Demo";
2630   // DemoBuffer = New DemoBufferObject; // (handle this later, if needed)
2631   Debug.Assert(! IS_NOTHING(&DemoBuffer, sizeof(DemoBuffer)));
2632   menPlay_Click();
2633   lblStatus.ForeColor = vbButtonText;
2634   RecordDemoFlag = 0;
2635   Let_ModifiedFlag(True);
2636   if (! STRING_IS_LIKE(CurPath, TmpPath))
2637   {
2638     OrigPath = CurPath;
2639     CurPath = TmpPath;
2640   }
2641
2642   LInfo.DemoRandomSeed = RecDemoRandomSeed;
2643   SaveMPX(TmpPath);
2644   SET_TO_NOTHING(&DemoBuffer, sizeof(DemoBuffer));
2645   subFetchAndInitLevel();
2646 }
2647
2648 void menStop_Click()
2649 {
2650   EndFlag = True;
2651   LeadOutCounter = 1;
2652   if (PauseMode != 0)
2653     menPause_Click();
2654
2655   fpsTim.Enabled = False;
2656   fpsTim_Timer();
2657   lblFps.Caption = "";
2658   menRec.Enabled = True;
2659   menPlay.Enabled = True;
2660   menPause.Enabled = False;
2661   menStop.Enabled = False;
2662   cmdPlay.Enabled = True;
2663   cmdPause.Enabled = False;
2664   cmdStop.Enabled = False;
2665   cmdRecordDemo.Enabled = True;
2666   cmdPlayDemo.Enabled = DemoAvailable;
2667   cmdPlayAll.Enabled = DemosAvailable;
2668   menPlayDemo.Enabled = DemoAvailable;
2669   menPlayAll.Enabled = DemosAvailable;
2670   menFaster.Enabled = False;
2671   menSlower.Enabled = False;
2672   cmbFile.Enabled = True;
2673   cmbLevel.Enabled = True;
2674 }
2675
2676 static void menStretch_Click(int Index)
2677 {
2678   ReStretch(0.25 * Index);
2679   // DisplayLevel True
2680 }
2681
2682 static void menToolTips_Click()
2683 {
2684   {
2685     menToolTips.Checked = ! menToolTips.Checked;
2686     if (menToolTips.Checked)
2687     {
2688       cmdPlay.ToolTipText = "Play Game (Space)";
2689       cmdPause.ToolTipText = "Pause (P)";
2690       cmdStop.ToolTipText = "Stop (Q)";
2691       cmdPlayDemo.ToolTipText = "Play demo (Ctrl+Space)";
2692       cmdRecordDemo.ToolTipText = "Record demo (Ctrl+R)";
2693       lblInfoCount.ToolTipText = "Number of infotrons needed";
2694       lblRedDiskCount.ToolTipText = "Number of red disks";
2695       cmbLevel.ToolTipText = "List of all levels in the file";
2696       cmbFile.ToolTipText = "List of files in current directory";
2697       lblFps.ToolTipText = "Animation speed in fps";
2698       lblFrameCount.ToolTipText = "Game time in frames";
2699     }
2700     else
2701     {
2702       cmdPlay.ToolTipText = "";
2703       cmdPause.ToolTipText = "";
2704       cmdStop.ToolTipText = "";
2705       cmdPlayDemo.ToolTipText = "";
2706       cmdRecordDemo.ToolTipText = "";
2707       lblInfoCount.ToolTipText = "";
2708       lblRedDiskCount.ToolTipText = "";
2709       cmbLevel.ToolTipText = "";
2710       cmbFile.ToolTipText = "";
2711       lblFps.ToolTipText = "";
2712       lblFrameCount.ToolTipText = "";
2713     }
2714
2715   }
2716 }
2717
2718 static void menTrim_Click()
2719 {
2720   LevelInfoType Tmp;
2721   char *OldOPath;
2722
2723   OldOPath = OrigPath;
2724   Tmp = LInfo;
2725   Tmp.SpecialPortCount = 0; // hack: all special ports are deleted
2726   menCopy_Click();
2727   CreateLevel(FMark.Width, FMark.Height);
2728   LInfo = Tmp;
2729   OrigPath = OldOPath;
2730   CurPath = OldOPath;
2731   menSelectAll_Click();
2732   menPaste_Click();
2733   picViewPort_Resize();
2734 }
2735
2736 static void menZonkOff_Click()
2737 {
2738   menZonkOn.Checked = False;
2739   menZonkOff.Checked = True;
2740   SpSaveMenu();
2741   SpLoadMenu();
2742 }
2743
2744 static void menZonkOn_Click()
2745 {
2746   menZonkOn.Checked = True;
2747   menZonkOff.Checked = False;
2748   SpSaveMenu();
2749   SpLoadMenu();
2750 }
2751
2752 static void PanelTim_Timer()
2753 {
2754   int Tmp;
2755
2756   Tmp = Panel.Height;
2757   if (PanelSeq < Panel.Height && -1 < PanelSeq)
2758   {
2759     PanelSeq = (ShowPanel != 0 ? PanelSeq + 2 : PanelSeq - 2);
2760     Tmp = ScaleHeight - Tmp + PanelSeq;
2761     Panel.top = Tmp;
2762     picViewPort.Height = Tmp;
2763   }
2764   else
2765   {
2766     PanelTim.Enabled = False;
2767     PanelSeq = (PanelSeq < 0 ? 0 : PanelSeq - );
2768     ShowPanel = (ShowPanel == 0 ? 1 : 0);
2769     menPanel.Checked = (ShowPanel != 0);
2770   }
2771 }
2772
2773 static void picKeys_MouseUp(int Button, int Shift, float X, float Y)
2774 {
2775   FocusTim.Enabled = True;
2776 }
2777
2778 static void picMenu_Click()
2779 {
2780 }
2781
2782 static void picPane_KeyDown(int KeyCode, int Shift)
2783 {
2784   if (KeyCode < 0 || 255 < KeyCode)
2785     return;
2786
2787   KeyState[KeyCode] = True;
2788   switch (KeyCode)
2789   {
2790     case vbKeyControl:
2791       if (MouseButton == 0 && EditFlag)
2792         picPane.MousePointer = 15;
2793
2794       break;
2795
2796     case vbKeyUp:
2797     case vbKeyLeft:
2798     case vbKeyDown:
2799     case vbKeyRight:
2800     case vbKeySpace:
2801       if (DemoFlag != 0)
2802       {
2803         DemoFlag = 0;
2804         UpdateDeltaT();
2805       }
2806
2807       break;
2808
2809     case vbKeyF12:
2810       if (DemoFlag != 0 && 2 == Shift)
2811       {
2812         DemoFlag = 0;
2813         UpdateDeltaT();
2814       }
2815
2816       break;
2817
2818     case vbKeyF11:
2819       bCapturePane = ! bCapturePane;
2820       break;
2821   }
2822 }
2823
2824 static void picPane_KeyUp(int KeyCode, int Shift)
2825 {
2826   if (KeyCode < 0 || 255 < KeyCode)
2827     return;
2828
2829   KeyState[KeyCode] = False;
2830   switch (KeyCode)
2831   {
2832     case vbKeyPageUp:
2833       if (menFaster.Enabled)
2834         menFaster_Click();
2835
2836       break;
2837
2838     case vbKeyPageDown:
2839       if (menSlower.Enabled)
2840         menSlower_Click();
2841
2842       break;
2843
2844     case vbKeySpace:
2845       if (2 == Shift) // ctrl+space
2846       {
2847         if (menPlayDemo.Enabled)
2848           menPlayDemo_Click();
2849
2850       }
2851       else
2852       {
2853         if (menPlay.Enabled)
2854           menPlay_Click();
2855       }
2856
2857       break;
2858
2859     case vbKeyQ:
2860       if (menStop.Enabled)
2861         menStop_Click();
2862
2863       break;
2864
2865     case vbKeyR:
2866       if (menRec.Enabled)
2867         menRec_Click();
2868
2869       break;
2870
2871     case vbKeyP:
2872     case vbKeyPause:
2873       if (menPause.Enabled && (Shift == 0))
2874         menPause_Click();
2875
2876       break;
2877
2878     case vbKeyControl:
2879       if (MouseButton == 0 && EditFlag)
2880         picPane.MousePointer = 0;
2881       break;
2882   }
2883 }
2884
2885 static void picPane_MouseDown(int Button, int Shift, float X, float Y)
2886 {
2887   int OldEdMode;
2888
2889   MouseButton = Button;
2890   OldEdMode = EditMode;
2891   if (Button != 1)
2892   {
2893     if (Button == 2 && Shift != 2)
2894     {
2895       EditMode = edSelect;
2896     }
2897     else
2898     {
2899       return;
2900     }
2901   }
2902
2903   if (Shift == 2)
2904     EditMode = edMove;
2905
2906   OSX = ScrollX;
2907   OSY = ScrollY;
2908   MDX = X;
2909   MDY = Y;
2910   switch (EditMode)
2911   {
2912     case edMove:
2913       picPane.MousePointer = 5; // size
2914       UserDragFlag = True;
2915       break;
2916
2917     case edDraw:
2918       SetField(X, Y, ToolBox.ASpriteIndex);
2919       break;
2920
2921     case edSelect:
2922       FMark.SetPoint1 EdGetX(X), EdGetY(Y);
2923       FMark.MoveMarker;
2924       break;
2925   }
2926
2927   EditMode = OldEdMode;
2928 }
2929
2930 static void picPane_MouseMove(int Button, int Shift, float X, float Y)
2931 {
2932   boolean Oldflag;
2933   int OldEdMode;
2934
2935   OldEdMode = EditMode;
2936   if (Button != 1)
2937   {
2938     if (EditFlag && Button == 2 && Shift != 2)
2939     {
2940       EditMode = edSelect;
2941     }
2942     else
2943     {
2944       return;
2945     }
2946   }
2947
2948   if (Shift == 2)
2949     EditMode = edMove;
2950
2951   switch (EditMode)
2952   {
2953     case edMove:
2954       Oldflag = NoDisplayFlag;
2955       NoDisplayFlag = False;
2956       ScrollTo(OSX - X + MDX, OSY - Y + MDY);
2957       Stage.Blt();
2958       NoDisplayFlag = Oldflag;
2959       break;
2960
2961     case edDraw:
2962       SetField(X, Y, ToolBox.ASpriteIndex);
2963       break;
2964
2965     case edSelect:
2966       FMark.SetPoint2 EdGetX(X), EdGetY(Y);
2967       FMark.MoveMarker;
2968       break;
2969   }
2970
2971   EditMode = OldEdMode;
2972 }
2973
2974 static void picPane_MouseUp(int Button, int Shift, float X, float Y)
2975 {
2976   MouseButton = MouseButton ^ Button;
2977   picPane.MousePointer = 0;
2978   UserDragFlag = False;
2979   if (menEditMain.Enabled && Button == 2)
2980   {
2981     if (MDX == X && MDY == Y)
2982       PopupMenu menEditMain;
2983   }
2984 }
2985
2986 #endif
2987
2988 static void picPane_Paint()
2989 {
2990   boolean Oldflag;
2991
2992   Oldflag = NoDisplayFlag;
2993   NoDisplayFlag = False;
2994
2995 #if 0
2996   Stage.Blt();
2997 #endif
2998
2999   NoDisplayFlag = Oldflag;
3000 }
3001
3002 static void ReStretch(float NewStretch)
3003 {
3004 #if 1
3005   long BW2, LW, LH;
3006 #else
3007   long BW2, LW, LH, i;
3008 #endif
3009
3010 #if 0
3011   printf("::: MainForm.c: ReStretch(): %d, %d\n", Loaded, LevelLoaded);
3012 #endif
3013
3014   if (! Loaded)
3015   {
3016 #if 0
3017     printf("::: NewStretch == %f\n", NewStretch);
3018 #endif
3019
3020     Stretch = NewStretch;
3021     return;
3022   }
3023
3024 #if 0
3025   MousePointer = 11;
3026   SET_TO_NOTHING(&Stage, sizeof(Stage));
3027   SET_TO_NOTHING(&StretchedSprites, sizeof(StretchedSprites));
3028   menStretch(Stretch / 0.25).Checked = False;
3029 #endif
3030
3031   Stretch = NewStretch;
3032
3033 #if 0
3034   menStretch(Stretch / 0.25).Checked = True;
3035   //  StretchWidth = BaseWidth ' * NewStretch
3036   //  StretchWidth2 = StretchWidth \ 2
3037   //  TwoPixels = 2 '* Stretch
3038   // StretchLoad Sprites, imgMpx.Picture, 16, 16
3039 #endif
3040
3041   BW2 = StretchWidth / 2;
3042   LW = (FieldWidth + 2) * BaseWidth; // StretchWidth
3043   LH = (FieldHeight + 2) * BaseWidth; // StretchWidth
3044
3045 #if 0
3046   // i = bmpStage.CreateAtSize(LW, LH)
3047   // Stage = New DDScrollBuffer; // (handle this later, if needed)
3048   i = Stage.CreateAtSize(LW, LH, picPane.hWnd);
3049   // Set StretchedSprites = NormalSprites.GetStretchCopy(Stretch)
3050   ReLoadStretchSprites();
3051   if (i == 0 || IS_NOTHING(&StretchedSprites, sizeof(StretchedSprites)))
3052   {
3053     // menStretch(Stretch / 0.5).Enabled = False
3054     if (0.5 <= Stretch)
3055       ReStretch(Stretch - 0.25);
3056
3057   }
3058   else
3059 #endif
3060   {
3061     StretchedSprites.DestXOff = 1 * BaseWidth; // StretchWidth
3062     StretchedSprites.DestYOff = 1 * BaseWidth; // StretchWidth
3063     Stage.DestXOff = 1 * StretchWidth;
3064     Stage.DestYOff = 1 * StretchWidth;
3065     StretchedSprites.DestinationSurface = Stage.Surface;
3066
3067 #if 0
3068     Stage.Cls();
3069 #endif
3070
3071     if (Loaded && LevelLoaded)
3072     {
3073 #if 0
3074       printf("::: MainForm.c: ReStretch(): ...\n");
3075 #endif
3076
3077       SetDisplayRegion();
3078       picViewPort_Resize();
3079       DisplayLevel();
3080     }
3081
3082     subCalculateScreenScrollPos();
3083
3084 #if 0
3085   printf("::: MainForm.c: ReStretch(): %d, %d\n", ScreenScrollXPos, ScreenScrollYPos);
3086 #endif
3087
3088     ScrollTo(ScreenScrollXPos, ScreenScrollYPos);
3089
3090 #if 0
3091     Stage.Blt();
3092 #endif
3093
3094     picPane_Paint();
3095   }
3096
3097 #if 0
3098   MousePointer = 0;
3099 #endif
3100 }
3101
3102 static void SetScrollEdges()
3103 {
3104 #if 0
3105   printf("::: MainForm.c: SetScrollEdges() ... [%ld, %ld, %ld, %ld] [%f, %d] [%d, %d, %d, %d]\n",
3106          DisplayMinX, DisplayMinY, DisplayMaxX, DisplayMaxY,
3107          Stretch, BaseWidth,
3108          ScrollMinX, ScrollMinY, ScrollMaxX, ScrollMaxY);
3109 #endif
3110
3111   ScrollMinX = (int)(DisplayMinX - 0.5) * Stretch * BaseWidth;
3112   ScrollMinY = (int)(DisplayMinY - 0.5) * Stretch * BaseWidth;
3113   ScrollMaxX = (int)(DisplayMaxX + 1.5) * Stretch * BaseWidth - picPane.Width;
3114   ScrollMaxY = (int)(DisplayMaxY + 1.5) * Stretch * BaseWidth - picPane.Height;
3115
3116 #if 0
3117   printf("::: MainForm.c: SetScrollEdges() done [%d, %d, %d, %d]\n",
3118          ScrollMinX, ScrollMinY, ScrollMaxX, ScrollMaxY);
3119 #endif
3120 }
3121
3122 void DrawField(int X, int Y)
3123 {
3124   int Tmp, tsi;
3125
3126   tsi = GetSI(X, Y);
3127   Tmp = LowByte(PlayField16[tsi]);
3128   if (40 < Tmp)
3129     Tmp = 0;
3130
3131   if (Tmp == fiRAM || Tmp == fiHardWare)
3132     Tmp = DisPlayField[tsi];
3133
3134   if (Tmp == fiBug || Tmp == 40)
3135     Tmp = DisPlayField[tsi];
3136
3137   if (EditFlag)
3138   {
3139     if (fiOrangeDisk < Tmp && Tmp < fiSnikSnak)
3140       Tmp = DisPlayField[tsi];
3141   }
3142
3143   StretchedSprites.BltEx(StretchWidth * X, StretchWidth * Y, Tmp);
3144 }
3145
3146 void DrawFieldAnimated(int X, int Y)
3147 {
3148   int Tmp, tsi;
3149
3150   tsi = GetSI(X, Y);
3151   Tmp = LowByte(PlayField16[tsi]);
3152   switch (Tmp)
3153   {
3154     case fiSnikSnak:
3155       subDrawAnimatedSnikSnaks(tsi);
3156       break;
3157
3158     case fiElectron:
3159       subDrawAnimatedElectrons(tsi);
3160       break;
3161
3162     default:
3163       //      If 40 < Tmp Then Tmp = 0
3164       //      If Tmp = fiRAM Or Tmp = fiHardWare Then Tmp = DisPlayField(tsi)
3165       //      If Tmp = fiBug Or Tmp = 40 Then Tmp = DisPlayField(tsi)
3166       //      If EditFlag Then
3167       //        If fiOrangeDisk < Tmp And Tmp < fiSnikSnak Then Tmp = DisPlayField(tsi)
3168       //      End If
3169       //      StretchedSprites.BltEx StretchWidth * X, StretchWidth * Y, Tmp
3170       break;
3171   }
3172 }
3173
3174 void DrawFieldNoAnimated(int X, int Y)
3175 {
3176   int Tmp, tsi;
3177
3178   tsi = GetSI(X, Y);
3179   Tmp = LowByte(PlayField16[tsi]);
3180   switch (Tmp)
3181   {
3182     case fiSnikSnak:
3183       StretchedSprites.BltEx(StretchWidth * X, StretchWidth * Y, fiSpace);
3184       break;
3185
3186     case fiElectron:
3187       StretchedSprites.BltEx(StretchWidth * X, StretchWidth * Y, fiSpace);
3188       break;
3189
3190     default:
3191       if (40 < Tmp)
3192         Tmp = 0;
3193
3194       if (Tmp == fiRAM || Tmp == fiHardWare)
3195         Tmp = DisPlayField[tsi];
3196
3197       if (Tmp == fiBug || Tmp == 40)
3198         Tmp = DisPlayField[tsi];
3199
3200       if (EditFlag)
3201       {
3202         if (fiOrangeDisk < Tmp && Tmp < fiSnikSnak)
3203           Tmp = DisPlayField[tsi];
3204       }
3205
3206 #if 0
3207       printf("::: MainForm.c: DrawFieldNoAnimated(): %d, %d [%d]\n",
3208              X, Y, Tmp);
3209 #endif
3210
3211       StretchedSprites.BltEx(StretchWidth * X, StretchWidth * Y, Tmp);
3212       break;
3213   }
3214 }
3215
3216 void DrawSprite(int X, int Y, int SpritePos)
3217 {
3218   StretchedSprites.BltEx(StretchWidth * X, StretchWidth * Y, SpritePos);
3219 }
3220
3221 #if 0
3222
3223 void InvalidateRect(long XMin, long YMin, long XMax, long YMax)
3224 {
3225   long X, Y;
3226
3227   //  For Y = YMin To YMax
3228   //    For X = XMin To XMax
3229   //      Field(X, Y).GraphicsValid = 0
3230   //    Next X
3231   //  Next Y
3232 }
3233
3234 static void picViewPort_MouseUp(int Button, int Shift, float X, float Y)
3235 {
3236   FocusTim.Enabled = True;
3237 }
3238
3239 static void picViewPort_Paint()
3240 {
3241   // Debug.Print "picViewPort_Paint()"
3242 }
3243
3244 #endif
3245
3246 static void picViewPort_Resize()
3247 {
3248 #if 0
3249   long bdX, bdY, PanelVisibility;
3250   long X, Y, dx, dY;
3251   SettingsObject s;
3252   boolean B;
3253
3254   bdX = picFrame.Width - picFrame.ScaleWidth;
3255   bdY = picFrame.Height - picFrame.ScaleHeight;
3256   dx = Min(picViewPort.ScaleWidth - bdX, (DisplayWidth - 1) * Stretch * BaseWidth);
3257   dx = Max(dx, 0);
3258   dY = Min(picViewPort.ScaleHeight - bdX, (DisplayHeight - 1) * Stretch * BaseWidth);
3259   dY = Max(dY, 0);
3260   B = s.Read("LimitToOriginalFieldSize", False);
3261   PanelVisibility = 24 * (Panel.Height - PanelSeq - (float)1) / Panel.Height;
3262   if (B)
3263   {
3264     dx = Min(320 * Stretch, dx);
3265     dY = Min((200 - PanelVisibility) * Stretch, dY);
3266   }
3267
3268   X = Max((picViewPort.ScaleWidth - dx) / 2, 0);
3269   Y = Max((picViewPort.ScaleHeight - dY) / 2, 0);
3270   picPane.Move X, Y, dx, dY;
3271   picFrame.Move X - bdX / 2, Y - bdY / 2, dx + bdX, dY + bdY;
3272 #endif
3273
3274   SetScrollEdges();
3275
3276 #if 0
3277   printf("::: MainForm.c: picViewPort_Resize(): %d, %d\n", ScrollX, ScrollY);
3278 #endif
3279
3280   ScrollTo(ScrollX, ScrollY);
3281
3282   //  SizeTim.Interval = 1
3283 }
3284
3285 #if 0
3286
3287 //
3288 // Private Sub SizeTim_Timer()
3289 // Dim wdX&, wdY&
3290 //  SizeTim.Interval = 0
3291 //  wdX = Max(0, picViewPort.ScaleWidth - picPane.Width) * Screen.TwipsPerPixelX
3292 //  wdY = Max(0, picViewPort.ScaleHeight - picPane.Height) * Screen.TwipsPerPixelY
3293 //  If (0 < wdX) Or (0 < wdY) Then
3294 //    Move Left, Top, Width - wdX, Height - wdY
3295 //  End If
3296 // End Sub
3297
3298 static void LoadKeyIndicators()
3299 {
3300   int i;
3301
3302   picKeys.BackColor = vbButtonFace;
3303   for (i = 2; i <= 5; i++)
3304   {
3305     Load shpKey(i);
3306   }
3307
3308   for (i = 1; i <= 5; i++)
3309   {
3310     shpKey(i).FillColor = vbButtonFace;
3311     shpKey(i).Visible = True;
3312   }
3313
3314   shpKey(1).Move 7, 0;
3315   shpKey(2).Move 0, 7;
3316   shpKey(3).Move 7, 14;
3317   shpKey(4).Move 14, 7;
3318   shpKey(5).Move 7, 7;
3319 }
3320
3321 void ShowKey(int KeyVar)
3322 {
3323   boolean State[5 + 1];
3324   int i;
3325   boolean Tmp;
3326   long Col;
3327   static boolean LastState[5 + 1];
3328
3329   //  For i = 1 To 5
3330   //    State(i) = False
3331   //  Next i
3332   switch (KeyVar)
3333   {
3334     case 0:
3335       // do nothing
3336       break;
3337
3338     case Is < 5:
3339       State[KeyVar] = True;
3340       break;
3341
3342     default:
3343       State[5] = True;
3344       if (KeyVar < 9)
3345         State[KeyVar - 4] = True;
3346       break;
3347   }
3348
3349   for (i = 1; i <= 5; i++)
3350   {
3351     Tmp = State[i];
3352     if (Tmp ^ LastState[i])
3353     {
3354       Col = (i == 5 ? vbRed : vbGreen);
3355       shpKey(i).FillColor = (Tmp ? Col : vbButtonFace);
3356       shpKey(i).Refresh;
3357       LastState[i] = Tmp;
3358     }
3359   }
3360 }
3361
3362 static void GetSettings()
3363 {
3364   SettingsObject s;
3365   char *APath;
3366   long X, Y;
3367   int i;
3368   boolean Flag;
3369
3370   {
3371     // last file info
3372     APath = WithSlash(App.Path);
3373     CurPath = s.Read("LastPath", APath);
3374     OrigPath = CurPath;
3375     // window width and height
3376     X = s.Read("Width", Width);
3377     Y = s.Read("Height", Height);
3378     if (X < 0 Then X == 0: If Y < 0)
3379       Y = 0;
3380
3381     if (Screen.Width < X)
3382       X = Screen.Width;
3383
3384     if (Screen.Height < Y)
3385       Y = Screen.Height;
3386
3387     Width = X;
3388     Height = Y;
3389     // window position and state
3390     X = s.Read("Left", left);
3391     Y = s.Read("Top", top);
3392     if (X < 0 Then X == 0: If Y < 0)
3393       Y = 0;
3394
3395     if (Screen.Width < (X + Width))
3396       X = Screen.Width - Width;
3397
3398     if (Screen.Height < (Y + Height))
3399       Y = Screen.Height - Height;
3400
3401     left = X;
3402     top = Y;
3403     WindowState = s.Read("WinState", vbNormal);
3404     // flags/options
3405     Flag = s.Read("ShowToolTips", True);
3406     if (Flag)
3407       menToolTips_Click();
3408
3409     menBorder.Checked = ! CBool(s.Read("ShowBorder", False));
3410     Flag = CBool(s.Read("AutoScroll", True));
3411     if (! Flag)
3412     {
3413       AutoScrollFlag = False;
3414       menAutoScroll.Checked = False;
3415     }
3416
3417     Flag = CBool(s.Read("SoundFX", True));
3418     FXOnFlag = (Flag ? -1 : 0);
3419     menSoundFX.Checked = Flag;
3420     SignatureDelay = CLng(s.Read("SignatureDelay", 3000));
3421     AllowRedDiskCheat = CInt(s.Read("AllowRedDiskCheat", 1));
3422     AllowEatRightRedDiskBug = CInt(s.Read("AllowEatRightRedDiskBug", 1));
3423     MySignature = s.Read("MySignature", "");
3424     // speed
3425     X = s.Read("FrameDelayPlay", 1000000 / 35);
3426     i = GetSpeedIndex(X);
3427     menPlaySpeed_Click(i);
3428     X = s.Read("FrameDelayDemo", 1000000 / 35);
3429     i = GetSpeedIndex(X);
3430     menDemoSpeed_Click(i);
3431     // Zoom
3432     i = s.Read("Stretch", 4);
3433     if (i < menStretch.LBound || menStretch.UBound < i)
3434       i = 4;
3435
3436     menStretch_Click (i);
3437   }
3438 }
3439
3440 static void SaveSettings()
3441 {
3442   SettingsObject s;
3443   int i;
3444
3445   {
3446     s.Save "LastPath", (ModifiedFlag ? OrigPath : CurPath);
3447     if (WindowState != vbMinimized)
3448     {
3449       s.Save "Width", Width;
3450       s.Save "Height", Height;
3451       s.Save "Left", left;
3452       s.Save "Top", top;
3453       s.Save "WinState", WindowState;
3454     }
3455
3456     s.Save "ShowToolTips", menToolTips.Checked;
3457     s.Save "ShowBorder", menBorder.Checked;
3458     s.Save "AutoScroll", menAutoScroll.Checked;
3459     s.Save "SoundFX", menSoundFX.Checked;
3460     s.Save "SignatureDelay", SignatureDelay;
3461     s.Save "AllowRedDiskCheat", AllowRedDiskCheat;
3462     s.Save "AllowEatRightRedDiskBug", AllowEatRightRedDiskBug;
3463     s.Save "MySignature", MySignature;
3464     // speeds
3465     s.Save "FrameDelayPlay", DeltaTPlay;
3466     s.Save "FrameDelayDemo", DeltaTDemo;
3467     // zoom
3468     for (i = menStretch.LBound; i <= menStretch.UBound; i++)
3469     {
3470       if (menStretch(i).Checked)
3471         break;
3472     }
3473
3474     s.Save "Stretch", i;
3475     //    s.Save "",
3476   }
3477 }
3478
3479 void ReLoadStretchSprites()
3480 {
3481   long Tmp;
3482   BitMapObject NBMP, SBMP;
3483   char *tmpMpxBmp;
3484
3485   //  If Stretch = 1 Then
3486   MpxBmp = App.Path & "/Mpx.bmp";
3487   //  Else
3488   //    MpxBmp = App.Path & "\Mpx" & Stretch & ".bmp"
3489   //    tmpMpxBmp = App.Path & "\Mpx.bmp"
3490   //    If FileExists(MpxBmp) And FileExists(tmpMpxBmp) Then
3491   //      If FileDateTime(MpxBmp) < FileDateTime(tmpMpxBmp) Then
3492   //        MayKill MpxBmp
3493   //      End If
3494   //    End If
3495   //    If Not FileExists(MpxBmp) Then
3496   //      MousePointer = 11
3497   // //      Set NBMP = New BitMapObject // (handle this later, if needed)
3498   //      tmpMpxBmp = App.Path & "\Mpx.bmp"
3499   //      If Not FileExists(tmpMpxBmp) Then
3500   //        ReportError "ReLoadStretchSprites", "File not found: " & tmpMpxBmp
3501   //        MESSAGE_BOX("an error occured"); // MsgBox "File not found: " & tmpMpxBmp, vbCritical, "MegaPlex - Error"
3502   //        End
3503   //      End If
3504   //      NBMP.CreateFromFile tmpMpxBmp
3505   //      Set SBMP = NBMP.GetStretchCopy(Stretch)
3506   //      SBMP.SaveToFile MpxBmp
3507   //      Set NBMP = Nothing
3508   //      Set SBMP = Nothing
3509   //      MousePointer = 0
3510   //    End If
3511   //  End If
3512   // StretchedSprites = New DDSpriteBuffer; // (handle this later, if needed)
3513   if (! StretchedSprites.CreateFromFile(MpxBmp, 16, 16))
3514     SET_TO_NOTHING(&StretchedSprites, sizeof(StretchedSprites));
3515 }
3516
3517 void SaveSnapshot(currency Number)
3518 {
3519   char *Path;
3520
3521   Path = CAT(WithSlash(App.Path), "Capture");
3522   if (! IsDir(Path))
3523     MkDir(Path);
3524
3525   Path = Path & "\" & Format(Number, "00000000") & ".bmp";
3526   SavePicture CaptureWindow(picPane.hWnd, True, 0, 0, picPane.ScaleWidth, picPane.ScaleHeight), Path;
3527 }
3528
3529 #endif