Add libsnes target files (Themaister, twinaphex)

This commit is contained in:
Barry Harris 2012-01-27 20:56:17 +00:00
parent 6fb16325cd
commit dd8063a633
8 changed files with 1600 additions and 0 deletions

107
makefile.libsnes Normal file
View File

@ -0,0 +1,107 @@
DEBUG=0
ifeq ($(platform),)
platform = unix
ifeq ($(shell uname -a),)
platform = win
else ifneq ($(findstring Darwin,$(shell uname -a)),)
platform = osx
else ifneq ($(findstring MINGW,$(shell uname -a)),)
platform = win
endif
endif
ifeq ($(platform), unix)
TARGET := libsnes.so
fpic := -fPIC
SHARED := -shared -Wl,-no-undefined
ENDIANNESS_DEFINES := -DLSB_FIRST
else ifeq ($(platform), osx)
TARGET := libsnes.dylib
fpic := -fPIC
SHARED := -dynamiclib
ENDIANNESS_DEFINES := -DLSB_FIRST
else ifeq ($(platform), ps3)
TARGET := libsnes.a
SHARED := -shared, -Wl, --version-script=libsnes/link.T
CC = ppu-lv2-gcc
CXX = ppu-lv2-g++
AR = ppu-lv2-ar
ENDIANNESS_DEFINES = -DWORDS_BIGENDIAN
PLATFORM_DEFINES := -D__CELLOS_LV2 -DSN_TARGET_PS3
else
TARGET := snes.dll
CC = gcc
CXX = g++
SHARED := -shared -Wl,-no-undefined
LDFLAGS += -static-libgcc -static-libstdc++
ENDIANNESS_DEFINES := -DLSB_FIRST
endif
all: $(TARGET)
MAIN_FBA_DIR := ./fbalpha/trunk/src
FBA_BURN_DIR := $(MAIN_FBA_DIR)/burn
FBA_BURN_DRIVERS_DIR := $(MAIN_FBA_DIR)/burn/drivers
FBA_BURNER_DIR := $(MAIN_FBA_DIR)/burner
LIBSNES_DIR := ./libsnes
FBA_CPU_DIR := $(MAIN_FBA_DIR)/cpu
FBA_LIB_DIR := ./utils
FBA_INTERFACE_DIR := $(MAIN_FBA_DIR)/interface
BURN_BLACKLIST := $(FBA_BURN_DIR)/zet_c68k.cpp $(FBA_BURN_DIR)/sek_c68k.cpp $(FBA_BURNER_DIR)/tracklst.cpp $(FBA_CPU_DIR)/arm7/arm7exec.c $(FBA_CPU_DIR)/arm7/arm7core.c $(FBA_CPU_DIR)/hd6309/6309tbl.c $(FBA_CPU_DIR)/hd6309/6309ops.c $(FBA_CPU_DIR)/konami/konamtbl.c $(FBA_CPU_DIR)/konami/konamops.c $(FBA_CPU_DIR)/m68k/m68k_in.c $(FBA_CPU_DIR)/m6800/6800ops.c $(FBA_CPU_DIR)/m6800/6800tbl.c $(FBA_CPU_DIR)/m6805/6805ops.c $(FBA_CPU_DIR)/m6809/6809ops.c $(FBA_CPU_DIR)/m6809/6809tbl.c $(FBA_CPU_DIR)/sh2/mksh2.cpp $(FBA_CPU_DIR)/sh2/mksh2-x86.cpp $(FBA_CPU_DIR)/m68k/m68kmake.c $(FBA_BURNER_DIR)/wave_writer.cpp $(FBA_CPU_DIR)/m68k/m68kdasm.c $(FBA_LIBSNES_DIR)/menu.cpp $(FBA_CPU_DIR)/sh2/mksh2.cpp $(FBA_BURNER_DIR)/sshot.cpp $(FBA_BURNER_DIR)/conc.cpp $(FBA_BURNER_DIR)/dat.cpp $(FBA_BURNER_DIR)/cong.cpp $(FBA_BURNER_DIR)/image.cpp $(FBA_BURNER_DIR)/misc.cpp $(FBA_CPU_DIR)/h6280/tblh6280.c $(FBA_CPU_DIR)/m6502/t65sc02.c $(FBA_CPU_DIR)/m6502/t65c02.c $(FBA_CPU_DIR)/m6502/tdeco16.c $(FBA_CPU_DIR)/m6502/tn2a03.c $(FBA_CPU_DIR)/m6502/t6502.c $(FBA_CPU_DIR)/nec/v25sfr.c $(FBA_CPU_DIR)/nec/v25instr.c $(FBA_CPU_DIR)/nec/necinstr.c $(FBA_BURN_DIR)/drivers/capcom/ctv_make.cpp
FBA_BURN_DIRS := $(FBA_BURN_DIR) $(FBA_BURN_DIR)/devices $(FBA_BURN_DIR)/sound $(FBA_BURN_DRIVERS_DIR)/capcom $(FBA_BURN_DRIVERS_DIR)/cave $(FBA_BURN_DRIVERS_DIR)/dataeast $(FBA_BURN_DRIVERS_DIR)/cps3 $(FBA_BURN_DRIVERS_DIR)/galaxian $(FBA_BURN_DRIVERS_DIR)/konami $(FBA_BURN_DRIVERS_DIR)/irem $(FBA_BURN_DRIVERS_DIR)/megadrive $(FBA_BURN_DRIVERS_DIR)/misc $(FBA_BURN_DRIVERS_DIR)/neogeo $(FBA_BURN_DRIVERS_DIR)/pgm $(FBA_BURN_DRIVERS_DIR)/psikyo $(FBA_BURN_DRIVERS_DIR)/sega $(FBA_BURN_DRIVERS_DIR)/taito $(FBA_BURN_DRIVERS_DIR)/toaplan $(FBA_BURN_DRIVERS_DIR)/misc_post90s $(FBA_BURN_DRIVERS_DIR)/misc_pre90s
FBA_CPU_DIRS := $(FBA_CPU_DIR) $(FBA_CPU_DIR)/arm7 $(FBA_CPU_DIR)/arm $(FBA_CPU_DIR)/hd6309 $(FBA_CPU_DIR)/i8039 $(FBA_CPU_DIR)/konami $(FBA_CPU_DIR)/m68k $(FBA_CPU_DIR)/m6502 $(FBA_CPU_DIR)/m6800 $(FBA_CPU_DIR)/m6805 $(FBA_CPU_DIR)/m6809 $(FBA_CPU_DIR)/nec $(FBA_CPU_DIR)/s2650 $(FBA_CPU_DIR)/sh2 $(FBA_CPU_DIR)/z80 $(FBA_CPU_DIR)/h6280
FBA_LIB_DIRS := $(FBA_LIB_DIR)/zlib $(FBA_LIB_DIR)/File_Extractor/fex $(FBA_LIB_DIR)/File_Extractor/7z_C
FBA_SRC_DIRS := $(FBA_BURNER_DIR) $(FBA_BURN_DIRS) $(FBA_CPU_DIRS) $(FBA_BURNER_DIRS) $(FBA_LIB_DIRS)
FBA_CXXSRCS := $(filter-out $(BURN_BLACKLIST),$(foreach dir,$(FBA_SRC_DIRS),$(wildcard $(dir)/*.cpp)))
FBA_CXXSRCS += $(LIBSNES_DIR)/libsnes.cpp $(LIBSNES_DIR)/archive.cpp $(FBA_BURNER_DIR)/platform/win32/neocdlist.cpp
FBA_CXXOBJ := $(FBA_CXXSRCS:.cpp=.o)
FBA_CSRCS := $(filter-out $(BURN_BLACKLIST),$(foreach dir,$(FBA_SRC_DIRS),$(wildcard $(dir)/*.c)))
FBA_COBJ := $(FBA_CSRCS:.c=.o)
OBJS := $(FBA_COBJ) $(FBA_CXXOBJ)
FBA_DEFINES := -DNO_ASMCORE -DNO_AUTOFIRE -DNO_CHEATSEARCH -DNO_COMBO -DUSE_SPEEDHACKS -DNO_PNG -DOLD_AUDIOCORE=0 -D__LIBSNES__ $(ENDIANNESS_DEFINES) $(PLATFORM_DEFINES) -DTIXML_USE_TICPP
ifeq ($(DEBUG), 1)
CFLAGS += -O0 -g
CXXFLAGS += -O0 -g
else
CFLAGS += -O3 -DNDEBUG
CXXFLAGS += -O3 -DNDEBUG
endif
CFLAGS += -std=gnu99 $(fpic) -Wno-write-strings $(FBA_DEFINES)
CXXFLAGS += $(fpic) -Wno-write-strings $(FBA_DEFINES)
LDFLAGS += -Wl,-no-undefined $(fpic) -Wl,--version-script=libsnes/link.T
INCDIRS := -I$(FBA_BURNER_DIR)/platform/win32 -I$(LIBSNES_DIR) -I$(FBA_BURN_DIR) -I$(FBA_BURN_DIR)/burner -I$(MAIN_FBA_DIR)/cpu -I$(FBA_BURN_DIR)/sound -I$(FBA_BURN_DIR)/devices -I../../generated -I$(FBA_INTERFACE_DIR) -I$(FBA_INTERFACE_DIR)/input -I$(FBA_INTERFACE_DIR)/cd -I$(FBA_BURNER_DIR) -I$(MAIN_FBA_DIR)/generated -I$(FBA_CPU_DIR) -I$(FBA_CPU_DIR)/m6809 -I$(FBA_CPU_DIR)/m6805 -I$(FBA_CPU_DIR)/m6800 -I$(FBA_CPU_DIR)/nec -I$(FBA_CPU_DIR)/hd6309 -I$(FBA_CPU_DIR)/arm7 -I$(FBA_CPU_DIR)/i8039 -I$(FBA_CPU_DIR)/konami -I$(FBA_CPU_DIR)/m68k -I$(FBA_CPU_DIR)/m6502 -I$(FBA_CPU_DIR)/z80 -I$(FBA_CPU_DIR)/sh2 -I$(FBA_CPU_DIR)/s2650 -I$(FBA_CPU_DIR)/arm -I$(FBA_LIB_DIR)/zlib -I$(FBA_BURN_DIR)/drivers/capcom -I$(FBA_BURN_DIR)/drivers/dataeast -I$(FBA_BURN_DIR)/drivers/cave -I$(FBA_BURN_DIR)/drivers/neogeo -I$(FBA_BURN_DIR)/drivers/psikyo -I$(FBA_BURN_DIR)/drivers/sega -I$(FBA_BURN_DIR)/drivers/toaplan -I$(FBA_BURN_DIR)/drivers/taito -I$(FBA_BURN_DIR)/drivers/misc_post90s -I$(FBA_LIB_DIR)
$(TARGET): $(OBJS)
@echo "LD $@"
ifeq ($(platform), ps3)
@$(AR) rcs $@ $(OBJECTS)
else
@$(CXX) -o $@ $(SHARED) $(OBJS) $(LDFLAGS)
endif
%.o: %.cpp
@echo "CXX $<"
@$(CXX) -c -o $@ $< $(CXXFLAGS) $(INCDIRS)
%.o: %.c
@echo "CC $<"
@$(CC) -c -o $@ $< $(CFLAGS) $(INCDIRS)
clean:
rm -f $(TARGET)
rm -f $(OBJS)
.PHONY: clean

View File

@ -0,0 +1,296 @@
// Archive extract module, added by regret
// use Blargg's File_Extractor (http://www.slack.net/~ant/)
/* changelog:
update 5: change loadonefile() to use separate fex handle
update 4: update to Blargg's File_Extractor 1.0.0
update 3: rewrite interface, use Blargg's great File_Extractor
update 2: add load one file from archive
update 1: add 7zip aupport
*/
#include "burner.h"
#include "File_Extractor/fex/fex.h"
#include "archive.h"
static File_Extractor* fex = NULL;
static fex_err_t err = NULL;
static int nCurrFile = 0; // The current file we are pointing to
static inline bool error(const char* error)
{
if (error)
{
#ifdef _DEBUG
printf("fex Error: %s\n", error);
#endif
return true;
}
return false;
}
// check if input name has 7z or zip file, the name will link with extension
// return value: 0:zip; 1:7z; -1:none
int archiveCheck(char* name, int zipOnly)
{
if (!name)
return ARC_NONE;
static char archiveName[MAX_PATH] = "";
int ret = ARC_NONE;
// try zip first
sprintf(archiveName, "%s.zip", name);
static File_Extractor* fex_scan = NULL;
static fex_err_t err_scan = NULL;
err_scan = fex_open(&fex_scan, archiveName);
if (!error(err_scan)) {
ret = ARC_ZIP;
strcat(name, ".zip");
} else {
if (!zipOnly) {
// try 7z
sprintf(archiveName, "%s.7z", name);
err_scan = fex_open(&fex_scan, archiveName);
if (!error(err_scan)) {
ret = ARC_7Z;
strcat(name, ".7z");
}
}
}
if (fex_scan) {
fex_close(fex_scan);
fex_scan = NULL;
}
return ret;
}
int archiveOpen(const char* archive)
{
if (!archive)
return 1;
err = fex_open(&fex, archive);
if (error(err))
return 1;
nCurrFile = 0;
return 0;
}
int archiveClose()
{
if (fex) {
fex_close(fex);
fex = NULL;
}
return 0;
}
// Get the contents of a archive file into an array of ArcEntry
int archiveGetList(ArcEntry** list, int* count)
{
if (!fex || !list)
return 1;
int nListLen = 0;
while (!fex_done(fex))
{
err = fex_next(fex);
if (error(err))
{
archiveClose();
return 1;
}
nListLen++;
}
// Make an array of File Entries
if (nListLen == 0)
{
archiveClose();
return 1;
}
ArcEntry* List = (struct ArcEntry *)malloc(nListLen * sizeof(struct ArcEntry));
if (List == NULL)
{
archiveClose();
return 1;
}
memset(List, 0, nListLen * sizeof(ArcEntry));
err = fex_rewind(fex);
if (error(err))
{
archiveClose();
return 1;
}
// Step through all of the files, until we get to the end
for (nCurrFile = 0, err = NULL;
nCurrFile < nListLen && !error(err);
nCurrFile++, err = fex_next(fex))
{
fex_stat(fex);
// Allocate space for the filename
const char* name = fex_name(fex);
if (name == NULL) continue;
char* szName = (char *)malloc(strlen(name) + 1);
if (szName == NULL) continue;
strcpy(szName, name);
List[nCurrFile].szName = szName;
List[nCurrFile].nLen = fex_size(fex);
List[nCurrFile].nCrc = fex_crc32(fex);
}
// return the file list
*list = List;
if (count)
*count = nListLen;
err = fex_rewind(fex);
if (error(err))
{
archiveClose();
return 1;
}
nCurrFile = 0;
return 0;
}
int archiveLoadFile(uint8_t* dest, int nLen, int nEntry, int* wrote)
{
if (!fex || nLen <= 0)
return 1;
// if (nEntry < nCurrFile)
{
err = fex_rewind(fex);
if (error(err))
return 1;
nCurrFile = 0;
}
// Now step through to the file we need
while (nCurrFile < nEntry)
{
err = fex_next(fex);
if (error(err) || fex_done(fex))
return 1;
nCurrFile++;
}
err = fex_read(fex, dest, nLen);
if (error(err))
return 1;
if (wrote != NULL)
*wrote = nLen;
return 0;
}
int archiveLoadOneFile(const char* arc, const char* file, void** dest, int* wrote)
{
File_Extractor* fex_one = NULL;
fex_err_t err_one = fex_open(&fex_one, arc);
if (error(err_one))
return 1;
int nListLen = 0;
while (!fex_done(fex_one))
{
err_one = fex_next(fex_one);
if (error(err_one))
{
fex_close(fex_one);
return 1;
}
nListLen++;
}
if (nListLen <= 0)
{
fex_close(fex_one);
return 1;
}
err_one = fex_rewind(fex_one);
if (error(err_one))
{
fex_close(fex_one);
return 1;
}
if (file) {
const char* filename = file;
int currentFile = 0;
for (currentFile = 0, err_one = NULL;
currentFile < nListLen && !error(err_one);
currentFile++, err_one = fex_next(fex_one))
{
fex_stat(fex_one);
const char* name = fex_name(fex_one);
if (name == NULL)
continue;
if (!strcmp(name, filename))
break;
}
if (currentFile == nListLen)
{
fex_close(fex_one);
return 1; // didn't find
}
}
fex_stat(fex_one);
long len = fex_size(fex_one);
if (*dest == NULL)
{
*dest = (unsigned char*)malloc(len);
if (!*dest)
{
fex_close(fex_one);
return 1;
}
}
// Extract file
err_one = fex_read(fex_one, *dest, len);
if (wrote != NULL) *wrote = len;
fex_close(fex_one);
if (error(err_one))
{
free(*dest);
return 1;
}
return 0;
}

View File

@ -0,0 +1,18 @@
#ifndef ARCHIVE_H__
#define ARCHIVE_H__
#include <stdint.h>
#include <stddef.h>
struct ArcEntry { char* szName; unsigned int nLen; unsigned int nCrc; };
enum ARCTYPE { ARC_NONE = -1, ARC_ZIP = 0, ARC_7Z, ARC_NUM };
int archiveCheck(char* name, int zipOnly = 0);
int archiveOpen(const char* archive);
int archiveClose();
int archiveGetList(ArcEntry** list, int* count = NULL);
int archiveLoadFile(uint8_t* dest, int len, int entry, int* wrote = NULL);
#endif

View File

@ -0,0 +1,932 @@
#include "libsnes.hpp"
#include "archive.h"
#include "burner.h"
#include "inp_keys.h"
#include "state.h"
#include <string.h>
#include <stdio.h>
#include <vector>
#include <string>
#include <ctype.h>
// FBA cruft.
unsigned ArcadeJoystick;
int bDrvOkay;
int bRunPause;
bool bAlwaysProcessKeyboardInput;
struct ROMFIND
{
unsigned int nState;
int nArchive;
int nPos;
};
unsigned int BurnDrvGetIndexByName(const char* name);
int BurnDrvGetArchiveName(char** pszName, unsigned int i, bool ext, unsigned int type);
#define STAT_NOFIND 0
#define STAT_OK 1
#define STAT_CRC 2
#define STAT_SMALL 3
#define STAT_LARGE 4
static std::vector<std::string> g_find_list_path;
static ROMFIND g_find_list[1024];
static unsigned g_rom_count;
#define AUDIO_SEGMENT_LENGTH 534 // <-- Hardcoded value that corresponds well to 32kHz audio.
#define AUDIO_SEGMENT_LENGTH_TIMES_CHANNELS (534 * 2)
static uint16_t g_fba_frame[1024 * 1024];
static uint16_t g_fba_frame_conv[1024 * 1024];
static int16_t g_audio_buf[AUDIO_SEGMENT_LENGTH_TIMES_CHANNELS];
// libsnes globals
static snes_video_refresh_t video_cb;
static snes_audio_sample_t audio_cb;
static snes_input_poll_t poll_cb;
static snes_input_state_t input_cb;
void snes_set_video_refresh(snes_video_refresh_t cb) { video_cb = cb; }
void snes_set_audio_sample(snes_audio_sample_t cb) { audio_cb = cb; }
void snes_set_input_poll(snes_input_poll_t cb) { poll_cb = cb; }
void snes_set_input_state(snes_input_state_t cb) { input_cb = cb; }
// SSNES extension.
static snes_environment_t environ_cb;
void snes_set_environment(snes_environment_t cb) { environ_cb = cb; }
static char g_rom_name[1024];
static char g_rom_dir[1024];
static char g_basename[1024];
/////
static void poll_input();
static bool init_input();
// FBA stubs
TCHAR szAppHiscorePath[MAX_PATH];
TCHAR szAppSamplesPath[MAX_PATH];
TCHAR szAppBurnVer[16];
CDEmuStatusValue CDEmuStatus;
const char* isowavLBAToMSF(const int LBA) { return ""; }
int isowavMSFToLBA(const char* address) { return 0; }
TCHAR* GetIsoPath() { return NULL; }
INT32 CDEmuInit() { return 0; }
INT32 CDEmuExit() { return 0; }
INT32 CDEmuStop() { return 0; }
INT32 CDEmuPlay(UINT8 M, UINT8 S, UINT8 F) { return 0; }
INT32 CDEmuLoadSector(INT32 LBA, char* pBuffer) { return 0; }
UINT8* CDEmuReadTOC(INT32 track) { return 0; }
UINT8* CDEmuReadQChannel() { return 0; }
INT32 CDEmuGetSoundBuffer(INT16* buffer, INT32 samples) { return 0; }
void InpDIPSWResetDIPs (void) {}
int InputSetCooperativeLevel(const bool bExclusive, const bool bForeGround) { return 0; }
void Reinitialise(void) {}
// Non-idiomatic (OutString should be to the left to match strcpy())
// Seems broken to not check nOutSize.
char* TCHARToANSI(const TCHAR* pszInString, char* pszOutString, int /*nOutSize*/)
{
if (pszOutString)
{
strcpy(pszOutString, pszInString);
return pszOutString;
}
return (char*)pszInString;
}
int QuoteRead(char **, char **, char*) { return 1; }
char *LabelCheck(char *, char *) { return 0; }
const int nConfigMinVersion = 0x020921;
//////////////
static int find_rom_by_crc(unsigned crc, const ArcEntry *list, unsigned elems)
{
for (unsigned i = 0; i < elems; i++)
{
if (list[i].nCrc == crc)
return i;
}
return -1;
}
static void free_archive_list(ArcEntry *list, unsigned count)
{
if (list)
{
for (unsigned i = 0; i < count; i++)
free(list[i].szName);
free(list);
}
}
static int archive_load_rom(uint8_t *dest, int *wrote, int i)
{
if (i < 0 || i >= g_rom_count)
return 1;
int archive = g_find_list[i].nArchive;
if (archiveOpen(g_find_list_path[archive].c_str()))
return 1;
BurnRomInfo ri = {0};
BurnDrvGetRomInfo(&ri, i);
if (archiveLoadFile(dest, ri.nLen, g_find_list[i].nPos, wrote))
{
archiveClose();
return 1;
}
archiveClose();
return 0;
}
// This code is very confusing. The original code is even more confusing :(
static bool open_archive()
{
// FBA wants some roms ... Figure out how many.
g_rom_count = 0;
while (!BurnDrvGetRomInfo(0, g_rom_count))
g_rom_count++;
g_find_list_path.clear();
// Check if we have said archives.
// Check if archives are found. These are relative to g_rom_dir.
char *rom_name;
for (unsigned index = 0; index < 32; index++)
{
if (BurnDrvGetArchiveName(&rom_name, index, false, 0))
continue;
char path[1024];
snprintf(path, sizeof(path), "%s/%s", g_rom_dir, rom_name);
int ret = archiveCheck(path, 0);
if (ret == ARC_NONE)
continue;
g_find_list_path.push_back(path);
}
memset(g_find_list, 0, sizeof(g_find_list));
for (unsigned z = 0; z < g_find_list_path.size(); z++)
{
if (archiveOpen(g_find_list_path[z].c_str()))
continue;
ArcEntry *list;
int count;
archiveGetList(&list, &count);
// Try to map the ROMs FBA wants to ROMs we find inside our pretty archives ...
for (unsigned i = 0; i < g_rom_count; i++)
{
if (g_find_list[i].nState == STAT_OK)
continue;
BurnRomInfo ri = {0};
BurnDrvGetRomInfo(&ri, i);
int index = find_rom_by_crc(ri.nCrc, list, count);
if (index < 0)
{
archiveClose();
return false;
}
// Yay, we found it!
g_find_list[i].nArchive = z;
g_find_list[i].nPos = index;
g_find_list[i].nState = STAT_OK;
// Sanity checking ...
//if (!(ri.nType & BRF_OPT) && ri.nCrc)
// nTotalSize += ri.nLen;
if (list[index].nLen == ri.nLen)
{
if (ri.nCrc && list[index].nCrc != ri.nCrc)
g_find_list[i].nState = STAT_CRC;
}
else if (list[index].nLen < ri.nLen)
g_find_list[i].nState = STAT_SMALL;
else if (list[index].nLen > ri.nLen)
g_find_list[i].nState = STAT_LARGE;
}
free_archive_list(list, count);
archiveClose();
}
BurnExtLoadRom = archive_load_rom;
return true;
}
void snes_init()
{
BurnLibInit();
if (environ_cb)
{
bool need_fullpath = true;
environ_cb(SNES_ENVIRONMENT_SET_NEED_FULLPATH, &need_fullpath);
}
}
void snes_term()
{
BurnDrvExit();
BurnLibExit();
}
static bool g_reset;
void snes_power() { g_reset = true; }
void snes_reset() { g_reset = true; }
// Copy stuff :o
static inline void blit_regular(unsigned width, unsigned height, unsigned pitch)
{
for (unsigned y = 0; y < height; y++)
{
memcpy(g_fba_frame_conv + y * 1024,
g_fba_frame + y * (pitch >> 1),
width * sizeof(uint16_t));
}
video_cb(g_fba_frame_conv, width, height);
}
static inline void blit_flipped(unsigned width, unsigned height, unsigned pitch)
{
for (unsigned y = 0; y < height; y++)
{
memcpy(g_fba_frame_conv + (height - 1 - y) * 1024,
g_fba_frame + y * (pitch >> 1),
width * sizeof(uint16_t));
}
video_cb(g_fba_frame_conv, width, height);
}
static inline void blit_vertical(unsigned width, unsigned height, unsigned pitch)
{
unsigned in_width = height;
unsigned in_height = width;
pitch >>= 1;
// Flip y and x coords pretty much ...
for (unsigned y = 0; y < in_height; y++)
for (unsigned x = 0; x < in_width; x++)
g_fba_frame_conv[(height - x - 1) * 1024 + y] = g_fba_frame[y * pitch + x];
video_cb(g_fba_frame_conv, width, height);
}
static inline void blit_vertical_flipped(unsigned width, unsigned height, unsigned pitch)
{
unsigned in_width = height;
unsigned in_height = width;
pitch >>= 1;
// Flip y and x coords pretty much ...
for (unsigned y = 0; y < in_height; y++)
for (unsigned x = 0; x < in_width; x++)
g_fba_frame_conv[x * 1024 + (width - 1 - y)] = g_fba_frame[y * pitch + x];
video_cb(g_fba_frame_conv, width, height);
}
void snes_run()
{
int width, height;
BurnDrvGetVisibleSize(&width, &height);
pBurnDraw = (uint8_t*)g_fba_frame;
unsigned drv_flags = BurnDrvGetFlags();
if (drv_flags & BDF_ORIENTATION_VERTICAL)
nBurnPitch = height * sizeof(uint16_t);
else
nBurnPitch = width * sizeof(uint16_t);
nBurnLayer = 0xff;
pBurnSoundOut = g_audio_buf;
nBurnSoundRate = 32000;
nBurnSoundLen = AUDIO_SEGMENT_LENGTH;
nCurrentFrame++;
poll_input();
BurnDrvFrame();
if ((drv_flags & (BDF_ORIENTATION_VERTICAL | BDF_ORIENTATION_FLIPPED)) == (BDF_ORIENTATION_VERTICAL | BDF_ORIENTATION_FLIPPED))
blit_vertical_flipped(width, height, nBurnPitch);
else if (drv_flags & BDF_ORIENTATION_VERTICAL)
blit_vertical(width, height, nBurnPitch);
else if (drv_flags & BDF_ORIENTATION_FLIPPED)
blit_flipped(width, height, nBurnPitch);
else
blit_regular(width, height, nBurnPitch);
for (unsigned i = 0; i < AUDIO_SEGMENT_LENGTH_TIMES_CHANNELS; i += 2)
audio_cb(g_audio_buf[i + 0], g_audio_buf[i + 1]);
}
static uint8_t *write_state_ptr;
static const uint8_t *read_state_ptr;
static unsigned state_size;
static int burn_write_state_cb(BurnArea *pba)
{
memcpy(write_state_ptr, pba->Data, pba->nLen);
write_state_ptr += pba->nLen;
return 0;
}
static int burn_read_state_cb(BurnArea *pba)
{
memcpy(pba->Data, read_state_ptr, pba->nLen);
read_state_ptr += pba->nLen;
return 0;
}
static int burn_dummy_state_cb(BurnArea *pba)
{
state_size += pba->nLen;
}
unsigned snes_serialize_size()
{
if (state_size)
return state_size;
BurnAcb = burn_dummy_state_cb;
state_size = 0;
BurnAreaScan(ACB_VOLATILE | ACB_WRITE, 0);
return state_size;
}
bool snes_serialize(uint8_t *data, unsigned size)
{
if (size != state_size)
return false;
BurnAcb = burn_write_state_cb;
write_state_ptr = data;
BurnAreaScan(ACB_VOLATILE | ACB_WRITE, 0);
return true;
}
bool snes_unserialize(const uint8_t *data, unsigned size)
{
if (size != state_size)
return false;
BurnAcb = burn_read_state_cb;
read_state_ptr = data;
BurnAreaScan(ACB_VOLATILE | ACB_READ, 0);
return true;
}
void snes_cheat_reset() {}
void snes_cheat_set(unsigned, bool, const char*) {}
static bool fba_init(unsigned driver)
{
nBurnDrvActive = driver;
if (!open_archive())
return false;
nFMInterpolation = 3;
nInterpolation = 3;
BurnDrvInit();
if (environ_cb)
{
int width, height;
BurnDrvGetVisibleSize(&width, &height);
snes_geometry geom = { width, height, width, height };
environ_cb(SNES_ENVIRONMENT_SET_GEOMETRY, &geom);
unsigned pitch = 2048;
environ_cb(SNES_ENVIRONMENT_SET_PITCH, &pitch);
}
return true;
}
static unsigned int HighCol15(int r, int g, int b, int /* i */)
{
unsigned int t = 0;
t |= (r << 7) & 0x7c00;
t |= (g << 2) & 0x03e0;
t |= (b >> 3) & 0x001f;
return t;
}
int VidRecalcPal()
{
return BurnRecalcPal();
}
static void init_video()
{
nBurnBpp = 2;
VidRecalcPal();
BurnHighCol = HighCol15;
}
static void init_audio()
{
pBurnSoundOut = g_audio_buf;
nBurnSoundRate = 32000;
nBurnSoundLen = AUDIO_SEGMENT_LENGTH;
}
// Infer paths from basename.
bool snes_load_cartridge_normal(const char*, const uint8_t *, unsigned)
{
unsigned i = BurnDrvGetIndexByName(g_basename);
if (i < nBurnDrvCount)
{
init_video();
init_audio();
if (!fba_init(i))
return false;
init_input();
return true;
}
else
return false;
}
void snes_set_cartridge_basename(const char *basename)
{
snprintf(g_rom_name, sizeof(g_rom_name), "%s.zip", basename);
strcpy(g_rom_dir, g_rom_name);
char *split = strrchr(g_rom_dir, '/');
if (!split)
split = strrchr(g_rom_dir, '\\');
if (split)
*split = '\0';
if (split)
{
strcpy(g_basename, split + 1);
split = strrchr(g_basename, '.');
if (split)
*split = '\0';
}
//fprintf(stderr, "PATH: %s\n", g_rom_name);
//fprintf(stderr, "DIR: %s\n", g_rom_dir);
//fprintf(stderr, "BASENAME: %s\n", g_basename);
}
bool snes_load_cartridge_bsx_slotted(
const char*, const uint8_t*, unsigned,
const char*, const uint8_t*, unsigned
)
{ return false; }
bool snes_load_cartridge_bsx(
const char*, const uint8_t *, unsigned,
const char*, const uint8_t *, unsigned
)
{ return false; }
bool snes_load_cartridge_sufami_turbo(
const char*, const uint8_t*, unsigned,
const char*, const uint8_t*, unsigned,
const char*, const uint8_t*, unsigned
)
{ return false; }
bool snes_load_cartridge_super_game_boy(
const char*, const uint8_t*, unsigned,
const char*, const uint8_t*, unsigned
)
{ return false; }
void snes_unload_cartridge(void) {}
bool snes_get_region() { return SNES_REGION_NTSC; }
uint8_t *snes_get_memory_data(unsigned) { return 0; }
unsigned snes_get_memory_size(unsigned) { return 0; }
unsigned snes_library_revision_major() { return 1; }
unsigned snes_library_revision_minor() { return 3; }
const char *snes_library_id() { return "FBANext/libsnes"; }
void snes_set_controller_port_device(bool, unsigned) {}
// Input stuff.
// Ref GamcPlayer() in ../gamc.cpp
#define P1_COIN FBK_5
#define P1_START FBK_1
#define P1_LEFT FBK_LEFTARROW
#define P1_RIGHT FBK_RIGHTARROW
#define P1_UP FBK_UPARROW
#define P1_DOWN FBK_DOWNARROW
#define P1_FIRE1 FBK_A
#define P1_FIRE2 FBK_S
#define P1_FIRE3 FBK_D
#define P1_FIRE4 FBK_Z
#define P1_FIRE5 FBK_X
#define P1_FIRE6 FBK_C
#define P1_FIRED FBK_V
#define P1_SERVICE FBK_F2
#define P2_COIN 0x07
#define P2_START 0x03
#define P2_LEFT 0x4000
#define P2_RIGHT 0x4001
#define P2_UP 0x4002
#define P2_DOWN 0x4003
#define P2_FIRE1 0x4080
#define P2_FIRE2 0x4081
#define P2_FIRE3 0x4082
#define P2_FIRE4 0x4083
#define P2_FIRE5 0x4084
#define P2_FIRE6 0x4085
#define P2_FIRED 0x4086
#define P3_COIN 0x08
#define P3_START 0x04
#define P3_LEFT 0x4100
#define P3_RIGHT 0x4101
#define P3_UP 0x4102
#define P3_DOWN 0x4103
#define P3_FIRE1 0x4180
#define P3_FIRE2 0x4181
#define P3_FIRE3 0x4182
#define P3_FIRE4 0x4183
#define P3_FIRE5 0x4184
#define P3_FIRE6 0x4185
#define P4_COIN 0x09
#define P4_START 0x05
#define P4_LEFT 0x4200
#define P4_RIGHT 0x4201
#define P4_UP 0x4202
#define P4_DOWN 0x4203
#define P4_FIRE1 0x4280
#define P4_FIRE2 0x4281
#define P4_FIRE3 0x4282
#define P4_FIRE4 0x4283
#define P4_FIRE5 0x4284
#define P4_FIRE6 0x4285
static unsigned char keybinds[0x5000][2];
#define _B(x) SNES_DEVICE_ID_JOYPAD_##x
#define RESET_BIND 12
#define SERVICE_BIND 13
static bool init_input()
{
GameInpInit();
GameInpDefault();
bool has_analog = false;
struct GameInp* pgi = GameInp;
for (unsigned i = 0; i < nGameInpCount; i++, pgi++)
{
if (pgi->nType == BIT_ANALOG_REL)
{
has_analog = true;
break;
}
}
//needed for Neo Geo button mappings (and other drivers in future)
const char * boardrom = BurnDrvGetTextA(DRV_BOARDROM);
// Bind to nothing.
for (unsigned i = 0; i < 0x5000; i++)
keybinds[i][0] = 0xff;
// Reset
keybinds[FBK_F3 ][0] = RESET_BIND;
keybinds[FBK_F3 ][1] = 0;
keybinds[P1_SERVICE ][0] = SERVICE_BIND;
keybinds[P1_SERVICE ][1] = 0;
keybinds[P1_COIN ][0] = _B(SELECT);
keybinds[P1_COIN ][1] = 0;
keybinds[P1_START ][0] = _B(START);
keybinds[P1_START ][1] = 0;
keybinds[P1_UP ][0] = _B(UP);
keybinds[P1_UP ][1] = 0;
keybinds[P1_DOWN ][0] = _B(DOWN);
keybinds[P1_DOWN ][1] = 0;
keybinds[P1_LEFT ][0] = _B(LEFT);
keybinds[P1_LEFT ][1] = 0;
keybinds[P1_RIGHT ][0] = _B(RIGHT);
keybinds[P1_RIGHT ][1] = 0;
keybinds[P1_FIRE1 ][0] = _B(Y);
keybinds[P1_FIRE1 ][1] = 0;
keybinds[P1_FIRE2 ][0] = _B(X);
keybinds[P1_FIRE2 ][1] = 0;
keybinds[P1_FIRE3 ][0] = _B(L);
keybinds[P1_FIRE3 ][1] = 0;
keybinds[P1_FIRE4 ][0] = _B(B);
keybinds[P1_FIRE4 ][1] = 0;
keybinds[P1_FIRE5 ][0] = _B(A);
keybinds[P1_FIRE5 ][1] = 0;
if(boardrom && (strcmp(boardrom,"neogeo") == 0))
{
keybinds[P1_FIRE6][0] = _B(Y);
keybinds[P1_FIRE6][1] = 0;
keybinds[P1_FIRED][0] = _B(X);
keybinds[P1_FIRED][1] = 0;
}
else
{
keybinds[P1_FIRE6 ][0] = _B(R);
keybinds[P1_FIRE6 ][1] = 0;
}
#if 0
keybinds[0x88 ][0] = L2;
keybinds[0x88 ][1] = 0;
keybinds[0x8A ][0] = R2;
keybinds[0x8A ][1] = 0;
keybinds[0x3b ][0] = L3;
keybinds[0x3b ][1] = 0;
keybinds[0x21 ][0] = R2;
keybinds[0x21 ][1] = 0;
#endif
keybinds[P2_COIN ][0] = _B(SELECT);
keybinds[P2_COIN ][1] = 1;
keybinds[P2_START ][0] = _B(START);
keybinds[P2_START ][1] = 1;
keybinds[P2_UP ][0] = _B(UP);
keybinds[P2_UP ][1] = 1;
keybinds[P2_DOWN ][0] = _B(DOWN);
keybinds[P2_DOWN ][1] = 1;
keybinds[P2_LEFT ][0] = _B(LEFT);
keybinds[P2_LEFT ][1] = 1;
keybinds[P2_RIGHT ][0] = _B(RIGHT);
keybinds[P2_RIGHT ][1] = 1;
keybinds[P2_FIRE1 ][0] = _B(Y);
if (boardrom && (strcmp(boardrom, "neogeo") == 0))
{
keybinds[P2_FIRE3][0] = _B(Y);
keybinds[P2_FIRE3][1] = 1;
keybinds[P2_FIRE4][0] = _B(X);
keybinds[P2_FIRE4][1] = 1;
keybinds[P2_FIRE1][0] = _B(B);
keybinds[P2_FIRE1][1] = 1;
keybinds[P2_FIRE2][0] = _B(A);
keybinds[P2_FIRE2][1] = 1;
}
else
{
keybinds[P2_FIRE1 ][1] = 1;
keybinds[P2_FIRE2 ][0] = _B(X);
keybinds[P2_FIRE2 ][1] = 1;
keybinds[P2_FIRE3 ][0] = _B(L);
keybinds[P2_FIRE3 ][1] = 1;
keybinds[P2_FIRE4 ][0] = _B(B);
keybinds[P2_FIRE4 ][1] = 1;
keybinds[P2_FIRE5 ][0] = _B(A);
keybinds[P2_FIRE5 ][1] = 1;
keybinds[P2_FIRE6 ][0] = _B(R);
keybinds[P2_FIRE6 ][1] = 1;
}
#if 0
keybinds[0x4088 ][0] = L2;
keybinds[0x4088 ][1] = 1;
keybinds[0x408A ][0] = R2;
keybinds[0x408A ][1] = 1;
keybinds[0x408b ][0] = L3;
keybinds[0x408b ][1] = 1;
keybinds[0x408c ][0] = R3;
keybinds[0x408c ][1] = 1;
#endif
keybinds[P3_COIN ][0] = _B(SELECT);
keybinds[P3_COIN ][1] = 2;
keybinds[P3_START ][0] = _B(START);
keybinds[P3_START ][1] = 2;
keybinds[P3_UP ][0] = _B(UP);
keybinds[P3_UP ][1] = 2;
keybinds[P3_DOWN ][0] = _B(DOWN);
keybinds[P3_DOWN ][1] = 2;
keybinds[P3_LEFT ][0] = _B(LEFT);
keybinds[P3_LEFT ][1] = 2;
keybinds[P3_RIGHT ][0] = _B(RIGHT);
keybinds[P3_RIGHT ][1] = 2;
keybinds[P3_FIRE1 ][0] = _B(Y);
keybinds[P3_FIRE1 ][1] = 2;
keybinds[P3_FIRE2 ][0] = _B(X);
keybinds[P3_FIRE2 ][1] = 2;
keybinds[P3_FIRE3 ][0] = _B(L);
keybinds[P3_FIRE3 ][1] = 2;
keybinds[P3_FIRE4 ][0] = _B(B);
keybinds[P3_FIRE4 ][1] = 2;
keybinds[P3_FIRE5 ][0] = _B(A);
keybinds[P3_FIRE5 ][1] = 2;
keybinds[P3_FIRE6 ][0] = _B(R);
keybinds[P3_FIRE6 ][1] = 2;
#if 0
keybinds[0x4188 ][0] = L2;
keybinds[0x4188 ][1] = 2;
keybinds[0x418A ][0] = R2;
keybinds[0x418A ][1] = 2;
keybinds[0x418b ][0] = L3;
keybinds[0x418b ][1] = 2;
keybinds[0x418c ][0] = R3;
keybinds[0x418c ][1] = 2;
#endif
keybinds[P4_COIN ][0] = _B(SELECT);
keybinds[P4_COIN ][1] = 3;
keybinds[P4_START ][0] = _B(START);
keybinds[P4_START ][1] = 3;
keybinds[P4_UP ][0] = _B(UP);
keybinds[P4_UP ][1] = 3;
keybinds[P4_DOWN ][0] = _B(DOWN);
keybinds[P4_DOWN ][1] = 3;
keybinds[P4_LEFT ][0] = _B(LEFT);
keybinds[P4_LEFT ][1] = 3;
keybinds[P4_RIGHT ][0] = _B(RIGHT);
keybinds[P4_RIGHT ][1] = 3;
keybinds[P4_FIRE1 ][0] = _B(Y);
keybinds[P4_FIRE1 ][1] = 3;
keybinds[P4_FIRE2 ][0] = _B(X);
keybinds[P4_FIRE2 ][1] = 3;
keybinds[P4_FIRE3 ][0] = _B(L);
keybinds[P4_FIRE3 ][1] = 3;
keybinds[P4_FIRE4 ][0] = _B(B);
keybinds[P4_FIRE4 ][1] = 3;
keybinds[P4_FIRE5 ][0] = _B(A);
keybinds[P4_FIRE5 ][1] = 3;
keybinds[P4_FIRE6 ][0] = _B(R);
keybinds[P4_FIRE6 ][1] = 3;
#if 0
keybinds[0x4288 ][0] = L2;
keybinds[0x4288 ][1] = 3;
keybinds[0x428A ][0] = R2;
keybinds[0x428A ][1] = 3;
keybinds[0x428b ][0] = L3;
keybinds[0x428b ][1] = 3;
keybinds[0x428c ][0] = R3;
keybinds[0x428c ][1] = 3;
#endif
return has_analog;
}
static void poll_input()
{
poll_cb();
struct GameInp* pgi = GameInp;
unsigned controller_binds_count = nGameInpCount;
for (int i = 0; i < controller_binds_count; i++, pgi++)
{
int nAdd = 0;
if ((pgi->nInput & GIT_GROUP_SLIDER) == 0) // not a slider
continue;
if (pgi->nInput == GIT_KEYSLIDER)
{
// Get states of the two keys
if (input_cb(0, SNES_DEVICE_JOYPAD, 0,
keybinds[pgi->Input.Slider.SliderAxis.nSlider[0]][0]))
nAdd -= 0x100;
if (input_cb(0, SNES_DEVICE_JOYPAD, 0,
keybinds[pgi->Input.Slider.SliderAxis.nSlider[1]][0]))
nAdd += 0x100;
}
// nAdd is now -0x100 to +0x100
// Change to slider speed
nAdd *= pgi->Input.Slider.nSliderSpeed;
nAdd /= 0x100;
if (pgi->Input.Slider.nSliderCenter)
{ // Attact to center
int v = pgi->Input.Slider.nSliderValue - 0x8000;
v *= (pgi->Input.Slider.nSliderCenter - 1);
v /= pgi->Input.Slider.nSliderCenter;
v += 0x8000;
pgi->Input.Slider.nSliderValue = v;
}
pgi->Input.Slider.nSliderValue += nAdd;
// Limit slider
if (pgi->Input.Slider.nSliderValue < 0x0100)
pgi->Input.Slider.nSliderValue = 0x0100;
if (pgi->Input.Slider.nSliderValue > 0xFF00)
pgi->Input.Slider.nSliderValue = 0xFF00;
}
pgi = GameInp;
for (unsigned i = 0; i < controller_binds_count; i++, pgi++)
{
switch (pgi->nInput)
{
case GIT_CONSTANT: // Constant value
pgi->Input.nVal = pgi->Input.Constant.nConst;
*(pgi->Input.pVal) = pgi->Input.nVal;
break;
case GIT_SWITCH:
{
// Digital input
unsigned id = keybinds[pgi->Input.Switch.nCode][0];
unsigned port = keybinds[pgi->Input.Switch.nCode][1];
bool state;
if (id == RESET_BIND)
{
state = g_reset;
g_reset = false;
}
else if (id == SERVICE_BIND)
{
state =
input_cb(0, SNES_DEVICE_JOYPAD, 0, _B(START)) &&
input_cb(0, SNES_DEVICE_JOYPAD, 0, _B(SELECT)) &&
input_cb(0, SNES_DEVICE_JOYPAD, 0, _B(L)) &&
input_cb(0, SNES_DEVICE_JOYPAD, 0, _B(R));
}
else if (port < 2)
state = input_cb(port, SNES_DEVICE_JOYPAD, 0, id);
else
state = input_cb(true, SNES_DEVICE_MULTITAP, port - 1, id);
if (pgi->nType & BIT_GROUP_ANALOG)
{
// Set analog controls to full
if (state)
pgi->Input.nVal = 0xFFFF;
else
pgi->Input.nVal = 0x0001;
#ifdef LSB_FIRST
*(pgi->Input.pShortVal) = pgi->Input.nVal;
#else
*((int *)pgi->Input.pShortVal) = pgi->Input.nVal;
#endif
}
else
{
// Binary controls
if (state)
pgi->Input.nVal = 1;
else
pgi->Input.nVal = 0;
*(pgi->Input.pVal) = pgi->Input.nVal;
}
break;
}
case GIT_KEYSLIDER: // Keyboard slider
{
int nSlider = pgi->Input.Slider.nSliderValue;
if (pgi->nType == BIT_ANALOG_REL) {
nSlider -= 0x8000;
nSlider >>= 4;
}
pgi->Input.nVal = (unsigned short)nSlider;
#ifdef LSB_FIRST
*(pgi->Input.pShortVal) = pgi->Input.nVal;
#else
*((int *)pgi->Input.pShortVal) = pgi->Input.nVal;
#endif
break;
}
}
}
}

View File

@ -0,0 +1,186 @@
#ifndef LIBSNES_HPP
#define LIBSNES_HPP
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
#define SNES_PORT_1 0
#define SNES_PORT_2 1
#define SNES_DEVICE_NONE 0
#define SNES_DEVICE_JOYPAD 1
#define SNES_DEVICE_MULTITAP 2
#define SNES_DEVICE_MOUSE 3
#define SNES_DEVICE_SUPER_SCOPE 4
#define SNES_DEVICE_JUSTIFIER 5
#define SNES_DEVICE_JUSTIFIERS 6
#define SNES_DEVICE_SERIAL_CABLE 7
#define SNES_DEVICE_ID_JOYPAD_B 0
#define SNES_DEVICE_ID_JOYPAD_Y 1
#define SNES_DEVICE_ID_JOYPAD_SELECT 2
#define SNES_DEVICE_ID_JOYPAD_START 3
#define SNES_DEVICE_ID_JOYPAD_UP 4
#define SNES_DEVICE_ID_JOYPAD_DOWN 5
#define SNES_DEVICE_ID_JOYPAD_LEFT 6
#define SNES_DEVICE_ID_JOYPAD_RIGHT 7
#define SNES_DEVICE_ID_JOYPAD_A 8
#define SNES_DEVICE_ID_JOYPAD_X 9
#define SNES_DEVICE_ID_JOYPAD_L 10
#define SNES_DEVICE_ID_JOYPAD_R 11
#define SNES_DEVICE_ID_MOUSE_X 0
#define SNES_DEVICE_ID_MOUSE_Y 1
#define SNES_DEVICE_ID_MOUSE_LEFT 2
#define SNES_DEVICE_ID_MOUSE_RIGHT 3
#define SNES_DEVICE_ID_SUPER_SCOPE_X 0
#define SNES_DEVICE_ID_SUPER_SCOPE_Y 1
#define SNES_DEVICE_ID_SUPER_SCOPE_TRIGGER 2
#define SNES_DEVICE_ID_SUPER_SCOPE_CURSOR 3
#define SNES_DEVICE_ID_SUPER_SCOPE_TURBO 4
#define SNES_DEVICE_ID_SUPER_SCOPE_PAUSE 5
#define SNES_DEVICE_ID_JUSTIFIER_X 0
#define SNES_DEVICE_ID_JUSTIFIER_Y 1
#define SNES_DEVICE_ID_JUSTIFIER_TRIGGER 2
#define SNES_DEVICE_ID_JUSTIFIER_START 3
#define SNES_REGION_NTSC 0
#define SNES_REGION_PAL 1
#define SNES_MEMORY_CARTRIDGE_RAM 0
#define SNES_MEMORY_CARTRIDGE_RTC 1
#define SNES_MEMORY_BSX_RAM 2
#define SNES_MEMORY_BSX_PRAM 3
#define SNES_MEMORY_SUFAMI_TURBO_A_RAM 4
#define SNES_MEMORY_SUFAMI_TURBO_B_RAM 5
#define SNES_MEMORY_GAME_BOY_RAM 6
#define SNES_MEMORY_GAME_BOY_RTC 7
#define SNES_MEMORY_WRAM 100
#define SNES_MEMORY_APURAM 101
#define SNES_MEMORY_VRAM 102
#define SNES_MEMORY_OAM 103
#define SNES_MEMORY_CGRAM 104
// SSNES extension. Not required to be implemented for a working implementation.
#define SNES_ENVIRONMENT_GET_FULLPATH 0 // const char ** --
// Full path of game loaded.
//
#define SNES_ENVIRONMENT_SET_GEOMETRY 1 // const struct snes_geometry * --
// Window geometry information for the system/game.
//
#define SNES_ENVIRONMENT_SET_PITCH 2 // const unsigned * --
// Pitch of game image.
//
#define SNES_ENVIRONMENT_GET_OVERSCAN 3 // bool * --
// Boolean value whether or not the implementation should use overscan.
//
#define SNES_ENVIRONMENT_SET_TIMING 4 // const struct snes_system_timing * --
// Set exact timings of the system. Used primarily for video recording.
//
#define SNES_ENVIRONMENT_GET_CAN_DUPE 5 // bool * --
// Boolean value whether or not SSNES supports frame duping,
// passing NULL to video frame callback.
//
//
#define SNES_ENVIRONMENT_SET_NEED_FULLPATH 6 // const bool * --
// Boolean value telling if implementation needs a valid fullpath to be able to run.
// If this is the case, SSNES will not open the rom directly,
// and pass NULL to rom data.
// Implementation must then use SNES_ENVIRONMENT_GET_FULLPATH.
// This is useful for implementations with very large roms,
// which are impractical to load fully into RAM.
struct snes_geometry
{
unsigned base_width; // Nominal video width of system.
unsigned base_height; // Nominal video height of system.
unsigned max_width; // Maximum possible width of system.
unsigned max_height; // Maximum possible height of system.
};
struct snes_system_timing
{
double fps;
double sample_rate;
};
typedef bool (*snes_environment_t)(unsigned cmd, void *data);
// Must be called before calling snes_init().
void snes_set_environment(snes_environment_t);
////
typedef void (*snes_video_refresh_t)(const uint16_t *data, unsigned width, unsigned height);
typedef void (*snes_audio_sample_t)(uint16_t left, uint16_t right);
typedef void (*snes_input_poll_t)(void);
typedef int16_t (*snes_input_state_t)(bool port, unsigned device, unsigned index, unsigned id);
const char* snes_library_id(void);
unsigned snes_library_revision_major(void);
unsigned snes_library_revision_minor(void);
void snes_set_video_refresh(snes_video_refresh_t);
void snes_set_audio_sample(snes_audio_sample_t);
void snes_set_input_poll(snes_input_poll_t);
void snes_set_input_state(snes_input_state_t);
void snes_set_controller_port_device(bool port, unsigned device);
void snes_set_cartridge_basename(const char *basename);
void snes_init(void);
void snes_term(void);
void snes_power(void);
void snes_reset(void);
void snes_run(void);
unsigned snes_serialize_size(void);
bool snes_serialize(uint8_t *data, unsigned size);
bool snes_unserialize(const uint8_t *data, unsigned size);
void snes_cheat_reset(void);
void snes_cheat_set(unsigned index, bool enabled, const char *code);
bool snes_load_cartridge_normal(
const char *rom_xml, const uint8_t *rom_data, unsigned rom_size
);
bool snes_load_cartridge_bsx_slotted(
const char *rom_xml, const uint8_t *rom_data, unsigned rom_size,
const char *bsx_xml, const uint8_t *bsx_data, unsigned bsx_size
);
bool snes_load_cartridge_bsx(
const char *rom_xml, const uint8_t *rom_data, unsigned rom_size,
const char *bsx_xml, const uint8_t *bsx_data, unsigned bsx_size
);
bool snes_load_cartridge_sufami_turbo(
const char *rom_xml, const uint8_t *rom_data, unsigned rom_size,
const char *sta_xml, const uint8_t *sta_data, unsigned sta_size,
const char *stb_xml, const uint8_t *stb_data, unsigned stb_size
);
bool snes_load_cartridge_super_game_boy(
const char *rom_xml, const uint8_t *rom_data, unsigned rom_size,
const char *dmg_xml, const uint8_t *dmg_data, unsigned dmg_size
);
void snes_unload_cartridge(void);
bool snes_get_region(void);
uint8_t* snes_get_memory_data(unsigned id);
unsigned snes_get_memory_size(unsigned id);
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,5 @@
{
global: snes_*;
local: *;
};

0
src/burner/libsnes/net.h Normal file
View File

View File

@ -0,0 +1,56 @@
#ifndef __PORT_TYPEDEFS_H
#define __PORT_TYPEDEFS_H
#include <stdint.h>
#include <wchar.h>
#include "inp_keys.h"
#define TCHAR char
#undef __cdecl
#define __cdecl
#define bprintf(...) {}
#define _strnicmp(s1, s2, n) strncasecmp(s1, s2, n)
#define _stricmp(x, y) strcasecmp(x,y)
#define _T(x) x
#define _tcstol strtol
#define _tfopen fopen
#define _fgetts fgets
#define _tcslen strlen
#define _stprintf sprintf
#define _istspace(x) isspace(x)
#define _tcsncmp strncmp
#define _tcsncpy strncpy
#define _tcsstr strstr
#define _stscanf sscanf
#define _ftprintf fprintf
#define _tcsicmp(a, b) strcasecmp(a, b)
#define _tcscpy(to, from) strcpy(to, from)
/*define lstrlen what does lstrlen correspond to?*/
#undef __fastcall
#undef _fastcall
#define __fastcall /*what does this correspond to?*/
#define _fastcall /*same as above - what does this correspond to?*/
#define ANSIToTCHAR(str, foo, bar) (str)
/* for Windows / Xbox 360 (below VS2010) - typedefs for missing stdint.h types such as uintptr_t?*/
/*FBA defines*/
#define PUF_TEXT_NO_TRANSLATE (0)
#define PUF_TYPE_ERROR (1)
extern TCHAR szAppBurnVer[16];
typedef int HWND;
extern int bDrvOkay;
extern int bRunPause;
extern bool bAlwaysProcessKeyboardInput;
extern HWND hScrnWnd; // Handle to the screen window
extern void InpDIPSWResetDIPs (void);
#endif