diff --git a/genius/genius.cpp b/genius/genius.cpp index 4f9bb425..b8beb24f 100644 --- a/genius/genius.cpp +++ b/genius/genius.cpp @@ -43,6 +43,7 @@ ListWindow::ListWindow() { }); layout.setPadding(5); + gameList.setHeadered(); gameList.onActivate([&] { modifyButton.doActivate(); }); gameList.onChange([&] { updateWindow(); }); appendButton.setText("Append").onActivate([&] { @@ -75,19 +76,16 @@ auto ListWindow::quit() -> void { 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")) - ); + gameList.append(TableViewColumn().setText("Name").setExpandable()); + gameList.append(TableViewColumn().setText("Region")); + gameList.append(TableViewColumn().setText("Revision")); + gameList.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)) - ); + TableViewItem item{&gameList}; + item.append(TableViewCell().setText(game.name)); + item.append(TableViewCell().setText(game.region)); + item.append(TableViewCell().setText(game.revision)); + item.append(TableViewCell().setText(game.board)); } Application::processEvents(); gameList.resizeColumns(); diff --git a/higan/emulator/emulator.hpp b/higan/emulator/emulator.hpp index 4a53bcb7..4cddd823 100644 --- a/higan/emulator/emulator.hpp +++ b/higan/emulator/emulator.hpp @@ -13,7 +13,7 @@ using namespace nall; namespace Emulator { static const string Name = "higan"; - static const string Version = "106.54"; + static const string Version = "106.55"; static const string Author = "byuu"; static const string License = "GPLv3"; static const string Website = "https://byuu.org/"; diff --git a/higan/resource/resource.cpp b/higan/resource/resource.cpp index e9042514..2d675a8a 100644 --- a/higan/resource/resource.cpp +++ b/higan/resource/resource.cpp @@ -1,9 +1,8 @@ -#include #include "resource.hpp" namespace Resource { namespace Sprite { -const nall::vector CrosshairRed = { //size: 342 +const unsigned char CrosshairRed[342] = { 137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82,0,0,0,32,0,0,0,32,8,6,0,0,0,115,122,122, 244,0,0,0,4,115,66,73,84,8,8,8,8,124,8,100,136,0,0,0,9,112,72,89,115,0,0,14,196,0,0,14, 196,1,149,43,14,27,0,0,0,248,73,68,65,84,88,133,205,87,65,14,196,32,8,132,102,255,255,101,246,176,177,139, @@ -16,7 +15,7 @@ const nall::vector CrosshairRed = { //size: 342 94,23,13,77,214,104,44,103,174,163,143,86,189,244,187,224,232,151,81,21,132,39,210,33,91,246,54,132,193,44,226,219, 107,95,57,136,120,253,172,254,16,23,0,0,0,0,73,69,78,68,174,66,96,130, }; -const nall::vector CrosshairGreen = { //size: 329 +const unsigned char CrosshairGreen[329] = { 137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82,0,0,0,32,0,0,0,32,8,6,0,0,0,115,122,122, 244,0,0,0,4,115,66,73,84,8,8,8,8,124,8,100,136,0,0,0,9,112,72,89,115,0,0,14,196,0,0,14, 196,1,149,43,14,27,0,0,0,235,73,68,65,84,88,133,213,87,65,18,195,32,8,196,78,31,230,211,253,153,61,180, @@ -29,7 +28,7 @@ const nall::vector CrosshairGreen = { //size: 329 238,241,241,126,143,125,62,216,173,151,209,35,222,134,235,96,98,252,229,226,3,112,72,179,236,202,138,114,18,0,0,0, 0,73,69,78,68,174,66,96,130, }; -const nall::vector CrosshairBlue = { //size: 332 +const unsigned char CrosshairBlue[332] = { 137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82,0,0,0,32,0,0,0,32,8,6,0,0,0,115,122,122, 244,0,0,0,4,115,66,73,84,8,8,8,8,124,8,100,136,0,0,0,9,112,72,89,115,0,0,14,196,0,0,14, 196,1,149,43,14,27,0,0,0,238,73,68,65,84,88,133,213,87,91,18,195,32,8,196,78,15,232,81,189,161,253,9, diff --git a/higan/resource/resource.hpp b/higan/resource/resource.hpp index ded7f195..5c888361 100644 --- a/higan/resource/resource.hpp +++ b/higan/resource/resource.hpp @@ -1,7 +1,7 @@ namespace Resource { namespace Sprite { -extern const nall::vector CrosshairRed; -extern const nall::vector CrosshairGreen; -extern const nall::vector CrosshairBlue; +extern const unsigned char CrosshairRed[342]; +extern const unsigned char CrosshairGreen[329]; +extern const unsigned char CrosshairBlue[332]; } } diff --git a/higan/sfc/controller/super-scope/super-scope.cpp b/higan/sfc/controller/super-scope/super-scope.cpp index 6e852afa..6dacb712 100644 --- a/higan/sfc/controller/super-scope/super-scope.cpp +++ b/higan/sfc/controller/super-scope/super-scope.cpp @@ -77,7 +77,7 @@ auto SuperScope::data() -> uint2 { bool newturbo = platform->inputPoll(port, ID::Device::SuperScope, Turbo); if(newturbo && !oldturbo) { turbo = !turbo; //toggle state - sprite->setPixels(turbo ? Resource::Sprite::CrosshairRed : Resource::Sprite::CrosshairGreen); + sprite->setPixels(turbo ? (image)Resource::Sprite::CrosshairRed : (image)Resource::Sprite::CrosshairGreen); } oldturbo = newturbo; diff --git a/higan/target-bsnes/input/hotkeys.cpp b/higan/target-bsnes/input/hotkeys.cpp index 7527d4c0..624ce281 100644 --- a/higan/target-bsnes/input/hotkeys.cpp +++ b/higan/target-bsnes/input/hotkeys.cpp @@ -14,19 +14,19 @@ auto InputManager::bindHotkeys() -> void { })); hotkeys.append(InputHotkey("Save State").onPress([&] { - program.saveState({"quick/slot ", stateSlot}); + program.saveState({"Quick/Slot ", stateSlot}); })); hotkeys.append(InputHotkey("Load State").onPress([&] { - program.loadState({"quick/slot ", stateSlot}); + program.loadState({"Quick/Slot ", stateSlot}); })); hotkeys.append(InputHotkey("Load Undo State").onPress([&] { - program.loadState("quick/undo"); + program.loadState("Quick/Undo"); })); hotkeys.append(InputHotkey("Load Redo State").onPress([&] { - program.loadState("quick/redo"); + program.loadState("Quick/Redo"); })); hotkeys.append(InputHotkey("Increment State Slot").onPress([&] { diff --git a/higan/target-bsnes/presentation/presentation.cpp b/higan/target-bsnes/presentation/presentation.cpp index fe11b08e..de2ebc1d 100644 --- a/higan/target-bsnes/presentation/presentation.cpp +++ b/higan/target-bsnes/presentation/presentation.cpp @@ -79,41 +79,42 @@ auto Presentation::create() -> void { saveState.setIcon(Icon::Action::Save).setText("Save State"); for(uint index : range(QuickStates)) { MenuItem item{&saveState}; - item.setProperty("name", {"quick/slot ", 1 + index}); + item.setProperty("name", {"Quick/Slot ", 1 + index}); item.setProperty("title", {"Slot ", 1 + index}); item.setText({"Slot ", 1 + index}); - item.onActivate([=] { program.saveState({"quick/slot ", 1 + index}); }); + item.onActivate([=] { program.saveState({"Quick/Slot ", 1 + index}); }); } loadState.setIcon(Icon::Media::Play).setText("Load State"); for(uint index : range(QuickStates)) { MenuItem item{&loadState}; - item.setProperty("name", {"quick/slot ", 1 + index}); + item.setProperty("name", {"Quick/Slot ", 1 + index}); item.setProperty("title", {"Slot ", 1 + index}); item.setText({"Slot ", 1 + index}); - item.onActivate([=] { program.loadState({"quick/slot ", 1 + index}); }); + item.onActivate([=] { program.loadState({"Quick/Slot ", 1 + index}); }); } loadState.append(MenuSeparator()); loadState.append(MenuItem() - .setProperty("name", "quick/undo") + .setProperty("name", "Quick/Undo") .setProperty("title", "Undo Last Save") .setIcon(Icon::Edit::Undo).setText("Undo Last Save").onActivate([&] { - program.loadState("quick/undo"); + program.loadState("Quick/Undo"); })); loadState.append(MenuItem() - .setProperty("name", "quick/redo") + .setProperty("name", "Quick/Redo") .setProperty("title", "Redo Last Undo") .setIcon(Icon::Edit::Redo).setText("Redo Last Undo").onActivate([&] { - program.loadState("quick/redo"); + program.loadState("Quick/Redo"); })); loadState.append(MenuItem().setIcon(Icon::Edit::Clear).setText("Remove All States").onActivate([&] { if(MessageDialog("Are you sure you want to permanently remove all quick states for this game?").setParent(*this).question() == "Yes") { - for(uint index : range(QuickStates)) program.removeState({"quick/slot ", 1 + index}); - program.removeState("quick/undo"); - program.removeState("quick/redo"); - updateStateMenus(); + for(uint index : range(QuickStates)) program.removeState({"Quick/Slot ", 1 + index}); + program.removeState("Quick/Undo"); + program.removeState("Quick/Redo"); } })); - speedMenu.setIcon(Icon::Device::Clock).setText("Speed"); + speedMenu.setIcon(Icon::Device::Clock).setText("Speed").setEnabled( + !settings["Video/Blocking"].boolean() && settings["Audio/Blocking"].boolean() + ); speedSlowest.setText("50% (Slowest)").setProperty("multiplier", "2.0").onActivate([&] { program.updateAudioFrequency(); }); speedSlow.setText("75% (Slow)").setProperty("multiplier", "1.333").onActivate([&] { program.updateAudioFrequency(); }); speedNormal.setText("100% (Normal)").setProperty("multiplier", "1.0").onActivate([&] { program.updateAudioFrequency(); }); @@ -195,7 +196,7 @@ auto Presentation::create() -> void { #if defined(PLATFORM_WINDOWS) Application::Windows::onModalChange([&](bool modal) { - if(modal && audio) audio->clear(); + if(modal) audio.clear(); }); #endif @@ -443,7 +444,7 @@ auto Presentation::updateSizeMenu() -> void { } auto Presentation::updateStateMenus() -> void { - auto states = program.availableStates("quick/"); + auto states = program.availableStates("Quick/"); for(auto& action : saveState.actions()) { if(auto item = action.cast()) { @@ -507,7 +508,7 @@ auto Presentation::updateRecentGames() -> void { displayName.append(Location::prefix(part), " + "); } displayName.trimRight(" + ", 1L); - item.setIcon(games(0).endsWith("/") ? Icon::Action::Open : Icon::Emblem::File); + item.setIcon(games(0).endsWith("/") ? (image)Icon::Action::Open : (image)Icon::Emblem::File); item.setText(displayName); item.onActivate([=] { program.gameQueue = games; diff --git a/higan/target-bsnes/program/game.cpp b/higan/target-bsnes/program/game.cpp index eafd5bee..a866f924 100644 --- a/higan/target-bsnes/program/game.cpp +++ b/higan/target-bsnes/program/game.cpp @@ -27,7 +27,7 @@ auto Program::load() -> void { hackCompatibility(); emulator->power(); if(emulatorSettings.autoLoadStateOnLoad.checked()) { - program.loadState("quick/undo"); + program.loadState("Quick/Undo"); } showMessage({ verified() ? "Verified game loaded" : "Game loaded", diff --git a/higan/target-bsnes/program/platform.cpp b/higan/target-bsnes/program/platform.cpp index 6d0633fe..fc3a0fb1 100644 --- a/higan/target-bsnes/program/platform.cpp +++ b/higan/target-bsnes/program/platform.cpp @@ -12,11 +12,11 @@ auto Program::open(uint id, string name, vfs::file::mode mode, bool required) -> if(id == 0) { //System if(name == "boards.bml" && mode == vfs::file::mode::read) { - result = vfs::memory::file::open(Resource::System::Boards.data(), Resource::System::Boards.size()); + result = vfs::memory::file::open(Resource::System::Boards, sizeof(Resource::System::Boards)); } if(name == "ipl.rom" && mode == vfs::file::mode::read) { - result = vfs::memory::file::open(Resource::System::IPLROM.data(), Resource::System::IPLROM.size()); + result = vfs::memory::file::open(Resource::System::IPLROM, sizeof(Resource::System::IPLROM)); } } diff --git a/higan/target-bsnes/program/program.cpp b/higan/target-bsnes/program/program.cpp index 948aa23a..ef94d816 100644 --- a/higan/target-bsnes/program/program.cpp +++ b/higan/target-bsnes/program/program.cpp @@ -16,10 +16,11 @@ Program program; auto Program::create(vector arguments) -> void { Emulator::platform = this; - aboutWindow.create(); presentation.create(); presentation.setVisible(); + aboutWindow.create(); + settingsWindow.create(); videoSettings.create(); audioSettings.create(); inputSettings.create(); @@ -27,15 +28,14 @@ auto Program::create(vector arguments) -> void { pathSettings.create(); emulatorSettings.create(); driverSettings.create(); - settingsWindow.create(); + toolsWindow.create(); cheatDatabase.create(); cheatWindow.create(); cheatEditor.create(); stateWindow.create(); stateManager.create(); manifestViewer.create(); - toolsWindow.create(); if(settings["Crashed"].boolean()) { MessageDialog( diff --git a/higan/target-bsnes/program/states.cpp b/higan/target-bsnes/program/states.cpp index 83436e3c..cb2cf30e 100644 --- a/higan/target-bsnes/program/states.cpp +++ b/higan/target-bsnes/program/states.cpp @@ -60,8 +60,8 @@ auto Program::loadStateData(string filename) -> vector { auto Program::loadState(string filename) -> bool { string prefix = Location::file(filename); if(auto memory = loadStateData(filename)) { - if(filename != "quick/undo") saveUndoState(); - if(filename == "quick/undo") saveRedoState(); + if(filename != "Quick/Undo") saveUndoState(); + if(filename == "Quick/Undo") saveRedoState(); auto serializerRLE = Decode::RLE(memory.data() + 3 * sizeof(uint)); serializer s{serializerRLE.data(), serializerRLE.size()}; if(!emulator->unserialize(s)) return showMessage({"[", prefix, "] is in incompatible format"}), false; @@ -122,7 +122,7 @@ auto Program::saveState(string filename) -> bool { output.append(location, saveState.data(), saveState.size()); } - if(filename.beginsWith("quick/")) presentation.updateStateMenus(); + if(filename.beginsWith("Quick/")) presentation.updateStateMenus(); stateManager.stateEvent(filename); return showMessage({"Saved [", prefix, "]"}), true; } @@ -130,7 +130,7 @@ auto Program::saveState(string filename) -> bool { auto Program::saveUndoState() -> bool { auto statusTime = this->statusTime; auto statusMessage = this->statusMessage; - auto result = saveState("quick/undo"); + auto result = saveState("Quick/Undo"); this->statusTime = statusTime; this->statusMessage = statusMessage; return result; @@ -139,7 +139,7 @@ auto Program::saveUndoState() -> bool { auto Program::saveRedoState() -> bool { auto statusTime = this->statusTime; auto statusMessage = this->statusMessage; - auto result = saveState("quick/redo"); + auto result = saveState("Quick/Redo"); this->statusTime = statusTime; this->statusMessage = statusMessage; return result; diff --git a/higan/target-bsnes/resource/resource.bml b/higan/target-bsnes/resource/resource.bml index 118a653b..86f0d42e 100644 --- a/higan/target-bsnes/resource/resource.bml +++ b/higan/target-bsnes/resource/resource.bml @@ -2,5 +2,5 @@ namespace name=Resource binary name=Icon file=icon.png binary name=Logo file=logo.png namespace name=System - binary name=Boards file="../../systems/Super Famicom.sys/boards.bml" + string name=Boards file="../../systems/Super Famicom.sys/boards.bml" binary name=IPLROM file="../../systems/Super Famicom.sys/ipl.rom" diff --git a/higan/target-bsnes/resource/resource.cpp b/higan/target-bsnes/resource/resource.cpp index 5407aa7e..30e09107 100644 --- a/higan/target-bsnes/resource/resource.cpp +++ b/higan/target-bsnes/resource/resource.cpp @@ -1,8 +1,7 @@ -#include #include "resource.hpp" namespace Resource { -const nall::vector Icon = { //size: 3463 +const unsigned char Icon[3463] = { 137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82,0,0,0,128,0,0,0,128,8,6,0,0,0,195,62,97, 203,0,0,0,4,103,65,77,65,0,0,177,143,11,252,97,5,0,0,0,32,99,72,82,77,0,0,122,38,0,0,128, 132,0,0,250,0,0,0,128,232,0,0,117,48,0,0,234,96,0,0,58,152,0,0,23,112,156,186,81,60,0,0,0, @@ -113,7 +112,7 @@ const nall::vector Icon = { //size: 3463 105,97,47,98,115,110,101,115,47,105,99,111,110,47,98,115,110,101,115,46,115,118,103,188,87,222,120,0,0,0,0,73, 69,78,68,174,66,96,130, }; -const nall::vector Logo = { //size: 23467 +const unsigned char Logo[23467] = { 137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82,0,0,1,144,0,0,0,85,8,6,0,0,0,103,237,178, 127,0,0,0,4,103,65,77,65,0,0,177,143,11,252,97,5,0,0,0,32,99,72,82,77,0,0,122,38,0,0,128, 132,0,0,250,0,0,0,128,232,0,0,117,48,0,0,234,96,0,0,58,152,0,0,23,112,156,186,81,60,0,0,0, @@ -850,953 +849,245 @@ const nall::vector Logo = { //size: 23467 0,0,0,73,69,78,68,174,66,96,130, }; namespace System { -const nall::vector Boards = { //size: 30182 - 100,97,116,97,98,97,115,101,10,32,32,114,101,118,105,115,105,111,110,58,32,50,48,49,56,45,48,55,45,50,53,10, - 10,47,47,66,111,97,114,100,115,32,40,80,114,111,100,117,99,116,105,111,110,41,10,10,100,97,116,97,98,97,115,101, - 10,32,32,114,101,118,105,115,105,111,110,58,32,50,48,49,56,45,48,53,45,49,54,10,10,98,111,97,114,100,58,32, - 66,65,78,68,65,73,45,80,84,45,57,50,51,10,32,32,109,101,109,111,114,121,32,116,121,112,101,61,82,79,77,32, - 99,111,110,116,101,110,116,61,80,114,111,103,114,97,109,10,32,32,32,32,109,97,112,32,97,100,100,114,101,115,115,61, - 48,48,45,49,102,44,56,48,45,57,102,58,56,48,48,48,45,102,102,102,102,32,109,97,115,107,61,48,120,56,48,48, - 48,10,32,32,115,108,111,116,32,116,121,112,101,61,83,117,102,97,109,105,84,117,114,98,111,10,32,32,32,32,114,111, - 109,10,32,32,32,32,32,32,109,97,112,32,97,100,100,114,101,115,115,61,50,48,45,51,102,44,97,48,45,98,102,58, - 56,48,48,48,45,102,102,102,102,32,109,97,115,107,61,48,120,56,48,48,48,10,32,32,32,32,114,97,109,10,32,32, - 32,32,32,32,109,97,112,32,97,100,100,114,101,115,115,61,54,48,45,54,102,44,101,48,45,101,102,58,48,48,48,48, - 45,102,102,102,102,10,32,32,115,108,111,116,32,116,121,112,101,61,83,117,102,97,109,105,84,117,114,98,111,10,32,32, - 32,32,114,111,109,10,32,32,32,32,32,32,109,97,112,32,97,100,100,114,101,115,115,61,52,48,45,53,102,44,99,48, - 45,100,102,58,48,48,48,48,45,102,102,102,102,32,109,97,115,107,61,48,120,56,48,48,48,10,32,32,32,32,114,97, - 109,10,32,32,32,32,32,32,109,97,112,32,97,100,100,114,101,115,115,61,55,48,45,55,100,44,102,48,45,102,102,58, - 48,48,48,48,45,102,102,102,102,10,10,98,111,97,114,100,58,32,66,83,67,45,49,65,53,66,57,80,45,48,49,10, - 32,32,109,101,109,111,114,121,32,116,121,112,101,61,82,65,77,32,99,111,110,116,101,110,116,61,83,97,118,101,10,32, - 32,32,32,109,97,112,32,97,100,100,114,101,115,115,61,49,48,45,49,55,58,53,48,48,48,45,53,102,102,102,32,109, - 97,115,107,61,48,120,102,48,48,48,10,32,32,112,114,111,99,101,115,115,111,114,32,105,100,101,110,116,105,102,105,101, - 114,61,77,67,67,10,32,32,32,32,109,97,112,32,97,100,100,114,101,115,115,61,48,48,45,48,102,58,53,48,48,48, - 45,53,102,102,102,10,32,32,32,32,109,99,117,10,32,32,32,32,32,32,109,97,112,32,97,100,100,114,101,115,115,61, - 48,48,45,51,102,44,56,48,45,98,102,58,56,48,48,48,45,102,102,102,102,10,32,32,32,32,32,32,109,97,112,32, - 97,100,100,114,101,115,115,61,52,48,45,55,100,44,99,48,45,102,102,58,48,48,48,48,45,102,102,102,102,10,32,32, - 32,32,32,32,109,97,112,32,97,100,100,114,101,115,115,61,50,48,45,51,102,44,97,48,45,98,102,58,54,48,48,48, - 45,55,102,102,102,10,32,32,32,32,32,32,109,101,109,111,114,121,32,116,121,112,101,61,82,79,77,32,99,111,110,116, - 101,110,116,61,80,114,111,103,114,97,109,10,32,32,32,32,32,32,109,101,109,111,114,121,32,116,121,112,101,61,82,65, - 77,32,99,111,110,116,101,110,116,61,68,111,119,110,108,111,97,100,10,32,32,32,32,32,32,115,108,111,116,32,116,121, - 112,101,61,66,83,77,101,109,111,114,121,10,10,98,111,97,114,100,58,32,66,83,67,45,49,65,53,77,45,48,50,10, - 32,32,109,101,109,111,114,121,32,116,121,112,101,61,82,79,77,32,99,111,110,116,101,110,116,61,80,114,111,103,114,97, - 109,10,32,32,32,32,109,97,112,32,97,100,100,114,101,115,115,61,48,48,45,49,102,58,56,48,48,48,45,102,102,102, - 102,32,109,97,115,107,61,48,120,56,48,48,48,32,98,97,115,101,61,48,120,48,48,48,48,48,48,10,32,32,32,32, - 109,97,112,32,97,100,100,114,101,115,115,61,50,48,45,51,102,58,56,48,48,48,45,102,102,102,102,32,109,97,115,107, - 61,48,120,56,48,48,48,32,98,97,115,101,61,48,120,49,48,48,48,48,48,10,32,32,32,32,109,97,112,32,97,100, - 100,114,101,115,115,61,56,48,45,57,102,58,56,48,48,48,45,102,102,102,102,32,109,97,115,107,61,48,120,56,48,48, - 48,32,98,97,115,101,61,48,120,50,48,48,48,48,48,10,32,32,32,32,109,97,112,32,97,100,100,114,101,115,115,61, - 97,48,45,98,102,58,56,48,48,48,45,102,102,102,102,32,109,97,115,107,61,48,120,56,48,48,48,32,98,97,115,101, - 61,48,120,49,48,48,48,48,48,10,32,32,109,101,109,111,114,121,32,116,121,112,101,61,82,65,77,32,99,111,110,116, - 101,110,116,61,83,97,118,101,10,32,32,32,32,109,97,112,32,97,100,100,114,101,115,115,61,55,48,45,55,100,44,102, - 48,45,102,102,58,48,48,48,48,45,55,102,102,102,32,109,97,115,107,61,48,120,56,48,48,48,10,32,32,115,108,111, - 116,32,116,121,112,101,61,66,83,77,101,109,111,114,121,10,32,32,32,32,109,97,112,32,97,100,100,114,101,115,115,61, - 99,48,45,101,102,58,48,48,48,48,45,102,102,102,102,10,10,98,111,97,114,100,58,32,66,83,67,45,49,65,55,77, - 45,48,49,10,32,32,109,101,109,111,114,121,32,116,121,112,101,61,82,79,77,32,99,111,110,116,101,110,116,61,80,114, - 111,103,114,97,109,10,32,32,32,32,109,97,112,32,97,100,100,114,101,115,115,61,48,48,45,49,102,58,56,48,48,48, - 45,102,102,102,102,32,109,97,115,107,61,48,120,56,48,48,48,32,98,97,115,101,61,48,120,48,48,48,48,48,48,10, - 32,32,32,32,109,97,112,32,97,100,100,114,101,115,115,61,50,48,45,51,102,58,56,48,48,48,45,102,102,102,102,32, - 109,97,115,107,61,48,120,56,48,48,48,32,98,97,115,101,61,48,120,49,48,48,48,48,48,10,32,32,32,32,109,97, - 112,32,97,100,100,114,101,115,115,61,56,48,45,57,102,58,56,48,48,48,45,102,102,102,102,32,109,97,115,107,61,48, - 120,56,48,48,48,32,98,97,115,101,61,48,120,50,48,48,48,48,48,10,32,32,32,32,109,97,112,32,97,100,100,114, - 101,115,115,61,97,48,45,98,102,58,56,48,48,48,45,102,102,102,102,32,109,97,115,107,61,48,120,56,48,48,48,32, - 98,97,115,101,61,48,120,49,48,48,48,48,48,10,32,32,109,101,109,111,114,121,32,116,121,112,101,61,82,65,77,32, - 99,111,110,116,101,110,116,61,83,97,118,101,10,32,32,32,32,109,97,112,32,97,100,100,114,101,115,115,61,55,48,45, - 55,100,44,102,48,45,102,102,58,48,48,48,48,45,55,102,102,102,32,109,97,115,107,61,48,120,56,48,48,48,10,32, - 32,115,108,111,116,32,116,121,112,101,61,66,83,77,101,109,111,114,121,10,32,32,32,32,109,97,112,32,97,100,100,114, - 101,115,115,61,99,48,45,101,102,58,48,48,48,48,45,102,102,102,102,10,10,98,111,97,114,100,58,32,66,83,67,45, - 49,74,51,77,45,48,49,10,32,32,109,101,109,111,114,121,32,116,121,112,101,61,82,79,77,32,99,111,110,116,101,110, - 116,61,80,114,111,103,114,97,109,10,32,32,32,32,109,97,112,32,97,100,100,114,101,115,115,61,48,48,45,49,102,44, - 56,48,45,57,102,58,56,48,48,48,45,102,102,102,102,10,32,32,32,32,109,97,112,32,97,100,100,114,101,115,115,61, - 52,48,45,53,102,44,99,48,45,100,102,58,48,48,48,48,45,102,102,102,102,10,32,32,109,101,109,111,114,121,32,116, - 121,112,101,61,82,65,77,32,99,111,110,116,101,110,116,61,83,97,118,101,10,32,32,32,32,109,97,112,32,97,100,100, - 114,101,115,115,61,50,48,45,51,102,44,97,48,45,98,102,58,54,48,48,48,45,55,102,102,102,32,109,97,115,107,61, - 48,120,101,48,48,48,10,32,32,115,108,111,116,32,116,121,112,101,61,66,83,77,101,109,111,114,121,10,32,32,32,32, - 109,97,112,32,97,100,100,114,101,115,115,61,50,48,45,51,102,44,97,48,45,98,102,58,56,48,48,48,45,102,102,102, - 102,10,32,32,32,32,109,97,112,32,97,100,100,114,101,115,115,61,54,48,45,55,100,44,101,48,45,102,102,58,48,48, - 48,48,45,102,102,102,102,10,10,98,111,97,114,100,58,32,66,83,67,45,49,74,53,77,45,48,49,10,32,32,109,101, - 109,111,114,121,32,116,121,112,101,61,82,79,77,32,99,111,110,116,101,110,116,61,80,114,111,103,114,97,109,10,32,32, - 32,32,109,97,112,32,97,100,100,114,101,115,115,61,48,48,45,49,102,44,56,48,45,57,102,58,56,48,48,48,45,102, - 102,102,102,10,32,32,32,32,109,97,112,32,97,100,100,114,101,115,115,61,52,48,45,53,102,44,99,48,45,100,102,58, - 48,48,48,48,45,102,102,102,102,10,32,32,109,101,109,111,114,121,32,116,121,112,101,61,82,65,77,32,99,111,110,116, - 101,110,116,61,83,97,118,101,10,32,32,32,32,109,97,112,32,97,100,100,114,101,115,115,61,50,48,45,51,102,44,97, - 48,45,98,102,58,54,48,48,48,45,55,102,102,102,32,109,97,115,107,61,48,120,101,48,48,48,10,32,32,115,108,111, - 116,32,116,121,112,101,61,66,83,77,101,109,111,114,121,10,32,32,32,32,109,97,112,32,97,100,100,114,101,115,115,61, - 50,48,45,51,102,44,97,48,45,98,102,58,56,48,48,48,45,102,102,102,102,10,32,32,32,32,109,97,112,32,97,100, - 100,114,101,115,115,61,54,48,45,55,100,44,101,48,45,102,102,58,48,48,48,48,45,102,102,102,102,10,10,98,111,97, - 114,100,58,32,66,83,67,45,49,76,51,66,45,48,49,10,32,32,112,114,111,99,101,115,115,111,114,32,97,114,99,104, - 105,116,101,99,116,117,114,101,61,87,54,53,67,56,49,54,83,10,32,32,32,32,109,97,112,32,97,100,100,114,101,115, - 115,61,48,48,45,51,102,44,56,48,45,98,102,58,50,50,48,48,45,50,51,102,102,10,32,32,32,32,109,99,117,10, - 32,32,32,32,32,32,109,97,112,32,97,100,100,114,101,115,115,61,48,48,45,51,102,44,56,48,45,98,102,58,56,48, - 48,48,45,102,102,102,102,32,109,97,115,107,61,48,120,52,48,56,48,48,48,10,32,32,32,32,32,32,109,97,112,32, - 97,100,100,114,101,115,115,61,99,48,45,102,102,58,48,48,48,48,45,102,102,102,102,10,32,32,32,32,32,32,109,101, - 109,111,114,121,32,116,121,112,101,61,82,79,77,32,99,111,110,116,101,110,116,61,80,114,111,103,114,97,109,10,32,32, - 32,32,32,32,115,108,111,116,32,116,121,112,101,61,66,83,77,101,109,111,114,121,10,32,32,32,32,109,101,109,111,114, - 121,32,116,121,112,101,61,82,65,77,32,99,111,110,116,101,110,116,61,83,97,118,101,10,32,32,32,32,32,32,109,97, - 112,32,97,100,100,114,101,115,115,61,48,48,45,51,102,44,56,48,45,98,102,58,54,48,48,48,45,55,102,102,102,32, - 115,105,122,101,61,48,120,50,48,48,48,10,32,32,32,32,32,32,109,97,112,32,97,100,100,114,101,115,115,61,52,48, - 45,52,102,58,48,48,48,48,45,102,102,102,102,10,32,32,32,32,109,101,109,111,114,121,32,116,121,112,101,61,82,65, - 77,32,99,111,110,116,101,110,116,61,73,110,116,101,114,110,97,108,10,32,32,32,32,32,32,109,97,112,32,97,100,100, - 114,101,115,115,61,48,48,45,51,102,44,56,48,45,98,102,58,51,48,48,48,45,51,55,102,102,32,115,105,122,101,61, - 48,120,56,48,48,10,10,98,111,97,114,100,58,32,66,83,67,45,49,76,53,66,45,48,49,10,32,32,112,114,111,99, - 101,115,115,111,114,32,97,114,99,104,105,116,101,99,116,117,114,101,61,87,54,53,67,56,49,54,83,10,32,32,32,32, - 109,97,112,32,97,100,100,114,101,115,115,61,48,48,45,51,102,44,56,48,45,98,102,58,50,50,48,48,45,50,51,102, - 102,10,32,32,32,32,109,99,117,10,32,32,32,32,32,32,109,97,112,32,97,100,100,114,101,115,115,61,48,48,45,51, - 102,44,56,48,45,98,102,58,56,48,48,48,45,102,102,102,102,32,109,97,115,107,61,48,120,52,48,56,48,48,48,10, - 32,32,32,32,32,32,109,97,112,32,97,100,100,114,101,115,115,61,99,48,45,102,102,58,48,48,48,48,45,102,102,102, - 102,10,32,32,32,32,32,32,109,101,109,111,114,121,32,116,121,112,101,61,82,79,77,32,99,111,110,116,101,110,116,61, - 80,114,111,103,114,97,109,10,32,32,32,32,32,32,115,108,111,116,32,116,121,112,101,61,66,83,77,101,109,111,114,121, - 10,32,32,32,32,109,101,109,111,114,121,32,116,121,112,101,61,82,65,77,32,99,111,110,116,101,110,116,61,83,97,118, - 101,10,32,32,32,32,32,32,109,97,112,32,97,100,100,114,101,115,115,61,48,48,45,51,102,44,56,48,45,98,102,58, - 54,48,48,48,45,55,102,102,102,32,115,105,122,101,61,48,120,50,48,48,48,10,32,32,32,32,32,32,109,97,112,32, - 97,100,100,114,101,115,115,61,52,48,45,52,102,58,48,48,48,48,45,102,102,102,102,10,32,32,32,32,109,101,109,111, - 114,121,32,116,121,112,101,61,82,65,77,32,99,111,110,116,101,110,116,61,73,110,116,101,114,110,97,108,10,32,32,32, - 32,32,32,109,97,112,32,97,100,100,114,101,115,115,61,48,48,45,51,102,44,56,48,45,98,102,58,51,48,48,48,45, - 51,55,102,102,32,115,105,122,101,61,48,120,56,48,48,10,10,98,111,97,114,100,58,32,83,71,66,45,82,45,49,48, - 10,32,32,109,101,109,111,114,121,32,116,121,112,101,61,82,79,77,32,99,111,110,116,101,110,116,61,80,114,111,103,114, - 97,109,10,32,32,32,32,109,97,112,32,97,100,100,114,101,115,115,61,48,48,45,55,100,44,56,48,45,102,102,58,56, - 48,48,48,45,102,102,102,102,32,109,97,115,107,61,48,120,56,48,48,48,10,32,32,32,32,109,97,112,32,97,100,100, - 114,101,115,115,61,52,48,45,55,100,44,99,48,45,102,102,58,48,48,48,48,45,55,102,102,102,32,109,97,115,107,61, - 48,120,56,48,48,48,10,32,32,112,114,111,99,101,115,115,111,114,32,105,100,101,110,116,105,102,105,101,114,61,73,67, - 68,32,114,101,118,105,115,105,111,110,61,50,10,32,32,32,32,109,97,112,32,97,100,100,114,101,115,115,61,48,48,45, - 51,102,44,56,48,45,98,102,58,54,48,48,48,45,54,55,102,102,44,55,48,48,48,45,55,102,102,102,10,32,32,32, - 32,109,101,109,111,114,121,32,116,121,112,101,61,82,79,77,32,99,111,110,116,101,110,116,61,66,111,111,116,32,97,114, - 99,104,105,116,101,99,116,117,114,101,61,76,82,51,53,57,48,50,10,32,32,32,32,115,108,111,116,32,116,121,112,101, - 61,71,97,109,101,66,111,121,10,10,98,111,97,114,100,58,32,83,72,86,67,45,49,65,48,78,45,40,48,49,44,48, - 50,44,49,48,44,50,48,44,51,48,41,10,32,32,109,101,109,111,114,121,32,116,121,112,101,61,82,79,77,32,99,111, - 110,116,101,110,116,61,80,114,111,103,114,97,109,10,32,32,32,32,109,97,112,32,97,100,100,114,101,115,115,61,48,48, - 45,55,100,44,56,48,45,102,102,58,56,48,48,48,45,102,102,102,102,32,109,97,115,107,61,48,120,56,48,48,48,10, - 32,32,32,32,109,97,112,32,97,100,100,114,101,115,115,61,52,48,45,55,100,44,99,48,45,102,102,58,48,48,48,48, - 45,55,102,102,102,32,109,97,115,107,61,48,120,56,48,48,48,10,10,98,111,97,114,100,58,32,83,72,86,67,45,49, - 65,49,66,45,40,48,52,44,48,53,44,48,54,41,10,32,32,109,101,109,111,114,121,32,116,121,112,101,61,82,79,77, - 32,99,111,110,116,101,110,116,61,80,114,111,103,114,97,109,10,32,32,32,32,109,97,112,32,97,100,100,114,101,115,115, - 61,48,48,45,49,102,44,56,48,45,57,102,58,56,48,48,48,45,102,102,102,102,32,109,97,115,107,61,48,120,56,48, - 48,48,10,32,32,109,101,109,111,114,121,32,116,121,112,101,61,82,65,77,32,99,111,110,116,101,110,116,61,83,97,118, - 101,10,32,32,32,32,109,97,112,32,97,100,100,114,101,115,115,61,55,48,45,55,100,44,102,48,45,102,102,58,48,48, - 48,48,45,102,102,102,102,10,10,98,111,97,114,100,58,32,83,72,86,67,45,49,65,49,77,45,40,48,49,44,49,48, - 44,49,49,44,50,48,41,10,32,32,109,101,109,111,114,121,32,116,121,112,101,61,82,79,77,32,99,111,110,116,101,110, - 116,61,80,114,111,103,114,97,109,10,32,32,32,32,109,97,112,32,97,100,100,114,101,115,115,61,48,48,45,55,100,44, - 56,48,45,102,102,58,56,48,48,48,45,102,102,102,102,32,109,97,115,107,61,48,120,56,48,48,48,10,32,32,109,101, - 109,111,114,121,32,116,121,112,101,61,82,65,77,32,99,111,110,116,101,110,116,61,83,97,118,101,10,32,32,32,32,109, - 97,112,32,97,100,100,114,101,115,115,61,55,48,45,55,100,44,102,48,45,102,102,58,48,48,48,48,45,55,102,102,102, - 32,109,97,115,107,61,48,120,56,48,48,48,10,10,98,111,97,114,100,58,32,83,72,86,67,45,49,65,51,66,45,40, - 49,49,44,49,50,44,49,51,41,10,32,32,109,101,109,111,114,121,32,116,121,112,101,61,82,79,77,32,99,111,110,116, - 101,110,116,61,80,114,111,103,114,97,109,10,32,32,32,32,109,97,112,32,97,100,100,114,101,115,115,61,48,48,45,49, - 102,44,56,48,45,57,102,58,56,48,48,48,45,102,102,102,102,32,109,97,115,107,61,48,120,56,48,48,48,10,32,32, - 109,101,109,111,114,121,32,116,121,112,101,61,82,65,77,32,99,111,110,116,101,110,116,61,83,97,118,101,10,32,32,32, - 32,109,97,112,32,97,100,100,114,101,115,115,61,55,48,45,55,100,44,102,48,45,102,102,58,48,48,48,48,45,102,102, - 102,102,10,10,98,111,97,114,100,58,32,83,72,86,67,45,49,65,51,66,45,50,48,10,32,32,109,101,109,111,114,121, - 32,116,121,112,101,61,82,79,77,32,99,111,110,116,101,110,116,61,80,114,111,103,114,97,109,10,32,32,32,32,109,97, - 112,32,97,100,100,114,101,115,115,61,48,48,45,55,100,44,56,48,45,102,102,58,56,48,48,48,45,102,102,102,102,32, - 109,97,115,107,61,48,120,56,48,48,48,10,32,32,109,101,109,111,114,121,32,116,121,112,101,61,82,65,77,32,99,111, - 110,116,101,110,116,61,83,97,118,101,10,32,32,32,32,109,97,112,32,97,100,100,114,101,115,115,61,55,48,45,55,100, - 44,102,48,45,102,102,58,48,48,48,48,45,55,102,102,102,32,109,97,115,107,61,48,120,56,48,48,48,10,10,98,111, - 97,114,100,58,32,83,72,86,67,45,49,65,51,77,45,40,49,48,44,50,48,44,50,49,44,51,48,41,10,32,32,109, - 101,109,111,114,121,32,116,121,112,101,61,82,79,77,32,99,111,110,116,101,110,116,61,80,114,111,103,114,97,109,10,32, - 32,32,32,109,97,112,32,97,100,100,114,101,115,115,61,48,48,45,55,100,44,56,48,45,102,102,58,56,48,48,48,45, - 102,102,102,102,32,109,97,115,107,61,48,120,56,48,48,48,10,32,32,109,101,109,111,114,121,32,116,121,112,101,61,82, - 65,77,32,99,111,110,116,101,110,116,61,83,97,118,101,10,32,32,32,32,109,97,112,32,97,100,100,114,101,115,115,61, - 55,48,45,55,100,44,102,48,45,102,102,58,48,48,48,48,45,55,102,102,102,32,109,97,115,107,61,48,120,56,48,48, - 48,10,10,98,111,97,114,100,58,32,83,72,86,67,45,49,65,53,66,45,40,48,50,44,48,52,41,10,32,32,109,101, - 109,111,114,121,32,116,121,112,101,61,82,79,77,32,99,111,110,116,101,110,116,61,80,114,111,103,114,97,109,10,32,32, - 32,32,109,97,112,32,97,100,100,114,101,115,115,61,48,48,45,49,102,44,56,48,45,57,102,58,56,48,48,48,45,102, - 102,102,102,32,109,97,115,107,61,48,120,56,48,48,48,10,32,32,109,101,109,111,114,121,32,116,121,112,101,61,82,65, - 77,32,99,111,110,116,101,110,116,61,83,97,118,101,10,32,32,32,32,109,97,112,32,97,100,100,114,101,115,115,61,55, - 48,45,55,100,44,102,48,45,102,102,58,48,48,48,48,45,102,102,102,102,10,10,98,111,97,114,100,58,32,83,72,86, - 67,45,49,65,53,77,45,40,48,49,44,49,49,44,50,48,41,10,32,32,109,101,109,111,114,121,32,116,121,112,101,61, - 82,79,77,32,99,111,110,116,101,110,116,61,80,114,111,103,114,97,109,10,32,32,32,32,109,97,112,32,97,100,100,114, - 101,115,115,61,48,48,45,55,100,44,56,48,45,102,102,58,56,48,48,48,45,102,102,102,102,32,109,97,115,107,61,48, - 120,56,48,48,48,10,32,32,109,101,109,111,114,121,32,116,121,112,101,61,82,65,77,32,99,111,110,116,101,110,116,61, - 83,97,118,101,10,32,32,32,32,109,97,112,32,97,100,100,114,101,115,115,61,55,48,45,55,100,44,102,48,45,102,102, - 58,48,48,48,48,45,55,102,102,102,32,109,97,115,107,61,48,120,56,48,48,48,10,10,98,111,97,114,100,58,32,83, - 72,86,67,45,49,66,48,78,45,40,48,50,44,48,51,44,49,48,41,10,32,32,109,101,109,111,114,121,32,116,121,112, - 101,61,82,79,77,32,99,111,110,116,101,110,116,61,80,114,111,103,114,97,109,10,32,32,32,32,109,97,112,32,97,100, - 100,114,101,115,115,61,48,48,45,49,102,44,56,48,45,57,102,58,56,48,48,48,45,102,102,102,102,32,109,97,115,107, - 61,48,120,56,48,48,48,10,32,32,112,114,111,99,101,115,115,111,114,32,97,114,99,104,105,116,101,99,116,117,114,101, - 61,117,80,68,55,55,50,53,10,32,32,32,32,109,97,112,32,97,100,100,114,101,115,115,61,51,48,45,51,102,44,98, - 48,45,98,102,58,56,48,48,48,45,102,102,102,102,32,109,97,115,107,61,48,120,51,102,102,102,10,32,32,32,32,109, - 101,109,111,114,121,32,116,121,112,101,61,82,79,77,32,99,111,110,116,101,110,116,61,80,114,111,103,114,97,109,32,97, - 114,99,104,105,116,101,99,116,117,114,101,61,117,80,68,55,55,50,53,10,32,32,32,32,109,101,109,111,114,121,32,116, - 121,112,101,61,82,79,77,32,99,111,110,116,101,110,116,61,68,97,116,97,32,97,114,99,104,105,116,101,99,116,117,114, - 101,61,117,80,68,55,55,50,53,10,32,32,32,32,109,101,109,111,114,121,32,116,121,112,101,61,82,65,77,32,99,111, - 110,116,101,110,116,61,68,97,116,97,32,97,114,99,104,105,116,101,99,116,117,114,101,61,117,80,68,55,55,50,53,10, - 32,32,32,32,111,115,99,105,108,108,97,116,111,114,10,10,98,111,97,114,100,58,32,83,72,86,67,45,49,66,53,66, - 45,48,50,10,32,32,109,101,109,111,114,121,32,116,121,112,101,61,82,79,77,32,99,111,110,116,101,110,116,61,80,114, - 111,103,114,97,109,10,32,32,32,32,109,97,112,32,97,100,100,114,101,115,115,61,48,48,45,49,102,44,56,48,45,57, - 102,58,56,48,48,48,45,102,102,102,102,32,109,97,115,107,61,48,120,56,48,48,48,10,32,32,109,101,109,111,114,121, - 32,116,121,112,101,61,82,65,77,32,99,111,110,116,101,110,116,61,83,97,118,101,10,32,32,32,32,109,97,112,32,97, - 100,100,114,101,115,115,61,55,48,45,55,100,44,102,48,45,102,102,58,48,48,48,48,45,102,102,102,102,10,32,32,112, - 114,111,99,101,115,115,111,114,32,97,114,99,104,105,116,101,99,116,117,114,101,61,117,80,68,55,55,50,53,10,32,32, - 32,32,109,97,112,32,97,100,100,114,101,115,115,61,50,48,45,51,102,44,97,48,45,98,102,58,56,48,48,48,45,102, - 102,102,102,32,109,97,115,107,61,48,120,51,102,102,102,10,32,32,32,32,109,101,109,111,114,121,32,116,121,112,101,61, - 82,79,77,32,99,111,110,116,101,110,116,61,80,114,111,103,114,97,109,32,97,114,99,104,105,116,101,99,116,117,114,101, - 61,117,80,68,55,55,50,53,10,32,32,32,32,109,101,109,111,114,121,32,116,121,112,101,61,82,79,77,32,99,111,110, - 116,101,110,116,61,68,97,116,97,32,97,114,99,104,105,116,101,99,116,117,114,101,61,117,80,68,55,55,50,53,10,32, - 32,32,32,109,101,109,111,114,121,32,116,121,112,101,61,82,65,77,32,99,111,110,116,101,110,116,61,68,97,116,97,32, - 97,114,99,104,105,116,101,99,116,117,114,101,61,117,80,68,55,55,50,53,10,32,32,32,32,111,115,99,105,108,108,97, - 116,111,114,10,10,98,111,97,114,100,58,32,83,72,86,67,45,49,67,48,78,10,32,32,112,114,111,99,101,115,115,111, - 114,32,97,114,99,104,105,116,101,99,116,117,114,101,61,71,83,85,10,32,32,32,32,109,97,112,32,97,100,100,114,101, - 115,115,61,48,48,45,51,102,44,56,48,45,98,102,58,51,48,48,48,45,51,52,102,102,10,32,32,32,32,109,101,109, - 111,114,121,32,116,121,112,101,61,82,79,77,32,99,111,110,116,101,110,116,61,80,114,111,103,114,97,109,10,32,32,32, - 32,32,32,109,97,112,32,97,100,100,114,101,115,115,61,48,48,45,49,102,44,56,48,45,57,102,58,56,48,48,48,45, - 102,102,102,102,32,109,97,115,107,61,48,120,56,48,48,48,10,32,32,32,32,109,101,109,111,114,121,32,116,121,112,101, - 61,82,65,77,32,99,111,110,116,101,110,116,61,83,97,118,101,10,32,32,32,32,32,32,109,97,112,32,97,100,100,114, - 101,115,115,61,54,48,45,55,100,44,101,48,45,102,102,58,48,48,48,48,45,102,102,102,102,10,10,98,111,97,114,100, - 58,32,83,72,86,67,45,49,67,48,78,53,83,45,48,49,10,32,32,112,114,111,99,101,115,115,111,114,32,97,114,99, - 104,105,116,101,99,116,117,114,101,61,71,83,85,10,32,32,32,32,109,97,112,32,97,100,100,114,101,115,115,61,48,48, - 45,51,102,44,56,48,45,98,102,58,51,48,48,48,45,51,52,102,102,10,32,32,32,32,109,101,109,111,114,121,32,116, - 121,112,101,61,82,79,77,32,99,111,110,116,101,110,116,61,80,114,111,103,114,97,109,10,32,32,32,32,32,32,109,97, - 112,32,97,100,100,114,101,115,115,61,48,48,45,49,102,44,56,48,45,57,102,58,56,48,48,48,45,102,102,102,102,32, - 109,97,115,107,61,48,120,56,48,48,48,10,32,32,32,32,109,101,109,111,114,121,32,116,121,112,101,61,82,65,77,32, - 99,111,110,116,101,110,116,61,83,97,118,101,10,32,32,32,32,32,32,109,97,112,32,97,100,100,114,101,115,115,61,54, - 48,45,55,100,44,101,48,45,102,102,58,48,48,48,48,45,102,102,102,102,10,10,98,111,97,114,100,58,32,83,72,86, - 67,45,49,67,65,48,78,53,83,45,48,49,10,32,32,112,114,111,99,101,115,115,111,114,32,97,114,99,104,105,116,101, - 99,116,117,114,101,61,71,83,85,10,32,32,32,32,109,97,112,32,97,100,100,114,101,115,115,61,48,48,45,51,102,44, - 56,48,45,98,102,58,51,48,48,48,45,51,52,102,102,10,32,32,32,32,109,101,109,111,114,121,32,116,121,112,101,61, - 82,79,77,32,99,111,110,116,101,110,116,61,80,114,111,103,114,97,109,10,32,32,32,32,32,32,109,97,112,32,97,100, - 100,114,101,115,115,61,48,48,45,51,102,44,56,48,45,98,102,58,56,48,48,48,45,102,102,102,102,32,109,97,115,107, - 61,48,120,56,48,48,48,10,32,32,32,32,32,32,109,97,112,32,97,100,100,114,101,115,115,61,52,48,45,53,102,44, - 99,48,45,100,102,58,48,48,48,48,45,102,102,102,102,10,32,32,32,32,109,101,109,111,114,121,32,116,121,112,101,61, - 82,65,77,32,99,111,110,116,101,110,116,61,83,97,118,101,10,32,32,32,32,32,32,109,97,112,32,97,100,100,114,101, - 115,115,61,48,48,45,51,102,44,56,48,45,98,102,58,54,48,48,48,45,55,102,102,102,32,115,105,122,101,61,48,120, - 50,48,48,48,10,32,32,32,32,32,32,109,97,112,32,97,100,100,114,101,115,115,61,55,48,45,55,49,44,102,48,45, - 102,49,58,48,48,48,48,45,102,102,102,102,10,10,98,111,97,114,100,58,32,83,72,86,67,45,49,67,65,48,78,54, - 83,45,48,49,10,32,32,112,114,111,99,101,115,115,111,114,32,97,114,99,104,105,116,101,99,116,117,114,101,61,71,83, - 85,10,32,32,32,32,109,97,112,32,97,100,100,114,101,115,115,61,48,48,45,51,102,44,56,48,45,98,102,58,51,48, - 48,48,45,51,52,102,102,10,32,32,32,32,109,101,109,111,114,121,32,116,121,112,101,61,82,79,77,32,99,111,110,116, - 101,110,116,61,80,114,111,103,114,97,109,10,32,32,32,32,32,32,109,97,112,32,97,100,100,114,101,115,115,61,48,48, - 45,51,102,44,56,48,45,98,102,58,56,48,48,48,45,102,102,102,102,32,109,97,115,107,61,48,120,56,48,48,48,10, - 32,32,32,32,32,32,109,97,112,32,97,100,100,114,101,115,115,61,52,48,45,53,102,44,99,48,45,100,102,58,48,48, - 48,48,45,102,102,102,102,10,32,32,32,32,109,101,109,111,114,121,32,116,121,112,101,61,82,65,77,32,99,111,110,116, - 101,110,116,61,83,97,118,101,10,32,32,32,32,32,32,109,97,112,32,97,100,100,114,101,115,115,61,48,48,45,51,102, - 44,56,48,45,98,102,58,54,48,48,48,45,55,102,102,102,32,115,105,122,101,61,48,120,50,48,48,48,10,32,32,32, - 32,32,32,109,97,112,32,97,100,100,114,101,115,115,61,55,48,45,55,49,44,102,48,45,102,49,58,48,48,48,48,45, - 102,102,102,102,10,10,98,111,97,114,100,58,32,83,72,86,67,45,49,67,65,54,66,45,48,49,10,32,32,112,114,111, - 99,101,115,115,111,114,32,97,114,99,104,105,116,101,99,116,117,114,101,61,71,83,85,10,32,32,32,32,109,97,112,32, - 97,100,100,114,101,115,115,61,48,48,45,51,102,44,56,48,45,98,102,58,51,48,48,48,45,51,52,102,102,10,32,32, - 32,32,109,101,109,111,114,121,32,116,121,112,101,61,82,79,77,32,99,111,110,116,101,110,116,61,80,114,111,103,114,97, - 109,10,32,32,32,32,32,32,109,97,112,32,97,100,100,114,101,115,115,61,48,48,45,51,102,44,56,48,45,98,102,58, - 56,48,48,48,45,102,102,102,102,32,109,97,115,107,61,48,120,56,48,48,48,10,32,32,32,32,32,32,109,97,112,32, - 97,100,100,114,101,115,115,61,52,48,45,53,102,44,99,48,45,100,102,58,48,48,48,48,45,102,102,102,102,10,32,32, - 32,32,109,101,109,111,114,121,32,116,121,112,101,61,82,65,77,32,99,111,110,116,101,110,116,61,83,97,118,101,10,32, - 32,32,32,32,32,109,97,112,32,97,100,100,114,101,115,115,61,48,48,45,51,102,44,56,48,45,98,102,58,54,48,48, - 48,45,55,102,102,102,32,115,105,122,101,61,48,120,50,48,48,48,10,32,32,32,32,32,32,109,97,112,32,97,100,100, - 114,101,115,115,61,55,48,45,55,49,44,102,48,45,102,49,58,48,48,48,48,45,102,102,102,102,10,10,98,111,97,114, - 100,58,32,83,72,86,67,45,49,67,66,48,78,55,83,45,48,49,10,32,32,112,114,111,99,101,115,115,111,114,32,97, - 114,99,104,105,116,101,99,116,117,114,101,61,71,83,85,10,32,32,32,32,109,97,112,32,97,100,100,114,101,115,115,61, - 48,48,45,51,102,44,56,48,45,98,102,58,51,48,48,48,45,51,52,102,102,10,32,32,32,32,109,101,109,111,114,121, - 32,116,121,112,101,61,82,79,77,32,99,111,110,116,101,110,116,61,80,114,111,103,114,97,109,10,32,32,32,32,32,32, - 109,97,112,32,97,100,100,114,101,115,115,61,48,48,45,51,102,58,56,48,48,48,45,102,102,102,102,32,109,97,115,107, - 61,48,120,56,48,48,48,10,32,32,32,32,32,32,109,97,112,32,97,100,100,114,101,115,115,61,52,48,45,53,102,58, - 48,48,48,48,45,102,102,102,102,10,32,32,32,32,109,101,109,111,114,121,32,116,121,112,101,61,82,65,77,32,99,111, - 110,116,101,110,116,61,83,97,118,101,10,32,32,32,32,32,32,109,97,112,32,97,100,100,114,101,115,115,61,48,48,45, - 51,102,44,56,48,45,98,102,58,54,48,48,48,45,55,102,102,102,32,115,105,122,101,61,48,120,50,48,48,48,10,32, - 32,32,32,32,32,109,97,112,32,97,100,100,114,101,115,115,61,55,48,45,55,49,58,48,48,48,48,45,102,102,102,102, - 10,10,98,111,97,114,100,58,32,83,72,86,67,45,49,67,66,53,66,45,50,48,10,32,32,112,114,111,99,101,115,115, - 111,114,32,97,114,99,104,105,116,101,99,116,117,114,101,61,71,83,85,10,32,32,32,32,109,97,112,32,97,100,100,114, - 101,115,115,61,48,48,45,51,102,44,56,48,45,98,102,58,51,48,48,48,45,51,52,102,102,10,32,32,32,32,109,101, - 109,111,114,121,32,116,121,112,101,61,82,79,77,32,99,111,110,116,101,110,116,61,80,114,111,103,114,97,109,10,32,32, - 32,32,32,32,109,97,112,32,97,100,100,114,101,115,115,61,48,48,45,51,102,58,56,48,48,48,45,102,102,102,102,32, - 109,97,115,107,61,48,120,56,48,48,48,10,32,32,32,32,32,32,109,97,112,32,97,100,100,114,101,115,115,61,52,48, - 45,53,102,58,48,48,48,48,45,102,102,102,102,10,32,32,32,32,109,101,109,111,114,121,32,116,121,112,101,61,82,65, - 77,32,99,111,110,116,101,110,116,61,83,97,118,101,10,32,32,32,32,32,32,109,97,112,32,97,100,100,114,101,115,115, - 61,48,48,45,51,102,44,56,48,45,98,102,58,54,48,48,48,45,55,102,102,102,32,115,105,122,101,61,48,120,50,48, - 48,48,10,32,32,32,32,32,32,109,97,112,32,97,100,100,114,101,115,115,61,55,48,45,55,49,58,48,48,48,48,45, - 102,102,102,102,10,10,98,111,97,114,100,58,32,83,72,86,67,45,49,67,66,55,66,45,48,49,10,32,32,112,114,111, - 99,101,115,115,111,114,32,97,114,99,104,105,116,101,99,116,117,114,101,61,71,83,85,10,32,32,32,32,109,97,112,32, - 97,100,100,114,101,115,115,61,48,48,45,51,102,44,56,48,45,98,102,58,51,48,48,48,45,51,52,102,102,10,32,32, - 32,32,109,101,109,111,114,121,32,116,121,112,101,61,82,79,77,32,99,111,110,116,101,110,116,61,80,114,111,103,114,97, - 109,10,32,32,32,32,32,32,109,97,112,32,97,100,100,114,101,115,115,61,48,48,45,51,102,58,56,48,48,48,45,102, - 102,102,102,32,109,97,115,107,61,48,120,56,48,48,48,10,32,32,32,32,32,32,109,97,112,32,97,100,100,114,101,115, - 115,61,52,48,45,53,102,58,48,48,48,48,45,102,102,102,102,10,32,32,32,32,109,101,109,111,114,121,32,116,121,112, - 101,61,82,65,77,32,99,111,110,116,101,110,116,61,83,97,118,101,10,32,32,32,32,32,32,109,97,112,32,97,100,100, - 114,101,115,115,61,48,48,45,51,102,44,56,48,45,98,102,58,54,48,48,48,45,55,102,102,102,32,115,105,122,101,61, - 48,120,50,48,48,48,10,32,32,32,32,32,32,109,97,112,32,97,100,100,114,101,115,115,61,55,48,45,55,49,58,48, - 48,48,48,45,102,102,102,102,10,10,98,111,97,114,100,58,32,83,72,86,67,45,49,68,67,48,78,45,48,49,10,32, - 32,112,114,111,99,101,115,115,111,114,32,97,114,99,104,105,116,101,99,116,117,114,101,61,72,71,53,49,66,83,49,54, - 57,10,32,32,32,32,109,97,112,32,97,100,100,114,101,115,115,61,48,48,45,51,102,44,56,48,45,98,102,58,54,99, - 48,48,45,54,102,102,102,44,55,99,48,48,45,55,102,102,102,10,32,32,32,32,109,101,109,111,114,121,32,116,121,112, - 101,61,82,79,77,32,99,111,110,116,101,110,116,61,80,114,111,103,114,97,109,10,32,32,32,32,32,32,109,97,112,32, - 97,100,100,114,101,115,115,61,48,48,45,51,102,44,56,48,45,98,102,58,56,48,48,48,45,102,102,102,102,32,109,97, - 115,107,61,48,120,56,48,48,48,10,32,32,32,32,109,101,109,111,114,121,32,116,121,112,101,61,82,65,77,32,99,111, - 110,116,101,110,116,61,83,97,118,101,10,32,32,32,32,32,32,109,97,112,32,97,100,100,114,101,115,115,61,55,48,45, - 55,55,58,48,48,48,48,45,55,102,102,102,10,32,32,32,32,109,101,109,111,114,121,32,116,121,112,101,61,82,79,77, - 32,99,111,110,116,101,110,116,61,68,97,116,97,32,97,114,99,104,105,116,101,99,116,117,114,101,61,72,71,53,49,66, - 83,49,54,57,10,32,32,32,32,109,101,109,111,114,121,32,116,121,112,101,61,82,65,77,32,99,111,110,116,101,110,116, - 61,68,97,116,97,32,97,114,99,104,105,116,101,99,116,117,114,101,61,72,71,53,49,66,83,49,54,57,10,32,32,32, - 32,32,32,109,97,112,32,97,100,100,114,101,115,115,61,48,48,45,51,102,44,56,48,45,98,102,58,54,48,48,48,45, - 54,98,102,102,44,55,48,48,48,45,55,98,102,102,32,109,97,115,107,61,48,120,102,48,48,48,10,32,32,32,32,111, - 115,99,105,108,108,97,116,111,114,10,10,98,111,97,114,100,58,32,83,72,86,67,45,49,68,83,48,66,45,50,48,10, - 32,32,109,101,109,111,114,121,32,116,121,112,101,61,82,79,77,32,99,111,110,116,101,110,116,61,80,114,111,103,114,97, - 109,10,32,32,32,32,109,97,112,32,97,100,100,114,101,115,115,61,48,48,45,55,100,44,56,48,45,102,102,58,56,48, - 48,48,45,102,102,102,102,32,109,97,115,107,61,48,120,56,48,48,48,10,32,32,112,114,111,99,101,115,115,111,114,32, - 97,114,99,104,105,116,101,99,116,117,114,101,61,117,80,68,57,54,48,53,48,10,32,32,32,32,109,97,112,32,97,100, - 100,114,101,115,115,61,54,48,45,54,55,44,101,48,45,101,55,58,48,48,48,48,45,51,102,102,102,10,32,32,32,32, - 109,101,109,111,114,121,32,116,121,112,101,61,82,79,77,32,99,111,110,116,101,110,116,61,80,114,111,103,114,97,109,32, - 97,114,99,104,105,116,101,99,116,117,114,101,61,117,80,68,57,54,48,53,48,10,32,32,32,32,109,101,109,111,114,121, - 32,116,121,112,101,61,82,79,77,32,99,111,110,116,101,110,116,61,68,97,116,97,32,97,114,99,104,105,116,101,99,116, - 117,114,101,61,117,80,68,57,54,48,53,48,10,32,32,32,32,109,101,109,111,114,121,32,116,121,112,101,61,82,65,77, - 32,99,111,110,116,101,110,116,61,68,97,116,97,32,97,114,99,104,105,116,101,99,116,117,114,101,61,117,80,68,57,54, - 48,53,48,10,32,32,32,32,32,32,109,97,112,32,97,100,100,114,101,115,115,61,54,56,45,54,102,44,101,56,45,101, - 102,58,48,48,48,48,45,55,102,102,102,32,109,97,115,107,61,48,120,56,48,48,48,10,32,32,32,32,111,115,99,105, - 108,108,97,116,111,114,10,10,98,111,97,114,100,58,32,83,72,86,67,45,49,74,48,78,45,40,48,49,44,49,48,44, - 50,48,41,10,32,32,109,101,109,111,114,121,32,116,121,112,101,61,82,79,77,32,99,111,110,116,101,110,116,61,80,114, - 111,103,114,97,109,10,32,32,32,32,109,97,112,32,97,100,100,114,101,115,115,61,48,48,45,51,102,44,56,48,45,98, - 102,58,56,48,48,48,45,102,102,102,102,10,32,32,32,32,109,97,112,32,97,100,100,114,101,115,115,61,52,48,45,55, - 100,44,99,48,45,102,102,58,48,48,48,48,45,102,102,102,102,10,10,98,111,97,114,100,58,32,83,72,86,67,45,49, - 74,49,77,45,40,49,49,44,50,48,41,10,32,32,109,101,109,111,114,121,32,116,121,112,101,61,82,79,77,32,99,111, - 110,116,101,110,116,61,80,114,111,103,114,97,109,10,32,32,32,32,109,97,112,32,97,100,100,114,101,115,115,61,48,48, - 45,51,102,44,56,48,45,98,102,58,56,48,48,48,45,102,102,102,102,10,32,32,32,32,109,97,112,32,97,100,100,114, - 101,115,115,61,52,48,45,55,100,44,99,48,45,102,102,58,48,48,48,48,45,102,102,102,102,10,32,32,109,101,109,111, - 114,121,32,116,121,112,101,61,82,65,77,32,99,111,110,116,101,110,116,61,83,97,118,101,10,32,32,32,32,109,97,112, - 32,97,100,100,114,101,115,115,61,50,48,45,51,102,44,97,48,45,98,102,58,54,48,48,48,45,55,102,102,102,32,109, - 97,115,107,61,48,120,101,48,48,48,10,10,98,111,97,114,100,58,32,83,72,86,67,45,49,74,51,66,45,48,49,10, - 32,32,109,101,109,111,114,121,32,116,121,112,101,61,82,79,77,32,99,111,110,116,101,110,116,61,80,114,111,103,114,97, - 109,10,32,32,32,32,109,97,112,32,97,100,100,114,101,115,115,61,48,48,45,51,102,44,56,48,45,98,102,58,56,48, - 48,48,45,102,102,102,102,10,32,32,32,32,109,97,112,32,97,100,100,114,101,115,115,61,52,48,45,55,100,44,99,48, - 45,102,102,58,48,48,48,48,45,102,102,102,102,10,32,32,109,101,109,111,114,121,32,116,121,112,101,61,82,65,77,32, - 99,111,110,116,101,110,116,61,83,97,118,101,10,32,32,32,32,109,97,112,32,97,100,100,114,101,115,115,61,50,48,45, - 51,102,44,97,48,45,98,102,58,54,48,48,48,45,55,102,102,102,32,109,97,115,107,61,48,120,101,48,48,48,10,10, - 98,111,97,114,100,58,32,83,72,86,67,45,49,74,51,77,45,40,48,49,44,49,49,44,50,48,41,10,32,32,109,101, - 109,111,114,121,32,116,121,112,101,61,82,79,77,32,99,111,110,116,101,110,116,61,80,114,111,103,114,97,109,10,32,32, - 32,32,109,97,112,32,97,100,100,114,101,115,115,61,48,48,45,51,102,44,56,48,45,98,102,58,56,48,48,48,45,102, - 102,102,102,10,32,32,32,32,109,97,112,32,97,100,100,114,101,115,115,61,52,48,45,55,100,44,99,48,45,102,102,58, - 48,48,48,48,45,102,102,102,102,10,32,32,109,101,109,111,114,121,32,116,121,112,101,61,82,65,77,32,99,111,110,116, - 101,110,116,61,83,97,118,101,10,32,32,32,32,109,97,112,32,97,100,100,114,101,115,115,61,50,48,45,51,102,44,97, - 48,45,98,102,58,54,48,48,48,45,55,102,102,102,32,109,97,115,107,61,48,120,101,48,48,48,10,10,98,111,97,114, - 100,58,32,83,72,86,67,45,49,74,53,77,45,40,48,49,44,49,49,44,50,48,41,10,32,32,109,101,109,111,114,121, - 32,116,121,112,101,61,82,79,77,32,99,111,110,116,101,110,116,61,80,114,111,103,114,97,109,10,32,32,32,32,109,97, - 112,32,97,100,100,114,101,115,115,61,48,48,45,51,102,44,56,48,45,98,102,58,56,48,48,48,45,102,102,102,102,10, - 32,32,32,32,109,97,112,32,97,100,100,114,101,115,115,61,52,48,45,55,100,44,99,48,45,102,102,58,48,48,48,48, - 45,102,102,102,102,10,32,32,109,101,109,111,114,121,32,116,121,112,101,61,82,65,77,32,99,111,110,116,101,110,116,61, - 83,97,118,101,10,32,32,32,32,109,97,112,32,97,100,100,114,101,115,115,61,50,48,45,51,102,44,97,48,45,98,102, - 58,54,48,48,48,45,55,102,102,102,32,109,97,115,107,61,48,120,101,48,48,48,10,10,98,111,97,114,100,58,32,83, - 72,86,67,45,49,75,48,78,45,48,49,10,32,32,109,101,109,111,114,121,32,116,121,112,101,61,82,79,77,32,99,111, - 110,116,101,110,116,61,80,114,111,103,114,97,109,10,32,32,32,32,109,97,112,32,97,100,100,114,101,115,115,61,48,48, - 45,51,102,44,56,48,45,98,102,58,56,48,48,48,45,102,102,102,102,10,32,32,32,32,109,97,112,32,97,100,100,114, - 101,115,115,61,52,48,45,55,100,44,99,48,45,102,102,58,48,48,48,48,45,102,102,102,102,10,32,32,112,114,111,99, - 101,115,115,111,114,32,97,114,99,104,105,116,101,99,116,117,114,101,61,117,80,68,55,55,50,53,10,32,32,32,32,109, - 97,112,32,97,100,100,114,101,115,115,61,48,48,45,49,102,44,56,48,45,57,102,58,54,48,48,48,45,55,102,102,102, - 32,109,97,115,107,61,48,120,102,102,102,10,32,32,32,32,109,101,109,111,114,121,32,116,121,112,101,61,82,79,77,32, - 99,111,110,116,101,110,116,61,80,114,111,103,114,97,109,32,97,114,99,104,105,116,101,99,116,117,114,101,61,117,80,68, - 55,55,50,53,10,32,32,32,32,109,101,109,111,114,121,32,116,121,112,101,61,82,79,77,32,99,111,110,116,101,110,116, - 61,68,97,116,97,32,97,114,99,104,105,116,101,99,116,117,114,101,61,117,80,68,55,55,50,53,10,32,32,32,32,109, - 101,109,111,114,121,32,116,121,112,101,61,82,65,77,32,99,111,110,116,101,110,116,61,68,97,116,97,32,97,114,99,104, - 105,116,101,99,116,117,114,101,61,117,80,68,55,55,50,53,10,32,32,32,32,111,115,99,105,108,108,97,116,111,114,10, - 10,98,111,97,114,100,58,32,83,72,86,67,45,49,75,49,66,45,48,49,10,32,32,109,101,109,111,114,121,32,116,121, - 112,101,61,82,79,77,32,99,111,110,116,101,110,116,61,80,114,111,103,114,97,109,10,32,32,32,32,109,97,112,32,97, - 100,100,114,101,115,115,61,48,48,45,51,102,44,56,48,45,98,102,58,56,48,48,48,45,102,102,102,102,10,32,32,32, - 32,109,97,112,32,97,100,100,114,101,115,115,61,52,48,45,55,100,44,99,48,45,102,102,58,48,48,48,48,45,102,102, - 102,102,10,32,32,109,101,109,111,114,121,32,116,121,112,101,61,82,65,77,32,99,111,110,116,101,110,116,61,83,97,118, - 101,10,32,32,32,32,109,97,112,32,97,100,100,114,101,115,115,61,50,48,45,51,102,44,97,48,45,98,102,58,54,48, - 48,48,45,55,102,102,102,32,109,97,115,107,61,48,120,101,48,48,48,10,32,32,112,114,111,99,101,115,115,111,114,32, - 97,114,99,104,105,116,101,99,116,117,114,101,61,117,80,68,55,55,50,53,10,32,32,32,32,109,97,112,32,97,100,100, - 114,101,115,115,61,48,48,45,49,102,44,56,48,45,57,102,58,54,48,48,48,45,55,102,102,102,32,109,97,115,107,61, - 48,120,102,102,102,10,32,32,32,32,109,101,109,111,114,121,32,116,121,112,101,61,82,79,77,32,99,111,110,116,101,110, - 116,61,80,114,111,103,114,97,109,32,97,114,99,104,105,116,101,99,116,117,114,101,61,117,80,68,55,55,50,53,10,32, - 32,32,32,109,101,109,111,114,121,32,116,121,112,101,61,82,79,77,32,99,111,110,116,101,110,116,61,68,97,116,97,32, - 97,114,99,104,105,116,101,99,116,117,114,101,61,117,80,68,55,55,50,53,10,32,32,32,32,109,101,109,111,114,121,32, - 116,121,112,101,61,82,65,77,32,99,111,110,116,101,110,116,61,68,97,116,97,32,97,114,99,104,105,116,101,99,116,117, - 114,101,61,117,80,68,55,55,50,53,10,32,32,32,32,111,115,99,105,108,108,97,116,111,114,10,10,98,111,97,114,100, - 58,32,83,72,86,67,45,49,76,48,78,51,83,45,48,49,10,32,32,112,114,111,99,101,115,115,111,114,32,97,114,99, - 104,105,116,101,99,116,117,114,101,61,87,54,53,67,56,49,54,83,10,32,32,32,32,109,97,112,32,97,100,100,114,101, - 115,115,61,48,48,45,51,102,44,56,48,45,98,102,58,50,50,48,48,45,50,51,102,102,10,32,32,32,32,109,99,117, - 10,32,32,32,32,32,32,109,97,112,32,97,100,100,114,101,115,115,61,48,48,45,51,102,44,56,48,45,98,102,58,56, - 48,48,48,45,102,102,102,102,32,109,97,115,107,61,48,120,52,48,56,48,48,48,10,32,32,32,32,32,32,109,97,112, - 32,97,100,100,114,101,115,115,61,99,48,45,102,102,58,48,48,48,48,45,102,102,102,102,10,32,32,32,32,32,32,109, - 101,109,111,114,121,32,116,121,112,101,61,82,79,77,32,99,111,110,116,101,110,116,61,80,114,111,103,114,97,109,10,32, - 32,32,32,109,101,109,111,114,121,32,116,121,112,101,61,82,65,77,32,99,111,110,116,101,110,116,61,83,97,118,101,10, - 32,32,32,32,32,32,109,97,112,32,97,100,100,114,101,115,115,61,48,48,45,51,102,44,56,48,45,98,102,58,54,48, - 48,48,45,55,102,102,102,32,115,105,122,101,61,48,120,50,48,48,48,10,32,32,32,32,32,32,109,97,112,32,97,100, - 100,114,101,115,115,61,52,48,45,52,102,58,48,48,48,48,45,102,102,102,102,10,32,32,32,32,109,101,109,111,114,121, - 32,116,121,112,101,61,82,65,77,32,99,111,110,116,101,110,116,61,73,110,116,101,114,110,97,108,10,32,32,32,32,32, - 32,109,97,112,32,97,100,100,114,101,115,115,61,48,48,45,51,102,44,56,48,45,98,102,58,51,48,48,48,45,51,55, - 102,102,32,115,105,122,101,61,48,120,56,48,48,10,10,98,111,97,114,100,58,32,83,72,86,67,45,49,76,51,66,45, - 40,48,50,44,49,49,41,10,32,32,112,114,111,99,101,115,115,111,114,32,97,114,99,104,105,116,101,99,116,117,114,101, - 61,87,54,53,67,56,49,54,83,10,32,32,32,32,109,97,112,32,97,100,100,114,101,115,115,61,48,48,45,51,102,44, - 56,48,45,98,102,58,50,50,48,48,45,50,51,102,102,10,32,32,32,32,109,99,117,10,32,32,32,32,32,32,109,97, - 112,32,97,100,100,114,101,115,115,61,48,48,45,51,102,44,56,48,45,98,102,58,56,48,48,48,45,102,102,102,102,32, - 109,97,115,107,61,48,120,52,48,56,48,48,48,10,32,32,32,32,32,32,109,97,112,32,97,100,100,114,101,115,115,61, - 99,48,45,102,102,58,48,48,48,48,45,102,102,102,102,10,32,32,32,32,32,32,109,101,109,111,114,121,32,116,121,112, - 101,61,82,79,77,32,99,111,110,116,101,110,116,61,80,114,111,103,114,97,109,10,32,32,32,32,109,101,109,111,114,121, - 32,116,121,112,101,61,82,65,77,32,99,111,110,116,101,110,116,61,83,97,118,101,10,32,32,32,32,32,32,109,97,112, - 32,97,100,100,114,101,115,115,61,48,48,45,51,102,44,56,48,45,98,102,58,54,48,48,48,45,55,102,102,102,32,115, - 105,122,101,61,48,120,50,48,48,48,10,32,32,32,32,32,32,109,97,112,32,97,100,100,114,101,115,115,61,52,48,45, - 52,102,58,48,48,48,48,45,102,102,102,102,10,32,32,32,32,109,101,109,111,114,121,32,116,121,112,101,61,82,65,77, - 32,99,111,110,116,101,110,116,61,73,110,116,101,114,110,97,108,10,32,32,32,32,32,32,109,97,112,32,97,100,100,114, - 101,115,115,61,48,48,45,51,102,44,56,48,45,98,102,58,51,48,48,48,45,51,55,102,102,32,115,105,122,101,61,48, - 120,56,48,48,10,10,98,111,97,114,100,58,32,83,72,86,67,45,49,76,53,66,45,40,49,49,44,50,48,41,10,32, - 32,112,114,111,99,101,115,115,111,114,32,97,114,99,104,105,116,101,99,116,117,114,101,61,87,54,53,67,56,49,54,83, - 10,32,32,32,32,109,97,112,32,97,100,100,114,101,115,115,61,48,48,45,51,102,44,56,48,45,98,102,58,50,50,48, - 48,45,50,51,102,102,10,32,32,32,32,109,99,117,10,32,32,32,32,32,32,109,97,112,32,97,100,100,114,101,115,115, - 61,48,48,45,51,102,44,56,48,45,98,102,58,56,48,48,48,45,102,102,102,102,32,109,97,115,107,61,48,120,52,48, - 56,48,48,48,10,32,32,32,32,32,32,109,97,112,32,97,100,100,114,101,115,115,61,99,48,45,102,102,58,48,48,48, - 48,45,102,102,102,102,10,32,32,32,32,32,32,109,101,109,111,114,121,32,116,121,112,101,61,82,79,77,32,99,111,110, - 116,101,110,116,61,80,114,111,103,114,97,109,10,32,32,32,32,109,101,109,111,114,121,32,116,121,112,101,61,82,65,77, - 32,99,111,110,116,101,110,116,61,83,97,118,101,10,32,32,32,32,32,32,109,97,112,32,97,100,100,114,101,115,115,61, - 48,48,45,51,102,44,56,48,45,98,102,58,54,48,48,48,45,55,102,102,102,32,115,105,122,101,61,48,120,50,48,48, - 48,10,32,32,32,32,32,32,109,97,112,32,97,100,100,114,101,115,115,61,52,48,45,52,102,58,48,48,48,48,45,102, - 102,102,102,10,32,32,32,32,109,101,109,111,114,121,32,116,121,112,101,61,82,65,77,32,99,111,110,116,101,110,116,61, - 73,110,116,101,114,110,97,108,10,32,32,32,32,32,32,109,97,112,32,97,100,100,114,101,115,115,61,48,48,45,51,102, - 44,56,48,45,98,102,58,51,48,48,48,45,51,55,102,102,32,115,105,122,101,61,48,120,56,48,48,10,10,98,111,97, - 114,100,58,32,83,72,86,67,45,49,78,48,78,45,40,48,49,44,49,48,41,10,32,32,112,114,111,99,101,115,115,111, - 114,32,105,100,101,110,116,105,102,105,101,114,61,83,68,68,49,10,32,32,32,32,109,97,112,32,97,100,100,114,101,115, - 115,61,48,48,45,51,102,44,56,48,45,98,102,58,52,56,48,48,45,52,56,48,102,10,32,32,32,32,109,99,117,10, - 32,32,32,32,32,32,109,97,112,32,97,100,100,114,101,115,115,61,48,48,45,51,102,44,56,48,45,98,102,58,56,48, - 48,48,45,102,102,102,102,10,32,32,32,32,32,32,109,97,112,32,97,100,100,114,101,115,115,61,99,48,45,102,102,58, - 48,48,48,48,45,102,102,102,102,10,32,32,32,32,32,32,109,101,109,111,114,121,32,116,121,112,101,61,82,79,77,32, - 99,111,110,116,101,110,116,61,80,114,111,103,114,97,109,10,10,98,111,97,114,100,58,32,83,72,86,67,45,50,65,48, - 78,45,48,49,35,65,10,32,32,109,101,109,111,114,121,32,116,121,112,101,61,82,79,77,32,99,111,110,116,101,110,116, - 61,80,114,111,103,114,97,109,10,32,32,32,32,109,97,112,32,97,100,100,114,101,115,115,61,48,48,45,50,102,44,56, - 48,45,97,102,58,56,48,48,48,45,102,102,102,102,32,109,97,115,107,61,48,120,56,48,48,48,10,32,32,32,32,109, - 97,112,32,97,100,100,114,101,115,115,61,52,48,45,54,102,44,99,48,45,101,102,58,48,48,48,48,45,102,102,102,102, - 32,109,97,115,107,61,48,120,56,48,48,48,10,10,98,111,97,114,100,58,32,83,72,86,67,45,50,65,48,78,45,40, - 48,49,44,49,48,44,49,49,44,50,48,41,10,32,32,109,101,109,111,114,121,32,116,121,112,101,61,82,79,77,32,99, - 111,110,116,101,110,116,61,80,114,111,103,114,97,109,10,32,32,32,32,109,97,112,32,97,100,100,114,101,115,115,61,48, - 48,45,55,100,44,56,48,45,102,102,58,56,48,48,48,45,102,102,102,102,32,109,97,115,107,61,48,120,56,48,48,48, - 10,32,32,32,32,109,97,112,32,97,100,100,114,101,115,115,61,52,48,45,55,100,44,99,48,45,102,102,58,48,48,48, - 48,45,55,102,102,102,32,109,97,115,107,61,48,120,56,48,48,48,10,10,98,111,97,114,100,58,32,83,72,86,67,45, - 50,65,49,77,45,48,49,10,32,32,109,101,109,111,114,121,32,116,121,112,101,61,82,79,77,32,99,111,110,116,101,110, - 116,61,80,114,111,103,114,97,109,10,32,32,32,32,109,97,112,32,97,100,100,114,101,115,115,61,48,48,45,55,100,44, - 56,48,45,102,102,58,56,48,48,48,45,102,102,102,102,32,109,97,115,107,61,48,120,56,48,48,48,10,32,32,109,101, - 109,111,114,121,32,116,121,112,101,61,82,65,77,32,99,111,110,116,101,110,116,61,83,97,118,101,10,32,32,32,32,109, - 97,112,32,97,100,100,114,101,115,115,61,55,48,45,55,100,44,102,48,45,102,102,58,48,48,48,48,45,55,102,102,102, - 32,109,97,115,107,61,48,120,56,48,48,48,10,10,98,111,97,114,100,58,32,83,72,86,67,45,50,65,51,66,45,48, - 49,10,32,32,109,101,109,111,114,121,32,116,121,112,101,61,82,79,77,32,99,111,110,116,101,110,116,61,80,114,111,103, - 114,97,109,10,32,32,32,32,109,97,112,32,97,100,100,114,101,115,115,61,48,48,45,51,102,44,56,48,45,98,102,58, - 56,48,48,48,45,102,102,102,102,32,109,97,115,107,61,48,120,56,48,48,48,10,32,32,109,101,109,111,114,121,32,116, - 121,112,101,61,82,65,77,32,99,111,110,116,101,110,116,61,83,97,118,101,10,32,32,32,32,109,97,112,32,97,100,100, - 114,101,115,115,61,55,48,45,55,100,44,102,48,45,102,102,58,48,48,48,48,45,55,102,102,102,32,109,97,115,107,61, - 48,120,56,48,48,48,10,10,98,111,97,114,100,58,32,83,72,86,67,45,50,65,51,77,45,48,49,35,65,10,32,32, - 109,101,109,111,114,121,32,116,121,112,101,61,82,79,77,32,99,111,110,116,101,110,116,61,80,114,111,103,114,97,109,10, - 32,32,32,32,109,97,112,32,97,100,100,114,101,115,115,61,48,48,45,51,102,44,56,48,45,98,102,58,56,48,48,48, - 45,102,102,102,102,32,109,97,115,107,61,48,120,56,48,48,48,10,32,32,109,101,109,111,114,121,32,116,121,112,101,61, - 82,65,77,32,99,111,110,116,101,110,116,61,83,97,118,101,10,32,32,32,32,109,97,112,32,97,100,100,114,101,115,115, - 61,55,48,45,55,100,44,102,48,45,102,102,58,48,48,48,48,45,55,102,102,102,32,109,97,115,107,61,48,120,56,48, - 48,48,10,10,98,111,97,114,100,58,32,83,72,86,67,45,50,65,51,77,45,40,48,49,44,49,49,44,50,48,41,10, - 32,32,109,101,109,111,114,121,32,116,121,112,101,61,82,79,77,32,99,111,110,116,101,110,116,61,80,114,111,103,114,97, - 109,10,32,32,32,32,109,97,112,32,97,100,100,114,101,115,115,61,48,48,45,55,100,44,56,48,45,102,102,58,56,48, - 48,48,45,102,102,102,102,32,109,97,115,107,61,48,120,56,48,48,48,10,32,32,109,101,109,111,114,121,32,116,121,112, - 101,61,82,65,77,32,99,111,110,116,101,110,116,61,83,97,118,101,10,32,32,32,32,109,97,112,32,97,100,100,114,101, - 115,115,61,55,48,45,55,100,44,102,48,45,102,102,58,48,48,48,48,45,55,102,102,102,32,109,97,115,107,61,48,120, - 56,48,48,48,10,10,98,111,97,114,100,58,32,83,72,86,67,45,50,65,53,77,45,48,49,10,32,32,109,101,109,111, - 114,121,32,116,121,112,101,61,82,79,77,32,99,111,110,116,101,110,116,61,80,114,111,103,114,97,109,10,32,32,32,32, - 109,97,112,32,97,100,100,114,101,115,115,61,48,48,45,55,100,44,56,48,45,102,102,58,56,48,48,48,45,102,102,102, - 102,32,109,97,115,107,61,48,120,56,48,48,48,10,32,32,109,101,109,111,114,121,32,116,121,112,101,61,82,65,77,32, - 99,111,110,116,101,110,116,61,83,97,118,101,10,32,32,32,32,109,97,112,32,97,100,100,114,101,115,115,61,55,48,45, - 55,100,44,102,48,45,102,102,58,48,48,48,48,45,55,102,102,102,32,109,97,115,107,61,48,120,56,48,48,48,10,10, - 98,111,97,114,100,58,32,83,72,86,67,45,50,66,51,66,45,48,49,10,32,32,109,101,109,111,114,121,32,116,121,112, - 101,61,82,79,77,32,99,111,110,116,101,110,116,61,80,114,111,103,114,97,109,10,32,32,32,32,109,97,112,32,97,100, - 100,114,101,115,115,61,48,48,45,51,102,44,56,48,45,98,102,58,56,48,48,48,45,102,102,102,102,32,109,97,115,107, - 61,48,120,56,48,48,48,10,32,32,109,101,109,111,114,121,32,116,121,112,101,61,82,65,77,32,99,111,110,116,101,110, - 116,61,83,97,118,101,10,32,32,32,32,109,97,112,32,97,100,100,114,101,115,115,61,55,48,45,55,100,44,102,48,45, - 102,102,58,48,48,48,48,45,55,102,102,102,32,109,97,115,107,61,48,120,56,48,48,48,10,32,32,112,114,111,99,101, - 115,115,111,114,32,97,114,99,104,105,116,101,99,116,117,114,101,61,117,80,68,55,55,50,53,10,32,32,32,32,109,97, - 112,32,97,100,100,114,101,115,115,61,54,48,45,54,102,44,101,48,45,101,102,58,48,48,48,48,45,55,102,102,102,32, - 109,97,115,107,61,48,120,51,102,102,102,10,32,32,32,32,109,101,109,111,114,121,32,116,121,112,101,61,82,79,77,32, - 99,111,110,116,101,110,116,61,80,114,111,103,114,97,109,32,97,114,99,104,105,116,101,99,116,117,114,101,61,117,80,68, - 55,55,50,53,10,32,32,32,32,109,101,109,111,114,121,32,116,121,112,101,61,82,79,77,32,99,111,110,116,101,110,116, - 61,68,97,116,97,32,97,114,99,104,105,116,101,99,116,117,114,101,61,117,80,68,55,55,50,53,10,32,32,32,32,109, - 101,109,111,114,121,32,116,121,112,101,61,82,65,77,32,99,111,110,116,101,110,116,61,68,97,116,97,32,97,114,99,104, - 105,116,101,99,116,117,114,101,61,117,80,68,55,55,50,53,10,32,32,32,32,111,115,99,105,108,108,97,116,111,114,10, - 10,98,111,97,114,100,58,32,83,72,86,67,45,50,68,67,48,78,45,48,49,10,32,32,112,114,111,99,101,115,115,111, - 114,32,97,114,99,104,105,116,101,99,116,117,114,101,61,72,71,53,49,66,83,49,54,57,10,32,32,32,32,109,97,112, - 32,97,100,100,114,101,115,115,61,48,48,45,51,102,44,56,48,45,98,102,58,54,99,48,48,45,54,102,102,102,44,55, - 99,48,48,45,55,102,102,102,10,32,32,32,32,109,101,109,111,114,121,32,116,121,112,101,61,82,79,77,32,99,111,110, - 116,101,110,116,61,80,114,111,103,114,97,109,10,32,32,32,32,32,32,109,97,112,32,97,100,100,114,101,115,115,61,48, - 48,45,51,102,44,56,48,45,98,102,58,56,48,48,48,45,102,102,102,102,32,109,97,115,107,61,48,120,56,48,48,48, - 10,32,32,32,32,109,101,109,111,114,121,32,116,121,112,101,61,82,65,77,32,99,111,110,116,101,110,116,61,83,97,118, - 101,10,32,32,32,32,32,32,109,97,112,32,97,100,100,114,101,115,115,61,55,48,45,55,55,58,48,48,48,48,45,55, - 102,102,102,10,32,32,32,32,109,101,109,111,114,121,32,116,121,112,101,61,82,79,77,32,99,111,110,116,101,110,116,61, - 68,97,116,97,32,97,114,99,104,105,116,101,99,116,117,114,101,61,72,71,53,49,66,83,49,54,57,10,32,32,32,32, - 109,101,109,111,114,121,32,116,121,112,101,61,82,65,77,32,99,111,110,116,101,110,116,61,68,97,116,97,32,97,114,99, - 104,105,116,101,99,116,117,114,101,61,72,71,53,49,66,83,49,54,57,10,32,32,32,32,32,32,109,97,112,32,97,100, - 100,114,101,115,115,61,48,48,45,51,102,44,56,48,45,98,102,58,54,48,48,48,45,54,98,102,102,44,55,48,48,48, - 45,55,98,102,102,32,109,97,115,107,61,48,120,102,48,48,48,10,32,32,32,32,111,115,99,105,108,108,97,116,111,114, - 10,10,98,111,97,114,100,58,32,83,72,86,67,45,50,69,51,77,45,48,49,10,32,32,109,101,109,111,114,121,32,116, - 121,112,101,61,82,79,77,32,99,111,110,116,101,110,116,61,80,114,111,103,114,97,109,10,32,32,32,32,109,97,112,32, - 97,100,100,114,101,115,115,61,48,48,45,51,102,44,56,48,45,98,102,58,56,48,48,48,45,102,102,102,102,32,109,97, - 115,107,61,48,120,56,48,48,48,10,32,32,112,114,111,99,101,115,115,111,114,32,105,100,101,110,116,105,102,105,101,114, - 61,79,66,67,49,10,32,32,32,32,109,97,112,32,97,100,100,114,101,115,115,61,48,48,45,51,102,44,56,48,45,98, - 102,58,54,48,48,48,45,55,102,102,102,32,109,97,115,107,61,48,120,101,48,48,48,10,32,32,32,32,109,97,112,32, - 97,100,100,114,101,115,115,61,55,48,45,55,49,44,102,48,45,102,49,58,54,48,48,48,45,55,102,102,102,44,101,48, - 48,48,45,102,102,102,102,32,109,97,115,107,61,48,120,101,48,48,48,10,32,32,32,32,109,101,109,111,114,121,32,116, - 121,112,101,61,82,65,77,32,99,111,110,116,101,110,116,61,83,97,118,101,10,10,98,111,97,114,100,58,32,83,72,86, - 67,45,50,74,48,78,45,40,48,49,44,49,48,44,49,49,44,50,48,41,10,32,32,109,101,109,111,114,121,32,116,121, - 112,101,61,82,79,77,32,99,111,110,116,101,110,116,61,80,114,111,103,114,97,109,10,32,32,32,32,109,97,112,32,97, - 100,100,114,101,115,115,61,48,48,45,51,102,44,56,48,45,98,102,58,56,48,48,48,45,102,102,102,102,10,32,32,32, - 32,109,97,112,32,97,100,100,114,101,115,115,61,52,48,45,55,100,44,99,48,45,102,102,58,48,48,48,48,45,102,102, - 102,102,10,10,98,111,97,114,100,58,32,83,72,86,67,45,50,74,51,77,45,40,48,49,44,49,49,44,50,48,41,10, - 32,32,109,101,109,111,114,121,32,116,121,112,101,61,82,79,77,32,99,111,110,116,101,110,116,61,80,114,111,103,114,97, - 109,10,32,32,32,32,109,97,112,32,97,100,100,114,101,115,115,61,48,48,45,51,102,44,56,48,45,98,102,58,56,48, - 48,48,45,102,102,102,102,10,32,32,32,32,109,97,112,32,97,100,100,114,101,115,115,61,52,48,45,55,100,44,99,48, - 45,102,102,58,48,48,48,48,45,102,102,102,102,10,32,32,109,101,109,111,114,121,32,116,121,112,101,61,82,65,77,32, - 99,111,110,116,101,110,116,61,83,97,118,101,10,32,32,32,32,109,97,112,32,97,100,100,114,101,115,115,61,49,48,45, - 49,102,44,51,48,45,51,102,44,57,48,45,57,102,44,98,48,45,98,102,58,54,48,48,48,45,55,102,102,102,32,109, - 97,115,107,61,48,120,101,48,48,48,10,10,98,111,97,114,100,58,32,83,72,86,67,45,50,74,53,77,45,48,49,10, - 32,32,109,101,109,111,114,121,32,116,121,112,101,61,82,79,77,32,99,111,110,116,101,110,116,61,80,114,111,103,114,97, - 109,10,32,32,32,32,109,97,112,32,97,100,100,114,101,115,115,61,48,48,45,51,102,44,56,48,45,98,102,58,56,48, - 48,48,45,102,102,102,102,10,32,32,32,32,109,97,112,32,97,100,100,114,101,115,115,61,52,48,45,55,100,44,99,48, - 45,102,102,58,48,48,48,48,45,102,102,102,102,10,32,32,109,101,109,111,114,121,32,116,121,112,101,61,82,65,77,32, - 99,111,110,116,101,110,116,61,83,97,118,101,10,32,32,32,32,109,97,112,32,97,100,100,114,101,115,115,61,49,48,45, - 49,102,44,51,48,45,51,102,44,57,48,45,57,102,44,98,48,45,98,102,58,54,48,48,48,45,55,102,102,102,32,109, - 97,115,107,61,48,120,101,48,48,48,10,10,98,111,97,114,100,58,32,83,72,86,67,45,51,74,48,78,45,48,49,10, - 32,32,109,101,109,111,114,121,32,116,121,112,101,61,82,79,77,32,99,111,110,116,101,110,116,61,80,114,111,103,114,97, - 109,10,32,32,32,32,109,97,112,32,97,100,100,114,101,115,115,61,48,48,45,50,102,44,56,48,45,97,102,58,56,48, - 48,48,45,102,102,102,102,10,32,32,32,32,109,97,112,32,97,100,100,114,101,115,115,61,52,48,45,54,102,44,99,48, - 45,101,102,58,48,48,48,48,45,102,102,102,102,10,10,98,111,97,114,100,58,32,83,72,86,67,45,66,65,48,78,45, - 40,48,49,44,49,48,41,10,32,32,109,101,109,111,114,121,32,116,121,112,101,61,82,79,77,32,99,111,110,116,101,110, - 116,61,80,114,111,103,114,97,109,10,32,32,32,32,109,97,112,32,97,100,100,114,101,115,115,61,48,48,45,55,100,44, - 56,48,45,102,102,58,56,48,48,48,45,102,102,102,102,32,109,97,115,107,61,48,120,56,48,48,48,10,32,32,32,32, - 109,97,112,32,97,100,100,114,101,115,115,61,52,48,45,55,100,44,99,48,45,102,102,58,48,48,48,48,45,55,102,102, - 102,32,109,97,115,107,61,48,120,56,48,48,48,10,10,98,111,97,114,100,58,32,83,72,86,67,45,66,65,49,77,45, - 48,49,10,32,32,109,101,109,111,114,121,32,116,121,112,101,61,82,79,77,32,99,111,110,116,101,110,116,61,80,114,111, - 103,114,97,109,10,32,32,32,32,109,97,112,32,97,100,100,114,101,115,115,61,48,48,45,55,100,44,56,48,45,102,102, - 58,56,48,48,48,45,102,102,102,102,32,109,97,115,107,61,48,120,56,48,48,48,10,32,32,109,101,109,111,114,121,32, - 116,121,112,101,61,82,65,77,32,99,111,110,116,101,110,116,61,83,97,118,101,10,32,32,32,32,109,97,112,32,97,100, - 100,114,101,115,115,61,55,48,45,55,100,44,102,48,45,102,102,58,48,48,48,48,45,55,102,102,102,32,109,97,115,107, - 61,48,120,56,48,48,48,10,10,98,111,97,114,100,58,32,83,72,86,67,45,66,65,51,77,45,40,48,49,44,49,48, - 41,10,32,32,109,101,109,111,114,121,32,116,121,112,101,61,82,79,77,32,99,111,110,116,101,110,116,61,80,114,111,103, - 114,97,109,10,32,32,32,32,109,97,112,32,97,100,100,114,101,115,115,61,48,48,45,55,100,44,56,48,45,102,102,58, - 56,48,48,48,45,102,102,102,102,32,109,97,115,107,61,48,120,56,48,48,48,10,32,32,109,101,109,111,114,121,32,116, - 121,112,101,61,82,65,77,32,99,111,110,116,101,110,116,61,83,97,118,101,10,32,32,32,32,109,97,112,32,97,100,100, - 114,101,115,115,61,55,48,45,55,100,44,102,48,45,102,102,58,48,48,48,48,45,55,102,102,102,32,109,97,115,107,61, - 48,120,56,48,48,48,10,10,98,111,97,114,100,58,32,83,72,86,67,45,66,74,48,78,45,40,48,49,44,50,48,41, - 10,32,32,109,101,109,111,114,121,32,116,121,112,101,61,82,79,77,32,99,111,110,116,101,110,116,61,80,114,111,103,114, - 97,109,10,32,32,32,32,109,97,112,32,97,100,100,114,101,115,115,61,48,48,45,51,102,44,56,48,45,98,102,58,56, - 48,48,48,45,102,102,102,102,10,32,32,32,32,109,97,112,32,97,100,100,114,101,115,115,61,52,48,45,55,100,44,99, - 48,45,102,102,58,48,48,48,48,45,102,102,102,102,10,10,98,111,97,114,100,58,32,83,72,86,67,45,66,74,49,77, - 45,40,49,48,44,50,48,41,10,32,32,109,101,109,111,114,121,32,116,121,112,101,61,82,79,77,32,99,111,110,116,101, - 110,116,61,80,114,111,103,114,97,109,10,32,32,32,32,109,97,112,32,97,100,100,114,101,115,115,61,48,48,45,51,102, - 44,56,48,45,98,102,58,56,48,48,48,45,102,102,102,102,10,32,32,32,32,109,97,112,32,97,100,100,114,101,115,115, - 61,52,48,45,55,100,44,99,48,45,102,102,58,48,48,48,48,45,102,102,102,102,10,32,32,109,101,109,111,114,121,32, - 116,121,112,101,61,82,65,77,32,99,111,110,116,101,110,116,61,83,97,118,101,10,32,32,32,32,109,97,112,32,97,100, - 100,114,101,115,115,61,50,48,45,51,102,44,97,48,45,98,102,58,54,48,48,48,45,55,102,102,102,32,109,97,115,107, - 61,48,120,101,48,48,48,10,10,98,111,97,114,100,58,32,83,72,86,67,45,66,74,51,77,45,40,49,48,44,50,48, - 41,10,32,32,109,101,109,111,114,121,32,116,121,112,101,61,82,79,77,32,99,111,110,116,101,110,116,61,80,114,111,103, - 114,97,109,10,32,32,32,32,109,97,112,32,97,100,100,114,101,115,115,61,48,48,45,51,102,44,56,48,45,98,102,58, - 56,48,48,48,45,102,102,102,102,10,32,32,32,32,109,97,112,32,97,100,100,114,101,115,115,61,52,48,45,55,100,44, - 99,48,45,102,102,58,48,48,48,48,45,102,102,102,102,10,32,32,109,101,109,111,114,121,32,116,121,112,101,61,82,65, - 77,32,99,111,110,116,101,110,116,61,83,97,118,101,10,32,32,32,32,109,97,112,32,97,100,100,114,101,115,115,61,50, - 48,45,51,102,44,97,48,45,98,102,58,54,48,48,48,45,55,102,102,102,32,109,97,115,107,61,48,120,101,48,48,48, - 10,10,98,111,97,114,100,58,32,83,72,86,67,45,76,68,72,51,67,45,48,49,10,32,32,112,114,111,99,101,115,115, - 111,114,32,105,100,101,110,116,105,102,105,101,114,61,83,80,67,55,49,49,48,10,32,32,32,32,109,97,112,32,97,100, - 100,114,101,115,115,61,48,48,45,51,102,44,56,48,45,98,102,58,52,56,48,48,45,52,56,51,102,10,32,32,32,32, - 109,97,112,32,97,100,100,114,101,115,115,61,53,48,44,53,56,58,48,48,48,48,45,102,102,102,102,10,32,32,32,32, - 109,99,117,10,32,32,32,32,32,32,109,97,112,32,97,100,100,114,101,115,115,61,48,48,45,51,102,44,56,48,45,98, - 102,58,56,48,48,48,45,102,102,102,102,32,109,97,115,107,61,48,120,56,48,48,48,48,48,10,32,32,32,32,32,32, - 109,97,112,32,97,100,100,114,101,115,115,61,99,48,45,102,102,58,48,48,48,48,45,102,102,102,102,32,109,97,115,107, - 61,48,120,99,48,48,48,48,48,10,32,32,32,32,32,32,109,101,109,111,114,121,32,116,121,112,101,61,82,79,77,32, - 99,111,110,116,101,110,116,61,80,114,111,103,114,97,109,10,32,32,32,32,32,32,109,101,109,111,114,121,32,116,121,112, - 101,61,82,79,77,32,99,111,110,116,101,110,116,61,68,97,116,97,10,32,32,32,32,109,101,109,111,114,121,32,116,121, - 112,101,61,82,65,77,32,99,111,110,116,101,110,116,61,83,97,118,101,10,32,32,32,32,32,32,109,97,112,32,97,100, - 100,114,101,115,115,61,48,48,45,51,102,44,56,48,45,98,102,58,54,48,48,48,45,55,102,102,102,32,109,97,115,107, - 61,48,120,101,48,48,48,10,32,32,114,116,99,32,109,97,110,117,102,97,99,116,117,114,101,114,61,69,112,115,111,110, - 10,32,32,32,32,109,97,112,32,97,100,100,114,101,115,115,61,48,48,45,51,102,44,56,48,45,98,102,58,52,56,52, - 48,45,52,56,52,50,10,32,32,32,32,109,101,109,111,114,121,32,116,121,112,101,61,82,84,67,32,99,111,110,116,101, - 110,116,61,84,105,109,101,32,109,97,110,117,102,97,99,116,117,114,101,114,61,69,112,115,111,110,10,10,98,111,97,114, - 100,58,32,83,72,86,67,45,76,78,51,66,45,48,49,10,32,32,109,101,109,111,114,121,32,116,121,112,101,61,82,65, - 77,32,99,111,110,116,101,110,116,61,83,97,118,101,10,32,32,32,32,109,97,112,32,97,100,100,114,101,115,115,61,48, - 48,45,51,102,44,56,48,45,98,102,58,54,48,48,48,45,55,102,102,102,32,109,97,115,107,61,48,120,101,48,48,48, - 10,32,32,32,32,109,97,112,32,97,100,100,114,101,115,115,61,55,48,45,55,51,58,48,48,48,48,45,102,102,102,102, - 10,32,32,112,114,111,99,101,115,115,111,114,32,105,100,101,110,116,105,102,105,101,114,61,83,68,68,49,10,32,32,32, - 32,109,97,112,32,97,100,100,114,101,115,115,61,48,48,45,51,102,44,56,48,45,98,102,58,52,56,48,48,45,52,56, - 48,102,10,32,32,32,32,109,99,117,10,32,32,32,32,32,32,109,97,112,32,97,100,100,114,101,115,115,61,48,48,45, - 51,102,44,56,48,45,98,102,58,56,48,48,48,45,102,102,102,102,10,32,32,32,32,32,32,109,97,112,32,97,100,100, - 114,101,115,115,61,99,48,45,102,102,58,48,48,48,48,45,102,102,102,102,10,32,32,32,32,32,32,109,101,109,111,114, - 121,32,116,121,112,101,61,82,79,77,32,99,111,110,116,101,110,116,61,80,114,111,103,114,97,109,10,10,98,111,97,114, - 100,58,32,83,72,86,67,45,83,71,66,50,45,48,49,10,32,32,109,101,109,111,114,121,32,116,121,112,101,61,82,79, - 77,32,99,111,110,116,101,110,116,61,80,114,111,103,114,97,109,10,32,32,32,32,109,97,112,32,97,100,100,114,101,115, - 115,61,48,48,45,55,100,44,56,48,45,102,102,58,56,48,48,48,45,102,102,102,102,32,109,97,115,107,61,48,120,56, - 48,48,48,10,32,32,32,32,109,97,112,32,97,100,100,114,101,115,115,61,52,48,45,55,100,44,99,48,45,102,102,58, - 48,48,48,48,45,55,102,102,102,32,109,97,115,107,61,48,120,56,48,48,48,10,32,32,112,114,111,99,101,115,115,111, - 114,32,105,100,101,110,116,105,102,105,101,114,61,73,67,68,32,114,101,118,105,115,105,111,110,61,50,10,32,32,32,32, - 109,97,112,32,97,100,100,114,101,115,115,61,48,48,45,51,102,44,56,48,45,98,102,58,54,48,48,48,45,54,55,102, - 102,44,55,48,48,48,45,55,102,102,102,10,32,32,32,32,109,101,109,111,114,121,32,116,121,112,101,61,82,79,77,32, - 99,111,110,116,101,110,116,61,66,111,111,116,32,97,114,99,104,105,116,101,99,116,117,114,101,61,76,82,51,53,57,48, - 50,10,32,32,32,32,111,115,99,105,108,108,97,116,111,114,10,32,32,32,32,115,108,111,116,32,116,121,112,101,61,71, - 97,109,101,66,111,121,10,10,98,111,97,114,100,58,32,83,72,86,67,45,89,65,48,78,45,48,49,10,32,32,109,101, - 109,111,114,121,32,116,121,112,101,61,82,79,77,32,99,111,110,116,101,110,116,61,80,114,111,103,114,97,109,10,32,32, - 32,32,109,97,112,32,97,100,100,114,101,115,115,61,48,48,45,55,100,44,56,48,45,102,102,58,56,48,48,48,45,102, - 102,102,102,32,109,97,115,107,61,48,120,56,48,48,48,10,32,32,32,32,109,97,112,32,97,100,100,114,101,115,115,61, - 52,48,45,55,100,44,99,48,45,102,102,58,48,48,48,48,45,55,102,102,102,32,109,97,115,107,61,48,120,56,48,48, - 48,10,10,98,111,97,114,100,58,32,83,72,86,67,45,89,74,48,78,45,48,49,10,32,32,109,101,109,111,114,121,32, - 116,121,112,101,61,82,79,77,32,99,111,110,116,101,110,116,61,80,114,111,103,114,97,109,10,32,32,32,32,109,97,112, - 32,97,100,100,114,101,115,115,61,48,48,45,51,102,44,56,48,45,98,102,58,56,48,48,48,45,102,102,102,102,10,32, - 32,32,32,109,97,112,32,97,100,100,114,101,115,115,61,52,48,45,55,100,44,99,48,45,102,102,58,48,48,48,48,45, - 102,102,102,102,10,10,47,47,66,111,97,114,100,115,32,40,71,101,110,101,114,105,99,41,10,10,100,97,116,97,98,97, - 115,101,10,32,32,114,101,118,105,115,105,111,110,58,32,50,48,49,56,45,48,55,45,50,53,10,10,98,111,97,114,100, - 58,32,65,82,77,45,76,79,82,79,77,45,82,65,77,10,32,32,109,101,109,111,114,121,32,116,121,112,101,61,82,79, - 77,32,99,111,110,116,101,110,116,61,80,114,111,103,114,97,109,10,32,32,32,32,109,97,112,32,97,100,100,114,101,115, - 115,61,48,48,45,55,100,44,56,48,45,102,102,58,56,48,48,48,45,102,102,102,102,32,109,97,115,107,61,48,120,56, - 48,48,48,10,32,32,32,32,109,97,112,32,97,100,100,114,101,115,115,61,52,48,45,54,102,44,99,48,45,101,102,58, - 48,48,48,48,45,55,102,102,102,32,109,97,115,107,61,48,120,56,48,48,48,10,32,32,109,101,109,111,114,121,32,116, - 121,112,101,61,82,65,77,32,99,111,110,116,101,110,116,61,83,97,118,101,10,32,32,32,32,109,97,112,32,97,100,100, - 114,101,115,115,61,55,48,45,55,100,44,102,48,45,102,102,58,48,48,48,48,45,102,102,102,102,10,32,32,112,114,111, - 99,101,115,115,111,114,32,97,114,99,104,105,116,101,99,116,117,114,101,61,65,82,77,54,10,32,32,32,32,109,97,112, - 32,97,100,100,114,101,115,115,61,48,48,45,51,102,44,56,48,45,98,102,58,51,56,48,48,45,51,56,102,102,10,32, - 32,32,32,109,101,109,111,114,121,32,116,121,112,101,61,82,79,77,32,99,111,110,116,101,110,116,61,80,114,111,103,114, - 97,109,32,97,114,99,104,105,116,101,99,116,117,114,101,61,65,82,77,54,10,32,32,32,32,109,101,109,111,114,121,32, - 116,121,112,101,61,82,79,77,32,99,111,110,116,101,110,116,61,68,97,116,97,32,97,114,99,104,105,116,101,99,116,117, - 114,101,61,65,82,77,54,10,32,32,32,32,109,101,109,111,114,121,32,116,121,112,101,61,82,65,77,32,99,111,110,116, - 101,110,116,61,68,97,116,97,32,97,114,99,104,105,116,101,99,116,117,114,101,61,65,82,77,54,10,32,32,32,32,111, - 115,99,105,108,108,97,116,111,114,10,10,98,111,97,114,100,58,32,66,83,45,72,73,82,79,77,45,82,65,77,10,32, - 32,109,101,109,111,114,121,32,116,121,112,101,61,82,79,77,32,99,111,110,116,101,110,116,61,80,114,111,103,114,97,109, - 10,32,32,32,32,109,97,112,32,97,100,100,114,101,115,115,61,48,48,45,49,102,44,56,48,45,57,102,58,56,48,48, - 48,45,102,102,102,102,10,32,32,32,32,109,97,112,32,97,100,100,114,101,115,115,61,52,48,45,53,102,44,99,48,45, - 100,102,58,48,48,48,48,45,102,102,102,102,10,32,32,109,101,109,111,114,121,32,116,121,112,101,61,82,65,77,32,99, - 111,110,116,101,110,116,61,83,97,118,101,10,32,32,32,32,109,97,112,32,97,100,100,114,101,115,115,61,50,48,45,51, - 102,44,97,48,45,98,102,58,54,48,48,48,45,55,102,102,102,32,109,97,115,107,61,48,120,101,48,48,48,10,32,32, - 115,108,111,116,32,116,121,112,101,61,66,83,77,101,109,111,114,121,10,32,32,32,32,109,97,112,32,97,100,100,114,101, - 115,115,61,50,48,45,51,102,44,97,48,45,98,102,58,56,48,48,48,45,102,102,102,102,10,32,32,32,32,109,97,112, - 32,97,100,100,114,101,115,115,61,54,48,45,55,100,44,101,48,45,102,102,58,48,48,48,48,45,102,102,102,102,10,10, - 98,111,97,114,100,58,32,66,83,45,76,79,82,79,77,45,82,65,77,10,32,32,109,101,109,111,114,121,32,116,121,112, - 101,61,82,79,77,32,99,111,110,116,101,110,116,61,80,114,111,103,114,97,109,10,32,32,32,32,109,97,112,32,97,100, - 100,114,101,115,115,61,48,48,45,49,102,58,56,48,48,48,45,102,102,102,102,32,98,97,115,101,61,48,120,48,48,48, - 48,48,48,32,109,97,115,107,61,48,120,56,48,48,48,10,32,32,32,32,109,97,112,32,97,100,100,114,101,115,115,61, - 50,48,45,51,102,58,56,48,48,48,45,102,102,102,102,32,98,97,115,101,61,48,120,49,48,48,48,48,48,32,109,97, - 115,107,61,48,120,56,48,48,48,10,32,32,32,32,109,97,112,32,97,100,100,114,101,115,115,61,56,48,45,57,102,58, - 56,48,48,48,45,102,102,102,102,32,98,97,115,101,61,48,120,50,48,48,48,48,48,32,109,97,115,107,61,48,120,56, - 48,48,48,10,32,32,32,32,109,97,112,32,97,100,100,114,101,115,115,61,97,48,45,98,102,58,56,48,48,48,45,102, - 102,102,102,32,98,97,115,101,61,48,120,49,48,48,48,48,48,32,109,97,115,107,61,48,120,56,48,48,48,10,32,32, - 109,101,109,111,114,121,32,116,121,112,101,61,82,65,77,32,99,111,110,116,101,110,116,61,83,97,118,101,10,32,32,32, - 32,109,97,112,32,97,100,100,114,101,115,115,61,55,48,45,55,100,44,102,48,45,102,102,58,48,48,48,48,45,55,102, - 102,102,32,109,97,115,107,61,48,120,56,48,48,48,10,32,32,115,108,111,116,32,116,121,112,101,61,66,83,77,101,109, - 111,114,121,10,32,32,32,32,109,97,112,32,97,100,100,114,101,115,115,61,99,48,45,101,102,58,48,48,48,48,45,102, - 102,102,102,10,10,98,111,97,114,100,58,32,66,83,45,77,67,67,45,82,65,77,10,32,32,109,101,109,111,114,121,32, - 116,121,112,101,61,82,65,77,32,99,111,110,116,101,110,116,61,83,97,118,101,10,32,32,32,32,109,97,112,32,97,100, - 100,114,101,115,115,61,49,48,45,49,55,58,53,48,48,48,45,53,102,102,102,32,109,97,115,107,61,48,120,102,48,48, - 48,10,32,32,112,114,111,99,101,115,115,111,114,32,105,100,101,110,116,105,102,105,101,114,61,77,67,67,10,32,32,32, - 32,109,97,112,32,97,100,100,114,101,115,115,61,48,48,45,48,102,58,53,48,48,48,45,53,102,102,102,10,32,32,32, - 32,109,99,117,10,32,32,32,32,32,32,109,97,112,32,97,100,100,114,101,115,115,61,48,48,45,51,102,44,56,48,45, - 98,102,58,56,48,48,48,45,102,102,102,102,10,32,32,32,32,32,32,109,97,112,32,97,100,100,114,101,115,115,61,52, - 48,45,55,100,44,99,48,45,102,102,58,48,48,48,48,45,102,102,102,102,10,32,32,32,32,32,32,109,97,112,32,97, - 100,100,114,101,115,115,61,50,48,45,51,102,44,97,48,45,98,102,58,54,48,48,48,45,55,102,102,102,10,32,32,32, - 32,32,32,109,101,109,111,114,121,32,116,121,112,101,61,82,79,77,32,99,111,110,116,101,110,116,61,80,114,111,103,114, - 97,109,10,32,32,32,32,32,32,109,101,109,111,114,121,32,116,121,112,101,61,82,65,77,32,99,111,110,116,101,110,116, - 61,68,111,119,110,108,111,97,100,10,32,32,32,32,32,32,115,108,111,116,32,116,121,112,101,61,66,83,77,101,109,111, - 114,121,10,10,98,111,97,114,100,58,32,66,83,45,83,65,49,45,82,65,77,10,32,32,112,114,111,99,101,115,115,111, - 114,32,97,114,99,104,105,116,101,99,116,117,114,101,61,87,54,53,67,56,49,54,83,10,32,32,32,32,109,97,112,32, - 97,100,100,114,101,115,115,61,48,48,45,51,102,44,56,48,45,98,102,58,50,50,48,48,45,50,51,102,102,10,32,32, - 32,32,109,99,117,10,32,32,32,32,32,32,109,97,112,32,97,100,100,114,101,115,115,61,48,48,45,51,102,44,56,48, - 45,98,102,58,56,48,48,48,45,102,102,102,102,32,109,97,115,107,61,48,120,52,48,56,48,48,48,10,32,32,32,32, - 32,32,109,97,112,32,97,100,100,114,101,115,115,61,99,48,45,102,102,58,48,48,48,48,45,102,102,102,102,10,32,32, - 32,32,32,32,109,101,109,111,114,121,32,116,121,112,101,61,82,79,77,32,99,111,110,116,101,110,116,61,80,114,111,103, - 114,97,109,10,32,32,32,32,32,32,115,108,111,116,32,116,121,112,101,61,66,83,77,101,109,111,114,121,10,32,32,32, - 32,109,101,109,111,114,121,32,116,121,112,101,61,82,65,77,32,99,111,110,116,101,110,116,61,83,97,118,101,10,32,32, - 32,32,32,32,109,97,112,32,97,100,100,114,101,115,115,61,48,48,45,51,102,44,56,48,45,98,102,58,54,48,48,48, - 45,55,102,102,102,32,115,105,122,101,61,48,120,50,48,48,48,10,32,32,32,32,32,32,109,97,112,32,97,100,100,114, - 101,115,115,61,52,48,45,52,102,58,48,48,48,48,45,102,102,102,102,10,32,32,32,32,109,101,109,111,114,121,32,116, - 121,112,101,61,82,65,77,32,99,111,110,116,101,110,116,61,73,110,116,101,114,110,97,108,10,32,32,32,32,32,32,109, - 97,112,32,97,100,100,114,101,115,115,61,48,48,45,51,102,44,56,48,45,98,102,58,51,48,48,48,45,51,55,102,102, - 32,115,105,122,101,61,48,120,56,48,48,10,10,98,111,97,114,100,58,32,69,86,69,78,84,45,67,67,57,50,10,32, - 32,109,101,109,111,114,121,32,116,121,112,101,61,82,65,77,32,99,111,110,116,101,110,116,61,83,97,118,101,10,32,32, - 32,32,109,97,112,32,97,100,100,114,101,115,115,61,55,48,45,55,100,44,102,48,45,102,102,58,48,48,48,48,45,55, - 102,102,102,32,109,97,115,107,61,48,120,56,48,48,48,10,32,32,112,114,111,99,101,115,115,111,114,32,109,97,110,117, - 102,97,99,116,117,114,101,114,61,78,69,67,32,97,114,99,104,105,116,101,99,116,117,114,101,61,117,80,68,55,56,50, - 49,52,10,32,32,32,32,105,100,101,110,116,105,102,105,101,114,58,32,67,97,109,112,117,115,32,67,104,97,108,108,101, - 110,103,101,32,39,57,50,10,32,32,32,32,109,97,112,32,97,100,100,114,101,115,115,61,99,48,44,101,48,58,48,48, - 48,48,10,32,32,32,32,109,99,117,10,32,32,32,32,32,32,109,97,112,32,97,100,100,114,101,115,115,61,48,48,45, - 49,102,44,56,48,45,57,102,58,56,48,48,48,45,102,102,102,102,10,32,32,32,32,32,32,109,101,109,111,114,121,32, - 116,121,112,101,61,82,79,77,32,99,111,110,116,101,110,116,61,80,114,111,103,114,97,109,10,32,32,32,32,32,32,109, - 101,109,111,114,121,32,116,121,112,101,61,82,79,77,32,99,111,110,116,101,110,116,61,76,101,118,101,108,45,49,10,32, - 32,32,32,32,32,109,101,109,111,114,121,32,116,121,112,101,61,82,79,77,32,99,111,110,116,101,110,116,61,76,101,118, - 101,108,45,50,10,32,32,32,32,32,32,109,101,109,111,114,121,32,116,121,112,101,61,82,79,77,32,99,111,110,116,101, - 110,116,61,76,101,118,101,108,45,51,10,32,32,32,32,100,105,112,10,32,32,112,114,111,99,101,115,115,111,114,32,109, - 97,110,117,102,97,99,116,117,114,101,114,61,78,69,67,32,97,114,99,104,105,116,101,99,116,117,114,101,61,117,80,68, - 55,55,50,53,10,32,32,32,32,109,97,112,32,97,100,100,114,101,115,115,61,50,48,45,51,102,44,97,48,45,98,102, - 58,56,48,48,48,45,102,102,102,102,32,109,97,115,107,61,48,120,55,102,102,102,10,32,32,32,32,109,101,109,111,114, - 121,32,116,121,112,101,61,82,79,77,32,99,111,110,116,101,110,116,61,80,114,111,103,114,97,109,32,97,114,99,104,105, - 116,101,99,116,117,114,101,61,117,80,68,55,55,50,53,10,32,32,32,32,109,101,109,111,114,121,32,116,121,112,101,61, - 82,79,77,32,99,111,110,116,101,110,116,61,68,97,116,97,32,97,114,99,104,105,116,101,99,116,117,114,101,61,117,80, - 68,55,55,50,53,10,32,32,32,32,109,101,109,111,114,121,32,116,121,112,101,61,82,65,77,32,99,111,110,116,101,110, - 116,61,68,97,116,97,32,97,114,99,104,105,116,101,99,116,117,114,101,61,117,80,68,55,55,50,53,10,32,32,32,32, - 111,115,99,105,108,108,97,116,111,114,10,10,98,111,97,114,100,58,32,69,86,69,78,84,45,80,70,57,52,10,32,32, - 109,101,109,111,114,121,32,116,121,112,101,61,82,65,77,32,99,111,110,116,101,110,116,61,83,97,118,101,10,32,32,32, - 32,109,97,112,32,97,100,100,114,101,115,115,61,51,48,45,51,102,44,98,48,45,98,102,58,54,48,48,48,45,55,102, - 102,102,32,109,97,115,107,61,48,120,101,48,48,48,10,32,32,112,114,111,99,101,115,115,111,114,32,109,97,110,117,102, - 97,99,116,117,114,101,114,61,78,69,67,32,97,114,99,104,105,116,101,99,116,117,114,101,61,117,80,68,55,56,50,49, - 52,10,32,32,32,32,105,100,101,110,116,105,102,105,101,114,58,32,80,111,119,101,114,70,101,115,116,32,39,57,52,10, - 32,32,32,32,109,97,112,32,97,100,100,114,101,115,115,61,49,48,44,50,48,58,54,48,48,48,10,32,32,32,32,109, - 99,117,10,32,32,32,32,32,32,109,97,112,32,97,100,100,114,101,115,115,61,48,48,45,51,102,44,56,48,45,98,102, - 58,56,48,48,48,45,102,102,102,102,10,32,32,32,32,32,32,109,97,112,32,97,100,100,114,101,115,115,61,99,48,45, - 102,102,58,48,48,48,48,45,102,102,102,102,10,32,32,32,32,32,32,109,101,109,111,114,121,32,116,121,112,101,61,82, - 79,77,32,99,111,110,116,101,110,116,61,80,114,111,103,114,97,109,10,32,32,32,32,32,32,109,101,109,111,114,121,32, - 116,121,112,101,61,82,79,77,32,99,111,110,116,101,110,116,61,76,101,118,101,108,45,49,10,32,32,32,32,32,32,109, - 101,109,111,114,121,32,116,121,112,101,61,82,79,77,32,99,111,110,116,101,110,116,61,76,101,118,101,108,45,50,10,32, - 32,32,32,32,32,109,101,109,111,114,121,32,116,121,112,101,61,82,79,77,32,99,111,110,116,101,110,116,61,76,101,118, - 101,108,45,51,10,32,32,32,32,100,105,112,10,32,32,112,114,111,99,101,115,115,111,114,32,109,97,110,117,102,97,99, - 116,117,114,101,114,61,78,69,67,32,97,114,99,104,105,116,101,99,116,117,114,101,61,117,80,68,55,55,50,53,10,32, - 32,32,32,109,97,112,32,97,100,100,114,101,115,115,61,48,48,45,48,102,44,56,48,45,56,102,58,54,48,48,48,45, - 55,102,102,102,32,109,97,115,107,61,48,120,102,102,102,10,32,32,32,32,109,101,109,111,114,121,32,116,121,112,101,61, - 82,79,77,32,99,111,110,116,101,110,116,61,80,114,111,103,114,97,109,32,97,114,99,104,105,116,101,99,116,117,114,101, - 61,117,80,68,55,55,50,53,10,32,32,32,32,109,101,109,111,114,121,32,116,121,112,101,61,82,79,77,32,99,111,110, - 116,101,110,116,61,68,97,116,97,32,97,114,99,104,105,116,101,99,116,117,114,101,61,117,80,68,55,55,50,53,10,32, - 32,32,32,109,101,109,111,114,121,32,116,121,112,101,61,82,65,77,32,99,111,110,116,101,110,116,61,68,97,116,97,32, - 97,114,99,104,105,116,101,99,116,117,114,101,61,117,80,68,55,55,50,53,10,32,32,32,32,111,115,99,105,108,108,97, - 116,111,114,10,10,98,111,97,114,100,58,32,69,88,72,73,82,79,77,45,82,65,77,10,32,32,109,101,109,111,114,121, - 32,116,121,112,101,61,82,79,77,32,99,111,110,116,101,110,116,61,80,114,111,103,114,97,109,10,32,32,32,32,109,97, - 112,32,97,100,100,114,101,115,115,61,48,48,45,51,102,58,56,48,48,48,45,102,102,102,102,32,98,97,115,101,61,48, - 120,52,48,48,48,48,48,10,32,32,32,32,109,97,112,32,97,100,100,114,101,115,115,61,52,48,45,55,100,58,48,48, - 48,48,45,102,102,102,102,32,98,97,115,101,61,48,120,52,48,48,48,48,48,10,32,32,32,32,109,97,112,32,97,100, - 100,114,101,115,115,61,56,48,45,98,102,58,56,48,48,48,45,102,102,102,102,32,109,97,115,107,61,48,120,99,48,48, - 48,48,48,10,32,32,32,32,109,97,112,32,97,100,100,114,101,115,115,61,99,48,45,102,102,58,48,48,48,48,45,102, - 102,102,102,32,109,97,115,107,61,48,120,99,48,48,48,48,48,10,32,32,109,101,109,111,114,121,32,116,121,112,101,61, - 82,65,77,32,99,111,110,116,101,110,116,61,83,97,118,101,10,32,32,32,32,109,97,112,32,97,100,100,114,101,115,115, - 61,50,48,45,51,102,44,97,48,45,98,102,58,54,48,48,48,45,55,102,102,102,32,109,97,115,107,61,48,120,101,48, - 48,48,10,32,32,32,32,109,97,112,32,97,100,100,114,101,115,115,61,55,48,45,55,100,58,48,48,48,48,45,55,102, - 102,102,10,10,98,111,97,114,100,58,32,69,88,72,73,82,79,77,45,82,65,77,45,83,72,65,82,80,82,84,67,10, - 32,32,109,101,109,111,114,121,32,116,121,112,101,61,82,79,77,32,99,111,110,116,101,110,116,61,80,114,111,103,114,97, - 109,10,32,32,32,32,109,97,112,32,97,100,100,114,101,115,115,61,48,48,45,51,102,58,56,48,48,48,45,102,102,102, - 102,32,98,97,115,101,61,48,120,52,48,48,48,48,48,10,32,32,32,32,109,97,112,32,97,100,100,114,101,115,115,61, - 52,48,45,55,100,58,48,48,48,48,45,102,102,102,102,32,98,97,115,101,61,48,120,52,48,48,48,48,48,10,32,32, - 32,32,109,97,112,32,97,100,100,114,101,115,115,61,56,48,45,98,102,58,56,48,48,48,45,102,102,102,102,32,109,97, - 115,107,61,48,120,99,48,48,48,48,48,10,32,32,32,32,109,97,112,32,97,100,100,114,101,115,115,61,99,48,45,102, - 102,58,48,48,48,48,45,102,102,102,102,32,109,97,115,107,61,48,120,99,48,48,48,48,48,10,32,32,109,101,109,111, - 114,121,32,116,121,112,101,61,82,65,77,32,99,111,110,116,101,110,116,61,83,97,118,101,10,32,32,32,32,109,97,112, - 32,97,100,100,114,101,115,115,61,50,48,45,51,102,44,97,48,45,98,102,58,54,48,48,48,45,55,102,102,102,32,109, - 97,115,107,61,48,120,101,48,48,48,10,32,32,32,32,109,97,112,32,97,100,100,114,101,115,115,61,55,48,45,55,100, - 58,48,48,48,48,45,55,102,102,102,10,32,32,114,116,99,32,109,97,110,117,102,97,99,116,117,114,101,114,61,83,104, - 97,114,112,10,32,32,32,32,109,97,112,32,97,100,100,114,101,115,115,61,48,48,45,51,102,44,56,48,45,98,102,58, - 50,56,48,48,45,50,56,48,49,10,32,32,32,32,109,101,109,111,114,121,32,116,121,112,101,61,82,84,67,32,99,111, - 110,116,101,110,116,61,84,105,109,101,32,109,97,110,117,102,97,99,116,117,114,101,114,61,83,104,97,114,112,10,10,98, - 111,97,114,100,58,32,69,88,78,69,67,45,76,79,82,79,77,10,32,32,109,101,109,111,114,121,32,116,121,112,101,61, - 82,79,77,32,99,111,110,116,101,110,116,61,80,114,111,103,114,97,109,10,32,32,32,32,109,97,112,32,97,100,100,114, - 101,115,115,61,48,48,45,55,100,44,56,48,45,102,102,58,56,48,48,48,45,102,102,102,102,32,109,97,115,107,61,48, - 120,56,48,48,48,10,32,32,112,114,111,99,101,115,115,111,114,32,97,114,99,104,105,116,101,99,116,117,114,101,61,117, - 80,68,57,54,48,53,48,10,32,32,32,32,109,97,112,32,97,100,100,114,101,115,115,61,54,48,45,54,55,44,101,48, - 45,101,55,58,48,48,48,48,45,51,102,102,102,10,32,32,32,32,109,101,109,111,114,121,32,116,121,112,101,61,82,79, - 77,32,99,111,110,116,101,110,116,61,80,114,111,103,114,97,109,32,97,114,99,104,105,116,101,99,116,117,114,101,61,117, - 80,68,57,54,48,53,48,10,32,32,32,32,109,101,109,111,114,121,32,116,121,112,101,61,82,79,77,32,99,111,110,116, - 101,110,116,61,68,97,116,97,32,97,114,99,104,105,116,101,99,116,117,114,101,61,117,80,68,57,54,48,53,48,10,32, - 32,32,32,109,101,109,111,114,121,32,116,121,112,101,61,82,65,77,32,99,111,110,116,101,110,116,61,68,97,116,97,32, - 97,114,99,104,105,116,101,99,116,117,114,101,61,117,80,68,57,54,48,53,48,10,32,32,32,32,32,32,109,97,112,32, - 97,100,100,114,101,115,115,61,54,56,45,54,102,44,101,56,45,101,102,58,48,48,48,48,45,55,102,102,102,32,109,97, - 115,107,61,48,120,56,48,48,48,10,32,32,32,32,111,115,99,105,108,108,97,116,111,114,10,10,98,111,97,114,100,58, - 32,69,88,83,80,67,55,49,49,48,45,82,65,77,45,69,80,83,79,78,82,84,67,10,32,32,109,101,109,111,114,121, - 32,116,121,112,101,61,82,79,77,32,99,111,110,116,101,110,116,61,69,120,112,97,110,115,105,111,110,10,32,32,32,32, - 109,97,112,32,97,100,100,114,101,115,115,61,52,48,45,52,102,58,48,48,48,48,45,102,102,102,102,10,32,32,112,114, - 111,99,101,115,115,111,114,32,105,100,101,110,116,105,102,105,101,114,61,83,80,67,55,49,49,48,10,32,32,32,32,109, - 97,112,32,97,100,100,114,101,115,115,61,48,48,45,51,102,44,56,48,45,98,102,58,52,56,48,48,45,52,56,51,102, - 10,32,32,32,32,109,97,112,32,97,100,100,114,101,115,115,61,53,48,44,53,56,58,48,48,48,48,45,102,102,102,102, - 10,32,32,32,32,109,99,117,10,32,32,32,32,32,32,109,97,112,32,97,100,100,114,101,115,115,61,48,48,45,51,102, - 44,56,48,45,98,102,58,56,48,48,48,45,102,102,102,102,32,109,97,115,107,61,48,120,56,48,48,48,48,48,10,32, - 32,32,32,32,32,109,97,112,32,97,100,100,114,101,115,115,61,99,48,45,102,102,58,48,48,48,48,45,102,102,102,102, - 32,109,97,115,107,61,48,120,99,48,48,48,48,48,10,32,32,32,32,32,32,109,101,109,111,114,121,32,116,121,112,101, - 61,82,79,77,32,99,111,110,116,101,110,116,61,80,114,111,103,114,97,109,10,32,32,32,32,32,32,109,101,109,111,114, - 121,32,116,121,112,101,61,82,79,77,32,99,111,110,116,101,110,116,61,68,97,116,97,10,32,32,32,32,109,101,109,111, - 114,121,32,116,121,112,101,61,82,65,77,32,99,111,110,116,101,110,116,61,83,97,118,101,10,32,32,32,32,32,32,109, - 97,112,32,97,100,100,114,101,115,115,61,48,48,45,51,102,44,56,48,45,98,102,58,54,48,48,48,45,55,102,102,102, - 32,109,97,115,107,61,48,120,101,48,48,48,10,32,32,114,116,99,32,109,97,110,117,102,97,99,116,117,114,101,114,61, - 69,112,115,111,110,10,32,32,32,32,109,97,112,32,97,100,100,114,101,115,115,61,48,48,45,51,102,44,56,48,45,98, - 102,58,52,56,52,48,45,52,56,52,50,10,32,32,32,32,109,101,109,111,114,121,32,116,121,112,101,61,82,84,67,32, - 99,111,110,116,101,110,116,61,84,105,109,101,32,109,97,110,117,102,97,99,116,117,114,101,114,61,69,112,115,111,110,10, - 10,98,111,97,114,100,58,32,71,66,45,76,79,82,79,77,10,32,32,109,101,109,111,114,121,32,116,121,112,101,61,82, - 79,77,32,99,111,110,116,101,110,116,61,80,114,111,103,114,97,109,10,32,32,32,32,109,97,112,32,97,100,100,114,101, - 115,115,61,48,48,45,55,100,44,56,48,45,102,102,58,56,48,48,48,45,102,102,102,102,32,109,97,115,107,61,48,120, - 56,48,48,48,10,32,32,32,32,109,97,112,32,97,100,100,114,101,115,115,61,52,48,45,55,100,44,99,48,45,102,102, - 58,48,48,48,48,45,55,102,102,102,32,109,97,115,107,61,48,120,56,48,48,48,10,32,32,112,114,111,99,101,115,115, - 111,114,32,105,100,101,110,116,105,102,105,101,114,61,73,67,68,32,114,101,118,105,115,105,111,110,61,50,10,32,32,32, - 32,109,97,112,32,97,100,100,114,101,115,115,61,48,48,45,51,102,44,56,48,45,98,102,58,54,48,48,48,45,54,55, - 102,102,44,55,48,48,48,45,55,102,102,102,10,32,32,32,32,109,101,109,111,114,121,32,116,121,112,101,61,82,79,77, - 32,99,111,110,116,101,110,116,61,66,111,111,116,32,97,114,99,104,105,116,101,99,116,117,114,101,61,76,82,51,53,57, - 48,50,10,32,32,32,32,111,115,99,105,108,108,97,116,111,114,10,32,32,32,32,115,108,111,116,32,116,121,112,101,61, - 71,97,109,101,66,111,121,10,10,98,111,97,114,100,58,32,71,83,85,45,82,65,77,10,32,32,112,114,111,99,101,115, - 115,111,114,32,97,114,99,104,105,116,101,99,116,117,114,101,61,71,83,85,10,32,32,32,32,109,97,112,32,97,100,100, - 114,101,115,115,61,48,48,45,51,102,44,56,48,45,98,102,58,51,48,48,48,45,51,52,102,102,10,32,32,32,32,109, - 101,109,111,114,121,32,116,121,112,101,61,82,79,77,32,99,111,110,116,101,110,116,61,80,114,111,103,114,97,109,10,32, - 32,32,32,32,32,109,97,112,32,97,100,100,114,101,115,115,61,48,48,45,51,102,44,56,48,45,98,102,58,56,48,48, - 48,45,102,102,102,102,32,109,97,115,107,61,48,120,56,48,48,48,10,32,32,32,32,32,32,109,97,112,32,97,100,100, - 114,101,115,115,61,52,48,45,53,102,44,99,48,45,100,102,58,48,48,48,48,45,102,102,102,102,10,32,32,32,32,109, - 101,109,111,114,121,32,116,121,112,101,61,82,65,77,32,99,111,110,116,101,110,116,61,83,97,118,101,10,32,32,32,32, - 32,32,109,97,112,32,97,100,100,114,101,115,115,61,48,48,45,51,102,44,56,48,45,98,102,58,54,48,48,48,45,55, - 102,102,102,32,115,105,122,101,61,48,120,50,48,48,48,10,32,32,32,32,32,32,109,97,112,32,97,100,100,114,101,115, - 115,61,55,48,45,55,49,44,102,48,45,102,49,58,48,48,48,48,45,102,102,102,102,10,10,98,111,97,114,100,58,32, - 72,73,82,79,77,10,32,32,109,101,109,111,114,121,32,116,121,112,101,61,82,79,77,32,99,111,110,116,101,110,116,61, - 80,114,111,103,114,97,109,10,32,32,32,32,109,97,112,32,97,100,100,114,101,115,115,61,48,48,45,51,102,44,56,48, - 45,98,102,58,56,48,48,48,45,102,102,102,102,10,32,32,32,32,109,97,112,32,97,100,100,114,101,115,115,61,52,48, - 45,55,100,44,99,48,45,102,102,58,48,48,48,48,45,102,102,102,102,10,10,98,111,97,114,100,58,32,72,73,82,79, - 77,45,82,65,77,10,32,32,109,101,109,111,114,121,32,116,121,112,101,61,82,79,77,32,99,111,110,116,101,110,116,61, - 80,114,111,103,114,97,109,10,32,32,32,32,109,97,112,32,97,100,100,114,101,115,115,61,48,48,45,51,102,44,56,48, - 45,98,102,58,56,48,48,48,45,102,102,102,102,10,32,32,32,32,109,97,112,32,97,100,100,114,101,115,115,61,52,48, - 45,55,100,44,99,48,45,102,102,58,48,48,48,48,45,102,102,102,102,10,32,32,109,101,109,111,114,121,32,116,121,112, - 101,61,82,65,77,32,99,111,110,116,101,110,116,61,83,97,118,101,10,32,32,32,32,109,97,112,32,97,100,100,114,101, - 115,115,61,50,48,45,51,102,44,97,48,45,98,102,58,54,48,48,48,45,55,102,102,102,32,109,97,115,107,61,48,120, - 101,48,48,48,10,10,98,111,97,114,100,58,32,72,73,84,65,67,72,73,45,76,79,82,79,77,10,32,32,112,114,111, - 99,101,115,115,111,114,32,97,114,99,104,105,116,101,99,116,117,114,101,61,72,71,53,49,66,83,49,54,57,10,32,32, - 32,32,109,97,112,32,97,100,100,114,101,115,115,61,48,48,45,51,102,44,56,48,45,98,102,58,54,99,48,48,45,54, - 102,102,102,44,55,99,48,48,45,55,102,102,102,10,32,32,32,32,109,101,109,111,114,121,32,116,121,112,101,61,82,79, - 77,32,99,111,110,116,101,110,116,61,80,114,111,103,114,97,109,10,32,32,32,32,32,32,109,97,112,32,97,100,100,114, - 101,115,115,61,48,48,45,51,102,44,56,48,45,98,102,58,56,48,48,48,45,102,102,102,102,32,109,97,115,107,61,48, - 120,56,48,48,48,10,32,32,32,32,109,101,109,111,114,121,32,116,121,112,101,61,82,65,77,32,99,111,110,116,101,110, - 116,61,83,97,118,101,10,32,32,32,32,32,32,109,97,112,32,97,100,100,114,101,115,115,61,55,48,45,55,55,58,48, - 48,48,48,45,55,102,102,102,10,32,32,32,32,109,101,109,111,114,121,32,116,121,112,101,61,82,79,77,32,99,111,110, - 116,101,110,116,61,68,97,116,97,32,97,114,99,104,105,116,101,99,116,117,114,101,61,72,71,53,49,66,83,49,54,57, - 10,32,32,32,32,109,101,109,111,114,121,32,116,121,112,101,61,82,65,77,32,99,111,110,116,101,110,116,61,68,97,116, - 97,32,97,114,99,104,105,116,101,99,116,117,114,101,61,72,71,53,49,66,83,49,54,57,10,32,32,32,32,32,32,109, - 97,112,32,97,100,100,114,101,115,115,61,48,48,45,51,102,44,56,48,45,98,102,58,54,48,48,48,45,54,98,102,102, - 44,55,48,48,48,45,55,98,102,102,32,109,97,115,107,61,48,120,102,48,48,48,10,32,32,32,32,111,115,99,105,108, - 108,97,116,111,114,10,10,98,111,97,114,100,58,32,76,79,82,79,77,10,32,32,109,101,109,111,114,121,32,116,121,112, - 101,61,82,79,77,32,99,111,110,116,101,110,116,61,80,114,111,103,114,97,109,10,32,32,32,32,109,97,112,32,97,100, - 100,114,101,115,115,61,48,48,45,55,100,44,56,48,45,102,102,58,56,48,48,48,45,102,102,102,102,32,109,97,115,107, - 61,48,120,56,48,48,48,10,10,98,111,97,114,100,58,32,76,79,82,79,77,45,82,65,77,10,32,32,109,101,109,111, - 114,121,32,116,121,112,101,61,82,79,77,32,99,111,110,116,101,110,116,61,80,114,111,103,114,97,109,10,32,32,32,32, - 109,97,112,32,97,100,100,114,101,115,115,61,48,48,45,55,100,44,56,48,45,102,102,58,56,48,48,48,45,102,102,102, - 102,32,109,97,115,107,61,48,120,56,48,48,48,10,32,32,109,101,109,111,114,121,32,116,121,112,101,61,82,65,77,32, - 99,111,110,116,101,110,116,61,83,97,118,101,10,32,32,32,32,109,97,112,32,97,100,100,114,101,115,115,61,55,48,45, - 55,100,44,102,48,45,102,102,58,48,48,48,48,45,55,102,102,102,32,109,97,115,107,61,48,120,56,48,48,48,10,10, - 98,111,97,114,100,58,32,76,79,82,79,77,45,82,65,77,35,65,10,32,32,109,101,109,111,114,121,32,116,121,112,101, - 61,82,79,77,32,99,111,110,116,101,110,116,61,80,114,111,103,114,97,109,10,32,32,32,32,109,97,112,32,97,100,100, - 114,101,115,115,61,48,48,45,51,102,44,56,48,45,98,102,58,56,48,48,48,45,102,102,102,102,32,109,97,115,107,61, - 48,120,56,48,48,48,10,32,32,109,101,109,111,114,121,32,116,121,112,101,61,82,65,77,32,99,111,110,116,101,110,116, - 61,83,97,118,101,10,32,32,32,32,109,97,112,32,97,100,100,114,101,115,115,61,55,48,45,55,100,44,102,48,45,102, - 102,58,48,48,48,48,45,102,102,102,102,32,109,97,115,107,61,48,120,56,48,48,48,10,10,98,111,97,114,100,58,32, - 78,69,67,45,72,73,82,79,77,10,32,32,109,101,109,111,114,121,32,116,121,112,101,61,82,79,77,32,99,111,110,116, - 101,110,116,61,80,114,111,103,114,97,109,10,32,32,32,32,109,97,112,32,97,100,100,114,101,115,115,61,48,48,45,51, - 102,44,56,48,45,98,102,58,56,48,48,48,45,102,102,102,102,10,32,32,32,32,109,97,112,32,97,100,100,114,101,115, - 115,61,52,48,45,55,100,44,99,48,45,102,102,58,48,48,48,48,45,102,102,102,102,10,32,32,112,114,111,99,101,115, - 115,111,114,32,97,114,99,104,105,116,101,99,116,117,114,101,61,117,80,68,55,55,50,53,10,32,32,32,32,109,97,112, - 32,97,100,100,114,101,115,115,61,48,48,45,49,102,44,56,48,45,57,102,58,54,48,48,48,45,55,102,102,102,32,109, - 97,115,107,61,48,120,102,102,102,10,32,32,32,32,109,101,109,111,114,121,32,116,121,112,101,61,82,79,77,32,99,111, - 110,116,101,110,116,61,80,114,111,103,114,97,109,32,97,114,99,104,105,116,101,99,116,117,114,101,61,117,80,68,55,55, - 50,53,10,32,32,32,32,109,101,109,111,114,121,32,116,121,112,101,61,82,79,77,32,99,111,110,116,101,110,116,61,68, - 97,116,97,32,97,114,99,104,105,116,101,99,116,117,114,101,61,117,80,68,55,55,50,53,10,32,32,32,32,109,101,109, - 111,114,121,32,116,121,112,101,61,82,65,77,32,99,111,110,116,101,110,116,61,68,97,116,97,32,97,114,99,104,105,116, - 101,99,116,117,114,101,61,117,80,68,55,55,50,53,10,32,32,32,32,111,115,99,105,108,108,97,116,111,114,10,10,98, - 111,97,114,100,58,32,78,69,67,45,72,73,82,79,77,45,82,65,77,10,32,32,109,101,109,111,114,121,32,116,121,112, - 101,61,82,79,77,32,99,111,110,116,101,110,116,61,80,114,111,103,114,97,109,10,32,32,32,32,109,97,112,32,97,100, - 100,114,101,115,115,61,48,48,45,51,102,44,56,48,45,98,102,58,56,48,48,48,45,102,102,102,102,10,32,32,32,32, - 109,97,112,32,97,100,100,114,101,115,115,61,52,48,45,55,100,44,99,48,45,102,102,58,48,48,48,48,45,102,102,102, - 102,10,32,32,109,101,109,111,114,121,32,116,121,112,101,61,82,65,77,32,99,111,110,116,101,110,116,61,83,97,118,101, - 10,32,32,32,32,109,97,112,32,97,100,100,114,101,115,115,61,50,48,45,51,102,44,97,48,45,98,102,58,54,48,48, - 48,45,55,102,102,102,32,109,97,115,107,61,48,120,101,48,48,48,10,32,32,112,114,111,99,101,115,115,111,114,32,97, - 114,99,104,105,116,101,99,116,117,114,101,61,117,80,68,55,55,50,53,10,32,32,32,32,109,97,112,32,97,100,100,114, - 101,115,115,61,48,48,45,49,102,44,56,48,45,57,102,58,54,48,48,48,45,55,102,102,102,32,109,97,115,107,61,48, - 120,102,102,102,10,32,32,32,32,109,101,109,111,114,121,32,116,121,112,101,61,82,79,77,32,99,111,110,116,101,110,116, - 61,80,114,111,103,114,97,109,32,97,114,99,104,105,116,101,99,116,117,114,101,61,117,80,68,55,55,50,53,10,32,32, - 32,32,109,101,109,111,114,121,32,116,121,112,101,61,82,79,77,32,99,111,110,116,101,110,116,61,68,97,116,97,32,97, - 114,99,104,105,116,101,99,116,117,114,101,61,117,80,68,55,55,50,53,10,32,32,32,32,109,101,109,111,114,121,32,116, - 121,112,101,61,82,65,77,32,99,111,110,116,101,110,116,61,68,97,116,97,32,97,114,99,104,105,116,101,99,116,117,114, - 101,61,117,80,68,55,55,50,53,10,32,32,32,32,111,115,99,105,108,108,97,116,111,114,10,10,98,111,97,114,100,58, - 32,78,69,67,45,76,79,82,79,77,10,32,32,109,101,109,111,114,121,32,116,121,112,101,61,82,79,77,32,99,111,110, - 116,101,110,116,61,80,114,111,103,114,97,109,10,32,32,32,32,109,97,112,32,97,100,100,114,101,115,115,61,48,48,45, - 49,102,44,56,48,45,57,102,58,56,48,48,48,45,102,102,102,102,32,109,97,115,107,61,48,120,56,48,48,48,10,32, - 32,112,114,111,99,101,115,115,111,114,32,97,114,99,104,105,116,101,99,116,117,114,101,61,117,80,68,55,55,50,53,10, - 32,32,32,32,109,97,112,32,97,100,100,114,101,115,115,61,51,48,45,51,102,44,98,48,45,98,102,58,56,48,48,48, - 45,102,102,102,102,32,109,97,115,107,61,48,120,51,102,102,102,10,32,32,32,32,109,101,109,111,114,121,32,116,121,112, - 101,61,82,79,77,32,99,111,110,116,101,110,116,61,80,114,111,103,114,97,109,32,97,114,99,104,105,116,101,99,116,117, - 114,101,61,117,80,68,55,55,50,53,10,32,32,32,32,109,101,109,111,114,121,32,116,121,112,101,61,82,79,77,32,99, - 111,110,116,101,110,116,61,68,97,116,97,32,97,114,99,104,105,116,101,99,116,117,114,101,61,117,80,68,55,55,50,53, - 10,32,32,32,32,109,101,109,111,114,121,32,116,121,112,101,61,82,65,77,32,99,111,110,116,101,110,116,61,68,97,116, - 97,32,97,114,99,104,105,116,101,99,116,117,114,101,61,117,80,68,55,55,50,53,10,32,32,32,32,111,115,99,105,108, - 108,97,116,111,114,10,10,98,111,97,114,100,58,32,78,69,67,45,76,79,82,79,77,45,82,65,77,10,32,32,109,101, - 109,111,114,121,32,116,121,112,101,61,82,79,77,32,99,111,110,116,101,110,116,61,80,114,111,103,114,97,109,10,32,32, - 32,32,109,97,112,32,97,100,100,114,101,115,115,61,48,48,45,51,102,44,56,48,45,98,102,58,56,48,48,48,45,102, - 102,102,102,32,109,97,115,107,61,48,120,56,48,48,48,10,32,32,109,101,109,111,114,121,32,116,121,112,101,61,82,65, - 77,32,99,111,110,116,101,110,116,61,83,97,118,101,10,32,32,32,32,109,97,112,32,97,100,100,114,101,115,115,61,55, - 48,45,55,100,44,102,48,45,102,102,58,48,48,48,48,45,55,102,102,102,32,109,97,115,107,61,48,120,56,48,48,48, - 10,32,32,112,114,111,99,101,115,115,111,114,32,97,114,99,104,105,116,101,99,116,117,114,101,61,117,80,68,55,55,50, - 53,10,32,32,32,32,109,97,112,32,97,100,100,114,101,115,115,61,54,48,45,54,102,44,101,48,45,101,102,58,48,48, - 48,48,45,55,102,102,102,32,109,97,115,107,61,48,120,51,102,102,102,10,32,32,32,32,109,101,109,111,114,121,32,116, - 121,112,101,61,82,79,77,32,99,111,110,116,101,110,116,61,80,114,111,103,114,97,109,32,97,114,99,104,105,116,101,99, - 116,117,114,101,61,117,80,68,55,55,50,53,10,32,32,32,32,109,101,109,111,114,121,32,116,121,112,101,61,82,79,77, - 32,99,111,110,116,101,110,116,61,68,97,116,97,32,97,114,99,104,105,116,101,99,116,117,114,101,61,117,80,68,55,55, - 50,53,10,32,32,32,32,109,101,109,111,114,121,32,116,121,112,101,61,82,65,77,32,99,111,110,116,101,110,116,61,68, - 97,116,97,32,97,114,99,104,105,116,101,99,116,117,114,101,61,117,80,68,55,55,50,53,10,32,32,32,32,111,115,99, - 105,108,108,97,116,111,114,10,10,98,111,97,114,100,58,32,78,69,67,45,76,79,82,79,77,45,82,65,77,35,65,10, - 32,32,109,101,109,111,114,121,32,116,121,112,101,61,82,79,77,32,99,111,110,116,101,110,116,61,80,114,111,103,114,97, - 109,10,32,32,32,32,109,97,112,32,97,100,100,114,101,115,115,61,48,48,45,49,102,44,56,48,45,57,102,58,56,48, - 48,48,45,102,102,102,102,32,109,97,115,107,61,48,120,56,48,48,48,10,32,32,109,101,109,111,114,121,32,116,121,112, - 101,61,82,65,77,32,99,111,110,116,101,110,116,61,83,97,118,101,10,32,32,32,32,109,97,112,32,97,100,100,114,101, - 115,115,61,55,48,45,55,100,44,102,48,45,102,102,58,48,48,48,48,45,102,102,102,102,10,32,32,112,114,111,99,101, - 115,115,111,114,32,97,114,99,104,105,116,101,99,116,117,114,101,61,117,80,68,55,55,50,53,10,32,32,32,32,109,97, - 112,32,97,100,100,114,101,115,115,61,50,48,45,51,102,44,97,48,45,98,102,58,56,48,48,48,45,102,102,102,102,32, - 109,97,115,107,61,48,120,51,102,102,102,10,32,32,32,32,109,101,109,111,114,121,32,116,121,112,101,61,82,79,77,32, - 99,111,110,116,101,110,116,61,80,114,111,103,114,97,109,32,97,114,99,104,105,116,101,99,116,117,114,101,61,117,80,68, - 55,55,50,53,10,32,32,32,32,109,101,109,111,114,121,32,116,121,112,101,61,82,79,77,32,99,111,110,116,101,110,116, - 61,68,97,116,97,32,97,114,99,104,105,116,101,99,116,117,114,101,61,117,80,68,55,55,50,53,10,32,32,32,32,109, - 101,109,111,114,121,32,116,121,112,101,61,82,65,77,32,99,111,110,116,101,110,116,61,68,97,116,97,32,97,114,99,104, - 105,116,101,99,116,117,114,101,61,117,80,68,55,55,50,53,10,32,32,32,32,111,115,99,105,108,108,97,116,111,114,10, - 10,98,111,97,114,100,58,32,79,66,67,49,45,76,79,82,79,77,45,82,65,77,10,32,32,109,101,109,111,114,121,32, - 116,121,112,101,61,82,79,77,32,99,111,110,116,101,110,116,61,80,114,111,103,114,97,109,10,32,32,32,32,109,97,112, - 32,97,100,100,114,101,115,115,61,48,48,45,51,102,44,56,48,45,98,102,58,56,48,48,48,45,102,102,102,102,32,109, - 97,115,107,61,48,120,56,48,48,48,10,32,32,112,114,111,99,101,115,115,111,114,32,105,100,101,110,116,105,102,105,101, - 114,61,79,66,67,49,10,32,32,32,32,109,97,112,32,97,100,100,114,101,115,115,61,48,48,45,51,102,44,56,48,45, - 98,102,58,54,48,48,48,45,55,102,102,102,32,109,97,115,107,61,48,120,101,48,48,48,10,32,32,32,32,109,97,112, - 32,97,100,100,114,101,115,115,61,55,48,45,55,49,44,102,48,45,102,49,58,54,48,48,48,45,55,102,102,102,44,101, - 48,48,48,45,102,102,102,102,32,109,97,115,107,61,48,120,101,48,48,48,10,32,32,32,32,109,101,109,111,114,121,32, - 116,121,112,101,61,82,65,77,32,99,111,110,116,101,110,116,61,83,97,118,101,10,10,98,111,97,114,100,58,32,83,65, - 49,45,82,65,77,10,32,32,112,114,111,99,101,115,115,111,114,32,97,114,99,104,105,116,101,99,116,117,114,101,61,87, - 54,53,67,56,49,54,83,10,32,32,32,32,109,97,112,32,97,100,100,114,101,115,115,61,48,48,45,51,102,44,56,48, - 45,98,102,58,50,50,48,48,45,50,51,102,102,10,32,32,32,32,109,99,117,10,32,32,32,32,32,32,109,97,112,32, - 97,100,100,114,101,115,115,61,48,48,45,51,102,44,56,48,45,98,102,58,56,48,48,48,45,102,102,102,102,32,109,97, - 115,107,61,48,120,52,48,56,48,48,48,10,32,32,32,32,32,32,109,97,112,32,97,100,100,114,101,115,115,61,99,48, - 45,102,102,58,48,48,48,48,45,102,102,102,102,10,32,32,32,32,32,32,109,101,109,111,114,121,32,116,121,112,101,61, - 82,79,77,32,99,111,110,116,101,110,116,61,80,114,111,103,114,97,109,10,32,32,32,32,109,101,109,111,114,121,32,116, - 121,112,101,61,82,65,77,32,99,111,110,116,101,110,116,61,83,97,118,101,10,32,32,32,32,32,32,109,97,112,32,97, - 100,100,114,101,115,115,61,48,48,45,51,102,44,56,48,45,98,102,58,54,48,48,48,45,55,102,102,102,32,115,105,122, - 101,61,48,120,50,48,48,48,10,32,32,32,32,32,32,109,97,112,32,97,100,100,114,101,115,115,61,52,48,45,52,102, - 58,48,48,48,48,45,102,102,102,102,10,32,32,32,32,109,101,109,111,114,121,32,116,121,112,101,61,82,65,77,32,99, - 111,110,116,101,110,116,61,73,110,116,101,114,110,97,108,10,32,32,32,32,32,32,109,97,112,32,97,100,100,114,101,115, - 115,61,48,48,45,51,102,44,56,48,45,98,102,58,51,48,48,48,45,51,55,102,102,32,115,105,122,101,61,48,120,56, - 48,48,10,10,98,111,97,114,100,58,32,83,68,68,49,10,32,32,112,114,111,99,101,115,115,111,114,32,105,100,101,110, - 116,105,102,105,101,114,61,83,68,68,49,10,32,32,32,32,109,97,112,32,97,100,100,114,101,115,115,61,48,48,45,51, - 102,44,56,48,45,98,102,58,52,56,48,48,45,52,56,48,102,10,32,32,32,32,109,99,117,10,32,32,32,32,32,32, - 109,97,112,32,97,100,100,114,101,115,115,61,48,48,45,51,102,44,56,48,45,98,102,58,56,48,48,48,45,102,102,102, - 102,10,32,32,32,32,32,32,109,97,112,32,97,100,100,114,101,115,115,61,99,48,45,102,102,58,48,48,48,48,45,102, - 102,102,102,10,32,32,32,32,32,32,109,101,109,111,114,121,32,116,121,112,101,61,82,79,77,32,99,111,110,116,101,110, - 116,61,80,114,111,103,114,97,109,10,10,98,111,97,114,100,58,32,83,68,68,49,45,82,65,77,10,32,32,109,101,109, - 111,114,121,32,116,121,112,101,61,82,65,77,32,99,111,110,116,101,110,116,61,83,97,118,101,10,32,32,32,32,109,97, - 112,32,97,100,100,114,101,115,115,61,48,48,45,51,102,44,56,48,45,98,102,58,54,48,48,48,45,55,102,102,102,32, - 109,97,115,107,61,48,120,101,48,48,48,10,32,32,32,32,109,97,112,32,97,100,100,114,101,115,115,61,55,48,45,55, - 51,58,48,48,48,48,45,102,102,102,102,32,109,97,115,107,61,48,120,56,48,48,48,10,32,32,112,114,111,99,101,115, - 115,111,114,32,105,100,101,110,116,105,102,105,101,114,61,83,68,68,49,10,32,32,32,32,109,97,112,32,97,100,100,114, - 101,115,115,61,48,48,45,51,102,44,56,48,45,98,102,58,52,56,48,48,45,52,56,48,102,10,32,32,32,32,109,99, - 117,10,32,32,32,32,32,32,109,97,112,32,97,100,100,114,101,115,115,61,48,48,45,51,102,44,56,48,45,98,102,58, - 56,48,48,48,45,102,102,102,102,10,32,32,32,32,32,32,109,97,112,32,97,100,100,114,101,115,115,61,99,48,45,102, - 102,58,48,48,48,48,45,102,102,102,102,10,32,32,32,32,32,32,109,101,109,111,114,121,32,116,121,112,101,61,82,79, - 77,32,99,111,110,116,101,110,116,61,80,114,111,103,114,97,109,10,10,98,111,97,114,100,58,32,83,80,67,55,49,49, - 48,45,82,65,77,10,32,32,112,114,111,99,101,115,115,111,114,32,105,100,101,110,116,105,102,105,101,114,61,83,80,67, - 55,49,49,48,10,32,32,32,32,109,97,112,32,97,100,100,114,101,115,115,61,48,48,45,51,102,44,56,48,45,98,102, - 58,52,56,48,48,45,52,56,51,102,10,32,32,32,32,109,97,112,32,97,100,100,114,101,115,115,61,53,48,44,53,56, - 58,48,48,48,48,45,102,102,102,102,10,32,32,32,32,109,99,117,10,32,32,32,32,32,32,109,97,112,32,97,100,100, - 114,101,115,115,61,48,48,45,51,102,44,56,48,45,98,102,58,56,48,48,48,45,102,102,102,102,32,109,97,115,107,61, - 48,120,56,48,48,48,48,48,10,32,32,32,32,32,32,109,97,112,32,97,100,100,114,101,115,115,61,99,48,45,102,102, - 58,48,48,48,48,45,102,102,102,102,32,109,97,115,107,61,48,120,99,48,48,48,48,48,10,32,32,32,32,32,32,109, - 101,109,111,114,121,32,116,121,112,101,61,82,79,77,32,99,111,110,116,101,110,116,61,80,114,111,103,114,97,109,10,32, - 32,32,32,32,32,109,101,109,111,114,121,32,116,121,112,101,61,82,79,77,32,99,111,110,116,101,110,116,61,68,97,116, - 97,10,32,32,32,32,109,101,109,111,114,121,32,116,121,112,101,61,82,65,77,32,99,111,110,116,101,110,116,61,83,97, - 118,101,10,32,32,32,32,32,32,109,97,112,32,97,100,100,114,101,115,115,61,48,48,45,51,102,44,56,48,45,98,102, - 58,54,48,48,48,45,55,102,102,102,32,109,97,115,107,61,48,120,101,48,48,48,10,10,98,111,97,114,100,58,32,83, - 80,67,55,49,49,48,45,82,65,77,45,69,80,83,79,78,82,84,67,10,32,32,112,114,111,99,101,115,115,111,114,32, - 105,100,101,110,116,105,102,105,101,114,61,83,80,67,55,49,49,48,10,32,32,32,32,109,97,112,32,97,100,100,114,101, - 115,115,61,48,48,45,51,102,44,56,48,45,98,102,58,52,56,48,48,45,52,56,51,102,10,32,32,32,32,109,97,112, - 32,97,100,100,114,101,115,115,61,53,48,44,53,56,58,48,48,48,48,45,102,102,102,102,10,32,32,32,32,109,99,117, - 10,32,32,32,32,32,32,109,97,112,32,97,100,100,114,101,115,115,61,48,48,45,51,102,44,56,48,45,98,102,58,56, - 48,48,48,45,102,102,102,102,32,109,97,115,107,61,48,120,56,48,48,48,48,48,10,32,32,32,32,32,32,109,97,112, - 32,97,100,100,114,101,115,115,61,99,48,45,102,102,58,48,48,48,48,45,102,102,102,102,32,109,97,115,107,61,48,120, - 99,48,48,48,48,48,10,32,32,32,32,32,32,109,101,109,111,114,121,32,116,121,112,101,61,82,79,77,32,99,111,110, - 116,101,110,116,61,80,114,111,103,114,97,109,10,32,32,32,32,32,32,109,101,109,111,114,121,32,116,121,112,101,61,82, - 79,77,32,99,111,110,116,101,110,116,61,68,97,116,97,10,32,32,32,32,109,101,109,111,114,121,32,116,121,112,101,61, - 82,65,77,32,99,111,110,116,101,110,116,61,83,97,118,101,10,32,32,32,32,32,32,109,97,112,32,97,100,100,114,101, - 115,115,61,48,48,45,51,102,44,56,48,45,98,102,58,54,48,48,48,45,55,102,102,102,32,109,97,115,107,61,48,120, - 101,48,48,48,10,32,32,114,116,99,32,109,97,110,117,102,97,99,116,117,114,101,114,61,69,112,115,111,110,10,32,32, - 32,32,109,97,112,32,97,100,100,114,101,115,115,61,48,48,45,51,102,44,56,48,45,98,102,58,52,56,52,48,45,52, - 56,52,50,10,32,32,32,32,109,101,109,111,114,121,32,116,121,112,101,61,82,84,67,32,99,111,110,116,101,110,116,61, - 84,105,109,101,32,109,97,110,117,102,97,99,116,117,114,101,114,61,69,112,115,111,110,10,10,98,111,97,114,100,58,32, - 83,84,45,76,79,82,79,77,10,32,32,109,101,109,111,114,121,32,116,121,112,101,61,82,79,77,32,99,111,110,116,101, - 110,116,61,80,114,111,103,114,97,109,10,32,32,32,32,109,97,112,32,97,100,100,114,101,115,115,61,48,48,45,49,102, - 44,56,48,45,57,102,58,56,48,48,48,45,102,102,102,102,32,109,97,115,107,61,48,120,56,48,48,48,10,32,32,115, - 108,111,116,32,116,121,112,101,61,83,117,102,97,109,105,84,117,114,98,111,10,32,32,32,32,114,111,109,10,32,32,32, - 32,32,32,109,97,112,32,97,100,100,114,101,115,115,61,50,48,45,51,102,44,97,48,45,98,102,58,56,48,48,48,45, - 102,102,102,102,32,109,97,115,107,61,48,120,56,48,48,48,10,32,32,32,32,114,97,109,10,32,32,32,32,32,32,109, - 97,112,32,97,100,100,114,101,115,115,61,54,48,45,54,102,44,101,48,45,101,102,58,48,48,48,48,45,102,102,102,102, - 10,32,32,115,108,111,116,32,116,121,112,101,61,83,117,102,97,109,105,84,117,114,98,111,10,32,32,32,32,114,111,109, - 10,32,32,32,32,32,32,109,97,112,32,97,100,100,114,101,115,115,61,52,48,45,53,102,44,99,48,45,100,102,58,48, - 48,48,48,45,102,102,102,102,32,109,97,115,107,61,48,120,56,48,48,48,10,32,32,32,32,114,97,109,10,32,32,32, - 32,32,32,109,97,112,32,97,100,100,114,101,115,115,61,55,48,45,55,100,44,102,48,45,102,102,58,48,48,48,48,45, - 102,102,102,102,10,10, -}; -const nall::vector IPLROM = { //size: 64 +const char Boards[30183] = + "database\n revision: 2018-07-25\n\n//Boards (Production)\n\ndatabase\n revision: 2018-05-16\n\nboard: BANDAI-PT-923\n memory type=ROM " + "content=Program\n map address=00-1f,80-9f:8000-ffff mask=0x8000\n slot type=SufamiTurbo\n rom\n map address=20-3f,a0-bf:" + "8000-ffff mask=0x8000\n ram\n map address=60-6f,e0-ef:0000-ffff\n slot type=SufamiTurbo\n rom\n map address=40-5f,c0" + "-df:0000-ffff mask=0x8000\n ram\n map address=70-7d,f0-ff:0000-ffff\n\nboard: BSC-1A5B9P-01\n memory type=RAM content=Save\n " + " map address=10-17:5000-5fff mask=0xf000\n processor identifier=MCC\n map address=00-0f:5000-5fff\n mcu\n map address=" + "00-3f,80-bf:8000-ffff\n map address=40-7d,c0-ff:0000-ffff\n map address=20-3f,a0-bf:6000-7fff\n memory type=ROM cont" + "ent=Program\n memory type=RAM content=Download\n slot type=BSMemory\n\nboard: BSC-1A5M-02\n memory type=ROM content=Progra" + "m\n map address=00-1f:8000-ffff mask=0x8000 base=0x000000\n map address=20-3f:8000-ffff mask=0x8000 base=0x100000\n map ad" + "dress=80-9f:8000-ffff mask=0x8000 base=0x200000\n map address=a0-bf:8000-ffff mask=0x8000 base=0x100000\n memory type=RAM cont" + "ent=Save\n map address=70-7d,f0-ff:0000-7fff mask=0x8000\n slot type=BSMemory\n map address=c0-ef:0000-ffff\n\nboard: BSC-1A7M" + "-01\n memory type=ROM content=Program\n map address=00-1f:8000-ffff mask=0x8000 base=0x000000\n map address=20-3f:8000-ffff " + "mask=0x8000 base=0x100000\n map address=80-9f:8000-ffff mask=0x8000 base=0x200000\n map address=a0-bf:8000-ffff mask=0x8000 " + "base=0x100000\n memory type=RAM content=Save\n map address=70-7d,f0-ff:0000-7fff mask=0x8000\n slot type=BSMemory\n map addr" + "ess=c0-ef:0000-ffff\n\nboard: BSC-1J3M-01\n memory type=ROM content=Program\n map address=00-1f,80-9f:8000-ffff\n map address=" + "40-5f,c0-df:0000-ffff\n memory type=RAM content=Save\n map address=20-3f,a0-bf:6000-7fff mask=0xe000\n slot type=BSMemory\n " + "map address=20-3f,a0-bf:8000-ffff\n map address=60-7d,e0-ff:0000-ffff\n\nboard: BSC-1J5M-01\n memory type=ROM content=Program\n " + " map address=00-1f,80-9f:8000-ffff\n map address=40-5f,c0-df:0000-ffff\n memory type=RAM content=Save\n map address=20-3f,a" + "0-bf:6000-7fff mask=0xe000\n slot type=BSMemory\n map address=20-3f,a0-bf:8000-ffff\n map address=60-7d,e0-ff:0000-ffff\n\nboa" + "rd: BSC-1L3B-01\n processor architecture=W65C816S\n map address=00-3f,80-bf:2200-23ff\n mcu\n map address=00-3f,80-bf:80" + "00-ffff mask=0x408000\n map address=c0-ff:0000-ffff\n memory type=ROM content=Program\n slot type=BSMemory\n memor" + "y type=RAM content=Save\n map address=00-3f,80-bf:6000-7fff size=0x2000\n map address=40-4f:0000-ffff\n memory type=RA" + "M content=Internal\n map address=00-3f,80-bf:3000-37ff size=0x800\n\nboard: BSC-1L5B-01\n processor architecture=W65C816S\n " + "map address=00-3f,80-bf:2200-23ff\n mcu\n map address=00-3f,80-bf:8000-ffff mask=0x408000\n map address=c0-ff:0000-fff" + "f\n memory type=ROM content=Program\n slot type=BSMemory\n memory type=RAM content=Save\n map address=00-3f,80-bf:" + "6000-7fff size=0x2000\n map address=40-4f:0000-ffff\n memory type=RAM content=Internal\n map address=00-3f,80-bf:3000-" + "37ff size=0x800\n\nboard: SGB-R-10\n memory type=ROM content=Program\n map address=00-7d,80-ff:8000-ffff mask=0x8000\n map add" + "ress=40-7d,c0-ff:0000-7fff mask=0x8000\n processor identifier=ICD revision=2\n map address=00-3f,80-bf:6000-67ff,7000-7fff\n " + " memory type=ROM content=Boot architecture=LR35902\n slot type=GameBoy\n\nboard: SHVC-1A0N-(01,02,10,20,30)\n memory type=ROM co" + "ntent=Program\n map address=00-7d,80-ff:8000-ffff mask=0x8000\n map address=40-7d,c0-ff:0000-7fff mask=0x8000\n\nboard: SHVC-1" + "A1B-(04,05,06)\n memory type=ROM content=Program\n map address=00-1f,80-9f:8000-ffff mask=0x8000\n memory type=RAM content=Sav" + "e\n map address=70-7d,f0-ff:0000-ffff\n\nboard: SHVC-1A1M-(01,10,11,20)\n memory type=ROM content=Program\n map address=00-7d," + "80-ff:8000-ffff mask=0x8000\n memory type=RAM content=Save\n map address=70-7d,f0-ff:0000-7fff mask=0x8000\n\nboard: SHVC-1A3B-(" + "11,12,13)\n memory type=ROM content=Program\n map address=00-1f,80-9f:8000-ffff mask=0x8000\n memory type=RAM content=Save\n " + " map address=70-7d,f0-ff:0000-ffff\n\nboard: SHVC-1A3B-20\n memory type=ROM content=Program\n map address=00-7d,80-ff:8000-ffff " + "mask=0x8000\n memory type=RAM content=Save\n map address=70-7d,f0-ff:0000-7fff mask=0x8000\n\nboard: SHVC-1A3M-(10,20,21,30)\n m" + "emory type=ROM content=Program\n map address=00-7d,80-ff:8000-ffff mask=0x8000\n memory type=RAM content=Save\n map address=" + "70-7d,f0-ff:0000-7fff mask=0x8000\n\nboard: SHVC-1A5B-(02,04)\n memory type=ROM content=Program\n map address=00-1f,80-9f:8000-f" + "fff mask=0x8000\n memory type=RAM content=Save\n map address=70-7d,f0-ff:0000-ffff\n\nboard: SHVC-1A5M-(01,11,20)\n memory type=" + "ROM content=Program\n map address=00-7d,80-ff:8000-ffff mask=0x8000\n memory type=RAM content=Save\n map address=70-7d,f0-ff" + ":0000-7fff mask=0x8000\n\nboard: SHVC-1B0N-(02,03,10)\n memory type=ROM content=Program\n map address=00-1f,80-9f:8000-ffff mask" + "=0x8000\n processor architecture=uPD7725\n map address=30-3f,b0-bf:8000-ffff mask=0x3fff\n memory type=ROM content=Program a" + "rchitecture=uPD7725\n memory type=ROM content=Data architecture=uPD7725\n memory type=RAM content=Data architecture=uPD7725\n" + " oscillator\n\nboard: SHVC-1B5B-02\n memory type=ROM content=Program\n map address=00-1f,80-9f:8000-ffff mask=0x8000\n memory" + " type=RAM content=Save\n map address=70-7d,f0-ff:0000-ffff\n processor architecture=uPD7725\n map address=20-3f,a0-bf:8000-f" + "fff mask=0x3fff\n memory type=ROM content=Program architecture=uPD7725\n memory type=ROM content=Data architecture=uPD7725\n " + " memory type=RAM content=Data architecture=uPD7725\n oscillator\n\nboard: SHVC-1C0N\n processor architecture=GSU\n map addre" + "ss=00-3f,80-bf:3000-34ff\n memory type=ROM content=Program\n map address=00-1f,80-9f:8000-ffff mask=0x8000\n memory type" + "=RAM content=Save\n map address=60-7d,e0-ff:0000-ffff\n\nboard: SHVC-1C0N5S-01\n processor architecture=GSU\n map address=00" + "-3f,80-bf:3000-34ff\n memory type=ROM content=Program\n map address=00-1f,80-9f:8000-ffff mask=0x8000\n memory type=RAM " + "content=Save\n map address=60-7d,e0-ff:0000-ffff\n\nboard: SHVC-1CA0N5S-01\n processor architecture=GSU\n map address=00-3f," + "80-bf:3000-34ff\n memory type=ROM content=Program\n map address=00-3f,80-bf:8000-ffff mask=0x8000\n map address=40-5f," + "c0-df:0000-ffff\n memory type=RAM content=Save\n map address=00-3f,80-bf:6000-7fff size=0x2000\n map address=70-71,f0-" + "f1:0000-ffff\n\nboard: SHVC-1CA0N6S-01\n processor architecture=GSU\n map address=00-3f,80-bf:3000-34ff\n memory type=ROM cont" + "ent=Program\n map address=00-3f,80-bf:8000-ffff mask=0x8000\n map address=40-5f,c0-df:0000-ffff\n memory type=RAM cont" + "ent=Save\n map address=00-3f,80-bf:6000-7fff size=0x2000\n map address=70-71,f0-f1:0000-ffff\n\nboard: SHVC-1CA6B-01\n pro" + "cessor architecture=GSU\n map address=00-3f,80-bf:3000-34ff\n memory type=ROM content=Program\n map address=00-3f,80-bf:" + "8000-ffff mask=0x8000\n map address=40-5f,c0-df:0000-ffff\n memory type=RAM content=Save\n map address=00-3f,80-bf:600" + "0-7fff size=0x2000\n map address=70-71,f0-f1:0000-ffff\n\nboard: SHVC-1CB0N7S-01\n processor architecture=GSU\n map address=" + "00-3f,80-bf:3000-34ff\n memory type=ROM content=Program\n map address=00-3f:8000-ffff mask=0x8000\n map address=40-5f:" + "0000-ffff\n memory type=RAM content=Save\n map address=00-3f,80-bf:6000-7fff size=0x2000\n map address=70-71:0000-ffff" + "\n\nboard: SHVC-1CB5B-20\n processor architecture=GSU\n map address=00-3f,80-bf:3000-34ff\n memory type=ROM content=Program\n " + " map address=00-3f:8000-ffff mask=0x8000\n map address=40-5f:0000-ffff\n memory type=RAM content=Save\n map address" + "=00-3f,80-bf:6000-7fff size=0x2000\n map address=70-71:0000-ffff\n\nboard: SHVC-1CB7B-01\n processor architecture=GSU\n map " + "address=00-3f,80-bf:3000-34ff\n memory type=ROM content=Program\n map address=00-3f:8000-ffff mask=0x8000\n map addres" + "s=40-5f:0000-ffff\n memory type=RAM content=Save\n map address=00-3f,80-bf:6000-7fff size=0x2000\n map address=70-71:0" + "000-ffff\n\nboard: SHVC-1DC0N-01\n processor architecture=HG51BS169\n map address=00-3f,80-bf:6c00-6fff,7c00-7fff\n memory typ" + "e=ROM content=Program\n map address=00-3f,80-bf:8000-ffff mask=0x8000\n memory type=RAM content=Save\n map address=70-" + "77:0000-7fff\n memory type=ROM content=Data architecture=HG51BS169\n memory type=RAM content=Data architecture=HG51BS169\n " + " map address=00-3f,80-bf:6000-6bff,7000-7bff mask=0xf000\n oscillator\n\nboard: SHVC-1DS0B-20\n memory type=ROM content=Progra" + "m\n map address=00-7d,80-ff:8000-ffff mask=0x8000\n processor architecture=uPD96050\n map address=60-67,e0-e7:0000-3fff\n " + "memory type=ROM content=Program architecture=uPD96050\n memory type=ROM content=Data architecture=uPD96050\n memory type=RAM" + " content=Data architecture=uPD96050\n map address=68-6f,e8-ef:0000-7fff mask=0x8000\n oscillator\n\nboard: SHVC-1J0N-(01,10," + "20)\n memory type=ROM content=Program\n map address=00-3f,80-bf:8000-ffff\n map address=40-7d,c0-ff:0000-ffff\n\nboard: SHVC-1" + "J1M-(11,20)\n memory type=ROM content=Program\n map address=00-3f,80-bf:8000-ffff\n map address=40-7d,c0-ff:0000-ffff\n memo" + "ry type=RAM content=Save\n map address=20-3f,a0-bf:6000-7fff mask=0xe000\n\nboard: SHVC-1J3B-01\n memory type=ROM content=Progra" + "m\n map address=00-3f,80-bf:8000-ffff\n map address=40-7d,c0-ff:0000-ffff\n memory type=RAM content=Save\n map address=20-" + "3f,a0-bf:6000-7fff mask=0xe000\n\nboard: SHVC-1J3M-(01,11,20)\n memory type=ROM content=Program\n map address=00-3f,80-bf:8000-f" + "fff\n map address=40-7d,c0-ff:0000-ffff\n memory type=RAM content=Save\n map address=20-3f,a0-bf:6000-7fff mask=0xe000\n\nboar" + "d: SHVC-1J5M-(01,11,20)\n memory type=ROM content=Program\n map address=00-3f,80-bf:8000-ffff\n map address=40-7d,c0-ff:0000" + "-ffff\n memory type=RAM content=Save\n map address=20-3f,a0-bf:6000-7fff mask=0xe000\n\nboard: SHVC-1K0N-01\n memory type=ROM co" + "ntent=Program\n map address=00-3f,80-bf:8000-ffff\n map address=40-7d,c0-ff:0000-ffff\n processor architecture=uPD7725\n m" + "ap address=00-1f,80-9f:6000-7fff mask=0xfff\n memory type=ROM content=Program architecture=uPD7725\n memory type=ROM content" + "=Data architecture=uPD7725\n memory type=RAM content=Data architecture=uPD7725\n oscillator\n\nboard: SHVC-1K1B-01\n memory ty" + "pe=ROM content=Program\n map address=00-3f,80-bf:8000-ffff\n map address=40-7d,c0-ff:0000-ffff\n memory type=RAM content=Sav" + "e\n map address=20-3f,a0-bf:6000-7fff mask=0xe000\n processor architecture=uPD7725\n map address=00-1f,80-9f:6000-7fff mask=" + "0xfff\n memory type=ROM content=Program architecture=uPD7725\n memory type=ROM content=Data architecture=uPD7725\n memory " + "type=RAM content=Data architecture=uPD7725\n oscillator\n\nboard: SHVC-1L0N3S-01\n processor architecture=W65C816S\n map addre" + "ss=00-3f,80-bf:2200-23ff\n mcu\n map address=00-3f,80-bf:8000-ffff mask=0x408000\n map address=c0-ff:0000-ffff\n m" + "emory type=ROM content=Program\n memory type=RAM content=Save\n map address=00-3f,80-bf:6000-7fff size=0x2000\n map ad" + "dress=40-4f:0000-ffff\n memory type=RAM content=Internal\n map address=00-3f,80-bf:3000-37ff size=0x800\n\nboard: SHVC-1L3B-" + "(02,11)\n processor architecture=W65C816S\n map address=00-3f,80-bf:2200-23ff\n mcu\n map address=00-3f,80-bf:8000-ffff " + "mask=0x408000\n map address=c0-ff:0000-ffff\n memory type=ROM content=Program\n memory type=RAM content=Save\n map" + " address=00-3f,80-bf:6000-7fff size=0x2000\n map address=40-4f:0000-ffff\n memory type=RAM content=Internal\n map addr" + "ess=00-3f,80-bf:3000-37ff size=0x800\n\nboard: SHVC-1L5B-(11,20)\n processor architecture=W65C816S\n map address=00-3f,80-bf:220" + "0-23ff\n mcu\n map address=00-3f,80-bf:8000-ffff mask=0x408000\n map address=c0-ff:0000-ffff\n memory type=ROM con" + "tent=Program\n memory type=RAM content=Save\n map address=00-3f,80-bf:6000-7fff size=0x2000\n map address=40-4f:0000-f" + "fff\n memory type=RAM content=Internal\n map address=00-3f,80-bf:3000-37ff size=0x800\n\nboard: SHVC-1N0N-(01,10)\n processo" + "r identifier=SDD1\n map address=00-3f,80-bf:4800-480f\n mcu\n map address=00-3f,80-bf:8000-ffff\n map address=c0-ff:" + "0000-ffff\n memory type=ROM content=Program\n\nboard: SHVC-2A0N-01#A\n memory type=ROM content=Program\n map address=00-2f,8" + "0-af:8000-ffff mask=0x8000\n map address=40-6f,c0-ef:0000-ffff mask=0x8000\n\nboard: SHVC-2A0N-(01,10,11,20)\n memory type=ROM c" + "ontent=Program\n map address=00-7d,80-ff:8000-ffff mask=0x8000\n map address=40-7d,c0-ff:0000-7fff mask=0x8000\n\nboard: SHVC-" + "2A1M-01\n memory type=ROM content=Program\n map address=00-7d,80-ff:8000-ffff mask=0x8000\n memory type=RAM content=Save\n m" + "ap address=70-7d,f0-ff:0000-7fff mask=0x8000\n\nboard: SHVC-2A3B-01\n memory type=ROM content=Program\n map address=00-3f,80-bf:" + "8000-ffff mask=0x8000\n memory type=RAM content=Save\n map address=70-7d,f0-ff:0000-7fff mask=0x8000\n\nboard: SHVC-2A3M-01#A\n " + "memory type=ROM content=Program\n map address=00-3f,80-bf:8000-ffff mask=0x8000\n memory type=RAM content=Save\n map address" + "=70-7d,f0-ff:0000-7fff mask=0x8000\n\nboard: SHVC-2A3M-(01,11,20)\n memory type=ROM content=Program\n map address=00-7d,80-ff:80" + "00-ffff mask=0x8000\n memory type=RAM content=Save\n map address=70-7d,f0-ff:0000-7fff mask=0x8000\n\nboard: SHVC-2A5M-01\n memo" + "ry type=ROM content=Program\n map address=00-7d,80-ff:8000-ffff mask=0x8000\n memory type=RAM content=Save\n map address=70-" + "7d,f0-ff:0000-7fff mask=0x8000\n\nboard: SHVC-2B3B-01\n memory type=ROM content=Program\n map address=00-3f,80-bf:8000-ffff mask" + "=0x8000\n memory type=RAM content=Save\n map address=70-7d,f0-ff:0000-7fff mask=0x8000\n processor architecture=uPD7725\n ma" + "p address=60-6f,e0-ef:0000-7fff mask=0x3fff\n memory type=ROM content=Program architecture=uPD7725\n memory type=ROM content" + "=Data architecture=uPD7725\n memory type=RAM content=Data architecture=uPD7725\n oscillator\n\nboard: SHVC-2DC0N-01\n processo" + "r architecture=HG51BS169\n map address=00-3f,80-bf:6c00-6fff,7c00-7fff\n memory type=ROM content=Program\n map address=0" + "0-3f,80-bf:8000-ffff mask=0x8000\n memory type=RAM content=Save\n map address=70-77:0000-7fff\n memory type=ROM content=" + "Data architecture=HG51BS169\n memory type=RAM content=Data architecture=HG51BS169\n map address=00-3f,80-bf:6000-6bff,7000" + "-7bff mask=0xf000\n oscillator\n\nboard: SHVC-2E3M-01\n memory type=ROM content=Program\n map address=00-3f,80-bf:8000-ffff ma" + "sk=0x8000\n processor identifier=OBC1\n map address=00-3f,80-bf:6000-7fff mask=0xe000\n map address=70-71,f0-f1:6000-7fff,e0" + "00-ffff mask=0xe000\n memory type=RAM content=Save\n\nboard: SHVC-2J0N-(01,10,11,20)\n memory type=ROM content=Program\n map a" + "ddress=00-3f,80-bf:8000-ffff\n map address=40-7d,c0-ff:0000-ffff\n\nboard: SHVC-2J3M-(01,11,20)\n memory type=ROM content=Progra" + "m\n map address=00-3f,80-bf:8000-ffff\n map address=40-7d,c0-ff:0000-ffff\n memory type=RAM content=Save\n map address=10-" + "1f,30-3f,90-9f,b0-bf:6000-7fff mask=0xe000\n\nboard: SHVC-2J5M-01\n memory type=ROM content=Program\n map address=00-3f,80-bf:80" + "00-ffff\n map address=40-7d,c0-ff:0000-ffff\n memory type=RAM content=Save\n map address=10-1f,30-3f,90-9f,b0-bf:6000-7fff m" + "ask=0xe000\n\nboard: SHVC-3J0N-01\n memory type=ROM content=Program\n map address=00-2f,80-af:8000-ffff\n map address=40-6f,c0" + "-ef:0000-ffff\n\nboard: SHVC-BA0N-(01,10)\n memory type=ROM content=Program\n map address=00-7d,80-ff:8000-ffff mask=0x8000\n " + "map address=40-7d,c0-ff:0000-7fff mask=0x8000\n\nboard: SHVC-BA1M-01\n memory type=ROM content=Program\n map address=00-7d,80-ff" + ":8000-ffff mask=0x8000\n memory type=RAM content=Save\n map address=70-7d,f0-ff:0000-7fff mask=0x8000\n\nboard: SHVC-BA3M-(01,10" + ")\n memory type=ROM content=Program\n map address=00-7d,80-ff:8000-ffff mask=0x8000\n memory type=RAM content=Save\n map add" + "ress=70-7d,f0-ff:0000-7fff mask=0x8000\n\nboard: SHVC-BJ0N-(01,20)\n memory type=ROM content=Program\n map address=00-3f,80-bf:8" + "000-ffff\n map address=40-7d,c0-ff:0000-ffff\n\nboard: SHVC-BJ1M-(10,20)\n memory type=ROM content=Program\n map address=00-3f" + ",80-bf:8000-ffff\n map address=40-7d,c0-ff:0000-ffff\n memory type=RAM content=Save\n map address=20-3f,a0-bf:6000-7fff mask" + "=0xe000\n\nboard: SHVC-BJ3M-(10,20)\n memory type=ROM content=Program\n map address=00-3f,80-bf:8000-ffff\n map address=40-7d," + "c0-ff:0000-ffff\n memory type=RAM content=Save\n map address=20-3f,a0-bf:6000-7fff mask=0xe000\n\nboard: SHVC-LDH3C-01\n process" + "or identifier=SPC7110\n map address=00-3f,80-bf:4800-483f\n map address=50,58:0000-ffff\n mcu\n map address=00-3f,80-b" + "f:8000-ffff mask=0x800000\n map address=c0-ff:0000-ffff mask=0xc00000\n memory type=ROM content=Program\n memory typ" + "e=ROM content=Data\n memory type=RAM content=Save\n map address=00-3f,80-bf:6000-7fff mask=0xe000\n rtc manufacturer=Epson" + "\n map address=00-3f,80-bf:4840-4842\n memory type=RTC content=Time manufacturer=Epson\n\nboard: SHVC-LN3B-01\n memory type=RA" + "M content=Save\n map address=00-3f,80-bf:6000-7fff mask=0xe000\n map address=70-73:0000-ffff\n processor identifier=SDD1\n " + " map address=00-3f,80-bf:4800-480f\n mcu\n map address=00-3f,80-bf:8000-ffff\n map address=c0-ff:0000-ffff\n memor" + "y type=ROM content=Program\n\nboard: SHVC-SGB2-01\n memory type=ROM content=Program\n map address=00-7d,80-ff:8000-ffff mask=0x8" + "000\n map address=40-7d,c0-ff:0000-7fff mask=0x8000\n processor identifier=ICD revision=2\n map address=00-3f,80-bf:6000-67f" + "f,7000-7fff\n memory type=ROM content=Boot architecture=LR35902\n oscillator\n slot type=GameBoy\n\nboard: SHVC-YA0N-01\n me" + "mory type=ROM content=Program\n map address=00-7d,80-ff:8000-ffff mask=0x8000\n map address=40-7d,c0-ff:0000-7fff mask=0x800" + "0\n\nboard: SHVC-YJ0N-01\n memory type=ROM content=Program\n map address=00-3f,80-bf:8000-ffff\n map address=40-7d,c0-ff:0000-" + "ffff\n\n//Boards (Generic)\n\ndatabase\n revision: 2018-07-25\n\nboard: ARM-LOROM-RAM\n memory type=ROM content=Program\n map addres" + "s=00-7d,80-ff:8000-ffff mask=0x8000\n map address=40-6f,c0-ef:0000-7fff mask=0x8000\n memory type=RAM content=Save\n map add" + "ress=70-7d,f0-ff:0000-ffff\n processor architecture=ARM6\n map address=00-3f,80-bf:3800-38ff\n memory type=ROM content=Progr" + "am architecture=ARM6\n memory type=ROM content=Data architecture=ARM6\n memory type=RAM content=Data architecture=ARM6\n o" + "scillator\n\nboard: BS-HIROM-RAM\n memory type=ROM content=Program\n map address=00-1f,80-9f:8000-ffff\n map address=40-5f,c0-" + "df:0000-ffff\n memory type=RAM content=Save\n map address=20-3f,a0-bf:6000-7fff mask=0xe000\n slot type=BSMemory\n map addre" + "ss=20-3f,a0-bf:8000-ffff\n map address=60-7d,e0-ff:0000-ffff\n\nboard: BS-LOROM-RAM\n memory type=ROM content=Program\n map ad" + "dress=00-1f:8000-ffff base=0x000000 mask=0x8000\n map address=20-3f:8000-ffff base=0x100000 mask=0x8000\n map address=80-9f:" + "8000-ffff base=0x200000 mask=0x8000\n map address=a0-bf:8000-ffff base=0x100000 mask=0x8000\n memory type=RAM content=Save\n " + " map address=70-7d,f0-ff:0000-7fff mask=0x8000\n slot type=BSMemory\n map address=c0-ef:0000-ffff\n\nboard: BS-MCC-RAM\n memory " + "type=RAM content=Save\n map address=10-17:5000-5fff mask=0xf000\n processor identifier=MCC\n map address=00-0f:5000-5fff\n " + " mcu\n map address=00-3f,80-bf:8000-ffff\n map address=40-7d,c0-ff:0000-ffff\n map address=20-3f,a0-bf:6000-7fff\n " + " memory type=ROM content=Program\n memory type=RAM content=Download\n slot type=BSMemory\n\nboard: BS-SA1-RAM\n processo" + "r architecture=W65C816S\n map address=00-3f,80-bf:2200-23ff\n mcu\n map address=00-3f,80-bf:8000-ffff mask=0x408000\n " + " map address=c0-ff:0000-ffff\n memory type=ROM content=Program\n slot type=BSMemory\n memory type=RAM content=Save\n " + " map address=00-3f,80-bf:6000-7fff size=0x2000\n map address=40-4f:0000-ffff\n memory type=RAM content=Internal\n m" + "ap address=00-3f,80-bf:3000-37ff size=0x800\n\nboard: EVENT-CC92\n memory type=RAM content=Save\n map address=70-7d,f0-ff:0000-7" + "fff mask=0x8000\n processor manufacturer=NEC architecture=uPD78214\n identifier: Campus Challenge '92\n map address=c0,e0:00" + "00\n mcu\n map address=00-1f,80-9f:8000-ffff\n memory type=ROM content=Program\n memory type=ROM content=Level-1\n " + " memory type=ROM content=Level-2\n memory type=ROM content=Level-3\n dip\n processor manufacturer=NEC architecture=uPD" + "7725\n map address=20-3f,a0-bf:8000-ffff mask=0x7fff\n memory type=ROM content=Program architecture=uPD7725\n memory type=" + "ROM content=Data architecture=uPD7725\n memory type=RAM content=Data architecture=uPD7725\n oscillator\n\nboard: EVENT-PF94\n " + "memory type=RAM content=Save\n map address=30-3f,b0-bf:6000-7fff mask=0xe000\n processor manufacturer=NEC architecture=uPD7821" + "4\n identifier: PowerFest '94\n map address=10,20:6000\n mcu\n map address=00-3f,80-bf:8000-ffff\n map address=c0-" + "ff:0000-ffff\n memory type=ROM content=Program\n memory type=ROM content=Level-1\n memory type=ROM content=Level-2\n " + " memory type=ROM content=Level-3\n dip\n processor manufacturer=NEC architecture=uPD7725\n map address=00-0f,80-8f:6000-" + "7fff mask=0xfff\n memory type=ROM content=Program architecture=uPD7725\n memory type=ROM content=Data architecture=uPD7725\n " + " memory type=RAM content=Data architecture=uPD7725\n oscillator\n\nboard: EXHIROM-RAM\n memory type=ROM content=Program\n ma" + "p address=00-3f:8000-ffff base=0x400000\n map address=40-7d:0000-ffff base=0x400000\n map address=80-bf:8000-ffff mask=0xc00" + "000\n map address=c0-ff:0000-ffff mask=0xc00000\n memory type=RAM content=Save\n map address=20-3f,a0-bf:6000-7fff mask=0xe0" + "00\n map address=70-7d:0000-7fff\n\nboard: EXHIROM-RAM-SHARPRTC\n memory type=ROM content=Program\n map address=00-3f:8000-fff" + "f base=0x400000\n map address=40-7d:0000-ffff base=0x400000\n map address=80-bf:8000-ffff mask=0xc00000\n map address=c0-f" + "f:0000-ffff mask=0xc00000\n memory type=RAM content=Save\n map address=20-3f,a0-bf:6000-7fff mask=0xe000\n map address=70-7d" + ":0000-7fff\n rtc manufacturer=Sharp\n map address=00-3f,80-bf:2800-2801\n memory type=RTC content=Time manufacturer=Sharp\n\nb" + "oard: EXNEC-LOROM\n memory type=ROM content=Program\n map address=00-7d,80-ff:8000-ffff mask=0x8000\n processor architecture=u" + "PD96050\n map address=60-67,e0-e7:0000-3fff\n memory type=ROM content=Program architecture=uPD96050\n memory type=ROM cont" + "ent=Data architecture=uPD96050\n memory type=RAM content=Data architecture=uPD96050\n map address=68-6f,e8-ef:0000-7fff ma" + "sk=0x8000\n oscillator\n\nboard: EXSPC7110-RAM-EPSONRTC\n memory type=ROM content=Expansion\n map address=40-4f:0000-ffff\n pr" + "ocessor identifier=SPC7110\n map address=00-3f,80-bf:4800-483f\n map address=50,58:0000-ffff\n mcu\n map address=00-3f" + ",80-bf:8000-ffff mask=0x800000\n map address=c0-ff:0000-ffff mask=0xc00000\n memory type=ROM content=Program\n memor" + "y type=ROM content=Data\n memory type=RAM content=Save\n map address=00-3f,80-bf:6000-7fff mask=0xe000\n rtc manufacturer=" + "Epson\n map address=00-3f,80-bf:4840-4842\n memory type=RTC content=Time manufacturer=Epson\n\nboard: GB-LOROM\n memory type=R" + "OM content=Program\n map address=00-7d,80-ff:8000-ffff mask=0x8000\n map address=40-7d,c0-ff:0000-7fff mask=0x8000\n process" + "or identifier=ICD revision=2\n map address=00-3f,80-bf:6000-67ff,7000-7fff\n memory type=ROM content=Boot architecture=LR359" + "02\n oscillator\n slot type=GameBoy\n\nboard: GSU-RAM\n processor architecture=GSU\n map address=00-3f,80-bf:3000-34ff\n m" + "emory type=ROM content=Program\n map address=00-3f,80-bf:8000-ffff mask=0x8000\n map address=40-5f,c0-df:0000-ffff\n m" + "emory type=RAM content=Save\n map address=00-3f,80-bf:6000-7fff size=0x2000\n map address=70-71,f0-f1:0000-ffff\n\nboard: " + "HIROM\n memory type=ROM content=Program\n map address=00-3f,80-bf:8000-ffff\n map address=40-7d,c0-ff:0000-ffff\n\nboard: HIRO" + "M-RAM\n memory type=ROM content=Program\n map address=00-3f,80-bf:8000-ffff\n map address=40-7d,c0-ff:0000-ffff\n memory typ" + "e=RAM content=Save\n map address=20-3f,a0-bf:6000-7fff mask=0xe000\n\nboard: HITACHI-LOROM\n processor architecture=HG51BS169\n " + " map address=00-3f,80-bf:6c00-6fff,7c00-7fff\n memory type=ROM content=Program\n map address=00-3f,80-bf:8000-ffff mask=0" + "x8000\n memory type=RAM content=Save\n map address=70-77:0000-7fff\n memory type=ROM content=Data architecture=HG51BS169" + "\n memory type=RAM content=Data architecture=HG51BS169\n map address=00-3f,80-bf:6000-6bff,7000-7bff mask=0xf000\n oscil" + "lator\n\nboard: LOROM\n memory type=ROM content=Program\n map address=00-7d,80-ff:8000-ffff mask=0x8000\n\nboard: LOROM-RAM\n memo" + "ry type=ROM content=Program\n map address=00-7d,80-ff:8000-ffff mask=0x8000\n memory type=RAM content=Save\n map address=70-" + "7d,f0-ff:0000-7fff mask=0x8000\n\nboard: LOROM-RAM#A\n memory type=ROM content=Program\n map address=00-3f,80-bf:8000-ffff mask=" + "0x8000\n memory type=RAM content=Save\n map address=70-7d,f0-ff:0000-ffff mask=0x8000\n\nboard: NEC-HIROM\n memory type=ROM cont" + "ent=Program\n map address=00-3f,80-bf:8000-ffff\n map address=40-7d,c0-ff:0000-ffff\n processor architecture=uPD7725\n map" + " address=00-1f,80-9f:6000-7fff mask=0xfff\n memory type=ROM content=Program architecture=uPD7725\n memory type=ROM content=D" + "ata architecture=uPD7725\n memory type=RAM content=Data architecture=uPD7725\n oscillator\n\nboard: NEC-HIROM-RAM\n memory typ" + "e=ROM content=Program\n map address=00-3f,80-bf:8000-ffff\n map address=40-7d,c0-ff:0000-ffff\n memory type=RAM content=Save" + "\n map address=20-3f,a0-bf:6000-7fff mask=0xe000\n processor architecture=uPD7725\n map address=00-1f,80-9f:6000-7fff mask=0" + "xfff\n memory type=ROM content=Program architecture=uPD7725\n memory type=ROM content=Data architecture=uPD7725\n memory t" + "ype=RAM content=Data architecture=uPD7725\n oscillator\n\nboard: NEC-LOROM\n memory type=ROM content=Program\n map address=00-" + "1f,80-9f:8000-ffff mask=0x8000\n processor architecture=uPD7725\n map address=30-3f,b0-bf:8000-ffff mask=0x3fff\n memory typ" + "e=ROM content=Program architecture=uPD7725\n memory type=ROM content=Data architecture=uPD7725\n memory type=RAM content=Dat" + "a architecture=uPD7725\n oscillator\n\nboard: NEC-LOROM-RAM\n memory type=ROM content=Program\n map address=00-3f,80-bf:8000-f" + "fff mask=0x8000\n memory type=RAM content=Save\n map address=70-7d,f0-ff:0000-7fff mask=0x8000\n processor architecture=uPD772" + "5\n map address=60-6f,e0-ef:0000-7fff mask=0x3fff\n memory type=ROM content=Program architecture=uPD7725\n memory type=ROM" + " content=Data architecture=uPD7725\n memory type=RAM content=Data architecture=uPD7725\n oscillator\n\nboard: NEC-LOROM-RAM#A\n" + " memory type=ROM content=Program\n map address=00-1f,80-9f:8000-ffff mask=0x8000\n memory type=RAM content=Save\n map addre" + "ss=70-7d,f0-ff:0000-ffff\n processor architecture=uPD7725\n map address=20-3f,a0-bf:8000-ffff mask=0x3fff\n memory type=ROM " + "content=Program architecture=uPD7725\n memory type=ROM content=Data architecture=uPD7725\n memory type=RAM content=Data arch" + "itecture=uPD7725\n oscillator\n\nboard: OBC1-LOROM-RAM\n memory type=ROM content=Program\n map address=00-3f,80-bf:8000-ffff m" + "ask=0x8000\n processor identifier=OBC1\n map address=00-3f,80-bf:6000-7fff mask=0xe000\n map address=70-71,f0-f1:6000-7fff,e" + "000-ffff mask=0xe000\n memory type=RAM content=Save\n\nboard: SA1-RAM\n processor architecture=W65C816S\n map address=00-3f,80" + "-bf:2200-23ff\n mcu\n map address=00-3f,80-bf:8000-ffff mask=0x408000\n map address=c0-ff:0000-ffff\n memory type=" + "ROM content=Program\n memory type=RAM content=Save\n map address=00-3f,80-bf:6000-7fff size=0x2000\n map address=40-4f" + ":0000-ffff\n memory type=RAM content=Internal\n map address=00-3f,80-bf:3000-37ff size=0x800\n\nboard: SDD1\n processor iden" + "tifier=SDD1\n map address=00-3f,80-bf:4800-480f\n mcu\n map address=00-3f,80-bf:8000-ffff\n map address=c0-ff:0000-f" + "fff\n memory type=ROM content=Program\n\nboard: SDD1-RAM\n memory type=RAM content=Save\n map address=00-3f,80-bf:6000-7fff " + "mask=0xe000\n map address=70-73:0000-ffff mask=0x8000\n processor identifier=SDD1\n map address=00-3f,80-bf:4800-480f\n mc" + "u\n map address=00-3f,80-bf:8000-ffff\n map address=c0-ff:0000-ffff\n memory type=ROM content=Program\n\nboard: SPC711" + "0-RAM\n processor identifier=SPC7110\n map address=00-3f,80-bf:4800-483f\n map address=50,58:0000-ffff\n mcu\n map add" + "ress=00-3f,80-bf:8000-ffff mask=0x800000\n map address=c0-ff:0000-ffff mask=0xc00000\n memory type=ROM content=Program\n " + " memory type=ROM content=Data\n memory type=RAM content=Save\n map address=00-3f,80-bf:6000-7fff mask=0xe000\n\nboard: S" + "PC7110-RAM-EPSONRTC\n processor identifier=SPC7110\n map address=00-3f,80-bf:4800-483f\n map address=50,58:0000-ffff\n mcu" + "\n map address=00-3f,80-bf:8000-ffff mask=0x800000\n map address=c0-ff:0000-ffff mask=0xc00000\n memory type=ROM con" + "tent=Program\n memory type=ROM content=Data\n memory type=RAM content=Save\n map address=00-3f,80-bf:6000-7fff mask=0x" + "e000\n rtc manufacturer=Epson\n map address=00-3f,80-bf:4840-4842\n memory type=RTC content=Time manufacturer=Epson\n\nboard: " + "ST-LOROM\n memory type=ROM content=Program\n map address=00-1f,80-9f:8000-ffff mask=0x8000\n slot type=SufamiTurbo\n rom\n " + " map address=20-3f,a0-bf:8000-ffff mask=0x8000\n ram\n map address=60-6f,e0-ef:0000-ffff\n slot type=SufamiTurbo\n rom" + "\n map address=40-5f,c0-df:0000-ffff mask=0x8000\n ram\n map address=70-7d,f0-ff:0000-ffff\n\n" +; +const unsigned char IPLROM[64] = { 205,239,189,232,0,198,29,208,252,143,170,244,143,187,245,120,204,244,208,251,47,25,235,244,208,252,126,244,208,11,228,245, 203,244,215,0,252,208,243,171,1,16,239,126,244,16,235,186,246,218,0,186,244,196,244,221,93,208,219,31,0,0,192,255, }; diff --git a/higan/target-bsnes/resource/resource.hpp b/higan/target-bsnes/resource/resource.hpp index c671bfc1..833f43c2 100644 --- a/higan/target-bsnes/resource/resource.hpp +++ b/higan/target-bsnes/resource/resource.hpp @@ -1,8 +1,8 @@ namespace Resource { -extern const nall::vector Icon; -extern const nall::vector Logo; +extern const unsigned char Icon[3463]; +extern const unsigned char Logo[23467]; namespace System { -extern const nall::vector Boards; -extern const nall::vector IPLROM; +extern const char Boards[30183]; +extern const unsigned char IPLROM[64]; } } diff --git a/higan/target-bsnes/settings/drivers.cpp b/higan/target-bsnes/settings/drivers.cpp index 60cb8ba5..0cb9fbd0 100644 --- a/higan/target-bsnes/settings/drivers.cpp +++ b/higan/target-bsnes/settings/drivers.cpp @@ -20,6 +20,7 @@ auto DriverSettings::create() -> void { videoBlockingToggle.setText("Synchronize").onToggle([&] { settings["Video/Blocking"].setValue(videoBlockingToggle.checked()); program.updateVideoBlocking(); + presentation.speedMenu.setEnabled(!videoBlockingToggle.checked() && audioBlockingToggle.checked()); }); videoFlushToggle.setText("GPU sync").onToggle([&] { settings["Video/Flush"].setValue(videoFlushToggle.checked()); @@ -47,6 +48,7 @@ auto DriverSettings::create() -> void { audioBlockingToggle.setText("Synchronize").onToggle([&] { settings["Audio/Blocking"].setValue(audioBlockingToggle.checked()); program.updateAudioBlocking(); + presentation.speedMenu.setEnabled(!videoBlockingToggle.checked() && audioBlockingToggle.checked()); }); audioDynamicToggle.setText("Dynamic rate").onToggle([&] { settings["Audio/Dynamic"].setValue(audioDynamicToggle.checked()); diff --git a/higan/target-bsnes/tools/cheat-editor.cpp b/higan/target-bsnes/tools/cheat-editor.cpp index 3930d66a..c93849bc 100644 --- a/higan/target-bsnes/tools/cheat-editor.cpp +++ b/higan/target-bsnes/tools/cheat-editor.cpp @@ -56,7 +56,7 @@ auto CheatWindow::create() -> void { nameValue.onActivate([&] { if(acceptButton.enabled()) acceptButton.doActivate(); }); nameValue.onChange([&] { doChange(); }); codeLayout.setAlignment(0.0); - codeLabel.setText("Code:"); + codeLabel.setText("Code(s):"); codeValue.setFont(Font().setFamily(Font::Mono)); codeValue.onChange([&] { doChange(); }); enableOption.setText("Enable"); diff --git a/higan/target-bsnes/tools/manifest-viewer.cpp b/higan/target-bsnes/tools/manifest-viewer.cpp index 0b1cc165..61577b59 100644 --- a/higan/target-bsnes/tools/manifest-viewer.cpp +++ b/higan/target-bsnes/tools/manifest-viewer.cpp @@ -34,7 +34,7 @@ auto ManifestViewer::loadManifest() -> void { if(offset == 1 && program.bsMemory) verified = program.bsMemory.verified; if(offset == 1 && program.sufamiTurboA) verified = program.sufamiTurboA.verified; if(offset == 2 && program.sufamiTurboB) verified = program.sufamiTurboB.verified; - item.setIcon(verified ? Icon::Emblem::Program : Icon::Emblem::Binary); + item.setIcon(verified ? (image)Icon::Emblem::Program : (image)Icon::Emblem::Binary); } manifestOption.doChange(); } @@ -49,6 +49,6 @@ auto ManifestViewer::selectManifest() -> void { if(offset == 1 && program.bsMemory) location = program.bsMemory.location; if(offset == 1 && program.sufamiTurboA) location = program.sufamiTurboA.location; if(offset == 2 && program.sufamiTurboB) location = program.sufamiTurboB.location; - typeIcon.setIcon(location.endsWith("/") ? Icon::Action::Open : Icon::Emblem::File); + typeIcon.setIcon(location.endsWith("/") ? (image)Icon::Action::Open : (image)Icon::Emblem::File); nameLabel.setText(location.trimRight("/", 1L)); } diff --git a/higan/target-bsnes/tools/state-manager.cpp b/higan/target-bsnes/tools/state-manager.cpp index e2e1f8d5..7a52d498 100644 --- a/higan/target-bsnes/tools/state-manager.cpp +++ b/higan/target-bsnes/tools/state-manager.cpp @@ -60,8 +60,8 @@ auto StateManager::create() -> void { stateList.sort(); }); categoryLabel.setText("Category:"); - categoryOption.append(ComboButtonItem().setText("Managed States").setProperty("type", "managed/")); - categoryOption.append(ComboButtonItem().setText("Quick States").setProperty("type", "quick/")); + categoryOption.append(ComboButtonItem().setText("Managed States").setProperty("type", "Managed/")); + categoryOption.append(ComboButtonItem().setText("Quick States").setProperty("type", "Quick/")); categoryOption.onChange([&] { loadStates(); }); statePreviewSeparator.setColor({192, 192, 192}); statePreviewLabel.setFont(Font().setBold()).setText("Preview"); @@ -142,8 +142,8 @@ auto StateManager::updateSelection() -> void { loadButton.setEnabled(batched.size() == 1); saveButton.setEnabled(batched.size() == 1); editButton.setEnabled(batched.size() == 1); - addButton.setVisible(type() != "quick/"); - editButton.setVisible(type() != "quick/"); + addButton.setVisible(type() != "Quick/"); + editButton.setVisible(type() != "Quick/"); removeButton.setEnabled(batched.size() >= 1); statePreview.setColor({0, 0, 0}); diff --git a/higan/target-higan/higan.cpp b/higan/target-higan/higan.cpp index 4d3d67d4..5d59fc82 100644 --- a/higan/target-higan/higan.cpp +++ b/higan/target-higan/higan.cpp @@ -12,10 +12,13 @@ auto locate(string name) -> string { return {Path::userData(), "higan/", name}; } -#include -auto nall::main(vector arguments) -> void { +auto hiro::initialize() -> void { Application::setName("higan"); Application::setScreenSaver(false); +} + +#include +auto nall::main(vector arguments) -> void { new Program(arguments); Application::run(); } diff --git a/higan/target-higan/presentation/presentation.cpp b/higan/target-higan/presentation/presentation.cpp index abe7c1b0..d3bfc641 100644 --- a/higan/target-higan/presentation/presentation.cpp +++ b/higan/target-higan/presentation/presentation.cpp @@ -264,13 +264,13 @@ auto Presentation::clearViewport() -> void { uint length = 0; uint width = 16; uint height = 16; - if(video->lock(output, length, width, height)) { + if(video->acquire(output, length, width, height)) { for(uint y : range(height)) { auto line = output + y * (length >> 2); for(uint x : range(width)) *line++ = 0xff000000; } if(!emulator || !emulator->loaded()) drawIcon(output, length, width, height); - video->unlock(); + video->release(); video->output(); } } @@ -385,7 +385,7 @@ auto Presentation::loadSystems() -> void { string filename = system["Load"].text(); string load = Location::base(filename).trimRight("/", 1L); string alias = system["Alias"].text(); - item.setIcon(load ? Icon::Emblem::Folder : Icon::Device::Storage); + item.setIcon(load ? (image)Icon::Emblem::Folder : (image)Icon::Device::Storage); item.setText({alias ? alias : load ? load : name, " ..."}); item.onActivate([=] { for(auto& emulator : program->emulators) { diff --git a/higan/target-higan/program/platform.cpp b/higan/target-higan/program/platform.cpp index 2dea3cd2..047d3fcc 100644 --- a/higan/target-higan/program/platform.cpp +++ b/higan/target-higan/program/platform.cpp @@ -67,14 +67,14 @@ auto Program::videoRefresh(uint displayID, const uint32* data, uint pitch, uint height -= overscanVertical * 2; } - if(video->lock(output, length, width, height)) { + if(video->acquire(output, length, width, height)) { length >>= 2; for(auto y : range(height)) { memory::copy(output + y * length, data + y * pitch, width); } - video->unlock(); + video->release(); video->output(); } diff --git a/higan/target-higan/program/utility.cpp b/higan/target-higan/program/utility.cpp index 6ebd10e3..187bcb72 100644 --- a/higan/target-higan/program/utility.cpp +++ b/higan/target-higan/program/utility.cpp @@ -1,41 +1,44 @@ auto Program::initializeVideoDriver() -> void { - if(!Video::availableDrivers().find(settings["Video/Driver"].text())) { - settings["Video/Driver"].setValue("None"); + if(!Video::hasDrivers().find(settings["Video/Driver"].text())) { + settings["Video/Driver"].setValue(Video::safestDriver()); } - video = Video::create(settings["Video/Driver"].text()); + video = new Video; + video->create(settings["Video/Driver"].text()); video->setContext(presentation->viewport.handle()); video->setBlocking(settings["Video/Synchronize"].boolean()); if(!video->ready()) { MessageDialog().setText("Failed to initialize video driver").warning(); - video = Video::create("None"); + video = new Video; + video->create("None"); } presentation->clearViewport(); } auto Program::initializeAudioDriver() -> void { - if(!Audio::availableDrivers().find(settings["Audio/Driver"].text())) { + if(!Audio::hasDrivers().find(settings["Audio/Driver"].text())) { settings["Audio/Driver"].setValue("None"); } - audio = Audio::create(settings["Audio/Driver"].text()); + audio = new Audio; + audio->create(settings["Audio/Driver"].text()); audio->setContext(presentation->viewport.handle()); - if(!audio->availableDevices().find(settings["Audio/Device"].text())) { - settings["Audio/Device"].setValue(audio->availableDevices()(0)); + if(!audio->hasDevices().find(settings["Audio/Device"].text())) { + settings["Audio/Device"].setValue(audio->device()); } audio->setDevice(settings["Audio/Device"].text()); - if(!audio->availableFrequencies().find(settings["Audio/Frequency"].real())) { - settings["Audio/Frequency"].setValue(audio->availableFrequencies()(0)); + if(!audio->hasFrequencies().find(settings["Audio/Frequency"].natural())) { + settings["Audio/Frequency"].setValue(audio->frequency()); } - audio->setFrequency(settings["Audio/Frequency"].real()); + audio->setFrequency(settings["Audio/Frequency"].natural()); - if(!audio->availableLatencies().find(settings["Audio/Latency"].natural())) { - settings["Audio/Latency"].setValue(audio->availableLatencies()(0)); + if(!audio->hasLatencies().find(settings["Audio/Latency"].natural())) { + settings["Audio/Latency"].setValue(audio->latency()); } - audio->setLatency(settings["Audio/Latency"].real()); + audio->setLatency(settings["Audio/Latency"].natural()); audio->setChannels(2); audio->setExclusive(settings["Audio/Exclusive"].boolean()); @@ -43,22 +46,25 @@ auto Program::initializeAudioDriver() -> void { if(!audio->ready()) { MessageDialog().setText("Failed to initialize audio driver").warning(); - audio = Audio::create("None"); + audio = new Audio; + audio->create("None"); } Emulator::audio.setFrequency(settings["Audio/Frequency"].real()); } auto Program::initializeInputDriver() -> void { - if(!Input::availableDrivers().find(settings["Input/Driver"].text())) { + if(!Input::hasDrivers().find(settings["Input/Driver"].text())) { settings["Input/Driver"].setValue("None"); } - input = Input::create(settings["Input/Driver"].text()); + input = new Input; + input->create(settings["Input/Driver"].text()); input->setContext(presentation->viewport.handle()); if(!input->ready()) { MessageDialog().setText("Failed to initialize input driver").warning(); - input = Input::create("None"); + input = new Input; + input->create("None"); } } diff --git a/higan/target-higan/resource/resource.cpp b/higan/target-higan/resource/resource.cpp index 0f659a8d..fc4f05b6 100644 --- a/higan/target-higan/resource/resource.cpp +++ b/higan/target-higan/resource/resource.cpp @@ -1,8 +1,7 @@ -#include #include "resource.hpp" namespace Resource { -const nall::vector Icon = { //size: 3088 +const unsigned char Icon[3088] = { 137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82,0,0,0,112,0,0,0,112,8,6,0,0,0,198,224,244, 75,0,0,0,4,103,65,77,65,0,0,177,143,11,252,97,5,0,0,0,32,99,72,82,77,0,0,122,38,0,0,128, 132,0,0,250,0,0,0,128,232,0,0,117,48,0,0,234,96,0,0,58,152,0,0,23,112,156,186,81,60,0,0,0, @@ -101,7 +100,7 @@ const nall::vector Icon = { //size: 3088 105,97,47,104,105,103,97,110,47,105,99,111,110,47,104,105,103,97,110,45,110,111,99,105,114,99,108,101,46,115,118,103, 144,27,14,155,0,0,0,0,73,69,78,68,174,66,96,130, }; -const nall::vector Logo = { //size: 25128 +const unsigned char Logo[25128] = { 137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82,0,0,1,143,0,0,0,95,8,6,0,0,0,16,211,75, 124,0,0,0,4,103,65,77,65,0,0,177,143,11,252,97,5,0,0,0,32,99,72,82,77,0,0,122,38,0,0,128, 132,0,0,250,0,0,0,128,232,0,0,117,48,0,0,234,96,0,0,58,152,0,0,23,112,156,186,81,60,0,0,0, diff --git a/higan/target-higan/resource/resource.hpp b/higan/target-higan/resource/resource.hpp index 131c0ce8..52f42e5f 100644 --- a/higan/target-higan/resource/resource.hpp +++ b/higan/target-higan/resource/resource.hpp @@ -1,4 +1,4 @@ namespace Resource { -extern const nall::vector Icon; -extern const nall::vector Logo; +extern const unsigned char Icon[3088]; +extern const unsigned char Logo[25128]; } diff --git a/higan/target-higan/settings/advanced.cpp b/higan/target-higan/settings/advanced.cpp index 4ff634ff..e315caae 100644 --- a/higan/target-higan/settings/advanced.cpp +++ b/higan/target-higan/settings/advanced.cpp @@ -7,26 +7,23 @@ AdvancedSettings::AdvancedSettings(TabFrame* parent) : TabFrameItem(parent) { driverLabel.setText("Driver Selection").setFont(Font().setBold()); videoLabel.setText("Video:"); videoDriver.onChange([&] { settings["Video/Driver"].setValue(videoDriver.selected().text()); }); - for(auto& driver : Video::availableDrivers()) { - ComboButtonItem item; + for(auto& driver : Video::hasDrivers()) { + ComboButtonItem item{&videoDriver}; item.setText(driver); - videoDriver.append(item); if(settings["Video/Driver"].text() == driver) item.setSelected(); } audioLabel.setText("Audio:"); audioDriver.onChange([&] { settings["Audio/Driver"].setValue(audioDriver.selected().text()); }); - for(auto& driver : Audio::availableDrivers()) { - ComboButtonItem item; + for(auto& driver : Audio::hasDrivers()) { + ComboButtonItem item{&audioDriver}; item.setText(driver); - audioDriver.append(item); if(settings["Audio/Driver"].text() == driver) item.setSelected(); } inputLabel.setText("Input:"); inputDriver.onChange([&] { settings["Input/Driver"].setValue(inputDriver.selected().text()); }); - for(auto& driver : Input::availableDrivers()) { - ComboButtonItem item; + for(auto& driver : Input::hasDrivers()) { + ComboButtonItem item{&inputDriver}; item.setText(driver); - inputDriver.append(item); if(settings["Input/Driver"].text() == driver) item.setSelected(); } diff --git a/higan/target-higan/settings/audio.cpp b/higan/target-higan/settings/audio.cpp index 362fdb9c..d50c5972 100644 --- a/higan/target-higan/settings/audio.cpp +++ b/higan/target-higan/settings/audio.cpp @@ -13,7 +13,7 @@ AudioSettings::AudioSettings(TabFrame* parent) : TabFrameItem(parent) { updateDevice(); }); - for(auto& device : audio->availableDevices()) { + for(auto& device : audio->hasDevices()) { deviceList.append(ComboButtonItem().setText(device)); if(device == settings["Audio/Device"].text()) { deviceList.item(deviceList.itemCount() - 1).setSelected(); @@ -54,15 +54,15 @@ AudioSettings::AudioSettings(TabFrame* parent) : TabFrameItem(parent) { auto AudioSettings::updateDevice() -> void { frequencyList.reset(); - for(auto& frequency : audio->availableFrequencies()) { - frequencyList.append(ComboButtonItem().setText((uint)frequency)); - if(frequency == settings["Audio/Frequency"].real()) { + for(auto& frequency : audio->hasFrequencies()) { + frequencyList.append(ComboButtonItem().setText(frequency)); + if(frequency == settings["Audio/Frequency"].natural()) { frequencyList.item(frequencyList.itemCount() - 1).setSelected(); } } latencyList.reset(); - for(auto& latency : audio->availableLatencies()) { + for(auto& latency : audio->hasLatencies()) { latencyList.append(ComboButtonItem().setText(latency)); if(latency == settings["Audio/Latency"].natural()) { latencyList.item(latencyList.itemCount() - 1).setSelected(); diff --git a/higan/target-higan/settings/hotkeys.cpp b/higan/target-higan/settings/hotkeys.cpp index f9668fff..36e56b2d 100644 --- a/higan/target-higan/settings/hotkeys.cpp +++ b/higan/target-higan/settings/hotkeys.cpp @@ -3,6 +3,7 @@ HotkeySettings::HotkeySettings(TabFrame* parent) : TabFrameItem(parent) { setText("Hotkeys"); layout.setPadding(5); + mappingList.setHeadered(); mappingList.onActivate([&] { assignMapping(); }); mappingList.onChange([&] { eraseButton.setEnabled((bool)mappingList.selected()); }); resetButton.setText("Reset").onActivate([&] { @@ -24,15 +25,12 @@ HotkeySettings::HotkeySettings(TabFrame* parent) : TabFrameItem(parent) { auto HotkeySettings::reloadMappings() -> void { mappingList.reset(); - mappingList.append(TableViewHeader().setVisible() - .append(TableViewColumn().setText("Name")) - .append(TableViewColumn().setText("Mapping").setExpandable()) - ); + mappingList.append(TableViewColumn().setText("Name")); + mappingList.append(TableViewColumn().setText("Mapping").setExpandable()); for(auto& hotkey : inputManager->hotkeys) { - mappingList.append(TableViewItem() - .append(TableViewCell().setText(hotkey->name)) - .append(TableViewCell()) - ); + TableViewItem item{&mappingList}; + item.append(TableViewCell().setText(hotkey->name)); + item.append(TableViewCell()); } mappingList.resizeColumns(); } diff --git a/higan/target-higan/settings/input.cpp b/higan/target-higan/settings/input.cpp index 1d7087bd..6dacd98a 100644 --- a/higan/target-higan/settings/input.cpp +++ b/higan/target-higan/settings/input.cpp @@ -23,6 +23,7 @@ InputSettings::InputSettings(TabFrame* parent) : TabFrameItem(parent) { emulatorList.onChange([&] { reloadPorts(); }); portList.onChange([&] { reloadDevices(); }); deviceList.onChange([&] { reloadMappings(); }); + mappingList.setHeadered(); mappingList.onActivate([&] { assignMapping(); }); mappingList.onChange([&] { updateControls(); }); assignMouse1.setVisible(false).onActivate([&] { assignMouseInput(0); }); @@ -98,15 +99,12 @@ auto InputSettings::reloadDevices() -> void { auto InputSettings::reloadMappings() -> void { eraseButton.setEnabled(false); mappingList.reset(); - mappingList.append(TableViewHeader().setVisible() - .append(TableViewColumn().setText("Name")) - .append(TableViewColumn().setText("Mapping").setExpandable()) - ); + mappingList.append(TableViewColumn().setText("Name")); + mappingList.append(TableViewColumn().setText("Mapping").setExpandable()); for(auto& mapping : activeDevice().mappings) { - mappingList.append(TableViewItem() - .append(TableViewCell().setText(mapping.name)) - .append(TableViewCell()) - ); + TableViewItem item{&mappingList}; + item.append(TableViewCell().setText(mapping.name)); + item.append(TableViewCell()); } refreshMappings(); } diff --git a/higan/target-higan/settings/systems.cpp b/higan/target-higan/settings/systems.cpp index f7ec8515..485d0bda 100644 --- a/higan/target-higan/settings/systems.cpp +++ b/higan/target-higan/settings/systems.cpp @@ -32,10 +32,8 @@ SystemSettings::SystemSettings(TabFrame* parent) : TabFrameItem(parent) { auto SystemSettings::reload() -> void { systemList.reset(); - systemList.append(TableViewHeader().setVisible() - .append(TableViewColumn()) - .append(TableViewColumn().setText("System").setExpandable()) - ); + systemList.append(TableViewColumn()); + systemList.append(TableViewColumn().setText("System").setExpandable()); for(auto system : settings.find("Systems/System")) { string name = system.text(); string load = Location::base(system["Load"].text()).trimRight("/", 1L); @@ -46,7 +44,7 @@ auto SystemSettings::reload() -> void { .setChecked(system["Visible"].boolean()) ) .append(TableViewCell() - .setIcon(load ? Icon::Emblem::Folder : Icon::Device::Storage) + .setIcon(load ? (image)Icon::Emblem::Folder : (image)Icon::Device::Storage) .setText(alias ? alias : load ? load : name) ) ); diff --git a/higan/target-higan/tools/cheat-editor.cpp b/higan/target-higan/tools/cheat-editor.cpp index d9ca1499..93baa465 100644 --- a/higan/target-higan/tools/cheat-editor.cpp +++ b/higan/target-higan/tools/cheat-editor.cpp @@ -3,19 +3,17 @@ CheatEditor::CheatEditor(TabFrame* parent) : TabFrameItem(parent) { setText("Cheat Editor"); layout.setPadding(5); - cheatList.append(TableViewHeader().setVisible() - .append(TableViewColumn()) - .append(TableViewColumn().setText("Slot").setForegroundColor({0, 128, 0}).setAlignment(1.0)) - .append(TableViewColumn().setText("Code(s)")) - .append(TableViewColumn().setText("Description").setExpandable()) - ); + cheatList.setHeadered(); + cheatList.append(TableViewColumn()); + cheatList.append(TableViewColumn().setText("Slot").setForegroundColor({0, 128, 0}).setAlignment(1.0)); + cheatList.append(TableViewColumn().setText("Code(s)")); + cheatList.append(TableViewColumn().setText("Description").setExpandable()); for(auto slot : range(Slots)) { - cheatList.append(TableViewItem() - .append(TableViewCell().setCheckable()) - .append(TableViewCell().setText(1 + slot)) - .append(TableViewCell()) - .append(TableViewCell()) - ); + TableViewItem item{&cheatList}; + item.append(TableViewCell().setCheckable()); + item.append(TableViewCell().setText(1 + slot)); + item.append(TableViewCell()); + item.append(TableViewCell()); } cheatList.onChange([&] { doChangeSelected(); }); cheatList.onToggle([&](auto cell) { diff --git a/higan/target-higan/tools/state-manager.cpp b/higan/target-higan/tools/state-manager.cpp index b5740208..8e741595 100644 --- a/higan/target-higan/tools/state-manager.cpp +++ b/higan/target-higan/tools/state-manager.cpp @@ -3,15 +3,13 @@ StateManager::StateManager(TabFrame* parent) : TabFrameItem(parent) { setText("State Manager"); layout.setPadding(5); - stateList.append(TableViewHeader().setVisible() - .append(TableViewColumn().setText("Slot").setForegroundColor({0, 128, 0}).setAlignment(1.0)) - .append(TableViewColumn().setText("Description").setExpandable()) - ); + stateList.setHeadered(); + stateList.append(TableViewColumn().setText("Slot").setForegroundColor({0, 128, 0}).setAlignment(1.0)); + stateList.append(TableViewColumn().setText("Description").setExpandable()); for(auto slot : range(Slots)) { - stateList.append(TableViewItem() - .append(TableViewCell().setText(1 + slot)) - .append(TableViewCell()) - ); + TableViewItem item{&stateList}; + item.append(TableViewCell().setText(1 + slot)); + item.append(TableViewCell()); } stateList.onActivate([&] { doLoad(); }); stateList.onChange([&] { doChangeSelected(); }); diff --git a/hiro/cocoa/application.cpp b/hiro/cocoa/application.cpp index 1878e63c..60a7b7d7 100644 --- a/hiro/cocoa/application.cpp +++ b/hiro/cocoa/application.cpp @@ -4,20 +4,20 @@ -(NSApplicationTerminateReply) applicationShouldTerminate:(NSApplication*)sender { using hiro::Application; - if(Application::state.cocoa.onQuit) Application::Cocoa::doQuit(); + if(Application::state().cocoa.onQuit) Application::Cocoa::doQuit(); else Application::quit(); return NSTerminateCancel; } -(BOOL) applicationShouldHandleReopen:(NSApplication*)application hasVisibleWindows:(BOOL)flag { using hiro::Application; - if(Application::state.cocoa.onActivate) Application::Cocoa::doActivate(); + if(Application::state().cocoa.onActivate) Application::Cocoa::doActivate(); return NO; } -(void) run:(NSTimer*)timer { using hiro::Application; - if(Application::state.onMain) Application::doMain(); + if(Application::state().onMain) Application::doMain(); } -(void) updateInDock:(NSTimer*)timer { @@ -40,7 +40,7 @@ namespace hiro { auto pApplication::run() -> void { //applicationTimer = [NSTimer scheduledTimerWithTimeInterval:0.1667 target:cocoaDelegate selector:@selector(updateInDock:) userInfo:nil repeats:YES]; - if(Application::state.onMain) { + if(Application::state().onMain) { applicationTimer = [NSTimer scheduledTimerWithTimeInterval:0.0 target:cocoaDelegate selector:@selector(run:) userInfo:nil repeats:YES]; //below line is needed to run application during window resize; however it has a large performance penalty on the resize smoothness @@ -63,7 +63,7 @@ auto pApplication::pendingEvents() -> bool { auto pApplication::processEvents() -> void { @autoreleasepool { - while(!Application::state.quit) { + while(!Application::state().quit) { NSEvent* event = [NSApp nextEventMatchingMask:NSAnyEventMask untilDate:[NSDate distantPast] inMode:NSDefaultRunLoopMode dequeue:YES]; if(event == nil) break; [event retain]; diff --git a/hiro/cocoa/object.hpp b/hiro/cocoa/object.hpp index 7f04a5af..058e6a79 100644 --- a/hiro/cocoa/object.hpp +++ b/hiro/cocoa/object.hpp @@ -2,7 +2,7 @@ namespace hiro { -struct pObject : mLock { +struct pObject : Lock { pObject(mObject& reference) : reference(reference) {} virtual ~pObject() {} auto self() const -> mObject& { return (mObject&)reference; } diff --git a/hiro/cocoa/platform.cpp b/hiro/cocoa/platform.cpp index 91090b02..6373f500 100644 --- a/hiro/cocoa/platform.cpp +++ b/hiro/cocoa/platform.cpp @@ -47,7 +47,6 @@ #include "widget/tab-frame.cpp" #include "widget/tab-frame-item.cpp" #include "widget/table-view.cpp" -#include "widget/table-view-header.cpp" #include "widget/table-view-column.cpp" #include "widget/table-view-item.cpp" #include "widget/table-view-cell.cpp" diff --git a/hiro/cocoa/platform.hpp b/hiro/cocoa/platform.hpp index a9768032..82fd234c 100644 --- a/hiro/cocoa/platform.hpp +++ b/hiro/cocoa/platform.hpp @@ -51,7 +51,6 @@ #include "widget/tab-frame.hpp" #include "widget/tab-frame-item.hpp" #include "widget/table-view.hpp" -#include "widget/table-view-header.hpp" #include "widget/table-view-column.hpp" #include "widget/table-view-item.hpp" #include "widget/table-view-cell.hpp" diff --git a/hiro/cocoa/widget/table-view-column.cpp b/hiro/cocoa/widget/table-view-column.cpp index 94fc6a5d..61e12067 100644 --- a/hiro/cocoa/widget/table-view-column.cpp +++ b/hiro/cocoa/widget/table-view-column.cpp @@ -4,7 +4,7 @@ namespace hiro { auto pTableViewColumn::construct() -> void { @autoreleasepool { - if(auto tableView = _grandparent()) { + if(auto tableView = _parent()) { [tableView->cocoaView reloadColumns]; } } @@ -12,7 +12,7 @@ auto pTableViewColumn::construct() -> void { auto pTableViewColumn::destruct() -> void { @autoreleasepool { - if(auto tableView = _grandparent()) { + if(auto tableView = _parent()) { [tableView->cocoaView reloadColumns]; } } @@ -43,20 +43,25 @@ auto pTableViewColumn::setHorizontalAlignment(double alignment) -> void { } auto pTableViewColumn::setIcon(const image& icon) -> void { + //TODO } auto pTableViewColumn::setResizable(bool resizable) -> void { } -auto pTableViewColumn::setSortable(bool sortable) -> void { +auto pTableViewColumn::setSorting(Sort sorting) -> void { + setText(state().text); } auto pTableViewColumn::setText(const string& text) -> void { @autoreleasepool { - if(auto pTableView = _grandparent()) { - NSTableColumn* tableColumn = [[pTableView->cocoaView content] tableColumnWithIdentifier:[[NSNumber numberWithInteger:self().offset()] stringValue]]; - [[tableColumn headerCell] setStringValue:[NSString stringWithUTF8STring:text]]; - [[pTableView->cocoaView headerView] setNeedsDisplay:YES]; + if(auto parent = _parent()) { + string label = text; + if(state().sorting == Sort::Ascending ) label.append(" \u25b4"); + if(state().sorting == Sort::Descending) label.append(" \u25be"); + NSTableColumn* tableColumn = [[parent->cocoaView content] tableColumnWithIdentifier:[[NSNumber numberWithInteger:self().offset()] stringValue]]; + [[tableColumn headerCell] setStringValue:[NSString stringWithUTF8STring:label]]; + [[parent->cocoaView headerView] setNeedsDisplay:YES]; } } } @@ -70,16 +75,11 @@ auto pTableViewColumn::setVisible(bool visible) -> void { auto pTableViewColumn::setWidth(signed width) -> void { } -auto pTableViewColumn::_grandparent() -> maybe { - if(auto parent = _parent()) return parent->_parent(); - return nothing; -} - -auto pTableViewColumn::_parent() -> maybe { +auto pTableViewColumn::_parent() -> maybe { if(auto parent = self().parentTableViewHeader()) { if(auto self = parent->self()) return *self; } - return nothing; + return {}; } } diff --git a/hiro/cocoa/widget/table-view-column.hpp b/hiro/cocoa/widget/table-view-column.hpp index e75045a5..16914931 100644 --- a/hiro/cocoa/widget/table-view-column.hpp +++ b/hiro/cocoa/widget/table-view-column.hpp @@ -15,14 +15,13 @@ struct pTableViewColumn : pObject { auto setHorizontalAlignment(double) -> void; auto setIcon(const image& icon) -> void; auto setResizable(bool resizable) -> void; - auto setSortable(bool sortable) -> void; + auto setSorting(Sort sorting) -> void; auto setText(const string& text) -> void; auto setVerticalAlignment(double) -> void; auto setVisible(bool visible) -> void override; auto setWidth(signed width) -> void; - auto _grandparent() -> maybe; - auto _parent() -> maybe; + auto _parent() -> maybe; }; } diff --git a/hiro/cocoa/widget/table-view-header.cpp b/hiro/cocoa/widget/table-view-header.cpp deleted file mode 100644 index 72d9e99c..00000000 --- a/hiro/cocoa/widget/table-view-header.cpp +++ /dev/null @@ -1,38 +0,0 @@ -#if defined(Hiro_TableView) - -namespace hiro { - -auto pTableViewHeader::construct() -> void { -} - -auto pTableViewHeader::destruct() -> void { -} - -auto pTableViewHeader::append(sTableViewColumn column) -> void { -} - -auto pTableViewHeader::remove(sTableViewColumn column) -> void { -} - -auto pTableViewHeader::setVisible(bool visible) -> void { - @autoreleasepool { - if(auto pTableView = _parent()) { - if(visible) { - [[pTableView->cocoaView content] setHeaderView:[[[NSTableHeaderView alloc] init] autorelease]]; - } else { - [[pTableView->cocoaView content] setHeaderView:nil]; - } - } - } -} - -auto pTableViewHeader::_parent() -> maybe { - if(auto parent = self().parentTableView()) { - if(auto self = parent->self()) return *self; - } - return nothing; -} - -} - -#endif diff --git a/hiro/cocoa/widget/table-view-header.hpp b/hiro/cocoa/widget/table-view-header.hpp deleted file mode 100644 index 7027afcb..00000000 --- a/hiro/cocoa/widget/table-view-header.hpp +++ /dev/null @@ -1,17 +0,0 @@ -#if defined(Hiro_TableView) - -namespace hiro { - -struct pTableViewHeader : pObject { - Declare(TableViewHeader, Object) - - auto append(sTableViewColumn column) -> void; - auto remove(sTableViewColumn column) -> void; - auto setVisible(bool visible) -> void override; - - auto _parent() -> maybe; -}; - -} - -#endif diff --git a/hiro/cocoa/widget/table-view.cpp b/hiro/cocoa/widget/table-view.cpp index ea81db20..b43a437c 100644 --- a/hiro/cocoa/widget/table-view.cpp +++ b/hiro/cocoa/widget/table-view.cpp @@ -267,6 +267,8 @@ auto pTableView::construct() -> void { setBordered(state().bordered); setFont(self().font(true)); setForegroundColor(state().foregroundColor); + setHeadered(state().headered); + setSortable(state().sortable); } } @@ -277,12 +279,10 @@ auto pTableView::destruct() -> void { } } -auto pTableView::append(sTableViewHeader header) -> void { +auto pTableView::append(sTableViewColumn column) -> void { @autoreleasepool { [cocoaView reloadColumns]; resizeColumns(); - - header->setVisible(header->visible()); } } @@ -292,7 +292,7 @@ auto pTableView::append(sTableViewItem item) -> void { } } -auto pTableView::remove(sTableViewHeader header) -> void { +auto pTableView::remove(sTableViewColumn column) -> void { @autoreleasepool { [cocoaView reloadColumns]; resizeColumns(); @@ -307,30 +307,28 @@ auto pTableView::remove(sTableViewItem item) -> void { auto pTableView::resizeColumns() -> void { @autoreleasepool { - if(auto& header = state().header) { - vector widths; - int minimumWidth = 0; - int expandable = 0; - for(auto column : range(header->columnCount())) { - int width = _width(column); - widths.append(width); - minimumWidth += width; - if(header->column(column).expandable()) expandable++; - } + vector widths; + int minimumWidth = 0; + int expandable = 0; + for(uint column : range(self().columnCount())) { + int width = _width(column); + widths.append(width); + minimumWidth += width; + if(state().columns[column]->expandable()) expandable++; + } - int maximumWidth = self().geometry().width() - 18; //include margin for vertical scroll bar - int expandWidth = 0; - if(expandable && maximumWidth > minimumWidth) { - expandWidth = (maximumWidth - minimumWidth) / expandable; - } + int maximumWidth = self().geometry().width() - 18; //include margin for vertical scroll bar + int expandWidth = 0; + if(expandable && maximumWidth > minimumWidth) { + expandWidth = (maximumWidth - minimumWidth) / expandable; + } - for(auto column : range(header->columnCount())) { - if(auto self = header->state.columns[column]->self()) { - int width = widths[column]; - if(self->state().expandable) width += expandWidth; - NSTableColumn* tableColumn = [[cocoaView content] tableColumnWithIdentifier:[[NSNumber numberWithInteger:column] stringValue]]; - [tableColumn setWidth:width]; - } + for(uint column : range(self().columnCount())) { + if(auto self = state().columns[column]->self()) { + int width = widths[column]; + if(self->state().expandable) width += expandWidth; + NSTableColumn* tableColumn = [[cocoaView content] tableColumnWithIdentifier:[[NSNumber numberWithInteger:column] stringValue]]; + [tableColumn setWidth:width]; } } } @@ -367,6 +365,17 @@ auto pTableView::setFont(const Font& font) -> void { auto pTableView::setForegroundColor(Color color) -> void { } +auto pTableView::setHeadered(bool headered) -> void { + @autoreleasepool { + if(headered == state().headered) return; + if(headered) { + [[pTableView->cocoaView content] setHeaderView:[[[NSTableHeaderView alloc] init] autorelease]]; + } else { + [[pTableView->cocoaView content] setHeaderView:nil]; + } + } +} + auto pTableView::_cellWidth(uint row, uint column) -> uint { uint width = 8; if(auto pTableViewItem = self().item(row)) { @@ -387,57 +396,32 @@ auto pTableView::_cellWidth(uint row, uint column) -> uint { auto pTableView::_columnWidth(uint column) -> uint { uint width = 8; - if(auto& header = state().header) { - if(auto pTableViewColumn = header->column(column)) { - if(auto& icon = pTableViewColumn->state.icon) { - width += icon.width() + 2; - } - if(auto& text = pTableViewColumn->state.text) { - width += pFont::size(pTableViewColumn->font(true), text).width(); - } + if(auto column = self().column(column)) { + if(auto& icon = column->state.icon) { + width += icon.width() + 2; + } + if(auto& text = column->state.text) { + width += pFont::size(column->font(true), text).width(); + } + if(column->state.sorting != Sort::None) { + width += 16; } } return width; } auto pTableView::_width(uint column) -> uint { - if(auto& header = state().header) { - if(auto width = header->column(column).width()) return width; - uint width = 1; - if(!header->column(column).visible()) return width; - if(header->visible()) width = max(width, _columnWidth(column)); - for(auto row : range(state().items.size())) { - width = max(width, _cellWidth(row, column)); - } - return width; + if(auto width = self().column(column).width()) return width; + uint width = 1; + if(!self().column(column).visible()) return width; + if(state().headered) width = max(width, _columnWidth(column)); + for(auto row : range(state().items.size())) { + width = max(width, _cellWidth(row, column)); } - return 1; + return width; } /* -auto pTableView::autoSizeColumns() -> void { - @autoreleasepool { - if(tableView.state.checkable) { - NSTableColumn* tableColumn = [[cocoaView content] tableColumnWithIdentifier:@"check"]; - [tableColumn setWidth:20.0]; - } - - unsigned height = [[cocoaView content] rowHeight]; - for(unsigned column = 0; column < max(1u, tableView.state.headerText.size()); column++) { - NSTableColumn* tableColumn = [[cocoaView content] tableColumnWithIdentifier:[[NSNumber numberWithInteger:column] stringValue]]; - unsigned minimumWidth = pFont::size([[tableColumn headerCell] font], tableView.state.headerText(column)).width + 4; - for(unsigned row = 0; row < tableView.state.text.size(); row++) { - unsigned width = pFont::size([cocoaView font], tableView.state.text(row)(column)).width + 2; - if(tableView.state.image(row)(height)) width += height + 2; - if(width > minimumWidth) minimumWidth = width; - } - [tableColumn setWidth:minimumWidth]; - } - - [[cocoaView content] sizeLastColumnToFit]; - } -} - auto pTableView::setSelected(bool selected) -> void { @autoreleasepool { if(selected == false) { diff --git a/hiro/cocoa/widget/table-view.hpp b/hiro/cocoa/widget/table-view.hpp index 548587e3..4c08f8df 100644 --- a/hiro/cocoa/widget/table-view.hpp +++ b/hiro/cocoa/widget/table-view.hpp @@ -46,9 +46,9 @@ namespace hiro { struct pTableView : pWidget { Declare(TableView, Widget) - auto append(sTableViewHeader header) -> void; + auto append(sTableViewColumn column) -> void; auto append(sTableViewItem item) -> void; - auto remove(sTableViewHeader header) -> void; + auto remove(sTableViewColumn column) -> void; auto remove(sTableViewItem item) -> void; auto resizeColumns() -> void; auto setAlignment(Alignment alignment) -> void; @@ -58,6 +58,8 @@ struct pTableView : pWidget { auto setEnabled(bool enabled) -> void override; auto setFont(const Font& font) -> void override; auto setForegroundColor(Color color) -> void; + auto setHeadered(bool headered) -> void; + auto setSortable(bool sortable) -> void; auto _cellWidth(uint row, uint column) -> uint; auto _columnWidth(uint column) -> uint; diff --git a/hiro/cocoa/window.cpp b/hiro/cocoa/window.cpp index 8482cf00..71a05b0a 100644 --- a/hiro/cocoa/window.cpp +++ b/hiro/cocoa/window.cpp @@ -17,7 +17,8 @@ NSBundle* bundle = [NSBundle mainBundle]; NSDictionary* dictionary = [bundle infoDictionary]; NSString* applicationName = [dictionary objectForKey:@"CFBundleDisplayName"]; - if(applicationName == nil) applicationName = [NSString stringWithUTF8String:hiro::Application::state.name]; + string hiroName = hiro::Application::state().name ? hiro::Application::state().name : string{"hiro"}; + if(applicationName == nil) applicationName = [NSString stringWithUTF8String:hiroName]; menuBar = [[NSMenu alloc] init]; diff --git a/hiro/core/application.cpp b/hiro/core/application.cpp index 8ae463ab..b3cf0716 100644 --- a/hiro/core/application.cpp +++ b/hiro/core/application.cpp @@ -1,13 +1,11 @@ #if defined(Hiro_Application) -Application::State Application::state; - auto Application::doMain() -> void { - if(state.onMain) return state.onMain(); + if(state().onMain) return state().onMain(); } auto Application::font() -> Font { - return state.font; + return state().font; } auto Application::kill() -> void { @@ -16,19 +14,19 @@ auto Application::kill() -> void { } auto Application::locale() -> Locale& { - return state.locale; + return state().locale; } auto Application::modal() -> bool { - return state.modal > 0; + return state().modal > 0; } auto Application::name() -> string { - return state.name; + return state().name; } auto Application::onMain(const function& callback) -> void { - state.onMain = callback; + state().onMain = callback; } auto Application::run() -> void { @@ -44,87 +42,93 @@ auto Application::processEvents() -> void { } auto Application::quit() -> void { - state.quit = true; + state().quit = true; return pApplication::quit(); } auto Application::scale() -> float { - return state.scale; + return state().scale; } auto Application::scale(float value) -> float { - return value * state.scale; + return value * state().scale; } auto Application::screenSaver() -> bool { - return state.screenSaver; + return state().screenSaver; } auto Application::setFont(const Font& font) -> void { - state.font = font; + state().font = font; } auto Application::setName(const string& name) -> void { - state.name = name; + state().name = name; } auto Application::setScale(float scale) -> void { - state.scale = scale; + state().scale = scale; } auto Application::setScreenSaver(bool screenSaver) -> void { - state.screenSaver = screenSaver; + state().screenSaver = screenSaver; pApplication::setScreenSaver(screenSaver); } +//this ensures Application::state is initialized prior to use +auto Application::state() -> State& { + static State state; + return state; +} + auto Application::unscale(float value) -> float { - return value * (1.0 / state.scale); + return value * (1.0 / state().scale); } //Windows //======= auto Application::Windows::doModalChange(bool modal) -> void { - if(state.windows.onModalChange) return state.windows.onModalChange(modal); + if(state().windows.onModalChange) return state().windows.onModalChange(modal); } auto Application::Windows::onModalChange(const function& callback) -> void { - state.windows.onModalChange = callback; + state().windows.onModalChange = callback; } //Cocoa //===== auto Application::Cocoa::doAbout() -> void { - if(state.cocoa.onAbout) return state.cocoa.onAbout(); + if(state().cocoa.onAbout) return state().cocoa.onAbout(); } auto Application::Cocoa::doActivate() -> void { - if(state.cocoa.onActivate) return state.cocoa.onActivate(); + if(state().cocoa.onActivate) return state().cocoa.onActivate(); } auto Application::Cocoa::doPreferences() -> void { - if(state.cocoa.onPreferences) return state.cocoa.onPreferences(); + if(state().cocoa.onPreferences) return state().cocoa.onPreferences(); } auto Application::Cocoa::doQuit() -> void { - if(state.cocoa.onQuit) return state.cocoa.onQuit(); + if(state().cocoa.onQuit) return state().cocoa.onQuit(); } auto Application::Cocoa::onAbout(const function& callback) -> void { - state.cocoa.onAbout = callback; + state().cocoa.onAbout = callback; } auto Application::Cocoa::onActivate(const function& callback) -> void { - state.cocoa.onActivate = callback; + state().cocoa.onActivate = callback; } auto Application::Cocoa::onPreferences(const function& callback) -> void { - state.cocoa.onPreferences = callback; + state().cocoa.onPreferences = callback; } auto Application::Cocoa::onQuit(const function& callback) -> void { - state.cocoa.onQuit = callback; + state().cocoa.onQuit = callback; } //Internal diff --git a/hiro/core/application.hpp b/hiro/core/application.hpp index ff1ecea9..4f87f803 100644 --- a/hiro/core/application.hpp +++ b/hiro/core/application.hpp @@ -65,7 +65,8 @@ struct Application { function onQuit; } cocoa; }; - static State state; + static auto initialize() -> void; + static auto state() -> State&; }; #endif diff --git a/hiro/core/font.hpp b/hiro/core/font.hpp index 492a5424..4d36f0d5 100644 --- a/hiro/core/font.hpp +++ b/hiro/core/font.hpp @@ -2,7 +2,7 @@ struct Font { using type = Font; - Font(const string& family = "", float size = 0); + Font(const string& family = "", float size = 0.0); explicit operator bool() const; auto operator==(const Font& source) const -> bool; @@ -15,7 +15,7 @@ struct Font { auto setBold(bool bold = true) -> type&; auto setFamily(const string& family = "") -> type&; auto setItalic(bool italic = true) -> type&; - auto setSize(float size = 0) -> type&; + auto setSize(float size = 0.0) -> type&; auto size() const -> float; auto size(const string& text) const -> Size; @@ -27,7 +27,7 @@ struct Font { //sizeof(Font) == 32 struct State { string family; //24 - float size = 8.0; //4 + float size = 0.0; //4 char bold = false; //1+ char italic = false; //1=4 } state; diff --git a/hiro/core/lock.hpp b/hiro/core/lock.hpp index fb226003..3e5dfb39 100644 --- a/hiro/core/lock.hpp +++ b/hiro/core/lock.hpp @@ -2,12 +2,10 @@ //shared functionality used for pObject on all platforms -struct mLock { +struct Lock { struct Handle { - Handle(const mLock* self) : self(self) { - if(self) { - ++self->locks; - } + Handle(const Lock* self) : self(self) { + if(self) ++self->locks; } ~Handle() { @@ -23,11 +21,11 @@ struct mLock { return false; } - const mLock* self = nullptr; + const Lock* self = nullptr; }; auto acquired() const -> bool { - return locks || Application::state.quit; + return locks || Application::state().quit; } auto acquire() const -> Handle { @@ -50,5 +48,3 @@ struct mLock { mutable int locks = 0; }; - -using Lock = mLock; diff --git a/hiro/core/window.cpp b/hiro/core/window.cpp index bd8b6882..bec629e8 100644 --- a/hiro/core/window.cpp +++ b/hiro/core/window.cpp @@ -292,10 +292,10 @@ auto mWindow::setMinimumSize(Size size) -> type& { auto mWindow::setModal(bool modal) -> type& { state.modal = modal; if(modal) { - Application::state.modal++; + Application::state().modal++; } else { - Application::state.modal--; - assert(Application::state.modal >= 0); + Application::state().modal--; + assert(Application::state().modal >= 0); } signal(setModal, modal); return *this; diff --git a/hiro/extension/browser-dialog.cpp b/hiro/extension/browser-dialog.cpp index 94082d61..7268d08c 100644 --- a/hiro/extension/browser-dialog.cpp +++ b/hiro/extension/browser-dialog.cpp @@ -228,7 +228,7 @@ auto BrowserDialogWindow::setPath(string path) -> void { if(state.action == "openFolder") continue; } if(!isMatch(content)) continue; - view.append(ListViewItem().setText(content).setIcon(isFolder ? Icon::Action::Open : Icon::Emblem::File)); + view.append(ListViewItem().setText(content).setIcon(isFolder ? (image)Icon::Action::Open : (image)Icon::Emblem::File)); } Application::processEvents(); diff --git a/hiro/extension/message-dialog.hpp b/hiro/extension/message-dialog.hpp index f9f901b1..3cbd4d64 100644 --- a/hiro/extension/message-dialog.hpp +++ b/hiro/extension/message-dialog.hpp @@ -15,7 +15,7 @@ struct MessageDialog { private: struct State { vector buttons; - vector icon; + image icon; sWindow parent; string response; string text; diff --git a/hiro/gtk/application.cpp b/hiro/gtk/application.cpp index d9c18831..bc06d0a5 100644 --- a/hiro/gtk/application.cpp +++ b/hiro/gtk/application.cpp @@ -10,7 +10,7 @@ bool pApplication::xdgScreenSaver = false; #endif auto pApplication::run() -> void { - while(!Application::state.quit) { + while(!Application::state().quit) { Application::doMain(); processEvents(); } @@ -48,7 +48,7 @@ auto pApplication::initialize() -> void { #endif //set WM_CLASS to Application::name() - auto name = Application::state.name ? Application::state.name : string{"hiro"}; + auto name = Application::state().name ? Application::state().name : string{"hiro"}; gdk_set_program_class(name); #if defined(BUILD_DEBUG) diff --git a/hiro/gtk/keyboard.cpp b/hiro/gtk/keyboard.cpp index 6c6a32c6..3be81caf 100644 --- a/hiro/gtk/keyboard.cpp +++ b/hiro/gtk/keyboard.cpp @@ -3,7 +3,7 @@ namespace hiro { auto pKeyboard::poll() -> vector { - if(Application::state.quit) return {}; + if(Application::state().quit) return {}; vector result; char state[256]; diff --git a/hiro/gtk/message-window.cpp b/hiro/gtk/message-window.cpp index 4391297a..db45e292 100644 --- a/hiro/gtk/message-window.cpp +++ b/hiro/gtk/message-window.cpp @@ -9,7 +9,7 @@ static auto Message(MessageWindow::State& state, GtkMessageType messageStyle) -> ); if(state.title) gtk_window_set_title(GTK_WINDOW(dialog), state.title); - else if(Application::state.name) gtk_window_set_title(GTK_WINDOW(dialog), Application::state.name); + else if(Application::state().name) gtk_window_set_title(GTK_WINDOW(dialog), Application::state().name); switch(state.buttons) { case MessageWindow::Buttons::Ok: diff --git a/hiro/gtk/object.hpp b/hiro/gtk/object.hpp index 7f04a5af..058e6a79 100644 --- a/hiro/gtk/object.hpp +++ b/hiro/gtk/object.hpp @@ -2,7 +2,7 @@ namespace hiro { -struct pObject : mLock { +struct pObject : Lock { pObject(mObject& reference) : reference(reference) {} virtual ~pObject() {} auto self() const -> mObject& { return (mObject&)reference; } diff --git a/hiro/gtk/widget/radio-label.cpp b/hiro/gtk/widget/radio-label.cpp index 89d6b6cd..81941513 100644 --- a/hiro/gtk/widget/radio-label.cpp +++ b/hiro/gtk/widget/radio-label.cpp @@ -14,6 +14,7 @@ auto pRadioLabel::construct() -> void { gtkToggleButton = GTK_TOGGLE_BUTTON(gtkWidget); gtkRadioButton = GTK_RADIO_BUTTON(gtkWidget); + setGroup(state().group); setText(state().text); g_signal_connect(G_OBJECT(gtkWidget), "toggled", G_CALLBACK(RadioLabel_activate), (gpointer)this); @@ -31,9 +32,8 @@ auto pRadioLabel::minimumSize() const -> Size { } auto pRadioLabel::setChecked() -> void { - lock(); + auto lock = acquire(); gtk_toggle_button_set_active(gtkToggleButton, true); - unlock(); } auto pRadioLabel::setGroup(sGroup group) -> void { @@ -42,7 +42,7 @@ auto pRadioLabel::setGroup(sGroup group) -> void { if(auto object = weak.acquire()) { if(auto radioLabel = dynamic_cast(object.data())) { if(auto self = radioLabel->self()) { - self->lock(); + auto lock = self->acquire(); gtk_radio_button_set_group(self->gtkRadioButton, nullptr); if(!gtkRadioButton) { gtkRadioButton = self->gtkRadioButton; @@ -51,7 +51,6 @@ auto pRadioLabel::setGroup(sGroup group) -> void { gtk_radio_button_set_group(self->gtkRadioButton, gtk_radio_button_get_group(*gtkRadioButton)); gtk_toggle_button_set_active(self->gtkToggleButton, radioLabel->state.checked = false); } - self->unlock(); } } } diff --git a/hiro/gtk/window.cpp b/hiro/gtk/window.cpp index 5dbd1e9a..6937b1e3 100644 --- a/hiro/gtk/window.cpp +++ b/hiro/gtk/window.cpp @@ -138,7 +138,7 @@ auto pWindow::construct() -> void { gtk_window_set_resizable(GTK_WINDOW(widget), true); //if program was given a name, try and set the window taskbar icon from one of the pixmaps folders - if(!Application::state.name); + if(!Application::state().name); else if(_setIcon({Path::user(), ".local/share/icons/"})); else if(_setIcon("/usr/local/share/pixmaps/")); else if(_setIcon("/usr/share/pixmaps/")); @@ -379,8 +379,8 @@ auto pWindow::setMinimumSize(Size size) -> void { auto pWindow::setModal(bool modal) -> void { if(modal) { gtk_window_set_modal(GTK_WINDOW(widget), true); - while(!Application::state.quit && state().modal) { - if(Application::state.onMain) { + while(!Application::state().quit && state().modal) { + if(Application::state().onMain) { Application::doMain(); } else { usleep(20 * 1000); @@ -454,13 +454,13 @@ auto pWindow::_menuTextHeight() const -> int { auto pWindow::_setIcon(const string& pathname) -> bool { string filename; - filename = {pathname, Application::state.name, ".svg"}; + filename = {pathname, Application::state().name, ".svg"}; if(file::exists(filename)) { gtk_window_set_icon_from_file(GTK_WINDOW(widget), filename, nullptr); return true; } - filename = {pathname, Application::state.name, ".png"}; + filename = {pathname, Application::state().name, ".png"}; if(file::exists(filename)) { //maximum image size GTK+ supports is 256x256; scale image down if necessary to prevent error image icon(filename); diff --git a/hiro/qt/action/menu-radio-item.cpp b/hiro/qt/action/menu-radio-item.cpp index 4d72df44..ceef6d70 100644 --- a/hiro/qt/action/menu-radio-item.cpp +++ b/hiro/qt/action/menu-radio-item.cpp @@ -23,7 +23,7 @@ auto pMenuRadioItem::construct() -> void { } auto pMenuRadioItem::destruct() -> void { -if(Application::state.quit) return; //TODO: hack +if(Application::state().quit) return; //TODO: hack delete qtMenuRadioItem; delete qtActionGroup; qtMenuRadioItem = nullptr; diff --git a/hiro/qt/action/menu.cpp b/hiro/qt/action/menu.cpp index 011da24c..fe54d706 100644 --- a/hiro/qt/action/menu.cpp +++ b/hiro/qt/action/menu.cpp @@ -23,7 +23,7 @@ auto pMenu::construct() -> void { } auto pMenu::destruct() -> void { -if(Application::state.quit) return; //TODO: hack +if(Application::state().quit) return; //TODO: hack delete qtMenu; qtMenu = nullptr; } diff --git a/hiro/qt/application.cpp b/hiro/qt/application.cpp index 84db1907..35f94727 100644 --- a/hiro/qt/application.cpp +++ b/hiro/qt/application.cpp @@ -5,8 +5,8 @@ namespace hiro { XlibDisplay* pApplication::display = nullptr; auto pApplication::run() -> void { - if(Application::state.onMain) { - while(!Application::state.quit) { + if(Application::state().onMain) { + while(!Application::state().quit) { Application::doMain(); processEvents(); } @@ -53,7 +53,7 @@ auto pApplication::initialize() -> void { display = XOpenDisplay(0); - auto name = Application::state.name ? Application::state.name : string{"hiro"}; + static auto name = Application::state().name ? Application::state().name : string{"hiro"}; //QApplication stores references to argc; //and will access them after pApplication::initialize() returns diff --git a/hiro/qt/header.hpp b/hiro/qt/header.hpp index 8a4ca2dc..c9587d9f 100644 --- a/hiro/qt/header.hpp +++ b/hiro/qt/header.hpp @@ -3,6 +3,8 @@ #if HIRO_QT==5 #include #endif +#undef foreach + #include #define XK_MISCELLANY #define XK_LATIN1 diff --git a/hiro/qt/object.hpp b/hiro/qt/object.hpp index 7f04a5af..058e6a79 100644 --- a/hiro/qt/object.hpp +++ b/hiro/qt/object.hpp @@ -2,7 +2,7 @@ namespace hiro { -struct pObject : mLock { +struct pObject : Lock { pObject(mObject& reference) : reference(reference) {} virtual ~pObject() {} auto self() const -> mObject& { return (mObject&)reference; } diff --git a/hiro/qt/platform.cpp b/hiro/qt/platform.cpp index 4448245b..b13f4b2c 100644 --- a/hiro/qt/platform.cpp +++ b/hiro/qt/platform.cpp @@ -50,7 +50,6 @@ #include "widget/tab-frame.cpp" #include "widget/tab-frame-item.cpp" #include "widget/table-view.cpp" -#include "widget/table-view-header.cpp" #include "widget/table-view-column.cpp" #include "widget/table-view-item.cpp" #include "widget/table-view-cell.cpp" diff --git a/hiro/qt/platform.hpp b/hiro/qt/platform.hpp index 4b90eb1e..8487b29a 100644 --- a/hiro/qt/platform.hpp +++ b/hiro/qt/platform.hpp @@ -52,7 +52,6 @@ #include "widget/tab-frame.hpp" #include "widget/tab-frame-item.hpp" #include "widget/table-view.hpp" -#include "widget/table-view-header.hpp" #include "widget/table-view-column.hpp" #include "widget/table-view-item.hpp" #include "widget/table-view-cell.hpp" diff --git a/hiro/qt/widget/combo-button.cpp b/hiro/qt/widget/combo-button.cpp index 771f6dea..41b76684 100644 --- a/hiro/qt/widget/combo-button.cpp +++ b/hiro/qt/widget/combo-button.cpp @@ -10,7 +10,7 @@ auto pComboButton::construct() -> void { } auto pComboButton::destruct() -> void { -if(Application::state.quit) return; //TODO: hack +if(Application::state().quit) return; //TODO: hack delete qtComboButton; qtWidget = qtComboButton = nullptr; } diff --git a/hiro/qt/widget/tab-frame.cpp b/hiro/qt/widget/tab-frame.cpp index 987fc8b8..4d301874 100644 --- a/hiro/qt/widget/tab-frame.cpp +++ b/hiro/qt/widget/tab-frame.cpp @@ -11,7 +11,7 @@ auto pTabFrame::construct() -> void { } auto pTabFrame::destruct() -> void { -if(Application::state.quit) return; //TODO: hack +if(Application::state().quit) return; //TODO: hack delete qtTabFrame; qtWidget = qtTabFrame = nullptr; } diff --git a/hiro/qt/widget/table-view-column.cpp b/hiro/qt/widget/table-view-column.cpp index 90d24ef7..4a7e88be 100644 --- a/hiro/qt/widget/table-view-column.cpp +++ b/hiro/qt/widget/table-view-column.cpp @@ -3,7 +3,18 @@ namespace hiro { auto pTableViewColumn::construct() -> void { - if(auto header = _parent()) header->_setState(); + if(auto parent = _parent()) { + auto lock = parent->acquire(); + //parent->qtTableView->setAlternatingRowColors(parent->self().columnCount() >= 2); + parent->qtTableView->setColumnCount(parent->self().columnCount()); + for(auto& column : parent->state().columns) { + if(auto delegate = column->self()) { + delegate->setIcon(delegate->state().icon); + delegate->setText(delegate->state().text); //also handles setSorting(); + delegate->_setState(); + } + } + } } auto pTableViewColumn::destruct() -> void { @@ -42,19 +53,31 @@ auto pTableViewColumn::setHorizontalAlignment(double alignment) -> void { } auto pTableViewColumn::setIcon(const image& icon) -> void { - //unsupported + if(auto parent = _parent()) { + parent->qtTableView->headerItem()->setIcon(self().offset(), CreateIcon(icon)); + } } auto pTableViewColumn::setResizable(bool resizable) -> void { _setState(); } -auto pTableViewColumn::setSortable(bool sortable) -> void { - _setState(); +auto pTableViewColumn::setSorting(Sort) -> void { + if(auto parent = _parent()) { + string label = state().text; + if(state().sorting == Sort::Ascending ) label.append(" \u25b4"); + if(state().sorting == Sort::Descending) label.append(" \u25be"); + parent->qtTableView->headerItem()->setText(self().offset(), QString::fromUtf8(label)); + } } -auto pTableViewColumn::setText(const string& text) -> void { - _setState(); +auto pTableViewColumn::setText(const string&) -> void { + if(auto parent = _parent()) { + string label = state().text; + if(state().sorting == Sort::Ascending ) label.append(" \u25b4"); + if(state().sorting == Sort::Descending) label.append(" \u25be"); + parent->qtTableView->headerItem()->setText(self().offset(), QString::fromUtf8(label)); + } } auto pTableViewColumn::setVerticalAlignment(double alignment) -> void { @@ -69,36 +92,26 @@ auto pTableViewColumn::setWidth(signed width) -> void { _setState(); } -auto pTableViewColumn::_parent() -> maybe { - if(auto parent = self().parentTableViewHeader()) { +auto pTableViewColumn::_parent() -> maybe { + if(auto parent = self().parentTableView()) { if(auto delegate = parent->self()) return *delegate; } - return nothing; + return {}; } auto pTableViewColumn::_setState() -> void { - if(auto header = _parent()) { - if(auto parent = header->_parent()) { - auto lock = parent->acquire(); - #if HIRO_QT==4 - parent->qtTableView->header()->setResizeMode(self().offset(), state().resizable ? QHeaderView::Interactive : QHeaderView::Fixed); - #elif HIRO_QT==5 - parent->qtTableView->header()->setSectionResizeMode(self().offset(), state().resizable ? QHeaderView::Interactive : QHeaderView::Fixed); - #endif - bool clickable = false; - for(auto& column : header->state().columns) clickable |= column->state.sortable; - #if HIRO_QT==4 - parent->qtTableView->header()->setClickable(clickable); - #elif HIRO_QT==5 - parent->qtTableView->header()->setSectionsClickable(clickable); - #endif - parent->qtTableView->headerItem()->setText(self().offset(), QString::fromUtf8(state().text)); - parent->qtTableView->setColumnHidden(self().offset(), !self().visible()); + if(auto parent = _parent()) { + auto lock = parent->acquire(); + #if HIRO_QT==4 + parent->qtTableView->header()->setResizeMode(self().offset(), state().resizable ? QHeaderView::Interactive : QHeaderView::Fixed); + #elif HIRO_QT==5 + parent->qtTableView->header()->setSectionResizeMode(self().offset(), state().resizable ? QHeaderView::Interactive : QHeaderView::Fixed); + #endif + parent->qtTableView->setColumnHidden(self().offset(), !self().visible()); - for(auto& item : parent->state().items) { - if(auto cell = item->cell(self().offset())) { - if(auto self = cell->self()) self->_setState(); - } + for(auto& item : parent->state().items) { + if(auto cell = item->cell(self().offset())) { + if(auto self = cell->self()) self->_setState(); } } } diff --git a/hiro/qt/widget/table-view-column.hpp b/hiro/qt/widget/table-view-column.hpp index f3933e11..0355218a 100644 --- a/hiro/qt/widget/table-view-column.hpp +++ b/hiro/qt/widget/table-view-column.hpp @@ -15,13 +15,13 @@ struct pTableViewColumn : pObject { auto setHorizontalAlignment(double alignment) -> void; auto setIcon(const image& icon) -> void; auto setResizable(bool resizable) -> void; - auto setSortable(bool sortable) -> void; + auto setSorting(Sort sorting) -> void; auto setText(const string& text) -> void; auto setVerticalAlignment(double alignment) -> void; auto setVisible(bool visible) -> void; auto setWidth(signed width) -> void; - auto _parent() -> maybe; + auto _parent() -> maybe; auto _setState() -> void; }; diff --git a/hiro/qt/widget/table-view-header.cpp b/hiro/qt/widget/table-view-header.cpp deleted file mode 100644 index b01d2ba6..00000000 --- a/hiro/qt/widget/table-view-header.cpp +++ /dev/null @@ -1,43 +0,0 @@ -#if defined(Hiro_TableView) - -namespace hiro { - -auto pTableViewHeader::construct() -> void { -} - -auto pTableViewHeader::destruct() -> void { -} - -auto pTableViewHeader::append(sTableViewColumn column) -> void { - _setState(); -} - -auto pTableViewHeader::remove(sTableViewColumn column) -> void { -} - -auto pTableViewHeader::setVisible(bool visible) -> void { - _setState(); -} - -auto pTableViewHeader::_parent() -> maybe { - if(auto parent = self().parentTableView()) { - if(auto delegate = parent->self()) return *delegate; - } - return nothing; -} - -auto pTableViewHeader::_setState() -> void { - if(auto parent = _parent()) { - auto lock = parent->acquire(); - //parent->qtTableView->setAlternatingRowColors(self().columnCount() >= 2); - parent->qtTableView->setColumnCount(self().columnCount()); - parent->qtTableView->setHeaderHidden(!self().visible()); - for(auto& column : state().columns) { - if(auto self = column->self()) self->_setState(); - } - } -} - -} - -#endif diff --git a/hiro/qt/widget/table-view-header.hpp b/hiro/qt/widget/table-view-header.hpp deleted file mode 100644 index 814f3ac8..00000000 --- a/hiro/qt/widget/table-view-header.hpp +++ /dev/null @@ -1,18 +0,0 @@ -#if defined(Hiro_TableView) - -namespace hiro { - -struct pTableViewHeader : pObject { - Declare(TableViewHeader, Object) - - auto append(sTableViewColumn column) -> void; - auto remove(sTableViewColumn column) -> void; - auto setVisible(bool visible) -> void override; - - auto _parent() -> maybe; - auto _setState() -> void; -}; - -} - -#endif diff --git a/hiro/qt/widget/table-view.cpp b/hiro/qt/widget/table-view.cpp index 59dce43d..8512a4b3 100644 --- a/hiro/qt/widget/table-view.cpp +++ b/hiro/qt/widget/table-view.cpp @@ -27,24 +27,21 @@ auto pTableView::construct() -> void { setBatchable(state().batchable); setBordered(state().bordered); setForegroundColor(state().foregroundColor); + setHeadered(state().headered); + setSortable(state().sortable); pWidget::construct(); } auto pTableView::destruct() -> void { -if(Application::state.quit) return; //TODO: hack +if(Application::state().quit) return; //TODO: hack delete qtTableViewDelegate; delete qtTableView; qtWidget = qtTableView = nullptr; qtTableViewDelegate = nullptr; } -auto pTableView::append(sTableViewHeader header) -> void { - lock(); - if(auto self = header->self()) { - self->_setState(); - } - unlock(); +auto pTableView::append(sTableViewColumn column) -> void { } auto pTableView::append(sTableViewItem item) -> void { @@ -56,44 +53,40 @@ auto pTableView::append(sTableViewItem item) -> void { unlock(); } -auto pTableView::remove(sTableViewHeader header) -> void { +auto pTableView::remove(sTableViewColumn column) -> void { } auto pTableView::remove(sTableViewItem item) -> void { } auto pTableView::resizeColumns() -> void { - lock(); + auto lock = acquire(); - if(auto& header = state().header) { - vector widths; - signed minimumWidth = 0; - signed expandable = 0; - for(auto column : range(header->columnCount())) { - signed width = _width(column); - widths.append(width); - minimumWidth += width; - if(header->column(column).expandable()) expandable++; - } - - signed maximumWidth = self().geometry().width() - 6; - if(auto scrollBar = qtTableView->verticalScrollBar()) { - if(scrollBar->isVisible()) maximumWidth -= scrollBar->geometry().width(); - } - - signed expandWidth = 0; - if(expandable && maximumWidth > minimumWidth) { - expandWidth = (maximumWidth - minimumWidth) / expandable; - } - - for(auto column : range(header->columnCount())) { - signed width = widths[column]; - if(header->column(column).expandable()) width += expandWidth; - qtTableView->setColumnWidth(column, width); - } + vector widths; + signed minimumWidth = 0; + signed expandable = 0; + for(auto column : range(self().columnCount())) { + signed width = _width(column); + widths.append(width); + minimumWidth += width; + if(self().column(column).expandable()) expandable++; } - unlock(); + signed maximumWidth = self().geometry().width() - 6; + if(auto scrollBar = qtTableView->verticalScrollBar()) { + if(scrollBar->isVisible()) maximumWidth -= scrollBar->geometry().width(); + } + + signed expandWidth = 0; + if(expandable && maximumWidth > minimumWidth) { + expandWidth = (maximumWidth - minimumWidth) / expandable; + } + + for(auto column : range(self().columnCount())) { + signed width = widths[column]; + if(self().column(column).expandable()) width += expandWidth; + qtTableView->setColumnWidth(column, width); + } } auto pTableView::setAlignment(Alignment alignment) -> void { @@ -128,40 +121,48 @@ auto pTableView::setForegroundColor(Color color) -> void { qtTableView->setAutoFillBackground((bool)color); } +auto pTableView::setHeadered(bool headered) -> void { + qtTableView->setHeaderHidden(!headered); +} + +auto pTableView::setSortable(bool sortable) -> void { + #if HIRO_QT==4 + qtTableView->header()->setClickable(sortable); + #elif HIRO_QT==5 + qtTableView->header()->setSectionsClickable(sortable); + #endif +} + //called on resize/show events auto pTableView::_onSize() -> void { //resize columns only if at least one column is expandable - if(auto& header = state().header) { - for(auto& column : header->state.columns) { - if(column->expandable()) return resizeColumns(); - } + for(auto& column : state().columns) { + if(column->expandable()) return resizeColumns(); } } auto pTableView::_width(unsigned column) -> unsigned { - if(auto& header = state().header) { - if(auto width = header->column(column).width()) return width; - unsigned width = 1; - if(!header->column(column).visible()) return width; - if(header->visible()) width = max(width, _widthOfColumn(column)); - for(auto row : range(state().items.size())) { - width = max(width, _widthOfCell(row, column)); - } - return width; + if(auto width = self().column(column).width()) return width; + unsigned width = 1; + if(!self().column(column).visible()) return width; + if(state().headered) width = max(width, _widthOfColumn(column)); + for(auto row : range(state().items.size())) { + width = max(width, _widthOfCell(row, column)); } - return 1; + return width; } auto pTableView::_widthOfColumn(unsigned _column) -> unsigned { unsigned width = 8; - if(auto& header = state().header) { - if(auto column = header->column(_column)) { - if(auto& icon = column->state.icon) { - width += icon.width() + 4; - } - if(auto& text = column->state.text) { - width += pFont::size(column->font(true), text).width(); - } + if(auto column = self().column(_column)) { + if(auto& icon = column->state.icon) { + width += icon.width() + 4; + } + if(auto& text = column->state.text) { + width += pFont::size(column->font(true), text).width(); + } + if(column->state.sorting != Sort::None) { + width += 12; } } return width; @@ -204,10 +205,8 @@ auto QtTableView::onContext() -> void { } auto QtTableView::onSort(int columnNumber) -> void { - if(auto& header = p.state().header) { - if(auto column = header->column(columnNumber)) { - if(!p.locked() && column.sortable()) p.self().doSort(column); - } + if(auto column = p.self().column(columnNumber)) { + if(!p.locked() && p.state().sortable) p.self().doSort(column); } } diff --git a/hiro/qt/widget/table-view.hpp b/hiro/qt/widget/table-view.hpp index f36f6403..ff1a9342 100644 --- a/hiro/qt/widget/table-view.hpp +++ b/hiro/qt/widget/table-view.hpp @@ -5,9 +5,9 @@ namespace hiro { struct pTableView : pWidget { Declare(TableView, Widget) - auto append(sTableViewHeader header) -> void; + auto append(sTableViewColumn header) -> void; auto append(sTableViewItem item) -> void; - auto remove(sTableViewHeader header) -> void; + auto remove(sTableViewColumn header) -> void; auto remove(sTableViewItem item) -> void; auto resizeColumns() -> void; auto setAlignment(Alignment alignment) -> void; @@ -15,6 +15,8 @@ struct pTableView : pWidget { auto setBatchable(bool batchable) -> void; auto setBordered(bool bordered) -> void; auto setForegroundColor(Color color) -> void; + auto setHeadered(bool headered) -> void; + auto setSortable(bool sortable) -> void; auto _onSize() -> void; auto _width(unsigned column) -> unsigned; diff --git a/hiro/qt/widget/text-edit.cpp b/hiro/qt/widget/text-edit.cpp index 2b6b565b..466c51aa 100644 --- a/hiro/qt/widget/text-edit.cpp +++ b/hiro/qt/widget/text-edit.cpp @@ -13,7 +13,7 @@ auto pTextEdit::construct() -> void { } auto pTextEdit::destruct() -> void { -if(Application::state.quit) return; //TODO: hack +if(Application::state().quit) return; //TODO: hack delete qtTextEdit; qtWidget = qtTextEdit = nullptr; } diff --git a/hiro/qt/window.cpp b/hiro/qt/window.cpp index 34773a5c..22e54977 100644 --- a/hiro/qt/window.cpp +++ b/hiro/qt/window.cpp @@ -7,7 +7,7 @@ auto pWindow::construct() -> void { qtWindow->setWindowTitle(" "); //if program was given a name, try and set the window taskbar icon to a matching pixmap image - if(auto name = Application::state.name) { + if(auto name = Application::state().name) { if(file::exists({Path::user(), ".local/share/icons/", name, ".png"})) { qtWindow->setWindowIcon(QIcon(QString::fromUtf8(string{Path::user(), ".local/share/icons/", name, ".png"}))); } else if(file::exists({"/usr/local/share/pixmaps/", name, ".png"})) { @@ -44,7 +44,7 @@ auto pWindow::construct() -> void { } auto pWindow::destruct() -> void { -if(Application::state.quit) return; //TODO: hack +if(Application::state().quit) return; //TODO: hack delete qtStatusBar; delete qtContainer; delete qtMenuBar; @@ -189,8 +189,8 @@ auto pWindow::setModal(bool modal) -> void { setVisible(false); qtWindow->setWindowModality(Qt::ApplicationModal); setVisible(true); - while(!Application::state.quit && state().modal) { - if(Application::state.onMain) { + while(!Application::state().quit && state().modal) { + if(Application::state().onMain) { Application::doMain(); } else { usleep(20 * 1000); @@ -217,13 +217,12 @@ auto pWindow::setTitle(const string& text) -> void { } auto pWindow::setVisible(bool visible) -> void { - lock(); + auto lock = acquire(); qtWindow->setVisible(visible); if(visible) { _updateFrameGeometry(); setGeometry(state().geometry); } - unlock(); } auto pWindow::_append(mWidget& widget) -> void { diff --git a/hiro/resource/resource.cpp b/hiro/resource/resource.cpp index fbf4cacd..9f699851 100644 --- a/hiro/resource/resource.cpp +++ b/hiro/resource/resource.cpp @@ -1,6 +1,8 @@ +#include "resource.hpp" + namespace Icon { namespace Action { -const nall::vector Add = { //size: 323 +const unsigned char Add[323] = { 137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82,0,0,0,16,0,0,0,16,8,6,0,0,0,31,243,255, 97,0,0,0,6,98,75,71,68,0,0,0,0,0,0,249,67,187,127,0,0,0,9,112,72,89,115,0,0,13,215,0, 0,13,215,1,66,40,155,120,0,0,0,7,116,73,77,69,7,214,1,11,16,0,17,148,68,120,161,0,0,0,208,73, @@ -13,7 +15,7 @@ const nall::vector Add = { //size: 323 243,217,244,107,103,140,137,170,181,79,182,21,127,155,61,84,114,75,11,139,178,119,142,0,0,0,0,73,69,78,68,174, 66,96,130, }; -const nall::vector Attach = { //size: 649 +const unsigned char Attach[649] = { 137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82,0,0,0,16,0,0,0,16,8,6,0,0,0,31,243,255, 97,0,0,0,4,115,66,73,84,8,8,8,8,124,8,100,136,0,0,0,25,116,69,88,116,83,111,102,116,119,97,114, 101,0,119,119,119,46,105,110,107,115,99,97,112,101,46,111,114,103,155,238,60,26,0,0,2,27,73,68,65,84,56,141, @@ -36,7 +38,7 @@ const nall::vector Attach = { //size: 649 106,179,62,2,12,83,155,131,52,48,11,220,5,194,1,127,176,172,4,126,1,41,32,186,81,242,76,218,213,0,0,0, 0,73,69,78,68,174,66,96,130, }; -const nall::vector Bookmark = { //size: 686 +const unsigned char Bookmark[686] = { 137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82,0,0,0,16,0,0,0,16,8,6,0,0,0,31,243,255, 97,0,0,0,6,98,75,71,68,0,255,0,255,0,255,160,189,167,147,0,0,0,9,112,72,89,115,0,0,11,19,0, 0,11,19,1,0,154,156,24,0,0,0,7,116,73,77,69,7,213,10,17,21,6,52,65,49,61,207,0,0,2,59,73, @@ -60,7 +62,7 @@ const nall::vector Bookmark = { //size: 686 221,234,14,26,128,72,36,194,78,163,215,90,127,221,211,211,211,189,147,194,104,52,218,7,240,7,70,86,184,198,50,151, 228,191,0,0,0,0,73,69,78,68,174,66,96,130, }; -const nall::vector FullScreen = { //size: 650 +const unsigned char FullScreen[650] = { 137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82,0,0,0,16,0,0,0,16,8,6,0,0,0,31,243,255, 97,0,0,0,6,98,75,71,68,0,255,0,255,0,255,160,189,167,147,0,0,0,9,112,72,89,115,0,0,11,19,0, 0,11,19,1,0,154,156,24,0,0,0,7,116,73,77,69,7,214,3,16,19,13,53,226,119,223,154,0,0,0,53,116, @@ -83,7 +85,7 @@ const nall::vector FullScreen = { //size: 650 234,217,110,100,141,226,182,80,40,220,28,142,15,157,110,102,151,243,185,252,173,21,142,211,185,159,81,219,35,189,0,0, 0,0,73,69,78,68,174,66,96,130, }; -const nall::vector Mute = { //size: 632 +const unsigned char Mute[632] = { 137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82,0,0,0,16,0,0,0,16,8,6,0,0,0,31,243,255, 97,0,0,0,4,115,66,73,84,8,8,8,8,124,8,100,136,0,0,0,25,116,69,88,116,83,111,102,116,119,97,114, 101,0,119,119,119,46,105,110,107,115,99,97,112,101,46,111,114,103,155,238,60,26,0,0,2,10,73,68,65,84,56,141, @@ -105,7 +107,7 @@ const nall::vector Mute = { //size: 632 4,13,209,40,149,189,61,154,122,123,169,236,238,82,45,149,216,5,255,92,0,192,188,82,47,66,120,122,218,151,51,227, 91,48,254,11,41,211,229,38,66,238,34,57,0,0,0,0,73,69,78,68,174,66,96,130, }; -const nall::vector New = { //size: 477 +const unsigned char New[477] = { 137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82,0,0,0,16,0,0,0,16,8,6,0,0,0,31,243,255, 97,0,0,0,6,98,75,71,68,0,252,0,233,0,79,52,215,177,13,0,0,0,9,112,72,89,115,0,0,11,19,0, 0,11,19,1,0,154,156,24,0,0,0,7,116,73,77,69,7,213,2,18,14,38,28,211,182,25,41,0,0,1,106,73, @@ -122,7 +124,7 @@ const nall::vector New = { //size: 477 123,17,134,57,120,136,124,199,193,176,165,193,217,176,29,51,169,221,177,17,114,185,28,143,129,139,227,248,67,146,36,197, 127,33,197,113,252,158,255,133,43,204,61,153,96,123,172,20,201,0,0,0,0,73,69,78,68,174,66,96,130, }; -const nall::vector Open = { //size: 672 +const unsigned char Open[672] = { 137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82,0,0,0,16,0,0,0,16,8,6,0,0,0,31,243,255, 97,0,0,0,4,115,66,73,84,8,8,8,8,124,8,100,136,0,0,0,9,112,72,89,115,0,0,13,215,0,0,13, 215,1,66,40,155,120,0,0,0,25,116,69,88,116,83,111,102,116,119,97,114,101,0,119,119,119,46,105,110,107,115,99, @@ -145,7 +147,7 @@ const nall::vector Open = { //size: 672 136,187,7,119,103,109,163,245,96,94,127,90,173,63,207,113,216,217,217,5,145,175,33,23,237,179,83,75,29,119,192,89, 94,90,251,175,195,180,188,108,100,228,222,111,248,2,75,29,117,50,217,195,0,0,0,0,73,69,78,68,174,66,96,130, }; -const nall::vector Properties = { //size: 464 +const unsigned char Properties[464] = { 137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82,0,0,0,16,0,0,0,16,8,6,0,0,0,31,243,255, 97,0,0,0,6,98,75,71,68,0,255,0,255,0,255,160,189,167,147,0,0,0,9,112,72,89,115,0,0,11,19,0, 0,11,19,1,0,154,156,24,0,0,0,7,116,73,77,69,7,213,11,4,10,21,27,198,210,43,84,0,0,1,93,73, @@ -162,7 +164,7 @@ const nall::vector Properties = { //size: 464 135,118,45,211,52,41,151,203,41,63,11,96,219,246,207,96,48,120,125,230,43,218,182,253,201,127,232,15,224,142,163,230, 109,49,155,36,0,0,0,0,73,69,78,68,174,66,96,130, }; -const nall::vector Quit = { //size: 799 +const unsigned char Quit[799] = { 137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82,0,0,0,16,0,0,0,16,8,6,0,0,0,31,243,255, 97,0,0,0,4,115,66,73,84,8,8,8,8,124,8,100,136,0,0,0,9,112,72,89,115,0,0,13,215,0,0,13, 215,1,66,40,155,120,0,0,0,25,116,69,88,116,83,111,102,116,119,97,114,101,0,119,119,119,46,105,110,107,115,99, @@ -189,7 +191,7 @@ const nall::vector Quit = { //size: 799 109,189,252,188,173,151,247,239,107,204,204,204,44,25,248,190,127,234,234,181,43,35,181,90,21,17,97,236,209,216,55,235, 252,117,57,231,8,130,224,15,32,253,31,63,61,253,93,147,0,165,101,0,0,0,0,73,69,78,68,174,66,96,130, }; -const nall::vector Refresh = { //size: 912 +const unsigned char Refresh[912] = { 137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82,0,0,0,16,0,0,0,16,8,6,0,0,0,31,243,255, 97,0,0,0,4,115,66,73,84,8,8,8,8,124,8,100,136,0,0,0,25,116,69,88,116,83,111,102,116,119,97,114, 101,0,119,119,119,46,105,110,107,115,99,97,112,101,46,111,114,103,155,238,60,26,0,0,3,34,73,68,65,84,56,141, @@ -220,7 +222,7 @@ const nall::vector Refresh = { //size: 912 3,192,123,13,134,182,87,49,111,144,82,197,13,93,155,33,194,80,213,145,135,108,203,252,219,15,247,127,46,85,118,106, 19,101,204,198,0,0,0,0,73,69,78,68,174,66,96,130, }; -const nall::vector Remove = { //size: 247 +const unsigned char Remove[247] = { 137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82,0,0,0,16,0,0,0,16,8,6,0,0,0,31,243,255, 97,0,0,0,6,98,75,71,68,0,0,0,0,0,0,249,67,187,127,0,0,0,9,112,72,89,115,0,0,13,215,0, 0,13,215,1,66,40,155,120,0,0,0,7,116,73,77,69,7,214,1,11,15,59,34,0,92,18,194,0,0,0,132,73, @@ -230,7 +232,7 @@ const nall::vector Remove = { //size: 247 20,208,125,60,239,182,71,2,51,97,130,126,16,222,139,175,9,51,56,199,209,74,28,10,154,71,94,109,62,225,248,254, 63,241,3,172,83,45,219,70,228,128,216,0,0,0,0,73,69,78,68,174,66,96,130, }; -const nall::vector Save = { //size: 911 +const unsigned char Save[911] = { 137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82,0,0,0,16,0,0,0,16,8,6,0,0,0,31,243,255, 97,0,0,0,6,98,75,71,68,0,0,0,0,0,0,249,67,187,127,0,0,0,9,112,72,89,115,0,0,11,19,0, 0,11,19,1,0,154,156,24,0,0,0,7,116,73,77,69,7,213,11,10,13,55,15,158,42,216,191,0,0,0,140,116, @@ -261,7 +263,7 @@ const nall::vector Save = { //size: 911 237,120,93,28,165,20,241,186,58,148,82,44,137,70,115,150,3,169,142,228,25,224,52,255,167,206,95,147,59,51,76,213, 34,98,109,0,0,0,0,73,69,78,68,174,66,96,130, }; -const nall::vector Search = { //size: 935 +const unsigned char Search[935] = { 137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82,0,0,0,16,0,0,0,16,8,6,0,0,0,31,243,255, 97,0,0,0,6,98,75,71,68,0,255,0,255,0,255,160,189,167,147,0,0,0,9,112,72,89,115,0,0,13,215,0, 0,13,215,1,66,40,155,120,0,0,0,7,116,73,77,69,7,213,6,29,17,18,8,200,223,108,120,0,0,3,52,73, @@ -293,7 +295,7 @@ const nall::vector Search = { //size: 935 185,206,1,0,90,91,91,91,84,205,242,195,220,238,67,248,191,122,9,59,169,102,147,104,79,162,5,0,0,0,0,73, 69,78,68,174,66,96,130, }; -const nall::vector Settings = { //size: 611 +const unsigned char Settings[611] = { 137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82,0,0,0,16,0,0,0,16,8,6,0,0,0,31,243,255, 97,0,0,0,6,98,75,71,68,0,255,0,255,0,255,160,189,167,147,0,0,0,9,112,72,89,115,0,0,11,19,0, 0,11,19,1,0,154,156,24,0,0,0,7,116,73,77,69,7,213,9,26,12,19,57,139,99,194,72,0,0,1,240,73, @@ -315,7 +317,7 @@ const nall::vector Settings = { //size: 611 210,190,66,48,146,186,4,76,56,184,219,196,59,225,55,55,226,213,246,234,188,84,188,0,0,0,0,73,69,78,68,174, 66,96,130, }; -const nall::vector Stop = { //size: 820 +const unsigned char Stop[820] = { 137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82,0,0,0,16,0,0,0,16,8,6,0,0,0,31,243,255, 97,0,0,0,6,98,75,71,68,0,255,0,255,0,255,160,189,167,147,0,0,0,9,112,72,89,115,0,0,11,19,0, 0,11,19,1,0,154,156,24,0,0,0,7,116,73,77,69,7,213,10,17,23,45,13,107,192,156,192,0,0,2,193,73, @@ -345,7 +347,7 @@ const nall::vector Stop = { //size: 820 }; } namespace Application { -const nall::vector Browser = { //size: 928 +const unsigned char Browser[928] = { 137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82,0,0,0,16,0,0,0,16,8,6,0,0,0,31,243,255, 97,0,0,0,6,98,75,71,68,0,255,0,255,0,255,160,189,167,147,0,0,0,9,112,72,89,115,0,0,11,19,0, 0,11,19,1,0,154,156,24,0,0,0,7,116,73,77,69,7,213,4,26,7,44,7,230,25,222,143,0,0,0,53,116, @@ -376,7 +378,7 @@ const nall::vector Browser = { //size: 928 59,197,235,66,151,199,31,218,194,61,250,6,198,204,23,78,156,158,213,173,192,139,232,178,15,132,80,202,239,168,78,123, 93,9,237,179,175,63,153,62,195,255,205,223,112,108,55,247,49,218,29,149,0,0,0,0,73,69,78,68,174,66,96,130, }; -const nall::vector Calculator = { //size: 686 +const unsigned char Calculator[686] = { 137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82,0,0,0,16,0,0,0,16,8,6,0,0,0,31,243,255, 97,0,0,0,6,98,75,71,68,0,0,0,0,0,0,249,67,187,127,0,0,0,9,112,72,89,115,0,0,11,19,0, 0,11,19,1,0,154,156,24,0,0,0,7,116,73,77,69,7,213,6,6,13,47,29,93,206,74,167,0,0,0,53,116, @@ -400,7 +402,7 @@ const nall::vector Calculator = { //size: 686 65,128,70,132,189,189,47,124,255,241,141,195,232,96,16,114,31,80,174,86,55,206,252,157,255,0,132,92,203,16,0,89, 204,210,0,0,0,0,73,69,78,68,174,66,96,130, }; -const nall::vector Calendar = { //size: 603 +const unsigned char Calendar[603] = { 137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82,0,0,0,16,0,0,0,16,8,6,0,0,0,31,243,255, 97,0,0,0,6,98,75,71,68,0,251,0,251,0,251,85,89,109,150,0,0,0,9,112,72,89,115,0,0,11,18,0, 0,11,18,1,210,221,126,252,0,0,0,7,116,73,77,69,7,213,6,3,15,29,43,75,94,175,19,0,0,0,62,116, @@ -421,7 +423,7 @@ const nall::vector Calendar = { //size: 603 40,20,46,128,135,135,63,108,183,91,42,149,202,139,197,225,8,12,13,124,144,219,239,155,27,224,235,253,253,239,55,255, 145,63,127,253,184,249,11,104,130,125,246,45,41,107,239,0,0,0,0,73,69,78,68,174,66,96,130, }; -const nall::vector Chat = { //size: 422 +const unsigned char Chat[422] = { 137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82,0,0,0,16,0,0,0,16,8,6,0,0,0,31,243,255, 97,0,0,0,6,98,75,71,68,0,0,0,0,0,0,249,67,187,127,0,0,0,9,112,72,89,115,0,0,13,215,0, 0,13,215,1,66,40,155,120,0,0,0,7,116,73,77,69,7,213,6,6,13,5,59,224,168,3,114,0,0,1,51,73, @@ -437,7 +439,7 @@ const nall::vector Chat = { //size: 422 165,115,93,248,243,71,0,172,22,178,122,77,213,130,72,51,210,15,141,12,145,160,100,148,198,107,0,0,0,0,73,69, 78,68,174,66,96,130, }; -const nall::vector FileManager = { //size: 378 +const unsigned char FileManager[378] = { 137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82,0,0,0,16,0,0,0,16,8,6,0,0,0,31,243,255, 97,0,0,0,6,98,75,71,68,0,0,0,0,0,0,249,67,187,127,0,0,0,9,112,72,89,115,0,0,13,215,0, 0,13,215,1,66,40,155,120,0,0,0,7,116,73,77,69,7,213,6,16,18,41,48,44,67,93,90,0,0,1,7,73, @@ -451,7 +453,7 @@ const nall::vector FileManager = { //size: 378 48,33,96,236,43,155,27,135,99,131,212,123,164,82,164,222,231,62,208,56,39,90,59,107,247,139,11,254,76,235,218,84, 7,231,146,194,8,95,134,90,101,183,231,143,210,134,0,0,0,0,73,69,78,68,174,66,96,130, }; -const nall::vector Mail = { //size: 550 +const unsigned char Mail[550] = { 137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82,0,0,0,16,0,0,0,16,8,6,0,0,0,31,243,255, 97,0,0,0,6,98,75,71,68,0,0,0,0,0,0,249,67,187,127,0,0,0,9,112,72,89,115,0,0,11,18,0, 0,11,18,1,210,221,126,252,0,0,0,7,116,73,77,69,7,213,6,6,12,23,54,231,47,101,43,0,0,1,179,73, @@ -471,7 +473,7 @@ const nall::vector Mail = { //size: 550 145,82,6,2,134,199,198,71,251,254,227,142,134,143,228,26,183,0,252,253,172,100,78,184,216,168,0,0,0,0,73,69, 78,68,174,66,96,130, }; -const nall::vector Monitor = { //size: 611 +const unsigned char Monitor[611] = { 137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82,0,0,0,16,0,0,0,16,8,6,0,0,0,31,243,255, 97,0,0,0,6,98,75,71,68,0,255,0,255,0,255,160,189,167,147,0,0,0,9,112,72,89,115,0,0,11,19,0, 0,11,19,1,0,154,156,24,0,0,0,7,116,73,77,69,7,213,10,19,17,58,52,159,194,36,103,0,0,1,240,73, @@ -493,7 +495,7 @@ const nall::vector Monitor = { //size: 611 81,95,135,73,96,122,114,242,198,246,127,227,255,230,39,112,67,0,83,217,168,244,129,0,0,0,0,73,69,78,68,174, 66,96,130, }; -const nall::vector Terminal = { //size: 668 +const unsigned char Terminal[668] = { 137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82,0,0,0,16,0,0,0,16,8,6,0,0,0,31,243,255, 97,0,0,0,6,98,75,71,68,0,255,0,255,0,255,160,189,167,147,0,0,0,9,112,72,89,115,0,0,11,19,0, 0,11,19,1,0,154,156,24,0,0,0,7,116,73,77,69,7,213,10,18,21,37,27,70,252,216,25,0,0,2,41,73, @@ -516,7 +518,7 @@ const nall::vector Terminal = { //size: 668 89,41,104,224,105,32,226,239,228,151,190,147,205,205,95,54,198,100,180,214,149,81,54,166,12,217,30,101,173,53,70,155, 216,88,59,36,34,247,254,2,215,162,130,23,152,77,245,29,0,0,0,0,73,69,78,68,174,66,96,130, }; -const nall::vector TextEditor = { //size: 574 +const unsigned char TextEditor[574] = { 137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82,0,0,0,16,0,0,0,16,8,6,0,0,0,31,243,255, 97,0,0,0,6,98,75,71,68,0,255,0,255,0,255,160,189,167,147,0,0,0,9,112,72,89,115,0,0,11,19,0, 0,11,19,1,0,154,156,24,0,0,0,7,116,73,77,69,7,213,9,22,18,55,41,59,82,2,72,0,0,1,203,73, @@ -538,7 +540,7 @@ const nall::vector TextEditor = { //size: 574 }; } namespace Device { -const nall::vector Clock = { //size: 897 +const unsigned char Clock[897] = { 137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82,0,0,0,16,0,0,0,16,8,6,0,0,0,31,243,255, 97,0,0,0,6,98,75,71,68,0,0,0,0,0,0,249,67,187,127,0,0,0,9,112,72,89,115,0,0,13,215,0, 0,13,215,1,66,40,155,120,0,0,0,7,116,73,77,69,7,213,9,15,8,58,5,128,132,46,85,0,0,3,14,73, @@ -569,7 +571,7 @@ const nall::vector Clock = { //size: 897 155,26,40,3,171,64,22,40,0,234,182,248,95,201,36,100,6,22,194,54,223,0,0,0,0,73,69,78,68,174,66,96, 130, }; -const nall::vector Display = { //size: 662 +const unsigned char Display[662] = { 137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82,0,0,0,16,0,0,0,16,8,6,0,0,0,31,243,255, 97,0,0,0,4,115,66,73,84,8,8,8,8,124,8,100,136,0,0,0,9,112,72,89,115,0,0,13,215,0,0,13, 215,1,66,40,155,120,0,0,0,25,116,69,88,116,83,111,102,116,119,97,114,101,0,119,119,119,46,105,110,107,115,99, @@ -592,7 +594,7 @@ const nall::vector Display = { //size: 662 135,191,179,49,102,164,222,172,63,109,70,205,107,214,154,51,128,22,161,248,50,240,131,197,222,110,255,158,136,196,127,190, 255,5,119,143,242,70,185,147,13,30,0,0,0,0,73,69,78,68,174,66,96,130, }; -const nall::vector Joypad = { //size: 812 +const unsigned char Joypad[812] = { 137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82,0,0,0,16,0,0,0,16,8,6,0,0,0,31,243,255, 97,0,0,0,6,98,75,71,68,0,172,0,77,0,0,52,214,215,123,0,0,0,9,112,72,89,115,0,0,11,19,0, 0,11,19,1,0,154,156,24,0,0,0,7,116,73,77,69,7,213,4,7,15,10,39,178,201,163,153,0,0,0,140,116, @@ -620,7 +622,7 @@ const nall::vector Joypad = { //size: 812 36,210,68,2,168,86,171,0,212,106,181,142,6,142,227,120,70,237,70,121,7,53,251,31,168,192,0,159,97,230,172,204, 0,0,0,0,73,69,78,68,174,66,96,130, }; -const nall::vector Keyboard = { //size: 587 +const unsigned char Keyboard[587] = { 137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82,0,0,0,16,0,0,0,16,8,6,0,0,0,31,243,255, 97,0,0,0,4,115,66,73,84,8,8,8,8,124,8,100,136,0,0,0,9,112,72,89,115,0,0,13,215,0,0,13, 215,1,66,40,155,120,0,0,0,25,116,69,88,116,83,111,102,116,119,97,114,101,0,119,119,119,46,105,110,107,115,99, @@ -641,7 +643,7 @@ const nall::vector Keyboard = { //size: 587 233,179,39,90,169,225,157,236,156,3,199,55,24,112,226,191,98,104,31,252,55,129,95,252,113,137,228,164,151,154,151,0, 0,0,0,73,69,78,68,174,66,96,130, }; -const nall::vector Microphone = { //size: 703 +const unsigned char Microphone[703] = { 137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82,0,0,0,16,0,0,0,16,8,6,0,0,0,31,243,255, 97,0,0,0,6,98,75,71,68,0,234,0,234,0,234,127,141,58,17,0,0,0,9,112,72,89,115,0,0,13,215,0, 0,13,215,1,66,40,155,120,0,0,0,7,116,73,77,69,7,213,11,3,22,42,33,208,235,186,119,0,0,2,76,73, @@ -665,7 +667,7 @@ const nall::vector Microphone = { //size: 703 18,224,0,108,255,149,178,178,189,53,221,114,177,133,220,122,14,41,20,190,121,148,194,128,167,127,170,238,95,0,34,78, 167,235,92,197,218,49,136,84,79,254,0,227,216,1,121,79,52,137,54,0,0,0,0,73,69,78,68,174,66,96,130, }; -const nall::vector Mouse = { //size: 720 +const unsigned char Mouse[720] = { 137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82,0,0,0,16,0,0,0,16,8,6,0,0,0,31,243,255, 97,0,0,0,6,98,75,71,68,0,255,0,255,0,255,160,189,167,147,0,0,0,9,112,72,89,115,0,0,11,19,0, 0,11,19,1,0,154,156,24,0,0,0,7,116,73,77,69,7,213,4,8,13,24,4,51,189,102,0,0,0,0,53,116, @@ -690,7 +692,7 @@ const nall::vector Mouse = { //size: 720 110,4,168,85,171,213,187,147,19,227,143,38,39,198,47,3,87,26,116,149,1,174,2,107,135,47,254,2,161,171,0,195, 167,31,206,166,0,0,0,0,73,69,78,68,174,66,96,130, }; -const nall::vector Network = { //size: 408 +const unsigned char Network[408] = { 137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82,0,0,0,16,0,0,0,16,8,6,0,0,0,31,243,255, 97,0,0,0,6,98,75,71,68,0,0,0,0,0,0,249,67,187,127,0,0,0,9,112,72,89,115,0,0,11,18,0, 0,11,18,1,210,221,126,252,0,0,0,7,116,73,77,69,7,214,2,16,22,3,20,11,54,9,17,0,0,1,37,73, @@ -705,7 +707,7 @@ const nall::vector Network = { //size: 408 199,235,186,214,31,127,222,182,183,118,118,139,2,172,141,245,77,194,48,204,157,76,88,129,194,0,124,223,231,191,146,101, 124,85,244,9,241,192,132,130,214,14,135,66,0,0,0,0,73,69,78,68,174,66,96,130, }; -const nall::vector Optical = { //size: 720 +const unsigned char Optical[720] = { 137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82,0,0,0,16,0,0,0,16,8,6,0,0,0,31,243,255, 97,0,0,0,6,98,75,71,68,0,0,0,0,0,0,249,67,187,127,0,0,0,9,112,72,89,115,0,0,11,19,0, 0,11,19,1,0,154,156,24,0,0,0,7,116,73,77,69,7,213,4,5,17,7,21,115,1,202,165,0,0,0,140,116, @@ -730,7 +732,7 @@ const nall::vector Optical = { //size: 720 108,110,221,190,115,107,169,16,28,123,110,89,214,221,185,213,87,125,45,34,91,27,213,205,111,217,250,63,189,144,236,196, 0,156,143,39,0,0,0,0,73,69,78,68,174,66,96,130, }; -const nall::vector Printer = { //size: 481 +const unsigned char Printer[481] = { 137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82,0,0,0,16,0,0,0,16,8,6,0,0,0,31,243,255, 97,0,0,0,6,98,75,71,68,0,255,0,255,0,255,160,189,167,147,0,0,0,9,112,72,89,115,0,0,11,17,0, 0,11,17,1,127,100,95,145,0,0,0,7,116,73,77,69,7,213,8,18,15,53,11,122,248,175,234,0,0,1,110,73, @@ -748,7 +750,7 @@ const nall::vector Printer = { //size: 481 151,1,120,188,189,187,57,253,194,111,126,252,0,186,104,203,229,25,65,188,29,0,0,0,0,73,69,78,68,174,66,96, 130, }; -const nall::vector Speaker = { //size: 592 +const unsigned char Speaker[592] = { 137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82,0,0,0,16,0,0,0,16,8,6,0,0,0,31,243,255, 97,0,0,0,4,115,66,73,84,8,8,8,8,124,8,100,136,0,0,0,25,116,69,88,116,83,111,102,116,119,97,114, 101,0,119,119,119,46,105,110,107,115,99,97,112,101,46,111,114,103,155,238,60,26,0,0,1,226,73,68,65,84,56,141, @@ -769,7 +771,7 @@ const nall::vector Speaker = { //size: 592 189,213,106,245,219,30,160,51,196,78,213,106,181,231,56,115,222,247,253,100,191,254,95,55,56,136,126,0,228,148,200,42, 201,231,90,24,0,0,0,0,73,69,78,68,174,66,96,130, }; -const nall::vector Storage = { //size: 603 +const unsigned char Storage[603] = { 137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82,0,0,0,16,0,0,0,16,8,6,0,0,0,31,243,255, 97,0,0,0,6,98,75,71,68,0,255,0,255,0,255,160,189,167,147,0,0,0,9,112,72,89,115,0,0,11,19,0, 0,11,19,1,0,154,156,24,0,0,0,7,116,73,77,69,7,213,4,5,15,53,8,235,207,124,119,0,0,0,140,116, @@ -792,7 +794,7 @@ const nall::vector Storage = { //size: 603 }; } namespace Edit { -const nall::vector Clear = { //size: 773 +const unsigned char Clear[773] = { 137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82,0,0,0,16,0,0,0,16,8,6,0,0,0,31,243,255, 97,0,0,0,4,115,66,73,84,8,8,8,8,124,8,100,136,0,0,0,25,116,69,88,116,83,111,102,116,119,97,114, 101,0,119,119,119,46,105,110,107,115,99,97,112,101,46,111,114,103,155,238,60,26,0,0,2,151,73,68,65,84,56,141, @@ -819,7 +821,7 @@ const nall::vector Clear = { //size: 773 45,83,138,62,165,16,224,154,181,156,76,56,242,120,254,220,75,126,7,67,8,40,132,18,218,0,0,0,0,73,69,78, 68,174,66,96,130, }; -const nall::vector Copy = { //size: 498 +const unsigned char Copy[498] = { 137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82,0,0,0,16,0,0,0,16,8,6,0,0,0,31,243,255, 97,0,0,0,6,98,75,71,68,0,0,0,0,0,0,249,67,187,127,0,0,0,9,112,72,89,115,0,0,11,19,0, 0,11,19,1,0,154,156,24,0,0,0,7,116,73,77,69,7,213,10,26,20,8,47,131,20,52,155,0,0,1,127,73, @@ -837,7 +839,7 @@ const nall::vector Copy = { //size: 498 221,22,167,18,177,228,28,233,21,31,30,167,179,166,105,46,121,125,172,191,42,0,40,36,98,201,29,0,248,5,66,89, 166,3,21,136,247,216,0,0,0,0,73,69,78,68,174,66,96,130, }; -const nall::vector Cut = { //size: 807 +const unsigned char Cut[807] = { 137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82,0,0,0,16,0,0,0,16,8,6,0,0,0,31,243,255, 97,0,0,0,6,98,75,71,68,0,0,0,0,0,0,249,67,187,127,0,0,0,9,112,72,89,115,0,0,11,19,0, 0,11,19,1,0,154,156,24,0,0,0,7,116,73,77,69,7,213,10,28,22,29,49,104,65,100,94,0,0,2,180,73, @@ -865,7 +867,7 @@ const nall::vector Cut = { //size: 807 55,16,200,241,135,195,26,95,36,226,83,168,84,231,173,162,232,254,13,160,243,58,7,220,52,193,60,0,0,0,0,73, 69,78,68,174,66,96,130, }; -const nall::vector Delete = { //size: 680 +const unsigned char Delete[680] = { 137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82,0,0,0,16,0,0,0,16,8,6,0,0,0,31,243,255, 97,0,0,0,6,98,75,71,68,0,141,0,142,0,139,33,244,163,126,0,0,0,9,112,72,89,115,0,0,11,19,0, 0,11,19,1,0,154,156,24,0,0,0,7,116,73,77,69,7,214,6,19,15,29,9,72,179,203,198,0,0,0,15,116, @@ -889,7 +891,7 @@ const nall::vector Delete = { //size: 680 60,73,164,146,51,68,32,16,152,185,61,159,253,206,178,220,134,9,248,9,228,204,195,8,165,247,44,101,0,0,0,0, 73,69,78,68,174,66,96,130, }; -const nall::vector Find = { //size: 617 +const unsigned char Find[617] = { 137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82,0,0,0,16,0,0,0,16,8,6,0,0,0,31,243,255, 97,0,0,0,6,98,75,71,68,0,240,0,240,0,239,52,6,103,27,0,0,0,9,112,72,89,115,0,0,11,19,0, 0,11,19,1,0,154,156,24,0,0,0,7,116,73,77,69,7,213,11,5,16,15,5,37,253,173,47,0,0,1,246,73, @@ -911,7 +913,7 @@ const nall::vector Find = { //size: 617 43,130,127,68,44,30,149,13,145,255,18,0,148,88,60,106,1,148,13,131,191,6,140,246,211,127,51,231,46,0,0,0, 0,73,69,78,68,174,66,96,130, }; -const nall::vector Paste = { //size: 561 +const unsigned char Paste[561] = { 137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82,0,0,0,16,0,0,0,16,8,6,0,0,0,31,243,255, 97,0,0,0,9,112,72,89,115,0,0,11,19,0,0,11,19,1,0,154,156,24,0,0,0,7,116,73,77,69,7,213, 10,14,0,28,21,175,226,241,24,0,0,1,208,73,68,65,84,56,203,149,147,177,107,83,81,20,198,127,247,189,52,130, @@ -931,7 +933,7 @@ const nall::vector Paste = { //size: 561 3,0,36,181,138,49,102,83,85,59,6,96,225,92,247,26,49,140,51,130,84,187,215,248,228,21,75,127,1,79,230,225, 152,120,105,196,218,0,0,0,0,73,69,78,68,174,66,96,130, }; -const nall::vector Redo = { //size: 591 +const unsigned char Redo[591] = { 137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82,0,0,0,16,0,0,0,16,8,6,0,0,0,31,243,255, 97,0,0,0,6,98,75,71,68,0,255,0,255,0,255,160,189,167,147,0,0,0,9,112,72,89,115,0,0,13,215,0, 0,13,215,1,66,40,155,120,0,0,0,7,116,73,77,69,7,214,7,26,10,39,21,63,184,237,33,0,0,1,220,73, @@ -952,7 +954,7 @@ const nall::vector Redo = { //size: 591 175,59,118,63,127,36,184,137,35,192,2,80,5,54,158,36,221,239,2,188,249,69,167,243,47,131,223,215,75,186,5,94, 207,53,222,0,0,0,0,73,69,78,68,174,66,96,130, }; -const nall::vector Replace = { //size: 776 +const unsigned char Replace[776] = { 137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82,0,0,0,16,0,0,0,16,8,6,0,0,0,31,243,255, 97,0,0,0,6,98,75,71,68,0,255,0,255,0,255,160,189,167,147,0,0,0,9,112,72,89,115,0,0,11,19,0, 0,11,19,1,0,154,156,24,0,0,0,7,116,73,77,69,7,214,1,6,22,4,3,245,118,104,130,0,0,2,149,73, @@ -979,7 +981,7 @@ const nall::vector Replace = { //size: 776 237,66,136,9,83,20,75,146,156,127,135,199,227,105,7,114,252,15,253,6,121,205,27,12,206,189,173,89,0,0,0,0, 73,69,78,68,174,66,96,130, }; -const nall::vector Undo = { //size: 650 +const unsigned char Undo[650] = { 137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82,0,0,0,16,0,0,0,16,8,6,0,0,0,31,243,255, 97,0,0,0,6,98,75,71,68,0,255,0,255,0,255,160,189,167,147,0,0,0,9,112,72,89,115,0,0,13,215,0, 0,13,215,1,66,40,155,120,0,0,0,7,116,73,77,69,7,214,7,26,10,14,0,22,35,150,33,0,0,2,23,73, @@ -1004,7 +1006,7 @@ const nall::vector Undo = { //size: 650 }; } namespace Emblem { -const nall::vector Archive = { //size: 540 +const unsigned char Archive[540] = { 137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82,0,0,0,16,0,0,0,16,8,6,0,0,0,31,243,255, 97,0,0,0,6,98,75,71,68,0,0,0,0,0,0,249,67,187,127,0,0,0,9,112,72,89,115,0,0,13,215,0, 0,13,215,1,66,40,155,120,0,0,0,7,116,73,77,69,7,213,6,16,18,24,9,181,27,210,224,0,0,1,169,73, @@ -1023,7 +1025,7 @@ const nall::vector Archive = { //size: 540 17,224,74,61,216,46,1,169,251,93,7,113,149,224,123,255,32,205,247,17,130,252,2,176,229,107,211,19,199,207,108,102, 252,95,19,189,193,255,176,111,224,210,135,204,19,41,165,180,0,0,0,0,73,69,78,68,174,66,96,130, }; -const nall::vector Audio = { //size: 688 +const unsigned char Audio[688] = { 137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82,0,0,0,16,0,0,0,16,8,6,0,0,0,31,243,255, 97,0,0,0,4,115,66,73,84,8,8,8,8,124,8,100,136,0,0,0,9,112,72,89,115,0,0,13,215,0,0,13, 215,1,66,40,155,120,0,0,0,25,116,69,88,116,83,111,102,116,119,97,114,101,0,119,119,119,46,105,110,107,115,99, @@ -1047,7 +1049,7 @@ const nall::vector Audio = { //size: 688 245,115,26,235,43,208,111,142,103,158,101,153,30,49,70,98,133,204,49,242,37,77,236,27,140,121,253,7,117,49,14,53, 175,233,38,194,0,0,0,0,73,69,78,68,174,66,96,130, }; -const nall::vector Binary = { //size: 560 +const unsigned char Binary[560] = { 137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82,0,0,0,16,0,0,0,16,8,6,0,0,0,31,243,255, 97,0,0,0,6,98,75,71,68,0,255,0,255,0,255,160,189,167,147,0,0,0,9,112,72,89,115,0,0,13,215,0, 0,13,215,1,66,40,155,120,0,0,0,7,116,73,77,69,7,213,4,22,20,7,56,114,185,172,74,0,0,1,189,73, @@ -1067,7 +1069,7 @@ const nall::vector Binary = { //size: 560 12,59,166,175,197,29,94,21,62,95,168,46,82,16,148,252,173,44,20,142,76,224,27,231,184,202,252,6,31,155,240,68, 82,120,70,77,0,0,0,0,73,69,78,68,174,66,96,130, }; -const nall::vector File = { //size: 741 +const unsigned char File[741] = { 137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82,0,0,0,16,0,0,0,16,8,6,0,0,0,31,243,255, 97,0,0,0,4,115,66,73,84,8,8,8,8,124,8,100,136,0,0,0,9,112,72,89,115,0,0,13,215,0,0,13, 215,1,66,40,155,120,0,0,0,25,116,69,88,116,83,111,102,116,119,97,114,101,0,119,119,119,46,105,110,107,115,99, @@ -1093,7 +1095,7 @@ const nall::vector File = { //size: 741 186,188,7,163,82,153,216,86,213,251,139,11,175,63,3,252,5,198,186,65,227,184,230,144,207,0,0,0,0,73,69,78, 68,174,66,96,130, }; -const nall::vector Folder = { //size: 581 +const unsigned char Folder[581] = { 137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82,0,0,0,16,0,0,0,16,8,6,0,0,0,31,243,255, 97,0,0,0,4,115,66,73,84,8,8,8,8,124,8,100,136,0,0,0,9,112,72,89,115,0,0,13,215,0,0,13, 215,1,66,40,155,120,0,0,0,25,116,69,88,116,83,111,102,116,119,97,114,101,0,119,119,119,46,105,110,107,115,99, @@ -1114,7 +1116,7 @@ const nall::vector Folder = { //size: 581 119,199,119,159,130,243,227,251,248,159,1,34,140,69,194,139,223,71,22,33,158,28,99,167,49,0,0,0,0,73,69,78, 68,174,66,96,130, }; -const nall::vector Font = { //size: 627 +const unsigned char Font[627] = { 137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82,0,0,0,16,0,0,0,16,8,6,0,0,0,31,243,255, 97,0,0,0,4,115,66,73,84,8,8,8,8,124,8,100,136,0,0,0,25,116,69,88,116,83,111,102,116,119,97,114, 101,0,119,119,119,46,105,110,107,115,99,97,112,101,46,111,114,103,155,238,60,26,0,0,2,5,73,68,65,84,56,141, @@ -1136,7 +1138,7 @@ const nall::vector Font = { //size: 627 197,24,236,163,169,186,187,162,116,119,29,105,186,119,28,7,165,148,19,0,134,110,223,185,117,243,63,191,243,181,95,46, 181,156,109,120,254,28,88,0,0,0,0,73,69,78,68,174,66,96,130, }; -const nall::vector Image = { //size: 558 +const unsigned char Image[558] = { 137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82,0,0,0,16,0,0,0,16,8,6,0,0,0,31,243,255, 97,0,0,0,6,98,75,71,68,0,255,0,255,0,255,160,189,167,147,0,0,0,9,112,72,89,115,0,0,13,215,0, 0,13,215,1,66,40,155,120,0,0,0,7,116,73,77,69,7,213,11,10,16,7,18,54,148,178,182,0,0,1,187,73, @@ -1156,7 +1158,7 @@ const nall::vector Image = { //size: 558 167,114,14,16,66,176,186,178,156,165,231,48,69,74,153,1,235,141,199,15,239,141,250,157,207,0,181,88,225,150,139,66, 18,171,0,0,0,0,73,69,78,68,174,66,96,130, }; -const nall::vector Markup = { //size: 709 +const unsigned char Markup[709] = { 137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82,0,0,0,16,0,0,0,16,8,6,0,0,0,31,243,255, 97,0,0,0,6,98,75,71,68,0,255,0,255,0,255,160,189,167,147,0,0,0,9,112,72,89,115,0,0,11,19,0, 0,11,19,1,0,154,156,24,0,0,0,7,116,73,77,69,7,213,4,22,20,19,51,203,197,162,151,0,0,2,82,73, @@ -1181,7 +1183,7 @@ const nall::vector Markup = { //size: 709 173,81,193,197,118,193,196,48,76,110,77,116,146,203,229,248,5,131,250,25,20,161,246,118,40,0,0,0,0,73,69,78, 68,174,66,96,130, }; -const nall::vector Program = { //size: 609 +const unsigned char Program[609] = { 137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82,0,0,0,16,0,0,0,16,8,6,0,0,0,31,243,255, 97,0,0,0,6,98,75,71,68,0,0,0,0,0,0,249,67,187,127,0,0,0,9,112,72,89,115,0,0,13,215,0, 0,13,215,1,66,40,155,120,0,0,0,7,116,73,77,69,7,214,1,5,14,9,17,179,225,58,161,0,0,1,238,73, @@ -1203,7 +1205,7 @@ const nall::vector Program = { //size: 609 245,153,250,129,201,122,147,215,84,249,95,226,7,144,100,183,170,35,108,244,94,0,0,0,0,73,69,78,68,174,66,96, 130, }; -const nall::vector Script = { //size: 516 +const unsigned char Script[516] = { 137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82,0,0,0,16,0,0,0,16,8,6,0,0,0,31,243,255, 97,0,0,0,6,98,75,71,68,0,236,0,236,0,236,29,35,22,54,0,0,0,9,112,72,89,115,0,0,11,19,0, 0,11,19,1,0,154,156,24,0,0,0,7,116,73,77,69,7,213,9,15,10,59,4,237,28,251,236,0,0,1,145,73, @@ -1222,7 +1224,7 @@ const nall::vector Script = { //size: 516 253,118,195,252,191,251,219,110,63,0,75,23,217,217,95,1,152,44,191,17,163,238,139,75,0,0,0,0,73,69,78,68, 174,66,96,130, }; -const nall::vector Text = { //size: 333 +const unsigned char Text[333] = { 137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82,0,0,0,16,0,0,0,16,8,6,0,0,0,31,243,255, 97,0,0,0,6,98,75,71,68,0,255,0,255,0,255,160,189,167,147,0,0,0,9,112,72,89,115,0,0,11,19,0, 0,11,19,1,0,154,156,24,0,0,0,7,116,73,77,69,7,213,4,22,20,15,56,186,96,38,66,0,0,0,218,73, @@ -1235,7 +1237,7 @@ const nall::vector Text = { //size: 333 4,33,147,221,61,200,178,140,191,40,49,198,124,54,77,115,61,146,100,140,121,227,191,244,5,84,81,95,185,252,185,63, 236,0,0,0,0,73,69,78,68,174,66,96,130, }; -const nall::vector Video = { //size: 592 +const unsigned char Video[592] = { 137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82,0,0,0,16,0,0,0,16,8,6,0,0,0,31,243,255, 97,0,0,0,6,98,75,71,68,0,255,0,255,0,255,160,189,167,147,0,0,0,9,112,72,89,115,0,0,13,215,0, 0,13,215,1,66,40,155,120,0,0,0,7,116,73,77,69,7,213,4,28,9,32,30,1,50,75,149,0,0,1,221,73, @@ -1258,7 +1260,7 @@ const nall::vector Video = { //size: 592 }; } namespace Go { -const nall::vector Down = { //size: 683 +const unsigned char Down[683] = { 137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82,0,0,0,16,0,0,0,16,8,6,0,0,0,31,243,255, 97,0,0,0,4,115,66,73,84,8,8,8,8,124,8,100,136,0,0,0,25,116,69,88,116,83,111,102,116,119,97,114, 101,0,119,119,119,46,105,110,107,115,99,97,112,101,46,111,114,103,155,238,60,26,0,0,2,61,73,68,65,84,56,141, @@ -1282,7 +1284,7 @@ const nall::vector Down = { //size: 683 230,63,95,218,104,253,191,0,0,56,124,69,189,15,0,195,55,197,217,127,245,252,2,115,74,18,42,134,104,28,203,0, 0,0,0,73,69,78,68,174,66,96,130, }; -const nall::vector Home = { //size: 606 +const unsigned char Home[606] = { 137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82,0,0,0,16,0,0,0,16,8,6,0,0,0,31,243,255, 97,0,0,0,6,98,75,71,68,0,0,0,0,0,0,249,67,187,127,0,0,0,9,112,72,89,115,0,0,13,215,0, 0,13,215,1,66,40,155,120,0,0,0,7,116,73,77,69,7,213,10,14,20,37,19,83,42,210,59,0,0,1,235,73, @@ -1303,7 +1305,7 @@ const nall::vector Home = { //size: 606 112,245,3,65,36,18,193,182,109,18,137,4,2,137,16,16,139,197,112,28,103,0,178,44,43,252,23,174,207,58,175,0, 135,225,98,245,229,139,215,119,255,0,86,248,213,163,133,187,128,26,0,0,0,0,73,69,78,68,174,66,96,130, }; -const nall::vector Left = { //size: 655 +const unsigned char Left[655] = { 137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82,0,0,0,16,0,0,0,16,8,6,0,0,0,31,243,255, 97,0,0,0,4,115,66,73,84,8,8,8,8,124,8,100,136,0,0,0,25,116,69,88,116,83,111,102,116,119,97,114, 101,0,119,119,119,46,105,110,107,115,99,97,112,101,46,111,114,103,155,238,60,26,0,0,2,33,73,68,65,84,56,141, @@ -1326,7 +1328,7 @@ const nall::vector Left = { //size: 655 203,229,138,87,90,181,6,94,182,58,82,195,182,80,50,191,156,11,120,17,212,124,229,90,239,252,23,109,243,52,116,236, 202,203,9,0,0,0,0,73,69,78,68,174,66,96,130, }; -const nall::vector Right = { //size: 676 +const unsigned char Right[676] = { 137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82,0,0,0,16,0,0,0,16,8,6,0,0,0,31,243,255, 97,0,0,0,4,115,66,73,84,8,8,8,8,124,8,100,136,0,0,0,25,116,69,88,116,83,111,102,116,119,97,114, 101,0,119,119,119,46,105,110,107,115,99,97,112,101,46,111,114,103,155,238,60,26,0,0,2,54,73,68,65,84,56,141, @@ -1350,7 +1352,7 @@ const nall::vector Right = { //size: 676 254,167,4,66,18,95,78,167,238,197,162,133,145,243,241,27,65,222,9,180,110,118,229,182,0,0,0,0,73,69,78,68, 174,66,96,130, }; -const nall::vector Up = { //size: 652 +const unsigned char Up[652] = { 137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82,0,0,0,16,0,0,0,16,8,6,0,0,0,31,243,255, 97,0,0,0,4,115,66,73,84,8,8,8,8,124,8,100,136,0,0,0,25,116,69,88,116,83,111,102,116,119,97,114, 101,0,119,119,119,46,105,110,107,115,99,97,112,101,46,111,114,103,155,238,60,26,0,0,2,30,73,68,65,84,56,141, @@ -1375,7 +1377,7 @@ const nall::vector Up = { //size: 652 }; } namespace Media { -const nall::vector Back = { //size: 770 +const unsigned char Back[770] = { 137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82,0,0,0,16,0,0,0,16,8,6,0,0,0,31,243,255, 97,0,0,0,6,98,75,71,68,0,0,0,0,0,0,249,67,187,127,0,0,0,9,112,72,89,115,0,0,11,19,0, 0,11,19,1,0,154,156,24,0,0,0,7,116,73,77,69,7,213,12,6,17,45,2,189,124,103,101,0,0,2,143,73, @@ -1402,7 +1404,7 @@ const nall::vector Back = { //size: 770 74,105,0,0,33,196,95,134,145,133,66,107,180,191,249,146,220,194,180,154,76,242,0,0,0,0,73,69,78,68,174,66, 96,130, }; -const nall::vector Eject = { //size: 628 +const unsigned char Eject[628] = { 137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82,0,0,0,16,0,0,0,16,8,6,0,0,0,31,243,255, 97,0,0,0,4,115,66,73,84,8,8,8,8,124,8,100,136,0,0,0,25,116,69,88,116,83,111,102,116,119,97,114, 101,0,119,119,119,46,105,110,107,115,99,97,112,101,46,111,114,103,155,238,60,26,0,0,2,6,73,68,65,84,56,141, @@ -1424,7 +1426,7 @@ const nall::vector Eject = { //size: 628 83,255,21,203,178,92,2,202,87,0,208,9,160,11,43,49,110,73,0,64,26,192,44,85,125,103,250,79,1,6,128,191, 20,183,247,30,217,9,206,54,0,0,0,0,73,69,78,68,174,66,96,130, }; -const nall::vector Flash = { //size: 607 +const unsigned char Flash[607] = { 137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82,0,0,0,16,0,0,0,16,8,6,0,0,0,31,243,255, 97,0,0,0,4,115,66,73,84,8,8,8,8,124,8,100,136,0,0,0,9,112,72,89,115,0,0,13,215,0,0,13, 215,1,66,40,155,120,0,0,0,25,116,69,88,116,83,111,102,116,119,97,114,101,0,119,119,119,46,105,110,107,115,99, @@ -1445,7 +1447,7 @@ const nall::vector Flash = { //size: 607 152,152,224,99,249,125,238,95,104,93,212,81,44,22,241,38,104,255,92,39,137,211,231,167,31,32,238,8,134,216,181,11, 218,28,104,2,119,23,74,243,79,254,2,78,177,239,207,22,156,213,133,0,0,0,0,73,69,78,68,174,66,96,130, }; -const nall::vector Floppy = { //size: 561 +const unsigned char Floppy[561] = { 137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82,0,0,0,16,0,0,0,16,8,6,0,0,0,31,243,255, 97,0,0,0,4,115,66,73,84,8,8,8,8,124,8,100,136,0,0,0,25,116,69,88,116,83,111,102,116,119,97,114, 101,0,119,119,119,46,105,110,107,115,99,97,112,101,46,111,114,103,155,238,60,26,0,0,1,195,73,68,65,84,56,141, @@ -1465,7 +1467,7 @@ const nall::vector Floppy = { //size: 561 183,126,243,92,252,173,110,76,76,32,48,61,7,187,177,176,35,134,192,158,191,144,139,169,27,145,240,227,15,253,243,15, 58,103,73,91,81,0,0,0,0,73,69,78,68,174,66,96,130, }; -const nall::vector Next = { //size: 771 +const unsigned char Next[771] = { 137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82,0,0,0,16,0,0,0,16,8,6,0,0,0,31,243,255, 97,0,0,0,6,98,75,71,68,0,0,0,0,0,0,249,67,187,127,0,0,0,9,112,72,89,115,0,0,11,19,0, 0,11,19,1,0,154,156,24,0,0,0,7,116,73,77,69,7,213,12,6,17,45,27,217,23,207,165,0,0,2,144,73, @@ -1492,7 +1494,7 @@ const nall::vector Next = { //size: 771 46,82,74,175,148,146,236,115,84,74,73,241,63,248,13,221,115,236,68,32,12,77,214,0,0,0,0,73,69,78,68,174, 66,96,130, }; -const nall::vector Optical = { //size: 931 +const unsigned char Optical[931] = { 137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82,0,0,0,16,0,0,0,16,8,6,0,0,0,31,243,255, 97,0,0,0,6,98,75,71,68,0,255,0,255,0,255,160,189,167,147,0,0,0,9,112,72,89,115,0,0,13,215,0, 0,13,215,1,66,40,155,120,0,0,0,7,116,73,77,69,7,213,4,1,17,53,53,42,125,41,75,0,0,3,48,73, @@ -1524,7 +1526,7 @@ const nall::vector Optical = { //size: 931 68,16,4,155,158,231,253,100,24,198,248,201,57,255,11,186,149,81,110,74,152,180,58,0,0,0,0,73,69,78,68,174, 66,96,130, }; -const nall::vector Pause = { //size: 464 +const unsigned char Pause[464] = { 137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82,0,0,0,16,0,0,0,16,8,6,0,0,0,31,243,255, 97,0,0,0,6,98,75,71,68,0,255,0,255,0,255,160,189,167,147,0,0,0,9,112,72,89,115,0,0,11,19,0, 0,11,19,1,0,154,156,24,0,0,0,7,116,73,77,69,7,213,12,6,17,32,43,74,96,129,68,0,0,1,93,73, @@ -1541,7 +1543,7 @@ const nall::vector Pause = { //size: 464 5,150,237,218,108,55,167,68,34,165,105,99,35,17,41,72,115,74,26,143,116,191,185,183,252,23,241,19,86,58,109,31, 74,23,56,251,0,0,0,0,73,69,78,68,174,66,96,130, }; -const nall::vector Play = { //size: 660 +const unsigned char Play[660] = { 137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82,0,0,0,16,0,0,0,16,8,6,0,0,0,31,243,255, 97,0,0,0,6,98,75,71,68,0,255,0,255,0,255,160,189,167,147,0,0,0,9,112,72,89,115,0,0,11,19,0, 0,11,19,1,0,154,156,24,0,0,0,7,116,73,77,69,7,213,12,6,17,36,33,206,217,173,94,0,0,2,33,73, @@ -1564,7 +1566,7 @@ const nall::vector Play = { //size: 660 53,125,66,61,57,7,48,155,138,162,80,207,81,38,162,48,0,3,192,26,195,48,214,127,215,146,136,216,131,212,249,23, 48,70,193,31,65,224,78,98,0,0,0,0,73,69,78,68,174,66,96,130, }; -const nall::vector Record = { //size: 653 +const unsigned char Record[653] = { 137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82,0,0,0,16,0,0,0,16,8,6,0,0,0,31,243,255, 97,0,0,0,4,115,66,73,84,8,8,8,8,124,8,100,136,0,0,0,25,116,69,88,116,83,111,102,116,119,97,114, 101,0,119,119,119,46,105,110,107,115,99,97,112,101,46,111,114,103,155,238,60,26,0,0,2,31,73,68,65,84,56,141, @@ -1587,7 +1589,7 @@ const nall::vector Record = { //size: 653 251,103,148,127,235,35,145,188,13,164,25,72,120,192,78,134,249,108,92,223,149,128,255,213,47,18,206,244,197,113,23,107, 46,0,0,0,0,73,69,78,68,174,66,96,130, }; -const nall::vector Rewind = { //size: 764 +const unsigned char Rewind[764] = { 137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82,0,0,0,16,0,0,0,16,8,6,0,0,0,31,243,255, 97,0,0,0,6,98,75,71,68,0,0,0,0,0,0,249,67,187,127,0,0,0,9,112,72,89,115,0,0,11,19,0, 0,11,19,1,0,154,156,24,0,0,0,7,116,73,77,69,7,213,12,6,17,39,32,146,243,206,11,0,0,2,137,73, @@ -1613,7 +1615,7 @@ const nall::vector Rewind = { //size: 764 246,131,228,119,37,112,22,23,101,2,238,5,144,81,20,87,10,0,108,219,17,0,104,0,87,255,186,77,156,115,101,13, 70,56,231,250,63,87,245,59,186,53,233,69,8,225,63,138,0,0,0,0,73,69,78,68,174,66,96,130, }; -const nall::vector Skip = { //size: 782 +const unsigned char Skip[782] = { 137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82,0,0,0,16,0,0,0,16,8,6,0,0,0,31,243,255, 97,0,0,0,6,98,75,71,68,0,0,0,0,0,0,249,67,187,127,0,0,0,9,112,72,89,115,0,0,11,19,0, 0,11,19,1,0,154,156,24,0,0,0,7,116,73,77,69,7,213,12,6,17,39,8,167,70,102,241,0,0,2,155,73, @@ -1640,7 +1642,7 @@ const nall::vector Skip = { //size: 782 108,187,224,3,192,83,144,117,81,16,54,246,124,6,74,169,151,82,74,118,225,2,254,71,126,1,54,156,22,72,126,132, 128,72,0,0,0,0,73,69,78,68,174,66,96,130, }; -const nall::vector Stop = { //size: 429 +const unsigned char Stop[429] = { 137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82,0,0,0,16,0,0,0,16,8,6,0,0,0,31,243,255, 97,0,0,0,6,98,75,71,68,0,255,0,255,0,255,160,189,167,147,0,0,0,9,112,72,89,115,0,0,11,19,0, 0,11,19,1,0,154,156,24,0,0,0,7,116,73,77,69,7,213,12,6,17,40,46,242,211,255,195,0,0,1,58,73, @@ -1658,7 +1660,7 @@ const nall::vector Stop = { //size: 429 }; } namespace Place { -const nall::vector Bookmarks = { //size: 753 +const unsigned char Bookmarks[753] = { 137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82,0,0,0,16,0,0,0,16,8,6,0,0,0,31,243,255, 97,0,0,0,6,98,75,71,68,0,255,0,255,0,255,160,189,167,147,0,0,0,9,112,72,89,115,0,0,11,19,0, 0,11,19,1,0,154,156,24,0,0,0,7,116,73,77,69,7,213,10,6,3,42,40,185,100,186,202,0,0,0,53,116, @@ -1684,7 +1686,7 @@ const nall::vector Bookmarks = { //size: 753 240,31,132,238,134,76,222,201,152,165,149,170,56,221,55,57,85,92,152,253,207,239,204,226,171,105,1,240,27,115,187,219, 217,106,190,108,255,0,0,0,0,73,69,78,68,174,66,96,130, }; -const nall::vector Desktop = { //size: 722 +const unsigned char Desktop[722] = { 137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82,0,0,0,16,0,0,0,16,8,6,0,0,0,31,243,255, 97,0,0,0,6,98,75,71,68,0,255,0,255,0,255,160,189,167,147,0,0,0,9,112,72,89,115,0,0,11,19,0, 0,11,19,1,0,154,156,24,0,0,0,7,116,73,77,69,7,213,2,23,0,42,10,182,151,62,76,0,0,2,95,73, @@ -1709,7 +1711,7 @@ const nall::vector Desktop = { //size: 722 11,59,140,241,114,146,69,17,119,228,81,211,213,211,64,255,152,52,46,55,191,168,226,111,159,137,255,93,63,1,185,254, 98,48,219,255,91,223,0,0,0,0,73,69,78,68,174,66,96,130, }; -const nall::vector Home = { //size: 679 +const unsigned char Home[679] = { 137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82,0,0,0,16,0,0,0,16,8,6,0,0,0,31,243,255, 97,0,0,0,4,115,66,73,84,8,8,8,8,124,8,100,136,0,0,0,9,112,72,89,115,0,0,13,215,0,0,13, 215,1,66,40,155,120,0,0,0,25,116,69,88,116,83,111,102,116,119,97,114,101,0,119,119,119,46,105,110,107,115,99, @@ -1733,7 +1735,7 @@ const nall::vector Home = { //size: 679 239,119,103,159,130,178,255,171,125,133,234,87,155,8,109,17,243,226,47,238,171,54,255,32,151,176,79,0,0,0,0,73, 69,78,68,174,66,96,130, }; -const nall::vector Server = { //size: 642 +const unsigned char Server[642] = { 137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82,0,0,0,16,0,0,0,16,8,6,0,0,0,31,243,255, 97,0,0,0,6,98,75,71,68,0,96,0,96,0,96,101,20,102,74,0,0,0,9,112,72,89,115,0,0,11,18,0, 0,11,18,1,210,221,126,252,0,0,0,7,116,73,77,69,7,213,5,24,13,41,13,225,69,167,57,0,0,0,62,116, @@ -1756,7 +1758,7 @@ const nall::vector Server = { //size: 642 162,75,129,231,151,151,151,31,252,63,158,1,254,0,124,80,17,254,250,115,5,147,0,0,0,0,73,69,78,68,174,66, 96,130, }; -const nall::vector Settings = { //size: 629 +const unsigned char Settings[629] = { 137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82,0,0,0,16,0,0,0,16,8,6,0,0,0,31,243,255, 97,0,0,0,6,98,75,71,68,0,255,0,255,0,255,160,189,167,147,0,0,0,9,112,72,89,115,0,0,11,19,0, 0,11,19,1,0,154,156,24,0,0,0,7,116,73,77,69,7,213,11,4,11,55,32,209,169,238,103,0,0,0,29,116, @@ -1778,7 +1780,7 @@ const nall::vector Settings = { //size: 629 223,201,193,112,13,142,84,237,187,73,212,49,51,211,25,10,187,69,39,153,230,199,79,31,78,37,241,220,127,225,255,215, 95,179,89,175,43,2,12,187,45,0,0,0,0,73,69,78,68,174,66,96,130, }; -const nall::vector Share = { //size: 697 +const unsigned char Share[697] = { 137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82,0,0,0,16,0,0,0,16,8,6,0,0,0,31,243,255, 97,0,0,0,4,115,66,73,84,8,8,8,8,124,8,100,136,0,0,0,9,112,72,89,115,0,0,13,215,0,0,13, 215,1,66,40,155,120,0,0,0,25,116,69,88,116,83,111,102,116,119,97,114,101,0,119,119,119,46,105,110,107,115,99, @@ -1804,7 +1806,7 @@ const nall::vector Share = { //size: 697 }; } namespace Prompt { -const nall::vector Error = { //size: 653 +const unsigned char Error[653] = { 137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82,0,0,0,16,0,0,0,16,8,6,0,0,0,31,243,255, 97,0,0,0,6,98,75,71,68,0,0,0,0,0,0,249,67,187,127,0,0,0,9,112,72,89,115,0,0,11,19,0, 0,11,19,1,0,154,156,24,0,0,0,7,116,73,77,69,7,213,11,10,9,50,14,147,83,180,176,0,0,2,26,73, @@ -1827,7 +1829,7 @@ const nall::vector Error = { //size: 653 182,141,233,237,69,69,112,154,77,58,245,58,95,143,142,186,206,139,183,110,227,255,172,243,79,194,71,102,30,185,88,118, 119,0,0,0,0,73,69,78,68,174,66,96,130, }; -const nall::vector Information = { //size: 863 +const unsigned char Information[863] = { 137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82,0,0,0,16,0,0,0,16,8,6,0,0,0,31,243,255, 97,0,0,0,6,98,75,71,68,0,0,0,0,0,0,249,67,187,127,0,0,0,9,112,72,89,115,0,0,11,19,0, 0,11,19,1,0,154,156,24,0,0,0,7,116,73,77,69,7,213,3,2,6,32,50,58,80,156,247,0,0,0,53,116, @@ -1856,7 +1858,7 @@ const nall::vector Information = { //size: 863 169,105,108,90,78,167,141,206,204,190,50,2,210,16,253,52,250,194,216,236,4,0,80,85,125,242,122,141,32,196,31,89, 88,88,120,157,151,23,251,40,146,233,55,86,76,54,94,124,138,29,4,0,0,0,0,73,69,78,68,174,66,96,130, }; -const nall::vector Question = { //size: 932 +const unsigned char Question[932] = { 137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82,0,0,0,16,0,0,0,16,8,6,0,0,0,31,243,255, 97,0,0,0,4,115,66,73,84,8,8,8,8,124,8,100,136,0,0,0,25,116,69,88,116,83,111,102,116,119,97,114, 101,0,119,119,119,46,105,110,107,115,99,97,112,101,46,111,114,103,155,238,60,26,0,0,3,54,73,68,65,84,56,141, @@ -1888,7 +1890,7 @@ const nall::vector Question = { //size: 932 74,5,1,164,148,93,179,179,217,136,82,234,150,56,255,7,102,247,76,148,162,219,138,97,0,0,0,0,73,69,78,68, 174,66,96,130, }; -const nall::vector Warning = { //size: 603 +const unsigned char Warning[603] = { 137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82,0,0,0,16,0,0,0,16,8,6,0,0,0,31,243,255, 97,0,0,0,6,98,75,71,68,0,255,0,255,0,255,160,189,167,147,0,0,0,9,112,72,89,115,0,0,11,19,0, 0,11,19,1,0,154,156,24,0,0,0,7,116,73,77,69,7,214,2,16,14,39,45,183,238,146,119,0,0,1,232,73, diff --git a/hiro/resource/resource.hpp b/hiro/resource/resource.hpp index 00b73dec..d25dbf40 100644 --- a/hiro/resource/resource.hpp +++ b/hiro/resource/resource.hpp @@ -1,103 +1,103 @@ namespace Icon { namespace Action { -extern const nall::vector Add; -extern const nall::vector Attach; -extern const nall::vector Bookmark; -extern const nall::vector FullScreen; -extern const nall::vector Mute; -extern const nall::vector New; -extern const nall::vector Open; -extern const nall::vector Properties; -extern const nall::vector Quit; -extern const nall::vector Refresh; -extern const nall::vector Remove; -extern const nall::vector Save; -extern const nall::vector Search; -extern const nall::vector Settings; -extern const nall::vector Stop; +extern const unsigned char Add[323]; +extern const unsigned char Attach[649]; +extern const unsigned char Bookmark[686]; +extern const unsigned char FullScreen[650]; +extern const unsigned char Mute[632]; +extern const unsigned char New[477]; +extern const unsigned char Open[672]; +extern const unsigned char Properties[464]; +extern const unsigned char Quit[799]; +extern const unsigned char Refresh[912]; +extern const unsigned char Remove[247]; +extern const unsigned char Save[911]; +extern const unsigned char Search[935]; +extern const unsigned char Settings[611]; +extern const unsigned char Stop[820]; } namespace Application { -extern const nall::vector Browser; -extern const nall::vector Calculator; -extern const nall::vector Calendar; -extern const nall::vector Chat; -extern const nall::vector FileManager; -extern const nall::vector Mail; -extern const nall::vector Monitor; -extern const nall::vector Terminal; -extern const nall::vector TextEditor; +extern const unsigned char Browser[928]; +extern const unsigned char Calculator[686]; +extern const unsigned char Calendar[603]; +extern const unsigned char Chat[422]; +extern const unsigned char FileManager[378]; +extern const unsigned char Mail[550]; +extern const unsigned char Monitor[611]; +extern const unsigned char Terminal[668]; +extern const unsigned char TextEditor[574]; } namespace Device { -extern const nall::vector Clock; -extern const nall::vector Display; -extern const nall::vector Joypad; -extern const nall::vector Keyboard; -extern const nall::vector Microphone; -extern const nall::vector Mouse; -extern const nall::vector Network; -extern const nall::vector Optical; -extern const nall::vector Printer; -extern const nall::vector Speaker; -extern const nall::vector Storage; +extern const unsigned char Clock[897]; +extern const unsigned char Display[662]; +extern const unsigned char Joypad[812]; +extern const unsigned char Keyboard[587]; +extern const unsigned char Microphone[703]; +extern const unsigned char Mouse[720]; +extern const unsigned char Network[408]; +extern const unsigned char Optical[720]; +extern const unsigned char Printer[481]; +extern const unsigned char Speaker[592]; +extern const unsigned char Storage[603]; } namespace Edit { -extern const nall::vector Clear; -extern const nall::vector Copy; -extern const nall::vector Cut; -extern const nall::vector Delete; -extern const nall::vector Find; -extern const nall::vector Paste; -extern const nall::vector Redo; -extern const nall::vector Replace; -extern const nall::vector Undo; +extern const unsigned char Clear[773]; +extern const unsigned char Copy[498]; +extern const unsigned char Cut[807]; +extern const unsigned char Delete[680]; +extern const unsigned char Find[617]; +extern const unsigned char Paste[561]; +extern const unsigned char Redo[591]; +extern const unsigned char Replace[776]; +extern const unsigned char Undo[650]; } namespace Emblem { -extern const nall::vector Archive; -extern const nall::vector Audio; -extern const nall::vector Binary; -extern const nall::vector File; -extern const nall::vector Folder; -extern const nall::vector Font; -extern const nall::vector Image; -extern const nall::vector Markup; -extern const nall::vector Program; -extern const nall::vector Script; -extern const nall::vector Text; -extern const nall::vector Video; +extern const unsigned char Archive[540]; +extern const unsigned char Audio[688]; +extern const unsigned char Binary[560]; +extern const unsigned char File[741]; +extern const unsigned char Folder[581]; +extern const unsigned char Font[627]; +extern const unsigned char Image[558]; +extern const unsigned char Markup[709]; +extern const unsigned char Program[609]; +extern const unsigned char Script[516]; +extern const unsigned char Text[333]; +extern const unsigned char Video[592]; } namespace Go { -extern const nall::vector Down; -extern const nall::vector Home; -extern const nall::vector Left; -extern const nall::vector Right; -extern const nall::vector Up; +extern const unsigned char Down[683]; +extern const unsigned char Home[606]; +extern const unsigned char Left[655]; +extern const unsigned char Right[676]; +extern const unsigned char Up[652]; } namespace Media { -extern const nall::vector Back; -extern const nall::vector Eject; -extern const nall::vector Flash; -extern const nall::vector Floppy; -extern const nall::vector Next; -extern const nall::vector Optical; -extern const nall::vector Pause; -extern const nall::vector Play; -extern const nall::vector Record; -extern const nall::vector Rewind; -extern const nall::vector Skip; -extern const nall::vector Stop; +extern const unsigned char Back[770]; +extern const unsigned char Eject[628]; +extern const unsigned char Flash[607]; +extern const unsigned char Floppy[561]; +extern const unsigned char Next[771]; +extern const unsigned char Optical[931]; +extern const unsigned char Pause[464]; +extern const unsigned char Play[660]; +extern const unsigned char Record[653]; +extern const unsigned char Rewind[764]; +extern const unsigned char Skip[782]; +extern const unsigned char Stop[429]; } namespace Place { -extern const nall::vector Bookmarks; -extern const nall::vector Desktop; -extern const nall::vector Home; -extern const nall::vector Server; -extern const nall::vector Settings; -extern const nall::vector Share; +extern const unsigned char Bookmarks[753]; +extern const unsigned char Desktop[722]; +extern const unsigned char Home[679]; +extern const unsigned char Server[642]; +extern const unsigned char Settings[629]; +extern const unsigned char Share[697]; } namespace Prompt { -extern const nall::vector Error; -extern const nall::vector Information; -extern const nall::vector Question; -extern const nall::vector Warning; +extern const unsigned char Error[653]; +extern const unsigned char Information[863]; +extern const unsigned char Question[932]; +extern const unsigned char Warning[603]; } } diff --git a/hiro/windows/application.cpp b/hiro/windows/application.cpp index 9b6610e0..8078b79d 100644 --- a/hiro/windows/application.cpp +++ b/hiro/windows/application.cpp @@ -8,8 +8,8 @@ static auto CALLBACK Application_windowProc(HWND, UINT, WPARAM, LPARAM) -> LRESU auto pApplication::run() -> void { MSG msg; - if(Application::state.onMain) { - while(!Application::state.quit) { + if(Application::state().onMain) { + while(!Application::state().quit) { Application::doMain(); processEvents(); } @@ -243,7 +243,7 @@ case WM_GETMINMAXINFO: { */ static auto CALLBACK Application_windowProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) -> LRESULT { - if(Application::state.quit) return DefWindowProc(hwnd, msg, wparam, lparam); + if(Application::state().quit) return DefWindowProc(hwnd, msg, wparam, lparam); auto object = (mObject*)GetWindowLongPtr(hwnd, GWLP_USERDATA); if(!object) return DefWindowProc(hwnd, msg, wparam, lparam); diff --git a/hiro/windows/object.hpp b/hiro/windows/object.hpp index 470ef8ea..8eac13a6 100644 --- a/hiro/windows/object.hpp +++ b/hiro/windows/object.hpp @@ -2,7 +2,7 @@ namespace hiro { -struct pObject : mLock { +struct pObject : Lock { pObject(mObject& reference) : reference(reference) {} virtual ~pObject() = default; virtual auto construct() -> void; diff --git a/hiro/windows/platform.cpp b/hiro/windows/platform.cpp index be079a6a..466fa247 100644 --- a/hiro/windows/platform.cpp +++ b/hiro/windows/platform.cpp @@ -41,7 +41,6 @@ #include "widget/label.cpp" #include "widget/line-edit.cpp" #include "widget/table-view.cpp" -#include "widget/table-view-header.cpp" #include "widget/table-view-column.cpp" #include "widget/table-view-item.cpp" #include "widget/table-view-cell.cpp" diff --git a/hiro/windows/platform.hpp b/hiro/windows/platform.hpp index e52a78a8..6db6f485 100644 --- a/hiro/windows/platform.hpp +++ b/hiro/windows/platform.hpp @@ -68,7 +68,6 @@ static vector windows; #include "widget/tab-frame.hpp" #include "widget/tab-frame-item.hpp" #include "widget/table-view.hpp" -#include "widget/table-view-header.hpp" #include "widget/table-view-column.hpp" #include "widget/table-view-item.hpp" #include "widget/table-view-cell.hpp" diff --git a/hiro/windows/utility.cpp b/hiro/windows/utility.cpp index d6d383b9..97c95786 100644 --- a/hiro/windows/utility.cpp +++ b/hiro/windows/utility.cpp @@ -148,7 +148,7 @@ static auto CALLBACK Menu_windowProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM } static auto CALLBACK Shared_windowProc(WindowProc windowProc, HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) -> LRESULT { - if(Application::state.quit) return DefWindowProc(hwnd, msg, wparam, lparam); + if(Application::state().quit) return DefWindowProc(hwnd, msg, wparam, lparam); auto object = (mObject*)GetWindowLongPtr(hwnd, GWLP_USERDATA); if(!object) return DefWindowProc(hwnd, msg, wparam, lparam); diff --git a/hiro/windows/widget/line-edit.cpp b/hiro/windows/widget/line-edit.cpp index 7b663b7f..21226fa8 100644 --- a/hiro/windows/widget/line-edit.cpp +++ b/hiro/windows/widget/line-edit.cpp @@ -36,12 +36,12 @@ auto pLineEdit::setEditable(bool editable) -> void { } auto pLineEdit::setForegroundColor(Color color) -> void { + InvalidateRect(hwnd, 0, true); } auto pLineEdit::setText(const string& text) -> void { - lock(); + auto lock = acquire(); SetWindowText(hwnd, utf16_t(text)); - unlock(); } auto pLineEdit::onChange() -> void { diff --git a/hiro/windows/widget/table-view-column.cpp b/hiro/windows/widget/table-view-column.cpp index 76fb61d3..e984c6fa 100644 --- a/hiro/windows/widget/table-view-column.cpp +++ b/hiro/windows/widget/table-view-column.cpp @@ -3,25 +3,23 @@ namespace hiro { auto pTableViewColumn::construct() -> void { - if(auto grandparent = _grandparent()) { - grandparent->lock(); + if(auto parent = _parent()) { + auto lock = parent->acquire(); wchar_t text[] = L""; LVCOLUMN lvColumn{0}; lvColumn.mask = LVCF_FMT | LVCF_TEXT | LVCF_SUBITEM; lvColumn.fmt = LVCFMT_LEFT; lvColumn.iSubItem = self().offset(); lvColumn.pszText = text; - ListView_InsertColumn(grandparent->hwnd, self().offset(), &lvColumn); + ListView_InsertColumn(parent->hwnd, self().offset(), &lvColumn); _setState(); - grandparent->unlock(); } } auto pTableViewColumn::destruct() -> void { - if(auto grandparent = _grandparent()) { - grandparent->lock(); - ListView_DeleteColumn(grandparent->hwnd, self().offset()); - grandparent->unlock(); + if(auto parent = _parent()) { + auto lock = parent->acquire(); + ListView_DeleteColumn(parent->hwnd, self().offset()); } } @@ -57,7 +55,8 @@ auto pTableViewColumn::setResizable(bool resizable) -> void { _setState(); } -auto pTableViewColumn::setSortable(bool sortable) -> void { +auto pTableViewColumn::setSorting(Sort sorting) -> void { + _setState(); } auto pTableViewColumn::setText(const string& text) -> void { @@ -71,36 +70,33 @@ auto pTableViewColumn::setWidth(signed width) -> void { _setState(); } -auto pTableViewColumn::_grandparent() -> maybe { - if(auto parent = _parent()) return parent->_parent(); - return nothing; -} - -auto pTableViewColumn::_parent() -> maybe { - if(auto parent = self().parentTableViewHeader()) { +auto pTableViewColumn::_parent() -> maybe { + if(auto parent = self().parentTableView()) { if(auto self = parent->self()) return *self; } - return nothing; + return {}; } auto pTableViewColumn::_setState() -> void { - if(auto grandparent = _grandparent()) { - grandparent->lock(); - grandparent->_setIcons(); - utf16_t text(state().text); + if(auto parent = _parent()) { + auto lock = parent->acquire(); + parent->_setIcons(); + string text = state().text; + if(state().sorting == Sort::Ascending ) text.append(" ^"); + if(state().sorting == Sort::Descending) text.append(" v"); + utf16_t wtext(text); LVCOLUMN lvColumn; lvColumn.mask = LVCF_FMT | LVCF_SUBITEM | LVCF_TEXT | LVCF_WIDTH; lvColumn.fmt = LVCFMT_CENTER; lvColumn.iSubItem = self().offset(); lvColumn.iImage = self().offset(); - lvColumn.pszText = text; + lvColumn.pszText = wtext; lvColumn.cx = _width; if(state().horizontalAlignment < 0.333) lvColumn.fmt = LVCFMT_LEFT; if(state().horizontalAlignment > 0.666) lvColumn.fmt = LVCFMT_RIGHT; if(state().icon) lvColumn.mask |= LVCF_IMAGE; if(!state().resizable) lvColumn.fmt |= LVCFMT_FIXED_WIDTH; - ListView_SetColumn(grandparent->hwnd, self().offset(), &lvColumn); - grandparent->unlock(); + ListView_SetColumn(parent->hwnd, self().offset(), &lvColumn); } } diff --git a/hiro/windows/widget/table-view-column.hpp b/hiro/windows/widget/table-view-column.hpp index 91c503f7..9d13d0d3 100644 --- a/hiro/windows/widget/table-view-column.hpp +++ b/hiro/windows/widget/table-view-column.hpp @@ -14,13 +14,12 @@ struct pTableViewColumn : pObject { auto setHorizontalAlignment(double alignment) -> void; auto setIcon(const image& icon) -> void; auto setResizable(bool resizable) -> void; - auto setSortable(bool sortable) -> void; + auto setSorting(Sort sorting) -> void; auto setText(const string& text) -> void; auto setVerticalAlignment(double alignment) -> void; auto setWidth(signed width) -> void; - auto _grandparent() -> maybe; - auto _parent() -> maybe; + auto _parent() -> maybe; auto _setState() -> void; signed _width = 128; //computed width (via TableView::resizeColumns) diff --git a/hiro/windows/widget/table-view-header.cpp b/hiro/windows/widget/table-view-header.cpp deleted file mode 100644 index 71f02a47..00000000 --- a/hiro/windows/widget/table-view-header.cpp +++ /dev/null @@ -1,42 +0,0 @@ -#if defined(Hiro_TableView) - -namespace hiro { - -auto pTableViewHeader::construct() -> void { - _setState(); -} - -auto pTableViewHeader::destruct() -> void { -} - -auto pTableViewHeader::append(sTableViewColumn column) -> void { -} - -auto pTableViewHeader::remove(sTableViewColumn column) -> void { -} - -auto pTableViewHeader::setVisible(bool visible) -> void { - _setState(); -} - -auto pTableViewHeader::_parent() -> maybe { - if(auto parent = self().parentTableView()) { - if(auto self = parent->self()) return *self; - } - return nothing; -} - -auto pTableViewHeader::_setState() -> void { - if(auto parent = _parent()) { - auto style = GetWindowLong(parent->hwnd, GWL_STYLE); - self().visible() ? style &=~ LVS_NOCOLUMNHEADER : style |= LVS_NOCOLUMNHEADER; - SetWindowLong(parent->hwnd, GWL_STYLE, style); - for(auto& column : state().columns) { - if(auto self = column->self()) self->_setState(); - } - } -} - -} - -#endif diff --git a/hiro/windows/widget/table-view-header.hpp b/hiro/windows/widget/table-view-header.hpp deleted file mode 100644 index 814f3ac8..00000000 --- a/hiro/windows/widget/table-view-header.hpp +++ /dev/null @@ -1,18 +0,0 @@ -#if defined(Hiro_TableView) - -namespace hiro { - -struct pTableViewHeader : pObject { - Declare(TableViewHeader, Object) - - auto append(sTableViewColumn column) -> void; - auto remove(sTableViewColumn column) -> void; - auto setVisible(bool visible) -> void override; - - auto _parent() -> maybe; - auto _setState() -> void; -}; - -} - -#endif diff --git a/hiro/windows/widget/table-view.cpp b/hiro/windows/widget/table-view.cpp index cd6f94d9..5feb4e8d 100644 --- a/hiro/windows/widget/table-view.cpp +++ b/hiro/windows/widget/table-view.cpp @@ -35,8 +35,9 @@ auto pTableView::construct() -> void { setBackgroundColor(state().backgroundColor); setBatchable(state().batchable); setBordered(state().bordered); + setHeadered(state().headered); + setSortable(state().sortable); _setIcons(); - _setSortable(); resizeColumns(); } @@ -45,61 +46,53 @@ auto pTableView::destruct() -> void { DestroyWindow(hwnd); } -auto pTableView::append(sTableViewHeader header) -> void { +auto pTableView::append(sTableViewColumn column) -> void { resizeColumns(); } auto pTableView::append(sTableViewItem item) -> void { } -auto pTableView::remove(sTableViewHeader header) -> void { - LVCOLUMN lvColumn{LVCF_WIDTH}; - while(ListView_GetColumn(hwnd, 0, &lvColumn)) { - ListView_DeleteColumn(hwnd, 0); - } +auto pTableView::remove(sTableViewColumn column) -> void { } auto pTableView::remove(sTableViewItem item) -> void { } auto pTableView::resizeColumns() -> void { - lock(); + auto lock = acquire(); - if(auto& header = state().header) { - vector widths; - signed minimumWidth = 0; - signed expandable = 0; - for(auto column : range(header->columnCount())) { - signed width = _width(column); - widths.append(width); - minimumWidth += width; - if(header->column(column).expandable()) expandable++; - } + vector widths; + signed minimumWidth = 0; + signed expandable = 0; + for(auto column : range(self().columnCount())) { + signed width = _width(column); + widths.append(width); + minimumWidth += width; + if(state().columns[column]->expandable()) expandable++; + } - signed maximumWidth = self().geometry().width() - 4; - SCROLLBARINFO sbInfo{sizeof(SCROLLBARINFO)}; - if(GetScrollBarInfo(hwnd, OBJID_VSCROLL, &sbInfo)) { - if(!(sbInfo.rgstate[0] & STATE_SYSTEM_INVISIBLE)) { - maximumWidth -= sbInfo.rcScrollBar.right - sbInfo.rcScrollBar.left; - } - } - - signed expandWidth = 0; - if(expandable && maximumWidth > minimumWidth) { - expandWidth = (maximumWidth - minimumWidth) / expandable; - } - - for(auto column : range(header->columnCount())) { - if(auto self = header->state.columns[column]->self()) { - signed width = widths[column]; - if(self->state().expandable) width += expandWidth; - self->_width = width; - self->_setState(); - } + signed maximumWidth = self().geometry().width() - 4; + SCROLLBARINFO sbInfo{sizeof(SCROLLBARINFO)}; + if(GetScrollBarInfo(hwnd, OBJID_VSCROLL, &sbInfo)) { + if(!(sbInfo.rgstate[0] & STATE_SYSTEM_INVISIBLE)) { + maximumWidth -= sbInfo.rcScrollBar.right - sbInfo.rcScrollBar.left; } } - unlock(); + signed expandWidth = 0; + if(expandable && maximumWidth > minimumWidth) { + expandWidth = (maximumWidth - minimumWidth) / expandable; + } + + for(auto column : range(self().columnCount())) { + if(auto self = state().columns[column]->self()) { + signed width = widths[column]; + if(self->state().expandable) width += expandWidth; + self->_width = width; + self->_setState(); + } + } } auto pTableView::setAlignment(Alignment alignment) -> void { @@ -125,10 +118,8 @@ auto pTableView::setForegroundColor(Color color) -> void { auto pTableView::setGeometry(Geometry geometry) -> void { pWidget::setGeometry(geometry); - if(auto& header = state().header) { - for(auto& column : header->state.columns) { - if(column->state.expandable) return resizeColumns(); - } + for(auto& column : state().columns) { + if(column->state.expandable) return resizeColumns(); } } @@ -179,9 +170,7 @@ auto pTableView::onCustomDraw(LPARAM lparam) -> LRESULT { HDC hdc = lvcd->nmcd.hdc; HDC hdcSource = CreateCompatibleDC(hdc); unsigned row = lvcd->nmcd.dwItemSpec; - auto& header = state().header; - if(!header) break; - for(auto column : range(header->columnCount())) { + for(auto column : range(self().columnCount())) { RECT rc, rcLabel; ListView_GetSubItemRect(hwnd, row, column, LVIR_BOUNDS, &rc); ListView_GetSubItemRect(hwnd, row, column, LVIR_LABEL, &rcLabel); @@ -278,10 +267,8 @@ auto pTableView::onCustomDraw(LPARAM lparam) -> LRESULT { auto pTableView::onSort(LPARAM lparam) -> void { auto nmlistview = (LPNMLISTVIEW)lparam; - if(auto& header = state().header) { - if(auto column = header->column(nmlistview->iSubItem)) { - if(column->sortable()) self().doSort(column); - } + if(auto column = self().column(nmlistview->iSubItem)) { + if(state().sortable) self().doSort(column); } } @@ -301,6 +288,19 @@ auto pTableView::onToggle(LPARAM lparam) -> void { } } +auto pTableView::setHeadered(bool headered) -> void { + auto style = GetWindowLong(hwnd, GWL_STYLE); + headered ? style &=~ LVS_NOCOLUMNHEADER : style |= LVS_NOCOLUMNHEADER; + SetWindowLong(hwnd, GWL_STYLE, style); +} + +auto pTableView::setSortable(bool sortable) -> void { + //note: this won't change the visual style: WC_LISTVIEW caches this in CreateWindow + auto style = GetWindowLong(hwnd, GWL_STYLE); + sortable ? style &=~ LVS_NOSORTHEADER : style |= LVS_NOSORTHEADER; + SetWindowLong(hwnd, GWL_STYLE, style); +} + auto pTableView::_backgroundColor(unsigned _row, unsigned _column) -> Color { if(auto item = self().item(_row)) { if(auto cell = item->cell(_column)) { @@ -308,11 +308,11 @@ auto pTableView::_backgroundColor(unsigned _row, unsigned _column) -> Color { } if(auto color = item->backgroundColor()) return color; } -// if(auto column = self().column(_column)) { -// if(auto color = column->backgroundColor()) return color; -// } +//if(auto column = self().column(_column)) { +// if(auto color = column->backgroundColor()) return color; +//} if(auto color = self().backgroundColor()) return color; -// if(state().columns.size() >= 2 && _row % 2) return {240, 240, 240}; +//if(state().columns.size() >= 2 && _row % 2) return {240, 240, 240}; return {255, 255, 255}; } @@ -336,14 +336,15 @@ auto pTableView::_cellWidth(unsigned _row, unsigned _column) -> unsigned { auto pTableView::_columnWidth(unsigned _column) -> unsigned { unsigned width = 12; - if(auto header = state().header) { - if(auto column = header->column(_column)) { - if(auto& icon = column->state.icon) { - width += 16 + 12; //yes; icon spacing in column headers is excessive - } - if(auto& text = column->state.text) { - width += pFont::size(self().font(true), text).width(); - } + if(auto column = self().column(_column)) { + if(auto& icon = column->state.icon) { + width += 16 + 12; //yes; icon spacing in column headers is excessive + } + if(auto& text = column->state.text) { + width += pFont::size(self().font(true), text).width(); + } + if(column->state.sorting != Sort::None) { + width += 12; } } return width; @@ -356,9 +357,9 @@ auto pTableView::_font(unsigned _row, unsigned _column) -> Font { } if(auto font = item->font()) return font; } -// if(auto column = self().column(_column)) { -// if(auto font = column->font()) return font; -// } +//if(auto column = self().column(_column)) { +// if(auto font = column->font()) return font; +//} if(auto font = self().font(true)) return font; return {}; } @@ -370,9 +371,9 @@ auto pTableView::_foregroundColor(unsigned _row, unsigned _column) -> Color { } if(auto color = item->foregroundColor()) return color; } -// if(auto column = self().column(_column)) { -// if(auto color = column->foregroundColor()) return color; -// } +//if(auto column = self().column(_column)) { +// if(auto color = column->foregroundColor()) return color; +//} if(auto color = self().foregroundColor()) return color; return {0, 0, 0}; } @@ -383,21 +384,19 @@ auto pTableView::_setIcons() -> void { imageList = ImageList_Create(16, 16, ILC_COLOR32, 1, 0); ListView_SetImageList(hwnd, imageList, LVSIL_SMALL); - if(auto& header = state().header) { - for(auto column : range(header->columnCount())) { - image icon; - if(auto& sourceIcon = header->state.columns[column]->state.icon) { - icon.allocate(sourceIcon.width(), sourceIcon.height()); - memory::copy(icon.data(), sourceIcon.data(), icon.size()); - icon.scale(16, 16); - } else { - icon.allocate(16, 16); - icon.fill(0x00ffffff); - } - auto bitmap = CreateBitmap(icon); - ImageList_Add(imageList, bitmap, nullptr); - DeleteObject(bitmap); + for(auto column : range(self().columnCount())) { + image icon; + if(auto& sourceIcon = state().columns[column]->state.icon) { + icon.allocate(sourceIcon.width(), sourceIcon.height()); + memory::copy(icon.data(), sourceIcon.data(), icon.size()); + icon.scale(16, 16); + } else { + icon.allocate(16, 16); + icon.fill(0x00ffffff); } + auto bitmap = CreateBitmap(icon); + ImageList_Add(imageList, bitmap, nullptr); + DeleteObject(bitmap); } //empty icon used for ListViewItems (drawn manually via onCustomDraw) @@ -409,31 +408,14 @@ auto pTableView::_setIcons() -> void { DeleteObject(bitmap); } -auto pTableView::_setSortable() -> void { - bool sortable = false; - if(auto& header = state().header) { - for(auto& column : header->state.columns) { - if(column->sortable()) sortable = true; - } - } - - //note: this won't change the visual style: WC_LISTVIEW caches this in CreateWindow - auto style = GetWindowLong(hwnd, GWL_STYLE); - !sortable ? style |= LVS_NOSORTHEADER : style &=~ LVS_NOSORTHEADER; - SetWindowLong(hwnd, GWL_STYLE, style); -} - auto pTableView::_width(unsigned column) -> unsigned { - if(auto& header = state().header) { - if(auto width = header->state.columns[column]->width()) return width; - unsigned width = 1; - if(header->visible()) width = max(width, _columnWidth(column)); - for(auto row : range(state().items.size())) { - width = max(width, _cellWidth(row, column)); - } - return width; + if(auto width = self().column(column).width()) return width; + unsigned width = 1; + if(state().headered) width = max(width, _columnWidth(column)); + for(auto row : range(state().items.size())) { + width = max(width, _cellWidth(row, column)); } - return 1; + return width; } } diff --git a/hiro/windows/widget/table-view.hpp b/hiro/windows/widget/table-view.hpp index 65fa610d..36a1732f 100644 --- a/hiro/windows/widget/table-view.hpp +++ b/hiro/windows/widget/table-view.hpp @@ -5,9 +5,9 @@ namespace hiro { struct pTableView : pWidget { Declare(TableView, Widget) - auto append(sTableViewHeader header) -> void; + auto append(sTableViewColumn column) -> void; auto append(sTableViewItem item) -> void; - auto remove(sTableViewHeader header) -> void; + auto remove(sTableViewColumn column) -> void; auto remove(sTableViewItem item) -> void; auto resizeColumns() -> void; auto setAlignment(Alignment alignment) -> void; @@ -16,6 +16,8 @@ struct pTableView : pWidget { auto setBordered(bool bordered) -> void; auto setForegroundColor(Color color) -> void; auto setGeometry(Geometry geometry) -> void override; + auto setHeadered(bool headered) -> void; + auto setSortable(bool sortable) -> void; auto onActivate(LPARAM lparam) -> void; auto onChange(LPARAM lparam) -> void; @@ -30,7 +32,6 @@ struct pTableView : pWidget { auto _font(unsigned row, unsigned column) -> Font; auto _foregroundColor(unsigned row, unsigned column) -> Color; auto _setIcons() -> void; - auto _setSortable() -> void; auto _width(unsigned column) -> unsigned; WindowProc windowProc = nullptr; diff --git a/hiro/windows/widget/text-edit.cpp b/hiro/windows/widget/text-edit.cpp index 2ddb830d..fc04f47e 100644 --- a/hiro/windows/widget/text-edit.cpp +++ b/hiro/windows/widget/text-edit.cpp @@ -25,6 +25,7 @@ auto pTextEdit::destruct() -> void { auto pTextEdit::setBackgroundColor(Color color) -> void { if(backgroundBrush) { DeleteObject(backgroundBrush); backgroundBrush = 0; } backgroundBrush = CreateSolidBrush(color ? CreateRGB(color) : GetSysColor(COLOR_WINDOW)); + InvalidateRect(hwnd, 0, true); } auto pTextEdit::setCursor(Cursor cursor) -> void { @@ -40,14 +41,14 @@ auto pTextEdit::setEditable(bool editable) -> void { } auto pTextEdit::setForegroundColor(Color color) -> void { + InvalidateRect(hwnd, 0, true); } auto pTextEdit::setText(string text) -> void { - lock(); + auto lock = acquire(); text.replace("\r", ""); text.replace("\n", "\r\n"); SetWindowText(hwnd, utf16_t(text)); - unlock(); } auto pTextEdit::setWordWrap(bool wordWrap) -> void { diff --git a/hiro/windows/window.cpp b/hiro/windows/window.cpp index f39408df..4f8f26a5 100644 --- a/hiro/windows/window.cpp +++ b/hiro/windows/window.cpp @@ -170,7 +170,7 @@ auto pWindow::setModal(bool modality) -> void { _modalityUpdate(); while(state().modal) { Application::processEvents(); - if(Application::state.onMain) { + if(Application::state().onMain) { Application::doMain(); } else { usleep(20 * 1000); @@ -193,6 +193,9 @@ auto pWindow::setTitle(string text) -> void { auto pWindow::setVisible(bool visible) -> void { auto lock = acquire(); ShowWindow(hwnd, visible ? SW_SHOWNORMAL : SW_HIDE); + if(auto& sizable = state().sizable) { + sizable->setGeometry(self().geometry().setPosition()); + } if(!visible) setModal(false); } diff --git a/nall/image.hpp b/nall/image.hpp index 25c39e5f..0623baa6 100644 --- a/nall/image.hpp +++ b/nall/image.hpp @@ -46,8 +46,9 @@ struct image { inline image(image&& source); inline image(bool endian, uint depth, uint64_t alphaMask, uint64_t redMask, uint64_t greenMask, uint64_t blueMask); inline image(const string& filename); + inline image(const void* data, uint size); inline image(const vector& buffer); - inline image(const uint8_t* data, uint size); + template inline image(Type (&Name)[Size]); inline image(); inline ~image(); diff --git a/nall/image/core.hpp b/nall/image/core.hpp index bd0b7423..4c7bcbaa 100644 --- a/nall/image/core.hpp +++ b/nall/image/core.hpp @@ -24,18 +24,17 @@ image::image(const string& filename) { load(filename); } -image::image(const vector& buffer) { - auto data = buffer.data(); - auto size = buffer.size(); - if(0); +image::image(const void* data_, uint size) { + auto data = (const uint8_t*)data_; + if(size < 4); else if(data[0] == 'B' && data[1] == 'M') loadBMP(data, size); else if(data[1] == 'P' && data[2] == 'N' && data[3] == 'G') loadPNG(data, size); } -image::image(const uint8_t* data, unsigned size) { - if(0); - else if(data[0] == 'B' && data[1] == 'M') loadBMP(data, size); - else if(data[1] == 'P' && data[2] == 'N' && data[3] == 'G') loadPNG(data, size); +image::image(const vector& buffer) : image(buffer.data(), buffer.size()) { +} + +template image::image(Type (&Name)[Size]) : image(Name, Size) { } image::image() { diff --git a/nall/vfs/memory/file.hpp b/nall/vfs/memory/file.hpp index 4f9afa27..12b93dab 100644 --- a/nall/vfs/memory/file.hpp +++ b/nall/vfs/memory/file.hpp @@ -5,9 +5,9 @@ namespace nall { namespace vfs { namespace memory { struct file : vfs::file { ~file() { delete[] _data; } - static auto open(const uint8_t* data, uintmax size) -> vfs::shared::file { + static auto open(const void* data, uintmax size) -> vfs::shared::file { auto instance = shared_pointer{new file}; - instance->_open(data, size); + instance->_open((const uint8_t*)data, size); return instance; } diff --git a/ruby/GNUmakefile b/ruby/GNUmakefile index 83d42583..c7531aa2 100644 --- a/ruby/GNUmakefile +++ b/ruby/GNUmakefile @@ -12,8 +12,7 @@ ifeq ($(ruby),) ruby += audio.oss audio.alsa audio.openal audio.pulseaudio audio.pulseaudiosimple audio.ao ruby += input.sdl input.xlib input.udev else ifeq ($(platform),bsd) -# ruby += video.glx video.glx2 video.xvideo video.xshm - ruby += video.glx2 video.xshm + ruby += video.glx video.glx2 video.xvideo video.xshm ruby += audio.oss audio.openal ruby += input.sdl input.xlib endif @@ -39,7 +38,7 @@ ruby.options += $(if $(findstring video.xvideo,$(ruby)),-lXv) ruby.options += $(if $(findstring audio.alsa,$(ruby)),-lasound) ruby.options += $(if $(findstring audio.ao,$(ruby)),-lao) -ruby.options += $(if $(findstring audio.directsound,$(ruby)),-ldsound) +ruby.options += $(if $(findstring audio.directsound,$(ruby)),-ldsound -luuid) ruby.options += $(if $(findstring audio.pulseaudio,$(ruby)),-lpulse) ruby.options += $(if $(findstring audio.pulseaudiosimple,$(ruby)),-lpulse-simple) ruby.options += $(if $(findstring audio.wasapi,$(ruby)),-lavrt -luuid) diff --git a/ruby/audio/alsa.cpp b/ruby/audio/alsa.cpp index 6d780b72..276a7787 100644 --- a/ruby/audio/alsa.cpp +++ b/ruby/audio/alsa.cpp @@ -1,63 +1,58 @@ #include -struct AudioALSA : Audio { - AudioALSA() { initialize(); } +struct AudioALSA : AudioDriver { + AudioALSA& self = *this; + AudioALSA(Audio& super) : AudioDriver(super) {} ~AudioALSA() { terminate(); } + auto create() -> bool override { + super.setDevice(hasDevices().first()); + super.setChannels(2); + super.setFrequency(48000); + super.setLatency(20); + return initialize(); + } + auto driver() -> string override { return "ALSA"; } auto ready() -> bool override { return _ready; } - auto hasDevice() -> bool override { return true; } auto hasBlocking() -> bool override { return true; } - auto hasChannels() -> bool override { return true; } - auto hasFrequency() -> bool override { return true; } - auto hasLatency() -> bool override { return true; } - auto availableDevices() -> vector override { - return queryDevices(); + auto hasDevices() -> vector override { + vector devices; + + char** list; + if(snd_device_name_hint(-1, "pcm", (void***)&list) == 0) { + uint index = 0; + while(list[index]) { + char* deviceName = snd_device_name_get_hint(list[index], "NAME"); + if(deviceName) devices.append(deviceName); + free(deviceName); + index++; + } + } + + snd_device_name_free_hint((void**)list); + return devices; } - auto availableChannels() -> vector override { + auto hasChannels() -> vector override { return {2}; } - auto availableFrequencies() -> vector override { - return {44100.0, 48000.0, 96000.0}; + auto hasFrequencies() -> vector override { + return {44100, 48000, 96000}; } - auto availableLatencies() -> vector override { + auto hasLatencies() -> vector override { return {20, 40, 60, 80, 100}; } - auto setDevice(string device) -> bool override { - if(device == Audio::device()) return true; - if(!Audio::setDevice(device)) return false; - return initialize(); - } - - auto setBlocking(bool blocking) -> bool override { - if(blocking == Audio::blocking()) return true; - if(!Audio::setBlocking(blocking)) return false; - return true; - } - - auto setChannels(uint channels) -> bool override { - if(channels == Audio::channels()) return true; - if(!Audio::setChannels(channels)) return false; - return true; - } - - auto setFrequency(double frequency) -> bool override { - if(frequency == Audio::frequency()) return true; - if(!Audio::setFrequency(frequency)) return false; - return initialize(); - } - - auto setLatency(uint latency) -> bool override { - if(latency == Audio::latency()) return true; - if(!Audio::setLatency(latency)) return false; - return initialize(); - } + auto setDevice(string device) -> bool override { return initialize(); } + auto setBlocking(bool blocking) -> bool override { return true; } + auto setChannels(uint channels) -> bool override { return true; } + auto setFrequency(uint frequency) -> bool override { return initialize(); } + auto setLatency(uint latency) -> bool override { return initialize(); } auto level() -> double override { snd_pcm_sframes_t available = snd_pcm_avail_update(_interface); @@ -66,8 +61,6 @@ struct AudioALSA : Audio { } auto output(const double samples[]) -> void override { - if(!ready()) return; - _buffer[_offset] = (uint16_t)sclamp<16>(samples[0] * 32767.0) << 0; _buffer[_offset] |= (uint16_t)sclamp<16>(samples[1] * 32767.0) << 16; _offset++; @@ -77,7 +70,7 @@ struct AudioALSA : Audio { available = snd_pcm_avail_update(_interface); if(available < 0) snd_pcm_recover(_interface, available, 1); if(available < _offset) { - if(!_blocking) { + if(!self.blocking) { _offset = 0; return; } @@ -113,13 +106,12 @@ private: auto initialize() -> bool { terminate(); - string device = "default"; - if(queryDevices().find(_device)) device = _device; - if(snd_pcm_open(&_interface, device, SND_PCM_STREAM_PLAYBACK, SND_PCM_NONBLOCK) < 0) return terminate(), false; + if(!hasDevices().find(self.device)) self.device = hasDevices().first(); + if(snd_pcm_open(&_interface, self.device, SND_PCM_STREAM_PLAYBACK, SND_PCM_NONBLOCK) < 0) return terminate(), false; - uint rate = (uint)_frequency; - uint bufferTime = _latency * 1000; - uint periodTime = _latency * 1000 / 8; + uint rate = self.frequency; + uint bufferTime = self.latency * 1000; + uint periodTime = self.latency * 1000 / 8; snd_pcm_hw_params_t* hardwareParameters; snd_pcm_hw_params_alloca(&hardwareParameters); @@ -162,24 +154,6 @@ private: } } - auto queryDevices() -> vector { - vector devices; - - char** list; - if(snd_device_name_hint(-1, "pcm", (void***)&list) == 0) { - uint index = 0; - while(list[index]) { - char* deviceName = snd_device_name_get_hint(list[index], "NAME"); - if(deviceName) devices.append(deviceName); - free(deviceName); - index++; - } - } - - snd_device_name_free_hint((void**)list); - return devices; - } - bool _ready = false; snd_pcm_t* _interface = nullptr; diff --git a/ruby/audio/ao.cpp b/ruby/audio/ao.cpp index 8a4a19fa..0a851dfc 100644 --- a/ruby/audio/ao.cpp +++ b/ruby/audio/ao.cpp @@ -1,24 +1,29 @@ #include -struct AudioAO : Audio { - AudioAO() { initialize(); } +struct AudioAO : AudioDriver { + AudioAO& self = *this; + AudioAO(Audio& super) : AudioDriver(super) {} ~AudioAO() { terminate(); } + auto create() -> bool override { + super.setChannels(2); + super.setFrequency(48000); + return initialize(); + } + auto driver() -> string override { return "libao"; } auto ready() -> bool override { return _ready; } - auto hasFrequencies() -> bool override { return true; } - - auto availableFrequencies() -> vector override { - return {44100.0, 48000.0, 96000.0}; + auto hasChannels() -> vector override { + return {2}; } - auto setFrequency(double frequency) -> bool override { - if(frequency == Audio::frequency()) return true; - if(!Audio::setFrequency(frequency)) return false; - return initialize(); + auto hasFrequencies() -> vector override { + return {44100, 48000, 96000}; } + auto setFrequency(uint frequency) -> bool override { return initialize(); } + auto output(const double samples[]) -> void override { uint32_t sample = 0; sample |= (uint16_t)sclamp<16>(samples[0] * 32767.0) << 0; @@ -38,7 +43,7 @@ private: ao_sample_format format; format.bits = 16; format.channels = 2; - format.rate = (uint)_frequency; + format.rate = self.frequency; format.byte_format = AO_FMT_LITTLE; format.matrix = nullptr; diff --git a/ruby/audio/asio.cpp b/ruby/audio/asio.cpp index 008819a7..3587eac2 100644 --- a/ruby/audio/asio.cpp +++ b/ruby/audio/asio.cpp @@ -2,80 +2,70 @@ #include "asio.hpp" struct AudioASIO : Audio { - static AudioASIO* self; - AudioASIO() { self = this; initialize(); } + static AudioASIO* instance; + AudioASIO& self = *this; + AudioASIO(Audio& super) : AudioDriver(super) { instance = this; } ~AudioASIO() { terminate(); } + auto create() -> bool override { + super.setDevice(hasDevices().first()); + super.setChannels(2); + super.setFrequency(48000); + super.setLatency(2048); + return initialize(); + } + auto driver() -> string override { return "ASIO"; } auto ready() -> bool override { return _ready; } auto hasContext() -> bool override { return true; } - auto hasDevice() -> bool override { return true; } auto hasBlocking() -> bool override { return true; } - auto hasChannels() -> bool override { return true; } - auto hasFrequency() -> bool override { return true; } - auto hasLatency() -> bool override { return true; } - auto availableDevices() -> vector override { + auto hasDevices() -> vector override { + self.devices.reset(); + for(auto candidate : registry::contents("HKLM\\SOFTWARE\\ASIO\\")) { + if(auto classID = registry::read({"HKLM\\SOFTWARE\\ASIO\\", candidate, "CLSID"})) { + self.devices.append({candidate.trimRight("\\", 1L), classID}); + } + } + vector devices; - for(auto& device : _devices) devices.append(device.name); + for(auto& device : self.devices) devices.append(device.name); return devices; } - auto availableChannels() -> vector override { + auto hasChannels() -> vector override { return {1, 2}; } - auto availableFrequencies() -> vector override { - return {_frequency}; + auto hasFrequencies() -> vector override { + return {self.frequency}; } - auto availableLatencies() -> vector override { + auto hasLatencies() -> vector override { vector latencies; uint latencyList[] = {64, 96, 128, 192, 256, 384, 512, 768, 1024, 1536, 2048, 3072, 6144}; //factors of 6144 for(auto& latency : latencyList) { - if(latency < _active.minimumBufferSize) continue; - if(latency > _active.maximumBufferSize) continue; + if(self.activeDevice) { + if(latency < self.activeDevice.minimumBufferSize) continue; + if(latency > self.activeDevice.maximumBufferSize) continue; + } latencies.append(latency); } return latencies; } - auto setContext(uintptr context) -> bool override { - if(context == Audio::context()) return true; - if(!Audio::setContext(context)) return false; - return initialize(); - } - - auto setDevice(string device) -> bool override { - if(device == Audio::device()) return true; - if(!Audio::setDevice(device)) return false; - return initialize(); - } - - auto setBlocking(bool blocking) -> bool override { - if(blocking == Audio::blocking()) return true; - if(!Audio::setBlocking(blocking)) return false; - return initialize(); - } - - auto setChannels(uint channels) -> bool override { - if(channels == Audio::channels()) return true; - if(!Audio::setChannels(channels)) return false; - return initialize(); - } - - auto setLatency(uint latency) -> bool override { - if(latency == Audio::latency()) return true; - if(!Audio::setLatency(latency)) return false; - return initialize(); - } + auto setContext(uintptr context) -> bool override { return initialize(); } + auto setDevice(string device) -> bool override { return initialize(); } + auto setBlocking(bool blocking) -> bool override { return initialize(); } + auto setChannels(uint channels) -> bool override { return initialize(); } + auto setLatency(uint latency) -> bool override { return initialize(); } auto clear() -> void override { if(!ready()) return; - for(uint n : range(_channels)) { - memory::fill(_channel[n].buffers[0], _latency * _sampleSize); - memory::fill(_channel[n].buffers[1], _latency * _sampleSize); + for(uint n : range(self.channels)) { + memory::fill(_channel[n].buffers[0], self.latency * _sampleSize); + memory::fill(_channel[n].buffers[1], self.latency * _sampleSize); } memory::fill(_queue.samples, sizeof(_queue.samples)); _queue.read = 0; @@ -85,10 +75,10 @@ struct AudioASIO : Audio { auto output(const double samples[]) -> void override { if(!ready()) return; - if(_blocking) { - while(_queue.count >= _latency); + if(self.blocking) { + while(_queue.count >= self.latency); } - for(uint n : range(_channels)) { + for(uint n : range(self.channels)) { _queue.samples[_queue.write][n] = samples[n]; } _queue.write++; @@ -99,39 +89,40 @@ private: auto initialize() -> bool { terminate(); - //enumerate available ASIO drivers from the registry - for(auto candidate : registry::contents("HKLM\\SOFTWARE\\ASIO\\")) { - if(auto classID = registry::read({"HKLM\\SOFTWARE\\ASIO\\", candidate, "CLSID"})) { - _devices.append({candidate.trimRight("\\", 1L), classID}); - if(candidate == _device) _active = _devices.right(); + hasDevices(); //this call populates self.devices + if(!self.devices) return false; + + self.activeDevice = {}; + for(auto& device : self.devices) { + if(self.device == device.name) { + self.activeDevice = device; + break; } } - if(!_devices) return false; - - if(!_active.name) { - _active = _devices.left(); - _device = _active.name; + if(!self.activeDevice) { + self.activeDevice = self.devices.first(); + self.device = self.activeDevice.name; } CLSID classID; - if(CLSIDFromString((LPOLESTR)utf16_t(_active.classID), (LPCLSID)&classID) != S_OK) return false; + if(CLSIDFromString((LPOLESTR)utf16_t(self.activeDevice.classID), (LPCLSID)&classID) != S_OK) return false; if(CoCreateInstance(classID, 0, CLSCTX_INPROC_SERVER, classID, (void**)&_asio) != S_OK) return false; - if(!_asio->init((void*)_context)) return false; - if(_asio->getSampleRate(&_active.sampleRate) != ASE_OK) return false; - if(_asio->getChannels(&_active.inputChannels, &_active.outputChannels) != ASE_OK) return false; + if(!_asio->init((void*)self.context)) return false; + if(_asio->getSampleRate(&self.activeDevice.sampleRate) != ASE_OK) return false; + if(_asio->getChannels(&self.activeDevice.inputChannels, &self.activeDevice.outputChannels) != ASE_OK) return false; if(_asio->getBufferSize( - &_active.minimumBufferSize, - &_active.maximumBufferSize, - &_active.preferredBufferSize, - &_active.granularity + &self.activeDevice.minimumBufferSize, + &self.activeDevice.maximumBufferSize, + &self.activeDevice.preferredBufferSize, + &self.activeDevice.granularity ) != ASE_OK) return false; - _frequency = _active.sampleRate; - _latency = _latency < _active.minimumBufferSize ? _active.minimumBufferSize : _latency; - _latency = _latency > _active.maximumBufferSize ? _active.maximumBufferSize : _latency; + self.frequency = self.activeDevice.sampleRate; + self.latency = self.latency < self.activeDevice.minimumBufferSize ? self.activeDevice.minimumBufferSize : self.latency; + self.latency = self.latency > self.activeDevice.maximumBufferSize ? self.activeDevice.maximumBufferSize : self.latency; - for(auto n : range(_channels)) { + for(uint n : range(self.channels)) { _channel[n].isInput = false; _channel[n].channelNum = n; _channel[n].buffers[0] = nullptr; @@ -142,8 +133,8 @@ private: callbacks.sampleRateDidChange = &AudioASIO::_sampleRateDidChange; callbacks.asioMessage = &AudioASIO::_asioMessage; callbacks.bufferSwitchTimeInfo = &AudioASIO::_bufferSwitchTimeInfo; - if(_asio->createBuffers(_channel, _channels, _latency, &callbacks) != ASE_OK) return false; - if(_asio->getLatencies(&_active.inputLatency, &_active.outputLatency) != ASE_OK) return false; + if(_asio->createBuffers(_channel, self.channels, self.latency, &callbacks) != ASE_OK) return false; + if(_asio->getLatencies(&self.activeDevice.inputLatency, &self.activeDevice.outputLatency) != ASE_OK) return false; //assume for the sake of sanity that all buffers use the same sample format ... ASIOChannelInfo channelInformation = {}; @@ -167,8 +158,7 @@ private: auto terminate() -> void { _ready = false; - _devices.reset(); - _active = {}; + self.activeDevice = {}; if(_asio) { _asio->stop(); _asio->disposeBuffers(); @@ -179,33 +169,33 @@ private: private: static auto _bufferSwitch(long doubleBufferInput, ASIOBool directProcess) -> void { - return self->bufferSwitch(doubleBufferInput, directProcess); + return instance->bufferSwitch(doubleBufferInput, directProcess); } static auto _sampleRateDidChange(ASIOSampleRate sampleRate) -> void { - return self->sampleRateDidChange(sampleRate); + return instance->sampleRateDidChange(sampleRate); } static auto _asioMessage(long selector, long value, void* message, double* optional) -> long { - return self->asioMessage(selector, value, message, optional); + return instance->asioMessage(selector, value, message, optional); } static auto _bufferSwitchTimeInfo(ASIOTime* parameters, long doubleBufferIndex, ASIOBool directProcess) -> ASIOTime* { - return self->bufferSwitchTimeInfo(parameters, doubleBufferIndex, directProcess); + return instance->bufferSwitchTimeInfo(parameters, doubleBufferIndex, directProcess); } auto bufferSwitch(long doubleBufferInput, ASIOBool directProcess) -> void { - for(uint sampleIndex : range(_latency)) { + for(uint sampleIndex : range(self.latency)) { double samples[8] = {0}; if(_queue.count) { - for(uint n : range(_channels)) { + for(uint n : range(self.channels)) { samples[n] = _queue.samples[_queue.read][n]; } _queue.read++; _queue.count--; } - for(uint n : range(_channels)) { + for(uint n : range(self.channels)) { auto buffer = (uint8_t*)_channel[n].buffers[doubleBufferInput]; buffer += sampleIndex * _sampleSize; @@ -263,6 +253,8 @@ private: }; struct Device { + explicit operator bool() const { return name; } + string name; string classID; @@ -278,12 +270,12 @@ private: }; Queue _queue; - vector _devices; - Device _active; + vector devices; + Device activeDevice; IASIO* _asio = nullptr; ASIOBufferInfo _channel[8]; long _sampleFormat; long _sampleSize; }; -AudioASIO* AudioASIO::self = nullptr; +AudioASIO* AudioASIO::instance = nullptr; diff --git a/ruby/audio/directsound.cpp b/ruby/audio/directsound.cpp index 428a4aa3..ed2f8155 100644 --- a/ruby/audio/directsound.cpp +++ b/ruby/audio/directsound.cpp @@ -1,51 +1,33 @@ #include -struct AudioDirectSound : Audio { - AudioDirectSound() { - Audio::setFrequency(48000.0); - Audio::setLatency(40); - initialize(); - } +struct AudioDirectSound : AudioDriver { + AudioDirectSound& self = *this; + AudioDirectSound(Audio& super) : AudioDriver(super) {} + ~AudioDirectSound() { terminate(); } - ~AudioDirectSound() { - terminate(); + auto create() -> bool override { + super.setChannels(2); + super.setFrequency(48000); + super.setLatency(40); + return initialize(); } auto driver() -> string override { return "DirectSound"; } auto ready() -> bool override { return _ready; } auto hasBlocking() -> bool override { return true; } - auto hasFrequency() -> bool override { return true; } - auto hasLatency() -> bool override { return true; } - auto availableFrequencies() -> vector override { - return {44100.0, 48000.0, 96000.0}; + auto hasFrequencies() -> vector override { + return {44100, 48000, 96000}; } - auto availableLatencies() -> vector override { + auto hasLatencies() -> vector override { return {40, 60, 80, 100}; } - auto defaultFrequency() -> double override { return 48000.0; } - auto defaultLatency() -> uint override { return 40; } - - auto setBlocking(bool blocking) -> bool override { - if(blocking == Audio::blocking()) return true; - if(!Audio::setBlocking(blocking)) return false; - return true; - } - - auto setFrequency(double frequency) -> bool override { - if(frequency == Audio::frequency()) return true; - if(!Audio::setFrequency(frequency)) return false; - return initialize(); - } - - auto setLatency(uint latency) -> bool override { - if(latency == Audio::latency()) return true; - if(!Audio::setLatency(latency)) return false; - return initialize(); - } + auto setBlocking(bool blocking) -> bool override { return true; } + auto setFrequency(uint frequency) -> bool override { return initialize(); } + auto setLatency(uint latency) -> bool override { return initialize(); } auto clear() -> void override { if(!ready()) return; @@ -78,7 +60,7 @@ struct AudioDirectSound : Audio { if(++_offset < _period) return; _offset = 0; - if(_blocking) { + if(self.blocking) { //wait until playback buffer has an empty ring to write new audio data to while(_ringDistance >= _rings - 1) { DWORD position; @@ -115,7 +97,7 @@ private: terminate(); _rings = 8; - _period = _frequency * _latency / _rings / 1000.0 + 0.5; + _period = self.frequency * self.latency / _rings / 1000.0 + 0.5; _buffer = new uint32_t[_period * _rings]; _offset = 0; @@ -131,8 +113,8 @@ private: WAVEFORMATEX waveFormat = {}; waveFormat.wFormatTag = WAVE_FORMAT_PCM; - waveFormat.nChannels = _channels; - waveFormat.nSamplesPerSec = (uint)_frequency; + waveFormat.nChannels = self.channels; + waveFormat.nSamplesPerSec = self.frequency; waveFormat.wBitsPerSample = 16; waveFormat.nBlockAlign = waveFormat.nChannels * waveFormat.wBitsPerSample / 8; waveFormat.nAvgBytesPerSec = waveFormat.nSamplesPerSec * waveFormat.nBlockAlign; @@ -145,7 +127,7 @@ private: secondaryDescription.guid3DAlgorithm = GUID_NULL; secondaryDescription.lpwfxFormat = &waveFormat; _interface->CreateSoundBuffer(&secondaryDescription, &_secondary, 0); - _secondary->SetFrequency((uint)_frequency); + _secondary->SetFrequency(self.frequency); _secondary->SetCurrentPosition(0); _ready = true; diff --git a/ruby/audio/openal.cpp b/ruby/audio/openal.cpp index 1393c009..da6a50ec 100644 --- a/ruby/audio/openal.cpp +++ b/ruby/audio/openal.cpp @@ -7,6 +7,7 @@ #endif struct AudioOpenAL : AudioDriver { + AudioOpenAL& self = *this; AudioOpenAL(Audio& driver) : AudioDriver(super) {} ~AudioOpenAL() { terminate(); } @@ -161,8 +162,6 @@ private: return true; } - AudioOpenAL& self = *this; - bool _ready = false; ALCdevice* _openAL = nullptr; diff --git a/ruby/audio/oss.cpp b/ruby/audio/oss.cpp index 508ec458..eeb0f95b 100644 --- a/ruby/audio/oss.cpp +++ b/ruby/audio/oss.cpp @@ -14,6 +14,7 @@ #endif struct AudioOSS : AudioDriver { + AudioOSS& self = *this; AudioOSS(Audio& super) : AudioDriver(super) {} ~AudioOSS() { terminate(); } @@ -118,8 +119,6 @@ private: return true; } - AudioOSS& self = *this; - int _fd = -1; int _format = AFMT_S16_LE; int _bufferSize = 1; diff --git a/ruby/audio/pulseaudio.cpp b/ruby/audio/pulseaudio.cpp index b48e2ada..eaa0112c 100644 --- a/ruby/audio/pulseaudio.cpp +++ b/ruby/audio/pulseaudio.cpp @@ -1,41 +1,32 @@ #include struct AudioPulseAudio : Audio { - AudioPulseAudio() { initialize(); } + AudioPulseAudio& self = *this; + AudioPulseAudio(Audio& super) : AudioDriver(super) {} ~AudioPulseAudio() { terminate(); } + auto create() -> bool override { + super.setFrequency(48000); + super.setLatency(40); + return initialize(); + } + auto driver() -> string override { return "PulseAudio"; } auto ready() -> bool override { return _ready; } auto hasBlocking() -> bool override { return true; } - auto hasFrequency() -> bool override { return true; } - auto hasLatency() -> bool override { return true; } - auto availableFrequencies() -> vector override { - return {44100.0, 48000.0, 96000.0}; + auto hasFrequencies() -> vector override { + return {44100, 48000, 96000}; } - auto availableLatencies() -> vector override { + auto hasLatencies() -> vector override { return {20, 40, 60, 80, 100}; } - auto setBlocking(bool blocking) -> bool override { - if(blocking == Audio::blocking()) return true; - if(!Audio::setBlocking(blocking)) return false; - return true; - } - - auto setFrequency(double frequency) -> bool override { - if(frequency == Audio::frequency()) return true; - if(!Audio::setFrequency(frequency)) return false; - return initialize(); - } - - auto setLatency(uint latency) -> bool override { - if(latency == Audio::latency()) return true; - if(!Audio::setLatency(latency)) return false; - return initialize(); - } + auto setBlocking(bool blocking) -> bool override { return true; } + auto setFrequency(double frequency) -> bool override { return initialize(); } + auto setLatency(uint latency) -> bool override { return initialize(); } auto output(const double samples[]) -> void override { pa_stream_begin_write(_stream, (void**)&_buffer, &_period); @@ -80,12 +71,12 @@ private: _specification.format = PA_SAMPLE_S16LE; _specification.channels = 2; - _specification.rate = (uint)_frequency; + _specification.rate = self.frequency; _stream = pa_stream_new(_context, "audio", &_specification, nullptr); pa_buffer_attr bufferAttributes; bufferAttributes.maxlength = -1; - bufferAttributes.tlength = pa_usec_to_bytes(_latency * PA_USEC_PER_MSEC, &_specification); + bufferAttributes.tlength = pa_usec_to_bytes(self.latency * PA_USEC_PER_MSEC, &_specification); bufferAttributes.prebuf = -1; bufferAttributes.minreq = -1; bufferAttributes.fragsize = -1; diff --git a/ruby/audio/pulseaudiosimple.cpp b/ruby/audio/pulseaudiosimple.cpp index c7347d0b..8cb51fd9 100644 --- a/ruby/audio/pulseaudiosimple.cpp +++ b/ruby/audio/pulseaudiosimple.cpp @@ -1,24 +1,25 @@ #include #include -struct AudioPulseAudioSimple : Audio { - AudioPulseAudioSimple() { initialize(); } +struct AudioPulseAudioSimple : AudioDriver { + AudioPulseAudioSimple& self = *this; + AudioPulseAudioSimple(Audio& super) : AudioDriver(super) {} ~AudioPulseAudioSimple() { terminate(); } + auto create() -> bool override { + super.setBlocking(true); + super.setFrequency(48000); + return initialize(); + } + auto driver() -> string override { return "PulseAudioSimple"; } auto ready() -> bool override { return _ready; } - auto hasFrequency() -> bool override { return true; } - - auto availableFrequencies() -> vector override { - return {44100.0, 48000.0, 96000.0}; + auto hasFrequencies() -> vector override { + return {44100, 48000, 96000}; } - auto setFrequency(double frequency) -> bool override { - if(frequency == Audio::frequency()) return true; - if(!Audio::setFrequency(frequency)) return false; - return initialize(); - } + auto setFrequency(uint frequency) -> bool override { return initialize(); } auto output(const double samples[]) -> void override { if(!ready()) return; @@ -39,7 +40,7 @@ private: pa_sample_spec specification; specification.format = PA_SAMPLE_S16LE; specification.channels = 2; - specification.rate = (uint)_frequency; + specification.rate = self.frequency; int error = 0; _interface = pa_simple_new( diff --git a/ruby/audio/wasapi.cpp b/ruby/audio/wasapi.cpp index 691635c2..eb1f2cdd 100644 --- a/ruby/audio/wasapi.cpp +++ b/ruby/audio/wasapi.cpp @@ -6,63 +6,45 @@ #include #include -struct AudioWASAPI : Audio { - AudioWASAPI() { initialize(); } +struct AudioWASAPI : AudioDriver { + AudioWASAPI& self = *this; + AudioWASAPI(Audio& super) : AudioDriver(super) {} ~AudioWASAPI() { terminate(); } + auto create() -> bool override { + super.setLatency(40); + return initialize(); + } + auto driver() -> string override { return "WASAPI"; } auto ready() -> bool override { return _ready; } auto hasExclusive() -> bool override { return true; } - auto hasDevice() -> bool override { return true; } auto hasBlocking() -> bool override { return true; } - auto hasFrequency() -> bool override { return true; } - auto hasLatency() -> bool override { return true; } - auto availableDevices() -> vector override { + auto hasDevices() -> vector override { return _devices; } - auto availableFrequencies() -> vector override { - return {_frequency}; + auto hasChannels() -> vector override { + return {self.channels}; + } + + auto hasFrequencies() -> vector override { + return {self.frequency}; } auto availableLatencies() -> vector override { return {0, 20, 40, 60, 80, 100}; } - auto setExclusive(bool exclusive) -> bool override { - if(exclusive == Audio::exclusive()) return true; - if(!Audio::setExclusive(exclusive)) return false; - return initialize(); - } - - auto setDevice(string device) -> bool override { - if(device == Audio::device()) return true; - if(!Audio::setDevice(device)) return false; - return initialize(); - } - - auto setBlocking(bool blocking) -> bool override { - if(blocking == Audio::blocking()) return true; - if(!Audio::setBlocking(blocking)) return false; - return true; - } - - auto setFrequency(double frequency) -> bool override { - if(frequency == Audio::frequency()) return true; - if(!Audio::setFrequency(frequency)) return false; - return initialize(); - } - - auto setLatency(uint latency) -> bool override { - if(latency == Audio::latency()) return true; - if(!Audio::setLatency(latency)) return false; - return initialize(); - } + auto setExclusive(bool exclusive) -> bool override { return initialize(); } + auto setDevice(string device) -> bool override { return initialize(); } + auto setBlocking(bool blocking) -> bool override { return true; } + auto setFrequency(uint frequency) -> bool override { return initialize(); } + auto setLatency(uint latency) -> bool override { return initialize(); } auto clear() -> void override { - if(!ready()) return; _queue.read = 0; _queue.write = 0; _queue.count = 0; @@ -72,8 +54,6 @@ struct AudioWASAPI : Audio { } auto output(const double samples[]) -> void override { - if(!ready()) return; - for(uint n : range(_channels)) { _queue.samples[_queue.write][n] = samples[n]; } @@ -81,7 +61,7 @@ struct AudioWASAPI : Audio { _queue.count++; if(_queue.count >= _bufferSize) { - if(WaitForSingleObject(_eventHandle, _blocking ? INFINITE : 0) == WAIT_OBJECT_0) { + if(WaitForSingleObject(_eventHandle, self.blocking ? INFINITE : 0) == WAIT_OBJECT_0) { write(); } } @@ -131,7 +111,7 @@ private: waveFormat = *(WAVEFORMATEXTENSIBLE*)propVariant.blob.pBlobData; propertyStore->Release(); if(_audioClient->GetDevicePeriod(nullptr, &_devicePeriod) != S_OK) return false; - auto latency = max(_devicePeriod, (REFERENCE_TIME)_latency * 10'000); //1ms to 100ns units + auto latency = max(_devicePeriod, (REFERENCE_TIME)self.latency * 10'000); //1ms to 100ns units auto result = _audioClient->Initialize(AUDCLNT_SHAREMODE_EXCLUSIVE, AUDCLNT_STREAMFLAGS_EVENTCALLBACK, latency, latency, &waveFormat.Format, nullptr); if(result == AUDCLNT_E_BUFFER_SIZE_NOT_ALIGNED) { if(_audioClient->GetBufferSize(&_bufferSize) != S_OK) return false; @@ -149,7 +129,7 @@ private: waveFormat = *(WAVEFORMATEXTENSIBLE*)waveFormatEx; CoTaskMemFree(waveFormatEx); if(_audioClient->GetDevicePeriod(&_devicePeriod, nullptr)) return false; - auto latency = max(_devicePeriod, (REFERENCE_TIME)_latency * 10'000); //1ms to 100ns units + auto latency = max(_devicePeriod, (REFERENCE_TIME)self.latency * 10'000); //1ms to 100ns units if(_audioClient->Initialize(AUDCLNT_SHAREMODE_SHARED, AUDCLNT_STREAMFLAGS_EVENTCALLBACK, latency, 0, &waveFormat.Format, nullptr) != S_OK) return false; } @@ -158,8 +138,8 @@ private: if(_audioClient->GetService(IID_IAudioRenderClient, (void**)&_renderClient) != S_OK) return false; if(_audioClient->GetBufferSize(&_bufferSize) != S_OK) return false; - _channels = waveFormat.Format.nChannels; - _frequency = waveFormat.Format.nSamplesPerSec; + self.channels = waveFormat.Format.nChannels; + self.frequency = waveFormat.Format.nSamplesPerSec; _mode = waveFormat.SubFormat.Data1; _precision = waveFormat.Format.wBitsPerSample; diff --git a/ruby/audio/xaudio2.cpp b/ruby/audio/xaudio2.cpp index d3f80e5f..5f75a7fb 100644 --- a/ruby/audio/xaudio2.cpp +++ b/ruby/audio/xaudio2.cpp @@ -1,42 +1,33 @@ #include "xaudio2.hpp" #include -struct AudioXAudio2 : Audio, public IXAudio2VoiceCallback { - AudioXAudio2() { initialize(); } +struct AudioXAudio2 : AudioDriver, public IXAudio2VoiceCallback { + AudioXAudio2& self = *this; + AudioXAudio2(Audio& super) : AudioDriver(super) {} ~AudioXAudio2() { terminate(); } + auto create() -> bool override { + super.setFrequency(48000); + super.setLatency(40); + return initialize(); + } + auto driver() -> string override { return "XAudio2"; } auto ready() -> bool override { return _ready; } auto hasBlocking() -> bool override { return true; } - auto hasFrequency() -> bool override { return true; } - auto hasLatency() -> bool override { return true; } - auto availableFrequencies() -> vector override { - return {44100.0, 48000.0, 96000.0}; + auto hasFrequencies() -> vector override { + return {44100, 48000, 96000}; } - auto availableLatencies() -> vector override { + auto hasLatencies() -> vector override { return {20, 40, 60, 80, 100}; } - auto setBlocking(bool blocking) -> bool override { - if(blocking == Audio::blocking()) return true; - if(!Audio::setBlocking(blocking)) return false; - return true; - } - - auto setFrequency(double frequency) -> bool override { - if(frequency == Audio::frequency()) return true; - if(!Audio::setFrequency(frequency)) return false; - return initialize(); - } - - auto setLatency(uint latency) -> bool override { - if(latency == Audio::latency()) return true; - if(!Audio::setLatency(latency)) return false; - return initialize(); - } + auto setBlocking(bool blocking) -> bool override { return true; } + auto setFrequency(uint frequency) -> bool override { return initialize(); } + auto setLatency(uint latency) -> bool override { return initialize(); } auto clear() -> void override { if(!_sourceVoice) return; @@ -58,7 +49,7 @@ struct AudioXAudio2 : Audio, public IXAudio2VoiceCallback { _bufferOffset = 0; if(_bufferQueue == _bufferCount - 1) { - if(_blocking) { + if(self.blocking) { //wait until there is at least one other free buffer for the next sample while(_bufferQueue == _bufferCount - 1); } else { //we need one free buffer for the next sample, so ignore the current contents @@ -75,7 +66,7 @@ private: terminate(); _bufferCount = 8; - _period = _frequency * _latency / _bufferCount / 1000.0 + 0.5; + _period = self.frequency * self.latency / _bufferCount / 1000.0 + 0.5; _buffer = new uint32_t[_period * _bufferCount]; _bufferOffset = 0; _bufferIndex = 0; @@ -94,12 +85,12 @@ private: if(deviceDetails.Role & DefaultGameDevice) deviceID = deviceIndex; } - if(FAILED(_interface->CreateMasteringVoice(&_masterVoice, _channels, (uint)_frequency, 0, deviceID, nullptr))) return terminate(), false; + if(FAILED(_interface->CreateMasteringVoice(&_masterVoice, _channels, self.frequency, 0, deviceID, nullptr))) return terminate(), false; WAVEFORMATEX waveFormat; waveFormat.wFormatTag = WAVE_FORMAT_PCM; waveFormat.nChannels = _channels; - waveFormat.nSamplesPerSec = (uint)_frequency; + waveFormat.nSamplesPerSec = self.frequency; waveFormat.nBlockAlign = 4; waveFormat.wBitsPerSample = 16; waveFormat.nAvgBytesPerSec = waveFormat.nSamplesPerSec * waveFormat.nBlockAlign; diff --git a/ruby/input/carbon.cpp b/ruby/input/carbon.cpp index cfcc0a24..0f6b88c6 100644 --- a/ruby/input/carbon.cpp +++ b/ruby/input/carbon.cpp @@ -1,6 +1,7 @@ #include "keyboard/carbon.cpp" struct InputCarbon : InputDriver { + InputCarbon& self = *this; InputCarbon(Input& super) : InputDriver(super), keyboard(super) {} ~InputCarbon() { terminate(); } @@ -37,7 +38,6 @@ private: keyboard.terminate(); } - InputCarbon& self = *this; bool isReady = false; InputKeyboardCarbon keyboard; }; diff --git a/ruby/input/quartz.cpp b/ruby/input/quartz.cpp index f7761b55..67fa04c1 100644 --- a/ruby/input/quartz.cpp +++ b/ruby/input/quartz.cpp @@ -1,6 +1,7 @@ #include "keyboard/quartz.cpp" struct InputQuartz : InputDriver { + InputQuartz& self = *this; InputQuartz(Input& super) : InputDriver(super), keyboard(super) {} ~InputQuartz() { terminate(); } @@ -37,7 +38,6 @@ private: keyboard.terminate(); } - InputQuartz& self = *this; bool isReady = false; InputKeyboardQuartz keyboard; }; diff --git a/ruby/input/sdl.cpp b/ruby/input/sdl.cpp index 3d03d811..8f725dce 100644 --- a/ruby/input/sdl.cpp +++ b/ruby/input/sdl.cpp @@ -7,6 +7,7 @@ #include "joypad/sdl.cpp" struct InputSDL : InputDriver { + InputSDL& self = *this; InputSDL(Input& super) : InputDriver(super), keyboard(super), mouse(super), joypad(super) {} ~InputSDL() { terminate(); } @@ -54,7 +55,6 @@ private: joypad.terminate(); } - InputSDL& self = *this; bool isReady = false; InputKeyboardXlib keyboard; InputMouseXlib mouse; diff --git a/ruby/input/udev.cpp b/ruby/input/udev.cpp index 82d15af9..b9bf2f40 100644 --- a/ruby/input/udev.cpp +++ b/ruby/input/udev.cpp @@ -13,6 +13,7 @@ #include "joypad/udev.cpp" struct InputUdev : InputDriver { + InputUdev& self = *this; InputUdev(Input& super) : InputDriver(super), keyboard(super), mouse(super), joypad(super) {} ~InputUdev() { terminate(); } @@ -60,7 +61,6 @@ private: joypad.terminate(); } - InputUdev& self = *this; bool isReady = false; InputKeyboardXlib keyboard; InputMouseXlib mouse; diff --git a/ruby/input/windows.cpp b/ruby/input/windows.cpp index 46471479..0e5b9ea3 100644 --- a/ruby/input/windows.cpp +++ b/ruby/input/windows.cpp @@ -9,6 +9,7 @@ #include "joypad/directinput.cpp" struct InputWindows : InputDriver { + InputWindows& self = *this; InputWindows(Input& driver) : InputDriver(super), keyboard(super), mouse(super), joypadXInput(super), joypadDirectInput(super) {} ~InputWindows() { terminate(); } @@ -63,8 +64,8 @@ private: if(!directInputContext) return false; if(!keyboard.initialize()) return false; - if(!mouse.initialize(_context)) return false; - bool xinputAvailable = _joypadXInput.initialize(); + if(!mouse.initialize(self.context)) return false; + bool xinputAvailable = joypadXInput.initialize(); if(!joypadDirectInput.initialize(self.context, directInputContext, xinputAvailable)) return false; return isReady = true; } @@ -83,7 +84,6 @@ private: } } - InputWindows& self = *this; bool isReady = false; InputKeyboardRawInput keyboard; InputMouseRawInput mouse; diff --git a/ruby/input/xlib.cpp b/ruby/input/xlib.cpp index 8f0938fc..8b1f0e7c 100644 --- a/ruby/input/xlib.cpp +++ b/ruby/input/xlib.cpp @@ -8,6 +8,7 @@ #include "mouse/xlib.cpp" struct InputXlib : InputDriver { + InputXlib& self = *this; InputXlib(Input& super) : InputDriver(super), keyboard(super), mouse(super) {} ~InputXlib() { terminate(); } @@ -52,7 +53,6 @@ private: mouse.terminate(); } - InputXlib& self = *this; bool isReady = false; InputKeyboardXlib keyboard; InputMouseXlib mouse; diff --git a/ruby/video/cgl.cpp b/ruby/video/cgl.cpp index 7e39655d..38773754 100644 --- a/ruby/video/cgl.cpp +++ b/ruby/video/cgl.cpp @@ -11,10 +11,15 @@ struct VideoCGL; -(void) reshape; @end -struct VideoCGL : Video, OpenGL { - VideoCGL() { initialize(); } +struct VideoCGL : VideoDriver, OpenGL { + VideoCGL& self = *this; + VideoCGL(Video& super) : VideoDriver(super) {} ~VideoCGL() { terminate(); } + auto create() -> bool override { + return initialize(); + } + auto driver() -> string override { return "OpenGL"; } auto ready() -> bool override { return _ready; } @@ -25,14 +30,10 @@ struct VideoCGL : Video, OpenGL { auto hasShader() -> bool override { return true; } auto setContext(uintptr context) -> bool override { - if(context == Video::context()) return true; - if(!Video::setContext(context)) return false; return initialize(); } auto setBlocking(bool blocking) -> bool override { - if(blocking == Video::blocking()) return true; - if(!Video::setBlocking(blocking)) return false; if(!view) return true; @autoreleasepool { [[view openGLContext] makeCurrentContext]; @@ -43,28 +44,21 @@ struct VideoCGL : Video, OpenGL { } auto setFlush(bool flush) -> bool override { - if(flush == Video::flush()) return true; - if(!Video::setFlush(flush)) return false; return true; } - auto setSmooth(bool smooth) -> bool override { - if(smooth == Video::smooth()) return true; - if(!Video::setSmooth(smooth)) return false; - if(!shader()) OpenGL::filter = smooth ? GL_LINEAR : GL_NEAREST; + auto setSmooth(bool) -> bool override { + if(!self.shader) OpenGL::filter = self.smooth ? GL_LINEAR : GL_NEAREST; return true; } - auto setShader(string shader) -> bool override { - if(shader == Video::shader()) return true; - if(!Video::setShader(shader)) return false; - OpenGL::setShader(shader); - if(!shader) OpenGL::filter = smooth() ? GL_LINEAR : GL_NEAREST; + auto setShader(string) -> bool override { + OpenGL::setShader(self.shader); + if(!self.shader) OpenGL::filter = self.smooth ? GL_LINEAR : GL_NEAREST; return true; } auto clear() -> void override { - if(!ready()) return; @autoreleasepool { [view lockFocus]; OpenGL::clear(); @@ -74,17 +68,14 @@ struct VideoCGL : Video, OpenGL { } auto acquire(uint32_t*& data, uint& pitch, uint width, uint height) -> bool override { - if(!ready()) return false; OpenGL::size(width, height); return OpenGL::lock(data, pitch); } auto release() -> void override { - if(!ready()) return; } auto output() -> void override { - if(!ready()) return; @autoreleasepool { if([view lockFocusIfCanDraw]) { auto area = [view convertRectToBacking:[view bounds]]; @@ -92,7 +83,7 @@ struct VideoCGL : Video, OpenGL { OpenGL::outputHeight = area.size.height; OpenGL::output(); [[view openGLContext] flushBuffer]; - if(flush()) glFinish(); + if(self.flush) glFinish(); [view unlockFocus]; } } @@ -101,7 +92,7 @@ struct VideoCGL : Video, OpenGL { private: auto initialize() -> bool { terminate(); - if(!_context) return false; + if(!self.context) return false; @autoreleasepool { NSOpenGLPixelFormatAttribute attributeList[] = { @@ -112,7 +103,7 @@ private: 0 }; - auto context = (NSView*)_context; + auto context = (NSView*)self.context; auto size = [context frame].size; auto format = [[[NSOpenGLPixelFormat alloc] initWithAttributes:attributeList] autorelease]; auto openGLContext = [[[NSOpenGLContext alloc] initWithFormat:format shareContext:nil] autorelease]; @@ -129,7 +120,7 @@ private: OpenGL::initialize(); - int blocking = _blocking; + int blocking = self.blocking; [[view openGLContext] setValues:&blocking forParameter:NSOpenGLCPSwapInterval]; [view unlockFocus]; diff --git a/ruby/video/direct3d.cpp b/ruby/video/direct3d.cpp index a357fb26..4258d9fc 100644 --- a/ruby/video/direct3d.cpp +++ b/ruby/video/direct3d.cpp @@ -7,10 +7,15 @@ static LRESULT CALLBACK VideoDirect3D_WindowProcedure(HWND hwnd, UINT msg, WPARA return DefWindowProc(hwnd, msg, wparam, lparam); } -struct VideoDirect3D : Video { - VideoDirect3D() { initialize(); } +struct VideoDirect3D : VideoDriver { + VideoDirect3D& self = *this; + VideoDirect3D(Video& super) : VideoDriver(super) {} ~VideoDirect3D() { terminate(); } + auto create() -> bool override { + return initialize(); + } + auto driver() -> string override { return "Direct3D"; } auto ready() -> bool override { return _ready; } @@ -19,30 +24,10 @@ struct VideoDirect3D : Video { auto hasBlocking() -> bool override { return true; } auto hasSmooth() -> bool override { return true; } - auto setExclusive(bool exclusive) -> bool override { - if(exclusive == Video::exclusive()) return true; - if(!Video::setExclusive(exclusive)) return false; - return initialize(); - } - - auto setContext(uintptr context) -> bool override { - if(context == Video::context()) return true; - if(!Video::setContext(context)) return false; - return initialize(); - } - - auto setBlocking(bool blocking) -> bool override { - if(blocking == Video::blocking()) return true; - if(!Video::setBlocking(blocking)) return false; - return true; - } - - auto setSmooth(bool smooth) -> bool override { - if(smooth == Video::smooth()) return true; - if(!Video::setSmooth(smooth)) return false; - if(ready()) updateFilter(); - return true; - } + auto setExclusive(bool exclusive) -> bool override { return initialize(); } + auto setContext(uintptr context) -> bool override { return initialize(); } + auto setBlocking(bool blocking) -> bool override { return true; } + auto setSmooth(bool smooth) -> bool override { return updateFilter(); } auto clear() -> void override { if(!ready()) return; @@ -66,7 +51,6 @@ struct VideoDirect3D : Video { } auto acquire(uint32_t*& data, uint& pitch, uint width, uint height) -> bool override { - if(!ready()) return false; if(_lost && !recover()) return false; //if output size changed, driver must be re-initialized. @@ -90,14 +74,12 @@ struct VideoDirect3D : Video { } auto release() -> void override { - if(!ready()) return; _surface->UnlockRect(); _surface->Release(); _surface = nullptr; } auto output() -> void override { - if(!ready()) return; if(_lost && !recover()) return; _device->BeginScene(); @@ -183,13 +165,14 @@ private: (D3DPOOL)_texturePool, &_texture, nullptr); } - auto updateFilter() -> void { - if(!_device) return; - if(_lost && !recover()) return; + auto updateFilter() -> bool { + if(!_device) return false; + if(_lost && !recover()) return false; auto filter = !_smooth ? D3DTEXF_POINT : D3DTEXF_LINEAR; _device->SetSamplerState(0, D3DSAMP_MINFILTER, filter); _device->SetSamplerState(0, D3DSAMP_MAGFILTER, filter); + return true; } //(x,y) screen coordinates, in pixels diff --git a/ruby/video/directdraw.cpp b/ruby/video/directdraw.cpp index 48261cf6..b23b9e34 100644 --- a/ruby/video/directdraw.cpp +++ b/ruby/video/directdraw.cpp @@ -1,10 +1,15 @@ #include #undef interface -struct VideoDirectDraw : Video { - VideoDirectDraw() { initialize(); } +struct VideoDirectDraw : VideoDriver { + VideoDirectDraw& self = *this; + VideoDirectDraw(Video& super) : VideoDriver(super) {} ~VideoDirectDraw() { terminate(); } + auto create() -> bool override { + return initialize(); + } + auto driver() -> string override { return "DirectDraw"; } auto ready() -> bool override { return _ready; } @@ -12,19 +17,14 @@ struct VideoDirectDraw : Video { auto hasBlocking() -> bool override { return true; } auto setContext(uintptr context) -> bool override { - if(context == Video::context()) return true; - if(!Video::setContext(context)) return false; return initialize(); } auto setBlocking(bool blocking) -> bool override { - if(blocking == Video::blocking()) return true; - if(!Video::setBlocking(blocking)) return false; return true; } auto clear() -> void override { - if(!ready()) return; DDBLTFX fx = {}; fx.dwSize = sizeof(DDBLTFX); fx.dwFillColor = 0x00000000; @@ -33,7 +33,6 @@ struct VideoDirectDraw : Video { } auto acquire(uint32_t*& data, uint& pitch, uint width, uint height) -> bool override { - if(!ready()) return false; if(width != _width || height != _height) resize(_width = width, _height = height); DDSURFACEDESC2 description = {}; description.dwSize = sizeof(DDSURFACEDESC2); @@ -46,13 +45,11 @@ struct VideoDirectDraw : Video { } auto release() -> void override { - if(!ready()) return; _raster->Unlock(0); } auto output() -> void override { - if(!ready()) return; - if(_blocking) while(true) { + if(self.blocking) while(true) { BOOL vblank; _interface->GetVerticalBlankStatus(&vblank); if(vblank) break; @@ -62,10 +59,10 @@ struct VideoDirectDraw : Video { SetRect(&source, 0, 0, _width, _height); POINT point = {0, 0}; - ClientToScreen((HWND)_context, &point); + ClientToScreen((HWND)self.context, &point); RECT target; - GetClientRect((HWND)_context, &target); + GetClientRect((HWND)self.context, &target); OffsetRect(&target, point.x, point.y); if(_screen->Blt(&target, _raster, &source, DDBLT_WAIT, 0) == DDERR_SURFACELOST) { @@ -77,14 +74,14 @@ struct VideoDirectDraw : Video { private: auto initialize() -> bool { terminate(); - if(!_context) return false; + if(!self.context) return false; LPDIRECTDRAW interface = nullptr; DirectDrawCreate(0, &interface, 0); interface->QueryInterface(IID_IDirectDraw7, (void**)&_interface); interface->Release(); - _interface->SetCooperativeLevel((HWND)_context, DDSCL_NORMAL); + _interface->SetCooperativeLevel((HWND)self.context, DDSCL_NORMAL); DDSURFACEDESC2 description = {}; description.dwSize = sizeof(DDSURFACEDESC2); @@ -93,7 +90,7 @@ private: _interface->CreateSurface(&description, &_screen, 0); _interface->CreateClipper(0, &_clipper, 0); - _clipper->SetHWnd(0, (HWND)_context); + _clipper->SetHWnd(0, (HWND)self.context); _screen->SetClipper(_clipper); _raster = nullptr; diff --git a/ruby/video/gdi.cpp b/ruby/video/gdi.cpp index 7731f1fd..8e4a9f2a 100644 --- a/ruby/video/gdi.cpp +++ b/ruby/video/gdi.cpp @@ -1,25 +1,20 @@ -struct VideoGDI : Video { - VideoGDI() { initialize(); } +struct VideoGDI : VideoDriver { + VideoGDI& self = *this; + VideoGDI(Video& super) : VideoDriver(super) {} ~VideoGDI() { terminate(); } + auto create() -> bool override { + return initialize(); + } + auto driver() -> string override { return "GDI"; } auto ready() -> bool override { return _ready; } auto hasContext() -> bool override { return true; } - auto setContext(uintptr context) -> bool override { - if(context == Video::context()) return true; - if(!Video::setContext(context)) return false; - return initialize(); - } - - auto clear() -> void override { - if(!ready()) return; - } + auto setContext(uintptr context) -> bool override { return initialize(); } auto acquire(uint32_t*& data, uint& pitch, uint width, uint height) -> bool override { - if(!ready()) return false; - if(!_buffer || _width != width || _height != height) { if(_buffer) delete[] _buffer; if(_bitmap) DeleteObject(_bitmap); @@ -29,11 +24,11 @@ struct VideoGDI : Video { _width = width; _height = height; - HDC hdc = GetDC((HWND)_context); + HDC hdc = GetDC((HWND)self.context); _dc = CreateCompatibleDC(hdc); _bitmap = CreateCompatibleBitmap(hdc, width, height); SelectObject(_dc, _bitmap); - ReleaseDC((HWND)_context, hdc); + ReleaseDC((HWND)self.context, hdc); memory::fill(&_info, sizeof(BITMAPINFO)); _info.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); @@ -50,25 +45,22 @@ struct VideoGDI : Video { } auto release() -> void override { - if(!ready()) return; } auto output() -> void override { - if(!ready()) return; - RECT rc; - GetClientRect((HWND)_context, &rc); + GetClientRect((HWND)self.context, &rc); SetDIBits(_dc, _bitmap, 0, _height, (void*)_buffer, &_info, DIB_RGB_COLORS); - HDC hdc = GetDC((HWND)_context); + HDC hdc = GetDC((HWND)self.context); StretchBlt(hdc, rc.left, rc.top, rc.right, rc.bottom, _dc, 0, 0, _width, _height, SRCCOPY); - ReleaseDC((HWND)_context, hdc); + ReleaseDC((HWND)self.context, hdc); } private: auto initialize() -> bool { terminate(); - if(!_context) return false; + if(!self.context) return false; _width = 0; _height = 0; diff --git a/ruby/video/glx.cpp b/ruby/video/glx.cpp index 4b5bf714..cb4bc196 100644 --- a/ruby/video/glx.cpp +++ b/ruby/video/glx.cpp @@ -7,47 +7,43 @@ auto VideoGLX_X11ErrorHandler(Display*, XErrorEvent*) -> int { return 0; //suppress errors } -struct VideoGLX : Video, OpenGL { - VideoGLX() { initialize(); } +struct VideoGLX : VideoDriver, OpenGL { + VideoGLX& self = *this; + VideoGLX(Video& super) : VideoDriver(super) {} ~VideoGLX() { terminate(); } + auto create() -> bool override { + super.setFormat("RGB24"); + return initialize(); + } + auto driver() -> string override { return "OpenGL"; } auto ready() -> bool override { return _ready; } auto hasContext() -> bool override { return true; } auto hasBlocking() -> bool override { return true; } auto hasFlush() -> bool override { return true; } - auto hasFormat() -> bool override { return true; } auto hasSmooth() -> bool override { return true; } auto hasShader() -> bool override { return true; } - auto availableFormats() -> vector override { - return {"RGB24", "RGB30"}; + auto hasFormats() -> vector override { + return {"RGB24"}; //"RGB30" } auto setContext(uintptr context) -> bool override { - if(context == Video::context()) return true; - if(!Video::setContext(context)) return false; return initialize(); } auto setBlocking(bool blocking) -> bool override { - if(blocking == Video::blocking()) return true; - if(!Video::setBlocking(blocking)) return false; if(glXSwapInterval) glXSwapInterval(blocking); return true; } auto setFlush(bool flush) -> bool override { - if(flush == Video::flush()) return true; - if(!Video::setFlush(flush)) return false; return true; } auto setFormat(string format) -> bool override { - if(format == Video::format()) return true; - if(!Video::setFormat(format)) return false; - if(format == "RGB24") { OpenGL::inputFormat = GL_RGBA8; return true; @@ -61,46 +57,37 @@ struct VideoGLX : Video, OpenGL { return false; } - auto setSmooth(bool smooth) -> bool override { - if(smooth == Video::smooth()) return true; - if(!Video::setSmooth(smooth)) return false; - if(!shader()) OpenGL::filter = smooth ? GL_LINEAR : GL_NEAREST; + auto setSmooth(bool) -> bool override { + if(!self.shader) OpenGL::filter = self.smooth ? GL_LINEAR : GL_NEAREST; return true; } - auto setShader(string shader) -> bool override { - if(shader == Video::shader()) return true; - if(!Video::setShader(shader)) return false; - OpenGL::setShader(shader); - if(!shader) OpenGL::filter = smooth() ? GL_LINEAR : GL_NEAREST; + auto setShader(string) -> bool override { + OpenGL::setShader(self.shader); + if(!self.shader) OpenGL::filter = self.smooth ? GL_LINEAR : GL_NEAREST; return true; } auto clear() -> void override { - if(!ready()) return; OpenGL::clear(); if(_doubleBuffer) glXSwapBuffers(_display, _glXWindow); } auto acquire(uint32_t*& data, uint& pitch, uint width, uint height) -> bool override { - if(!ready()) return false; OpenGL::size(width, height); return OpenGL::lock(data, pitch); } auto release() -> void override { - if(!ready()) return; } auto output() -> void override { - if(!ready()) return; - //we must ensure that the child window is the same size as the parent window. //unfortunately, we cannot hook the parent window resize event notification, //as we did not create the parent window, nor have any knowledge of the toolkit used. //therefore, inelegant as it may be, we query each window size and resize as needed. XWindowAttributes parent, child; - XGetWindowAttributes(_display, (Window)_context, &parent); + XGetWindowAttributes(_display, (Window)self.context, &parent); XGetWindowAttributes(_display, (Window)_window, &child); if(child.width != parent.width || child.height != parent.height) { XResizeWindow(_display, _window, parent.width, parent.height); @@ -110,7 +97,7 @@ struct VideoGLX : Video, OpenGL { OpenGL::outputHeight = parent.height; OpenGL::output(); if(_doubleBuffer) glXSwapBuffers(_display, _glXWindow); - if(flush()) glFinish(); + if(self.flush) glFinish(); } auto poll() -> void override { @@ -120,7 +107,7 @@ struct VideoGLX : Video, OpenGL { if(event.type == Expose) { XWindowAttributes attributes; XGetWindowAttributes(_display, _window, &attributes); - doUpdate(attributes.width, attributes.height); + super.doUpdate(attributes.width, attributes.height); } } } @@ -128,7 +115,7 @@ struct VideoGLX : Video, OpenGL { private: auto initialize() -> bool { terminate(); - if(!_context) return false; + if(!self.context) return false; _display = XOpenDisplay(nullptr); _screen = DefaultScreen(_display); @@ -138,11 +125,11 @@ private: if(_versionMajor < 1 || (_versionMajor == 1 && _versionMinor < 2)) return false; XWindowAttributes windowAttributes; - XGetWindowAttributes(_display, (Window)_context, &windowAttributes); + XGetWindowAttributes(_display, (Window)self.context, &windowAttributes); - int redDepth = Video::format() == "RGB30" ? 10 : 8; - int greenDepth = Video::format() == "RGB30" ? 10 : 8; - int blueDepth = Video::format() == "RGB30" ? 10 : 8; + int redDepth = VideoDriver::format == "RGB30" ? 10 : 8; + int greenDepth = VideoDriver::format == "RGB30" ? 10 : 8; + int blueDepth = VideoDriver::format == "RGB30" ? 10 : 8; //let GLX determine the best Visual to use for GL output; provide a few hints //note: some video drivers will override double buffering attribute @@ -162,7 +149,7 @@ private: XVisualInfo* vi = glXGetVisualFromFBConfig(_display, fbConfig[0]); - //(Window)_context has already been realized, most likely with DefaultVisual. + //(Window)self.context has already been realized, most likely with DefaultVisual. //GLX requires that the GL output window has the same Visual as the GLX context. //it is not possible to change the Visual of an already realized (created) window. //therefore a new child window, using the same GLX Visual, must be created and binded to it. @@ -170,7 +157,7 @@ private: XSetWindowAttributes attributes = {}; attributes.colormap = _colormap; attributes.border_pixel = 0; - _window = XCreateWindow(_display, /* parent = */ (Window)_context, + _window = XCreateWindow(_display, /* parent = */ (Window)self.context, /* x = */ 0, /* y = */ 0, windowAttributes.width, windowAttributes.height, /* border_width = */ 0, vi->depth, InputOutput, vi->visual, CWColormap | CWBorderPixel, &attributes); @@ -219,7 +206,7 @@ private: return false; } - if(glXSwapInterval) glXSwapInterval(_blocking); + if(glXSwapInterval) glXSwapInterval(self.blocking); //read attributes of frame buffer for later use, as requested attributes from above are not always granted int value = 0; diff --git a/ruby/video/glx2.cpp b/ruby/video/glx2.cpp index b09addc7..db70d685 100644 --- a/ruby/video/glx2.cpp +++ b/ruby/video/glx2.cpp @@ -22,6 +22,7 @@ #endif struct VideoGLX2 : VideoDriver { + VideoGLX2& self = *this; VideoGLX2(Video& super) : VideoDriver(super) {} ~VideoGLX2() { terminate(); } @@ -260,8 +261,6 @@ private: glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, _glWidth, _glHeight, 0, GL_BGRA, _glFormat, _glBuffer); } - VideoGLX2& self = *this; - bool _ready = false; Display* _display = nullptr; diff --git a/ruby/video/wgl.cpp b/ruby/video/wgl.cpp index 9da15220..3e66b922 100644 --- a/ruby/video/wgl.cpp +++ b/ruby/video/wgl.cpp @@ -3,10 +3,15 @@ #define WGL_CONTEXT_MAJOR_VERSION_ARB 0x2091 #define WGL_CONTEXT_MINOR_VERSION_ARB 0x2092 -struct VideoWGL : Video, OpenGL { - VideoWGL() { initialize(); } +struct VideoWGL : VideoDriver, OpenGL { + VideoWGL& self = *this; + VideoWGL(Video& super) : VideoDriver(super) {} ~VideoWGL() { terminate(); } + auto create() -> bool override { + return initialize(); + } + auto driver() -> string override { return "OpenGL"; } auto ready() -> bool override { return _ready; } @@ -17,70 +22,56 @@ struct VideoWGL : Video, OpenGL { auto hasShader() -> bool override { return true; } auto setContext(uintptr context) -> bool override { - if(context == Video::context()) return true; - if(!Video::setContext(context)) return false; return initialize(); } auto setBlocking(bool blocking) -> bool override { - if(blocking == Video::blocking()) return true; - if(!Video::setBlocking(blocking)) return false; if(wglSwapInterval) wglSwapInterval(blocking); return true; } auto setFlush(bool flush) -> bool override { - if(flush == Video::flush()) return true; - if(!Video::setFlush(flush)) return false; return true; } - auto setSmooth(bool smooth) -> bool override { - if(smooth == Video::smooth()) return true; - if(!Video::setSmooth(smooth)) return false; - if(!shader()) OpenGL::filter = smooth ? GL_LINEAR : GL_NEAREST; + auto setSmooth(bool) -> bool override { + if(!self.shader) OpenGL::filter = self.smooth ? GL_LINEAR : GL_NEAREST; return true; } - auto setShader(string shader) -> bool override { - if(shader == Video::shader()) return true; - if(!Video::setShader(shader)) return false; - OpenGL::setShader(shader); - if(!shader) OpenGL::filter = smooth() ? GL_LINEAR : GL_NEAREST; + auto setShader(string) -> bool override { + OpenGL::setShader(self.shader); + if(!self.shader) OpenGL::filter = self.smooth ? GL_LINEAR : GL_NEAREST; return true; } auto clear() -> void override { - if(!ready()) return; OpenGL::clear(); SwapBuffers(_display); } auto acquire(uint32_t*& data, uint& pitch, uint width, uint height) -> bool override { - if(!ready()) return false; OpenGL::size(width, height); return OpenGL::lock(data, pitch); } auto release() -> void override { - if(!ready()) return; } auto output() -> void override { - if(!ready()) return; RECT rectangle; - GetClientRect((HWND)_context, &rectangle); + GetClientRect((HWND)self.context, &rectangle); OpenGL::outputWidth = rectangle.right - rectangle.left; OpenGL::outputHeight = rectangle.bottom - rectangle.top; OpenGL::output(); SwapBuffers(_display); - if(flush()) glFinish(); + if(self.flush) glFinish(); } private: auto initialize() -> bool { terminate(); - if(!_context) return false; + if(!self.context) return false; PIXELFORMATDESCRIPTOR descriptor = {}; descriptor.nSize = sizeof(PIXELFORMATDESCRIPTOR); @@ -88,7 +79,7 @@ private: descriptor.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER; descriptor.iPixelType = PFD_TYPE_RGBA; - _display = GetDC((HWND)_context); + _display = GetDC((HWND)self.context); GLuint pixelFormat = ChoosePixelFormat(_display, &descriptor); SetPixelFormat(_display, pixelFormat, &descriptor); @@ -112,7 +103,7 @@ private: } } - if(wglSwapInterval) wglSwapInterval(_blocking); + if(wglSwapInterval) wglSwapInterval(self.blocking); return _ready = OpenGL::initialize(); } diff --git a/ruby/video/xshm.cpp b/ruby/video/xshm.cpp index bddcd454..7d581572 100644 --- a/ruby/video/xshm.cpp +++ b/ruby/video/xshm.cpp @@ -9,10 +9,11 @@ #include struct VideoXShm : VideoDriver { + VideoXShm& self = *this; VideoXShm(Video& super) : VideoDriver(super) {} ~VideoXShm() { terminate(); } - auto create() -> bool { + auto create() -> bool override { return initialize(); } @@ -184,8 +185,6 @@ private: return cr << 16 | cg << 8 | cb << 0; } - VideoXShm& self = *this; - bool _ready = false; uint32_t* _inputBuffer = nullptr; diff --git a/ruby/video/xvideo.cpp b/ruby/video/xvideo.cpp index 2b80bf8c..cfe60b28 100644 --- a/ruby/video/xvideo.cpp +++ b/ruby/video/xvideo.cpp @@ -6,36 +6,35 @@ extern "C" auto XvShmCreateImage(Display*, XvPortID, int, char*, int, int, XShmSegmentInfo*) -> XvImage*; -struct VideoXVideo : Video { - VideoXVideo() { initialize(); } +struct VideoXVideo : VideoDriver { + VideoXVideo& self = *this; + VideoXVideo(Video& super) : VideoDriver(super) {} ~VideoXVideo() { terminate(); } + auto create() -> bool override { + return initialize(); + } + auto driver() -> string override { return "XVideo"; } auto ready() -> bool override { return _ready; } auto hasContext() -> bool override { return true; } auto hasBlocking() -> bool override { return true; } - auto hasFormat() -> bool override { return true; } - auto availableFormats() -> vector override { + auto hasFormats() -> vector override { return _formatNames; } auto setContext(uintptr context) -> bool override { - if(context == Video::context()) return true; - if(!Video::setContext(context)) return false; return initialize(); } auto setBlocking(bool blocking) -> bool override { - if(blocking == Video::blocking()) return true; - if(!Video::setBlocking(blocking)) return false; - bool result = false; Display* display = XOpenDisplay(nullptr); Atom atom = XInternAtom(display, "XV_SYNC_TO_VBLANK", true); if(atom != None && _port >= 0) { - XvSetPortAttribute(display, _port, atom, _blocking); + XvSetPortAttribute(display, _port, atom, self.blocking); result = true; } XCloseDisplay(display); @@ -43,13 +42,10 @@ struct VideoXVideo : Video { } auto setFormat(string format) -> bool override { - if(format == Video::format()) return true; - if(!Video::setFormat(format)) return false; return initialize(); } auto clear() -> void override { - if(!ready()) return; memory::fill(_buffer, _bufferWidth * _bufferHeight); //clear twice in case video is double buffered ... output(); @@ -57,19 +53,15 @@ struct VideoXVideo : Video { } auto acquire(uint32_t*& data, uint& pitch, uint width, uint height) -> bool override { - if(!ready()) return false; if(width != _width || height != _height) resize(_width = width, _height = height); pitch = _bufferWidth * 4; return data = _buffer; } auto release() -> void override { - if(!ready()) return; } auto output() -> void override { - if(!ready()) return; - XWindowAttributes target; XGetWindowAttributes(_display, _window, &target); @@ -78,7 +70,7 @@ struct VideoXVideo : Video { //as we did not create the parent window, nor have any knowledge of the toolkit used. //therefore, query each window size and resize as needed. XWindowAttributes parent; - XGetWindowAttributes(_display, (Window)_context, &parent); + XGetWindowAttributes(_display, (Window)self.context, &parent); if(target.width != parent.width || target.height != parent.height) { XResizeWindow(_display, _window, parent.width, parent.height); } @@ -109,7 +101,7 @@ struct VideoXVideo : Video { if(event.type == Expose) { XWindowAttributes attributes; XGetWindowAttributes(_display, _window, &attributes); - doUpdate(attributes.width, attributes.height); + super.doUpdate(attributes.width, attributes.height); } } } @@ -117,7 +109,7 @@ struct VideoXVideo : Video { private: auto initialize() -> bool { terminate(); - if(!_context) return false; + if(!self.context) return false; _display = XOpenDisplay(nullptr); @@ -154,7 +146,7 @@ private: //this is so that even if parent window visual depth doesn't match Xv visual //(common with composited windows), Xv can still render to child window. XWindowAttributes windowAttributes; - XGetWindowAttributes(_display, (Window)_context, &windowAttributes); + XGetWindowAttributes(_display, (Window)self.context, &windowAttributes); XVisualInfo visualTemplate; visualTemplate.visualid = visualID; @@ -169,11 +161,11 @@ private: return false; } - _colormap = XCreateColormap(_display, (Window)_context, visualInfo->visual, AllocNone); + _colormap = XCreateColormap(_display, (Window)self.context, visualInfo->visual, AllocNone); XSetWindowAttributes attributes = {}; attributes.colormap = _colormap; attributes.border_pixel = 0; - _window = XCreateWindow(_display, /* parent = */ (Window)_context, + _window = XCreateWindow(_display, /* parent = */ (Window)self.context, /* x = */ 0, /* y = */ 0, windowAttributes.width, windowAttributes.height, /* border_width = */ 0, depth, InputOutput, visualInfo->visual, CWColormap | CWBorderPixel | CWEventMask, &attributes); @@ -200,13 +192,13 @@ private: print("XVideo: unable to find a supported image format.\n"); return false; } - if(auto match = _formatNames.find(Video::format())) { + if(auto match = _formatNames.find(self.format)) { _formatID = _formatIDs[match()]; _formatName = _formatNames[match()]; } else { _formatID = _formatIDs[0]; _formatName = _formatNames[0]; - Video::setFormat(_formatName); + self.format = _formatName; } _ready = true;