From 0c3f0834abccff7db53c1c38f9d28306d7eeca39 Mon Sep 17 00:00:00 2001 From: Tim Allen Date: Sun, 7 Aug 2011 00:03:52 +1000 Subject: [PATCH] Update to v080r05 release. byuu says: Includes updated versions of nall and phoenix, which mostly improves the GTK+ version. However, it appears to be crashing at the moment after loading a game. Unfortunately it works when gdb is used, so I can't easily debug it :/ You can now build with make phoenix=gtk if you want the GTK+ version on Linux (the Qt version is leagues better even on Gnome, please use it if at all possible.) There's also settings.startFullScreen, config-file only, to allow for front-end use. Forgot to add the reset/power hotkeys. I also fixed compilation of ui-gameboy on GCC 4.6. I hope that's the last switch(enum) error, those are damn annoying. Can't wait to switch to GCC 4.6 on Windows. --- bsnes/Makefile | 3 +- bsnes/nall/bmp.hpp | 101 +++++ bsnes/nall/directory.hpp | 2 +- bsnes/nall/file.hpp | 20 +- bsnes/nall/filemap.hpp | 2 +- bsnes/nall/gzip.hpp | 87 ++++ bsnes/nall/http.hpp | 23 +- bsnes/nall/inflate.hpp | 3 +- bsnes/nall/platform.hpp | 4 +- bsnes/nall/png.hpp | 423 ++++++++++++++++++ bsnes/nall/resource.hpp | 4 +- bsnes/nall/string/base.hpp | 73 +-- bsnes/nall/string/compare.hpp | 39 +- bsnes/nall/string/replace.hpp | 123 ++--- bsnes/nall/string/split.hpp | 62 +-- bsnes/nall/string/strpos.hpp | 41 +- bsnes/nall/string/trim.hpp | 3 +- bsnes/nall/string/utility.hpp | 154 +++---- bsnes/nall/string/wrapper.hpp | 11 +- bsnes/nall/{ => windows}/utf8.hpp | 0 bsnes/nall/{unzip.hpp => zip.hpp} | 6 +- bsnes/phoenix/core/core.cpp | 14 +- bsnes/phoenix/core/core.hpp | 38 +- bsnes/phoenix/core/state.hpp | 30 +- bsnes/phoenix/gtk/gtk.cpp | 2 + bsnes/phoenix/gtk/gtk.hpp | 32 +- bsnes/phoenix/gtk/widget/canvas.cpp | 49 +- bsnes/phoenix/gtk/widget/combo-box.cpp | 4 +- bsnes/phoenix/gtk/widget/hex-edit.cpp | 12 +- .../gtk/widget/horizontal-scroll-bar.cpp | 29 ++ .../phoenix/gtk/widget/horizontal-slider.cpp | 2 + bsnes/phoenix/gtk/widget/line-edit.cpp | 2 +- .../gtk/widget/vertical-scroll-bar.cpp | 29 ++ bsnes/phoenix/gtk/widget/vertical-slider.cpp | 2 + bsnes/phoenix/gtk/widget/viewport.cpp | 2 +- bsnes/phoenix/gtk/window.cpp | 107 ++--- bsnes/phoenix/phoenix.cpp | 1 + bsnes/phoenix/qt/qt.cpp | 2 + bsnes/phoenix/qt/qt.moc | 124 ++++- bsnes/phoenix/qt/qt.moc.hpp | 41 +- .../qt/widget/horizontal-scroll-bar.cpp | 29 ++ .../phoenix/qt/widget/vertical-scroll-bar.cpp | 29 ++ bsnes/phoenix/qt/window.cpp | 10 +- bsnes/phoenix/reference/reference.cpp | 2 + bsnes/phoenix/reference/reference.hpp | 25 +- .../widget/horizontal-scroll-bar.cpp | 12 + .../reference/widget/vertical-scroll-bar.cpp | 12 + bsnes/phoenix/reference/window.cpp | 6 +- bsnes/phoenix/sync.sh | 1 + .../windows/widget/horizontal-scroll-bar.cpp | 32 ++ .../windows/widget/vertical-scroll-bar.cpp | 32 ++ .../windows/widget/vertical-slider.cpp | 2 +- bsnes/phoenix/windows/window.cpp | 23 +- bsnes/phoenix/windows/windows.cpp | 61 ++- bsnes/phoenix/windows/windows.hpp | 29 +- bsnes/snes/snes.hpp | 2 +- bsnes/ui-gameboy/Makefile | 12 +- bsnes/ui-gameboy/interface.cpp | 2 +- bsnes/ui/Makefile | 12 +- bsnes/ui/config.cpp | 1 + bsnes/ui/config.hpp | 1 + bsnes/ui/general/about-window.cpp | 2 +- bsnes/ui/general/main-window.cpp | 2 +- bsnes/ui/input/hotkeys.cpp | 2 +- bsnes/ui/main.cpp | 1 + bsnes/ui/tools/cheat-editor.cpp | 2 +- bsnes/ui/tools/state-manager.cpp | 2 +- bsnes/ui/utility/utility.cpp | 14 +- bsnes/ui/utility/utility.hpp | 4 +- 69 files changed, 1579 insertions(+), 491 deletions(-) create mode 100755 bsnes/nall/bmp.hpp create mode 100755 bsnes/nall/gzip.hpp create mode 100755 bsnes/nall/png.hpp rename bsnes/nall/{ => windows}/utf8.hpp (100%) rename bsnes/nall/{unzip.hpp => zip.hpp} (97%) create mode 100755 bsnes/phoenix/gtk/widget/horizontal-scroll-bar.cpp create mode 100755 bsnes/phoenix/gtk/widget/vertical-scroll-bar.cpp create mode 100755 bsnes/phoenix/qt/widget/horizontal-scroll-bar.cpp create mode 100755 bsnes/phoenix/qt/widget/vertical-scroll-bar.cpp create mode 100755 bsnes/phoenix/reference/widget/horizontal-scroll-bar.cpp create mode 100755 bsnes/phoenix/reference/widget/vertical-scroll-bar.cpp create mode 100755 bsnes/phoenix/windows/widget/horizontal-scroll-bar.cpp create mode 100755 bsnes/phoenix/windows/widget/vertical-scroll-bar.cpp diff --git a/bsnes/Makefile b/bsnes/Makefile index 4af87086..5f7140cb 100755 --- a/bsnes/Makefile +++ b/bsnes/Makefile @@ -3,9 +3,10 @@ snes := snes gameboy := gameboy profile := accuracy ui := ui +# phoenix := gtk -# debugger options := +# debugger # compiler c := $(compiler) -std=gnu99 diff --git a/bsnes/nall/bmp.hpp b/bsnes/nall/bmp.hpp new file mode 100755 index 00000000..f66cd753 --- /dev/null +++ b/bsnes/nall/bmp.hpp @@ -0,0 +1,101 @@ +#ifndef NALL_BMP_HPP +#define NALL_BMP_HPP + +#include + +//BMP reader / writer +//author: byuu +//note: only 24-bit RGB and 32-bit ARGB uncompressed images supported + +namespace nall { + +struct bmp { + static bool read(const string &filename, uint32_t *&data, unsigned &width, unsigned &height); + static bool write(const string &filename, const uint32_t *data, unsigned width, unsigned height, bool alpha = false); +}; + +bool bmp::read(const string &filename, uint32_t *&data, unsigned &width, unsigned &height) { + file fp; + if(fp.open(filename, file::mode::read) == false) return false; + if(fp.size() < 0x36) return false; + + if(fp.readm(2) != 0x424d) return false; + fp.seek(0x000a); + unsigned offset = fp.readl(4); + unsigned dibsize = fp.readl(4); + if(dibsize != 40) return false; + signed headerWidth = fp.readl(4); + if(headerWidth < 0) return false; + signed headerHeight = fp.readl(4); + fp.readl(2); + unsigned bitsPerPixel = fp.readl(2); + if(bitsPerPixel != 24 && bitsPerPixel != 32) return false; + unsigned compression = fp.readl(4); + if(compression != 0) return false; + fp.seek(offset); + + bool noFlip = headerHeight < 0; + width = headerWidth, height = abs(headerHeight); + data = new uint32_t[width * height]; + + unsigned bytesPerPixel = bitsPerPixel / 8; + unsigned alignedWidth = width * bytesPerPixel; + unsigned paddingLength = 0; + while(alignedWidth % 4) alignedWidth++, paddingLength++; + + for(unsigned y = 0; y < height; y++) { + uint32_t *p = noFlip ? data + y * width : data + (height - 1 - y) * width; + for(unsigned x = 0; x < width; x++, p++) { + *p = fp.readl(bytesPerPixel); + if(bytesPerPixel == 3) *p |= 255 << 24; + } + if(paddingLength) fp.readl(paddingLength); + } + + fp.close(); + return true; +} + +bool bmp::write(const string &filename, const uint32_t *data, unsigned width, unsigned height, bool alpha) { + file fp; + if(fp.open(filename, file::mode::write) == false) return false; + + unsigned bitsPerPixel = alpha ? 32 : 24; + unsigned bytesPerPixel = bitsPerPixel / 8; + unsigned alignedWidth = width * bytesPerPixel; + unsigned paddingLength = 0; + unsigned imageSize = alignedWidth * height; + unsigned fileSize = 0x36 + imageSize; + while(alignedWidth % 4) alignedWidth++, paddingLength++; + + fp.writem(0x424d, 2); //signature + fp.writel(fileSize, 4); //file size + fp.writel(0, 2); //reserved + fp.writel(0, 2); //reserved + fp.writel(0x36, 4); //offset + + fp.writel(40, 4); //DIB size + fp.writel(width, 4); //width + fp.writel(-height, 4); //height + fp.writel(1, 2); //color planes + fp.writel(bitsPerPixel, 2); //bits per pixel + fp.writel(0, 4); //compression method (BI_RGB) + fp.writel(imageSize, 4); //image data size + fp.writel(3780, 4); //horizontal resolution + fp.writel(3780, 4); //vertical resolution + fp.writel(0, 4); //palette size + fp.writel(0, 4); //important color count + + for(unsigned y = 0; y < height; y++) { + const uint32_t *p = data + y * width; + for(unsigned x = 0; x < width; x++) fp.writel(*p++, bytesPerPixel); + if(paddingLength) fp.writel(0, paddingLength); + } + + fp.close(); + return true; +} + +} + +#endif diff --git a/bsnes/nall/directory.hpp b/bsnes/nall/directory.hpp index 4d3bcba5..7fbc15f4 100755 --- a/bsnes/nall/directory.hpp +++ b/bsnes/nall/directory.hpp @@ -6,7 +6,7 @@ #include #if defined(_WIN32) - #include + #include #else #include #include diff --git a/bsnes/nall/file.hpp b/bsnes/nall/file.hpp index 1d40cf65..4b9f76b4 100755 --- a/bsnes/nall/file.hpp +++ b/bsnes/nall/file.hpp @@ -4,8 +4,8 @@ #include #include #include -#include #include +#include namespace nall { inline FILE* fopen_utf8(const string &utf8_filename, const char *mode) { @@ -22,6 +22,24 @@ namespace nall { enum class index : unsigned { absolute, relative }; enum class time : unsigned { create, modify, access }; + static bool read(const string &filename, uint8_t *&data, unsigned &size) { + file fp; + if(fp.open(filename, mode::read) == false) return false; + size = fp.size(); + data = new uint8_t[size]; + fp.read(data, size); + fp.close(); + return true; + } + + static bool write(const string &filename, const uint8_t *data, unsigned size) { + file fp; + if(fp.open(filename, mode::write) == false) return false; + fp.write(data, size); + fp.close(); + return true; + } + uint8_t read() { if(!fp) return 0xff; //file not open if(file_mode == mode::write) return 0xff; //reads not permitted diff --git a/bsnes/nall/filemap.hpp b/bsnes/nall/filemap.hpp index 5e8cc059..f04ec899 100755 --- a/bsnes/nall/filemap.hpp +++ b/bsnes/nall/filemap.hpp @@ -2,7 +2,7 @@ #define NALL_FILEMAP_HPP #include -#include +#include #include #include diff --git a/bsnes/nall/gzip.hpp b/bsnes/nall/gzip.hpp new file mode 100755 index 00000000..635d3277 --- /dev/null +++ b/bsnes/nall/gzip.hpp @@ -0,0 +1,87 @@ +#ifndef NALL_GZIP_HPP +#define NALL_GZIP_HPP + +#include +#include + +namespace nall { + +struct gzip { + string filename; + uint8_t *data; + unsigned size; + + bool decompress(const string &filename); + bool decompress(const uint8_t *data, unsigned size); + + gzip(); + ~gzip(); +}; + +bool gzip::decompress(const string &filename) { + uint8_t *data; + unsigned size; + if(file::read(filename, data, size) == false) return false; + bool result = decompress(data, size); + delete[] data; + return result; +} + +bool gzip::decompress(const uint8_t *data, unsigned size) { + if(size < 18) return false; + if(data[0] != 0x1f) return false; + if(data[1] != 0x8b) return false; + unsigned cm = data[2]; + unsigned flg = data[3]; + unsigned mtime = data[4]; + mtime |= data[5] << 8; + mtime |= data[6] << 16; + mtime |= data[7] << 24; + unsigned xfl = data[8]; + unsigned os = data[9]; + unsigned p = 10; + unsigned isize = data[size - 4]; + isize |= data[size - 3] << 8; + isize |= data[size - 2] << 16; + isize |= data[size - 1] << 24; + filename = ""; + + if(flg & 0x04) { //FEXTRA + unsigned xlen = data[p + 0]; + xlen |= data[p + 1] << 8; + p += 2 + xlen; + } + + if(flg & 0x08) { //FNAME + char buffer[PATH_MAX]; + for(unsigned n = 0; n < PATH_MAX; n++, p++) { + buffer[n] = data[p]; + if(data[p] == 0) break; + } + if(data[p++]) return false; + filename = buffer; + } + + if(flg & 0x10) { //FCOMMENT + while(data[p++]); + } + + if(flg & 0x02) { //FHCRC + p += 2; + } + + this->size = isize; + this->data = new uint8_t[this->size]; + return inflate(this->data, this->size, data + p, size - p - 8); +} + +gzip::gzip() : data(0) { +} + +gzip::~gzip() { + if(data) delete[] data; +} + +} + +#endif diff --git a/bsnes/nall/http.hpp b/bsnes/nall/http.hpp index bef4954e..5fc9737f 100755 --- a/bsnes/nall/http.hpp +++ b/bsnes/nall/http.hpp @@ -28,9 +28,10 @@ struct http { size = 0; send({ - "GET ", path, " HTTP/1.1\n" - "Host: ", hostname, "\n" - "\n" + "GET ", path, " HTTP/1.1\r\n" + "Host: ", hostname, "\r\n" + "Connection: close\r\n" + "\r\n" }); header = downloadHeader(); @@ -99,7 +100,7 @@ struct http { inline void downloadContent(uint8_t *&data, unsigned &size) { unsigned capacity = 0; - if(header.position("Transfer-Encoding: chunked")) { + if(header.iposition("\r\nTransfer-Encoding: chunked\r\n")) { while(true) { unsigned length = hex(downloadChunkLength()); if(length == 0) break; @@ -115,7 +116,7 @@ struct http { length -= packetlength; } } - } else if(auto position = header.position("Content-Length: ")) { + } else if(auto position = header.iposition("\r\nContent-Length: ")) { unsigned length = decimal((const char*)header + position() + 16); while(length) { char buffer[256]; @@ -150,8 +151,12 @@ struct http { serversocket = -1; } + #ifdef _WIN32 + inline int close(int sock) { + return closesocket(sock); + } + inline http() { - #ifdef _WIN32 int sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); if(sock == INVALID_SOCKET && WSAGetLastError() == WSANOTINITIALISED) { WSADATA wsaData; @@ -159,9 +164,11 @@ struct http { WSACleanup(); return; } - } else close(sock); - #endif + } else { + close(sock); + } } + #endif }; } diff --git a/bsnes/nall/inflate.hpp b/bsnes/nall/inflate.hpp index 6fa1012a..c989e3f1 100755 --- a/bsnes/nall/inflate.hpp +++ b/bsnes/nall/inflate.hpp @@ -17,7 +17,8 @@ inline bool inflate( const uint8_t *source, unsigned sourceLength ) { unsigned long tl = targetLength, sl = sourceLength; - return puff::puff((unsigned char*)target, &tl, (unsigned char*)source, &sl) == 0; + int result = puff::puff((unsigned char*)target, &tl, (unsigned char*)source, &sl); + return result == 0; } namespace puff { diff --git a/bsnes/nall/platform.hpp b/bsnes/nall/platform.hpp index 4eb5d8ad..5c226e3e 100755 --- a/bsnes/nall/platform.hpp +++ b/bsnes/nall/platform.hpp @@ -5,10 +5,9 @@ //minimum version needed for _wstat64, etc #undef __MSVCRT_VERSION__ #define __MSVCRT_VERSION__ 0x0601 + #include #endif -#include - //========================= //standard platform headers //========================= @@ -67,7 +66,6 @@ #define rmdir _rmdir #define usleep(n) Sleep(n / 1000) #define vsnprintf _vsnprintf - static int close(int sock) { return closesocket(sock); } #endif //================ diff --git a/bsnes/nall/png.hpp b/bsnes/nall/png.hpp new file mode 100755 index 00000000..998489a1 --- /dev/null +++ b/bsnes/nall/png.hpp @@ -0,0 +1,423 @@ +#ifndef NALL_PNG_HPP +#define NALL_PNG_HPP + +//PNG image decoder +//author: byuu + +#include +#include + +namespace nall { + +struct png { + uint32_t *data; + unsigned size; + + struct Info { + unsigned width; + unsigned height; + unsigned bitDepth; + unsigned colorType; + unsigned compressionMethod; + unsigned filterType; + unsigned interlaceMethod; + + unsigned bytesPerPixel; + unsigned pitch; + + uint8_t palette[256][3]; + } info; + + uint8_t *rawData; + unsigned rawSize; + + inline bool decode(const string &filename); + inline bool decode(const uint8_t *sourceData, unsigned sourceSize); + inline void transform(); + inline void alphaTransform(uint32_t rgb = 0xffffff); + png(); + ~png(); + +protected: + enum class FourCC : unsigned { + IHDR = 0x49484452, + PLTE = 0x504c5445, + IDAT = 0x49444154, + IEND = 0x49454e44, + }; + + static const unsigned interlace[7][4]; + unsigned bitpos; + + inline unsigned inflateSize(); + inline bool deinterlace(const uint8_t *&inputData, unsigned pass); + inline bool filter(uint8_t *outputData, const uint8_t *inputData, unsigned width, unsigned height); + inline unsigned read(const uint8_t *data, unsigned length); + inline unsigned decode(const uint8_t *&data); + inline unsigned readbits(const uint8_t *&data); + inline unsigned scale(unsigned n); +}; + +bool png::decode(const string &filename) { + uint8_t *data; + unsigned size; + if(file::read(filename, data, size) == false) return false; + bool result = decode(data, size); + delete[] data; + return result; +} + +bool png::decode(const uint8_t *sourceData, unsigned sourceSize) { + if(sourceSize < 8) return false; + if(read(sourceData + 0, 4) != 0x89504e47) return false; + if(read(sourceData + 4, 4) != 0x0d0a1a0a) return false; + + uint8_t *compressedData = 0; + unsigned compressedSize = 0; + + unsigned offset = 8; + while(offset < sourceSize) { + unsigned length = read(sourceData + offset + 0, 4); + unsigned fourCC = read(sourceData + offset + 4, 4); + unsigned checksum = read(sourceData + offset + 8 + length, 4); + + if(fourCC == (unsigned)FourCC::IHDR) { + info.width = read(sourceData + offset + 8, 4); + info.height = read(sourceData + offset + 12, 4); + info.bitDepth = read(sourceData + offset + 16, 1); + info.colorType = read(sourceData + offset + 17, 1); + info.compressionMethod = read(sourceData + offset + 18, 1); + info.filterType = read(sourceData + offset + 19, 1); + info.interlaceMethod = read(sourceData + offset + 20, 1); + + if(info.bitDepth == 0 || info.bitDepth > 16) return false; + if(info.bitDepth & (info.bitDepth - 1)) return false; //not a power of two + if(info.compressionMethod != 0) return false; + if(info.filterType != 0) return false; + if(info.interlaceMethod != 0 && info.interlaceMethod != 1) return false; + + switch(info.colorType) { + case 0: info.bytesPerPixel = info.bitDepth * 1; break; //L + case 2: info.bytesPerPixel = info.bitDepth * 3; break; //R,G,B + case 3: info.bytesPerPixel = info.bitDepth * 1; break; //P + case 4: info.bytesPerPixel = info.bitDepth * 2; break; //L,A + case 6: info.bytesPerPixel = info.bitDepth * 4; break; //R,G,B,A + default: return false; + } + + if(info.colorType == 2 || info.colorType == 4 || info.colorType == 6) + if(info.bitDepth != 8 && info.bitDepth != 16) return false; + if(info.colorType == 3 && info.bitDepth == 16) return false; + + info.bytesPerPixel = (info.bytesPerPixel + 7) / 8; + info.pitch = (int)info.width * info.bytesPerPixel; + } + + if(fourCC == (unsigned)FourCC::PLTE) { + if(length % 3) return false; + for(unsigned n = 0, p = offset + 8; n < length / 3; n++) { + info.palette[n][0] = sourceData[p++]; + info.palette[n][1] = sourceData[p++]; + info.palette[n][2] = sourceData[p++]; + } + } + + if(fourCC == (unsigned)FourCC::IDAT) { + compressedData = (uint8_t*)realloc(compressedData, compressedSize + length); + memcpy(compressedData + compressedSize, sourceData + offset + 8, length); + compressedSize += length; + } + + if(fourCC == (unsigned)FourCC::IEND) { + break; + } + + offset += 4 + 4 + length + 4; + } + + unsigned interlacedSize = inflateSize(); + uint8_t *interlacedData = new uint8_t[interlacedSize]; + + bool result = inflate(interlacedData, interlacedSize, compressedData + 2, compressedSize - 6); + delete[] compressedData; + + if(result == false) { + delete[] interlacedData; + return false; + } + + rawSize = info.width * info.height * info.bytesPerPixel; + rawData = new uint8_t[rawSize]; + + if(info.interlaceMethod == 0) { + if(filter(rawData, interlacedData, info.width, info.height) == false) { + delete[] interlacedData; + delete[] rawData; + rawData = 0; + return false; + } + } else { + const uint8_t *passData = interlacedData; + for(unsigned pass = 0; pass < 7; pass++) { + if(deinterlace(passData, pass) == false) { + delete[] interlacedData; + delete[] rawData; + rawData = 0; + return false; + } + } + } + + delete[] interlacedData; + return true; +} + +const unsigned png::interlace[7][4] = { + //x-distance, y-distance, x-origin, y-origin + { 8, 8, 0, 0 }, + { 8, 8, 4, 0 }, + { 4, 8, 0, 4 }, + { 4, 4, 2, 0 }, + { 2, 4, 0, 2 }, + { 2, 2, 1, 0 }, + { 1, 2, 0, 1 }, +}; + +unsigned png::inflateSize() { + if(info.interlaceMethod == 0) { + return info.width * info.height * info.bytesPerPixel + info.height; + } + + unsigned size = 0; + for(unsigned pass = 0; pass < 7; pass++) { + unsigned xd = interlace[pass][0], yd = interlace[pass][1]; + unsigned xo = interlace[pass][2], yo = interlace[pass][3]; + unsigned width = (info.width + (xd - xo - 1)) / xd; + unsigned height = (info.height + (yd - yo - 1)) / yd; + if(width == 0 || height == 0) continue; + size += width * height * info.bytesPerPixel + height; + } + return size; +} + +bool png::deinterlace(const uint8_t *&inputData, unsigned pass) { + unsigned xd = interlace[pass][0], yd = interlace[pass][1]; + unsigned xo = interlace[pass][2], yo = interlace[pass][3]; + unsigned width = (info.width + (xd - xo - 1)) / xd; + unsigned height = (info.height + (yd - yo - 1)) / yd; + if(width == 0 || height == 0) return true; + + unsigned outputSize = width * height * info.bytesPerPixel; + uint8_t *outputData = new uint8_t[outputSize]; + bool result = filter(outputData, inputData, width, height); + + const uint8_t *rd = outputData; + for(unsigned y = yo; y < info.height; y += yd) { + uint8_t *wr = rawData + y * info.pitch; + for(unsigned x = xo; x < info.width; x += xd) { + for(unsigned b = 0; b < info.bytesPerPixel; b++) { + wr[x * info.bytesPerPixel + b] = *rd++; + } + } + } + + inputData += outputSize + height; + delete[] outputData; + return result; +} + +bool png::filter(uint8_t *outputData, const uint8_t *inputData, unsigned width, unsigned height) { + uint8_t *wr = outputData; + const uint8_t *rd = inputData; + int bpp = info.bytesPerPixel, pitch = width * bpp; + for(int y = 0; y < height; y++) { + uint8_t filter = *rd++; + + switch(filter) { + case 0x00: //None + for(int x = 0; x < pitch; x++) { + wr[x] = rd[x]; + } + break; + + case 0x01: //Subtract + for(int x = 0; x < pitch; x++) { + wr[x] = rd[x] + (x - bpp < 0 ? 0 : wr[x - bpp]); + } + break; + + case 0x02: //Above + for(int x = 0; x < pitch; x++) { + wr[x] = rd[x] + (y - 1 < 0 ? 0 : wr[x - pitch]); + } + break; + + case 0x03: //Average + for(int x = 0; x < pitch; x++) { + short a = x - bpp < 0 ? 0 : wr[x - bpp]; + short b = y - 1 < 0 ? 0 : wr[x - pitch]; + + wr[x] = rd[x] + (uint8_t)((a + b) / 2); + } + break; + + case 0x04: //Paeth + for(int x = 0; x < pitch; x++) { + short a = x - bpp < 0 ? 0 : wr[x - bpp]; + short b = y - 1 < 0 ? 0 : wr[x - pitch]; + short c = x - bpp < 0 || y - 1 < 0 ? 0 : wr[x - pitch - bpp]; + + short p = a + b - c; + short pa = p > a ? p - a : a - p; + short pb = p > b ? p - b : b - p; + short pc = p > c ? p - c : c - p; + + uint8_t paeth = (uint8_t)((pa <= pb && pa <= pc) ? a : (pb <= pc) ? b : c); + + wr[x] = rd[x] + paeth; + } + break; + + default: //Invalid + return false; + } + + rd += pitch; + wr += pitch; + } + + return true; +} + +unsigned png::read(const uint8_t *data, unsigned length) { + unsigned result = 0; + while(length--) result = (result << 8) | (*data++); + return result; +} + +unsigned png::decode(const uint8_t *&data) { + unsigned p, r, g, b, a; + + switch(info.colorType) { + case 0: //L + r = g = b = scale(readbits(data)); + a = 0xff; + break; + case 2: //R,G,B + r = scale(readbits(data)); + g = scale(readbits(data)); + b = scale(readbits(data)); + a = 0xff; + break; + case 3: //P + p = readbits(data); + r = info.palette[p][0]; + g = info.palette[p][1]; + b = info.palette[p][2]; + a = 0xff; + break; + case 4: //L,A + r = g = b = scale(readbits(data)); + a = scale(readbits(data)); + break; + case 6: //R,G,B,A + r = scale(readbits(data)); + g = scale(readbits(data)); + b = scale(readbits(data)); + a = scale(readbits(data)); + break; + } + + return (a << 24) | (r << 16) | (g << 8) | (b << 0); +} + +unsigned png::readbits(const uint8_t *&data) { + unsigned result = 0; + switch(info.bitDepth) { + case 1: + result = (*data >> bitpos) & 1; + bitpos++; + if(bitpos == 8) { data++; bitpos = 0; } + break; + case 2: + result = (*data >> bitpos) & 3; + bitpos += 2; + if(bitpos == 8) { data++; bitpos = 0; } + break; + case 4: + result = (*data >> bitpos) & 15; + bitpos += 4; + if(bitpos == 8) { data++; bitpos = 0; } + break; + case 8: + result = *data++; + break; + case 16: + result = (data[0] << 8) | (data[1] << 0); + data += 2; + break; + } + return result; +} + +unsigned png::scale(unsigned n) { + switch(info.bitDepth) { + case 1: return n ? 0xff : 0x00; + case 2: return n * 0x55; + case 4: return n * 0x11; + case 8: return n; + case 16: return n >> 8; + } + return 0; +} + +void png::transform() { + if(data) delete[] data; + data = new uint32_t[info.width * info.height]; + + bitpos = 0; + const uint8_t *rd = rawData; + for(unsigned y = 0; y < info.height; y++) { + uint32_t *wr = data + y * info.width; + for(unsigned x = 0; x < info.width; x++) { + wr[x] = decode(rd); + } + } +} + +void png::alphaTransform(uint32_t rgb) { + transform(); + + uint8_t ir = rgb >> 16; + uint8_t ig = rgb >> 8; + uint8_t ib = rgb >> 0; + + uint32_t *p = data; + for(unsigned y = 0; y < info.height; y++) { + for(unsigned x = 0; x < info.width; x++) { + uint32_t pixel = *p; + uint8_t a = pixel >> 24; + uint8_t r = pixel >> 16; + uint8_t g = pixel >> 8; + uint8_t b = pixel >> 0; + + r = (r * a) + (ir * (255 - a)) >> 8; + g = (g * a) + (ig * (255 - a)) >> 8; + b = (b * a) + (ib * (255 - a)) >> 8; + + *p++ = (255 << 24) | (r << 16) | (g << 8) | (b << 0); + } + } +} + +png::png() : data(0), rawData(0) { +} + +png::~png() { + if(data) delete[] data; + if(rawData) delete[] rawData; +} + +} + +#endif diff --git a/bsnes/nall/resource.hpp b/bsnes/nall/resource.hpp index 6803b16d..f8fd5153 100755 --- a/bsnes/nall/resource.hpp +++ b/bsnes/nall/resource.hpp @@ -2,7 +2,7 @@ #define NALL_RESOURCE_HPP #include -#include +#include namespace nall { @@ -39,7 +39,7 @@ struct resource { bool decode(const uint8_t *cdata, unsigned csize) { if(data) delete[] data; - unzip archive; + zip archive; if(archive.open(cdata, csize) == false) return false; if(archive.file.size() == 0) return false; bool result = archive.extract(archive.file[0], data, size); diff --git a/bsnes/nall/string/base.hpp b/bsnes/nall/string/base.hpp index 3eb16f87..ef331515 100755 --- a/bsnes/nall/string/base.hpp +++ b/bsnes/nall/string/base.hpp @@ -8,8 +8,8 @@ #include #include #include -#include #include +#include namespace nall { class string; @@ -22,13 +22,13 @@ namespace nall { template inline string& assign(Args&&... args); template inline string& append(Args&&... args); - inline string& assign_(const char*); - inline string& append_(const char*); inline bool readfile(const string&); - inline string& replace (const char*, const char*); - inline string& qreplace(const char*, const char*); + template inline string& replace(const char*, const char*); + template inline string& ireplace(const char*, const char*); + template inline string& qreplace(const char*, const char*); + template inline string& iqreplace(const char*, const char*); inline unsigned length() const; @@ -37,7 +37,6 @@ namespace nall { inline bool wildcard(const char*) const; inline bool iwildcard(const char*) const; - inline lstring lwildcard(const char*) const; inline bool beginswith(const char*) const; inline bool ibeginswith(const char*) const; @@ -52,10 +51,12 @@ namespace nall { template inline string& ltrim(const char *key = " "); template inline string& rtrim(const char *key = " "); - template inline string& trim (const char *key = " "); + template inline string& trim(const char *key = " ", const char *rkey = 0); inline optional position(const char *key) const; + inline optional iposition(const char *key) const; inline optional qposition(const char *key) const; + inline optional iqposition(const char *key) const; inline operator const char*() const; inline char* operator()(); @@ -76,10 +77,16 @@ namespace nall { inline string(string&&); inline ~string(); + //internal functions + inline string& assign_(const char*); + inline string& append_(const char*); + protected: char *data; unsigned size; + template inline string& ureplace(const char*, const char*); + #if defined(QSTRING_H) public: inline operator QString() const; @@ -91,24 +98,28 @@ namespace nall { template inline lstring& operator<<(T value); inline optional find(const char*) const; - template inline void split (const char*, const char*); - template inline void qsplit(const char*, const char*); + template inline lstring& split(const char*, const char*); + template inline lstring& isplit(const char*, const char*); + template inline lstring& qsplit(const char*, const char*); + template inline lstring& iqsplit(const char*, const char*); lstring(); lstring(std::initializer_list); + + protected: + template inline lstring& usplit(const char*, const char*); }; //compare.hpp inline char chrlower(char c); inline char chrupper(char c); - inline int stricmp(const char *str1, const char *str2); + inline int istrcmp(const char *str1, const char *str2); inline bool wildcard(const char *str, const char *pattern); inline bool iwildcard(const char *str, const char *pattern); - inline lstring lwildcard(const char *str, const char *pattern); - inline bool strbegin (const char *str, const char *key); - inline bool stribegin(const char *str, const char *key); - inline bool strend (const char *str, const char *key); - inline bool striend(const char *str, const char *key); + inline bool strbegin(const char *str, const char *key); + inline bool istrbegin(const char *str, const char *key); + inline bool strend(const char *str, const char *key); + inline bool istrend(const char *str, const char *key); //convert.hpp inline char* strlower(char *str); @@ -116,14 +127,14 @@ namespace nall { inline char* qstrlower(char *str); inline char* qstrupper(char *str); inline char* strtr(char *dest, const char *before, const char *after); - inline uintmax_t hex (const char *str); - inline intmax_t integer(const char *str); + inline uintmax_t hex(const char *str); + inline intmax_t integer(const char *str); inline uintmax_t decimal(const char *str); - inline uintmax_t binary (const char *str); - inline double fp (const char *str); + inline uintmax_t binary(const char *str); + inline double fp(const char *str); //math.hpp - inline bool strint (const char *str, int &result); + inline bool strint(const char *str, int &result); inline bool strmath(const char *str, int &result); //platform.hpp @@ -137,27 +148,31 @@ namespace nall { //strpos.hpp inline optional strpos(const char *str, const char *key); + inline optional istrpos(const char *str, const char *key); inline optional qstrpos(const char *str, const char *key); + inline optional iqstrpos(const char *str, const char *key); + template inline optional ustrpos(const char *str, const char *key); //trim.hpp template inline char* ltrim(char *str, const char *key = " "); template inline char* rtrim(char *str, const char *key = " "); - template inline char* trim (char *str, const char *key = " "); + template inline char* trim(char *str, const char *key = " ", const char *rkey = 0); //utility.hpp + template alwaysinline bool chrequal(char x, char y); + template alwaysinline bool quoteskip(T *&p); + template alwaysinline bool quotecopy(char *&t, T *&p); inline unsigned strlcpy(string &dest, const char *src, unsigned length); inline unsigned strlcat(string &dest, const char *src, unsigned length); inline string substr(const char *src, unsigned start = 0, unsigned length = ~0u); inline string sha256(const uint8_t *data, unsigned size); - inline string integer(intmax_t value); - template inline string linteger(intmax_t value); - template inline string rinteger(intmax_t value); - inline string decimal(uintmax_t value); - template inline string ldecimal(uintmax_t value); - template inline string rdecimal(uintmax_t value); - template inline string hex(uintmax_t value); - template inline string binary(uintmax_t value); + template inline string integer(intmax_t value); + template inline string linteger(intmax_t value); + template inline string decimal(uintmax_t value); + template inline string ldecimal(uintmax_t value); + template inline string hex(uintmax_t value); + template inline string binary(uintmax_t value); inline unsigned fp(char *str, double value); inline string fp(double value); diff --git a/bsnes/nall/string/compare.hpp b/bsnes/nall/string/compare.hpp index 8ec6428b..ad311d74 100755 --- a/bsnes/nall/string/compare.hpp +++ b/bsnes/nall/string/compare.hpp @@ -11,7 +11,7 @@ char chrupper(char c) { return (c >= 'a' && c <= 'z') ? c - ('a' - 'A') : c; } -int stricmp(const char *str1, const char *str2) { +int istrcmp(const char *str1, const char *str2) { while(*str1) { if(chrlower(*str1) != chrlower(*str2)) break; str1++, str2++; @@ -59,39 +59,6 @@ bool iwildcard(const char *s, const char *p) { return !*p; } -lstring lwildcard(const char *s, const char *p) { - lstring output; - array sp, ep; - const char *cp = 0, *mp = 0; - while(*s && *p != '*') { - if(*p != '?' && *s != *p) return output; - p++, s++; - } - while(*s) { - if(*p == '*') { - sp.append(s), ep.append(s); - if(!*++p) { - while(*s) s++; - ep[ep.size() - 1] = s; - break; - } - mp = p, cp = s + 1; - } else if(*p == '?' || *p == *s) { - p++, s++; - } else { - ep[ep.size() - 1] = cp; - p = mp, s = cp++; - } - } - while(*p == '*') p++; - if(*p) return output; - - for(unsigned n = 0; n < sp.size(); n++) { - output.append(substr(sp[n], 0, ep[n] - sp[n])); - } - return output; -} - bool strbegin(const char *str, const char *key) { int i, ssl = strlen(str), ksl = strlen(key); @@ -99,7 +66,7 @@ bool strbegin(const char *str, const char *key) { return (!memcmp(str, key, ksl)); } -bool stribegin(const char *str, const char *key) { +bool istrbegin(const char *str, const char *key) { int ssl = strlen(str), ksl = strlen(key); if(ksl > ssl) return false; @@ -122,7 +89,7 @@ bool strend(const char *str, const char *key) { return (!memcmp(str + ssl - ksl, key, ksl)); } -bool striend(const char *str, const char *key) { +bool istrend(const char *str, const char *key) { int ssl = strlen(str), ksl = strlen(key); if(ksl > ssl) return false; diff --git a/bsnes/nall/string/replace.hpp b/bsnes/nall/string/replace.hpp index db405a9b..7c7a09d4 100755 --- a/bsnes/nall/string/replace.hpp +++ b/bsnes/nall/string/replace.hpp @@ -3,100 +3,49 @@ namespace nall { -string& string::replace(const char *key, const char *token) { - int i, z, ksl = strlen(key), tsl = strlen(token), ssl = length(); - unsigned int replace_count = 0, size = ssl; - char *buffer; +template +string& string::ureplace(const char *key, const char *token) { + if(!key || !*key) return *this; + enum : unsigned { limit = Limit ? Limit : ~0u }; - if(ksl <= ssl) { - if(tsl > ksl) { //the new string may be longer than the old string... - for(i = 0; i <= ssl - ksl;) { //so let's find out how big of a string we'll need... - if(!memcmp(data + i, key, ksl)) { - replace_count++; - i += ksl; - } else i++; - } - size = ssl + ((tsl - ksl) * replace_count); - reserve(size); + const char *p = data; + unsigned counter = 0, keyLength = 0; + + while(*p) { + if(quoteskip(p)) continue; + for(unsigned n = 0;; n++) { + if(key[n] == 0) { counter++; p += n; keyLength = n; break; } + if(!chrequal(key[n], p[n])) { p++; break; } } - - buffer = new char[size + 1]; - for(i = z = 0; i < ssl;) { - if(i <= ssl - ksl) { - if(!memcmp(data + i, key, ksl)) { - memcpy(buffer + z, token, tsl); - z += tsl; - i += ksl; - } else buffer[z++] = data[i++]; - } else buffer[z++] = data[i++]; - } - buffer[z] = 0; - - assign(buffer); - delete[] buffer; } + if(counter == 0) return *this; + if(Limit) counter = min(counter, Limit); + + char *t = data, *base; + unsigned tokenLength = strlen(token); + if(tokenLength > keyLength) { + t = base = strdup(data); + reserve((unsigned)(p - data) + ((tokenLength - keyLength) * counter)); + } + char *o = data; + + while(*t && counter) { + if(quotecopy(o, t)) continue; + for(unsigned n = 0;; n++) { + if(key[n] == 0) { counter--; memcpy(o, token, tokenLength); t += keyLength; o += tokenLength; break; } + if(!chrequal(key[n], t[n])) { *o++ = *t++; break; } + } + } + do *o++ = *t; while(*t++); + if(tokenLength > keyLength) free(base); return *this; } -string& string::qreplace(const char *key, const char *token) { - int i, l, z, ksl = strlen(key), tsl = strlen(token), ssl = length(); - unsigned int replace_count = 0, size = ssl; - uint8_t x; - char *buffer; - - if(ksl <= ssl) { - if(tsl > ksl) { - for(i = 0; i <= ssl - ksl;) { - x = data[i]; - if(x == '\"' || x == '\'') { - l = i; - i++; - while(data[i++] != x) { - if(i == ssl) { - i = l; - break; - } - } - } - if(!memcmp(data + i, key, ksl)) { - replace_count++; - i += ksl; - } else i++; - } - size = ssl + ((tsl - ksl) * replace_count); - reserve(size); - } - - buffer = new char[size + 1]; - for(i = z = 0; i < ssl;) { - x = data[i]; - if(x == '\"' || x == '\'') { - l = i++; - while(data[i] != x && i < ssl)i++; - if(i >= ssl)i = l; - else { - memcpy(buffer + z, data + l, i - l); - z += i - l; - } - } - if(i <= ssl - ksl) { - if(!memcmp(data + i, key, ksl)) { - memcpy(buffer + z, token, tsl); - z += tsl; - i += ksl; - replace_count++; - } else buffer[z++] = data[i++]; - } else buffer[z++] = data[i++]; - } - buffer[z] = 0; - - assign(buffer); - delete[] buffer; - } - - return *this; -} +template string &string::replace(const char *key, const char *token) { return ureplace(key, token); } +template string &string::ireplace(const char *key, const char *token) { return ureplace(key, token); } +template string &string::qreplace(const char *key, const char *token) { return ureplace(key, token); } +template string &string::iqreplace(const char *key, const char *token) { return ureplace(key, token); } }; diff --git a/bsnes/nall/string/split.hpp b/bsnes/nall/string/split.hpp index 8d3ca877..1644401b 100755 --- a/bsnes/nall/string/split.hpp +++ b/bsnes/nall/string/split.hpp @@ -3,56 +3,36 @@ namespace nall { -template void lstring::split(const char *key, const char *src) { - unsigned limit = Limit; +template lstring& lstring::usplit(const char *key, const char *base) { reset(); + if(!key || !*key) return *this; - int ssl = strlen(src), ksl = strlen(key); - int lp = 0, split_count = 0; + const char *p = base; + unsigned counter = 0; - for(int i = 0; i <= ssl - ksl;) { - if(!memcmp(src + i, key, ksl)) { - strlcpy(operator[](split_count++), src + lp, i - lp + 1); - i += ksl; - lp = i; - if(!--limit) break; - } else i++; - } - - operator[](split_count++) = src + lp; -} - -template void lstring::qsplit(const char *key, const char *src) { - unsigned limit = Limit; - reset(); - - int ssl = strlen(src), ksl = strlen(key); - int lp = 0, split_count = 0; - - for(int i = 0; i <= ssl - ksl;) { - uint8_t x = src[i]; - - if(x == '\"' || x == '\'') { - int z = i++; //skip opening quote - while(i < ssl && src[i] != x) i++; - if(i >= ssl) i = z; //failed match, rewind i - else { - i++; //skip closing quote - continue; //restart in case next char is also a quote + while(*p) { + if(Limit) if(counter >= Limit) break; + if(quoteskip(p)) continue; + for(unsigned n = 0;; n++) { + if(key[n] == 0) { + strlcpy(operator[](counter++), base, (unsigned)(p - base + 1)); + p += n; + base = p; + break; } + if(!chrequal(key[n], p[n])) { p++; break; } } - - if(!memcmp(src + i, key, ksl)) { - strlcpy(operator[](split_count++), src + lp, i - lp + 1); - i += ksl; - lp = i; - if(!--limit) break; - } else i++; } - operator[](split_count++) = src + lp; + operator[](counter) = base; + return *this; } +template lstring& lstring::split(const char *key, const char *src) { return usplit(key, src); } +template lstring& lstring::isplit(const char *key, const char *src) { return usplit(key, src); } +template lstring& lstring::qsplit(const char *key, const char *src) { return usplit(key, src); } +template lstring& lstring::iqsplit(const char *key, const char *src) { return usplit(key, src); } + }; #endif diff --git a/bsnes/nall/string/strpos.hpp b/bsnes/nall/string/strpos.hpp index 1907a2f3..3b28923e 100755 --- a/bsnes/nall/string/strpos.hpp +++ b/bsnes/nall/string/strpos.hpp @@ -2,40 +2,33 @@ #define NALL_STRING_STRPOS_HPP //usage example: -//if(auto pos = strpos(str, key)) print(pos(), "\n"); -//prints position of key within str, only if it is found +//if(auto position = strpos(str, key)) print(position(), "\n"); +//prints position of key within str; but only if it is found namespace nall { -optional strpos(const char *str, const char *key) { - unsigned ssl = strlen(str), ksl = strlen(key); - if(ksl > ssl) return { false, 0 }; +template +optional ustrpos(const char *str, const char *key) { + const char *base = str; - for(unsigned i = 0; i <= ssl - ksl; i++) { - if(!memcmp(str + i, key, ksl)) return { true, i }; - } - - return { false, 0 }; -} - -optional qstrpos(const char *str, const char *key) { - unsigned ssl = strlen(str), ksl = strlen(key); - if(ksl > ssl) return { false, 0 }; - - for(unsigned i = 0; i <= ssl - ksl;) { - uint8_t x = str[i]; - if(x == '\"' || x == '\'') { - uint8_t z = i++; - while(str[i] != x && i < ssl) i++; - if(i >= ssl) i = z; + while(*str) { + if(quoteskip(str)) continue; + for(unsigned n = 0;; n++) { + if(key[n] == 0) return { true, (unsigned)(str - base) }; + if(str[n] == 0) return { false, 0 }; + if(!chrequal(str[n], key[n])) break; } - if(!memcmp(str + i, key, ksl)) return { true, i }; - i++; + str++; } return { false, 0 }; } +optional strpos(const char *str, const char *key) { return ustrpos(str, key); } +optional istrpos(const char *str, const char *key) { return ustrpos(str, key); } +optional qstrpos(const char *str, const char *key) { return ustrpos(str, key); } +optional iqstrpos(const char *str, const char *key) { return ustrpos(str, key); } + } #endif diff --git a/bsnes/nall/string/trim.hpp b/bsnes/nall/string/trim.hpp index f5355d7d..d1f15ee1 100755 --- a/bsnes/nall/string/trim.hpp +++ b/bsnes/nall/string/trim.hpp @@ -29,7 +29,8 @@ template char* rtrim(char *str, const char *key) { return str; } -template char* trim(char *str, const char *key) { +template char* trim(char *str, const char *key, const char *rkey) { + if(rkey) return ltrim(rtrim(str, rkey), key); return ltrim(rtrim(str, key), key); } diff --git a/bsnes/nall/string/utility.hpp b/bsnes/nall/string/utility.hpp index 6906fae4..13faaf64 100755 --- a/bsnes/nall/string/utility.hpp +++ b/bsnes/nall/string/utility.hpp @@ -3,6 +3,38 @@ namespace nall { +template +bool chrequal(char x, char y) { + if(Insensitive) return chrlower(x) == chrlower(y); + return x == y; +} + +template +bool quoteskip(T *&p) { + if(Quoted == false) return false; + if(*p != '\'' && *p != '\"') return false; + + while(*p == '\'' || *p == '\"') { + char x = *p++; + while(*p && *p++ != x); + } + return true; +} + +template +bool quotecopy(char *&t, T *&p) { + if(Quoted == false) return false; + if(*p != '\'' && *p != '\"') return false; + + while(*p == '\'' || *p == '\"') { + char x = *p++; + *t++ = x; + while(*p && *p != x) *t++ = *p++; + *t++ = *p++; + } + return true; +} + unsigned strlcpy(string &dest, const char *src, unsigned length) { dest.reserve(length); return strlcpy(dest(), src, length); @@ -39,33 +71,7 @@ string sha256(const uint8_t *data, unsigned size) { /* arithmetic <> string */ -string integer(intmax_t value) { - bool negative = value < 0; - if(negative) value = abs(value); - - char buffer[64]; - unsigned size = 0; - - do { - unsigned n = value % 10; - buffer[size++] = '0' + n; - value /= 10; - } while(value); - buffer[size++] = negative ? '-' : '+'; - buffer[size] = 0; - - char result[size + 1]; - memset(result, '0', size); - result[size] = 0; - - for(signed x = size - 1, y = 0; x >= 0 && y < size; x--, y++) { - result[x] = buffer[y]; - } - - return (const char*)result; -} - -template string linteger(intmax_t value) { +template string integer(intmax_t value) { bool negative = value < 0; if(negative) value = abs(value); @@ -82,34 +88,7 @@ template string linteger(intmax_t value) { unsigned length = (length_ == 0 ? size : length_); char result[length + 1]; - memset(result, ' ', length); - result[length] = 0; - - for(signed x = 0, y = size - 1; x < length && y >= 0; x++, y--) { - result[x] = buffer[y]; - } - - return (const char*)result; -} - -template string rinteger(intmax_t value) { - bool negative = value < 0; - if(negative) value = abs(value); - - char buffer[64]; - unsigned size = 0; - - do { - unsigned n = value % 10; - buffer[size++] = '0' + n; - value /= 10; - } while(value); - buffer[size++] = negative ? '-' : '+'; - buffer[size] = 0; - - unsigned length = (length_ == 0 ? size : length_); - char result[length + 1]; - memset(result, ' ', length); + memset(result, padding, length); result[length] = 0; for(signed x = length - 1, y = 0; x >= 0 && y < size; x--, y++) { @@ -119,29 +98,10 @@ template string rinteger(intmax_t value) { return (const char*)result; } -string decimal(uintmax_t value) { - char buffer[64]; - unsigned size = 0; - - do { - unsigned n = value % 10; - buffer[size++] = '0' + n; - value /= 10; - } while(value); - buffer[size] = 0; - - char result[size + 1]; - memset(result, '0', size); - result[size] = 0; - - for(signed x = size - 1, y = 0; x >= 0 && y < size; x--, y++) { - result[x] = buffer[y]; - } - - return (const char*)result; -} - -template string ldecimal(uintmax_t value) { +template string linteger(intmax_t value) { + bool negative = value < 0; + if(negative) value = abs(value); + char buffer[64]; unsigned size = 0; @@ -150,11 +110,12 @@ template string ldecimal(uintmax_t value) { buffer[size++] = '0' + n; value /= 10; } while(value); + buffer[size++] = negative ? '-' : '+'; buffer[size] = 0; unsigned length = (length_ == 0 ? size : length_); char result[length + 1]; - memset(result, ' ', length); + memset(result, padding, length); result[length] = 0; for(signed x = 0, y = size - 1; x < length && y >= 0; x++, y--) { @@ -164,7 +125,7 @@ template string ldecimal(uintmax_t value) { return (const char*)result; } -template string rdecimal(uintmax_t value) { +template string decimal(uintmax_t value) { char buffer[64]; unsigned size = 0; @@ -177,7 +138,7 @@ template string rdecimal(uintmax_t value) { unsigned length = (length_ == 0 ? size : length_); char result[length + 1]; - memset(result, ' ', length); + memset(result, padding, length); result[length] = 0; for(signed x = length - 1, y = 0; x >= 0 && y < size; x--, y++) { @@ -187,7 +148,30 @@ template string rdecimal(uintmax_t value) { return (const char*)result; } -template string hex(uintmax_t value) { +template string ldecimal(uintmax_t value) { + char buffer[64]; + unsigned size = 0; + + do { + unsigned n = value % 10; + buffer[size++] = '0' + n; + value /= 10; + } while(value); + buffer[size] = 0; + + unsigned length = (length_ == 0 ? size : length_); + char result[length + 1]; + memset(result, padding, length); + result[length] = 0; + + for(signed x = 0, y = size - 1; x < length && y >= 0; x++, y--) { + result[x] = buffer[y]; + } + + return (const char*)result; +} + +template string hex(uintmax_t value) { char buffer[64]; unsigned size = 0; @@ -199,7 +183,7 @@ template string hex(uintmax_t value) { unsigned length = (length_ == 0 ? size : length_); char result[length + 1]; - memset(result, '0', length); + memset(result, padding, length); result[length] = 0; for(signed x = length - 1, y = 0; x >= 0 && y < size; x--, y++) { @@ -209,7 +193,7 @@ template string hex(uintmax_t value) { return (const char*)result; } -template string binary(uintmax_t value) { +template string binary(uintmax_t value) { char buffer[256]; unsigned size = 0; @@ -221,7 +205,7 @@ template string binary(uintmax_t value) { unsigned length = (length_ == 0 ? size : length_); char result[length + 1]; - memset(result, '0', length); + memset(result, padding, length); result[length] = 0; for(signed x = length - 1, y = 0; x >= 0 && y < size; x--, y++) { diff --git a/bsnes/nall/string/wrapper.hpp b/bsnes/nall/string/wrapper.hpp index 0ce279b0..a28c1ced 100755 --- a/bsnes/nall/string/wrapper.hpp +++ b/bsnes/nall/string/wrapper.hpp @@ -6,17 +6,16 @@ namespace nall { unsigned string::length() const { return strlen(data); } bool string::equals(const char *str) const { return !strcmp(data, str); } -bool string::iequals(const char *str) const { return !stricmp(data, str); } +bool string::iequals(const char *str) const { return !istrcmp(data, str); } bool string::wildcard(const char *str) const { return nall::wildcard(data, str); } bool string::iwildcard(const char *str) const { return nall::iwildcard(data, str); } -lstring string::lwildcard(const char *str) const { return nall::lwildcard(data, str); } bool string::beginswith(const char *str) const { return strbegin(data, str); } -bool string::ibeginswith(const char *str) const { return stribegin(data, str); } +bool string::ibeginswith(const char *str) const { return istrbegin(data, str); } bool string::endswith(const char *str) const { return strend(data, str); } -bool string::iendswith(const char *str) const { return striend(data, str); } +bool string::iendswith(const char *str) const { return istrend(data, str); } string& string::lower() { nall::strlower(data); return *this; } string& string::upper() { nall::strupper(data); return *this; } @@ -26,10 +25,12 @@ string& string::transform(const char *before, const char *after) { nall::strtr(d template string& string::ltrim(const char *key) { nall::ltrim(data, key); return *this; } template string& string::rtrim(const char *key) { nall::rtrim(data, key); return *this; } -template string& string::trim (const char *key) { nall::trim (data, key); return *this; } +template string& string::trim(const char *key, const char *rkey) { nall::trim (data, key, rkey); return *this; } optional string::position(const char *key) const { return strpos(data, key); } +optional string::iposition(const char *key) const { return istrpos(data, key); } optional string::qposition(const char *key) const { return qstrpos(data, key); } +optional string::iqposition(const char *key) const { return iqstrpos(data, key); } } diff --git a/bsnes/nall/utf8.hpp b/bsnes/nall/windows/utf8.hpp similarity index 100% rename from bsnes/nall/utf8.hpp rename to bsnes/nall/windows/utf8.hpp diff --git a/bsnes/nall/unzip.hpp b/bsnes/nall/zip.hpp similarity index 97% rename from bsnes/nall/unzip.hpp rename to bsnes/nall/zip.hpp index 189dc4dd..ad9c7506 100755 --- a/bsnes/nall/unzip.hpp +++ b/bsnes/nall/zip.hpp @@ -8,7 +8,7 @@ namespace nall { -struct unzip { +struct zip { struct File { string name; const uint8_t *data; @@ -18,7 +18,7 @@ struct unzip { unsigned crc32; }; - inline bool open(const char *filename) { + inline bool open(const string &filename) { close(); if(fm.open(filename, filemap::mode::read) == false) return false; if(open(fm.data(), fm.size()) == false) { @@ -100,7 +100,7 @@ struct unzip { if(fm.open()) fm.close(); } - ~unzip() { + ~zip() { close(); } diff --git a/bsnes/phoenix/core/core.cpp b/bsnes/phoenix/core/core.cpp index 89d26718..63c152b2 100755 --- a/bsnes/phoenix/core/core.cpp +++ b/bsnes/phoenix/core/core.cpp @@ -47,11 +47,12 @@ Window Window::None; void Window::append(Layout &layout) { state.layout.append(layout); return p.append(layout); } void Window::append(Menu &menu) { state.menu.append(menu); ((Action&)menu).state.parent = this; return p.append(menu); } void Window::append(Widget &widget) { state.widget.append(widget); return p.append(widget); } +Color Window::backgroundColor() { return p.backgroundColor(); } Geometry Window::frameGeometry() { Geometry geometry = p.geometry(), margin = p.frameMargin(); return { geometry.x - margin.x, geometry.y - margin.y, geometry.width + margin.width, geometry.height + margin.height }; } Geometry Window::frameMargin() { return p.frameMargin(); } bool Window::focused() { return p.focused(); } Geometry Window::geometry() { return p.geometry(); } -void Window::setBackgroundColor(uint8_t red, uint8_t green, uint8_t blue) { state.backgroundColor = true; state.backgroundColorRed = red; state.backgroundColorGreen = green; state.backgroundColorBlue = blue; return p.setBackgroundColor(red, green, blue); } +void Window::setBackgroundColor(const Color &color) { state.backgroundColorOverride = true; state.backgroundColor = color; return p.setBackgroundColor(color); } void Window::setFrameGeometry(const Geometry &geometry) { Geometry margin = p.frameMargin(); return setGeometry({ geometry.x + margin.x, geometry.y + margin.y, geometry.width - margin.width, geometry.height - margin.height }); } void Window::setFocused() { return p.setFocused(); } void Window::setFullScreen(bool fullScreen) { state.fullScreen = fullScreen; return p.setFullScreen(fullScreen); } @@ -93,6 +94,7 @@ RadioItem::RadioItem() : state(*new State), base_from_member(*new p bool Widget::enabled() { return state.enabled; } Font& Widget::font() { return p.font(); } +Geometry Widget::geometry() { return state.geometry; } Geometry Widget::minimumGeometry() { return p.minimumGeometry(); } void Widget::setEnabled(bool enabled) { state.enabled = enabled; return p.setEnabled(enabled); } void Widget::setFocused() { return p.setFocused(); } @@ -128,6 +130,11 @@ void HexEdit::setRows(unsigned rows) { state.rows = rows; return p.setRows(rows) void HexEdit::update() { return p.update(); } HexEdit::HexEdit() : state(*new State), base_from_member(*new pHexEdit(*this)), Widget(base_from_member::value), p(base_from_member::value) { p.constructor(); } +unsigned HorizontalScrollBar::position() { return p.position(); } +void HorizontalScrollBar::setLength(unsigned length) { state.length = length; return p.setLength(length); } +void HorizontalScrollBar::setPosition(unsigned position) { state.position = position; return p.setPosition(position); } +HorizontalScrollBar::HorizontalScrollBar() : state(*new State), base_from_member(*new pHorizontalScrollBar(*this)), Widget(base_from_member::value), p(base_from_member::value) { p.constructor(); } + unsigned HorizontalSlider::position() { return p.position(); } void HorizontalSlider::setLength(unsigned length) { state.length = length; return p.setLength(length); } void HorizontalSlider::setPosition(unsigned position) { state.position = position; return p.setPosition(position); } @@ -172,6 +179,11 @@ void TextEdit::setWordWrap(bool wordWrap) { state.wordWrap = wordWrap; return p. string TextEdit::text() { return p.text(); } TextEdit::TextEdit() : state(*new State), base_from_member(*new pTextEdit(*this)), Widget(base_from_member::value), p(base_from_member::value) { p.constructor(); } +unsigned VerticalScrollBar::position() { return p.position(); } +void VerticalScrollBar::setLength(unsigned length) { state.length = length; return p.setLength(length); } +void VerticalScrollBar::setPosition(unsigned position) { state.position = position; return p.setPosition(position); } +VerticalScrollBar::VerticalScrollBar() : state(*new State), base_from_member(*new pVerticalScrollBar(*this)), Widget(base_from_member::value), p(base_from_member::value) { p.constructor(); } + unsigned VerticalSlider::position() { return p.position(); } void VerticalSlider::setLength(unsigned length) { state.length = length; return p.setLength(length); } void VerticalSlider::setPosition(unsigned position) { state.position = position; return p.setPosition(position); } diff --git a/bsnes/phoenix/core/core.hpp b/bsnes/phoenix/core/core.hpp index f09e6a2c..c09909ed 100755 --- a/bsnes/phoenix/core/core.hpp +++ b/bsnes/phoenix/core/core.hpp @@ -21,6 +21,7 @@ struct pCanvas; struct pCheckBox; struct pComboBox; struct pHexEdit; +struct pHorizontalScrollBar; struct pHorizontalSlider; struct pLabel; struct pLineEdit; @@ -28,6 +29,7 @@ struct pListView; struct pProgressBar; struct pRadioBox; struct pTextEdit; +struct pVerticalScrollBar; struct pVerticalSlider; struct pViewport; @@ -43,6 +45,12 @@ struct Geometry { inline Geometry(signed x, signed y, unsigned width, unsigned height) : x(x), y(y), width(width), height(height) {} }; +struct Color { + uint8_t red, green, blue, alpha; + inline Color() : red(0), green(0), blue(0), alpha(255) {} + inline Color(uint8_t red, uint8_t green, uint8_t blue, uint8_t alpha = 255) : red(red), green(green), blue(blue), alpha(alpha) {} +}; + struct Object { Object(); Object& operator=(const Object&) = delete; @@ -124,11 +132,12 @@ struct Window : Object { void append(Layout &layout); void append(Menu &menu); void append(Widget &widget); + Color backgroundColor(); Geometry frameGeometry(); Geometry frameMargin(); bool focused(); Geometry geometry(); - void setBackgroundColor(uint8_t red, uint8_t green, uint8_t blue); + void setBackgroundColor(const Color &color); void setFrameGeometry(const Geometry &geometry); void setFocused(); void setFullScreen(bool fullScreen = true); @@ -223,6 +232,7 @@ struct Layout : Object { struct Widget : Object { bool enabled(); Font& font(); + Geometry geometry(); Geometry minimumGeometry(); void setEnabled(bool enabled = true); void setFocused(); @@ -300,6 +310,19 @@ struct HexEdit : private nall::base_from_member, Widget { pHexEdit &p; }; +struct HorizontalScrollBar : private nall::base_from_member, Widget { + nall::function onChange; + + unsigned position(); + void setLength(unsigned length); + void setPosition(unsigned position); + + HorizontalScrollBar(); + struct State; + State &state; + pHorizontalScrollBar &p; +}; + struct HorizontalSlider : private nall::base_from_member, Widget { nall::function onChange; @@ -406,6 +429,19 @@ struct TextEdit : private nall::base_from_member, Widget { pTextEdit &p; }; +struct VerticalScrollBar : private nall::base_from_member, Widget { + nall::function onChange; + + unsigned position(); + void setLength(unsigned length); + void setPosition(unsigned position); + + VerticalScrollBar(); + struct State; + State &state; + pVerticalScrollBar &p; +}; + struct VerticalSlider : private nall::base_from_member, Widget { nall::function onChange; diff --git a/bsnes/phoenix/core/state.hpp b/bsnes/phoenix/core/state.hpp index 75df5abb..cbe6970c 100755 --- a/bsnes/phoenix/core/state.hpp +++ b/bsnes/phoenix/core/state.hpp @@ -24,8 +24,8 @@ struct Timer::State { }; struct Window::State { - bool backgroundColor; - unsigned backgroundColorRed, backgroundColorGreen, backgroundColorBlue; + bool backgroundColorOverride; + Color backgroundColor; bool fullScreen; Geometry geometry; reference_array layout; @@ -42,10 +42,8 @@ struct Window::State { Font *widgetFont; State() { - backgroundColor = false; - backgroundColorRed = 0; - backgroundColorGreen = 0; - backgroundColorBlue = 0; + backgroundColorOverride = false; + backgroundColor = { 0, 0, 0, 255 }; fullScreen = false; geometry = { 128, 128, 256, 256 }; menuFont = 0; @@ -152,6 +150,16 @@ struct HexEdit::State { } }; +struct HorizontalScrollBar::State { + unsigned length; + unsigned position; + + State() { + length = 101; + position = 0; + } +}; + struct HorizontalSlider::State { unsigned length; unsigned position; @@ -223,6 +231,16 @@ struct TextEdit::State { } }; +struct VerticalScrollBar::State { + unsigned length; + unsigned position; + + State() { + length = 101; + position = 0; + } +}; + struct VerticalSlider::State { unsigned length; unsigned position; diff --git a/bsnes/phoenix/gtk/gtk.cpp b/bsnes/phoenix/gtk/gtk.cpp index 1c06df83..5a30278d 100755 --- a/bsnes/phoenix/gtk/gtk.cpp +++ b/bsnes/phoenix/gtk/gtk.cpp @@ -19,6 +19,7 @@ #include "widget/check-box.cpp" #include "widget/combo-box.cpp" #include "widget/hex-edit.cpp" +#include "widget/horizontal-scroll-bar.cpp" #include "widget/horizontal-slider.cpp" #include "widget/label.cpp" #include "widget/line-edit.cpp" @@ -26,6 +27,7 @@ #include "widget/progress-bar.cpp" #include "widget/radio-box.cpp" #include "widget/text-edit.cpp" +#include "widget/vertical-scroll-bar.cpp" #include "widget/vertical-slider.cpp" #include "widget/viewport.cpp" diff --git a/bsnes/phoenix/gtk/gtk.hpp b/bsnes/phoenix/gtk/gtk.hpp index 8a27fb03..bd2f19fd 100755 --- a/bsnes/phoenix/gtk/gtk.hpp +++ b/bsnes/phoenix/gtk/gtk.hpp @@ -82,14 +82,16 @@ struct pWindow : public pObject { GtkWidget *statusContainer; GtkWidget *menu; GtkWidget *status; + GdkEventConfigure lastConfigure; void append(Layout &layout); void append(Menu &menu); void append(Widget &widget); + Color backgroundColor(); bool focused(); Geometry frameMargin(); Geometry geometry(); - void setBackgroundColor(uint8_t red, uint8_t green, uint8_t blue); + void setBackgroundColor(const Color &color); void setFocused(); void setFullScreen(bool fullScreen); void setGeometry(const Geometry &geometry); @@ -202,8 +204,7 @@ struct pButton : public pWidget { struct pCanvas : public pWidget { Canvas &canvas; - uint32_t *bufferRGB; - uint32_t *bufferBGR; + cairo_surface_t *surface; uint32_t* buffer(); void setGeometry(const Geometry &geometry); @@ -211,7 +212,6 @@ struct pCanvas : public pWidget { pCanvas(Canvas &canvas) : pWidget(canvas), canvas(canvas) {} void constructor(); - void redraw(); }; struct pCheckBox : public pWidget { @@ -264,6 +264,18 @@ struct pHexEdit : public pWidget { void updateScroll(); }; +struct pHorizontalScrollBar : public pWidget { + HorizontalScrollBar &horizontalScrollBar; + + Geometry minimumGeometry(); + unsigned position(); + void setLength(unsigned length); + void setPosition(unsigned position); + + pHorizontalScrollBar(HorizontalScrollBar &horizontalScrollBar) : pWidget(horizontalScrollBar), horizontalScrollBar(horizontalScrollBar) {} + void constructor(); +}; + struct pHorizontalSlider : public pWidget { HorizontalSlider &horizontalSlider; @@ -368,6 +380,18 @@ struct pTextEdit : public pWidget { void constructor(); }; +struct pVerticalScrollBar : public pWidget { + VerticalScrollBar &verticalScrollBar; + + Geometry minimumGeometry(); + unsigned position(); + void setLength(unsigned length); + void setPosition(unsigned position); + + pVerticalScrollBar(VerticalScrollBar &verticalScrollBar) : pWidget(verticalScrollBar), verticalScrollBar(verticalScrollBar) {} + void constructor(); +}; + struct pVerticalSlider : public pWidget { VerticalSlider &verticalSlider; diff --git a/bsnes/phoenix/gtk/widget/canvas.cpp b/bsnes/phoenix/gtk/widget/canvas.cpp index 2a0d479b..c2261d17 100755 --- a/bsnes/phoenix/gtk/widget/canvas.cpp +++ b/bsnes/phoenix/gtk/widget/canvas.cpp @@ -1,17 +1,21 @@ -static void Canvas_expose(pCanvas *self) { - self->redraw(); +static gboolean Canvas_expose(GtkWidget *widget, GdkEvent *event, pCanvas *self) { + cairo_t *context = gdk_cairo_create(gtk_widget_get_window(widget)); + cairo_set_source_surface(context, self->surface, 0, 0); + cairo_paint(context); + cairo_destroy(context); + return true; } uint32_t* pCanvas::buffer() { - return bufferRGB; + return (uint32_t*)cairo_image_surface_get_data(surface); } void pCanvas::setGeometry(const Geometry &geometry) { - delete[] bufferRGB; - delete[] bufferBGR; + if(geometry.width == cairo_image_surface_get_width(surface) + && geometry.height == cairo_image_surface_get_height(surface)) return; - bufferRGB = new uint32_t[geometry.width * geometry.height](); - bufferBGR = new uint32_t[geometry.width * geometry.height](); + cairo_surface_destroy(surface); + surface = cairo_image_surface_create(CAIRO_FORMAT_RGB24, geometry.width, geometry.height); pWidget::setGeometry(geometry); update(); @@ -19,41 +23,16 @@ void pCanvas::setGeometry(const Geometry &geometry) { void pCanvas::update() { if(gtk_widget_get_realized(gtkWidget) == false) return; - GdkRectangle rect; - rect.x = 0; - rect.y = 0; - rect.width = gtkWidget->allocation.width; - rect.height = gtkWidget->allocation.height; - gdk_window_invalidate_rect(gtkWidget->window, &rect, true); + gdk_window_invalidate_rect(gtk_widget_get_window(gtkWidget), 0, true); } void pCanvas::constructor() { - bufferRGB = new uint32_t[256 * 256](); - bufferBGR = new uint32_t[256 * 256](); - + surface = cairo_image_surface_create(CAIRO_FORMAT_RGB24, 256, 256); gtkWidget = gtk_drawing_area_new(); GdkColor color; color.pixel = color.red = color.green = color.blue = 0; gtk_widget_modify_bg(gtkWidget, GTK_STATE_NORMAL, &color); gtk_widget_set_double_buffered(gtkWidget, false); gtk_widget_add_events(gtkWidget, GDK_EXPOSURE_MASK); - g_signal_connect_swapped(G_OBJECT(gtkWidget), "expose_event", G_CALLBACK(Canvas_expose), (gpointer)this); -} - -void pCanvas::redraw() { - if(gtk_widget_get_realized(gtkWidget) == false) return; - uint32_t *rgb = bufferRGB, *bgr = bufferBGR; - for(unsigned y = gtkWidget->allocation.height; y; y--) { - for(unsigned x = gtkWidget->allocation.width; x; x--) { - uint32_t pixel = *rgb++; - *bgr++ = ((pixel << 16) & 0xff0000) | (pixel & 0x00ff00) | ((pixel >> 16) & 0x0000ff); - } - } - - gdk_draw_rgb_32_image( - gtkWidget->window, - gtkWidget->style->fg_gc[GTK_WIDGET_STATE(gtkWidget)], - 0, 0, gtkWidget->allocation.width, gtkWidget->allocation.height, - GDK_RGB_DITHER_NONE, (guchar*)bufferBGR, sizeof(uint32_t) * gtkWidget->allocation.width - ); + g_signal_connect(G_OBJECT(gtkWidget), "expose_event", G_CALLBACK(Canvas_expose), (gpointer)this); } diff --git a/bsnes/phoenix/gtk/widget/combo-box.cpp b/bsnes/phoenix/gtk/widget/combo-box.cpp index 0ea1e200..b8c65fa5 100755 --- a/bsnes/phoenix/gtk/widget/combo-box.cpp +++ b/bsnes/phoenix/gtk/widget/combo-box.cpp @@ -18,9 +18,7 @@ Geometry pComboBox::minimumGeometry() { void pComboBox::reset() { locked = true; - for(signed n = itemCounter - 1; n >= 0; n--) { - gtk_combo_box_remove_text(GTK_COMBO_BOX(gtkWidget), n); - } + gtk_list_store_clear(GTK_LIST_STORE(gtk_combo_box_get_model(GTK_COMBO_BOX(gtkWidget)))); itemCounter = 0; locked = false; } diff --git a/bsnes/phoenix/gtk/widget/hex-edit.cpp b/bsnes/phoenix/gtk/widget/hex-edit.cpp index 481ab77d..7aa61a07 100755 --- a/bsnes/phoenix/gtk/widget/hex-edit.cpp +++ b/bsnes/phoenix/gtk/widget/hex-edit.cpp @@ -112,17 +112,17 @@ bool pHexEdit::keyPress(unsigned scancode) { unsigned cursorY = position / lineWidth; unsigned cursorX = position % lineWidth; - if(scancode == GDK_Home) { + if(scancode == GDK_KEY_Home) { setCursorPosition(cursorY * lineWidth + 10); return true; } - if(scancode == GDK_End) { + if(scancode == GDK_KEY_End) { setCursorPosition(cursorY * lineWidth + 10 + (hexEdit.state.columns * 3 - 1)); return true; } - if(scancode == GDK_Up) { + if(scancode == GDK_KEY_Up) { if(cursorY != 0) return false; signed newOffset = hexEdit.state.offset - hexEdit.state.columns; @@ -133,7 +133,7 @@ bool pHexEdit::keyPress(unsigned scancode) { return true; } - if(scancode == GDK_Down) { + if(scancode == GDK_KEY_Down) { if(cursorY != hexEdit.state.rows - 1) return false; signed newOffset = hexEdit.state.offset + hexEdit.state.columns; @@ -144,7 +144,7 @@ bool pHexEdit::keyPress(unsigned scancode) { return true; } - if(scancode == GDK_Page_Up) { + if(scancode == GDK_KEY_Page_Up) { signed newOffset = hexEdit.state.offset - hexEdit.state.columns * hexEdit.state.rows; if(newOffset >= 0) { hexEdit.setOffset(newOffset); @@ -155,7 +155,7 @@ bool pHexEdit::keyPress(unsigned scancode) { return true; } - if(scancode == GDK_Page_Down) { + if(scancode == GDK_KEY_Page_Down) { signed newOffset = hexEdit.state.offset + hexEdit.state.columns * hexEdit.state.rows; for(unsigned n = 0; n < hexEdit.state.rows; n++) { if(newOffset + hexEdit.state.columns * hexEdit.state.rows - (hexEdit.state.columns - 1) <= hexEdit.state.length) { diff --git a/bsnes/phoenix/gtk/widget/horizontal-scroll-bar.cpp b/bsnes/phoenix/gtk/widget/horizontal-scroll-bar.cpp new file mode 100755 index 00000000..f260cb58 --- /dev/null +++ b/bsnes/phoenix/gtk/widget/horizontal-scroll-bar.cpp @@ -0,0 +1,29 @@ +static void HorizontalScrollBar_change(HorizontalScrollBar *self) { + if(self->state.position == self->position()) return; + self->state.position = self->position(); + if(self->onChange) self->onChange(); +} + +Geometry pHorizontalScrollBar::minimumGeometry() { + return { 0, 0, 0, 20 }; +} + +unsigned pHorizontalScrollBar::position() { + return (unsigned)gtk_range_get_value(GTK_RANGE(gtkWidget)); +} + +void pHorizontalScrollBar::setLength(unsigned length) { + length += length == 0; + gtk_range_set_range(GTK_RANGE(gtkWidget), 0, length - 1); + gtk_range_set_increments(GTK_RANGE(gtkWidget), 1, length >> 3); +} + +void pHorizontalScrollBar::setPosition(unsigned position) { + gtk_range_set_value(GTK_RANGE(gtkWidget), position); +} + +void pHorizontalScrollBar::constructor() { + gtkWidget = gtk_hscrollbar_new(0); + setLength(101); + g_signal_connect_swapped(G_OBJECT(gtkWidget), "value-changed", G_CALLBACK(HorizontalScrollBar_change), (gpointer)&horizontalScrollBar); +} diff --git a/bsnes/phoenix/gtk/widget/horizontal-slider.cpp b/bsnes/phoenix/gtk/widget/horizontal-slider.cpp index 89a17a8a..4541b6fd 100755 --- a/bsnes/phoenix/gtk/widget/horizontal-slider.cpp +++ b/bsnes/phoenix/gtk/widget/horizontal-slider.cpp @@ -15,6 +15,7 @@ unsigned pHorizontalSlider::position() { void pHorizontalSlider::setLength(unsigned length) { length += length == 0; gtk_range_set_range(GTK_RANGE(gtkWidget), 0, length - 1); + gtk_range_set_increments(GTK_RANGE(gtkWidget), 1, length >> 3); } void pHorizontalSlider::setPosition(unsigned position) { @@ -24,5 +25,6 @@ void pHorizontalSlider::setPosition(unsigned position) { void pHorizontalSlider::constructor() { gtkWidget = gtk_hscale_new_with_range(0, 100, 1); gtk_scale_set_draw_value(GTK_SCALE(gtkWidget), false); + setLength(101); g_signal_connect_swapped(G_OBJECT(gtkWidget), "value-changed", G_CALLBACK(HorizontalSlider_change), (gpointer)&horizontalSlider); } diff --git a/bsnes/phoenix/gtk/widget/line-edit.cpp b/bsnes/phoenix/gtk/widget/line-edit.cpp index e783b3e2..e630b3f5 100755 --- a/bsnes/phoenix/gtk/widget/line-edit.cpp +++ b/bsnes/phoenix/gtk/widget/line-edit.cpp @@ -13,7 +13,7 @@ Geometry pLineEdit::minimumGeometry() { } void pLineEdit::setEditable(bool editable) { - gtk_entry_set_editable(GTK_ENTRY(gtkWidget), editable); + gtk_editable_set_editable(GTK_EDITABLE(gtkWidget), editable); } void pLineEdit::setText(const string &text) { diff --git a/bsnes/phoenix/gtk/widget/vertical-scroll-bar.cpp b/bsnes/phoenix/gtk/widget/vertical-scroll-bar.cpp new file mode 100755 index 00000000..bde3b73f --- /dev/null +++ b/bsnes/phoenix/gtk/widget/vertical-scroll-bar.cpp @@ -0,0 +1,29 @@ +static void VerticalScrollBar_change(VerticalScrollBar *self) { + if(self->state.position == self->position()) return; + self->state.position = self->position(); + if(self->onChange) self->onChange(); +} + +Geometry pVerticalScrollBar::minimumGeometry() { + return { 0, 0, 20, 0 }; +} + +unsigned pVerticalScrollBar::position() { + return (unsigned)gtk_range_get_value(GTK_RANGE(gtkWidget)); +} + +void pVerticalScrollBar::setLength(unsigned length) { + length += length == 0; + gtk_range_set_range(GTK_RANGE(gtkWidget), 0, length - 1); + gtk_range_set_increments(GTK_RANGE(gtkWidget), 1, length >> 3); +} + +void pVerticalScrollBar::setPosition(unsigned position) { + gtk_range_set_value(GTK_RANGE(gtkWidget), position); +} + +void pVerticalScrollBar::constructor() { + gtkWidget = gtk_vscrollbar_new(0); + setLength(101); + g_signal_connect_swapped(G_OBJECT(gtkWidget), "value-changed", G_CALLBACK(VerticalScrollBar_change), (gpointer)&verticalScrollBar); +} diff --git a/bsnes/phoenix/gtk/widget/vertical-slider.cpp b/bsnes/phoenix/gtk/widget/vertical-slider.cpp index b19632f7..ebe59ee7 100755 --- a/bsnes/phoenix/gtk/widget/vertical-slider.cpp +++ b/bsnes/phoenix/gtk/widget/vertical-slider.cpp @@ -15,6 +15,7 @@ unsigned pVerticalSlider::position() { void pVerticalSlider::setLength(unsigned length) { length += length == 0; gtk_range_set_range(GTK_RANGE(gtkWidget), 0, length - 1); + gtk_range_set_increments(GTK_RANGE(gtkWidget), 1, length >> 3); } void pVerticalSlider::setPosition(unsigned position) { @@ -24,5 +25,6 @@ void pVerticalSlider::setPosition(unsigned position) { void pVerticalSlider::constructor() { gtkWidget = gtk_vscale_new_with_range(0, 100, 1); gtk_scale_set_draw_value(GTK_SCALE(gtkWidget), false); + setLength(101); g_signal_connect_swapped(G_OBJECT(gtkWidget), "value-changed", G_CALLBACK(VerticalSlider_change), (gpointer)&verticalSlider); } diff --git a/bsnes/phoenix/gtk/widget/viewport.cpp b/bsnes/phoenix/gtk/widget/viewport.cpp index fd3bae57..7683c7f9 100755 --- a/bsnes/phoenix/gtk/widget/viewport.cpp +++ b/bsnes/phoenix/gtk/widget/viewport.cpp @@ -1,5 +1,5 @@ uintptr_t pViewport::handle() { - return GDK_WINDOW_XID(gtkWidget->window); + return GDK_WINDOW_XID(gtk_widget_get_window(gtkWidget)); } void pViewport::constructor() { diff --git a/bsnes/phoenix/gtk/window.cpp b/bsnes/phoenix/gtk/window.cpp index 632929dc..8204a939 100755 --- a/bsnes/phoenix/gtk/window.cpp +++ b/bsnes/phoenix/gtk/window.cpp @@ -1,70 +1,57 @@ static void Action_setFont(GtkWidget *widget, gpointer font); static void Widget_setFont(GtkWidget *widget, gpointer font); -static gint Window_close(Window *window) { +static gint Window_close(GtkWidget *widget, GdkEvent *event, Window *window) { if(window->onClose) window->onClose(); window->setVisible(false); return true; } -static gboolean Window_configure(Window *window) { +static gboolean Window_configure(GtkWidget *widget, GdkEvent *event, Window *window) { if(gtk_widget_get_realized(window->p.widget) == false) return false; + GdkWindow *gdkWindow = gtk_widget_get_window(widget); //update geometry settings - Display *display = XOpenDisplay(0); - XWindowAttributes attributes, parentAttributes; - XGetWindowAttributes(display, GDK_WINDOW_XID(window->p.widget->window), &attributes); - X11Window rootWindow, parentWindow, *childWindow = 0; - unsigned int childCount; - XQueryTree(display, GDK_WINDOW_XID(window->p.widget->window), &rootWindow, &parentWindow, &childWindow, &childCount); - XGetWindowAttributes(display, parentWindow, &parentAttributes); - if(childWindow) XFree(childWindow); - XCloseDisplay(display); + GdkRectangle border, client; + gdk_window_get_frame_extents(gdkWindow, &border); + gdk_window_get_geometry(gdkWindow, 0, 0, &client.width, &client.height, 0); + gdk_window_get_origin(gdkWindow, &client.x, &client.y); - settings.frameGeometryX = attributes.x; - settings.frameGeometryY = attributes.y; - settings.frameGeometryWidth = parentAttributes.width - attributes.width; - settings.frameGeometryHeight = parentAttributes.height - attributes.height; - - GtkAllocation menuAllocation, statusAllocation; - gtk_widget_get_allocation(window->p.menu, &menuAllocation); - gtk_widget_get_allocation(window->p.status, &statusAllocation); - - if(menuAllocation.height > 1) settings.menuGeometryHeight = menuAllocation.height; - if(statusAllocation.height > 1) settings.statusGeometryHeight = statusAllocation.height; - - //calculate current window position - signed eventX = parentAttributes.x + attributes.x; - signed eventY = parentAttributes.y + attributes.y + window->p.menuHeight(); - unsigned eventWidth = attributes.width; - unsigned eventHeight = attributes.height - window->p.menuHeight() - window->p.statusHeight(); + settings.frameGeometryX = client.x - border.x; + settings.frameGeometryY = client.y - border.y; + settings.frameGeometryWidth = border.width - client.width; + settings.frameGeometryHeight = border.height - client.height; //move - if(window->p.locked == false && window->state.fullScreen == false) { - if(window->state.geometry.x != eventX || window->state.geometry.y != eventY) { - window->state.geometry.x = eventX; - window->state.geometry.y = eventY; + if(event->configure.x != window->p.lastConfigure.x + || event->configure.y != window->p.lastConfigure.y + ) { + if(window->state.fullScreen == false) { + window->state.geometry.x = client.x; + window->state.geometry.y = client.y + window->p.menuHeight(); } + if(window->p.locked == false && window->onMove) window->onMove(); } - if(window->onMove) window->onMove(); - //size - if(window->p.locked == false && window->state.fullScreen == false) { - if(window->state.geometry.width != eventWidth || window->state.geometry.height != eventHeight) { - window->state.geometry.width = eventWidth; - window->state.geometry.height = eventHeight; + if(event->configure.width != window->p.lastConfigure.width + || event->configure.height != window->p.lastConfigure.height + ) { + if(window->state.fullScreen == false) { + window->state.geometry.width = client.width; + window->state.geometry.height = client.height - window->p.menuHeight() - window->p.statusHeight(); } + + foreach(layout, window->state.layout) { + Geometry geometry = window->geometry(); + geometry.x = geometry.y = 0; + layout.setGeometry(geometry); + } + + if(window->p.locked == false && window->onSize) window->onSize(); } - foreach(layout, window->state.layout) { - Geometry geometry = window->geometry(); - geometry.x = geometry.y = 0; - layout.setGeometry(geometry); - } - - if(window->onSize) window->onSize(); - + window->p.lastConfigure = event->configure; return false; } @@ -77,7 +64,7 @@ void pWindow::append(Layout &layout) { void pWindow::append(Menu &subMenu) { if(window.state.menuFont) subMenu.p.setFont(*window.state.menuFont); - gtk_menu_bar_append(menu, subMenu.p.widget); + gtk_menu_shell_append(GTK_MENU_SHELL(menu), subMenu.p.widget); gtk_widget_show(subMenu.p.widget); } @@ -90,6 +77,12 @@ void pWindow::append(Widget &widget) { widget.setVisible(); } +Color pWindow::backgroundColor() { + if(window.state.backgroundColorOverride) return window.state.backgroundColor; + GdkColor color = widget->style->bg[GTK_STATE_NORMAL]; + return { (uint8_t)(color.red >> 8), (uint8_t)(color.green >> 8), (uint8_t)(color.blue >> 8), 255 }; +} + Geometry pWindow::frameMargin() { if(window.state.fullScreen) return { 0, menuHeight(), 0, menuHeight() + statusHeight() }; return { @@ -111,13 +104,13 @@ Geometry pWindow::geometry() { return window.state.geometry; } -void pWindow::setBackgroundColor(uint8_t red, uint8_t green, uint8_t blue) { - GdkColor color; - color.pixel = (red << 16) | (green << 8) | (blue << 0); - color.red = (red << 8) | (red << 0); - color.green = (green << 8) | (green << 0); - color.blue = (blue << 8) | (blue << 0); - gtk_widget_modify_bg(widget, GTK_STATE_NORMAL, &color); +void pWindow::setBackgroundColor(const Color &color) { + GdkColor gdkColor; + gdkColor.pixel = (color.red << 16) | (color.green << 8) | (color.blue << 0); + gdkColor.red = (color.red << 8) | (color.red << 0); + gdkColor.green = (color.green << 8) | (color.green << 0); + gdkColor.blue = (color.blue << 8) | (color.blue << 0); + gtk_widget_modify_bg(widget, GTK_STATE_NORMAL, &gdkColor); } void pWindow::setFocused() { @@ -129,14 +122,12 @@ void pWindow::setFullScreen(bool fullScreen) { gtk_window_unfullscreen(GTK_WINDOW(widget)); gtk_window_set_resizable(GTK_WINDOW(widget), window.state.resizable); gtk_window_set_decorated(GTK_WINDOW(widget), true); - locked = true; for(unsigned n = 0; n < 4; n++) { setGeometry(window.state.geometry); gtk_widget_set_size_request(widget, -1, -1); OS::processEvents(); usleep(2000); } - locked = false; } else { gtk_window_fullscreen(GTK_WINDOW(widget)); gtk_window_set_decorated(GTK_WINDOW(widget), false); @@ -224,8 +215,8 @@ void pWindow::constructor() { setTitle(""); setGeometry(window.state.geometry); - g_signal_connect_swapped(G_OBJECT(widget), "delete-event", G_CALLBACK(Window_close), (gpointer)&window); - g_signal_connect_swapped(G_OBJECT(widget), "configure-event", G_CALLBACK(Window_configure), (gpointer)&window); + g_signal_connect(G_OBJECT(widget), "delete-event", G_CALLBACK(Window_close), (gpointer)&window); + g_signal_connect(G_OBJECT(widget), "configure-event", G_CALLBACK(Window_configure), (gpointer)&window); } unsigned pWindow::menuHeight() { diff --git a/bsnes/phoenix/phoenix.cpp b/bsnes/phoenix/phoenix.cpp index d73c3b6a..77276e02 100755 --- a/bsnes/phoenix/phoenix.cpp +++ b/bsnes/phoenix/phoenix.cpp @@ -22,6 +22,7 @@ #define X11None 0L #include + #include #include #include #include diff --git a/bsnes/phoenix/qt/qt.cpp b/bsnes/phoenix/qt/qt.cpp index 42bd10ee..2eb69bdb 100755 --- a/bsnes/phoenix/qt/qt.cpp +++ b/bsnes/phoenix/qt/qt.cpp @@ -20,6 +20,7 @@ #include "widget/check-box.cpp" #include "widget/combo-box.cpp" #include "widget/hex-edit.cpp" +#include "widget/horizontal-scroll-bar.cpp" #include "widget/horizontal-slider.cpp" #include "widget/label.cpp" #include "widget/line-edit.cpp" @@ -27,6 +28,7 @@ #include "widget/progress-bar.cpp" #include "widget/radio-box.cpp" #include "widget/text-edit.cpp" +#include "widget/vertical-scroll-bar.cpp" #include "widget/vertical-slider.cpp" #include "widget/viewport.cpp" diff --git a/bsnes/phoenix/qt/qt.moc b/bsnes/phoenix/qt/qt.moc index dd08a286..1fd8f337 100755 --- a/bsnes/phoenix/qt/qt.moc +++ b/bsnes/phoenix/qt/qt.moc @@ -1,7 +1,7 @@ /**************************************************************************** ** Meta object code from reading C++ file 'qt.moc.hpp' ** -** Created: Tue May 24 19:33:16 2011 +** Created: Fri Aug 5 17:51:21 2011 ** by: The Qt Meta Object Compiler version 62 (Qt 4.7.0) ** ** WARNING! All changes made in this file will be lost! @@ -606,6 +606,67 @@ int pHexEdit::qt_metacall(QMetaObject::Call _c, int _id, void **_a) } return _id; } +static const uint qt_meta_data_pHorizontalScrollBar[] = { + + // content: + 5, // revision + 0, // classname + 0, 0, // classinfo + 1, 14, // methods + 0, 0, // properties + 0, 0, // enums/sets + 0, 0, // constructors + 0, // flags + 0, // signalCount + + // slots: signature, parameters, type, tag, flags + 22, 21, 21, 21, 0x0a, + + 0 // eod +}; + +static const char qt_meta_stringdata_pHorizontalScrollBar[] = { + "pHorizontalScrollBar\0\0onChange()\0" +}; + +const QMetaObject pHorizontalScrollBar::staticMetaObject = { + { &QObject::staticMetaObject, qt_meta_stringdata_pHorizontalScrollBar, + qt_meta_data_pHorizontalScrollBar, 0 } +}; + +#ifdef Q_NO_DATA_RELOCATION +const QMetaObject &pHorizontalScrollBar::getStaticMetaObject() { return staticMetaObject; } +#endif //Q_NO_DATA_RELOCATION + +const QMetaObject *pHorizontalScrollBar::metaObject() const +{ + return QObject::d_ptr->metaObject ? QObject::d_ptr->metaObject : &staticMetaObject; +} + +void *pHorizontalScrollBar::qt_metacast(const char *_clname) +{ + if (!_clname) return 0; + if (!strcmp(_clname, qt_meta_stringdata_pHorizontalScrollBar)) + return static_cast(const_cast< pHorizontalScrollBar*>(this)); + if (!strcmp(_clname, "pWidget")) + return static_cast< pWidget*>(const_cast< pHorizontalScrollBar*>(this)); + return QObject::qt_metacast(_clname); +} + +int pHorizontalScrollBar::qt_metacall(QMetaObject::Call _c, int _id, void **_a) +{ + _id = QObject::qt_metacall(_c, _id, _a); + if (_id < 0) + return _id; + if (_c == QMetaObject::InvokeMetaMethod) { + switch (_id) { + case 0: onChange(); break; + default: ; + } + _id -= 1; + } + return _id; +} static const uint qt_meta_data_pHorizontalSlider[] = { // content: @@ -918,6 +979,67 @@ int pTextEdit::qt_metacall(QMetaObject::Call _c, int _id, void **_a) } return _id; } +static const uint qt_meta_data_pVerticalScrollBar[] = { + + // content: + 5, // revision + 0, // classname + 0, 0, // classinfo + 1, 14, // methods + 0, 0, // properties + 0, 0, // enums/sets + 0, 0, // constructors + 0, // flags + 0, // signalCount + + // slots: signature, parameters, type, tag, flags + 20, 19, 19, 19, 0x0a, + + 0 // eod +}; + +static const char qt_meta_stringdata_pVerticalScrollBar[] = { + "pVerticalScrollBar\0\0onChange()\0" +}; + +const QMetaObject pVerticalScrollBar::staticMetaObject = { + { &QObject::staticMetaObject, qt_meta_stringdata_pVerticalScrollBar, + qt_meta_data_pVerticalScrollBar, 0 } +}; + +#ifdef Q_NO_DATA_RELOCATION +const QMetaObject &pVerticalScrollBar::getStaticMetaObject() { return staticMetaObject; } +#endif //Q_NO_DATA_RELOCATION + +const QMetaObject *pVerticalScrollBar::metaObject() const +{ + return QObject::d_ptr->metaObject ? QObject::d_ptr->metaObject : &staticMetaObject; +} + +void *pVerticalScrollBar::qt_metacast(const char *_clname) +{ + if (!_clname) return 0; + if (!strcmp(_clname, qt_meta_stringdata_pVerticalScrollBar)) + return static_cast(const_cast< pVerticalScrollBar*>(this)); + if (!strcmp(_clname, "pWidget")) + return static_cast< pWidget*>(const_cast< pVerticalScrollBar*>(this)); + return QObject::qt_metacast(_clname); +} + +int pVerticalScrollBar::qt_metacall(QMetaObject::Call _c, int _id, void **_a) +{ + _id = QObject::qt_metacall(_c, _id, _a); + if (_id < 0) + return _id; + if (_c == QMetaObject::InvokeMetaMethod) { + switch (_id) { + case 0: onChange(); break; + default: ; + } + _id -= 1; + } + return _id; +} static const uint qt_meta_data_pVerticalSlider[] = { // content: diff --git a/bsnes/phoenix/qt/qt.moc.hpp b/bsnes/phoenix/qt/qt.moc.hpp index ba6ab2ad..0453363c 100755 --- a/bsnes/phoenix/qt/qt.moc.hpp +++ b/bsnes/phoenix/qt/qt.moc.hpp @@ -101,10 +101,11 @@ public: void append(Layout &layout); void append(Menu &menu); void append(Widget &widget); + Color backgroundColor(); Geometry frameMargin(); bool focused(); Geometry geometry(); - void setBackgroundColor(uint8_t red, uint8_t green, uint8_t blue); + void setBackgroundColor(const Color &color); void setFocused(); void setFullScreen(bool fullScreen); void setGeometry(const Geometry &geometry); @@ -330,6 +331,25 @@ public slots: void onScroll(); }; +struct pHorizontalScrollBar : public QObject, public pWidget { + Q_OBJECT + +public: + HorizontalScrollBar &horizontalScrollBar; + QScrollBar *qtScrollBar; + + Geometry minimumGeometry(); + unsigned position(); + void setLength(unsigned length); + void setPosition(unsigned position); + + pHorizontalScrollBar(HorizontalScrollBar &horizontalScrollBar) : pWidget(horizontalScrollBar), horizontalScrollBar(horizontalScrollBar) {} + void constructor(); + +public slots: + void onChange(); +}; + struct pHorizontalSlider : public QObject, public pWidget { Q_OBJECT @@ -462,6 +482,25 @@ public slots: void onChange(); }; +struct pVerticalScrollBar : public QObject, public pWidget { + Q_OBJECT + +public: + VerticalScrollBar &verticalScrollBar; + QScrollBar *qtScrollBar; + + Geometry minimumGeometry(); + unsigned position(); + void setLength(unsigned length); + void setPosition(unsigned position); + + pVerticalScrollBar(VerticalScrollBar &verticalScrollBar) : pWidget(verticalScrollBar), verticalScrollBar(verticalScrollBar) {} + void constructor(); + +public slots: + void onChange(); +}; + struct pVerticalSlider : public QObject, public pWidget { Q_OBJECT diff --git a/bsnes/phoenix/qt/widget/horizontal-scroll-bar.cpp b/bsnes/phoenix/qt/widget/horizontal-scroll-bar.cpp new file mode 100755 index 00000000..43f5c42f --- /dev/null +++ b/bsnes/phoenix/qt/widget/horizontal-scroll-bar.cpp @@ -0,0 +1,29 @@ +Geometry pHorizontalScrollBar::minimumGeometry() { + return { 0, 0, 0, 15 }; +} + +unsigned pHorizontalScrollBar::position() { + return qtScrollBar->value(); +} + +void pHorizontalScrollBar::setLength(unsigned length) { + length += length == 0; + qtScrollBar->setRange(0, length - 1); + qtScrollBar->setPageStep(length >> 3); +} + +void pHorizontalScrollBar::setPosition(unsigned position) { + qtScrollBar->setValue(position); +} + +void pHorizontalScrollBar::constructor() { + qtWidget = qtScrollBar = new QScrollBar(Qt::Horizontal); + qtScrollBar->setRange(0, 100); + qtScrollBar->setPageStep(101 >> 3); + connect(qtScrollBar, SIGNAL(valueChanged(int)), SLOT(onChange())); +} + +void pHorizontalScrollBar::onChange() { + horizontalScrollBar.state.position = position(); + if(horizontalScrollBar.onChange) horizontalScrollBar.onChange(); +} diff --git a/bsnes/phoenix/qt/widget/vertical-scroll-bar.cpp b/bsnes/phoenix/qt/widget/vertical-scroll-bar.cpp new file mode 100755 index 00000000..a0638157 --- /dev/null +++ b/bsnes/phoenix/qt/widget/vertical-scroll-bar.cpp @@ -0,0 +1,29 @@ +Geometry pVerticalScrollBar::minimumGeometry() { + return { 0, 0, 15, 0 }; +} + +unsigned pVerticalScrollBar::position() { + return qtScrollBar->value(); +} + +void pVerticalScrollBar::setLength(unsigned length) { + length += length == 0; + qtScrollBar->setRange(0, length - 1); + qtScrollBar->setPageStep(length >> 3); +} + +void pVerticalScrollBar::setPosition(unsigned position) { + qtScrollBar->setValue(position); +} + +void pVerticalScrollBar::constructor() { + qtWidget = qtScrollBar = new QScrollBar(Qt::Vertical); + qtScrollBar->setRange(0, 100); + qtScrollBar->setPageStep(101 >> 3); + connect(qtScrollBar, SIGNAL(valueChanged(int)), SLOT(onChange())); +} + +void pVerticalScrollBar::onChange() { + verticalScrollBar.state.position = position(); + if(verticalScrollBar.onChange) verticalScrollBar.onChange(); +} diff --git a/bsnes/phoenix/qt/window.cpp b/bsnes/phoenix/qt/window.cpp index a11eb58b..7fa2bdff 100755 --- a/bsnes/phoenix/qt/window.cpp +++ b/bsnes/phoenix/qt/window.cpp @@ -18,6 +18,12 @@ void pWindow::append(Widget &widget) { widget.setVisible(widget.state.visible); } +Color pWindow::backgroundColor() { + if(window.state.backgroundColorOverride) return window.state.backgroundColor; + QColor color = qtWindow->palette().color(QPalette::ColorRole::Window); + return { (uint8_t)color.red(), (uint8_t)color.green(), (uint8_t)color.blue(), (uint8_t)color.alpha() }; +} + Geometry pWindow::frameMargin() { unsigned menuHeight = window.state.menuVisible ? qtMenu->height() : 0; unsigned statusHeight = window.state.statusVisible ? qtStatus->height() : 0; @@ -43,9 +49,9 @@ Geometry pWindow::geometry() { return window.state.geometry; } -void pWindow::setBackgroundColor(uint8_t red, uint8_t green, uint8_t blue) { +void pWindow::setBackgroundColor(const Color &color) { QPalette palette; - palette.setColor(QPalette::Window, QColor(red, green, blue)); + palette.setColor(QPalette::Window, QColor(color.red, color.green, color.blue)); qtContainer->setPalette(palette); qtContainer->setAutoFillBackground(true); } diff --git a/bsnes/phoenix/reference/reference.cpp b/bsnes/phoenix/reference/reference.cpp index d2b04b8e..7d2262bc 100755 --- a/bsnes/phoenix/reference/reference.cpp +++ b/bsnes/phoenix/reference/reference.cpp @@ -18,6 +18,7 @@ #include "widget/check-box.cpp" #include "widget/combo-box.cpp" #include "widget/hex-edit.cpp" +#include "widget/horizontal-scroll-bar.cpp" #include "widget/horizontal-slider.cpp" #include "widget/label.cpp" #include "widget/line-edit.cpp" @@ -25,6 +26,7 @@ #include "widget/progress-bar.cpp" #include "widget/radio-box.cpp" #include "widget/text-edit.cpp" +#include "widget/vertical-scroll-bar.cpp" #include "widget/vertical-slider.cpp" #include "widget/viewport.cpp" diff --git a/bsnes/phoenix/reference/reference.hpp b/bsnes/phoenix/reference/reference.hpp index 6c48b171..d5872518 100755 --- a/bsnes/phoenix/reference/reference.hpp +++ b/bsnes/phoenix/reference/reference.hpp @@ -63,10 +63,11 @@ struct pWindow : public pObject { void append(Layout &layout); void append(Menu &menu); void append(Widget &widget); + Color backgroundColor(); bool focused(); Geometry frameMargin(); Geometry geometry(); - void setBackgroundColor(uint8_t red, uint8_t green, uint8_t blue); + void setBackgroundColor(const Color &color); void setFocused(); void setFullScreen(bool fullScreen); void setGeometry(const Geometry &geometry); @@ -214,6 +215,17 @@ struct pHexEdit : public pWidget { void constructor(); }; +struct pHorizontalScrollBar : public pWidget { + HorizontalScrollBar &horizontalScrollBar; + + unsigned position(); + void setLength(unsigned length); + void setPosition(unsigned position); + + pHorizontalScrollBar(HorizontalScrollBar &horizontalScrollBar) : pWidget(horizontalScrollBar), horizontalScrollBar(horizontalScrollBar) {} + void constructor(); +}; + struct pHorizontalSlider : public pWidget { HorizontalSlider &horizontalSlider; @@ -300,6 +312,17 @@ struct pTextEdit : public pWidget { void constructor(); }; +struct pVerticalScrollBar : public pWidget { + VerticalScrollBar &verticalScrollBar; + + unsigned position(); + void setLength(unsigned length); + void setPosition(unsigned position); + + pVerticalScrollBar(VerticalScrollBar &verticalScrollBar) : pWidget(verticalScrollBar), verticalScrollBar(verticalScrollBar) {} + void constructor(); +}; + struct pVerticalSlider : public pWidget { VerticalSlider &verticalSlider; diff --git a/bsnes/phoenix/reference/widget/horizontal-scroll-bar.cpp b/bsnes/phoenix/reference/widget/horizontal-scroll-bar.cpp new file mode 100755 index 00000000..352b3393 --- /dev/null +++ b/bsnes/phoenix/reference/widget/horizontal-scroll-bar.cpp @@ -0,0 +1,12 @@ +unsigned pHorizontalScrollBar::position() { + return 0; +} + +void pHorizontalScrollBar::setLength(unsigned length) { +} + +void pHorizontalScrollBar::setPosition(unsigned position) { +} + +void pHorizontalScrollBar::constructor() { +} diff --git a/bsnes/phoenix/reference/widget/vertical-scroll-bar.cpp b/bsnes/phoenix/reference/widget/vertical-scroll-bar.cpp new file mode 100755 index 00000000..26795248 --- /dev/null +++ b/bsnes/phoenix/reference/widget/vertical-scroll-bar.cpp @@ -0,0 +1,12 @@ +unsigned pVerticalScrollBar::position() { + return 0; +} + +void pVerticalScrollBar::setLength(unsigned length) { +} + +void pVerticalScrollBar::setPosition(unsigned position) { +} + +void pVerticalScrollBar::constructor() { +} diff --git a/bsnes/phoenix/reference/window.cpp b/bsnes/phoenix/reference/window.cpp index a31ce464..e9ceebb7 100755 --- a/bsnes/phoenix/reference/window.cpp +++ b/bsnes/phoenix/reference/window.cpp @@ -7,6 +7,10 @@ void pWindow::append(Menu &menu) { void pWindow::append(Widget &widget) { } +Color pWindow::backgroundColor() { + return { 0, 0, 0, 255 }; +} + bool pWindow::focused() { return false; } @@ -19,7 +23,7 @@ Geometry pWindow::geometry() { return { 0, 0, 0, 0 }; } -void pWindow::setBackgroundColor(uint8_t red, uint8_t green, uint8_t blue) { +void pWindow::setBackgroundColor(const Color &color) { } void pWindow::setFocused() { diff --git a/bsnes/phoenix/sync.sh b/bsnes/phoenix/sync.sh index b51e3b40..40ee3d98 100755 --- a/bsnes/phoenix/sync.sh +++ b/bsnes/phoenix/sync.sh @@ -6,3 +6,4 @@ synchronize() { } synchronize "nall" +rm -r nall/test diff --git a/bsnes/phoenix/windows/widget/horizontal-scroll-bar.cpp b/bsnes/phoenix/windows/widget/horizontal-scroll-bar.cpp new file mode 100755 index 00000000..0e114e09 --- /dev/null +++ b/bsnes/phoenix/windows/widget/horizontal-scroll-bar.cpp @@ -0,0 +1,32 @@ +Geometry pHorizontalScrollBar::minimumGeometry() { + return { 0, 0, 0, 18 }; +} + +unsigned pHorizontalScrollBar::position() { + return GetScrollPos(hwnd, SB_CTL); +} + +void pHorizontalScrollBar::setLength(unsigned length) { + length += (length == 0); + SetScrollRange(hwnd, SB_CTL, 0, length - 1, TRUE); + horizontalScrollBar.setPosition(0); +} + +void pHorizontalScrollBar::setPosition(unsigned position) { return; + SetScrollPos(hwnd, SB_CTL, position, TRUE); +} + +void pHorizontalScrollBar::constructor() { + setParent(Window::None); +} + +void pHorizontalScrollBar::setParent(Window &parent) { + if(hwnd) DestroyWindow(hwnd); + hwnd = CreateWindow( + L"SCROLLBAR", L"", WS_CHILD | WS_VISIBLE | WS_TABSTOP | SBS_HORZ, + 0, 0, 0, 0, parent.p.hwnd, (HMENU)id, GetModuleHandle(0), 0 + ); + SetWindowLongPtr(hwnd, GWLP_USERDATA, (LONG_PTR)&horizontalScrollBar); + setLength(horizontalScrollBar.state.length); + setPosition(horizontalScrollBar.state.position); +} diff --git a/bsnes/phoenix/windows/widget/vertical-scroll-bar.cpp b/bsnes/phoenix/windows/widget/vertical-scroll-bar.cpp new file mode 100755 index 00000000..3d763a51 --- /dev/null +++ b/bsnes/phoenix/windows/widget/vertical-scroll-bar.cpp @@ -0,0 +1,32 @@ +Geometry pVerticalScrollBar::minimumGeometry() { + return { 0, 0, 18, 0 }; +} + +unsigned pVerticalScrollBar::position() { + return GetScrollPos(hwnd, SB_CTL); +} + +void pVerticalScrollBar::setLength(unsigned length) { + length += (length == 0); + SetScrollRange(hwnd, SB_CTL, 0, length - 1, TRUE); + verticalScrollBar.setPosition(0); +} + +void pVerticalScrollBar::setPosition(unsigned position) { + SetScrollPos(hwnd, SB_CTL, position, TRUE); +} + +void pVerticalScrollBar::constructor() { + setParent(Window::None); +} + +void pVerticalScrollBar::setParent(Window &parent) { + if(hwnd) DestroyWindow(hwnd); + hwnd = CreateWindow( + L"SCROLLBAR", L"", WS_CHILD | WS_VISIBLE | SBS_VERT, + 0, 0, 0, 0, parent.p.hwnd, (HMENU)id, GetModuleHandle(0), 0 + ); + SetWindowLongPtr(hwnd, GWLP_USERDATA, (LONG_PTR)&verticalScrollBar); + setLength(verticalScrollBar.state.length); + setPosition(verticalScrollBar.state.position); +} diff --git a/bsnes/phoenix/windows/widget/vertical-slider.cpp b/bsnes/phoenix/windows/widget/vertical-slider.cpp index 8c170cdf..dc1a7a22 100755 --- a/bsnes/phoenix/windows/widget/vertical-slider.cpp +++ b/bsnes/phoenix/windows/widget/vertical-slider.cpp @@ -1,5 +1,5 @@ Geometry pVerticalSlider::minimumGeometry() { - return { 0, 0, 25, 0 }; + return { 0, 0, 0, 25 }; } unsigned pVerticalSlider::position() { diff --git a/bsnes/phoenix/windows/window.cpp b/bsnes/phoenix/windows/window.cpp index 752bd0c1..3955168d 100755 --- a/bsnes/phoenix/windows/window.cpp +++ b/bsnes/phoenix/windows/window.cpp @@ -16,6 +16,12 @@ void pWindow::append(Widget &widget) { widget.p.setParent(window); } +Color pWindow::backgroundColor() { + if(window.state.backgroundColorOverride) return window.state.backgroundColor; + DWORD color = GetSysColor(COLOR_3DFACE); + return { (uint8_t)(color >> 16), (uint8_t)(color >> 8), (uint8_t)(color >> 0), 255 }; +} + bool pWindow::focused() { return (GetForegroundWindow() == hwnd); } @@ -37,10 +43,15 @@ Geometry pWindow::frameMargin() { Geometry pWindow::geometry() { Geometry margin = frameMargin(); - //note: GetWindowRect returns -32000(x),-32000(y) when window is minimized - WINDOWPLACEMENT wp; - GetWindowPlacement(hwnd, &wp); - RECT rc = wp.rcNormalPosition; + RECT rc; + if(IsIconic(hwnd)) { + //GetWindowRect returns -32000(x),-32000(y) when window is minimized + WINDOWPLACEMENT wp; + GetWindowPlacement(hwnd, &wp); + rc = wp.rcNormalPosition; + } else { + GetWindowRect(hwnd, &rc); + } signed x = rc.left + margin.x; signed y = rc.top + margin.y; @@ -50,9 +61,9 @@ Geometry pWindow::geometry() { return { x, y, width, height }; } -void pWindow::setBackgroundColor(uint8_t red, uint8_t green, uint8_t blue) { +void pWindow::setBackgroundColor(const Color &color) { if(brush) DeleteObject(brush); - brushColor = RGB(red, green, blue); + brushColor = RGB(color.red, color.green, color.blue); brush = CreateSolidBrush(brushColor); } diff --git a/bsnes/phoenix/windows/windows.cpp b/bsnes/phoenix/windows/windows.cpp index 94b1497a..565099e4 100755 --- a/bsnes/phoenix/windows/windows.cpp +++ b/bsnes/phoenix/windows/windows.cpp @@ -19,6 +19,7 @@ #include "widget/check-box.cpp" #include "widget/combo-box.cpp" #include "widget/hex-edit.cpp" +#include "widget/horizontal-scroll-bar.cpp" #include "widget/horizontal-slider.cpp" #include "widget/label.cpp" #include "widget/line-edit.cpp" @@ -26,6 +27,7 @@ #include "widget/progress-bar.cpp" #include "widget/radio-box.cpp" #include "widget/text-edit.cpp" +#include "widget/vertical-scroll-bar.cpp" #include "widget/vertical-slider.cpp" #include "widget/viewport.cpp" @@ -175,7 +177,7 @@ void pOS::initialize() { WNDCLASS wc; wc.cbClsExtra = 0; wc.cbWndExtra = 0; - wc.hbrBackground = (HBRUSH)(COLOR_3DFACE + 1); + wc.hbrBackground = GetSysColorBrush(COLOR_3DFACE); wc.hCursor = LoadCursor(0, IDC_ARROW); wc.hIcon = LoadIcon(GetModuleHandle(0), MAKEINTRESOURCE(2)); wc.hInstance = GetModuleHandle(0); @@ -199,7 +201,7 @@ void pOS::initialize() { wc.cbClsExtra = 0; wc.cbWndExtra = 0; - wc.hbrBackground = (HBRUSH)(COLOR_3DFACE + 1); + wc.hbrBackground = GetSysColorBrush(COLOR_3DFACE); wc.hCursor = LoadCursor(0, IDC_ARROW); wc.hIcon = LoadIcon(0, IDI_APPLICATION); wc.hInstance = GetModuleHandle(0); @@ -408,11 +410,58 @@ static LRESULT CALLBACK OS_windowProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM case WM_HSCROLL: case WM_VSCROLL: { - unsigned id = LOWORD(wparam); - HWND control = GetDlgItem(window.p.hwnd, id); - if(control == 0) break; - Object *object = (Object*)GetWindowLongPtr(control, GWLP_USERDATA); + Object *object = 0; + if(lparam) { + object = (Object*)GetWindowLongPtr((HWND)lparam, GWLP_USERDATA); + } else { + unsigned id = LOWORD(wparam); + HWND control = GetDlgItem(window.p.hwnd, id); + if(control == 0) break; + object = (Object*)GetWindowLongPtr(control, GWLP_USERDATA); + } if(object == 0) break; + + if(dynamic_cast(object) + || dynamic_cast(object)) { + SCROLLINFO info; + memset(&info, 0, sizeof(SCROLLINFO)); + info.cbSize = sizeof(SCROLLINFO); + info.fMask = SIF_ALL; + GetScrollInfo((HWND)lparam, SB_CTL, &info); + + switch(LOWORD(wparam)) { + case SB_LEFT: info.nPos = info.nMin; break; + case SB_RIGHT: info.nPos = info.nMax; break; + case SB_LINELEFT: info.nPos--; break; + case SB_LINERIGHT: info.nPos++; break; + case SB_PAGELEFT: info.nPos -= info.nMax >> 3; break; + case SB_PAGERIGHT: info.nPos += info.nMax >> 3; break; + case SB_THUMBTRACK: info.nPos = info.nTrackPos; break; + } + + info.fMask = SIF_POS; + SetScrollInfo((HWND)lparam, SB_CTL, &info, TRUE); + + //Windows may clamp position to scrollbar range + GetScrollInfo((HWND)lparam, SB_CTL, &info); + + if(dynamic_cast(object)) { + HorizontalScrollBar &horizontalScrollBar = (HorizontalScrollBar&)*object; + if(horizontalScrollBar.state.position != info.nPos) { + horizontalScrollBar.state.position = info.nPos; + horizontalScrollBar.onChange(); + } + } else { + VerticalScrollBar &verticalScrollBar = (VerticalScrollBar&)*object; + if(verticalScrollBar.state.position != info.nPos) { + verticalScrollBar.state.position = info.nPos; + verticalScrollBar.onChange(); + } + } + + return TRUE; + } + if(dynamic_cast(object)) { HorizontalSlider &horizontalSlider = (HorizontalSlider&)*object; if(horizontalSlider.state.position != horizontalSlider.position()) { diff --git a/bsnes/phoenix/windows/windows.hpp b/bsnes/phoenix/windows/windows.hpp index 76bace93..1cc92696 100755 --- a/bsnes/phoenix/windows/windows.hpp +++ b/bsnes/phoenix/windows/windows.hpp @@ -78,10 +78,11 @@ struct pWindow : public pObject { void append(Layout &layout); void append(Menu &menu); void append(Widget &widget); + Color backgroundColor(); bool focused(); Geometry frameMargin(); Geometry geometry(); - void setBackgroundColor(uint8_t red, uint8_t green, uint8_t blue); + void setBackgroundColor(const Color &color); void setFocused(); void setFullScreen(bool fullScreen); void setGeometry(const Geometry &geometry); @@ -250,6 +251,19 @@ struct pHexEdit : public pWidget { void setParent(Window &parent); }; +struct pHorizontalScrollBar : public pWidget { + HorizontalScrollBar &horizontalScrollBar; + + Geometry minimumGeometry(); + unsigned position(); + void setLength(unsigned length); + void setPosition(unsigned position); + + pHorizontalScrollBar(HorizontalScrollBar &horizontalScrollBar) : pWidget(horizontalScrollBar), horizontalScrollBar(horizontalScrollBar) {} + void constructor(); + void setParent(Window &parent); +}; + struct pHorizontalSlider : public pWidget { HorizontalSlider &horizontalSlider; @@ -350,6 +364,19 @@ struct pTextEdit : public pWidget { void setParent(Window &parent); }; +struct pVerticalScrollBar : public pWidget { + VerticalScrollBar &verticalScrollBar; + + Geometry minimumGeometry(); + unsigned position(); + void setLength(unsigned length); + void setPosition(unsigned position); + + pVerticalScrollBar(VerticalScrollBar &verticalScrollBar) : pWidget(verticalScrollBar), verticalScrollBar(verticalScrollBar) {} + void constructor(); + void setParent(Window &parent); +}; + struct pVerticalSlider : public pWidget { VerticalSlider &verticalSlider; diff --git a/bsnes/snes/snes.hpp b/bsnes/snes/snes.hpp index 7af71635..4c6a2b87 100755 --- a/bsnes/snes/snes.hpp +++ b/bsnes/snes/snes.hpp @@ -1,7 +1,7 @@ namespace SNES { namespace Info { static const char Name[] = "bsnes"; - static const char Version[] = "080.04"; + static const char Version[] = "080.05"; static const unsigned SerializerVersion = 21; } } diff --git a/bsnes/ui-gameboy/Makefile b/bsnes/ui-gameboy/Makefile index e1d0fdb9..00911327 100755 --- a/bsnes/ui-gameboy/Makefile +++ b/bsnes/ui-gameboy/Makefile @@ -5,11 +5,13 @@ ui_objects += ruby phoenix # platform ifeq ($(platform),x) -# phoenix_compile = $(call compile,-DPHOENIX_GTK `pkg-config --cflags gtk+-2.0`) -# link += `pkg-config --libs gtk+-2.0` - - phoenix_compile = $(call compile,-DPHOENIX_QT `pkg-config --cflags QtCore QtGui`) - link += `pkg-config --libs QtCore QtGui` + ifeq ($(phoenix),gtk) + phoenix_compile = $(call compile,-DPHOENIX_GTK `pkg-config --cflags gtk+-2.0`) + link += `pkg-config --libs gtk+-2.0` + else + phoenix_compile = $(call compile,-DPHOENIX_QT `pkg-config --cflags QtCore QtGui`) + link += `pkg-config --libs QtCore QtGui` + endif ruby := video.glx video.xv video.sdl ruby += audio.alsa audio.openal audio.oss audio.pulseaudio audio.pulseaudiosimple audio.ao diff --git a/bsnes/ui-gameboy/interface.cpp b/bsnes/ui-gameboy/interface.cpp index 15a1e0d5..1b1d27b8 100755 --- a/bsnes/ui-gameboy/interface.cpp +++ b/bsnes/ui-gameboy/interface.cpp @@ -37,7 +37,7 @@ void Interface::input_poll() { } bool Interface::input_poll(unsigned id) { - switch(id) { + switch((GameBoy::Input)id) { case GameBoy::Input::Up: return inputState[keyboard(0)[Keyboard::Up]]; case GameBoy::Input::Down: return inputState[keyboard(0)[Keyboard::Down]]; case GameBoy::Input::Left: return inputState[keyboard(0)[Keyboard::Left]]; diff --git a/bsnes/ui/Makefile b/bsnes/ui/Makefile index 7cf34207..dc521b62 100755 --- a/bsnes/ui/Makefile +++ b/bsnes/ui/Makefile @@ -7,11 +7,13 @@ ui_objects += $(if $(call streq,$(platform),win),resource) # platform ifeq ($(platform),x) -# phoenix_compile = $(call compile,-DPHOENIX_GTK `pkg-config --cflags gtk+-2.0`) -# link += `pkg-config --libs gtk+-2.0` - - phoenix_compile = $(call compile,-DPHOENIX_QT `pkg-config --cflags QtCore QtGui`) - link += `pkg-config --libs QtCore QtGui` + ifeq ($(phoenix),gtk) + phoenix_compile = $(call compile,-DPHOENIX_GTK `pkg-config --cflags gtk+-2.0`) + link += `pkg-config --libs gtk+-2.0` + else + phoenix_compile = $(call compile,-DPHOENIX_QT `pkg-config --cflags QtCore QtGui`) + link += `pkg-config --libs QtCore QtGui` + endif ruby := video.glx video.xv video.sdl ruby += audio.alsa audio.openal audio.oss audio.pulseaudio audio.pulseaudiosimple audio.ao diff --git a/bsnes/ui/config.cpp b/bsnes/ui/config.cpp index df3a78a0..7e676df1 100755 --- a/bsnes/ui/config.cpp +++ b/bsnes/ui/config.cpp @@ -43,6 +43,7 @@ void Configuration::create() { attach(input.driver = "", "input.driver"); + attach(settings.startFullScreen = false, "settings.startFullScreen", "Start in full screen mode for front-end use"); attach(settings.focusPolicy = 0, "settings.focusPolicy"); attach(controller.port1 = 1, "controller.port1"); diff --git a/bsnes/ui/config.hpp b/bsnes/ui/config.hpp index ac577c33..d8413510 100755 --- a/bsnes/ui/config.hpp +++ b/bsnes/ui/config.hpp @@ -30,6 +30,7 @@ struct Configuration : public configuration { } input; struct Settings { + bool startFullScreen; unsigned focusPolicy; } settings; diff --git a/bsnes/ui/general/about-window.cpp b/bsnes/ui/general/about-window.cpp index 0143f533..0f6cdd93 100755 --- a/bsnes/ui/general/about-window.cpp +++ b/bsnes/ui/general/about-window.cpp @@ -6,7 +6,7 @@ void AboutWindow::create() { application.addWindow(this, "AboutWindow", "160,160"); setTitle("About bsnes ..."); setResizable(false); - setBackgroundColor(255, 255, 255); + setBackgroundColor({ 255, 255, 255 }); information.setText({ "bsnes v", SNES::Info::Version, " ~ Profile: ", SNES::Info::Profile, diff --git a/bsnes/ui/general/main-window.cpp b/bsnes/ui/general/main-window.cpp index 9ddfcdb3..05cba25b 100755 --- a/bsnes/ui/general/main-window.cpp +++ b/bsnes/ui/general/main-window.cpp @@ -7,7 +7,7 @@ void MainWindow::create() { application.addWindow(this, "MainWindow", "128,128"); setMenuFont(application.proportionalFont); setStatusFont(application.proportionalFontBold); - setBackgroundColor(0, 0, 0); + setBackgroundColor({ 0, 0, 0 }); system.setText("System"); diff --git a/bsnes/ui/input/hotkeys.cpp b/bsnes/ui/input/hotkeys.cpp index fb716545..007fc878 100755 --- a/bsnes/ui/input/hotkeys.cpp +++ b/bsnes/ui/input/hotkeys.cpp @@ -29,7 +29,7 @@ void InputMapper::poll_hotkeys(unsigned scancode, int16_t value) { //fullscreen if(scancode == hotkeysGeneral.fullscreenToggle.scancode) { - utility.setFullscreen(!utility.fullscreen); + utility.setFullScreen(!utility.fullScreen); } //mouse capture diff --git a/bsnes/ui/main.cpp b/bsnes/ui/main.cpp index 80376cb2..9e9d9341 100755 --- a/bsnes/ui/main.cpp +++ b/bsnes/ui/main.cpp @@ -109,6 +109,7 @@ void Application::main(int argc, char **argv) { utility.setControllers(); utility.setFilter(); utility.setShader(); + if(config.settings.startFullScreen) utility.setFullScreen(); if(argc == 2) cartridge.loadNormal(argv[1]); diff --git a/bsnes/ui/tools/cheat-editor.cpp b/bsnes/ui/tools/cheat-editor.cpp index eb76f5d7..024936fa 100755 --- a/bsnes/ui/tools/cheat-editor.cpp +++ b/bsnes/ui/tools/cheat-editor.cpp @@ -5,7 +5,7 @@ void CheatEditor::load() { cheatList.reset(); for(unsigned i = 0; i < 128; i++) { cheatList.append(""); - cheatText[i][CheatSlot] = rdecimal<3>(i + 1); + cheatText[i][CheatSlot] = decimal<3>(i + 1); cheatText[i][CheatCode] = ""; cheatText[i][CheatDesc] = ""; } diff --git a/bsnes/ui/tools/state-manager.cpp b/bsnes/ui/tools/state-manager.cpp index e226ae58..1a39eab5 100755 --- a/bsnes/ui/tools/state-manager.cpp +++ b/bsnes/ui/tools/state-manager.cpp @@ -46,7 +46,7 @@ void StateManager::synchronize() { void StateManager::refresh() { for(unsigned i = 0; i < 32; i++) { - stateList.modify(i, rdecimal<2>(i + 1), slotLoadDescription(i)); + stateList.modify(i, decimal<2>(i + 1), slotLoadDescription(i)); } stateList.autoSizeColumns(); } diff --git a/bsnes/ui/utility/utility.cpp b/bsnes/ui/utility/utility.cpp index 198f561a..e1652f96 100755 --- a/bsnes/ui/utility/utility.cpp +++ b/bsnes/ui/utility/utility.cpp @@ -82,13 +82,13 @@ void Utility::setScale(unsigned scale) { mainWindow.setGeometry({ geom.x, geom.y, width, height }); } -void Utility::setFullscreen(bool fullscreen) { - this->fullscreen = fullscreen; +void Utility::setFullScreen(bool fullScreen) { + this->fullScreen = fullScreen; - mainWindow.setMenuVisible(!fullscreen); - mainWindow.setStatusVisible(!fullscreen); - mainWindow.setFullScreen(fullscreen); - if(fullscreen == false) { + mainWindow.setMenuVisible(!fullScreen); + mainWindow.setStatusVisible(!fullScreen); + mainWindow.setFullScreen(fullScreen); + if(fullScreen == false) { input.unacquire(); setScale(); } else { @@ -215,6 +215,6 @@ void Utility::loadState(unsigned slot) { } Utility::Utility() { - fullscreen = false; + fullScreen = false; statusTime = 0; } diff --git a/bsnes/ui/utility/utility.hpp b/bsnes/ui/utility/utility.hpp index 9f7fd04a..b8b7cac6 100755 --- a/bsnes/ui/utility/utility.hpp +++ b/bsnes/ui/utility/utility.hpp @@ -7,7 +7,7 @@ struct Utility : property { void setControllers(); void setScale(unsigned scale = 0); - void setFullscreen(bool fullscreen = true); + void setFullScreen(bool fullScreen = true); void setFilter(); void setShader(); @@ -21,7 +21,7 @@ struct Utility : property { Utility(); - bool fullscreen; + bool fullScreen; unsigned viewportX, viewportY; unsigned viewportWidth, viewportHeight;