Files
slippi-ssbm-asm/Recording/FlushFrameBuffer.asm
2021-07-27 17:24:15 -07:00

98 lines
3.1 KiB
NASM

################################################################################
# Address: 803219ec
################################################################################
.include "Common/Common.s"
.include "Recording/Recording.s"
.include "Online/Online.s"
################################################################################
# Routine: FlushFrameBuffer
# ------------------------------------------------------------------------------
# Description: Flush the buffer once per frame to actually send the frame data
################################################################################
# struct offsets
.set OFST_CMD,0x0
.set OFST_FRAME,OFST_CMD+0x1
.set OFST_LATEST_FINALIZED_FRAME,OFST_FRAME+0x4
.set BOOKEND_STRUCT_SIZE,OFST_LATEST_FINALIZED_FRAME+0x4
# registers
.set REG_Buffer,30
.set REG_BufferOffset,29
.set REG_WritePos,28
backup
#Check if VS Mode
branchl r12,FN_ShouldRecord
cmpwi r3,0x0
beq Injection_Exit
# get buffer
lwz r3, primaryDataBuffer(r13)
lwz REG_Buffer, RDB_TXB_ADDRESS(r3)
lwz REG_BufferOffset,bufferOffset(r13)
add REG_WritePos,REG_Buffer,REG_BufferOffset
# check if buffer length is 0
cmpwi REG_BufferOffset,0
beq Injection_Exit
# add frame bookend to transfer buffer
# send data
# initial RNG command byte
li r3,CMD_FRAME_BOOKEND
stb r3,OFST_CMD(REG_WritePos)
# send frame count
lwz r3,frameIndex(r13)
stw r3,OFST_FRAME(REG_WritePos)
# send the latest finalized frame index. This is only relevant during rollback
# where we continue on with frames when their contents may change later.
# Having this here helps any kind of real-time system listening to the file
# wait until a frame will no longer change before processing it
getMinorMajor r3
cmpwi r3, SCENE_ONLINE_IN_GAME
lwz r3,frameIndex(r13)
bne WRITE_FINALIZED_FRAME
# Convert latest online frame index to replay frame index format
lwz r5, OFST_R13_ODB_ADDR(r13) # data buffer address
lbz r4, ODB_IS_DISCONNECTED(r5)
cmpwi r4, 0
bne WRITE_FINALIZED_FRAME # If disconnected, just write the current frame
lbz r4, ODB_IS_GAME_OVER(r5)
cmpwi r4, 0
bne WRITE_FINALIZED_FRAME # If game is over, just write the current frame
lwz r4, ODB_STABLE_FINALIZED_FRAME(r5)
addi r4, r4, CONST_FirstFrameIdx
lwz r7, ODB_PAUSE_COUNTER(r5)
sub r4, r4, r7
cmpw r4, r3
# If latest frame greater than current frame, use current. This could happen in the case where
# we have really low ping and have received frames we are not ready to use yet. I think in
# practice, Dolphin doesn't ever return a frame greater than the current frame, but still safer
# to have this here
bge WRITE_FINALIZED_FRAME
mr r3, r4
WRITE_FINALIZED_FRAME:
stw r3,OFST_LATEST_FINALIZED_FRAME(REG_WritePos)
# increment buffer offset, we dont need to write it to memory because it's
# about to get cleared anyway
addi REG_BufferOffset,REG_BufferOffset,BOOKEND_STRUCT_SIZE
#------------- Transfer Buffer ------------
mr r3,REG_Buffer
mr r4,REG_BufferOffset
li r5,CONST_ExiWrite
branchl r12,FN_EXITransferBuffer
# reset buffer offset
li r3,0
stw r3,bufferOffset(r13)
Injection_Exit:
restore
lwz r0, 0x001C (sp)