Update to bsnes v064r03 release.

Some changes to libsnes. Really hoping the API will be stable from
this point out ...
This commit is contained in:
byuu 2010-04-19 17:37:14 +00:00
parent 645689e683
commit 42a4c1d60e
7 changed files with 26 additions and 545 deletions

View File

@ -33,10 +33,14 @@ struct Interface : public SNES::Interface {
static Interface interface;
unsigned snes_library_revision(void) {
unsigned snes_library_revision_major(void) {
return 1;
}
unsigned snes_library_revision_minor(void) {
return 0;
}
void snes_set_video_refresh(snes_video_refresh_t video_refresh) {
interface.pvideo_refresh = video_refresh;
}
@ -79,10 +83,6 @@ void snes_run(void) {
SNES::system.run();
}
void snes_unload(void) {
SNES::cartridge.unload();
}
unsigned snes_serialize_size(void) {
return SNES::system.serialize_size();
}
@ -116,7 +116,7 @@ void snes_load_cartridge_normal(
) {
snes_cheat_reset();
SNES::memory::cartrom.copy(rom_data, rom_size);
string xmlrom = rom_xml ? string(rom_xml) : snes_information(rom_data, rom_size).xml_memory_map;
string xmlrom = (rom_xml && *rom_xml) ? string(rom_xml) : snes_information(rom_data, rom_size).xml_memory_map;
SNES::cartridge.load(SNES::Cartridge::Mode::Normal, { xmlrom });
SNES::system.power();
}
@ -176,6 +176,10 @@ void snes_load_cartridge_super_game_boy(
SNES::system.power();
}
void snes_unload_cartridge(void) {
SNES::cartridge.unload();
}
bool snes_get_region(void) {
return SNES::system.region() == SNES::System::Region::NTSC ? 0 : 1;
}
@ -207,33 +211,3 @@ unsigned snes_get_memory_size(unsigned id) {
}
return 0;
}
static uint32_t colortable[32768];
void snes_blit_set_colortable(const uint32_t *new_colortable) {
memcpy(colortable, new_colortable, 32768 * sizeof(uint32_t));
}
void snes_blit(
uint32_t *output, unsigned output_pitch, unsigned output_width, unsigned output_height,
const uint16_t *input, unsigned input_pitch, unsigned input_width, unsigned input_height
) {
output_pitch >>= 2;
input_pitch >>= 1;
double step_x = (double)input_width / (double)output_width;
double step_y = (double)input_height / (double)output_height;
double pos_y = 0;
for(unsigned y = 0; y < output_height; y++) {
uint32_t *o = output + y * output_pitch;
const uint16_t *i = input + (unsigned)(pos_y + 0.5) * input_pitch;
double pos_x = 0;
for(unsigned x = 0; x < output_width; x++) {
unsigned pixel = i[(unsigned)(pos_x + 0.5)];
*o++ = colortable[pixel];
pos_x += step_x;
}
pos_y += step_y;
}
}

View File

@ -7,14 +7,8 @@
extern "C" {
#endif
#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_PORT_1 0
#define SNES_PORT_2 1
#define SNES_DEVICE_NONE 0
#define SNES_DEVICE_JOYPAD 1
@ -54,12 +48,22 @@ extern "C" {
#define SNES_DEVICE_ID_JUSTIFIER_TRIGGER 2
#define SNES_DEVICE_ID_JUSTIFIER_START 3
#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
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);
unsigned snes_library_revision(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);
@ -73,7 +77,6 @@ void snes_term(void);
void snes_power(void);
void snes_reset(void);
void snes_run(void);
void snes_unload(void);
unsigned snes_serialize_size(void);
bool snes_serialize(uint8_t *data, unsigned size);
@ -107,16 +110,12 @@ void snes_load_cartridge_super_game_boy(
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);
void snes_blit_set_colortable(const uint32_t *colortable);
void snes_blit(
uint32_t *output, unsigned output_pitch, unsigned output_width, unsigned output_height,
const uint16_t *input, unsigned input_pitch, unsigned input_width, unsigned input_height
);
#ifdef __cplusplus
}
#endif

View File

@ -1,4 +1,4 @@
static const char bsnesVersion[] = "064.02";
static const char bsnesVersion[] = "064.03";
static const char bsnesTitle[] = "bsnes";
static const unsigned bsnesSerializerVersion = 10;

View File

@ -1,200 +0,0 @@
#!/usr/bin/python
import sys, time, array, ctypes, os, ao
import pygtk
pygtk.require("2.0")
import gtk, gobject
from libsnes import SNES
snes = SNES()
class MainWindow(gtk.Window):
def __init__(self):
gtk.Window.__init__(self, gtk.WINDOW_TOPLEVEL)
self.keystate_up = 0
self.keystate_down = 0
self.keystate_left = 0
self.keystate_right = 0
self.keystate_a = 0
self.keystate_b = 0
self.keystate_x = 0
self.keystate_y = 0
self.keystate_l = 0
self.keystate_r = 0
self.keystate_select = 0
self.keystate_start = 0
self.set_title("bsnes/PyGTK")
self.set_position(gtk.WIN_POS_CENTER)
self.set_resizable(False)
self.connect("key-press-event", self.key_press)
self.connect("key-release-event", self.key_release)
self.connect("destroy", self.destroy)
self.box = gtk.VBox()
self.add(self.box)
self.menu = gtk.MenuBar()
self.system_menu = gtk.Menu()
self.system_menuitem = gtk.MenuItem("System")
self.system_menuitem.set_submenu(self.system_menu)
self.system_load = gtk.MenuItem("Load Cartridge")
self.system_load.connect("activate", self.load_cartridge)
self.system_menu.append(self.system_load)
self.system_quit = gtk.MenuItem("Quit")
self.system_quit.connect("activate", gtk.main_quit)
self.system_menu.append(self.system_quit)
self.settings_menu = gtk.Menu()
self.settings_menuitem = gtk.MenuItem("Settings")
self.settings_menuitem.set_submenu(self.settings_menu)
self.tools_menu = gtk.Menu()
self.tools_menuitem = gtk.MenuItem("Tools")
self.tools_menuitem.set_submenu(self.tools_menu)
self.help_menu = gtk.Menu()
self.help_menuitem = gtk.MenuItem("Help")
self.help_menuitem.set_submenu(self.help_menu)
self.menu.append(self.system_menuitem)
self.menu.append(self.settings_menuitem)
self.menu.append(self.tools_menuitem)
self.menu.append(self.help_menuitem)
self.box.pack_start(self.menu, False, False, 0)
self.canvas = gtk.DrawingArea()
self.canvas.modify_bg(gtk.STATE_NORMAL, gtk.gdk.Color(0, 0, 0))
self.canvas.set_size_request(512, 448)
self.box.pack_start(self.canvas)
self.videobuffer = array.array('B', [0] * 512 * 448 * 4)
self.audiobuffer = array.array('H', [0] * 256 * 2)
self.audiolength = 0
self.audio = ao.AudioDevice("alsa", bits = 16, rate = 32000, channels = 2)
self.show_all()
snes.init()
snes.set_video_refresh(self.video_refresh)
snes.set_audio_sample(self.audio_sample)
snes.set_input_poll(self.input_poll)
snes.set_input_state(self.input_state)
colortable = array.array('I', [0] * 32 * 32 * 32)
offset = 0
for r in xrange(32):
for g in xrange(32):
for b in xrange(32):
colortable[offset] = (r << 19) + (g << 11) + (b << 3)
offset += 1
snes.set_colortable(colortable)
if len(sys.argv) == 2:
snes.load_cartridge_normal(sys.argv[1])
def key_press(self, widget, event):
if event.keyval == 65362: self.keystate_up = 1
if event.keyval == 65364: self.keystate_down = 1
if event.keyval == 65361: self.keystate_left = 1
if event.keyval == 65363: self.keystate_right = 1
if event.keyval == 122: self.keystate_b = 1
if event.keyval == 120: self.keystate_a = 1
if event.keyval == 97: self.keystate_y = 1
if event.keyval == 115: self.keystate_x = 1
if event.keyval == 100: self.keystate_l = 1
if event.keyval == 99: self.keystate_r = 1
if event.keyval == 39: self.keystate_select = 1
if event.keyval == 65293: self.keystate_start = 1
def key_release(self, widget, event):
if event.keyval == 65362: self.keystate_up = 0
if event.keyval == 65364: self.keystate_down = 0
if event.keyval == 65361: self.keystate_left = 0
if event.keyval == 65363: self.keystate_right = 0
if event.keyval == 122: self.keystate_b = 0
if event.keyval == 120: self.keystate_a = 0
if event.keyval == 97: self.keystate_y = 0
if event.keyval == 115: self.keystate_x = 0
if event.keyval == 100: self.keystate_l = 0
if event.keyval == 99: self.keystate_r = 0
if event.keyval == 39: self.keystate_select = 0
if event.keyval == 65293: self.keystate_start = 0
def destroy(self, widget, data=None):
snes.term()
gtk.main_quit()
def load_cartridge(self, widget):
dialog = gtk.FileChooserDialog("Load Cartridge", None, gtk.FILE_CHOOSER_ACTION_OPEN,
(gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL, gtk.STOCK_OPEN, gtk.RESPONSE_OK))
dialog.set_default_response(gtk.RESPONSE_OK)
filter = gtk.FileFilter()
filter.set_name("SNES cartridges")
filter.add_pattern("*.sfc")
filter.add_pattern("*.smc")
filter.add_pattern("*.swc")
filter.add_pattern("*.fig")
dialog.add_filter(filter)
response = dialog.run()
if response == gtk.RESPONSE_OK:
snes.unload()
snes.load_cartridge_normal(dialog.get_filename())
dialog.destroy()
def run(self):
if snes.loaded == True:
snes.run()
def video_refresh(self, data, width, height):
# ignore overscan region to guarantee 1:1 pixel scaling
if height == 239: height = 224
if height == 478: height = 448
pitch = 2048
if height >= 448: pitch = 1024
drawable = self.canvas.window
gc = self.canvas.get_style().fg_gc[gtk.STATE_NORMAL]
snes.blit(self.videobuffer, 2048, 512, 448, data, pitch, width, height)
drawable.draw_rgb_32_image(gc, 0, 0, 512, 448, gtk.gdk.RGB_DITHER_NONE, self.videobuffer, -1)
def audio_sample(self, left, right):
self.audiobuffer[self.audiolength] = left; self.audiolength += 1
self.audiobuffer[self.audiolength] = right; self.audiolength += 1
if self.audiolength == 256 * 2:
self.audio.play(self.audiobuffer, 256 * 2 * 2)
self.audiolength = 0
def input_poll(self):
pass
def input_state(self, port, device, index, identifier):
if port == 1: return 0
if self.keystate_up == 1 and self.keystate_down == 1: self.keystate_down = 0
if self.keystate_left == 1 and self.keystate_right == 1: self.keystate_right = 0
if identifier == 0: return self.keystate_b
if identifier == 1: return self.keystate_y
if identifier == 2: return self.keystate_select
if identifier == 3: return self.keystate_start
if identifier == 4: return self.keystate_up
if identifier == 5: return self.keystate_down
if identifier == 6: return self.keystate_left
if identifier == 7: return self.keystate_right
if identifier == 8: return self.keystate_a
if identifier == 9: return self.keystate_x
if identifier == 10: return self.keystate_l
if identifier == 11: return self.keystate_r
return 0
mainWindow = MainWindow()
timer = gobject.timeout_add(10, lambda: mainWindow.run() or True)
gtk.main()

View File

@ -1,135 +0,0 @@
#!/usr/bin/python
import sys, time, array, ctypes, os, ao
from PyQt4 import QtCore
from PyQt4 import QtGui
from PyQt4 import QtOpenGL
from OpenGL.GL import *
from libsnes import SNES
snes = SNES()
class Canvas(QtOpenGL.QGLWidget):
def __init__(self, parent = None):
self.videobuffer = array.array('I', [0] * 512 * 512)
self.colortable = array.array('I', [0] * 32 * 32 * 32)
offset = 0
for r in xrange(32):
for g in xrange(32):
for b in xrange(32):
self.colortable[offset] = (b << 19) + (g << 11) + (r << 3)
offset += 1
snes.set_colortable(self.colortable)
self.rasterWidth = 256
self.rasterHeight = 224
QtOpenGL.QGLWidget.__init__(self, parent)
self.setMinimumSize(512, 448)
def videoRefresh(self, data, width, height):
pitch = 2048
if height >= 448: pitch = 1024
if height == 239: height = 224
if height == 478: height = 448
self.rasterWidth = width
self.rasterHeight = height
snes.blit(self.videobuffer, 2048, width, height, data, pitch, width, height)
self.update()
def paintGL(self):
outputWidth = self.width()
outputHeight = self.height()
textureWidth = 512
textureHeight = 512
glMatrixMode(GL_PROJECTION)
glLoadIdentity()
glOrtho(0, outputWidth, 0, outputHeight, -1.0, 1.0)
glViewport(0, 0, outputWidth, outputHeight)
glMatrixMode(GL_MODELVIEW)
glLoadIdentity()
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR)
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, self.rasterWidth, self.rasterHeight, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, self.videobuffer.tostring())
w = 1.0 * self.rasterWidth / textureWidth
h = 1.0 * self.rasterHeight / textureHeight
u = outputWidth
v = outputHeight
glBegin(GL_TRIANGLE_STRIP)
glTexCoord2f(0, 0); glVertex3i(0, v, 0)
glTexCoord2f(w, 0); glVertex3i(u, v, 0)
glTexCoord2f(0, h); glVertex3i(0, 0, 0)
glTexCoord2f(w, h); glVertex3i(u, 0, 0)
glEnd()
def initializeGL(self):
glDisable(GL_ALPHA_TEST)
glDisable(GL_BLEND)
glDisable(GL_DEPTH_TEST)
glDisable(GL_POLYGON_SMOOTH)
glDisable(GL_STENCIL_TEST)
glEnable(GL_DITHER)
glEnable(GL_TEXTURE_2D)
glClearColor(0.0, 0.0, 0.0, 0.0)
glBindTexture(GL_TEXTURE_2D, glGenTextures(1))
glPixelStorei(GL_UNPACK_ROW_LENGTH, 512)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER)
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 512, 512, 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, self.videobuffer.tostring())
class MainWindow(QtGui.QMainWindow):
def __init__(self, parent = None):
QtGui.QMainWindow.__init__(self, parent)
self.setWindowTitle("bsnes/PyQt")
self.menu_system = self.menuBar().addMenu("&System")
self.menu_system_loadCartridge = QtGui.QAction("Load Cartridge ...", self)
self.connect(self.menu_system_loadCartridge, QtCore.SIGNAL('triggered()'), self.loadCartridgeEvent)
self.menu_system.addAction(self.menu_system_loadCartridge)
self.menu_system_quit = QtGui.QAction("Quit", self)
self.connect(self.menu_system_quit, QtCore.SIGNAL('triggered()'), QtCore.SLOT('close()'))
self.menu_system.addAction(self.menu_system_quit)
self.menu_settings = self.menuBar().addMenu("S&ettings")
self.menu_tools = self.menuBar().addMenu("&Tools")
self.menu_help = self.menuBar().addMenu("&Help")
self.canvas = Canvas()
self.setCentralWidget(self.canvas)
self.resize(0, 0)
self.show()
self.audio = ao.AudioDevice("alsa", bits = 16, rate = 32000, channels = 2)
snes.init()
snes.set_video_refresh(self.canvas.videoRefresh)
snes.set_audio_sample(self.audioSample)
if len(sys.argv) == 2:
snes.load_cartridge_normal(sys.argv[1])
def audioSample(self, left, right):
self.audio.play(array.array('H', [left, right]), 4)
def loadCartridgeEvent(self):
filename = QtGui.QFileDialog.getOpenFileName(self, "Load SNES Cartridge", "", "SNES cartridges (*.sfc)")
if len(filename) > 0:
snes.load_cartridge_normal(filename)
app = QtGui.QApplication(sys.argv)
mainWindow = MainWindow()
while mainWindow.isVisible() == True:
app.processEvents()
if snes.loaded == True:
snes.run()

