Compare commits

..
22 Commits
Author SHA1 Message Date
byuu 7dec0b2a3c Update to bsnes v014 release.
This version adds speed regulation, greatly improves PPU rendering, and increases speed by ~30% over the previous version.
Changelog:
    - Rewrote offset-per-tile mode emulation, should be correct now. Fixes Chrono Trigger, Contra III, Tetris Attack, etc.
    - Fixed a bug with HDMA occuring during interrupts. Fixes Tales of Phantasia souond test screen
    - Updated compiler to Visual Studio 2005, and enabled profile guided optimizations
    - Added conditional compilation of debugging functions (faster without them)
    - Added conditional compilation of core classes as pointers (allowing polymorphism) or objects (allowing inlining). The latter results in a speed increase
    - Small fixes to BG and OAM rendering routines
    - Corrected sprite tile bounds wrapping
    - Corrected sprite rendering in hires video modes
    - Rewrote color add/sub routines, should be correct now. Fixes Illusion of Gaia menu, etc.
    - Optimized video blitting routines, will temporarilly break mixed video mode screenshots
    - Prevented selecting menu options via return key from being recognized as keypresses by the emulator
    - Added system speed regulation (60hz/NTSC or 50hz/PAL)! Many thanks to kode54, GIGO, and Richard Bannister for their assistance
I disabled the debugger and polymorphism, and enabled profile guided optimizations for this build, to maximize speed. The debugger and polymorphism can be re-enabled via uncommenting the respective #defines in src/base.h and recompiling, or bsnes v0.013 can be used. I may start releasing two separate builds in the future... not sure yet.
2005-11-12 16:49:26 +00:00
byuu f288280ceb Update to bsnes v013r02 release.
[No changelog available]
2005-10-25 23:25:28 +00:00
byuu c6c5f4669c Update to bsnes v013 release.
- Greatly improved HDMA timing and accuracy with help from anomie and DMV27 -- fixes bugs in Energy Breaker and Street Fighter Alpha 2
    - Fixed a problem with color add/sub code -- fixes opening battle in Tales of Phantasia and clouds in Energy Breaker
    - Temporarily added DMV27's bugfix for the DSP KON register -- fixes sound in Der Langrisser, but this is not a hardware-accurate fix
    - Disabled VRAM writes outside of vblank -- fixes Hook, but breaks many PD ROMs and fan translations (Roto's BS Zelda hack, Gideon Zhi's Ys 4 translation, etc). I might add an option in the future to toggle this behavior, but for now these games will no longer work. Please keep in mind these games will not run properly on real SNES hardware, either.
    - Improved frameskipping code thanks to a suggestion from Richard Bannister
    - Misc. other code cleanups and improvements (notably in the color table generation code)
    - bsnes is now endian-safe and runs on Mac OS X
    - Added caching support for window clipping tables resulting in a slight speedup. Please let me know if you spot any errors as a result of this change.
2005-10-23 23:32:30 +00:00
byuu 397b9c4505 Update to bsnes v012 release.
Changelog:
    - Added S-DSP emulation
    - Added sound output support via DirectSound -- no sound buffering though, so sound is muted by default
    - Added option to record raw sound output to WAV files
    - Added multiple color adjustment filters to the video output
    - Added mode3/4 direct color support
    - Added mode7 direct color and mosaic support
    - Greatly improved mode7 rendering algorithm thanks to anomie
    - Fixed mode7 screen repitition and EXTBG effects
    - Greatly increased accuracy of NMI and IRQ timing, and emulated many newly discovered hardware quirks involving the two
    - A few speed improvements courtesy of Nach for profiling the code for me
I'm now looking for assistance with sound buffering. Specifically, I need help modifying the DirectSound code to allow the emulator to be ran between 50%-400% normal speed, while keeping the sound output relatively good. If you have experience with this and can help, please get in touch with me (setsunakun0 at hotmail dot com).
2005-10-02 00:38:34 +00:00
byuu 7e2cfb6d40 Update to bsnes v011 release.
- Fixed Mode 0 color palette index problem. Fixes ToP, DQ5, etc.
    - Improved LoROM memory mapper to support 32mbit images. Fixes Tokimeki Memorial, etc.
    - Added full S-DD1 support, SFA2 and Star Ocean are now playable. Special thanks to Andreas Naive
    - Updated BGnxOFS / Mode7 registers with anomie's latest findings
    - Added basic ROM mirroring support. Fixes copy protection issues in MMX, etc.
    - Rewrote string library to work better on gcc/linux
    - Cleaned up S-RTC/S-DD1 emulation to make way for future add-on chip emulation
    - Rewrote DMA code, now runs cycle-by-cycle
    - Rewrote HDMA code, now allows HDMA to be enabled mid-frame, fixes many games
    - Fixed a bug in Mode7 vertical screen flip mode. Fixes FF5 title screen, etc.
    - Greatly improved IRQ triggering. Fixes Der Langrisser, etc.
    - Added full support for open bus. This includes PPU1 and PPU2 open bus support
    - Modified CPU core back to cycle-based system. Slower, but improves debugger
    - Implemented temporary fix for debugger to handle new cycle-based cores
    - Modified CGRAM to ignore highest bit, since it is not used at all by the SNES, and is impossible to read on real hardware. Lowers memory usage by ~1.2mb
    - Added mostly accurate PAL timing support. This should increase compatibility by ~30% or so
    - More stuff I'm forgetting at the moment...
2005-08-26 20:38:00 +00:00
byuu 970dcea0ac Update to bsnes v010 release.
bsnes now supports SPC700 emulation (no DSP or sound support, however), and has greatly improved compatibility. It also now contains a keyboard-only joypad configuration tool.
2005-08-03 21:22:42 +00:00
byuu 402c146a53 Update to bsnes v009 release.
- Fixed non-interlaced display modes from not drawing every other frame
    - Changed OAM halve to skip every other scanline in 224-height modes
    - Updated renderer to properly support games that switch resolutions mid-frame
    - Fixed VRAM address remapping modes, fixes DQ3R, FF: MQ
    - Fixed a bug in main color window clipping affecting BGs
    - Added video color curve option, thanks to Overload for the idea + color table
    - Added vblank, FPS counter, and DDraw surface memory options to settings menu
    - Added fullscreen modes 640x480 and 1024x768 to video modes
    - Added option to toggle the menubar on and off by pressing the escape key
    - Mode3 was not rendering sprites
    - Priorities were wrong for modes 2-4, thanks to anomie for info
    - Fixed a serious bug in IRQ interrupts. May not be perfect, but helps many games
2005-06-26 11:07:38 +00:00
byuu a471c150c9 Update to bsnes v008 release.
moving the window + main color window clipping into the bg/oam/mode7 rendering routines themselves, I was able to greatly simplify the most complicated part of rendering: the final pass where color add/sub effects are applied. As a result, the new PPU core is not only ~35% faster (on graphics intensive screens, even faster on simpler screens), but more accurate as well. Awesome.
In celebration, I´m releasing bsnes v0.008. I can actually run all games I have at >60fps on my Athlon 1.67ghz PC. Probably not something to brag about, though ...
Oh, and I also updated the keyboard polling code to only capture keypresses if the main window has focus. I´ve been meaning to do this for the better part of a year now, but never got around to it.
If, for some reason, you still want to use the old renderer, you can uncomment the first line in src/ppu/bppu/bppu.h and recompile the emulator yourself. Or you can use v0.007a, I´ll leave it up for a bit.
2005-06-21 09:13:40 +00:00
byuu ea38ea2537 Update to bsnes v007a release.
[No changelog available]
2005-06-13 04:34:10 +00:00
byuu 09b326ae86 Update to bsnes v007 release.
I have done quite a bit, so I´ll try my best to recap most of the fixes since the last release...
    - HDMA was not running during DMA transfers
    - Emulator did not recognize any filetype other than .smc
    - Added configuration file support and imported my vector/string/config libraries into bsnes
    - Added option to use system RAM instead of video RAM for display, this can greatly increase speed on certain video cards
    - Increased speed by ~15% by adding 256x224 renderer (still very buggy when the SNES mixes video modes mid-frame)
    - mvn/mvp opcodes were not setting the DB register
    - Fixed joypad input in many games (Super Mario: All Stars, Dragon Quest III, etc.)
    - Major speedup with frakeskip option
    - Fixed default aspect ratio when emulator is first started
There´s probably a lot more, but that´s all I remember offhand... this release should be a lot closer to the quality of v0.005a, but still needs a bit more polishing.
2005-06-12 08:15:22 +00:00
byuu a60f667b25 Update to bsnes v006 release.
The rewrite is now complete. I finished adding frameskip, and fixed some crashing issues with loading multiple ROMs. I wrapped all malloc/free calls with memalloc/memfree, which are custom functions that log each call, and let you pass sprintf-style arguments to them to debug memory leaks. Don´t see any, nor have I noticed any in bsnes; but it makes a nice test tool anyway.
I found out today that the mvn/mvp instructions actually set the DB register to the destination bank. Weird. This fixed Final Fantasy V, Chrono Trigger, and Dragon Quest III (which now runs as a result) graphics. Not all of them, but quite a few. I had also previously been setting the M/X flags of the P register when xce was executed. I never anticipated a game using xce while in native mode to switch to... native mode... but apparently, Chrono Trigger does. And my code was incorrect. So now Chrono Trigger gets past the name select screen, but dies a few screens after still.
The only really major flaw I am aware of that bsnes v0.005 did not have is with the battle screens in Squaresoft games. I get horrible flickering and "crushed scanlines" every other frame on them, for some reason. I´ll try and track that down for the next release, but I didn´t want to hold up a new release any longer. As a result, I´ll leave up v0.005a for the time being until I get this problem fixed.
2005-05-13 12:03:02 +00:00
byuu 6f7cf1bd31 Update to bsnes v005a release.
[No changelog available]
2005-02-06 04:04:32 +00:00
byuu 8751bc433f Update to bsnes v005 release.
Released a new version of bsnes today. Version 0.0.005 is up on the main page now.
The changes since .004 wip10 include: DRAM timing fix (now occurs mid-opcode), memory address speed fix, added CPU cycle condition 4 to all opcodes that use it, and fixed a bug where DRAM refresh was not changing start positions every other scanline.
With the new version, Chrono Trigger should get a little further, and Final Fantasy 5 should get in-game now. The only problem FF5 seems to have is sprite corrution in the menus. I´m too busy with the CPU timing to mess around with the PPU right now, though. Also, the APU is not bridged to the CPU in this release, so compatibility is (still) really low.
After I get the APU working fairly well, I´ll (try and) start keeping a what´s new file so that people can know what all changed between public releases of the emulator without having to follow this page. Sorry for the inconvenience in the mean time.

[No archive available]
2005-02-05 00:00:00 +00:00
byuu afbee40bc0 Update to bsnes v004 release.
[No changelog available]

[No archive available]
2004-12-24 00:00:00 +00:00
byuu 81e9be64d2 Update to bsnes v003r01 release.
[No changelog available]

[No archive available]
2004-12-13 00:00:00 +00:00
byuu 0cd4972d11 Update to bsnes v002 ir11 release.
Doubled the width of sprites when the width of the screen is 512. The SNES Test Program now runs through all of the character test correctly. The windows are off-by-one though.
Added the very bizarre 00:4300-00:437f memory region that is unique from 7e:4300-7e:437f. Then I added read support from $2180. This allowed the SNES Test Program to not crash after failing the electronics test, and it also fixed the horrible graphics corruption in Der Langrisser.
The fonts were still failing, so I went in with my tracer and found out what was causing it. The following code:
	gx816->regs.pc += (signed char)(arg + 2);
This is the code used to increment the pc counter after relative branches. The problem is that I had parinthesis around the + 2 as well as arg. Therefore, if arg was 0x7e, 0x7f, 0xfe, or 0xff, it would change the sign. This would in turn make the program counter off by 256 bytes. Very bad. Fixing this fixed the font in Der Langrisser, and also fixed Super Mario World, when Yoshi spits a turtle out, the game will no longer crash.
Next, via the Der Langrisser world map, I realized that anomie´s description of the BG/mode7 register latches was reversed: the BG registers (may) share a common latch between all of them, but the mode7 registers do not. I removed the common latches from the mode7 regs, but I haven´t added the latch to the BG registers yet.
I also realized that clearing the entire screen on a BG mode change would probably not be a good thing for games that change video modes mid-frame. So I tried working on getting the weird single-frame garble that pops up every minute or so to go away, but to no avail. I´m having a difficult time tracking down the exact cause of the error, but I believe it to be a buffer overflow, or something along those lines.

[No archive available]
2004-12-11 00:00:00 +00:00
byuu 938609818f Update to bsnes v002 ir9 release.
[No changelog available]
2004-12-07 01:12:32 +00:00
byuu 487491e6f2 Update to bsnes v002 ir7 release.
The bug in the Bahamut Lagoon mode7 screens turned out to be that I never added the dividend result to $4216/$4217. It always returned the multiplication of $4202/$4203. This also fixed the sprites in battles for Dai Kaijuu Monogatari. I added a bunch of window stuff, including a double size windowed mode, and a fullscreen mode. Lots of fixes to the interface, as well as code cleanup. It's still pretty buggy, there's a lot of variables to keep up with in the GUI at present...
I also added better tile caching, I just cache all tiles when they are rendered, for all 3 color depths (4, 16, 256). Seems to help a little. A portion of the speed gain was lost by fixing the dividend result, though. Very strange, since I wouldn't think much work would go into a simple line of code that's called 20 times a frame probably at best... oh well.

[No archive available]
2004-12-05 00:00:00 +00:00
byuu a6ccc7e5d2 Update to unreleased version.
First, I fixed some issues with the mode7 / scroll regs thanks to info from anomie. Qwertie's mode7 demo runs without modification now. Next, I fixed a small glitch with tiles getting cut off on the right edge of the screen, fixes some flickering on the edges in Zelda 3. Finally, I added tile caching to all 4 BG layers. It didn't really increase speed by much (~10%), and upped the RAM requirements by 1.2mb... I left the old code in case I need to fall back on it. My only guess (hope) is that the bottleneck lies somewhere else...

[No archive available]
2004-12-04 00:00:00 +00:00
byuu 39dd39cc09 Update to unreleased version.
Had a small glitch in the OAM $2102/$2103 register settings, fixed that and now both Zelda 3 and Super Mario World always show sprites perfectly. The only error to my knowledge in the below screenshots is that the large version of the mario sprite in the third pic is not shown at the top left of the screen. Which could be because I have no mosaic support. But at any rate, both games should be completely playable now, albeit very slowly. I tried to speed up things by caching some stuff in the PPU, but I couldn't find a nice way to implement it that would result in a significant speed increase. Oh yeah, Zelda won't follow you in Zelda 3, but you can just go to the throne room and push the picture to the right yourself, and she'll appear when you reach the sanctuary.
I also updated the debugger, it uses a smaller font, which is a bit harder to read, but saves a lot of screen space. This will definately be needed when I add in more of the debugging windows in the future, so it's better to get used to it now than later.

[No archive available]
2004-11-27 00:00:00 +00:00
byuu 1a017ff697 Update to unreleased version.
Added SRAM support. It's compatible with other emulators. It maps both the LoROM SRAM between $700000-$7dffff, and HiROM SRAM between $3n6000-$3n7fff (where n = 0 - f).
Modified the screen to redraw at scanline 224, instead of 0. Fixes some flickering between screens in some games.
Moved the lighting adjustment code ($2100 bits 0-3) directly into the PPU, rather than outside in the platform-specific code. This is because games have the ability to adjust this value per scanline. Also allowed the games to control the background enable ($2100 bit 7) flag per scanline now. This allowed Bahamut Lagoon's dragon intro to work.
I then added mode2 support, so now all that's missing is modes 5 and 6 (interlaced).
I also created an easy #define to select between the public domain mode7 code I wrote, and the snes9x mode7 code. I'll go through one of these days and rewrite the snes9x code in a clean environment (e.g. without using the current mode7 file as a reference) to avoid the issue altogether, but for now... the snes9x code is twice as fast, and that's good enough for me.
Lastly, I also added in a trace checkbox to enable tracing. As such, the zip file of my work up now has debug mode enabled by default. I really need an overhaul of the gui implementation, and a configuration file. I have a very nice string library system (that I wrote myself) that I would love to take advantage of in this project.
Here's some screenshots of the dragon intro. Lots of HDMA here, showing that I pretty much have HDMA down, now. I remember zsnes used to have a problem with these screens, and had to do something with an HDMA hack to get around it. They figured out what the problem was, eventually. I was actually quite surprised my emulator does not suffer from this same problem. Lucky for me, as they never did mention what the problem was to begin with. The HDMA is technically drawing too soon (at the start of the scanline instead of the end) which probably messes things up a bit, and I'm guessing the scroll registers are screwing up in one or two of the below pics. No mosaic support either.

