Automap mark saving working for 3D maps.

This commit is contained in:
Martin Haye 2018-04-05 08:30:04 -07:00
parent 94f5ab3a7e
commit 0248c70646
6 changed files with 249 additions and 88 deletions

View File

@ -58,7 +58,7 @@ class A2PackPartitions
static final int FLOPPY_SIZE = 35*8 // good old 140k floppy = 280 blks
static final int AC_KLUDGE = 2 // minus 1 to work around last-block bug in AppleCommander
static final int DOS_OVERHEAD = 3 // only 3 blks overhead! ProRWTS is so freaking amazing.
static final int SAVE_GAME_SIZE = 10 // 9 blocks data, 1 block index
static final int SAVE_GAME_BYTES = 0x1200
static final int MAX_DISKS = 20 // for now this should be way more than enough
def typeNumToDisplayName = [1: "Code",
@ -103,8 +103,8 @@ class A2PackPartitions
def mapNames = [:] // map name (and short name also) to map.2dor3d, map.num
def sysCode = [:] // memory manager
def code = [:] // code name to code.num, code.buf
def maps2D = [:] // map name to map.num, map.buf
def maps3D = [:] // map name to map.num, map.buf
def maps2D = [:] // map name to map.num, map.buf, map.order, map.width, map.height
def maps3D = [:] // map name to map.num, map.buf, map.order, map.width, map.height
def tiles = [:] // tile id to tile.buf
def smTiles = [:] // tile id to small-size tile.buf
def tileSets = [:] // tileset name to tileset.num, tileset.buf
@ -713,7 +713,7 @@ class A2PackPartitions
sectionNums[vsect][hsect] = num
def sectName = "$mapName-$hsect-$vsect"
addResourceDep("map", mapName, "map2D", sectName)
maps2D[sectName] = [num:num, order:mapEl.@order, buf:buf]
maps2D[sectName] = [num:num, order:mapEl.@order, buf:buf, width: TILES_PER_ROW, height: ROWS_PER_SECTION]
}
}
@ -1153,7 +1153,8 @@ class A2PackPartitions
def (scriptModule, locationsWithTriggers) = packScripts(mapEl, name, rows[0].size(), rows.size())
def buf = ByteBuffer.allocate(50000)
write3DMap(buf, name, rows, scriptModule, locationsWithTriggers)
maps3D[name] = [num:num, order:mapEl.@order, buf:compress(unwrapByteBuffer(buf))]
maps3D[name] = [num:num, order:mapEl.@order, buf:compress(unwrapByteBuffer(buf)),
width:rows[0].size(), height:rows.size()]
allMaps << [name:name, order:parseOrder(mapEl.@order)]
}
}
@ -1920,7 +1921,7 @@ class A2PackPartitions
//println "LEGENDOS blks=$coreBlks"
availBlks -= coreBlks
// Disk 1 also holds the save game file
availBlks -= SAVE_GAME_SIZE
availBlks -= calcSaveGameBlks()
}
def (chunks, spaceUsed) = fillDisk(partNum, availBlks, mapsTodo, mapsToDupe)
@ -3617,6 +3618,31 @@ end
}
}
def calcAutomapMarksSize() {
int size = 0
maps2D.each { k,v -> size += 2 + ((v.width+7)>>3)*(v.height) } // 2 = mapNum+len header
maps3D.each { k,v -> size += 2 + ((v.width+7)>>3)*(v.height) } // 2 = mapNum+len header
size += 1 // end of marks
return size
}
def calcSaveGameBlks() {
def size = SAVE_GAME_BYTES
size += 2 // header for size-of-marks
size += calcAutomapMarksSize()
return ((size+511)>>9) + 1
}
def writeEmptyMarks(outStream, maps, flag) {
maps.each { k, v ->
outStream.write((byte)(v.num | flag))
def size = ((v.width + 7) >> 3) * v.height
assert size > 0 && size < 255
outStream.write((byte)(size+2)) // +2 so it includes the header
(1..size).each { outStream.write( (byte) 0) }
}
}
def copyOrCreateSave(dstDir)
{
def prevSave = new File("build/prevGame/game.1.save.bin#0")
@ -3627,9 +3653,19 @@ end
else {
// Create empty save file
newSave.withOutputStream { outStream ->
(0..(18*256 - 1)).each {
outStream.write( (byte) 0)
}
// First, a big block for copying the small-object heap
(1..SAVE_GAME_BYTES).each { outStream.write( (byte) 0) }
// Followed by empty automap marks
// Header: size of remaining marks data
int marksSize = calcAutomapMarksSize()
outStream.write((byte)(marksSize & 0xFF))
outStream.write((byte)((marksSize >> 8) & 0xFF))
// Then empty marks for each map
writeEmptyMarks(outStream, maps2D, 0)
writeEmptyMarks(outStream, maps3D, 0x80)
// And a terminator
outStream.write((byte)0)
}
}
}

