Files
dusklight/include/dusk/endian.h
T
qwertyquerty 767ba3bb14 Ongoing gameplay dev (#49)
* launch.json cwd

* bodge to load gci for testing

* stub card stat

* gameplay bodges

* viewport, ub fixes

* add release with debug info cmake variant

* be fixes, sound stub

* viewport h

* d_msg_flow BE

* be fopAcM_createItemFromEnemyID

* update launch configuration to use iso

* more audio stubs

* Attempt to set viewport and get messages for brightness check

* skip opening scene again, fixed JMessage::TResourceContainer::TCResource::Do_destroy

* add guards for viewport changes

* moar endian swapping to get Link sitting in PROC_OPENING_SCENE and for dialogues

* BE d_msg_class i_data

* stub bgm start

* fix div by 0 error (for now)

* TEMP_BROKEN in d_menu_ring

* REQUIRES_GX_LINES

* properly stub renderingAmap::draw with REQUIRES_GX_LINES

* better stubbing outside of stubs

* fix event data getting swapped multiple times

* evil draw vp fix

* Stub log imgui

This redirects all spammy logs to an imgui window that is cleared per frame.

This fixes the serious performance dip of the logging, and makes the regular log readable.

* Oops move those optimization changes I accidentally committed behind a flag

DUSK_SELECTED_OPT

* gx_line macro in map

* fix audio stubbing

* switch to CARD API aurora impl

* remove kabufuda from link libs

* refactor imgui stuff and add input viewer

* merge stub log with refactor

* accidentally committed a metaforce header shh

* basic map loader

* ImGuiConsole: Add missing <thread> include

* you may now play as luigi (you may now load stages with bridges)

* bloom fix

* bloom leak fix

* cloud shadow fix

* add soft reset button to imgui menu

* if it broke dont not fix it

* i swear i committed this

* BE swap indMtx in JPAResource::setPTev

* wnark ct fix

* frsqrte implementation from kinoko

* Fix Clang compile error in JAISeq::prepare_getSeqData_

* Add endian conversions to dMsgFlow_c::getInitNodeIndex

This fixes a freeze when Fado tries to stop you from leaving the
starting area.

* Add RAII GXTexObj wrapper; fix almost all leaks

* Update aurora for indirect texturing

* Update aurora for CARD fix

* Fix Clang build

* More d_msg_flow endian fixes

Fixes softlock when trying to talk to Fado and possibly other NPCs.

* no frame limiter

* get pause menu working

* proper frame limiting

* particle pointer size fix

* improve map loader a bit

---------

Co-authored-by: Jasper St. Pierre <jstpierre@mecheye.net>
Co-authored-by: TakaRikka <takarikka@outlook.com>
Co-authored-by: CraftyBoss <talibabdulmaalik@gmail.com>
Co-authored-by: Luke Street <luke@street.dev>
Co-authored-by: Lurs <2795933+Lurs@users.noreply.github.com>
Co-authored-by: PJB3005 <pieterjan.briers+git@gmail.com>
Co-authored-by: tgsm <doodrabbit@hotmail.com>
Co-authored-by: Max Roncace <me@caseif.net>
Co-authored-by: Phillip Stephens <antidote.crk@gmail.com>
2026-03-12 04:01:03 -07:00

276 lines
5.4 KiB
C++

#ifndef DOLPHIN_ENDIAN_H
#define DOLPHIN_ENDIAN_H
#include <bit>
#include "dolphin/types.h"
#include "dolphin/mtx.h"
// Platform detection - Little Endian targets
#if defined(_WIN32) || defined(__x86_64__) || defined(__i386__) || defined(__aarch64__) || defined(_M_X64) || defined(_M_IX86)
#define TARGET_LITTLE_ENDIAN 1
#else
#define TARGET_LITTLE_ENDIAN 0
#endif
#if TARGET_LITTLE_ENDIAN
#ifdef _MSC_VER
#include <stdlib.h>
#define BSWAP16(x) _byteswap_ushort(x)
#define BSWAP32(x) _byteswap_ulong(x)
#define BSWAP64(x) _byteswap_uint64(x)
#else
#define BSWAP16(x) __builtin_bswap16(x)
#define BSWAP32(x) __builtin_bswap32(x)
#define BSWAP64(x) __builtin_bswap64(x)
#endif
#else
#define BSWAP16(x) (x)
#define BSWAP32(x) (x)
#endif
// Big-Endian to Host conversion
inline u16 be16(u16 val) { return BSWAP16(val); }
inline s16 be16s(s16 val) { return (s16)BSWAP16((u16)val); }
inline u32 be32(u32 val) { return BSWAP32(val); }
inline s32 be32s(s32 val) { return (s32)BSWAP32((u32)val); }
inline u64 be64(u64 val) { return BSWAP64(val); }
inline s64 be64s(s64 val) { return (s64)BSWAP64((u64)val); }
#ifdef TARGET_PC
// Helper wrappers so code below reads nicely:
static inline u16 RES_U16(u16 v) {
return be16(v);
}
static inline s16 RES_S16(s16 v) {
return be16s(v);
}
static inline u32 RES_U32(u32 v) {
return be32(v);
}
static inline s32 RES_S32(s32 v) {
return be32s(v);
}
static inline u64 RES_U64(u64 v) {
return be64(v);
}
static inline s64 RES_S64(s64 v) {
return be64s(v);
}
static inline f32 RES_F32(f32 v) {
return std::bit_cast<f32, s32>(RES_S32(std::bit_cast<s32, f32>(v)));
}
#else
// On GameCube host-endian == file-endian, these are no-ops (keep as macros to allow compile in
// original code paths)
#define RES_U16(x) (x)
#define RES_S16(x) (x)
#define RES_U32(x) (x)
#define RES_S32(x) (x)
#endif
#ifdef TARGET_PC
/*
* Declares a big-endian integer type.
*/
template<class T>
struct BE {
T inner;
BE() = default;
BE(const T& from) {
inner = swap(from);
}
// post-ops
T operator--(int) {
T orig = inner;
*this -= 1;
return swap(orig);
}
T operator++(int) {
T orig = inner;
*this += 1;
return swap(orig);
}
operator T() const {
return swap(inner);
}
T host[[nodiscard]]() const {
return swap(inner);
}
static T swap[[nodiscard]](T val);
};
#define BIN_ASSIGN_OP(op) \
\
template<typename TA, typename TB> \
constexpr BE<TA>& operator op(BE<TA>& a, TB b) { \
TA aCopy = a; \
aCopy op b; \
a = aCopy; \
return a; \
}
BIN_ASSIGN_OP(&=);
BIN_ASSIGN_OP(|=);
BIN_ASSIGN_OP(+=);
BIN_ASSIGN_OP(-=);
BIN_ASSIGN_OP(/=);
BIN_ASSIGN_OP(^=);
#undef BIN_ASSIGN_OP
template<>
inline u16 BE<u16>::swap(u16 val) {
return RES_U16(val);
}
template<>
inline s16 BE<s16>::swap(s16 val) {
return RES_S16(val);
}
template<>
inline u32 BE<u32>::swap(u32 val) {
return RES_U32(val);
}
template<>
inline s32 BE<s32>::swap(s32 val) {
return RES_S32(val);
}
template<>
inline s64 BE<s64>::swap(s64 val) {
return RES_S64(val);
}
template<>
inline u64 BE<u64>::swap(u64 val) {
return RES_U64(val);
}
template<>
inline f32 BE<f32>::swap(f32 val) {
return RES_F32(val);
}
template<>
inline S16Vec BE<S16Vec>::swap(S16Vec val) {
return {
BE<s16>::swap(val.x),
BE<s16>::swap(val.y),
BE<s16>::swap(val.z),
};
}
template<>
struct BE<Vec> {
BE<f32> x;
BE<f32> y;
BE<f32> z;
BE() = default;
BE(f32 x, f32 y, f32 z) {
this->x = x;
this->y = y;
this->z = z;
}
BE(const Vec& from) {
x = from.x;
y = from.y;
z = from.z;
}
operator Vec() const {
return { x, y, z };
}
static Vec swap(Vec val) {
return {
BE<f32>::swap(val.x),
BE<f32>::swap(val.y),
BE<f32>::swap(val.z),
};
}
};
template <>
struct BE<Mtx44> {
BE<f32> contents[4][4];
auto& operator[](int x) const {
return contents[x];
}
};
template <>
struct BE<Mtx> {
BE<f32> contents[3][4];
auto& operator[](int x) const {
return contents[x];
}
void to_host(Mtx& mtx) const {
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 4; j++) {
mtx[i][j] = contents[i][j];
}
}
}
};
template<typename T>
void be_swap(T& val) {
val = BE<T>::swap(val);
}
template<typename T, u32 N>
void be_swap(T (& val)[N]) {
for (u32 i = 0; i < N; i++) {
be_swap(val[i]);
}
}
template<typename T>
void be_swap(T array[], const u32 size) {
for (u32 i = 0; i < size; i++) {
be_swap(array[i]);
}
}
template<>
inline void be_swap(Mtx44& val) {
for (auto & x : val) {
for (float & y : x) {
be_swap(y);
}
}
}
template<>
inline void be_swap(Mtx& val) {
for (auto & x : val) {
for (float & y : x) {
be_swap(y);
}
}
}
#define BE(T) BE<T>
#define BE_HOST(T) (T.host())
#else
#define BE(T) T
#define BE_HOST(T) (T)
#endif
#endif // DOLPHIN_ENDIAN_H