git.y1.nz

SameBoy

Accurate GB/GBC emulator
download: https://git.y1.nz/archives/sameboy.tar.gz
README | Files | Log | Refs | LICENSE

Core/save_state.h

      1 #pragma once
      2 
      3 /* Macros to make the GB_gameboy_t struct more future compatible when state saving */
      4 #include <stddef.h>
      5 
      6 #define GB_PADDING(type, old_usage) type old_usage##__do_not_use
      7 
      8 #ifdef __cplusplus
      9 /* For bsnes integration. C++ code does not need section information, and throws a fit over certain types such
     10    as anonymous enums inside unions */
     11 #if __clang__
     12 #define GB_SECTION(name, ...) __attribute__ ((aligned (8))) __VA_ARGS__
     13 #else
     14 // GCC's handling of attributes is so awfully bad, that it is alone a good enough reason to never use that compiler
     15 #define GB_SECTION(name, ...) _Pragma("GCC diagnostic push") _Pragma("GCC diagnostic ignored \"-Wpedantic\"") alignas(8) char _align_##name[0]; __VA_ARGS__ _Pragma("GCC diagnostic pop")
     16 #endif
     17 #else
     18 #define GB_SECTION(name, ...) union __attribute__ ((aligned (8))) {uint8_t name##_section_start; struct {__VA_ARGS__};}; uint8_t name##_section_end[0];
     19 #ifdef GB_INTERNAL
     20 #define GB_SECTION_OFFSET(name) (offsetof(GB_gameboy_t, name##_section_start))
     21 #define GB_SECTION_SIZE(name) (offsetof(GB_gameboy_t, name##_section_end) - offsetof(GB_gameboy_t, name##_section_start))
     22 /* This roundabout way to get the section offset is because GCC 9 is a bad compiler and will false-positively complain
     23    about memset buffer overflows otherwise */
     24 #define GB_GET_SECTION(gb, name) (void *)((uint8_t *)(gb) + GB_SECTION_OFFSET(name))
     25 #endif
     26 #endif
     27 
     28 #if __clang_major__ >= 8 || __GNUC__ >= 13 || defined(__cplusplus)
     29 #define GB_ENUM(type, ...) enum : type __VA_ARGS__
     30 #else
     31 #define GB_ENUM(type, ...) __typeof__((type)((enum __VA_ARGS__)0))
     32 #endif
     33 
     34 /* Public calls related to save states */
     35 int GB_save_state(GB_gameboy_t *gb, const char *path);
     36 size_t GB_get_save_state_size(GB_gameboy_t *gb);
     37 /* Assumes buffer is big enough to contain the save state. Use with GB_get_save_state_size(). */
     38 void GB_save_state_to_buffer(GB_gameboy_t *gb, uint8_t *buffer);
     39 
     40 int GB_load_state(GB_gameboy_t *gb, const char *path);
     41 int GB_load_state_from_buffer(GB_gameboy_t *gb, const uint8_t *buffer, size_t length);
     42 bool GB_is_save_state(const char *path);
     43 int GB_get_state_model(const char *path, GB_model_t *model);
     44 int GB_get_state_model_from_buffer(const uint8_t *buffer, size_t length, GB_model_t *model);
     45 
     46 #ifdef GB_INTERNAL
     47 static inline uint32_t GB_state_magic(void)
     48 {
     49     if (sizeof(bool) == 1) return 'SAME';
     50     return 'S4ME';
     51 }
     52 
     53 /* For internal in-memory save states (rewind, debugger) that do not need BESS */
     54 internal size_t GB_get_save_state_size_no_bess(GB_gameboy_t *gb);
     55 internal void GB_save_state_to_buffer_no_bess(GB_gameboy_t *gb, uint8_t *buffer);
     56 #endif

This webpage is intended to be an accessible preview of this repository. To get a fuller picture, clone it and use the git CLI.