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