Compare commits

..

1 commit

Author SHA1 Message Date
Ilari Liusvaara
77ee92e7c4 Multicore WIP 2015-01-11 11:20:06 +02:00
344 changed files with 5329 additions and 9054 deletions

6
.gitmodules vendored
View file

@ -1,6 +0,0 @@
[submodule "bsnes"]
path = bsnes
url = .
[submodule "gambatte"]
path = gambatte
url = .

369
CHANGELOG
View file

@ -1819,372 +1819,3 @@ rr2-β21 [Sunday May 4th 2014]
* Some Win32 build fixes
* TAS input keyboard support
* Use urandom / rtlgenrandom
rr2-β22 [Saturday January 24th 2015]
====================================
* Lua: memory.getregisters()
* Zeroize: Don't crash if size=0
* Remove unused variable and some commented out debug code
* movb -> lsnes_instance.mlogic
* lsnes_memory -> lsnes_instance.memory
* Don't extern lsnes_lua_state, it is only used in one file
* lsnes_lua_state -> lsnes_instance.lua
* lsnes_memorywatch -> lsnes_instance.mwatch
* lsnes_vsetc -> lsnes_instance.setcache
* Get rid of lsnes_vset[foo]
* Instancefy inthread.cpp stuff
* Instancefy subtitles.cpp stuff
* Clean up some uses of lsnes_instance
* Instancefy mbranch.cpp stuff
* Kill unused generic_controller_name()
* Instancefy multitrack.cpp stuff
* Instancefy emustatus.cpp stuff
* Split random number functions from misc.cpp to dedicated file
* Move lsnes_kbd and lsnes_mapper to be instance vars
* Command sets WIP
* Simplify command::* memory management
* Use recursive locks to deal with the locking mess in command::*
* Delete some unused fields
* Fix valgrind warnings in inthread.cpp
* Inverse binding sets
* EVDEV: Select on joysticks
* Listener object is better than 3 lambdas + handle
* Initialize fdset before polling on it
* Setting sets
* Kill command::set::get_commands()
* Reduce dependicies between header files
* keyboard.cpp: Get rid of register_queue
* keyboard-mapper.cpp: Get rid of register_queue
* Lua.cpp: Get rid of register-queue
* settingvar.cpp: Get rid of register_queue
* Lua.cpp: Don't call unregister callbacks if nothing get unreg'd
* Kill off register-queue
* Rename some classes
* Move memorywatch stuff to dedicated namespace
* Namespacify mathexpr
* Move lua-framebuffer to lua namespace
* lua.hpp: Forward-declare keyboard::key
* controller_frame_vector: Use object instead of lambda for notify
* Scope listener base classes inside respective master classes
* Fix keyboard::keyboard::all_keys and all_modifiers
* Toggle sound mute command/hotkey
* Move directory stuff to dedicated namespace
* Move rename_overwrite from zip:: to directory::
* Change some terms in UI
* Don't crash if trying to select key without keys (shouldn't happen)
* Instancefy alias binds management
* Instancefy next rrdata
* Instancefy internal emulation thread execution queue
* Instancefy cart mappings
* Make main controllers state a instance variable
* Introduce run_show_error() and use it to clean up some code
* Instancefy project state
* Don't crash on exit with voice track loaded
* Get rid of most absolute refs to lsnes_instance in src/core
* run in emu thread: Throw exceptions over thread switches
* Gambatte: Fix bus write breaks
* Gambatte: Fix execute breaks on bus and IOAMHRAM
* Don't corrupt memory when trying to GC various items on exit
* Make the emulator harder to imporperly quit
* Fix all sort of Windows stupidities
* Add some test commands
* Refactor debugging into instance object
* Faster arithmetic modulo 2^255-19 on 64-bit
* Remove broken crap
* Some optimizations & fixes
* Some more optimization, some test code for this thing
* Move some debug stuff to be in class scope
* Instancefy framerate stuff
* Instancefy framebuffer stuff
* Make various instance stuff to take references to other instance objs
* Do some more stuff missed in last commit
* Factor queue stuff to its own file
* Make instance vars to be pointers
* Properly handle deletes if those behave oddly on some platform
* Remove unused dump_region_map()
* Rewrite basic video dumping framework
* Instancefy button manager stuff
* Make helper class for instance member allocation / deallocation
* Combine some small headers together
* Factor message stream stuff to its own files
* Some #include cleanup
* Move render_video_hud and killed_audio_length to master dumper class
* Refactor video dump framedrop handling
* Instancefy dispatch stuff
* Move action_update to be via dispatch
* Remove unused load_rom_from_commandline
* More include cleanups
* Instancefy base mmio stuff
* Get rid of direct references to emulation thread in branchesmenu.cpp
* Use variable obtained earlier for current branch
* Cleanup direct emulation thread references in editor-authors.cpp
* Get rid of direct references from dumpmenu.cpp to emulation thread
* Remove direct emulation thread references from keyboard.cpp
* Sweep instance variables upward in UI code
* Fix repainting status panel
* More sweeping instance variables up
* Eliminate settings_tab::call_window_fit(), nothing uses it
* Push instances up out from settings window code
* Push instance vars out of keyboard/mouse driver code
* Do not use CORE() multiple times in the same function, it is pointless
* Use helper class to simplify per-instance external vars
* Fix warnings from valgrind
* Refactor slotcache to be instance variable
* Make some values const, remove some unused stuff
* Lua: Memory address object
* Kill emulation_thread, nothing uses it
* lua::state::reset(): Use get instead of get_soft
* Instancefy lua core stuff
* Don't crash if exiting on panic
* When panicing, show last message (as it is presumably related)
* read_lua_fragment: Don't duplicate the script infinite number of times
* Actually don't start if sysrc.lua is bad
* Remove Lua 5.1 support
* Make some arrow magic constants in gui-arrow.cpp const
* Make render queue scratch variables instance variables
* Some non-instance variables cleanup
* Cleanup unused boost includes
* Instancefy audioapi core (but not driver) stuff
* Make some static variables in audioapi functions fields of audioapi class
* Instancefy currently loaded ROM
* Privatefy loaded_rom rtype, region and orig_region
* Refactor save jukebox handling into its own class
* Make class for emulator run mode
* Factor updating status to its own class
* Cleanup some symbols
* Fix updating statusbar on save slot change
* Clean up window-fileupload.cpp
* Clean up use of project->moviepath/otherpath
* Clean up instance usage in editor-voicesub.cpp
* Use UI_in_project_context() in branchesmenu.cpp
* bsnes: Fix on_latch in alttimings mode
* Fix build on GCC 4.9
* Fix memory.writeregion
* Fix compilation on Mac OS X
* Fix loading lz images with 128 or more colors
* Fix some accidentially mistyped variables in makefile
* Lua: Initialize some variables in address.cpp to make GCC happy
* Revert "Remove Lua 5.1 support"
* 25519: Add valgrind test mode
* Opus: Support some newly added stuff
* Small whitespace cleanup
* Commentary: Fix gain on oggopus export
* Fix emulator going out of whack after project load
* Add -pthread to flags
* Don't overdraw in outside draw
* Add few extra sound commands
* Fix jukebox slot select
* Remember sound device over sound restart
* Remember sound devices
* Oggopus: Complain about single-dpage streams with bad granulepos
* Lua: memory.action_flags
* Print messages about loaded libraries
* Library: Don't fail link without library support
* Wxwidgets: --library=<filename>
* C interface: render_text (version bump to v2)
* Music: Use all PSID LSIDs as implicit entrypoints (not just the first)
* Refactor controller runtime code generation
* Namespace library port-controller stuff
* Refactor library GC to its own namespace
* Refactor memory_region{,_direct} to be subclasses of memory_space
* Make workthread a class in top namespace and move some stuff under it
* Rename token_iterator_foreach to token_iterator::foreach
* Split audioapi to core interface and driver interface parts
* Fix crash if canceling load of other project
* Allow memory watch to read registers
* Show error dialog if project switch fails
* Add missing file
* gambatte fixes: Properly save MBC3 without RTC
* Don't try to do controller runtime codegen on X32, it won't work
* Memory watch fixes
* Rudimentary library unloading support
* Allow binding commands to class instance
* Module unloading: Small cleanup
* Module unloading: Small further cleanup
* Reinitialize gamepads command and fix EVDEV going bonkers on gamepad suddenly disconnecting
* Remove unused function
* Show VMA relative hex address when dumping debug hook list
* Tweak format of command help files and do some further command cleanup
* Don't try to unregister killed debug CBs
* bsnes: Add hcounter/vcounter registers
* Tracelogger: Unregister the frame callback even on hard kill
* Music playback: Guard against crazy pcmpos
* Wxwidgets: Fix loading ROM from commandline
* Fix most hotkeys to show up in configuration (were missing due to errant !)
* Fix error message if trying to load ROM with project active
* If project switch loads savestate, mark position at point of save
* Squash some wrong-thread bugs
* Memory editor: Squash another wrong-thread bug
* Add the UI thread checking code
* runuifun: Allow marking cb routine to run once at a time
* wxwidgets: Add some missing conversions for string arguments
* Oops from previous commit
* Portaudio: Don't blacklist ALSA default/sysdefault for input
* Redraw framebuffer when entering break pause
* Fix some nondeterminism (probably wouldn't cause desyncs)
* Lua: PALETTE:get()
* Fix some valgrind warnings
* Exit immediately on double fault
* Update the default build options
* Libao: Don't crash on quit
* Remove some utilities that should not be there anymore
* Use $DOT_EXECUTABLE_SUFFIX instead of hardcoding .exe
* Fattest? Really?
* Ignore some build helper programs, now that the .exe rule doesn't cover those
* Don't use arbitrary garbage as amount of samples to squash
* Show error from Lua if parsing Lua expression fails
* Don't let one unload currently used core (crashes the emulator)
* Lua 5.3 support
* Cleanup Lua multiversion support
* Add wide (64 bits) versions of bit functions if Lua 5.3 is used
* Fix Win32 build
* Fix compile error with Lua 5.1
* Clean up all build helper programs on make clean
* Add commands and Lua functions to manipulate running speed
* Remove target for font.cpp.dep
* Readd rule for font.cpp.dep in different way
* Pluginmanager: Autocreate directory instead of crashing
* Fix bad download crashing the emulator
* bsnes: DMA tracing
* bsnes: Support IRQ/NMI tracing
rr2-β23 [Thursday May 28th 2015]
================================
* Lua: Don't lua_error() out of context with pending dtors
* Add $LSNES_NO_SOUND_IN to disable sound input
* Makefile: Build cmdhelp before anything else
* keymapper: Verify gamepad config write before committing
* Remember volume settings across restarts
* Remember video settings
* Fix CUSTOMFONT text positioning
* Only exit poll advance on poll to non-00 control
* Show error instead silently failing tangent positive edge
* Fix race condition in makefile
* Fix scaling-related crashes
* NULL video dumper
* Fix some compilation errors on Mac OS X
* Move all regex matching to library/string.cpp
* Switch to std::regex by default
* Movie editor: Don't lock up on trying to display error messages
* Add a internal TODO list
* Lua: add gui.get_runmode()
* Movie editor: Fix unnamed branch to show properly in select branch
* If initsram/initstate points to LSS file, pull the matching member
* wxwidgets: Hide dumper called "NULL"
* Force game panel to window size in fullscreen mode
* Implicitly redirect cmdhelp includes to corresponding JSON files
* Fix movie length being wrong for imported binary tracks
* Lua: input.controller_info(): Don't crash with out-of-range port
* Lua: movie.rom_loaded()
* Lua: movie.get_rom_info()
* Force a repaint when becoming fullscreen
* wxwidgets: exit-fullscreen to forcibly exit fullscreen mode
* Make gitlinks for bsnes and gambatte
* Throw mic in to entropy pool
* Fix hostendian memory watches
* Fix race condition in do_mix_tsc()
* Lua: Don't run class destructor if constructor failed
* Fix typo in resolve_filename documentation
* bit.(r)flagdecode: Fix unicode in on/off strings
* Wxwidgets: Add keycode entries for å, ä and ö
* Wxwidgets: Fix §
* Wxwidgets: Fix some compile errors in editor-memorywatch.cpp
* Wxwidgets: Fix some compile errors in window-fileupload.cpp
* Lua: movie.get_game_info
* Don't callback to Lua in inconsistent state when loading a new ROM
* SNES: Functions for messing with clockrate (for debugging games)
* Remove some unnecressary casts
* Add back reload-rom and close-rom
* Add load-rom command
* Split overly large loaded_rom constructor
* Fix speed going out of whack after doing unsafe rewind
* Refactor loaded_rom to make public fields private
* Move NULL core code to its own file
* Internally refactor loaded ROM imageset out of loaded ROM code
* Refer to loaded ROM imagesets as handles
* A bit of code cleanup
* Mark the core methods that should be idempotent as const
* Refactor dynamic state to its own subobject
* Refactor unsafe rewinding a bit now that state is its own subobject
* Clean up dynamic state handling a bit
* Circle coordinates can go negative and thus must be signed
* Add dedicated method for resetting to poweron state
* Add description of PALETTE:get()
* Fix typo in Lua reference
* Don't leak open file descriptors to loaded ROMs
* Fix race between killing object and drawing object
* Fix a compiler warning
* Small rendering speedups
* Actually kill objects using palette about to be GC'd
* font rendering: Use ranges for bounding instead of buggy routine
* Have only one main Lua function trampoline
* Use master state for trampolines
* Lua: Memory usage limit
* Framework for memory usage tracking
* Redo text rendering (adds halo support to gui.text())
* Make git diff --check happier
* Clean up system font drawing
* Memory tracker: Add tracking of render objects
* Rework how memory tracking works
* Small whitespace cleanup
rr2-β24 [Monday December 31st 2018]
===================================
* Don't overflow buffers if bsnes goes bonkers* Lua: get_directory_contents & get_file_type
* Fix multiple problems with text drawing
* Fix load preserving movie displaying wrong screenshot
* Eliminate sloppy types from headers
* Don't crash on trying to create 0x0 bitmap or tilemap
* Lua: CUSTOMFONT:dump(): Dump font to file
* Fix build breakage on Win32
* Close the ROM on quit to avoid crashes
* Remove bogus comments in gui-tilemap.cpp
* Merge remote-tracking branch 'origin/master'
* Cleanup bitmap and tilemap rendering a bit
* Merge some common drawing code between bitmaps and tilemaps
* Use standard bitmap composition for rendered text bitmaps
* ss_int24_t and ss_uint24_t are integers
* Fix do_load_rom() in readonly case
* Add movie.subframe_to_frame
* movie::frame_subframes: Gracefully handle invalid frame numbers
* Fix crash on loading invalid PNG files
* Fix gamepad reset
* Fix bsnes compilation for GCC 5.X
* Fix MSU-1 bug where write to MSU1BASE+4 is mirred to MSUBASE+5
* When loading gamepaks, use #1 as MSU-1 base only if system has BIOS
* Fix help for +tangent/-tangent to be less obscure
* Fix disassembly of SNES BRL instruction
* Fix crash if loading type0 PNG without tRNS chunk
* Fix compilation with Lua 5.1
* Nuke last remains of boost::regex from outside string.cpp
* Add regex sanity checks on startup and add --sanity-check
* Fix Valgrind warning about uninitialized variable
* Add bit.fextract, bit.bfields
* bsnes: Add Lua function to dump 2bpp sprites (and allow 4-color palettes)
* Fix "empty path points to root" bug
* Don't try to uninstall handlers for active core
* Allow modifying button to be autofire/autohold/typed
* Lua Add getters for various paths
* Some new hotkeys
* Small cleanup: move up some lsnes_instance stuff
* Virtualize audio system for instances
* Fix crash if mouse_x or mouse_y are hooked
* Don't try to enter loadstate with loadstate already in progress
* Fix crash if text containing \n is printed at nonzero x
* PIX_FMT_* constants are deprecated, use AV_PIX_FMT_* instead
* Support uncompressing ZIP compression method 12 (bzip2)
* Lua: Fix type confusion between signed and unsigned
* When redrawing screen, read the last written frame
* Fix few uninitialized variables and a stack smash in AVI dumper
* Linear transformed texture sampling for (d)bitmap
* Specialize (D)BITMAP:sample_texture when s is power of two
* Lua (d)bitmap: add hflip and vflip functions
* Save: Fix issues with adding an extension if missing
* De-header SNES games with headers submultiple of 512 bytes correctly
* Make wrapper for boost::lexical_cast
* Bus fixes: Reading of CPU MMIO registers does not update MDR
* Add <functional> to files that use std::function
* Delay committing fullscreen until seeing window size change
* Track all window size changes while in fullscreen
* Fix bogus ROM type mismatch when using --rom
* movie.get_last_movie()

View file

@ -20,8 +20,7 @@ ifdef HOST_BOOST_NEEDS_MT
HOST_BOOST_POSTFIX=-mt
endif
LDFLAGS = -pthread -lboost_iostreams$(BOOST_LIB_POSTFIX) -lboost_filesystem$(BOOST_LIB_POSTFIX) -lboost_system$(BOOST_LIB_POSTFIX) -lz $(USER_LDFLAGS)
HOSTHELPER_LDFLAGS =
LDFLAGS = -pthread -lboost_iostreams$(BOOST_LIB_POSTFIX) -lboost_filesystem$(BOOST_LIB_POSTFIX) -lboost_system$(BOOST_LIB_POSTFIX) -lboost_regex$(BOOST_LIB_POSTFIX) -lz $(USER_LDFLAGS)
ifeq ($(THREADS), NATIVE)
CFLAGS += -DNATIVE_THREADS
@ -34,14 +33,6 @@ $(error "Bad value for THREADS (expected NATIVE or BOOST)")
endif
endif
ifeq ($(REGEX), BOOST)
CFLAGS += -DUSE_BOOST_REGEX
LDFLAGS += -lboost_regex$(BOOST_LIB_POSTFIX)
HOSTHELPER_LDFLAGS += -lboost_regex$(HOST_BOOST_POSTFIX)
endif
HOSTHELPER_LDFLAGS += -lboost_system$(HOST_BOOST_POSTFIX)
ifdef NEED_LIBICONV
LDFLAGS += -liconv
endif
@ -99,8 +90,6 @@ platclean:
clean:
$(MAKE) -C src clean
rm -f buildaux/version$(DOT_EXECUTABLE_SUFFIX)
rm -f buildaux/mkdeps$(DOT_EXECUTABLE_SUFFIX)
rm -f buildaux/txt2cstr$(DOT_EXECUTABLE_SUFFIX)
forcelook:
@true

3
TODO
View file

@ -1,3 +0,0 @@
- Memory Tracking: Track dynamic state.
- Fix paths and filenames containing non-ASCII on Win32.
- Win64 build.

View file

@ -1 +1 @@
2-β24
2-β21

1
bsnes

@ -1 +0,0 @@
Subproject commit 4cfbbeadc3abe3e3911f7f59ce57b715edc76563

View file

@ -1,7 +1,7 @@
From b19b3b2d1d7a522af695f4482abb28e52804326b Mon Sep 17 00:00:00 2001
From: Ilari Liusvaara <ilari.liusvaara@elisanet.fi>
Date: Wed, 9 Nov 2011 00:30:36 +0200
Subject: [PATCH 01/27] Make libsnes compile
Subject: [PATCH 01/21] Make libsnes compile
Changes between v083 and v084 had broken libsnes. Fix it so it at least
compiles.
@ -10,7 +10,7 @@ compiles.
1 file changed, 35 insertions(+), 2 deletions(-)
diff --git a/ui-libsnes/libsnes.cpp b/ui-libsnes/libsnes.cpp
index fbb4482c..5f5ded69 100755
index fbb4482..5f5ded6 100755
--- a/ui-libsnes/libsnes.cpp
+++ b/ui-libsnes/libsnes.cpp
@@ -1,5 +1,6 @@
@ -78,5 +78,5 @@ index fbb4482c..5f5ded69 100755
}
SNES::cartridge.load(SNES::Cartridge::Mode::SuperGameBoy, xmlrom);
--
2.15.0.rc1
2.0.0

View file

