Making progress on display of automap specials.

This commit is contained in:
Martin Haye 2018-05-06 09:25:42 -07:00
parent f49a34434d
commit 7ffc63db8e
5 changed files with 245 additions and 89 deletions

View File

@ -392,7 +392,7 @@ class A2PackPartitions
/*
* Parse raw tile image data and return it as a two buffers: fullsize mainBuf,
* and reduced size smBuf
* and reduced size smBuf (for automap display)
*/
def parseTileData(imgEl)
{
@ -1027,6 +1027,7 @@ class A2PackPartitions
def numberGlobalTiles(dataIn)
{
def tileNum = 0
def amapTnum = 0
dataIn.tile.sort{(it.@category + it.@name).toLowerCase()}.each { tile ->
def lname = tile.@name.toLowerCase().trim().replaceAll(/\s*-\s*[23][dD]\s*/, "")
def cat = tile.@category.toLowerCase().trim()
@ -1043,7 +1044,7 @@ class A2PackPartitions
{
def setNum = tileSets.size() + 1
assert setNum == 1 : "Special tile set must be first."
def setName = "tileSet_special"
def setName = "tileSet_global"
def tileIds = [] as Set
def tileMap = [:]
def buf = ByteBuffer.allocate(50000)
@ -1064,6 +1065,37 @@ class A2PackPartitions
}
tileSets[setName] = [num:setNum, mainBuf:buf, smBuf:ByteBuffer.allocate(1), tileMap:tileMap, tileIds:tileIds]
addResourceDep("map", "<root>", "tileSet", "tileSet_global")
return [setNum, tileMap]
}
/** Pack tiles for special automap places into their own tile set. */
def packAutomapTileSet(dataIn)
{
def setNum = tileSets.size() + 1
assert setNum == 2 : "Automap tile set must be first."
def setName = "tileSet_automap"
def tileIds = [] as Set
def tileMap = [:]
def buf = ByteBuffer.allocate(50000)
// Add each automap tile to the set
dataIn.tile.sort{(it.@category + it.@name).toLowerCase()}.each { tile ->
def name = tile.@name
def id = tile.@id
def data = tiles[id]
def cat = tile.@category.toLowerCase().trim()
if (cat == "automap") {
def num = tileMap.size()
tileIds.add(id)
tileMap[id] = num
data.flip() // crazy stuff to append one buffer to another
buf.put(data)
}
}
tileSets[setName] = [num:setNum, mainBuf:buf, smBuf:ByteBuffer.allocate(1), tileMap:tileMap, tileIds:tileIds]
addResourceDep("map", "<root>", "tileSet", "tileSet_automap")
return [setNum, tileMap]
}
@ -1120,7 +1152,6 @@ class A2PackPartitions
}
addMapDep("tileSet", "tileSet${setNum}")
addMapDep("tileSet", "tileSet_special") // each map requires the global tileset as well
// Start by assuming we'll create a new tileset
def tileMap = tileSet.tileMap
@ -2406,39 +2437,39 @@ class A2PackPartitions
automapSpecials.sort().each { mapNum, y, x, tileNum ->
if (mapNum != prevMapNum) {
if (prevY > 0) {
out.println(" !byte 0 ; end of y=$prevY")
out.println(" !byte \$FF ; end of y=$prevY")
out.println("+")
}
if (prevMapNum) {
out.println(" !byte 0 ; end of data for map $prevMapNum")
out.println(" !byte \$FF ; end of data for map $prevMapNum")
out.println("++")
}
out.println("")
out.println(" !byte $mapNum ; start of data for map $mapNum")
out.println(" !byte ++ - * + 1; length of this map's data (incl. hdr)")
out.println(" !byte ++ - *; length of this map's data (incl. hdr) - 1")
prevMapNum = mapNum
prevY = -1
}
if (y != prevY) {
if (prevY > 0) {
out.println(" !byte 0 ; end of y=$prevY")
out.println(" !byte \$FF ; end of y=$prevY")
out.println("+")
}
out.println(" !byte $y ; y=$y")
out.println(" !byte + - * + 1 ; length of y=$y data (incl. hdr)")
out.println(" !byte + - * ; length of y=$y data (incl. hdr) - 1")
prevY = y
}
out.println(" !byte $x, 3, $tileNum ; x=$x, size=3, tile=$tileNum")
out.println(" !byte $x, 2, $tileNum ; x=$x, size=2, tile=$tileNum")
}
if (prevY > 0) {
out.println(" !byte 0 ; end of y=$prevY")
out.println(" !byte \$FF ; end of y=$prevY")
out.println("+")
}
if (prevMapNum) {
out.println(" !byte 0 ; end of data for map $prevMapNum")
out.println(" !byte \$FF ; end of data for map $prevMapNum")
out.println("++")
}
out.println(" !byte 0; end of all maps")
out.println(" !byte \$FF; end of all maps")
}
replaceIfDiff("build/src/mapScripts/gen_mapSpecials.s")
}
@ -2639,6 +2670,9 @@ class A2PackPartitions
numberGlobalTiles(dataIn)
packGlobalTileSet(dataIn)
// Automap special tiles have to come next.
packAutomapTileSet(dataIn)
// Play around with music
def midiFile = new File(xmlFile.getAbsoluteFile().getParentFile(), "song.mid")
if (midiFile.exists())
@ -2757,6 +2791,7 @@ class A2PackPartitions
buf.put((byte)(tileSet.tileIds.size()))
tileSet.mainBuf.flip() // crazy stuff to append one buffer to another
buf.put(tileSet.mainBuf)
// After the large size tiles, add the small size tiles for automap display
tileSet.smBuf.flip() // crazy stuff to append one buffer to another
buf.put(tileSet.smBuf)
tileSet.buf = compress(unwrapByteBuffer(buf))

