mirror of
https://github.com/project-slippi/slippi-ssbm-asm.git
synced 2025-10-05 23:52:43 +02:00
98 lines
3.1 KiB
NASM
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)
|