Commiting some movie work now because I'm paranoid, code not entirely stable though.
This commit is contained in:
@@ -48,6 +48,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
extern unsigned int versionNumber, CRC32, cur_zst_size;
|
||||
extern unsigned int JoyAOrig, JoyBOrig, JoyCOrig, JoyDOrig, JoyEOrig;
|
||||
extern unsigned char pl1contrl, pl2contrl, pl3contrl, pl4contrl, pl5contrl;
|
||||
extern unsigned int MsgCount, MessageOn;
|
||||
extern unsigned char MovieStartMethod, GUIReset, ReturnFromSPCStall, GUIQuit;
|
||||
extern unsigned char MovieProcessing, *Msgptr, fnamest[512];
|
||||
@@ -71,7 +72,7 @@ bool zst_load(FILE *);
|
||||
print_bin(JoyEOrig, &usede); printf("\n");
|
||||
|
||||
static unsigned int useda, usedb, usedc, usedd, usede;
|
||||
void print_bin(unsigned int num, unsigned int *used)
|
||||
static void print_bin(unsigned int num, unsigned int *used)
|
||||
{
|
||||
unsigned int mask = BIT(31);
|
||||
while (mask)
|
||||
@@ -115,6 +116,16 @@ Header
|
||||
2 bytes - Number of internal chapters
|
||||
2 bytes - Length of author name
|
||||
3 bytes - ZST size
|
||||
2 bytes - Initial input configuration
|
||||
1 bit - Input 1 enabled
|
||||
1 bit - Input 2 enabled
|
||||
1 bit - Input 3 enabled
|
||||
1 bit - Input 4 enabled
|
||||
1 bit - Input 5 enabled
|
||||
1 bit - Mouse in first port
|
||||
1 bit - Mouse in second port
|
||||
1 bit - Super Scope in second port
|
||||
8 bits - Reserved
|
||||
1 byte - Flag Byte
|
||||
2 bits - Start from ZST/Power On/Reset/Power On + Clear SRAM
|
||||
1 bit - NTSC or PAL
|
||||
@@ -223,6 +234,7 @@ struct zmv_header
|
||||
unsigned short internal_chapters;
|
||||
unsigned short author_len;
|
||||
unsigned int zst_size; //We only read/write 3 bytes for this
|
||||
unsigned short initial_input;
|
||||
struct
|
||||
{
|
||||
enum zmv_start_methods start_method;
|
||||
@@ -245,7 +257,8 @@ static void zmv_header_write(struct zmv_header *zmv_head, FILE *fp)
|
||||
fwrite2(zmv_head->internal_chapters, fp);
|
||||
fwrite2(zmv_head->author_len, fp);
|
||||
fwrite3(zmv_head->zst_size, fp);
|
||||
|
||||
fwrite2(zmv_head->initial_input, fp);
|
||||
|
||||
switch (zmv_head->zmv_flag.start_method)
|
||||
{
|
||||
case zmv_sm_zst:
|
||||
@@ -513,6 +526,59 @@ static size_t internal_chapter_delete_after(struct internal_chapter_buf *icb, si
|
||||
|
||||
/*
|
||||
|
||||
Bit Encoder and Decoder
|
||||
|
||||
*/
|
||||
|
||||
size_t bit_encoder(unsigned int data, unsigned int mask, unsigned char *buffer, size_t skip_bits)
|
||||
{
|
||||
unsigned char bit_loop;
|
||||
|
||||
for (bit_loop = 31; ; bit_loop--)
|
||||
{
|
||||
if (mask & BIT(bit_loop))
|
||||
{
|
||||
if (data & BIT(bit_loop))
|
||||
{
|
||||
buffer[skip_bits/8] |= BIT(7-(skip_bits&7));
|
||||
}
|
||||
else
|
||||
{
|
||||
buffer[skip_bits/8] &= ~BIT(7-(skip_bits&7));
|
||||
}
|
||||
skip_bits++;
|
||||
}
|
||||
|
||||
if (!bit_loop) { break; }
|
||||
}
|
||||
|
||||
return(skip_bits);
|
||||
}
|
||||
|
||||
size_t bit_decoder(unsigned int *data, unsigned int mask, unsigned char *buffer, size_t skip_bits)
|
||||
{
|
||||
unsigned char bit_loop;
|
||||
*data = 0;
|
||||
|
||||
for (bit_loop = 31; ; bit_loop--)
|
||||
{
|
||||
if (mask & BIT(bit_loop))
|
||||
{
|
||||
if (buffer[skip_bits/8] & BIT(7-(skip_bits&7)))
|
||||
{
|
||||
*data |= BIT(bit_loop);
|
||||
}
|
||||
skip_bits++;
|
||||
}
|
||||
|
||||
if (!bit_loop) { break; }
|
||||
}
|
||||
|
||||
return(skip_bits);
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
Shared var between record/replay functions
|
||||
|
||||
*/
|
||||
@@ -524,11 +590,11 @@ static struct
|
||||
FILE *fp;
|
||||
struct
|
||||
{
|
||||
unsigned short A;
|
||||
unsigned short B;
|
||||
unsigned short C;
|
||||
unsigned short D;
|
||||
unsigned short E;
|
||||
unsigned int A;
|
||||
unsigned int B;
|
||||
unsigned int C;
|
||||
unsigned int D;
|
||||
unsigned int E;
|
||||
} last_joy_state;
|
||||
unsigned char write_buffer[WRITE_BUFFER_SIZE];
|
||||
size_t write_buffer_loc;
|
||||
@@ -540,23 +606,22 @@ static struct
|
||||
|
||||
static void save_last_joy_state(unsigned char *buffer)
|
||||
{
|
||||
buffer[0] = (zmv_vars.last_joy_state.A >> 4) & 0xFF;
|
||||
buffer[1] = ((zmv_vars.last_joy_state.A << 4) & 0xF0) | ((zmv_vars.last_joy_state.B >> 8) & 0x0F);
|
||||
buffer[2] = zmv_vars.last_joy_state.B & 0xFF;
|
||||
buffer[3] = (zmv_vars.last_joy_state.C >> 4) & 0xFF;
|
||||
buffer[4] = ((zmv_vars.last_joy_state.C << 4) & 0xF0) | ((zmv_vars.last_joy_state.D >> 8) & 0x0F);
|
||||
buffer[5] = zmv_vars.last_joy_state.D & 0xFF;
|
||||
buffer[6] = (zmv_vars.last_joy_state.E >> 4) & 0xFF;
|
||||
buffer[7] = (zmv_vars.last_joy_state.E << 4) & 0xF0;
|
||||
size_t skip_bits = 0;
|
||||
skip_bits = bit_encoder(zmv_vars.last_joy_state.A, 0xFFF00000, buffer, skip_bits);
|
||||
skip_bits = bit_encoder(zmv_vars.last_joy_state.B, 0xFFF00000, buffer, skip_bits);
|
||||
skip_bits = bit_encoder(zmv_vars.last_joy_state.C, 0xFFF00000, buffer, skip_bits);
|
||||
skip_bits = bit_encoder(zmv_vars.last_joy_state.D, 0xFFF00000, buffer, skip_bits);
|
||||
skip_bits = bit_encoder(zmv_vars.last_joy_state.E, 0xFFF00000, buffer, skip_bits);
|
||||
}
|
||||
|
||||
static void load_last_joy_state(unsigned char *buffer)
|
||||
{
|
||||
zmv_vars.last_joy_state.A = (((unsigned short)(buffer[0])) << 4) | ((buffer[1] & 0xF0) >> 4);
|
||||
zmv_vars.last_joy_state.B = (((unsigned short)(buffer[1] & 0x0F)) << 8) | buffer[2];
|
||||
zmv_vars.last_joy_state.C = (((unsigned short)(buffer[3])) << 4) | ((buffer[4] & 0xF0) >> 4);
|
||||
zmv_vars.last_joy_state.D = (((unsigned short)(buffer[4] & 0x0F)) << 8) | buffer[5];
|
||||
zmv_vars.last_joy_state.E = (((unsigned short)(buffer[6])) << 4) | ((buffer[7] & 0xF0) >> 4);
|
||||
size_t skip_bits = 0;
|
||||
skip_bits = bit_decoder(&zmv_vars.last_joy_state.A, 0xFFF00000, buffer, skip_bits);
|
||||
skip_bits = bit_decoder(&zmv_vars.last_joy_state.B, 0xFFF00000, buffer, skip_bits);
|
||||
skip_bits = bit_decoder(&zmv_vars.last_joy_state.C, 0xFFF00000, buffer, skip_bits);
|
||||
skip_bits = bit_decoder(&zmv_vars.last_joy_state.D, 0xFFF00000, buffer, skip_bits);
|
||||
skip_bits = bit_decoder(&zmv_vars.last_joy_state.E, 0xFFF00000, buffer, skip_bits);
|
||||
}
|
||||
|
||||
static void write_last_joy_state(FILE *fp)
|
||||
@@ -683,33 +748,19 @@ static void zmv_record_command(enum zmv_commands command)
|
||||
flush_input_if_needed();
|
||||
}
|
||||
|
||||
#define RECORD_PAD(prev, cur, bit) \
|
||||
if ((unsigned short)(cur >> 20) != prev) \
|
||||
{ \
|
||||
prev = (unsigned short)(cur >> 20); \
|
||||
flag |= BIT(bit); \
|
||||
\
|
||||
if (nibble & 1) \
|
||||
{ \
|
||||
press_buf[nibble/2] |= ((unsigned char)(prev & 0x0F)) << 4; \
|
||||
nibble++; \
|
||||
press_buf[nibble/2] = (unsigned char)(prev >> 4); \
|
||||
nibble += 2; \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
press_buf[nibble/2] = (unsigned char)(prev & 0xFF); \
|
||||
nibble += 2; \
|
||||
press_buf[nibble/2] = (unsigned char)(prev >> 8); \
|
||||
nibble++; \
|
||||
} \
|
||||
}
|
||||
#define RECORD_PAD(prev, cur, bit) \
|
||||
if (cur != prev) \
|
||||
{ \
|
||||
prev = cur; \
|
||||
flag |= BIT(bit); \
|
||||
skip_bits = bit_encoder(prev, 0xFFF00000, press_buf, skip_bits); \
|
||||
}
|
||||
|
||||
static void zmv_record(bool slow, unsigned char combos_used)
|
||||
{
|
||||
unsigned char flag = 0;
|
||||
unsigned char press_buf[] = { 0, 0, 0, 0, 0, 0, 0, 0 };
|
||||
unsigned char nibble = 0;
|
||||
size_t skip_bits = 0;
|
||||
|
||||
if (slow) { zmv_vars.header.slow_frames++; }
|
||||
|
||||
@@ -725,7 +776,7 @@ static void zmv_record(bool slow, unsigned char combos_used)
|
||||
|
||||
if (flag)
|
||||
{
|
||||
unsigned char buffer_used = (nibble/2) + (nibble&1);
|
||||
unsigned char buffer_used = skip_bits/8 + ((skip_bits&7) ? 1 : 0);
|
||||
|
||||
zmv_rle_flush();
|
||||
|
||||
@@ -877,6 +928,8 @@ static bool zmv_open(char *filename)
|
||||
zmv_vars.filename = (char *)malloc(filename_len+1); //+1 for null
|
||||
strcpy(zmv_vars.filename, filename);
|
||||
|
||||
debug_input_start;
|
||||
|
||||
return(true);
|
||||
}
|
||||
return(false);
|
||||
@@ -893,27 +946,22 @@ static bool zmv_replay_command(enum zmv_commands command)
|
||||
return(false);
|
||||
}
|
||||
|
||||
#define RESTORE_PAD(cur, prev) cur = (((unsigned int)prev) << 20) | 0x8000
|
||||
#define RESTORE_PAD(cur, prev) cur = prev
|
||||
|
||||
#define REPLAY_PAD(prev, cur, bit) \
|
||||
if (flag & BIT(bit)) \
|
||||
{ \
|
||||
if (mid_byte) \
|
||||
{ \
|
||||
prev = (byte & 0xF0) >> 4; \
|
||||
fread(&byte, 1, 1, zmv_vars.fp); \
|
||||
prev |= ((unsigned long)byte) << 4; \
|
||||
mid_byte = false; \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
fread(&byte, 1, 1, zmv_vars.fp); \
|
||||
prev = byte; \
|
||||
fread(&byte, 1, 1, zmv_vars.fp); \
|
||||
prev |= ((unsigned long)(byte & 0xF)) << 8; \
|
||||
mid_byte = true; \
|
||||
} \
|
||||
} \
|
||||
#define REPLAY_PAD(prev, cur, bit) \
|
||||
if (flag & BIT(bit)) \
|
||||
{ \
|
||||
if (skip_bits && ((skip_bits&7) < 4)) \
|
||||
{ \
|
||||
fread(press_buf + skip_bits/8, 1, 1, zmv_vars.fp); \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
fread(press_buf + skip_bits/8, 1, 2, zmv_vars.fp); \
|
||||
} \
|
||||
skip_bits = bit_decoder(&prev, 0xFFF00000, press_buf, skip_bits); \
|
||||
prev |= 0x8000; \
|
||||
} \
|
||||
RESTORE_PAD(cur, prev)
|
||||
|
||||
static bool zmv_replay()
|
||||
@@ -928,12 +976,12 @@ static bool zmv_replay()
|
||||
RESTORE_PAD(JoyDOrig, zmv_vars.last_joy_state.D);
|
||||
RESTORE_PAD(JoyEOrig, zmv_vars.last_joy_state.E);
|
||||
zmv_vars.rle_count--;
|
||||
|
||||
debug_input;
|
||||
}
|
||||
else
|
||||
{
|
||||
unsigned char flag = 0;
|
||||
unsigned char byte;
|
||||
bool mid_byte = false;
|
||||
zmv_vars.rle_count = 0;
|
||||
|
||||
fread(&flag, 1, 1, zmv_vars.fp);
|
||||
@@ -954,23 +1002,31 @@ static bool zmv_replay()
|
||||
return(false);
|
||||
}
|
||||
|
||||
if (flag & BIT(1)) //RLE
|
||||
else 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
|
||||
else if (flag & BIT(2)) //Internal Chapter
|
||||
{
|
||||
fseek(zmv_vars.fp, INT_CHAP_SIZE, SEEK_CUR);
|
||||
return(zmv_replay());
|
||||
}
|
||||
|
||||
REPLAY_PAD(zmv_vars.last_joy_state.A, JoyAOrig, 7);
|
||||
REPLAY_PAD(zmv_vars.last_joy_state.B, JoyBOrig, 6);
|
||||
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.E, JoyEOrig, 3);
|
||||
else
|
||||
{
|
||||
unsigned char press_buf[] = { 0, 0, 0, 0, 0, 0, 0, 0 };
|
||||
size_t skip_bits = 0;
|
||||
|
||||
REPLAY_PAD(zmv_vars.last_joy_state.A, JoyAOrig, 7);
|
||||
REPLAY_PAD(zmv_vars.last_joy_state.B, JoyBOrig, 6);
|
||||
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.E, JoyEOrig, 3);
|
||||
|
||||
debug_input;
|
||||
}
|
||||
}
|
||||
|
||||
zmv_open_vars.frames_replayed++;
|
||||
@@ -1461,6 +1517,87 @@ bool mzt_load(char *statename, bool playback)
|
||||
|
||||
/////////////////////////////////////////////////////////
|
||||
|
||||
/*
|
||||
|
||||
Code for dumping raw video
|
||||
|
||||
*/
|
||||
|
||||
#define RAW_BUFFER_FRAMES 10
|
||||
#define RAW_WIDTH 256
|
||||
#define RAW_HEIGHT 223
|
||||
#define RAW_PIXEL_SIZE 4
|
||||
#define RAW_FRAME_SIZE (RAW_WIDTH*RAW_HEIGHT)
|
||||
#define RAW_PIXEL_FRAME_SIZE (RAW_FRAME_SIZE*RAW_PIXEL_SIZE)
|
||||
|
||||
struct
|
||||
{
|
||||
FILE *fp;
|
||||
unsigned int *frame_buffer;
|
||||
size_t frame_index;
|
||||
} raw_vid;
|
||||
|
||||
static void raw_video_close()
|
||||
{
|
||||
if (raw_vid.fp)
|
||||
{
|
||||
if (raw_vid.frame_buffer)
|
||||
{
|
||||
if (raw_vid.frame_index)
|
||||
{
|
||||
fwrite(raw_vid.frame_buffer, RAW_PIXEL_FRAME_SIZE, raw_vid.frame_index, raw_vid.fp);
|
||||
}
|
||||
|
||||
free(raw_vid.frame_buffer);
|
||||
}
|
||||
|
||||
fclose(raw_vid.fp);
|
||||
raw_vid.fp = 0;
|
||||
}
|
||||
}
|
||||
|
||||
static void raw_video_open(const char *filename)
|
||||
{
|
||||
memset(&raw_vid, 0, sizeof(raw_vid));
|
||||
raw_vid.fp = fopen(filename, "wb");
|
||||
if (!(raw_vid.frame_buffer = (unsigned int *)malloc(RAW_PIXEL_FRAME_SIZE*RAW_BUFFER_FRAMES)))
|
||||
{
|
||||
raw_video_close();
|
||||
}
|
||||
}
|
||||
|
||||
#define PIXEL (vidbuffer[(i*288) + j + 16])
|
||||
static void raw_video_write_frame()
|
||||
{
|
||||
extern unsigned short *vidbuffer;
|
||||
if (raw_vid.fp)
|
||||
{
|
||||
size_t i, j;
|
||||
unsigned int *pixel_dest = raw_vid.frame_buffer + raw_vid.frame_index*RAW_FRAME_SIZE;
|
||||
|
||||
//Use zsKnight's 16 to 32 bit color conversion (optimized by Nach)
|
||||
for (i = 0; i < RAW_HEIGHT; i++)
|
||||
{
|
||||
unsigned int *scanline = pixel_dest + i*RAW_WIDTH;
|
||||
for (j = 0; j < RAW_WIDTH; j++)
|
||||
{
|
||||
scanline[j] = ((PIXEL&0xF800) << 8) | ((PIXEL&0x07E0) << 5) |
|
||||
((PIXEL&0x001F) << 3) | 0xFF000000;
|
||||
}
|
||||
}
|
||||
|
||||
raw_vid.frame_index++;
|
||||
|
||||
if (raw_vid.frame_index == RAW_BUFFER_FRAMES)
|
||||
{
|
||||
fwrite(raw_vid.frame_buffer, RAW_PIXEL_FRAME_SIZE, RAW_BUFFER_FRAMES, raw_vid.fp);
|
||||
raw_vid.frame_index = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////
|
||||
|
||||
/*
|
||||
Nach's insane subtitle library for movies files :)
|
||||
|
||||
@@ -1709,6 +1846,11 @@ static void OldMoviePlay(FILE *fp)
|
||||
MessageOn = MsgCount;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void MovieInsertChapter()
|
||||
{
|
||||
switch (MovieProcessing)
|
||||
|
||||
@@ -96,10 +96,12 @@ static void copy_state_data(unsigned char *buffer, void (*copy_func)(unsigned ch
|
||||
if (spcon)
|
||||
{
|
||||
copy_spc_data(&buffer, copy_func);
|
||||
/*
|
||||
if (buffer) //Rewind stuff
|
||||
{
|
||||
copy_func(&buffer, &echoon0, PHdspsave2);
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
if (C4Enable)
|
||||
@@ -430,10 +432,9 @@ void calculate_state_sizes()
|
||||
old_zst_size = state_size + sizeof(zst_header_old)-1;
|
||||
}
|
||||
|
||||
//copy_state_data(RewindBufferPos, memcpyinc, false);
|
||||
void zst_save(FILE *fp, bool Thumbnail)
|
||||
{
|
||||
fwrite(zst_header_cur, 1, sizeof(zst_header_cur)-1, fp); //-1 for null
|
||||
|
||||
PrepareOffset();
|
||||
PrepareSaveState();
|
||||
unpackfunct();
|
||||
@@ -449,9 +450,17 @@ void zst_save(FILE *fp, bool Thumbnail)
|
||||
SaveSA1(); //Convert SA-1 stuff to standard, non displacement format
|
||||
}
|
||||
|
||||
fwrite(zst_header_cur, 1, sizeof(zst_header_cur)-1, fp); //-1 for null
|
||||
|
||||
fhandle = fp; //Set global file handle
|
||||
copy_state_data(0, write_save_state_data, false);
|
||||
|
||||
if (Thumbnail)
|
||||
{
|
||||
CapturePicture();
|
||||
fwrite(PrevPicture, 1, 64*56*sizeof(unsigned short), fp);
|
||||
}
|
||||
|
||||
if (SFXEnable)
|
||||
{
|
||||
SfxRomBuffer += SfxCROM;
|
||||
@@ -463,12 +472,6 @@ void zst_save(FILE *fp, bool Thumbnail)
|
||||
RestoreSA1(); //Convert back SA-1 stuff
|
||||
}
|
||||
|
||||
if (Thumbnail)
|
||||
{
|
||||
CapturePicture();
|
||||
fwrite(PrevPicture, 1, 64*56*sizeof(unsigned short), fp);
|
||||
}
|
||||
|
||||
ResetOffset();
|
||||
ResetState();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user