Compare commits

..

183 commits

Author SHA1 Message Date
Ilari Liusvaara
7d9b3e93ec Track all window size changes while in fullscreen 2018-01-08 04:24:45 +02:00
Ilari Liusvaara
3dee7b756a Delay committing fullscreen until seeing window size change
Hopefully gets rid of race condition in fullscreening the emulator.
2018-01-08 01:51:43 +02:00
Ilari Liusvaara
323db52b6b Add <functional> to files that use std::function 2017-10-26 04:41:20 +03:00
Ilari Liusvaara
f49b82c989 Bus fixes: Reading of CPU MMIO registers does not update MDR
Also fixes controller timings to be more realistic.
2017-10-25 14:22:19 +03:00
Ilari Liusvaara
6fd18bd0f0 Make wrapper for boost::lexical_cast
This makes it easier to eventually get rid of boost::lexical_cast.
2017-10-25 14:11:43 +03:00
Ilari Liusvaara
b5f3e543d8 De-header SNES games with headers submultiple of 512 bytes correctly 2017-08-30 19:06:51 +03:00
Ilari Liusvaara
4c6338888d Save: Fix issues with adding an extension if missing
- The code should search for the last '.', not the first.
- Case-insensitively compare the extensions.
2017-08-08 09:48:53 +03:00
Rodrigo A. do Amaral
9318e4de94 Lua (d)bitmap: add hflip and vflip functions 2017-07-14 06:07:03 +03:00
Ilari Liusvaara
298610752b Specialize (D)BITMAP:sample_texture when s is power of two 2017-07-13 20:27:38 +03:00
Ilari Liusvaara
f85cdab6c5 Linear transformed texture sampling for (d)bitmap 2017-07-13 15:44:52 +03:00
Ilari Liusvaara
dd18168993 Fix few uninitialized variables and a stack smash in AVI dumper
- Fix uninitialized closed flag in avi_worker
- Fix uninitialized stream parameters in avi_writer
- Fix stack smash in AVI write_pkt (the padding is only 2 bytes, don't
  write an u32 into it!)
2017-05-29 17:32:09 +03:00
Ilari Liusvaara
7be5215c08 When redrawing screen, read the last written frame
This should fix the bug with loadstates, where wrong screenshot was
displayed in certain race condition.
2017-05-23 11:11:32 +03:00
Ilari Liusvaara
8ac8304824 Lua: Fix type confusion between signed and unsigned
This bug seemed to cause all hell to break lose with negative numbers
2017-04-18 19:25:07 +03:00
Ilari Liusvaara
c2e40c4cd3 Support uncompressing ZIP compression method 12 (bzip2) 2017-02-05 17:15:57 +02:00
Ilari Liusvaara
669381821e PIX_FMT_* constants are deprecated, use AV_PIX_FMT_* instead 2017-01-24 16:28:57 +02:00
Ilari Liusvaara
c5d441c6b0 Fix crash if text containing \n is printed at nonzero x 2016-09-18 23:00:13 +03:00
Ilari Liusvaara
5544b9ba12 Don't try to enter loadstate with loadstate already in progress 2016-08-09 18:59:25 +03:00
Ilari Liusvaara
4c9bb20270 Fix crash if mouse_x or mouse_y are hooked
Turns out framebuffer draw recalibrates mouse_x and mouse_y, which then
calls into hook. Which is no-no, because framebuffer draw runs in GUI
thread, and hooks must run in game thread.
2016-07-23 11:16:34 +03:00
Ilari Liusvaara
eb6ff6c38b Virtualize audio system for instances 2016-04-17 10:14:05 +03:00
Ilari Liusvaara
7903ba1fda Small cleanup: move up some lsnes_instance stuff 2016-04-16 10:51:02 +03:00
Ilari Liusvaara
40ac5d56e3 Some new hotkeys
- Flush slotinfo cache
- Reload current ROM
- Close current ROM
- Increase speed
- Decrease speed
2016-04-15 12:50:15 +03:00
Ilari Liusvaara
a3f1d7c8a4 Lua Add getters for various paths 2016-04-15 09:18:48 +03:00
Ilari Liusvaara
d287f64c14 Allow modifying button to be autofire/autohold/typed 2016-04-14 20:22:13 +03:00
Ilari Liusvaara
62ee8b0039 Don't try to uninstall handlers for active core
Should stop the Gambatte/Bsnes SGB core from crashing on exit.
2016-01-01 08:01:16 +02:00
Ilari Liusvaara
05ad5b9da1 Fix "empty path points to root" bug
Unset paths are supposed to point to the current directory, not the
root.
2016-01-01 07:57:48 +02:00
Ilari Liusvaara
019fbc2646 bsnes: Add Lua function to dump 2bpp sprites (and allow 4-color palettes) 2015-12-29 03:01:46 +02:00
Ilari Liusvaara
3da2e26e1b Add bit.fextract, bit.bfields 2015-12-24 21:26:12 +02:00
Ilari Liusvaara
610685db0f Fix Valgrind warning about uninitialized variable 2015-12-15 04:17:53 +02:00
Ilari Liusvaara
6a580bb332 Add regex sanity checks on startup and add --sanity-check 2015-12-15 04:17:11 +02:00
Ilari Liusvaara
fa3e5b6751 Nuke last remains of boost::regex from outside string.cpp 2015-12-11 19:42:35 +02:00
Ilari Liusvaara
813449ac1b Fix compilation with Lua 5.1
Apparently Lua 5.1 doesn't have LUA_OK (0).
2015-11-05 00:22:11 +02:00
Ilari Liusvaara
ff697846d1 Fix crash if loading type0 PNG without tRNS chunk 2015-10-26 21:38:36 +02:00
Ilari Liusvaara
476f79f14a Fix disassembly of SNES BRL instruction 2015-10-26 21:20:25 +02:00
Ilari Liusvaara
e9e00fd881 Fix help for +tangent/-tangent to be less obscure 2015-10-04 05:31:11 +03:00
Ilari Liusvaara
51bbbd1772 When loading gamepaks, use #1 as MSU-1 base only if system has BIOS 2015-09-07 21:01:15 +03:00
Ilari Liusvaara
1834c61dfb Fix MSU-1 bug where write to MSU1BASE+4 is mirred to MSUBASE+5 2015-09-07 20:52:01 +03:00
Ilari Liusvaara
5ab3b133a4 Fix bsnes compilation for GCC 5.X 2015-08-08 11:13:39 +03:00
Ilari Liusvaara
918dc6db7b Fix gamepad reset
Don't create duplicate keys for gamepads during reset (causing those
keys to stop working) and properly offline all buttons and axes in
gamepad that is offlined.
2015-08-01 00:25:37 +03:00
Ilari Liusvaara
97ba0292d6 Fix crash on loading invalid PNG files
(Just a divide by zero)
2015-07-25 17:23:59 +03:00
Ilari Liusvaara
d8048863e8 movie::frame_subframes: Gracefully handle invalid frame numbers
Doesn't fix cache invalidation errors tho.
2015-07-04 12:18:11 +03:00
Ilari Liusvaara
6d1a67719b Add movie.subframe_to_frame 2015-07-03 22:24:47 +03:00
Ilari Liusvaara
5e73a844a9 Fix do_load_rom() in readonly case 2015-06-29 20:56:04 +03:00
Ilari Liusvaara
4a4c71acf4 ss_int24_t and ss_uint24_t are integers
Fixes memory.readhword pushing the result as a float instead of integer.
2015-06-27 02:45:43 +03:00
Ilari Liusvaara
957738035f Use standard bitmap composition for rendered text bitmaps 2015-06-24 12:54:45 +03:00
Ilari Liusvaara
859d60513f Merge some common drawing code between bitmaps and tilemaps 2015-06-23 14:46:14 +03:00
Ilari Liusvaara
7ada70888f Cleanup bitmap and tilemap rendering a bit 2015-06-23 14:32:59 +03:00
Ilari Liusvaara
250679f656 Merge remote-tracking branch 'origin/master' 2015-06-23 13:46:21 +03:00
Ilari Liusvaara
2e609624fa Remove bogus comments in gui-tilemap.cpp
size_t can't overrun as a pointer.
2015-06-23 13:45:47 +03:00
Ilari Liusvaara
daa5ca41e9 Close the ROM on quit to avoid crashes 2015-06-21 09:12:03 +03:00
Ilari Liusvaara
4a4004d3f8 Fix build breakage on Win32 2015-06-16 21:23:14 +03:00
Ilari Liusvaara
0b3743e258 Lua: CUSTOMFONT:dump(): Dump font to file
This can be used in conjuction with edit() method for editing fonts and
then dumping those back into file.
2015-06-11 05:31:23 +03:00
Ilari Liusvaara
73e0232176 Don't crash on trying to create 0x0 bitmap or tilemap 2015-06-10 19:20:44 +03:00
Ilari Liusvaara
d86f713aa4 Eliminate sloppy types from headers
This should give identical layouts on all platforms (modulo 32/64 bit)
2015-06-07 12:49:19 +03:00
Ilari Liusvaara
52073af3ac Fix load preserving movie displaying wrong screenshot 2015-06-05 01:06:53 +03:00
Ilari Liusvaara
1c48e0ab06 Fix multiple problems with text drawing
- Fix the background to be of correct size
- Fix pre/post error in gui.text() positioning
- Fix pre/post error in custom font rendering, leading to crap pixels
2015-06-04 02:01:43 +03:00
Ilari Liusvaara
c5b368ab3f Lua: get_directory_contents & get_file_type
Useful for reading contents of directories
2015-06-02 08:38:55 +03:00
Ilari Liusvaara
1056f4b4b2 Don't overflow buffers if bsnes goes bonkers
The test state I got by corrupting savestate still crashes however.
2015-05-31 23:45:02 +03:00
Ilari Liusvaara
80867950f3 lsnes rr2-β23 2015-05-28 12:41:52 +03:00
Ilari Liusvaara
88a00a2a84 Some new TODOs 2015-05-28 12:37:40 +03:00
Ilari Liusvaara
2da23de987 Small whitespace cleanup 2015-05-27 23:08:54 +03:00
Ilari Liusvaara
0d83c3aba6 Rework how memory tracking works
Also adds a few new tracking categories, like movie storage
2015-05-27 17:59:00 +03:00
Ilari Liusvaara
0960e967ea Memory tracker: Add tracking of render objects 2015-05-27 16:28:01 +03:00
Ilari Liusvaara
c2a7eed9d8 Clean up system font drawing
Refactor font reading to fewer places
2015-05-27 15:38:22 +03:00
Ilari Liusvaara
1dd19faaeb Make git diff --check happier 2015-05-27 11:14:56 +03:00
Ilari Liusvaara
8bca9ce614 Remove TODO list entry now done 2015-05-27 10:49:58 +03:00
Ilari Liusvaara
0c0156647b Redo text rendering (adds halo support to gui.text())
Now gui.text() and friends support halos. Also fixes a bug with partially
opaque halos in CUSTOMFONT rendering.
2015-05-27 10:44:50 +03:00
Ilari Liusvaara
56deafcd4a Framework for memory usage tracking
Adds tracking for Lua VM and ROM images. The rest comes later.
2015-05-26 13:16:09 +03:00
Ilari Liusvaara
82a7c255a4 Lua: Memory usage limit
This allows limiting memory usage by Lua, which might very well be useful,
given the behaviour of accumulating garbage in memory if one does not
garbage-collect.
2015-05-25 23:44:51 +03:00
Ilari Liusvaara
6a2d7f9aa2 Use master state for trampolines
Fixes memory corruption if any Lua function creates a trampoline
2015-05-25 22:31:51 +03:00
Ilari Liusvaara
478472e883 Have only one main Lua function trampoline
This makes it easier to have special modes when Lua functions are running
later...
2015-05-25 21:16:45 +03:00
Ilari Liusvaara
f06eb401c4 font rendering: Use ranges for bounding instead of buggy routine
This fixes the drawing junk problem if character is drawn off top or
off left.
2015-05-20 08:51:14 +03:00
Ilari Liusvaara
f04379b03c Actually kill objects using palette about to be GC'd 2015-05-14 20:37:23 +03:00
Ilari Liusvaara
a8bc4a2cf8 Small rendering speedups
Pass the object pins as references instead of values. Saves about
150 CPU cycles per value for me.
2015-05-14 20:04:41 +03:00
Ilari Liusvaara
ae71090387 Fix a compiler warning
The warning is false, init of spd can't be avoided if is_string=false.
2015-05-14 19:53:33 +03:00
Ilari Liusvaara
04d7e60fe1 Fix race between killing object and drawing object
Previously, it was possible to draw and kill object queue at the same
time, possibly leading to crashes from accessing object state after
destroying it. Fix this.
2015-05-14 19:20:21 +03:00
Ilari Liusvaara
15ff9e0cc8 Don't leak open file descriptors to loaded ROMs 2015-05-09 19:16:44 +03:00
Ilari Liusvaara
8a794244be Fix typo in Lua reference 2015-05-08 01:10:12 +03:00
Ilari Liusvaara
10eb0dbd22 Add description of PALETTE:get() 2015-05-03 02:24:11 +03:00
Ilari Liusvaara
eeaf3706d8 Add dedicated method for resetting to poweron state
This speeds up "rewind to beginning" operation.
2015-04-27 10:03:28 +03:00
Ilari Liusvaara
9aa8578e74 Circle coordinates can go negative and thus must be signed
Fixes the bug where only one fourth of circle was drawn.
2015-04-27 08:20:26 +03:00
Ilari Liusvaara
17efbec1a6 Clean up dynamic state handling a bit 2015-04-25 15:51:18 +03:00
Ilari Liusvaara
39286f820a Refactor unsafe rewinding a bit now that state is its own subobject 2015-04-25 13:18:37 +03:00
Ilari Liusvaara
653f44e353 Refactor dynamic state to its own subobject
This is meant as base for further refactoring
2015-04-14 15:39:50 +03:00
Ilari Liusvaara
a45baf5559 Mark the core methods that should be idempotent as const 2015-04-14 13:06:13 +03:00
Ilari Liusvaara
4d3d483a34 A bit of code cleanup 2015-04-14 12:40:57 +03:00
Ilari Liusvaara
3571fb3e08 Refer to loaded ROM imagesets as handles 2015-04-14 12:34:19 +03:00
Ilari Liusvaara
b7aedc6cd9 Internally refactor loaded ROM imageset out of loaded ROM code 2015-04-14 11:25:10 +03:00
Ilari Liusvaara
1bf49d532d Move NULL core code to its own file 2015-04-14 10:27:35 +03:00
Ilari Liusvaara
a6b7391da5 Refactor loaded_rom to make public fields private 2015-04-14 10:21:31 +03:00
Ilari Liusvaara
8af9dda77f Fix speed going out of whack after doing unsafe rewind 2015-04-12 23:10:57 +03:00
Ilari Liusvaara
a1b96d75da Split overly large loaded_rom constructor 2015-04-11 20:31:23 +03:00
Ilari Liusvaara
2842b76907 Add load-rom command
This is not really complete: There are three ROM load modes, this is just
one of those.
2015-04-11 06:01:20 +03:00
Ilari Liusvaara
c51cfe9099 Add back reload-rom and close-rom
These commands have seemingly gotten lost somewhere
2015-04-11 04:37:39 +03:00
Ilari Liusvaara
71d649c487 Remove some unnecressary casts 2015-04-10 23:01:07 +03:00
Ilari Liusvaara
ae3cb19a03 SNES: Functions for messing with clockrate (for debugging games) 2015-04-09 04:18:59 +03:00
Ilari Liusvaara
f2169b725f Don't callback to Lua in inconsistent state when loading a new ROM 2015-04-09 04:18:05 +03:00
Ilari Liusvaara
046bc221ef Lua: movie.get_game_info 2015-04-04 22:22:33 +03:00
Ilari Liusvaara
5f0d5dcdb0 Wxwidgets: Fix some compile errors in window-fileupload.cpp 2015-04-04 00:52:48 +03:00
Ilari Liusvaara
3eb7585947 Wxwidgets: Fix some compile errors in editor-memorywatch.cpp 2015-04-04 00:24:49 +03:00
Ilari Liusvaara
d7744e00e7 Wxwidgets: Fix § 2015-03-23 19:31:54 +02:00
Ilari Liusvaara
52dff27f3e Wxwidgets: Add keycode entries for å, ä and ö
Allows these keys to be used as bindings, hotkeys or controller keys
2015-03-21 17:33:10 +02:00
Ilari Liusvaara
93875839b9 bit.(r)flagdecode: Fix unicode in on/off strings 2015-03-11 03:18:49 +02:00
Ilari Liusvaara
929155f14d Fix typo in resolve_filename documentation 2015-03-10 22:40:13 +02:00
Ilari Liusvaara
63b59e35f7 Lua: Don't run class destructor if constructor failed 2015-03-04 22:34:03 +02:00
Ilari Liusvaara
aade7a9fb8 Fix race condition in do_mix_tsc()
The lock needs to protect count from concurrent update. Especially since
if double increment happens in the wrong place, the routine starts
scribbling memory until whole thing crashes.
2015-03-04 21:48:14 +02:00
Ilari Liusvaara
fd65e1e435 Fix hostendian memory watches 2015-02-27 19:02:43 +02:00
Ilari Liusvaara
8e95c54d68 Throw mic in to entropy pool 2015-02-27 19:02:25 +02:00
Ilari Liusvaara
e3fc1ed5fa Make gitlinks for bsnes and gambatte
HTTP Code 418...
2015-02-14 10:05:52 +02:00
Ilari Liusvaara
94170ec2d5 wxwidgets: exit-fullscreen to forcibly exit fullscreen mode 2015-02-14 01:45:43 +02:00
Ilari Liusvaara
ea78fecb1b Force a repaint when becoming fullscreen
Fixes game screen when fullscreen is entered with game pauses
2015-02-14 01:25:17 +02:00
Ilari Liusvaara
19b12b1215 Lua: movie.get_rom_info() 2015-02-13 22:49:43 +02:00
Ilari Liusvaara
4e70e95e7f Lua: movie.rom_loaded() 2015-02-13 22:18:44 +02:00
Ilari Liusvaara
8967f3a261 Lua: input.controller_info(): Don't crash with out-of-range port 2015-02-13 22:01:26 +02:00
Ilari Liusvaara
7ece85f0c6 Fix movie length being wrong for imported binary tracks 2015-02-13 08:55:53 +02:00
Ilari Liusvaara
5f8f8af25f Implicitly redirect cmdhelp includes to corresponding JSON files
This should help with the superfluous building due to cmdhelp.
2015-02-12 21:56:19 +02:00
Ilari Liusvaara
c86f10376a Force game panel to window size in fullscreen mode
This should fix fullscreen mode on Win32.

