Selectable amount of rewind states no longer dummy. Fixed loading rewind when none left. Todo: make the state prior loadable too.
This commit is contained in:
@@ -55,21 +55,17 @@ EXTSYM fxbit67pcal,SfxSFR,nosprincr,cpucycle,switchtovirqdeb,switchtonmideb
|
|||||||
EXTSYM MovieSeekBehind,SaveSramData,BackupCVFrame,RestoreCVFrame,loadstate
|
EXTSYM MovieSeekBehind,SaveSramData,BackupCVFrame,RestoreCVFrame,loadstate
|
||||||
EXTSYM KeyInsrtChap,KeyNextChap,KeyPrevChap,MovieInsertChapter,MovieSeekAhead
|
EXTSYM KeyInsrtChap,KeyNextChap,KeyPrevChap,MovieInsertChapter,MovieSeekAhead
|
||||||
EXTSYM ResetDuringMovie,EMUPauseKey,INCRFrameKey,MovieWaiting,NoInputRead
|
EXTSYM ResetDuringMovie,EMUPauseKey,INCRFrameKey,MovieWaiting,NoInputRead
|
||||||
|
EXTSYM AllocatedRewindStates
|
||||||
|
|
||||||
%ifdef __MSDOS__
|
%ifdef __MSDOS__
|
||||||
EXTSYM dssel
|
EXTSYM dssel
|
||||||
%endif
|
%endif
|
||||||
|
|
||||||
SECTION .data
|
SECTION .data
|
||||||
NEWSYM CBackupPos, dd 0
|
|
||||||
NEWSYM PBackupPos, dd 0
|
|
||||||
NEWSYM tempedx, dd 0
|
NEWSYM tempedx, dd 0
|
||||||
NEWSYM tempesi, dd 0
|
NEWSYM tempesi, dd 0
|
||||||
NEWSYM tempedi, dd 0
|
NEWSYM tempedi, dd 0
|
||||||
NEWSYM tempebp, dd 0
|
NEWSYM tempebp, dd 0
|
||||||
NEWSYM RewindOldPos, dd 0
|
|
||||||
NEWSYM RewindPos, dd 0
|
|
||||||
NEWSYM RewindTimer, dd 0
|
NEWSYM RewindTimer, dd 0
|
||||||
NEWSYM BackState, db 1
|
NEWSYM BackState, db 1
|
||||||
NEWSYM BackStateSize, dd 6
|
NEWSYM BackStateSize, dd 6
|
||||||
@@ -96,76 +92,39 @@ NEWSYM ProcessRewind
|
|||||||
cmp byte[pressed+eax],1
|
cmp byte[pressed+eax],1
|
||||||
jne near .notokay
|
jne near .notokay
|
||||||
mov byte[pressed+eax],2
|
mov byte[pressed+eax],2
|
||||||
mov eax,[RewindOldPos]
|
|
||||||
cmp [RewindPos],eax
|
|
||||||
je near .notokay
|
|
||||||
dec dword[RewindPos]
|
|
||||||
and dword[RewindPos],0Fh
|
|
||||||
mov eax,[RewindOldPos]
|
|
||||||
cmp [RewindPos],eax
|
|
||||||
je .notokay2
|
|
||||||
dec dword[RewindPos]
|
|
||||||
and dword[RewindPos],0Fh
|
|
||||||
mov eax,[RewindPos]
|
|
||||||
mov [PBackupPos],eax
|
|
||||||
push ecx
|
|
||||||
push ebx
|
|
||||||
pushad
|
pushad
|
||||||
call RestoreCVFrame
|
call RestoreCVFrame
|
||||||
popad
|
popad
|
||||||
|
|
||||||
mov esi,[tempesi]
|
mov esi,[tempesi]
|
||||||
mov edi,[tempedi]
|
mov edi,[tempedi]
|
||||||
mov ebp,[tempebp]
|
mov ebp,[tempebp]
|
||||||
; Clear Cache Check
|
|
||||||
mov ebx,vidmemch2
|
|
||||||
mov ecx,4096+4096+4096
|
|
||||||
.next
|
|
||||||
mov byte[ebx],1
|
|
||||||
inc ebx
|
|
||||||
dec ecx
|
|
||||||
jnz .next
|
|
||||||
pop ebx
|
|
||||||
pop ecx
|
|
||||||
inc dword[RewindPos]
|
|
||||||
and dword[RewindPos],0Fh
|
|
||||||
mov edx,[tempedx]
|
mov edx,[tempedx]
|
||||||
.notokay
|
.notokay
|
||||||
ret
|
ret
|
||||||
.notokay2
|
|
||||||
inc dword[RewindPos]
|
|
||||||
and dword[RewindPos],0Fh
|
|
||||||
ret
|
|
||||||
|
|
||||||
NEWSYM UpdateRewind
|
NEWSYM UpdateRewind
|
||||||
push eax
|
cmp byte[AllocatedRewindStates],0
|
||||||
|
je .norewinds
|
||||||
cmp dword[KeyRewind],0
|
cmp dword[KeyRewind],0
|
||||||
je .notftimer
|
je .norewinds
|
||||||
call ProcessRewind
|
|
||||||
dec dword[RewindTimer]
|
dec dword[RewindTimer]
|
||||||
jnz .notftimer
|
jnz .checkrewind
|
||||||
jmp .okay
|
|
||||||
.notftimer
|
|
||||||
pop eax
|
|
||||||
ret
|
|
||||||
.okay
|
|
||||||
mov eax,[RewindPos]
|
|
||||||
mov [CBackupPos],eax
|
|
||||||
mov [tempedx],edx
|
mov [tempedx],edx
|
||||||
mov [tempesi],esi
|
mov [tempesi],esi
|
||||||
mov [tempedi],edi
|
mov [tempedi],edi
|
||||||
mov [tempebp],ebp
|
mov [tempebp],ebp
|
||||||
|
|
||||||
pushad
|
pushad
|
||||||
call BackupCVFrame
|
call BackupCVFrame
|
||||||
popad
|
popad
|
||||||
inc dword[RewindPos]
|
|
||||||
and dword[RewindPos],0Fh
|
.checkrewind
|
||||||
mov eax,[RewindOldPos]
|
call ProcessRewind
|
||||||
cmp [RewindPos],eax
|
.norewinds
|
||||||
jne .noteq
|
|
||||||
inc dword[RewindOldPos]
|
|
||||||
and dword[RewindOldPos],0Fh
|
|
||||||
.noteq
|
|
||||||
pop eax
|
|
||||||
ret
|
ret
|
||||||
|
|
||||||
SECTION .data
|
SECTION .data
|
||||||
|
|||||||
@@ -192,47 +192,51 @@ static void memcpyrinc(unsigned char **src, void *dest, size_t len)
|
|||||||
|
|
||||||
extern unsigned int RewindTimer;
|
extern unsigned int RewindTimer;
|
||||||
extern unsigned char RewindStates;
|
extern unsigned char RewindStates;
|
||||||
|
|
||||||
unsigned char *StateBackup = 0;
|
unsigned char *StateBackup = 0;
|
||||||
|
unsigned char AllocatedRewindStates, LatestRewindPos, EarliestRewindPos;
|
||||||
|
|
||||||
size_t rewind_state_size, cur_zst_size, old_zst_size;
|
size_t rewind_state_size, cur_zst_size, old_zst_size;
|
||||||
|
|
||||||
/* A nice idea, but needs more ported from the assembly first.
|
extern unsigned char RewindFrames, romispal;
|
||||||
size_t RewindPos, RewindEarliestPos;
|
extern unsigned char MovieProcessing;
|
||||||
|
void zmv_rewind_save(size_t, bool);
|
||||||
|
void zmv_rewind_load(size_t, bool);
|
||||||
|
|
||||||
|
#define ActualRewindFrames (RewindFrames * (romispal ? 25 : 30))
|
||||||
|
|
||||||
void BackupCVFrame()
|
void BackupCVFrame()
|
||||||
{
|
{
|
||||||
unsigned char *RewindBufferPos = StateBackup + RewindPos*rewind_state_size;
|
unsigned char *RewindBufferPos = StateBackup + LatestRewindPos*rewind_state_size;
|
||||||
printf("Backing up rewind in slot #%u\n", RewindPos);
|
printf("Backing up rewind in slot #%u\n", LatestRewindPos);
|
||||||
|
|
||||||
|
if (MovieProcessing == 1) { zmv_rewind_save(LatestRewindPos, true); }
|
||||||
|
else if (MovieProcessing == 2) { zmv_rewind_save(LatestRewindPos, false); }
|
||||||
copy_state_data(RewindBufferPos, memcpyinc, false);
|
copy_state_data(RewindBufferPos, memcpyinc, false);
|
||||||
RewindPos++;
|
|
||||||
if (RewindPos == RewindStates)
|
LatestRewindPos = (LatestRewindPos != AllocatedRewindStates-1) ? LatestRewindPos+1 : 0;
|
||||||
|
if (LatestRewindPos == EarliestRewindPos)
|
||||||
{
|
{
|
||||||
RewindPos = 0;
|
EarliestRewindPos = (EarliestRewindPos != AllocatedRewindStates-1) ? EarliestRewindPos+1 : 0;
|
||||||
}
|
}
|
||||||
if (RewindPos == RewindEarliestPos)
|
|
||||||
{
|
RewindTimer = ActualRewindFrames;
|
||||||
RewindEarliestPos++;
|
|
||||||
if (RewindEarliestPos == RewindStates)
|
|
||||||
{
|
|
||||||
RewindEarliestPos = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
RewindTimer = 60*3;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void RestoreCVFrame()
|
void RestoreCVFrame()
|
||||||
{
|
|
||||||
if (RewindPos != RewindEarliestPos)
|
|
||||||
{
|
{
|
||||||
unsigned char *RewindBufferPos;
|
unsigned char *RewindBufferPos;
|
||||||
|
|
||||||
if (!RewindPos)
|
if (LatestRewindPos != EarliestRewindPos)
|
||||||
{
|
{
|
||||||
RewindPos = RewindStates;
|
LatestRewindPos = (LatestRewindPos) ? LatestRewindPos-1 : AllocatedRewindStates-1;
|
||||||
}
|
}
|
||||||
RewindPos--;
|
|
||||||
|
|
||||||
RewindBufferPos = StateBackup + RewindPos*rewind_state_size;
|
RewindBufferPos = StateBackup + LatestRewindPos*rewind_state_size;
|
||||||
printf("Restoring rewind in slot #%u\n", RewindPos);
|
printf("Restoring rewind in slot #%u\n", LatestRewindPos);
|
||||||
|
|
||||||
|
if (MovieProcessing == 1) { zmv_rewind_load(LatestRewindPos, true); }
|
||||||
|
else if (MovieProcessing == 2) { zmv_rewind_load(LatestRewindPos, false); }
|
||||||
copy_state_data(RewindBufferPos, memcpyrinc, true);
|
copy_state_data(RewindBufferPos, memcpyrinc, true);
|
||||||
|
|
||||||
//Clear Cache Check
|
//Clear Cache Check
|
||||||
@@ -240,27 +244,7 @@ void RestoreCVFrame()
|
|||||||
memset(vidmemch4, 1, sizeof(vidmemch4));
|
memset(vidmemch4, 1, sizeof(vidmemch4));
|
||||||
memset(vidmemch8, 1, sizeof(vidmemch8));
|
memset(vidmemch8, 1, sizeof(vidmemch8));
|
||||||
|
|
||||||
RewindTimer = 60*3;
|
RewindTimer = ActualRewindFrames;
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void MultipleFrameBack(unsigned int i)
|
|
||||||
{
|
|
||||||
while (i--)
|
|
||||||
{
|
|
||||||
if (RewindPos != RewindEarliestPos)
|
|
||||||
{
|
|
||||||
if (!RewindPos)
|
|
||||||
{
|
|
||||||
RewindPos = RewindStates;
|
|
||||||
}
|
|
||||||
RewindPos--;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetupRewindBuffer()
|
void SetupRewindBuffer()
|
||||||
@@ -272,47 +256,7 @@ void SetupRewindBuffer()
|
|||||||
StateBackup = (unsigned char *)malloc(rewind_state_size*RewindStates);
|
StateBackup = (unsigned char *)malloc(rewind_state_size*RewindStates);
|
||||||
if (StateBackup) { break; }
|
if (StateBackup) { break; }
|
||||||
}
|
}
|
||||||
}
|
AllocatedRewindStates = RewindStates;
|
||||||
*/
|
|
||||||
|
|
||||||
extern unsigned int CBackupPos, PBackupPos, RewindPos, RewindOldPos;
|
|
||||||
extern unsigned char RewindFrames, romispal;
|
|
||||||
extern unsigned char MovieProcessing;
|
|
||||||
void zmv_rewind_save(size_t, bool);
|
|
||||||
void zmv_rewind_load(size_t, bool);
|
|
||||||
|
|
||||||
#define ActualRewindFrames (RewindFrames * (romispal ? 25 : 30))
|
|
||||||
|
|
||||||
void BackupCVFrame()
|
|
||||||
{
|
|
||||||
unsigned char *RewindBufferPos = StateBackup + CBackupPos*rewind_state_size;
|
|
||||||
//printf("Backing up rewind in slot #%u\n", CBackupPos);
|
|
||||||
copy_state_data(RewindBufferPos, memcpyinc, false);
|
|
||||||
if (MovieProcessing == 1) { zmv_rewind_save(CBackupPos, true); }
|
|
||||||
else if (MovieProcessing == 2) { zmv_rewind_save(CBackupPos, false); }
|
|
||||||
RewindTimer = ActualRewindFrames;
|
|
||||||
}
|
|
||||||
|
|
||||||
void RestoreCVFrame()
|
|
||||||
{
|
|
||||||
unsigned char *RewindBufferPos = StateBackup + PBackupPos*rewind_state_size;
|
|
||||||
//printf("Restoring rewind in slot #%u\n", PBackupPos);
|
|
||||||
copy_state_data(RewindBufferPos, memcpyrinc, true);
|
|
||||||
if (MovieProcessing == 1) { zmv_rewind_load(PBackupPos, true); }
|
|
||||||
else if (MovieProcessing == 2) { zmv_rewind_load(PBackupPos, false); }
|
|
||||||
RewindTimer = ActualRewindFrames;
|
|
||||||
}
|
|
||||||
|
|
||||||
void SetupRewindBuffer()
|
|
||||||
{
|
|
||||||
if (StateBackup){ free(StateBackup); }
|
|
||||||
RewindStates = 16;
|
|
||||||
StateBackup = 0;
|
|
||||||
StateBackup = (unsigned char *)malloc(rewind_state_size*RewindStates);
|
|
||||||
if (!StateBackup)
|
|
||||||
{
|
|
||||||
asm_call(outofmemory);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static size_t state_size;
|
static size_t state_size;
|
||||||
@@ -324,18 +268,15 @@ static void state_size_tally(unsigned char **dest, void *src, size_t len)
|
|||||||
|
|
||||||
void InitRewindVars()
|
void InitRewindVars()
|
||||||
{
|
{
|
||||||
#ifndef __MSDOS__ //When all the code is ported to C, we can make this work with DOS too
|
|
||||||
unsigned char almost_useless_array[1]; //An array is needed for copy_state_data to give the correct size
|
unsigned char almost_useless_array[1]; //An array is needed for copy_state_data to give the correct size
|
||||||
state_size = 0;
|
state_size = 0;
|
||||||
copy_state_data(almost_useless_array, state_size_tally, false);
|
copy_state_data(almost_useless_array, state_size_tally, false);
|
||||||
rewind_state_size = state_size;
|
rewind_state_size = state_size;
|
||||||
|
|
||||||
SetupRewindBuffer();
|
SetupRewindBuffer();
|
||||||
RewindPos = 0;
|
LatestRewindPos = 0;
|
||||||
RewindOldPos = 0;
|
EarliestRewindPos = 0;
|
||||||
//RewindEarliestPos = 0;
|
RewindTimer = 1;
|
||||||
RewindTimer = ActualRewindFrames;
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//This is used to preserve system load state between loads
|
//This is used to preserve system load state between loads
|
||||||
|
|||||||
Reference in New Issue
Block a user