www.jupiter-ace.co.uk

Previous Page > Listings Index > SokoED listing


SokoED
by
Ricardo Fernandes Lopes
( SokoED                     )
( The SokoACE map editor     )

( (c) 2006  by Ricardo Fernandes Lopes )
( under the GNU General Public License )

( ------------ How to Use it -------------)
( Load the SokoACE map editor with:       )
(  LOAD SOKOED                            )
(                                         )
( Create a new map 123 from scratch using:)
(  123 NEW                                )
(                                         )
( or load an existing map to edit with:   )
(  MAP BLOAD mapname ED                   )
(                                         )
( When finished, quit editor with Q       )
( then save map to tape using:            )
(  MAP BSAVE mapname                      )
( ----------------------------------------)

( Graphic characters )
CREATE T 56 ALLOT
: GR 8 * T + DUP 8 + SWAP DO I C! LOOP ;
16 BASE C!
00 00 00 00 00 00 00 00 00 GR ( Not used     )
00 00 00 18 18 00 00 00 01 GR ( Target       )
3C 42 81 FF 99 99 7E 3C 02 GR ( Soko         )
3C 42 BD FF BD 99 7E 3C 03 GR ( Soko + Target)
00 7E 42 42 42 42 7E 00 04 GR ( Box          )
00 7E 42 5A 5A 42 7E 00 05 GR ( Box + Target )
FF AB D5 AB D5 AB D5 FF 06 GR ( Wall         )
DECIMAL
: SETGR 56 0 DO T I + C@ 10240 I + C! LOOP ;

( Screen elements)
01 CONSTANT TARGET
02 CONSTANT SOKO
04 CONSTANT BOX
06 CONSTANT WALL
32 CONSTANT BL

: KEY ( -- c , wait for keypress)
  BEGIN INKEY 0= UNTIL
  BEGIN INKEY ?DUP UNTIL ;

: >UPPER ( c1 -- c2 , convert to uppercase)
  DUP 96 > IF 223 AND THEN ;

: +! ( n adr -- )  SWAP OVER @ + SWAP ! ;

   1 VARIABLE MAP#    ( Map number     )
9546 VARIABLE CURSOR  ( Cursor address )

( Movement directions)
-32 CONSTANT UP
 32 CONSTANT DOWN
 -1 CONSTANT LEFT
  1 CONSTANT RIGHT

( Displaying cursor)
: CURSOR-ON   CURSOR @ DUP C@ 128  OR SWAP C! ;
: CURSOR-OFF  CURSOR @ DUP C@ 127 AND SWAP C! ;

: GO ( dir -- , move cursor to given direction)
  CURSOR @ SWAP OVER +              ( Calc new cursor position)
  DUP 31 AND 20 < IF SWAP THEN DROP ( horizontal limit)
  9280 MAX 9907 MIN                 ( vertical limit )
  CURSOR ! ;


: WALK ( c -- c , Move cursor )
  DUP ASCII I = IF    UP GO ELSE
  DUP ASCII K = IF  DOWN GO ELSE
  DUP ASCII J = IF  LEFT GO ELSE
  DUP ASCII L = IF RIGHT GO
  THEN THEN THEN THEN ;

( Place a character at cursor position )
: SET ( c -- )   CURSOR @ C! ;

: DRAW ( c -- c )
  DUP ASCII X = IF            BL SET ELSE
  DUP ASCII T = IF        TARGET SET ELSE
  DUP ASCII B = IF           BOX SET ELSE
  DUP ASCII O = IF  BOX TARGET + SET ELSE
  DUP ASCII S = IF          SOKO SET ELSE
  DUP ASCII Z = IF SOKO TARGET + SET ELSE
  DUP ASCII W = IF          WALL SET
  THEN THEN THEN THEN THEN THEN THEN ;

: .MAP#  1 0 AT ." MAP " MAP# @ . SPACE ;

: .FRAME
   0  0 AT ." _SokoACE Map Editor_ version 1.0"
   2 21 AT ." I Up"
   3 21 AT ." K Down"
   4 21 AT ." J Left"
   5 21 AT ." L Right"
   7 21 AT ." S Soko"
   8 21 AT ." Z Soko+Trgt"
   9 21 AT ." B Box"
  10 21 AT ." O Box+Trgt"
  11 21 AT ." T Target"
  12 21 AT ." W Wall"
  13 21 AT ." X Clr Cell"
  15 21 AT ." C Clr Map"
  16 21 AT ." N Map + 1"
  17 21 AT ." P Map - 1"
  18 21 AT ." M Map ?"
  20 21 AT ." Q quit"
  22  0 AT ." _by Ricardo F Lopes_   c 2006"
  .MAP# ;

: #IN ( -- n , get a number from the user)
  QUERY NUMBER DUP
  IF
    4181 =
    IF DROP DROP 0 THEN ( avoid float numbers )
  THEN ;

: PLAY ( c -- )
  WALK DRAW
  DUP ASCII C = IF  CLS .FRAME        ELSE
  DUP ASCII N = IF    1 MAP# +! .MAP# ELSE
  DUP ASCII P = IF   -1 MAP# +! .MAP# ELSE
  DUP ASCII M = IF  #IN MAP# !  .MAP#
  THEN THEN THEN THEN DROP ;

21 20 * CONSTANT MAPSIZE
CREATE BUF MAPSIZE ALLOT
: MAP ( adr n -- )   BUF MAPSIZE ;

( Copy Map on screen to buffer for saving)
: SCR>BUF
  8224 BUF ( src dst )
  21 0     ( 21 lines )
  DO
    20 0   ( 20 chars per line )
    DO
      OVER I + @ OVER I + !
      2
    +LOOP
    20 + SWAP
    32 + SWAP
  LOOP ;

( Copy Map on buffer to screen for editing)
: BUF>SCR
  1 0 AT
  BUF 21 0
  DO DUP 20 TYPE CR 20 + LOOP DROP ;

: ED ( Edit map on screen)
  INVIS CLS SETGR
  BUF>SCR .FRAME
  9546 CURSOR !
  BEGIN
    CURSOR-ON KEY >UPPER CURSOR-OFF
    DUP ASCII Q = 0=
  WHILE
    PLAY
  REPEAT 
  DROP SCR>BUF ; ( save screen to buffer for saving )

( create a new map )
: NEW ( n -- , Start new map n)
  MAP# ! CLS .MAP# SCR>BUF ED ;