lawless-legends/Platform/Apple/virtual/src/plasma/gameloop.pla

880 lines
19 KiB
Plaintext
Raw Normal View History

2014-08-21 15:17:50 +00:00
///////////////////////////////////////////////////////////////////////////////////////////////////
// Handy constants.
2014-06-25 15:47:28 +00:00
const FALSE = 0
const TRUE = !FALSE
const NULL = 0
2014-08-21 15:17:50 +00:00
///////////////////////////////////////////////////////////////////////////////////////////////////
// Fixed memory locations
const raycaster = $6000 // main mem
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
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
const DEBUG_MEM = $1A
2014-07-06 21:40:35 +00:00
const CHAIN_LOADER = $1E
const FATAL_ERROR = $1F
2014-07-09 02:11:03 +00:00
const callbacks = $300
const OVERMAP = 11
2014-08-21 15:17:50 +00:00
///////////////////////////////////////////////////////////////////////////////////////////////////
// Predefined functions, for circular calls
2014-07-09 02:11:03 +00:00
predef moveBackward, setWindow2
2014-07-06 23:13:44 +00:00
2014-08-21 15:17:50 +00:00
///////////////////////////////////////////////////////////////////////////////////////////////////
// Raycaster variables
word zp = 0
const playerDir = $5D
const playerX = $5E
const playerY = $60
2014-07-06 23:45:27 +00:00
const backBuf = $6A
const frontBuf = $6B
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
2014-08-21 15:17:50 +00:00
const cursh = $74 // Cursor H-pos 0-39
const cursv = $75 // Cursor V-pos 0-23
const MAX_LOC_TRIG = 128
2014-08-21 15:17:50 +00:00
///////////////////////////////////////////////////////////////////////////////////////////////////
// Strings.
2014-07-06 21:40:35 +00:00
byte helloStr[] = "Loading Lawless Legends.\n"
byte loopStr[] = "Entering keyboard loop.\n"
byte tooManyTriggers[] = "Too many triggers"
2014-07-06 14:40:57 +00:00
2014-08-21 15:17:50 +00:00
///////////////////////////////////////////////////////////////////////////////////////////////////
// Global variables
byte mapNum = OVERMAP
2014-07-06 21:40:35 +00:00
word pFont
word pMap
word pScripts
word cmdTbl[64]
byte nLocTrig
byte locTrig_x[MAX_LOC_TRIG]
byte locTrig_y[MAX_LOC_TRIG]
word locTrig_func[MAX_LOC_TRIG]
byte prevX
byte prevY
word prevScript
byte prevMapNum
byte redraw
byte titleLoaded = FALSE
byte cacheSky, cacheGround
word cacheX, cacheY
byte cacheDir
byte resetLocFromCache = FALSE
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
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-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
word skyNum = 9
word groundNum = 10
2014-08-21 15:17:50 +00:00
///////////////////////////////////////////////////////////////////////////////////////////////////
// Definitions used by assembly code
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
end
2014-08-21 15:17:50 +00:00
///////////////////////////////////////////////////////////////////////////////////////////////////
// Print a string
asm puts
2014-07-06 21:40:35 +00:00
txa
pha
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
asm crout
bit setROM
jsr crout
2014-07-09 02:11:03 +00:00
dex ; don't-care return value
bit setLcRW+lcBank2
rts
end
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
///////////////////////////////////////////////////////////////////////////////////////////////////
// Work with the memory manager
// 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
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
///////////////////////////////////////////////////////////////////////////////////////////////////
// Set up the ray casting engine
// Params: pMap
asm initRaycaster
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
2014-08-21 15:17:50 +00:00
///////////////////////////////////////////////////////////////////////////////////////////////////
// Render one frame using the ray caster.
// Params: none
2014-07-06 21:40:35 +00:00
asm renderFrame
txa
pha
bit setROM
jsr $6003
pla
tax
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
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
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)
asm setColor
txa
pha
bit setROM
lda evalStkL,x
ldy evalStkH,x
jsr $600C
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
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
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
cmp #$20
bcc +
cmp #$80
bcc ++
+ lda #$C4
jsr $fded
brk
++ 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
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
lda cursh
cmp wndleft
beq +
lda #$20
jsr printCHAR
+ pla
2014-07-20 22:52:51 +00:00
bne --
++ lda #$d
jsr printCHAR
bit setLcRW+lcBank2
2014-07-20 22:52:51 +00:00
pla
tax
rts
end
2014-08-21 15:17:50 +00:00
///////////////////////////////////////////////////////////////////////////////////////////////////
// General methods
2014-07-06 23:45:27 +00:00
def fatal(msg)
loader(FATAL_ERROR, MAIN_MEM, msg)
end
def getUpperKey()
byte key
while ^keyboard < 128
loop
key = ^keyboard & $7F
^keystrobe
if key >= $60
key = key - $20
fin
return key
end
def setSky(num)
skyNum = num
setColor(0<<8 | skyGndTbl1[skyNum])
setColor(1<<8 | skyGndTbl2[skyNum])
end
def nextSky()
setSky((skyNum + 1) & $F)
end
def setGround(num)
groundNum = num
setColor(2<<8 | skyGndTbl1[groundNum])
setColor(3<<8 | skyGndTbl2[groundNum])
end
def nextGround()
setGround((groundNum + 1) & $F)
end
def debugMem(bank, code)
^$c051
^$c054
printHex(code)
loader(DEBUG_MEM, bank, 0)
getUpperKey()
^$c050
end
2014-07-06 23:45:27 +00:00
def initMap()
word scriptModule
2014-07-06 23:45:27 +00:00
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)
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)
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
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
2014-07-25 18:23:27 +00:00
initRaycaster(pMap)
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()
clearWindow()
2014-07-25 18:23:27 +00:00
2014-07-09 02:11:03 +00:00
prevX = -1
prevY = -1
prevScript = -1
nLocTrig = 0
prevMapNum = mapNum
if pScripts
*pScripts()
fin
2014-08-21 15:17:50 +00:00
// If we're returning to a map, resume from where the player left off
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()
redraw = FALSE
2014-07-06 23:45:27 +00:00
end
2014-08-21 15:17:50 +00:00
// Window for the map name bar
def setWindow1()
^wndtop = 1
^wndbtm = 2
^wndleft = 4
^wndwdth = 18
^cursv = ^wndtop
^cursh = ^wndleft
end
2014-08-21 15:17:50 +00:00
// Window for the large upper right bar
def setWindow2()
^wndtop = 3
^wndbtm = 17
^wndleft = 22
2014-07-23 20:39:43 +00:00
^wndwdth = 37
^cursv = ^wndtop
^cursh = ^wndleft
end
2014-08-21 15:17:50 +00:00
// Window for the mid-size lower right bar
def setWindow3()
^wndtop = 18
^wndbtm = 23
^wndleft = 23
^wndwdth = 37
^cursv = ^wndtop
^cursh = ^wndleft
end
2014-08-21 15:17:50 +00:00
///////////////////////////////////////////////////////////////////////////////////////////////////
// Actions
def initCmd(key, func)
if key >= $60
key = key - $20
fin
cmdTbl[key-$20] = func
end
def flipToFirstPage
if ^frontBuf == 1
renderFrame()
redraw = FALSE
fin
end
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
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
fin
if mapNum <> prevMapNum
flipToFirstPage()
initMap()
2014-07-09 02:11:03 +00:00
fin
end
def moveForward()
word wasBlocked
2014-07-09 02:11:03 +00:00
word func
wasBlocked = isBlocked()
*playerX = *playerX + walkDirs[^playerDir << 1]
*playerY = *playerY + walkDirs[(^playerDir << 1) + 1]
if !wasBlocked and isBlocked()
moveBackward()
fin
end
def adjustDir(n)
^playerDir = (^playerDir + n) & $F
end
def moveBackward()
adjustDir(8)
moveForward()
adjustDir(8)
end
def rotateLeft()
adjustDir(-1)
end
def rotateRight()
adjustDir(1)
end
def strafeRight()
adjustDir(4)
moveForward()
adjustDir(-4)
end
def strafeLeft()
adjustDir(-4)
moveForward()
adjustDir(4)
end
def setMap(is3d, num)
2014-08-21 15:17:50 +00:00
// save player state if we're coming *from* the over-map
if mapNum == OVERMAP
cacheX = *playerX
cacheY = *playerY
cacheDir = ^playerDir
cacheSky = skyNum
cacheGround = groundNum
else
resetLocFromCache = TRUE
fin
mapNum = num
end
def nextMap()
2014-07-06 23:45:27 +00:00
mapNum = mapNum + 1
if mapNum > 20
2014-07-06 23:45:27 +00:00
mapNum = 1
fin
setMap(1, mapNum)
2014-07-06 23:45:27 +00:00
end
def teleport(x, y, dir)
*playerX = ((x+1)<<8) | $80
*playerY = ((y+1)<<8) | $80
prevX = x
prevY = y
prevScript = -1
clearWindow()
^playerDir = dir
redraw = TRUE
end
def kbdLoop()
word key, func
while TRUE
key = getUpperKey()
key = key - $20
if key >= 0 and key < $40
func = cmdTbl[key]
if func
func()
renderFrame()
redraw = FALSE
checkScript()
if redraw
renderFrame()
redraw = FALSE
fin
fin
fin
loop
end
2014-07-09 02:11:03 +00:00
def setLocationTrigger(x, y, func)
if nLocTrig == MAX_LOC_TRIG
fatal(@tooManyTriggers)
fin
2014-07-09 02:11:03 +00:00
locTrig_x[nLocTrig] = x
locTrig_y[nLocTrig] = y
locTrig_func[nLocTrig] = func
nLocTrig = nLocTrig + 1
end
def getYN()
byte key
while TRUE
key = getUpperKey()
if key == 'Y'
return 1
elsif key == 'N'
clearWindow()
return 0
fin
beep()
loop
end
2014-08-21 15:17:50 +00:00
///////////////////////////////////////////////////////////////////////////////////////////////////
// Main code.
//
2014-07-06 21:40:35 +00:00
puts(@helloStr)
2014-08-21 15:17:50 +00:00
// Init the command table
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)
2014-07-06 23:45:27 +00:00
initCmd('N', @nextMap)
initCmd('Y', @nextSky)
initCmd('G', @nextGround)
2014-08-21 15:17:50 +00:00
// $300
2014-07-09 02:11:03 +00:00
callbacks.0 = $4c
callbacks:1 = @setLocationTrigger
2014-08-21 15:17:50 +00:00
// $303
2014-07-09 02:11:03 +00:00
callbacks.3 = $4c
callbacks:4 = @displayStr
2014-08-21 15:17:50 +00:00
// $306
callbacks.6 = $4c
callbacks:7 = @getYN
2014-08-21 15:17:50 +00:00
// $309
callbacks.9 = $4c
callbacks:10 = @setMap
2014-08-21 15:17:50 +00:00
// $30C
callbacks.12 = $4c
callbacks:13 = @setSky
2014-08-21 15:17:50 +00:00
// $30F
callbacks.15 = $4c
callbacks:16 = @setGround
2014-08-21 15:17:50 +00:00
// $312
callbacks.18 = $4c
callbacks:19 = @teleport
2014-08-21 15:17:50 +00:00
// 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)
2014-08-21 15:17:50 +00:00
loader(FINISH_LOAD, MAIN_MEM, 1) // 1 = keep open
titleLoaded = TRUE
^$c050
^$c057
^$c054
^$c052
2014-08-21 15:17:50 +00:00
// 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
2014-07-06 23:45:27 +00:00
initMap()
2014-07-06 21:40:35 +00:00
setWindow2()
2014-08-21 15:17:50 +00:00
// Main keyboard loop
puts(@loopStr)
kbdLoop()
2014-06-25 15:47:28 +00:00
done