More work refactoring API to rendering engines.

This commit is contained in:
Martin Haye 2015-03-31 12:02:48 -07:00
parent bea1cc29e5
commit 4227042b11
5 changed files with 310 additions and 384 deletions

View File

@ -680,18 +680,21 @@ class PackPartitions
def buf = ByteBuffer.allocate(50000)
// Add each special tile to the set
def nFound = 0
dataIn.tile.each { tile ->
def name = tile.@name
def id = tile.@id
def data = tiles[id]
if (name.equalsIgnoreCase("Player avatar - 2D")) {
if (name.equalsIgnoreCase("Avatars1 - 2D")) {
def num = tileMap.size()
tileIds.add(id)
tileMap[id] = num
data.flip() // crazy stuff to append one buffer to another
buf.put(data)
nFound += 1
}
}
assert nFound == 1
tileSets[setName] = [num:setNum, buf:buf, tileMap:tileMap, tileIds:tileIds]
return [setNum, tileMap]

View File

@ -52,6 +52,7 @@ codeBegin:
bcc locationCheck
jmp main_dispatch
jmp aux_dispatch
jmp __asmPlasm
locationCheck:
jsr monrts
tsx
@ -1896,6 +1897,44 @@ doAllFixups: !zone
.mainBase !word 0
.auxBase !word 0
;------------------------------------------------------------------------------
; Utility routine for convenient assembly routines in PLASMA code.
; Params: Y=number of parameters passed from PLASMA routine
; 1. Save PLASMA's X register index to evalStk
; 2. Switch to ROM
; 3. Load the last parameter into A=lo, Y=hi
; 4. Run the calling routine (X still points into evalStk for add'l params if needed)
; 5. Switch back to LC RAM
; 6. Restore PLASMA's X register, and advance it over the parameter(s)
; 7. Store A=lo/Y=hi into PLASMA return value
; 8. Return to PLASMA
__asmPlasm: !zone
pla ; save address of calling routine, so we can call it
clc
adc #1
sta .jsr+1
pla
adc #0
sta .jsr+2
dey
sty tmp ; adjust PLASMA stack pointer to skip over params
txa
.add adc tmp
pha ; and save that
bit setROM ; switch to ROM
lda evalStkL,x ; get last param to A=lo
ldy evalStkH,x ; ...Y=hi
.jsr jsr $1111 ; call the routine to do work
bit setLcRW+lcBank2 ; read from language card (where PLASMA runtime lives)
sta tmp ; save return value lo
pla
tax ; restore adjusted PLASMA stack pointer
lda tmp
sta evalStkL,x ; store return value
tya
sta evalStkH,x
rts ; and return to PLASMA interpreter
;------------------------------------------------------------------------------
; Segment tables

View File

@ -274,3 +274,10 @@ FATAL_ERROR = $1F
;
; This command halts and thus never returns.
;------------------------------------------------------------------------------
; Convenience for writing assembly routines in PLASMA source
!macro asmPlasm nArgs {
ldy #nArgs
jsr _asmPlasm
}
_asmPlasm = $809

View File

@ -71,23 +71,7 @@ const OVERMAP_IS_3D = 0
///////////////////////////////////////////////////////////////////////////////////////////////////
// Predefined functions, for circular calls or out-of-order calls
predef moveBackward, setWindow2, initCmds2D, initCmds3D
///////////////////////////////////////////////////////////////////////////////////////////////////
// Raycaster variables
const playerDir = $5D
const playerX = $5E
const playerY = $60
const backBuf = $6A
const frontBuf = $6B
///////////////////////////////////////////////////////////////////////////////////////////////////
// Tile engine variables
const relX = $50
const relY = $51
const avatarTile= $9D // the avatar variables are set by tile engine during its draw phase
const avatarX = $9E
const avatarY = $9F
predef setWindow2, initCmds2D, initCmds3D
///////////////////////////////////////////////////////////////////////////////////////////////////
// Font engine variables
@ -115,58 +99,6 @@ byte redraw
byte titleLoaded = FALSE
byte textDrawn = FALSE
// 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
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
@ -191,39 +123,14 @@ DEBUG = 1
tmp = $2
pTmp = $4
; Variables that get set by the tile engine when it draws
avatarTile = $9D
avatarX = $9E ; from the tile engine
avatarY = $9F ; ...ditto
end
asm fooFunc
clc
- lda evalStkL,x
sta pTmp
lda evalStkH,x
sta pTmp+1
ldy #0
txa
sta (pTmp),y
bcs +
inx
sec
bcs -
+ rts
end
///////////////////////////////////////////////////////////////////////////////////////////////////
// Print a string
asm puts
txa
pha
bit setROM
lda evalStkL,x
+asmPlasm 1
sta pTmp
lda evalStkH,x
sta pTmp+1
sty pTmp+1
ldy #0
lda (pTmp),y
tax
@ -234,16 +141,13 @@ asm puts
iny
dex
bne -
bit setLcRW+lcBank2
pla
tax
rts
end
///////////////////////////////////////////////////////////////////////////////////////////////////
// Print part of a string, until we hit the end or a '%' code. Return how far we got, or -1 for end.
asm partialPrintf
bit setROM
+asmPlasm 2
lda evalStkL+1,x
sta pTmp
lda evalStkH+1,x
@ -257,8 +161,6 @@ asm partialPrintf
tay
iny ; increment past length byte
inx ; drop second argument
lda #0
sta evalStkH,x ; clear out high byte of return value
- lda (pTmp),y
ora #$80
cmp #'%' ; stop if we hit % code
@ -267,65 +169,50 @@ asm partialPrintf
iny
dec tmp ; otherwise go until end of string
bne -
ldy #0 ; if we hit end of string, return val will be $FF
dec evalStkH,x ; hi byte $FF as well
+ dey ; adjust back for length byte
ldy #$FF ; if we hit end of string, return -1
tya
sta evalStkL,x ; tell caller how far we got
bit setLcRW+lcBank2
rts
+ dey ; adjust back for length byte
tya ; that's the lo byte of return
ldy #0 ; hi byte of return is zero
rts
end
///////////////////////////////////////////////////////////////////////////////////////////////////
// Print a 16-bit hex value
asm printHex
bit setROM
lda evalStkH,x
jsr prbyte
lda evalStkL,x
jsr prbyte
bit setLcRW+lcBank2
rts
+asmPlasm 1
tax
tya
jmp prntax
end
///////////////////////////////////////////////////////////////////////////////////////////////////
// Print a single character
asm printChar
bit setROM
lda evalStkL,x
ora #$80
jsr cout
bit setLcRW+lcBank2
rts
+asmPlasm 1
jmp cout
end
///////////////////////////////////////////////////////////////////////////////////////////////////
// Print a carriage return
asm crout
bit setROM
jsr crout
dex ; don't-care return value
bit setLcRW+lcBank2
rts
+asmPlasm 0
jmp crout
end
///////////////////////////////////////////////////////////////////////////////////////////////////
// Ring the bell
asm beep
bit setROM
jsr bell
dex ; don't-care return value
bit setLcRW+lcBank2
rts
+asmPlasm 0
jmp bell
end
///////////////////////////////////////////////////////////////////////////////////////////////////
// Send a command to the memory manager
// Params: cmd, mainOrAux, amount
asm loader
txa
pha
bit setROM
+asmPlasm 3
lda evalStkL+2,x ; command code
pha
lda evalStkL+1,x ; main or aux
@ -335,30 +222,15 @@ asm loader
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
jmp mainLoader ; ret value in A=lo/Y=hi
+ jmp auxLoader ; ditto
end
///////////////////////////////////////////////////////////////////////////////////////////////////
// Set up the font engine
// Params: pFont
asm initFontEngine
txa
pha
bit setROM
+asmPlasm 1
ldy evalStkL,x ; font engine likes *lo* byte in Y
lda evalStkH,x ; hi byte in X
tax
@ -368,73 +240,7 @@ asm initFontEngine
jsr displayMODE
; Set to normal (non-inverse) text
lda #pNORMAL
jsr drawMODE
pla
tax
bit setLcRW+lcBank2
rts
end
///////////////////////////////////////////////////////////////////////////////////////////////////
// Set up the ray casting engine or tile engine (they share the same address)
// Params: pMap
asm initDisplayEngine
txa
pha
bit setROM
lda evalStkL,x
ldy evalStkH,x
jsr $6000
pla
tax
bit setLcRW+lcBank2
rts
end
///////////////////////////////////////////////////////////////////////////////////////////////////
// Render one frame using the ray caster or tile engine (they share the same address)
// Params: none
asm renderFrame
txa
pha
bit setROM
jsr $6003
pla
tax
dex ; don't-care return value
bit setLcRW+lcBank2
rts
end
///////////////////////////////////////////////////////////////////////////////////////////////////
// Deal with crossing into a new map section
// Params: none
asm checkCrossing
txa
pha
bit setROM
jsr $6006
pla
tax
dex ; don't-care return value
bit setLcRW+lcBank2
rts
end
///////////////////////////////////////////////////////////////////////////////////////////////////
// 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
jmp drawMODE
end
///////////////////////////////////////////////////////////////////////////////////////////////////
@ -457,28 +263,17 @@ end
// Use the font engine to clear the current text window
// Params: None
asm clearWindow
bit setROM
txa
pha
jsr clearWINDOW
bit setLcRW+lcBank2
pla
tax
dex ; don't-care return value
rts
+asmPlasm 0
jmp clearWINDOW
end
///////////////////////////////////////////////////////////////////////////////////////////////////
// Display a string using the font engine. Automatically splits lines to keep words from breaking.
// Params: pStr
asm displayStr
bit setROM
txa
pha
lda evalStkL,x
+asmPlasm 1
sta pTmp
lda evalStkH,x
sta pTmp+1
sty pTmp+1
ldy #0
lda (pTmp),y
beq ++
@ -532,11 +327,7 @@ asm displayStr
+ pla
bne --
++ lda #$d
jsr printCHAR
bit setLcRW+lcBank2
pla
tax
rts
jmp printCHAR
end
///////////////////////////////////////////////////////////////////////////////////////////////////
@ -634,24 +425,11 @@ def getUpperKey()
return key
end
///////////////////////////////////////////////////////////////////////////////////////////////////
// Is the player's current position a physical obstruction?
def isBlocked()
return ^avatarTile & $40
end
///////////////////////////////////////////////////////////////////////////////////////////////////
// Is there a script attached to the player's current position?
def isScripted()
return ^avatarTile & $20
end
///////////////////////////////////////////////////////////////////////////////////////////////////
// Set the sky color (relevant to 3D display only)
def setSky(num)
skyNum = num
setColor(0<<8 | skyGndTbl1[skyNum])
setColor(1<<8 | skyGndTbl2[skyNum])
setColor(0, skyNum)
end
///////////////////////////////////////////////////////////////////////////////////////////////////
@ -664,12 +442,11 @@ end
// Set the ground color (relevant to 3D display only)
def setGround(num)
groundNum = num
setColor(2<<8 | skyGndTbl1[groundNum])
setColor(3<<8 | skyGndTbl2[groundNum])
setColor(1, groundNum)
end
///////////////////////////////////////////////////////////////////////////////////////////////////
// Switch to the next ground color
// Switch to the next ground color (3D only)
def nextGround()
setGround((groundNum + 1) & $F)
end
@ -1131,13 +908,7 @@ end
///////////////////////////////////////////////////////////////////////////////////////////////////
// Load and display the title screen.
def loadTitle()
word v1
word v2
puts("Loading Lawless Legends.\n")
v1 = 1
v2 = 2
fooFunc(@v1, @v2)
printf2("v1=%d v2=%d\n", v1, v2)
// Load the title screen
puts("Loading title screen.\n")

View File

@ -10,17 +10,12 @@ start:
; then routines that call those to build complexity. The main
; code is at the very end.
; jmp initMap ; params: mapNum, x, y, dir
; jmp flipToPage1 ; params: none
; jmp getPos ; params: @x, @y, @dir
; jmp setPos ; params: x (0-255), y (0-255), dir (0-15)
; Old vectors
; jmp initMap
; jmp renderFrame
; jmp isBlocked
; jmp isScripted
; jmp setColor
jmp pl_initMap ; params: pMapData, x, y, dir; return: map name (as C str)
jmp pl_flipToPage1 ; params: none; return: nothing
jmp pl_getPos ; params: @x, @y, @dir; return: nothing
jmp pl_setPos ; params: x (0-255), y (0-255), dir (0-15); return: nothing
jmp pl_advance ; params: none; return: 1 if new pos *and* scripted
jmp pl_setColor ; params: slot (0=sky/1=ground), color (0-15); return: nothing
; Conditional assembly flags
DOUBLE_BUFFER = 1 ; whether to double-buffer
@ -38,32 +33,6 @@ DEBUG_COLUMN = -1
; PLASMA
!source "../include/plasma.i"
; Experimental, possibly unused, code
; Store a single byte number to a pointer on the PLASMA eval stack. Clears hi byte.
; A-reg = offset in PLASMA stack (0=first param, 1=second param, etc.)
; Y-reg = value to store
; (X-reg = PLASMA's stack pointer, unchanged)
setPlasmaVar: !zone {
stx .add+1
sty .val+1
clc
.add adc #0
tay
lda evalStkL,y
sta .sto1+1
sta .sto2+1
lda evalStkH,y
sta .sto1+2
sta .sto2+2
.val lda #0
.sto1 sta $1111
ldy #1
lda #0
.sto2 sta $1111,y
+ rts
}
; Local constants
MAX_SPRITES = 64 ; max # sprites visible at once
NUM_COLS = 63
@ -1707,8 +1676,41 @@ calcMapOrigin: !zone
rts
;-------------------------------------------------------------------------------
; Check if the player's current location is an obstruction block
isBlocked: !zone
; Advance in current direction if not blocked.
; Params: none
; Return 1 if player is on a new block *and* that block has script(s).
pl_advance: !zone
txa
pha ; save PLASMA eval stk pos
bit setROM ; switch out PLASMA while we work
lda playerDir
asl
asl ; shift twice: each dir is 4 bytes in table
tax
; Advance the coordinates based on the direction.
; Along the way, we save each one on the stack for later compare or restore
lda playerX
pha
clc
adc walkDirs,x
sta playerX
lda playerX+1
pha
adc walkDirs+1,x
sta playerX
lda playerY
pha
clc
adc walkDirs+2,x
sta playerY
lda playerY+1
pha
clc
adc walkDirs+3,x
; Check if the new position is blocked
jsr calcMapOrigin
sta pMap
sty pMap+1
@ -1718,8 +1720,48 @@ isBlocked: !zone
beq +
tax
jsr getTileFlags
and #2 ; flag 2 is for obstructions
+ rts
sta tmp+1
and #2 ; tile flag 2 is for obstructions
beq .ok
; Blocked! Restore old position.
pla
sta playerY+1
pla
sta playerY
pla
sta playerX+1
pla
sta playerX
ldy #0
beq .done
.ok ; Not blocked. See if we're in a new map tile.
pla
eor playerY+1
sta tmp
pla
pla
eor playerX+1
ora tmp
tay
pla
tya
beq .done ; if not a new position, return zero
; It is a new position. Is script hint set?
ldy playerX+1
lda (pMap),y
ldy #0
and #$20 ; map flag $20 is the script hint
beq .done ; if not scripted, return zero
iny ; else return 1
.done pla
tax ; restore PLASMA eval stk pos
dex ; make room for return value
tya ; retrieve ret value
sta evalStkL,x ; and store it
lda #0
sta evalStkH,x
bit setLcRW+lcBank2 ; switch PLASMA runtime back in
rts
;-------------------------------------------------------------------------------
; Check if the player's current location has a script flag on it
@ -1844,19 +1886,25 @@ renderFrame: !zone
;-------------------------------------------------------------------------------
; Flip back buffer onto the screen
flip: !zone
pl_flipToPage1: !zone
lda frontBuf
beq +
flip:
!if DOUBLE_BUFFER {
ldx backBuf
ldy backBuf
lda frontBuf
sta backBuf
stx frontBuf
lda page1,x
sty frontBuf
lda page1,y
}
; Hack for real (not emulated) IIc: sometimes displays only lo-bit graphics
; unless we do this. *HUGE* thanks to Brendan Robert for the fix!
sta $C07E ; disable double-hi-res
lda $C05F ; disable double-hi-res
rts
+ rts
;-------------------------------------------------------------------------------
+ jmp flip
;-------------------------------------------------------------------------------
copyScreen: !zone
@ -1877,61 +1925,81 @@ copyScreen: !zone
rts
;-------------------------------------------------------------------------------
setColor: !zone
; Called by PLASMA code to get the position on the map.
; Parameters: @x, @y, @dir
; Returns: Nothing
pl_getPos: !zone {
lda playerDir
jsr .sto
inx
lda playerY+1
jsr .sto
inx
lda playerX+1
; Now fall thru, and exit with X incremented twice (3 params - 1 return slot = 2)
.sto ldy evalStkL,x
sty pTmp
ldy evalStkH,x
sty pTmp+1
ldy #0
sta (pTmp),y
tya
iny
sta (pTmp),y
rts
}
;-------------------------------------------------------------------------------
; Called by PLASMA code to set the position on the map.
; Parameters: x, y, dir
; Returns: Nothing
pl_setPos: !zone {
lda evalStkL,x
and #15
sta playerDir
lda evalStkL+1,x
sta playerY+1
lda evalStkL+2,x
sta playerX+1
lda #$80
sta playerY
sta playerX
rts
}
;-------------------------------------------------------------------------------
pl_setColor: !zone
lda evalStkL,x ; color number
tay
lda skyGndTbl2,y
pha
lda skyGndTbl1,y
pha
lda evalStkH,x ; slot
and #1
asl
tay
pla
sta skyColorEven,y
pla
sta skyColorOdd,y
inx ; toss unused stack slot (parms=2, ret=1, diff=1)
rts
;-------------------------------------------------------------------------------
; Set the window for the top (map name) bar
set_window1: !zone
lda #1
sta wndtop
sta cursv
lda #2
sta wndbtm
lda #4
sta wndleft
sta cursh
lda #18
sta wndwdth
rts
;-------------------------------------------------------------------------------
; Set the window for the large upper right bar
set_window2: !zone
lda #3
sta wndtop
sta cursv
lda #17
sta wndbtm
lda #23
sta wndleft
sta cursh
lda #37
sta wndwdth
rts
;-------------------------------------------------------------------------------
; Set the window for the smaller lower right bar
set_window3: !zone
lda #18
sta wndtop
sta cursv
lda #23
sta wndbtm
lda #23
sta wndleft
sta cursh
lda #37
sta wndwdth
rts
;-------------------------------------------------------------------------------
; The real action
initMap: !zone
pl_initMap: !zone
txa
pha ; save PLASMA's eval stack pos
; Record the address of the map
lda evalStkL+3,x
sta mapHeader
sty mapHeader+1
lda evalStkH+3,x
sta mapHeader+1
; Record player X, Y and dir
jsr pl_setPos
; Proceed with loading
bit setROM ; switch out PLASMA while we work
jsr loadTextures
jsr copyScreen
lda tablesInitted
@ -1947,34 +2015,17 @@ initMap: !zone
jsr setExpansionCaller
jsr graphInit
bit clrMixed
; Display the name of the map in the upper left box.
jsr set_window1
jsr clearWINDOW
lda wndwdth
sec
sbc wndleft
sbc mapNameLen
lsr
clc
adc wndleft
bpl +
lda #0
+ tax
ldy wndtop
jsr tabXY
ldy mapName ; now display the name itself
ldx mapName+1
jsr printCSTR
; play characters in the little window on the bottom right
jsr set_window3
jsr clearWINDOW
jsr printSCSTR
!raw "Name Am/Li",13
!raw "-------- --/--",13
!raw "Dead Eye 07/21",13
!raw "Cliff H. 10/36",13
!raw "Prospect 13/24"
!byte 0
; Return the map name (as a C str)
bit setLcRW+lcBank2 ; switch PLASMA runtime back in
pla ; restore PLASMA's eval stk pos
tax
inx
inx ; toss 3 slots (params=4, ret=1, diff=3)
inx
lda mapName
sta evalStkL,x ; return map name to PLASMA caller
lda mapName+1
sta evalStkH,x
rts
; Following are log/pow lookup tables. For speed, align them on a page boundary.
@ -3117,3 +3168,58 @@ mapSpriteH !fill MAX_SPRITES
sinTbl !word $0000, $8699, $877F, $87E1, $8800, $87E1, $877F, $8699
!word $8195, $0699, $077F, $07E1, $0800, $07E1, $077F, $0699
; Dithering patterns for sky and ground, encoded specially for this engine. 16 different combinations.
skyGndTbl1:
!byte $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
skyGndTbl2:
!byte $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
; Movement amounts when walking at each angle
; Each entry consists of an X bump and a Y bump, in 8.8 fixed point
walkDirs !word $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