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