rnd-20091124-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 DrawFrameIfNeeded()
1007 {
1008   DrawFrame(0);
1009
1010   /* !!! CHECK THIS !!! */
1011 #if 1
1012   if (! menBorder.Checked)
1013     DrawFrame(1);
1014 #endif
1015 }
1016
1017 void DisplayLevel()
1018 {
1019   int X, Y;
1020
1021 #if 0
1022   printf("::: MainForm.c: DisplayLevel(): %d, %d, %d\n",
1023          Loaded, LevelLoaded, bPlaying);
1024 #endif
1025
1026   if (! Loaded)
1027     return;
1028
1029   if (! LevelLoaded)
1030     return;
1031
1032 #if 1
1033   SetDisplayRegion();
1034 #endif
1035
1036   DrawFrame(0);
1037
1038   /* !!! CHECK THIS !!! */
1039 #if 1
1040   if (! menBorder.Checked)
1041     DrawFrame(1);
1042 #endif
1043
1044   if (bPlaying)
1045   {
1046 #if 0
1047     printf("::: MainForm.c: DisplayLevel(): [%ld, %ld, %ld, %ld] [%d, %d]...\n",
1048            DisplayMinX, DisplayMinY, DisplayMaxX, DisplayMaxY,
1049            FieldWidth, FieldHeight);
1050 #endif
1051
1052     for (Y = DisplayMinY; Y <= DisplayMaxY; Y++)
1053     {
1054       for (X = DisplayMinX; X <= DisplayMaxX; X++)
1055       {
1056         DrawFieldNoAnimated(X, Y);
1057       }
1058     }
1059
1060     for (Y = DisplayMinY; Y <= DisplayMaxY; Y++)
1061     {
1062       for (X = DisplayMinX; X <= DisplayMaxX; X++)
1063       {
1064         DrawFieldAnimated(X, Y);
1065       }
1066     }
1067
1068   }
1069   else
1070   {
1071     for (Y = DisplayMinY; Y <= DisplayMaxY; Y++)
1072     {
1073       for (X = DisplayMinX; X <= DisplayMaxX; X++)
1074       {
1075         DrawField(X, Y);
1076       }
1077     }
1078   }
1079 }
1080
1081 #if 0
1082
1083 static void cmbFile_Click()
1084 {
1085   CurPath = CAT(StripDir(OrigPath), CAT("/", cmbFile.List(cmbFile.ListIndex)));
1086   OrigPath = CurPath;
1087   FillLevelList(CurPath, LevelNumber);
1088   if (STRING_IS_LIKE(OrigPath, "*.mpx") || STRING_IS_LIKE(OrigPath, "*.sp"))
1089   {
1090     menSave.Enabled = True;
1091   }
1092   else
1093   {
1094     menSave.Enabled = False;
1095   }
1096 }
1097
1098 static void cmbFile_KeyDown(int KeyCode, int Shift)
1099 {
1100   picPane_KeyDown(KeyCode, Shift);
1101 }
1102
1103 static void cmbFile_KeyUp(int KeyCode, int Shift)
1104 {
1105   picPane_KeyUp(KeyCode, Shift);
1106 }
1107
1108 static int GetFileNameToSave()
1109 {
1110   static int GetFileNameToSave;
1111
1112   char *T;
1113
1114   (char *)T = StripFileName(OrigPath);
1115   if (STRING_IS_LIKE(T, "*.dat") || STRING_IS_LIKE(T, "*.d##"))
1116   {
1117     T = "Level" & Format(LevelNumber, "#000");
1118   }
1119
1120   GetFileNameToSave = T;
1121
1122   return GetFileNameToSave;
1123 }
1124
1125 static void cmbLevel_Click()
1126 {
1127   long InfoCount;
1128   boolean Oldflag;
1129   int Msg;
1130   static long LastIndex = 0;
1131   static boolean bBlock = False;
1132
1133   if (bBlock)
1134     return;
1135
1136   // //////////////////////////////////////////////////////////////////
1137   if (ModifiedFlag)
1138   {
1139     VbMsgBoxResult Res;
1140
1141     Msg = "Save changes to " & GetFileNameToSave() & " ?";
1142     Res = MsgBox(Msg, vbYesNoCancel, AppTitle & " - close level");
1143     if (Res == vbCancel) // fallback
1144     {
1145       bBlock = True;
1146
1147       // --- On Error Resume Next
1148       cmbLevel.ListIndex = LastIndex;
1149       // --- On Error GoTo 0
1150
1151       bBlock = False;
1152       Debug.Assert cmbLevel.ListIndex = LastIndex;
1153       return;
1154     }
1155
1156     if (Res == vbYes)
1157     {
1158       // Dim oldCurPath$
1159       // oldCurPath = CurPath
1160       if (FileExists(OrigPath) && menSave.Enabled)
1161       {
1162         menSave_Click();
1163       }
1164       else
1165       {
1166         if (! SaveAs()) // fallback
1167         {
1168           bBlock = True;
1169
1170           // --- On Error Resume Next
1171           cmbLevel.ListIndex = LastIndex;
1172           // --- On Error GoTo 0
1173
1174           bBlock = False;
1175           Debug.Assert cmbLevel.ListIndex = LastIndex;
1176           return;
1177         }
1178       }
1179
1180       // CurPath = oldCurPath
1181     }
1182
1183     Let_ModifiedFlag(False);
1184     CurPath = OrigPath;
1185   }
1186
1187   // //////////////////////////////////////////////////////////////////
1188   {
1189     LevelNumber = cmbLevel.ListIndex + 1;
1190     DemoFlag = False;
1191     if (Loaded)
1192     {
1193       Oldflag = NoDisplayFlag;
1194       NoDisplayFlag = False;
1195       subFetchAndInitLevel();
1196       if ((0 < SignatureDelay) && ! (WindowState == vbMinimized))
1197       {
1198         Msg = LInfo.LevelTitle & vbNewLine & "(" & FieldWidth & " x " & FieldHeight & ")";
1199         if (DemoAvailable && bSignatureAvailable)
1200           Msg = Msg & vbNewLine & vbNewLine & gSignature;
1201
1202         SignatureForm.Signature = Msg;
1203         SignatureForm.DelayMS = SignatureDelay;
1204         int X, Y;
1205
1206         X = left + (Width - SignatureForm.Width) / 2;
1207         Y = top + (Height - SignatureForm.Height) / 2;
1208         SignatureForm.Move X, Y;
1209         SignatureForm.Show vbModeless, Me;
1210         Me.SetFocus;
1211       }
1212
1213       lblStatus = "MegaPlex";
1214       lblFrameCount = GetTotalFramesOfDemo();
1215       if (EditFlag)
1216         EdAll();
1217
1218       ReStretch(Stretch);
1219       // picPane_Paint
1220       Stage.Blt();
1221       NoDisplayFlag = Oldflag;
1222       LastIndex = cmbLevel.ListIndex;
1223     }
1224
1225   }
1226   menPlayDemo.Enabled = DemoAvailable;
1227   cmdPlayDemo.Enabled = DemoAvailable;
1228 }
1229
1230 static void cmblevel_KeyDown(int KeyCode, int Shift)
1231 {
1232   if (GameLoopRunning != 0)
1233     return;
1234
1235   switch (KeyCode)
1236   {
1237     case vbKeySpace:
1238       if (menPlay.Enabled == True)
1239         menPlay_Click();
1240
1241       break;
1242
1243     default:
1244       picPane_KeyDown(KeyCode, Shift);
1245       break;
1246   }
1247 }
1248
1249 static void cmbLevel_KeyUp(int KeyCode, int Shift)
1250 {
1251   picPane_KeyUp(KeyCode, Shift);
1252 }
1253
1254 static void cmdPause_Click()
1255 {
1256   menPause_Click();
1257 }
1258
1259 static void cmdPause_MouseUp(int Button, int Shift, float X, float Y)
1260 {
1261   FocusTim.Enabled = True;
1262 }
1263
1264 static void cmdPlay_Click()
1265 {
1266   if (menPlay.Enabled)
1267     menPlay_Click();
1268 }
1269
1270 static void cmdPlay_MouseUp(int Button, int Shift, float X, float Y)
1271 {
1272   FocusTim.Enabled = True;
1273 }
1274
1275 static void cmdPlayAll_Click()
1276 {
1277   menPlayAll_Click();
1278 }
1279
1280 static void cmdPlayAll_MouseUp(int Button, int Shift, float X, float Y)
1281 {
1282   FocusTim.Enabled = True;
1283 }
1284
1285 static void cmdPlayDemo_Click()
1286 {
1287   menPlayDemo_Click();
1288 }
1289
1290 static void cmdPlayDemo_MouseUp(int Button, int Shift, float X, float Y)
1291 {
1292   FocusTim.Enabled = True;
1293 }
1294
1295 static void cmdRecordDemo_Click()
1296 {
1297   if (menRec.Enabled)
1298     menRec_Click();
1299 }
1300
1301 static void cmdRecordDemo_MouseUp(int Button, int Shift, float X, float Y)
1302 {
1303   FocusTim.Enabled = True;
1304 }
1305
1306 static void cmdStop_Click()
1307 {
1308   if (menStop.Enabled)
1309     menStop_Click();
1310 }
1311
1312 static void cmdStop_MouseUp(int Button, int Shift, float X, float Y)
1313 {
1314   FocusTim.Enabled = True;
1315 }
1316
1317 static void FocusTim_Timer()
1318 {
1319   FocusTim.Enabled = False;
1320
1321   // --- On Error Resume Next
1322   picPane.SetFocus;
1323 }
1324
1325 static void Form_KeyDown(int KeyCode, int Shift)
1326 {
1327   picPane_KeyDown(KeyCode, Shift);
1328 }
1329
1330 static void Form_KeyUp(int KeyCode, int Shift)
1331 {
1332   picPane_KeyUp(KeyCode, Shift);
1333 }
1334
1335 #endif
1336
1337 void Form_Load()
1338 {
1339 #if 0
1340
1341   long i;
1342   SettingsObject s;
1343
1344 #endif
1345
1346   Loaded = False;
1347   DemoFlag = 0;
1348   PanelSeq = 0;
1349   EditFlag = False;
1350   EditMode = edMove;
1351   // FMark = New MarkerObject; // (handle this later, if needed)
1352
1353   InitGlobals();
1354
1355 #if 0
1356
1357   LoadMenus();
1358
1359   TmpPath = GetValidTempPath();
1360   if (TmpPath == "")
1361     exit(-1);
1362
1363   CleanTempDir(TmpPath);
1364   TmpPath = CAT(WithSlash(TmpPath), GetMyTempFileName());
1365   GetSettings();
1366   ShowPanel = 1;
1367
1368   InitDirectX(hWnd, picPane.hWnd);
1369
1370   //  AllowRedDiskCheat = 1
1371   MpxBmp = CAT(App.Path, "/mpx.bmp");
1372   // // Set NormalSprites = New DDSpriteBuffer // (handle this later, if needed)
1373   // NormalSprites.CreateFromFile MPXBMP, 16, 16
1374
1375   Field = REDIM_2D(sizeof(int), 0, 2 + 1 - 1, 0, 2 + 1 - 1);
1376
1377   picViewPort.ScaleMode = vbPixels;
1378
1379 #endif
1380
1381   PauseMode = 0;
1382   //  BaseWidth = 16
1383
1384 #if 1
1385   if (0)
1386     menBorder_Click();
1387 #endif
1388
1389   Loaded = True;
1390
1391   ReStretch(Stretch);
1392
1393 #if 0
1394
1395   LoadKeyIndicators();
1396
1397   Show();
1398
1399   FillFileList(CurPath);
1400   if (s.Read("ShowSplash", True))
1401   {
1402     // frmSplash.EnableTimer
1403     frmSplash.Show vbModal, Me;
1404   }
1405
1406 #endif
1407 }
1408
1409 #if 0
1410
1411 static void FillLevelList(char *Path, int LevelIndex)
1412 {
1413   long FNum, LevLen, i, iMax;
1414   char *TFile;
1415
1416   cmbLevel.Clear;
1417   if (! FileExists(Path))
1418     return;
1419
1420   if ((STRING_IS_LIKE(Path, "*.D??")) || (STRING_IS_LIKE(Path, "*.sp")))
1421   {
1422     FNum = FreeFile();
1423     LevLen = 1536;
1424     FNum = fopen(Path, "rb");
1425     {
1426       i = 0;
1427       FILE_GET(FNum, (long)1441 + i * LevLen, &LInfo, sizeof(LInfo));
1428       cmbLevel.AddItem Format(i + 1, "#000") & "   " & LInfo.LevelTitle, i;
1429       if (STRING_IS_LIKE(Path, "*.D??"))
1430       {
1431         while (!(EOF(FNum)))
1432         {
1433           i = i + 1;
1434           FILE_GET(FNum, (long)1441 + i * LevLen, &LInfo, sizeof(LInfo));
1435           if (EOF(FNum))
1436             break;
1437
1438           cmbLevel.AddItem Format(i + 1, "#000") & "   " & LInfo.LevelTitle, i;
1439         }
1440       }
1441
1442       if (LevelIndex <= i && 0 < LevelIndex)
1443         i = LevelIndex - 1;
1444       else
1445         i = 0;
1446
1447       cmbLevel.ListIndex = i;
1448     }
1449     fclose(FNum);
1450   }
1451   else if (STRING_IS_LIKE(Path, "*.mpx"))
1452   {
1453     FNum = FreeFile();
1454     LevLen = 1536;
1455     FNum = fopen(Path, "rb");
1456     {
1457       i = 0;
1458       if (MpxOpen(Path))
1459       {
1460         for (i = 1; i <= LevelCount; i++)
1461         {
1462           if (! MpxLoadLInfo(CInt(i)))
1463             break;
1464
1465           cmbLevel.AddItem Format(i, "#000") & "   " & LInfo.LevelTitle, i - 1;
1466         }
1467
1468         MpxClose();
1469       }
1470
1471       if (LevelIndex < i && 0 < LevelIndex)
1472         i = LevelIndex - 1;
1473       else
1474         i = 0;
1475
1476       if (i < cmbLevel.ListCount)
1477         cmbLevel.ListIndex = i;
1478
1479     }
1480     fclose(FNum);
1481   }
1482 }
1483
1484 static void FillFileList(char *Path)
1485 {
1486   long FNum, LevLen, i;
1487   int nDemoCount;
1488   char *TFile, *TPath, *OFile;
1489
1490   cmbFile.Clear;
1491   i = 0;
1492   nDemoCount = 0;
1493   TPath = WithSlash(StripDir(Path));
1494   OFile = StripFileName(Path);
1495   TFile = Dir(TPath & "*.D??");
1496   while (TFile != "")
1497   {
1498     if (FileLen(TPath & TFile) == 170496)
1499     {
1500       cmbFile.AddItem TFile;
1501     }
1502
1503     TFile = Dir;
1504   }
1505
1506   TFile = Dir(TPath & "*.SP");
1507   while (TFile != "")
1508   {
1509     nDemoCount = nDemoCount + 1;
1510     cmbFile.AddItem TFile;
1511     TFile = Dir;
1512   }
1513
1514   TFile = Dir(TPath & "*.mpx");
1515   while (TFile != "")
1516   {
1517     nDemoCount = nDemoCount + 1;
1518     cmbFile.AddItem TFile;
1519     TFile = Dir;
1520   }
1521
1522   i = cmbFile.ListCount - 1;
1523   if (0 < cmbFile.ListCount)
1524   {
1525     do
1526     {
1527       if ((cmbFile.List(i) Like OFile) || i == 0)
1528         break;
1529
1530       i = i - 1;
1531     }
1532     while (!(i < 1));
1533
1534     cmbFile.ListIndex = i;
1535   }
1536
1537   DemosAvailable = (1 < nDemoCount);
1538   menPlayAll.Enabled = DemosAvailable;
1539   cmdPlayAll.Enabled = DemosAvailable;
1540 }
1541
1542 static void LoadMenus()
1543 {
1544   long i;
1545
1546   // speeds
1547   menFaster.Enabled = False;
1548   menSlower.Enabled = False;
1549   InitSpeeds();
1550   for (i = 1; i <= nSpeedCount; i++)
1551   {
1552     if (1 < i)
1553     {
1554       Load menPlaySpeed(i);
1555       Load menDemoSpeed(i);
1556     }
1557
1558     menPlaySpeed(i).Caption = GetSpeedDescriptionFPS(SpeedsByDelayUS[i]);
1559     menDemoSpeed(i).Caption = GetSpeedDescriptionFPS(SpeedsByDelayUS[i]);
1560   }
1561
1562   // zoom
1563   menStretch(1).Caption = Format(0.25, "#0.00") & ";
1564   1";
1565   if (Stretch == 0.25)
1566     menStretch(1).Checked = True;
1567
1568   for (i = 2; i <= 20; i++)
1569   {
1570     Load menStretch(i);
1571     menStretch(i).Caption = Format(0.25 * i, "#0.00") & ";
1572     1";
1573     menStretch(i).Checked = ((i * 0.25) == Stretch);
1574   }
1575
1576   menSp.Enabled = False;
1577 }
1578
1579 //
1580 // Function DisplayShift&()
1581 // Dim X&, Y&, A&, B&, iX&, iiX&, LD&
1582 // Dim Sprite&
1583 //  DisplayShift = 0
1584 //    For A = 0 To picPane.ScaleWidth
1585 //      For Y = DisplayMinY To DisplayMaxY
1586 //        For X = DisplayMinX To DisplayMaxX
1587 //          iX = StretchWidth * X + A
1588 //          Sprite = Field(X, Y).SpritePos
1589 //          If picPane.ScaleWidth < (iX + 1) Then
1590 //            iX = iX - picPane.ScaleWidth
1591 //          Else
1592 //            If picPane.ScaleWidth < (iX + 1 + BaseWidth) Then
1593 //              iiX = iX - picPane.ScaleWidth
1594 //              Sprites.BitBltSprite picPane.hdc, iiX, StretchWidth * Y, Sprite
1595 //            End If
1596 //          End If
1597 //          Sprites.BitBltSprite picPane.hdc, iX, StretchWidth * Y, Sprite
1598 //        Next X
1599 //      Next Y
1600 //      DisplayShift = DisplayShift + 1
1601 //      'DoEvents
1602 //    Next A
1603 // End Function
1604
1605 static void Form_Paint()
1606 {
1607   // Debug.Print "Form_Paint()"
1608 }
1609
1610 static void Form_Resize()
1611 {
1612   long Space, NW, NH;
1613   int Tmp;
1614
1615   if (WindowState == vbMinimized || ! Loaded)
1616     return;
1617
1618   Space = Panel.left;
1619   //  NW = ScaleWidth - 2 * Space: If NW < 0 Then NW = 0
1620   //  NH = ScaleHeight - 3 * Space - cmbLevel.Height: If NH < 0 Then NH = 0
1621   //  picViewPort.Move Space, Space, NW, NH
1622   Tmp = (ShowPanel != 0 ? ScaleHeight - Panel.Height : ScaleHeight);
1623   if (Tmp < 0)
1624     Tmp = 0;
1625
1626   picViewPort.Move 0, 0, ScaleWidth, Tmp;
1627   //  Tmp = 2 * Space + picViewPort.Height
1628   Panel.top = Tmp;
1629   Panel.left = (ScaleWidth - Panel.Width) / 2;
1630   //  'cmdNormal.Top = 2 * Space + picViewPort.Height
1631   //  cmbLevel.Top = Tmp
1632   //  lblRedDiskCount.Top = Tmp
1633   //  lblInfoCount.Top = Tmp
1634   //  picKeys.Top = Tmp
1635   //  lblFrameCount.Top = Tmp
1636   //  cmdPlayAll.Top = Tmp
1637 }
1638
1639 #endif
1640
1641 static void DrawFrame(int Delta)
1642 {
1643   int i, LX, tY, RX, BY;
1644
1645   LX = -1 + Delta;
1646   tY = -1 + Delta;
1647   RX = FieldWidth - Delta;
1648   BY = FieldHeight - Delta;
1649   DrawSprite(LX, tY, posFrameCorner);
1650   DrawSprite(LX, BY, posFrameCorner);
1651   DrawSprite(RX, tY, posFrameCorner);
1652   DrawSprite(RX, BY, posFrameCorner);
1653   for (i = LX + 1; i <= RX - 1; i++)
1654   {
1655     DrawSprite(i, tY, posFrameHorizontal);
1656     DrawSprite(i, BY, posFrameHorizontal);
1657   }
1658
1659   for (i = tY + 1; i <= BY - 1; i++)
1660   {
1661     DrawSprite(LX, i, posFrameVertical);
1662     DrawSprite(RX, i, posFrameVertical);
1663   }
1664 }
1665
1666 static void RestoreFrame()
1667 {
1668   int i, LX, tY, RX, BY;
1669
1670   LX = 0;
1671   tY = 0;
1672   RX = FieldWidth - 1;
1673   BY = FieldHeight - 1;
1674   for (i = LX; i <= RX; i++)
1675   {
1676     DrawField(i, tY);
1677     DrawField(i, BY);
1678   }
1679
1680   for (i = tY + 1; i <= BY - 1; i++)
1681   {
1682     DrawField(LX, i);
1683     DrawField(RX, i);
1684   }
1685 }
1686
1687 #if 0
1688
1689 static void Form_Unload(int Cancel)
1690 {
1691   EndFlag = True;
1692   ExitToMenuFlag = 1;
1693   if (cmdPlayAll.STRING_IS_LIKE(Caption, "Quit*"))
1694   {
1695     cmdPlayAll_Click();
1696   }
1697
1698   if (menEdit.Checked)
1699     menEdit_Click();
1700
1701   if (ModifiedFlag)
1702   {
1703     char *Msg;
1704     VbMsgBoxResult Res;
1705
1706     Msg = "Save changes to " & GetFileNameToSave() & " ?";
1707     Res = MsgBox(Msg, vbYesNoCancel, AppTitle & " - closing");
1708     if (Res == vbCancel)
1709     {
1710       Cancel = -1;
1711       return;
1712     }
1713
1714     if (Res == vbYes)
1715     {
1716       if (FileExists(OrigPath) && menSave.Enabled)
1717       {
1718         menSave_Click();
1719       }
1720       else
1721       {
1722         menSaveAs_Click();
1723       }
1724     }
1725   }
1726
1727   if (FileExists(TmpPath) || ModifiedFlag)
1728   {
1729     MayKill(TmpPath);
1730     CurPath = OrigPath;
1731   }
1732
1733   ReleaseDirectDraw();
1734   SaveSettings();
1735   End;
1736 }
1737
1738 static void fpsTim_Timer()
1739 {
1740   currency TickDiff;
1741   static int count5 = 0;
1742
1743   count5 = count5 + 1;
1744   if (4 < count5)
1745   {
1746     TickDiff = T.TickDiffUS(LastTick);
1747     lblFps.Caption = CLng(Round((1000000 * (TimerVar - LastFrame)) / (TickDiff), 0));
1748     LastFrame = TimerVar;
1749     LastTick = T.TickNow();
1750     count5 = 0;
1751   }
1752
1753   // If NoDisplayFlag Then lblFrameCount = TimerVar
1754   lblFrameCount = TimerVar;
1755 }
1756
1757 static void menAbout_Click()
1758 {
1759   frmSplash.Show vbModal, Me;
1760 }
1761
1762 static void menAutoScroll_Click()
1763 {
1764   {
1765     menAutoScroll.Checked = ! menAutoScroll.Checked;
1766     AutoScrollFlag = menAutoScroll.Checked;
1767   }
1768 }
1769
1770 #endif
1771
1772 static void menBorder_Click()
1773 {
1774   if (menBorder.Checked)
1775   {
1776     menBorder.Checked = False;
1777     DisplayMinX = 1;
1778     DisplayMaxX = FieldWidth - 2;
1779     DisplayWidth = FieldWidth;
1780     DisplayMinY = 1;
1781     DisplayMaxY = FieldHeight - 2;
1782     DisplayHeight = FieldHeight;
1783
1784     if (Loaded && LevelLoaded)
1785       DrawFrame(1);
1786
1787   }
1788   else
1789   {
1790     menBorder.Checked = True;
1791     DisplayMinX = 0;
1792     DisplayMaxX = FieldWidth - 1;
1793     DisplayWidth = FieldWidth + 2;
1794     DisplayMinY = 0;
1795     DisplayMaxY = FieldHeight - 1;
1796     DisplayHeight = FieldHeight + 2;
1797
1798     if (Loaded && LevelLoaded)
1799       RestoreFrame();
1800   }
1801
1802   ReStretch(Stretch);
1803   // DisplayLevel True
1804 }
1805
1806 void SetDisplayRegion()
1807 {
1808   if (! menBorder.Checked)
1809   {
1810     DisplayMinX = 1;
1811     DisplayMaxX = FieldWidth - 2;
1812     DisplayWidth = FieldWidth;
1813     DisplayMinY = 1;
1814     DisplayMaxY = FieldHeight - 2;
1815     DisplayHeight = FieldHeight;
1816
1817     if (LevelLoaded)
1818       DrawFrame(1);
1819
1820   }
1821   else
1822   {
1823     DisplayMinX = 0;
1824     DisplayMaxX = FieldWidth - 1;
1825     DisplayWidth = FieldWidth + 2;
1826     DisplayMinY = 0;
1827     DisplayMaxY = FieldHeight - 1;
1828     DisplayHeight = FieldHeight + 2;
1829
1830     if (LevelLoaded)
1831       RestoreFrame();
1832   }
1833 }
1834
1835 #if 0
1836
1837 static void menCopy_Click()
1838 {
1839   FMark.Copy;
1840 }
1841
1842 void menEdit_Click()
1843 {
1844   long L;
1845
1846   if (menEdit.Checked)
1847   {
1848     menEdit.Checked = False;
1849     // leave edit mode
1850     if (EditFlag)
1851       Unload ToolBox;
1852
1853     EditFlag = False;
1854     UnEdAll();
1855     FMark.ShowMarker False;
1856     picViewPort.MousePointer = 0;
1857     if (ModifiedFlag)
1858     {
1859       if (! STRING_IS_LIKE(CurPath, TmpPath))
1860       {
1861         OrigPath = CurPath;
1862         CurPath = TmpPath;
1863       }
1864
1865       SaveMPX(TmpPath);
1866     }
1867
1868     DisplayLevel();
1869     Stage.Blt();
1870   }
1871   else
1872   {
1873     if (! LevelLoaded)
1874     {
1875       Beep();
1876       return;
1877     }
1878
1879     if (ModifiedFlag)
1880     {
1881       if (! STRING_IS_LIKE(CurPath, TmpPath))
1882       {
1883         OrigPath = CurPath;
1884         CurPath = TmpPath;
1885       }
1886
1887       SaveMPX(TmpPath);
1888     }
1889
1890     subFetchAndInitLevel();
1891     menEdit.Checked = True;
1892     // enter edit mode
1893     EditFlag = True;
1894     // ScaleMode = vbTwips
1895     ToolBox.Move (Width - ToolBox.Width) / 2, Height - ToolBox.Height;
1896     // ScaleMode = vbPixels
1897     //    L = GetWindowLong(ToolBox.hWnd, GWL_STYLE)
1898     //    L = L And (Not WS_POPUP)
1899     //    L = L Or WS_CHILD
1900     //    SetWindowLong ToolBox.hWnd, GWL_STYLE, L
1901     //    SetParent ToolBox.hWnd, hWnd
1902     ToolBox.Show vbModeless, Me;
1903     EdAll();
1904     DisplayLevel();
1905     Stage.Blt();
1906     FMark.ShowMarker True;
1907   }
1908 }
1909
1910 static void menEnOff_Click()
1911 {
1912   menEnOn.Checked = False;
1913   menEnOff.Checked = True;
1914   SpSaveMenu();
1915   SpLoadMenu();
1916 }
1917
1918 static void menEnOn_Click()
1919 {
1920   menEnOn.Checked = True;
1921   menEnOff.Checked = False;
1922   SpSaveMenu();
1923   SpLoadMenu();
1924 }
1925
1926 static void menExit_Click()
1927 {
1928   Unload Me;
1929 }
1930
1931 static void menFaster_Click()
1932 {
1933   int i;
1934
1935   if (! bPlaying)
1936   {
1937     Debug.Assert(False);
1938     return;
1939   }
1940
1941   if (DemoFlag != 0) // demoplayback
1942   {
1943     i = GetSpeedIndex(DeltaTDemo);
1944     i = i - 1;
1945     If i < 2 Then i = 2;
1946     menDemoSpeed_Click (i);
1947   }
1948   else
1949   {
1950     i = GetSpeedIndex(DeltaTPlay);
1951     i = i - 1;
1952     If i < 2 Then i = 2;
1953     menPlaySpeed_Click (i);
1954   }
1955 }
1956
1957 static void menSlower_Click()
1958 {
1959   int i;
1960
1961   if (! bPlaying)
1962   {
1963     Debug.Assert(False);
1964     return;
1965   }
1966
1967   if (DemoFlag != 0) // demoplayback
1968   {
1969     i = GetSpeedIndex(DeltaTDemo);
1970     i = i + 1;
1971     If nSpeedCount < i Then i = nSpeedCount;
1972     menDemoSpeed_Click (i);
1973   }
1974   else
1975   {
1976     i = GetSpeedIndex(DeltaTPlay);
1977     i = i + 1;
1978     If nSpeedCount < i Then i = nSpeedCount;
1979     menPlaySpeed_Click (i);
1980   }
1981 }
1982
1983 void menPlaySpeed_Click(int Index)
1984 {
1985   int i;
1986
1987   //  If NoDisplayFlag And (GameLoopRunning <> 0) Then
1988   //    NoDisplayFlag = False
1989   //    DisplayLevel
1990   //  End If
1991   //  NoDisplayFlag = False
1992   for (i = menPlaySpeed.LBound; i <= menPlaySpeed.UBound; i++)
1993   {
1994     {
1995       menPlaySpeed(i).Checked = (Index == i);
1996     }
1997   }
1998
1999   BlockingSpeed = False;
2000   DeltaTPlay = SpeedsByDelayUS[Index];
2001   UpdateDeltaT();
2002   //  If DeltaTPlay < 0 Then
2003   //    Stage.Blt
2004   //    DeltaT = 0
2005   //    NoDisplayFlag = True
2006   //  End If
2007 }
2008
2009 void menDemoSpeed_Click(int Index)
2010 {
2011   int i;
2012
2013   //  If NoDisplayFlag And (GameLoopRunning <> 0) Then
2014   //    NoDisplayFlag = False
2015   //    DisplayLevel
2016   //  End If
2017   NoDisplayFlag = False;
2018   for (i = menDemoSpeed.LBound; i <= menDemoSpeed.UBound; i++)
2019   {
2020     {
2021       menDemoSpeed(i).Checked = (Index == i);
2022     }
2023   }
2024
2025   BlockingSpeed = False;
2026   DeltaTDemo = SpeedsByDelayUS[Index];
2027   UpdateDeltaT();
2028   //  If DeltaTPlay < 0 Then
2029   //    Stage.Blt
2030   //    DeltaT = 0
2031   //    NoDisplayFlag = True
2032   //  End If
2033 }
2034
2035 static void UpdateDeltaT()
2036 {
2037   if (! bPlaying)
2038     return;
2039
2040   DeltaT = (DemoFlag != 0 ? DeltaTDemo : DeltaTPlay);
2041   if (DeltaT < 0)
2042   {
2043     Stage.Blt();
2044     DeltaT = 0;
2045     NoDisplayFlag = True;
2046   }
2047   else
2048   {
2049     if (NoDisplayFlag && GameLoopRunning != 0)
2050     {
2051       NoDisplayFlag = False;
2052       DisplayLevel();
2053     }
2054     else
2055     {
2056       NoDisplayFlag = False;
2057     }
2058   }
2059 }
2060
2061 static void menGravOff_Click()
2062 {
2063   menGravOn.Checked = False;
2064   menGravOff.Checked = True;
2065   SpSaveMenu();
2066   SpLoadMenu();
2067 }
2068
2069 static void menGravOn_Click()
2070 {
2071   menGravOn.Checked = True;
2072   menGravOff.Checked = False;
2073   SpSaveMenu();
2074   SpLoadMenu();
2075 }
2076
2077 static void menNew_Click()
2078 {
2079   NewForm.Show vbModal, Me;
2080   CreateLevel(FieldWidth, FieldHeight);
2081   ReStretch(Stretch);
2082 }
2083
2084 static void menNewStd_Click()
2085 {
2086   CreateLevel(60, 24);
2087   ReStretch(Stretch);
2088 }
2089
2090 static void menOpen_Click()
2091 {
2092   long LFilt;
2093
2094   {
2095     // cmDlg.DefaultExt = "sp"
2096
2097     /*
2098
2099     (prevent compiler warning here due to suspected use of trigraph)
2100
2101     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";
2102     */
2103
2104     LFilt = LastOpenFilter;
2105     cmDlg.FilterIndex = (0 < LFilt & LFilt < 5 ? LFilt : 1);
2106     if (FileExists(CurPath))
2107       cmDlg.InitDir = WithSlash(StripDir(CurPath));
2108
2109     cmDlg.flags = cdlOFNHideReadOnly | cdlOFNLongNames;
2110   }
2111
2112   // --- On Error GoTo menOpenEH
2113   cmDlg.ShowOpen;
2114   // --- On Error GoTo 0
2115
2116   LFilt = cmDlg.FilterIndex;
2117   LastOpenFilter = LFilt;
2118   CurPath = cmDlg.FileName;
2119   OrigPath = CurPath;
2120   FillFileList (CurPath);
2121
2122 menOpenEH:
2123 }
2124
2125 static void menOptions_Click()
2126 {
2127   OptionsForm oFrm;
2128
2129   oFrm.Show vbModal, Me;
2130   SaveSettings();
2131   picViewPort_Resize();
2132 }
2133
2134 static void menPanel_Click()
2135 {
2136   {
2137     PanelVisible = ! menPanel.Checked;
2138   }
2139 }
2140
2141 void Let_PanelVisible(boolean NewVal)
2142 {
2143   static boolean HidePanel = False;
2144
2145   if (HidePanel != NewVal)
2146     return;
2147
2148   HidePanel = ! NewVal;
2149   PanelTim.Enabled = True;
2150 }
2151
2152 static void DrawPauseLayer(long Layer)
2153 {
2154   DirectDrawPalette Pal;
2155   PALETTEENTRY *Val;
2156   long i;
2157
2158   // Dim X&, Y&
2159   //  For Y = 0 To bmpStage.Height Step BaseWidth
2160   //    For X = 0 To bmpStage.Width Step BaseWidth
2161   //      Pause.TransparentDraw bmpStageHDC, X, Y, Layer
2162   //    Next X
2163   //  Next Y
2164   //  With Stage.Surface
2165   //    Set Pal = .GetPalette
2166   //    for i=1 to pal.GetEntries(
2167   //  Stage.Surface.SetPalette
2168 }
2169
2170 static void menPaste_Click()
2171 {
2172   FMark.Paste;
2173   DisplayLevel();
2174   Stage.Blt();
2175 }
2176
2177 static void menPause_Click()
2178 {
2179   static StdPicture OldPic;
2180   static char *OldText = 0;
2181
2182   PauseMode = (PauseMode != 0 ? 0 : 1);
2183   if (PauseMode != 0)
2184   {
2185     if (IS_NOTHING(&OldPic, sizeof(OldPic)))
2186       OldPic = cmdPause.Picture;
2187
2188     cmdPause.Picture = cmdPause.DownPicture;
2189     OldText = lblStatus.Caption;
2190     lblStatus = "Paused ...";
2191   }
2192   else
2193   {
2194     cmdPause.Picture = OldPic;
2195     lblStatus.Caption = OldText;
2196   }
2197 }
2198
2199 static void menPlayAll_Click()
2200 {
2201   long iMin, iMax, i;
2202   int FNum;
2203   char *LogPath, *OutStr, *ReRecPath, *SPPath;
2204   boolean bEqual;
2205   static boolean QuitFlag = False;
2206
2207   if (cmdPlayAll.STRING_IS_LIKE(Caption, "Play) All Demos")
2208   {
2209     cmdPlayAll.Caption = "Quit All";
2210     menPlayAll.Caption = "Quit All";
2211     FocusTim.Enabled = True;
2212     QuitFlag = False;
2213     iMin = 0;
2214     iMax = cmbFile.ListCount - 1;
2215     LogPath = StripDir(CurPath) & "/Error.Log";
2216     if (Dir(LogPath) != "")
2217       Kill(LogPath);
2218
2219     for (i = iMin; i <= iMax; i++)
2220     {
2221       cmbFile.ListIndex = i;
2222       //      If CurPath Like "*.sp" Or CurPath Like "*.mpx" Then
2223       if (DemoAvailable)
2224       {
2225         SPPath = CurPath;
2226         ReRecPath = SPPath & ".ReRec";
2227         menPlayDemo_Click();
2228         // SaveSP ReRecPath
2229         // bEqual = FilesEqual(ReRecPath, SPPath)
2230         // If bEqual Then MayKill ReRecPath
2231         bEqual = True;
2232         OutStr = cmbFile.List(i) & " -> ";
2233         //
2234         if (Val(lblFrameCount) != GetTotalFramesOfDemo())
2235         {
2236           OutStr = OutStr & "Error in GetTotalFramesOfDemo()! ";
2237           Debug.Assert(False);
2238         }
2239
2240         //
2241         if ((LevelStatus == 1) && bEqual)
2242         {
2243           OutStr = OutStr & "Success";
2244         }
2245         else if (QuitFlag)
2246         {
2247           OutStr = OutStr & "All Demos (float)Canceled";
2248         }
2249         else
2250         {
2251           if (LevelStatus != 1)
2252           {
2253             OutStr = OutStr & "### Level Failed ### (TimerVar == " & TimerVar & ")";
2254           }
2255
2256           if (! bEqual)
2257           {
2258             OutStr = OutStr & "### ReRecording is binary different ###";
2259           }
2260         }
2261
2262         FNum = FreeFile();
2263         FNum = fopen(LogPath, "ab");
2264         Print #FNum, OutStr;
2265         fclose(FNum);
2266         if (QuitFlag)
2267           break;
2268       }
2269     }
2270
2271     cmdPlayAll.Caption = "Play All Demos";
2272     menPlayAll.Caption = "Play All Demos";
2273     SettingsObject Settings;
2274
2275     MySignature = Settings.Read("MySignature", "");
2276     FirstDemoByte = 0x81;
2277   }
2278   else
2279   {
2280     QuitFlag = True;
2281     if (menStop.Enabled)
2282       menStop_Click();
2283   }
2284 }
2285
2286 static void menRemSP_Click()
2287 {
2288   RemoveSP();
2289   SpLoadMenu();
2290 }
2291
2292 static void menRestoreBorder_Click()
2293 {
2294   RestoreBorder();
2295 }
2296
2297 static void menSave_Click()
2298 {
2299   if (! ModifiedFlag)
2300     return;
2301
2302   if (STRING_IS_LIKE(CurPath, TmpPath))
2303     CurPath = OrigPath;
2304
2305   if (STRING_IS_LIKE(CurPath, "") || STRING_IS_LIKE(CurPath, "*.dat"))
2306   {
2307     menSaveAs_Click();
2308     return;
2309   }
2310
2311   if (STRING_IS_LIKE(CurPath, "*.sp"))
2312   {
2313     menSaveAs_Click();
2314     return;
2315   }
2316
2317   if (! FileExists(CurPath) || STRING_IS_LIKE(CurPath, "Untitled"))
2318   {
2319     menSaveAs_Click();
2320     return;
2321   }
2322
2323   SaveMPX(CurPath);
2324   Let_ModifiedFlag(False);
2325 }
2326
2327 static void menSaveAs_Click()
2328 {
2329   if (SaveAs())
2330     FillFileList (CurPath);
2331 }
2332
2333 static boolean SaveAs()
2334 {
2335   static boolean SaveAs;
2336
2337   char *FN;
2338   SettingsObject s;
2339
2340   SaveAs = False;
2341   {
2342     // cmDlg.DefaultExt = "sp"
2343     cmDlg.Filter = "MegaPlex Level (*.mpx)|*.mpx|SpeedFix Demo (*.sp)|*.sp";
2344     cmDlg.FilterIndex = LastSaveFilter;
2345     // If OrigPath Like "*.sp" Then cmDlg.FilterIndex = 1 Else cmDlg.FilterIndex = 0
2346     if (FileExists(OrigPath))
2347     {
2348       cmDlg.InitDir = WithSlash(StripDir(OrigPath));
2349       cmDlg.InitDir = s.Read("LastSaveDir", cmDlg.InitDir);
2350       cmDlg.FileName = StripExtensionlessFileName(GetFileNameToSave());
2351     }
2352
2353     cmDlg.flags = cdlOFNHideReadOnly | cdlOFNLongNames;
2354   }
2355
2356   // --- On Error GoTo SaveAsEH
2357   cmDlg.ShowSave;
2358   // --- On Error GoTo 0
2359
2360   LastSaveFilter = cmDlg.FilterIndex;
2361   FN = cmDlg.FileName;
2362   SettingsObject_Save("LastSaveDir", WithSlash(StripDir(FN)));
2363   if (STRING_IS_LIKE(FN, "*.sp"))
2364   {
2365     SaveSP(FN);
2366   }
2367   else if (STRING_IS_LIKE(FN, "*.mpx"))
2368   {
2369     SaveMPX(FN);
2370   }
2371
2372   Let_ModifiedFlag(False);
2373   SaveAs = True;
2374
2375 SaveAsEH:
2376
2377   return SaveAs;
2378 }
2379
2380 static void menSelectAll_Click()
2381 {
2382   FMark.SetPoint1 0, 0;
2383   FMark.SetPoint2 FieldWidth - 1, FieldHeight - 1;
2384 }
2385
2386 static void menShowLInfo_Click()
2387 {
2388   char *Msg;
2389
2390   Msg = LInfo.LevelTitle & vbNewLine & "(" & FieldWidth & " x " & FieldHeight & ")";
2391   if (DemoAvailable && bSignatureAvailable)
2392     Msg = Msg & vbNewLine & vbNewLine & gSignature;
2393
2394   SignatureForm.Signature = Msg;
2395   SignatureForm.DelayMS = 5000;
2396   int X, Y;
2397
2398   X = left + (Width - SignatureForm.Width) / 2;
2399   Y = top + (Height - SignatureForm.Height) / 2;
2400   SignatureForm.Move X, Y;
2401   SignatureForm.Show vbModeless, Me;
2402   Me.SetFocus;
2403 }
2404
2405 static void menSoundFX_Click()
2406 {
2407   {
2408     menSoundFX.Checked = ! menSoundFX.Checked;
2409     FXOnFlag = (menSoundFX.Checked ? -1 : 0);
2410   }
2411 }
2412
2413 #endif
2414
2415 // static void menPlay_Click()
2416 void menPlay_Click()
2417 {
2418 #if 0
2419
2420   boolean OldEditFlag;
2421
2422   // Trace "MainForm", "--> menPlay_Click()"
2423   if (! LevelLoaded)
2424   {
2425     Beep();
2426     return;
2427   }
2428
2429   SignatureForm.DelayMS = 1;
2430   menPlay.Enabled = False;
2431   menPause.Enabled = True;
2432   menStop.Enabled = True;
2433   cmdPlay.Enabled = False;
2434   cmdPause.Enabled = True;
2435   cmdStop.Enabled = True;
2436   cmdPlayDemo.Enabled = False;
2437   menPlayDemo.Enabled = False;
2438   cmdRecordDemo.Enabled = False;
2439   menRec.Enabled = False;
2440   menFaster.Enabled = True;
2441   menSlower.Enabled = True;
2442   if (cmdPlayAll.STRING_IS_LIKE(Caption, "Play*"))
2443   {
2444     cmdPlayAll.Enabled = False;
2445     menPlayAll.Enabled = False;
2446   }
2447
2448   cmbFile.Enabled = False;
2449   cmbLevel.Enabled = False;
2450   OldEditFlag = EditFlag;
2451   if (EditFlag)
2452     menEdit_Click();
2453
2454   menEditMain.Enabled = False;
2455   if (DemoFlag == 0 && RecordDemoFlag == 0)
2456     lblStatus = "Playing";
2457
2458   lblFrameCount = 0;
2459
2460 #endif
2461
2462   LastFrame = 0;
2463
2464 #if 0
2465   LastTick = T.TickNow();
2466 #endif
2467
2468 #if 0
2469   fpsTim.Enabled = True;
2470 #endif
2471
2472   // DimPrimary 100
2473   bPlaying = True;
2474
2475 #if 0
2476   UpdateDeltaT();
2477 #endif
2478
2479 #if 0
2480   printf("::: MainForm.c: menPlay_Click(): subFetchAndInitLevelB(): ...\n");
2481 #endif
2482
2483   subFetchAndInitLevelB();
2484
2485 #if 0
2486   printf("::: MainForm.c: menPlay_Click(): subFetchAndInitLevelB(): done\n");
2487 #endif
2488
2489   ReStretch(Stretch);
2490
2491   // Trace "MainForm", "CountDown 1"
2492   CountDown(2, (0 == DemoFlag));
2493   // Trace "MainForm", "Call GoPlay"
2494
2495   GoPlay();
2496
2497   // Trace "MainForm", "GoPlay returned"
2498
2499 #if 0
2500
2501   if (LevelStatus == 1)
2502   {
2503     lblStatus = "(float)Success";
2504   }
2505   else
2506   {
2507     lblStatus = "Try (float)again";
2508   }
2509
2510 #endif
2511
2512   // Trace "MainForm", "CountDown 1"
2513   CountDown(1, False);
2514   RecordDemoFlag = 0;
2515
2516 #if 0
2517   ShowKey(0);
2518 #endif
2519
2520   bPlaying = False;
2521   // Trace "MainForm", "Call subFetchAndInitLevel"
2522
2523   subFetchAndInitLevel();
2524
2525   // Trace "MainForm", "subFetchAndInitLevel returned"
2526
2527 #if 0
2528   Stage.Blt();
2529 #endif
2530
2531 #if 0
2532
2533   menEditMain.Enabled = True;
2534   if (OldEditFlag)
2535     menEdit_Click();
2536
2537   // Trace "MainForm", "<-- menPlay_Click()"
2538
2539 #endif
2540 }
2541
2542 #if 1
2543
2544 // static void menPlayDemo_Click()
2545 void menPlayDemo_Click()
2546 {
2547   DemoFlag = 1;
2548   RecordDemoFlag = 0;
2549
2550 #if 0
2551   lblStatus = "Demo Playback";
2552 #endif
2553
2554   menPlay_Click();
2555
2556 #if 1
2557   return;       /* return after initialization phase */
2558 #endif
2559
2560 #if 0
2561   if (LevelStatus != 1)
2562     lblStatus = "Demo Failed";
2563 #endif
2564
2565   DemoFlag = 0;
2566 }
2567
2568 #else
2569
2570 // static void menPlayDemo_Click()
2571 void menPlayDemo_Click()
2572 {
2573   DemoFlag = 1;
2574   RecordDemoFlag = 0;
2575
2576 #if 0
2577   lblStatus = "Demo Playback";
2578 #endif
2579
2580   menPlay_Click();
2581
2582 #if 0
2583   if (LevelStatus != 1)
2584     lblStatus = "Demo Failed";
2585 #endif
2586
2587   DemoFlag = 0;
2588 }
2589
2590 #endif
2591
2592 #if 0
2593
2594 static void menRec_Click()
2595 {
2596   Trace("MainForm", "--> menRec_Click()");
2597   if (! LevelLoaded)
2598   {
2599     Beep();
2600     return;
2601   }
2602
2603   RecordDemoFlag = 1;
2604   DemoFlag = 0;
2605   lblStatus.ForeColor = vbRed;
2606   lblStatus = "Recording Demo";
2607   // DemoBuffer = New DemoBufferObject; // (handle this later, if needed)
2608   Debug.Assert(! IS_NOTHING(&DemoBuffer, sizeof(DemoBuffer)));
2609   Trace("MainForm", "Call menPlayClick");
2610   menPlay_Click();
2611   Trace("MainForm", "menPlayClick returned");
2612
2613   lblStatus.ForeColor = vbButtonText;
2614   RecordDemoFlag = 0;
2615   Let_ModifiedFlag(True);
2616   if (! STRING_IS_LIKE(CurPath, TmpPath))
2617   {
2618     OrigPath = CurPath;
2619     CurPath = TmpPath;
2620   }
2621
2622   LInfo.DemoRandomSeed = RecDemoRandomSeed;
2623   Trace("MainForm", "Call SaveMPX(TmpPath)");
2624   SaveMPX(TmpPath);
2625   Trace("MainForm", "Set DemoBuffer == Nothing");
2626   SET_TO_NOTHING(&DemoBuffer, sizeof(DemoBuffer));
2627   Trace("MainForm", "Call subFetchAndInitLevel");
2628   subFetchAndInitLevel();
2629   cmdPlayDemo.Enabled = DemoAvailable;
2630   Trace("MainForm", "<-- menRec_Click()");
2631 }
2632
2633 static void menReRecordDemo_Click()
2634 {
2635   if (! LevelLoaded)
2636   {
2637     Beep();
2638     return;
2639   }
2640
2641   RecordDemoFlag = 1;
2642   DemoFlag = 1;
2643   lblStatus.ForeColor = vbRed;
2644   lblStatus = "ReRecording Demo";
2645   // DemoBuffer = New DemoBufferObject; // (handle this later, if needed)
2646   Debug.Assert(! IS_NOTHING(&DemoBuffer, sizeof(DemoBuffer)));
2647   menPlay_Click();
2648   lblStatus.ForeColor = vbButtonText;
2649   RecordDemoFlag = 0;
2650   Let_ModifiedFlag(True);
2651   if (! STRING_IS_LIKE(CurPath, TmpPath))
2652   {
2653     OrigPath = CurPath;
2654     CurPath = TmpPath;
2655   }
2656
2657   LInfo.DemoRandomSeed = RecDemoRandomSeed;
2658   SaveMPX(TmpPath);
2659   SET_TO_NOTHING(&DemoBuffer, sizeof(DemoBuffer));
2660   subFetchAndInitLevel();
2661 }
2662
2663 void menStop_Click()
2664 {
2665   EndFlag = True;
2666   LeadOutCounter = 1;
2667   if (PauseMode != 0)
2668     menPause_Click();
2669
2670   fpsTim.Enabled = False;
2671   fpsTim_Timer();
2672   lblFps.Caption = "";
2673   menRec.Enabled = True;
2674   menPlay.Enabled = True;
2675   menPause.Enabled = False;
2676   menStop.Enabled = False;
2677   cmdPlay.Enabled = True;
2678   cmdPause.Enabled = False;
2679   cmdStop.Enabled = False;
2680   cmdRecordDemo.Enabled = True;
2681   cmdPlayDemo.Enabled = DemoAvailable;
2682   cmdPlayAll.Enabled = DemosAvailable;
2683   menPlayDemo.Enabled = DemoAvailable;
2684   menPlayAll.Enabled = DemosAvailable;
2685   menFaster.Enabled = False;
2686   menSlower.Enabled = False;
2687   cmbFile.Enabled = True;
2688   cmbLevel.Enabled = True;
2689 }
2690
2691 static void menStretch_Click(int Index)
2692 {
2693   ReStretch(0.25 * Index);
2694   // DisplayLevel True
2695 }
2696
2697 static void menToolTips_Click()
2698 {
2699   {
2700     menToolTips.Checked = ! menToolTips.Checked;
2701     if (menToolTips.Checked)
2702     {
2703       cmdPlay.ToolTipText = "Play Game (Space)";
2704       cmdPause.ToolTipText = "Pause (P)";
2705       cmdStop.ToolTipText = "Stop (Q)";
2706       cmdPlayDemo.ToolTipText = "Play demo (Ctrl+Space)";
2707       cmdRecordDemo.ToolTipText = "Record demo (Ctrl+R)";
2708       lblInfoCount.ToolTipText = "Number of infotrons needed";
2709       lblRedDiskCount.ToolTipText = "Number of red disks";
2710       cmbLevel.ToolTipText = "List of all levels in the file";
2711       cmbFile.ToolTipText = "List of files in current directory";
2712       lblFps.ToolTipText = "Animation speed in fps";
2713       lblFrameCount.ToolTipText = "Game time in frames";
2714     }
2715     else
2716     {
2717       cmdPlay.ToolTipText = "";
2718       cmdPause.ToolTipText = "";
2719       cmdStop.ToolTipText = "";
2720       cmdPlayDemo.ToolTipText = "";
2721       cmdRecordDemo.ToolTipText = "";
2722       lblInfoCount.ToolTipText = "";
2723       lblRedDiskCount.ToolTipText = "";
2724       cmbLevel.ToolTipText = "";
2725       cmbFile.ToolTipText = "";
2726       lblFps.ToolTipText = "";
2727       lblFrameCount.ToolTipText = "";
2728     }
2729
2730   }
2731 }
2732
2733 static void menTrim_Click()
2734 {
2735   LevelInfoType Tmp;
2736   char *OldOPath;
2737
2738   OldOPath = OrigPath;
2739   Tmp = LInfo;
2740   Tmp.SpecialPortCount = 0; // hack: all special ports are deleted
2741   menCopy_Click();
2742   CreateLevel(FMark.Width, FMark.Height);
2743   LInfo = Tmp;
2744   OrigPath = OldOPath;
2745   CurPath = OldOPath;
2746   menSelectAll_Click();
2747   menPaste_Click();
2748   picViewPort_Resize();
2749 }
2750
2751 static void menZonkOff_Click()
2752 {
2753   menZonkOn.Checked = False;
2754   menZonkOff.Checked = True;
2755   SpSaveMenu();
2756   SpLoadMenu();
2757 }
2758
2759 static void menZonkOn_Click()
2760 {
2761   menZonkOn.Checked = True;
2762   menZonkOff.Checked = False;
2763   SpSaveMenu();
2764   SpLoadMenu();
2765 }
2766
2767 static void PanelTim_Timer()
2768 {
2769   int Tmp;
2770
2771   Tmp = Panel.Height;
2772   if (PanelSeq < Panel.Height && -1 < PanelSeq)
2773   {
2774     PanelSeq = (ShowPanel != 0 ? PanelSeq + 2 : PanelSeq - 2);
2775     Tmp = ScaleHeight - Tmp + PanelSeq;
2776     Panel.top = Tmp;
2777     picViewPort.Height = Tmp;
2778   }
2779   else
2780   {
2781     PanelTim.Enabled = False;
2782     PanelSeq = (PanelSeq < 0 ? 0 : PanelSeq - );
2783     ShowPanel = (ShowPanel == 0 ? 1 : 0);
2784     menPanel.Checked = (ShowPanel != 0);
2785   }
2786 }
2787
2788 static void picKeys_MouseUp(int Button, int Shift, float X, float Y)
2789 {
2790   FocusTim.Enabled = True;
2791 }
2792
2793 static void picMenu_Click()
2794 {
2795 }
2796
2797 static void picPane_KeyDown(int KeyCode, int Shift)
2798 {
2799   if (KeyCode < 0 || 255 < KeyCode)
2800     return;
2801
2802   KeyState[KeyCode] = True;
2803   switch (KeyCode)
2804   {
2805     case vbKeyControl:
2806       if (MouseButton == 0 && EditFlag)
2807         picPane.MousePointer = 15;
2808
2809       break;
2810
2811     case vbKeyUp:
2812     case vbKeyLeft:
2813     case vbKeyDown:
2814     case vbKeyRight:
2815     case vbKeySpace:
2816       if (DemoFlag != 0)
2817       {
2818         DemoFlag = 0;
2819         UpdateDeltaT();
2820       }
2821
2822       break;
2823
2824     case vbKeyF12:
2825       if (DemoFlag != 0 && 2 == Shift)
2826       {
2827         DemoFlag = 0;
2828         UpdateDeltaT();
2829       }
2830
2831       break;
2832
2833     case vbKeyF11:
2834       bCapturePane = ! bCapturePane;
2835       break;
2836   }
2837 }
2838
2839 static void picPane_KeyUp(int KeyCode, int Shift)
2840 {
2841   if (KeyCode < 0 || 255 < KeyCode)
2842     return;
2843
2844   KeyState[KeyCode] = False;
2845   switch (KeyCode)
2846   {
2847     case vbKeyPageUp:
2848       if (menFaster.Enabled)
2849         menFaster_Click();
2850
2851       break;
2852
2853     case vbKeyPageDown:
2854       if (menSlower.Enabled)
2855         menSlower_Click();
2856
2857       break;
2858
2859     case vbKeySpace:
2860       if (2 == Shift) // ctrl+space
2861       {
2862         if (menPlayDemo.Enabled)
2863           menPlayDemo_Click();
2864
2865       }
2866       else
2867       {
2868         if (menPlay.Enabled)
2869           menPlay_Click();
2870       }
2871
2872       break;
2873
2874     case vbKeyQ:
2875       if (menStop.Enabled)
2876         menStop_Click();
2877
2878       break;
2879
2880     case vbKeyR:
2881       if (menRec.Enabled)
2882         menRec_Click();
2883
2884       break;
2885
2886     case vbKeyP:
2887     case vbKeyPause:
2888       if (menPause.Enabled && (Shift == 0))
2889         menPause_Click();
2890
2891       break;
2892
2893     case vbKeyControl:
2894       if (MouseButton == 0 && EditFlag)
2895         picPane.MousePointer = 0;
2896       break;
2897   }
2898 }
2899
2900 static void picPane_MouseDown(int Button, int Shift, float X, float Y)
2901 {
2902   int OldEdMode;
2903
2904   MouseButton = Button;
2905   OldEdMode = EditMode;
2906   if (Button != 1)
2907   {
2908     if (Button == 2 && Shift != 2)
2909     {
2910       EditMode = edSelect;
2911     }
2912     else
2913     {
2914       return;
2915     }
2916   }
2917
2918   if (Shift == 2)
2919     EditMode = edMove;
2920
2921   OSX = ScrollX;
2922   OSY = ScrollY;
2923   MDX = X;
2924   MDY = Y;
2925   switch (EditMode)
2926   {
2927     case edMove:
2928       picPane.MousePointer = 5; // size
2929       UserDragFlag = True;
2930       break;
2931
2932     case edDraw:
2933       SetField(X, Y, ToolBox.ASpriteIndex);
2934       break;
2935
2936     case edSelect:
2937       FMark.SetPoint1 EdGetX(X), EdGetY(Y);
2938       FMark.MoveMarker;
2939       break;
2940   }
2941
2942   EditMode = OldEdMode;
2943 }
2944
2945 static void picPane_MouseMove(int Button, int Shift, float X, float Y)
2946 {
2947   boolean Oldflag;
2948   int OldEdMode;
2949
2950   OldEdMode = EditMode;
2951   if (Button != 1)
2952   {
2953     if (EditFlag && Button == 2 && Shift != 2)
2954     {
2955       EditMode = edSelect;
2956     }
2957     else
2958     {
2959       return;
2960     }
2961   }
2962
2963   if (Shift == 2)
2964     EditMode = edMove;
2965
2966   switch (EditMode)
2967   {
2968     case edMove:
2969       Oldflag = NoDisplayFlag;
2970       NoDisplayFlag = False;
2971       ScrollTo(OSX - X + MDX, OSY - Y + MDY);
2972       Stage.Blt();
2973       NoDisplayFlag = Oldflag;
2974       break;
2975
2976     case edDraw:
2977       SetField(X, Y, ToolBox.ASpriteIndex);
2978       break;
2979
2980     case edSelect:
2981       FMark.SetPoint2 EdGetX(X), EdGetY(Y);
2982       FMark.MoveMarker;
2983       break;
2984   }
2985
2986   EditMode = OldEdMode;
2987 }
2988
2989 static void picPane_MouseUp(int Button, int Shift, float X, float Y)
2990 {
2991   MouseButton = MouseButton ^ Button;
2992   picPane.MousePointer = 0;
2993   UserDragFlag = False;
2994   if (menEditMain.Enabled && Button == 2)
2995   {
2996     if (MDX == X && MDY == Y)
2997       PopupMenu menEditMain;
2998   }
2999 }
3000
3001 #endif
3002
3003 static void picPane_Paint()
3004 {
3005   boolean Oldflag;
3006
3007   Oldflag = NoDisplayFlag;
3008   NoDisplayFlag = False;
3009
3010 #if 0
3011   Stage.Blt();
3012 #endif
3013
3014   NoDisplayFlag = Oldflag;
3015 }
3016
3017 static void ReStretch(float NewStretch)
3018 {
3019 #if 1
3020   long BW2, LW, LH;
3021 #else
3022   long BW2, LW, LH, i;
3023 #endif
3024
3025 #if 0
3026   printf("::: MainForm.c: ReStretch(): %d, %d\n", Loaded, LevelLoaded);
3027 #endif
3028
3029   if (! Loaded)
3030   {
3031 #if 0
3032     printf("::: NewStretch == %f\n", NewStretch);
3033 #endif
3034
3035     Stretch = NewStretch;
3036     return;
3037   }
3038
3039 #if 0
3040   MousePointer = 11;
3041   SET_TO_NOTHING(&Stage, sizeof(Stage));
3042   SET_TO_NOTHING(&StretchedSprites, sizeof(StretchedSprites));
3043   menStretch(Stretch / 0.25).Checked = False;
3044 #endif
3045
3046   Stretch = NewStretch;
3047
3048 #if 0
3049   menStretch(Stretch / 0.25).Checked = True;
3050   //  StretchWidth = BaseWidth ' * NewStretch
3051   //  StretchWidth2 = StretchWidth \ 2
3052   //  TwoPixels = 2 '* Stretch
3053   // StretchLoad Sprites, imgMpx.Picture, 16, 16
3054 #endif
3055
3056   BW2 = StretchWidth / 2;
3057   LW = (FieldWidth + 2) * BaseWidth; // StretchWidth
3058   LH = (FieldHeight + 2) * BaseWidth; // StretchWidth
3059
3060 #if 0
3061   // i = bmpStage.CreateAtSize(LW, LH)
3062   // Stage = New DDScrollBuffer; // (handle this later, if needed)
3063   i = Stage.CreateAtSize(LW, LH, picPane.hWnd);
3064   // Set StretchedSprites = NormalSprites.GetStretchCopy(Stretch)
3065   ReLoadStretchSprites();
3066   if (i == 0 || IS_NOTHING(&StretchedSprites, sizeof(StretchedSprites)))
3067   {
3068     // menStretch(Stretch / 0.5).Enabled = False
3069     if (0.5 <= Stretch)
3070       ReStretch(Stretch - 0.25);
3071
3072   }
3073   else
3074 #endif
3075   {
3076     StretchedSprites.DestXOff = 1 * BaseWidth; // StretchWidth
3077     StretchedSprites.DestYOff = 1 * BaseWidth; // StretchWidth
3078     Stage.DestXOff = 1 * StretchWidth;
3079     Stage.DestYOff = 1 * StretchWidth;
3080     StretchedSprites.DestinationSurface = Stage.Surface;
3081
3082 #if 0
3083     Stage.Cls();
3084 #endif
3085
3086     if (Loaded && LevelLoaded)
3087     {
3088 #if 0
3089       printf("::: MainForm.c: ReStretch(): ...\n");
3090 #endif
3091
3092       SetDisplayRegion();
3093       picViewPort_Resize();
3094       DisplayLevel();
3095     }
3096
3097     subCalculateScreenScrollPos();
3098
3099 #if 0
3100   printf("::: MainForm.c: ReStretch(): %d, %d\n", ScreenScrollXPos, ScreenScrollYPos);
3101 #endif
3102
3103     ScrollTo(ScreenScrollXPos, ScreenScrollYPos);
3104
3105 #if 0
3106     Stage.Blt();
3107 #endif
3108
3109     picPane_Paint();
3110   }
3111
3112 #if 0
3113   MousePointer = 0;
3114 #endif
3115 }
3116
3117 static void SetScrollEdges()
3118 {
3119 #if 0
3120   printf("::: MainForm.c: SetScrollEdges() ... [%ld, %ld, %ld, %ld] [%f, %d] [%d, %d, %d, %d]\n",
3121          DisplayMinX, DisplayMinY, DisplayMaxX, DisplayMaxY,
3122          Stretch, BaseWidth,
3123          ScrollMinX, ScrollMinY, ScrollMaxX, ScrollMaxY);
3124 #endif
3125
3126   ScrollMinX = (int)(DisplayMinX - 0.5) * Stretch * BaseWidth;
3127   ScrollMinY = (int)(DisplayMinY - 0.5) * Stretch * BaseWidth;
3128   ScrollMaxX = (int)(DisplayMaxX + 1.5) * Stretch * BaseWidth - picPane.Width;
3129   ScrollMaxY = (int)(DisplayMaxY + 1.5) * Stretch * BaseWidth - picPane.Height;
3130
3131 #if 0
3132   printf("::: MainForm.c: SetScrollEdges() done [%d, %d, %d, %d]\n",
3133          ScrollMinX, ScrollMinY, ScrollMaxX, ScrollMaxY);
3134 #endif
3135 }
3136
3137 void DrawField(int X, int Y)
3138 {
3139   int Tmp, tsi;
3140
3141   tsi = GetSI(X, Y);
3142   Tmp = LowByte(PlayField16[tsi]);
3143   if (40 < Tmp)
3144     Tmp = 0;
3145
3146   if (Tmp == fiRAM || Tmp == fiHardWare)
3147     Tmp = DisPlayField[tsi];
3148
3149   if (Tmp == fiBug || Tmp == 40)
3150     Tmp = DisPlayField[tsi];
3151
3152   if (EditFlag)
3153   {
3154     if (fiOrangeDisk < Tmp && Tmp < fiSnikSnak)
3155       Tmp = DisPlayField[tsi];
3156   }
3157
3158   StretchedSprites.BltEx(StretchWidth * X, StretchWidth * Y, Tmp);
3159 }
3160
3161 void DrawFieldAnimated(int X, int Y)
3162 {
3163   int Tmp, tsi;
3164
3165   tsi = GetSI(X, Y);
3166   Tmp = LowByte(PlayField16[tsi]);
3167   switch (Tmp)
3168   {
3169     case fiSnikSnak:
3170       subDrawAnimatedSnikSnaks(tsi);
3171       break;
3172
3173     case fiElectron:
3174       subDrawAnimatedElectrons(tsi);
3175       break;
3176
3177     default:
3178       //      If 40 < Tmp Then Tmp = 0
3179       //      If Tmp = fiRAM Or Tmp = fiHardWare Then Tmp = DisPlayField(tsi)
3180       //      If Tmp = fiBug Or Tmp = 40 Then Tmp = DisPlayField(tsi)
3181       //      If EditFlag Then
3182       //        If fiOrangeDisk < Tmp And Tmp < fiSnikSnak Then Tmp = DisPlayField(tsi)
3183       //      End If
3184       //      StretchedSprites.BltEx StretchWidth * X, StretchWidth * Y, Tmp
3185       break;
3186   }
3187 }
3188
3189 void DrawFieldNoAnimated(int X, int Y)
3190 {
3191   int Tmp, tsi;
3192
3193   tsi = GetSI(X, Y);
3194   Tmp = LowByte(PlayField16[tsi]);
3195   switch (Tmp)
3196   {
3197     case fiSnikSnak:
3198       StretchedSprites.BltEx(StretchWidth * X, StretchWidth * Y, fiSpace);
3199       break;
3200
3201     case fiElectron:
3202       StretchedSprites.BltEx(StretchWidth * X, StretchWidth * Y, fiSpace);
3203       break;
3204
3205     default:
3206       if (40 < Tmp)
3207         Tmp = 0;
3208
3209       if (Tmp == fiRAM || Tmp == fiHardWare)
3210         Tmp = DisPlayField[tsi];
3211
3212       if (Tmp == fiBug || Tmp == 40)
3213         Tmp = DisPlayField[tsi];
3214
3215       if (EditFlag)
3216       {
3217         if (fiOrangeDisk < Tmp && Tmp < fiSnikSnak)
3218           Tmp = DisPlayField[tsi];
3219       }
3220
3221 #if 0
3222       if (TEST_flag)
3223         printf("::: MainForm.c: DrawFieldNoAnimated(): %d, %d [%d]\n",
3224                X, Y, Tmp);
3225 #endif
3226
3227       StretchedSprites.BltEx(StretchWidth * X, StretchWidth * Y, Tmp);
3228       break;
3229   }
3230 }
3231
3232 void DrawSprite(int X, int Y, int SpritePos)
3233 {
3234   StretchedSprites.BltEx(StretchWidth * X, StretchWidth * Y, SpritePos);
3235 }
3236
3237 #if 0
3238
3239 void InvalidateRect(long XMin, long YMin, long XMax, long YMax)
3240 {
3241   long X, Y;
3242
3243   //  For Y = YMin To YMax
3244   //    For X = XMin To XMax
3245   //      Field(X, Y).GraphicsValid = 0
3246   //    Next X
3247   //  Next Y
3248 }
3249
3250 static void picViewPort_MouseUp(int Button, int Shift, float X, float Y)
3251 {
3252   FocusTim.Enabled = True;
3253 }
3254
3255 static void picViewPort_Paint()
3256 {
3257   // Debug.Print "picViewPort_Paint()"
3258 }
3259
3260 #endif
3261
3262 static void picViewPort_Resize()
3263 {
3264 #if 0
3265   long bdX, bdY, PanelVisibility;
3266   long X, Y, dx, dY;
3267   SettingsObject s;
3268   boolean B;
3269
3270   bdX = picFrame.Width - picFrame.ScaleWidth;
3271   bdY = picFrame.Height - picFrame.ScaleHeight;
3272   dx = Min(picViewPort.ScaleWidth - bdX, (DisplayWidth - 1) * Stretch * BaseWidth);
3273   dx = Max(dx, 0);
3274   dY = Min(picViewPort.ScaleHeight - bdX, (DisplayHeight - 1) * Stretch * BaseWidth);
3275   dY = Max(dY, 0);
3276   B = s.Read("LimitToOriginalFieldSize", False);
3277   PanelVisibility = 24 * (Panel.Height - PanelSeq - (float)1) / Panel.Height;
3278   if (B)
3279   {
3280     dx = Min(320 * Stretch, dx);
3281     dY = Min((200 - PanelVisibility) * Stretch, dY);
3282   }
3283
3284   X = Max((picViewPort.ScaleWidth - dx) / 2, 0);
3285   Y = Max((picViewPort.ScaleHeight - dY) / 2, 0);
3286   picPane.Move X, Y, dx, dY;
3287   picFrame.Move X - bdX / 2, Y - bdY / 2, dx + bdX, dY + bdY;
3288 #endif
3289
3290   SetScrollEdges();
3291
3292 #if 0
3293   printf("::: MainForm.c: picViewPort_Resize(): %d, %d\n", ScrollX, ScrollY);
3294 #endif
3295
3296   ScrollTo(ScrollX, ScrollY);
3297
3298   //  SizeTim.Interval = 1
3299 }
3300
3301 #if 0
3302
3303 //
3304 // Private Sub SizeTim_Timer()
3305 // Dim wdX&, wdY&
3306 //  SizeTim.Interval = 0
3307 //  wdX = Max(0, picViewPort.ScaleWidth - picPane.Width) * Screen.TwipsPerPixelX
3308 //  wdY = Max(0, picViewPort.ScaleHeight - picPane.Height) * Screen.TwipsPerPixelY
3309 //  If (0 < wdX) Or (0 < wdY) Then
3310 //    Move Left, Top, Width - wdX, Height - wdY
3311 //  End If
3312 // End Sub
3313
3314 static void LoadKeyIndicators()
3315 {
3316   int i;
3317
3318   picKeys.BackColor = vbButtonFace;
3319   for (i = 2; i <= 5; i++)
3320   {
3321     Load shpKey(i);
3322   }
3323
3324   for (i = 1; i <= 5; i++)
3325   {
3326     shpKey(i).FillColor = vbButtonFace;
3327     shpKey(i).Visible = True;
3328   }
3329
3330   shpKey(1).Move 7, 0;
3331   shpKey(2).Move 0, 7;
3332   shpKey(3).Move 7, 14;
3333   shpKey(4).Move 14, 7;
3334   shpKey(5).Move 7, 7;
3335 }
3336
3337 void ShowKey(int KeyVar)
3338 {
3339   boolean State[5 + 1];
3340   int i;
3341   boolean Tmp;
3342   long Col;
3343   static boolean LastState[5 + 1];
3344
3345   //  For i = 1 To 5
3346   //    State(i) = False
3347   //  Next i
3348   switch (KeyVar)
3349   {
3350     case 0:
3351       // do nothing
3352       break;
3353
3354     case Is < 5:
3355       State[KeyVar] = True;
3356       break;
3357
3358     default:
3359       State[5] = True;
3360       if (KeyVar < 9)
3361         State[KeyVar - 4] = True;
3362       break;
3363   }
3364
3365   for (i = 1; i <= 5; i++)
3366   {
3367     Tmp = State[i];
3368     if (Tmp ^ LastState[i])
3369     {
3370       Col = (i == 5 ? vbRed : vbGreen);
3371       shpKey(i).FillColor = (Tmp ? Col : vbButtonFace);
3372       shpKey(i).Refresh;
3373       LastState[i] = Tmp;
3374     }
3375   }
3376 }
3377
3378 static void GetSettings()
3379 {
3380   SettingsObject s;
3381   char *APath;
3382   long X, Y;
3383   int i;
3384   boolean Flag;
3385
3386   {
3387     // last file info
3388     APath = WithSlash(App.Path);
3389     CurPath = s.Read("LastPath", APath);
3390     OrigPath = CurPath;
3391     // window width and height
3392     X = s.Read("Width", Width);
3393     Y = s.Read("Height", Height);
3394     if (X < 0 Then X == 0: If Y < 0)
3395       Y = 0;
3396
3397     if (Screen.Width < X)
3398       X = Screen.Width;
3399
3400     if (Screen.Height < Y)
3401       Y = Screen.Height;
3402
3403     Width = X;
3404     Height = Y;
3405     // window position and state
3406     X = s.Read("Left", left);
3407     Y = s.Read("Top", top);
3408     if (X < 0 Then X == 0: If Y < 0)
3409       Y = 0;
3410
3411     if (Screen.Width < (X + Width))
3412       X = Screen.Width - Width;
3413
3414     if (Screen.Height < (Y + Height))
3415       Y = Screen.Height - Height;
3416
3417     left = X;
3418     top = Y;
3419     WindowState = s.Read("WinState", vbNormal);
3420     // flags/options
3421     Flag = s.Read("ShowToolTips", True);
3422     if (Flag)
3423       menToolTips_Click();
3424
3425     menBorder.Checked = ! CBool(s.Read("ShowBorder", False));
3426     Flag = CBool(s.Read("AutoScroll", True));
3427     if (! Flag)
3428     {
3429       AutoScrollFlag = False;
3430       menAutoScroll.Checked = False;
3431     }
3432
3433     Flag = CBool(s.Read("SoundFX", True));
3434     FXOnFlag = (Flag ? -1 : 0);
3435     menSoundFX.Checked = Flag;
3436     SignatureDelay = CLng(s.Read("SignatureDelay", 3000));
3437     AllowRedDiskCheat = CInt(s.Read("AllowRedDiskCheat", 1));
3438     AllowEatRightRedDiskBug = CInt(s.Read("AllowEatRightRedDiskBug", 1));
3439     MySignature = s.Read("MySignature", "");
3440     // speed
3441     X = s.Read("FrameDelayPlay", 1000000 / 35);
3442     i = GetSpeedIndex(X);
3443     menPlaySpeed_Click(i);
3444     X = s.Read("FrameDelayDemo", 1000000 / 35);
3445     i = GetSpeedIndex(X);
3446     menDemoSpeed_Click(i);
3447     // Zoom
3448     i = s.Read("Stretch", 4);
3449     if (i < menStretch.LBound || menStretch.UBound < i)
3450       i = 4;
3451
3452     menStretch_Click (i);
3453   }
3454 }
3455
3456 static void SaveSettings()
3457 {
3458   SettingsObject s;
3459   int i;
3460
3461   {
3462     s.Save "LastPath", (ModifiedFlag ? OrigPath : CurPath);
3463     if (WindowState != vbMinimized)
3464     {
3465       s.Save "Width", Width;
3466       s.Save "Height", Height;
3467       s.Save "Left", left;
3468       s.Save "Top", top;
3469       s.Save "WinState", WindowState;
3470     }
3471
3472     s.Save "ShowToolTips", menToolTips.Checked;
3473     s.Save "ShowBorder", menBorder.Checked;
3474     s.Save "AutoScroll", menAutoScroll.Checked;
3475     s.Save "SoundFX", menSoundFX.Checked;
3476     s.Save "SignatureDelay", SignatureDelay;
3477     s.Save "AllowRedDiskCheat", AllowRedDiskCheat;
3478     s.Save "AllowEatRightRedDiskBug", AllowEatRightRedDiskBug;
3479     s.Save "MySignature", MySignature;
3480     // speeds
3481     s.Save "FrameDelayPlay", DeltaTPlay;
3482     s.Save "FrameDelayDemo", DeltaTDemo;
3483     // zoom
3484     for (i = menStretch.LBound; i <= menStretch.UBound; i++)
3485     {
3486       if (menStretch(i).Checked)
3487         break;
3488     }
3489
3490     s.Save "Stretch", i;
3491     //    s.Save "",
3492   }
3493 }
3494
3495 void ReLoadStretchSprites()
3496 {
3497   long Tmp;
3498   BitMapObject NBMP, SBMP;
3499   char *tmpMpxBmp;
3500
3501   //  If Stretch = 1 Then
3502   MpxBmp = App.Path & "/Mpx.bmp";
3503   //  Else
3504   //    MpxBmp = App.Path & "\Mpx" & Stretch & ".bmp"
3505   //    tmpMpxBmp = App.Path & "\Mpx.bmp"
3506   //    If FileExists(MpxBmp) And FileExists(tmpMpxBmp) Then
3507   //      If FileDateTime(MpxBmp) < FileDateTime(tmpMpxBmp) Then
3508   //        MayKill MpxBmp
3509   //      End If
3510   //    End If
3511   //    If Not FileExists(MpxBmp) Then
3512   //      MousePointer = 11
3513   // //      Set NBMP = New BitMapObject // (handle this later, if needed)
3514   //      tmpMpxBmp = App.Path & "\Mpx.bmp"
3515   //      If Not FileExists(tmpMpxBmp) Then
3516   //        ReportError "ReLoadStretchSprites", "File not found: " & tmpMpxBmp
3517   //        MESSAGE_BOX("an error occured"); // MsgBox "File not found: " & tmpMpxBmp, vbCritical, "MegaPlex - Error"
3518   //        End
3519   //      End If
3520   //      NBMP.CreateFromFile tmpMpxBmp
3521   //      Set SBMP = NBMP.GetStretchCopy(Stretch)
3522   //      SBMP.SaveToFile MpxBmp
3523   //      Set NBMP = Nothing
3524   //      Set SBMP = Nothing
3525   //      MousePointer = 0
3526   //    End If
3527   //  End If
3528   // StretchedSprites = New DDSpriteBuffer; // (handle this later, if needed)
3529   if (! StretchedSprites.CreateFromFile(MpxBmp, 16, 16))
3530     SET_TO_NOTHING(&StretchedSprites, sizeof(StretchedSprites));
3531 }
3532
3533 void SaveSnapshot(currency Number)
3534 {
3535   char *Path;
3536
3537   Path = CAT(WithSlash(App.Path), "Capture");
3538   if (! IsDir(Path))
3539     MkDir(Path);
3540
3541   Path = Path & "\" & Format(Number, "00000000") & ".bmp";
3542   SavePicture CaptureWindow(picPane.hWnd, True, 0, 0, picPane.ScaleWidth, picPane.ScaleHeight), Path;
3543 }
3544
3545 #endif