Also properly letterbox the screen when in fullscreen mode
2015-02-12 16:11:12 +02:00
Ilari Liusvaara
791684edc3 wxwidgets: Hide dumper called "NULL"
This is not working dumper (it is meant for PGO using lsnes-dumpavi),
so don't show it.
2015-02-12 13:16:56 +02:00
Ilari Liusvaara
ff1004d7fa If initsram/initstate points to LSS file, pull the matching member 2015-02-12 01:40:36 +02:00
Ilari Liusvaara
bdcf21a4e1 Movie editor: Fix unnamed branch to show properly in select branch 2015-02-12 00:38:07 +02:00
Ilari Liusvaara
95ec8a8ba7 Lua: add gui.get_runmode() 2015-02-11 21:24:06 +02:00
Ilari Liusvaara
5c0f57448c Add a internal TODO list 2015-02-08 18:11:51 +02:00
Ilari Liusvaara
773e84cfd7 Movie editor: Don't lock up on trying to display error messages 2015-02-08 18:02:33 +02:00
Ilari Liusvaara
44aa95cc57 Switch to std::regex by default 2015-02-07 15:32:34 +02:00
Ilari Liusvaara
54cbe456b4 Move all regex matching to library/string.cpp
This is in preparation to having an option to use std::regex. Also should
fix a few bugs with trace log.
2015-02-07 14:37:18 +02:00
Ilari Liusvaara
94b603c9f2 Fix some compilation errors on Mac OS X 2015-02-04 21:28:25 +02:00
Ilari Liusvaara
1cb702bd5e NULL video dumper
Might be useful for abusing dumpavi for running emulation without UI
and to have autoexit.
2015-02-02 22:00:23 +02:00
Ilari Liusvaara
7c7ee6637d Fix scaling-related crashes
Turns out libswscale scribbles past end of buffer, so allocate some extra
scratch space.
2015-01-31 01:38:57 +02:00
Ilari Liusvaara
5f0b9e3315 Fix race condition in makefile 2015-01-31 01:37:22 +02:00
Ilari Liusvaara
58e4ad1b94 Show error instead silently failing tangent positive edge
If there is no file to save the stream to, tangent positive edge used to
silently fail. Fix it to show error message.
2015-01-30 20:18:18 +02:00
Ilari Liusvaara
2312324824 Only exit poll advance on poll to non-00 control 2015-01-30 19:45:46 +02:00
Ilari Liusvaara
8d5783536a Fix CUSTOMFONT text positioning
Coordinate system is supposed to be relative to game area, not draw
area.
2015-01-30 09:42:35 +02:00
Ilari Liusvaara
6e80331962 Remember video settings 2015-01-30 02:30:47 +02:00
Ilari Liusvaara
538128686a Remember volume settings across restarts 2015-01-30 02:16:08 +02:00
Ilari Liusvaara
d507a05237 keymapper: Verify gamepad config write before committing 2015-01-30 01:54:28 +02:00
Ilari Liusvaara
b3c0fc76f9 Makefile: Build cmdhelp before anything else
This should hopefully reduce strange rebuilding going on with cmdhelp
2015-01-28 17:06:51 +02:00
Ilari Liusvaara
7584121717 Add $LSNES_NO_SOUND_IN to disable sound input
It seems that sound input sometimes causes crashes and lockups on
start-up.
2015-01-28 17:01:30 +02:00
Ilari Liusvaara
792bb0867e Lua: Don't lua_error() out of context with pending dtors
That likely would cause memory leaks. Also make a commit in order to
tell apart rr2-β22b1 from rr2-β22.
2015-01-28 13:07:50 +02:00
Ilari Liusvaara
43e2ce5906 lsnes rr2-β22 2015-01-24 17:14:01 +02:00
Ilari Liusvaara
d4c6bd3bbd bsnes: Support IRQ/NMI tracing 2015-01-24 16:48:40 +02:00
Ilari Liusvaara
162a57c950 bsnes: DMA tracing 2015-01-20 10:36:22 +02:00
Ilari Liusvaara
2f9782fd9c Fix bad download crashing the emulator
Turns out the way download timer was stopped was buggy and crashed the
emulator in some cases (especially if download failed or couln't be
loaded).

