Lots of work on automap marks.

This commit is contained in:
Martin Haye 2018-04-16 05:35:40 -07:00
parent df61fb6baa
commit f4062d506a
10 changed files with 221 additions and 31 deletions

View File

@ -3641,6 +3641,7 @@ end
outStream.write((byte)(size+2)) // +2 so it includes the header
(1..size).each { outStream.write( (byte) 0) }
}
// no end-of-marks yet, to avoid terminator between 2d and 3d
}
def copyOrCreateSave(dstDir)

View File

@ -185,13 +185,19 @@ _writeMarks: !zone
ldy #0
sty ldrlo
ldx #2 ; length 2
sty ldrlo
lda #cmdread
sec ; rdwrpart
jsr callProRWTS
; Read the existing marks data
lda #2
sta ldrlo
lda #$40
sta ldrhi
ldx $4000
ldy $4001
lda #cmdread
jsr .rw
sec
jsr callProRWTS
; Begin scan
lda #2
sta pTmp
@ -228,18 +234,23 @@ _writeMarks: !zone
- sta rwts_mark,x
dex
bpl -
ldx #2 ; seek to start of marks on disk: offset $1202
ldx #0 ; seek to start of marks on disk: offset $1200
ldy #$12
lda #cmdseek
sec ; rdwrpart
jsr callProRWTS
lda #cmdwrite ; write new marks
.rw ldx #2 ; marks at $4002
ldx #0 ; starting from $4000
stx ldrlo
ldx #$40
stx ldrhi
ldx $4000 ; length of marks
lda #$40
sta ldrhi
ldy $4001
lda $4000
clc
adc #2 ; length of marks plus header
bcc +
iny
+ tax
lda #cmdwrite ; write new marks
sec
; fall through to final ProRWTS command
callProRWTS:

View File

