diff --git a/Makefile.libretro b/Makefile.libretro new file mode 100644 index 0000000..8de2e00 --- /dev/null +++ b/Makefile.libretro @@ -0,0 +1,179 @@ +NTSC = 0 +DEBUG = 0 + +GENPLUS_SRC_DIR := source +LIBRETRO_DIR := libretro + +ifeq ($(platform),) +platform = unix +ifeq ($(shell uname -a),) + platform = win +else ifneq ($(findstring MINGW,$(shell uname -a)),) + platform = win +else ifneq ($(findstring Darwin,$(shell uname -a)),) + platform = osx +else ifneq ($(findstring win,$(shell uname -a)),) + platform = win +endif +endif + +ifeq ($(platform), unix) + TARGET := libretro.so + fpic := -fPIC + SHARED := -shared -Wl,--version-script=libretro/link.T -Wl,--no-undefined -lz + ENDIANNESS_DEFINES := -DLSB_FIRST + PLATFORM_DEFINES := -DHAVE_ZLIB +else ifeq ($(platform), osx) + TARGET := libretro.dylib + fpic := -fPIC + SHARED := -dynamiclib -lz + ENDIANNESS_DEFINES := -DLSB_FIRST + PLATFORM_DEFINES := -DHAVE_ZLIB +else ifeq ($(platform), sncps3) + TARGET := libretro_ps3.a + CC = $(CELL_SDK)/host-win32/sn/bin/ps3ppusnc.exe + AR = $(CELL_SDK)/host-win32/sn/bin/ps3snarl.exe + PLATFORM_DEFINES := -D__CELLOS_LV2 -DALT_RENDER +else ifeq ($(platform), ps3) + TARGET := libretro_ps3.a + CC = $(CELL_SDK)/host-win32/ppu/bin/ppu-lv2-gcc.exe + AR = $(CELL_SDK)/host-win32/ppu/bin/ppu-lv2-ar.exe + PLATFORM_DEFINES := -D__CELLOS_LV2 -DALT_RENDER +else ifeq ($(platform), psl1ght) + TARGET := libretro_psl1ght.a + CC = $(PS3DEV)/ppu/bin/ppu-gcc + AR = $(PS3DEV)/ppu/bin/ppu-ar + PLATFORM_DEFINES := -D__CELLOS_LV2 -DALT_RENDER +else ifeq ($(platform), xenon) + TARGET := libretro_xenon360.a + CC = xenon-gcc + AR = xenon-ar + PLATFORM_DEFINES := -D__LIBXENON__ -DALT_RENDER +else ifeq ($(platform), wii) + TARGET := libretro_wii.a + CC = $(DEVKITPPC)/bin/powerpc-eabi-gcc + AR = $(DEVKITPPC)/bin/powerpc-eabi-ar + PLATFORM_DEFINES := -DGEKKO -mrvl -mcpu=750 -meabi -mhard-float -DALT_RENDER +else + TARGET := retro.dll + CC = gcc + SHARED := -shared -static-libgcc -static-libstdc++ -Wl,--version-script=libretro/link.T -Wl,--no-undefined -lz + + ENDIANNESS_DEFINES := -DLSB_FIRST + PLATFORM_DEFINES := -DHAVE_ZLIB +endif + +ifeq ($(NTSC), 1) + CFLAGS += -DUSE_NTSC +endif + +ifeq ($(DEBUG), 1) + CFLAGS += -O0 -g +else + CFLAGS += -O3 -DNDEBUG +endif + +LIBRETRO_SRC := $(GENPLUS_SRC_DIR)/genesis.c \ + $(GENPLUS_SRC_DIR)/vdp_ctrl.c \ + $(GENPLUS_SRC_DIR)/vdp_render.c \ + $(GENPLUS_SRC_DIR)/system.c \ + $(GENPLUS_SRC_DIR)/io_ctrl.c \ + $(GENPLUS_SRC_DIR)/loadrom.c \ + $(GENPLUS_SRC_DIR)/mem68k.c \ + $(GENPLUS_SRC_DIR)/state.c \ + $(GENPLUS_SRC_DIR)/memz80.c \ + $(GENPLUS_SRC_DIR)/membnk.c \ + $(GENPLUS_SRC_DIR)/input_hw/activator.c \ + $(GENPLUS_SRC_DIR)/input_hw/gamepad.c \ + $(GENPLUS_SRC_DIR)/input_hw/input.c \ + $(GENPLUS_SRC_DIR)/input_hw/lightgun.c \ + $(GENPLUS_SRC_DIR)/input_hw/mouse.c \ + $(GENPLUS_SRC_DIR)/input_hw/paddle.c \ + $(GENPLUS_SRC_DIR)/input_hw/sportspad.c \ + $(GENPLUS_SRC_DIR)/input_hw/teamplayer.c \ + $(GENPLUS_SRC_DIR)/input_hw/xe_a1p.c \ + $(GENPLUS_SRC_DIR)/input_hw/terebi_oekaki.c \ + $(GENPLUS_SRC_DIR)/cd_hw/cd_cart.c \ + $(GENPLUS_SRC_DIR)/cd_hw/cdc.c \ + $(GENPLUS_SRC_DIR)/cd_hw/cdd.c \ + $(GENPLUS_SRC_DIR)/cd_hw/gfx.c \ + $(GENPLUS_SRC_DIR)/cd_hw/pcm.c \ + $(GENPLUS_SRC_DIR)/cd_hw/scd.c \ + $(GENPLUS_SRC_DIR)/cart_hw/areplay.c \ + $(GENPLUS_SRC_DIR)/cart_hw/md_cart.c \ + $(GENPLUS_SRC_DIR)/cart_hw/sms_cart.c \ + $(GENPLUS_SRC_DIR)/cart_hw/gg_eeprom.c \ + $(GENPLUS_SRC_DIR)/cart_hw/md_eeprom.c \ + $(GENPLUS_SRC_DIR)/cart_hw/ggenie.c \ + $(GENPLUS_SRC_DIR)/cart_hw/sram.c \ + $(GENPLUS_SRC_DIR)/cart_hw/svp/ssp16.c \ + $(GENPLUS_SRC_DIR)/cart_hw/svp/svp.c \ + $(GENPLUS_SRC_DIR)/ntsc/md_ntsc.c \ + $(GENPLUS_SRC_DIR)/ntsc/sms_ntsc.c \ + $(GENPLUS_SRC_DIR)/sound/Fir_Resampler.c \ + $(GENPLUS_SRC_DIR)/sound/eq.c \ + $(GENPLUS_SRC_DIR)/sound/sound.c \ + $(GENPLUS_SRC_DIR)/sound/ym2612.c \ + $(GENPLUS_SRC_DIR)/sound/ym2413.c \ + $(GENPLUS_SRC_DIR)/sound/sn76489.c \ + $(GENPLUS_SRC_DIR)/sound/blip.c \ + $(GENPLUS_SRC_DIR)/z80/z80.c \ + $(GENPLUS_SRC_DIR)/m68k/m68kcpu.c \ + $(GENPLUS_SRC_DIR)/m68k/s68kcpu.c \ + $(LIBRETRO_DIR)/libretro.c + +LIBRETRO_OBJ := $(LIBRETRO_SRC:.c=.o) + +ifeq ($(platform), sncps3) +CODE_DEFINES = +else +CODE_DEFINES = -std=gnu99 +endif + +DEFINES := +CFLAGS += $(fpic) $(DEFINES) $(CODE_DEFINES) + +LIBRETRO_CFLAGS := -I$(GENPLUS_SRC_DIR) \ + -I$(GENPLUS_SRC_DIR)/sound \ + -I$(GENPLUS_SRC_DIR)/input_hw \ + -I$(GENPLUS_SRC_DIR)/cart_hw \ + -I$(GENPLUS_SRC_DIR)/cd_hw \ + -I$(GENPLUS_SRC_DIR)/cart_hw/svp \ + -I$(GENPLUS_SRC_DIR)/m68k \ + -I$(GENPLUS_SRC_DIR)/z80 \ + -I$(GENPLUS_SRC_DIR)/ntsc \ + -I$(LIBRETRO_DIR) \ + -DUSE_15BPP_RENDERING \ + $(ENDIANNESS_DEFINES) \ + $(PLATFORM_DEFINES) \ + -D__LIBRETRO__ + +LIBRETRO_LIBS := -lm + + +all: $(TARGET) + +%.o: %.c + $(CC) -o $@ -c $< $(CFLAGS) $(LIBRETRO_CFLAGS) + +$(TARGET): $(LIBRETRO_OBJ) +ifeq ($(platform), sncps3) + $(AR) rcs $@ $(LIBRETRO_OBJ) +else ifeq ($(platform), ps3) + $(AR) rcs $@ $(LIBRETRO_OBJ) +else ifeq ($(platform), psl1ght) + $(AR) rcs $@ $(LIBRETRO_OBJ) +else ifeq ($(platform), xenon) + $(AR) rcs $@ $(LIBRETRO_OBJ) +else ifeq ($(platform), wii) + $(AR) rcs $@ $(LIBRETRO_OBJ) +else + $(CC) -o $(TARGET) $(fpic) $(LIBRETRO_OBJ) $(LIBRETRO_LIBS) $(SHARED) +endif + +clean: + rm -f $(LIBRETRO_OBJ) + rm -f $(TARGET) + +.PHONY: clean + diff --git a/libretro/jni/Android.mk b/libretro/jni/Android.mk new file mode 100644 index 0000000..600a6c0 --- /dev/null +++ b/libretro/jni/Android.mk @@ -0,0 +1,62 @@ +LOCAL_PATH := $(call my-dir) + +include $(CLEAR_VARS) + +GENPLUS_SRC_DIR := ../src +LIBRETRO_DIR := ../libretro + +LOCAL_MODULE := libretro +LOCAL_SRC_FILES := $(GENPLUS_SRC_DIR)/genesis.c \ + $(GENPLUS_SRC_DIR)/vdp_ctrl.c \ + $(GENPLUS_SRC_DIR)/vdp_render.c \ + $(GENPLUS_SRC_DIR)/system.c \ + $(GENPLUS_SRC_DIR)/io_ctrl.c \ + $(GENPLUS_SRC_DIR)/loadrom.c \ + $(GENPLUS_SRC_DIR)/mem68k.c \ + $(GENPLUS_SRC_DIR)/state.c \ + $(GENPLUS_SRC_DIR)/memz80.c \ + $(GENPLUS_SRC_DIR)/membnk.c \ + $(GENPLUS_SRC_DIR)/input_hw/activator.c \ + $(GENPLUS_SRC_DIR)/input_hw/gamepad.c \ + $(GENPLUS_SRC_DIR)/input_hw/input.c \ + $(GENPLUS_SRC_DIR)/input_hw/lightgun.c \ + $(GENPLUS_SRC_DIR)/input_hw/mouse.c \ + $(GENPLUS_SRC_DIR)/input_hw/paddle.c \ + $(GENPLUS_SRC_DIR)/input_hw/sportspad.c \ + $(GENPLUS_SRC_DIR)/input_hw/teamplayer.c \ + $(GENPLUS_SRC_DIR)/input_hw/xe_a1p.c \ + $(GENPLUS_SRC_DIR)/input_hw/terebi_oekaki.c \ + $(GENPLUS_SRC_DIR)/cart_hw/areplay.c \ + $(GENPLUS_SRC_DIR)/cart_hw/md_cart.c \ + $(GENPLUS_SRC_DIR)/cart_hw/sms_cart.c \ + $(GENPLUS_SRC_DIR)/cart_hw/gg_eeprom.c \ + $(GENPLUS_SRC_DIR)/cart_hw/md_eeprom.c \ + $(GENPLUS_SRC_DIR)/cart_hw/ggenie.c \ + $(GENPLUS_SRC_DIR)/cart_hw/sram.c \ + $(GENPLUS_SRC_DIR)/cart_hw/svp/ssp16.c \ + $(GENPLUS_SRC_DIR)/cart_hw/svp/svp.c \ + $(GENPLUS_SRC_DIR)/ntsc/md_ntsc.c \ + $(GENPLUS_SRC_DIR)/ntsc/sms_ntsc.c \ + $(GENPLUS_SRC_DIR)/sound/Fir_Resampler.c \ + $(GENPLUS_SRC_DIR)/sound/eq.c \ + $(GENPLUS_SRC_DIR)/sound/sound.c \ + $(GENPLUS_SRC_DIR)/sound/ym2612.c \ + $(GENPLUS_SRC_DIR)/sound/ym2413.c \ + $(GENPLUS_SRC_DIR)/sound/sn76489.c \ + $(GENPLUS_SRC_DIR)/sound/blip.c \ + $(GENPLUS_SRC_DIR)/z80/z80.c \ + $(GENPLUS_SRC_DIR)/m68k/m68kcpu.c \ + $(LIBRETRO_DIR)/libretro.c + +LOCAL_C_INCLUDES = $(LOCAL_PATH)/$(GENPLUS_SRC_DIR) \ + $(LOCAL_PATH)/$(GENPLUS_SRC_DIR)/sound \ + $(LOCAL_PATH)/$(GENPLUS_SRC_DIR)/input_hw \ + $(LOCAL_PATH)/$(GENPLUS_SRC_DIR)/cart_hw \ + $(LOCAL_PATH)/$(GENPLUS_SRC_DIR)/cart_hw/svp \ + $(LOCAL_PATH)/$(GENPLUS_SRC_DIR)/m68k \ + $(LOCAL_PATH)/$(GENPLUS_SRC_DIR)/z80 \ + $(LOCAL_PATH)/$(GENPLUS_SRC_DIR)/ntsc \ + $(LOCAL_PATH)/$(LIBRETRO_DIR) + +LOCAL_CFLAGS = -DINLINE=inline -DUSE_15BPP_RENDERING -DLSB_FIRST -D__LIBRETRO__ +include $(BUILD_SHARED_LIBRARY) diff --git a/libretro/libretro.c b/libretro/libretro.c new file mode 100644 index 0000000..c53bef5 --- /dev/null +++ b/libretro/libretro.c @@ -0,0 +1,1009 @@ +#ifndef _MSC_VER +#include +#endif +#include +#include +#ifndef __CELLOS_LV2__ +#include +#endif + +#ifdef _MSC_VER +#define snprintf _snprintf +#pragma pack(1) +#endif + +#include "shared.h" +#include "libretro.h" +#include "state.h" +#include "genesis.h" +#include "md_ntsc.h" +#include "sms_ntsc.h" + +sms_ntsc_t *sms_ntsc; +md_ntsc_t *md_ntsc; + +static int vwidth; +static int vheight; +static bool failed_init; + +unsigned retro_api_version(void) { return RETRO_API_VERSION; } + +static retro_video_refresh_t video_cb; +static retro_input_poll_t input_poll_cb; +static retro_input_state_t input_state_cb; +static retro_environment_t environ_cb; +static retro_audio_sample_batch_t audio_batch_cb; + +void retro_set_environment(retro_environment_t cb) { environ_cb = cb; } +void retro_set_video_refresh(retro_video_refresh_t cb) { video_cb = cb; } +void retro_set_audio_sample(retro_audio_sample_t cb) { (void)cb; } +void retro_set_audio_sample_batch(retro_audio_sample_batch_t cb) { audio_batch_cb = cb; } +void retro_set_input_poll(retro_input_poll_t cb) { input_poll_cb = cb; } +void retro_set_input_state(retro_input_state_t cb) { input_state_cb = cb; } + +struct bind_conv +{ + int retro; + int genesis; +}; + +static struct bind_conv binds[] = { + { RETRO_DEVICE_ID_JOYPAD_B, INPUT_B }, + { RETRO_DEVICE_ID_JOYPAD_A, INPUT_C }, + { RETRO_DEVICE_ID_JOYPAD_X, INPUT_Y }, + { RETRO_DEVICE_ID_JOYPAD_Y, INPUT_A }, + { RETRO_DEVICE_ID_JOYPAD_START, INPUT_START }, + { RETRO_DEVICE_ID_JOYPAD_L, INPUT_X }, + { RETRO_DEVICE_ID_JOYPAD_R, INPUT_Z }, + { RETRO_DEVICE_ID_JOYPAD_UP, INPUT_UP }, + { RETRO_DEVICE_ID_JOYPAD_DOWN, INPUT_DOWN }, + { RETRO_DEVICE_ID_JOYPAD_LEFT, INPUT_LEFT }, + { RETRO_DEVICE_ID_JOYPAD_RIGHT, INPUT_RIGHT }, + { RETRO_DEVICE_ID_JOYPAD_SELECT, INPUT_MODE }, +}; + + +static char g_rom_dir[1024]; + +extern uint8 system_hw; + +char GG_ROM[256]; +char AR_ROM[256]; +char SK_ROM[256]; +char SK_UPMEM[256]; +char GG_BIOS[256]; +char MS_BIOS_EU[256]; +char MS_BIOS_JP[256]; +char MS_BIOS_US[256]; +char CD_BIOS_EU[256]; +char CD_BIOS_US[256]; +char CD_BIOS_JP[256]; +char DEFAULT_PATH[1024]; +char CD_BRAM_JP[256]; +char CD_BRAM_US[256]; +char CD_BRAM_EU[256]; +char CART_BRAM[256]; + +/* Mega CD backup RAM stuff */ +static uint32_t brm_crc[2]; +static uint8_t brm_format[0x40] = +{ + 0x5f,0x5f,0x5f,0x5f,0x5f,0x5f,0x5f,0x5f,0x5f,0x5f,0x5f,0x00,0x00,0x00,0x00,0x40, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x53,0x45,0x47,0x41,0x5f,0x43,0x44,0x5f,0x52,0x4f,0x4d,0x00,0x01,0x00,0x00,0x00, + 0x52,0x41,0x4d,0x5f,0x43,0x41,0x52,0x54,0x52,0x49,0x44,0x47,0x45,0x5f,0x5f,0x5f +}; + +/************************************ + * Genesis Plus implementation + ************************************/ +#define CHUNKSIZE (0x10000) + +int load_archive(char *filename, unsigned char *buffer, int maxsize) +{ + int size = 0; + char in[CHUNKSIZE]; + char msg[64] = "Unable to open file"; + + /* Open file */ + FILE *fd = fopen(filename, "rb"); + + /* Mega CD BIOS are required files */ + if (!strcmp(filename,CD_BIOS_US) || !strcmp(filename,CD_BIOS_EU) || !strcmp(filename,CD_BIOS_JP)) + { + sprintf(msg,"Unable to open CD BIOS"); + } + + if (!fd) + { + fprintf(stderr, "ERROR - %s.\n"); + return 0; + } + + /* Read first chunk */ + fread(in, CHUNKSIZE, 1, fd); + + { + /* Get file size */ + fseek(fd, 0, SEEK_END); + size = ftell(fd); + fseek(fd, 0, SEEK_SET); + + /* size limit */ + if(size > maxsize) + { + fclose(fd); + fprintf(stderr, "ERROR - File is too large.\n"); + return 0; + } + + sprintf((char *)msg,"Loading %d bytes ...", size); + fprintf(stderr, "INFORMATION - %s\n", msg); + + /* Read into buffer */ + int left = size; + while (left > CHUNKSIZE) + { + fread(buffer, CHUNKSIZE, 1, fd); + buffer += CHUNKSIZE; + left -= CHUNKSIZE; + } + + /* Read remaining bytes */ + fread(buffer, left, 1, fd); + } + + /* Close file */ + fclose(fd); + + /* Return loaded ROM size */ + return size; +} + + +static uint16_t bitmap_data_[1024 * 512]; + +static void init_bitmap(void) +{ + memset(&bitmap, 0, sizeof(bitmap)); + bitmap.width = 1024; + bitmap.height = 512; + bitmap.pitch = bitmap.width * sizeof(uint16_t); + bitmap.data = (uint8_t *)bitmap_data_; + bitmap.viewport.w = 0; + bitmap.viewport.h = 0; + bitmap.viewport.x = 0; + bitmap.viewport.y = 0; +} + +#define CONFIG_VERSION "GENPLUS-GX 1.6.1" + +static void config_default(void) +{ + /* version TAG */ + strncpy(config.version,CONFIG_VERSION,16); + + /* sound options */ + config.psg_preamp = 150; + config.fm_preamp = 100; + config.hq_fm = 1; + config.psgBoostNoise = 0; + config.filter = 0; + config.lp_range = 50; + config.low_freq = 880; + config.high_freq = 5000; + config.lg = 1.0; + config.mg = 1.0; + config.hg = 1.0; + config.rolloff = 0.990; + config.dac_bits = 14; + config.ym2413 = 2; /* AUTO */ + + /* system options */ + config.system = 0; /* AUTO */ + config.region_detect = 0; /* AUTO */ + config.vdp_mode = 0; /* AUTO */ + config.master_clock = 0; /* AUTO */ + config.force_dtack = 0; + config.addr_error = 1; + config.bios = 0; + config.lock_on = 0; + config.hot_swap = 0; + + /* video options */ + config.xshift = 0; + config.yshift = 0; + config.xscale = 0; + config.yscale = 0; + config.aspect = 0; + config.overscan = 0; /* 3 == FULL */ +#if defined(USE_NTSC) + config.ntsc = 1; +#endif + config.vsync = 1; /* AUTO */ + + config.render = 0; + config.bilinear = 0; + + /* controllers options */ + config.gun_cursor[0] = 1; + config.gun_cursor[1] = 1; + config.invert_mouse = 0; + + /* menu options */ + config.autoload = 0; + config.autocheat = 0; + config.s_auto = 0; + config.s_default = 1; + config.s_device = 0; + config.l_device = 0; + config.bg_overlay = 0; + config.screen_w = 658; + config.bgm_volume = 100.0; + config.sfx_volume = 100.0; + + /* hot swap requires at least a first initialization */ + config.hot_swap &= 1; +} + +static const double pal_fps = 53203424.0 / (3420.0 * 313.0); +static const double ntsc_fps = 53693175.0 / (3420.0 * 262.0); + +static void init_audio(void) +{ + audio_init(32000, vdp_pal ? pal_fps : ntsc_fps); +} + +static void configure_controls(void) +{ + unsigned i; + + switch (system_hw) + { + case SYSTEM_MD: + case SYSTEM_MCD: + for(i = 0; i < MAX_INPUTS; i++) + { + config.input[i].padtype = DEVICE_PAD6B; + input.system[i] = SYSTEM_MD_GAMEPAD; + } + break; + case SYSTEM_GG: + case SYSTEM_SMS: + input.system[0] = SYSTEM_MS_GAMEPAD; + input.system[1] = SYSTEM_MS_GAMEPAD; + break; + default: + break; + } +} + +static int slot_load(int slot) +{ + char filename[MAXPATHLEN]; + unsigned long filesize, done = 0; + uint8_t *buffer; + + /* File Type */ + if (slot > 0) + fprintf(stderr, "INFORMATION - Loading State ...\n"); + else + { + if (!sram.on || (system_hw == SYSTEM_MCD)) + { + fprintf(stderr, "ERROR - SRAM is disabled.\n"); + return 0; + } + + fprintf(stderr, "INFORMATION - Loading SRAM ...\n"); + } + + /* Device Type */ + /* FAT file */ + if (slot > 0) + sprintf (filename,"%s/saves/%s.gp%d", DEFAULT_PATH, rom_filename, slot - 1); + else + sprintf (filename,"%s/saves/%s.srm", DEFAULT_PATH, rom_filename); + + /* Open file */ + FILE *fp = fopen(filename, "rb"); + if (!fp) + { + fprintf(stderr, "ERROR - Unable to open file.\n"); + return 0; + } + + /* Get file size */ + fseek(fp, 0, SEEK_END); + filesize = ftell(fp); + fseek(fp, 0, SEEK_SET); + + /* allocate buffer */ + buffer = (uint8_t *)memalign(32,filesize); + if (!buffer) + { + fprintf(stderr, "ERROR - Unable to allocate memory.\n"); + fclose(fp); + return 0; + } + + /* Read into buffer (2k blocks) */ + while (filesize > CHUNKSIZE) + { + fread(buffer + done, CHUNKSIZE, 1, fp); + done += CHUNKSIZE; + filesize -= CHUNKSIZE; + } + + /* Read remaining bytes */ + fread(buffer + done, filesize, 1, fp); + done += filesize; + + /* Close file */ + fclose(fp); + + if (slot > 0) + { + /* Load state */ + if (state_load(buffer) <= 0) + { + free(buffer); + fprintf(stderr, "Invalid state file.\n"); + return 0; + } + } + else + { + /* load SRAM */ + memcpy(sram.sram, buffer, 0x10000); + + /* update CRC */ + sram.crc = crc32(0, sram.sram, 0x10000); + } + + free(buffer); + return 1; +} + +static int slot_save(int slot) +{ + char filename[MAXPATHLEN]; + unsigned long filesize, done = 0; + uint8_t *buffer; + + if (slot > 0) + { + fprintf(stderr, "INFORMATION - Saving State ...\n"); + + /* allocate buffer */ + buffer = (uint8_t *)memalign(32,STATE_SIZE); + if (!buffer) + { + fprintf(stderr, "ERROR - Unable to allocate memory.\n"); + return 0; + } + + filesize = state_save(buffer); + } + else + { + /* only save if SRAM is enabled */ + if (!sram.on || (system_hw == SYSTEM_MCD)) + { + fprintf(stderr, "ERROR - SRAM is disabled.\n"); + return 0; + } + + /* only save if SRAM has been modified */ + if (crc32(0, &sram.sram[0], 0x10000) == sram.crc) + { + fprintf(stderr, "WARNING - SRAM not modified.\n"); + return 0; + } + + fprintf(stderr, "INFORMATION - Saving SRAM ...\n"); + + /* allocate buffer */ + buffer = (uint8_t *)memalign(32, 0x10000); + if (!buffer) + { + fprintf(stderr, "ERROR - Unable to allocate memory.\n"); + return 0; + } + + /* copy SRAM data */ + memcpy(buffer, sram.sram, 0x10000); + filesize = 0x10000; + + /* update CRC */ + sram.crc = crc32(0, sram.sram, 0x10000); + } + + /* Device Type */ + { + /* FAT filename */ + if (slot > 0) + { + sprintf(filename, "%s/saves/%s.gp%d", DEFAULT_PATH, rom_filename, slot - 1); + } + else + { + sprintf(filename, "%s/saves/%s.srm", DEFAULT_PATH, rom_filename); + } + + /* Open file */ + FILE *fp = fopen(filename, "wb"); + if (!fp) + { + fprintf(stderr, "ERROR - Unable to open file.\n"); + free(buffer); + return 0; + } + + /* Write from buffer (2k blocks) */ + while (filesize > CHUNKSIZE) + { + fwrite(buffer + done, CHUNKSIZE, 1, fp); + done += CHUNKSIZE; + filesize -= CHUNKSIZE; + } + + /* Write remaining bytes */ + fwrite(buffer + done, filesize, 1, fp); + done += filesize; + + /* Close file */ + fclose(fp); + free(buffer); + } + + return 1; +} + + +static void slot_autoload(int slot) +{ + /* Mega CD backup RAM specific */ + if (!slot && (system_hw == SYSTEM_MCD)) + { + /* automatically load internal backup RAM */ + unsigned i = ((region_code ^ 0x40) >> 6) - 1; + const char *path = NULL; + + switch(i) + { + case 0: + path = CD_BRAM_JP; + break; + case 1: + path = CD_BRAM_EU; + break; + case 2: + path = CD_BRAM_US; + break; + default: + return; + } + + FILE *fp = fopen(path, "rb"); + if (fp != NULL) + { + fread(scd.bram, 0x2000, 1, fp); + fclose(fp); + + /* update CRC */ + brm_crc[0] = crc32(0, scd.bram, 0x2000); + } + + /* check if internal backup RAM is correctly formatted */ + if (memcmp(scd.bram + 0x2000 - 0x20, brm_format + 0x20, 0x20)) + { + /* clear internal backup RAM */ + memset(scd.bram, 0x00, 0x200); + + /* internal Backup RAM size fields */ + brm_format[0x10] = brm_format[0x12] = brm_format[0x14] = brm_format[0x16] = 0x00; + brm_format[0x11] = brm_format[0x13] = brm_format[0x15] = brm_format[0x17] = (sizeof(scd.bram) / 64) - 3; + + /* format internal backup RAM */ + memcpy(scd.bram + 0x2000 - 0x40, brm_format, 0x40); + } + + /* automatically load cartridge backup RAM (if enabled) */ + if (scd.cartridge.id) + { + fp = fopen(CART_BRAM, "rb"); + if (fp != NULL) + { + fread(scd.cartridge.area, scd.cartridge.mask + 1, 1, fp); + fclose(fp); + + /* update CRC */ + brm_crc[1] = crc32(0, scd.cartridge.area, scd.cartridge.mask + 1); + } + + /* check if cartridge backup RAM is correctly formatted */ + if (memcmp(scd.cartridge.area + scd.cartridge.mask + 1 - 0x20, brm_format + 0x20, 0x20)) + { + /* clear cartridge backup RAM */ + memset(scd.cartridge.area, 0x00, scd.cartridge.mask + 1); + + /* Cartridge Backup RAM size fields */ + brm_format[0x10] = brm_format[0x12] = brm_format[0x14] = brm_format[0x16] = (((scd.cartridge.mask + 1) / 64) - 3) >> 8; + brm_format[0x11] = brm_format[0x13] = brm_format[0x15] = brm_format[0x17] = (((scd.cartridge.mask + 1) / 64) - 3) & 0xff; + + /* format cartridge backup RAM */ + memcpy(scd.cartridge.area + scd.cartridge.mask + 1 - 0x40, brm_format, 0x40); + } + } + + return; + } + + if (strlen(rom_filename)) + { + slot_load(slot); + } +} + +static void slot_autosave(int slot) +{ + /* Mega CD backup RAM specific */ + if (!slot && (system_hw == SYSTEM_MCD)) + { + /* verify that internal backup RAM has been modified */ + if (crc32(0, scd.bram, 0x2000) != brm_crc[0]) + { + /* check if it is correctly formatted before saving */ + if (!memcmp(scd.bram + 0x2000 - 0x20, brm_format + 0x20, 0x20)) + { + unsigned i = ((region_code ^ 0x40) >> 6) - 1; + const char *path = NULL; + + switch(i) + { + case 0: + path = CD_BRAM_JP; + break; + case 1: + path = CD_BRAM_EU; + break; + case 2: + path = CD_BRAM_US; + break; + default: + return; + } + FILE *fp = fopen(path, "wb"); + if (fp != NULL) + { + fwrite(scd.bram, 0x2000, 1, fp); + fclose(fp); + + /* update CRC */ + brm_crc[0] = crc32(0, scd.bram, 0x2000); + } + } + } + + /* verify that cartridge backup RAM has been modified */ + if (scd.cartridge.id && (crc32(0, scd.cartridge.area, scd.cartridge.mask + 1) != brm_crc[1])) + { + /* check if it is correctly formatted before saving */ + if (!memcmp(scd.cartridge.area + scd.cartridge.mask + 1 - 0x20, brm_format + 0x20, 0x20)) + { + FILE *fp = fopen(CART_BRAM, "wb"); + if (fp != NULL) + { + fwrite(scd.cartridge.area, scd.cartridge.mask + 1, 1, fp); + fclose(fp); + + /* update CRC */ + brm_crc[1] = crc32(0, scd.cartridge.area, scd.cartridge.mask + 1); + } + } + } + + return; + } + + if (strlen(rom_filename)) + slot_save(slot); +} + +/************************************ + * libretro implementation + ************************************/ + +static struct retro_system_av_info g_av_info; + +void retro_get_system_info(struct retro_system_info *info) +{ + info->library_name = "Genesis Plus GX"; + info->library_version = "v1.7.0"; + info->valid_extensions = "md|smd|bin|cue|gen|zip|MD|SMD|bin|CUE|GEN|ZIP|sms|SMS|gg|GG|sg|SG"; + info->block_extract = false; + info->need_fullpath = true; +} + +void retro_get_system_av_info(struct retro_system_av_info *info) +{ + *info = g_av_info; +} + +void retro_set_controller_port_device(unsigned port, unsigned device) +{ + (void)port; + (void)device; +} + +size_t retro_serialize_size(void) { return STATE_SIZE; } + +bool retro_serialize(void *data, size_t size) +{ + if (size != STATE_SIZE) + return FALSE; + + state_save(data); + + return TRUE; +} + +bool retro_unserialize(const void *data, size_t size) +{ + if (size != STATE_SIZE) + return FALSE; + + state_load((uint8_t*)data); + + return TRUE; +} + +void retro_cheat_reset(void) {} +void retro_cheat_set(unsigned index, bool enabled, const char *code) +{ + (void)index; + (void)enabled; + (void)code; +} + +static void extract_directory(char *buf, const char *path, size_t size) +{ + strncpy(buf, path, size - 1); + buf[size - 1] = '\0'; + + char *base = strrchr(buf, '/'); + if (!base) + base = strrchr(buf, '\\'); + + if (base) + *base = '\0'; + else + buf[0] = '\0'; +} + +static void retro_set_viewport_dimensions(void) +{ + unsigned i; + struct retro_game_geometry geom; + struct retro_system_timing timing; + + /* HACK: Emulate 10 dummy frames to figure out the real viewport dimensions of the game. */ + if((system_hw & SYSTEM_PBC) == SYSTEM_MD || (system_hw & SYSTEM_PBC) == SYSTEM_MCD) + for (i = 0; i < 10; i++) + system_frame_gen(0); + else + for (i = 0; i < 10; i++) + system_frame_sms(0); + + retro_reset(); + + vwidth = bitmap.viewport.w; + vheight = bitmap.viewport.h; + +#if defined(USE_NTSC) + if (config.ntsc) + { + if (system_hw & SYSTEM_MD) + vwidth = MD_NTSC_OUT_WIDTH(vwidth); + else + vwidth = SMS_NTSC_OUT_WIDTH(vwidth); + } +#endif + + geom.base_width = vwidth; + geom.base_height = vheight; + geom.max_width = 1024; + geom.max_height = 512; + + timing.sample_rate = 32000; + + if (vdp_pal) + timing.fps = pal_fps; + else + timing.fps = ntsc_fps; + + g_av_info.geometry = geom; + g_av_info.timing = timing; +} + +bool retro_load_game(const struct retro_game_info *info) +{ + int i; + const char *full_path; + extract_directory(g_rom_dir, info->path, sizeof(g_rom_dir)); + + if(failed_init) + return false; + + snprintf(DEFAULT_PATH, sizeof(DEFAULT_PATH), g_rom_dir); +#ifdef _XBOX + snprintf(CART_BRAM, sizeof(CART_BRAM), "%s\\cart.brm", g_rom_dir); +#else + snprintf(CART_BRAM, sizeof(CART_BRAM), "%s/cart.brm", g_rom_dir); +#endif + + fprintf(stderr, "BRAM file is located at: %s\n", CART_BRAM); + + config_default(); + init_bitmap(); + + full_path = info->path; + + failed_init = true; + + if (full_path) + failed_init = !(load_rom((char*)full_path)); + + if(failed_init) + return false; + + configure_controls(); + + init_audio(); + + system_init(); + system_reset(); + + if (system_hw == SYSTEM_MCD) + slot_autoload(0); + + retro_set_viewport_dimensions(); + + return TRUE; +} + +bool retro_load_game_special(unsigned game_type, const struct retro_game_info *info, size_t num_info) +{ + (void)game_type; + (void)info; + (void)num_info; +} + +void retro_unload_game(void) +{ + if (system_hw == SYSTEM_MCD) + slot_autosave(0); +} + +unsigned retro_get_region(void) { return vdp_pal ? RETRO_REGION_PAL : RETRO_REGION_NTSC; } + +void *retro_get_memory_data(unsigned id) +{ + if (!sram.on) + return NULL; + + switch (id) + { + case RETRO_MEMORY_SAVE_RAM: + return sram.sram; + + default: + return NULL; + } +} + +size_t retro_get_memory_size(unsigned id) +{ + if (!sram.on) + return 0; + + switch (id) + { + case RETRO_MEMORY_SAVE_RAM: + return sram.end - sram.start; + + default: + return 0; + } +} + +void retro_init(void) +{ + const char *dir = NULL; +#if defined(USE_NTSC) + sms_ntsc = calloc(1, sizeof(sms_ntsc_t)); + md_ntsc = calloc(1, sizeof(md_ntsc_t)); + sms_ntsc_init(sms_ntsc, &sms_ntsc_composite); + md_ntsc_init(md_ntsc, &md_ntsc_composite); +#endif + + if (environ_cb(RETRO_ENVIRONMENT_GET_SYSTEM_DIRECTORY, &dir) && dir) + { + snprintf(CD_BRAM_EU, sizeof(CD_BRAM_EU), "%sscd_E.brm", dir); + snprintf(CD_BRAM_US, sizeof(CD_BRAM_US), "%sscd_U.brm", dir); + snprintf(CD_BRAM_JP, sizeof(CD_BRAM_JP), "%sscd_J.brm", dir); + snprintf(CD_BIOS_EU, sizeof(CD_BIOS_EU), "%sbios_CD_E.bin", dir); + snprintf(CD_BIOS_US, sizeof(CD_BIOS_US), "%sbios_CD_U.bin", dir); + snprintf(CD_BIOS_JP, sizeof(CD_BIOS_JP), "%sbios_CD_J.bin", dir); + snprintf(MS_BIOS_EU, sizeof(MS_BIOS_EU), "%sbios_E.sms", dir); + snprintf(MS_BIOS_US, sizeof(MS_BIOS_US), "%sbios_U.sms", dir); + snprintf(MS_BIOS_JP, sizeof(MS_BIOS_JP), "%sbios_J.sms", dir); + snprintf(GG_BIOS, sizeof(GG_BIOS), "%sbios.gg", dir); + snprintf(SK_ROM, sizeof(SK_ROM), "%ssk.bin", dir); + snprintf(SK_UPMEM, sizeof(SK_UPMEM), "%ssk2chip.bin", dir); + snprintf(GG_ROM, sizeof(GG_ROM), "%sggenie.bin", dir); + snprintf(AR_ROM, sizeof(AR_ROM), "%sareplay.bin", dir); + fprintf(stderr, "Sega CD EU BRAM should be located at: %s\n", CD_BRAM_EU); + fprintf(stderr, "Sega CD US BRAM should be located at: %s\n", CD_BRAM_US); + fprintf(stderr, "Sega CD JP BRAM should be located at: %s\n", CD_BRAM_JP); + fprintf(stderr, "Sega CD EU BIOS should be located at: %s\n", CD_BIOS_EU); + fprintf(stderr, "Sega CD US BIOS should be located at: %s\n", CD_BIOS_US); + fprintf(stderr, "Sega CD JP BIOS should be located at: %s\n", CD_BIOS_JP); + fprintf(stderr, "Master System EU BIOS should be located at: %s\n", MS_BIOS_EU); + fprintf(stderr, "Master System US BIOS should be located at: %s\n", MS_BIOS_US); + fprintf(stderr, "Master System JP BIOS should be located at: %s\n", MS_BIOS_JP); + fprintf(stderr, "Game Gear BIOS should be located at: %s\n", GG_BIOS); + fprintf(stderr, "S&K upmem ROM should be located at: %s\n", SK_UPMEM); + fprintf(stderr, "S&K ROM should be located at: %s\n", SK_ROM); + fprintf(stderr, "Game Genie ROM should be located at: %s\n", GG_ROM); + fprintf(stderr, "Action Replay ROM should be located at: %s\n", AR_ROM); + } + else + { + fprintf(stderr, "System directory is not defined. Cannot continue ...\n"); + failed_init = true; + } + + unsigned level = 1; + environ_cb(RETRO_ENVIRONMENT_SET_PERFORMANCE_LEVEL, &level); +} + +void retro_deinit(void) +{ + system_shutdown(); +#if defined(USE_NTSC) + free(md_ntsc); + free(sms_ntsc); +#endif +} + +void retro_reset(void) { gen_reset(0); } + +int16 soundbuffer[1920]; + +void osd_input_update(void) +{ + unsigned res[MAX_INPUTS], i, j; + + for(i = 0; i < MAX_INPUTS; i++) + res[i] = 0; + + if (!input_poll_cb) + return; + + input_poll_cb(); + + switch (input.system[0]) + { + case SYSTEM_MS_GAMEPAD: + case SYSTEM_MD_GAMEPAD: + if(input.dev[0] != NO_DEVICE) + { + for (j = 0; j < sizeof(binds) / sizeof(binds[0]); j++) + { + if (input_state_cb(0, RETRO_DEVICE_JOYPAD, 0, binds[j].retro)) + res[0] |= binds[j].genesis; + } + + input.pad[0] = res[0]; + } + break; + case SYSTEM_MOUSE: + break; + case SYSTEM_ACTIVATOR: + break; + case SYSTEM_XE_A1P: + break; + case SYSTEM_WAYPLAY: + break; + case SYSTEM_TEAMPLAYER: + break; + case SYSTEM_LIGHTPHASER: + break; + case SYSTEM_PADDLE: + break; + case SYSTEM_SPORTSPAD: + break; + default: + break; + } + + + switch (input.system[1]) + { + case SYSTEM_MS_GAMEPAD: + case SYSTEM_MD_GAMEPAD: + if(input.dev[4] != NO_DEVICE) + { + for (j = 0; j < sizeof(binds) / sizeof(binds[0]); j++) + { + if (input_state_cb(1, RETRO_DEVICE_JOYPAD, 0, binds[j].retro)) + res[1] |= binds[j].genesis; + input.pad[4] = res[1]; + } + } + break; + case SYSTEM_MOUSE: + break; + case SYSTEM_ACTIVATOR: + break; + case SYSTEM_XE_A1P: + break; + case SYSTEM_TEAMPLAYER: + break; + case SYSTEM_LIGHTPHASER: + break; + case SYSTEM_PADDLE: + break; + case SYSTEM_SPORTSPAD: + break; + default: + break; + } + + if (cart.special & HW_J_CART) + { + for(i = 5; i < 7; i++) + { + for (j = 0; j < sizeof(binds) / sizeof(binds[0]); j++) + { + if (input_state_cb(i-3, RETRO_DEVICE_JOYPAD, 0, binds[j].retro)) + res[i-3] |= binds[j].genesis; + input.pad[i] = res[i-3]; + } + } + } + +} + +void retro_run(void) +{ + int aud; + + switch(system_hw) + { + case SYSTEM_MCD: + system_frame_scd(0); + break; + case SYSTEM_MD: + case SYSTEM_PBC: + system_frame_gen(0); + break; + case SYSTEM_SMS: + system_frame_sms(0); + break; + default: + break; + } + +#if defined(USE_NTSC) + video_cb(bitmap_data_ + bitmap.viewport.y * 1024, config.ntsc ? vwidth : bitmap.viewport.w, bitmap.viewport.h, 2048); +#else + video_cb(bitmap_data_ + bitmap.viewport.x + bitmap.viewport.y * 1024, bitmap.viewport.w, bitmap.viewport.h, 2048); +#endif + + aud = audio_update(soundbuffer) << 1; + audio_batch_cb(soundbuffer, aud >> 1); +} + diff --git a/libretro/libretro.h b/libretro/libretro.h new file mode 100755 index 0000000..8aa579e --- /dev/null +++ b/libretro/libretro.h @@ -0,0 +1,333 @@ +#ifndef LIBRETRO_H__ +#define LIBRETRO_H__ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#else +#if defined(_MSC_VER) && !defined(__cplusplus) +#define bool unsigned char +#define true 1 +#define false 0 +#else +#include +#endif +#endif + +#define RETRO_API_VERSION 1 + +#define RETRO_DEVICE_MASK 0xff +#define RETRO_DEVICE_NONE 0 +#define RETRO_DEVICE_JOYPAD 1 +#define RETRO_DEVICE_MOUSE 2 +#define RETRO_DEVICE_KEYBOARD 3 +#define RETRO_DEVICE_LIGHTGUN 4 +#define RETRO_DEVICE_ANALOG 5 + +#define RETRO_DEVICE_JOYPAD_MULTITAP ((1 << 8) | RETRO_DEVICE_JOYPAD) +#define RETRO_DEVICE_LIGHTGUN_SUPER_SCOPE ((1 << 8) | RETRO_DEVICE_LIGHTGUN) +#define RETRO_DEVICE_LIGHTGUN_JUSTIFIER ((2 << 8) | RETRO_DEVICE_LIGHTGUN) +#define RETRO_DEVICE_LIGHTGUN_JUSTIFIERS ((3 << 8) | RETRO_DEVICE_LIGHTGUN) + +#define RETRO_DEVICE_ID_JOYPAD_B 0 +#define RETRO_DEVICE_ID_JOYPAD_Y 1 +#define RETRO_DEVICE_ID_JOYPAD_SELECT 2 +#define RETRO_DEVICE_ID_JOYPAD_START 3 +#define RETRO_DEVICE_ID_JOYPAD_UP 4 +#define RETRO_DEVICE_ID_JOYPAD_DOWN 5 +#define RETRO_DEVICE_ID_JOYPAD_LEFT 6 +#define RETRO_DEVICE_ID_JOYPAD_RIGHT 7 +#define RETRO_DEVICE_ID_JOYPAD_A 8 +#define RETRO_DEVICE_ID_JOYPAD_X 9 +#define RETRO_DEVICE_ID_JOYPAD_L 10 +#define RETRO_DEVICE_ID_JOYPAD_R 11 +#define RETRO_DEVICE_ID_JOYPAD_L2 12 +#define RETRO_DEVICE_ID_JOYPAD_R2 13 +#define RETRO_DEVICE_ID_JOYPAD_L3 14 +#define RETRO_DEVICE_ID_JOYPAD_R3 15 + +#define RETRO_DEVICE_INDEX_ANALOG_LEFT 0 +#define RETRO_DEVICE_INDEX_ANALOG_RIGHT 1 +#define RETRO_DEVICE_ID_ANALOG_X 0 +#define RETRO_DEVICE_ID_ANALOG_Y 1 + +#define RETRO_DEVICE_ID_MOUSE_X 0 +#define RETRO_DEVICE_ID_MOUSE_Y 1 +#define RETRO_DEVICE_ID_MOUSE_LEFT 2 +#define RETRO_DEVICE_ID_MOUSE_RIGHT 3 + +#define RETRO_DEVICE_ID_LIGHTGUN_X 0 +#define RETRO_DEVICE_ID_LIGHTGUN_Y 1 +#define RETRO_DEVICE_ID_LIGHTGUN_TRIGGER 2 +#define RETRO_DEVICE_ID_LIGHTGUN_CURSOR 3 +#define RETRO_DEVICE_ID_LIGHTGUN_TURBO 4 +#define RETRO_DEVICE_ID_LIGHTGUN_PAUSE 5 +#define RETRO_DEVICE_ID_LIGHTGUN_START 6 + +#define RETRO_REGION_NTSC 0 +#define RETRO_REGION_PAL 1 + +#define RETRO_MEMORY_MASK 0xff +#define RETRO_MEMORY_SAVE_RAM 0 +#define RETRO_MEMORY_RTC 1 +#define RETRO_MEMORY_SYSTEM_RAM 2 +#define RETRO_MEMORY_VIDEO_RAM 3 + +#define RETRO_MEMORY_SNES_BSX_RAM ((1 << 8) | RETRO_MEMORY_SAVE_RAM) +#define RETRO_MEMORY_SNES_BSX_PRAM ((2 << 8) | RETRO_MEMORY_SAVE_RAM) +#define RETRO_MEMORY_SNES_SUFAMI_TURBO_A_RAM ((3 << 8) | RETRO_MEMORY_SAVE_RAM) +#define RETRO_MEMORY_SNES_SUFAMI_TURBO_B_RAM ((4 << 8) | RETRO_MEMORY_SAVE_RAM) +#define RETRO_MEMORY_SNES_GAME_BOY_RAM ((5 << 8) | RETRO_MEMORY_SAVE_RAM) +#define RETRO_MEMORY_SNES_GAME_BOY_RTC ((6 << 8) | RETRO_MEMORY_RTC) + +#define RETRO_GAME_TYPE_BSX 0x101 +#define RETRO_GAME_TYPE_BSX_SLOTTED 0x102 +#define RETRO_GAME_TYPE_SUFAMI_TURBO 0x103 +#define RETRO_GAME_TYPE_SUPER_GAME_BOY 0x104 + + +// Environment commands. +#define RETRO_ENVIRONMENT_SET_ROTATION 1 // const unsigned * -- + // Sets screen rotation of graphics. + // Is only implemented if rotation can be accelerated by hardware. + // Valid values are 0, 1, 2, 3, which rotates screen by 0, 90, 180, 270 degrees + // counter-clockwise respectively. + // +#define RETRO_ENVIRONMENT_GET_OVERSCAN 2 // bool * -- + // Boolean value whether or not the implementation should use overscan, or crop away overscan. + // +#define RETRO_ENVIRONMENT_GET_CAN_DUPE 3 // bool * -- + // Boolean value whether or not RetroArch supports frame duping, + // passing NULL to video frame callback. + // +#define RETRO_ENVIRONMENT_GET_VARIABLE 4 // struct retro_variable * -- + // Interface to aquire user-defined information from environment + // that cannot feasibly be supported in a multi-system way. + // Mostly used for obscure, + // specific features that the user can tap into when neseccary. + // +#define RETRO_ENVIRONMENT_SET_VARIABLES 5 // const struct retro_variable * -- + // Allows an implementation to signal the environment + // which variables it might want to check for later using GET_VARIABLE. + // 'data' points to an array of retro_variable structs terminated by a { NULL, NULL } element. + // retro_variable::value should contain a human readable description of the key. + // +#define RETRO_ENVIRONMENT_SET_MESSAGE 6 // const struct retro_message * -- + // Sets a message to be displayed in implementation-specific manner for a certain amount of 'frames'. + // Should not be used for trivial messages, which should simply be logged to stderr. +#define RETRO_ENVIRONMENT_SHUTDOWN 7 // N/A (NULL) -- + // Requests the frontend to shutdown. + // Should only be used if game has a specific + // way to shutdown the game from a menu item or similar. + // +#define RETRO_ENVIRONMENT_SET_PERFORMANCE_LEVEL 8 + // const unsigned * -- + // Gives a hint to the frontend how demanding this implementation + // is on a system. E.g. reporting a level of 2 means + // this implementation should run decently on all frontends + // of level 2 and up. + // + // It can be used by the frontend to potentially warn + // about too demanding implementations. + // + // The levels are "floating", but roughly defined as: + // 1: Low-powered devices such as Raspberry Pi, smart phones, tablets, etc. + // 2: Medium-spec consoles, such as PS3/360, with sub-par CPUs. + // 3: Modern desktop/laptops with reasonably powerful CPUs. + // 4: High-end desktops with very powerful CPUs. + // + // This function can be called on a per-game basis, + // as certain games an implementation can play might be + // particularily demanding. + // If called, it should be called in retro_load_game(). + // +#define RETRO_ENVIRONMENT_GET_SYSTEM_DIRECTORY 9 + // const char ** -- + // Returns the "system" directory of the frontend. + // This directory can be used to store system specific ROMs such as BIOSes, configuration data, etc. + // The returned value can be NULL. + // If so, no such directory is defined, + // and it's up to the implementation to find a suitable directory. + // +#define RETRO_ENVIRONMENT_SET_PIXEL_FORMAT 10 + // const enum retro_pixel_format * -- + // Sets the internal pixel format used by the implementation. + // The default pixel format is RETRO_PIXEL_FORMAT_XRGB1555. + // If the call returns false, the frontend does not support this pixel format. + // This function should be called inside retro_load_game() or retro_get_system_av_info(). + +enum retro_pixel_format +{ + RETRO_PIXEL_FORMAT_0RGB1555 = 0, // 0RGB1555, native endian. 0 bit must be set to 0. + RETRO_PIXEL_FORMAT_XRGB8888 // XRGB8888, native endian. X bits are ignored. +}; + +struct retro_message +{ + const char *msg; // Message to be displayed. + unsigned frames; // Duration in frames of message. +}; + +struct retro_system_info +{ + const char *library_name; // Descriptive name of library. Should not contain any version numbers, etc. + const char *library_version; // Descriptive version of core. + + const char *valid_extensions; // A string listing probably rom extensions the core will be able to load, separated with pipe. + // I.e. "bin|rom|iso". + // Typically used for a GUI to filter out extensions. + + bool need_fullpath; // If true, retro_load_game() is guaranteed to provide a valid pathname in retro_game_info::path. + // ::data and ::size are both invalid. + // If false, ::data and ::size are guaranteed to be valid, but ::path might not be valid. + // This is typically set to true for libretro implementations that must load from file. + // Implementations should strive for setting this to false, as it allows the frontend to perform patching, etc. + + bool block_extract; // If true, the frontend is not allowed to extract any archives before loading the real ROM. + // Necessary for certain libretro implementations that load games from zipped archives. +}; + +struct retro_game_geometry +{ + unsigned base_width; // Nominal video width of game. + unsigned base_height; // Nominal video height of game. + unsigned max_width; // Maximum possible width of game. + unsigned max_height; // Maximum possible height of game. + + float aspect_ratio; // Nominal aspect ratio of game. If aspect_ratio is <= 0.0, + // an aspect ratio of base_width / base_height is assumed. + // A frontend could override this setting if desired. +}; + +struct retro_system_timing +{ + double fps; // FPS of video content. + double sample_rate; // Sampling rate of audio. +}; + +struct retro_system_av_info +{ + struct retro_game_geometry geometry; + struct retro_system_timing timing; +}; + +struct retro_variable +{ + const char *key; // Variable to query in RETRO_ENVIRONMENT_GET_VARIABLE. + // If NULL, obtains the complete environment string if more complex parsing is necessary. + // The environment string is formatted as key-value pairs delimited by semicolons as so: + // "key1=value1;key2=value2;..." + const char *value; // Value to be obtained. If key does not exist, it is set to NULL. +}; + +struct retro_game_info +{ + const char *path; // Path to game, UTF-8 encoded. Usually used as a reference. + // May be NULL if rom was loaded from stdin or similar. + // retro_system_info::need_fullpath guaranteed that this path is valid. + const void *data; // Memory buffer of loaded game. Will be NULL if need_fullpath was set. + size_t size; // Size of memory buffer. + const char *meta; // String of implementation specific meta-data. +}; + +// Callbacks +// +// Environment callback. Gives implementations a way of performing uncommon tasks. Extensible. +typedef bool (*retro_environment_t)(unsigned cmd, void *data); + +// Render a frame. Pixel format is 15-bit 0RGB1555 native endian unless changed (see RETRO_ENVIRONMENT_SET_PIXEL_FORMAT). +// Width and height specify dimensions of buffer. +// Pitch specifices length in bytes between two lines in buffer. +typedef void (*retro_video_refresh_t)(const void *data, unsigned width, unsigned height, size_t pitch); + +// Renders a single audio frame. Should only be used if implementation generates a single sample at a time. +// Format is signed 16-bit native endian. +typedef void (*retro_audio_sample_t)(int16_t left, int16_t right); +// Renders multiple audio frames in one go. One frame is defined as a sample of left and right channels, interleaved. +// I.e. int16_t buf[4] = { l, r, l, r }; would be 2 frames. +// Only one of the audio callbacks must ever be used. +typedef size_t (*retro_audio_sample_batch_t)(const int16_t *data, size_t frames); + +// Polls input. +typedef void (*retro_input_poll_t)(void); +// Queries for input for player 'port'. device will be masked with RETRO_DEVICE_MASK. +// Specialization of devices such as RETRO_DEVICE_JOYPAD_MULTITAP that have been set with retro_set_controller_port_device() +// will still use the higher level RETRO_DEVICE_JOYPAD to request input. +typedef int16_t (*retro_input_state_t)(unsigned port, unsigned device, unsigned index, unsigned id); + +// Sets callbacks. retro_set_environment() is guaranteed to be called before retro_init(). +// The rest of the set_* functions are guaranteed to have been called before the first call to retro_run() is made. +void retro_set_environment(retro_environment_t); +void retro_set_video_refresh(retro_video_refresh_t); +void retro_set_audio_sample(retro_audio_sample_t); +void retro_set_audio_sample_batch(retro_audio_sample_batch_t); +void retro_set_input_poll(retro_input_poll_t); +void retro_set_input_state(retro_input_state_t); + +// Library global initialization/deinitialization. +void retro_init(void); +void retro_deinit(void); + +// Must return RETRO_API_VERSION. Used to validate ABI compatibility when the API is revised. +unsigned retro_api_version(void); + +// Gets statically known system info. Pointers provided in *info must be statically allocated. +// Can be called at any time, even before retro_init(). +void retro_get_system_info(struct retro_system_info *info); + +// Gets information about system audio/video timings and geometry. +// Can be called only after retro_load_game() has successfully completed. +void retro_get_system_av_info(struct retro_system_av_info *info); + +// Sets device to be used for player 'port'. +void retro_set_controller_port_device(unsigned port, unsigned device); + +// Resets the current game. +void retro_reset(void); + +// Runs the game for one video frame. +// During retro_run(), input_poll callback must be called at least once. +// +// If a frame is not rendered for reasons where a game "dropped" a frame, +// this still counts as a frame, and retro_run() should explicitly dupe a frame if GET_CAN_DUPE returns true. +// In this case, the video callback can take a NULL argument for data. +void retro_run(void); + +// Returns the amount of data the implementation requires to serialize internal state (save states). +// Beetween calls to retro_load_game() and retro_unload_game(), the returned size is never allowed to be larger than a previous returned value, to +// ensure that the frontend can allocate a save state buffer once. +size_t retro_serialize_size(void); + +// Serializes internal state. If failed, or size is lower than retro_serialize_size(), it should return false, true otherwise. +bool retro_serialize(void *data, size_t size); +bool retro_unserialize(const void *data, size_t size); + +void retro_cheat_reset(void); +void retro_cheat_set(unsigned index, bool enabled, const char *code); + +// Loads a game. +bool retro_load_game(const struct retro_game_info *game); + +// Loads a "special" kind of game. Should not be used except in extreme cases. +bool retro_load_game_special( + unsigned game_type, + const struct retro_game_info *info, size_t num_info +); + +// Unloads a currently loaded game. +void retro_unload_game(void); + +// Gets region of game. +unsigned retro_get_region(void); + +// Gets region of memory. +void *retro_get_memory_data(unsigned id); +size_t retro_get_memory_size(unsigned id); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/libretro/link.T b/libretro/link.T new file mode 100644 index 0000000..b0c262d --- /dev/null +++ b/libretro/link.T @@ -0,0 +1,5 @@ +{ + global: retro_*; + local: *; +}; + diff --git a/libretro/msvc/msvc-2010-360.sln b/libretro/msvc/msvc-2010-360.sln new file mode 100644 index 0000000..e2735ee --- /dev/null +++ b/libretro/msvc/msvc-2010-360.sln @@ -0,0 +1,32 @@ + +Microsoft Visual Studio Solution File, Format Version 11.00 +# Visual Studio 2010 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "genesis-next-msvc-2010-360", "msvc-2010-360/msvc-2010-360.vcxproj", "{00CE82EC-E948-4BB6-B726-23BF1571B05A}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + CodeAnalysis|Xbox 360 = CodeAnalysis|Xbox 360 + Debug|Xbox 360 = Debug|Xbox 360 + Profile_FastCap|Xbox 360 = Profile_FastCap|Xbox 360 + Profile|Xbox 360 = Profile|Xbox 360 + Release_LTCG|Xbox 360 = Release_LTCG|Xbox 360 + Release|Xbox 360 = Release|Xbox 360 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {00CE82EC-E948-4BB6-B726-23BF1571B05A}.CodeAnalysis|Xbox 360.ActiveCfg = CodeAnalysis|Xbox 360 + {00CE82EC-E948-4BB6-B726-23BF1571B05A}.CodeAnalysis|Xbox 360.Build.0 = CodeAnalysis|Xbox 360 + {00CE82EC-E948-4BB6-B726-23BF1571B05A}.Debug|Xbox 360.ActiveCfg = Debug|Xbox 360 + {00CE82EC-E948-4BB6-B726-23BF1571B05A}.Debug|Xbox 360.Build.0 = Debug|Xbox 360 + {00CE82EC-E948-4BB6-B726-23BF1571B05A}.Profile_FastCap|Xbox 360.ActiveCfg = Profile_FastCap|Xbox 360 + {00CE82EC-E948-4BB6-B726-23BF1571B05A}.Profile_FastCap|Xbox 360.Build.0 = Profile_FastCap|Xbox 360 + {00CE82EC-E948-4BB6-B726-23BF1571B05A}.Profile|Xbox 360.ActiveCfg = Profile|Xbox 360 + {00CE82EC-E948-4BB6-B726-23BF1571B05A}.Profile|Xbox 360.Build.0 = Profile|Xbox 360 + {00CE82EC-E948-4BB6-B726-23BF1571B05A}.Release_LTCG|Xbox 360.ActiveCfg = Release_LTCG|Xbox 360 + {00CE82EC-E948-4BB6-B726-23BF1571B05A}.Release_LTCG|Xbox 360.Build.0 = Release_LTCG|Xbox 360 + {00CE82EC-E948-4BB6-B726-23BF1571B05A}.Release|Xbox 360.ActiveCfg = Release|Xbox 360 + {00CE82EC-E948-4BB6-B726-23BF1571B05A}.Release|Xbox 360.Build.0 = Release|Xbox 360 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/libretro/msvc/msvc-2010-360/msvc-2010-360.vcxproj b/libretro/msvc/msvc-2010-360/msvc-2010-360.vcxproj new file mode 100644 index 0000000..58e66e9 --- /dev/null +++ b/libretro/msvc/msvc-2010-360/msvc-2010-360.vcxproj @@ -0,0 +1,618 @@ + + + + + CodeAnalysis + Xbox 360 + + + Debug + Xbox 360 + + + Profile + Xbox 360 + + + Profile_FastCap + Xbox 360 + + + Release + Xbox 360 + + + Release_LTCG + Xbox 360 + + + + + CompileAsC + CompileAsC + CompileAsC + CompileAsC + CompileAsC + CompileAsC + + + CompileAsC + CompileAsC + CompileAsC + CompileAsC + CompileAsC + CompileAsC + + + CompileAsC + CompileAsC + CompileAsC + CompileAsC + CompileAsC + CompileAsC + + + CompileAsC + CompileAsC + CompileAsC + CompileAsC + CompileAsC + CompileAsC + + + CompileAsC + CompileAsC + CompileAsC + CompileAsC + CompileAsC + CompileAsC + + + CompileAsC + CompileAsC + CompileAsC + CompileAsC + CompileAsC + CompileAsC + + + CompileAsC + CompileAsC + CompileAsC + CompileAsC + CompileAsC + CompileAsC + + + CompileAsC + CompileAsC + CompileAsC + CompileAsC + CompileAsC + CompileAsC + + + CompileAsC + CompileAsC + CompileAsC + CompileAsC + CompileAsC + CompileAsC + + + CompileAsC + CompileAsC + CompileAsC + CompileAsC + CompileAsC + CompileAsC + + + CompileAsC + CompileAsC + CompileAsC + CompileAsC + CompileAsC + CompileAsC + + + CompileAsC + CompileAsC + CompileAsC + CompileAsC + CompileAsC + CompileAsC + + + CompileAsC + CompileAsC + CompileAsC + CompileAsC + CompileAsC + CompileAsC + + + CompileAsC + CompileAsC + CompileAsC + CompileAsC + CompileAsC + CompileAsC + + + CompileAsC + CompileAsC + CompileAsC + CompileAsC + CompileAsC + CompileAsC + + + CompileAsC + CompileAsC + CompileAsC + CompileAsC + CompileAsC + CompileAsC + + + CompileAsC + CompileAsC + CompileAsC + CompileAsC + CompileAsC + CompileAsC + + + CompileAsC + CompileAsC + CompileAsC + CompileAsC + CompileAsC + CompileAsC + + + CompileAsC + CompileAsC + CompileAsC + CompileAsC + CompileAsC + CompileAsC + + + CompileAsC + CompileAsC + CompileAsC + CompileAsC + CompileAsC + CompileAsC + + + CompileAsC + CompileAsC + CompileAsC + CompileAsC + CompileAsC + CompileAsC + + + CompileAsC + CompileAsC + CompileAsC + CompileAsC + CompileAsC + CompileAsC + + + CompileAsC + CompileAsC + CompileAsC + CompileAsC + CompileAsC + CompileAsC + + + + CompileAsC + CompileAsC + CompileAsC + CompileAsC + CompileAsC + CompileAsC + + + CompileAsC + CompileAsC + CompileAsC + CompileAsC + CompileAsC + CompileAsC + + + CompileAsC + CompileAsC + CompileAsC + CompileAsC + CompileAsC + CompileAsC + + + CompileAsC + CompileAsC + CompileAsC + CompileAsC + CompileAsC + CompileAsC + + + CompileAsC + CompileAsC + CompileAsC + CompileAsC + CompileAsC + CompileAsC + + + CompileAsC + CompileAsC + CompileAsC + CompileAsC + CompileAsC + CompileAsC + + + CompileAsC + CompileAsC + CompileAsC + CompileAsC + CompileAsC + CompileAsC + + + CompileAsC + CompileAsC + CompileAsC + CompileAsC + CompileAsC + CompileAsC + + + CompileAsC + CompileAsC + CompileAsC + CompileAsC + CompileAsC + CompileAsC + + + CompileAsC + CompileAsC + CompileAsC + CompileAsC + CompileAsC + CompileAsC + + + CompileAsC + CompileAsC + CompileAsC + CompileAsC + CompileAsC + CompileAsC + + + CompileAsC + CompileAsC + CompileAsC + CompileAsC + CompileAsC + CompileAsC + + + CompileAsC + CompileAsC + CompileAsC + CompileAsC + CompileAsC + CompileAsC + + + CompileAsC + CompileAsC + CompileAsC + CompileAsC + CompileAsC + CompileAsC + + + CompileAsC + CompileAsC + CompileAsC + CompileAsC + CompileAsC + CompileAsC + + + CompileAsC + CompileAsC + CompileAsC + CompileAsC + CompileAsC + CompileAsC + + + CompileAsC + CompileAsC + CompileAsC + CompileAsC + CompileAsC + CompileAsC + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + {00CE82EC-E948-4BB6-B726-23BF1571B05A} + Xbox360Proj + genesis-next-msvc-2010-360 + + + + StaticLibrary + MultiByte + + + StaticLibrary + MultiByte + + + StaticLibrary + MultiByte + + + StaticLibrary + MultiByte + + + StaticLibrary + MultiByte + + + StaticLibrary + true + MultiByte + + + + + + + + + + + + + + + + + + + + + + + + + $(OutDir)libretro_xdk360$(TargetExt) + + + $(OutDir)libretro_xdk360$(TargetExt) + + + $(OutDir)libretro_xdk360$(TargetExt) + + + $(OutDir)libretro_xdk360$(TargetExt) + + + $(OutDir)libretro_xdk360$(TargetExt) + + + $(OutDir)libretro_xdk360$(TargetExt) + + + + NotUsing + Level3 + ProgramDatabase + Disabled + false + true + false + $(OutDir)$(ProjectName).pch + MultiThreadedDebug + _DEBUG;_XBOX;_LIB;INLINE=static _inline;__attribute__=;__inline__=_inline;__extension__=;USE_15BPP_RENDERING;__LIBRETRO__;%(PreprocessorDefinitions);__LIBRETRO__USE_ZLIB__ + Callcap + $(SolutionDir)\..\libretro;$(SolutionDir)\..\src;$(SolutionDir)\..\src\m68k;$(SolutionDir)\..\src\sound;$(SolutionDir)\..\src\cart_hw;$(SolutionDir)\..\src\cart_hw\svp;$(SolutionDir)\..\src\input_hw;$(SolutionDir)\..\src\ntsc;$(SolutionDir)\..\src\z80;%(AdditionalIncludeDirectories) + CompileAsC + + + true + + + + + NotUsing + Level4 + ProgramDatabase + Disabled + false + true + AnalyzeOnly + false + $(OutDir)$(ProjectName).pch + MultiThreadedDebug + _DEBUG;_XBOX;_LIB;%(PreprocessorDefinitions);__LIBRETRO__USE_ZLIB__ + Callcap + $(SolutionDir)\..\libretro;$(SolutionDir)\..\src;$(SolutionDir)\..\src\m68k;$(SolutionDir)\..\src\sound;$(SolutionDir)\..\src\cart_hw;$(SolutionDir)\..\src\cart_hw\svp;$(SolutionDir)\..\src\input_hw;$(SolutionDir)\..\src\ntsc;$(SolutionDir)\..\src\z80;%(AdditionalIncludeDirectories) + CompileAsC + + + true + + + + + Level3 + NotUsing + Full + true + false + true + ProgramDatabase + Size + false + $(OutDir)$(ProjectName).pch + MultiThreaded + NDEBUG;_XBOX;PROFILE;_LIB;%(PreprocessorDefinitions);__LIBRETRO__USE_ZLIB__ + Callcap + $(SolutionDir)\..\libretro;$(SolutionDir)\..\src;$(SolutionDir)\..\src\m68k;$(SolutionDir)\..\src\sound;$(SolutionDir)\..\src\cart_hw;$(SolutionDir)\..\src\cart_hw\svp;$(SolutionDir)\..\src\input_hw;$(SolutionDir)\..\src\ntsc;$(SolutionDir)\..\src\z80;%(AdditionalIncludeDirectories) + CompileAsC + + + true + false + xapilib.lib;%(IgnoreSpecificDefaultLibraries) + true + + + + + Level3 + NotUsing + Full + true + false + true + ProgramDatabase + Fastcap + Size + false + $(OutDir)$(ProjectName).pch + MultiThreaded + NDEBUG;_XBOX;PROFILE;FASTCAP;_LIB;%(PreprocessorDefinitions);__LIBRETRO__USE_ZLIB__ + $(SolutionDir)\..\libretro;$(SolutionDir)\..\src;$(SolutionDir)\..\src\m68k;$(SolutionDir)\..\src\sound;$(SolutionDir)\..\src\cart_hw;$(SolutionDir)\..\src\cart_hw\svp;$(SolutionDir)\..\src\input_hw;$(SolutionDir)\..\src\ntsc;$(SolutionDir)\..\src\z80;%(AdditionalIncludeDirectories) + CompileAsC + + + true + false + true + + + + + Level3 + NotUsing + Full + true + true + ProgramDatabase + Size + false + false + $(OutDir)$(ProjectName).pch + MultiThreaded + NDEBUG;_XBOX;_LIB;INLINE=static _inline;__inline__=_inline;__extension__=;USE_15BPP_RENDERING;__LIBRETRO__;%(PreprocessorDefinitions);__LIBRETRO__USE_ZLIB__ + $(SolutionDir)\..\libretro;$(SolutionDir)\..\src;$(SolutionDir)\..\src\m68k;$(SolutionDir)\..\src\sound;$(SolutionDir)\..\src\cart_hw;$(SolutionDir)\..\src\cart_hw\svp;$(SolutionDir)\..\src\input_hw;$(SolutionDir)\..\src\ntsc;$(SolutionDir)\..\src\z80;%(AdditionalIncludeDirectories) + CompileAsC + + + true + true + true + + + + + Level3 + NotUsing + Full + true + true + ProgramDatabase + Size + false + false + $(OutDir)$(ProjectName).pch + MultiThreaded + NDEBUG;_XBOX;LTCG;_LIB;INLINE=static _inline;__inline__=_inline;__extension__=;USE_15BPP_RENDERING;__LIBRETRO__;%(PreprocessorDefinitions);__LIBRETRO__USE_ZLIB__ + $(SolutionDir)\..\libretro;$(SolutionDir)\..\src;$(SolutionDir)\..\src\m68k;$(SolutionDir)\..\src\sound;$(SolutionDir)\..\src\cart_hw;$(SolutionDir)\..\src\cart_hw\svp;$(SolutionDir)\..\src\input_hw;$(SolutionDir)\..\src\ntsc;$(SolutionDir)\..\src\z80;%(AdditionalIncludeDirectories) + CompileAsC + + + true + true + true + + + + + + diff --git a/libretro/msvc/msvc-2010-360/msvc-2010-360.vcxproj.filters b/libretro/msvc/msvc-2010-360/msvc-2010-360.vcxproj.filters new file mode 100644 index 0000000..b91af40 --- /dev/null +++ b/libretro/msvc/msvc-2010-360/msvc-2010-360.vcxproj.filters @@ -0,0 +1,350 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hpp;hxx;hm;inl;inc;xsd + + + {c0268b8d-1c7d-44d5-ae67-e3e365c991b7} + + + {c3d17076-e795-431e-b50f-7606c81367b9} + + + {5351583e-dbd9-4060-8497-6ddfd31e3666} + + + {943f2af4-23b4-43eb-b9cd-91cc7af172c5} + + + {ff45bed3-12a9-437d-ac34-7e83518ba624} + + + {f0c37c57-d905-4002-a129-5b9ffc907c05} + + + {2f0a4c83-ad74-4742-baef-35fafdca0e67} + + + {c9414edf-4224-4099-8f74-b0e568024aaf} + + + {a4dfea3d-749a-49ef-8da0-83b11b257674} + + + {31cd36b8-e005-4711-b914-e959f77f84c2} + + + {72abffc5-b66c-49dd-85e9-534022a36bc6} + + + {4756672f-68e1-40c7-b78f-2a962c9bbe9e} + + + {48e868f1-3e80-4888-9273-2b6676beb9f7} + + + {7ce7e0de-8fc7-48bd-8fda-8afa919ee775} + + + {53739b7c-d154-46d2-8a8d-28cc67c675aa} + + + {c90aed8d-25e3-439e-acec-f66acc8b4c0d} + + + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files\m68k + + + Source Files\sound + + + Source Files\sound + + + Source Files\sound + + + Source Files\sound + + + Source Files\sound + + + Source Files\sound + + + Source Files\sound + + + Source Files\cart_hw + + + Source Files\cart_hw + + + Source Files\cart_hw + + + Source Files\cart_hw + + + Source Files\cart_hw + + + Source Files\cart_hw + + + Source Files\cart_hw + + + Source Files\input_hw + + + Source Files\input_hw + + + Source Files\input_hw + + + Source Files\input_hw + + + Source Files\input_hw + + + Source Files\input_hw + + + Source Files\input_hw + + + Source Files\input_hw + + + Source Files\input_hw + + + Source Files\input_hw + + + Source Files\z80 + + + Source Files\cart_hw\svp + + + Source Files\cart_hw\svp + + + Source Files\libretro + + + Source Files\ntsc + + + Source Files\ntsc + + + + + Header Files\libretro + + + Header Files\libretro + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files\cart_hw + + + Header Files\cart_hw + + + Header Files\cart_hw + + + Header Files\cart_hw + + + Header Files\cart_hw + + + Header Files\cart_hw + + + Header Files\cart_hw + + + Header Files\input_hw + + + Header Files\input_hw + + + Header Files\input_hw + + + Header Files\input_hw + + + Header Files\input_hw + + + Header Files\input_hw + + + Header Files\input_hw + + + Header Files\input_hw + + + Header Files\input_hw + + + Header Files\input_hw + + + Header Files\sound + + + Header Files\sound + + + Header Files\sound + + + Header Files\sound + + + Header Files\sound + + + Header Files\sound + + + Header Files\sound + + + Header Files\z80 + + + Header Files\z80 + + + Header Files\m68k + + + Header Files\m68k + + + Header Files\m68k + + + Header Files\m68k + + + Header Files\cart_hw\svp + + + Header Files\cart_hw\svp + + + Header Files\ntsc + + + Header Files\ntsc + + + Header Files\ntsc + + + Header Files\ntsc + + + Header Files\ntsc + + + Header Files\ntsc + + + diff --git a/libretro/msvc/msvc-2010.sln b/libretro/msvc/msvc-2010.sln new file mode 100644 index 0000000..c3c278d --- /dev/null +++ b/libretro/msvc/msvc-2010.sln @@ -0,0 +1,20 @@ + +Microsoft Visual Studio Solution File, Format Version 11.00 +# Visual Studio 2010 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "msvc-2010", "msvc-2010/msvc-2010.vcxproj", "{29DF2EE7-2930-4BD3-8AC5-81A2534ACC99}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + Release|Win32 = Release|Win32 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {29DF2EE7-2930-4BD3-8AC5-81A2534ACC99}.Debug|Win32.ActiveCfg = Debug|Win32 + {29DF2EE7-2930-4BD3-8AC5-81A2534ACC99}.Debug|Win32.Build.0 = Debug|Win32 + {29DF2EE7-2930-4BD3-8AC5-81A2534ACC99}.Release|Win32.ActiveCfg = Release|Win32 + {29DF2EE7-2930-4BD3-8AC5-81A2534ACC99}.Release|Win32.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/libretro/msvc/msvc-2010/libretro.def b/libretro/msvc/msvc-2010/libretro.def new file mode 100644 index 0000000..2a71c09 --- /dev/null +++ b/libretro/msvc/msvc-2010/libretro.def @@ -0,0 +1,27 @@ +LIBRARY "libretro-prboom msvc2010" +EXPORTS +retro_set_environment +retro_set_video_refresh +retro_set_audio_sample +retro_set_audio_sample_batch +retro_set_input_poll +retro_set_input_state +retro_init +retro_deinit +retro_api_version +retro_get_system_info +retro_get_system_av_info +retro_set_controller_port_device +retro_reset +retro_run +retro_serialize_size +retro_serialize +retro_unserialize +retro_cheat_reset +retro_cheat_set +retro_load_game +retro_load_game_special +retro_unload_game +retro_get_region +retro_get_memory_data +retro_get_memory_size diff --git a/libretro/msvc/msvc-2010/msvc-2010.vcxproj b/libretro/msvc/msvc-2010/msvc-2010.vcxproj new file mode 100644 index 0000000..672fdfc --- /dev/null +++ b/libretro/msvc/msvc-2010/msvc-2010.vcxproj @@ -0,0 +1,319 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + + {29DF2EE7-2930-4BD3-8AC5-81A2534ACC99} + Win32Proj + msvc2010 + genesis-next-msvc-2010 + + + + DynamicLibrary + true + Unicode + + + DynamicLibrary + false + true + Unicode + + + + + + + + + + + + + true + libretro + + + false + libretro + + + + + + Level3 + Disabled + WIN32;_DEBUG;_WINDOWS;_USRDLL;MSVC2010_EXPORTS;_CRT_SECURE_NO_WARNINGS;INLINE=static _inline;__inline__=_inline;__extension__=;LSB_FIRST;__LIBRETRO__;USE_15BPP_RENDERING;%(PreprocessorDefinitions) + $(SolutionDir)/../src;$(SolutionDir)/../utils/zlib;$(SolutionDir)/../src/cart_hw/svp;$(SolutionDir)/../libretro;$(SolutionDir)/../src/m68k;$(SolutionDir)/../src/z80;$(SolutionDir)/../src/input_hw;$(SolutionDir)/../src/cart_hw;$(SolutionDir)/../src/sound;$(SolutionDir)/../src/ntsc;%(AdditionalIncludeDirectories) + + + Windows + true + libretro.def + + + + + Level3 + + + MaxSpeed + true + true + WIN32;NDEBUG;_WINDOWS;_USRDLL;MSVC2010_EXPORTS;_CRT_SECURE_NO_WARNINGS;INLINE=static _inline;__inline__=_inline;__extension__=;LSB_FIRST;__LIBRETRO__;USE_15BPP_RENDERING;%(PreprocessorDefinitions) + $(SolutionDir)/../src;$(SolutionDir)/../utils/zlib;$(SolutionDir)/../src/cart_hw/svp;$(SolutionDir)/../libretro;$(SolutionDir)/../src/m68k;$(SolutionDir)/../src/z80;$(SolutionDir)/../src/input_hw;$(SolutionDir)/../src/cart_hw;$(SolutionDir)/../src/sound;$(SolutionDir)/../src/ntsc;%(AdditionalIncludeDirectories) + + + Windows + true + true + true + libretro.def + + + + + CompileAsC + CompileAsC + + + CompileAsC + CompileAsC + + + CompileAsC + CompileAsC + + + CompileAsC + CompileAsC + + + CompileAsC + CompileAsC + + + CompileAsC + CompileAsC + + + CompileAsC + CompileAsC + + + CompileAsC + CompileAsC + + + CompileAsC + CompileAsC + + + CompileAsC + CompileAsC + + + CompileAsC + CompileAsC + + + CompileAsC + CompileAsC + + + CompileAsC + CompileAsC + + + CompileAsC + CompileAsC + + + CompileAsC + CompileAsC + + + CompileAsC + CompileAsC + + + CompileAsC + CompileAsC + + + CompileAsC + CompileAsC + + + CompileAsC + CompileAsC + + + CompileAsC + CompileAsC + + + CompileAsC + CompileAsC + + + CompileAsC + CompileAsC + + + CompileAsC + CompileAsC + + + CompileAsC + CompileAsC + + + CompileAsC + CompileAsC + + + CompileAsC + CompileAsC + + + CompileAsC + CompileAsC + + + CompileAsC + CompileAsC + + + CompileAsC + CompileAsC + + + CompileAsC + CompileAsC + + + CompileAsC + CompileAsC + + + CompileAsC + CompileAsC + + + CompileAsC + CompileAsC + + + CompileAsC + CompileAsC + + + CompileAsC + CompileAsC + + + CompileAsC + CompileAsC + + + CompileAsC + CompileAsC + + + CompileAsC + CompileAsC + + + CompileAsC + CompileAsC + + + CompileAsC + CompileAsC + + + CompileAsC + CompileAsC + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/libretro/msvc/msvc-2010/msvc-2010.vcxproj.filters b/libretro/msvc/msvc-2010/msvc-2010.vcxproj.filters new file mode 100644 index 0000000..3b79ab7 --- /dev/null +++ b/libretro/msvc/msvc-2010/msvc-2010.vcxproj.filters @@ -0,0 +1,390 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + {e0f9ca3b-df0f-4cf9-bde1-9fa3c945b0df} + + + {0605ef1a-d898-494c-a898-8f06000646ae} + + + {8b373848-96f7-4410-a466-5d7cb6866b0f} + + + {ea37a461-94f4-40e3-91a8-2b254b94f547} + + + {becebb08-7987-4fe3-8ee0-dd47889d4996} + + + {e66cf784-cb76-4a70-a2e0-327a3b4c96eb} + + + {39a1110f-2062-4e3c-9f43-aca63cc20cda} + + + {95e90e29-1915-4f70-b6e0-50b9dace48cf} + + + {2d43f01a-655e-4052-a900-51a34992c5de} + + + {6d10d7fc-8d96-43e1-8e4e-bfdc000e301c} + + + {163bbf21-faa7-4192-b50a-a4767bf9747b} + + + {a142c167-5986-4e2b-9673-6d32158b19c5} + + + {5202f178-780c-4312-bf82-0161b7af4657} + + + {878a07f3-c007-46a9-b695-749cf7a74cee} + + + {7e019ffb-cb39-421f-bc49-bde151103026} + + + {5ff9df4d-6de7-495c-8a2d-155709c2c4a6} + + + {1a79b638-97fd-46c8-b75d-aa93debaed87} + + + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files\z80 + + + Source Files\m68k + + + Source Files\cart_hw + + + Source Files\cart_hw + + + Source Files\cart_hw + + + Source Files\cart_hw + + + Source Files\cart_hw + + + Source Files\cart_hw + + + Source Files\cart_hw + + + Source Files\cart_hw\svp + + + Source Files\cart_hw\svp + + + Source Files\sound + + + Source Files\sound + + + Source Files\sound + + + Source Files\sound + + + Source Files\sound + + + Source Files\sound + + + Source Files\sound + + + Source Files\input_hw + + + Source Files\input_hw + + + Source Files\input_hw + + + Source Files\input_hw + + + Source Files\input_hw + + + Source Files\input_hw + + + Source Files\input_hw + + + Source Files\input_hw + + + Source Files\input_hw + + + Source Files\input_hw + + + Source Files\ntsc + + + Source Files\ntsc + + + Source Files\libretro + + + + + Header Files\libretro + + + Header Files\libretro + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files\z80 + + + Header Files\z80 + + + Header Files\m68k + + + Header Files\m68k + + + Header Files\m68k + + + Header Files\m68k + + + Header Files\input_hw + + + Header Files\input_hw + + + Header Files\input_hw + + + Header Files\input_hw + + + Header Files\input_hw + + + Header Files\input_hw + + + Header Files\input_hw + + + Header Files\input_hw + + + Header Files\input_hw + + + Header Files\input_hw + + + Header Files\sound + + + Header Files\sound + + + Header Files\sound + + + Header Files\sound + + + Header Files\sound + + + Header Files\sound + + + Header Files\sound + + + Header Files\ntsc + + + Header Files\ntsc + + + Header Files\ntsc + + + Header Files\ntsc + + + Header Files\ntsc + + + Header Files\ntsc + + + Header Files\cart_hw + + + Header Files\cart_hw + + + Header Files\cart_hw + + + Header Files\cart_hw + + + Header Files\cart_hw + + + Header Files\cart_hw + + + Header Files\cart_hw + + + Header Files\cart_hw\svp + + + Header Files\cart_hw\svp + + + Header Files\zlib + + + Header Files\zlib + + + Header Files\zlib + + + Header Files\zlib + + + Header Files\zlib + + + Header Files\zlib + + + Header Files\zlib + + + Header Files\zlib + + + Header Files\zlib + + + Header Files\zlib + + + Header Files\zlib + + + \ No newline at end of file diff --git a/libretro/osd.h b/libretro/osd.h new file mode 100644 index 0000000..e056150 --- /dev/null +++ b/libretro/osd.h @@ -0,0 +1,114 @@ +#ifndef _OSD_H +#define _OSD_H + +#ifdef _MSC_VER +#include +typedef unsigned char bool; +#define strncasecmp _strnicmp +#endif + +#include +#include +#include + +#define MAX_INPUTS 8 +#define MAX_KEYS 8 +#define MAXPATHLEN 1024 + +#ifndef TRUE +#define TRUE 1 +#endif + +#ifndef FALSE +#define FALSE 0 +#endif + +#ifndef M_PI +#define M_PI 3.1415926535897932385 +#endif + +typedef struct +{ + int8 device; + uint8 port; + uint8 padtype; +} t_input_config; + +typedef struct +{ + char version[16]; + uint8 hq_fm; + uint8 filter; + uint8 psgBoostNoise; + uint8 dac_bits; + uint8 ym2413; + int16 psg_preamp; + int16 fm_preamp; + int16 lp_range; + int16 low_freq; + int16 high_freq; + int16 lg; + int16 mg; + int16 hg; + float rolloff; + uint8 system; + uint8 region_detect; + uint8 master_clock; + uint8 vdp_mode; + uint8 force_dtack; + uint8 addr_error; + uint8 tmss; + uint8 bios; + uint8 lock_on; + uint8 hot_swap; + uint8 invert_mouse; + uint8 gun_cursor[2]; + uint8 overscan; + uint8 ntsc; + uint8 vsync; + uint8 render; + uint8 tv_mode; + uint8 bilinear; + uint8 aspect; + int16 xshift; + int16 yshift; + int16 xscale; + int16 yscale; + t_input_config input[MAX_INPUTS]; + uint16 pad_keymap[4][MAX_KEYS]; + uint8 autoload; + uint8 autocheat; + uint8 s_auto; + uint8 s_default; + uint8 s_device; + uint8 l_device; + uint8 bg_overlay; + int16 screen_w; + float bgm_volume; + float sfx_volume; + char lastdir[4][2][MAXPATHLEN]; +} t_config; + +/* Global data */ +t_config config; + +extern char GG_ROM[256]; +extern char AR_ROM[256]; +extern char SK_ROM[256]; +extern char SK_UPMEM[256]; +extern char GG_BIOS[256]; +extern char CD_BIOS_EU[256]; +extern char CD_BIOS_US[256]; +extern char CD_BIOS_JP[256]; +extern char MS_BIOS_US[256]; +extern char MS_BIOS_EU[256]; +extern char MS_BIOS_JP[256]; + +extern int16 soundbuffer[1920]; + +#define VERSION "Genesis Plus GX 1.7.0 (libretro)" + +void osd_input_update(void); +int load_archive(char *filename, unsigned char *buffer, int maxsize); + +#endif /* _OSD_H */ diff --git a/libretro/scrc32.h b/libretro/scrc32.h new file mode 100644 index 0000000..e65ea23 --- /dev/null +++ b/libretro/scrc32.h @@ -0,0 +1,79 @@ +#ifndef _S_CRC32_H +#define _S_CRC32_H + +static const unsigned long crc_table[256] = { + 0x00000000L, 0x77073096L, 0xee0e612cL, 0x990951baL, 0x076dc419L, + 0x706af48fL, 0xe963a535L, 0x9e6495a3L, 0x0edb8832L, 0x79dcb8a4L, + 0xe0d5e91eL, 0x97d2d988L, 0x09b64c2bL, 0x7eb17cbdL, 0xe7b82d07L, + 0x90bf1d91L, 0x1db71064L, 0x6ab020f2L, 0xf3b97148L, 0x84be41deL, + 0x1adad47dL, 0x6ddde4ebL, 0xf4d4b551L, 0x83d385c7L, 0x136c9856L, + 0x646ba8c0L, 0xfd62f97aL, 0x8a65c9ecL, 0x14015c4fL, 0x63066cd9L, + 0xfa0f3d63L, 0x8d080df5L, 0x3b6e20c8L, 0x4c69105eL, 0xd56041e4L, + 0xa2677172L, 0x3c03e4d1L, 0x4b04d447L, 0xd20d85fdL, 0xa50ab56bL, + 0x35b5a8faL, 0x42b2986cL, 0xdbbbc9d6L, 0xacbcf940L, 0x32d86ce3L, + 0x45df5c75L, 0xdcd60dcfL, 0xabd13d59L, 0x26d930acL, 0x51de003aL, + 0xc8d75180L, 0xbfd06116L, 0x21b4f4b5L, 0x56b3c423L, 0xcfba9599L, + 0xb8bda50fL, 0x2802b89eL, 0x5f058808L, 0xc60cd9b2L, 0xb10be924L, + 0x2f6f7c87L, 0x58684c11L, 0xc1611dabL, 0xb6662d3dL, 0x76dc4190L, + 0x01db7106L, 0x98d220bcL, 0xefd5102aL, 0x71b18589L, 0x06b6b51fL, + 0x9fbfe4a5L, 0xe8b8d433L, 0x7807c9a2L, 0x0f00f934L, 0x9609a88eL, + 0xe10e9818L, 0x7f6a0dbbL, 0x086d3d2dL, 0x91646c97L, 0xe6635c01L, + 0x6b6b51f4L, 0x1c6c6162L, 0x856530d8L, 0xf262004eL, 0x6c0695edL, + 0x1b01a57bL, 0x8208f4c1L, 0xf50fc457L, 0x65b0d9c6L, 0x12b7e950L, + 0x8bbeb8eaL, 0xfcb9887cL, 0x62dd1ddfL, 0x15da2d49L, 0x8cd37cf3L, + 0xfbd44c65L, 0x4db26158L, 0x3ab551ceL, 0xa3bc0074L, 0xd4bb30e2L, + 0x4adfa541L, 0x3dd895d7L, 0xa4d1c46dL, 0xd3d6f4fbL, 0x4369e96aL, + 0x346ed9fcL, 0xad678846L, 0xda60b8d0L, 0x44042d73L, 0x33031de5L, + 0xaa0a4c5fL, 0xdd0d7cc9L, 0x5005713cL, 0x270241aaL, 0xbe0b1010L, + 0xc90c2086L, 0x5768b525L, 0x206f85b3L, 0xb966d409L, 0xce61e49fL, + 0x5edef90eL, 0x29d9c998L, 0xb0d09822L, 0xc7d7a8b4L, 0x59b33d17L, + 0x2eb40d81L, 0xb7bd5c3bL, 0xc0ba6cadL, 0xedb88320L, 0x9abfb3b6L, + 0x03b6e20cL, 0x74b1d29aL, 0xead54739L, 0x9dd277afL, 0x04db2615L, + 0x73dc1683L, 0xe3630b12L, 0x94643b84L, 0x0d6d6a3eL, 0x7a6a5aa8L, + 0xe40ecf0bL, 0x9309ff9dL, 0x0a00ae27L, 0x7d079eb1L, 0xf00f9344L, + 0x8708a3d2L, 0x1e01f268L, 0x6906c2feL, 0xf762575dL, 0x806567cbL, + 0x196c3671L, 0x6e6b06e7L, 0xfed41b76L, 0x89d32be0L, 0x10da7a5aL, + 0x67dd4accL, 0xf9b9df6fL, 0x8ebeeff9L, 0x17b7be43L, 0x60b08ed5L, + 0xd6d6a3e8L, 0xa1d1937eL, 0x38d8c2c4L, 0x4fdff252L, 0xd1bb67f1L, + 0xa6bc5767L, 0x3fb506ddL, 0x48b2364bL, 0xd80d2bdaL, 0xaf0a1b4cL, + 0x36034af6L, 0x41047a60L, 0xdf60efc3L, 0xa867df55L, 0x316e8eefL, + 0x4669be79L, 0xcb61b38cL, 0xbc66831aL, 0x256fd2a0L, 0x5268e236L, + 0xcc0c7795L, 0xbb0b4703L, 0x220216b9L, 0x5505262fL, 0xc5ba3bbeL, + 0xb2bd0b28L, 0x2bb45a92L, 0x5cb36a04L, 0xc2d7ffa7L, 0xb5d0cf31L, + 0x2cd99e8bL, 0x5bdeae1dL, 0x9b64c2b0L, 0xec63f226L, 0x756aa39cL, + 0x026d930aL, 0x9c0906a9L, 0xeb0e363fL, 0x72076785L, 0x05005713L, + 0x95bf4a82L, 0xe2b87a14L, 0x7bb12baeL, 0x0cb61b38L, 0x92d28e9bL, + 0xe5d5be0dL, 0x7cdcefb7L, 0x0bdbdf21L, 0x86d3d2d4L, 0xf1d4e242L, + 0x68ddb3f8L, 0x1fda836eL, 0x81be16cdL, 0xf6b9265bL, 0x6fb077e1L, + 0x18b74777L, 0x88085ae6L, 0xff0f6a70L, 0x66063bcaL, 0x11010b5cL, + 0x8f659effL, 0xf862ae69L, 0x616bffd3L, 0x166ccf45L, 0xa00ae278L, + 0xd70dd2eeL, 0x4e048354L, 0x3903b3c2L, 0xa7672661L, 0xd06016f7L, + 0x4969474dL, 0x3e6e77dbL, 0xaed16a4aL, 0xd9d65adcL, 0x40df0b66L, + 0x37d83bf0L, 0xa9bcae53L, 0xdebb9ec5L, 0x47b2cf7fL, 0x30b5ffe9L, + 0xbdbdf21cL, 0xcabac28aL, 0x53b39330L, 0x24b4a3a6L, 0xbad03605L, + 0xcdd70693L, 0x54de5729L, 0x23d967bfL, 0xb3667a2eL, 0xc4614ab8L, + 0x5d681b02L, 0x2a6f2b94L, 0xb40bbe37L, 0xc30c8ea1L, 0x5a05df1bL, + 0x2d02ef8dL +}; + +#define DO1_CRC32(buf) crc = crc_table[((int)crc ^ (*buf++)) & 0xff] ^ (crc >> 8); +#define DO2_CRC32(buf) DO1_CRC32(buf); DO1_CRC32(buf); +#define DO4_CRC32(buf) DO2_CRC32(buf); DO2_CRC32(buf); +#define DO8_CRC32(buf) DO4_CRC32(buf); DO4_CRC32(buf); + +static unsigned long crc32(unsigned long crc, const unsigned char *buf, unsigned int len) +{ + if (buf == 0) return 0L; + crc = crc ^ 0xffffffffL; + while (len >= 8) + { + DO8_CRC32(buf); + len -= 8; + } + if (len) do { + DO1_CRC32(buf); + } while (--len); + return crc ^ 0xffffffffL; +} + +#endif \ No newline at end of file