;---------------------------------------------------------------; ; ; ; Snail Maze ; ; Version 1.0.0 ; ; ; ; By James Vernon ; ; jamesv82@live.com.au ; ; http://www.jvti.org ; ; ; ; You are allowed to use parts of this code as long as you give ; ; credit where it is due :) ; ; ; ; Based on the original Snail Maze game for Sega Master System ; ; ; ;---------------------------------------------------------------; #include "ti84pce.inc" #define bcall(xxxx) call xxxx _lddehl = $021DA0 #define VERSION "1.0.0" #define HUFF84PCE vbuf = vram+(320*240) ; constants TILE_SIZE = 10 MOVE_COUNT_INI = TILE_SIZE-2 NUM_LEVELS = 12 CHAR_SPRITE_SIZE = (7*7)+2 CHAR_WIDTH = 8 SEGA_XS = 72 SEGA_XE = SEGA_XS+41 SEGA_XG = SEGA_XE+39 SEGA_XA = SEGA_XG+40 SEGA_Y = 90 SEGA_S_WIDTH = 41 SEGA_E_WIDTH = 39 SEGA_G_WIDTH = 40 SEGA_A_WIDTH = 54 SEGA_HEIGHT = 47 MAZE_WIDTH = 30 MAZE_HEIGHT = 16 MAZE_TOP = 70 MAZE_BOTTOM = MAZE_TOP+(MAZE_HEIGHT*TILE_SIZE) MAZE_LEFT = 10 MAZE_RIGHT = MAZE_LEFT+(MAZE_WIDTH*TILE_SIZE) BORDER_RIGHT = vbuf+(MAZE_TOP*320)+MAZE_RIGHT BORDER_BOTTOM = vbuf+(MAZE_BOTTOM*320)+MAZE_LEFT ; vars sx = pixelshadow2 sy = sx+1 gx = sy+1 gy = gx+1 timeAdd = gy+1 timeMain = timeAdd+1 dir = timeMain+1 moveCount = dir+1 level = moveCount+1 frame = level+1 strBuffer = frame+1 treeAddr = strBuffer+6 charBuffer = treeAddr+3 maze = charBuffer+CHAR_SPRITE_SIZE ; locations to extract character & logo data to sprChars = savesscreen segaS = sprChars+4000 segaE = segaS+3000 segaG = segaE+3000 segaA = segaG+3000 huffLib = cmdpixelshadow .org userMem-2 .db tExtTok,tAsm84CeCmp start: bcall(_runindicoff) call clearVram call clearVbuf call vram8bpp xor a ld (timeMain),a ld (level),a ld (frame),a ; extract character data ld hl,packedChars ld de,sprChars ld ix,huffLib call huffExtr ; extract logo data ld hl,packedLogo ld ix,huffLib push hl \ push ix ld de,segaS ld b,0 call huffExtr pop ix \ pop hl \ push hl \ push ix ld de,segaE ld b,1 call huffExtr pop ix \ pop hl \ push hl \ push ix ld de,segaG ld b,2 call huffExtr pop ix \ pop hl ld de,segaA ld b,3 call huffExtr ld bc,50000 call waitBC ; do sega intro ld b,38 intro: push bc dec b ld a,SEGA_S_WIDTH sub b ld c,a ; C = width to copy ld de,SEGA_XS ld ix,segaS call copySprite pop bc push bc dec b ld a,SEGA_E_WIDTH sub b ld c,a ; C = width to copy ld de,SEGA_XE ld ix,segaE call copySprite pop bc push bc dec b ld a,SEGA_G_WIDTH sub b ld c,a ; C = width to copy ld de,SEGA_XG ld ix,segaG call copySprite pop bc push bc dec b ld a,SEGA_A_WIDTH sub b ld c,a ; C = width to copy ld de,SEGA_XA ld ix,segaA call copySprite pop bc djnz intro call clearVbuf ld bc,100000 call waitBC ; write top text ld ix,strWelcome1 ld de,20 ld l,20 call printString ; "WELCOME..." ld de,20 ld l,30 call printString ; "MASTER..." ld de,248 ld l,15 call printString ; version number ld de,190 ld l,45 call printString ; "RD" ld de,240 ld l,45 call printString ; "TIME" ld a,C_YELLOW ld (__charColour),a newLevel: ld a,(level) ld b,a add a,a add a,b ld de,0 ld e,a ld hl,levelTable add hl,de ; HL => levelTable entry bcall(_lddehl) ex de,hl ; HL => level data call loadMaze ld a,(level) inc a ld hl,0 \ ld l,a ; HL = round number ld b,2 ld de,190+(CHAR_WIDTH*3) ld c,45 call printHL ; show round number ld a,(timeMain) ld hl,0 \ ld l,a ; HL = time left ld b,3 ld de,240+(CHAR_WIDTH*5) ld c,45 call printHL ; show time left call copyVbuf call drawMaze mainLoop: ld a,(timeMain) ld hl,0 \ ld l,a ; HL = time left ld b,3 ld de,240+(CHAR_WIDTH*5) ld c,45 call printHL ; show time left call drawSnail call copyVbuf ; check keys call scanKeys ld a,(moveCount) dec a bit 7,a jp z,continueMove ; if partway through a move, continue it and skip the d-pad checking ld a,(kbdG7) bit kbitUp,a jp nz,moveUp bit kbitDown,a jp nz,moveDown bit kbitLeft,a jp nz,moveLeft bit kbitRight,a jp nz,moveRight afterDpad: ld a,(kbdG6) bit kbitClear,a ; [CLEAR]? jr nz,quit ld a,(kbdG1) bit kbitMode,a ; [MODE]? jr nz,quit ei ld hl,frame inc (hl) ld a,(hl) and $3F jr nz,afterCheckTime ; only decrement time every 64th frame ld hl,timeMain ld a,(hl) dec (hl) or a ; was timer 0 and it's now finished? jr z,timeUp afterCheckTime: call checkGoal jr nc,mainLoop mazeFinished: ld hl,level inc (hl) ld a,(hl) cp NUM_LEVELS jp nz,newLevel gameFinished: ld ix,strCongrats ld de,96 ld l,MAZE_TOP-8 call printString ; "CONGRATULATIONS!" call copyVbuf ld bc,200000 call waitBC call waitKey quit: call vram16bpp bcall(_clrlcdfull) bcall(_homeup) bcall(_drawstatusbar) ei ret timeUp: ld ix,strTimeUp ld de,128 ld l,MAZE_TOP-8 call printString ; "TIME UP!" call copyVbuf ld bc,200000 call waitBC jr quit vram8bpp: ld hl,palette ld de,mpLcdPalette ld bc,PALETTE_SIZE ldir ld a,$27 ld (mpLcdCtrl),a ret vram16bpp: ld a,$2D ld (mpLcdCtrl),a ret waitKey: bcall(_getcsc) ; A = key pressed or a ; check if 0 jr z,waitKey ; if so, no key was pressed ret clearVram: ld hl,vram ld de,vram+1 jr clearBuf clearVbuf: ld hl,vbuf ld de,vbuf+1 clearBuf: ld (hl),C_BLACK ld bc,320*240-1 ldir ret copyVbuf: ld hl,vbuf ld de,vram ld bc,320*240 ldir ret ;------------------------------------------------ ; scanKeys - scan keys ; input: none ; output: keypad registers are updated accordingly ;------------------------------------------------ scanKeys: di ld hl,DI_Mode ld (hl),$02 ; single scan mode xor a skWait: cp (hl) ; wait for idle mode jr nz,skWait ret ;------------------------------------------------ ; waitBC - wait for a bit ; input: BC = wait length ; output: none ;------------------------------------------------ waitBC: ei push bc \ pop bc push bc \ pop bc push bc \ pop bc push bc \ pop bc push bc \ pop bc push bc \ pop bc push bc \ pop bc push bc \ pop bc dec bc bcall(_chkbcis0) jr nz,waitBC ret ;------------------------------------------------ ; other routine files ;------------------------------------------------ #include "draw.asm" ; drawing routines #include "huffextr.asm" ; huffman routine #include "maze.asm" ; maze routines #include "move.asm" ; movement routines #include "text.asm" ; text routines ;------------------------------------------------ ; data ;------------------------------------------------ #include "images.asm" ; image data C_BLACK = 0 C_WHITE = 1 C_WALL = 2 C_YELLOW = 6 packedChars: #import "chars.huf" packedLogo: #import "logo.huf" tileTable: .dl tile0,tile1,tile2,tile3 snailTable: .dl snailUp,snailDown,snailLeft,snailRight strWelcome1: .db "WELCOME TO THE SEGA",0 strWelcome2: .db "MASTER SYSTEM.",0 strVersion: .db "V",VERSION,0 strRd: .db "RD",0 strTime: .db "TIME",0 strTimeUp: .db "TIME UP!",0 strCongrats: .db "CONGRATULATIONS!",0 levelTable: .dl level01,level02,level03,level04,level05,level06 .dl level07,level08,level09,level10,level11,level12 level01: #import "/maps/level01.smz" level02: #import "/maps/level02.smz" level03: #import "/maps/level03.smz" level04: #import "/maps/level04.smz" level05: #import "/maps/level05.smz" level06: #import "/maps/level06.smz" level07: #import "/maps/level07.smz" level08: #import "/maps/level08.smz" level09: #import "/maps/level09.smz" level10: #import "/maps/level10.smz" level11: #import "/maps/level11.smz" level12: #import "/maps/level12.smz" .end