@ -28,6 +28,7 @@ struc TMapSection
byte bm_tilesetNum
word pm_tileset
byte bm_visible
byte bm_needMarks
word wm_x0 // upper-left coord of map in global space
word wm_y0
word wm_x1 // bottom-right coord of map (exclusive) in global space
@ -55,6 +56,7 @@ word screenX0, screenY0, screenX1, screenY1
byte nHorzSects
byte sectionBuf[SECT_BUF_SIZE]
word pLastSection
word pAllMarks
///////////////////////////////////////////////////////////////////////////////////////////////////
// Definitions used by assembly code
@ -64,6 +66,7 @@ asm _defs
!source "../../include/plasma.i"
!source "../../include/mem.i"
!source "../../include/fontEngine.i"
!source "../../include/marks.i"
tmp = $2 ; length 2
pTmp = $4 ; length 2
tilePtrs = $6 ; length 2
@ -291,6 +294,9 @@ asm fillRow(mapRowData, mask, tileTrans, pSmallTiles, blankTile, width, tilePtrs
lda (pSrc),y ; get raw data
iny
sty .srcOff
asl
bpl .blank ; skip unless $40 bit is set denoting this space has been seen
lsr
and .param_mask,x ; mask to get just tile number
beq .blank
tay
@ -342,6 +348,149 @@ asm fillRow(mapRowData, mask, tileTrans, pSmallTiles, blankTile, width, tilePtrs
rts
end
///////////////////////////////////////////////////////////////////////////////////////////////////
asm writeMarks()#0
!zone
+asmPlasmNoRet 0
sei
sta setAuxZP
bit setLcRW+lcBank1
jsr writeMarks
bit setLcRW+lcBank2
sta clrAuxZP
cli
rts
end
///////////////////////////////////////////////////////////////////////////////////////////////////
asm mergeMarks(allMarks, mapNum, mapData, width, stride, height)#0
!zone {
+asmPlasmNoRet 6
.param_allMarks = evalStkL+5
.param_mapNum = evalStkL+4
.param_mapData = evalStkL+3
.param_width = evalStkL+2
.param_stride = evalStkL+1
.param_height = evalStkL+0
.byteCt = pTmp
.bitCt = pTmp+1
; First, set up a routine in zero page to read a byte from aux mem
.jsr
jsr fixedRTS
stx ysav
tsx
dex
lda $100,x
clc
adc #.rdaux-.jsr-2
sta pTmp
lda $101,x
adc #0
sta pTmp+1
ldy #12
- lda (pTmp),y
sta $10,y
dey
bpl -
bmi .go ; always taken - skip over the routine we just copied
.rdaux
sei ; prevent interrupts while in aux mem
sta setAuxRd
lda (pSrc),y
iny
sta clrAuxRd
cli
rts
.go
ldx ysav
lda .param_allMarks,x
sta pSrc
lda .param_allMarks+evalStkH-evalStkL,x
sta pSrc+1
.scan
ldy #0
jsr $10 ; read map num
+prA
+prWord pSrc
cmp .param_mapNum,x
beq .found
cmp #0
bne +
+prChr 'M'
brk ; not found!!?
+ jsr $10 ; read size
clc
adc pSrc
sta pSrc
bcc .scan
inc pSrc+1
bne .scan ; always taken
.found
lda .param_mapData,x
sta pDst
lda .param_mapData+evalStkH-evalStkL,x
sta pDst+1
iny ; skip over size byte
; Process a row of data
.row
lda .param_width,x
sta .byteCt
lda #0
sta .bitCt
; Process one byte (column) in the row
.column
dec .bitCt
bpl +
jsr $10
sta tmp
lda #7
sta .bitCt
+ lsr tmp
bcc .nextcol
ldx #0
lda (pDst,x)
ora #$40
sta (pDst,x)
.nextcol
inc pDst
bne +
inc pDst+1
+ dec .byteCt
bne .column
.nextrow
ldx ysav
lda .param_stride,x
sec
sbc .param_width,x
clc
adc pDst
sta pDst
bcc +
inc pDst+1
+ dec .param_height,x
bne .row
rts
} ; end of zone
end
///////////////////////////////////////////////////////////////////////////////////////////////////
def loadMarks()#0
word len
// First, call the automark write routine. This has not only the effect of flushing the marks
// to disk, but also leaving them loaded for us at $4000 (main).
writeMarks
// Copy the marks to aux, where they'll be safe from memory manager operations
len = *$4000
pAllMarks = auxMmgr(REQUEST_MEMORY, len)
memcpy($4002, pAllMarks, len, 1)
end
///////////////////////////////////////////////////////////////////////////////////////////////////
def displayRow3D(pScreen, mapRowData, tileTrans, pSmallTiles, width)#0
fillRow(mapRowData, $1F, tileTrans, pSmallTiles, @blankTile, width, @tilePtrs)
@ -359,6 +508,7 @@ def make3DSection(pSection)#0
// Record the map data (it's already loaded for 3D display)
pSection->bm_mapNum = mapNum
pSection=>pm_map = pCurMap
pSection->bm_needMarks = TRUE
// Record the tile set number
pSection->bm_tilesetNum = ^(pSection=>pm_map + 3)
@ -376,6 +526,7 @@ def make2DSection(pSection, sh, sv)#0
// Record the map data (the top-left segment is already loaded)
pSection->bm_mapNum = mapNum + (sv*nHorzSects) + sh
pSection=>pm_map = (pSection->bm_mapNum == mapNum) ?? pCurMap :: NULL
pSection->bm_needMarks = TRUE
// Tileset will be calculated later
pSection->bm_tilesetNum = 0
@ -465,6 +616,7 @@ def freeSections#0
if pSection=>pm_map and pSection=>pm_map <> pCurMap
mmgr(FREE_MEMORY, pSection=>pm_map)
pSection=>pm_map = NULL
pSection->bm_needMarks = TRUE
fin
if pSection=>pm_tileset
mmgr(FREE_MEMORY, pSection=>pm_tileset)
@ -491,8 +643,15 @@ def displaySection3D(pSection)#0
loop
mapData = tileTrans + (nTextures*3) + 2 // *2 for tilenum+texnum, *1 for texture flags, 2 for zero-terms
// The +1's below are to skip over the sentinel row and column that 3D maps have
rowData = mapData + ((pSection->bm_oy + 1) * rowSize) + pSection->bm_ox + 1
// Merge automap marks into the data if not done yet
rowData = mapData + rowSize + 1 // skip sentinel row and column that 3D maps have
if pSection->bm_needMarks
// allMarks mapNum mapData width stride height
mergeMarks(pAllMarks, pSection->bm_mapNum | $80, rowData, rowSize-2, rowSize, ^(pSection=>pm_map+1)-2)
pSection->bm_needMarks = FALSE
fin
rowData = rowData + (pSection->bm_oy * rowSize) + pSection->bm_ox
// The << 3 below is because each row is 8 screen lines
line = (pSection->bm_sy << 3) + MAP_TOP
lx = MAP_LEFT + pSection->bm_sx
@ -508,14 +667,21 @@ end
///////////////////////////////////////////////////////////////////////////////////////////////////
def displaySection2D(pSection)#0
word pSmallTiles, rowData
byte y, rowSize, line, lx
byte y, line, lx
// Figure out where the small tiles reside (at the end of the full size tiles)
pSmallTiles = pSection=>pm_tileset + 1 + ((^(pSection=>pm_tileset)) << 5)
// The +6 below is to skip over the 2D map's header
rowData = pSection=>pm_map + 6 + (pSection->bm_oy * SECTION_WIDTH_2D) + pSection->bm_ox
// The << 3 below is because each row is 8 screen lines
// Merge automap marks into the data if not done yet
rowData = pSection=>pm_map + 6 // header = 6 bytes
if pSection->bm_needMarks
// allMarks mapNum mapData width stride height
mergeMarks(pAllMarks, pSection->bm_mapNum, rowData, SECTION_WIDTH_2D, SECTION_WIDTH_2D, SECTION_HEIGHT_2D)
pSection->bm_needMarks = FALSE
fin
rowData = rowData + (pSection->bm_oy * SECTION_WIDTH_2D) + pSection->bm_ox
// The << 3 below is because each row is 8 screen lines
line = (pSection->bm_sy << 3) + MAP_TOP
lx = MAP_LEFT + pSection->bm_sx
@ -710,6 +876,7 @@ def _automap_show()#1
showTitle
centerScreen
loadMarks
prepSections(0,0)
displaySections
@ -747,6 +914,8 @@ def _automap_show()#1
break
wend
until key == 27 or key == 'Q' or key == '-' // esc or Q or - to exit
auxMmgr(FREE_MEMORY, pAllMarks)
return 0
end

View File

@ -211,8 +211,8 @@ def _startup()#1
mmgr(FINISH_LOAD, 0)
// Relocate font engine and font data to their final spots up in the language card
memcpy(pEngine, fontEngine, fontEngineLen)
memcpy(pFont, fontData, fontDataLen)
memcpy(pEngine, fontEngine, fontEngineLen, 0)
memcpy(pFont, fontData, fontDataLen, 0)
// Tell the font engine where to find its font
setFont(fontData)
@ -287,7 +287,7 @@ def _saveGame()#1
heapCollect()
// Copy data to main memory, and write it out.
memcpy(HEAP_BOTTOM, LOAD_SAVE_BUF, HEAP_SIZE) // LC to low mem
memcpy(HEAP_BOTTOM, LOAD_SAVE_BUF, HEAP_SIZE, 0) // LC to low mem
_rwGame(RWTS_WRITE)
return 0
end
@ -306,7 +306,7 @@ def loadInternal()#1
elsif p_loaded=>w_heapSize < 100 or p_loaded=>w_heapSize > HEAP_SIZE or p_loaded=>w_typeHash <> typeHash
fatal("Incompatible game file.")
fin
memcpy(LOAD_SAVE_BUF, HEAP_BOTTOM, HEAP_SIZE) // low mem to LC
memcpy(LOAD_SAVE_BUF, HEAP_BOTTOM, HEAP_SIZE, 0) // low mem to LC
initHeap(p_loaded=>w_heapSize)
heapCollect() // make sure heap is valid, and record final size
return TRUE

View File

@ -73,7 +73,7 @@ import gamelib
predef lookupResourcePart(sectionNum, resourceNum)#1
predef makeModifier(name, value)#1
predef max(a, b)#1
predef memcpy(pSrc, pDst, len)#0
predef memcpy(pSrc, pDst, len, auxWr)#0
predef memset(pDst, val, len)#0
predef min(a, b)#1
predef mmgr(cmd, wordParam)#1

View File

@ -302,19 +302,22 @@ end
///////////////////////////////////////////////////////////////////////////////////////////////////
// Memory copy - Non-overlapping regions only!
export asm memcpy(pSrc, pDst, len)#0
+asmPlasmNoRet 3
lda evalStkL+2,x ; source ptr
export asm memcpy(pSrc, pDst, len, auxWr)#0
+asmPlasmNoRet 4
lda evalStkL+3,x ; source ptr
sta tmp
lda evalStkH+2,x
lda evalStkH+3,x
sta tmp+1
lda evalStkL+1,x ; dest ptr
lda evalStkL+2,x ; dest ptr
sta pTmp
lda evalStkH+1,x
lda evalStkH+2,x
sta pTmp+1
lda evalStkH,x ; len hi
ldy evalStkL,x ; auxWr
sei ; prevent interrupts while possibly in aux
sta clrAuxWr,y
lda evalStkH+1,x ; len hi
pha
lda evalStkL,x ; len lo
lda evalStkL+1,x ; len lo
tax
ldy #0
.pglup:
@ -339,6 +342,8 @@ export asm memcpy(pSrc, pDst, len)#0
dex
bne -
.done
sta clrAuxWr
cli ; inerrupts ok now that we're back in main
rts
end
@ -548,7 +553,7 @@ export asm finishString(isPlural)#1
dey ; undo copy of the paren
stx tmp+1 ; save position in input
dex ; needed for failsafe operation
lda tmp ; set copy flag (V) initially
bit tmp ; set copy flag (V) initially
bne .findsl ; to same as isPlural flag
clv
.findsl ; see if there's a slash within the parens
@ -2691,7 +2696,7 @@ export def setScriptInfo(mapName, moduleNum, timeFn, trigTbl, wdt, hgt)#0
// Record new script, and prepare to free old one. While theoretically there could be a
// circumstance where the old prev is still un-freed, it's rare enough that it'd be hard to
// get freeing it here correct. So we leave freeing to the main keyboard loop.
// test freeing it here correctly. So we leave freeing to the main keyboard loop.
if scriptModule <> moduleNum
prevScriptModule = scriptModule
scriptModule = moduleNum

View File

@ -120,7 +120,7 @@ def showPos()#1
printf3("Facing=%d Sky=%d Ground=%d", getDir(), skyNum, groundNum)
fin
puts("\nHit any key.\n")
getUpperKey()
rdkey()
^$c052
return 0
end

View File

@ -497,7 +497,7 @@ def doSplit(player, item)#1
if nToSplit >= 1 and nToSplit <= item=>w_count-1
item=>w_count = item=>w_count - nToSplit
newItem = mmgr(HEAP_ALLOC, TYPE_FANCY_ITEM)
memcpy(item, newItem, TFancyItem)
memcpy(item, newItem, TFancyItem, 0)
newItem=>w_count = nToSplit
newItem=>p_nextObj = item=>p_nextObj
item=>p_nextObj = newItem

View File

@ -1751,6 +1751,7 @@ pl_texControl: !zone {
cpx nTextures
bne -
; This is also our signal to save the automap bits
sei
ldx mapWidth
ldy mapHeight
lda mapBase
@ -1773,6 +1774,7 @@ pl_texControl: !zone {
jsr saveMarks
bit setLcRW+lcBank2
sta clrAuxZP
cli
rts
}

View File

@ -190,6 +190,7 @@ LOAD_SECTION
;----------------------------------------------------------------------
SAVE_MARKS
SEI ; prevent interrupts while in aux
STA setAuxZP
STA X_COUNTER ; temporarily save map num
TXA ; map pointer lo
@ -208,6 +209,7 @@ SAVE_MARKS
JSR saveMarks
BIT setLcRW+lcBank2
STA clrAuxZP
CLI ; interrupts ok now that we're back to main
RTS
;----------------------------------------------------------------------