mirror of
https://github.com/badvision/lawless-legends.git
synced 2024-07-05 01:28:57 +00:00
Improved look and consistency of automap size reduction.
This commit is contained in:
parent
a245855a5e
commit
1e6a12fd4c
@ -95,6 +95,7 @@ class A2PackPartitions
|
||||
def maps2D = [:] // map name to map.num, map.buf
|
||||
def maps3D = [:] // map name to map.num, map.buf
|
||||
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
|
||||
def avatars = [:] // avatar tile name to tile num (within the special tileset)
|
||||
def lampTiles = [] // animated series of lamp tiles
|
||||
@ -281,10 +282,8 @@ class A2PackPartitions
|
||||
return DatatypeConverter.printHexBinary(md.digest())
|
||||
}
|
||||
|
||||
def pixelize(dataEl)
|
||||
def pixelize(dataEl, stride, nBytes, nLines)
|
||||
{
|
||||
def nBytes = dataEl.@width as int
|
||||
def nLines = dataEl.@height as int
|
||||
def hexStr = dataEl.text()
|
||||
return (0..<nLines).collect { lineNum ->
|
||||
def outRow = []
|
||||
@ -314,15 +313,48 @@ class A2PackPartitions
|
||||
// Locate the data for the Apple II (as opposed to C64 etc.)
|
||||
def data = imgEl.displayData?.find { it.@platform == "AppleII" }
|
||||
assert data : "image '${imgEl.@name}' missing AppleII platform data"
|
||||
def rows = pixelize(data)
|
||||
def rows = pixelize(data, data.@width as int, 10, 64)
|
||||
|
||||
// Retain only the upper-left 64 lines x 32 pixels
|
||||
return rows[0..63].collect { it[0..31] }
|
||||
return rows.collect { it[0..31] }
|
||||
}
|
||||
|
||||
/*
|
||||
* Add a pixel to a reduction pixel buffer
|
||||
*/
|
||||
def addPix(pixBuf, hibitBuf, int pix)
|
||||
{
|
||||
if (pixBuf.containsKey(pix))
|
||||
pixBuf[pix] += 1
|
||||
else
|
||||
pixBuf[pix] = 1
|
||||
|
||||
int hibit = pix >> 2
|
||||
if (hibitBuf.containsKey(hibit))
|
||||
hibitBuf[hibit] += 1
|
||||
else
|
||||
hibitBuf[hibit] = 1
|
||||
}
|
||||
|
||||
/*
|
||||
* Parse raw tile image data and return it as a buffer.
|
||||
*/
|
||||
def choosePix(pixBuf, x, y)
|
||||
{
|
||||
def inv = ((((x>>1)+(y>>1)) & 1) * 2) - 1 // 1 or -1, in a dither pattern
|
||||
inv = 1 // FOO: no dither for now
|
||||
def accum = []
|
||||
pixBuf.each { pix, count ->
|
||||
accum << [count, pix*inv]
|
||||
}
|
||||
def choice = accum.sort().reverse()[0]
|
||||
return Math.abs(choice[1])
|
||||
}
|
||||
|
||||
/*
|
||||
* Parse raw tile image data and return it as a two buffers: fullsize mainBuf,
|
||||
* and reduced size smBuf
|
||||
*/
|
||||
def parseTileData(imgEl)
|
||||
{
|
||||
// Locate the data for the Apple II (as opposed to C64 etc.)
|
||||
@ -331,14 +363,44 @@ class A2PackPartitions
|
||||
|
||||
// Parse out the hex data on each line and add it to a buffer.
|
||||
def hexStr = dataEl.text()
|
||||
def outBuf = ByteBuffer.allocate(50000)
|
||||
def mainBuf = ByteBuffer.allocate(32)
|
||||
for (def pos = 0; pos < hexStr.size(); pos += 2) {
|
||||
def val = Integer.parseInt(hexStr[pos..pos+1], 16)
|
||||
outBuf.put((byte)val)
|
||||
mainBuf.put((byte)val)
|
||||
}
|
||||
|
||||
// All done. Return the buffer.
|
||||
return outBuf
|
||||
// Make a reduced-size version
|
||||
def rows = pixelize(dataEl, 2, 2, 16)
|
||||
def smBuf = ByteBuffer.allocate(9)
|
||||
smBuf.put((byte)0) // placeholder for hi bits
|
||||
def hibits = 0
|
||||
def pixBuf
|
||||
for (int y = 0; y < 16; y += 2)
|
||||
{
|
||||
def hibitBuf = [:]
|
||||
def outByte = 0
|
||||
for (int x = 0; x < 7; x += 2)
|
||||
{
|
||||
pixBuf = [:]
|
||||
addPix(pixBuf, hibitBuf, rows[y] [x])
|
||||
addPix(pixBuf, hibitBuf, rows[y+1][x])
|
||||
if (x < 6) {
|
||||
addPix(pixBuf, hibitBuf, rows[y] [x+1])
|
||||
addPix(pixBuf, hibitBuf, rows[y+1][x+1])
|
||||
}
|
||||
def outPix = choosePix(pixBuf, x, y)
|
||||
outByte = (outByte >> 2) | ((outPix & 3) << 6)
|
||||
}
|
||||
// No: (outByte >> 7) | ((outByte << 1) & 0xFF) // rotate one bit for efficient Apple II code
|
||||
smBuf.put((byte)outByte)
|
||||
hibits = (hibits >> 1) | (choosePix(hibitBuf, 0, y) << 7)
|
||||
}
|
||||
smBuf.position(0)
|
||||
smBuf.put((byte)hibits)
|
||||
smBuf.position(9)
|
||||
|
||||
// All done. Return the buffers.
|
||||
return [mainBuf, smBuf]
|
||||
}
|
||||
|
||||
/*
|
||||
@ -875,8 +937,9 @@ class A2PackPartitions
|
||||
|
||||
def packTile(imgEl)
|
||||
{
|
||||
def buf = parseTileData(imgEl)
|
||||
tiles[imgEl.@id] = buf
|
||||
def (mainBuf, smBuf) = parseTileData(imgEl)
|
||||
tiles[imgEl.@id] = mainBuf
|
||||
smTiles[imgEl.@id] = smBuf
|
||||
}
|
||||
|
||||
/** Identify the avatars and other global tiles, and number them */
|
||||
@ -920,7 +983,7 @@ class A2PackPartitions
|
||||
}
|
||||
}
|
||||
|
||||
tileSets[setName] = [num:setNum, buf:buf, tileMap:tileMap, tileIds:tileIds]
|
||||
tileSets[setName] = [num:setNum, mainBuf:buf, smBuf:ByteBuffer.allocate(1), tileMap:tileMap, tileIds:tileIds]
|
||||
return [setNum, tileMap]
|
||||
}
|
||||
|
||||
@ -968,7 +1031,11 @@ class A2PackPartitions
|
||||
else {
|
||||
setNum = tileSets.size() + 1
|
||||
//println "Creating new tileSet $setNum."
|
||||
tileSet = [num:setNum, buf:ByteBuffer.allocate(50000), tileMap:[:], tileIds:tileIds]
|
||||
tileSet = [num:setNum,
|
||||
mainBuf:ByteBuffer.allocate(50000),
|
||||
smBuf:ByteBuffer.allocate(20000),
|
||||
tileMap:[:],
|
||||
tileIds:tileIds]
|
||||
tileSets["tileSet${setNum}"] = tileSet
|
||||
}
|
||||
|
||||
@ -977,7 +1044,8 @@ class A2PackPartitions
|
||||
|
||||
// Start by assuming we'll create a new tileset
|
||||
def tileMap = tileSet.tileMap
|
||||
def buf = tileSet.buf
|
||||
def mainBuf = tileSet.mainBuf
|
||||
def smBuf = tileSet.smBuf
|
||||
|
||||
// Then add each non-null tile to the set
|
||||
(yOff ..< yOff+height).each { y ->
|
||||
@ -990,12 +1058,15 @@ class A2PackPartitions
|
||||
assert num < 64 : "Error: Only 63 kinds of tiles are allowed on any given map."
|
||||
tileMap[id] = num
|
||||
tiles[id].flip() // crazy stuff to append one buffer to another
|
||||
buf.put(tiles[id])
|
||||
mainBuf.put(tiles[id])
|
||||
smTiles[id].flip()
|
||||
smBuf.put(smTiles[id])
|
||||
}
|
||||
}
|
||||
}
|
||||
assert tileMap.size() > 0
|
||||
assert buf.position() > 0
|
||||
assert mainBuf.position() > 0
|
||||
assert smBuf.position() > 0
|
||||
|
||||
return [setNum, tileMap]
|
||||
}
|
||||
@ -2377,7 +2448,13 @@ class A2PackPartitions
|
||||
|
||||
// Now that the tileSets are complete, compress them.
|
||||
tileSets.each { name, tileSet ->
|
||||
tileSet.buf = compress(unwrapByteBuffer(tileSet.buf))
|
||||
def buf = ByteBuffer.allocate(50000)
|
||||
buf.put((byte)(tileSet.tileIds.size()))
|
||||
tileSet.mainBuf.flip() // crazy stuff to append one buffer to another
|
||||
buf.put(tileSet.mainBuf)
|
||||
tileSet.smBuf.flip() // crazy stuff to append one buffer to another
|
||||
buf.put(tileSet.smBuf)
|
||||
tileSet.buf = compress(unwrapByteBuffer(buf))
|
||||
}
|
||||
|
||||
//println("rdeps - phase 2:" + JsonOutput.prettyPrint(JsonOutput.toJson(resourceDeps)))
|
||||
@ -4062,8 +4139,8 @@ end
|
||||
outIndented("p_player = global=>p_players\n")
|
||||
outIndented("while p_player\n")
|
||||
++indent
|
||||
outIndented(
|
||||
"setStat(p_player, $stat, getStat(p_player, $stat) ${blk.@type == 'interaction_increase_party_stats' ? '+' : '-'} $amount)\n")
|
||||
outIndented("setStat(p_player, $stat, getStat(p_player, $stat) " +
|
||||
"${blk.@type == 'interaction_increase_party_stats' ? '+' : '-'} $amount)\n")
|
||||
outIndented("p_player = p_player=>p_nextObj\n")
|
||||
--indent
|
||||
outIndented("loop\n")
|
||||
|
@ -19,7 +19,7 @@ predef _automap_show()#1
|
||||
word[] funcTbl = @_automap_show
|
||||
|
||||
word tilePtrs[40]
|
||||
byte blankTile[32]
|
||||
byte blankTile[9]
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Definitions used by assembly code
|
||||
@ -28,150 +28,121 @@ asm _defs
|
||||
!source "../../include/global.i"
|
||||
!source "../../include/plasma.i"
|
||||
!source "../../include/mem.i"
|
||||
!source "../../include/fontEngine.i"
|
||||
tmp = $2 ; length 2
|
||||
pTmp = $4 ; length 2
|
||||
pix0 = $6 ; length 1
|
||||
pix1 = $7 ; length 1
|
||||
tilePtrs = $8 ; length 2
|
||||
tileOff = $A ; length 1
|
||||
nTiles = $B ; length 1
|
||||
pScreen = $C ; length 2
|
||||
pTile = $E ; length 2
|
||||
ysav = $34
|
||||
tilePtrs = $6 ; length 2
|
||||
pTile = $8 ; length 2
|
||||
pBlank = $A ; length 2
|
||||
hibits = $C ; length 1
|
||||
nTiles = $D ; length 1
|
||||
prevBits = $E ; length 1
|
||||
unused0F = $F ; length 1
|
||||
linePtrs = $10 ; length 2*8 = 16
|
||||
ysav = $34 ; length 1
|
||||
end
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
asm drawSlice(tilePtrs, nTiles, pScreen)#0
|
||||
+asmPlasmNoRet 3
|
||||
|
||||
lda #$60
|
||||
sta 0
|
||||
jsr 0 ; FOO
|
||||
|
||||
lda #0 ; start at zero tile offset
|
||||
.row
|
||||
sta tileOff
|
||||
sty pScreen+1
|
||||
lda evalStkL+0,x ; re-init low byte of screen ptr each row
|
||||
sta pScreen
|
||||
asm drawSlice(pBlank, pScreen, nTiles, tilePtrs)#0
|
||||
+asmPlasmNoRet 4
|
||||
sta tilePtrs
|
||||
sty tilePtrs+1
|
||||
lda evalStkL+1,x
|
||||
sta nTiles
|
||||
lda evalStkL+2,x
|
||||
sta tilePtrs
|
||||
sta pTmp
|
||||
lda evalStkH+2,x
|
||||
sta tilePtrs+1
|
||||
clc ; start with even-tile logic
|
||||
.tileLoop
|
||||
sta pTmp+1
|
||||
lda evalStkL+3,x
|
||||
sta pBlank
|
||||
lda evalStkH+3,x
|
||||
sta pBlank+1
|
||||
; Grab the line pointers for all 8 lines
|
||||
ldx #0
|
||||
- lda pTmp
|
||||
sta linePtrs,x
|
||||
inx
|
||||
lda pTmp+1
|
||||
sta linePtrs,x
|
||||
inx
|
||||
jsr NextScreenLine
|
||||
cpx #16
|
||||
bne -
|
||||
; Process one tile
|
||||
.tile
|
||||
ldy #0
|
||||
lda (tilePtrs),y
|
||||
sta pTile
|
||||
inc tilePtrs
|
||||
bne +
|
||||
inc tilePtrs+1
|
||||
+ lda (tilePtrs),y
|
||||
iny
|
||||
lda (tilePtrs),y
|
||||
sta pTile+1
|
||||
inc tilePtrs
|
||||
bne +
|
||||
inc tilePtrs+1
|
||||
+ ldy tileOff ; start at correct vertical offset within each tile
|
||||
lda (pTile),y
|
||||
bcs .oddTile ; first time even, second time odd, third time even, etc.
|
||||
.evenTile
|
||||
lsr ; in bit A-0
|
||||
ror pix0 ; out bit 0
|
||||
lsr ; in bit A-1
|
||||
ror pix0 ; out bit 1
|
||||
lsr ; in bit A-2 (skip)
|
||||
lsr ; in bit A-3 (skip)
|
||||
lsr ; in bit A-4
|
||||
ror pix0 ; out bit 2
|
||||
lsr ; in bit A-5
|
||||
ror pix0 ; out bit 3
|
||||
; in bit A-6 (skip)
|
||||
; in bit A-7 (hi skip)
|
||||
iny
|
||||
lda (pTile),y
|
||||
lsr ; in bit A-8 (skip)
|
||||
lsr ; in bit A-9
|
||||
ror pix0 ; out bit 4
|
||||
lsr ; in bit A-10
|
||||
ror pix0 ; out bit 5
|
||||
lsr ; in bit A-11 (skip)
|
||||
lsr ; in bit A-12 (skip)
|
||||
lsr ; in bit A-13
|
||||
ror pix0 ; out bit 6
|
||||
lsr ; in bit A-14
|
||||
ror pix1 ; out bit 8 (!)
|
||||
lsr ; in bit A-15 (hibit)
|
||||
ror pix0 ; out bit 7 (!)
|
||||
lda pix0
|
||||
sec ; next iteration, use odd-tile logic
|
||||
|
||||
.store
|
||||
ldy #0
|
||||
sta (pScreen),y
|
||||
inc pScreen
|
||||
dec nTiles ; count down tiles done
|
||||
bne .tileLoop ; go until we've done all tiles for the row
|
||||
lda pScreen+1
|
||||
lda tilePtrs
|
||||
clc
|
||||
adc #4 ; advance to next screen line
|
||||
tay
|
||||
lda tileOff ; carry already clear from above
|
||||
adc #4 ; advance 2 rows within the tiles (1 we did, 1 skipping for downsize)
|
||||
cmp #32 ; until done with all 32 bytes of tiles
|
||||
bcc .row
|
||||
rts ; finished
|
||||
|
||||
.oddTile
|
||||
lsr ; in bit B-0 (skip)
|
||||
lsr ; in bit B-1 (skip)
|
||||
lsr ; in bit B-2
|
||||
ror pix1 ; out bit 9
|
||||
lsr ; in bit B-3
|
||||
ror pix1 ; out bit 10
|
||||
lsr ; in bit B-4 (skip)
|
||||
lsr ; in bit B-5 (skip)
|
||||
lsr ; in bit B-6
|
||||
ror pix1 ; out bit 11
|
||||
; in bit B-7 (hi skip)
|
||||
iny
|
||||
adc #2
|
||||
sta tilePtrs
|
||||
bcc +
|
||||
inc tilePtrs+1
|
||||
+ dey
|
||||
lda (pTile),y
|
||||
lsr ; in bit B-8
|
||||
ror pix1 ; out bit 12
|
||||
lsr ; in bit B-9 (skip)
|
||||
lsr ; in bit B-10 (skip)
|
||||
lsr ; in bit B-11
|
||||
ror pix1 ; out bit 13
|
||||
lsr ; in bit B-12
|
||||
ror pix1 ; out bit 14
|
||||
lsr ; in bit B-13 (skip)
|
||||
lsr ; in bit B-14 (skip)
|
||||
lsr ; in bit B-15 (hibit)
|
||||
ror pix1 ; out bit 15 (hibit)
|
||||
lda pix1
|
||||
clc ; next iteration, use even-tile logic
|
||||
bcc .store ; always taken
|
||||
sta hibits
|
||||
sta (pBlank),y ; if next tile is blank, match hi bits of this tile
|
||||
iny
|
||||
ldx #0
|
||||
lda linePtrs
|
||||
lsr
|
||||
bcs .odd
|
||||
.even
|
||||
lda (pTile),y
|
||||
iny
|
||||
asl
|
||||
ror prevBits
|
||||
lsr hibits
|
||||
ror
|
||||
sta (linePtrs,x)
|
||||
inc linePtrs,x
|
||||
inx
|
||||
inx
|
||||
cpx #16
|
||||
bne .even
|
||||
beq .next ; always taken
|
||||
.odd
|
||||
lda (pTile),y
|
||||
iny
|
||||
lsr prevBits
|
||||
rol
|
||||
asl
|
||||
lsr hibits
|
||||
ror
|
||||
sta (linePtrs,x)
|
||||
inc linePtrs,x
|
||||
inx
|
||||
inx
|
||||
cpx #16
|
||||
bne .odd
|
||||
.next
|
||||
dec nTiles
|
||||
bne .tile
|
||||
rts
|
||||
end
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
def displayRow(rowNum, mapRowData, tileTrans, pTileset, width)#0
|
||||
def displayRow(rowNum, mapRowData, tileTrans, pSmallTiles, width)#0
|
||||
byte x, mapRaw, tileNum
|
||||
for x = 0 to width-1
|
||||
mapRaw = ^(mapRowData + x) & $1F
|
||||
if mapRaw
|
||||
tileNum = ^(tileTrans + ((mapRaw - 1) << 1))
|
||||
tilePtrs[x] = pTileset + ((tileNum-1) << 5) // 32 bytes per tile in the tileset
|
||||
tilePtrs[x] = pSmallTiles + ((tileNum-1) * 9) // 9 bytes per reduced tile in the tileset
|
||||
else
|
||||
tilePtrs[x] = @blankTile
|
||||
fin
|
||||
next
|
||||
drawSlice(@tilePtrs, width, getScreenLine((rowNum+2)<<3) + 2)
|
||||
drawSlice(@blankTile, getScreenLine((rowNum+2)<<3) + 2, width, @tilePtrs)
|
||||
end
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
def _automap_show()#1
|
||||
word pTileset, tileTrans, mapData
|
||||
word pTileset, pSmallTiles, tileTrans, mapData
|
||||
byte nTextures, y, rowSize, numRows
|
||||
|
||||
setBigWindow
|
||||
@ -186,6 +157,9 @@ def _automap_show()#1
|
||||
pTileset = mmgr(QUEUE_LOAD, (^(pCurMap+3))<<8 | RES_TYPE_TILESET)
|
||||
mmgr(FINISH_LOAD, 0)
|
||||
|
||||
// Figure out where the small tiles reside (at the end of the full size tiles)
|
||||
pSmallTiles = pTileset + 1 + ((^pTileset) << 5)
|
||||
|
||||
// Extract significant pointers from the map blob
|
||||
rowSize = ^pCurMap
|
||||
numRows = ^(pCurMap+1)
|
||||
@ -198,12 +172,12 @@ def _automap_show()#1
|
||||
//printf2("mapData=$%x, rowSize=%d\n", mapData, rowSize) // FOO
|
||||
|
||||
// Clear out the blank tile buffer
|
||||
memset(@blankTile, 0, 32)
|
||||
memset(@blankTile, 0, 9)
|
||||
|
||||
// Display each row
|
||||
for y = 0 to numRows-3 // two sentinel rows, and an extra because zero-indexed.
|
||||
// The +1's below are to skip over the sentinel row and column that 3D maps have
|
||||
displayRow(y, mapData + ((y+1)*rowSize) + 1, tileTrans, pTileset, rowSize-2)
|
||||
displayRow(y, mapData + ((y+1)*rowSize) + 1, tileTrans, pSmallTiles, rowSize-2)
|
||||
next
|
||||
|
||||
getUpperKey
|
||||
|
@ -862,7 +862,7 @@ ROW_OFFSET = 3
|
||||
ROL .tsadd+1
|
||||
DEY
|
||||
BNE -
|
||||
CLC
|
||||
SEC ; skip over initial count
|
||||
ADC GLOBAL_TILESET_LOC
|
||||
TAY
|
||||
LDA GLOBAL_TILESET_LOC+1
|
||||
@ -892,7 +892,7 @@ ROW_OFFSET = 3
|
||||
ROL TILE_SOURCE+1
|
||||
ASL
|
||||
ROL TILE_SOURCE+1
|
||||
CLC
|
||||
SEC ; skip over initial tile count
|
||||
ADC TILE_BASE
|
||||
TAY
|
||||
LDA TILE_SOURCE+1
|
||||
|
Loading…
Reference in New Issue
Block a user