View File

@ -2142,6 +2142,8 @@ disk_queueLoad: !zone
ldx tmp ; get back lo part of addr
rts ; success! all done.
.notFound:
+prByte resType
+prByte resNum
jsr inlineFatal : !text "ResNotFnd", 0
.bump3: iny ; skip resource number
iny ; skip lo byte of length

View File

@ -8,8 +8,48 @@
; governing permissions and limitations under the License.
;****************************************************************************************
; Memory manager
; ------------------
;------------------------------------------------------------------------------
; Resource types
RES_TYPE_CODE = $1
RES_TYPE_2D_MAP = $2
RES_TYPE_3D_MAP = $3
RES_TYPE_TILESET = $4
RES_TYPE_TEXTURE = $5
RES_TYPE_SCREEN = $6
RES_TYPE_FONT = $7
RES_TYPE_MODULE = $8
RES_TYPE_BYTECODE = $9
RES_TYPE_FIXUP = $A
RES_TYPE_PORTRAIT = $B
RES_TYPE_SONG = $C
;------------------------------------------------------------------------------
; Command codes
RESET_MEMORY = $10
REQUEST_MEMORY = $11
LOCK_MEMORY = $12
UNLOCK_MEMORY = $13
SET_MEM_TARGET = $14
START_LOAD = $15
QUEUE_LOAD = $16
FINISH_LOAD = $17
FREE_MEMORY = $18
CALC_FREE = $19
DEBUG_MEM = $1A
CHECK_MEM = $1B
ADVANCE_ANIMS = $1C
FIND_IN_MEM = $1D
FATAL_ERROR = $1F
HEAP_SET = $20
HEAP_ADD_TYPE = $21
HEAP_ALLOC = $22
HEAP_INTERN = $23
HEAP_COLLECT = $24
;------------------------------------------------------------------------------
; Memory manager description
; --------------------------
;
; Memory is managed in variable-sized segments. In each 48kb memory bank (main and aux),
; a linked list identifies each segment there as well as usage flags to mark free, used,
@ -150,27 +190,11 @@
mainLoader = $800
auxLoader = mainLoader+3
;------------------------------------------------------------------------------
; Resource types
RES_TYPE_CODE = 1
RES_TYPE_2D_MAP = 2
RES_TYPE_3D_MAP = 3
RES_TYPE_TILESET = 4
RES_TYPE_TEXTURE = 5
RES_TYPE_SCREEN = 6
RES_TYPE_FONT = 7
RES_TYPE_MODULE = 8
RES_TYPE_BYTECODE = 9
RES_TYPE_FIXUP = 10
RES_TYPE_PORTRAIT = 11
RES_TYPE_SONG = 12
;------------------------------------------------------------------------------
; Command codes
;------------------------------------------------------------------------------
RESET_MEMORY = $10
;RESET_MEMORY = $10
; Input: None
;
; Output: None
@ -188,7 +212,7 @@ RESET_MEMORY = $10
; This command is acted upon and then passed on to chained loaders.
;------------------------------------------------------------------------------
REQUEST_MEMORY = $11
;REQUEST_MEMORY = $11
; Input: X-reg(lo) / Y-reg(hi) - number of bytes to allocate
;
; Output: X-reg(lo) / Y-reg(hi) - address allocated
@ -206,7 +230,7 @@ REQUEST_MEMORY = $11
; This command is acted upon immediately and chained loaders are not called.
;------------------------------------------------------------------------------
LOCK_MEMORY = $12
;LOCK_MEMORY = $12
; Input: X-reg(lo) / Y-reg(hi) - address of segment to lock
;
; Output: None
@ -217,7 +241,7 @@ LOCK_MEMORY = $12
; This command is acted upon immediately and chained loaders are not called.
;------------------------------------------------------------------------------
UNLOCK_MEMORY = $13
;UNLOCK_MEMORY = $13
; Input: X-reg(lo) / Y-reg(hi) - address of segment to unlock (must be start
; of a memory area that was previously locked)
;
@ -227,7 +251,7 @@ UNLOCK_MEMORY = $13
; RESET_MEMORY.
;------------------------------------------------------------------------------
SET_MEM_TARGET = $14
;SET_MEM_TARGET = $14
; Input: X-reg(lo) / Y-reg(hi) - address to target
;
; Output: None
@ -240,7 +264,7 @@ SET_MEM_TARGET = $14
; subsequent allocations will revert to their normal behavior.
;------------------------------------------------------------------------------
START_LOAD = $15
;START_LOAD = $15
; Input: X-reg - disk partition number (1 for boot disk, 2-15 for others)
;
; Output: None
@ -251,7 +275,7 @@ START_LOAD = $15
; The partition is recorded and passed on to chained loaders.
;------------------------------------------------------------------------------
QUEUE_LOAD = $16
;QUEUE_LOAD = $16
; Input: X-reg - resource type
; Y-reg - resource number
;
@ -273,7 +297,7 @@ QUEUE_LOAD = $16
; triggered.
;------------------------------------------------------------------------------
FINISH_LOAD = $17
;FINISH_LOAD = $17
; Input: None
;
; Output: None
@ -284,7 +308,7 @@ FINISH_LOAD = $17
; This command is acted upon by this loader and passed to chained loaders.
;------------------------------------------------------------------------------
FREE_MEMORY = $18
;FREE_MEMORY = $18
; Input: X-reg(lo) / Y-reg(hi) - address of segment to mark as free (must
; be start of a memory area that was previously requested or loaded)
;
@ -294,7 +318,7 @@ FREE_MEMORY = $18
; reused. This also clears the lock bit!
;------------------------------------------------------------------------------
CALC_FREE = $19
;CALC_FREE = $19
; Input: None
;
; Output: X-reg(lo) / Y-reg(hi) - bytes of memory currently free
@ -303,7 +327,7 @@ CALC_FREE = $19
; loader for main mem free, or aux mem loader for aux mem free.
;------------------------------------------------------------------------------
DEBUG_MEM = $1A
;DEBUG_MEM = $1A
; Input: None
;
; Output: None
@ -311,7 +335,7 @@ DEBUG_MEM = $1A
; Print out the currently allocated memory blocks and their states.
;------------------------------------------------------------------------------
CHECK_MEM = $1B
;CHECK_MEM = $1B
; Input: None
;
; Output: None
@ -320,7 +344,7 @@ CHECK_MEM = $1B
; has been set) are all intact.
;------------------------------------------------------------------------------
ADVANCE_ANIMS = $1C
;ADVANCE_ANIMS = $1C
; Input: X-reg - direction change (0=no change, 1=change).
; Only applied to resources marked as "forward/backward" order.
; Y-reg - number of frames to skip.
@ -340,7 +364,7 @@ ADVANCE_ANIMS = $1C
; or main) are processed.
;------------------------------------------------------------------------------
FIND_IN_MEM = $1D
;FIND_IN_MEM = $1D
; Input: X-reg - resource type
; Y-reg - resource number
;
@ -350,7 +374,7 @@ FIND_IN_MEM = $1D
; its address. Otherwise returns 0000.
;------------------------------------------------------------------------------
FATAL_ERROR = $1F
;FATAL_ERROR = $1F
; Input: X-reg(lo) / Y-reg(hi): message pointer. Message can be:
; (1) a zero-terminated, hi-bit ASCII string, (assembly style), or
; (2) a length-prefixed, lo-bit ASCII string (PLASMA / ProDOS style)
@ -364,7 +388,7 @@ FATAL_ERROR = $1F
; This command halts and thus never returns.
;------------------------------------------------------------------------------
HEAP_SET = $20
;HEAP_SET = $20
; Input: X-reg(lo) / Y-reg(hi): pointer to allocated block for heap
;
; Output: None
@ -377,7 +401,7 @@ HEAP_SET = $20
; setting the global type ($80).
;------------------------------------------------------------------------------
HEAP_ADD_TYPE = $21
;HEAP_ADD_TYPE = $21
; Input: X-reg(lo) / Y-reg(hi): pointer to type table
;
; Output: None
@ -395,7 +419,7 @@ HEAP_ADD_TYPE = $21
; byte n: zero (0) value marks end of table
;------------------------------------------------------------------------------
HEAP_ALLOC = $22
;HEAP_ALLOC = $22
; Input: X-reg: string length $00-7F, or type code $80-FF
;
; Output: X-reg(lo) / Y-reg(hi): pointer to allocated object space
@ -419,7 +443,7 @@ HEAP_ALLOC = $22
; Note: strings of length zero are considered valid and supported.
;------------------------------------------------------------------------------
HEAP_INTERN = $23
;HEAP_INTERN = $23
; Input: X-reg(lo) / Y-reg(hi): PLASMA-style string in regular RAM
;
; Output: X-reg(lo) / Y-reg(hi): pointer to allocated object space
@ -431,7 +455,7 @@ HEAP_INTERN = $23
; Else, allocates heap space and copy the string into it.
;------------------------------------------------------------------------------
HEAP_COLLECT = $24
;HEAP_COLLECT = $24
; Input: None.
;
; Output: X-reg(lo) / Y-reg(hi): new top of heap after collection. If you