View File

@ -30,7 +30,8 @@ MAX_SEGS = 96
DEBUG = 0
SANITY_CHECK = 0 ; also prints out request data
; Zero page temporary variables
; Zero page temporary variables.
; Don't move these - they overlap in clever ways with ProRWTS shadows (see below)
tmp = $2 ; len 2
pTmp = $4 ; len 2
reqLen = $6 ; len 2

View File

@ -78,8 +78,8 @@
; 0D7B.9xxx (free, managed)
; A0xx.BFFF gameloop PLASMA code (loaded as high as possible)
; C000.CFFF I/O
; (bank 1) D000.DAFF ProRWTS runtime
; (bank 1) DB00.DFFF (unused)
; (bank 1) D000.DAFF ProRWTS runtime and buffers
; (bank 1) DB00.DFFF automap mark queueing code and buffer
; (bank 2) D000.DFFF texture expander part 2
; E000.FFF9 texture expander part 3
; FFFA.FFFF 6502 vectors

View File

@ -0,0 +1,31 @@
;****************************************************************************************
; Copyright (C) 2015 The 8-Bit Bunch. Licensed under the Apache License, Version 1.1
; (the "License"); you may not use this file except in compliance with the License.
; You may obtain a copy of the License at <http://www.apache.org/licenses/LICENSE-1.1>.
; Unless required by applicable law or agreed to in writing, software distributed under
; the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
; ANY KIND, either express or implied. See the License for the specific language
; governing permissions and limitations under the License.
;****************************************************************************************
; ProRWTS equates
proRWTS = $D000 ;over in aux LC (in bank 1 just like mem mgr)
status = $3 ;returns non-zero on error
auxreq = $a ;set to 1 to read/write aux memory, else main memory is used
sizelo = $6 ;set if enable_write=1 and writing, or reading, or if enable_seek=1 and seeking
sizehi = $7 ;set if enable_write=1 and writing, or reading, or if enable_seek=1 and seeking
reqcmd = $2 ;set (read/write/seek) if enable_write=1 or enable_seek=1
;if allow_multi=1, bit 7 selects floppy drive in current slot
; (clear=drive 1, set=drive 2) during open call
;bit 7 must be clear for read/write/seek on opened file
ldrlo = $E ;set to load address if override_adr=1
ldrhi = $F ;set to load address if override_adr=1
namlo = $C ;name of file to access
namhi = $D ;name of file to access
rwts_mark = $18 ;to reset seek ptr, zero out 4 bytes here
cmdseek = 0 ;requires enable_seek=1
cmdread = 1 ;requires enable_write=1
cmdwrite = 2 ;requires enable_write=1

View File

