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:
byuu 2008-05-25 18:45:59 +00:00
parent 96fe8f760d
commit ebb9367c68
96 changed files with 1553 additions and 1166 deletions

View File

@ -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

View File

@ -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)))

View File

@ -1,4 +1,4 @@
#define BSNES_VERSION "0.031"
#define BSNES_VERSION "0.032"
#define BSNES_TITLE "bsnes v" BSNES_VERSION
#define BUSCORE sBus

View File

@ -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);

View File

@ -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;
}
}

View File

@ -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;
}
}
}

View File

@ -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

View File

@ -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;
}
}

View File

@ -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;
}
}
}

View File

@ -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

View File

@ -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",

View File

@ -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;

View File

@ -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) {}
};

View File

@ -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

View File

@ -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"
};

View File

@ -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;

View File

@ -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);

View File

@ -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 */

View File

@ -10,6 +10,7 @@ public:
pCheckbox(Checkbox&);
/* internal */
GtkWidget *checkbox;
GtkWidget* gtk_handle();
GtkWidget *checkbox;
bool locked;
};

View File

@ -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);

View File

@ -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);

View File

@ -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);
}

View File

@ -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();
}

View File

@ -55,6 +55,7 @@ public:
/* internal */
GdkScreen *screen;
GdkColormap *colormap;
PangoFontDescription *font;
bool is_composited;
char default_path[PATH_MAX];

View File

@ -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);

View File

@ -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() {

View File

@ -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 */

View File

@ -9,6 +9,7 @@ public:
pMenuCheckItem(MenuCheckItem&);
/* internal */
GtkWidget *item;
GtkWidget* gtk_handle();
GtkWidget *item;
bool locked;
};

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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 */

View File

@ -8,6 +8,7 @@ public:
pMenuRadioItem(MenuRadioItem&);
/* internal */
GtkWidget *item;
GtkWidget* gtk_handle();
GtkWidget *item;
bool locked;
};

View File

@ -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 */

View File

@ -9,6 +9,7 @@ public:
pRadiobox(Radiobox&);
/* internal */
GtkWidget *radiobox;
GtkWidget* gtk_handle();
GtkWidget *radiobox;
bool locked;
};

View File

@ -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);

View File

@ -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>

View File

@ -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_) {

View File

@ -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);

View File

@ -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() {

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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_) {

View File

@ -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)

View File

@ -11,6 +11,7 @@
#define _WIN32_IE 0x0600
#define NOMINMAX
#define UNICODE
#include <windows.h>
#include <commctrl.h>
#include <shlobj.h>

View File

@ -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_) {

View File

@ -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);
}

View File

@ -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;

View File

@ -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;
}

View File

@ -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;

View File

@ -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));

View File

@ -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() {

View File

@ -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,

55
src/lib/hiro/win/utf.cpp Normal file
View File

@ -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;
};

View File

@ -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) {

View File

@ -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;

View File

@ -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

136
src/lib/ruby/audio/alsa.cpp Normal file
View File

@ -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

23
src/lib/ruby/audio/alsa.h Normal file
View File

@ -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;
};

View File

@ -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)

View File

@ -1,6 +1,6 @@
/*
ruby
version: 0.02 (2008-04-06)
version: 0.03 (2008-05-04)
license: public domain
*/

View File

@ -30,6 +30,10 @@
/* Audio */
#ifdef AUDIO_ALSA
#include <ruby/audio/alsa.cpp>
#endif
#ifdef AUDIO_AO
#include <ruby/audio/ao.cpp>
#endif

View File

@ -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;
}

View File

@ -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

View File

@ -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;
};

View File

@ -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;

View File

@ -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);
}

View File

@ -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; }
};

View File

@ -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);
}

View File

@ -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) {}
};

View File

@ -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),

View File

@ -93,7 +93,7 @@ case 0xe0: {
case 0xed: {
op_io();
op_io();
regs.p.c ^= 1;
regs.p.c = !regs.p.c;
} break;
//ei

View File

@ -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;
}

View File

@ -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;

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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);

View File

@ -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();
}

View File

@ -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

View File

@ -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();
}
};

View File

@ -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

View File

@ -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() {

View File

@ -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);

View File

@ -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);

View File

@ -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();

View File

@ -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();

View File

@ -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);
}

View File

@ -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();
}

View File

@ -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;

View File

@ -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);

View File

@ -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();

View File

@ -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;
}

View File

@ -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;

View File

@ -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());

View File

@ -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"