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