Abuse the focus timer to clean up download timers, so to avoid timer
stopping and cleaning up itself.
2015-01-19 12:28:02 +02:00
Ilari Liusvaara
8403744ba6 Pluginmanager: Autocreate directory instead of crashing
Pluginmanager was crashing the emulator if opened without autoload
directory existing. Fix it to create the directory (and not crash the
emulator if this fails).
2015-01-19 06:27:10 +02:00
Ilari Liusvaara
0346a1ea3e Readd rule for font.cpp.dep in different way
Turns out Win32 build broke from removing font.cpp.dep
2015-01-17 09:37:38 +02:00
Ilari Liusvaara
94732b0bc4 Remove target for font.cpp.dep
This was causing build failures
2015-01-17 09:26:12 +02:00
Ilari Liusvaara
d09d301849 Add commands and Lua functions to manipulate running speed 2015-01-17 09:25:50 +02:00
Ilari Liusvaara
ac51bf61e8 Clean up all build helper programs on make clean 2015-01-16 05:45:05 +02:00
Ilari Liusvaara
201d65116a Fix compile error with Lua 5.1 2015-01-14 03:29:06 +02:00
Ilari Liusvaara
346ea41e0d Fix Win32 build 2015-01-13 22:49:32 +02:00
Ilari Liusvaara
680be72a8f Add wide (64 bits) versions of bit functions if Lua 5.3 is used 2015-01-06 19:20:25 +02:00
Ilari Liusvaara
71b57756ca Cleanup Lua multiversion support 2015-01-06 08:13:10 +02:00
Ilari Liusvaara
f4c1bc6e84 Lua 5.3 support 2015-01-06 05:19:39 +02:00
Ilari Liusvaara
50fd1b6b5f Don't let one unload currently used core (crashes the emulator) 2015-01-06 02:55:03 +02:00
Ilari Liusvaara
aff0370e35 Show error from Lua if parsing Lua expression fails 2015-01-03 02:24:38 +02:00
Ilari Liusvaara
667f7df3c1 Don't use arbitrary garbage as amount of samples to squash 2015-01-02 02:37:03 +02:00
Ilari Liusvaara
f68459ac53 Ignore some build helper programs, now that the .exe rule doesn't cover those 2015-01-01 21:47:47 +02:00
Ilari Liusvaara
696cab4862 Fattest? Really? 2015-01-01 21:42:26 +02:00
Ilari Liusvaara
82b7c8d5e2 Use $DOT_EXECUTABLE_SUFFIX instead of hardcoding .exe 2015-01-01 21:41:39 +02:00
Ilari Liusvaara
16da5396aa Remove some utilities that should not be there anymore 2015-01-01 21:26:37 +02:00
Ilari Liusvaara
0e844d4720 Libao: Don't crash on quit 2015-01-01 21:09:09 +02:00
Ilari Liusvaara
9c484d819e Update the default build options
Remove references to SDL, which hasn't been supported for a while, make
bsnes default to compat and switch to std::thread by default
2015-01-01 20:34:02 +02:00
Ilari Liusvaara
4262be0b93 Exit immediately on double fault 2014-12-31 00:11:57 +02:00
Ilari Liusvaara
37d587da21 Fix some valgrind warnings 2014-12-30 23:59:17 +02:00
Ilari Liusvaara
5dedb34943 Lua: PALETTE:get() 2014-12-20 06:38:47 +02:00
Ilari Liusvaara
b074cb2e31 Fix some nondeterminism (probably wouldn't cause desyncs) 2014-12-19 18:12:43 +02:00
Ilari Liusvaara
0ae6981b5c Redraw framebuffer when entering break pause
Fixes memory watches with tracelogging.
2014-12-13 00:10:34 +02:00
Ilari Liusvaara
dc0a6e1282 Portaudio: Don't blacklist ALSA default/sysdefault for input 2014-12-11 08:50:27 +02:00
Ilari Liusvaara
386405aace Oops from previous commit 2014-12-11 08:21:32 +02:00
Ilari Liusvaara
0ea814c0c3 wxwidgets: Add some missing conversions for string arguments 2014-12-11 08:18:49 +02:00
Ilari Liusvaara
03a57aa421 runuifun: Allow marking cb routine to run once at a time 2014-12-10 08:55:02 +02:00
Ilari Liusvaara
4d86f19837 Add the UI thread checking code
Might still have some false positives.
2014-12-09 16:46:50 +02:00
Ilari Liusvaara
0e29ab43eb Memory editor: Squash another wrong-thread bug
This appears if ROM is loaded for any reason while memory editor is open.
2014-12-09 16:36:59 +02:00
Ilari Liusvaara
a98208c284 Squash some wrong-thread bugs 2014-12-09 13:33:28 +02:00
Ilari Liusvaara
4b44f8ee10 If project switch loads savestate, mark position at point of save 2014-12-04 22:21:41 +02:00
Ilari Liusvaara
b6349a0980 Fix error message if trying to load ROM with project active 2014-12-04 09:58:01 +02:00
Ilari Liusvaara
03de099aae Fix most hotkeys to show up in configuration (were missing due to errant !) 2014-12-03 08:50:52 +02:00
Ilari Liusvaara
8e6eb72351 Wxwidgets: Fix loading ROM from commandline 2014-11-28 18:51:28 +02:00
Ilari Liusvaara
d19d0e8945 Music playback: Guard against crazy pcmpos
Previously crazy pcmpos values could cause division by zero or signed
overflows.
2014-11-27 19:31:01 +02:00
Ilari Liusvaara
3146ec5352 Tracelogger: Unregister the frame callback even on hard kill
Fixes memory corruption if ROM is reloaded and then tracelogger window
is closed.
2014-11-27 16:44:58 +02:00
Ilari Liusvaara
60f9d3b217 bsnes: Add hcounter/vcounter registers 2014-11-24 12:42:29 +02:00
Ilari Liusvaara
514984671d Don't try to unregister killed debug CBs 2014-11-24 11:26:47 +02:00
Ilari Liusvaara
9fdd0bdd38 Tweak format of command help files and do some further command cleanup 2014-11-18 16:19:01 +02:00
Ilari Liusvaara
028a51066c Show VMA relative hex address when dumping debug hook list 2014-11-18 07:43:05 +02:00
Ilari Liusvaara
4ab23cfeb4 Remove unused function 2014-11-17 21:39:47 +02:00
335 changed files with 9166 additions and 3506 deletions

4
.gitignore vendored
View file

@ -17,3 +17,7 @@ src/fonts/font.cpp
src/core/version.cpp
src/cmdhelp/*.cpp
include/cmdhelp/*.hpp
src/emulation/make-ports
src/cmdhelp/mkstubs
src/cmdhelp/mkstubsi
buildaux/mkdeps

6
.gitmodules vendored Normal file
View file

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

308
CHANGELOG
View file

@ -1819,3 +1819,311 @@ 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

View file

@ -20,7 +20,8 @@ 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) -lboost_regex$(BOOST_LIB_POSTFIX) -lz $(USER_LDFLAGS)
LDFLAGS = -pthread -lboost_iostreams$(BOOST_LIB_POSTFIX) -lboost_filesystem$(BOOST_LIB_POSTFIX) -lboost_system$(BOOST_LIB_POSTFIX) -lz $(USER_LDFLAGS)
HOSTHELPER_LDFLAGS =
ifeq ($(THREADS), NATIVE)
CFLAGS += -DNATIVE_THREADS
@ -33,6 +34,14 @@ $(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
@ -70,26 +79,28 @@ bsnes/out/libsnes.$(ARCHIVE_SUFFIX): forcelook
$(REALRANLIB) bsnes/out/libsnes.$(ARCHIVE_SUFFIX)
src/__all_files__: src/core/version.cpp buildaux/mkdeps.exe buildaux/txt2cstr.exe forcelook
src/__all_files__: src/core/version.cpp buildaux/mkdeps$(DOT_EXECUTABLE_SUFFIX) buildaux/txt2cstr$(DOT_EXECUTABLE_SUFFIX) forcelook
$(MAKE) -C src precheck
$(MAKE) -C src
cp src/lsnes$(DOT_EXECUTABLE_SUFFIX) .
buildaux/txt2cstr.exe: buildaux/txt2cstr.cpp
buildaux/txt2cstr$(DOT_EXECUTABLE_SUFFIX): buildaux/txt2cstr.cpp
$(HOSTCC) $(HOSTCCFLAGS) -o $@ $<
buildaux/version.exe: buildaux/version.cpp VERSION
buildaux/version$(DOT_EXECUTABLE_SUFFIX): buildaux/version.cpp VERSION
$(HOSTCC) $(HOSTCCFLAGS) -o $@ $<
buildaux/mkdeps.exe: buildaux/mkdeps.cpp VERSION
buildaux/mkdeps$(DOT_EXECUTABLE_SUFFIX): buildaux/mkdeps.cpp VERSION
$(HOSTCC) $(HOSTCCFLAGS) -o $@ $< -lboost_filesystem$(HOST_BOOST_POSTFIX) -lboost_system$(HOST_BOOST_POSTFIX)
src/core/version.cpp: buildaux/version.exe forcelook
buildaux/version.exe >$@
src/core/version.cpp: buildaux/version$(DOT_EXECUTABLE_SUFFIX) forcelook
buildaux/version$(DOT_EXECUTABLE_SUFFIX) >$@
platclean:
$(MAKE) -C src platclean
clean:
$(MAKE) -C src clean
rm -f buildaux/version.exe
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 Normal file
View file

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

View file

@ -1 +1 @@
2-β21
2-β23

1
bsnes Submodule

@ -0,0 +1 @@
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/21] Make libsnes compile
Subject: [PATCH 01/27] 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 fbb4482..5f5ded6 100755
index fbb4482c..5f5ded69 100755
--- a/ui-libsnes/libsnes.cpp
+++ b/ui-libsnes/libsnes.cpp
@@ -1,5 +1,6 @@
@ -78,5 +78,5 @@ index fbb4482..5f5ded6 100755
}
SNES::cartridge.load(SNES::Cartridge::Mode::SuperGameBoy, xmlrom);
--
2.0.0
2.15.0.rc1

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/21] Fix bsnes version number in libsnes to be v085, not
Subject: [PATCH 02/27] Fix bsnes version number in libsnes to be v085, not
v083
---
@ -9,7 +9,7 @@ Subject: [PATCH 02/21] 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 5f5ded6..0e63075 100755
index 5f5ded69..0e63075e 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 5f5ded6..0e63075 100755
unsigned snes_library_revision_major(void) {
--
2.0.0
2.15.0.rc1

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/21] Don't use time() in emulating chips
Subject: [PATCH 03/27] 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 386fb62..3c98019 100755
index 386fb628..3c980195 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 386fb62..3c98019 100755
regs.r2192_hour = t->tm_hour;
diff --git a/snes/chip/spc7110/spc7110.cpp b/snes/chip/spc7110/spc7110.cpp
index d2dc640..74a817a 100755
index d2dc640b..74a817a6 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 d2dc640..74a817a 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 1b2fd2a..78fc4c1 100755
index 1b2fd2aa..78fc4c1f 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 1b2fd2a..78fc4c1 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 a0e3a81..b3017c9 100755
index a0e3a81b..b3017c90 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 a0e3a81..b3017c9 100755
+
}
diff --git a/snes/interface/interface.hpp b/snes/interface/interface.hpp
index f1a48c0..df975e8 100755
index f1a48c0f..df975e83 100755
--- a/snes/interface/interface.hpp
+++ b/snes/interface/interface.hpp
@@ -5,6 +5,7 @@ struct Interface {
@ -80,5 +80,5 @@ index f1a48c0..df975e8 100755
extern Interface *interface;
--
2.0.0
2.15.0.rc1

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/21] Save controller state when savestating
Subject: [PATCH 04/27] 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 9091b21..f254bed 100755
index 9091b21b..f254bedb 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 9091b21..f254bed 100755
+
}
diff --git a/snes/controller/controller.hpp b/snes/controller/controller.hpp
index 7332712..827b2eb 100755
index 73327129..827b2eb4 100755
--- a/snes/controller/controller.hpp
+++ b/snes/controller/controller.hpp
@@ -13,12 +13,14 @@
@ -64,7 +64,7 @@ index 7332712..827b2eb 100755
bool iobit();
void iobit(bool data);
diff --git a/snes/controller/gamepad/gamepad.cpp b/snes/controller/gamepad/gamepad.cpp
index 594020d..4fa1c99 100755
index 594020d2..4fa1c99e 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 594020d..4fa1c99 100755
latched = 0;
counter = 0;
diff --git a/snes/controller/gamepad/gamepad.hpp b/snes/controller/gamepad/gamepad.hpp
index c5ca69c..a2392d1 100755
index c5ca69ca..a2392d1e 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 c5ca69c..a2392d1 100755
bool latched;
unsigned counter;
diff --git a/snes/controller/justifier/justifier.cpp b/snes/controller/justifier/justifier.cpp
index 6207916..ad13a9b 100755
index 62079166..ad13a9bd 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 6207916..ad13a9b 100755
create(Controller::Enter, 21477272);
latched = 0;
diff --git a/snes/controller/justifier/justifier.hpp b/snes/controller/justifier/justifier.hpp
index f927acf..6b7bba0 100755
index f927acf6..6b7bba07 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 f927acf..6b7bba0 100755
//private:
diff --git a/snes/controller/mouse/mouse.cpp b/snes/controller/mouse/mouse.cpp
index c9f5d16..6b26fae 100755
index c9f5d16b..6b26fae5 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 c9f5d16..6b26fae 100755
latched = 0;
counter = 0;
diff --git a/snes/controller/mouse/mouse.hpp b/snes/controller/mouse/mouse.hpp
index 95e24b6..b66ea51 100755
index 95e24b65..b66ea513 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 95e24b6..b66ea51 100755
bool latched;
unsigned counter;
diff --git a/snes/controller/multitap/multitap.cpp b/snes/controller/multitap/multitap.cpp
index 3a6eb72..146c41d 100755
index 3a6eb720..146c41d4 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 3a6eb72..146c41d 100755
latched = 0;
counter1 = 0;
diff --git a/snes/controller/multitap/multitap.hpp b/snes/controller/multitap/multitap.hpp
index 0540af7..e6324ac 100755
index 0540af71..e6324ac5 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 0540af7..e6324ac 100755
bool latched;
unsigned counter1;
diff --git a/snes/controller/superscope/superscope.cpp b/snes/controller/superscope/superscope.cpp
index 12068f0..1a1dfbf 100755
index 12068f05..1a1dfbff 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 12068f0..1a1dfbf 100755
create(Controller::Enter, 21477272);
latched = 0;
diff --git a/snes/controller/superscope/superscope.hpp b/snes/controller/superscope/superscope.hpp
index a7a90b7..93509d7 100755
index a7a90b71..93509d79 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 a7a90b7..93509d7 100755
//private:
diff --git a/snes/system/input.cpp b/snes/system/input.cpp
index 9050310..ec5559d 100755
index 90503106..ec5559dc 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 9050310..ec5559d 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 13ef46e..6832e82 100755
index 13ef46e1..6832e823 100755
--- a/snes/system/input.hpp
+++ b/snes/system/input.hpp
@@ -31,6 +31,7 @@ struct Input {
@ -330,7 +330,7 @@ index 13ef46e..6832e82 100755
Input();
~Input();
diff --git a/snes/system/serialization.cpp b/snes/system/serialization.cpp
index f7d6f3b..08e7051 100755
index f7d6f3b1..08e70510 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 f7d6f3b..08e7051 100755
if(cartridge.mode() == Cartridge::Mode::SufamiTurbo) sufamiturbo.serialize(s);
if(cartridge.mode() == Cartridge::Mode::SuperGameBoy) icd2.serialize(s);
--
2.0.0
2.15.0.rc1

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/21] Fix unserialization of 64-bit signed integers
Subject: [PATCH 05/27] 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 ff2337a..e6bc8fa 100755
index ff2337ab..e6bc8fad 100755
--- a/nall/serializer.hpp
+++ b/nall/serializer.hpp
@@ -58,7 +58,7 @@ namespace nall {
@ -21,5 +21,5 @@ index ff2337a..e6bc8fa 100755
isize += size;
}
--
2.0.0
2.15.0.rc1

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/21] Allow frontend to control random number seed
Subject: [PATCH 06/27] Allow frontend to control random number seed
---
snes/interface/interface.cpp | 5 +++++
@ -10,7 +10,7 @@ Subject: [PATCH 06/21] 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 b3017c9..0a21a13 100755
index b3017c90..0a21a132 100755
--- a/snes/interface/interface.cpp
+++ b/snes/interface/interface.cpp
@@ -23,4 +23,9 @@ time_t Interface::currentTime()
@ -24,7 +24,7 @@ index b3017c9..0a21a13 100755
+
}
diff --git a/snes/interface/interface.hpp b/snes/interface/interface.hpp
index df975e8..30ee7fd 100755
index df975e83..30ee7fde 100755
--- a/snes/interface/interface.hpp
+++ b/snes/interface/interface.hpp
@@ -6,6 +6,7 @@ struct Interface {
@ -36,7 +36,7 @@ index df975e8..30ee7fd 100755
extern Interface *interface;
diff --git a/snes/system/system.cpp b/snes/system/system.cpp
index c19a7c5..dbd912d 100755
index c19a7c51..dbd912d8 100755
--- a/snes/system/system.cpp
+++ b/snes/system/system.cpp
@@ -146,7 +146,7 @@ void System::unload() {
@ -49,5 +49,5 @@ index c19a7c5..dbd912d 100755
region = config.region;
expansion = config.expansion_port;
--
2.0.0
2.15.0.rc1

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/21] Fix mouse polling
Subject: [PATCH 07/27] 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 6b26fae..1a066b9 100755
index 6b26fae5..1a066b98 100755
--- a/snes/controller/mouse/mouse.cpp
+++ b/snes/controller/mouse/mouse.cpp
@@ -3,9 +3,13 @@
@ -48,7 +48,7 @@ index 6b26fae..1a066b9 100755
}
diff --git a/snes/controller/mouse/mouse.hpp b/snes/controller/mouse/mouse.hpp
index b66ea51..b07c8ab 100755
index b66ea513..b07c8ab7 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 b66ea51..b07c8ab 100755
+ int _position_y;
};
--
2.0.0
2.15.0.rc1

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/21] Fix uninitialized variables
Subject: [PATCH 08/27] 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 d0c9e07..c6809f7 100755
index d0c9e077..c6809f73 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 d0c9e07..c6809f7 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 1a3835b..a21e5e3 100755
index 1a3835b3..a21e5e31 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 1a3835b..a21e5e3 100755
}
diff --git a/snes/cpu/core/core.cpp b/snes/cpu/core/core.cpp
index 427176b..a5b809b 100755
index 427176b0..a5b809b9 100755
--- a/snes/cpu/core/core.cpp
+++ b/snes/cpu/core/core.cpp
@@ -86,4 +86,12 @@ CPUcore::CPUcore() {
@ -68,7 +68,7 @@ index 427176b..a5b809b 100755
+
}
diff --git a/snes/cpu/core/core.hpp b/snes/cpu/core/core.hpp
index 964bd12..7a685a8 100755
index 964bd128..7a685a8d 100755
--- a/snes/cpu/core/core.hpp
+++ b/snes/cpu/core/core.hpp
@@ -7,6 +7,8 @@ struct CPUcore {
@ -81,7 +81,7 @@ index 964bd12..7a685a8 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 f6ae975..2d7d343 100755
index f6ae9754..2d7d3432 100755
--- a/snes/cpu/cpu.cpp
+++ b/snes/cpu/cpu.cpp
@@ -125,6 +125,7 @@ void CPU::power() {
@ -93,7 +93,7 @@ index f6ae975..2d7d343 100755
void CPU::reset() {
diff --git a/snes/smp/core/core.cpp b/snes/smp/core/core.cpp
index 9c94d00..2fc29be 100755
index 9c94d00a..2fc29be1 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 9c94d00..2fc29be 100755
+
}
diff --git a/snes/smp/core/core.hpp b/snes/smp/core/core.hpp
index 6adf6f6..1489fce 100755
index 6adf6f6b..1489fcef 100755
--- a/snes/smp/core/core.hpp
+++ b/snes/smp/core/core.hpp
@@ -11,6 +11,8 @@ struct SMPcore {
@ -126,7 +126,7 @@ index 6adf6f6..1489fce 100755
string disassemble_opcode(uint16 addr);
diff --git a/snes/smp/smp.cpp b/snes/smp/smp.cpp
index 9080624..d4ccf42 100755
index 90806245..d4ccf425 100755
--- a/snes/smp/smp.cpp
+++ b/snes/smp/smp.cpp
@@ -53,6 +53,7 @@ void SMP::power() {
@ -138,5 +138,5 @@ index 9080624..d4ccf42 100755
void SMP::reset() {
--
2.0.0
2.15.0.rc1

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/21] Add needed support for detecting true polls as opposed
Subject: [PATCH 09/27] Add needed support for detecting true polls as opposed
to just autopolling
---
@ -10,7 +10,7 @@ Subject: [PATCH 09/21] 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 3da865e..4944577 100755
index 3da865e2..49445773 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 3da865e..4944577 100755
#include "dma/dma.hpp"
#include "memory/memory.hpp"
diff --git a/snes/cpu/mmio/mmio.cpp b/snes/cpu/mmio/mmio.cpp
index 8b6aaa6..c5ee930 100755
index 8b6aaa6a..c5ee930f 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 8b6aaa6..c5ee930 100755
//DMAPx
uint8 CPU::mmio_r43x0(uint8 i) {
--
2.0.0
2.15.0.rc1

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/21] Fix compiling on GCC 4.7
Subject: [PATCH 10/27] 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 1b255ce..07a64df 100755
index 1b255ce2..07a64dfc 100755
--- a/nall/string.hpp
+++ b/nall/string.hpp
@@ -25,8 +25,8 @@
@ -22,5 +22,5 @@ index 1b255ce..07a64df 100755
#include <nall/string/convert.hpp>
#include <nall/string/cstring.hpp>
--
2.0.0
2.15.0.rc1

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/21] Support notifying latches
Subject: [PATCH 11/27] Support notifying latches
---
snes/cpu/mmio/mmio.cpp | 1 +
@ -11,7 +11,7 @@ Subject: [PATCH 11/21] Support notifying latches
4 files changed, 8 insertions(+)
diff --git a/snes/cpu/mmio/mmio.cpp b/snes/cpu/mmio/mmio.cpp
index c5ee930..b7afff0 100755
index c5ee930f..b7afff00 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 c5ee930..b7afff0 100755
input.port2->latch(data & 1);
}
diff --git a/snes/cpu/timing/joypad.cpp b/snes/cpu/timing/joypad.cpp
index 179df27..6a98de0 100755
index 179df27d..6a98de00 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 179df27..6a98de0 100755
input.port2->latch(1);
input.port1->latch(0);
diff --git a/snes/interface/interface.cpp b/snes/interface/interface.cpp
index 0a21a13..6685556 100755
index 0a21a132..6685556c 100755
--- a/snes/interface/interface.cpp
+++ b/snes/interface/interface.cpp
@@ -28,4 +28,9 @@ time_t Interface::randomSeed()
@ -49,7 +49,7 @@ index 0a21a13..6685556 100755
+
}
diff --git a/snes/interface/interface.hpp b/snes/interface/interface.hpp
index 30ee7fd..203f7b0 100755
index 30ee7fde..203f7b0c 100755
--- a/snes/interface/interface.hpp
+++ b/snes/interface/interface.hpp
@@ -7,6 +7,7 @@ struct Interface {
@ -61,5 +61,5 @@ index 30ee7fd..203f7b0 100755
extern Interface *interface;
--
2.0.0
2.15.0.rc1

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/21] Support unlimited number of breakpoints
Subject: [PATCH 12/27] Support unlimited number of breakpoints
---
snes/alt/cpu/cpu.cpp | 22 +++++++-------
@ -40,7 +40,7 @@ Subject: [PATCH 12/21] 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 814908d..dcbb92d 100755
index 814908d0..dcbb92d3 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 814908d..dcbb92d 100755
void CPU::power() {
diff --git a/snes/alt/ppu-compatibility/ppu.cpp b/snes/alt/ppu-compatibility/ppu.cpp
index a21e5e3..122b143 100755
index a21e5e31..122b1430 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 a21e5e3..122b143 100755
void PPU::power() {
diff --git a/snes/alt/ppu-parallel/ppu.cpp b/snes/alt/ppu-parallel/ppu.cpp
index 1c3dcb7..8dd118b 100755
index 1c3dcb70..8dd118b2 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 1c3dcb7..8dd118b 100755
void PPU::power() {
diff --git a/snes/alt/ppu-performance/ppu.cpp b/snes/alt/ppu-performance/ppu.cpp
index 7c231bc..4b2b294 100755
index 7c231bc0..4b2b2948 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 7c231bc..4b2b294 100755
void PPU::power() {
diff --git a/snes/cartridge/cartridge.hpp b/snes/cartridge/cartridge.hpp
index 37555bc..82e73c4 100755
index 37555bc0..82e73c4c 100755
--- a/snes/cartridge/cartridge.hpp
+++ b/snes/cartridge/cartridge.hpp
@@ -12,6 +12,22 @@ struct Cartridge : property<Cartridge> {
@ -160,7 +160,7 @@ index 37555bc..82e73c4 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 e639fe5..2dd0d64 100755
index e639fe52..2dd0d646 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 e639fe5..2dd0d64 100755
write = { &Memory::write, &memory };
mode = Bus::MapMode::Direct;
diff --git a/snes/cheat/cheat.cpp b/snes/cheat/cheat.cpp
index 46c42d1..3a269cc 100755
index 46c42d1c..3a269cc5 100755
--- a/snes/cheat/cheat.cpp
+++ b/snes/cheat/cheat.cpp
@@ -21,9 +21,9 @@ void Cheat::synchronize() {
@ -283,7 +283,7 @@ index 46c42d1..3a269cc 100755
}
}
diff --git a/snes/cheat/cheat.hpp b/snes/cheat/cheat.hpp
index 306b99b..b4d2a42 100755
index 306b99b1..b4d2a42e 100755
--- a/snes/cheat/cheat.hpp
+++ b/snes/cheat/cheat.hpp
@@ -1,6 +1,7 @@
@ -295,7 +295,7 @@ index 306b99b..b4d2a42 100755
struct Cheat : public linear_vector<CheatCode> {
diff --git a/snes/chip/bsx/satellaview/satellaview.cpp b/snes/chip/bsx/satellaview/satellaview.cpp
index 3c98019..25af8e5 100755
index 3c980195..25af8e56 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 3c98019..25af8e5 100755
void BSXSatellaview::unload() {
diff --git a/snes/chip/hitachidsp/hitachidsp.cpp b/snes/chip/hitachidsp/hitachidsp.cpp
index 1042267..3e5c5bd 100755
index 1042267e..3e5c5bdb 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 1042267..3e5c5bd 100755
}
state = State::Idle;
diff --git a/snes/chip/hitachidsp/memory.cpp b/snes/chip/hitachidsp/memory.cpp
index 3c9c3af..36868e8 100755
index 3c9c3af1..36868e88 100755
--- a/snes/chip/hitachidsp/memory.cpp
+++ b/snes/chip/hitachidsp/memory.cpp
@@ -1,7 +1,7 @@
@ -336,7 +336,7 @@ index 3c9c3af..36868e8 100755
}
diff --git a/snes/chip/nss/nss.cpp b/snes/chip/nss/nss.cpp
index 964973d..5946af3 100755
index 964973d0..5946af3b 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 964973d..5946af3 100755
void NSS::unload() {
diff --git a/snes/chip/sa1/memory/memory.cpp b/snes/chip/sa1/memory/memory.cpp
index d13ac92..9bb4ff2 100755
index d13ac929..9bb4ff20 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 d13ac92..9bb4ff2 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 ffb9e9f..ab8e1ed 100755
index ffb9e9f6..ab8e1edd 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 ffb9e9f..ab8e1ed 100755
uint8 mmc_read(unsigned addr);
diff --git a/snes/chip/sa1/sa1.cpp b/snes/chip/sa1/sa1.cpp
index 71c6310..30e0080 100755
index 71c6310a..30e00809 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 71c6310..30e0080 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 c9b8b1c..5d6cc55 100755
index c9b8b1c4..5d6cc55f 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 c9b8b1c..5d6cc55 100755
void SDD1::unload() {
diff --git a/snes/cpu/core/core.hpp b/snes/cpu/core/core.hpp
index 7a685a8..9d77f3c 100755
index 7a685a8d..9d77f3c5 100755
--- a/snes/cpu/core/core.hpp
+++ b/snes/cpu/core/core.hpp
@@ -10,7 +10,7 @@ struct CPUcore {
@ -418,7 +418,7 @@ index 7a685a8..9d77f3c 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 030b3ab..ab8dde2 100755
index 030b3ab5..ab8dde24 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 030b3ab..ab8dde2 100755
uint16 CPUcore::dreadw(uint32 addr) {
diff --git a/snes/cpu/core/memory.hpp b/snes/cpu/core/memory.hpp
index 4992657..132501c 100755
index 49926578..132501c1 100755
--- a/snes/cpu/core/memory.hpp
+++ b/snes/cpu/core/memory.hpp
@@ -1,5 +1,5 @@
@ -442,7 +442,7 @@ index 4992657..132501c 100755
alwaysinline uint8_t op_readstack() {
diff --git a/snes/cpu/cpu.cpp b/snes/cpu/cpu.cpp
index 2d7d343..39da6b1 100755
index 2d7d3432..39da6b16 100755
--- a/snes/cpu/cpu.cpp
+++ b/snes/cpu/cpu.cpp
@@ -78,8 +78,8 @@ void CPU::enter() {
@ -493,7 +493,7 @@ index 2d7d343..39da6b1 100755
void CPU::power() {
diff --git a/snes/cpu/debugger/debugger.cpp b/snes/cpu/debugger/debugger.cpp
index a33518e..8301bdb 100755
index a33518ed..8301bdb6 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 a33518e..8301bdb 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 579f6f0..c3d66db 100755
index 579f6f03..c3d66db5 100755
--- a/snes/cpu/debugger/debugger.hpp
+++ b/snes/cpu/debugger/debugger.hpp
@@ -16,7 +16,7 @@ public:
@ -521,7 +521,7 @@ index 579f6f0..c3d66db 100755
CPUDebugger();
diff --git a/snes/cpu/dma/dma.cpp b/snes/cpu/dma/dma.cpp
index e8cdb3e..0a00bfe 100755
index e8cdb3ec..0a00bfea 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 e8cdb3e..0a00bfe 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 c2c8f1f..31f82c3 100755
index c2c8f1fa..31f82c31 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 c2c8f1f..31f82c3 100755
alu_edge();
return regs.mdr;
diff --git a/snes/cpu/memory/memory.hpp b/snes/cpu/memory/memory.hpp
index d33861d..fd64ba8 100755
index d33861d4..fd64ba8b 100755
--- a/snes/cpu/memory/memory.hpp
+++ b/snes/cpu/memory/memory.hpp
@@ -1,4 +1,4 @@
@ -571,7 +571,7 @@ index d33861d..fd64ba8 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 b7afff0..30048c1 100755
index b7afff00..30048c19 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 b7afff0..30048c1 100755
//WMDATA
diff --git a/snes/debugger/debugger.cpp b/snes/debugger/debugger.cpp
index b131233..e8d0f5a 100755
index b1312339..e8d0f5af 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 b131233..e8d0f5a 100755
case MemorySource::APUBus: {
diff --git a/snes/memory/memory-inline.hpp b/snes/memory/memory-inline.hpp
index 70503be..45f150c 100755
index 70503bea..45f150c9 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 70503be..45f150c 100755
return writer[lookup[addr]](target[addr], data);
}
diff --git a/snes/memory/memory.cpp b/snes/memory/memory.cpp
index ede9cbd..a9a484a 100755
index ede9cbd0..a9a484a0 100755
--- a/snes/memory/memory.cpp
+++ b/snes/memory/memory.cpp
@@ -27,6 +27,7 @@ void Bus::map(
@ -715,7 +715,7 @@ index ede9cbd..a9a484a 100755
}
diff --git a/snes/memory/memory.hpp b/snes/memory/memory.hpp
index 634e071..c20e14d 100755
index 634e0717..c20e14db 100755
--- a/snes/memory/memory.hpp
+++ b/snes/memory/memory.hpp
@@ -44,10 +44,13 @@ private:
@ -756,7 +756,7 @@ index 634e071..c20e14d 100755
~Bus();
};
diff --git a/snes/ppu/ppu.cpp b/snes/ppu/ppu.cpp
index 8545175..13e231c 100755
index 8545175f..13e231cf 100755
--- a/snes/ppu/ppu.cpp
+++ b/snes/ppu/ppu.cpp
@@ -87,8 +87,8 @@ void PPU::enable() {
@ -771,7 +771,7 @@ index 8545175..13e231c 100755
void PPU::power() {
diff --git a/snes/smp/core/core.hpp b/snes/smp/core/core.hpp
index 1489fce..13d6936 100755
index 1489fcef..13d69364 100755
--- a/snes/smp/core/core.hpp
+++ b/snes/smp/core/core.hpp
@@ -2,7 +2,7 @@ struct SMPcore {
@ -784,7 +784,7 @@ index 1489fce..13d6936 100755
#include "registers.hpp"
#include "memory.hpp"
diff --git a/snes/snes.hpp b/snes/snes.hpp
index dffeeee..37ed1fe 100755
index dffeeee3..37ed1feb 100755
--- a/snes/snes.hpp
+++ b/snes/snes.hpp
@@ -1,5 +1,6 @@
@ -795,5 +795,5 @@ index dffeeee..37ed1fe 100755
namespace SNES {
namespace Info {
--
2.0.0
2.15.0.rc1

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/21] Support auto-detecting bsnes version
Subject: [PATCH 13/27] Support auto-detecting bsnes version
---
bsnes.mk | 3 +++
@ -10,7 +10,7 @@ Subject: [PATCH 13/21] Support auto-detecting bsnes version
diff --git a/bsnes.mk b/bsnes.mk
new file mode 100644
index 0000000..20f22f6
index 00000000..20f22f61
--- /dev/null
+++ b/bsnes.mk
@@ -0,0 +1,3 @@
@ -18,5 +18,5 @@ index 0000000..20f22f6
+LIBSNES_DIR=ui-libsnes
+BSNES_VERSION=085
--
2.0.0
2.15.0.rc1

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/21] Support alternate (more accurate) poll timings
Subject: [PATCH 14/27] Support alternate (more accurate) poll timings
---
snes/config/config.cpp | 1 +
@ -13,7 +13,7 @@ Subject: [PATCH 14/21] 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 701af94..206daae 100755
index 701af94c..206daae0 100755
--- a/snes/config/config.cpp
+++ b/snes/config/config.cpp
@@ -13,6 +13,7 @@ Configuration::Configuration() {
@ -25,7 +25,7 @@ index 701af94..206daae 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 1f4d037..dabde59 100755
index 1f4d037c..dabde597 100755
--- a/snes/config/config.hpp
+++ b/snes/config/config.hpp
@@ -10,6 +10,7 @@ struct Configuration {
@ -37,7 +37,7 @@ index 1f4d037..dabde59 100755
struct SMP {
diff --git a/snes/cpu/timing/joypad.cpp b/snes/cpu/timing/joypad.cpp
index 6a98de0..ae8e94f 100755
index 6a98de00..ae8e94f8 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 6a98de0..ae8e94f 100755
+
#endif
diff --git a/snes/cpu/timing/timing.cpp b/snes/cpu/timing/timing.cpp
index f1378f0..d7cf24f 100755
index f1378f0c..d7cf24f3 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 f1378f0..d7cf24f 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 6c225da..bf15a72 100755
index 6c225dab..bf15a727 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 6c225da..bf15a72 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 37ed1fe..4e3ba64 100755
index 37ed1feb..4e3ba64c 100755
--- a/snes/snes.hpp
+++ b/snes/snes.hpp
@@ -1,6 +1,7 @@
@ -134,5 +134,5 @@ index 37ed1fe..4e3ba64 100755
namespace SNES {
namespace Info {
--
2.0.0
2.15.0.rc1

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/21] Fix mouse speed support
Subject: [PATCH 15/27] Fix mouse speed support
---
snes/config/config.cpp | 1 +
@ -11,7 +11,7 @@ Subject: [PATCH 15/21] Fix mouse speed support
4 files changed, 14 insertions(+), 2 deletions(-)
diff --git a/snes/config/config.cpp b/snes/config/config.cpp
index 206daae..1983137 100755
index 206daae0..19831370 100755
--- a/snes/config/config.cpp
+++ b/snes/config/config.cpp
@@ -8,6 +8,7 @@ Configuration::Configuration() {
@ -23,7 +23,7 @@ index 206daae..1983137 100755
cpu.version = 2;
cpu.ntsc_frequency = 21477272; //315 / 88 * 6000000
diff --git a/snes/config/config.hpp b/snes/config/config.hpp
index dabde59..68fe0bd 100755
index dabde597..68fe0bde 100755
--- a/snes/config/config.hpp
+++ b/snes/config/config.hpp
@@ -1,9 +1,12 @@
@ -40,7 +40,7 @@ index dabde59..68fe0bd 100755
struct CPU {
unsigned version;
diff --git a/snes/controller/mouse/mouse.cpp b/snes/controller/mouse/mouse.cpp
index 1a066b9..caa7a35 100755
index 1a066b98..caa7a358 100755
--- a/snes/controller/mouse/mouse.cpp
+++ b/snes/controller/mouse/mouse.cpp
@@ -1,6 +1,10 @@
@ -87,7 +87,7 @@ index 1a066b9..caa7a35 100755
#endif
diff --git a/snes/controller/mouse/mouse.hpp b/snes/controller/mouse/mouse.hpp
index b07c8ab..13a9313 100755
index b07c8ab7..13a9313e 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 b07c8ab..13a9313 100755
int _position_y;
};
--
2.0.0
2.15.0.rc1

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/21] Fix tracelog of controller registers
Subject: [PATCH 16/27] 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 ab8dde2..624a80c 100755
index ab8dde24..624a80ce 100755
--- a/snes/cpu/core/disassembler/disassembler.cpp
+++ b/snes/cpu/core/disassembler/disassembler.cpp
@@ -1,6 +1,8 @@
@ -21,5 +21,5 @@ index ab8dde2..624a80c 100755
//$[00-3f|80-bf]:[2000-5fff]
//do not read MMIO registers within debugger
--
2.0.0
2.15.0.rc1

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/21] Fix performance problem with non-bus breakpoints
Subject: [PATCH 17/27] Fix performance problem with non-bus breakpoints
---
snes/memory/memory.cpp | 35 ++++++++++++++++++++++++++---------
@ -10,7 +10,7 @@ Subject: [PATCH 17/21] 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 a9a484a..d22e313 100755
index a9a484a0..d22e3137 100755
--- a/snes/memory/memory.cpp
+++ b/snes/memory/memory.cpp
@@ -43,6 +43,7 @@ void Bus::map(
@ -77,7 +77,7 @@ index a9a484a..d22e313 100755
Bus::Bus() {
diff --git a/snes/memory/memory.hpp b/snes/memory/memory.hpp
index c20e14d..ee0c0a9 100755
index c20e14db..ee0c0a9e 100755
--- a/snes/memory/memory.hpp
+++ b/snes/memory/memory.hpp
@@ -52,6 +52,7 @@ struct Bus {
@ -89,7 +89,7 @@ index c20e14d..ee0c0a9 100755
unsigned idcount;
function<uint8 (unsigned)> reader[256];
diff --git a/snes/snes.hpp b/snes/snes.hpp
index 4e3ba64..9589db9 100755
index 4e3ba64c..9589db9b 100755
--- a/snes/snes.hpp
+++ b/snes/snes.hpp
@@ -38,6 +38,7 @@ namespace SNES {
@ -101,5 +101,5 @@ index 4e3ba64..9589db9 100755
#include <gameboy/gameboy.hpp>
--
2.0.0
2.15.0.rc1

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/21] Support VRAM, OAM, CGRAM and APURAM breakpoints
Subject: [PATCH 18/27] Support VRAM, OAM, CGRAM and APURAM breakpoints
---
snes/alt/ppu-compatibility/memory/memory.cpp | 44 +++++++++++++++++++++--
@ -19,7 +19,7 @@ Subject: [PATCH 18/21] 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 3f120d8..e47cf20 100755
index 3f120d84..e47cf201 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 3f120d8..e47cf20 100755
}
}
diff --git a/snes/alt/ppu-compatibility/ppu.hpp b/snes/alt/ppu-compatibility/ppu.hpp
index cccaabb..4adac4c 100755
index cccaabba..4adac4c4 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 cccaabb..4adac4c 100755
enum : bool { Threaded = true };
alwaysinline void step(unsigned clocks);
diff --git a/snes/cartridge/cartridge.hpp b/snes/cartridge/cartridge.hpp
index 82e73c4..2358c08 100755
index 82e73c4c..2358c088 100755
--- a/snes/cartridge/cartridge.hpp
+++ b/snes/cartridge/cartridge.hpp
@@ -26,6 +26,10 @@ struct Cartridge : property<Cartridge> {
@ -171,7 +171,7 @@ index 82e73c4..2358c08 100755
enum class Slot : unsigned {
diff --git a/snes/smp/core/core.hpp b/snes/smp/core/core.hpp
index 13d6936..03f9ac6 100755
index 13d69364..03f9ac66 100755
--- a/snes/smp/core/core.hpp
+++ b/snes/smp/core/core.hpp
@@ -1,6 +1,6 @@
@ -183,7 +183,7 @@ index 13d6936..03f9ac6 100755
virtual void op_step();
diff --git a/snes/smp/core/memory.hpp b/snes/smp/core/memory.hpp
index c4b6d99..c297962 100755
index c4b6d99f..c297962f 100755
--- a/snes/smp/core/memory.hpp
+++ b/snes/smp/core/memory.hpp
@@ -1,9 +1,9 @@
@ -208,7 +208,7 @@ index c4b6d99..c297962 100755
alwaysinline void op_writedp(uint8 addr, uint8 data) {
diff --git a/snes/smp/core/opcodes.cpp b/snes/smp/core/opcodes.cpp
index 95b9844..43db081 100755
index 95b9844f..43db081d 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 95b9844..43db081 100755
}
diff --git a/snes/smp/debugger/debugger.cpp b/snes/smp/debugger/debugger.cpp
index 9546c11..894fdac 100755
index 9546c118..894fdac9 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 9546c11..894fdac 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 d5d28e5..26bc7af 100755
index d5d28e53..26bc7af9 100755
--- a/snes/smp/debugger/debugger.hpp
+++ b/snes/smp/debugger/debugger.hpp
@@ -14,7 +14,7 @@ public:
@ -376,7 +376,7 @@ index d5d28e5..26bc7af 100755
SMPDebugger();
diff --git a/snes/smp/memory/memory.cpp b/snes/smp/memory/memory.cpp
index 391324c..58c1191 100755
index 391324c4..58c11915 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 391324c..58c1191 100755
cycle_edge();
return r;
diff --git a/snes/smp/memory/memory.hpp b/snes/smp/memory/memory.hpp
index 1a07445..faa28da 100755
index 1a07445d..faa28daa 100755
--- a/snes/smp/memory/memory.hpp
+++ b/snes/smp/memory/memory.hpp
@@ -1,9 +1,9 @@
@ -506,7 +506,7 @@ index 1a07445..faa28da 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 6b387cb..6b6ae83 100755
index 6b387cba..6b6ae837 100755
--- a/snes/smp/smp.hpp
+++ b/snes/smp/smp.hpp
@@ -1,6 +1,10 @@
@ -521,7 +521,7 @@ index 6b387cb..6b6ae83 100755
enum : bool { Threaded = true };
alwaysinline void step(unsigned clocks);
diff --git a/snes/snes.hpp b/snes/snes.hpp
index 9589db9..27632bf 100755
index 9589db9b..27632bff 100755
--- a/snes/snes.hpp
+++ b/snes/snes.hpp
@@ -1,6 +1,7 @@
@ -533,5 +533,5 @@ index 9589db9..27632bf 100755
namespace SNES {
--
2.0.0
2.15.0.rc1

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/21] SA1 trace hook support
Subject: [PATCH 19/27] SA1 trace hook support
---
snes/chip/sa1/sa1.cpp | 2 ++
@ -10,7 +10,7 @@ Subject: [PATCH 19/21] SA1 trace hook support
3 files changed, 6 insertions(+)
diff --git a/snes/chip/sa1/sa1.cpp b/snes/chip/sa1/sa1.cpp
index 30e0080..fdec362 100755
index 30e00809..fdec362c 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 30e0080..fdec362 100755
}
}
diff --git a/snes/chip/sa1/sa1.hpp b/snes/chip/sa1/sa1.hpp
index 732b2a8..efd3637 100755
index 732b2a85..efd36376 100755
--- a/snes/chip/sa1/sa1.hpp
+++ b/snes/chip/sa1/sa1.hpp
@@ -15,6 +15,9 @@ public:
@ -37,7 +37,7 @@ index 732b2a8..efd3637 100755
void enter();
void tick();
diff --git a/snes/snes.hpp b/snes/snes.hpp
index 27632bf..3bdca7e 100755
index 27632bff..3bdca7e5 100755
--- a/snes/snes.hpp
+++ b/snes/snes.hpp
@@ -3,6 +3,7 @@
@ -49,5 +49,5 @@ index 27632bf..3bdca7e 100755
namespace SNES {
namespace Info {
--
2.0.0
2.15.0.rc1

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/21] Fixes to SA1 open bus emulation
Subject: [PATCH 20/27] 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 9bb4ff2..614dfb0 100755
index 9bb4ff20..614dfb0c 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 9bb4ff2..614dfb0 100755
uint8 SA1::mmc_read(unsigned addr) {
--
2.0.0
2.15.0.rc1

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/21] Call notify latch function on alternate timings mode
Subject: [PATCH 21/27] Call notify latch function on alternate timings mode
too
---
@ -9,7 +9,7 @@ Subject: [PATCH 21/21] 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 ae8e94f..3fd4d23 100755
index ae8e94f8..3fd4d23e 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 ae8e94f..3fd4d23 100755
input.port2->latch(1);
}
--
2.0.0
2.15.0.rc1

View file

@ -0,0 +1,288 @@
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

@ -0,0 +1,86 @@
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

@ -0,0 +1,50 @@
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

@ -0,0 +1,26 @@
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

@ -0,0 +1,25 @@
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

@ -0,0 +1,377 @@
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,9 +9,27 @@
namespace boost_fs = boost::filesystem;
std::string search_include(const std::list<std::string>& searchpath, const std::string& filename,
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,
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
gambatte Submodule

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

View file

@ -5,6 +5,7 @@
#include <set>
#include <stdexcept>
#include <iostream>
#include <functional>
#include "library/framebuffer.hpp"
#include "library/dispatch.hpp"
@ -105,6 +106,10 @@ public:
*/
virtual dumper_base* start(master_dumper& _mdumper, const std::string& mode, const std::string& targetname)
throw(std::bad_alloc, std::runtime_error) = 0;
/**
* Is hidden?
*/
virtual bool hidden() const { return false; }
/**
* Add dumper update notifier object.
*/

View file

@ -5,6 +5,8 @@
#include <string>
#include <map>
class audioapi_instance;
//All the following need to be implemented by the sound driver itself
struct _audioapi_driver
{
@ -79,4 +81,29 @@ std::map<std::string, std::string> audioapi_driver_get_devices(bool rec) throw(s
*/
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

View file

@ -121,6 +121,9 @@ 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;
@ -138,6 +141,12 @@ 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

@ -9,6 +9,7 @@
class emulator_dispatch;
class loaded_rom;
class memory_space;
/**
* Debugging context.
@ -16,7 +17,7 @@ class loaded_rom;
class debug_context
{
public:
debug_context(emulator_dispatch& _dispatch, loaded_rom& _rom, command::group& _cmd);
debug_context(emulator_dispatch& _dispatch, loaded_rom& _rom, memory_space& _mspace, command::group& _cmd);
/**
* Type of event.
*/
@ -163,6 +164,7 @@ private:
std::function<void()> tracelog_change_cb;
emulator_dispatch& edispatch;
loaded_rom& rom;
memory_space& mspace;
command::group& cmd;
struct dispatch::target<> corechange;
bool corechange_r = false;

View file

@ -5,6 +5,7 @@
#include <string>
#include <set>
#include <map>
#include "library/command.hpp"
#include "library/triplebuffer.hpp"
class movie_logic;
@ -57,13 +58,15 @@ struct _lsnes_status
struct slotinfo_cache
{
slotinfo_cache(movie_logic& _mlogic);
slotinfo_cache(movie_logic& _mlogic, command::group& _cmd);
std::string get(const std::string& _filename);
void flush(const std::string& _filename);
void flush();
private:
std::map<std::string, std::string> cache;
movie_logic& mlogic;
command::group& cmd;
command::_fnptr<> flushcmd;
};
struct status_updater

View file

@ -2,6 +2,7 @@
#define _framebuffer__hpp__included__
#include "core/window.hpp"
#include "core/queue.hpp"
#include "library/command.hpp"
#include "library/framebuffer.hpp"
#include "library/triplebuffer.hpp"
@ -31,7 +32,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);
status_updater& _supdater, command::group& _cmd, input_queue& _iqueue);
/**
* The main framebuffer.
*/
@ -110,6 +111,7 @@ private:
loaded_rom& rom;
status_updater& supdater;
command::group& cmd;
input_queue& iqueue;
command::_fnptr<command::arg_filename> screenshot;
};

