mirror of
https://github.com/ares-emulator/ares.git
synced 2026-11-12 14:13:23 -10:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
449a3ad426 | ||
|
|
ccfff86140 | ||
|
|
4525d00eba | ||
|
|
d0d8c2a921 | ||
|
|
8a91c95002 | ||
|
|
9484d1bc92 | ||
|
|
4163059b21 | ||
|
|
697f23d45c | ||
|
|
b671e49644 | ||
|
|
92ab697f8c | ||
|
|
4147dc42d0 | ||
|
|
05fca49b11 | ||
|
|
3a81ac94a5 | ||
|
|
3f43747474 | ||
|
|
5b4702afc4 | ||
|
|
7df9157abd | ||
|
|
f1009ec634 | ||
|
|
0bf6c40d1f | ||
|
|
2bafd18a5a | ||
|
|
c434e8a0d5 | ||
|
|
39b1acb177 | ||
|
|
920d139302 | ||
|
|
a59ecb3dd4 | ||
|
|
7b039b712e | ||
|
|
8d8bfe9e7e | ||
|
|
3c2ca5a383 | ||
|
|
b16fe19793 | ||
|
|
70429285ba | ||
|
|
cda10094da | ||
|
|
3c3956744f | ||
|
|
1a32ed7cfa | ||
|
|
fa0f1c1e98 | ||
|
|
9000bb4084 | ||
|
|
973ef89d4a | ||
|
|
94675634c1 | ||
|
|
b85025263a | ||
|
|
165f1e74b5 |
No files matched your search
BIN
Binary file not shown.
BIN
Binary file not shown.
Binary file not shown.
Executable
+93
@@ -0,0 +1,93 @@
|
||||
include nall/Makefile
|
||||
snes := snes
|
||||
profile := compatibility
|
||||
ui := ui-qt
|
||||
|
||||
# compiler
|
||||
c := $(compiler) -std=gnu99
|
||||
cpp := $(subst cc,++,$(compiler)) -std=gnu++0x
|
||||
flags := -O3 -fomit-frame-pointer -I. -I$(snes)
|
||||
link :=
|
||||
objects :=
|
||||
|
||||
# profile-guided instrumentation
|
||||
# flags += -fprofile-generate
|
||||
# link += -lgcov
|
||||
|
||||
# profile-guided optimization
|
||||
# flags += -fprofile-use
|
||||
|
||||
# platform
|
||||
ifeq ($(platform),x)
|
||||
link += -s -ldl -lX11 -lXext
|
||||
else ifeq ($(platform),osx)
|
||||
else ifeq ($(platform),win)
|
||||
link += -mwindows
|
||||
# link += -mconsole
|
||||
link += -mthreads -s -luuid -lkernel32 -luser32 -lgdi32 -lcomctl32 -lcomdlg32 -lshell32 -lole32
|
||||
link += -enable-stdcall-fixup -Wl,-enable-auto-import -Wl,-enable-runtime-pseudo-reloc
|
||||
else
|
||||
unknown_platform: help;
|
||||
endif
|
||||
|
||||
# implicit rules
|
||||
compile = \
|
||||
$(strip \
|
||||
$(if $(filter %.c,$<), \
|
||||
$(c) $(flags) $1 -c $< -o $@, \
|
||||
$(if $(filter %.cpp,$<), \
|
||||
$(cpp) $(flags) $1 -c $< -o $@ \
|
||||
) \
|
||||
) \
|
||||
)
|
||||
|
||||
%.o: $<; $(call compile)
|
||||
|
||||
all: build;
|
||||
|
||||
include $(snes)/Makefile
|
||||
include $(ui)/Makefile
|
||||
|
||||
objects := $(patsubst %,obj/%.o,$(objects))
|
||||
|
||||
# targets
|
||||
build: ui_build $(objects)
|
||||
ifeq ($(platform),osx)
|
||||
test -d ../bsnes.app || mkdir -p ../bsnes.app/Contents/MacOS
|
||||
$(strip $(cpp) -o ../bsnes.app/Contents/MacOS/bsnes $(objects) $(link))
|
||||
else
|
||||
$(strip $(cpp) -o out/bsnes $(objects) $(link))
|
||||
endif
|
||||
|
||||
install:
|
||||
ifeq ($(platform),x)
|
||||
install -D -m 755 out/bsnes $(DESTDIR)$(prefix)/bin/bsnes
|
||||
install -D -m 644 ui-qt/data/bsnes.png $(DESTDIR)$(prefix)/share/pixmaps/bsnes.png
|
||||
install -D -m 644 ui-qt/data/bsnes.desktop $(DESTDIR)$(prefix)/share/applications/bsnes.desktop
|
||||
gconftool-2 --type bool --set /desktop/gnome/interface/menus_have_icons true
|
||||
endif
|
||||
|
||||
uninstall:
|
||||
ifeq ($(platform),x)
|
||||
rm $(DESTDIR)$(prefix)/bin/bsnes
|
||||
rm $(DESTDIR)$(prefix)/share/pixmaps/bsnes.png
|
||||
rm $(DESTDIR)$(prefix)/share/applications/bsnes.desktop
|
||||
endif
|
||||
|
||||
clean: ui_clean
|
||||
-@$(call delete,obj/*.o)
|
||||
-@$(call delete,obj/*.a)
|
||||
-@$(call delete,obj/*.so)
|
||||
-@$(call delete,obj/*.dylib)
|
||||
-@$(call delete,obj/*.dll)
|
||||
-@$(call delete,*.res)
|
||||
-@$(call delete,*.pgd)
|
||||
-@$(call delete,*.pgc)
|
||||
-@$(call delete,*.ilk)
|
||||
-@$(call delete,*.pdb)
|
||||
-@$(call delete,*.manifest)
|
||||
|
||||
archive-all:
|
||||
tar -cjf bsnes.tar.bz2 launcher libco nall obj out phoenix ruby snes ui-phoenix ui-qt Makefile cc.bat clean.bat sync.sh
|
||||
|
||||
help:;
|
||||
Executable
+2
@@ -0,0 +1,2 @@
|
||||
@mingw32-make -j 2
|
||||
@pause
|
||||
Regular → Executable
+1
-1
@@ -1 +1 @@
|
||||
@mingw32-make clean
|
||||
@mingw32-make clean
|
||||
Regular → Executable
File renamed without changes.
Regular → Executable
File renamed without changes.
|
Before Width: | Height: | Size: 22 KiB After Width: | Height: | Size: 22 KiB |
Executable
+4
@@ -0,0 +1,4 @@
|
||||
@windres resource.rc resource.o
|
||||
@mingw32-g++ -std=gnu++0x -mwindows -s -O3 -fomit-frame-pointer -I.. -o ../out/bsnes launcher.cpp resource.o
|
||||
@del *.o
|
||||
@pause
|
||||
Executable
+2
@@ -0,0 +1,2 @@
|
||||
clear
|
||||
g++ -std=gnu++0x -s -O3 -fomit-frame-pointer -I.. -o ../out/bsnes launcher.cpp
|
||||
Executable
+54
@@ -0,0 +1,54 @@
|
||||
#include <nall/config.hpp>
|
||||
#include <nall/detect.hpp>
|
||||
#include <nall/file.hpp>
|
||||
#include <nall/foreach.hpp>
|
||||
#include <nall/platform.hpp>
|
||||
#include <nall/stdint.hpp>
|
||||
#include <nall/string.hpp>
|
||||
using namespace nall;
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
char path[PATH_MAX], *unused;
|
||||
#if !defined(PLATFORM_WIN)
|
||||
unused = realpath(argv[0], path);
|
||||
#else
|
||||
wchar_t **argw = CommandLineToArgvW(GetCommandLineW(), &argc);
|
||||
unused = realpath(nall::utf8_t(argw[0]), path);
|
||||
#endif
|
||||
string realPath = dir(path);
|
||||
string basePath = string(dir(path), "bsnes-qt.cfg");
|
||||
unused = userpath(path);
|
||||
if(!strend(path, "/") && !strend(path, "\\")) strcat(path, "/");
|
||||
string userPath = string(path, ".bsnes/bsnes-qt.cfg");
|
||||
|
||||
configuration config;
|
||||
string profile;
|
||||
config.attach(profile = "", "system.profile");
|
||||
if(config.load(userPath) == false) config.load(basePath);
|
||||
if(profile == "") profile = "compatibility";
|
||||
|
||||
string binaryName = string("bsnes-", profile);
|
||||
#if defined(PLATFORM_WIN)
|
||||
binaryName << ".dll";
|
||||
#endif
|
||||
string fileName = string(realPath, binaryName);
|
||||
|
||||
#if !defined(PLATFORM_WIN)
|
||||
char **args = new char*[argc + 1];
|
||||
args[0] = strdup(binaryName);
|
||||
for(unsigned i = 1; i < argc; i++) args[i] = strdup(argv[i]);
|
||||
args[argc] = 0;
|
||||
execvp(args[0], args);
|
||||
execv(fileName, args);
|
||||
print("[bsnes] Error: unable to locate binary file: ", binaryName, "\n");
|
||||
#else
|
||||
STARTUPINFOW si;
|
||||
PROCESS_INFORMATION pi;
|
||||
memset(&si, 0, sizeof(STARTUPINFOW));
|
||||
if(!CreateProcessW(nall::utf16_t(fileName), GetCommandLineW(), NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi)) {
|
||||
MessageBoxA(0, string("Error: unable to locate binary file: ", binaryName), "bsnes", MB_OK);
|
||||
}
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
Executable
+2
@@ -0,0 +1,2 @@
|
||||
1 24 "bsnes.Manifest"
|
||||
IDI_ICON1 ICON DISCARDABLE "bsnes.ico"
|
||||
Regular → Executable
File renamed without changes.
Regular → Executable
File renamed without changes.
Regular → Executable
File renamed without changes.
Regular → Executable
File renamed without changes.
Regular → Executable
File renamed without changes.
Regular → Executable
File renamed without changes.
Regular → Executable
File renamed without changes.
Regular → Executable
File renamed without changes.
Regular → Executable
File renamed without changes.
Regular → Executable
File renamed without changes.
Regular → Executable
+4
-2
@@ -29,8 +29,10 @@ ifeq ($(platform),)
|
||||
endif
|
||||
|
||||
ifeq ($(compiler),)
|
||||
ifeq ($(platform),osx)
|
||||
compiler := gcc-4.2
|
||||
ifeq ($(platform),win)
|
||||
compiler := gcc
|
||||
else ifeq ($(platform),osx)
|
||||
compiler := gcc-mp-4.4
|
||||
else
|
||||
compiler := gcc
|
||||
endif
|
||||
Regular → Executable
-6
@@ -12,12 +12,6 @@ namespace nall {
|
||||
template<typename T, typename U> T max(const T &t, const U &u) {
|
||||
return t > u ? t : u;
|
||||
}
|
||||
|
||||
//pseudo-random number generator
|
||||
inline unsigned prng() {
|
||||
static unsigned n = 0;
|
||||
return n = (n >> 1) ^ (((n & 1) - 1) & 0xedb88320);
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
Regular → Executable
+5
-5
@@ -2,8 +2,8 @@
|
||||
#define NALL_ANY_HPP
|
||||
|
||||
#include <typeinfo>
|
||||
#include <type_traits>
|
||||
#include <nall/static.hpp>
|
||||
#include <nall/traits.hpp>
|
||||
|
||||
namespace nall {
|
||||
class any {
|
||||
@@ -13,8 +13,8 @@ namespace nall {
|
||||
|
||||
template<typename T> any& operator=(const T& value_) {
|
||||
typedef typename static_if<
|
||||
is_array<T>::value,
|
||||
typename remove_extent<typename add_const<T>::type>::type*,
|
||||
std::is_array<T>::value,
|
||||
typename std::remove_extent<typename std::add_const<T>::type>::type*,
|
||||
T
|
||||
>::type auto_t;
|
||||
|
||||
@@ -49,13 +49,13 @@ namespace nall {
|
||||
};
|
||||
|
||||
template<typename T> T any_cast(any &value) {
|
||||
typedef typename remove_reference<T>::type nonref;
|
||||
typedef typename std::remove_reference<T>::type nonref;
|
||||
if(value.type() != typeid(nonref)) throw;
|
||||
return static_cast<any::holder<nonref>*>(value.container)->value;
|
||||
}
|
||||
|
||||
template<typename T> T any_cast(const any &value) {
|
||||
typedef const typename remove_reference<T>::type nonref;
|
||||
typedef const typename std::remove_reference<T>::type nonref;
|
||||
if(value.type() != typeid(nonref)) throw;
|
||||
return static_cast<any::holder<nonref>*>(value.container)->value;
|
||||
}
|
||||
Regular → Executable
+32
-9
@@ -3,10 +3,13 @@
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <initializer_list>
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
#include <nall/algorithm.hpp>
|
||||
#include <nall/bit.hpp>
|
||||
#include <nall/concept.hpp>
|
||||
#include <nall/traits.hpp>
|
||||
#include <nall/foreach.hpp>
|
||||
#include <nall/utility.hpp>
|
||||
|
||||
namespace nall {
|
||||
//dynamic vector array
|
||||
@@ -47,13 +50,32 @@ namespace nall {
|
||||
return pool;
|
||||
}
|
||||
|
||||
void add(const T data) {
|
||||
void append(const T data) {
|
||||
operator[](buffersize) = data;
|
||||
}
|
||||
|
||||
signed find(const T data) {
|
||||
for(unsigned i = 0; i < size(); i++) if(pool[i] == data) return i;
|
||||
return -1; //not found
|
||||
template<typename U> void insert(unsigned index, const U list) {
|
||||
unsigned listsize = container_size(list);
|
||||
resize(buffersize + listsize);
|
||||
memmove(pool + index + listsize, pool + index, (buffersize - index) * sizeof(T));
|
||||
foreach(item, list) pool[index++] = item;
|
||||
}
|
||||
|
||||
void insert(unsigned index, const T item) {
|
||||
insert(index, array<T>{ item });
|
||||
}
|
||||
|
||||
void remove(unsigned index, unsigned count = 1) {
|
||||
for(unsigned i = index; count + i < buffersize; i++) {
|
||||
pool[i] = pool[count + i];
|
||||
}
|
||||
if(count + index >= buffersize) resize(index); //every element >= index was removed
|
||||
else resize(buffersize - count);
|
||||
}
|
||||
|
||||
optional<unsigned> find(const T data) {
|
||||
for(unsigned i = 0; i < size(); i++) if(pool[i] == data) return { true, i };
|
||||
return { false, 0 };
|
||||
}
|
||||
|
||||
void clear() {
|
||||
@@ -64,7 +86,7 @@ namespace nall {
|
||||
}
|
||||
|
||||
array(std::initializer_list<T> list) : pool(0), poolsize(0), buffersize(0) {
|
||||
for(const T *p = list.begin(); p != list.end(); ++p) add(*p);
|
||||
for(const T *p = list.begin(); p != list.end(); ++p) append(*p);
|
||||
}
|
||||
|
||||
~array() {
|
||||
@@ -81,7 +103,7 @@ namespace nall {
|
||||
return *this;
|
||||
}
|
||||
|
||||
array(const array &source) : pool(0) {
|
||||
array(const array &source) : pool(0), poolsize(0), buffersize(0) {
|
||||
operator=(source);
|
||||
}
|
||||
|
||||
@@ -92,11 +114,12 @@ namespace nall {
|
||||
poolsize = source.poolsize;
|
||||
buffersize = source.buffersize;
|
||||
source.pool = 0;
|
||||
source.reset();
|
||||
return *this;
|
||||
}
|
||||
|
||||
array(array &&source) {
|
||||
operator=(move(source));
|
||||
array(array &&source) : pool(0), poolsize(0), buffersize(0) {
|
||||
operator=(std::move(source));
|
||||
}
|
||||
|
||||
//index
|
||||
Regular → Executable
File renamed without changes.
Regular → Executable
File renamed without changes.
Executable
+34
@@ -0,0 +1,34 @@
|
||||
#ifndef NALL_CONCEPT_HPP
|
||||
#define NALL_CONCEPT_HPP
|
||||
|
||||
#include <nall/static.hpp>
|
||||
#include <nall/utility.hpp>
|
||||
|
||||
namespace nall {
|
||||
//unsigned count() const;
|
||||
template<typename T> struct has_count { enum { value = false }; };
|
||||
|
||||
//unsigned length() const;
|
||||
template<typename T> struct has_length { enum { value = false }; };
|
||||
|
||||
//unsigned size() const;
|
||||
template<typename T> struct has_size { enum { value = false }; };
|
||||
|
||||
template<typename T> unsigned container_size(const T& object, typename mp_enable_if<has_count<T>>::type = 0) {
|
||||
return object.count();
|
||||
}
|
||||
|
||||
template<typename T> unsigned container_size(const T& object, typename mp_enable_if<has_length<T>>::type = 0) {
|
||||
return object.length();
|
||||
}
|
||||
|
||||
template<typename T> unsigned container_size(const T& object, typename mp_enable_if<has_size<T>>::type = 0) {
|
||||
return object.size();
|
||||
}
|
||||
|
||||
template<typename T> unsigned container_size(const T& object, typename mp_enable_if<std::is_array<T>>::type = 0) {
|
||||
return sizeof(T) / sizeof(typename std::remove_extent<T>::type);
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
Regular → Executable
+5
-6
@@ -49,7 +49,7 @@ namespace nall {
|
||||
case signed_t: *(signed*)data = strsigned(s); break;
|
||||
case unsigned_t: *(unsigned*)data = strunsigned(s); break;
|
||||
case double_t: *(double*)data = strdouble(s); break;
|
||||
case string_t: trim(s, "\""); *(string*)data = s; break;
|
||||
case string_t: s.trim("\""); *(string*)data = s; break;
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -78,14 +78,13 @@ namespace nall {
|
||||
line.split("\n", data);
|
||||
|
||||
for(unsigned i = 0; i < line.size(); i++) {
|
||||
int position = qstrpos(line[i], "#");
|
||||
if(position >= 0) line[i][position] = 0;
|
||||
if(qstrpos(line[i], " = ") < 0) continue;
|
||||
if(auto position = qstrpos(line[i], "#")) line[i][position()] = 0;
|
||||
if(!qstrpos(line[i], " = ")) continue;
|
||||
|
||||
lstring part;
|
||||
part.qsplit(" = ", line[i]);
|
||||
trim(part[0]);
|
||||
trim(part[1]);
|
||||
part[0].trim();
|
||||
part[1].trim();
|
||||
|
||||
for(unsigned n = 0; n < list.size(); n++) {
|
||||
if(part[0] == list[n].name) {
|
||||
Regular → Executable
File renamed without changes.
Regular → Executable
File renamed without changes.
Regular → Executable
+7
-8
@@ -15,9 +15,8 @@ namespace nall {
|
||||
|
||||
//no match, use input; remove input identifier, if one exists
|
||||
if(strbegin(input, "{{")) {
|
||||
int pos = strpos(input, "}}");
|
||||
if(pos >= 0) {
|
||||
string temp = substr(input, pos + 2);
|
||||
if(auto pos = strpos(input, "}}")) {
|
||||
string temp = substr(input, pos() + 2);
|
||||
return temp;
|
||||
}
|
||||
}
|
||||
@@ -28,7 +27,7 @@ namespace nall {
|
||||
bool import(const char *filename) {
|
||||
string data;
|
||||
if(data.readfile(filename) == false) return false;
|
||||
ltrim_once(data, "\xef\xbb\xbf"); //remove UTF-8 marker, if it exists
|
||||
data.ltrim_once("\xef\xbb\xbf"); //remove UTF-8 marker, if it exists
|
||||
data.replace("\r", "");
|
||||
|
||||
lstring line;
|
||||
@@ -40,12 +39,12 @@ namespace nall {
|
||||
if(part.size() != 2) continue;
|
||||
|
||||
//remove whitespace
|
||||
trim(part[0]);
|
||||
trim(part[1]);
|
||||
part[0].trim();
|
||||
part[1].trim();
|
||||
|
||||
//remove quotes
|
||||
trim_once(part[0], "\"");
|
||||
trim_once(part[1], "\"");
|
||||
part[0].trim_once("\"");
|
||||
part[1].trim_once("\"");
|
||||
|
||||
unsigned n = index_input.size();
|
||||
index_input[n] = part[0];
|
||||
Executable
+129
@@ -0,0 +1,129 @@
|
||||
#ifndef NALL_DIRECTORY_HPP
|
||||
#define NALL_DIRECTORY_HPP
|
||||
|
||||
#include <nall/foreach.hpp>
|
||||
#include <nall/sort.hpp>
|
||||
#include <nall/string.hpp>
|
||||
|
||||
#if defined(_WIN32)
|
||||
#include <nall/utf8.hpp>
|
||||
#else
|
||||
#include <dirent.h>
|
||||
#include <stdio.h>
|
||||
#include <sys/types.h>
|
||||
#endif
|
||||
|
||||
namespace nall {
|
||||
|
||||
struct directory {
|
||||
static lstring folders(const char *pathname);
|
||||
static lstring files(const char *pathname);
|
||||
static lstring contents(const char *pathname);
|
||||
};
|
||||
|
||||
#if defined(_WIN32)
|
||||
inline lstring directory::folders(const char *pathname) {
|
||||
lstring list;
|
||||
string path = pathname;
|
||||
path.transform("/", "\\");
|
||||
if(!strend(path, "\\")) path.append("\\");
|
||||
path.append("*");
|
||||
HANDLE handle;
|
||||
WIN32_FIND_DATA data;
|
||||
handle = FindFirstFile(utf16_t(path), &data);
|
||||
if(handle != INVALID_HANDLE_VALUE) {
|
||||
if(wcscmp(data.cFileName, L".") && wcscmp(data.cFileName, L"..")) {
|
||||
if(data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
|
||||
list.append(string(utf8_t(data.cFileName), "/"));
|
||||
}
|
||||
}
|
||||
while(FindNextFile(handle, &data) != false) {
|
||||
if(wcscmp(data.cFileName, L".") && wcscmp(data.cFileName, L"..")) {
|
||||
if(data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
|
||||
list.append(string(utf8_t(data.cFileName), "/"));
|
||||
}
|
||||
}
|
||||
}
|
||||
FindClose(handle);
|
||||
}
|
||||
sort(&list[0], list.size());
|
||||
return list;
|
||||
}
|
||||
|
||||
inline lstring directory::files(const char *pathname) {
|
||||
lstring list;
|
||||
string path = pathname;
|
||||
path.transform("/", "\\");
|
||||
if(!strend(path, "\\")) path.append("\\");
|
||||
path.append("*");
|
||||
HANDLE handle;
|
||||
WIN32_FIND_DATA data;
|
||||
handle = FindFirstFile(utf16_t(path), &data);
|
||||
if(handle != INVALID_HANDLE_VALUE) {
|
||||
if((data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == 0) {
|
||||
list.append(utf8_t(data.cFileName));
|
||||
}
|
||||
while(FindNextFile(handle, &data) != false) {
|
||||
if((data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == 0) {
|
||||
list.append(utf8_t(data.cFileName));
|
||||
}
|
||||
}
|
||||
FindClose(handle);
|
||||
}
|
||||
sort(&list[0], list.size());
|
||||
return list;
|
||||
}
|
||||
|
||||
inline lstring directory::contents(const char *pathname) {
|
||||
lstring folders = directory::folders(pathname);
|
||||
lstring files = directory::files(pathname);
|
||||
foreach(file, files) folders.append(file);
|
||||
return folders;
|
||||
}
|
||||
#else
|
||||
inline lstring directory::folders(const char *pathname) {
|
||||
lstring list;
|
||||
DIR *dp;
|
||||
struct dirent *ep;
|
||||
dp = opendir(pathname);
|
||||
if(dp) {
|
||||
while(ep = readdir(dp)) {
|
||||
if(!strcmp(ep->d_name, ".")) continue;
|
||||
if(!strcmp(ep->d_name, "..")) continue;
|
||||
if(ep->d_type & DT_DIR) list.append(string(ep->d_name, "/"));
|
||||
}
|
||||
closedir(dp);
|
||||
}
|
||||
sort(&list[0], list.size());
|
||||
return list;
|
||||
|
||||
}
|
||||
|
||||
inline lstring directory::files(const char *pathname) {
|
||||
lstring list;
|
||||
DIR *dp;
|
||||
struct dirent *ep;
|
||||
dp = opendir(pathname);
|
||||
if(dp) {
|
||||
while(ep = readdir(dp)) {
|
||||
if(!strcmp(ep->d_name, ".")) continue;
|
||||
if(!strcmp(ep->d_name, "..")) continue;
|
||||
if((ep->d_type & DT_DIR) == 0) list.append(ep->d_name);
|
||||
}
|
||||
closedir(dp);
|
||||
}
|
||||
sort(&list[0], list.size());
|
||||
return list;
|
||||
}
|
||||
|
||||
inline lstring directory::contents(const char *pathname) {
|
||||
lstring folders = directory::folders(pathname);
|
||||
lstring files = directory::files(pathname);
|
||||
foreach(file, files) folders.append(file);
|
||||
return folders;
|
||||
}
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
Regular → Executable
+12
-35
@@ -3,9 +3,9 @@
|
||||
|
||||
//dynamic linking support
|
||||
|
||||
#include <string.h>
|
||||
#include <nall/detect.hpp>
|
||||
#include <nall/stdint.hpp>
|
||||
#include <nall/string.hpp>
|
||||
#include <nall/utility.hpp>
|
||||
|
||||
#if defined(PLATFORM_X) || defined(PLATFORM_OSX)
|
||||
@@ -18,7 +18,7 @@
|
||||
namespace nall {
|
||||
struct library {
|
||||
bool opened() const { return handle; }
|
||||
bool open(const char*);
|
||||
bool open(const char*, const char* = "");
|
||||
void* sym(const char*);
|
||||
void close();
|
||||
|
||||
@@ -33,20 +33,10 @@ namespace nall {
|
||||
};
|
||||
|
||||
#if defined(PLATFORM_X)
|
||||
inline bool library::open(const char *name) {
|
||||
inline bool library::open(const char *name, const char *path) {
|
||||
if(handle) close();
|
||||
char *t = new char[strlen(name) + 256];
|
||||
strcpy(t, "lib");
|
||||
strcat(t, name);
|
||||
strcat(t, ".so");
|
||||
handle = (uintptr_t)dlopen(t, RTLD_LAZY);
|
||||
if(!handle) {
|
||||
strcpy(t, "/usr/local/lib/lib");
|
||||
strcat(t, name);
|
||||
strcat(t, ".so");
|
||||
handle = (uintptr_t)dlopen(t, RTLD_LAZY);
|
||||
}
|
||||
delete[] t;
|
||||
handle = (uintptr_t)dlopen(string(path, *path && !strend(path, "/") ? "/" : "", "lib", name, ".so"), RTLD_LAZY);
|
||||
if(!handle) handle = (uintptr_t)dlopen(string("/usr/local/lib/lib", name, ".so"), RTLD_LAZY);
|
||||
return handle;
|
||||
}
|
||||
|
||||
@@ -61,20 +51,10 @@ namespace nall {
|
||||
handle = 0;
|
||||
}
|
||||
#elif defined(PLATFORM_OSX)
|
||||
inline bool library::open(const char *name) {
|
||||
inline bool library::open(const char *name, const char *path) {
|
||||
if(handle) close();
|
||||
char *t = new char[strlen(name) + 256];
|
||||
strcpy(t, "lib");
|
||||
strcat(t, name);
|
||||
strcat(t, ".dylib");
|
||||
handle = (uintptr_t)dlopen(t, RTLD_LAZY);
|
||||
if(!handle) {
|
||||
strcpy(t, "/usr/local/lib/lib");
|
||||
strcat(t, name);
|
||||
strcat(t, ".dylib");
|
||||
handle = (uintptr_t)dlopen(t, RTLD_LAZY);
|
||||
}
|
||||
delete[] t;
|
||||
handle = (uintptr_t)dlopen(string(path, *path && !strend(path, "/") ? "/" : "", "lib", name, ".dylib"), RTLD_LAZY);
|
||||
if(!handle) handle = (uintptr_t)dlopen(string("/usr/local/lib/lib", name, ".dylib"), RTLD_LAZY);
|
||||
return handle;
|
||||
}
|
||||
|
||||
@@ -89,13 +69,10 @@ namespace nall {
|
||||
handle = 0;
|
||||
}
|
||||
#elif defined(PLATFORM_WIN)
|
||||
inline bool library::open(const char *name) {
|
||||
inline bool library::open(const char *name, const char *path) {
|
||||
if(handle) close();
|
||||
char *t = new char[strlen(name) + 8];
|
||||
strcpy(t, name);
|
||||
strcat(t, ".dll");
|
||||
handle = (uintptr_t)LoadLibraryW(utf16_t(t));
|
||||
delete[] t;
|
||||
string filepath(path, *path && !strend(path, "/") && !strend(path, "\\") ? "\\" : "", name, ".dll");
|
||||
handle = (uintptr_t)LoadLibraryW(utf16_t(filepath));
|
||||
return handle;
|
||||
}
|
||||
|
||||
@@ -110,7 +87,7 @@ namespace nall {
|
||||
handle = 0;
|
||||
}
|
||||
#else
|
||||
inline bool library::open(const char*) { return false; }
|
||||
inline bool library::open(const char*, const char*) { return false; }
|
||||
inline void* library::sym(const char*) { return 0; }
|
||||
inline void library::close() {}
|
||||
#endif
|
||||
Regular → Executable
File renamed without changes.
Regular → Executable
+5
-3
@@ -11,6 +11,7 @@
|
||||
#endif
|
||||
|
||||
#include <nall/stdint.hpp>
|
||||
#include <nall/string.hpp>
|
||||
#include <nall/utf8.hpp>
|
||||
#include <nall/utility.hpp>
|
||||
|
||||
@@ -83,9 +84,10 @@ namespace nall {
|
||||
while(length--) write(*buffer++);
|
||||
}
|
||||
|
||||
void print(const char *string) {
|
||||
if(!string) return;
|
||||
while(*string) write(*string++);
|
||||
template<typename... Args> void print(Args... args) {
|
||||
string data(args...);
|
||||
const char *p = data;
|
||||
while(*p) write(*p++);
|
||||
}
|
||||
|
||||
void flush() {
|
||||
Regular → Executable
File renamed without changes.
Executable
+12
@@ -0,0 +1,12 @@
|
||||
#ifndef NALL_FOREACH_HPP
|
||||
#define NALL_FOREACH_HPP
|
||||
|
||||
#include <type_traits>
|
||||
#include <nall/concept.hpp>
|
||||
|
||||
#undef foreach
|
||||
#define foreach(iter, object) \
|
||||
for(unsigned foreach_counter = 0, foreach_limit = container_size(object), foreach_once = 0, foreach_broken = 0; foreach_counter < foreach_limit && foreach_broken == 0; foreach_counter++, foreach_once = 0) \
|
||||
for(auto &iter = object[foreach_counter]; foreach_once == 0 && (foreach_broken = 1); foreach_once++, foreach_broken = 0)
|
||||
|
||||
#endif
|
||||
Executable
+91
@@ -0,0 +1,91 @@
|
||||
#ifndef NALL_FUNCTION_HPP
|
||||
#define NALL_FUNCTION_HPP
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <functional>
|
||||
#include <type_traits>
|
||||
|
||||
namespace nall {
|
||||
template<typename T> class function;
|
||||
|
||||
template<typename R, typename... P>
|
||||
class function<R (P...)> {
|
||||
private:
|
||||
struct base1 { virtual void func1(P...) {} };
|
||||
struct base2 { virtual void func2(P...) {} };
|
||||
struct derived : base1, virtual base2 {};
|
||||
|
||||
struct data_t {
|
||||
R (*callback)(const data_t&, P...);
|
||||
union {
|
||||
R (*callback_global)(P...);
|
||||
struct {
|
||||
R (derived::*callback_member)(P...);
|
||||
void *object;
|
||||
};
|
||||
};
|
||||
} data;
|
||||
|
||||
static R callback_global(const data_t &data, P... p) {
|
||||
return data.callback_global(p...);
|
||||
}
|
||||
|
||||
template<typename C>
|
||||
static R callback_member(const data_t &data, P... p) {
|
||||
return (((C*)data.object)->*((R (C::*&)(P...))data.callback_member))(p...);
|
||||
}
|
||||
|
||||
public:
|
||||
R operator()(P... p) const { return data.callback(data, p...); }
|
||||
operator bool() const { return data.callback; }
|
||||
void reset() { data.callback = 0; }
|
||||
|
||||
function& operator=(const function &source) { memcpy(&data, &source.data, sizeof(data_t)); return *this; }
|
||||
function(const function &source) { operator=(source); }
|
||||
|
||||
//no pointer
|
||||
function() {
|
||||
data.callback = 0;
|
||||
}
|
||||
|
||||
//symbolic link pointer (nall/dl.hpp::sym, etc)
|
||||
function(void *callback) {
|
||||
data.callback = callback ? &callback_global : 0;
|
||||
data.callback_global = (R (*)(P...))callback;
|
||||
}
|
||||
|
||||
//global function pointer
|
||||
function(R (*callback)(P...)) {
|
||||
data.callback = &callback_global;
|
||||
data.callback_global = callback;
|
||||
}
|
||||
|
||||
//member function pointer
|
||||
template<typename C>
|
||||
function(R (C::*callback)(P...), C *object) {
|
||||
static_assert(sizeof data.callback_member >= sizeof callback, "callback_member is too small");
|
||||
data.callback = &callback_member<C>;
|
||||
(R (C::*&)(P...))data.callback_member = callback;
|
||||
data.object = object;
|
||||
}
|
||||
|
||||
//const member function pointer
|
||||
template<typename C>
|
||||
function(R (C::*callback)(P...) const, C *object) {
|
||||
static_assert(sizeof data.callback_member >= sizeof callback, "callback_member is too small");
|
||||
data.callback = &callback_member<C>;
|
||||
(R (C::*&)(P...))data.callback_member = (R (C::*&)(P...))callback;
|
||||
data.object = object;
|
||||
}
|
||||
|
||||
//lambda function pointer
|
||||
template<typename T>
|
||||
function(T callback) {
|
||||
static_assert(std::is_same<R, typename std::result_of<T(P...)>::type>::value, "lambda mismatch");
|
||||
data.callback = &callback_global;
|
||||
data.callback_global = (R (*)(P...))callback;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
Regular → Executable
+12
-12
@@ -91,11 +91,11 @@ struct Keyboard {
|
||||
static uint16_t decode(const char *name) {
|
||||
string s(name);
|
||||
if(!strbegin(name, "KB")) return 0;
|
||||
ltrim(s, "KB");
|
||||
s.ltrim("KB");
|
||||
unsigned id = strunsigned(s);
|
||||
int pos = strpos(s, "::");
|
||||
if(pos < 0) return 0;
|
||||
s = substr(s, pos + 2);
|
||||
auto pos = strpos(s, "::");
|
||||
if(!pos) return 0;
|
||||
s = substr(s, pos() + 2);
|
||||
for(unsigned i = 0; i < Limit; i++) {
|
||||
if(s == KeyboardScancodeName[i]) return Base + Size * id + i;
|
||||
}
|
||||
@@ -188,11 +188,11 @@ struct Mouse {
|
||||
static uint16_t decode(const char *name) {
|
||||
string s(name);
|
||||
if(!strbegin(name, "MS")) return 0;
|
||||
ltrim(s, "MS");
|
||||
s.ltrim("MS");
|
||||
unsigned id = strunsigned(s);
|
||||
int pos = strpos(s, "::");
|
||||
if(pos < 0) return 0;
|
||||
s = substr(s, pos + 2);
|
||||
auto pos = strpos(s, "::");
|
||||
if(!pos) return 0;
|
||||
s = substr(s, pos() + 2);
|
||||
for(unsigned i = 0; i < Limit; i++) {
|
||||
if(s == MouseScancodeName[i]) return Base + Size * id + i;
|
||||
}
|
||||
@@ -312,11 +312,11 @@ struct Joypad {
|
||||
static uint16_t decode(const char *name) {
|
||||
string s(name);
|
||||
if(!strbegin(name, "JP")) return 0;
|
||||
ltrim(s, "JP");
|
||||
s.ltrim("JP");
|
||||
unsigned id = strunsigned(s);
|
||||
int pos = strpos(s, "::");
|
||||
if(pos < 0) return 0;
|
||||
s = substr(s, pos + 2);
|
||||
auto pos = strpos(s, "::");
|
||||
if(!pos) return 0;
|
||||
s = substr(s, pos() + 2);
|
||||
for(unsigned i = 0; i < Limit; i++) {
|
||||
if(s == JoypadScancodeName[i]) return Base + Size * id + i;
|
||||
}
|
||||
Regular → Executable
File renamed without changes.
Regular → Executable
File renamed without changes.
Regular → Executable
+42
@@ -23,10 +23,12 @@
|
||||
#include <direct.h>
|
||||
#include <shlobj.h>
|
||||
#undef interface
|
||||
#define dllexport __declspec(dllexport)
|
||||
#else
|
||||
#include <unistd.h>
|
||||
#include <pwd.h>
|
||||
#include <sys/stat.h>
|
||||
#define dllexport
|
||||
#endif
|
||||
|
||||
//==================
|
||||
@@ -76,5 +78,45 @@
|
||||
#define alwaysinline inline
|
||||
#endif
|
||||
|
||||
//=========================
|
||||
//file system functionality
|
||||
//=========================
|
||||
|
||||
#if defined(_WIN32)
|
||||
inline char* realpath(const char *filename, char *resolvedname) {
|
||||
wchar_t fn[_MAX_PATH] = L"";
|
||||
_wfullpath(fn, nall::utf16_t(filename), _MAX_PATH);
|
||||
strcpy(resolvedname, nall::utf8_t(fn));
|
||||
return resolvedname;
|
||||
}
|
||||
|
||||
inline char* userpath(char *path) {
|
||||
wchar_t fp[_MAX_PATH] = L"";
|
||||
SHGetFolderPathW(0, CSIDL_APPDATA | CSIDL_FLAG_CREATE, 0, 0, fp);
|
||||
strcpy(path, nall::utf8_t(fp));
|
||||
return path;
|
||||
}
|
||||
|
||||
inline char* getcwd(char *path) {
|
||||
wchar_t fp[_MAX_PATH] = L"";
|
||||
_wgetcwd(fp, _MAX_PATH);
|
||||
strcpy(path, nall::utf8_t(fp));
|
||||
return path;
|
||||
}
|
||||
#else
|
||||
//realpath() already exists
|
||||
|
||||
inline char* userpath(char *path) {
|
||||
*path = 0;
|
||||
struct passwd *userinfo = getpwuid(getuid());
|
||||
if(userinfo) strcpy(path, userinfo->pw_dir);
|
||||
return path;
|
||||
}
|
||||
|
||||
inline char *getcwd(char *path) {
|
||||
return getcwd(path, PATH_MAX);
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
Regular → Executable
File renamed without changes.
Regular → Executable
File renamed without changes.
Regular → Executable
File renamed without changes.
Regular → Executable
File renamed without changes.
Regular → Executable
File renamed without changes.
Regular → Executable
+4
-4
@@ -211,9 +211,9 @@ inline void FileDialog::filterBoxChanged() {
|
||||
if(filters.length() == 0) {
|
||||
fileSystemModel->setNameFilters(QStringList() << "*");
|
||||
} else {
|
||||
filters = substr(filters, strpos(filters, "("));
|
||||
ltrim(filters, "(");
|
||||
rtrim(filters, ")");
|
||||
filters = substr(filters, strpos(filters, "(")());
|
||||
filters.ltrim("(");
|
||||
filters.rtrim(")");
|
||||
lstring part;
|
||||
part.split(" ", filters);
|
||||
QStringList list;
|
||||
@@ -279,7 +279,7 @@ inline void FileDialog::setNameFilters(const string &filters) {
|
||||
inline void FileDialog::acceptAction() {
|
||||
string path = fileSystemModel->rootPath().toUtf8().constData();
|
||||
path << "/" << notdir(fileNameEdit->text().toUtf8().constData());
|
||||
rtrim(path, "/");
|
||||
path.rtrim("/");
|
||||
if(QDir(path).exists()) {
|
||||
emit accepted(path);
|
||||
setPath(path);
|
||||
Regular → Executable
File renamed without changes.
Regular → Executable
File renamed without changes.
Regular → Executable
File renamed without changes.
Executable
+20
@@ -0,0 +1,20 @@
|
||||
#ifndef NALL_RANDOM_HPP
|
||||
#define NALL_RANDOM_HPP
|
||||
|
||||
namespace nall {
|
||||
//pseudo-random number generator
|
||||
inline unsigned prng() {
|
||||
static unsigned n = 0;
|
||||
return n = (n >> 1) ^ (((n & 1) - 1) & 0xedb88320);
|
||||
}
|
||||
|
||||
struct random_cyclic {
|
||||
unsigned seed;
|
||||
inline unsigned operator()() {
|
||||
return seed = (seed >> 1) ^ (((seed & 1) - 1) & 0xedb88320);
|
||||
}
|
||||
random_cyclic() : seed(0) {}
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
Regular → Executable
+8
-3
@@ -23,7 +23,7 @@ namespace nall {
|
||||
return ::write(port, (void*)data, length);
|
||||
}
|
||||
|
||||
bool open(const char *portname, unsigned rate) {
|
||||
bool open(const char *portname, unsigned rate, bool flowcontrol) {
|
||||
close();
|
||||
|
||||
port = ::open(portname, O_RDWR | O_NOCTTY | O_NDELAY | O_NONBLOCK);
|
||||
@@ -41,8 +41,13 @@ namespace nall {
|
||||
attr.c_iflag &=~ (BRKINT | PARMRK | INPCK | ISTRIP | INLCR | IGNCR | ICRNL | IXON | IXOFF | IXANY);
|
||||
attr.c_iflag |= (IGNBRK | IGNPAR);
|
||||
attr.c_oflag &=~ (OPOST);
|
||||
attr.c_cflag &=~ (CSIZE | CSTOPB | PARENB);
|
||||
attr.c_cflag |= (CS8 | CREAD | CLOCAL);
|
||||
attr.c_cflag &=~ (CSIZE | CSTOPB | PARENB | CLOCAL);
|
||||
attr.c_cflag |= (CS8 | CREAD);
|
||||
if(flowcontrol == false) {
|
||||
attr.c_cflag &= ~CRTSCTS;
|
||||
} else {
|
||||
attr.c_cflag |= CRTSCTS;
|
||||
}
|
||||
attr.c_cc[VTIME] = attr.c_cc[VMIN] = 0;
|
||||
|
||||
if(tcsetattr(port, TCSANOW, &attr) == -1) { close(); return false; }
|
||||
Regular → Executable
+6
-4
@@ -1,8 +1,9 @@
|
||||
#ifndef NALL_SERIALIZER_HPP
|
||||
#define NALL_SERIALIZER_HPP
|
||||
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
#include <nall/stdint.hpp>
|
||||
#include <nall/traits.hpp>
|
||||
#include <nall/utility.hpp>
|
||||
|
||||
namespace nall {
|
||||
@@ -16,6 +17,7 @@ namespace nall {
|
||||
//caveats:
|
||||
//- only plain-old-data can be stored. complex classes must provide serialize(serializer&);
|
||||
//- floating-point usage is not portable across platforms
|
||||
|
||||
class serializer {
|
||||
public:
|
||||
enum mode_t { Load, Save, Size };
|
||||
@@ -51,7 +53,7 @@ namespace nall {
|
||||
}
|
||||
|
||||
template<typename T> void integer(T &value) {
|
||||
enum { size = is_bool<T>::value ? 1 : sizeof(T) };
|
||||
enum { size = std::is_same<bool, T>::value ? 1 : sizeof(T) };
|
||||
if(imode == Save) {
|
||||
for(unsigned n = 0; n < size; n++) idata[isize++] = value >> (n << 3);
|
||||
} else if(imode == Load) {
|
||||
@@ -63,7 +65,7 @@ namespace nall {
|
||||
}
|
||||
|
||||
template<typename T> void array(T &array) {
|
||||
enum { size = sizeof(T) / sizeof(typename remove_extent<T>::type) };
|
||||
enum { size = sizeof(T) / sizeof(typename std::remove_extent<T>::type) };
|
||||
for(unsigned n = 0; n < size; n++) integer(array[n]);
|
||||
}
|
||||
|
||||
@@ -102,7 +104,7 @@ namespace nall {
|
||||
}
|
||||
|
||||
serializer(serializer &&s) {
|
||||
operator=(move(s));
|
||||
operator=(std::move(s));
|
||||
}
|
||||
|
||||
//construction
|
||||
Regular → Executable
File renamed without changes.
Regular → Executable
+168
-54
@@ -1,28 +1,135 @@
|
||||
#include "xml.hpp"
|
||||
XML xml;
|
||||
#ifndef NALL_SNES_INFO_HPP
|
||||
#define NALL_SNES_INFO_HPP
|
||||
|
||||
typedef uint8_t uint8;
|
||||
typedef uint16_t uint16;
|
||||
typedef uint32_t uint32;
|
||||
typedef uint64_t uint64;
|
||||
namespace nall {
|
||||
|
||||
void XML::generate(string &xml, const uint8_t *data, unsigned size) {
|
||||
class snes_information {
|
||||
public:
|
||||
string xml_memory_map;
|
||||
|
||||
inline snes_information(const uint8_t *data, unsigned size);
|
||||
|
||||
private:
|
||||
inline void read_header(const uint8_t *data, unsigned size);
|
||||
inline unsigned find_header(const uint8_t *data, unsigned size);
|
||||
inline unsigned score_header(const uint8_t *data, unsigned size, unsigned addr);
|
||||
inline unsigned gameboy_ram_size(const uint8_t *data, unsigned size);
|
||||
inline bool gameboy_has_rtc(const uint8_t *data, unsigned size);
|
||||
|
||||
enum HeaderField {
|
||||
CartName = 0x00,
|
||||
Mapper = 0x15,
|
||||
RomType = 0x16,
|
||||
RomSize = 0x17,
|
||||
RamSize = 0x18,
|
||||
CartRegion = 0x19,
|
||||
Company = 0x1a,
|
||||
Version = 0x1b,
|
||||
Complement = 0x1c, //inverse checksum
|
||||
Checksum = 0x1e,
|
||||
ResetVector = 0x3c,
|
||||
};
|
||||
|
||||
enum Mode {
|
||||
ModeNormal,
|
||||
ModeBsxSlotted,
|
||||
ModeBsx,
|
||||
ModeSufamiTurbo,
|
||||
ModeSuperGameBoy,
|
||||
};
|
||||
|
||||
enum Type {
|
||||
TypeNormal,
|
||||
TypeBsxSlotted,
|
||||
TypeBsxBios,
|
||||
TypeBsx,
|
||||
TypeSufamiTurboBios,
|
||||
TypeSufamiTurbo,
|
||||
TypeSuperGameBoy1Bios,
|
||||
TypeSuperGameBoy2Bios,
|
||||
TypeGameBoy,
|
||||
TypeUnknown,
|
||||
};
|
||||
|
||||
enum Region {
|
||||
NTSC,
|
||||
PAL,
|
||||
};
|
||||
|
||||
enum MemoryMapper {
|
||||
LoROM,
|
||||
HiROM,
|
||||
ExLoROM,
|
||||
ExHiROM,
|
||||
SuperFXROM,
|
||||
SA1ROM,
|
||||
SPC7110ROM,
|
||||
BSCLoROM,
|
||||
BSCHiROM,
|
||||
BSXROM,
|
||||
STROM,
|
||||
};
|
||||
|
||||
enum DSP1MemoryMapper {
|
||||
DSP1Unmapped,
|
||||
DSP1LoROM1MB,
|
||||
DSP1LoROM2MB,
|
||||
DSP1HiROM,
|
||||
};
|
||||
|
||||
bool loaded; //is a base cartridge inserted?
|
||||
unsigned crc32; //crc32 of all cartridges (base+slot(s))
|
||||
unsigned rom_size;
|
||||
unsigned ram_size;
|
||||
|
||||
Mode mode;
|
||||
Type type;
|
||||
Region region;
|
||||
MemoryMapper mapper;
|
||||
DSP1MemoryMapper dsp1_mapper;
|
||||
|
||||
bool has_bsx_slot;
|
||||
bool has_superfx;
|
||||
bool has_sa1;
|
||||
bool has_srtc;
|
||||
bool has_sdd1;
|
||||
bool has_spc7110;
|
||||
bool has_spc7110rtc;
|
||||
bool has_cx4;
|
||||
bool has_dsp1;
|
||||
bool has_dsp2;
|
||||
bool has_dsp3;
|
||||
bool has_dsp4;
|
||||
bool has_obc1;
|
||||
bool has_st010;
|
||||
bool has_st011;
|
||||
bool has_st018;
|
||||
};
|
||||
|
||||
snes_information::snes_information(const uint8_t *data, unsigned size) {
|
||||
read_header(data, size);
|
||||
|
||||
xml = "<?xml version='1.0' encoding='UTF-8'?>\n";
|
||||
string xml = "<?xml version='1.0' encoding='UTF-8'?>\n";
|
||||
|
||||
if(type == TypeBsx) {
|
||||
xml << "<cartridge/>";
|
||||
xml_memory_map = xml;
|
||||
return;
|
||||
} else if(type == TypeSufamiTurbo) {
|
||||
}
|
||||
|
||||
if(type == TypeSufamiTurbo) {
|
||||
xml << "<cartridge/>";
|
||||
xml_memory_map = xml;
|
||||
return;
|
||||
} else if(type == TypeGameBoy) {
|
||||
}
|
||||
|
||||
if(type == TypeGameBoy) {
|
||||
xml << "<cartridge rtc='" << gameboy_has_rtc(data, size) << "'>\n";
|
||||
if(gameboy_ram_size(data, size) > 0) {
|
||||
xml << " <ram size='" << strhex(gameboy_ram_size(data, size)) << "'/>\n";
|
||||
}
|
||||
xml << "</cartridge>\n";
|
||||
xml_memory_map = xml;
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -56,30 +163,6 @@ void XML::generate(string &xml, const uint8_t *data, unsigned size) {
|
||||
xml << " <map address='80-bf:6000-7fff'/>\n";
|
||||
xml << " </mmio>\n";
|
||||
xml << " </supergameboy>\n";
|
||||
} else if(has_sdd1) {
|
||||
xml << " <rom>\n";
|
||||
xml << " <map mode='linear' address='00-3f:8000-ffff'/>\n";
|
||||
xml << " <map mode='linear' address='40-7f:0000-ffff'/>\n";
|
||||
xml << " <map mode='linear' address='80-bf:8000-ffff'/>\n";
|
||||
xml << " </rom>\n";
|
||||
|
||||
if(ram_size > 0) {
|
||||
xml << " <ram size='" << strhex(ram_size) << "'>\n";
|
||||
xml << " <map mode='linear' address='20-3f:6000-7fff'/>\n";
|
||||
xml << " <map mode='linear' address='a0-bf:6000-7fff'/>\n";
|
||||
xml << " <map mode='linear' address='70-7f:0000-7fff'/>\n";
|
||||
xml << " </ram>\n";
|
||||
}
|
||||
|
||||
xml << " <sdd1>\n";
|
||||
xml << " <mcu>\n";
|
||||
xml << " <map address='c0-ff:0000-ffff'/>\n";
|
||||
xml << " </mcu>\n";
|
||||
xml << " <mmio>\n";
|
||||
xml << " <map address='00-3f:4800-4807'/>\n";
|
||||
xml << " <map address='80-bf:4800-4807'/>\n";
|
||||
xml << " </mmio>\n";
|
||||
xml << " </sdd1>\n";
|
||||
} else if(has_spc7110) {
|
||||
xml << " <rom>\n";
|
||||
xml << " <map mode='shadow' address='00-0f:8000-ffff'/>\n";
|
||||
@@ -147,6 +230,20 @@ void XML::generate(string &xml, const uint8_t *data, unsigned size) {
|
||||
}
|
||||
xml << " </ram>\n";
|
||||
}
|
||||
} else if(mapper == ExLoROM) {
|
||||
xml << " <rom>\n";
|
||||
xml << " <map mode='linear' address='00-3f:8000-ffff'/>\n";
|
||||
xml << " <map mode='linear' address='40-7f:0000-ffff'/>\n";
|
||||
xml << " <map mode='linear' address='80-bf:8000-ffff'/>\n";
|
||||
xml << " </rom>\n";
|
||||
|
||||
if(ram_size > 0) {
|
||||
xml << " <ram size='" << strhex(ram_size) << "'>\n";
|
||||
xml << " <map mode='linear' address='20-3f:6000-7fff'/>\n";
|
||||
xml << " <map mode='linear' address='a0-bf:6000-7fff'/>\n";
|
||||
xml << " <map mode='linear' address='70-7f:0000-7fff'/>\n";
|
||||
xml << " </ram>\n";
|
||||
}
|
||||
} else if(mapper == ExHiROM) {
|
||||
xml << " <rom>\n";
|
||||
xml << " <map mode='shadow' address='00-3f:8000-ffff' offset='400000'/>\n";
|
||||
@@ -290,6 +387,18 @@ void XML::generate(string &xml, const uint8_t *data, unsigned size) {
|
||||
xml << " </srtc>\n";
|
||||
}
|
||||
|
||||
if(has_sdd1) {
|
||||
xml << " <sdd1>\n";
|
||||
xml << " <mcu>\n";
|
||||
xml << " <map address='c0-ff:0000-ffff'/>\n";
|
||||
xml << " </mcu>\n";
|
||||
xml << " <mmio>\n";
|
||||
xml << " <map address='00-3f:4800-4807'/>\n";
|
||||
xml << " <map address='80-bf:4800-4807'/>\n";
|
||||
xml << " </mmio>\n";
|
||||
xml << " </sdd1>\n";
|
||||
}
|
||||
|
||||
if(has_cx4) {
|
||||
xml << " <cx4>\n";
|
||||
xml << " <mmio>\n";
|
||||
@@ -335,12 +444,12 @@ void XML::generate(string &xml, const uint8_t *data, unsigned size) {
|
||||
if(has_dsp2) {
|
||||
xml << " <necdsp program='DSP-2'>\n";
|
||||
xml << " <dr>\n";
|
||||
xml << " <map address='20-3f:6000-6fff'/>\n";
|
||||
xml << " <map address='a0-bf:6000-6fff'/>\n";
|
||||
xml << " </dr>\n";
|
||||
xml << " <sr>\n";
|
||||
xml << " <map address='20-3f:8000-bfff'/>\n";
|
||||
xml << " <map address='a0-bf:8000-bfff'/>\n";
|
||||
xml << " </dr>\n";
|
||||
xml << " <sr>\n";
|
||||
xml << " <map address='20-3f:c000-ffff'/>\n";
|
||||
xml << " <map address='a0-bf:c000-ffff'/>\n";
|
||||
xml << " </sr>\n";
|
||||
xml << " </necdsp>\n";
|
||||
}
|
||||
@@ -409,9 +518,10 @@ void XML::generate(string &xml, const uint8_t *data, unsigned size) {
|
||||
}
|
||||
|
||||
xml << "</cartridge>\n";
|
||||
xml_memory_map = xml;
|
||||
}
|
||||
|
||||
void XML::read_header(const uint8_t *data, unsigned size) {
|
||||
void snes_information::read_header(const uint8_t *data, unsigned size) {
|
||||
type = TypeUnknown;
|
||||
mapper = LoROM;
|
||||
dsp1_mapper = DSP1Unmapped;
|
||||
@@ -449,11 +559,11 @@ void XML::read_header(const uint8_t *data, unsigned size) {
|
||||
}
|
||||
|
||||
const unsigned index = find_header(data, size);
|
||||
const uint8 mapperid = data[index + Mapper];
|
||||
const uint8 rom_type = data[index + RomType];
|
||||
const uint8 rom_size = data[index + RomSize];
|
||||
const uint8 company = data[index + Company];
|
||||
const uint8 regionid = data[index + CartRegion] & 0x7f;
|
||||
const uint8_t mapperid = data[index + Mapper];
|
||||
const uint8_t rom_type = data[index + RomType];
|
||||
const uint8_t rom_size = data[index + RomSize];
|
||||
const uint8_t company = data[index + Company];
|
||||
const uint8_t regionid = data[index + CartRegion] & 0x7f;
|
||||
|
||||
ram_size = 1024 << (data[index + RamSize] & 7);
|
||||
if(ram_size == 1024) ram_size = 0; //no RAM present
|
||||
@@ -515,7 +625,7 @@ void XML::read_header(const uint8_t *data, unsigned size) {
|
||||
//detect presence of BS-X flash cartridge connector (reads extended header information)
|
||||
if(data[index - 14] == 'Z') {
|
||||
if(data[index - 11] == 'J') {
|
||||
uint8 n13 = data[index - 13];
|
||||
uint8_t n13 = data[index - 13];
|
||||
if((n13 >= 'A' && n13 <= 'Z') || (n13 >= '0' && n13 <= '9')) {
|
||||
if(company == 0x33 || (data[index - 10] == 0x00 && data[index - 4] == 0x00)) {
|
||||
has_bsx_slot = true;
|
||||
@@ -634,7 +744,7 @@ void XML::read_header(const uint8_t *data, unsigned size) {
|
||||
}
|
||||
}
|
||||
|
||||
unsigned XML::find_header(const uint8_t *data, unsigned size) const {
|
||||
unsigned snes_information::find_header(const uint8_t *data, unsigned size) {
|
||||
unsigned score_lo = score_header(data, size, 0x007fc0);
|
||||
unsigned score_hi = score_header(data, size, 0x00ffc0);
|
||||
unsigned score_ex = score_header(data, size, 0x40ffc0);
|
||||
@@ -649,16 +759,16 @@ unsigned XML::find_header(const uint8_t *data, unsigned size) const {
|
||||
}
|
||||
}
|
||||
|
||||
unsigned XML::score_header(const uint8_t *data, unsigned size, unsigned addr) const {
|
||||
unsigned snes_information::score_header(const uint8_t *data, unsigned size, unsigned addr) {
|
||||
if(size < addr + 64) return 0; //image too small to contain header at this location?
|
||||
int score = 0;
|
||||
|
||||
uint16 resetvector = data[addr + ResetVector] | (data[addr + ResetVector + 1] << 8);
|
||||
uint16 checksum = data[addr + Checksum ] | (data[addr + Checksum + 1] << 8);
|
||||
uint16 complement = data[addr + Complement ] | (data[addr + Complement + 1] << 8);
|
||||
uint16_t resetvector = data[addr + ResetVector] | (data[addr + ResetVector + 1] << 8);
|
||||
uint16_t checksum = data[addr + Checksum ] | (data[addr + Checksum + 1] << 8);
|
||||
uint16_t complement = data[addr + Complement ] | (data[addr + Complement + 1] << 8);
|
||||
|
||||
uint8 resetop = data[(addr & ~0x7fff) | (resetvector & 0x7fff)]; //first opcode executed upon reset
|
||||
uint8 mapper = data[addr + Mapper] & ~0x10; //mask off irrelevent FastROM-capable bit
|
||||
uint8_t resetop = data[(addr & ~0x7fff) | (resetvector & 0x7fff)]; //first opcode executed upon reset
|
||||
uint8_t mapper = data[addr + Mapper] & ~0x10; //mask off irrelevent FastROM-capable bit
|
||||
|
||||
//$00:[000-7fff] contains uninitialized RAM and MMIO.
|
||||
//reset vector must point to ROM at $00:[8000-ffff] to be considered valid.
|
||||
@@ -730,7 +840,7 @@ unsigned XML::score_header(const uint8_t *data, unsigned size, unsigned addr) co
|
||||
return score;
|
||||
}
|
||||
|
||||
unsigned XML::gameboy_ram_size(const uint8_t *data, unsigned size) const {
|
||||
unsigned snes_information::gameboy_ram_size(const uint8_t *data, unsigned size) {
|
||||
if(size < 512) return 0;
|
||||
switch(data[0x0149]) {
|
||||
case 0x00: return 0 * 1024;
|
||||
@@ -743,8 +853,12 @@ unsigned XML::gameboy_ram_size(const uint8_t *data, unsigned size) const {
|
||||
}
|
||||
}
|
||||
|
||||
bool XML::gameboy_has_rtc(const uint8_t *data, unsigned size) const {
|
||||
bool snes_information::gameboy_has_rtc(const uint8_t *data, unsigned size) {
|
||||
if(size < 512) return false;
|
||||
if(data[0x0147] == 0x0f ||data[0x0147] == 0x10) return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
Regular → Executable
File renamed without changes.
Regular → Executable
File renamed without changes.
Regular → Executable
File renamed without changes.
Regular → Executable
+4
@@ -2,7 +2,10 @@
|
||||
#define NALL_STRING_HPP
|
||||
|
||||
#include <initializer_list>
|
||||
#include <nall/utility.hpp>
|
||||
|
||||
#include <nall/string/base.hpp>
|
||||
#include <nall/string/bsv.hpp>
|
||||
#include <nall/string/core.hpp>
|
||||
#include <nall/string/cast.hpp>
|
||||
#include <nall/string/compare.hpp>
|
||||
@@ -11,6 +14,7 @@
|
||||
#include <nall/string/match.hpp>
|
||||
#include <nall/string/math.hpp>
|
||||
#include <nall/string/strl.hpp>
|
||||
#include <nall/string/strpos.hpp>
|
||||
#include <nall/string/trim.hpp>
|
||||
#include <nall/string/replace.hpp>
|
||||
#include <nall/string/split.hpp>
|
||||
Executable
+141
@@ -0,0 +1,141 @@
|
||||
#ifndef NALL_STRING_BASE_HPP
|
||||
#define NALL_STRING_BASE_HPP
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <nall/concept.hpp>
|
||||
#include <nall/stdint.hpp>
|
||||
#include <nall/utf8.hpp>
|
||||
#include <nall/vector.hpp>
|
||||
|
||||
namespace nall {
|
||||
class string;
|
||||
template<typename T> inline string to_string(T);
|
||||
|
||||
class string {
|
||||
public:
|
||||
inline void reserve(unsigned);
|
||||
inline unsigned length() const;
|
||||
|
||||
inline string& assign(const char*);
|
||||
inline string& append(const char*);
|
||||
inline string& append(bool);
|
||||
inline string& append(signed int value);
|
||||
inline string& append(unsigned int value);
|
||||
inline string& append(double value);
|
||||
|
||||
template<typename T> inline string& operator= (T value);
|
||||
template<typename T> inline string& operator<<(T value);
|
||||
|
||||
inline operator const char*() const;
|
||||
inline char* operator()();
|
||||
inline char& operator[](int);
|
||||
|
||||
inline bool operator==(const char*) const;
|
||||
inline bool operator!=(const char*) const;
|
||||
inline bool operator< (const char*) const;
|
||||
inline bool operator<=(const char*) const;
|
||||
inline bool operator> (const char*) const;
|
||||
inline bool operator>=(const char*) const;
|
||||
|
||||
inline string& operator=(const string&);
|
||||
inline string& operator=(string&&);
|
||||
|
||||
template<typename... Args> inline string(Args&&... args);
|
||||
inline string(const string&);
|
||||
inline string(string&&);
|
||||
inline ~string();
|
||||
|
||||
inline bool readfile(const char*);
|
||||
inline string& replace (const char*, const char*);
|
||||
inline string& qreplace(const char*, const char*);
|
||||
|
||||
inline string& lower();
|
||||
inline string& upper();
|
||||
inline string& transform(const char *before, const char *after);
|
||||
inline string& ltrim(const char *key = " ");
|
||||
inline string& rtrim(const char *key = " ");
|
||||
inline string& trim (const char *key = " ");
|
||||
inline string& ltrim_once(const char *key = " ");
|
||||
inline string& rtrim_once(const char *key = " ");
|
||||
inline string& trim_once (const char *key = " ");
|
||||
|
||||
protected:
|
||||
char *data;
|
||||
unsigned size;
|
||||
|
||||
#if defined(QSTRING_H)
|
||||
public:
|
||||
inline operator QString() const;
|
||||
#endif
|
||||
};
|
||||
|
||||
class lstring : public linear_vector<string> {
|
||||
public:
|
||||
template<typename T> inline lstring& operator<<(T value);
|
||||
|
||||
inline optional<unsigned> find(const char*);
|
||||
inline void split (const char*, const char*, unsigned = 0);
|
||||
inline void qsplit(const char*, const char*, unsigned = 0);
|
||||
|
||||
lstring();
|
||||
lstring(std::initializer_list<string>);
|
||||
};
|
||||
|
||||
//compare.hpp
|
||||
inline char chrlower(char c);
|
||||
inline char chrupper(char c);
|
||||
inline int stricmp(const char *dest, const char *src);
|
||||
inline bool strbegin (const char *str, const char *key);
|
||||
inline bool stribegin(const char *str, const char *key);
|
||||
inline bool strend (const char *str, const char *key);
|
||||
inline bool striend(const char *str, const char *key);
|
||||
|
||||
//convert.hpp
|
||||
inline char* strlower(char *str);
|
||||
inline char* strupper(char *str);
|
||||
inline char* strtr(char *dest, const char *before, const char *after);
|
||||
inline uintmax_t strhex (const char *str);
|
||||
inline intmax_t strsigned (const char *str);
|
||||
inline uintmax_t strunsigned(const char *str);
|
||||
inline uintmax_t strbin (const char *str);
|
||||
inline double strdouble (const char *str);
|
||||
|
||||
//match.hpp
|
||||
inline bool match(const char *pattern, const char *str);
|
||||
|
||||
//math.hpp
|
||||
inline bool strint (const char *str, int &result);
|
||||
inline bool strmath(const char *str, int &result);
|
||||
|
||||
//strl.hpp
|
||||
inline unsigned strlcpy(char *dest, const char *src, unsigned length);
|
||||
inline unsigned strlcat(char *dest, const char *src, unsigned length);
|
||||
|
||||
//trim.hpp
|
||||
inline char* ltrim(char *str, const char *key = " ");
|
||||
inline char* rtrim(char *str, const char *key = " ");
|
||||
inline char* trim (char *str, const char *key = " ");
|
||||
inline char* ltrim_once(char *str, const char *key = " ");
|
||||
inline char* rtrim_once(char *str, const char *key = " ");
|
||||
inline char* trim_once (char *str, const char *key = " ");
|
||||
|
||||
//utility.hpp
|
||||
inline unsigned strlcpy(string &dest, const char *src, unsigned length);
|
||||
inline unsigned strlcat(string &dest, const char *src, unsigned length);
|
||||
inline string substr(const char *src, unsigned start = 0, unsigned length = 0);
|
||||
inline string& strtr(string &dest, const char *before, const char *after);
|
||||
template<unsigned length = 0, char padding = '0'> inline string strhex(uintmax_t value);
|
||||
template<unsigned length = 0, char padding = '0'> inline string strsigned(intmax_t value);
|
||||
template<unsigned length = 0, char padding = '0'> inline string strunsigned(uintmax_t value);
|
||||
template<unsigned length = 0, char padding = '0'> inline string strbin(uintmax_t value);
|
||||
inline unsigned strdouble(char *str, double value);
|
||||
inline string strdouble(double value);
|
||||
|
||||
//variadic.hpp
|
||||
template<typename... Args> inline void print(Args&&... args);
|
||||
};
|
||||
|
||||
#endif
|
||||
Executable
+75
@@ -0,0 +1,75 @@
|
||||
#ifndef NALL_STRING_BSV_HPP
|
||||
#define NALL_STRING_BSV_HPP
|
||||
|
||||
//BSV parser
|
||||
//version 0.01
|
||||
|
||||
namespace nall {
|
||||
|
||||
inline string bsv_decode(const char *input) {
|
||||
string output;
|
||||
unsigned offset = 0;
|
||||
while(*input) {
|
||||
//illegal characters
|
||||
if(*input == '}' ) return "";
|
||||
if(*input == '\r') return "";
|
||||
if(*input == '\n') return "";
|
||||
|
||||
//normal characters
|
||||
if(*input != '{') { output[offset++] = *input++; continue; }
|
||||
|
||||
//entities
|
||||
if(strbegin(input, "{lf}")) { output[offset++] = '\n'; input += 4; continue; }
|
||||
if(strbegin(input, "{lb}")) { output[offset++] = '{'; input += 4; continue; }
|
||||
if(strbegin(input, "{rb}")) { output[offset++] = '}'; input += 4; continue; }
|
||||
|
||||
//illegal entities
|
||||
return "";
|
||||
}
|
||||
output[offset] = 0;
|
||||
return output;
|
||||
}
|
||||
|
||||
inline string bsv_encode(const char *input) {
|
||||
string output;
|
||||
unsigned offset = 0;
|
||||
while(*input) {
|
||||
//illegal characters
|
||||
if(*input == '\r') return "";
|
||||
|
||||
if(*input == '\n') {
|
||||
output[offset++] = '{';
|
||||
output[offset++] = 'l';
|
||||
output[offset++] = 'f';
|
||||
output[offset++] = '}';
|
||||
input++;
|
||||
continue;
|
||||
}
|
||||
|
||||
if(*input == '{') {
|
||||
output[offset++] = '{';
|
||||
output[offset++] = 'l';
|
||||
output[offset++] = 'b';
|
||||
output[offset++] = '}';
|
||||
input++;
|
||||
continue;
|
||||
}
|
||||
|
||||
if(*input == '}') {
|
||||
output[offset++] = '{';
|
||||
output[offset++] = 'r';
|
||||
output[offset++] = 'b';
|
||||
output[offset++] = '}';
|
||||
input++;
|
||||
continue;
|
||||
}
|
||||
|
||||
output[offset++] = *input++;
|
||||
}
|
||||
output[offset] = 0;
|
||||
return output;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
Executable
+32
@@ -0,0 +1,32 @@
|
||||
#ifndef NALL_STRING_CAST_HPP
|
||||
#define NALL_STRING_CAST_HPP
|
||||
|
||||
namespace nall {
|
||||
|
||||
//this is needed, as C++0x does not support explicit template specialization inside classes
|
||||
template<> inline string to_string<bool> (bool v) { return v ? "true" : "false"; }
|
||||
template<> inline string to_string<signed int> (signed int v) { return strsigned(v); }
|
||||
template<> inline string to_string<unsigned int> (unsigned int v) { return strunsigned(v); }
|
||||
template<> inline string to_string<double> (double v) { return strdouble(v); }
|
||||
template<> inline string to_string<char*> (char *v) { return v; }
|
||||
template<> inline string to_string<const char*> (const char *v) { return v; }
|
||||
template<> inline string to_string<string> (string v) { return v; }
|
||||
template<> inline string to_string<const string&>(const string &v) { return v; }
|
||||
|
||||
template<typename T> string& string::operator= (T value) { return assign(to_string<T>(value)); }
|
||||
template<typename T> string& string::operator<<(T value) { return append(to_string<T>(value)); }
|
||||
|
||||
template<typename T> lstring& lstring::operator<<(T value) {
|
||||
operator[](size()).assign(to_string<T>(value));
|
||||
return *this;
|
||||
}
|
||||
|
||||
#if defined(QSTRING_H)
|
||||
template<> inline string to_string<QString>(QString v) { return v.toUtf8().constData(); }
|
||||
template<> inline string to_string<const QString&>(const QString &v) { return v.toUtf8().constData(); }
|
||||
string::operator QString() const { return QString::fromUtf8(*this); }
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
Regular → Executable
+4
-32
@@ -1,6 +1,8 @@
|
||||
#ifndef NALL_STRING_COMPARE_HPP
|
||||
#define NALL_STRING_COMPARE_HPP
|
||||
|
||||
namespace nall {
|
||||
|
||||
char chrlower(char c) {
|
||||
return (c >= 'A' && c <= 'Z') ? c + ('a' - 'A') : c;
|
||||
}
|
||||
@@ -19,38 +21,6 @@ int stricmp(const char *dest, const char *src) {
|
||||
return (int)chrlower(*dest) - (int)chrlower(*src);
|
||||
}
|
||||
|
||||
int strpos(const char *str, const char *key) {
|
||||
int ssl = strlen(str), ksl = strlen(key);
|
||||
|
||||
if(ksl > ssl) return -1;
|
||||
for(int i = 0; i <= ssl - ksl; i++) {
|
||||
if(!memcmp(str + i, key, ksl)) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
int qstrpos(const char *str, const char *key) {
|
||||
int ssl = strlen(str), ksl = strlen(key);
|
||||
|
||||
if(ksl > ssl) return -1;
|
||||
for(int i = 0; i <= ssl - ksl;) {
|
||||
uint8_t x = str[i];
|
||||
if(x == '\"' || x == '\'') {
|
||||
uint8_t z = i++;
|
||||
while(str[i] != x && i < ssl) i++;
|
||||
if(i >= ssl) i = z;
|
||||
}
|
||||
if(!memcmp(str + i, key, ksl)) {
|
||||
return i;
|
||||
} else {
|
||||
i++;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
bool strbegin(const char *str, const char *key) {
|
||||
int i, ssl = strlen(str), ksl = strlen(key);
|
||||
|
||||
@@ -97,4 +67,6 @@ bool striend(const char *str, const char *key) {
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
Regular → Executable
+9
-1
@@ -1,6 +1,8 @@
|
||||
#ifndef NALL_STRING_CONVERT_HPP
|
||||
#define NALL_STRING_CONVERT_HPP
|
||||
|
||||
namespace nall {
|
||||
|
||||
char* strlower(char *str) {
|
||||
if(!str) return 0;
|
||||
int i = 0;
|
||||
@@ -38,6 +40,10 @@ char* strtr(char *dest, const char *before, const char *after) {
|
||||
return dest;
|
||||
}
|
||||
|
||||
string& string::lower() { nall::strlower(data); return *this; }
|
||||
string& string::upper() { nall::strupper(data); return *this; }
|
||||
string& string::transform(const char *before, const char *after) { nall::strtr(data, before, after); return *this; }
|
||||
|
||||
uintmax_t strhex(const char *str) {
|
||||
if(!str) return 0;
|
||||
uintmax_t result = 0;
|
||||
@@ -125,7 +131,7 @@ double strdouble(const char *str) {
|
||||
while(*str) {
|
||||
uint8_t x = *str++;
|
||||
if(x >= '0' && x <= '9') x -= '0';
|
||||
else if(x == '.') break; //break loop and read fractional part
|
||||
else if(x == '.' || x == ',') break; //break loop and read fractional part
|
||||
else return (double)result_integral; //invalid value, assume no fractional part
|
||||
result_integral = result_integral * 10 + x;
|
||||
}
|
||||
@@ -146,4 +152,6 @@ double strdouble(const char *str) {
|
||||
return !negate ? result : -result;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
Regular → Executable
+37
-26
@@ -3,7 +3,7 @@
|
||||
|
||||
namespace nall {
|
||||
|
||||
void string::reserve(size_t size_) {
|
||||
void string::reserve(unsigned size_) {
|
||||
if(size_ > size) {
|
||||
size = size_;
|
||||
data = (char*)realloc(data, size + 1);
|
||||
@@ -29,6 +29,11 @@ string& string::append(const char *s) {
|
||||
return *this;
|
||||
}
|
||||
|
||||
string& string::append(bool value) { append(value ? "true" : "false"); return *this; }
|
||||
string& string::append(signed int value) { append(strsigned(value)); return *this; }
|
||||
string& string::append(unsigned int value) { append(strunsigned(value)); return *this; }
|
||||
string& string::append(double value) { append(strdouble(value)); return *this; }
|
||||
|
||||
string::operator const char*() const {
|
||||
return data;
|
||||
}
|
||||
@@ -49,15 +54,34 @@ 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() {
|
||||
string& string::operator=(const string &value) {
|
||||
assign(value);
|
||||
return *this;
|
||||
}
|
||||
|
||||
string& string::operator=(string &&source) {
|
||||
if(data) free(data);
|
||||
size = source.size;
|
||||
data = source.data;
|
||||
source.data = 0;
|
||||
source.size = 0;
|
||||
return *this;
|
||||
}
|
||||
|
||||
static void istring(string &output) {
|
||||
}
|
||||
|
||||
template<typename T, typename... Args>
|
||||
static void istring(string &output, const T &value, Args&&... args) {
|
||||
output.append(value);
|
||||
istring(output, std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
template<typename... Args> string::string(Args&&... args) {
|
||||
size = 64;
|
||||
data = (char*)malloc(size + 1);
|
||||
*data = 0;
|
||||
}
|
||||
|
||||
string::string(const char *value) {
|
||||
size = strlen(value);
|
||||
data = strdup(value);
|
||||
istring(*this, std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
string::string(const string &value) {
|
||||
@@ -71,21 +95,8 @@ string::string(string &&source) {
|
||||
source.data = 0;
|
||||
}
|
||||
|
||||
string& string::operator=(const string &value) {
|
||||
assign(value);
|
||||
return *this;
|
||||
}
|
||||
|
||||
string& string::operator=(string &&source) {
|
||||
if(data) free(data);
|
||||
size = source.size;
|
||||
data = source.data;
|
||||
source.data = 0;
|
||||
return *this;
|
||||
}
|
||||
|
||||
string::~string() {
|
||||
free(data);
|
||||
if(data) free(data);
|
||||
}
|
||||
|
||||
bool string::readfile(const char *filename) {
|
||||
@@ -94,12 +105,12 @@ bool string::readfile(const char *filename) {
|
||||
#if !defined(_WIN32)
|
||||
FILE *fp = fopen(filename, "rb");
|
||||
#else
|
||||
FILE *fp = _wfopen(nall::utf16_t(filename), L"rb");
|
||||
FILE *fp = _wfopen(utf16_t(filename), L"rb");
|
||||
#endif
|
||||
if(!fp) return false;
|
||||
|
||||
fseek(fp, 0, SEEK_END);
|
||||
size_t size = ftell(fp);
|
||||
unsigned size = ftell(fp);
|
||||
rewind(fp);
|
||||
char *fdata = new char[size + 1];
|
||||
unsigned unused = fread(fdata, 1, size, fp);
|
||||
@@ -111,11 +122,11 @@ bool string::readfile(const char *filename) {
|
||||
return true;
|
||||
}
|
||||
|
||||
int lstring::find(const char *key) {
|
||||
optional<unsigned> lstring::find(const char *key) {
|
||||
for(unsigned i = 0; i < size(); i++) {
|
||||
if(operator[](i) == key) return i;
|
||||
if(operator[](i) == key) return { true, i };
|
||||
}
|
||||
return -1;
|
||||
return { false, 0 };
|
||||
}
|
||||
|
||||
inline lstring::lstring() {
|
||||
Executable
+61
@@ -0,0 +1,61 @@
|
||||
#ifndef NALL_FILENAME_HPP
|
||||
#define NALL_FILENAME_HPP
|
||||
|
||||
namespace nall {
|
||||
|
||||
// "foo/bar.c" -> "foo/", "bar.c" -> "./"
|
||||
inline string dir(char const *name) {
|
||||
string result = name;
|
||||
for(signed i = strlen(result); i >= 0; i--) {
|
||||
if(result[i] == '/' || result[i] == '\\') {
|
||||
result[i + 1] = 0;
|
||||
break;
|
||||
}
|
||||
if(i == 0) result = "./";
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
// "foo/bar.c" -> "bar.c"
|
||||
inline string notdir(char const *name) {
|
||||
for(signed i = strlen(name); i >= 0; i--) {
|
||||
if(name[i] == '/' || name[i] == '\\') {
|
||||
name += i + 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
string result = name;
|
||||
return result;
|
||||
}
|
||||
|
||||
// "foo/bar.c" -> "foo/bar"
|
||||
inline string basename(char const *name) {
|
||||
string result = name;
|
||||
for(signed i = strlen(result); i >= 0; i--) {
|
||||
if(result[i] == '/' || result[i] == '\\') {
|
||||
//file has no extension
|
||||
break;
|
||||
}
|
||||
if(result[i] == '.') {
|
||||
result[i] = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
// "foo/bar.c" -> "c"
|
||||
inline string extension(char const *name) {
|
||||
for(signed i = strlen(name); i >= 0; i--) {
|
||||
if(name[i] == '.') {
|
||||
name += i + 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
string result = name;
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
Regular → Executable
+4
@@ -1,6 +1,8 @@
|
||||
#ifndef NALL_STRING_MATCH_HPP
|
||||
#define NALL_STRING_MATCH_HPP
|
||||
|
||||
namespace nall {
|
||||
|
||||
bool match(const char *p, const char *s) {
|
||||
const char *p_ = 0, *s_ = 0;
|
||||
|
||||
@@ -69,4 +71,6 @@ bool match(const char *p, const char *s) {
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
Regular → Executable
+4
@@ -1,6 +1,8 @@
|
||||
#ifndef NALL_STRING_MATH_HPP
|
||||
#define NALL_STRING_MATH_HPP
|
||||
|
||||
namespace nall {
|
||||
|
||||
static int eval_integer(const char *&s) {
|
||||
if(!*s) throw "unrecognized_integer";
|
||||
int value = 0, x = *s, y = *(s + 1);
|
||||
@@ -157,4 +159,6 @@ bool strmath(const char *s, int &result) {
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
Regular → Executable
File renamed without changes.
Regular → Executable
File renamed without changes.
Regular → Executable
+9
-5
@@ -1,13 +1,15 @@
|
||||
#ifndef NALL_STRING_STRL_HPP
|
||||
#define NALL_STRING_STRL_HPP
|
||||
|
||||
namespace nall {
|
||||
|
||||
//strlcpy, strlcat based on OpenBSD implementation by Todd C. Miller
|
||||
|
||||
//return = strlen(src)
|
||||
size_t strlcpy(char *dest, const char *src, size_t length) {
|
||||
unsigned strlcpy(char *dest, const char *src, unsigned length) {
|
||||
char *d = dest;
|
||||
const char *s = src;
|
||||
size_t n = length;
|
||||
unsigned n = length;
|
||||
|
||||
if(n) {
|
||||
while(--n && (*d++ = *s++)); //copy as many bytes as possible, or until null terminator reached
|
||||
@@ -22,13 +24,13 @@ size_t strlcpy(char *dest, const char *src, size_t length) {
|
||||
}
|
||||
|
||||
//return = strlen(src) + min(length, strlen(dest))
|
||||
size_t strlcat(char *dest, const char *src, size_t length) {
|
||||
unsigned strlcat(char *dest, const char *src, unsigned length) {
|
||||
char *d = dest;
|
||||
const char *s = src;
|
||||
size_t n = length;
|
||||
unsigned n = length;
|
||||
|
||||
while(n-- && *d) d++; //find end of dest
|
||||
size_t dlength = d - dest;
|
||||
unsigned dlength = d - dest;
|
||||
n = length - dlength; //subtract length of dest from maximum string length
|
||||
|
||||
if(!n) return dlength + strlen(s);
|
||||
@@ -45,4 +47,6 @@ size_t strlcat(char *dest, const char *src, size_t length) {
|
||||
return dlength + (s - src); //return length of resulting string, sans null terminator
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
Executable
+41
@@ -0,0 +1,41 @@
|
||||
#ifndef NALL_STRING_STRPOS_HPP
|
||||
#define NALL_STRING_STRPOS_HPP
|
||||
|
||||
//usage example:
|
||||
//if(auto pos = strpos(str, key)) print(pos(), "\n");
|
||||
//prints position of key within str, only if it is found
|
||||
|
||||
namespace nall {
|
||||
|
||||
inline optional<unsigned> strpos(const char *str, const char *key) {
|
||||
unsigned ssl = strlen(str), ksl = strlen(key);
|
||||
if(ksl > ssl) return { false, 0 };
|
||||
|
||||
for(unsigned i = 0; i <= ssl - ksl; i++) {
|
||||
if(!memcmp(str + i, key, ksl)) return { true, i };
|
||||
}
|
||||
|
||||
return { false, 0 };
|
||||
}
|
||||
|
||||
inline optional<unsigned> qstrpos(const char *str, const char *key) {
|
||||
unsigned ssl = strlen(str), ksl = strlen(key);
|
||||
if(ksl > ssl) return { false, 0 };
|
||||
|
||||
for(unsigned i = 0; i <= ssl - ksl;) {
|
||||
uint8_t x = str[i];
|
||||
if(x == '\"' || x == '\'') {
|
||||
uint8_t z = i++;
|
||||
while(str[i] != x && i < ssl) i++;
|
||||
if(i >= ssl) i = z;
|
||||
}
|
||||
if(!memcmp(str + i, key, ksl)) return { true, i };
|
||||
i++;
|
||||
}
|
||||
|
||||
return { false, 0 };
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
Regular → Executable
+11
@@ -1,6 +1,8 @@
|
||||
#ifndef NALL_STRING_TRIM_HPP
|
||||
#define NALL_STRING_TRIM_HPP
|
||||
|
||||
namespace nall {
|
||||
|
||||
char* ltrim(char *str, const char *key) {
|
||||
if(!key || !*key) return str;
|
||||
while(strbegin(str, key)) {
|
||||
@@ -47,4 +49,13 @@ char* trim_once(char *str, const char *key) {
|
||||
return ltrim_once(rtrim_once(str, key), key);
|
||||
}
|
||||
|
||||
string& string::ltrim(const char *key) { nall::ltrim(data, key); return *this; }
|
||||
string& string::rtrim(const char *key) { nall::rtrim(data, key); return *this; }
|
||||
string& string::trim (const char *key) { nall::trim (data, key); return *this; }
|
||||
string& string::ltrim_once(const char *key) { nall::ltrim_once(data, key); return *this; }
|
||||
string& string::rtrim_once(const char *key) { nall::rtrim_once(data, key); return *this; }
|
||||
string& string::trim_once (const char *key) { nall::trim_once (data, key); return *this; }
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
Regular → Executable
+19
-27
@@ -1,18 +1,20 @@
|
||||
#ifndef NALL_STRING_UTILITY_HPP
|
||||
#define NALL_STRING_UTILITY_HPP
|
||||
|
||||
size_t strlcpy(nall::string &dest, const char *src, size_t length) {
|
||||
namespace nall {
|
||||
|
||||
unsigned strlcpy(string &dest, const char *src, unsigned length) {
|
||||
dest.reserve(length);
|
||||
return strlcpy(dest(), src, length);
|
||||
}
|
||||
|
||||
size_t strlcat(nall::string &dest, const char *src, size_t length) {
|
||||
unsigned strlcat(string &dest, const char *src, unsigned length) {
|
||||
dest.reserve(length);
|
||||
return strlcat(dest(), src, length);
|
||||
}
|
||||
|
||||
nall::string substr(const char *src, size_t start, size_t length) {
|
||||
nall::string dest;
|
||||
string substr(const char *src, unsigned start, unsigned length) {
|
||||
string dest;
|
||||
if(length == 0) {
|
||||
//copy entire string
|
||||
dest = src + start;
|
||||
@@ -23,22 +25,10 @@ nall::string substr(const char *src, size_t start, size_t length) {
|
||||
return dest;
|
||||
}
|
||||
|
||||
/* very simplistic wrappers to return nall::string& instead of char* type */
|
||||
|
||||
nall::string& strlower(nall::string &str) { strlower(str()); return str; }
|
||||
nall::string& strupper(nall::string &str) { strupper(str()); return str; }
|
||||
nall::string& strtr(nall::string &dest, const char *before, const char *after) { strtr(dest(), before, after); return dest; }
|
||||
nall::string& ltrim(nall::string &str, const char *key) { ltrim(str(), key); return str; }
|
||||
nall::string& rtrim(nall::string &str, const char *key) { rtrim(str(), key); return str; }
|
||||
nall::string& trim (nall::string &str, const char *key) { trim (str(), key); return str; }
|
||||
nall::string& ltrim_once(nall::string &str, const char *key) { ltrim_once(str(), key); return str; }
|
||||
nall::string& rtrim_once(nall::string &str, const char *key) { rtrim_once(str(), key); return str; }
|
||||
nall::string& trim_once (nall::string &str, const char *key) { trim_once (str(), key); return str; }
|
||||
|
||||
/* arithmetic <> string */
|
||||
|
||||
template<unsigned length, char padding> nall::string strhex(uintmax_t value) {
|
||||
nall::string output;
|
||||
template<unsigned length, char padding> string strhex(uintmax_t value) {
|
||||
string output;
|
||||
unsigned offset = 0;
|
||||
|
||||
//render string backwards, as we do not know its length yet
|
||||
@@ -61,8 +51,8 @@ template<unsigned length, char padding> nall::string strhex(uintmax_t value) {
|
||||
return output;
|
||||
}
|
||||
|
||||
template<unsigned length, char padding> nall::string strsigned(intmax_t value) {
|
||||
nall::string output;
|
||||
template<unsigned length, char padding> string strsigned(intmax_t value) {
|
||||
string output;
|
||||
unsigned offset = 0;
|
||||
|
||||
bool negative = value < 0;
|
||||
@@ -87,8 +77,8 @@ template<unsigned length, char padding> nall::string strsigned(intmax_t value) {
|
||||
return output;
|
||||
}
|
||||
|
||||
template<unsigned length, char padding> nall::string strunsigned(uintmax_t value) {
|
||||
nall::string output;
|
||||
template<unsigned length, char padding> string strunsigned(uintmax_t value) {
|
||||
string output;
|
||||
unsigned offset = 0;
|
||||
|
||||
do {
|
||||
@@ -109,8 +99,8 @@ template<unsigned length, char padding> nall::string strunsigned(uintmax_t value
|
||||
return output;
|
||||
}
|
||||
|
||||
template<unsigned length, char padding> nall::string strbin(uintmax_t value) {
|
||||
nall::string output;
|
||||
template<unsigned length, char padding> string strbin(uintmax_t value) {
|
||||
string output;
|
||||
unsigned offset = 0;
|
||||
|
||||
do {
|
||||
@@ -134,7 +124,7 @@ template<unsigned length, char padding> nall::string strbin(uintmax_t value) {
|
||||
//using sprintf is certainly not the most ideal method to convert
|
||||
//a double to a string ... but attempting to parse a double by
|
||||
//hand, digit-by-digit, results in subtle rounding errors.
|
||||
size_t strdouble(char *str, double value) {
|
||||
unsigned strdouble(char *str, double value) {
|
||||
char buffer[256];
|
||||
sprintf(buffer, "%f", value);
|
||||
|
||||
@@ -155,11 +145,13 @@ size_t strdouble(char *str, double value) {
|
||||
return length + 1;
|
||||
}
|
||||
|
||||
nall::string strdouble(double value) {
|
||||
nall::string temp;
|
||||
string strdouble(double value) {
|
||||
string temp;
|
||||
temp.reserve(strdouble(0, value));
|
||||
strdouble(temp(), value);
|
||||
return temp;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
Executable
+12
@@ -0,0 +1,12 @@
|
||||
#ifndef NALL_STRING_VARIADIC_HPP
|
||||
#define NALL_STRING_VARIADIC_HPP
|
||||
|
||||
namespace nall {
|
||||
|
||||
template<typename... Args> inline void print(Args&&... args) {
|
||||
printf("%s", (const char*)string(std::forward<Args>(args)...));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
Regular → Executable
+64
-67
@@ -2,9 +2,7 @@
|
||||
#define NALL_STRING_XML_HPP
|
||||
|
||||
//XML subset parser
|
||||
//version 0.04
|
||||
|
||||
#include <nall/array.hpp>
|
||||
//version 0.05
|
||||
|
||||
namespace nall {
|
||||
|
||||
@@ -16,15 +14,14 @@ struct xml_attribute {
|
||||
|
||||
struct xml_element : xml_attribute {
|
||||
string parse() const;
|
||||
array<xml_attribute*> attribute;
|
||||
array<xml_element*> element;
|
||||
~xml_element();
|
||||
linear_vector<xml_attribute> attribute;
|
||||
linear_vector<xml_element> element;
|
||||
|
||||
protected:
|
||||
void parse_doctype(const char *&data);
|
||||
bool parse_head(string data);
|
||||
bool parse_body(const char *&data);
|
||||
friend xml_element *xml_parse(const char *data);
|
||||
friend xml_element xml_parse(const char *data);
|
||||
};
|
||||
|
||||
inline string xml_attribute::parse() const {
|
||||
@@ -68,21 +65,25 @@ inline string xml_element::parse() const {
|
||||
}
|
||||
|
||||
if(strbegin(source, "<!--")) {
|
||||
signed pos = strpos(source, "-->");
|
||||
if(pos == -1) return "";
|
||||
source += pos + 3;
|
||||
continue;
|
||||
if(auto pos = strpos(source, "-->")) {
|
||||
source += pos() + 3;
|
||||
continue;
|
||||
} else {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
if(strbegin(source, "<![CDATA[")) {
|
||||
signed pos = strpos(source, "]]>");
|
||||
if(pos == -1) return "";
|
||||
string cdata = substr(source, 9, pos - 9);
|
||||
data << cdata;
|
||||
offset += strlen(cdata);
|
||||
if(auto pos = strpos(source, "]]>")) {
|
||||
string cdata = substr(source, 9, pos() - 9);
|
||||
data << cdata;
|
||||
offset += strlen(cdata);
|
||||
|
||||
source += offset + 3;
|
||||
continue;
|
||||
source += offset + 3;
|
||||
continue;
|
||||
} else {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
//reject illegal characters
|
||||
@@ -118,10 +119,10 @@ inline bool xml_element::parse_head(string data) {
|
||||
data.qreplace("\t", " ");
|
||||
data.qreplace("\r", " ");
|
||||
data.qreplace("\n", " ");
|
||||
while(qstrpos(data, " ") >= 0) data.qreplace(" ", " ");
|
||||
while(qstrpos(data, " ")) data.qreplace(" ", " ");
|
||||
data.qreplace(" =", "=");
|
||||
data.qreplace("= ", "=");
|
||||
rtrim(data);
|
||||
data.rtrim();
|
||||
|
||||
lstring part;
|
||||
part.qsplit(" ", data);
|
||||
@@ -134,13 +135,13 @@ inline bool xml_element::parse_head(string data) {
|
||||
side.qsplit("=", part[i]);
|
||||
if(side.size() != 2) throw "...";
|
||||
|
||||
xml_attribute *attr = new xml_attribute;
|
||||
attr->name = side[0];
|
||||
attr->content = side[1];
|
||||
if(strbegin(attr->content, "\"") && strend(attr->content, "\"")) trim_once(attr->content, "\"");
|
||||
else if(strbegin(attr->content, "'") && strend(attr->content, "'")) trim_once(attr->content, "'");
|
||||
xml_attribute attr;
|
||||
attr.name = side[0];
|
||||
attr.content = side[1];
|
||||
if(strbegin(attr.content, "\"") && strend(attr.content, "\"")) attr.content.trim_once("\"");
|
||||
else if(strbegin(attr.content, "'") && strend(attr.content, "'")) attr.content.trim_once("'");
|
||||
else throw "...";
|
||||
attribute.add(attr);
|
||||
attribute.append(attr);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -156,34 +157,38 @@ inline bool xml_element::parse_body(const char *&data) {
|
||||
}
|
||||
|
||||
if(strbegin(data, "!--")) {
|
||||
signed offset = strpos(data, "-->");
|
||||
if(offset == -1) throw "...";
|
||||
data += offset + 3;
|
||||
continue;
|
||||
if(auto offset = strpos(data, "-->")) {
|
||||
data += offset() + 3;
|
||||
continue;
|
||||
} else {
|
||||
throw "...";
|
||||
}
|
||||
}
|
||||
|
||||
if(strbegin(data, "![CDATA[")) {
|
||||
signed offset = strpos(data, "]]>");
|
||||
if(offset == -1) throw "...";
|
||||
data += offset + 3;
|
||||
continue;
|
||||
if(auto offset = strpos(data, "]]>")) {
|
||||
data += offset() + 3;
|
||||
continue;
|
||||
} else {
|
||||
throw "...";
|
||||
}
|
||||
}
|
||||
|
||||
signed offset = strpos(data, ">");
|
||||
if(offset == -1) throw "...";
|
||||
auto offset = strpos(data, ">");
|
||||
if(!offset) throw "...";
|
||||
|
||||
string tag = substr(data, 0, offset);
|
||||
data += offset + 1;
|
||||
string tag = substr(data, 0, offset());
|
||||
data += offset() + 1;
|
||||
const char *content_begin = data;
|
||||
|
||||
bool self_terminating = false;
|
||||
|
||||
if(strend(tag, "?") == true) {
|
||||
self_terminating = true;
|
||||
rtrim_once(tag, "?");
|
||||
tag.rtrim_once("?");
|
||||
} else if(strend(tag, "/") == true) {
|
||||
self_terminating = true;
|
||||
rtrim_once(tag, "/");
|
||||
tag.rtrim_once("/");
|
||||
}
|
||||
|
||||
parse_head(tag);
|
||||
@@ -191,48 +196,41 @@ inline bool xml_element::parse_body(const char *&data) {
|
||||
|
||||
while(*data) {
|
||||
unsigned index = element.size();
|
||||
xml_element *elem = new xml_element;
|
||||
if(elem->parse_body(data) == false) {
|
||||
delete elem;
|
||||
|
||||
xml_element node;
|
||||
if(node.parse_body(data) == false) {
|
||||
if(*data == '/') {
|
||||
signed length = data - content_begin - 1;
|
||||
if(length > 0) content = substr(content_begin, 0, length);
|
||||
|
||||
data++;
|
||||
offset = strpos(data, ">");
|
||||
if(offset == -1) throw "...";
|
||||
auto offset = strpos(data, ">");
|
||||
if(!offset) throw "...";
|
||||
|
||||
tag = substr(data, 0, offset);
|
||||
data += offset + 1;
|
||||
tag = substr(data, 0, offset());
|
||||
data += offset() + 1;
|
||||
|
||||
tag.replace("\t", " ");
|
||||
tag.replace("\r", " ");
|
||||
tag.replace("\n", " ");
|
||||
while(strpos(tag, " ") >= 0) tag.replace(" ", " ");
|
||||
rtrim(tag);
|
||||
while(strpos(tag, " ")) tag.replace(" ", " ");
|
||||
tag.rtrim();
|
||||
|
||||
if(name != tag) throw "...";
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
element.add(elem);
|
||||
element.append(node);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
inline xml_element::~xml_element() {
|
||||
for(unsigned i = 0; i < attribute.size(); i++) delete attribute[i];
|
||||
for(unsigned i = 0; i < element.size(); i++) delete element[i];
|
||||
}
|
||||
|
||||
//ensure there is only one root element
|
||||
inline bool xml_validate(xml_element *document) {
|
||||
inline bool xml_validate(xml_element &document) {
|
||||
unsigned root_counter = 0;
|
||||
|
||||
for(unsigned i = 0; i < document->element.size(); i++) {
|
||||
string &name = document->element[i]->name;
|
||||
for(unsigned i = 0; i < document.element.size(); i++) {
|
||||
string &name = document.element[i].name;
|
||||
if(strbegin(name, "?")) continue;
|
||||
if(strbegin(name, "!")) continue;
|
||||
if(++root_counter > 1) return false;
|
||||
@@ -241,25 +239,24 @@ inline bool xml_validate(xml_element *document) {
|
||||
return true;
|
||||
}
|
||||
|
||||
inline xml_element* xml_parse(const char *data) {
|
||||
xml_element *self = new xml_element;
|
||||
inline xml_element xml_parse(const char *data) {
|
||||
xml_element self;
|
||||
|
||||
try {
|
||||
while(*data) {
|
||||
xml_element *elem = new xml_element;
|
||||
if(elem->parse_body(data) == false) {
|
||||
delete elem;
|
||||
xml_element node;
|
||||
if(node.parse_body(data) == false) {
|
||||
break;
|
||||
} else {
|
||||
self->element.add(elem);
|
||||
self.element.append(node);
|
||||
}
|
||||
}
|
||||
|
||||
if(xml_validate(self) == false) throw "...";
|
||||
return self;
|
||||
} catch(const char*) {
|
||||
delete self;
|
||||
return 0;
|
||||
xml_element empty;
|
||||
return empty;
|
||||
}
|
||||
}
|
||||
|
||||
Regular → Executable
File renamed without changes.
Regular → Executable
+15
-1
@@ -6,9 +6,11 @@
|
||||
|
||||
#if defined(_WIN32)
|
||||
|
||||
#undef UNICODE
|
||||
#undef _WIN32_WINNT
|
||||
#define _WIN32_WINNT 0x0501
|
||||
#undef NOMINMAX
|
||||
#define UNICODE
|
||||
#define _WIN32_WINNT 0x0501
|
||||
#define NOMINMAX
|
||||
#include <windows.h>
|
||||
#undef interface
|
||||
@@ -62,9 +64,21 @@ namespace nall {
|
||||
delete[] buffer;
|
||||
}
|
||||
|
||||
utf8_t(const utf8_t&) = delete;
|
||||
utf8_t& operator=(const utf8_t&) = delete;
|
||||
|
||||
private:
|
||||
char *buffer;
|
||||
};
|
||||
|
||||
inline void utf8_args(int &argc, char **&argv) {
|
||||
wchar_t **wargv = CommandLineToArgvW(GetCommandLineW(), &argc);
|
||||
argv = new char*[argc];
|
||||
for(unsigned i = 0; i < argc; i++) {
|
||||
argv[i] = new char[_MAX_PATH];
|
||||
strcpy(argv[i], nall::utf8_t(wargv[i]));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif //if defined(_WIN32)
|
||||
Regular → Executable
+16
-18
@@ -1,29 +1,18 @@
|
||||
#ifndef NALL_UTILITY_HPP
|
||||
#define NALL_UTILITY_HPP
|
||||
|
||||
#include <nall/traits.hpp>
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
|
||||
namespace nall {
|
||||
template<typename T> struct identity {
|
||||
typedef T type;
|
||||
};
|
||||
|
||||
template<typename T> typename remove_reference<T>::type&& move(T &&value) {
|
||||
return value;
|
||||
}
|
||||
|
||||
template<typename T> T&& forward(typename identity<T>::type &&value) {
|
||||
return value;
|
||||
}
|
||||
|
||||
template<bool C, typename T = bool> struct enable_if { typedef T type; };
|
||||
template<typename T> struct enable_if<false, T> {};
|
||||
template<typename C, typename T = bool> struct mp_enable_if : enable_if<C::value, T> {};
|
||||
|
||||
template<typename T> inline void swap(T &x, T &y) {
|
||||
T temp(move(x));
|
||||
x = move(y);
|
||||
y = move(temp);
|
||||
T temp(std::move(x));
|
||||
x = std::move(y);
|
||||
y = std::move(temp);
|
||||
}
|
||||
|
||||
template<typename T> struct base_from_member {
|
||||
@@ -31,9 +20,18 @@ namespace nall {
|
||||
base_from_member(T value_) : value(value_) {}
|
||||
};
|
||||
|
||||
template<typename T> inline T* allocate(size_t size, const T &value) {
|
||||
template<typename T> class optional {
|
||||
bool valid;
|
||||
T value;
|
||||
public:
|
||||
inline operator bool() const { return valid; }
|
||||
inline const T& operator()() const { if(!valid) throw; return value; }
|
||||
inline optional(bool valid, const T &value) : valid(valid), value(value) {}
|
||||
};
|
||||
|
||||
template<typename T> inline T* allocate(unsigned size, const T &value) {
|
||||
T *array = new T[size];
|
||||
for(size_t i = 0; i < size; i++) array[i] = value;
|
||||
for(unsigned i = 0; i < size; i++) array[i] = value;
|
||||
return array;
|
||||
}
|
||||
}
|
||||
Regular → Executable
+3
-3
@@ -1,9 +1,9 @@
|
||||
#ifndef NALL_VARINT_HPP
|
||||
#define NALL_VARINT_HPP
|
||||
|
||||
#include <type_traits>
|
||||
#include <nall/bit.hpp>
|
||||
#include <nall/static.hpp>
|
||||
#include <nall/traits.hpp>
|
||||
|
||||
namespace nall {
|
||||
template<unsigned bits> class uint_t {
|
||||
@@ -22,7 +22,7 @@ namespace nall {
|
||||
>::type
|
||||
>::type
|
||||
>::type T;
|
||||
static_assert<!is_void<T>::value> uint_assert;
|
||||
static_assert(!std::is_same<T, void>::value, "");
|
||||
T data;
|
||||
|
||||
public:
|
||||
@@ -63,7 +63,7 @@ namespace nall {
|
||||
>::type
|
||||
>::type
|
||||
>::type T;
|
||||
static_assert<!is_void<T>::value> int_assert;
|
||||
static_assert(!std::is_same<T, void>::value, "");
|
||||
T data;
|
||||
|
||||
public:
|
||||
Regular → Executable
+59
-13
@@ -3,10 +3,12 @@
|
||||
|
||||
#include <initializer_list>
|
||||
#include <new>
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
#include <nall/algorithm.hpp>
|
||||
#include <nall/bit.hpp>
|
||||
#include <nall/concept.hpp>
|
||||
#include <nall/traits.hpp>
|
||||
#include <nall/foreach.hpp>
|
||||
#include <nall/utility.hpp>
|
||||
|
||||
namespace nall {
|
||||
@@ -67,11 +69,31 @@ namespace nall {
|
||||
objectsize = newsize;
|
||||
}
|
||||
|
||||
void add(const T data) {
|
||||
void append(const T data) {
|
||||
if(objectsize + 1 > poolsize) reserve(objectsize + 1);
|
||||
new(pool + objectsize++) T(data);
|
||||
}
|
||||
|
||||
template<typename U> void insert(unsigned index, const U list) {
|
||||
linear_vector<T> merged;
|
||||
for(unsigned i = 0; i < index; i++) merged.append(pool[i]);
|
||||
foreach(item, list) merged.append(item);
|
||||
for(unsigned i = index; i < objectsize; i++) merged.append(pool[i]);
|
||||
operator=(merged);
|
||||
}
|
||||
|
||||
void insert(unsigned index, const T item) {
|
||||
insert(index, linear_vector<T>{ item });
|
||||
}
|
||||
|
||||
void remove(unsigned index, unsigned count = 1) {
|
||||
for(unsigned i = index; count + i < objectsize; i++) {
|
||||
pool[i] = pool[count + i];
|
||||
}
|
||||
if(count + index >= objectsize) resize(index); //every element >= index was removed
|
||||
else resize(objectsize - count);
|
||||
}
|
||||
|
||||
inline T& operator[](unsigned index) {
|
||||
if(index >= objectsize) resize(index + 1);
|
||||
return pool[index];
|
||||
@@ -86,11 +108,12 @@ namespace nall {
|
||||
inline linear_vector<T>& operator=(const linear_vector<T> &source) {
|
||||
reset();
|
||||
reserve(source.capacity());
|
||||
for(unsigned i = 0; i < source.size(); i++) add(source[i]);
|
||||
resize(source.size());
|
||||
for(unsigned i = 0; i < source.size(); i++) operator[](i) = source.operator[](i);
|
||||
return *this;
|
||||
}
|
||||
|
||||
linear_vector(const linear_vector<T> &source) {
|
||||
linear_vector(const linear_vector<T> &source) : pool(0), poolsize(0), objectsize(0) {
|
||||
operator=(source);
|
||||
}
|
||||
|
||||
@@ -101,11 +124,12 @@ namespace nall {
|
||||
poolsize = source.poolsize;
|
||||
objectsize = source.objectsize;
|
||||
source.pool = 0;
|
||||
source.reset();
|
||||
return *this;
|
||||
}
|
||||
|
||||
linear_vector(linear_vector<T> &&source) {
|
||||
operator=(move(source));
|
||||
linear_vector(linear_vector<T> &&source) : pool(0), poolsize(0), objectsize(0) {
|
||||
operator=(std::move(source));
|
||||
}
|
||||
|
||||
//construction
|
||||
@@ -113,7 +137,7 @@ namespace nall {
|
||||
}
|
||||
|
||||
linear_vector(std::initializer_list<T> list) : pool(0), poolsize(0), objectsize(0) {
|
||||
for(const T *p = list.begin(); p != list.end(); ++p) add(*p);
|
||||
for(const T *p = list.begin(); p != list.end(); ++p) append(*p);
|
||||
}
|
||||
|
||||
~linear_vector() {
|
||||
@@ -173,11 +197,31 @@ namespace nall {
|
||||
objectsize = newsize;
|
||||
}
|
||||
|
||||
void add(const T data) {
|
||||
void append(const T data) {
|
||||
if(objectsize + 1 > poolsize) reserve(objectsize + 1);
|
||||
pool[objectsize++] = new T(data);
|
||||
}
|
||||
|
||||
template<typename U> void insert(unsigned index, const U list) {
|
||||
pointer_vector<T> merged;
|
||||
for(unsigned i = 0; i < index; i++) merged.append(*pool[i]);
|
||||
foreach(item, list) merged.append(item);
|
||||
for(unsigned i = index; i < objectsize; i++) merged.append(*pool[i]);
|
||||
operator=(merged);
|
||||
}
|
||||
|
||||
void insert(unsigned index, const T item) {
|
||||
insert(index, pointer_vector<T>{ item });
|
||||
}
|
||||
|
||||
void remove(unsigned index, unsigned count = 1) {
|
||||
for(unsigned i = index; count + i < objectsize; i++) {
|
||||
*pool[i] = *pool[count + i];
|
||||
}
|
||||
if(count + index >= objectsize) resize(index); //every element >= index was removed
|
||||
else resize(objectsize - count);
|
||||
}
|
||||
|
||||
inline T& operator[](unsigned index) {
|
||||
if(index >= objectsize) resize(index + 1);
|
||||
if(!pool[index]) pool[index] = new T;
|
||||
@@ -193,11 +237,12 @@ namespace nall {
|
||||
inline pointer_vector<T>& operator=(const pointer_vector<T> &source) {
|
||||
reset();
|
||||
reserve(source.capacity());
|
||||
for(unsigned i = 0; i < source.size(); i++) add(source[i]);
|
||||
resize(source.size());
|
||||
for(unsigned i = 0; i < source.size(); i++) operator[](i) = source.operator[](i);
|
||||
return *this;
|
||||
}
|
||||
|
||||
pointer_vector(const pointer_vector<T> &source) {
|
||||
pointer_vector(const pointer_vector<T> &source) : pool(0), poolsize(0), objectsize(0) {
|
||||
operator=(source);
|
||||
}
|
||||
|
||||
@@ -208,11 +253,12 @@ namespace nall {
|
||||
poolsize = source.poolsize;
|
||||
objectsize = source.objectsize;
|
||||
source.pool = 0;
|
||||
source.reset();
|
||||
return *this;
|
||||
}
|
||||
|
||||
pointer_vector(pointer_vector<T> &&source) {
|
||||
operator=(move(source));
|
||||
pointer_vector(pointer_vector<T> &&source) : pool(0), poolsize(0), objectsize(0) {
|
||||
operator=(std::move(source));
|
||||
}
|
||||
|
||||
//construction
|
||||
@@ -220,7 +266,7 @@ namespace nall {
|
||||
}
|
||||
|
||||
pointer_vector(std::initializer_list<T> list) : pool(0), poolsize(0), objectsize(0) {
|
||||
for(const T *p = list.begin(); p != list.end(); ++p) add(*p);
|
||||
for(const T *p = list.begin(); p != list.end(); ++p) append(*p);
|
||||
}
|
||||
|
||||
~pointer_vector() {
|
||||
@@ -0,0 +1 @@
|
||||
*
|
||||
@@ -0,0 +1 @@
|
||||
*
|
||||
Executable
+12
@@ -0,0 +1,12 @@
|
||||
static void Button_tick(Button *self) {
|
||||
if(self->onTick) self->onTick();
|
||||
}
|
||||
|
||||
void Button::create(Window &parent, unsigned x, unsigned y, unsigned width, unsigned height, const char *text) {
|
||||
object->widget = gtk_button_new_with_label(text);
|
||||
gtk_widget_set_size_request(object->widget, width, height);
|
||||
g_signal_connect_swapped(G_OBJECT(object->widget), "clicked", G_CALLBACK(Button_tick), (gpointer)this);
|
||||
if(parent.window->defaultFont) setFont(*parent.window->defaultFont);
|
||||
gtk_fixed_put(GTK_FIXED(parent.object->formContainer), object->widget, x, y);
|
||||
gtk_widget_show(object->widget);
|
||||
}
|
||||
Executable
+58
@@ -0,0 +1,58 @@
|
||||
static void Canvas_expose(Canvas *self) {
|
||||
uint32_t *rgb = self->canvas->bufferRGB;
|
||||
uint32_t *bgr = self->canvas->bufferBGR;
|
||||
for(unsigned y = self->object->widget->allocation.height; y; y--) {
|
||||
for(unsigned x = self->object->widget->allocation.width; x; x--) {
|
||||
uint32_t pixel = *rgb++;
|
||||
*bgr++ = ((pixel << 16) & 0xff0000) | (pixel & 0x00ff00) | ((pixel >> 16) & 0x0000ff);
|
||||
}
|
||||
}
|
||||
|
||||
gdk_draw_rgb_32_image(
|
||||
self->object->widget->window,
|
||||
self->object->widget->style->fg_gc[GTK_WIDGET_STATE(self->object->widget)],
|
||||
0, 0, self->object->widget->allocation.width, self->object->widget->allocation.height,
|
||||
GDK_RGB_DITHER_NONE, (guchar*)self->canvas->bufferBGR, self->canvas->pitch
|
||||
);
|
||||
}
|
||||
|
||||
void Canvas::create(Window &parent, unsigned x, unsigned y, unsigned width, unsigned height) {
|
||||
canvas->bufferRGB = new uint32_t[width * height]();
|
||||
canvas->bufferBGR = new uint32_t[width * height]();
|
||||
canvas->pitch = width * sizeof(uint32_t);
|
||||
|
||||
object->widget = gtk_drawing_area_new();
|
||||
GdkColor color;
|
||||
color.pixel = color.red = color.green = color.blue = 0;
|
||||
gtk_widget_modify_bg(object->widget, GTK_STATE_NORMAL, &color);
|
||||
gtk_widget_set_double_buffered(object->widget, false);
|
||||
gtk_widget_add_events(object->widget, GDK_EXPOSURE_MASK);
|
||||
gtk_widget_set_size_request(object->widget, width, height);
|
||||
g_signal_connect_swapped(G_OBJECT(object->widget), "expose_event", G_CALLBACK(Canvas_expose), (gpointer)this);
|
||||
gtk_fixed_put(GTK_FIXED(parent.object->formContainer), object->widget, x, y);
|
||||
gtk_widget_show(object->widget);
|
||||
}
|
||||
|
||||
uint32_t* Canvas::buffer() {
|
||||
return canvas->bufferRGB;
|
||||
}
|
||||
|
||||
void Canvas::redraw() {
|
||||
GdkRectangle rect;
|
||||
rect.x = 0;
|
||||
rect.y = 0;
|
||||
rect.width = object->widget->allocation.width;
|
||||
rect.height = object->widget->allocation.height;
|
||||
gdk_window_invalidate_rect(object->widget->window, &rect, true);
|
||||
}
|
||||
|
||||
Canvas::Canvas() {
|
||||
canvas = new Canvas::Data;
|
||||
canvas->bufferRGB = 0;
|
||||
canvas->bufferBGR = 0;
|
||||
}
|
||||
|
||||
Canvas::~Canvas() {
|
||||
if(canvas->bufferRGB) delete[] canvas->bufferRGB;
|
||||
if(canvas->bufferBGR) delete[] canvas->bufferBGR;
|
||||
}
|
||||
Executable
+22
@@ -0,0 +1,22 @@
|
||||
static void CheckBox_tick(CheckBox *self) {
|
||||
if(self->onTick && self->object->locked == false) self->onTick();
|
||||
}
|
||||
|
||||
void CheckBox::create(Window &parent, unsigned x, unsigned y, unsigned width, unsigned height, const char *text) {
|
||||
object->widget = gtk_check_button_new_with_label(text);
|
||||
gtk_widget_set_size_request(object->widget, width, height);
|
||||
g_signal_connect_swapped(G_OBJECT(object->widget), "toggled", G_CALLBACK(CheckBox_tick), (gpointer)this);
|
||||
if(parent.window->defaultFont) setFont(*parent.window->defaultFont);
|
||||
gtk_fixed_put(GTK_FIXED(parent.object->formContainer), object->widget, x, y);
|
||||
gtk_widget_show(object->widget);
|
||||
}
|
||||
|
||||
bool CheckBox::checked() {
|
||||
return gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(object->widget));
|
||||
}
|
||||
|
||||
void CheckBox::setChecked(bool checked) {
|
||||
object->locked = true;
|
||||
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(object->widget), checked);
|
||||
object->locked = false;
|
||||
}
|
||||
Executable
+47
@@ -0,0 +1,47 @@
|
||||
void ComboBox_change(ComboBox *self) {
|
||||
if(self->object->locked == false && self->onChange) self->onChange();
|
||||
}
|
||||
|
||||
void ComboBox::create(Window &parent, unsigned x, unsigned y, unsigned width, unsigned height, const char *text) {
|
||||
object->widget = gtk_combo_box_new_text();
|
||||
gtk_widget_set_size_request(object->widget, width, height);
|
||||
g_signal_connect_swapped(G_OBJECT(object->widget), "changed", G_CALLBACK(ComboBox_change), (gpointer)this);
|
||||
|
||||
if(*text) {
|
||||
lstring list;
|
||||
list.split("\n", text);
|
||||
foreach(item, list) addItem(item);
|
||||
}
|
||||
|
||||
if(parent.window->defaultFont) setFont(*parent.window->defaultFont);
|
||||
gtk_fixed_put(GTK_FIXED(parent.object->formContainer), object->widget, x, y);
|
||||
gtk_widget_show(object->widget);
|
||||
}
|
||||
|
||||
void ComboBox::reset() {
|
||||
object->locked = true;
|
||||
for(signed i = counter - 1; i >= 0; i--) {
|
||||
gtk_combo_box_remove_text(GTK_COMBO_BOX(object->widget), i);
|
||||
}
|
||||
object->locked = false;
|
||||
counter = 0;
|
||||
}
|
||||
|
||||
void ComboBox::addItem(const char *text) {
|
||||
gtk_combo_box_append_text(GTK_COMBO_BOX(object->widget), text);
|
||||
if(counter++ == 0) setSelection(0);
|
||||
}
|
||||
|
||||
unsigned ComboBox::selection() {
|
||||
return gtk_combo_box_get_active(GTK_COMBO_BOX(object->widget));
|
||||
}
|
||||
|
||||
void ComboBox::setSelection(unsigned item) {
|
||||
object->locked = true;
|
||||
gtk_combo_box_set_active(GTK_COMBO_BOX(object->widget), item);
|
||||
object->locked = false;
|
||||
}
|
||||
|
||||
ComboBox::ComboBox() {
|
||||
counter = 0;
|
||||
}
|
||||
Executable
+48
@@ -0,0 +1,48 @@
|
||||
static void EditBox_change(EditBox *self) {
|
||||
if(self->object->locked == false && self->onChange) self->onChange();
|
||||
}
|
||||
|
||||
void EditBox::create(Window &parent, unsigned x, unsigned y, unsigned width, unsigned height, const char *text) {
|
||||
object->widget = gtk_scrolled_window_new(0, 0);
|
||||
gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(object->widget), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
|
||||
gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(object->widget), GTK_SHADOW_ETCHED_IN);
|
||||
gtk_widget_set_size_request(object->widget, width, height);
|
||||
object->subWidget = gtk_text_view_new();
|
||||
gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW(object->subWidget), GTK_WRAP_WORD_CHAR);
|
||||
gtk_container_add(GTK_CONTAINER(object->widget), object->subWidget);
|
||||
object->textBuffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(object->subWidget));
|
||||
gtk_text_buffer_set_text(object->textBuffer, text, -1);
|
||||
g_signal_connect_swapped(G_OBJECT(object->textBuffer), "changed", G_CALLBACK(EditBox_change), (gpointer)this);
|
||||
if(parent.window->defaultFont) setFont(*parent.window->defaultFont);
|
||||
gtk_fixed_put(GTK_FIXED(parent.object->formContainer), object->widget, x, y);
|
||||
gtk_widget_show(object->subWidget);
|
||||
gtk_widget_show(object->widget);
|
||||
}
|
||||
|
||||
void EditBox::setFocused() {
|
||||
gtk_widget_grab_focus(object->subWidget);
|
||||
}
|
||||
|
||||
void EditBox::setEditable(bool editable) {
|
||||
gtk_text_view_set_editable(GTK_TEXT_VIEW(object->subWidget), editable);
|
||||
}
|
||||
|
||||
void EditBox::setWordWrap(bool wordWrap) {
|
||||
gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW(object->subWidget), wordWrap ? GTK_WRAP_WORD_CHAR : GTK_WRAP_NONE);
|
||||
}
|
||||
|
||||
string EditBox::text() {
|
||||
GtkTextIter start, end;
|
||||
gtk_text_buffer_get_start_iter(object->textBuffer, &start);
|
||||
gtk_text_buffer_get_end_iter(object->textBuffer, &end);
|
||||
char *temp = gtk_text_buffer_get_text(object->textBuffer, &start, &end, true);
|
||||
string text = temp;
|
||||
g_free(temp);
|
||||
return text;
|
||||
}
|
||||
|
||||
void EditBox::setText(const char *text) {
|
||||
object->locked = true;
|
||||
gtk_text_buffer_set_text(object->textBuffer, text, -1);
|
||||
object->locked = false;
|
||||
}
|
||||
Executable
+18
@@ -0,0 +1,18 @@
|
||||
bool Font::create(const char *name, unsigned size, Font::Style style) {
|
||||
font->font = pango_font_description_new();
|
||||
pango_font_description_set_family(font->font, name);
|
||||
pango_font_description_set_size(font->font, size * PANGO_SCALE);
|
||||
pango_font_description_set_style(font->font, (style & Style::Italic) == Style::Italic ? PANGO_STYLE_OBLIQUE : PANGO_STYLE_NORMAL);
|
||||
pango_font_description_set_weight(font->font, (style & Style::Bold) == Style::Bold ? PANGO_WEIGHT_BOLD : PANGO_WEIGHT_NORMAL);
|
||||
return true;
|
||||
}
|
||||
|
||||
Font::Font() {
|
||||
font = new Font::Data;
|
||||
font->font = 0;
|
||||
}
|
||||
|
||||
Font::~Font() {
|
||||
if(font->font) pango_font_description_free(font->font);
|
||||
delete font;
|
||||
}
|
||||
Executable
+191
@@ -0,0 +1,191 @@
|
||||
#include <unistd.h>
|
||||
#include <pwd.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#define None X11None
|
||||
#define Window X11Window
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
#include <gdk/gdkx.h>
|
||||
#include <cairo.h>
|
||||
#include <gdk/gdkkeysyms.h>
|
||||
|
||||
#undef None
|
||||
#undef Window
|
||||
|
||||
using namespace nall;
|
||||
|
||||
namespace phoenix {
|
||||
|
||||
#include "object.cpp"
|
||||
#include "font.cpp"
|
||||
#include "menu.cpp"
|
||||
#include "widget.cpp"
|
||||
#include "window.cpp"
|
||||
#include "button.cpp"
|
||||
#include "canvas.cpp"
|
||||
#include "checkbox.cpp"
|
||||
#include "combobox.cpp"
|
||||
#include "editbox.cpp"
|
||||
#include "horizontalslider.cpp"
|
||||
#include "label.cpp"
|
||||
#include "listbox.cpp"
|
||||
#include "progressbar.cpp"
|
||||
#include "radiobox.cpp"
|
||||
#include "textbox.cpp"
|
||||
#include "verticalslider.cpp"
|
||||
#include "viewport.cpp"
|
||||
#include "messagewindow.cpp"
|
||||
|
||||
OS &os = OS::handle();
|
||||
Window Window::None;
|
||||
|
||||
OS& OS::handle() {
|
||||
static OS os;
|
||||
return os;
|
||||
}
|
||||
|
||||
bool OS::pending() {
|
||||
return gtk_events_pending();
|
||||
}
|
||||
|
||||
void OS::run() {
|
||||
while(pending()) gtk_main_iteration_do(false);
|
||||
}
|
||||
|
||||
void OS::main() {
|
||||
gtk_main();
|
||||
}
|
||||
|
||||
void OS::quit() {
|
||||
gtk_main_quit();
|
||||
}
|
||||
|
||||
unsigned OS::desktopWidth() {
|
||||
return gdk_screen_get_width(gdk_screen_get_default());
|
||||
}
|
||||
|
||||
unsigned OS::desktopHeight() {
|
||||
return gdk_screen_get_height(gdk_screen_get_default());
|
||||
}
|
||||
|
||||
string OS::folderSelect(Window &parent, const char *path) {
|
||||
string name;
|
||||
|
||||
GtkWidget *dialog = gtk_file_chooser_dialog_new(
|
||||
"Select Folder",
|
||||
&parent != &Window::None ? GTK_WINDOW(parent.object->widget) : (GtkWindow*)0,
|
||||
GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER,
|
||||
GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
|
||||
GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT,
|
||||
(const gchar*)0
|
||||
);
|
||||
|
||||
if(path) gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(dialog), path);
|
||||
|
||||
if(gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
|
||||
char *temp = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog));
|
||||
name = temp;
|
||||
g_free(temp);
|
||||
}
|
||||
|
||||
gtk_widget_destroy(dialog);
|
||||
return name;
|
||||
}
|
||||
|
||||
string OS::fileOpen(Window &parent, const char *filter, const char *path) {
|
||||
string name;
|
||||
|
||||
GtkWidget *dialog = gtk_file_chooser_dialog_new(
|
||||
"Open File",
|
||||
&parent != &Window::None ? GTK_WINDOW(parent.object->widget) : (GtkWindow*)0,
|
||||
GTK_FILE_CHOOSER_ACTION_OPEN,
|
||||
GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
|
||||
GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT,
|
||||
(const gchar*)0
|
||||
);
|
||||
|
||||
if(path) gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(dialog), path);
|
||||
|
||||
lstring list;
|
||||
list.split("\n", filter);
|
||||
foreach(item, list) {
|
||||
lstring part;
|
||||
part.split("\t", item);
|
||||
GtkFileFilter *filter = gtk_file_filter_new();
|
||||
gtk_file_filter_set_name(filter, string(part[0], " (", part[1], ")"));
|
||||
lstring patterns;
|
||||
patterns.split(",", part[1]);
|
||||
foreach(pattern, patterns) gtk_file_filter_add_pattern(filter, pattern);
|
||||
gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(dialog), filter);
|
||||
}
|
||||
|
||||
if(gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
|
||||
char *temp = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog));
|
||||
name = temp;
|
||||
g_free(temp);
|
||||
}
|
||||
|
||||
gtk_widget_destroy(dialog);
|
||||
return name;
|
||||
}
|
||||
|
||||
string OS::fileSave(Window &parent, const char *filter, const char *path) {
|
||||
string name;
|
||||
|
||||
GtkWidget *dialog = gtk_file_chooser_dialog_new(
|
||||
"Save File",
|
||||
&parent != &Window::None ? GTK_WINDOW(parent.object->widget) : (GtkWindow*)0,
|
||||
GTK_FILE_CHOOSER_ACTION_SAVE,
|
||||
GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
|
||||
GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT,
|
||||
(const gchar*)0
|
||||
);
|
||||
|
||||
if(path) gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(dialog), path);
|
||||
|
||||
lstring list;
|
||||
list.split("\n", filter);
|
||||
foreach(item, list) {
|
||||
lstring part;
|
||||
part.split("\t", item);
|
||||
GtkFileFilter *filter = gtk_file_filter_new();
|
||||
gtk_file_filter_set_name(filter, string(part[0], " (", part[1], ")"));
|
||||
lstring patterns;
|
||||
patterns.split(",", part[1]);
|
||||
foreach(pattern, patterns) gtk_file_filter_add_pattern(filter, pattern);
|
||||
gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(dialog), filter);
|
||||
}
|
||||
|
||||
if(gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
|
||||
char *temp = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog));
|
||||
name = temp;
|
||||
g_free(temp);
|
||||
}
|
||||
|
||||
gtk_widget_destroy(dialog);
|
||||
return name;
|
||||
}
|
||||
|
||||
OS::OS() {
|
||||
os = new OS::Data;
|
||||
int argc = 1;
|
||||
char *argv[2];
|
||||
argv[0] = new char[8];
|
||||
argv[1] = 0;
|
||||
strcpy(argv[0], "phoenix");
|
||||
char **argvp = argv;
|
||||
gtk_init(&argc, &argvp);
|
||||
|
||||
gtk_rc_parse_string(
|
||||
"style \"phoenix-gtk\"\n"
|
||||
"{\n"
|
||||
" GtkComboBox::appears-as-list = 1\n"
|
||||
" GtkTreeView::vertical-separator = 0\n"
|
||||
"}\n"
|
||||
"class \"GtkComboBox\" style \"phoenix-gtk\"\n"
|
||||
"class \"GtkTreeView\" style \"phoenix-gtk\"\n"
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
Executable
+250
@@ -0,0 +1,250 @@
|
||||
namespace phoenix {
|
||||
|
||||
struct Window;
|
||||
|
||||
struct Object {
|
||||
Object();
|
||||
Object& operator=(const Object&) = delete;
|
||||
Object(const Object&) = delete;
|
||||
//private:
|
||||
virtual void unused();
|
||||
struct Data;
|
||||
Data *object;
|
||||
};
|
||||
|
||||
struct Font : Object {
|
||||
enum class Style : unsigned {
|
||||
None = 0,
|
||||
Bold = 1,
|
||||
Italic = 2,
|
||||
};
|
||||
bool create(const char *name, unsigned size, Font::Style style = Style::None);
|
||||
Font();
|
||||
~Font();
|
||||
//private:
|
||||
struct Data;
|
||||
Data *font;
|
||||
};
|
||||
|
||||
inline Font::Style operator|(Font::Style a, Font::Style b) { return (Font::Style)((unsigned)a | (unsigned)b); }
|
||||
inline Font::Style operator&(Font::Style a, Font::Style b) { return (Font::Style)((unsigned)a & (unsigned)b); }
|
||||
|
||||
struct Action : Object {
|
||||
void setFont(Font &font);
|
||||
bool visible();
|
||||
void setVisible(bool visible = true);
|
||||
bool enabled();
|
||||
void setEnabled(bool enabled = true);
|
||||
};
|
||||
|
||||
struct Menu : Action {
|
||||
void create(Window &parent, const char *text);
|
||||
void create(Menu &parent, const char *text);
|
||||
};
|
||||
|
||||
struct MenuSeparator : Action {
|
||||
void create(Menu &parent);
|
||||
};
|
||||
|
||||
struct MenuItem : Action {
|
||||
nall::function<void ()> onTick;
|
||||
void create(Menu &parent, const char *text);
|
||||
};
|
||||
|
||||
struct MenuCheckItem : Action {
|
||||
nall::function<void ()> onTick;
|
||||
void create(Menu &parent, const char *text);
|
||||
bool checked();
|
||||
void setChecked(bool checked = true);
|
||||
};
|
||||
|
||||
struct MenuRadioItem : Action {
|
||||
nall::function<void ()> onTick;
|
||||
void create(Menu &parent, const char *text);
|
||||
void create(MenuRadioItem &parent, const char *text);
|
||||
bool checked();
|
||||
void setChecked();
|
||||
private:
|
||||
MenuRadioItem *first;
|
||||
};
|
||||
|
||||
struct Widget : Object {
|
||||
virtual void setFont(Font &font);
|
||||
bool visible();
|
||||
void setVisible(bool visible = true);
|
||||
bool enabled();
|
||||
void setEnabled(bool enabled = true);
|
||||
virtual bool focused();
|
||||
virtual void setFocused();
|
||||
};
|
||||
|
||||
struct Window : Widget {
|
||||
static Window None;
|
||||
nall::function<bool ()> onClose;
|
||||
void create(unsigned x, unsigned y, unsigned width, unsigned height, const char *text = "");
|
||||
bool focused();
|
||||
void setFocused();
|
||||
void setGeometry(unsigned x, unsigned y, unsigned width, unsigned height);
|
||||
void setDefaultFont(Font &font);
|
||||
void setFont(Font &font);
|
||||
void setBackgroundColor(uint8_t red, uint8_t green, uint8_t blue);
|
||||
void setTitle(const char *text);
|
||||
void setStatusText(const char *text);
|
||||
void setMenuVisible(bool visible = true);
|
||||
void setStatusVisible(bool visible = true);
|
||||
Window();
|
||||
//private:
|
||||
struct Data;
|
||||
Data *window;
|
||||
};
|
||||
|
||||
struct Button : Widget {
|
||||
nall::function<void ()> onTick;
|
||||
void create(Window &parent, unsigned x, unsigned y, unsigned width, unsigned height, const char *text = "");
|
||||
};
|
||||
|
||||
struct Canvas : Widget {
|
||||
void create(Window &parent, unsigned x, unsigned y, unsigned width, unsigned height);
|
||||
uint32_t* buffer();
|
||||
void redraw();
|
||||
Canvas();
|
||||
~Canvas();
|
||||
//private:
|
||||
struct Data;
|
||||
Data *canvas;
|
||||
};
|
||||
|
||||
struct CheckBox : Widget {
|
||||
nall::function<void ()> onTick;
|
||||
void create(Window &parent, unsigned x, unsigned y, unsigned width, unsigned height, const char *text = "");
|
||||
bool checked();
|
||||
void setChecked(bool checked = true);
|
||||
};
|
||||
|
||||
struct ComboBox : Widget {
|
||||
nall::function<void ()> onChange;
|
||||
void create(Window &parent, unsigned x, unsigned y, unsigned width, unsigned height, const char *text = "");
|
||||
void reset();
|
||||
void addItem(const char *text);
|
||||
unsigned selection();
|
||||
void setSelection(unsigned item);
|
||||
ComboBox();
|
||||
private:
|
||||
unsigned counter;
|
||||
};
|
||||
|
||||
struct EditBox : Widget {
|
||||
nall::function<void ()> onChange;
|
||||
void create(Window &parent, unsigned x, unsigned y, unsigned width, unsigned height, const char *text = "");
|
||||
void setFocused();
|
||||
void setEditable(bool editable = true);
|
||||
void setWordWrap(bool wordWrap = true);
|
||||
nall::string text();
|
||||
void setText(const char *text);
|
||||
};
|
||||
|
||||
struct HorizontalSlider : Widget {
|
||||
nall::function<void ()> onChange;
|
||||
void create(Window &parent, unsigned x, unsigned y, unsigned width, unsigned height, unsigned length);
|
||||
unsigned position();
|
||||
void setPosition(unsigned position);
|
||||
};
|
||||
|
||||
struct Label : Widget {
|
||||
void create(Window &parent, unsigned x, unsigned y, unsigned width, unsigned height, const char *text = "");
|
||||
void setText(const char *text);
|
||||
};
|
||||
|
||||
struct ListBox : Widget {
|
||||
nall::function<void ()> onActivate;
|
||||
nall::function<void ()> onChange;
|
||||
void create(Window &parent, unsigned x, unsigned y, unsigned width, unsigned height, const char *text = "");
|
||||
void setFocused();
|
||||
void setHeaderVisible(bool headerVisible = true);
|
||||
void setFont(Font &font);
|
||||
void reset();
|
||||
void resizeColumnsToContent();
|
||||
void addItem(const char *text);
|
||||
void setItem(unsigned row, const char *text);
|
||||
nall::optional<unsigned> selection();
|
||||
void setSelection(unsigned row);
|
||||
ListBox();
|
||||
//private:
|
||||
struct Data;
|
||||
Data *listBox;
|
||||
};
|
||||
|
||||
struct ProgressBar : Widget {
|
||||
void create(Window &parent, unsigned x, unsigned y, unsigned width, unsigned height);
|
||||
void setProgress(unsigned progress);
|
||||
};
|
||||
|
||||
struct RadioBox : Widget {
|
||||
nall::function<void ()> onTick;
|
||||
void create(Window &parent, unsigned x, unsigned y, unsigned width, unsigned height, const char *text = "");
|
||||
void create(RadioBox &parent, unsigned x, unsigned y, unsigned width, unsigned height, const char *text = "");
|
||||
bool checked();
|
||||
void setChecked();
|
||||
private:
|
||||
RadioBox *first;
|
||||
};
|
||||
|
||||
struct TextBox : Widget {
|
||||
nall::function<void ()> onChange;
|
||||
void create(Window &parent, unsigned x, unsigned y, unsigned width, unsigned height, const char *text = "");
|
||||
void setEditable(bool editable = true);
|
||||
nall::string text();
|
||||
void setText(const char *text);
|
||||
};
|
||||
|
||||
struct VerticalSlider : Widget {
|
||||
nall::function<void ()> onChange;
|
||||
void create(Window &parent, unsigned x, unsigned y, unsigned width, unsigned height, unsigned length);
|
||||
unsigned position();
|
||||
void setPosition(unsigned position);
|
||||
};
|
||||
|
||||
struct Viewport : Widget {
|
||||
void create(Window &parent, unsigned x, unsigned y, unsigned width, unsigned height);
|
||||
uintptr_t handle();
|
||||
};
|
||||
|
||||
struct MessageWindow : Object {
|
||||
enum class Buttons : unsigned {
|
||||
Ok,
|
||||
OkCancel,
|
||||
YesNo,
|
||||
};
|
||||
enum class Response : unsigned {
|
||||
Ok,
|
||||
Cancel,
|
||||
Yes,
|
||||
No,
|
||||
};
|
||||
static Response information(Window &parent, const char *text, Buttons = Buttons::Ok);
|
||||
static Response question(Window &parent, const char *text, Buttons = Buttons::YesNo);
|
||||
static Response warning(Window &parent, const char *text, Buttons = Buttons::Ok);
|
||||
static Response critical(Window &parent, const char *text, Buttons = Buttons::Ok);
|
||||
};
|
||||
|
||||
struct OS : Object {
|
||||
bool pending();
|
||||
void run();
|
||||
void main();
|
||||
void quit();
|
||||
unsigned desktopWidth();
|
||||
unsigned desktopHeight();
|
||||
nall::string folderSelect(Window &parent, const char *path = "");
|
||||
nall::string fileOpen(Window &parent, const char *filter, const char *path = "");
|
||||
nall::string fileSave(Window &parent, const char *filter, const char *path = "");
|
||||
//private:
|
||||
static OS& handle();
|
||||
struct Data;
|
||||
Data *os;
|
||||
private:
|
||||
OS();
|
||||
};
|
||||
|
||||
extern OS &os;
|
||||
|
||||
}
|
||||
Executable
+24
@@ -0,0 +1,24 @@
|
||||
static void HorizontalSlider_change(HorizontalSlider *self) {
|
||||
if(self->object->position == self->position()) return;
|
||||
self->object->position = self->position();
|
||||
if(self->onChange) self->onChange();
|
||||
}
|
||||
|
||||
void HorizontalSlider::create(Window &parent, unsigned x, unsigned y, unsigned width, unsigned height, unsigned length) {
|
||||
object->position = 0;
|
||||
length += (length == 0);
|
||||
object->widget = gtk_hscale_new_with_range(0, length - 1, 1);
|
||||
gtk_scale_set_draw_value(GTK_SCALE(object->widget), false);
|
||||
gtk_widget_set_size_request(object->widget, width, height);
|
||||
g_signal_connect_swapped(G_OBJECT(object->widget), "value-changed", G_CALLBACK(HorizontalSlider_change), (gpointer)this);
|
||||
gtk_fixed_put(GTK_FIXED(parent.object->formContainer), object->widget, x, y);
|
||||
gtk_widget_show(object->widget);
|
||||
}
|
||||
|
||||
unsigned HorizontalSlider::position() {
|
||||
return (unsigned)gtk_range_get_value(GTK_RANGE(object->widget));
|
||||
}
|
||||
|
||||
void HorizontalSlider::setPosition(unsigned position) {
|
||||
gtk_range_set_value(GTK_RANGE(object->widget), position);
|
||||
}
|
||||
Executable
+12
@@ -0,0 +1,12 @@
|
||||
void Label::create(Window &parent, unsigned x, unsigned y, unsigned width, unsigned height, const char *text) {
|
||||
object->widget = gtk_label_new(text);
|
||||
gtk_misc_set_alignment(GTK_MISC(object->widget), 0.0, 0.5);
|
||||
gtk_widget_set_size_request(object->widget, width, height);
|
||||
if(parent.window->defaultFont) setFont(*parent.window->defaultFont);
|
||||
gtk_fixed_put(GTK_FIXED(parent.object->formContainer), object->widget, x, y);
|
||||
gtk_widget_show(object->widget);
|
||||
}
|
||||
|
||||
void Label::setText(const char *text) {
|
||||
gtk_label_set_text(GTK_LABEL(object->widget), text);
|
||||
}
|
||||
Executable
+154
@@ -0,0 +1,154 @@
|
||||
static void ListBox_change(ListBox *self) {
|
||||
signed selection = -1;
|
||||
if(auto position = self->selection()) selection = position();
|
||||
if(selection == self->listBox->selection) return;
|
||||
self->listBox->selection = selection;
|
||||
if(self->onChange) self->onChange();
|
||||
}
|
||||
|
||||
static void ListBox_activate(ListBox *self) {
|
||||
signed selection = -1;
|
||||
if(auto position = self->selection()) selection = position();
|
||||
self->listBox->selection = selection;
|
||||
if(self->onActivate) self->onActivate();
|
||||
}
|
||||
|
||||
void ListBox::create(Window &parent, unsigned x, unsigned y, unsigned width, unsigned height, const char *text) {
|
||||
listBox->selection = -1;
|
||||
object->widget = gtk_scrolled_window_new(0, 0);
|
||||
gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(object->widget), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
|
||||
gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(object->widget), GTK_SHADOW_ETCHED_IN);
|
||||
gtk_widget_set_size_request(object->widget, width, height);
|
||||
|
||||
lstring list;
|
||||
list.split("\t", text);
|
||||
|
||||
GType *v = (GType*)malloc(list.size() * sizeof(GType));
|
||||
for(unsigned i = 0; i < list.size(); i++) v[i] = G_TYPE_STRING;
|
||||
listBox->store = gtk_list_store_newv(list.size(), v);
|
||||
free(v);
|
||||
|
||||
object->subWidget = gtk_tree_view_new_with_model(GTK_TREE_MODEL(listBox->store));
|
||||
gtk_container_add(GTK_CONTAINER(object->widget), object->subWidget);
|
||||
g_object_unref(G_OBJECT(listBox->store));
|
||||
|
||||
//alternate color of each row if there is more than one column
|
||||
gtk_tree_view_set_rules_hint(GTK_TREE_VIEW(object->subWidget), list.size() >= 2);
|
||||
gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(object->subWidget), false);
|
||||
|
||||
for(unsigned i = 0; i < list.size(); i++) {
|
||||
listBox->column[i].renderer = gtk_cell_renderer_text_new();
|
||||
listBox->column[i].column = gtk_tree_view_column_new_with_attributes(
|
||||
list[i], listBox->column[i].renderer, "text", i, (void*)0
|
||||
);
|
||||
listBox->column[i].label = gtk_label_new(list[i]);
|
||||
gtk_tree_view_column_set_widget(GTK_TREE_VIEW_COLUMN(listBox->column[i].column), listBox->column[i].label);
|
||||
gtk_tree_view_append_column(GTK_TREE_VIEW(object->subWidget), listBox->column[i].column);
|
||||
gtk_widget_show(listBox->column[i].label);
|
||||
}
|
||||
|
||||
g_signal_connect_swapped(G_OBJECT(object->subWidget), "cursor-changed", G_CALLBACK(ListBox_change), (gpointer)this);
|
||||
g_signal_connect_swapped(G_OBJECT(object->subWidget), "row-activated", G_CALLBACK(ListBox_activate), (gpointer)this);
|
||||
|
||||
if(parent.window->defaultFont) setFont(*parent.window->defaultFont);
|
||||
gtk_fixed_put(GTK_FIXED(parent.object->formContainer), object->widget, x, y);
|
||||
gtk_widget_show(object->subWidget);
|
||||
gtk_widget_show(object->widget);
|
||||
}
|
||||
|
||||
void ListBox::setFocused() {
|
||||
gtk_widget_grab_focus(object->subWidget);
|
||||
}
|
||||
|
||||
void ListBox::setHeaderVisible(bool visible) {
|
||||
gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(object->subWidget), visible);
|
||||
}
|
||||
|
||||
void ListBox::setFont(Font &font) {
|
||||
Widget::setFont(font);
|
||||
unsigned columns = 1;
|
||||
while(true) {
|
||||
if(gtk_tree_view_get_column(GTK_TREE_VIEW(object->subWidget), columns) == 0) break;
|
||||
columns++;
|
||||
}
|
||||
for(unsigned i = 0; i < columns; i++) {
|
||||
gtk_widget_modify_font(listBox->column[i].label, font.font->font);
|
||||
}
|
||||
}
|
||||
|
||||
void ListBox::reset() {
|
||||
listBox->selection = -1;
|
||||
gtk_list_store_clear(GTK_LIST_STORE(listBox->store));
|
||||
gtk_tree_view_set_model(GTK_TREE_VIEW(object->subWidget), GTK_TREE_MODEL(listBox->store));
|
||||
//reset gtk_scrolled_window scrollbar position to 0,0 (top-left), as ListBox is now empty
|
||||
gtk_scrolled_window_set_hadjustment(GTK_SCROLLED_WINDOW(object->widget), 0);
|
||||
gtk_scrolled_window_set_vadjustment(GTK_SCROLLED_WINDOW(object->widget), 0);
|
||||
}
|
||||
|
||||
void ListBox::resizeColumnsToContent() {
|
||||
gtk_tree_view_columns_autosize(GTK_TREE_VIEW(object->subWidget));
|
||||
}
|
||||
|
||||
void ListBox::addItem(const char *text) {
|
||||
lstring list;
|
||||
list.split("\t", text);
|
||||
GtkTreeIter iter;
|
||||
gtk_list_store_append(listBox->store, &iter);
|
||||
for(unsigned i = 0; i < list.size(); i++) {
|
||||
gtk_list_store_set(listBox->store, &iter, i, (const char*)list[i], -1);
|
||||
}
|
||||
}
|
||||
|
||||
void ListBox::setItem(unsigned row, const char *text) {
|
||||
GtkTreeModel *model = gtk_tree_view_get_model(GTK_TREE_VIEW(object->subWidget));
|
||||
GtkTreeIter iter;
|
||||
for(unsigned i = 0; i <= row; i++) {
|
||||
if(i == 0) gtk_tree_model_get_iter_first(model, &iter);
|
||||
else gtk_tree_model_iter_next(model, &iter);
|
||||
}
|
||||
|
||||
lstring list;
|
||||
list.split("\t", text);
|
||||
for(unsigned i = 0; i < list.size(); i++) {
|
||||
gtk_list_store_set(listBox->store, &iter, i, (const char*)list[i], -1);
|
||||
}
|
||||
}
|
||||
|
||||
optional<unsigned> ListBox::selection() {
|
||||
GtkTreeSelection *selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(object->subWidget));
|
||||
GtkTreeModel *model = gtk_tree_view_get_model(GTK_TREE_VIEW(object->subWidget));
|
||||
GtkTreeIter iter;
|
||||
if(gtk_tree_model_get_iter_first(model, &iter) == false) return { false, 0 };
|
||||
if(gtk_tree_selection_iter_is_selected(selection, &iter) == true) return { true, 0 };
|
||||
for(unsigned i = 1;; i++) {
|
||||
if(gtk_tree_model_iter_next(model, &iter) == false) return { false, 0 };
|
||||
if(gtk_tree_selection_iter_is_selected(selection, &iter) == true) return { true, i };
|
||||
}
|
||||
return { false, 0 };
|
||||
}
|
||||
|
||||
void ListBox::setSelection(unsigned row) {
|
||||
signed current = -1;
|
||||
if(auto position = selection()) current = position();
|
||||
GtkTreeSelection *selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(object->subWidget));
|
||||
GtkTreeModel *model = gtk_tree_view_get_model(GTK_TREE_VIEW(object->subWidget));
|
||||
gtk_tree_selection_unselect_all(selection);
|
||||
|
||||
GtkTreeIter iter;
|
||||
if(gtk_tree_model_get_iter_first(model, &iter) == false) return;
|
||||
if(row == 0) {
|
||||
gtk_tree_selection_select_iter(selection, &iter);
|
||||
return;
|
||||
}
|
||||
for(unsigned i = 1;; i++) {
|
||||
if(gtk_tree_model_iter_next(model, &iter) == false) return;
|
||||
if(row == i) {
|
||||
gtk_tree_selection_select_iter(selection, &iter);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ListBox::ListBox() {
|
||||
listBox = new ListBox::Data;
|
||||
}
|
||||
Executable
+113
@@ -0,0 +1,113 @@
|
||||
static void Action_setFont(GtkWidget *widget, gpointer font) {
|
||||
gtk_widget_modify_font(widget, (PangoFontDescription*)font);
|
||||
if(GTK_IS_CONTAINER(widget)) {
|
||||
gtk_container_foreach(GTK_CONTAINER(widget), (GtkCallback)Action_setFont, font);
|
||||
}
|
||||
}
|
||||
|
||||
void Action::setFont(Font &font) {
|
||||
Action_setFont(object->widget, font.font->font);
|
||||
}
|
||||
|
||||
bool Action::visible() {
|
||||
return gtk_widget_get_visible(object->widget);
|
||||
}
|
||||
|
||||
void Action::setVisible(bool visible) {
|
||||
gtk_widget_set_visible(object->widget, visible);
|
||||
}
|
||||
|
||||
bool Action::enabled() {
|
||||
return gtk_widget_get_sensitive(object->widget);
|
||||
}
|
||||
|
||||
void Action::setEnabled(bool enabled) {
|
||||
gtk_widget_set_sensitive(object->widget, enabled);
|
||||
}
|
||||
|
||||
void Menu::create(Window &parent, const char *text) {
|
||||
object->menu = gtk_menu_new();
|
||||
object->widget = gtk_menu_item_new_with_label(text);
|
||||
gtk_menu_item_set_submenu(GTK_MENU_ITEM(object->widget), object->menu);
|
||||
if(parent.window->defaultFont) setFont(*parent.window->defaultFont);
|
||||
gtk_menu_bar_append(parent.object->menu, object->widget);
|
||||
gtk_widget_show(object->widget);
|
||||
}
|
||||
|
||||
void Menu::create(Menu &parent, const char *text) {
|
||||
object->menu = gtk_menu_new();
|
||||
object->widget = gtk_menu_item_new_with_label(text);
|
||||
gtk_menu_item_set_submenu(GTK_MENU_ITEM(object->widget), object->menu);
|
||||
gtk_menu_shell_append(GTK_MENU_SHELL(parent.object->menu), object->widget);
|
||||
gtk_widget_show(object->widget);
|
||||
}
|
||||
|
||||
void MenuSeparator::create(Menu &parent) {
|
||||
object->widget = gtk_separator_menu_item_new();
|
||||
gtk_menu_shell_append(GTK_MENU_SHELL(parent.object->menu), object->widget);
|
||||
gtk_widget_show(object->widget);
|
||||
}
|
||||
|
||||
static void MenuItem_tick(MenuItem *self) {
|
||||
if(self->onTick) self->onTick();
|
||||
}
|
||||
|
||||
void MenuItem::create(Menu &parent, const char *text) {
|
||||
object->widget = gtk_menu_item_new_with_label(text);
|
||||
g_signal_connect_swapped(G_OBJECT(object->widget), "activate", G_CALLBACK(MenuItem_tick), (gpointer)this);
|
||||
gtk_menu_shell_append(GTK_MENU_SHELL(parent.object->menu), object->widget);
|
||||
gtk_widget_show(object->widget);
|
||||
}
|
||||
|
||||
static void MenuCheckItem_tick(MenuCheckItem *self) {
|
||||
if(self->onTick && self->object->locked == false) self->onTick();
|
||||
}
|
||||
|
||||
void MenuCheckItem::create(Menu &parent, const char *text) {
|
||||
object->widget = gtk_check_menu_item_new_with_label(text);
|
||||
g_signal_connect_swapped(G_OBJECT(object->widget), "toggled", G_CALLBACK(MenuCheckItem_tick), (gpointer)this);
|
||||
gtk_menu_shell_append(GTK_MENU_SHELL(parent.object->menu), object->widget);
|
||||
gtk_widget_show(object->widget);
|
||||
}
|
||||
|
||||
bool MenuCheckItem::checked() {
|
||||
return gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(object->widget));
|
||||
}
|
||||
|
||||
void MenuCheckItem::setChecked(bool state) {
|
||||
object->locked = true;
|
||||
gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(object->widget), state);
|
||||
object->locked = false;
|
||||
}
|
||||
|
||||
static void MenuRadioItem_tick(MenuRadioItem *self) {
|
||||
if(self->onTick && self->checked() && self->object->locked == false) self->onTick();
|
||||
}
|
||||
|
||||
void MenuRadioItem::create(Menu &parent, const char *text) {
|
||||
first = this;
|
||||
object->parentMenu = &parent;
|
||||
object->widget = gtk_radio_menu_item_new_with_label(0, text);
|
||||
g_signal_connect_swapped(G_OBJECT(object->widget), "toggled", G_CALLBACK(MenuRadioItem_tick), (gpointer)this);
|
||||
gtk_menu_shell_append(GTK_MENU_SHELL(parent.object->menu), object->widget);
|
||||
gtk_widget_show(object->widget);
|
||||
}
|
||||
|
||||
void MenuRadioItem::create(MenuRadioItem &parent, const char *text) {
|
||||
first = parent.first;
|
||||
object->parentMenu = parent.object->parentMenu;
|
||||
object->widget = gtk_radio_menu_item_new_with_label_from_widget(GTK_RADIO_MENU_ITEM(first->object->widget), text);
|
||||
g_signal_connect_swapped(G_OBJECT(object->widget), "toggled", G_CALLBACK(MenuRadioItem_tick), (gpointer)this);
|
||||
gtk_menu_shell_append(GTK_MENU_SHELL(object->parentMenu->object->menu), object->widget);
|
||||
gtk_widget_show(object->widget);
|
||||
}
|
||||
|
||||
bool MenuRadioItem::checked() {
|
||||
return gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(object->widget));
|
||||
}
|
||||
|
||||
void MenuRadioItem::setChecked() {
|
||||
object->locked = true;
|
||||
gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(object->widget), true);
|
||||
object->locked = false;
|
||||
}
|
||||
Executable
+65
@@ -0,0 +1,65 @@
|
||||
static MessageWindow::Response MessageWindow_response(MessageWindow::Buttons buttons, gint response) {
|
||||
if(response == GTK_RESPONSE_OK) return MessageWindow::Response::Ok;
|
||||
if(response == GTK_RESPONSE_CANCEL) return MessageWindow::Response::Cancel;
|
||||
if(response == GTK_RESPONSE_YES) return MessageWindow::Response::Yes;
|
||||
if(response == GTK_RESPONSE_NO) return MessageWindow::Response::No;
|
||||
if(buttons == MessageWindow::Buttons::OkCancel) return MessageWindow::Response::Cancel;
|
||||
if(buttons == MessageWindow::Buttons::YesNo) return MessageWindow::Response::No;
|
||||
return MessageWindow::Response::Ok;
|
||||
}
|
||||
|
||||
MessageWindow::Response MessageWindow::information(Window &parent, const char *text, MessageWindow::Buttons buttons) {
|
||||
GtkButtonsType buttonsType = GTK_BUTTONS_OK;
|
||||
if(buttons == Buttons::OkCancel) buttonsType = GTK_BUTTONS_OK_CANCEL;
|
||||
if(buttons == Buttons::YesNo) buttonsType = GTK_BUTTONS_YES_NO;
|
||||
|
||||
GtkWidget *dialog = gtk_message_dialog_new(
|
||||
&parent != &Window::None ? GTK_WINDOW(parent.object->widget) : (GtkWindow*)0,
|
||||
GTK_DIALOG_MODAL, GTK_MESSAGE_INFO, buttonsType, "%s", text
|
||||
);
|
||||
gint response = gtk_dialog_run(GTK_DIALOG(dialog));
|
||||
gtk_widget_destroy(dialog);
|
||||
return MessageWindow_response(buttons, response);
|
||||
}
|
||||
|
||||
MessageWindow::Response MessageWindow::question(Window &parent, const char *text, MessageWindow::Buttons buttons) {
|
||||
GtkButtonsType buttonsType = GTK_BUTTONS_OK;
|
||||
if(buttons == Buttons::OkCancel) buttonsType = GTK_BUTTONS_OK_CANCEL;
|
||||
if(buttons == Buttons::YesNo) buttonsType = GTK_BUTTONS_YES_NO;
|
||||
|
||||
GtkWidget *dialog = gtk_message_dialog_new(
|
||||
&parent != &Window::None ? GTK_WINDOW(parent.object->widget) : (GtkWindow*)0,
|
||||
GTK_DIALOG_MODAL, GTK_MESSAGE_QUESTION, buttonsType, "%s", text
|
||||
);
|
||||
gint response = gtk_dialog_run(GTK_DIALOG(dialog));
|
||||
gtk_widget_destroy(dialog);
|
||||
return MessageWindow_response(buttons, response);
|
||||
}
|
||||
|
||||
MessageWindow::Response MessageWindow::warning(Window &parent, const char *text, MessageWindow::Buttons buttons) {
|
||||
GtkButtonsType buttonsType = GTK_BUTTONS_OK;
|
||||
if(buttons == Buttons::OkCancel) buttonsType = GTK_BUTTONS_OK_CANCEL;
|
||||
if(buttons == Buttons::YesNo) buttonsType = GTK_BUTTONS_YES_NO;
|
||||
|
||||
GtkWidget *dialog = gtk_message_dialog_new(
|
||||
&parent != &Window::None ? GTK_WINDOW(parent.object->widget) : (GtkWindow*)0,
|
||||
GTK_DIALOG_MODAL, GTK_MESSAGE_WARNING, buttonsType, "%s", text
|
||||
);
|
||||
gint response = gtk_dialog_run(GTK_DIALOG(dialog));
|
||||
gtk_widget_destroy(dialog);
|
||||
return MessageWindow_response(buttons, response);
|
||||
}
|
||||
|
||||
MessageWindow::Response MessageWindow::critical(Window &parent, const char *text, MessageWindow::Buttons buttons) {
|
||||
GtkButtonsType buttonsType = GTK_BUTTONS_OK;
|
||||
if(buttons == Buttons::OkCancel) buttonsType = GTK_BUTTONS_OK_CANCEL;
|
||||
if(buttons == Buttons::YesNo) buttonsType = GTK_BUTTONS_YES_NO;
|
||||
|
||||
GtkWidget *dialog = gtk_message_dialog_new(
|
||||
&parent != &Window::None ? GTK_WINDOW(parent.object->widget) : (GtkWindow*)0,
|
||||
GTK_DIALOG_MODAL, GTK_MESSAGE_ERROR, buttonsType, "%s", text
|
||||
);
|
||||
gint response = gtk_dialog_run(GTK_DIALOG(dialog));
|
||||
gtk_widget_destroy(dialog);
|
||||
return MessageWindow_response(buttons, response);
|
||||
}
|
||||
Loaded 100 of 1193 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user