Update to v093r02 release.

byuu says:

Changelog:
- nall: fixed major memory leak in string class
- ruby: video shaders support #define-based settings now
- phoenix/GTK+: support > 256x256 icons for window / task bar / alt-tab
- sfc: remove random/ and config/, merge into system/
- ethos: delete higan.png (48x48), replace with higan512.png (512x512)
  as new higan.png
- ethos: default gamma to 100% (no color adjustment)
- ethos: use "Video Shaders/Display Emulation/" instead of "Video
  Shaders/Emulation/"
- use g++ instead of g++-4.7 (g++ -v must be >= 4.7)
- use -std=c++11 instead of -std=gnu++11
- applied a few patches from Debian upstream to make their packaging job
  easier

So because colors are normalized in GLSL, I won't be able to offer video
shaders absolute color literals. We will have to perform basic color
conversion inside the core.

As such, the current plan is to create some sort of Emulator::Settings
interface. With that, I'll connect an option for color correction, which
will be on by default. For FC/SFC, that will mean gamma correction
(darker / stronger colors), and for GB/GBC/GBA, it will mean simulating
the weird brightness levels of the displays. I am undecided on whether
to use pea soup green for the GB or not. By not doing so, it'll be
easier for the display emulation shader to do it.
This commit is contained in:
Tim Allen 2013-11-09 22:45:54 +11:00
parent 66f136718e
commit 8c0b0fa4ad
87 changed files with 1446 additions and 455 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.2 KiB

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 25 KiB

View File

@ -3,7 +3,7 @@
namespace Emulator { namespace Emulator {
static const char Name[] = "higan"; static const char Name[] = "higan";
static const char Version[] = "093.01"; static const char Version[] = "093.02";
static const char Author[] = "byuu"; static const char Author[] = "byuu";
static const char License[] = "GPLv3"; static const char License[] = "GPLv3";
static const char Website[] = "http://byuu.org/"; static const char Website[] = "http://byuu.org/";

View File

@ -10,10 +10,7 @@
[space] := [space] :=
[space] += [space] +=
#####
# platform detection # platform detection
#####
ifeq ($(platform),) ifeq ($(platform),)
uname := $(shell uname -s) uname := $(shell uname -s)
ifeq ($(uname),) ifeq ($(uname),)
@ -37,6 +34,7 @@ ifeq ($(platform),)
endif endif
endif endif
# compiler detection
ifeq ($(compiler),) ifeq ($(compiler),)
ifeq ($(platform),windows) ifeq ($(platform),windows)
compiler := g++ compiler := g++
@ -48,19 +46,20 @@ ifeq ($(compiler),)
link := -lc++ -lobjc link := -lc++ -lobjc
else ifeq ($(platform),bsd) else ifeq ($(platform),bsd)
compiler := clang++ compiler := clang++
flags := -w flags := -w -I/usr/local/include
else else
compiler := g++-4.7 compiler := g++
flags := flags :=
link := link :=
endif endif
cflags := -x c -std=gnu99 cflags := -x c -std=c99
objcflags := -x objective-c -std=gnu99 objcflags := -x objective-c -std=c99
cppflags := -x c++ -std=gnu++11 cppflags := -x c++ -std=c++11
objcppflags := -x objective-c++ -std=gnu++11 objcppflags := -x objective-c++ -std=c++11
endif endif
# cross-compilation support
ifeq ($(arch),x86) ifeq ($(arch),x86)
flags := -m32 $(flags) flags := -m32 $(flags)
link := -m32 $(link) link := -m32 $(link)
@ -70,9 +69,7 @@ ifeq ($(prefix),)
prefix := /usr/local prefix := /usr/local
endif endif
#####
# function rwildcard(directory, pattern) # function rwildcard(directory, pattern)
#####
rwildcard = \ rwildcard = \
$(strip \ $(strip \
$(filter $(if $2,$2,%), \ $(filter $(if $2,$2,%), \
@ -84,9 +81,7 @@ rwildcard = \
) \ ) \
) )
#####
# function strtr(source, from, to) # function strtr(source, from, to)
#####
strtr = \ strtr = \
$(eval __temp := $1) \ $(eval __temp := $1) \
$(strip \ $(strip \
@ -99,19 +94,13 @@ strtr = \
$(__temp) \ $(__temp) \
) )
#####
# function strupper(source) # function strupper(source)
#####
strupper = $(call strtr,$1,$([a-z]),$([A-Z])) strupper = $(call strtr,$1,$([a-z]),$([A-Z]))
#####
# function strlower(source) # function strlower(source)
#####
strlower = $(call strtr,$1,$([A-Z]),$([a-z])) strlower = $(call strtr,$1,$([A-Z]),$([a-z]))
#####
# function strlen(source) # function strlen(source)
#####
strlen = \ strlen = \
$(eval __temp := $(subst $([space]),_,$1)) \ $(eval __temp := $(subst $([space]),_,$1)) \
$(words \ $(words \
@ -126,12 +115,8 @@ strlen = \
) \ ) \
) )
#####
# function streq(source) # function streq(source)
#####
streq = $(if $(filter-out xx,x$(subst $1,,$2)$(subst $2,,$1)x),,1) streq = $(if $(filter-out xx,x$(subst $1,,$2)$(subst $2,,$1)x),,1)
#####
# function strne(source) # function strne(source)
#####
strne = $(if $(filter-out xx,x$(subst $1,,$2)$(subst $2,,$1)x),1,) strne = $(if $(filter-out xx,x$(subst $1,,$2)$(subst $2,,$1)x),1,)

View File

@ -8,6 +8,7 @@ namespace nall {
constexpr inline uintmax_t binary_(const char* s, uintmax_t sum = 0) { constexpr inline uintmax_t binary_(const char* s, uintmax_t sum = 0) {
return ( return (
*s == '0' || *s == '1' ? binary_(s + 1, (sum << 1) | *s - '0') : *s == '0' || *s == '1' ? binary_(s + 1, (sum << 1) | *s - '0') :
*s == '\'' ? binary_(s + 1, sum) :
sum sum
); );
} }
@ -15,6 +16,7 @@ constexpr inline uintmax_t binary_(const char* s, uintmax_t sum = 0) {
constexpr inline uintmax_t octal_(const char* s, uintmax_t sum = 0) { constexpr inline uintmax_t octal_(const char* s, uintmax_t sum = 0) {
return ( return (
*s >= '0' && *s <= '7' ? octal_(s + 1, (sum << 3) | *s - '0') : *s >= '0' && *s <= '7' ? octal_(s + 1, (sum << 3) | *s - '0') :
*s == '\'' ? octal_(s + 1, sum) :
sum sum
); );
} }
@ -22,6 +24,7 @@ constexpr inline uintmax_t octal_(const char* s, uintmax_t sum = 0) {
constexpr inline uintmax_t decimal_(const char* s, uintmax_t sum = 0) { constexpr inline uintmax_t decimal_(const char* s, uintmax_t sum = 0) {
return ( return (
*s >= '0' && *s <= '9' ? decimal_(s + 1, (sum * 10) + *s - '0') : *s >= '0' && *s <= '9' ? decimal_(s + 1, (sum * 10) + *s - '0') :
*s == '\'' ? decimal_(s + 1, sum) :
sum sum
); );
} }
@ -31,6 +34,7 @@ constexpr inline uintmax_t hex_(const char* s, uintmax_t sum = 0) {
*s >= 'A' && *s <= 'F' ? hex_(s + 1, (sum << 4) | *s - 'A' + 10) : *s >= 'A' && *s <= 'F' ? hex_(s + 1, (sum << 4) | *s - 'A' + 10) :
*s >= 'a' && *s <= 'f' ? hex_(s + 1, (sum << 4) | *s - 'a' + 10) : *s >= 'a' && *s <= 'f' ? hex_(s + 1, (sum << 4) | *s - 'a' + 10) :
*s >= '0' && *s <= '9' ? hex_(s + 1, (sum << 4) | *s - '0') : *s >= '0' && *s <= '9' ? hex_(s + 1, (sum << 4) | *s - '0') :
*s == '\'' ? hex_(s + 1, sum) :
sum sum
); );
} }

View File

