From 9e93360d11591ded985648b3fd8171689ab44bc6 Mon Sep 17 00:00:00 2001 From: Martin Haye Date: Mon, 25 May 2020 13:32:51 -0700 Subject: [PATCH] Save memory during automap display by packing small tilesets separately from regular tilesets. --- .../src/org/badvision/A2PackPartitions.groovy | 74 +++++++++---------- Platform/Apple/virtual/src/core/mem.s | 2 + Platform/Apple/virtual/src/include/mem.i | 27 +++---- Platform/Apple/virtual/src/plasma/automap.pla | 12 +-- .../Apple/virtual/src/plasma/gameloop.pla | 8 +- .../Apple/virtual/src/plasma/globalDefs.plh | 27 +++---- 6 files changed, 75 insertions(+), 75 deletions(-) diff --git a/Platform/Apple/tools/PackPartitions/src/org/badvision/A2PackPartitions.groovy b/Platform/Apple/tools/PackPartitions/src/org/badvision/A2PackPartitions.groovy index b267c793..69ff8232 100644 --- a/Platform/Apple/tools/PackPartitions/src/org/badvision/A2PackPartitions.groovy +++ b/Platform/Apple/tools/PackPartitions/src/org/badvision/A2PackPartitions.groovy @@ -56,6 +56,7 @@ class A2PackPartitions def TYPE_PORTRAIT = 11 def TYPE_SONG = 12 def TYPE_STORY = 13 + def TYPE_SM_TILE_SET = 14 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 @@ -76,21 +77,23 @@ class A2PackPartitions 10: "Code", 11: "Portrait image", 12: "Song", - 13: "Story"] + 13: "Story", + 14: "Small tile set"] - def typeNameToNum = ["code": TYPE_CODE, - "map2D": TYPE_2D_MAP, - "map3D": TYPE_3D_MAP, - "tileSet": TYPE_TILE_SET, - "texture": TYPE_TEXTURE_IMG, - "frame": TYPE_SCREEN, - "font": TYPE_FONT, - "module": TYPE_MODULE, - "bytecode": TYPE_BYTECODE, - "fixup": TYPE_FIXUP, - "portrait": TYPE_PORTRAIT, - "song": TYPE_SONG, - "story": TYPE_STORY] + def typeNameToNum = ["code": TYPE_CODE, + "map2D": TYPE_2D_MAP, + "map3D": TYPE_3D_MAP, + "tileSet": TYPE_TILE_SET, + "texture": TYPE_TEXTURE_IMG, + "frame": TYPE_SCREEN, + "font": TYPE_FONT, + "module": TYPE_MODULE, + "bytecode": TYPE_BYTECODE, + "fixup": TYPE_FIXUP, + "portrait": TYPE_PORTRAIT, + "song": TYPE_SONG, + "story": TYPE_STORY, + "smTileSet": TYPE_SM_TILE_SET] def typeNumToName = [1: "code", 2: "map2D", @@ -104,7 +107,8 @@ class A2PackPartitions 10: "fixup", 11: "portrait", 12: "song", - 13: "story"] + 13: "story", + 14: "smTileSet"] def mapNames = [:] // map name (and short name also) to map.2dor3d, map.num def mapSizes = [] // array of [2dOr3D, mapNum, marksSize] @@ -115,6 +119,7 @@ class A2PackPartitions 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 smTileSets= [:] // 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 def textures = [:] // img name to img.num, img.buf @@ -1117,6 +1122,7 @@ class A2PackPartitions } tileSets[setName] = [num:setNum, tileMap:tileMap, tileIds:tileIds] + smTileSets[setName] = [num:setNum, tileMap:tileMap, tileIds:tileIds] addResourceDep("map", "", "tileSet", "tileSet_global") return [setNum, tileMap] } @@ -1141,6 +1147,7 @@ class A2PackPartitions } tileSets[setName] = [num:setNum, tileMap:tileMap, tileIds:tileIds] + smTileSets[setName] = [num:setNum, tileMap:tileMap, tileIds:tileIds] addResourceDep("map", "", "tileSet", "tileSet_automap") return [setNum, tileMap] } @@ -1189,10 +1196,9 @@ class A2PackPartitions else { setNum = tileSets.size() + 1 //println "Creating new tileSet $setNum." - tileSet = [num:setNum, - tileMap:[:], - tileIds:tileIds] + tileSet = [num:setNum, tileMap:[:], tileIds:tileIds] tileSets["tileSet${setNum}"] = tileSet + smTileSets["tileSet${setNum}"] = [num:setNum, tileMap: tileSet.tileMap, tileIds:tileIds] } addMapDep("tileSet", "tileSet${setNum}") @@ -1985,6 +1991,7 @@ class A2PackPartitions recordChunks("map2D", maps2D) recordChunks("map3D", maps3D) recordChunks("tileSet", tileSets) + recordChunks("smTileSet",smTileSets) recordChunks("texture", textures) recordChunks("frame", frames) recordChunks("portrait", portraits) @@ -2845,6 +2852,8 @@ class A2PackPartitions if (!resourceDeps.containsKey(fromKey)) resourceDeps[fromKey] = [] as Set resourceDeps[fromKey] << [toType, toName] + if (toType == "tileSet") + addResourceDep(fromType, fromName, "smTileSet", toName) } def addMapDep(toType, toName) @@ -2867,48 +2876,35 @@ class A2PackPartitions tileFrames[fullName] << tile.@id } - // Then finish each set - tileSets.each { name, tileSet -> finishTileSet(tileNames, tileFrames, tileSet) } + // Then finish each tile set + tileSets.each { name, tileSet -> + // Determine the max # of animation frames + tileSet.buf = packAnimTiles(tileSet, tileNames, tileFrames, tiles) + smTileSets[name].buf = packAnimTiles(tileSet, tileNames, tileFrames, smTiles) + } } - def finishTileSet(tileNames, tileFrames, tileSet) + def packAnimTiles(tileSet, tileNames, tileFrames, tiles) { - // Determine the max # of animation frames def maxFrames = 0 tileSet.tileIds.each { id -> maxFrames = Math.max(maxFrames, tileFrames[tileNames[id]].size) } - //println("tileSet.num=${tileSet.num}, maxFrames=$maxFrames") def animBuf = new AnimBuf() for (int frameNum = 1; frameNum <= maxFrames; frameNum++) { def frameBuf = ByteBuffer.allocate(50000) frameBuf.put((byte)(tileSet.tileIds.size())) - - // First the large size tiles tileSet.tileIds.each { id -> def frames = tileFrames[tileNames[id]] def frame = frames[(frameNum-1) % frames.size()] tiles[frame].flip() // crazy stuff to append one buffer to another frameBuf.put(tiles[frame]) } - - // Then add the small size tiles for automap display - tileSet.tileIds.each { id -> - def frames = tileFrames[tileNames[id]] - def frame = frames[(frameNum-1) % frames.size()] - smTiles[frame].flip() // crazy stuff to append one buffer to another - frameBuf.put(smTiles[frame]) - } - - // Now that we have all the tiles for this frame, put it in the animation buffer - //println(" frame=$frameNum buf.size=${frameBuf.position()}") animBuf.addImage(frameNum, "f", frameBuf) } - - // Make the diffs and do the final packing. - tileSet.buf = compress(animBuf.pack()) + return compress(animBuf.pack()) } def pack(xmlFile, dataIn) diff --git a/Platform/Apple/virtual/src/core/mem.s b/Platform/Apple/virtual/src/core/mem.s index 911e90b5..b944902f 100644 --- a/Platform/Apple/virtual/src/core/mem.s +++ b/Platform/Apple/virtual/src/core/mem.s @@ -2689,6 +2689,8 @@ advanceAnims: !zone { beq .anim cmp #RES_TYPE_TILESET beq .anim + cmp #RES_TYPE_SM_TILESET + beq .anim bne .next ; not animated; skip .anim lda tSegAdrLo,x ; pointer to start of resource sta pTmp diff --git a/Platform/Apple/virtual/src/include/mem.i b/Platform/Apple/virtual/src/include/mem.i index 17e1a5e4..7a3ed78f 100644 --- a/Platform/Apple/virtual/src/include/mem.i +++ b/Platform/Apple/virtual/src/include/mem.i @@ -11,19 +11,20 @@ ;------------------------------------------------------------------------------ ; 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 -RES_TYPE_STORY = $D +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 +RES_TYPE_STORY = $D +RES_TYPE_SM_TILESET = $E ;------------------------------------------------------------------------------ ; Command codes diff --git a/Platform/Apple/virtual/src/plasma/automap.pla b/Platform/Apple/virtual/src/plasma/automap.pla index 5c221424..becb2854 100644 --- a/Platform/Apple/virtual/src/plasma/automap.pla +++ b/Platform/Apple/virtual/src/plasma/automap.pla @@ -597,7 +597,7 @@ def loadMarks()#0 pSpecialsBuf = auxMmgr(QUEUE_LOAD, CODE_GEN_MAP_SPECIALS<<8 | RES_TYPE_CODE) // While we're at it, load the automap special tiles. - specTileset = mmgr(QUEUE_LOAD, 2<<8 | RES_TYPE_TILESET) // always tileset 2 (just after global tiles) + specTileset = mmgr(QUEUE_LOAD, 2<<8 | RES_TYPE_SM_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 @@ -609,8 +609,8 @@ def loadMarks()#0 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 = specTileset + 3 + ((^(specTileset+2)) << 5) + // Figure out where the small versions of the special tiles reside + pSpecialTiles = specTileset + 3 end /////////////////////////////////////////////////////////////////////////////////////////////////// @@ -722,7 +722,7 @@ def prepSections(extraLeft, extraTop)#0 // This part only happens in 2D mode (a 3D section have tileset filled in at construction) pSection->bm_tilesetNum = ^(pSection=>pm_map + 4) fin - pSection=>pm_tileset = mmgr(QUEUE_LOAD, (pSection->bm_tilesetNum)<<8 | RES_TYPE_TILESET) + pSection=>pm_tileset = mmgr(QUEUE_LOAD, (pSection->bm_tilesetNum)<<8 | RES_TYPE_SM_TILESET) fin pSection = pSection + TMapSection loop @@ -839,7 +839,7 @@ def displaySections#0 //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 + 3 + ((^(pSection=>pm_tileset + 2)) << 5) + pSmallTiles = pSection=>pm_tileset + 3 // And draw (different routines to handle differing map data layouts) if mapIs3D @@ -1156,7 +1156,7 @@ def _automap_show(targetX, targetY)#1 // Ensure the global tileset is reloaded (otherwise tile eng will try to load it from wrong partition) mmgr(START_LOAD, 1) - pGlobalTileset = mmgr(QUEUE_LOAD, 1<<8 | RES_TYPE_TILESET) + pGlobalTileset = mmgr(QUEUE_LOAD, 1<<8 | RES_TYPE_SM_TILESET) mmgr(FINISH_LOAD, 0) // All done. diff --git a/Platform/Apple/virtual/src/plasma/gameloop.pla b/Platform/Apple/virtual/src/plasma/gameloop.pla index 37786774..54e93515 100644 --- a/Platform/Apple/virtual/src/plasma/gameloop.pla +++ b/Platform/Apple/virtual/src/plasma/gameloop.pla @@ -2143,14 +2143,14 @@ end /////////////////////////////////////////////////////////////////////////////////////////////////// export def textureControl(flg)#0 flipToPage1 - if flg <> texturesLoaded and renderLoaded and mapIs3D + if flg <> texturesLoaded and renderLoaded if flg _texControl(1) - loadUtil3d - showingLamp = (skyNum == 0 or skyNum == 8) + if mapIs3D; loadUtil3d; fin + showingLamp = mapIs3D and (skyNum == 0 or skyNum == 8) else _texControl(0) - if pModUtil3d and !inScript // e.g. strafe -> script -> combat: need strafe to stay in mem! + if pModUtil3d and mapIs3D and !inScript // e.g. strafe -> script -> combat: need strafe to stay in mem! mmgr(FREE_MEMORY, pModUtil3d) pModUtil3d = NULL util3d = NULL diff --git a/Platform/Apple/virtual/src/plasma/globalDefs.plh b/Platform/Apple/virtual/src/plasma/globalDefs.plh index ef78f681..cb2279ab 100644 --- a/Platform/Apple/virtual/src/plasma/globalDefs.plh +++ b/Platform/Apple/virtual/src/plasma/globalDefs.plh @@ -34,19 +34,20 @@ const BIGWIN_HEIGHT = BIGWIN_BOTTOM - BIGWIN_TOP // Memory manager definitions // Resource types -const RES_TYPE_CODE = 1 -const RES_TYPE_2D_MAP = 2 -const RES_TYPE_3D_MAP = 3 -const RES_TYPE_TILESET = 4 -const RES_TYPE_TEXTURE = 5 -const RES_TYPE_SCREEN = 6 -const RES_TYPE_FONT = 7 -const RES_TYPE_MODULE = 8 -const RES_TYPE_BYTECODE = 9 -const RES_TYPE_FIXUP = 10 -const RES_TYPE_PORTRAIT = 11 -const RES_TYPE_SONG = 12 -const RES_TYPE_STORY = 13 +const RES_TYPE_CODE = 1 +const RES_TYPE_2D_MAP = 2 +const RES_TYPE_3D_MAP = 3 +const RES_TYPE_TILESET = 4 +const RES_TYPE_TEXTURE = 5 +const RES_TYPE_SCREEN = 6 +const RES_TYPE_FONT = 7 +const RES_TYPE_MODULE = 8 +const RES_TYPE_BYTECODE = 9 +const RES_TYPE_FIXUP = 10 +const RES_TYPE_PORTRAIT = 11 +const RES_TYPE_SONG = 12 +const RES_TYPE_STORY = 13 +const RES_TYPE_SM_TILESET = 14 // Command codes const RESET_MEMORY = $10