View file

@ -21,6 +21,16 @@ 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.
*
@ -84,10 +94,15 @@ 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;
@ -96,11 +111,15 @@ 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

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

View file

@ -6,6 +6,9 @@
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);
void with_unloaded_library(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

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

View file

@ -5,6 +5,7 @@
#include <vector>
#include <stdexcept>
#include "library/string.hpp"
#include "library/memtracker.hpp"
/**
* \brief Fatal error.

View file

@ -77,8 +77,14 @@ public:
*
* parameter subframe: True if this is for subframe update, false if for frame update.
*/
portctrl::frame update_controls(bool subframe) throw(std::bad_alloc, std::runtime_error);
portctrl::frame update_controls(bool subframe, bool forced = false) throw(std::bad_alloc, std::runtime_error);
/**
* Notify user poll (exit poll advance).
*
* returns: If true, update_controls is forced.
*/
bool notify_user_poll() throw(std::bad_alloc, std::runtime_error);
/**
* Release memory for mov, mf and rrd.
*/

View file

@ -51,7 +51,7 @@ extern std::string last_save;
* Parameter secs: The seconds counter.
* Parameter ssecs: The subsecond counter.
*/
void mainloop_restore_state(const std::vector<char>& state, uint64_t secs, uint64_t ssecs);
void mainloop_restore_state(const dynamic_state& state);
std::string get_mprefix_for_project();
void set_mprefix_for_project(const std::string& pfx);

View file

@ -1,6 +1,7 @@
#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
@ -39,4 +40,25 @@ 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,6 +14,69 @@
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.
*/
@ -52,6 +115,24 @@ 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.
*
@ -90,12 +171,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)
void save(const std::string& filename, unsigned compression, bool binary, rrdata_set& rrd, bool as_state)
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) throw(std::bad_alloc, std::runtime_error);
void save(std::ostream& outstream, rrdata_set& rrd, bool as_state) throw(std::bad_alloc, std::runtime_error);
/**
* Force loading as corrupt.
*/
@ -152,46 +233,10 @@ 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.
*/
@ -204,14 +249,6 @@ 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.
*/
@ -233,9 +270,9 @@ struct moviefile
*/
std::map<moviefile_subtiming, std::string> subtitles;
/**
* Active macros at savestate.
* Dynamic state.
*/
std::map<std::string, uint64_t> active_macros;
dynamic_state dyn;
/**
* Get number of frames in movie.
*
@ -274,13 +311,18 @@ 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();
private:
moviefile(const moviefile&);
moviefile& operator=(const moviefile&);
void binary_io(int stream, rrdata_set& rrd) throw(std::bad_alloc, std::runtime_error);
void binary_io(int stream, rrdata_set& rrd, bool as_state) 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 save(zip::writer& w, rrdata_set& rrd, bool as_state) throw(std::bad_alloc, std::runtime_error);
void load(zip::reader& r, core_type& romtype) throw(std::bad_alloc, std::runtime_error);
memtracker::autorelease tracker;
};
void emerg_save_movie(const moviefile& mv, rrdata_set& rrd);

12
include/core/nullcore.hpp Normal file
View file

@ -0,0 +1,12 @@
#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::cache& _setcache, button_mapping& _buttons,
controller_state& _controls, settingvar::group& _setgroup, 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::cache& setcache;
settingvar::group& setgroup;
button_mapping& buttons;
emulator_dispatch& edispatch;
input_queue& iqueue;

View file

@ -4,6 +4,7 @@
#include "library/exrethrow.hpp"
#include "library/keyboard.hpp"
#include "library/threads.hpp"
#include <functional>
#include <deque>
namespace command
@ -65,7 +66,7 @@ struct input_queue
threads::lock queue_lock;
threads::cv queue_condition;
std::deque<keypress_info> keypresses;
std::deque<std::string> commands;
std::deque<std::pair<const char*, std::string>> commands;
std::deque<function_queue_entry> functions;
volatile uint64_t functions_executed;
volatile uint64_t next_function;
@ -91,6 +92,15 @@ struct input_queue
* Parameter c: The command to queue.
*/
void queue(const std::string& c) throw(std::bad_alloc);
/**
* Queue command and arguments.
*
* - Can be called from any thread.
*
* Parameter c: The command to queue.
* Parameter a: The arguments for function.
*/
void queue(const char* c, const std::string& a) throw(std::bad_alloc);
/**
* Queue function to be called in emulation thread.
*

View file

@ -47,4 +47,9 @@ 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,27 +7,10 @@
#include <stdexcept>
#include "core/misc.hpp"
#include "core/rom-small.hpp"
#include "core/romimage.hpp"
#include "interface/romtype.hpp"
#include "library/fileimage.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;
};
/**
* ROM loaded into memory.
*/
@ -38,50 +21,13 @@ struct loaded_rom
*/
loaded_rom() throw();
/**
* Take in ROM filename (or a bundle) and load it to memory.
* Create ROM from image.
*
* parameter file: The file to load
* parameter tmpprefer: The core name to prefer.
* parameter _image: The image to use load
* throws std::bad_alloc: Not enough memory.
* throws std::runtime_error: Loading ROM file failed.
*/
loaded_rom(const std::string& file, const std::string& tmpprefer = "") throw(std::bad_alloc,
std::runtime_error);
/**
* Take a ROM and load it.
*/
loaded_rom(const std::string& file, const std::string& core, const std::string& type,
const std::string& region);
/**
* Load a multi-file ROM.
*/
loaded_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.
*/
loaded_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;
loaded_rom(rom_image_handle _image) throw(std::bad_alloc, std::runtime_error);
/**
* 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.
@ -91,6 +37,10 @@ struct loaded_rom
*/
void load(std::map<std::string, std::string>& settings, uint64_t rtc_sec, uint64_t rtc_subsec)
throw(std::bad_alloc, std::runtime_error);
/**
* Reset the emulation state to state just before last load.
*/
void reset_to_load() { return rtype().reset_to_load(); }
/**
* Saves core state into buffer. WARNING: This takes emulated time.
*
@ -107,19 +57,10 @@ struct loaded_rom
*/
void load_core_state(const std::vector<char>& buf, bool nochecksum = false) throw(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; }
core_type& get_internal_rom_type() { return rtype(); }
/**
* Get internal region representation.
*/
@ -127,95 +68,109 @@ struct loaded_rom
/**
* Is same ROM type?
*/
bool is_of_type(core_type& type) { return (rtype == &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); }
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::string get_core_identifier() { return rtype().get_core_identifier(); }
std::pair<uint32_t, uint32_t> get_scale_factors(uint32_t width, uint32_t height)
{
return rtype->get_scale_factors(width, height);
return rtype().get_scale_factors(width, height);
}
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 || rtype->isnull(); }
std::vector<std::string> get_trace_cpus() { return rtype->get_trace_cpus(); }
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);
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(); }
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);
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 rtype->get_regions(); }
const std::string& get_iname() { return rtype->get_iname(); }
std::map<std::string, std::vector<char>> save_sram() throw(std::bad_alloc) { return rtype->save_sram(); }
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() throw(std::bad_alloc) { return rtype().save_sram(); }
void load_sram(std::map<std::string, std::vector<char>>& sram) throw(std::bad_alloc)
{
rtype->load_sram(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 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(); }
void set_debug_flags(uint64_t addr, unsigned flags_set, unsigned flags_clear)
{
return rtype->set_debug_flags(addr, flags_set, flags_clear);
return rtype().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 rtype().set_cheat(addr, value, set);
}
void debug_reset()
{
rtype->debug_reset();
rtype().debug_reset();
}
//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(); }
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(); }
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); }
bool region_compatible_with(core_region& run)
{
return orig_region && orig_region->compatible_with(run);
return image->get_region().compatible_with(run);
}
private:
/**
* ROM type
*/
core_type* rtype;
/**
* ROM region (this is the currently active region).
*/
core_type& rtype() { return image->get_type(); }
//The internal ROM image.
rom_image_handle image;
//ROM region.
core_region* region;
/**
* ROM original region (this is the region ROM is loaded as).
*/
core_region* orig_region;
};
/**
@ -236,11 +191,6 @@ std::pair<core_type*, core_region*> get_current_rom_info() throw();
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
{
//Pack file to load. Overrides everything else.
@ -260,17 +210,10 @@ 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);
loaded_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

231
include/core/romimage.hpp Normal file
View file

@ -0,0 +1,231 @@
#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 = "") throw(std::bad_alloc,
std::runtime_error);
/**
* 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) throw(std::bad_alloc, std::runtime_error);
/**
* 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) throw(std::bad_alloc, std::runtime_error);
//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)
throw(std::bad_alloc, std::runtime_error);
//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,9 +161,12 @@ 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,4 +5,10 @@
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,6 +49,8 @@ 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

@ -166,6 +166,10 @@ 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; };
@ -202,6 +206,7 @@ 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,6 +51,7 @@ 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>
@ -109,8 +110,9 @@ 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
//Reserved capabilities.
#define LSNES_CORE_CAP1_RESERVED18 0x00040000U
#define LSNES_CORE_CAP1_RESERVED19 0x00080000U
#define LSNES_CORE_CAP1_RESERVED20 0x00100000U
#define LSNES_CORE_CAP1_RESERVED21 0x00200000U
@ -211,7 +213,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.
long text_len;
ssize_t text_len;
//Input: Bytes per pixel to request. Can be 1, 2, 3 or 4.
unsigned bytes_pp;
//Input: Foreground color (native endian).
@ -838,6 +840,16 @@ 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
{
};
#ifdef LSNES_BUILD_AS_BUILTIN_CORE
void lsnes_register_builtin_core(lsnes_core_func_t fn);

View file

@ -9,6 +9,7 @@
#include "interface/setting.hpp"
#include "library/framebuffer.hpp"
#include "library/threads.hpp"
#include "library/loadlib.hpp"
struct core_region;
struct core_type;
@ -17,6 +18,11 @@ struct core_romimage;
struct core_romimage_info;
struct core_core;
/**
* The module currently being loaded.
*/
extern thread_local const loadlib::module* module_loading;
/**
* Interface device register.
*/
@ -317,7 +323,7 @@ struct core_core
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();
std::string get_core_identifier() const;
std::map<std::string, std::vector<char>> save_sram() throw(std::bad_alloc);
void load_sram(std::map<std::string, std::vector<char>>& sram) throw(std::bad_alloc);
void serialize(std::vector<char>& out);
@ -334,7 +340,7 @@ struct core_core
void set_pflag(bool pflag);
framebuffer::raw& draw_cover();
std::vector<portctrl::type*> get_port_types() { return port_types; }
std::string get_core_shortname();
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);
@ -346,7 +352,7 @@ struct core_core
static void uninstall_all_handlers();
static void initialize_new_cores();
void hide() { hidden = true; }
bool is_hidden() { return hidden; }
bool is_hidden() const { return hidden; }
std::set<const interface_action*> get_actions();
const interface_device_reg* get_registers();
int reset_action(bool hard);
@ -355,12 +361,14 @@ struct core_core
void set_cheat(uint64_t addr, uint64_t value, bool set);
std::vector<std::string> get_trace_cpus();
void debug_reset();
bool isnull();
bool isnull() const;
void reset_to_load() { c_reset_to_load(); }
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() = 0;
virtual std::string c_core_identifier() const = 0;
/**
* Set the current region.
*
@ -453,7 +461,7 @@ protected:
/**
* Get shortened name of the core.
*/
virtual std::string c_get_core_shortname() = 0;
virtual std::string c_get_core_shortname() const = 0;
/**
* Set the system controls to appropriate values for next frame.
*
@ -523,10 +531,14 @@ protected:
* Reset all debug hooks.
*/
virtual void c_debug_reset() = 0;
/**
* Reset to state equivalent to ROM load.
*/
virtual void c_reset_to_load() = 0;
/**
* Is null core (only NULL core should define this).
*/
virtual bool c_isnull();
virtual bool c_isnull() const;
private:
std::vector<portctrl::type*> port_types;
bool hidden;
@ -541,18 +553,18 @@ public:
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_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);
@ -565,7 +577,7 @@ public:
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() { return core->get_core_shortname(); }
std::string get_core_shortname() const { return core->get_core_shortname(); }
std::map<std::string, std::vector<char>> save_sram() throw(std::bad_alloc) { return core->save_sram(); }
void load_sram(std::map<std::string, std::vector<char>>& sram) throw(std::bad_alloc)
{
@ -593,7 +605,7 @@ public:
return core->execute_action(id, p);
}
unsigned action_flags(unsigned id) { return core->action_flags(id); }
bool is_hidden() { return core->is_hidden(); }
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(); }
@ -610,7 +622,9 @@ public:
}
std::vector<std::string> get_trace_cpus() { return core->get_trace_cpus(); }
void debug_reset() { core->debug_reset(); }
bool isnull() { return core->isnull(); }
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.
@ -661,7 +675,7 @@ public:
*/
core_sysregion(const std::string& name, core_type& type, core_region& region);
~core_sysregion() throw();
const std::string& get_name();
const std::string& get_name() const;
core_region& get_region();
core_type& get_type();
void fill_framerate_magic(uint64_t* magic); //4 elements filled.

