ares-openbsd/nall/string.hpp

371 行
13 KiB
C++
Raw 通常表示 履歴

#pragma once
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <algorithm>
#include <initializer_list>
#include <memory>
#include <nall/platform.hpp>
#include <nall/array-view.hpp>
#include <nall/atoi.hpp>
#include <nall/function.hpp>
#include <nall/intrinsics.hpp>
Update to v094r09 release. byuu says: This will easily be the biggest diff in the history of higan. And not in a good way. * target-higan and target-loki have been blown away completely * nall and ruby massively updated * phoenix replaced with hiro (pretty near a total rewrite) * target-higan restarted using hiro (just a window for now) * all emulation cores updated to compile again * installation changed to not require root privileges (installs locally) For the foreseeable future (maybe even permanently?), the new higan UI will only build under Linux/BSD with GTK+ 2.20+. Probably the most likely route for Windows/OS X will be to try and figure out how to build hiro/GTK on those platforms, as awful as that would be. The other alternative would be to produce new UIs for those platforms ... which would actually be a good opportunity to make something much more user friendly. Being that I just started on this a few hours ago, that means that for at least a few weeks, don't expect to be able to actually play any games. Right now, you can pretty much just compile the binary and that's it. It's quite possible that some nall changes didn't produce compilation errors, but will produce runtime errors. So until the UI can actually load games, we won't know if anything is broken. But we should mostly be okay. It was mostly just trim<1> -> trim changes, moving to Hash::SHA256 (much cleaner), and patching some reckless memory copy functions enough to compile. Progress isn't going to be like it was before: I'm now dividing my time much thinner between studying and other hobbies. My aim this time is not to produce a binary for everyone to play games on. Rather, it's to keep the emulator alive. I want to be able to apply critical patches again. And I would also like the base of the emulator to live on, for use in other emulator frontends that utilize higan.
2015-02-26 19:10:46 +09:00
#include <nall/memory.hpp>
#include <nall/primitives.hpp>
#include <nall/shared-pointer.hpp>
#include <nall/stdint.hpp>
Update to v106r96 release. byuu says: Templates now import to the user data folders, so you can create multiple gamepads with distinct mappings ... or at least, you will be able to. Things have progressed enough that you can map keyboard inputs to play Zelda 3 a bit now. But if you close the emulator, the assignment device will be lost. Right now, it's serializing things to the root.bml document instead of to individual peripherals, and it's also not properly serializing/unserializing the HID object from ruby. The old naming of program, emulator, emulators didn't match the new design where Program wasn't the center of higan anymore (the configuration manager precedes it), and Emulator has become higan, so that's been renamed to emulator, interface, interfaces. Some new work on hiro and nall: MessageDialog - when dismissing, set the response to the last button - add dismissed() function NameDialog - new class for create / rename file/folder dialog boxes BrowserDialog - add create (folder), rename, and delete support directory: - add copy() function - fix sorting of folders to ignore trailing / string: - added string::from<T> and string.to<T> for object binding - requires string::operator bool() to return true when capacity() == 0 ... The last one is going to be really contentious, but ... oh my gods I am in love with it already. So for an example: auto x = shared_pointer_make<Foo>(); node->setProperty("id", string::from(x)); if(auto y = node->property("id")) y.to<shared_pointer<Foo>>()->bar(); The idea is to add another special case in nall::string, where when the capacity is zero, the new _hold pointer holds a type-erasing object. This object is set via string::from<T>(), and extracted via string.to<T>(). The capacity is always >= 23 normally, due to SSO, so it's okay to special-case zero. _hold doesn't make the string take any more space ... with SSO of 24 and two pointers before, we're just using up the rest of the space we already had. The total size of strings is still 32. Although at some point I'll probably make it 40 for 64-bit size/capacity, but that's not super pressing right now. Anyway ... why in the hell would I do this? Well, hiro has the Object::property/setProperty system for keeping a set (red-black tree) of name:value mappings. And higan adopted the same system for its Node objects. The name is obviously a string, but the value is also a string. Why a string? Because it's the easiest to serialize, and can be converted to and from any data type: booleans, integers, floats, strings, pointers ... and all of those implicitly convert into strings for you, so you setProperty("name", 3.7) is just fine. But it can't hold objects. Even if you allocate a new pointer and store it in the string, it'll end up leaking if you don't make sure to extract the pointer and delete it before the string goes away. I really didn't want to move the property system to any<T> types because they are such a massive pain in the ass to use in every case. It would make serializing/unserializing Property structures in Node elements way more painful, too. And any<T> basically requires heap allocation for absolutely any value. nall::string will only allocate memory when the string size is > 24 (or now, if you use the new string::from support.) Now obviously, string::from has a caveat: you can't serialize it. You can copy a string holding a T object to another safely, but once you try and print it into a text document, the string value will be empty, and when you try and read a string back from the text file, it's gonna also be empty. Even if we extracted the pointer from the string to store, restarting your program would invalidate the pointer anyway. This is a pretty significant win ... for my tree structure in higan's system manager, I can just hold shared_pointer copies of each Node inside each TreeViewItem, and retrieve them directly. No crazy path traversal up and down the tree with lots of string parsing involved. No possibilities for bizarre bugs because the two get out of sync, or the tree paths change in higan, or whatever else. The worst thing that could possibly happen is the shared_pointers between higan::Interface::root() and SystemManager get broken, and SystemManager just stabs at perfectly valid but detached Node objects. No big deal. No problem. In practice that's not going to happen anyway. In implementing this new feature, I realized that my template<typename... P> string(P&&...) constructor was matching instead of string(const string&), so I added a string(string&) constructor, which should in general help the performance of building strings a whole hell of a lot, presumably much more than the tiny tiny hit for the extra checks for the new string::from mode. There's only one thing about string::from that kind of worries me ... explicit string::operator bool() const must necessarily return true when holding a T object, even though the size and capacity are both zero. If we don't do this, the values will be lost in eg setProperty erasing nall::set entries when the assigned value is a blank string. I don't know if this will have unfortunate side effects in other string processing code, but ... in general, I've never used nall::from in any other code, so if there's an issue, we'll find it as we are using nall::from objects. The change should not impact any existing code as such. Lastly, the MessageDialog change ... in way too many places, I do tests like if(MessageDialog() .... question() == "Yes") or (... question() == "No"), but I don't test both Yes and No. So whichever I tested with ==, it'd be false when the MessageDialog were dismissed, and the inverse for !=. Not good. Sometimes it's the difference between deleting a directory recursively or cancelling the operation. I don't think in the history of using hiro I've ever bothered to actually test for .question()=="", so I think this change is really imporant. If the dismissal case is really needed, MessageDialog::dismissed() can be checked now instead. So the next big thing is going to be more advanced tree parsing: it doesn't really matter whether the root tree gets serialized with all the peripheral input values, but we absolutely must serialize each peripheral to its respective folder. And when unserializing the root, we have to go through and unserialize all of the peripherals. Also for input mapping, I have to serialize the hardware HID path + deviceID + vendorID, and then create a binding function that'll scan the root tree for all Input devices and rebind the shared_pointers to the new shared_pointer<HID::Device> instances. But, hopefully, hopefully ... I can get that done in the next WIP.
2019-02-03 16:55:29 +09:00
#include <nall/unique-pointer.hpp>
#include <nall/utility.hpp>
2011-11-17 21:05:35 +09:00
#include <nall/varint.hpp>
#include <nall/vector.hpp>
#include <nall/view.hpp>
namespace nall {
struct string;
Update to v099r14 release. byuu says: Changelog: - (u)int(max,ptr) abbreviations removed; use _t suffix now [didn't feel like they were contributing enough to be worth it] - cleaned up nall::integer,natural,real functionality - toInteger, toNatural, toReal for parsing strings to numbers - fromInteger, fromNatural, fromReal for creating strings from numbers - (string,Markup::Node,SQL-based-classes)::(integer,natural,real) left unchanged - template<typename T> numeral(T value, long padding, char padchar) -> string for print() formatting - deduces integer,natural,real based on T ... cast the value if you want to override - there still exists binary,octal,hex,pointer for explicit print() formatting - lstring -> string_vector [but using lstring = string_vector; is declared] - would be nice to remove the using lstring eventually ... but that'd probably require 10,000 lines of changes >_> - format -> string_format [no using here; format was too ambiguous] - using integer = Integer<sizeof(int)*8>; and using natural = Natural<sizeof(uint)*8>; declared - for consistency with boolean. These three are meant for creating zero-initialized values implicitly (various uses) - R65816::io() -> idle() and SPC700::io() -> idle() [more clear; frees up struct IO {} io; naming] - SFC CPU, PPU, SMP use struct IO {} io; over struct (Status,Registers) {} (status,registers); now - still some CPU::Status status values ... they didn't really fit into IO functionality ... will have to think about this more - SFC CPU, PPU, SMP now use step() exclusively instead of addClocks() calling into step() - SFC CPU joypad1_bits, joypad2_bits were unused; killed them - SFC PPU CGRAM moved into PPU::Screen; since nothing else uses it - SFC PPU OAM moved into PPU::Object; since nothing else uses it - the raw uint8[544] array is gone. OAM::read() constructs values from the OAM::Object[512] table now - this avoids having to determine how we want to sub-divide the two OAM memory sections - this also eliminates the OAM::synchronize() functionality - probably more I'm forgetting The FPS fluctuations are driving me insane. This WIP went from 128fps to 137fps. Settled on 133.5fps for the final build. But nothing I changed should have affected performance at all. This level of fluctuation makes it damn near impossible to know whether I'm speeding things up or slowing things down with changes.
2016-07-01 20:50:32 +09:00
struct string_format;
struct string_view {
using type = string_view;
//view.hpp
string_view();
string_view(const string_view& source);
string_view(string_view&& source);
string_view(const char* data);
string_view(const char* data, u32 size);
string_view(const string& source);
template<typename... P> string_view(P&&... p);
~string_view();
auto operator=(const string_view& source) -> type&;
auto operator=(string_view&& source) -> type&;
auto operator==(const char* source) const -> bool { return strcmp(data(), source) == 0; }
auto operator!=(const char* source) const -> bool { return strcmp(data(), source) != 0; }
explicit operator bool() const;
operator const char*() const;
auto data() const -> const char*;
auto size() const -> u32;
auto begin() const { return &_data[0]; }
auto end() const { return &_data[size()]; }
protected:
string* _string;
const char* _data;
mutable s32 _size;
};
//adaptive (SSO + COW) is by far the best choice, the others exist solely to:
//1) demonstrate the performance benefit of combining SSO + COW
//2) rule out allocator bugs by trying different allocators when needed
#define NALL_STRING_ALLOCATOR_ADAPTIVE
//#define NALL_STRING_ALLOCATOR_COPY_ON_WRITE
//#define NALL_STRING_ALLOCATOR_SMALL_STRING_OPTIMIZATION
//#define NALL_STRING_ALLOCATOR_VECTOR
//cast.hpp
template<typename T> struct stringify;
//format.hpp
template<typename... P> auto print(P&&...) -> void;
template<typename... P> auto print(FILE*, P&&...) -> void;
template<typename T> auto pad(const T& value, long precision = 0, char padchar = ' ') -> string;
template<typename T> auto hex(T value, long precision = 0, char padchar = '0') -> string;
template<typename T> auto octal(T value, long precision = 0, char padchar = '0') -> string;
template<typename T> auto binary(T value, long precision = 0, char padchar = '0') -> string;
//match.hpp
auto tokenize(const char* s, const char* p) -> bool;
auto tokenize(vector<string>& list, const char* s, const char* p) -> bool;
//utf8.hpp
auto characters(string_view self, s32 offset = 0, s32 length = -1) -> u32;
//utility.hpp
auto slice(string_view self, s32 offset = 0, s32 length = -1) -> string;
template<typename T> auto fromInteger(char* result, T value) -> char*;
template<typename T> auto fromNatural(char* result, T value) -> char*;
template<typename T> auto fromHex(char* result, T value) -> char*;
template<typename T> auto fromReal(char* str, T value) -> u32;
struct string {
using type = string;
protected:
#if defined(NALL_STRING_ALLOCATOR_ADAPTIVE)
enum : u32 { SSO = 24 };
union {
struct { //copy-on-write
char* _data;
u32* _refs;
};
struct { //small-string-optimization
char _text[SSO];
};
};
auto _allocate() -> void;
auto _copy() -> void;
auto _resize() -> void;
#endif
#if defined(NALL_STRING_ALLOCATOR_COPY_ON_WRITE)
char* _data;
mutable u32* _refs;
auto _allocate() -> char*;
auto _copy() -> char*;
#endif
#if defined(NALL_STRING_ALLOCATOR_SMALL_STRING_OPTIMIZATION)
enum : u32 { SSO = 24 };
union {
char* _data;
char _text[SSO];
};
#endif
#if defined(NALL_STRING_ALLOCATOR_VECTOR)
char* _data;
#endif
u32 _capacity;
u32 _size;
public:
string();
string(string& source) : string() { operator=(source); }
string(const string& source) : string() { operator=(source); }
2022-09-13 16:47:47 +09:00
string(string&& source) : string() { operator=(std::move(source)); }
template<typename T = char> auto get() -> T*;
template<typename T = char> auto data() const -> const T*;
template<typename T = char> auto size() const -> u32 { return _size / sizeof(T); }
template<typename T = char> auto capacity() const -> u32 { return _capacity / sizeof(T); }
auto reset() -> type&;
auto reserve(u32) -> type&;
auto resize(u32) -> type&;
auto operator=(const string&) -> type&;
auto operator=(string&&) -> type&;
template<typename T, typename... P> string(T&& s, P&&... p) : string() {
2022-09-13 16:47:47 +09:00
append(std::forward<T>(s), std::forward<P>(p)...);
}
~string() { reset(); }
Update to v106r97 release. byuu says: Very, very slow going ... sigh. Aforementioned changes to the Property system in hiro and higan. string::from/to removed. Input mappings now serialize the path/vendor/product IDs, and input binding events were added to connect inputs back to devices on load and on ruby device attach/detach events. (Speaking of ... a good tangent would be a notification callback when adding/remove HID::Device objects from ruby::Input. Neither hard nor expensive to scan the result of Input::poll() to detect this, but still.) The actual tree of each peripheral is loaded and saved now, and there's an initial attempt at importing this data into the actual root tree on load. I'm going to have to do this same thing in the port selection manager when attaching/detaching peripherals. There's code in place now to detect when you try to connect the same peripheral to multiple ports, and it'll stop you. It won't attempt to validate this if you give Interface::initialize a root.bml file that has the same peripheral in two ports, however. Maybe later we can detect that as well somehow ... it won't crash or anything even if you do this anyway. There's new <Platform::attach>, detach callbacks to send notifications to the GUI whenever the emulator tree changes in any way. And it's about here that I'm running into problems again. When closing the emulator, I'm seemingly unable to get the tree to actually destruct properly. If we have ~Node::Port call disconnect(), it works, but then segfaults after the application terminates in the global destructors. I was thinking, the Peripheral is inside of the Port, so maybe catch ~Node::Peripheral instead, see if it's attached to a parent Node::Port via the weak_pointer it holds, but no matter what that painfully segfaults on startup. I was pretty sure I wiped out all of the copies of the shared_pointers to the ports before calling Application::exit(), but it seems not. I guess that's the one downside to using shared pointers and holding copies of them everywhere. It quickly becomes overwhelming to keep it all in your head. Best I can think is to just slowly work on destructing everything as cleanly as possible. Eg closing the input mapping window should erase the list to clear the Node handles cached in the TableViewItem entries, reset its holding of the Node::Port for said mapping, etc. There's another problem with the <Platform::attach,detach> ... it's getting called with a bunch of nameless items. Nodes without names should never be attached to the emulator tree, so there's some spurious copies somewhere ... I'll need to update the static create() functions to take variadic template parameter lists, and make the name parameter a constant for the construction of Node objects. That should allow me to find where nameless Nodes are being spawned, and stop that from happening. A lot more work needs to go into serializing and unserializing Node::Peripherals to their respective folders. I feel like Node::clone is asking for too much trouble, and we should instead rely more heavily on <Platform::attach> during the load process to then connect peripherals for us from our shadow tree instance. The GUI should only ever call a function that copies all of the properties from the shadow unserializing tree to the actual emulation core, and never act recursively. I really don't know what to do about the serialized root tree holding all of the peripheral metadata. We have to do it in the case of peripherals having their own ports that may be connected to things, but ... a lot of the information in the tree isn't necessary at all. It would probably make sense to write some code to filter the serialized tree, like stripping all Input nodes from it before saving. Well whatever ... I *really* have to hurry up with this, but there's just so much work to do ... sigh.
2019-02-04 10:16:27 +09:00
explicit operator bool() const { return _size; }
operator const char*() const { return (const char*)data(); }
operator array_span<char>() { return {(char*)get(), size()}; }
operator array_view<char>() const { return {(const char*)data(), size()}; }
operator array_span<u8>() { return {(u8*)get(), size()}; }
operator array_view<u8>() const { return {(const u8*)data(), size()}; }
auto operator==(const string& source) const -> bool {
return size() == source.size() && memory::compare(data(), source.data(), size()) == 0;
}
auto operator!=(const string& source) const -> bool {
return size() != source.size() || memory::compare(data(), source.data(), size()) != 0;
}
auto operator==(const char* source) const -> bool { return strcmp(data(), source) == 0; }
auto operator!=(const char* source) const -> bool { return strcmp(data(), source) != 0; }
auto operator==(string_view source) const -> bool { return compare(source) == 0; }
auto operator!=(string_view source) const -> bool { return compare(source) != 0; }
auto operator< (string_view source) const -> bool { return compare(source) < 0; }
auto operator<=(string_view source) const -> bool { return compare(source) <= 0; }
auto operator> (string_view source) const -> bool { return compare(source) > 0; }
auto operator>=(string_view source) const -> bool { return compare(source) >= 0; }
auto begin() -> char* { return &get()[0]; }
auto end() -> char* { return &get()[size()]; }
auto begin() const -> const char* { return &data()[0]; }
auto end() const -> const char* { return &data()[size()]; }
//atoi.hpp
auto boolean() const -> bool;
auto integer() const -> s64;
auto natural() const -> u64;
auto hex() const -> u64;
auto real() const -> f64;
//core.hpp
auto operator[](u32) const -> const char&;
auto operator()(u32, char = 0) const -> char;
template<typename... P> auto assign(P&&...) -> type&;
template<typename T, typename... P> auto prepend(const T&, P&&...) -> type&;
template<typename... P> auto prepend(const nall::string_format&, P&&...) -> type&;
template<typename T> auto _prepend(const stringify<T>&) -> type&;
template<typename T, typename... P> auto append(const T&, P&&...) -> type&;
template<typename... P> auto append(const nall::string_format&, P&&...) -> type&;
template<typename T> auto _append(const stringify<T>&) -> type&;
auto length() const -> u32;
//find.hpp
auto contains(string_view characters) const -> maybe<u32>;
template<bool, bool> auto _find(s32, string_view) const -> maybe<u32>;
auto find(string_view source) const -> maybe<u32>;
auto ifind(string_view source) const -> maybe<u32>;
auto qfind(string_view source) const -> maybe<u32>;
auto iqfind(string_view source) const -> maybe<u32>;
auto findFrom(s32 offset, string_view source) const -> maybe<u32>;
auto ifindFrom(s32 offset, string_view source) const -> maybe<u32>;
auto findNext(s32 offset, string_view source) const -> maybe<u32>;
auto ifindNext(s32 offset, string_view source) const -> maybe<u32>;
auto findPrevious(s32 offset, string_view source) const -> maybe<u32>;
auto ifindPrevious(s32 offset, string_view source) const -> maybe<u32>;
//format.hpp
auto format(const nall::string_format& params) -> type&;
//compare.hpp
template<bool> static auto _compare(const char*, u32, const char*, u32) -> s32;
static auto compare(string_view, string_view) -> s32;
static auto icompare(string_view, string_view) -> s32;
auto compare(string_view source) const -> s32;
auto icompare(string_view source) const -> s32;
auto equals(string_view source) const -> bool;
auto iequals(string_view source) const -> bool;
auto beginsWith(string_view source) const -> bool;
auto ibeginsWith(string_view source) const -> bool;
auto endsWith(string_view source) const -> bool;
auto iendsWith(string_view source) const -> bool;
//convert.hpp
auto downcase() -> type&;
auto upcase() -> type&;
auto qdowncase() -> type&;
auto qupcase() -> type&;
auto transform(string_view from, string_view to) -> type&;
//match.hpp
auto match(string_view source) const -> bool;
auto imatch(string_view source) const -> bool;
//replace.hpp
template<bool, bool> auto _replace(string_view, string_view, long) -> type&;
auto replace(string_view from, string_view to, long limit = LONG_MAX) -> type&;
auto ireplace(string_view from, string_view to, long limit = LONG_MAX) -> type&;
auto qreplace(string_view from, string_view to, long limit = LONG_MAX) -> type&;
auto iqreplace(string_view from, string_view to, long limit = LONG_MAX) -> type&;
//split.hpp
auto split(string_view key, long limit = LONG_MAX) const -> vector<string>;
auto isplit(string_view key, long limit = LONG_MAX) const -> vector<string>;
auto qsplit(string_view key, long limit = LONG_MAX) const -> vector<string>;
auto iqsplit(string_view key, long limit = LONG_MAX) const -> vector<string>;
//trim.hpp
auto trim(string_view lhs, string_view rhs, long limit = LONG_MAX) -> type&;
auto trimLeft(string_view lhs, long limit = LONG_MAX) -> type&;
auto trimRight(string_view rhs, long limit = LONG_MAX) -> type&;
auto itrim(string_view lhs, string_view rhs, long limit = LONG_MAX) -> type&;
auto itrimLeft(string_view lhs, long limit = LONG_MAX) -> type&;
auto itrimRight(string_view rhs, long limit = LONG_MAX) -> type&;
auto strip() -> type&;
auto stripLeft() -> type&;
auto stripRight() -> type&;
//utf8.hpp
auto characters(s32 offset = 0, s32 length = -1) const -> u32;
//utility.hpp
static auto read(string_view filename) -> string;
static auto repeat(string_view pattern, u32 times) -> string;
auto fill(char fill = ' ') -> type&;
auto hash() const -> u32;
auto remove(u32 offset, u32 length) -> type&;
auto reverse() -> type&;
auto size(s32 length, char fill = ' ') -> type&;
auto slice(s32 offset = 0, s32 length = -1) const -> string;
};
template<> struct vector<string> : vector_base<string> {
using type = vector<string>;
using vector_base<string>::vector_base;
vector(const vector& source) { vector_base::operator=(source); }
vector(vector& source) { vector_base::operator=(source); }
2022-09-13 16:47:47 +09:00
vector(vector&& source) { vector_base::operator=(std::move(source)); }
template<typename... P> vector(P&&... p) { append(std::forward<P>(p)...); }
auto operator=(const vector& source) -> type& { return vector_base::operator=(source), *this; }
auto operator=(vector& source) -> type& { return vector_base::operator=(source), *this; }
2022-09-13 16:47:47 +09:00
auto operator=(vector&& source) -> type& { return vector_base::operator=(std::move(source)), *this; }
//vector.hpp
template<typename... P> auto append(const string&, P&&...) -> type&;
auto append() -> type&;
auto isort() -> type&;
auto find(string_view source) const -> maybe<u32>;
auto ifind(string_view source) const -> maybe<u32>;
auto match(string_view pattern) const -> vector<string>;
auto merge(string_view separator = "") const -> string;
auto strip() -> type&;
//split.hpp
template<bool, bool> auto _split(string_view, string_view, long) -> type&;
};
Update to v099r14 release. byuu says: Changelog: - (u)int(max,ptr) abbreviations removed; use _t suffix now [didn't feel like they were contributing enough to be worth it] - cleaned up nall::integer,natural,real functionality - toInteger, toNatural, toReal for parsing strings to numbers - fromInteger, fromNatural, fromReal for creating strings from numbers - (string,Markup::Node,SQL-based-classes)::(integer,natural,real) left unchanged - template<typename T> numeral(T value, long padding, char padchar) -> string for print() formatting - deduces integer,natural,real based on T ... cast the value if you want to override - there still exists binary,octal,hex,pointer for explicit print() formatting - lstring -> string_vector [but using lstring = string_vector; is declared] - would be nice to remove the using lstring eventually ... but that'd probably require 10,000 lines of changes >_> - format -> string_format [no using here; format was too ambiguous] - using integer = Integer<sizeof(int)*8>; and using natural = Natural<sizeof(uint)*8>; declared - for consistency with boolean. These three are meant for creating zero-initialized values implicitly (various uses) - R65816::io() -> idle() and SPC700::io() -> idle() [more clear; frees up struct IO {} io; naming] - SFC CPU, PPU, SMP use struct IO {} io; over struct (Status,Registers) {} (status,registers); now - still some CPU::Status status values ... they didn't really fit into IO functionality ... will have to think about this more - SFC CPU, PPU, SMP now use step() exclusively instead of addClocks() calling into step() - SFC CPU joypad1_bits, joypad2_bits were unused; killed them - SFC PPU CGRAM moved into PPU::Screen; since nothing else uses it - SFC PPU OAM moved into PPU::Object; since nothing else uses it - the raw uint8[544] array is gone. OAM::read() constructs values from the OAM::Object[512] table now - this avoids having to determine how we want to sub-divide the two OAM memory sections - this also eliminates the OAM::synchronize() functionality - probably more I'm forgetting The FPS fluctuations are driving me insane. This WIP went from 128fps to 137fps. Settled on 133.5fps for the final build. But nothing I changed should have affected performance at all. This level of fluctuation makes it damn near impossible to know whether I'm speeding things up or slowing things down with changes.
2016-07-01 20:50:32 +09:00
struct string_format : vector<string> {
using type = string_format;
2022-09-13 16:47:47 +09:00
template<typename... P> string_format(P&&... p) { reserve(sizeof...(p)); append(std::forward<P>(p)...); }
template<typename T, typename... P> auto append(const T&, P&&... p) -> type&;
auto append() -> type&;
};
Update to v106r79 release. byuu says: This WIP is just work on nall/primitives ... Basically, I'm coming to the conclusion that it's just not practical to try and make Natural/Integer implicitly castable to primitive signed and unsigned integers. C++ just has too many edge cases there. I also want to get away from the problem of C++ deciding that all math operations return 32-bit values, unless one of the parameters is 64-bit, in which case you get a 64-bit value. You know, so things like array[-1] won't end up accessing the 4 billionth element of the array. It's nice to be fancy and minimally size operations (eg 32-bit+32-bit = 33-bit), but it's just too unintuitive. I think all Natural<X>+Natural<Y> expessions should result in a Natural<64> (eg natural) type. nall/primitives/operators.hpp has been removed, and new Natural<>Natural / Integer<>Integer casts exist. My feeling is that signed and unsigned types should not be implicitly convertible where data loss can occur. In the future, I think an integer8*natural8 is fine to return an integer64, and the bitwise operators are probably all fine between the two types. I could probably add (Integer,Natural)+Boolean conversions as well. To simplify expressions, there are new user-defined literals for _b (boolean), _n (natural), _i (integer), _r (real), _n# (eg _n8), _i# (eg _i8), _r# (eg _r32), and _s (nall::string). In the long-term, my intention is to make the conversion and cast constructors explicit for primitive types, but obviously that'll shatter most of higan, so for now that won't be the case. Something I can do in the future is allow implicit conversion and casting to (u)int64_t. That may be a nice balance.
2019-01-15 13:33:20 +09:00
inline auto operator"" _s(const char* value, std::size_t) -> string { return {value}; }
}
#include <nall/string/view.hpp>
#include <nall/string/pascal.hpp>
#include <nall/string/atoi.hpp>
#include <nall/string/cast.hpp>
Update to v094r09 release. byuu says: This will easily be the biggest diff in the history of higan. And not in a good way. * target-higan and target-loki have been blown away completely * nall and ruby massively updated * phoenix replaced with hiro (pretty near a total rewrite) * target-higan restarted using hiro (just a window for now) * all emulation cores updated to compile again * installation changed to not require root privileges (installs locally) For the foreseeable future (maybe even permanently?), the new higan UI will only build under Linux/BSD with GTK+ 2.20+. Probably the most likely route for Windows/OS X will be to try and figure out how to build hiro/GTK on those platforms, as awful as that would be. The other alternative would be to produce new UIs for those platforms ... which would actually be a good opportunity to make something much more user friendly. Being that I just started on this a few hours ago, that means that for at least a few weeks, don't expect to be able to actually play any games. Right now, you can pretty much just compile the binary and that's it. It's quite possible that some nall changes didn't produce compilation errors, but will produce runtime errors. So until the UI can actually load games, we won't know if anything is broken. But we should mostly be okay. It was mostly just trim<1> -> trim changes, moving to Hash::SHA256 (much cleaner), and patching some reckless memory copy functions enough to compile. Progress isn't going to be like it was before: I'm now dividing my time much thinner between studying and other hobbies. My aim this time is not to produce a binary for everyone to play games on. Rather, it's to keep the emulator alive. I want to be able to apply critical patches again. And I would also like the base of the emulator to live on, for use in other emulator frontends that utilize higan.
2015-02-26 19:10:46 +09:00
#include <nall/string/compare.hpp>
#include <nall/string/convert.hpp>
#include <nall/string/core.hpp>
Update to v094r09 release. byuu says: This will easily be the biggest diff in the history of higan. And not in a good way. * target-higan and target-loki have been blown away completely * nall and ruby massively updated * phoenix replaced with hiro (pretty near a total rewrite) * target-higan restarted using hiro (just a window for now) * all emulation cores updated to compile again * installation changed to not require root privileges (installs locally) For the foreseeable future (maybe even permanently?), the new higan UI will only build under Linux/BSD with GTK+ 2.20+. Probably the most likely route for Windows/OS X will be to try and figure out how to build hiro/GTK on those platforms, as awful as that would be. The other alternative would be to produce new UIs for those platforms ... which would actually be a good opportunity to make something much more user friendly. Being that I just started on this a few hours ago, that means that for at least a few weeks, don't expect to be able to actually play any games. Right now, you can pretty much just compile the binary and that's it. It's quite possible that some nall changes didn't produce compilation errors, but will produce runtime errors. So until the UI can actually load games, we won't know if anything is broken. But we should mostly be okay. It was mostly just trim<1> -> trim changes, moving to Hash::SHA256 (much cleaner), and patching some reckless memory copy functions enough to compile. Progress isn't going to be like it was before: I'm now dividing my time much thinner between studying and other hobbies. My aim this time is not to produce a binary for everyone to play games on. Rather, it's to keep the emulator alive. I want to be able to apply critical patches again. And I would also like the base of the emulator to live on, for use in other emulator frontends that utilize higan.
2015-02-26 19:10:46 +09:00
#include <nall/string/find.hpp>
#include <nall/string/format.hpp>
Update to v094r09 release. byuu says: This will easily be the biggest diff in the history of higan. And not in a good way. * target-higan and target-loki have been blown away completely * nall and ruby massively updated * phoenix replaced with hiro (pretty near a total rewrite) * target-higan restarted using hiro (just a window for now) * all emulation cores updated to compile again * installation changed to not require root privileges (installs locally) For the foreseeable future (maybe even permanently?), the new higan UI will only build under Linux/BSD with GTK+ 2.20+. Probably the most likely route for Windows/OS X will be to try and figure out how to build hiro/GTK on those platforms, as awful as that would be. The other alternative would be to produce new UIs for those platforms ... which would actually be a good opportunity to make something much more user friendly. Being that I just started on this a few hours ago, that means that for at least a few weeks, don't expect to be able to actually play any games. Right now, you can pretty much just compile the binary and that's it. It's quite possible that some nall changes didn't produce compilation errors, but will produce runtime errors. So until the UI can actually load games, we won't know if anything is broken. But we should mostly be okay. It was mostly just trim<1> -> trim changes, moving to Hash::SHA256 (much cleaner), and patching some reckless memory copy functions enough to compile. Progress isn't going to be like it was before: I'm now dividing my time much thinner between studying and other hobbies. My aim this time is not to produce a binary for everyone to play games on. Rather, it's to keep the emulator alive. I want to be able to apply critical patches again. And I would also like the base of the emulator to live on, for use in other emulator frontends that utilize higan.
2015-02-26 19:10:46 +09:00
#include <nall/string/match.hpp>
#include <nall/string/replace.hpp>
#include <nall/string/split.hpp>
Update to v094r09 release. byuu says: This will easily be the biggest diff in the history of higan. And not in a good way. * target-higan and target-loki have been blown away completely * nall and ruby massively updated * phoenix replaced with hiro (pretty near a total rewrite) * target-higan restarted using hiro (just a window for now) * all emulation cores updated to compile again * installation changed to not require root privileges (installs locally) For the foreseeable future (maybe even permanently?), the new higan UI will only build under Linux/BSD with GTK+ 2.20+. Probably the most likely route for Windows/OS X will be to try and figure out how to build hiro/GTK on those platforms, as awful as that would be. The other alternative would be to produce new UIs for those platforms ... which would actually be a good opportunity to make something much more user friendly. Being that I just started on this a few hours ago, that means that for at least a few weeks, don't expect to be able to actually play any games. Right now, you can pretty much just compile the binary and that's it. It's quite possible that some nall changes didn't produce compilation errors, but will produce runtime errors. So until the UI can actually load games, we won't know if anything is broken. But we should mostly be okay. It was mostly just trim<1> -> trim changes, moving to Hash::SHA256 (much cleaner), and patching some reckless memory copy functions enough to compile. Progress isn't going to be like it was before: I'm now dividing my time much thinner between studying and other hobbies. My aim this time is not to produce a binary for everyone to play games on. Rather, it's to keep the emulator alive. I want to be able to apply critical patches again. And I would also like the base of the emulator to live on, for use in other emulator frontends that utilize higan.
2015-02-26 19:10:46 +09:00
#include <nall/string/trim.hpp>
#include <nall/string/utf8.hpp>
#include <nall/string/utility.hpp>
#include <nall/string/vector.hpp>
#include <nall/string/eval/node.hpp>
#include <nall/string/eval/literal.hpp>
#include <nall/string/eval/parser.hpp>
#include <nall/string/eval/evaluator.hpp>
Update to v091r05 release. [No prior releases were posted to the WIP thread. -Ed.] byuu says: Super Famicom mapping system has been reworked as discussed with the mask= changes. offset becomes base, mode is gone. Also added support for comma-separated fields in the address fields, to reduce the number of map lines needed. <?xml version="1.0" encoding="UTF-8"?> <cartridge region="NTSC"> <superfx revision="2"> <rom name="program.rom" size="0x200000"/> <ram name="save.rwm" size="0x8000"/> <map id="io" address="00-3f,80-bf:3000-32ff"/> <map id="rom" address="00-3f:8000-ffff" mask="0x8000"/> <map id="rom" address="40-5f:0000-ffff"/> <map id="ram" address="00-3f,80-bf:6000-7fff" size="0x2000"/> <map id="ram" address="70-71:0000-ffff"/> </superfx> </cartridge> Or in BML: cartridge region=NTSC superfx revision=2 rom name=program.rom size=0x200000 ram name=save.rwm size=0x8000 map id=io address=00-3f,80-bf:3000-32ff map id=rom address=00-3f:8000-ffff mask=0x8000 map id=rom address=40-5f:0000-ffff map id=ram address=00-3f,80-bf:6000-7fff size=0x2000 map id=ram address=70-71:0000-ffff As a result of the changes, old mappings will no longer work. The above XML example will run Super Mario World 2: Yoshi's Island. Otherwise, you'll have to write your own. All that's left now is to work some sort of database mapping system in, so I can start dumping carts en masse. The NES changes that FitzRoy asked for are mostly in as well. Also, part of the reason I haven't released a WIP ... but fuck it, I'm not going to wait forever to post a new WIP. I've added a skeleton driver to emulate Campus Challenge '92 and Powerfest '94. There's no actual emulation, except for the stuff I can glean from looking at the pictures of the board. It has a DSP-1 (so SR/DR registers), four ROMs that map in and out, RAM, etc. I've also added preliminary mapping to upload high scores to a website, but obviously I need the ROMs first.
2012-10-09 17:25:32 +09:00
#include <nall/string/markup/node.hpp>
#include <nall/string/markup/find.hpp>
Update to v091r05 release. [No prior releases were posted to the WIP thread. -Ed.] byuu says: Super Famicom mapping system has been reworked as discussed with the mask= changes. offset becomes base, mode is gone. Also added support for comma-separated fields in the address fields, to reduce the number of map lines needed. <?xml version="1.0" encoding="UTF-8"?> <cartridge region="NTSC"> <superfx revision="2"> <rom name="program.rom" size="0x200000"/> <ram name="save.rwm" size="0x8000"/> <map id="io" address="00-3f,80-bf:3000-32ff"/> <map id="rom" address="00-3f:8000-ffff" mask="0x8000"/> <map id="rom" address="40-5f:0000-ffff"/> <map id="ram" address="00-3f,80-bf:6000-7fff" size="0x2000"/> <map id="ram" address="70-71:0000-ffff"/> </superfx> </cartridge> Or in BML: cartridge region=NTSC superfx revision=2 rom name=program.rom size=0x200000 ram name=save.rwm size=0x8000 map id=io address=00-3f,80-bf:3000-32ff map id=rom address=00-3f:8000-ffff mask=0x8000 map id=rom address=40-5f:0000-ffff map id=ram address=00-3f,80-bf:6000-7fff size=0x2000 map id=ram address=70-71:0000-ffff As a result of the changes, old mappings will no longer work. The above XML example will run Super Mario World 2: Yoshi's Island. Otherwise, you'll have to write your own. All that's left now is to work some sort of database mapping system in, so I can start dumping carts en masse. The NES changes that FitzRoy asked for are mostly in as well. Also, part of the reason I haven't released a WIP ... but fuck it, I'm not going to wait forever to post a new WIP. I've added a skeleton driver to emulate Campus Challenge '92 and Powerfest '94. There's no actual emulation, except for the stuff I can glean from looking at the pictures of the board. It has a DSP-1 (so SR/DR registers), four ROMs that map in and out, RAM, etc. I've also added preliminary mapping to upload high scores to a website, but obviously I need the ROMs first.
2012-10-09 17:25:32 +09:00
#include <nall/string/markup/bml.hpp>
#include <nall/string/markup/xml.hpp>
Update to v094r09 release. byuu says: This will easily be the biggest diff in the history of higan. And not in a good way. * target-higan and target-loki have been blown away completely * nall and ruby massively updated * phoenix replaced with hiro (pretty near a total rewrite) * target-higan restarted using hiro (just a window for now) * all emulation cores updated to compile again * installation changed to not require root privileges (installs locally) For the foreseeable future (maybe even permanently?), the new higan UI will only build under Linux/BSD with GTK+ 2.20+. Probably the most likely route for Windows/OS X will be to try and figure out how to build hiro/GTK on those platforms, as awful as that would be. The other alternative would be to produce new UIs for those platforms ... which would actually be a good opportunity to make something much more user friendly. Being that I just started on this a few hours ago, that means that for at least a few weeks, don't expect to be able to actually play any games. Right now, you can pretty much just compile the binary and that's it. It's quite possible that some nall changes didn't produce compilation errors, but will produce runtime errors. So until the UI can actually load games, we won't know if anything is broken. But we should mostly be okay. It was mostly just trim<1> -> trim changes, moving to Hash::SHA256 (much cleaner), and patching some reckless memory copy functions enough to compile. Progress isn't going to be like it was before: I'm now dividing my time much thinner between studying and other hobbies. My aim this time is not to produce a binary for everyone to play games on. Rather, it's to keep the emulator alive. I want to be able to apply critical patches again. And I would also like the base of the emulator to live on, for use in other emulator frontends that utilize higan.
2015-02-26 19:10:46 +09:00
#include <nall/string/transform/cml.hpp>
#include <nall/string/transform/dml.hpp>