ares-openbsd/nall/array-span.hpp

115 行
3.1 KiB
C++
Raw 通常表示 履歴

#pragma once
#include <nall/array-view.hpp>
namespace nall {
template<typename T> struct array_span : array_view<T> {
using type = array_span;
using super = array_view<T>;
array_span() {
super::_data = nullptr;
super::_size = 0;
}
array_span(nullptr_t) {
super::_data = nullptr;
super::_size = 0;
}
array_span(void* data, u64 size) {
super::_data = (T*)data;
super::_size = (s32)size;
}
template<s32 size> array_span(T (&data)[size]) {
super::_data = data;
super::_size = size;
}
Update to ares v118 release. I'm excited to launch ares v118 today, the first release featuring playable, full-speed Nintendo 64 emulation! The new Nintendo 64 emulation is made possible thanks to [Themaister] very graciously porting his Vulkan-based ParaLLEl-RDP graphics renderer to ares. With its default settings, it is nearly pixel-perfect to real hardware, and it optionally supports upscaling to 2x or 4x the original Nintendo 64 resolution, plus optional supersampling back down to the original resolution (for enhanced anti-aliasing) if desired. The Vulkan support requires an appropriate graphics card, and either Windows or Linux. At this time, Vulkan is not available for macOS nor the BSDs. Also new for the Nintendo 64 core in this release is Rumble Pak, Cartridge Pak, SRAM, EEPROM, and Flash save support. Note that for right now, the Rumble Pak will only be enabled for games which use internal saves (SRAM, EEPROM, and Flash.) That does not cover all Rumble Pak-capable games. The option to choose between Rumble Paks and Cartridge Paks will be added to a future release. For the PlayStation core, [Luke Usher] provided two rendering fixes that allow Final Fantasy VII and Tony Hawk's Pro Skater to be fully playable! Right now, approximately 33% of the Nintendo 64 library is fully playable, and about 67% of the PlayStation library is fully playable. Each core has only been under active development for about one month each, so they both have a long way to go. Please treat these early releases as tech samples, rather than finished emulation cores. Further, note that the Nintendo 64 and PlayStation cores employ cached interpreters. This is a middle-ground between the accuracy of interpreters and the performance of dynamic recompilers. As such, ares' system requirements will be a bit higher than traditional emulators for these systems. Presuming no background task interference or CPU throttling, generally speaking, a Ryzen 5 2600 or better CPU should get you to around ~120fps in the average case, and ~60fps in the worst case. The source code has also been released under the terms of the Creative Commons BY-NC-ND 4.0 license. [Themaister]: http://github.com/Themaister/ [Luke Usher]: https://twitter.com/LukeUsher1
2021-02-21 08:51:00 +09:00
explicit operator bool() const {
return super::_data && super::_size > 0;
}
explicit operator T*() {
return (T*)super::_data;
}
T& operator*() const {
return (T&)*super::_data;
}
auto operator++() -> type& { super::_data++; super::_size--; return *this; }
auto operator--() -> type& { super::_data--; super::_size++; return *this; }
auto operator++(s32) -> type { auto copy = *this; ++(*this); return copy; }
auto operator--(s32) -> type { auto copy = *this; --(*this); return copy; }
auto operator[](u32 index) -> T& { return (T&)super::operator[](index); }
template<typename U = T> auto data() -> U* { return (U*)super::_data; }
template<typename U = T> auto data() const -> const U* { return (const U*)super::_data; }
auto begin() -> iterator<T> { return {(T*)super::_data, (u32)0}; }
auto end() -> iterator<T> { return {(T*)super::_data, (u32)super::_size}; }
auto rbegin() -> reverse_iterator<T> { return {(T*)super::_data, (u32)super::_size - 1}; }
auto rend() -> reverse_iterator<T> { return {(T*)super::_data, (u32)-1}; }
auto write(T value) -> void {
operator[](0) = value;
super::_data++;
super::_size--;
}
auto span(u32 offset, u32 length) -> type {
#ifdef DEBUG
struct out_of_bounds {};
if(offset + length >= super::_size) throw out_of_bounds{};
#endif
return {(T*)super::_data + offset, length};
}
//array_span<u8> specializations
template<typename U> auto writel(U value, u32 size) -> void;
template<typename U> auto writem(U value, u32 size) -> void;
template<typename U> auto writevn(U value, u32 size) -> void;
template<typename U> auto writevi(U value, u32 size) -> void;
};
//array_span<u8>
template<> inline auto array_span<u8>::write(u8 value) -> void {
operator[](0) = value;
_data++;
_size--;
}
template<> template<typename U> inline auto array_span<u8>::writel(U value, u32 size) -> void {
for(u32 byte : range(size)) write(value >> byte * 8);
}
template<> template<typename U> inline auto array_span<u8>::writem(U value, u32 size) -> void {
for(u32 byte : reverse(range(size))) write(value >> byte * 8);
}
template<> template<typename U> inline auto array_span<u8>::writevn(U value, u32 size) -> void {
while(true) {
auto byte = value & 0x7f;
value >>= 7;
if(value == 0) return write(0x80 | byte);
write(byte);
value--;
}
}
template<> template<typename U> inline auto array_span<u8>::writevi(U value, u32 size) -> void {
bool negate = value < 0;
if(negate) value = ~value;
value = value << 1 | negate;
writevn(value);
}
}