mirror of https://github.com/bsnes-emu/bsnes.git
Update to v106r2 release.
byuu says: Changelog: - Super Famicom: added support for loading manifests without embedded mapping information¹ - genius: initial commit - various Makefile cleanups ¹: so the idea here is to try and aim for a stable manifest format, and to allow direct transposition of icarus/genius database entries into manifest files. The exact mechanics of how this is going to work is currently in flux, but we'll get there. For right now, `Super Famicom.sys` gains `boards.bml`, which is the raw database from my board-editor tool, and higan itself tries to load `boards.bml`, match an entry to game/board from the game's `manifest.bml` file, and then transform it into the format currently used by higan. It does this only when the game's `manifest.bml` file lacks a board node. When such a board node exists, it works as previous versions of higan did. The only incompatible change right now is information/title is now located at game/label. I may transition window title display to just use the filenames instead. Longer term, some thought is going to need to go into the format of the `boards.bml` database itself, and at which point in the process I should be transforming things. Give it time, we'll refine this into something nicer.
This commit is contained in:
parent
aef8d5e962
commit
2f81b5a3e7
|
@ -0,0 +1,59 @@
|
|||
build := stable
|
||||
include ../nall/GNUmakefile
|
||||
include ../hiro/GNUmakefile
|
||||
|
||||
name := genius
|
||||
flags += -I..
|
||||
|
||||
objects := obj/hiro.o
|
||||
objects += obj/genius.o
|
||||
objects += $(if $(call streq,$(platform),windows),obj/resource.o)
|
||||
|
||||
all: $(objects)
|
||||
$(strip $(compiler) -o out/$(name) $(objects) $(link) $(hirolink))
|
||||
ifeq ($(platform),macos)
|
||||
rm -rf out/$(name).app
|
||||
mkdir -p out/$(name).app/Contents/MacOS/
|
||||
mkdir -p out/$(name).app/Contents/Resources/
|
||||
mv out/$(name) out/$(name).app/Contents/MacOS/$(name)
|
||||
cp data/$(name).plist out/$(name).app/Contents/Info.plist
|
||||
sips -s format icns data/$(name).png --out out/$(name).app/Contents/Resources/$(name).icns
|
||||
endif
|
||||
|
||||
obj/hiro.o: ../hiro/hiro.cpp
|
||||
$(compiler) $(hiroflags) -o obj/hiro.o -c ../hiro/hiro.cpp
|
||||
|
||||
obj/genius.o: genius.cpp genius.hpp
|
||||
$(compiler) $(cppflags) $(flags) -o obj/genius.o -c genius.cpp
|
||||
|
||||
obj/resource.o:
|
||||
$(windres) data/$(name).rc obj/resource.o
|
||||
|
||||
clean:
|
||||
ifeq ($(platform),macos)
|
||||
rm -rf out/$(name).app
|
||||
endif
|
||||
$(call rm,obj/*)
|
||||
$(call rm,out/*)
|
||||
|
||||
install:
|
||||
ifeq ($(platform),macos)
|
||||
cp -R out/$(name).app /Applications/$(name).app
|
||||
else ifneq ($(filter $(platform),linux bsd),)
|
||||
mkdir -p $(prefix)/bin/
|
||||
mkdir -p $(prefix)/share/applications/
|
||||
mkdir -p $(prefix)/share/icons/
|
||||
mkdir -p $(prefix)/share/$(name)/
|
||||
cp out/$(name) $(prefix)/bin/$(name)
|
||||
cp data/$(name).desktop $(prefix)/share/applications/$(name).desktop
|
||||
cp data/$(name).png $(prefix)/share/icons/$(name).png
|
||||
endif
|
||||
|
||||
uninstall:
|
||||
ifeq ($(platform),macos)
|
||||
rm -rf /Applications/$(name).app
|
||||
else ifneq ($(filter $(platform),linux bsd),)
|
||||
rm -f $(prefix)/bin/$(name)
|
||||
rm -f $(prefix)/share/applications/$(name).desktop
|
||||
rm -f $(prefix)/share/icons/$(name).png
|
||||
endif
|
|
@ -0,0 +1,14 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
||||
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
|
||||
<assemblyIdentity type="win32" name="genius" version="1.0.0.0" processorArchitecture="*"/>
|
||||
<dependency>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity type="win32" name="Microsoft.Windows.Common-Controls" version="6.0.0.0" processorArchitecture="*" publicKeyToken="6595b64144ccf1df" language="*"/>
|
||||
</dependentAssembly>
|
||||
</dependency>
|
||||
<asmv3:application xmlns:asmv3="urn:schemas-microsoft-com:asm.v3">
|
||||
<asmv3:windowsSettings xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">
|
||||
<dpiAware>false</dpiAware>
|
||||
</asmv3:windowsSettings>
|
||||
</asmv3:application>
|
||||
</assembly>
|
|
@ -0,0 +1,8 @@
|
|||
[Desktop Entry]
|
||||
Name=genius
|
||||
Comment=Emulator
|
||||
Exec=genius
|
||||
Icon=genius
|
||||
Terminal=false
|
||||
Type=Application
|
||||
Categories=Game;Emulator;
|
Binary file not shown.
After Width: | Height: | Size: 33 KiB |
|
@ -0,0 +1,18 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>org.byuu.genius</string>
|
||||
<key>CFBundleDisplayName</key>
|
||||
<string>genius</string>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>genius</string>
|
||||
<key>CFBundleIconFile</key>
|
||||
<string>genius.icns</string>
|
||||
<key>NSHighResolutionCapable</key>
|
||||
<true/>
|
||||
<key>NSSupportsAutomaticGraphicsSwitching</key>
|
||||
<true/>
|
||||
</dict>
|
||||
</plist>
|
Binary file not shown.
After Width: | Height: | Size: 14 KiB |
|
@ -0,0 +1,2 @@
|
|||
1 24 "genius.Manifest"
|
||||
2 ICON DISCARDABLE "genius.ico"
|
|
@ -0,0 +1,80 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
width="256mm"
|
||||
height="256mm"
|
||||
viewBox="0 0 256 256"
|
||||
version="1.1"
|
||||
id="svg8"
|
||||
inkscape:version="0.92.2 (5c3e80d, 2017-08-06)"
|
||||
sodipodi:docname="icarus.svg">
|
||||
<defs
|
||||
id="defs2" />
|
||||
<sodipodi:namedview
|
||||
id="base"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="0.5"
|
||||
inkscape:cx="62.34093"
|
||||
inkscape:cy="560"
|
||||
inkscape:document-units="mm"
|
||||
inkscape:current-layer="layer1"
|
||||
showgrid="false"
|
||||
inkscape:window-width="1920"
|
||||
inkscape:window-height="1028"
|
||||
inkscape:window-x="-8"
|
||||
inkscape:window-y="-8"
|
||||
inkscape:window-maximized="1" />
|
||||
<metadata
|
||||
id="metadata5">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title />
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g
|
||||
inkscape:label="Layer 1"
|
||||
inkscape:groupmode="layer"
|
||||
id="layer1"
|
||||
transform="translate(0,-41)">
|
||||
<circle
|
||||
id="path10"
|
||||
cx="128.0"
|
||||
cy="169.0"
|
||||
r="120.0"
|
||||
style="stroke-width:0.25;fill:#b8b8ff;fill-opacity:1" />
|
||||
<g
|
||||
aria-label="氷"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:260.07336426px;line-height:1.25;font-family:KaiTi;-inkscape-font-specification:KaiTi;letter-spacing:0px;word-spacing:0px;fill:#4050e0;fill-opacity:1;stroke:#4050e0;stroke-width:6;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
id="text818">
|
||||
<path
|
||||
style="fill:#4050e0;fill-opacity:1;stroke:#4050e0;stroke-width:6;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="m 130.80961,146.24049 q 5.07956,5.07956 14.22276,15.23868 14.22277,-13.20685 25.39779,-27.42962 12.19094,-15.23867 11.17503,-24.38187 0,-10.15912 10.15912,-4.06365 10.15911,6.09547 14.22276,12.19094 4.06364,5.07956 -2.03182,7.11138 -6.09547,1.01591 -22.35006,14.22276 -15.23867,12.19094 -32.50917,26.4137 13.20685,11.17503 23.36597,20.31823 11.17502,9.14321 24.38187,18.28641 14.22277,8.1273 27.42962,14.22276 14.22276,5.07956 21.33414,7.11139 7.11138,2.03182 -3.04773,5.07955 -9.14321,2.03183 -23.36597,3.04774 -14.22276,0 -21.33414,-2.03182 -6.09547,-3.04774 -11.17503,-8.1273 -4.06365,-5.07956 -24.38188,-27.42961 -19.30232,-23.36597 -31.49326,-39.62055 1.01591,41.65237 2.03182,64.00243 2.03183,22.35005 0,34.54099 -2.03182,12.19094 -8.12729,19.30232 -5.07956,7.11138 -8.12729,4.06365 -2.03182,-2.03183 -7.11138,-11.17503 -5.07956,-8.12729 -16.254587,-15.23867 -11.175027,-8.1273 1.015912,-5.07956 12.190935,2.03182 16.254585,2.03182 4.06365,-1.01591 6.09547,-7.11138 2.03182,-7.11138 2.03182,-46.73193 0,-40.63646 -1.01591,-77.20928 -1.01591,-37.58873 -6.09547,-45.716022 -5.07956,-9.143205 4.06365,-7.111382 10.15911,1.015912 16.25458,5.079558 7.11138,3.047735 4.06365,9.143205 -3.04774,5.079557 -4.06365,15.238673 -1.01591,10.159118 -1.01591,51.811488 z"
|
||||
id="path822" />
|
||||
<path
|
||||
style="fill:#4050e0;fill-opacity:1;stroke:#4050e0;stroke-width:6;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="m 88.141325,149.28823 q 5.079558,1.01591 14.222765,7.11138 9.1432,6.09547 4.06364,10.15911 -5.07955,4.06365 -12.190935,18.28641 -6.09547,14.22276 -14.222763,25.39779 -8.127292,10.15912 -19.30232,19.30232 -11.175027,8.12729 -21.334143,12.19094 -9.143204,3.04774 -16.254585,5.07956 -6.095469,1.01591 5.079558,-6.09547 11.175027,-7.11138 21.334143,-17.2705 11.175027,-10.15911 18.286408,-21.33414 8.127293,-12.19094 11.175028,-20.31823 3.047735,-9.14321 3.047735,-14.22276 1.015911,-5.07956 -3.047735,-5.07956 -4.063646,0 -15.238674,4.06364 -10.159116,4.06365 -15.238674,6.09547 -4.063646,2.03183 -13.20685,-3.04773 -8.127293,-6.09547 2.031823,-6.09547 11.175027,-1.01591 24.381878,-5.07956 14.222762,-5.07956 17.270497,-7.11138 4.063646,-3.04773 9.143204,-2.03182 z"
|
||||
id="path820" />
|
||||
<path
|
||||
style="fill:#4050e0;fill-opacity:1;stroke:#4050e0;stroke-width:6;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="m 63.759447,101.54038 q 9.143204,1.01591 18.286409,5.07956 9.143204,4.06365 11.175027,11.17503 2.031823,7.11138 -1.015912,11.17503 -3.047734,4.06364 -15.238673,-4.06365 -11.175028,-9.1432 -16.254586,-16.25459 -5.079557,-8.12729 3.047735,-7.11138 z"
|
||||
id="path815" />
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 4.9 KiB |
|
@ -0,0 +1,475 @@
|
|||
#include <nall/nall.hpp>
|
||||
using namespace nall;
|
||||
|
||||
#include <hiro/hiro.hpp>
|
||||
using namespace hiro;
|
||||
|
||||
#include "genius.hpp"
|
||||
unique_pointer<ListWindow> listWindow;
|
||||
unique_pointer<GameWindow> gameWindow;
|
||||
unique_pointer<MemoryWindow> memoryWindow;
|
||||
|
||||
//
|
||||
|
||||
ListWindow::ListWindow() {
|
||||
listWindow = this;
|
||||
|
||||
fileMenu.setText("File");
|
||||
newAction.setText("New").onActivate([&] { newDatabase(); });
|
||||
openAction.setText("Open ...").onActivate([&] {
|
||||
if(auto location = BrowserDialog().setParent(*this).setFilters({"*.bml"}).openFile()) {
|
||||
loadDatabase(location);
|
||||
}
|
||||
});
|
||||
saveAction.setText("Save").onActivate([&] {
|
||||
if(!location) return saveAsAction.doActivate();
|
||||
saveDatabase(location);
|
||||
});
|
||||
saveAsAction.setText("Save As ...").onActivate([&] {
|
||||
if(auto location = BrowserDialog().setParent(*this).setFilters({"*.bml"}).saveFile()) {
|
||||
saveDatabase(location);
|
||||
}
|
||||
});
|
||||
quitAction.setText("Quit").onActivate([&] { quit(); });
|
||||
|
||||
helpMenu.setText("Help");
|
||||
aboutAction.setText("About ...").onActivate([&] {
|
||||
MessageDialog().setParent(*this).setTitle("About").setText({
|
||||
"genius v01\n",
|
||||
"Author: byuu\n",
|
||||
"Website: https://byuu.org/"
|
||||
}).information();
|
||||
});
|
||||
|
||||
layout.setMargin(5);
|
||||
gameList.onActivate([&] { modifyButton.doActivate(); });
|
||||
gameList.onChange([&] { updateWindow(); });
|
||||
appendButton.setText("Append").onActivate([&] {
|
||||
setEnabled(false);
|
||||
gameWindow->show();
|
||||
});
|
||||
modifyButton.setText("Modify").onActivate([&] {
|
||||
if(auto item = gameList.selected()) {
|
||||
setEnabled(false);
|
||||
gameWindow->show(games[item.offset()]);
|
||||
}
|
||||
});
|
||||
removeButton.setText("Remove").onActivate([&] { removeGame(); });
|
||||
|
||||
onClose([&] { quit(); });
|
||||
|
||||
setSize({960, 600});
|
||||
reloadList();
|
||||
updateWindow();
|
||||
setCentered();
|
||||
setVisible();
|
||||
}
|
||||
|
||||
auto ListWindow::quit() -> void {
|
||||
if(!modified || MessageDialog().setParent(*this).setText({
|
||||
"Are you sure you want to quit without saving your changes?"
|
||||
}).question() == "Yes") {
|
||||
Application::quit();
|
||||
}
|
||||
}
|
||||
|
||||
auto ListWindow::reloadList() -> void {
|
||||
gameList.reset();
|
||||
gameList.append(TableViewHeader()
|
||||
.append(TableViewColumn().setText("Name").setExpandable())
|
||||
.append(TableViewColumn().setText("Region"))
|
||||
.append(TableViewColumn().setText("Revision"))
|
||||
.append(TableViewColumn().setText("Board"))
|
||||
);
|
||||
for(auto& game : games) {
|
||||
gameList.append(TableViewItem()
|
||||
.append(TableViewCell().setText(game.name))
|
||||
.append(TableViewCell().setText(game.region))
|
||||
.append(TableViewCell().setText(game.revision))
|
||||
.append(TableViewCell().setText(game.board))
|
||||
);
|
||||
}
|
||||
Application::processEvents();
|
||||
gameList.resizeColumns();
|
||||
}
|
||||
|
||||
auto ListWindow::updateWindow() -> void {
|
||||
modifyButton.setEnabled((bool)gameList.selected());
|
||||
removeButton.setEnabled((bool)gameList.selected());
|
||||
string name = Location::base(location);
|
||||
if(!name) name = "(Untitled)";
|
||||
setTitle({modified ? "*" : "", name, " [", games.size(), "] - genius"});
|
||||
}
|
||||
|
||||
auto ListWindow::newDatabase() -> void {
|
||||
games.reset();
|
||||
modified = false;
|
||||
location = "";
|
||||
reloadList();
|
||||
updateWindow();
|
||||
}
|
||||
|
||||
auto ListWindow::loadDatabase(string location) -> void {
|
||||
auto document = BML::unserialize(string::read(location));
|
||||
|
||||
games.reset();
|
||||
for(auto node : document.find("game")) {
|
||||
Game game;
|
||||
game.sha256 = node["sha256"].text();
|
||||
game.region = node["region"].text();
|
||||
game.revision = node["revision"].text();
|
||||
game.board = node["board"].text();
|
||||
game.name = node["name"].text();
|
||||
game.label = node["label"].text();
|
||||
game.note = node["note"].text();
|
||||
for(auto leaf : node.find("memory")) {
|
||||
Memory memory;
|
||||
memory.type = leaf["type"].text();
|
||||
memory.size = leaf["size"].text();
|
||||
memory.name = leaf["name"].text();
|
||||
game.memories.append(memory);
|
||||
}
|
||||
games.append(game);
|
||||
}
|
||||
|
||||
modified = false;
|
||||
this->location = location;
|
||||
reloadList();
|
||||
updateWindow();
|
||||
}
|
||||
|
||||
auto ListWindow::saveDatabase(string location) -> void {
|
||||
file fp{location, file::mode::write};
|
||||
if(!fp) return MessageDialog().setParent(*this).setText({
|
||||
"Error: failed to write file.\n\n",
|
||||
"Name: ", location
|
||||
}).error(), void();
|
||||
|
||||
auto copy = games;
|
||||
copy.sort([](auto x, auto y) {
|
||||
return string::icompare(x.name, y.name) < 0;
|
||||
});
|
||||
|
||||
fp.print("database\n");
|
||||
fp.print(" revision: ", chrono::local::date(), "\n\n");
|
||||
|
||||
for(auto& game : copy) {
|
||||
fp.print("game\n");
|
||||
fp.print(" sha256: ", game.sha256, "\n");
|
||||
fp.print(" region: ", game.region, "\n");
|
||||
fp.print(" revision: ", game.revision, "\n");
|
||||
if(game.board)
|
||||
fp.print(" board: ", game.board, "\n");
|
||||
fp.print(" name: ", game.name, "\n");
|
||||
if(game.label)
|
||||
fp.print(" label: ", game.label, "\n");
|
||||
if(game.note)
|
||||
fp.print(" note: ", game.note, "\n");
|
||||
for(auto& memory : game.memories) {
|
||||
fp.print(" memory\n");
|
||||
fp.print(" type: ", memory.type, "\n");
|
||||
fp.print(" size: ", memory.size, "\n");
|
||||
fp.print(" name: ", memory.name, "\n");
|
||||
}
|
||||
fp.print("\n");
|
||||
}
|
||||
|
||||
modified = false;
|
||||
this->location = location;
|
||||
updateWindow();
|
||||
}
|
||||
|
||||
auto ListWindow::appendGame(Game game) -> void {
|
||||
modified = true;
|
||||
auto offset = games.size();
|
||||
games.append(game);
|
||||
reloadList();
|
||||
gameList.item(offset).setSelected().setFocused();
|
||||
updateWindow();
|
||||
}
|
||||
|
||||
auto ListWindow::modifyGame(Game game) -> void {
|
||||
if(auto item = gameList.selected()) {
|
||||
modified = true;
|
||||
auto offset = item.offset();
|
||||
games[offset] = game;
|
||||
reloadList();
|
||||
gameList.item(offset).setSelected().setFocused();
|
||||
updateWindow();
|
||||
}
|
||||
}
|
||||
|
||||
auto ListWindow::removeGame() -> void {
|
||||
if(auto item = gameList.selected()) {
|
||||
if(MessageDialog().setParent(*this).setText({
|
||||
"Are you sure you want to permanently remove this game?\n\n",
|
||||
"Name: ", item.cell(0).text()
|
||||
}).question() == "Yes") {
|
||||
modified = true;
|
||||
games.remove(item.offset());
|
||||
reloadList();
|
||||
updateWindow();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
GameWindow::GameWindow() {
|
||||
gameWindow = this;
|
||||
|
||||
layout.setMargin(5);
|
||||
hashLabel.setText("SHA256:");
|
||||
hashEdit.setFont(Font().setFamily(Font::Mono)).onChange([&] { modified = true, updateWindow(); });
|
||||
regionLabel.setText("Region:");
|
||||
regionEdit.setFont(Font().setFamily(Font::Mono)).onChange([&] { modified = true, updateWindow(); });
|
||||
revisionLabel.setText("Revision:");
|
||||
revisionEdit.setFont(Font().setFamily(Font::Mono)).onChange([&] { modified = true, updateWindow(); });
|
||||
boardLabel.setText("Board:");
|
||||
boardEdit.setFont(Font().setFamily(Font::Mono)).onChange([&] { modified = true, updateWindow(); });
|
||||
nameLabel.setText("Name:");
|
||||
nameEdit.onChange([&] { modified = true, updateWindow(); });
|
||||
labelLabel.setText("Label:");
|
||||
labelEdit.onChange([&] { modified = true, updateWindow(); });
|
||||
noteLabel.setText("Note:");
|
||||
noteEdit.onChange([&] { modified = true, updateWindow(); });
|
||||
memoryList.onActivate([&] { modifyButton.doActivate(); });
|
||||
memoryList.onChange([&] { updateWindow(); });
|
||||
appendButton.setText("Append").onActivate([&] {
|
||||
setEnabled(false);
|
||||
memoryWindow->show();
|
||||
});
|
||||
modifyButton.setText("Modify").onActivate([&] {
|
||||
if(auto item = memoryList.selected()) {
|
||||
setEnabled(false);
|
||||
memoryWindow->show(game.memories[item.offset()]);
|
||||
}
|
||||
});
|
||||
removeButton.setText("Remove").onActivate([&] { removeMemory(); });
|
||||
acceptButton.setText("Accept").onActivate([&] { accept(); });
|
||||
cancelButton.setText("Cancel").onActivate([&] { cancel(); });
|
||||
|
||||
onClose([&] { cancel(); });
|
||||
|
||||
setSize({800, 480});
|
||||
setDismissable();
|
||||
}
|
||||
|
||||
auto GameWindow::show(Game game) -> void {
|
||||
this->game = game;
|
||||
modified = false;
|
||||
create = !game.sha256;
|
||||
|
||||
hashEdit.setText(game.sha256).setEditable(create);
|
||||
regionEdit.setText(game.region);
|
||||
revisionEdit.setText(game.revision);
|
||||
boardEdit.setText(game.board);
|
||||
nameEdit.setText(game.name);
|
||||
labelEdit.setText(game.label);
|
||||
noteEdit.setText(game.note);
|
||||
acceptButton.setText(create ? "Create" : "Modify");
|
||||
|
||||
reloadList();
|
||||
updateWindow();
|
||||
setCentered(*listWindow);
|
||||
setVisible();
|
||||
|
||||
if(create) {
|
||||
hashEdit.setFocused();
|
||||
} else {
|
||||
cancelButton.setFocused();
|
||||
}
|
||||
}
|
||||
|
||||
auto GameWindow::accept() -> void {
|
||||
game.sha256 = hashEdit.text().strip();
|
||||
game.region = regionEdit.text().strip();
|
||||
game.revision = revisionEdit.text().strip();
|
||||
game.board = boardEdit.text().strip();
|
||||
game.name = nameEdit.text().strip();
|
||||
game.label = labelEdit.text().strip();
|
||||
game.note = noteEdit.text().strip();
|
||||
|
||||
if(create) {
|
||||
listWindow->appendGame(game);
|
||||
} else {
|
||||
listWindow->modifyGame(game);
|
||||
}
|
||||
|
||||
memoryWindow->setVisible(false);
|
||||
setVisible(false);
|
||||
listWindow->setEnabled();
|
||||
listWindow->setFocused();
|
||||
}
|
||||
|
||||
auto GameWindow::cancel() -> void {
|
||||
if(!modified || MessageDialog().setParent(*this).setText({
|
||||
"Are you sure you want to discard your changes to this game?"
|
||||
}).question() == "Yes") {
|
||||
memoryWindow->setVisible(false);
|
||||
setVisible(false);
|
||||
listWindow->setEnabled();
|
||||
listWindow->setFocused();
|
||||
}
|
||||
}
|
||||
|
||||
auto GameWindow::reloadList() -> void {
|
||||
memoryList.reset();
|
||||
memoryList.append(TableViewHeader()
|
||||
.append(TableViewColumn().setText("Type"))
|
||||
.append(TableViewColumn().setText("Size"))
|
||||
.append(TableViewColumn().setText("Name").setExpandable())
|
||||
);
|
||||
for(auto& memory : game.memories) {
|
||||
memoryList.append(TableViewItem()
|
||||
.append(TableViewCell().setText(memory.type))
|
||||
.append(TableViewCell().setText(memory.size))
|
||||
.append(TableViewCell().setText(memory.name))
|
||||
);
|
||||
}
|
||||
Application::processEvents();
|
||||
memoryList.resizeColumns();
|
||||
}
|
||||
|
||||
auto GameWindow::updateWindow() -> void {
|
||||
bool valid = true;
|
||||
hashEdit.setBackgroundColor(
|
||||
!create ? Color{192, 255, 192}
|
||||
: hashEdit.text().strip().size() == 64 ? Color{}
|
||||
: (valid = false, Color{255, 224, 224})
|
||||
);
|
||||
regionEdit.setBackgroundColor(regionEdit.text().strip() ? Color{} : (valid = false, Color{255, 224, 224}));
|
||||
revisionEdit.setBackgroundColor(revisionEdit.text().strip() ? Color{} : (valid = false, Color{255, 224, 224}));
|
||||
boardEdit.setBackgroundColor(boardEdit.text().strip() ? Color{} : (Color{255, 255, 240}));
|
||||
nameEdit.setBackgroundColor(nameEdit.text().strip() ? Color{} : (valid = false, Color{255, 224, 224}));
|
||||
labelEdit.setBackgroundColor(labelEdit.text().strip() ? Color{} : (Color{255, 255, 240}));
|
||||
noteEdit.setBackgroundColor(noteEdit.text().strip() ? Color{} : (Color{255, 255, 240}));
|
||||
modifyButton.setEnabled((bool)memoryList.selected());
|
||||
removeButton.setEnabled((bool)memoryList.selected());
|
||||
acceptButton.setEnabled(valid);
|
||||
setTitle({modified ? "*" : "", create ? "Add New Game" : "Modify Game Details"});
|
||||
}
|
||||
|
||||
auto GameWindow::appendMemory(Memory memory) -> void {
|
||||
modified = true;
|
||||
auto offset = game.memories.size();
|
||||
game.memories.append(memory);
|
||||
reloadList();
|
||||
memoryList.item(offset).setSelected().setFocused();
|
||||
updateWindow();
|
||||
}
|
||||
|
||||
auto GameWindow::modifyMemory(Memory memory) -> void {
|
||||
if(auto item = memoryList.selected()) {
|
||||
modified = true;
|
||||
auto offset = item.offset();
|
||||
game.memories[offset] = memory;
|
||||
reloadList();
|
||||
memoryList.item(offset).setSelected().setFocused();
|
||||
updateWindow();
|
||||
}
|
||||
}
|
||||
|
||||
auto GameWindow::removeMemory() -> void {
|
||||
if(auto item = memoryList.selected()) {
|
||||
if(MessageDialog().setParent(*this).setText({
|
||||
"Are you sure you want to permanently remove this memory?\n\n",
|
||||
"Name: ", item.cell(2).text()
|
||||
}).question() == "Yes") {
|
||||
modified = true;
|
||||
game.memories.remove(item.offset());
|
||||
reloadList();
|
||||
updateWindow();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
MemoryWindow::MemoryWindow() {
|
||||
memoryWindow = this;
|
||||
|
||||
layout.setMargin(5);
|
||||
typeLabel.setText("Type:");
|
||||
typeEdit.append(ComboEditItem().setText("ROM"));
|
||||
typeEdit.append(ComboEditItem().setText("EPROM"));
|
||||
typeEdit.append(ComboEditItem().setText("EEPROM"));
|
||||
typeEdit.append(ComboEditItem().setText("NOR"));
|
||||
typeEdit.append(ComboEditItem().setText("PSRAM"));
|
||||
typeEdit.append(ComboEditItem().setText("NVRAM"));
|
||||
typeEdit.append(ComboEditItem().setText("RAM"));
|
||||
typeEdit.onChange([&] { modified = true, updateWindow(); });
|
||||
sizeLabel.setText("Size:");
|
||||
sizeEdit.setFont(Font().setFamily(Font::Mono)).onChange([&] { modified = true, updateWindow(); });
|
||||
nameLabel.setText("Name:");
|
||||
nameEdit.onChange([&] { modified = true, updateWindow(); });
|
||||
acceptButton.setText("Accept").onActivate([&] { accept(); });
|
||||
cancelButton.setText("Cancel").onActivate([&] { cancel(); });
|
||||
|
||||
onClose([&] { cancel(); });
|
||||
|
||||
setSize({280, layout.minimumSize().height()});
|
||||
setDismissable();
|
||||
}
|
||||
|
||||
auto MemoryWindow::show(Memory memory) -> void {
|
||||
this->memory = memory;
|
||||
modified = false;
|
||||
create = !memory.type;
|
||||
|
||||
typeEdit.setText(memory.type);
|
||||
sizeEdit.setText(memory.size);
|
||||
nameEdit.setText(memory.name);
|
||||
|
||||
updateWindow();
|
||||
setCentered(*gameWindow);
|
||||
setVisible();
|
||||
|
||||
typeEdit.setFocused();
|
||||
}
|
||||
|
||||
auto MemoryWindow::accept() -> void {
|
||||
memory.type = typeEdit.text().strip();
|
||||
memory.size = sizeEdit.text().strip();
|
||||
memory.name = nameEdit.text().strip();
|
||||
|
||||
if(create) {
|
||||
gameWindow->appendMemory(memory);
|
||||
} else {
|
||||
gameWindow->modifyMemory(memory);
|
||||
}
|
||||
|
||||
setVisible(false);
|
||||
gameWindow->setEnabled();
|
||||
gameWindow->setFocused();
|
||||
}
|
||||
|
||||
auto MemoryWindow::cancel() -> void {
|
||||
if(!modified || MessageDialog().setParent(*this).setText({
|
||||
"Are you sure you want to discard your changes to this memory?"
|
||||
}).question() == "Yes") {
|
||||
setVisible(false);
|
||||
gameWindow->setEnabled();
|
||||
gameWindow->setFocused();
|
||||
}
|
||||
}
|
||||
|
||||
auto MemoryWindow::updateWindow() -> void {
|
||||
bool valid = true;
|
||||
typeEdit.setBackgroundColor(typeEdit.text().strip() ? Color{} : (valid = false, Color{255, 224, 224}));
|
||||
sizeEdit.setBackgroundColor(sizeEdit.text().strip() ? Color{} : (valid = false, Color{255, 224, 224}));
|
||||
nameEdit.setBackgroundColor(nameEdit.text().strip() ? Color{} : (valid = false, Color{255, 224, 224}));
|
||||
acceptButton.setEnabled(valid);
|
||||
setTitle({modified ? "*" : "", create ? "Add New Memory" : "Modify Memory Details"});
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
#include <nall/main.hpp>
|
||||
auto nall::main(string_vector) -> void {
|
||||
Application::setName("genius");
|
||||
new ListWindow;
|
||||
new GameWindow;
|
||||
new MemoryWindow;
|
||||
Application::run();
|
||||
}
|
|
@ -0,0 +1,125 @@
|
|||
struct Memory {
|
||||
string type;
|
||||
string size;
|
||||
string name;
|
||||
};
|
||||
|
||||
struct Game {
|
||||
string sha256;
|
||||
string region;
|
||||
string revision;
|
||||
string board;
|
||||
string name;
|
||||
string label;
|
||||
string note;
|
||||
vector<Memory> memories;
|
||||
};
|
||||
|
||||
struct ListWindow : Window {
|
||||
ListWindow();
|
||||
auto quit() -> void;
|
||||
auto reloadList() -> void;
|
||||
auto updateWindow() -> void;
|
||||
auto newDatabase() -> void;
|
||||
auto loadDatabase(string) -> void;
|
||||
auto saveDatabase(string) -> void;
|
||||
auto appendGame(Game) -> void;
|
||||
auto modifyGame(Game) -> void;
|
||||
auto removeGame() -> void;
|
||||
|
||||
private:
|
||||
bool modified = false;
|
||||
vector<Game> games;
|
||||
string location;
|
||||
|
||||
MenuBar menuBar{this};
|
||||
Menu fileMenu{&menuBar};
|
||||
MenuItem newAction{&fileMenu};
|
||||
MenuItem openAction{&fileMenu};
|
||||
MenuItem saveAction{&fileMenu};
|
||||
MenuItem saveAsAction{&fileMenu};
|
||||
MenuSeparator quitSeparator{&fileMenu};
|
||||
MenuItem quitAction{&fileMenu};
|
||||
Menu helpMenu{&menuBar};
|
||||
MenuItem aboutAction{&helpMenu};
|
||||
|
||||
HorizontalLayout layout{this};
|
||||
TableView gameList{&layout, Size{~0, ~0}};
|
||||
VerticalLayout controlLayout{&layout, Size{80, ~0}};
|
||||
Button appendButton{&controlLayout, Size{~0, 0}};
|
||||
Button modifyButton{&controlLayout, Size{~0, 0}};
|
||||
Button removeButton{&controlLayout, Size{~0, 0}};
|
||||
};
|
||||
|
||||
struct GameWindow : Window {
|
||||
GameWindow();
|
||||
auto show(Game = {}) -> void;
|
||||
auto accept() -> void;
|
||||
auto cancel() -> void;
|
||||
auto reloadList() -> void;
|
||||
auto updateWindow() -> void;
|
||||
auto appendMemory(Memory) -> void;
|
||||
auto modifyMemory(Memory) -> void;
|
||||
auto removeMemory() -> void;
|
||||
|
||||
private:
|
||||
bool modified = false;
|
||||
bool create = true;
|
||||
Game game;
|
||||
|
||||
VerticalLayout layout{this};
|
||||
HorizontalLayout hashLayout{&layout, Size{~0, 0}};
|
||||
Label hashLabel{&hashLayout, Size{50, 0}};
|
||||
LineEdit hashEdit{&hashLayout, Size{~0, 0}};
|
||||
HorizontalLayout infoLayout{&layout, Size{~0, 0}};
|
||||
Label regionLabel{&infoLayout, Size{50, 0}};
|
||||
LineEdit regionEdit{&infoLayout, Size{~0, 0}};
|
||||
Label revisionLabel{&infoLayout, Size{0, 0}};
|
||||
LineEdit revisionEdit{&infoLayout, Size{~0, 0}};
|
||||
Label boardLabel{&infoLayout, Size{0, 0}};
|
||||
LineEdit boardEdit{&infoLayout, Size{~0, 0}};
|
||||
HorizontalLayout nameLayout{&layout, Size{~0, 0}};
|
||||
Label nameLabel{&nameLayout, Size{50, 0}};
|
||||
LineEdit nameEdit{&nameLayout, Size{~0, 0}};
|
||||
HorizontalLayout labelLayout{&layout, Size{~0, 0}};
|
||||
Label labelLabel{&labelLayout, Size{50, 0}};
|
||||
LineEdit labelEdit{&labelLayout, Size{~0, 0}};
|
||||
HorizontalLayout noteLayout{&layout, Size{~0, 0}};
|
||||
Label noteLabel{¬eLayout, Size{50, 0}};
|
||||
LineEdit noteEdit{¬eLayout, Size{~0, 0}};
|
||||
TableView memoryList{&layout, Size{~0, ~0}};
|
||||
HorizontalLayout controlLayout{&layout, Size{~0, 0}};
|
||||
Button appendButton{&controlLayout, Size{80, 0}};
|
||||
Button modifyButton{&controlLayout, Size{80, 0}};
|
||||
Button removeButton{&controlLayout, Size{80, 0}};
|
||||
Widget spacer{&controlLayout, Size{~0, 0}};
|
||||
Button acceptButton{&controlLayout, Size{80, 0}};
|
||||
Button cancelButton{&controlLayout, Size{80, 0}};
|
||||
};
|
||||
|
||||
struct MemoryWindow : Window {
|
||||
MemoryWindow();
|
||||
auto show(Memory = {}) -> void;
|
||||
auto accept() -> void;
|
||||
auto cancel() -> void;
|
||||
auto updateWindow() -> void;
|
||||
|
||||
private:
|
||||
bool modified = false;
|
||||
bool create = true;
|
||||
Memory memory;
|
||||
|
||||
VerticalLayout layout{this};
|
||||
HorizontalLayout infoLayout{&layout, Size{~0, 0}};
|
||||
Label typeLabel{&infoLayout, Size{40, 0}};
|
||||
ComboEdit typeEdit{&infoLayout, Size{~0, 0}};
|
||||
Label sizeLabel{&infoLayout, Size{0, 0}};
|
||||
LineEdit sizeEdit{&infoLayout, Size{~0, 0}};
|
||||
HorizontalLayout nameLayout{&layout, Size{~0, 0}};
|
||||
Label nameLabel{&nameLayout, Size{40, 0}};
|
||||
LineEdit nameEdit{&nameLayout, Size{~0, 0}};
|
||||
HorizontalLayout controlLayout{&layout, Size{~0, 0}};
|
||||
Widget spacer{&controlLayout, Size{~0, 0}};
|
||||
Button acceptButton{&controlLayout, Size{80, 0}};
|
||||
Button cancelButton{&controlLayout, Size{80, 0}};
|
||||
};
|
|
@ -0,0 +1 @@
|
|||
*.o
|
|
@ -0,0 +1 @@
|
|||
genius
|
|
@ -1,4 +1,4 @@
|
|||
build := optimize
|
||||
build := performance
|
||||
include ../nall/GNUmakefile
|
||||
|
||||
binary := application
|
||||
|
@ -8,7 +8,6 @@ objects := libco emulator audio video resource
|
|||
flags += -I. -I..
|
||||
|
||||
ifeq ($(platform),windows)
|
||||
link += $(if $(call streq,$(console),true),-mconsole,-mwindows)
|
||||
ifeq ($(binary),application)
|
||||
link += -mthreads -lpthread -luuid -lkernel32 -luser32 -lgdi32 -lcomctl32 -lcomdlg32 -lshell32
|
||||
link += -Wl,-enable-auto-import
|
||||
|
@ -61,5 +60,5 @@ ui := target-$(target)
|
|||
include $(ui)/GNUmakefile
|
||||
|
||||
clean:
|
||||
-@$(call delete,out/*)
|
||||
-@$(call delete,obj/*)
|
||||
$(call rm,out/*)
|
||||
$(call rm,obj/*)
|
||||
|
|
|
@ -12,7 +12,7 @@ using namespace nall;
|
|||
|
||||
namespace Emulator {
|
||||
static const string Name = "higan";
|
||||
static const string Version = "106.01";
|
||||
static const string Version = "106.02";
|
||||
static const string Author = "byuu";
|
||||
static const string License = "GPLv3";
|
||||
static const string Website = "https://byuu.org/";
|
||||
|
|
|
@ -66,6 +66,7 @@ private:
|
|||
auto loadSufamiTurboB() -> bool;
|
||||
|
||||
//load.cpp
|
||||
auto loadBoard(Markup::Node) -> Markup::Node;
|
||||
auto loadCartridge(Markup::Node) -> void;
|
||||
auto loadGameBoy(Markup::Node) -> void;
|
||||
auto loadBSMemory(Markup::Node) -> void;
|
||||
|
|
|
@ -1,6 +1,61 @@
|
|||
auto Cartridge::loadBoard(Markup::Node node) -> Markup::Node {
|
||||
string output;
|
||||
|
||||
auto region = node["game/region"].text();
|
||||
auto board = node["game/board"].text();
|
||||
board.trimLeft("SHVC-", 1L);
|
||||
board.trimLeft("SNSP-", 1L);
|
||||
board.trimLeft("MAXI-", 1L);
|
||||
board.trimLeft("MJSC-", 1L);
|
||||
board.trimLeft("EA-", 1L);
|
||||
|
||||
if(auto fp = platform->open(ID::System, "boards.bml", File::Read, File::Required)) {
|
||||
auto document = BML::unserialize(fp->reads());
|
||||
for(auto leaf : document.find("board")) {
|
||||
auto id = leaf["id"].text();
|
||||
bool matched = id == board;
|
||||
if(!matched && id.match("*(*)*")) {
|
||||
auto part = id.transform("()", "||").split("|");
|
||||
for(auto& revision : part(1).split(",")) {
|
||||
if(string{part(0), revision, part(2)} == board) matched = true;
|
||||
}
|
||||
}
|
||||
if(!matched) continue;
|
||||
if(region.endsWith("-USA")
|
||||
|| region.endsWith("-CAN")
|
||||
|| region.endsWith("-JPN")
|
||||
|| region.endsWith("-KOR")
|
||||
|| region == "NTSC") {
|
||||
output.append("region=ntsc\n");
|
||||
} else {
|
||||
output.append("region=pal\n");
|
||||
}
|
||||
uint counter = 0;
|
||||
for(auto& line : leaf.text().split("\n")) {
|
||||
if(line.endsWith("rom") || line.endsWith("ram")) {
|
||||
auto memory = node.find("game/memory");
|
||||
if(counter < memory.size()) {
|
||||
line.append(" name=", memory[counter]["name"].text());
|
||||
line.append(" size=", memory[counter]["size"].text());
|
||||
if(memory[counter]["type"].text() == "RAM") line.append(" volatile");
|
||||
counter++;
|
||||
}
|
||||
}
|
||||
output.append(line, "\n");
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
print(output, "\n");
|
||||
return BML::unserialize(output);
|
||||
}
|
||||
|
||||
auto Cartridge::loadCartridge(Markup::Node node) -> void {
|
||||
information.title.cartridge = node["information/title"].text();
|
||||
information.title.cartridge = node["game/label"].text();
|
||||
|
||||
auto board = node["board"];
|
||||
if(!board) board = loadBoard(node);
|
||||
if(region() == "Auto") {
|
||||
if(board["region"].text() == "ntsc") information.region = "NTSC";
|
||||
if(board["region"].text() == "pal") information.region = "PAL";
|
||||
|
|
|
@ -0,0 +1,407 @@
|
|||
database type=sfc-boards revision=2017-12-29
|
||||
|
||||
board id:1A0N-(01,02,10,20,30)
|
||||
:rom
|
||||
: map address=00-7d,80-ff:8000-ffff mask=0x8000
|
||||
: map address=40-7d,c0-ff:0000-7fff mask=0x8000
|
||||
|
||||
board id:1A1B-(04,05,06)
|
||||
:rom
|
||||
: map address=00-1f,80-9f:8000-ffff mask=0x8000
|
||||
:ram
|
||||
: map address=70-7d,f0-ff:0000-ffff
|
||||
|
||||
board id:1A1M-(01,10,11,20)
|
||||
:rom
|
||||
: map address=00-7d,80-ff:8000-ffff mask=0x8000
|
||||
:ram
|
||||
: map address=70-7d,f0-ff:0000-7fff mask=0x8000
|
||||
|
||||
board id:1A3B-(11,12,13)
|
||||
:rom
|
||||
: map address=00-1f,80-9f:8000-ffff mask=0x8000
|
||||
:ram
|
||||
: map address=70-7d,f0-ff:0000-ffff
|
||||
|
||||
board id:1A3B-20
|
||||
:rom
|
||||
: map address=00-7d,80-ff:8000-ffff mask=0x8000
|
||||
:ram
|
||||
: map address=70-7d,f0-ff:0000-7fff mask=0x8000
|
||||
|
||||
board id:1A3M-(10,20,21,30)
|
||||
:rom
|
||||
: map address=00-7d,80-ff:8000-ffff mask=0x8000
|
||||
:ram
|
||||
: map address=70-7d,f0-ff:0000-7fff mask=0x8000
|
||||
|
||||
board id:1A5B-(02,04)
|
||||
:rom
|
||||
: map address=00-1f,80-9f:8000-ffff mask=0x8000
|
||||
:ram
|
||||
: map address=70-7d,f0-ff:0000-ffff
|
||||
|
||||
board id:1A5M-(01,11,20)
|
||||
:rom
|
||||
: map address=00-7d,80-ff:8000-ffff mask=0x8000
|
||||
:ram
|
||||
: map address=70-7d,f0-ff:0000-7fff mask=0x8000
|
||||
|
||||
board id:1B0N-(02,03,10)
|
||||
:rom
|
||||
: map address=00-1f,80-9f:8000-ffff mask=0x8000
|
||||
:necdsp model=uPD7725 frequency=8000000
|
||||
: map address=30-3f,b0-bf:8000-ffff mask=0x3fff
|
||||
: prom
|
||||
: drom
|
||||
: dram
|
||||
|
||||
board id:1B5B-02
|
||||
:rom
|
||||
: map address=00-1f,80-9f:8000-ffff mask=0x8000
|
||||
:ram
|
||||
: map address=70-7d,f0-ff:0000-ffff
|
||||
:necdsp model=uPD7725 frequency=8000000
|
||||
: map address=20-3f,a0-bf:8000-ffff mask=0x3fff
|
||||
: prom
|
||||
: drom
|
||||
: dram
|
||||
|
||||
board id:1C0N
|
||||
:superfx
|
||||
: map address=00-3f,80-bf:3000-34ff
|
||||
: rom
|
||||
: map address=00-1f,80-9f:8000-ffff mask=0x8000
|
||||
: ram
|
||||
: map address=60-7d,e0-ff:0000-ffff
|
||||
|
||||
board id:1C0N5S-01
|
||||
:superfx
|
||||
: map address=00-3f,80-bf:3000-34ff
|
||||
: rom
|
||||
: map address=00-1f,80-9f:8000-ffff mask=0x8000
|
||||
: ram
|
||||
: map address=60-7d,e0-ff:0000-ffff
|
||||
|
||||
board id:1CA0N5S-01
|
||||
:superfx
|
||||
: map address=00-3f,80-bf:3000-34ff
|
||||
: rom
|
||||
: map address=00-3f,80-bf:8000-ffff mask=0x8000
|
||||
: map address=40-5f,c0-df:0000-ffff
|
||||
: ram
|
||||
: map address=00-3f,80-bf:6000-7fff size=0x2000
|
||||
: map address=70-71,f0-f1:0000-ffff
|
||||
|
||||
board id:1CA0N6S-01
|
||||
:superfx
|
||||
: map address=00-3f,80-bf:3000-34ff
|
||||
: rom
|
||||
: map address=00-3f,80-bf:8000-ffff mask=0x8000
|
||||
: map address=40-5f,c0-df:0000-ffff
|
||||
: ram
|
||||
: map address=00-3f,80-bf:6000-7fff size=0x2000
|
||||
: map address=70-71,f0-f1:0000-ffff
|
||||
|
||||
board id:1CA6B-01
|
||||
:superfx
|
||||
: map address=00-3f,80-bf:3000-34ff
|
||||
: rom
|
||||
: map address=00-3f,80-bf:8000-ffff mask=0x8000
|
||||
: map address=40-5f,c0-df:0000-ffff
|
||||
: ram
|
||||
: map address=00-3f,80-bf:6000-7fff size=0x2000
|
||||
: map address=70-71,f0-f1:0000-ffff
|
||||
|
||||
board id:1CB0N7S-01
|
||||
:superfx
|
||||
: map address=00-3f,80-bf:3000-34ff
|
||||
: rom
|
||||
: map address=00-3f:8000-ffff mask=0x8000
|
||||
: map address=40-5f:0000-ffff
|
||||
: ram
|
||||
: map address=00-3f,80-bf:6000-7fff size=0x2000
|
||||
: map address=70-71:0000-ffff
|
||||
|
||||
board id:1CB5B-20
|
||||
:superfx
|
||||
: map address=00-3f,80-bf:3000-34ff
|
||||
: rom
|
||||
: map address=00-3f:8000-ffff mask=0x8000
|
||||
: map address=40-5f:0000-ffff
|
||||
: ram
|
||||
: map address=00-3f,80-bf:6000-7fff size=0x2000
|
||||
: map address=70-71:0000-ffff
|
||||
|
||||
board id:1CB7B-01
|
||||
:superfx
|
||||
: map address=00-3f,80-bf:3000-34ff
|
||||
: rom
|
||||
: map address=00-3f:8000-ffff mask=0x8000
|
||||
: map address=40-5f:0000-ffff
|
||||
: ram
|
||||
: map address=00-3f,80-bf:6000-7fff size=0x2000
|
||||
: map address=70-71:0000-ffff
|
||||
|
||||
board id:1DC0N-01
|
||||
:hitachidsp model=HG51B169 frequency=20000000
|
||||
: map address=00-3f,80-bf:6c00-6fff,7c00-7fff
|
||||
: rom
|
||||
: map address=00-3f,80-bf:8000-ffff mask=0x8000
|
||||
: ram
|
||||
: map address=70-77:0000-7fff mask=0x8000
|
||||
: drom
|
||||
: dram
|
||||
: map address=00-3f,80-bf:6000-6bff,7000-7bff mask=0xf000
|
||||
|
||||
board id:1DS0B-20
|
||||
:rom
|
||||
: map address=00-7d,80-ff:8000-ffff mask=0x8000
|
||||
:necdsp model=uPD96050 frequency=11000000
|
||||
: map address=60-67,e0-e7:0000-3fff
|
||||
: prom
|
||||
: drom
|
||||
: dram
|
||||
: map address=68-6f,e8-ef:0000-7fff mask=0x8000
|
||||
|
||||
board id:1J0N-(01,10,20)
|
||||
:rom
|
||||
: map address=00-3f,80-bf:8000-ffff
|
||||
: map address=40-7d,c0-ff:0000-ffff
|
||||
|
||||
board id:1J1M-(11,20)
|
||||
:rom
|
||||
: map address=00-3f,80-bf:8000-ffff
|
||||
: map address=40-7d,c0-ff:0000-ffff
|
||||
:ram
|
||||
: map address=20-3f,a0-bf:6000-7fff mask=0xe000
|
||||
|
||||
board id:1J3B-01
|
||||
:rom
|
||||
: map address=00-3f,80-bf:8000-ffff
|
||||
: map address=40-7d,c0-ff:0000-ffff
|
||||
:ram
|
||||
: map address=20-3f,a0-bf:6000-7fff mask=0xe000
|
||||
|
||||
board id:1J3M-(01,11,20)
|
||||
:rom
|
||||
: map address=00-3f,80-bf:8000-ffff
|
||||
: map address=40-7d,c0-ff:0000-ffff
|
||||
:ram
|
||||
: map address=20-3f,a0-bf:6000-7fff mask=0xe000
|
||||
|
||||
board id:1J5M-(11,20)
|
||||
:rom
|
||||
: map address=00-3f,80-bf:8000-ffff
|
||||
: map address=40-7d,c0-ff:0000-ffff
|
||||
:ram
|
||||
: map address=20-3f,a0-bf:6000-7fff mask=0xe000
|
||||
|
||||
board id:1K0N-01
|
||||
:rom
|
||||
: map address=00-3f,80-bf:8000-ffff
|
||||
: map address=40-7d,c0-ff:0000-ffff
|
||||
:necdsp model=uPD7725 frequency=8000000
|
||||
: map address=00-1f,80-9f:6000-7fff mask=0xfff
|
||||
: prom
|
||||
: drom
|
||||
: dram
|
||||
|
||||
board id:1K1B-01
|
||||
:rom
|
||||
: map address=00-3f,80-bf:8000-ffff
|
||||
: map address=40-7d,c0-ff:0000-ffff
|
||||
:ram
|
||||
: map address=20-3f,a0-bf:6000-7fff mask=0xe000
|
||||
:necdsp model=uPD7725 frequency=8000000
|
||||
: map address=00-1f,80-9f:6000-7fff mask=0xfff
|
||||
: prom
|
||||
: drom
|
||||
: dram
|
||||
|
||||
board id:1L0N3S-01
|
||||
:sa1
|
||||
: map address=00-3f,80-bf:2200-23ff
|
||||
: rom
|
||||
: map address=00-3f,80-bf:8000-ffff mask=0x408000
|
||||
: map address=c0-ff:0000-ffff
|
||||
: bwram
|
||||
: map address=00-3f,80-bf:6000-7fff size=0x2000
|
||||
: map address=40-4f:0000-ffff
|
||||
: iram
|
||||
: map address=00-3f,80-bf:3000-37ff size=0x800
|
||||
|
||||
board id:1L3B-(02,11)
|
||||
:sa1
|
||||
: map address=00-3f,80-bf:2200-23ff
|
||||
: rom
|
||||
: map address=00-3f,80-bf:8000-ffff mask=0x408000
|
||||
: map address=c0-ff:0000-ffff
|
||||
: bwram
|
||||
: map address=00-3f,80-bf:6000-7fff size=0x2000
|
||||
: map address=40-4f:0000-ffff
|
||||
: iram
|
||||
: map address=00-3f,80-bf:3000-37ff size=0x800
|
||||
|
||||
board id:1L5B-(11,20)
|
||||
:sa1
|
||||
: map address=00-3f,80-bf:2200-23ff
|
||||
: rom
|
||||
: map address=00-3f,80-bf:8000-ffff mask=0x408000
|
||||
: map address=c0-ff:0000-ffff
|
||||
: bwram
|
||||
: map address=00-3f,80-bf:6000-7fff size=0x2000
|
||||
: map address=40-4f:0000-ffff
|
||||
: iram
|
||||
: map address=00-3f,80-bf:3000-37ff size=0x800
|
||||
|
||||
board id:1N0N-01
|
||||
:sdd1
|
||||
: map address=00-3f,80-bf:4800-480f
|
||||
: rom
|
||||
: map address=00-3f,80-bf:8000-ffff
|
||||
: map address=c0-ff:0000-ffff
|
||||
|
||||
board id:2A0N-(01,10,11,20)
|
||||
:rom
|
||||
: map address=00-7d,80-ff:8000-ffff mask=0x8000
|
||||
: map address=40-7d,c0-ff:0000-7fff mask=0x8000
|
||||
|
||||
board id:2A1M-01
|
||||
:rom
|
||||
: map address=00-7d,80-ff:8000-ffff mask=0x8000
|
||||
:ram
|
||||
: map address=70-7d,f0-ff:0000-7fff mask=0x8000
|
||||
|
||||
board id:2A3B-01
|
||||
:rom
|
||||
: map address=00-3f,80-bf:8000-ffff mask=0x8000
|
||||
:ram
|
||||
: map address=70-7d,f0-ff:0000-7fff mask=0x8000
|
||||
|
||||
board id:2A3M-01#R
|
||||
:rom
|
||||
: map address=00-3f,80-bf:8000-ffff mask=0x8000
|
||||
:ram
|
||||
: map address=70-7d,f0-ff:0000-7fff mask=0x8000
|
||||
|
||||
board id:2A3M-(01,11,20)
|
||||
:rom
|
||||
: map address=00-7d,80-ff:8000-ffff mask=0x8000
|
||||
:ram
|
||||
: map address=70-7d,f0-ff:0000-7fff mask=0x8000
|
||||
|
||||
board id:2A5M-01
|
||||
:rom
|
||||
: map address=00-7d,80-ff:8000-ffff mask=0x8000
|
||||
:ram
|
||||
: map address=70-7d,f0-ff:0000-7fff mask=0x8000
|
||||
|
||||
board id:2B3B-01
|
||||
:rom
|
||||
: map address=00-3f,80-bf:8000-ffff mask=0x8000
|
||||
:ram
|
||||
: map address=70-7d,f0-ff:0000-7fff mask=0x8000
|
||||
:necdsp model=uPD7725 frequency=8000000
|
||||
: map address=60-6f,e0-ef:0000-7fff mask=0x3fff
|
||||
: prom
|
||||
: drom
|
||||
: dram
|
||||
|
||||
board id:2DC0N-01
|
||||
:hitachidsp model=HG51B169 frequency=20000000
|
||||
: map address=00-3f,80-bf:6c00-6fff,7c00-7fff
|
||||
: rom
|
||||
: map address=00-3f,80-bf:8000-ffff mask=0x8000
|
||||
: ram
|
||||
: map address=70-77:0000-7fff mask=0x8000
|
||||
: drom
|
||||
: dram
|
||||
: map address=00-3f,80-bf:6000-6bff,7000-7bff mask=0xf000
|
||||
|
||||
board id:2E3M-01
|
||||
:rom
|
||||
: map address=00-3f,80-bf:8000-ffff mask=0x8000
|
||||
:obc1
|
||||
: map address=00-3f,80-bf:6000-7fff mask=0xe000
|
||||
: map address=70-71,f0-f1:6000-7fff,e000-ffff mask=0xe000
|
||||
: ram
|
||||
|
||||
board id:2J0N-(01,10,11,20)
|
||||
:rom
|
||||
: map address=00-3f,80-bf:8000-ffff
|
||||
: map address=40-7d,c0-ff:0000-ffff
|
||||
|
||||
board id:2J3M-(01,11,20)
|
||||
:rom
|
||||
: map address=00-3f,80-bf:8000-ffff
|
||||
: map address=40-7d,c0-ff:0000-ffff
|
||||
:ram
|
||||
: map address=10-1f,30-3f,90-9f,b0-bf:6000-7fff mask=0xe000
|
||||
|
||||
board id:2J5M-01
|
||||
:rom
|
||||
: map address=00-3f,80-bf:8000-ffff
|
||||
: map address=40-7d,c0-ff:0000-ffff
|
||||
:ram
|
||||
: map address=10-1f,30-3f,90-9f,b0-bf:6000-7fff mask=0xe000
|
||||
|
||||
board id:3J0N-01
|
||||
:rom
|
||||
: map address=00-2f,80-af:8000-ffff
|
||||
: map address=40-6f,c0-ef:0000-ffff
|
||||
|
||||
board id:BA0N-(01,10)
|
||||
:rom
|
||||
: map address=00-7d,80-ff:8000-ffff mask=0x8000
|
||||
: map address=40-7d,c0-ff:0000-7fff mask=0x8000
|
||||
|
||||
board id:BA1M-01
|
||||
:rom
|
||||
: map address=00-7d,80-ff:8000-ffff mask=0x8000
|
||||
:ram
|
||||
: map address=70-7d,f0-ff:0000-7fff mask=0x8000
|
||||
|
||||
board id:BA3M-(01,10)
|
||||
:rom
|
||||
: map address=00-7d,80-ff:8000-ffff mask=0x8000
|
||||
:ram
|
||||
: map address=70-7d,f0-ff:0000-7fff mask=0x8000
|
||||
|
||||
board id:BJ0N-(01,20)
|
||||
:rom
|
||||
: map address=00-3f,80-bf:8000-ffff
|
||||
: map address=40-7d,c0-ff:0000-ffff
|
||||
|
||||
board id:BJ1M-10
|
||||
:rom
|
||||
: map address=00-3f,80-bf:8000-ffff
|
||||
: map address=40-7d,c0-ff:0000-ffff
|
||||
:ram
|
||||
: map address=20-3f,a0-bf:6000-7fff mask=0xe000
|
||||
|
||||
board id:BJ3M-10
|
||||
:rom
|
||||
: map address=00-3f,80-bf:8000-ffff
|
||||
: map address=40-7d,c0-ff:0000-ffff
|
||||
:ram
|
||||
: map address=20-3f,a0-bf:6000-7fff mask=0xe000
|
||||
|
||||
board id:SGB-R-10
|
||||
:rom
|
||||
: map address=00-7d,80-ff:8000-ffff mask=0x8000
|
||||
: map address=40-7d,c0-ff:0000-7fff mask=0x8000
|
||||
:icd2 revision=1
|
||||
: map address=00-3f,80-bf:6000-67ff,7000-7fff
|
||||
: rom
|
||||
|
||||
board id:YA0N-01
|
||||
:rom
|
||||
: map address=00-7d,80-ff:8000-ffff mask=0x8000
|
||||
: map address=40-7d,c0-ff:0000-7fff mask=0x8000
|
||||
|
||||
board id:YJ0N-01
|
||||
:rom
|
||||
: map address=00-3f,80-bf:8000-ffff
|
||||
: map address=40-7d,c0-ff:0000-ffff
|
||||
|
|
@ -69,7 +69,7 @@ obj/ui-resource.o:
|
|||
build: $(objects)
|
||||
$(strip $(compiler) -o out/$(name) $(objects) $(link))
|
||||
ifeq ($(platform),macos)
|
||||
@if [ -d out/$(name).app ]; then rm -r out/$(name).app; fi
|
||||
rm -rf out/$(name).app
|
||||
mkdir -p out/$(name).app/Contents/MacOS/
|
||||
mkdir -p out/$(name).app/Contents/Resources/
|
||||
mv out/$(name) out/$(name).app/Contents/MacOS/$(name)
|
||||
|
@ -102,9 +102,9 @@ ifeq ($(shell id -un),root)
|
|||
$(error "make uninstall should not be run as root")
|
||||
else ifeq ($(platform),windows)
|
||||
else ifeq ($(platform),macos)
|
||||
if [ -d /Applications/$(name).app ]; then rm -r /Applications/$(name).app; fi
|
||||
rm -rf /Applications/$(name).app
|
||||
else ifneq ($(filter $(platform),linux bsd),)
|
||||
if [ -f $(prefix)/bin/$(name) ]; then rm $(prefix)/bin/$(name); fi
|
||||
if [ -f $(prefix)/share/applications/$(name).desktop ]; then rm $(prefix)/share/applications/$(name).desktop; fi
|
||||
if [ -f $(prefix)/share/icons/$(name).png ]; then rm $(prefix)/share/icons/$(name).png; fi
|
||||
rm -f $(prefix)/bin/$(name)
|
||||
rm -f $(prefix)/share/applications/$(name).desktop
|
||||
rm -f $(prefix)/share/icons/$(name).png
|
||||
endif
|
||||
|
|
|
@ -60,7 +60,7 @@ auto BrowserDialogWindow::accept() -> void {
|
|||
if(!name && batched) name = batched.left()->cell(0)->text();
|
||||
if(!name || isFolder(name)) return;
|
||||
if(file::exists({state.path, name})) {
|
||||
if(MessageDialog("File already exists; overwrite it?").question() != "Yes") return;
|
||||
if(MessageDialog("File already exists. Overwrite it?").question() != "Yes") return;
|
||||
}
|
||||
response.selected.append(string{state.path, name});
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -1,14 +1,9 @@
|
|||
build := optimize
|
||||
build := performance
|
||||
include ../nall/GNUmakefile
|
||||
include ../hiro/GNUmakefile
|
||||
|
||||
name := icarus
|
||||
flags += -I..
|
||||
link +=
|
||||
|
||||
ifeq ($(platform),windows)
|
||||
link += -mwindows
|
||||
endif
|
||||
|
||||
objects := obj/hiro.o
|
||||
objects += obj/icarus.o
|
||||
|
@ -17,7 +12,7 @@ objects += $(if $(call streq,$(platform),windows),obj/resource.o)
|
|||
all: $(objects)
|
||||
$(strip $(compiler) -o out/$(name) $(objects) $(link) $(hirolink))
|
||||
ifeq ($(platform),macos)
|
||||
@if [ -d out/$(name).app ]; then rm -r out/$(name).app; fi
|
||||
rm -rf out/$(name).app
|
||||
mkdir -p out/$(name).app/Contents/MacOS/
|
||||
mkdir -p out/$(name).app/Contents/Resources/
|
||||
mv out/$(name) out/$(name).app/Contents/MacOS/$(name)
|
||||
|
@ -32,14 +27,14 @@ obj/icarus.o: icarus.cpp $(call rwildcard,core/) $(call rwildcard,heuristics/) $
|
|||
$(compiler) $(cppflags) $(flags) -o obj/icarus.o -c icarus.cpp
|
||||
|
||||
obj/resource.o:
|
||||
$(windres) data/icarus.rc obj/resource.o
|
||||
$(windres) data/$(name).rc obj/resource.o
|
||||
|
||||
clean:
|
||||
ifeq ($(platform),macos)
|
||||
@if [ -d out/$(name).app ]; then rm out/$(name).app; fi
|
||||
rm -rf out/$(name).app
|
||||
endif
|
||||
-@$(call delete,obj/*)
|
||||
-@$(call delete,out/*)
|
||||
$(call rm,obj/*)
|
||||
$(call rm,out/*)
|
||||
|
||||
install:
|
||||
ifeq ($(platform),macos)
|
||||
|
@ -49,17 +44,17 @@ else ifneq ($(filter $(platform),linux bsd),)
|
|||
mkdir -p $(prefix)/share/applications/
|
||||
mkdir -p $(prefix)/share/icons/
|
||||
mkdir -p $(prefix)/share/$(name)/Database/
|
||||
if [ -f out/$(name) ]; then cp out/$(name) $(prefix)/bin/$(name); fi
|
||||
cp -R Database/* $(prefix)/share/$(name)/Database/
|
||||
cp out/$(name) $(prefix)/bin/$(name)
|
||||
cp data/$(name).desktop $(prefix)/share/applications/$(name).desktop
|
||||
cp data/$(name).png $(prefix)/share/icons/$(name).png
|
||||
cp -R Database/* $(prefix)/share/$(name)/Database/
|
||||
endif
|
||||
|
||||
uninstall:
|
||||
ifeq ($(platform),macos)
|
||||
if [ -d /Applications/$(name).app ]; then rm -r /Applications/$(name).app; fi
|
||||
rm -rf /Applications/$(name).app
|
||||
else ifneq ($(filter $(platform),linux bsd),)
|
||||
if [ -f $(prefix)/bin/$(name) ]; then rm $(prefix)/bin/$(name); fi
|
||||
if [ -f $(prefix)/share/applications/$(name).desktop ]; then rm $(prefix)/share/applications/$(name).desktop; fi
|
||||
if [ -f $(prefix)/share/icons/$(name).png ]; then rm $(prefix)/share/icons/$(name).png; fi
|
||||
rm -f $(prefix)/bin/$(name)
|
||||
rm -f $(prefix)/share/applications/$(name).desktop
|
||||
rm -f $(prefix)/share/icons/$(name).png
|
||||
endif
|
||||
|
|
|
@ -12,13 +12,12 @@ auto Icarus::superFamicomManifest(string location) -> string {
|
|||
|
||||
auto Icarus::superFamicomManifest(vector<uint8_t>& buffer, string location) -> string {
|
||||
string markup;
|
||||
string digest = Hash::SHA256(buffer.data(), buffer.size()).digest();
|
||||
string digest = Hash::SHA256(buffer).digest();
|
||||
|
||||
if(settings["icarus/UseDatabase"].boolean() && !markup) {
|
||||
for(auto node : database.superFamicom) {
|
||||
if(node["sha256"].text() == digest) {
|
||||
markup.append(node.text(), "\n sha256: ", digest, "\n");
|
||||
break;
|
||||
for(auto game : database.superFamicom.find("game")) {
|
||||
if(game["sha256"].text() == digest) {
|
||||
return BML::serialize(game);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -28,10 +27,10 @@ auto Icarus::superFamicomManifest(vector<uint8_t>& buffer, string location) -> s
|
|||
SuperFamicomCartridge cartridge{buffer.data(), buffer.size(), hasMSU1};
|
||||
if(markup = cartridge.markup) {
|
||||
markup.append("\n");
|
||||
markup.append("information\n");
|
||||
markup.append(" region: ", cartridge.region == SuperFamicomCartridge::Region::NTSC ? "NTSC" : "PAL", "\n");
|
||||
markup.append(" title: ", Location::prefix(location), "\n");
|
||||
markup.append("game\n");
|
||||
markup.append(" sha256: ", digest, "\n");
|
||||
markup.append(" region: ", cartridge.region == SuperFamicomCartridge::Region::NTSC ? "NTSC" : "PAL", "\n");
|
||||
markup.append(" label: ", Location::prefix(location), "\n");
|
||||
markup.append(" note: ", "heuristically generated by icarus\n");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,11 +2,11 @@
|
|||
MAKEFLAGS := Rr
|
||||
.SUFFIXES:
|
||||
|
||||
[0-9] = 0 1 2 3 4 5 6 7 8 9
|
||||
[A-Z] = A B C D E F G H I J K L M N O P Q R S T U V W X Y Z
|
||||
[a-z] = a b c d e f g h i j k l m n o p q r s t u v w x y z
|
||||
[0-9] = 0 1 2 3 4 5 6 7 8 9
|
||||
[markup] = ` ~ ! @ \# $$ % ^ & * ( ) - _ = + [ { ] } \ | ; : ' " , < . > / ?
|
||||
[all] = $([A-Z]) $([a-z]) $([0-9]) $([markup])
|
||||
[all] = $([0-9]) $([A-Z]) $([a-z]) $([markup])
|
||||
[space] :=
|
||||
[space] +=
|
||||
|
||||
|
@ -15,22 +15,28 @@ ifeq ($(platform),)
|
|||
uname := $(shell uname -s)
|
||||
ifeq ($(uname),)
|
||||
platform := windows
|
||||
delete = del $(subst /,\,$1)
|
||||
rm = del /q $(subst /,\,$1)
|
||||
rmdir = del /s /q $(subst /,\,$1) && if exist $(subst /,\,$1) (rmdir /s /q $(subst /,\,$1))
|
||||
else ifneq ($(findstring Windows,$(uname)),)
|
||||
platform := windows
|
||||
delete = del $(subst /,\,$1)
|
||||
rm = del /q $(subst /,\,$1)
|
||||
rmdir = del /s /q $(subst /,\,$1) && if exist $(subst /,\,$1) (rmdir /s /q $(subst /,\,$1))
|
||||
else ifneq ($(findstring _NT,$(uname)),)
|
||||
platform := windows
|
||||
delete = del $(subst /,\,$1)
|
||||
rm = del /q $(subst /,\,$1)
|
||||
rmdir = del /s /q $(subst /,\,$1) && if exist $(subst /,\,$1) (rmdir /s /q $(subst /,\,$1))
|
||||
else ifneq ($(findstring Darwin,$(uname)),)
|
||||
platform := macos
|
||||
delete = rm -f $1
|
||||
rm = rm -f $1
|
||||
rmdir = rm -rf $1
|
||||
else ifneq ($(findstring Linux,$(uname)),)
|
||||
platform := linux
|
||||
delete = rm -f $1
|
||||
rm = rm -f $1
|
||||
rmdir = rm -rf $1
|
||||
else ifneq ($(findstring BSD,$(uname)),)
|
||||
platform := bsd
|
||||
delete = rm -f $1
|
||||
rm = rm -f $1
|
||||
rmdir = rm -rf $1
|
||||
else
|
||||
$(error unknown platform, please specify manually.)
|
||||
endif
|
||||
|
@ -59,23 +65,17 @@ ifeq ($(compiler),)
|
|||
endif
|
||||
endif
|
||||
|
||||
# build settings
|
||||
ifeq ($(build),optimize)
|
||||
flags += -O3
|
||||
else ifeq ($(build),release)
|
||||
flags += -O2
|
||||
# build optimization levels
|
||||
ifeq ($(build),debug)
|
||||
flags += -Og -DBUILD_DEBUG
|
||||
else ifeq ($(build),stable)
|
||||
flags += -O1
|
||||
else ifeq ($(build),debug)
|
||||
flags += -g
|
||||
else ifeq ($(build),profile)
|
||||
flags += -pg
|
||||
link += -pg
|
||||
else ifeq ($(build),instrument)
|
||||
flags += -O3 -fprofile-generate
|
||||
link += -lgcov
|
||||
else ifeq ($(build),optimize)
|
||||
flags += -O3 -fprofile-use
|
||||
flags += -O1 -DBUILD_STABLE
|
||||
else ifeq ($(build),size)
|
||||
flags += -Os -DBUILD_SIZE
|
||||
else ifeq ($(build),release)
|
||||
flags += -O2 -DBUILD_RELEASE
|
||||
else ifeq ($(build),performance)
|
||||
flags += -O3 -DBUILD_PERFORMANCE
|
||||
endif
|
||||
|
||||
# clang settings
|
||||
|
|
|
@ -343,7 +343,7 @@ inline auto to_vector(Pair value) -> vector<uint8_t> {
|
|||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
#if 0
|
||||
inline auto hex(const Pair& value, long precision = 0, char padchar = '0') -> string {
|
||||
string text;
|
||||
if(!upper(value)) {
|
||||
|
@ -354,7 +354,7 @@ inline auto hex(const Pair& value, long precision = 0, char padchar = '0') -> st
|
|||
}
|
||||
return pad(text, precision, padchar);
|
||||
}
|
||||
*/
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -15,10 +15,18 @@ struct array {
|
|||
}
|
||||
|
||||
auto operator[](uint index) -> T& {
|
||||
#ifdef DEBUG
|
||||
struct out_of_bounds {};
|
||||
if(index >= Capacity) throw out_of_bounds{};
|
||||
#endif
|
||||
return _pool.t[index];
|
||||
}
|
||||
|
||||
auto operator[](uint index) const -> const T& {
|
||||
#ifdef DEBUG
|
||||
struct out_of_bounds {};
|
||||
if(index >= Capacity) throw out_of_bounds{};
|
||||
#endif
|
||||
return _pool.t[index];
|
||||
}
|
||||
|
||||
|
|
|
@ -47,6 +47,10 @@ struct bitvector {
|
|||
}
|
||||
|
||||
auto get(uint position) const -> bool {
|
||||
#ifdef DEBUG
|
||||
struct out_of_bounds {};
|
||||
if(position >= bits) throw out_of_bounds{};
|
||||
#endif
|
||||
return pool[position >> 3] & (0x80 >> (position & 7));
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,37 @@
|
|||
#pragma once
|
||||
|
||||
#include <nall/arithmetic.hpp>
|
||||
|
||||
namespace nall { namespace Decode {
|
||||
|
||||
template<uint Bits, typename T> inline auto Base(const string& value) -> T {
|
||||
static const string format =
|
||||
Bits == 2 ? "01"
|
||||
: Bits == 8 ? "01234567"
|
||||
: Bits == 10 ? "0123456789"
|
||||
: Bits == 16 ? "0123456789abcdef"
|
||||
: Bits == 32 ? "0123456789abcdefghijklmnopqrstuv"
|
||||
: Bits == 34 ? "023456789abcdefghijkmnopqrstuvwxyz" //1l
|
||||
: Bits == 36 ? "0123456789abcdefghijklmnopqrstuvwxyz"
|
||||
: Bits == 57 ? "23456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz" //01IOl
|
||||
: Bits == 62 ? "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
|
||||
: Bits == 64 ? "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz{}"
|
||||
: Bits == 85 ? "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz!#$%()+,-.:;=@[]^_`{|}~" //\ "&'*/<>?
|
||||
: "";
|
||||
static bool initialized = false;
|
||||
static uint8_t lookup[256] = {0};
|
||||
if(!initialized) {
|
||||
initialized = true;
|
||||
for(uint n : range(format.size())) {
|
||||
lookup[format[n]] = n;
|
||||
}
|
||||
}
|
||||
|
||||
T result = 0;
|
||||
for(auto byte : value) {
|
||||
result = result * Bits + lookup[byte];
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
}}
|
|
@ -1,23 +0,0 @@
|
|||
#pragma once
|
||||
|
||||
#include <nall/arithmetic.hpp>
|
||||
|
||||
namespace nall { namespace Decode {
|
||||
|
||||
template<typename T> inline auto Base57(const string& value) -> T {
|
||||
T result = 0;
|
||||
for(auto n : rrange(value.size())) {
|
||||
auto byte = value[n];
|
||||
if(byte >= '2' && byte <= '9') byte -= '2' - 0;
|
||||
else if(byte >= 'A' && byte <= 'H') byte -= 'A' - 8;
|
||||
else if(byte >= 'J' && byte <= 'N') byte -= 'J' - 16;
|
||||
else if(byte >= 'P' && byte <= 'Z') byte -= 'P' - 21;
|
||||
else if(byte >= 'a' && byte <= 'k') byte -= 'a' - 32;
|
||||
else if(byte >= 'm' && byte <= 'z') byte -= 'm' - 43;
|
||||
else return 0;
|
||||
result = result * 57 + byte;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
}}
|
|
@ -3,23 +3,23 @@
|
|||
namespace nall { namespace Decode {
|
||||
|
||||
inline auto Base64(const string& text) -> vector<uint8_t> {
|
||||
auto value = [](char n) -> uint8_t {
|
||||
if(n >= 'A' && n <= 'Z') return n - 'A' + 0;
|
||||
if(n >= 'a' && n <= 'z') return n - 'a' + 26;
|
||||
if(n >= '0' && n <= '9') return n - '0' + 52;
|
||||
if(n == '+' || n == '-') return 62;
|
||||
if(n == '/' || n == '_') return 63;
|
||||
return 64; //error code
|
||||
};
|
||||
static bool initialized = false;
|
||||
static uint8_t lookup[256] = {0};
|
||||
if(!initialized) {
|
||||
initialized = true;
|
||||
for(uint n : range(26)) lookup['A' + n] = n;
|
||||
for(uint n : range(26)) lookup['a' + n] = n + 26;
|
||||
for(uint n : range(10)) lookup['0' + n] = n + 52;
|
||||
lookup['+'] = lookup['-'] = 62;
|
||||
lookup['/'] = lookup['_'] = 63;
|
||||
}
|
||||
|
||||
vector<uint8_t> result;
|
||||
|
||||
uint8_t buffer, output;
|
||||
for(unsigned i = 0; i < text.size(); i++) {
|
||||
uint8_t buffer = value(text[i]);
|
||||
if(buffer > 63) break;
|
||||
for(uint n : range(text.size())) {
|
||||
uint8_t buffer = lookup[text[n]];
|
||||
|
||||
switch(i & 3) {
|
||||
switch(n & 3) {
|
||||
case 0:
|
||||
output = buffer << 2;
|
||||
break;
|
||||
|
@ -40,6 +40,7 @@ inline auto Base64(const string& text) -> vector<uint8_t> {
|
|||
}
|
||||
}
|
||||
|
||||
if(text.size() & 3) result.append(output | buffer);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,33 @@
|
|||
#pragma once
|
||||
|
||||
#include <nall/arithmetic.hpp>
|
||||
|
||||
namespace nall { namespace Encode {
|
||||
|
||||
template<uint Bits, typename T> inline auto Base(T value) -> string {
|
||||
static const string format =
|
||||
Bits == 2 ? "01"
|
||||
: Bits == 8 ? "01234567"
|
||||
: Bits == 10 ? "0123456789"
|
||||
: Bits == 16 ? "0123456789abcdef"
|
||||
: Bits == 32 ? "0123456789abcdefghijklmnopqrstuv"
|
||||
: Bits == 34 ? "023456789abcdefghijkmnopqrstuvwxyz" //1l
|
||||
: Bits == 36 ? "0123456789abcdefghijklmnopqrstuvwxyz"
|
||||
: Bits == 57 ? "23456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz" //01IOl
|
||||
: Bits == 62 ? "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
|
||||
: Bits == 64 ? "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz{}"
|
||||
: Bits == 85 ? "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz!#$%()+,-.:;=@[]^_`{|}~" //\ "&'*/<>?
|
||||
: "";
|
||||
static const uint size = ceil(sizeof(T) * 8 / log2(Bits));
|
||||
|
||||
string result;
|
||||
result.resize(size);
|
||||
char* data = result.get() + size;
|
||||
for(auto byte : result) {
|
||||
*--data = format[value % Bits];
|
||||
value /= Bits;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
}}
|
|
@ -1,19 +0,0 @@
|
|||
#pragma once
|
||||
|
||||
#include <nall/arithmetic.hpp>
|
||||
|
||||
namespace nall { namespace Encode {
|
||||
|
||||
template<typename T> inline auto Base57(T value) -> string {
|
||||
static const char lookup[] = "23456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz";
|
||||
static const uint size = ceil(sizeof(T) * 8 / log2(57));
|
||||
|
||||
string result;
|
||||
for(auto n : range(size)) {
|
||||
result.append(lookup[value % 57]);
|
||||
value /= 57;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
}}
|
|
@ -2,14 +2,15 @@
|
|||
|
||||
namespace nall { namespace Encode {
|
||||
|
||||
inline auto Base64(const void* vdata, unsigned size, const string& format = "MIME") -> string {
|
||||
auto data = (const uint8_t*)vdata;
|
||||
vector<uint8_t> result;
|
||||
|
||||
char lookup[65];
|
||||
for(unsigned n = 0; n < 26; n++) lookup[ 0 + n] = 'A' + n;
|
||||
for(unsigned n = 0; n < 26; n++) lookup[26 + n] = 'a' + n;
|
||||
for(unsigned n = 0; n < 10; n++) lookup[52 + n] = '0' + n;
|
||||
inline auto Base64(const void* vdata, uint size, const string& format = "MIME") -> string {
|
||||
static bool initialized = false;
|
||||
static char lookup[65] = {0};
|
||||
if(!initialized) {
|
||||
initialized = true;
|
||||
for(uint n : range(26)) lookup[n + 0] = 'A' + n;
|
||||
for(uint n : range(26)) lookup[n + 26] = 'a' + n;
|
||||
for(uint n : range(10)) lookup[n + 52] = '0' + n;
|
||||
}
|
||||
|
||||
if(format == "MIME") {
|
||||
lookup[62] = '+';
|
||||
|
@ -21,37 +22,36 @@ inline auto Base64(const void* vdata, unsigned size, const string& format = "MIM
|
|||
lookup[64] = 0;
|
||||
} else return "";
|
||||
|
||||
unsigned overflow = (3 - (size % 3)) % 3; //bytes to round to nearest multiple of 3
|
||||
auto data = (const uint8_t*)vdata;
|
||||
uint overflow = (3 - (size % 3)) % 3; //bytes to round to nearest multiple of 3
|
||||
string result;
|
||||
uint8_t buffer;
|
||||
|
||||
for(unsigned i = 0; i < size; i++) {
|
||||
switch(i % 3) {
|
||||
for(uint n : range(size)) {
|
||||
switch(n % 3) {
|
||||
case 0:
|
||||
buffer = data[i] >> 2;
|
||||
result.append(lookup[buffer]);
|
||||
buffer = (data[i] & 3) << 4;
|
||||
buffer = data[n] >> 2;
|
||||
result.append(lookup[buffer]);
|
||||
buffer = (data[n] & 3) << 4;
|
||||
break;
|
||||
|
||||
case 1:
|
||||
buffer |= data[i] >> 4;
|
||||
result.right() = lookup[buffer];
|
||||
buffer = (data[i] & 15) << 2;
|
||||
buffer |= data[n] >> 4;
|
||||
result.append(lookup[buffer]);
|
||||
buffer = (data[n] & 15) << 2;
|
||||
break;
|
||||
|
||||
case 2:
|
||||
buffer |= data[i] >> 6;
|
||||
result.right() = lookup[buffer];
|
||||
buffer = (data[i] & 63);
|
||||
buffer |= data[n] >> 6;
|
||||
result.append(lookup[buffer]);
|
||||
buffer = (data[n] & 63);
|
||||
result.append(lookup[buffer]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(overflow) result.append(lookup[buffer]);
|
||||
if(lookup[64]) {
|
||||
if(overflow >= 1) result.append(lookup[64]);
|
||||
if(overflow >= 2) result.append(lookup[64]);
|
||||
while(result.size() % 4) result.append(lookup[64]);
|
||||
}
|
||||
|
||||
return result;
|
||||
|
|
|
@ -3,21 +3,21 @@
|
|||
namespace nall {
|
||||
using uint = unsigned;
|
||||
|
||||
struct Intrinsics {
|
||||
enum class Compiler : uint { Clang, GCC, VisualCPP, Unknown };
|
||||
enum class Compiler : uint { Clang, GCC, Microsoft, Unknown };
|
||||
enum class Platform : uint { Windows, MacOS, Linux, BSD, Unknown };
|
||||
enum class API : uint { Windows, Posix, Unknown };
|
||||
enum class Display : uint { Windows, Quartz, Xorg, Unknown };
|
||||
enum class DisplayServer : uint { Windows, Quartz, Xorg, Unknown };
|
||||
enum class Processor : uint { x86, amd64, ARM, PPC32, PPC64, Unknown };
|
||||
enum class Endian : uint { LSB, MSB, Unknown };
|
||||
enum class Build : uint { Debug, Stable, Size, Release, Performance };
|
||||
|
||||
static inline auto compiler() -> Compiler;
|
||||
static inline auto platform() -> Platform;
|
||||
static inline auto api() -> API;
|
||||
static inline auto display() -> Display;
|
||||
static inline auto processor() -> Processor;
|
||||
static inline auto endian() -> Endian;
|
||||
};
|
||||
static inline constexpr auto compiler() -> Compiler;
|
||||
static inline constexpr auto platform() -> Platform;
|
||||
static inline constexpr auto api() -> API;
|
||||
static inline constexpr auto display() -> DisplayServer;
|
||||
static inline constexpr auto processor() -> Processor;
|
||||
static inline constexpr auto endian() -> Endian;
|
||||
static inline constexpr auto build() -> Build;
|
||||
}
|
||||
|
||||
/* Compiler detection */
|
||||
|
@ -26,7 +26,7 @@ namespace nall {
|
|||
|
||||
#if defined(__clang__)
|
||||
#define COMPILER_CLANG
|
||||
auto Intrinsics::compiler() -> Compiler { return Compiler::Clang; }
|
||||
constexpr auto compiler() -> Compiler { return Compiler::Clang; }
|
||||
|
||||
#pragma clang diagnostic ignored "-Wunknown-pragmas"
|
||||
#pragma clang diagnostic ignored "-Wempty-body"
|
||||
|
@ -42,20 +42,20 @@ namespace nall {
|
|||
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
|
||||
#elif defined(__GNUC__)
|
||||
#define COMPILER_GCC
|
||||
auto Intrinsics::compiler() -> Compiler { return Compiler::GCC; }
|
||||
constexpr auto compiler() -> Compiler { return Compiler::GCC; }
|
||||
|
||||
#pragma GCC diagnostic ignored "-Wunknown-pragmas"
|
||||
#pragma GCC diagnostic ignored "-Wpragmas"
|
||||
#pragma GCC diagnostic ignored "-Wswitch-bool"
|
||||
#elif defined(_MSC_VER)
|
||||
#define COMPILER_VISUALCPP
|
||||
auto Intrinsics::compiler() -> Compiler { return Compiler::VisualCPP; }
|
||||
#define COMPILER_MICROSOFT
|
||||
constexpr auto compiler() -> Compiler { return Compiler::Microsoft; }
|
||||
|
||||
#pragma warning(disable:4996) //libc "deprecation" warnings
|
||||
#else
|
||||
#warning "unable to detect compiler"
|
||||
#define COMPILER_UNKNOWN
|
||||
auto Intrinsics::compiler() -> Compiler { return Compiler::Unknown; }
|
||||
constexpr auto compiler() -> Compiler { return Compiler::Unknown; }
|
||||
#endif
|
||||
|
||||
}
|
||||
|
@ -68,38 +68,38 @@ namespace nall {
|
|||
#define PLATFORM_WINDOWS
|
||||
#define API_WINDOWS
|
||||
#define DISPLAY_WINDOWS
|
||||
auto Intrinsics::platform() -> Platform { return Platform::Windows; }
|
||||
auto Intrinsics::api() -> API { return API::Windows; }
|
||||
auto Intrinsics::display() -> Display { return Display::Windows; }
|
||||
constexpr auto platform() -> Platform { return Platform::Windows; }
|
||||
constexpr auto api() -> API { return API::Windows; }
|
||||
constexpr auto display() -> DisplayServer { return DisplayServer::Windows; }
|
||||
#elif defined(__APPLE__)
|
||||
#define PLATFORM_MACOS
|
||||
#define API_POSIX
|
||||
#define DISPLAY_QUARTZ
|
||||
auto Intrinsics::platform() -> Platform { return Platform::MacOS; }
|
||||
auto Intrinsics::api() -> API { return API::Posix; }
|
||||
auto Intrinsics::display() -> Display { return Display::Quartz; }
|
||||
constexpr auto platform() -> Platform { return Platform::MacOS; }
|
||||
constexpr auto api() -> API { return API::Posix; }
|
||||
constexpr auto display() -> DisplayServer { return DisplayServer::Quartz; }
|
||||
#elif defined(linux) || defined(__linux__)
|
||||
#define PLATFORM_LINUX
|
||||
#define API_POSIX
|
||||
#define DISPLAY_XORG
|
||||
auto Intrinsics::platform() -> Platform { return Platform::Linux; }
|
||||
auto Intrinsics::api() -> API { return API::Posix; }
|
||||
auto Intrinsics::display() -> Display { return Display::Xorg; }
|
||||
constexpr auto platform() -> Platform { return Platform::Linux; }
|
||||
constexpr auto api() -> API { return API::Posix; }
|
||||
constexpr auto display() -> DisplayServer { return DisplayServer::Xorg; }
|
||||
#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__NetBSD__) || defined(__OpenBSD__)
|
||||
#define PLATFORM_BSD
|
||||
#define API_POSIX
|
||||
#define DISPLAY_XORG
|
||||
auto Intrinsics::platform() -> Platform { return Platform::BSD; }
|
||||
auto Intrinsics::api() -> API { return API::Posix; }
|
||||
auto Intrinsics::display() -> Display { return Display::Xorg; }
|
||||
constexpr auto platform() -> Platform { return Platform::BSD; }
|
||||
constexpr auto api() -> API { return API::Posix; }
|
||||
constexpr auto display() -> DisplayServer { return DisplayServer::Xorg; }
|
||||
#else
|
||||
#warning "unable to detect platform"
|
||||
#define PLATFORM_UNKNOWN
|
||||
#define API_UNKNOWN
|
||||
#define DISPLAY_UNKNOWN
|
||||
auto Intrinsics::platform() -> Platform { return Platform::Unknown; }
|
||||
auto Intrinsics::api() -> API { return API::Unknown; }
|
||||
auto Intrinsics::display() -> Display { return Display::Unknown; }
|
||||
constexpr auto platform() -> Platform { return Platform::Unknown; }
|
||||
constexpr auto api() -> API { return API::Unknown; }
|
||||
constexpr auto display() -> DisplayServer { return DisplayServer::Unknown; }
|
||||
#endif
|
||||
|
||||
}
|
||||
|
@ -112,29 +112,29 @@ namespace nall {
|
|||
#include <sys/endian.h>
|
||||
#endif
|
||||
|
||||
/* Processor Detection */
|
||||
/* Processor detection */
|
||||
|
||||
namespace nall {
|
||||
|
||||
#if defined(__i386__) || defined(_M_IX86)
|
||||
#define PROCESSOR_X86
|
||||
auto Intrinsics::processor() -> Processor { return Processor::x86; }
|
||||
constexpr auto processor() -> Processor { return Processor::x86; }
|
||||
#elif defined(__amd64__) || defined(_M_AMD64)
|
||||
#define PROCESSOR_AMD64
|
||||
auto Intrinsics::processor() -> Processor { return Processor::amd64; }
|
||||
constexpr auto processor() -> Processor { return Processor::amd64; }
|
||||
#elif defined(__arm__)
|
||||
#define PROCESSOR_ARM
|
||||
auto Intrinsics::processor() -> Processor { return Processor::ARM; }
|
||||
constexpr auto processor() -> Processor { return Processor::ARM; }
|
||||
#elif defined(__ppc64__) || defined(_ARCH_PPC64)
|
||||
#define PROCESSOR_PPC64
|
||||
auto Intrinsics::processor() -> Processor { return Processor::PPC64; }
|
||||
constexpr auto processor() -> Processor { return Processor::PPC64; }
|
||||
#elif defined(__ppc__) || defined(_ARCH_PPC) || defined(_M_PPC)
|
||||
#define PROCESSOR_PPC32
|
||||
auto Intrinsics::processor() -> Processor { return Processor::PPC32; }
|
||||
constexpr auto processor() -> Processor { return Processor::PPC32; }
|
||||
#else
|
||||
#warning "unable to detect processor"
|
||||
#define PROCESSOR_UNKNOWN
|
||||
auto Intrinsics::processor() -> Processor { return Processor::Unknown; }
|
||||
constexpr auto processor() -> Processor { return Processor::Unknown; }
|
||||
#endif
|
||||
|
||||
}
|
||||
|
@ -145,14 +145,44 @@ namespace nall {
|
|||
|
||||
#if (defined(__BYTE_ORDER) && defined(__LITTLE_ENDIAN) && __BYTE_ORDER == __LITTLE_ENDIAN) || defined(__LITTLE_ENDIAN__) || defined(__i386__) || defined(__amd64__) || defined(_M_IX86) || defined(_M_AMD64)
|
||||
#define ENDIAN_LSB
|
||||
auto Intrinsics::endian() -> Endian { return Endian::LSB; }
|
||||
constexpr auto endian() -> Endian { return Endian::LSB; }
|
||||
#elif (defined(__BYTE_ORDER) && defined(__BIG_ENDIAN) && __BYTE_ORDER == __BIG_ENDIAN) || defined(__BIG_ENDIAN__) || defined(__powerpc__) || defined(_M_PPC)
|
||||
#define ENDIAN_MSB
|
||||
auto Intrinsics::endian() -> Endian { return Endian::MSB; }
|
||||
constexpr auto endian() -> Endian { return Endian::MSB; }
|
||||
#else
|
||||
#warning "unable to detect endian"
|
||||
#define ENDIAN_UNKNOWN
|
||||
auto Intrinsics::endian() -> Endian { return Endian::Unknown; }
|
||||
constexpr auto endian() -> Endian { return Endian::Unknown; }
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
/* Build optimization level detection */
|
||||
|
||||
#undef DEBUG
|
||||
#undef NDEBUG
|
||||
|
||||
namespace nall {
|
||||
|
||||
#if defined(BUILD_DEBUG)
|
||||
#define DEBUG
|
||||
constexpr auto build() -> Build { return Build::Debug; }
|
||||
#elif defined(BUILD_STABLE)
|
||||
#define DEBUG
|
||||
constexpr auto build() -> Build { return Build::Stable; }
|
||||
#elif defined(BUILD_SIZE)
|
||||
#define NDEBUG
|
||||
constexpr auto build() -> Build { return Build::Size; }
|
||||
#elif defined(BUILD_RELEASE)
|
||||
#define NDEBUG
|
||||
constexpr auto build() -> Build { return Build::Release; }
|
||||
#elif defined(BUILD_PERFORMANCE)
|
||||
#define NDEBUG
|
||||
constexpr auto build() -> Build { return Build::Performance; }
|
||||
#else
|
||||
//default to debug mode
|
||||
#define DEBUG
|
||||
constexpr auto build() -> Build { return Build::Debug; }
|
||||
#endif
|
||||
|
||||
}
|
||||
|
|
|
@ -58,6 +58,7 @@
|
|||
#include <nall/utility.hpp>
|
||||
#include <nall/varint.hpp>
|
||||
#include <nall/vector.hpp>
|
||||
#include <nall/decode/base.hpp>
|
||||
#include <nall/decode/base64.hpp>
|
||||
#include <nall/decode/bmp.hpp>
|
||||
#include <nall/decode/gzip.hpp>
|
||||
|
@ -65,6 +66,7 @@
|
|||
#include <nall/decode/png.hpp>
|
||||
#include <nall/decode/url.hpp>
|
||||
#include <nall/decode/zip.hpp>
|
||||
#include <nall/encode/base.hpp>
|
||||
#include <nall/encode/base64.hpp>
|
||||
#include <nall/encode/url.hpp>
|
||||
#include <nall/hash/crc16.hpp>
|
||||
|
|
|
@ -54,7 +54,7 @@ namespace Math {
|
|||
#include <poll.h>
|
||||
#endif
|
||||
|
||||
#if defined(COMPILER_VISUALCPP)
|
||||
#if defined(COMPILER_MICROSOFT)
|
||||
#define va_copy(dest, src) ((dest) = (src))
|
||||
#endif
|
||||
|
||||
|
@ -104,7 +104,7 @@ namespace Math {
|
|||
#if defined(COMPILER_CLANG) || defined(COMPILER_GCC)
|
||||
#define neverinline __attribute__((noinline))
|
||||
#define alwaysinline inline __attribute__((always_inline))
|
||||
#elif defined(COMPILER_VISUALCPP)
|
||||
#elif defined(COMPILER_MICROSOFT)
|
||||
#define neverinline __declspec(noinline)
|
||||
#define alwaysinline inline __forceinline
|
||||
#else
|
||||
|
|
|
@ -174,8 +174,8 @@ public:
|
|||
inline auto real() const -> double;
|
||||
|
||||
//core.hpp
|
||||
inline auto operator[](int) const -> const char&;
|
||||
inline auto operator()(int, char) const -> char;
|
||||
inline auto operator[](uint) const -> const char&;
|
||||
inline auto operator()(uint, char) const -> char;
|
||||
template<typename... P> inline auto assign(P&&...) -> type&;
|
||||
template<typename T, typename... P> inline auto prepend(const T&, P&&...) -> type&;
|
||||
template<typename... P> inline auto prepend(const nall::string_format&, P&&...) -> type&;
|
||||
|
|
|
@ -15,13 +15,16 @@
|
|||
|
||||
namespace nall {
|
||||
|
||||
auto string::operator[](int position) const -> const char& {
|
||||
//if(position > size() + 1) throw;
|
||||
auto string::operator[](uint position) const -> const char& {
|
||||
#ifdef DEBUG
|
||||
struct out_of_bounds {};
|
||||
if(position >= size() + 1) throw out_of_bounds{};
|
||||
#endif
|
||||
return data()[position];
|
||||
}
|
||||
|
||||
auto string::operator()(int position, char fallback) const -> char {
|
||||
if(position > size() + 1) return fallback;
|
||||
auto string::operator()(uint position, char fallback) const -> char {
|
||||
if(position >= size() + 1) return fallback;
|
||||
return data()[position];
|
||||
}
|
||||
|
||||
|
|
|
@ -84,11 +84,14 @@ auto string::size(int length, char fill) -> string& {
|
|||
|
||||
auto slice(string_view self, int offset, int length) -> string {
|
||||
string result;
|
||||
if(offset < self.size()) {
|
||||
if(offset < 0) offset = self.size() - abs(offset);
|
||||
if(offset >= 0 && offset < self.size()) {
|
||||
if(length < 0) length = self.size() - offset;
|
||||
if(length >= 0) {
|
||||
result.resize(length);
|
||||
memory::copy(result.get(), self.data() + offset, length);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
|
|
@ -3,10 +3,18 @@
|
|||
namespace nall {
|
||||
|
||||
template<typename T> auto vector<T>::operator[](uint offset) -> T& {
|
||||
#ifdef DEBUG
|
||||
struct out_of_bounds {};
|
||||
if(offset >= size()) throw out_of_bounds{};
|
||||
#endif
|
||||
return _pool[offset];
|
||||
}
|
||||
|
||||
template<typename T> auto vector<T>::operator[](uint offset) const -> const T& {
|
||||
#ifdef DEBUG
|
||||
struct out_of_bounds {};
|
||||
if(offset >= size()) throw out_of_bounds{};
|
||||
#endif
|
||||
return _pool[offset];
|
||||
}
|
||||
|
||||
|
|
|
@ -1,14 +1,5 @@
|
|||
#pragma once
|
||||
|
||||
/* ruby
|
||||
* author: byuu
|
||||
* license: ISC
|
||||
* version: 0.16 (2017-07-08)
|
||||
*
|
||||
* ruby is a cross-platform hardware abstraction layer.
|
||||
* it provides a common interface to video, audio and input devices.
|
||||
*/
|
||||
|
||||
#include <nall/nall.hpp>
|
||||
|
||||
namespace ruby {
|
||||
|
|
Loading…
Reference in New Issue