diff --git a/general.h b/general.h index c03c2f2174..75bcd018fd 100644 --- a/general.h +++ b/general.h @@ -522,6 +522,38 @@ static inline uint8_t is_little_endian(void) return u.y[0]; } +static inline uint32_t swap_if_big32(uint32_t val) +{ + if (is_little_endian()) // Little-endian + return val; + else + return (val >> 24) | ((val >> 8) & 0xFF00) | ((val << 8) & 0xFF0000) | (val << 24); +} + +static inline uint32_t swap_if_little32(uint32_t val) +{ + if (is_little_endian()) + return (val >> 24) | ((val >> 8) & 0xFF00) | ((val << 8) & 0xFF0000) | (val << 24); + else + return val; +} + +static inline uint16_t swap_if_big16(uint16_t val) +{ + if (is_little_endian()) + return val; + else + return (val >> 8) | (val << 8); +} + +static inline uint16_t swap_if_little16(uint16_t val) +{ + if (is_little_endian()) + return (val >> 8) | (val << 8); + else + return val; +} + #ifdef GEKKO #include #endif diff --git a/movie.c b/movie.c index 0ca2e69829..29dec763f0 100644 --- a/movie.c +++ b/movie.c @@ -40,38 +40,6 @@ struct bsv_movie bool did_rewind; }; -#define BSV_MAGIC 0x42535631 - -#define MAGIC_INDEX 0 -#define SERIALIZER_INDEX 1 -#define CRC_INDEX 2 -#define STATE_SIZE_INDEX 3 - -// Convert to big-endian if needed -static inline uint32_t swap_if_big32(uint32_t val) -{ - if (is_little_endian()) // Little-endian - return val; - else - return (val >> 24) | ((val >> 8) & 0xFF00) | ((val << 8) & 0xFF0000) | (val << 24); -} - -static inline uint32_t swap_if_little32(uint32_t val) -{ - if (!is_little_endian()) // Big-endian - return val; - else - return (val >> 24) | ((val >> 8) & 0xFF00) | ((val << 8) & 0xFF0000) | (val << 24); -} - -static inline uint16_t swap_if_big16(uint16_t val) -{ - if (is_little_endian()) - return val; - else - return (val >> 8) | (val << 8); -} - static bool init_playback(bsv_movie_t *handle, const char *path) { handle->playback = true; @@ -267,64 +235,3 @@ void bsv_movie_frame_rewind(bsv_movie_t *handle) } } -uint32_t *bsv_header_generate(size_t *size, uint32_t magic) -{ - uint32_t bsv_header[4] = {0}; - unsigned serialize_size = psnes_serialize_size(); - size_t header_size = sizeof(bsv_header) + serialize_size; - *size = header_size; - - uint32_t *header = (uint32_t*)malloc(header_size); - if (!header) - return NULL; - - bsv_header[MAGIC_INDEX] = swap_if_little32(BSV_MAGIC); - bsv_header[SERIALIZER_INDEX] = swap_if_big32(magic); - bsv_header[CRC_INDEX] = swap_if_big32(g_extern.cart_crc); - bsv_header[STATE_SIZE_INDEX] = swap_if_big32(serialize_size); - - if (serialize_size && !psnes_serialize((uint8_t*)header + sizeof(bsv_header), serialize_size)) - { - free(header); - return NULL; - } - - memcpy(header, bsv_header, sizeof(bsv_header)); - return header; -} - -bool bsv_parse_header(const uint32_t *header, uint32_t magic) -{ - uint32_t in_bsv = swap_if_little32(header[MAGIC_INDEX]); - if (in_bsv != BSV_MAGIC) - { - SSNES_ERR("BSV magic mismatch, got 0x%x, expected 0x%x.\n", - in_bsv, BSV_MAGIC); - return false; - } - - uint32_t in_magic = swap_if_big32(header[SERIALIZER_INDEX]); - if (in_magic != magic) - { - SSNES_ERR("Magic mismatch, got 0x%x, expected 0x%x.\n", in_magic, magic); - return false; - } - - uint32_t in_crc = swap_if_big32(header[CRC_INDEX]); - if (in_crc != g_extern.cart_crc) - { - SSNES_ERR("CRC32 mismatch, got 0x%x, expected 0x%x.\n", in_crc, g_extern.cart_crc); - return false; - } - - uint32_t in_state_size = swap_if_big32(header[STATE_SIZE_INDEX]); - if (in_state_size != psnes_serialize_size()) - { - SSNES_ERR("Serialization size mismatch, got 0x%x, expected 0x%x.\n", - in_state_size, psnes_serialize_size()); - return false; - } - - return true; -} - diff --git a/movie.h b/movie.h index 6ac5287769..a7c2480e17 100644 --- a/movie.h +++ b/movie.h @@ -22,6 +22,13 @@ #include #include "boolean.h" +#define BSV_MAGIC 0x42535631 + +#define MAGIC_INDEX 0 +#define SERIALIZER_INDEX 1 +#define CRC_INDEX 2 +#define STATE_SIZE_INDEX 3 + typedef struct bsv_movie bsv_movie_t; enum ssnes_movie_type @@ -30,9 +37,6 @@ enum ssnes_movie_type SSNES_MOVIE_RECORD }; -uint32_t *bsv_header_generate(size_t *size, uint32_t magic); -bool bsv_parse_header(const uint32_t *header, uint32_t magic); - bsv_movie_t *bsv_movie_init(const char *path, enum ssnes_movie_type type); // Playback diff --git a/netplay.c b/netplay.c index 42e70a4946..d298593551 100644 --- a/netplay.c +++ b/netplay.c @@ -608,6 +608,67 @@ static bool get_info(netplay_t *handle) return true; } +static uint32_t *bsv_header_generate(size_t *size, uint32_t magic) +{ + uint32_t bsv_header[4] = {0}; + unsigned serialize_size = psnes_serialize_size(); + size_t header_size = sizeof(bsv_header) + serialize_size; + *size = header_size; + + uint32_t *header = (uint32_t*)malloc(header_size); + if (!header) + return NULL; + + bsv_header[MAGIC_INDEX] = swap_if_little32(BSV_MAGIC); + bsv_header[SERIALIZER_INDEX] = swap_if_big32(magic); + bsv_header[CRC_INDEX] = swap_if_big32(g_extern.cart_crc); + bsv_header[STATE_SIZE_INDEX] = swap_if_big32(serialize_size); + + if (serialize_size && !psnes_serialize((uint8_t*)header + sizeof(bsv_header), serialize_size)) + { + free(header); + return NULL; + } + + memcpy(header, bsv_header, sizeof(bsv_header)); + return header; +} + +static bool bsv_parse_header(const uint32_t *header, uint32_t magic) +{ + uint32_t in_bsv = swap_if_little32(header[MAGIC_INDEX]); + if (in_bsv != BSV_MAGIC) + { + SSNES_ERR("BSV magic mismatch, got 0x%x, expected 0x%x.\n", + in_bsv, BSV_MAGIC); + return false; + } + + uint32_t in_magic = swap_if_big32(header[SERIALIZER_INDEX]); + if (in_magic != magic) + { + SSNES_ERR("Magic mismatch, got 0x%x, expected 0x%x.\n", in_magic, magic); + return false; + } + + uint32_t in_crc = swap_if_big32(header[CRC_INDEX]); + if (in_crc != g_extern.cart_crc) + { + SSNES_ERR("CRC32 mismatch, got 0x%x, expected 0x%x.\n", in_crc, g_extern.cart_crc); + return false; + } + + uint32_t in_state_size = swap_if_big32(header[STATE_SIZE_INDEX]); + if (in_state_size != psnes_serialize_size()) + { + SSNES_ERR("Serialization size mismatch, got 0x%x, expected 0x%x.\n", + in_state_size, psnes_serialize_size()); + return false; + } + + return true; +} + static bool get_info_spectate(netplay_t *handle) { if (!send_nickname(handle, handle->fd)) @@ -1178,14 +1239,6 @@ static void netplay_pre_frame_net(netplay_t *handle) input_poll_net(); } -static inline uint16_t swap_if_big16(uint16_t input) -{ - if (is_little_endian()) - return input; - else - return (input << 8) | (input >> 8); -} - static void netplay_set_spectate_input(netplay_t *handle, int16_t input) { if (handle->spectate_input_ptr >= handle->spectate_input_size)