Added RLE to ZMV, prepared for command bit, cleaned up rewind.

This commit is contained in:
n-a-c-h
2005-03-31 10:27:28 +00:00
parent a5664e01bf
commit d9ea9d0c64

View File

@@ -487,6 +487,7 @@ static struct
struct internal_chapter_buf internal_chapters; struct internal_chapter_buf internal_chapters;
size_t last_internal_chapter_offset; size_t last_internal_chapter_offset;
char *filename; char *filename;
size_t rle_count;
} zmv_vars; } zmv_vars;
static void save_last_joy_state(unsigned char *buffer) static void save_last_joy_state(unsigned char *buffer)
@@ -529,6 +530,23 @@ static void flush_input_buffer()
fwrite(zmv_vars.write_buffer, zmv_vars.write_buffer_loc, 1, zmv_vars.fp); fwrite(zmv_vars.write_buffer, zmv_vars.write_buffer_loc, 1, zmv_vars.fp);
zmv_vars.write_buffer_loc = 0; zmv_vars.write_buffer_loc = 0;
} }
if (zmv_vars.rle_count)
{
if (zmv_vars.rle_count > 5)
{
zmv_vars.write_buffer[0] = BIT(1); //RLE bit
fwrite(zmv_vars.write_buffer, 1, 1, zmv_vars.fp);
fwrite4(zmv_vars.header.frames, zmv_vars.fp);
}
else
{
memset(zmv_vars.write_buffer, 0, zmv_vars.rle_count);
fwrite(zmv_vars.write_buffer, zmv_vars.rle_count, 1, zmv_vars.fp);
}
zmv_vars.rle_count = 0;
}
zmv_vars.header.author_len = 0; //If we're writing, then author is erased if there zmv_vars.header.author_len = 0; //If we're writing, then author is erased if there
} }
@@ -604,8 +622,6 @@ static void zmv_record(bool slow, unsigned char combos_used)
unsigned char press_buf[] = { 0, 0, 0, 0, 0, 0, 0, 0 }; unsigned char press_buf[] = { 0, 0, 0, 0, 0, 0, 0, 0 };
unsigned char nibble = 0; unsigned char nibble = 0;
zmv_vars.header.frames++;
if (slow) { zmv_vars.header.slow_frames++; } if (slow) { zmv_vars.header.slow_frames++; }
zmv_vars.header.key_combos += combos_used; zmv_vars.header.key_combos += combos_used;
@@ -616,20 +632,40 @@ static void zmv_record(bool slow, unsigned char combos_used)
RECORD_PAD(zmv_vars.last_joy_state.D, JoyDOrig, 4); RECORD_PAD(zmv_vars.last_joy_state.D, JoyDOrig, 4);
RECORD_PAD(zmv_vars.last_joy_state.E, JoyEOrig, 3); RECORD_PAD(zmv_vars.last_joy_state.E, JoyEOrig, 3);
zmv_vars.write_buffer[zmv_vars.write_buffer_loc] = flag;
zmv_vars.write_buffer_loc++;
if (flag) if (flag)
{ {
unsigned char buffer_used = (nibble/2) + (nibble&1); unsigned char buffer_used = (nibble/2) + (nibble&1);
memcpy(zmv_vars.write_buffer+zmv_vars.write_buffer_loc, press_buf, buffer_used);
zmv_vars.write_buffer_loc += buffer_used; if (zmv_vars.rle_count)
{
if (zmv_vars.rle_count > 5)
{
zmv_vars.write_buffer[zmv_vars.write_buffer_loc++] = BIT(1); //RLE bit
memcpy(zmv_vars.write_buffer+zmv_vars.write_buffer_loc, uint32_to_bytes(zmv_vars.header.frames), 4);
zmv_vars.write_buffer_loc += 4;
}
else
{
memset(zmv_vars.write_buffer+zmv_vars.write_buffer_loc, 0, zmv_vars.rle_count);
zmv_vars.write_buffer_loc += zmv_vars.rle_count;
}
zmv_vars.rle_count = 0;
} }
if (zmv_vars.write_buffer_loc > WRITE_BUFFER_SIZE - (1+sizeof(press_buf))) zmv_vars.write_buffer[zmv_vars.write_buffer_loc++] = flag;
memcpy(zmv_vars.write_buffer+zmv_vars.write_buffer_loc, press_buf, buffer_used);
zmv_vars.write_buffer_loc += buffer_used;
if (zmv_vars.write_buffer_loc > WRITE_BUFFER_SIZE - (6+sizeof(press_buf)))
{ {
flush_input_buffer(); flush_input_buffer();
} }
}
else
{
zmv_vars.rle_count++;
}
zmv_vars.header.frames++;
} }
static bool zmv_insert_chapter() static bool zmv_insert_chapter()
@@ -766,6 +802,8 @@ static bool zmv_open(char *filename)
return(false); return(false);
} }
#define RESTORE_PAD(cur, prev) cur = (((unsigned int)prev) << 20) | 0x8000
#define REPLAY_PAD(prev, cur, bit) \ #define REPLAY_PAD(prev, cur, bit) \
if (flag & BIT(bit)) \ if (flag & BIT(bit)) \
{ \ { \
@@ -785,23 +823,46 @@ static bool zmv_open(char *filename)
mid_byte = true; \ mid_byte = true; \
} \ } \
} \ } \
cur = (((unsigned int)prev) << 20) | 0x8000; RESTORE_PAD(cur, prev)
static bool zmv_replay() static bool zmv_replay()
{ {
if (zmv_open_vars.frames_replayed < zmv_vars.header.frames) if (zmv_open_vars.frames_replayed < zmv_vars.header.frames)
{
if (zmv_vars.rle_count)
{
RESTORE_PAD(JoyAOrig, zmv_vars.last_joy_state.A);
RESTORE_PAD(JoyBOrig, zmv_vars.last_joy_state.B);
RESTORE_PAD(JoyCOrig, zmv_vars.last_joy_state.C);
RESTORE_PAD(JoyDOrig, zmv_vars.last_joy_state.D);
RESTORE_PAD(JoyEOrig, zmv_vars.last_joy_state.E);
zmv_vars.rle_count--;
}
else
{ {
unsigned char flag = 0; unsigned char flag = 0;
unsigned char byte; unsigned char byte;
bool mid_byte = false; bool mid_byte = false;
zmv_vars.rle_count = 0;
fread(&flag, 1, 1, zmv_vars.fp); fread(&flag, 1, 1, zmv_vars.fp);
if (flag & BIT(2)) if (flag & BIT(0)) //Command
{
return(zmv_replay());
}
if (flag & BIT(1)) //RLE
{
zmv_vars.rle_count = fread4(zmv_vars.fp) - zmv_open_vars.frames_replayed;
return(zmv_replay());
}
if (flag & BIT(2)) //Internal Chapter
{ {
fseek(zmv_vars.fp, INT_CHAP_SIZE, SEEK_CUR); fseek(zmv_vars.fp, INT_CHAP_SIZE, SEEK_CUR);
fread(&flag, 1, 1, zmv_vars.fp); return(zmv_replay());
} }
REPLAY_PAD(zmv_vars.last_joy_state.A, JoyAOrig, 7); REPLAY_PAD(zmv_vars.last_joy_state.A, JoyAOrig, 7);
@@ -809,7 +870,7 @@ static bool zmv_replay()
REPLAY_PAD(zmv_vars.last_joy_state.C, JoyCOrig, 5); REPLAY_PAD(zmv_vars.last_joy_state.C, JoyCOrig, 5);
REPLAY_PAD(zmv_vars.last_joy_state.D, JoyDOrig, 4); REPLAY_PAD(zmv_vars.last_joy_state.D, JoyDOrig, 4);
REPLAY_PAD(zmv_vars.last_joy_state.E, JoyEOrig, 3); REPLAY_PAD(zmv_vars.last_joy_state.E, JoyEOrig, 3);
}
zmv_open_vars.frames_replayed++; zmv_open_vars.frames_replayed++;
return(true); return(true);
} }
@@ -857,6 +918,7 @@ static bool zmv_next_chapter()
fseek(zmv_vars.fp, next_external, SEEK_SET); fseek(zmv_vars.fp, next_external, SEEK_SET);
} }
zmv_vars.rle_count = 0;
return(true); return(true);
} }
return(false); return(false);
@@ -868,6 +930,7 @@ static void zmv_rewind_playback()
zst_load(zmv_vars.fp); zst_load(zmv_vars.fp);
zmv_open_vars.frames_replayed = 0; zmv_open_vars.frames_replayed = 0;
zmv_open_vars.last_chapter_frame = 0; zmv_open_vars.last_chapter_frame = 0;
zmv_vars.rle_count = 0;
} }
static void zmv_prev_chapter() static void zmv_prev_chapter()
@@ -943,6 +1006,7 @@ static void zmv_prev_chapter()
fseek(zmv_vars.fp, prev_external, SEEK_SET); fseek(zmv_vars.fp, prev_external, SEEK_SET);
} }
zmv_open_vars.last_chapter_frame = zmv_open_vars.frames_replayed; zmv_open_vars.last_chapter_frame = zmv_open_vars.frames_replayed;
zmv_vars.rle_count = 0;
} }
static void zmv_add_chapter() static void zmv_add_chapter()
@@ -1015,6 +1079,14 @@ static void zmv_replay_to_record()
zmv_vars.header.frames = zmv_open_vars.frames_replayed; zmv_vars.header.frames = zmv_open_vars.frames_replayed;
zmv_vars.header.internal_chapters = internal_chapter_delete_after(&zmv_vars.internal_chapters, ftell(zmv_vars.fp)); zmv_vars.header.internal_chapters = internal_chapter_delete_after(&zmv_vars.internal_chapters, ftell(zmv_vars.fp));
zmv_vars.last_internal_chapter_offset = internal_chapter_lesser(&zmv_vars.internal_chapters, ~0); zmv_vars.last_internal_chapter_offset = internal_chapter_lesser(&zmv_vars.internal_chapters, ~0);
if (zmv_vars.rle_count)
{
fseek(zmv_vars.fp, -4, SEEK_CUR);
fwrite4(zmv_vars.header.frames, zmv_vars.fp);
zmv_vars.rle_count = 0;
}
ftruncate(fileno(zmv_vars.fp), ftell(zmv_vars.fp)); ftruncate(fileno(zmv_vars.fp), ftell(zmv_vars.fp));
} }
@@ -1029,11 +1101,20 @@ Rewind related functions and vars
*/ */
unsigned char *zmv_rewind_buffer = 0; struct zmv_rewind
{
unsigned char last_joy_state[8];
size_t file_pos;
unsigned int frames;
size_t rle_count;
};
struct zmv_rewind *zmv_rewind_buffer = 0;
static void zmv_alloc_rewind_buffer(unsigned char rewind_states) static void zmv_alloc_rewind_buffer(unsigned char rewind_states)
{ {
zmv_rewind_buffer = (unsigned char *)malloc(16*rewind_states); zmv_rewind_buffer = (struct zmv_rewind *)malloc(sizeof(struct zmv_rewind)*rewind_states);
} }
static void zmv_dealloc_rewind_buffer() static void zmv_dealloc_rewind_buffer()
@@ -1047,37 +1128,32 @@ static void zmv_dealloc_rewind_buffer()
void zmv_rewind_save(size_t state, bool playback) void zmv_rewind_save(size_t state, bool playback)
{ {
unsigned char *state_start_pos = zmv_rewind_buffer + 16*state; save_last_joy_state(zmv_rewind_buffer[state].last_joy_state);
size_t file_pos = ftell(zmv_vars.fp) + zmv_vars.write_buffer_loc; zmv_rewind_buffer[state].file_pos = ftell(zmv_vars.fp) + zmv_vars.write_buffer_loc;
zmv_rewind_buffer[state].frames = playback ? zmv_open_vars.frames_replayed : zmv_vars.header.frames;
save_last_joy_state(state_start_pos); zmv_rewind_buffer[state].rle_count = zmv_vars.rle_count;
memcpy(state_start_pos+8, &file_pos, 4);
memcpy(state_start_pos+12, playback ? &zmv_open_vars.frames_replayed : &zmv_vars.header.frames, 4);
} }
void zmv_rewind_load(size_t state, bool playback) void zmv_rewind_load(size_t state, bool playback)
{ {
unsigned char *state_start_pos = zmv_rewind_buffer + 16*state; size_t file_pos = zmv_rewind_buffer[state].file_pos;
size_t file_pos = 0; load_last_joy_state(zmv_rewind_buffer[state].last_joy_state);
load_last_joy_state(state_start_pos);
memcpy(&file_pos, state_start_pos+8, 4);
if (playback) if (playback)
{ {
memcpy(&zmv_open_vars.frames_replayed, state_start_pos+12, 4); zmv_open_vars.frames_replayed = zmv_rewind_buffer[state].frames;
fseek(zmv_vars.fp, file_pos, SEEK_SET); fseek(zmv_vars.fp, file_pos, SEEK_SET);
zmv_vars.rle_count = zmv_rewind_buffer[state].rle_count;
} }
else else
{ {
size_t frame = 0;
memcpy(&frame, state_start_pos+12, 4);
zmv_vars.header.rerecords++;
zmv_vars.header.removed_frames += zmv_vars.header.frames - frame;
zmv_vars.header.frames = frame;
flush_input_buffer(); flush_input_buffer();
zmv_vars.header.rerecords++;
zmv_vars.header.removed_frames += zmv_vars.header.frames - zmv_rewind_buffer[state].frames;
zmv_vars.header.frames = zmv_rewind_buffer[state].frames;
zmv_vars.rle_count = zmv_rewind_buffer[state].rle_count;
fseek(zmv_vars.fp, file_pos, SEEK_SET); fseek(zmv_vars.fp, file_pos, SEEK_SET);
ftruncate(fileno(zmv_vars.fp), file_pos); ftruncate(fileno(zmv_vars.fp), file_pos);
@@ -1221,6 +1297,8 @@ bool mzt_load(char *statename, bool playback)
rewind_point = fread4(fp); rewind_point = fread4(fp);
fclose(fp); fclose(fp);
zmv_vars.rle_count = 0;
if (!playback) if (!playback)
{ {
gzFile gzp = 0; gzFile gzp = 0;