View file

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

View file

@ -95,6 +95,13 @@ public:
* parameter cmd: Command to exeucte.
*/
void invoke(const std::string& cmd) throw();
/**
* Look up and invoke a command. No alias expansion is performed, but recursion checking is.
*
* parameter cmd: Command to execute.
* parameter args: The parameters for command.
*/
void invoke(const std::string& cmd, const std::string& args) throw();
/**
* Get set of aliases.
*/

View file

@ -24,7 +24,6 @@ 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

@ -3,6 +3,7 @@
#include <vector>
#include <cstdint>
#include <functional>
#include <cstdlib>
#include <iostream>
#include <stdexcept>
@ -24,6 +25,8 @@ 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);
@ -33,6 +36,10 @@ public:
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

@ -8,9 +8,12 @@
#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; };
@ -491,6 +494,16 @@ 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;
}
}
};
/**
@ -527,7 +540,8 @@ 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) throw();
std::pair<size_t, size_t> get_metrics(const std::string& string, uint32_t xalign, bool xdbl, bool ydbl)
throw();
/**
* Layout a string.
*
@ -535,6 +549,13 @@ struct font
* Returns: String layout.
*/
std::vector<layout> dolayout(const std::string& string) throw(std::bad_alloc);
/**
* Get width of string.
*
* Parameter string: The string to get width of.
* Returns: The width.
*/
uint32_t get_width(const std::string& string);
/**
* Get set of all glyph numbers.
*/
@ -557,6 +578,26 @@ 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];
@ -636,12 +677,18 @@ struct queue
private:
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]; };
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 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,6 +1,7 @@
#ifndef _library__gamepad__hpp__included__
#define _library__gamepad__hpp__included__
#include <functional>
#include <cstdint>
#include <set>
#include "json.hpp"

