mirror of https://github.com/bsnes-emu/bsnes.git
Update to bsnes v032 release.
- Core: simplified CPU / SMP flag calculations - Added ALSA audio output driver to Linux port [Nach] - Improved font handling for Windows and Linux ports - Greatly cleaned up the user interface - Windows port now uses Unicode instead of ANSI - Added localization support - Config and locale files can now be placed inside bsnes executable directory for single-user mode, if desired - Fixed crashing bug with HQ2x on Linux/amd64 port [RedDwarf, Nach] - Hid "Power Cycle" option by default, as it is too similar to "Reset" - Slighty tweaked program icon [FitzRoy] - Minor code cleanups -- replaced union bitfields with templates, improved memory allocation, etc
This commit is contained in:
parent
96fe8f760d
commit
ebb9367c68
29
readme.txt
29
readme.txt
|
@ -1,5 +1,5 @@
|
|||
bsnes
|
||||
Version: 0.031
|
||||
Version: 0.032
|
||||
Author: byuu
|
||||
|
||||
--------
|
||||
|
@ -13,6 +13,29 @@ http://byuu.org/
|
|||
|
||||
Please see license.txt for important licensing information.
|
||||
|
||||
--------------
|
||||
Configuration:
|
||||
--------------
|
||||
bsnes has two configuration files: bsnes.cfg, for program settings; and
|
||||
locale.cfg, for localization.
|
||||
|
||||
For each file, bsnes will start by looking inside the same folder where the
|
||||
bsnes executable is located. If said file is not found, it will then check your
|
||||
user profile folder. On Windows, this is located at "%APPDATA%/.bsnes". On all
|
||||
other operating systems, this is located at "~/.bsnes". If said file is still
|
||||
not found, it will automatically be created in your user profile folder.
|
||||
|
||||
If you wish to use bsnes in single-user mode, be sure that both files exist
|
||||
inside the same folder as the bsnes executable. If they do not, you can simply
|
||||
create new blank files and bsnes will use them in the future.
|
||||
|
||||
If you wish to use bsnes in multi-user mode, simply delete these two files from
|
||||
the bsnes executable directory if they exist.
|
||||
|
||||
If you wish to have multiple configuration profiles for the same user, you will
|
||||
need to make copies of the bsnes executable, and use each one in single-user
|
||||
mode.
|
||||
|
||||
------------------
|
||||
Known Limitations:
|
||||
------------------
|
||||
|
@ -60,10 +83,10 @@ Coprocessor used only by the following games:
|
|||
- Super Power League 4
|
||||
|
||||
ST-011
|
||||
SETA DSP used only by Quick-move Shogi Match with Nidan Rank-holder Morita
|
||||
SETA DSP used by Quick-move Shogi Match with Nidan Rank-holder Morita
|
||||
|
||||
ST-018
|
||||
SETA RISC CPU used only by Quick-move Shogi Match with Nidan Rank-holder Morita 2
|
||||
SETA RISC CPU used by Quick-move Shogi Match with Nidan Rank-holder Morita 2
|
||||
|
||||
Super Gameboy
|
||||
Cartridge passthrough used for playing Gameboy games
|
||||
|
|
|
@ -11,7 +11,7 @@ ifneq ($(findstring gcc,$(compiler)),) # GCC family
|
|||
cpp = $(subst cc,++,$(compiler)) $(flags)
|
||||
obj = o
|
||||
rule = -c $< -o $@
|
||||
link =
|
||||
link = -s
|
||||
mkbin = -o$1
|
||||
mkdef = -D$1
|
||||
mklib = -l$1
|
||||
|
@ -34,7 +34,7 @@ endif
|
|||
##########
|
||||
|
||||
ifeq ($(platform),x) # X11
|
||||
ruby = video.glx video.xv video.sdl audio.openal audio.oss audio.ao input.sdl input.x
|
||||
ruby = video.glx video.xv video.sdl audio.openal audio.oss audio.alsa audio.ao input.sdl input.x
|
||||
link += `pkg-config --libs gtk+-2.0`
|
||||
link += $(call mklib,Xtst)
|
||||
delete = rm -f $1
|
||||
|
@ -66,6 +66,7 @@ link += $(if $(findstring video.directdraw,$(ruby)),$(call mklib,ddraw))
|
|||
link += $(if $(findstring video.glx,$(ruby)),$(call mklib,GL))
|
||||
link += $(if $(findstring video.wgl,$(ruby)),$(call mklib,opengl32))
|
||||
link += $(if $(findstring video.xv,$(ruby)),$(call mklib,Xv))
|
||||
link += $(if $(findstring audio.alsa,$(ruby)),$(call mklib,asound))
|
||||
link += $(if $(findstring audio.ao,$(ruby)),$(call mklib,ao))
|
||||
link += $(if $(findstring audio.directsound,$(ruby)),$(call mklib,dsound))
|
||||
link += $(if $(findstring audio.openal,$(ruby)),$(if $(call streq,$(platform),x),$(call mklib,openal),$(call mklib,openal32)))
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
#define BSNES_VERSION "0.031"
|
||||
#define BSNES_VERSION "0.032"
|
||||
#define BSNES_TITLE "bsnes v" BSNES_VERSION
|
||||
|
||||
#define BUSCORE sBus
|
||||
|
|
|
@ -102,19 +102,19 @@ bool Cartridge::unload() {
|
|||
bus.unload_cart();
|
||||
|
||||
switch(info.type) {
|
||||
case CartridgeNormal: unload_cart_normal(); break;
|
||||
case CartridgeBSX: unload_cart_bsx(); break;
|
||||
case CartridgeBSC: unload_cart_bsc(); break;
|
||||
case CartridgeSufamiTurbo: unload_cart_st(); break;
|
||||
case CartridgeNormal: unload_cart_normal(); break;
|
||||
case CartridgeBSX: unload_cart_bsx(); break;
|
||||
case CartridgeBSC: unload_cart_bsc(); break;
|
||||
case CartridgeSufamiTurbo: unload_cart_st(); break;
|
||||
}
|
||||
|
||||
safe_free(cart.rom);
|
||||
safe_free(cart.ram);
|
||||
safe_free(bs.ram);
|
||||
safe_free(stA.rom);
|
||||
safe_free(stA.ram);
|
||||
safe_free(stB.rom);
|
||||
safe_free(stB.ram);
|
||||
if(cart.rom) { delete[] cart.rom; cart.rom = 0; }
|
||||
if(cart.ram) { delete[] cart.ram; cart.ram = 0; }
|
||||
if(bs.ram) { delete[] bs.ram; bs.ram = 0; }
|
||||
if(stA.rom) { delete[] stA.rom; stA.rom = 0; }
|
||||
if(stA.ram) { delete[] stA.ram; stA.ram = 0; }
|
||||
if(stB.rom) { delete[] stB.rom; stB.rom = 0; }
|
||||
if(stB.ram) { delete[] stB.ram; stB.ram = 0; }
|
||||
|
||||
char fn[PATH_MAX];
|
||||
strcpy(fn, cart.fn);
|
||||
|
|
|
@ -14,7 +14,7 @@ void Cartridge::load_cart_bsc(const char *base, const char *slot) {
|
|||
|
||||
if(load_file(get_patch_filename(cart.fn, "ups"), data, size, CompressionInspect) == true) {
|
||||
apply_patch(data, size, cart.rom, cart.rom_size);
|
||||
if(data) { free(data); data = 0; }
|
||||
delete[] data;
|
||||
}
|
||||
|
||||
if(*bs.fn) {
|
||||
|
@ -23,7 +23,7 @@ void Cartridge::load_cart_bsc(const char *base, const char *slot) {
|
|||
bs.ram = data, bs.ram_size = size;
|
||||
if(load_file(get_patch_filename(bs.fn, "ups"), data, size, CompressionInspect) == true) {
|
||||
apply_patch(data, size, bs.ram, bs.ram_size);
|
||||
if(data) { free(data); data = 0; }
|
||||
delete[] data;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -35,12 +35,12 @@ void Cartridge::load_cart_bsc(const char *base, const char *slot) {
|
|||
info.region = NTSC;
|
||||
|
||||
if(info.ram_size > 0) {
|
||||
cart.ram = (uint8*)malloc(cart.ram_size = info.ram_size);
|
||||
cart.ram = new uint8_t[cart.ram_size = info.ram_size];
|
||||
memset(cart.ram, 0xff, cart.ram_size);
|
||||
|
||||
if(load_file(get_save_filename(cart.fn, "srm"), data, size, CompressionNone) == true) {
|
||||
memcpy(cart.ram, data, min(size, cart.ram_size));
|
||||
safe_free(data);
|
||||
delete[] data;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -20,7 +20,7 @@ void Cartridge::load_cart_bsx(const char *base, const char *slot) {
|
|||
|
||||
if(load_file(get_patch_filename(cart.fn, "ups"), data, size, CompressionInspect) == true) {
|
||||
apply_patch(data, size, cart.rom, cart.rom_size);
|
||||
if(data) { free(data); data = 0; }
|
||||
delete[] data;
|
||||
}
|
||||
|
||||
memset(bsxcart.sram.handle (), 0x00, bsxcart.sram.size ());
|
||||
|
@ -28,12 +28,12 @@ void Cartridge::load_cart_bsx(const char *base, const char *slot) {
|
|||
|
||||
if(load_file(get_save_filename(cart.fn, "srm"), data, size, CompressionNone) == true) {
|
||||
memcpy(bsxcart.sram.handle (), data, min(bsxcart.sram.size (), size));
|
||||
safe_free(data);
|
||||
delete[] data;
|
||||
}
|
||||
|
||||
if(load_file(get_save_filename(cart.fn, "psr"), data, size, CompressionNone) == true) {
|
||||
memcpy(bsxcart.psram.handle(), data, min(bsxcart.psram.size(), size));
|
||||
safe_free(data);
|
||||
delete[] data;
|
||||
}
|
||||
|
||||
if(*bs.fn) {
|
||||
|
@ -42,7 +42,7 @@ void Cartridge::load_cart_bsx(const char *base, const char *slot) {
|
|||
bs.ram = data, bs.ram_size = size;
|
||||
if(load_file(get_patch_filename(bs.fn, "ups"), data, size, CompressionInspect) == true) {
|
||||
apply_patch(data, size, bs.ram, bs.ram_size);
|
||||
if(data) { free(data); data = 0; }
|
||||
delete[] data;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -158,8 +158,8 @@ bool Cartridge::apply_patch(const uint8_t *pdata, const unsigned psize, uint8_t
|
|||
}
|
||||
|
||||
if(apply == true) {
|
||||
free(data);
|
||||
data = (uint8_t*)malloc(size = outsize);
|
||||
delete[] data;
|
||||
data = new uint8_t[size = outsize];
|
||||
memcpy(data, outdata, outsize);
|
||||
} else {
|
||||
dprintf("* Warning: patch application failed!");
|
||||
|
@ -168,11 +168,12 @@ bool Cartridge::apply_patch(const uint8_t *pdata, const unsigned psize, uint8_t
|
|||
if(outdata) delete[] outdata;
|
||||
}
|
||||
|
||||
bool Cartridge::save_file(const char *fn, uint8 *data, uint size) {
|
||||
FileWriter ff(fn);
|
||||
if(!ff.ready())return false;
|
||||
ff.write(data, size);
|
||||
return true;
|
||||
bool Cartridge::save_file(const char *fn, uint8 *data, uint size) {
|
||||
FILE *fp = fopen(fn, "wb");
|
||||
if(!fp) return false;
|
||||
fwrite(data, 1, size, fp);
|
||||
fclose(fp);
|
||||
return true;
|
||||
}
|
||||
|
||||
#endif //ifdef CART_CPP
|
||||
|
|
|
@ -12,17 +12,17 @@ void Cartridge::load_cart_normal(const char *filename) {
|
|||
|
||||
//load ROM data, ignore 512-byte header if detected
|
||||
if((size & 0x7fff) != 512) {
|
||||
cart.rom = (uint8*)malloc(cart.rom_size = size);
|
||||
cart.rom = new uint8_t[cart.rom_size = size];
|
||||
memcpy(cart.rom, data, size);
|
||||
} else {
|
||||
cart.rom = (uint8*)malloc(cart.rom_size = size - 512);
|
||||
cart.rom = new uint8_t[cart.rom_size = size - 512];
|
||||
memcpy(cart.rom, data + 512, size - 512);
|
||||
}
|
||||
safe_free(data);
|
||||
delete[] data;
|
||||
|
||||
if(load_file(get_patch_filename(cart.fn, "ups"), data, size, CompressionInspect) == true) {
|
||||
apply_patch(data, size, cart.rom, cart.rom_size);
|
||||
if(data) { free(data); data = 0; }
|
||||
delete[] data;
|
||||
}
|
||||
|
||||
info.crc32 = crc32_calculate(cart.rom, cart.rom_size);
|
||||
|
@ -31,12 +31,12 @@ void Cartridge::load_cart_normal(const char *filename) {
|
|||
read_header();
|
||||
|
||||
if(info.ram_size > 0) {
|
||||
cart.ram = (uint8*)malloc(cart.ram_size = info.ram_size);
|
||||
cart.ram = new uint8_t[cart.ram_size = info.ram_size];
|
||||
memset(cart.ram, 0xff, cart.ram_size);
|
||||
|
||||
if(load_file(get_save_filename(cart.fn, "srm"), data, size, CompressionNone) == true) {
|
||||
memcpy(cart.ram, data, min(size, cart.ram_size));
|
||||
safe_free(data);
|
||||
delete[] data;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -15,51 +15,51 @@ void Cartridge::load_cart_st(const char *base, const char *slotA, const char *sl
|
|||
uint8_t *data = 0;
|
||||
unsigned size;
|
||||
if(load_file(cart.fn, data, size, CompressionAuto) == true) {
|
||||
cart.rom = (uint8*)malloc(cart.rom_size = 0x040000);
|
||||
cart.rom = new(zeromemory) uint8_t[cart.rom_size = 0x040000];
|
||||
memcpy(cart.rom, data, min(size, cart.rom_size));
|
||||
safe_free(data);
|
||||
delete[] data;
|
||||
if(load_file(get_patch_filename(cart.fn, "ups"), data, size, CompressionInspect) == true) {
|
||||
apply_patch(data, size, cart.rom, cart.rom_size);
|
||||
if(data) { free(data); data = 0; }
|
||||
delete[] data;
|
||||
}
|
||||
}
|
||||
|
||||
if(*stA.fn) {
|
||||
if(load_file(stA.fn, data, size, CompressionAuto) == true) {
|
||||
stA.rom = (uint8*)malloc(stA.rom_size = 0x100000);
|
||||
stA.rom = new(zeromemory) uint8_t[stA.rom_size = 0x100000];
|
||||
memcpy(stA.rom, data, min(size, stA.rom_size));
|
||||
safe_free(data);
|
||||
delete[] data;
|
||||
if(load_file(get_patch_filename(stA.fn, "ups"), data, size, CompressionInspect) == true) {
|
||||
apply_patch(data, size, stA.rom, stA.rom_size);
|
||||
if(data) { free(data); data = 0; }
|
||||
delete[] data;
|
||||
}
|
||||
|
||||
stA.ram = (uint8*)malloc(stA.ram_size = 0x020000);
|
||||
stA.ram = new uint8_t[stA.ram_size = 0x020000];
|
||||
memset(stA.ram, 0xff, stA.ram_size);
|
||||
|
||||
if(load_file(get_save_filename(stA.fn, "srm"), data, size, CompressionNone) == true) {
|
||||
memcpy(stA.ram, data, min(size, 0x020000U));
|
||||
safe_free(data);
|
||||
delete[] data;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(*stB.fn) {
|
||||
if(load_file(stB.fn, data, size, CompressionAuto) == true) {
|
||||
stB.rom = (uint8*)malloc(stB.rom_size = 0x100000);
|
||||
stB.rom = new(zeromemory) uint8_t[stB.rom_size = 0x100000];
|
||||
memcpy(stB.rom, data, min(size, stB.rom_size));
|
||||
safe_free(data);
|
||||
delete[] data;
|
||||
if(load_file(get_patch_filename(stB.fn, "ups"), data, size, CompressionInspect) == true) {
|
||||
apply_patch(data, size, stB.rom, stB.rom_size);
|
||||
if(data) { free(data); data = 0; }
|
||||
delete[] data;
|
||||
}
|
||||
|
||||
stB.ram = (uint8*)malloc(stB.ram_size = 0x020000);
|
||||
stB.ram = new uint8_t[stB.ram_size = 0x020000];
|
||||
memset(stB.ram, 0xff, stB.ram_size);
|
||||
|
||||
if(load_file(get_save_filename(stB.fn, "srm"), data, size, CompressionNone) == true) {
|
||||
memcpy(stB.ram, data, min(size, 0x020000U));
|
||||
safe_free(data);
|
||||
delete[] data;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -20,7 +20,7 @@ void BSXCart::reset() {
|
|||
}
|
||||
|
||||
void BSXCart::update_memory_map() {
|
||||
Memory &cart = (regs.r[0x01] & 0x80) == 0x00 ? (Memory&)bsxflash : (Memory&)psram;
|
||||
Memory &cart = (regs.r[0x01] & 0x80) == 0x00 ? (Memory&)bsxflash : (Memory&)psram;
|
||||
|
||||
if((regs.r[0x02] & 0x80) == 0x00) { //LoROM mapping
|
||||
bus.map(Bus::MapLinear, 0x00, 0x7d, 0x8000, 0xffff, cart);
|
||||
|
@ -59,7 +59,7 @@ Memory &cart = (regs.r[0x01] & 0x80) == 0x00 ? (Memory&)bsxflash : (Memory&)psra
|
|||
|
||||
uint8 BSXCart::mmio_read(uint addr) {
|
||||
if((addr & 0xf0ffff) == 0x005000) { //$[00-0f]:5000 MMIO
|
||||
uint8 n = (addr >> 16) & 15;
|
||||
uint8 n = (addr >> 16) & 15;
|
||||
return regs.r[n];
|
||||
}
|
||||
|
||||
|
@ -72,7 +72,7 @@ uint8 BSXCart::mmio_read(uint addr) {
|
|||
|
||||
void BSXCart::mmio_write(uint addr, uint8 data) {
|
||||
if((addr & 0xf0ffff) == 0x005000) { //$[00-0f]:5000 MMIO
|
||||
uint8 n = (addr >> 16) & 15;
|
||||
uint8 n = (addr >> 16) & 15;
|
||||
regs.r[n] = data;
|
||||
if(n == 0x0e && data & 0x80) update_memory_map();
|
||||
return;
|
||||
|
@ -84,16 +84,16 @@ void BSXCart::mmio_write(uint addr, uint8 data) {
|
|||
}
|
||||
|
||||
BSXCart::BSXCart() {
|
||||
sram_data = (uint8*)malloc( 32 * 1024);
|
||||
psram_data = (uint8*)malloc(512 * 1024);
|
||||
sram_data = new uint8_t[ 32 * 1024];
|
||||
psram_data = new uint8_t[512 * 1024];
|
||||
|
||||
sram.map (sram_data, 32 * 1024);
|
||||
psram.map(psram_data, 512 * 1024);
|
||||
}
|
||||
|
||||
BSXCart::~BSXCart() {
|
||||
safe_free(sram_data);
|
||||
safe_free(psram_data);
|
||||
delete[] sram_data;
|
||||
delete[] psram_data;
|
||||
}
|
||||
|
||||
#endif //ifdef BSX_CPP
|
||||
|
|
|
@ -44,8 +44,9 @@ string file_updatepath(const char *req_file, const char *req_path) {
|
|||
return path;
|
||||
}
|
||||
|
||||
string_setting Path::base("path.base",
|
||||
"Path that bsnes resides in", "");
|
||||
string_setting Path::base("path.base", "Path that bsnes resides in", "");
|
||||
string_setting Path::user("path.user", "Path to user folder", "");
|
||||
|
||||
string_setting Path::rom(config(), "path.rom",
|
||||
"Default path to look for ROM files in (\"\" = use default directory)", "");
|
||||
string_setting Path::patch(config(), "path.patch",
|
||||
|
|
|
@ -10,7 +10,7 @@ extern struct File {
|
|||
} file;
|
||||
|
||||
extern struct Path {
|
||||
static string_setting base, rom, patch, save, cheat;
|
||||
static string_setting base, user, rom, patch, save, cheat;
|
||||
static string_setting bsx, st;
|
||||
} path;
|
||||
|
||||
|
|
|
@ -1,19 +1,32 @@
|
|||
template<int mask>
|
||||
struct CPUFlag {
|
||||
uint8 &data;
|
||||
|
||||
inline operator bool() const { return data & mask; }
|
||||
inline CPUFlag& operator=(bool i) { data = (data & ~mask) | (-i & mask); return *this; }
|
||||
|
||||
CPUFlag(uint8 &data_) : data(data_) {}
|
||||
};
|
||||
|
||||
class CPURegFlags {
|
||||
public:
|
||||
union {
|
||||
uint8 data;
|
||||
struct {
|
||||
bool order_msb8(n:1, v:1, m:1, x:1, d:1, i:1, z:1, c:1);
|
||||
};
|
||||
};
|
||||
public:
|
||||
uint8 data;
|
||||
CPUFlag<0x80> n;
|
||||
CPUFlag<0x40> v;
|
||||
CPUFlag<0x20> m;
|
||||
CPUFlag<0x10> x;
|
||||
CPUFlag<0x08> d;
|
||||
CPUFlag<0x04> i;
|
||||
CPUFlag<0x02> z;
|
||||
CPUFlag<0x01> c;
|
||||
|
||||
inline operator unsigned() const { return data; }
|
||||
template<typename T> inline unsigned operator = (const T i) { data = i; return data; }
|
||||
template<typename T> inline unsigned operator |= (const T i) { data |= i; return data; }
|
||||
template<typename T> inline unsigned operator ^= (const T i) { data ^= i; return data; }
|
||||
template<typename T> inline unsigned operator &= (const T i) { data &= i; return data; }
|
||||
inline unsigned operator = (unsigned i) { data = i; return data; }
|
||||
inline unsigned operator |= (unsigned i) { data |= i; return data; }
|
||||
inline unsigned operator ^= (unsigned i) { data ^= i; return data; }
|
||||
inline unsigned operator &= (unsigned i) { data &= i; return data; }
|
||||
|
||||
CPURegFlags() : data(0) {}
|
||||
CPURegFlags() : data(0), n(data), v(data), m(data), x(data), d(data), i(data), z(data), c(data) {}
|
||||
};
|
||||
|
||||
class CPUReg16 {
|
||||
|
@ -24,17 +37,17 @@ public:
|
|||
};
|
||||
|
||||
inline operator unsigned() const { return w; }
|
||||
template<typename T> inline unsigned operator = (const T i) { w = i; return w; }
|
||||
template<typename T> inline unsigned operator |= (const T i) { w |= i; return w; }
|
||||
template<typename T> inline unsigned operator ^= (const T i) { w ^= i; return w; }
|
||||
template<typename T> inline unsigned operator &= (const T i) { w &= i; return w; }
|
||||
template<typename T> inline unsigned operator <<= (const T i) { w <<= i; return w; }
|
||||
template<typename T> inline unsigned operator >>= (const T i) { w >>= i; return w; }
|
||||
template<typename T> inline unsigned operator += (const T i) { w += i; return w; }
|
||||
template<typename T> inline unsigned operator -= (const T i) { w -= i; return w; }
|
||||
template<typename T> inline unsigned operator *= (const T i) { w *= i; return w; }
|
||||
template<typename T> inline unsigned operator /= (const T i) { w /= i; return w; }
|
||||
template<typename T> inline unsigned operator %= (const T i) { w %= i; return w; }
|
||||
inline unsigned operator = (unsigned i) { w = i; return w; }
|
||||
inline unsigned operator |= (unsigned i) { w |= i; return w; }
|
||||
inline unsigned operator ^= (unsigned i) { w ^= i; return w; }
|
||||
inline unsigned operator &= (unsigned i) { w &= i; return w; }
|
||||
inline unsigned operator <<= (unsigned i) { w <<= i; return w; }
|
||||
inline unsigned operator >>= (unsigned i) { w >>= i; return w; }
|
||||
inline unsigned operator += (unsigned i) { w += i; return w; }
|
||||
inline unsigned operator -= (unsigned i) { w -= i; return w; }
|
||||
inline unsigned operator *= (unsigned i) { w *= i; return w; }
|
||||
inline unsigned operator /= (unsigned i) { w /= i; return w; }
|
||||
inline unsigned operator %= (unsigned i) { w %= i; return w; }
|
||||
|
||||
CPUReg16() : w(0) {}
|
||||
};
|
||||
|
@ -48,17 +61,17 @@ public:
|
|||
};
|
||||
|
||||
inline operator unsigned() const { return d; }
|
||||
template<typename T> inline unsigned operator = (const T i) { d = uclip<24>(i); return d; }
|
||||
template<typename T> inline unsigned operator |= (const T i) { d = uclip<24>(d | i); return d; }
|
||||
template<typename T> inline unsigned operator ^= (const T i) { d = uclip<24>(d ^ i); return d; }
|
||||
template<typename T> inline unsigned operator &= (const T i) { d = uclip<24>(d & i); return d; }
|
||||
template<typename T> inline unsigned operator <<= (const T i) { d = uclip<24>(d << i); return d; }
|
||||
template<typename T> inline unsigned operator >>= (const T i) { d = uclip<24>(d >> i); return d; }
|
||||
template<typename T> inline unsigned operator += (const T i) { d = uclip<24>(d + i); return d; }
|
||||
template<typename T> inline unsigned operator -= (const T i) { d = uclip<24>(d - i); return d; }
|
||||
template<typename T> inline unsigned operator *= (const T i) { d = uclip<24>(d * i); return d; }
|
||||
template<typename T> inline unsigned operator /= (const T i) { d = uclip<24>(d / i); return d; }
|
||||
template<typename T> inline unsigned operator %= (const T i) { d = uclip<24>(d % i); return d; }
|
||||
inline unsigned operator = (unsigned i) { d = uclip<24>(i); return d; }
|
||||
inline unsigned operator |= (unsigned i) { d = uclip<24>(d | i); return d; }
|
||||
inline unsigned operator ^= (unsigned i) { d = uclip<24>(d ^ i); return d; }
|
||||
inline unsigned operator &= (unsigned i) { d = uclip<24>(d & i); return d; }
|
||||
inline unsigned operator <<= (unsigned i) { d = uclip<24>(d << i); return d; }
|
||||
inline unsigned operator >>= (unsigned i) { d = uclip<24>(d >> i); return d; }
|
||||
inline unsigned operator += (unsigned i) { d = uclip<24>(d + i); return d; }
|
||||
inline unsigned operator -= (unsigned i) { d = uclip<24>(d - i); return d; }
|
||||
inline unsigned operator *= (unsigned i) { d = uclip<24>(d * i); return d; }
|
||||
inline unsigned operator /= (unsigned i) { d = uclip<24>(d / i); return d; }
|
||||
inline unsigned operator %= (unsigned i) { d = uclip<24>(d % i); return d; }
|
||||
|
||||
CPUReg24() : d(0) {}
|
||||
};
|
||||
|
@ -70,6 +83,6 @@ public:
|
|||
CPURegFlags p;
|
||||
uint8 db;
|
||||
uint8 mdr;
|
||||
bool e;
|
||||
CPURegs() : db(0), mdr(0x00), e(false) {}
|
||||
bool e;
|
||||
CPURegs() : db(0), mdr(0), e(false) {}
|
||||
};
|
||||
|
|
|
@ -2,210 +2,204 @@
|
|||
|
||||
//op_read
|
||||
inline void sCPU::op_adc_b() {
|
||||
int32 r = regs.a.l + rd.l + regs.p.c;
|
||||
int r;
|
||||
if(regs.p.d) {
|
||||
uint8 n0 = (regs.a.l ) & 15;
|
||||
uint8 n1 = (regs.a.l >> 4) & 15;
|
||||
n0 += ((rd.l) & 15) + regs.p.c;
|
||||
uint8 n0 = (regs.a.l ) & 15;
|
||||
uint8 n1 = (regs.a.l >> 4) & 15;
|
||||
n0 += (rd.l & 15) + regs.p.c;
|
||||
if(n0 > 9) {
|
||||
n0 -= 10;
|
||||
n0 &= 15;
|
||||
n0 = (n0 - 10) & 15;
|
||||
n1++;
|
||||
}
|
||||
n1 += ((rd.l >> 4) & 15);
|
||||
if(n1 > 9) {
|
||||
n1 -= 10;
|
||||
n1 &= 15;
|
||||
n1 = (n1 - 10) & 15;
|
||||
regs.p.c = 1;
|
||||
} else {
|
||||
regs.p.c = 0;
|
||||
}
|
||||
r = (n1 << 4) | (n0);
|
||||
r = (n1 << 4) | n0;
|
||||
} else {
|
||||
r = regs.a.l + rd.l + regs.p.c;
|
||||
regs.p.c = (r > 0xff);
|
||||
regs.p.c = r > 0xff;
|
||||
}
|
||||
regs.p.n = !!(r & 0x80);
|
||||
regs.p.v = !!(~(regs.a.l ^ rd.l) & (regs.a.l ^ r) & 0x80);
|
||||
regs.p.z = ((uint8)r == 0);
|
||||
regs.p.n = r & 0x80;
|
||||
regs.p.v = ~(regs.a.l ^ rd.l) & (regs.a.l ^ r) & 0x80;
|
||||
regs.p.z = (uint8)r == 0;
|
||||
regs.a.l = r;
|
||||
}
|
||||
|
||||
inline void sCPU::op_adc_w() {
|
||||
int32 r;
|
||||
int r;
|
||||
if(regs.p.d) {
|
||||
uint8 n0 = (regs.a.w ) & 15;
|
||||
uint8 n1 = (regs.a.w >> 4) & 15;
|
||||
uint8 n2 = (regs.a.w >> 8) & 15;
|
||||
uint8 n3 = (regs.a.w >> 12) & 15;
|
||||
n0 += ((rd.w) & 15) + regs.p.c;
|
||||
uint8 n0 = (regs.a.w ) & 15;
|
||||
uint8 n1 = (regs.a.w >> 4) & 15;
|
||||
uint8 n2 = (regs.a.w >> 8) & 15;
|
||||
uint8 n3 = (regs.a.w >> 12) & 15;
|
||||
n0 += (rd.w & 15) + regs.p.c;
|
||||
if(n0 > 9) {
|
||||
n0 -= 10;
|
||||
n0 &= 15;
|
||||
n0 = (n0 - 10) & 15;
|
||||
n1++;
|
||||
}
|
||||
n1 += ((rd.w >> 4) & 15);
|
||||
if(n1 > 9) {
|
||||
n1 -= 10;
|
||||
n1 &= 15;
|
||||
n1 = (n1 - 10) & 15;
|
||||
n2++;
|
||||
}
|
||||
n2 += ((rd.w >> 8) & 15);
|
||||
if(n2 > 9) {
|
||||
n2 -= 10;
|
||||
n2 &= 15;
|
||||
n2 = (n2 - 10) & 15;
|
||||
n3++;
|
||||
}
|
||||
n3 += ((rd.w >> 12) & 15);
|
||||
if(n3 > 9) {
|
||||
n3 -= 10;
|
||||
n3 &= 15;
|
||||
n3 = (n3 - 10) & 15;
|
||||
regs.p.c = 1;
|
||||
} else {
|
||||
regs.p.c = 0;
|
||||
}
|
||||
r = (n3 << 12) | (n2 << 8) | (n1 << 4) | (n0);
|
||||
r = (n3 << 12) | (n2 << 8) | (n1 << 4) | n0;
|
||||
} else {
|
||||
r = regs.a.w + rd.w + regs.p.c;
|
||||
regs.p.c = (r > 0xffff);
|
||||
regs.p.c = r > 0xffff;
|
||||
}
|
||||
regs.p.n = !!(r & 0x8000);
|
||||
regs.p.v = !!(~(regs.a.w ^ rd.w) & (regs.a.w ^ r) & 0x8000);
|
||||
regs.p.z = ((uint16)r == 0);
|
||||
regs.p.n = r & 0x8000;
|
||||
regs.p.v = ~(regs.a.w ^ rd.w) & (regs.a.w ^ r) & 0x8000;
|
||||
regs.p.z = (uint16)r == 0;
|
||||
regs.a.w = r;
|
||||
}
|
||||
|
||||
inline void sCPU::op_and_b() {
|
||||
regs.a.l &= rd.l;
|
||||
regs.p.n = !!(regs.a.l & 0x80);
|
||||
regs.p.z = (regs.a.l == 0);
|
||||
regs.p.n = regs.a.l & 0x80;
|
||||
regs.p.z = regs.a.l == 0;
|
||||
}
|
||||
|
||||
inline void sCPU::op_and_w() {
|
||||
regs.a.w &= rd.w;
|
||||
regs.p.n = !!(regs.a.w & 0x8000);
|
||||
regs.p.z = (regs.a.w == 0);
|
||||
regs.p.n = regs.a.w & 0x8000;
|
||||
regs.p.z = regs.a.w == 0;
|
||||
}
|
||||
|
||||
inline void sCPU::op_bit_b() {
|
||||
regs.p.n = !!(rd.l & 0x80);
|
||||
regs.p.v = !!(rd.l & 0x40);
|
||||
regs.p.z = ((rd.l & regs.a.l) == 0);
|
||||
regs.p.n = rd.l & 0x80;
|
||||
regs.p.v = rd.l & 0x40;
|
||||
regs.p.z = (rd.l & regs.a.l) == 0;
|
||||
}
|
||||
|
||||
inline void sCPU::op_bit_w() {
|
||||
regs.p.n = !!(rd.w & 0x8000);
|
||||
regs.p.v = !!(rd.w & 0x4000);
|
||||
regs.p.z = ((rd.w & regs.a.w) == 0);
|
||||
regs.p.n = rd.w & 0x8000;
|
||||
regs.p.v = rd.w & 0x4000;
|
||||
regs.p.z = (rd.w & regs.a.w) == 0;
|
||||
}
|
||||
|
||||
inline void sCPU::op_cmp_b() {
|
||||
int32 r = regs.a.l - rd.l;
|
||||
regs.p.n = !!(r & 0x80);
|
||||
regs.p.z = ((uint8)r == 0);
|
||||
regs.p.c = (r >= 0);
|
||||
int r = regs.a.l - rd.l;
|
||||
regs.p.n = r & 0x80;
|
||||
regs.p.z = (uint8)r == 0;
|
||||
regs.p.c = r >= 0;
|
||||
}
|
||||
|
||||
inline void sCPU::op_cmp_w() {
|
||||
int32 r = regs.a.w - rd.w;
|
||||
regs.p.n = !!(r & 0x8000);
|
||||
regs.p.z = ((uint16)r == 0);
|
||||
regs.p.c = (r >= 0);
|
||||
int r = regs.a.w - rd.w;
|
||||
regs.p.n = r & 0x8000;
|
||||
regs.p.z = (uint16)r == 0;
|
||||
regs.p.c = r >= 0;
|
||||
}
|
||||
|
||||
inline void sCPU::op_cpx_b() {
|
||||
int32 r = regs.x.l - rd.l;
|
||||
regs.p.n = !!(r & 0x80);
|
||||
regs.p.z = ((uint8)r == 0);
|
||||
regs.p.c = (r >= 0);
|
||||
int r = regs.x.l - rd.l;
|
||||
regs.p.n = r & 0x80;
|
||||
regs.p.z = (uint8)r == 0;
|
||||
regs.p.c = r >= 0;
|
||||
}
|
||||
|
||||
inline void sCPU::op_cpx_w() {
|
||||
int32 r = regs.x.w - rd.w;
|
||||
regs.p.n = !!(r & 0x8000);
|
||||
regs.p.z = ((uint16)r == 0);
|
||||
regs.p.c = (r >= 0);
|
||||
int r = regs.x.w - rd.w;
|
||||
regs.p.n = r & 0x8000;
|
||||
regs.p.z = (uint16)r == 0;
|
||||
regs.p.c = r >= 0;
|
||||
}
|
||||
|
||||
inline void sCPU::op_cpy_b() {
|
||||
int32 r = regs.y.l - rd.l;
|
||||
regs.p.n = !!(r & 0x80);
|
||||
regs.p.z = ((uint8)r == 0);
|
||||
regs.p.c = (r >= 0);
|
||||
int r = regs.y.l - rd.l;
|
||||
regs.p.n = r & 0x80;
|
||||
regs.p.z = (uint8)r == 0;
|
||||
regs.p.c = r >= 0;
|
||||
}
|
||||
|
||||
inline void sCPU::op_cpy_w() {
|
||||
int32 r = regs.y.w - rd.w;
|
||||
regs.p.n = !!(r & 0x8000);
|
||||
regs.p.z = ((uint16)r == 0);
|
||||
regs.p.c = (r >= 0);
|
||||
int r = regs.y.w - rd.w;
|
||||
regs.p.n = r & 0x8000;
|
||||
regs.p.z = (uint16)r == 0;
|
||||
regs.p.c = r >= 0;
|
||||
}
|
||||
|
||||
inline void sCPU::op_eor_b() {
|
||||
regs.a.l ^= rd.l;
|
||||
regs.p.n = !!(regs.a.l & 0x80);
|
||||
regs.p.z = (regs.a.l == 0);
|
||||
regs.p.n = regs.a.l & 0x80;
|
||||
regs.p.z = regs.a.l == 0;
|
||||
}
|
||||
|
||||
inline void sCPU::op_eor_w() {
|
||||
regs.a.w ^= rd.w;
|
||||
regs.p.n = !!(regs.a.w & 0x8000);
|
||||
regs.p.z = (regs.a.w == 0);
|
||||
regs.p.n = regs.a.w & 0x8000;
|
||||
regs.p.z = regs.a.w == 0;
|
||||
}
|
||||
|
||||
inline void sCPU::op_lda_b() {
|
||||
regs.a.l = rd.l;
|
||||
regs.p.n = !!(regs.a.l & 0x80);
|
||||
regs.p.z = (regs.a.l == 0);
|
||||
regs.p.n = regs.a.l & 0x80;
|
||||
regs.p.z = regs.a.l == 0;
|
||||
}
|
||||
|
||||
inline void sCPU::op_lda_w() {
|
||||
regs.a.w = rd.w;
|
||||
regs.p.n = !!(regs.a.w & 0x8000);
|
||||
regs.p.z = (regs.a.w == 0);
|
||||
regs.p.n = regs.a.w & 0x8000;
|
||||
regs.p.z = regs.a.w == 0;
|
||||
}
|
||||
|
||||
inline void sCPU::op_ldx_b() {
|
||||
regs.x.l = rd.l;
|
||||
regs.p.n = !!(regs.x.l & 0x80);
|
||||
regs.p.z = (regs.x.l == 0);
|
||||
regs.p.n = regs.x.l & 0x80;
|
||||
regs.p.z = regs.x.l == 0;
|
||||
}
|
||||
|
||||
inline void sCPU::op_ldx_w() {
|
||||
regs.x.w = rd.w;
|
||||
regs.p.n = !!(regs.x.w & 0x8000);
|
||||
regs.p.z = (regs.x.w == 0);
|
||||
regs.p.n = regs.x.w & 0x8000;
|
||||
regs.p.z = regs.x.w == 0;
|
||||
}
|
||||
|
||||
inline void sCPU::op_ldy_b() {
|
||||
regs.y.l = rd.l;
|
||||
regs.p.n = !!(regs.y.l & 0x80);
|
||||
regs.p.z = (regs.y.l == 0);
|
||||
regs.p.n = regs.y.l & 0x80;
|
||||
regs.p.z = regs.y.l == 0;
|
||||
}
|
||||
|
||||
inline void sCPU::op_ldy_w() {
|
||||
regs.y.w = rd.w;
|
||||
regs.p.n = !!(regs.y.w & 0x8000);
|
||||
regs.p.z = (regs.y.w == 0);
|
||||
regs.p.n = regs.y.w & 0x8000;
|
||||
regs.p.z = regs.y.w == 0;
|
||||
}
|
||||
|
||||
inline void sCPU::op_ora_b() {
|
||||
regs.a.l |= rd.l;
|
||||
regs.p.n = !!(regs.a.l & 0x80);
|
||||
regs.p.z = (regs.a.l == 0);
|
||||
regs.p.n = regs.a.l & 0x80;
|
||||
regs.p.z = regs.a.l == 0;
|
||||
}
|
||||
|
||||
inline void sCPU::op_ora_w() {
|
||||
regs.a.w |= rd.w;
|
||||
regs.p.n = !!(regs.a.w & 0x8000);
|
||||
regs.p.z = (regs.a.w == 0);
|
||||
regs.p.n = regs.a.w & 0x8000;
|
||||
regs.p.z = regs.a.w == 0;
|
||||
}
|
||||
|
||||
inline void sCPU::op_sbc_b() {
|
||||
int32 r;
|
||||
int r;
|
||||
if(regs.p.d) {
|
||||
uint8 n0 = (regs.a.l ) & 15;
|
||||
uint8 n1 = (regs.a.l >> 4) & 15;
|
||||
uint8 n0 = (regs.a.l ) & 15;
|
||||
uint8 n1 = (regs.a.l >> 4) & 15;
|
||||
n0 -= ((rd.l ) & 15) + !regs.p.c;
|
||||
n1 -= ((rd.l >> 4) & 15);
|
||||
if(n0 > 9) {
|
||||
|
@ -221,21 +215,21 @@ int32 r;
|
|||
r = (n1 << 4) | (n0);
|
||||
} else {
|
||||
r = regs.a.l - rd.l - !regs.p.c;
|
||||
regs.p.c = (r >= 0);
|
||||
regs.p.c = r >= 0;
|
||||
}
|
||||
regs.p.n = !!(r & 0x80);
|
||||
regs.p.v = !!((regs.a.l ^ rd.l) & (regs.a.l ^ r) & 0x80);
|
||||
regs.p.z = ((uint8)r == 0);
|
||||
regs.p.n = r & 0x80;
|
||||
regs.p.v = (regs.a.l ^ rd.l) & (regs.a.l ^ r) & 0x80;
|
||||
regs.p.z = (uint8)r == 0;
|
||||
regs.a.l = r;
|
||||
}
|
||||
|
||||
inline void sCPU::op_sbc_w() {
|
||||
int32 r;
|
||||
int r;
|
||||
if(regs.p.d) {
|
||||
uint8 n0 = (regs.a.w ) & 15;
|
||||
uint8 n1 = (regs.a.w >> 4) & 15;
|
||||
uint8 n2 = (regs.a.w >> 8) & 15;
|
||||
uint8 n3 = (regs.a.w >> 12) & 15;
|
||||
uint8 n0 = (regs.a.w ) & 15;
|
||||
uint8 n1 = (regs.a.w >> 4) & 15;
|
||||
uint8 n2 = (regs.a.w >> 8) & 15;
|
||||
uint8 n3 = (regs.a.w >> 12) & 15;
|
||||
n0 -= ((rd.w ) & 15) + !regs.p.c;
|
||||
n1 -= ((rd.w >> 4) & 15);
|
||||
n2 -= ((rd.w >> 8) & 15);
|
||||
|
@ -261,116 +255,116 @@ int32 r;
|
|||
r = (n3 << 12) | (n2 << 8) | (n1 << 4) | (n0);
|
||||
} else {
|
||||
r = regs.a.w - rd.w - !regs.p.c;
|
||||
regs.p.c = (r >= 0);
|
||||
regs.p.c = r >= 0;
|
||||
}
|
||||
regs.p.n = !!(r & 0x8000);
|
||||
regs.p.v = !!((regs.a.w ^ rd.w) & (regs.a.w ^ r) & 0x8000);
|
||||
regs.p.z = ((uint16)r == 0);
|
||||
regs.p.n = r & 0x8000;
|
||||
regs.p.v = (regs.a.w ^ rd.w) & (regs.a.w ^ r) & 0x8000;
|
||||
regs.p.z = (uint16)r == 0;
|
||||
regs.a.w = r;
|
||||
}
|
||||
|
||||
//op_rmw
|
||||
inline void sCPU::op_inc_b() {
|
||||
rd.l++;
|
||||
regs.p.n = !!(rd.l & 0x80);
|
||||
regs.p.z = (rd.l == 0);
|
||||
regs.p.n = rd.l & 0x80;
|
||||
regs.p.z = rd.l == 0;
|
||||
}
|
||||
|
||||
inline void sCPU::op_inc_w() {
|
||||
rd.w++;
|
||||
regs.p.n = !!(rd.w & 0x8000);
|
||||
regs.p.z = (rd.w == 0);
|
||||
regs.p.n = rd.w & 0x8000;
|
||||
regs.p.z = rd.w == 0;
|
||||
}
|
||||
|
||||
inline void sCPU::op_dec_b() {
|
||||
rd.l--;
|
||||
regs.p.n = !!(rd.l & 0x80);
|
||||
regs.p.z = (rd.l == 0);
|
||||
regs.p.n = rd.l & 0x80;
|
||||
regs.p.z = rd.l == 0;
|
||||
}
|
||||
|
||||
inline void sCPU::op_dec_w() {
|
||||
rd.w--;
|
||||
regs.p.n = !!(rd.w & 0x8000);
|
||||
regs.p.z = (rd.w == 0);
|
||||
regs.p.n = rd.w & 0x8000;
|
||||
regs.p.z = rd.w == 0;
|
||||
}
|
||||
|
||||
inline void sCPU::op_asl_b() {
|
||||
regs.p.c = !!(rd.l & 0x80);
|
||||
regs.p.c = rd.l & 0x80;
|
||||
rd.l <<= 1;
|
||||
regs.p.n = !!(rd.l & 0x80);
|
||||
regs.p.z = (rd.l == 0);
|
||||
regs.p.n = rd.l & 0x80;
|
||||
regs.p.z = rd.l == 0;
|
||||
}
|
||||
|
||||
inline void sCPU::op_asl_w() {
|
||||
regs.p.c = !!(rd.w & 0x8000);
|
||||
regs.p.c = rd.w & 0x8000;
|
||||
rd.w <<= 1;
|
||||
regs.p.n = !!(rd.w & 0x8000);
|
||||
regs.p.z = (rd.w == 0);
|
||||
regs.p.n = rd.w & 0x8000;
|
||||
regs.p.z = rd.w == 0;
|
||||
}
|
||||
|
||||
inline void sCPU::op_lsr_b() {
|
||||
regs.p.c = rd.l & 1;
|
||||
rd.l >>= 1;
|
||||
regs.p.n = !!(rd.l & 0x80);
|
||||
regs.p.z = (rd.l == 0);
|
||||
regs.p.n = rd.l & 0x80;
|
||||
regs.p.z = rd.l == 0;
|
||||
}
|
||||
|
||||
inline void sCPU::op_lsr_w() {
|
||||
regs.p.c = rd.w & 1;
|
||||
rd.w >>= 1;
|
||||
regs.p.n = !!(rd.w & 0x8000);
|
||||
regs.p.z = (rd.w == 0);
|
||||
regs.p.n = rd.w & 0x8000;
|
||||
regs.p.z = rd.w == 0;
|
||||
}
|
||||
|
||||
inline void sCPU::op_rol_b() {
|
||||
uint16 carry = (uint16)regs.p.c;
|
||||
regs.p.c = !!(rd.l & 0x80);
|
||||
unsigned carry = (unsigned)regs.p.c;
|
||||
regs.p.c = rd.l & 0x80;
|
||||
rd.l = (rd.l << 1) | carry;
|
||||
regs.p.n = !!(rd.l & 0x80);
|
||||
regs.p.z = (rd.l == 0);
|
||||
regs.p.n = rd.l & 0x80;
|
||||
regs.p.z = rd.l == 0;
|
||||
}
|
||||
|
||||
inline void sCPU::op_rol_w() {
|
||||
uint16 carry = (uint16)regs.p.c;
|
||||
regs.p.c = !!(rd.w & 0x8000);
|
||||
unsigned carry = (unsigned)regs.p.c;
|
||||
regs.p.c = rd.w & 0x8000;
|
||||
rd.w = (rd.w << 1) | carry;
|
||||
regs.p.n = !!(rd.w & 0x8000);
|
||||
regs.p.z = (rd.w == 0);
|
||||
regs.p.n = rd.w & 0x8000;
|
||||
regs.p.z = rd.w == 0;
|
||||
}
|
||||
|
||||
inline void sCPU::op_ror_b() {
|
||||
uint16 carry = (uint16)regs.p.c << 7;
|
||||
unsigned carry = (unsigned)regs.p.c << 7;
|
||||
regs.p.c = rd.l & 1;
|
||||
rd.l = carry | (rd.l >> 1);
|
||||
regs.p.n = !!(rd.l & 0x80);
|
||||
regs.p.z = (rd.l == 0);
|
||||
regs.p.n = rd.l & 0x80;
|
||||
regs.p.z = rd.l == 0;
|
||||
}
|
||||
|
||||
inline void sCPU::op_ror_w() {
|
||||
uint16 carry = (uint16)regs.p.c << 15;
|
||||
unsigned carry = (unsigned)regs.p.c << 15;
|
||||
regs.p.c = rd.w & 1;
|
||||
rd.w = carry | (rd.w >> 1);
|
||||
regs.p.n = !!(rd.w & 0x8000);
|
||||
regs.p.z = (rd.w == 0);
|
||||
regs.p.n = rd.w & 0x8000;
|
||||
regs.p.z = rd.w == 0;
|
||||
}
|
||||
|
||||
inline void sCPU::op_trb_b() {
|
||||
regs.p.z = ((rd.l & regs.a.l) == 0);
|
||||
regs.p.z = (rd.l & regs.a.l) == 0;
|
||||
rd.l &= ~regs.a.l;
|
||||
}
|
||||
|
||||
inline void sCPU::op_trb_w() {
|
||||
regs.p.z = ((rd.w & regs.a.w) == 0);
|
||||
regs.p.z = (rd.w & regs.a.w) == 0;
|
||||
rd.w &= ~regs.a.w;
|
||||
}
|
||||
|
||||
inline void sCPU::op_tsb_b() {
|
||||
regs.p.z = ((rd.l & regs.a.l) == 0);
|
||||
regs.p.z = (rd.l & regs.a.l) == 0;
|
||||
rd.l |= regs.a.l;
|
||||
}
|
||||
|
||||
inline void sCPU::op_tsb_w() {
|
||||
regs.p.z = ((rd.w & regs.a.w) == 0);
|
||||
regs.p.z = (rd.w & regs.a.w) == 0;
|
||||
rd.w |= regs.a.w;
|
||||
}
|
||||
|
||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 26 KiB After Width: | Height: | Size: 26 KiB |
Binary file not shown.
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 1.3 KiB |
|
@ -2,39 +2,40 @@ static char enc_icon48[] = {
|
|||
"_gAB8AHwAfAB8AHwAfAB8P8B8AHwAfAB8AHwAfAB8AHw_wHwAfAB8AHwAfAB8AHw"
|
||||
"AfD_AfAB8AHwAfAB8AHwAfAB8P8B8AHwAfAB8AHwAfAB8AHw_wHwAfAB8AHwAfAB"
|
||||
"8AHwAfD_AfAB8AHwAfAB8AHwAfAB8P8B8AHwAfAB8AHwAfAB8AHw_wHwAfAB8AHw"
|
||||
"AfAB8AHwAfD_AfAB8AHwAfAB8AHwAfABgFD_oRYPBAA1BABWVQQAWwQAQQQAGgQA"
|
||||
"Av8u8AHwAfAB8AHwAfAB8AHwVbSAAQQALQQAsAQA9FUEAP8EwPsEAM4EAFP9BAAE"
|
||||
"QvAB8AHwAfAB8AHwqwHwvOAEBACFBAD5uPDVBOD-BAC9BAAUSvAB8L8B8AHwAfAB"
|
||||
"8AHwvGADBACuoqjwBPAEwNsEABZS8H8B8AHwAfAB8AHwAfDAIHuvnPAE8ATwBCDH"
|
||||
"BAAFVvC_AfAB8AHwAfAB8LzAIAQA3vaY8ATwBPAEYGZa8AHw3wHwAfAB8AHwwMCX"
|
||||
"kPAE8OsE8ASg3wQABl7wAfAB8K8B8AHwAfC8QAYEAOeQ8PcE8ATw0OMvYvAB8AHw"
|
||||
"AfDXAfAB8MBAHAQA_JDwBPALBPAE4GRi8AAAPz9U_wEEAA0EAB0EAB59BAAPBABE"
|
||||
"9gHwAfDA8BVVBABxBAB3BAChUET9p5zwBPAE8BaGuMALBACqbAQAzgQA9AQA-wQA"
|
||||
"qvwEAPYEANYEAHoEAL4SlvAB8AHwAfAEhjIEAF68FEKo8ATwBFCBcIFHtQQA5AQA"
|
||||
"_wTwBKDuBAB-XDQQjvAB8AHwAfAQhmhHzPYE8ARgpQ5YwEBor2xBsPAE8AQQ_QQA"
|
||||
"hFTyfwHwAfAB8MjA-Bgg8wTQowAQ-_-rACMuNrz_SrzwBPAE8MQgZ4LwbwHwAfAB"
|
||||
"8BDJkbTwBMCnAAfLfV-0ETU6fP_mnPAE8ATwBCAkExxfhvAB8AHwAfDEgBEEAO0D"
|
||||
"uPAEQKQO_f-tAIBCLDX_cTw-mPA3BPAE8ASAlYLwAUDNAKoBBAAFBAAUBAAiBAB-"
|
||||
"JQhAEBAYEETz5PYE8KgABZxKRfIENju8_9eQ8ATwBPAEoOq0wKoDBAAsBACGBADM"
|
||||
"BADq7AQA_AQA_gSAEBAYEOrKBACDBAAqBABMo6gAFkC88AQgrvgCBy83wP8VPj7_"
|
||||
"-JDwBPCvBPAIs7yAuBDEoED_BPBXBPAEQDAQwAQAKcCAHRf8S7hQMBl_uFk4O_--"
|
||||
"KYzwBPAE8ATwvEBhBABe95zwBPAE8ARg9gQAW1HAIJ8XFKwA8uhIkFUEAB-sxhkE"
|
||||
"AH0EAJL1BADDBADznPAE8ATwwADozQBIBAD5kPAE8ATwAQTg-ADQACn_nrwYAshD"
|
||||
"pPUB8NAQEQQA3nGgRqjwBPDAkOKI8ATw9wTwBPAEIM8UAwHwAfAB8HvIEPQYzKjw"
|
||||
"BPAEQDQS0t-I8ATwBPAE8ARAeprwAfB3AfDEYLAZyqzwBPAEAMX1cAAvBADxiPAE"
|
||||
"8ATwBOB68AQAGZbwAfAB8MSgHK0EAPGw8ASg_gQAScBDvj4URZTwBPAE8AQw6gQA"
|
||||
"RjwN9mwJ__8IBAAT_QQAGgRADBAUEET2xHDgE6u48ARwuwQAA0CFGQQAup0EAPOc"
|
||||
"8ATwBIDyBACgmADLABe0gAkEAKpFBACaBADSBADsBABa-QQA-wRADBDtBADTVQQA"
|
||||
"nQQASAQACsDAGK0EAPW48AQg3QQAFfbwVcggEQQAUwQAoRxD6b0EAPRcJNwwEBAY"
|
||||
"EJ8EAKpRBAAQuIAGBABuBAC66AQA_wTwBPAEgOoEAEpzBAAHSxBBOFgryF-88BQg"
|
||||
"LHEB8NDQBgQAC10EAA0IQLj-vDAQBADFr5jwBPAE8ASgywQAFMRA6pm4gOcEAHAE"
|
||||
"AOAgAfCvAfAB8AHwvEACBAC1jPAvBPAE8ATwBAC_VBBDMtT_TrAAeQQAPAQAYKLf"
|
||||
"AfAB8AHwAfDAQBnYQozw1wTwBPAE8P0EAB1p8AHwrwHwAfAB8MDgGAQA-ojw7wTw"
|
||||
"BPAE8AQA_AQA3PsB8N8B8AHwAfDA8CQVsYjwBPD3BPAE8AQAulz1AfAB8AHw1wHw"
|
||||
"AfDEQA0EAL2M8ATw9wTwBKAEFBFh8AHwAfAB8FcB8AHwxIAFBABoBADjXQQA_pzw"
|
||||
"BPAEgOUEAG3_hCUB8AHwAfAB8AHwAfAB8KvIEFwXPQQAkgQAz8BGXveYQwQQDBAU"
|
||||
"ENAEAJT9BABB9CYB8AHwAfAB8AHwrwHwAfAB8NBwBAQADtgl_QQwDxRA5PIB8AHw"
|
||||
"AfAB8P8B8AHwAfAB8AHwAfAB8AHw_wHwAfAB8AHwAfAB8AHwAfD_AfAB8AHwAfAB"
|
||||
"8AHwAfAB8P8B8AHwAfAB8AHwAfAB8AHw_wHwAfAB8AHwAfAB8AHwAfD_AfAB8AHw"
|
||||
"AfAB8AHwAfAB8P8B8AHwAfAB8AHwAfAB8AHwfwHwAfAB8AHwAfAB8AGA"
|
||||
"AfAB8AHwAfD_AfAB8AHwAfAB8AHwAfABAAD_qgAD_p8VOwD_oRaI_qEWthD-oBbL"
|
||||
"CADE_qEAFaP_oBZm_p38GBU28AHwAfAB8AHwAfBfAfAB8AFQuBCoAMe0AP4twAD_"
|
||||
"BPAEIPAkAIX_-JkZCkLwAfAB8AHwAfBHAfAB8HSB_wABtABvPQQA-7DwBPAEECwA"
|
||||
"0P74oBIbTvAB8AHwAfAB8EcB8AHweEGgFWwkAv0HqPAE8MSwFdX-oRr-E1LwAfAB"
|
||||
"8AHwAfAB8Lzg6KEUMRAC96DwBPAE8P3EIKXAEVrwAfAB8AHwAfDzAfDAsBa3mPAE"
|
||||
"8ATwwED_uAE4E1rwAfAB8AHwAfAB8PG8YKIVJDjyBPAE8ATA-KAWoF7wAfAB8AHw"
|
||||
"AfB7AfD4gmmQ8ATwBPDM4-Z_XvAB8AHwAfAB8AHwwICPH_wSePQE8ATwBMClDxEB"
|
||||
"YNBERP8PPz_-oEw-Pv56CACMCACCgggAXT8__yD2BA808wHwAfDAkKMSDv6AmxwS"
|
||||
"_qQYH8QC6kjIAJTUAOug8ATwhOFDRABYUDw8_hWsAI9QPj7_8KwA_wTw_oL6BAC1"
|
||||
"PT3-MpbwjwHwAfAB8AxmpRkUFAOOkxjzBPAEoJ8PEEAQdZQAOrwA47TwBPAoAPh9"
|
||||
"yAB0hvAB8AHwAfBcsha6XFwC-KzwBPDsAOQ0EHWQAD0EAPSs8ATwBMCAn4LwAfAB"
|
||||
"8AHwXLUVakz4gwTwKACbQkL-F0wBTuac8ATwiPH-_AQATh-C8AHwAfAB8ExifwAC"
|
||||
"DcAAtbTwfKT8_qETejSAAJOc8ATwBPAUY9p9CAAIhvAB8AHwAfCEYZ4MGDWE8YCn"
|
||||
"nEs8_3oRgAD1lPAE8ATwBKBVh4LwAQAUCwDNACQEAKBNAMwAaggAewgAoH8AywBz"
|
||||
"CABbCABgNwDIAA458Nxp2IO88Hwhzf-ZEQ-0A15XjPAE8ATwhOGlfaDOVAA1oACY"
|
||||
"sADhCAD9jQgA_wTwBEDMAPQEAHq7NABjCAAcq2QRvPAW9sUMXHwAiIzwBPAE8MDg"
|
||||
"otZxIMsAGYQArQQATv6s8ATwzPAA4wQAUVcKAGQmYAR9MILpBAB3sP-qKgbgUPwC"
|
||||
"mwQAevuAAP6U8ATwBPDAYO3QANEAHIQA3JjwBPCrBPAEoPwEAGyAQVRwAeCV_qIX"
|
||||
"WPQWZNJ8AKoQgAQbSAI2hABtzAC6xAgA_aDwBPCIxOc4Ab6mjPAE8ATwBPAEAPYE"
|
||||
"AK9YZwHwAfA2QwLAAEgEAK7dqPAE8MCAx8AA5Ijw_wTwBPAE8ExCFPQB8AHwAQDQ"
|
||||
"Q0P-E5QAw6zwBPD1wECLcAC2iPAE8ATwBPD1BAD70AMqmvAB8AHwATDQODj-EpgA"
|
||||
"1LDwxPbFBAAxcCDNAOyM8ATwewTwBOCGkvAB8AHwIOM8t-AzuPC8g66UasQwyJDw"
|
||||
"VwTwBPAEIPHEBG4KAAJBDcYKAP7-LAQAT1UEAGUEAHAEAGoEAFd1BAA5BAASJAAY"
|
||||
"-8Qg_gaytPB8Yeg7O_8eUTGgvwAEyABUUAK3XZAA9aTw6OJsFdgIAIOQAM8AG_11"
|
||||
"_guUAKpgCAC1BADvDAD_BPAxBED-_vgIAEoA_nzDBAD4o0BA_lO88Lwgjuy4FPLw"
|
||||
"AYDPABCYAKpCoABtBACKBACbEACKngQAk4wnzQBXoCd3qBe5plgh4azwBPDM8P76"
|
||||
"9QQAiwwA1CjgGeQSvMD6yAQAKbHwAfAB8AHwvMC9RBH-nPAE8ATwBKDAxCFVVDXu"
|
||||
"sADzCAC9dEgEX3nwAfAB8AHwvMAxBAD8X4zwBPAE8ATwTAB-3Ewh_bQADHHwAfAB"
|
||||
"8AHwAfDAYL50iPAE8ATwBPDAQMRl8L8B8AHwAfAB8AHwcABMiPDvBPAE8ATwwECc"
|
||||
"ZfAB8AHwrwHwAfAB8HQAAnQAsIzw9wTwBPC84OQIABy1AfAB8O8B8AHwAfDs1ZUI"
|
||||
"8wTwBPD1vGDHBAAkXfAB8AHwAfCnAfAB8Mjw_zCEAJ8EAK7rpPAE8CgA9wQAvAQA"
|
||||
"_lQQAJC1AfAB8AHwAfAB8FcB8MjwkBE6BABsBACPVQQApAQArwQAqQQAl_UgAHgI"
|
||||
"AEsEANQsAfAB8P8B8AHwAfAB8AHwAfAB8AHw_wHwAfAB8AHwAfAB8AHwAfD_AfAB"
|
||||
"8AHwAfAB8AHwAfAB8P8B8AHwAfAB8AHwAfAB8AHw_wHwAfAB8AHwAfAB8AHwAfD_"
|
||||
"AfAB8AHwAfAB8AHwAfAB8P8B8AHwAfAB8AHwAfAB8AHw_wHwAfAB8AHwAfAB8AHw"
|
||||
"AfD_AfAB8AHwAfAB8AHwAfAB8A8B8AHwAfABsA"
|
||||
};
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
bbase : version 0.13 ~byuu (2008-04-02)
|
||||
bbase : version 0.14 ~byuu (2008-04-16)
|
||||
license: public domain
|
||||
*/
|
||||
|
||||
|
@ -99,37 +99,12 @@ static char *userpath(char *output) {
|
|||
#else
|
||||
static char *userpath(char *output) {
|
||||
strcpy(output, "."); //failsafe
|
||||
struct passwd *userinfo = getpwuid(getuid());
|
||||
struct passwd *userinfo = getpwuid(getuid());
|
||||
if(userinfo) { strcpy(output, userinfo->pw_dir); }
|
||||
return output;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*****
|
||||
* template functions
|
||||
*****/
|
||||
|
||||
template<typename T> inline void safe_free(T &handle) {
|
||||
if(handle) {
|
||||
free(handle);
|
||||
handle = 0;
|
||||
}
|
||||
}
|
||||
|
||||
template<typename T> inline void safe_delete(T &handle) {
|
||||
if(handle) {
|
||||
delete handle;
|
||||
handle = 0;
|
||||
}
|
||||
}
|
||||
|
||||
template<typename T> inline void safe_release(T &handle) {
|
||||
if(handle) {
|
||||
handle->Release();
|
||||
handle = 0;
|
||||
}
|
||||
}
|
||||
|
||||
template<int min, int max, typename T> inline T minmax(const T x) {
|
||||
return (x < (T)min) ? (T)min : (x > (T)max) ? (T)max : x;
|
||||
}
|
||||
|
@ -177,47 +152,47 @@ template<int min, int max, typename T> inline T minmax(const T x) {
|
|||
*****/
|
||||
|
||||
//pseudo-random number generator
|
||||
static uint prng() {
|
||||
static uint n = 0;
|
||||
static unsigned prng() {
|
||||
static unsigned n = 0;
|
||||
return n = (n >> 1) ^ (((n & 1) - 1) & 0xedb88320);
|
||||
}
|
||||
|
||||
static uint64 fget(FILE *fp, uint length = 1) {
|
||||
uint64 data = 0;
|
||||
for(uint i = 0; i < length; i++) {
|
||||
static uint64 fget(FILE *fp, unsigned length = 1) {
|
||||
uint64 data = 0;
|
||||
for(unsigned i = 0; i < length; i++) {
|
||||
data |= fgetc(fp) << (i << 3);
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
static void fput(FILE *fp, uint64 data, uint length = 1) {
|
||||
for(uint i = 0; i < length; i++) {
|
||||
static void fput(FILE *fp, uint64 data, unsigned length = 1) {
|
||||
for(unsigned i = 0; i < length; i++) {
|
||||
fputc(data >> (i << 3), fp);
|
||||
}
|
||||
}
|
||||
|
||||
static bool fexists(const char *fn) {
|
||||
FILE *fp = fopen(fn, "rb");
|
||||
if(!fp)return false;
|
||||
FILE *fp = fopen(fn, "rb");
|
||||
if(!fp) return false;
|
||||
fclose(fp);
|
||||
fp = 0;
|
||||
return true;
|
||||
}
|
||||
|
||||
static uint32 fsize(FILE *fp) {
|
||||
if(!fp)return 0;
|
||||
uint32 pos = ftell(fp);
|
||||
static unsigned fsize(FILE *fp) {
|
||||
if(!fp) return 0;
|
||||
unsigned pos = ftell(fp);
|
||||
fseek(fp, 0, SEEK_END);
|
||||
uint32 size = ftell(fp);
|
||||
unsigned size = ftell(fp);
|
||||
fseek(fp, pos, SEEK_SET);
|
||||
return size;
|
||||
}
|
||||
|
||||
static uint32 fsize(const char *fn) {
|
||||
FILE *fp = fopen(fn, "rb");
|
||||
if(!fp)return 0;
|
||||
static unsigned fsize(const char *fn) {
|
||||
FILE *fp = fopen(fn, "rb");
|
||||
if(!fp) return 0;
|
||||
fseek(fp, 0, SEEK_END);
|
||||
uint32 size = ftell(fp);
|
||||
unsigned size = ftell(fp);
|
||||
fclose(fp);
|
||||
fp = 0;
|
||||
return size;
|
||||
|
|
|
@ -4,6 +4,7 @@ void hiro_pbutton_tick(pButton *p) {
|
|||
|
||||
void pButton::create(uint style, uint width, uint height, const char *text) {
|
||||
button = gtk_button_new_with_label(text ? text : "");
|
||||
set_default_font(button);
|
||||
gtk_widget_set_size_request(button, width, height);
|
||||
gtk_widget_show(button);
|
||||
g_signal_connect_swapped(G_OBJECT(button), "clicked", G_CALLBACK(hiro_pbutton_tick), (gpointer)this);
|
||||
|
|
|
@ -1,9 +1,10 @@
|
|||
void hiro_pcheckbox_tick(pCheckbox *p) {
|
||||
if(p->self.on_tick) p->self.on_tick(Event(Event::Tick, p->checked(), &p->self));
|
||||
if(!p->locked && p->self.on_tick) p->self.on_tick(Event(Event::Tick, p->checked(), &p->self));
|
||||
}
|
||||
|
||||
void pCheckbox::create(uint style, uint width, uint height, const char *text) {
|
||||
checkbox = gtk_check_button_new_with_label(text ? text : "");
|
||||
set_default_font(checkbox);
|
||||
gtk_widget_set_size_request(checkbox, width, height);
|
||||
gtk_widget_show(checkbox);
|
||||
g_signal_connect_swapped(G_OBJECT(checkbox), "toggled", G_CALLBACK(hiro_pcheckbox_tick), (gpointer)this);
|
||||
|
@ -15,7 +16,9 @@ void pCheckbox::set_text(const char *text) {
|
|||
}
|
||||
|
||||
void pCheckbox::check(bool state) {
|
||||
locked = true;
|
||||
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(checkbox), state ? TRUE : FALSE);
|
||||
locked = false;
|
||||
}
|
||||
|
||||
void pCheckbox::uncheck() {
|
||||
|
@ -28,6 +31,7 @@ bool pCheckbox::checked() {
|
|||
|
||||
pCheckbox::pCheckbox(Checkbox &self_) : pFormControl(self_), self(self_) {
|
||||
checkbox = 0;
|
||||
locked = false;
|
||||
}
|
||||
|
||||
/* internal */
|
||||
|
|
|
@ -10,6 +10,7 @@ public:
|
|||
pCheckbox(Checkbox&);
|
||||
|
||||
/* internal */
|
||||
GtkWidget *checkbox;
|
||||
GtkWidget* gtk_handle();
|
||||
GtkWidget *checkbox;
|
||||
bool locked;
|
||||
};
|
||||
|
|
|
@ -4,6 +4,7 @@ void hiro_pcombobox_change(pCombobox *p) {
|
|||
|
||||
void pCombobox::create(uint style, uint width, uint height, const char *text) {
|
||||
combobox = gtk_combo_box_new_text();
|
||||
set_default_font(combobox);
|
||||
gtk_widget_set_size_request(combobox, width, height);
|
||||
gtk_widget_show(combobox);
|
||||
|
||||
|
|
|
@ -8,12 +8,12 @@ void pEditbox::create(uint style, uint width, uint height, const char *text) {
|
|||
gtk_widget_set_size_request(editbox, width, height);
|
||||
gtk_widget_show(editbox);
|
||||
} else {
|
||||
GtkPolicyType hscroll = (style & Editbox::HorizontalScrollAlways) ? GTK_POLICY_ALWAYS :
|
||||
(style & Editbox::HorizontalScrollNever) ? GTK_POLICY_NEVER :
|
||||
GTK_POLICY_AUTOMATIC;
|
||||
GtkPolicyType vscroll = (style & Editbox::VerticalScrollAlways) ? GTK_POLICY_ALWAYS :
|
||||
(style & Editbox::VerticalScrollNever) ? GTK_POLICY_NEVER :
|
||||
GTK_POLICY_AUTOMATIC;
|
||||
GtkPolicyType hscroll = (style & Editbox::HorizontalScrollAlways) ? GTK_POLICY_ALWAYS :
|
||||
(style & Editbox::HorizontalScrollNever) ? GTK_POLICY_NEVER :
|
||||
GTK_POLICY_AUTOMATIC;
|
||||
GtkPolicyType vscroll = (style & Editbox::VerticalScrollAlways) ? GTK_POLICY_ALWAYS :
|
||||
(style & Editbox::VerticalScrollNever) ? GTK_POLICY_NEVER :
|
||||
GTK_POLICY_AUTOMATIC;
|
||||
scrollbox = gtk_scrolled_window_new(0, 0);
|
||||
gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrollbox), hscroll, vscroll);
|
||||
gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(scrollbox), GTK_SHADOW_ETCHED_IN);
|
||||
|
@ -26,6 +26,8 @@ void pEditbox::create(uint style, uint width, uint height, const char *text) {
|
|||
gtk_widget_show(editbox);
|
||||
gtk_widget_show(scrollbox);
|
||||
}
|
||||
|
||||
set_default_font(editbox);
|
||||
}
|
||||
|
||||
void pEditbox::set_text(const char *text) {
|
||||
|
@ -38,10 +40,10 @@ void pEditbox::set_text(const char *text) {
|
|||
|
||||
uint pEditbox::get_text(char *text, uint length) {
|
||||
if(multiline == false) {
|
||||
const char *temp = gtk_entry_get_text(GTK_ENTRY(editbox));
|
||||
const char *temp = gtk_entry_get_text(GTK_ENTRY(editbox));
|
||||
return strlcpy(text, temp ? temp : "", length);
|
||||
} else {
|
||||
GtkTextIter start, end;
|
||||
GtkTextIter start, end;
|
||||
gtk_text_buffer_get_start_iter(buffer, &start);
|
||||
gtk_text_buffer_get_end_iter(buffer, &end);
|
||||
return strlcpy(text, gtk_text_buffer_get_text(buffer, &start, &end, true), length);
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
void pFrame::create(uint style, uint width, uint height, const char *text) {
|
||||
frame = gtk_frame_new(text ? text : "");
|
||||
set_default_font(frame);
|
||||
gtk_widget_set_size_request(frame, width, height);
|
||||
gtk_widget_show(frame);
|
||||
}
|
||||
|
|
|
@ -6,6 +6,17 @@ using nall::max;
|
|||
|
||||
namespace libhiro {
|
||||
|
||||
static void set_font(GtkWidget *widget, gpointer font) {
|
||||
gtk_widget_modify_font(widget, (PangoFontDescription*)font);
|
||||
if(GTK_IS_CONTAINER(widget)) {
|
||||
gtk_container_foreach(GTK_CONTAINER(widget), (GtkCallback)set_font, font);
|
||||
}
|
||||
}
|
||||
|
||||
static void set_default_font(GtkWidget *widget) {
|
||||
set_font(widget, phiro().font);
|
||||
}
|
||||
|
||||
#include "keymap.cpp"
|
||||
#include "widget.cpp"
|
||||
#include "window.cpp"
|
||||
|
@ -49,9 +60,15 @@ void pHiro::init() {
|
|||
} else {
|
||||
colormap = gdk_screen_get_rgb_colormap(screen);
|
||||
}
|
||||
|
||||
font = pango_font_description_new();
|
||||
pango_font_description_set_family(font, "Sans");
|
||||
pango_font_description_set_absolute_size(font, 11.0 * PANGO_SCALE);
|
||||
pango_font_description_set_style(font, PANGO_STYLE_NORMAL);
|
||||
}
|
||||
|
||||
void pHiro::term() {
|
||||
pango_font_description_free(font);
|
||||
enable_screensaver();
|
||||
}
|
||||
|
||||
|
|
|
@ -55,6 +55,7 @@ public:
|
|||
/* internal */
|
||||
GdkScreen *screen;
|
||||
GdkColormap *colormap;
|
||||
PangoFontDescription *font;
|
||||
bool is_composited;
|
||||
char default_path[PATH_MAX];
|
||||
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
void pLabel::create(uint style, uint width, uint height, const char *text) {
|
||||
label = gtk_label_new(text ? text : "");
|
||||
set_default_font(label);
|
||||
gtk_misc_set_alignment(GTK_MISC(label), 0.0, 0.0);
|
||||
gtk_widget_set_size_request(label, width, height);
|
||||
gtk_widget_show(label);
|
||||
|
|
|
@ -8,22 +8,22 @@ void hiro_plistbox_activate(pListbox *p) {
|
|||
}
|
||||
|
||||
void pListbox::create(uint style, uint width, uint height, const char *columns, const char *text) {
|
||||
bool header = style & Listbox::Header;
|
||||
GtkPolicyType hscroll = (style & Listbox::HorizontalScrollAlways) ? GTK_POLICY_ALWAYS :
|
||||
(style & Listbox::HorizontalScrollNever) ? GTK_POLICY_NEVER :
|
||||
GTK_POLICY_AUTOMATIC;
|
||||
GtkPolicyType vscroll = (style & Listbox::VerticalScrollAlways) ? GTK_POLICY_ALWAYS :
|
||||
(style & Listbox::VerticalScrollNever) ? GTK_POLICY_NEVER :
|
||||
GTK_POLICY_AUTOMATIC;
|
||||
bool header = style & Listbox::Header;
|
||||
GtkPolicyType hscroll = (style & Listbox::HorizontalScrollAlways) ? GTK_POLICY_ALWAYS :
|
||||
(style & Listbox::HorizontalScrollNever) ? GTK_POLICY_NEVER :
|
||||
GTK_POLICY_AUTOMATIC;
|
||||
GtkPolicyType vscroll = (style & Listbox::VerticalScrollAlways) ? GTK_POLICY_ALWAYS :
|
||||
(style & Listbox::VerticalScrollNever) ? GTK_POLICY_NEVER :
|
||||
GTK_POLICY_AUTOMATIC;
|
||||
|
||||
scrollbox = gtk_scrolled_window_new(0, 0);
|
||||
gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrollbox), hscroll, vscroll);
|
||||
gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(scrollbox), GTK_SHADOW_ETCHED_IN);
|
||||
|
||||
lstring list;
|
||||
lstring list;
|
||||
split(list, "\t", columns);
|
||||
|
||||
GType *v = (GType*)malloc(count(list) * sizeof(GType));
|
||||
GType *v = (GType*)malloc(count(list) * sizeof(GType));
|
||||
for(uint i = 0; i < count(list); i++) v[i] = G_TYPE_STRING;
|
||||
store = gtk_list_store_newv(count(list), v);
|
||||
free(v);
|
||||
|
@ -35,7 +35,7 @@ GType *v = (GType*)malloc(count(list) * sizeof(GType));
|
|||
gtk_widget_show(listbox);
|
||||
gtk_widget_show(scrollbox);
|
||||
|
||||
//alternate colors for each listbox entry if there are multiple columns ...
|
||||
//alternate colors for each listbox entry if there are multiple columns ...
|
||||
gtk_tree_view_set_rules_hint(GTK_TREE_VIEW(listbox), count(list) >= 2 ? true : false);
|
||||
for(uint i = 0; i < count(list); i++) {
|
||||
renderer = gtk_cell_renderer_text_new();
|
||||
|
@ -54,6 +54,8 @@ GType *v = (GType*)malloc(count(list) * sizeof(GType));
|
|||
|
||||
g_signal_connect_swapped(G_OBJECT(listbox), "cursor-changed", G_CALLBACK(hiro_plistbox_change), (gpointer)this);
|
||||
g_signal_connect_swapped(G_OBJECT(listbox), "row-activated", G_CALLBACK(hiro_plistbox_activate), (gpointer)this);
|
||||
|
||||
set_default_font(listbox);
|
||||
}
|
||||
|
||||
void pListbox::autosize_columns() {
|
||||
|
|
|
@ -1,15 +1,18 @@
|
|||
void hiro_pmenucheckitem_tick(pMenuCheckItem *p) {
|
||||
if(p->self.on_tick) p->self.on_tick(Event(Event::Tick, p->checked(), &p->self));
|
||||
if(!p->locked && p->self.on_tick) p->self.on_tick(Event(Event::Tick, p->checked(), &p->self));
|
||||
}
|
||||
|
||||
void pMenuCheckItem::create(const char *text) {
|
||||
item = gtk_check_menu_item_new_with_label(text ? text : "?");
|
||||
set_default_font(item);
|
||||
gtk_widget_show(item);
|
||||
g_signal_connect_swapped(G_OBJECT(item), "toggled", G_CALLBACK(hiro_pmenucheckitem_tick), (gpointer)this);
|
||||
}
|
||||
|
||||
void pMenuCheckItem::check(bool state) {
|
||||
locked = true;
|
||||
gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(item), state ? TRUE : FALSE);
|
||||
locked = false;
|
||||
}
|
||||
|
||||
void pMenuCheckItem::uncheck() {
|
||||
|
@ -22,6 +25,7 @@ bool pMenuCheckItem::checked() {
|
|||
|
||||
pMenuCheckItem::pMenuCheckItem(MenuCheckItem &self_) : pMenuControl(self_), self(self_) {
|
||||
item = 0;
|
||||
locked = true;
|
||||
}
|
||||
|
||||
/* internal */
|
||||
|
|
|
@ -9,6 +9,7 @@ public:
|
|||
pMenuCheckItem(MenuCheckItem&);
|
||||
|
||||
/* internal */
|
||||
GtkWidget *item;
|
||||
GtkWidget* gtk_handle();
|
||||
GtkWidget *item;
|
||||
bool locked;
|
||||
};
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
void pMenuGroup::create(const char *text) {
|
||||
group = gtk_menu_new();
|
||||
item = gtk_menu_item_new_with_label(text ? text : "");
|
||||
set_default_font(item);
|
||||
gtk_menu_item_set_submenu(GTK_MENU_ITEM(item), group);
|
||||
gtk_widget_show(item);
|
||||
}
|
||||
|
|
|
@ -4,6 +4,7 @@ void hiro_pmenuitem_tick(pMenuItem *p) {
|
|||
|
||||
void pMenuItem::create(const char *text) {
|
||||
item = gtk_menu_item_new_with_label(text ? text : "");
|
||||
set_default_font(item);
|
||||
g_signal_connect_swapped(G_OBJECT(item), "activate", G_CALLBACK(hiro_pmenuitem_tick), (gpointer)this);
|
||||
gtk_widget_show(item);
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
void hiro_pmenuradioitem_tick(pMenuRadioItem *p) {
|
||||
//GTK+ sends two messages: one for the activated radio item,
|
||||
//and one for the deactivated radio item. ignore the latter.
|
||||
if(p->checked() && p->self.on_tick) p->self.on_tick(Event(Event::Tick, 0, &p->self));
|
||||
//GTK+ sends two messages: one for the activated radio item,
|
||||
//and one for the deactivated radio item. ignore the latter.
|
||||
if(!p->locked && p->checked() && p->self.on_tick) p->self.on_tick(Event(Event::Tick, 0, &p->self));
|
||||
}
|
||||
|
||||
void pMenuRadioItem::create(MenuRadioItemGroup &group, const char *text) {
|
||||
|
@ -10,12 +10,15 @@ void pMenuRadioItem::create(MenuRadioItemGroup &group, const char *text) {
|
|||
} else {
|
||||
item = gtk_radio_menu_item_new_with_label_from_widget(GTK_RADIO_MENU_ITEM(group[0]->p.gtk_handle()), text ? text : "");
|
||||
}
|
||||
set_default_font(item);
|
||||
gtk_widget_show(item);
|
||||
g_signal_connect_swapped(G_OBJECT(item), "toggled", G_CALLBACK(hiro_pmenuradioitem_tick), (gpointer)this);
|
||||
}
|
||||
|
||||
void pMenuRadioItem::check() {
|
||||
locked = true;
|
||||
gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(item), TRUE);
|
||||
locked = false;
|
||||
}
|
||||
|
||||
bool pMenuRadioItem::checked() {
|
||||
|
@ -24,6 +27,7 @@ bool pMenuRadioItem::checked() {
|
|||
|
||||
pMenuRadioItem::pMenuRadioItem(MenuRadioItem &self_) : pMenuControl(self_), self(self_) {
|
||||
item = 0;
|
||||
locked = false;
|
||||
}
|
||||
|
||||
/* internal */
|
||||
|
|
|
@ -8,6 +8,7 @@ public:
|
|||
pMenuRadioItem(MenuRadioItem&);
|
||||
|
||||
/* internal */
|
||||
GtkWidget *item;
|
||||
GtkWidget* gtk_handle();
|
||||
GtkWidget *item;
|
||||
bool locked;
|
||||
};
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
void hiro_pradiobox_tick(pRadiobox *p) {
|
||||
//GTK+ sends two messages: one for the activated radiobox,
|
||||
//and one for the deactivated radiobox. ignore the latter.
|
||||
if(p->checked() && p->self.on_tick) p->self.on_tick(Event(Event::Tick, 0, &p->self));
|
||||
//GTK+ sends two messages: one for the activated radiobox,
|
||||
//and one for the deactivated radiobox. ignore the latter.
|
||||
if(!p->locked && p->checked() && p->self.on_tick) p->self.on_tick(Event(Event::Tick, 0, &p->self));
|
||||
}
|
||||
|
||||
void pRadiobox::create(RadioboxGroup &group, uint style, uint width, uint height, const char *text) {
|
||||
|
@ -10,6 +10,7 @@ void pRadiobox::create(RadioboxGroup &group, uint style, uint width, uint height
|
|||
} else {
|
||||
radiobox = gtk_radio_button_new_with_label_from_widget(GTK_RADIO_BUTTON(group[0]->p.gtk_handle()), text ? text : "");
|
||||
}
|
||||
set_default_font(radiobox);
|
||||
gtk_widget_set_size_request(radiobox, width, height);
|
||||
gtk_widget_show(radiobox);
|
||||
g_signal_connect_swapped(G_OBJECT(radiobox), "toggled", G_CALLBACK(hiro_pradiobox_tick), (gpointer)this);
|
||||
|
@ -21,7 +22,9 @@ void pRadiobox::set_text(const char *text) {
|
|||
}
|
||||
|
||||
void pRadiobox::check() {
|
||||
locked = true;
|
||||
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(radiobox), TRUE);
|
||||
locked = false;
|
||||
}
|
||||
|
||||
bool pRadiobox::checked() {
|
||||
|
@ -30,6 +33,7 @@ bool pRadiobox::checked() {
|
|||
|
||||
pRadiobox::pRadiobox(Radiobox &self_) : pFormControl(self), self(self_) {
|
||||
radiobox = 0;
|
||||
locked = false;
|
||||
}
|
||||
|
||||
/* internal */
|
||||
|
|
|
@ -9,6 +9,7 @@ public:
|
|||
pRadiobox(Radiobox&);
|
||||
|
||||
/* internal */
|
||||
GtkWidget *radiobox;
|
||||
GtkWidget* gtk_handle();
|
||||
GtkWidget *radiobox;
|
||||
bool locked;
|
||||
};
|
||||
|
|
|
@ -65,6 +65,7 @@ void pWindow::create(uint style, uint width, uint height, const char *text) {
|
|||
//without affecting the statusbar color
|
||||
statuscontainer = gtk_event_box_new();
|
||||
statusbar = gtk_statusbar_new();
|
||||
set_default_font(statusbar);
|
||||
gtk_container_add(GTK_CONTAINER(statuscontainer), statusbar);
|
||||
gtk_statusbar_set_has_resize_grip(GTK_STATUSBAR(statusbar), false);
|
||||
gtk_box_pack_start(GTK_BOX(menucontainer), statuscontainer, false, false, 0);
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
hiro
|
||||
version: 0.003 (2008-04-06)
|
||||
version: 0.004 (2008-05-14)
|
||||
author: byuu
|
||||
license: public domain
|
||||
*/
|
||||
|
@ -11,6 +11,7 @@
|
|||
#include <nall/array.hpp>
|
||||
#include <nall/function.hpp>
|
||||
#include <nall/input.hpp>
|
||||
#include <nall/new.hpp>
|
||||
#include <nall/stdint.hpp>
|
||||
#include <nall/string.hpp>
|
||||
#include <nall/utility.hpp>
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
void pButton::create(uint style, uint width, uint height, const char *text) {
|
||||
hwnd = CreateWindow("BUTTON", text ? text : "", WS_CHILD | WS_TABSTOP | WS_VISIBLE,
|
||||
hwnd = CreateWindow(L"BUTTON", utf16(text), WS_CHILD | WS_TABSTOP | WS_VISIBLE,
|
||||
0, 0, width, height,
|
||||
phiro().default_hwnd, (HMENU)instance, GetModuleHandle(0), 0);
|
||||
SetWindowLongPtr(hwnd, GWLP_USERDATA, (LONG_PTR)this);
|
||||
|
@ -7,7 +7,7 @@ void pButton::create(uint style, uint width, uint height, const char *text) {
|
|||
}
|
||||
|
||||
void pButton::set_text(const char *text) {
|
||||
SetWindowText(hwnd, text ? text : "");
|
||||
SetWindowText(hwnd, utf16(text));
|
||||
}
|
||||
|
||||
pButton::pButton(Button &self_) : pFormControl(self_), self(self_) {
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
void pCanvas::create(uint style, uint width, uint height) {
|
||||
hwnd = CreateWindow("hiro_window", "", WS_CHILD,
|
||||
hwnd = CreateWindow(L"hiro_window", L"", WS_CHILD,
|
||||
0, 0, width, height,
|
||||
phiro().default_hwnd, (HMENU)instance, GetModuleHandle(0), 0);
|
||||
SetWindowLongPtr(hwnd, GWLP_USERDATA, (LONG_PTR)this);
|
||||
|
|
|
@ -1,20 +1,16 @@
|
|||
void pCheckbox::create(uint style, uint width, uint height, const char *text) {
|
||||
hwnd = CreateWindow("BUTTON", text ? text : "", WS_CHILD | WS_TABSTOP | WS_VISIBLE | BS_CHECKBOX,
|
||||
hwnd = CreateWindow(L"BUTTON", utf16(text), WS_CHILD | WS_TABSTOP | WS_VISIBLE | BS_CHECKBOX,
|
||||
0, 0, width, height,
|
||||
phiro().default_hwnd, (HMENU)instance, GetModuleHandle(0), 0);
|
||||
SendMessage(hwnd, WM_SETFONT, (WPARAM)phiro().default_font, 0);
|
||||
}
|
||||
|
||||
void pCheckbox::set_text(const char *text) {
|
||||
SetWindowText(hwnd, text ? text : "");
|
||||
SetWindowText(hwnd, utf16(text));
|
||||
}
|
||||
|
||||
void pCheckbox::check(bool state) {
|
||||
bool prev = checked();
|
||||
SendMessage(hwnd, BM_SETCHECK, (WPARAM)(state ? TRUE : FALSE), 0);
|
||||
if(prev != state) {
|
||||
if(self.on_tick) self.on_tick(Event(Event::Tick, state, &self));
|
||||
}
|
||||
}
|
||||
|
||||
void pCheckbox::uncheck() {
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
void pCombobox::create(uint style, uint width, uint height, const char *text) {
|
||||
hwnd = CreateWindowEx(WS_EX_CLIENTEDGE, "COMBOBOX", "",
|
||||
hwnd = CreateWindowEx(WS_EX_CLIENTEDGE, L"COMBOBOX", L"",
|
||||
WS_CHILD | WS_TABSTOP | WS_VISIBLE | CBS_DROPDOWNLIST | CBS_HASSTRINGS,
|
||||
0, 0, width, 200,
|
||||
phiro().default_hwnd, (HMENU)instance, GetModuleHandle(0), 0);
|
||||
|
@ -17,7 +17,7 @@ void pCombobox::create(uint style, uint width, uint height, const char *text) {
|
|||
}
|
||||
|
||||
void pCombobox::add_item(const char *text) {
|
||||
SendMessage(hwnd, CB_ADDSTRING, 0, (LPARAM)text);
|
||||
SendMessage(hwnd, CB_ADDSTRING, 0, (LPARAM)(wchar_t*)utf16(text));
|
||||
if(SendMessage(hwnd, CB_GETCOUNT, 0, 0) == 1) set_selection(0);
|
||||
}
|
||||
|
||||
|
|
|
@ -8,7 +8,7 @@ void pEditbox::create(uint style, uint width, uint height, const char *text) {
|
|||
(style & Editbox::HorizontalScrollNever) ? 0 :
|
||||
ES_AUTOHSCROLL;
|
||||
|
||||
hwnd = CreateWindowEx(WS_EX_CLIENTEDGE, "EDIT", "",
|
||||
hwnd = CreateWindowEx(WS_EX_CLIENTEDGE, L"EDIT", L"",
|
||||
WS_CHILD | WS_VISIBLE | vscroll | hscroll |
|
||||
(multiline == true ? ES_MULTILINE | ES_WANTRETURN : WS_TABSTOP) |
|
||||
(readonly == true ? ES_READONLY : 0),
|
||||
|
@ -22,14 +22,15 @@ void pEditbox::set_text(const char *text) {
|
|||
string temp = text ? text : "";
|
||||
replace(temp, "\r", "");
|
||||
replace(temp, "\n", "\r\n");
|
||||
SetWindowText(hwnd, temp);
|
||||
SetWindowText(hwnd, utf16(temp));
|
||||
}
|
||||
|
||||
uint pEditbox::get_text(char *text, uint length) {
|
||||
GetWindowText(hwnd, text, length);
|
||||
string temp = text;
|
||||
wchar_t buffer[length * 2 + 1];
|
||||
GetWindowText(hwnd, buffer, length * 2);
|
||||
string temp = (const char*)utf8(buffer);
|
||||
replace(temp, "\r", "");
|
||||
strcpy(text, temp);
|
||||
strlcpy(text, temp, length);
|
||||
return strlen(text);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
void pFrame::create(uint style, uint width, uint height, const char *text) {
|
||||
hwnd = CreateWindow("BUTTON", text ? text : "", WS_CHILD | WS_VISIBLE | BS_GROUPBOX,
|
||||
hwnd = CreateWindow(L"BUTTON", utf16(text), WS_CHILD | WS_VISIBLE | BS_GROUPBOX,
|
||||
0, 0, width, height,
|
||||
phiro().default_hwnd, (HMENU)instance, GetModuleHandle(0), 0);
|
||||
SendMessage(hwnd, WM_SETFONT, (WPARAM)phiro().default_font, 0);
|
||||
}
|
||||
|
||||
void pFrame::set_text(const char *text) {
|
||||
SetWindowText(hwnd, text ? text : "");
|
||||
SetWindowText(hwnd, utf16(text));
|
||||
}
|
||||
|
||||
pFrame::pFrame(Frame &self_) : pFormControl(self_), self(self_) {
|
||||
|
|
|
@ -8,6 +8,7 @@ namespace libhiro {
|
|||
|
||||
LRESULT CALLBACK phiro_wndproc(HWND, UINT, WPARAM, LPARAM);
|
||||
|
||||
#include "utf.cpp"
|
||||
#include "keymap.cpp"
|
||||
#include "widget.cpp"
|
||||
#include "window.cpp"
|
||||
|
@ -43,14 +44,14 @@ void pHiro::init() {
|
|||
wc.hIcon = LoadIcon(0, IDI_APPLICATION);
|
||||
wc.hInstance = GetModuleHandle(0);
|
||||
wc.lpfnWndProc = phiro_wndproc;
|
||||
wc.lpszClassName = "hiro_window";
|
||||
wc.lpszClassName = L"hiro_window";
|
||||
wc.lpszMenuName = 0;
|
||||
wc.style = CS_HREDRAW | CS_VREDRAW;
|
||||
RegisterClass(&wc);
|
||||
|
||||
InitCommonControls();
|
||||
default_hwnd = CreateWindow("hiro_window", "", WS_POPUP, 0, 0, 640, 480, 0, 0, GetModuleHandle(0), 0);
|
||||
default_font = create_font("Tahoma", 9);
|
||||
default_hwnd = CreateWindow(L"hiro_window", L"", WS_POPUP, 0, 0, 640, 480, 0, 0, GetModuleHandle(0), 0);
|
||||
default_font = create_font("Tahoma", 8);
|
||||
black_brush = CreateSolidBrush(RGB(0, 0, 0));
|
||||
}
|
||||
|
||||
|
@ -76,12 +77,13 @@ bool pHiro::pending() {
|
|||
}
|
||||
|
||||
bool pHiro::folder_select(Window *focus, char *filename, const char *path) {
|
||||
wchar_t wfilename[_MAX_PATH] = L"";
|
||||
strcpy(filename, "");
|
||||
BROWSEINFO bi;
|
||||
bi.hwndOwner = focus ? focus->p.hwnd : 0;
|
||||
bi.pidlRoot = NULL;
|
||||
bi.pszDisplayName = filename;
|
||||
bi.lpszTitle = "Select Folder";
|
||||
bi.pszDisplayName = wfilename;
|
||||
bi.lpszTitle = L"";
|
||||
bi.ulFlags = BIF_NEWDIALOGSTYLE | BIF_RETURNONLYFSDIRS;
|
||||
bi.lpfn = NULL;
|
||||
bi.lParam = 0;
|
||||
|
@ -89,7 +91,7 @@ bool pHiro::folder_select(Window *focus, char *filename, const char *path) {
|
|||
bool result = false;
|
||||
LPITEMIDLIST pidl = SHBrowseForFolder(&bi);
|
||||
if(pidl) {
|
||||
if(SHGetPathFromIDList(pidl, filename)) {
|
||||
if(SHGetPathFromIDList(pidl, wfilename)) {
|
||||
result = true;
|
||||
IMalloc *imalloc = 0;
|
||||
if(SUCCEEDED(SHGetMalloc(&imalloc))) {
|
||||
|
@ -98,6 +100,7 @@ bool pHiro::folder_select(Window *focus, char *filename, const char *path) {
|
|||
}
|
||||
}
|
||||
}
|
||||
strcpy(filename, utf8(wfilename));
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -127,19 +130,25 @@ bool pHiro::file_open(Window *focus, char *filename, const char *path, const cha
|
|||
if(pf[i] == '|') pf[i] = '\0';
|
||||
}
|
||||
|
||||
utf16 wpf(pf);
|
||||
utf16 wdir(dir);
|
||||
wchar_t wfilename[_MAX_PATH] = L"";
|
||||
|
||||
OPENFILENAME ofn;
|
||||
strcpy(filename, "");
|
||||
memset(&ofn, 0, sizeof(ofn));
|
||||
ofn.lStructSize = sizeof(ofn);
|
||||
ofn.hwndOwner = focus ? focus->p.hwnd : 0;
|
||||
ofn.lpstrFilter = pf;
|
||||
ofn.lpstrInitialDir = dir;
|
||||
ofn.lpstrFile = filename;
|
||||
ofn.lpstrFilter = wpf;
|
||||
ofn.lpstrInitialDir = wdir;
|
||||
ofn.lpstrFile = wfilename;
|
||||
ofn.nMaxFile = MAX_PATH;
|
||||
ofn.Flags = OFN_EXPLORER | OFN_FILEMUSTEXIST;
|
||||
ofn.lpstrDefExt = "";
|
||||
ofn.lpstrDefExt = L"";
|
||||
|
||||
return GetOpenFileName(&ofn);
|
||||
bool result = GetOpenFileName(&ofn);
|
||||
strcpy(filename, utf8(wfilename));
|
||||
return result;
|
||||
}
|
||||
|
||||
bool pHiro::file_save(Window *focus, char *filename, const char *path, const char *filter) {
|
||||
|
@ -168,19 +177,25 @@ bool pHiro::file_save(Window *focus, char *filename, const char *path, const cha
|
|||
if(pf[i] == '|') pf[i] = '\0';
|
||||
}
|
||||
|
||||
utf16 wpf(pf);
|
||||
utf16 wdir(dir);
|
||||
wchar_t wfilename[_MAX_PATH] = L"";
|
||||
|
||||
OPENFILENAME ofn;
|
||||
strcpy(filename, "");
|
||||
memset(&ofn, 0, sizeof(ofn));
|
||||
ofn.lStructSize = sizeof(ofn);
|
||||
ofn.hwndOwner = focus ? focus->p.hwnd : 0;
|
||||
ofn.lpstrFilter = pf;
|
||||
ofn.lpstrInitialDir = dir;
|
||||
ofn.lpstrFile = filename;
|
||||
ofn.lpstrFilter = wpf;
|
||||
ofn.lpstrInitialDir = wdir;
|
||||
ofn.lpstrFile = wfilename;
|
||||
ofn.nMaxFile = MAX_PATH;
|
||||
ofn.Flags = OFN_EXPLORER | OFN_FILEMUSTEXIST;
|
||||
ofn.lpstrDefExt = "";
|
||||
ofn.lpstrDefExt = L"";
|
||||
|
||||
return GetSaveFileName(&ofn);
|
||||
bool result = GetSaveFileName(&ofn);
|
||||
strcpy(filename, utf8(wfilename));
|
||||
return result;
|
||||
}
|
||||
|
||||
uint pHiro::screen_width() {
|
||||
|
@ -214,11 +229,11 @@ pHiro& phiro() {
|
|||
/* internal */
|
||||
|
||||
HFONT pHiro::create_font(const char *name, uint size) {
|
||||
HDC hdc = GetDC(0);
|
||||
HFONT font = CreateFont(-MulDiv(size, GetDeviceCaps(hdc, LOGPIXELSY), 72),
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, name);
|
||||
ReleaseDC(0, hdc);
|
||||
return font;
|
||||
return CreateFont(
|
||||
-(size * 96.0 / 72.0 + 0.5), //96 = DPI
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
utf16(name)
|
||||
);
|
||||
}
|
||||
|
||||
Widget* pHiro::get_widget(uint instance) {
|
||||
|
@ -256,38 +271,38 @@ LRESULT pHiro::wndproc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) {
|
|||
|
||||
case WM_CLOSE: {
|
||||
if(!p || p->self.type != Widget::WindowType) break;
|
||||
Window &w = ((pWindow*)p)->self;
|
||||
Window &w = ((pWindow*)p)->self;
|
||||
if(w.on_close) return (bool)w.on_close(Event(Event::Close, 0, &w));
|
||||
return TRUE; //true = destroy window
|
||||
} break;
|
||||
|
||||
case WM_ENTERMENULOOP: {
|
||||
if(!p || p->self.type != Widget::WindowType) break;
|
||||
Window &w = ((pWindow*)p)->self;
|
||||
Window &w = ((pWindow*)p)->self;
|
||||
if(w.on_block) w.on_block(Event(Event::Block, 0, &w));
|
||||
} break;
|
||||
|
||||
case WM_KEYDOWN: {
|
||||
if(!p || p->self.type != Widget::WindowType) break;
|
||||
Window &w = ((pWindow*)p)->self;
|
||||
Window &w = ((pWindow*)p)->self;
|
||||
if(w.on_keydown) w.on_keydown(Event(Event::KeyDown, translate_key(wparam), &w));
|
||||
} break;
|
||||
|
||||
case WM_KEYUP: {
|
||||
if(!p || p->self.type != Widget::WindowType) break;
|
||||
Window &w = ((pWindow*)p)->self;
|
||||
Window &w = ((pWindow*)p)->self;
|
||||
if(w.on_keyup) w.on_keyup(Event(Event::KeyUp, translate_key(wparam), &w));
|
||||
} break;
|
||||
|
||||
case WM_ERASEBKGND: {
|
||||
if(!p) break;
|
||||
HBRUSH brush = 0;
|
||||
HBRUSH brush = 0;
|
||||
if(p->self.type == Widget::WindowType) brush = ((pWindow*)p)->background;
|
||||
if(p->self.type == Widget::CanvasType) brush = phiro().black_brush;
|
||||
if(!brush) break;
|
||||
RECT rc;
|
||||
RECT rc;
|
||||
GetClientRect(hwnd, &rc);
|
||||
PAINTSTRUCT ps;
|
||||
PAINTSTRUCT ps;
|
||||
BeginPaint(hwnd, &ps);
|
||||
FillRect(ps.hdc, &rc, brush);
|
||||
EndPaint(hwnd, &ps);
|
||||
|
@ -299,36 +314,42 @@ LRESULT pHiro::wndproc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) {
|
|||
} break;
|
||||
|
||||
case WM_COMMAND: {
|
||||
Widget *widget = get_widget(LOWORD(wparam));
|
||||
Widget *widget = get_widget(LOWORD(wparam));
|
||||
if(!widget) break;
|
||||
|
||||
switch(widget->type) {
|
||||
case Widget::MenuItemType: {
|
||||
MenuItem &w = (MenuItem&)*widget;
|
||||
MenuItem &w = (MenuItem&)*widget;
|
||||
if(w.on_tick) w.on_tick(Event(Event::Tick, 0, &w));
|
||||
} break;
|
||||
case Widget::MenuCheckItemType: {
|
||||
MenuCheckItem &w = (MenuCheckItem&)*widget;
|
||||
MenuCheckItem &w = (MenuCheckItem&)*widget;
|
||||
w.check(!w.checked()); //invert check state
|
||||
if(w.on_tick) w.on_tick(Event(Event::Tick, w.checked(), &w));
|
||||
} break;
|
||||
case Widget::MenuRadioItemType: {
|
||||
MenuRadioItem &w = (MenuRadioItem&)*widget;
|
||||
MenuRadioItem &w = (MenuRadioItem&)*widget;
|
||||
bool checked = w.checked();
|
||||
w.check();
|
||||
if(!checked && w.on_tick) w.on_tick(Event(Event::Tick, w.checked(), &w));
|
||||
} break;
|
||||
case Widget::ButtonType: {
|
||||
Button &w = (Button&)*widget;
|
||||
Button &w = (Button&)*widget;
|
||||
if(w.on_tick) w.on_tick(Event(Event::Tick, 0, &w));
|
||||
} break;
|
||||
case Widget::CheckboxType: {
|
||||
Checkbox &w = (Checkbox&)*widget;
|
||||
Checkbox &w = (Checkbox&)*widget;
|
||||
w.check(!w.checked()); //invert check state
|
||||
if(w.on_tick) w.on_tick(Event(Event::Tick, w.checked(), &w));
|
||||
} break;
|
||||
case Widget::RadioboxType: {
|
||||
Radiobox &w = (Radiobox&)*widget;
|
||||
Radiobox &w = (Radiobox&)*widget;
|
||||
bool checked = w.checked();
|
||||
w.check();
|
||||
if(!checked && w.on_tick) w.on_tick(Event(Event::Tick, w.checked(), &w));
|
||||
} break;
|
||||
case Widget::ComboboxType: {
|
||||
Combobox &combobox = (Combobox&)*widget;
|
||||
Combobox &combobox = (Combobox&)*widget;
|
||||
if(HIWORD(wparam) == CBN_SELCHANGE) {
|
||||
if(combobox.p.combobox_selection == combobox.get_selection()) break;
|
||||
if(combobox.on_change) combobox.on_change(Event(Event::Change, combobox.p.combobox_selection = combobox.get_selection(), &combobox));
|
||||
|
@ -339,12 +360,12 @@ LRESULT pHiro::wndproc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) {
|
|||
|
||||
case WM_HSCROLL:
|
||||
case WM_VSCROLL: {
|
||||
Widget *widget = get_widget(GetDlgCtrlID((HWND)lparam));
|
||||
Widget *widget = get_widget(GetDlgCtrlID((HWND)lparam));
|
||||
if(!widget) break;
|
||||
|
||||
switch(widget->type) {
|
||||
case Widget::SliderType: {
|
||||
Slider &slider = (Slider&)*widget;
|
||||
Slider &slider = (Slider&)*widget;
|
||||
if(slider.p.slider_position == slider.get_position()) break;
|
||||
if(slider.on_change) slider.on_change(Event(Event::Change, slider.p.slider_position = slider.get_position(), &slider));
|
||||
} break;
|
||||
|
@ -352,12 +373,12 @@ LRESULT pHiro::wndproc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) {
|
|||
} break;
|
||||
|
||||
case WM_NOTIFY: {
|
||||
Widget *widget = get_widget(LOWORD(wparam));
|
||||
Widget *widget = get_widget(LOWORD(wparam));
|
||||
if(!widget) break;
|
||||
|
||||
switch(widget->type) {
|
||||
case Widget::ListboxType: {
|
||||
Listbox &listbox = (Listbox&)*widget;
|
||||
Listbox &listbox = (Listbox&)*widget;
|
||||
if(((LPNMHDR)lparam)->code == LVN_ITEMCHANGED
|
||||
&& ((LPNMLISTVIEW)lparam)->uChanged & LVIF_STATE
|
||||
&& ListView_GetItemState(listbox.p.hwnd, ((LPNMLISTVIEW)lparam)->iItem, LVIS_FOCUSED)
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
#define _WIN32_IE 0x0600
|
||||
#define NOMINMAX
|
||||
|
||||
#define UNICODE
|
||||
#include <windows.h>
|
||||
#include <commctrl.h>
|
||||
#include <shlobj.h>
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
void pLabel::create(uint style, uint width, uint height, const char *text) {
|
||||
hwnd = CreateWindow("STATIC", text ? text : "", WS_CHILD | WS_VISIBLE,
|
||||
hwnd = CreateWindow(L"STATIC", utf16(text), WS_CHILD | WS_VISIBLE,
|
||||
0, 0, width, height,
|
||||
phiro().default_hwnd, (HMENU)instance, GetModuleHandle(0), 0);
|
||||
SendMessage(hwnd, WM_SETFONT, (WPARAM)phiro().default_font, 0);
|
||||
}
|
||||
|
||||
void pLabel::set_text(const char *text) {
|
||||
SetWindowText(hwnd, text ? text : "");
|
||||
SetWindowText(hwnd, utf16(text));
|
||||
}
|
||||
|
||||
pLabel::pLabel(Label &self_) : pFormControl(self_), self(self_) {
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
void pListbox::create(uint style, uint width, uint height, const char *columns, const char *text) {
|
||||
bool header = style & Listbox::Header;
|
||||
uint hscroll = (style & Listbox::HorizontalScrollAlways) ? WS_HSCROLL :
|
||||
(style & Listbox::HorizontalScrollNever) ? 0 :
|
||||
0;
|
||||
uint vscroll = (style & Listbox::VerticalScrollAlways) ? WS_VSCROLL :
|
||||
(style & Listbox::VerticalScrollNever) ? 0 :
|
||||
0;
|
||||
hwnd = CreateWindowEx(WS_EX_CLIENTEDGE, WC_LISTVIEW, "",
|
||||
bool header = style & Listbox::Header;
|
||||
unsigned hscroll = (style & Listbox::HorizontalScrollAlways) ? WS_HSCROLL :
|
||||
(style & Listbox::HorizontalScrollNever) ? 0 :
|
||||
0;
|
||||
unsigned vscroll = (style & Listbox::VerticalScrollAlways) ? WS_VSCROLL :
|
||||
(style & Listbox::VerticalScrollNever) ? 0 :
|
||||
0;
|
||||
hwnd = CreateWindowEx(WS_EX_CLIENTEDGE, WC_LISTVIEW, L"",
|
||||
WS_CHILD | WS_TABSTOP | WS_VISIBLE |
|
||||
LVS_REPORT | LVS_SINGLESEL | LVS_SHOWSELALWAYS | LVS_NOSORTHEADER | vscroll | hscroll |
|
||||
(header ? 0 : LVS_NOCOLUMNHEADER),
|
||||
|
@ -15,27 +15,28 @@ uint vscroll = (style & Listbox::VerticalScrollAlways) ? WS_VSCROLL :
|
|||
SendMessage(hwnd, WM_SETFONT, (WPARAM)phiro().default_font, 0);
|
||||
ListView_SetExtendedListViewStyle(hwnd, LVS_EX_FULLROWSELECT);
|
||||
|
||||
lstring list;
|
||||
lstring list;
|
||||
split(list, "\t", columns ? columns : "");
|
||||
column_count = count(list);
|
||||
for(uint i = 0; i < count(list); i++) {
|
||||
LVCOLUMN column;
|
||||
for(unsigned i = 0; i < count(list); i++) {
|
||||
LVCOLUMN column;
|
||||
column.mask = LVCF_FMT | LVCF_TEXT | LVCF_SUBITEM;
|
||||
column.fmt = LVCFMT_LEFT;
|
||||
column.iSubItem = count(list);
|
||||
column.pszText = (LPSTR)list[i]();
|
||||
utf16 ulist(list[i]);
|
||||
column.pszText = ulist;
|
||||
ListView_InsertColumn(hwnd, i, &column);
|
||||
}
|
||||
|
||||
if(text && *text) {
|
||||
split(list, "\n", text);
|
||||
for(uint i = 0; i < count(list); i++) add_item(list[i]);
|
||||
for(unsigned i = 0; i < count(list); i++) add_item(list[i]);
|
||||
}
|
||||
autosize_columns();
|
||||
}
|
||||
|
||||
void pListbox::autosize_columns() {
|
||||
for(uint i = 0; i < column_count; i++) {
|
||||
for(unsigned i = 0; i < column_count; i++) {
|
||||
ListView_SetColumnWidth(hwnd, i, LVSCW_AUTOSIZE_USEHEADER);
|
||||
}
|
||||
}
|
||||
|
@ -45,40 +46,43 @@ void pListbox::set_column_width(uint column, uint width) {
|
|||
}
|
||||
|
||||
void pListbox::add_item(const char *text) {
|
||||
lstring list;
|
||||
lstring list;
|
||||
split(list, "\t", text ? text : "");
|
||||
LVITEM item;
|
||||
uint pos = ListView_GetItemCount(hwnd);
|
||||
LVITEM item;
|
||||
unsigned pos = ListView_GetItemCount(hwnd);
|
||||
item.mask = LVIF_TEXT;
|
||||
item.iItem = pos;
|
||||
item.iSubItem = 0;
|
||||
item.pszText = (LPSTR)list[0]();
|
||||
utf16 wtext(list[0]);
|
||||
item.pszText = wtext;
|
||||
ListView_InsertItem(hwnd, &item);
|
||||
|
||||
for(uint i = 1; i < count(list); i++) {
|
||||
ListView_SetItemText(hwnd, pos, i, (LPSTR)list[i]());
|
||||
for(unsigned i = 1; i < count(list); i++) {
|
||||
utf16 wtext(list[i]);
|
||||
ListView_SetItemText(hwnd, pos, i, wtext);
|
||||
}
|
||||
}
|
||||
|
||||
void pListbox::set_item(uint index, const char *text) {
|
||||
lstring list;
|
||||
lstring list;
|
||||
split(list, "\t", text ? text : "");
|
||||
for(uint i = 0; i < count(list); i++) {
|
||||
ListView_SetItemText(hwnd, index, i, list[i]());
|
||||
for(unsigned i = 0; i < count(list); i++) {
|
||||
utf16 wtext(list[i]);
|
||||
ListView_SetItemText(hwnd, index, i, wtext);
|
||||
}
|
||||
}
|
||||
|
||||
int pListbox::get_selection() {
|
||||
uint count = ListView_GetItemCount(hwnd);
|
||||
for(uint i = 0; i < count; i++) {
|
||||
unsigned count = ListView_GetItemCount(hwnd);
|
||||
for(unsigned i = 0; i < count; i++) {
|
||||
if(ListView_GetItemState(hwnd, i, LVIS_SELECTED)) return i;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
void pListbox::set_selection(int index) {
|
||||
uint count = ListView_GetItemCount(hwnd);
|
||||
for(uint i = 0; i < count; i++) {
|
||||
unsigned count = ListView_GetItemCount(hwnd);
|
||||
for(unsigned i = 0; i < count; i++) {
|
||||
ListView_SetItemState(hwnd, i, LVIS_FOCUSED, (i == index) ? LVIS_FOCUSED : 0);
|
||||
ListView_SetItemState(hwnd, i, LVIS_SELECTED, (i == index) ? LVIS_SELECTED : 0);
|
||||
}
|
||||
|
|
|
@ -3,11 +3,7 @@ void pMenuCheckItem::create(const char *text_) {
|
|||
}
|
||||
|
||||
void pMenuCheckItem::check(bool state) {
|
||||
bool prev = checked();
|
||||
CheckMenuItem(parent, instance, state ? MF_CHECKED : MF_UNCHECKED);
|
||||
if(prev != state) {
|
||||
if(self.on_tick) self.on_tick(Event(Event::Tick, state, &self));
|
||||
}
|
||||
}
|
||||
|
||||
void pMenuCheckItem::uncheck() {
|
||||
|
@ -15,7 +11,7 @@ void pMenuCheckItem::uncheck() {
|
|||
}
|
||||
|
||||
bool pMenuCheckItem::checked() {
|
||||
MENUITEMINFO info;
|
||||
MENUITEMINFO info;
|
||||
memset(&info, 0, sizeof info);
|
||||
info.cbSize = sizeof info;
|
||||
info.fMask = MIIM_STATE;
|
||||
|
|
|
@ -6,20 +6,20 @@ void pMenuGroup::create(const char *text_) {
|
|||
void pMenuGroup::attach(MenuControl &menucontrol) {
|
||||
switch(menucontrol.type) {
|
||||
case Widget::MenuGroupType: {
|
||||
AppendMenu(group, MF_STRING | MF_POPUP, (uint)((MenuGroup&)menucontrol).p.group, menucontrol.p.text);
|
||||
AppendMenu(group, MF_STRING | MF_POPUP, (uint)((MenuGroup&)menucontrol).p.group, utf16(menucontrol.p.text));
|
||||
} break;
|
||||
|
||||
case Widget::MenuItemType:
|
||||
case Widget::MenuCheckItemType:
|
||||
case Widget::MenuRadioItemType: {
|
||||
AppendMenu(group, MF_STRING, menucontrol.p.instance, menucontrol.p.text);
|
||||
AppendMenu(group, MF_STRING, menucontrol.p.instance, utf16(menucontrol.p.text));
|
||||
if(menucontrol.type == Widget::MenuRadioItemType && ((MenuRadioItem&)menucontrol).p.create_checked) {
|
||||
CheckMenuItem(group, menucontrol.p.instance, MF_CHECKED);
|
||||
}
|
||||
} break;
|
||||
|
||||
case Widget::MenuSeparatorType: {
|
||||
AppendMenu(group, MF_SEPARATOR, menucontrol.p.instance, "");
|
||||
AppendMenu(group, MF_SEPARATOR, menucontrol.p.instance, L"");
|
||||
} break;
|
||||
}
|
||||
|
||||
|
|
|
@ -5,15 +5,13 @@ void pMenuRadioItem::create(MenuRadioItemGroup &group_, const char *text_) {
|
|||
}
|
||||
|
||||
void pMenuRadioItem::check() {
|
||||
bool prev = checked();
|
||||
for(uint i = 0; i < group.size(); i++) {
|
||||
CheckMenuItem(parent, group[i]->p.instance, (group[i] == &self) ? MF_CHECKED : MF_UNCHECKED);
|
||||
}
|
||||
if(prev == false && self.on_tick) self.on_tick(Event(Event::Tick, 0, &self));
|
||||
}
|
||||
|
||||
bool pMenuRadioItem::checked() {
|
||||
MENUITEMINFO info;
|
||||
MENUITEMINFO info;
|
||||
memset(&info, 0, sizeof info);
|
||||
info.cbSize = sizeof info;
|
||||
info.fMask = MIIM_STATE;
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
void pProgressbar::create(uint style, uint width, uint height) {
|
||||
hwnd = CreateWindow(PROGRESS_CLASS, "", WS_CHILD | WS_VISIBLE | PBS_SMOOTH,
|
||||
hwnd = CreateWindow(PROGRESS_CLASS, L"", WS_CHILD | WS_VISIBLE | PBS_SMOOTH,
|
||||
0, 0, width, height,
|
||||
phiro().default_hwnd, (HMENU)instance, GetModuleHandle(0), 0);
|
||||
SendMessage(hwnd, PBM_SETRANGE, 0, MAKELPARAM(0, 100));
|
||||
|
|
|
@ -1,21 +1,19 @@
|
|||
void pRadiobox::create(RadioboxGroup &group_, uint style, uint width, uint height, const char *text) {
|
||||
group = group_;
|
||||
hwnd = CreateWindow("BUTTON", text ? text : "", WS_CHILD | WS_TABSTOP | WS_VISIBLE | BS_RADIOBUTTON,
|
||||
hwnd = CreateWindow(L"BUTTON", utf16(text), WS_CHILD | WS_TABSTOP | WS_VISIBLE | BS_RADIOBUTTON,
|
||||
0, 0, width, height, phiro().default_hwnd, (HMENU)instance, GetModuleHandle(0), 0);
|
||||
SendMessage(hwnd, WM_SETFONT, (WPARAM)phiro().default_font, 0);
|
||||
if(group[0] == &self) check();
|
||||
}
|
||||
|
||||
void pRadiobox::set_text(const char *text) {
|
||||
SetWindowText(hwnd, text);
|
||||
SetWindowText(hwnd, utf16(text));
|
||||
}
|
||||
|
||||
void pRadiobox::check() {
|
||||
bool prev = checked();
|
||||
for(uint i = 0; i < group.size(); i++) {
|
||||
SendMessage(group[i]->p.hwnd, BM_SETCHECK, (WPARAM)(group[i] == &self), 0);
|
||||
}
|
||||
if(prev == false && self.on_tick) self.on_tick(Event(Event::Tick, 0, &self));
|
||||
}
|
||||
|
||||
bool pRadiobox::checked() {
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
void pSlider::create(uint style, uint width, uint height, uint length) {
|
||||
if(length < 1) length = 1;
|
||||
|
||||
hwnd = CreateWindow(TRACKBAR_CLASS, "",
|
||||
hwnd = CreateWindow(TRACKBAR_CLASS, L"",
|
||||
WS_CHILD | WS_VISIBLE | WS_TABSTOP | TBS_NOTICKS | TBS_BOTH |
|
||||
(style & Slider::Vertical ? TBS_VERT : TBS_HORZ),
|
||||
0, 0, width, height,
|
||||
|
|
|
@ -0,0 +1,55 @@
|
|||
/*****
|
||||
* UTF-8 to UTF-16
|
||||
*****/
|
||||
class utf16 {
|
||||
public:
|
||||
operator wchar_t*() {
|
||||
return buffer;
|
||||
}
|
||||
|
||||
operator const wchar_t*() const {
|
||||
return buffer;
|
||||
}
|
||||
|
||||
utf16(const char *s = "") {
|
||||
if(!s) s = "";
|
||||
unsigned length = MultiByteToWideChar(CP_UTF8, 0, s, -1, 0, 0);
|
||||
buffer = new(zeromemory) wchar_t[length + 1];
|
||||
MultiByteToWideChar(CP_UTF8, 0, s, -1, buffer, length);
|
||||
}
|
||||
|
||||
~utf16() {
|
||||
delete[] buffer;
|
||||
}
|
||||
|
||||
private:
|
||||
wchar_t *buffer;
|
||||
};
|
||||
|
||||
/*****
|
||||
* UTF-16 to UTF-8
|
||||
*****/
|
||||
class utf8 {
|
||||
public:
|
||||
operator char*() {
|
||||
return buffer;
|
||||
}
|
||||
|
||||
operator const char*() const {
|
||||
return buffer;
|
||||
}
|
||||
|
||||
utf8(const wchar_t *s = L"") {
|
||||
if(!s) s = L"";
|
||||
unsigned length = WideCharToMultiByte(CP_UTF8, 0, s, -1, 0, 0, (const char*)0, (BOOL*)0);
|
||||
buffer = new(zeromemory) char[length + 1];
|
||||
WideCharToMultiByte(CP_UTF8, 0, s, -1, buffer, length, (const char*)0, (BOOL*)0);
|
||||
}
|
||||
|
||||
~utf8() {
|
||||
delete[] buffer;
|
||||
}
|
||||
|
||||
private:
|
||||
char *buffer;
|
||||
};
|
|
@ -4,16 +4,16 @@ void pWindow::create(uint style, uint width_, uint height_, const char *text) {
|
|||
RECT rc;
|
||||
SystemParametersInfo(SPI_GETWORKAREA, 0, &rc, 0);
|
||||
|
||||
hwnd = CreateWindowEx(0, "hiro_window", text ? text : "",
|
||||
hwnd = CreateWindowEx(0, L"hiro_window", utf16(text),
|
||||
WS_POPUP | WS_SYSMENU | WS_CAPTION | WS_MINIMIZEBOX,
|
||||
rc.left, rc.top, width_, height_,
|
||||
0, 0, GetModuleHandle(0), 0);
|
||||
hwndr = CreateWindowEx(0, "hiro_window", text ? text : "",
|
||||
hwndr = CreateWindowEx(0, L"hiro_window", utf16(text),
|
||||
WS_POPUP | WS_SYSMENU | WS_CAPTION | WS_MINIMIZEBOX,
|
||||
rc.left, rc.top, width_, height_,
|
||||
0, 0, GetModuleHandle(0), 0);
|
||||
hmenu = CreateMenu();
|
||||
hstatus = CreateWindowEx(0, STATUSCLASSNAME, "",
|
||||
hstatus = CreateWindowEx(0, STATUSCLASSNAME, L"",
|
||||
WS_CHILD, 0, 0, 0, 0, hwnd, 0, GetModuleHandle(0), 0);
|
||||
SetWindowLongPtr(hwnd, GWLP_USERDATA, (LONG_PTR)this);
|
||||
|
||||
|
@ -194,7 +194,7 @@ void pWindow::set_icon(unsigned width, unsigned height, const uint32_t *data) {
|
|||
}
|
||||
|
||||
void pWindow::set_text(const char *text) {
|
||||
SetWindowText(hwnd, text);
|
||||
SetWindowText(hwnd, utf16(text));
|
||||
}
|
||||
|
||||
void pWindow::attach(Window &window, uint x, uint y) {
|
||||
|
@ -214,7 +214,7 @@ void pWindow::attach(Window &window, uint x, uint y) {
|
|||
}
|
||||
|
||||
void pWindow::attach(MenuGroup &menugroup) {
|
||||
AppendMenu(hmenu, MF_STRING | MF_POPUP, (uint)menugroup.p.group, menugroup.p.text);
|
||||
AppendMenu(hmenu, MF_STRING | MF_POPUP, (uint)menugroup.p.group, utf16(menugroup.p.text));
|
||||
if(menu_visible() == false) menu_show();
|
||||
}
|
||||
|
||||
|
@ -317,7 +317,7 @@ bool pWindow::menu_visible() {
|
|||
}
|
||||
|
||||
void pWindow::status_set_text(const char *text) {
|
||||
SendMessage(hstatus, SB_SETTEXT, 0, (LPARAM)text);
|
||||
SendMessage(hstatus, SB_SETTEXT, 0, (LPARAM)(wchar_t*)utf16(text));
|
||||
}
|
||||
|
||||
void pWindow::status_show(bool state) {
|
||||
|
|
|
@ -71,15 +71,15 @@ void HQ2xFilter::render(
|
|||
uint32_t *out0 = output;
|
||||
uint32_t *out1 = output + outpitch;
|
||||
|
||||
#define W1 input[-1 - pitch]
|
||||
#define W2 input[ 0 - pitch]
|
||||
#define W3 input[+1 - pitch]
|
||||
#define W1 input[-1 - (int)pitch]
|
||||
#define W2 input[ 0 - (int)pitch]
|
||||
#define W3 input[+1 - (int)pitch]
|
||||
#define W4 input[-1]
|
||||
#define W5 input[ 0]
|
||||
#define W6 input[+1]
|
||||
#define W7 input[-1 + pitch]
|
||||
#define W8 input[ 0 + pitch]
|
||||
#define W9 input[+1 + pitch]
|
||||
#define W7 input[-1 + (int)pitch]
|
||||
#define W8 input[ 0 + (int)pitch]
|
||||
#define W9 input[+1 + (int)pitch]
|
||||
|
||||
input += pitch;
|
||||
memset(out0, 0, 2048); out0 += outpitch << 1;
|
||||
|
|
|
@ -0,0 +1,66 @@
|
|||
#ifndef NALL_DICTIONARY_HPP
|
||||
#define NALL_DICTIONARY_HPP
|
||||
|
||||
#include <nall/array.hpp>
|
||||
#include <nall/string.hpp>
|
||||
#include <nall/utility.hpp>
|
||||
|
||||
namespace nall {
|
||||
|
||||
class dictionary : noncopyable {
|
||||
public:
|
||||
const char* operator[](const char *input) const {
|
||||
for(unsigned i = 0; i < index_input.size(); i++) {
|
||||
if(!strcmp(input, index_input[i])) return index_output[i];
|
||||
}
|
||||
return input; //no match, return input rather than null string
|
||||
}
|
||||
|
||||
bool import(const char *filename) {
|
||||
string data;
|
||||
if(fread(data, filename) == false) return false;
|
||||
replace(data, "\r", "");
|
||||
|
||||
lstring line;
|
||||
split(line, "\n", data);
|
||||
for(unsigned i = 0; i < count(line); i++) {
|
||||
lstring part;
|
||||
//format: "Input" = "Output"
|
||||
qsplit(part, "=", line[i]);
|
||||
if(count(part) != 2) continue;
|
||||
|
||||
//remove whitespace
|
||||
trim(part[0]);
|
||||
trim(part[1]);
|
||||
|
||||
//remove quotes
|
||||
trim_once(part[0], "\"");
|
||||
trim_once(part[1], "\"");
|
||||
|
||||
unsigned i = index_input.size();
|
||||
index_input[i] = strdup(part[0]);
|
||||
index_output[i] = strdup(part[1]);
|
||||
}
|
||||
}
|
||||
|
||||
void reset() {
|
||||
for(unsigned i = 0; i < index_input.size(); i++) {
|
||||
free(index_input[i]);
|
||||
free(index_output[i]);
|
||||
}
|
||||
index_input.reset();
|
||||
index_output.reset();
|
||||
}
|
||||
|
||||
~dictionary() {
|
||||
reset();
|
||||
}
|
||||
|
||||
private:
|
||||
array<char*> index_input;
|
||||
array<char*> index_output;
|
||||
};
|
||||
|
||||
} //namespace nall
|
||||
|
||||
#endif //ifndef NALL_DICTIONARY_HPP
|
|
@ -0,0 +1,136 @@
|
|||
#include <alsa/asoundlib.h>
|
||||
|
||||
#include <ruby/ruby.h>
|
||||
|
||||
namespace ruby {
|
||||
|
||||
#include "alsa.h"
|
||||
|
||||
class pAudioALSA {
|
||||
public:
|
||||
AudioALSA &self;
|
||||
|
||||
struct {
|
||||
snd_pcm_t *handle;
|
||||
snd_pcm_format_t format;
|
||||
int channels;
|
||||
const char *name;
|
||||
unsigned latency;
|
||||
} device;
|
||||
|
||||
struct {
|
||||
uint16_t *data;
|
||||
unsigned length;
|
||||
unsigned size;
|
||||
} buffer;
|
||||
|
||||
struct {
|
||||
unsigned frequency;
|
||||
} settings;
|
||||
|
||||
bool cap(Audio::Setting setting) {
|
||||
if(setting == Audio::Frequency) return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
uintptr_t get(Audio::Setting setting) {
|
||||
if(setting == Audio::Frequency) return settings.frequency;
|
||||
return false;
|
||||
}
|
||||
|
||||
bool set(Audio::Setting setting, uintptr_t param) {
|
||||
if(setting == Audio::Frequency) {
|
||||
settings.frequency = param;
|
||||
if(device.handle) {
|
||||
term();
|
||||
init();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void sample(uint16_t left, uint16_t right) {
|
||||
if(!device.handle) return;
|
||||
|
||||
buffer.data[buffer.length++] = left;
|
||||
buffer.data[buffer.length++] = right;
|
||||
if(buffer.length + 2 < buffer.size) return; //will crash in some cases if not stopped two before
|
||||
|
||||
snd_pcm_sframes_t written = snd_pcm_writei(device.handle, buffer.data, buffer.length);
|
||||
if(written < 0) {
|
||||
snd_pcm_recover(device.handle, written, 1);
|
||||
//no samples written, drop one sample to prevent possible emulation stall
|
||||
buffer.length -= 2;
|
||||
memmove(buffer.data, buffer.data + 2, buffer.length * sizeof(uint16_t));
|
||||
} else if(written < buffer.length) {
|
||||
//only some samples written
|
||||
buffer.length -= written;
|
||||
memmove(buffer.data, buffer.data + written, buffer.length * sizeof(uint16_t));
|
||||
} else {
|
||||
//all samples written
|
||||
buffer.length = 0;
|
||||
}
|
||||
}
|
||||
|
||||
bool init() {
|
||||
buffer.data = new uint16_t[buffer.size];
|
||||
|
||||
if(snd_pcm_open(&device.handle, device.name, SND_PCM_STREAM_PLAYBACK, SND_PCM_NONBLOCK) < 0) {
|
||||
//failed to initialize
|
||||
term();
|
||||
return false;
|
||||
}
|
||||
|
||||
if(snd_pcm_set_params(device.handle, device.format, SND_PCM_ACCESS_RW_INTERLEAVED,
|
||||
device.channels, settings.frequency, 1, device.latency) < 0) {
|
||||
//failed to set device parameters
|
||||
term();
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void term() {
|
||||
if(device.handle) {
|
||||
snd_pcm_drain(device.handle);
|
||||
snd_pcm_close(device.handle);
|
||||
device.handle = 0;
|
||||
}
|
||||
|
||||
if(buffer.data) {
|
||||
delete[] buffer.data;
|
||||
buffer.data = 0;
|
||||
}
|
||||
}
|
||||
|
||||
pAudioALSA(AudioALSA &self_) : self(self_) {
|
||||
device.handle = 0;
|
||||
device.format = SND_PCM_FORMAT_S16_LE;
|
||||
device.channels = 2;
|
||||
device.name = "default";
|
||||
device.latency = 90;
|
||||
|
||||
buffer.data = 0;
|
||||
buffer.length = 0;
|
||||
buffer.size = device.latency * 32;
|
||||
|
||||
settings.frequency = 22050;
|
||||
}
|
||||
|
||||
~pAudioALSA() {
|
||||
term();
|
||||
}
|
||||
};
|
||||
|
||||
bool AudioALSA::cap(Setting setting) { return p.cap(setting); }
|
||||
uintptr_t AudioALSA::get(Setting setting) { return p.get(setting); }
|
||||
bool AudioALSA::set(Setting setting, uintptr_t param) { return p.set(setting, param); }
|
||||
void AudioALSA::sample(uint16_t left, uint16_t right) { p.sample(left, right); }
|
||||
bool AudioALSA::init() { return p.init(); }
|
||||
void AudioALSA::term() { p.term(); }
|
||||
AudioALSA::AudioALSA() : p(*new pAudioALSA(*this)) {}
|
||||
AudioALSA::~AudioALSA() { delete &p; }
|
||||
|
||||
} //namespace ruby
|
|
@ -0,0 +1,23 @@
|
|||
/*
|
||||
audio.alsa (2008-05-04)
|
||||
author: Nach
|
||||
*/
|
||||
|
||||
class pAudioALSA;
|
||||
|
||||
class AudioALSA : public Audio {
|
||||
public:
|
||||
bool cap(Setting);
|
||||
uintptr_t get(Setting);
|
||||
bool set(Setting, uintptr_t);
|
||||
|
||||
void sample(uint16_t left, uint16_t right);
|
||||
bool init();
|
||||
void term();
|
||||
|
||||
AudioALSA();
|
||||
~AudioALSA();
|
||||
|
||||
private:
|
||||
pAudioALSA &p;
|
||||
};
|
|
@ -92,6 +92,10 @@ void AudioInterface::driver(const char *driver) {
|
|||
|
||||
if(!strcmp(driver, "none")) p = new Audio();
|
||||
|
||||
#ifdef AUDIO_ALSA
|
||||
else if(!strcmp(driver, "alsa")) p = new AudioALSA();
|
||||
#endif
|
||||
|
||||
#ifdef AUDIO_AO
|
||||
else if(!strcmp(driver, "ao")) p = new AudioAO();
|
||||
#endif
|
||||
|
@ -114,6 +118,8 @@ void AudioInterface::driver(const char *driver) {
|
|||
p = new AudioDS();
|
||||
#elif defined(AUDIO_AO)
|
||||
p = new AudioAO();
|
||||
#elif defined(AUDIO_ALSA)
|
||||
p = new AudioALSA();
|
||||
#elif defined(AUDIO_OPENAL)
|
||||
p = new AudioOpenAL();
|
||||
#elif defined(AUDIO_OSS)
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
ruby
|
||||
version: 0.02 (2008-04-06)
|
||||
version: 0.03 (2008-05-04)
|
||||
license: public domain
|
||||
*/
|
||||
|
||||
|
|
|
@ -30,6 +30,10 @@
|
|||
|
||||
/* Audio */
|
||||
|
||||
#ifdef AUDIO_ALSA
|
||||
#include <ruby/audio/alsa.cpp>
|
||||
#endif
|
||||
|
||||
#ifdef AUDIO_AO
|
||||
#include <ruby/audio/ao.cpp>
|
||||
#endif
|
||||
|
|
|
@ -330,12 +330,9 @@ void bPPU::cgram_write(uint16 addr, uint8 value) {
|
|||
}
|
||||
|
||||
bPPU::bPPU() {
|
||||
vram = (uint8*)malloc(65536);
|
||||
oam = (uint8*)malloc( 544);
|
||||
cgram = (uint8*)malloc( 512);
|
||||
memset(vram, 0, 65536);
|
||||
memset(oam, 0, 544);
|
||||
memset(cgram, 0, 512);
|
||||
vram = new(zeromemory) uint8_t[65536];
|
||||
oam = new(zeromemory) uint8_t[ 544];
|
||||
cgram = new(zeromemory) uint8_t[ 512];
|
||||
|
||||
init_tiledata_cache();
|
||||
|
||||
|
@ -359,7 +356,7 @@ bPPU::bPPU() {
|
|||
}
|
||||
|
||||
bPPU::~bPPU() {
|
||||
free(vram);
|
||||
free(oam);
|
||||
free(cgram);
|
||||
delete[] vram;
|
||||
delete[] oam;
|
||||
delete[] cgram;
|
||||
}
|
||||
|
|
|
@ -15,19 +15,16 @@ uint8_t* FileReader::read(unsigned length) {
|
|||
|
||||
if(length == 0) {
|
||||
//read the entire file into RAM
|
||||
data = (uint8*)malloc(filesize);
|
||||
memset(data, 0, filesize);
|
||||
data = new(zeromemory) uint8_t[filesize];
|
||||
if(fp) fread(data, 1, filesize, fp);
|
||||
} else if(length > filesize) {
|
||||
//read the entire file into RAM, pad the rest with 0x00s
|
||||
data = (uint8*)malloc(length);
|
||||
memset(data, 0, length);
|
||||
if(fp)fread(data, 1, filesize, fp);
|
||||
data = new(zeromemory) uint8_t[length];
|
||||
if(fp) fread(data, 1, filesize, fp);
|
||||
} else { //filesize >= length
|
||||
//read only what was requested
|
||||
data = (uint8*)malloc(length);
|
||||
memset(data, 0, length);
|
||||
if(fp)fread(data, 1, length, fp);
|
||||
data = new(zeromemory) uint8_t[length];
|
||||
if(fp) fread(data, 1, length, fp);
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
@ -57,25 +54,5 @@ FileReader::~FileReader() {
|
|||
fp = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void FileWriter::write(uint8_t *buffer, unsigned length) {
|
||||
if(!fp) return;
|
||||
fwrite(buffer, 1, length, fp);
|
||||
}
|
||||
|
||||
bool FileWriter::ready() {
|
||||
return (fp != 0);
|
||||
}
|
||||
|
||||
FileWriter::FileWriter(const char *fn) {
|
||||
fp = fopen(fn, "wb");
|
||||
}
|
||||
|
||||
FileWriter::~FileWriter() {
|
||||
if(fp) {
|
||||
fclose(fp);
|
||||
fp = 0;
|
||||
}
|
||||
}
|
||||
|
||||
#endif //ifdef READER_CPP
|
||||
|
|
|
@ -1,25 +1,13 @@
|
|||
class FileReader : public Reader {
|
||||
private:
|
||||
FILE *fp;
|
||||
unsigned filesize;
|
||||
|
||||
public:
|
||||
unsigned size();
|
||||
uint8_t* read(unsigned length = 0);
|
||||
bool ready();
|
||||
|
||||
FileReader(const char *fn);
|
||||
~FileReader();
|
||||
};
|
||||
|
||||
class FileWriter : public Writer {
|
||||
private:
|
||||
FILE *fp;
|
||||
|
||||
public:
|
||||
void write(uint8_t *buffer, unsigned length);
|
||||
bool ready();
|
||||
|
||||
FileWriter(const char *fn);
|
||||
~FileWriter();
|
||||
~FileReader();
|
||||
|
||||
private:
|
||||
FILE *fp;
|
||||
unsigned filesize;
|
||||
};
|
||||
|
|
|
@ -15,19 +15,16 @@ uint8_t* GZReader::read(unsigned length) {
|
|||
|
||||
if(length == 0) {
|
||||
//read the entire file into RAM
|
||||
data = (uint8*)malloc(filesize);
|
||||
memset(data, 0, filesize);
|
||||
if(gp)gzread(gp, data, filesize);
|
||||
data = new(zeromemory) uint8_t[filesize];
|
||||
if(gp) gzread(gp, data, filesize);
|
||||
} else if(length > filesize) {
|
||||
//read the entire file into RAM, pad the rest with 0x00s
|
||||
data = (uint8*)malloc(length);
|
||||
memset(data, 0, length);
|
||||
if(gp)gzread(gp, data, filesize);
|
||||
data = new(zeromemory) uint8_t[length];
|
||||
if(gp) gzread(gp, data, filesize);
|
||||
} else { //filesize >= length
|
||||
//read only what was requested
|
||||
data = (uint8*)malloc(length);
|
||||
memset(data, 0, length);
|
||||
if(gp)gzread(gp, data, length);
|
||||
data = new(zeromemory) uint8_t[length];
|
||||
if(gp) gzread(gp, data, length);
|
||||
}
|
||||
|
||||
return data;
|
||||
|
@ -40,7 +37,7 @@ bool GZReader::ready() {
|
|||
GZReader::GZReader(const char *fn) {
|
||||
gp = 0;
|
||||
FILE *fp = fopen(fn, "rb");
|
||||
if(!fp)return;
|
||||
if(!fp) return;
|
||||
|
||||
fseek(fp, 0, SEEK_END);
|
||||
filesize = ftell(fp);
|
||||
|
@ -62,7 +59,7 @@ uint32 gzsize;
|
|||
fp = 0;
|
||||
|
||||
gp = gzopen(fn, "rb");
|
||||
if(!gp)return;
|
||||
if(!gp) return;
|
||||
|
||||
if(!gzdirect(gp)) {
|
||||
filesize = gzsize;
|
||||
|
|
|
@ -15,12 +15,11 @@ uint8_t* JMAReader::read(unsigned length) {
|
|||
|
||||
if(length <= filesize) {
|
||||
//read the entire file into RAM
|
||||
data = (uint8_t*)malloc(filesize);
|
||||
data = new(zeromemory) uint8_t[filesize];
|
||||
JMAFile.extract_file(cname, data);
|
||||
} else if(length > filesize) {
|
||||
//read the entire file into RAM, pad the rest with 0x00s
|
||||
data = (uint8_t*)malloc(length);
|
||||
memset(data, 0, length);
|
||||
data = new(zeromemory) uint8_t[length];
|
||||
JMAFile.extract_file(cname, data);
|
||||
}
|
||||
|
||||
|
|
|
@ -13,9 +13,3 @@ public:
|
|||
virtual uint8_t* read(unsigned length = 0) = 0;
|
||||
virtual bool ready() { return true; } //can only call read() when ready() returns true
|
||||
};
|
||||
|
||||
class Writer {
|
||||
public:
|
||||
virtual void write(uint8_t *buffer, uint32 length) = 0;
|
||||
virtual bool ready() { return true; }
|
||||
};
|
||||
|
|
|
@ -15,12 +15,11 @@ uint8_t* ZipReader::read(unsigned length) {
|
|||
|
||||
if(length <= filesize) {
|
||||
//read the entire file into RAM
|
||||
data = (uint8_t*)malloc(filesize);
|
||||
data = new(zeromemory) uint8_t[filesize];
|
||||
unzReadCurrentFile(zipfile, data, filesize);
|
||||
} else if(length > filesize) {
|
||||
//read the entire file into RAM, pad the rest with 0x00s
|
||||
data = (uint8_t*)malloc(length);
|
||||
memset(data, 0, length);
|
||||
data = new(zeromemory) uint8_t[length];
|
||||
unzReadCurrentFile(zipfile, data, filesize);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,19 +1,32 @@
|
|||
template<int mask>
|
||||
struct SMPFlag {
|
||||
uint8 &data;
|
||||
|
||||
inline operator bool() const { return data & mask; }
|
||||
inline SMPFlag& operator=(bool i) { data = (data & ~mask) | (-i & mask); return *this; }
|
||||
|
||||
SMPFlag(uint8 &data_) : data(data_) {}
|
||||
};
|
||||
|
||||
class SMPRegFlags {
|
||||
public:
|
||||
union {
|
||||
uint8 data;
|
||||
struct {
|
||||
bool order_msb8(n:1, v:1, p:1, b:1, h:1, i:1, z:1, c:1);
|
||||
};
|
||||
};
|
||||
public:
|
||||
uint8 data;
|
||||
SMPFlag<0x80> n;
|
||||
SMPFlag<0x40> v;
|
||||
SMPFlag<0x20> p;
|
||||
SMPFlag<0x10> b;
|
||||
SMPFlag<0x08> h;
|
||||
SMPFlag<0x04> i;
|
||||
SMPFlag<0x02> z;
|
||||
SMPFlag<0x01> c;
|
||||
|
||||
inline operator unsigned() const { return data; }
|
||||
template<typename T> inline unsigned operator = (const T i) { data = i; return data; }
|
||||
template<typename T> inline unsigned operator |= (const T i) { data |= i; return data; }
|
||||
template<typename T> inline unsigned operator ^= (const T i) { data ^= i; return data; }
|
||||
template<typename T> inline unsigned operator &= (const T i) { data &= i; return data; }
|
||||
inline unsigned operator = (unsigned i) { data = i; return data; }
|
||||
inline unsigned operator |= (unsigned i) { data |= i; return data; }
|
||||
inline unsigned operator ^= (unsigned i) { data ^= i; return data; }
|
||||
inline unsigned operator &= (unsigned i) { data &= i; return data; }
|
||||
|
||||
SMPRegFlags() : data(0) {}
|
||||
SMPRegFlags() : data(0), n(data), v(data), p(data), b(data), h(data), i(data), z(data), c(data) {}
|
||||
};
|
||||
|
||||
class SMPRegs {
|
||||
|
@ -24,5 +37,6 @@ public:
|
|||
struct { uint8 order_lsb2(a, y); };
|
||||
};
|
||||
uint8 x, sp;
|
||||
SMPRegFlags p;
|
||||
SMPRegFlags p;
|
||||
SMPRegs() : pc(0), ya(0), x(0), sp(0) {}
|
||||
};
|
||||
|
|
|
@ -64,7 +64,7 @@ clrv(0xe0) {
|
|||
notc(0xed) {
|
||||
1:op_io();
|
||||
2:op_io();
|
||||
regs.p.c ^= 1;
|
||||
regs.p.c = !regs.p.c;
|
||||
}
|
||||
|
||||
ei(0xa0, 1),
|
||||
|
|
|
@ -93,7 +93,7 @@ case 0xe0: {
|
|||
case 0xed: {
|
||||
op_io();
|
||||
op_io();
|
||||
regs.p.c ^= 1;
|
||||
regs.p.c = !regs.p.c;
|
||||
} break;
|
||||
|
||||
//ei
|
||||
|
|
|
@ -1,125 +1,125 @@
|
|||
#ifdef SSMP_CPP
|
||||
|
||||
uint8 sSMP::op_adc(uint8 x, uint8 y) {
|
||||
int16 r = x + y + regs.p.c;
|
||||
regs.p.n = !!(r & 0x80);
|
||||
regs.p.v = !!(~(x ^ y) & (y ^ (uint8)r) & 0x80);
|
||||
regs.p.h = !!((x ^ y ^ (uint8)r) & 0x10);
|
||||
regs.p.z = ((uint8)r == 0);
|
||||
regs.p.c = (r > 0xff);
|
||||
int r = x + y + regs.p.c;
|
||||
regs.p.n = r & 0x80;
|
||||
regs.p.v = ~(x ^ y) & (x ^ r) & 0x80;
|
||||
regs.p.h = (x ^ y ^ r) & 0x10;
|
||||
regs.p.z = (uint8)r == 0;
|
||||
regs.p.c = r > 0xff;
|
||||
return r;
|
||||
}
|
||||
|
||||
uint16 sSMP::op_addw(uint16 x, uint16 y) {
|
||||
uint16 r;
|
||||
uint16 r;
|
||||
regs.p.c = 0;
|
||||
r = op_adc(x, y);
|
||||
r |= op_adc(x >> 8, y >> 8) << 8;
|
||||
regs.p.z = (r == 0);
|
||||
regs.p.z = r == 0;
|
||||
return r;
|
||||
}
|
||||
|
||||
uint8 sSMP::op_and(uint8 x, uint8 y) {
|
||||
x &= y;
|
||||
regs.p.n = !!(x & 0x80);
|
||||
regs.p.z = (x == 0);
|
||||
regs.p.n = x & 0x80;
|
||||
regs.p.z = x == 0;
|
||||
return x;
|
||||
}
|
||||
|
||||
uint8 sSMP::op_cmp(uint8 x, uint8 y) {
|
||||
int16 r = x - y;
|
||||
regs.p.n = !!(r & 0x80);
|
||||
regs.p.z = ((uint8)r == 0);
|
||||
regs.p.c = (r >= 0);
|
||||
int r = x - y;
|
||||
regs.p.n = r & 0x80;
|
||||
regs.p.z = (uint8)r == 0;
|
||||
regs.p.c = r >= 0;
|
||||
return x;
|
||||
}
|
||||
|
||||
uint16 sSMP::op_cmpw(uint16 x, uint16 y) {
|
||||
int32 r = x - y;
|
||||
regs.p.n = !!(r & 0x8000);
|
||||
regs.p.z = ((uint16)r == 0);
|
||||
regs.p.c = (r >= 0);
|
||||
int r = x - y;
|
||||
regs.p.n = r & 0x8000;
|
||||
regs.p.z = (uint16)r == 0;
|
||||
regs.p.c = r >= 0;
|
||||
return x;
|
||||
}
|
||||
|
||||
uint8 sSMP::op_eor(uint8 x, uint8 y) {
|
||||
x ^= y;
|
||||
regs.p.n = !!(x & 0x80);
|
||||
regs.p.z = (x == 0);
|
||||
regs.p.n = x & 0x80;
|
||||
regs.p.z = x == 0;
|
||||
return x;
|
||||
}
|
||||
|
||||
uint8 sSMP::op_or(uint8 x, uint8 y) {
|
||||
x |= y;
|
||||
regs.p.n = !!(x & 0x80);
|
||||
regs.p.z = (x == 0);
|
||||
regs.p.n = x & 0x80;
|
||||
regs.p.z = x == 0;
|
||||
return x;
|
||||
}
|
||||
|
||||
uint8 sSMP::op_sbc(uint8 x, uint8 y) {
|
||||
int16 r = x - y - !regs.p.c;
|
||||
regs.p.n = !!(r & 0x80);
|
||||
regs.p.v = !!((x ^ y) & (x ^ (uint8)r) & 0x80);
|
||||
regs.p.h = !((x ^ y ^ (uint8)r) & 0x10);
|
||||
regs.p.z = ((uint8)r == 0);
|
||||
regs.p.c = (r >= 0);
|
||||
int r = x - y - !regs.p.c;
|
||||
regs.p.n = r & 0x80;
|
||||
regs.p.v = (x ^ y) & (x ^ r) & 0x80;
|
||||
regs.p.h = !((x ^ y ^ r) & 0x10);
|
||||
regs.p.z = (uint8)r == 0;
|
||||
regs.p.c = r >= 0;
|
||||
return r;
|
||||
}
|
||||
|
||||
uint16 sSMP::op_subw(uint16 x, uint16 y) {
|
||||
uint16 r;
|
||||
uint16 r;
|
||||
regs.p.c = 1;
|
||||
r = op_sbc(x, y);
|
||||
r |= op_sbc(x >> 8, y >> 8) << 8;
|
||||
regs.p.z = (r == 0);
|
||||
regs.p.z = r == 0;
|
||||
return r;
|
||||
}
|
||||
|
||||
uint8 sSMP::op_inc(uint8 x) {
|
||||
x++;
|
||||
regs.p.n = !!(x & 0x80);
|
||||
regs.p.z = (x == 0);
|
||||
regs.p.n = x & 0x80;
|
||||
regs.p.z = x == 0;
|
||||
return x;
|
||||
}
|
||||
|
||||
uint8 sSMP::op_dec(uint8 x) {
|
||||
x--;
|
||||
regs.p.n = !!(x & 0x80);
|
||||
regs.p.z = (x == 0);
|
||||
regs.p.n = x & 0x80;
|
||||
regs.p.z = x == 0;
|
||||
return x;
|
||||
}
|
||||
|
||||
uint8 sSMP::op_asl(uint8 x) {
|
||||
regs.p.c = !!(x & 0x80);
|
||||
regs.p.c = x & 0x80;
|
||||
x <<= 1;
|
||||
regs.p.n = !!(x & 0x80);
|
||||
regs.p.z = (x == 0);
|
||||
regs.p.n = x & 0x80;
|
||||
regs.p.z = x == 0;
|
||||
return x;
|
||||
}
|
||||
|
||||
uint8 sSMP::op_lsr(uint8 x) {
|
||||
regs.p.c = !!(x & 0x01);
|
||||
regs.p.c = x & 0x01;
|
||||
x >>= 1;
|
||||
regs.p.n = !!(x & 0x80);
|
||||
regs.p.z = (x == 0);
|
||||
regs.p.n = x & 0x80;
|
||||
regs.p.z = x == 0;
|
||||
return x;
|
||||
}
|
||||
|
||||
uint8 sSMP::op_rol(uint8 x) {
|
||||
uint8 carry = (uint8)regs.p.c;
|
||||
regs.p.c = !!(x & 0x80);
|
||||
unsigned carry = (unsigned)regs.p.c;
|
||||
regs.p.c = x & 0x80;
|
||||
x = (x << 1) | carry;
|
||||
regs.p.n = !!(x & 0x80);
|
||||
regs.p.z = (x == 0);
|
||||
regs.p.n = x & 0x80;
|
||||
regs.p.z = x == 0;
|
||||
return x;
|
||||
}
|
||||
|
||||
uint8 sSMP::op_ror(uint8 x) {
|
||||
uint8 carry = (uint8)regs.p.c << 7;
|
||||
regs.p.c = !!(x & 0x01);
|
||||
unsigned carry = (unsigned)regs.p.c << 7;
|
||||
regs.p.c = x & 0x01;
|
||||
x = carry | (x >> 1);
|
||||
regs.p.n = !!(x & 0x80);
|
||||
regs.p.z = (x == 0);
|
||||
regs.p.n = x & 0x80;
|
||||
regs.p.z = x == 0;
|
||||
return x;
|
||||
}
|
||||
|
||||
|
|
|
@ -58,10 +58,9 @@ void Tracer::enable(bool en) {
|
|||
|
||||
void Tracer::cpuopmask_enable(bool en) {
|
||||
if(en == true && cpuopmask_enabled() == false) {
|
||||
settings.cpuopmasktbl = (uint8*)malloc(0x200000);
|
||||
memset(settings.cpuopmasktbl, 0x00, 0x200000);
|
||||
settings.cpuopmasktbl = new(zeromemory) uint8_t[0x200000];
|
||||
} else if(en == false && cpuopmask_enabled() == true) {
|
||||
safe_free(settings.cpuopmasktbl);
|
||||
delete[] settings.cpuopmasktbl;
|
||||
}
|
||||
|
||||
settings.cpuopmask = en;
|
||||
|
@ -69,10 +68,9 @@ void Tracer::cpuopmask_enable(bool en) {
|
|||
|
||||
void Tracer::smpopmask_enable(bool en) {
|
||||
if(en == true && smpopmask_enabled() == false) {
|
||||
settings.smpopmasktbl = (uint8*)malloc(0x2000);
|
||||
memset(settings.smpopmasktbl, 0x00, 0x2000);
|
||||
settings.smpopmasktbl = new(zeromemory) uint8_t[0x2000];
|
||||
} else if(en == false && smpopmask_enabled() == true) {
|
||||
safe_free(settings.smpopmasktbl);
|
||||
delete[] settings.smpopmasktbl;
|
||||
}
|
||||
|
||||
settings.smpopmask = en;
|
||||
|
|
|
@ -1,40 +1,40 @@
|
|||
const char AboutWindow::about_text[1024] = ""
|
||||
"bsnes -- version " BSNES_VERSION "\n"
|
||||
"Author: byuu\n"
|
||||
"Project began: October 14th, 2004";
|
||||
|
||||
const char AboutWindow::contributors_text[1024] =
|
||||
"Contributors:\n"
|
||||
" anomie, blargg, DMV27, GIGO, kode54, Nach,\n"
|
||||
" Overload, Richard Bannister, TRAC, zones";
|
||||
|
||||
uintptr_t AboutWindow::close(Event) {
|
||||
hide();
|
||||
return false;
|
||||
}
|
||||
|
||||
void AboutWindow::setup() {
|
||||
create(Window::AutoCenter, 350, 125, "About bsnes ...");
|
||||
set_icon(48, 48, (uint32_t*)resource::icon48);
|
||||
|
||||
icon.create(0, 48, 48);
|
||||
about.create(0, 287, 48, about_text);
|
||||
contributors.create(0, 340, 48, contributors_text);
|
||||
|
||||
attach(icon, 5, 5);
|
||||
attach(about, 58, 5);
|
||||
create(Window::AutoCenter, 320, 130, translate["About bsnes ..."]);
|
||||
set_icon(48, 48, (uint32_t*)resource::icon48);
|
||||
|
||||
icon.create(0, 48, 48);
|
||||
about.create(0, 225, 48, string()
|
||||
<< "bsnes -- " << translate["Version"] << " " << BSNES_VERSION "\n"
|
||||
<< translate["Author"] << ": byuu\n"
|
||||
<< translate["Project began: October 14th, 2004"]
|
||||
);
|
||||
contributors.create(0, 275, 70, string()
|
||||
<< translate["Contributors:"] << "\n"
|
||||
<< " anomie, blargg, DMV27, GIGO, kode54, Nach,\n"
|
||||
<< " Overload, Richard Bannister, TRAC, zones\n"
|
||||
<< "\n"
|
||||
<< translate["Localization by: byuu"]
|
||||
);
|
||||
|
||||
attach(icon, 5, 5);
|
||||
attach(about, 58, 5);
|
||||
attach(contributors, 5, 58);
|
||||
|
||||
on_close = bind(&AboutWindow::close, this);
|
||||
|
||||
uint8_t *buffer = new uint8_t[48 * 48 * 4];
|
||||
memcpy(buffer, resource::icon48, 48 * 48 * 4);
|
||||
for(unsigned i = 0; i < 48 * 48; i++) {
|
||||
uint8_t alpha = buffer[i * 4 + 3];
|
||||
buffer[i * 4 + 2] = uint8_t(1.0 / 256.0 * alpha * buffer[i * 4 + 2]);
|
||||
buffer[i * 4 + 1] = uint8_t(1.0 / 256.0 * alpha * buffer[i * 4 + 1]);
|
||||
buffer[i * 4 + 0] = uint8_t(1.0 / 256.0 * alpha * buffer[i * 4 + 0]);
|
||||
}
|
||||
memcpy(icon.buffer(), buffer, 48 * 48 * 4);
|
||||
delete[] buffer;
|
||||
on_close = bind(&AboutWindow::close, this);
|
||||
|
||||
uint8_t *buffer = new uint8_t[48 * 48 * 4];
|
||||
memcpy(buffer, resource::icon48, 48 * 48 * 4);
|
||||
for(unsigned i = 0; i < 48 * 48; i++) {
|
||||
uint8_t alpha = buffer[i * 4 + 3];
|
||||
buffer[i * 4 + 2] = uint8_t(1.0 / 256.0 * alpha * buffer[i * 4 + 2]);
|
||||
buffer[i * 4 + 1] = uint8_t(1.0 / 256.0 * alpha * buffer[i * 4 + 1]);
|
||||
buffer[i * 4 + 0] = uint8_t(1.0 / 256.0 * alpha * buffer[i * 4 + 0]);
|
||||
}
|
||||
memcpy(icon.buffer(), buffer, 48 * 48 * 4);
|
||||
delete[] buffer;
|
||||
}
|
||||
|
|
|
@ -8,13 +8,7 @@ bool MainWindow::input_ready() {
|
|||
}
|
||||
|
||||
uintptr_t MainWindow::close(Event) {
|
||||
app.term = true;
|
||||
window_about.hide();
|
||||
window_message.hide();
|
||||
window_settings.hide();
|
||||
window_bsxloader.hide();
|
||||
window_stloader.hide();
|
||||
hide();
|
||||
event::quit();
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -26,14 +20,14 @@ uintptr_t MainWindow::event(Event e) {
|
|||
|
||||
if(e.widget == &menu_file_load_bsx) {
|
||||
window_bsxloader.mode = BSXLoaderWindow::ModeBSX;
|
||||
window_bsxloader.set_text("Load BS-X Cartridge");
|
||||
window_bsxloader.set_text(translate["Load BS-X Cartridge"]);
|
||||
window_bsxloader.tbase.set_text(config::path.bsx);
|
||||
window_bsxloader.focus();
|
||||
}
|
||||
|
||||
if(e.widget == &menu_file_load_bsc) {
|
||||
window_bsxloader.mode = BSXLoaderWindow::ModeBSC;
|
||||
window_bsxloader.set_text("Load BS-X Slotted Cartridge");
|
||||
window_bsxloader.set_text(translate["Load BS-X Slotted Cartridge"]);
|
||||
window_bsxloader.tbase.set_text("");
|
||||
window_bsxloader.focus();
|
||||
}
|
||||
|
@ -59,53 +53,50 @@ uintptr_t MainWindow::event(Event e) {
|
|||
event(Event(Event::Close));
|
||||
}
|
||||
|
||||
if(locked == false) {
|
||||
//set locked to true to update below menu item check statuses without triggering events
|
||||
if(e.widget == &menu_settings_videomode_1x) { event::update_multiplier(1); }
|
||||
if(e.widget == &menu_settings_videomode_2x) { event::update_multiplier(2); }
|
||||
if(e.widget == &menu_settings_videomode_3x) { event::update_multiplier(3); }
|
||||
if(e.widget == &menu_settings_videomode_4x) { event::update_multiplier(4); }
|
||||
if(e.widget == &menu_settings_videomode_5x) { event::update_multiplier(5); }
|
||||
if(e.widget == &menu_settings_videomode_1x) { event::update_multiplier(1); }
|
||||
if(e.widget == &menu_settings_videomode_2x) { event::update_multiplier(2); }
|
||||
if(e.widget == &menu_settings_videomode_3x) { event::update_multiplier(3); }
|
||||
if(e.widget == &menu_settings_videomode_4x) { event::update_multiplier(4); }
|
||||
if(e.widget == &menu_settings_videomode_5x) { event::update_multiplier(5); }
|
||||
|
||||
if(e.widget == &menu_settings_videomode_aspect_correction) {
|
||||
event::update_aspect_correction(menu_settings_videomode_aspect_correction.checked());
|
||||
}
|
||||
|
||||
if(e.widget == &menu_settings_videomode_ntsc) { event::update_region(0); }
|
||||
if(e.widget == &menu_settings_videomode_pal) { event::update_region(1); }
|
||||
|
||||
if(e.widget == &menu_settings_videofilter_hwpoint) { event::update_hardware_filter(0); }
|
||||
if(e.widget == &menu_settings_videofilter_hwlinear) { event::update_hardware_filter(1); }
|
||||
|
||||
if(e.widget == &menu_settings_videofilter_swnone) { event::update_software_filter(0); }
|
||||
if(e.widget == &menu_settings_videofilter_swscanline) { event::update_software_filter(1); }
|
||||
if(e.widget == &menu_settings_videofilter_swscale2x) { event::update_software_filter(2); }
|
||||
if(e.widget == &menu_settings_videofilter_swhq2x) { event::update_software_filter(3); }
|
||||
if(e.widget == &menu_settings_videofilter_swntsc) { event::update_software_filter(4); }
|
||||
|
||||
if(e.widget == &menu_settings_videoframeskip_0) { config::video.frameskip = 0; }
|
||||
if(e.widget == &menu_settings_videoframeskip_1) { config::video.frameskip = 1; }
|
||||
if(e.widget == &menu_settings_videoframeskip_2) { config::video.frameskip = 2; }
|
||||
if(e.widget == &menu_settings_videoframeskip_3) { config::video.frameskip = 3; }
|
||||
if(e.widget == &menu_settings_videoframeskip_4) { config::video.frameskip = 4; }
|
||||
if(e.widget == &menu_settings_videoframeskip_5) { config::video.frameskip = 5; }
|
||||
if(e.widget == &menu_settings_videoframeskip_6) { config::video.frameskip = 6; }
|
||||
if(e.widget == &menu_settings_videoframeskip_7) { config::video.frameskip = 7; }
|
||||
if(e.widget == &menu_settings_videoframeskip_8) { config::video.frameskip = 8; }
|
||||
if(e.widget == &menu_settings_videoframeskip_9) { config::video.frameskip = 9; }
|
||||
|
||||
if(e.widget == &menu_settings_mute) {
|
||||
config::audio.mute = menu_settings_mute.checked();
|
||||
}
|
||||
|
||||
if(e.widget == &menu_settings_speedreg_disabled) { event::update_speed_regulation(0); }
|
||||
if(e.widget == &menu_settings_speedreg_slowest) { event::update_speed_regulation(1); }
|
||||
if(e.widget == &menu_settings_speedreg_slow) { event::update_speed_regulation(2); }
|
||||
if(e.widget == &menu_settings_speedreg_normal) { event::update_speed_regulation(3); }
|
||||
if(e.widget == &menu_settings_speedreg_fast) { event::update_speed_regulation(4); }
|
||||
if(e.widget == &menu_settings_speedreg_fastest) { event::update_speed_regulation(5); }
|
||||
if(e.widget == &menu_settings_videomode_aspect_correction) {
|
||||
event::update_aspect_correction(menu_settings_videomode_aspect_correction.checked());
|
||||
}
|
||||
|
||||
if(e.widget == &menu_settings_videomode_ntsc) { event::update_region(0); }
|
||||
if(e.widget == &menu_settings_videomode_pal) { event::update_region(1); }
|
||||
|
||||
if(e.widget == &menu_settings_videofilter_hwpoint) { event::update_hardware_filter(0); }
|
||||
if(e.widget == &menu_settings_videofilter_hwlinear) { event::update_hardware_filter(1); }
|
||||
|
||||
if(e.widget == &menu_settings_videofilter_swnone) { event::update_software_filter(0); }
|
||||
if(e.widget == &menu_settings_videofilter_swscanline) { event::update_software_filter(1); }
|
||||
if(e.widget == &menu_settings_videofilter_swscale2x) { event::update_software_filter(2); }
|
||||
if(e.widget == &menu_settings_videofilter_swhq2x) { event::update_software_filter(3); }
|
||||
if(e.widget == &menu_settings_videofilter_swntsc) { event::update_software_filter(4); }
|
||||
|
||||
if(e.widget == &menu_settings_videoframeskip_0) { event::update_frameskip(0); }
|
||||
if(e.widget == &menu_settings_videoframeskip_1) { event::update_frameskip(1); }
|
||||
if(e.widget == &menu_settings_videoframeskip_2) { event::update_frameskip(2); }
|
||||
if(e.widget == &menu_settings_videoframeskip_3) { event::update_frameskip(3); }
|
||||
if(e.widget == &menu_settings_videoframeskip_4) { event::update_frameskip(4); }
|
||||
if(e.widget == &menu_settings_videoframeskip_5) { event::update_frameskip(5); }
|
||||
if(e.widget == &menu_settings_videoframeskip_6) { event::update_frameskip(6); }
|
||||
if(e.widget == &menu_settings_videoframeskip_7) { event::update_frameskip(7); }
|
||||
if(e.widget == &menu_settings_videoframeskip_8) { event::update_frameskip(8); }
|
||||
if(e.widget == &menu_settings_videoframeskip_9) { event::update_frameskip(9); }
|
||||
|
||||
if(e.widget == &menu_settings_mute) {
|
||||
config::audio.mute = menu_settings_mute.checked();
|
||||
}
|
||||
|
||||
if(e.widget == &menu_settings_emuspeed_slowest) { event::update_emulation_speed(0); }
|
||||
if(e.widget == &menu_settings_emuspeed_slow) { event::update_emulation_speed(1); }
|
||||
if(e.widget == &menu_settings_emuspeed_normal) { event::update_emulation_speed(2); }
|
||||
if(e.widget == &menu_settings_emuspeed_fast) { event::update_emulation_speed(3); }
|
||||
if(e.widget == &menu_settings_emuspeed_fastest) { event::update_emulation_speed(4); }
|
||||
if(e.widget == &menu_settings_emuspeed_disabled) { event::update_emulation_speed(5); }
|
||||
|
||||
if(e.widget == &menu_settings_config) { window_settings.show(); }
|
||||
|
||||
if(e.widget == &menu_misc_logaudio) {
|
||||
|
@ -130,53 +121,52 @@ uintptr_t MainWindow::block(Event) {
|
|||
}
|
||||
|
||||
void MainWindow::setup() {
|
||||
locked = true;
|
||||
|
||||
create(Window::AutoCenter, 256, 224, BSNES_TITLE);
|
||||
set_background_color(0, 0, 0);
|
||||
set_icon(48, 48, (uint32_t*)resource::icon48);
|
||||
|
||||
MenuRadioItemGroup group;
|
||||
attach(menu_file.create("File"));
|
||||
menu_file.attach(menu_file_load.create("Load Cartridge ..."));
|
||||
menu_file.attach(menu_file_load_special.create("Load Special"));
|
||||
menu_file_load_special.attach(menu_file_load_bsx.create("Load BS-X Cartridge ..."));
|
||||
menu_file_load_special.attach(menu_file_load_bsc.create("Load BS-X Slotted Cartridge ..."));
|
||||
menu_file_load_special.attach(menu_file_load_st.create("Load ST Cartridge ..."));
|
||||
menu_file.attach(menu_file_unload.create("Unload Cartridge"));
|
||||
MenuRadioItemGroup group;
|
||||
attach(menu_file.create(translate["System"]));
|
||||
menu_file.attach(menu_file_load.create(string() << translate["Load Cartridge"] << " ..."));
|
||||
menu_file.attach(menu_file_load_special.create(translate["Load Special"]));
|
||||
menu_file_load_special.attach(menu_file_load_bsx.create(string() << translate["Load BS-X Cartridge"] << " ..."));
|
||||
menu_file_load_special.attach(menu_file_load_bsc.create(string() << translate["Load BS-X Slotted Cartridge"] << " ..."));
|
||||
menu_file_load_special.attach(menu_file_load_st.create(string() << translate["Load Sufami Turbo Cartridge"] << " ..."));
|
||||
menu_file.attach(menu_file_unload.create(translate["Unload Cartridge"]));
|
||||
menu_file.attach(menu_file_sep1.create());
|
||||
menu_file.attach(menu_file_reset.create("Reset System"));
|
||||
menu_file.attach(menu_file_power.create("Power Cycle System"));
|
||||
menu_file.attach(menu_file_reset.create(translate["Reset"]));
|
||||
menu_file_power.create(translate["Power Cycle"]);
|
||||
if(config::advanced.enable) menu_file.attach(menu_file_power);
|
||||
menu_file.attach(menu_file_sep2.create());
|
||||
menu_file.attach(menu_file_exit.create("Exit"));
|
||||
menu_file.attach(menu_file_exit.create(translate["Exit"]));
|
||||
|
||||
attach(menu_settings.create("Settings"));
|
||||
menu_settings.attach(menu_settings_videomode.create("Video Mode"));
|
||||
attach(menu_settings.create(translate["Settings"]));
|
||||
menu_settings.attach(menu_settings_videomode.create(translate["Video Mode"]));
|
||||
group.add(&menu_settings_videomode_1x);
|
||||
group.add(&menu_settings_videomode_2x);
|
||||
group.add(&menu_settings_videomode_3x);
|
||||
group.add(&menu_settings_videomode_4x);
|
||||
group.add(&menu_settings_videomode_5x);
|
||||
menu_settings_videomode.attach(menu_settings_videomode_1x.create(group, "Scale 1x"));
|
||||
menu_settings_videomode.attach(menu_settings_videomode_2x.create(group, "Scale 2x"));
|
||||
menu_settings_videomode.attach(menu_settings_videomode_3x.create(group, "Scale 3x"));
|
||||
menu_settings_videomode.attach(menu_settings_videomode_4x.create(group, "Scale 4x"));
|
||||
menu_settings_videomode.attach(menu_settings_videomode_5x.create(group, "Scale 5x"));
|
||||
menu_settings_videomode.attach(menu_settings_videomode_1x.create(group, translate["Scale 1x"]));
|
||||
menu_settings_videomode.attach(menu_settings_videomode_2x.create(group, translate["Scale 2x"]));
|
||||
menu_settings_videomode.attach(menu_settings_videomode_3x.create(group, translate["Scale 3x"]));
|
||||
menu_settings_videomode.attach(menu_settings_videomode_4x.create(group, translate["Scale 4x"]));
|
||||
menu_settings_videomode.attach(menu_settings_videomode_5x.create(group, translate["Scale 5x"]));
|
||||
group.reset();
|
||||
menu_settings_videomode.attach(menu_settings_videomode_sep1.create());
|
||||
menu_settings_videomode.attach(menu_settings_videomode_aspect_correction.create("Correct Aspect Ratio"));
|
||||
menu_settings_videomode.attach(menu_settings_videomode_aspect_correction.create(translate["Correct Aspect Ratio"]));
|
||||
menu_settings_videomode.attach(menu_settings_videomode_sep2.create());
|
||||
group.add(&menu_settings_videomode_ntsc);
|
||||
group.add(&menu_settings_videomode_pal);
|
||||
menu_settings_videomode.attach(menu_settings_videomode_ntsc.create(group, "NTSC"));
|
||||
menu_settings_videomode.attach(menu_settings_videomode_pal.create(group, "PAL"));
|
||||
menu_settings_videomode.attach(menu_settings_videomode_ntsc.create(group, translate["NTSC"]));
|
||||
menu_settings_videomode.attach(menu_settings_videomode_pal.create(group, translate["PAL"]));
|
||||
group.reset();
|
||||
|
||||
menu_settings.attach(menu_settings_videofilter.create("Video Filter"));
|
||||
menu_settings.attach(menu_settings_videofilter.create(translate["Video Filter"]));
|
||||
group.add(&menu_settings_videofilter_hwpoint);
|
||||
group.add(&menu_settings_videofilter_hwlinear);
|
||||
menu_settings_videofilter.attach(menu_settings_videofilter_hwpoint.create(group, "Point"));
|
||||
menu_settings_videofilter.attach(menu_settings_videofilter_hwlinear.create(group, "Linear"));
|
||||
menu_settings_videofilter.attach(menu_settings_videofilter_hwpoint.create(group, translate["Point"]));
|
||||
menu_settings_videofilter.attach(menu_settings_videofilter_hwlinear.create(group, translate["Linear"]));
|
||||
group.reset();
|
||||
menu_settings_videofilter.attach(menu_settings_videofilter_sep1.create());
|
||||
group.add(&menu_settings_videofilter_swnone);
|
||||
|
@ -184,14 +174,14 @@ MenuRadioItemGroup group;
|
|||
group.add(&menu_settings_videofilter_swscale2x);
|
||||
group.add(&menu_settings_videofilter_swhq2x);
|
||||
group.add(&menu_settings_videofilter_swntsc);
|
||||
menu_settings_videofilter.attach(menu_settings_videofilter_swnone.create(group, "None"));
|
||||
menu_settings_videofilter.attach(menu_settings_videofilter_swscanline.create(group, "Scanline"));
|
||||
menu_settings_videofilter.attach(menu_settings_videofilter_swscale2x.create(group, "Scale2x"));
|
||||
menu_settings_videofilter.attach(menu_settings_videofilter_swhq2x.create(group, "HQ2x"));
|
||||
menu_settings_videofilter.attach(menu_settings_videofilter_swntsc.create(group, "NTSC"));
|
||||
menu_settings_videofilter.attach(menu_settings_videofilter_swnone.create(group, translate["None"]));
|
||||
menu_settings_videofilter.attach(menu_settings_videofilter_swscanline.create(group, translate["Scanline"]));
|
||||
menu_settings_videofilter.attach(menu_settings_videofilter_swscale2x.create(group, translate["Scale2x"]));
|
||||
menu_settings_videofilter.attach(menu_settings_videofilter_swhq2x.create(group, translate["HQ2x"]));
|
||||
menu_settings_videofilter.attach(menu_settings_videofilter_swntsc.create(group, translate["NTSC"]));
|
||||
group.reset();
|
||||
|
||||
menu_settings.attach(menu_settings_videoframeskip.create("Video Frameskip"));
|
||||
menu_settings.attach(menu_settings_videoframeskip.create(translate["Video Frameskip"]));
|
||||
group.add(&menu_settings_videoframeskip_0);
|
||||
group.add(&menu_settings_videoframeskip_1);
|
||||
group.add(&menu_settings_videoframeskip_2);
|
||||
|
@ -202,47 +192,49 @@ MenuRadioItemGroup group;
|
|||
group.add(&menu_settings_videoframeskip_7);
|
||||
group.add(&menu_settings_videoframeskip_8);
|
||||
group.add(&menu_settings_videoframeskip_9);
|
||||
menu_settings_videoframeskip.attach(menu_settings_videoframeskip_0.create(group, "0"));
|
||||
menu_settings_videoframeskip.attach(menu_settings_videoframeskip_sep1.create());
|
||||
menu_settings_videoframeskip.attach(menu_settings_videoframeskip_1.create(group, "1"));
|
||||
menu_settings_videoframeskip.attach(menu_settings_videoframeskip_2.create(group, "2"));
|
||||
menu_settings_videoframeskip.attach(menu_settings_videoframeskip_3.create(group, "3"));
|
||||
menu_settings_videoframeskip.attach(menu_settings_videoframeskip_4.create(group, "4"));
|
||||
menu_settings_videoframeskip.attach(menu_settings_videoframeskip_5.create(group, "5"));
|
||||
menu_settings_videoframeskip.attach(menu_settings_videoframeskip_6.create(group, "6"));
|
||||
menu_settings_videoframeskip.attach(menu_settings_videoframeskip_7.create(group, "7"));
|
||||
menu_settings_videoframeskip.attach(menu_settings_videoframeskip_8.create(group, "8"));
|
||||
menu_settings_videoframeskip.attach(menu_settings_videoframeskip_9.create(group, "9"));
|
||||
menu_settings_videoframeskip.attach(menu_settings_videoframeskip_0.create(group, translate["0"]));
|
||||
menu_settings_videoframeskip.attach(menu_settings_videoframeskip_1.create(group, translate["1"]));
|
||||
menu_settings_videoframeskip.attach(menu_settings_videoframeskip_2.create(group, translate["2"]));
|
||||
menu_settings_videoframeskip.attach(menu_settings_videoframeskip_3.create(group, translate["3"]));
|
||||
menu_settings_videoframeskip.attach(menu_settings_videoframeskip_4.create(group, translate["4"]));
|
||||
menu_settings_videoframeskip.attach(menu_settings_videoframeskip_5.create(group, translate["5"]));
|
||||
menu_settings_videoframeskip.attach(menu_settings_videoframeskip_6.create(group, translate["6"]));
|
||||
menu_settings_videoframeskip.attach(menu_settings_videoframeskip_7.create(group, translate["7"]));
|
||||
menu_settings_videoframeskip.attach(menu_settings_videoframeskip_8.create(group, translate["8"]));
|
||||
menu_settings_videoframeskip.attach(menu_settings_videoframeskip_9.create(group, translate["9"]));
|
||||
group.reset();
|
||||
|
||||
menu_settings.attach(menu_settings_sep1.create());
|
||||
menu_settings.attach(menu_settings_mute.create("Mute Sound Output"));
|
||||
menu_settings.attach(menu_settings_mute.create(translate["Mute Audio Output"]));
|
||||
menu_settings.attach(menu_settings_sep2.create());
|
||||
|
||||
menu_settings.attach(menu_settings_speedreg.create("Speed Regulation"));
|
||||
group.add(&menu_settings_speedreg_disabled);
|
||||
group.add(&menu_settings_speedreg_slowest);
|
||||
group.add(&menu_settings_speedreg_slow);
|
||||
group.add(&menu_settings_speedreg_normal);
|
||||
group.add(&menu_settings_speedreg_fast);
|
||||
group.add(&menu_settings_speedreg_fastest);
|
||||
menu_settings_speedreg.attach(menu_settings_speedreg_disabled.create(group, "Disabled"));
|
||||
menu_settings_speedreg.attach(menu_settings_speedreg_sep1.create());
|
||||
menu_settings_speedreg.attach(menu_settings_speedreg_slowest.create(group, "Slowest"));
|
||||
menu_settings_speedreg.attach(menu_settings_speedreg_slow.create(group, "Slow"));
|
||||
menu_settings_speedreg.attach(menu_settings_speedreg_normal.create(group, "Normal"));
|
||||
menu_settings_speedreg.attach(menu_settings_speedreg_fast.create(group, "Fast"));
|
||||
menu_settings_speedreg.attach(menu_settings_speedreg_fastest.create(group, "Fastest"));
|
||||
menu_settings.attach(menu_settings_emuspeed.create(translate["Emulation Speed"]));
|
||||
group.add(&menu_settings_emuspeed_slowest);
|
||||
group.add(&menu_settings_emuspeed_slow);
|
||||
group.add(&menu_settings_emuspeed_normal);
|
||||
group.add(&menu_settings_emuspeed_fast);
|
||||
group.add(&menu_settings_emuspeed_fastest);
|
||||
group.add(&menu_settings_emuspeed_disabled);
|
||||
menu_settings_emuspeed.attach(menu_settings_emuspeed_slowest.create(group, translate["50%"]));
|
||||
menu_settings_emuspeed.attach(menu_settings_emuspeed_slow.create(group, translate["75%"]));
|
||||
menu_settings_emuspeed.attach(menu_settings_emuspeed_normal.create(group, translate["100%"]));
|
||||
menu_settings_emuspeed.attach(menu_settings_emuspeed_fast.create(group, translate["150%"]));
|
||||
menu_settings_emuspeed.attach(menu_settings_emuspeed_fastest.create(group, translate["200%"]));
|
||||
menu_settings_emuspeed.attach(menu_settings_emuspeed_disabled.create(group, translate["Uncapped"]));
|
||||
group.reset();
|
||||
|
||||
menu_settings.attach(menu_settings_sep3.create());
|
||||
menu_settings.attach(menu_settings_config.create("Configuration ..."));
|
||||
menu_settings.attach(menu_settings_config.create(string() << translate["Configuration"] << " ..."));
|
||||
|
||||
attach(menu_misc.create("Misc"));
|
||||
menu_misc.attach(menu_misc_logaudio.create("Log Audio Data"));
|
||||
menu_misc.attach(menu_misc_showstatus.create("Show Statusbar"));
|
||||
attach(menu_misc.create(translate["Misc"]));
|
||||
menu_misc.attach(menu_misc_logaudio.create(translate["Log Audio Data"]));
|
||||
menu_misc.attach(menu_misc_showstatus.create(translate["Show Statusbar"]));
|
||||
menu_misc.attach(menu_misc_sep1.create());
|
||||
menu_misc.attach(menu_misc_about.create("About ..."));
|
||||
menu_misc.attach(menu_misc_about.create(string() << translate["About"] << " ..."));
|
||||
|
||||
menu_file_unload.disable();
|
||||
menu_file_reset.disable();
|
||||
menu_file_power.disable();
|
||||
|
||||
view.create(0, 256, 224);
|
||||
attach(view, 0, 0);
|
||||
|
@ -289,12 +281,12 @@ MenuRadioItemGroup group;
|
|||
menu_settings_videoframeskip_9.on_tick =
|
||||
|
||||
menu_settings_mute.on_tick =
|
||||
menu_settings_speedreg_disabled.on_tick =
|
||||
menu_settings_speedreg_slowest.on_tick =
|
||||
menu_settings_speedreg_slow.on_tick =
|
||||
menu_settings_speedreg_normal.on_tick =
|
||||
menu_settings_speedreg_fast.on_tick =
|
||||
menu_settings_speedreg_fastest.on_tick =
|
||||
menu_settings_emuspeed_slowest.on_tick =
|
||||
menu_settings_emuspeed_slow.on_tick =
|
||||
menu_settings_emuspeed_normal.on_tick =
|
||||
menu_settings_emuspeed_fast.on_tick =
|
||||
menu_settings_emuspeed_fastest.on_tick =
|
||||
menu_settings_emuspeed_disabled.on_tick =
|
||||
menu_settings_config.on_tick =
|
||||
|
||||
menu_misc_logaudio.on_tick =
|
||||
|
@ -302,10 +294,11 @@ MenuRadioItemGroup group;
|
|||
menu_misc_about.on_tick =
|
||||
|
||||
bind(&MainWindow::event, this);
|
||||
|
||||
if(config::misc.status_enable) status.show();
|
||||
}
|
||||
|
||||
void MainWindow::update_menu_settings() {
|
||||
locked = true;
|
||||
void MainWindow::sync() {
|
||||
event::load_video_settings();
|
||||
|
||||
switch(event::video_settings.multiplier) { default:
|
||||
|
@ -338,16 +331,27 @@ void MainWindow::update_menu_settings() {
|
|||
|
||||
menu_settings_mute.check(config::audio.mute);
|
||||
|
||||
switch(config::system.speed_regulation) {
|
||||
case 0: menu_settings_speedreg_disabled.check(); break;
|
||||
case 1: menu_settings_speedreg_slowest.check(); break;
|
||||
case 2: menu_settings_speedreg_slow.check(); break;
|
||||
case 3: menu_settings_speedreg_normal.check(); break;
|
||||
case 4: menu_settings_speedreg_fast.check(); break;
|
||||
case 5: menu_settings_speedreg_fastest.check(); break;
|
||||
switch(config::video.frameskip) {
|
||||
case 0: menu_settings_videoframeskip_0.check(); break;
|
||||
case 1: menu_settings_videoframeskip_1.check(); break;
|
||||
case 2: menu_settings_videoframeskip_2.check(); break;
|
||||
case 3: menu_settings_videoframeskip_3.check(); break;
|
||||
case 4: menu_settings_videoframeskip_4.check(); break;
|
||||
case 5: menu_settings_videoframeskip_5.check(); break;
|
||||
case 6: menu_settings_videoframeskip_6.check(); break;
|
||||
case 7: menu_settings_videoframeskip_7.check(); break;
|
||||
case 8: menu_settings_videoframeskip_8.check(); break;
|
||||
case 9: menu_settings_videoframeskip_9.check(); break;
|
||||
}
|
||||
|
||||
switch(config::system.emulation_speed) {
|
||||
case 0: menu_settings_emuspeed_slowest.check(); break;
|
||||
case 1: menu_settings_emuspeed_slow.check(); break;
|
||||
case 2: menu_settings_emuspeed_normal.check(); break;
|
||||
case 3: menu_settings_emuspeed_fast.check(); break;
|
||||
case 4: menu_settings_emuspeed_fastest.check(); break;
|
||||
case 5: menu_settings_emuspeed_disabled.check(); break;
|
||||
}
|
||||
|
||||
menu_misc_showstatus.check(config::misc.status_enable);
|
||||
|
||||
locked = false;
|
||||
}
|
||||
|
|
|
@ -36,7 +36,6 @@ public:
|
|||
MenuRadioItem menu_settings_videofilter_swntsc;
|
||||
MenuGroup menu_settings_videoframeskip;
|
||||
MenuRadioItem menu_settings_videoframeskip_0;
|
||||
MenuSeparator menu_settings_videoframeskip_sep1;
|
||||
MenuRadioItem menu_settings_videoframeskip_1;
|
||||
MenuRadioItem menu_settings_videoframeskip_2;
|
||||
MenuRadioItem menu_settings_videoframeskip_3;
|
||||
|
@ -49,14 +48,13 @@ public:
|
|||
MenuSeparator menu_settings_sep1;
|
||||
MenuCheckItem menu_settings_mute;
|
||||
MenuSeparator menu_settings_sep2;
|
||||
MenuGroup menu_settings_speedreg;
|
||||
MenuRadioItem menu_settings_speedreg_disabled;
|
||||
MenuSeparator menu_settings_speedreg_sep1;
|
||||
MenuRadioItem menu_settings_speedreg_slowest;
|
||||
MenuRadioItem menu_settings_speedreg_slow;
|
||||
MenuRadioItem menu_settings_speedreg_normal;
|
||||
MenuRadioItem menu_settings_speedreg_fast;
|
||||
MenuRadioItem menu_settings_speedreg_fastest;
|
||||
MenuGroup menu_settings_emuspeed;
|
||||
MenuRadioItem menu_settings_emuspeed_slowest;
|
||||
MenuRadioItem menu_settings_emuspeed_slow;
|
||||
MenuRadioItem menu_settings_emuspeed_normal;
|
||||
MenuRadioItem menu_settings_emuspeed_fast;
|
||||
MenuRadioItem menu_settings_emuspeed_fastest;
|
||||
MenuRadioItem menu_settings_emuspeed_disabled;
|
||||
MenuSeparator menu_settings_sep3;
|
||||
MenuItem menu_settings_config;
|
||||
|
||||
|
@ -68,11 +66,10 @@ public:
|
|||
|
||||
Canvas view;
|
||||
|
||||
bool locked;
|
||||
|
||||
bool input_ready();
|
||||
void setup();
|
||||
void update_menu_settings();
|
||||
void sync();
|
||||
|
||||
uintptr_t close(Event);
|
||||
uintptr_t event(Event);
|
||||
uintptr_t block(Event);
|
||||
|
|
|
@ -5,16 +5,16 @@ uintptr_t MessageWindow::close(Event) {
|
|||
|
||||
void MessageWindow::setup() {
|
||||
create(Window::AutoCenter, 400, 100, "");
|
||||
message.create(0, 390, 60, "Test\nMessage");
|
||||
ok.create(0, 100, 30, "Ok");
|
||||
message.create(0, 390, 60, "");
|
||||
ok.create(0, 100, 25, translate["Ok"]);
|
||||
attach(message, 5, 5);
|
||||
attach(ok, 295, 65);
|
||||
attach(ok, 295, 70);
|
||||
|
||||
on_close = ok.on_tick = bind(&MessageWindow::close, this);
|
||||
}
|
||||
|
||||
void MessageWindow::show(const char *message_, const char *title_) {
|
||||
message.set_text(message_);
|
||||
set_text(title_);
|
||||
set_text(translate[title_]);
|
||||
focus();
|
||||
}
|
||||
|
|
|
@ -1,10 +1,11 @@
|
|||
namespace config {
|
||||
|
||||
char filename[PATH_MAX + 16] = "bsnes.cfg";
|
||||
char bsnes_cfg[PATH_MAX] = "";
|
||||
char locale_cfg[PATH_MAX] = "";
|
||||
|
||||
struct System {
|
||||
static string_setting video, audio, input;
|
||||
static integral_setting speed_regulation;
|
||||
static integral_setting emulation_speed;
|
||||
static integral_setting gamma_ramp, sepia, grayscale, invert, contrast, brightness, gamma;
|
||||
} system;
|
||||
|
||||
|
@ -12,15 +13,15 @@ string_setting System::video(config(), "system.video", "Video hardware interface
|
|||
string_setting System::audio(config(), "system.audio", "Audio hardware interface", "");
|
||||
string_setting System::input(config(), "system.input", "Input hardware interface", "");
|
||||
|
||||
integral_setting System::speed_regulation(config(), "system.speed_regulation",
|
||||
"Speed regulation setting\n"
|
||||
"0 = Disabled\n"
|
||||
"1 = Slowest\n"
|
||||
"2 = Slow\n"
|
||||
"3 = Normal\n"
|
||||
"4 = Fast\n"
|
||||
"5 = Fastest",
|
||||
integral_setting::decimal, 3);
|
||||
integral_setting System::emulation_speed(config(), "system.emulation_speed",
|
||||
"Relative speed of emulator compared to SNES hardware\n"
|
||||
"0 = 50%\n"
|
||||
"1 = 75%\n"
|
||||
"2 = 100%\n"
|
||||
"3 = 150%\n"
|
||||
"4 = 200%\n"
|
||||
"5 = Uncapped",
|
||||
integral_setting::decimal, 2);
|
||||
|
||||
integral_setting System::gamma_ramp(config(), "system.colorfilter.gamma_ramp",
|
||||
"Use precalculated TV-style gamma ramp", integral_setting::boolean, true);
|
||||
|
@ -117,7 +118,12 @@ struct Input {
|
|||
static string_setting load;
|
||||
static string_setting pause;
|
||||
static string_setting reset;
|
||||
static string_setting power;
|
||||
static string_setting power;
|
||||
static string_setting quit;
|
||||
static string_setting speed_decrease;
|
||||
static string_setting speed_increase;
|
||||
static string_setting frameskip_decrease;
|
||||
static string_setting frameskip_increase;
|
||||
static string_setting toggle_fullscreen;
|
||||
static string_setting toggle_menubar;
|
||||
static string_setting toggle_statusbar;
|
||||
|
@ -164,13 +170,18 @@ string_setting Input::Joypad2::r (config(), "input.joypad2.r", "", "l")
|
|||
string_setting Input::Joypad2::select(config(), "input.joypad2.select", "", "lbracket");
|
||||
string_setting Input::Joypad2::start (config(), "input.joypad2.start", "", "rbracket");
|
||||
|
||||
string_setting Input::GUI::load (config(), "input.gui.load", "", "none");
|
||||
string_setting Input::GUI::pause (config(), "input.gui.pause", "", "f12");
|
||||
string_setting Input::GUI::reset (config(), "input.gui.reset", "", "none");
|
||||
string_setting Input::GUI::power (config(), "input.gui.power", "", "none");
|
||||
string_setting Input::GUI::toggle_fullscreen(config(), "input.gui.toggle_fullscreen", "", "f11");
|
||||
string_setting Input::GUI::toggle_menubar (config(), "input.gui.toggle_menubar", "", "escape");
|
||||
string_setting Input::GUI::toggle_statusbar (config(), "input.gui.toggle_statusbar", "", "escape");
|
||||
string_setting Input::GUI::load (config(), "input.gui.load", "", "none");
|
||||
string_setting Input::GUI::pause (config(), "input.gui.pause", "", "f12");
|
||||
string_setting Input::GUI::reset (config(), "input.gui.reset", "", "none");
|
||||
string_setting Input::GUI::power (config(), "input.gui.power", "", "none");
|
||||
string_setting Input::GUI::quit (config(), "input.gui.quit", "", "none");
|
||||
string_setting Input::GUI::speed_decrease (config(), "input.gui.speed_decrease", "", "divide");
|
||||
string_setting Input::GUI::speed_increase (config(), "input.gui.speed_increase", "", "multiply");
|
||||
string_setting Input::GUI::frameskip_decrease(config(), "input.gui.frameskip_decrease", "", "subtract");
|
||||
string_setting Input::GUI::frameskip_increase(config(), "input.gui.frameskip_increase", "", "add");
|
||||
string_setting Input::GUI::toggle_fullscreen (config(), "input.gui.toggle_fullscreen", "", "f11");
|
||||
string_setting Input::GUI::toggle_menubar (config(), "input.gui.toggle_menubar", "", "escape");
|
||||
string_setting Input::GUI::toggle_statusbar (config(), "input.gui.toggle_statusbar", "", "escape");
|
||||
|
||||
struct Misc {
|
||||
static integral_setting opacity;
|
||||
|
@ -187,4 +198,11 @@ string_setting Misc::status_text(config(), "misc.status_text",
|
|||
"%f = executed frames per second\n"
|
||||
"%m = maximum frames per second"
|
||||
"", "%n : %f / %m");
|
||||
};
|
||||
|
||||
struct Advanced {
|
||||
static integral_setting enable;
|
||||
} advanced;
|
||||
|
||||
integral_setting Advanced::enable(config(), "advanced.enable", "Enable advanced, developer-oriented UI options", integral_setting::boolean, false);
|
||||
|
||||
} //namespace config
|
||||
|
|
100
src/ui/event.cpp
100
src/ui/event.cpp
|
@ -12,6 +12,19 @@ void keydown(uint16_t key) {
|
|||
}
|
||||
if(key == input_manager.gui.reset) reset();
|
||||
if(key == input_manager.gui.power) power();
|
||||
if(key == input_manager.gui.quit) quit();
|
||||
if(key == input_manager.gui.speed_decrease) {
|
||||
update_emulation_speed(config::system.emulation_speed - 1);
|
||||
}
|
||||
if(key == input_manager.gui.speed_increase) {
|
||||
update_emulation_speed(config::system.emulation_speed + 1);
|
||||
}
|
||||
if(key == input_manager.gui.frameskip_decrease) {
|
||||
update_frameskip(config::video.frameskip - 1);
|
||||
}
|
||||
if(key == input_manager.gui.frameskip_increase) {
|
||||
update_frameskip(config::video.frameskip + 1);
|
||||
}
|
||||
if(key == input_manager.gui.toggle_fullscreen) toggle_fullscreen();
|
||||
if(key == input_manager.gui.toggle_menubar) toggle_menubar();
|
||||
if(key == input_manager.gui.toggle_statusbar) toggle_statusbar();
|
||||
|
@ -99,25 +112,30 @@ void update_software_filter(uint software_filter) {
|
|||
update_video_settings();
|
||||
}
|
||||
|
||||
void update_speed_regulation(uint speed) {
|
||||
config::system.speed_regulation = speed <= 5 ? speed : 0;
|
||||
void update_frameskip(int speed) {
|
||||
config::video.frameskip = max(0, min(9, speed));
|
||||
window_main.sync();
|
||||
}
|
||||
|
||||
void update_emulation_speed(int speed) {
|
||||
config::system.emulation_speed = max(0, min(5, speed));
|
||||
|
||||
//adjust audio frequency to match selected speed setting
|
||||
if(audio.cap(Audio::Frequency)) {
|
||||
switch(config::system.speed_regulation) {
|
||||
case 0: audio.set(Audio::Frequency, 32000); break; //disabled
|
||||
case 1: audio.set(Audio::Frequency, 16000); break; //slowest (50%)
|
||||
case 2: audio.set(Audio::Frequency, 24000); break; //slow (75%)
|
||||
case 3: audio.set(Audio::Frequency, 32000); break; //normal (100%)
|
||||
case 4: audio.set(Audio::Frequency, 48000); break; //fast (150%)
|
||||
case 5: audio.set(Audio::Frequency, 64000); break; //fastest (200%)
|
||||
switch(config::system.emulation_speed) {
|
||||
case 0: audio.set(Audio::Frequency, 16000); break; //slowest (50%)
|
||||
case 1: audio.set(Audio::Frequency, 24000); break; //slow (75%)
|
||||
case 2: audio.set(Audio::Frequency, 32000); break; //normal (100%)
|
||||
case 3: audio.set(Audio::Frequency, 48000); break; //fast (150%)
|
||||
case 4: audio.set(Audio::Frequency, 64000); break; //fastest (200%)
|
||||
case 5: audio.set(Audio::Frequency, 32000); break; //disabled
|
||||
}
|
||||
}
|
||||
|
||||
//do not regulate speed when speed regulation is disabled
|
||||
if(audio.cap(Audio::Synchronize)) {
|
||||
audio.set(Audio::Synchronize, config::system.speed_regulation != 0);
|
||||
}
|
||||
audio.set(Audio::Synchronize, config::system.emulation_speed != 5);
|
||||
|
||||
window_main.sync();
|
||||
}
|
||||
|
||||
void update_status() {
|
||||
|
@ -129,13 +147,13 @@ void update_status() {
|
|||
ppu.status.frames_updated = false;
|
||||
|
||||
unsigned max_framerate = snes.region() == SNES::NTSC ? 60 : 50;
|
||||
switch(config::system.speed_regulation) {
|
||||
case 0: max_framerate = 0; break;
|
||||
case 1: max_framerate = unsigned(0.50 * max_framerate); break;
|
||||
case 2: max_framerate = unsigned(0.75 * max_framerate); break;
|
||||
case 3: break;
|
||||
case 4: max_framerate = unsigned(1.50 * max_framerate); break;
|
||||
case 5: max_framerate = unsigned(2.00 * max_framerate); break;
|
||||
switch(config::system.emulation_speed) {
|
||||
case 0: max_framerate = unsigned(0.50 * max_framerate); break;
|
||||
case 1: max_framerate = unsigned(0.75 * max_framerate); break;
|
||||
case 2: break;
|
||||
case 3: max_framerate = unsigned(1.50 * max_framerate); break;
|
||||
case 4: max_framerate = unsigned(2.00 * max_framerate); break;
|
||||
case 5: max_framerate = 0; break;
|
||||
}
|
||||
|
||||
string output = (const char*)config::misc.status_text;
|
||||
|
@ -212,7 +230,7 @@ void update_video_settings() {
|
|||
video.set(Video::Filter, video_settings.hardware_filter);
|
||||
|
||||
//update main window video mode checkbox settings
|
||||
window_main.update_menu_settings();
|
||||
window_main.sync();
|
||||
}
|
||||
|
||||
void update_opacity() {
|
||||
|
@ -243,7 +261,8 @@ void toggle_menubar() {
|
|||
}
|
||||
|
||||
void toggle_statusbar() {
|
||||
window_main.status.show(!window_main.status.visible());
|
||||
config::misc.status_enable = !window_main.status.visible();
|
||||
window_main.status.show(config::misc.status_enable);
|
||||
update_video_settings();
|
||||
}
|
||||
|
||||
|
@ -291,15 +310,20 @@ void load_cart_normal(const char *filename) {
|
|||
if(cartridge.loaded() == true) cartridge.unload();
|
||||
cartridge.load_cart_normal(filename);
|
||||
|
||||
//warn if unsupported hardware detected
|
||||
if(cartridge.info.superfx) alert("Warning: unsupported SuperFX chip detected.");
|
||||
if(cartridge.info.sa1) alert("Warning: unsupported SA-1 chip detected.");
|
||||
if(cartridge.info.spc7110) alert("Warning: unsupported SPC7110 chip detected.");
|
||||
if(cartridge.info.st011) alert("Warning: unsupported ST011 chip detected.");
|
||||
if(cartridge.info.st018) alert("Warning: unsupported ST018 chip detected.");
|
||||
//warn if unsupported hardware detected
|
||||
string message = translate["Unsupported $ chip detected."];
|
||||
const char *name;
|
||||
if(cartridge.info.superfx) { name = "SuperFX"; replace(message, "$", name); alert(message); }
|
||||
if(cartridge.info.sa1) { name = "SA-1"; replace(message, "$", name); alert(message); }
|
||||
if(cartridge.info.spc7110) { name = "SPC7110"; replace(message, "$", name); alert(message); }
|
||||
if(cartridge.info.st011) { name = "ST011"; replace(message, "$", name); alert(message); }
|
||||
if(cartridge.info.st018) { name = "ST018"; replace(message, "$", name); alert(message); }
|
||||
|
||||
app.pause = false;
|
||||
snes.power();
|
||||
window_main.menu_file_unload.enable();
|
||||
window_main.menu_file_reset.enable();
|
||||
window_main.menu_file_power.enable();
|
||||
window_cheat_editor.refresh();
|
||||
}
|
||||
|
||||
|
@ -311,6 +335,9 @@ void load_cart_bsx(const char *base, const char *slot) {
|
|||
|
||||
app.pause = false;
|
||||
snes.power();
|
||||
window_main.menu_file_unload.enable();
|
||||
window_main.menu_file_reset.enable();
|
||||
window_main.menu_file_power.enable();
|
||||
window_cheat_editor.refresh();
|
||||
}
|
||||
|
||||
|
@ -322,6 +349,9 @@ void load_cart_bsc(const char *base, const char *slot) {
|
|||
|
||||
app.pause = false;
|
||||
snes.power();
|
||||
window_main.menu_file_unload.enable();
|
||||
window_main.menu_file_reset.enable();
|
||||
window_main.menu_file_power.enable();
|
||||
window_cheat_editor.refresh();
|
||||
}
|
||||
|
||||
|
@ -333,6 +363,9 @@ void load_cart_st(const char *base, const char *slotA, const char *slotB) {
|
|||
|
||||
app.pause = false;
|
||||
snes.power();
|
||||
window_main.menu_file_unload.enable();
|
||||
window_main.menu_file_reset.enable();
|
||||
window_main.menu_file_power.enable();
|
||||
window_cheat_editor.refresh();
|
||||
}
|
||||
|
||||
|
@ -343,6 +376,9 @@ void unload_rom() {
|
|||
audio.clear();
|
||||
}
|
||||
event::update_status();
|
||||
window_main.menu_file_unload.disable();
|
||||
window_main.menu_file_reset.disable();
|
||||
window_main.menu_file_power.disable();
|
||||
window_cheat_editor.refresh();
|
||||
}
|
||||
|
||||
|
@ -360,4 +396,14 @@ void power() {
|
|||
}
|
||||
}
|
||||
|
||||
void quit() {
|
||||
app.term = true;
|
||||
window_about.hide();
|
||||
window_message.hide();
|
||||
window_settings.hide();
|
||||
window_bsxloader.hide();
|
||||
window_stloader.hide();
|
||||
window_main.hide();
|
||||
}
|
||||
|
||||
};
|
||||
|
|
|
@ -20,7 +20,8 @@ void update_region(uint);
|
|||
void update_hardware_filter(uint);
|
||||
void update_software_filter(uint);
|
||||
|
||||
void update_speed_regulation(uint);
|
||||
void update_frameskip(int);
|
||||
void update_emulation_speed(int);
|
||||
|
||||
void update_status();
|
||||
void update_video_settings();
|
||||
|
@ -37,6 +38,8 @@ void load_cart_bsc(const char*, const char*);
|
|||
void load_cart_st(const char*, const char*, const char*);
|
||||
void unload_rom();
|
||||
void reset();
|
||||
void power();
|
||||
void power();
|
||||
|
||||
void quit();
|
||||
|
||||
} //namespace event
|
||||
|
|
|
@ -12,6 +12,11 @@ public:
|
|||
uint16_t pause;
|
||||
uint16_t reset;
|
||||
uint16_t power;
|
||||
uint16_t quit;
|
||||
uint16_t speed_decrease;
|
||||
uint16_t speed_increase;
|
||||
uint16_t frameskip_decrease;
|
||||
uint16_t frameskip_increase;
|
||||
uint16_t toggle_fullscreen;
|
||||
uint16_t toggle_menubar;
|
||||
uint16_t toggle_statusbar;
|
||||
|
@ -84,13 +89,18 @@ void InputManager::bind() {
|
|||
joypad2.l.state = joypad2.r.state = joypad2.select.state = joypad2.start.state =
|
||||
false;
|
||||
|
||||
gui.load = input_find(config::input.gui.load);
|
||||
gui.pause = input_find(config::input.gui.pause);
|
||||
gui.reset = input_find(config::input.gui.reset);
|
||||
gui.power = input_find(config::input.gui.power);
|
||||
gui.toggle_fullscreen = input_find(config::input.gui.toggle_fullscreen);
|
||||
gui.toggle_menubar = input_find(config::input.gui.toggle_menubar);
|
||||
gui.toggle_statusbar = input_find(config::input.gui.toggle_statusbar);
|
||||
gui.load = input_find(config::input.gui.load);
|
||||
gui.pause = input_find(config::input.gui.pause);
|
||||
gui.reset = input_find(config::input.gui.reset);
|
||||
gui.power = input_find(config::input.gui.power);
|
||||
gui.quit = input_find(config::input.gui.quit);
|
||||
gui.speed_decrease = input_find(config::input.gui.speed_decrease);
|
||||
gui.speed_increase = input_find(config::input.gui.speed_increase);
|
||||
gui.frameskip_decrease = input_find(config::input.gui.frameskip_decrease);
|
||||
gui.frameskip_increase = input_find(config::input.gui.frameskip_increase);
|
||||
gui.toggle_fullscreen = input_find(config::input.gui.toggle_fullscreen);
|
||||
gui.toggle_menubar = input_find(config::input.gui.toggle_menubar);
|
||||
gui.toggle_statusbar = input_find(config::input.gui.toggle_statusbar);
|
||||
}
|
||||
|
||||
void InputManager::poll() {
|
||||
|
|
|
@ -51,33 +51,33 @@ uintptr_t BSXLoaderWindow::cancel_tick(Event) {
|
|||
}
|
||||
|
||||
void BSXLoaderWindow::setup() {
|
||||
create(Window::AutoCenter, 640, 150, "Load BS-X Cartridge");
|
||||
create(Window::AutoCenter, 565, 131, translate["Load BS-X Cartridge"]);
|
||||
set_icon(48, 48, (uint32_t*)resource::icon48);
|
||||
|
||||
lbase.create(0, 630, 20, "Base cartridge:");
|
||||
tbase.create(0, 420, 30);
|
||||
bbase.create(0, 100, 30, "Browse ...");
|
||||
cbase.create(0, 100, 30, "Clear");
|
||||
lbase.create(0, 555, 18, translate["Base cartridge:"]);
|
||||
tbase.create(0, 345, 25);
|
||||
bbase.create(0, 100, 25, translate["Browse ..."]);
|
||||
cbase.create(0, 100, 25, translate["Clear"]);
|
||||
|
||||
lslot.create(0, 630, 20, "Slot cartridge:");
|
||||
tslot.create(0, 420, 30);
|
||||
bslot.create(0, 100, 30, "Browse ...");
|
||||
cslot.create(0, 100, 30, "Clear");
|
||||
lslot.create(0, 555, 18, translate["Slot cartridge:"]);
|
||||
tslot.create(0, 345, 25);
|
||||
bslot.create(0, 100, 25, translate["Browse ..."]);
|
||||
cslot.create(0, 100, 25, translate["Clear"]);
|
||||
|
||||
load.create (0, 312, 30, "Load");
|
||||
cancel.create(0, 312, 30, "Cancel");
|
||||
load.create (0, 275, 25, translate["Load"]);
|
||||
cancel.create(0, 275, 25, translate["Cancel"]);
|
||||
|
||||
uint y = 5;
|
||||
attach(lbase, 5, y); y += 20;
|
||||
unsigned y = 5;
|
||||
attach(lbase, 5, y); y += 18;
|
||||
attach(tbase, 5, y);
|
||||
attach(bbase, 430, y);
|
||||
attach(cbase, 535, y); y += 30 + 5;
|
||||
attach(lslot, 5, y); y += 20;
|
||||
attach(bbase, 355, y);
|
||||
attach(cbase, 460, y); y += 25 + 5;
|
||||
attach(lslot, 5, y); y += 18;
|
||||
attach(tslot, 5, y);
|
||||
attach(bslot, 430, y);
|
||||
attach(cslot, 535, y); y += 30 + 5;
|
||||
attach(bslot, 355, y);
|
||||
attach(cslot, 460, y); y += 25 + 5;
|
||||
attach(load, 5, y);
|
||||
attach(cancel, 323, y); y += 30 + 5;
|
||||
attach(cancel, 285, y); y += 25 + 5;
|
||||
|
||||
on_close = bind(&BSXLoaderWindow::close, this);
|
||||
bbase.on_tick = bind(&BSXLoaderWindow::bbase_tick, this);
|
||||
|
|
|
@ -61,42 +61,42 @@ uintptr_t STLoaderWindow::cancel_tick(Event) {
|
|||
}
|
||||
|
||||
void STLoaderWindow::setup() {
|
||||
create(Window::AutoCenter, 640, 205, "Load Sufami Turbo Cartridge");
|
||||
create(Window::AutoCenter, 565, 179, translate["Load Sufami Turbo Cartridge"]);
|
||||
set_icon(48, 48, (uint32_t*)resource::icon48);
|
||||
|
||||
lbase.create(0, 630, 20, "Base cartridge:");
|
||||
tbase.create(0, 420, 30);
|
||||
bbase.create(0, 100, 30, "Browse ...");
|
||||
cbase.create(0, 100, 30, "Clear");
|
||||
lbase.create(0, 555, 18, translate["Base cartridge:"]);
|
||||
tbase.create(0, 345, 25);
|
||||
bbase.create(0, 100, 25, translate["Browse ..."]);
|
||||
cbase.create(0, 100, 25, translate["Clear"]);
|
||||
|
||||
lslotA.create(0, 630, 20, "Slot A cartridge:");
|
||||
tslotA.create(0, 420, 30);
|
||||
bslotA.create(0, 100, 30, "Browse ...");
|
||||
cslotA.create(0, 100, 30, "Clear");
|
||||
lslotA.create(0, 555, 18, translate["Slot A cartridge:"]);
|
||||
tslotA.create(0, 345, 25);
|
||||
bslotA.create(0, 100, 25, translate["Browse ..."]);
|
||||
cslotA.create(0, 100, 25, translate["Clear"]);
|
||||
|
||||
lslotB.create(0, 630, 20, "Slot B cartridge:");
|
||||
tslotB.create(0, 420, 30);
|
||||
bslotB.create(0, 100, 30, "Browse ...");
|
||||
cslotB.create(0, 100, 30, "Clear");
|
||||
lslotB.create(0, 555, 18, translate["Slot B cartridge:"]);
|
||||
tslotB.create(0, 345, 25);
|
||||
bslotB.create(0, 100, 25, translate["Browse ..."]);
|
||||
cslotB.create(0, 100, 25, translate["Clear"]);
|
||||
|
||||
load.create (0, 312, 30, "Load");
|
||||
cancel.create(0, 312, 30, "Cancel");
|
||||
load.create (0, 275, 25, translate["Load"]);
|
||||
cancel.create(0, 275, 25, translate["Cancel"]);
|
||||
|
||||
uint y = 5;
|
||||
attach(lbase, 5, y); y += 20;
|
||||
unsigned y = 5;
|
||||
attach(lbase, 5, y); y += 18;
|
||||
attach(tbase, 5, y);
|
||||
attach(bbase, 430, y);
|
||||
attach(cbase, 535, y); y += 30 + 5;
|
||||
attach(lslotA, 5, y); y += 20;
|
||||
attach(bbase, 355, y);
|
||||
attach(cbase, 460, y); y += 25 + 5;
|
||||
attach(lslotA, 5, y); y += 18;
|
||||
attach(tslotA, 5, y);
|
||||
attach(bslotA, 430, y);
|
||||
attach(cslotA, 535, y); y += 30 + 5;
|
||||
attach(lslotB, 5, y); y += 20;
|
||||
attach(bslotA, 355, y);
|
||||
attach(cslotA, 460, y); y += 25 + 5;
|
||||
attach(lslotB, 5, y); y += 18;
|
||||
attach(tslotB, 5, y);
|
||||
attach(bslotB, 430, y);
|
||||
attach(cslotB, 535, y); y += 30 + 5;
|
||||
attach(bslotB, 355, y);
|
||||
attach(cslotB, 460, y); y += 25 + 5;
|
||||
attach(load, 5, y);
|
||||
attach(cancel, 323, y); y += 30 + 5;
|
||||
attach(cancel, 285, y); y += 25 + 5;
|
||||
|
||||
on_close = bind(&STLoaderWindow::close, this);
|
||||
bbase.on_tick = bind(&STLoaderWindow::bbase_tick, this);
|
||||
|
|
|
@ -65,32 +65,57 @@ void dprintf(uint source, const char *s, ...) {
|
|||
fprintf(stdout, "[%d]: %s\r\n", source, str);
|
||||
}
|
||||
|
||||
void set_config_filename() {
|
||||
userpath(config::filename);
|
||||
strcat(config::filename, "/.bsnes");
|
||||
mkdir(config::filename); //always make directory in case it does not exist, fail silently if it does
|
||||
strcat(config::filename, "/bsnes.cfg");
|
||||
}
|
||||
void get_paths(const char *image) {
|
||||
char temp[PATH_MAX] = "";
|
||||
realpath(image, temp);
|
||||
|
||||
void get_base_path(const char *image) {
|
||||
char full_name[PATH_MAX] = "";
|
||||
realpath(image, full_name);
|
||||
|
||||
string t = full_name;
|
||||
if(strlen(t) != 0) {
|
||||
if(strlen(temp) != 0) {
|
||||
for(int i = strlen(temp) - 1; i >= 0; i--) {
|
||||
if(temp[i] == '\\') temp[i] = '/';
|
||||
}
|
||||
//remove program name
|
||||
//TODO: rewrite this to be cleaner ...
|
||||
replace(t, "\\", "/");
|
||||
for(int i = strlen(t) - 1; i >= 0; i--) {
|
||||
if(t()[i] == '/' || t()[i] == '\\') {
|
||||
t()[i] = 0;
|
||||
for(int i = strlen(temp) - 1; i >= 0; i--) {
|
||||
if(temp[i] == '/') {
|
||||
temp[i] = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(strend(t, "/") == false) strcat(t, "/");
|
||||
config::path.base = t;
|
||||
if(strend(temp, "/") == false) strcat(temp, "/");
|
||||
config::path.base = temp;
|
||||
|
||||
userpath(temp);
|
||||
if(strend(temp, "/") == false) strcat(temp, "/");
|
||||
config::path.user = temp;
|
||||
}
|
||||
|
||||
void set_config_filenames() {
|
||||
char filename[PATH_MAX];
|
||||
|
||||
//locate bsnes.cfg
|
||||
strcpy(filename, config::path.base);
|
||||
strcat(filename, "bsnes.cfg");
|
||||
if(!fexists(filename)) {
|
||||
strcpy(filename, config::path.user);
|
||||
strcat(filename, ".bsnes");
|
||||
mkdir(filename);
|
||||
strcat(filename, "/bsnes.cfg");
|
||||
}
|
||||
strcpy(config::bsnes_cfg, filename);
|
||||
fprintf(stdout, "Config file: %s\n", config::bsnes_cfg);
|
||||
|
||||
//locate locale.cfg
|
||||
strcpy(filename, config::path.base);
|
||||
strcat(filename, "locale.cfg");
|
||||
if(!fexists(filename)) {
|
||||
strcpy(filename, config::path.user);
|
||||
strcat(filename, ".bsnes");
|
||||
mkdir(filename);
|
||||
strcat(filename, "/locale.cfg");
|
||||
}
|
||||
strcpy(config::locale_cfg, filename);
|
||||
fprintf(stdout, "Locale file: %s\n", config::locale_cfg);
|
||||
}
|
||||
|
||||
void run() {
|
||||
|
@ -128,29 +153,34 @@ int main(int argc, char *argv[]) {
|
|||
#endif
|
||||
/*
|
||||
int main(int argc, char *argv[]) { */
|
||||
set_config_filename();
|
||||
get_base_path(argv[0]);
|
||||
get_paths(argv[0]);
|
||||
set_config_filenames();
|
||||
|
||||
config::config().load(config::filename);
|
||||
if(fexists(config::filename) == false) {
|
||||
config::config().load(config::bsnes_cfg);
|
||||
if(fexists(config::bsnes_cfg) == false) {
|
||||
//in case program crashes on first run, save config file
|
||||
//settings, so that they can be modified by hand ...
|
||||
config::config().save(config::filename);
|
||||
config::config().save(config::bsnes_cfg);
|
||||
}
|
||||
translate.import(config::locale_cfg);
|
||||
|
||||
hiro().init();
|
||||
ui_init();
|
||||
snes.init();
|
||||
|
||||
if(argc >= 2) {
|
||||
if(argc >= 2 && fexists(argv[1])) {
|
||||
cartridge.load_cart_normal(argv[1]);
|
||||
snes.power();
|
||||
window_main.menu_file_unload.enable();
|
||||
window_main.menu_file_reset.enable();
|
||||
window_main.menu_file_power.enable();
|
||||
}
|
||||
|
||||
while(app.term == false) run();
|
||||
|
||||
event::unload_rom();
|
||||
|
||||
config::config().save(config::filename);
|
||||
config::config().save(config::bsnes_cfg);
|
||||
snes.term();
|
||||
ui_term();
|
||||
hiro().term();
|
||||
|
|
|
@ -7,7 +7,9 @@ uintptr_t AdvancedWindow::list_change(Event) {
|
|||
unsigned i = lookup[pos];
|
||||
string default_;
|
||||
config::config().list[i]->get_default(default_);
|
||||
desc.set_text(string() << "(default = " << default_ << ")\n" << config::config().list[i]->description);
|
||||
desc.set_text(string()
|
||||
<< "(" << translate["Default"] << " = " << default_ << ")\n"
|
||||
<< config::config().list[i]->description);
|
||||
string value_;
|
||||
config::config().list[i]->get(value_);
|
||||
edit_val.set_text(value_);
|
||||
|
@ -39,7 +41,7 @@ void AdvancedWindow::update(uint pos, const char *data) {
|
|||
<< config::config().list[i]->name
|
||||
<< (value_ == default_ ? "" : " (*)")
|
||||
<< "\t"
|
||||
<< (config::config().list[i]->type == setting::string_type ? "string" : "integral")
|
||||
<< (config::config().list[i]->type == setting::string_type ? translate["string"] : translate["integer"])
|
||||
<< "\t"
|
||||
<< value_
|
||||
);
|
||||
|
@ -58,7 +60,7 @@ void AdvancedWindow::load() {
|
|||
if(strbegin(name, "snes.controller_port_")) continue;
|
||||
if(strpos(name, "colorfilter.") >= 0) continue;
|
||||
if(name == "misc.status_enable") continue;
|
||||
if(name == "system.regulate_speed") continue;
|
||||
if(name == "system.emulation_speed") continue;
|
||||
if(strbegin(name, "video.windowed.") && name != "video.windowed.synchronize") continue;
|
||||
if(strbegin(name, "video.fullscreen.") && name != "video.fullscreen.synchronize") continue;
|
||||
if(name == "audio.mute") continue;
|
||||
|
@ -73,7 +75,7 @@ void AdvancedWindow::load() {
|
|||
<< name
|
||||
<< (value_ == default_ ? "" : " (*)")
|
||||
<< "\t"
|
||||
<< (config::config().list[i]->type == setting::string_type ? "string" : "integral")
|
||||
<< (config::config().list[i]->type == setting::string_type ? translate["string"] : translate["integer"])
|
||||
<< "\t"
|
||||
<< value_
|
||||
);
|
||||
|
@ -84,21 +86,19 @@ void AdvancedWindow::load() {
|
|||
void AdvancedWindow::setup() {
|
||||
create(0, 475, 355);
|
||||
|
||||
list.create(Listbox::Header | Listbox::VerticalScrollAlways, 475, 235, "Name\tType\tValue");
|
||||
desc.create(Editbox::Multiline | Editbox::VerticalScrollAlways | Editbox::Readonly, 475, 80,
|
||||
"Note: modification of certain variables will not take effect until\n"
|
||||
"bsnes is restarted. (*) = modified"
|
||||
);
|
||||
edit_val.create(0, 265, 30, "<current value>");
|
||||
set_val.create (0, 100, 30, "Set");
|
||||
set_def.create (0, 100, 30, "Default");
|
||||
list.create(Listbox::Header | Listbox::VerticalScrollAlways, 475, 240,
|
||||
string() << translate["Name"] << "\t" << translate["Type"] << "\t" << translate["Value"]);
|
||||
desc.create(Editbox::Multiline | Editbox::VerticalScrollAlways | Editbox::Readonly, 475, 80, translate["<description>"]);
|
||||
edit_val.create(0, 265, 25, translate["<current value>"]);
|
||||
set_val.create (0, 100, 25, translate["Set"]);
|
||||
set_def.create (0, 100, 25, translate["Default"]);
|
||||
|
||||
unsigned y = 0;
|
||||
attach(list, 0, y); y += 235 + 5;
|
||||
attach(list, 0, y); y += 240 + 5;
|
||||
attach(desc, 0, y); y += 80 + 5;
|
||||
attach(edit_val, 0, y);
|
||||
attach(set_val, 270, y);
|
||||
attach(set_def, 375, y); y += 30 + 5;
|
||||
attach(set_def, 375, y); y += 25 + 5;
|
||||
|
||||
load();
|
||||
list.autosize_columns();
|
||||
|
|
|
@ -1,20 +1,21 @@
|
|||
void CheatEditorWindow::setup() {
|
||||
create(0, 475, 355);
|
||||
|
||||
list.create(Listbox::Header | Listbox::VerticalScrollAlways, 475, 285, "Status\tCode\tDescription");
|
||||
add_code.create (0, 155, 30, "Add Code");
|
||||
toggle_code.create(0, 155, 30, "Toggle Status");
|
||||
delete_code.create(0, 155, 30, "Delete Code");
|
||||
code.create(0, 155, 30, "<code>");
|
||||
desc.create(0, 315, 30, "<description>");
|
||||
list.create(Listbox::Header | Listbox::VerticalScrollAlways, 475, 295,
|
||||
string() << translate["Status"] << "\t" << translate["Code"] << "\t" << translate["Description"]);
|
||||
add_code.create (0, 155, 25, translate["Add Code"]);
|
||||
toggle_code.create(0, 155, 25, translate["Toggle Status"]);
|
||||
delete_code.create(0, 155, 25, translate["Delete Code"]);
|
||||
code.create(0, 155, 25, translate["<code>"]);
|
||||
desc.create(0, 315, 25, translate["<description>"]);
|
||||
|
||||
unsigned y = 0;
|
||||
attach(list, 0, y); y += 285 + 5;
|
||||
attach(list, 0, y); y += 295 + 5;
|
||||
attach(add_code, 0, y);
|
||||
attach(toggle_code, 160, y);
|
||||
attach(delete_code, 320, y); y += 30 + 5;
|
||||
attach(delete_code, 320, y); y += 25 + 5;
|
||||
attach(code, 0, y);
|
||||
attach(desc, 160, y); y += 30 + 5;
|
||||
attach(desc, 160, y); y += 25 + 5;
|
||||
|
||||
list.on_activate = bind(&CheatEditorWindow::toggle_event, this);
|
||||
add_code.on_tick = bind(&CheatEditorWindow::add_tick, this);
|
||||
|
@ -27,14 +28,14 @@ void CheatEditorWindow::setup() {
|
|||
void CheatEditorWindow::refresh() {
|
||||
list.reset();
|
||||
|
||||
for(uint i = 0; i < cheat.count(); i++) {
|
||||
for(unsigned i = 0; i < cheat.count(); i++) {
|
||||
bool enabled;
|
||||
uint32 addr;
|
||||
uint8 data;
|
||||
char s_code[256], s_desc[256];
|
||||
cheat.get(i, enabled, addr, data, s_code, s_desc);
|
||||
list.add_item(string()
|
||||
<< (enabled ? "Enabled" : "Disabled") << "\t"
|
||||
<< (enabled ? translate["Enabled"] : translate["Disabled"]) << "\t"
|
||||
<< s_code << "\t"
|
||||
<< s_desc);
|
||||
}
|
||||
|
@ -60,7 +61,7 @@ uintptr_t CheatEditorWindow::toggle_event(Event) {
|
|||
char s_code[256], s_desc[256];
|
||||
cheat.get(index, enabled, addr, data, s_code, s_desc);
|
||||
list.set_item(index, string()
|
||||
<< (enabled ? "Enabled" : "Disabled") << "\t"
|
||||
<< (enabled ? translate["Enabled"] : translate["Disabled"]) << "\t"
|
||||
<< s_code << "\t"
|
||||
<< s_desc);
|
||||
}
|
||||
|
|
|
@ -3,29 +3,29 @@
|
|||
void InputConfigWindow::setup() {
|
||||
create(0, 475, 355);
|
||||
|
||||
capture_mode.create(0, 475, 15, "When emulation window does not have focus:");
|
||||
capture_mode.create(0, 475, 18, translate["When emulation window does not have focus:"]);
|
||||
RadioboxGroup group;
|
||||
group.add(&capture_always);
|
||||
group.add(&capture_focus);
|
||||
group.add(&capture_pause);
|
||||
capture_always.create(group, 0, 155, 20, "Allow input");
|
||||
capture_focus.create(group, 0, 155, 20, "Ignore input");
|
||||
capture_pause.create(group, 0, 155, 20, "Pause emulation");
|
||||
capture_always.create(group, 0, 155, 18, translate["Allow input"]);
|
||||
capture_focus.create (group, 0, 155, 18, translate["Ignore input"]);
|
||||
capture_pause.create (group, 0, 155, 18, translate["Pause emulation"]);
|
||||
|
||||
list.create(Listbox::Header | Listbox::VerticalScrollAlways, 475, 275, "Name\tValue");
|
||||
setkey.create(0, 235, 30, "Assign Key");
|
||||
list.create(Listbox::Header | Listbox::VerticalScrollAlways, 475, 284, string() << translate["Name"] << "\t" << translate["Value"]);
|
||||
setkey.create(0, 235, 25, translate["Assign Key"]);
|
||||
setkey.disable();
|
||||
clrkey.create(0, 235, 30, "Unassign Key");
|
||||
clrkey.create(0, 235, 25, translate["Unassign Key"]);
|
||||
clrkey.disable();
|
||||
|
||||
unsigned y = 0;
|
||||
attach(capture_mode, 0, y); y += 15 + 5;
|
||||
attach(capture_mode, 0, y); y += 18;
|
||||
attach(capture_always, 0, y);
|
||||
attach(capture_focus, 160, y);
|
||||
attach(capture_pause, 320, y); y += 20 + 5;
|
||||
attach(list, 0, y); y += 275 + 5;
|
||||
attach(capture_pause, 320, y); y += 18 + 5;
|
||||
attach(list, 0, y); y += 284 + 5;
|
||||
attach(setkey, 0, y);
|
||||
attach(clrkey, 240, y); y += 30 + 5;
|
||||
attach(clrkey, 240, y); y += 25 + 5;
|
||||
|
||||
capture_always.on_tick = bind(&InputConfigWindow::capture_change, this);
|
||||
capture_focus.on_tick = bind(&InputConfigWindow::capture_change, this);
|
||||
|
@ -39,14 +39,16 @@ void InputConfigWindow::setup() {
|
|||
else if(config::input.capture_mode == 2) capture_pause.check();
|
||||
else config::input.capture_mode = 0; //capture_always
|
||||
|
||||
for(unsigned i = 0; i < list_size; i++) list.add_item("???\t???");
|
||||
for(unsigned i = 0; i < inputcount; i++) list.add_item("???\t???");
|
||||
refresh_list();
|
||||
window_input_capture.setup();
|
||||
}
|
||||
|
||||
void InputConfigWindow::refresh_list() {
|
||||
for(unsigned i = 0; i < list_size; i++) {
|
||||
list.set_item(i, string() << list_index[i] << "\t" << input_find(get_value(i)));
|
||||
for(unsigned i = 0; i < inputcount; i++) {
|
||||
const char *name;
|
||||
acquire(i, name);
|
||||
list.set_item(i, string() << name << "\t" << input_find(get_value(i)));
|
||||
}
|
||||
list.autosize_columns();
|
||||
}
|
||||
|
@ -67,9 +69,13 @@ uintptr_t InputConfigWindow::list_change(Event) {
|
|||
|
||||
uintptr_t InputConfigWindow::set_tick(Event) {
|
||||
int pos = list.get_selection();
|
||||
if(pos < 0) return true;
|
||||
if(pos < 0 || pos >= inputcount) return true;
|
||||
window_input_capture.index = pos;
|
||||
window_input_capture.label.set_text(string() << "Press a key to assign to " << list_index[pos] << " ...");
|
||||
string message = translate["Press a key to assign to $ ..."];
|
||||
const char *name;
|
||||
acquire(pos, name);
|
||||
replace(message, "$", name);
|
||||
window_input_capture.label.set_text(message);
|
||||
window_input_capture.canvas.show(pos < 24); //only show joypad graphic if setting joypad 1/2 button
|
||||
window_input_capture.show();
|
||||
return true;
|
||||
|
@ -106,12 +112,12 @@ uintptr_t InputCaptureWindow::close(Event) {
|
|||
}
|
||||
|
||||
void InputCaptureWindow::setup() {
|
||||
create(Window::AutoCenter, 382, 208, "bsnes Key Capture");
|
||||
label.create(0, 340, 20);
|
||||
create(Window::AutoCenter, 382, 206, translate["bsnes Key Capture"]);
|
||||
label.create(0, 340, 18);
|
||||
canvas.create(0, 372, 178);
|
||||
memcpy(canvas.buffer(), resource::controller, 372 * 178 * 4);
|
||||
attach(label, 5, 5);
|
||||
attach(canvas, 5, 25);
|
||||
attach(canvas, 5, 23);
|
||||
on_close = bind(&InputCaptureWindow::close, this);
|
||||
}
|
||||
|
||||
|
@ -123,120 +129,62 @@ InputCaptureWindow::InputCaptureWindow() {
|
|||
|
||||
/* Misc */
|
||||
|
||||
const int InputConfigWindow::list_size = 31;
|
||||
|
||||
const char InputConfigWindow::list_index[][64] = {
|
||||
"Joypad 1 Up",
|
||||
"Joypad 1 Down",
|
||||
"Joypad 1 Left",
|
||||
"Joypad 1 Right",
|
||||
"Joypad 1 A",
|
||||
"Joypad 1 B",
|
||||
"Joypad 1 X",
|
||||
"Joypad 1 Y",
|
||||
"Joypad 1 L",
|
||||
"Joypad 1 R",
|
||||
"Joypad 1 Select",
|
||||
"Joypad 1 Start",
|
||||
|
||||
"Joypad 2 Up",
|
||||
"Joypad 2 Down",
|
||||
"Joypad 2 Left",
|
||||
"Joypad 2 Right",
|
||||
"Joypad 2 A",
|
||||
"Joypad 2 B",
|
||||
"Joypad 2 X",
|
||||
"Joypad 2 Y",
|
||||
"Joypad 2 L",
|
||||
"Joypad 2 R",
|
||||
"Joypad 2 Select",
|
||||
"Joypad 2 Start",
|
||||
|
||||
"Load Cartridge",
|
||||
"Pause Emulation",
|
||||
"Reset System",
|
||||
"Power Cycle System",
|
||||
"Toggle Fullscreen",
|
||||
"Toggle Menubar",
|
||||
"Toggle Statusbar",
|
||||
};
|
||||
|
||||
uint InputConfigWindow::get_value(uint index) {
|
||||
string_setting& InputConfigWindow::acquire(unsigned index, const char *&name) {
|
||||
switch(index) {
|
||||
case 0: return input_find(config::input.joypad1.up);
|
||||
case 1: return input_find(config::input.joypad1.down);
|
||||
case 2: return input_find(config::input.joypad1.left);
|
||||
case 3: return input_find(config::input.joypad1.right);
|
||||
case 4: return input_find(config::input.joypad1.a);
|
||||
case 5: return input_find(config::input.joypad1.b);
|
||||
case 6: return input_find(config::input.joypad1.x);
|
||||
case 7: return input_find(config::input.joypad1.y);
|
||||
case 8: return input_find(config::input.joypad1.l);
|
||||
case 9: return input_find(config::input.joypad1.r);
|
||||
case 10: return input_find(config::input.joypad1.select);
|
||||
case 11: return input_find(config::input.joypad1.start);
|
||||
case 0: name = translate["Joypad 1 Up"]; return config::input.joypad1.up;
|
||||
case 1: name = translate["Joypad 1 Down"]; return config::input.joypad1.down;
|
||||
case 2: name = translate["Joypad 1 Left"]; return config::input.joypad1.left;
|
||||
case 3: name = translate["Joypad 1 Right"]; return config::input.joypad1.right;
|
||||
case 4: name = translate["Joypad 1 A"]; return config::input.joypad1.a;
|
||||
case 5: name = translate["Joypad 1 B"]; return config::input.joypad1.b;
|
||||
case 6: name = translate["Joypad 1 X"]; return config::input.joypad1.x;
|
||||
case 7: name = translate["Joypad 1 Y"]; return config::input.joypad1.y;
|
||||
case 8: name = translate["Joypad 1 L"]; return config::input.joypad1.l;
|
||||
case 9: name = translate["Joypad 1 R"]; return config::input.joypad1.r;
|
||||
case 10: name = translate["Joypad 1 Select"]; return config::input.joypad1.select;
|
||||
case 11: name = translate["Joypad 1 Start"]; return config::input.joypad1.start;
|
||||
|
||||
case 12: return input_find(config::input.joypad2.up);
|
||||
case 13: return input_find(config::input.joypad2.down);
|
||||
case 14: return input_find(config::input.joypad2.left);
|
||||
case 15: return input_find(config::input.joypad2.right);
|
||||
case 16: return input_find(config::input.joypad2.a);
|
||||
case 17: return input_find(config::input.joypad2.b);
|
||||
case 18: return input_find(config::input.joypad2.x);
|
||||
case 19: return input_find(config::input.joypad2.y);
|
||||
case 20: return input_find(config::input.joypad2.l);
|
||||
case 21: return input_find(config::input.joypad2.r);
|
||||
case 22: return input_find(config::input.joypad2.select);
|
||||
case 23: return input_find(config::input.joypad2.start);
|
||||
case 12: name = translate["Joypad 2 Up"]; return config::input.joypad2.up;
|
||||
case 13: name = translate["Joypad 2 Down"]; return config::input.joypad2.down;
|
||||
case 14: name = translate["Joypad 2 Left"]; return config::input.joypad2.left;
|
||||
case 15: name = translate["Joypad 2 Right"]; return config::input.joypad2.right;
|
||||
case 16: name = translate["Joypad 2 A"]; return config::input.joypad2.a;
|
||||
case 17: name = translate["Joypad 2 B"]; return config::input.joypad2.b;
|
||||
case 18: name = translate["Joypad 2 X"]; return config::input.joypad2.x;
|
||||
case 19: name = translate["Joypad 2 Y"]; return config::input.joypad2.y;
|
||||
case 20: name = translate["Joypad 2 L"]; return config::input.joypad2.l;
|
||||
case 21: name = translate["Joypad 2 R"]; return config::input.joypad2.r;
|
||||
case 22: name = translate["Joypad 2 Select"]; return config::input.joypad2.select;
|
||||
case 23: name = translate["Joypad 2 Start"]; return config::input.joypad2.start;
|
||||
|
||||
case 24: return input_find(config::input.gui.load);
|
||||
case 25: return input_find(config::input.gui.pause);
|
||||
case 26: return input_find(config::input.gui.reset);
|
||||
case 27: return input_find(config::input.gui.power);
|
||||
case 28: return input_find(config::input.gui.toggle_fullscreen);
|
||||
case 29: return input_find(config::input.gui.toggle_menubar);
|
||||
case 30: return input_find(config::input.gui.toggle_statusbar);
|
||||
case 24: name = translate["Load Cartridge"]; return config::input.gui.load;
|
||||
case 25: name = translate["Pause Emulation"]; return config::input.gui.pause;
|
||||
case 26: name = translate["Reset System"]; return config::input.gui.reset;
|
||||
case 27: name = translate["Power Cycle System"]; return config::input.gui.power;
|
||||
case 28: name = translate["Exit Emulator"]; return config::input.gui.quit;
|
||||
case 29: name = translate["Emulation Speed Decrease"]; return config::input.gui.speed_decrease;
|
||||
case 30: name = translate["Emulation Speed Increase"]; return config::input.gui.speed_increase;
|
||||
case 31: name = translate["Frameskip Decrease"]; return config::input.gui.frameskip_decrease;
|
||||
case 32: name = translate["Frameskip Increase"]; return config::input.gui.frameskip_increase;
|
||||
case 33: name = translate["Toggle Fullscreen"]; return config::input.gui.toggle_fullscreen;
|
||||
case 34: name = translate["Toggle Menubar"]; return config::input.gui.toggle_menubar;
|
||||
case 35: name = translate["Toggle Statusbar"]; return config::input.gui.toggle_statusbar;
|
||||
}
|
||||
|
||||
return keyboard::none;
|
||||
name = "";
|
||||
static string_setting notfound("", "", "");
|
||||
return notfound;
|
||||
}
|
||||
|
||||
const int InputConfigWindow::inputcount = 36;
|
||||
|
||||
uint InputConfigWindow::get_value(uint index) {
|
||||
const char *name;
|
||||
return input_find(acquire(index, name));
|
||||
}
|
||||
|
||||
void InputConfigWindow::set_value(uint index, uint16 value) {
|
||||
switch(index) {
|
||||
case 0: config::input.joypad1.up = input_find(value); break;
|
||||
case 1: config::input.joypad1.down = input_find(value); break;
|
||||
case 2: config::input.joypad1.left = input_find(value); break;
|
||||
case 3: config::input.joypad1.right = input_find(value); break;
|
||||
case 4: config::input.joypad1.a = input_find(value); break;
|
||||
case 5: config::input.joypad1.b = input_find(value); break;
|
||||
case 6: config::input.joypad1.x = input_find(value); break;
|
||||
case 7: config::input.joypad1.y = input_find(value); break;
|
||||
case 8: config::input.joypad1.l = input_find(value); break;
|
||||
case 9: config::input.joypad1.r = input_find(value); break;
|
||||
case 10: config::input.joypad1.select = input_find(value); break;
|
||||
case 11: config::input.joypad1.start = input_find(value); break;
|
||||
|
||||
case 12: config::input.joypad2.up = input_find(value); break;
|
||||
case 13: config::input.joypad2.down = input_find(value); break;
|
||||
case 14: config::input.joypad2.left = input_find(value); break;
|
||||
case 15: config::input.joypad2.right = input_find(value); break;
|
||||
case 16: config::input.joypad2.a = input_find(value); break;
|
||||
case 17: config::input.joypad2.b = input_find(value); break;
|
||||
case 18: config::input.joypad2.x = input_find(value); break;
|
||||
case 19: config::input.joypad2.y = input_find(value); break;
|
||||
case 20: config::input.joypad2.l = input_find(value); break;
|
||||
case 21: config::input.joypad2.r = input_find(value); break;
|
||||
case 22: config::input.joypad2.select = input_find(value); break;
|
||||
case 23: config::input.joypad2.start = input_find(value); break;
|
||||
|
||||
case 24: config::input.gui.load = input_find(value); break;
|
||||
case 25: config::input.gui.pause = input_find(value); break;
|
||||
case 26: config::input.gui.reset = input_find(value); break;
|
||||
case 27: config::input.gui.power = input_find(value); break;
|
||||
case 28: config::input.gui.toggle_fullscreen = input_find(value); break;
|
||||
case 29: config::input.gui.toggle_menubar = input_find(value); break;
|
||||
case 30: config::input.gui.toggle_statusbar = input_find(value); break;
|
||||
}
|
||||
|
||||
const char *name;
|
||||
acquire(index, name) = input_find(value);
|
||||
input_manager.bind();
|
||||
}
|
||||
|
|
|
@ -15,9 +15,9 @@ public:
|
|||
uintptr_t list_change(Event);
|
||||
uintptr_t set_tick(Event);
|
||||
uintptr_t clr_tick(Event);
|
||||
|
||||
static const int list_size;
|
||||
static const char list_index[][64];
|
||||
|
||||
string_setting& acquire(unsigned index, const char *&name);
|
||||
static const int inputcount;
|
||||
uint get_value(uint index);
|
||||
void set_value(uint index, uint16 value);
|
||||
} window_input_config;
|
||||
|
|
|
@ -71,50 +71,50 @@ uintptr_t PathSettingsWindow::defaultpath_cheat(Event) {
|
|||
void PathSettingsWindow::setup() {
|
||||
create(0, 475, 355);
|
||||
|
||||
lrompath.create(0, 475, 20, "Default game ROM path:");
|
||||
rompath.create(Editbox::Readonly, 265, 30);
|
||||
romselect.create(0, 100, 30, "Select");
|
||||
romdefault.create(0, 100, 30, "Default");
|
||||
autodetect.create(0, 475, 20, "Auto-detect file compression type (ignore file extension)");
|
||||
lrompath.create(0, 475, 18, translate["Default game ROM path:"]);
|
||||
rompath.create(Editbox::Readonly, 265, 25);
|
||||
romselect.create(0, 100, 25, translate["Select"]);
|
||||
romdefault.create(0, 100, 25, translate["Default"]);
|
||||
autodetect.create(0, 475, 18, translate["Auto-detect file compression type (ignore file extension)"]);
|
||||
|
||||
lpatchpath.create(0, 475, 20, "Default UPS patch path:");
|
||||
patchpath.create(Editbox::Readonly, 265, 30);
|
||||
patchselect.create(0, 100, 30, "Select");
|
||||
patchdefault.create(0, 100, 30, "Default");
|
||||
bypass_crc32.create(0, 475, 20, "Bypass CRC32 patch validation (not recommended)");
|
||||
lpatchpath.create(0, 475, 18, translate["Default UPS patch path:"]);
|
||||
patchpath.create(Editbox::Readonly, 265, 25);
|
||||
patchselect.create(0, 100, 25, translate["Select"]);
|
||||
patchdefault.create(0, 100, 25, translate["Default"]);
|
||||
bypass_crc32.create(0, 475, 18, translate["Bypass CRC32 patch validation (not recommended)"]);
|
||||
|
||||
lsavepath.create(0, 475, 20, "Default save RAM path:");
|
||||
savepath.create(Editbox::Readonly, 265, 30);
|
||||
saveselect.create(0, 100, 30, "Select");
|
||||
savedefault.create(0, 100, 30, "Default");
|
||||
lsavepath.create(0, 475, 18, translate["Default save RAM path:"]);
|
||||
savepath.create(Editbox::Readonly, 265, 25);
|
||||
saveselect.create(0, 100, 25, translate["Select"]);
|
||||
savedefault.create(0, 100, 25, translate["Default"]);
|
||||
|
||||
lcheatpath.create(0, 475, 20, "Default cheat file path:");
|
||||
cheatpath.create(Editbox::Readonly, 265, 30);
|
||||
cheatselect.create(0, 100, 30, "Select");
|
||||
cheatdefault.create(0, 100, 30, "Default");
|
||||
lcheatpath.create(0, 475, 18, translate["Default cheat file path:"]);
|
||||
cheatpath.create(Editbox::Readonly, 265, 25);
|
||||
cheatselect.create(0, 100, 25, translate["Select"]);
|
||||
cheatdefault.create(0, 100, 25, translate["Default"]);
|
||||
|
||||
unsigned y = 0;
|
||||
attach(lrompath, 0, y); y += 20;
|
||||
attach(lrompath, 0, y); y += 18;
|
||||
attach(rompath, 0, y);
|
||||
attach(romselect, 270, y);
|
||||
attach(romdefault, 375, y); y += 30;
|
||||
attach(autodetect, 0, y); y += 25;
|
||||
attach(romdefault, 375, y); y += 25;
|
||||
attach(autodetect, 0, y); y += 18 + 5;
|
||||
|
||||
attach(lpatchpath, 0, y); y += 20;
|
||||
attach(lpatchpath, 0, y); y += 18;
|
||||
attach(patchpath, 0, y);
|
||||
attach(patchselect, 270, y);
|
||||
attach(patchdefault, 375, y); y += 30;
|
||||
attach(bypass_crc32, 0, y); y += 25;
|
||||
attach(patchdefault, 375, y); y += 25;
|
||||
attach(bypass_crc32, 0, y); y += 18 + 5;
|
||||
|
||||
attach(lsavepath, 0, y); y += 20;
|
||||
attach(lsavepath, 0, y); y += 18;
|
||||
attach(savepath, 0, y);
|
||||
attach(saveselect, 270, y);
|
||||
attach(savedefault, 375, y); y += 35;
|
||||
attach(savedefault, 375, y); y += 25 + 5;
|
||||
|
||||
attach(lcheatpath, 0, y); y += 20;
|
||||
attach(lcheatpath, 0, y); y += 18;
|
||||
attach(cheatpath, 0, y);
|
||||
attach(cheatselect, 270, y);
|
||||
attach(cheatdefault, 375, y); y += 35;
|
||||
attach(cheatdefault, 375, y); y += 25 + 5;
|
||||
|
||||
romselect.on_tick = bind(&PathSettingsWindow::selectpath_rom, this);
|
||||
romdefault.on_tick = bind(&PathSettingsWindow::defaultpath_rom, this);
|
||||
|
|
|
@ -1,24 +1,24 @@
|
|||
void SettingsWindow::setup() {
|
||||
create(Window::AutoCenter, 640, 365, "bsnes Configuration Settings");
|
||||
create(Window::AutoCenter, 625, 365, translate["bsnes Configuration Settings"]);
|
||||
set_icon(48, 48, (uint32_t*)resource::icon48);
|
||||
|
||||
panel_list.create(0, 150, 355);
|
||||
panel_list.add_item("Raster Settings");
|
||||
panel_list.add_item("Input Configuration");
|
||||
panel_list.add_item("Path Settings");
|
||||
panel_list.add_item("Cheat Code Editor");
|
||||
panel_list.add_item("Advanced");
|
||||
panel_list.create(0, 135, 355);
|
||||
panel_list.add_item(translate["Video"]);
|
||||
panel_list.add_item(translate["Input"]);
|
||||
panel_list.add_item(translate["Paths"]);
|
||||
panel_list.add_item(translate["Cheat Codes"]);
|
||||
panel_list.add_item(translate["Advanced"]);
|
||||
|
||||
attach(panel_list, 5, 5);
|
||||
attach(window_raster_settings, 160, 5);
|
||||
attach(window_input_config, 160, 5);
|
||||
attach(window_path_settings, 160, 5);
|
||||
attach(window_cheat_editor, 160, 5);
|
||||
attach(window_advanced, 160, 5);
|
||||
attach(panel_list, 5, 5);
|
||||
attach(window_video_settings, 145, 5);
|
||||
attach(window_input_config, 145, 5);
|
||||
attach(window_path_settings, 145, 5);
|
||||
attach(window_cheat_editor, 145, 5);
|
||||
attach(window_advanced, 145, 5);
|
||||
|
||||
on_close = bind(&SettingsWindow::close, this);
|
||||
panel_list.on_change = bind(&SettingsWindow::list_change, this);
|
||||
panel_list.set_selection(0);
|
||||
panel_list.set_selection(1); //default to input configuration (most frequently used panel)
|
||||
}
|
||||
|
||||
uintptr_t SettingsWindow::close(Event) {
|
||||
|
@ -27,18 +27,18 @@ uintptr_t SettingsWindow::close(Event) {
|
|||
}
|
||||
|
||||
uintptr_t SettingsWindow::list_change(Event) {
|
||||
window_raster_settings.hide();
|
||||
window_video_settings.hide();
|
||||
window_input_config.hide();
|
||||
window_path_settings.hide();
|
||||
window_cheat_editor.hide();
|
||||
window_advanced.hide();
|
||||
|
||||
switch(panel_list.get_selection()) {
|
||||
case 0: window_raster_settings.show(); break;
|
||||
case 1: window_input_config.show(); break;
|
||||
case 2: window_path_settings.show(); break;
|
||||
case 3: window_cheat_editor.show(); break;
|
||||
case 4: window_advanced.show(); break;
|
||||
case 0: window_video_settings.show(); break;
|
||||
case 1: window_input_config.show(); break;
|
||||
case 2: window_path_settings.show(); break;
|
||||
case 3: window_cheat_editor.show(); break;
|
||||
case 4: window_advanced.show(); break;
|
||||
}
|
||||
|
||||
panel_list.focus();
|
||||
|
|
|
@ -1,54 +1,54 @@
|
|||
void RasterSettingsWindow::setup() {
|
||||
void VideoSettingsWindow::setup() {
|
||||
create(0, 475, 355);
|
||||
|
||||
lcontrast.create (0, 475, 20);
|
||||
lcontrast.create (0, 475, 18);
|
||||
contrast.create (0, 475, 30, 192);
|
||||
lbrightness.create (0, 475, 20);
|
||||
lbrightness.create (0, 475, 18);
|
||||
brightness.create (0, 475, 30, 192);
|
||||
lgamma.create (0, 475, 20);
|
||||
lgamma.create (0, 475, 18);
|
||||
gamma.create (0, 475, 30, 191);
|
||||
gamma_ramp.create (0, 235, 20, "Gamma ramp");
|
||||
sepia.create (0, 235, 20, "Sepia");
|
||||
grayscale.create (0, 235, 20, "Grayscale");
|
||||
invert.create (0, 235, 20, "Invert colors");
|
||||
preset_optimal.create (0, 235, 30, "Optimal Preset");
|
||||
preset_standard.create(0, 235, 30, "Standard Preset");
|
||||
gamma_ramp.create (0, 235, 18, translate["Gamma ramp"]);
|
||||
sepia.create (0, 235, 18, translate["Sepia"]);
|
||||
grayscale.create (0, 235, 18, translate["Grayscale"]);
|
||||
invert.create (0, 235, 18, translate["Invert colors"]);
|
||||
preset_optimal.create (0, 235, 25, translate["Optimal Preset"]);
|
||||
preset_standard.create(0, 235, 25, translate["Standard Preset"]);
|
||||
sync_ui();
|
||||
|
||||
uint y = 0;
|
||||
attach(lcontrast, 0, y); y += 20;
|
||||
attach(lcontrast, 0, y); y += 18;
|
||||
attach(contrast, 0, y); y += 30;
|
||||
attach(lbrightness, 0, y); y += 20;
|
||||
attach(lbrightness, 0, y); y += 18;
|
||||
attach(brightness, 0, y); y += 30;
|
||||
attach(lgamma, 0, y); y += 20;
|
||||
attach(lgamma, 0, y); y += 18;
|
||||
attach(gamma, 0, y); y += 30;
|
||||
attach(gamma_ramp, 0, y);
|
||||
attach(sepia, 240, y); y += 20;
|
||||
attach(sepia, 240, y); y += 18;
|
||||
attach(grayscale, 0, y);
|
||||
attach(invert, 240, y); y += 20;
|
||||
attach(invert, 240, y); y += 18;
|
||||
attach(preset_optimal, 0, y);
|
||||
attach(preset_standard, 240, y); y += 30;
|
||||
attach(preset_standard, 240, y); y += 25;
|
||||
|
||||
contrast.on_change = bind(&RasterSettingsWindow::contrast_change, this);
|
||||
brightness.on_change = bind(&RasterSettingsWindow::brightness_change, this);
|
||||
gamma.on_change = bind(&RasterSettingsWindow::gamma_change, this);
|
||||
gamma_ramp.on_tick = bind(&RasterSettingsWindow::gammaramp_tick, this);
|
||||
sepia.on_tick = bind(&RasterSettingsWindow::sepia_tick, this);
|
||||
grayscale.on_tick = bind(&RasterSettingsWindow::grayscale_tick, this);
|
||||
invert.on_tick = bind(&RasterSettingsWindow::invert_tick, this);
|
||||
preset_optimal.on_tick = bind(&RasterSettingsWindow::optimal_tick, this);
|
||||
preset_standard.on_tick = bind(&RasterSettingsWindow::standard_tick, this);
|
||||
contrast.on_change = bind(&VideoSettingsWindow::contrast_change, this);
|
||||
brightness.on_change = bind(&VideoSettingsWindow::brightness_change, this);
|
||||
gamma.on_change = bind(&VideoSettingsWindow::gamma_change, this);
|
||||
gamma_ramp.on_tick = bind(&VideoSettingsWindow::gammaramp_tick, this);
|
||||
sepia.on_tick = bind(&VideoSettingsWindow::sepia_tick, this);
|
||||
grayscale.on_tick = bind(&VideoSettingsWindow::grayscale_tick, this);
|
||||
invert.on_tick = bind(&VideoSettingsWindow::invert_tick, this);
|
||||
preset_optimal.on_tick = bind(&VideoSettingsWindow::optimal_tick, this);
|
||||
preset_standard.on_tick = bind(&VideoSettingsWindow::standard_tick, this);
|
||||
}
|
||||
|
||||
//update all UI controls to match config file values ...
|
||||
void RasterSettingsWindow::sync_ui() {
|
||||
void VideoSettingsWindow::sync_ui() {
|
||||
ui_lock = true; //supress event messages while syncing UI elements, prevents infinite recursion
|
||||
contrast.set_position(config::system.contrast + 96);
|
||||
lcontrast.set_text(string() << "Contrast: " << (int)config::system.contrast);
|
||||
lcontrast.set_text(string() << translate["Contrast"] << ": " << (int)config::system.contrast);
|
||||
brightness.set_position(config::system.brightness + 96);
|
||||
lbrightness.set_text(string() << "Brightness: " << (int)config::system.brightness);
|
||||
lbrightness.set_text(string() << translate["Brightness"] << ": " << (int)config::system.brightness);
|
||||
gamma.set_position(config::system.gamma - 10);
|
||||
lgamma.set_text(string() << "Gamma: " << (int)config::system.gamma); //TODO: print gamma as "%0.2f" / 100.0
|
||||
lgamma.set_text(string() << translate["Gamma"] << ": " << (int)config::system.gamma); //TODO: print gamma as "%0.2f" / 100.0
|
||||
gamma_ramp.check(config::system.gamma_ramp);
|
||||
sepia.check(config::system.sepia);
|
||||
grayscale.check(config::system.grayscale);
|
||||
|
@ -66,7 +66,7 @@ void RasterSettingsWindow::sync_ui() {
|
|||
ui_lock = false;
|
||||
}
|
||||
|
||||
uintptr_t RasterSettingsWindow::contrast_change(Event) {
|
||||
uintptr_t VideoSettingsWindow::contrast_change(Event) {
|
||||
if(!ui_lock && config::system.contrast != contrast.get_position() - 96) {
|
||||
config::system.contrast = contrast.get_position() - 96;
|
||||
sync_ui();
|
||||
|
@ -74,7 +74,7 @@ uintptr_t RasterSettingsWindow::contrast_change(Event) {
|
|||
return true;
|
||||
}
|
||||
|
||||
uintptr_t RasterSettingsWindow::brightness_change(Event) {
|
||||
uintptr_t VideoSettingsWindow::brightness_change(Event) {
|
||||
if(!ui_lock && config::system.brightness != brightness.get_position() - 96) {
|
||||
config::system.brightness = brightness.get_position() - 96;
|
||||
sync_ui();
|
||||
|
@ -82,7 +82,7 @@ uintptr_t RasterSettingsWindow::brightness_change(Event) {
|
|||
return true;
|
||||
}
|
||||
|
||||
uintptr_t RasterSettingsWindow::gamma_change(Event) {
|
||||
uintptr_t VideoSettingsWindow::gamma_change(Event) {
|
||||
if(!ui_lock && config::system.gamma != gamma.get_position() + 10) {
|
||||
config::system.gamma = gamma.get_position() + 10;
|
||||
sync_ui();
|
||||
|
@ -90,7 +90,7 @@ uintptr_t RasterSettingsWindow::gamma_change(Event) {
|
|||
return true;
|
||||
}
|
||||
|
||||
uintptr_t RasterSettingsWindow::gammaramp_tick(Event) {
|
||||
uintptr_t VideoSettingsWindow::gammaramp_tick(Event) {
|
||||
if(!ui_lock && config::system.gamma_ramp != gamma_ramp.checked()) {
|
||||
config::system.gamma_ramp = gamma_ramp.checked();
|
||||
sync_ui();
|
||||
|
@ -98,7 +98,7 @@ uintptr_t RasterSettingsWindow::gammaramp_tick(Event) {
|
|||
return true;
|
||||
}
|
||||
|
||||
uintptr_t RasterSettingsWindow::sepia_tick(Event) {
|
||||
uintptr_t VideoSettingsWindow::sepia_tick(Event) {
|
||||
if(!ui_lock && config::system.sepia != sepia.checked()) {
|
||||
config::system.sepia = sepia.checked();
|
||||
sync_ui();
|
||||
|
@ -106,7 +106,7 @@ uintptr_t RasterSettingsWindow::sepia_tick(Event) {
|
|||
return true;
|
||||
}
|
||||
|
||||
uintptr_t RasterSettingsWindow::grayscale_tick(Event) {
|
||||
uintptr_t VideoSettingsWindow::grayscale_tick(Event) {
|
||||
if(!ui_lock && config::system.grayscale != grayscale.checked()) {
|
||||
config::system.grayscale = grayscale.checked();
|
||||
sync_ui();
|
||||
|
@ -114,7 +114,7 @@ uintptr_t RasterSettingsWindow::grayscale_tick(Event) {
|
|||
return true;
|
||||
}
|
||||
|
||||
uintptr_t RasterSettingsWindow::invert_tick(Event) {
|
||||
uintptr_t VideoSettingsWindow::invert_tick(Event) {
|
||||
if(!ui_lock && config::system.invert != invert.checked()) {
|
||||
config::system.invert = invert.checked();
|
||||
sync_ui();
|
||||
|
@ -122,7 +122,7 @@ uintptr_t RasterSettingsWindow::invert_tick(Event) {
|
|||
return true;
|
||||
}
|
||||
|
||||
uintptr_t RasterSettingsWindow::optimal_tick(Event) {
|
||||
uintptr_t VideoSettingsWindow::optimal_tick(Event) {
|
||||
config::system.contrast = 0;
|
||||
config::system.brightness = 0;
|
||||
config::system.gamma = 80;
|
||||
|
@ -134,7 +134,7 @@ uintptr_t RasterSettingsWindow::optimal_tick(Event) {
|
|||
return true;
|
||||
}
|
||||
|
||||
uintptr_t RasterSettingsWindow::standard_tick(Event) {
|
||||
uintptr_t VideoSettingsWindow::standard_tick(Event) {
|
||||
config::system.contrast = 0;
|
||||
config::system.brightness = 0;
|
||||
config::system.gamma = 100;
|
||||
|
@ -146,6 +146,6 @@ uintptr_t RasterSettingsWindow::standard_tick(Event) {
|
|||
return true;
|
||||
}
|
||||
|
||||
RasterSettingsWindow::RasterSettingsWindow() {
|
||||
VideoSettingsWindow::VideoSettingsWindow() {
|
||||
ui_lock = false;
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
class RasterSettingsWindow : public Window {
|
||||
class VideoSettingsWindow : public Window {
|
||||
public:
|
||||
Label lcontrast;
|
||||
Label lbrightness;
|
||||
|
@ -29,5 +29,5 @@ public:
|
|||
uintptr_t optimal_tick(Event);
|
||||
uintptr_t standard_tick(Event);
|
||||
|
||||
RasterSettingsWindow();
|
||||
} window_raster_settings;
|
||||
VideoSettingsWindow();
|
||||
} window_video_settings;
|
|
@ -8,7 +8,7 @@
|
|||
#include "loader/stloader.cpp"
|
||||
|
||||
#include "settings/settings.cpp"
|
||||
#include "settings/rastersettings.cpp"
|
||||
#include "settings/videosettings.cpp"
|
||||
#include "settings/inputconfig.cpp"
|
||||
#include "settings/pathsettings.cpp"
|
||||
#include "settings/cheateditor.cpp"
|
||||
|
@ -25,7 +25,7 @@ void ui_init() {
|
|||
window_bsxloader.setup();
|
||||
window_stloader.setup();
|
||||
|
||||
window_raster_settings.setup();
|
||||
window_video_settings.setup();
|
||||
window_input_config.setup();
|
||||
window_path_settings.setup();
|
||||
window_cheat_editor.setup();
|
||||
|
@ -44,7 +44,7 @@ void ui_init() {
|
|||
video.set(Video::Handle, window_main.view.handle());
|
||||
video.set(Video::Synchronize, false);
|
||||
audio.set(Audio::Handle, window_main.handle());
|
||||
audio.set(Audio::Synchronize, config::system.speed_regulation != 0);
|
||||
audio.set(Audio::Synchronize, config::system.emulation_speed != 0);
|
||||
audio.set(Audio::Frequency, 32000);
|
||||
input.set(Input::Handle, window_main.handle());
|
||||
|
||||
|
|
|
@ -1,5 +1,8 @@
|
|||
#include <nall/base64.hpp>
|
||||
#include <nall/lzss.hpp>
|
||||
#include <nall/base64.hpp>
|
||||
#include <nall/dictionary.hpp>
|
||||
#include <nall/lzss.hpp>
|
||||
|
||||
nall::dictionary translate;
|
||||
|
||||
#include "base/main.h"
|
||||
#include "base/about.h"
|
||||
|
@ -9,7 +12,7 @@
|
|||
#include "loader/stloader.h"
|
||||
|
||||
#include "settings/settings.h"
|
||||
#include "settings/rastersettings.h"
|
||||
#include "settings/videosettings.h"
|
||||
#include "settings/inputconfig.h"
|
||||
#include "settings/pathsettings.h"
|
||||
#include "settings/cheateditor.h"
|
||||
|
|
Loading…
Reference in New Issue