Animation progress.

This commit is contained in:
Martin Haye
2016-10-22 08:46:37 -07:00
parent 466cd1923d
commit 2ef692c537
5 changed files with 71 additions and 63 deletions

View File

@@ -72,6 +72,8 @@ class A2PackPartitions
def bytecodes = [:] // module name to bytecode.num, bytecode.buf def bytecodes = [:] // module name to bytecode.num, bytecode.buf
def fixups = [:] // module name to fixup.num, fixup.buf def fixups = [:] // module name to fixup.num, fixup.buf
def fooFlg = false
def itemNameToFunc = [:] def itemNameToFunc = [:]
def playerNameToFunc = [:] def playerNameToFunc = [:]
@@ -337,8 +339,8 @@ class A2PackPartitions
} }
// Put the results into the buffer // Put the results into the buffer
def outBuf = ByteBuffer.allocate(128*18 + 1) assert dstPos == 128*18
outBuf.put((byte)1) // to start with: 1 frame, no flags def outBuf = ByteBuffer.allocate(dstPos)
outBuf.put(arr) outBuf.put(arr)
// All done. Return the buffer. // All done. Return the buffer.
@@ -775,6 +777,7 @@ class A2PackPartitions
def (name, animFrameNum, animFlags) = decodeImageName(imgEl.@name ?: "img$num") def (name, animFrameNum, animFlags) = decodeImageName(imgEl.@name ?: "img$num")
if (!portraits.containsKey(name)) { if (!portraits.containsKey(name)) {
def num = portraits.size() + 1 def num = portraits.size() + 1
fooFlg = (num == 1)
portraits[name] = [num:num, anim:new AnimBuf()] portraits[name] = [num:num, anim:new AnimBuf()]
} }
portraits[name].anim.addImage(animFrameNum, animFlags, parse126Data(imgEl)) portraits[name].anim.addImage(animFrameNum, animFlags, parse126Data(imgEl))
@@ -1786,7 +1789,9 @@ class A2PackPartitions
if (!grabEntireFromCache("portraits", portraits, xmlLastMod)) { if (!grabEntireFromCache("portraits", portraits, xmlLastMod)) {
portraitImgs.each { image -> packPortrait(image) } portraitImgs.each { image -> packPortrait(image) }
portraits.each { name, portrait -> portraits.each { name, portrait ->
println "Packing portrait $name." fooFlg = (portrait.num == 1)
if (fooFlg)
println "Packing portrait $name."
portrait.buf = portrait.anim.pack() portrait.buf = portrait.anim.pack()
portrait.anim = null portrait.anim = null
} }
@@ -3414,18 +3419,26 @@ end
def addImage(animFrameNum, animFlags, imgBuf) def addImage(animFrameNum, animFlags, imgBuf)
{ {
dbg("addImage: $animFrameNum=$animFrameNum size=${imgBuf.position()}")
if (animFrameNum == 1) if (animFrameNum == 1)
this.animFlags = animFlags this.animFlags = animFlags
buffers << imgBuf buffers << imgBuf
assert animFrameNum == buffers.size() : "Missing animation frame" assert animFrameNum == buffers.size() : "Missing animation frame"
} }
def dbg(str)
{
if (fooFlg)
System.out.println(str)
}
def pack() def pack()
{ {
def outBuf = ByteBuffer.allocate(50000) // plenty of room def outBuf = ByteBuffer.allocate(50000) // plenty of room
// If no animation, add a stub to the start of the (only) image and return it // If no animation, add a stub to the start of the (only) image and return it
assert buffers.size() >= 1 assert buffers.size() >= 1
dbg("nBuffers=${buffers.size()}")
if (buffers.size() == 1) { if (buffers.size() == 1) {
outBuf.put((byte)0) outBuf.put((byte)0)
outBuf.put((byte)0) outBuf.put((byte)0)
@@ -3436,6 +3449,8 @@ end
// At start of buffer, put offset to animation header, then the first frame // At start of buffer, put offset to animation header, then the first frame
def offset = buffers[0].position() + 2 // 2 for the offset itself def offset = buffers[0].position() + 2 // 2 for the offset itself
dbg("Initial offset=$offset")
dbg(String.format("First image byte=\$%x", buffers[0].get(0)))
outBuf.put((byte)(offset & 0xFF)) outBuf.put((byte)(offset & 0xFF))
outBuf.put((byte)((offset >> 8) & 0xFF)) outBuf.put((byte)((offset >> 8) & 0xFF))
buffers[0].flip() buffers[0].flip()
@@ -3447,13 +3462,16 @@ end
case "" : flagByte = 0; break case "" : flagByte = 0; break
case "f" : flagByte = 1; break case "f" : flagByte = 1; break
case "fb": flagByte = 2; break case "fb": flagByte = 2; break
case "r" : flagByte = 3; break case "s": flagByte = 3; break
case "r" : flagByte = 4; break
default : throw new Exception("Unrecognized animation flags '$animFlags'") default : throw new Exception("Unrecognized animation flags '$animFlags'")
} }
outBuf.put((byte) flagByte) dbg("flagByte=$flagByte")
dbg("nFrames=${buffers.size()}")
outBuf.put((byte)flagByte)
outBuf.put((byte)1) // used to store current anim dir; start with 1=forward outBuf.put((byte)1) // used to store current anim dir; start with 1=forward
outBuf.put((byte)(buffers.size() - 1)) // index of last frame
outBuf.put((byte)0) // used to store current anim frame outBuf.put((byte)0) // used to store current anim frame
outBuf.put((byte)(buffers.size())) // number of frames
// Then each patch // Then each patch
buffers[1..-1].each { inBuf -> buffers[1..-1].each { inBuf ->

View File

@@ -29,8 +29,8 @@ MAX_SEGS = 96
DO_COMP_CHECKSUMS = 0 ; during compression debugging DO_COMP_CHECKSUMS = 0 ; during compression debugging
DEBUG_DECOMP = 0 DEBUG_DECOMP = 0
DEBUG = 1 DEBUG = 0
SANITY_CHECK = 1 ; also prints out request data SANITY_CHECK = 0 ; also prints out request data
; Zero page temporary variables ; Zero page temporary variables
tmp = $2 ; len 2 tmp = $2 ; len 2
@@ -1442,6 +1442,9 @@ aux_dispatch:
+ cmp #FATAL_ERROR + cmp #FATAL_ERROR
bne + bne +
jmp fatalError jmp fatalError
+ cmp #ADVANCE_ANIMS
bne +
jmp advanceAnims
+ jmp nextLdVec ; Pass command to next chained loader + jmp nextLdVec ; Pass command to next chained loader
;------------------------------------------------------------------------------ ;------------------------------------------------------------------------------
@@ -3002,9 +3005,9 @@ advanceAnims: !zone {
lda #0 lda #0
sta .ret+1 ; clear count of animated sta .ret+1 ; clear count of animated
cli ; no interrupts while we read and write aux mem cli ; no interrupts while we read and write aux mem
sta setAuxRd ; read and ldx isAuxCmd ; grab starting segment for main or aux mem
sta setAuxWr ; write aux mem sta clrAuxRd,x ; read and
ldx #1 ; grab starting segment for aux mem sta clrAuxWr,x ; write aux or main mem, depending on how called
.loop: lda tSegType,x ; segment flags and type .loop: lda tSegType,x ; segment flags and type
bpl .next ; skip non-active bpl .next ; skip non-active
and #$F ; get type and #$F ; get type
@@ -3049,6 +3052,9 @@ advSingleAnim: !zone {
adc pTmp+1 adc pTmp+1
sta tmp+1 sta tmp+1
sta clrAuxRd
brk
jsr applyPatch ; unpatch to get back to base frame data jsr applyPatch ; unpatch to get back to base frame data
.chkr ldy #0 .chkr ldy #0

View File

@@ -91,9 +91,9 @@
; bytes 0-1: offset to animation header (or $0000 if not animated) ; bytes 0-1: offset to animation header (or $0000 if not animated)
; bytes 2-n: invariant image data ; bytes 2-n: invariant image data
; Followed by animation header: ; Followed by animation header:
; byte 0: animation type (1=Forward, 2=Forward+Backward, 3=Random) ; byte 0: animation type (1=Forward, 2=Forward+Backward, 3=Fwd+Stop, 4=Random)
; byte 1: current anim dir ; byte 1: current anim dir
; byte 2: index of last frame (= number of frames *minus 1*) ; byte 2: number of frames
; byte 3: current anim frame ; byte 3: current anim frame
; Followed by patches. Each patch: ; Followed by patches. Each patch:
; bytes 0-1: length of patch (including this length header, and also anim hdr for 1st patch) ; bytes 0-1: length of patch (including this length header, and also anim hdr for 1st patch)
@@ -277,6 +277,25 @@ CHECK_MEM = $1B
; Check that memory manager structures (and heap structures, if a heap ; Check that memory manager structures (and heap structures, if a heap
; has been set) are all intact. ; has been set) are all intact.
;------------------------------------------------------------------------------
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.
; Only applied to resources marked as "random" order.
;
; Output: Number of animated resources found.
;
; Checks for and advances each active animated resource to its next
; frame of animation. They are advanced based on their animation type:
; 1=Forward - e.g. 0 1 2 0 1 2 0 1 2
; 2=Forward+Backward - e.g. 0 1 2 1 0 1 2 1 0
; 3=Forward+Stop - e.g. 0 1 2 2 2 2 2 2 2
; 4=Random - e.g. 0 2 0 1 2 2 0 1 1
;
; Note that only animated resources in the specified memory bank (aux
; or main) are processed.
;------------------------------------------------------------------------------ ;------------------------------------------------------------------------------
CHAIN_LOADER = $1E CHAIN_LOADER = $1E
; Input: X-reg / Y-reg - pointer to loader (X=lo, Y=hi) to add to chain ; Input: X-reg / Y-reg - pointer to loader (X=lo, Y=hi) to add to chain

View File

@@ -21,10 +21,6 @@ const CHAR_WND_GOLD_X = 83
const CHAR_WND_WEAPON_X = 83 const CHAR_WND_WEAPON_X = 83
const CHAR_WND_LIFE_X = 112 const CHAR_WND_LIFE_X = 112
const ANIM_FLAG_FWD = $20
const ANIM_FLAG_FWD_BKWD = $40
const ANIM_FLAG_RANDOM = $80
const ANIM_PAUSE_MAX = 300 const ANIM_PAUSE_MAX = 300
// Max gold // Max gold
@@ -102,11 +98,8 @@ byte tabBuf[5]
// Animation tracking // Animation tracking
word curPortrait = 0 word curPortrait = 0
byte animFlags
byte animDir
byte animDirCt byte animDirCt
byte animNumFrames byte anyAnims = TRUE
byte animFrame
word animPauseCt word animPauseCt
// Shared string constants // Shared string constants
@@ -1011,7 +1004,7 @@ export def getUpperKey()
*seed = *seed + 1 *seed = *seed + 1
animPauseCt = animPauseCt - 1 animPauseCt = animPauseCt - 1
if animPauseCt < 0 if animPauseCt < 0
if curPortrait and animNumFrames > 1 if curPortrait and anyAnims
nextAnimFrame() nextAnimFrame()
fin fin
animPauseCt = ANIM_PAUSE_MAX animPauseCt = ANIM_PAUSE_MAX
@@ -1028,7 +1021,7 @@ export def pause(count)
while count >= 0 while count >= 0
animPauseCt = animPauseCt - 1 animPauseCt = animPauseCt - 1
if animPauseCt < 0 if animPauseCt < 0
if curPortrait and animNumFrames > 1 if curPortrait and anyAnims
nextAnimFrame() nextAnimFrame()
fin fin
animPauseCt = ANIM_PAUSE_MAX animPauseCt = ANIM_PAUSE_MAX
@@ -1689,7 +1682,7 @@ def showAnimFrame()
// Determine data pointer based on current animation frame // Determine data pointer based on current animation frame
if !curPortrait; return; fin if !curPortrait; return; fin
pData = curPortrait + 1 + (animFrame * 2304) // 18*128 = 2304 pData = curPortrait + 2 // skip anim-hdr offset
// Show it on-screen // Show it on-screen
if frameLoaded == 3 // 3D-mode frame? Note: don't check mapIs3D, because we might be in an engine if frameLoaded == 3 // 3D-mode frame? Note: don't check mapIs3D, because we might be in an engine
@@ -1704,48 +1697,22 @@ end
/////////////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////////////
// Advance to next frame of current animation, if any // Advance to next frame of current animation, if any
def nextAnimFrame() def nextAnimFrame()
word oldAnimFrame if !curPortrait or !anyAnims; return; fin
if !curPortrait; return; fin
oldAnimFrame = animFrame
// Choose a new direction based on the flags. Do this the first time, and once every 3-7 frames. // Choose a new direction based on the flags. Do this the first time, and once every 3-7 frames.
animDirCt = animDirCt - 1 animDirCt = animDirCt - 1
if !animDir or animDirCt == 0 if animDirCt <= 0
if animFlags & ANIM_FLAG_FWD
animDir = 'F'
elsif animFlags & ANIM_FLAG_FWD_BKWD
if animDir == 'B'
animDir = 'F'
else
animDir = 'B'
fin
elsif (animFlags & ANIM_FLAG_RANDOM)
animDir = 'R'
else
animDir = 0
fin
animDirCt = (rand16() % 5) + 3 animDirCt = (rand16() % 5) + 3
fin fin
// Advance in the current direction // Advance animations.
if animDir == 'F' // forward // First part is whether to switch directions on fwd/back anims.
animFrame = animFrame + 1 // Second part is how many frames to advance random anims.
if animFrame >= animNumFrames if auxMmgr(ADVANCE_ANIMS, animDirCt==0 | (rand16() % 5))
animFrame = 0 // Animation is present - display the new frame
fin
elsif animDir == 'B' // backward
if animFrame == 0
animFrame = animNumFrames - 1
else
animFrame = animFrame - 1
fin
elsif animDir == 'R' // random
animFrame = rand16() % animNumFrames
fin
// And show it.
if animFrame <> oldAnimFrame
showAnimFrame() showAnimFrame()
else
anyAnims = FALSE
fin fin
// Reset the animation pause // Reset the animation pause
@@ -1779,10 +1746,7 @@ export def setPortrait(portraitNum)
mmgr(START_LOAD, 2) // portraits are in partition 2 mmgr(START_LOAD, 2) // portraits are in partition 2
curPortrait = auxMmgr(QUEUE_LOAD, portraitNum<<8 | RES_TYPE_PORTRAIT) curPortrait = auxMmgr(QUEUE_LOAD, portraitNum<<8 | RES_TYPE_PORTRAIT)
mmgr(FINISH_LOAD, 0) mmgr(FINISH_LOAD, 0)
animFrame = 0 anyAnims = TRUE // for now; might get cleared if we discover otherwise on advance
animFlags = readAuxByte(curPortrait)
animNumFrames = animFlags & $F
animDir = 0
animDirCt = 1 animDirCt = 1
animPauseCt = ANIM_PAUSE_MAX animPauseCt = ANIM_PAUSE_MAX

View File

@@ -50,6 +50,7 @@ const FREE_MEMORY = $18
const CALC_FREE = $19 const CALC_FREE = $19
const DEBUG_MEM = $1A const DEBUG_MEM = $1A
const CHECK_MEM = $1B const CHECK_MEM = $1B
const ADVANCE_ANIMS = $1C
const CHAIN_LOADER = $1E const CHAIN_LOADER = $1E
const FATAL_ERROR = $1F const FATAL_ERROR = $1F
const HEAP_SET = $20 const HEAP_SET = $20