@ -1,7 +1,7 @@
From bb2fed04fbfe62a89e4bcfe90f44b4738f7c7c1a Mon Sep 17 00:00:00 2001
From: Ilari Liusvaara <ilari.liusvaara@elisanet.fi>
Date: Wed, 9 Nov 2011 00:31:59 +0200
Subject: [PATCH 02/27] Fix bsnes version number in libsnes to be v085, not
Subject: [PATCH 02/21] Fix bsnes version number in libsnes to be v085, not
v083
---
@ -9,7 +9,7 @@ Subject: [PATCH 02/27] Fix bsnes version number in libsnes to be v085, not
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/ui-libsnes/libsnes.cpp b/ui-libsnes/libsnes.cpp
index 5f5ded69..0e63075e 100755
index 5f5ded6..0e63075 100755
--- a/ui-libsnes/libsnes.cpp
+++ b/ui-libsnes/libsnes.cpp
@@ -112,7 +112,7 @@ struct Interface : public SNES::Interface {
@ -22,5 +22,5 @@ index 5f5ded69..0e63075e 100755
unsigned snes_library_revision_major(void) {
--
2.15.0.rc1
2.0.0

View file

@ -1,7 +1,7 @@
From 7379b4570e5755a5a1da25181ba4f5d1ca461a98 Mon Sep 17 00:00:00 2001
From: Ilari Liusvaara <ilari.liusvaara@elisanet.fi>
Date: Wed, 9 Nov 2011 00:37:44 +0200
Subject: [PATCH 03/27] Don't use time() in emulating chips
Subject: [PATCH 03/21] Don't use time() in emulating chips
Instead of using time() in chip emulation, create new interface method
currentTime(), defaulting to time(0). This way frontend can cleanly
@ -15,7 +15,7 @@ override the current time bsnes is using.
5 files changed, 9 insertions(+), 3 deletions(-)
diff --git a/snes/chip/bsx/satellaview/satellaview.cpp b/snes/chip/bsx/satellaview/satellaview.cpp
index 386fb628..3c980195 100755
index 386fb62..3c98019 100755
--- a/snes/chip/bsx/satellaview/satellaview.cpp
+++ b/snes/chip/bsx/satellaview/satellaview.cpp
@@ -38,7 +38,7 @@ uint8 BSXSatellaview::mmio_read(unsigned addr) {
@ -28,7 +28,7 @@ index 386fb628..3c980195 100755
regs.r2192_hour = t->tm_hour;
diff --git a/snes/chip/spc7110/spc7110.cpp b/snes/chip/spc7110/spc7110.cpp
index d2dc640b..74a817a6 100755
index d2dc640..74a817a 100755
--- a/snes/chip/spc7110/spc7110.cpp
+++ b/snes/chip/spc7110/spc7110.cpp
@@ -101,7 +101,7 @@ void SPC7110::set_data_adjust(unsigned addr) { r4814 = addr; r4815 = addr >> 8;
@ -41,7 +41,7 @@ index d2dc640b..74a817a6 100755
//sizeof(time_t) is platform-dependent; though rtc[] needs to be platform-agnostic.
//yet platforms with 32-bit signed time_t will overflow every ~68 years. handle this by
diff --git a/snes/chip/srtc/srtc.cpp b/snes/chip/srtc/srtc.cpp
index 1b2fd2aa..78fc4c1f 100755
index 1b2fd2a..78fc4c1 100755
--- a/snes/chip/srtc/srtc.cpp
+++ b/snes/chip/srtc/srtc.cpp
@@ -31,7 +31,7 @@ void SRTC::reset() {
@ -54,7 +54,7 @@ index 1b2fd2aa..78fc4c1f 100755
//sizeof(time_t) is platform-dependent; though rtc[] needs to be platform-agnostic.
//yet platforms with 32-bit signed time_t will overflow every ~68 years. handle this by
diff --git a/snes/interface/interface.cpp b/snes/interface/interface.cpp
index a0e3a81b..b3017c90 100755
index a0e3a81..b3017c9 100755
--- a/snes/interface/interface.cpp
+++ b/snes/interface/interface.cpp
@@ -18,4 +18,9 @@ void Interface::message(const string &text) {
@ -68,7 +68,7 @@ index a0e3a81b..b3017c90 100755
+
}
diff --git a/snes/interface/interface.hpp b/snes/interface/interface.hpp
index f1a48c0f..df975e83 100755
index f1a48c0..df975e8 100755
--- a/snes/interface/interface.hpp
+++ b/snes/interface/interface.hpp
@@ -5,6 +5,7 @@ struct Interface {
@ -80,5 +80,5 @@ index f1a48c0f..df975e83 100755
extern Interface *interface;
--
2.15.0.rc1
2.0.0

View file

@ -1,7 +1,7 @@
From efe1b5884c316ce070953edd87c6c9aeffffaa94 Mon Sep 17 00:00:00 2001
From: Ilari Liusvaara <ilari.liusvaara@elisanet.fi>
Date: Wed, 9 Nov 2011 01:52:08 +0200
Subject: [PATCH 04/27] Save controller state when savestating
Subject: [PATCH 04/21] Save controller state when savestating
When savestating, save the controller state and restore it upon loadstate.
Prevents libsnes from mixing up buttons.
@ -24,7 +24,7 @@ Prevents libsnes from mixing up buttons.
15 files changed, 142 insertions(+), 3 deletions(-)
diff --git a/snes/controller/controller.cpp b/snes/controller/controller.cpp
index 9091b21b..f254bedb 100755
index 9091b21..f254bed 100755
--- a/snes/controller/controller.cpp
+++ b/snes/controller/controller.cpp
@@ -46,8 +46,16 @@ void Controller::iobit(bool data) {
@ -45,7 +45,7 @@ index 9091b21b..f254bedb 100755
+
}
diff --git a/snes/controller/controller.hpp b/snes/controller/controller.hpp
index 73327129..827b2eb4 100755
index 7332712..827b2eb 100755
--- a/snes/controller/controller.hpp
+++ b/snes/controller/controller.hpp
@@ -13,12 +13,14 @@
@ -64,7 +64,7 @@ index 73327129..827b2eb4 100755
bool iobit();
void iobit(bool data);
diff --git a/snes/controller/gamepad/gamepad.cpp b/snes/controller/gamepad/gamepad.cpp
index 594020d2..4fa1c99e 100755
index 594020d..4fa1c99 100755
--- a/snes/controller/gamepad/gamepad.cpp
+++ b/snes/controller/gamepad/gamepad.cpp
@@ -13,6 +13,19 @@ void Gamepad::latch(bool data) {
@ -88,7 +88,7 @@ index 594020d2..4fa1c99e 100755
latched = 0;
counter = 0;
diff --git a/snes/controller/gamepad/gamepad.hpp b/snes/controller/gamepad/gamepad.hpp
index c5ca69ca..a2392d1e 100755
index c5ca69c..a2392d1 100755
--- a/snes/controller/gamepad/gamepad.hpp
+++ b/snes/controller/gamepad/gamepad.hpp
@@ -2,7 +2,7 @@ struct Gamepad : Controller {
@ -101,7 +101,7 @@ index c5ca69ca..a2392d1e 100755
bool latched;
unsigned counter;
diff --git a/snes/controller/justifier/justifier.cpp b/snes/controller/justifier/justifier.cpp
index 62079166..ad13a9bd 100755
index 6207916..ad13a9b 100755
--- a/snes/controller/justifier/justifier.cpp
+++ b/snes/controller/justifier/justifier.cpp
@@ -100,6 +100,42 @@ void Justifier::latch(bool data) {
@ -148,7 +148,7 @@ index 62079166..ad13a9bd 100755
create(Controller::Enter, 21477272);
latched = 0;
diff --git a/snes/controller/justifier/justifier.hpp b/snes/controller/justifier/justifier.hpp
index f927acf6..6b7bba07 100755
index f927acf..6b7bba0 100755
--- a/snes/controller/justifier/justifier.hpp
+++ b/snes/controller/justifier/justifier.hpp
@@ -2,6 +2,7 @@ struct Justifier : Controller {
@ -160,7 +160,7 @@ index f927acf6..6b7bba07 100755
//private:
diff --git a/snes/controller/mouse/mouse.cpp b/snes/controller/mouse/mouse.cpp
index c9f5d16b..6b26fae5 100755
index c9f5d16..6b26fae 100755
--- a/snes/controller/mouse/mouse.cpp
+++ b/snes/controller/mouse/mouse.cpp
@@ -61,6 +61,19 @@ void Mouse::latch(bool data) {
@ -184,7 +184,7 @@ index c9f5d16b..6b26fae5 100755
latched = 0;
counter = 0;
diff --git a/snes/controller/mouse/mouse.hpp b/snes/controller/mouse/mouse.hpp
index 95e24b65..b66ea513 100755
index 95e24b6..b66ea51 100755
--- a/snes/controller/mouse/mouse.hpp
+++ b/snes/controller/mouse/mouse.hpp
@@ -2,7 +2,7 @@ struct Mouse : Controller {
@ -197,7 +197,7 @@ index 95e24b65..b66ea513 100755
bool latched;
unsigned counter;
diff --git a/snes/controller/multitap/multitap.cpp b/snes/controller/multitap/multitap.cpp
index 3a6eb720..146c41d4 100755
index 3a6eb72..146c41d 100755
--- a/snes/controller/multitap/multitap.cpp
+++ b/snes/controller/multitap/multitap.cpp
@@ -30,6 +30,22 @@ void Multitap::latch(bool data) {
@ -224,7 +224,7 @@ index 3a6eb720..146c41d4 100755
latched = 0;
counter1 = 0;
diff --git a/snes/controller/multitap/multitap.hpp b/snes/controller/multitap/multitap.hpp
index 0540af71..e6324ac5 100755
index 0540af7..e6324ac 100755
--- a/snes/controller/multitap/multitap.hpp
+++ b/snes/controller/multitap/multitap.hpp
@@ -2,7 +2,7 @@ struct Multitap : Controller {
@ -237,7 +237,7 @@ index 0540af71..e6324ac5 100755
bool latched;
unsigned counter1;
diff --git a/snes/controller/superscope/superscope.cpp b/snes/controller/superscope/superscope.cpp
index 12068f05..1a1dfbff 100755
index 12068f0..1a1dfbf 100755
--- a/snes/controller/superscope/superscope.cpp
+++ b/snes/controller/superscope/superscope.cpp
@@ -100,6 +100,37 @@ void SuperScope::latch(bool data) {
@ -279,7 +279,7 @@ index 12068f05..1a1dfbff 100755
create(Controller::Enter, 21477272);
latched = 0;
diff --git a/snes/controller/superscope/superscope.hpp b/snes/controller/superscope/superscope.hpp
index a7a90b71..93509d79 100755
index a7a90b7..93509d7 100755
--- a/snes/controller/superscope/superscope.hpp
+++ b/snes/controller/superscope/superscope.hpp
@@ -2,6 +2,7 @@ struct SuperScope : Controller {
@ -291,7 +291,7 @@ index a7a90b71..93509d79 100755
//private:
diff --git a/snes/system/input.cpp b/snes/system/input.cpp
index 90503106..ec5559dc 100755
index 9050310..ec5559d 100755
--- a/snes/system/input.cpp
+++ b/snes/system/input.cpp
@@ -26,6 +26,22 @@ void Input::connect(bool port, Input::Device id) {
@ -318,7 +318,7 @@ index 90503106..ec5559dc 100755
connect(Controller::Port1, Input::Device::Joypad);
connect(Controller::Port2, Input::Device::Joypad);
diff --git a/snes/system/input.hpp b/snes/system/input.hpp
index 13ef46e1..6832e823 100755
index 13ef46e..6832e82 100755
--- a/snes/system/input.hpp
+++ b/snes/system/input.hpp
@@ -31,6 +31,7 @@ struct Input {
@ -330,7 +330,7 @@ index 13ef46e1..6832e823 100755
Input();
~Input();
diff --git a/snes/system/serialization.cpp b/snes/system/serialization.cpp
index f7d6f3b1..08e70510 100755
index f7d6f3b..08e7051 100755
--- a/snes/system/serialization.cpp
+++ b/snes/system/serialization.cpp
@@ -56,6 +56,7 @@ void System::serialize_all(serializer &s) {
@ -342,5 +342,5 @@ index f7d6f3b1..08e70510 100755
if(cartridge.mode() == Cartridge::Mode::SufamiTurbo) sufamiturbo.serialize(s);
if(cartridge.mode() == Cartridge::Mode::SuperGameBoy) icd2.serialize(s);
--
2.15.0.rc1
2.0.0

View file

@ -1,14 +1,14 @@
From cdf2f46490f128308eb7f399d03530936ebeda0a Mon Sep 17 00:00:00 2001
From: Ilari Liusvaara <ilari.liusvaara@elisanet.fi>
Date: Fri, 11 Nov 2011 03:05:48 +0200
Subject: [PATCH 05/27] Fix unserialization of 64-bit signed integers
Subject: [PATCH 05/21] Fix unserialization of 64-bit signed integers
---
nall/serializer.hpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/nall/serializer.hpp b/nall/serializer.hpp
index ff2337ab..e6bc8fad 100755
index ff2337a..e6bc8fa 100755
--- a/nall/serializer.hpp
+++ b/nall/serializer.hpp
@@ -58,7 +58,7 @@ namespace nall {
@ -21,5 +21,5 @@ index ff2337ab..e6bc8fad 100755
isize += size;
}
--
2.15.0.rc1
2.0.0

View file

@ -1,7 +1,7 @@
From 4dc46334ec175e26277632fee4aea80768749af9 Mon Sep 17 00:00:00 2001
From: Ilari Liusvaara <ilari.liusvaara@elisanet.fi>
Date: Fri, 11 Nov 2011 19:49:46 +0200
Subject: [PATCH 06/27] Allow frontend to control random number seed
Subject: [PATCH 06/21] Allow frontend to control random number seed
---
snes/interface/interface.cpp | 5 +++++
@ -10,7 +10,7 @@ Subject: [PATCH 06/27] Allow frontend to control random number seed
3 files changed, 7 insertions(+), 1 deletion(-)
diff --git a/snes/interface/interface.cpp b/snes/interface/interface.cpp
index b3017c90..0a21a132 100755
index b3017c9..0a21a13 100755
--- a/snes/interface/interface.cpp
+++ b/snes/interface/interface.cpp
@@ -23,4 +23,9 @@ time_t Interface::currentTime()
@ -24,7 +24,7 @@ index b3017c90..0a21a132 100755
+
}
diff --git a/snes/interface/interface.hpp b/snes/interface/interface.hpp
index df975e83..30ee7fde 100755
index df975e8..30ee7fd 100755
--- a/snes/interface/interface.hpp
+++ b/snes/interface/interface.hpp
@@ -6,6 +6,7 @@ struct Interface {
@ -36,7 +36,7 @@ index df975e83..30ee7fde 100755
extern Interface *interface;
diff --git a/snes/system/system.cpp b/snes/system/system.cpp
index c19a7c51..dbd912d8 100755
index c19a7c5..dbd912d 100755
--- a/snes/system/system.cpp
+++ b/snes/system/system.cpp
@@ -146,7 +146,7 @@ void System::unload() {
@ -49,5 +49,5 @@ index c19a7c51..dbd912d8 100755
region = config.region;
expansion = config.expansion_port;
--
2.15.0.rc1
2.0.0

View file

@ -1,7 +1,7 @@
From eeaf6dc52d39ca9c150ff61864c11297d200d968 Mon Sep 17 00:00:00 2001
From: Ilari Liusvaara <ilari.liusvaara@elisanet.fi>
Date: Wed, 7 Mar 2012 16:57:18 +0200
Subject: [PATCH 07/27] Fix mouse polling
Subject: [PATCH 07/21] Fix mouse polling
Don't poll for mouse motion excessive number of times (no need to poll it for
each bit!)
@ -11,7 +11,7 @@ each bit!)
2 files changed, 14 insertions(+), 2 deletions(-)
diff --git a/snes/controller/mouse/mouse.cpp b/snes/controller/mouse/mouse.cpp
index 6b26fae5..1a066b98 100755
index 6b26fae..1a066b9 100755
--- a/snes/controller/mouse/mouse.cpp
+++ b/snes/controller/mouse/mouse.cpp
@@ -3,9 +3,13 @@
@ -48,7 +48,7 @@ index 6b26fae5..1a066b98 100755
}
diff --git a/snes/controller/mouse/mouse.hpp b/snes/controller/mouse/mouse.hpp
index b66ea513..b07c8ab7 100755
index b66ea51..b07c8ab 100755
--- a/snes/controller/mouse/mouse.hpp
+++ b/snes/controller/mouse/mouse.hpp
@@ -6,4 +6,6 @@ struct Mouse : Controller {
@ -59,5 +59,5 @@ index b66ea513..b07c8ab7 100755
+ int _position_y;
};
--
2.15.0.rc1
2.0.0

View file

@ -1,7 +1,7 @@
From 7018377c93553071fc404db872b2746d40ac3bce Mon Sep 17 00:00:00 2001
From: Ilari Liusvaara <ilari.liusvaara@elisanet.fi>
Date: Sat, 1 Sep 2012 11:23:34 +0300
Subject: [PATCH 08/27] Fix uninitialized variables
Subject: [PATCH 08/21] Fix uninitialized variables
These uninitialized variables cause a lot of desyncs in Shadowrun.
---
@ -16,7 +16,7 @@ These uninitialized variables cause a lot of desyncs in Shadowrun.
8 files changed, 38 insertions(+)
diff --git a/snes/alt/dsp/dsp.cpp b/snes/alt/dsp/dsp.cpp
index d0c9e077..c6809f73 100755
index d0c9e07..c6809f7 100755
--- a/snes/alt/dsp/dsp.cpp
+++ b/snes/alt/dsp/dsp.cpp
@@ -40,6 +40,8 @@ void DSP::write(uint8 addr, uint8 data) {
@ -29,7 +29,7 @@ index d0c9e077..c6809f73 100755
spc_dsp.reset();
spc_dsp.set_output(samplebuffer, 8192);
diff --git a/snes/alt/ppu-compatibility/ppu.cpp b/snes/alt/ppu-compatibility/ppu.cpp
index 1a3835b3..a21e5e31 100755
index 1a3835b..a21e5e3 100755
--- a/snes/alt/ppu-compatibility/ppu.cpp
+++ b/snes/alt/ppu-compatibility/ppu.cpp
@@ -345,6 +345,17 @@ void PPU::power() {
@ -51,7 +51,7 @@ index 1a3835b3..a21e5e31 100755
}
diff --git a/snes/cpu/core/core.cpp b/snes/cpu/core/core.cpp
index 427176b0..a5b809b9 100755
index 427176b..a5b809b 100755
--- a/snes/cpu/core/core.cpp
+++ b/snes/cpu/core/core.cpp
@@ -86,4 +86,12 @@ CPUcore::CPUcore() {
@ -68,7 +68,7 @@ index 427176b0..a5b809b9 100755
+
}
diff --git a/snes/cpu/core/core.hpp b/snes/cpu/core/core.hpp
index 964bd128..7a685a8d 100755
index 964bd12..7a685a8 100755
--- a/snes/cpu/core/core.hpp
+++ b/snes/cpu/core/core.hpp
@@ -7,6 +7,8 @@ struct CPUcore {
@ -81,7 +81,7 @@ index 964bd128..7a685a8d 100755
virtual uint8_t op_read(uint32_t addr) = 0;
virtual void op_write(uint32_t addr, uint8_t data) = 0;
diff --git a/snes/cpu/cpu.cpp b/snes/cpu/cpu.cpp
index f6ae9754..2d7d3432 100755
index f6ae975..2d7d343 100755
--- a/snes/cpu/cpu.cpp
+++ b/snes/cpu/cpu.cpp
@@ -125,6 +125,7 @@ void CPU::power() {
@ -93,7 +93,7 @@ index f6ae9754..2d7d3432 100755
void CPU::reset() {
diff --git a/snes/smp/core/core.cpp b/snes/smp/core/core.cpp
index 9c94d00a..2fc29be1 100755
index 9c94d00..2fc29be 100755
--- a/snes/smp/core/core.cpp
+++ b/snes/smp/core/core.cpp
@@ -269,4 +269,15 @@ void SMPcore::op_step() {
@ -113,7 +113,7 @@ index 9c94d00a..2fc29be1 100755
+
}
diff --git a/snes/smp/core/core.hpp b/snes/smp/core/core.hpp
index 6adf6f6b..1489fcef 100755
index 6adf6f6..1489fce 100755
--- a/snes/smp/core/core.hpp
+++ b/snes/smp/core/core.hpp
@@ -11,6 +11,8 @@ struct SMPcore {
@ -126,7 +126,7 @@ index 6adf6f6b..1489fcef 100755
string disassemble_opcode(uint16 addr);
diff --git a/snes/smp/smp.cpp b/snes/smp/smp.cpp
index 90806245..d4ccf425 100755
index 9080624..d4ccf42 100755
--- a/snes/smp/smp.cpp
+++ b/snes/smp/smp.cpp
@@ -53,6 +53,7 @@ void SMP::power() {
@ -138,5 +138,5 @@ index 90806245..d4ccf425 100755
void SMP::reset() {
--
2.15.0.rc1
2.0.0

View file

@ -1,7 +1,7 @@
From 6e0364c9a86caa71623a188a720b2d68b304b89b Mon Sep 17 00:00:00 2001
From: Ilari Liusvaara <ilari.liusvaara@elisanet.fi>
Date: Mon, 24 Sep 2012 21:46:09 +0300
Subject: [PATCH 09/27] Add needed support for detecting true polls as opposed
Subject: [PATCH 09/21] Add needed support for detecting true polls as opposed
to just autopolling
---
@ -10,7 +10,7 @@ Subject: [PATCH 09/27] Add needed support for detecting true polls as opposed
2 files changed, 11 insertions(+), 8 deletions(-)
diff --git a/snes/cpu/cpu.hpp b/snes/cpu/cpu.hpp
index 3da865e2..49445773 100755
index 3da865e..4944577 100755
--- a/snes/cpu/cpu.hpp
+++ b/snes/cpu/cpu.hpp
@@ -25,6 +25,7 @@ struct CPU : public Processor, public CPUcore, public PPUcounter {
@ -22,7 +22,7 @@ index 3da865e2..49445773 100755
#include "dma/dma.hpp"
#include "memory/memory.hpp"
diff --git a/snes/cpu/mmio/mmio.cpp b/snes/cpu/mmio/mmio.cpp
index 8b6aaa6a..c5ee930f 100755
index 8b6aaa6..c5ee930 100755
--- a/snes/cpu/mmio/mmio.cpp
+++ b/snes/cpu/mmio/mmio.cpp
@@ -42,6 +42,7 @@ void CPU::mmio_w4016(uint8 data) {
@ -65,5 +65,5 @@ index 8b6aaa6a..c5ee930f 100755
//DMAPx
uint8 CPU::mmio_r43x0(uint8 i) {
--
2.15.0.rc1
2.0.0

View file

@ -1,14 +1,14 @@
From e397bd46f17d6ea00c8c96d5a8e0c5f5b4a6f642 Mon Sep 17 00:00:00 2001
From: Ilari Liusvaara <ilari.liusvaara@elisanet.fi>
Date: Sun, 14 Oct 2012 23:31:36 +0300
Subject: [PATCH 10/27] Fix compiling on GCC 4.7
Subject: [PATCH 10/21] Fix compiling on GCC 4.7
---
nall/string.hpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/nall/string.hpp b/nall/string.hpp
index 1b255ce2..07a64dfc 100755
index 1b255ce..07a64df 100755
--- a/nall/string.hpp
+++ b/nall/string.hpp
@@ -25,8 +25,8 @@
@ -22,5 +22,5 @@ index 1b255ce2..07a64dfc 100755
#include <nall/string/convert.hpp>
#include <nall/string/cstring.hpp>
--
2.15.0.rc1
2.0.0

View file

@ -1,7 +1,7 @@
From e047aa8eb9883f60e4141effba8128a4a555d8be Mon Sep 17 00:00:00 2001
From: Ilari Liusvaara <ilari.liusvaara@elisanet.fi>
Date: Sun, 27 Oct 2013 10:52:45 +0200
Subject: [PATCH 11/27] Support notifying latches
Subject: [PATCH 11/21] Support notifying latches
---
snes/cpu/mmio/mmio.cpp | 1 +
@ -11,7 +11,7 @@ Subject: [PATCH 11/27] Support notifying latches
4 files changed, 8 insertions(+)
diff --git a/snes/cpu/mmio/mmio.cpp b/snes/cpu/mmio/mmio.cpp
index c5ee930f..b7afff00 100755
index c5ee930..b7afff0 100755
--- a/snes/cpu/mmio/mmio.cpp
+++ b/snes/cpu/mmio/mmio.cpp
@@ -33,6 +33,7 @@ void CPU::mmio_w2183(uint8 data) {
@ -23,7 +23,7 @@ index c5ee930f..b7afff00 100755
input.port2->latch(data & 1);
}
diff --git a/snes/cpu/timing/joypad.cpp b/snes/cpu/timing/joypad.cpp
index 179df27d..6a98de00 100755
index 179df27..6a98de0 100755
--- a/snes/cpu/timing/joypad.cpp
+++ b/snes/cpu/timing/joypad.cpp
@@ -9,6 +9,7 @@ void CPU::step_auto_joypad_poll() {
@ -35,7 +35,7 @@ index 179df27d..6a98de00 100755
input.port2->latch(1);
input.port1->latch(0);
diff --git a/snes/interface/interface.cpp b/snes/interface/interface.cpp
index 0a21a132..6685556c 100755
index 0a21a13..6685556 100755
--- a/snes/interface/interface.cpp
+++ b/snes/interface/interface.cpp
@@ -28,4 +28,9 @@ time_t Interface::randomSeed()
@ -49,7 +49,7 @@ index 0a21a132..6685556c 100755
+
}
diff --git a/snes/interface/interface.hpp b/snes/interface/interface.hpp
index 30ee7fde..203f7b0c 100755
index 30ee7fd..203f7b0 100755
--- a/snes/interface/interface.hpp
+++ b/snes/interface/interface.hpp
@@ -7,6 +7,7 @@ struct Interface {
@ -61,5 +61,5 @@ index 30ee7fde..203f7b0c 100755
extern Interface *interface;
--
2.15.0.rc1
2.0.0

View file

@ -1,7 +1,7 @@
From a5b380757b086e3a00b47fe14e2a63c74683e8da Mon Sep 17 00:00:00 2001
From: Ilari Liusvaara <ilari.liusvaara@elisanet.fi>
Date: Thu, 28 Nov 2013 22:36:29 +0200
Subject: [PATCH 12/27] Support unlimited number of breakpoints
Subject: [PATCH 12/21] Support unlimited number of breakpoints
---
snes/alt/cpu/cpu.cpp | 22 +++++++-------
@ -40,7 +40,7 @@ Subject: [PATCH 12/27] Support unlimited number of breakpoints
33 files changed, 166 insertions(+), 70 deletions(-)
diff --git a/snes/alt/cpu/cpu.cpp b/snes/alt/cpu/cpu.cpp
index 814908d0..dcbb92d3 100755
index 814908d..dcbb92d 100755
--- a/snes/alt/cpu/cpu.cpp
+++ b/snes/alt/cpu/cpu.cpp
@@ -89,24 +89,24 @@ void CPU::enable() {
@ -80,7 +80,7 @@ index 814908d0..dcbb92d3 100755
void CPU::power() {
diff --git a/snes/alt/ppu-compatibility/ppu.cpp b/snes/alt/ppu-compatibility/ppu.cpp
index a21e5e31..122b1430 100755
index a21e5e3..122b143 100755
--- a/snes/alt/ppu-compatibility/ppu.cpp
+++ b/snes/alt/ppu-compatibility/ppu.cpp
@@ -126,8 +126,8 @@ void PPU::enable() {
@ -95,7 +95,7 @@ index a21e5e31..122b1430 100755
void PPU::power() {
diff --git a/snes/alt/ppu-parallel/ppu.cpp b/snes/alt/ppu-parallel/ppu.cpp
index 1c3dcb70..8dd118b2 100755
index 1c3dcb7..8dd118b 100755
--- a/snes/alt/ppu-parallel/ppu.cpp
+++ b/snes/alt/ppu-parallel/ppu.cpp
@@ -36,8 +36,8 @@ void PPU::frame() {
@ -110,7 +110,7 @@ index 1c3dcb70..8dd118b2 100755
void PPU::power() {
diff --git a/snes/alt/ppu-performance/ppu.cpp b/snes/alt/ppu-performance/ppu.cpp
index 7c231bc0..4b2b2948 100755
index 7c231bc..4b2b294 100755
--- a/snes/alt/ppu-performance/ppu.cpp
+++ b/snes/alt/ppu-performance/ppu.cpp
@@ -90,8 +90,8 @@ void PPU::enable() {
@ -125,7 +125,7 @@ index 7c231bc0..4b2b2948 100755
void PPU::power() {
diff --git a/snes/cartridge/cartridge.hpp b/snes/cartridge/cartridge.hpp
index 37555bc0..82e73c4c 100755
index 37555bc..82e73c4 100755
--- a/snes/cartridge/cartridge.hpp
+++ b/snes/cartridge/cartridge.hpp
@@ -12,6 +12,22 @@ struct Cartridge : property<Cartridge> {
@ -160,7 +160,7 @@ index 37555bc0..82e73c4c 100755
Mapping();
Mapping(const function<uint8 (unsigned)>&, const function<void (unsigned, uint8)>&);
diff --git a/snes/cartridge/markup.cpp b/snes/cartridge/markup.cpp
index e639fe52..2dd0d646 100755
index e639fe5..2dd0d64 100755
--- a/snes/cartridge/markup.cpp
+++ b/snes/cartridge/markup.cpp
@@ -74,6 +74,7 @@ void Cartridge::parse_markup_rom(XML::Node &root) {
@ -250,7 +250,7 @@ index e639fe52..2dd0d646 100755
write = { &Memory::write, &memory };
mode = Bus::MapMode::Direct;
diff --git a/snes/cheat/cheat.cpp b/snes/cheat/cheat.cpp
index 46c42d1c..3a269cc5 100755
index 46c42d1..3a269cc 100755
--- a/snes/cheat/cheat.cpp
+++ b/snes/cheat/cheat.cpp
@@ -21,9 +21,9 @@ void Cheat::synchronize() {
@ -283,7 +283,7 @@ index 46c42d1c..3a269cc5 100755
}
}
diff --git a/snes/cheat/cheat.hpp b/snes/cheat/cheat.hpp
index 306b99b1..b4d2a42e 100755
index 306b99b..b4d2a42 100755
--- a/snes/cheat/cheat.hpp
+++ b/snes/cheat/cheat.hpp
@@ -1,6 +1,7 @@
@ -295,7 +295,7 @@ index 306b99b1..b4d2a42e 100755
struct Cheat : public linear_vector<CheatCode> {
diff --git a/snes/chip/bsx/satellaview/satellaview.cpp b/snes/chip/bsx/satellaview/satellaview.cpp
index 3c980195..25af8e56 100755
index 3c98019..25af8e5 100755
--- a/snes/chip/bsx/satellaview/satellaview.cpp
+++ b/snes/chip/bsx/satellaview/satellaview.cpp
@@ -6,8 +6,8 @@ void BSXSatellaview::init() {
@ -310,7 +310,7 @@ index 3c980195..25af8e56 100755
void BSXSatellaview::unload() {
diff --git a/snes/chip/hitachidsp/hitachidsp.cpp b/snes/chip/hitachidsp/hitachidsp.cpp
index 1042267e..3e5c5bdb 100755
index 1042267..3e5c5bd 100755
--- a/snes/chip/hitachidsp/hitachidsp.cpp
+++ b/snes/chip/hitachidsp/hitachidsp.cpp
@@ -23,7 +23,7 @@ void HitachiDSP::enter() {
@ -323,7 +323,7 @@ index 1042267e..3e5c5bdb 100755
}
state = State::Idle;
diff --git a/snes/chip/hitachidsp/memory.cpp b/snes/chip/hitachidsp/memory.cpp
index 3c9c3af1..36868e88 100755
index 3c9c3af..36868e8 100755
--- a/snes/chip/hitachidsp/memory.cpp
+++ b/snes/chip/hitachidsp/memory.cpp
@@ -1,7 +1,7 @@
@ -336,7 +336,7 @@ index 3c9c3af1..36868e88 100755
}
diff --git a/snes/chip/nss/nss.cpp b/snes/chip/nss/nss.cpp
index 964973d0..5946af3b 100755
index 964973d..5946af3 100755
--- a/snes/chip/nss/nss.cpp
+++ b/snes/chip/nss/nss.cpp
@@ -10,8 +10,8 @@ void NSS::init() {
@ -351,7 +351,7 @@ index 964973d0..5946af3b 100755
void NSS::unload() {
diff --git a/snes/chip/sa1/memory/memory.cpp b/snes/chip/sa1/memory/memory.cpp
index d13ac929..9bb4ff20 100755
index d13ac92..9bb4ff2 100755
--- a/snes/chip/sa1/memory/memory.cpp
+++ b/snes/chip/sa1/memory/memory.cpp
@@ -107,7 +107,7 @@ void SA1::op_io() {
@ -364,7 +364,7 @@ index d13ac929..9bb4ff20 100755
if(((addr & 0x40e000) == 0x006000) || ((addr & 0xd00000) == 0x400000)) tick();
return bus_read(addr);
diff --git a/snes/chip/sa1/memory/memory.hpp b/snes/chip/sa1/memory/memory.hpp
index ffb9e9f6..ab8e1edd 100755
index ffb9e9f..ab8e1ed 100755
--- a/snes/chip/sa1/memory/memory.hpp
+++ b/snes/chip/sa1/memory/memory.hpp
@@ -3,7 +3,7 @@ void bus_write(unsigned addr, uint8 data);
@ -377,7 +377,7 @@ index ffb9e9f6..ab8e1edd 100755
uint8 mmc_read(unsigned addr);
diff --git a/snes/chip/sa1/sa1.cpp b/snes/chip/sa1/sa1.cpp
index 71c6310a..30e00809 100755
index 71c6310..30e0080 100755
--- a/snes/chip/sa1/sa1.cpp
+++ b/snes/chip/sa1/sa1.cpp
@@ -37,7 +37,7 @@ void SA1::enter() {
@ -390,7 +390,7 @@ index 71c6310a..30e00809 100755
if(!regs.e) op_writestack(regs.pc.b);
op_writestack(regs.pc.h);
diff --git a/snes/chip/sdd1/sdd1.cpp b/snes/chip/sdd1/sdd1.cpp
index c9b8b1c4..5d6cc55f 100755
index c9b8b1c..5d6cc55 100755
--- a/snes/chip/sdd1/sdd1.cpp
+++ b/snes/chip/sdd1/sdd1.cpp
@@ -14,8 +14,8 @@ void SDD1::init() {
@ -405,7 +405,7 @@ index c9b8b1c4..5d6cc55f 100755
void SDD1::unload() {
diff --git a/snes/cpu/core/core.hpp b/snes/cpu/core/core.hpp
index 7a685a8d..9d77f3c5 100755
index 7a685a8..9d77f3c 100755
--- a/snes/cpu/core/core.hpp
+++ b/snes/cpu/core/core.hpp
@@ -10,7 +10,7 @@ struct CPUcore {
@ -418,7 +418,7 @@ index 7a685a8d..9d77f3c5 100755
virtual void last_cycle() = 0;
virtual bool interrupt_pending() = 0;
diff --git a/snes/cpu/core/disassembler/disassembler.cpp b/snes/cpu/core/disassembler/disassembler.cpp
index 030b3ab5..ab8dde24 100755
index 030b3ab..ab8dde2 100755
--- a/snes/cpu/core/disassembler/disassembler.cpp
+++ b/snes/cpu/core/disassembler/disassembler.cpp
@@ -6,7 +6,7 @@ uint8 CPUcore::dreadb(uint32 addr) {
@ -431,7 +431,7 @@ index 030b3ab5..ab8dde24 100755
uint16 CPUcore::dreadw(uint32 addr) {
diff --git a/snes/cpu/core/memory.hpp b/snes/cpu/core/memory.hpp
index 49926578..132501c1 100755
index 4992657..132501c 100755
--- a/snes/cpu/core/memory.hpp
+++ b/snes/cpu/core/memory.hpp
@@ -1,5 +1,5 @@
@ -442,7 +442,7 @@ index 49926578..132501c1 100755
alwaysinline uint8_t op_readstack() {
diff --git a/snes/cpu/cpu.cpp b/snes/cpu/cpu.cpp
index 2d7d3432..39da6b16 100755
index 2d7d343..39da6b1 100755
--- a/snes/cpu/cpu.cpp
+++ b/snes/cpu/cpu.cpp
@@ -78,8 +78,8 @@ void CPU::enter() {
@ -493,7 +493,7 @@ index 2d7d3432..39da6b16 100755
void CPU::power() {
diff --git a/snes/cpu/debugger/debugger.cpp b/snes/cpu/debugger/debugger.cpp
index a33518ed..8301bdb6 100755
index a33518e..8301bdb 100755
--- a/snes/cpu/debugger/debugger.cpp
+++ b/snes/cpu/debugger/debugger.cpp
@@ -19,8 +19,8 @@ void CPUDebugger::op_step() {
@ -508,7 +508,7 @@ index a33518ed..8301bdb6 100755
debugger.breakpoint_test(Debugger::Breakpoint::Source::CPUBus, Debugger::Breakpoint::Mode::Read, addr, data);
return data;
diff --git a/snes/cpu/debugger/debugger.hpp b/snes/cpu/debugger/debugger.hpp
index 579f6f03..c3d66db5 100755
index 579f6f0..c3d66db 100755
--- a/snes/cpu/debugger/debugger.hpp
+++ b/snes/cpu/debugger/debugger.hpp
@@ -16,7 +16,7 @@ public:
@ -521,7 +521,7 @@ index 579f6f03..c3d66db5 100755
CPUDebugger();
diff --git a/snes/cpu/dma/dma.cpp b/snes/cpu/dma/dma.cpp
index e8cdb3ec..0a00bfea 100755
index e8cdb3e..0a00bfe 100755
--- a/snes/cpu/dma/dma.cpp
+++ b/snes/cpu/dma/dma.cpp
@@ -26,7 +26,7 @@ bool CPU::dma_addr_valid(uint32 abus) {
@ -543,7 +543,7 @@ index e8cdb3ec..0a00bfea 100755
dma_write(dma_addr_valid(abus), abus, regs.mdr);
}
diff --git a/snes/cpu/memory/memory.cpp b/snes/cpu/memory/memory.cpp
index c2c8f1fa..31f82c31 100755
index c2c8f1f..31f82c3 100755
--- a/snes/cpu/memory/memory.cpp
+++ b/snes/cpu/memory/memory.cpp
@@ -10,11 +10,11 @@ void CPU::op_io() {
@ -561,7 +561,7 @@ index c2c8f1fa..31f82c31 100755
alu_edge();
return regs.mdr;
diff --git a/snes/cpu/memory/memory.hpp b/snes/cpu/memory/memory.hpp
index d33861d4..fd64ba8b 100755
index d33861d..fd64ba8 100755
--- a/snes/cpu/memory/memory.hpp
+++ b/snes/cpu/memory/memory.hpp
@@ -1,4 +1,4 @@
@ -571,7 +571,7 @@ index d33861d4..fd64ba8b 100755
debugvirtual void op_write(uint32 addr, uint8 data);
alwaysinline unsigned speed(unsigned addr) const;
diff --git a/snes/cpu/mmio/mmio.cpp b/snes/cpu/mmio/mmio.cpp
index b7afff00..30048c19 100755
index b7afff0..30048c1 100755
--- a/snes/cpu/mmio/mmio.cpp
+++ b/snes/cpu/mmio/mmio.cpp
@@ -5,7 +5,7 @@ bool CPU::joylatch() { return status.joypad_strobe_latch; }
@ -584,7 +584,7 @@ index b7afff00..30048c19 100755
//WMDATA
diff --git a/snes/debugger/debugger.cpp b/snes/debugger/debugger.cpp
index b1312339..e8d0f5af 100755
index b131233..e8d0f5a 100755
--- a/snes/debugger/debugger.cpp
+++ b/snes/debugger/debugger.cpp
@@ -33,7 +33,7 @@ uint8 Debugger::read(Debugger::MemorySource source, unsigned addr) {
@ -597,7 +597,7 @@ index b1312339..e8d0f5af 100755
case MemorySource::APUBus: {
diff --git a/snes/memory/memory-inline.hpp b/snes/memory/memory-inline.hpp
index 70503bea..45f150c9 100755
index 70503be..45f150c 100755
--- a/snes/memory/memory-inline.hpp
+++ b/snes/memory/memory-inline.hpp
@@ -51,11 +51,26 @@ MappedRAM::MappedRAM() : data_(0), size_(0), write_protect_(false) {}
@ -631,7 +631,7 @@ index 70503bea..45f150c9 100755
return writer[lookup[addr]](target[addr], data);
}
diff --git a/snes/memory/memory.cpp b/snes/memory/memory.cpp
index ede9cbd0..a9a484a0 100755
index ede9cbd..a9a484a 100755
--- a/snes/memory/memory.cpp
+++ b/snes/memory/memory.cpp
@@ -27,6 +27,7 @@ void Bus::map(
@ -715,7 +715,7 @@ index ede9cbd0..a9a484a0 100755
}
diff --git a/snes/memory/memory.hpp b/snes/memory/memory.hpp
index 634e0717..c20e14db 100755
index 634e071..c20e14d 100755
--- a/snes/memory/memory.hpp
+++ b/snes/memory/memory.hpp
@@ -44,10 +44,13 @@ private:
@ -756,7 +756,7 @@ index 634e0717..c20e14db 100755
~Bus();
};
diff --git a/snes/ppu/ppu.cpp b/snes/ppu/ppu.cpp
index 8545175f..13e231cf 100755
index 8545175..13e231c 100755
--- a/snes/ppu/ppu.cpp
+++ b/snes/ppu/ppu.cpp
@@ -87,8 +87,8 @@ void PPU::enable() {
@ -771,7 +771,7 @@ index 8545175f..13e231cf 100755
void PPU::power() {
diff --git a/snes/smp/core/core.hpp b/snes/smp/core/core.hpp
index 1489fcef..13d69364 100755
index 1489fce..13d6936 100755
--- a/snes/smp/core/core.hpp
+++ b/snes/smp/core/core.hpp
@@ -2,7 +2,7 @@ struct SMPcore {
@ -784,7 +784,7 @@ index 1489fcef..13d69364 100755
#include "registers.hpp"
#include "memory.hpp"
diff --git a/snes/snes.hpp b/snes/snes.hpp
index dffeeee3..37ed1feb 100755
index dffeeee..37ed1fe 100755
--- a/snes/snes.hpp
+++ b/snes/snes.hpp
@@ -1,5 +1,6 @@
@ -795,5 +795,5 @@ index dffeeee3..37ed1feb 100755
namespace SNES {
namespace Info {
--
2.15.0.rc1
2.0.0

View file

@ -1,7 +1,7 @@
From 8bc6bb381e680616dcc843c99889799aedd43163 Mon Sep 17 00:00:00 2001
From: Ilari Liusvaara <ilari.liusvaara@elisanet.fi>
Date: Sat, 30 Nov 2013 10:27:37 +0200
Subject: [PATCH 13/27] Support auto-detecting bsnes version
Subject: [PATCH 13/21] Support auto-detecting bsnes version
---
bsnes.mk | 3 +++
@ -10,7 +10,7 @@ Subject: [PATCH 13/27] Support auto-detecting bsnes version
diff --git a/bsnes.mk b/bsnes.mk
new file mode 100644
index 00000000..20f22f61
index 0000000..20f22f6
--- /dev/null
+++ b/bsnes.mk
@@ -0,0 +1,3 @@
@ -18,5 +18,5 @@ index 00000000..20f22f61
+LIBSNES_DIR=ui-libsnes
+BSNES_VERSION=085
--
2.15.0.rc1
2.0.0

View file

@ -1,7 +1,7 @@
From 40c456dadd79cb2c94379fda8b41a4d0ba051ad1 Mon Sep 17 00:00:00 2001
From: Ilari Liusvaara <ilari.liusvaara@elisanet.fi>
Date: Sat, 7 Dec 2013 23:32:44 +0200
Subject: [PATCH 14/27] Support alternate (more accurate) poll timings
Subject: [PATCH 14/21] Support alternate (more accurate) poll timings
---
snes/config/config.cpp | 1 +
@ -13,7 +13,7 @@ Subject: [PATCH 14/27] Support alternate (more accurate) poll timings
6 files changed, 56 insertions(+), 4 deletions(-)
diff --git a/snes/config/config.cpp b/snes/config/config.cpp
index 701af94c..206daae0 100755
index 701af94..206daae 100755
--- a/snes/config/config.cpp
+++ b/snes/config/config.cpp
@@ -13,6 +13,7 @@ Configuration::Configuration() {
@ -25,7 +25,7 @@ index 701af94c..206daae0 100755
smp.ntsc_frequency = 24607104; //32040.5 * 768
smp.pal_frequency = 24607104;
diff --git a/snes/config/config.hpp b/snes/config/config.hpp
index 1f4d037c..dabde597 100755
index 1f4d037..dabde59 100755
--- a/snes/config/config.hpp
+++ b/snes/config/config.hpp
@@ -10,6 +10,7 @@ struct Configuration {
@ -37,7 +37,7 @@ index 1f4d037c..dabde597 100755
struct SMP {
diff --git a/snes/cpu/timing/joypad.cpp b/snes/cpu/timing/joypad.cpp
index 6a98de00..ae8e94f8 100755
index 6a98de0..ae8e94f 100755
--- a/snes/cpu/timing/joypad.cpp
+++ b/snes/cpu/timing/joypad.cpp
@@ -29,4 +29,44 @@ void CPU::step_auto_joypad_poll() {
@ -86,7 +86,7 @@ index 6a98de00..ae8e94f8 100755
+
#endif
diff --git a/snes/cpu/timing/timing.cpp b/snes/cpu/timing/timing.cpp
index f1378f0c..d7cf24f3 100755
index f1378f0..d7cf24f 100755
--- a/snes/cpu/timing/timing.cpp
+++ b/snes/cpu/timing/timing.cpp
@@ -17,10 +17,18 @@ void CPU::add_clocks(unsigned clocks) {
@ -113,7 +113,7 @@ index f1378f0c..d7cf24f3 100755
if(status.dram_refreshed == false && hcounter() >= status.dram_refresh_position) {
diff --git a/snes/cpu/timing/timing.hpp b/snes/cpu/timing/timing.hpp
index 6c225dab..bf15a727 100755
index 6c225da..bf15a72 100755
--- a/snes/cpu/timing/timing.hpp
+++ b/snes/cpu/timing/timing.hpp
@@ -22,3 +22,4 @@ alwaysinline bool irq_test();
@ -122,7 +122,7 @@ index 6c225dab..bf15a727 100755
void step_auto_joypad_poll();
+void step_auto_joypad_poll_NEW(bool polarity);
diff --git a/snes/snes.hpp b/snes/snes.hpp
index 37ed1feb..4e3ba64c 100755
index 37ed1fe..4e3ba64 100755
--- a/snes/snes.hpp
+++ b/snes/snes.hpp
@@ -1,6 +1,7 @@
@ -134,5 +134,5 @@ index 37ed1feb..4e3ba64c 100755
namespace SNES {
namespace Info {
--
2.15.0.rc1
2.0.0

View file

@ -1,7 +1,7 @@
From 863bde899b53ae31e854096ac5258208c848a293 Mon Sep 17 00:00:00 2001
From: Ilari Liusvaara <ilari.liusvaara@elisanet.fi>
Date: Thu, 6 Mar 2014 21:07:54 +0200
Subject: [PATCH 15/27] Fix mouse speed support
Subject: [PATCH 15/21] Fix mouse speed support
---
snes/config/config.cpp | 1 +
@ -11,7 +11,7 @@ Subject: [PATCH 15/27] Fix mouse speed support
4 files changed, 14 insertions(+), 2 deletions(-)
diff --git a/snes/config/config.cpp b/snes/config/config.cpp
index 206daae0..19831370 100755
index 206daae..1983137 100755
--- a/snes/config/config.cpp
+++ b/snes/config/config.cpp
@@ -8,6 +8,7 @@ Configuration::Configuration() {
@ -23,7 +23,7 @@ index 206daae0..19831370 100755
cpu.version = 2;
cpu.ntsc_frequency = 21477272; //315 / 88 * 6000000
diff --git a/snes/config/config.hpp b/snes/config/config.hpp
index dabde597..68fe0bde 100755
index dabde59..68fe0bd 100755
--- a/snes/config/config.hpp
+++ b/snes/config/config.hpp
@@ -1,9 +1,12 @@
@ -40,7 +40,7 @@ index dabde597..68fe0bde 100755
struct CPU {
unsigned version;
diff --git a/snes/controller/mouse/mouse.cpp b/snes/controller/mouse/mouse.cpp
index 1a066b98..caa7a358 100755
index 1a066b9..caa7a35 100755
--- a/snes/controller/mouse/mouse.cpp
+++ b/snes/controller/mouse/mouse.cpp
@@ -1,6 +1,10 @@
@ -87,7 +87,7 @@ index 1a066b98..caa7a358 100755
#endif
diff --git a/snes/controller/mouse/mouse.hpp b/snes/controller/mouse/mouse.hpp
index b07c8ab7..13a9313e 100755
index b07c8ab..13a9313 100755
--- a/snes/controller/mouse/mouse.hpp
+++ b/snes/controller/mouse/mouse.hpp
@@ -6,6 +6,7 @@ struct Mouse : Controller {
@ -99,5 +99,5 @@ index b07c8ab7..13a9313e 100755
int _position_y;
};
--
2.15.0.rc1
2.0.0

View file

@ -1,14 +1,14 @@
From 60267d1f22fd2ff3197c6c829640f66304c89283 Mon Sep 17 00:00:00 2001
From: Ilari Liusvaara <ilari.liusvaara@elisanet.fi>
Date: Sun, 16 Mar 2014 16:40:55 +0200
Subject: [PATCH 16/27] Fix tracelog of controller registers
Subject: [PATCH 16/21] Fix tracelog of controller registers
---
snes/cpu/core/disassembler/disassembler.cpp | 2 ++
1 file changed, 2 insertions(+)
diff --git a/snes/cpu/core/disassembler/disassembler.cpp b/snes/cpu/core/disassembler/disassembler.cpp
index ab8dde24..624a80ce 100755
index ab8dde2..624a80c 100755
--- a/snes/cpu/core/disassembler/disassembler.cpp
+++ b/snes/cpu/core/disassembler/disassembler.cpp
@@ -1,6 +1,8 @@
@ -21,5 +21,5 @@ index ab8dde24..624a80ce 100755
//$[00-3f|80-bf]:[2000-5fff]
//do not read MMIO registers within debugger
--
2.15.0.rc1
2.0.0

View file

@ -1,7 +1,7 @@
From de71f12eb59a41899a5c77d797e144e6f0919777 Mon Sep 17 00:00:00 2001
From: Ilari Liusvaara <ilari.liusvaara@elisanet.fi>
Date: Mon, 17 Mar 2014 14:22:58 +0200
Subject: [PATCH 17/27] Fix performance problem with non-bus breakpoints
Subject: [PATCH 17/21] Fix performance problem with non-bus breakpoints
---
snes/memory/memory.cpp | 35 ++++++++++++++++++++++++++---------
@ -10,7 +10,7 @@ Subject: [PATCH 17/27] Fix performance problem with non-bus breakpoints
3 files changed, 28 insertions(+), 9 deletions(-)
diff --git a/snes/memory/memory.cpp b/snes/memory/memory.cpp
index a9a484a0..d22e3137 100755
index a9a484a..d22e313 100755
--- a/snes/memory/memory.cpp
+++ b/snes/memory/memory.cpp
@@ -43,6 +43,7 @@ void Bus::map(
@ -77,7 +77,7 @@ index a9a484a0..d22e3137 100755
Bus::Bus() {
diff --git a/snes/memory/memory.hpp b/snes/memory/memory.hpp
index c20e14db..ee0c0a9e 100755
index c20e14d..ee0c0a9 100755
--- a/snes/memory/memory.hpp
+++ b/snes/memory/memory.hpp
@@ -52,6 +52,7 @@ struct Bus {
@ -89,7 +89,7 @@ index c20e14db..ee0c0a9e 100755
unsigned idcount;
function<uint8 (unsigned)> reader[256];
diff --git a/snes/snes.hpp b/snes/snes.hpp
index 4e3ba64c..9589db9b 100755
index 4e3ba64..9589db9 100755
--- a/snes/snes.hpp
+++ b/snes/snes.hpp
@@ -38,6 +38,7 @@ namespace SNES {
@ -101,5 +101,5 @@ index 4e3ba64c..9589db9b 100755
#include <gameboy/gameboy.hpp>
--
2.15.0.rc1
2.0.0

View file

@ -1,7 +1,7 @@
From 6bd069191d29ad70d38c82d59dd72cd0996fc45c Mon Sep 17 00:00:00 2001
From: Ilari Liusvaara <ilari.liusvaara@elisanet.fi>
Date: Mon, 31 Mar 2014 20:17:46 +0300
Subject: [PATCH 18/27] Support VRAM, OAM, CGRAM and APURAM breakpoints
Subject: [PATCH 18/21] Support VRAM, OAM, CGRAM and APURAM breakpoints
---
snes/alt/ppu-compatibility/memory/memory.cpp | 44 +++++++++++++++++++++--
@ -19,7 +19,7 @@ Subject: [PATCH 18/27] Support VRAM, OAM, CGRAM and APURAM breakpoints
12 files changed, 122 insertions(+), 45 deletions(-)
diff --git a/snes/alt/ppu-compatibility/memory/memory.cpp b/snes/alt/ppu-compatibility/memory/memory.cpp
index 3f120d84..e47cf201 100755
index 3f120d8..e47cf20 100755
--- a/snes/alt/ppu-compatibility/memory/memory.cpp
+++ b/snes/alt/ppu-compatibility/memory/memory.cpp
@@ -47,20 +47,31 @@ uint8 PPU::vram_mmio_read(uint16 addr) {
@ -139,7 +139,7 @@ index 3f120d84..e47cf201 100755
}
}
diff --git a/snes/alt/ppu-compatibility/ppu.hpp b/snes/alt/ppu-compatibility/ppu.hpp
index cccaabba..4adac4c4 100755
index cccaabb..4adac4c 100755
--- a/snes/alt/ppu-compatibility/ppu.hpp
+++ b/snes/alt/ppu-compatibility/ppu.hpp
@@ -3,6 +3,12 @@ public:
@ -156,7 +156,7 @@ index cccaabba..4adac4c4 100755
enum : bool { Threaded = true };
alwaysinline void step(unsigned clocks);
diff --git a/snes/cartridge/cartridge.hpp b/snes/cartridge/cartridge.hpp
index 82e73c4c..2358c088 100755
index 82e73c4..2358c08 100755
--- a/snes/cartridge/cartridge.hpp
+++ b/snes/cartridge/cartridge.hpp
@@ -26,6 +26,10 @@ struct Cartridge : property<Cartridge> {
@ -171,7 +171,7 @@ index 82e73c4c..2358c088 100755
enum class Slot : unsigned {
diff --git a/snes/smp/core/core.hpp b/snes/smp/core/core.hpp
index 13d69364..03f9ac66 100755
index 13d6936..03f9ac6 100755
--- a/snes/smp/core/core.hpp
+++ b/snes/smp/core/core.hpp
@@ -1,6 +1,6 @@
@ -183,7 +183,7 @@ index 13d69364..03f9ac66 100755
virtual void op_step();
diff --git a/snes/smp/core/memory.hpp b/snes/smp/core/memory.hpp
index c4b6d99f..c297962f 100755
index c4b6d99..c297962 100755
--- a/snes/smp/core/memory.hpp
+++ b/snes/smp/core/memory.hpp
@@ -1,9 +1,9 @@
@ -208,7 +208,7 @@ index c4b6d99f..c297962f 100755
alwaysinline void op_writedp(uint8 addr, uint8 data) {
diff --git a/snes/smp/core/opcodes.cpp b/snes/smp/core/opcodes.cpp
index 95b9844f..43db081d 100755
index 95b9844..43db081 100755
--- a/snes/smp/core/opcodes.cpp
+++ b/snes/smp/core/opcodes.cpp
@@ -11,7 +11,7 @@ template<uint8 (SMPcore::*op)(uint8)>
@ -348,7 +348,7 @@ index 95b9844f..43db081d 100755
}
diff --git a/snes/smp/debugger/debugger.cpp b/snes/smp/debugger/debugger.cpp
index 9546c118..894fdac9 100755
index 9546c11..894fdac 100755
--- a/snes/smp/debugger/debugger.cpp
+++ b/snes/smp/debugger/debugger.cpp
@@ -18,8 +18,8 @@ void SMPDebugger::op_step() {
@ -363,7 +363,7 @@ index 9546c118..894fdac9 100755
debugger.breakpoint_test(Debugger::Breakpoint::Source::APURAM, Debugger::Breakpoint::Mode::Read, addr, data);
return data;
diff --git a/snes/smp/debugger/debugger.hpp b/snes/smp/debugger/debugger.hpp
index d5d28e53..26bc7af9 100755
index d5d28e5..26bc7af 100755
--- a/snes/smp/debugger/debugger.hpp
+++ b/snes/smp/debugger/debugger.hpp
@@ -14,7 +14,7 @@ public:
@ -376,7 +376,7 @@ index d5d28e53..26bc7af9 100755
SMPDebugger();
diff --git a/snes/smp/memory/memory.cpp b/snes/smp/memory/memory.cpp
index 391324c4..58c11915 100755
index 391324c..58c1191 100755
--- a/snes/smp/memory/memory.cpp
+++ b/snes/smp/memory/memory.cpp
@@ -19,61 +19,83 @@ void SMP::port_write(uint2 port, uint8 data) {
@ -490,7 +490,7 @@ index 391324c4..58c11915 100755
cycle_edge();
return r;
diff --git a/snes/smp/memory/memory.hpp b/snes/smp/memory/memory.hpp
index 1a07445d..faa28daa 100755
index 1a07445..faa28da 100755
--- a/snes/smp/memory/memory.hpp
+++ b/snes/smp/memory/memory.hpp
@@ -1,9 +1,9 @@
@ -506,7 +506,7 @@ index 1a07445d..faa28daa 100755
+debugvirtual uint8 op_read(uint16 addr, bool exec);
debugvirtual void op_write(uint16 addr, uint8 data);
diff --git a/snes/smp/smp.hpp b/snes/smp/smp.hpp
index 6b387cba..6b6ae837 100755
index 6b387cb..6b6ae83 100755
--- a/snes/smp/smp.hpp
+++ b/snes/smp/smp.hpp
@@ -1,6 +1,10 @@
@ -521,7 +521,7 @@ index 6b387cba..6b6ae837 100755
enum : bool { Threaded = true };
alwaysinline void step(unsigned clocks);
diff --git a/snes/snes.hpp b/snes/snes.hpp
index 9589db9b..27632bff 100755
index 9589db9..27632bf 100755
--- a/snes/snes.hpp
+++ b/snes/snes.hpp
@@ -1,6 +1,7 @@
@ -533,5 +533,5 @@ index 9589db9b..27632bff 100755
namespace SNES {
--
2.15.0.rc1
2.0.0

View file

@ -1,7 +1,7 @@
From f1106d3dffd27dab526a703aa434512495fbacea Mon Sep 17 00:00:00 2001
From: Ilari Liusvaara <ilari.liusvaara@elisanet.fi>
Date: Mon, 14 Apr 2014 21:21:36 +0300
Subject: [PATCH 19/27] SA1 trace hook support
Subject: [PATCH 19/21] SA1 trace hook support
---
snes/chip/sa1/sa1.cpp | 2 ++
@ -10,7 +10,7 @@ Subject: [PATCH 19/27] SA1 trace hook support
3 files changed, 6 insertions(+)
diff --git a/snes/chip/sa1/sa1.cpp b/snes/chip/sa1/sa1.cpp
index 30e00809..fdec362c 100755
index 30e0080..fdec362 100755
--- a/snes/chip/sa1/sa1.cpp
+++ b/snes/chip/sa1/sa1.cpp
@@ -32,6 +32,8 @@ void SA1::enter() {
@ -23,7 +23,7 @@ index 30e00809..fdec362c 100755
}
}
diff --git a/snes/chip/sa1/sa1.hpp b/snes/chip/sa1/sa1.hpp
index 732b2a85..efd36376 100755
index 732b2a8..efd3637 100755
--- a/snes/chip/sa1/sa1.hpp
+++ b/snes/chip/sa1/sa1.hpp
@@ -15,6 +15,9 @@ public:
@ -37,7 +37,7 @@ index 732b2a85..efd36376 100755
void enter();
void tick();
diff --git a/snes/snes.hpp b/snes/snes.hpp
index 27632bff..3bdca7e5 100755
index 27632bf..3bdca7e 100755
--- a/snes/snes.hpp
+++ b/snes/snes.hpp
@@ -3,6 +3,7 @@
@ -49,5 +49,5 @@ index 27632bff..3bdca7e5 100755
namespace SNES {
namespace Info {
--
2.15.0.rc1
2.0.0

View file

@ -1,14 +1,14 @@
From cf662a12578778cb50c25d5275ce58deabd7eabe Mon Sep 17 00:00:00 2001
From: Ilari Liusvaara <ilari.liusvaara@elisanet.fi>
Date: Wed, 30 Apr 2014 00:18:58 +0300
Subject: [PATCH 20/27] Fixes to SA1 open bus emulation
Subject: [PATCH 20/21] Fixes to SA1 open bus emulation
---
snes/chip/sa1/memory/memory.cpp | 19 +++++++++++--------
1 file changed, 11 insertions(+), 8 deletions(-)
diff --git a/snes/chip/sa1/memory/memory.cpp b/snes/chip/sa1/memory/memory.cpp
index 9bb4ff20..614dfb0c 100755
index 9bb4ff2..614dfb0 100755
--- a/snes/chip/sa1/memory/memory.cpp
+++ b/snes/chip/sa1/memory/memory.cpp
@@ -36,6 +36,7 @@ uint8 SA1::bus_read(unsigned addr) {
@ -74,5 +74,5 @@ index 9bb4ff20..614dfb0c 100755
uint8 SA1::mmc_read(unsigned addr) {
--
2.15.0.rc1
2.0.0

View file

@ -1,7 +1,7 @@
From 63fc77b07d517c2f9a0fd6ca3fa94f30fb0f5ec2 Mon Sep 17 00:00:00 2001
From: Ilari Liusvaara <ilari.liusvaara@elisanet.fi>
Date: Sun, 15 Jun 2014 22:01:26 +0300
Subject: [PATCH 21/27] Call notify latch function on alternate timings mode
Subject: [PATCH 21/21] Call notify latch function on alternate timings mode
too
---
@ -9,7 +9,7 @@ Subject: [PATCH 21/27] Call notify latch function on alternate timings mode
1 file changed, 1 insertion(+)
diff --git a/snes/cpu/timing/joypad.cpp b/snes/cpu/timing/joypad.cpp
index ae8e94f8..3fd4d23e 100755
index ae8e94f..3fd4d23 100755
--- a/snes/cpu/timing/joypad.cpp
+++ b/snes/cpu/timing/joypad.cpp
@@ -41,6 +41,7 @@ void CPU::step_auto_joypad_poll_NEW(bool polarity) {
@ -21,5 +21,5 @@ index ae8e94f8..3fd4d23e 100755
input.port2->latch(1);
}
--
2.15.0.rc1
2.0.0

View file

@ -1,288 +0,0 @@
From 5bc96b8aeea26729ef4399c2d8d5e562894616e1 Mon Sep 17 00:00:00 2001
From: Ilari Liusvaara <ilari.liusvaara@elisanet.fi>
Date: Tue, 20 Jan 2015 10:04:58 +0200
Subject: [PATCH 22/27] Support DMA tracing
---
snes/alt/ppu-compatibility/mmio/mmio.cpp | 18 +++++++
snes/alt/ppu-compatibility/ppu.cpp | 1 +
snes/alt/ppu-compatibility/ppu.hpp | 4 ++
snes/cpu/cpu.cpp | 1 +
snes/cpu/cpu.hpp | 1 +
snes/cpu/dma/dma.cpp | 84 ++++++++++++++++++++++++++++++++
snes/cpu/dma/dma.hpp | 5 ++
snes/ppu/mmio/mmio.cpp | 18 +++++++
snes/ppu/ppu.cpp | 1 +
snes/ppu/ppu.hpp | 3 ++
snes/snes.hpp | 1 +
11 files changed, 137 insertions(+)
diff --git a/snes/alt/ppu-compatibility/mmio/mmio.cpp b/snes/alt/ppu-compatibility/mmio/mmio.cpp
index aedb67c1..0a269cc0 100755
--- a/snes/alt/ppu-compatibility/mmio/mmio.cpp
+++ b/snes/alt/ppu-compatibility/mmio/mmio.cpp
@@ -1,5 +1,23 @@
#ifdef PPU_CPP
+size_t PPU::get_dma_oam_subaddr(char* buf)
+{
+ return sprintf(buf, "[%03x]", regs.oam_addr);
+}
+
+size_t PPU::get_dma_cgram_subaddr(char* buf)
+{
+ return sprintf(buf, "[%02x%c]", regs.cgram_addr >> 1, (regs.cgram_addr & 1) ?
+ 'H' : 'L');
+}
+
+size_t PPU::get_dma_vram_subaddr(char* buf)
+{
+ return sprintf(buf, "[%04x map%d inc %d on %s]", regs.vram_addr << 1,
+ regs.vram_mapping, 2 * regs.vram_incsize, regs.vram_incmode ? "high" :
+ "low");
+}
+
//INIDISP
void PPU::mmio_w2100(uint8 value) {
if(regs.display_disabled == true && cpu.vcounter() == (!overscan() ? 225 : 240)) {
diff --git a/snes/alt/ppu-compatibility/ppu.cpp b/snes/alt/ppu-compatibility/ppu.cpp
index 122b1430..ac886edc 100755
--- a/snes/alt/ppu-compatibility/ppu.cpp
+++ b/snes/alt/ppu-compatibility/ppu.cpp
@@ -1,4 +1,5 @@
#include <snes/snes.hpp>
+#include <cstdio>
#define PPU_CPP
namespace SNES {
diff --git a/snes/alt/ppu-compatibility/ppu.hpp b/snes/alt/ppu-compatibility/ppu.hpp
index 4adac4c4..b0eabf7c 100755
--- a/snes/alt/ppu-compatibility/ppu.hpp
+++ b/snes/alt/ppu-compatibility/ppu.hpp
@@ -14,6 +14,10 @@ public:
alwaysinline void step(unsigned clocks);
alwaysinline void synchronize_cpu();
+ size_t get_dma_oam_subaddr(char* buf);
+ size_t get_dma_cgram_subaddr(char* buf);
+ size_t get_dma_vram_subaddr(char* buf);
+
#include "memory/memory.hpp"
#include "mmio/mmio.hpp"
#include "render/render.hpp"
diff --git a/snes/cpu/cpu.cpp b/snes/cpu/cpu.cpp
index 39da6b16..ce112afa 100755
--- a/snes/cpu/cpu.cpp
+++ b/snes/cpu/cpu.cpp
@@ -1,4 +1,5 @@
#include <snes/snes.hpp>
+#include <cstdio>
#define CPU_CPP
namespace SNES {
diff --git a/snes/cpu/cpu.hpp b/snes/cpu/cpu.hpp
index 49445773..fd665b1f 100755
--- a/snes/cpu/cpu.hpp
+++ b/snes/cpu/cpu.hpp
@@ -26,6 +26,7 @@ struct CPU : public Processor, public CPUcore, public PPUcounter {
~CPU();
bool controller_flag;
+ function<void(const char*)> dma_trace_fn;
private:
#include "dma/dma.hpp"
#include "memory/memory.hpp"
diff --git a/snes/cpu/dma/dma.cpp b/snes/cpu/dma/dma.cpp
index 0a00bfea..8f7be263 100755
--- a/snes/cpu/dma/dma.cpp
+++ b/snes/cpu/dma/dma.cpp
@@ -144,6 +144,7 @@ void CPU::dma_run() {
for(unsigned i = 0; i < 8; i++) {
if(channel[i].dma_enabled == false) continue;
+ dma_trace_start(i);
unsigned index = 0;
do {
@@ -155,6 +156,7 @@ void CPU::dma_run() {
dma_write(false);
dma_edge();
+ dma_trace_end(i);
channel[i].dma_enabled = false;
}
@@ -202,6 +204,7 @@ void CPU::hdma_run() {
channel[i].dma_enabled = false; //HDMA run during DMA will stop DMA mid-transfer
if(channel[i].hdma_do_transfer) {
+ dma_trace_hdma(i);
static const unsigned transfer_length[8] = { 1, 2, 2, 4, 4, 4, 2, 4 };
unsigned length = transfer_length[channel[i].transfer_mode];
for(unsigned index = 0; index < length; index++) {
@@ -286,4 +289,85 @@ void CPU::dma_reset() {
pipe.data = 0;
}
+size_t CPU::dma_trace_subaddr(char* buf, uint8 b_addr)
+{
+ if(b_addr == 0x04 || b_addr == 0x38) {
+ return ppu.get_dma_oam_subaddr(buf);
+ }
+ if(b_addr == 0x22 || b_addr == 0x3B) {
+ return ppu.get_dma_cgram_subaddr(buf);
+ }
+ if(b_addr == 0x18 || b_addr == 0x19 || b_addr == 0x39 || b_addr == 0x3A) {
+ return ppu.get_dma_vram_subaddr(buf);
+ }
+ if(b_addr == 0x80) {
+ return sprintf(buf, "[%06x]", 0x7e0000 | status.wram_addr);
+ }
+ return 0;
+}
+
+void CPU::dma_trace_start(unsigned i)
+{
+ if(!dma_trace_fn) return;
+ char buf[512];
+ size_t ptr = 0;
+ unsigned bytes = channel[i].transfer_size;
+ if(!bytes) bytes = 0x10000;
+ ptr += sprintf(buf + ptr, "-- DMA%i %d(%x) bytes ", i, bytes, bytes);
+ if(channel[i].direction) {
+ //B->A
+ ptr += sprintf(buf + ptr, "%02x", channel[i].dest_addr);
+ ptr += dma_trace_subaddr(buf + ptr, channel[i].dest_addr);
+ ptr += sprintf(buf + ptr, "-> %02x%04x", channel[i].source_bank,
+ channel[i].source_addr);
+ } else {
+ //A->B
+ ptr += sprintf(buf + ptr, "%02x%04x -> %02x", channel[i].source_bank,
+ channel[i].source_addr, channel[i].dest_addr);
+ ptr += dma_trace_subaddr(buf + ptr, channel[i].dest_addr);
+ }
+ if(channel[i].fixed_transfer)
+ ptr += sprintf(buf + ptr, " fixed");
+ else if(channel[i].reverse_transfer)
+ ptr += sprintf(buf + ptr, " decrement");
+ else
+ ptr += sprintf(buf + ptr, " incrment");
+ ptr += sprintf(buf + ptr, " mode%d --", channel[i].transfer_mode);
+ dma_trace_fn(buf);
+}
+
+void CPU::dma_trace_end(unsigned i)
+{
+ if(!dma_trace_fn) return;
+ if(!channel[i].transfer_size) return; //No message for complete DMA.
+ char buf[512];
+ size_t ptr = 0;
+ sprintf(buf, "-- DMA%i aborted with %d(0x%x) bytes remaining --", i,
+ (int)channel[i].transfer_size, (unsigned)channel[i].transfer_size);
+ dma_trace_fn(buf);
+}
+
+void CPU::dma_trace_hdma(unsigned i)
+{
+ if(!dma_trace_fn) return;
+ char buf[512];
+ size_t ptr = 0;
+ unsigned addr = channel[i].indirect ?
+ (channel[i].indirect_bank << 16) | (channel[i].indirect_addr) :
+ (channel[i].source_bank << 16) | (channel[i].hdma_addr);
+ ptr += sprintf(buf + ptr, "-- HDMA%i %06x -> %02x", i, addr,
+ channel[i].dest_addr);
+ ptr += dma_trace_subaddr(buf + ptr, channel[i].dest_addr);
+ if(channel[i].indirect)
+ ptr += sprintf(buf + ptr, " indirect");
+ if(channel[i].fixed_transfer)
+ ptr += sprintf(buf + ptr, " fixed");
+ else if(channel[i].reverse_transfer)
+ ptr += sprintf(buf + ptr, " decrement");
+ else
+ ptr += sprintf(buf + ptr, " incrment");
+ ptr += sprintf(buf + ptr, " mode%d --", channel[i].transfer_mode);
+ dma_trace_fn(buf);
+}
+
#endif
diff --git a/snes/cpu/dma/dma.hpp b/snes/cpu/dma/dma.hpp
index 33755bde..8740bb3a 100755
--- a/snes/cpu/dma/dma.hpp
+++ b/snes/cpu/dma/dma.hpp
@@ -77,3 +77,8 @@ void hdma_init();
void dma_power();
void dma_reset();
+
+size_t dma_trace_subaddr(char* buf, uint8 b_addr);
+void dma_trace_start(unsigned i);
+void dma_trace_end(unsigned i);
+void dma_trace_hdma(unsigned i);
diff --git a/snes/ppu/mmio/mmio.cpp b/snes/ppu/mmio/mmio.cpp
index 302f74f8..4a4fb9ce 100755
--- a/snes/ppu/mmio/mmio.cpp
+++ b/snes/ppu/mmio/mmio.cpp
@@ -1,5 +1,23 @@
#ifdef PPU_CPP
+size_t PPU::get_dma_oam_subaddr(char* buf)
+{
+ return sprintf(buf, "[%03x]", regs.oam_addr);
+}
+
+size_t PPU::get_dma_cgram_subaddr(char* buf)
+{
+ return sprintf(buf, "[%02x%c]", regs.cgram_addr >> 1, (regs.cgram_addr & 1) ?
+ 'H' : 'L');
+}
+
+size_t PPU::get_dma_vram_subaddr(char* buf)
+{
+ return sprintf(buf, "[%04x map%d inc %d on %s]", regs.vram_addr << 1,
+ regs.vram_mapping, 2 * regs.vram_incsize, regs.vram_incmode ? "high" :
+ "low");
+}
+
bool PPU::interlace() const {
return display.interlace;
}
diff --git a/snes/ppu/ppu.cpp b/snes/ppu/ppu.cpp
index 13e231cf..58742098 100755
--- a/snes/ppu/ppu.cpp
+++ b/snes/ppu/ppu.cpp
@@ -1,4 +1,5 @@
#include <snes/snes.hpp>
+#include <cstdio>
#define PPU_CPP
namespace SNES {
diff --git a/snes/ppu/ppu.hpp b/snes/ppu/ppu.hpp
index fdba113c..0addb775 100755
--- a/snes/ppu/ppu.hpp
+++ b/snes/ppu/ppu.hpp
@@ -21,6 +21,9 @@ struct PPU : public Processor, public PPUcounter {
PPU();
~PPU();
+ size_t get_dma_oam_subaddr(char* buf);
+ size_t get_dma_cgram_subaddr(char* buf);
+ size_t get_dma_vram_subaddr(char* buf);
private:
uint32 *surface;
uint32 *output;
diff --git a/snes/snes.hpp b/snes/snes.hpp
index 3bdca7e5..7c48ebb3 100755
--- a/snes/snes.hpp
+++ b/snes/snes.hpp
@@ -4,6 +4,7 @@
#define BSNES_SUPPORTS_ADV_BREAKPOINTS_PPU
#define BSNES_SUPPORTS_ALT_TIMINGS
#define BSNES_SUPPORTS_TRACE_SA1
+#define BSNES_SUPPORTS_DMA_TRACE
namespace SNES {
namespace Info {
--
2.15.0.rc1

View file

@ -1,86 +0,0 @@
From 9682df9e33c366dfe047a99c8bcefc2c8ab29620 Mon Sep 17 00:00:00 2001
From: Ilari Liusvaara <ilari.liusvaara@elisanet.fi>
Date: Sat, 24 Jan 2015 16:46:18 +0200
Subject: [PATCH 23/27] Add autopoller and IRQ/NMI tracing
---
snes/cpu/cpu.cpp | 3 +++
snes/cpu/timing/joypad.cpp | 16 ++++++++++++++--
2 files changed, 17 insertions(+), 2 deletions(-)
diff --git a/snes/cpu/cpu.cpp b/snes/cpu/cpu.cpp
index ce112afa..e11fc882 100755
--- a/snes/cpu/cpu.cpp
+++ b/snes/cpu/cpu.cpp
@@ -69,14 +69,17 @@ void CPU::enter() {
if(status.interrupt_pending) {
status.interrupt_pending = false;
if(status.nmi_pending) {
+ if(dma_trace_fn) dma_trace_fn("-- NMI occured --");
status.nmi_pending = false;
regs.vector = (regs.e == false ? 0xffea : 0xfffa);
op_irq();
} else if(status.irq_pending) {
+ if(dma_trace_fn) dma_trace_fn("-- IRQ occured --");
status.irq_pending = false;
regs.vector = (regs.e == false ? 0xffee : 0xfffe);
op_irq();
} else if(status.reset_pending) {
+ if(dma_trace_fn) dma_trace_fn("-- RESET occured --");
status.reset_pending = false;
add_clocks(186);
regs.pc.l = bus.read(0xfffc, false);
diff --git a/snes/cpu/timing/joypad.cpp b/snes/cpu/timing/joypad.cpp
index 3fd4d23e..afca7504 100755
--- a/snes/cpu/timing/joypad.cpp
+++ b/snes/cpu/timing/joypad.cpp
@@ -6,9 +6,9 @@ void CPU::step_auto_joypad_poll() {
//cache enable state at first iteration
if(status.auto_joypad_counter == 0) status.auto_joypad_latch = status.auto_joypad_poll;
status.auto_joypad_active = status.auto_joypad_counter <= 15;
-
if(status.auto_joypad_active && status.auto_joypad_latch) {
if(status.auto_joypad_counter == 0) {
+ if(dma_trace_fn) dma_trace_fn("-- Start automatic polling --");
interface->notifyLatched();
input.port1->latch(1);
input.port2->latch(1);
@@ -23,6 +23,12 @@ void CPU::step_auto_joypad_poll() {
status.joy2 = (status.joy2 << 1) | (bool)(port1 & 1);
status.joy3 = (status.joy3 << 1) | (bool)(port0 & 2);
status.joy4 = (status.joy4 << 1) | (bool)(port1 & 2);
+ if(status.auto_joypad_counter == 15) {
+ char buf[512];
+ sprintf(buf, "-- End automatic polling [%04x %04x %04x %04x] --",
+ status.joy1, status.joy2, status.joy3, status.joy4);
+ if(dma_trace_fn) dma_trace_fn(buf);
+ }
}
status.auto_joypad_counter++;
@@ -40,6 +46,7 @@ void CPU::step_auto_joypad_poll_NEW(bool polarity) {
status.auto_joypad_active = false;
} else {
if(status.auto_joypad_counter == 1) {
+ if(dma_trace_fn) dma_trace_fn("-- Start automatic polling --");
status.auto_joypad_active = true;
interface->notifyLatched();
input.port1->latch(1);
@@ -58,8 +65,13 @@ void CPU::step_auto_joypad_poll_NEW(bool polarity) {
status.joy3 = (status.joy3 << 1) | (bool)(port0 & 2);
status.joy4 = (status.joy4 << 1) | (bool)(port1 & 2);
}
- if(status.auto_joypad_counter == 34)
+ if(status.auto_joypad_counter == 34) {
status.auto_joypad_active = false;
+ char buf[512];
+ sprintf(buf, "-- End automatic polling [%04x %04x %04x %04x] --",
+ status.joy1, status.joy2, status.joy3, status.joy4);
+ if(dma_trace_fn) dma_trace_fn(buf);
+ }
}
status.auto_joypad_counter++;
}
--
2.15.0.rc1

View file

@ -1,50 +0,0 @@
From f2bbef8a4e12e05190a68dfe410cff3e4b1eb13f Mon Sep 17 00:00:00 2001
From: Ilari Liusvaara <ilari.liusvaara@elisanet.fi>
Date: Sat, 8 Aug 2015 11:09:41 +0300
Subject: [PATCH 24/27] Build fixes for GCC 5.X
---
nall/bit.hpp | 21 +++++++++++++++------
1 file changed, 15 insertions(+), 6 deletions(-)
diff --git a/nall/bit.hpp b/nall/bit.hpp
index 67a35ad6..11d9d8de 100755
--- a/nall/bit.hpp
+++ b/nall/bit.hpp
@@ -8,18 +8,27 @@ namespace nall {
}
template<int bits> constexpr inline unsigned uclip(const unsigned x) {
- enum { m = (1U << (bits - 1)) + ((1U << (bits - 1)) - 1) };
- return (x & m);
+ return x & ((1U << (bits - 1)) + ((1U << (bits - 1)) - 1));
+ }
+
+ template<int bits> constexpr inline signed sclamp_b() {
+ return 1U << (bits - 1);
+ }
+
+ template<int bits> constexpr inline signed sclamp_m() {
+ return (1U << (bits - 1)) - 1;
}
template<int bits> constexpr inline signed sclamp(const signed x) {
- enum { b = 1U << (bits - 1), m = (1U << (bits - 1)) - 1 };
- return (x > m) ? m : (x < -b) ? -b : x;
+ return (x > sclamp_m<bits>()) ? sclamp_m<bits>() : (x < -sclamp_b<bits>()) ? -sclamp_b<bits>() : x;
+ }
+
+ template<int bits> constexpr inline signed sclip_m() {
+ return (1U << (bits)) - 1;
}
template<int bits> constexpr inline signed sclip(const signed x) {
- enum { b = 1U << (bits - 1), m = (1U << bits) - 1 };
- return ((x & m) ^ b) - b;
+ return ((x & sclip_m<bits>()) ^ sclamp_b<bits>()) - sclamp_b<bits>();
}
namespace bit {
--
2.15.0.rc1

View file

@ -1,26 +0,0 @@
From d39571de650d49636778a73c66414aff372c08af Mon Sep 17 00:00:00 2001
From: Ilari Liusvaara <ilari.liusvaara@elisanet.fi>
Date: Mon, 7 Sep 2015 20:48:14 +0300
Subject: [PATCH 25/27] Fix MSU-1 bug where write to MSU1BASE+4 is mirred to
MSUBASE+5
---
snes/chip/msu1/msu1.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/snes/chip/msu1/msu1.cpp b/snes/chip/msu1/msu1.cpp
index 71700e60..ec1cf46a 100755
--- a/snes/chip/msu1/msu1.cpp
+++ b/snes/chip/msu1/msu1.cpp
@@ -107,7 +107,7 @@ void MSU1::mmio_write(unsigned addr, uint8 data) {
if(datafile.open()) datafile.seek(mmio.data_offset);
mmio.data_busy = false;
break;
- case 4: mmio.audio_track = (mmio.audio_track & 0xff00) | (data << 0);
+ case 4: mmio.audio_track = (mmio.audio_track & 0xff00) | (data << 0); break;
case 5: mmio.audio_track = (mmio.audio_track & 0x00ff) | (data << 8);
if(audiofile.open()) audiofile.close();
if(audiofile.open(interface->path(Cartridge::Slot::Base, { "-", (unsigned)mmio.audio_track, ".pcm" }), file::mode::read)) {
--
2.15.0.rc1

View file

@ -1,25 +0,0 @@
From c0a2270cfd5f56e8a311b36011e1f15fac6c54ca Mon Sep 17 00:00:00 2001
From: Ilari Liusvaara <ilariliusvaara@welho.com>
Date: Tue, 9 Aug 2016 18:54:57 +0300
Subject: [PATCH 26/27] Add <vector> to avoid compile error due to missing
std::vector
---
snes/snes.hpp | 1 +
1 file changed, 1 insertion(+)
diff --git a/snes/snes.hpp b/snes/snes.hpp
index 7c48ebb3..3a65e360 100755
--- a/snes/snes.hpp
+++ b/snes/snes.hpp
@@ -22,6 +22,7 @@ namespace SNES {
#include <libco/libco.h>
+#include <vector>
#include <nall/platform.hpp>
#include <nall/algorithm.hpp>
#include <nall/any.hpp>
--
2.15.0.rc1

View file

@ -1,377 +0,0 @@
From 4cfbbeadc3abe3e3911f7f59ce57b715edc76563 Mon Sep 17 00:00:00 2001
From: Ilari Liusvaara <ilariliusvaara@welho.com>
Date: Wed, 25 Oct 2017 14:18:34 +0300
Subject: [PATCH 27/27] Bus fixes: Do not update MDR on read from CPU MMIO
space
Also, updates the controller read timings to be more accurate.
---
snes/config/config.cpp | 1 +
snes/config/config.hpp | 1 +
snes/cpu/cpu.cpp | 2 +
snes/cpu/memory/memory.cpp | 26 ++++++++-
snes/cpu/mmio/mmio.cpp | 14 +++--
snes/cpu/timing/joypad.cpp | 132 +++++++++++++++++++++++++++++++++++++++------
snes/cpu/timing/timing.cpp | 11 ++--
snes/cpu/timing/timing.hpp | 3 +-
snes/snes.hpp | 1 +
9 files changed, 166 insertions(+), 25 deletions(-)
diff --git a/snes/config/config.cpp b/snes/config/config.cpp
index 19831370..8dcfd7e8 100755
--- a/snes/config/config.cpp
+++ b/snes/config/config.cpp
@@ -15,6 +15,7 @@ Configuration::Configuration() {
cpu.pal_frequency = 21281370;
cpu.wram_init_value = 0x55;
cpu.alt_poll_timings = false;
+ cpu.bus_fixes = false;
smp.ntsc_frequency = 24607104; //32040.5 * 768
smp.pal_frequency = 24607104;
diff --git a/snes/config/config.hpp b/snes/config/config.hpp
index 68fe0bde..d8577e39 100755
--- a/snes/config/config.hpp
+++ b/snes/config/config.hpp
@@ -14,6 +14,7 @@ struct Configuration {
unsigned pal_frequency;
unsigned wram_init_value;
bool alt_poll_timings;
+ bool bus_fixes;
} cpu;
struct SMP {
diff --git a/snes/cpu/cpu.cpp b/snes/cpu/cpu.cpp
index e11fc882..5e8e3137 100755
--- a/snes/cpu/cpu.cpp
+++ b/snes/cpu/cpu.cpp
@@ -1,5 +1,7 @@
#include <snes/snes.hpp>
#include <cstdio>
+#include <iostream>
+#include <cassert>
#define CPU_CPP
namespace SNES {
diff --git a/snes/cpu/memory/memory.cpp b/snes/cpu/memory/memory.cpp
index 31f82c31..df439c22 100755
--- a/snes/cpu/memory/memory.cpp
+++ b/snes/cpu/memory/memory.cpp
@@ -14,10 +14,32 @@ uint8 CPU::op_read(uint32 addr, bool exec) {
status.clock_count = speed(addr);
dma_edge();
add_clocks(status.clock_count - 4);
- regs.mdr = bus.read(addr, exec);
+ //MDR presents the state held by parasitic capacitance of the external bus.
+ //This bus is not affected by reads from CPU-internal registers, only if
+ //some external device responds. SDD1 does hook some of these addresses, but
+ //passes read straight through, as expected (as the CPU probably won't
+ //monitor if external device responds, even if it broadcasts a read).
+ //
+ //We use 4000-43FF as CPU register range, and not 4000-437F it likely is
+ //for quickness of checking. This will only affect things if some device
+ //tries to map the 4380-43FF range (that device will still work correctly,
+ //but openbus in that range won't).
+ //
+ //This was discovered while investigating why one Super Metroid glitch
+ //worked on emulator but crashed on real console.
+ //
+ //a word fetch from 2f4017 AND 0xfffc results in 2f3c and a word fetch from
+ //2f4210 AND 0x7f7f results in 2f22. This also extends to long fetches
+ //by arguments. E.g. long argument fetch from 94420F with 2F already on
+ //the bus AND 0x7f7fff results in 2f222f.
+ //
+ //The reason for masking some bits in above explanation was to ignore some
+ //known bits in those registers (bits 7 of 4210 and 4211, bits 0&1 of 4017).
+ uint8_t tmp = bus.read(addr, exec);
+ if(!config.cpu.bus_fixes || (addr & 0x40FC00) != 0x004000) regs.mdr = tmp;
add_clocks(4);
alu_edge();
- return regs.mdr;
+ return tmp;
}
void CPU::op_write(uint32 addr, uint8 data) {
diff --git a/snes/cpu/mmio/mmio.cpp b/snes/cpu/mmio/mmio.cpp
index 30048c19..be2990a3 100755
--- a/snes/cpu/mmio/mmio.cpp
+++ b/snes/cpu/mmio/mmio.cpp
@@ -33,9 +33,17 @@ void CPU::mmio_w2183(uint8 data) {
//strobing $4016.d0 affects both controller port latches.
//$4017 bit 0 writes are ignored.
void CPU::mmio_w4016(uint8 data) {
- if(data&1) interface->notifyLatched();
- input.port1->latch(data & 1);
- input.port2->latch(data & 1);
+ //Only consider autoassert if both busfix and auto flags are set.
+ auto auto_asserted = (status.auto_joypad_counter & 384) == 384;
+ //Bit 6 of status.auto_joypad_counter follows "manual" latch.
+ auto oldstatus = auto_asserted || (status.auto_joypad_counter & 64) != 0;
+ status.auto_joypad_counter &= ~64;
+ status.auto_joypad_counter |= (data & 1) << 6;
+ auto newstatus = auto_asserted || (status.auto_joypad_counter & 64) != 0;
+ //If !oldstatus and newstatus, signal latch.
+ if(!oldstatus && newstatus) interface->notifyLatched();
+ input.port1->latch(newstatus);
+ input.port2->latch(newstatus);
}
//JOYSER0
diff --git a/snes/cpu/timing/joypad.cpp b/snes/cpu/timing/joypad.cpp
index afca7504..b60be020 100755
--- a/snes/cpu/timing/joypad.cpp
+++ b/snes/cpu/timing/joypad.cpp
@@ -3,11 +3,14 @@
//called every 256 clocks; see CPU::add_clocks()
void CPU::step_auto_joypad_poll() {
if(vcounter() >= (ppu.overscan() == false ? 225 : 240)) {
+ auto cycle = status.auto_joypad_counter & 63;
//cache enable state at first iteration
- if(status.auto_joypad_counter == 0) status.auto_joypad_latch = status.auto_joypad_poll;
- status.auto_joypad_active = status.auto_joypad_counter <= 15;
+ if(cycle == 0) status.auto_joypad_latch = status.auto_joypad_poll;
+ status.auto_joypad_active = cycle <= 15;
if(status.auto_joypad_active && status.auto_joypad_latch) {
- if(status.auto_joypad_counter == 0) {
+ if(cycle == 0) {
+ if(status.auto_joypad_counter & 128)
+ std::cerr << "step_auto_joypad_poll(): bus fixes set (counter=" << status.auto_joypad_counter << ")???" << std::endl;
if(dma_trace_fn) dma_trace_fn("-- Start automatic polling --");
interface->notifyLatched();
input.port1->latch(1);
@@ -23,7 +26,7 @@ void CPU::step_auto_joypad_poll() {
status.joy2 = (status.joy2 << 1) | (bool)(port1 & 1);
status.joy3 = (status.joy3 << 1) | (bool)(port0 & 2);
status.joy4 = (status.joy4 << 1) | (bool)(port1 & 2);
- if(status.auto_joypad_counter == 15) {
+ if(cycle == 15) {
char buf[512];
sprintf(buf, "-- End automatic polling [%04x %04x %04x %04x] --",
status.joy1, status.joy2, status.joy3, status.joy4);
@@ -31,32 +34,129 @@ void CPU::step_auto_joypad_poll() {
}
}
- status.auto_joypad_counter++;
+ //Only bits 0-5 are supposed to increment.
+ if(cycle < 60)
+ status.auto_joypad_counter++;
}
}
//called every 128 clocks; see CPU::add_clocks()
-void CPU::step_auto_joypad_poll_NEW(bool polarity) {
- if(status.auto_joypad_counter > 0 && status.auto_joypad_counter <= 34) {
+void CPU::step_auto_joypad_poll_NEW2(bool polarity) {
+ //Poll starts on multiple of 128 mod 256 clocks (polarity=false) on first
+ //vblank scanline. If autopoller is off, mark as done for the frame.
+ if(vcounter() >= (ppu.overscan() == false ? 225 : 240) && !polarity &&
+ (status.auto_joypad_counter & 63) == 0) {
+ if(!(status.auto_joypad_counter & 128))
+ std::cerr << "step_auto_joypad_poll_NEW2(): bus fixes clear???" << std::endl;
+ //Preserve high bits of autopoll counter.
+ auto x = status.auto_joypad_counter & ~63;
+ status.auto_joypad_counter = x | (status.auto_joypad_poll ? 1 : 36);
+ status.auto_joypad_latch = status.auto_joypad_poll;
+ }
+ //Abuse bit 6 of counter for "manual" poll flag. Bit 7 is supposed to be
+ //always set.
+ auto cycle = status.auto_joypad_counter & 63;
+ auto old_latchstate = (status.auto_joypad_counter & 320) != 0;
+ //If not enabled... This is not latched, as autopoll can be aborted.
+ if(!status.auto_joypad_poll && cycle > 0 && cycle < 36) {
+ if(dma_trace_fn) dma_trace_fn("-- Automatic polling ABORTED --");
+ status.auto_joypad_counter += (36 - cycle);
+ status.auto_joypad_active = false;
+ status.auto_joypad_latch = false;
+ //Release autopoll latch.
+ status.auto_joypad_counter &= ~256; //Autopoll clears latch.
+ auto new_latchstate = (status.auto_joypad_counter & 320) != 0;
+ if(old_latchstate && !new_latchstate) {
+ input.port1->latch(0);
+ input.port2->latch(0);
+ }
+ return;
+ }
+ //On cycle #1, latch is asserted (unless latch is already high, in this
+ //case the autopoller is supposed to force latch high too).
+ if(cycle == 1) {
+ if(dma_trace_fn) dma_trace_fn("-- Start automatic polling --");
+ //Assert autopoll latch.
+ status.auto_joypad_counter |= 256;
+ auto new_latchstate = (status.auto_joypad_counter & 320) != 0;
+ if(!old_latchstate && new_latchstate) {
+ interface->notifyLatched();
+ input.port1->latch(1);
+ input.port2->latch(1);
+ }
+ }
+ //On cycle #2, busy is asserted and controllers are cleared.
+ if(cycle == 2) {
+ status.joy1 = 0;
+ status.joy2 = 0;
+ status.joy3 = 0;
+ status.joy4 = 0;
+ status.auto_joypad_active = true;
+ }
+ //Then, on cycle #3, latch is deasserted, unless "manual" latch forces
+ //real latch high.
+ if(cycle == 3) {
+ //Release autopoll latch.
+ status.auto_joypad_counter &= ~256;
+ auto new_latchstate = (status.auto_joypad_counter & 320) != 0;
+ if(old_latchstate && !new_latchstate) {
+ input.port1->latch(0);
+ input.port2->latch(0);
+ }
+ }
+ //Then on cycles #4, #6, #8, ..., #34, a bit is shifted. Also, clock would
+ //go low, but we can not emulate that.
+ if(cycle >= 4 && cycle <= 34 && cycle % 2 == 0) {
+ uint2 port0 = input.port1->data();
+ uint2 port1 = input.port2->data();
+ status.joy1 = (status.joy1 << 1) | (bool)(port0 & 1);
+ status.joy2 = (status.joy2 << 1) | (bool)(port1 & 1);
+ status.joy3 = (status.joy3 << 1) | (bool)(port0 & 2);
+ status.joy4 = (status.joy4 << 1) | (bool)(port1 & 2);
+ }
+ //Then on cycles #5, #7, #9, ..., #35, clock drops high, But we can not
+ //emulate that.
+ //Then on cycle #35, busy flag is deasserted and poll is complete.
+ if(cycle == 35) {
+ status.auto_joypad_active = false;
+ char buf[512];
+ sprintf(buf, "-- End automatic polling [%04x %04x %04x %04x] --",
+ status.joy1, status.joy2, status.joy3, status.joy4);
+ if(dma_trace_fn) dma_trace_fn(buf);
+ }
+ //The entiere train is 35 cycles.
+ if(cycle > 0 && cycle < 36) {
+ status.auto_joypad_counter++;
+ }
+}
+
+
+//called every 128 clocks; see CPU::add_clocks()
+void CPU::step_auto_joypad_poll_NEW(bool polarity, bool new2) {
+ if(new2) return step_auto_joypad_poll_NEW2(polarity);
+ auto cycle = status.auto_joypad_counter & 63;
+ if(cycle > 0 && cycle <= 34) {
if(!status.auto_joypad_latch) {
//FIXME: Is this right, busy flag goes on even if not enabled???
- if(status.auto_joypad_counter == 1)
+ if(cycle == 1)
status.auto_joypad_active = true;
- if(status.auto_joypad_counter == 34)
+ if(cycle == 34)
status.auto_joypad_active = false;
} else {
- if(status.auto_joypad_counter == 1) {
+ if(cycle == 1) {
+ if(status.auto_joypad_counter & 128)
+ std::cerr << "step_auto_joypad_poll_NEW(): bus fixes set???" << std::endl;
if(dma_trace_fn) dma_trace_fn("-- Start automatic polling --");
status.auto_joypad_active = true;
interface->notifyLatched();
input.port1->latch(1);
input.port2->latch(1);
}
- if(status.auto_joypad_counter == 3) {
+ if(cycle == 3) {
input.port1->latch(0);
input.port2->latch(0);
}
- if((status.auto_joypad_counter & 1) != 0 && status.auto_joypad_counter != 1) {
+ if((cycle & 1) != 0 && cycle != 1) {
uint2 port0 = input.port1->data();
uint2 port1 = input.port2->data();
@@ -65,7 +165,7 @@ void CPU::step_auto_joypad_poll_NEW(bool polarity) {
status.joy3 = (status.joy3 << 1) | (bool)(port0 & 2);
status.joy4 = (status.joy4 << 1) | (bool)(port1 & 2);
}
- if(status.auto_joypad_counter == 34) {
+ if(cycle == 34) {
status.auto_joypad_active = false;
char buf[512];
sprintf(buf, "-- End automatic polling [%04x %04x %04x %04x] --",
@@ -75,9 +175,11 @@ void CPU::step_auto_joypad_poll_NEW(bool polarity) {
}
status.auto_joypad_counter++;
}
- if(vcounter() >= (ppu.overscan() == false ? 225 : 240) && status.auto_joypad_counter == 0 && !polarity) {
+ if(vcounter() >= (ppu.overscan() == false ? 225 : 240) && cycle == 0 && !polarity) {
+ //Preserve high bits of autopoller counter.
+ auto x = status.auto_joypad_counter & ~63;
status.auto_joypad_latch = status.auto_joypad_poll;
- status.auto_joypad_counter = 1;
+ status.auto_joypad_counter = x | 1;
}
}
diff --git a/snes/cpu/timing/timing.cpp b/snes/cpu/timing/timing.cpp
index d7cf24f3..ef81d891 100755
--- a/snes/cpu/timing/timing.cpp
+++ b/snes/cpu/timing/timing.cpp
@@ -17,12 +17,12 @@ void CPU::add_clocks(unsigned clocks) {
step(clocks);
- if(config.cpu.alt_poll_timings) {
+ if(config.cpu.alt_poll_timings || config.cpu.bus_fixes) {
bool opolarity = (status.auto_joypad_clock & 128);
status.auto_joypad_clock = (status.auto_joypad_clock + clocks) & 0xFF;
bool npolarity = (status.auto_joypad_clock & 128);
if(opolarity != npolarity)
- step_auto_joypad_poll_NEW(opolarity);
+ step_auto_joypad_poll_NEW(opolarity, config.cpu.bus_fixes);
} else {
status.auto_joypad_clock += clocks;
if(status.auto_joypad_clock >= 256) {
@@ -53,7 +53,8 @@ void CPU::scanline() {
status.hdma_init_position = (cpu_version == 1 ? 12 + 8 - dma_counter() : 12 + dma_counter());
status.hdma_init_triggered = false;
- status.auto_joypad_counter = 0;
+ //Only clear the low 6 bits (counter).
+ status.auto_joypad_counter &= ~63;
}
//DRAM refresh occurs once every scanline
@@ -200,7 +201,9 @@ void CPU::timing_reset() {
status.auto_joypad_active = false;
status.auto_joypad_latch = false;
- status.auto_joypad_counter = 0;
+ //Set bit 7 of joypad counter if bus fixes are active (for combined
+ //latch behavior).
+ status.auto_joypad_counter = config.cpu.bus_fixes ? 128 : 0;
status.auto_joypad_clock = 0;
}
diff --git a/snes/cpu/timing/timing.hpp b/snes/cpu/timing/timing.hpp
index bf15a727..8be2b830 100755
--- a/snes/cpu/timing/timing.hpp
+++ b/snes/cpu/timing/timing.hpp
@@ -22,4 +22,5 @@ alwaysinline bool irq_test();
//joypad.cpp
void step_auto_joypad_poll();
-void step_auto_joypad_poll_NEW(bool polarity);
+void step_auto_joypad_poll_NEW(bool polarity, bool new2);
+void step_auto_joypad_poll_NEW2(bool polarity);
diff --git a/snes/snes.hpp b/snes/snes.hpp
index 3a65e360..961842b3 100755
--- a/snes/snes.hpp
+++ b/snes/snes.hpp
@@ -3,6 +3,7 @@
#define BSNES_SUPPORTS_ADV_BREAKPOINTS
#define BSNES_SUPPORTS_ADV_BREAKPOINTS_PPU
#define BSNES_SUPPORTS_ALT_TIMINGS
+#define BSNES_SUPPORTS_BUS_FIXES
#define BSNES_SUPPORTS_TRACE_SA1
#define BSNES_SUPPORTS_DMA_TRACE
--
2.15.0.rc1

View file

@ -9,27 +9,9 @@
namespace boost_fs = boost::filesystem;
bool is_cmdhelp_file(const std::string& filename)
{
std::string _filename = filename;
return (_filename.length() > 8 && _filename.substr(0, 8) == "cmdhelp/");
}
std::string search_include(const std::list<std::string>& searchpath, const std::string& _filename,
std::string search_include(const std::list<std::string>& searchpath, const std::string& filename,
const std::string& ref_by)
{
std::string filename = _filename;
//Hack: process cmdhelp includes internally as the date were for the JSON include.
if(is_cmdhelp_file(filename)) {
if(filename != "cmdhelp/inverselist.hpp") {
filename = "../src/" + filename;
//Replace the extension with .json.
size_t split = filename.find_last_of("./\\");
if(split < filename.length() && filename[split] == '.') {
filename = filename.substr(0, split) + ".json";
}
}
}
size_t p = ref_by.find_last_of("/");
if(p < ref_by.length()) {
std::string i = ref_by;

@ -1 +0,0 @@
Subproject commit a77b5548ae91cf66d1d18d4fbe2aa76eb39c7ea3

View file

@ -5,7 +5,6 @@
#include <set>
#include <stdexcept>
#include <iostream>
#include <functional>
#include "library/framebuffer.hpp"
#include "library/dispatch.hpp"
@ -41,7 +40,7 @@ public:
* Parameter id: The ID of dumper.
* Throws std::bad_alloc: Not enough memory.
*/
dumper_factory_base(const std::string& id);
dumper_factory_base(const std::string& id) throw(std::bad_alloc);
/**
* Unregister a dumper.
*/
@ -58,14 +57,14 @@ public:
* Returns: The set.
* Throws std::bad_alloc: Not enough memory.
*/
static std::set<dumper_factory_base*> get_dumper_set();
static std::set<dumper_factory_base*> get_dumper_set() throw(std::bad_alloc);
/**
* List all valid submodes.
*
* Returns: List of all valid submodes. Empty list means this dumper has no submodes.
* Throws std::bad_alloc: Not enough memory.
*/
virtual std::set<std::string> list_submodes() = 0;
virtual std::set<std::string> list_submodes() throw(std::bad_alloc) = 0;
/**
* Get mode details
*
@ -86,7 +85,7 @@ public:
* Returns: The name.
* Throws std::bad_alloc: Not enough memory.
*/
virtual std::string name() = 0;
virtual std::string name() throw(std::bad_alloc) = 0;
/**
* Get human-readable name for submode.
*
@ -94,7 +93,7 @@ public:
* Returns: The name.
* Throws std::bad_alloc: Not enough memory.
*/
virtual std::string modename(const std::string& mode) = 0;
virtual std::string modename(const std::string& mode) throw(std::bad_alloc) = 0;
/**
* Start dump.
*
@ -105,11 +104,7 @@ public:
* Throws std::runtime_error: Can't start dump.
*/
virtual dumper_base* start(master_dumper& _mdumper, const std::string& mode, const std::string& targetname)
= 0;
/**
* Is hidden?
*/
virtual bool hidden() const { return false; }
throw(std::bad_alloc, std::runtime_error) = 0;
/**
* Add dumper update notifier object.
*/
@ -142,7 +137,7 @@ public:
/**
* Construct game info.
*/
gameinfo();
gameinfo() throw(std::bad_alloc);
/**
* Game name.
*/
@ -167,7 +162,7 @@ public:
* Returns: The time formated.
* Throws std::bad_alloc: Not enough memory.
*/
std::string get_readable_time(unsigned digits) const;
std::string get_readable_time(unsigned digits) const throw(std::bad_alloc);
/**
* Get number of authors.
*
@ -181,7 +176,7 @@ public:
* Returns: The short name.
* Throws std::bad_alloc: Not enough memory.
*/
std::string get_author_short(size_t idx) const;
std::string get_author_short(size_t idx) const throw(std::bad_alloc);
/**
* Get long name of author (full name and nickname if present).
*
@ -189,7 +184,7 @@ public:
* Returns: The long name.
* Throws std::bad_alloc: Not enough memory.
*/
std::string get_author_long(size_t idx) const;
std::string get_author_long(size_t idx) const throw(std::bad_alloc);
/**
* Get rerecord count as a number. If rerecord count is too high, returns the maximum representatible count.
*
@ -224,7 +219,8 @@ public:
/**
* Call start on dumper.
*/
dumper_base* start(dumper_factory_base& factory, const std::string& mode, const std::string& targetname);
dumper_base* start(dumper_factory_base& factory, const std::string& mode, const std::string& targetname)
throw(std::bad_alloc, std::runtime_error);
/**
* Add dumper update notifier object.
*/

View file

@ -5,8 +5,6 @@
#include <string>
#include <map>
class audioapi_instance;
//All the following need to be implemented by the sound driver itself
struct _audioapi_driver
{
@ -59,50 +57,26 @@ bool audioapi_driver_initialized();
* Parameter pdev: The new sound device (playback).
* Parameter rdev: The new sound device (recording)
*/
void audioapi_driver_set_device(const std::string& pdev, const std::string& rdev);
void audioapi_driver_set_device(const std::string& pdev, const std::string& rdev) throw(std::bad_alloc,
std::runtime_error);
/**
* Get current sound device (playback).
*
* Returns: The current sound device.
*/
std::string audioapi_driver_get_device(bool rec);
std::string audioapi_driver_get_device(bool rec) throw(std::bad_alloc);
/**
* Get available sound devices (playback).
*
* Returns: The map of devices. Keyed by name of the device, values are human-readable names for devices.
*/
std::map<std::string, std::string> audioapi_driver_get_devices(bool rec);
std::map<std::string, std::string> audioapi_driver_get_devices(bool rec) throw(std::bad_alloc);
/**
* Identification for sound plugin.
*/
const char* audioapi_driver_name() throw();
/**
* Add an instance to be mixed.
*/
void audioapi_connect_instance(audioapi_instance& instance);
/**
* Remove an instance from being mixed.
*/
void audioapi_disconnect_instance(audioapi_instance& instance);
/**
* Send a rate change.
*/
void audioapi_send_rate_change(unsigned rrate, unsigned prate);
/**
* Broadcast voice input to all instances.
*/
void audioapi_put_voice(float* samples, size_t count);
/**
* Get mixed music + voice out from all instances.
*/
void audioapi_get_mixed(int16_t* samples, size_t count, bool stereo);
#endif
#endif

View file

@ -121,9 +121,6 @@ private:
std::map<std::string, active_bind> active_buttons;
std::map<std::string, keyboard::ctrlrkey*> added_keys;
std::set<core_core*> cores_done;
bool promote_autohold;
bool promote_autofire;
bool promote_typed;
controller_state& controls;
keyboard::mapper& mapper;
keyboard::keyboard& keyboard;
@ -141,12 +138,6 @@ private:
command::_fnptr<const std::string&> button_ar;
command::_fnptr<const std::string&> button_at;
command::_fnptr<const std::string&> button_a;
command::_fnptr<> afire_p;
command::_fnptr<> afire_n;
command::_fnptr<> ahold_p;
command::_fnptr<> ahold_n;
command::_fnptr<> typed_p;
command::_fnptr<> typed_n;
};

View file

@ -65,7 +65,7 @@ public:
* Parameter ptype: The new types for ports.
* Throws std::runtime_error: Illegal port type.
*/
void set_ports(const portctrl::type_set& ptype);
void set_ports(const portctrl::type_set& ptype) throw(std::runtime_error);
/**
* Get status of current controls (with autohold/autofire factored in).
*

View file

@ -19,7 +19,7 @@ struct file_download
file_download();
~file_download();
//Lauch.
void do_async(loaded_rom& rom);
void do_async(loadable_rom& rom);
void cancel();
//Status.
volatile bool finished; //This signals download finishing, call finish().
@ -29,7 +29,7 @@ struct file_download
threads::cv cond;
threads::lock m;
//Internal.
void _do_async(loaded_rom& rom);
void _do_async(loadable_rom& rom);
std::string tempname;
std::string tempname2;
};

View file

@ -2,7 +2,6 @@
#define _framebuffer__hpp__included__
#include "core/window.hpp"
#include "core/queue.hpp"
#include "library/command.hpp"
#include "library/framebuffer.hpp"
#include "library/triplebuffer.hpp"
@ -32,7 +31,7 @@ class emu_framebuffer
public:
emu_framebuffer(subtitle_commentary& _subtitles, settingvar::group& _settings, memwatch_set& _mwatch,
keyboard::keyboard& _keyboard, emulator_dispatch& _dispatch, lua_state& _lua2, loaded_rom& _rom,
status_updater& _supdater, command::group& _cmd, input_queue& _iqueue);
status_updater& _supdater, command::group& _cmd);
/**
* The main framebuffer.
*/
@ -50,7 +49,7 @@ public:
*
* throws std::bad_alloc: Not enough memory.
*/
static void init_special_screens();
static void init_special_screens() throw(std::bad_alloc);
/**
* Copy framebuffer to backing store, running Lua hooks if any.
*/
@ -62,7 +61,7 @@ public:
/**
* Return last complete framebuffer.
*/
framebuffer::raw get_framebuffer();
framebuffer::raw get_framebuffer() throw(std::bad_alloc);
/**
* Render framebuffer to main screen.
*/
@ -74,7 +73,7 @@ public:
/**
* Take a screenshot to specified file.
*/
void take_screenshot(const std::string& file);
void take_screenshot(const std::string& file) throw(std::bad_alloc, std::runtime_error);
/**
* Kill pending requests associated with object.
*/
@ -111,7 +110,6 @@ private:
loaded_rom& rom;
status_updater& supdater;
command::group& cmd;
input_queue& iqueue;
command::_fnptr<command::arg_filename> screenshot;
};

View file

@ -21,16 +21,6 @@ public:
*/
void set_speed_multiplier(double multiplier) throw();
/**
* Increase the speed to next step.
*/
void increase_speed() throw();
/**
* Decrease the speed to next step.
*/
void decrease_speed() throw();
/**
* Get the target speed multiplier.
*
@ -94,15 +84,10 @@ public:
*/
bool turboed;
private:
void set_speed_cmd(const std::string& args);
uint64_t get_time(uint64_t curtime, bool update);
double get_realized_fps();
void add_frame(uint64_t linear_time);
std::pair<bool, double> read_fps();
//Step should be ODD.
void set_speedstep(unsigned step);
//Step can be EVEN if between steps.
unsigned get_speedstep();
uint64_t last_time_update;
uint64_t time_at_last_update;
bool time_frozen;
@ -111,15 +96,11 @@ private:
//Framerate.
double nominal_framerate;
double multiplier_framerate;
bool framerate_realtime_locked;
threads::lock framerate_lock;
command::group& cmd;
command::_fnptr<> turbo_p;
command::_fnptr<> turbo_r;
command::_fnptr<> turbo_t;
command::_fnptr<const std::string&> setspeed_t;
command::_fnptr<> spd_inc;
command::_fnptr<> spd_dec;
};
#endif

View file

@ -2,7 +2,6 @@
#define _instance__hpp__included__
#include "library/threads.hpp"
#include <cstring>
class movie_logic;
class memory_space;
@ -56,7 +55,7 @@ public:
{
entry e;
e.ptr = ptr = reinterpret_cast<T*>(new char[sizeof(T) + 32]);
memset((char*)ptr, 0, sizeof(T) + 32);
memset(ptr, 0, sizeof(T) + 32);
e.free1 = null;
e.free2 = free2;
e.prev = list;
@ -124,7 +123,7 @@ struct emulator_instance
master_dumper* mdumper;
slotinfo_cache* slotcache;
audioapi_instance* audio;
loaded_rom* rom;
loadable_rom* rom;
save_jukebox* jukebox;
emulator_runmode* runmode;
status_updater* supdater;

View file

@ -23,7 +23,7 @@ struct joystick_driver
* - The call occurs in the main thread.
* - Implemented by the joystick plugin.
*/
void joystick_driver_init(bool soft = false) throw();
void joystick_driver_init() throw();
/**
* Joystick quit function.
*
@ -31,7 +31,7 @@ void joystick_driver_init(bool soft = false) throw();
* - The call occurs in the main thread.
* - Implemented by the joystick plugin.
*/
void joystick_driver_quit(bool soft = false) throw();
void joystick_driver_quit() throw();
/**
* Signal the joystick thread to quit.
*/

View file

@ -7,8 +7,5 @@ void handle_post_loadlibrary();
void autoload_libraries(void(*on_error)(const std::string& libname, const std::string& err, bool system) = NULL);
void with_loaded_library(const loadlib::module& l);
bool with_unloaded_library(loadlib::module& l);
std::string loadlib_debug_get_user_library_dir();
std::string loadlib_debug_get_system_library_dir();
#endif

View file

@ -9,7 +9,8 @@
/**
* \brief Emulator main loop.
*/
void main_loop(struct loaded_rom& rom, struct moviefile& settings, bool load_has_to_succeed = false);
void main_loop(struct loadable_rom& rom, struct moviefile& settings, bool load_has_to_succeed = false)
throw(std::bad_alloc, std::runtime_error);
std::vector<std::string> get_jukebox_names();
void set_jukebox_names(const std::vector<std::string>& newj);
void init_main_callbacks();

View file

@ -15,7 +15,7 @@ class cart_mappings_refresher
{
public:
cart_mappings_refresher(memory_space& _mspace, movie_logic& _mlogic, loaded_rom& _rom);
void operator()();
void operator()() throw(std::bad_alloc);
private:
memory_space& mspace;
movie_logic& mlogic;

View file

@ -4,7 +4,6 @@
#include <string>
#include <stdexcept>
#include <set>
#include <functional>
#include "library/memorywatch.hpp"
#include "library/json.hpp"

View file

@ -5,7 +5,6 @@
#include <vector>
#include <stdexcept>
#include "library/string.hpp"
#include "library/memtracker.hpp"
/**
* \brief Fatal error.
@ -20,7 +19,7 @@ void fatal_error() throw();
* \return The config directory path.
* \throw std::bad_alloc Not enough memory.
*/
std::string get_config_path();
std::string get_config_path() throw(std::bad_alloc);
/**
* \brief Panic on OOM.

View file

@ -29,7 +29,7 @@ public:
*
* returns: The movie instance.
*/
movie& get_movie();
movie& get_movie() throw(std::runtime_error);
/**
* Set the movie instance associated.
@ -39,7 +39,7 @@ public:
/**
* Get the current movie file.
*/
moviefile& get_mfile();
moviefile& get_mfile() throw(std::runtime_error);
/**
* Set the current movie file.
@ -48,7 +48,7 @@ public:
/**
* Get current rrdata.
*/
rrdata_set& get_rrdata();
rrdata_set& get_rrdata() throw(std::runtime_error);
/**
* Set current rrdata.
@ -58,7 +58,7 @@ public:
/**
* Notify about new frame starting.
*/
void new_frame_starting(bool dont_poll);
void new_frame_starting(bool dont_poll) throw(std::bad_alloc, std::runtime_error);
/**
* Poll for input.
@ -70,31 +70,20 @@ public:
* throws std::bad_alloc: Not enough memory.
* throws std::runtime_error: Error polling for input.
*/
short input_poll(unsigned port, unsigned dev, unsigned id);
short input_poll(unsigned port, unsigned dev, unsigned id) throw(std::bad_alloc, std::runtime_error);
/**
* Called when movie code needs new controls snapshot.
*
* parameter subframe: True if this is for subframe update, false if for frame update.
*/
portctrl::frame update_controls(bool subframe, bool forced = false);
portctrl::frame update_controls(bool subframe) throw(std::bad_alloc, std::runtime_error);
/**
* Notify user poll (exit poll advance).
*
* returns: If true, update_controls is forced.
*/
bool notify_user_poll();
/**
* Release memory for mov, mf and rrd.
*/
void release_memory();
/**
* Set frob with data routine.
*/
void set_frob_with_value(std::function<void(unsigned,unsigned,unsigned,short&)> func);
private:
std::function<void(unsigned,unsigned,unsigned,short&)> frob_with_value;
movie_logic(const movie_logic&);
movie_logic& operator=(const movie_logic&);
movie* mov;

View file

@ -31,12 +31,13 @@
#define SAVE_MOVIE 1
std::string resolve_relative_path(const std::string& path);
std::pair<std::string, std::string> split_author(const std::string& author);
std::pair<std::string, std::string> split_author(const std::string& author) throw(std::bad_alloc,
std::runtime_error);
void do_save_state(const std::string& filename, int binary);
void do_save_movie(const std::string& filename, int binary);
void do_load_rom();
void do_load_rewind();
void do_save_state(const std::string& filename, int binary) throw(std::bad_alloc, std::runtime_error);
void do_save_movie(const std::string& filename, int binary) throw(std::bad_alloc, std::runtime_error);
void do_load_rom() throw(std::bad_alloc, std::runtime_error);
void do_load_rewind() throw(std::bad_alloc, std::runtime_error);
void do_load_state(struct moviefile& _movie, int lmode, bool& used);
bool do_load_state(const std::string& filename, int lmode);
std::string translate_name_mprefix(std::string original, int& binary, int save);
@ -50,7 +51,7 @@ extern std::string last_save;
* Parameter secs: The seconds counter.
* Parameter ssecs: The subsecond counter.
*/
void mainloop_restore_state(const dynamic_state& state);
void mainloop_restore_state(const std::vector<char>& state, uint64_t secs, uint64_t ssecs);
std::string get_mprefix_for_project();
void set_mprefix_for_project(const std::string& pfx);

View file

@ -1,7 +1,6 @@
#ifndef _moviefile_common__hpp__included__
#define _moviefile_common__hpp__included__
#include <functional>
#include "core/moviefile.hpp"
#define DEFAULT_RTC_SECOND 1000000000ULL
#define DEFAULT_RTC_SUBSECOND 0ULL
@ -40,25 +39,4 @@ private:
int s;
};
struct moviefile_sram_extractor_text : public moviefile::sram_extractor
{
moviefile_sram_extractor_text(const std::string& filename);
~moviefile_sram_extractor_text();
std::set<std::string> enumerate();
void read(const std::string& name, std::vector<char>& v);
private:
zip::reader z;
};
struct moviefile_sram_extractor_binary : public moviefile::sram_extractor
{
moviefile_sram_extractor_binary(const std::string& filename);
~moviefile_sram_extractor_binary();
std::set<std::string> enumerate();
void read(const std::string& name, std::vector<char>& v);
private:
int s;
};
#endif

View file

@ -14,69 +14,6 @@
class loaded_rom;
/**
* Dynamic state parts of movie file.
*/
struct dynamic_state
{
/**
* Ctor.
*/
dynamic_state();
/**
* Contents of SRAM on time of savestate (if is_savestate is true).
*/
std::map<std::string, std::vector<char>> sram;
/**
* Core savestate (if is_savestate is true).
*/
std::vector<char> savestate; //Savestate to load (if is_savestate is true).
/**
* Host memory (if is_savestate is true).
*/
std::vector<char> host_memory;
/**
* Screenshot (if is_savestate is true).
*/
std::vector<char> screenshot;
/**
* Current frame (if is_savestate is true).
*/
uint64_t save_frame;
/**
* Number of lagged frames (if is_savestate is true).
*/
uint64_t lagged_frames;
/**
* Poll counters (if is_savestate is true).
*/
std::vector<uint32_t> pollcounters;
/**
* Poll flag.
*/
unsigned poll_flag;
/**
* Current RTC second.
*/
int64_t rtc_second;
/**
* Current RTC subsecond.
*/
int64_t rtc_subsecond;
/**
* Active macros at savestate.
*/
std::map<std::string, uint64_t> active_macros;
/**
* Clear the state to power-on defaults.
*/
void clear(int64_t sec, int64_t ssec, const std::map<std::string, std::vector<char>>& initsram);
/**
* Swap the dynamic state with another.
*/
void swap(dynamic_state& s) throw();
};
/**
* This structure gives parsed representationg of movie file, as result of decoding or for encoding.
*/
@ -115,30 +52,12 @@ struct moviefile
private:
branch_extractor* real;
};
/**
* Extract SRAMs.
*/
struct sram_extractor
{
sram_extractor(const std::string& filename);
virtual ~sram_extractor();
virtual std::set<std::string> enumerate() { return real->enumerate(); }
virtual void read(const std::string& name, std::vector<char>& v) { real->read(name, v); }
protected:
sram_extractor() { real = NULL; }
private:
sram_extractor* real;
};
/**
* Identify if file is movie/savestate file or not.
*/
static bool is_movie_or_savestate(const std::string& filename);
/**
* This constructor construct movie structure with default settings.
*
* throws std::bad_alloc: Not enough memory.
*/
moviefile();
moviefile() throw(std::bad_alloc);
/**
* This constructor loads a movie/savestate file and fills structure accordingly.
@ -148,7 +67,7 @@ struct moviefile
* throws std::bad_alloc: Not enough memory.
* throws std::runtime_error: Can't load the movie file
*/
moviefile(const std::string& filename, core_type& romtype);
moviefile(const std::string& filename, core_type& romtype) throw(std::bad_alloc, std::runtime_error);
/**
* Fill a stub movie with specified loaded ROM.
@ -171,11 +90,12 @@ struct moviefile
* throws std::bad_alloc: Not enough memory.
* throws std::runtime_error: Can't save the movie file.
*/
void save(const std::string& filename, unsigned compression, bool binary, rrdata_set& rrd, bool as_state);
void save(const std::string& filename, unsigned compression, bool binary, rrdata_set& rrd)
throw(std::bad_alloc, std::runtime_error);
/**
* Reads this movie structure and saves it to stream (uncompressed ZIP).
*/
void save(std::ostream& outstream, rrdata_set& rrd, bool as_state);
void save(std::ostream& outstream, rrdata_set& rrd) throw(std::bad_alloc, std::runtime_error);
/**
* Force loading as corrupt.
*/
@ -232,10 +152,46 @@ struct moviefile
* Contents of RAM on time of initial powerup.
*/
std::map<std::string, std::vector<char>> ramcontent;
/**
* True if savestate, false if movie.
*/
bool is_savestate;
/**
* Contents of SRAM on time of savestate (if is_savestate is true).
*/
std::map<std::string, std::vector<char>> sram;
/**
* Core savestate (if is_savestate is true).
*/
std::vector<char> savestate; //Savestate to load (if is_savestate is true).
/**
* Anchoring core savestate (if not empty).
*/
std::vector<char> anchor_savestate;
/**
* Host memory (if is_savestate is true).
*/
std::vector<char> host_memory;
/**
* Screenshot (if is_savestate is true).
*/
std::vector<char> screenshot;
/**
* Current frame (if is_savestate is true).
*/
uint64_t save_frame;
/**
* Number of lagged frames (if is_savestate is true).
*/
uint64_t lagged_frames;
/**
* Poll counters (if is_savestate is true).
*/
std::vector<uint32_t> pollcounters;
/**
* Poll flag.
*/
unsigned poll_flag;
/**
* Compressed rrdata.
*/
@ -248,6 +204,14 @@ struct moviefile
* Branches.
*/
std::map<std::string, portctrl::frame_vector> branches;
/**
* Current RTC second.
*/
int64_t rtc_second;
/**
* Current RTC subsecond.
*/
int64_t rtc_subsecond;
/**
* Movie starting RTC second.
*/
@ -269,9 +233,9 @@ struct moviefile
*/
std::map<moviefile_subtiming, std::string> subtitles;
/**
* Dynamic state.
* Active macros at savestate.
*/
dynamic_state dyn;
std::map<std::string, uint64_t> active_macros;
/**
* Get number of frames in movie.
*
@ -310,23 +274,13 @@ struct moviefile
* Fixup input pointer post-copy.
*/
void fixup_current_branch(const moviefile& mv);
/**
* Clear the dynamic state to power-on defaults.
*/
void clear_dynstate();
/**
* Get the filename of the movie.
*/
std::string get_filename() { return filename; }
private:
moviefile(const moviefile&);
moviefile& operator=(const moviefile&);
void binary_io(int stream, rrdata_set& rrd, bool as_state);
void binary_io(int stream, struct core_type& romtype);
void save(zip::writer& w, rrdata_set& rrd, bool as_state);
void load(zip::reader& r, core_type& romtype);
memtracker::autorelease tracker;
std::string filename;
void binary_io(int stream, rrdata_set& rrd) throw(std::bad_alloc, std::runtime_error);
void binary_io(int stream, struct core_type& romtype) throw(std::bad_alloc, std::runtime_error);
void save(zip::writer& w, rrdata_set& rrd) throw(std::bad_alloc, std::runtime_error);
void load(zip::reader& r, core_type& romtype) throw(std::bad_alloc, std::runtime_error);
};
void emerg_save_movie(const moviefile& mv, rrdata_set& rrd);

View file

@ -1,12 +0,0 @@
#ifndef _nullcore__hpp__included__
#define _nullcore__hpp__included__
class core_core;
class core_type;
class core_region;
core_core& get_null_core();
core_type& get_null_type();
core_region& get_null_region();
#endif

View file

@ -164,7 +164,7 @@ class project_state
{
public:
project_state(voice_commentary& _commentary, memwatch_set& _mwatch, command::group& _command,
controller_state& _controls, settingvar::group& _setgroup, button_mapping& _buttons,
controller_state& _controls, settingvar::cache& _setcache, button_mapping& _buttons,
emulator_dispatch& _edispatch, input_queue& _iqueue, loaded_rom& _rom, status_updater& _supdater);
~project_state();
/**
@ -232,7 +232,7 @@ private:
memwatch_set& mwatch;
command::group& command;
controller_state& controls;
settingvar::group& setgroup;
settingvar::cache& setcache;
button_mapping& buttons;
emulator_dispatch& edispatch;
input_queue& iqueue;

View file

@ -4,7 +4,6 @@
#include "library/exrethrow.hpp"
#include "library/keyboard.hpp"
#include "library/threads.hpp"
#include <functional>
#include <deque>
namespace command
@ -83,7 +82,7 @@ struct input_queue
*
* Parameter k: The keypress to queue.
*/
void queue(const keypress_info& k);
void queue(const keypress_info& k) throw(std::bad_alloc);
/**
* Queue command.
*
@ -91,7 +90,7 @@ struct input_queue
*
* Parameter c: The command to queue.
*/
void queue(const std::string& c);
void queue(const std::string& c) throw(std::bad_alloc);
/**
* Queue command and arguments.
*
@ -100,7 +99,7 @@ struct input_queue
* Parameter c: The command to queue.
* Parameter a: The arguments for function.
*/
void queue(const char* c, const std::string& a);
void queue(const char* c, const std::string& a) throw(std::bad_alloc);
/**
* Queue function to be called in emulation thread.
*
@ -111,7 +110,8 @@ struct input_queue
* Parameter arg: Argument to pass to the function.
* Parameter sync: If true, execute function call synchronously, else asynchronously.
*/
void queue(std::function<void()> f, std::function<void(std::exception& e)> onerror, bool sync);
void queue(std::function<void()> f, std::function<void(std::exception& e)> onerror, bool sync)
throw(std::bad_alloc);
/**
* Run all queues.
*/

View file

@ -15,7 +15,7 @@
* \return The random hexadecimal string.
* \throws std::bad_alloc Not enough memory.
*/
std::string get_random_hexstring(size_t length);
std::string get_random_hexstring(size_t length) throw(std::bad_alloc);
/**
* \brief Set random seed
@ -25,7 +25,7 @@ std::string get_random_hexstring(size_t length);
* \param seed The value to use as seed.
* \throw std::bad_alloc Not enough memory.
*/
void set_random_seed(const std::string& seed);
void set_random_seed(const std::string& seed) throw(std::bad_alloc);
/**
* \brief Set random seed to (hopefully) unique value
@ -35,7 +35,7 @@ void set_random_seed(const std::string& seed);
*
* \throw std::bad_alloc Not enough memory.
*/
void set_random_seed();
void set_random_seed() throw(std::bad_alloc);
/**
* Mix some entropy.
@ -47,9 +47,4 @@ void random_mix_timing_entropy();
*/
void highrandom_256(uint8_t* buf);
/**
* Contribute buffer of entropy.
*/
void contribute_random_entropy(void* buf, size_t bytes);
#endif

View file

@ -7,46 +7,41 @@
#include <stdexcept>
#include "core/misc.hpp"
#include "core/rom-small.hpp"
#include "core/romimage.hpp"
#include "interface/romtype.hpp"
#include "library/fileimage.hpp"
/**
* ROM loaded into memory.
*/
struct loaded_rom
//ROM request.
struct rom_request
{
//List of core types.
std::vector<core_type*> cores;
//Selected core (default core on call).
bool core_guessed;
size_t selected;
//Filename selected (on entry, filename hint).
bool has_slot[ROM_SLOT_COUNT];
bool guessed[ROM_SLOT_COUNT];
std::string filename[ROM_SLOT_COUNT];
std::string hash[ROM_SLOT_COUNT];
std::string hashxml[ROM_SLOT_COUNT];
//Canceled flag.
bool canceled;
};
struct loadable_rom;
/**
* Create blank ROM
* An in-core emulation instance.
*/
loaded_rom() throw();
/**
* Create ROM from image.
*
* parameter _image: The image to use load
* throws std::bad_alloc: Not enough memory.
* throws std::runtime_error: Loading ROM file failed.
*/
loaded_rom(rom_image_handle _image);
/**
* Switches the active cartridge to this cartridge. The compatiblity between selected region and original region
* is checked. Region is updated after cartridge has been loaded.
*
* throws std::bad_alloc: Not enough memory
* throws std::runtime_error: Switching cartridges failed.
*/
void load(std::map<std::string, std::string>& settings, uint64_t rtc_sec, uint64_t rtc_subsec);
/**
* Reset the emulation state to state just before last load.
*/
void reset_to_load() { return rtype().reset_to_load(); }
struct incore_rom
{
/**
* Saves core state into buffer. WARNING: This takes emulated time.
*
* returns: The saved state.
* throws std::bad_alloc: Not enough memory.
*/
std::vector<char> save_core_state(bool nochecksum = false);
std::vector<char> save_core_state(bool nochecksum = false) throw(std::bad_alloc, std::runtime_error);
/**
* Loads core state from buffer.
@ -54,122 +49,198 @@ struct loaded_rom
* parameter buf: The buffer containing the state.
* throws std::runtime_error: Loading state failed.
*/
void load_core_state(const std::vector<char>& buf, bool nochecksum = false);
void load_core_state(const std::vector<char>& buf, bool nochecksum = false) throw(std::runtime_error);
/**
* Get internal type representation.
* Get gametype of this ROM.
*/
core_type& get_internal_rom_type() { return rtype(); }
core_sysregion& get_sysregion() { return cinst->from_type().combine_region(*region); }
/**
* Get internal region representation.
*/
core_region& get_internal_region() { return *region; }
/**
* Is same ROM type?
*/
bool is_of_type(core_type& type) { return image->is_of_type(type); }
/**
* Get gametype of this ROM.
*/
core_sysregion& get_sysregion() { return rtype().combine_region(*region); }
/**
* Set internal region representation.
*/
void set_internal_region(core_region& reg) { region = &reg; }
/**
* Access main ROM image.
*
* parameter index: The index of ROM slot to access.
* returns: The ROM image (NULL image if index is out of range).
*/
fileimage::image& get_rom(size_t index) { return image->get_image(index, false); }
/**
* Access ROM markup image.
*
* parameter index: The index of ROM slot to access.
* returns: The ROM markup image (NULL image if index is out of range).
*/
fileimage::image& get_markup(size_t index) { return image->get_image(index, true); }
/**
* Get filename of ROM pack, if any.
*/
const std::string& get_pack_filename() { return image->get_pack_filename(); }
/**
* Get MSU-1 base fileaname.
*/
const std::string& get_msu1_base() { return image->get_msu1_base(); }
//ROM methods.
std::string get_core_identifier() { return rtype().get_core_identifier(); }
std::pair<uint32_t, uint32_t> get_scale_factors(uint32_t width, uint32_t height)
void set_internal_region(core_region& reg) { region = &reg; }
std::map<std::string, std::vector<char>> save_sram() throw(std::bad_alloc) { return cinst->save_sram(); }
void load_sram(std::map<std::string, std::vector<char>>& sram) throw(std::bad_alloc)
{
return rtype().get_scale_factors(width, height);
cinst->load_sram(sram);
}
const std::string& get_hname() { return image->get_hname(); }
core_sysregion& combine_region(core_region& reg) { return rtype().combine_region(reg); }
bool isnull() { return rtype().isnull(); }
std::vector<std::string> get_trace_cpus() { return rtype().get_trace_cpus(); }
controller_set controllerconfig(std::map<std::string, std::string>& settings)
{
return rtype().controllerconfig(settings);
}
core_setting_group& get_settings() { return rtype().get_settings(); }
std::set<std::string> srams() { return rtype().srams(); }
double get_PAR() { return rtype().get_PAR(); }
std::string get_systemmenu_name() { return rtype().get_systemmenu_name(); }
unsigned action_flags(unsigned id) { return rtype().action_flags(id); }
std::set<const interface_action*> get_actions() { return rtype().get_actions(); }
void execute_action(unsigned id, const std::vector<interface_action_paramval>& p)
{
return rtype().execute_action(id, p);
}
std::pair<unsigned, unsigned> lightgun_scale() { return rtype().lightgun_scale(); }
const interface_device_reg* get_registers() { return rtype().get_registers(); }
bool get_pflag() { return rtype().get_pflag(); }
void set_pflag(bool pflag) { rtype().set_pflag(pflag); }
std::pair<uint64_t, uint64_t> get_bus_map() { return rtype().get_bus_map(); }
std::list<core_region*> get_regions() { return image->get_regions(); }
const std::string& get_iname() { return rtype().get_iname(); }
std::map<std::string, std::vector<char>> save_sram() { return rtype().save_sram(); }
void load_sram(std::map<std::string, std::vector<char>>& sram)
{
rtype().load_sram(sram);
}
std::list<core_vma_info> vma_list() { return rtype().vma_list(); }
framebuffer::raw& draw_cover() { return rtype().draw_cover(); }
int reset_action(bool hard) { return rtype().reset_action(hard); }
void pre_emulate_frame(portctrl::frame& cf) { return rtype().pre_emulate_frame(cf); }
void emulate() { rtype().emulate(); }
void runtosave() { rtype().runtosave(); }
std::pair<uint32_t, uint32_t> get_audio_rate() { return rtype().get_audio_rate(); }
std::list<core_vma_info> vma_list() { return cinst->vma_list(); }
framebuffer::raw& draw_cover() { return cinst->draw_cover(); }
int reset_action(bool hard) { return cinst->reset_action(hard); }
void pre_emulate_frame(portctrl::frame& cf) { return cinst->pre_emulate_frame(cf); }
void emulate() { cinst->emulate(); }
void runtosave() { cinst->runtosave(); }
std::pair<uint32_t, uint32_t> get_audio_rate() { return cinst->get_audio_rate(); }
void set_debug_flags(uint64_t addr, unsigned flags_set, unsigned flags_clear)
{
return rtype().set_debug_flags(addr, flags_set, flags_clear);
return cinst->set_debug_flags(addr, flags_set, flags_clear);
}
void set_cheat(uint64_t addr, uint64_t value, bool set)
{
return rtype().set_cheat(addr, value, set);
return cinst->set_cheat(addr, value, set);
}
void debug_reset()
{
rtype().debug_reset();
cinst->debug_reset();
}
//Region methods.
const std::string& orig_region_get_iname() { return image->get_region().get_iname(); }
const std::string& orig_region_get_hname() { return image->get_region().get_hname(); }
std::pair<uint32_t, uint32_t> get_scale_factors(uint32_t width, uint32_t height)
{
return cinst->get_scale_factors(width, height);
}
std::vector<std::string> get_trace_cpus() { return cinst->get_trace_cpus(); }
std::set<std::string> srams() { return cinst->srams(); }
double get_PAR() { return cinst->get_PAR(); }
unsigned action_flags(unsigned id) { return cinst->action_flags(id); }
std::set<const interface_action*> get_actions() { return cinst->get_actions(); }
void execute_action(unsigned id, const std::vector<interface_action_paramval>& p)
{
return cinst->execute_action(id, p);
}
std::pair<unsigned, unsigned> lightgun_scale() { return cinst->lightgun_scale(); }
const interface_device_reg* get_registers() { return cinst->get_registers(); }
bool get_pflag() { return cinst->get_pflag(); }
void set_pflag(bool pflag) { cinst->set_pflag(pflag); }
std::pair<uint64_t, uint64_t> get_bus_map() { return cinst->get_bus_map(); }
const std::string& region_get_iname() { return region->get_iname(); }
const std::string& region_get_hname() { return region->get_hname(); }
double region_approx_framerate() { return region->approx_framerate(); }
void region_fill_framerate_magic(uint64_t* magic) { region->fill_framerate_magic(magic); }
void destroy();
loadable_rom& orig_rom() { return *lrom; }
private:
/**
* Loaded ROM this has been created from.
*/
loadable_rom* lrom;
/**
* ROM instance
*/
core_instance* cinst;
/**
* ROM region (this is the currently active region).
*/
core_region* region;
};
/**
* A Loadable ROM
*/
struct loadable_rom
{
/**
* Create blank ROM
*/
loadable_rom() throw();
/**
* Take in ROM filename (or a bundle) and load it to memory.
*
* parameter file: The file to load
* parameter tmpprefer: The core name to prefer.
* throws std::bad_alloc: Not enough memory.
* throws std::runtime_error: Loading ROM file failed.
*/
loadable_rom(const std::string& file, const std::string& tmpprefer = "") throw(std::bad_alloc,
std::runtime_error);
/**
* Take a ROM and load it.
*/
loadable_rom(const std::string& file, const std::string& core, const std::string& type,
const std::string& region);
/**
* Load a multi-file ROM.
*/
loadable_rom(const std::string file[ROM_SLOT_COUNT], const std::string& core, const std::string& type,
const std::string& region);
/**
* Take in ROM filename and load it to memory with specified type.
*
* parameter file: The file to load
* parameter ctype: The core type to use.
* throws std::bad_alloc: Not enough memory.
* throws std::runtime_error: Loading ROM file failed.
*/
loadable_rom(const std::string& file, core_type& ctype) throw(std::bad_alloc, std::runtime_error);
/**
* Loaded main ROM
*/
fileimage::image romimg[ROM_SLOT_COUNT];
/**
* Loaded main ROM XML
*/
fileimage::image romxml[ROM_SLOT_COUNT];
/**
* MSU-1 base.
*/
std::string msu1_base;
/**
* Load filename.
*/
std::string load_filename;
/**
* Switches the active cartridge to this cartridge. The compatiblity between selected region and original region
* is checked. Region is updated after cartridge has been loaded.
*
* returns: The incore ROM.
* throws std::bad_alloc: Not enough memory
* throws std::runtime_error: Switching cartridges failed.
*/
incore_rom& load(std::map<std::string, std::string>& settings, uint64_t rtc_sec, uint64_t rtc_subsec)
throw(std::bad_alloc, std::runtime_error);
/**
* Is file a gamepak?
*
* parameter filename: The file to probe.
* retruns: True if gamepak, false if not.
* throws std::runtime_error: No such file.
*/
static bool is_gamepak(const std::string& filename) throw(std::bad_alloc, std::runtime_error);
/**
* Get internal type representation.
*/
core_type& get_internal_rom_type() { return *rtype; }
/**
* Is multicore capable?
*/
bool multicore_capable() { return rtype->multicore_capable(); }
/**
* Is same ROM type?
*/
bool is_of_type(core_type& type) { return (rtype == &type); }
//ROM methods.
std::string get_core_identifier() { return rtype->get_core_identifier(); }
const std::string& get_hname() { return rtype->get_hname(); }
core_sysregion& combine_region(core_region& reg) { return rtype->combine_region(reg); }
bool isnull() { return rtype->isnull(); }
controller_set controllerconfig(std::map<std::string, std::string>& settings)
{
return rtype->controllerconfig(settings);
}
core_setting_group& get_settings() { return rtype->get_settings(); }
std::string get_systemmenu_name() { return rtype->get_systemmenu_name(); }
std::list<core_region*> get_regions() { return rtype->get_regions(); }
const std::string& get_iname() { return rtype->get_iname(); }
//Region methods.
const std::string& orig_region_get_iname() { return orig_region->get_iname(); }
const std::string& orig_region_get_hname() { return orig_region->get_hname(); }
bool region_compatible_with(core_region& run)
{
return image->get_region().compatible_with(run);
return orig_region && orig_region->compatible_with(run);
}
private:
core_type& rtype() { return image->get_type(); }
//The internal ROM image.
rom_image_handle image;
//ROM region.
core_region* region;
/**
* The ROM type.
*/
core_type* rtype;
/**
* ROM original region (this is the region ROM is loaded as).
*/
core_region* orig_region;
};
/**
@ -187,7 +258,13 @@ std::pair<core_type*, core_region*> get_current_rom_info() throw();
* throws std::bad_alloc: Out of memory.
* throws std::runtime_error: Failed to load.
*/
std::map<std::string, std::vector<char>> load_sram_commandline(const std::vector<std::string>& cmdline);
std::map<std::string, std::vector<char>> load_sram_commandline(const std::vector<std::string>& cmdline)
throw(std::bad_alloc, std::runtime_error);
/**
* Set the hasher callback.
*/
void set_hasher_callback(std::function<void(uint64_t, uint64_t)> cb);
struct romload_request
{
@ -208,10 +285,17 @@ bool _load_new_rom(const romload_request& req);
bool reload_active_rom();
regex_results get_argument(const std::vector<std::string>& cmdline, const std::string& regexp);
std::string get_requested_core(const std::vector<std::string>& cmdline);
loadable_rom construct_rom(const std::string& movie_filename, const std::vector<std::string>& cmdline);
void try_guess_roms(rom_request& req);
void record_filehash(const std::string& file, uint64_t prefix, const std::string& hash);
std::string try_to_guess_rom(const std::string& hint, const std::string& hash, const std::string& xhash,
core_type& type, unsigned i);
//Map of preferred cores for each extension and type.
extern std::map<std::string, core_type*> preferred_core;
//Main hasher
extern fileimage::hash lsnes_image_hasher;
#endif

View file

@ -1,229 +0,0 @@
#ifndef _romimage__hpp__included__
#define _romimage__hpp__included__
#include <functional>
#include "core/rom-small.hpp"
#include "interface/romtype.hpp"
#include "library/fileimage.hpp"
#include "library/threads.hpp"
//ROM request.
struct rom_request
{
//List of core types.
std::vector<core_type*> cores;
//Selected core (default core on call).
bool core_guessed;
size_t selected;
//Filename selected (on entry, filename hint).
bool has_slot[ROM_SLOT_COUNT];
bool guessed[ROM_SLOT_COUNT];
std::string filename[ROM_SLOT_COUNT];
std::string hash[ROM_SLOT_COUNT];
std::string hashxml[ROM_SLOT_COUNT];
//Canceled flag.
bool canceled;
};
/**
* A collection of files making up a ROM image.
*/
class rom_image
{
public:
/**
* Create blank ROM
*/
rom_image() throw();
/**
* Take in ROM filename (or a bundle) and load it to memory.
*
* parameter file: The file to load
* parameter tmpprefer: The core name to prefer.
* throws std::bad_alloc: Not enough memory.
* throws std::runtime_error: Loading ROM file failed.
*/
rom_image(const std::string& file, const std::string& tmpprefer = "");
/**
* Take a ROM and load it.
*/
rom_image(const std::string& file, const std::string& core, const std::string& type,
const std::string& region);
/**
* Load a multi-file ROM.
*/
rom_image(const std::string file[ROM_SLOT_COUNT], const std::string& core, const std::string& type,
const std::string& region);
/**
* Take in ROM filename and load it to memory with specified type.
*
* parameter file: The file to load
* parameter ctype: The core type to use.
* throws std::bad_alloc: Not enough memory.
* throws std::runtime_error: Loading ROM file failed.
*/
rom_image(const std::string& file, core_type& ctype);
/**
* Destroy ROM image.
*/
~rom_image();
/**
* Get ROM type.
*/
core_type& get_type() { return *rtype; }
/**
* Get ROM region.
*/
core_region& get_region() { return *orig_region; }
/**
* Do region setup. Changes orig_region to specified if NULL.
*/
void setup_region(core_region& reg);
/**
* Get image.
*/
fileimage::image& get_image(size_t index, bool xml)
{
if(index < ROM_SLOT_COUNT) {
if(xml)
return romxml[index];
else
return romimg[index];
} else
return null_img;
}
/**
* Get filename of ROM pack, if any.
*/
const std::string& get_pack_filename() { return load_filename; }
/**
* Get MSU-1 base fileaname.
*/
const std::string& get_msu1_base() { return msu1_base; }
/**
* Is same ROM type?
*/
bool is_of_type(core_type& type) { return (rtype == &type); }
/**
* Is file a gamepak?
*
* parameter filename: The file to probe.
* retruns: True if gamepak, false if not.
* throws std::runtime_error: No such file.
*/
static bool is_gamepak(const std::string& filename);
//ROM functions.
std::list<core_region*> get_regions() { return rtype->get_regions(); }
const std::string& get_hname() { return rtype->get_hname(); }
private:
rom_image(const rom_image&);
rom_image& operator=(const rom_image&);
//Account images.
void account_images();
//Static NULL image.
static fileimage::image null_img;
//Loaded ROM images.
fileimage::image romimg[ROM_SLOT_COUNT];
//Loaded ROM XML (markup) images.
fileimage::image romxml[ROM_SLOT_COUNT];
//MSU-1 base filename.
std::string msu1_base;
//Load filename.
std::string load_filename;
//ROM type.
core_type* rtype;
//ROM region.
core_region* region;
//Region ROM was loaded as.
core_region* orig_region;
//Reference count.
threads::lock usage_lock;
size_t usage_count;
void get() { threads::alock l(usage_lock); usage_count++; }
bool put() { threads::alock l(usage_lock); return !--usage_count; }
friend class rom_image_handle;
//Handle bundle load case.
void load_bundle(const std::string& file, std::istream& spec, const std::string& tmpprefer);
//Tracker.
memtracker::autorelease tracker;
};
/**
* A handle for ROM imageset.
*/
class rom_image_handle
{
public:
/**
* Create a handle to NULL imageset.
*/
rom_image_handle()
{
img = &null_img;
}
/**
* Create a new handle with refcount 1. The specified ROM imageset has to be allocated using new.
*/
rom_image_handle(rom_image* _img)
{
img = _img;
img->usage_count = 1;
}
/**
* Copy-construct a handle.
*/
rom_image_handle(const rom_image_handle& h)
{
h.get();
img = h.img;
}
/**
* Assign a handle.
*/
rom_image_handle& operator=(const rom_image_handle& h)
{
if(img == h.img) return *this;
h.get();
put();
img = h.img;
return *this;
}
/**
* Destroy a handle.
*/
~rom_image_handle()
{
put();
}
/**
* Access the handle.
*/
rom_image& operator*()
{
return *img;
}
/**
* Access the handle.
*/
rom_image* operator->()
{
return img;
}
private:
static rom_image null_img;
mutable rom_image* img;
void get() const { if(img != &null_img) img->get(); }
void put() const { if(img != &null_img && img->put()) delete img; }
};
void record_filehash(const std::string& file, uint64_t prefix, const std::string& hash);
void set_hasher_callback(std::function<void(uint64_t, uint64_t)> cb);
rom_image_handle construct_rom(const std::string& movie_filename, const std::vector<std::string>& cmdline);
//Map of preferred cores for each extension and type.
extern std::map<std::string, core_type*> preferred_core;
//Main hasher
extern fileimage::hash lsnes_image_hasher;
#endif

View file

@ -161,12 +161,9 @@ public:
* Get current point
*/
unsigned get_point();
/**
* Get the current runmode.
*/
uint64_t get();
private:
void revalidate();
uint64_t get();
void set(uint64_t m);
bool is(uint64_t m);
uint64_t mode;

View file

@ -5,10 +5,4 @@
extern settingvar::set lsnes_setgrp;
extern settingvar::supervariable<settingvar::model_path> SET_rompath;
extern settingvar::supervariable<settingvar::model_path> SET_moviepath;
extern settingvar::supervariable<settingvar::model_path> SET_firmwarepath;
extern settingvar::supervariable<settingvar::model_path> SET_slotpath;
#endif

View file

@ -49,8 +49,6 @@ struct dumper_information_1
std::string name;
//Is this dumper active?
bool active;
//Hidden?
bool hidden;
//Modes available (first is internal name, second is human-readable one).
std::map<std::string, std::string> modes;
};

View file

@ -93,7 +93,7 @@ struct platform
* returns: The output stream.
* throws std::bad_alloc: Not enough memory.
*/
static std::ostream& out();
static std::ostream& out() throw(std::bad_alloc);
/**
* Message buffer.
*/
@ -110,7 +110,7 @@ struct platform
* parameter msg: The messages to add (split by '\n').
* throws std::bad_alloc: Not enough memory.
*/
static void message(const std::string& msg);
static void message(const std::string& msg) throw(std::bad_alloc);
/**
* Displays fatal error message, quitting after the user acks it (called by fatal_error()).
*
@ -140,7 +140,7 @@ struct platform
/**
* Get sound device description.
*/
static std::string get_sound_device_description(bool rec);
static std::string get_sound_device_description(bool rec) throw(std::bad_alloc);
/**
* Show error message dialog after UI thread becomes free.
*

View file

@ -7,4 +7,4 @@ extern framebuffer::font main_font;
void do_init_font();
#endif
#endif

View file

@ -166,10 +166,6 @@ template<> struct e2t<LSNES_CORE_GET_VMA_LIST> {
typedef lsnes_core_get_vma_list* t;
typedef lsnes_core_get_vma_list& r;
};
template<> struct e2t<LSNES_CORE_REINIT> {
typedef lsnes_core_reinit* t;
typedef lsnes_core_reinit& r;
};
template<typename T> class t2e {};
template<> struct t2e<lsnes_core_enumerate_cores> { const static int e = LSNES_CORE_ENUMERATE_CORES; };
@ -206,7 +202,6 @@ template<> struct t2e<lsnes_core_draw_cover> { const static int e = LSNES_CORE_D
template<> struct t2e<lsnes_core_pre_emulate> { const static int e = LSNES_CORE_PRE_EMULATE; };
template<> struct t2e<lsnes_core_get_device_regs> { const static int e = LSNES_CORE_GET_DEVICE_REGS; };
template<> struct t2e<lsnes_core_get_vma_list> { const static int e = LSNES_CORE_GET_VMA_LIST; };
template<> struct t2e<lsnes_core_reinit> { const static int e = LSNES_CORE_REINIT; };
}
#endif

View file

@ -51,7 +51,6 @@ THE SOFTWARE.
* - If you only have one region, use ID of 0 for that and GET_REGION/SET_REGION are not needed.
*/
#include <unistd.h>
#include <stdint.h>
#include <time.h>
@ -110,8 +109,8 @@ extern "C" {
#define LSNES_CORE_CAP1_MEMWATCH 0x00010000U
//Core supports lightguns (By setting lightgun_height/lightgun_width in LSNES_CORE_GET_AV_STATE).
#define LSNES_CORE_CAP1_LIGHTGUN 0x00020000U
//Core supports fast reinit (By supporting LSNES_CORE_REINIT).
#define LSNES_CORE_CAP1_REINIT 0x00040000U
//Core supports multicore (By supporting LSNES_CORE_LOAD_ROM2).
#define LSNES_CORE_CAP1_MULTICORE 0x00040000U
//Reserved capabilities.
#define LSNES_CORE_CAP1_RESERVED19 0x00080000U
#define LSNES_CORE_CAP1_RESERVED20 0x00100000U
@ -213,7 +212,7 @@ struct lsnes_core_fontrender_req
//Input: Text to render (UTF-8).
const char* text;
//Input: Length of text in bytes. If negative, text is null-terminated.
ssize_t text_len;
long text_len;
//Input: Bytes per pixel to request. Can be 1, 2, 3 or 4.
unsigned bytes_pp;
//Input: Foreground color (native endian).
@ -425,7 +424,7 @@ struct lsnes_core_get_sysregion_info
//Request 5: Get current A/V state.
//Item: Core ID.
//Item: Core ID (Instance ID if LSNES_CORE_CAP1_MULTICORE)
//Default action: (required)
//Fill the structure with current A/V state.
#define LSNES_CORE_GET_AV_STATE 5
@ -442,7 +441,7 @@ struct lsnes_core_get_av_state
//Request 6: Emulate a frame
//Item: Core ID.
//Item: Core ID (Instance ID if LSNES_CORE_CAP1_MULTICORE)
//Default action: (required).
//Emulate a frame and output the video and audio data resulting.
#define LSNES_CORE_EMULATE 6
@ -451,7 +450,7 @@ struct lsnes_core_emulate
};
//Request 7: Save state.
//Item: Core ID.
//Item: Core ID (Instance ID if LSNES_CORE_CAP1_MULTICORE)
//Default action: (required).
//Save core state.
#define LSNES_CORE_SAVESTATE 7
@ -464,7 +463,7 @@ struct lsnes_core_savestate
};
//Request 8: Load state.
//Item: Core ID.
//Item: Core ID (Instance ID if LSNES_CORE_CAP1_MULTICORE)
//Default action: (required).
//Load core state.
#define LSNES_CORE_LOADSTATE 8
@ -525,7 +524,7 @@ struct lsnes_core_load_rom
};
//Request 11: Get region.
//Item: Core ID.
//Item: Core ID (Instance ID if LSNES_CORE_CAP1_MULTICORE)
//Default action: Fill region 0.
//Return the current region.
#define LSNES_CORE_GET_REGION 11
@ -536,7 +535,7 @@ struct lsnes_core_get_region
};
//Request 12: Set region.
//Item: Core ID.
//Item: Core ID (Instance ID if LSNES_CORE_CAP1_MULTICORE)
//Default action: If region is 0, succeed, otherwise fail.
//Set current region.
#define LSNES_CORE_SET_REGION 12
@ -556,7 +555,7 @@ struct lsnes_core_deinitialize
};
//Request 14: Get poll flag state.
//Item: Core ID.
//Item: Core ID (Instance ID if LSNES_CORE_CAP1_MULTICORE)
//Default action: Return flag inferred from polls.
//Return the poll flag state.
//The poll flag gets automatically set to 1 if core reads controllers.
@ -568,7 +567,7 @@ struct lsnes_core_get_pflag
};
//Request 15: Set poll flag state.
//Item: Core ID.
//Item: Core ID (Instance ID if LSNES_CORE_CAP1_MULTICORE)
//Default action: Set flag inferred from polls.
//Sets the poll flag state.
#define LSNES_CORE_SET_PFLAG 15
@ -579,7 +578,7 @@ struct lsnes_core_set_pflag
};
//Request 16: Get action flags.
//Item: Core ID.
//Item: Core ID (Instance ID if LSNES_CORE_CAP1_MULTICORE)
//Default action: Act as if flags was 1.
//Get flags for given action.
#define LSNES_CORE_GET_ACTION_FLAGS 16
@ -594,7 +593,7 @@ struct lsnes_core_get_action_flags
};
//Request 17: Execute action.
//Item: Core ID.
//Item: Core ID (Instance ID if LSNES_CORE_CAP1_MULTICORE)
//Default action: Do nothing.
//Execute given action.
#define LSNES_CORE_EXECUTE_ACTION 17
@ -618,7 +617,7 @@ struct lsnes_core_execute_action
};
//Request 18: Get bus mapping.
//Item: Core ID.
//Item: Core ID (Instance ID if LSNES_CORE_CAP1_MULTICORE)
//Default action: base=0, size=0 (no mapping).
//Get the base and size of bus mapping.
#define LSNES_CORE_GET_BUS_MAPPING 18
@ -631,7 +630,7 @@ struct lsnes_core_get_bus_mapping
};
//Request 19: Enumerate SRAMs.
//Item iD: Core ID.
//Item iD: Core ID (Instance ID if LSNES_CORE_CAP1_MULTICORE)
//Default action: Return empty set.
//Get the set of SRAMs available.
#define LSNES_CORE_ENUMERATE_SRAM 19
@ -642,7 +641,7 @@ struct lsnes_core_enumerate_sram
};
//Request 20: Save SRAMs.
//Item id: Core ID.
//Item id: Core ID (Instance ID if LSNES_CORE_CAP1_MULTICORE)
//Default action: Return empty set.
//Save the contents of SRAMs.
#define LSNES_CORE_SAVE_SRAM 20
@ -653,7 +652,7 @@ struct lsnes_core_save_sram
};
//Request 21: Load SRAMs.
//Item id: Core ID.
//Item id: Core ID (Instance ID if LSNES_CORE_CAP1_MULTICORE)
//Default action: Warn about any SRAMs present.
//Load the contents of SRAMs.
#define LSNES_CORE_LOAD_SRAM 21
@ -664,7 +663,7 @@ struct lsnes_core_load_sram
};
//Request 22: Get reset action number.
//Item id: Core ID.
//Item id: Core ID (Instance ID if LSNES_CORE_CAP1_MULTICORE)
//Default action: Return -1 for both (not supported).
//Return the IDs for reset actions.
#define LSNES_CORE_GET_RESET_ACTION 22
@ -677,7 +676,7 @@ struct lsnes_core_get_reset_action
};
//Request 23: Get scale factors.
//Item id: Core ID.
//Item id: Core ID (Instance ID if LSNES_CORE_CAP1_MULTICORE)
//Default action: Scale to at least 360 width, 320 height.
//Compute scale factors for given resolution.
#define LSNES_CORE_COMPUTE_SCALE 23
@ -694,7 +693,7 @@ struct lsnes_core_compute_scale
};
//Request 24: Run to save.
//Item id: Core ID.
//Item id: Core ID (Instance ID if LSNES_CORE_CAP1_MULTICORE)
//Default action: Do nothing.
//Run to next save point (can be at most frame).
#define LSNES_CORE_RUNTOSAVE 24
@ -703,7 +702,7 @@ struct lsnes_core_runtosave
};
//Request 25: Poweron the system
//Item id: Core ID.
//Item id: Core ID (Instance ID if LSNES_CORE_CAP1_MULTICORE)
//Default action: Do nothing.
//Powers on the emulate system.
#define LSNES_CORE_POWERON 25
@ -712,16 +711,16 @@ struct lsnes_core_poweron
};
//Request 26: Unload the ROM.
//Item id: Core ID.
//Item id: Core ID (Instance ID if LSNES_CORE_CAP1_MULTICORE)
//Default action: Do nothing.
//Signals that the ROM is no longer needed and can be unloaded.
//Signals that the ROM is no longer needed and can be unloaded. Destroys the instance of LSNES_CORE_CAP1_MULTICORE.
#define LSNES_CORE_UNLOAD_CARTRIDGE 26
struct lsnes_core_unload_cartridge
{
};
//Request 27: Reset debugging.
//Item id: Core ID.
//Item id: Core ID (Instance ID if LSNES_CORE_CAP1_MULTICORE)
//Default action: Do nothing.
//Signals that debugging system should discard all breakpoints, cheats and tracks.
#define LSNES_CORE_DEBUG_RESET 27
@ -730,7 +729,7 @@ struct lsnes_core_debug_reset
};
//Request 28: Set debug flags.
//Item id: Core ID.
//Item id: Core ID (Instance ID if LSNES_CORE_CAP1_MULTICORE)
//Default action: Do nothing.
//Set debugging flags.
#define LSNES_CORE_SET_DEBUG_FLAGS 28
@ -749,7 +748,7 @@ struct lsnes_core_set_debug_flags
};
//Request 29: Set cheat.
//Item id: Core ID.
//Item id: Core ID (Instance ID if LSNES_CORE_CAP1_MULTICORE)
//Default action: Do nothing.
//Set or clear cheat.
#define LSNES_CORE_SET_CHEAT 29
@ -764,7 +763,7 @@ struct lsnes_core_set_cheat
};
//Request 30: Draw cover page.
//Item id: Core ID.
//Item id: Core ID (Instance ID if LSNES_CORE_CAP1_MULTICORE)
//Default action: Draw black screen.
//Draw the cover page.
#define LSNES_CORE_DRAW_COVER 30
@ -775,7 +774,7 @@ struct lsnes_core_draw_cover
};
//Request 31: Set system controls before emulating frame.
//Item id: Core ID.
//Item id: Core ID (Instance ID if LSNES_CORE_CAP1_MULTICORE)
//Default action: Do nothing.
//Set the system controls before frame is emulated.
#define LSNES_CORE_PRE_EMULATE 31
@ -788,7 +787,7 @@ struct lsnes_core_pre_emulate
};
//Request 32: Get list of device registers.
//Item id: Core ID.
//Item id: Core ID (Instance ID if LSNES_CORE_CAP1_MULTICORE)
//Default action: Return no registers.
//Return list of device registers.
#define LSNES_CORE_GET_DEVICE_REGS 32
@ -810,7 +809,7 @@ struct lsnes_core_get_device_regs
};
//Request 33: Get VMA list.
//Item id: Core ID.
//Item id: Core ID (Instance ID if LSNES_CORE_CAP1_MULTICORE)
//Default action: Return no VMAs.
//Get the list of VMAs.
#define LSNES_CORE_GET_VMA_LIST 33
@ -840,14 +839,23 @@ struct lsnes_core_get_vma_list
struct lsnes_core_get_vma_list_vma** vmas;
};
//Request 34: Reinit core to last loaded state.
//Item id: Core ID.
//Default action: Emulate using loadstate.
//Signals that the core state should be reset to state just after last load (load savestate at moment of initial
//poweron).
#define LSNES_CORE_REINIT 27
struct lsnes_core_reinit
//Request 34: Load ROM and allocate instance ID. Only for emu_flags1 >= 3.
//Item id: Type ID.
//Default action: Not used.
//Load given ROM, allocating instance ID.
#define LSNES_CORE_LOAD_ROM2 34
struct lsnes_core_load_rom2
{
//Input: The image set.
struct lsnes_core_load_rom_image* images;
//Input: System settings. Ended by entry with NULL name.
struct lsnes_core_system_setting* settings;
//Input: RTC second.
uint64_t rtc_sec;
//Input: RTC subsecond.
uint64_t rtc_subsec;
//Output: The instance ID.
unsigned instance_id;
};

View file

@ -319,56 +319,212 @@ struct core_core
core_core(std::initializer_list<portctrl::type*> ports, std::initializer_list<interface_action> actions);
core_core(std::vector<portctrl::type*> ports, std::vector<interface_action> actions);
virtual ~core_core() throw();
bool set_region(core_region& region);
std::pair<uint32_t, uint32_t> get_video_rate();
double get_PAR();
std::pair<uint32_t, uint32_t> get_audio_rate();
std::string get_core_identifier() const;
std::map<std::string, std::vector<char>> save_sram();
void load_sram(std::map<std::string, std::vector<char>>& sram);
void serialize(std::vector<char>& out);
void unserialize(const char* in, size_t insize);
core_region& get_region();
void power();
void unload_cartridge();
std::pair<uint32_t, uint32_t> get_scale_factors(uint32_t width, uint32_t height);
std::string get_core_identifier();
void install_handler();
void uninstall_handler();
void emulate();
void runtosave();
bool get_pflag();
void set_pflag(bool pflag);
framebuffer::raw& draw_cover();
std::vector<portctrl::type*> get_port_types() { return port_types; }
std::string get_core_shortname() const;
void pre_emulate_frame(portctrl::frame& cf);
void execute_action(unsigned id, const std::vector<interface_action_paramval>& p);
unsigned action_flags(unsigned id);
std::pair<uint64_t, uint64_t> get_bus_map();
std::list<core_vma_info> vma_list();
std::set<std::string> srams();
std::string get_core_shortname();
static std::set<core_core*> all_cores();
static void install_all_handlers();
static void uninstall_all_handlers();
static void initialize_new_cores();
void hide() { hidden = true; }
bool is_hidden() const { return hidden; }
std::set<const interface_action*> get_actions();
const interface_device_reg* get_registers();
int reset_action(bool hard);
std::pair<unsigned, unsigned> lightgun_scale();
void set_debug_flags(uint64_t addr, unsigned flags_set, unsigned flags_clear);
void set_cheat(uint64_t addr, uint64_t value, bool set);
std::vector<std::string> get_trace_cpus();
void debug_reset();
bool isnull() const;
void reset_to_load() { c_reset_to_load(); }
bool is_hidden() { return hidden; }
bool isnull();
bool safe_to_unload(loadlib::module& mod) { return !mod.is_marked(this); }
protected:
/**
* Get the name of the core.
*/
virtual std::string c_core_identifier() const = 0;
virtual std::string c_core_identifier() = 0;
/**
* Do basic core initialization. Called on lsnes startup.
*/
virtual void c_install_handler() = 0;
/**
* Do basic core uninitialization. Called on lsnes shutdown.
*/
virtual void c_uninstall_handler() = 0;
/**
* Get shortened name of the core.
*/
virtual std::string c_get_core_shortname() = 0;
/**
* Is null core (only NULL core should define this).
*/
virtual bool c_isnull();
private:
bool hidden;
};
struct core_instance;
struct core_type
{
public:
core_type(const core_type_params& params);
core_type(std::initializer_list<core_type_params> p) : core_type(*p.begin()) {}
virtual ~core_type() throw();
static std::list<core_type*> get_core_types();
core_region& get_preferred_region();
std::list<core_region*> get_regions();
core_sysregion& combine_region(core_region& reg);
const std::string& get_iname();
const std::string& get_hname();
std::list<std::string> get_extensions();
bool is_known_extension(const std::string& ext);
core_sysregion& lookup_sysregion(const std::string& sysreg);
std::string get_biosname();
unsigned get_id();
unsigned get_image_count();
core_romimage_info get_image_info(unsigned index);
core_instance& load(core_romimage* images, std::map<std::string, std::string>& settings, uint64_t rtc_sec,
uint64_t rtc_subsec);
controller_set controllerconfig(std::map<std::string, std::string>& settings);
core_setting_group& get_settings();
core_core* get_core() { return core; }
void install_handler() { core->install_handler(); }
void uninstall_handler() { core->uninstall_handler(); }
std::string get_systemmenu_name() { return sysname; }
bool is_hidden() { return core->is_hidden(); }
std::string get_core_identifier() { return core->get_core_identifier(); }
std::string get_core_shortname() { return core->get_core_shortname(); }
bool isnull() { return core->isnull(); }
bool safe_to_unload(loadlib::module& mod) { return core->safe_to_unload(mod); }
bool multicore_capable() { return t_multicore_capable(); }
protected:
/**
* Load a ROM slot set. Changes the ROM currently loaded for core.
*
* Parameter images: The set of images to load.
* Parameter settings: The settings to use.
* Parameter rtc_sec: The initial RTC seconds value.
* Parameter rtc_subsec: The initial RTC subseconds value.
* Returns: The new instance, or NULL on failure.
*/
virtual core_instance* t_load_rom(core_romimage* images, std::map<std::string, std::string>& settings,
uint64_t rtc_sec, uint64_t rtc_subsec) = 0;
/**
* Obtain controller config for given settings.
*
* Parameter settings: The settings to use.
* Returns: The controller configuration.
*/
virtual controller_set t_controllerconfig(std::map<std::string, std::string>& settings) = 0;
/**
* Is multicore capable?
*/
virtual bool t_multicore_capable() const;
private:
core_type(const core_type&);
core_type& operator=(const core_type&);
unsigned id;
std::string iname;
std::string hname;
std::string biosname;
std::string sysname;
std::list<core_region*> regions;
std::vector<core_romimage_info> imageinfo;
core_setting_group settings;
core_core* core;
};
/**
* System type / region pair.
*
* All run regions for given system must have valid pairs.
*/
struct core_sysregion
{
public:
/**
* Create a new system type / region pair.
*
* Parameter name: The internal name of the pair.
* Parameter type: The system.
* Parameter region: The region.
*/
core_sysregion(const std::string& name, core_type& type, core_region& region);
~core_sysregion() throw();
const std::string& get_name();
core_region& get_region();
core_type& get_type();
void fill_framerate_magic(uint64_t* magic); //4 elements filled.
/**
* Find all sysregions matching specified name.
*
* Parameter name: The name of system region.
* Returns: Sysregions matching the specified.
*/
static std::set<core_sysregion*> find_matching(const std::string& name);
private:
core_sysregion(const core_sysregion&);
core_sysregion& operator=(const core_sysregion&);
std::string name;
core_type& type;
core_region& region;
};
/**
* A core instance.
*/
struct core_instance
{
public:
virtual ~core_instance();
void serialize(std::vector<char>& out) { c_serialize(out); }
void unserialize(const char* in, size_t insize) { c_unserialize(in, insize); }
core_type& from_type() { return *type; }
bool set_region(core_region& region) { return c_set_region(region); }
std::pair<uint32_t, uint32_t> get_video_rate() { return c_video_rate(); }
double get_PAR() { return c_get_PAR(); }
std::pair<uint32_t, uint32_t> get_audio_rate() { return c_audio_rate(); }
std::map<std::string, std::vector<char>> save_sram() throw(std::bad_alloc) { return c_save_sram(); }
void load_sram(std::map<std::string, std::vector<char>>& sram) throw(std::bad_alloc) { c_load_sram(sram); }
core_region& get_region() { return c_get_region(); }
void power() { return c_power(); }
std::pair<uint32_t, uint32_t> get_scale_factors(uint32_t width, uint32_t height)
{
return c_get_scale_factors(width, height);
}
void emulate() { c_emulate(); }
void runtosave() { c_runtosave(); }
bool get_pflag() { return c_get_pflag(); }
void set_pflag(bool pflag) { return c_set_pflag(pflag); }
framebuffer::raw& draw_cover() { return c_draw_cover(); }
std::vector<portctrl::type*> get_port_types() { return port_types; }
void pre_emulate_frame(portctrl::frame& cf) { c_pre_emulate_frame(cf); }
void execute_action(unsigned id, const std::vector<interface_action_paramval>& p)
{
c_execute_action(id, p);
}
unsigned action_flags(unsigned id) { return c_action_flags(id); }
std::pair<uint64_t, uint64_t> get_bus_map() { return c_get_bus_map(); }
std::list<core_vma_info> vma_list() { return c_vma_list(); }
std::set<std::string> srams() { return c_srams(); }
std::set<const interface_action*> get_actions();
const interface_device_reg* get_registers() { return c_get_registers(); }
int reset_action(bool hard) { return c_reset_action(hard); }
std::pair<unsigned, unsigned> lightgun_scale() { return c_lightgun_scale(); }
void set_debug_flags(uint64_t addr, unsigned flags_set, unsigned flags_clear)
{
c_set_debug_flags(addr, flags_set, flags_clear);
}
void set_cheat(uint64_t addr, uint64_t value, bool set) { return c_set_cheat(addr, value, set); }
std::vector<std::string> get_trace_cpus() { return c_get_trace_cpus(); }
void debug_reset() { return c_debug_reset(); }
bool unload_destroys_instance() { return type->multicore_capable(); }
//If multicore, capable, DESTROYS the instance.
void unload_cartridge();
protected:
core_type* type;
/**
* Serialize the system state.
*/
virtual void c_serialize(std::vector<char>& out) = 0;
/**
* Unserialize the system state.
*/
virtual void c_unserialize(const char* in, size_t insize) = 0;
/**
* Set the current region.
*
@ -393,21 +549,13 @@ protected:
/**
* Save all SRAMs.
*/
virtual std::map<std::string, std::vector<char>> c_save_sram() = 0;
virtual std::map<std::string, std::vector<char>> c_save_sram() throw(std::bad_alloc) = 0;
/**
* Load all SRAMs.
*
* Note: Must handle SRAM being missing or shorter or longer than expected.
*/
virtual void c_load_sram(std::map<std::string, std::vector<char>>& sram) = 0;
/**
* Serialize the system state.
*/
virtual void c_serialize(std::vector<char>& out) = 0;
/**
* Unserialize the system state.
*/
virtual void c_unserialize(const char* in, size_t insize) = 0;
virtual void c_load_sram(std::map<std::string, std::vector<char>>& sram) throw(std::bad_alloc) = 0;
/**
* Get current region.
*/
@ -416,22 +564,6 @@ protected:
* Poweron the console.
*/
virtual void c_power() = 0;
/**
* Unload the cartridge from the console.
*/
virtual void c_unload_cartridge() = 0;
/**
* Get the current scale factors for screen as (xscale, yscale).
*/
virtual std::pair<uint32_t, uint32_t> c_get_scale_factors(uint32_t width, uint32_t height) = 0;
/**
* Do basic core initialization. Called on lsnes startup.
*/
virtual void c_install_handler() = 0;
/**
* Do basic core uninitialization. Called on lsnes shutdown.
*/
virtual void c_uninstall_handler() = 0;
/**
* Emulate one frame.
*/
@ -458,10 +590,6 @@ protected:
* Should display information about the ROM loaded.
*/
virtual framebuffer::raw& c_draw_cover() = 0;
/**
* Get shortened name of the core.
*/
virtual std::string c_get_core_shortname() const = 0;
/**
* Set the system controls to appropriate values for next frame.
*
@ -532,168 +660,19 @@ protected:
*/
virtual void c_debug_reset() = 0;
/**
* Reset to state equivalent to ROM load.
* Unload the cartridge from the console (prepare instance to be destroyed).
*/
virtual void c_reset_to_load() = 0;
virtual void c_unload_cartridge() = 0;
/**
* Is null core (only NULL core should define this).
* Get the current scale factors for screen as (xscale, yscale).
*/
virtual bool c_isnull() const;
virtual std::pair<uint32_t, uint32_t> c_get_scale_factors(uint32_t width, uint32_t height) = 0;
private:
std::vector<portctrl::type*> port_types;
bool hidden;
std::map<std::string, interface_action> actions;
threads::lock actions_lock;
};
struct core_type
{
public:
core_type(const core_type_params& params);
core_type(std::initializer_list<core_type_params> p) : core_type(*p.begin()) {}
virtual ~core_type() throw();
static std::list<core_type*> get_core_types();
core_region& get_preferred_region() const;
std::list<core_region*> get_regions() const;
core_sysregion& combine_region(core_region& reg) const;
const std::string& get_iname() const;
const std::string& get_hname() const;
std::list<std::string> get_extensions() const;
bool is_known_extension(const std::string& ext) const;
core_sysregion& lookup_sysregion(const std::string& sysreg) const;
std::string get_biosname() const;
unsigned get_id() const;
unsigned get_image_count() const;
core_romimage_info get_image_info(unsigned index) const;
bool load(core_romimage* images, std::map<std::string, std::string>& settings, uint64_t rtc_sec,
uint64_t rtc_subsec);
controller_set controllerconfig(std::map<std::string, std::string>& settings);
core_setting_group& get_settings();
std::pair<uint64_t, uint64_t> get_bus_map() { return core->get_bus_map(); }
std::list<core_vma_info> vma_list() { return core->vma_list(); }
std::set<std::string> srams() { return core->srams(); }
core_core* get_core() { return core; }
bool set_region(core_region& region) { return core->set_region(region); }
std::pair<uint32_t, uint32_t> get_video_rate() { return core->get_video_rate(); }
std::pair<uint32_t, uint32_t> get_audio_rate() { return core->get_audio_rate(); }
std::string get_core_identifier() { return core->get_core_identifier(); }
std::string get_core_shortname() const { return core->get_core_shortname(); }
std::map<std::string, std::vector<char>> save_sram() { return core->save_sram(); }
void load_sram(std::map<std::string, std::vector<char>>& sram)
{
core->load_sram(sram);
}
void serialize(std::vector<char>& out) { core->serialize(out); }
void unserialize(const char* in, size_t insize) { core->unserialize(in, insize); }
core_region& get_region() { return core->get_region(); }
void power() { core->power(); }
void unload_cartridge() { core->unload_cartridge(); }
std::pair<uint32_t, uint32_t> get_scale_factors(uint32_t width, uint32_t height)
{
return core->get_scale_factors(width, height);
}
void install_handler() { core->install_handler(); }
void uninstall_handler() { core->uninstall_handler(); }
void emulate() { core->emulate(); }
void runtosave() { core->runtosave(); }
bool get_pflag() { return core->get_pflag(); }
void set_pflag(bool pflag) { core->set_pflag(pflag); }
framebuffer::raw& draw_cover() { return core->draw_cover(); }
std::string get_systemmenu_name() { return sysname; }
void execute_action(unsigned id, const std::vector<interface_action_paramval>& p)
{
return core->execute_action(id, p);
}
unsigned action_flags(unsigned id) { return core->action_flags(id); }
bool is_hidden() const { return core->is_hidden(); }
double get_PAR() { return core->get_PAR(); }
void pre_emulate_frame(portctrl::frame& cf) { return core->pre_emulate_frame(cf); }
std::set<const interface_action*> get_actions() { return core->get_actions(); }
const interface_device_reg* get_registers() { return core->get_registers(); }
int reset_action(bool hard) { return core->reset_action(hard); }
std::pair<unsigned, unsigned> lightgun_scale() { return core->lightgun_scale(); }
void set_debug_flags(uint64_t addr, unsigned flags_set, unsigned flags_clear)
{
return core->set_debug_flags(addr, flags_set, flags_clear);
}
void set_cheat(uint64_t addr, uint64_t value, bool set)
{
return core->set_cheat(addr, value, set);
}
std::vector<std::string> get_trace_cpus() { return core->get_trace_cpus(); }
void debug_reset() { core->debug_reset(); }
bool isnull() const { return core->isnull(); }
void reset_to_load() { return core->reset_to_load(); }
bool safe_to_unload(loadlib::module& mod) const { return core->safe_to_unload(mod); }
protected:
/**
* Load a ROM slot set. Changes the ROM currently loaded for core.
*
* Parameter images: The set of images to load.
* Parameter settings: The settings to use.
* Parameter rtc_sec: The initial RTC seconds value.
* Parameter rtc_subsec: The initial RTC subseconds value.
* Returns: -1 on failure, 0 on success.
*/
virtual int t_load_rom(core_romimage* images, std::map<std::string, std::string>& settings, uint64_t rtc_sec,
uint64_t rtc_subsec) = 0;
/**
* Obtain controller config for given settings.
*
* Parameter settings: The settings to use.
* Returns: The controller configuration.
*/
virtual controller_set t_controllerconfig(std::map<std::string, std::string>& settings) = 0;
private:
core_type(const core_type&);
core_type& operator=(const core_type&);
unsigned id;
std::string iname;
std::string hname;
std::string biosname;
std::string sysname;
std::list<core_region*> regions;
std::vector<core_romimage_info> imageinfo;
core_setting_group settings;
core_core* core;
};
/**
* System type / region pair.
*
* All run regions for given system must have valid pairs.
*/
struct core_sysregion
{
public:
/**
* Create a new system type / region pair.
*
* Parameter name: The internal name of the pair.
* Parameter type: The system.
* Parameter region: The region.
*/
core_sysregion(const std::string& name, core_type& type, core_region& region);
~core_sysregion() throw();
const std::string& get_name() const;
core_region& get_region();
core_type& get_type();
void fill_framerate_magic(uint64_t* magic); //4 elements filled.
/**
* Find all sysregions matching specified name.
*
* Parameter name: The name of system region.
* Returns: Sysregions matching the specified.
*/
static std::set<core_sysregion*> find_matching(const std::string& name);
private:
core_sysregion(const core_sysregion&);
core_sysregion& operator=(const core_sysregion&);
std::string name;
core_type& type;
core_region& region;
};
//Register a sysregion to name mapping.
void register_sysregion_mapping(std::string from, std::string to);
std::string lookup_sysregion_mapping(std::string from);

View file

@ -40,7 +40,7 @@ struct core_setting_value
/**
* Create a new setting value.
*/
core_setting_value(const core_setting_value_param& p);
core_setting_value(const core_setting_value_param& p) throw(std::bad_alloc);
/**
* Internal value.
*/
@ -95,15 +95,15 @@ struct core_setting
/**
* Get set of human-readable strings.
*/
std::vector<std::string> hvalues() const;
std::vector<std::string> hvalues() const throw(std::runtime_error);
/**
* Translate hvalue to ivalue.
*/
std::string hvalue_to_ivalue(const std::string& hvalue) const;
std::string hvalue_to_ivalue(const std::string& hvalue) const throw(std::runtime_error);
/**
* Translate ivalue to index.
*/
signed ivalue_to_index(const std::string& ivalue) const;
signed ivalue_to_index(const std::string& ivalue) const throw(std::runtime_error);
/**
* Validate a value.
*
@ -138,13 +138,14 @@ struct core_setting_group
* Translate ivalue to index.
*/
signed ivalue_to_index(std::map<std::string, std::string>& values, const std::string& name) const
throw(std::runtime_error)
{
return settings.find(name)->second.ivalue_to_index(values[name]);
}
/**
* Fill a map of settings with defaults.
*/
void fill_defaults(std::map<std::string, std::string>& values);
void fill_defaults(std::map<std::string, std::string>& values) throw(std::bad_alloc);
/**
* Get set of settings.
*/

View file

@ -78,6 +78,7 @@ public:
operator label&();
operator label*();
label& external(void* addr);
private:
std::list<label> labels;
};

View file

@ -46,7 +46,7 @@ public:
/**
* Create a new set.
*/
set();
set() throw(std::bad_alloc);
/**
* Destroy a set.
*/
@ -54,17 +54,17 @@ public:
/**
* Add a command to set.
*/
void do_register(const std::string& name, factory_base& cmd);
void do_register(const std::string& name, factory_base& cmd) throw(std::bad_alloc);
/**
* Remove a command from set.
*/
void do_unregister(const std::string& name, factory_base& cmd);
void do_unregister(const std::string& name, factory_base& cmd) throw(std::bad_alloc);
/**
* Add a notification callback and call ccb on all.
*
* Parameter listener: The listener to add.
*/
void add_callback(listener& listener);
void add_callback(listener& listener) throw(std::bad_alloc);
/**
* Drop a notification callback and call dcb on all.
*
@ -84,7 +84,7 @@ public:
/**
* Create a new command group. This also places some builtin commands in that new group.
*/
group();
group() throw(std::bad_alloc);
/**
* Destroy a group.
*/
@ -105,31 +105,31 @@ public:
/**
* Get set of aliases.
*/
std::set<std::string> get_aliases();
std::set<std::string> get_aliases() throw(std::bad_alloc);
/**
* Get alias
*/
std::string get_alias_for(const std::string& aname);
std::string get_alias_for(const std::string& aname) throw(std::bad_alloc);
/**
* Set alias
*/
void set_alias_for(const std::string& aname, const std::string& avalue);
void set_alias_for(const std::string& aname, const std::string& avalue) throw(std::bad_alloc);
/**
* Is alias name valid.
*/
bool valid_alias_name(const std::string& aname);
bool valid_alias_name(const std::string& aname) throw(std::bad_alloc);
/**
* Register a command.
*/
void do_register(const std::string& name, base& cmd);
void do_register(const std::string& name, base& cmd) throw(std::bad_alloc);
/**
* Unregister a command.
*/
void do_unregister(const std::string& name, base& cmd);
void do_unregister(const std::string& name, base& cmd) throw(std::bad_alloc);
/**
* Add all commands (including future ones) in given set.
*/
void add_set(set& s);
void add_set(set& s) throw(std::bad_alloc);
/**
* Drop a set of commands.
*/
@ -175,7 +175,7 @@ public:
* parameter dynamic: Should the object be freed when its parent group dies?
* throws std::bad_alloc: Not enough memory.
*/
base(group& group, const std::string& cmd, bool dynamic);
base(group& group, const std::string& cmd, bool dynamic) throw(std::bad_alloc);
/**
* Deregister a command.
@ -189,16 +189,16 @@ public:
* throws std::bad_alloc: Not enough memory.
* throws std::runtime_error: Command execution failed.
*/
virtual void invoke(const std::string& arguments) = 0;
virtual void invoke(const std::string& arguments) throw(std::bad_alloc, std::runtime_error) = 0;
/**
* Get short help for command.
*/
virtual std::string get_short_help();
virtual std::string get_short_help() throw(std::bad_alloc);
/**
* Get long help for command.
*/
virtual std::string get_long_help();
virtual std::string get_long_help() throw(std::bad_alloc);
/**
* Get name of command.
*/
@ -231,7 +231,7 @@ public:
* parameter cmd: The command to register.
* throws std::bad_alloc: Not enough memory.
*/
void _factory_base(set& _set, const std::string& cmd);
void _factory_base(set& _set, const std::string& cmd) throw(std::bad_alloc);
/**
* Destructor.
*/
@ -316,7 +316,7 @@ public:
* parameter dynamic: Should the object be freed when its parent group dies?
*/
_fnptr(group& group, const std::string& name, const std::string& _description,
const std::string& _help, void (*_fn)(args... arguments), bool dynamic = false)
const std::string& _help, void (*_fn)(args... arguments), bool dynamic = false) throw(std::bad_alloc)
: base(group, name, dynamic)
{
shorthelp = _description;
@ -331,7 +331,7 @@ public:
* parameter fn: Function to call on command.
* parameter description Description&Help for the command
*/
_fnptr(group& _group, stub _name, std::function<void(args... arguments)> _fn)
_fnptr(group& _group, stub _name, std::function<void(args... arguments)> _fn) throw(std::bad_alloc)
: base(_group, _name.name, false)
{
shorthelp = _name.desc;
@ -349,7 +349,7 @@ public:
*
* parameter a: Arguments to function.
*/
void invoke(const std::string& a)
void invoke(const std::string& a) throw(std::bad_alloc, std::runtime_error)
{
invoke_fn(fn, a);
}
@ -359,7 +359,7 @@ public:
* returns: Description.
* throw std::bad_alloc: Not enough memory.
*/
std::string get_short_help()
std::string get_short_help() throw(std::bad_alloc)
{
return shorthelp;
}
@ -369,7 +369,7 @@ public:
* returns: help.
* throw std::bad_alloc: Not enough memory.
*/
std::string get_long_help()
std::string get_long_help() throw(std::bad_alloc)
{
return help;
}
@ -393,7 +393,7 @@ public:
* parameter desc: Command descriptor.
* parameter fn: Function to call on command.
*/
fnptr(set& _set, stub _name, void (*_fn)(args... arguments))
fnptr(set& _set, stub _name, void (*_fn)(args... arguments)) throw(std::bad_alloc)
{
shorthelp = _name.desc;
name = _name.name;
@ -411,7 +411,7 @@ public:
* parameter fn: Function to call on command.
*/
fnptr(set& _set, const std::string& _name, const std::string& _description,
const std::string& _help, void (*_fn)(args... arguments))
const std::string& _help, void (*_fn)(args... arguments)) throw(std::bad_alloc)
{
shorthelp = _description;
name = _name;
@ -428,7 +428,7 @@ public:
/**
* Make a command.
*/
base* make(group& grp)
base* make(group& grp) throw(std::bad_alloc)
{
return new _fnptr<args...>(grp, name, shorthelp, help, fn, true);
}
@ -463,7 +463,7 @@ public:
/**
* Make a command.
*/
base* make(group& grp)
base* make(group& grp) throw(std::bad_alloc)
{
return new T(grp, name);
}

View file

@ -8,4 +8,4 @@ template<typename T> void eat_argument(T arg) {
_eat_argument((void*)arg2);
}
#endif
#endif

View file

@ -24,6 +24,7 @@ public:
add_ex_spec(prio, [](std::exception& e) -> bool { return (dynamic_cast<T*>(&e) != NULL); },
[](std::exception& e) -> std::function<void()> { T _ex = *dynamic_cast<T*>(&e);
return [_ex]() -> void { throw _ex; }; });
}
};

View file

@ -10,7 +10,7 @@
namespace fileimage
{
std::vector<char> patch(const std::vector<char>& original, const std::vector<char>& patch,
int32_t offset);
int32_t offset) throw(std::bad_alloc, std::runtime_error);
/**
* ROM patcher.
@ -20,7 +20,7 @@ struct patcher
/**
* Constructor.
*/
patcher();
patcher() throw(std::bad_alloc);
/**
* Destructor.
*/
@ -36,7 +36,7 @@ struct patcher
* Do the patch.
*/
virtual void dopatch(std::vector<char>& out, const std::vector<char>& original,
const std::vector<char>& patch, int32_t offset) = 0;
const std::vector<char>& patch, int32_t offset) throw(std::bad_alloc, std::runtime_error) = 0;
};
}

View file

@ -161,7 +161,7 @@ struct image
*
* throws std::bad_alloc: Not enough memory.
*/
image();
image() throw(std::bad_alloc);
/**
* This constructor construct slot by reading data from file. If filename is "", constructs an empty slot.
@ -174,7 +174,7 @@ struct image
* throws std::runtime_error: Can't load the data.
*/
image(hash& hasher, const std::string& filename, const std::string& base,
const struct info& imginfo);
const struct info& imginfo) throw(std::bad_alloc, std::runtime_error);
/**
* This method patches this slot using specified IPS patch.
@ -186,7 +186,7 @@ struct image
* throws std::bad_alloc: Not enough memory.
* throws std::runtime_error: Bad IPS patch, or trying to patch file image.
*/
void patch(const std::vector<char>& patch, int32_t offset);
void patch(const std::vector<char>& patch, int32_t offset) throw(std::bad_alloc, std::runtime_error);
/**
* Type.
*/

View file

@ -3,7 +3,6 @@
#include <vector>
#include <cstdint>
#include <functional>
#include <cstdlib>
#include <iostream>
#include <stdexcept>
@ -25,20 +24,15 @@ public:
std::vector<uint32_t> fglyph; //Bitpacked, element breaks between rows.
void render(fb<false>& fb, int32_t x, int32_t y, color fg, color bg, color hl) const;
void render(fb<true>& fb, int32_t x, int32_t y, color fg, color bg, color hl) const;
void render(uint8_t* buf, size_t stride, uint32_t u, uint32_t v, uint32_t w, uint32_t h) const;
void dump(std::ostream& s) const;
};
font2();
font2(const std::string& file);
font2(struct font& bfont);
void add(const std::u32string& key, const glyph& fglyph);
std::u32string best_ligature_match(const std::u32string& codepoints, size_t start) const;
void add(const std::u32string& key, const glyph& fglyph) throw(std::bad_alloc);
std::u32string best_ligature_match(const std::u32string& codepoints, size_t start) const
throw(std::bad_alloc);
const glyph& lookup_glyph(const std::u32string& key) const throw();
unsigned get_rowadvance() const throw() { return rowadvance; }
std::pair<uint32_t, uint32_t> get_metrics(const std::u32string& str, uint32_t xalign) const;
void for_each_glyph(const std::u32string& str, uint32_t xalign, std::function<void(uint32_t x, uint32_t y,
const glyph& g)> cb) const;
void dump(const std::string& file) const;
private:
std::map<std::u32string, glyph> glyphs;
unsigned rowadvance;

View file

@ -19,9 +19,9 @@ public:
void decode(uint64_t* target, const uint8_t* src, size_t width,
const auxpalette<true>& auxp) throw();
void set_palette(auxpalette<false>& auxp, uint8_t rshift, uint8_t gshift,
uint8_t bshift);
uint8_t bshift) throw(std::bad_alloc);
void set_palette(auxpalette<true>& auxp, uint8_t rshift, uint8_t gshift,
uint8_t bshift);
uint8_t bshift) throw(std::bad_alloc);
uint8_t get_bpp() throw();
uint8_t get_ss_bpp() throw();
uint32_t get_magic() throw();

View file

@ -20,9 +20,9 @@ public:
void decode(uint64_t* target, const uint8_t* src, size_t width,
const auxpalette<true>& auxp) throw();
void set_palette(auxpalette<false>& auxp, uint8_t rshift, uint8_t gshift,
uint8_t bshift);
uint8_t bshift) throw(std::bad_alloc);
void set_palette(auxpalette<true>& auxp, uint8_t rshift, uint8_t gshift,
uint8_t bshift);
uint8_t bshift) throw(std::bad_alloc);
uint8_t get_bpp() throw();
uint8_t get_ss_bpp() throw();
uint32_t get_magic() throw();

View file

@ -20,9 +20,9 @@ public:
void decode(uint64_t* target, const uint8_t* src, size_t width,
const auxpalette<true>& auxp) throw();
void set_palette(auxpalette<false>& auxp, uint8_t rshift, uint8_t gshift,
uint8_t bshift);
uint8_t bshift) throw(std::bad_alloc);
void set_palette(auxpalette<true>& auxp, uint8_t rshift, uint8_t gshift,
uint8_t bshift);
uint8_t bshift) throw(std::bad_alloc);
uint8_t get_bpp() throw();
uint8_t get_ss_bpp() throw();
uint32_t get_magic() throw();

View file

@ -20,9 +20,9 @@ public:
void decode(uint64_t* target, const uint8_t* src, size_t width,
const auxpalette<true>& auxp) throw();
void set_palette(auxpalette<false>& auxp, uint8_t rshift, uint8_t gshift,
uint8_t bshift);
uint8_t bshift) throw(std::bad_alloc);
void set_palette(auxpalette<true>& auxp, uint8_t rshift, uint8_t gshift,
uint8_t bshift);
uint8_t bshift) throw(std::bad_alloc);
uint8_t get_bpp() throw();
uint8_t get_ss_bpp() throw();
uint32_t get_magic() throw();

View file

@ -19,9 +19,9 @@ public:
void decode(uint64_t* target, const uint8_t* src, size_t width,
const auxpalette<true>& auxp) throw();
void set_palette(auxpalette<false>& auxp, uint8_t rshift, uint8_t gshift,
uint8_t bshift);
uint8_t bshift) throw(std::bad_alloc);
void set_palette(auxpalette<true>& auxp, uint8_t rshift, uint8_t gshift,
uint8_t bshift);
uint8_t bshift) throw(std::bad_alloc);
uint8_t get_bpp() throw();
uint8_t get_ss_bpp() throw();
uint32_t get_magic() throw();

View file

@ -19,7 +19,7 @@ public:
/**
* Register the pixel format.
*/
pixfmt();
pixfmt() throw(std::bad_alloc);
/**
* Decode pixel format data into RGB data (0, R, G, B).
*/
@ -39,12 +39,12 @@ public:
* Create aux palette.
*/
virtual void set_palette(auxpalette<false>& auxp, uint8_t rshift, uint8_t gshift,
uint8_t bshift) = 0;
uint8_t bshift) throw(std::bad_alloc) = 0;
/**
* Create aux palette.
*/
virtual void set_palette(auxpalette<true>& auxp, uint8_t rshift, uint8_t gshift,
uint8_t bshift) = 0;
uint8_t bshift) throw(std::bad_alloc) = 0;
/**
* Bytes per pixel in data.
*/

View file

@ -8,12 +8,9 @@
#include <map>
#include <set>
#include "framebuffer-pixfmt.hpp"
#include "threads.hpp"
#include "memtracker.hpp"
namespace framebuffer
{
extern const char* render_page_id;
template<bool X> struct elem {};
template<> struct elem<false> { typedef uint32_t t; };
template<> struct elem<true> { typedef uint64_t t; };
@ -100,13 +97,13 @@ struct raw
*
* Parameter info: The framebuffer info.
*/
raw(const info& finfo);
raw(const info& finfo) throw(std::bad_alloc);
/**
* Create a new framebuffer backed by memory buffer.
*
* The resulting framebuffer can be written to.
*/
raw();
raw() throw(std::bad_alloc);
/**
* Copy a framebuffer.
*
@ -114,34 +111,34 @@ struct raw
*
* Parameter f: The framebuffer.
*/
raw(const raw& f);
raw(const raw& f) throw(std::bad_alloc);
/**
* Assign a framebuffer.
*
* Parameter f: The framebuffer.
* Throws std::runtime_error: The target framebuffer is not writable.
*/
raw& operator=(const raw& f);
raw& operator=(const raw& f) throw(std::bad_alloc, std::runtime_error);
/**
* Load contents of framebuffer.
*
* parameter data: The data to load.
* throws std::runtime_error: The target framebuffer is not writable.
*/
void load(const std::vector<char>& data);
void load(const std::vector<char>& data) throw(std::bad_alloc, std::runtime_error);
/**
* Save contents of framebuffer.
*
* parameter data: The vector to write the data to (in format compatible with load()).
*/
void save(std::vector<char>& data);
void save(std::vector<char>& data) throw(std::bad_alloc);
/**
* Save contents of framebuffer as a PNG.
*
* parameter file: The filename to save to.
* throws std::runtime_error: Can't save the PNG.
*/
void save_png(const std::string& file);
void save_png(const std::string& file) throw(std::bad_alloc, std::runtime_error);
/**
* Get width.
*
@ -226,7 +223,7 @@ struct fb
* parameter upside_down: If true, image is upside down in memory.
* throws std::bad_alloc: Not enough memory.
*/
void reallocate(size_t _width, size_t _height, bool upside_down = false);
void reallocate(size_t _width, size_t _height, bool upside_down = false) throw(std::bad_alloc);
/**
* Set origin
@ -278,7 +275,7 @@ struct fb
* parameter g Shift for green component
* parameter b Shift for blue component
*/
void set_palette(uint32_t r, uint32_t g, uint32_t b);
void set_palette(uint32_t r, uint32_t g, uint32_t b) throw(std::bad_alloc);
/**
* Get stride of image.
*
@ -375,7 +372,7 @@ struct object
/**
* Clone the object.
*/
virtual void clone(struct queue& q) const = 0;
virtual void clone(struct queue& q) const throw(std::bad_alloc) = 0;
};
/**
@ -422,7 +419,7 @@ struct color
set_palette(default_shift_r << 1, default_shift_g << 1, default_shift_b << 1, true);
//std::cerr << "Color " << color << " -> hi=" << hi << " lo=" << lo << " inv=" << inv << std::endl;
}
color(const std::string& color);
color(const std::string& color) throw(std::bad_alloc, std::runtime_error);
static std::string stringify(int64_t number);
void set_palette(unsigned rshift, unsigned gshift, unsigned bshift, bool X) throw();
template<bool X> void set_palette(struct fb<X>& s) throw()
@ -494,16 +491,6 @@ struct font
bool wide; //If set, 16 wide instead of 8.
uint32_t* data; //Glyph data. Bitpacked with element padding between rows.
size_t offset; //Glyph offset.
uint32_t get_width() const throw() { return wide ? 16 : 8; }
uint32_t get_height() const throw() { return 16; }
bool read_pixel(uint32_t x, uint32_t y) const throw()
{
if(wide) {
return ((data[y >> 1] >> (31 - (((y & 1) << 4) + x))) & 1) != 0;
} else {
return ((data[y >> 2] >> (31 - (((y & 3) << 3) + x))) & 1) != 0;
}
}
};
/**
@ -518,7 +505,7 @@ struct font
/**
* Constructor.
*/
font();
font() throw(std::bad_alloc);
/**
* Load a .hex format font.
*
@ -526,7 +513,7 @@ struct font
* Parameter size: The font data size in bytes.
* Throws std::runtime_error: Bad font data.
*/
void load_hex(const char* data, size_t size);
void load_hex(const char* data, size_t size) throw(std::bad_alloc, std::runtime_error);
/**
* Locate glyph.
*
@ -540,22 +527,14 @@ struct font
* Parameter string: The string to get metrics of.
* Returns: A pair. First element is width of string, the second is height of string.
*/
std::pair<size_t, size_t> get_metrics(const std::string& string, uint32_t xalign, bool xdbl, bool ydbl)
throw();
std::pair<size_t, size_t> get_metrics(const std::string& string) throw();
/**
* Layout a string.
*
* Parameter string: The string to get layout of.
* Returns: String layout.
*/
std::vector<layout> dolayout(const std::string& string);
/**
* Get width of string.
*
* Parameter string: The string to get width of.
* Returns: The width.
*/
uint32_t get_width(const std::string& string);
std::vector<layout> dolayout(const std::string& string) throw(std::bad_alloc);
/**
* Get set of all glyph numbers.
*/
@ -578,33 +557,13 @@ struct font
*/
template<bool X> void render(struct fb<X>& scr, int32_t x, int32_t y, const std::string& text,
color fg, color bg, bool hdbl, bool vdbl) throw();
/**
* Call function on every glyph.
*
* Parameter str: The string to call on.
* Parameter alignx: The x alignment.
* Parameter cb: The callback to call.
*/
void for_each_glyph(const std::string& str, uint32_t alignx, bool xdbl, bool ydbl,
std::function<void(uint32_t x, uint32_t y, const glyph& g, bool xdbl, bool ydbl)> cb);
/**
* Render to bitmap.
*
* Parameter buf: The bufer to render on.
* Parameter stride: The stride on buffer.
* Parameter str: The string to render.
* Parameter alignx: The x alignment.
* Parameter hdbl: If set, double width horizontally.
* Parameter vdbl: If set, double height vertically.
*/
void render(uint8_t* buf, size_t stride, const std::string& str, uint32_t alignx, bool hdbl, bool vdbl);
private:
glyph bad_glyph;
uint32_t bad_glyph_data[4];
std::map<uint32_t, glyph> glyphs;
size_t tabstop;
std::vector<uint32_t> memory;
void load_hex_glyph(const char* data, size_t size);
void load_hex_glyph(const char* data, size_t size) throw(std::bad_alloc, std::runtime_error);
};
@ -633,7 +592,7 @@ struct queue
/**
* Get memory from internal allocator.
*/
void* alloc(size_t block);
void* alloc(size_t block) throw(std::bad_alloc);
/**
* Call object constructor on internal memory.
@ -645,7 +604,7 @@ struct queue
/**
* Copy objects from another render queue.
*/
void copy_from(queue& q);
void copy_from(queue& q) throw(std::bad_alloc);
/**
* Helper for clone.
*/
@ -675,20 +634,14 @@ struct queue
*/
~queue() throw();
private:
void add(struct object& obj);
void add(struct object& obj) throw(std::bad_alloc);
struct node { struct object* obj; struct node* next; bool killed; };
struct page {
char content[RENDER_PAGE_SIZE];
page() { memtracker::singleton()(render_page_id, RENDER_PAGE_SIZE + 36); }
~page() { memtracker::singleton()(render_page_id, -RENDER_PAGE_SIZE - 36); }
};
struct page { char content[RENDER_PAGE_SIZE]; };
struct node* queue_head;
struct node* queue_tail;
size_t memory_allocated;
size_t pages;
threads::lock display_mutex; //Synchronize display and kill.
std::map<size_t, page> memory;
memtracker::autorelease tracker;
};
/**

View file

@ -1,7 +1,6 @@
#ifndef _library__gamepad__hpp__included__
#define _library__gamepad__hpp__included__
#include <functional>
#include <cstdint>
#include <set>
#include "json.hpp"

View file

@ -13,7 +13,7 @@ public:
/**
* Ctor, forces the object to be constructed (to avoid races).
*/
globalwrap()
globalwrap() throw(std::bad_alloc)
{
(*this)();
}
@ -23,7 +23,7 @@ public:
* returns: The wrapped object.
* throws std::bad_alloc: Not enough memory.
*/
T& operator()()
T& operator()() throw(std::bad_alloc)
{
if(!storage) {
if(!state) //State initializes to 0.

View file

@ -17,7 +17,7 @@ namespace hex
* Returns: Hex string.
* Throws std::bad_alloc: Not enough memory.
*/
std::string b_to(const uint8_t* data, size_t datalen, bool uppercase = false);
std::string b_to(const uint8_t* data, size_t datalen, bool uppercase = false) throw(std::bad_alloc);
/**
* Transform unsigned integer into full-width hexadecimal.
@ -27,7 +27,7 @@ std::string b_to(const uint8_t* data, size_t datalen, bool uppercase = false);
* Returns: The hex string.
* Throws std::bad_alloc: Not enough memory.
*/
template<typename T> std::string to(T data, bool prefix = false);
template<typename T> std::string to(T data, bool prefix = false) throw(std::bad_alloc);
/**
* Transform uint8 into full-width hexadecimal.
@ -37,7 +37,7 @@ template<typename T> std::string to(T data, bool prefix = false);
* Returns: The hex string.
* Throws std::bad_alloc: Not enough memory.
*/
inline std::string to8(uint8_t data, bool prefix = false) { return to<uint8_t>(data, prefix); }
inline std::string to8(uint8_t data, bool prefix = false) throw(std::bad_alloc) { return to<uint8_t>(data, prefix); }
/**
* Transform uint16 into full-width hexadecimal.
@ -47,7 +47,7 @@ inline std::string to8(uint8_t data, bool prefix = false) { return to<uint8_t>(d
* Returns: The hex string.
* Throws std::bad_alloc: Not enough memory.
*/
inline std::string to16(uint16_t data, bool prefix = false)
inline std::string to16(uint16_t data, bool prefix = false) throw(std::bad_alloc)
{
return to<uint16_t>(data, prefix);
}
@ -60,7 +60,7 @@ inline std::string to16(uint16_t data, bool prefix = false)
* Returns: The hex string.
* Throws std::bad_alloc: Not enough memory.
*/
std::string to24(uint32_t data, bool prefix = false);
std::string to24(uint32_t data, bool prefix = false) throw(std::bad_alloc);
/**
* Transform uint32 into full-width hexadecimal.
@ -70,7 +70,7 @@ std::string to24(uint32_t data, bool prefix = false);
* Returns: The hex string.
* Throws std::bad_alloc: Not enough memory.
*/
inline std::string to32(uint32_t data, bool prefix = false)
inline std::string to32(uint32_t data, bool prefix = false) throw(std::bad_alloc)
{
return to<uint32_t>(data, prefix);
}
@ -83,7 +83,7 @@ inline std::string to32(uint32_t data, bool prefix = false)
* Returns: The hex string.
* Throws std::bad_alloc: Not enough memory.
*/
inline std::string to64(uint64_t data, bool prefix = false)
inline std::string to64(uint64_t data, bool prefix = false) throw(std::bad_alloc)
{
return to<uint64_t>(data, prefix);
}
@ -95,7 +95,7 @@ inline std::string to64(uint64_t data, bool prefix = false)
* Parameter hex: The hexadecimal string.
* Throws std::runtime_error: Bad hexadecimal character in string.
*/
void b_from(uint8_t* buf, const std::string& hex);
void b_from(uint8_t* buf, const std::string& hex) throw(std::runtime_error);
/**
* Transform hexadecimal into unsigned integer.
@ -103,7 +103,7 @@ void b_from(uint8_t* buf, const std::string& hex);
* Parameter hex: The hexadecimal string.
* Throws std::runtime_error: Bad hexadecimal character in string.
*/
template<typename T> T from(const std::string& hex);
template<typename T> T from(const std::string& hex) throw(std::runtime_error);
}
#endif

View file

@ -6,7 +6,6 @@
#include <cstdlib>
#include <map>
#include <string>
#include <functional>
#include "threads.hpp"
class http_request
@ -120,7 +119,7 @@ public:
/**
* Get final code.
*/
uint32_t get_http_code();
long get_http_code();
private:
static int progress(void* userdata, double dltotal, double dlnow, double ultotal, double ulnow);
int _progress(double dltotal, double dlnow, double ultotal, double ulnow);
@ -146,7 +145,7 @@ struct http_async_request
int64_t final_dl; //Final amount downloaded (OUTPUT).
int64_t final_ul; //Final amound uploaded (OUTPUT).
std::string errormsg; //Final error (OUTPUT).
uint32_t http_code; //HTTP error code (OUTPUT).
long http_code; //HTTP error code (OUTPUT).
volatile bool finished; //Finished flag (semi-transient).
threads::cv finished_cond; //This condition variable is fired on finish.
http_request* req; //The HTTP request object (TRANSIENT).

View file

@ -40,9 +40,4 @@ private:
char v[3];
};
template<typename T> struct is_ss_int24 { const static bool flag = false; };
template<> struct is_ss_int24<ss_uint24_t> { const static bool flag = true; };
template<> struct is_ss_int24<ss_int24_t> { const static bool flag = true; };
#endif

View file

@ -21,7 +21,7 @@ public:
* Returns: The number drawn.
* Throws std::bad_alloc: Not enough memory.
*/
uint64_t operator()();
uint64_t operator()() throw(std::bad_alloc);
/**
* Return a number into the pool.
*

View file

@ -182,21 +182,21 @@ class pointer
{
public:
pointer();
pointer(const std::string& ptr);
pointer(const std::u32string& ptr);
pointer pastend() const { return field(U"-"); }
pointer& pastend_inplace() { return field_inplace(U"-"); }
pointer index(uint64_t idx) const;
pointer& index_inplace(uint64_t idx);
pointer field(const std::string& fld) const { return field(utf8::to32(fld)); }
pointer& field_inplace(const std::string& fld)
pointer(const std::string& ptr) throw(std::bad_alloc);
pointer(const std::u32string& ptr) throw(std::bad_alloc);
pointer pastend() const throw(std::bad_alloc) { return field(U"-"); }
pointer& pastend_inplace() throw(std::bad_alloc) { return field_inplace(U"-"); }
pointer index(uint64_t idx) const throw(std::bad_alloc);
pointer& index_inplace(uint64_t idx) throw(std::bad_alloc);
pointer field(const std::string& fld) const throw(std::bad_alloc) { return field(utf8::to32(fld)); }
pointer& field_inplace(const std::string& fld) throw(std::bad_alloc)
{
return field_inplace(utf8::to32(fld));
}
pointer field(const std::u32string& fld) const;
pointer& field_inplace(const std::u32string& fld);
pointer remove() const;
pointer& remove_inplace();
pointer field(const std::u32string& fld) const throw(std::bad_alloc);
pointer& field_inplace(const std::u32string& fld) throw(std::bad_alloc);
pointer remove() const throw(std::bad_alloc);
pointer& remove_inplace() throw(std::bad_alloc);
std::string as_string8() const { return utf8::to8(_pointer); }
std::u32string as_string() const { return _pointer; }
friend std::ostream& operator<<(std::ostream& s, const pointer& p);
@ -273,7 +273,7 @@ private:
size_t depth;
enum _state
{
S_STANDARD,
S_NORMAL,
S_END,
S_COMMA,
S_START,
@ -299,8 +299,8 @@ public:
*/
node(null_tag) throw();
node(boolean_tag, bool b) throw();
node(string_tag, const std::u32string& str);
node(string_tag, const std::string& str);
node(string_tag, const std::u32string& str) throw(std::bad_alloc);
node(string_tag, const std::string& str) throw(std::bad_alloc);
node(number_tag, double n) throw();
node(number_tag, int64_t n) throw();
node(number_tag, uint64_t n) throw();
@ -314,15 +314,15 @@ public:
/**
* Copy Constructor.
*/
node(const node& _node);
node(const node& _node) throw(std::bad_alloc);
/**
* Construct object from description.
*/
node(const std::string& doc);
node(const std::string& doc) throw(std::bad_alloc, error);
/**
* Serialize document.
*/
std::string serialize(printer* printer = NULL) const;
std::string serialize(printer* printer = NULL) const throw(std::bad_alloc, error);
/**
* Get type of node.
*/
@ -330,68 +330,68 @@ public:
/**
* Get type of node by pointer.
*/
int type_of(const std::u32string& pointer) const;
int type_of(const std::string& pointer) const
int type_of(const std::u32string& pointer) const throw(std::bad_alloc);
int type_of(const std::string& pointer) const throw(std::bad_alloc)
{
return type_of(utf8::to32(pointer));
}
int type_of(const pointer& ptr) const
int type_of(const pointer& ptr) const throw(std::bad_alloc)
{
return type_of(ptr._pointer);
}
/**
* Get type of node by pointer (indirect).
*/
int type_of_indirect(const std::u32string& pointer) const;
int type_of_indirect(const std::string& pointer) const
int type_of_indirect(const std::u32string& pointer) const throw(std::bad_alloc);
int type_of_indirect(const std::string& pointer) const throw(std::bad_alloc)
{
return type_of_indirect(utf8::to32(pointer));
}
int type_of_indirect(const pointer& ptr) const
int type_of_indirect(const pointer& ptr) const throw(std::bad_alloc)
{
return type_of_indirect(ptr._pointer);
}
/**
* Resolve an indirect pointer
*/
std::u32string resolve_indirect(const std::u32string& pointer) const;
std::string resolve_indirect(const std::string& pointer) const
std::u32string resolve_indirect(const std::u32string& pointer) const throw(std::bad_alloc);
std::string resolve_indirect(const std::string& pointer) const throw(std::bad_alloc)
{
return utf8::to8(resolve_indirect(utf8::to32(pointer)));
}
pointer resolve_indirect(const pointer& ptr) const
pointer resolve_indirect(const pointer& ptr) const throw(std::bad_alloc)
{
return pointer(resolve_indirect(ptr._pointer));
}
/**
* Get double numeric value (NT_NUMBER).
*/
double as_double() const;
double as_double() const throw(error);
/**
* Get int64_t value (NT_NUMBER).
*/
int64_t as_int() const;
int64_t as_int() const throw(error);
/**
* Get uint64_t value (NT_NUMBER).
*/
uint64_t as_uint() const;
uint64_t as_uint() const throw(error);
/**
* Read the string as UTF-8 (NT_STRING).
*/
const std::u32string& as_string() const;
std::string as_string8() const { return utf8::to8(as_string()); }
const std::u32string& as_string() const throw(std::bad_alloc, error);
std::string as_string8() const throw(std::bad_alloc, error) { return utf8::to8(as_string()); }
/**
* Get boolean value (NT_BOOLEAN).
*/
bool as_bool() const;
bool as_bool() const throw(error);
/**
* Read number of indices in array (NT_ARRAY).
*/
size_t index_count() const;
size_t index_count() const throw(error);
/**
* Read specified index from array (NT_ARRAY).
*/
const node& index(size_t idx) const
const node& index(size_t idx) const throw(error)
{
const node* n;
auto e = index_soft(idx, n);
@ -401,30 +401,30 @@ public:
/**
* Read number of indices in object key (NT_OBJECT).
*/
size_t field_count(const std::u32string& key) const;
size_t field_count(const std::string& key) const
size_t field_count(const std::u32string& key) const throw(error);
size_t field_count(const std::string& key) const throw(std::bad_alloc, error)
{
return field_count(utf8::to32(key));
}
/**
* Specified field exists (NT_OBJECT)
*/
bool field_exists(const std::u32string& key) const;
bool field_exists(const std::string& key) const
bool field_exists(const std::u32string& key) const throw(error);
bool field_exists(const std::string& key) const throw(std::bad_alloc, error)
{
return field_exists(utf8::to32(key));
}
/**
* Read specified key from object (NT_OBJECT).
*/
const node& field(const std::u32string& key, size_t subindex = 0) const
const node& field(const std::u32string& key, size_t subindex = 0) const throw(error)
{
const node* n;
auto e = field_soft(key, subindex, n);
if(e != ERR_OK) throw error(e);
return *n;
}
const node& field(const std::string& key, size_t subindex = 0) const
const node& field(const std::string& key, size_t subindex = 0) const throw(std::bad_alloc, error)
{
return field(utf8::to32(key), subindex);
}
@ -432,40 +432,40 @@ public:
/**
* Apply JSON pointer (RFC 6901).
*/
const node& follow(const std::u32string& pointer) const
const node& follow(const std::u32string& pointer) const throw(std::bad_alloc, error)
{
const node* n;
auto e = follow_soft(pointer, n);
if(e != ERR_OK) throw error(e);
return *n;
}
const node& follow(const std::string& pointer) const
const node& follow(const std::string& pointer) const throw(std::bad_alloc, error)
{
return follow(utf8::to32(pointer));
}
const node& follow(const pointer& ptr) const
const node& follow(const pointer& ptr) const throw(std::bad_alloc, error)
{
return follow(ptr._pointer);
}
/**
* Apply JSON pointer (RFC 6901) following strings as indirect references.
*/
const node& follow_indirect(const std::u32string& pointer) const
const node& follow_indirect(const std::u32string& pointer) const throw(std::bad_alloc, error)
{
return follow(resolve_indirect(pointer));
}
const node& follow_indirect(const std::string& pointer) const
const node& follow_indirect(const std::string& pointer) const throw(std::bad_alloc, error)
{
return follow_indirect(utf8::to32(pointer));
}
const node& follow_indirect(const pointer& ptr) const
const node& follow_indirect(const pointer& ptr) const throw(std::bad_alloc, error)
{
return follow_indirect(ptr._pointer);
}
/**
* Set value of node (any).
*/
node& operator=(const node& node);
node& operator=(const node& node) throw(std::bad_alloc);
/**
* Set value of node.
*/
@ -474,15 +474,15 @@ public:
node& set(number_tag, double number) throw();
node& set(number_tag, int64_t number) throw();
node& set(number_tag, uint64_t number) throw();
node& set(string_tag, const std::u32string& key);
node& set(string_tag tag, const std::string& key)
node& set(string_tag, const std::u32string& key) throw(std::bad_alloc);
node& set(string_tag tag, const std::string& key) throw(std::bad_alloc)
{
return set(tag, utf8::to32(key));
}
/**
* Read/Write specified index from array (NT_ARRAY).
*/
node& index(size_t idx)
node& index(size_t idx) throw(error)
{
node* n;
auto e = index_soft(idx, n);
@ -492,141 +492,141 @@ public:
/**
* Append new element to array (NT_ARRAY).
*/
node& append(const node& node);
node& append(const node& node) throw(std::bad_alloc, error);
/**
* Read/Write specified key from object (NT_OBJECT).
*/
node& field(const std::u32string& key, size_t subindex = 0)
node& field(const std::u32string& key, size_t subindex = 0) throw(error)
{
node* n;
auto e = field_soft(key, subindex, n);
if(e != ERR_OK) throw error(e);
return *n;
}
node& field(const std::string& key, size_t subindex = 0)
node& field(const std::string& key, size_t subindex = 0) throw(std::bad_alloc, error)
{
return field(utf8::to32(key), subindex);
}
/**
* Insert new element to object (NT_OBJECT).
*/
node& insert(const std::u32string& key, const node& node);
node& insert(const std::string& key, const node& node)
node& insert(const std::u32string& key, const node& node) throw(std::bad_alloc, error);
node& insert(const std::string& key, const node& node) throw(std::bad_alloc, error)
{
return insert(utf8::to32(key), node);
}
/**
* Apply JSON pointer (RFC 6901).
*/
node& follow(const std::u32string& pointer)
node& follow(const std::u32string& pointer) throw(std::bad_alloc, error)
{
node* n;
auto e = follow_soft(pointer, n);
if(e != ERR_OK) throw error(e);
return *n;
}
node& follow(const std::string& pointer)
node& follow(const std::string& pointer) throw(std::bad_alloc, error)
{
return follow(utf8::to32(pointer));
}
node& follow(const pointer& ptr)
node& follow(const pointer& ptr) throw(std::bad_alloc, error)
{
return follow(ptr._pointer);
}
/**
* Apply JSON pointer (RFC 6901) following strings as indirect references.
*/
node& follow_indirect(const std::u32string& pointer)
node& follow_indirect(const std::u32string& pointer) throw(std::bad_alloc, error)
{
return follow(resolve_indirect(pointer));
}
node& follow_indirect(const std::string& pointer)
node& follow_indirect(const std::string& pointer) throw(std::bad_alloc, error)
{
return follow_indirect(utf8::to32(pointer));
}
node& follow_indirect(const pointer& ptr)
node& follow_indirect(const pointer& ptr) throw(std::bad_alloc, error)
{
return follow_indirect(ptr._pointer);
}
/**
* Return node specified by JSON pointer (RFC 6901). If the last component doesn't exist, it is created as NULL.
*/
node& operator[](const std::u32string& pointer);
node& operator[](const std::string& pointer)
node& operator[](const std::u32string& pointer) throw(std::bad_alloc, error);
node& operator[](const std::string& pointer) throw(std::bad_alloc, error)
{
return (*this)[utf8::to32(pointer)];
}
node& operator[](const pointer& ptr)
node& operator[](const pointer& ptr) throw(std::bad_alloc, error)
{
return (*this)[ptr._pointer];
}
/**
* Create node at specified pointer and return it.
*/
node& insert_node(const std::u32string& pointer, const node& nwn);
node& insert_node(const std::string& pointer, const node& nwn)
node& insert_node(const std::u32string& pointer, const node& nwn) throw(std::bad_alloc, error);
node& insert_node(const std::string& pointer, const node& nwn) throw(std::bad_alloc, error)
{
return insert_node(utf8::to32(pointer), nwn);
}
node& insert_node(const pointer& ptr, const node& nwn)
node& insert_node(const pointer& ptr, const node& nwn) throw(std::bad_alloc, error)
{
return insert_node(ptr._pointer, nwn);
}
/**
* Delete a node by pointer and return what was deleted.
*/
node delete_node(const std::u32string& pointer);
node delete_node(const std::string& pointer)
node delete_node(const std::u32string& pointer) throw(std::bad_alloc, error);
node delete_node(const std::string& pointer) throw(std::bad_alloc, error)
{
return delete_node(utf8::to32(pointer));
}
node delete_node(const pointer& ptr)
node delete_node(const pointer& ptr) throw(std::bad_alloc, error)
{
return delete_node(ptr._pointer);
}
/**
* Synonym for follow().
*/
const node& operator[](const std::u32string& pointer) const
const node& operator[](const std::u32string& pointer) const throw(std::bad_alloc, error)
{
return follow(pointer);
}
const node& operator[](const std::string& pointer) const
const node& operator[](const std::string& pointer) const throw(std::bad_alloc, error)
{
return follow(pointer);
}
const node& operator[](const pointer& ptr) const
const node& operator[](const pointer& ptr) const throw(std::bad_alloc, error)
{
return follow(ptr._pointer);
}
/**
* Delete an array index. The rest are shifted.
*/
void erase_index(size_t idx);
void erase_index(size_t idx) throw(error);
/**
* Delete an array field. The rest are shifted.
*/
void erase_field(const std::u32string& fld, size_t idx = 0);
void erase_field(const std::string& fld, size_t idx = 0)
void erase_field(const std::u32string& fld, size_t idx = 0) throw(error);
void erase_field(const std::string& fld, size_t idx = 0) throw(std::bad_alloc, error)
{
erase_field(utf8::to32(fld), idx);
}
/**
* Delete an entiere array field.
*/
void erase_field_all(const std::u32string& fld);
void erase_field_all(const std::string& fld)
void erase_field_all(const std::u32string& fld) throw(error);
void erase_field_all(const std::string& fld) throw(std::bad_alloc, error)
{
erase_field_all(utf8::to32(fld));
}
/**
* Apply a JSON patch.
*/
node patch(const node& patch) const;
node patch(const node& patch) const throw(std::bad_alloc, error);
/**
* Clear entiere array or object.
*/
void clear();
void clear() throw(error);
/**
* Iterator.
*/
@ -639,14 +639,14 @@ public:
typedef node& reference;
typedef node* pointer;
iterator() throw();
iterator(node& n);
std::u32string key();
std::string key8() { return utf8::to8(key()); }
size_t index();
node& operator*();
node* operator->();
iterator operator++(int);
iterator& operator++();
iterator(node& n) throw(error);
std::u32string key() throw(std::bad_alloc, error);
std::string key8() throw(std::bad_alloc, error) { return utf8::to8(key()); }
size_t index() throw(error);
node& operator*() throw(error);
node* operator->() throw(error);
iterator operator++(int) throw(error);
iterator& operator++() throw(error);
bool operator==(const iterator& i) throw();
bool operator!=(const iterator& i) throw();
private:
@ -667,14 +667,14 @@ public:
typedef const node& reference;
typedef const node* pointer;
const_iterator() throw();
const_iterator(const node& n);
std::u32string key();
std::string key8() { return utf8::to8(key()); }
size_t index();
const node& operator*();
const node* operator->();
const_iterator operator++(int);
const_iterator& operator++();
const_iterator(const node& n) throw(error);
std::u32string key() throw(std::bad_alloc, error);
std::string key8() throw(std::bad_alloc, error) { return utf8::to8(key()); }
size_t index() throw(error);
const node& operator*() throw(error);
const node* operator->() throw(error);
const_iterator operator++(int) throw(error);
const_iterator& operator++() throw(error);
bool operator==(const const_iterator& i) throw();
bool operator!=(const const_iterator& i) throw();
private:
@ -685,14 +685,14 @@ public:
/**
* Iterators
*/
const_iterator begin() const { return const_iterator(*this); }
const_iterator begin() const throw(error) { return const_iterator(*this); }
const_iterator end() const throw() { return const_iterator(); }
iterator begin() { return iterator(*this); }
iterator begin() throw(error) { return iterator(*this); }
iterator end() throw() { return iterator(); }
/**
* Delete item pointed by iterator. The rest are shifted and new iterator is returned.
*/
iterator erase(iterator itr);
iterator erase(iterator itr) throw(error);
private:
class number_holder
{
@ -723,8 +723,8 @@ private:
friend class iterator;
friend class const_iterator;
void fixup_nodes(const node& _node);
void ctor(const std::string& doc, size_t& ptr, size_t len);
node(const std::string& doc, size_t& ptr, size_t len);
void ctor(const std::string& doc, size_t& ptr, size_t len) throw(std::bad_alloc, error);
node(const std::string& doc, size_t& ptr, size_t len) throw(std::bad_alloc, error);
template<typename T> void set_helper(T v)
{
std::u32string tmp;
@ -748,8 +748,8 @@ private:
std::list<node> xarray;
std::vector<node*> xarray_index;
std::map<std::u32string, std::list<node>> xobject;
errorcode follow_soft(const std::u32string& pointer, const node*& out) const;
errorcode follow_soft(const std::u32string& pointer, node*& out);
errorcode follow_soft(const std::u32string& pointer, const node*& out) const throw(std::bad_alloc);
errorcode follow_soft(const std::u32string& pointer, node*& out) throw(std::bad_alloc);
errorcode field_soft(const std::u32string& key, size_t subindex, node*& out) throw();
errorcode field_soft(const std::u32string& key, size_t subindex, const node*& out) const throw();
errorcode index_soft(size_t index, node*& out) throw();

View file

@ -18,7 +18,7 @@ class invbind;
class ctrlrkey;
std::pair<key*, unsigned> keymapper_lookup_subkey(keyboard& kbd, const std::string& name,
bool axis);
bool axis) throw(std::bad_alloc, std::runtime_error);
/**
* Key specifier
@ -28,17 +28,17 @@ struct keyspec
/**
* Create a new key specifier (invalid).
*/
keyspec();
keyspec() throw(std::bad_alloc);
/**
* Create a new key specifier from keyspec.
*
* Parameter keyspec: The key specifier.
*/
keyspec(const std::string& keyspec);
keyspec(const std::string& keyspec) throw(std::bad_alloc, std::runtime_error);
/**
* Get the key specifier as a keyspec.
*/
operator std::string();
operator std::string() throw(std::bad_alloc);
/**
* Is valid?
*/
@ -126,7 +126,7 @@ public:
/**
* Add a callback on new invese bind.
*/
void add_callback(listener& listener);
void add_callback(listener& listener) throw(std::bad_alloc);
/**
* Drop a callback on new inverse bind.
*/
@ -142,7 +142,7 @@ public:
/**
* Create new keyboard mapper.
*/
mapper(keyboard& kbd, command::group& domain);
mapper(keyboard& kbd, command::group& domain) throw(std::bad_alloc);
/**
* Destroy a keyboard mapper.
*/
@ -157,7 +157,8 @@ public:
* throws std::bad_alloc: Not enough memory.
* throws std::runtime_error: The binding would conflict with existing one or invalid modifier/key.
*/
void bind(std::string mod, std::string modmask, std::string keyname, std::string command);
void bind(std::string mod, std::string modmask, std::string keyname, std::string command)
throw(std::bad_alloc, std::runtime_error);
/**
* Unbinds a key, erroring out if binding does not exist.
*
@ -167,67 +168,68 @@ public:
* throws std::bad_alloc: Not enough memory.
* throws std::runtime_error: The binding does not exist.
*/
void unbind(std::string mod, std::string modmask, std::string keyname);
void unbind(std::string mod, std::string modmask, std::string keyname) throw(std::bad_alloc,
std::runtime_error);
/**
* Get keys bound.
*
* Returns: The set of keyspecs that are bound.
*/
std::list<keyspec> get_bindings();
std::list<keyspec> get_bindings() throw(std::bad_alloc);
/**
* Get command for key.
*/
std::string get(const keyspec& keyspec);
std::string get(const keyspec& keyspec) throw(std::bad_alloc);
/**
* Bind command for key.
*
* Parameter keyspec: The key specifier to bind to.
* Parameter cmd: The command to bind. If "", the key is unbound.
*/
void set(const keyspec& keyspec, const std::string& cmd);
void set(const keyspec& keyspec, const std::string& cmd) throw(std::bad_alloc, std::runtime_error);
/**
* Get set of inverse binds.
*
* Returns: The set of all inverses.
*/
std::set<invbind*> get_inverses();
std::set<invbind*> get_inverses() throw(std::bad_alloc);
/**
* Find inverse bind by command.
*
* Parameter command: The command.
* Returns: The inverse bind, or NULL if none.
*/
invbind* get_inverse(const std::string& command);
invbind* get_inverse(const std::string& command) throw(std::bad_alloc);
/**
* Get set of controller keys.
*
* Returns: The set of all controller keys.
*/
std::set<ctrlrkey*> get_controller_keys();
std::set<ctrlrkey*> get_controller_keys() throw(std::bad_alloc);
/**
* Get specific controller key.
*/
ctrlrkey* get_controllerkey(const std::string& command);
ctrlrkey* get_controllerkey(const std::string& command) throw(std::bad_alloc);
/**
* Get list of controller keys for specific keyboard key.
*/
std::list<ctrlrkey*> get_controllerkeys_kbdkey(key* kbdkey);
std::list<ctrlrkey*> get_controllerkeys_kbdkey(key* kbdkey) throw(std::bad_alloc);
/**
* Register inverse bind.
*/
void do_register(const std::string& name, invbind& bind);
void do_register(const std::string& name, invbind& bind) throw(std::bad_alloc);
/**
* Unregister inverse bind.
*/
void do_unregister(const std::string& name, invbind& bind);
void do_unregister(const std::string& name, invbind& bind) throw(std::bad_alloc);
/**
* Register controller key.
*/
void do_register(const std::string& name, ctrlrkey& ckey);
void do_register(const std::string& name, ctrlrkey& ckey) throw(std::bad_alloc);
/**
* Unregister inverse bind.
*/
void do_unregister(const std::string& name, ctrlrkey& ckey);
void do_unregister(const std::string& name, ctrlrkey& ckey) throw(std::bad_alloc);
/**
* Get keyboard.
*/
@ -243,7 +245,7 @@ public:
* Parameter polarity: Polarity (true is rising edge, false is falling edge).
* Returns: The fixed command, or "" if nothing should be run.
*/
static std::string fixup_command_polarity(std::string cmd, bool polarity);
static std::string fixup_command_polarity(std::string cmd, bool polarity) throw(std::bad_alloc);
/**
* Add a set of inverse binds.
*/
@ -266,7 +268,7 @@ public:
bool operator!=(const struct triplet& a) const { return !(a == *this); }
bool operator>=(const struct triplet& a) const { return !(a < *this); }
bool operator>(const struct triplet& a) const { return (a < *this); }
keyspec as_keyspec() const;
keyspec as_keyspec() const throw(std::bad_alloc);
bool index;
modifier_set mod;
modifier_set mask;
@ -309,7 +311,8 @@ public:
* Parameter _command: Command this is for.
* Parameter _name: Name of inverse key.
*/
invbind_info(invbind_set& set, const std::string& _command, const std::string& _name);
invbind_info(invbind_set& set, const std::string& _command, const std::string& _name)
throw(std::bad_alloc);
/**
* Destructor.
*/
@ -341,7 +344,8 @@ public:
* Parameter command: Command this is for.
* Parameter name: Name of inverse key.
*/
invbind(mapper& kmapper, const std::string& command, const std::string& name, bool dynamic = false);
invbind(mapper& kmapper, const std::string& command, const std::string& name, bool dynamic = false)
throw(std::bad_alloc);
/**
* Destructor.
*/
@ -352,25 +356,25 @@ public:
* Parameter index: Index of the keyspec to get.
* Returns: The keyspec.
*/
keyspec get(unsigned index);
keyspec get(unsigned index) throw(std::bad_alloc);
/**
* Clear key (subsequent keys fill the gap).
*
* Parameter index: Index of key to clear.
*/
void clear(unsigned index);
void clear(unsigned index) throw(std::bad_alloc);
/**
* Add key to set.
*
* Parameter keyspec: The new keyspec.
*/
void append(const keyspec& keyspec);
void append(const keyspec& keyspec) throw(std::bad_alloc);
/**
* Get name for command.
*
* Returns: The name.
*/
std::string getname();
std::string getname() throw(std::bad_alloc);
/**
* Notify mapper dying.
*/
@ -404,7 +408,7 @@ public:
* Parameter axis: If true, create a axis-type key.
*/
ctrlrkey(mapper& kmapper, const std::string& command, const std::string& name,
bool axis = false);
bool axis = false) throw(std::bad_alloc);
/**
* Destructor.
*/
@ -416,7 +420,7 @@ public:
/**
* Get the trigger key.
*/
std::string get_string(unsigned index);
std::string get_string(unsigned index) throw(std::bad_alloc);
/**
* Set the trigger key (appends).
*/
@ -424,7 +428,7 @@ public:
/**
* Set the trigger key (appends).
*/
void append(const std::string& key);
void append(const std::string& key) throw(std::bad_alloc, std::runtime_error);
/**
* Remove the trigger key.
*/

View file

@ -27,7 +27,7 @@ public:
/**
* Create a new instance.
*/
keyboard();
keyboard() throw(std::bad_alloc);
/**
* Destroy an instance.
*
@ -41,7 +41,7 @@ public:
* Returns: The modifier.
* Throws std::runtime_error: No such modifier.
*/
modifier& lookup_modifier(const std::string& name);
modifier& lookup_modifier(const std::string& name) throw(std::runtime_error);
/**
* Try lookup modifier by name.
*
@ -54,14 +54,14 @@ public:
*
* Returns: The set of modifiers.
*/
std::list<modifier*> all_modifiers();
std::list<modifier*> all_modifiers() throw(std::bad_alloc);
/**
* Register a modifier.
*
* Parameter name: The name of the modifier.
* Parameter mod: The modifier.
*/
void do_register(const std::string& name, modifier& mod);
void do_register(const std::string& name, modifier& mod) throw(std::bad_alloc);
/**
* Unregister a modifier.
*
@ -75,7 +75,7 @@ public:
* Returns: The key.
* Throws std::runtime_error: No such key.
*/
key& lookup_key(const std::string& name);
key& lookup_key(const std::string& name) throw(std::runtime_error);
/**
* Try lookup key by name.
*
@ -88,14 +88,14 @@ public:
*
* Returns: The set of keys.
*/
std::list<key*> all_keys();
std::list<key*> all_keys() throw(std::bad_alloc);
/**
* Register a key.
*
* Parameter name: The name of the key.
* Parameter mod: The key.
*/
void do_register(const std::string& name, key& mod);
void do_register(const std::string& name, key& mod) throw(std::bad_alloc);
/**
* Unregister a key.
*
@ -132,7 +132,7 @@ public:
* Parameter keyb: The keyboard these will be on.
* Parameter _name: The name of the modifier.
*/
modifier(keyboard& keyb, const std::string& _name)
modifier(keyboard& keyb, const std::string& _name) throw(std::bad_alloc)
: kbd(keyb), name(_name)
{
keyb.do_register(name, *this);
@ -144,7 +144,7 @@ public:
* Parameter _name: The name of the modifier.
* Parameter _link: The name of the modifier group this is in.
*/
modifier(keyboard& keyb, const std::string& _name, const std::string& _link)
modifier(keyboard& keyb, const std::string& _name, const std::string& _link) throw(std::bad_alloc)
: kbd(keyb), name(_name), link(_link)
{
keyb.do_register(name, *this);
@ -195,7 +195,7 @@ public:
* parameter really: If true, actually add the key. If false, do nothing.
* throws std::bad_alloc: Not enough memory.
*/
void add(modifier& mod, bool really = true);
void add(modifier& mod, bool really = true) throw(std::bad_alloc);
/**
* Remove a modifier from the set.
*
@ -203,7 +203,7 @@ public:
* parameter really: If true, actually remove the key. If false, do nothing.
* throws std::bad_alloc: Not enough memory.
*/
void remove(modifier& mod, bool really = true);
void remove(modifier& mod, bool really = true) throw(std::bad_alloc);
/**
* Construct modifier set from comma-separated string.
*
@ -213,7 +213,8 @@ public:
* throws std::bad_alloc: Not enough memory.
* throws std::runtime_error: Illegal modifier or wrong syntax.
*/
static modifier_set construct(keyboard& kbd, const std::string& modifiers);
static modifier_set construct(keyboard& kbd, const std::string& modifiers) throw(std::bad_alloc,
std::runtime_error);
/**
* Check modifier against its mask for validity.
*
@ -225,7 +226,7 @@ public:
* returns: True if set is valid, false if not.
* throws std::bad_alloc: Not enough memory.
*/
bool valid(modifier_set& mask);
bool valid(modifier_set& mask) throw(std::bad_alloc);
/**
* Check if this modifier set triggers the action.
*
@ -235,11 +236,11 @@ public:
* - Modifiers with this linkage group do not appear in either set nor trigger.
*
*/
bool triggers(const modifier_set& trigger, const modifier_set& mask);
bool triggers(const modifier_set& trigger, const modifier_set& mask) throw(std::bad_alloc);
/**
* Stringify.
*/
operator std::string() const;
operator std::string() const throw(std::bad_alloc);
/**
* Equality check.
*
@ -499,7 +500,8 @@ public:
* Parameter clazz: The class of the key.
* Parameter type: The type of key.
*/
key(keyboard& keyb, const std::string& name, const std::string& clazz, keytype type);
key(keyboard& keyb, const std::string& name, const std::string& clazz, keytype type)
throw(std::bad_alloc);
/**
* Destructor.
*/
@ -526,7 +528,7 @@ public:
* Parameter listener: The listener.
* Parameter analog: If true, also pass analog events.
*/
void add_listener(event_listener& listener, bool analog);
void add_listener(event_listener& listener, bool analog) throw(std::bad_alloc);
/**
* Remove listener.
*
@ -557,7 +559,7 @@ public:
/**
* Get the subkey suffixes.
*/
virtual std::vector<std::string> get_subkeys() = 0;
virtual std::vector<std::string> get_subkeys() throw(std::bad_alloc) = 0;
/**
* Dynamic cast to axis type.
*/
@ -599,7 +601,7 @@ public:
* Parameter name: The base name of the key.
* Parameter clazz: The class of the key.
*/
key_key(keyboard& keyb, const std::string& name, const std::string& clazz);
key_key(keyboard& keyb, const std::string& name, const std::string& clazz) throw(std::bad_alloc);
/**
* Destructor.
*/
@ -622,7 +624,7 @@ public:
/**
* Get the subkey suffixes.
*/
std::vector<std::string> get_subkeys();
std::vector<std::string> get_subkeys() throw(std::bad_alloc);
private:
key_key(key_key&);
key_key& operator=(key_key&);
@ -642,7 +644,7 @@ public:
* Parameter name: The base name of the key.
* Parameter clazz: The class of the key.
*/
key_hat(keyboard& keyb, const std::string& name, const std::string& clazz);
key_hat(keyboard& keyb, const std::string& name, const std::string& clazz) throw(std::bad_alloc);
/**
* Destructor.
*/
@ -665,7 +667,7 @@ public:
/**
* Get the subkey suffixes.
*/
std::vector<std::string> get_subkeys();
std::vector<std::string> get_subkeys() throw(std::bad_alloc);
private:
key_hat(key_hat&);
key_hat& operator=(key_hat&);
@ -686,7 +688,8 @@ public:
* Parameter clazz: The class of the key.
* Parameter mode: Initial mode: -1 => disabled, 0 => axis, 1 => pressure
*/
key_axis(keyboard& keyb, const std::string& name, const std::string& clazz, int mode);
key_axis(keyboard& keyb, const std::string& name, const std::string& clazz, int mode)
throw(std::bad_alloc);
/**
* Destructor.
*/
@ -709,7 +712,7 @@ public:
/**
* Get the subkey suffixes.
*/
std::vector<std::string> get_subkeys();
std::vector<std::string> get_subkeys() throw(std::bad_alloc);
/**
* Get mode.
*/
@ -742,7 +745,7 @@ public:
* Parameter cal: Initial calibration.
*/
key_mouse(keyboard& keyb, const std::string& name, const std::string& clazz,
mouse_calibration cal);
mouse_calibration cal) throw(std::bad_alloc);
/**
* Destructor.
*/
@ -765,7 +768,7 @@ public:
/**
* Get the subkey suffixes. Returns empty list.
*/
std::vector<std::string> get_subkeys();
std::vector<std::string> get_subkeys() throw(std::bad_alloc);
/**
* Get calibration.
*/

View file

@ -1,13 +1,16 @@
#ifndef _library__loadlib__hpp__included__
#define _library__loadlib__hpp__included__
#include <functional>
#include <string>
#include <stdexcept>
#include <map>
#include <set>
#include "threads.hpp"
#if defined(_WIN32) || defined(_WIN64)
#include <windows.h>
#endif
namespace loadlib
{
threads::lock& global_mutex();
@ -32,7 +35,7 @@ public:
* Throws std::bad_alloc: Not enough memory.
* Throws std::runtime_error: Error loading shared library.
*/
library(const std::string& filename)
library(const std::string& filename) throw(std::bad_alloc, std::runtime_error)
{
try {
set_loading(this);
@ -60,7 +63,7 @@ public:
* Throws std::bad_alloc: Not enough memory.
* Throws std::runtime_error: Error looking up the symbol.
*/
void* operator[](const std::string& symbol) const
void* operator[](const std::string& symbol) const throw(std::bad_alloc, std::runtime_error)
{
threads::alock h(global_mutex());
if(!lib) throw std::runtime_error("Symbol '" + symbol + "' not found");
@ -106,15 +109,19 @@ public:
*/
static library* loading() throw();
private:
void set_loading(library* lib);
void set_loading(library* lib) throw(std::bad_alloc);
struct internal
{
internal(const std::string& filename);
internal(const std::string& filename) throw(std::bad_alloc, std::runtime_error);
~internal() throw();
void* operator[](const std::string& symbol) const;
void* operator[](const std::string& symbol) const throw(std::bad_alloc, std::runtime_error);
internal(const internal&);
internal& operator=(const internal&);
#if defined(_WIN32) || defined(_WIN64)
HMODULE handle;
#elif !defined(NO_DLFCN)
void* handle;
#endif
size_t refs;
std::string libname;
void mark(const void* obj) { marked.insert(obj); }
@ -158,11 +165,11 @@ public:
/**
* Symbol lookup.
*/
void* operator[](const std::string& symbol) const;
void* operator[](const std::string& symbol) const throw(std::bad_alloc, std::runtime_error);
/**
* Variable symbol lookup.
*/
template<typename T> T* var(const std::string& symbol) const
template<typename T> T* var(const std::string& symbol) const throw(std::bad_alloc, std::runtime_error)
{
return (T*)(*this)[symbol];
}
@ -170,6 +177,7 @@ public:
* Function symbol lookup.
*/
template<typename T, typename... U> typename fntype<T, U...>::t fn(const std::string& symbol) const
throw(std::bad_alloc, std::runtime_error)
{
return (typename fntype<T, U...>::t)(*this)[symbol];
}

View file

@ -7,13 +7,11 @@
#include <typeindex>
#include <map>
#include <unordered_map>
#include <functional>
#include <set>
#include <list>
#include <cassert>
#include "string.hpp"
#include "utf8.hpp"
#include "int24.hpp"
#include "lua-version.hpp"
namespace lua
@ -30,7 +28,6 @@ class class_base;
class state
{
public:
const static unsigned trampoline_upvals = 2;
//Auxillary type for store-tag.
template<typename T> struct _store_tag
{
@ -194,7 +191,7 @@ public:
/**
* Create a new state.
*/
state();
state() throw(std::bad_alloc);
/**
* Create a new state with specified master state.
*/
@ -221,85 +218,14 @@ public:
* Set OOM handler.
*/
void set_oom_handler(void (*oom)()) { oom_handler = oom ? oom : builtin_oom; }
/**
* Set soft OOM handler.
*/
void set_soft_oom_handler(void (*oom)(int status)) { soft_oom_handler = oom ? oom : builtin_soft_oom; }
/**
* Set memory use change handler.
*/
void set_memory_change_handler(std::function<void(ssize_t change)> cb)
{
memory_change = cb;
}
/**
* Reset the state.
*/
void reset();
void reset() throw(std::runtime_error, std::bad_alloc);
/**
* Deinit the state.
*/
void deinit() throw();
/**
* Create a trampoline.
*
* Parameter fn The function to execute.
* Parameter n_upvals The number of extra upvalues besides the 2 used by trampoline itself. Popped from stack.
*/
void push_trampoline(int(*fn)(state& L), unsigned n_upvals);
/**
* Get specified trampoline upvalue index.
*/
int trampoline_upval(int val) { return lua_upvalueindex(trampoline_upvals + val); }
/**
* Set value of interruptable flag.
*
* Parameter flag: The flag.
*/
void set_interruptable_flag(bool flag)
{
if(master) master->set_interruptable_flag(flag); else interruptable = flag;
}
/**
* Get interruptable flag.
*/
bool get_interruptable_flag()
{
if(master) return master->get_interruptable_flag(); else return interruptable;
}
/**
* Set memory limit.
*/
void set_memory_limit(size_t limit)
{
if(master) master->set_memory_limit(limit); else memory_limit = limit;
}
/**
* Get memory limit.
*/
size_t get_memory_limit()
{
if(master) return master->get_memory_limit(); else return memory_limit;
}
/**
* Get memory use.
*/
size_t get_memory_use()
{
if(master) return master->get_memory_use(); else return memory_use;
}
/**
* Charge against memory limit.
*/
bool charge_memory(size_t amount, bool release);
/**
* Execute function in interruptable mode.
*
* Parameter fn: The function to execute
* Parameter in: Number of slots to copy in.
* Parameter out: Number of slots to copy out.
*/
void run_interruptable(std::function<void()> fn, unsigned in, unsigned out);
/**
* Get a string argument.
*
@ -308,7 +234,7 @@ public:
* Returns: The string.
* Throws std::runtime_error: The specified argument is not a string.
*/
std::string get_string(int argindex, const std::string& fname)
std::string get_string(int argindex, const std::string& fname) throw(std::runtime_error, std::bad_alloc)
{
if(isnone(argindex))
(stringfmt() << "argument #" << argindex << " to " << fname << " must be string").throwex();
@ -318,20 +244,6 @@ public:
(stringfmt() << "argument #" << argindex << " to " << fname << " must be string").throwex();
return std::string(f, f + len);
}
/**
* Read slot as string.
*
* Parameter argindex: The stack index.
* Returns: The string.
*/
std::string as_string(int argindex)
{
if(isnone(argindex)) return "(none)";
size_t len;
const char* f = lua_tolstring(lua_handle, argindex, &len);
if(!f) return "(null)";
return std::string(f, f + len);
}
/**
* Get a boolean argument.
*
@ -340,7 +252,7 @@ public:
* Returns: The string.
* Throws std::runtime_error: The specified argument is not a boolean.
*/
bool get_bool(int argindex, const std::string& fname)
bool get_bool(int argindex, const std::string& fname) throw(std::runtime_error, std::bad_alloc)
{
if(isnone(argindex) || !isboolean(argindex))
(stringfmt() << "argument #" << argindex << " to " << fname << " must be boolean").throwex();
@ -419,30 +331,19 @@ public:
* Parameter args: Arguments to pass to the callback.
*/
template<typename... T>
bool callback(std::list<char>& cblist, const char*& r_cb, bool& r_cb_f, T... args)
bool callback(const std::list<char>& cblist, T... args)
{
bool any = false;
for(auto i = cblist.begin(); i != cblist.end();) {
pushlightuserdata(const_cast<char*>(&*i));
for(auto& i : cblist) {
pushlightuserdata(const_cast<char*>(&i));
rawget(LUA_REGISTRYINDEX);
int t = type(-1);
if(t != LUA_TFUNCTION) {
pop(1);
} else {
//Note the currently running CB so that unregister treats it specially if it is
//unrgistered.
r_cb = &*i;
_callback(0, args...);
r_cb = NULL;
any = true;
}
//Currently iterated function may be erased. The memory has to be freed in that case.
if(r_cb_f) {
r_cb_f = false;
i = cblist.erase(i);
} else {
i++;
}
}
return any;
}
@ -480,7 +381,7 @@ public:
void _register(state& L); //Reads callback from top of lua stack.
void _unregister(state& L); //Reads callback from top of lua stack.
template<typename... T> bool callback(T... args) {
bool any = L.callback(callbacks, running_cb, running_cb_f, args...);
bool any = L.callback(callbacks, args...);
if(fn_cbname != "" && L.callback(fn_cbname, args...))
any = true;
return any;
@ -491,8 +392,6 @@ public:
callback_list(const callback_list&);
callback_list& operator=(const callback_list&);
std::list<char> callbacks;
const char* running_cb;
bool running_cb_f;
state& L;
std::string name;
std::string fn_cbname;
@ -512,7 +411,6 @@ public:
void* newuserdata(size_t size) { return lua_newuserdata(lua_handle, size); }
int setmetatable(int index) { return lua_setmetatable(lua_handle, index); }
int type(int index) { return lua_type(lua_handle, index); }
void replace(int index) { lua_replace(lua_handle, index); }
int getmetatable(int index) { return lua_getmetatable(lua_handle, index); }
int rawequal(int index1, int index2) { return lua_rawequal(lua_handle, index1, index2); }
void* touserdata(int index) { return lua_touserdata(lua_handle, index); }
@ -541,7 +439,7 @@ public:
int toboolean(int index) { return lua_toboolean(lua_handle, index); }
const char* tolstring(int index, size_t *len) { return lua_tolstring(lua_handle, index, len); }
lua_Number tonumber(int index) { return lua_tonumber(lua_handle, index); }
int64_t tointeger(int index) { return LUA_INTEGER_POSTFIX(lua_to) (lua_handle, index); }
uint64_t tointeger(int index) { return LUA_INTEGER_POSTFIX(lua_to) (lua_handle, index); }
void gettable(int index) { lua_gettable(lua_handle, index); }
int load(lua_Reader reader, void* data, const char* chunkname, const char* mode) {
(void)mode;
@ -552,41 +450,26 @@ public:
void pushlstring(const char* s, size_t len) { lua_pushlstring(lua_handle, s, len); }
void pushlstring(const std::string& s) { lua_pushlstring(lua_handle, s.c_str(), s.length()); }
void pushlstring(const char32_t* s, size_t len) { pushlstring(utf8::to8(std::u32string(s, len))); }
int pcall(int nargs, int nresults, int errfunc)
{
state* master_state = this;
while(master_state->master) master_state = master_state->master;
//Upon entry to protected mode, interruptable mode is always set, and it is restored on exit
//from protected mode.
bool old_interruptable = master_state->interruptable;
master_state->interruptable = true;
auto ret = lua_pcall(lua_handle, nargs, nresults, errfunc);
master_state->interruptable = old_interruptable;
return ret;
}
int pcall(int nargs, int nresults, int errfunc) { return lua_pcall(lua_handle, nargs, nresults, errfunc); }
int next(int index) { return lua_next(lua_handle, index); }
int isnoneornil(int index) { return lua_isnoneornil(lua_handle, index); }
void rawgeti(int index, int n) { lua_rawgeti(lua_handle, index, n); }
template<typename T> void pushnumber(T val)
{
if(std::numeric_limits<T>::is_integer || is_ss_int24<T>::flag)
return LUA_INTEGER_POSTFIX(lua_push) (lua_handle, val);
if(std::numeric_limits<T>::is_integer)
_pushinteger(val);
else
return lua_pushnumber(lua_handle, val);
_pushnumber(val);
}
void pushboolean(bool b) { lua_pushboolean(lua_handle, b); }
void pushglobals() { LUA_LOADGLOBALS }
private:
void _pushnumber(lua_Number n) { return lua_pushnumber(lua_handle, n); }
void _pushinteger(uint64_t n) { return LUA_INTEGER_POSTFIX(lua_push) (lua_handle, n); }
static void builtin_oom();
static void builtin_soft_oom(int status);
static void* builtin_alloc(void* user, void* old, size_t olds, size_t news);
void (*oom_handler)();
void (*soft_oom_handler)(int status);
std::function<void(ssize_t change)> memory_change;
state* master;
bool interruptable;
size_t memory_limit;
size_t memory_use;
lua_State* lua_handle;
state(state&);
state& operator=(state&);

View file

@ -1,7 +1,6 @@
#ifndef _library__lua_class__hpp__included__
#define _library__lua_class__hpp__included__
#include <functional>
#include "lua-base.hpp"
#include "lua-pin.hpp"
@ -221,32 +220,28 @@ template<class T> class _class : public class_base
template<typename... U> T* _create(state& _state, U... args)
{
size_t overcommit = T::overcommit(args...);
void* obj = NULL;
auto st = &_state;
_state.run_interruptable([st, overcommit, &obj]() {
obj = st->newuserdata(sizeof(T) + overcommit);
}, 0, 1);
void* obj = _state.newuserdata(sizeof(T) + overcommit);
load_metatable(_state);
_state.setmetatable(-2);
T* _obj = reinterpret_cast<T*>(obj);
try {
new(_obj) T(_state, args...);
} catch(...) {
//CTOR FAILED. Get rid of the dtor (since it would error) and then dump the object.
_state.newtable();
_state.setmetatable(-2);
_state.pop(1);
throw;
}
new(_obj) T(_state, args...);
return _obj;
}
static int class_bind_trampoline(state& L)
static int class_bind_trampoline(lua_State* LS)
{
class_binding<T>* b = (class_binding<T>*)L.touserdata(L.trampoline_upval(1));
T* p = _class<T>::get(L, 1, b->fname);
lua::parameters P(L, b->fname);
return (p->*(b->fn))(L, P);
try {
class_binding<T>* b = (class_binding<T>*)lua_touserdata(LS, lua_upvalueindex(1));
state L(*b->_state, LS);
T* p = _class<T>::get(L, 1, b->fname);
lua::parameters P(L, b->fname);
return (p->*(b->fn))(L, P);
} catch(std::exception& e) {
std::string err = e.what();
lua_pushlstring(LS, err.c_str(), err.length());
lua_error(LS);
}
return 0; //NOTREACHED
}
T* _get(state& _state, int arg, const std::string& fname, bool optional = false)
@ -303,7 +298,7 @@ badtype:
bdata->_state = &_state.get_master();
std::copy(fname.begin(), fname.end(), bdata->fname);
bdata->fname[fname.length()] = 0;
_state.push_trampoline(class_bind_trampoline, 1);
_state.pushcclosure(class_bind_trampoline, 1);
_state.rawset(-3);
_state.pop(1);
}
@ -377,6 +372,7 @@ public:
* Throws std::runtime_error: Wrong type.
*/
static T* get(state& _state, int arg, const std::string& fname, bool optional = false)
throw(std::bad_alloc, std::runtime_error)
{
return objclass<T>()._get(_state, arg, fname, optional);
}
@ -432,7 +428,8 @@ public:
* Parameter fname: Name of function for error message purposes.
* Throws std::runtime_error: Wrong type.
*/
static objpin<T> pin(state& _state, int arg, const std::string& fname)
static objpin<T> pin(state& _state, int arg, const std::string& fname) throw(std::bad_alloc,
std::runtime_error)
{
return objclass<T>()._pin(_state, arg, fname);
}
@ -454,27 +451,30 @@ public:
return r;
}
private:
static int dogc(state& L)
static int dogc(lua_State* LS)
{
T* obj = reinterpret_cast<T*>(L.touserdata(1));
T* obj = reinterpret_cast<T*>(lua_touserdata(LS, 1));
obj->~T();
return 0;
}
static int newindex(state& L)
static int newindex(lua_State* LS)
{
throw std::runtime_error("Writing metatables of classes is not allowed");
lua_pushstring(LS, "Writing metatables of classes is not allowed");
lua_error(LS);
return 0;
}
static int index(state& L)
static int index(lua_State* LS)
{
L.getmetatable(1);
L.pushvalue(2);
L.rawget(-2);
if(L.type(-1) == LUA_TNIL) {
std::string err = std::string("Class '") + L.tostring(L.trampoline_upval(1)) +
"' does not have class method '" + L.tostring(2) + "'";
throw std::runtime_error(err);
lua_getmetatable(LS, 1);
lua_pushvalue(LS, 2);
lua_rawget(LS, -2);
if(lua_type(LS, -1) == LUA_TNIL) {
std::string err = std::string("Class '") + lua_tostring(LS, lua_upvalueindex(1)) +
"' does not have class method '" + lua_tostring(LS, 2) + "'";
lua_pushstring(LS, err.c_str());
lua_error(LS);
}
return 1;
}
@ -491,14 +491,14 @@ again:
_state.pushvalue(-1);
_state.setmetatable(-2);
_state.pushstring("__gc");
_state.push_trampoline(&_class<T>::dogc, 0);
_state.pushcfunction(&_class<T>::dogc);
_state.rawset(-3);
_state.pushstring("__newindex");
_state.push_trampoline(&_class<T>::newindex, 0);
_state.pushcfunction(&_class<T>::newindex);
_state.rawset(-3);
_state.pushstring("__index");
_state.pushlstring(name);
_state.push_trampoline(&_class<T>::index, 1);
_state.pushcclosure(&_class<T>::index, 1);
_state.rawset(-3);
_state.rawset(LUA_REGISTRYINDEX);
goto again;

View file

@ -17,8 +17,10 @@ struct render_context
uint32_t height;
};
framebuffer::color get_fb_color(lua::state& L, int index, const std::string& fname);
framebuffer::color get_fb_color(lua::state& L, int index, const std::string& fname, int64_t dflt);
framebuffer::color get_fb_color(lua::state& L, int index, const std::string& fname)
throw(std::bad_alloc, std::runtime_error);
framebuffer::color get_fb_color(lua::state& L, int index, const std::string& fname, int64_t dflt)
throw(std::bad_alloc, std::runtime_error);
}
#endif

View file

@ -1,8 +1,6 @@
#ifndef _library__lua_function__hpp__included__
#define _library__lua_function__hpp__included__
#include <functional>
namespace lua
{
class parameters;
@ -58,7 +56,7 @@ public:
/**
* Register function.
*/
function(function_group& group, const std::string& name);
function(function_group& group, const std::string& name) throw(std::bad_alloc);
/**
* Unregister function.
*/

View file

@ -23,20 +23,11 @@ extern "C"
#define LUA_SUPPORTS_INTEGERS
#define LUA_SUPPORTS_LOAD_STRING
#else
#if LUA_VERSION_NUM == 504
#define LUA_SUPPORTS_LOAD_MODE
#define LUA_SUPPORTS_RIDX_GLOBALS
#define LUA_SUPPORTS_INTEGERS
#define LUA_SUPPORTS_LOAD_STRING
#else
#error "Unsupported Lua version"
#endif
#endif
#endif
#endif
#ifdef LUA_SUPPORTS_INTEGERS
#define LUA_INTEGER_POSTFIX(X) X##integer

View file

@ -22,12 +22,12 @@ public:
*
* Parameter space: The memory space.
*/
memory_search(memory_space& space);
memory_search(memory_space& space) throw(std::bad_alloc);
/**
* Reset the context so all addresses are candidates again.
*/
void reset();
void reset() throw(std::bad_alloc);
/**
* This searches the memory space, leaving those addresses for which condition object returns true.
@ -54,7 +54,7 @@ public:
/**
* Returns list of all candidates. This function isn't lazy, so be careful when calling with many candidates.
*/
std::list<uint64_t> get_candidates();
std::list<uint64_t> get_candidates() throw(std::bad_alloc);
/**
* Is specified address a candidate?
*/

View file

@ -1,7 +1,6 @@
#ifndef _library__memorywatch_fb__hpp__included__
#define _library__memorywatch_fb__hpp__included__
#include <functional>
#include "framebuffer.hpp"
#include "memorywatch.hpp"
#include "mathexpr.hpp"

View file

@ -2,7 +2,6 @@
#define _library__memorywatch__hpp__included__
#include "mathexpr.hpp"
#include <functional>
#include <list>
#include <set>
#include <map>

Some files were not shown because too many files have changed in this diff Show more