View file

@ -6,6 +6,7 @@
#include <cstdlib>
#include <map>
#include <string>
#include <functional>
#include "threads.hpp"
class http_request
@ -119,7 +120,7 @@ public:
/**
* Get final code.
*/
long get_http_code();
uint32_t 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);
@ -145,7 +146,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).
long http_code; //HTTP error code (OUTPUT).
uint32_t 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,4 +40,9 @@ 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

@ -273,7 +273,7 @@ private:
size_t depth;
enum _state
{
S_NORMAL,
S_STANDARD,
S_END,
S_COMMA,
S_START,

View file

@ -1,15 +1,13 @@
#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();
@ -36,7 +34,14 @@ public:
*/
library(const std::string& filename) throw(std::bad_alloc, std::runtime_error)
{
lib = new internal(filename);
try {
set_loading(this);
lib = new internal(filename);
set_loading(NULL);
} catch(...) {
set_loading(NULL);
throw;
}
}
/**
* Unload a library.
@ -94,7 +99,14 @@ public:
return *this;
}
std::string get_libname() const { return lib->libname; }
void mark(const void* obj) const { if(lib) lib->mark(obj); }
bool is_marked(const void* obj) const { return lib ? lib->is_marked(obj) : false; }
/**
* Get currently loading library, or NULL if nothing is loading.
*/
static library* loading() throw();
private:
void set_loading(library* lib) throw(std::bad_alloc);
struct internal
{
internal(const std::string& filename) throw(std::bad_alloc, std::runtime_error);
@ -102,15 +114,14 @@ private:
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); }
bool is_marked(const void* obj) { return marked.count(obj); }
std::set<const void*> marked;
};
internal* lib;
mutable internal* lib;
};
/**
@ -171,6 +182,14 @@ public:
* Run all not ran initialization functions.
*/
static void run_initializers();
/**
* Mark object (only works for libraries).
*/
void mark(const void* obj) const { if(dynamic) lib.mark(obj); }
/**
* Is object marked (only works for libraries)?
*/
bool is_marked(const void* obj) const { return dynamic ? lib.is_marked(obj) : false; }
private:
bool dynamic;
library lib;

View file