View File

@ -1,157 +0,0 @@
import sys, time, array, ctypes, os
libsnes = ctypes.cdll.LoadLibrary("/usr/local/lib/libsnes.so")
snes_video_refresh_t = ctypes.CFUNCTYPE(None, ctypes.POINTER(ctypes.c_uint16), ctypes.c_uint, ctypes.c_uint)
snes_set_video_refresh = libsnes.snes_set_video_refresh
snes_set_video_refresh.restype = None
snes_set_video_refresh.argtypes = [snes_video_refresh_t]
snes_audio_sample_t = ctypes.CFUNCTYPE(None, ctypes.c_uint16, ctypes.c_uint16)
snes_set_audio_sample = libsnes.snes_set_audio_sample
snes_set_audio_sample.restype = None
snes_set_audio_sample.argtypes = [snes_audio_sample_t]
snes_input_poll_t = ctypes.CFUNCTYPE(None)
snes_set_input_poll = libsnes.snes_set_input_poll
snes_set_input_poll.restype = None
snes_set_input_poll.argtypes = [snes_input_poll_t]
snes_input_state_t = ctypes.CFUNCTYPE(ctypes.c_int16, ctypes.c_bool, ctypes.c_uint, ctypes.c_uint, ctypes.c_uint)
snes_set_input_state = libsnes.snes_set_input_state
snes_set_input_state.restype = ctypes.c_int16
snes_set_input_state.argtypes = [snes_input_state_t]
snes_library_revision = libsnes.snes_library_revision
snes_library_revision.restype = ctypes.c_uint
snes_library_revision.argtypes = []
snes_init = libsnes.snes_init
snes_init.restype = None
snes_init.argtypes = []
snes_term = libsnes.snes_term
snes_term.restype = None
snes_term.argtypes = []
snes_power = libsnes.snes_power
snes_power.restype = None
snes_power.argtypes = []
snes_reset = libsnes.snes_reset
snes_reset.restype = None
snes_reset.argtypes = []
snes_run = libsnes.snes_run
snes_run.restype = None
snes_run.argtypes = []
snes_unload = libsnes.snes_unload
snes_unload.restype = None
snes_unload.argtypes = []
snes_serialize_size = libsnes.snes_serialize_size
snes_serialize_size.restype = ctypes.c_uint
snes_serialize_size.argtypes = []
snes_serialize = libsnes.snes_serialize
snes_serialize.restype = ctypes.c_bool
snes_serialize.argtypes = [ctypes.POINTER(ctypes.c_uint8), ctypes.c_uint]
snes_unserialize = libsnes.snes_unserialize
snes_unserialize.restype = ctypes.c_bool
snes_unserialize.argtypes = [ctypes.POINTER(ctypes.c_uint8), ctypes.c_uint]
snes_cheat_reset = libsnes.snes_cheat_reset
snes_cheat_reset.restype = None
snes_cheat_reset.argtypes = []
snes_cheat_set = libsnes.snes_cheat_set
snes_cheat_set.restype = None
snes_cheat_set.argtypes = [ctypes.c_uint, ctypes.c_bool, ctypes.POINTER(ctypes.c_char)]
snes_load_cartridge_normal = libsnes.snes_load_cartridge_normal
snes_load_cartridge_normal.restype = None
snes_load_cartridge_normal.argtypes = [ctypes.POINTER(ctypes.c_char), ctypes.POINTER(ctypes.c_uint8), ctypes.c_uint]
snes_get_region = libsnes.snes_get_region
snes_get_region.restype = ctypes.c_bool
snes_get_region.argtypes = []
snes_get_memory_data = libsnes.snes_get_memory_data
snes_get_memory_data.restype = ctypes.POINTER(ctypes.c_uint8)
snes_get_memory_data.argtypes = [ctypes.c_uint]
snes_get_memory_size = libsnes.snes_get_memory_size
snes_get_memory_size.restype = ctypes.c_uint
snes_get_memory_size.argtypes = [ctypes.c_uint]
snes_blit_set_colortable = libsnes.snes_blit_set_colortable
snes_blit_set_colortable.restype = None
snes_blit_set_colortable.argtypes = [ctypes.POINTER(ctypes.c_uint32)]
snes_blit = libsnes.snes_blit
snes_blit.restype = None
snes_blit.argtypes = [ctypes.POINTER(ctypes.c_uint32), ctypes.c_uint, ctypes.c_uint, ctypes.c_uint, ctypes.POINTER(ctypes.c_uint16), ctypes.c_uint, ctypes.c_uint, ctypes.c_uint]
class SNES:
def __init__(self):
self.loaded = False
def library_revision(self):
return snes_library_revision()
def set_video_refresh(self, callback):
self.video_refresh = snes_video_refresh_t(callback)
snes_set_video_refresh(self.video_refresh)
def set_audio_sample(self, callback):
self.audio_sample = snes_audio_sample_t(callback)
snes_set_audio_sample(self.audio_sample)
def set_input_poll(self, callback):
self.input_poll = snes_input_poll_t(callback)
snes_set_input_poll(self.input_poll)
def set_input_state(self, callback):
self.input_state = snes_input_state_t(callback)
snes_set_input_state(self.input_state)
def init(self):
snes_init()
def term(self):
snes_term()
def power(self):
snes_power()
def reset(self):
snes_reset()
def run(self):
snes_run()
def unload(self):
snes_unload()
self.loaded = False
def serialize_size(self):
return snes_serialize_size()
def load_cartridge_normal(self, filename):
size = os.path.getsize(filename)
fp = open(filename, "rb")
data = fp.read()
snes_load_cartridge_normal(None, ctypes.cast(data, ctypes.POINTER(ctypes.c_uint8)), size)
fp.close()
self.loaded = True
def get_region(self):
return snes_get_region()
def set_colortable(self, colortable):
snes_blit_set_colortable(ctypes.cast(colortable.buffer_info()[0], ctypes.POINTER(ctypes.c_uint32)))
def blit(self, outbuffer, outpitch, outwidth, outheight, inbuffer, inpitch, width, height):
snes_blit(ctypes.cast(outbuffer.buffer_info()[0], ctypes.POINTER(ctypes.c_uint32)), outpitch, outwidth, outheight, inbuffer, inpitch, width, height)

Binary file not shown.