Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
630 changes: 625 additions & 5 deletions data/data_symbols.csv

Large diffs are not rendered by default.

469 changes: 235 additions & 234 deletions data/mcswitch_functions.csv

Large diffs are not rendered by default.

4 changes: 4 additions & 0 deletions src/4JLibraries_Source/NX/MemSect.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
#include "NX/Platform.h"

/** No operation on Switch (0x7100609ed0). */
void MemSect(int) {}
4 changes: 2 additions & 2 deletions src/4JLibraries_Source/NX/Platform.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,9 @@ void XPhysicalFree(void* ptr) {
free(ptr);
}

#ifndef _WIN32
void __debugbreak() {} // I assume this just calls compiler intrinsic on x86

void MemSect(int) {}
#endif

void PIXBeginNamedEvent(float, const char*, ...) {}
void PIXEndNamedEvent() {}
Expand Down
4 changes: 2 additions & 2 deletions src/4JLibraries_Source/NX/Render/C4JRender.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#pragma once

#include "arm_neon.h"
#include <arm_neon.h>

class _XSOCIAL_PREVIEWIMAGE;
class ImageFileBuffer;
Expand Down Expand Up @@ -41,7 +41,7 @@ class C4JRender {
virtual void MatrixPop() = 0;
virtual void MatrixPush() = 0;
virtual float32x4_t MatrixMult(float*) = 0;
virtual void MatrixGet(int) = 0;
virtual float* MatrixGet(int) = 0;
virtual void Set_matrixDirty() = 0;
virtual void Initialise() = 0;
virtual void InitialiseContext() = 0;
Expand Down
1,436 changes: 1,436 additions & 0 deletions src/4JLibraries_Source/NX/Render/NvnProcLoader.cpp

Large diffs are not rendered by default.

178 changes: 175 additions & 3 deletions src/4JLibraries_Source/NX/Render/RendererCore.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,67 @@
#include <cstring>

__thread Renderer::Context* sContext;
static __thread MatrixStruct sMatrixResult;

// NON_MATCHING | score: 800 (lower is better)
extern "C" Renderer::Context* Renderer__getContext() {
return sContext;
}

static const MatrixStruct identityMatrix = {
{{1.0f, 0.0f, 0.0f, 0.0f}, {0.0f, 1.0f, 0.0f, 0.0f}, {0.0f, 0.0f, 1.0f, 0.0f}, {0.0f, 0.0f, 0.0f, 1.0f}}};
unsigned int textureWidths[6] = {1920, 1280, 512, 256, 128, 64};
unsigned int textureHeights[6] = {1080, 720, 512, 256, 128, 64};
nn::os::MutexType someRendererMutex;

Renderer::Context::Context(Renderer*, bool a2) {
this->m_filler[0] = a2;
// NON_MATCHING | score: 5575 (lower is better)
Renderer::Context::Context(Renderer*, bool creationFlag) {
m_ptr1DE0 = nullptr;
m_ptr1DE8 = nullptr;
m_ptr1DF0 = nullptr;
m_creationFlag = creationFlag;
// Only the base entries are initialized; stack storage and matrix-dirty flags are preserved.
m_matrixDepth[0] = 0;
m_matrixStacks[0][0] = identityMatrix;
m_matrixDepth[1] = 0;
m_matrixDepth[2] = 0;
m_matrixDepth[3] = 0;
m_matrixMode = 0;
m_matrixStacks[1][0] = identityMatrix;
m_matrixStacks[2][0] = identityMatrix;
m_matrixStacks[3][0] = identityMatrix;
m_byte1040 = false;
m_float1044 = 1.0f;
m_lightingEnabled = false;
for (int i = 0; i < 4; i++) {
m_textureBindings[i] = 0;
m_textureBindingDirty[i] = false;
m_textureFlags[i] = false;
}
m_fogEnabled = false;
m_byte1DD8 = false;
m_commandBuffer = nullptr;
m_dword1CE0 = -1;
memset(m_data1CE8, 0, sizeof(m_data1CE8));
m_byte1CDC = false;
m_byte1D38 = false;
m_fogDirty = false;
m_byte1CE4 = false;
m_textureScaleUI[0] = 1.0f;
m_textureScaleUI[1] = 1.0f;
m_textureScaleUI[2] = 0.0f;
m_textureScaleUI[3] = 0.0f;
nvnBlendStateSetDefaults(&m_blendState);
nvnDepthStencilStateSetDefaults(&m_depthStencilState);
nvnDepthStencilStateSetDepthTestEnable(&m_depthStencilState, true);
nvnDepthStencilStateSetDepthFunc(&m_depthStencilState, NVN_DEPTH_FUNC_LEQUAL);
nvnColorStateSetDefaults(&m_colorState);
nvnPolygonStateSetDefaults(&m_polygonState);
nvnChannelMaskStateSetDefaults(&m_channelMaskState);
m_depthFunc = NVN_DEPTH_FUNC_LEQUAL;
for (int i = 0; i < 6; i++)
m_stateDirty[i] = true;
m_dword1CC0 = 0;
}

Renderer::Renderer() : C4JRender() {
Expand All @@ -31,7 +86,7 @@ Renderer::Renderer() : C4JRender() {
Renderer::sInstance = this;
}

// NON_MATCHING: inline the tls offset getter, could be some compiler flag
// NON_MATCHING | score: 800 (lower is better)
void Renderer::InitialiseContext(bool idk) {
sContext = new Renderer::Context(this, idk);
}
Expand Down Expand Up @@ -429,3 +484,120 @@ float32x4_t Renderer::MatrixMult(float* matrix) {
void Renderer::UpdateGamma(unsigned short gamma) {
this->m_gammaIntensity = gamma;
}

void Renderer::MatrixMode(int mode) {
Renderer__getContext()->m_matrixMode = mode;
}

void Renderer::MatrixSetIdentity() {
Context* context = Renderer__getContext();
int mode = context->m_matrixMode;
MatrixStruct& top = context->m_matrixStacks[mode][context->m_matrixDepth[mode]];
top.m__[0] = identityMatrix.m__[0];
top.m__[1] = identityMatrix.m__[1];
top.m__[2] = identityMatrix.m__[2];
top.m__[3] = identityMatrix.m__[3];
context->m_matrixDirty[context->m_matrixMode] = true;
}

// name guessed
// NON_MATCHING | score: 1940 (lower is better)
float32x4_t Renderer::MultWithStack(MatrixStruct input) {
Context* context = Renderer__getContext();
int mode = context->m_matrixMode;
MatrixStruct& top = context->m_matrixStacks[mode][context->m_matrixDepth[mode]];
float32x4_t a = top.m__[0];
float32x4_t b = top.m__[1];
float32x4_t c = top.m__[2];
float32x4_t d = top.m__[3];
float32x4_t result;
for (int i = 0; i < 4; i++) {
float32x4_t column = vmulq_laneq_f32(a, input.m__[i], 0);
column = vfmaq_laneq_f32(column, b, input.m__[i], 1);
column = vfmaq_laneq_f32(column, c, input.m__[i], 2);
result = vfmaq_laneq_f32(column, d, input.m__[i], 3);
top.m__[i] = result;
}
context->m_matrixDirty[context->m_matrixMode] = true;
return result;
}

void Renderer::MatrixTranslate(float x, float y, float z) {
MatrixStruct matrix = identityMatrix;
matrix.m__[3] = (float32x4_t){x, y, z, 1.0f};
MultWithStack(matrix);
}

// NON_MATCHING | score: 1445 (lower is better)
void Renderer::MatrixScale(float x, float y, float z) {
MatrixStruct matrix
= {{{x, 0.0f, 0.0f, 0.0f}, {0.0f, y, 0.0f, 0.0f}, {0.0f, 0.0f, z, 0.0f}, {0.0f, 0.0f, 0.0f, 1.0f}}};
MultWithStack(matrix);
}

// NON_MATCHING | score: 700 (lower is better)
void Renderer::MatrixOrthogonal(float left, float right, float bottom, float top, float near, float far) {
float x = 1.0f / (right - left);
float y = 1.0f / (top - bottom);
float z = -1.0f / (far - near);
MatrixStruct matrix = {{{x + x, 0.0f, 0.0f, 0.0f},
{0.0f, y + y, 0.0f, 0.0f},
{0.0f, 0.0f, z, 0.0f},
{-(left + right) * x, -(bottom + top) * y, z * near, 1.0f}}};
MultWithStack(matrix);
}

void Renderer::MatrixPush() {
Context* context = Renderer__getContext();
int mode = context->m_matrixMode;
MatrixStruct* top = &context->m_matrixStacks[mode][context->m_matrixDepth[mode]];
memcpy(top + 1, top, sizeof(MatrixStruct));
context->m_matrixDepth[context->m_matrixMode]++;
}

void Renderer::MatrixPop() {
Context* context = Renderer__getContext();
context->m_matrixDepth[context->m_matrixMode]--;
context->m_matrixDirty[context->m_matrixMode] = true;
}

// NON_MATCHING | score: 800 (lower is better)
float* Renderer::MatrixGet(int mode) {
Context* context = Renderer__getContext();
MatrixStruct& top = context->m_matrixStacks[mode][context->m_matrixDepth[mode]];
float32x4_t a = top.m__[0];
float32x4_t b = top.m__[1];
float32x4_t c = top.m__[2];
float32x4_t d = top.m__[3];
sMatrixResult.m__[0] = a;
sMatrixResult.m__[1] = b;
sMatrixResult.m__[2] = c;
sMatrixResult.m__[3] = d;
return reinterpret_cast<float*>(&sMatrixResult);
}

void Renderer::Set_matrixDirty() {
Context* context = Renderer__getContext();
context->m_matrixStacks[0][0].m__[0] = identityMatrix.m__[0];
context->m_matrixStacks[0][0].m__[1] = identityMatrix.m__[1];
context->m_matrixStacks[0][0].m__[2] = identityMatrix.m__[2];
context->m_matrixStacks[0][0].m__[3] = identityMatrix.m__[3];
context->m_matrixStacks[1][0].m__[0] = identityMatrix.m__[0];
context->m_matrixStacks[1][0].m__[1] = identityMatrix.m__[1];
context->m_matrixStacks[1][0].m__[2] = identityMatrix.m__[2];
context->m_matrixStacks[1][0].m__[3] = identityMatrix.m__[3];
context->m_matrixStacks[3][0].m__[0] = identityMatrix.m__[0];
context->m_matrixStacks[3][0].m__[1] = identityMatrix.m__[1];
context->m_matrixStacks[3][0].m__[2] = identityMatrix.m__[2];
context->m_matrixStacks[3][0].m__[3] = identityMatrix.m__[3];
context->m_matrixStacks[2][0].m__[0] = identityMatrix.m__[0];
context->m_matrixStacks[2][0].m__[1] = identityMatrix.m__[1];
context->m_matrixStacks[2][0].m__[2] = identityMatrix.m__[2];
context->m_matrixStacks[2][0].m__[3] = identityMatrix.m__[3];
context->m_matrixDirty[0] = true;
context->m_matrixDirty[1] = true;
context->m_matrixDirty[3] = true;
context->m_matrixDirty[2] = true;
m_dword29C0 = -1;
m_dword29C4 = -1;
}
60 changes: 56 additions & 4 deletions src/4JLibraries_Source/NX/Render/RendererCore.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,49 @@ class Renderer : public C4JRender {
public:
Context(Renderer*, bool);

char m_filler[0x1F30];
char m_gap0[0x10];
MatrixStruct m_matrixStacks[4][16];
bool m_matrixDirty[4];
int m_matrixDepth[4];
int m_matrixMode;
int m_textureBindings[4];
bool m_textureBindingDirty[4];
bool m_textureFlags[4];
bool m_byte1040;
float m_float1044;
NVNblendState m_blendState;
NVNdepthStencilState m_depthStencilState;
NVNcolorState m_colorState;
NVNpolygonState m_polygonState;
NVNchannelMaskState m_channelMaskState;
int m_depthFunc;
bool m_stateDirty[6];
char m_gap106E[0xC52];
int m_dword1CC0;
bool m_fogEnabled;
char m_gap1CC5[0x13];
bool m_fogDirty;
bool m_lightingEnabled;
char m_gap1CDA[2];
bool m_byte1CDC;
char m_gap1CDD[3];
int m_dword1CE0;
bool m_byte1CE4;
bool m_creationFlag;
char m_gap1CE6[2];
char m_data1CE8[0x50];
bool m_byte1D38;
char m_gap1D39[0x87];
void* m_commandBuffer;
char m_gap1DC8[0x10];
bool m_byte1DD8;
char m_gap1DD9[7];
void* m_ptr1DE0;
void* m_ptr1DE8;
void* m_ptr1DF0;
char m_gap1DF8[0x28];
float m_textureScaleUI[4];
char m_gap1E30[0x100];
};

Renderer();
Expand All @@ -58,8 +100,8 @@ class Renderer : public C4JRender {

virtual void Tick();
virtual void UpdateGamma(unsigned short gamma);
// see OpenGL for more info (modes starts from 0 and ends in 2, they are in the same order as they are in
// OpenGL)
/** NX maintains four independently selected matrix stacks, each with sixteen entries.
*/
virtual void MatrixMode(int);
virtual void MatrixSetIdentity();
virtual void MatrixTranslate(float, float, float);
Expand All @@ -70,7 +112,7 @@ class Renderer : public C4JRender {
virtual void MatrixPop();
virtual void MatrixPush();
virtual float32x4_t MatrixMult(float* matrix);
virtual void MatrixGet(int);
virtual float* MatrixGet(int);
virtual void Set_matrixDirty();
// unused params were probably used in Xbox One
virtual void Initialise();
Expand Down Expand Up @@ -343,3 +385,13 @@ class Renderer : public C4JRender {
int m_elo;
int m_elo22;
};

static_assert(sizeof(MatrixStruct) == 0x40, "Matrix size");
static_assert(alignof(MatrixStruct) == 0x10, "Matrix alignment");
static_assert(sizeof(Renderer::Context) == 0x1F30, "Renderer context size");
static_assert(offsetof(Renderer::Context, m_matrixStacks) == 0x10, "Matrix stack offset");
static_assert(offsetof(Renderer::Context, m_matrixDirty) == 0x1010, "Matrix dirty offset");
static_assert(offsetof(Renderer::Context, m_matrixMode) == 0x1024, "Matrix mode offset");
static_assert(offsetof(Renderer::Context, m_blendState) == 0x1048, "Blend state offset");
static_assert(offsetof(Renderer::Context, m_creationFlag) == 0x1CE5, "Context flag offset");
static_assert(offsetof(Renderer::Context, m_textureScaleUI) == 0x1E20, "UI texture scale offset");
6 changes: 6 additions & 0 deletions src/4JLibraries_Source/NX/Render/StbiFile.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
#include "NX/Render/TextureUtil.h"

// name guessed
StbiFile* StbiFile::fromUser(void* user) {
return static_cast<StbiFile*>(user);
}
11 changes: 7 additions & 4 deletions src/4JLibraries_Source/NX/Render/TextureUtil.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ void TextureUtil::decodeJpeg(void* buffer, int len, int* x, int* y) {
}
}

// NON_MATCHING: I don't understand the graphic shit too much so this is shitty impl
// NON_MATCHING | score: 3930 (lower is better)
void TextureUtil::insertZlibAlphaChannelData(void* data, int width, int height, void* sourceData,
int sourceLen) {
unsigned long decompressedSize = width * height;
Expand Down Expand Up @@ -124,10 +124,13 @@ int StbiFile::read(void* user, char* data, int size) {
return dataRead;
}

// this one requires nn sdk symbol which I wont't bother to get
// void StbiFile::skip(void* user, int n) {}
void StbiFile::skip(void* user, int n) {
StbiFile* file = StbiFile::fromUser(user);
SetFilePointer(file->m_fileHandle, n, nullptr, 1);
StbiFile::fromUser(user)->m_dataRead += n;
}

// NON_MATCHING: some weird stuff is going on here, but logic should be the same though
// NON_MATCHING | score: 115 (lower is better)
int StbiFile::eof(void* user) {
return StbiFile::fromUser(user)->m_fileSize <= StbiFile::fromUser(user)->m_dataRead;
}
Loading