diff --git a/readme.txt b/readme.txt index dddd28c7..93af60bb 100644 --- a/readme.txt +++ b/readme.txt @@ -1,5 +1,5 @@ bsnes -Version: 0.031 +Version: 0.032 Author: byuu -------- @@ -13,6 +13,29 @@ http://byuu.org/ Please see license.txt for important licensing information. +-------------- +Configuration: +-------------- +bsnes has two configuration files: bsnes.cfg, for program settings; and +locale.cfg, for localization. + +For each file, bsnes will start by looking inside the same folder where the +bsnes executable is located. If said file is not found, it will then check your +user profile folder. On Windows, this is located at "%APPDATA%/.bsnes". On all +other operating systems, this is located at "~/.bsnes". If said file is still +not found, it will automatically be created in your user profile folder. + +If you wish to use bsnes in single-user mode, be sure that both files exist +inside the same folder as the bsnes executable. If they do not, you can simply +create new blank files and bsnes will use them in the future. + +If you wish to use bsnes in multi-user mode, simply delete these two files from +the bsnes executable directory if they exist. + +If you wish to have multiple configuration profiles for the same user, you will +need to make copies of the bsnes executable, and use each one in single-user +mode. + ------------------ Known Limitations: ------------------ @@ -60,10 +83,10 @@ Coprocessor used only by the following games: - Super Power League 4 ST-011 -SETA DSP used only by Quick-move Shogi Match with Nidan Rank-holder Morita +SETA DSP used by Quick-move Shogi Match with Nidan Rank-holder Morita ST-018 -SETA RISC CPU used only by Quick-move Shogi Match with Nidan Rank-holder Morita 2 +SETA RISC CPU used by Quick-move Shogi Match with Nidan Rank-holder Morita 2 Super Gameboy Cartridge passthrough used for playing Gameboy games diff --git a/src/Makefile b/src/Makefile index b160823b..a33359dd 100644 --- a/src/Makefile +++ b/src/Makefile @@ -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))) diff --git a/src/base.h b/src/base.h index d55d2ecf..68caa0e8 100644 --- a/src/base.h +++ b/src/base.h @@ -1,4 +1,4 @@ -#define BSNES_VERSION "0.031" +#define BSNES_VERSION "0.032" #define BSNES_TITLE "bsnes v" BSNES_VERSION #define BUSCORE sBus diff --git a/src/cart/cart.cpp b/src/cart/cart.cpp index 94d03d8a..1406e442 100644 --- a/src/cart/cart.cpp +++ b/src/cart/cart.cpp @@ -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); diff --git a/src/cart/cart_bsc.cpp b/src/cart/cart_bsc.cpp index 0d4a8324..4b1f72e1 100644 --- a/src/cart/cart_bsc.cpp +++ b/src/cart/cart_bsc.cpp @@ -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; } } diff --git a/src/cart/cart_bsx.cpp b/src/cart/cart_bsx.cpp index 07e951dc..ba59b945 100644 --- a/src/cart/cart_bsx.cpp +++ b/src/cart/cart_bsx.cpp @@ -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; } } } diff --git a/src/cart/cart_file.cpp b/src/cart/cart_file.cpp index 3ed99e73..ea70ad3f 100644 --- a/src/cart/cart_file.cpp +++ b/src/cart/cart_file.cpp @@ -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 diff --git a/src/cart/cart_normal.cpp b/src/cart/cart_normal.cpp index ccd99cd5..3460cc0f 100644 --- a/src/cart/cart_normal.cpp +++ b/src/cart/cart_normal.cpp @@ -12,17 +12,17 @@ void Cartridge::load_cart_normal(const char *filename) { //load ROM data, ignore 512-byte header if detected if((size & 0x7fff) != 512) { - cart.rom = (uint8*)malloc(cart.rom_size = size); + cart.rom = new uint8_t[cart.rom_size = size]; memcpy(cart.rom, data, size); } else { - cart.rom = (uint8*)malloc(cart.rom_size = size - 512); + cart.rom = new uint8_t[cart.rom_size = size - 512]; memcpy(cart.rom, data + 512, size - 512); } - safe_free(data); + delete[] data; if(load_file(get_patch_filename(cart.fn, "ups"), data, size, CompressionInspect) == true) { apply_patch(data, size, cart.rom, cart.rom_size); - if(data) { free(data); data = 0; } + delete[] data; } info.crc32 = crc32_calculate(cart.rom, cart.rom_size); @@ -31,12 +31,12 @@ void Cartridge::load_cart_normal(const char *filename) { read_header(); if(info.ram_size > 0) { - cart.ram = (uint8*)malloc(cart.ram_size = info.ram_size); + cart.ram = new uint8_t[cart.ram_size = info.ram_size]; memset(cart.ram, 0xff, cart.ram_size); if(load_file(get_save_filename(cart.fn, "srm"), data, size, CompressionNone) == true) { memcpy(cart.ram, data, min(size, cart.ram_size)); - safe_free(data); + delete[] data; } } diff --git a/src/cart/cart_st.cpp b/src/cart/cart_st.cpp index 8c0acc6f..049765f7 100644 --- a/src/cart/cart_st.cpp +++ b/src/cart/cart_st.cpp @@ -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; } } } diff --git a/src/chip/bsx/bsx_cart.cpp b/src/chip/bsx/bsx_cart.cpp index 60e84e3b..49585061 100644 --- a/src/chip/bsx/bsx_cart.cpp +++ b/src/chip/bsx/bsx_cart.cpp @@ -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 diff --git a/src/config/config.cpp b/src/config/config.cpp index 1ca8345c..a04511d3 100644 --- a/src/config/config.cpp +++ b/src/config/config.cpp @@ -44,8 +44,9 @@ string file_updatepath(const char *req_file, const char *req_path) { return path; } -string_setting Path::base("path.base", - "Path that bsnes resides in", ""); +string_setting Path::base("path.base", "Path that bsnes resides in", ""); +string_setting Path::user("path.user", "Path to user folder", ""); + string_setting Path::rom(config(), "path.rom", "Default path to look for ROM files in (\"\" = use default directory)", ""); string_setting Path::patch(config(), "path.patch", diff --git a/src/config/config.h b/src/config/config.h index 27975f56..46d8a0be 100644 --- a/src/config/config.h +++ b/src/config/config.h @@ -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; diff --git a/src/cpu/cpuregs.h b/src/cpu/cpuregs.h index 4c6195ee..727aa60b 100644 --- a/src/cpu/cpuregs.h +++ b/src/cpu/cpuregs.h @@ -1,19 +1,32 @@ +template +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 inline unsigned operator = (const T i) { data = i; return data; } - template inline unsigned operator |= (const T i) { data |= i; return data; } - template inline unsigned operator ^= (const T i) { data ^= i; return data; } - template 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 inline unsigned operator = (const T i) { w = i; return w; } - template inline unsigned operator |= (const T i) { w |= i; return w; } - template inline unsigned operator ^= (const T i) { w ^= i; return w; } - template inline unsigned operator &= (const T i) { w &= i; return w; } - template inline unsigned operator <<= (const T i) { w <<= i; return w; } - template inline unsigned operator >>= (const T i) { w >>= i; return w; } - template inline unsigned operator += (const T i) { w += i; return w; } - template inline unsigned operator -= (const T i) { w -= i; return w; } - template inline unsigned operator *= (const T i) { w *= i; return w; } - template inline unsigned operator /= (const T i) { w /= i; return w; } - template 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 inline unsigned operator = (const T i) { d = uclip<24>(i); return d; } - template inline unsigned operator |= (const T i) { d = uclip<24>(d | i); return d; } - template inline unsigned operator ^= (const T i) { d = uclip<24>(d ^ i); return d; } - template inline unsigned operator &= (const T i) { d = uclip<24>(d & i); return d; } - template inline unsigned operator <<= (const T i) { d = uclip<24>(d << i); return d; } - template inline unsigned operator >>= (const T i) { d = uclip<24>(d >> i); return d; } - template inline unsigned operator += (const T i) { d = uclip<24>(d + i); return d; } - template inline unsigned operator -= (const T i) { d = uclip<24>(d - i); return d; } - template inline unsigned operator *= (const T i) { d = uclip<24>(d * i); return d; } - template inline unsigned operator /= (const T i) { d = uclip<24>(d / i); return d; } - template 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) {} }; diff --git a/src/cpu/scpu/core/opfn.cpp b/src/cpu/scpu/core/opfn.cpp index 23d9372f..72bb7571 100644 --- a/src/cpu/scpu/core/opfn.cpp +++ b/src/cpu/scpu/core/opfn.cpp @@ -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; } diff --git a/src/data/bsnes.ico b/src/data/bsnes.ico index 7ea9879b..646d8c5f 100644 Binary files a/src/data/bsnes.ico and b/src/data/bsnes.ico differ diff --git a/src/data/bsnes.png b/src/data/bsnes.png index b2c8cd4e..02986ba8 100644 Binary files a/src/data/bsnes.png and b/src/data/bsnes.png differ diff --git a/src/data/icon48.h b/src/data/icon48.h index b9cfaa8a..4d1daf76 100644 --- a/src/data/icon48.h +++ b/src/data/icon48.h @@ -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" }; diff --git a/src/lib/bbase.h b/src/lib/bbase.h index 3f314a18..2976b6c8 100644 --- a/src/lib/bbase.h +++ b/src/lib/bbase.h @@ -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 inline void safe_free(T &handle) { - if(handle) { - free(handle); - handle = 0; - } -} - -template inline void safe_delete(T &handle) { - if(handle) { - delete handle; - handle = 0; - } -} - -template inline void safe_release(T &handle) { - if(handle) { - handle->Release(); - handle = 0; - } -} - template inline T minmax(const T x) { return (x < (T)min) ? (T)min : (x > (T)max) ? (T)max : x; } @@ -177,47 +152,47 @@ template 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; diff --git a/src/lib/hiro/gtk/button.cpp b/src/lib/hiro/gtk/button.cpp index 4c76fcd7..8a2e106d 100644 --- a/src/lib/hiro/gtk/button.cpp +++ b/src/lib/hiro/gtk/button.cpp @@ -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); diff --git a/src/lib/hiro/gtk/checkbox.cpp b/src/lib/hiro/gtk/checkbox.cpp index f7770d90..5df53f4b 100644 --- a/src/lib/hiro/gtk/checkbox.cpp +++ b/src/lib/hiro/gtk/checkbox.cpp @@ -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 */ diff --git a/src/lib/hiro/gtk/checkbox.h b/src/lib/hiro/gtk/checkbox.h index bf3cbb3d..74229917 100644 --- a/src/lib/hiro/gtk/checkbox.h +++ b/src/lib/hiro/gtk/checkbox.h @@ -10,6 +10,7 @@ public: pCheckbox(Checkbox&); /* internal */ - GtkWidget *checkbox; GtkWidget* gtk_handle(); + GtkWidget *checkbox; + bool locked; }; diff --git a/src/lib/hiro/gtk/combobox.cpp b/src/lib/hiro/gtk/combobox.cpp index 6166d0e5..930dc96a 100644 --- a/src/lib/hiro/gtk/combobox.cpp +++ b/src/lib/hiro/gtk/combobox.cpp @@ -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); diff --git a/src/lib/hiro/gtk/editbox.cpp b/src/lib/hiro/gtk/editbox.cpp index a27655f5..efd2fa98 100644 --- a/src/lib/hiro/gtk/editbox.cpp +++ b/src/lib/hiro/gtk/editbox.cpp @@ -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); diff --git a/src/lib/hiro/gtk/frame.cpp b/src/lib/hiro/gtk/frame.cpp index f378bb9e..9f2ed854 100644 --- a/src/lib/hiro/gtk/frame.cpp +++ b/src/lib/hiro/gtk/frame.cpp @@ -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); } diff --git a/src/lib/hiro/gtk/hiro.cpp b/src/lib/hiro/gtk/hiro.cpp index b0cca09f..881495d4 100644 --- a/src/lib/hiro/gtk/hiro.cpp +++ b/src/lib/hiro/gtk/hiro.cpp @@ -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(); } diff --git a/src/lib/hiro/gtk/hiro.h b/src/lib/hiro/gtk/hiro.h index fcd39151..eabe89de 100644 --- a/src/lib/hiro/gtk/hiro.h +++ b/src/lib/hiro/gtk/hiro.h @@ -55,6 +55,7 @@ public: /* internal */ GdkScreen *screen; GdkColormap *colormap; + PangoFontDescription *font; bool is_composited; char default_path[PATH_MAX]; diff --git a/src/lib/hiro/gtk/label.cpp b/src/lib/hiro/gtk/label.cpp index 809a8561..12389fcf 100644 --- a/src/lib/hiro/gtk/label.cpp +++ b/src/lib/hiro/gtk/label.cpp @@ -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); diff --git a/src/lib/hiro/gtk/listbox.cpp b/src/lib/hiro/gtk/listbox.cpp index fd7d418f..f7f3fab4 100644 --- a/src/lib/hiro/gtk/listbox.cpp +++ b/src/lib/hiro/gtk/listbox.cpp @@ -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() { diff --git a/src/lib/hiro/gtk/menucheckitem.cpp b/src/lib/hiro/gtk/menucheckitem.cpp index 1fc9fba8..fcf8267c 100644 --- a/src/lib/hiro/gtk/menucheckitem.cpp +++ b/src/lib/hiro/gtk/menucheckitem.cpp @@ -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 */ diff --git a/src/lib/hiro/gtk/menucheckitem.h b/src/lib/hiro/gtk/menucheckitem.h index d54202aa..74f262be 100644 --- a/src/lib/hiro/gtk/menucheckitem.h +++ b/src/lib/hiro/gtk/menucheckitem.h @@ -9,6 +9,7 @@ public: pMenuCheckItem(MenuCheckItem&); /* internal */ - GtkWidget *item; GtkWidget* gtk_handle(); + GtkWidget *item; + bool locked; }; diff --git a/src/lib/hiro/gtk/menugroup.cpp b/src/lib/hiro/gtk/menugroup.cpp index 74c2d499..a05fc5f0 100644 --- a/src/lib/hiro/gtk/menugroup.cpp +++ b/src/lib/hiro/gtk/menugroup.cpp @@ -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); } diff --git a/src/lib/hiro/gtk/menuitem.cpp b/src/lib/hiro/gtk/menuitem.cpp index 5da5be8d..46d338c7 100644 --- a/src/lib/hiro/gtk/menuitem.cpp +++ b/src/lib/hiro/gtk/menuitem.cpp @@ -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); } diff --git a/src/lib/hiro/gtk/menuradioitem.cpp b/src/lib/hiro/gtk/menuradioitem.cpp index 873760f3..839d1f67 100644 --- a/src/lib/hiro/gtk/menuradioitem.cpp +++ b/src/lib/hiro/gtk/menuradioitem.cpp @@ -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 */ diff --git a/src/lib/hiro/gtk/menuradioitem.h b/src/lib/hiro/gtk/menuradioitem.h index 56f9b585..10bbee42 100644 --- a/src/lib/hiro/gtk/menuradioitem.h +++ b/src/lib/hiro/gtk/menuradioitem.h @@ -8,6 +8,7 @@ public: pMenuRadioItem(MenuRadioItem&); /* internal */ - GtkWidget *item; GtkWidget* gtk_handle(); + GtkWidget *item; + bool locked; }; diff --git a/src/lib/hiro/gtk/radiobox.cpp b/src/lib/hiro/gtk/radiobox.cpp index 1dd1551c..0a20ed45 100644 --- a/src/lib/hiro/gtk/radiobox.cpp +++ b/src/lib/hiro/gtk/radiobox.cpp @@ -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 */ diff --git a/src/lib/hiro/gtk/radiobox.h b/src/lib/hiro/gtk/radiobox.h index 8b5825d6..8d5e83db 100644 --- a/src/lib/hiro/gtk/radiobox.h +++ b/src/lib/hiro/gtk/radiobox.h @@ -9,6 +9,7 @@ public: pRadiobox(Radiobox&); /* internal */ - GtkWidget *radiobox; GtkWidget* gtk_handle(); + GtkWidget *radiobox; + bool locked; }; diff --git a/src/lib/hiro/gtk/window.cpp b/src/lib/hiro/gtk/window.cpp index a1e9bd31..09d7b0c4 100644 --- a/src/lib/hiro/gtk/window.cpp +++ b/src/lib/hiro/gtk/window.cpp @@ -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); diff --git a/src/lib/hiro/hiro.h b/src/lib/hiro/hiro.h index 82e596a6..2cc16268 100644 --- a/src/lib/hiro/hiro.h +++ b/src/lib/hiro/hiro.h @@ -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 #include #include +#include #include #include #include diff --git a/src/lib/hiro/win/button.cpp b/src/lib/hiro/win/button.cpp index ac0cfb1b..12762669 100644 --- a/src/lib/hiro/win/button.cpp +++ b/src/lib/hiro/win/button.cpp @@ -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_) { diff --git a/src/lib/hiro/win/canvas.cpp b/src/lib/hiro/win/canvas.cpp index 19160414..b0755500 100644 --- a/src/lib/hiro/win/canvas.cpp +++ b/src/lib/hiro/win/canvas.cpp @@ -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); diff --git a/src/lib/hiro/win/checkbox.cpp b/src/lib/hiro/win/checkbox.cpp index c11cfe87..208c156c 100644 --- a/src/lib/hiro/win/checkbox.cpp +++ b/src/lib/hiro/win/checkbox.cpp @@ -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() { diff --git a/src/lib/hiro/win/combobox.cpp b/src/lib/hiro/win/combobox.cpp index acb3858f..4fb06fc9 100644 --- a/src/lib/hiro/win/combobox.cpp +++ b/src/lib/hiro/win/combobox.cpp @@ -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); } diff --git a/src/lib/hiro/win/editbox.cpp b/src/lib/hiro/win/editbox.cpp index d1b8b686..f0554c42 100644 --- a/src/lib/hiro/win/editbox.cpp +++ b/src/lib/hiro/win/editbox.cpp @@ -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); } diff --git a/src/lib/hiro/win/frame.cpp b/src/lib/hiro/win/frame.cpp index 73c75c1c..974a8c85 100644 --- a/src/lib/hiro/win/frame.cpp +++ b/src/lib/hiro/win/frame.cpp @@ -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_) { diff --git a/src/lib/hiro/win/hiro.cpp b/src/lib/hiro/win/hiro.cpp index 3a69dd17..594a8ba6 100644 --- a/src/lib/hiro/win/hiro.cpp +++ b/src/lib/hiro/win/hiro.cpp @@ -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) diff --git a/src/lib/hiro/win/hiro.h b/src/lib/hiro/win/hiro.h index 8969990d..8477cb9d 100644 --- a/src/lib/hiro/win/hiro.h +++ b/src/lib/hiro/win/hiro.h @@ -11,6 +11,7 @@ #define _WIN32_IE 0x0600 #define NOMINMAX +#define UNICODE #include #include #include diff --git a/src/lib/hiro/win/label.cpp b/src/lib/hiro/win/label.cpp index 3860c163..de51c697 100644 --- a/src/lib/hiro/win/label.cpp +++ b/src/lib/hiro/win/label.cpp @@ -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_) { diff --git a/src/lib/hiro/win/listbox.cpp b/src/lib/hiro/win/listbox.cpp index f8d72ac4..221f987e 100644 --- a/src/lib/hiro/win/listbox.cpp +++ b/src/lib/hiro/win/listbox.cpp @@ -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); } diff --git a/src/lib/hiro/win/menucheckitem.cpp b/src/lib/hiro/win/menucheckitem.cpp index b327ce8f..45bf6a63 100644 --- a/src/lib/hiro/win/menucheckitem.cpp +++ b/src/lib/hiro/win/menucheckitem.cpp @@ -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; diff --git a/src/lib/hiro/win/menugroup.cpp b/src/lib/hiro/win/menugroup.cpp index b1b4a2a7..87ea6c9e 100644 --- a/src/lib/hiro/win/menugroup.cpp +++ b/src/lib/hiro/win/menugroup.cpp @@ -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; } diff --git a/src/lib/hiro/win/menuradioitem.cpp b/src/lib/hiro/win/menuradioitem.cpp index 0b69f6b3..55ac65d1 100644 --- a/src/lib/hiro/win/menuradioitem.cpp +++ b/src/lib/hiro/win/menuradioitem.cpp @@ -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; diff --git a/src/lib/hiro/win/progressbar.cpp b/src/lib/hiro/win/progressbar.cpp index 171342db..772deec1 100644 --- a/src/lib/hiro/win/progressbar.cpp +++ b/src/lib/hiro/win/progressbar.cpp @@ -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)); diff --git a/src/lib/hiro/win/radiobox.cpp b/src/lib/hiro/win/radiobox.cpp index d776674d..32d6ac78 100644 --- a/src/lib/hiro/win/radiobox.cpp +++ b/src/lib/hiro/win/radiobox.cpp @@ -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() { diff --git a/src/lib/hiro/win/slider.cpp b/src/lib/hiro/win/slider.cpp index 81e1eb95..013f4959 100644 --- a/src/lib/hiro/win/slider.cpp +++ b/src/lib/hiro/win/slider.cpp @@ -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, diff --git a/src/lib/hiro/win/utf.cpp b/src/lib/hiro/win/utf.cpp new file mode 100644 index 00000000..aa1386ca --- /dev/null +++ b/src/lib/hiro/win/utf.cpp @@ -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; +}; diff --git a/src/lib/hiro/win/window.cpp b/src/lib/hiro/win/window.cpp index d7a70cc6..cbccd45f 100644 --- a/src/lib/hiro/win/window.cpp +++ b/src/lib/hiro/win/window.cpp @@ -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) { diff --git a/src/lib/libfilter/hq2x.cpp b/src/lib/libfilter/hq2x.cpp index 0418fdde..3076ae2e 100644 --- a/src/lib/libfilter/hq2x.cpp +++ b/src/lib/libfilter/hq2x.cpp @@ -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; diff --git a/src/lib/nall/dictionary.hpp b/src/lib/nall/dictionary.hpp new file mode 100644 index 00000000..2541442a --- /dev/null +++ b/src/lib/nall/dictionary.hpp @@ -0,0 +1,66 @@ +#ifndef NALL_DICTIONARY_HPP +#define NALL_DICTIONARY_HPP + +#include +#include +#include + +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 index_input; + array index_output; +}; + +} //namespace nall + +#endif //ifndef NALL_DICTIONARY_HPP diff --git a/src/lib/ruby/audio/alsa.cpp b/src/lib/ruby/audio/alsa.cpp new file mode 100644 index 00000000..bf988eff --- /dev/null +++ b/src/lib/ruby/audio/alsa.cpp @@ -0,0 +1,136 @@ +#include + +#include + +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 diff --git a/src/lib/ruby/audio/alsa.h b/src/lib/ruby/audio/alsa.h new file mode 100644 index 00000000..b6ca8509 --- /dev/null +++ b/src/lib/ruby/audio/alsa.h @@ -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; +}; diff --git a/src/lib/ruby/ruby.cpp b/src/lib/ruby/ruby.cpp index a05a1ad0..0790687b 100644 --- a/src/lib/ruby/ruby.cpp +++ b/src/lib/ruby/ruby.cpp @@ -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) diff --git a/src/lib/ruby/ruby.h b/src/lib/ruby/ruby.h index 9bf7f833..8841b4a8 100644 --- a/src/lib/ruby/ruby.h +++ b/src/lib/ruby/ruby.h @@ -1,6 +1,6 @@ /* ruby - version: 0.02 (2008-04-06) + version: 0.03 (2008-05-04) license: public domain */ diff --git a/src/lib/ruby/ruby_impl.cpp b/src/lib/ruby/ruby_impl.cpp index acca3dbd..af5dca12 100644 --- a/src/lib/ruby/ruby_impl.cpp +++ b/src/lib/ruby/ruby_impl.cpp @@ -30,6 +30,10 @@ /* Audio */ +#ifdef AUDIO_ALSA + #include +#endif + #ifdef AUDIO_AO #include #endif diff --git a/src/ppu/bppu/bppu.cpp b/src/ppu/bppu/bppu.cpp index a864d66c..d0267099 100644 --- a/src/ppu/bppu/bppu.cpp +++ b/src/ppu/bppu/bppu.cpp @@ -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; } diff --git a/src/reader/filereader.cpp b/src/reader/filereader.cpp index 62b19c72..a1342db8 100644 --- a/src/reader/filereader.cpp +++ b/src/reader/filereader.cpp @@ -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 diff --git a/src/reader/filereader.h b/src/reader/filereader.h index a04f1385..c8f6df43 100644 --- a/src/reader/filereader.h +++ b/src/reader/filereader.h @@ -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; }; diff --git a/src/reader/gzreader.cpp b/src/reader/gzreader.cpp index cae1f5ee..8b04b60f 100644 --- a/src/reader/gzreader.cpp +++ b/src/reader/gzreader.cpp @@ -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; diff --git a/src/reader/jmareader.cpp b/src/reader/jmareader.cpp index 13fff44e..6d7ed3c5 100644 --- a/src/reader/jmareader.cpp +++ b/src/reader/jmareader.cpp @@ -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); } diff --git a/src/reader/reader.h b/src/reader/reader.h index e2af7bc1..1dd19448 100644 --- a/src/reader/reader.h +++ b/src/reader/reader.h @@ -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; } -}; diff --git a/src/reader/zipreader.cpp b/src/reader/zipreader.cpp index 140ae1e0..ca07ade1 100644 --- a/src/reader/zipreader.cpp +++ b/src/reader/zipreader.cpp @@ -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); } diff --git a/src/smp/smpregs.h b/src/smp/smpregs.h index 587cc35b..e9a35588 100644 --- a/src/smp/smpregs.h +++ b/src/smp/smpregs.h @@ -1,19 +1,32 @@ +template +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 inline unsigned operator = (const T i) { data = i; return data; } - template inline unsigned operator |= (const T i) { data |= i; return data; } - template inline unsigned operator ^= (const T i) { data ^= i; return data; } - template 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) {} }; diff --git a/src/smp/ssmp/core/op_misc.b b/src/smp/ssmp/core/op_misc.b index 2829c7ee..a6baba95 100644 --- a/src/smp/ssmp/core/op_misc.b +++ b/src/smp/ssmp/core/op_misc.b @@ -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), diff --git a/src/smp/ssmp/core/op_misc.cpp b/src/smp/ssmp/core/op_misc.cpp index a1c754d8..eb4360a9 100644 --- a/src/smp/ssmp/core/op_misc.cpp +++ b/src/smp/ssmp/core/op_misc.cpp @@ -93,7 +93,7 @@ case 0xe0: { case 0xed: { op_io(); op_io(); - regs.p.c ^= 1; + regs.p.c = !regs.p.c; } break; //ei diff --git a/src/smp/ssmp/core/opfn.cpp b/src/smp/ssmp/core/opfn.cpp index c6027901..8e9b3ead 100644 --- a/src/smp/ssmp/core/opfn.cpp +++ b/src/smp/ssmp/core/opfn.cpp @@ -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; } diff --git a/src/snes/tracer/tracer.cpp b/src/snes/tracer/tracer.cpp index 4f7f1bc9..1c1989a9 100644 --- a/src/snes/tracer/tracer.cpp +++ b/src/snes/tracer/tracer.cpp @@ -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; diff --git a/src/ui/base/about.cpp b/src/ui/base/about.cpp index ff8256f3..c020f69c 100644 --- a/src/ui/base/about.cpp +++ b/src/ui/base/about.cpp @@ -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; } diff --git a/src/ui/base/main.cpp b/src/ui/base/main.cpp index adbd057d..1ba77b72 100644 --- a/src/ui/base/main.cpp +++ b/src/ui/base/main.cpp @@ -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; } diff --git a/src/ui/base/main.h b/src/ui/base/main.h index 412759a2..0117a4a3 100644 --- a/src/ui/base/main.h +++ b/src/ui/base/main.h @@ -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); diff --git a/src/ui/base/message.cpp b/src/ui/base/message.cpp index a8b213bb..bbbbea5d 100644 --- a/src/ui/base/message.cpp +++ b/src/ui/base/message.cpp @@ -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(); } diff --git a/src/ui/config.cpp b/src/ui/config.cpp index 2c3008b2..fbd1e094 100644 --- a/src/ui/config.cpp +++ b/src/ui/config.cpp @@ -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 diff --git a/src/ui/event.cpp b/src/ui/event.cpp index f606f883..9581f8be 100644 --- a/src/ui/event.cpp +++ b/src/ui/event.cpp @@ -12,6 +12,19 @@ void keydown(uint16_t key) { } if(key == input_manager.gui.reset) reset(); if(key == input_manager.gui.power) power(); + if(key == input_manager.gui.quit) quit(); + if(key == input_manager.gui.speed_decrease) { + update_emulation_speed(config::system.emulation_speed - 1); + } + if(key == input_manager.gui.speed_increase) { + update_emulation_speed(config::system.emulation_speed + 1); + } + if(key == input_manager.gui.frameskip_decrease) { + update_frameskip(config::video.frameskip - 1); + } + if(key == input_manager.gui.frameskip_increase) { + update_frameskip(config::video.frameskip + 1); + } if(key == input_manager.gui.toggle_fullscreen) toggle_fullscreen(); if(key == input_manager.gui.toggle_menubar) toggle_menubar(); if(key == input_manager.gui.toggle_statusbar) toggle_statusbar(); @@ -99,25 +112,30 @@ void update_software_filter(uint software_filter) { update_video_settings(); } -void update_speed_regulation(uint speed) { - config::system.speed_regulation = speed <= 5 ? speed : 0; +void update_frameskip(int speed) { + config::video.frameskip = max(0, min(9, speed)); + window_main.sync(); +} + +void update_emulation_speed(int speed) { + config::system.emulation_speed = max(0, min(5, speed)); //adjust audio frequency to match selected speed setting if(audio.cap(Audio::Frequency)) { - switch(config::system.speed_regulation) { - case 0: audio.set(Audio::Frequency, 32000); break; //disabled - case 1: audio.set(Audio::Frequency, 16000); break; //slowest (50%) - case 2: audio.set(Audio::Frequency, 24000); break; //slow (75%) - case 3: audio.set(Audio::Frequency, 32000); break; //normal (100%) - case 4: audio.set(Audio::Frequency, 48000); break; //fast (150%) - case 5: audio.set(Audio::Frequency, 64000); break; //fastest (200%) + switch(config::system.emulation_speed) { + case 0: audio.set(Audio::Frequency, 16000); break; //slowest (50%) + case 1: audio.set(Audio::Frequency, 24000); break; //slow (75%) + case 2: audio.set(Audio::Frequency, 32000); break; //normal (100%) + case 3: audio.set(Audio::Frequency, 48000); break; //fast (150%) + case 4: audio.set(Audio::Frequency, 64000); break; //fastest (200%) + case 5: audio.set(Audio::Frequency, 32000); break; //disabled } } //do not regulate speed when speed regulation is disabled - if(audio.cap(Audio::Synchronize)) { - audio.set(Audio::Synchronize, config::system.speed_regulation != 0); - } + audio.set(Audio::Synchronize, config::system.emulation_speed != 5); + + window_main.sync(); } void update_status() { @@ -129,13 +147,13 @@ void update_status() { ppu.status.frames_updated = false; unsigned max_framerate = snes.region() == SNES::NTSC ? 60 : 50; - switch(config::system.speed_regulation) { - case 0: max_framerate = 0; break; - case 1: max_framerate = unsigned(0.50 * max_framerate); break; - case 2: max_framerate = unsigned(0.75 * max_framerate); break; - case 3: break; - case 4: max_framerate = unsigned(1.50 * max_framerate); break; - case 5: max_framerate = unsigned(2.00 * max_framerate); break; + switch(config::system.emulation_speed) { + case 0: max_framerate = unsigned(0.50 * max_framerate); break; + case 1: max_framerate = unsigned(0.75 * max_framerate); break; + case 2: break; + case 3: max_framerate = unsigned(1.50 * max_framerate); break; + case 4: max_framerate = unsigned(2.00 * max_framerate); break; + case 5: max_framerate = 0; break; } string output = (const char*)config::misc.status_text; @@ -212,7 +230,7 @@ void update_video_settings() { video.set(Video::Filter, video_settings.hardware_filter); //update main window video mode checkbox settings - window_main.update_menu_settings(); + window_main.sync(); } void update_opacity() { @@ -243,7 +261,8 @@ void toggle_menubar() { } void toggle_statusbar() { - window_main.status.show(!window_main.status.visible()); + config::misc.status_enable = !window_main.status.visible(); + window_main.status.show(config::misc.status_enable); update_video_settings(); } @@ -291,15 +310,20 @@ void load_cart_normal(const char *filename) { if(cartridge.loaded() == true) cartridge.unload(); cartridge.load_cart_normal(filename); -//warn if unsupported hardware detected - if(cartridge.info.superfx) alert("Warning: unsupported SuperFX chip detected."); - if(cartridge.info.sa1) alert("Warning: unsupported SA-1 chip detected."); - if(cartridge.info.spc7110) alert("Warning: unsupported SPC7110 chip detected."); - if(cartridge.info.st011) alert("Warning: unsupported ST011 chip detected."); - if(cartridge.info.st018) alert("Warning: unsupported ST018 chip detected."); + //warn if unsupported hardware detected + string message = translate["Unsupported $ chip detected."]; + const char *name; + if(cartridge.info.superfx) { name = "SuperFX"; replace(message, "$", name); alert(message); } + if(cartridge.info.sa1) { name = "SA-1"; replace(message, "$", name); alert(message); } + if(cartridge.info.spc7110) { name = "SPC7110"; replace(message, "$", name); alert(message); } + if(cartridge.info.st011) { name = "ST011"; replace(message, "$", name); alert(message); } + if(cartridge.info.st018) { name = "ST018"; replace(message, "$", name); alert(message); } app.pause = false; snes.power(); + window_main.menu_file_unload.enable(); + window_main.menu_file_reset.enable(); + window_main.menu_file_power.enable(); window_cheat_editor.refresh(); } @@ -311,6 +335,9 @@ void load_cart_bsx(const char *base, const char *slot) { app.pause = false; snes.power(); + window_main.menu_file_unload.enable(); + window_main.menu_file_reset.enable(); + window_main.menu_file_power.enable(); window_cheat_editor.refresh(); } @@ -322,6 +349,9 @@ void load_cart_bsc(const char *base, const char *slot) { app.pause = false; snes.power(); + window_main.menu_file_unload.enable(); + window_main.menu_file_reset.enable(); + window_main.menu_file_power.enable(); window_cheat_editor.refresh(); } @@ -333,6 +363,9 @@ void load_cart_st(const char *base, const char *slotA, const char *slotB) { app.pause = false; snes.power(); + window_main.menu_file_unload.enable(); + window_main.menu_file_reset.enable(); + window_main.menu_file_power.enable(); window_cheat_editor.refresh(); } @@ -343,6 +376,9 @@ void unload_rom() { audio.clear(); } event::update_status(); + window_main.menu_file_unload.disable(); + window_main.menu_file_reset.disable(); + window_main.menu_file_power.disable(); window_cheat_editor.refresh(); } @@ -360,4 +396,14 @@ void power() { } } +void quit() { + app.term = true; + window_about.hide(); + window_message.hide(); + window_settings.hide(); + window_bsxloader.hide(); + window_stloader.hide(); + window_main.hide(); +} + }; diff --git a/src/ui/event.h b/src/ui/event.h index 29b080bb..ccba6afa 100644 --- a/src/ui/event.h +++ b/src/ui/event.h @@ -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 diff --git a/src/ui/inputmanager.cpp b/src/ui/inputmanager.cpp index f11be3ab..a3ceacc1 100644 --- a/src/ui/inputmanager.cpp +++ b/src/ui/inputmanager.cpp @@ -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() { diff --git a/src/ui/loader/bsxloader.cpp b/src/ui/loader/bsxloader.cpp index 5cf85b14..eff143cd 100644 --- a/src/ui/loader/bsxloader.cpp +++ b/src/ui/loader/bsxloader.cpp @@ -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); diff --git a/src/ui/loader/stloader.cpp b/src/ui/loader/stloader.cpp index 73bed7ff..29347ff5 100644 --- a/src/ui/loader/stloader.cpp +++ b/src/ui/loader/stloader.cpp @@ -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); diff --git a/src/ui/main.cpp b/src/ui/main.cpp index a4d61fb0..384a0bc4 100644 --- a/src/ui/main.cpp +++ b/src/ui/main.cpp @@ -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(); diff --git a/src/ui/settings/advanced.cpp b/src/ui/settings/advanced.cpp index b152cd6b..f1701ca4 100644 --- a/src/ui/settings/advanced.cpp +++ b/src/ui/settings/advanced.cpp @@ -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, ""); - 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[""]); + edit_val.create(0, 265, 25, translate[""]); + 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(); diff --git a/src/ui/settings/cheateditor.cpp b/src/ui/settings/cheateditor.cpp index dee76f63..f1c99c3b 100644 --- a/src/ui/settings/cheateditor.cpp +++ b/src/ui/settings/cheateditor.cpp @@ -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, ""); - desc.create(0, 315, 30, ""); + 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[""]); + desc.create(0, 315, 25, translate[""]); 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); } diff --git a/src/ui/settings/inputconfig.cpp b/src/ui/settings/inputconfig.cpp index 6473245d..384d25d0 100644 --- a/src/ui/settings/inputconfig.cpp +++ b/src/ui/settings/inputconfig.cpp @@ -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(); } diff --git a/src/ui/settings/inputconfig.h b/src/ui/settings/inputconfig.h index 3efcca91..48fd2105 100644 --- a/src/ui/settings/inputconfig.h +++ b/src/ui/settings/inputconfig.h @@ -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; diff --git a/src/ui/settings/pathsettings.cpp b/src/ui/settings/pathsettings.cpp index 10100684..c2230561 100644 --- a/src/ui/settings/pathsettings.cpp +++ b/src/ui/settings/pathsettings.cpp @@ -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); diff --git a/src/ui/settings/settings.cpp b/src/ui/settings/settings.cpp index b738cde7..2bfede35 100644 --- a/src/ui/settings/settings.cpp +++ b/src/ui/settings/settings.cpp @@ -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(); diff --git a/src/ui/settings/rastersettings.cpp b/src/ui/settings/videosettings.cpp similarity index 56% rename from src/ui/settings/rastersettings.cpp rename to src/ui/settings/videosettings.cpp index c077564e..89992364 100644 --- a/src/ui/settings/rastersettings.cpp +++ b/src/ui/settings/videosettings.cpp @@ -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; } diff --git a/src/ui/settings/rastersettings.h b/src/ui/settings/videosettings.h similarity index 82% rename from src/ui/settings/rastersettings.h rename to src/ui/settings/videosettings.h index 9d924efd..b1d0ef9e 100644 --- a/src/ui/settings/rastersettings.h +++ b/src/ui/settings/videosettings.h @@ -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; diff --git a/src/ui/ui.cpp b/src/ui/ui.cpp index 045ec5d5..6deb005f 100644 --- a/src/ui/ui.cpp +++ b/src/ui/ui.cpp @@ -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()); diff --git a/src/ui/ui.h b/src/ui/ui.h index eaef0074..7a4c731c 100644 --- a/src/ui/ui.h +++ b/src/ui/ui.h @@ -1,5 +1,8 @@ -#include -#include +#include +#include +#include + +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"