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 fixups = [:] // module name to fixup.num, fixup.buf
def fooFlg = false
def itemNameToFunc = [:]
def playerNameToFunc = [:]
@ -337,8 +339,8 @@ class A2PackPartitions
}
// Put the results into the buffer
def outBuf = ByteBuffer.allocate(128*18 + 1)
outBuf.put((byte)1) // to start with: 1 frame, no flags
assert dstPos == 128*18
def outBuf = ByteBuffer.allocate(dstPos)
outBuf.put(arr)
// All done. Return the buffer.
@ -775,6 +777,7 @@ class A2PackPartitions
def (name, animFrameNum, animFlags) = decodeImageName(imgEl.@name ?: "img$num")
if (!portraits.containsKey(name)) {
def num = portraits.size() + 1
fooFlg = (num == 1)
portraits[name] = [num:num, anim:new AnimBuf()]
}
portraits[name].anim.addImage(animFrameNum, animFlags, parse126Data(imgEl))
@ -1786,7 +1789,9 @@ class A2PackPartitions
if (!grabEntireFromCache("portraits", portraits, xmlLastMod)) {
portraitImgs.each { image -> packPortrait(image) }
portraits.each { name, portrait ->
println "Packing portrait $name."
fooFlg = (portrait.num == 1)
if (fooFlg)
println "Packing portrait $name."
portrait.buf = portrait.anim.pack()
portrait.anim = null
}
@ -3414,18 +3419,26 @@ end
def addImage(animFrameNum, animFlags, imgBuf)
{
dbg("addImage: $animFrameNum=$animFrameNum size=${imgBuf.position()}")
if (animFrameNum == 1)
this.animFlags = animFlags
buffers << imgBuf
assert animFrameNum == buffers.size() : "Missing animation frame"
}
def dbg(str)
{
if (fooFlg)
System.out.println(str)
}
def pack()
{
def outBuf = ByteBuffer.allocate(50000) // plenty of room
// If no animation, add a stub to the start of the (only) image and return it
assert buffers.size() >= 1
dbg("nBuffers=${buffers.size()}")
if (buffers.size() == 1) {
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
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 >> 8) & 0xFF))
buffers[0].flip()
@ -3447,13 +3462,16 @@ end
case "" : flagByte = 0; break
case "f" : flagByte = 1; 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'")
}
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)(buffers.size() - 1)) // index of last frame
outBuf.put((byte)0) // used to store current anim frame
outBuf.put((byte)(buffers.size())) // number of frames
// Then each patch
buffers[1..-1].each { inBuf ->

View File

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

View File

@ -91,9 +91,9 @@
; bytes 0-1: offset to animation header (or $0000 if not animated)
; bytes 2-n: invariant image data
; 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 2: index of last frame (= number of frames *minus 1*)
; byte 2: number of frames
; byte 3: current anim frame
; Followed by patches. Each 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
; 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
; 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_LIFE_X = 112
const ANIM_FLAG_FWD = $20
const ANIM_FLAG_FWD_BKWD = $40
const ANIM_FLAG_RANDOM = $80
const ANIM_PAUSE_MAX = 300
// Max gold
@ -102,11 +98,8 @@ byte tabBuf[5]
// Animation tracking
word curPortrait = 0
byte animFlags
byte animDir
byte animDirCt
byte animNumFrames
byte animFrame
byte anyAnims = TRUE
word animPauseCt
// Shared string constants
@ -1011,7 +1004,7 @@ export def getUpperKey()
*seed = *seed + 1
animPauseCt = animPauseCt - 1
if animPauseCt < 0
if curPortrait and animNumFrames > 1
if curPortrait and anyAnims
nextAnimFrame()
fin
animPauseCt = ANIM_PAUSE_MAX
@ -1028,7 +1021,7 @@ export def pause(count)
while count >= 0
animPauseCt = animPauseCt - 1
if animPauseCt < 0
if curPortrait and animNumFrames > 1
if curPortrait and anyAnims
nextAnimFrame()
fin
animPauseCt = ANIM_PAUSE_MAX
@ -1689,7 +1682,7 @@ def showAnimFrame()
// Determine data pointer based on current animation frame
if !curPortrait; return; fin
pData = curPortrait + 1 + (animFrame * 2304) // 18*128 = 2304
pData = curPortrait + 2 // skip anim-hdr offset
// Show it on-screen
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
def nextAnimFrame()
word oldAnimFrame
if !curPortrait; return; fin
oldAnimFrame = animFrame
if !curPortrait or !anyAnims; return; fin
// Choose a new direction based on the flags. Do this the first time, and once every 3-7 frames.
animDirCt = animDirCt - 1
if !animDir or 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
if animDirCt <= 0
animDirCt = (rand16() % 5) + 3
fin
// Advance in the current direction
if animDir == 'F' // forward
animFrame = animFrame + 1
if animFrame >= animNumFrames
animFrame = 0
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
// Advance animations.
// First part is whether to switch directions on fwd/back anims.
// Second part is how many frames to advance random anims.
if auxMmgr(ADVANCE_ANIMS, animDirCt==0 | (rand16() % 5))
// Animation is present - display the new frame
showAnimFrame()
else
anyAnims = FALSE
fin
// Reset the animation pause
@ -1779,10 +1746,7 @@ export def setPortrait(portraitNum)
mmgr(START_LOAD, 2) // portraits are in partition 2
curPortrait = auxMmgr(QUEUE_LOAD, portraitNum<<8 | RES_TYPE_PORTRAIT)
mmgr(FINISH_LOAD, 0)
animFrame = 0
animFlags = readAuxByte(curPortrait)
animNumFrames = animFlags & $F
animDir = 0
anyAnims = TRUE // for now; might get cleared if we discover otherwise on advance
animDirCt = 1
animPauseCt = ANIM_PAUSE_MAX

View File

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