@ -7,15 +7,14 @@
#include <typeindex>
#include <map>
#include <unordered_map>
#include <functional>
#include <set>
#include <list>
#include <cassert>
#include "string.hpp"
#include "utf8.hpp"
extern "C"
{
#include <lua.h>
}
#include "int24.hpp"
#include "lua-version.hpp"
namespace lua
{
@ -31,6 +30,7 @@ class class_base;
class state
{
public:
const static unsigned trampoline_upvals = 2;
//Auxillary type for store-tag.
template<typename T> struct _store_tag
{
@ -152,7 +152,7 @@ private:
template<typename... T> void _callback(int argc, string_tag tag, T... args)
{
pushlstring(tag.val.c_str(), tag.val.length());
pushlstring(tag.val);
_callback(argc + 1, args...);
}
@ -221,6 +221,17 @@ 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.
*/
@ -229,6 +240,66 @@ public:
* 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.
*
@ -239,7 +310,7 @@ public:
*/
std::string get_string(int argindex, const std::string& fname) throw(std::runtime_error, std::bad_alloc)
{
if(lua_isnone(lua_handle, argindex))
if(isnone(argindex))
(stringfmt() << "argument #" << argindex << " to " << fname << " must be string").throwex();
size_t len;
const char* f = lua_tolstring(lua_handle, argindex, &len);
@ -257,7 +328,7 @@ public:
*/
bool get_bool(int argindex, const std::string& fname) throw(std::runtime_error, std::bad_alloc)
{
if(lua_isnone(lua_handle, argindex) || !lua_isboolean(lua_handle, argindex))
if(isnone(argindex) || !isboolean(argindex))
(stringfmt() << "argument #" << argindex << " to " << fname << " must be boolean").throwex();
return (lua_toboolean(lua_handle, argindex) != 0);
}
@ -272,9 +343,17 @@ public:
template<typename T>
T get_numeric_argument(int argindex, const std::string& fname)
{
if(lua_isnone(lua_handle, argindex) || !lua_isnumber(lua_handle, argindex))
(stringfmt() << "Argument #" << argindex << " to " << fname << " must be numeric").throwex();
return static_cast<T>(lua_tonumber(lua_handle, argindex));
if(std::numeric_limits<T>::is_integer) {
if(isnone(argindex) || !isinteger(argindex))
(stringfmt() << "Argument #" << argindex << " to " << fname
<< " must be integer").throwex();
return static_cast<T>(lua_tointeger(lua_handle, argindex));
} else {
if(isnone(argindex) || !isnumber(argindex))
(stringfmt() << "Argument #" << argindex << " to " << fname
<< " must be numeric").throwex();
return static_cast<T>(lua_tonumber(lua_handle, argindex));
}
}
/**
* Get a optional numeric argument.
@ -287,12 +366,19 @@ public:
template<typename T>
void get_numeric_argument(unsigned argindex, T& value, const std::string& fname)
{
if(lua_isnoneornil(lua_handle, argindex))
if(isnoneornil(argindex))
return;
if(lua_isnone(lua_handle, argindex) || !lua_isnumber(lua_handle, argindex))
(stringfmt() << "Argument #" << argindex << " to " << fname << " must be numeric if "
"present").throwex();
value = static_cast<T>(lua_tonumber(lua_handle, argindex));
if(std::numeric_limits<T>::is_integer) {
if(isnone(argindex) || !isinteger(argindex))
(stringfmt() << "Argument #" << argindex << " to " << fname << " must be integer if "
"present").throwex();
value = static_cast<T>(lua_tointeger(lua_handle, argindex));
} else {
if(isnone(argindex) || !isnumber(argindex))
(stringfmt() << "Argument #" << argindex << " to " << fname << " must be numeric if "
"present").throwex();
value = static_cast<T>(lua_tonumber(lua_handle, argindex));
}
}
/**
* Do a callback.
@ -399,6 +485,7 @@ 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); }
@ -421,37 +508,58 @@ public:
void insert(int index) { lua_insert(lua_handle, index); }
void settable(int index) { lua_settable(lua_handle, index); }
int isnone(int index) { return lua_isnone(lua_handle, index); }
void pushnumber(lua_Number n) { return lua_pushnumber(lua_handle, n); }
int isnumber(int index) { return lua_isnumber(lua_handle, index); }
int isinteger(int index) { return LUA_INTEGER_POSTFIX(lua_is) (lua_handle, index); }
int isboolean(int index) { return lua_isboolean(lua_handle, index); }
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); }
void pushboolean(int b) { lua_pushboolean(lua_handle, b); }
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); }
void gettable(int index) { lua_gettable(lua_handle, index); }
#if LUA_VERSION_NUM == 501
int load(lua_Reader reader, void* data, const char* chunkname) { return lua_load(lua_handle, reader, data,
chunkname); }
#endif
#if LUA_VERSION_NUM == 502
int load(lua_Reader reader, void* data, const char* chunkname, const char* mode) { return lua_load(lua_handle,
reader, data, chunkname, mode); }
#endif
int load(lua_Reader reader, void* data, const char* chunkname, const char* mode) {
(void)mode;
return lua_load(lua_handle, reader, data, chunkname LUA_LOADMODE_ARG(mode) );
}
const char* tostring(int index) { return lua_tostring(lua_handle, index); }
const char* tolstring(int index, size_t& len) { return lua_tolstring(lua_handle, index, &len); }
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) { return lua_pcall(lua_handle, nargs, nresults, errfunc); }
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 next(int index) { return lua_next(lua_handle, index); }
int isnoneornil(int index) { return lua_isnoneornil(lua_handle, index); }
lua_Integer tointeger(int index) { return lua_tointeger(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);
else
return lua_pushnumber(lua_handle, val);
}
void pushboolean(bool b) { lua_pushboolean(lua_handle, b); }
void pushglobals() { LUA_LOADGLOBALS }
private:
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,6 +1,7 @@
#ifndef _library__lua_class__hpp__included__
#define _library__lua_class__hpp__included__
#include <functional>
#include "lua-base.hpp"
#include "lua-pin.hpp"
@ -220,28 +221,32 @@ 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 = _state.newuserdata(sizeof(T) + overcommit);
void* obj = NULL;
auto st = &_state;
_state.run_interruptable([st, overcommit, &obj]() {
obj = st->newuserdata(sizeof(T) + overcommit);
}, 0, 1);
load_metatable(_state);
_state.setmetatable(-2);
T* _obj = reinterpret_cast<T*>(obj);
new(_obj) T(_state, args...);
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;
}
return _obj;
}
static int class_bind_trampoline(lua_State* LS)
static int class_bind_trampoline(state& L)
{
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
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);
}
T* _get(state& _state, int arg, const std::string& fname, bool optional = false)
@ -298,7 +303,7 @@ badtype:
bdata->_state = &_state.get_master();
std::copy(fname.begin(), fname.end(), bdata->fname);
bdata->fname[fname.length()] = 0;
_state.pushcclosure(class_bind_trampoline, 1);
_state.push_trampoline(class_bind_trampoline, 1);
_state.rawset(-3);
_state.pop(1);
}
@ -451,30 +456,27 @@ public:
return r;
}
private:
static int dogc(lua_State* LS)
static int dogc(state& L)
{
T* obj = reinterpret_cast<T*>(lua_touserdata(LS, 1));
T* obj = reinterpret_cast<T*>(L.touserdata(1));
obj->~T();
return 0;
}
static int newindex(lua_State* LS)
static int newindex(state& L)
{
lua_pushstring(LS, "Writing metatables of classes is not allowed");
lua_error(LS);
return 0;
throw std::runtime_error("Writing metatables of classes is not allowed");
}
static int index(lua_State* LS)
static int index(state& L)
{
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);
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);
}
return 1;
}
@ -491,14 +493,14 @@ again:
_state.pushvalue(-1);
_state.setmetatable(-2);
_state.pushstring("__gc");
_state.pushcfunction(&_class<T>::dogc);
_state.push_trampoline(&_class<T>::dogc, 0);
_state.rawset(-3);
_state.pushstring("__newindex");
_state.pushcfunction(&_class<T>::newindex);
_state.push_trampoline(&_class<T>::newindex, 0);
_state.rawset(-3);
_state.pushstring("__index");
_state.pushlstring(name);
_state.pushcclosure(&_class<T>::index, 1);
_state.push_trampoline(&_class<T>::index, 1);
_state.rawset(-3);
_state.rawset(LUA_REGISTRYINDEX);
goto again;

View file

@ -1,6 +1,8 @@
#ifndef _library__lua_function__hpp__included__
#define _library__lua_function__hpp__included__
#include <functional>
namespace lua
{
class parameters;

View file

@ -0,0 +1,57 @@
#ifndef _library__lua_version__hpp__included__
#define _library__lua_version__hpp__included__
extern "C"
{
#include <lua.h>
}
#if LUA_VERSION_NUM == 501
#else
#if LUA_VERSION_NUM == 502
#define LUA_SUPPORTS_LOAD_MODE
#define LUA_SUPPORTS_RIDX_GLOBALS
#else
#if LUA_VERSION_NUM == 503
#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
#ifdef LUA_SUPPORTS_INTEGERS
#define LUA_INTEGER_POSTFIX(X) X##integer
#else
#define LUA_INTEGER_POSTFIX(X) X##number
#endif
#ifdef LUA_SUPPORTS_LOAD_MODE
#define LUA_LOADMODE_ARG(X) , X
#else
#define LUA_LOADMODE_ARG(X)
#endif
#ifdef LUA_SUPPORTS_RIDX_GLOBALS
#define LUA_LOADGLOBALS rawgeti(LUA_REGISTRYINDEX, LUA_RIDX_GLOBALS);
#else
#define LUA_LOADGLOBALS pushvalue(LUA_GLOBALSINDEX);
#endif
#ifdef LUA_SUPPORTS_LOAD_STRING
#define LUA_LOAD_CMD "load"
#else
#define LUA_LOAD_CMD "loadstring"
#endif
#endif

View file

@ -241,6 +241,13 @@ public:
* Parameter buffer: Buffer to store to (get_linear_size() bytes).
*/
void read_all_linear_memory(uint8_t* buffer);
/**
* Get textual identifier for mapped address.
*
* Parameter addr: The address to get textual form for.
* Returns: The textual address.
*/
std::string address_to_textual(uint64_t addr);
private:
threads::lock mlock;
std::vector<region*> u_regions;

View file

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

View file

@ -0,0 +1,52 @@
#ifndef _library__memtracker__hpp__included__
#define _library__memtracker__hpp__included__
#include "threads.hpp"
#include <map>
class memtracker
{
public:
memtracker();
~memtracker();
void operator()(const char* category, ssize_t change);
void reset(const char* category, size_t value);
std::map<std::string, size_t> report();
static memtracker& singleton();
class autorelease
{
public:
autorelease(memtracker& _track, const char* cat, size_t amount)
: tracker(_track), category(cat), committed(amount)
{
tracker(category, committed);
}
~autorelease()
{
tracker(category, -(ssize_t)committed);
}
void operator()(ssize_t delta)
{
if(delta < 0 && committed < (size_t)-delta) {
tracker(category, -(ssize_t)committed);
committed = 0;
} else {
tracker(category, delta);
committed = committed + delta;
}
}
private:
memtracker& tracker;
const char* category;
size_t committed;
};
private:
bool invalid;
threads::lock mut;
std::map<std::string, size_t> data;
memtracker(const memtracker&);
memtracker& operator=(const memtracker&);
};
#endif

View file

@ -5,6 +5,7 @@
#include <cstdint>
#include <stdexcept>
#include "portctrl-data.hpp"
#include "memtracker.hpp"
/**
* Movie being played back or recorded
@ -320,6 +321,8 @@ private:
uint64_t cached_subframe;
//Count present subframes in frame starting from first_subframe (returns 0 if out of movie).
uint32_t count_changes(uint64_t first_subframe) throw();
//Tracker.
memtracker::autorelease tracker;
};
#endif

View file

@ -18,6 +18,7 @@
#include <set>
#include "json.hpp"
#include "threads.hpp"
#include "memtracker.hpp"
namespace binarystream
{
@ -48,6 +49,7 @@ namespace binarystream
namespace portctrl
{
extern const char* movie_page_id;
/**
* Is not field terminator.
*
@ -1241,6 +1243,10 @@ public:
* Find subframe number corresponding to given frame (1-based).
*/
int64_t find_frame(uint64_t n);
/**
* Find frame number corresponding to given subframe (0-based).
*/
int64_t subframe_to_frame(uint64_t n);
/**
* Notify sync flag polarity change.
*
@ -1320,7 +1326,11 @@ private:
class page
{
public:
page() { memset(content, 0, CONTROLLER_PAGE_SIZE); }
page() {
memtracker::singleton()(movie_page_id, CONTROLLER_PAGE_SIZE + 36);
memset(content, 0, CONTROLLER_PAGE_SIZE);
}
~page() { memtracker::singleton()(movie_page_id, -CONTROLLER_PAGE_SIZE - 36); }
unsigned char content[CONTROLLER_PAGE_SIZE];
};
size_t frames_per_page;
@ -1342,6 +1352,7 @@ private:
cache_page_num--;
cache_page = NULL;
}
memtracker::autorelease tracker;
};
void frame::sync(bool x) throw()

View file

@ -7,35 +7,31 @@
namespace serialization
{
template<typename T> struct unsigned_of {};
template<> struct unsigned_of<int8_t> { typedef uint8_t t; };
template<> struct unsigned_of<uint8_t> { typedef uint8_t t; };
template<> struct unsigned_of<int16_t> { typedef uint16_t t; };
template<> struct unsigned_of<uint16_t> { typedef uint16_t t; };
template<> struct unsigned_of<int32_t> { typedef uint32_t t; };
template<> struct unsigned_of<uint32_t> { typedef uint32_t t; };
template<> struct unsigned_of<int64_t> { typedef uint64_t t; };
template<> struct unsigned_of<uint64_t> { typedef uint64_t t; };
template<size_t n> struct unsigned_of {};
template<> struct unsigned_of<1> { typedef uint8_t t; };
template<> struct unsigned_of<2> { typedef uint16_t t; };
template<> struct unsigned_of<4> { typedef uint32_t t; };
template<> struct unsigned_of<8> { typedef uint64_t t; };
template<typename T1, bool be>
void write_common(uint8_t* target, T1 value)
{
for(size_t i = 0; i < sizeof(T1); i++)
if(be)
target[i] = static_cast<typename unsigned_of<T1>::t>(value) >> 8 * (sizeof(T1) - i - 1);
target[i] = static_cast<typename unsigned_of<sizeof(T1)>::t>(value) >> 8 * (sizeof(T1) - i - 1);
else
target[i] = static_cast<typename unsigned_of<T1>::t>(value) >> 8 * i;
target[i] = static_cast<typename unsigned_of<sizeof(T1)>::t>(value) >> 8 * i;
}
template<typename T1, bool be>
T1 read_common(const uint8_t* source)
{
typename unsigned_of<T1>::t value = 0;
typename unsigned_of<sizeof(T1)>::t value = 0;
for(size_t i = 0; i < sizeof(T1); i++)
if(be)
value |= static_cast<typename unsigned_of<T1>::t>(source[i]) << 8 * (sizeof(T1) - i - 1);
value |= static_cast<typename unsigned_of<sizeof(T1)>::t>(source[i]) << 8 * (sizeof(T1) - i - 1);
else
value |= static_cast<typename unsigned_of<T1>::t>(source[i]) << 8 * i;
value |= static_cast<typename unsigned_of<sizeof(T1)>::t>(source[i]) << 8 * i;
return static_cast<T1>(value);
}

View file

@ -390,7 +390,7 @@ public:
/**
* Get setting.
*/
valtype_t get() throw(std::bad_alloc)
valtype_t get() const throw(std::bad_alloc)
{
threads::arlock h(get_setting_lock());
return model::transform(value);
@ -398,7 +398,7 @@ public:
/**
* Get setting.
*/
operator valtype_t()
operator valtype_t() const
{
return get();
}

View file

@ -1,6 +1,7 @@
#ifndef _library__string__hpp__included__
#define _library__string__hpp__included__
#include <functional>
#include <string>
#include <sstream>
#include <set>
@ -230,14 +231,30 @@ private:
regex_results regex(const std::string& regex, const std::string& str, const char* ex = NULL)
throw(std::bad_alloc, std::runtime_error);
enum regex_match_mode
{
REGEX_MATCH_REGEX = 0,
REGEX_MATCH_LITERIAL = 1,
REGEX_MATCH_IWILDCARDS = 2,
REGEX_MATCH_IREGEX = 3,
};
/**
* Regexp a string and return match result.
*
* Parameter regex: The regexp to apply.
* Parameter str: The string to apply the regexp to.
* Parameter mode: Match mode.
* Returns: True if matches, false if not.
*/
bool regex_match(const std::string& regex, const std::string& str) throw(std::bad_alloc, std::runtime_error);
bool regex_match(const std::string& regex, const std::string& str, enum regex_match_mode mode = REGEX_MATCH_REGEX)
throw(std::bad_alloc, std::runtime_error);
/**
* Try match a case-insensitive string fragment and return the result.
*
* \param pattern The pattern to match a
*/
/**
* Cast string to bool.
@ -249,6 +266,11 @@ bool regex_match(const std::string& regex, const std::string& str) throw(std::ba
*/
int string_to_bool(const std::string& cast_to_bool);
template<typename T> T raw_lexical_cast(const std::string& value)
{
return boost::lexical_cast<T>(value);
}
/**
* \brief Typeconvert string.
*/
@ -299,7 +321,7 @@ template<typename T> inline T parse_value(const std::string& value) throw(std::b
}
return val;
}
return boost::lexical_cast<T>(value);
return raw_lexical_cast<T>(value);
} catch(std::exception& e) {
throw std::runtime_error("Can't parse value '" + value + "': " + e.what());
}

View file

@ -1,6 +1,7 @@
#ifndef _library_triplebuffer__hpp__included__
#define _library_triplebuffer__hpp__included__
#include <functional>
#include <stdexcept>
#include "threads.hpp"
@ -45,6 +46,12 @@ public:
* Throws std::logic_error: If write count is 0.
*/
void put_write() throw(std::logic_error);
/**
* Call specified function synchronously for last written buffer.
*
* The buffer number is passed to specified function.
*/
void read_last_write_synchronous(std::function<void(unsigned)> fn) throw();
private:
threads::lock lock;
unsigned last_complete; //Number of last completed buffer
@ -103,6 +110,15 @@ public:
* Throws std::logic_error: If write count is 0.
*/
void put_write() throw(std::logic_error) { l.put_write(); }
/**
* Call specified function synchronously for last written buffer.
*
* The buffer itself is passed to the function.
*/
void read_last_write_synchronous(std::function<void(T&)> fn) throw()
{
l.read_last_write_synchronous([this,fn](unsigned x){ fn(*objs[x]); });
}
private:
T* objs[3];
logic l;

View file

@ -145,12 +145,12 @@ public:
/**
* This iterator iterates members of ZIP archive in forward order.
*/
typedef iterator_class<std::map<std::string, unsigned long long>::iterator, std::string> iterator;
typedef iterator_class<std::map<std::string, uint64_t>::iterator, std::string> iterator;
/**
* This iterator iterates members of ZIP archive in reverse order
*/
typedef iterator_class<std::map<std::string, unsigned long long>::reverse_iterator, std::string>
typedef iterator_class<std::map<std::string, uint64_t>::reverse_iterator, std::string>
riterator;
/**
@ -278,7 +278,7 @@ public:
private:
reader(reader&);
reader& operator=(reader&);
std::map<std::string, unsigned long long> offsets;
std::map<std::string, uint64_t> offsets;
std::ifstream* zipstream;
size_t* refcnt;
};
@ -421,10 +421,10 @@ public:
private:
struct file_info
{
unsigned long crc;
unsigned long uncompressed_size;
unsigned long compressed_size;
unsigned long offset;
uint32_t crc;
uint32_t uncompressed_size;
uint32_t compressed_size;
uint32_t offset;
};
writer(writer&);

View file

@ -9,6 +9,7 @@
#include "library/lua-class.hpp"
#include "library/lua-params.hpp"
#include "library/framebuffer.hpp"
#include "library/range.hpp"
#include "library/threads.hpp"
#include "library/string.hpp"
@ -30,6 +31,7 @@ struct lua_palette
static int load(lua::state& L, lua::parameters& P);
static int load_str(lua::state& L, lua::parameters& P);
int set(lua::state& L, lua::parameters& P);
int get(lua::state& L, lua::parameters& P);
int hash(lua::state& L, lua::parameters& P);
int debug(lua::state& L, lua::parameters& P);
int adjust_transparency(lua::state& L, lua::parameters& P);
@ -54,11 +56,14 @@ struct lua_bitmap
int pset(lua::state& L, lua::parameters& P);
int pget(lua::state& L, lua::parameters& P);
int size(lua::state& L, lua::parameters& P);
int hflip(lua::state& L, lua::parameters& P);
int vflip(lua::state& L, lua::parameters& P);
int hash(lua::state& L, lua::parameters& P);
template<bool scaled, bool porterduff> int blit(lua::state& L, lua::parameters& P);
template<bool scaled> int blit_priority(lua::state& L, lua::parameters& P);
int save_png(lua::state& L, lua::parameters& P);
int _save_png(lua::state& L, lua::parameters& P, bool is_method);
int sample_texture(lua::state& L, lua::parameters& P);
};
struct lua_dbitmap
@ -78,11 +83,14 @@ struct lua_dbitmap
int pset(lua::state& L, lua::parameters& P);
int pget(lua::state& L, lua::parameters& P);
int size(lua::state& L, lua::parameters& P);
int hflip(lua::state& L, lua::parameters& P);
int vflip(lua::state& L, lua::parameters& P);
int hash(lua::state& L, lua::parameters& P);
template<bool scaled, bool porterduff> int blit(lua::state& L, lua::parameters& P);
int save_png(lua::state& L, lua::parameters& P);
int adjust_transparency(lua::state& L, lua::parameters& P);
int _save_png(lua::state& L, lua::parameters& P, bool is_method);
int sample_texture(lua::state& L, lua::parameters& P);
};
struct lua_loaded_bitmap
@ -98,5 +106,75 @@ struct lua_loaded_bitmap
template<bool png> static int load_str(lua::state& L, lua::parameters& P);
};
template<bool T> class lua_bitmap_holder
{
public:
lua_bitmap_holder(lua_bitmap& _b, lua_palette& _p) : b(_b), p(_p) {};
size_t stride() { return b.width; }
void lock()
{
p.palette_mutex.lock();
palette = p.colors;
pallim = p.color_count;
}
void unlock()
{
p.palette_mutex.unlock();
}
void draw(size_t bmpidx, typename framebuffer::fb<T>::element_t& target)
{
uint16_t i = b.pixels[bmpidx];
if(i < pallim)
palette[i].apply(target);
}
private:
lua_bitmap& b;
lua_palette& p;
framebuffer::color* palette;
size_t pallim;
};
template<bool T> class lua_dbitmap_holder
{
public:
lua_dbitmap_holder(lua_dbitmap& _d) : d(_d) {};
size_t stride() { return d.width; }
void lock() {}
void unlock() {}
void draw(size_t bmpidx, typename framebuffer::fb<T>::element_t& target)
{
d.pixels[bmpidx].apply(target);
}
private:
lua_dbitmap& d;
};
template<bool T, class B> void lua_bitmap_composite(struct framebuffer::fb<T>& scr, int32_t xp,
int32_t yp, const range& X, const range& Y, const range& sX, const range& sY, bool outside, B bmp) throw()
{
if(!X.size() || !Y.size()) return;
size_t stride = bmp.stride();
bmp.lock();
for(uint32_t r = Y.low(); r != Y.high(); r++) {
typename framebuffer::fb<T>::element_t* rptr = scr.rowptr(yp + r);
size_t eptr = xp + X.low();
uint32_t xmin = X.low();
bool cut = outside && sY.in(r);
if(cut && sX.in(xmin)) {
xmin = sX.high();
eptr += (sX.high() - X.low());
}
for(uint32_t c = xmin; c < X.high(); c++, eptr++) {
if(__builtin_expect(cut && c == sX.low(), 0)) {
c += sX.size();
eptr += sX.size();
}
bmp.draw(r * stride + c, rptr[eptr]);
}
}
bmp.unlock();
}
#endif

23
include/lua/halo.hpp Normal file
View file

@ -0,0 +1,23 @@
#ifndef _lua__halo__hpp__included__
#define _lua__halo__hpp__included__
#include <cstdlib>
#include "library/framebuffer.hpp"
/**
* Render a 1px wide halo around monochrome image.
*
* Parameter pixmap: The pixmap to render halo on. Must be aligned to 32 bytes.
* Parameter width: Width of the pixmap. Must be multiple of 32 bytes.
* Parameter height: Height of the pixmap.
*/
void render_halo(unsigned char* pixmap, size_t width, size_t height);
/**
* Blit a bitmap to screen.
*/
template<bool X> void halo_blit(struct framebuffer::fb<X>& scr, unsigned char* pixmap, size_t width,
size_t height, size_t owidth, size_t oheight, uint32_t x, uint32_t y, framebuffer::color& bg,
framebuffer::color& fg, framebuffer::color& hl) throw();
#endif

View file

@ -5,10 +5,13 @@
#include <map>
#include <list>
#include "core/controllerframe.hpp"
#include "library/command.hpp"
#include "library/movie.hpp"
#include "library/framebuffer.hpp"
#include "library/lua-base.hpp"
#include "library/lua-framebuffer.hpp"
#include "library/memtracker.hpp"
#include "library/settingvar.hpp"
namespace command { class group; }
namespace keyboard { class key; }
@ -16,12 +19,14 @@ namespace keyboard { class key; }
#define LUA_TIMED_HOOK_IDLE 0
#define LUA_TIMED_HOOK_TIMER 1
void init_lua() throw();
void quit_lua() throw();
class emulator_instance;
void init_lua(emulator_instance& inst) throw();
void quit_lua(emulator_instance& inst) throw();
struct lua_state
{
lua_state(lua::state& _L, command::group& _command);
lua_state(lua::state& _L, command::group& _command, settingvar::group& settings);
~lua_state();
lua::state::callback_list* on_paint;
@ -72,8 +77,7 @@ struct lua_state
void callback_snoop_input(uint32_t port, uint32_t controller, uint32_t index, short value) throw();
void callback_quit() throw();
void callback_keyhook(const std::string& key, keyboard::key& p) throw();
void callback_do_unsafe_rewind(const std::vector<char>& save, uint64_t secs, uint64_t ssecs, movie& mov,
void* u);
void callback_do_unsafe_rewind(movie& mov, void* u);
bool callback_do_button(uint32_t port, uint32_t controller, uint32_t index, const char* type);
void callback_movie_lost(const char* what);
void callback_do_latch(std::list<std::string>& args);
@ -102,10 +106,13 @@ struct lua_state
lua::render_context* renderq_saved;
lua::render_context* renderq_last;
bool renderq_redirect;
void set_memory_limit(size_t max_mb);
std::list<std::string> startup_scripts;
std::map<std::string, std::u32string> watch_vars;
private:
void do_reset();
void do_evaluate(const std::string& a);
bool run_lua_fragment() throw(std::bad_alloc);
template<typename... T> bool run_callback(lua::state::callback_list& list, T... args);
void run_synchronous_paint(struct lua::render_context* ctx);
@ -113,6 +120,26 @@ private:
command::group& command;
bool recursive_flag;
const char* luareader_fragment;
command::_fnptr<> resetcmd;
command::_fnptr<const std::string&> evalcmd;
command::_fnptr<const std::string&> evalcmd2;
command::_fnptr<command::arg_filename> runcmd;
struct _listener : public settingvar::listener
{
_listener(settingvar::group& group, lua_state& _obj)
: obj(_obj), grp(group)
{
group.add_listener(*this);
}
~_listener() throw()
{
grp.remove_listener(*this);
}
void on_setting_change(settingvar::group& grp, const settingvar::base& val);
lua_state& obj;
settingvar::group& grp;
};
_listener listener;
};
#endif

View file

@ -3,22 +3,19 @@
#include "library/lua-base.hpp"
#include "library/string.hpp"
#include "core/moviefile.hpp"
struct lua_unsaferewind
{
lua_unsaferewind(lua::state& L);
static size_t overcommit() { return 0; }
std::vector<char> state;
uint64_t frame;
uint64_t lag;
//The console state.
dynamic_state console_state;
//Extra state variable involved in fast movie restore. It is not part of normal console state.
uint64_t ptr;
uint64_t secs;
uint64_t ssecs;
std::vector<uint32_t> pollcounters;
std::vector<char> hostmemory;
std::string print()
{
return (stringfmt() << "to frame " << frame).str();
return (stringfmt() << "to frame " << console_state.save_frame).str();
}
};

View file

@ -2,6 +2,7 @@
#define _plat_wxwidgets__menu_branches__hpp__included__
#include "core/dispatch.hpp"
#include <functional>
#include <wx/string.h>
#include <wx/wx.h>
#include <map>

View file

@ -1,6 +1,7 @@
#ifndef _plat_wxwidgets__menu_loadrom__hpp__included__
#define _plat_wxwidgets__menu_loadrom__hpp__included__
#include <functional>
#include <wx/string.h>
#include <wx/wx.h>
#include "interface/romtype.hpp"

View file

@ -3,6 +3,7 @@
#include "core/dispatch.hpp"
#include "library/recentfiles.hpp"
#include <functional>
#include <wx/string.h>
#include <wx/wx.h>
#include <map>

View file

@ -2,6 +2,7 @@
#define _plat_wxwidgets__menu_tracelog__hpp__included__
#include "core/dispatch.hpp"
#include <functional>
#include <wx/string.h>
#include <wx/wx.h>
#include <map>

View file

@ -1,10 +1,17 @@
#ifndef _plat_wxwidgets__platform__hpp__included__
#define _plat_wxwidgets__platform__hpp__included__
#include <wx/wx.h>
#include <wx/event.h>
#include <wx/control.h>
#include <wx/combobox.h>
#include "core/queue.hpp"
#include "core/moviefile.hpp"
#include "core/window.hpp"
#include "library/threads.hpp"
#include <functional>
#include <cstdlib>
#include <cstdint>
#include <cstddef>
@ -12,6 +19,32 @@
#include <wx/string.h>
#include <wx/event.h>
void _check_ui_thread(const char* file, int line);
#define CHECK_UI_THREAD _check_ui_thread( __FILE__ , __LINE__ )
struct runuifun_once_ctx
{
runuifun_once_ctx()
{
flag = false;
}
bool set_flag()
{
threads::alock h(m);
if(flag) return false;
flag = true;
return true;
}
void clear_flag()
{
threads::alock h(m);
flag = false;
}
private:
threads::lock m;
bool flag;
};
class wxwin_mainwindow;
class wxwin_messages;
class wxwin_status;
@ -44,7 +77,7 @@ void initialize_wx_mouse(emulator_instance& inst);
void deinitialize_wx_mouse(emulator_instance& inst);
void signal_program_exit();
void signal_resize_needed();
void _runuifun_async(void (*fn)(void*), void* arg);
void _runuifun_async(runuifun_once_ctx* octx, void (*fn)(void*), void* arg);
void show_projectwindow(wxWindow* modwin, emulator_instance& inst);
void signal_core_change();
void do_save_configuration();
@ -86,10 +119,12 @@ bool wxeditor_hexeditor_available(emulator_instance& inst);
bool wxeditor_hexeditor_jumpto(emulator_instance& inst, uint64_t addr);
void wxwindow_tasinput_update(emulator_instance& inst);
template<typename T>
void runuifun(T fn)
template<typename T> void runuifun(T fn) {
_runuifun_async(nullptr, functor_call_helper2<T>, new T(fn));
}
template<typename T> void runuifun(runuifun_once_ctx& octx, T fn)
{
_runuifun_async(functor_call_helper2<T>, new T(fn));
_runuifun_async(&octx, functor_call_helper2<T>, new T(fn));
}
//Thrown by various dialog functions if canceled.
@ -101,6 +136,8 @@ public:
//Prompt for stuff. These all can throw canceled_exception.
std::string pick_file_member(wxWindow* parent, const std::string& title, const std::string& startdir);
unsigned pick_among_index(wxWindow* parent, const std::string& title, const std::string& prompt,
const std::vector<std::string>& choices, unsigned defaultchoice = 0);
std::string pick_among(wxWindow* parent, const std::string& title, const std::string& prompt,
const std::vector<std::string>& choices, unsigned defaultchoice = 0);
std::string pick_text(wxWindow* parent, const std::string& title, const std::string& prompt,

View file

@ -1,6 +1,7 @@
#ifndef _platform__wxwidgets__settings_common__hpp__included__
#define _platform__wxwidgets__settings_common__hpp__included__
#include <functional>
#include <string>
#include "platform/wxwidgets/platform.hpp"
#include <wx/wx.h>

853
lua.lyx

File diff suppressed because it is too large Load diff

BIN
lua.pdf

Binary file not shown.

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