@ -32,7 +32,7 @@ struct Node {
void set(const string& value) { void set(const string& value) {
switch(type) { switch(type) {
case Type::Bool: *(bool*)data = (value == "true"); break; case Type::Bool: *(bool*)data = (value != "false"); break;
case Type::Signed: *(signed*)data = integer(value); break; case Type::Signed: *(signed*)data = integer(value); break;
case Type::Unsigned: *(unsigned*)data = decimal(value); break; case Type::Unsigned: *(unsigned*)data = decimal(value); break;
case Type::Double: *(double*)data = real(value); break; case Type::Double: *(double*)data = real(value); break;

View File

@ -1,6 +1,8 @@
#ifndef NALL_DSP_HPP #ifndef NALL_DSP_HPP
#define NALL_DSP_HPP #define NALL_DSP_HPP
#include <nall/bit.hpp>
#include <algorithm> #include <algorithm>
#ifdef __SSE__ #ifdef __SSE__
#include <xmmintrin.h> #include <xmmintrin.h>

View File

@ -535,7 +535,7 @@ void ResampleUtility::gen_sinc(double* out, int size, double cutoff, double kais
// Generate right half of sinc // Generate right half of sinc
for ( int i = 0; i < half_size; i++ ) for ( int i = 0; i < half_size; i++ )
{ {
double angle = (i * 2 + 1) * (M_PI / 2); double angle = (i * 2 + 1) * (Math::Pi / 2);
mid [i] = sin( angle * cutoff ) / angle; mid [i] = sin( angle * cutoff ) / angle;
} }
@ -553,9 +553,9 @@ void ResampleUtility::gen_sinc_os(double* out, int size, double cutoff, double k
for(int i = 0; i < size; i++) for(int i = 0; i < size; i++)
{ {
if(i == (size / 2)) if(i == (size / 2))
out[i] = 2 * M_PI * (cutoff / 2); //0.078478; //1.0; //sin(2 * M_PI * (cutoff / 2) * (i - size / 2)) / (i - (size / 2)); out[i] = 2 * Math::Pi * (cutoff / 2); //0.078478; //1.0; //sin(2 * M_PI * (cutoff / 2) * (i - size / 2)) / (i - (size / 2));
else else
out[i] = sin(2 * M_PI * (cutoff / 2) * (i - size / 2)) / (i - (size / 2)); out[i] = sin(2 * Math::Pi * (cutoff / 2) * (i - size / 2)) / (i - (size / 2));
// out[i] *= 0.3635819 - 0.4891775 * cos(2 * M_PI * i / (size - 1)) + 0.1365995 * cos(4 * M_PI * i / (size - 1)) - 0.0106411 * cos(6 * M_PI * i / (size - 1)); // out[i] *= 0.3635819 - 0.4891775 * cos(2 * M_PI * i / (size - 1)) + 0.1365995 * cos(4 * M_PI * i / (size - 1)) - 0.0106411 * cos(6 * M_PI * i / (size - 1));
//0.42 - 0.5 * cos(2 * M_PI * i / (size - 1)) + 0.08 * cos(4 * M_PI * i / (size - 1)); //0.42 - 0.5 * cos(2 * M_PI * i / (size - 1)) + 0.08 * cos(4 * M_PI * i / (size - 1));

View File

@ -5,6 +5,7 @@
#include <nall/stdint.hpp> #include <nall/stdint.hpp>
#include <nall/string.hpp> #include <nall/string.hpp>
#include <nall/utility.hpp> #include <nall/utility.hpp>
#include <nall/varint.hpp>
#include <nall/windows/utf8.hpp> #include <nall/windows/utf8.hpp>
#include <nall/stream/memory.hpp> #include <nall/stream/memory.hpp>
@ -18,7 +19,7 @@ inline FILE* fopen_utf8(const string& filename, const string& mode) {
#endif #endif
} }
struct file { struct file : varint {
enum class mode : unsigned { read, write, modify, append, readwrite = modify, writeread = append }; enum class mode : unsigned { read, write, modify, append, readwrite = modify, writeread = append };
enum class index : unsigned { absolute, relative }; enum class index : unsigned { absolute, relative };
enum class time : unsigned { create, modify, access }; enum class time : unsigned { create, modify, access };
@ -32,11 +33,16 @@ struct file {
} }
static bool move(const string& sourcename, const string& targetname) { static bool move(const string& sourcename, const string& targetname) {
#if !defined(_WIN32) auto result = rename(sourcename, targetname);
return rename(sourcename, targetname) == 0; if(result == 0) return true;
#else if(errno == EXDEV) {
return _wrename(utf16_t(sourcename), utf16_t(targetname)) == 0; //cannot move files between file systems; copy file instead of failing
#endif if(file::copy(sourcename, targetname)) {
file::remove(sourcename);
return true;
}
}
return false;
} }
static bool remove(const string& filename) { static bool remove(const string& filename) {

View File

@ -496,9 +496,9 @@ bool image::loadPNG(const uint8_t* pngData, unsigned pngSize) {
} }
bool image::loadPNG(const string& filename) { bool image::loadPNG(const string& filename) {
filemap map; if(!file::exists(filename)) return false;
if(map.open(filename, filemap::mode::read) == false) return false; auto buffer = file::read(filename);
return loadPNG(map.data(), map.size()); return loadPNG(buffer.data(), buffer.size());
} }
} }

View File

@ -4,12 +4,14 @@
namespace nall { namespace nall {
struct Intrinsics { struct Intrinsics {
enum class Compiler : unsigned { Clang, GCC, VisualC, Unknown }; enum class Compiler : unsigned { Clang, GCC, VisualCPP, Unknown };
enum class Platform : unsigned { X, OSX, Windows, Unknown }; enum class Platform : unsigned { Windows, MacOSX, X, Unknown }; //X = Linux, BSD, etc
enum class Architecture : unsigned { x86, amd64, Unknown };
enum class Endian : unsigned { LSB, MSB, Unknown }; enum class Endian : unsigned { LSB, MSB, Unknown };
static inline Compiler compiler(); static inline Compiler compiler();
static inline Platform platform(); static inline Platform platform();
static inline Architecture architecture();
static inline Endian endian(); static inline Endian endian();
}; };
@ -22,8 +24,8 @@ struct Intrinsics {
#define COMPILER_GCC #define COMPILER_GCC
Intrinsics::Compiler Intrinsics::compiler() { return Intrinsics::Compiler::GCC; } Intrinsics::Compiler Intrinsics::compiler() { return Intrinsics::Compiler::GCC; }
#elif defined(_MSC_VER) #elif defined(_MSC_VER)
#define COMPILER_VISUALC #define COMPILER_VISUALCPP
Intrinsics::Compiler Intrinsics::compiler() { return Intrinsics::Compiler::VisualC; } Intrinsics::Compiler Intrinsics::compiler() { return Intrinsics::Compiler::VisualCPP; }
#else #else
#warning "unable to detect compiler" #warning "unable to detect compiler"
#define COMPILER_UNKNOWN #define COMPILER_UNKNOWN
@ -32,36 +34,46 @@ struct Intrinsics {
/* Platform detection */ /* Platform detection */
#if defined(linux) || defined(__linux__) || defined(__sun__) || defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__NetBSD__) || defined(__OpenBSD__) #if defined(_WIN32)
#define PLATFORM_WINDOWS
Intrinsics::Platform Intrinsics::platform() { return Intrinsics::Platform::Windows; }
#elif defined(__APPLE__)
#define PLATFORM_MACOSX
Intrinsics::Platform Intrinsics::platform() { return Intrinsics::Platform::MacOSX; }
#elif defined(linux) || defined(__linux__) || defined(__sun__) || defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__GNU__)
#define PLATFORM_X #define PLATFORM_X
Intrinsics::Platform Intrinsics::platform() { return Intrinsics::Platform::X; } Intrinsics::Platform Intrinsics::platform() { return Intrinsics::Platform::X; }
#elif defined(__APPLE__)
#define PLATFORM_OSX
Intrinsics::Platform Intrinsics::platform() { return Intrinsics::Platform::OSX; }
#elif defined(_WIN32)
#define PLATFORM_WINDOWS
#define PLATFORM_WIN
Intrinsics::Platform Intrinsics::platform() { return Intrinsics::Platform::Windows; }
#else #else
#warning "unable to detect platform" #warning "unable to detect platform"
#define PLATFORM_UNKNOWN #define PLATFORM_UNKNOWN
Intrinsics::Platform Intrinsics::platform() { return Intrinsics::Platform::Unknown; } Intrinsics::Platform Intrinsics::platform() { return Intrinsics::Platform::Unknown; }
#endif #endif
/* Architecture Detection */
#if defined(__i386__) || defined(_M_IX86)
#define ARCH_X86
Intrinsics::Architecture Intrinsics::architecture() { return Intrinsics::Architecture::x86; }
#elif defined(__amd64__) || defined(_M_AMD64)
#define ARCH_AMD64
Intrinsics::Architecture Intrinsics::architecture() { return Intrinsics::Architecture::amd64; }
#else
#warning "unable to detect architecture"
#define ARCH_UNKNOWN
Intrinsics::Architecture Intrinsics::architecture() { return Intrinsics::Architecture::Unknown; }
#endif
/* Endian detection */ /* Endian detection */
#if defined(__i386__) || defined(__amd64__) || defined(_M_IX86) || defined(_M_AMD64) #if (defined(__BYTE_ORDER) && defined(__LITTLE_ENDIAN) && __BYTE_ORDER == __LITTLE_ENDIAN) || defined(__LITTLE_ENDIAN__) || defined(__i386__) || defined(__amd64__) || defined(_M_IX86) || defined(_M_AMD64)
#define ENDIAN_LSB #define ENDIAN_LSB
#define ARCH_LSB
Intrinsics::Endian Intrinsics::endian() { return Intrinsics::Endian::LSB; } Intrinsics::Endian Intrinsics::endian() { return Intrinsics::Endian::LSB; }
#elif defined(__powerpc__) || defined(_M_PPC) || defined(__BIG_ENDIAN__) #elif (defined(__BYTE_ORDER) && defined(__BIG_ENDIAN) && __BYTE_ORDER == __BIG_ENDIAN) || defined(__BIG_ENDIAN__) || defined(__powerpc__) || defined(_M_PPC)
#define ENDIAN_MSB #define ENDIAN_MSB
#define ARCH_MSB
Intrinsics::Endian Intrinsics::endian() { return Intrinsics::Endian::MSB; } Intrinsics::Endian Intrinsics::endian() { return Intrinsics::Endian::MSB; }
#else #else
#warning "unable to detect endian" #warning "unable to detect endian"
#define ENDIAN_UNKNOWN #define ENDIAN_UNKNOWN
#define ARCH_UNKNOWN
Intrinsics::Endian Intrinsics::endian() { return Intrinsics::Endian::Unknown; } Intrinsics::Endian Intrinsics::endian() { return Intrinsics::Endian::Unknown; }
#endif #endif

View File

@ -23,7 +23,7 @@ namespace nall {
template<typename... Args> inline void invoke(const string& name, Args&&... args) { template<typename... Args> inline void invoke(const string& name, Args&&... args) {
lstring argl(std::forward<Args>(args)...); lstring argl(std::forward<Args>(args)...);
for(auto& arg : argl) if(arg.find(" ")) arg = {"\"", arg, "\""}; for(auto& arg : argl) if(arg.find(" ")) arg = {"\"", arg, "\""};
string arguments = argl.concatenate(" "); string arguments = argl.merge(" ");
ShellExecuteW(NULL, NULL, utf16_t(name), utf16_t(arguments), NULL, SW_SHOWNORMAL); ShellExecuteW(NULL, NULL, utf16_t(name), utf16_t(arguments), NULL, SW_SHOWNORMAL);
} }

View File

@ -1,6 +1,11 @@
#ifndef NALL_PLATFORM_HPP #ifndef NALL_PLATFORM_HPP
#define NALL_PLATFORM_HPP #define NALL_PLATFORM_HPP
namespace Math {
static const long double e = 2.71828182845904523536;
static const long double Pi = 3.14159265358979323846;
}
#if defined(_WIN32) #if defined(_WIN32)
//minimum version needed for _wstat64, etc //minimum version needed for _wstat64, etc
#undef __MSVCRT_VERSION__ #undef __MSVCRT_VERSION__
@ -40,29 +45,24 @@
#define dllexport #define dllexport
#endif #endif
//================== //==========
//warning supression
//==================
//Visual C++ //Visual C++
#if defined(_MSC_VER) //==========
//disable libc "deprecation" warnings
#pragma warning(disable:4996)
#endif
//================
//POSIX compliance
//================
#if defined(_MSC_VER) #if defined(_MSC_VER)
#define PATH_MAX _MAX_PATH #pragma warning(disable:4996) //disable libc "deprecation" warnings
#define va_copy(dest, src) ((dest) = (src)) #define va_copy(dest, src) ((dest) = (src))
#endif #endif
#if defined(_WIN32) #if defined(_WIN32)
#define getcwd _getcwd extern "C" int _fileno(FILE*);
#define putenv _putenv
#define vsnprintf _vsnprintf inline int access(const char* path, int amode) { return _waccess(nall::utf16_t(path), amode); }
inline int fileno(FILE* stream) { return _fileno(stream); }
inline char* getcwd(char* buf, size_t size) { wchar_t wpath[PATH_MAX] = L""; if(!_wgetcwd(wpath, size)) return nullptr; strcpy(buf, nall::utf8_t(wpath)); return buf; }
inline int putenv(char* string) { return _wputenv(nall::utf16_t(string)); }
inline char* realpath(const char* file_name, char* resolved_name) { wchar_t wfile_name[PATH_MAX] = L""; if(!_wfullpath(wfile_name, nall::utf16_t(file_name), PATH_MAX)) return nullptr; strcpy(resolved_name, nall::utf8_t(wfile_name)); return resolved_name; }
inline int rename(const char* oldname, const char* newname) { return _wrename(nall::utf16_t(oldname), nall::utf16_t(newname)); }
inline void usleep(unsigned milliseconds) { Sleep(milliseconds / 1000); } inline void usleep(unsigned milliseconds) { Sleep(milliseconds / 1000); }
#endif #endif
@ -72,15 +72,12 @@
#if defined(__clang__) || defined(__GNUC__) #if defined(__clang__) || defined(__GNUC__)
#define noinline __attribute__((noinline)) #define noinline __attribute__((noinline))
#define inline inline
#define alwaysinline inline __attribute__((always_inline)) #define alwaysinline inline __attribute__((always_inline))
#elif defined(_MSC_VER) #elif defined(_MSC_VER)
#define noinline __declspec(noinline) #define noinline __declspec(noinline)
#define inline inline
#define alwaysinline inline __forceinline #define alwaysinline inline __forceinline
#else #else
#define noinline #define noinline
#define inline inline
#define alwaysinline inline #define alwaysinline inline
#endif #endif

View File

@ -137,7 +137,7 @@ bool png::decode(const uint8_t* sourceData, unsigned sourceSize) {
uint8_t *interlacedData = new uint8_t[interlacedSize]; uint8_t *interlacedData = new uint8_t[interlacedSize];
bool result = inflate(interlacedData, interlacedSize, compressedData + 2, compressedSize - 6); bool result = inflate(interlacedData, interlacedSize, compressedData + 2, compressedSize - 6);
delete[] compressedData; free(compressedData);
if(result == false) { if(result == false) {
delete[] interlacedData; delete[] interlacedData;

View File

@ -63,6 +63,7 @@ void string::reset() {
string& string::operator=(const string& source) { string& string::operator=(const string& source) {
if(&source == this) return *this; if(&source == this) return *this;
reset();
_data = source._data; _data = source._data;
_capacity = source._capacity; _capacity = source._capacity;
_size = source._size; _size = source._size;
@ -71,6 +72,7 @@ string& string::operator=(const string& source) {
string& string::operator=(string&& source) { string& string::operator=(string&& source) {
if(&source == this) return *this; if(&source == this) return *this;
reset();
_data = std::move(source._data); _data = std::move(source._data);
_capacity = source._capacity; _capacity = source._capacity;
_size = source._size; _size = source._size;
@ -80,17 +82,21 @@ string& string::operator=(string&& source) {
} }
template<typename T, typename... Args> string::string(T&& source, Args&&... args) { template<typename T, typename... Args> string::string(T&& source, Args&&... args) {
_capacity = 0; construct();
_size = 0;
sprint(*this, std::forward<T>(source), std::forward<Args>(args)...); sprint(*this, std::forward<T>(source), std::forward<Args>(args)...);
} }
string::string() { string::string() {
_capacity = 0; construct();
_size = 0;
} }
string::~string() { string::~string() {
reset();
}
void string::construct() {
_capacity = 0;
_size = 0;
} }
} }

View File

@ -63,6 +63,7 @@ void string::reset() {
string& string::operator=(const string& source) { string& string::operator=(const string& source) {
if(&source == this) return *this; if(&source == this) return *this;
reset();
if(source._capacity >= SSO) { if(source._capacity >= SSO) {
_data = (char*)malloc(source._capacity + 1); _data = (char*)malloc(source._capacity + 1);
_capacity = source._capacity; _capacity = source._capacity;
@ -78,6 +79,7 @@ string& string::operator=(const string& source) {
string& string::operator=(string&& source) { string& string::operator=(string&& source) {
if(&source == this) return *this; if(&source == this) return *this;
reset();
memcpy(this, &source, sizeof(string)); memcpy(this, &source, sizeof(string));
source._data = nullptr; source._data = nullptr;
source._capacity = SSO - 1; source._capacity = SSO - 1;
@ -86,20 +88,22 @@ string& string::operator=(string&& source) {
} }
template<typename T, typename... Args> string::string(T&& source, Args&&... args) { template<typename T, typename... Args> string::string(T&& source, Args&&... args) {
_data = nullptr; construct();
_capacity = SSO - 1;
_size = 0;
sprint(*this, std::forward<T>(source), std::forward<Args>(args)...); sprint(*this, std::forward<T>(source), std::forward<Args>(args)...);
} }
string::string() { string::string() {
_data = nullptr; construct();
_capacity = SSO - 1;
_size = 0;
} }
string::~string() { string::~string() {
if(_capacity >= SSO) free(_data); reset();
}
void string::construct() {
_data = nullptr;
_capacity = SSO - 1;
_size = 0;
} }
} }

View File

@ -50,6 +50,7 @@ void string::reset() {
string& string::operator=(const string& source) { string& string::operator=(const string& source) {
if(&source == this) return *this; if(&source == this) return *this;
reset();
_data = (char*)malloc(source._size + 1); _data = (char*)malloc(source._size + 1);
_capacity = source._size; _capacity = source._size;
_size = source._size; _size = source._size;
@ -59,6 +60,7 @@ string& string::operator=(const string& source) {
string& string::operator=(string&& source) { string& string::operator=(string&& source) {
if(&source == this) return *this; if(&source == this) return *this;
reset();
_data = source._data; _data = source._data;
_capacity = source._capacity; _capacity = source._capacity;
_size = source._size; _size = source._size;
@ -69,20 +71,22 @@ string& string::operator=(string&& source) {
} }
template<typename T, typename... Args> string::string(T&& source, Args&&... args) { template<typename T, typename... Args> string::string(T&& source, Args&&... args) {
_data = nullptr; construct();
_capacity = 0;
_size = 0;
sprint(*this, std::forward<T>(source), std::forward<Args>(args)...); sprint(*this, std::forward<T>(source), std::forward<Args>(args)...);
} }
string::string() { string::string() {
_data = nullptr; construct();
_capacity = 0;
_size = 0;
} }
string::~string() { string::~string() {
if(_data) free(_data); reset();
}
void string::construct() {
_data = nullptr;
_capacity = 0;
_size = 0;
} }
} }

View File

@ -144,6 +144,9 @@ public:
template<unsigned Limit, bool Insensitive, bool Quoted> inline string& ureplace(rstring, rstring); template<unsigned Limit, bool Insensitive, bool Quoted> inline string& ureplace(rstring, rstring);
inline string& _append(const char*); inline string& _append(const char*);
private:
inline void construct();
#if defined(QSTRING_H) #if defined(QSTRING_H)
public: public:
inline operator QString() const; inline operator QString() const;
@ -154,7 +157,6 @@ public:
struct lstring : vector<string> { struct lstring : vector<string> {
inline optional<unsigned> find(rstring) const; inline optional<unsigned> find(rstring) const;
inline string merge(const string&) const; inline string merge(const string&) const;
inline string concatenate(const string&) const; //deprecated
inline lstring& isort(); inline lstring& isort();
inline lstring& strip(); inline lstring& strip();
inline void append() {} inline void append() {}
@ -188,6 +190,7 @@ inline string notdir(string name);
inline string parentdir(string name); inline string parentdir(string name);
inline string basename(string name); inline string basename(string name);
inline string extension(string name); inline string extension(string name);
inline string tempname();
//format.hpp //format.hpp
template<signed precision = 0, char padchar = ' '> inline string format(const string& value); template<signed precision = 0, char padchar = ' '> inline string format(const string& value);

View File

@ -62,6 +62,7 @@ inline void utf8_write(char* s, const UTF8& utf8);
template<bool Insensitive> alwaysinline bool chrequal(char x, char y); template<bool Insensitive> alwaysinline bool chrequal(char x, char y);
template<bool Quoted, typename T> alwaysinline bool quoteskip(T*& p); template<bool Quoted, typename T> alwaysinline bool quoteskip(T*& p);
template<bool Quoted, typename T> alwaysinline bool quotecopy(char*& t, T*& p); template<bool Quoted, typename T> alwaysinline bool quotecopy(char*& t, T*& p);
inline char* strduplicate(const char* s);
} }

View File

@ -11,29 +11,40 @@ bool chrequal(char x, char y) {
template<bool Quoted, typename T> template<bool Quoted, typename T>
bool quoteskip(T*& p) { bool quoteskip(T*& p) {
if(Quoted == false) return false; if(Quoted == false) return false;
if(*p != '\'' && *p != '\"') return false; if(*p != '\"') return false;
while(*p == '\'' || *p == '\"') { while(*p == '\"') {
char x = *p++; char x = *p++;
while(*p && *p++ != x); while(*p && *p++ != x);
} }
return true; return true;
} }
template<bool Quoted, typename T> template<bool Quoted, typename T>
bool quotecopy(char*& t, T*& p) { bool quotecopy(char*& t, T*& p) {
if(Quoted == false) return false; if(Quoted == false) return false;
if(*p != '\'' && *p != '\"') return false; if(*p != '\"') return false;
while(*p == '\'' || *p == '\"') { while(*p == '\"') {
char x = *p++; char x = *p++;
*t++ = x; *t++ = x;
while(*p && *p != x) *t++ = *p++; while(*p && *p != x) *t++ = *p++;
*t++ = *p++; *t++ = *p++;
} }
return true; return true;
} }
//strdup() is not a standard function, so recreate it
char* strduplicate(const char* s) {
if(s == nullptr) return nullptr;
unsigned length = strlen(s);
char* result = (char*)malloc(length + 1);
strcpy(result, s);
return result;
}
} }
#endif #endif

View File

@ -75,10 +75,12 @@ bool string::operator> (const char* str) const { return strcmp(data(), str) > 0
bool string::operator>=(const char* str) const { return strcmp(data(), str) >= 0; } bool string::operator>=(const char* str) const { return strcmp(data(), str) >= 0; }
string::string(const string& source) { string::string(const string& source) {
construct();
operator=(source); operator=(source);
} }
string::string(string&& source) { string::string(string&& source) {
construct();
operator=(std::move(source)); operator=(std::move(source));
} }

View File

@ -19,7 +19,7 @@ inline string literalNumber(const char*& s) {
if(p[0] == '%' || (p[0] == '0' && p[1] == 'b')) { if(p[0] == '%' || (p[0] == '0' && p[1] == 'b')) {
unsigned prefix = 1 + (p[0] == '0'); unsigned prefix = 1 + (p[0] == '0');
p += prefix; p += prefix;
while(p[0] == '0' || p[0] == '1') p++; while(p[0] == '\'' || p[0] == '0' || p[0] == '1') p++;
if(p - s <= prefix) throw "invalid binary literal"; if(p - s <= prefix) throw "invalid binary literal";
string result = substr(s, 0, p - s); string result = substr(s, 0, p - s);
s = p; s = p;
@ -30,7 +30,7 @@ inline string literalNumber(const char*& s) {
if(p[0] == '0' && p[1] == 'o') { if(p[0] == '0' && p[1] == 'o') {
unsigned prefix = 1 + (p[0] == '0'); unsigned prefix = 1 + (p[0] == '0');
p += prefix; p += prefix;
while(p[0] >= '0' && p[0] <= '7') p++; while(p[0] == '\'' || (p[0] >= '0' && p[0] <= '7')) p++;
if(p - s <= prefix) throw "invalid octal literal"; if(p - s <= prefix) throw "invalid octal literal";
string result = substr(s, 0, p - s); string result = substr(s, 0, p - s);
s = p; s = p;
@ -41,7 +41,7 @@ inline string literalNumber(const char*& s) {
if(p[0] == '$' || (p[0] == '0' && p[1] == 'x')) { if(p[0] == '$' || (p[0] == '0' && p[1] == 'x')) {
unsigned prefix = 1 + (p[0] == '0'); unsigned prefix = 1 + (p[0] == '0');
p += prefix; p += prefix;
while((p[0] >= '0' && p[0] <= '9') || (p[0] >= 'A' && p[0] <= 'F') || (p[0] >= 'a' && p[0] <= 'f')) p++; while(p[0] == '\'' || (p[0] >= '0' && p[0] <= '9') || (p[0] >= 'A' && p[0] <= 'F') || (p[0] >= 'a' && p[0] <= 'f')) p++;
if(p - s <= prefix) throw "invalid hex literal"; if(p - s <= prefix) throw "invalid hex literal";
string result = substr(s, 0, p - s); string result = substr(s, 0, p - s);
s = p; s = p;
@ -49,7 +49,7 @@ inline string literalNumber(const char*& s) {
} }
//decimal //decimal
while(p[0] >= '0' && p[0] <= '9') p++; while(p[0] == '\'' || (p[0] >= '0' && p[0] <= '9')) p++;
if(p[0] != '.') { if(p[0] != '.') {
string result = substr(s, 0, p - s); string result = substr(s, 0, p - s);
s = p; s = p;
@ -58,7 +58,7 @@ inline string literalNumber(const char*& s) {
//floating-point //floating-point
p++; p++;
while(p[0] >= '0' && p[0] <= '9') p++; while(p[0] == '\'' || (p[0] >= '0' && p[0] <= '9')) p++;
string result = substr(s, 0, p - s); string result = substr(s, 0, p - s);
s = p; s = p;
return result; return result;

View File

@ -69,6 +69,16 @@ string extension(string name) {
return name; return name;
} }
string tempname() {
string path = temppath();
srand(time(nullptr));
while(true) {
uint32_t seed = rand();
string filename = {path, ".temporary-", hex<8>(seed)};
if(access(filename, F_OK) != 0) return filename;
}
}
} }
#endif #endif

View File

@ -18,11 +18,6 @@ string lstring::merge(const string& separator) const {
return output; return output;
} }
//deprecated: alias to merge()
string lstring::concatenate(const string& separator) const {
return merge(separator);
}
lstring& lstring::isort() { lstring& lstring::isort() {
nall::sort(pool, objectsize, [](const string& x, const string& y) { nall::sort(pool, objectsize, [](const string& x, const string& y) {
return istrcmp(x, y) < 0; return istrcmp(x, y) < 0;

View File

@ -115,7 +115,7 @@ struct Node {
if(path.size() == 0) result.append(node); if(path.size() == 0) result.append(node);
else { else {
auto list = node.find(path.concatenate("/")); auto list = node.find(path.merge("/"));
for(auto& item : list) result.append(item); for(auto& item : list) result.append(item);
} }
} }

View File

@ -3,33 +3,22 @@
namespace nall { namespace nall {
string activepath() { string activepath() {
string result;
#if defined(PLATFORM_WINDOWS)
wchar_t path[PATH_MAX] = L"";
auto unused = _wgetcwd(path, PATH_MAX);
result = (const char*)utf8_t(path);
result.transform("\\", "/");
#else
char path[PATH_MAX] = ""; char path[PATH_MAX] = "";
auto unused = getcwd(path, PATH_MAX); auto unused = getcwd(path, PATH_MAX);
result = path; string result = path;
#endif
if(result.empty()) result = "."; if(result.empty()) result = ".";
result.transform("\\", "/");
if(result.endswith("/") == false) result.append("/"); if(result.endswith("/") == false) result.append("/");
return result; return result;
} }
string realpath(const string& name) { string realpath(const string& name) {
string result; string result;
#if defined(PLATFORM_WINDOWS)
wchar_t path[PATH_MAX] = L"";
if(_wfullpath(path, utf16_t(name), PATH_MAX)) result = (const char*)utf8_t(path);
result.transform("\\", "/");
#else
char path[PATH_MAX] = ""; char path[PATH_MAX] = "";
if(::realpath(name, path)) result = path; if(::realpath(name, path)) result = path;
#endif
if(result.empty()) result = {activepath(), name}; if(result.empty()) result = {activepath(), name};
result.transform("\\", "/");
if(result.endswith("/") == false) result.append("/");
return result; return result;
} }

View File

@ -26,7 +26,7 @@ string& string::ureplace(rstring key, rstring token) {
signed displacementSize = displacement * counter; signed displacementSize = displacement * counter;
if(token.size() > key.size()) { if(token.size() > key.size()) {
t = base = strdup(data()); t = base = strduplicate(data());
reserve((unsigned)(p - data()) + displacementSize); reserve((unsigned)(p - data()) + displacementSize);
} }
char* o = data(); char* o = data();

View File

@ -3,10 +3,53 @@
#include <nall/bit.hpp> #include <nall/bit.hpp>
#include <nall/serializer.hpp> #include <nall/serializer.hpp>
#include <nall/stdint.hpp>
#include <nall/traits.hpp> #include <nall/traits.hpp>
namespace nall { namespace nall {
struct varint {
virtual uint8_t read() = 0;
virtual void write(uint8_t) = 0;
uintmax_t readvu() {
uintmax_t data = 0, shift = 1;
while(true) {
uint8_t x = read();
data += (x & 0x7f) * shift;
if(x & 0x80) break;
shift <<= 7;
data += shift;
}
return data;
}
intmax_t readvs() {
uintmax_t data = readvu();
bool sign = data & 1;
data >>= 1;
if(sign) data = -data;
return data;
}
void writevu(uintmax_t data) {
while(true) {
uint8_t x = data & 0x7f;
data >>= 7;
if(data == 0) return write(0x80 | x);
write(x);
data--;
}
}
void writevs(intmax_t data) {
bool sign = data < 0;
if(sign) data = -data;
data = (data << 1) | sign;
writevu(data);
}
};
template<unsigned bits> struct uint_t { template<unsigned bits> struct uint_t {
private: private:
typedef typename type_if<bits <= 8 * sizeof(unsigned), unsigned, uintmax_t>::type type_t; typedef typename type_if<bits <= 8 * sizeof(unsigned), unsigned, uintmax_t>::type type_t;

View File

@ -28,7 +28,7 @@ struct registry {
lstring part = name.split("/"); lstring part = name.split("/");
HKEY handle, rootKey = root(part.take(0)); HKEY handle, rootKey = root(part.take(0));
string node = part.take(); string node = part.take();
string path = part.concatenate("\\"); string path = part.merge("\\");
if(RegOpenKeyExW(rootKey, utf16_t(path), 0, NWR_FLAGS | KEY_READ, &handle) == ERROR_SUCCESS) { if(RegOpenKeyExW(rootKey, utf16_t(path), 0, NWR_FLAGS | KEY_READ, &handle) == ERROR_SUCCESS) {
wchar_t data[NWR_SIZE] = L""; wchar_t data[NWR_SIZE] = L"";
DWORD size = NWR_SIZE * sizeof(wchar_t); DWORD size = NWR_SIZE * sizeof(wchar_t);
@ -43,7 +43,7 @@ struct registry {
lstring part = name.split("/"); lstring part = name.split("/");
HKEY handle, rootKey = root(part.take(0)); HKEY handle, rootKey = root(part.take(0));
string node = part.take(); string node = part.take();
string path = part.concatenate("\\"); string path = part.merge("\\");
if(RegOpenKeyExW(rootKey, utf16_t(path), 0, NWR_FLAGS | KEY_READ, &handle) == ERROR_SUCCESS) { if(RegOpenKeyExW(rootKey, utf16_t(path), 0, NWR_FLAGS | KEY_READ, &handle) == ERROR_SUCCESS) {
wchar_t data[NWR_SIZE] = L""; wchar_t data[NWR_SIZE] = L"";
DWORD size = NWR_SIZE * sizeof(wchar_t); DWORD size = NWR_SIZE * sizeof(wchar_t);
@ -75,7 +75,7 @@ struct registry {
lstring part = name.split("/"); lstring part = name.split("/");
HKEY rootKey = root(part.take(0)); HKEY rootKey = root(part.take(0));
string node = part.take(); string node = part.take();
string path = part.concatenate("\\"); string path = part.merge("\\");
if(node.empty()) return SHDeleteKeyW(rootKey, utf16_t(path)) == ERROR_SUCCESS; if(node.empty()) return SHDeleteKeyW(rootKey, utf16_t(path)) == ERROR_SUCCESS;
return SHDeleteValueW(rootKey, utf16_t(path), utf16_t(node)) == ERROR_SUCCESS; return SHDeleteValueW(rootKey, utf16_t(path), utf16_t(node)) == ERROR_SUCCESS;
} }
@ -84,7 +84,7 @@ struct registry {
lstring part = name.split("/"), result; lstring part = name.split("/"), result;
HKEY handle, rootKey = root(part.take(0)); HKEY handle, rootKey = root(part.take(0));
part.remove(); part.remove();
string path = part.concatenate("\\"); string path = part.merge("\\");
if(RegOpenKeyExW(rootKey, utf16_t(path), 0, NWR_FLAGS | KEY_READ, &handle) == ERROR_SUCCESS) { if(RegOpenKeyExW(rootKey, utf16_t(path), 0, NWR_FLAGS | KEY_READ, &handle) == ERROR_SUCCESS) {
DWORD folders, nodes; DWORD folders, nodes;
RegQueryInfoKey(handle, nullptr, nullptr, nullptr, &folders, nullptr, nullptr, &nodes, nullptr, nullptr, nullptr, nullptr); RegQueryInfoKey(handle, nullptr, nullptr, nullptr, &folders, nullptr, nullptr, &nodes, nullptr, nullptr, nullptr, nullptr);

View File

@ -16,6 +16,10 @@
#include <windows.h> #include <windows.h>
#undef interface #undef interface
#if !defined(PATH_MAX)
#define PATH_MAX 260
#endif
namespace nall { namespace nall {
//UTF-8 to UTF-16 //UTF-8 to UTF-16
struct utf16_t { struct utf16_t {
@ -74,7 +78,7 @@ namespace nall {
wchar_t** wargv = CommandLineToArgvW(GetCommandLineW(), &argc); wchar_t** wargv = CommandLineToArgvW(GetCommandLineW(), &argc);
argv = new char*[argc]; argv = new char*[argc];
for(unsigned i = 0; i < argc; i++) { for(unsigned i = 0; i < argc; i++) {
argv[i] = new char[_MAX_PATH]; argv[i] = new char[PATH_MAX];
strcpy(argv[i], nall::utf8_t(wargv[i])); strcpy(argv[i], nall::utf8_t(wargv[i]));
} }
} }

View File

@ -23,6 +23,7 @@
#include "widget/canvas.cpp" #include "widget/canvas.cpp"
#include "widget/check-button.cpp" #include "widget/check-button.cpp"
#include "widget/combo-button.cpp" #include "widget/combo-button.cpp"
#include "widget/console.cpp"
#include "widget/hex-edit.cpp" #include "widget/hex-edit.cpp"
#include "widget/horizontal-scroller.cpp" #include "widget/horizontal-scroller.cpp"
#include "widget/horizontal-slider.cpp" #include "widget/horizontal-slider.cpp"

View File

@ -30,6 +30,7 @@ namespace phoenix {
#include "widget/canvas.hpp" #include "widget/canvas.hpp"
#include "widget/check-button.hpp" #include "widget/check-button.hpp"
#include "widget/combo-button.hpp" #include "widget/combo-button.hpp"
#include "widget/console.hpp"
#include "widget/hex-edit.hpp" #include "widget/hex-edit.hpp"
#include "widget/horizontal-scroller.hpp" #include "widget/horizontal-scroller.hpp"
#include "widget/horizontal-slider.hpp" #include "widget/horizontal-slider.hpp"

View File

@ -0,0 +1,32 @@
@implementation CocoaConsole : NSScrollView
-(id) initWith:(phoenix::Console&)consoleReference {
if(self = [super initWithFrame:NSMakeRect(0, 0, 0, 0)]) {
console = &consoleReference;
}
return self;
}
@end
namespace phoenix {
void pConsole::print(string text) {
}
void pConsole::reset() {
}
void pConsole::constructor() {
@autoreleasepool {
cocoaView = cocoaConsole = [[CocoaConsole alloc] initWith:console];
}
}
void pConsole::destructor() {
@autoreleasepool {
[cocoaView release];
}
}
}

View File

@ -0,0 +1,22 @@
@interface CocoaConsole : NSScrollView {
@public
phoenix::Console* console;
}
-(id) initWith:(phoenix::Console&)console;
@end
namespace phoenix {
struct pConsole : public pWidget {
Console& console;
CocoaConsole* cocoaConsole = nullptr;
void print(string text);
void reset();
pConsole(Console& console) : pWidget(console), console(console) {}
void constructor();
void destructor();
};
}

View File

@ -999,6 +999,30 @@ ComboButton::~ComboButton() {
delete &state; delete &state;
} }
//Console
//=======
void Console::print_(string text) {
return p.print(text);
}
void Console::reset() {
return p.reset();
}
Console::Console():
state(*new State),
base_from_member<pConsole&>(*new pConsole(*this)),
Widget(base_from_member<pConsole&>::value),
p(base_from_member<pConsole&>::value) {
p.constructor();
}
Console::~Console() {
p.destructor();
delete &state;
}
//HexEdit //HexEdit
//======= //=======

View File

@ -38,6 +38,7 @@ struct pButton;
struct pCanvas; struct pCanvas;
struct pCheckButton; struct pCheckButton;
struct pComboButton; struct pComboButton;
struct pConsole;
struct pHexEdit; struct pHexEdit;
struct pHorizontalScroller; struct pHorizontalScroller;
struct pHorizontalSlider; struct pHorizontalSlider;
@ -469,6 +470,21 @@ struct ComboButton : private nall::base_from_member<pComboButton&>, Widget {
pComboButton& p; pComboButton& p;
}; };
struct Console : private nall::base_from_member<pConsole&>, Widget {
nall::function<void (nall::string)> onActivate;
template<typename... Args> void print(Args&&... args) { print_({args...}); }
void print_(nall::string text);
void reset();
Console();
~Console();
struct State;
State& state;
pConsole& p;
};
struct HexEdit : private nall::base_from_member<pHexEdit&>, Widget { struct HexEdit : private nall::base_from_member<pHexEdit&>, Widget {
nall::function<uint8_t (unsigned)> onRead; nall::function<uint8_t (unsigned)> onRead;
nall::function<void (unsigned, uint8_t)> onWrite; nall::function<void (unsigned, uint8_t)> onWrite;

View File

@ -111,6 +111,9 @@ struct ComboButton::State {
vector<string> text; vector<string> text;
}; };
struct Console::State {
};
struct HexEdit::State { struct HexEdit::State {
unsigned columns = 16; unsigned columns = 16;
unsigned length = 0; unsigned length = 0;

View File

@ -39,7 +39,7 @@ void pApplication::initialize() {
gtk_init(&argc, &argvp); gtk_init(&argc, &argvp);
GtkSettings* gtkSettings = gtk_settings_get_default(); GtkSettings* gtkSettings = gtk_settings_get_default();
g_object_set(gtkSettings, "gtk-button-images", true, nullptr); //g_object_set(gtkSettings, "gtk-button-images", true, nullptr);
gtk_rc_parse_string(R"( gtk_rc_parse_string(R"(
style "phoenix-gtk" style "phoenix-gtk"

View File

@ -24,6 +24,7 @@
#include "widget/canvas.cpp" #include "widget/canvas.cpp"
#include "widget/check-button.cpp" #include "widget/check-button.cpp"
#include "widget/combo-button.cpp" #include "widget/combo-button.cpp"
#include "widget/console.cpp"
#include "widget/hex-edit.cpp" #include "widget/hex-edit.cpp"
#include "widget/horizontal-scroller.cpp" #include "widget/horizontal-scroller.cpp"
#include "widget/horizontal-slider.cpp" #include "widget/horizontal-slider.cpp"

View File

@ -314,6 +314,23 @@ struct pComboButton : public pWidget {
void orphan(); void orphan();
}; };
struct pConsole : public pWidget {
Console& console;
GtkWidget* subWidget;
GtkTextBuffer* textBuffer;
string command;
void print(string text);
void reset();
pConsole(Console& console) : pWidget(console), console(console) {}
void constructor();
void destructor();
void orphan();
bool keyPress(unsigned scancode, unsigned mask);
void seekCursorToEnd();
};
struct pHexEdit : public pWidget { struct pHexEdit : public pWidget {
HexEdit& hexEdit; HexEdit& hexEdit;
GtkWidget* container; GtkWidget* container;
@ -334,8 +351,10 @@ struct pHexEdit : public pWidget {
void destructor(); void destructor();
void orphan(); void orphan();
unsigned cursorPosition(); unsigned cursorPosition();
bool keyPress(unsigned scancode); bool keyPress(unsigned scancode, unsigned mask);
void scroll(unsigned position); signed rows();
signed rowsScrollable();
void scroll(signed position);
void setCursorPosition(unsigned position); void setCursorPosition(unsigned position);
void setScroll(); void setScroll();
void updateScroll(); void updateScroll();

View File

@ -1,5 +1,14 @@
namespace phoenix { namespace phoenix {
static GdkColor CreateColor(uint8_t r, uint8_t g, uint8_t b) {
GdkColor color;
color.pixel = (r << 16) | (g << 8) | (b << 0);
color.red = (r << 8) | (r << 0);
color.green = (g << 8) | (g << 0);
color.blue = (b << 8) | (b << 0);
return color;
}
static GdkPixbuf* CreatePixbuf(const nall::image& image, bool scale = false) { static GdkPixbuf* CreatePixbuf(const nall::image& image, bool scale = false) {
nall::image gdkImage = image; nall::image gdkImage = image;
gdkImage.transform(0, 32, 255u << 24, 255u << 0, 255u << 8, 255u << 16); gdkImage.transform(0, 32, 255u << 24, 255u << 0, 255u << 8, 255u << 16);

View File

@ -0,0 +1,88 @@
namespace phoenix {
static bool Console_keyPress(GtkWidget* widget, GdkEventKey* event, Console* self) {
return self->p.keyPress(event->keyval, event->state);
}
void pConsole::print(string text) {
seekCursorToEnd();
gtk_text_buffer_insert_at_cursor(textBuffer, text, -1);
GtkTextMark* mark = gtk_text_buffer_get_mark(textBuffer, "insert");
gtk_text_view_scroll_mark_onscreen(GTK_TEXT_VIEW(subWidget), mark);
}
void pConsole::reset() {
gtk_text_buffer_set_text(textBuffer, "", -1);
}
void pConsole::constructor() {
gtkWidget = gtk_scrolled_window_new(0, 0);
gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(gtkWidget), GTK_POLICY_AUTOMATIC, GTK_POLICY_ALWAYS);
gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(gtkWidget), GTK_SHADOW_ETCHED_IN);
subWidget = gtk_text_view_new();
gtk_text_view_set_editable(GTK_TEXT_VIEW(subWidget), false);
gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW(subWidget), GTK_WRAP_NONE);
gtk_container_add(GTK_CONTAINER(gtkWidget), subWidget);
textBuffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(subWidget));
GdkColor background = CreateColor(48, 24, 24);
gtk_widget_modify_base(subWidget, GTK_STATE_NORMAL, &background);
GdkColor foreground = CreateColor(255, 255, 255);
gtk_widget_modify_text(subWidget, GTK_STATE_NORMAL, &foreground);
g_signal_connect(G_OBJECT(subWidget), "key-press-event", G_CALLBACK(Console_keyPress), (gpointer)&console);
gtk_widget_show(subWidget);
}
void pConsole::destructor() {
gtk_widget_destroy(subWidget);
gtk_widget_destroy(gtkWidget);
}
void pConsole::orphan() {
destructor();
constructor();
}
bool pConsole::keyPress(unsigned scancode, unsigned mask) {
if(mask & (GDK_CONTROL_MASK | GDK_MOD1_MASK | GDK_SUPER_MASK)) return false; //allow actions such as Ctrl+C (copy)
if(scancode == GDK_KEY_Return || scancode == GDK_KEY_KP_Enter) {
print("\n");
if(console.onActivate) console.onActivate(command);
command.reset();
return true;
}
if(scancode == GDK_KEY_BackSpace) {
if(command.size()) {
command.resize(command.size() - 1);
GtkTextIter lhs, rhs;
gtk_text_buffer_get_end_iter(textBuffer, &lhs);
gtk_text_buffer_get_end_iter(textBuffer, &rhs);
gtk_text_iter_set_offset(&lhs, gtk_text_iter_get_offset(&lhs) - 1);
gtk_text_buffer_delete(textBuffer, &lhs, &rhs);
seekCursorToEnd();
}
return true;
}
if(scancode >= 0x20 && scancode <= 0x7e) {
print({(char)scancode});
command.append((char)scancode);
return true;
}
return false;
}
void pConsole::seekCursorToEnd() {
GtkTextIter iter;
gtk_text_buffer_get_end_iter(textBuffer, &iter);
gtk_text_buffer_place_cursor(textBuffer, &iter);
}
}

View File

@ -1,16 +1,30 @@
namespace phoenix { namespace phoenix {
static bool HexEdit_keyPress(GtkWidget* widget, GdkEventKey* event, HexEdit* self) { static bool HexEdit_keyPress(GtkWidget* widget, GdkEventKey* event, HexEdit* self) {
return self->p.keyPress(event->keyval); return self->p.keyPress(event->keyval, event->state);
} }
static bool HexEdit_scroll(GtkRange* range, GtkScrollType scroll, gdouble value, HexEdit* self) { static bool HexEdit_mouseScroll(GtkWidget* widget, GdkEventScroll* event, HexEdit* self) {
self->p.scroll((unsigned)value); double position = gtk_range_get_value(GTK_RANGE(self->p.scrollBar));
return false;
if(event->direction == GDK_SCROLL_UP) {
self->p.scroll(position - 1);
}
if(event->direction == GDK_SCROLL_DOWN) {
self->p.scroll(position + 1);
}
return true; //do not propagate event further
}
static bool HexEdit_scroll(GtkRange* range, GtkScrollType scroll, double value, HexEdit* self) {
self->p.scroll((signed)value);
return true; //do not propagate event further
} }
bool pHexEdit::focused() { bool pHexEdit::focused() {
return GTK_WIDGET_HAS_FOCUS(subWidget); return GTK_WIDGET_HAS_FOCUS(subWidget) || GTK_WIDGET_HAS_FOCUS(scrollBar);
} }
void pHexEdit::setColumns(unsigned columns) { void pHexEdit::setColumns(unsigned columns) {
@ -55,8 +69,7 @@ void pHexEdit::update() {
uint8_t data = hexEdit.onRead(offset++); uint8_t data = hexEdit.onRead(offset++);
hexdata.append(hex<2>(data)); hexdata.append(hex<2>(data));
hexdata.append(" "); hexdata.append(" ");
char buffer[2] = { data >= 0x20 && data <= 0x7e ? (char)data : '.', 0 }; ansidata.append(data >= 0x20 && data <= 0x7e ? (char)data : '.');
ansidata.append(buffer);
} else { } else {
hexdata.append(" "); hexdata.append(" ");
ansidata.append(" "); ansidata.append(" ");
@ -78,7 +91,7 @@ void pHexEdit::constructor() {
gtkWidget = gtk_hbox_new(false, 0); gtkWidget = gtk_hbox_new(false, 0);
container = gtk_scrolled_window_new(0, 0); container = gtk_scrolled_window_new(0, 0);
gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(container), GTK_POLICY_NEVER, GTK_POLICY_NEVER); gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(container), GTK_POLICY_AUTOMATIC, GTK_POLICY_NEVER);
gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(container), GTK_SHADOW_ETCHED_IN); gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(container), GTK_SHADOW_ETCHED_IN);
subWidget = gtk_text_view_new(); subWidget = gtk_text_view_new();
@ -86,12 +99,14 @@ void pHexEdit::constructor() {
gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW(subWidget), GTK_WRAP_NONE); gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW(subWidget), GTK_WRAP_NONE);
gtk_container_add(GTK_CONTAINER(container), subWidget); gtk_container_add(GTK_CONTAINER(container), subWidget);
g_signal_connect(G_OBJECT(subWidget), "key-press-event", G_CALLBACK(HexEdit_keyPress), (gpointer)&hexEdit); g_signal_connect(G_OBJECT(subWidget), "key-press-event", G_CALLBACK(HexEdit_keyPress), (gpointer)&hexEdit);
g_signal_connect(G_OBJECT(subWidget), "scroll-event", G_CALLBACK(HexEdit_mouseScroll), (gpointer)&hexEdit);
scrollBar = gtk_vscrollbar_new((GtkAdjustment*)0); scrollBar = gtk_vscrollbar_new((GtkAdjustment*)nullptr);
gtk_range_set_range(GTK_RANGE(scrollBar), 0, 255); gtk_range_set_range(GTK_RANGE(scrollBar), 0, 255);
gtk_range_set_increments(GTK_RANGE(scrollBar), 1, 16); gtk_range_set_increments(GTK_RANGE(scrollBar), 1, 16);
gtk_widget_set_sensitive(scrollBar, false); gtk_widget_set_sensitive(scrollBar, false);
g_signal_connect(G_OBJECT(scrollBar), "change-value", G_CALLBACK(HexEdit_scroll), (gpointer)&hexEdit); g_signal_connect(G_OBJECT(scrollBar), "change-value", G_CALLBACK(HexEdit_scroll), (gpointer)&hexEdit);
g_signal_connect(G_OBJECT(scrollBar), "scroll-event", G_CALLBACK(HexEdit_mouseScroll), (gpointer)&hexEdit);
gtk_box_pack_start(GTK_BOX(gtkWidget), container, true, true, 0); gtk_box_pack_start(GTK_BOX(gtkWidget), container, true, true, 0);
gtk_box_pack_start(GTK_BOX(gtkWidget), scrollBar, false, false, 1); gtk_box_pack_start(GTK_BOX(gtkWidget), scrollBar, false, false, 1);
@ -128,13 +143,15 @@ unsigned pHexEdit::cursorPosition() {
return gtk_text_iter_get_offset(&iter); return gtk_text_iter_get_offset(&iter);
} }
bool pHexEdit::keyPress(unsigned scancode) { bool pHexEdit::keyPress(unsigned scancode, unsigned mask) {
if(!hexEdit.onRead) return false; if(!hexEdit.onRead) return false;
unsigned position = cursorPosition(); if(mask & (GDK_CONTROL_MASK | GDK_MOD1_MASK | GDK_SUPER_MASK)) return false; //allow actions such as Ctrl+C (copy)
unsigned lineWidth = 10 + (hexEdit.state.columns * 3) + 1 + hexEdit.state.columns + 1;
unsigned cursorY = position / lineWidth; signed position = cursorPosition();
unsigned cursorX = position % lineWidth; signed lineWidth = 10 + (hexEdit.state.columns * 3) + 1 + hexEdit.state.columns + 1;
signed cursorY = position / lineWidth;
signed cursorX = position % lineWidth;
if(scancode == GDK_Home) { if(scancode == GDK_Home) {
setCursorPosition(cursorY * lineWidth + 10); setCursorPosition(cursorY * lineWidth + 10);
@ -158,6 +175,7 @@ bool pHexEdit::keyPress(unsigned scancode) {
} }
if(scancode == GDK_Down) { if(scancode == GDK_Down) {
if(cursorY >= rows() - 1) return true;
if(cursorY != hexEdit.state.rows - 1) return false; if(cursorY != hexEdit.state.rows - 1) return false;
signed newOffset = hexEdit.state.offset + hexEdit.state.columns; signed newOffset = hexEdit.state.offset + hexEdit.state.columns;
@ -234,9 +252,19 @@ bool pHexEdit::keyPress(unsigned scancode) {
return true; return true;
} }
void pHexEdit::scroll(unsigned position) { //number of actual rows
unsigned rows = hexEdit.state.length / hexEdit.state.columns; signed pHexEdit::rows() {
if(position >= rows) position = rows - 1; return (max(1u, hexEdit.state.length) + hexEdit.state.columns - 1) / hexEdit.state.columns;
}
//number of scrollable row positions
signed pHexEdit::rowsScrollable() {
return max(0u, rows() - hexEdit.state.rows);
}
void pHexEdit::scroll(signed position) {
if(position > rowsScrollable()) position = rowsScrollable();
if(position < 0) position = 0;
hexEdit.setOffset(position * hexEdit.state.columns); hexEdit.setOffset(position * hexEdit.state.columns);
} }
@ -254,10 +282,8 @@ void pHexEdit::setCursorPosition(unsigned position) {
} }
void pHexEdit::setScroll() { void pHexEdit::setScroll() {
unsigned rows = hexEdit.state.length / hexEdit.state.columns; if(rowsScrollable() > 0) {
if(rows) rows--; gtk_range_set_range(GTK_RANGE(scrollBar), 0, rowsScrollable());
if(rows) {
gtk_range_set_range(GTK_RANGE(scrollBar), 0, rows);
gtk_widget_set_sensitive(scrollBar, true); gtk_widget_set_sensitive(scrollBar, true);
} else { } else {
gtk_widget_set_sensitive(scrollBar, false); gtk_widget_set_sensitive(scrollBar, false);

View File

@ -49,11 +49,15 @@ void pTextEdit::constructor() {
gtkWidget = gtk_scrolled_window_new(0, 0); gtkWidget = gtk_scrolled_window_new(0, 0);
gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(gtkWidget), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(gtkWidget), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(gtkWidget), GTK_SHADOW_ETCHED_IN); gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(gtkWidget), GTK_SHADOW_ETCHED_IN);
subWidget = gtk_text_view_new(); subWidget = gtk_text_view_new();
gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW(subWidget), GTK_WRAP_WORD_CHAR); gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW(subWidget), GTK_WRAP_WORD_CHAR);
gtk_container_add(GTK_CONTAINER(gtkWidget), subWidget); gtk_container_add(GTK_CONTAINER(gtkWidget), subWidget);
textBuffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(subWidget)); textBuffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(subWidget));
g_signal_connect_swapped(G_OBJECT(textBuffer), "changed", G_CALLBACK(TextEdit_change), (gpointer)&textEdit); g_signal_connect_swapped(G_OBJECT(textBuffer), "changed", G_CALLBACK(TextEdit_change), (gpointer)&textEdit);
gtk_widget_show(subWidget); gtk_widget_show(subWidget);
setEditable(textEdit.state.editable); setEditable(textEdit.state.editable);

View File

@ -212,11 +212,7 @@ void pWindow::remove(Widget& widget) {
} }
void pWindow::setBackgroundColor(Color color) { void pWindow::setBackgroundColor(Color color) {
GdkColor gdkColor; GdkColor gdkColor = CreateColor(color.red, color.green, color.blue);
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); gtk_widget_modify_bg(widget, GTK_STATE_NORMAL, &gdkColor);
} }
@ -327,10 +323,15 @@ void pWindow::constructor() {
//if program was given a name, try and set the window taskbar icon from one of the pixmaps folders //if program was given a name, try and set the window taskbar icon from one of the pixmaps folders
if(applicationState.name.empty() == false) { if(applicationState.name.empty() == false) {
if(file::exists({"/usr/share/pixmaps/", applicationState.name, ".png"})) { string filename = {"/usr/share/pixmaps/", applicationState.name, ".png"};
gtk_window_set_icon_from_file(GTK_WINDOW(widget), string{"/usr/share/pixmaps/", applicationState.name, ".png"}, nullptr); if(!file::exists(filename)) filename = {"/usr/local/share/pixmaps/", applicationState.name, ".png"};
} else if(file::exists({"/usr/local/share/pixmaps/", applicationState.name, ".png"})) { if(file::exists(filename)) {
gtk_window_set_icon_from_file(GTK_WINDOW(widget), string{"/usr/local/share/pixmaps/", applicationState.name, ".png"}, nullptr); //maximum image size supported by GTK+ is 256x256; so we must scale larger images ourselves
nall::image icon(filename);
icon.scale(min(256u, icon.width), min(256u, icon.height), Interpolation::Hermite);
GdkPixbuf* pixbuf = CreatePixbuf(icon);
gtk_window_set_icon(GTK_WINDOW(widget), pixbuf);
g_object_unref(G_OBJECT(pixbuf));
} }
} }

View File

@ -12,7 +12,7 @@ string pBrowserWindow::directory(BrowserWindow::State& state) {
} }
string pBrowserWindow::open(BrowserWindow::State& state) { string pBrowserWindow::open(BrowserWindow::State& state) {
string filters = state.filters.concatenate(";;"); string filters = state.filters.merge(";;");
//convert filter list from phoenix to Qt format, example: //convert filter list from phoenix to Qt format, example:
//"Text, XML files (*.txt,*.xml)" -> "Text, XML files (*.txt *.xml)" //"Text, XML files (*.txt,*.xml)" -> "Text, XML files (*.txt *.xml)"
@ -32,7 +32,7 @@ string pBrowserWindow::open(BrowserWindow::State& state) {
} }
string pBrowserWindow::save(BrowserWindow::State& state) { string pBrowserWindow::save(BrowserWindow::State& state) {
string filters = state.filters.concatenate(";;"); string filters = state.filters.merge(";;");
//convert filter list from phoenix to Qt format, example: //convert filter list from phoenix to Qt format, example:
//"Text, XML files (*.txt,*.xml)" -> "Text, XML files (*.txt *.xml)" //"Text, XML files (*.txt,*.xml)" -> "Text, XML files (*.txt *.xml)"

View File

@ -25,6 +25,7 @@
#include "widget/canvas.cpp" #include "widget/canvas.cpp"
#include "widget/check-button.cpp" #include "widget/check-button.cpp"
#include "widget/combo-button.cpp" #include "widget/combo-button.cpp"
#include "widget/console.cpp"
#include "widget/hex-edit.cpp" #include "widget/hex-edit.cpp"
#include "widget/horizontal-scroller.cpp" #include "widget/horizontal-scroller.cpp"
#include "widget/horizontal-slider.cpp" #include "widget/horizontal-slider.cpp"

View File

@ -1,16 +1,16 @@
/**************************************************************************** /****************************************************************************
** Meta object code from reading C++ file 'platform.moc.hpp' ** Meta object code from reading C++ file 'platform.moc.hpp'
** **
** Created: Wed Jul 17 05:52:48 2013 ** Created: Tue Nov 5 18:38:24 2013
** by: The Qt Meta Object Compiler version 62 (Qt 4.6.3) ** by: The Qt Meta Object Compiler version 63 (Qt 4.8.2)
** **
** WARNING! All changes made in this file will be lost! ** WARNING! All changes made in this file will be lost!
*****************************************************************************/ *****************************************************************************/
#if !defined(Q_MOC_OUTPUT_REVISION) #if !defined(Q_MOC_OUTPUT_REVISION)
#error "The header file 'platform.moc.hpp' doesn't include <QObject>." #error "The header file 'platform.moc.hpp' doesn't include <QObject>."
#elif Q_MOC_OUTPUT_REVISION != 62 #elif Q_MOC_OUTPUT_REVISION != 63
#error "This file was generated using the moc from 4.6.3. It" #error "This file was generated using the moc from 4.8.2. It"
#error "cannot be used with the include files from this version of Qt." #error "cannot be used with the include files from this version of Qt."
#error "(The moc has changed too much.)" #error "(The moc has changed too much.)"
#endif #endif
@ -19,7 +19,7 @@ QT_BEGIN_MOC_NAMESPACE
static const uint qt_meta_data_phoenix__pTimer[] = { static const uint qt_meta_data_phoenix__pTimer[] = {
// content: // content:
4, // revision 6, // revision
0, // classname 0, // classname
0, 0, // classinfo 0, 0, // classinfo
1, 14, // methods 1, 14, // methods
@ -39,9 +39,26 @@ static const char qt_meta_stringdata_phoenix__pTimer[] = {
"phoenix::pTimer\0\0onActivate()\0" "phoenix::pTimer\0\0onActivate()\0"
}; };
void phoenix::pTimer::qt_static_metacall(QObject *_o, QMetaObject::Call _c, int _id, void **_a)
{
if (_c == QMetaObject::InvokeMetaMethod) {
Q_ASSERT(staticMetaObject.cast(_o));
pTimer *_t = static_cast<pTimer *>(_o);
switch (_id) {
case 0: _t->onActivate(); break;
default: ;
}
}
Q_UNUSED(_a);
}
const QMetaObjectExtraData phoenix::pTimer::staticMetaObjectExtraData = {
0, qt_static_metacall
};
const QMetaObject phoenix::pTimer::staticMetaObject = { const QMetaObject phoenix::pTimer::staticMetaObject = {
{ &QObject::staticMetaObject, qt_meta_stringdata_phoenix__pTimer, { &QObject::staticMetaObject, qt_meta_stringdata_phoenix__pTimer,
qt_meta_data_phoenix__pTimer, 0 } qt_meta_data_phoenix__pTimer, &staticMetaObjectExtraData }
}; };
#ifdef Q_NO_DATA_RELOCATION #ifdef Q_NO_DATA_RELOCATION
@ -69,10 +86,8 @@ int phoenix::pTimer::qt_metacall(QMetaObject::Call _c, int _id, void **_a)
if (_id < 0) if (_id < 0)
return _id; return _id;
if (_c == QMetaObject::InvokeMetaMethod) { if (_c == QMetaObject::InvokeMetaMethod) {
switch (_id) { if (_id < 1)
case 0: onActivate(); break; qt_static_metacall(this, _c, _id, _a);
default: ;
}
_id -= 1; _id -= 1;
} }
return _id; return _id;
@ -80,7 +95,7 @@ int phoenix::pTimer::qt_metacall(QMetaObject::Call _c, int _id, void **_a)
static const uint qt_meta_data_phoenix__pWindow[] = { static const uint qt_meta_data_phoenix__pWindow[] = {
// content: // content:
4, // revision 6, // revision
0, // classname 0, // classname
0, 0, // classinfo 0, 0, // classinfo
0, 0, // methods 0, 0, // methods
@ -97,9 +112,21 @@ static const char qt_meta_stringdata_phoenix__pWindow[] = {
"phoenix::pWindow\0" "phoenix::pWindow\0"
}; };
void phoenix::pWindow::qt_static_metacall(QObject *_o, QMetaObject::Call _c, int _id, void **_a)
{
Q_UNUSED(_o);
Q_UNUSED(_id);
Q_UNUSED(_c);
Q_UNUSED(_a);
}
const QMetaObjectExtraData phoenix::pWindow::staticMetaObjectExtraData = {
0, qt_static_metacall
};
const QMetaObject phoenix::pWindow::staticMetaObject = { const QMetaObject phoenix::pWindow::staticMetaObject = {
{ &QObject::staticMetaObject, qt_meta_stringdata_phoenix__pWindow, { &QObject::staticMetaObject, qt_meta_stringdata_phoenix__pWindow,
qt_meta_data_phoenix__pWindow, 0 } qt_meta_data_phoenix__pWindow, &staticMetaObjectExtraData }
}; };
#ifdef Q_NO_DATA_RELOCATION #ifdef Q_NO_DATA_RELOCATION
@ -131,7 +158,7 @@ int phoenix::pWindow::qt_metacall(QMetaObject::Call _c, int _id, void **_a)
static const uint qt_meta_data_phoenix__pItem[] = { static const uint qt_meta_data_phoenix__pItem[] = {
// content: // content:
4, // revision 6, // revision
0, // classname 0, // classname
0, 0, // classinfo 0, 0, // classinfo
1, 14, // methods 1, 14, // methods
@ -151,9 +178,26 @@ static const char qt_meta_stringdata_phoenix__pItem[] = {
"phoenix::pItem\0\0onActivate()\0" "phoenix::pItem\0\0onActivate()\0"
}; };
void phoenix::pItem::qt_static_metacall(QObject *_o, QMetaObject::Call _c, int _id, void **_a)
{
if (_c == QMetaObject::InvokeMetaMethod) {
Q_ASSERT(staticMetaObject.cast(_o));
pItem *_t = static_cast<pItem *>(_o);
switch (_id) {
case 0: _t->onActivate(); break;
default: ;
}
}
Q_UNUSED(_a);
}
const QMetaObjectExtraData phoenix::pItem::staticMetaObjectExtraData = {
0, qt_static_metacall
};
const QMetaObject phoenix::pItem::staticMetaObject = { const QMetaObject phoenix::pItem::staticMetaObject = {
{ &QObject::staticMetaObject, qt_meta_stringdata_phoenix__pItem, { &QObject::staticMetaObject, qt_meta_stringdata_phoenix__pItem,
qt_meta_data_phoenix__pItem, 0 } qt_meta_data_phoenix__pItem, &staticMetaObjectExtraData }
}; };
#ifdef Q_NO_DATA_RELOCATION #ifdef Q_NO_DATA_RELOCATION
@ -181,10 +225,8 @@ int phoenix::pItem::qt_metacall(QMetaObject::Call _c, int _id, void **_a)
if (_id < 0) if (_id < 0)
return _id; return _id;
if (_c == QMetaObject::InvokeMetaMethod) { if (_c == QMetaObject::InvokeMetaMethod) {
switch (_id) { if (_id < 1)
case 0: onActivate(); break; qt_static_metacall(this, _c, _id, _a);
default: ;
}
_id -= 1; _id -= 1;
} }
return _id; return _id;
@ -192,7 +234,7 @@ int phoenix::pItem::qt_metacall(QMetaObject::Call _c, int _id, void **_a)
static const uint qt_meta_data_phoenix__pCheckItem[] = { static const uint qt_meta_data_phoenix__pCheckItem[] = {
// content: // content:
4, // revision 6, // revision
0, // classname 0, // classname
0, 0, // classinfo 0, 0, // classinfo
1, 14, // methods 1, 14, // methods
@ -212,9 +254,26 @@ static const char qt_meta_stringdata_phoenix__pCheckItem[] = {
"phoenix::pCheckItem\0\0onToggle()\0" "phoenix::pCheckItem\0\0onToggle()\0"
}; };
void phoenix::pCheckItem::qt_static_metacall(QObject *_o, QMetaObject::Call _c, int _id, void **_a)
{
if (_c == QMetaObject::InvokeMetaMethod) {
Q_ASSERT(staticMetaObject.cast(_o));
pCheckItem *_t = static_cast<pCheckItem *>(_o);
switch (_id) {
case 0: _t->onToggle(); break;
default: ;
}
}
Q_UNUSED(_a);
}
const QMetaObjectExtraData phoenix::pCheckItem::staticMetaObjectExtraData = {
0, qt_static_metacall
};
const QMetaObject phoenix::pCheckItem::staticMetaObject = { const QMetaObject phoenix::pCheckItem::staticMetaObject = {
{ &QObject::staticMetaObject, qt_meta_stringdata_phoenix__pCheckItem, { &QObject::staticMetaObject, qt_meta_stringdata_phoenix__pCheckItem,
qt_meta_data_phoenix__pCheckItem, 0 } qt_meta_data_phoenix__pCheckItem, &staticMetaObjectExtraData }
}; };
#ifdef Q_NO_DATA_RELOCATION #ifdef Q_NO_DATA_RELOCATION
@ -242,10 +301,8 @@ int phoenix::pCheckItem::qt_metacall(QMetaObject::Call _c, int _id, void **_a)
if (_id < 0) if (_id < 0)
return _id; return _id;
if (_c == QMetaObject::InvokeMetaMethod) { if (_c == QMetaObject::InvokeMetaMethod) {
switch (_id) { if (_id < 1)
case 0: onToggle(); break; qt_static_metacall(this, _c, _id, _a);
default: ;
}
_id -= 1; _id -= 1;
} }
return _id; return _id;
@ -253,7 +310,7 @@ int phoenix::pCheckItem::qt_metacall(QMetaObject::Call _c, int _id, void **_a)
static const uint qt_meta_data_phoenix__pRadioItem[] = { static const uint qt_meta_data_phoenix__pRadioItem[] = {
// content: // content:
4, // revision 6, // revision
0, // classname 0, // classname
0, 0, // classinfo 0, 0, // classinfo
1, 14, // methods 1, 14, // methods
@ -273,9 +330,26 @@ static const char qt_meta_stringdata_phoenix__pRadioItem[] = {
"phoenix::pRadioItem\0\0onActivate()\0" "phoenix::pRadioItem\0\0onActivate()\0"
}; };
void phoenix::pRadioItem::qt_static_metacall(QObject *_o, QMetaObject::Call _c, int _id, void **_a)
{
if (_c == QMetaObject::InvokeMetaMethod) {
Q_ASSERT(staticMetaObject.cast(_o));
pRadioItem *_t = static_cast<pRadioItem *>(_o);
switch (_id) {
case 0: _t->onActivate(); break;
default: ;
}
}
Q_UNUSED(_a);
}
const QMetaObjectExtraData phoenix::pRadioItem::staticMetaObjectExtraData = {
0, qt_static_metacall
};
const QMetaObject phoenix::pRadioItem::staticMetaObject = { const QMetaObject phoenix::pRadioItem::staticMetaObject = {
{ &QObject::staticMetaObject, qt_meta_stringdata_phoenix__pRadioItem, { &QObject::staticMetaObject, qt_meta_stringdata_phoenix__pRadioItem,
qt_meta_data_phoenix__pRadioItem, 0 } qt_meta_data_phoenix__pRadioItem, &staticMetaObjectExtraData }
}; };
#ifdef Q_NO_DATA_RELOCATION #ifdef Q_NO_DATA_RELOCATION
@ -303,10 +377,8 @@ int phoenix::pRadioItem::qt_metacall(QMetaObject::Call _c, int _id, void **_a)
if (_id < 0) if (_id < 0)
return _id; return _id;
if (_c == QMetaObject::InvokeMetaMethod) { if (_c == QMetaObject::InvokeMetaMethod) {
switch (_id) { if (_id < 1)
case 0: onActivate(); break; qt_static_metacall(this, _c, _id, _a);
default: ;
}
_id -= 1; _id -= 1;
} }
return _id; return _id;
@ -314,7 +386,7 @@ int phoenix::pRadioItem::qt_metacall(QMetaObject::Call _c, int _id, void **_a)
static const uint qt_meta_data_phoenix__pButton[] = { static const uint qt_meta_data_phoenix__pButton[] = {
// content: // content:
4, // revision 6, // revision
0, // classname 0, // classname
0, 0, // classinfo 0, 0, // classinfo
1, 14, // methods 1, 14, // methods
@ -334,9 +406,26 @@ static const char qt_meta_stringdata_phoenix__pButton[] = {
"phoenix::pButton\0\0onActivate()\0" "phoenix::pButton\0\0onActivate()\0"
}; };
void phoenix::pButton::qt_static_metacall(QObject *_o, QMetaObject::Call _c, int _id, void **_a)
{
if (_c == QMetaObject::InvokeMetaMethod) {
Q_ASSERT(staticMetaObject.cast(_o));
pButton *_t = static_cast<pButton *>(_o);
switch (_id) {
case 0: _t->onActivate(); break;
default: ;
}
}
Q_UNUSED(_a);
}
const QMetaObjectExtraData phoenix::pButton::staticMetaObjectExtraData = {
0, qt_static_metacall
};
const QMetaObject phoenix::pButton::staticMetaObject = { const QMetaObject phoenix::pButton::staticMetaObject = {
{ &QObject::staticMetaObject, qt_meta_stringdata_phoenix__pButton, { &QObject::staticMetaObject, qt_meta_stringdata_phoenix__pButton,
qt_meta_data_phoenix__pButton, 0 } qt_meta_data_phoenix__pButton, &staticMetaObjectExtraData }
}; };
#ifdef Q_NO_DATA_RELOCATION #ifdef Q_NO_DATA_RELOCATION
@ -364,10 +453,8 @@ int phoenix::pButton::qt_metacall(QMetaObject::Call _c, int _id, void **_a)
if (_id < 0) if (_id < 0)
return _id; return _id;
if (_c == QMetaObject::InvokeMetaMethod) { if (_c == QMetaObject::InvokeMetaMethod) {
switch (_id) { if (_id < 1)
case 0: onActivate(); break; qt_static_metacall(this, _c, _id, _a);
default: ;
}
_id -= 1; _id -= 1;
} }
return _id; return _id;
@ -375,7 +462,7 @@ int phoenix::pButton::qt_metacall(QMetaObject::Call _c, int _id, void **_a)
static const uint qt_meta_data_phoenix__pCanvas[] = { static const uint qt_meta_data_phoenix__pCanvas[] = {
// content: // content:
4, // revision 6, // revision
0, // classname 0, // classname
0, 0, // classinfo 0, 0, // classinfo
0, 0, // methods 0, 0, // methods
@ -392,9 +479,21 @@ static const char qt_meta_stringdata_phoenix__pCanvas[] = {
"phoenix::pCanvas\0" "phoenix::pCanvas\0"
}; };
void phoenix::pCanvas::qt_static_metacall(QObject *_o, QMetaObject::Call _c, int _id, void **_a)
{
Q_UNUSED(_o);
Q_UNUSED(_id);
Q_UNUSED(_c);
Q_UNUSED(_a);
}
const QMetaObjectExtraData phoenix::pCanvas::staticMetaObjectExtraData = {
0, qt_static_metacall
};
const QMetaObject phoenix::pCanvas::staticMetaObject = { const QMetaObject phoenix::pCanvas::staticMetaObject = {
{ &QObject::staticMetaObject, qt_meta_stringdata_phoenix__pCanvas, { &QObject::staticMetaObject, qt_meta_stringdata_phoenix__pCanvas,
qt_meta_data_phoenix__pCanvas, 0 } qt_meta_data_phoenix__pCanvas, &staticMetaObjectExtraData }
}; };
#ifdef Q_NO_DATA_RELOCATION #ifdef Q_NO_DATA_RELOCATION
@ -426,7 +525,7 @@ int phoenix::pCanvas::qt_metacall(QMetaObject::Call _c, int _id, void **_a)
static const uint qt_meta_data_phoenix__pCheckButton[] = { static const uint qt_meta_data_phoenix__pCheckButton[] = {
// content: // content:
4, // revision 6, // revision
0, // classname 0, // classname
0, 0, // classinfo 0, 0, // classinfo
1, 14, // methods 1, 14, // methods
@ -446,9 +545,26 @@ static const char qt_meta_stringdata_phoenix__pCheckButton[] = {
"phoenix::pCheckButton\0\0onToggle()\0" "phoenix::pCheckButton\0\0onToggle()\0"
}; };
void phoenix::pCheckButton::qt_static_metacall(QObject *_o, QMetaObject::Call _c, int _id, void **_a)
{
if (_c == QMetaObject::InvokeMetaMethod) {
Q_ASSERT(staticMetaObject.cast(_o));
pCheckButton *_t = static_cast<pCheckButton *>(_o);
switch (_id) {
case 0: _t->onToggle(); break;
default: ;
}
}
Q_UNUSED(_a);
}
const QMetaObjectExtraData phoenix::pCheckButton::staticMetaObjectExtraData = {
0, qt_static_metacall
};
const QMetaObject phoenix::pCheckButton::staticMetaObject = { const QMetaObject phoenix::pCheckButton::staticMetaObject = {
{ &QObject::staticMetaObject, qt_meta_stringdata_phoenix__pCheckButton, { &QObject::staticMetaObject, qt_meta_stringdata_phoenix__pCheckButton,
qt_meta_data_phoenix__pCheckButton, 0 } qt_meta_data_phoenix__pCheckButton, &staticMetaObjectExtraData }
}; };
#ifdef Q_NO_DATA_RELOCATION #ifdef Q_NO_DATA_RELOCATION
@ -476,10 +592,8 @@ int phoenix::pCheckButton::qt_metacall(QMetaObject::Call _c, int _id, void **_a)
if (_id < 0) if (_id < 0)
return _id; return _id;
if (_c == QMetaObject::InvokeMetaMethod) { if (_c == QMetaObject::InvokeMetaMethod) {
switch (_id) { if (_id < 1)
case 0: onToggle(); break; qt_static_metacall(this, _c, _id, _a);
default: ;
}
_id -= 1; _id -= 1;
} }
return _id; return _id;
@ -487,7 +601,7 @@ int phoenix::pCheckButton::qt_metacall(QMetaObject::Call _c, int _id, void **_a)
static const uint qt_meta_data_phoenix__pComboButton[] = { static const uint qt_meta_data_phoenix__pComboButton[] = {
// content: // content:
4, // revision 6, // revision
0, // classname 0, // classname
0, 0, // classinfo 0, 0, // classinfo
1, 14, // methods 1, 14, // methods
@ -507,9 +621,26 @@ static const char qt_meta_stringdata_phoenix__pComboButton[] = {
"phoenix::pComboButton\0\0onChange()\0" "phoenix::pComboButton\0\0onChange()\0"
}; };
void phoenix::pComboButton::qt_static_metacall(QObject *_o, QMetaObject::Call _c, int _id, void **_a)
{
if (_c == QMetaObject::InvokeMetaMethod) {
Q_ASSERT(staticMetaObject.cast(_o));
pComboButton *_t = static_cast<pComboButton *>(_o);
switch (_id) {
case 0: _t->onChange(); break;
default: ;
}
}
Q_UNUSED(_a);
}
const QMetaObjectExtraData phoenix::pComboButton::staticMetaObjectExtraData = {
0, qt_static_metacall
};
const QMetaObject phoenix::pComboButton::staticMetaObject = { const QMetaObject phoenix::pComboButton::staticMetaObject = {
{ &QObject::staticMetaObject, qt_meta_stringdata_phoenix__pComboButton, { &QObject::staticMetaObject, qt_meta_stringdata_phoenix__pComboButton,
qt_meta_data_phoenix__pComboButton, 0 } qt_meta_data_phoenix__pComboButton, &staticMetaObjectExtraData }
}; };
#ifdef Q_NO_DATA_RELOCATION #ifdef Q_NO_DATA_RELOCATION
@ -537,18 +668,79 @@ int phoenix::pComboButton::qt_metacall(QMetaObject::Call _c, int _id, void **_a)
if (_id < 0) if (_id < 0)
return _id; return _id;
if (_c == QMetaObject::InvokeMetaMethod) { if (_c == QMetaObject::InvokeMetaMethod) {
switch (_id) { if (_id < 1)
case 0: onChange(); break; qt_static_metacall(this, _c, _id, _a);
default: ;
}
_id -= 1; _id -= 1;
} }
return _id; return _id;
} }
static const uint qt_meta_data_phoenix__pConsole[] = {
// content:
6, // revision
0, // classname
0, 0, // classinfo
0, 0, // methods
0, 0, // properties
0, 0, // enums/sets
0, 0, // constructors
0, // flags
0, // signalCount
0 // eod
};
static const char qt_meta_stringdata_phoenix__pConsole[] = {
"phoenix::pConsole\0"
};
void phoenix::pConsole::qt_static_metacall(QObject *_o, QMetaObject::Call _c, int _id, void **_a)
{
Q_UNUSED(_o);
Q_UNUSED(_id);
Q_UNUSED(_c);
Q_UNUSED(_a);
}
const QMetaObjectExtraData phoenix::pConsole::staticMetaObjectExtraData = {
0, qt_static_metacall
};
const QMetaObject phoenix::pConsole::staticMetaObject = {
{ &QObject::staticMetaObject, qt_meta_stringdata_phoenix__pConsole,
qt_meta_data_phoenix__pConsole, &staticMetaObjectExtraData }
};
#ifdef Q_NO_DATA_RELOCATION
const QMetaObject &phoenix::pConsole::getStaticMetaObject() { return staticMetaObject; }
#endif //Q_NO_DATA_RELOCATION
const QMetaObject *phoenix::pConsole::metaObject() const
{
return QObject::d_ptr->metaObject ? QObject::d_ptr->metaObject : &staticMetaObject;
}
void *phoenix::pConsole::qt_metacast(const char *_clname)
{
if (!_clname) return 0;
if (!strcmp(_clname, qt_meta_stringdata_phoenix__pConsole))
return static_cast<void*>(const_cast< pConsole*>(this));
if (!strcmp(_clname, "pWidget"))
return static_cast< pWidget*>(const_cast< pConsole*>(this));
return QObject::qt_metacast(_clname);
}
int phoenix::pConsole::qt_metacall(QMetaObject::Call _c, int _id, void **_a)
{
_id = QObject::qt_metacall(_c, _id, _a);
if (_id < 0)
return _id;
return _id;
}
static const uint qt_meta_data_phoenix__pHexEdit[] = { static const uint qt_meta_data_phoenix__pHexEdit[] = {
// content: // content:
4, // revision 6, // revision
0, // classname 0, // classname
0, 0, // classinfo 0, 0, // classinfo
1, 14, // methods 1, 14, // methods
@ -568,9 +760,26 @@ static const char qt_meta_stringdata_phoenix__pHexEdit[] = {
"phoenix::pHexEdit\0\0onScroll()\0" "phoenix::pHexEdit\0\0onScroll()\0"
}; };
void phoenix::pHexEdit::qt_static_metacall(QObject *_o, QMetaObject::Call _c, int _id, void **_a)
{
if (_c == QMetaObject::InvokeMetaMethod) {
Q_ASSERT(staticMetaObject.cast(_o));
pHexEdit *_t = static_cast<pHexEdit *>(_o);
switch (_id) {
case 0: _t->onScroll(); break;
default: ;
}
}
Q_UNUSED(_a);
}
const QMetaObjectExtraData phoenix::pHexEdit::staticMetaObjectExtraData = {
0, qt_static_metacall
};
const QMetaObject phoenix::pHexEdit::staticMetaObject = { const QMetaObject phoenix::pHexEdit::staticMetaObject = {
{ &QObject::staticMetaObject, qt_meta_stringdata_phoenix__pHexEdit, { &QObject::staticMetaObject, qt_meta_stringdata_phoenix__pHexEdit,
qt_meta_data_phoenix__pHexEdit, 0 } qt_meta_data_phoenix__pHexEdit, &staticMetaObjectExtraData }
}; };
#ifdef Q_NO_DATA_RELOCATION #ifdef Q_NO_DATA_RELOCATION
@ -598,10 +807,8 @@ int phoenix::pHexEdit::qt_metacall(QMetaObject::Call _c, int _id, void **_a)
if (_id < 0) if (_id < 0)
return _id; return _id;
if (_c == QMetaObject::InvokeMetaMethod) { if (_c == QMetaObject::InvokeMetaMethod) {
switch (_id) { if (_id < 1)
case 0: onScroll(); break; qt_static_metacall(this, _c, _id, _a);
default: ;
}
_id -= 1; _id -= 1;
} }
return _id; return _id;
@ -609,7 +816,7 @@ int phoenix::pHexEdit::qt_metacall(QMetaObject::Call _c, int _id, void **_a)
static const uint qt_meta_data_phoenix__pHorizontalScroller[] = { static const uint qt_meta_data_phoenix__pHorizontalScroller[] = {
// content: // content:
4, // revision 6, // revision
0, // classname 0, // classname
0, 0, // classinfo 0, 0, // classinfo
1, 14, // methods 1, 14, // methods
@ -629,9 +836,26 @@ static const char qt_meta_stringdata_phoenix__pHorizontalScroller[] = {
"phoenix::pHorizontalScroller\0\0onChange()\0" "phoenix::pHorizontalScroller\0\0onChange()\0"
}; };
void phoenix::pHorizontalScroller::qt_static_metacall(QObject *_o, QMetaObject::Call _c, int _id, void **_a)
{
if (_c == QMetaObject::InvokeMetaMethod) {
Q_ASSERT(staticMetaObject.cast(_o));
pHorizontalScroller *_t = static_cast<pHorizontalScroller *>(_o);
switch (_id) {
case 0: _t->onChange(); break;
default: ;
}
}
Q_UNUSED(_a);
}
const QMetaObjectExtraData phoenix::pHorizontalScroller::staticMetaObjectExtraData = {
0, qt_static_metacall
};
const QMetaObject phoenix::pHorizontalScroller::staticMetaObject = { const QMetaObject phoenix::pHorizontalScroller::staticMetaObject = {
{ &QObject::staticMetaObject, qt_meta_stringdata_phoenix__pHorizontalScroller, { &QObject::staticMetaObject, qt_meta_stringdata_phoenix__pHorizontalScroller,
qt_meta_data_phoenix__pHorizontalScroller, 0 } qt_meta_data_phoenix__pHorizontalScroller, &staticMetaObjectExtraData }
}; };
#ifdef Q_NO_DATA_RELOCATION #ifdef Q_NO_DATA_RELOCATION
@ -659,10 +883,8 @@ int phoenix::pHorizontalScroller::qt_metacall(QMetaObject::Call _c, int _id, voi
if (_id < 0) if (_id < 0)
return _id; return _id;
if (_c == QMetaObject::InvokeMetaMethod) { if (_c == QMetaObject::InvokeMetaMethod) {
switch (_id) { if (_id < 1)
case 0: onChange(); break; qt_static_metacall(this, _c, _id, _a);
default: ;
}
_id -= 1; _id -= 1;
} }
return _id; return _id;
@ -670,7 +892,7 @@ int phoenix::pHorizontalScroller::qt_metacall(QMetaObject::Call _c, int _id, voi
static const uint qt_meta_data_phoenix__pHorizontalSlider[] = { static const uint qt_meta_data_phoenix__pHorizontalSlider[] = {
// content: // content:
4, // revision 6, // revision
0, // classname 0, // classname
0, 0, // classinfo 0, 0, // classinfo
1, 14, // methods 1, 14, // methods
@ -690,9 +912,26 @@ static const char qt_meta_stringdata_phoenix__pHorizontalSlider[] = {
"phoenix::pHorizontalSlider\0\0onChange()\0" "phoenix::pHorizontalSlider\0\0onChange()\0"
}; };
void phoenix::pHorizontalSlider::qt_static_metacall(QObject *_o, QMetaObject::Call _c, int _id, void **_a)
{
if (_c == QMetaObject::InvokeMetaMethod) {
Q_ASSERT(staticMetaObject.cast(_o));
pHorizontalSlider *_t = static_cast<pHorizontalSlider *>(_o);
switch (_id) {
case 0: _t->onChange(); break;
default: ;
}
}
Q_UNUSED(_a);
}
const QMetaObjectExtraData phoenix::pHorizontalSlider::staticMetaObjectExtraData = {
0, qt_static_metacall
};
const QMetaObject phoenix::pHorizontalSlider::staticMetaObject = { const QMetaObject phoenix::pHorizontalSlider::staticMetaObject = {
{ &QObject::staticMetaObject, qt_meta_stringdata_phoenix__pHorizontalSlider, { &QObject::staticMetaObject, qt_meta_stringdata_phoenix__pHorizontalSlider,
qt_meta_data_phoenix__pHorizontalSlider, 0 } qt_meta_data_phoenix__pHorizontalSlider, &staticMetaObjectExtraData }
}; };
#ifdef Q_NO_DATA_RELOCATION #ifdef Q_NO_DATA_RELOCATION
@ -720,10 +959,8 @@ int phoenix::pHorizontalSlider::qt_metacall(QMetaObject::Call _c, int _id, void
if (_id < 0) if (_id < 0)
return _id; return _id;
if (_c == QMetaObject::InvokeMetaMethod) { if (_c == QMetaObject::InvokeMetaMethod) {
switch (_id) { if (_id < 1)
case 0: onChange(); break; qt_static_metacall(this, _c, _id, _a);
default: ;
}
_id -= 1; _id -= 1;
} }
return _id; return _id;
@ -731,7 +968,7 @@ int phoenix::pHorizontalSlider::qt_metacall(QMetaObject::Call _c, int _id, void
static const uint qt_meta_data_phoenix__pLineEdit[] = { static const uint qt_meta_data_phoenix__pLineEdit[] = {
// content: // content:
4, // revision 6, // revision
0, // classname 0, // classname
0, 0, // classinfo 0, 0, // classinfo
2, 14, // methods 2, 14, // methods
@ -753,9 +990,27 @@ static const char qt_meta_stringdata_phoenix__pLineEdit[] = {
"onChange()\0" "onChange()\0"
}; };
void phoenix::pLineEdit::qt_static_metacall(QObject *_o, QMetaObject::Call _c, int _id, void **_a)
{
if (_c == QMetaObject::InvokeMetaMethod) {
Q_ASSERT(staticMetaObject.cast(_o));
pLineEdit *_t = static_cast<pLineEdit *>(_o);
switch (_id) {
case 0: _t->onActivate(); break;
case 1: _t->onChange(); break;
default: ;
}
}
Q_UNUSED(_a);
}
const QMetaObjectExtraData phoenix::pLineEdit::staticMetaObjectExtraData = {
0, qt_static_metacall
};
const QMetaObject phoenix::pLineEdit::staticMetaObject = { const QMetaObject phoenix::pLineEdit::staticMetaObject = {
{ &QObject::staticMetaObject, qt_meta_stringdata_phoenix__pLineEdit, { &QObject::staticMetaObject, qt_meta_stringdata_phoenix__pLineEdit,
qt_meta_data_phoenix__pLineEdit, 0 } qt_meta_data_phoenix__pLineEdit, &staticMetaObjectExtraData }
}; };
#ifdef Q_NO_DATA_RELOCATION #ifdef Q_NO_DATA_RELOCATION
@ -783,11 +1038,8 @@ int phoenix::pLineEdit::qt_metacall(QMetaObject::Call _c, int _id, void **_a)
if (_id < 0) if (_id < 0)
return _id; return _id;
if (_c == QMetaObject::InvokeMetaMethod) { if (_c == QMetaObject::InvokeMetaMethod) {
switch (_id) { if (_id < 2)
case 0: onActivate(); break; qt_static_metacall(this, _c, _id, _a);
case 1: onChange(); break;
default: ;
}
_id -= 2; _id -= 2;
} }
return _id; return _id;
@ -795,7 +1047,7 @@ int phoenix::pLineEdit::qt_metacall(QMetaObject::Call _c, int _id, void **_a)
static const uint qt_meta_data_phoenix__pListView[] = { static const uint qt_meta_data_phoenix__pListView[] = {
// content: // content:
4, // revision 6, // revision
0, // classname 0, // classname
0, 0, // classinfo 0, 0, // classinfo
3, 14, // methods 3, 14, // methods
@ -819,9 +1071,27 @@ static const char qt_meta_stringdata_phoenix__pListView[] = {
"onToggle(QTreeWidgetItem*)\0" "onToggle(QTreeWidgetItem*)\0"
}; };
void phoenix::pListView::qt_static_metacall(QObject *_o, QMetaObject::Call _c, int _id, void **_a)
{
if (_c == QMetaObject::InvokeMetaMethod) {
Q_ASSERT(staticMetaObject.cast(_o));
pListView *_t = static_cast<pListView *>(_o);
switch (_id) {
case 0: _t->onActivate(); break;
case 1: _t->onChange((*reinterpret_cast< QTreeWidgetItem*(*)>(_a[1]))); break;
case 2: _t->onToggle((*reinterpret_cast< QTreeWidgetItem*(*)>(_a[1]))); break;
default: ;
}
}
}
const QMetaObjectExtraData phoenix::pListView::staticMetaObjectExtraData = {
0, qt_static_metacall
};
const QMetaObject phoenix::pListView::staticMetaObject = { const QMetaObject phoenix::pListView::staticMetaObject = {
{ &QObject::staticMetaObject, qt_meta_stringdata_phoenix__pListView, { &QObject::staticMetaObject, qt_meta_stringdata_phoenix__pListView,
qt_meta_data_phoenix__pListView, 0 } qt_meta_data_phoenix__pListView, &staticMetaObjectExtraData }
}; };
#ifdef Q_NO_DATA_RELOCATION #ifdef Q_NO_DATA_RELOCATION
@ -849,12 +1119,8 @@ int phoenix::pListView::qt_metacall(QMetaObject::Call _c, int _id, void **_a)
if (_id < 0) if (_id < 0)
return _id; return _id;
if (_c == QMetaObject::InvokeMetaMethod) { if (_c == QMetaObject::InvokeMetaMethod) {
switch (_id) { if (_id < 3)
case 0: onActivate(); break; qt_static_metacall(this, _c, _id, _a);
case 1: onChange((*reinterpret_cast< QTreeWidgetItem*(*)>(_a[1]))); break;
case 2: onToggle((*reinterpret_cast< QTreeWidgetItem*(*)>(_a[1]))); break;
default: ;
}
_id -= 3; _id -= 3;
} }
return _id; return _id;
@ -862,7 +1128,7 @@ int phoenix::pListView::qt_metacall(QMetaObject::Call _c, int _id, void **_a)
static const uint qt_meta_data_phoenix__pRadioButton[] = { static const uint qt_meta_data_phoenix__pRadioButton[] = {
// content: // content:
4, // revision 6, // revision
0, // classname 0, // classname
0, 0, // classinfo 0, 0, // classinfo
1, 14, // methods 1, 14, // methods
@ -882,9 +1148,26 @@ static const char qt_meta_stringdata_phoenix__pRadioButton[] = {
"phoenix::pRadioButton\0\0onActivate()\0" "phoenix::pRadioButton\0\0onActivate()\0"
}; };
void phoenix::pRadioButton::qt_static_metacall(QObject *_o, QMetaObject::Call _c, int _id, void **_a)
{
if (_c == QMetaObject::InvokeMetaMethod) {
Q_ASSERT(staticMetaObject.cast(_o));
pRadioButton *_t = static_cast<pRadioButton *>(_o);
switch (_id) {
case 0: _t->onActivate(); break;
default: ;
}
}
Q_UNUSED(_a);
}
const QMetaObjectExtraData phoenix::pRadioButton::staticMetaObjectExtraData = {
0, qt_static_metacall
};
const QMetaObject phoenix::pRadioButton::staticMetaObject = { const QMetaObject phoenix::pRadioButton::staticMetaObject = {
{ &QObject::staticMetaObject, qt_meta_stringdata_phoenix__pRadioButton, { &QObject::staticMetaObject, qt_meta_stringdata_phoenix__pRadioButton,
qt_meta_data_phoenix__pRadioButton, 0 } qt_meta_data_phoenix__pRadioButton, &staticMetaObjectExtraData }
}; };
#ifdef Q_NO_DATA_RELOCATION #ifdef Q_NO_DATA_RELOCATION
@ -912,10 +1195,8 @@ int phoenix::pRadioButton::qt_metacall(QMetaObject::Call _c, int _id, void **_a)
if (_id < 0) if (_id < 0)
return _id; return _id;
if (_c == QMetaObject::InvokeMetaMethod) { if (_c == QMetaObject::InvokeMetaMethod) {
switch (_id) { if (_id < 1)
case 0: onActivate(); break; qt_static_metacall(this, _c, _id, _a);
default: ;
}
_id -= 1; _id -= 1;
} }
return _id; return _id;
@ -923,7 +1204,7 @@ int phoenix::pRadioButton::qt_metacall(QMetaObject::Call _c, int _id, void **_a)
static const uint qt_meta_data_phoenix__pTextEdit[] = { static const uint qt_meta_data_phoenix__pTextEdit[] = {
// content: // content:
4, // revision 6, // revision
0, // classname 0, // classname
0, 0, // classinfo 0, 0, // classinfo
1, 14, // methods 1, 14, // methods
@ -943,9 +1224,26 @@ static const char qt_meta_stringdata_phoenix__pTextEdit[] = {
"phoenix::pTextEdit\0\0onChange()\0" "phoenix::pTextEdit\0\0onChange()\0"
}; };
void phoenix::pTextEdit::qt_static_metacall(QObject *_o, QMetaObject::Call _c, int _id, void **_a)
{
if (_c == QMetaObject::InvokeMetaMethod) {
Q_ASSERT(staticMetaObject.cast(_o));
pTextEdit *_t = static_cast<pTextEdit *>(_o);
switch (_id) {
case 0: _t->onChange(); break;
default: ;
}
}
Q_UNUSED(_a);
}
const QMetaObjectExtraData phoenix::pTextEdit::staticMetaObjectExtraData = {
0, qt_static_metacall
};
const QMetaObject phoenix::pTextEdit::staticMetaObject = { const QMetaObject phoenix::pTextEdit::staticMetaObject = {
{ &QObject::staticMetaObject, qt_meta_stringdata_phoenix__pTextEdit, { &QObject::staticMetaObject, qt_meta_stringdata_phoenix__pTextEdit,
qt_meta_data_phoenix__pTextEdit, 0 } qt_meta_data_phoenix__pTextEdit, &staticMetaObjectExtraData }
}; };
#ifdef Q_NO_DATA_RELOCATION #ifdef Q_NO_DATA_RELOCATION
@ -973,10 +1271,8 @@ int phoenix::pTextEdit::qt_metacall(QMetaObject::Call _c, int _id, void **_a)
if (_id < 0) if (_id < 0)
return _id; return _id;
if (_c == QMetaObject::InvokeMetaMethod) { if (_c == QMetaObject::InvokeMetaMethod) {
switch (_id) { if (_id < 1)
case 0: onChange(); break; qt_static_metacall(this, _c, _id, _a);
default: ;
}
_id -= 1; _id -= 1;
} }
return _id; return _id;
@ -984,7 +1280,7 @@ int phoenix::pTextEdit::qt_metacall(QMetaObject::Call _c, int _id, void **_a)
static const uint qt_meta_data_phoenix__pVerticalScroller[] = { static const uint qt_meta_data_phoenix__pVerticalScroller[] = {
// content: // content:
4, // revision 6, // revision
0, // classname 0, // classname
0, 0, // classinfo 0, 0, // classinfo
1, 14, // methods 1, 14, // methods
@ -1004,9 +1300,26 @@ static const char qt_meta_stringdata_phoenix__pVerticalScroller[] = {
"phoenix::pVerticalScroller\0\0onChange()\0" "phoenix::pVerticalScroller\0\0onChange()\0"
}; };
void phoenix::pVerticalScroller::qt_static_metacall(QObject *_o, QMetaObject::Call _c, int _id, void **_a)
{
if (_c == QMetaObject::InvokeMetaMethod) {
Q_ASSERT(staticMetaObject.cast(_o));
pVerticalScroller *_t = static_cast<pVerticalScroller *>(_o);
switch (_id) {
case 0: _t->onChange(); break;
default: ;
}
}
Q_UNUSED(_a);
}
const QMetaObjectExtraData phoenix::pVerticalScroller::staticMetaObjectExtraData = {
0, qt_static_metacall
};
const QMetaObject phoenix::pVerticalScroller::staticMetaObject = { const QMetaObject phoenix::pVerticalScroller::staticMetaObject = {
{ &QObject::staticMetaObject, qt_meta_stringdata_phoenix__pVerticalScroller, { &QObject::staticMetaObject, qt_meta_stringdata_phoenix__pVerticalScroller,
qt_meta_data_phoenix__pVerticalScroller, 0 } qt_meta_data_phoenix__pVerticalScroller, &staticMetaObjectExtraData }
}; };
#ifdef Q_NO_DATA_RELOCATION #ifdef Q_NO_DATA_RELOCATION
@ -1034,10 +1347,8 @@ int phoenix::pVerticalScroller::qt_metacall(QMetaObject::Call _c, int _id, void
if (_id < 0) if (_id < 0)
return _id; return _id;
if (_c == QMetaObject::InvokeMetaMethod) { if (_c == QMetaObject::InvokeMetaMethod) {
switch (_id) { if (_id < 1)
case 0: onChange(); break; qt_static_metacall(this, _c, _id, _a);
default: ;
}
_id -= 1; _id -= 1;
} }
return _id; return _id;
@ -1045,7 +1356,7 @@ int phoenix::pVerticalScroller::qt_metacall(QMetaObject::Call _c, int _id, void
static const uint qt_meta_data_phoenix__pVerticalSlider[] = { static const uint qt_meta_data_phoenix__pVerticalSlider[] = {
// content: // content:
4, // revision 6, // revision
0, // classname 0, // classname
0, 0, // classinfo 0, 0, // classinfo
1, 14, // methods 1, 14, // methods
@ -1065,9 +1376,26 @@ static const char qt_meta_stringdata_phoenix__pVerticalSlider[] = {
"phoenix::pVerticalSlider\0\0onChange()\0" "phoenix::pVerticalSlider\0\0onChange()\0"
}; };
void phoenix::pVerticalSlider::qt_static_metacall(QObject *_o, QMetaObject::Call _c, int _id, void **_a)
{
if (_c == QMetaObject::InvokeMetaMethod) {
Q_ASSERT(staticMetaObject.cast(_o));
pVerticalSlider *_t = static_cast<pVerticalSlider *>(_o);
switch (_id) {
case 0: _t->onChange(); break;
default: ;
}
}
Q_UNUSED(_a);
}
const QMetaObjectExtraData phoenix::pVerticalSlider::staticMetaObjectExtraData = {
0, qt_static_metacall
};
const QMetaObject phoenix::pVerticalSlider::staticMetaObject = { const QMetaObject phoenix::pVerticalSlider::staticMetaObject = {
{ &QObject::staticMetaObject, qt_meta_stringdata_phoenix__pVerticalSlider, { &QObject::staticMetaObject, qt_meta_stringdata_phoenix__pVerticalSlider,
qt_meta_data_phoenix__pVerticalSlider, 0 } qt_meta_data_phoenix__pVerticalSlider, &staticMetaObjectExtraData }
}; };
#ifdef Q_NO_DATA_RELOCATION #ifdef Q_NO_DATA_RELOCATION
@ -1095,10 +1423,8 @@ int phoenix::pVerticalSlider::qt_metacall(QMetaObject::Call _c, int _id, void **
if (_id < 0) if (_id < 0)
return _id; return _id;
if (_c == QMetaObject::InvokeMetaMethod) { if (_c == QMetaObject::InvokeMetaMethod) {
switch (_id) { if (_id < 1)
case 0: onChange(); break; qt_static_metacall(this, _c, _id, _a);
default: ;
}
_id -= 1; _id -= 1;
} }
return _id; return _id;

View File

@ -388,6 +388,29 @@ public slots:
void onChange(); void onChange();
}; };
struct pConsole : public QObject, public pWidget {
Q_OBJECT
public:
Console& console;
struct QtConsole : public QTextEdit {
pConsole& self;
void keyPressEvent(QKeyEvent*);
void keyPressEventAcknowledge(QKeyEvent*);
QtConsole(pConsole& self) : self(self) {}
};
QtConsole* qtConsole;
void print(string text);
void reset();
pConsole(Console& console) : pWidget(console), console(console) {}
void constructor();
void destructor();
void orphan();
void keyPressEvent(QKeyEvent*);
};
struct pHexEdit : public QObject, public pWidget { struct pHexEdit : public QObject, public pWidget {
Q_OBJECT Q_OBJECT
@ -397,11 +420,17 @@ public:
pHexEdit& self; pHexEdit& self;
void keyPressEvent(QKeyEvent*); void keyPressEvent(QKeyEvent*);
void keyPressEventAcknowledge(QKeyEvent*); void keyPressEventAcknowledge(QKeyEvent*);
void wheelEvent(QWheelEvent*);
QtHexEdit(pHexEdit& self) : self(self) {} QtHexEdit(pHexEdit& self) : self(self) {}
}; };
struct QtHexEditScrollBar : public QScrollBar {
pHexEdit& self;
bool event(QEvent*);
QtHexEditScrollBar(pHexEdit& self) : QScrollBar(Qt::Vertical), self(self) {}
};
QtHexEdit* qtHexEdit; QtHexEdit* qtHexEdit;
QHBoxLayout* qtLayout; QHBoxLayout* qtLayout;
QScrollBar* qtScroll; QtHexEditScrollBar* qtScroll;
void setColumns(unsigned columns); void setColumns(unsigned columns);
void setLength(unsigned length); void setLength(unsigned length);
@ -414,6 +443,9 @@ public:
void destructor(); void destructor();
void orphan(); void orphan();
void keyPressEvent(QKeyEvent*); void keyPressEvent(QKeyEvent*);
signed rows();
signed rowsScrollable();
void scrollTo(signed position);
public slots: public slots:
void onScroll(); void onScroll();

View File

@ -0,0 +1,36 @@
namespace phoenix {
void pConsole::print(string text) {
}
void pConsole::reset() {
}
void pConsole::constructor() {
qtWidget = qtConsole = new QtConsole(*this);
pWidget::synchronizeState();
}
void pConsole::destructor() {
delete qtConsole;
qtWidget = qtConsole = nullptr;
}
void pConsole::orphan() {
destructor();
constructor();
}
void pConsole::keyPressEvent(QKeyEvent* event) {
}
void pConsole::QtConsole::keyPressEvent(QKeyEvent* event) {
self.keyPressEvent(event);
}
void pConsole::QtConsole::keyPressEventAcknowledge(QKeyEvent* event) {
QTextEdit::keyPressEvent(event);
}
}

View File

@ -45,8 +45,7 @@ void pHexEdit::update() {
uint8_t data = hexEdit.onRead(offset++); uint8_t data = hexEdit.onRead(offset++);
hexdata.append(hex<2>(data)); hexdata.append(hex<2>(data));
hexdata.append(" "); hexdata.append(" ");
char buffer[2] = { data >= 0x20 && data <= 0x7e ? (char)data : '.', 0 }; ansidata.append(data >= 0x20 && data <= 0x7e ? (char)data : '.');
ansidata.append(buffer);
} else { } else {
hexdata.append(" "); hexdata.append(" ");
ansidata.append(" "); ansidata.append(" ");
@ -70,6 +69,7 @@ void pHexEdit::constructor() {
qtHexEdit->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); qtHexEdit->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
qtHexEdit->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); qtHexEdit->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
qtHexEdit->setTextInteractionFlags(Qt::TextSelectableByKeyboard | Qt::TextSelectableByMouse);
qtLayout = new QHBoxLayout; qtLayout = new QHBoxLayout;
qtLayout->setAlignment(Qt::AlignRight); qtLayout->setAlignment(Qt::AlignRight);
@ -77,7 +77,7 @@ void pHexEdit::constructor() {
qtLayout->setSpacing(0); qtLayout->setSpacing(0);
qtHexEdit->setLayout(qtLayout); qtHexEdit->setLayout(qtLayout);
qtScroll = new QScrollBar(Qt::Vertical); qtScroll = new QtHexEditScrollBar(*this);
qtScroll->setSingleStep(1); qtScroll->setSingleStep(1);
qtLayout->addWidget(qtScroll); qtLayout->addWidget(qtScroll);
@ -108,38 +108,92 @@ void pHexEdit::orphan() {
void pHexEdit::keyPressEvent(QKeyEvent* event) { void pHexEdit::keyPressEvent(QKeyEvent* event) {
if(!hexEdit.onRead) return; if(!hexEdit.onRead) return;
QTextCursor cursor = qtHexEdit->textCursor(); //allow Ctrl+C (copy)
unsigned lineWidth = 10 + (hexEdit.state.columns * 3) + 1 + hexEdit.state.columns + 1; if(event->key() == Qt::Key_C && event->modifiers() == Qt::ControlModifier) {
unsigned cursorY = cursor.position() / lineWidth; qtHexEdit->keyPressEventAcknowledge(event);
unsigned cursorX = cursor.position() % lineWidth; return;
}
unsigned nibble; //disallow other text operations (cut, paste, etc)
if(event->modifiers() & (Qt::ControlModifier | Qt::AltModifier | Qt::MetaModifier)) return;
QTextCursor cursor = qtHexEdit->textCursor();
signed lineWidth = 10 + (hexEdit.state.columns * 3) + 1 + hexEdit.state.columns + 1;
signed cursorY = cursor.position() / lineWidth;
signed cursorX = cursor.position() % lineWidth;
unsigned nibble = 0;
switch(event->key()) { switch(event->key()) {
case Qt::Key_0: nibble = 0; break; default: return;
case Qt::Key_1: nibble = 1; break;
case Qt::Key_2: nibble = 2; break; case Qt::Key_Left:
case Qt::Key_3: nibble = 3; break; if(cursorX > 0) {
case Qt::Key_4: nibble = 4; break; cursor.setPosition(cursor.position() - 1);
case Qt::Key_5: nibble = 5; break; qtHexEdit->setTextCursor(cursor);
case Qt::Key_6: nibble = 6; break;
case Qt::Key_7: nibble = 7; break;
case Qt::Key_8: nibble = 8; break;
case Qt::Key_9: nibble = 9; break;
case Qt::Key_A: nibble = 10; break;
case Qt::Key_B: nibble = 11; break;
case Qt::Key_C: nibble = 12; break;
case Qt::Key_D: nibble = 13; break;
case Qt::Key_E: nibble = 14; break;
case Qt::Key_F: nibble = 15; break;
default: {
//allow navigation keys to move cursor, but block text input
qtHexEdit->setTextInteractionFlags(Qt::TextInteractionFlags(
Qt::TextSelectableByKeyboard | Qt::TextSelectableByMouse
));
qtHexEdit->keyPressEventAcknowledge(event);
qtHexEdit->setTextInteractionFlags(Qt::TextEditorInteraction);
return;
} }
return;
case Qt::Key_Right:
if(cursorX < lineWidth - 1) {
cursor.setPosition(cursor.position() + 1);
qtHexEdit->setTextCursor(cursor);
}
return;
case Qt::Key_Home:
cursor.setPosition(cursorY * lineWidth + 10);
qtHexEdit->setTextCursor(cursor);
return;
case Qt::Key_End:
cursor.setPosition(cursorY * lineWidth + 57);
qtHexEdit->setTextCursor(cursor);
return;
case Qt::Key_Up:
if(cursorY > 0) {
cursor.setPosition(cursor.position() - lineWidth);
qtHexEdit->setTextCursor(cursor);
} else {
scrollTo(qtScroll->sliderPosition() - 1);
}
return;
case Qt::Key_Down:
if(cursorY >= rows() - 1) {
//cannot scroll down further
} else if(cursorY < hexEdit.state.rows - 1) {
cursor.setPosition(cursor.position() + lineWidth);
qtHexEdit->setTextCursor(cursor);
} else {
scrollTo(qtScroll->sliderPosition() + 1);
}
return;
case Qt::Key_PageUp:
scrollTo(qtScroll->sliderPosition() - hexEdit.state.rows);
return;
case Qt::Key_PageDown:
scrollTo(qtScroll->sliderPosition() + hexEdit.state.rows);
return;
case Qt::Key_0: nibble = 0; break;
case Qt::Key_1: nibble = 1; break;
case Qt::Key_2: nibble = 2; break;
case Qt::Key_3: nibble = 3; break;
case Qt::Key_4: nibble = 4; break;
case Qt::Key_5: nibble = 5; break;
case Qt::Key_6: nibble = 6; break;
case Qt::Key_7: nibble = 7; break;
case Qt::Key_8: nibble = 8; break;
case Qt::Key_9: nibble = 9; break;
case Qt::Key_A: nibble = 10; break;
case Qt::Key_B: nibble = 11; break;
case Qt::Key_C: nibble = 12; break;
case Qt::Key_D: nibble = 13; break;
case Qt::Key_E: nibble = 14; break;
case Qt::Key_F: nibble = 15; break;
} }
if(cursorX >= 10) { if(cursorX >= 10) {
@ -177,6 +231,22 @@ void pHexEdit::keyPressEvent(QKeyEvent* event) {
} }
} }
//number of actual rows
signed pHexEdit::rows() {
return (max(1u, hexEdit.state.length) + hexEdit.state.columns - 1) / hexEdit.state.columns;
}
//number of scrollable row positions
signed pHexEdit::rowsScrollable() {
return max(0u, rows() - hexEdit.state.rows);
}
void pHexEdit::scrollTo(signed position) {
if(position > rowsScrollable()) position = rowsScrollable();
if(position < 0) position = 0;
qtScroll->setSliderPosition(position);
}
void pHexEdit::onScroll() { void pHexEdit::onScroll() {
if(locked) return; if(locked) return;
unsigned offset = qtScroll->sliderPosition(); unsigned offset = qtScroll->sliderPosition();
@ -192,4 +262,24 @@ void pHexEdit::QtHexEdit::keyPressEventAcknowledge(QKeyEvent* event) {
QTextEdit::keyPressEvent(event); QTextEdit::keyPressEvent(event);
} }
void pHexEdit::QtHexEdit::wheelEvent(QWheelEvent* event) {
if(event->orientation() == Qt::Vertical) {
signed offset = event->delta() < 0 ? +1 : -1;
self.scrollTo(self.qtScroll->sliderPosition() + offset);
event->accept();
}
}
bool pHexEdit::QtHexEditScrollBar::event(QEvent* event) {
if(event->type() == QEvent::Wheel) {
QWheelEvent* wheelEvent = (QWheelEvent*)event;
if(wheelEvent->orientation() == Qt::Vertical) {
signed offset = wheelEvent->delta() < 0 ? +1 : -1;
self.scrollTo(sliderPosition() + offset);
return true;
}
}
return QScrollBar::event(event);
}
} }

View File

@ -8,7 +8,7 @@ void pTextEdit::setCursorPosition(unsigned position) {
} }
void pTextEdit::setEditable(bool editable) { void pTextEdit::setEditable(bool editable) {
qtTextEdit->setReadOnly(!editable); qtTextEdit->setTextInteractionFlags(editable ? Qt::TextEditorInteraction : Qt::TextSelectableByKeyboard | Qt::TextSelectableByMouse);
} }
void pTextEdit::setText(string text) { void pTextEdit::setText(string text) {
@ -36,7 +36,6 @@ void pTextEdit::constructor() {
} }
void pTextEdit::destructor() { void pTextEdit::destructor() {
if(sizable.state.layout) sizable.state.layout->remove(textEdit);
delete qtTextEdit; delete qtTextEdit;
qtWidget = qtTextEdit = nullptr; qtWidget = qtTextEdit = nullptr;
} }

View File

@ -22,6 +22,7 @@
#include "widget/canvas.cpp" #include "widget/canvas.cpp"
#include "widget/check-button.cpp" #include "widget/check-button.cpp"
#include "widget/combo-button.cpp" #include "widget/combo-button.cpp"
#include "widget/console.cpp"
#include "widget/hex-edit.cpp" #include "widget/hex-edit.cpp"
#include "widget/horizontal-scroller.cpp" #include "widget/horizontal-scroller.cpp"
#include "widget/horizontal-slider.cpp" #include "widget/horizontal-slider.cpp"

View File

@ -30,6 +30,7 @@ namespace phoenix {
#include "widget/canvas.hpp" #include "widget/canvas.hpp"
#include "widget/check-button.hpp" #include "widget/check-button.hpp"
#include "widget/combo-button.hpp" #include "widget/combo-button.hpp"
#include "widget/console.hpp"
#include "widget/hex-edit.hpp" #include "widget/hex-edit.hpp"
#include "widget/horizontal-scroller.hpp" #include "widget/horizontal-scroller.hpp"
#include "widget/horizontal-slider.hpp" #include "widget/horizontal-slider.hpp"

View File

@ -0,0 +1,15 @@
namespace phoenix {
void pConsole::print(string text) {
}
void pConsole::reset() {
}
void pConsole::constructor() {
}
void pConsole::destructor() {
}
}

View File

@ -0,0 +1,14 @@
namespace phoenix {
struct pConsole : public pWidget {
Console& console;
void print(string text);
void reset();
pConsole(Console& console) : pWidget(console), console(console) {}
void constructor();
void destructor();
};
}

View File

@ -267,7 +267,12 @@ static LRESULT CALLBACK Application_windowProc(HWND hwnd, UINT msg, WPARAM wpara
case WM_CTLCOLORBTN: case WM_CTLCOLORBTN:
case WM_CTLCOLORSTATIC: { case WM_CTLCOLORSTATIC: {
Object* object = (Object*)GetWindowLongPtr((HWND)lparam, GWLP_USERDATA); Object* object = (Object*)GetWindowLongPtr((HWND)lparam, GWLP_USERDATA);
if(object && window.p.brush) { if(object == nullptr) break;
if(dynamic_cast<HexEdit*>(object) || dynamic_cast<LineEdit*>(object) || dynamic_cast<TextEdit*>(object)) {
//text edit controls, when disabled, use CTLCOLORSTATIC instead of CTLCOLOREDIT
//override this behavior: we do not want read-only edit controls to use the parent window background color
return DefWindowProc(hwnd, WM_CTLCOLOREDIT, wparam, lparam);
} else if(window.p.brush) {
HDC hdc = (HDC)wparam; HDC hdc = (HDC)wparam;
SetBkColor((HDC)wparam, window.p.brushColor); SetBkColor((HDC)wparam, window.p.brushColor);
return (INT_PTR)window.p.brush; return (INT_PTR)window.p.brush;

View File

@ -25,6 +25,7 @@
#include "widget/canvas.cpp" #include "widget/canvas.cpp"
#include "widget/check-button.cpp" #include "widget/check-button.cpp"
#include "widget/combo-button.cpp" #include "widget/combo-button.cpp"
#include "widget/console.cpp"
#include "widget/hex-edit.cpp" #include "widget/hex-edit.cpp"
#include "widget/horizontal-scroller.cpp" #include "widget/horizontal-scroller.cpp"
#include "widget/horizontal-slider.cpp" #include "widget/horizontal-slider.cpp"

View File

@ -305,8 +305,23 @@ struct pComboButton : public pWidget {
void setGeometry(Geometry geometry); void setGeometry(Geometry geometry);
}; };
struct pConsole : public pWidget {
Console& console;
LRESULT CALLBACK (*windowProc)(HWND, UINT, LPARAM, WPARAM);
void print(string text);
void reset();
pConsole(Console& console) : pWidget(console), console(console) {}
void constructor();
void destructor();
void orphan();
bool keyPress(unsigned key);
};
struct pHexEdit : public pWidget { struct pHexEdit : public pWidget {
HexEdit& hexEdit; HexEdit& hexEdit;
HWND scrollBar;
LRESULT CALLBACK (*windowProc)(HWND, UINT, LPARAM, WPARAM); LRESULT CALLBACK (*windowProc)(HWND, UINT, LPARAM, WPARAM);
void setColumns(unsigned columns); void setColumns(unsigned columns);
@ -320,6 +335,10 @@ struct pHexEdit : public pWidget {
void destructor(); void destructor();
void orphan(); void orphan();
bool keyPress(unsigned key); bool keyPress(unsigned key);
signed rows();
signed rowsScrollable();
signed scrollPosition();
void scrollTo(signed position);
}; };
struct pHorizontalScroller : public pWidget { struct pHorizontalScroller : public pWidget {

View File

@ -0,0 +1,44 @@
namespace phoenix {
static LRESULT CALLBACK Console_windowProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) {
Console& console = *(Console*)GetWindowLongPtr(hwnd, GWLP_USERDATA);
if(msg == WM_CHAR) {
if(console.p.keyPress(wparam)) return 0;
}
return console.p.windowProc(hwnd, msg, wparam, lparam);
}
void pConsole::print(string text) {
}
void pConsole::reset() {
}
void pConsole::constructor() {
hwnd = CreateWindowEx(
WS_EX_CLIENTEDGE, L"EDIT", L"",
WS_CHILD | WS_TABSTOP | ES_READONLY | ES_MULTILINE | ES_WANTRETURN,
0, 0, 0, 0, parentWindow->p.hwnd, (HMENU)id, GetModuleHandle(0), 0
);
SetWindowLongPtr(hwnd, GWLP_USERDATA, (LONG_PTR)&console);
setDefaultFont();
windowProc = (LRESULT CALLBACK (*)(HWND, UINT, LPARAM, WPARAM))GetWindowLongPtr(hwnd, GWLP_WNDPROC);
SetWindowLongPtr(hwnd, GWLP_WNDPROC, (LONG_PTR)Console_windowProc);
synchronize();
}
void pConsole::destructor() {
DestroyWindow(hwnd);
}
void pConsole::orphan() {
destructor();
constructor();
}
bool pConsole::keyPress(unsigned scancode) {
return false;
}
}

View File

@ -2,9 +2,52 @@ namespace phoenix {
static LRESULT CALLBACK HexEdit_windowProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) { static LRESULT CALLBACK HexEdit_windowProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) {
HexEdit& hexEdit = *(HexEdit*)GetWindowLongPtr(hwnd, GWLP_USERDATA); HexEdit& hexEdit = *(HexEdit*)GetWindowLongPtr(hwnd, GWLP_USERDATA);
if(msg == WM_CHAR) {
switch(msg) {
case WM_KEYDOWN:
if(hexEdit.p.keyPress(wparam)) return 0; if(hexEdit.p.keyPress(wparam)) return 0;
break;
case WM_MOUSEWHEEL: {
signed offset = -((int16_t)HIWORD(wparam) / WHEEL_DELTA);
hexEdit.p.scrollTo(hexEdit.p.scrollPosition() + offset);
return true;
} }
case WM_SIZE: {
RECT rc;
GetClientRect(hexEdit.p.hwnd, &rc);
SetWindowPos(hexEdit.p.scrollBar, HWND_TOP, rc.right - 18, 0, 18, rc.bottom, SWP_SHOWWINDOW);
break;
}
case WM_VSCROLL: {
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);
GetScrollInfo((HWND)lparam, SB_CTL, &info); //get clamped position
hexEdit.p.scrollTo(info.nPos);
return TRUE;
}
}
return hexEdit.p.windowProc(hwnd, msg, wparam, lparam); return hexEdit.p.windowProc(hwnd, msg, wparam, lparam);
} }
@ -13,10 +56,13 @@ void pHexEdit::setColumns(unsigned columns) {
} }
void pHexEdit::setLength(unsigned length) { void pHexEdit::setLength(unsigned length) {
SetScrollRange(scrollBar, SB_CTL, 0, rowsScrollable(), TRUE);
EnableWindow(scrollBar, rowsScrollable() > 0);
update(); update();
} }
void pHexEdit::setOffset(unsigned offset) { void pHexEdit::setOffset(unsigned offset) {
SetScrollPos(scrollBar, SB_CTL, offset / hexEdit.state.columns, TRUE);
update(); update();
} }
@ -45,8 +91,7 @@ void pHexEdit::update() {
uint8_t data = hexEdit.onRead(offset++); uint8_t data = hexEdit.onRead(offset++);
hexdata.append(hex<2>(data)); hexdata.append(hex<2>(data));
hexdata.append(" "); hexdata.append(" ");
char buffer[2] = {data >= 0x20 && data <= 0x7e ? (char)data : '.', 0}; ansidata.append(data >= 0x20 && data <= 0x7e ? (char)data : '.');
ansidata.append(buffer);
} else { } else {
hexdata.append(" "); hexdata.append(" ");
ansidata.append(" "); ansidata.append(" ");
@ -66,15 +111,27 @@ void pHexEdit::update() {
void pHexEdit::constructor() { void pHexEdit::constructor() {
hwnd = CreateWindowEx( hwnd = CreateWindowEx(
WS_EX_CLIENTEDGE, L"EDIT", L"", WS_EX_CLIENTEDGE, L"EDIT", L"",
WS_CHILD | WS_TABSTOP | ES_READONLY | ES_MULTILINE | ES_WANTRETURN, WS_CHILD | WS_TABSTOP | ES_AUTOHSCROLL | ES_READONLY | ES_MULTILINE | ES_WANTRETURN,
0, 0, 0, 0, parentWindow->p.hwnd, (HMENU)id, GetModuleHandle(0), 0 0, 0, 0, 0, parentWindow->p.hwnd, (HMENU)id, GetModuleHandle(0), 0
); );
SetWindowLongPtr(hwnd, GWLP_USERDATA, (LONG_PTR)&hexEdit); SetWindowLongPtr(hwnd, GWLP_USERDATA, (LONG_PTR)&hexEdit);
setDefaultFont();
update(); scrollBar = CreateWindowEx(
0, L"SCROLLBAR", L"",
WS_VISIBLE | WS_CHILD | SBS_VERT,
0, 0, 0, 0, hwnd, (HMENU)id, GetModuleHandle(0), 0
);
SetWindowLongPtr(scrollBar, GWLP_USERDATA, (LONG_PTR)&hexEdit);
windowProc = (LRESULT CALLBACK (*)(HWND, UINT, LPARAM, WPARAM))GetWindowLongPtr(hwnd, GWLP_WNDPROC); windowProc = (LRESULT CALLBACK (*)(HWND, UINT, LPARAM, WPARAM))GetWindowLongPtr(hwnd, GWLP_WNDPROC);
SetWindowLongPtr(hwnd, GWLP_WNDPROC, (LONG_PTR)HexEdit_windowProc); SetWindowLongPtr(hwnd, GWLP_WNDPROC, (LONG_PTR)HexEdit_windowProc);
setDefaultFont();
setLength(hexEdit.state.length);
setOffset(hexEdit.state.offset);
update();
PostMessage(hwnd, EM_SETSEL, 10, 10);
synchronize(); synchronize();
} }
@ -90,10 +147,45 @@ void pHexEdit::orphan() {
bool pHexEdit::keyPress(unsigned scancode) { bool pHexEdit::keyPress(unsigned scancode) {
if(!hexEdit.onRead) return false; if(!hexEdit.onRead) return false;
unsigned position = LOWORD(Edit_GetSel(hwnd)); signed position = LOWORD(Edit_GetSel(hwnd));
unsigned lineWidth = 10 + (hexEdit.state.columns * 3) + 1 + hexEdit.state.columns + 2; signed lineWidth = 10 + (hexEdit.state.columns * 3) + 1 + hexEdit.state.columns + 2;
unsigned cursorY = position / lineWidth; signed cursorY = position / lineWidth;
unsigned cursorX = position % lineWidth; signed cursorX = position % lineWidth;
if(scancode == VK_HOME) {
signed offset = cursorY * lineWidth + 10;
Edit_SetSel(hwnd, offset, offset);
return true;
}
if(scancode == VK_END) {
signed offset = cursorY * lineWidth + 57;
Edit_SetSel(hwnd, offset, offset);
return true;
}
if(scancode == VK_UP) {
if(cursorY > 0) return false;
scrollTo(scrollPosition() - 1);
return true;
}
if(scancode == VK_DOWN) {
if(cursorY >= rows() - 1) return true;
if(cursorY < hexEdit.state.rows - 1) return false;
scrollTo(scrollPosition() + 1);
return true;
}
if(scancode == VK_PRIOR) {
scrollTo(scrollPosition() - hexEdit.state.rows);
return true;
}
if(scancode == VK_NEXT) {
scrollTo(scrollPosition() + hexEdit.state.rows);
return true;
}
//convert scancode to hex nibble //convert scancode to hex nibble
if(scancode >= '0' && scancode <= '9') scancode = scancode - '0'; if(scancode >= '0' && scancode <= '9') scancode = scancode - '0';
@ -137,4 +229,23 @@ bool pHexEdit::keyPress(unsigned scancode) {
return true; return true;
} }
signed pHexEdit::rows() {
return (max(1u, hexEdit.state.length) + hexEdit.state.columns - 1) / hexEdit.state.columns;
}
signed pHexEdit::rowsScrollable() {
return max(0u, rows() - hexEdit.state.rows);
}
signed pHexEdit::scrollPosition() {
return hexEdit.state.offset / hexEdit.state.columns;
}
void pHexEdit::scrollTo(signed position) {
if(position > rowsScrollable()) position = rowsScrollable();
if(position < 0) position = 0;
if(position == scrollPosition()) return;
hexEdit.setOffset(position * hexEdit.state.columns);
}
} }

View File

@ -5,6 +5,8 @@ void OpenGL::shader(const char* pathname) {
for(auto& frame : frames) glDeleteTextures(1, &frame.texture); for(auto& frame : frames) glDeleteTextures(1, &frame.texture);
frames.reset(); frames.reset();
settings.reset();
format = GL_RGBA8; format = GL_RGBA8;
filter = GL_LINEAR; filter = GL_LINEAR;
wrap = GL_CLAMP_TO_BORDER; wrap = GL_CLAMP_TO_BORDER;
@ -13,6 +15,11 @@ void OpenGL::shader(const char* pathname) {
if(pathname) { if(pathname) {
auto document = Markup::Document(file::read({pathname, "manifest.bml"})); auto document = Markup::Document(file::read({pathname, "manifest.bml"}));
for(auto& node : document["settings"]) {
settings.insert({node.name, node.text()});
}
for(auto& node : document.find("program")) { for(auto& node : document.find("program")) {
unsigned n = programs.size(); unsigned n = programs.size();
programs(n).bind(this, node, pathname); programs(n).bind(this, node, pathname);

View File

@ -2,10 +2,10 @@
#include <GL/gl.h> #include <GL/gl.h>
#include <GL/glx.h> #include <GL/glx.h>
#define glGetProcAddress(name) (*glXGetProcAddress)((const GLubyte*)(name)) #define glGetProcAddress(name) (*glXGetProcAddress)((const GLubyte*)(name))
#elif defined(PLATFORM_OSX) #elif defined(PLATFORM_MACOSX)
#include <OpenGL/gl.h> #include <OpenGL/gl.h>
#include <OpenGL/gl3.h> #include <OpenGL/gl3.h>
#elif defined(PLATFORM_WIN) #elif defined(PLATFORM_WINDOWS)
#include <GL/gl.h> #include <GL/gl.h>
#include <GL/glext.h> #include <GL/glext.h>
#define glGetProcAddress(name) wglGetProcAddress(name) #define glGetProcAddress(name) wglGetProcAddress(name)
@ -57,6 +57,7 @@ struct OpenGLProgram : OpenGLSurface {
vector<OpenGLTexture> pixmaps; vector<OpenGLTexture> pixmaps;
void bind(OpenGL* instance, const Markup::Node& node, const string& pathname); void bind(OpenGL* instance, const Markup::Node& node, const string& pathname);
void parse(OpenGL* instance, string& source);
void release(); void release();
}; };
@ -74,6 +75,17 @@ struct OpenGL : OpenGLProgram {
unsigned outputWidth = 0; unsigned outputWidth = 0;
unsigned outputHeight = 0; unsigned outputHeight = 0;
struct Setting {
string name;
string value;
bool operator< (const Setting& source) { return name < source.name; }
bool operator==(const Setting& source) { return name == source.name; }
Setting() {}
Setting(const string& name) : name(name) {}
Setting(const string& name, const string& value) : name(name), value(value) {}
};
set<Setting> settings;
void shader(const char* pathname); void shader(const char* pathname);
void bind(const Markup::Node& node, const string& pathname); void bind(const Markup::Node& node, const string& pathname);
bool lock(uint32_t*& data, unsigned& pitch); bool lock(uint32_t*& data, unsigned& pitch);

View File

@ -17,6 +17,7 @@ void OpenGLProgram::bind(OpenGL* instance, const Markup::Node& node, const strin
if(file::exists({pathname, node["vertex"].text()})) { if(file::exists({pathname, node["vertex"].text()})) {
string source = file::read({pathname, node["vertex"].text()}); string source = file::read({pathname, node["vertex"].text()});
parse(instance, source);
vertex = glrCreateShader(program, GL_VERTEX_SHADER, source); vertex = glrCreateShader(program, GL_VERTEX_SHADER, source);
} else { } else {
vertex = glrCreateShader(program, GL_VERTEX_SHADER, OpenGLVertexShader); vertex = glrCreateShader(program, GL_VERTEX_SHADER, OpenGLVertexShader);
@ -24,6 +25,7 @@ void OpenGLProgram::bind(OpenGL* instance, const Markup::Node& node, const strin
if(file::exists({pathname, node["geometry"].text()})) { if(file::exists({pathname, node["geometry"].text()})) {
string source = file::read({pathname, node["geometry"].text()}); string source = file::read({pathname, node["geometry"].text()});
parse(instance, source);
geometry = glrCreateShader(program, GL_GEOMETRY_SHADER, source); geometry = glrCreateShader(program, GL_GEOMETRY_SHADER, source);
} else { } else {
//geometry shaders, when attached, must pass all vertex output through to the fragment shaders //geometry shaders, when attached, must pass all vertex output through to the fragment shaders
@ -32,6 +34,7 @@ void OpenGLProgram::bind(OpenGL* instance, const Markup::Node& node, const strin
if(file::exists({pathname, node["fragment"].text()})) { if(file::exists({pathname, node["fragment"].text()})) {
string source = file::read({pathname, node["fragment"].text()}); string source = file::read({pathname, node["fragment"].text()});
parse(instance, source);
fragment = glrCreateShader(program, GL_FRAGMENT_SHADER, source); fragment = glrCreateShader(program, GL_FRAGMENT_SHADER, source);
} else { } else {
fragment = glrCreateShader(program, GL_FRAGMENT_SHADER, OpenGLFragmentShader); fragment = glrCreateShader(program, GL_FRAGMENT_SHADER, OpenGLFragmentShader);
@ -68,6 +71,25 @@ void OpenGLProgram::bind(OpenGL* instance, const Markup::Node& node, const strin
glrLinkProgram(program); glrLinkProgram(program);
} }
//apply manifest settings to shader source #in tags
void OpenGLProgram::parse(OpenGL* instance, string& source) {
lstring lines = source.split("\n");
for(auto& line : lines) {
string s = line;
if(auto position = s.find("//")) s.resize(position()); //strip comments
s.strip(); //remove extraneous whitespace
if(s.match("#in ?*")) {
s.ltrim<1>("#in ").strip();
if(auto setting = instance->settings.find({s})) {
line = {"#define ", setting().name, " ", setting().value};
} else {
line.reset(); //undefined variable (test in source with #ifdef)
}
}
}
source = lines.merge("\n");
}
void OpenGLProgram::release() { void OpenGLProgram::release() {
OpenGLSurface::release(); OpenGLSurface::release();
for(auto& pixmap : pixmaps) glDeleteTextures(1, &pixmap.texture); for(auto& pixmap : pixmaps) glDeleteTextures(1, &pixmap.texture);

View File

@ -126,9 +126,6 @@ void PPU::enable() {
} }
void PPU::power() { void PPU::power() {
ppu1_version = config.ppu1.version;
ppu2_version = config.ppu2.version;
for(auto& n : vram) n = 0x00; for(auto& n : vram) n = 0x00;
for(auto& n : oam) n = 0x00; for(auto& n : oam) n = 0x00;
for(auto& n : cgram) n = 0x00; for(auto& n : cgram) n = 0x00;

View File

@ -14,8 +14,8 @@ struct PPU : Thread, public PPUcounter {
uint32* surface; uint32* surface;
uint32* output; uint32* output;
uint8 ppu1_version; unsigned ppu1_version = 1;
uint8 ppu2_version; unsigned ppu2_version = 3;
static void Enter(); static void Enter();
void add_clocks(unsigned clocks); void add_clocks(unsigned clocks);

View File

@ -53,7 +53,6 @@ void SuperFX::unload() {
void SuperFX::power() { void SuperFX::power() {
GSU::power(); GSU::power();
clockmode = config.superfx.speed;
} }
void SuperFX::reset() { void SuperFX::reset() {

View File

@ -19,7 +19,7 @@ struct SuperFX : Processor::GSU, Coprocessor {
void serialize(serializer&); void serialize(serializer&);
privileged: privileged:
unsigned clockmode; unsigned clockmode = 0; //0 = selectable, 1 = force 10.74mhz, 2 = force 21.48mhz
unsigned instruction_counter; unsigned instruction_counter;
}; };

View File

@ -1,26 +0,0 @@
#ifdef SYSTEM_CPP
Configuration config;
Configuration::Configuration() {
controller_port1 = Input::Device::Joypad;
controller_port2 = Input::Device::Joypad;
expansion_port = System::ExpansionPortDevice::Satellaview;
region = System::Region::Autodetect;
random = true;
cpu.version = 2;
cpu.ntsc_frequency = 21477272; //315 / 88 * 6000000
cpu.pal_frequency = 21281370;
cpu.wram_init_value = 0x55;
smp.ntsc_frequency = 24607104; //32040.5 * 768
smp.pal_frequency = 24607104;
ppu1.version = 1;
ppu2.version = 3;
superfx.speed = 0; //0 = auto-select, 1 = force 10.74MHz, 2 = force 21.48MHz
}
#endif

View File

@ -1,35 +0,0 @@
struct Configuration {
Input::Device controller_port1;
Input::Device controller_port2;
System::ExpansionPortDevice expansion_port;
System::Region region;
bool random;
struct CPU {
unsigned version;
unsigned ntsc_frequency;
unsigned pal_frequency;
unsigned wram_init_value;
} cpu;
struct SMP {
unsigned ntsc_frequency;
unsigned pal_frequency;
} smp;
struct PPU1 {
unsigned version;
} ppu1;
struct PPU2 {
unsigned version;
} ppu2;
struct SuperFX {
unsigned speed;
} superfx;
Configuration();
};
extern Configuration config;

View File

@ -120,8 +120,7 @@ void CPU::enable() {
} }
void CPU::power() { void CPU::power() {
cpu_version = config.cpu.version; for(auto& byte : wram) byte = random(0x55);
for(auto& byte : wram) byte = random(config.cpu.wram_init_value);
regs.a = regs.x = regs.y = 0x0000; regs.a = regs.x = regs.y = 0x0000;
regs.s = 0x01ff; regs.s = 0x01ff;

View File

@ -26,13 +26,13 @@ struct CPU : Processor::R65816, Thread, public PPUcounter {
~CPU(); ~CPU();
privileged: privileged:
unsigned cpu_version = 2; //allowed: 1, 2
#include "dma/dma.hpp" #include "dma/dma.hpp"
#include "memory/memory.hpp" #include "memory/memory.hpp"
#include "mmio/mmio.hpp" #include "mmio/mmio.hpp"
#include "timing/timing.hpp" #include "timing/timing.hpp"
uint8 cpu_version;
struct Status { struct Status {
bool interrupt_pending; bool interrupt_pending;

View File

@ -87,9 +87,6 @@ void PPU::enable() {
} }
void PPU::power() { void PPU::power() {
ppu1_version = config.ppu1.version;
ppu2_version = config.ppu2.version;
for(auto& n : vram) n = random(0x00); for(auto& n : vram) n = random(0x00);
for(auto& n : oam) n = random(0x00); for(auto& n : oam) n = random(0x00);
for(auto& n : cgram) n = random(0x00); for(auto& n : cgram) n = random(0x00);

View File

@ -22,12 +22,12 @@ struct PPU : Thread, public PPUcounter {
~PPU(); ~PPU();
privileged: privileged:
unsigned ppu1_version = 1; //allowed: 1
unsigned ppu2_version = 3; //allowed: 1, 2, 3
uint32* surface; uint32* surface;
uint32* output; uint32* output;
uint8 ppu1_version;
uint8 ppu2_version;
struct { struct {
bool interlace; bool interlace;
bool overscan; bool overscan;

View File

@ -1,18 +0,0 @@
Random random;
void Random::seed(unsigned seed_iter) {
iter = seed_iter;
}
unsigned Random::operator()(unsigned result) {
if(config.random == false) return result;
return iter = (iter >> 1) ^ (((iter & 1) - 1) & 0xedb88320);
}
void Random::serialize(serializer& s) {
s.integer(iter);
}
Random::Random() {
iter = 0;
}

View File

@ -1,11 +0,0 @@
struct Random {
void seed(unsigned seed);
unsigned operator()(unsigned result = 0);
void serialize(serializer&);
Random();
private:
unsigned iter;
};
extern Random random;

View File

@ -12,7 +12,7 @@
namespace SuperFamicom { namespace SuperFamicom {
namespace Info { namespace Info {
static const char Name[] = "bsnes"; static const char Name[] = "bsnes";
static const unsigned SerializerVersion = 26; static const unsigned SerializerVersion = 27;
} }
} }

View File

@ -21,8 +21,8 @@ void Input::connect(bool port, Input::Device id) {
} }
switch(port) { switch(port) {
case Controller::Port1: config.controller_port1 = id; break; case Controller::Port1: configuration.controller_port1 = id; break;
case Controller::Port2: config.controller_port2 = id; break; case Controller::Port2: configuration.controller_port2 = id; break;
} }
} }

View File

@ -4,16 +4,16 @@
namespace SuperFamicom { namespace SuperFamicom {
System system; System system;
Configuration configuration;
#include <sfc/config/config.cpp> Random random;
#include <sfc/scheduler/scheduler.cpp>
#include <sfc/random/random.cpp>
#include "video.cpp" #include "video.cpp"
#include "audio.cpp" #include "audio.cpp"
#include "input.cpp" #include "input.cpp"
#include "serialization.cpp" #include "serialization.cpp"
#include <sfc/scheduler/scheduler.cpp>
void System::run() { void System::run() {
scheduler.sync = Scheduler::SynchronizeMode::None; scheduler.sync = Scheduler::SynchronizeMode::None;
@ -86,8 +86,8 @@ void System::init() {
video.init(); video.init();
audio.init(); audio.init();
input.connect(0, config.controller_port1); input.connect(0, configuration.controller_port1);
input.connect(1, config.controller_port2); input.connect(1, configuration.controller_port2);
} }
void System::term() { void System::term() {
@ -102,14 +102,14 @@ void System::load() {
interface->notify("Error: required Super Famicom firmware ipl.rom not found.\n"); interface->notify("Error: required Super Famicom firmware ipl.rom not found.\n");
} }
region = config.region; region = configuration.region;
expansion = config.expansion_port; expansion = configuration.expansion_port;
if(region == Region::Autodetect) { if(region == Region::Autodetect) {
region = (cartridge.region() == Cartridge::Region::NTSC ? Region::NTSC : Region::PAL); region = (cartridge.region() == Cartridge::Region::NTSC ? Region::NTSC : Region::PAL);
} }
cpu_frequency = region() == Region::NTSC ? config.cpu.ntsc_frequency : config.cpu.pal_frequency; cpu_frequency = region() == Region::NTSC ? 21477272 : 21281370;
apu_frequency = region() == Region::NTSC ? config.smp.ntsc_frequency : config.smp.pal_frequency; apu_frequency = 24607104;
audio.coprocessor_enable(false); audio.coprocessor_enable(false);
@ -233,8 +233,8 @@ void System::reset() {
if(cartridge.has_msu1()) cpu.coprocessors.append(&msu1); if(cartridge.has_msu1()) cpu.coprocessors.append(&msu1);
scheduler.init(); scheduler.init();
input.connect(0, config.controller_port1); input.connect(0, configuration.controller_port1);
input.connect(1, config.controller_port2); input.connect(1, configuration.controller_port2);
} }
void System::scanline() { void System::scanline() {

View File

@ -42,12 +42,40 @@ private:
friend class Input; friend class Input;
}; };
extern System system;
#include "video.hpp" #include "video.hpp"
#include "audio.hpp" #include "audio.hpp"
#include "input.hpp" #include "input.hpp"
#include <sfc/config/config.hpp>
#include <sfc/scheduler/scheduler.hpp> #include <sfc/scheduler/scheduler.hpp>
#include <sfc/random/random.hpp>
extern System system; struct Configuration {
Input::Device controller_port1 = Input::Device::Joypad;
Input::Device controller_port2 = Input::Device::Joypad;
System::ExpansionPortDevice expansion_port = System::ExpansionPortDevice::Satellaview;
System::Region region = System::Region::Autodetect;
bool random = true;
};
extern Configuration configuration;
struct Random {
void seed(unsigned seed) {
iter = seed;
}
unsigned operator()(unsigned result) {
if(configuration.random == false) return result;
return iter = (iter >> 1) ^ (((iter & 1) - 1) & 0xedb88320);
}
void serialize(serializer& s) {
s.integer(iter);
}
private:
unsigned iter = 0;
};
extern Random random;

View File

@ -74,7 +74,7 @@ void Video::draw_cursor(uint16_t color, int x, int y) {
} }
void Video::update() { void Video::update() {
switch(config.controller_port2) { switch(configuration.controller_port2) {
case Input::Device::SuperScope: case Input::Device::SuperScope:
if(dynamic_cast<SuperScope*>(input.port2)) { if(dynamic_cast<SuperScope*>(input.port2)) {
SuperScope &device = (SuperScope&)*input.port2; SuperScope &device = (SuperScope&)*input.port2;

View File

@ -79,7 +79,7 @@ else ifeq ($(platform),macosx)
mkdir out/$(name).app/Contents/MacOS mkdir out/$(name).app/Contents/MacOS
mkdir out/$(name).app/Contents/Resources mkdir out/$(name).app/Contents/Resources
cp data/Info.plist out/$(name).app/Contents/Info.plist cp data/Info.plist out/$(name).app/Contents/Info.plist
sips -s format icns data/higan512.png --out out/$(name).app/Contents/Resources/higan.icns sips -s format icns data/higan.png --out out/$(name).app/Contents/Resources/higan.icns
$(strip $(compiler) -o out/$(name).app/Contents/MacOS/$(name) $(objects) $(link)) $(strip $(compiler) -o out/$(name).app/Contents/MacOS/$(name) $(objects) $(link))
else else
$(strip $(compiler) -o out/$(name) $(objects) $(link)) $(strip $(compiler) -o out/$(name) $(objects) $(link))

View File

@ -12,7 +12,7 @@ ConfigurationSettings::ConfigurationSettings() {
video.maskOverscan.append(video.maskOverscan.vertical = 8, "Vertical"); video.maskOverscan.append(video.maskOverscan.vertical = 8, "Vertical");
video.append(video.maskOverscan, "MaskOverscan"); video.append(video.maskOverscan, "MaskOverscan");
video.append(video.saturation = 100, "Saturation"); video.append(video.saturation = 100, "Saturation");
video.append(video.gamma = 150, "Gamma"); video.append(video.gamma = 100, "Gamma");
video.append(video.luminance = 100, "Luminance"); video.append(video.luminance = 100, "Luminance");
video.append(video.startFullScreen = false, "StartFullScreen"); video.append(video.startFullScreen = false, "StartFullScreen");
append(video, "Video"); append(video, "Video");

View File

@ -53,7 +53,7 @@ Program::Program(int argc, char** argv) {
bootstrap(); bootstrap();
active = nullptr; active = nullptr;
if(Intrinsics::platform() == Intrinsics::Platform::OSX) { if(Intrinsics::platform() == Intrinsics::Platform::MacOSX) {
normalFont = Font::sans(12); normalFont = Font::sans(12);
boldFont = Font::sans(12, "Bold"); boldFont = Font::sans(12, "Bold");
titleFont = Font::sans(20, "Bold"); titleFont = Font::sans(20, "Bold");

View File

@ -105,7 +105,7 @@ Presentation::Presentation() {
} }
settingsMenu.append(*new Separator); settingsMenu.append(*new Separator);
settingsMenu.append(synchronizeVideo, synchronizeAudio, muteAudio); settingsMenu.append(synchronizeVideo, synchronizeAudio, muteAudio);
if(Intrinsics::platform() != Intrinsics::Platform::OSX) { if(Intrinsics::platform() != Intrinsics::Platform::MacOSX) {
settingsMenu.append(*new Separator); settingsMenu.append(*new Separator);
settingsMenu.append(configurationSettings); settingsMenu.append(configurationSettings);
} }
@ -133,7 +133,7 @@ Presentation::Presentation() {
onClose = [&] { onClose = [&] {
setVisible(false); setVisible(false);
if(Intrinsics::platform() == Intrinsics::Platform::OSX) { if(Intrinsics::platform() == Intrinsics::Platform::MacOSX) {
utility->unload(); utility->unload();
} else { } else {
Application::quit(); Application::quit();
@ -151,7 +151,7 @@ Presentation::Presentation() {
shaderNone.onActivate = [&] { config->video.shader = "None"; utility->updateShader(); }; shaderNone.onActivate = [&] { config->video.shader = "None"; utility->updateShader(); };
shaderBlur.onActivate = [&] { config->video.shader = "Blur"; utility->updateShader(); }; shaderBlur.onActivate = [&] { config->video.shader = "Blur"; utility->updateShader(); };
shaderEmulation.onActivate = [&] { config->video.shader = "Emulation"; utility->updateShader(); }; shaderEmulation.onActivate = [&] { config->video.shader = "Display Emulation"; utility->updateShader(); };
centerVideo.onActivate = [&] { config->video.scaleMode = 0; utility->resize(); }; centerVideo.onActivate = [&] { config->video.scaleMode = 0; utility->resize(); };
scaleVideo.onActivate = [&] { config->video.scaleMode = 1; utility->resize(); }; scaleVideo.onActivate = [&] { config->video.scaleMode = 1; utility->resize(); };
stretchVideo.onActivate = [&] { config->video.scaleMode = 2; utility->resize(); }; stretchVideo.onActivate = [&] { config->video.scaleMode = 2; utility->resize(); };

View File

@ -57,7 +57,7 @@ AdvancedSettings::AdvancedSettings() {
libraryLayout.append(libraryLabel, {0, 0}, 5); libraryLayout.append(libraryLabel, {0, 0}, 5);
libraryLayout.append(libraryPath, {~0, 0}, 5); libraryLayout.append(libraryPath, {~0, 0}, 5);
libraryLayout.append(libraryBrowse, {80, 0}); libraryLayout.append(libraryBrowse, {80, 0});
if(Intrinsics::platform() != Intrinsics::Platform::OSX) { if(Intrinsics::platform() != Intrinsics::Platform::MacOSX) {
append(spacer, {~0, ~0}); append(spacer, {~0, ~0});
append(infoLabel, {~0, 0}); append(infoLabel, {~0, 0});
} }

View File

@ -203,10 +203,10 @@ void Utility::updateShader() {
video.set(Video::Shader, (const char*)""); video.set(Video::Shader, (const char*)"");
video.set(Video::Filter, Video::FilterLinear); video.set(Video::Filter, Video::FilterLinear);
return; return;
} else if(config->video.shader == "Emulation") { } else if(config->video.shader == "Display Emulation") {
if(program->active) { if(program->active) {
string pathname = program->path("Video Shaders/"); string pathname = program->path("Video Shaders/");
pathname.append("Emulation/"); pathname.append("Display Emulation/");
pathname.append(presentation->systemName, ".shader/"); pathname.append(presentation->systemName, ".shader/");
if(directory::exists(pathname)) { if(directory::exists(pathname)) {
video.set(Video::Shader, (const char*)pathname); video.set(Video::Shader, (const char*)pathname);