Commit e8bad8c3 authored by Toad King's avatar Toad King
Browse files

initial libretro changes

parent 6fb0c7a7

*.o
retro.*
DEBUG=0
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
CC = gcc
ifeq ($(platform), unix)
TARGET := libretro.so
fpic := -fPIC
SHARED := -shared -Wl,--version-script=libretro/link.T
else ifeq ($(platform), osx)
TARGET := libretro.dylib
fpic := -fPIC
SHARED := -dynamiclib
else ifeq ($(platform), ps3)
TARGET := libretro.a
CC = $(CELL_SDK)/host-win32/ppu/bin/ppu-lv2-gcc.exe
AR = $(CELL_SDK)/host-win32/ppu/bin/ppu-lv2-ar.exe
CFLAGS += -DBLARGG_BIG_ENDIAN=1 -D__ppc__
else ifeq ($(platform), sncps3)
TARGET := libretro.a
CC = $(CELL_SDK)/host-win32/sn/bin/ps3ppusnc.exe
AR = $(CELL_SDK)/host-win32/sn/bin/ps3snarl.exe
CFLAGS += -DBLARGG_BIG_ENDIAN=1 -D__ppc__
else ifeq ($(platform), xenon)
TARGET := libretro.a
CC = xenon-gcc
AR = xenon-ar
CFLAGS += -D__LIBXENON__ -m32 -D__ppc__
else ifeq ($(platform), wii)
TARGET := libretro.a
CC = $(DEVKITPPC)/bin/powerpc-eabi-gcc
AR = $(DEVKITPPC)/bin/powerpc-eabi-ar
CFLAGS += -DGEKKO -mrvl -mcpu=750 -meabi -mhard-float -DBLARGG_BIG_ENDIAN=1 -D__ppc__
else
TARGET := retro.dll
CC = gcc
fpic :=
LD_FLAGS :=
SHARED := -shared -static-libgcc -static-libstdc++ -Wl,--version-script=libretro/link.T
CFLAGS += -D__WIN32__ -D__WIN32_LIBRETRO__
endif
ifeq ($(DEBUG), 1)
CFLAGS += -O0 -g
else
CFLAGS += -O3
endif
OBJECTS = ./src/apu.o ./src/apuaux.o ./src/c4.o ./src/c4emu.o ./src/cheats.o ./src/cheats2.o ./src/clip.o ./src/data.o ./src/screenshot.o ./src/dsp1.o ./src/fxemu.o ./src/fxinst.o ./src/globals.o ./src/loadzip.o ./src/ppu.o ./src/dma.o ./src/memmap.o ./src/cpu.o ./src/cpuexec.o ./src/cpuops.o ./src/sa1.o ./src/sa1cpu.o ./src/sdd1.o ./src/sdd1emu.o ./src/snapshot.o ./src/soundux.o ./src/spc700.o ./src/spc700a.o ./src/srtc.o ./src/spc_decode.o ./src/tile16.o ./src/tile16add.o ./src/tile16add1_2.o ./src/tile16fadd1_2.o ./src/tile16sub.o ./src/tile16sub1_2.o ./src/tile16fsub1_2.o ./src/mode7new.o ./src/mode7.o ./src/mode7add.o ./src/mode7add1_2.o ./src/mode7sub.o ./src/mode7sub1_2.o ./src/mode7prio.o ./src/mode7addprio.o ./src/mode7add1_2prio.o ./src/mode7subprio.o ./src/mode7sub1_2prio.o ./src/gfx16.o ./src/rops.o ./libretro/libretro.o ./libretro/memstream.o
INCLUDES = -I.
DEFINES = -DHAVE_STRINGS_H -DHAVE_STDINT_H -DHAVE_INTTYPES_H -D__LIBRETRO__ -DINLINE=inline -DUSE_SA1
ifeq ($(platform), sncps3)
WARNINGS_DEFINES =
CODE_DEFINES =
else
WARNINGS_DEFINES = -Wall -W -Wno-unused-parameter -Wno-parentheses -Wno-write-strings -Wno-comment
CODE_DEFINES = -fomit-frame-pointer
endif
COMMON_DEFINES += $(CODE_DEFINES) $(WARNINGS_DEFINES) -DNDEBUG=1 $(fpic)
CFLAGS += $(DEFINES) $(COMMON_DEFINES)
all: $(TARGET)
$(TARGET): $(OBJECTS)
ifeq ($(platform), ps3)
$(AR) rcs $@ $(OBJECTS)
else ifeq ($(platform), sncps3)
$(AR) rcs $@ $(OBJECTS)
else ifeq ($(platform), xenon)
$(AR) rcs $@ $(OBJECTS)
else ifeq ($(platform), wii)
$(AR) rcs $@ $(OBJECTS)
else
$(CXX) $(fpic) $(SHARED) $(INCLUDES) -o $@ $(OBJECTS) -lm
endif
%.o: %.c
$(CC) $(INCLUDES) $(CFLAGS) -c -o $@ $<
%.o: %.cpp
$(CXX) $(INCLUDES) $(CFLAGS) -c -o $@ $<
%.o: %.s
$(CXX) $(INCLUDES) $(CFLAGS) -Wa,-I./src/ -c -o $@ $<
%.o: %.S
$(CXX) $(INCLUDES) $(CFLAGS) -Wa,-I./src/ -c -o $@ $<
clean:
rm -f $(OBJECTS) $(TARGET)
.PHONY: clean
#include <stdio.h>
#include <stdint.h>
#ifndef _MSC_VER
#include <stdbool.h>
#include <unistd.h>
#endif
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <fcntl.h>
#include "libretro.h"
#include "memstream.h"
#include "../src/snes9x.h"
#include "../src/memmap.h"
#include "../src/cpuexec.h"
#include "../src/srtc.h"
#include "../src/apu.h"
#include "../src/ppu.h"
#include "../src/snapshot.h"
#include "../src/soundux.h"
#include "../src/cheats.h"
#include "../src/display.h"
#define MAP_BUTTON(id, name) S9xMapButton((id), S9xGetCommandT((name)), false)
#define MAKE_BUTTON(pad, btn) (((pad)<<4)|(btn))
#define BTN_POINTER (RETRO_DEVICE_ID_JOYPAD_R + 1)
#define BTN_POINTER2 (BTN_POINTER + 1)
static retro_video_refresh_t video_cb = NULL;
static retro_input_poll_t poll_cb = NULL;
static retro_input_state_t input_cb = NULL;
static retro_audio_sample_batch_t audio_batch_cb = NULL;
static retro_environment_t environ_cb = NULL;
static uint32 joys[5];
bool8 ROMAPUEnabled = 0;
char currentWorkingDir[MAX_PATH+1] = {0};
memstream_t *s_stream;
int s_open(const char *fname, const char *mode)
{
s_stream = memstream_open();
return TRUE;
}
int s_read(void *p, int l)
{
return memstream_read(s_stream, p, l);
}
int s_write(void *p, int l)
{
return memstream_write(s_stream, p, l);
}
void s_close()
{
memstream_close(s_stream);
}
int (*statef_open)(const char *fname, const char *mode) = s_open;
int (*statef_read)(void *p, int l) = s_read;
int (*statef_write)(void *p, int l) = s_write;
void (*statef_close)() = s_close;
void *retro_get_memory_data(unsigned type)
{
uint8_t* data;
switch(type)
{
case RETRO_MEMORY_SAVE_RAM:
data = Memory.SRAM;
break;
case RETRO_MEMORY_SYSTEM_RAM:
data = Memory.RAM;
break;
case RETRO_MEMORY_VIDEO_RAM:
data = Memory.VRAM;
break;
default:
data = NULL;
break;
}
return data;
}
size_t retro_get_memory_size(unsigned type)
{
unsigned size;
switch(type)
{
case RETRO_MEMORY_SAVE_RAM:
size = (unsigned) (Memory.SRAMSize ? (1 << (Memory.SRAMSize + 3)) * 128 : 0);
if (size > 0x20000)
size = 0x20000;
break;
/*case RETRO_MEMORY_RTC:
size = (Settings.SRTC || Settings.SPC7110RTC)?20:0;
break;*/
case RETRO_MEMORY_SYSTEM_RAM:
size = 128 * 1024;
break;
case RETRO_MEMORY_VIDEO_RAM:
size = 64 * 1024;
break;
default:
size = 0;
break;
}
return size;
}
unsigned retro_api_version(void)
{
return RETRO_API_VERSION;
}
void retro_set_video_refresh(retro_video_refresh_t cb)
{
video_cb = cb;
}
void retro_set_audio_sample(retro_audio_sample_t 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)
{
poll_cb = cb;
}
void retro_set_input_state(retro_input_state_t cb)
{
input_cb = cb;
}
static bool use_overscan;
void retro_set_environment(retro_environment_t cb)
{
environ_cb = cb;
}
void retro_get_system_info(struct retro_system_info *info)
{
info->need_fullpath = false;
info->valid_extensions = "smc|fig|sfc|gd3|gd7|dx2|bsx|swc|zip|SMC|FIG|SFC|BSX|GD3|GD7|DX2|SWC|ZIP";
info->library_version = "7.2.0";
info->library_name = "PocketSNES";
info->block_extract = false;
}
static int16 audio_buf[0x10000];
int avail = 534;
void S9xGenerateSound()
{
}
uint32 S9xReadJoypad(int which1)
{
if (which1 > 4)
return 0;
return joys[which1];
}
void retro_set_controller_port_device(unsigned in_port, unsigned device)
{
}
void retro_get_system_av_info(struct retro_system_av_info *info)
{
info->geometry.base_width = 256;
info->geometry.base_height = 239;
info->geometry.max_width = 512;
info->geometry.max_height = 512;
if (!Settings.PAL)
info->timing.fps = 21477272.0 / 357366.0;
else
info->timing.fps = 21281370.0 / 425568.0;
info->timing.sample_rate = 32040.5;
info->geometry.aspect_ratio = 4.0f / 3.0f;
}
static void snes_init (void)
{
memset(&Settings, 0, sizeof(Settings));
Settings.JoystickEnabled = FALSE;
Settings.SoundPlaybackRate = 32000;
Settings.Stereo = TRUE;
Settings.SoundBufferSize = 0;
Settings.CyclesPercentage = 100;
Settings.DisableSoundEcho = FALSE;
Settings.APUEnabled = FALSE;
Settings.H_Max = SNES_CYCLES_PER_SCANLINE;
Settings.SkipFrames = AUTO_FRAMERATE;
Settings.Shutdown = Settings.ShutdownMaster = TRUE;
Settings.FrameTimePAL = 20000;
Settings.FrameTimeNTSC = 16667;
Settings.FrameTime = Settings.FrameTimeNTSC;
Settings.DisableSampleCaching = FALSE;
Settings.DisableMasterVolume = FALSE;
Settings.Mouse = FALSE;
Settings.SuperScope = FALSE;
Settings.MultiPlayer5 = FALSE;
// Settings.ControllerOption = SNES_MULTIPLAYER5;
Settings.ControllerOption = 0;
Settings.ForceTransparency = FALSE;
Settings.Transparency = TRUE;
Settings.SixteenBit = TRUE;
Settings.SupportHiRes = FALSE;
Settings.NetPlay = FALSE;
Settings.ServerName [0] = 0;
Settings.AutoSaveDelay = 30;
Settings.ApplyCheats = FALSE;
Settings.TurboMode = FALSE;
Settings.TurboSkipFrames = 15;
Settings.ThreadSound = FALSE;
Settings.SoundSync = FALSE;
Settings.asmspc700 = TRUE;
Settings.SpeedHacks = TRUE;
Settings.HBlankStart = (256 * Settings.H_Max) / SNES_HCOUNTER_MAX;
/*
Settings.SoundPlaybackRate = 5;
Settings.Stereo = TRUE;
Settings.SoundBufferSize = 0;
Settings.DisableSoundEcho = 0;
Settings.AltSampleDecode = 0;
Settings.SoundEnvelopeHeightReading = FALSE;
Settings.FixFrequency = 0;
Settings.CyclesPercentage = 100;
Settings.InterpolatedSound = TRUE;
Settings.APUEnabled = Settings.NextAPUEnabled = TRUE;
Settings.SoundMixInterval = 0;
Settings.H_Max = SNES_CYCLES_PER_SCANLINE;
Settings.SkipFrames = 10;
Settings.ShutdownMaster = TRUE;
Settings.FrameTimePAL = 20000;
Settings.FrameTimeNTSC = 16667;
Settings.DisableSampleCaching = FALSE;
Settings.DisableMasterVolume = FALSE;
Settings.Mouse = FALSE;
Settings.SuperScope = FALSE;
Settings.MultiPlayer5 = FALSE;
Settings.TurboMode = FALSE;
Settings.TurboSkipFrames = 40;
Settings.ControllerOption = SNES_MULTIPLAYER5;
Settings.Transparency = TRUE;
Settings.SixteenBit = TRUE;
Settings.SupportHiRes = TRUE;
Settings.NetPlay = FALSE;
Settings.ServerName [0] = 0;
Settings.ThreadSound = FALSE;
Settings.AutoSaveDelay = 30;
Settings.HBlankStart = (256 * Settings.H_Max) / SNES_HCOUNTER_MAX;
Settings.DisplayFrameRate = FALSE;
Settings.ReverseStereo = TRUE;
*/
CPU.Flags = 0;
if (!Memory.Init() || !S9xInitAPU())
{
Memory.Deinit();
S9xDeinitAPU();
fprintf(stderr, "[libsnes]: Failed to init Memory or APU.\n");
exit(1);
}
if (!S9xInitSound() || !S9xGraphicsInit()) exit(1);
//S9xSetSamplesAvailableCallback(S9xAudioCallback);
GFX.Pitch = use_overscan ? 1024 : 2048;
// hack to make sure GFX.Delta is always (2048 * 512 * 2) >> 1, needed for tile16_t.h
GFX.Screen = (uint8 *) calloc(1, 2048 * 512 * 2 * 2);
GFX.SubScreen = GFX.Screen + 2048 * 512 * 2;
GFX.ZBuffer = (uint8 *) calloc(1, GFX.Pitch * 512 * sizeof(uint16));
GFX.SubZBuffer = (uint8 *) calloc(1, GFX.Pitch * 512 * sizeof(uint16));
GFX.Delta = 1048576; //(GFX.SubScreen - GFX.Screen) >> 1;
if (GFX.Delta != ((GFX.SubScreen - GFX.Screen) >> 1))
{
printf("BAD DELTA! (is %u, should be %u)\n", ((GFX.SubScreen - GFX.Screen) >> 1), GFX.Delta);
exit(1);
}
/* controller port 1 */
//S9xSetController(0, CTL_JOYPAD, 0, 0, 0, 0);
//retro_devices[0] = RETRO_DEVICE_JOYPAD;
/* controller port 2 */
//S9xSetController(1, CTL_JOYPAD, 1, 0, 0, 0);
//retro_devices[1] = RETRO_DEVICE_JOYPAD;
//S9xUnmapAllControls();
//map_buttons();
//S9xSetSoundMute(FALSE);
}
void retro_init (void)
{
if (!environ_cb(RETRO_ENVIRONMENT_GET_OVERSCAN, &use_overscan))
use_overscan = FALSE;
snes_init();
}
/* libsnes uses relative values for analogue devices.
S9x seems to use absolute values, but do convert these into relative values in the core. (Why?!)
Hack around it. :) */
void retro_deinit(void)
{
S9xDeinitAPU();
Memory.Deinit();
S9xGraphicsDeinit();
//S9xUnmapAllControls();
}
void retro_reset (void)
{
S9xReset();
}
//static int16_t retro_mouse_state[2][2] = {{0}, {0}};
//static int16_t retro_scope_state[2] = {0};
//static int16_t retro_justifier_state[2][2] = {{0}, {0}};
void S9xSetButton(int i, uint16 b, bool pressed);
static void report_buttons (void)
{
int i, j;
for ( i = 0; i < 5; i++)
{
for (j = 0; j <= RETRO_DEVICE_ID_JOYPAD_R; j++)
{
if (input_cb(i, RETRO_DEVICE_JOYPAD, 0, j))
joys[i] |= (1 << (15 - j));
else
joys[i] &= ~(1 << (15 - j));
}
}
}
void retro_run (void)
{
S9xMainLoop();
S9xMixSamples(audio_buf, avail * 2);
audio_batch_cb((int16_t *) audio_buf, avail);
poll_cb();
report_buttons();
}
size_t retro_serialize_size (void)
{
uint8_t *tmpbuf;
tmpbuf = (uint8_t*)malloc(5000000);
memstream_set_buffer(tmpbuf, 5000000);
S9xFreezeGame("");
free(tmpbuf);
return memstream_get_last_size();
}
bool retro_serialize(void *data, size_t size)
{
memstream_set_buffer((uint8_t*)data, size);
if (S9xFreezeGame("") == FALSE)
return FALSE;
return TRUE;
}
bool retro_unserialize(const void * data, size_t size)
{
memstream_set_buffer((uint8_t*)data, size);
if (S9xUnfreezeGame("") == FALSE)
return FALSE;
return TRUE;
}
void retro_cheat_reset(void)
{}
void retro_cheat_set(unsigned unused, bool unused1, const char* unused2)
{}
bool retro_load_game(const struct retro_game_info *game)
{
bool8 loaded;
/* Hack. S9x cannot do stuff from RAM. <_< */
memstream_set_buffer((uint8_t*)game->data, game->size);
loaded = Memory.LoadROM("");
if (!loaded)
{
fprintf(stderr, "[libretro]: Rom loading failed...\n");
return FALSE;
}
//S9xGraphicsInit();
S9xReset();
CPU.APU_APUExecuting = Settings.APUEnabled = 3;
Settings.SixteenBitSound = true;
so.stereo = Settings.Stereo;
so.playback_rate = Settings.SoundPlaybackRate;
S9xSetPlaybackRate(so.playback_rate);
S9xSetSoundMute(FALSE);
return TRUE;
}
bool retro_load_game_special(
unsigned game_type,
const struct retro_game_info *info, size_t num_info
)
{ return false; }
void retro_unload_game (void)
{ }
unsigned retro_get_region (void)
{
return Settings.PAL ? RETRO_REGION_PAL : RETRO_REGION_NTSC;
}
bool8 S9xDeinitUpdate(int width, int height, bool8 sixteen_bit)
{
int y;
if (height == 448 || height == 478)
{
/* Pitch 2048 -> 1024, only done once per res-change. */
if (GFX.Pitch == 2048)
{
for ( y = 1; y < height; y++)
{
uint8_t *src = GFX.Screen + y * 1024;
uint8_t *dst = GFX.Screen + y * 512;
memcpy(dst, src, width * sizeof(uint8_t) * 2);
}
}
GFX.Pitch = 1024;
}
else
{
/* Pitch 1024 -> 2048, only done once per res-change. */
if (GFX.Pitch == 1024)
{
for ( y = height - 1; y >= 0; y--)
{
uint8_t *src = GFX.Screen + y * 512;
uint8_t *dst = GFX.Screen + y * 1024;
memcpy(dst, src, width * sizeof(uint8_t) * 2);
}
}
GFX.Pitch = 2048;
}
video_cb(GFX.Screen, width, height, GFX_PITCH);
return TRUE;
}
/* Dummy functions that should probably be implemented correctly later. */
const char* S9xGetFilename(const char* in) { return in; }
const char* S9xGetFilenameInc(const char* in) { return in; }
const char *S9xGetHomeDirectory() { return NULL; }
const char *S9xGetSnapshotDirectory() { return NULL; }
const char *S9xGetROMDirectory() { return NULL; }
const char* S9xChooseFilename(bool8 a) { return NULL; }
bool8 S9xInitUpdate() { return TRUE; }
bool8 S9xContinueUpdate(int width, int height) { return TRUE; }
void S9xSetPalette() {}
void S9xAutoSaveSRAM() {}
void S9xLoadSDD1Data() {}
bool8 S9xReadMousePosition (int which1_0_to_1, int &x, int &y, uint32 &buttons) { return FALSE; }
bool8 S9xReadSuperScopePosition (int &x, int &y, uint32 &buttons) { return FALSE; }
void JustifierButtons(uint32& x) {}
bool JustifierOffscreen() { return false; }
START_EXTERN_C
void S9xToggleSoundChannel (int channel) {}
bool8 S9xMovieActive() { return FALSE; }
bool8 S9xMoviePlaying() { return FALSE; }
void S9xMovieFreeze() {}