@ -13,8 +13,16 @@
; Use hi-bit ASCII for Apple II
!convtab "../include/hiBitAscii.ct"
; Other equates
!source "../include/prorwts.i"
target = $3 ; len 1
tmp = $4 ; len 2
pTmp = $6 ; len 2
pTmp = $6 ; len 2
pBuf = $8 ; len 2
; free: $9-$F (but used by prorwts)
retAddr = $10 ; len 2
width = $12 ; len 1
jmp saveMarks
@ -25,69 +33,54 @@ pTmp = $6 ; len 2
; TOS-1 = ...and hi byte
; TOS = map number (with hi bit set if 3D)
saveMarks: !zone
.lineCt = tmp+1
sta .adStrd+1
stx .cmpWd+1
sty lineCt
stx width
sty .lineCt
pla
sta retAddr
pla
sta retAddr+1
.rescan lda width ; need to reload (not just txa) in case rescanning after write
clc
adc #1
sta .ret+1
pla
adc #0
sta .ret+2
txa
adc #7 ; carry already clear from above
adc #7
lsr
lsr
lsr
sta .addBSz+1
sta tmp ; number of bytes per row
lda #0
- clc
.addBSz adc #11 ; self-modified above
dey ; multiply height * size-of-encoded-row
bne .addBSz ; Y=0 at end of loop (used below)
tax ; X is now the total # of encoded bytes
inx
inx ; plus header size
lda #<bufStart
sta pTmp
lda #>bufStart
sta pTmp+1
.scan pla
pha
cmp (pTmp),y
beq .found
lda (pTmp),y
beq .notfnd
iny
lda (pTmp),y
dey
clc
adc pTmp
sta pTmp
bcc .scan
inc pTmp+1
bne .scan ; always taken
- adc tmp
dey ; multiply height * bytes-per-row
bne - ; Y=0 at end of loop (used below)
tax ; X is # of encoded bytes...
inx
inx ; ...plus header size (2 bytes)
pla ; map number to look for
pha ; but keep on stack in case of rescanning or not found
jsr scan
bcs .found
.notfnd pla
sta (pTmp),y
.notfnd pla ; map number
sta (pBuf),y
iny
txa
sta (pTmp),y
txa ; get back record length
sta (pBuf),y
tay ; save offset for end-of-buffer marking
clc
adc pTmp
adc pBuf
bcc +
lda pTmp+1
lda pBuf+1
cmp #>(bufEnd-256)
bcs .full
+ lda #0 ; end-of-buffer mark, and also mask
sta (pTmp),y ; mark new end of buffer
beq .go
sta (pBuf),y ; mark new end of buffer
beq .go ; always taken
.found pla
.full jsr writeMarks ; write out existing marks and reset buffer
jmp .rescan
.found pla ; done with map number - discard it
lda #$FF
.go sta .mask1+1
sta .mask2+1
@ -106,24 +99,24 @@ saveMarks: !zone
asl ; shift $40 bit (automap) into carry
ror tmp ; save the bit
bcc +
lda (pTmp),y
lda (pBuf),y
.mask1 and #11 ; self-modified above
ora tmp
sta (pTmp),y
sta (pBuf),y
iny
lda #$80 ; restore sentinel
sta tmp
+ inx
.cmpWd cpx #11 ; check width (self-modified above)
cpx width
bne .get ; loop until row width is complete
lda tmp
bmi + ; skip final store if no bits
- lsr tmp ; low-align last set of bits in row
bcc -
lda (pTmp),y
lda (pBuf),y
.mask2 and #11 ; self-modified above
ora tmp
sta (pTmp),y
sta (pBuf),y
iny
+ lda .get+1
clc
@ -131,12 +124,131 @@ saveMarks: !zone
sta .get+1
bcc +
inc .get+2
+ dec lineCt
+ dec .lineCt
bne .nxtrow
.ret jmp $1111 ; self-modified above
.full brk ; TODO
jsr writeMarks ; for testing only
.ret lda retAddr+1
pha
lda retAddr
pha
rts
lineCt !byte 0
; Scan the buffer for A-reg as target map
; Advances pBuf through the buffer
; If a match is found, SEC, and pBuf points to the matching record
; Else, CLC and pBuf points to the buffer terminator
; In any case, Y=0 on exit
scan: !zone
sta target
lda #<bufStart
sta pBuf
lda #>bufStart
sta pBuf+1
- ldy #0
lda (pBuf),y
clc
beq + ; if end of buffer, Z=1 and C=0
cmp target
beq + ; if match, Z=1 and C=1
iny
lda (pBuf),y
adc pBuf
sta pBuf
bcc -
inc pBuf+1
bcs - ; always taken
+ rts
writeMarks: !zone
; First, open the file and seek to offset $1200
lda #<filename
sta namlo
lda #>filename
sta namhi
ldx #0
stx auxreq
ldy #$12
txa ; 0=cmdseek
clc ; opendir
jsr callProRWTS
; Read the length of the marks data
ldx #$40 ; read to $4000
stx ldrhi
ldy #0
sty ldrlo
ldx #2 ; length 2
sty ldrlo
lda #cmdread
sec ; rdwrpart
jsr callProRWTS
; Read the existing marks data
lda #cmdread
jsr .rw
; Begin scan
lda #2
sta pTmp
lda #$40
sta pTmp+1
.outer ldy #0
lda (pTmp),y
beq .end
jsr scan
iny
lda (pTmp),y ; need length in any case
bcc .next ; if no match, skip this record
pha ; save record length
cmp (pBuf),y ; sanity check
beq +
brk ; bad: length mismatch
+ tax
- iny
lda (pTmp),y
ora (pBuf),y ; merge the mark bits
sta (pTmp),y
dex
bne -
pla ; retrieve record length
clc
.next adc pTmp
sta pTmp
bcc .outer
inc pTmp+1
bne .outer ; always taken
.end lda #0
sta bufStart ; clear buffer of marks
ldx #3 ; reseek
- sta rwts_mark,x
dex
bpl -
ldx #2 ; seek to start of marks on disk: offset $1202
ldy #$12
lda #cmdseek
sec ; rdwrpart
jsr callProRWTS
lda #cmdwrite ; write new marks
.rw ldx #2 ; marks at $4002
stx ldrlo
ldx #$40
stx ldrhi
ldx $4000 ; length of marks
ldy $4001
sec
; fall through to final ProRWTS command
callProRWTS:
stx sizelo
sty sizehi
sta reqcmd
bcc +
jmp proRWTS ; rdwrpart; note: prorwts does not set status, so don't check it.
+ jsr proRWTS+3 ; opendir; status is updated
lda status
bne .err
rts
.err brk
filename
!byte 11 ; string len
!raw "GAME.1.SAVE" ; 'raw' chars to get lo-bit ascii that ProDOS likes.
bufStart = *
!byte 0

