Update to v089r12 release.

byuu says:

Changelog:
- Game Boy XML uses <cartridge><board type="MBC3"/> instead of
  <cartridge mapper="MBC3">
- if you run bsnes with a filename argument, it will invoke "purify
  filename" and exit immediately
  - this chains: purify will turn the file into a game folder, and then
    invoke bsnes with the game folder name
    - net result: you can drag a ZIP file onto bsnes or associate SMC
      headered ROMs with bsnes and they'll just work
- new nall: unified usage of - vs _ vs nothing on filenames; fancier
  lstring; fancier image (constructor for creating from filename or from
  memory); etc
- new phoenix: images in ListView, GTK+ merges the check box into the
  first column like the other targets do, etc
- browser list now uses icons to differentiate system folders from game
  folders (the game folder icon sucks, I'm open to suggestions though,
  as long as it's available on Debian Squeeze in /usr/share/icons, no
  custom stuff please)
This commit is contained in:
Tim Allen 2012-06-18 20:13:51 +10:00
parent ec8350794a
commit 36795e8061
57 changed files with 892 additions and 1427 deletions

View File

@ -3,7 +3,7 @@
namespace Emulator {
static const char Name[] = "bsnes";
static const char Version[] = "089.11";
static const char Version[] = "089.12";
static const char Author[] = "byuu";
static const char License[] = "GPLv3";
}
@ -15,7 +15,7 @@ namespace Emulator {
#include <nall/endian.hpp>
#include <nall/file.hpp>
#include <nall/function.hpp>
#include <nall/priorityqueue.hpp>
#include <nall/priority-queue.hpp>
#include <nall/property.hpp>
#include <nall/random.hpp>
#include <nall/serializer.hpp>

View File

@ -27,7 +27,7 @@ void Cartridge::load(System::Revision revision, const string &manifest) {
XML::Document document(manifest);
auto &mapperid = document["cartridge"]["mapper"].data;
auto &mapperid = document["cartridge"]["board"]["type"].data;
if(mapperid == "none" ) information.mapper = Mapper::MBC0;
if(mapperid == "MBC1" ) information.mapper = Mapper::MBC1;
if(mapperid == "MBC2" ) information.mapper = Mapper::MBC2;
@ -37,8 +37,8 @@ void Cartridge::load(System::Revision revision, const string &manifest) {
if(mapperid == "HuC1" ) information.mapper = Mapper::HuC1;
if(mapperid == "HuC3" ) information.mapper = Mapper::HuC3;
information.rtc = document["cartridge"]["rtc"].data == "true";
information.rumble = document["cartridge"]["rumble"].data == "true";
information.rtc = false;
information.rumble = false;
auto &rom = document["cartridge"]["rom"];
auto &ram = document["cartridge"]["ram"];

View File

@ -2,7 +2,7 @@
#define NALL_ANY_HPP
#include <typeinfo>
#include <nall/type_traits.hpp>
#include <nall/traits.hpp>
namespace nall {
struct any {

View File

@ -17,7 +17,7 @@
namespace nall {
struct directory {
static bool create(const string &pathname, unsigned permissions = 0755);
static bool create(const string &pathname, unsigned permissions = 0755); //recursive
static bool remove(const string &pathname);
static bool exists(const string &pathname);
static lstring folders(const string &pathname, const string &pattern = "*");
@ -27,7 +27,16 @@ struct directory {
#if defined(PLATFORM_WINDOWS)
inline bool directory::create(const string &pathname, unsigned permissions) {
return _wmkdir(utf16_t(pathname)) == 0;
string fullpath = pathname, path;
fullpath.transform("/", "\\");
fullpath.rtrim<1>("\\");
lstring pathpart = fullpath.split("\\");
bool result = false;
for(auto &part : pathpart) {
path.append(part, "\\");
result = _wmkdir(utf16_t(path)) == 0;
}
return result;
}
inline bool directory::remove(const string &pathname) {
@ -105,7 +114,14 @@ struct directory {
}
#else
inline bool directory::create(const string &pathname, unsigned permissions) {
return mkdir(pathname, permissions) == 0;
string fullpath = pathname, path = "/";
fullpath.trim<1>("/");
lstring pathpart = fullpath.split("/");
for(auto &part : pathpart) {
if(!directory::exists(path)) mkdir(path, permissions);
path.append(part, "/");
}
return mkdir(path, permissions) == 0;
}
inline bool directory::remove(const string &pathname) {

View File

@ -1,13 +1,22 @@
#ifndef NALL_NES_CARTRIDGE_HPP
#define NALL_NES_CARTRIDGE_HPP
#ifndef NALL_EMULATION_FAMICOM_HPP
#define NALL_EMULATION_FAMICOM_HPP
#include <nall/sha256.hpp>
#include <nall/string.hpp>
namespace nall {
struct FamicomCartridge {
string markup;
inline FamicomCartridge(const uint8_t *data, unsigned size);
//private:
unsigned mapper;
unsigned mirror;
unsigned prgrom;
unsigned prgram;
unsigned chrrom;
unsigned chrram;
};
FamicomCartridge::FamicomCartridge(const uint8_t *data, unsigned size) {
@ -18,12 +27,12 @@ FamicomCartridge::FamicomCartridge(const uint8_t *data, unsigned size) {
if(data[2] != 'S') return;
if(data[3] != 26) return;
unsigned mapper = ((data[7] >> 4) << 4) | (data[6] >> 4);
unsigned mirror = ((data[6] & 0x08) >> 2) | (data[6] & 0x01);
unsigned prgrom = data[4] * 0x4000;
unsigned chrrom = data[5] * 0x2000;
unsigned prgram = 0u;
unsigned chrram = chrrom == 0u ? 8192u : 0u;
mapper = ((data[7] >> 4) << 4) | (data[6] >> 4);
mirror = ((data[6] & 0x08) >> 2) | (data[6] & 0x01);
prgrom = data[4] * 0x4000;
chrrom = data[5] * 0x2000;
prgram = 0u;
chrram = chrrom == 0u ? 8192u : 0u;
markup.append("<cartridge sha256='", sha256(data, size), "'>\n");
@ -153,13 +162,13 @@ FamicomCartridge::FamicomCartridge(const uint8_t *data, unsigned size) {
}
markup.append(" <prg>\n");
if(prgrom) markup.append(" <rom size='", prgrom, "'/>\n");
if(prgram) markup.append(" <ram size='", prgram, "' nonvolatile='true'/>\n");
if(prgrom) markup.append(" <rom name='program.rom' size='0x", hex(prgrom), "'/>\n");
if(prgram) markup.append(" <ram name='save.ram' size='0x", hex(prgram), "'/>\n");
markup.append(" </prg>\n");
markup.append(" <chr>\n");
if(chrrom) markup.append(" <rom size='", chrrom, "'/>\n");
if(chrram) markup.append(" <ram size='", chrram, "'/>\n");
if(chrrom) markup.append(" <rom name='character.rom' size='0x", hex(chrrom), "'/>\n");
if(chrram) markup.append(" <ram size='0x", hex(chrram), "'/>\n");
markup.append(" </chr>\n");
markup.append("</cartridge>\n");

View File

@ -1,7 +1,8 @@
#ifndef NALL_GBA_CARTRIDGE_HPP
#define NALL_GBA_CARTRIDGE_HPP
#ifndef NALL_EMULATION_GAME_BOY_ADVANCE_HPP
#define NALL_EMULATION_GAME_BOY_ADVANCE_HPP
#include <nall/sha256.hpp>
#include <nall/string.hpp>
#include <nall/vector.hpp>
namespace nall {
@ -46,14 +47,14 @@ GameBoyAdvanceCartridge::GameBoyAdvanceCartridge(const uint8_t *data, unsigned s
markup = "<?xml version='1.0' encoding='UTF-8'?>\n";
markup.append("<cartridge sha256='", sha256(data, size), "'>\n");
markup.append(" <rom size='", size, "'/>\n");
markup.append(" <rom name='program.rom' size='0x", hex(size), "'/>\n");
if(0);
else if(identifiers.beginswith("SRAM_V" )) markup.append(" <ram type='SRAM' size='32768'/>\n");
else if(identifiers.beginswith("SRAM_F_V" )) markup.append(" <ram type='FRAM' size='32768'/>\n");
else if(identifiers.beginswith("EEPROM_V" )) markup.append(" <ram type='EEPROM' size='0'/>\n");
else if(identifiers.beginswith("FLASH_V" )) markup.append(" <ram type='FlashROM' size='65536'/>\n");
else if(identifiers.beginswith("FLASH512_V")) markup.append(" <ram type='FlashROM' size='65536'/>\n");
else if(identifiers.beginswith("FLASH1M_V" )) markup.append(" <ram type='FlashROM' size='131072'/>\n");
else if(identifiers.beginswith("SRAM_V" )) markup.append(" <ram name='save.ram' type='SRAM' size='0x8000'/>\n");
else if(identifiers.beginswith("SRAM_F_V" )) markup.append(" <ram name='save.ram' type='FRAM' size='0x8000'/>\n");
else if(identifiers.beginswith("EEPROM_V" )) markup.append(" <ram name='save.ram' type='EEPROM' size='0x0'/>\n");
else if(identifiers.beginswith("FLASH_V" )) markup.append(" <ram name='save.ram' type='FlashROM' size='0x10000'/>\n");
else if(identifiers.beginswith("FLASH512_V")) markup.append(" <ram name='save.ram' type='FlashROM' size='0x10000'/>\n");
else if(identifiers.beginswith("FLASH1M_V" )) markup.append(" <ram name='save.ram' type='FlashROM' size='0x20000'/>\n");
if(identifiers.empty() == false) markup.append(" <!-- detected: ", identifiers, " -->\n");
markup.append("</cartridge>\n");

View File

@ -1,5 +1,8 @@
#ifndef NALL_GB_CARTRIDGE_HPP
#define NALL_GB_CARTRIDGE_HPP
#ifndef NALL_EMULATION_GAME_BOY_HPP
#define NALL_EMULATION_GAME_BOY_HPP
#include <nall/sha256.hpp>
#include <nall/string.hpp>
namespace nall {
@ -17,6 +20,9 @@ struct GameBoyCartridge {
unsigned romsize;
unsigned ramsize;
bool cgb;
bool cgbonly;
} info;
};
@ -47,6 +53,9 @@ GameBoyCartridge::GameBoyCartridge(uint8_t *romdata, unsigned romsize) {
memcpy(romdata, header, 0x8000);
}
info.cgb = (romdata[0x0143] & 0x80) == 0x80;
info.cgbonly = (romdata[0x0143] & 0xc0) == 0xc0;
switch(romdata[0x0147]) {
case 0x00: info.mapper = "none"; break;
case 0x01: info.mapper = "MBC1"; break;
@ -100,9 +109,10 @@ GameBoyCartridge::GameBoyCartridge(uint8_t *romdata, unsigned romsize) {
if(info.mapper == "MBC2") info.ramsize = 512; //512 x 4-bit
markup = "<?xml version='1.0' encoding='UTF-8'?>\n";
markup.append("<cartridge mapper='", info.mapper, "' rtc='", info.rtc, "' rumble='", info.rumble, "'>\n");
markup.append(" <rom size='0x", hex(romsize), "'/>\n");
if(info.ramsize > 0) markup.append(" <ram size='0x", hex(info.ramsize), "' nonvolatile='", info.battery, "'/>\n");
markup.append("<cartridge>\n");
markup.append(" <board type='", info.mapper, "'/>\n");
markup.append(" <rom name='program.rom' size='0x", hex(romsize), "'/>\n");
if(info.ramsize > 0) markup.append(" <ram name='save.ram' size='0x", hex(info.ramsize), "'/>\n");
markup.append("</cartridge>\n");
markup.transform("'", "\"");
}

View File

@ -1,5 +1,5 @@
#ifndef NALL_SNES_USART_HPP
#define NALL_SNES_USART_HPP
#ifndef NALL_EMULATION_SUPER_FAMICOM_USART_HPP
#define NALL_EMULATION_SUPER_FAMICOM_USART_HPP
#include <nall/platform.hpp>
#include <nall/function.hpp>

View File

@ -1,5 +1,8 @@
#ifndef NALL_SNES_CARTRIDGE_HPP
#define NALL_SNES_CARTRIDGE_HPP
#ifndef NALL_EMULATION_SUPER_FAMICOM_HPP
#define NALL_EMULATION_SUPER_FAMICOM_HPP
#include <nall/sha256.hpp>
#include <nall/string.hpp>
namespace nall {
@ -11,8 +14,6 @@ struct SuperFamicomCartridge {
inline void read_header(const uint8_t *data, unsigned size);
inline unsigned find_header(const uint8_t *data, unsigned size);
inline unsigned score_header(const uint8_t *data, unsigned size, unsigned addr);
inline unsigned gameboy_ram_size(const uint8_t *data, unsigned size);
inline bool gameboy_has_rtc(const uint8_t *data, unsigned size);
enum HeaderField {
CartName = 0x00,
@ -121,11 +122,7 @@ SuperFamicomCartridge::SuperFamicomCartridge(const uint8_t *data, unsigned size)
}
if(type == TypeGameBoy) {
markup.append("<cartridge rtc='", gameboy_has_rtc(data, size), "'\n");
if(gameboy_ram_size(data, size) > 0) {
markup.append(" <ram size='0x", hex(gameboy_ram_size(data, size)), "'>\n");
}
markup.append("</cartridge>\n");
markup.append("<cartridge/>\n");
return;
}
@ -133,7 +130,7 @@ SuperFamicomCartridge::SuperFamicomCartridge(const uint8_t *data, unsigned size)
markup.append("<cartridge region='", region == NTSC ? "NTSC" : "PAL", "'>\n");
if(type == TypeSuperGameBoy1Bios || type == TypeSuperGameBoy2Bios) markup.append(
" <rom>\n"
" <rom name='program.rom' size='0x", hex(rom_size), "'>\n"
" <map mode='linear' address='00-7f:8000-ffff'/>\n"
" <map mode='linear' address='80-ff:8000-ffff'/>\n"
" </rom>\n"
@ -144,6 +141,7 @@ SuperFamicomCartridge::SuperFamicomCartridge(const uint8_t *data, unsigned size)
);
else if(has_cx4) markup.append(
" <rom name='program.rom' size='0x", hex(rom_size), "'/>\n"
" <hitachidsp model='HG51B169' frequency='20000000' firmware='cx4.rom' sha256='ae8d4d1961b93421ff00b3caa1d0f0ce7783e749772a3369c36b3dbf0d37ef18'>\n"
" <rom>\n"
" <map mode='linear' address='00-7f:8000-ffff'/>\n"
@ -158,6 +156,8 @@ SuperFamicomCartridge::SuperFamicomCartridge(const uint8_t *data, unsigned size)
else if(has_spc7110) {
markup.append(
" <rom name='program.rom' size='0x", hex(rom_size), "'/>\n"
" <ram name='save.ram' size='", hex(ram_size), "'/>\n"
" <spc7110>\n"
" <mmio>\n"
" <map address='00-3f:4800-483f'/>\n"
@ -174,7 +174,7 @@ SuperFamicomCartridge::SuperFamicomCartridge(const uint8_t *data, unsigned size)
" <map address='80-bf:8000-ffff'/>\n"
" <map address='c0-cf:0000-ffff'/>\n"
" </rom>\n"
" <ram size='0x", hex(ram_size), "'>\n"
" <ram>\n"
" <map address='00-3f:6000-7fff'/>\n"
" <map address='80-bf:6000-7fff'/>\n"
" </ram>\n"
@ -182,7 +182,7 @@ SuperFamicomCartridge::SuperFamicomCartridge(const uint8_t *data, unsigned size)
" </spc7110>\n"
);
if(has_spc7110rtc) markup.append(
" <epsonrtc>\n"
" <epsonrtc name='rtc.ram' size='0x10'>\n"
" <map address='00-3f:4840-4842'/>\n"
" <map address='80-bf:4840-4842'/>\n"
" </epsonrtc>\n"
@ -191,13 +191,13 @@ SuperFamicomCartridge::SuperFamicomCartridge(const uint8_t *data, unsigned size)
else if(mapper == LoROM) {
markup.append(
" <rom>\n"
" <rom name='program.rom' size='0x", hex(rom_size), "'>\n"
" <map mode='linear' address='00-7f:8000-ffff'/>\n"
" <map mode='linear' address='80-ff:8000-ffff'/>\n"
" </rom>\n"
);
if(ram_size > 0) markup.append(
" <ram size='0x", hex(ram_size), "'>\n"
" <ram name='save.ram' size='0x", hex(ram_size), "'>\n"
" <map mode='linear' address='20-3f:6000-7fff'/>\n"
" <map mode='linear' address='a0-bf:6000-7fff'/>\n"
" <map mode='linear' address='70-7f:", range, "'/>\n"
@ -208,7 +208,7 @@ SuperFamicomCartridge::SuperFamicomCartridge(const uint8_t *data, unsigned size)
else if(mapper == HiROM) {
markup.append(
" <rom>\n"
" <rom name='program.rom' size='0x", hex(rom_size), "'>\n"
" <map mode='shadow' address='00-3f:8000-ffff'/>\n"
" <map mode='linear' address='40-7f:0000-ffff'/>\n"
" <map mode='shadow' address='80-bf:8000-ffff'/>\n"
@ -216,7 +216,7 @@ SuperFamicomCartridge::SuperFamicomCartridge(const uint8_t *data, unsigned size)
" </rom>\n"
);
if(ram_size > 0) markup.append(
" <ram size='0x", hex(ram_size), "'>\n"
" <ram name='save.ram' size='0x", hex(ram_size), "'>\n"
" <map mode='linear' address='20-3f:6000-7fff'/>\n"
" <map mode='linear' address='a0-bf:6000-7fff'/>\n"
" <map mode='linear' address='70-7f:", range, "'/>\n"
@ -226,14 +226,14 @@ SuperFamicomCartridge::SuperFamicomCartridge(const uint8_t *data, unsigned size)
else if(mapper == ExLoROM) {
markup.append(
" <rom>\n"
" <rom name='program.rom' size='0x", hex(rom_size), "'>\n"
" <map mode='linear' address='00-3f:8000-ffff'/>\n"
" <map mode='linear' address='40-7f:0000-ffff'/>\n"
" <map mode='linear' address='80-bf:8000-ffff'/>\n"
" </rom>\n"
);
if(ram_size > 0) markup.append(
" <ram size='0x", hex(ram_size), "'>\n"
" <ram name='save.ram' size='0x", hex(ram_size), "'>\n"
" <map mode='linear' address='20-3f:6000-7fff'/>\n"
" <map mode='linear' address='a0-bf:6000-7fff'/>\n"
" <map mode='linear' address='70-7f:0000-7fff'/>\n"
@ -243,7 +243,7 @@ SuperFamicomCartridge::SuperFamicomCartridge(const uint8_t *data, unsigned size)
else if(mapper == ExHiROM) {
markup.append(
" <rom>\n"
" <rom name='program.rom' size='0x", hex(rom_size), "'>\n"
" <map mode='shadow' address='00-3f:8000-ffff' offset='0x400000'/>\n"
" <map mode='linear' address='40-7f:0000-ffff' offset='0x400000'/>\n"
" <map mode='shadow' address='80-bf:8000-ffff' offset='0x000000'/>\n"
@ -251,7 +251,7 @@ SuperFamicomCartridge::SuperFamicomCartridge(const uint8_t *data, unsigned size)
" </rom>\n"
);
if(ram_size > 0) markup.append(
" <ram size='0x", hex(ram_size), "'>\n"
" <ram name='save.ram' size='0x", hex(ram_size), "'>\n"
" <map mode='linear' address='20-3f:6000-7fff'/>\n"
" <map mode='linear' address='a0-bf:6000-7fff'/>\n"
" <map mode='linear' address='70-7f:", range, "'/>\n"
@ -259,62 +259,72 @@ SuperFamicomCartridge::SuperFamicomCartridge(const uint8_t *data, unsigned size)
);
}
else if(mapper == SuperFXROM) markup.append(
" <superfx revision='2'>\n"
" <rom>\n"
" <map mode='linear' address='00-3f:8000-ffff'/>\n"
" <map mode='linear' address='40-5f:0000-ffff'/>\n"
" <map mode='linear' address='80-bf:8000-ffff'/>\n"
" <map mode='linear' address='c0-df:0000-ffff'/>\n"
" </rom>\n"
" <ram size='0x", hex(ram_size), "'>\n"
" <map mode='linear' address='00-3f:6000-7fff' size='0x2000'/>\n"
" <map mode='linear' address='60-7f:0000-ffff'/>\n"
" <map mode='linear' address='80-bf:6000-7fff' size='0x2000'/>\n"
" <map mode='linear' address='e0-ff:0000-ffff'/>\n"
" </ram>\n"
" <mmio>\n"
" <map address='00-3f:3000-32ff'/>\n"
" <map address='80-bf:3000-32ff'/>\n"
" </mmio>\n"
" </superfx>\n"
);
else if(mapper == SuperFXROM) {
markup.append(" <rom name='program.rom' size='0x", hex(rom_size), "'/>\n");
if(ram_size > 0)
markup.append(" <ram name='save.ram' size='0x", hex(ram_size), "'/>\n");
markup.append(
" <superfx revision='2'>\n"
" <rom>\n"
" <map mode='linear' address='00-3f:8000-ffff'/>\n"
" <map mode='linear' address='40-5f:0000-ffff'/>\n"
" <map mode='linear' address='80-bf:8000-ffff'/>\n"
" <map mode='linear' address='c0-df:0000-ffff'/>\n"
" </rom>\n"
" <ram>\n"
" <map mode='linear' address='00-3f:6000-7fff' size='0x2000'/>\n"
" <map mode='linear' address='60-7f:0000-ffff'/>\n"
" <map mode='linear' address='80-bf:6000-7fff' size='0x2000'/>\n"
" <map mode='linear' address='e0-ff:0000-ffff'/>\n"
" </ram>\n"
" <mmio>\n"
" <map address='00-3f:3000-32ff'/>\n"
" <map address='80-bf:3000-32ff'/>\n"
" </mmio>\n"
" </superfx>\n"
);
}
else if(mapper == SA1ROM) markup.append(
" <sa1>\n"
" <mcu>\n"
" <rom>\n"
" <map mode='direct' address='00-3f:8000-ffff'/>\n"
" <map mode='direct' address='80-bf:8000-ffff'/>\n"
" <map mode='direct' address='c0-ff:0000-ffff'/>\n"
" </rom>\n"
" <ram>\n"
" <map mode='direct' address='00-3f:6000-7fff'/>\n"
" <map mode='direct' address='80-bf:6000-7fff'/>\n"
" </ram>\n"
" </mcu>\n"
" <iram size='0x800'>\n"
" <map mode='linear' address='00-3f:3000-37ff'/>\n"
" <map mode='linear' address='80-bf:3000-37ff'/>\n"
" </iram>\n"
" <bwram size='0x", hex(ram_size), "'>\n"
" <map mode='linear' address='40-4f:0000-ffff'/>\n"
" </bwram>\n"
" <mmio>\n"
" <map address='00-3f:2200-23ff'/>\n"
" <map address='80-bf:2200-23ff'/>\n"
" </mmio>\n"
" </sa1>\n"
);
else if(mapper == SA1ROM) {
markup.append(" <rom name='program.rom' size='0x", hex(rom_size), "'/>\n");
if(ram_size > 0)
markup.append(" <ram name='save.ram' size='0x", hex(ram_size), "'/>\n");
markup.append(
" <sa1>\n"
" <mcu>\n"
" <rom>\n"
" <map mode='direct' address='00-3f:8000-ffff'/>\n"
" <map mode='direct' address='80-bf:8000-ffff'/>\n"
" <map mode='direct' address='c0-ff:0000-ffff'/>\n"
" </rom>\n"
" <ram>\n"
" <map mode='direct' address='00-3f:6000-7fff'/>\n"
" <map mode='direct' address='80-bf:6000-7fff'/>\n"
" </ram>\n"
" </mcu>\n"
" <iram >\n"
" <map mode='linear' address='00-3f:3000-37ff'/>\n"
" <map mode='linear' address='80-bf:3000-37ff'/>\n"
" </iram>\n"
" <bwram>\n"
" <map mode='linear' address='40-4f:0000-ffff'/>\n"
" </bwram>\n"
" <mmio>\n"
" <map address='00-3f:2200-23ff'/>\n"
" <map address='80-bf:2200-23ff'/>\n"
" </mmio>\n"
" </sa1>\n"
);
}
else if(mapper == BSCLoROM) markup.append(
" <rom>\n"
" <rom name='program.rom' size='0x", hex(rom_size), "'>\n"
" <map mode='linear' address='00-1f:8000-ffff' offset='0x000000'/>\n"
" <map mode='linear' address='20-3f:8000-ffff' offset='0x100000'/>\n"
" <map mode='linear' address='80-9f:8000-ffff' offset='0x200000'/>\n"
" <map mode='linear' address='a0-bf:8000-ffff' offset='0x100000'/>\n"
" </rom>\n"
" <ram size='0x", hex(ram_size), "'>\n"
" <ram name='save.ram' size='0x", hex(ram_size), "'>\n"
" <map mode='linear' address='70-7f:0000-7fff'/>\n"
" <map mode='linear' address='f0-ff:0000-7fff'/>\n"
" </ram>\n"
@ -326,13 +336,13 @@ SuperFamicomCartridge::SuperFamicomCartridge(const uint8_t *data, unsigned size)
);
else if(mapper == BSCHiROM) markup.append(
" <rom>\n"
" <rom name='program.rom' size='0x", hex(rom_size), "'>\n"
" <map mode='shadow' address='00-1f:8000-ffff'/>\n"
" <map mode='linear' address='40-5f:0000-ffff'/>\n"
" <map mode='shadow' address='80-9f:8000-ffff'/>\n"
" <map mode='linear' address='c0-df:0000-ffff'/>\n"
" </rom>\n"
" <ram size='0x", hex(ram_size), "'>\n"
" <ram name='save.ram' size='0x", hex(ram_size), "'>\n"
" <map mode='linear' address='20-3f:6000-7fff'/>\n"
" <map mode='linear' address='a0-bf:6000-7fff'/>\n"
" </ram>\n"
@ -347,6 +357,9 @@ SuperFamicomCartridge::SuperFamicomCartridge(const uint8_t *data, unsigned size)
);
else if(mapper == BSXROM) markup.append(
" <rom name='program.rom' size='0x", hex(rom_size), "'/>\n"
" <ram name='save.ram' size='0x", hex(ram_size), "'/>\n"
" <psram name='bsx.ram' size='0x40000'/>\n"
" <bsx>\n"
" <mcu>\n"
" <map address='00-3f:8000-ffff'/>\n"
@ -363,7 +376,7 @@ SuperFamicomCartridge::SuperFamicomCartridge(const uint8_t *data, unsigned size)
);
else if(mapper == STROM) markup.append(
" <rom>\n"
" <rom name='program.rom' size='0x", hex(rom_size), "'>\n"
" <map mode='linear' address='00-1f:8000-ffff'/>\n"
" <map mode='linear' address='80-9f:8000-ffff'/>\n"
" </rom>\n"
@ -373,7 +386,7 @@ SuperFamicomCartridge::SuperFamicomCartridge(const uint8_t *data, unsigned size)
" <map mode='linear' address='20-3f:8000-ffff'/>\n"
" <map mode='linear' address='a0-bf:8000-ffff'/>\n"
" </rom>\n"
" <ram size='0x20000'>\n"
" <ram>\n"
" <map mode='linear' address='60-63:8000-ffff'/>\n"
" <map mode='linear' address='e0-e3:8000-ffff'/>\n"
" </ram>\n"
@ -383,7 +396,7 @@ SuperFamicomCartridge::SuperFamicomCartridge(const uint8_t *data, unsigned size)
" <map mode='linear' address='40-5f:8000-ffff'/>\n"
" <map mode='linear' address='c0-df:8000-ffff'/>\n"
" </rom>\n"
" <ram size='0x20000'>\n"
" <ram>\n"
" <map mode='linear' address='70-73:8000-ffff'/>\n"
" <map mode='linear' address='f0-f3:8000-ffff'/>\n"
" </ram>\n"
@ -392,7 +405,7 @@ SuperFamicomCartridge::SuperFamicomCartridge(const uint8_t *data, unsigned size)
);
if(has_srtc) markup.append(
" <sharprtc>\n"
" <sharprtc name='rtc.ram' size='0x10'>\n"
" <map address='00-3f:2800-2801'/>\n"
" <map address='80-bf:2800-2801'/>\n"
" </sharprtc>\n"
@ -534,6 +547,7 @@ SuperFamicomCartridge::SuperFamicomCartridge(const uint8_t *data, unsigned size)
);
markup.append("</cartridge>\n");
markup.transform("'", "\"");
}
void SuperFamicomCartridge::read_header(const uint8_t *data, unsigned size) {
@ -860,25 +874,6 @@ unsigned SuperFamicomCartridge::score_header(const uint8_t *data, unsigned size,
return score;
}
unsigned SuperFamicomCartridge::gameboy_ram_size(const uint8_t *data, unsigned size) {
if(size < 512) return 0;
switch(data[0x0149]) {
case 0x00: return 0 * 1024;
case 0x01: return 8 * 1024;
case 0x02: return 8 * 1024;
case 0x03: return 32 * 1024;
case 0x04: return 128 * 1024;
case 0x05: return 128 * 1024;
default: return 128 * 1024;
}
}
bool SuperFamicomCartridge::gameboy_has_rtc(const uint8_t *data, unsigned size) {
if(size < 512) return false;
if(data[0x0147] == 0x0f ||data[0x0147] == 0x10) return true;
return false;
}
}
#endif

View File

@ -7,9 +7,9 @@
#include <netinet/in.h>
#include <netdb.h>
#else
#include <windows.h>
#include <winsock2.h>
#include <ws2tcpip.h>
#include <windows.h>
#endif
#include <nall/platform.hpp>

View File

@ -36,6 +36,8 @@ struct image {
inline image(const image &source);
inline image(image &&source);
inline image(bool endian, unsigned depth, uint64_t alphaMask, uint64_t redMask, uint64_t greenMask, uint64_t blueMask);
inline image(const string &filename);
inline image(const uint8_t *data, unsigned size);
inline image();
inline ~image();
@ -43,6 +45,7 @@ struct image {
inline void write(uint8_t *data, uint64_t value) const;
inline void free();
inline bool empty() const;
inline void allocate(unsigned width, unsigned height);
inline void clear(uint64_t color);
inline bool load(const string &filename);
@ -146,6 +149,38 @@ image::image(bool endian, unsigned depth, uint64_t alphaMask, uint64_t redMask,
blue.depth = bitDepth(blue.mask), blue.shift = bitShift(blue.mask);
}
image::image(const string &filename) : data(nullptr) {
width = 0, height = 0, pitch = 0;
this->endian = 0;
this->depth = 32;
this->stride = 4;
alpha.mask = 255u << 24, red.mask = 255u << 16, green.mask = 255u << 8, blue.mask = 255u << 0;
alpha.depth = bitDepth(alpha.mask), alpha.shift = bitShift(alpha.mask);
red.depth = bitDepth(red.mask), red.shift = bitShift(red.mask);
green.depth = bitDepth(green.mask), green.shift = bitShift(green.mask);
blue.depth = bitDepth(blue.mask), blue.shift = bitShift(blue.mask);
load(filename);
}
image::image(const uint8_t *data, unsigned size) : data(nullptr) {
width = 0, height = 0, pitch = 0;
this->endian = 0;
this->depth = 32;
this->stride = 4;
alpha.mask = 255u << 24, red.mask = 255u << 16, green.mask = 255u << 8, blue.mask = 255u << 0;
alpha.depth = bitDepth(alpha.mask), alpha.shift = bitShift(alpha.mask);
red.depth = bitDepth(red.mask), red.shift = bitShift(red.mask);
green.depth = bitDepth(green.mask), green.shift = bitShift(green.mask);
blue.depth = bitDepth(blue.mask), blue.shift = bitShift(blue.mask);
loadPNG(data, size);
}
image::image() : data(nullptr) {
width = 0, height = 0, pitch = 0;
@ -187,6 +222,12 @@ void image::free() {
data = nullptr;
}
bool image::empty() const {
if(data == nullptr) return true;
if(width == 0 || height == 0) return true;
return false;
}
void image::allocate(unsigned width, unsigned height) {
if(data != nullptr && this->width == width && this->height == height) return;
free();

52
bsnes/nall/invoke.hpp Executable file
View File

@ -0,0 +1,52 @@
#ifndef NALL_INVOKE_HPP
#define NALL_INVOKE_HPP
//void invoke(const string &name, const string& args...);
//if a program is specified, it is executed with the arguments provided
//if a file is specified, the file is opened using the program associated with said file type
//if a folder is specified, the folder is opened using the associated file explorer
//if a URL is specified, the default web browser is opened and pointed at the URL requested
//path environment variable is always consulted
//execution is asynchronous (non-blocking); use system() for synchronous execution
#include <nall/string.hpp>
#ifdef _WIN32
#include <nall/windows/utf8.hpp>
#endif
namespace nall {
#ifdef _WIN32
template<typename... Args>
inline void invoke(const string &name, Args&&... args) {
lstring argl(std::forward<Args>(args)...);
for(auto &arg : argl) if(arg.position(" ")) arg = {"\"", arg, "\""};
string arguments = argl.concatenate(" ");
ShellExecuteW(NULL, NULL, utf16_t(name), utf16_t(arguments), NULL, SW_SHOWNORMAL);
}
#else
template<typename... Args>
inline void invoke(const string &name, Args&&... args) {
pid_t pid = fork();
if(pid == 0) {
const char *argv[1 + sizeof...(args) + 1], **argp = argv;
lstring argl(std::forward<Args>(args)...);
*argp++ = (const char*)name;
for(auto &arg : argl) *argp++ = (const char*)arg;
*argp++ = nullptr;
if(execvp(name, (char* const*)argv) < 0) {
execlp("xdg-open", "xdg-open", (const char*)name, nullptr);
}
exit(0);
}
}
#endif
}
#endif

View File

@ -59,9 +59,9 @@
#endif
#if defined(_WIN32)
#define getcwd _getcwd
#define putenv _putenv
#define vsnprintf _vsnprintf
#define getcwd _getcwd
#define putenv _putenv
#define vsnprintf _vsnprintf
inline void usleep(unsigned milliseconds) { Sleep(milliseconds / 1000); }
#endif
@ -83,57 +83,4 @@
#define alwaysinline inline
#endif
//=========================
//file system functionality
//=========================
#if defined(_WIN32)
inline char* realpath(const char *filename, char *resolvedname) {
wchar_t fn[_MAX_PATH] = L"";
_wfullpath(fn, nall::utf16_t(filename), _MAX_PATH);
strcpy(resolvedname, nall::utf8_t(fn));
for(unsigned n = 0; resolvedname[n]; n++) if(resolvedname[n] == '\\') resolvedname[n] = '/';
return resolvedname;
}
inline char* userpath(char *path) {
wchar_t fp[_MAX_PATH] = L"";
SHGetFolderPathW(0, CSIDL_APPDATA | CSIDL_FLAG_CREATE, 0, 0, fp);
strcpy(path, nall::utf8_t(fp));
for(unsigned n = 0; path[n]; n++) if(path[n] == '\\') path[n] = '/';
unsigned length = strlen(path);
if(path[length] != '/') strcpy(path + length, "/");
return path;
}
inline char* getcwd(char *path) {
wchar_t fp[_MAX_PATH] = L"";
_wgetcwd(fp, _MAX_PATH);
strcpy(path, nall::utf8_t(fp));
for(unsigned n = 0; path[n]; n++) if(path[n] == '\\') path[n] = '/';
unsigned length = strlen(path);
if(path[length] != '/') strcpy(path + length, "/");
return path;
}
#else
//realpath() already exists
inline char* userpath(char *path) {
*path = 0;
struct passwd *userinfo = getpwuid(getuid());
if(userinfo) strcpy(path, userinfo->pw_dir);
unsigned length = strlen(path);
if(path[length] != '/') strcpy(path + length, "/");
return path;
}
inline char *getcwd(char *path) {
auto unused = getcwd(path, PATH_MAX);
unsigned length = strlen(path);
if(path[length] != '/') strcpy(path + length, "/");
return path;
}
#endif
#endif

View File

@ -1,5 +1,5 @@
#ifndef NALL_PRIORITYQUEUE_HPP
#define NALL_PRIORITYQUEUE_HPP
#ifndef NALL_PRIORITY_QUEUE_HPP
#define NALL_PRIORITY_QUEUE_HPP
#include <limits>
#include <nall/function.hpp>

View File

@ -14,7 +14,7 @@
#include <nall/algorithm.hpp>
#include <nall/bit.hpp>
#include <nall/sort.hpp>
#include <nall/type_traits.hpp>
#include <nall/traits.hpp>
#include <nall/utility.hpp>
namespace nall {

View File

@ -1,458 +0,0 @@
#ifndef NALL_SNES_CPU_HPP
#define NALL_SNES_CPU_HPP
namespace nall {
struct SNESCPU {
enum : unsigned {
Implied, //
Constant, //#$00
AccumConstant, //#$00
IndexConstant, //#$00
Direct, //$00
DirectX, //$00,x
DirectY, //$00,y
IDirect, //($00)
IDirectX, //($00,x)
IDirectY, //($00),y
ILDirect, //[$00]
ILDirectY, //[$00],y
Address, //$0000
AddressX, //$0000,x
AddressY, //$0000,y
IAddressX, //($0000,x)
ILAddress, //[$0000]
PAddress, //PBR:$0000
PIAddress, //PBR:($0000)
Long, //$000000
LongX, //$000000,x
Stack, //$00,s
IStackY, //($00,s),y
BlockMove, //$00,$00
RelativeShort, //+/- $00
RelativeLong, //+/- $0000
};
struct OpcodeInfo {
char name[4];
unsigned mode;
};
static const OpcodeInfo opcodeInfo[256];
static unsigned getOpcodeLength(bool accum, bool index, uint8_t opcode);
static string disassemble(unsigned pc, bool accum, bool index, uint8_t opcode, uint8_t pl, uint8_t ph, uint8_t pb);
};
const SNESCPU::OpcodeInfo SNESCPU::opcodeInfo[256] = {
//0x00 - 0x0f
{ "brk", Constant },
{ "ora", IDirectX },
{ "cop", Constant },
{ "ora", Stack },
{ "tsb", Direct },
{ "ora", Direct },
{ "asl", Direct },
{ "ora", ILDirect },
{ "php", Implied },
{ "ora", AccumConstant },
{ "asl", Implied },
{ "phd", Implied },
{ "tsb", Address },
{ "ora", Address },
{ "asl", Address },
{ "ora", Long },
//0x10 - 0x1f
{ "bpl", RelativeShort },
{ "ora", IDirectY },
{ "ora", IDirect },
{ "ora", IStackY },
{ "trb", Direct },
{ "ora", DirectX },
{ "asl", DirectX },
{ "ora", ILDirectY },
{ "clc", Implied },
{ "ora", AddressY },
{ "inc", Implied },
{ "tcs", Implied },
{ "trb", Address },
{ "ora", AddressX },
{ "asl", AddressX },
{ "ora", LongX },
//0x20 - 0x2f
{ "jsr", Address },
{ "and", IDirectX },
{ "jsl", Long },
{ "and", Stack },
{ "bit", Direct },
{ "and", Direct },
{ "rol", Direct },
{ "and", ILDirect },
{ "plp", Implied },
{ "and", AccumConstant },
{ "rol", Implied },
{ "pld", Implied },
{ "bit", Address },
{ "and", Address },
{ "rol", Address },
{ "and", Long },
//0x30 - 0x3f
{ "bmi", RelativeShort },
{ "and", IDirectY },
{ "and", IDirect },
{ "and", IStackY },
{ "bit", DirectX },
{ "and", DirectX },
{ "rol", DirectX },
{ "and", ILDirectY },
{ "sec", Implied },
{ "and", AddressY },
{ "dec", Implied },
{ "tsc", Implied },
{ "bit", AddressX },
{ "and", AddressX },
{ "rol", AddressX },
{ "and", LongX },
//0x40 - 0x4f
{ "rti", Implied },
{ "eor", IDirectX },
{ "wdm", Constant },
{ "eor", Stack },
{ "mvp", BlockMove },
{ "eor", Direct },
{ "lsr", Direct },
{ "eor", ILDirect },
{ "pha", Implied },
{ "eor", AccumConstant },
{ "lsr", Implied },
{ "phk", Implied },
{ "jmp", PAddress },
{ "eor", Address },
{ "lsr", Address },
{ "eor", Long },
//0x50 - 0x5f
{ "bvc", RelativeShort },
{ "eor", IDirectY },
{ "eor", IDirect },
{ "eor", IStackY },
{ "mvn", BlockMove },
{ "eor", DirectX },
{ "lsr", DirectX },
{ "eor", ILDirectY },
{ "cli", Implied },
{ "eor", AddressY },
{ "phy", Implied },
{ "tcd", Implied },
{ "jml", Long },
{ "eor", AddressX },
{ "lsr", AddressX },
{ "eor", LongX },
//0x60 - 0x6f
{ "rts", Implied },
{ "adc", IDirectX },
{ "per", Address },
{ "adc", Stack },
{ "stz", Direct },
{ "adc", Direct },
{ "ror", Direct },
{ "adc", ILDirect },
{ "pla", Implied },
{ "adc", AccumConstant },
{ "ror", Implied },
{ "rtl", Implied },
{ "jmp", PIAddress },
{ "adc", Address },
{ "ror", Address },
{ "adc", Long },
//0x70 - 0x7f
{ "bvs", RelativeShort },
{ "adc", IDirectY },
{ "adc", IDirect },
{ "adc", IStackY },
{ "stz", DirectX },
{ "adc", DirectX },
{ "ror", DirectX },
{ "adc", ILDirectY },
{ "sei", Implied },
{ "adc", AddressY },
{ "ply", Implied },
{ "tdc", Implied },
{ "jmp", IAddressX },
{ "adc", AddressX },
{ "ror", AddressX },
{ "adc", LongX },
//0x80 - 0x8f
{ "bra", RelativeShort },
{ "sta", IDirectX },
{ "brl", RelativeLong },
{ "sta", Stack },
{ "sty", Direct },
{ "sta", Direct },
{ "stx", Direct },
{ "sta", ILDirect },
{ "dey", Implied },
{ "bit", AccumConstant },
{ "txa", Implied },
{ "phb", Implied },
{ "sty", Address },
{ "sta", Address },
{ "stx", Address },
{ "sta", Long },
//0x90 - 0x9f
{ "bcc", RelativeShort },
{ "sta", IDirectY },
{ "sta", IDirect },
{ "sta", IStackY },
{ "sty", DirectX },
{ "sta", DirectX },
{ "stx", DirectY },
{ "sta", ILDirectY },
{ "tya", Implied },
{ "sta", AddressY },
{ "txs", Implied },
{ "txy", Implied },
{ "stz", Address },
{ "sta", AddressX },
{ "stz", AddressX },
{ "sta", LongX },
//0xa0 - 0xaf
{ "ldy", IndexConstant },
{ "lda", IDirectX },
{ "ldx", IndexConstant },
{ "lda", Stack },
{ "ldy", Direct },
{ "lda", Direct },
{ "ldx", Direct },
{ "lda", ILDirect },
{ "tay", Implied },
{ "lda", AccumConstant },
{ "tax", Implied },
{ "plb", Implied },
{ "ldy", Address },
{ "lda", Address },
{ "ldx", Address },
{ "lda", Long },
//0xb0 - 0xbf
{ "bcs", RelativeShort },
{ "lda", IDirectY },
{ "lda", IDirect },
{ "lda", IStackY },
{ "ldy", DirectX },
{ "lda", DirectX },
{ "ldx", DirectY },
{ "lda", ILDirectY },
{ "clv", Implied },
{ "lda", AddressY },
{ "tsx", Implied },
{ "tyx", Implied },
{ "ldy", AddressX },
{ "lda", AddressX },
{ "ldx", AddressY },
{ "lda", LongX },
//0xc0 - 0xcf
{ "cpy", IndexConstant },
{ "cmp", IDirectX },
{ "rep", Constant },
{ "cmp", Stack },
{ "cpy", Direct },
{ "cmp", Direct },
{ "dec", Direct },
{ "cmp", ILDirect },
{ "iny", Implied },
{ "cmp", AccumConstant },
{ "dex", Implied },
{ "wai", Implied },
{ "cpy", Address },
{ "cmp", Address },
{ "dec", Address },
{ "cmp", Long },
//0xd0 - 0xdf
{ "bne", RelativeShort },
{ "cmp", IDirectY },
{ "cmp", IDirect },
{ "cmp", IStackY },
{ "pei", IDirect },
{ "cmp", DirectX },
{ "dec", DirectX },
{ "cmp", ILDirectY },
{ "cld", Implied },
{ "cmp", AddressY },
{ "phx", Implied },
{ "stp", Implied },
{ "jmp", ILAddress },
{ "cmp", AddressX },
{ "dec", AddressX },
{ "cmp", LongX },
//0xe0 - 0xef
{ "cpx", IndexConstant },
{ "sbc", IDirectX },
{ "sep", Constant },
{ "sbc", Stack },
{ "cpx", Direct },
{ "sbc", Direct },
{ "inc", Direct },
{ "sbc", ILDirect },
{ "inx", Implied },
{ "sbc", AccumConstant },
{ "nop", Implied },
{ "xba", Implied },
{ "cpx", Address },
{ "sbc", Address },
{ "inc", Address },
{ "sbc", Long },
//0xf0 - 0xff
{ "beq", RelativeShort },
{ "sbc", IDirectY },
{ "sbc", IDirect },
{ "sbc", IStackY },
{ "pea", Address },
{ "sbc", DirectX },
{ "inc", DirectX },
{ "sbc", ILDirectY },
{ "sed", Implied },
{ "sbc", AddressY },
{ "plx", Implied },
{ "xce", Implied },
{ "jsr", IAddressX },
{ "sbc", AddressX },
{ "inc", AddressX },
{ "sbc", LongX },
};
inline unsigned SNESCPU::getOpcodeLength(bool accum, bool index, uint8_t opcode) {
switch(opcodeInfo[opcode].mode) { default:
case Implied: return 1;
case Constant: return 2;
case AccumConstant: return 3 - accum;
case IndexConstant: return 3 - index;
case Direct: return 2;
case DirectX: return 2;
case DirectY: return 2;
case IDirect: return 2;
case IDirectX: return 2;
case IDirectY: return 2;
case ILDirect: return 2;
case ILDirectY: return 2;
case Address: return 3;
case AddressX: return 3;
case AddressY: return 3;
case IAddressX: return 3;
case ILAddress: return 3;
case PAddress: return 3;
case PIAddress: return 3;
case Long: return 4;
case LongX: return 4;
case Stack: return 2;
case IStackY: return 2;
case BlockMove: return 3;
case RelativeShort: return 2;
case RelativeLong: return 3;
}
}
inline string SNESCPU::disassemble(unsigned pc, bool accum, bool index, uint8_t opcode, uint8_t pl, uint8_t ph, uint8_t pb) {
string name = opcodeInfo[opcode].name;
unsigned mode = opcodeInfo[opcode].mode;
if(mode == Implied) return name;
if(mode == Constant) return { name, " #$", hex<2>(pl) };
if(mode == AccumConstant) return { name, " #$", accum ? "" : hex<2>(ph), hex<2>(pl) };
if(mode == IndexConstant) return { name, " #$", index ? "" : hex<2>(ph), hex<2>(pl) };
if(mode == Direct) return { name, " $", hex<2>(pl) };
if(mode == DirectX) return { name, " $", hex<2>(pl), ",x" };
if(mode == DirectY) return { name, " $", hex<2>(pl), ",y" };
if(mode == IDirect) return { name, " ($", hex<2>(pl), ")" };
if(mode == IDirectX) return { name, " ($", hex<2>(pl), ",x)" };
if(mode == IDirectY) return { name, " ($", hex<2>(pl), "),y" };
if(mode == ILDirect) return { name, " [$", hex<2>(pl), "]" };
if(mode == ILDirectY) return { name, " [$", hex<2>(pl), "],y" };
if(mode == Address) return { name, " $", hex<2>(ph), hex<2>(pl) };
if(mode == AddressX) return { name, " $", hex<2>(ph), hex<2>(pl), ",x" };
if(mode == AddressY) return { name, " $", hex<2>(ph), hex<2>(pl), ",y" };
if(mode == IAddressX) return { name, " ($", hex<2>(ph), hex<2>(pl), ",x)" };
if(mode == ILAddress) return { name, " [$", hex<2>(ph), hex<2>(pl), "]" };
if(mode == PAddress) return { name, " $", hex<2>(ph), hex<2>(pl) };
if(mode == PIAddress) return { name, " ($", hex<2>(ph), hex<2>(pl), ")" };
if(mode == Long) return { name, " $", hex<2>(pb), hex<2>(ph), hex<2>(pl) };
if(mode == LongX) return { name, " $", hex<2>(pb), hex<2>(ph), hex<2>(pl), ",x" };
if(mode == Stack) return { name, " $", hex<2>(pl), ",s" };
if(mode == IStackY) return { name, " ($", hex<2>(pl), ",s),y" };
if(mode == BlockMove) return { name, " $", hex<2>(ph), ",$", hex<2>(pl) };
if(mode == RelativeShort) {
unsigned addr = (pc + 2) + (int8_t)(pl << 0);
return { name, " $", hex<4>(addr) };
}
if(mode == RelativeLong) {
unsigned addr = (pc + 3) + (int16_t)((ph << 8) + (pl << 0));
return { name, " $", hex<4>(addr) };
}
return "";
}
}
#endif

View File

@ -1,639 +0,0 @@
#ifndef NALL_SNES_SMP_HPP
#define NALL_SNES_SMP_HPP
namespace nall {
struct SNESSMP {
enum : unsigned {
Implied, //
TVector, //0
Direct, //$00
DirectRelative, //$00,+/-$00
ADirect, //a,$00
AAbsolute, //a,$0000
AIX, //a,(x)
AIDirectX, //a,($00+x)
AConstant, //a,#$00
DirectDirect, //$00,$00
CAbsoluteBit, //c,$0000:0
Absolute, //$0000
P, //p
AbsoluteA, //$0000,a
Relative, //+/-$00
ADirectX, //a,$00+x
AAbsoluteX, //a,$0000+x
AAbsoluteY, //a,$0000+y
AIDirectY, //a,($00)+y
DirectConstant, //$00,#$00
IXIY, //(x),(y)
DirectX, //$00+x
A, //a
X, //x
XAbsolute, //x,$0000
IAbsoluteX, //($0000+x)
CNAbsoluteBit, //c,!$0000:0
XDirect, //x,$00
PVector, //$ff00
YaDirect, //ya,$00
XA, //x,a
YAbsolute, //y,$0000
Y, //y
AX, //a,x
YDirect, //y,$00
YConstant, //y,#$00
XSp, //x,sp
YaX, //ya,x
IXPA, //(x)+,a
SpX, //sp,x
AIXP, //a,(x)+
DirectA, //$00,a
IXA, //(x),a
IDirectXA, //($00+x),a
XConstant, //x,#$00
AbsoluteX, //$0000,x
AbsoluteBitC, //$0000:0,c
DirectY, //$00,y
AbsoluteY, //$0000,y
Ya, //ya
DirectXA, //$00+x,a
AbsoluteXA, //$0000+x,a
AbsoluteYA, //$0000+y,a
IDirectYA, //($00)+y,a
DirectYX, //$00+y,x
DirectYa, //$00,ya
DirectXY, //$00+x,y
AY, //a,y
DirectXRelative, //$00+x,+/-$00
XDirectY, //x,$00+y
YDirectX, //y,$00+x
YA, //y,a
YRelative, //y,+/-$00
};
struct OpcodeInfo {
char name[6];
unsigned mode;
};
static const OpcodeInfo opcodeInfo[256];
static unsigned getOpcodeLength(uint8_t opcode);
static string disassemble(uint16_t pc, uint8_t opcode, uint8_t pl, uint8_t ph);
static string disassemble(uint16_t pc, bool p, uint8_t opcode, uint8_t pl, uint8_t ph);
};
const SNESSMP::OpcodeInfo SNESSMP::opcodeInfo[256] = {
//0x00 - 0x0f
{ "nop ", Implied },
{ "tcall", TVector },
{ "set0 ", Direct },
{ "bbs0 ", DirectRelative },
{ "or ", ADirect },
{ "or ", AAbsolute },
{ "or ", AIX },
{ "or ", AIDirectX },
{ "or ", AConstant },
{ "or ", DirectDirect },
{ "or1 ", CAbsoluteBit },
{ "asl ", Direct },
{ "asl ", Absolute },
{ "push ", P },
{ "tset ", AbsoluteA },
{ "brk ", Implied },
//0x10 - 0x1f
{ "bpl ", Relative },
{ "tcall", TVector },
{ "clr0 ", Direct },
{ "bbc0 ", DirectRelative },
{ "or ", ADirectX },
{ "or ", AAbsoluteX },
{ "or ", AAbsoluteY },
{ "or ", AIDirectY },
{ "or ", DirectConstant },
{ "or ", IXIY },
{ "decw ", Direct },
{ "asl ", DirectX },
{ "asl ", A },
{ "dec ", X },
{ "cmp ", XAbsolute },
{ "jmp ", IAbsoluteX },
//0x20 - 0x2f
{ "clrp ", Implied },
{ "tcall", TVector },
{ "set1 ", Direct },
{ "bbs1 ", DirectRelative },
{ "and ", ADirect },
{ "and ", AAbsolute },
{ "and ", AIX },
{ "and ", AIDirectX },
{ "and ", AConstant },
{ "and ", DirectDirect },
{ "or1 ", CNAbsoluteBit },
{ "rol ", Direct },
{ "rol ", Absolute },
{ "push ", A },
{ "cbne ", DirectRelative },
{ "bra ", Relative },
//0x30 - 0x3f
{ "bmi ", Relative },
{ "tcall", TVector },
{ "clr1 ", Direct },
{ "bbc1 ", DirectRelative },
{ "and ", ADirectX },
{ "and ", AAbsoluteX },
{ "and ", AAbsoluteY },
{ "and ", AIDirectY },
{ "and ", DirectConstant },
{ "and ", IXIY },
{ "incw ", Direct },
{ "rol ", DirectX },
{ "rol ", A },
{ "inc ", X },
{ "cmp ", XDirect },
{ "call ", Absolute },
//0x40 - 0x4f
{ "setp ", Implied },
{ "tcall", TVector },
{ "set2 ", Direct },
{ "bbs2 ", DirectRelative },
{ "eor ", ADirect },
{ "eor ", AAbsolute },
{ "eor ", AIX },
{ "eor ", AIDirectX },
{ "eor ", AConstant },
{ "eor ", DirectDirect },
{ "and1 ", CAbsoluteBit },
{ "lsr ", Direct },
{ "lsr ", Absolute },
{ "push ", X },
{ "tclr ", AbsoluteA },
{ "pcall", PVector },
//0x50 - 0x5f
{ "bvc ", Relative },
{ "tcall", TVector },
{ "clr2 ", Direct },
{ "bbc2 ", DirectRelative },
{ "eor ", ADirectX },
{ "eor ", AAbsoluteX },
{ "eor ", AAbsoluteY },
{ "eor ", AIDirectY },
{ "eor ", DirectConstant },
{ "eor ", IXIY },
{ "cmpw ", YaDirect },
{ "lsr ", DirectX },
{ "lsr ", A },
{ "mov ", XA },
{ "cmp ", YAbsolute },
{ "jmp ", Absolute },
//0x60 - 0x6f
{ "clrc ", Implied },
{ "tcall", TVector },
{ "set3 ", Direct },
{ "bbs3 ", DirectRelative },
{ "cmp ", ADirect },
{ "cmp ", AAbsolute },
{ "cmp ", AIX },
{ "cmp ", AIDirectX },
{ "cmp ", AConstant },
{ "cmp ", DirectDirect },
{ "and1 ", CNAbsoluteBit },
{ "ror ", Direct },
{ "ror ", Absolute },
{ "push ", Y },
{ "dbnz ", DirectRelative },
{ "ret ", Implied },
//0x70 - 0x7f
{ "bvs ", Relative },
{ "tcall", TVector },
{ "clr3 ", Direct },
{ "bbc3 ", DirectRelative },
{ "cmp ", ADirectX },
{ "cmp ", AAbsoluteX },
{ "cmp ", AAbsoluteY },
{ "cmp ", AIDirectY },
{ "cmp ", DirectConstant },
{ "cmp ", IXIY },
{ "addw ", YaDirect },
{ "ror ", DirectX },
{ "ror ", A },
{ "mov ", AX },
{ "cmp ", YDirect },
{ "reti ", Implied },
//0x80 - 0x8f
{ "setc ", Implied },
{ "tcall", TVector },
{ "set4 ", Direct },
{ "bbs4 ", DirectRelative },
{ "adc ", ADirect },
{ "adc ", AAbsolute },
{ "adc ", AIX },
{ "adc ", AIDirectX },
{ "adc ", AConstant },
{ "adc ", DirectDirect },
{ "eor1 ", CAbsoluteBit },
{ "dec ", Direct },
{ "dec ", Absolute },
{ "mov ", YConstant },
{ "pop ", P },
{ "mov ", DirectConstant },
//0x90 - 0x9f
{ "bcc ", Relative },
{ "tcall", TVector },
{ "clr4 ", Direct },
{ "bbc4 ", DirectRelative },
{ "adc ", ADirectX },
{ "adc ", AAbsoluteX },
{ "adc ", AAbsoluteY },
{ "adc ", AIDirectY },
{ "adc ", DirectRelative },
{ "adc ", IXIY },
{ "subw ", YaDirect },
{ "dec ", DirectX },
{ "dec ", A },
{ "mov ", XSp },
{ "div ", YaX },
{ "xcn ", A },
//0xa0 - 0xaf
{ "ei ", Implied },
{ "tcall", TVector },
{ "set5 ", Direct },
{ "bbs5 ", DirectRelative },
{ "sbc ", ADirect },
{ "sbc ", AAbsolute },
{ "sbc ", AIX },
{ "sbc ", AIDirectX },
{ "sbc ", AConstant },
{ "sbc ", DirectDirect },
{ "mov1 ", CAbsoluteBit },
{ "inc ", Direct },
{ "inc ", Absolute },
{ "cmp ", YConstant },
{ "pop ", A },
{ "mov ", IXPA },
//0xb0 - 0xbf
{ "bcs ", Relative },
{ "tcall", TVector },
{ "clr5 ", Direct },
{ "bbc5 ", DirectRelative },
{ "sbc ", ADirectX },
{ "sbc ", AAbsoluteX },
{ "sbc ", AAbsoluteY },
{ "sbc ", AIDirectY },
{ "sbc ", DirectConstant },
{ "sbc ", IXIY },
{ "movw ", YaDirect },
{ "inc ", DirectX },
{ "inc ", A },
{ "mov ", SpX },
{ "das ", A },
{ "mov ", AIXP },
//0xc0 - 0xcf
{ "di ", Implied },
{ "tcall", TVector },
{ "set6 ", Direct },
{ "bbs6 ", DirectRelative },
{ "mov ", DirectA },
{ "mov ", AbsoluteA },
{ "mov ", IXA },
{ "mov ", IDirectXA },
{ "cmp ", XConstant },
{ "mov ", AbsoluteX },
{ "mov1 ", AbsoluteBitC },
{ "mov ", DirectY },
{ "mov ", AbsoluteY },
{ "mov ", XConstant },
{ "pop ", X },
{ "mul ", Ya },
//0xd0 - 0xdf
{ "bne ", Relative },
{ "tcall", TVector },
{ "clr6 ", Relative },
{ "bbc6 ", DirectRelative },
{ "mov ", DirectXA },
{ "mov ", AbsoluteXA },
{ "mov ", AbsoluteYA },
{ "mov ", IDirectYA },
{ "mov ", DirectX },
{ "mov ", DirectYX },
{ "movw ", DirectYa },
{ "mov ", DirectXY },
{ "dec ", Y },
{ "mov ", AY },
{ "cbne ", DirectXRelative },
{ "daa ", A },
//0xe0 - 0xef
{ "clrv ", Implied },
{ "tcall", TVector },
{ "set7 ", Direct },
{ "bbs7 ", DirectRelative },
{ "mov ", ADirect },
{ "mov ", AAbsolute },
{ "mov ", AIX },
{ "mov ", AIDirectX },
{ "mov ", AConstant },
{ "mov ", XAbsolute },
{ "not1 ", CAbsoluteBit },
{ "mov ", YDirect },
{ "mov ", YAbsolute },
{ "notc ", Implied },
{ "pop ", Y },
{ "sleep", Implied },
//0xf0 - 0xff
{ "beq ", Relative },
{ "tcall", TVector },
{ "clr7 ", Direct },
{ "bbc7 ", DirectRelative },
{ "mov ", ADirectX },
{ "mov ", AAbsoluteX },
{ "mov ", AAbsoluteY },
{ "mov ", AIDirectY },
{ "mov ", XDirect },
{ "mov ", XDirectY },
{ "mov ", DirectDirect },
{ "mov ", YDirectX },
{ "inc ", Y },
{ "mov ", YA },
{ "dbz ", YRelative },
{ "stop ", Implied },
};
inline unsigned SNESSMP::getOpcodeLength(uint8_t opcode) {
switch(opcodeInfo[opcode].mode) { default:
case Implied: return 1; //
case TVector: return 1; //0
case Direct: return 2; //$00
case DirectRelative: return 3; //$00,+/-$00
case ADirect: return 2; //a,$00
case AAbsolute: return 3; //a,$0000
case AIX: return 1; //a,(x)
case AIDirectX: return 2; //a,($00+x)
case AConstant: return 2; //a,#$00
case DirectDirect: return 3; //$00,$00
case CAbsoluteBit: return 3; //c,$0000:0
case Absolute: return 3; //$0000
case P: return 1; //p
case AbsoluteA: return 3; //$0000,a
case Relative: return 2; //+/-$00
case ADirectX: return 2; //a,$00+x
case AAbsoluteX: return 3; //a,$0000+x
case AAbsoluteY: return 3; //a,$0000+y
case AIDirectY: return 2; //a,($00)+y
case DirectConstant: return 3; //$00,#$00
case IXIY: return 1; //(x),(y)
case DirectX: return 2; //$00+x
case A: return 1; //a
case X: return 1; //x
case XAbsolute: return 3; //x,$0000
case IAbsoluteX: return 3; //($0000+x)
case CNAbsoluteBit: return 3; //c,!$0000:0
case XDirect: return 2; //x,$00
case PVector: return 2; //$ff00
case YaDirect: return 2; //ya,$00
case XA: return 1; //x,a
case YAbsolute: return 3; //y,$0000
case Y: return 1; //y
case AX: return 1; //a,x
case YDirect: return 2; //y,$00
case YConstant: return 2; //y,#$00
case XSp: return 1; //x,sp
case YaX: return 1; //ya,x
case IXPA: return 1; //(x)+,a
case SpX: return 1; //sp,x
case AIXP: return 1; //a,(x)+
case DirectA: return 2; //$00,a
case IXA: return 1; //(x),a
case IDirectXA: return 2; //($00+x),a
case XConstant: return 2; //x,#$00
case AbsoluteX: return 3; //$0000,x
case AbsoluteBitC: return 3; //$0000:0,c
case DirectY: return 2; //$00,y
case AbsoluteY: return 3; //$0000,y
case Ya: return 1; //ya
case DirectXA: return 2; //$00+x,a
case AbsoluteXA: return 3; //$0000+x,a
case AbsoluteYA: return 3; //$0000+y,a
case IDirectYA: return 2; //($00)+y,a
case DirectYX: return 2; //$00+y,x
case DirectYa: return 2; //$00,ya
case DirectXY: return 2; //$00+x,y
case AY: return 1; //a,y
case DirectXRelative: return 3; //$00+x,+/-$00
case XDirectY: return 2; //x,$00+y
case YDirectX: return 2; //y,$00+x
case YA: return 1; //y,a
case YRelative: return 2; //y,+/-$00
}
}
inline string SNESSMP::disassemble(uint16_t pc, uint8_t opcode, uint8_t pl, uint8_t ph) {
string name = opcodeInfo[opcode].name;
unsigned mode = opcodeInfo[opcode].mode;
unsigned pa = (ph << 8) + pl;
if(mode == Implied) return name;
if(mode == TVector) return { name, " ", opcode >> 4 };
if(mode == Direct) return { name, " $", hex<2>(pl) };
if(mode == DirectRelative) return { name, " $", hex<2>(pl), ",$", hex<4>(pc + 3 + (int8_t)ph) };
if(mode == ADirect) return { name, " a,$", hex<2>(pl) };
if(mode == AAbsolute) return { name, " a,$", hex<4>(pa) };
if(mode == AIX) return { name, "a,(x)" };
if(mode == AIDirectX) return { name, " a,($", hex<2>(pl), "+x)" };
if(mode == AConstant) return { name, " a,#$", hex<2>(pl) };
if(mode == DirectDirect) return { name, " $", hex<2>(ph), ",$", hex<2>(pl) };
if(mode == CAbsoluteBit) return { name, " c,$", hex<4>(pa & 0x1fff), ":", pa >> 13 };
if(mode == Absolute) return { name, " $", hex<4>(pa) };
if(mode == P) return { name, " p" };
if(mode == AbsoluteA) return { name, " $", hex<4>(pa), ",a" };
if(mode == Relative) return { name, " $", hex<4>(pc + 2 + (int8_t)pl) };
if(mode == ADirectX) return { name, " a,$", hex<2>(pl), "+x" };
if(mode == AAbsoluteX) return { name, " a,$", hex<4>(pa), "+x" };
if(mode == AAbsoluteY) return { name, " a,$", hex<4>(pa), "+y" };
if(mode == AIDirectY) return { name, " a,($", hex<2>(pl), ")+y" };
if(mode == DirectConstant) return { name, " $", hex<2>(ph), ",#$", hex<2>(pl) };
if(mode == IXIY) return { name, " (x),(y)" };
if(mode == DirectX) return { name, " $", hex<2>(pl), "+x" };
if(mode == A) return { name, " a" };
if(mode == X) return { name, " x" };
if(mode == XAbsolute) return { name, " x,$", hex<4>(pa) };
if(mode == IAbsoluteX) return { name, " ($", hex<4>(pa), "+x)" };
if(mode == CNAbsoluteBit) return { name, " c,!$", hex<4>(pa & 0x1fff), ":", pa >> 13 };
if(mode == XDirect) return { name, " x,$", hex<2>(pl) };
if(mode == PVector) return { name, " $ff", hex<2>(pl) };
if(mode == YaDirect) return { name, " ya,$", hex<2>(pl) };
if(mode == XA) return { name, " x,a" };
if(mode == YAbsolute) return { name, " y,$", hex<4>(pa) };
if(mode == Y) return { name, " y" };
if(mode == AX) return { name, " a,x" };
if(mode == YDirect) return { name, " y,$", hex<2>(pl) };
if(mode == YConstant) return { name, " y,#$", hex<2>(pl) };
if(mode == XSp) return { name, " x,sp" };
if(mode == YaX) return { name, " ya,x" };
if(mode == IXPA) return { name, " (x)+,a" };
if(mode == SpX) return { name, " sp,x" };
if(mode == AIXP) return { name, " a,(x)+" };
if(mode == DirectA) return { name, " $", hex<2>(pl), ",a" };
if(mode == IXA) return { name, " (x),a" };
if(mode == IDirectXA) return { name, " ($", hex<2>(pl), "+x),a" };
if(mode == XConstant) return { name, " x,#$", hex<2>(pl) };
if(mode == AbsoluteX) return { name, " $", hex<4>(pa), ",x" };
if(mode == AbsoluteBitC) return { name, " $", hex<4>(pa & 0x1fff), ":", pa >> 13, ",c" };
if(mode == DirectY) return { name, " $", hex<2>(pl), ",y" };
if(mode == AbsoluteY) return { name, " $", hex<4>(pa), ",y" };
if(mode == Ya) return { name, " ya" };
if(mode == DirectXA) return { name, " $", hex<2>(pl), "+x,a" };
if(mode == AbsoluteXA) return { name, " $", hex<4>(pa), "+x,a" };
if(mode == AbsoluteYA) return { name, " $", hex<4>(pa), "+y,a" };
if(mode == IDirectYA) return { name, " ($", hex<2>(pl), ")+y,a" };
if(mode == DirectYX) return { name, " $", hex<2>(pl), "+y,x" };
if(mode == DirectYa) return { name, " $", hex<2>(pl), ",ya" };
if(mode == DirectXY) return { name, " $", hex<2>(pl), "+x,y" };
if(mode == AY) return { name, " a,y" };
if(mode == DirectXRelative) return { name, " $", hex<2>(pl), ",$", hex<4>(pc + 3 + (int8_t)ph) };
if(mode == XDirectY) return { name, " x,$", hex<2>(pl), "+y" };
if(mode == YDirectX) return { name, " y,$", hex<2>(pl), "+x" };
if(mode == YA) return { name, " y,a" };
if(mode == YRelative) return { name, " y,$", hex<4>(pc + 2 + (int8_t)pl) };
return "";
}
inline string SNESSMP::disassemble(uint16_t pc, bool p, uint8_t opcode, uint8_t pl, uint8_t ph) {
string name = opcodeInfo[opcode].name;
unsigned mode = opcodeInfo[opcode].mode;
unsigned pdl = (p << 8) + pl;
unsigned pdh = (p << 8) + ph;
unsigned pa = (ph << 8) + pl;
if(mode == Implied) return name;
if(mode == TVector) return { name, " ", opcode >> 4 };
if(mode == Direct) return { name, " $", hex<3>(pdl) };
if(mode == DirectRelative) return { name, " $", hex<3>(pdl), ",$", hex<4>(pc + 3 + (int8_t)ph) };
if(mode == ADirect) return { name, " a,$", hex<3>(pdl) };
if(mode == AAbsolute) return { name, " a,$", hex<4>(pa) };
if(mode == AIX) return { name, "a,(x)" };
if(mode == AIDirectX) return { name, " a,($", hex<3>(pdl), "+x)" };
if(mode == AConstant) return { name, " a,#$", hex<2>(pl) };
if(mode == DirectDirect) return { name, " $", hex<3>(pdh), ",$", hex<3>(pdl) };
if(mode == CAbsoluteBit) return { name, " c,$", hex<4>(pa & 0x1fff), ":", pa >> 13 };
if(mode == Absolute) return { name, " $", hex<4>(pa) };
if(mode == P) return { name, " p" };
if(mode == AbsoluteA) return { name, " $", hex<4>(pa), ",a" };
if(mode == Relative) return { name, " $", hex<4>(pc + 2 + (int8_t)pl) };
if(mode == ADirectX) return { name, " a,$", hex<3>(pdl), "+x" };
if(mode == AAbsoluteX) return { name, " a,$", hex<4>(pa), "+x" };
if(mode == AAbsoluteY) return { name, " a,$", hex<4>(pa), "+y" };
if(mode == AIDirectY) return { name, " a,($", hex<3>(pdl), ")+y" };
if(mode == DirectConstant) return { name, " $", hex<3>(pdh), ",#$", hex<2>(pl) };
if(mode == IXIY) return { name, " (x),(y)" };
if(mode == DirectX) return { name, " $", hex<3>(pdl), "+x" };
if(mode == A) return { name, " a" };
if(mode == X) return { name, " x" };
if(mode == XAbsolute) return { name, " x,$", hex<4>(pa) };
if(mode == IAbsoluteX) return { name, " ($", hex<4>(pa), "+x)" };
if(mode == CNAbsoluteBit) return { name, " c,!$", hex<4>(pa & 0x1fff), ":", pa >> 13 };
if(mode == XDirect) return { name, " x,$", hex<3>(pdl) };
if(mode == PVector) return { name, " $ff", hex<2>(pl) };
if(mode == YaDirect) return { name, " ya,$", hex<3>(pdl) };
if(mode == XA) return { name, " x,a" };
if(mode == YAbsolute) return { name, " y,$", hex<4>(pa) };
if(mode == Y) return { name, " y" };
if(mode == AX) return { name, " a,x" };
if(mode == YDirect) return { name, " y,$", hex<3>(pdl) };
if(mode == YConstant) return { name, " y,#$", hex<2>(pl) };
if(mode == XSp) return { name, " x,sp" };
if(mode == YaX) return { name, " ya,x" };
if(mode == IXPA) return { name, " (x)+,a" };
if(mode == SpX) return { name, " sp,x" };
if(mode == AIXP) return { name, " a,(x)+" };
if(mode == DirectA) return { name, " $", hex<3>(pdl), ",a" };
if(mode == IXA) return { name, " (x),a" };
if(mode == IDirectXA) return { name, " ($", hex<3>(pdl), "+x),a" };
if(mode == XConstant) return { name, " x,#$", hex<2>(pl) };
if(mode == AbsoluteX) return { name, " $", hex<4>(pa), ",x" };
if(mode == AbsoluteBitC) return { name, " $", hex<4>(pa & 0x1fff), ":", pa >> 13, ",c" };
if(mode == DirectY) return { name, " $", hex<3>(pdl), ",y" };
if(mode == AbsoluteY) return { name, " $", hex<4>(pa), ",y" };
if(mode == Ya) return { name, " ya" };
if(mode == DirectXA) return { name, " $", hex<3>(pdl), "+x,a" };
if(mode == AbsoluteXA) return { name, " $", hex<4>(pa), "+x,a" };
if(mode == AbsoluteYA) return { name, " $", hex<4>(pa), "+y,a" };
if(mode == IDirectYA) return { name, " ($", hex<3>(pdl), ")+y,a" };
if(mode == DirectYX) return { name, " $", hex<3>(pdl), "+y,x" };
if(mode == DirectYa) return { name, " $", hex<3>(pdl), ",ya" };
if(mode == DirectXY) return { name, " $", hex<3>(pdl), "+x,y" };
if(mode == AY) return { name, " a,y" };
if(mode == DirectXRelative) return { name, " $", hex<3>(pdl), ",$", hex<4>(pc + 3 + (int8_t)ph) };
if(mode == XDirectY) return { name, " x,$", hex<3>(pdl), "+y" };
if(mode == YDirectX) return { name, " y,$", hex<3>(pdl), "+x" };
if(mode == YA) return { name, " y,a" };
if(mode == YRelative) return { name, " y,$", hex<4>(pc + 2 + (int8_t)pl) };
return "";
}
}
#endif

View File

@ -112,6 +112,8 @@ namespace nall {
struct lstring : vector<string> {
inline optional<unsigned> find(const char*) const;
inline string concatenate(const char*) const;
inline void append() {}
template<typename... Args> inline void append(const string&, Args&&...);
template<unsigned Limit = 0> inline lstring& split(const char*, const char*);
template<unsigned Limit = 0> inline lstring& isplit(const char*, const char*);
@ -121,8 +123,14 @@ namespace nall {
inline bool operator==(const lstring&) const;
inline bool operator!=(const lstring&) const;
inline lstring();
inline lstring(std::initializer_list<string>);
inline lstring& operator=(const lstring&);
inline lstring& operator=(lstring&);
inline lstring& operator=(lstring&&);
template<typename... Args> inline lstring(Args&&... args);
inline lstring(const lstring&);
inline lstring(lstring&);
inline lstring(lstring&&);
protected:
template<unsigned Limit, bool Insensitive, bool Quoted> inline lstring& usplit(const char*, const char*);
@ -149,9 +157,10 @@ namespace nall {
inline bool strmath(const char *str, int &result);
//platform.hpp
inline string realpath(const char *name);
inline string activepath();
inline string realpath(const string &name);
inline string userpath();
inline string currentpath();
inline string configpath();
//strm.hpp
inline unsigned strmcpy(char *target, const char *source, unsigned length);

View File

@ -146,6 +146,11 @@ string lstring::concatenate(const char *separator) const {
return output;
}
template<typename... Args> void lstring::append(const string &data, Args&&... args) {
vector::append(data);
append(std::forward<Args>(args)...);
}
bool lstring::operator==(const lstring &source) const {
if(this == &source) return true;
if(size() != source.size()) return false;
@ -159,11 +164,35 @@ bool lstring::operator!=(const lstring &source) const {
return !operator==(source);
}
inline lstring::lstring() {
lstring& lstring::operator=(const lstring &source) {
vector::operator=(source);
return *this;
}
inline lstring::lstring(std::initializer_list<string> list) {
for(auto &data : list) append(data);
lstring& lstring::operator=(lstring &source) {
vector::operator=(source);
return *this;
}
lstring& lstring::operator=(lstring &&source) {
vector::operator=(std::move(source));
return *this;
}
template<typename... Args> lstring::lstring(Args&&... args) {
append(std::forward<Args>(args)...);
}
lstring::lstring(const lstring &source) {
vector::operator=(source);
}
lstring::lstring(lstring &source) {
vector::operator=(source);
}
lstring::lstring(lstring &&source) {
vector::operator=(std::move(source));
}
}

View File

@ -2,36 +2,60 @@
namespace nall {
string currentpath() {
char path[PATH_MAX];
if(::getcwd(path)) {
string result(path);
result.transform("\\", "/");
if(result.endswith("/") == false) result.append("/");
return result;
}
return "./";
string activepath() {
string result;
#ifdef _WIN32
wchar_t path[PATH_MAX] = L"";
_wgetcwd(path, PATH_MAX);
result = (const char*)utf8_t(path);
result.transform("\\", "/");
#else
char path[PATH_MAX] = "";
getcwd(path, PATH_MAX);
result = path;
#endif
if(result.empty()) result = ".";
if(result.endswith("/") == false) result.append("/");
return result;
}
string realpath(const string &name) {
string result;
#ifdef _WIN32
wchar_t path[PATH_MAX] = L"";
if(_wfullpath(path, utf16_t(name), PATH_MAX)) result = (const char*)utf8_t(path);
result.transform("\\", "/");
#else
char path[PATH_MAX] = "";
if(::realpath(name, path)) result = path;
#endif
return result;
}
string userpath() {
char path[PATH_MAX];
if(::userpath(path)) {
string result(path);
result.transform("\\", "/");
if(result.endswith("/") == false) result.append("/");
return result;
}
return currentpath();
string result;
#ifdef _WIN32
wchar_t path[PATH_MAX] = L"";
SHGetFolderPathW(0, CSIDL_APPDATA | CSIDL_FLAG_CREATE, 0, 0, path);
result = (const char*)utf8_t(path);
result.transform("\\", "/");
#else
char path[PATH_MAX] = "";
struct passwd *userinfo = getpwuid(getuid());
if(userinfo) strcpy(path, userinfo->pw_dir);
result = path;
#endif
if(result.empty()) result = ".";
if(result.endswith("/") == false) result.append("/");
return result;
}
string realpath(const char *name) {
char path[PATH_MAX];
if(::realpath(name, path)) {
string result(path);
result.transform("\\", "/");
return result;
}
string configpath() {
#ifdef _WIN32
return userpath();
#else
return {userpath(), ".config/"};
#endif
}
}

View File

@ -1,5 +1,5 @@
#ifndef NALL_STATIC_HPP
#define NALL_STATIC_HPP
#ifndef NALL_TRAITS_HPP
#define NALL_TRAITS_HPP
#include <type_traits>

View File

@ -2,7 +2,7 @@
#define NALL_VARINT_HPP
#include <nall/bit.hpp>
#include <nall/type_traits.hpp>
#include <nall/traits.hpp>
namespace nall {
template<unsigned bits> struct uint_t {

30
bsnes/nall/windows/guid.hpp Executable file
View File

@ -0,0 +1,30 @@
#ifndef NALL_WINDOWS_GUID_HPP
#define NALL_WINDOWS_GUID_HPP
#include <nall/random.hpp>
#include <nall/string.hpp>
namespace nall {
//generate unique GUID
inline string guid() {
random_lfsr lfsr;
lfsr.seed(time(0));
for(unsigned n = 0; n < 256; n++) lfsr();
string output;
for(unsigned n = 0; n < 4; n++) output.append(hex<2>(lfsr()));
output.append("-");
for(unsigned n = 0; n < 2; n++) output.append(hex<2>(lfsr()));
output.append("-");
for(unsigned n = 0; n < 2; n++) output.append(hex<2>(lfsr()));
output.append("-");
for(unsigned n = 0; n < 2; n++) output.append(hex<2>(lfsr()));
output.append("-");
for(unsigned n = 0; n < 6; n++) output.append(hex<2>(lfsr()));
return {"{", output, "}"};
}
}
#endif

120
bsnes/nall/windows/registry.hpp Executable file
View File

@ -0,0 +1,120 @@
#ifndef NALL_WINDOWS_REGISTRY_HPP
#define NALL_WINDOWS_REGISTRY_HPP
#include <nall/platform.hpp>
#include <nall/string.hpp>
#include <shlwapi.h>
#ifndef KEY_WOW64_64KEY
#define KEY_WOW64_64KEY 0x0100
#endif
#ifndef KEY_WOW64_32KEY
#define KEY_WOW64_32KEY 0x0200
#endif
#ifndef NWR_FLAGS
#define NWR_FLAGS KEY_WOW64_64KEY
#endif
#ifndef NWR_SIZE
#define NWR_SIZE 4096
#endif
namespace nall {
struct registry {
static bool exists(const string &name) {
lstring part = name.split("/");
HKEY handle, rootKey = root(part.take(0));
string node = part.take();
string path = part.concatenate("\\");
if(RegOpenKeyExW(rootKey, utf16_t(path), 0, NWR_FLAGS | KEY_READ, &handle) == ERROR_SUCCESS) {
wchar_t data[NWR_SIZE] = L"";
DWORD size = NWR_SIZE * sizeof(wchar_t);
LONG result = RegQueryValueExW(handle, utf16_t(node), NULL, NULL, (LPBYTE)&data, (LPDWORD)&size);
RegCloseKey(handle);
if(result == ERROR_SUCCESS) return true;
}
return false;
}
static string read(const string &name) {
lstring part = name.split("/");
HKEY handle, rootKey = root(part.take(0));
string node = part.take();
string path = part.concatenate("\\");
if(RegOpenKeyExW(rootKey, utf16_t(path), 0, NWR_FLAGS | KEY_READ, &handle) == ERROR_SUCCESS) {
wchar_t data[NWR_SIZE] = L"";
DWORD size = NWR_SIZE * sizeof(wchar_t);
LONG result = RegQueryValueExW(handle, utf16_t(node), NULL, NULL, (LPBYTE)&data, (LPDWORD)&size);
RegCloseKey(handle);
if(result == ERROR_SUCCESS) return (const char*)utf8_t(data);
}
return "";
}
static void write(const string &name, const string &data = "") {
lstring part = name.split("/");
HKEY handle, rootKey = root(part.take(0));
string node = part.take(), path;
DWORD disposition;
for(unsigned n = 0; n < part.size(); n++) {
path.append(part[n]);
if(RegCreateKeyExW(rootKey, utf16_t(path), 0, NULL, 0, NWR_FLAGS | KEY_ALL_ACCESS, NULL, &handle, &disposition) == ERROR_SUCCESS) {
if(n == part.size() - 1) {
RegSetValueExW(handle, utf16_t(node), 0, REG_SZ, (BYTE*)(wchar_t*)utf16_t(data), (data.length() + 1) * sizeof(wchar_t));
}
RegCloseKey(handle);
}
path.append("\\");
}
}
static bool remove(const string &name) {
lstring part = name.split("/");
HKEY rootKey = root(part.take(0));
string node = part.take();
string path = part.concatenate("\\");
if(node.empty()) return SHDeleteKeyW(rootKey, utf16_t(path)) == ERROR_SUCCESS;
return SHDeleteValueW(rootKey, utf16_t(path), utf16_t(node)) == ERROR_SUCCESS;
}
static lstring contents(const string &name) {
lstring part = name.split("/"), result;
HKEY handle, rootKey = root(part.take(0));
part.remove();
string path = part.concatenate("\\");
if(RegOpenKeyExW(rootKey, utf16_t(path), 0, NWR_FLAGS | KEY_READ, &handle) == ERROR_SUCCESS) {
DWORD folders, nodes;
RegQueryInfoKey(handle, NULL, NULL, NULL, &folders, NULL, NULL, &nodes, NULL, NULL, NULL, NULL);
for(unsigned n = 0; n < folders; n++) {
wchar_t name[NWR_SIZE] = L"";
DWORD size = NWR_SIZE * sizeof(wchar_t);
RegEnumKeyEx(handle, n, (wchar_t*)&name, &size, NULL, NULL, NULL, NULL);
result.append({(const char*)utf8_t(name), "/"});
}
for(unsigned n = 0; n < nodes; n++) {
wchar_t name[NWR_SIZE] = L"";
DWORD size = NWR_SIZE * sizeof(wchar_t);
RegEnumValueW(handle, n, (wchar_t*)&name, &size, NULL, NULL, NULL, NULL);
result.append((const char*)utf8_t(name));
}
RegCloseKey(handle);
}
return result;
}
private:
static HKEY root(const string &name) {
if(name == "HKCR") return HKEY_CLASSES_ROOT;
if(name == "HKCC") return HKEY_CURRENT_CONFIG;
if(name == "HKCU") return HKEY_CURRENT_USER;
if(name == "HKLM") return HKEY_LOCAL_MACHINE;
if(name == "HKU" ) return HKEY_USERS;
return NULL;
}
};
}
#endif

View File

@ -12,6 +12,7 @@
#define UNICODE
#define _WIN32_WINNT 0x0501
#define NOMINMAX
#include <winsock2.h>
#include <windows.h>
#undef interface

View File

@ -80,28 +80,22 @@ struct zip {
return true;
}
inline bool extract(File &file, uint8_t *&data, unsigned &size) {
data = 0, size = 0;
inline vector<uint8_t> extract(File &file) {
vector<uint8_t> buffer;
if(file.cmode == 0) {
size = file.size;
data = new uint8_t[size];
memcpy(data, file.data, size);
return true;
buffer.resize(file.size);
memcpy(buffer.data(), file.data, file.size);
}
if(file.cmode == 8) {
size = file.size;
data = new uint8_t[size];
if(inflate(data, size, file.data, file.csize) == false) {
delete[] data;
size = 0;
return false;
buffer.resize(file.size);
if(inflate(buffer.data(), buffer.size(), file.data, file.csize) == false) {
buffer.reset();
}
return true;
}
return false;
return buffer;
}
inline void close() {

View File

@ -1058,6 +1058,7 @@ void ListView::modify_(unsigned row, const lstring &text) {
void ListView::reset() {
state.checked.reset();
state.image.reset();
state.text.reset();
return p.reset();
}
@ -1090,6 +1091,11 @@ void ListView::setHeaderVisible(bool visible) {
return p.setHeaderVisible(visible);
}
void ListView::setImage(unsigned row, unsigned column, const nall::image &image) {
state.image(row)(column) = image;
return p.setImage(row, column, image);
}
void ListView::setSelected(bool selected) {
state.selected = selected;
return p.setSelected(selected);

View File

@ -232,12 +232,12 @@ struct Action : Object {
};
struct Menu : private nall::base_from_member<pMenu&>, Action {
template<typename... Args> void append(Args&... args) { append({ args... }); }
template<typename... Args> void remove(Args&... args) { remove({ args... }); }
template<typename... Args> void append(Args&... args) { append({args...}); }
template<typename... Args> void remove(Args&... args) { remove({args...}); }
void append(const nall::set<Action&> &list);
void remove(const nall::set<Action&> &list);
void setImage(const nall::image &image);
void setImage(const nall::image &image = nall::image{});
void setText(const nall::string &text);
Menu();
@ -256,7 +256,7 @@ struct Separator : private nall::base_from_member<pSeparator&>, Action {
struct Item : private nall::base_from_member<pItem&>, Action {
nall::function<void ()> onActivate;
void setImage(const nall::image &image);
void setImage(const nall::image &image = nall::image{});
void setText(const nall::string &text);
Item();
@ -281,7 +281,7 @@ struct CheckItem : private nall::base_from_member<pCheckItem&>, Action {
};
struct RadioItem : private nall::base_from_member<pRadioItem&>, Action {
template<typename... Args> static void group(Args&... args) { group({ args... }); }
template<typename... Args> static void group(Args&... args) { group({args...}); }
static void group(const nall::set<RadioItem&> &list);
nall::function<void ()> onActivate;
@ -352,7 +352,7 @@ struct Widget : private nall::base_from_member<pWidget&>, Sizable {
struct Button : private nall::base_from_member<pButton&>, Widget {
nall::function<void ()> onActivate;
void setImage(const nall::image &image, Orientation = Orientation::Horizontal);
void setImage(const nall::image &image = nall::image{}, Orientation = Orientation::Horizontal);
void setText(const nall::string &text);
Button();
@ -398,7 +398,7 @@ struct CheckBox : private nall::base_from_member<pCheckBox&>, Widget {
struct ComboBox : private nall::base_from_member<pComboBox&>, Widget {
nall::function<void ()> onChange;
template<typename... Args> void append(const Args&... args) { append_({ args... }); }
template<typename... Args> void append(const Args&... args) { append_({args...}); }
void append_(const nall::lstring &list);
void reset();
@ -491,9 +491,9 @@ struct ListView : private nall::base_from_member<pListView&>, Widget {
nall::function<void ()> onChange;
nall::function<void (unsigned)> onToggle;
template<typename... Args> void append(const Args&... args) { append_({ args... }); }
template<typename... Args> void modify(unsigned row, const Args&... args) { modify_(row, { args... }); }
template<typename... Args> void setHeaderText(const Args&... args) { setHeaderText_({ args... }); }
template<typename... Args> void append(const Args&... args) { append_({args...}); }
template<typename... Args> void modify(unsigned row, const Args&... args) { modify_(row, {args...}); }
template<typename... Args> void setHeaderText(const Args&... args) { setHeaderText_({args...}); }
void append_(const nall::lstring &list);
void autoSizeColumns();
@ -506,6 +506,7 @@ struct ListView : private nall::base_from_member<pListView&>, Widget {
void setChecked(unsigned row, bool checked = true);
void setHeaderText_(const nall::lstring &list);
void setHeaderVisible(bool visible = true);
void setImage(unsigned row, unsigned column, const nall::image &image = nall::image{});
void setSelected(bool selected = true);
void setSelection(unsigned row);
@ -527,7 +528,7 @@ struct ProgressBar : private nall::base_from_member<pProgressBar&>, Widget {
};
struct RadioBox : private nall::base_from_member<pRadioBox&>, Widget {
template<typename... Args> static void group(Args&... args) { group({ args... }); }
template<typename... Args> static void group(Args&... args) { group({args...}); }
static void group(const nall::set<RadioBox&> &list);
nall::function<void ()> onActivate;

View File

@ -213,6 +213,7 @@ struct ListView::State {
vector<bool> checked;
lstring headerText;
bool headerVisible;
vector<vector<nall::image>> image;
bool selected;
unsigned selection;
vector<lstring> text;

View File

@ -3,8 +3,12 @@ static void Item_activate(Item *self) {
}
void pItem::setImage(const image &image) {
GtkImage *gtkImage = CreateImage(image, /* menuIcon = */ true);
gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(widget), (GtkWidget*)gtkImage);
if(image.empty() == false) {
GtkImage *gtkImage = CreateImage(image, true);
gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(widget), (GtkWidget*)gtkImage);
} else {
gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(widget), nullptr);
}
}
void pItem::setText(const string &text) {

View File

@ -14,8 +14,12 @@ void pMenu::remove(Action &action) {
}
void pMenu::setImage(const image &image) {
GtkImage *gtkImage = CreateImage(image, /* menuIcon = */ true);
gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(widget), (GtkWidget*)gtkImage);
if(image.empty() == false) {
GtkImage *gtkImage = CreateImage(image, true);
gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(widget), (GtkWidget*)gtkImage);
} else {
gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(widget), nullptr);
}
}
void pMenu::setText(const string &text) {

View File

@ -383,11 +383,11 @@ struct pListView : public pWidget {
GtkWidget *subWidget;
GtkListStore *store;
struct GtkColumn {
GtkCellRenderer *renderer;
GtkTreeViewColumn *column;
GtkCellRenderer *checkbox, *icon, *text;
GtkWidget *label;
};
linear_vector<GtkColumn> column;
vector<GtkColumn> column;
void append(const lstring &text);
void autoSizeColumns();
@ -400,6 +400,7 @@ struct pListView : public pWidget {
void setChecked(unsigned row, bool checked);
void setHeaderText(const lstring &text);
void setHeaderVisible(bool visible);
void setImage(unsigned row, unsigned column, const nall::image &image);
void setSelected(bool selected);
void setSelection(unsigned row);

View File

@ -1,13 +1,18 @@
static GtkImage* CreateImage(const nall::image &image, bool menuIcon = false) {
static GdkPixbuf* CreatePixbuf(const nall::image &image, bool scale = false) {
nall::image gdkImage = image;
gdkImage.transform(0, 32, 255u << 24, 255u << 0, 255u << 8, 255u << 16); //GTK+ uses ABGR format
if(menuIcon) gdkImage.scale(16, 16, Interpolation::Linear);
gdkImage.transform(0, 32, 255u << 24, 255u << 0, 255u << 8, 255u << 16);
if(scale) gdkImage.scale(15, 15, Interpolation::Linear);
GdkPixbuf *pixbuf = gdk_pixbuf_new(GDK_COLORSPACE_RGB, true, 8, gdkImage.width, gdkImage.height);
memcpy(gdk_pixbuf_get_pixels(pixbuf), gdkImage.data, gdkImage.width * gdkImage.height * 4);
return pixbuf;
}
static GtkImage* CreateImage(const nall::image &image, bool scale = false) {
GdkPixbuf *pixbuf = CreatePixbuf(image, scale);
GtkImage *gtkImage = (GtkImage*)gtk_image_new_from_pixbuf(pixbuf);
g_object_unref(pixbuf);
return gtkImage;
}

View File

@ -19,8 +19,12 @@ Geometry pButton::minimumGeometry() {
}
void pButton::setImage(const image &image, Orientation orientation) {
GtkImage *gtkImage = CreateImage(image);
gtk_button_set_image(GTK_BUTTON(gtkWidget), (GtkWidget*)gtkImage);
if(image.empty() == false) {
GtkImage *gtkImage = CreateImage(image);
gtk_button_set_image(GTK_BUTTON(gtkWidget), (GtkWidget*)gtkImage);
} else {
gtk_button_set_image(GTK_BUTTON(gtkWidget), nullptr);
}
switch(orientation) {
case Orientation::Horizontal: gtk_button_set_image_position(GTK_BUTTON(gtkWidget), GTK_POS_LEFT); break;
case Orientation::Vertical: gtk_button_set_image_position(GTK_BUTTON(gtkWidget), GTK_POS_TOP); break;

View File

@ -10,8 +10,8 @@ static void ListView_change(ListView *self) {
}
}
static void ListView_toggle(GtkCellRendererToggle *cell, gchar *path_string, ListView *self) {
unsigned row = decimal(path_string);
static void ListView_toggle(GtkCellRendererToggle *cell, gchar *path, ListView *self) {
unsigned row = decimal(path);
self->setChecked(row, !self->checked(row));
if(self->onToggle) self->onToggle(row);
}
@ -19,7 +19,7 @@ static void ListView_toggle(GtkCellRendererToggle *cell, gchar *path_string, Lis
void pListView::append(const lstring &text) {
GtkTreeIter iter;
gtk_list_store_append(store, &iter);
for(unsigned n = 0; n < text.size(); n++) gtk_list_store_set(store, &iter, 1 + n, (const char*)text[n], -1);
for(unsigned n = 0; n < text.size(); n++) gtk_list_store_set(store, &iter, 1 + n * 2 + 1, (const char*)text[n], -1);
}
void pListView::autoSizeColumns() {
@ -39,7 +39,7 @@ void pListView::modify(unsigned row, const lstring &text) {
GtkTreeModel *model = gtk_tree_view_get_model(GTK_TREE_VIEW(subWidget));
GtkTreeIter iter;
gtk_tree_model_get_iter_from_string(model, &iter, string(row));
for(unsigned n = 0; n < text.size(); n++) gtk_list_store_set(store, &iter, 1 + n, (const char*)text[n], -1);
for(unsigned n = 0; n < text.size(); n++) gtk_list_store_set(store, &iter, 1 + n * 2 + 1, (const char*)text[n], -1);
}
void pListView::reset() {
@ -69,7 +69,7 @@ unsigned pListView::selection() {
}
void pListView::setCheckable(bool checkable) {
gtk_tree_view_column_set_visible(column[0].column, checkable);
gtk_cell_renderer_set_visible(column(0).checkbox, checkable);
}
void pListView::setChecked(unsigned row, bool checked) {
@ -88,6 +88,18 @@ void pListView::setHeaderVisible(bool visible) {
gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(subWidget), visible);
}
void pListView::setImage(unsigned row, unsigned column, const nall::image &image) {
GtkTreeModel *model = gtk_tree_view_get_model(GTK_TREE_VIEW(subWidget));
GtkTreeIter iter;
gtk_tree_model_get_iter_from_string(model, &iter, string(row));
if(image.empty() == false) {
GdkPixbuf *pixbuf = CreatePixbuf(image, true);
gtk_list_store_set(store, &iter, 1 + column * 2, pixbuf, -1);
} else {
gtk_list_store_set(store, &iter, 1 + column * 2, nullptr, -1);
}
}
void pListView::setSelected(bool selected) {
if(selected == false) {
GtkTreeSelection *selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(subWidget));
@ -114,47 +126,56 @@ void pListView::setSelection(unsigned row) {
}
void pListView::constructor() {
gtkWidget = 0;
subWidget = 0;
gtkWidget = gtk_scrolled_window_new(0, 0);
gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(gtkWidget), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(gtkWidget), GTK_SHADOW_ETCHED_IN);
lstring headerText;
headerText.append(""); //checkbox column
for(auto &headerItem : listView.state.headerText) headerText.append(headerItem);
if(headerText.size() == 1) headerText.append("");
lstring headerText = listView.state.headerText;
if(headerText.size() == 0) headerText.append(""); //ListView must have at least one column
GType *v = (GType*)malloc(headerText.size() * sizeof(GType));
for(unsigned n = 0; n < headerText.size(); n++) v[n] = (n == 0 ? G_TYPE_BOOLEAN : G_TYPE_STRING);
store = gtk_list_store_newv(headerText.size(), v);
free(v);
column.reset();
vector<GType> gtype;
for(auto &text : headerText) {
GtkColumn cell;
cell.label = gtk_label_new(text);
cell.column = gtk_tree_view_column_new();
gtk_tree_view_column_set_resizable(cell.column, true);
gtk_tree_view_column_set_title(cell.column, "");
if(column.size() == 0) { //first column checkbox
cell.checkbox = gtk_cell_renderer_toggle_new();
gtk_tree_view_column_pack_start(cell.column, cell.checkbox, false);
gtk_tree_view_column_set_attributes(cell.column, cell.checkbox, "active", gtype.size(), nullptr);
gtype.append(G_TYPE_BOOLEAN);
g_signal_connect(cell.checkbox, "toggled", G_CALLBACK(ListView_toggle), (gpointer)&listView);
}
cell.icon = gtk_cell_renderer_pixbuf_new();
gtk_tree_view_column_pack_start(cell.column, cell.icon, false);
gtk_tree_view_column_set_attributes(cell.column, cell.icon, "pixbuf", gtype.size(), nullptr);
gtype.append(GDK_TYPE_PIXBUF);
cell.text = gtk_cell_renderer_text_new();
gtk_tree_view_column_pack_start(cell.column, cell.text, false);
gtk_tree_view_column_set_attributes(cell.column, cell.text, "text", gtype.size(), nullptr);
gtype.append(G_TYPE_STRING);
column.append(cell);
}
store = gtk_list_store_newv(gtype.size(), gtype.data());
subWidget = gtk_tree_view_new_with_model(GTK_TREE_MODEL(store));
gtk_container_add(GTK_CONTAINER(gtkWidget), subWidget);
g_object_unref(G_OBJECT(store));
for(unsigned n = 0; n < headerText.size(); n++) {
if(n == 0) {
column[n].renderer = gtk_cell_renderer_toggle_new();
column[n].column = gtk_tree_view_column_new_with_attributes("", column[n].renderer, "active", n, (void*)0);
gtk_tree_view_column_set_resizable(column[n].column, false);
gtk_tree_view_column_set_visible(column[n].column, false);
g_signal_connect(column[n].renderer, "toggled", G_CALLBACK(ListView_toggle), (gpointer)&listView);
} else {
column[n].renderer = gtk_cell_renderer_text_new();
column[n].column = gtk_tree_view_column_new_with_attributes("", column[n].renderer, "text", n, (void*)0);
gtk_tree_view_column_set_resizable(column[n].column, true);
}
column[n].label = gtk_label_new(headerText[n]);
gtk_tree_view_column_set_widget(GTK_TREE_VIEW_COLUMN(column[n].column), column[n].label);
gtk_tree_view_append_column(GTK_TREE_VIEW(subWidget), column[n].column);
gtk_widget_show(column[n].label);
for(auto &cell : column) {
gtk_tree_view_column_set_widget(GTK_TREE_VIEW_COLUMN(cell.column), cell.label);
gtk_tree_view_append_column(GTK_TREE_VIEW(subWidget), cell.column);
gtk_widget_show(cell.label);
}
gtk_tree_view_set_rules_hint(GTK_TREE_VIEW(subWidget), headerText.size() >= 3); //two or more columns + checkbox column
gtk_tree_view_set_search_column(GTK_TREE_VIEW(subWidget), 1);
gtk_tree_view_set_rules_hint(GTK_TREE_VIEW(subWidget), headerText.size() >= 2); //two or more columns + checkbox column
gtk_tree_view_set_search_column(GTK_TREE_VIEW(subWidget), 2);
g_signal_connect_swapped(G_OBJECT(subWidget), "cursor-changed", G_CALLBACK(ListView_change), (gpointer)&listView);
g_signal_connect_swapped(G_OBJECT(subWidget), "row-activated", G_CALLBACK(ListView_activate), (gpointer)&listView);
@ -185,7 +206,5 @@ void pListView::setFocused() {
void pListView::setFont(const string &font) {
pFont::setFont(gtkWidget, font);
for(unsigned n = 0; n < 1 + listView.state.headerText.size(); n++) {
pFont::setFont(column[n].label, font);
}
for(auto &cell : column) pFont::setFont(cell.label, font);
}

View File

@ -9,6 +9,7 @@
#define __MSVCRT_VERSION__ 0x0601
#define NOMINMAX
#include <winsock2.h>
#include <windows.h>
#include <windowsx.h>
#include <commctrl.h>

View File

@ -1,10 +1,5 @@
void pItem::setImage(const image &image) {
nall::image qtBuffer = image;
qtBuffer.transform(0, 32u, 255u << 24, 255u << 16, 255u << 8, 255u << 0);
QImage qtImage(qtBuffer.data, qtBuffer.width, qtBuffer.height, QImage::Format_ARGB32);
QIcon qtIcon(QPixmap::fromImage(qtImage));
qtAction->setIcon(qtIcon);
qtAction->setIcon(CreateIcon(image));
}
void pItem::setText(const string &text) {

View File

@ -34,12 +34,7 @@ void pMenu::setFont(const string &font) {
}
void pMenu::setImage(const image &image) {
nall::image qtBuffer = image;
qtBuffer.transform(0, 32u, 255u << 24, 255u << 16, 255u << 8, 255u << 0);
QImage qtImage(qtBuffer.data, qtBuffer.width, qtBuffer.height, QImage::Format_ARGB32);
QIcon qtIcon(QPixmap::fromImage(qtImage));
qtMenu->setIcon(qtIcon);
qtMenu->setIcon(CreateIcon(image));
}
void pMenu::setText(const string &text) {

View File

@ -1,7 +1,7 @@
/****************************************************************************
** Meta object code from reading C++ file 'platform.moc.hpp'
**
** Created: Tue May 1 09:36:37 2012
** Created: Sun Jun 17 11:38:40 2012
** by: The Qt Meta Object Compiler version 62 (Qt 4.6.3)
**
** WARNING! All changes made in this file will be lost!

View File

@ -493,6 +493,7 @@ public:
void setChecked(unsigned row, bool checked);
void setHeaderText(const lstring &text);
void setHeaderVisible(bool visible);
void setImage(unsigned row, unsigned column, const nall::image &image);
void setSelected(bool selected);
void setSelection(unsigned row);

View File

@ -1,3 +1,11 @@
static QIcon CreateIcon(const nall::image &image, bool scale = false) {
nall::image qtBuffer = image;
qtBuffer.transform(0, 32, 255u << 24, 255u << 16, 255u << 8, 255u << 0);
if(scale) qtBuffer.scale(16, 16, Interpolation::Linear);
QImage qtImage(qtBuffer.data, qtBuffer.width, qtBuffer.height, QImage::Format_ARGB32);
return QIcon(QPixmap::fromImage(qtImage));
}
static Keyboard::Keycode Keysym(int keysym) {
switch(keysym) {
case XK_Escape: return Keyboard::Keycode::Escape;

View File

@ -15,13 +15,8 @@ Geometry pButton::minimumGeometry() {
}
void pButton::setImage(const image &image, Orientation orientation) {
nall::image qtBuffer = image;
qtBuffer.transform(0, 32, 255u << 24, 255u << 16, 255u << 8, 255u << 0);
QImage qtImage(qtBuffer.data, qtBuffer.width, qtBuffer.height, QImage::Format_ARGB32);
QIcon qtIcon(QPixmap::fromImage(qtImage));
qtButton->setIconSize(QSize(qtBuffer.width, qtBuffer.height));
qtButton->setIcon(qtIcon);
qtButton->setIconSize(QSize(image.width, image.height));
qtButton->setIcon(CreateIcon(image));
qtButton->setStyleSheet("text-align: top;");
switch(orientation) {
case Orientation::Horizontal: qtButton->setToolButtonStyle(Qt::ToolButtonTextBesideIcon); break;

View File

@ -2,6 +2,7 @@ void pListView::append(const lstring &text) {
locked = true;
auto items = qtListView->findItems("", Qt::MatchContains);
QTreeWidgetItem *item = new QTreeWidgetItem(qtListView);
item->setData(0, Qt::UserRole, (unsigned)items.size());
if(listView.state.checkable) item->setCheckState(0, Qt::Unchecked);
for(unsigned n = 0; n < text.size(); n++) {
@ -73,6 +74,14 @@ void pListView::setHeaderVisible(bool visible) {
autoSizeColumns();
}
void pListView::setImage(unsigned row, unsigned column, const nall::image &image) {
QTreeWidgetItem *item = qtListView->topLevelItem(row);
if(item) {
if(image.empty() == 0) item->setIcon(column, CreateIcon(image));
if(image.empty() == 1) item->setIcon(column, QIcon());
}
}
void pListView::setSelected(bool selected) {
QTreeWidgetItem *item = qtListView->currentItem();
if(item) item->setSelected(selected);

View File

@ -368,6 +368,7 @@ struct pLineEdit : public pWidget {
struct pListView : public pWidget {
ListView &listView;
HIMAGELIST imageList;
bool lostFocus;
void append(const lstring &text);
@ -381,14 +382,16 @@ struct pListView : public pWidget {
void setChecked(unsigned row, bool checked);
void setHeaderText(const lstring &text);
void setHeaderVisible(bool visible);
void setImage(unsigned row, unsigned column, const image &image);
void setSelected(bool selected);
void setSelection(unsigned row);
pListView(ListView &listView) : pWidget(listView), listView(listView) {}
pListView(ListView &listView) : pWidget(listView), listView(listView), imageList(nullptr) {}
void constructor();
void destructor();
void orphan();
void setGeometry(const Geometry &geometry);
void setImageList();
};
struct pProgressBar : public pWidget {

View File

@ -2,9 +2,10 @@ void pListView::append(const lstring &list) {
wchar_t empty[] = L"";
unsigned row = ListView_GetItemCount(hwnd);
LVITEM item;
item.mask = LVIF_TEXT;
item.mask = LVIF_TEXT | LVIF_IMAGE;
item.iItem = row;
item.iSubItem = 0;
item.iImage = row;
item.pszText = empty;
locked = true;
ListView_InsertItem(hwnd, &item);
@ -88,6 +89,11 @@ void pListView::setHeaderVisible(bool visible) {
);
}
void pListView::setImage(unsigned row, unsigned column, const image &image) {
if(column != 0) return; //ListView can only set icons on first column
setImageList();
}
void pListView::setSelected(bool selected) {
locked = true;
lostFocus = false;
@ -118,6 +124,7 @@ void pListView::constructor() {
setHeaderText(listView.state.headerText);
setHeaderVisible(listView.state.headerVisible);
setCheckable(listView.state.checkable);
setImageList();
for(auto &text : listView.state.text) append(text);
for(unsigned n = 0; n < listView.state.checked.size(); n++) setChecked(n, listView.state.checked[n]);
if(listView.state.selected) setSelection(listView.state.selection);
@ -138,3 +145,33 @@ void pListView::setGeometry(const Geometry &geometry) {
pWidget::setGeometry(geometry);
autoSizeColumns();
}
void pListView::setImageList() {
if(imageList) {
ImageList_Destroy(imageList);
imageList = nullptr;
}
unsigned images = 0;
for(auto &image : listView.state.image) {
if(image.empty() == false) images++;
}
if(images == 0) return;
imageList = ImageList_Create(16, 16, ILC_COLOR32, listView.state.text.size(), 0);
for(unsigned rowID = 0; rowID < listView.state.image.size(); rowID++) {
auto &row = listView.state.image(rowID);
nall::image image = row(0);
if(image.empty()) {
image.allocate(16, 16);
image.clear(~0);
}
image.transform(0, 32, 255u << 24, 255u << 16, 255u << 8, 255u << 0);
image.scale(16, 16, Interpolation::Linear);
HBITMAP hbitmap = CreateBitmap(image);
ImageList_Add(imageList, hbitmap, NULL);
}
ListView_SetImageList(hwnd, imageList, LVSIL_SMALL);
}

View File

@ -68,6 +68,9 @@ else
$(strip $(cpp) -o out/$(name) $(objects) $(link))
endif
resource:
sourcery $(ui)/resource/resource.xml $(ui)/resource/resource.cpp $(ui)/resource/resource.hpp
install:
ifeq ($(USER),root)
@echo Please do not run make install as root.

View File

@ -1,5 +1,6 @@
#include "ethos.hpp"
#include "bootstrap.cpp"
#include "resource/resource.cpp"
Application *application = nullptr;
DSP dspaudio;
@ -57,13 +58,8 @@ Application::Application(int argc, char **argv) {
pause = false;
autopause = false;
char path[PATH_MAX];
auto unused = ::realpath(argv[0], path);
basepath = dir(path);
unused = ::userpath(path);
userpath = path;
if(Intrinsics::platform() != Intrinsics::Platform::Windows) userpath.append(".config/");
userpath.append("bsnes/");
basepath = realpath(argv[0]);
userpath = {nall::configpath(), "bsnes/"};
directory::create(userpath);
bootstrap();
@ -145,6 +141,13 @@ int main(int argc, char **argv) {
#if defined(PLATFORM_WINDOWS)
utf8_args(argc, argv);
#endif
//convert file to game folder; purify will then invoke bsnes with game folder
if(argc == 2 && !directory::exists(argv[1]) && file::exists(argv[1])) {
invoke("purify", argv[1]);
return 0;
}
new Application(argc, argv);
delete application;
return 0;

View File

@ -4,6 +4,7 @@
#include <nall/config.hpp>
#include <nall/directory.hpp>
#include <nall/dsp.hpp>
#include <nall/invoke.hpp>
#include <nall/map.hpp>
#include <nall/stream/file.hpp>
#include <nall/stream/memory.hpp>
@ -25,6 +26,7 @@ using namespace ruby;
#include "general/general.hpp"
#include "settings/settings.hpp"
#include "tools/tools.hpp"
#include "resource/resource.hpp"
Emulator::Interface& system();

View File

@ -163,9 +163,9 @@ void Browser::setPath(const string &path, unsigned selection) {
if(!filename.wildcard(R"(*.??/)") && !filename.wildcard(R"(*.???/)")) {
string name = filename;
name.rtrim<1>("/");
name = {"[ ", name, " ]"};
filenameList.append(filename);
fileList.append(name);
fileList.setImage(filenameList.size(), 0, image(resource::folder, sizeof resource::folder));
filenameList.append(filename);
}
}
@ -175,8 +175,9 @@ void Browser::setPath(const string &path, unsigned selection) {
if(filename.endswith(suffix)) {
string name = filename;
name.rtrim<1>(suffix);
filenameList.append(filename);
fileList.append(name);
fileList.setImage(filenameList.size(), 0, image(resource::game, sizeof resource::game));
filenameList.append(filename);
}
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 844 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

View File

@ -0,0 +1,173 @@
namespace resource {
const uint8_t folder[1176] = {
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,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,
97,112,101,46,111,114,103,155,238,60,26,0,0,4,21,73,68,65,84,88,133,237,151,61,111,28,69,24,199,127,51,187,
119,123,175,246,57,145,48,9,5,86,148,194,31,0,9,5,33,83,110,149,130,26,137,2,90,58,62,64,36,62,64,74,
132,68,133,104,161,67,72,167,64,23,201,138,2,138,210,69,194,198,196,40,22,198,247,186,119,222,151,153,157,25,138,123,
201,58,119,142,19,114,82,40,248,75,143,118,118,118,247,121,126,243,60,51,179,187,34,12,67,94,167,228,107,141,254,95,
0,240,1,110,220,184,225,43,165,126,54,198,188,119,209,3,66,136,220,90,251,249,195,135,15,191,92,25,64,154,166,91,
149,74,229,157,155,55,111,250,73,146,224,156,3,192,90,11,48,63,159,182,253,59,119,238,220,222,222,222,254,254,209,163,
71,199,43,1,80,74,101,213,106,213,29,29,29,209,233,116,112,206,45,53,0,33,4,155,155,155,249,193,193,193,71,192,
237,149,0,104,173,211,44,203,196,165,75,27,24,99,176,214,158,9,92,204,132,16,130,106,181,90,63,60,60,252,98,123,
123,251,214,172,127,153,156,115,218,90,251,241,222,222,222,143,207,5,0,178,44,203,188,78,167,75,167,211,153,3,204,142,
179,32,197,64,91,91,91,245,70,163,65,179,217,68,8,129,16,2,0,41,229,188,29,69,17,247,238,221,187,5,60,31,
224,242,229,203,105,191,223,247,54,54,90,104,173,23,0,150,149,98,166,56,142,1,230,16,69,139,227,24,99,76,237,188,
224,115,128,221,221,93,117,237,218,53,217,235,245,230,25,0,150,130,204,178,81,212,108,196,197,224,82,202,25,64,229,66,
0,0,99,140,109,54,215,100,154,102,220,63,180,220,221,63,27,228,188,58,63,171,25,204,228,153,22,206,93,185,206,219,
31,232,226,61,158,39,190,93,255,253,155,79,206,0,56,231,116,183,219,245,187,221,46,143,59,13,62,253,240,93,174,191,
181,81,112,54,61,62,47,250,18,200,105,207,60,206,147,206,152,175,190,187,255,254,236,188,152,1,221,104,212,171,90,107,
212,31,146,102,181,204,254,223,99,162,56,159,140,108,233,104,207,35,17,11,77,1,52,42,62,42,211,8,65,103,118,121,
190,21,27,99,116,191,63,160,219,237,18,103,150,122,181,132,53,147,27,228,212,193,179,134,59,207,220,83,179,19,179,214,
145,100,134,52,203,193,137,249,6,86,44,65,86,169,4,180,90,45,50,35,168,5,37,172,83,120,114,53,175,139,113,154,
83,111,250,140,134,57,214,186,39,11,0,121,158,171,40,26,209,239,15,208,230,13,170,129,143,115,14,79,158,155,231,23,
147,131,81,170,209,185,37,240,37,113,170,173,49,249,209,2,128,49,38,43,151,75,84,155,27,172,213,202,56,64,10,177,
188,248,47,40,227,28,163,84,147,91,135,231,9,130,178,199,105,146,41,33,196,201,2,128,181,54,27,141,198,28,15,20,
235,245,75,232,220,190,210,232,51,109,137,51,3,78,224,79,253,148,61,201,232,84,229,130,167,147,176,152,129,212,247,125,
188,32,160,73,153,76,217,11,131,76,230,152,195,186,201,62,97,236,196,84,110,151,173,72,156,131,193,40,181,185,115,139,
0,214,218,100,60,30,211,25,248,84,90,101,162,68,147,233,233,75,8,200,141,69,27,135,206,45,185,153,110,203,47,153,
149,68,25,134,227,196,19,210,91,90,130,84,8,129,12,26,148,74,62,163,68,19,37,154,84,25,148,182,47,29,108,153,
226,44,231,52,209,62,231,148,32,142,227,83,122,81,133,74,13,30,159,196,12,99,189,212,209,191,145,0,134,177,66,25,
83,250,245,234,94,47,124,252,12,128,181,54,6,129,245,107,100,185,37,138,53,74,95,60,15,94,84,82,10,78,134,9,
82,200,56,220,221,157,59,62,51,7,146,36,33,74,12,87,175,4,84,3,143,160,188,186,111,86,41,4,105,170,144,82,
12,139,253,197,18,36,0,154,18,235,85,143,122,105,21,85,127,42,231,28,253,36,65,88,59,88,0,104,183,219,98,103,
103,199,68,177,98,112,234,248,243,100,136,236,190,226,14,184,68,199,199,67,155,36,195,7,187,237,118,45,12,195,120,14,
0,120,81,20,253,244,203,161,248,76,173,227,255,182,255,202,31,187,103,228,192,2,88,157,30,28,63,248,225,235,226,53,
49,251,53,107,183,219,205,96,109,237,205,90,208,218,116,56,41,133,92,201,18,200,141,49,42,75,107,185,16,121,62,58,
233,1,127,133,97,216,91,0,152,66,72,32,96,146,153,124,21,0,83,5,64,10,168,48,12,207,44,45,241,255,207,233,
235,6,248,7,188,50,165,151,203,8,55,43,0,0,0,0,73,69,78,68,174,66,96,130,
};
const uint8_t game[844] = {
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,3,3,73,68,65,84,88,133,229,151,79,110,212,
48,24,197,127,182,227,56,81,39,116,36,132,0,169,167,226,2,101,209,93,239,192,150,37,171,46,43,245,4,92,164,183,
40,82,89,21,36,134,84,76,18,59,44,90,91,142,243,103,50,21,59,62,201,138,227,120,236,247,189,247,252,37,3,255,
123,136,116,224,234,234,234,67,150,101,55,64,165,148,66,74,137,115,14,107,109,104,93,215,133,107,220,95,26,3,118,93,
215,125,188,185,185,249,26,239,151,141,16,9,113,125,113,113,81,61,247,195,120,223,247,131,121,241,253,202,126,117,121,121,
121,13,44,3,176,214,110,1,110,111,111,17,66,32,165,12,87,41,37,74,41,148,82,8,33,80,74,177,221,110,209,90,
15,158,167,125,33,4,251,253,158,166,105,182,233,126,50,29,232,251,30,33,68,104,64,88,208,55,207,78,215,117,24,99,
70,191,247,109,77,140,24,112,206,133,13,98,6,210,38,165,164,40,138,48,127,42,60,16,159,200,20,168,17,3,206,185,
17,11,177,4,49,40,231,28,77,211,28,204,114,137,141,17,0,107,109,232,207,177,224,159,41,165,208,90,31,100,97,9,
200,36,3,233,230,233,189,181,150,60,207,41,203,146,186,174,233,186,46,204,91,202,124,21,0,207,192,156,9,1,140,49,
20,69,65,93,215,100,89,70,158,231,3,173,231,50,127,17,128,88,123,127,239,105,55,198,96,140,161,109,219,85,174,95,
13,96,202,132,41,35,62,218,182,5,240,213,110,113,211,163,25,72,179,23,66,208,52,13,90,235,80,92,252,243,199,199,
199,229,244,97,210,172,7,37,136,93,47,165,164,170,42,178,44,67,8,193,201,201,73,232,151,101,57,152,63,197,194,139,
37,136,77,168,181,198,90,27,42,97,215,117,97,222,210,113,92,205,128,215,50,205,222,103,16,75,226,156,11,12,120,64,
62,203,41,38,142,146,32,213,190,239,123,172,181,225,69,228,105,143,193,214,117,141,115,110,86,134,163,0,196,11,11,33,
200,178,140,170,170,6,115,235,186,14,114,120,79,40,165,70,155,28,205,64,74,181,7,32,165,28,248,195,24,67,158,231,
1,172,82,106,117,89,158,5,144,158,231,212,7,113,40,165,6,12,120,169,210,170,184,20,171,142,161,47,54,177,254,254,
236,123,205,227,58,177,219,237,86,3,152,250,34,26,80,37,132,96,179,217,80,150,229,200,96,155,205,6,173,245,96,190,
49,38,48,177,6,196,162,9,189,15,178,44,27,140,123,96,109,219,142,36,136,95,90,107,98,214,3,177,9,211,240,99,
190,8,77,197,161,162,52,11,32,149,96,238,37,3,79,18,164,0,60,232,135,135,135,17,107,171,1,132,135,82,6,157,
227,240,0,119,187,221,8,160,63,5,167,167,167,65,138,163,62,201,226,5,189,235,167,88,232,251,30,173,245,36,56,95,
71,252,247,229,82,164,167,160,146,82,254,234,251,254,213,217,217,89,24,156,211,185,40,138,197,197,211,242,155,231,249,14,
120,7,252,4,246,41,128,10,120,115,127,127,255,249,252,252,252,19,80,46,174,190,50,242,60,167,105,26,132,16,127,238,
238,238,190,0,239,1,5,124,7,92,156,90,14,188,5,94,3,91,192,60,79,252,23,241,135,167,100,107,224,7,240,13,
248,13,19,127,78,159,55,46,158,1,173,43,103,135,195,1,45,79,180,239,129,96,140,191,182,58,238,12,241,249,173,246,
0,0,0,0,73,69,78,68,174,66,96,130,
};
const uint8_t home[1774] = {
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,6,165,73,68,65,84,88,133,213,151,105,108,84,
215,21,199,127,119,121,111,54,143,199,96,199,118,48,120,12,184,200,20,8,187,218,34,71,8,186,56,106,80,165,162,42,
180,105,138,132,148,168,74,34,65,84,5,169,223,218,74,249,148,79,17,81,149,46,18,4,186,80,86,41,105,43,149,6,
21,53,4,137,184,13,132,8,154,64,98,226,98,48,216,96,60,216,99,207,246,238,189,253,48,11,94,134,85,202,135,30,
233,74,119,222,61,239,156,255,57,231,127,206,220,7,255,207,178,79,202,151,255,32,196,173,189,48,231,97,109,136,135,121,
105,63,248,40,181,167,177,161,225,137,150,154,154,218,211,189,189,253,129,49,223,120,26,62,249,194,1,236,129,198,136,214,
239,44,152,55,111,65,219,172,89,225,220,208,16,35,233,52,167,251,250,6,242,65,240,157,31,66,247,131,216,147,15,162,
252,59,88,17,11,133,78,175,90,190,124,113,91,91,91,24,41,113,64,196,247,89,222,218,218,20,246,188,191,254,17,190,
249,133,0,216,175,212,143,106,107,106,254,222,217,217,57,171,190,177,81,34,37,40,5,66,224,128,144,231,177,44,153,108,
8,249,254,159,246,41,245,131,251,181,123,207,18,252,28,228,66,165,94,111,104,106,122,122,197,170,85,117,74,74,48,6,
172,197,166,82,216,225,97,50,198,96,0,7,4,214,114,238,242,229,155,153,92,238,23,155,172,221,113,47,251,234,174,81,
67,226,17,173,143,182,119,116,60,177,100,245,234,90,169,74,234,66,96,135,134,112,195,195,20,140,33,164,20,198,57,140,
115,32,4,245,181,181,145,145,92,238,171,223,181,182,246,128,181,255,120,168,12,236,134,5,49,207,59,178,108,205,154,217,
77,173,173,26,107,193,24,92,16,96,47,93,34,184,117,139,51,195,67,92,29,188,193,202,100,146,230,104,148,113,107,201,
58,135,3,44,112,113,96,96,100,52,157,62,248,61,99,158,21,197,4,77,147,170,28,216,171,212,147,181,53,53,239,117,
110,216,208,214,212,222,174,81,10,164,196,25,131,189,120,145,241,155,55,121,127,104,144,196,75,219,88,117,234,20,255,77,
196,232,73,143,18,149,146,112,137,19,56,199,220,198,198,218,153,137,196,83,7,180,126,235,24,232,251,202,192,1,173,127,
22,111,104,216,246,149,174,174,25,94,36,82,140,218,90,220,200,8,230,252,121,110,142,142,114,46,147,38,249,203,55,136,
44,121,12,99,12,194,90,174,253,244,101,212,169,51,44,138,215,146,3,70,140,193,81,12,123,32,149,202,12,14,15,127,
48,28,4,93,63,134,241,170,0,118,65,56,166,212,161,57,11,22,60,190,120,253,250,184,152,72,182,129,1,204,133,11,
92,74,167,185,18,9,51,255,205,221,200,250,122,130,32,64,74,137,148,18,107,45,67,191,122,131,244,222,189,44,79,212,
97,132,32,101,12,22,112,206,145,74,167,115,253,55,110,156,79,7,193,218,45,144,42,251,85,0,191,135,217,81,173,79,
44,237,236,92,249,165,181,107,163,229,246,66,8,108,111,47,193,133,11,156,75,167,73,127,121,33,237,187,247,32,227,113,
140,49,68,34,17,102,206,156,73,44,22,195,24,67,120,197,74,188,214,57,124,124,228,8,205,218,35,170,53,89,231,176,
128,239,251,58,234,251,245,217,241,241,167,190,237,220,129,183,32,93,201,192,62,41,251,31,223,184,177,57,49,127,126,49,
35,214,226,130,0,243,209,71,100,251,250,248,112,116,148,25,155,55,211,244,194,11,24,99,176,214,18,139,197,8,135,195,
147,202,151,201,100,200,100,50,100,207,158,165,231,249,231,89,18,10,81,19,10,113,221,24,10,37,114,230,179,89,219,123,
245,234,21,107,204,186,239,67,143,4,208,74,229,18,237,237,2,165,64,41,156,49,4,221,221,140,124,254,57,221,35,35,
204,126,245,85,154,95,124,17,231,28,74,41,18,137,4,190,239,99,173,173,44,99,12,190,239,83,83,83,67,108,233,82,
58,14,29,226,172,148,220,200,100,104,212,26,191,68,78,29,10,201,185,45,45,115,164,82,255,156,220,5,165,201,230,198,
198,8,222,125,151,107,151,47,243,161,181,44,58,120,144,196,186,117,56,231,208,90,19,141,70,75,73,154,236,188,188,23,
66,16,137,68,8,183,180,176,248,237,183,185,212,216,72,239,216,24,141,90,19,41,129,144,158,135,86,202,77,107,67,55,
48,64,225,216,49,46,12,14,114,233,209,71,89,126,228,8,225,121,243,0,240,60,15,207,243,38,57,158,234,124,226,242,
60,15,47,145,96,225,254,253,140,173,94,205,127,70,71,121,68,41,226,82,34,197,237,230,171,0,48,159,125,70,238,248,
113,78,246,247,19,172,95,207,99,135,15,35,227,113,156,115,72,41,17,66,220,151,243,169,217,144,158,199,188,215,94,35,
252,204,51,188,63,52,196,12,41,153,33,111,199,173,1,2,99,194,215,78,158,228,124,42,53,58,190,105,83,108,197,43,
175,72,107,45,184,226,240,114,206,225,220,228,65,86,254,45,132,64,107,141,16,98,154,78,89,207,24,67,203,214,173,28,
239,233,41,4,71,143,6,29,241,120,36,31,4,53,21,0,57,107,215,255,187,175,239,196,220,45,91,126,114,184,174,110,
215,215,149,34,8,2,142,30,125,135,177,241,177,138,163,169,18,141,196,232,234,234,98,199,142,215,201,231,115,211,206,1,
60,63,196,75,219,182,146,207,231,25,156,63,63,104,59,113,226,91,31,244,247,255,165,96,237,154,10,128,205,240,49,206,
205,100,231,78,182,111,223,190,171,194,234,144,207,167,61,231,39,25,20,66,84,192,44,236,88,132,115,142,124,62,135,73,
62,137,239,41,60,45,49,198,146,47,88,114,133,0,174,252,13,231,28,133,66,1,165,84,102,99,127,255,123,64,221,52,
14,76,148,114,13,91,231,180,162,181,174,16,208,247,253,202,222,243,60,146,173,73,172,181,37,96,32,5,40,33,138,36,
155,144,176,114,25,172,181,211,106,84,245,15,194,57,135,181,150,100,50,137,214,85,85,0,104,104,104,168,0,24,207,6,
228,242,134,241,92,192,173,177,28,35,99,57,50,57,195,215,162,197,128,74,99,59,255,64,0,148,214,149,72,68,105,35,
25,71,139,94,242,174,3,4,21,0,255,250,228,90,117,148,81,38,118,69,97,234,241,93,75,80,118,44,40,165,84,128,
39,62,101,195,154,63,163,196,40,80,157,249,213,196,24,131,115,46,152,250,252,142,25,48,198,128,115,147,217,47,32,207,
50,14,28,95,92,41,77,113,232,248,172,171,59,83,213,177,246,138,35,187,80,40,32,165,204,62,16,0,237,121,20,131,
159,220,130,158,231,21,241,8,200,102,179,60,247,220,179,85,219,180,108,43,151,203,149,203,122,207,12,132,202,81,89,107,
145,66,86,53,60,17,80,62,159,39,159,191,205,173,106,37,145,82,82,40,20,8,130,192,2,13,20,239,3,193,84,0,
62,80,47,132,8,178,217,172,142,199,227,147,122,254,78,18,143,199,239,122,94,6,116,253,250,117,10,133,130,1,154,75,
126,7,1,59,17,128,6,252,84,42,245,230,206,157,59,183,56,231,238,122,99,6,248,205,175,127,123,47,149,138,8,33,
178,221,221,221,123,129,48,197,96,5,76,190,19,10,160,190,180,106,75,74,119,30,2,15,38,121,138,183,175,12,112,11,
184,12,100,167,2,40,139,7,68,74,72,31,234,227,181,138,56,160,80,114,154,101,194,21,253,127,69,252,95,225,237,227,
107,122,0,0,0,0,73,69,78,68,174,66,96,130,
};
const uint8_t up[1193] = {
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,4,96,73,68,65,84,88,133,237,150,91,108,21,
85,20,134,191,53,123,79,79,123,106,67,209,88,229,22,16,68,169,36,74,90,77,161,165,4,49,84,226,37,165,68,76,
68,209,68,162,49,193,75,144,2,79,18,12,198,24,19,140,36,198,7,194,19,193,224,131,81,12,225,1,19,12,81,210,
234,131,196,11,105,20,17,164,180,180,182,5,122,161,237,233,57,51,123,249,48,231,148,114,122,7,53,62,176,146,149,61,
151,61,235,255,214,218,107,207,12,220,180,235,180,133,59,200,41,223,98,171,110,52,142,119,189,15,22,246,153,61,190,228,
28,41,175,245,95,255,207,1,42,54,251,175,204,188,125,254,218,87,159,126,155,91,242,10,222,45,175,181,43,254,51,128,
138,45,182,114,74,193,173,187,170,151,61,27,239,13,46,178,250,225,231,242,173,245,63,95,178,41,118,247,191,14,176,236,
77,102,249,38,231,208,83,143,108,136,95,184,114,138,227,103,62,35,48,9,170,150,172,46,240,108,240,85,233,54,166,76,
22,192,76,116,98,233,14,226,38,180,117,107,150,191,56,45,22,183,210,208,242,45,78,67,90,187,255,96,193,244,135,196,
154,88,126,91,123,83,249,226,233,110,127,67,3,58,209,184,19,173,128,228,246,218,3,203,23,61,49,103,214,157,115,188,
134,214,227,128,32,34,56,13,249,254,220,33,22,45,88,156,115,215,180,249,101,205,115,236,174,137,138,195,4,43,80,81,
107,223,42,158,93,242,194,202,178,53,185,39,154,142,48,144,234,195,105,152,246,128,100,208,79,71,111,35,75,239,123,210,
63,219,116,234,254,59,74,18,77,141,245,250,211,63,2,80,94,107,30,47,154,58,99,247,51,85,27,227,191,182,213,211,
157,104,31,20,15,53,24,60,238,29,232,164,63,213,67,217,130,149,254,111,231,78,86,205,92,204,209,198,58,215,60,94,
252,49,151,160,98,107,236,222,88,44,254,233,250,85,155,226,45,61,167,233,236,255,107,204,96,127,94,250,133,214,222,211,
60,186,180,38,95,61,14,151,109,101,230,117,3,148,110,99,138,186,224,232,243,171,222,200,15,164,143,11,93,191,95,115,
95,7,251,236,106,191,169,58,126,110,254,26,155,11,149,37,43,11,125,181,71,74,119,16,159,52,192,218,181,152,152,179,
95,86,87,174,47,42,154,58,93,78,183,159,64,85,35,81,81,196,3,99,4,207,130,103,5,49,74,64,2,149,16,69,
169,63,123,144,217,51,230,154,226,185,15,204,203,237,181,7,0,25,13,96,196,30,40,124,204,126,248,96,241,178,234,21,
37,53,177,147,173,223,144,12,163,224,78,2,144,16,53,33,206,115,168,164,72,184,110,18,97,15,120,14,207,19,196,3,
167,1,45,93,103,169,92,88,109,91,219,155,103,221,182,232,138,223,88,231,142,141,164,53,140,108,105,173,89,55,163,104,
222,222,141,53,59,243,16,33,21,246,227,8,49,158,225,216,153,125,4,12,16,184,36,61,169,14,186,19,109,56,13,81,
64,29,168,42,53,197,219,80,141,142,213,129,11,149,253,135,63,238,239,25,232,92,87,255,126,120,48,91,207,102,95,112,
42,159,180,116,156,103,251,222,13,17,161,224,84,241,182,191,244,17,98,20,65,233,74,94,160,55,184,140,248,96,240,96,
80,80,240,140,176,123,223,59,136,146,194,35,36,130,203,19,228,139,145,18,30,6,80,183,43,16,8,6,207,75,95,198,
143,21,216,36,158,130,113,92,236,63,71,66,59,177,57,2,146,142,151,22,119,78,17,3,162,132,97,104,239,177,126,162,
11,64,12,132,3,36,70,90,130,97,0,217,246,195,30,82,229,155,1,148,75,3,231,73,104,23,198,23,36,189,222,81,
134,130,58,69,156,224,121,2,30,97,202,38,46,127,247,30,93,227,197,31,23,32,99,41,77,208,19,182,97,108,84,102,
207,128,164,43,160,170,184,80,144,80,17,111,212,134,191,49,128,190,160,19,207,128,103,36,130,176,130,151,174,128,115,130,
72,244,62,144,201,233,79,28,32,233,250,240,109,12,188,212,85,8,19,169,73,168,81,35,58,29,99,199,223,32,128,162,
8,130,10,145,136,48,8,224,50,194,50,105,253,9,1,216,52,65,122,127,71,153,106,40,132,184,232,86,152,190,166,87,
95,204,29,63,18,7,6,136,182,84,48,82,224,177,0,12,224,15,113,172,228,80,53,251,53,60,143,104,7,200,181,77,
152,1,115,14,80,228,74,51,133,128,3,82,89,30,142,7,96,128,156,44,231,131,189,59,71,45,209,8,230,39,218,177,
64,94,90,195,16,125,119,132,168,42,46,51,113,164,37,19,32,150,206,60,3,224,15,25,51,62,52,176,75,103,22,100,
101,155,28,50,38,211,226,201,108,177,209,204,203,130,176,67,68,51,194,67,191,166,110,8,200,80,152,140,104,0,195,255,
21,39,211,180,153,18,102,143,164,3,103,60,3,146,57,191,105,255,111,251,27,250,226,227,129,148,124,126,213,0,0,0,
0,73,69,78,68,174,66,96,130,
};
};

View File

@ -0,0 +1,6 @@
namespace resource {
extern const uint8_t folder[1176];
extern const uint8_t game[844];
extern const uint8_t home[1774];
extern const uint8_t up[1193];
};

View File

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<resource name="resource">
<binary id="folder" name="folder.png"/>
<binary id="game" name="game.png"/>
<binary id="home" name="home.png"/>
<binary id="up" name="up.png"/>
</resource>

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB