;================================================================================================== ; Handy constants. const FALSE = 0 const TRUE = !FALSE ;================================================================================================== ; Fixed memory locations const raycaster = $6000 ; main mem const expandVec = $800 ; aux mem const fontEngine = $BA00 ; main mem ;================================================================================================== ; Resource numbers const RES_NUM_RAYCASTER = 1 const RES_NUM_EXPAND_VEC = 2 const RES_NUM_FONT_ENGINE = 3 ;================================================================================================== ; Hardware addresses. const keyboard = $C000 const keystrobe = $C010 ;================================================================================================== ; Memory manager definitions ; Resource types const RES_TYPE_CODE = 1 const RES_TYPE_2D_MAP = 2 const RES_TYPE_3D_MAP = 3 const RES_TYPE_TILE = 4 const RES_TYPE_TEXTURE = 5 const RES_TYPE_SCREEN = 6 const RES_TYPE_FONT = 7 const RES_TYPE_MODULE = 8 const RES_TYPE_BYTECODE = 9 const RES_TYPE_FIXUP = 10 ; Memory banks const MAIN_MEM = 0 const AUX_MEM = 1 ; Command codes const RESET_MEMORY = $10 const REQUEST_MEMORY = $11 const LOCK_MEMORY = $12 const UNLOCK_MEMORY = $13 const SET_MEM_TARGET = $14 const START_LOAD = $15 const QUEUE_LOAD = $16 const FINISH_LOAD = $17 const FREE_MEMORY = $18 const CALC_FREE = $19 const CHAIN_LOADER = $1E const FATAL_ERROR = $1F ;================================================================================================== ; Raycaster variables word zp = 0 const playerDir = $5D const playerX = $5E const playerY = $60 ;================================================================================================== ; Strings. byte helloStr[] = "Loading Lawless Legends.\n" byte initFontStr[] = "Initting font engine.\n" byte initRaycastStr[] = "Initting raycaster.\n" byte loopStr[] = "Entering keyboard loop.\n" ;================================================================================================== ; Global variables word mapNum = 1 word pFont word pMap word cmdTbl[64] ; Movement amounts when walking at each angle ; Each entry consists of an X bump and a Y bump, in 8.8 fixed point word walkDirs[] = $0040, $0000 word = $003B, $0018 word = $002D, $002D word = $0018, $003B word = $0000, $0040 word = $FFE8, $003B word = $FFD3, $002D word = $FFC5, $0018 word = $FFC0, $0000 word = $FFC5, $FFE8 word = $FFD3, $FFD3 word = $FFE8, $FFC5 word = $0000, $FFC0 word = $0018, $FFC5 word = $002D, $FFD3 word = $003B, $FFE8 ;================================================================================================== ; Definitions used by assembly code asm __defs !source "../../include/global.i" !source "../../include/plasma.i" !source "../../include/mem.i" !source "../../include/fontEngine.i" tmp = $2 pTmp = $4 end ;================================================================================================== ; Print a string asm puts txa pha bit setROM lda evalStkL,x sta pTmp lda evalStkH,x sta pTmp+1 ldy #0 lda (pTmp),y tax iny - lda (pTmp),y ora #$80 jsr cout iny dex bne - bit setLcRW+lcBank2 pla tax rts end ;================================================================================================== ; Print a 16-bit hex value, followed by a space asm printHex bit setROM lda evalStkH,x jsr prbyte lda evalStkL,x jsr prbyte lda #$A0 jsr cout bit setLcRW+lcBank2 rts end asm crout bit setROM jsr crout inx ; don't-care return value bit setLcRW+lcBank2 rts end ;================================================================================================== ; Allocate memory asm loader ; (cmd, mainOrAux, amount) txa pha bit setROM lda evalStkL+2,x ; command code pha lda evalStkL+1,x ; main or aux lsr ldy evalStkH,x ; address (or other param) lda evalStkL,x tax pla bcs + jsr mainLoader clc bcc ++ + jsr auxLoader ++ stx tmp pla tax inx ; drop second and third parameters inx lda tmp sta evalStkL,x tya sta evalStkH,x bit setLcRW+lcBank2 rts end asm initFontEngine ; (pFont) txa pha bit setROM ldy evalStkL,x ; font engine likes *lo* byte in Y lda evalStkH,x ; hi byte in X tax jsr setFONT ; Set to write text on both hi-res pages at the same time lda #pHGR3 jsr displayMODE ; Set to normal (non-inverse) text lda #pNORMAL jsr drawMODE pla tax bit setLcRW+lcBank2 rts end asm initRaycaster ; (pMap) txa pha bit setROM lda evalStkL,x ldy evalStkH,x jsr $6000 pla tax bit setLcRW+lcBank2 rts end asm renderFrame txa pha bit setROM jsr $6003 pla tax dex ; don't-care return value bit setLcRW+lcBank2 rts end asm goMon bit setROM jmp $FF69 end ;================================================================================================== ; Actions def initCmd(key, func) if key >= $60 key = key - $20 fin cmdTbl[key-$20] = func end def moveForward() *playerX = *playerX + walkDirs[^playerDir * 2] *playerY = *playerY + walkDirs[^playerDir * 2 + 1] end def moveBackward() ^playerDir = (^playerDir + 8) & $F moveForward() ^playerDir = (^playerDir + 8) & $F end def rotateLeft() ^playerDir = (^playerDir - 1) & $F end def rotateRight() ^playerDir = (^playerDir + 1) & $F end def kbdLoop() word key, func while TRUE if ^keyboard >= 128 key = ^keyboard & $7F ^keystrobe key = key - $20 if key >= $40 key = key - $20 fin if key >= 0 and key < $40 func = cmdTbl[key] if func func() renderFrame() fin fin fin loop end ;================================================================================================== ; Main loop. ; puts(@helloStr) ; Reset memory (our module will stay since memory manager locked it upon load) loader(RESET_MEMORY, MAIN_MEM, 0) ; Load the font engine loader(SET_MEM_TARGET, MAIN_MEM, fontEngine) loader(QUEUE_LOAD, MAIN_MEM, RES_NUM_FONT_ENGINE<<8 | RES_TYPE_CODE) ; Load the raycaster loader(SET_MEM_TARGET, MAIN_MEM, raycaster) loader(QUEUE_LOAD, MAIN_MEM, RES_NUM_RAYCASTER<<8 | RES_TYPE_CODE) ; Load the texture expansion code loader(SET_MEM_TARGET, AUX_MEM, expandVec) loader(QUEUE_LOAD, AUX_MEM, RES_NUM_EXPAND_VEC<<8 | RES_TYPE_CODE) ; Load the frame image loader(SET_MEM_TARGET, MAIN_MEM, $2000) loader(QUEUE_LOAD, MAIN_MEM, 1<<8 | RES_TYPE_SCREEN) ; Load the font for the font engine pFont = loader(QUEUE_LOAD, MAIN_MEM, 1<<8 | RES_TYPE_FONT) ; Load the map pMap = loader(QUEUE_LOAD, MAIN_MEM, mapNum<<8 | RES_TYPE_3D_MAP) ; Load everything that we just queued loader(FINISH_LOAD, MAIN_MEM, 1) ; 1 = keep open ; Start up the font engine puts(@initFontStr) initFontEngine(pFont) ; Start up the raycaster puts(@initRaycastStr) initRaycaster(pMap) ; Set initial player position ^playerDir = 1 *playerX = $280 *playerY = $380 ; Init the command table initCmd('W', @moveForward) initCmd('A', @rotateLeft) initCmd('D', @rotateRight) initCmd('S', @moveBackward) initCmd('I', @moveForward) initCmd('J', @rotateLeft) initCmd('L', @rotateRight) initCmd('K', @moveBackward) ; Draw the first frame renderFrame() ; Main keyboard loop puts(@loopStr) kbdLoop() goMon() done