2014-08-21 15:17:50 +00:00
|
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
// Handy constants.
|
2014-06-25 15:47:28 +00:00
|
|
|
const FALSE = 0
|
|
|
|
const TRUE = !FALSE
|
2014-07-19 21:17:40 +00:00
|
|
|
const NULL = 0
|
2014-07-03 23:56:26 +00:00
|
|
|
|
2014-08-21 15:17:50 +00:00
|
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
// Fixed memory locations
|
|
|
|
const raycaster = $6000 // main mem
|
2015-01-10 21:17:56 +00:00
|
|
|
const tileEngine = $6000 // main mem
|
2014-08-21 15:17:50 +00:00
|
|
|
const expandVec = $2000 // aux mem
|
|
|
|
const fontEngine = $BA00 // main mem
|
2014-07-06 21:40:35 +00:00
|
|
|
|
2014-08-21 15:17:50 +00:00
|
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
// Resource numbers
|
2014-07-06 21:40:35 +00:00
|
|
|
const RES_NUM_RAYCASTER = 1
|
|
|
|
const RES_NUM_EXPAND_VEC = 2
|
|
|
|
const RES_NUM_FONT_ENGINE = 3
|
2015-01-10 21:17:56 +00:00
|
|
|
const RES_NUM_TILE_ENGINE = 4
|
2014-07-06 21:40:35 +00:00
|
|
|
|
2014-08-21 15:17:50 +00:00
|
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
// Hardware addresses.
|
2014-06-25 15:47:28 +00:00
|
|
|
const keyboard = $C000
|
|
|
|
const keystrobe = $C010
|
2014-07-06 21:40:35 +00:00
|
|
|
|
2014-08-21 15:17:50 +00:00
|
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
// Memory manager definitions
|
2014-07-06 21:40:35 +00:00
|
|
|
|
2014-08-21 15:17:50 +00:00
|
|
|
// Resource types
|
2014-07-06 21:40:35 +00:00
|
|
|
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
|
|
|
|
|
2014-08-21 15:17:50 +00:00
|
|
|
// Memory banks
|
2014-07-06 21:40:35 +00:00
|
|
|
const MAIN_MEM = 0
|
|
|
|
const AUX_MEM = 1
|
|
|
|
|
2014-08-21 15:17:50 +00:00
|
|
|
// Command codes
|
2014-07-06 21:40:35 +00:00
|
|
|
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
|
2014-07-22 01:28:39 +00:00
|
|
|
const DEBUG_MEM = $1A
|
2014-07-06 21:40:35 +00:00
|
|
|
const CHAIN_LOADER = $1E
|
|
|
|
const FATAL_ERROR = $1F
|
2014-07-03 23:56:26 +00:00
|
|
|
|
2015-01-07 22:48:04 +00:00
|
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
// Other constants
|
2014-07-09 02:11:03 +00:00
|
|
|
const callbacks = $300
|
2015-01-07 22:48:04 +00:00
|
|
|
const MAX_LOC_TRIG = 128
|
2014-07-23 19:50:16 +00:00
|
|
|
|
2015-01-10 21:17:56 +00:00
|
|
|
// 3D mode
|
|
|
|
//const OVERMAP_NUM = 11
|
|
|
|
//const OVERMAP_IS_3D = 1
|
|
|
|
// 2D mode
|
|
|
|
const OVERMAP_NUM = 1
|
|
|
|
const OVERMAP_IS_3D = 0
|
|
|
|
|
2014-08-21 15:17:50 +00:00
|
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////
|
2015-01-10 21:17:56 +00:00
|
|
|
// Predefined functions, for circular calls or out-of-order calls
|
|
|
|
predef moveBackward, setWindow2, initCmds2D, initCmds3D
|
2014-07-06 23:13:44 +00:00
|
|
|
|
2014-08-21 15:17:50 +00:00
|
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
// Raycaster variables
|
2014-07-06 23:02:52 +00:00
|
|
|
const playerDir = $5D
|
|
|
|
const playerX = $5E
|
|
|
|
const playerY = $60
|
2014-07-06 23:45:27 +00:00
|
|
|
const backBuf = $6A
|
|
|
|
const frontBuf = $6B
|
2014-07-06 23:02:52 +00:00
|
|
|
|
2014-08-21 15:17:50 +00:00
|
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
// Font engine variables
|
|
|
|
const wndleft = $70 // left edge of the window
|
|
|
|
const wndwdth = $71 // right edge (NOT width) of text window
|
|
|
|
const wndtop = $72 // top of text window
|
|
|
|
const wndbtm = $73 // bottom+1 of text window
|
|
|
|
const cursh = $74 // Cursor H-pos 0-39
|
|
|
|
const cursv = $75 // Cursor V-pos 0-23
|
2014-07-08 16:39:31 +00:00
|
|
|
|
2014-08-21 15:17:50 +00:00
|
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
// Strings.
|
2014-07-06 21:40:35 +00:00
|
|
|
byte helloStr[] = "Loading Lawless Legends.\n"
|
2014-07-19 22:55:27 +00:00
|
|
|
byte tooManyTriggers[] = "Too many triggers"
|
2014-07-06 14:40:57 +00:00
|
|
|
|
2014-08-21 15:17:50 +00:00
|
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
// Global variables
|
2015-01-07 22:48:04 +00:00
|
|
|
byte mapNum = OVERMAP_NUM
|
|
|
|
byte mapIs3D = OVERMAP_IS_3D
|
2014-07-06 21:40:35 +00:00
|
|
|
word pFont
|
|
|
|
word pMap
|
2014-07-08 23:02:10 +00:00
|
|
|
word pScripts
|
2014-07-06 23:02:52 +00:00
|
|
|
word cmdTbl[64]
|
2014-07-23 19:50:16 +00:00
|
|
|
byte nLocTrig
|
|
|
|
byte locTrig_x[MAX_LOC_TRIG]
|
|
|
|
byte locTrig_y[MAX_LOC_TRIG]
|
2014-07-19 20:54:41 +00:00
|
|
|
word locTrig_func[MAX_LOC_TRIG]
|
2014-07-23 19:50:16 +00:00
|
|
|
byte prevX
|
|
|
|
byte prevY
|
2014-07-19 21:17:40 +00:00
|
|
|
word prevScript
|
2014-07-23 19:50:16 +00:00
|
|
|
byte prevMapNum
|
2015-01-07 22:48:04 +00:00
|
|
|
byte prevMapIs3D
|
2014-07-23 19:50:16 +00:00
|
|
|
byte redraw
|
2014-07-22 01:28:39 +00:00
|
|
|
byte titleLoaded = FALSE
|
2014-07-23 19:50:16 +00:00
|
|
|
byte cacheSky, cacheGround
|
|
|
|
word cacheX, cacheY
|
|
|
|
byte cacheDir
|
|
|
|
byte resetLocFromCache = FALSE
|
2014-07-06 23:02:52 +00:00
|
|
|
|
2014-08-21 15:17:50 +00:00
|
|
|
// Movement amounts when walking at each angle
|
|
|
|
// Each entry consists of an X bump and a Y bump, in 8.8 fixed point
|
2014-07-06 23:02:52 +00:00
|
|
|
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
|
2014-07-03 23:56:26 +00:00
|
|
|
|
2014-08-21 15:17:50 +00:00
|
|
|
byte skyGndTbl1[] = $00 // lo-bit black
|
|
|
|
byte = $00 // lo-bit black
|
|
|
|
byte = $00 // lo-bit black
|
|
|
|
byte = $02 // violet
|
|
|
|
byte = $08 // green
|
|
|
|
byte = $0A // lo-bit white
|
|
|
|
byte = $0A // lo-bit white
|
|
|
|
byte = $0A // lo-bit white
|
|
|
|
byte = $20 // hi-bit black
|
|
|
|
byte = $20 // hi-bit black
|
|
|
|
byte = $20 // hi-bit black
|
|
|
|
byte = $22 // blue
|
|
|
|
byte = $28 // orange
|
|
|
|
byte = $2A // hi-bit white
|
|
|
|
byte = $2A // hi-bit white
|
|
|
|
byte = $2A // hi-bit white
|
|
|
|
byte skyGndTbl2[] = $00 // lo-bit black
|
|
|
|
byte = $02 // violet
|
|
|
|
byte = $08 // green
|
|
|
|
byte = $02 // violet
|
|
|
|
byte = $08 // green
|
|
|
|
byte = $02 // violet
|
|
|
|
byte = $08 // green
|
|
|
|
byte = $0A // lo-bit white
|
|
|
|
byte = $20 // hi-bit black
|
|
|
|
byte = $22 // blue
|
|
|
|
byte = $28 // orange
|
|
|
|
byte = $22 // blue
|
|
|
|
byte = $28 // orange
|
|
|
|
byte = $22 // blue
|
|
|
|
byte = $28 // orange
|
|
|
|
byte = $2A // hi-bit white
|
2014-07-07 00:04:26 +00:00
|
|
|
|
2014-07-07 01:22:31 +00:00
|
|
|
word skyNum = 9
|
|
|
|
word groundNum = 10
|
2014-07-07 00:04:26 +00:00
|
|
|
|
2014-08-21 15:17:50 +00:00
|
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
// Definitions used by assembly code
|
2014-07-03 23:56:26 +00:00
|
|
|
asm __defs
|
2014-07-06 21:40:35 +00:00
|
|
|
!source "../../include/global.i"
|
|
|
|
!source "../../include/plasma.i"
|
|
|
|
!source "../../include/mem.i"
|
|
|
|
!source "../../include/fontEngine.i"
|
|
|
|
tmp = $2
|
|
|
|
pTmp = $4
|
2014-07-03 23:56:26 +00:00
|
|
|
end
|
|
|
|
|
2014-08-21 15:17:50 +00:00
|
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
// Print a string
|
2014-07-03 23:56:26 +00:00
|
|
|
asm puts
|
2014-07-06 21:40:35 +00:00
|
|
|
txa
|
|
|
|
pha
|
2014-07-06 23:02:52 +00:00
|
|
|
bit setROM
|
2014-07-06 21:40:35 +00:00
|
|
|
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
|
2014-07-06 14:40:57 +00:00
|
|
|
end
|
|
|
|
|
2014-08-21 15:17:50 +00:00
|
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
// Print a 16-bit hex value, followed by a space
|
2014-07-06 14:40:57 +00:00
|
|
|
asm printHex
|
2014-07-06 21:40:35 +00:00
|
|
|
bit setROM
|
|
|
|
lda evalStkH,x
|
|
|
|
jsr prbyte
|
|
|
|
lda evalStkL,x
|
|
|
|
jsr prbyte
|
|
|
|
lda #$A0
|
|
|
|
jsr cout
|
|
|
|
bit setLcRW+lcBank2
|
|
|
|
rts
|
2014-06-25 15:47:28 +00:00
|
|
|
end
|
2014-07-03 23:56:26 +00:00
|
|
|
|
2015-01-10 21:17:56 +00:00
|
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
// Print a carriage return
|
2014-07-06 23:02:52 +00:00
|
|
|
asm crout
|
|
|
|
bit setROM
|
|
|
|
jsr crout
|
2014-07-09 02:11:03 +00:00
|
|
|
dex ; don't-care return value
|
2014-07-06 23:02:52 +00:00
|
|
|
bit setLcRW+lcBank2
|
|
|
|
rts
|
|
|
|
end
|
|
|
|
|
2015-01-10 21:17:56 +00:00
|
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
// Ring the bell
|
2014-07-19 22:55:27 +00:00
|
|
|
asm beep
|
|
|
|
bit setROM
|
|
|
|
jsr bell
|
|
|
|
dex ; don't-care return value
|
|
|
|
bit setLcRW+lcBank2
|
|
|
|
rts
|
|
|
|
end
|
|
|
|
|
2014-08-21 15:17:50 +00:00
|
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////
|
2015-01-10 21:17:56 +00:00
|
|
|
// Send a command to the memory manager
|
2014-08-21 15:17:50 +00:00
|
|
|
// Params: cmd, mainOrAux, amount
|
|
|
|
asm loader
|
2014-07-06 21:40:35 +00:00
|
|
|
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
|
2014-07-06 23:02:52 +00:00
|
|
|
inx ; drop second and third parameters
|
|
|
|
inx
|
2014-07-06 21:40:35 +00:00
|
|
|
lda tmp
|
|
|
|
sta evalStkL,x
|
|
|
|
tya
|
|
|
|
sta evalStkH,x
|
|
|
|
bit setLcRW+lcBank2
|
|
|
|
rts
|
|
|
|
end
|
|
|
|
|
2014-08-21 15:17:50 +00:00
|
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
// Set up the font engine
|
|
|
|
// Params: pFont
|
|
|
|
asm initFontEngine
|
2014-07-06 21:40:35 +00:00
|
|
|
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
|
|
|
|
|
2014-08-21 15:17:50 +00:00
|
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////
|
2015-01-18 00:38:52 +00:00
|
|
|
// Set up the ray casting engine or tile engine (they share the same address)
|
2014-08-21 15:17:50 +00:00
|
|
|
// Params: pMap
|
2015-01-18 00:38:52 +00:00
|
|
|
asm initDisplayEngine
|
2014-07-06 21:40:35 +00:00
|
|
|
txa
|
|
|
|
pha
|
|
|
|
bit setROM
|
|
|
|
lda evalStkL,x
|
|
|
|
ldy evalStkH,x
|
|
|
|
jsr $6000
|
|
|
|
pla
|
|
|
|
tax
|
|
|
|
bit setLcRW+lcBank2
|
|
|
|
rts
|
|
|
|
end
|
|
|
|
|
2015-01-10 21:17:56 +00:00
|
|
|
|
2014-08-21 15:17:50 +00:00
|
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////
|
2015-01-18 00:38:52 +00:00
|
|
|
// Render one frame using the ray caster or tile engine (they share the same address)
|
2014-08-21 15:17:50 +00:00
|
|
|
// Params: none
|
2015-01-18 00:38:52 +00:00
|
|
|
asm renderFrame
|
2014-07-06 21:40:35 +00:00
|
|
|
txa
|
|
|
|
pha
|
|
|
|
bit setROM
|
|
|
|
jsr $6003
|
|
|
|
pla
|
|
|
|
tax
|
2014-07-06 23:02:52 +00:00
|
|
|
dex ; don't-care return value
|
2014-07-06 21:40:35 +00:00
|
|
|
bit setLcRW+lcBank2
|
|
|
|
rts
|
2014-07-06 14:40:57 +00:00
|
|
|
end
|
2014-07-06 21:40:35 +00:00
|
|
|
|
2014-08-21 15:17:50 +00:00
|
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
// Is the player's current position a physical obstruction?
|
|
|
|
// Params: none
|
2014-07-06 23:09:10 +00:00
|
|
|
asm isBlocked
|
|
|
|
txa
|
|
|
|
pha
|
|
|
|
bit setROM
|
|
|
|
jsr $6006
|
|
|
|
tay
|
|
|
|
pla
|
|
|
|
tax
|
|
|
|
dex
|
|
|
|
tya
|
|
|
|
sta evalStkL,x
|
|
|
|
lda #0
|
|
|
|
sta evalStkH,x
|
|
|
|
bit setLcRW+lcBank2
|
|
|
|
rts
|
|
|
|
end
|
|
|
|
|
2014-08-21 15:17:50 +00:00
|
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
// Is there a script attached to the player's current position?
|
|
|
|
// Params: none
|
2014-07-19 21:17:40 +00:00
|
|
|
asm isScripted
|
|
|
|
txa
|
|
|
|
pha
|
|
|
|
bit setROM
|
|
|
|
jsr $6009
|
|
|
|
tay
|
|
|
|
pla
|
|
|
|
tax
|
|
|
|
dex
|
|
|
|
tya
|
|
|
|
sta evalStkL,x
|
|
|
|
lda #0
|
|
|
|
sta evalStkH,x
|
|
|
|
bit setLcRW+lcBank2
|
|
|
|
rts
|
|
|
|
end
|
|
|
|
|
2014-08-21 15:17:50 +00:00
|
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
// Set either the sky or ground color
|
|
|
|
// Params: (index<<8) | (colorCode)
|
2014-07-07 00:04:26 +00:00
|
|
|
asm setColor
|
|
|
|
txa
|
|
|
|
pha
|
|
|
|
bit setROM
|
|
|
|
lda evalStkL,x
|
|
|
|
ldy evalStkH,x
|
2014-07-19 21:17:40 +00:00
|
|
|
jsr $600C
|
2014-07-07 00:04:26 +00:00
|
|
|
bit setLcRW+lcBank2
|
|
|
|
pla
|
|
|
|
tax
|
|
|
|
rts
|
|
|
|
end
|
|
|
|
|
2014-08-21 15:17:50 +00:00
|
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
// Jump straight to the system monitor
|
|
|
|
// Params: None
|
2014-07-06 21:40:35 +00:00
|
|
|
asm goMon
|
|
|
|
bit setROM
|
|
|
|
jmp $FF69
|
2014-07-03 23:56:26 +00:00
|
|
|
end
|
|
|
|
|
2014-08-21 15:17:50 +00:00
|
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
// Use the font engine to clear the current text window
|
|
|
|
// Params: None
|
2014-07-09 02:11:03 +00:00
|
|
|
asm clearWindow
|
|
|
|
bit setROM
|
|
|
|
txa
|
|
|
|
pha
|
|
|
|
jsr clearWINDOW
|
|
|
|
bit setLcRW+lcBank2
|
|
|
|
pla
|
|
|
|
tax
|
|
|
|
dex ; don't-care return value
|
|
|
|
rts
|
|
|
|
end
|
|
|
|
|
2014-08-21 15:17:50 +00:00
|
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
// Display a string using the font engine. Automatically splits lines to keep words from breaking.
|
|
|
|
// Params: pStr
|
|
|
|
asm displayStr
|
2014-07-25 23:33:44 +00:00
|
|
|
bit setROM
|
2014-07-20 22:52:51 +00:00
|
|
|
txa
|
|
|
|
pha
|
|
|
|
lda evalStkL,x
|
|
|
|
sta pTmp
|
|
|
|
lda evalStkH,x
|
|
|
|
sta pTmp+1
|
|
|
|
ldy #0
|
|
|
|
lda (pTmp),y
|
|
|
|
beq ++
|
|
|
|
inc pTmp
|
|
|
|
bne +
|
|
|
|
inc pTmp+1
|
|
|
|
+
|
|
|
|
-- tax
|
|
|
|
ldy #0
|
|
|
|
- lda (pTmp),y
|
2014-07-25 22:05:34 +00:00
|
|
|
cmp #$20
|
|
|
|
bcc +
|
|
|
|
cmp #$80
|
|
|
|
bcc ++
|
|
|
|
+ lda #$C4
|
|
|
|
jsr $fded
|
|
|
|
brk
|
2014-07-25 23:33:44 +00:00
|
|
|
++ dex
|
2014-07-20 22:52:51 +00:00
|
|
|
cmp #$20
|
|
|
|
beq +
|
|
|
|
sta $281,y
|
|
|
|
iny
|
|
|
|
cpx #0
|
|
|
|
bne -
|
|
|
|
+ sty $280
|
|
|
|
tya
|
|
|
|
sec
|
|
|
|
adc pTmp
|
|
|
|
sta pTmp
|
|
|
|
bcc +
|
|
|
|
inc pTmp+1
|
|
|
|
+ txa
|
|
|
|
pha
|
2014-07-22 01:28:39 +00:00
|
|
|
tya
|
|
|
|
clc
|
|
|
|
adc cursh
|
|
|
|
sec
|
|
|
|
sbc #2
|
|
|
|
cmp wndwdth
|
|
|
|
bcc +
|
|
|
|
lda #$D
|
|
|
|
jsr printCHAR
|
|
|
|
+ ldy #$80
|
2014-07-20 22:52:51 +00:00
|
|
|
ldx #2
|
|
|
|
jsr printSTR
|
2014-07-22 01:28:39 +00:00
|
|
|
lda cursh
|
|
|
|
cmp wndleft
|
|
|
|
beq +
|
|
|
|
lda #$20
|
|
|
|
jsr printCHAR
|
|
|
|
+ pla
|
2014-07-20 22:52:51 +00:00
|
|
|
bne --
|
2014-07-22 01:28:39 +00:00
|
|
|
++ lda #$d
|
|
|
|
jsr printCHAR
|
|
|
|
bit setLcRW+lcBank2
|
2014-07-20 22:52:51 +00:00
|
|
|
pla
|
|
|
|
tax
|
|
|
|
rts
|
2014-07-08 16:39:31 +00:00
|
|
|
end
|
|
|
|
|
2014-08-21 15:17:50 +00:00
|
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
// General methods
|
2014-07-06 23:45:27 +00:00
|
|
|
|
2015-01-10 21:17:56 +00:00
|
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
// Fatal error: print message and stop the system.
|
2014-07-19 22:55:27 +00:00
|
|
|
def fatal(msg)
|
|
|
|
loader(FATAL_ERROR, MAIN_MEM, msg)
|
|
|
|
end
|
|
|
|
|
2015-01-10 21:17:56 +00:00
|
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
// Get a keystroke and convert it to upper case
|
2014-07-22 01:28:39 +00:00
|
|
|
def getUpperKey()
|
|
|
|
byte key
|
|
|
|
while ^keyboard < 128
|
|
|
|
loop
|
|
|
|
key = ^keyboard & $7F
|
|
|
|
^keystrobe
|
|
|
|
if key >= $60
|
|
|
|
key = key - $20
|
|
|
|
fin
|
|
|
|
return key
|
|
|
|
end
|
|
|
|
|
2015-01-10 21:17:56 +00:00
|
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
// Set the sky color (relevant to 3D display only)
|
2014-07-23 19:50:16 +00:00
|
|
|
def setSky(num)
|
|
|
|
skyNum = num
|
|
|
|
setColor(0<<8 | skyGndTbl1[skyNum])
|
|
|
|
setColor(1<<8 | skyGndTbl2[skyNum])
|
|
|
|
end
|
|
|
|
|
2015-01-10 21:17:56 +00:00
|
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
// Switch to the next sky color (3D only)
|
2014-07-23 19:50:16 +00:00
|
|
|
def nextSky()
|
|
|
|
setSky((skyNum + 1) & $F)
|
|
|
|
end
|
|
|
|
|
2015-01-10 21:17:56 +00:00
|
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
// Set the ground color (relevant to 3D display only)
|
2014-07-23 19:50:16 +00:00
|
|
|
def setGround(num)
|
|
|
|
groundNum = num
|
|
|
|
setColor(2<<8 | skyGndTbl1[groundNum])
|
|
|
|
setColor(3<<8 | skyGndTbl2[groundNum])
|
|
|
|
end
|
|
|
|
|
2015-01-10 21:17:56 +00:00
|
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
// Switch to the next ground color
|
2014-07-23 19:50:16 +00:00
|
|
|
def nextGround()
|
|
|
|
setGround((groundNum + 1) & $F)
|
|
|
|
end
|
|
|
|
|
2015-01-10 21:17:56 +00:00
|
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
// Switch to text mode and display mem manager debug printout, get a key, switch back to graphics.
|
2014-07-25 22:05:34 +00:00
|
|
|
def debugMem(bank, code)
|
|
|
|
^$c051
|
|
|
|
^$c054
|
|
|
|
printHex(code)
|
|
|
|
loader(DEBUG_MEM, bank, 0)
|
|
|
|
getUpperKey()
|
|
|
|
^$c050
|
|
|
|
end
|
|
|
|
|
2015-01-10 21:17:56 +00:00
|
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
// Clear the command table
|
|
|
|
def resetCmds()
|
|
|
|
byte i
|
|
|
|
for i = 0 to 63
|
|
|
|
cmdTbl[i] = 0
|
|
|
|
next
|
|
|
|
end
|
|
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
// Establish a keystroke -> command association in the command table
|
|
|
|
def initCmd(key, func)
|
|
|
|
if key >= $60
|
|
|
|
key = key - $20
|
|
|
|
fin
|
|
|
|
cmdTbl[key-$20] = func
|
|
|
|
end
|
|
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
// Load the Frame Image, and lock it.
|
|
|
|
def loadFrameImg()
|
|
|
|
if titleLoaded
|
|
|
|
loader(UNLOCK_MEMORY,MAIN_MEM, $2000)
|
|
|
|
loader(FREE_MEMORY, MAIN_MEM, $2000)
|
|
|
|
titleLoaded = FALSE
|
|
|
|
fin
|
|
|
|
loader(SET_MEM_TARGET, MAIN_MEM, $2000)
|
|
|
|
loader(QUEUE_LOAD, MAIN_MEM, 1<<8 | RES_TYPE_SCREEN)
|
|
|
|
loader(LOCK_MEMORY, MAIN_MEM, $2000)
|
|
|
|
end
|
|
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
// Load code and data, set up everything to display a 3D map
|
2015-01-07 22:48:04 +00:00
|
|
|
def initMap3D()
|
2014-07-15 16:52:58 +00:00
|
|
|
word scriptModule
|
2014-07-06 23:45:27 +00:00
|
|
|
|
2015-01-10 21:17:56 +00:00
|
|
|
// Set up the command table
|
|
|
|
initCmds3D()
|
|
|
|
|
2014-08-21 15:17:50 +00:00
|
|
|
// Reset memory (our module will stay since memory manager locked it upon load)
|
2014-07-06 23:45:27 +00:00
|
|
|
loader(RESET_MEMORY, MAIN_MEM, 0)
|
|
|
|
|
2014-08-21 15:17:50 +00:00
|
|
|
// Load the font engine
|
2014-07-06 23:45:27 +00:00
|
|
|
loader(SET_MEM_TARGET, MAIN_MEM, fontEngine)
|
|
|
|
loader(QUEUE_LOAD, MAIN_MEM, RES_NUM_FONT_ENGINE<<8 | RES_TYPE_CODE)
|
|
|
|
|
2014-08-21 15:17:50 +00:00
|
|
|
// Load the font for the font engine
|
|
|
|
loader(SET_MEM_TARGET, MAIN_MEM, $9000)
|
|
|
|
pFont = loader(QUEUE_LOAD, MAIN_MEM, 1<<8 | RES_TYPE_FONT)
|
|
|
|
|
|
|
|
// Load the raycaster
|
2014-07-06 23:45:27 +00:00
|
|
|
loader(SET_MEM_TARGET, MAIN_MEM, raycaster)
|
|
|
|
loader(QUEUE_LOAD, MAIN_MEM, RES_NUM_RAYCASTER<<8 | RES_TYPE_CODE)
|
|
|
|
|
2014-08-21 15:17:50 +00:00
|
|
|
// Load the texture expansion code
|
2014-07-06 23:45:27 +00:00
|
|
|
loader(SET_MEM_TARGET, AUX_MEM, expandVec)
|
|
|
|
loader(QUEUE_LOAD, AUX_MEM, RES_NUM_EXPAND_VEC<<8 | RES_TYPE_CODE)
|
|
|
|
|
2014-08-21 15:17:50 +00:00
|
|
|
// Load the map
|
2014-07-06 23:45:27 +00:00
|
|
|
pMap = loader(QUEUE_LOAD, MAIN_MEM, mapNum<<8 | RES_TYPE_3D_MAP)
|
|
|
|
|
2014-08-21 15:17:50 +00:00
|
|
|
// Load everything that we just queued
|
|
|
|
loader(FINISH_LOAD, MAIN_MEM, 1) // 1 = keep open
|
2014-07-06 23:45:27 +00:00
|
|
|
|
2014-08-21 15:17:50 +00:00
|
|
|
// Load the frame image (and lock it there)
|
2015-01-10 21:17:56 +00:00
|
|
|
loadFrameImg()
|
2014-07-22 01:28:39 +00:00
|
|
|
|
2014-08-21 15:17:50 +00:00
|
|
|
// Load the scripts for this map, if it has any.
|
|
|
|
scriptModule = pMap->2 // first 2 bytes are width and height, third byte is script module num
|
2014-07-15 16:52:58 +00:00
|
|
|
if scriptModule
|
|
|
|
pScripts = loader(QUEUE_LOAD, MAIN_MEM, (scriptModule << 8) | RES_TYPE_MODULE)
|
|
|
|
fin
|
2014-08-21 15:17:50 +00:00
|
|
|
loader(FINISH_LOAD, MAIN_MEM, 0) // 1 = keep open, for loading textures
|
2014-07-09 02:11:03 +00:00
|
|
|
|
2014-08-21 15:17:50 +00:00
|
|
|
// Start up the font engine
|
2014-07-06 23:45:27 +00:00
|
|
|
initFontEngine(pFont)
|
|
|
|
|
2014-08-21 15:17:50 +00:00
|
|
|
// Start up the raycaster
|
2015-01-18 00:38:52 +00:00
|
|
|
initDisplayEngine(pMap)
|
2014-07-25 18:23:27 +00:00
|
|
|
|
2014-08-21 15:17:50 +00:00
|
|
|
// Set initial player position in case the init script doesn't do it
|
2014-07-06 23:45:27 +00:00
|
|
|
^playerDir = 1
|
|
|
|
*playerX = $280
|
|
|
|
*playerY = $380
|
|
|
|
|
2014-08-21 15:17:50 +00:00
|
|
|
// Initialize the map scripts
|
2014-07-09 02:11:03 +00:00
|
|
|
setWindow2()
|
2014-07-20 14:01:21 +00:00
|
|
|
clearWindow()
|
2014-07-25 18:23:27 +00:00
|
|
|
|
2014-07-09 02:11:03 +00:00
|
|
|
prevX = -1
|
|
|
|
prevY = -1
|
2014-07-19 21:17:40 +00:00
|
|
|
prevScript = -1
|
2014-07-20 14:01:21 +00:00
|
|
|
nLocTrig = 0
|
|
|
|
prevMapNum = mapNum
|
2015-01-07 22:48:04 +00:00
|
|
|
prevMapIs3D = mapIs3D
|
2014-07-20 13:02:10 +00:00
|
|
|
if pScripts
|
|
|
|
*pScripts()
|
|
|
|
fin
|
2014-07-23 19:50:16 +00:00
|
|
|
|
2014-08-21 15:17:50 +00:00
|
|
|
// If we're returning to a map, resume from where the player left off
|
2014-07-23 19:50:16 +00:00
|
|
|
if resetLocFromCache
|
|
|
|
*playerX = cacheX
|
|
|
|
*playerY = cacheY
|
|
|
|
^playerDir = cacheDir
|
|
|
|
prevX = playerX.1 - 1
|
|
|
|
prevY = playerY.1 - 1
|
|
|
|
setSky(cacheSky)
|
|
|
|
setGround(cacheGround)
|
|
|
|
resetLocFromCache = FALSE
|
|
|
|
fin
|
2014-07-09 02:11:03 +00:00
|
|
|
|
2014-08-21 15:17:50 +00:00
|
|
|
// Draw the first frame
|
2014-07-06 23:45:27 +00:00
|
|
|
renderFrame()
|
2014-07-20 21:43:48 +00:00
|
|
|
redraw = FALSE
|
2014-07-06 23:45:27 +00:00
|
|
|
end
|
|
|
|
|
2015-01-10 21:17:56 +00:00
|
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
// Load code and data, set up everything to display a 2D map
|
|
|
|
def initMap2D()
|
|
|
|
word scriptModule
|
|
|
|
|
|
|
|
// Set up the command table
|
|
|
|
initCmds2D()
|
|
|
|
|
|
|
|
// 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 font for the font engine
|
|
|
|
loader(SET_MEM_TARGET, MAIN_MEM, $9000)
|
|
|
|
pFont = loader(QUEUE_LOAD, MAIN_MEM, 1<<8 | RES_TYPE_FONT)
|
|
|
|
|
|
|
|
// Load the tile engine
|
|
|
|
loader(SET_MEM_TARGET, MAIN_MEM, tileEngine)
|
|
|
|
loader(QUEUE_LOAD, MAIN_MEM, RES_NUM_TILE_ENGINE<<8 | RES_TYPE_CODE)
|
|
|
|
|
|
|
|
// Load everything that we just queued
|
|
|
|
loader(FINISH_LOAD, MAIN_MEM, 1) // 1 = keep open
|
|
|
|
|
|
|
|
// Load the frame image (and lock it there)
|
|
|
|
loadFrameImg()
|
|
|
|
|
|
|
|
// Start up the font engine
|
|
|
|
initFontEngine(pFont)
|
|
|
|
|
|
|
|
// Start up the tile engine
|
2015-01-18 00:38:52 +00:00
|
|
|
initDisplayEngine(mapNum)
|
2015-01-10 21:17:56 +00:00
|
|
|
|
2015-01-18 00:38:52 +00:00
|
|
|
// For now
|
|
|
|
prevX = -1
|
|
|
|
prevY = -1
|
|
|
|
prevScript = -1
|
|
|
|
nLocTrig = 0
|
|
|
|
prevMapNum = mapNum
|
|
|
|
prevMapIs3D = mapIs3D
|
|
|
|
pScripts = NULL
|
|
|
|
renderFrame()
|
|
|
|
redraw = FALSE
|
2015-01-10 21:17:56 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
// Set up mapNum (2D or 3D depending on state of is3DMap)
|
|
|
|
def initMap()
|
|
|
|
if mapIs3D
|
|
|
|
initMap3D()
|
|
|
|
else
|
|
|
|
initMap2D()
|
|
|
|
fin
|
|
|
|
end
|
|
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////
|
2014-08-21 15:17:50 +00:00
|
|
|
// Window for the map name bar
|
2014-07-08 16:39:31 +00:00
|
|
|
def setWindow1()
|
|
|
|
^wndtop = 1
|
|
|
|
^wndbtm = 2
|
|
|
|
^wndleft = 4
|
|
|
|
^wndwdth = 18
|
|
|
|
^cursv = ^wndtop
|
|
|
|
^cursh = ^wndleft
|
|
|
|
end
|
|
|
|
|
2015-01-10 21:17:56 +00:00
|
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////
|
2014-08-21 15:17:50 +00:00
|
|
|
// Window for the large upper right bar
|
2014-07-08 16:39:31 +00:00
|
|
|
def setWindow2()
|
|
|
|
^wndtop = 3
|
|
|
|
^wndbtm = 17
|
2014-07-22 01:28:39 +00:00
|
|
|
^wndleft = 22
|
2014-07-23 20:39:43 +00:00
|
|
|
^wndwdth = 37
|
2014-07-08 16:39:31 +00:00
|
|
|
^cursv = ^wndtop
|
|
|
|
^cursh = ^wndleft
|
|
|
|
end
|
|
|
|
|
2015-01-10 21:17:56 +00:00
|
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////
|
2014-08-21 15:17:50 +00:00
|
|
|
// Window for the mid-size lower right bar
|
2014-07-08 16:39:31 +00:00
|
|
|
def setWindow3()
|
|
|
|
^wndtop = 18
|
|
|
|
^wndbtm = 23
|
|
|
|
^wndleft = 23
|
|
|
|
^wndwdth = 37
|
|
|
|
^cursv = ^wndtop
|
|
|
|
^cursh = ^wndleft
|
|
|
|
end
|
|
|
|
|
2014-08-21 15:17:50 +00:00
|
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////
|
2015-01-10 21:17:56 +00:00
|
|
|
// Make sure page 1 of hi-res is displayed. Do this before doing memory manager operations, since
|
|
|
|
// they overwrite page 2.
|
2014-07-20 14:01:21 +00:00
|
|
|
def flipToFirstPage
|
|
|
|
if ^frontBuf == 1
|
|
|
|
renderFrame()
|
2014-07-20 21:43:48 +00:00
|
|
|
redraw = FALSE
|
2014-07-20 14:01:21 +00:00
|
|
|
fin
|
|
|
|
end
|
|
|
|
|
2015-01-10 21:17:56 +00:00
|
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
// Check for script(s) attached to the current location, and call them if there are any.
|
2014-07-09 02:11:03 +00:00
|
|
|
def checkScript()
|
|
|
|
word x
|
|
|
|
word y
|
|
|
|
word i
|
|
|
|
word func
|
|
|
|
x = playerX.1 - 1
|
|
|
|
y = playerY.1 - 1
|
|
|
|
if x <> prevX or y <> prevY
|
|
|
|
prevX = x
|
|
|
|
prevY = y
|
2014-07-19 21:17:40 +00:00
|
|
|
if prevScript
|
|
|
|
clearWindow()
|
|
|
|
fin
|
|
|
|
prevScript = NULL
|
|
|
|
if isScripted()
|
|
|
|
for i = 0 to nLocTrig-1
|
|
|
|
if x == locTrig_x[i] and y == locTrig_y[i]
|
|
|
|
prevScript = locTrig_func[i]
|
|
|
|
*prevScript()
|
|
|
|
fin
|
|
|
|
next
|
|
|
|
fin
|
2014-07-22 01:28:39 +00:00
|
|
|
fin
|
2015-01-07 22:48:04 +00:00
|
|
|
if (mapNum <> prevMapNum) or (mapIs3D <> prevMapIs3D)
|
2014-07-22 01:28:39 +00:00
|
|
|
flipToFirstPage()
|
2015-01-10 21:17:56 +00:00
|
|
|
initMap()
|
2014-07-09 02:11:03 +00:00
|
|
|
fin
|
|
|
|
end
|
|
|
|
|
2015-01-10 21:17:56 +00:00
|
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
// Advance one step forward (3D maps only)
|
2014-07-06 23:02:52 +00:00
|
|
|
def moveForward()
|
2014-07-07 01:22:31 +00:00
|
|
|
word wasBlocked
|
2014-07-09 02:11:03 +00:00
|
|
|
word func
|
2014-07-07 01:22:31 +00:00
|
|
|
wasBlocked = isBlocked()
|
2014-07-19 21:22:31 +00:00
|
|
|
*playerX = *playerX + walkDirs[^playerDir << 1]
|
|
|
|
*playerY = *playerY + walkDirs[(^playerDir << 1) + 1]
|
2014-07-07 01:22:31 +00:00
|
|
|
if !wasBlocked and isBlocked()
|
2014-07-06 23:09:10 +00:00
|
|
|
moveBackward()
|
|
|
|
fin
|
|
|
|
end
|
|
|
|
|
2015-01-10 21:17:56 +00:00
|
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
// Adjust player's direction plus or minus n increments (3D mode)
|
2014-07-06 23:09:10 +00:00
|
|
|
def adjustDir(n)
|
|
|
|
^playerDir = (^playerDir + n) & $F
|
2014-07-06 23:02:52 +00:00
|
|
|
end
|
|
|
|
|
2015-01-10 21:17:56 +00:00
|
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
// Move backward one step (3D mode)
|
2014-07-06 23:02:52 +00:00
|
|
|
def moveBackward()
|
2014-07-06 23:09:10 +00:00
|
|
|
adjustDir(8)
|
2014-07-06 23:02:52 +00:00
|
|
|
moveForward()
|
2014-07-06 23:09:10 +00:00
|
|
|
adjustDir(8)
|
2014-07-06 23:02:52 +00:00
|
|
|
end
|
|
|
|
|
2015-01-10 21:17:56 +00:00
|
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
// Turn left (3D mode)
|
2014-07-06 23:02:52 +00:00
|
|
|
def rotateLeft()
|
2014-07-06 23:09:10 +00:00
|
|
|
adjustDir(-1)
|
2014-07-06 23:02:52 +00:00
|
|
|
end
|
|
|
|
|
2015-01-10 21:17:56 +00:00
|
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
// Rotate to the right (3D mode)
|
2014-07-06 23:02:52 +00:00
|
|
|
def rotateRight()
|
2014-07-06 23:09:10 +00:00
|
|
|
adjustDir(1)
|
|
|
|
end
|
|
|
|
|
2015-01-10 21:17:56 +00:00
|
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
// Sidestep to the right (3D mode)
|
2014-07-06 23:09:10 +00:00
|
|
|
def strafeRight()
|
|
|
|
adjustDir(4)
|
|
|
|
moveForward()
|
|
|
|
adjustDir(-4)
|
|
|
|
end
|
|
|
|
|
2015-01-10 21:17:56 +00:00
|
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
// Sidestep to the left (3D mode)
|
2014-07-06 23:09:10 +00:00
|
|
|
def strafeLeft()
|
|
|
|
adjustDir(-4)
|
|
|
|
moveForward()
|
|
|
|
adjustDir(4)
|
2014-07-06 23:02:52 +00:00
|
|
|
end
|
|
|
|
|
2015-01-10 21:17:56 +00:00
|
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
// Switch to a new map (2D or 3D)
|
2015-01-07 22:48:04 +00:00
|
|
|
def setMap(is3D, num)
|
2014-08-21 15:17:50 +00:00
|
|
|
// save player state if we're coming *from* the over-map
|
2015-01-07 22:48:04 +00:00
|
|
|
if mapNum == OVERMAP_NUM and mapIs3D == OVERMAP_IS_3D
|
2014-07-23 19:50:16 +00:00
|
|
|
cacheX = *playerX
|
|
|
|
cacheY = *playerY
|
|
|
|
cacheDir = ^playerDir
|
|
|
|
cacheSky = skyNum
|
|
|
|
cacheGround = groundNum
|
|
|
|
else
|
|
|
|
resetLocFromCache = TRUE
|
|
|
|
fin
|
2015-01-07 22:48:04 +00:00
|
|
|
mapIs3D = is3D
|
2014-07-19 22:55:27 +00:00
|
|
|
mapNum = num
|
|
|
|
end
|
|
|
|
|
2015-01-10 21:17:56 +00:00
|
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
// Switch to next map in the current 2D or 3D mode.
|
2014-07-19 22:55:27 +00:00
|
|
|
def nextMap()
|
2014-07-06 23:45:27 +00:00
|
|
|
mapNum = mapNum + 1
|
2014-07-20 21:43:48 +00:00
|
|
|
if mapNum > 20
|
2014-07-06 23:45:27 +00:00
|
|
|
mapNum = 1
|
|
|
|
fin
|
2015-01-07 22:48:04 +00:00
|
|
|
setMap(mapIs3D, mapNum)
|
2014-07-06 23:45:27 +00:00
|
|
|
end
|
|
|
|
|
2015-01-10 21:17:56 +00:00
|
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
// Jump to a new map location (and in 3D mode, point in the given direction)
|
2014-07-20 13:02:10 +00:00
|
|
|
def teleport(x, y, dir)
|
|
|
|
*playerX = ((x+1)<<8) | $80
|
|
|
|
*playerY = ((y+1)<<8) | $80
|
2014-07-20 21:43:48 +00:00
|
|
|
prevX = x
|
|
|
|
prevY = y
|
|
|
|
prevScript = -1
|
|
|
|
clearWindow()
|
2014-07-20 13:02:10 +00:00
|
|
|
^playerDir = dir
|
2014-07-20 21:43:48 +00:00
|
|
|
redraw = TRUE
|
2014-07-20 13:02:10 +00:00
|
|
|
end
|
|
|
|
|
2015-01-10 21:17:56 +00:00
|
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
// Get a key and dispatch it to a command. Then do it again, forever.
|
2014-07-06 23:02:52 +00:00
|
|
|
def kbdLoop()
|
|
|
|
word key, func
|
|
|
|
while TRUE
|
2014-07-19 22:55:27 +00:00
|
|
|
key = getUpperKey()
|
|
|
|
key = key - $20
|
|
|
|
if key >= 0 and key < $40
|
|
|
|
func = cmdTbl[key]
|
|
|
|
if func
|
|
|
|
func()
|
|
|
|
renderFrame()
|
2014-07-20 21:43:48 +00:00
|
|
|
redraw = FALSE
|
2014-07-19 22:55:27 +00:00
|
|
|
checkScript()
|
2014-07-20 21:43:48 +00:00
|
|
|
if redraw
|
|
|
|
renderFrame()
|
|
|
|
redraw = FALSE
|
|
|
|
fin
|
2014-07-06 23:02:52 +00:00
|
|
|
fin
|
|
|
|
fin
|
|
|
|
loop
|
|
|
|
end
|
|
|
|
|
2015-01-10 21:17:56 +00:00
|
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
// Associate a location with a trigger function (i.e. a script)
|
2014-07-09 02:11:03 +00:00
|
|
|
def setLocationTrigger(x, y, func)
|
2014-07-19 20:54:41 +00:00
|
|
|
if nLocTrig == MAX_LOC_TRIG
|
2014-07-19 22:55:27 +00:00
|
|
|
fatal(@tooManyTriggers)
|
2014-07-19 20:54:41 +00:00
|
|
|
fin
|
2014-07-09 02:11:03 +00:00
|
|
|
locTrig_x[nLocTrig] = x
|
|
|
|
locTrig_y[nLocTrig] = y
|
|
|
|
locTrig_func[nLocTrig] = func
|
|
|
|
nLocTrig = nLocTrig + 1
|
2014-07-08 23:02:10 +00:00
|
|
|
end
|
|
|
|
|
2015-01-10 21:17:56 +00:00
|
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
// Get a key, and don't return until it's Y or N (or lower-case of those). Returns 1 for Y.
|
2014-07-19 22:55:27 +00:00
|
|
|
def getYN()
|
|
|
|
byte key
|
|
|
|
while TRUE
|
|
|
|
key = getUpperKey()
|
|
|
|
if key == 'Y'
|
|
|
|
return 1
|
|
|
|
elsif key == 'N'
|
2014-07-20 21:43:48 +00:00
|
|
|
clearWindow()
|
2014-07-19 22:55:27 +00:00
|
|
|
return 0
|
|
|
|
fin
|
|
|
|
beep()
|
|
|
|
loop
|
|
|
|
end
|
|
|
|
|
2015-01-10 21:17:56 +00:00
|
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
// Set up the command table for 3D mode
|
2015-01-07 22:48:04 +00:00
|
|
|
def initCmds3D()
|
|
|
|
resetCmds()
|
|
|
|
|
|
|
|
initCmd('W', @moveForward)
|
|
|
|
initCmd('A', @rotateLeft)
|
|
|
|
initCmd('D', @rotateRight)
|
|
|
|
initCmd('S', @moveBackward)
|
|
|
|
initCmd('X', @moveBackward)
|
|
|
|
initCmd('Z', @strafeLeft)
|
|
|
|
initCmd('C', @strafeRight)
|
|
|
|
|
|
|
|
initCmd('I', @moveForward)
|
|
|
|
initCmd('J', @rotateLeft)
|
|
|
|
initCmd('L', @rotateRight)
|
|
|
|
initCmd('K', @moveBackward)
|
|
|
|
initCmd(',', @moveBackward)
|
|
|
|
initCmd('M', @strafeLeft)
|
|
|
|
initCmd('.', @strafeRight)
|
|
|
|
|
|
|
|
initCmd('N', @nextMap)
|
|
|
|
|
|
|
|
initCmd('Y', @nextSky)
|
|
|
|
initCmd('G', @nextGround)
|
|
|
|
|
|
|
|
// $300
|
|
|
|
callbacks.0 = $4c
|
|
|
|
callbacks:1 = @setLocationTrigger
|
|
|
|
|
|
|
|
// $303
|
|
|
|
callbacks.3 = $4c
|
|
|
|
callbacks:4 = @displayStr
|
|
|
|
|
|
|
|
// $306
|
|
|
|
callbacks.6 = $4c
|
|
|
|
callbacks:7 = @getYN
|
|
|
|
|
|
|
|
// $309
|
|
|
|
callbacks.9 = $4c
|
|
|
|
callbacks:10 = @setMap
|
|
|
|
|
|
|
|
// $30C
|
|
|
|
callbacks.12 = $4c
|
|
|
|
callbacks:13 = @setSky
|
|
|
|
|
|
|
|
// $30F
|
|
|
|
callbacks.15 = $4c
|
|
|
|
callbacks:16 = @setGround
|
|
|
|
|
|
|
|
// $312
|
|
|
|
callbacks.18 = $4c
|
|
|
|
callbacks:19 = @teleport
|
|
|
|
end
|
|
|
|
|
2015-01-10 21:17:56 +00:00
|
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
// Set up the command table for 2D mode
|
|
|
|
def initCmds2D()
|
|
|
|
resetCmds()
|
|
|
|
|
|
|
|
//initCmd('W', @moveForward)
|
|
|
|
end
|
|
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
// Load and display the title screen.
|
|
|
|
def loadTitle()
|
|
|
|
puts(@helloStr)
|
|
|
|
|
|
|
|
// Load the title screen
|
|
|
|
loader(SET_MEM_TARGET, MAIN_MEM, $2000)
|
|
|
|
loader(QUEUE_LOAD, MAIN_MEM, 2<<8 | RES_TYPE_SCREEN)
|
|
|
|
loader(LOCK_MEMORY, MAIN_MEM, $2000)
|
|
|
|
loader(FINISH_LOAD, MAIN_MEM, 1) // 1 = keep open
|
|
|
|
titleLoaded = TRUE
|
|
|
|
^$c050
|
|
|
|
^$c057
|
|
|
|
^$c054
|
|
|
|
^$c052
|
|
|
|
// Hack for real (not emulated) IIc: sometimes displays only lo-bit graphics
|
|
|
|
// unless we do this. *HUGE* thanks to Brendan Robert for the fix!
|
|
|
|
^$C07E=0 // disable double-hi-res
|
|
|
|
^$C05F // disable double-hi-res
|
|
|
|
end
|
|
|
|
|
2014-08-21 15:17:50 +00:00
|
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
// Main code.
|
|
|
|
//
|
2015-01-07 22:48:04 +00:00
|
|
|
loadTitle()
|
2015-01-10 21:17:56 +00:00
|
|
|
initMap()
|
2014-07-08 16:39:31 +00:00
|
|
|
setWindow2()
|
2014-07-06 23:02:52 +00:00
|
|
|
kbdLoop()
|
|
|
|
|
2014-06-25 15:47:28 +00:00
|
|
|
done
|