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