View File

@ -22,6 +22,9 @@ const SCREEN_COLS = 36
const SECTION_WIDTH_2D = 22
const SECTION_HEIGHT_2D = 23
const specPtr = $BC // must match asm definition below for pSpecials
const specScanFor = $BE // must match asm definition below for scanFor
struc TMapSection
byte bm_mapNum
word pm_map
@ -57,6 +60,10 @@ byte nHorzSects
byte sectionBuf[SECT_BUF_SIZE]
word pLastSection
word pAllMarks
word pSpecialsBuf
word pSpecialTiles
word scanSpecials = $100 // placed at $100 so it can easily access aux mem
word pSpecTiles
///////////////////////////////////////////////////////////////////////////////////////////////////
// Definitions used by assembly code
@ -81,6 +88,8 @@ ysav = $34 ; length 1
; do not use $50..B5, as the current render (tile engine or raycaster) use these
pSrc = $B8 ; length 2
pDst = $BA ; length 2
pSpecials = $BC ; length 2
scanFor = $BE ; length 1
HB = evalStkH-evalStkL ; offset to get from lo byte to hi byte on eval stack
@ -247,29 +256,36 @@ asm scroll(srcLine, srcOff, dstLine, dstOff, width, dir, nLines)#0
end
///////////////////////////////////////////////////////////////////////////////////////////////////
asm fillRow(mapRowData, mask, tileTrans, pSmallTiles, blankTile, width, tilePtrs)#0
asm fillRow(mapRowData, mask, tileTrans, pSmallTiles, pSpecialTiles, blankTile, width, tilePtrs)#0
!zone
+asmPlasmNoRet 7
.param_mapRowData = evalStkL+6
.param_mask = evalStkL+5
.param_tileTrans = evalStkL+4
.param_pSmallTiles = evalStkL+3
.param_blankTile = evalStkL+2
.param_width = evalStkL+1
.param_tilePtrs = evalStkL+0
.srcOff = pTile
.dstOff = pTile+1
+asmPlasmNoRet 8
.param_mapRowData = evalStkL+7
.param_mask = evalStkL+6
.param_tileTrans = evalStkL+5
.param_pSmallTiles = evalStkL+4
.param_pSpecialTiles = evalStkL+3
.param_blankTile = evalStkL+2
.param_width = evalStkL+1
.param_tilePtrs = evalStkL+0
.srcOff = scanFor
.dstOff = pTile ; temporary use since we don't need it in this routine
.special = pTile+1 ; ditto
; psudocode:
; byte x, mapRaw, tileNum
; for x = 0 to width-1
; mapRaw = ^(mapRowData + x) & $1F
; if mapRaw
; if tileTrans
; tileNum = ^(tileTrans + ((mapRaw - 1) << 1))
; if mapRaw and (^(mapRowData + x) & $40) // automap 'seen' flag
; tileNum = scanSpecials(x)
; if tileNum
; tilePtrs[x] = pSpecialTiles + ((tileNum-1) * 9) // 9 bytes per reduced tile in the tileset
; else
; tileNum = mapRaw
; if tileTrans
; tileNum = ^(tileTrans + ((mapRaw - 1) << 1))
; else
; tileNum = mapRaw
; fin
; tilePtrs[x] = pSmallTiles + ((tileNum-1) * 9) // 9 bytes per reduced tile in the tileset
; fin
; tilePtrs[x] = pSmallTiles + ((tileNum-1) * 9) // 9 bytes per reduced tile in the tileset
; else
; tilePtrs[x] = @blankTile
; fin
@ -297,6 +313,13 @@ asm fillRow(mapRowData, mask, tileTrans, pSmallTiles, blankTile, width, tilePtrs
asl
bpl .blank ; skip unless $40 bit is set denoting this space has been seen
lsr
pha
jsr $100 ; scan for automap specials override
sta .special
beq +
dex ; to use pSpecialTiles instead of pSmallTiles
bpl .got ; always taken
+ pla ; normal processing (no special override)
and .param_mask,x ; mask to get just tile number
beq .blank
tay
@ -307,6 +330,7 @@ asm fillRow(mapRowData, mask, tileTrans, pSmallTiles, blankTile, width, tilePtrs
asl
tay
lda (pTmp),y
.got
tay
.notrans
dey ; tileNum - 1
@ -324,11 +348,14 @@ asm fillRow(mapRowData, mask, tileTrans, pSmallTiles, blankTile, width, tilePtrs
bcc +
inc tmp+1
+ clc
adc .param_pSmallTiles,x
adc .param_pSmallTiles,x ; X may have been adjusted to address pSpecialTiles instead
pha
lda tmp+1
adc .param_pSmallTiles+HB,x
bcc .store ; always taken
ldy .special
beq +
inx ; back to using normal pSmallTiles
+ bcc .store ; always taken
.blank
lda .param_blankTile,x
pha
@ -475,11 +502,58 @@ asm mergeMarks(allMarks, mapNum, mapData, width, stride, height)#0
} ; end of zone
end
///////////////////////////////////////////////////////////////////////////////////////////////////
asm _scanSpecials_start()#0
; Advance pSpecials looking for 'scanFor'
!zone {
; This gets copied to and run from $100 so it can easily access aux mem
sta setAuxRd
lda #$60
sta 0
jsr 0 ; FOO
.loop
ldy #0
lda (pSpecials),y
iny
cmp scanFor
beq +
eor #$FF ; if end of table...
beq .ret ; ...return zero (and don't go past end of table)
lda (pSpecials),y
tay
+ tya ; at this point, y=1 is match, 2+ is no-match skipping
sec ; yes, add one extra
adc pSpecials
sta pSpecials
bcc +
inc pSpecials+1
+ dey ; if len was 1, it was match; >=2 no match, loop again
bne .loop
lda (pSpecials),y ; y=0: match, get the value inside
.ret
sta clrAuxRd
rts
}
end
asm _scanSpecials_end()#0
nop ; dummy
end
///////////////////////////////////////////////////////////////////////////////////////////////////
def loadMarks()#0
word len
// First, call the automark write routine. This has not only the effect of flushing the marks
// Load the specials table since partition zero is probably still open
auxMmgr(START_LOAD, 1) // partition 1 is where the table lives
pSpecialsBuf = auxMmgr(QUEUE_LOAD, CODE_GEN_MAP_SPECIALS<<8 | RES_TYPE_CODE)
// While we're at it, load the automap special tiles.
pSpecTiles = mmgr(QUEUE_LOAD, 2<<8 | RES_TYPE_TILESET) // always tileset 2 (just after global tiles)
mmgr(FINISH_LOAD, 0)
// 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
@ -487,17 +561,20 @@ def loadMarks()#0
len = *$4000
pAllMarks = auxMmgr(REQUEST_MEMORY, len)
memcpy($4002, pAllMarks, len, 1)
// Figure out where the small versions of the special tiles reside (at the end of the full size tiles)
pSpecialTiles = pSpecialsBuf + 1 + ((^pSpecialsBuf) << 5)
end
///////////////////////////////////////////////////////////////////////////////////////////////////
def displayRow3D(pScreen, mapRowData, tileTrans, pSmallTiles, width)#0
fillRow(mapRowData, $1F, tileTrans, pSmallTiles, @blankTile, width, @tilePtrs)
def displayRow3D(pScreen, mapRowData, tileTrans, pSmallTiles, pSpecialTiles, width)#0
fillRow(mapRowData, $1F, tileTrans, pSmallTiles, pSpecialTiles, @blankTile, width, @tilePtrs)
drawSlice(@blankTile, pScreen, width, @tilePtrs)
end
///////////////////////////////////////////////////////////////////////////////////////////////////
def displayRow2D(pScreen, mapRowData, pSmallTiles, width)#0
fillRow(mapRowData, $3F, NULL, pSmallTiles, @blankTile, width, @tilePtrs)
def displayRow2D(pScreen, mapRowData, pSmallTiles, pSpecialTiles, width)#0
fillRow(mapRowData, $3F, NULL, pSmallTiles, pSpecialTiles, @blankTile, width, @tilePtrs)
drawSlice(@blankTile, pScreen, width, @tilePtrs)
end
@ -625,13 +702,10 @@ def freeSections#0
end
///////////////////////////////////////////////////////////////////////////////////////////////////
def displaySection3D(pSection)#0
word pSmallTiles, tileTrans, mapData, rowData
def displaySection3D(pSection, pSmallTiles)#0
word tileTrans, mapData, rowData, specBlk
byte nTextures, y, rowSize, 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)
// Extract significant pointers from the map blob
rowSize = ^(pSection=>pm_map)
tileTrans = pSection=>pm_map + 4
@ -654,22 +728,28 @@ def displaySection3D(pSection)#0
line = (pSection->bm_sy << 3) + MAP_TOP
lx = MAP_LEFT + pSection->bm_sx
// Find the map data in the specials buf
*specPtr = pSpecialsBuf
^specScanFor = pSection->bm_mapNum | $80
scanSpecials()#0
specBlk = *specPtr
// Display each visible row
for y = 1 to pSection->bm_ch // offset is 1 to skip over sentinel row
displayRow3D(getScreenLine(line) + lx, rowData, tileTrans, pSmallTiles, pSection->bm_cw)
*specPtr = specBlk
^specScanFor = y + pSection->wm_y0
scanSpecials()#0
displayRow3D(getScreenLine(line) + lx, rowData, tileTrans, pSmallTiles, pSpecialTiles, pSection->bm_cw)
rowData = rowData + rowSize
line = line + 8
next
end
///////////////////////////////////////////////////////////////////////////////////////////////////
def displaySection2D(pSection)#0
word pSmallTiles, rowData
def displaySection2D(pSection, pSmallTiles)#0
word rowData
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)
// Merge automap marks into the data if not done yet
rowData = pSection=>pm_map + 6 // header = 6 bytes
if pSection->bm_needMarks
@ -683,9 +763,14 @@ def displaySection2D(pSection)#0
line = (pSection->bm_sy << 3) + MAP_TOP
lx = MAP_LEFT + pSection->bm_sx
// Find the map data in the specials buf
*specPtr = pSpecialsBuf
^specScanFor = pSection->bm_mapNum
scanSpecials()#0
// Display each visible row
for y = 1 to pSection->bm_ch
displayRow2D(getScreenLine(line) + lx, rowData, pSmallTiles, pSection->bm_cw)
displayRow2D(getScreenLine(line) + lx, rowData, pSmallTiles, pSpecialTiles, pSection->bm_cw)
rowData = rowData + SECTION_WIDTH_2D
line = line + 8
next
@ -693,15 +778,23 @@ end
///////////////////////////////////////////////////////////////////////////////////////////////////
def displaySections#0
word pSection
word pSection, pSmallTiles, x
pSection = @sectionBuf
// Set up routine that scans the specials table in aux mem (routine lives in low stack page)
memcpy(@_scanSpecials_start, scanSpecials, @_scanSpecials_end - @_scanSpecials_start, 0)
while pSection <> pLastSection
//printSection(pSection)
if pSection->bm_visible
// Figure out where the small tiles reside (at the end of the full size tiles)
pSmallTiles = pSection=>pm_tileset + 1 + ((^(pSection=>pm_tileset)) << 5)
// And draw (different routines to handle differing map data layouts)
if mapIs3D
displaySection3D(pSection)
displaySection3D(pSection, pSmallTiles)
else
displaySection2D(pSection)
displaySection2D(pSection, pSmallTiles)
fin
fin
pSection = pSection + TMapSection
@ -914,6 +1007,8 @@ def _automap_show()#1
until key == 27 or key == 'Q' or key == '-' // esc or Q or - to exit
auxMmgr(FREE_MEMORY, pAllMarks)
auxMmgr(FREE_MEMORY, pSpecialsBuf)
mmgr(FREE_MEMORY, pSpecTiles)
return 0
end

View File

@ -2228,6 +2228,7 @@ def initMap(x, y, dir)#0
else
mmgr(QUEUE_LOAD, CODE_TILE_ENGINE<<8 | RES_TYPE_CODE)
fin
pGlobalTileset = mmgr(QUEUE_LOAD, 1<<8 | RES_TYPE_TILESET) // even in 3d, need tiles for lamp/etc.
mmgr(FINISH_LOAD, 0)
// Set up the command table
@ -2237,7 +2238,6 @@ def initMap(x, y, dir)#0
curMapPartition = lookupResourcePart(mapIs3D+1, mapNum)
mmgr(START_LOAD, curMapPartition)
pCurMap = mmgr(QUEUE_LOAD, mapNum<<8 | (RES_TYPE_2D_MAP+mapIs3D))
pGlobalTileset = mmgr(QUEUE_LOAD, 1<<8 | RES_TYPE_TILESET) // even in 3d, need tiles for lamp/etc.
mmgr(FINISH_LOAD, 0)
// Clear all the windows to the background color (hi-bit set)