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