View File

@ -60,6 +60,7 @@ asm __defs
!source "../../include/plasma.i"
!source "../../include/mem.i"
!source "../../include/fontEngine.i"
!source "../../include/prorwts.i"
; Optional debug printing support
DEBUG = 0
@ -68,26 +69,6 @@ DEBUG = 0
tmp = $2
pTmp = $4
; ProRWTS equates
proRWTS = $D000 ;over in aux LC (in bank 1 just like mem mgr)
status = $3 ;returns non-zero on error
auxreq = $a ;set to 1 to read/write aux memory, else main memory is used
sizelo = $6 ;set if enable_write=1 and writing, or reading, or if enable_seek=1 and seeking
sizehi = $7 ;set if enable_write=1 and writing, or reading, or if enable_seek=1 and seeking
reqcmd = $2 ;set (read/write/seek) if enable_write=1 or enable_seek=1
;if allow_multi=1, bit 7 selects floppy drive in current slot
; (clear=drive 1, set=drive 2) during open call
;bit 7 must be clear for read/write/seek on opened file
ldrlo = $E ;set to load address if override_adr=1
ldrhi = $F ;set to load address if override_adr=1
namlo = $C ;name of file to access
namhi = $D ;name of file to access
cmdseek = 0 ;requires enable_seek=1
cmdread = 1 ;requires enable_write=1
cmdwrite = 2 ;requires enable_write=1
; Yes, needs to be adjusted 3 places.
expandVec = $800