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