Stroq - A game in Forth#
About Stroq:#
Stroq is a simple but addictive puzzle game. I found the game for Linux and MacOS X on the Internet (Stroq Homepage) and decided to do a conversation for the Atari 8Bit Computer in Forth. Winfried Piegsda did the graphical design, sound and artwork, I did the coding in Forth (X-Forth for Atari). The Game programmed in little less than 4 weeks to be submitted to the annual ABBUC Software Contest where it scored the 5th place.
Screenshots#
Atari 8bit Version#
License:#
This game is licensed under the GNU Public License, Version 2 or higher.
Source:#
Atari XL/XE Computer (6502 X-Forth / FIG-Forth)#
I didn't look at the C-Sources, we only "stole" the puzzle level from the original game at sourceforge. Because the game was programmed under time pressure, the code is not "optimal".
( Stroq ) CR ." Loading Stroq" CR HEX : AT-X ( xp -- ) 55 ! ; : AT-Y ( yp -- ) 54 C! ; : AT ( xp yp -- ) AT-Y AT-X ; : AT-X? ( -- xp ) 55 @ ; 58 CONSTANT SAVMSC ( Pointer to Displaybuffer ) 14 CONSTANT MAXX 14 CONSTANT MAXY 0 VARIABLE pf MAXX MAXY * ALLOT pf CELL+ pf ! pf VARIABLE pfp ." Playfield is at $" pfp @ U. CR 0 VARIABLE curx 0 VARIABLE cury 0 VARIABLE lastx 0 VARIABLE lasty 0 VARIABLE lastblox 0 VARIABLE STROQPTR 7000 CONSTANT STROQMEM 0 VARIABLE LevelWidth 0 VARIABLE LevelHeight 0 VARIABLE BloxUsed 0 VARIABLE PuzzleNumber 0 VARIABLE XOffset 0 VARIABLE YOffset : WAITKEY KEY DROP ; : [PF"] R COUNT DUP 1+ R> + >R pfp @ SWAP CMOVE LevelWidth @ pfp +! ; : BEGINLEVEL pf @ pfp ! 0 STROQPTR ! 0 lastx ! 0 curx ! 0 lasty ! 0 cury ! 0 lastblox ! ; : PF" 22 STATE @ IF COMPILE [PF"] WORD C@ 1+ ALLOT ELSE WORD DUP C@ 1+ PAD SWAP CMOVE PAD COUNT THEN ; IMMEDIATE : CLS 7D EMIT ; : CONVERTLEVEL pfp @ DUP LevelWidth @ LevelHeight @ * + SWAP DO I C@ DUP 58 = IF 41 I C! THEN DUP 20 = IF 01 I C! THEN 4F = IF 81 I C! THEN LOOP ; : ENDLEVEL 10 LevelHeight @ - 2 / 28 * YOffset ! 28 LevelWidth @ 2 * - 2 / XOffset ! LevelWidth @ 2 MOD 0= IF -1 XOffset +! THEN LevelHeight @ 2 MOD 0= IF -28 YOffset +! THEN pf @ pfp ! CONVERTLEVEL ; : PRINTBLOX ( x y n -- ) ROT 2 * SAVMSC @ + XOffset @ + ROT 50 * YOffset @ + + 28 - SWAP 2 * 40 + OVER OVER SWAP C! 1+ SWAP 1+ OVER OVER C! 27 + SWAP 3F + SWAP OVER OVER C! 1+ SWAP 1+ SWAP C! ; : PRINTBLOX2 ( x y ) OVER OVER LevelWidth @ * + pfp @ + C@ DUP 80 AND IF 0F AND 70 + PRINTBLOX ELSE DUP 40 AND IF 0F AND PRINTBLOX ELSE DUP F0 AND 0= IF 0F AND 30 + PRINTBLOX ELSE DROP THEN THEN THEN ; : PRINTLEVEL LevelHeight @ 0 DO LevelWidth @ 0 DO I J PRINTBLOX2 LOOP LOOP ; : AND! ( n addr -- ) DUP C@ F0 AND ROT OR SWAP C! ; : PUTBLOX ( x y n -- ) ROT pfp @ + ROT LevelWidth @ * + AND! ; : INLINE? ( -- f ) curx @ lastx @ - ABS 1 = cury @ lasty @ - ABS 1 = + 1 = ; : CLEARHEADER BC40 28 ERASE ; : FLIPBLOX ( x y ) LevelWidth @ * + pfp @ + DUP C@ DUP 40 AND 0= IF 80 XOR SWAP C! ELSE DROP DROP THEN ; : GETBLOX ( x y -- n ) LevelWidth @ * + pfp @ + C@ 0F AND ; : GETCOLOR ( x y -- ) LevelWidth @ * + pfp @ + C@ 80 AND ; : EMPTY? ( -- f ) curx @ cury @ GETBLOX 1 = ; : PUTLBLOX ( n -- ) lastx @ lasty @ ROT PUTBLOX ; : PUTCBLOX ( n -- ) curx @ cury @ ROT PUTBLOX ; : SUCCESS ( -- ) lastx @ lasty @ PRINTBLOX2 curx @ cury @ PRINTBLOX2 curx @ lastx ! cury @ lasty ! 2 STROQPTR +! 1 BloxUsed +! curx @ STROQMEM STROQPTR @ + C! cury @ STROQMEM STROQPTR @ + 1+ C! ; : STROQADDR STROQMEM STROQPTR @ + ; : STROQX STROQADDR C@ ; : STROQY STROQADDR 1+ C@ ; : REWIND BEGIN STROQX STROQY 1 PUTBLOX STROQX STROQY PRINTBLOX2 STROQX curx @ = STROQY cury @ = AND 0= WHILE -2 STROQPTR +! -1 BloxUsed +! REPEAT -2 STROQPTR +! -1 BloxUsed +! STROQX lastx ! STROQY lasty ! STROQPTR @ 0 > IF STROQX curx @ = IF STROQY cury @ < IF 3 PUTCBLOX 3 lastblox ! ELSE 5 PUTCBLOX 5 lastblox ! THEN THEN STROQY cury @ = IF STROQX curx @ > IF 4 PUTCBLOX 4 lastblox ! ELSE 6 PUTCBLOX 6 lastblox ! THEN THEN ELSE 2 PUTCBLOX 2 lastblox ! THEN SUCCESS -2 STROQPTR +! ; : SOLVE CLEARHEADER A 0 AT STROQPTR @ IF STROQPTR @ 0 DO STROQX STROQY FLIPBLOX STROQX STROQY PRINTBLOX2 -2 STROQPTR +! 2 +LOOP 0 LevelHeight @ 1 - 1 DO 0 LevelWidth @ 1 - 1 DO I J GETCOLOR IF 2 OR ELSE 1 OR THEN LOOP 3 = IF 1 OR THEN LOOP IF ." Puzzle Not Solved! " 0 ELSE ." Puzzle Solved! " 1 THEN ELSE ." No Stroke! " 0 THEN WAITKEY ; : SETSTROQ ( -- ) INLINE? EMPTY? AND IF curx @ lastx @ = IF cury @ lasty @ - 1 = IF ( one down ) lastblox @ DUP 2 = IF 5 PUTLBLOX THEN DUP 3 = IF 8 PUTLBLOX THEN DUP 4 = IF C PUTLBLOX THEN 6 = IF A PUTLBLOX THEN 3 PUTCBLOX 3 lastblox ! ELSE ( one up ) lastblox @ DUP 2 = IF 3 PUTLBLOX THEN DUP 4 = IF B PUTLBLOX THEN DUP 5 = IF 8 PUTLBLOX THEN 6 = IF 9 PUTLBLOX THEN 5 PUTCBLOX 5 lastblox ! THEN ELSE curx @ lastx @ - 1 = IF ( one right ) lastblox @ DUP 2 = IF 4 PUTLBLOX THEN DUP 3 = IF B PUTLBLOX THEN DUP 5 = IF C PUTLBLOX THEN 6 = IF 7 PUTLBLOX THEN 6 PUTCBLOX 6 lastblox ! ELSE ( one left ) lastblox @ DUP 2 = IF 6 PUTLBLOX THEN DUP 3 = IF 9 PUTLBLOX THEN DUP 4 = IF 7 PUTLBLOX THEN 5 = IF A PUTLBLOX THEN 4 PUTCBLOX 4 lastblox ! THEN THEN SUCCESS ELSE EMPTY? 0= IF REWIND SUCCESS ELSE CLEARHEADER E 0 AT ." Illegal Move!" WAITKEY CLEARHEADER THEN THEN ; : SETBLOX ( -- ) lastblox @ IF SETSTROQ ELSE curx @ cury @ 2 PUTBLOX 2 lastblox ! SUCCESS THEN ; : CUROFF FF 2F0 C! ; : CURON 00 2F0 C! ; : HEADER ( Print header ) DECIMAL CUROFF 1 0 AT BloxUsed @ S>D <# # # # #> TYPE SPACE ." Blox used" 16 0 AT ." Puzzle Number " PuzzleNumber @ S>D <# # # # #> TYPE HEX ; 00 VARIABLE FOOTERMEM 28 ALLOT ." Footermem is at " FOOTERMEM . CR ( Displaylistgeraffel ) 230 CONSTANT SDLSTL 200 CONSTANT VSDLST D40E CONSTANT NMIEN 00 VARIABLE DLSAVE D40B CONSTANT VCOUNT : SAVEDL SDLSTL @ DLSAVE ! ; : RESTOREDL DLSAVE @ SDLSTL ! ; : SETDL ( addr -- ) BEGIN VCOUNT C@ 10 < UNTIL SDLSTL ! C0 NMIEN C! ; 0 VARIABLE DLGAME -2 ALLOT 70 C, 60 C, 80 C, ( DLI1 ) 00 C, 00 C, 42 C, BC40 , 80 C, ( DLI2 ) 00 C, 40 C, 0404 , 0404 , 0404 , 0404 , 0404 , 0404 , 0404 , 0404 , 0404 , 0404 , 0404 , 10 C, 80 C, ( DLI3 ) 10 C, 42 C, FOOTERMEM , 80 C, ( DLI4 ) 00 C, 41 C, DLGAME , : SETDLGAME DLGAME SETDL ; 0 VARIABLE DLHELP -2 ALLOT 70 C, 60 C, 80 C, ( DLI1 ) 00 C, 42 C, BC40 , 80 C, ( DLI2 ) 00 C, 00 C, 40 C, 40 C, 0202 , 0202 , 0202 , 0202 , 0202 , 0202 , 0202 , 0202 , 0202 , 0202 , 0202 , A0 C, ( DLI3 ) 00 C, 00 C, 42 C, FOOTERMEM , 80 C, ( DLI4 ) 00 C, 41 C, DLHELP , : SETDLHELP DLHELP SETDL ; 0 VARIABLE DLTITLE -2 ALLOT 70 C, 40 C, 80 C, 00 , 42 C, BC40 , 80 C, 00 C, 00 C, 30 C, ( 1) 4F C, 8010 , 0F C, 0F0F , 0F0F , 0F0F ( 2) 0F0F , 0F0F , 0F0F , 0F0F , ( 3) 0F0F , 0F0F , 0F0F , 0F0F , ( 4) 0F0F , 0F0F , 0F0F , 0F0F , ( 5) 0F0F , 0F0F , 0F0F , 0F0F , ( 6) 0F0F , 0F0F , 0F0F , 0F0F , ( 7) 0F0F , 0F0F , 0F0F , 0F0F , ( 8) 0F0F , 0F0F , 0F0F , 0F0F , ( 9) 0F0F , 0F0F , 0F0F , 0F0F , ( 10) 0F0F , 0F0F , 0F0F , 0F0F , ( 11) 0F0F , 0F0F , 0F0F , 0F0F , ( 12) 0F0F , 0F0F , 0F0F , 0F0F , ( 13) 0F0F , 0F0F , 0F0F , 0F0F , 4F C, 9000 , 0F C, ( 14) 0F0F , 0F0F , 0F0F , ( 15) 0F0F , 0F0F , 0F0F , 0F0F , ( 16) 0F0F , 0F0F , 0F0F , 0F0F , ( 17) 0F0F , 0F0F , 0F0F , 0F0F , ( 18) 0F0F , 0F0F , 0F0F , 0F0F , ( 19) 0F0F , 0F0F , 0F0F , 0F0F , ( 20) 0F0F , 0F0F , 0F0F , 0F0F , ( 21) 0F0F , 0F0F , 0F0F , 0F0F , ( 22) 0F0F , 0F0F , 0F0F , 0F0F , ( 23) 0F0F , 0F0F , 0F0F , A0 C, 00 C, 00 C, 42 C, FOOTERMEM , 80 C, 00 C, 41 C, DLTITLE , : SETDLTITLE DLTITLE SETDL ; ( Displaylist Interrupt ) D40A CONSTANT WSYNC D016 CONSTANT COLPF0 D017 CONSTANT COLPF1 D018 CONSTANT COLPF2 D019 CONSTANT COLPF3 D01A CONSTANT COLBK D409 CONSTANT CHBASE 02F4 CONSTANT CHBAS 80 4 - VARIABLE FONT 0E VARIABLE WHITE 00 VARIABLE BLACK 06 VARIABLE GREY B6 VARIABLE GREEN 84 VARIABLE BLUE 32 VARIABLE T-RED B2 VARIABLE T-GREEN 82 VARIABLE T-BLUE ( Poor Mens Assembler ) 48 CONSTANT PHA 68 CONSTANT PLA 40 CONSTANT RTI 8D CONSTANT STA AD CONSTANT LDA A9 CONSTANT LDA# 60 CONSTANT RTS 20 CONSTANT JSR 4C CONSTANT JMP 00 VARIABLE WHITEBAR -2 ALLOT LDA C, WHITE , STA C, WSYNC , STA C, COLBK , LDA C, BLACK , STA C, WSYNC , STA C, COLBK , RTS C, 00 VARIABLE DLI1 -2 ALLOT PHA C, JSR C, WHITEBAR , STA C, COLPF2 , LDA C, WHITE , STA C, COLPF1 , LDA# C, HERE DLI1 100 / C, STA C, VSDLST 1+ , LDA# C, HERE DLI1 100 MOD C, STA C, VSDLST , PLA C, RTI , ." DLI1 is at " DLI1 . CR 00 VARIABLE DLI2 -2 ALLOT ( Patch DLI1 ) DLI2 100 MOD SWAP C! DLI2 100 / SWAP C! PHA C, JSR C, WHITEBAR , LDA C, GREY , STA C, COLPF0 , LDA C, WHITE , STA C, COLPF1 , LDA C, BLUE , STA C, COLPF2 , LDA C, GREEN , STA C, COLPF3 , LDA C, FONT , STA C, CHBASE , LDA# C, HERE DLI2 100 / C, STA C, VSDLST 1+ , LDA# C, HERE DLI2 100 MOD C, STA C, VSDLST , PLA C, RTI C, ." DLI2 is at " DLI2 . CR 00 VARIABLE DLI3 -2 ALLOT ( Patch DLI2 ) DLI3 100 MOD SWAP C! DLI3 100 / SWAP C! PHA C, JSR C, WHITEBAR , STA C, COLPF2 , LDA C, WHITE , STA C, COLPF1 , LDA C, CHBAS , STA C, CHBASE , LDA# C, HERE DLI3 100 / C, STA C, VSDLST 1+ , LDA# C, HERE DLI3 100 MOD C, STA C, VSDLST , PLA C, RTI C, ." DLI3 is at " DLI3 . CR 00 VARIABLE DLI4 -2 ALLOT ( Patch DLI3 ) DLI4 100 MOD SWAP C! DLI4 100 / SWAP C! PHA C, JSR C, WHITEBAR , LDA# C, DLI1 100 / C, STA C, VSDLST 1+ , LDA# C, DLI1 100 MOD C, STA C, VSDLST , PLA C, RTI C, ." DLI4 is at " DLI4 . CR E462 CONSTANT XITVBV E45F CONSTANT SYSVBV 0224 CONSTANT VVBLKD 0222 CONSTANT VVBLKI 00 VARIABLE VBI -2 ALLOT PHA C, LDA# C, DLI1 100 / C, STA C, VSDLST 1+ , LDA# C, DLI1 100 MOD C, STA C, VSDLST , PLA C, JMP C, SYSVBV , ." VBI is at " VBI . CR ( Musik ) A001 CONSTANT MSTART A008 CONSTANT MSTOP A011 CONSTANT MINIT A017 CONSTANT MPLAY 00 VARIABLE MUSIC : SETMUSIC MSTART @ 9F20 = IF MINIT CALL MSTART CALL 1 MUSIC ! THEN ; : STOPMUSIC MSTART @ 9F20 = IF MSTOP CALL 0 MUSIC ! THEN ; : STARTMUSIC MSTART @ 9F20 = IF MSTART CALL 1 MUSIC ! THEN ; : SETVBI NMIEN C@ 0 NMIEN C! VBI VVBLKI ! NMIEN C! ; : SETDLI ( addr - ) ( STOPMUSIC SETVBI ) VSDLST ! ( STARTMUSIC ) ; : RESETDLI 60 NMIEN C! C0CE SETDLI ; ( Player Missile Grafics ) 022F CONSTANT SDMCTL 026F CONSTANT GPRIOR D000 CONSTANT HPOS0 D01D CONSTANT GRACTL D407 CONSTANT PMBASE D01C CONSTANT VDELAY 02C0 CONSTANT PCOLR0 : INITPM SDMCTL C@ 8 + SDMCTL C! ( Enable PM DMA ) 2 GRACTL C! ( Enable PM ) 1 GPRIOR C! 80 6 - PMBASE C! ; ( Player ) 0 VARIABLE CROSS -2 ALLOT 2 BASE ! 00000000 C, 11101110 C, 10000010 C, 10000010 C, 00000000 C, 10000010 C, 10000010 C, 11101110 C, 00000000 C, HEX : PMPOS ( x y -- ) 7A00 FF 00 FILL YOffset @ 40 / + 8 * 7A0B + LevelHeight @ 8 = IF 4 + THEN ( Hack! ) CROSS SWAP 9 CMOVE XOffset @ 2 / + 8 * 34 + HPOS0 C! 10 VDELAY C! ; ( Strings ) : ["] ( -- addr len ) R COUNT DUP 1+ R> + >R ; : " ( -- addr len ) 22 STATE @ IF COMPILE ["] WORD C@ 1+ ALLOT ELSE WORD DUP C@ 1+ PAD SWAP CMOVE PAD COUNT THEN ; IMMEDIATE ( Level ) : LEVEL1 7 LevelWidth ! 7 LevelHeight ! 0 BloxUsed ! 1 PuzzleNumber ! BEGINLEVEL PF" XXXXXXX" PF" XOO OOX" PF" XO O OX" PF" X O O X" PF" XO O OX" PF" XOO OOX" PF" XXXXXXX" ENDLEVEL ; : LEVEL2 A LevelWidth ! A LevelHeight ! 0 BloxUsed ! 2 PuzzleNumber ! BEGINLEVEL PF" XXXXXXXXXX" PF" XO O OO OX" PF" XO O OO OX" PF" XOOO OX" PF" XOOO OO OX" PF" XO O OO OX" PF" XO O OO X" PF" X OO OX" PF" X OO OX" PF" XXXXXXXXXX" ENDLEVEL ; : LEVEL3 8 LevelWidth ! A LevelHeight ! 0 BloxUsed ! 3 PuzzleNumber ! BEGINLEVEL PF" XXXXXXXX" PF" XO OOO X" PF" X OOO X" PF" XOO O X" PF" X O OO X" PF" X O OO X" PF" XOO OOX" PF" XOOO O X" PF" X O OOX" PF" XXXXXXXX" ENDLEVEL ; : LEVEL4 A LevelWidth ! A LevelHeight ! 0 BloxUsed ! 4 PuzzleNumber ! BEGINLEVEL PF" XXXXXXXXXX" PF" X OOX" PF" X OOOOX" PF" X OOOOOOX" PF" XOOOOOOO X" PF" X OOX" PF" X OOO X" PF" X OOO X" PF" XOOO X" PF" XXXXXXXXXX" ENDLEVEL ; : LEVEL5 A LevelWidth ! A LevelHeight ! 0 BloxUsed ! 5 PuzzleNumber ! BEGINLEVEL PF" XXXXXXXXXX" PF" XOOOO X" PF" XOOO X" PF" XOO OX" PF" XOOOO OX" PF" XOOO OX" PF" XOO OOOX" PF" XO OOOOOX" PF" X OOOOOOX" PF" XXXXXXXXXX" ENDLEVEL ; : LEVEL6 A LevelWidth ! A LevelHeight ! 0 BloxUsed ! 6 PuzzleNumber ! BEGINLEVEL PF" XXXXXXXXXX" PF" X OO X" PF" X OO X" PF" X OO X" PF" X OOO X" PF" X OOO X" PF" X OOOO X" PF" XOOOO OOX" PF" XOOO OOX" PF" XXXXXXXXXX" ENDLEVEL ; : LEVEL7 A LevelWidth ! A LevelHeight ! 0 BloxUsed ! 7 PuzzleNumber ! BEGINLEVEL PF" XXXXXXXXXX" PF" XOOOOOOO X" PF" XOOO OX" PF" XOOO OOX" PF" XOO OOOOOX" PF" XO OOOOX" PF" XO OOOOX" PF" XOO OOOOOX" PF" XOO OOOOOX" PF" XXXXXXXXXX" ENDLEVEL ; : LEVEL8 A LevelWidth ! 6 LevelHeight ! 0 BloxUsed ! 8 PuzzleNumber ! BEGINLEVEL PF" XXXXXXXXXX" PF" XO O O OOX" PF" XO OOO O X" PF" XOO OO X" PF" XOOO OOO X" PF" XXXXXXXXXX" ENDLEVEL ; : LEVEL9 A LevelWidth ! A LevelHeight ! 0 BloxUsed ! 9 PuzzleNumber ! BEGINLEVEL PF" XXXXXXXXXX" PF" XOO O OO X" PF" XOOO O X" PF" XOOOOO OOX" PF" XO OX" PF" XOO OOOX" PF" X O X" PF" XOOOOO OOX" PF" X OOX" PF" XXXXXXXXXX" ENDLEVEL ; : LEVELA A LevelWidth ! 8 LevelHeight ! 0 BloxUsed ! A PuzzleNumber ! BEGINLEVEL PF" XXXXXXXXXX" PF" X OOOOOO X" PF" X O OOX" PF" X OOOO O X" PF" X O O O X" PF" X O OOOOX" PF" X OOOOO X" PF" XXXXXXXXXX" ENDLEVEL ; : LEVELB 9 LevelWidth ! A LevelHeight ! 0 BloxUsed ! B PuzzleNumber ! BEGINLEVEL PF" XXXXXXXXX" PF" XOO OOX" PF" XOO OOX" PF" XOOO OOOX" PF" XOOO OOOX" PF" XOO O OOX" PF" XOO OOX" PF" XOO OOX" PF" XOO OOX" PF" XXXXXXXXX" ENDLEVEL ; : LEVELC 9 LevelWidth ! 8 LevelHeight ! 0 BloxUsed ! C PuzzleNumber ! BEGINLEVEL PF" XXXXXXXXX" PF" X OO OO X" PF" XO OX" PF" X O O X" PF" X O O X" PF" XO O OX" PF" X O O X" PF" XXXXXXXXX" ENDLEVEL ; : LEVELD A LevelWidth ! A LevelHeight ! 0 BloxUsed ! D PuzzleNumber ! BEGINLEVEL PF" XXXXXXXXXX" PF" XOO OOX" PF" XO OOOX" PF" X OOOOX" PF" X OOOX" PF" X O OO X" PF" X OOO OX" PF" XOOOOO X" PF" XOOOOOO X" PF" XXXXXXXXXX" ENDLEVEL ; : LEVELE A LevelWidth ! A LevelHeight ! 0 BloxUsed ! E PuzzleNumber ! BEGINLEVEL PF" XXXXXXXXXX" PF" XO OOOO OX" PF" X O OO O X" PF" XO O O OX" PF" X OOOOOO X" PF" X OOOO X" PF" X OOOOOO X" PF" XO OO OX" PF" XOOO OOOX" PF" XXXXXXXXXX" ENDLEVEL ; : LEVELF A LevelWidth ! 7 LevelHeight ! 0 BloxUsed ! F PuzzleNumber ! BEGINLEVEL PF" XXXXXXXXXX" PF" X OOOOOX" PF" XOO O O X" PF" X OOO X" PF" X OO O OOX" PF" XOOO O X" PF" XXXXXXXXXX" ENDLEVEL ; 00 VARIABLE LEVELMEM 60 ALLOT ." LevelMem is at " LEVELMEM . CR LEVELMEM 60 ERASE 00 VARIABLE MAXLEVEL : LOADLEVEL ." Load Level Savefile..." CR " D:STROQ.SAV" R/O OPEN-FILE DUP IF ." Open Savefile Error:" . CR WAITKEY ELSE DROP DUP LEVELMEM 60 ROT READ-FILE DUP IF DROP DROP ELSE DROP DROP CLOSE-FILE DROP ." ok" CR THEN THEN ; : SAVELEVEL ." Store Level Savefile..." CR " D:STROQ.SAV" W/O OPEN-FILE DUP IF ." Open Savefile Error:" . CR ELSE DROP DUP LEVELMEM 60 ROT WRITE-FILE DUP IF ." Save Savefile Error:" . CR ELSE DROP CLOSE-FILE DROP ." ok" CR THEN THEN ; : LEVELADDR LEVELMEM @ 4 * LEVELMEM + ; : >LEVEL ( xt -- ) 1 LEVELMEM +! LEVELADDR ! ; : GETLEVELXT ( -- xt ) LEVELADDR @ CFA ; : NEXTLEVEL 1 LEVELMEM +! MAXLEVEL @ LEVELMEM @ < IF 1 LEVELMEM ! THEN GETLEVELXT EXECUTE ; ' LEVEL1 >LEVEL ' LEVEL2 >LEVEL ' LEVEL3 >LEVEL ' LEVEL4 >LEVEL ' LEVEL5 >LEVEL ' LEVEL6 >LEVEL ' LEVEL7 >LEVEL ' LEVEL8 >LEVEL ' LEVEL9 >LEVEL ' LEVELA >LEVEL ' LEVELB >LEVEL ' LEVELC >LEVEL ' LEVELD >LEVEL ' LEVELE >LEVEL ' LEVELF >LEVEL LEVELMEM @ MAXLEVEL ! : SAVESCORE BloxUsed @ LEVELADDR 2+ ! ; ( Footer ) : CLEARFOOTER FOOTERMEM 28 ERASE ; : >FOOTER BC40 FOOTERMEM 28 CMOVE ; : FOOTER CLEARFOOTER 0 0 AT ." Main Menu:Solve Puzzle:Reset Puzzle:Help" >FOOTER ; : TFOOTER CLEARFOOTER 0 0 AT ." Start Game : Select Puzzle : Quit : Help" >FOOTER ; 00 VARIABLE I1 00 VARIABLE I2 : FINV I2 @ I1 @ DO FOOTERMEM I + DUP C@ 80 XOR SWAP C! LOOP ; 00 VARIABLE TSEL : TMENU BEGIN TSEL @ DUP 0= IF 00 I1 ! 0B I2 ! THEN DUP 1 = IF 0C I1 ! 1B I2 ! THEN DUP 2 = IF 1C I1 ! 22 I2 ! THEN 3 = IF 23 I1 ! 28 I2 ! THEN FINV KEY FINV DUP 2B = IF TSEL @ IF -1 TSEL +! THEN THEN DUP 2A = IF TSEL @ 3 < IF 1 TSEL +! THEN THEN 9B = UNTIL ; 00 VARIABLE GSEL : GMENU BEGIN GSEL @ DUP 0= IF 00 I1 ! 09 I2 ! THEN DUP 1 = IF 0A I1 ! 16 I2 ! THEN DUP 2 = IF 17 I1 ! 23 I2 ! THEN 3 = IF 24 I1 ! 28 I2 ! THEN FINV KEY FINV DUP 2B = IF GSEL @ IF -1 GSEL +! THEN THEN DUP 2A = IF GSEL @ 3 < IF 1 GSEL +! THEN THEN 9B = UNTIL ; ( Picture ) 8010 CONSTANT PICBASE : LOADPIC " D:STROQ.PIC" R/O OPEN-FILE DUP IF ." Pic Open Error " . CR BYE ELSE DROP DUP PICBASE 1C20 ROT READ-FILE DUP IF ." Pic Load Error " . . CR BYE ELSE DROP DROP CLOSE-FILE DROP THEN THEN ; ( Font ) 8000 400 - CONSTANT FONTBASE 0 VARIABLE SAVEFONT : LOADFONT " D:STROQ.FNT" R/O OPEN-FILE DUP IF ." Font Open Error " . CR BYE ELSE DROP DUP FONTBASE 400 ROT READ-FILE DUP IF ." Font Load Error " . . CR BYE ELSE DROP DROP CLOSE-FILE DROP THEN THEN ; : SETFONT CHBAS C@ SAVEFONT C! FONTBASE 100 / CHBAS C! ; : RESETFONT SAVEFONT C@ CHBAS C! ; : CROSSPOS curx @ cury @ PMPOS ; : CURUP cury @ IF -1 cury +! THEN ; : CURDOWN cury @ LevelHeight @ 1 - < IF 1 cury +! THEN ; : CURLEFT curx @ IF -1 curx +! THEN ; : CURRIGHT curx @ LevelWidth @ 1 - < IF 1 curx +! THEN ; 00 VARIABLE Pulse -2 ALLOT 00 C, 00 C, 00 C, 00 C, 02 C, 02 C, 02 C, 02 C, 04 C, 04 C, 04 C, 06 C, 06 C, 08 C, 0A C, 0C C, 0A C, 08 C, 06 C, 06 C, 04 C, 04 C, 04 C, 02 C, 02 C, 02 C, 02 C, 00 C, 00 C, 00 C, 00 C, 00 C, 00 VARIABLE PulseP 00 VARIABLE Count : WAIT 0 14 C! BEGIN 14 C@ UNTIL ; : NOCLICK FF 2DB C! ; : RESET GETLEVELXT EXECUTE 0 STROQPTR ! CLS PRINTLEVEL HEADER ; : DOS 0 HPOS0 C! CLS RESTOREDL CURON STOPMUSIC SAVELEVEL BYE ; : SETGAME 80 4 - FONT C! 82 BLUE ! DLI1 SETDLI SETDLGAME FOOTER CLS HEADER PRINTLEVEL ; : SETTITLE 0 BLUE ! TFOOTER CLS HEADER SETDLTITLE DLI1 SETDLI ; : HELP RESETDLI CLS 0 HPOS0 C! CHBAS C@ FONT C! B2 BLUE ! SETDLHELP DLI1 SETDLI 0 0 AT ." Stroq Help " 0 2 AT ." Atari Version 0 3 AT ." (C) 2005 Carsten Strotmann &" 0 4 AT ." Winfried Piegsda" 0 6 AT ." Stroq is OpenSource Software" 0 7 AT ." and Licensed under the GPL" 0 8 AT ." Version 2 or higher" 0 A AT ." How to play:" 0 B AT ." ------------" 0 D AT ." The goal of the game is simple, draw" 0 E AT ." a single continuous line, the stroke" 0 F AT ." from one square to another." 0 10 AT ." When you run the puzzle (Solve Puzzle)" 0 11 AT ." green and blue squares along the line" 0 12 AT ." will flop over (blue becoming green," 0 13 AT ." green becoming blue). The Puzzle is" 0 14 AT ." solved when all tiles on the row are" 0 15 AT ." the same color." WAITKEY CLS RESETDLI ; : MOVECURSOR 3 GSEL ! BEGIN ?TERMINAL IF KEY DUP 1C = IF CURUP THEN DUP 2D = IF CURUP THEN DUP 1D = IF CURDOWN THEN DUP 3D = IF CURDOWN THEN DUP 1E = IF CURLEFT THEN DUP 2B = IF CURLEFT THEN DUP 1F = IF CURRIGHT THEN DUP 2A = IF CURRIGHT THEN DUP 9B = IF SETBLOX HEADER THEN DUP 20 = IF SETBLOX HEADER THEN DUP 08 = IF HELP SETGAME THEN DUP 11 = IF DOS THEN DUP 12 = IF RESET THEN DUP 13 = IF SOLVE IF SAVESCORE NEXTLEVEL THEN RESET THEN DUP 1B = IF GMENU GSEL @ DUP 1 = IF SOLVE IF SAVESCORE NEXTLEVEL THEN RESET THEN DUP 2 = IF RESET THEN 3 = IF HELP SETGAME THEN THEN DUP 0D = IF MUSIC @ IF STOPMUSIC ELSE STARTMUSIC THEN THEN DROP ( 0 0 AT ." SP=" SP@ . ) CROSSPOS ELSE WAIT 1 Count +! Count @ 40 AND 0= IF PulseP @ 1+ 2F AND PulseP ! Pulse PulseP @ + @ PCOLR0 C! THEN THEN GSEL @ 0 = UNTIL 0 HPOS0 C! RESETDLI ; : SELECTPUZZLE RESETDLI CLS 0 HPOS0 C! CHBAS C@ FONT C! 32 BLUE ! SETDLHELP DLI1 SETDLI C 0 AT ." Select Puzzle " DECIMAL BEGIN 2 5 AT ." Level:" LEVELMEM @ S>D <# # # # #> TYPE SPACE 2 7 AT LEVELADDR 2 + @ DUP IF ." Solved with " S>D <# # # # #> TYPE SPACE ." Blox used." ELSE DROP ." Not solved. " THEN KEY DUP 2B = IF LEVELMEM @ 1 > IF -1 LEVELMEM +! THEN THEN DUP 2A = IF MAXLEVEL @ LEVELMEM @ > IF 1 LEVELMEM +! THEN THEN 9B = UNTIL HEX GETLEVELXT EXECUTE CLS RESETDLI ; : TITLE SETTITLE TMENU 84 BLUE ! RESETDLI ; : STROQ CLS SAVEDL 0 2C6 C! NOCLICK ." Starting Stroq..." CR ( ." Load Font..." CR ) ( LOADFONT ) ( ." Load Picture..." CR ) ( LOADPIC ) LOADLEVEL 0 LEVELMEM ! NEXTLEVEL INITPM SETMUSIC BEGIN TITLE TSEL @ DUP 0= IF SETGAME CROSSPOS MOVECURSOR THEN DUP 1 = IF SELECTPUZZLE THEN DUP 2 = IF DOS THEN 3 = IF HELP THEN AGAIN ; ." Ready." CR
Downloads#
The Atari Stroq Programm has some quirks when running in an Emulator (such as Atari800). It runs fine on the real hardware.