D-Miner
100 rem $$chan=9
102 rem $$stak=30000
104 rem $$heap=2048
106 rem rem $$asmb=win2_rxt_snd_sound_bin,0,10
108 rem $$asmb=win4_TKS_TMR_TIMER_BIN,0,10
110 rem rem $$asmb=win1_prg_game_mine_ptrmen_cde,0,82
112 rem $$asmb=win1_prg_game_mine_MINES_BIN,0,10
114 :
116 EXT_PROC 'BUTFREE'
118 EXT_FN 'BUTUSE%', 'CFHOME$', 'CFNAME$', 'CFVER$', 'LIN2STR$'
120 EXT_FN 'MN_COLOUR', 'MN_CONFIG', 'MN_ERR', 'MN_GAME', 'MN_INFO'
122 EXT_FN 'MN_LOOK', 'MN_MINES', 'MN_NUMSEL', 'MN_QSEL', 'MN_SCORE'
124 EXT_FN 'MN_SPOTSEL', 'MN_TIMER', 'NAT2RGB'
126 EXT_FN 'SP_BLANK', 'SP_BOMB', 'SP_BOMBE', 'SP_BOMBX', 'SP_COOL'
128 EXT_FN 'SP_FLAG', 'SP_N', 'SP_OOOO', 'SP_SLEEP', 'SP_SMILE'
130 EXT_FN 'SP_SOUR', 'SP_SPOTN', 'SP_SQUARE', 'SP_TICK', 'SP_WINK'
132 EXT_FN 'TSTSSS%', 'TSTTHG%'
134 EXT_PROC 'TIMER_DISP', 'TIMER_KILL', 'TIMER_LED', 'TIMER_PAUSE'
136 EXT_PROC 'TIMER_SET', 'TIMER_START', 'TIMER_STOP', 'WL_DRAW_LED'
138 EXT_FN 'TIMER_INIT', 'TIMER_STATE%', 'TIMER_TIME%'
140 EXT_PROC 'KILLSOUND', 'SOUNDFILE'
142 :
144 rem Prepare two versions:
146 rem 1) Mines_bin, Timer_bin
148 rem 2) The above + sound_bin, ptrmen_cde
150 :
152 rem D-Miner
154 :
156 rem Minesweeper Qlone
158 rem ©pjwitte 2oo4++
160 rem V 0.25, 2023 May 27
162 :
164 rem If not compiled
166 IF PEEK$(\\-4, 4) = 'SBAS' THEN
168 LRESPR 'win1_prg_game_mine_mines_bin'
170 LRESPR 'win4_TKS_TMR_TIMER_BIN'
172 END IF
174 :
176 RESTORE
178 :
180 rem Constants
182 :
184 c0% = 0: c1% = 1: c2% = 2: c3% = 3: c4% = 4: c5% = 5
186 c6% = 6: c7% = 7: c8% = 8: c9% = 9: c10% = 10: cm1% = -1
188 nul$ = '': spc$ = ' ': esc% = 27: hsh$ = '#': bks$ = '\'
190 ok$ = 'Ok'
192 :
194 con$ = 'con_': scr$ = 'scr_'
196 on% = c1%: off% = c0%
198 :
200 sqsz% = 16: rem square size
202 spr% = -2
204 minx% = c9%: miny% = c9%: rem min size
206 :
208 sp_litemavabg% = 520: rem Loose item available background
210 sp_litemavafg% = 521: rem Loose item available foreground
212 sp_litemselbg% = 522: rem Loose item selected background
214 sp_litemselfg% = 523: rem Loose item selected foreground
216 sp_litemunabg% = 524: rem Loose item unavailable background
218 sp_litemunafg% = 525: rem Loose item unavailable foreground
220 sp_appbg% = 535: rem Application window background
222 sp_infwinbg% = 527: rem Information window background
224 sp_infwinfg% = 528: rem Information window foreground
226 sp_buthigh% = 548: rem Button highlight
228 sp_butbd% = 549: rem Button border
230 sp_butbg% = 550: rem Button background
232 sp_butfg% = 551: rem Button foreground
234 sp_errbg% = 556: rem Error message background
236 sp_errfg% = 557: rem Error message foreground
238 :
240 rem Init global variables
242 :
244 DIM prec%(16): rem pointer record
246 DIM tprec%(16): rem Temporary prec%
248 grdx% = c9%: grdy% = c9%: rem default initial size
250 mencon = 65536
252 tpause% = c0%: rem Technical pause flag
254 :
256 DIM game%(c2%, c5%)
258 FOR i% = c0% TO c2%
260 FOR j% = c0% TO c5%: READ game%(i%, j%)
262 END FOR i%
264 rem c x X y m t
266 DATA 0, 10, 1, 10, -1, -1: rem games 1..3
268 DATA 1, 15, 1, 15, -1, -1: rem Current
270 DATA 0, 20, 1, 20, -1, -1
272 DIM gameT$(c2%, c6%)
274 FOR i% = c0% TO c2%: READ gameT$(i%)
276 DATA 'Auto', 'Timer', 'None'
278 gameM$ = 'Auto'
280 :
282 DIM colour$(c3%, c6%)
284 FOR i% = 0 TO c3%: READ colour$(i%)
286 DATA 'Red','Green','Orange','Blue'
288 :
290 li_move% = -1: rem wmov button - internal
292 li_resz% = -2: rem resize button
294 li_zzz% = -3: rem zleep
296 li_quit% = -4: rem quit
298 li_new% = -5: rem new game
300 li_conf% = -6: rem config menu
302 li_stat% = -7: rem stats menu
304 li_game% = -8: rem game menu
306 li_help% = -9: rem help
308 li_info% =-10: rem about
310 :
312 redraw = 0
314 lost = -1: playing% = 0: won = 1: stopped = 2: paused = 3
316 game = stopped: laststate = game
318 tmi_use% = -4: rem Timer loose items
320 tmi_aut% = -5: rem Auto
322 tmi_cup% = -6: rem Count up
324 tmi_cdn% = -7: rem Countdown
326 tmi_lrc% = -14: rem Last record
328 tmi_dgs% = -8: rem Digits start
330 tmi_dge% = -13: rem Digits end
332 tmw_dg1% = 11: tmw_dg3% = 13: rem Timer digit windows 1..3
334 wmcnt% = c4%: rem Mine count window
336 wtime% = c2%: rem Timer window
338 mapp% = c1%: rem main application window
340 tvx% = 4 + 16: rem Escape termination vector
342 immediate% = 48: rem Immediate return
344 mvec% = 11: rem Normal
346 menv% = c1% + c8%: rem For colour picker
348 nsvi% = c4%: nsvo% = 32 + c4%: rem Term for NumSel
350 nstio% = 30: rem Key repeat delay for numsel
352 bomb% = c9%: rem Code for mine: 0 = blank, 1..8
354 events% = c1% + c2%: rem 1 => timed out, 2 => warning
356 tio% = cm1%: rem Timeout
358 tmr_chg = 0: rem Timer changed flag
360 changed = 0: rem Overall changed flag
362 butsx% = 64: butsy% = 14: rem Button
364 butsprx% = 48: butch = 0
366 but_vi% = 33: but_vo% = 17: rem Return vectors for button
368 mwtv% = 32: _w% = 16: rem MessWin stuff
370 hlpxs% = 480: hlpys% = 180: rem Help stuff
372 abtxs% = 186: abtys% = 60: abtcx% = 29 : rem About stuff
374 wrnxs% = 250: wrnys% = 60: rem Warn stuff
376 sx$ = '_ub': rem Sound file extension
378 hx$ = '_txt': rem Help file extension
380 mgDmnr$ = 'dmnr01': rem ID for config file
382 mgDmsc$ = 'dmsc01': rem ID for score files
384 :
386 rem Misc global variables
388 sqr$ = Spra$(sp_square): rem mawitem addr
390 rem xdim%, ydim% dimn + 1
392 rem xsize%, ysize%, xpos%, ypos%
394 rem maxx%, maxy% max grid size in squares
396 rem mcount%, mleft% mines
398 rem ch, ch% & ci, ci% channels
400 rem k, awn, m% item number, etc
402 rem status%(), mines%(), mines$()
404 rem dummy%, er%, st% throwaway
406 rem tmr_use%, tmr_id... timer
408 rem events%, eve%, ev% timer events
410 rem bfpresent button frame
412 rem butbf, butch, butx%, buty%, butsx%, butsy%
414 rem but_t%, but_s%
416 :
418 rem Initialise
420 :
422 rem Fail unless hicolor
424 hicol = 0
426 IF VER$ = 'HBA' THEN
428 IF VER$(c1%) >= '3.00' AND DISP_TYPE > c8%: hicol = 1
430 END IF
432 :
434 IF hicol = 0: PrePreWarn 'This program only runs in high colour mode!'
436 IF tstthg%("Menus") <> c0%: PrePreWarn 'This program NEEDS QMenu to run'
438 rem Establish home directory
440 homed$ = cfhome$: rem Default
442 IF tstthg%("HOME") = c0% THEN
444 IF LEN(HOME_DIR$) > c4%: homed$ = HOME_DIR$
446 END IF
448 :
450 rem Test for button frame
452 x% = butsx%: y% = butsy%
454 er% = butuse%(x%, y%)
456 IF er% <> c0% THEN
458 bfpresent = 0: rem No button frame
460 ELSE
462 bfpresent = 1: butfree
464 END IF
466 :
468 ssspresent = 0: TstSSS: rem Check for sound system
470 :
472 rem Read Configuration or use defaults
474 :
476 hlpprg$ = homed$ & 'Help_obj' : rem Configure by editing cfg file
478 msgprg$ = homed$ & 'Choice_obj':
480 colsq$ = homed$ & 'colsq24_spr'
482 rem Fixed locations:
484 snd$ = homed$ & 'snd_': rem Location of sound files
486 paln$ = 'dminer_thm'
488 palset = 0: rem No job palette yet set
490 fnmscore$ = homed$ & 'score_txt': rem temp
492 SetDefaults
494 ch = FOPEN(con$): ERT ch: ch% = ch: rem Main window
496 COLOUR_24
498 :
500 WHEN ERRor
502 Burp 'bomb': PAUSE#ch; 50
504 IF ERNUM = -2 THEN
506 rem Probably timer got killed
508 IF tmr_id THEN
510 IF NOT JobLives(tmr_id) THEN
512 IF PreWarn('Timer job died', 'Quit', 'Repair', nul$) = 1 THEN
514 tmr_use% = off%: tmr_id = 0: Bye
516 ELSE
518 tmr_id = 0: TimerSet: TimerStart
520 RETRY ERLIN
522 END IF
524 END IF
526 END IF
528 ELSE
530 er = PreWarn('Fatal error ' & ERNUM, 'Quit', nul$, nul$)
532 Bye
534 END IF
536 END WHEN
538 :
540 er = CfgRead(homed$ & 'dminer_cfg')
542 IF FTEST(msgprg$) + FTEST(hlpprg$) + FTEST(colsq$) <> c0% THEN
544 PrePreWarn "Essential resources not found. See readme!"
546 END IF
548 IF er THEN
550 IF er < 0 THEN
552 mtx$ = 'Cannot read configuration file\\'
554 ELSE
556 mtx$ = 'Configuration file may be corrupt!\\'
558 END IF
560 IF PreWarn(mtx$ & Centre$(LEN(mtx$), "Use defaults?") & bks$ & bks$, ok$, 'Quit', nul$) = 2: >>
QUIT er
562 mtx$ = nul$
564 SetDefaults
566 END IF
568 Palette palno
570 :
572 rem Set the scene
574 :
576 RANDOMISE DATE
578 ct = FOPEN(con$): ERT ct: rem Timer window
580 :
582 base = SCR_BASE(#ch)
584 llen = SCR_LLEN(#ch)
586 bpp% = (llen / SCR_XLIM(#ch))
588 :
590 SetCol#ct; col_ptm, col_itm
592 FLIM#ch; maxx%, maxy%, dummy%, dummy%
594 maxx% = (maxx% - 80) DIV sqsz%: maxy% = (maxy% - 90) DIV sqsz%
596 IF maxx% > 25: maxx% = 25
598 IF maxy% > 25: maxy% = 25
600 tmr_stat% = off%
602 tmr_id = 0: rem Timer ID
604 :
606 SetGame
608 Winit xpos%, ypos%
610 Ping 'startup': ClearFields
612 events% = events% * 256: eve% = events%
614 :
616 rem Main program loop
618 REPeat main
620 k = MCALLT(#ch%, eve%, tio%, k, c0%)
622 PVAL#ch%; prec%
624 SELect ON k
626 = li_move%: WMOV#ch%; -1: MWLINK#ch; wtime%, #ct: rem Reassert link!
628 RDPT#ch; immediate%: PVAL#ch; prec%
630 xpos% = prec%(c10%) - c4%
632 ypos% = prec%(11) - c2%
634 changed = changed + 1
636 = li_resz%: rem Resize interactive
638 IF WarnGame THEN
640 TimerStop: Resize: TimerShow cm1%
642 END IF
644 = li_zzz%: rem Sleep
646 DoButton
648 = li_new%: rem Refresh/New game
650 IF moves% = on% AND game = playing% THEN
652 IF WarnGame = 0: NEXT main: ELSE : PAUSE#ch; 50
654 END IF
656 IF gme_jsd% = on% THEN
658 IF WarnGame THEN
660 TimerStop: ClearFields
662 IF prec%(c5%) = do%: JumpStart: GameStart
664 END IF
666 ELSE
668 TimerStop: ClearFields
670 IF prec%(c5%) = do%: JumpStart: GameStart
672 END IF
674 = li_quit%: IF WarnGame: Bye
676 = li_game%: rem game menu
678 IF WarnGame: GameMenu
680 = li_stat%: rem stats menu
682 MenuStats -1, -1, -1, -1
684 = li_conf%: rem config menu
686 pal = palno: redraw = 0
688 xp% = prec%(c10%) - c2%: yp% = prec%(11) - c2%
690 MenuConf
692 IF redraw THEN
694 IF pal <> palno THEN
696 palno = pal
698 Palette palno
700 END IF
702 MCLEAR#ch%
704 RestoreGame xp%, yp%
706 TimerShow cm1%: rem ### TimerShow should work out correct state!
708 END IF
710 = li_help%: rem help
712 Help#ch%; 'hlp_gen'
714 = li_info%: About
716 = mencon TO 2E9: rem Game
718 IF (timer_state%(tmr_id) && c4%) <> c0% AND game = playing% AND tmr_cup% = off% AND tmr_stat% >>
= on% THEN
720 rem Timed out unnoticed
722 Burp 'loose': GameLoose
724 NEXT main
726 END IF
728 IF game = paused THEN
730 TimerResume
732 game = laststate
734 END IF
736 IF game = playing% OR game = stopped THEN
738 GameStart
740 moves% = on%: rem Flag that a move has been made
742 awn = k: minum = MAWNUM(#ch%, awn, x%, y%)
744 IF prec%(c5%) = hit% THEN
746 Mark k, x%, y%
748 ELSE
750 IF status%(x%, y%) = c0% THEN
752 m% = mines%(x%, y%)
754 SELect ON m%
756 = bomb%: rem Hit a mine
758 IF Oooo%(k) > cm1%: EXPLODE k, x%, y%, c0%
760 = c0%: rem Blank
762 IF Oooo%(k) > cm1% THEN
764 Unravel x%, y%
766 END IF
768 = REMAINDER
770 IF Oooo%(k) > cm1% THEN
772 MAWITEM#ch%, k, spr%, sp_n(m%)
774 status%(x%, y%) = cm1%
776 ELSE
778 Ping 'release'
780 END IF
782 END SELect
784 ELSE
786 ClearAround x%, y%
788 END IF
790 END IF
792 ELSE
794 IF game = lost THEN
796 MITEM#ch%; li_new%, spr%, sp_sour
798 END IF
800 END IF
802 = -1280: rem Event
804 ev% = eve% DIV 256
806 SELect ON ev%
808 = c1%: rem Timed out
810 IF tmr_cup% = off% THEN
812 rem Doesnt timeout on countup
814 Burp 'loose': GameLoose
816 ELSE
818 TimerStop
820 END IF
822 tmr_stat% = off%
824 SetCol#ct; col_pto, col_ito
826 TimerShow timer_time%(tmr_id)
828 = c2%: rem Warning
830 Burp 'timeup': SetCol#ct; col_ptw, col_itw
832 END SELect
834 eve% = events%
836 = wtime%: rem Timer window
838 MenuTimer: gme_chg = tmr_chg
840 = REMAINDER : rem ErrMess idec$(k, 12,0)
842 END SELect
844 END REPeat main
846 :
848 rem Init windows and grid
850 :
852 DEFine PROCedure Winit(px%, py%)
854 rem Window initialisation
856 xsize% = (grdx% + c1%) * sqsz% + c4%: IF xsize% < 140: xsize% = 140
858 ysize% = (grdy% + c1%) * sqsz% + 70: IF ysize% < 104: ysize% = 104
860 MDRAW#ch%; mn_mines, px%, py%, xsize%, ysize%
862 RDPT#ch%; immediate%: PVAL#ch%; prec%: x% = prec%(14): y% = prec%(15)
864 xpos% = prec%(c10%) - c4%
866 ypos% = prec%(11) - c2%
868 END DEFine Winit
870 :
872 DEFine PROCedure ClearFields
874 LOCal i%, j%, x%, y%, r%, c%
876 rem (Re-)setup grid, set mines and grade proximities
878 DIM mines$(grdx%, grdy%, 12), mines%(grdx%, grdy%)
880 DIM status%(grdx%, grdy%): rem Game Status fields (not Wman)
882 xdim% = grdx% + c1%: ydim% = grdy% + c1%
884 game = stopped
886 :
888 rem Calculate number of mines. Increase relative number of mines as size
890 rem grows (paranthesis to avoid overflow) (this formula grows too fast)
892 rem mcount% = ((log10(xdim%) * xdim% * xdim%) div 100) * ydim%: rem 10%++ mines
894 IF gme_mcauto%: mcount% = GetMCount%
896 mleft% = mcount%
898 ShowCount: rem Display mine count
900 TimerSet: TimerShow cm1%
902 :
904 InitGrid
906 SetMines
908 GradeSquares
910 MITEM#ch%; li_new%, spr%, sp_smile
912 END DEFine ClearFields
914 :
916 DEFine FuNction GetMCount%
918 rem Thanks to Marcel Kilgus for this one:
920 RETurn .4167 * xdim% * ydim% - 5.833 * SQRT(xdim% * ydim%) + 26.667
922 END DEFine GetMCount%
924 :
926 DEFine PROCedure InitGrid
928 rem Use caller's locals
930 rem Fill array with cover sprites and display
932 FOR i% = c0% TO grdx%
934 FOR j% = c0% TO grdy%: mines$(i%, j%) = sqr$
936 END FOR i%
938 MAWDRAW#ch%; mapp%, mines$, c0%, c0%, spr%, sqsz%, sqsz%, c0%, c0%
940 END DEFine InitGrid
942 :
944 DEFine PROCedure SetMines
946 LOCal sml
948 rem Uses caller's locals
950 rem Set given number of sprites randomly
952 c% = xdim% * grdy%
954 FOR i% = c1% TO mcount%
956 REPeat sml
958 r% = RND(c0% TO c%)
960 x% = r% MOD xdim%: y% = r% DIV xdim%
962 IF mines%(x%, y%) <> bomb%: EXIT sml
964 END REPeat sml
966 mines%(x%, y%) = bomb%
968 END FOR i%
970 END DEFine SetMines
972 :
974 DEFine PROCedure GradeSquares
976 rem Uses caller's locals
978 rem Grade squares according to mines in proximity
980 FOR x% = c0% TO grdx%
982 FOR y% = c0% TO grdy%
984 IF mines%(x%, y%) = bomb% THEN
986 FOR i% = cm1% TO c1%
988 c% = x% + i%
990 FOR j% = cm1% TO c1%
992 IF NOT (i% = c0% AND j% = c0%) THEN
994 r% = y% + j%
996 IF c% >= c0% AND c% <= grdx% AND r% >= c0% AND r% <= grdy% THEN
998 IF mines%(c%, r%) <> bomb%
1000 mines%(c%, r%) = mines%(c%, r%) + c1%
1002 END IF
1004 END IF
1006 END IF
1008 END FOR j%
1010 END FOR i%
1012 END IF
1014 END FOR y%
1016 END FOR x%
1018 END DEFine GradeSquares
1020 :
1022 DEFine PROCedure Resize
1024 LOCal x%, y%
1026 IF prec%(c5%) = c2% THEN
1028 grdx% = minx%: grdy% = miny%
1030 ELSE
1032 WSIZE#ch; x%, y%
1034 grdx% = grdx% - (x% DIV sqsz%): grdy% = grdy% - (y% DIV sqsz%)
1036 IF grdx% < minx%: grdx% = minx%
1038 IF grdx% > maxx%: grdx% = maxx%
1040 IF grdy% < miny%: grdy% = miny%
1042 IF grdy% > maxy%: grdy% = maxy%
1044 IF gme_mcauto% = off% THEN
1046 minm% = grdx% * grdy% DIV 12: rem Max/Min number of mines
1048 maxm% = minm% * c4%: rem for this grid size
1050 IF mcount% > maxm%: mcount% = maxm%
1052 IF mcount% < minm%: mcount% = minm%
1054 END IF
1056 prec%(c10%) = prec%(c10%) + x%: IF prec%(c10%) < c4%: prec%(c10%) = c4%
1058 prec%(11) = prec%(11) + y%: IF prec%(11) < c2%: prec%(11) = c2%
1060 END IF
1062 NewWin prec%(c10%) - c4%, prec%(11) - c2%
1064 gme_chg = 1
1066 END DEFine Resize
1068 :
1070 DEFine PROCedure NewWin(xp%, yp%)
1072 rem Set up a new window
1074 MCLEAR#ch%: CLAMP
1076 Winit xp%, yp%
1078 ClearFields
1080 END DEFine NewWin
1082 :
1084 rem Mines
1086 :
1088 DEFine PROCedure Mark(it, xp%, yp%)
1090 LOCal i%, j%, s%
1092 rem Mark bomb square and check if game over
1094 IF status%(xp%, yp%) = c1% THEN
1096 Burp 'unflag'
1098 MAWITEM#ch%; it, spr%, sp_square
1100 mines$(xp%, yp%) = Spra$(sp_square)
1102 status%(xp%, yp%) = c0%
1104 mleft% = mleft% + c1%
1106 ELSE
1108 IF status%(xp%, yp%) = c0% THEN
1110 Ping 'flag'
1112 MAWITEM#ch%; it, spr%, sp_flag
1114 mines$(xp%, yp%) = Spra$(sp_flag)
1116 status%(xp%, yp%) = c1%
1118 mleft% = mleft% - c1%
1120 END IF
1122 END IF
1124 IF mleft% <= c0% THEN
1126 s% = c1%
1128 FOR i% = c0% TO grdx%
1130 FOR j% = c0% TO grdy%
1132 IF (mines%(i%, j%) = bomb% AND status%(i%, j%) <> c1%) OR (status%(i%, j%) = c1% AND mines%( >>
i%, j%) <> bomb%): s% = c0%: EXIT j%
1134 END FOR j%
1136 IF s% = c0%: EXIT i%
1138 END FOR i%
1140 IF s% = c1% THEN
1142 FOR i% = c0 TO grdx%
1144 FOR j% = c0% TO grdy%: status%(i%, j%) = cm1%
1146 END FOR i%
1148 MSTAT#ch%, mapp%, status%: MAWDRAW#ch%; mapp%
1150 GameWin
1152 ELSE
1154 Burp 'illegal'
1156 END IF
1158 END IF
1160 ShowCount
1162 IF mleft% <= -c10%: Burp 'loose': GameLoose
1164 END DEFine Mark
1166 :
1168 DEFine PROCedure Unravel(xp%, yp%)
1170 LOCal i%, j%, c%, r%
1172 rem Uncover adjacent blanks. Recursive!
1174 MAWITEM#ch%; ItNo(xp%, yp%), spr%, sp_blank
1176 mines$(xp%, yp%) = Spra$(sp_blank)
1178 status%(xp%, yp%) = cm1%
1180 s% = MSTAT%(#ch%; ItNo(xp%, yp%) TO c0%\ c0%)
1182 FOR i% = cm1% TO c1%
1184 c% = xp% + i%
1186 FOR j% = cm1% TO c1%
1188 IF NOT (i% = c0% AND j% = c0%) THEN
1190 r% = yp% + j%
1192 IF c% >= c0% AND c% <= grdx% AND r% >= c0% AND r% <= grdy% THEN
1194 IF status%(c%, r%) = c0% THEN
1196 IF mines%(c%, r%) = c0% THEN
1198 Unravel c%, r%
1200 ELSE
1202 IF mines%(c%, r%) < bomb% THEN
1204 MAWITEM#ch%; ItNo(c%, r%), spr%, sp_n(mines%(c%, r%))
1206 mines$(c%, r%) = Spra$(sp_n(mines%(c%, r%)))
1208 status%(c%, r%) = cm1%
1210 s% = MSTAT%(#ch%; ItNo(c%, r%) TO c0%\ c0%)
1212 END IF
1214 END IF
1216 END IF
1218 END IF
1220 END IF
1222 END FOR j%
1224 END FOR i%
1226 s% = MSTAT%(#ch%; ItNo(xp%, yp%) TO c0%): rem Redraw changed
1228 END DEFine Unravel
1230 :
1232 DEFine PROCedure EXPLODE(it, xp%, yp%, e%)
1234 LOCal i%, j%
1236 rem Explode bomb, reveal all, and finish game
1238 IF e% = c0% THEN
1240 MAWITEM#ch%, it, spr%, sp_bombx
1242 mines$(xp%, yp%) = Spra$(sp_bombx)
1244 Burp 'bomb'
1246 END IF
1248 status%(xp%, yp%) = cm1%
1250 FOR i% = c0% TO grdx%
1252 FOR j% = c0% TO grdy%
1254 IF status%(i%, j%) = c1% THEN
1256 IF mines%(i%, j%) <> bomb% THEN
1258 MAWITEM#ch%, ItNo(i%, j%), spr%, sp_bombe
1260 mines$(i%, j%) = Spra$(sp_bombe)
1262 END IF
1264 ELSE
1266 IF status%(i%, j%) = c0% AND mines%(i%, j%) = bomb% THEN
1268 MAWITEM#ch%, ItNo(i%, j%), spr%, sp_bomb
1270 mines$(i%, j%) = Spra$(sp_bomb)
1272 END IF
1274 END IF
1276 status%(i%, j%) = cm1%
1278 END FOR j%
1280 END FOR i%
1282 MSTAT#ch%, mapp%, status%: MAWDRAW#ch%; mapp%
1284 GameLoose
1286 END DEFine EXPLODE
1288 :
1290 DEFine FuNction Oooo%(it)
1292 rem Simulate button depress and allow regret
1294 Ping 'press'
1296 MITEM#ch%; li_new%, spr%, sp_oooo: MLIDRAW#ch%; li_new%
1298 MWINDOW#ch%; it
1300 SPRW#ch%; c0%, c0%, sp_blank
1302 RDPT#ch%; tvx%: PVAL#ch%; prec%
1304 Ping 'release'
1306 MITEM#ch%; li_new%, spr%, sp_smile
1308 RETurn prec%(c3%): rem Escape if pointer out of window
1310 END DEFine Oooo%
1312 :
1314 DEFine PROCedure ClearAround(xp%, yp%)
1316 LOCal i%, j%, c%, r%, s%, i
1318 rem If no unmarked mines clear around numbered square else flash
1320 IF status%(xp%, yp%) <> cm1% OR mines%(xp%, yp%) = c0%: Burp 'illegal': RETurn
1322 s% = c1%
1324 FOR i% = cm1% TO c1%
1326 c% = xp% + i%
1328 FOR j% = cm1% TO c1%
1330 r% = yp% + j%
1332 IF c% >= c0% AND c% <= grdx% AND r% >= c0% AND r% <= grdy% THEN
1334 IF mines%(c%, r%) = bomb% THEN
1336 IF status%(c%, r%) = c0% THEN
1338 s% = c0%
1340 END IF
1342 ELSE
1344 IF status%(c%, r%) = c1% THEN
1346 s% = cm1%: EXIT j%
1348 END IF
1350 END IF
1352 END IF
1354 END FOR j%
1356 IF s% = cm1%: EXIT i%
1358 END FOR i%
1360 :
1362 rem Check for wrongly marked mines
1364 IF s% = cm1% THEN
1366 Burp 'loose'
1368 i = ItNo(c%, r%)
1370 MAWITEM#ch%; i, spr%, sp_bombe
1372 mines$(c%, r%) = Spra$(sp_bombe)
1374 EXPLODE i, c%, r%, c1%: rem Flag wrong marker
1376 RETurn
1378 END IF
1380 :
1382 rem Unmarked mine(s) found: Flash
1384 IF s% = c0% THEN
1386 FOR i% = cm1% TO c1%
1388 c% = xp% + i%
1390 FOR j% = cm1% TO c1%
1392 r% = yp% + j%
1394 IF c% >= c0% AND c% <= grdx% AND r% >= c0% AND r% <= grdy% THEN
1396 IF status%(c%, r%) = c0% THEN
1398 Ping 'flash'
1400 i = ItNo(c%, r%)
1402 MAWITEM#ch%; i, spr%, sp_blank
1404 mines$(c%, r%) = Spra$(sp_blank)
1406 s% = MSTAT%(#ch%; i TO c1%\ c0%)
1408 END IF
1410 END IF
1412 END FOR j%
1414 END FOR i%
1416 s% = MSTAT%(#ch%; i TO c0%)
1418 :
1420 rem Wait for keyup, then unflash
1422 RDPT#ch%; c4%
1424 Ping 'release'
1426 FOR i% = cm1% TO c1%
1428 c% = xp% + i%
1430 FOR j% = cm1% TO c1%
1432 r% = yp% + j%
1434 IF c% >= c0% AND c% <= grdx% AND r% >= c0% AND r% <= grdy% THEN
1436 IF status%(c%, r%) = c0% THEN
1438 i = ItNo(c%, r%)
1440 MAWITEM#ch%; i, spr%, sp_square
1442 mines$(c%, r%) = Spra$(sp_square)
1444 s% = MSTAT%(#ch%; i TO c0%\ c0%)
1446 END IF
1448 END IF
1450 END FOR j%
1452 END FOR i%
1454 s% = MSTAT%(#ch%; i TO c0%)
1456 ELSE
1458 :
1460 rem No unmarked mines found: Clear surrounding squares
1462 Ping 'clear'
1464 FOR i% = cm1% TO c1%
1466 c% = xp% + i%
1468 FOR j% = cm1% TO c1%
1470 r% = yp% + j%
1472 IF c% >= c0% AND c% <= grdx% AND r% >= c0% AND r% <= grdy% THEN
1474 IF status%(c%, r%) = c0% THEN
1476 IF mines%(c%, r%) = c0% THEN
1478 Unravel c%, r%
1480 ELSE
1482 i = ItNo(c%, r%)
1484 MAWITEM#ch; i, spr%, sp_n(mines%(c%, r%))
1486 mines$(c%, r%) = Spra$(sp_n(mines%(c%, r%)))
1488 s% = MSTAT%(#ch%; i TO c0%)
1490 END IF
1492 status%(c%, r%) = cm1%
1494 END IF
1496 END IF
1498 END FOR j%
1500 END FOR i%
1502 END IF
1504 END DEFine ClearAround
1506 :
1508 DEFine PROCedure JumpStart
1510 LOCal rl, c%, r%
1512 rem Unravel a random field
1514 Ping 'new'
1516 REPeat rl
1518 c% = RND(c0% TO grdx%): r% = RND(c0% TO grdy%)
1520 IF mines%(c%, r%) = c0% THEN
1522 Unravel c%, r%
1524 EXIT rl
1526 END IF
1528 END REPeat rl
1530 END DEFine JumpStart
1532 :
1534 rem Submenus
1536 :
1538 DEFine PROCedure
1540 LOCal awl, k%
1542 LOCal retrac: rem Local to menus
1544 REPeat awl
1546 k% = AwRead%(wtime%)
1548 SELect ON k%
1550 = esc%: EXIT awl
1552 = c1%: rem HIT
1554 IF tmr_use% = on% AND tmr_stat% = on% THEN
1556 IF tmr_pause% = on% THEN
1558 TimerResume: Ping ok$
1560 game = laststate
1562 ELSE
1564 TimerPause: Ping 'pause'
1566 laststate = game: game = paused
1568 END IF
1570 END IF
1572 NEXT awl
1574 = c2%: rem DO
1576 MenuTime prec%(10) - 80, prec%(11) + 22
1578 = REMAINDER : NEXT awl
1580 END SELect
1582 END REPeat awl
1584 END DEFine MenuTimer
1586 :
1588 DEFine PROCedure (xp%, yp%)
1590 LOCal tml, i%, cm, st%, tk, d$(c3%)
1592 cm = FOPEN(con$): ERT cm
1594 MSETUP#cm; mn_timer, xp%, yp%
1596 MITEM#cm; tmi_use%, spr%, sp_spotn(spot%)
1598 MITEM#cm; tmi_aut%, spr%, sp_spotn(spot%)
1600 MITEM#cm; tmi_cup%, spr%, sp_spotn(spot%)
1602 MITEM#cm; tmi_cdn%, spr%, sp_spotn(spot%)
1604 MITEM#cm; tmi_lrc%, spr%, sp_spotn(spot%)
1606 st% = MSTAT%(#cm; tmi_lrc% TO cm1%\ c0%): rem NI yet
1608 IF tmr_use% = on% THEN
1610 SwitchOn
1612 ELSE
1614 SwitchOff
1616 END IF
1618 TechnicalPause
1620 MDRAW#cm
1622 Digits
1624 st% = c0%
1626 REPeat tml
1628 tk = MCALL(#cm; tk! st%)
1630 PVAL#cm; tprec%
1632 SELect ON tk
1634 = -2: Help#cm; 'hlp_timer': st% = c0%
1636 = -3: rem Quit
1638 retrac = tprec%(c5%) = c2%
1640 MCLEAR#cm: CLOSE#cm
1642 EXIT tml
1644 = tmi_use%: rem Toggle Use timer
1646 IF game = playing% THEN
1648 Burp 'illegal': NEXT tml
1650 ELSE
1652 tmr_use% = MSTAT%(#cm; tk)
1654 IF tmr_use% = on% THEN
1656 SwitchOn
1658 TimerSet
1660 ELSE
1662 TimerOff
1664 SwitchOff
1666 END IF
1668 END IF
1670 st% = MSTAT%(#cm; tk TO tmr_use%): rem Re-draw
1672 tmr_chg = 1
1674 = tmi_aut%: rem Toggle auto-calculate countdown
1676 st% = MSTAT%(#cm; tk): tmr_auto% = st%
1678 IF tmr_auto% = on%: tmr_cup% = off%
1680 SwitchOn
1682 st% = MSTAT%(#cm; tk TO st%): rem Re-draw
1684 tmr_chg = 1
1686 = tmi_cup%: rem Toggle Count up
1688 st% = MSTAT%(#cm; tk)
1690 tmr_cup% = st%: tmr_auto% = off%
1692 SwitchOn
1694 st% = MSTAT%(#cm; tk TO st%): rem Re-draw
1696 tmr_chg = 1
1698 = tmi_cdn%: rem Toggle Count down
1700 st% = MSTAT%(#cm; tk)
1702 IF st% = on%: tmr_cup% = off%: ELSE : tmr_cup% = on%
1704 tmr_auto% = off%
1706 SwitchOn
1708 st% = MSTAT%(#cm; tk TO st%): rem Re-draw
1710 tmr_chg = 1
1712 rem Edit Start time
1714 = tmi_dgs% - c2% TO tmi_dgs%: rem Up
1716 d$ = Z$(tmr_start%)
1718 i% = ABS(tk) - c7%
1720 IF tprec%(c5%) = c2% THEN
1722 IF d$(i%) = c9%: d$(i%) = c5%: ELSE : d$(i%) = c9%
1724 ELSE
1726 IF d$(i%) = c9% THEN
1728 d$(i%) = c0%
1730 ELSE
1732 d$(i%) = d$(i%) + c1%
1734 END IF
1736 END IF
1738 tmr_start% = d$: tmr_auto% = off%
1740 st% = c0%: tmr_chg = 1
1742 = tmi_dge% TO tmi_dgs% - c3%: rem Down
1744 d$ = Z$(tmr_start%)
1746 i% = ABS(tk) - c10%
1748 IF tprec%(c5%) = c2% THEN
1750 IF d$(i%) = c0%: d$(i%) = c5%: ELSE : d$(i%) = c0%
1752 ELSE
1754 IF d$(i%) = c0% THEN
1756 d$(i%) = c9%
1758 ELSE
1760 d$(i%) = d$(i%) - c1%
1762 END IF
1764 END IF
1766 tmr_start% = d$: tmr_auto% = off%
1768 st% = c0%: tmr_chg = 1
1770 = tmi_lrc%: rem Timer Last record
1772 END SELect
1774 Digits
1776 END REPeat tml
1778 TechnicalResume
1780 IF tmr_use% = on%: timer_disp tmr_id, c1%
1782 IF tmr_chg = 1 THEN
1784 rem Timer changed
1786 TimerSet
1788 IF tmr_stat% = off%: TimerShow cm1%
1790 IF tmr_pause% = on%: TimerResume: Ping ok$
1792 END IF
1794 IF tmr_use% = on% AND tmr_stat% = on% AND tmr_pause% = off% THEN
1796 IF tmr_id = 0 THEN
1798 TimerShow cm1%
1800 END IF
1802 END IF
1804 END DEFine MenuTime
1806 :
1808 DEFine PROCedure TechnicalPause
1810 IF tpause% = c0% THEN
1812 IF tmr_use% = on% AND tmr_pause% = off%: timer_disp tmr_id, c0%: tpause% = c1%
1814 END IF
1816 END DEFine TechnicalPause
1818 :
1820 DEFine PROCedure TechnicalResume
1822 IF tpause% = c1% THEN
1824 IF tmr_use% = on% AND tmr_pause% = off%: timer_disp tmr_id, c1%: tpause% = c0%
1826 END IF
1828 END DEFine TechnicalResume
1830 :
1832 DEFine PROCedure SwitchOn
1834 LOCal i%, st%
1836 st% = MSTAT%(#cm; tmi_use% TO c1%\ c0%)
1838 IF tmr_auto% = on% THEN
1840 st% = MSTAT%(#cm; tmi_aut% TO c1%\ c0%)
1842 st% = MSTAT%(#cm; tmi_cup% TO cm1%\ c0%)
1844 st% = MSTAT%(#cm; tmi_cdn% TO cm1%\ c0%)
1846 FOR i% = tmi_cup% TO tmi_dge% STEP cm1%
1848 st% = MSTAT%(#cm; i% TO cm1%\ c0%)
1850 END FOR i%
1852 ELSE
1854 IF tmr_cup% = on% THEN
1856 st% = MSTAT%(#cm; tmi_cup% TO c1%\ c0%)
1858 st% = MSTAT%(#cm; tmi_aut% TO c0%\ c0%)
1860 st% = MSTAT%(#cm; tmi_cdn% TO c0%\ c0%)
1862 FOR i% =tmi_dgs% TO tmi_dge% STEP cm1%
1864 st% = MSTAT%(#cm; i% TO cm1%\ c0%)
1866 END FOR i%
1868 ELSE
1870 st% = MSTAT%(#cm; tmi_cdn% TO c1%\ c0%)
1872 st% = MSTAT%(#cm; tmi_aut% TO c0%\ c0%)
1874 st% = MSTAT%(#cm; tmi_cup% TO c0%\ c0%)
1876 FOR i% = tmi_dgs% TO tmi_dge% STEP cm1%
1878 st% = MSTAT%(#cm; i% TO c0%\ c0%)
1880 END FOR i%
1882 END IF
1884 END IF
1886 END DEFine SwitchOn
1888 :
1890 DEFine PROCedure SwitchOff
1892 LOCal i%, st%
1894 st% = MSTAT%(#cm; tmi_use% TO c0%\ c0%)
1896 FOR i% = tmi_aut% TO tmi_dge% STEP cm1%
1898 st% = MSTAT%(#cm; i% TO cm1%\ c0%)
1900 END FOR i%
1902 END DEFine SwitchOff
1904 :
1906 DEFine PROCedure Digits
1908 LOCal i%, d$(c3%)
1910 IF tmr_use% = off% THEN
1912 d$ = '---'
1914 ELSE
1916 IF tmr_cup% = on% THEN
1918 d$ = '000'
1920 ELSE
1922 d$ = Z$(tmr_start%)
1924 END IF
1926 END IF
1928 FOR i% = tmw_dg1% TO tmw_dg3%
1930 MWINDOW#cm; i%! c0%: timer_led#cm; c1%, d$(i% - tmw_dg1% + c1%)
1932 END FOR i%
1934 END DEFine Digits
1936 :
1938 rem Timer
1940 :
1942 DEFine PROCedure TimerSet
1944 SetCol#ct; col_ptm, col_itm
1946 IF tmr_use% = off%: RETurn
1948 IF tmr_id = 0 THEN
1950 tmr_id = timer_init(#ct! c3%): rem padded to three digits
1952 END IF
1954 IF tmr_auto% = on% OR tmr_cup% = off% THEN
1956 IF tmr_auto% = on% THEN
1958 tmr_start% = TmrStart%(mcount%, xdim%, ydim%)
1960 END IF
1962 timer_set tmr_id, tmr_start% TO tmr_end%, tmr_wrd%
1964 ELSE
1966 timer_set tmr_id, c0% TO 999, tmr_wru%
1968 END IF
1970 END DEFine TimerSet
1972 :
1974 DEFine FuNction TmrStart%(mc%, xd%, yd%)
1976 LOCal t%
1978 t% = tmr_fact * mc% * mc% / xd% / yd%
1980 IF t% > 999: t% = 999
1982 RETurn t%
1984 END DEFine TmrStart%
1986 :
1988 DEFine PROCedure TimerShow(n%)
1990 MWLINK#ch; wtime%, #ct
1992 IF tmr_use% = on% THEN
1994 IF n% > cm1% THEN
1996 timer_led#ct; c3%, Z$(n%)
1998 ELSE
2000 IF tmr_cup% = on% THEN
2002 timer_led#ct; c3%, '000'
2004 ELSE
2006 timer_led#ct; c3%, Z$(tmr_start%)
2008 END IF
2010 END IF
2012 ELSE
2014 timer_led#ct; c3%, '---'
2016 END IF
2018 END DEFine TimerShow
2020 :
2022 DEFine PROCedure TimerStart
2024 IF tmr_use% = off% OR tmr_stat% = on%: RETurn : rem Untimed/already running
2026 tmr_stat% = on%: tmr_pause% = off%
2028 TimerShow cm1%: timer_start tmr_id
2030 END DEFine TimerStart
2032 :
2034 DEFine PROCedure TimerPause
2036 IF tmr_use% = off%: RETurn : rem Untimed
2038 IF tmr_stat% = on% THEN
2040 timer_pause tmr_id
2042 tmr_pause% = on%
2044 END IF
2046 END DEFine TimerPause
2048 :
2050 DEFine PROCedure TimerStop
2052 IF tmr_use% = off%: RETurn : rem Untimed
2054 timer_stop tmr_id
2056 tmr_stat% = off%: tmr_pause% = off%
2058 END DEFine TimerStop
2060 :
2062 DEFine PROCedure TimerOff
2064 IF tmr_use% = off%: RETurn : rem Already off
2066 timer_kill tmr_id: tmr_id = 0
2068 tmr_stat% = off%: tmr_pause% = off%
2070 END DEFine TimerOff
2072 :
2074 DEFine PROCedure TimerResume
2076 IF tmr_use% = off%: RETurn : rem Untimed
2078 timer_pause tmr_id
2080 tmr_stat% = on%: tmr_pause% = off%
2082 END DEFine TimerResume
2084 :
2086 rem Misc
2088 :
2090 DEFine PROCedure ShowCount
2092 rem Display count
2094 MWINDOW#ch; wmcnt%! c0%: SetCol#ch; col_pmc, col_imc
2096 timer_led#ch; c3%, Z$(mleft%)
2098 WM_PAPER#ch; sp_appbg%: rem To avoid flash of col_pmc
2100 END DEFine ShowCount
2102 :
2104 DEFine FuNction Z$(n%)
2106 LOCal s$
2108 IF n% < c0%: s$ = '-': ELSE s$ = nul$
2110 RETurn s$ & FILL$("0", c3% - LEN(ABS(n%) & s$)) & ABS(n%)
2112 END DEFine
2114 :
2116 DEFine FuNction Centre$(w%, txt$)
2118 rem Centre text
2120 IF LEN(txt$) > w% THEN
2122 RETurn txt$(c1% TO w%)
2124 ELSE
2126 RETurn FILL$(spc$, (w% - LEN(txt$)) DIV c2%) & txt$
2128 END IF
2130 END DEFine Centre$
2132 :
2134 DEFine FuNction ItNo(i%, j%)
2136 rem Create item number from coordinates
2138 RETurn (j% * xdim% + i% + c1%) * mencon + 1
2140 END DEFine ItNo
2142 :
2144 DEFine FuNction AwRead%(awno%)
2146 LOCal k%
2148 RDPT#ch; mvec%
2150 PVAL#ch; tprec%: k% = tprec%(c6%)
2152 IF (tprec%(c2%) + c1%) <> awno%: RETurn esc%
2154 IF k% = esc%: Bye
2156 RETurn k%
2158 END DEFine AwRead%
2160 :
2162 DEFine PROCedure SetCol(ch, cp, ci)
2164 PAPER#ch; cp: INK#ch; ci
2166 END DEFine
2168 :
2170 DEFine PROCedure Bye
2172 IF tmr_id <> 0: timer_kill tmr_id
2174 IF saveonx AND changed: CfgSave: Ping 'saved'
2176 MCLEAR#ch: CLAMP: CLOSE: QUIT
2178 END DEFine Bye
2180 :
2182 rem Button
2184 :
2186 DEFine PROCedure DoButton
2188 rem Save timer and window statuses,
2190 rem and close windows
2192 IF tmr_use% = on% THEN
2194 but_t% = timer_time%(tmr_id): but_s% = timer_state%(tmr_id)
2196 IF but_t% = 0 AND game <> lost: but_t% = tmr_start%
2198 timer_kill tmr_id: tmr_id = 0
2200 rem if tmr_stat% = on% and game = playing% then
2202 IF game = playing% THEN
2204 Ping 'pause'
2206 IF tmr_cup% = on% THEN
2208 but_t% = but_t% - c1%
2210 ELSE
2212 but_t% = but_t% + c1%
2214 END IF
2216 END IF
2218 END IF
2220 PVAL#ch; prec%
2222 CLOSE#ct: MCLEAR#ch: CLAMP: CLOSE#ch
2224 rem Use button frame if wanted and available
2226 IF butbf THEN
2228 butx% = butsx%: buty% = butsy%
2230 er% = butuse%(butx%, buty%): rem Returns position in butx/y
2232 IF er% <> c0%: butbf = 0
2234 END IF
2236 ButWin
2238 END DEFine DoButton
2240 :
2242 DEFine PROCedure ButWake
2244 LOCal p, i, t%, a%, u%, w%
2246 rem Re-open windows and restore game
2248 CLOSE#butch: butch = 0: IF bfpresent: butfree
2250 ch = FOPEN(con$): ERT ch: ch% = ch: OUTL#ch
2252 ct = FOPEN(con$): ERT ct: rem Timer window
2254 RestoreGame prec%(c10%) - c6%, prec%(11) - c4%
2256 :
2258 rem Restore timer state (a bit fiddley this)
2260 IF tmr_use% = on% THEN
2262 tmr_id = timer_init(#ct! c3%)
2264 IF tmr_stat% = on% THEN
2266 rem Set Paper/Ink colour according to state
2268 IF (but_s% && 16) > c0% THEN
2270 SetCol#ct; col_ptw, col_itw
2272 ELSE
2274 SetCol#ct; col_ptm, col_itm
2276 END IF
2278 IF tmr_cup% = on% THEN
2280 timer_set tmr_id, but_t% TO 999, tmr_wru%
2282 ELSE
2284 timer_set tmr_id, but_t% TO c0%, tmr_wrd%
2286 END IF
2288 TimerShow but_t%
2290 PAUSE#ct; c1%: rem Re-schedule!
2292 IF but_t% > c0% THEN
2294 timer_start tmr_id
2296 IF tmr_pause% = on%: timer_pause tmr_id
2298 END IF
2300 ELSE
2302 rem Stopped, timedout or not initialised
2304 TimerSet
2306 MWLINK#ch; wtime%, #ct
2308 IF game = playing% THEN
2310 SetCol#ct; col_ptm, col_itm
2312 TimerShow cm1%
2314 ELSE
2316 IF but_t% <= c0% AND game = lost THEN
2318 SetCol#ct; col_pto, col_ito
2320 ELSE
2322 SetCol#ct; col_ptm, col_itm
2324 END IF
2326 TimerShow but_t%
2328 END IF
2330 END IF
2332 ELSE
2334 rem Timer off
2336 MWLINK#ch; wtime%, #ct
2338 SetCol#ct; col_ptm, col_itm
2340 TimerShow but_t%
2342 END IF
2344 END DEFine ButWake
2346 :
2348 DEFine PROCedure ButWin
2350 rem Button window routine
2352 LOCal bl, owl
2354 butch = FOPEN(con$)
2356 IF butch > 0 THEN
2358 rem Define button window and display
2360 IF butx% < c0% OR buty% < c0% THEN
2362 OUTL#butch; butsx%, butsy%, prec%(14), prec%(15)
2364 ELSE
2366 OUTL#butch; butsx%, butsy%, butx%, buty%
2368 END IF
2370 WM_BORDER#butch; c1%, sp_butbd%
2372 WM_PAPER#butch; sp_butbg%: WM_INK#butch; sp_butfg%
2374 CLS#butch: CURSOR#butch; c2%, c1%: PRINT#butch; 'D-Miner';
2376 SPRW#butch; butsprx%, c1%, sp_sleep
2378 :
2380 rem Pointer out of button window
2382 REPeat bl
2384 RDPT#butch; but_vi%
2386 IF but_vi% DIV 256 >= c1%: EXIT bl
2388 Ping 'wake'
2390 WM_BORDER#butch; c1%, sp_buthigh%
2392 SPRW#butch; butsprx%, c1%, sp_wink
2394 :
2396 rem Pointer in button window
2398 REPeat owl
2400 RDPT#butch; but_vo%:
2402 IF but_vo% DIV 256 >= c1% THEN
2404 IF but_vo% DIV 256 = c2% OR butbf: EXIT bl
2406 WM_BORDER#butch; c0%, sp_butbd%: rem Why?
2408 WMOV#butch
2410 END IF
2412 WM_BORDER#butch; c1%, sp_butbd%
2414 SPRW#butch; butsprx%, c1%, sp_sleep
2416 EXIT owl
2418 END REPeat owl
2420 END REPeat bl
2422 ButWake
2424 ELSE
2426 rem Cannot do button
2428 Burp 'illegal'
2430 END IF
2432 END DEFine ButWin
2434 :
2436 DEFine PROCedure RestoreGame(xp%, yp%)
2438 Winit xp%, yp%
2440 ShowCount
2442 IF game = lost THEN
2444 MITEM#ch%; li_new%, spr%, sp_sour
2446 ELSE
2448 IF game = won: MITEM#ch%; li_new%, spr%, sp_cool
2450 END IF
2452 rem Restore game board
2454 MAWDRAW#ch%; mapp%, mines$, c0%, c0%, spr%, sqsz%, sqsz%, c0%, c0%
2456 END DEFine RestoreGame
2458 :
2460 DEFine PROCedure
2462 LOCal ml, mc, mk, s%, xp%, t$(c4%), snd, sox
2464 LOCal retrac : rem Local to menus
2466 TechnicalPause
2468 retrac = 0: colsq = 0
2470 mc = FOPEN(con$): IF mc < 0: ERT mc
2472 xp% = prec%(c10%) + c10%
2474 MSETUP#mc; mn_config, xp%, prec%(11) + 40
2476 sox = saveonx: snd = sound
2478 SetConf
2480 MDRAW#mc
2482 s% = c0%
2484 REPeat ml
2486 mk = MCALL(#mc; mk, s%)
2488 SELect ON mk
2490 = -2: Help#mc; 'hlp_config'
2492 = -3: IF changed: Ping ok$
2494 EXIT ml
2496 = -4: rem Sound
2498 s% = MSTAT%(#mc; mk)
2500 snd = s%: Ping ok$
2502 IF snd = (sound <> 0) THEN
2504 changed = changed - 1: IF changed < 0: changed = 0
2506 ELSE
2508 changed = changed + 1
2510 END IF
2512 = -5, -6: rem HIT/DO
2514 SwapHD
2516 IF t$ = 'HIT': hit% = c2%: do% = c1%: ELSE : hit% = c1%: do% = c2%
2518 s% = c0%: changed = changed + 1
2520 = -7: rem Look
2522 PVAL#mc; tprec%
2524 MenuLook tprec%(10) + 100, tprec%(11) + 76
2526 IF pal <> palno: changed = changed + 1
2528 s% = c0%
2530 = -8: rem Timer
2532 tmr_chg = 0
2534 PVAL#mc; tprec%
2536 MenuTime tprec%(10) + 100, tprec%(11) + 92
2538 s% = c0%
2540 IF tmr_chg: Ping ok$: changed = changed + tmr_chg
2542 = -9: rem Score
2544 PVAL#mc; tprec%
2546 changed = changed + MenuScore(tprec%(10) + 100, tprec%(11) + 108)
2548 s% = c0%
2550 = -10: rem Save on exit
2552 s% = MSTAT%(#mc; mk)
2554 IF sox = s% THEN
2556 changed = changed - 1: IF changed < 0: changed = 0
2558 ELSE
2560 changed = changed + 1
2562 saveonx = s%
2564 END IF
2566 = -11: rem Defaults
2568 SetDefaults: SetConf
2570 s% = MSTAT%(#mc; mk TO c0%)
2572 changed = 1
2574 Ping ok$
2576 = -12: rem Save Now
2578 SetSound snd
2580 CfgSave: Ping 'saved'
2582 s% = cm1%: NEXT ml
2584 END SELect
2586 IF changed THEN
2588 st% = MSTAT%(#mc; -12 TO c1%\ c0%)
2590 ELSE
2592 IF retrac: EXIT ml
2594 st% = MSTAT%(#mc; -12 TO cm1%\ c0%)
2596 END IF
2598 END REPeat ml
2600 MCLEAR#mc: CLOSE#mc
2602 SetSound snd
2604 IF colsq: RECHP colsq: colsq = 0
2606 TechnicalResume
2608 END DEFine MenuConf
2610 :
2612 DEFine PROCedure SetConf
2614 rem MenuConf subroutine
2616 MITEM#mc; -4, spr%, sp_spotn(spot%)
2618 MITEM#mc; -10, spr%, sp_spotn(spot%)
2620 IF (hit% = c1% AND MTEXT$(#mc; -5) <> 'HIT') OR (hit% = c2% AND MTEXT$(#mc; -5) <> 'DO'): >>
SwapHD
2622 IF sound: s% = MSTAT%(#mc; -4, c1%\ c0%): ELSE : s% = MSTAT%(#mc; -4, c0%\ c0%)
2624 s% = MSTAT%(#mc; -10, saveonx\ c0%)
2626 IF changed: s% = MSTAT%(#mc; -12, c1%\ c0%): ELSE : s% = MSTAT%(#mc; -12, cm1%\ c0%)
2628 END DEFine SetConf
2630 :
2632 DEFine PROCedure SwapHD
2634 rem MenuConf subroutine
2636 t$ = MTEXT$(#mc; -5)
2638 MITEM#mc; -5, c0%, MTEXT$(#mc; -6)
2640 MITEM#mc; -6, c0%, t$
2642 END DEFine SwapHD
2644 :
2646 DEFine PROCedure CfgSave
2648 LOCal i%, sc
2650 sc = FOP_OVER(homed$ & 'dminer_cfg'): IF sc < 0: Burp 'illegal': RETurn
2652 :
2654 rem Magic
2656 PRINT#sc; mgDmnr$
2658 :
2660 PRINT#sc\\ '* - File locations'\\
2662 Cfg 'Help', hlpprg$
2664 Cfg 'Message', msgprg$
2666 Cfg 'ColourSquare', colsq$
2668 Cfg 'SoundDir', snd$
2670 :
2672 PRINT#sc\\ '* - Game board'\\
2674 Cfg 'x-pos', xpos%
2676 Cfg 'y-pos', ypos%
2678 :
2680 FOR i% = c0% TO DIMN(game%)
2682 PRINT#sc\\ '* - Game #' & i%\\
2684 Cfg 'current', YN$(game%(i%, c0%))
2686 Cfg 'x-grid', game%(i%, c1%)
2688 Cfg 'linked', YN$(game%(i%, c2%))
2690 Cfg 'y-grid', game%(i%, c3%)
2692 Cfg 'mines', GetOpt$(game%(i%, c4%), gameM$)
2694 Cfg 'timer', GetOpt$(game%(i%, c5%), gameT$)
2696 END FOR i%
2698 :
2700 PRINT#sc\\ '* - General'\\
2702 Cfg 'sound', YN$(sound)
2704 Cfg 'palette', palno
2706 Cfg 'spots', colour$(spot% - c1%)
2708 Cfg 'HIT', hit%
2710 Cfg 'Save on Exit', YN$(saveonx)
2712 :
2714 PRINT#sc\\ '* - Timer'\\
2716 Cfg 'factor', tmr_fact
2718 Cfg 'warn up', tmr_wru%
2720 Cfg 'warn down', tmr_wrd%
2722 :
2724 PRINT#sc\\ '* - Score on'\\
2726 Cfg 'Count up', YN$(gme_cup%)
2728 Cfg 'Jump start', YN$(gme_jst%)
2730 Cfg 'Discard JS', YN$(gme_jsd%)
2732 PRINT#sc
2734 Cfg 'Auto save', YN$(autosave)
2736 :
2738 PRINT#sc\\ '* - Colours'\\
2740 Cfg 'Counter ink', Col$(col_imc)
2742 Cfg 'Counter paper', Col$(col_pmc)
2744 Cfg 'Timer ink', Col$(col_itm)
2746 Cfg 'Timer paper', Col$(col_ptm)
2748 Cfg 'Warn ink', Col$(col_itw)
2750 Cfg 'Warn paper', Col$(col_ptw)
2752 Cfg 'Timeout paper', Col$(col_pto)
2754 Cfg 'Timeout ink', Col$(col_ito)
2756 :
2758 PRINT#sc\\ '* - Button'\\
2760 Cfg 'Use button frame', YN$(butbf)
2762 Cfg 'Position x', butx%
2764 Cfg 'Position y', buty%
2766 :
2768 CLOSE#sc
2770 changed = 0
2772 END DEFine CfgSave
2774 :
2776 DEFine PROCedure Cfg(n$, e$)
2778 PRINT#sc; n$; TO 18; ':'! e$
2780 END DEFine Cfg
2782 :
2784 DEFine FuNction YN$(c)
2786 IF c: RETurn 'Yes': ELSE : RETurn 'No'
2788 END DEFine YN$
2790 :
2792 DEFine FuNction Col$(n)
2794 RETurn '$' & HEX$(n, 24)
2796 END DEFine Col$
2798 :
2800 DEFine FuNction CfgRead(fnm$)
2802 LOCal i%, il, sc, er, op, o$, l$, t$
2804 sc = GetMagic(fnm$, mgDmnr$)
2806 IF sc < 0: RETurn sc
2808 :
2810 er = 0
2812 :
2814 rem * - File locations
2816 rem If not a valid filename, dont change default
2818 t$ = Gcfg$('Help'): IF LEN(t$) > c5%: hlpprg$ = t$
2820 t$ = Gcfg$('Message'): IF LEN(t$) > c5%: msgprg$ = t$
2822 t$ = Gcfg$('ColourSquare'): IF LEN(t$) > c5%: colsq$ = t$
2824 t$ = Gcfg$('SoundDir'): IF LEN(t$) >= c4%: snd$ = t$
2826 :
2828 rem * - Game board
2830 xpos% = Gcfg$('x-pos')
2832 ypos% = Gcfg$('y-pos')
2834 :
2836 FOR i% = c0% TO DIMN(game%)
2838 rem * - Game #
2840 game%(i%, c0%) = GcfgY('current')
2842 game%(i%, c1%) = Gcfg$('x-grid')
2844 game%(i%, c2%) = GcfgY('linked')
2846 game%(i%, c3%) = Gcfg$('y-grid')
2848 game%(i%, c4%) = GcfgO('mines', gameM$)
2850 game%(i%, c5%) = GcfgO('timer', gameT$)
2852 END FOR i%
2854 :
2856 rem * - General
2858 sound = GcfgY('sound')
2860 SetSound sound
2862 :
2864 palno = Gcfg$('palette')
2866 spot% = ABS(GcfgO('spots', colour$))
2868 hit% = Gcfg$('HIT')
2870 saveonx = GcfgY('Save on Exit')
2872 :
2874 rem * - Timer
2876 tmr_fact = Gcfg$('factor')
2878 tmr_wru% = Gcfg$('warn up')
2880 tmr_wrd% = Gcfg$('warn down')
2882 :
2884 rem * - Score on
2886 gme_cup% = GcfgY('Count up')
2888 gme_jst% = GcfgY('Jump start')
2890 gme_jsd% = GcfgY('Discard JS')
2892 autosave = GcfgY('Auto save')
2894 :
2896 rem * - Colours
2898 col_imc = GcfgC('Counter ink')
2900 col_pmc = GcfgC('Counter paper')
2902 col_itm = GcfgC('Timer ink')
2904 col_ptm = GcfgC('Timer paper')
2906 col_itw = GcfgC('Warn ink')
2908 col_ptw = GcfgC('Warn paper')
2910 col_pto = GcfgC('Timeout paper')
2912 col_ito = GcfgC('Timeout ink')
2914 :
2916 rem * - Button
2918 butbf = GcfgY('Use button frame')
2920 butx% = Gcfg$('Position x')
2922 buty% = Gcfg$('Position y')
2924 :
2926 CLOSE#sc
2928 RETurn er
2930 END DEFine CfgRead
2932 :
2934 DEFine FuNction Gcfg$(tx$)
2936 REPeat il
2938 IF EOF(#sc): er = er + 1: EXIT il
2940 INPUT#sc; l$
2942 IF LEN(l$) = c0%: NEXT il
2944 p% = ': ' INSTR l$: IF p% = c0%: NEXT il
2946 IF (tx$ INSTR l$) <> c1%: NEXT il
2948 EXIT il
2950 END REPeat il
2952 IF er: RETurn nul$
2954 RETurn l$(p% + c2% TO LEN(l$))
2956 END DEFine Gcfg$
2958 :
2960 DEFine FuNction GcfgY(tx$)
2962 o$ = Gcfg$(tx$)
2964 IF 'yes' INSTR o$: RETurn 1: ELSE : RETurn 0
2966 END DEFine GcfgY
2968 :
2970 DEFine FuNction GcfgO(tx$, ar$)
2972 LOCal i%
2974 o$ = Gcfg$(tx$)
2976 op = 1000
2978 IF DIMN(ar$) > c0% THEN
2980 FOR i% = c0% TO DIMN(ar$)
2982 IF o$ == ar$(i%): op = cm1% - i%: EXIT i%
2984 END FOR i%
2986 ELSE
2988 IF o$ == ar$: op = cm1%
2990 END IF
2992 IF op = 1000: op = '0' & o$
2994 RETurn op
2996 END DEFine GcfgO
2998 :
3000 DEFine FuNction GcfgC(tx$)
3002 o$ = Gcfg$(tx$)
3004 IF LEN(o$) <> c7%: er = er + 1: RETurn 0
3006 RETurn HEX(o$(c2% TO LEN(o$)))
3008 END DEFine GcfgC
3010 :
3012 DEFine PROCedure (xp%, yp%)
3014 LOCal ml, mc, mk, x%, y%
3016 mc = FOPEN(con$): IF mc < 0: ERT mc
3018 MSETUP#mc; mn_look, xp%, yp%
3020 MITEM#mc; -4, c0%, nul$ & pal
3022 MDRAW#mc
3024 REPeat ml
3026 mk = MCALL(#mc; mk, c0%)
3028 PVAL#mc; tprec%
3030 x% = tprec%(10) + 92
3032 SELect ON mk
3034 = -2: Help#mc; 'hlp_look'
3036 = -3: rem Exit
3038 retrac = (tprec%(c5%) = c2%)
3040 IF changed: Ping ok$
3042 EXIT ml
3044 = -4: rem Palette
3046 IF tprec%(c5%) = c2% THEN
3048 pal = (MTEXT$(#mc; mk) + c1%) MOD c5%
3050 ELSE
3052 pal = (MTEXT$(#mc; mk) - c1%)
3054 IF pal < 0: pal = c4%
3056 END IF
3058 Palette pal
3060 MCLEAR#mc: MDRAW#mc; mn_look, xp%, yp%
3062 MITEM#mc; mk, 0, nul$ & pal
3064 = -5: rem Spots
3066 MenuSpotsel x%, tprec%(11) + 40
3068 = -6: rem Run
3070 y% = tprec%(11) + 76
3072 MenuColsel 'Run', x%, y%, col_ptm, col_itm, tmr_start%
3074 = -7: rem Warn
3076 y% = tprec%(11) + 92
3078 MenuColsel 'Warn', x%, y%, col_ptw, col_itw, tmr_wrn%
3080 = -8: rem Timeout
3082 y% = tprec%(11) + 108
3084 MenuColsel 'Time', x%, y%, col_pto, col_ito, tmr_end%
3086 = -9: rem Minecount
3088 y% = tprec%(11) + 124
3090 MenuColsel 'Count', x%, y%, col_pmc, col_imc, mcount%
3092 END SELect
3094 IF retrac: EXIT ml
3096 END REPeat ml
3098 IF pal <> palno THEN
3100 redraw = 1
3102 Palette palno: rem Dont change before exit config
3104 END IF
3106 MCLEAR#mc: CLOSE#mc
3108 END DEFine MenuLook
3110 :
3112 DEFine PROCedure Palette(p%)
3114 LOCal cp, adr, c$(c6%)
3116 IF p% = c4% THEN
3118 IF palset < 0 THEN
3120 rem No palette available
3122 p% = c0%: Burp 'illegal'
3124 ELSE
3126 IF palset = 0 THEN
3128 palset = ALCHP(SP_GETCOUNT * c2%)
3130 IF palset = 0 OR palset = -3 THEN
3132 palset = 0: p% = c0%
3134 SP_JOBPAL -1, p%
3136 ErrMess 'Not enough memory!'
3138 ELSE
3140 LoadPal
3142 END IF
3144 ELSE
3146 SP_JOBOWNPAL -1, palset
3148 END IF
3150 END IF
3152 ELSE
3154 SP_JOBPAL -1, p%
3156 END IF
3158 END DEFine Palette
3160 :
3162 DEFine PROCedure LoadPal
3164 rem Palette subroutine
3166 cp = FOP_IN(homed$ & paln$)
3168 IF cp < 0 THEN
3170 RECHP palset
3172 palset = 0: p% = c0%
3174 SP_JOBPAL -1, p%
3176 ErrMess 'Palette\' & paln$ & '\\not found!'
3178 ELSE
3180 FOR adr = palset TO palset + (SP_GETCOUNT - c1%) * c2% STEP c2%
3182 INPUT#cp; c$
3184 POKE_W adr, HEX(c$(c2% TO LEN(c$)))
3186 END FOR adr
3188 CLOSE#cp
3190 SP_JOBOWNPAL -1, palset
3192 END IF
3194 END DEFine LoadPal
3196 :
3198 DEFine PROCedure (xp%, yp%)
3200 LOCal mc, mk, s%
3202 mc = FOPEN(con$): IF mc < 0: ERT mc
3204 MSETUP#mc; mn_spotsel, xp%, yp%
3206 s% = MSTAT%(#mc; -spot%, c1%\ c0%)
3208 s% = spot%
3210 MDRAW#mc
3212 mk = MCALL(#mc; mk, s%)
3214 PVAL#mc; tprec%
3216 IF tprec%(c5%) = c2% THEN
3218 spot% = ABS(mk)
3220 IF s% <> spot%: changed = changed + 1
3222 Ping ok$
3224 END IF
3226 MCLEAR#mc: CLOSE#mc
3228 END DEFine MenuSpotsel
3230 :
3232 DEFine PROCedure (n$, xp%, yp%, colp, coli, t%)
3234 LOCal ml, cl, mc, mk, s%, x%, y%, c, c$(c4%)
3236 LOCal ci, cp, chg
3238 rem GLObal colsq, menv%, llen, base, bpp%
3240 rem Alters parameters!
3242 rem V0.01 April 18th 2004
3244 :
3246 IF colsq = 0 THEN
3248 colsq = FLEN(\colsq$)
3250 IF colsq > 0 THEN
3252 colsq = ALCHP(colsq)
3254 LBYTES colsq$, colsq
3256 ELSE
3258 Burp 'illegal': RETurn
3260 END IF
3262 END IF
3264 :
3266 mc = FOPEN(con$): IF mc < 0: ERT mc
3268 MSETUP#mc; mn_colour, xp%, yp%
3270 MINOB#mc; c2%, c1%, Centre$(c6%, n$)
3272 MDRAW#mc
3274 p% = MSTAT%(#mc; -3 TO c1%)
3276 MWINDOW#mc; c5%! c0%
3278 PAPER#mc; colp: INK#mc; coli
3280 timer_led#mc; c3%, Z$(t%)
3282 MWINDOW#mc; c1%
3284 SPRW#mc; c0%, c0%, colsq
3286 ok% = c1%: s% = c0%
3288 ci = coli: cp = colp: chg = 0
3290 COLOUR_NATIVE
3292 REPeat ml
3294 mk = MCALL(#mc; mk, s%)
3296 SELect ON mk
3298 = -2: rem Exit
3300 PVAL#mc; tprec%
3302 retrac = (tprec%(c5%) = c2%)
3304 chg = 0
3306 EXIT ml
3308 = -3: rem Paper
3310 TogglePink mk
3312 ok% = c1%
3314 = -4: rem Ink
3316 TogglePink mk
3318 ok% = c2%
3320 = 1: rem Colour square
3322 PVAL#mc; tprec%
3324 x% = tprec%(14): y% = tprec%(15)
3326 REPeat cl
3328 RDPT#mc; menv%, x%, y%
3330 PVAL#mc; tprec%
3332 IF tprec%(c2%) <> c0%: EXIT cl: rem Out of this apwin
3334 IF tprec%(c5%) = c2% THEN
3336 IF ok% = c1%
3338 cp = c: TogglePink -4
3340 ok% = c2%
3342 ELSE
3344 IF ok% = c0%
3346 IF MSTAT%(#mc; -3): ok% = c1%: ELSE : ok% = c2%
3348 NEXT cl
3350 ELSE
3352 ci = c: TogglePink -3
3354 ok% = c1%
3356 END IF
3358 END IF
3360 chg = 1
3362 ELSE
3364 IF tprec%(c5%) = c1% THEN
3366 IF ok% = c1%: cp = c: ELSE : ci = c
3368 chg = 1
3370 ok% = c0%
3372 EXIT cl: rem End colour select
3374 ELSE
3376 IF ok% = c0%: EXIT cl
3378 END IF
3380 END IF
3382 IF bpp% = c1% THEN
3384 c = PEEK(base + llen * y% + x%)
3386 ELSE
3388 c = PEEK_W(base + llen * y% + x% + x%)
3390 IF DISP_TYPE = 32: c = PCBO(c)
3392 END IF
3394 MWINDOW#mc; c5%! c0%
3396 IF ok% = c1% THEN
3398 PAPER#mc; c
3400 ELSE
3402 INK#mc; c
3404 END IF
3406 timer_led#mc; c3%, Z$(t%)
3408 END REPeat cl
3410 s% = c0%
3412 = -1025: rem DO Counter
3414 Ping ok$: EXIT ml
3416 = REMAINDER : Burp 'illegal'
3418 END SELect
3420 END REPeat ml
3422 MCLEAR#mc: CLOSE#mc
3424 IF chg THEN
3426 changed = changed + chg
3428 redraw = 1
3430 IF DISP_TYPE = 32: ci = PCBO(ci): cp = PCBO(cp)
3432 coli = nat2rgb(ci): colp = nat2rgb(cp)
3434 END IF
3436 COLOUR_24
3438 END DEFine MenuColsel
3440 :
3442 DEFine PROCedure TogglePink(k)
3444 LOCal k1, k2
3446 IF k = -3: k1 = -3: k2 = -4: ELSE : k2 = -3: k1 = -4
3448 s% = MSTAT%(#mc; k2, c0%\ c0%)
3450 s% = MSTAT%(#mc; k1, c1% TO c0%)
3452 END DEFine TogglePink
3454 :
3456 DEFine FuNction PCBO(n)
3458 LOCal c$(c4%)
3460 rem Little-endian for QPC
3462 c$ = HEX$(n, _w%)
3464 RETurn HEX(c$(c3% TO c4%) & c$(c1% TO c2%))
3466 rem c = c div 256 + (c mod 256) * 256: Doesnt work
3468 END DEFine PCBO
3470 :
3472 rem NumSel
3474 :
3476 DEFine FuNction NumSel%(xp%, yp%, st%, en%, cr%, opt$)
3478 LOCal nl, cn, nk, o%, n%, t%, o$(c8%)
3480 rem V0.01 Positive only
3482 :
3484 o% = cr%
3486 o$ = GetOpt$(o%, opt$)
3488 IF o% < c0%: n% = st%: ELSE : n% = o%
3490 t% = c0%
3492 cn = FOPEN(con$)
3494 MSETUP#cn; mn_numsel, xp%, yp%
3496 MITEM#cn; -2, c0%, o$
3498 MDRAW#cn
3500 REPeat nl
3502 nk = MCALL(#cn; nk, c0%)
3504 PVAL#cn; tprec%
3506 SELect ON nk
3508 = -1: rem Up
3510 IF tprec%(c5%) = c2% THEN
3512 ScrollUp #cn, c10%
3514 ELSE
3516 ScrollUp #cn; c1%
3518 END IF
3520 o% = n%
3522 = -2: rem Dial
3524 IF tprec%(c5%) = c1% OR tprec%(c6%) = esc% THEN
3526 o% = cr%: rem Discard changes
3528 END IF
3530 EXIT nl
3532 = -3: rem Down
3534 IF tprec%(c5%) = c2% THEN
3536 ScrollDn #cn; c10%
3538 ELSE
3540 ScrollDn #cn; c1%
3542 END IF
3544 o% = n%
3546 = -4, -5: rem Left/Right
3548 IF mk = -4 THEN
3550 t% = (t% - c1%) MOD (DIMN(opt$) + c2%)
3552 ELSE
3554 t% = (t% + c1%) MOD (DIMN(opt$) + c2%)
3556 END IF
3558 IF t% > DIMN(opt$) THEN
3560 o% = n%
3562 ELSE
3564 o% = cm1% - t%
3566 END IF
3568 o$ = GetOpt$(o%, opt$)
3570 MITEM #cn; -2, c0%, o$
3572 END SELect
3574 END REPeat nl
3576 MCLEAR#cn: CLOSE#cn
3578 RETurn o%: rem ret o$
3580 END DEFine NumSel%
3582 :
3584 DEFine FuNction GetOpt$(p%, opt$)
3586 IF p% < c0% THEN
3588 IF DIMN(opt$) = c0% THEN
3590 RETurn opt$: rem Plain variable
3592 ELSE
3594 RETurn opt$(ABS(p%) - c1%): rem Array
3596 END IF
3598 END IF
3600 RETurn nul$ & p%: rem Anything else is a number
3602 END DEFine GetOpt$
3604 :
3606 DEFine PROCedure ScrollUp(ch, a%)
3608 LOCal sul, x%, y%
3610 x% = tprec%(14): y% = tprec%(15)
3612 RDPT#ch; nsvi%, x%, y%, nstio%
3614 REPeat sul
3616 RDPT#ch; nsvo%
3618 PVAL#ch; tprec%
3620 NSInc a%
3622 s% = MSTAT%(#ch; -2 TO c0%)
3624 IF tprec%(c5%) = c0%: EXIT sul
3626 END REPeat sul
3628 t% = c1%
3630 END DEFine ScrollUp
3632 :
3634 DEFine PROCedure ScrollDn(ch, a%)
3636 LOCal sul, x%, y%
3638 x% = tprec%(14): y% = tprec%(15)
3640 RDPT#ch; nsvi%, x%, y%, nstio%
3642 REPeat sul
3644 RDPT#ch; nsvo%
3646 PVAL#ch; tprec%
3648 NSDec a%
3650 s% = MSTAT%(#ch; -2 TO c0%)
3652 IF tprec%(c5%) = c0%: EXIT sul
3654 END REPeat sul
3656 t% = n%
3658 END DEFine ScrollDn
3660 :
3662 DEFine PROCedure NSInc(a%)
3664 rem Subroutine of NumSel%
3666 n% = (n% + a%) MOD (en% + c1%)
3668 IF n% < st%: n% = st%
3670 MITEM#cn; -2, c0%, nul$ & n%
3672 END DEFine NSInc
3674 :
3676 DEFine PROCedure NSDec(a%)
3678 rem Subroutine of NumSel%
3680 n% = (n% - a%) MOD (en% + c1%)
3682 IF n% < st%: n% = en%
3684 MITEM#cn; -2, c0%, nul$ & n%
3686 END DEFine NSDec
3688 :
3690 rem End Numsel
3692 :
3694 DEFine FuNction (xp%, yp%)
3696 LOCal ml, cl, cm, mk, s%, chg
3698 rem V0.01 May 10th 2004
3700 rem V0.02 March 20th 2005 added Help
3702 :
3704 chg = 0
3706 cm = FOPEN(con$): IF cm < 0: ERT cm
3708 MSETUP#cm; mn_score, xp%, yp%
3710 MITEM#cm; -4, spr%, sp_spotn(spot%)
3712 MITEM#cm; -5, spr%, sp_spotn(spot%)
3714 MITEM#cm; -6, spr%, sp_spotn(spot%)
3716 MITEM#cm; -7, spr%, sp_spotn(spot%)
3718 s% = MSTAT%(#cm; -4, gme_cup%\ c0%)
3720 s% = MSTAT%(#cm; -5, gme_jst%\ c0%)
3722 s% = MSTAT%(#cm; -6, gme_jsd%\ c0%)
3724 s% = MSTAT%(#cm; -7, autosave\ c0%)
3726 MDRAW#cm
3728 s% = c0%
3730 REPeat ml
3732 mk = MCALL(#cm; mk, s%)
3734 SELect ON mk
3736 = -2: Help#cm; 'hlp_score'
3738 NEXT ml
3740 = -3: rem Exit
3742 IF chg = 0 THEN
3744 PVAL#cm; tprec%
3746 retrac = (tprec%(c5%) = c2%)
3748 ELSE
3750 Ping ok$
3752 END IF
3754 EXIT ml
3756 = -4: rem Count up
3758 s% = MSTAT%(#cm; mk)
3760 gme_cup% = s%
3762 = -5: rem Jump start
3764 s% = MSTAT%(#cm; mk)
3766 gme_jst% = s%
3768 = -6: rem Discard
3770 s% = MSTAT%(#cm; mk)
3772 gme_jsd% = s%
3774 = -7: rem Autosave
3776 s% = MSTAT%(#cm; mk)
3778 autosave = s%
3780 END SELect
3782 chg = 1
3784 END REPeat ml
3786 MCLEAR#cm: CLOSE#cm
3788 RETurn chg
3790 END DEFine MenuScore
3792 :
3794 DEFine PROCedure UpdtGame
3796 LOCal i%, j%, s%, it%
3798 FOR i% = c0% TO DIMN(game%)
3800 FOR j% = c0% TO DIMN(game%(c0%))
3802 it% = -4 - (i% * (DIMN(game%(c0%)) + c1%) + j%)
3804 SELect ON it%
3806 = -4, -10, -16: rem Spots
3808 rem Current game
3810 IF gme_chg: game%(i%, j%) = c0%: rem No game selected => game changed
3812 MITEM#cm; it%, spr%, sp_spotn(spot%)
3814 s% = MSTAT%(#cm; it%, game%(i%, j%)\ c0%)
3816 = -5, -7, -11, -13, -17, -19: rem Grid x, y
3818 MITEM#cm; it%, c0%, nul$ & game%(i%, j%)
3820 = -6, -12, -18: rem x
3822 rem If x selected then gridy is unavailable
3824 IF game%(i%, c1%) <> game%(i%, c3%) THEN
3826 rem But if x/y size different then unlock
3828 game%(i%, j%) = c0%
3830 END IF
3832 IF game%(i%, j%) = c1%: st% = MSTAT%(#cm; it% - c1%, cm1%\ c0%)
3834 = -8, -14, -20: rem Mines
3836 o$ = GetOpt$(game%(i%, j%), gameM$)
3838 MITEM#cm; it%, c0%, o$
3840 = -9, -15, -21: rem Timer
3842 o$ = GetOpt$(game%(i%, j%), gameT$)
3844 MITEM#cm; it%, c0%, o$
3846 END SELect
3848 END FOR j%
3850 END FOR i%
3852 END DEFine UpdtGame
3854 :
3856 DEFine FuNction (xp%, yp%)
3858 LOCal i%, j%, ml, cl, cm, mk, s%, st%, chg, o$(c6%)
3860 rem V0.01 May 10th 2004
3862 rem V0.02 March 14th 2005 Removed default game
3864 rem V0.03 March 19th 2005 Added Help
3866 rem V0.04 March 26th 2005 Fixed positioning. External changes reflected
3868 :
3870 chg = 0
3872 cm = FOPEN(con$): IF cm < 0: ERT cm
3874 MSETUP#cm; mn_game, xp%, yp%
3876 UpdtGame
3878 rem Save now
3880 s% = MSTAT%(#cm; -22, cm1%\ c0%)
3882 MDRAW#cm
3884 s% = c0%
3886 REPeat ml
3888 mk = MCALL(#cm; mk, s%)
3890 i% = ABS(mk + c4%) DIV (DIMN(game%(c0%)) + c1%)
3892 j% = ABS(mk + c4%) MOD (DIMN(game%(c0%)) + c1%)
3894 SELect ON mk
3896 = -2: Help#cm; 'hlp_game'
3898 = -3: rem Exit
3900 IF chg = 0 THEN
3902 PVAL#cm; tprec%
3904 retrac = (tprec%(c5%) = c2%)
3906 ELSE
3908 Ping ok$
3910 END IF
3912 EXIT ml
3914 = -4, -10, -16: rem Select game
3916 PVAL#cm; tprec%
3918 s% = MSTAT%(#cm; mk)
3920 IF gme_chg AND tprec%(c5%) = c1% THEN
3922 game%(i%, c0%) = c1%
3924 game%(i%, c1%) = xdim%
3926 game%(i%, c2%) = xdim% = ydim%
3928 game%(i%, c3%) = ydim%
3930 IF gme_mcauto% = on%: game%(i%, c4%) = cm1%: ELSE : game%(i%, c4%) = mcount%
3932 IF tmr_use% = off% THEN
3934 game%(i%, c5%) = -3
3936 ELSE : IF tmr_auto% = on% THEN
3938 game%(i%, c5%) = cm1%
3940 ELSE : IF tmr_cup% = on% THEN
3942 game%(i%, c5%) = -2
3944 ELSE : game%(i%, c5%) = tmr_start%
3946 END IF : END IF : END IF
3948 rem if tmr_lrc% = on%: game%(i%, c5%) = -4 Not yet implemented
3950 gme_chg = 0: UpdtGame
3952 ELSE
3954 FOR j% = -16, -10, -4: st% = MSTAT%(#cm; j%, c0%\ c0%)
3956 FOR j% = c0% TO DIMN(game%): game%(j%, c0%) = c0%
3958 st% = MSTAT%(#cm; mk, s%\ c0%)
3960 game%(i%, c0%) = c1%: s% = c1%
3962 IF game%(i%, c1%) > maxx%: game%(i%, c1%) = maxx%: rem No bigger that max
3964 IF game%(i%, c3%) > maxy%: game%(i%, c3%) = maxy%
3966 gme_chg = 0
3968 END IF
3970 redraw = 1
3972 IF tprec%(c5%) = c2%: EXIT ml
3974 = -5, -11, -17: rem Grid x
3976 game%(i%, j%) = NumSel%(-1, -1, c10%, maxx%, game%(i%, j%), game%(i%, j%))
3978 MITEM#cm; mk, c0%, nul$ & game%(i%, j%)
3980 IF game%(i%, c2%) = c1% THEN
3982 MITEM#cm; mk - c2%, c0%, nul$ & game%(i%, j%)
3984 game%(i%, c3%) = game%(i%, j%)
3986 END IF
3988 IF game%(i%, c4%) >= c0% THEN
3990 Maxminm i%: rem Calculate max/min no. mines
3992 IF game%(i%, c4%) > maxm%: game%(i%, c4%) = maxm%
3994 IF game%(i%, c4%) < minm%: game%(i%, c4%) = minm%
3996 MITEM#cm; mk - c3%, c0%, nul$ & game%(i%, c4%)
3998 END IF
4000 IF game%(i%, c0%) = c1%: redraw = 1: ELSE : chg = 1
4002 = -7, -13, -19: rem Grid y
4004 game%(i%, j%) = NumSel%(-1, -1, c10%, maxy%, game%(i%, j%), game%(i%, j%))
4006 MITEM#cm; mk, c0%, nul$ & game%(i%, j%)
4008 IF game%(i%, c2%) = c1% THEN
4010 MITEM#cm; mk + c2%, c0%, nul$ & game%(i%, j%)
4012 game%(i%, c1%) = game%(i%, j%)
4014 END IF
4016 IF game%(i%, c4%) >= c0% THEN
4018 Maxminm i%: rem Calculate max/min no. mines
4020 IF game%(i%, c4%) > maxm%: game%(i%, c4%) = maxm%
4022 IF game%(i%, c4%) < minm%: game%(i%, c4%) = minm%
4024 MITEM#cm; mk - c1%, c0%, nul$ & game%(i%, c4%)
4026 END IF
4028 IF game%(i%, c0%) = c1%: redraw = 1: ELSE : chg = 1
4030 = -6, -12, -18: rem x
4032 s% = MSTAT%(#cm; mk)
4034 game%(i%, j%) = s%
4036 IF s% = c1% THEN
4038 st% = MSTAT%(#cm; mk - c1%, cm1%\ c0%)
4040 ELSE
4042 st% = MSTAT%(#cm; mk - c1%, c0%\ c0%)
4044 END IF
4046 chg = 1
4048 = -8, -14, -20: rem Mines
4050 Maxminm i%: rem Calculate max/min no. mines
4052 game%(i%, j%) = NumSel%(-1, -1, minm%, maxm%, game%(i%, j%), gameM$)
4054 o$ = GetOpt$(game%(i%, j%), gameM$)
4056 MITEM#cm; mk, c0%, o$
4058 s% = c0%
4060 IF game%(i%, c0%) = c1%: redraw = 1: ELSE : chg = 1
4062 = -9, -15, -21: rem Timer
4064 game%(i%, j%) = NumSel%(-1, -1, c5%, 999, game%(i%, j%), gameT$)
4066 o$ = GetOpt$(game%(i%, j%), gameT$)
4068 MITEM#cm; mk, c0%, o$
4070 s% = c0%
4072 IF game%(i%, c0%) = c1%: redraw = 1: ELSE : chg = 1
4074 = -22: rem Save now
4076 CfgSave: Ping 'saved'
4078 s% = cm1%: chg = 0
4080 END SELect
4082 IF chg OR redraw: st% = MSTAT%(#cm; -22, c0%\ c0%)
4084 END REPeat ml
4086 MCLEAR#cm: CLOSE#cm
4088 IF redraw: chg = 1
4090 TechnicalResume
4092 RETurn chg
4094 END DEFine MenuGame
4096 :
4098 DEFine PROCedure Maxminm(g%)
4100 rem Calculate max and min number of mines for this grid size
4102 rem This to avoid crash (max too large) or stack overflow (min too small)
4104 minm% = game%(g%, c1%) * game%(g%, c3%) DIV 12: rem Min mines
4106 maxm% = minm% * c4%: rem Max mines
4108 END DEFine Maxminm
4110 :
4112 DEFine PROCedure SetGame
4114 LOCal i%, g%
4116 g% = cm1%
4118 rem Find current game
4120 FOR i% = c0% TO DIMN(game%)
4122 IF game%(i%, c0%) = c1%: g% = i%: EXIT i%
4124 END FOR i%
4126 IF g% = cm1%: g% = c0%: rem Nine found: Default is game #0
4128 grdx% = game%(g%, c1%) - c1%: grdy% = game%(g%, c3%) - c1%
4130 IF game%(g%, c4%) = cm1% THEN
4132 gme_mcauto% = on%
4134 ELSE
4136 gme_mcauto% = off%
4138 mcount% = game%(g%, c4%)
4140 END IF
4142 i% = game%(g%, c5%)
4144 SELect ON i%
4146 = cm1%: rem Auto
4148 tmr_use% = on%
4150 tmr_auto% = on%
4152 tmr_cup% = off%
4154 = -2: rem Count time
4156 tmr_use% = on%
4158 tmr_cup% = on%
4160 tmr_auto% = off%
4162 = -3: rem No timer
4164 tmr_use% = off%
4166 tmr_auto% = off%
4168 tmr_cup% = off%
4170 = REMAINDER : rem Seconds
4172 tmr_use% = on%
4174 tmr_auto% = off%
4176 tmr_cup% = off%
4178 tmr_start% = game%(g%, c5%)
4180 END SELect
4182 END DEFine SetGame
4184 :
4186 DEFine PROCedure
4188 LOCal wl, cm, mk
4190 LOCal xs%, ys%, dx%, i%, j%
4192 TechnicalPause
4194 xs% = xsize% - 20: ys% = ysize% - 60
4196 cm = FOPEN(con$): ERT cm
4198 MSETUP#cm; mn_info, prec%(c10%) + c10%, prec%(11) + 40, xs%, ys%
4200 MINOB#cm; c2%, c1%, 'Stats'
4202 MDRAW#cm; mn_info
4204 MWINDOW#cm; c6%! c0%
4206 OVER#cm; c0%
4208 xs% = xs% - c4%: ys% = ys% - 26
4210 dx% = xs% DIV 50: c% = c0%
4212 FOR i% = c0% TO xs% - dx% STEP dx%
4214 j% = RND(c% TO ys%): c% = c% + c2%
4216 WM_BLOCK#cm; dx%, j%, i%, ys% - j%, sp_infwinfg%
4218 END FOR i%
4220 WM_STRIP#cm; sp_infwinbg%
4222 CURSOR#cm; (xs% - 126) DIV c2%, ys% DIV c2%
4224 PRINT#cm; ' Stats not available '
4226 REPeat wl
4228 mk = MCALL(#cm; mk, c0%)
4230 SELect ON mk
4232 = -2: Help#cm; 'hlp_stats'
4234 = -3: Ping ok$: EXIT wl
4236 END SELect
4238 END REPeat wl
4240 MCLEAR#cm: CLOSE#cm
4242 TechnicalResume
4244 END DEFine MenuStats
4246 :
4248 DEFine PROCedure GameLoose
4250 TimerStop
4252 game = lost
4254 MITEM#ch%; li_new%, spr%, sp_sour
4256 END DEFine GameLoose
4258 :
4260 DEFine PROCedure GameWin
4262 TimerStop
4264 game = won
4266 Ping 'win'
4268 MITEM#ch%; li_new%, spr%, sp_cool
4270 END DEFine GameWin
4272 :
4274 DEFine PROCedure GameStart
4276 LOCal grd%
4278 grd% = grdx% * grdy%
4280 moves% = off%: rem No moves have been made
4282 IF 0 THEN
4284 rem ####
4286 IF autosave THEN
4288 sco = GetMagic(fnmscore$, mgDmsc$)
4290 IF sco < 0: ErrMess 'Opening score file\' & sco: RETurn
4292 PUT#sco\ 2E9; DATE, grd%, c0%, mcount%, mleft%
4294 CLOSE#sco
4296 END IF
4298 END IF
4300 TimerStart
4302 game = playing%
4304 END DEFine GameStart
4306 :
4308 DEFine PROCedure GameStop
4310 rem Stop game = loose game except in certain circumstances
4312 IF moves% = on% THEN
4314 game = lost
4316 ELSE
4318 IF gme_jsd% = off% AND game = playing% THEN
4320 game = stopped
4322 ELSE
4324 game = lost
4326 END IF
4328 END IF
4330 END DEFine GameStop
4332 :
4334 DEFine FuNction GetScore
4336 sco = GetMagic(fnmscore$, mgDmsc$)
4338 IF sco < 0: RETurn sco
4340 rem ###
4342 CLOSE#sco
4344 END DEFine GetScore
4346 :
4348 DEFine FuNction GetMagic(fnm$, mg$)
4350 LOCal i%, ch
4352 ch = FOPEN(fnm$): IF ch < 0: RETurn ch
4354 FOR i% = c1% TO LEN(mg$)
4356 IF INKEY$(#ch; cm1%) <> mg$(i%): CLOSE#ch: RETurn -12
4358 END FOR i%
4360 dummy% = CODE(INKEY$(#ch; cm1%)): rem Final lf
4362 RETurn ch
4364 END DEFine GetMagic
4366 :
4368 DEFine PROCedure
4370 redraw = 0
4372 xp% = prec%(c10%) + 90: yp% = prec%(11) + 38
4374 IF MenuGame(xp%, yp%): Ping ok$
4376 IF redraw THEN
4378 SetGame
4380 NewWin prec%(c10%) - c2%, prec%(11) - c2%
4382 END IF
4384 END DEFine GameMenu
4386 :
4388 rem Messages start
4390 :
4392 DEFine FuNction PreWarn(msg$, ch1$, ch2$, ch3$)
4394 LOCal adr, r, xo%, yo%, par$
4396 Burp 'warn'
4398 xo% = (SCR_XLIM(#ch%) - 240) DIV c2%
4400 yo% = (SCR_YLIM(#ch%) - 100) DIV c2%
4402 adr = ALCHP(4)
4404 par$ = HEX$(adr, 32) & hsh$ & cfname$ & spc$ & cfver$ & hsh$ & msg$ & hsh$ & ch1$ & hsh$ & ch2$ >>
& hsh$ & ch3$
4406 EW msgprg$; HEX$(240, _w%) & HEX$(100, _w%) & HEX$(xo%, _w%) & HEX$(yo%, _w%) & HEX$(c0%, 32) & >>
par$
4408 r = PEEK_L(adr): RECHP adr
4410 RETurn r
4412 END DEFine PreWarn
4414 :
4416 DEFine PROCedure ErrMess(tx$)
4418 LOCal i%, ce, c%, x%, y%
4420 Burp 'warn'
4422 ce = FOPEN(con$)
4424 rem Count lines in message (max == 6, not checked)
4426 c% = c0%
4428 FOR i% = c1% TO LEN(tx$)
4430 IF tx$(i%) = bks$: c% = c% + c1%
4432 END FOR i%
4434 IF c% < c3%: c% = c3%
4436 y% = prec%(11) + (prec%(c9%) - (c% * c10% + 48)) DIV c2%
4438 x% = prec%(c10%) + (prec%(c8%) - 136) DIV c2%
4440 MDRAW#ce; mn_err, x%, y%, 136, 56 + c% * c10%
4442 MWINDOW#ce; c3%! c0%: WM_INK#ce; sp_errfg%
4444 Split#ce, 21, tx$
4446 er = MCALL(#ce): MCLEAR#ce: CLOSE#ce
4448 END DEFine ErrMess
4450 :
4452 DEFine PROCedure Split(ch%, w%, t$)
4454 LOCal wl, p%, s%
4456 rem Slice lines at \ and print centred
4458 rem v0.01 March 25th 2005
4460 p% = c1%
4462 REPeat wl
4464 IF p% > LEN(t$): EXIT wl
4466 s% = '\' INSTR t$(p% TO LEN(t$))
4468 IF s% > 0 THEN
4470 PRINT#ch%; Centre$(w%, t$(p% TO p% + s% - c2%))
4472 p% = p% + s%
4474 ELSE
4476 PRINT#ch%;! Centre$(w%, t$(p% TO LEN(t$)))
4478 EXIT wl
4480 END IF
4482 END REPeat wl
4484 END DEFine Split
4486 :
4488 DEFine PROCedure Help(hc%, hlp$)
4490 LOCal t%
4492 t% = tpause%
4494 IF t% = c0%: TechnicalPause
4496 MessWin#hc%; hlpxs%, hlpys%, hlpprg$, homed$ & hlp$ & hx$, prec%
4498 IF t% = c0%: TechnicalResume
4500 END DEFine Help
4502 :
4504 DEFine PROCedure About
4506 Ping 'startup'
4508 IF Choose%(#ch%; 'About', Centre$(abtcx%, cfname$ & spc$ & cfver$) & '\' & Centre$(abtcx%, ' >>
©pjwitte 2oo4'), ok$, 'Readme', nul$) = c2% THEN
4510 Help#ch%; 'Readme'
4512 END IF
4514 Ping ok$
4516 END DEFine About
4518 :
4520 DEFine FuNction Choose%(cc%, tit$, msg$, ch1$, ch2$, ch3$)
4522 LOCal adr, r
4524 TechnicalPause
4526 IF prec%(c8%) <= wrnxs% THEN
4528 prec%(c9%) = wrnys% + wrnys%
4530 adr = ALCHP(4)
4532 MessWin#cc%; wrnxs%, wrnys%, msgprg$, HEX$(adr, 32) & hsh$ & tit$ & hsh$ & msg$ & hsh$ & ch1$ >>
& hsh$ & ch2$ & hsh$ & ch3$, prec%
4534 r = PEEK_L(adr): RECHP adr
4536 ELSE
4538 r = ITEM_SELECT(tit$, msg$, ch1$, ch2$, ch3$)
4540 END IF
4542 TechnicalResume
4544 RETurn r
4546 END DEFine Choose%
4548 :
4550 DEFine FuNction Warn(msg$, ch1$, ch2$, ch3$)
4552 Burp 'warn'
4554 RETurn Choose%(#ch%; 'Warning', msg$, ch1$, ch2$, ch3$)
4556 END DEFine Warn
4558 :
4560 DEFine FuNction WarnGame
4562 IF game = playing% AND moves% = on% THEN
4564 IF Warn(Centre$(39, 'Game in progress!') & '\If you continue the game is lost!','Resume', ' >>
Quit game', nul$) = 2 THEN
4566 Burp 'loose': GameLoose
4568 RETurn 1
4570 ELSE
4572 RETurn 0
4574 END IF
4576 ELSE
4578 IF moves% = off%: TechnicalPause
4580 END IF
4582 RETurn 1
4584 END DEFine WarnGame
4586 :
4588 rem <- MessWin ->
4590 :
4592 DEFine PROCedure MessWin(ch%, sx%, sy%, prg$, par$, pr%)
4594 LOCal hl, id, xo%, yo%, p$(c8%)
4596 rem Display a message window larger than the job window
4598 rem V0.01 February 6th 2005
4600 rem V0.02 March 25th 2005 Supports jobownpal
4602 :
4604 rem Parameters:
4606 rem window x and y size, display program name, additional
4608 rem parameter, current pointer record
4610 :
4612 rem The job at the other end must parse the following
4614 rem standard parameters (in consecutive hex):
4616 rem sizex.w, sizey.w, xorig.w, yorig.w, syspal.b
4618 rem The calling routine can append additional parameters
4620 rem in par$
4622 :
4624 xo% = pr%(c10%) + pr%(c8%) DIV c2%
4626 yo% = pr%(11) + pr%(c9%) DIV c2%
4628 xo% = xo% - (sx% DIV c2%): IF xo% < c0%: xo% = c0%
4630 yo% = yo% - (sy% DIV c2%): IF yo% < c0%: yo% = c0%
4632 IF palno = 4: p$ = HEX$(palset, 32): ELSE : p$ = HEX$(palno, 32)
4634 IF (xo% + sx% + c4%) > SCR_XLIM(#ch%): xo% = SCR_XLIM(#ch%) - sx% - c4%
4636 IF (yo% + sy% + c4%) > SCR_YLIM(#ch%): yo% = SCR_YLIM(#ch%) - sy% - c4%
4638 id = EXF(prg$; HEX$(sx%, _w%) & HEX$(sy%, _w%) & HEX$(xo%, _w%) & HEX$(yo%, _w%) & p$ & par$)
4640 :
4642 REPeat hl
4644 RDPT#ch%; mwtv%
4646 IF JobLives(id) THEN
4648 PTOP#ch%; id
4650 ELSE
4652 EXIT hl
4654 END IF
4656 END REPeat hl
4658 END DEFine MessWin
4660 :
4662 DEFine FuNction JobLives(jid)
4664 LOCal nj, n
4666 IF jid = 0: RETurn 1
4668 REPeat nj
4670 n = NXJOB(n, 0)
4672 IF n = 0 OR n = jid: EXIT nj
4674 END REPeat nj
4676 RETurn n
4678 END DEFine JobLives
4680 :
4682 rem Messages end
4684 :
4686 DEFine FuNction Spra$(spr)
4688 RETurn '@?' & LIN2STR$(spr)
4690 END DEFine Spra$
4692 :
4694 DEFine PROCedure Ping(nm$)
4696 rem Nice sound
4698 IF sound = 2 THEN
4700 IF FTEST(snd$ & nm$ & sx$) = 0 THEN
4702 KILLSOUND: SOUNDFILE snd$ & nm$ & sx$
4704 ELSE
4706 BEEP c2%, c2%
4708 END IF
4710 ELSE
4712 IF sound: BEEP c2%, c2%
4714 END IF
4716 END DEFine Ping
4718 :
4720 DEFine PROCedure Burp(nm$)
4722 rem Bad sound
4724 IF sound = 2 THEN
4726 IF FTEST(snd$ & nm$ & sx$) = 0 THEN
4728 KILLSOUND: SOUNDFILE snd$ & nm$ & sx$
4730 ELSE
4732 BEEP 999, 999
4734 END IF
4736 ELSE
4738 IF sound: BEEP 999, 999
4740 END IF
4742 END DEFine Burp
4744 :
4746 DEFine PROCedure SetSound(s)
4748 IF s THEN
4750 IF ssspresent: sound = 2: ELSE : sound = 1
4752 ELSE
4754 sound = 0
4756 END IF
4758 END DEFine SetSound
4760 :
4762 DEFine PROCedure SetDefaults
4764 hit% = c1%: do% = c2%: rem Mouse buttons
4766 SetSound 1
4768 palno = 0: rem palette number
4770 rem tmr_start% = 30: rem Timer start time
4772 tmr_fact = 25: rem Timer time factor
4774 tmr_end% = c0%: rem Timer end time (count down)
4776 tmr_use% = on%: rem Use timer
4778 tmr_cup% = off%: rem Timer count up: 0 = down (default)
4780 tmr_auto% = on%: rem Autocalculate time
4782 tmr_pause% = off%
4784 tmr_wru% = 989
4786 tmr_wrd% = 6
4788 spot% = c4%: rem spot colour default
4790 butbf = bfpresent: rem Use button frame if available..
4792 butx% = cm1%: buty% = cm1%: rem ..if not available use this position
4794 saveonx = 0: rem Save on exit
4796 gme_cup% = c0%: rem Game scoring variables
4798 gme_jst% = c0%
4800 gme_jsd% = c0%
4802 gme_mcauto% = on%: rem Auto mine count
4804 gme_chg = 0: rem Game changed outside game menu flag
4806 autosave = 1: rem Autosave score after each game
4808 :
4810 palno = 4: rem Defaults to own palette
4812 xpos% = cm1%: ypos% = cm1%: rem Window at pointer position
4814 :
4816 col_imc = '15772200': rem Counter ink = $F0AA28 - orange
4818 col_pmc = 0: rem Counter paper
4820 col_itm = '15772200': rem Timer ink = $F0AA28 - orange
4822 col_ptm = 0: rem Timer paper black
4824 col_itw = '16711680': rem Timer ink = $FF0000 - red
4826 col_ptw = -1: rem Warning paper white
4828 col_ito = '8421504': rem Timeout ink $808080 - dark grey
4830 col_pto = '15790320': rem Timeout paper $F0F0F0 - light grey
4832 END DEFine SetDefaults
4834 :
4836 DEFine PROCedure PrePreWarn(tx$)
4838 ch% = FOPEN("con_264x70"): Burp 'loose'
4840 BORDER#ch%; 1, 255: PAPER#ch%; 2: CLS#ch%
4842 PRINT#ch%; Centre$(44, cfname$ & spc$ & cfver$)
4844 PRINT#ch%; Centre$(44, FILL$('-', LEN(cfname$ & spc$ & cfver$)))\\
4846 PRINT#ch%; Centre$(44, tx$)\\
4848 PRINT#ch%; Centre$(44, 'Press any key to quit')
4850 PAUSE#ch%: QUIT
4852 END DEFine PrePreWarn
4854 :
4856 DEFine PROCedure TstSSS
4858 LOCal adr
4860 rem GLOBal ssspresent
4862 rem Test for presence of Sampled Sound System
4864 rem V0.01 pjwitte 2oo5
4866 :
4868 adr = ALCHP(26)
4870 POKE_L adr + 0, HEX("43fa0016"): rem lea.l result,a1
4872 POKE_L adr + 4, HEX("26780070"): rem move.l exv_i4,a3
4874 POKE_L adr + 8, HEX("0cab5353"): rem cmp.l #sss.flag,-8(a3)
4876 POKE_L adr + 12, HEX("5353fff8")
4878 POKE_L adr + 16, HEX("57e90001"): rem seq 1(a1)
4880 POKE_W adr + 20, HEX("7000") : rem moveq#0,d0
4882 POKE_W adr + 22, HEX("4e75") : rem rts
4884 POKE_W adr + 24, 0 : rem ds.w 1
4886 CALL adr
4888 ssspresent = PEEK_W(adr + 24)
4890 RECHP adr
4892 END DEFine TstSSS
4894 :
Generated with sb2htm on 2026 Jan 15
©pjwitte 2oo1 - 2o22
QL Software
