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