[No archive available]
2004-11-21 00:00:00 +00:00
byuu 591adfcb25 Update to unreleased version.
Initial release

[No archive available]
2004-10-14 00:00:00 +00:00
2823 changed files with 31195 additions and 280990 deletions

No files matched your search

-97
View File
@@ -1,97 +0,0 @@
ifeq ($(platform),windows)
options += -luuid -lkernel32 -luser32 -lgdi32 -lcomctl32 -lcomdlg32 -lshell32
options += -Wl,-enable-auto-import
options += -Wl,-enable-runtime-pseudo-reloc
else ifeq ($(platform),macos)
else ifneq ($(filter $(platform),linux bsd),)
options += -Wl,-export-dynamic
options += -lX11 -lXext
else
$(error "ares is a library and cannot be built directly.")
endif
ares.objects := ares
$(object.path)/ares.o: $(ares.path)/ares/ares.cpp
ifeq ($(vulkan),true)
flags += -DVULKAN
endif
ifeq ($(profile),accuracy)
flags += -DPROFILE_ACCURACY
endif
ifeq ($(profile),performance)
flags += -DPROFILE_PERFORMANCE
endif
ifneq ($(filter $(cores),fc),)
include $(ares.path)/fc/GNUmakefile
endif
ifneq ($(filter $(cores),sfc),)
include $(ares.path)/sfc/GNUmakefile
endif
ifneq ($(filter $(cores),n64),)
include $(ares.path)/n64/GNUmakefile
endif
ifneq ($(filter $(cores),sg),)
include $(ares.path)/sg/GNUmakefile
endif
ifneq ($(filter $(cores),ms),)
include $(ares.path)/ms/GNUmakefile
endif
ifneq ($(filter $(cores),md),)
include $(ares.path)/md/GNUmakefile
endif
ifneq ($(filter $(cores),saturn),)
include $(ares.path)/saturn/GNUmakefile
endif
ifneq ($(filter $(cores),ps1),)
include $(ares.path)/ps1/GNUmakefile
endif
ifneq ($(filter $(cores),pce),)
include $(ares.path)/pce/GNUmakefile
endif
ifneq ($(filter $(cores),msx),)
include $(ares.path)/msx/GNUmakefile
endif
ifneq ($(filter $(cores),cv),)
include $(ares.path)/cv/GNUmakefile
endif
ifneq ($(filter $(cores),gb),)
include $(ares.path)/gb/GNUmakefile
endif
ifneq ($(filter $(cores),gba),)
include $(ares.path)/gba/GNUmakefile
endif
ifneq ($(filter $(cores),ws),)
include $(ares.path)/ws/GNUmakefile
endif
ifneq ($(filter $(cores),ng),)
include $(ares.path)/ng/GNUmakefile
endif
ifneq ($(filter $(cores),ngp),)
include $(ares.path)/ngp/GNUmakefile
endif
include $(ares.path)/component/GNUmakefile
flags += $(foreach c,$(call strupper,$(cores)),-DCORE_$c)
ares.objects := $(ares.objects:%=$(object.path)/%.o)
-81
View File
@@ -1,81 +0,0 @@
#version 150
//anti-aliased nearest-neighbor
precision highp float;
uniform sampler2D source[];
uniform vec4 sourceSize[];
uniform vec4 targetSize[];
in Vertex {
vec2 texCoord;
};
out vec4 fragColor;
vec4 vpow(vec4 n, float e) {
return vec4(pow(n.x, e), pow(n.y, e), pow(n.z, e), pow(n.w, e));
}
vec4 toLQV(vec3 c) {
return vec4(c.r, c.g, c.b, c.r * 0.2989 + c.g * 0.5870 + c.b * 0.1140);
}
vec3 fromLQV(vec4 c) {
float f = c.w / (c.r * 0.2989 + c.g * 0.5870 + c.b * 0.1140);
return vec3(c.rgb) * f;
}
vec3 percent(float ssize, float tsize, float coord) {
float minfull = (coord * tsize - 0.5) / tsize * ssize;
float maxfull = (coord * tsize + 0.5) / tsize * ssize;
float realfull = floor(maxfull);
if(minfull > realfull) {
return vec3(
1,
(realfull + 0.5) / ssize,
(realfull + 0.5) / ssize
);
}
return vec3(
(maxfull - realfull) / (maxfull - minfull),
(realfull - 0.5) / ssize,
(realfull + 0.5) / ssize
);
}
void main() {
float srgb = 2.1;
float gamma = 3.0;
vec3 x = percent(sourceSize[0].x, targetSize[0].x, texCoord.x);
vec3 y = percent(sourceSize[0].y, targetSize[0].y, texCoord.y);
//get points to interpolate across in linear RGB
vec4 a = toLQV(vpow(texture(source[0], vec2(x[1], y[1])), srgb).rgb);
vec4 b = toLQV(vpow(texture(source[0], vec2(x[2], y[1])), srgb).rgb);
vec4 c = toLQV(vpow(texture(source[0], vec2(x[1], y[2])), srgb).rgb);
vec4 d = toLQV(vpow(texture(source[0], vec2(x[2], y[2])), srgb).rgb);
//use perceptual gamma for luminance component
a.w = pow(a.w, 1 / gamma);
b.w = pow(b.w, 1 / gamma);
c.w = pow(c.w, 1 / gamma);
d.w = pow(d.w, 1 / gamma);
//interpolate
vec4 gammaLQV =
(1.0 - x[0]) * (1.0 - y[0]) * a +
(0.0 + x[0]) * (1.0 - y[0]) * b +
(1.0 - x[0]) * (0.0 + y[0]) * c +
(0.0 + x[0]) * (0.0 + y[0]) * d;
//convert luminance gamma back to linear
gammaLQV.w = pow(gammaLQV.w, gamma);
//convert color back to sRGB
fragColor = vpow(vec4(fromLQV(gammaLQV), 1), 1 / srgb);
}
-8
View File
@@ -1,8 +0,0 @@
input
filter: nearest
program
fragment: AANN.fs
output
filter: nearest
@@ -1,21 +0,0 @@
#version 150
#define distortion 0.2
uniform sampler2D source[];
uniform vec4 sourceSize[];
in Vertex {
vec2 texCoord;
};
out vec4 fragColor;
vec2 radialDistortion(vec2 coord) {
vec2 cc = coord - vec2(0.5);
float dist = dot(cc, cc) * distortion;
return coord + cc * (1.0 - dist) * dist;
}
void main() {
fragColor = texture(source[0], radialDistortion(texCoord));
}
@@ -1,4 +0,0 @@
program
filter: linear
wrap: border
fragment: curvature.fs
@@ -1,25 +0,0 @@
#version 150
uniform sampler2D source[];
uniform vec4 sourceSize[];
in Vertex {
vec2 texCoord;
};
out vec4 fragColor;
vec3 grayscale(vec3 color) {
return vec3(dot(color, vec3(0.3, 0.59, 0.11)));
}
void main() {
vec2 offset = fract(texCoord * sourceSize[0].xy) - 0.5;
offset /= sourceSize[0].xy;
vec3 cx = texture(source[0], texCoord - offset).xyz;
vec3 cy = texture(source[0], texCoord).xyz;
vec3 cz = vec3(5.0 * grayscale(abs(cx - cy)));
fragColor = vec4(clamp(cz, 0.0, 1.0), 1.0);
}
@@ -1,4 +0,0 @@
program
filter: linear
wrap: edge
fragment: edge-detection.fs
@@ -1,4 +0,0 @@
program
filter: linear
wrap: border
fragment: scanline.fs
-20
View File
@@ -1,20 +0,0 @@
#version 150
uniform sampler2D source[];
in Vertex {
vec2 texCoord;
};
out vec4 fragColor;
void main() {
vec4 rgba = texture(source[0], texCoord);
vec4 intensity;
if(fract(gl_FragCoord.y * (0.5 * 4.0 / 3.0)) > 0.5) {
intensity = vec4(0);
} else {
intensity = smoothstep(0.2, 0.8, rgba) + normalize(rgba);
}
fragColor = intensity * -0.25 + rgba * 1.1;
}
Whitespace-only changes.
Whitespace-only changes.
Whitespace-only changes.
Binary file not shown.
Binary file not shown.
Whitespace-only changes.
Binary file not shown.
Binary file not shown.
Binary file not shown.
View File
Whitespace-only changes.
Whitespace-only changes.
@@ -1,122 +0,0 @@
layout
name: Japanese
//row 0
key: 0 わ を
key: 1 ! ぬ
key: 2 " ふ
key: 3 # あ ぁ
key: 4 $ う ぅ
key: 5 % え ぇ
key: 6 & お ぉ
key: 7 ’ や ゃ
//row 1
key: 8 ( ゆ ゅ
key: 9 ) よ ょ
key: - = ほ
key: ^ ~ へ
key: ¥ | ー
key: @ ‘ "
key: [ { 。
key: ; + れ
//row 2
key: : * け
key: ] } む
key: , < ね `
key: . > る 。
key: / ? め .
key: - ろ
key: A ち
key: B こ
//row 3
key: C そ
key: D し
key: E い ぃ
key: F は
key: G き
key: H く
key: I に
key: J ま
//row 4
key: K の
key: L り
key: M も
key: N み
key: O ら
key: P せ
key: Q た
key: R す
//row 5
key: S と
key: T か
key: U な
key: V ひ
key: W て
key: X さ
key: Y ん
key: Z つ っ
//row 6
key: SHIFT
key: CTRL
key: GRAPH
key: CAPS
key: かな
key: F1 F6
key: F2 F7
key: F3 F8
//row 7
key: F4 F9
key: F5 F10
key: ESC
key: TAB
key: STOP
key: BS
key: SELECT
key: RETURN
//row 8
key: SPACE
key: CLS/HOME
key: INS
key: DEL
key: ←
key: ↑
key: ↓
key: →
//row 9
key: *
key: +
key: /
key: 0
key: 1
key: 2
key: 3
key: 4
//row 10
key: 5
key: 6
key: 7
key: 8
key: 9
key: -
key: ,
key: .
//row 11
key:
key: 実行
key:
key: 取消
key:
key:
key:
key:
Binary file not shown.
Whitespace-only changes.
@@ -1,122 +0,0 @@
layout
name: Japanese
//row 0
key: 0 わ を
key: 1 ! ぬ
key: 2 " ふ
key: 3 # あ ぁ
key: 4 $ う ぅ
key: 5 % え ぇ
key: 6 & お ぉ
key: 7 ’ や ゃ
//row 1
key: 8 ( ゆ ゅ
key: 9 ) よ ょ
key: - = ほ
key: ^ ~ へ
key: ¥ | ー
key: @ ‘ "
key: [ { 。
key: ; + れ
//row 2
key: : * け
key: ] } む
key: , < ね `
key: . > る 。
key: / ? め .
key: - ろ
key: A ち
key: B こ
//row 3
key: C そ
key: D し
key: E い ぃ
key: F は
key: G き
key: H く
key: I に
key: J ま
//row 4
key: K の
key: L り
key: M も
key: N み
key: O ら
key: P せ
key: Q た
key: R す
//row 5
key: S と
key: T か
key: U な
key: V ひ
key: W て
key: X さ
key: Y ん
key: Z つ っ
//row 6
key: SHIFT
key: CTRL
key: GRAPH
key: CAPS
key: かな
key: F1 F6
key: F2 F7
key: F3 F8
//row 7
key: F4 F9
key: F5 F10
key: ESC
key: TAB
key: STOP
key: BS
key: SELECT
key: RETURN
//row 8
key: SPACE
key: CLS/HOME
key: INS
key: DEL
key: ←
key: ↑
key: ↓
key: →
//row 9
key: *
key: +
key: /
key: 0
key: 1
key: 2
key: 3
key: 4
//row 10
key: 5
key: 6
key: 7
key: 8
key: 9
key: -
key: ,
key: .
//row 11
key:
key: 実行
key:
key: 取消
key:
key:
key:
key:
Binary file not shown.
Binary file not shown.
Whitespace-only changes.
Whitespace-only changes.
Whitespace-only changes.
Whitespace-only changes.
Binary file not shown.
Whitespace-only changes.
Whitespace-only changes.
Whitespace-only changes.
Binary file not shown.
Binary file not shown.
Whitespace-only changes.
Whitespace-only changes.
Whitespace-only changes.
Whitespace-only changes.
Whitespace-only changes.
Binary file not shown.
Whitespace-only changes.
Whitespace-only changes.
Whitespace-only changes.
Whitespace-only changes.
Whitespace-only changes.
Whitespace-only changes.
Whitespace-only changes.
Whitespace-only changes.
Whitespace-only changes.
Whitespace-only changes.
Whitespace-only changes.
Whitespace-only changes.
-970
View File
@@ -1,970 +0,0 @@
database
revision: 2020-11-09
//Boards (Production)
database
revision: 2020-01-21
board: BANDAI-PT-923
memory type=ROM content=Program
map address=00-1f,80-9f:8000-ffff mask=0x8000
slot type=SufamiTurbo
rom
map address=20-3f,a0-bf:8000-ffff mask=0x8000
ram
map address=60-6f,e0-ef:0000-ffff
slot type=SufamiTurbo
rom
map address=40-5f,c0-df:0000-ffff mask=0x8000
ram
map address=70-7d,f0-ff:0000-ffff
board: BSC-1A5B9P-01
memory type=RAM content=Save
map address=10-17:5000-5fff mask=0xf000
processor identifier=MCC
map address=00-0f:5000-5fff
mcu
map address=00-3f,80-bf:8000-ffff
map address=40-7d,c0-ff:0000-ffff
map address=20-3f,a0-bf:6000-7fff
memory type=ROM content=Program
memory type=RAM content=Download
slot type=BSMemory
board: BSC-1A5M-02
memory type=ROM content=Program
map address=00-1f:8000-ffff mask=0xe08000 base=0x000000
map address=20-3f:8000-ffff mask=0xe08000 base=0x100000
map address=80-9f:8000-ffff mask=0xe08000 base=0x200000
map address=a0-bf:8000-ffff mask=0xe08000 base=0x100000
memory type=RAM content=Save
map address=70-7d,f0-ff:0000-7fff mask=0x8000
slot type=BSMemory
map address=c0-ef:0000-ffff
board: BSC-1A7M-(01,10)
memory type=ROM content=Program
map address=00-1f:8000-ffff mask=0xe08000 base=0x000000
map address=20-3f:8000-ffff mask=0xe08000 base=0x100000
map address=80-9f:8000-ffff mask=0xe08000 base=0x200000
map address=a0-bf:8000-ffff mask=0xe08000 base=0x100000
memory type=RAM content=Save
map address=70-7d,f0-ff:0000-7fff mask=0x8000
slot type=BSMemory
map address=c0-ef:0000-ffff
board: BSC-1J3M-01
memory type=ROM content=Program
map address=00-1f,80-9f:8000-ffff
map address=40-5f,c0-df:0000-ffff
memory type=RAM content=Save
map address=20-3f,a0-bf:6000-7fff mask=0xe000
slot type=BSMemory
map address=20-3f,a0-bf:8000-ffff
map address=60-7d,e0-ff:0000-ffff
board: BSC-1J5M-01
memory type=ROM content=Program
map address=00-1f,80-9f:8000-ffff
map address=40-5f,c0-df:0000-ffff
memory type=RAM content=Save
map address=20-3f,a0-bf:6000-7fff mask=0xe000
slot type=BSMemory
map address=20-3f,a0-bf:8000-ffff
map address=60-7d,e0-ff:0000-ffff
board: BSC-1L3B-01
processor architecture=W65C816S
map address=00-3f,80-bf:2200-23ff
mcu
map address=00-3f,80-bf:8000-ffff mask=0x408000
map address=c0-ff:0000-ffff
memory type=ROM content=Program
slot type=BSMemory
memory type=RAM content=Save
map address=00-3f,80-bf:6000-7fff size=0x2000
map address=40-4f:0000-ffff
memory type=RAM content=Internal
map address=00-3f,80-bf:3000-37ff size=0x800
board: BSC-1L5B-01
processor architecture=W65C816S
map address=00-3f,80-bf:2200-23ff
mcu
map address=00-3f,80-bf:8000-ffff mask=0x408000
map address=c0-ff:0000-ffff
memory type=ROM content=Program
slot type=BSMemory
memory type=RAM content=Save
map address=00-3f,80-bf:6000-7fff size=0x2000
map address=40-4f:0000-ffff
memory type=RAM content=Internal
map address=00-3f,80-bf:3000-37ff size=0x800
board: SGB-R-10
memory type=ROM content=Program
map address=00-7d,80-ff:8000-ffff mask=0x8000
map address=40-7d,c0-ff:0000-7fff mask=0x8000
processor identifier=ICD revision=2
map address=00-3f,80-bf:6000-67ff,7000-7fff
memory type=ROM content=Boot architecture=SM83
slot type=GameBoy
board: SHVC-1A0N-(01,02,10,20,30)
memory type=ROM content=Program
map address=00-7d,80-ff:8000-ffff mask=0x8000
map address=40-7d,c0-ff:0000-7fff mask=0x8000
board: SHVC-1A1B-(04,05,06)
memory type=ROM content=Program
map address=00-1f,80-9f:8000-ffff mask=0x8000
memory type=RAM content=Save
map address=70-7d,f0-ff:0000-ffff
board: SHVC-1A1M-(01,10,11,20)
memory type=ROM content=Program
map address=00-7d,80-ff:8000-ffff mask=0x8000
memory type=RAM content=Save
map address=70-7d,f0-ff:0000-7fff mask=0x8000
board: SHVC-1A3B-(11,12,13)
memory type=ROM content=Program
map address=00-1f,80-9f:8000-ffff mask=0x8000
memory type=RAM content=Save
map address=70-7d,f0-ff:0000-ffff
board: SHVC-1A3B-20
memory type=ROM content=Program
map address=00-7d,80-ff:8000-ffff mask=0x8000
memory type=RAM content=Save
map address=70-7d,f0-ff:0000-7fff mask=0x8000
board: SHVC-1A3M-(10,20,21,30)
memory type=ROM content=Program
map address=00-7d,80-ff:8000-ffff mask=0x8000
memory type=RAM content=Save
map address=70-7d,f0-ff:0000-7fff mask=0x8000
board: SHVC-1A5B-(02,04)
memory type=ROM content=Program
map address=00-1f,80-9f:8000-ffff mask=0x8000
memory type=RAM content=Save
map address=70-7d,f0-ff:0000-ffff
board: SHVC-1A5M-(01,11,20)
memory type=ROM content=Program
map address=00-7d,80-ff:8000-ffff mask=0x8000
memory type=RAM content=Save
map address=70-7d,f0-ff:0000-7fff mask=0x8000
board: SHVC-1B0N-(02,03,10)
memory type=ROM content=Program
map address=00-1f,80-9f:8000-ffff mask=0x8000
processor architecture=uPD7725
map address=30-3f,b0-bf:8000-ffff mask=0x3fff
memory type=ROM content=Program architecture=uPD7725
memory type=ROM content=Data architecture=uPD7725
memory type=RAM content=Data architecture=uPD7725
oscillator
board: SHVC-1B5B-02
memory type=ROM content=Program
map address=00-1f,80-9f:8000-ffff mask=0x8000
memory type=RAM content=Save
map address=70-7d,f0-ff:0000-ffff
processor architecture=uPD7725
map address=20-3f,a0-bf:8000-ffff mask=0x3fff
memory type=ROM content=Program architecture=uPD7725
memory type=ROM content=Data architecture=uPD7725
memory type=RAM content=Data architecture=uPD7725
oscillator
board: SHVC-1C0N
processor architecture=GSU
map address=00-3f,80-bf:3000-34ff
memory type=ROM content=Program
map address=00-1f,80-9f:8000-ffff mask=0x8000
memory type=RAM content=Save
map address=60-7d,e0-ff:0000-ffff
board: SHVC-1C0N5S-01
processor architecture=GSU
map address=00-3f,80-bf:3000-34ff
memory type=ROM content=Program
map address=00-1f,80-9f:8000-ffff mask=0x8000
memory type=RAM content=Save
map address=60-7d,e0-ff:0000-ffff
board: SHVC-1CA0N5S-01
processor architecture=GSU
map address=00-3f,80-bf:3000-34ff
memory type=ROM content=Program
map address=00-3f,80-bf:8000-ffff mask=0x8000
map address=40-5f,c0-df:0000-ffff
memory type=RAM content=Save
map address=00-3f,80-bf:6000-7fff size=0x2000
map address=70-71,f0-f1:0000-ffff
board: SHVC-1CA0N6S-01
processor architecture=GSU
map address=00-3f,80-bf:3000-34ff
memory type=ROM content=Program
map address=00-3f,80-bf:8000-ffff mask=0x8000
map address=40-5f,c0-df:0000-ffff
memory type=RAM content=Save
map address=00-3f,80-bf:6000-7fff size=0x2000
map address=70-71,f0-f1:0000-ffff
board: SHVC-1CA6B-01
processor architecture=GSU
map address=00-3f,80-bf:3000-34ff
memory type=ROM content=Program
map address=00-3f,80-bf:8000-ffff mask=0x8000
map address=40-5f,c0-df:0000-ffff
memory type=RAM content=Save
map address=00-3f,80-bf:6000-7fff size=0x2000
map address=70-71,f0-f1:0000-ffff
board: SHVC-1CB0N7S-01
processor architecture=GSU
map address=00-3f,80-bf:3000-34ff
memory type=ROM content=Program
map address=00-3f:8000-ffff mask=0x8000
map address=40-5f:0000-ffff
memory type=RAM content=Save
map address=00-3f,80-bf:6000-7fff size=0x2000
map address=70-71:0000-ffff
board: SHVC-1CB5B-(01,20)
processor architecture=GSU
map address=00-3f,80-bf:3000-34ff
memory type=ROM content=Program
map address=00-3f:8000-ffff mask=0x8000
map address=40-5f:0000-ffff
memory type=RAM content=Save
map address=00-3f,80-bf:6000-7fff size=0x2000
map address=70-71:0000-ffff
board: SHVC-1CB7B-01
processor architecture=GSU
map address=00-3f,80-bf:3000-34ff
memory type=ROM content=Program
map address=00-3f:8000-ffff mask=0x8000
map address=40-5f:0000-ffff
memory type=RAM content=Save
map address=00-3f,80-bf:6000-7fff size=0x2000
map address=70-71:0000-ffff
board: SHVC-1DC0N-01
processor architecture=HG51BS169
map address=00-3f,80-bf:6c00-6fff,7c00-7fff
memory type=ROM content=Program
map address=00-3f,80-bf:8000-ffff mask=0x8000
memory type=RAM content=Save
map address=70-77:0000-7fff
memory type=ROM content=Data architecture=HG51BS169
memory type=RAM content=Data architecture=HG51BS169
map address=00-3f,80-bf:6000-6bff,7000-7bff mask=0xf000
oscillator
board: SHVC-1DS0B-20
memory type=ROM content=Program
map address=00-7d,80-ff:8000-ffff mask=0x8000
processor architecture=uPD96050
map address=60-67,e0-e7:0000-3fff
memory type=ROM content=Program architecture=uPD96050
memory type=ROM content=Data architecture=uPD96050
memory type=RAM content=Data architecture=uPD96050
map address=68-6f,e8-ef:0000-7fff mask=0x8000
oscillator
board: SHVC-1J0N-(01,10,20)
memory type=ROM content=Program
map address=00-3f,80-bf:8000-ffff
map address=40-7d,c0-ff:0000-ffff
board: SHVC-1J1M-(11,20)
memory type=ROM content=Program
map address=00-3f,80-bf:8000-ffff
map address=40-7d,c0-ff:0000-ffff
memory type=RAM content=Save
map address=20-3f,a0-bf:6000-7fff mask=0xe000
board: SHVC-1J3B-01
memory type=ROM content=Program
map address=00-3f,80-bf:8000-ffff
map address=40-7d,c0-ff:0000-ffff
memory type=RAM content=Save
map address=20-3f,a0-bf:6000-7fff mask=0xe000
board: SHVC-1J3M-(01,11,20)
memory type=ROM content=Program
map address=00-3f,80-bf:8000-ffff
map address=40-7d,c0-ff:0000-ffff
memory type=RAM content=Save
map address=20-3f,a0-bf:6000-7fff mask=0xe000
board: SHVC-1J5M-(01,11,20)
memory type=ROM content=Program
map address=00-3f,80-bf:8000-ffff
map address=40-7d,c0-ff:0000-ffff
memory type=RAM content=Save
map address=20-3f,a0-bf:6000-7fff mask=0xe000
board: SHVC-1K0N-01
memory type=ROM content=Program
map address=00-3f,80-bf:8000-ffff
map address=40-7d,c0-ff:0000-ffff
processor architecture=uPD7725
map address=00-1f,80-9f:6000-7fff mask=0xfff
memory type=ROM content=Program architecture=uPD7725
memory type=ROM content=Data architecture=uPD7725
memory type=RAM content=Data architecture=uPD7725
oscillator
board: SHVC-1K1B-01
memory type=ROM content=Program
map address=00-3f,80-bf:8000-ffff
map address=40-7d,c0-ff:0000-ffff
memory type=RAM content=Save
map address=20-3f,a0-bf:6000-7fff mask=0xe000
processor architecture=uPD7725
map address=00-1f,80-9f:6000-7fff mask=0xfff
memory type=ROM content=Program architecture=uPD7725
memory type=ROM content=Data architecture=uPD7725
memory type=RAM content=Data architecture=uPD7725
oscillator
board: SHVC-1K1X-10
memory type=ROM content=Program
map address=00-3f,80-bf:8000-ffff
map address=40-7d,c0-ff:0000-ffff
memory type=RAM content=Save
map address=20-3f,a0-bf:6000-7fff mask=0xe000
processor architecture=uPD7725
map address=00-1f,80-9f:6000-7fff mask=0xfff
memory type=ROM content=Program architecture=uPD7725
memory type=ROM content=Data architecture=uPD7725
memory type=RAM content=Data architecture=uPD7725
oscillator
board: SHVC-1L0N3S-01
processor architecture=W65C816S
map address=00-3f,80-bf:2200-23ff
mcu
map address=00-3f,80-bf:8000-ffff mask=0x408000
map address=c0-ff:0000-ffff
memory type=ROM content=Program
memory type=RAM content=Save
map address=00-3f,80-bf:6000-7fff size=0x2000
map address=40-4f:0000-ffff
memory type=RAM content=Internal
map address=00-3f,80-bf:3000-37ff size=0x800
board: SHVC-1L3B-(02,11)
processor architecture=W65C816S
map address=00-3f,80-bf:2200-23ff
mcu
map address=00-3f,80-bf:8000-ffff mask=0x408000
map address=c0-ff:0000-ffff
memory type=ROM content=Program
memory type=RAM content=Save
map address=00-3f,80-bf:6000-7fff size=0x2000
map address=40-4f:0000-ffff
memory type=RAM content=Internal
map address=00-3f,80-bf:3000-37ff size=0x800
board: SHVC-1L5B-(11,20)
processor architecture=W65C816S
map address=00-3f,80-bf:2200-23ff
mcu
map address=00-3f,80-bf:8000-ffff mask=0x408000
map address=c0-ff:0000-ffff
memory type=ROM content=Program
memory type=RAM content=Save
map address=00-3f,80-bf:6000-7fff size=0x2000
map address=40-4f:0000-ffff
memory type=RAM content=Internal
map address=00-3f,80-bf:3000-37ff size=0x800
board: SHVC-1N0N-(01,10)
processor identifier=SDD1
map address=00-3f,80-bf:4800-480f
mcu
map address=00-3f,80-bf:8000-ffff
map address=c0-ff:0000-ffff
memory type=ROM content=Program
board: SHVC-2A0N-01#A
memory type=ROM content=Program
map address=00-2f,80-af:8000-ffff mask=0x8000
map address=40-6f,c0-ef:0000-ffff mask=0x8000
board: SHVC-2A0N-(01,10,11,20)
memory type=ROM content=Program
map address=00-7d,80-ff:8000-ffff mask=0x8000
map address=40-7d,c0-ff:0000-7fff mask=0x8000
board: SHVC-2A1M-01
memory type=ROM content=Program
map address=00-7d,80-ff:8000-ffff mask=0x8000
memory type=RAM content=Save
map address=70-7d,f0-ff:0000-7fff mask=0x8000
board: SHVC-2A3B-01
memory type=ROM content=Program
map address=00-3f,80-bf:8000-ffff mask=0x8000
memory type=RAM content=Save
map address=70-7d,f0-ff:0000-7fff mask=0x8000
board: SHVC-2A3M-01#A
memory type=ROM content=Program
map address=00-3f,80-bf:8000-ffff mask=0x8000
memory type=RAM content=Save
map address=70-7d,f0-ff:0000-7fff mask=0x8000
board: SHVC-2A3M-(01,11,20)
memory type=ROM content=Program
map address=00-7d,80-ff:8000-ffff mask=0x8000
memory type=RAM content=Save
map address=70-7d,f0-ff:0000-7fff mask=0x8000
board: SHVC-2A5M-01
memory type=ROM content=Program
map address=00-7d,80-ff:8000-ffff mask=0x8000
memory type=RAM content=Save
map address=70-7d,f0-ff:0000-7fff mask=0x8000
board: SHVC-2B3B-01
memory type=ROM content=Program
map address=00-3f,80-bf:8000-ffff mask=0x8000
memory type=RAM content=Save
map address=70-7d,f0-ff:0000-7fff mask=0x8000
processor architecture=uPD7725
map address=60-6f,e0-ef:0000-7fff mask=0x3fff
memory type=ROM content=Program architecture=uPD7725
memory type=ROM content=Data architecture=uPD7725
memory type=RAM content=Data architecture=uPD7725
oscillator
board: SHVC-2DC0N-01
processor architecture=HG51BS169
map address=00-3f,80-bf:6c00-6fff,7c00-7fff
memory type=ROM content=Program
map address=00-3f,80-bf:8000-ffff mask=0x8000
memory type=RAM content=Save
map address=70-77:0000-7fff
memory type=ROM content=Data architecture=HG51BS169
memory type=RAM content=Data architecture=HG51BS169
map address=00-3f,80-bf:6000-6bff,7000-7bff mask=0xf000
oscillator
board: SHVC-2E3M-01
memory type=ROM content=Program
map address=00-3f,80-bf:8000-ffff mask=0x8000
processor identifier=OBC1
map address=00-3f,80-bf:6000-7fff mask=0xe000
map address=70-71,f0-f1:6000-7fff,e000-ffff mask=0xe000
memory type=RAM content=Save
board: SHVC-2J0N-(01,10,11,20)
memory type=ROM content=Program
map address=00-3f,80-bf:8000-ffff
map address=40-7d,c0-ff:0000-ffff
board: SHVC-2J3M-(01,11,20)
memory type=ROM content=Program
map address=00-3f,80-bf:8000-ffff
map address=40-7d,c0-ff:0000-ffff
memory type=RAM content=Save
map address=10-1f,30-3f,90-9f,b0-bf:6000-7fff mask=0xe000
board: SHVC-2J5M-01
memory type=ROM content=Program
map address=00-3f,80-bf:8000-ffff
map address=40-7d,c0-ff:0000-ffff
memory type=RAM content=Save
map address=10-1f,30-3f,90-9f,b0-bf:6000-7fff mask=0xe000
board: SHVC-3J0N-01
memory type=ROM content=Program
map address=00-2f,80-af:8000-ffff
map address=40-6f,c0-ef:0000-ffff
board: SHVC-BA0N-(01,10)
memory type=ROM content=Program
map address=00-7d,80-ff:8000-ffff mask=0x8000
map address=40-7d,c0-ff:0000-7fff mask=0x8000
board: SHVC-BA1M-01
memory type=ROM content=Program
map address=00-7d,80-ff:8000-ffff mask=0x8000
memory type=RAM content=Save
map address=70-7d,f0-ff:0000-7fff mask=0x8000
board: SHVC-BA3M-(01,10)
memory type=ROM content=Program
map address=00-7d,80-ff:8000-ffff mask=0x8000
memory type=RAM content=Save
map address=70-7d,f0-ff:0000-7fff mask=0x8000
board: SHVC-BJ0N-(01,20)
memory type=ROM content=Program
map address=00-3f,80-bf:8000-ffff
map address=40-7d,c0-ff:0000-ffff
board: SHVC-BJ1M-(10,20)
memory type=ROM content=Program
map address=00-3f,80-bf:8000-ffff
map address=40-7d,c0-ff:0000-ffff
memory type=RAM content=Save
map address=20-3f,a0-bf:6000-7fff mask=0xe000
board: SHVC-BJ3M-(10,20)
memory type=ROM content=Program
map address=00-3f,80-bf:8000-ffff
map address=40-7d,c0-ff:0000-ffff
memory type=RAM content=Save
map address=20-3f,a0-bf:6000-7fff mask=0xe000
board: SHVC-LDH3C-01
processor identifier=SPC7110
map address=00-3f,80-bf:4800-483f
map address=50,58:0000-ffff
mcu
map address=00-3f,80-bf:8000-ffff mask=0x800000
map address=c0-ff:0000-ffff mask=0xc00000
memory type=ROM content=Program
memory type=ROM content=Data
memory type=RAM content=Save
map address=00-3f,80-bf:6000-7fff mask=0xe000
rtc manufacturer=Epson
map address=00-3f,80-bf:4840-4842
memory type=RTC content=Time manufacturer=Epson
board: SHVC-LJ3M-01
memory type=ROM content=Program
map address=00-3f:8000-ffff base=0x400000
map address=40-7d:0000-ffff base=0x400000
map address=80-bf:8000-ffff mask=0xc00000
map address=c0-ff:0000-ffff mask=0xc00000
memory type=RAM content=Save
map address=80-bf:6000-7fff mask=0xe000
board: SHVC-LN3B-01
memory type=RAM content=Save
map address=00-3f,80-bf:6000-7fff mask=0xe000
map address=70-73:0000-ffff
processor identifier=SDD1
map address=00-3f,80-bf:4800-480f
mcu
map address=00-3f,80-bf:8000-ffff
map address=c0-ff:0000-ffff
memory type=ROM content=Program
board: SHVC-SGB2-01
memory type=ROM content=Program
map address=00-7d,80-ff:8000-ffff mask=0x8000
map address=40-7d,c0-ff:0000-7fff mask=0x8000
processor identifier=ICD revision=2
map address=00-3f,80-bf:6000-67ff,7000-7fff
memory type=ROM content=Boot architecture=SM83
oscillator
slot type=GameBoy
board: SHVC-YA0N-01
memory type=ROM content=Program
map address=00-7d,80-ff:8000-ffff mask=0x8000
map address=40-7d,c0-ff:0000-7fff mask=0x8000
board: SHVC-YJ0N-01
memory type=ROM content=Program
map address=00-3f,80-bf:8000-ffff
map address=40-7d,c0-ff:0000-ffff
//Boards (Generic)
database
revision: 2020-11-09
board: ARM-LOROM-RAM
memory type=ROM content=Program
map address=00-7d,80-ff:8000-ffff mask=0x8000
map address=40-6f,c0-ef:0000-7fff mask=0x8000
memory type=RAM content=Save
map address=70-7d,f0-ff:0000-ffff
processor architecture=ARM6
map address=00-3f,80-bf:3800-38ff
memory type=ROM content=Program architecture=ARM6
memory type=ROM content=Data architecture=ARM6
memory type=RAM content=Data architecture=ARM6
oscillator
board: BS-HIROM-RAM
memory type=ROM content=Program
map address=00-1f,80-9f:8000-ffff
map address=40-5f,c0-df:0000-ffff
memory type=RAM content=Save
map address=20-3f,a0-bf:6000-7fff mask=0xe000
slot type=BSMemory
map address=20-3f,a0-bf:8000-ffff
map address=60-7d,e0-ff:0000-ffff
board: BS-LOROM-RAM
memory type=ROM content=Program
map address=00-1f:8000-ffff mask=0xe08000 base=0x000000
map address=20-3f:8000-ffff mask=0xe08000 base=0x100000
map address=80-9f:8000-ffff mask=0xe08000 base=0x200000
map address=a0-bf:8000-ffff mask=0xe08000 base=0x100000
memory type=RAM content=Save
map address=70-7d,f0-ff:0000-7fff mask=0x8000
slot type=BSMemory
map address=c0-ef:0000-ffff
board: BS-MCC-RAM
memory type=RAM content=Save
map address=10-17:5000-5fff mask=0xf000
processor identifier=MCC
map address=00-0f:5000-5fff
mcu
map address=00-3f,80-bf:8000-ffff
map address=40-7d,c0-ff:0000-ffff
map address=20-3f,a0-bf:6000-7fff
memory type=ROM content=Program
memory type=RAM content=Download
slot type=BSMemory
board: BS-SA1-RAM
processor architecture=W65C816S
map address=00-3f,80-bf:2200-23ff
mcu
map address=00-3f,80-bf:8000-ffff mask=0x408000
map address=c0-ff:0000-ffff
memory type=ROM content=Program
slot type=BSMemory
memory type=RAM content=Save
map address=00-3f,80-bf:6000-7fff size=0x2000
map address=40-4f:0000-ffff
memory type=RAM content=Internal
map address=00-3f,80-bf:3000-37ff size=0x800
board: EVENT-CC92
memory type=RAM content=Save
map address=70-7d,f0-ff:0000-7fff mask=0x8000
processor manufacturer=NEC architecture=uPD78214
identifier: Campus Challenge '92
map address=c0,e0:0000
mcu
map address=00-1f,80-9f:8000-ffff
memory type=ROM content=Program
memory type=ROM content=Level-1
memory type=ROM content=Level-2
memory type=ROM content=Level-3
dip
processor manufacturer=NEC architecture=uPD7725
map address=20-3f,a0-bf:8000-ffff mask=0x7fff
memory type=ROM content=Program architecture=uPD7725
memory type=ROM content=Data architecture=uPD7725
memory type=RAM content=Data architecture=uPD7725
oscillator
board: EVENT-PF94
memory type=RAM content=Save
map address=30-3f,b0-bf:6000-7fff mask=0xe000
processor manufacturer=NEC architecture=uPD78214
identifier: PowerFest '94
map address=10,20:6000
mcu
map address=00-3f,80-bf:8000-ffff
map address=c0-ff:0000-ffff
memory type=ROM content=Program
memory type=ROM content=Level-1
memory type=ROM content=Level-2
memory type=ROM content=Level-3
dip
processor manufacturer=NEC architecture=uPD7725
map address=00-0f,80-8f:6000-7fff mask=0xfff
memory type=ROM content=Program architecture=uPD7725
memory type=ROM content=Data architecture=uPD7725
memory type=RAM content=Data architecture=uPD7725
oscillator
board: EXHIROM
memory type=ROM content=Program
map address=00-3f:8000-ffff base=0x400000
map address=40-7d:0000-ffff base=0x400000
map address=80-bf:8000-ffff mask=0xc00000
map address=c0-ff:0000-ffff mask=0xc00000
board: EXHIROM-RAM
memory type=ROM content=Program
map address=00-3f:8000-ffff base=0x400000
map address=40-7d:0000-ffff base=0x400000
map address=80-bf:8000-ffff mask=0xc00000
map address=c0-ff:0000-ffff mask=0xc00000
memory type=RAM content=Save
map address=20-3f,a0-bf:6000-7fff mask=0xe000
board: EXHIROM-RAM-SHARPRTC
memory type=ROM content=Program
map address=00-3f:8000-ffff base=0x400000
map address=40-7d:0000-ffff base=0x400000
map address=80-bf:8000-ffff mask=0xc00000
map address=c0-ff:0000-ffff mask=0xc00000
memory type=RAM content=Save
map address=20-3f,a0-bf:6000-7fff mask=0xe000
rtc manufacturer=Sharp
map address=00-3f,80-bf:2800-2801
memory type=RTC content=Time manufacturer=Sharp
board: EXLOROM
memory type=ROM content=Program
map address=00-7d:8000-ffff mask=0x808000 base=0x400000
map address=80-ff:8000-ffff mask=0x808000 base=0x000000
board: EXLOROM-RAM
memory type=ROM content=Program
map address=00-7d:8000-ffff mask=0x808000 base=0x400000
map address=80-ff:8000-ffff mask=0x808000 base=0x000000
memory type=RAM content=Save
map address=70-7d,f0-ff:0000-7fff mask=0x8000
board: EXNEC-LOROM
memory type=ROM content=Program
map address=00-7d,80-ff:8000-ffff mask=0x8000
processor architecture=uPD96050
map address=60-67,e0-e7:0000-3fff
memory type=ROM content=Program architecture=uPD96050
memory type=ROM content=Data architecture=uPD96050
memory type=RAM content=Data architecture=uPD96050
map address=68-6f,e8-ef:0000-7fff mask=0x8000
oscillator
board: EXSPC7110-RAM-EPSONRTC
memory type=ROM content=Expansion
map address=40-4f:0000-ffff
processor identifier=SPC7110
map address=00-3f,80-bf:4800-483f
map address=50,58:0000-ffff
mcu
map address=00-3f,80-bf:8000-ffff mask=0x800000
map address=c0-ff:0000-ffff mask=0xc00000
memory type=ROM content=Program
memory type=ROM content=Data
memory type=RAM content=Save
map address=00-3f,80-bf:6000-7fff mask=0xe000
rtc manufacturer=Epson
map address=00-3f,80-bf:4840-4842
memory type=RTC content=Time manufacturer=Epson
board: GB-LOROM
memory type=ROM content=Program
map address=00-7d,80-ff:8000-ffff mask=0x8000
map address=40-7d,c0-ff:0000-7fff mask=0x8000
processor identifier=ICD revision=2
map address=00-3f,80-bf:6000-67ff,7000-7fff
memory type=ROM content=Boot architecture=SM83
oscillator
slot type=GameBoy
board: GSU-RAM
processor architecture=GSU
map address=00-3f,80-bf:3000-34ff
memory type=ROM content=Program
map address=00-3f,80-bf:8000-ffff mask=0x8000
map address=40-5f,c0-df:0000-ffff
memory type=RAM content=Save
map address=00-3f,80-bf:6000-7fff size=0x2000
map address=70-71,f0-f1:0000-ffff
board: HIROM
memory type=ROM content=Program
map address=00-3f,80-bf:8000-ffff
map address=40-7d,c0-ff:0000-ffff
board: HIROM-RAM
memory type=ROM content=Program
map address=00-3f,80-bf:8000-ffff
map address=40-7d,c0-ff:0000-ffff
memory type=RAM content=Save
map address=20-3f,a0-bf:6000-7fff mask=0xe000
board: HITACHI-LOROM
processor architecture=HG51BS169
map address=00-3f,80-bf:6c00-6fff,7c00-7fff
memory type=ROM content=Program
map address=00-3f,80-bf:8000-ffff mask=0x8000
memory type=RAM content=Save
map address=70-77:0000-7fff
memory type=ROM content=Data architecture=HG51BS169
memory type=RAM content=Data architecture=HG51BS169
map address=00-3f,80-bf:6000-6bff,7000-7bff mask=0xf000
oscillator
board: LOROM
memory type=ROM content=Program
map address=00-7d,80-ff:8000-ffff mask=0x8000
board: LOROM-RAM
memory type=ROM content=Program
map address=00-7d,80-ff:8000-ffff mask=0x8000
memory type=RAM content=Save
map address=70-7d,f0-ff:0000-7fff mask=0x8000
board: LOROM-RAM#A
memory type=ROM content=Program
map address=00-3f,80-bf:8000-ffff mask=0x8000
memory type=RAM content=Save
map address=70-7d,f0-ff:0000-ffff mask=0x8000
board: NEC-HIROM
memory type=ROM content=Program
map address=00-3f,80-bf:8000-ffff
map address=40-7d,c0-ff:0000-ffff
processor architecture=uPD7725
map address=00-1f,80-9f:6000-7fff mask=0xfff
memory type=ROM content=Program architecture=uPD7725
memory type=ROM content=Data architecture=uPD7725
memory type=RAM content=Data architecture=uPD7725
oscillator
board: NEC-HIROM-RAM
memory type=ROM content=Program
map address=00-3f,80-bf:8000-ffff
map address=40-7d,c0-ff:0000-ffff
memory type=RAM content=Save
map address=20-3f,a0-bf:6000-7fff mask=0xe000
processor architecture=uPD7725
map address=00-1f,80-9f:6000-7fff mask=0xfff
memory type=ROM content=Program architecture=uPD7725
memory type=ROM content=Data architecture=uPD7725
memory type=RAM content=Data architecture=uPD7725
oscillator
board: NEC-LOROM
memory type=ROM content=Program
map address=00-1f,80-9f:8000-ffff mask=0x8000
processor architecture=uPD7725
map address=30-3f,b0-bf:8000-ffff mask=0x3fff
memory type=ROM content=Program architecture=uPD7725
memory type=ROM content=Data architecture=uPD7725
memory type=RAM content=Data architecture=uPD7725
oscillator
board: NEC-LOROM-RAM
memory type=ROM content=Program
map address=00-3f,80-bf:8000-ffff mask=0x8000
memory type=RAM content=Save
map address=70-7d,f0-ff:0000-7fff mask=0x8000
processor architecture=uPD7725
map address=60-6f,e0-ef:0000-7fff mask=0x3fff
memory type=ROM content=Program architecture=uPD7725
memory type=ROM content=Data architecture=uPD7725
memory type=RAM content=Data architecture=uPD7725
oscillator
board: NEC-LOROM-RAM#A
memory type=ROM content=Program
map address=00-1f,80-9f:8000-ffff mask=0x8000
memory type=RAM content=Save
map address=70-7d,f0-ff:0000-ffff
processor architecture=uPD7725
map address=20-3f,a0-bf:8000-ffff mask=0x3fff
memory type=ROM content=Program architecture=uPD7725
memory type=ROM content=Data architecture=uPD7725
memory type=RAM content=Data architecture=uPD7725
oscillator
board: OBC1-LOROM-RAM
memory type=ROM content=Program
map address=00-3f,80-bf:8000-ffff mask=0x8000
processor identifier=OBC1
map address=00-3f,80-bf:6000-7fff mask=0xe000
map address=70-71,f0-f1:6000-7fff,e000-ffff mask=0xe000
memory type=RAM content=Save
board: SA1
processor architecture=W65C816S
map address=00-3f,80-bf:2200-23ff
mcu
map address=00-3f,80-bf:8000-ffff mask=0x408000
map address=c0-ff:0000-ffff
memory type=ROM content=Program
memory type=RAM content=Internal
map address=00-3f,80-bf:3000-37ff size=0x800
board: SA1-RAM
processor architecture=W65C816S
map address=00-3f,80-bf:2200-23ff
mcu
map address=00-3f,80-bf:8000-ffff mask=0x408000
map address=c0-ff:0000-ffff
memory type=ROM content=Program
memory type=RAM content=Save
map address=00-3f,80-bf:6000-7fff size=0x2000
map address=40-4f:0000-ffff
memory type=RAM content=Internal
map address=00-3f,80-bf:3000-37ff size=0x800
board: SDD1
processor identifier=SDD1
map address=00-3f,80-bf:4800-480f
mcu
map address=00-3f,80-bf:8000-ffff
map address=c0-ff:0000-ffff
memory type=ROM content=Program
board: SDD1-RAM
memory type=RAM content=Save
map address=00-3f,80-bf:6000-7fff mask=0xe000
map address=70-73:0000-ffff mask=0x8000
processor identifier=SDD1
map address=00-3f,80-bf:4800-480f
mcu
map address=00-3f,80-bf:8000-ffff
map address=c0-ff:0000-ffff
memory type=ROM content=Program
board: SPC7110-RAM
processor identifier=SPC7110
map address=00-3f,80-bf:4800-483f
map address=50,58:0000-ffff
mcu
map address=00-3f,80-bf:8000-ffff mask=0x800000
map address=c0-ff:0000-ffff mask=0xc00000
memory type=ROM content=Program
memory type=ROM content=Data
memory type=RAM content=Save
map address=00-3f,80-bf:6000-7fff mask=0xe000
board: SPC7110-RAM-EPSONRTC
processor identifier=SPC7110
map address=00-3f,80-bf:4800-483f
map address=50,58:0000-ffff
mcu
map address=00-3f,80-bf:8000-ffff mask=0x800000
map address=c0-ff:0000-ffff mask=0xc00000
memory type=ROM content=Program
memory type=ROM content=Data
memory type=RAM content=Save
map address=00-3f,80-bf:6000-7fff mask=0xe000
rtc manufacturer=Epson
map address=00-3f,80-bf:4840-4842
memory type=RTC content=Time manufacturer=Epson
board: ST-LOROM
memory type=ROM content=Program
map address=00-1f,80-9f:8000-ffff mask=0x8000
slot type=SufamiTurbo
rom
map address=20-3f,a0-bf:8000-ffff mask=0x8000
ram
map address=60-6f,e0-ef:0000-ffff
slot type=SufamiTurbo
rom
map address=40-5f,c0-df:0000-ffff mask=0x8000
ram
map address=70-7d,f0-ff:0000-ffff
Binary file not shown.
Whitespace-only changes.
Binary file not shown.
Binary file not shown.
Binary file not shown.
-11
View File
@@ -1,11 +0,0 @@
#include <ares/ares.hpp>
#include <ares/debug/debug.cpp>
#include <ares/node/node.cpp>
#include <ares/resource/resource.cpp>
namespace ares {
Platform* platform = nullptr;
bool _runAhead = false;
}
-79
View File
@@ -1,79 +0,0 @@
#pragma once
#include <libco/libco.h>
#include <nall/platform.hpp>
#include <nall/adaptive-array.hpp>
#include <nall/any.hpp>
#include <nall/array.hpp>
#include <nall/bump-allocator.hpp>
#include <nall/chrono.hpp>
#include <nall/directory.hpp>
#include <nall/dl.hpp>
#include <nall/endian.hpp>
#include <nall/image.hpp>
#include <nall/literals.hpp>
#include <nall/priority-queue.hpp>
#include <nall/queue.hpp>
#include <nall/random.hpp>
#include <nall/serializer.hpp>
#include <nall/set.hpp>
#include <nall/shared-pointer.hpp>
#include <nall/string.hpp>
#include <nall/terminal.hpp>
#include <nall/thread.hpp>
#include <nall/traits.hpp>
#include <nall/unique-pointer.hpp>
#include <nall/variant.hpp>
#include <nall/vector.hpp>
#include <nall/vfs.hpp>
#include <nall/cd.hpp>
#include <nall/dsp/iir/one-pole.hpp>
#include <nall/dsp/iir/biquad.hpp>
#include <nall/dsp/resampler/cubic.hpp>
#include <nall/hash/crc32.hpp>
#include <nall/hash/sha256.hpp>
using namespace nall;
namespace ares {
static const string Name = "ares";
static const string Version = "121";
static const string Copyright = "Near";
static const string License = "ISC";
static const string LicenseURI = "https://opensource.org/licenses/ISC";
static const string Website = "ares.dev";
static const string WebsiteURI = "https://ares.dev";
//incremented only when serialization format changes
static const u32 SerializerSignature = 0x31545342; //"BST1" (little-endian)
static const string SerializerVersion = "121";
namespace VFS {
using Pak = shared_pointer<vfs::directory>;
using File = shared_pointer<vfs::file>;
}
namespace Video {
static constexpr bool Threaded = true;
}
namespace Constants {
namespace Colorburst {
static constexpr f64 NTSC = 315.0 / 88.0 * 1'000'000.0;
static constexpr f64 PAL = 283.75 * 15'625.0 + 25.0;
}
}
extern bool _runAhead;
inline auto runAhead() -> bool { return _runAhead; }
inline auto setRunAhead(bool runAhead) -> void { _runAhead = runAhead; }
}
#include <ares/types.hpp>
#include <ares/random.hpp>
#include <ares/debug/debug.hpp>
#include <ares/node/node.hpp>
#include <ares/platform.hpp>
#include <ares/memory/readable.hpp>
#include <ares/memory/writable.hpp>
#include <ares/resource/resource.hpp>
-45
View File
@@ -1,45 +0,0 @@
namespace ares {
Debug _debug;
auto Debug::reset() -> void {
_totalNotices = 0;
_unhandledNotices.reset();
_unimplementedNotices.reset();
_unusualNotices.reset();
_unverifiedNotices.reset();
}
auto Debug::_unhandled(const string& text) -> void {
if(_unhandledNotices.find(text)) return;
if(_totalNotices++ > 256) return;
_unhandledNotices.append(text);
print(terminal::color::yellow("[unhandled] "), text, "\n");
}
auto Debug::_unimplemented(const string& text) -> void {
if(_unimplementedNotices.find(text)) return;
if(_totalNotices++ > 256) return;
_unimplementedNotices.append(text);
print(terminal::color::magenta("[unimplemented] "), text, "\n");
}
auto Debug::_unusual(const string& text) -> void {
if(_unusualNotices.find(text)) return;
if(_totalNotices++ > 256) return;
_unusualNotices.append(text);
print(terminal::color::cyan("[unusual] "), text, "\n");
}
auto Debug::_unverified(const string& text) -> void {
if(_unverifiedNotices.find(text)) return;
if(_totalNotices++ > 256) return;
_unverifiedNotices.append(text);
print(terminal::color::gray("[unverified] "), text, "\n");
}
}
-39
View File
@@ -1,39 +0,0 @@
namespace ares {
struct Debug {
auto reset() -> void;
template<typename... P> auto unhandled(P&&... p) -> void {
return _unhandled({forward<P>(p)...});
}
template<typename... P> auto unimplemented(P&&... p) -> void {
return _unimplemented({forward<P>(p)...});
}
template<typename... P> auto unusual(P&&... p) -> void {
return _unusual({forward<P>(p)...});
}
template<typename... P> auto unverified(P&&... p) -> void {
return _unverified({forward<P>(p)...});
}
private:
auto _unhandled(const string&) -> void;
auto _unimplemented(const string&) -> void;
auto _unusual(const string&) -> void;
auto _unverified(const string&) -> void;
u64 _totalNotices = 0;
vector<string> _unhandledNotices;
vector<string> _unimplementedNotices;
vector<string> _unusualNotices;
vector<string> _unverifiedNotices;
};
extern Debug _debug;
}
#define debug(function, ...) if constexpr(1) ares::_debug.function(__VA_ARGS__)
-4
View File
@@ -1,4 +0,0 @@
#include <ares/scheduler/thread.hpp>
#include <ares/scheduler/scheduler.hpp>
#include <ares/scheduler/thread.cpp>
#include <ares/scheduler/scheduler.cpp>
-30
View File
@@ -1,30 +0,0 @@
#pragma once
namespace ares::Memory {
inline auto mirror(u32 address, u32 size) -> u32 {
if(size == 0) return 0;
u32 base = 0;
u32 mask = 1 << 31;
while(address >= size) {
while(!(address & mask)) mask >>= 1;
address -= mask;
if(size > mask) {
size -= mask;
base += mask;
}
mask >>= 1;
}
return base + address;
}
inline auto reduce(u32 address, u32 mask) -> u32 {
while(mask) {
u32 bits = (mask & -mask) - 1;
address = address >> 1 & ~bits | address & bits;
mask = (mask & mask - 1) >> 1;
}
return address;
}
}
-73
View File
@@ -1,73 +0,0 @@
#pragma once
#include <ares/memory/memory.hpp>
namespace ares::Memory {
template<typename T>
struct Readable {
~Readable() { reset(); }
auto reset() -> void {
delete[] self.data;
self.data = nullptr;
self.size = 0;
self.mask = 0;
}
auto allocate(u32 size, T fill = (T)~0ull) -> void {
if(!size) return reset();
delete[] self.data;
self.size = size;
self.mask = bit::round(self.size) - 1;
self.data = new T[self.mask + 1];
memory::fill<T>(self.data, self.mask + 1, fill);
}
auto fill(T fill = ~0ull) -> void {
for(u32 address : range(self.size)) {
self.data[address] = fill;
}
}
auto load(VFS::File fp) -> void {
if(!self.size) allocate(fp->size());
fp->read({self.data, min(fp->size(), self.size * sizeof(T))});
for(u32 address = self.size; address <= self.mask; address++) {
self.data[address] = self.data[mirror(address, self.size)];
}
}
auto save(VFS::File fp) -> void {
fp->write({self.data, min(fp->size(), self.size * sizeof(T))});
}
explicit operator bool() const { return (bool)self.data; }
auto data() const -> const T* { return self.data; }
auto size() const -> u32 { return self.size; }
auto mask() const -> u32 { return self.mask; }
auto operator[](u32 address) const -> T { return self.data[address & self.mask]; }
auto read(u32 address) const -> T { return self.data[address & self.mask]; }
auto write(u32 address, T data) const -> void {}
auto program(u32 address, T data) const -> void { self.data[address & self.mask] = data; }
auto begin() -> T* { return &self.data[0]; }
auto end() -> T* { return &self.data[self.size]; }
auto begin() const -> const T* { return &self.data[0]; }
auto end() const -> const T* { return &self.data[self.size]; }
auto serialize(serializer& s) -> void {
s(array_span<T>{self.data, self.size});
}
//private:
struct {
T* data = nullptr;
u32 size = 0;
u32 mask = 0;
} self;
};
}
-75
View File
@@ -1,75 +0,0 @@
#pragma once
#include <ares/memory/memory.hpp>
namespace ares::Memory {
template<typename T>
struct Writable {
~Writable() { reset(); }
auto reset() -> void {
delete[] self.data;
self.data = nullptr;
self.size = 0;
self.mask = 0;
}
auto allocate(u32 size, T fill = (T)~0ull) -> void {
if(!size) return reset();
delete[] self.data;
self.size = size;
self.mask = bit::round(self.size) - 1;
self.data = new T[self.mask + 1];
memory::fill<T>(self.data, self.mask + 1, fill);
}
auto fill(T fill = ~0ull) -> void {
for(u32 address : range(self.size)) {
self.data[address] = fill;
}
}
auto load(VFS::File fp) -> void {
if(!self.size) allocate(fp->size());
fp->read({self.data, min(fp->size(), self.size * sizeof(T))});
for(u32 address = self.size; address <= self.mask; address++) {
self.data[address] = self.data[mirror(address, self.size)];
}
}
auto save(VFS::File fp) -> void {
fp->write({self.data, min(fp->size(), self.size * sizeof(T))});
}
explicit operator bool() const { return (bool)self.data; }
auto data() -> T* { return self.data; }
auto data() const -> const T* { return self.data; }
auto size() const -> u32 { return self.size; }
auto mask() const -> u32 { return self.mask; }
auto operator[](u32 address) -> T& { return self.data[address & self.mask]; }
auto operator[](u32 address) const -> T { return self.data[address & self.mask]; }
auto read(u32 address) const -> T { return self.data[address & self.mask]; }
auto write(u32 address, T data) -> void { self.data[address & self.mask] = data; }
auto program(u32 address, T data) -> void { self.data[address & self.mask] = data; }
auto begin() -> T* { return &self.data[0]; }
auto end() -> T* { return &self.data[self.size]; }
auto begin() const -> const T* { return &self.data[0]; }
auto end() const -> const T* { return &self.data[self.size]; }
auto serialize(serializer& s) -> void {
s(array_span<T>{self.data, self.size});
}
private:
struct {
T* data = nullptr;
u32 size = 0;
u32 mask = 0;
} self;
};
}
-8
View File
@@ -1,8 +0,0 @@
struct Attribute {
Attribute(const string& name, const any& value = {}) : name(name), value(value) {}
auto operator==(const Attribute& source) const -> bool { return name == source.name; }
auto operator< (const Attribute& source) const -> bool { return name < source.name; }
string name;
any value;
};
-4
View File
@@ -1,4 +0,0 @@
struct Audio : Object {
DeclareClass(Audio, "audio")
using Object::Object;
};
-131
View File
@@ -1,131 +0,0 @@
auto Stream::setChannels(u32 channels) -> void {
_channels.reset();
_channels.resize(channels);
}
auto Stream::setFrequency(f64 frequency) -> void {
_frequency = frequency;
setResamplerFrequency(_resamplerFrequency);
}
auto Stream::setResamplerFrequency(f64 resamplerFrequency) -> void {
_resamplerFrequency = resamplerFrequency;
for(auto& channel : _channels) {
channel.nyquist.reset();
channel.resampler.reset(_frequency, _resamplerFrequency);
}
if(_frequency >= _resamplerFrequency * 2) {
//add a low-pass filter to prevent aliasing during resampling
f64 cutoffFrequency = min(25000.0, _resamplerFrequency / 2.0 - 2000.0);
for(auto& channel : _channels) {
u32 passes = 3;
for(u32 pass : range(passes)) {
DSP::IIR::Biquad filter;
f64 q = DSP::IIR::Biquad::butterworth(passes * 2, pass);
filter.reset(DSP::IIR::Biquad::Type::LowPass, cutoffFrequency, _frequency, q);
channel.nyquist.append(filter);
}
}
}
}
auto Stream::setMuted(bool muted) -> void {
_muted = muted;
}
auto Stream::resetFilters() -> void {
for(auto& channel : _channels) {
channel.filters.reset();
}
}
auto Stream::addLowPassFilter(f64 cutoffFrequency, u32 order, u32 passes) -> void {
for(auto& channel : _channels) {
for(u32 pass : range(passes)) {
if(order == 1) {
Filter filter{Filter::Mode::OnePole, Filter::Type::LowPass, Filter::Order::First};
filter.onePole.reset(DSP::IIR::OnePole::Type::LowPass, cutoffFrequency, _frequency);
channel.filters.append(filter);
}
if(order == 2) {
Filter filter{Filter::Mode::Biquad, Filter::Type::LowPass, Filter::Order::Second};
f64 q = DSP::IIR::Biquad::butterworth(passes * 2, pass);
filter.biquad.reset(DSP::IIR::Biquad::Type::LowPass, cutoffFrequency, _frequency, q);
channel.filters.append(filter);
}
}
}
}
auto Stream::addHighPassFilter(f64 cutoffFrequency, u32 order, u32 passes) -> void {
for(auto& channel : _channels) {
for(u32 pass : range(passes)) {
if(order == 1) {
Filter filter{Filter::Mode::OnePole, Filter::Type::HighPass, Filter::Order::First};
filter.onePole.reset(DSP::IIR::OnePole::Type::HighPass, cutoffFrequency, _frequency);
channel.filters.append(filter);
}
if(order == 2) {
Filter filter{Filter::Mode::Biquad, Filter::Type::HighPass, Filter::Order::Second};
f64 q = DSP::IIR::Biquad::butterworth(passes * 2, pass);
filter.biquad.reset(DSP::IIR::Biquad::Type::HighPass, cutoffFrequency, _frequency, q);
channel.filters.append(filter);
}
}
}
}
auto Stream::addLowShelfFilter(f64 cutoffFrequency, u32 order, f64 gain, f64 slope) -> void {
for(auto& channel : _channels) {
if(order == 2) {
Filter filter{Filter::Mode::Biquad, Filter::Type::LowShelf, Filter::Order::Second};
f64 q = DSP::IIR::Biquad::shelf(gain, slope);
filter.biquad.reset(DSP::IIR::Biquad::Type::LowShelf, cutoffFrequency, _frequency, q);
channel.filters.append(filter);
}
}
}
auto Stream::addHighShelfFilter(f64 cutoffFrequency, u32 order, f64 gain, f64 slope) -> void {
for(auto& channel : _channels) {
if(order == 2) {
Filter filter{Filter::Mode::Biquad, Filter::Type::HighShelf, Filter::Order::Second};
f64 q = DSP::IIR::Biquad::shelf(gain, slope);
filter.biquad.reset(DSP::IIR::Biquad::Type::HighShelf, cutoffFrequency, _frequency, q);
channel.filters.append(filter);
}
}
}
auto Stream::pending() const -> bool {
return _channels && _channels[0].resampler.pending();
}
auto Stream::read(f64 samples[]) -> u32 {
for(u32 c : range(_channels.size())) {
samples[c] = _channels[c].resampler.read() * !muted();
}
return _channels.size();
}
auto Stream::write(const f64 samples[]) -> void {
for(u32 c : range(_channels.size())) {
f64 sample = samples[c] + 1e-25; //constant offset used to suppress denormals
for(auto& filter : _channels[c].filters) {
switch(filter.mode) {
case Filter::Mode::OnePole: sample = filter.onePole.process(sample); break;
case Filter::Mode::Biquad: sample = filter.biquad.process(sample); break;
}
}
for(auto& filter : _channels[c].nyquist) {
sample = filter.process(sample);
}
_channels[c].resampler.write(sample);
}
//if there are samples pending, then alert the frontend to possibly process them.
//this will generally happen when every audio stream has pending samples to be mixed.
if(pending()) platform->audio(shared());
}
-49
View File
@@ -1,49 +0,0 @@
struct Stream : Audio {
DeclareClass(Stream, "audio.stream")
using Audio::Audio;
auto channels() const -> u32 { return _channels.size(); }
auto frequency() const -> f64 { return _frequency; }
auto resamplerFrequency() const -> f64 { return _resamplerFrequency; }
auto muted() const -> bool { return _muted; }
auto setChannels(u32 channels) -> void;
auto setFrequency(f64 frequency) -> void;
auto setResamplerFrequency(f64 resamplerFrequency) -> void;
auto setMuted(bool muted) -> void;
auto resetFilters() -> void;
auto addLowPassFilter(f64 cutoffFrequency, u32 order, u32 passes = 1) -> void;
auto addHighPassFilter(f64 cutoffFrequency, u32 order, u32 passes = 1) -> void;
auto addLowShelfFilter(f64 cutoffFrequency, u32 order, f64 gain, f64 slope) -> void;
auto addHighShelfFilter(f64 cutoffFrequency, u32 order, f64 gain, f64 slope) -> void;
auto pending() const -> bool;
auto read(f64 samples[]) -> u32;
auto write(const f64 samples[]) -> void;
template<typename... P>
auto frame(P&&... p) -> void {
if(runAhead()) return;
f64 samples[sizeof...(p)] = {forward<P>(p)...};
write(samples);
}
protected:
struct Filter {
enum class Mode : u32 { OnePole, Biquad } mode;
enum class Type : u32 { None, LowPass, HighPass, LowShelf, HighShelf } type;
enum class Order : u32 { None, First, Second } order;
DSP::IIR::OnePole onePole;
DSP::IIR::Biquad biquad;
};
struct Channel {
vector<Filter> filters;
vector<DSP::IIR::Biquad> nyquist;
DSP::Resampler::Cubic resampler;
};
vector<Channel> _channels;
f64 _frequency = 48000.0;
f64 _resamplerFrequency = 48000.0;
bool _muted = false;
};
-34
View File
@@ -1,34 +0,0 @@
//horrible implementation of run-time introspection:
//allow converting a unique class string to a derived Node type.
struct Class {
struct Instance {
const string identifier;
const function<Node::Object ()> create;
};
static auto classes() -> vector<Instance>& {
static vector<Instance> classes;
return classes;
}
template<typename T> static auto register() -> void {
if(!classes().find([&](auto instance) { return instance.identifier == T::identifier; })) {
classes().append({T::identifier, &T::create});
} else {
throw;
}
}
static auto create(string identifier) -> Node::Object {
if(auto index = classes().find([&](auto instance) { return instance.identifier == identifier; })) {
return classes()[*index].create();
}
if(identifier == "Object") throw; //should never occur: detects unregistered classes
return create("Object");
}
template<typename T> struct Register {
Register() { Class::register<T>(); }
};
};
-4
View File
@@ -1,4 +0,0 @@
struct Component : Object {
DeclareClass(Component, "component");
using Object::Object;
};
@@ -1,30 +0,0 @@
struct RealTimeClock : Component {
DeclareClass(RealTimeClock, "component.real-time-clock")
using Component::Component;
auto update() -> void { if(_update) return _update(); }
auto timestamp() const -> u64 { return _timestamp; }
auto setUpdate(function<void ()> update) -> void { _update = update; }
auto setTimestamp(u64 timestamp) -> void { _timestamp = timestamp; }
auto synchronize(u64 timestamp = 0) -> void {
if(!timestamp) timestamp = chrono::timestamp();
_timestamp = timestamp;
update();
}
auto serialize(string& output, string depth) -> void override {
Component::serialize(output, depth);
output.append(depth, " timestamp: ", _timestamp, "\n");
}
auto unserialize(Markup::Node node) -> void override {
Component::unserialize(node);
_timestamp = node["timestamp"].natural();
}
protected:
function<void ()> _update;
u64 _timestamp;
};
-4
View File
@@ -1,4 +0,0 @@
struct Debugger : Object {
DeclareClass(Debugger, "debugger")
using Object::Object;
};
-26
View File
@@ -1,26 +0,0 @@
struct Graphics : Debugger {
DeclareClass(Graphics, "debugger.graphics")
Graphics(string name = {}) : Debugger(name) {
}
auto width() const -> u32 { return _width; }
auto height() const -> u32 { return _height; }
auto capture() const -> vector<u32> { if(_capture) return _capture(); return {}; }
auto setSize(u32 width, u32 height) -> void { _width = width, _height = height; }
auto setCapture(function<vector<u32> ()> capture) -> void { _capture = capture; }
auto serialize(string& output, string depth) -> void override {
Debugger::serialize(output, depth);
}
auto unserialize(Markup::Node node) -> void override {
Debugger::unserialize(node);
}
protected:
u32 _width = 0;
u32 _height = 0;
function<vector<u32> ()> _capture;
};
-27
View File
@@ -1,27 +0,0 @@
struct Memory : Debugger {
DeclareClass(Memory, "debugger.memory")
Memory(string name = {}) : Debugger(name) {
}
auto size() const -> u32 { return _size; }
auto read(u32 address) const -> n8 { if(_read) return _read(address); return 0; }
auto write(u32 address, u8 data) const -> void { if(_write) return _write(address, data); }
auto setSize(u32 size) -> void { _size = size; }
auto setRead(function<u8 (u32)> read) -> void { _read = read; }
auto setWrite(function<void (u32, u8)> write) -> void { _write = write; }
auto serialize(string& output, string depth) -> void override {
Debugger::serialize(output, depth);
}
auto unserialize(Markup::Node node) -> void override {
Debugger::unserialize(node);
}
protected:
u32 _size = 0;
function<u8 (u32)> _read;
function<void (u32, u8)> _write;
};
-21
View File
@@ -1,21 +0,0 @@
struct Properties : Debugger {
DeclareClass(Properties, "debugger.properties")
Properties(string name = {}) : Debugger(name) {
}
auto query() const -> string { if(_query) return _query(); return {}; }
auto setQuery(function<string ()> query) -> void { _query = query; }
auto serialize(string& output, string depth) -> void override {
Debugger::serialize(output, depth);
}
auto unserialize(Markup::Node node) -> void override {
Debugger::unserialize(node);
}
protected:
function<string ()> _query;
};
@@ -1,125 +0,0 @@
struct Instruction : Tracer {
DeclareClass(Instruction, "debugger.tracer.instruction")
Instruction(string name = {}, string component = {}) : Tracer(name, component) {
setMask(_mask);
setDepth(_depth);
}
auto addressBits() const -> u32 { return _addressBits; }
auto addressMask() const -> u32 { return _addressMask; }
auto mask() const -> bool { return _mask; }
auto depth() const -> u32 { return _depth; }
auto setAddressBits(u32 addressBits, u32 addressMask = 0) -> void {
_addressBits = addressBits;
_addressMask = addressMask;
}
auto setMask(bool mask) -> void {
_mask = mask;
}
auto setDepth(u32 depth) -> void {
_depth = depth;
_history.reset();
_history.resize(depth);
for(auto& history : _history) history = ~0;
}
auto address(u32 address) -> bool {
address &= (1u << _addressBits) - 1; //mask upper bits of address
_address = address;
address >>= _addressMask; //clip unneeded alignment bits (to reduce _masks size)
if(_mask && updateMasks()) {
if(_masks[address >> 3] & 1 << (address & 7)) return false; //do not trace twice
_masks[address >> 3] |= 1 << (address & 7);
}
if(_depth) {
for(auto history : _history) {
if(_address == history) {
_omitted++;
return false; //do not trace again if recently traced
}
}
for(auto index : range(_depth - 1)) {
_history[index] = _history[index + 1];
}
_history.last() = _address;
}
return true;
}
//mark an already-executed address as not executed yet for trace masking.
//call when writing to executable RAM to support self-modifying code.
auto invalidate(u32 address) -> void {
if(unlikely(_mask && updateMasks())) {
address &= (1u << _addressBits) - 1;
address >>= _addressMask;
_masks[address >> 3] &= ~(1 << (address & 7));
}
}
auto notify(const string& instruction, const string& context, const string& extra = {}) -> void {
if(!enabled()) return;
if(_omitted) {
PlatformLog({
"[Omitted: ", _omitted, "]\n"}
);
_omitted = 0;
}
string output{
_component, " ",
hex(_address, _addressBits + 3 >> 2), " ",
instruction, " ",
context, " ",
extra
};
PlatformLog({output.strip(), "\n"});
}
auto serialize(string& output, string depth) -> void override {
Tracer::serialize(output, depth);
output.append(depth, " addressBits: ", _addressBits, "\n");
output.append(depth, " addressMask: ", _addressMask, "\n");
output.append(depth, " mask: ", _mask, "\n");
output.append(depth, " depth: ", _depth, "\n");
}
auto unserialize(Markup::Node node) -> void override {
Tracer::unserialize(node);
_addressBits = node["addressBits"].natural();
_addressMask = node["addressMask"].natural();
_mask = node["mask"].boolean();
_depth = node["depth"].natural();
setMask(_mask);
setDepth(_depth);
}
protected:
auto updateMasks() -> bool {
auto size = 1ull << _addressBits >> _addressMask >> 3;
if(!_mask || !size) return _masks.reset(), false;
if(_masks.size() == size) return true;
_masks.reset();
_masks.resize(size);
return true;
}
u32 _addressBits = 32;
u32 _addressMask = 0;
bool _mask = false;
u32 _depth = 4;
//unserialized:
n64 _address = 0;
n64 _omitted = 0;
vector<u32> _history;
vector<u08> _masks;
};
@@ -1,18 +0,0 @@
struct Notification : Tracer {
DeclareClass(Notification, "debugger.tracer.notification")
Notification(string name = {}, string component = {}) : Tracer(name, component) {
}
auto notify(const string& message = {}) -> void {
if(!enabled()) return;
if(message) {
PlatformLog({_component, " ", _name, ": ", message, "\n"});
} else {
PlatformLog({_component, " ", _name, "\n"});
}
}
protected:
};
-29
View File
@@ -1,29 +0,0 @@
struct Tracer : Debugger {
DeclareClass(Tracer, "debugger.tracer")
Tracer(string name = {}, string component = {}) : Debugger(name) {
_component = component;
}
auto component() const -> string { return _component; }
auto enabled() const -> bool { return _enabled; }
auto setComponent(string component) -> void { _component = component; }
auto setEnabled(bool enabled) -> void { _enabled = enabled; }
auto serialize(string& output, string depth) -> void override {
Debugger::serialize(output, depth);
output.append(depth, " component: ", _component, "\n");
output.append(depth, " enabled: ", _enabled, "\n");
}
auto unserialize(Markup::Node node) -> void override {
Debugger::unserialize(node);
_component = node["component"].string();
_enabled = node["enabled"].boolean();
}
protected:
string _component;
bool _enabled = false;
};
-12
View File
@@ -1,12 +0,0 @@
struct Axis : Input {
DeclareClass(Axis, "input.axis")
using Input::Input;
auto value() const -> s64 { return _value; }
auto setValue(s64 value) -> void { _value = value; }
protected:
s64 _value = 0;
s64 _minimum = -32768;
s64 _maximum = +32767;
};
-10
View File
@@ -1,10 +0,0 @@
struct Button : Input {
DeclareClass(Button, "input.button")
using Input::Input;
auto value() const -> bool { return _value; }
auto setValue(bool value) -> void { _value = value; }
protected:
bool _value = 0;
};
-4
View File
@@ -1,4 +0,0 @@
struct Input : Object {
DeclareClass(Input, "input")
using Object::Object;
};
-10
View File
@@ -1,10 +0,0 @@
struct Rumble : Input {
DeclareClass(Rumble, "input.rumble")
using Input::Input;
auto enable() const -> bool { return _enable; }
auto setEnable(bool enable) -> void { _enable = enable; }
protected:
bool _enable = 0;
};
-12
View File
@@ -1,12 +0,0 @@
struct Trigger : Input {
DeclareClass(Trigger, "input.trigger")
using Input::Input;
auto value() const -> s64 { return _value; }
auto setValue(s64 value) -> void { _value = value; }
protected:
s64 _value = 0;
s64 _minimum = 0;
s64 _maximum = +32767;
};
-9
View File
@@ -1,9 +0,0 @@
namespace ares::Core {
namespace Video {
#include <ares/node/video/sprite.cpp>
#include <ares/node/video/screen.cpp>
}
namespace Audio {
#include <ares/node/audio/stream.cpp>
}
}
-185
View File
@@ -1,185 +0,0 @@
namespace ares::Core {
struct Object;
struct System;
struct Peripheral;
struct Port;
namespace Component {
struct Component;
struct RealTimeClock;
}
namespace Video {
struct Video;
struct Sprite;
struct Screen;
}
namespace Audio {
struct Audio;
struct Stream;
}
namespace Input {
struct Input;
struct Button;
struct Axis;
struct Trigger;
struct Rumble;
}
namespace Setting {
struct Setting;
struct Boolean;
struct Natural;
struct Integer;
struct Real;
struct String;
}
namespace Debugger {
struct Debugger;
struct Memory;
struct Graphics;
struct Properties;
namespace Tracer {
struct Tracer;
struct Notification;
struct Instruction;
}
}
}
namespace ares::Node {
using Object = shared_pointer<Core::Object>;
using System = shared_pointer<Core::System>;
using Peripheral = shared_pointer<Core::Peripheral>;
using Port = shared_pointer<Core::Port>;
namespace Component {
using Component = shared_pointer<Core::Component::Component>;
using RealTimeClock = shared_pointer<Core::Component::RealTimeClock>;
}
namespace Video {
using Video = shared_pointer<Core::Video::Video>;
using Sprite = shared_pointer<Core::Video::Sprite>;
using Screen = shared_pointer<Core::Video::Screen>;
}
namespace Audio {
using Audio = shared_pointer<Core::Audio::Audio>;
using Stream = shared_pointer<Core::Audio::Stream>;
}
namespace Input {
using Input = shared_pointer<Core::Input::Input>;
using Button = shared_pointer<Core::Input::Button>;
using Axis = shared_pointer<Core::Input::Axis>;
using Trigger = shared_pointer<Core::Input::Trigger>;
using Rumble = shared_pointer<Core::Input::Rumble>;
}
namespace Setting {
using Setting = shared_pointer<Core::Setting::Setting>;
using Boolean = shared_pointer<Core::Setting::Boolean>;
using Natural = shared_pointer<Core::Setting::Natural>;
using Integer = shared_pointer<Core::Setting::Integer>;
using Real = shared_pointer<Core::Setting::Real>;
using String = shared_pointer<Core::Setting::String>;
}
namespace Debugger {
using Debugger = shared_pointer<Core::Debugger::Debugger>;
using Memory = shared_pointer<Core::Debugger::Memory>;
using Graphics = shared_pointer<Core::Debugger::Graphics>;
using Properties = shared_pointer<Core::Debugger::Properties>;
namespace Tracer {
using Tracer = shared_pointer<Core::Debugger::Tracer::Tracer>;
using Notification = shared_pointer<Core::Debugger::Tracer::Notification>;
using Instruction = shared_pointer<Core::Debugger::Tracer::Instruction>;
}
}
}
namespace ares::Core {
// <ares/platform.hpp> forward declarations
static auto PlatformAttach(Node::Object) -> void;
static auto PlatformDetach(Node::Object) -> void;
static auto PlatformLog(string_view) -> void;
#include <ares/node/attribute.hpp>
#include <ares/node/class.hpp>
#include <ares/node/object.hpp>
#include <ares/node/system.hpp>
#include <ares/node/peripheral.hpp>
#include <ares/node/port.hpp>
namespace Component {
#include <ares/node/component/component.hpp>
#include <ares/node/component/real-time-clock.hpp>
}
namespace Video {
#include <ares/node/video/video.hpp>
#include <ares/node/video/sprite.hpp>
#include <ares/node/video/screen.hpp>
}
namespace Audio {
#include <ares/node/audio/audio.hpp>
#include <ares/node/audio/stream.hpp>
}
namespace Input {
#include <ares/node/input/input.hpp>
#include <ares/node/input/button.hpp>
#include <ares/node/input/axis.hpp>
#include <ares/node/input/trigger.hpp>
#include <ares/node/input/rumble.hpp>
}
namespace Setting {
#include <ares/node/setting/setting.hpp>
#include <ares/node/setting/boolean.hpp>
#include <ares/node/setting/natural.hpp>
#include <ares/node/setting/integer.hpp>
#include <ares/node/setting/real.hpp>
#include <ares/node/setting/string.hpp>
}
namespace Debugger {
#include <ares/node/debugger/debugger.hpp>
#include <ares/node/debugger/memory.hpp>
#include <ares/node/debugger/graphics.hpp>
#include <ares/node/debugger/properties.hpp>
namespace Tracer {
#include <ares/node/debugger/tracer/tracer.hpp>
#include <ares/node/debugger/tracer/notification.hpp>
#include <ares/node/debugger/tracer/instruction.hpp>
}
}
}
namespace ares::Node {
static inline auto create(string identifier) -> Object {
return Core::Class::create(identifier);
}
static inline auto serialize(Object node) -> string {
if(!node) return {};
string result;
node->serialize(result, {});
return result;
}
static inline auto unserialize(string markup) -> Object {
auto document = BML::unserialize(markup);
if(!document) return {};
auto node = Core::Class::create(document["node"].string());
node->unserialize(document["node"]);
return node;
}
static inline auto parent(Object child) -> Object {
if(!child || !child->parent()) return {};
if(auto parent = child->parent().acquire()) return parent;
return {};
}
template<typename T>
static inline auto find(Object from, string name) -> Object {
if(!from) return {};
if(auto object = from->find<T>(name)) return object;
return {};
}
template<typename T>
static inline auto enumerate(Object from) -> vector<T> {
vector<T> objects;
if(from) from->enumerate<T>(objects);
return objects;
}
}
-235
View File
@@ -1,235 +0,0 @@
//identifier is static, allowing template<typename T> to access via T::identifier
//identity() is virtual, allowing T* to access via T->identity()
#define DeclareClass(Type, Name) \
static inline const string identifier = Name; \
static auto create() -> Node::Object { return new Type; } \
auto identity() const -> string override { return Name; } \
private: static inline Class::Register<Type> register; public: \
struct Object : shared_pointer_this<Object> {
static inline const string identifier = "Object";
static auto create() -> Node::Object { return new Object; }
virtual auto identity() const -> string { return "Object"; }
private: static inline Class::Register<Object> register; public:
//DeclareClass(Object, "object")
Object(string name = {}) : _name(name) {}
virtual ~Object() = default;
auto name() const -> string { return _name; }
auto parent() const -> shared_pointer_weak<Object> { return _parent; }
auto setName(string_view name) -> void { _name = name; }
auto prepend(Node::Object node) -> Node::Object {
if(auto found = find(node)) return found;
_nodes.prepend(node);
node->_parent = shared();
PlatformAttach(node);
return node;
}
template<typename T, typename... P>
auto prepend(P&&... p) -> Node::Object {
using Type = typename T::type;
return prepend(shared_pointer<Type>::create(forward<P>(p)...));
}
auto append(Node::Object node) -> Node::Object {
if(auto found = find(node)) return found;
_nodes.append(node);
node->_parent = shared();
PlatformAttach(node);
return node;
}
template<typename T, typename... P>
auto append(P&&... p) -> Node::Object {
using Type = typename T::type;
return append(shared_pointer<Type>::create(forward<P>(p)...));
}
auto remove(Node::Object node) -> void {
if(auto index = _nodes.find(node)) {
PlatformDetach(node);
node->reset();
node->_parent.reset();
_nodes.remove(*index);
}
}
auto reset() -> void {
for(auto& node : _nodes) {
PlatformDetach(node);
node->reset();
node->_parent.reset();
}
_nodes.reset();
}
template<typename T>
auto cast() -> shared_pointer<typename T::type> {
if(dynamic_cast<typename T::type*>(this)) return shared();
return {};
}
template<typename T>
auto is() -> bool {
return (bool)cast<T>();
}
template<typename T>
auto find() -> vector<shared_pointer<typename T::type>> {
vector<shared_pointer<typename T::type>> result;
if(dynamic_cast<typename T::type*>(this)) {
if(auto instance = shared()) result.append(instance);
}
for(auto& node : _nodes) result.append(node->find<T>());
return result;
}
template<typename T>
auto find(u32 index) -> shared_pointer<typename T::type> {
auto result = find<T>();
if(index < result.size()) return result[index];
return {};
}
auto find(Node::Object source) -> Node::Object {
if(!source) return {};
for(auto& node : _nodes) {
if(node->identity() == source->identity() && node->_name == source->_name) return node;
}
return {};
}
template<typename T = Node::Object>
auto find(string name) -> T {
using Type = typename T::type;
auto path = name.split("/");
name = path.takeFirst();
for(auto& node : _nodes) {
if(node->_name != name) continue;
if(path) return node->find<T>(path.merge("/"));
if(node->identity() == Type::identifier) return node;
}
return {};
}
template<typename T = Node::Object>
auto scan(string name) -> T {
using Type = typename T::type;
for(auto& node : _nodes) {
if(node->identity() == Type::identifier && node->_name == name) return node;
if(auto result = node->scan<T>(name)) return result;
}
return {};
}
template<typename T>
auto enumerate(vector<T>& objects) -> void {
using Type = typename T::type;
if(auto instance = cast<T>()) objects.append(instance);
for(auto& node : _nodes) node->enumerate<T>(objects);
}
auto pak() -> VFS::Pak {
return _pak;
}
auto setPak(VFS::Pak pak) -> bool {
_pak = pak;
return (bool)_pak;
}
template<typename T = string>
auto attribute(const string& name) const -> T {
if(auto attribute = _attributes.find(name)) {
if(attribute->value.is<T>()) return attribute->value.get<T>();
}
return {};
}
template<typename T = string>
auto hasAttribute(const string& name) const -> bool {
if(auto attribute = _attributes.find(name)) {
if(attribute->value.is<T>()) return true;
}
return false;
}
template<typename T = string, typename U = string>
auto setAttribute(const string& name, const U& value = {}) -> void {
if constexpr(is_same_v<T, string> && !is_same_v<U, string>) return setAttribute(name, string{value});
if(auto attribute = _attributes.find(name)) {
if((const T&)value) attribute->value = (const T&)value;
else _attributes.remove(*attribute);
} else {
if((const T&)value) _attributes.insert({name, (const T&)value});
}
}
virtual auto load(Node::Object source) -> bool {
if(!source || identity() != source->identity() || _name != source->_name) return false;
_attributes = source->_attributes;
return true;
}
auto save() -> string {
string markup;
serialize(markup, {});
return markup;
}
virtual auto serialize(string& output, string depth) -> void {
output.append(depth, "node: ", identity(), "\n");
output.append(depth, " name: ", _name, "\n");
for(auto& attribute : _attributes) {
if(!attribute.value.is<string>()) continue;
output.append(depth, " attribute\n");
output.append(depth, " name: ", attribute.name, "\n");
output.append(depth, " value: ", attribute.value.get<string>(), "\n");
}
depth.append(" ");
for(auto& node : _nodes) {
node->serialize(output, depth);
}
}
virtual auto unserialize(Markup::Node markup) -> void {
if(!markup) return;
_name = markup["name"].string();
_attributes.reset();
for(auto& attribute : markup.find("attribute")) {
_attributes.insert({attribute["name"].string(), attribute["value"].string()});
}
for(auto& leaf : markup.find("node")) {
auto node = Class::create(leaf.string());
append(node);
node->unserialize(leaf);
}
}
virtual auto copy(Node::Object source) -> void {
_attributes = source->_attributes;
for(auto& from : source->_nodes) {
for(auto& to : _nodes) {
if(from->identity() != to->identity()) continue;
if(from->name() != to->name()) continue;
to->copy(from);
break;
}
}
}
auto begin() { return _nodes.begin(); }
auto end() { return _nodes.end(); }
protected:
string _name;
VFS::Pak _pak;
set<Attribute> _attributes;
shared_pointer_weak<Object> _parent;
vector<Node::Object> _nodes;
};
-4
View File
@@ -1,4 +0,0 @@
struct Peripheral : Object {
DeclareClass(Peripheral, "peripheral")
using Object::Object;
};
-74
View File
@@ -1,74 +0,0 @@
struct Port : Object {
DeclareClass(Port, "port")
using Object::Object;
auto type() const -> string { return _type; }
auto family() const -> string { return _family; }
auto hotSwappable() const -> bool { return _hotSwappable; }
auto supported() const -> vector<string> { return _supported; }
auto setAllocate(function<Node::Peripheral (string)> allocate) -> void { _allocate = allocate; }
auto setConnect(function<void ()> connect) -> void { _connect = connect; }
auto setDisconnect(function<void ()> disconnect) -> void { _disconnect = disconnect; }
auto setType(string type) -> void { _type = type; }
auto setFamily(string family) -> void { _family = family; }
auto setHotSwappable(bool hotSwappable) -> void { _hotSwappable = hotSwappable; }
auto setSupported(vector<string> supported) -> void { _supported = supported; }
auto connected() -> Node::Peripheral {
return find<Node::Peripheral>(0);
}
auto allocate(string name = {}) -> Node::Peripheral {
disconnect();
if(_allocate) return _allocate(name);
return {};
}
auto connect() -> void {
if(_connect) _connect();
}
auto disconnect() -> void {
if(auto peripheral = connected()) {
if(_disconnect) _disconnect();
remove(peripheral);
}
}
auto serialize(string& output, string depth) -> void override {
Object::serialize(output, depth);
output.append(depth, " type: ", _type, "\n");
output.append(depth, " family: ", _family, "\n");
output.append(depth, " hotSwappable: ", _hotSwappable, "\n");
}
auto unserialize(Markup::Node node) -> void override {
Object::unserialize(node);
_type = node["type"].string();
_family = node["family"].string();
_hotSwappable = node["hotSwappable"].boolean();
}
auto copy(Node::Object object) -> void override {
if(auto source = object->cast<Node::Port>()) {
Object::copy(source);
if(auto peripheral = source->find<Node::Peripheral>(0)) {
if(auto node = allocate(peripheral->name())) {
node->copy(peripheral);
connect();
node->copy(peripheral);
}
}
}
}
protected:
function<Node::Peripheral (string)> _allocate;
function<void ()> _connect;
function<void ()> _disconnect;
string _type;
string _family;
bool _hotSwappable = false;
vector<string> _supported;
};
-36
View File
@@ -1,36 +0,0 @@
struct Boolean : Setting {
DeclareClass(Boolean, "setting.boolean")
Boolean(string name = {}, bool value = {}, function<void (bool)> modify = {}) : Setting(name) {
_currentValue = value;
_latchedValue = value;
_modify = modify;
}
auto modify(bool value) const -> void { if(_modify) return _modify(value); }
auto value() const -> bool { return _currentValue; }
auto latch() const -> bool { return _latchedValue; }
auto setModify(function<void (bool)> modify) { _modify = modify; }
auto setValue(bool value) -> void {
_currentValue = value;
if(_dynamic) setLatch();
}
auto setLatch() -> void override {
if(_latchedValue == _currentValue) return;
_latchedValue = _currentValue;
modify(_latchedValue);
}
auto readValue() const -> string override { return value(); }
auto readLatch() const -> string override { return latch(); }
auto readAllowedValues() const -> vector<string> override { return {"false", "true"}; }
auto writeValue(string value) -> void override { setValue(value.boolean()); }
protected:
function<void (bool)> _modify;
bool _currentValue = {};
bool _latchedValue = {};
};
-47
View File
@@ -1,47 +0,0 @@
struct Integer : Setting {
DeclareClass(Integer, "setting.integer")
Integer(string name = {}, s64 value = {}, function<void (s64)> modify = {}) : Setting(name) {
_currentValue = value;
_latchedValue = value;
_modify = modify;
}
auto modify(s64 value) const -> void { if(_modify) return _modify(value); }
auto value() const -> s64 { return _currentValue; }
auto latch() const -> s64 { return _latchedValue; }
auto setModify(function<void (s64)> modify) { _modify = modify; }
auto setValue(s64 value) -> void {
if(_allowedValues && !_allowedValues.find(value)) return;
_currentValue = value;
if(_dynamic) setLatch();
}
auto setLatch() -> void override {
if(_latchedValue == _currentValue) return;
_latchedValue = _currentValue;
modify(_latchedValue);
}
auto setAllowedValues(vector<s64> allowedValues) -> void {
_allowedValues = allowedValues;
if(_allowedValues && !_allowedValues.find(_currentValue)) setValue(_allowedValues.first());
}
auto readValue() const -> string override { return value(); }
auto readLatch() const -> string override { return latch(); }
auto readAllowedValues() const -> vector<string> override {
vector<string> values;
for(auto value : _allowedValues) values.append(value);
return values;
}
auto writeValue(string value) -> void override { setValue(value.integer()); }
protected:
function<void (s64)> _modify;
s64 _currentValue = {};
s64 _latchedValue = {};
vector<s64> _allowedValues;
};
-47
View File
@@ -1,47 +0,0 @@
struct Natural : Setting {
DeclareClass(Natural, "setting.natural")
Natural(string name = {}, u64 value = {}, function<void (u64)> modify = {}) : Setting(name) {
_currentValue = value;
_latchedValue = value;
_modify = modify;
}
auto modify(u64 value) const -> void { if(_modify) return _modify(value); }
auto value() const -> u64 { return _currentValue; }
auto latch() const -> u64 { return _latchedValue; }
auto setModify(function<void (u64)> modify) { _modify = modify; }
auto setValue(u64 value) -> void {
if(_allowedValues && !_allowedValues.find(value)) return;
_currentValue = value;
if(_dynamic) setLatch();
}
auto setLatch() -> void override {
if(_latchedValue == _currentValue) return;
_latchedValue = _currentValue;
modify(_latchedValue);
}
auto setAllowedValues(vector<u64> allowedValues) -> void {
_allowedValues = allowedValues;
if(_allowedValues && !_allowedValues.find(_currentValue)) setValue(_allowedValues.first());
}
auto readValue() const -> string override { return value(); }
auto readLatch() const -> string override { return latch(); }
auto readAllowedValues() const -> vector<string> override {
vector<string> values;
for(auto value : _allowedValues) values.append(value);
return values;
}
auto writeValue(string value) -> void override { setValue(value.natural()); }
protected:
function<void (u64)> _modify;
u64 _currentValue = {};
u64 _latchedValue = {};
vector<u64> _allowedValues;
};
-47
View File
@@ -1,47 +0,0 @@
struct Real : Setting {
DeclareClass(Real, "setting.real")
Real(string name = {}, f64 value = {}, function<void (f64)> modify = {}) : Setting(name) {
_currentValue = value;
_latchedValue = value;
_modify = modify;
}
auto modify(f64 value) const -> void { if(_modify) return _modify(value); }
auto value() const -> f64 { return _currentValue; }
auto latch() const -> f64 { return _latchedValue; }
auto setModify(function<void (f64)> modify) { _modify = modify; }
auto setValue(f64 value) -> void {
if(_allowedValues && !_allowedValues.find(value)) return;
_currentValue = value;
if(_dynamic) setLatch();
}
auto setLatch() -> void override {
if(_latchedValue == _currentValue) return;
_latchedValue = _currentValue;
modify(_latchedValue);
}
auto setAllowedValues(vector<f64> allowedValues) -> void {
_allowedValues = allowedValues;
if(_allowedValues && !_allowedValues.find(_currentValue)) setValue(_allowedValues.first());
}
auto readValue() const -> string override { return value(); }
auto readLatch() const -> string override { return latch(); }
auto readAllowedValues() const -> vector<string> override {
vector<string> values;
for(auto value : _allowedValues) values.append(value);
return values;
}
auto writeValue(string value) -> void override { setValue(value.real()); }
protected:
function<void (f64)> _modify;
f64 _currentValue = {};
f64 _latchedValue = {};
vector<f64> _allowedValues;
};
-46
View File
@@ -1,46 +0,0 @@
struct Setting : Object {
DeclareClass(Setting, "setting")
using Object::Object;
auto dynamic() const -> bool { return _dynamic; }
auto setDynamic(bool dynamic) -> void {
_dynamic = dynamic;
}
virtual auto setLatch() -> void {}
virtual auto readValue() const -> string { return {}; }
virtual auto readLatch() const -> string { return {}; }
virtual auto readAllowedValues() const -> vector<string> { return {}; }
virtual auto writeValue(string value) -> void {}
auto load(Node::Object source) -> bool override {
if(!Object::load(source)) return false;
if(auto setting = source->cast<shared_pointer<Setting>>()) writeValue(setting->readValue());
return true;
}
auto copy(Node::Object object) -> void override {
if(auto source = object->cast<Node::Setting::Setting>()) {
Object::copy(source);
writeValue(source->readValue());
setLatch();
}
}
auto serialize(string& output, string depth) -> void override {
Object::serialize(output, depth);
output.append(depth, " dynamic: ", _dynamic, "\n");
output.append(depth, " value: ", readValue(), "\n");
}
auto unserialize(Markup::Node node) -> void override {
Object::unserialize(node);
_dynamic = node["dynamic"].boolean();
writeValue(node["value"].string());
}
protected:
bool _dynamic = false;
};
-43
View File
@@ -1,43 +0,0 @@
struct String : Setting {
DeclareClass(String, "setting.string")
String(string name = {}, string value = {}, function<void (string)> modify = {}) : Setting(name) {
_currentValue = value;
_latchedValue = value;
_modify = modify;
}
auto modify(string value) const -> void { if(_modify) return _modify(value); }
auto value() const -> string { return _currentValue; }
auto latch() const -> string { return _latchedValue; }
auto setModify(function<void (string)> modify) { _modify = modify; }
auto setValue(string value) -> void {
if(_allowedValues && !_allowedValues.find(value)) return;
_currentValue = value;
if(_dynamic) setLatch();
}
auto setLatch() -> void override {
if(_latchedValue == _currentValue) return;
_latchedValue = _currentValue;
modify(_latchedValue);
}
auto setAllowedValues(vector<string> allowedValues) -> void {
_allowedValues = allowedValues;
if(_allowedValues && !_allowedValues.find(_currentValue)) setValue(_allowedValues.first());
}
auto readValue() const -> string override { return value(); }
auto readLatch() const -> string override { return latch(); }
auto readAllowedValues() const -> vector<string> override { return _allowedValues; }
auto writeValue(string value) -> void override { setValue(value); }
protected:
function<void (string)> _modify;
string _currentValue = {};
string _latchedValue = {};
vector<string> _allowedValues;
};
-29
View File
@@ -1,29 +0,0 @@
struct System : Object {
DeclareClass(System, "system")
using Object::Object;
auto game() -> string { if(_game) return _game(); return {}; }
auto run() -> void { if(_run) return _run(); }
auto power(bool reset = false) -> void { if(_power) return _power(reset); }
auto save() -> void { if(_save) return _save(); }
auto unload() -> void { if(_unload) return _unload(); }
auto serialize(bool synchronize = true) -> serializer { if(_serialize) return _serialize(synchronize); return {}; }
auto unserialize(serializer& s) -> bool { if(_unserialize) return _unserialize(s); return false; }
auto setGame(function<string ()> game) -> void { _game = game; }
auto setRun(function<void ()> run) -> void { _run = run; }
auto setPower(function<void (bool)> power) -> void { _power = power; }
auto setSave(function<void ()> save) -> void { _save = save; }
auto setUnload(function<void ()> unload) -> void { _unload = unload; }
auto setSerialize(function<serializer (bool)> serialize) -> void { _serialize = serialize; }
auto setUnserialize(function<bool (serializer&)> unserialize) -> void { _unserialize = unserialize; }
protected:
function<string ()> _game;
function<void ()> _run;
function<void (bool)> _power;
function<void ()> _save;
function<void ()> _unload;
function<serializer (bool)> _serialize;
function<bool (serializer&)> _unserialize;
};
-387
View File
@@ -1,387 +0,0 @@
Screen::Screen(string name, u32 width, u32 height) : Video(name) {
_canvasWidth = width;
_canvasHeight = height;
if(width && height) {
_inputA = new u32[width * height]();
_inputB = new u32[width * height]();
_output = new u32[width * height]();
_rotate = new u32[width * height]();
if constexpr(ares::Video::Threaded) {
_thread = nall::thread::create({&Screen::main, this});
}
}
}
Screen::~Screen() {
if constexpr(ares::Video::Threaded) {
if(_canvasWidth && _canvasHeight) {
_kill = true;
_thread.join();
}
}
}
auto Screen::main(uintptr_t) -> void {
while(!_kill) {
usleep(1);
if(_frame) {
refresh();
_frame = false;
}
}
}
auto Screen::quit() -> void {
_kill = true;
_thread.join();
}
auto Screen::power() -> void {
lock_guard<recursive_mutex> lock(_mutex);
memory::fill<u32>(_inputA.data(), _canvasWidth * _canvasHeight, _fillColor);
memory::fill<u32>(_inputB.data(), _canvasWidth * _canvasHeight, _fillColor);
memory::fill<u32>(_output.data(), _canvasWidth * _canvasHeight, _fillColor);
memory::fill<u32>(_rotate.data(), _canvasWidth * _canvasHeight, _fillColor);
}
auto Screen::pixels(bool frame) -> array_span<u32> {
if(frame == 0) return {_inputA.data(), _canvasWidth * _canvasHeight};
if(frame == 1) return {_inputB.data(), _canvasWidth * _canvasHeight};
return {};
}
auto Screen::resetPalette() -> void {
lock_guard<recursive_mutex> lock(_mutex);
_palette.reset();
}
auto Screen::resetSprites() -> void {
lock_guard<recursive_mutex> lock(_mutex);
_sprites.reset();
}
auto Screen::setRefresh(function<void ()> refresh) -> void {
lock_guard<recursive_mutex> lock(_mutex);
_refresh = refresh;
}
auto Screen::setViewport(u32 x, u32 y, u32 width, u32 height) -> void {
lock_guard<recursive_mutex> lock(_mutex);
_viewportX = x;
_viewportY = y;
_viewportWidth = width;
_viewportHeight = height;
}
auto Screen::setSize(u32 width, u32 height) -> void {
lock_guard<recursive_mutex> lock(_mutex);
_width = width;
_height = height;
}
auto Screen::setScale(f64 scaleX, f64 scaleY) -> void {
lock_guard<recursive_mutex> lock(_mutex);
_scaleX = scaleX;
_scaleY = scaleY;
}
auto Screen::setAspect(f64 aspectX, f64 aspectY) -> void {
lock_guard<recursive_mutex> lock(_mutex);
_aspectX = aspectX;
_aspectY = aspectY;
}
auto Screen::setSaturation(f64 saturation) -> void {
lock_guard<recursive_mutex> lock(_mutex);
_saturation = saturation;
_palette.reset();
}
auto Screen::setGamma(f64 gamma) -> void {
lock_guard<recursive_mutex> lock(_mutex);
_gamma = gamma;
_palette.reset();
}
auto Screen::setLuminance(f64 luminance) -> void {
lock_guard<recursive_mutex> lock(_mutex);
_luminance = luminance;
_palette.reset();
}
auto Screen::setFillColor(u32 fillColor) -> void {
lock_guard<recursive_mutex> lock(_mutex);
_fillColor = fillColor;
}
auto Screen::setColorBleed(bool colorBleed) -> void {
lock_guard<recursive_mutex> lock(_mutex);
_colorBleed = colorBleed;
}
auto Screen::setInterframeBlending(bool interframeBlending) -> void {
lock_guard<recursive_mutex> lock(_mutex);
_interframeBlending = interframeBlending;
}
auto Screen::setRotation(u32 rotation) -> void {
lock_guard<recursive_mutex> lock(_mutex);
_rotation = rotation;
}
auto Screen::setProgressive(bool progressiveDouble) -> void {
lock_guard<recursive_mutex> lock(_mutex);
_interlace = false;
_progressive = true;
_progressiveDouble = progressiveDouble;
}
auto Screen::setInterlace(bool interlaceField) -> void {
lock_guard<recursive_mutex> lock(_mutex);
_progressive = false;
_interlace = true;
_interlaceField = interlaceField;
}
auto Screen::attach(Node::Video::Sprite sprite) -> void {
lock_guard<recursive_mutex> lock(_mutex);
if(_sprites.find(sprite)) return;
_sprites.append(sprite);
}
auto Screen::detach(Node::Video::Sprite sprite) -> void {
lock_guard<recursive_mutex> lock(_mutex);
if(!_sprites.find(sprite)) return;
_sprites.removeByValue(sprite);
}
auto Screen::colors(u32 colors, function<n64 (n32)> color) -> void {
lock_guard<recursive_mutex> lock(_mutex);
_colors = colors;
_color = color;
_palette.reset();
}
auto Screen::frame() -> void {
if(runAhead()) return;
while(_frame) spinloop();
lock_guard<recursive_mutex> lock(_mutex);
_inputA.swap(_inputB);
_frame = true;
if constexpr(!ares::Video::Threaded) {
refresh();
_frame = false;
}
}
auto Screen::refresh() -> void {
lock_guard<recursive_mutex> lock(_mutex);
if(runAhead()) return;
refreshPalette();
if(_refresh) _refresh();
auto viewX = _viewportX;
auto viewY = _viewportY;
auto viewWidth = _viewportWidth;
auto viewHeight = _viewportHeight;
auto pitch = _canvasWidth;
auto width = _canvasWidth;
auto height = _canvasHeight;
auto input = _inputB.data();
auto output = _output.data();
for(u32 y : range(height)) {
auto source = input + y * pitch;
auto target = output + y * width;
if(_interlace) {
if((_interlaceField & 1) == (y & 1)) {
for(u32 x : range(width)) {
auto color = _palette[*source++];
*target++ = color;
}
}
} else if(_progressive && _progressiveDouble) {
source = input + (y & ~1) * pitch;
for(u32 x : range(width)) {
auto color = _palette[*source++];
*target++ = color;
}
} else if(_interframeBlending) {
n32 mask = 1 << 24 | 1 << 16 | 1 << 8 | 1 << 0;
for(u32 x : range(width)) {
auto a = *target;
auto b = _palette[*source++];
*target++ = (a + b - ((a ^ b) & mask)) >> 1;
}
} else {
for(u32 x : range(width)) {
auto color = _palette[*source++];
*target++ = color;
}
}
}
if(_colorBleed) {
n32 mask = 1 << 24 | 1 << 16 | 1 << 8 | 1 << 0;
for(u32 y : range(height)) {
auto target = output + y * width;
for(u32 x : range(width)) {
auto a = target[x];
auto b = target[x + (x != width - 1)];
target[x] = (a + b - ((a ^ b) & mask)) >> 1;
}
}
}
for(auto& sprite : _sprites) {
if(!sprite->visible()) continue;
n32 alpha = 255u << 24;
for(int y : range(sprite->height())) {
s32 pixelY = sprite->y() + y;
if(pixelY < 0 || pixelY >= height) continue;
auto source = sprite->image().data() + y * sprite->width();
auto target = &output[pixelY * width];
for(s32 x : range(sprite->width())) {
s32 pixelX = sprite->x() + x;
if(pixelX < 0 || pixelX >= width) continue;
auto pixel = source[x];
if(pixel >> 24) target[pixelX] = alpha | pixel;
}
}
}
if(_rotation == 90) {
//rotate left
for(u32 y : range(height)) {
auto source = output + y * width;
for(u32 x : range(width)) {
auto target = _rotate.data() + (width - 1 - x) * height + y;
*target = *source++;
}
}
output = _rotate.data();
swap(width, height);
swap(viewWidth, viewHeight);
}
if(_rotation == 180) {
//rotate upside down
for(u32 y : range(height)) {
auto source = output + y * width;
for(u32 x : range(width)) {
auto target = _rotate.data() + (height - 1 - y) * width + (width - 1 - x);
*target = *source++;
}
}
output = _rotate.data();
}
if(_rotation == 270) {
//rotate right
for(u32 y : range(height)) {
auto source = output + y * width;
for(u32 x : range(width)) {
auto target = _rotate.data() + x * height + (height - 1 - y);
*target = *source++;
}
}
output = _rotate.data();
swap(width, height);
swap(viewWidth, viewHeight);
}
platform->video(shared(), output + viewX + viewY * width, width * sizeof(u32), viewWidth, viewHeight);
memory::fill<u32>(_inputB.data(), width * height, _fillColor);
}
auto Screen::refreshPalette() -> void {
lock_guard<recursive_mutex> lock(_mutex);
if(_palette) return;
//generate the color lookup palettes to convert native colors to ARGB8888
_palette = new u32[_colors];
for(u32 index : range(_colors)) {
n64 color = _color(index);
n16 b = color.bit( 0,15);
n16 g = color.bit(16,31);
n16 r = color.bit(32,47);
n16 a = 65535;
if(_saturation != 1.0) {
n16 grayscale = uclamp<16>((r + g + b) / 3);
f64 inverse = max(0.0, 1.0 - _saturation);
r = uclamp<16>(r * _saturation + grayscale * inverse);
g = uclamp<16>(g * _saturation + grayscale * inverse);
b = uclamp<16>(b * _saturation + grayscale * inverse);
}
if(_gamma != 1.0) {
f64 reciprocal = 1.0 / 32767.0;
r = r > 32767 ? r : n16(32767 * pow(r * reciprocal, _gamma));
g = g > 32767 ? g : n16(32767 * pow(g * reciprocal, _gamma));
b = b > 32767 ? b : n16(32767 * pow(b * reciprocal, _gamma));
}
if(_luminance != 1.0) {
r = uclamp<16>(r * _luminance);
g = uclamp<16>(g * _luminance);
b = uclamp<16>(b * _luminance);
}
a >>= 8;
r >>= 8;
g >>= 8;
b >>= 8;
_palette[index] = a << 24 | r << 16 | g << 8 | b << 0;
}
}
auto Screen::serialize(string& output, string depth) -> void {
Video::serialize(output, depth);
output.append(depth, " width: ", _width, "\n");
output.append(depth, " height: ", _height, "\n");
output.append(depth, " scaleX: ", _scaleX, "\n");
output.append(depth, " scaleY: ", _scaleY, "\n");
output.append(depth, " aspectX: ", _aspectX, "\n");
output.append(depth, " aspectY: ", _aspectY, "\n");
output.append(depth, " colors: ", _colors, "\n");
output.append(depth, " saturation: ", _saturation, "\n");
output.append(depth, " gamma: ", _gamma, "\n");
output.append(depth, " luminance: ", _luminance, "\n");
output.append(depth, " fillColor: ", _fillColor, "\n");
output.append(depth, " colorBleed: ", _colorBleed, "\n");
output.append(depth, " interlace: ", _interlace, "\n");
output.append(depth, " interframeBlending: ", _interframeBlending, "\n");
output.append(depth, " rotation: ", _rotation, "\n");
}
auto Screen::unserialize(Markup::Node node) -> void {
Video::unserialize(node);
_width = node["width"].natural();
_height = node["height"].natural();
_scaleX = node["scaleX"].real();
_scaleY = node["scaleY"].real();
_aspectX = node["aspectX"].real();
_aspectY = node["aspectY"].real();
_colors = node["colors"].natural();
_saturation = node["saturation"].real();
_gamma = node["gamma"].real();
_luminance = node["luminance"].real();
_fillColor = node["fillColor"].natural();
_colorBleed = node["colorBleed"].boolean();
_interlace = node["interlace"].natural();
_interframeBlending = node["interframeBlending"].boolean();
_rotation = node["rotation"].natural();
resetPalette();
resetSprites();
}
Loaded 100 of 2823 files, more files were not shown because too many files have changed in this diff. Show more