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