mirror of
https://github.com/projectPiki/pikmin2.git
synced 2024-11-26 23:00:27 +00:00
Cleanup stream.cpp and sysMath.cpp
This commit is contained in:
parent
60ec0577a1
commit
534586d595
@ -285,7 +285,7 @@ struct ShadowMgr : public CNode {
|
||||
u8 mEnabled; // _3C
|
||||
u8 mDoCheckCylinderType; // _3D
|
||||
int mCylinderID; // _40
|
||||
int _44; // _44, seems to be entirely unused
|
||||
int mUnused0; // _44, seems to be entirely unused
|
||||
Color4 mColor; // _48
|
||||
ShadowParms* mParms; // _4C
|
||||
};
|
||||
|
@ -21,27 +21,27 @@ struct Stream {
|
||||
mPosition = 0;
|
||||
setMode(STREAM_MODE_BINARY, 1);
|
||||
}
|
||||
|
||||
Stream(int);
|
||||
|
||||
virtual void read(void*, int) = 0;
|
||||
virtual void write(void*, int) = 0;
|
||||
virtual bool eof();
|
||||
virtual u32 getPending();
|
||||
virtual void read(void*, int) = 0; // _04
|
||||
virtual void write(void*, int) = 0; // _08
|
||||
virtual bool eof(); // _0C
|
||||
virtual u32 getPending(); // _10
|
||||
|
||||
void differentEndian(); // unused
|
||||
bool isSpace(char); // inline
|
||||
char skipSpace(); // inline
|
||||
void copyToTextBuffer(); // inline
|
||||
bool differentEndian() { return mEndian != STREAM_BIG_ENDIAN; }
|
||||
bool isSpace(char);
|
||||
char skipSpace();
|
||||
void copyToTextBuffer();
|
||||
char* getNextToken();
|
||||
void textBeginGroup(char*);
|
||||
void textEndGroup();
|
||||
void printf(char*, ...);
|
||||
void textWriteText(char*, ...);
|
||||
void skipPadding(u32); // inline
|
||||
void skipReading(u32);
|
||||
void skipReadingText();
|
||||
void _read(void*, int); // unused
|
||||
void _write(void*, int); // unused
|
||||
void _read(void* buffer, int length);
|
||||
void _write(void*, int);
|
||||
void textWriteTab(int);
|
||||
|
||||
u8 readByte();
|
||||
@ -50,10 +50,8 @@ struct Stream {
|
||||
int readInt();
|
||||
f32 readFloat();
|
||||
char* readString(char*, int);
|
||||
void readFixedString(); // unused
|
||||
|
||||
void writeString(char*);
|
||||
void writeFixedString(char*); // unused
|
||||
void writeByte(u8);
|
||||
void _writeByte(u8);
|
||||
void writeShort(s16);
|
||||
@ -99,12 +97,9 @@ struct Stream {
|
||||
struct RamStream : Stream {
|
||||
RamStream(void* bufferPointer, int bounds);
|
||||
|
||||
virtual void read(void*, int);
|
||||
virtual void write(void*, int);
|
||||
virtual bool eof();
|
||||
// virtual void getPending(); // from Stream
|
||||
|
||||
void set(u8*, int);
|
||||
virtual void read(void*, int); // _04
|
||||
virtual void write(void*, int); // _08
|
||||
virtual bool eof(); // _0C
|
||||
|
||||
void* mRamBufferStart; // _418
|
||||
int mBounds; // _41C
|
||||
@ -121,7 +116,7 @@ struct RamStream : Stream {
|
||||
* @param nullCheck Should we check if the file was successfully mounted to RAM or not?
|
||||
*/
|
||||
template <typename T>
|
||||
inline void loadAndRead(T* thisPtr, char* fname, JKRHeap* heap = nullptr, bool nullCheck = true)
|
||||
inline void loadFromFile(T* thisPtr, char* fname, JKRHeap* heap = nullptr, bool nullCheck = true)
|
||||
{
|
||||
void* handle = JKRDvdRipper::loadToMainRAM(fname, 0, Switch_0, 0, heap, JKRDvdRipper::ALLOC_DIR_BOTTOM, 0, 0, 0);
|
||||
if (nullCheck && !handle) {
|
||||
|
@ -23,15 +23,7 @@ AIConstants::AIConstants()
|
||||
mCameraAngle.mData = 180.0f;
|
||||
|
||||
char* fileName = "/user/Kando/aiConstants.txt";
|
||||
|
||||
void* handle = JKRDvdToMainRam(fileName, nullptr, Switch_0, 0, 0, JKRDvdRipper::ALLOC_DIR_BOTTOM, 0, nullptr, nullptr);
|
||||
|
||||
if (handle) {
|
||||
RamStream stream(handle, -1);
|
||||
stream.setMode(STREAM_MODE_TEXT, 1);
|
||||
read(stream);
|
||||
delete[] handle;
|
||||
}
|
||||
loadFromFile(this, fileName);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -338,7 +338,7 @@ Stages::Stages()
|
||||
_104 = 0;
|
||||
_10A = 0;
|
||||
|
||||
loadAndRead(this, "user/Abe/stages.txt", nullptr, false);
|
||||
loadFromFile(this, "user/Abe/stages.txt", nullptr, false);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -358,8 +358,9 @@ Mgr::Mgr()
|
||||
setModelSize(1);
|
||||
mObjectPathComponent = "user/Kando/objects/barrel";
|
||||
mParms = new BarrelParms();
|
||||
void* resource = JKRDvdRipper::loadToMainRAM("user/Abe/item/barrelParms.txt", nullptr, Switch_0, 0, nullptr,
|
||||
JKRDvdRipper::ALLOC_DIR_BOTTOM, 0, nullptr, nullptr);
|
||||
|
||||
void* resource = JKRDvdRipper::loadToMainRAM("user/Abe/item/barrelParms.txt", nullptr, Switch_0, 0, nullptr,
|
||||
JKRDvdRipper::ALLOC_DIR_BOTTOM, 0, nullptr, nullptr);
|
||||
if (resource) {
|
||||
RamStream stream(resource, -1);
|
||||
stream.setMode(STREAM_MODE_TEXT, true);
|
||||
|
@ -499,8 +499,9 @@ Mgr::Mgr()
|
||||
mObjectPathComponent = "user/Kando/objects/kanketusen";
|
||||
mItemName = "‹AŠÒŠÔŒ‡<EFBFBD>ò"; // 'return geyser'
|
||||
mParms = new FountainParms();
|
||||
void* data = JKRDvdRipper::loadToMainRAM("user/Abe/item/fountainParms.txt", nullptr, Switch_0, 0, nullptr,
|
||||
JKRDvdRipper::ALLOC_DIR_BOTTOM, 0, nullptr, nullptr);
|
||||
|
||||
void* data = JKRDvdRipper::loadToMainRAM("user/Abe/item/fountainParms.txt", nullptr, Switch_0, 0, nullptr,
|
||||
JKRDvdRipper::ALLOC_DIR_BOTTOM, 0, nullptr, nullptr);
|
||||
if (data != nullptr) {
|
||||
RamStream input(data, -1);
|
||||
input.setMode(STREAM_MODE_TEXT, 1);
|
||||
|
@ -125,7 +125,7 @@ ShadowMgr::ShadowMgr(int count)
|
||||
mEnabled = true;
|
||||
mDoCheckCylinderType = 1;
|
||||
mCylinderID = 0;
|
||||
_44 = 0;
|
||||
mUnused0 = 0;
|
||||
mName = "ShadowMgr";
|
||||
}
|
||||
|
||||
@ -690,17 +690,7 @@ bool ShadowMgr::isDrawJointShadow(JointShadowRootNode* node, int vpNum)
|
||||
* @note Address: 0x80242454
|
||||
* @note Size: 0xAC
|
||||
*/
|
||||
void ShadowMgr::readShadowParms(char* fileName)
|
||||
{
|
||||
void* data = JKRDvdRipper::loadToMainRAM(fileName, nullptr, Switch_0, 0, nullptr, JKRDvdRipper::ALLOC_DIR_BOTTOM, 0, nullptr, nullptr);
|
||||
|
||||
if (data) {
|
||||
RamStream input(data, -1);
|
||||
input.setMode(STREAM_MODE_TEXT, 1);
|
||||
read(input);
|
||||
delete[] data;
|
||||
}
|
||||
}
|
||||
void ShadowMgr::readShadowParms(char* fileName) { loadFromFile(this, fileName); }
|
||||
|
||||
/**
|
||||
* @note Address: 0x80242500
|
||||
@ -711,7 +701,7 @@ void ShadowMgr::write(Stream& output)
|
||||
output.writeShort((u16)mEnabled);
|
||||
output.writeShort((u16)mDoCheckCylinderType);
|
||||
output.writeInt(mCylinderID);
|
||||
output.writeInt(_44);
|
||||
output.writeInt(mUnused0);
|
||||
mColor.write(output);
|
||||
mParms->write(output);
|
||||
}
|
||||
@ -725,7 +715,7 @@ void ShadowMgr::read(Stream& input)
|
||||
mEnabled = input.readShort();
|
||||
mDoCheckCylinderType = input.readShort();
|
||||
mCylinderID = input.readInt();
|
||||
_44 = input.readInt();
|
||||
mUnused0 = input.readInt();
|
||||
mColor.read(input);
|
||||
mParms->read(input);
|
||||
}
|
||||
|
@ -207,7 +207,7 @@ f32 TimeMgr::getRealDayTime()
|
||||
*/
|
||||
void TimeMgr::loadSettingFile(char* filename)
|
||||
{
|
||||
loadAndRead(&mParms.mParms, filename, JKRHeap::sSystemHeap);
|
||||
loadFromFile(&mParms.mParms, filename, JKRHeap::sSystemHeap);
|
||||
init();
|
||||
}
|
||||
|
||||
|
@ -3,52 +3,61 @@
|
||||
#include "string.h"
|
||||
|
||||
/**
|
||||
* Checks if the given character is a whitespace character.
|
||||
*
|
||||
* @note Also checks if the character is a comment or scope character. (i.e. '#', '{', '}')
|
||||
* @param currByte The character to check.
|
||||
* @return True if the character is a whitespace character, false otherwise.
|
||||
*
|
||||
* @note Address: N/A
|
||||
* @note Size: 0x48
|
||||
*/
|
||||
bool Stream::isSpace(char currByte)
|
||||
{
|
||||
// check if current byte is whitespace/newline/hash/brackets
|
||||
return ((currByte == '\r') || (currByte == ' ') || (currByte == '\n') || (currByte == '\t') || (currByte == '#') || (currByte == '{')
|
||||
|| (currByte == '}'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Skips any leading whitespace characters in the stream and returns the first non-whitespace character encountered.
|
||||
*
|
||||
* @return The first non-whitespace character encountered, or 0 if not text mode / EOF.
|
||||
*
|
||||
* @note Address: N/A
|
||||
* @note Size: 0xEC
|
||||
*/
|
||||
// INLINE
|
||||
char Stream::skipSpace()
|
||||
{
|
||||
// return next byte that isn't a 'space' or a comment
|
||||
// if in binary mode (or end of file), return 0
|
||||
char byte;
|
||||
bool isComment = false;
|
||||
mBufferPos = 0;
|
||||
|
||||
mBufferPos = 0;
|
||||
// Spaces only occur in text mode
|
||||
if (mMode == STREAM_MODE_TEXT) {
|
||||
// check we're not at the end of the file
|
||||
while (!eof()) {
|
||||
char byte = _readByte(); // at 0x8
|
||||
// if we're in a comment line, skip until we hit a new line
|
||||
char currentChar = _readByte();
|
||||
|
||||
// If inside a comment, skip until a new line is encountered
|
||||
if (isComment) {
|
||||
if (byte == '\r' || byte == '\n') {
|
||||
isComment = 0;
|
||||
if (currentChar == '\r' || currentChar == '\n') {
|
||||
isComment = false;
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
// flag if we're starting a comment line
|
||||
if (byte == '#') {
|
||||
|
||||
// The start of a comment is indicated by a '#'
|
||||
if (currentChar == '#') {
|
||||
isComment = true;
|
||||
continue;
|
||||
}
|
||||
// so long as we don't hit newline/whitespace/hash/{ or }, we have a token!
|
||||
if (!isSpace(byte)) {
|
||||
return byte;
|
||||
|
||||
// If the byte is not a space, return it
|
||||
if (!isSpace(currentChar)) {
|
||||
return currentChar;
|
||||
}
|
||||
}
|
||||
}
|
||||
// if we reach eof or are in binary mode, return a 0
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -59,48 +68,51 @@ char Stream::skipSpace()
|
||||
bool Stream::eof() { return false; }
|
||||
|
||||
/**
|
||||
* Copies the contents of the stream to the text buffer.
|
||||
*
|
||||
* This function reads bytes from the stream and copies them to the text buffer until it encounters a space character.
|
||||
* If the space character is a '#' character, it treats the remaining bytes as a comment and stops copying.
|
||||
*
|
||||
* @note This function assumes that the text buffer has enough space to hold the copied bytes.
|
||||
*
|
||||
* @note Address: N/A
|
||||
* @note Size: 0x214
|
||||
*/
|
||||
// INLINE
|
||||
inline void Stream::copyToTextBuffer()
|
||||
{
|
||||
// copy next token (not starting with a 'space', not in a comment) to buffer
|
||||
// panic if we hit eof
|
||||
char nextByte;
|
||||
|
||||
// Skip any leading whitespace
|
||||
mBuffer[mBufferPos++] = skipSpace();
|
||||
while (!eof()) {
|
||||
nextByte = _readByte(); // at 0xA
|
||||
// if we hit a newline, whitespace, hash, { or }, put 0s until we hit something else
|
||||
nextByte = _readByte();
|
||||
|
||||
// If the next byte is a space, check if comment and null terminate the buffer
|
||||
if (isSpace(nextByte)) {
|
||||
mBuffer[mBufferPos++] = 0;
|
||||
// check if comment line
|
||||
|
||||
if (nextByte == '#') {
|
||||
while (!eof()) {
|
||||
nextByte = _readByte(); // at 0x9
|
||||
nextByte = _readByte();
|
||||
if ((nextByte != '\r') && (nextByte != '\n')) {
|
||||
// skip through comment line
|
||||
continue;
|
||||
} else {
|
||||
// we hit a new line! we're free from the comment
|
||||
return;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
return;
|
||||
} else { // we hit something else!
|
||||
|
||||
} else {
|
||||
// If the next byte is not a space, add it to the buffer
|
||||
mBuffer[mBufferPos++] = nextByte;
|
||||
|
||||
// if we hit a 0, exit
|
||||
if (!nextByte) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
// if we reach eof, panic
|
||||
|
||||
JUT_PANICLINE(98, "Reached EOF\n");
|
||||
}
|
||||
|
||||
@ -110,22 +122,13 @@ inline void Stream::copyToTextBuffer()
|
||||
*/
|
||||
char* Stream::getNextToken()
|
||||
{
|
||||
// if we're in text mode:
|
||||
// - writes next (non-comment/whitespace/newline/bracket) token into buffer
|
||||
// - returns a pointer to start of buffer
|
||||
// if we're in binary mode:
|
||||
// - returns null pointer
|
||||
|
||||
// if we're in binary mode, exit
|
||||
if (mMode == STREAM_MODE_BINARY) {
|
||||
return 0;
|
||||
// No tokenizing in binary mode
|
||||
return nullptr;
|
||||
} else {
|
||||
copyToTextBuffer();
|
||||
return mBuffer;
|
||||
}
|
||||
|
||||
// check next byte(s)
|
||||
copyToTextBuffer();
|
||||
|
||||
// return a pointer to beginning of buffer
|
||||
return mBuffer;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -134,7 +137,6 @@ char* Stream::getNextToken()
|
||||
*/
|
||||
void Stream::textBeginGroup(char* groupName)
|
||||
{
|
||||
// if in text mode, write 'beginning' characters
|
||||
if (mMode != STREAM_MODE_BINARY) {
|
||||
textWriteTab(mTabCount);
|
||||
textWriteText("# %s\r\n", groupName);
|
||||
@ -150,7 +152,6 @@ void Stream::textBeginGroup(char* groupName)
|
||||
*/
|
||||
void Stream::textEndGroup()
|
||||
{
|
||||
// if in text mode, write 'ending' characters
|
||||
if (mMode != STREAM_MODE_BINARY) {
|
||||
mTabCount--;
|
||||
textWriteTab(mTabCount);
|
||||
@ -159,20 +160,26 @@ void Stream::textEndGroup()
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints formatted text to the stream.
|
||||
*
|
||||
* This function takes a format string and a variable number of arguments, similar to the standard
|
||||
* C library function `printf`. The formatted text is written to the stream.
|
||||
*
|
||||
* @param format The format string specifying the text to be printed.
|
||||
* @param ... The variable arguments to be formatted and printed.
|
||||
*
|
||||
* @note Address: 0x804140F8
|
||||
* @note Size: 0xE4
|
||||
*/
|
||||
void Stream::printf(char* format, ...)
|
||||
{
|
||||
// prints text with given format information
|
||||
// doesn't check for text or binary, prints just the same
|
||||
char tempText[0x400];
|
||||
va_list args;
|
||||
|
||||
va_start(args, format);
|
||||
vsprintf(tempText, format, args);
|
||||
int len = strlen(tempText);
|
||||
|
||||
int len = strlen(tempText);
|
||||
if (len > 0) {
|
||||
char* textPtr = tempText;
|
||||
|
||||
@ -184,132 +191,124 @@ void Stream::printf(char* format, ...)
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes formatted text to the stream.
|
||||
*
|
||||
* This function writes formatted text to the stream using the specified format string and variable arguments.
|
||||
* The format string is similar to the one used in the standard C library's `printf` function.
|
||||
*
|
||||
* @param format The format string specifying the text to be written.
|
||||
* @param ... The variable arguments to be formatted and written to the stream.
|
||||
*
|
||||
* @remarks This function only writes text to the stream if the stream mode is not set to `STREAM_MODE_BINARY`.
|
||||
* If the stream mode is `STREAM_MODE_BINARY`, this function does nothing.
|
||||
*
|
||||
* @note Address: 0x804141DC
|
||||
* @note Size: 0xEC
|
||||
*/
|
||||
void Stream::textWriteText(char* format, ...)
|
||||
{
|
||||
// prints text with given format information
|
||||
// only prints text - won't print binary
|
||||
char tempText[0x400];
|
||||
va_list args;
|
||||
|
||||
if (mMode != STREAM_MODE_BINARY) {
|
||||
va_start(args, format);
|
||||
vsprintf(tempText, format, args);
|
||||
if (mMode == STREAM_MODE_BINARY) {
|
||||
return;
|
||||
}
|
||||
|
||||
int len = strlen(tempText);
|
||||
if (len > 0) {
|
||||
char* textPtr = tempText;
|
||||
va_start(args, format);
|
||||
vsprintf(tempText, format, args);
|
||||
|
||||
for (int i = 0; i < len; i++) {
|
||||
_writeByte(*textPtr);
|
||||
textPtr++;
|
||||
}
|
||||
int len = strlen(tempText);
|
||||
if (len > 0) {
|
||||
char* textPtr = tempText;
|
||||
|
||||
for (int i = 0; i < len; i++) {
|
||||
_writeByte(*textPtr);
|
||||
textPtr++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// /**
|
||||
// * @note Address: N/A
|
||||
// * @note Size: 0x70
|
||||
// */
|
||||
// void Stream::writePadding(u32)
|
||||
// {
|
||||
// // UNUSED FUNCTION - in stream.h header
|
||||
// }
|
||||
|
||||
/**
|
||||
* @note Address: N/A
|
||||
* @note Size: 0x6C
|
||||
*/
|
||||
// void Stream::skipPadding(u32)
|
||||
// {
|
||||
// // UNUSED FUNCTION
|
||||
// }
|
||||
|
||||
/**
|
||||
* Skips reading a specified number of bytes from the stream.
|
||||
*
|
||||
* @param len The number of bytes to skip.
|
||||
*
|
||||
* @note Address: 0x804142C8
|
||||
* @note Size: 0xC4
|
||||
*/
|
||||
void Stream::skipReading(u32 len)
|
||||
{
|
||||
// 'skips' whatever is being streamed byte by byte
|
||||
// need to handle differently if in text or binary mode
|
||||
// skips to next line in text mode
|
||||
// this version comes with a length 'len' for binary mode
|
||||
|
||||
// check mode
|
||||
if (mMode == STREAM_MODE_TEXT) { // we're in text mode
|
||||
// 'skip' through, but need to look out for new lines
|
||||
if (mMode == STREAM_MODE_TEXT) {
|
||||
while (!eof()) {
|
||||
s8 currByte = _readByte();
|
||||
|
||||
// If it isn't whitespace, continue
|
||||
if (currByte != '\r' && currByte != '\n') {
|
||||
continue;
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
|
||||
// If it is whitespace, return (skipped text)
|
||||
return;
|
||||
}
|
||||
} else { // we're in binary mode
|
||||
// loop through the stream up to 'len' and 'skip' it
|
||||
} else {
|
||||
for (int i = 0; i < len && !eof(); i++) {
|
||||
readByte();
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Skips reading text or bytes from the stream based on the stream mode.
|
||||
*
|
||||
* This function handles two different modes: STREAM_MODE_TEXT and other modes.
|
||||
* In STREAM_MODE_TEXT, it reads bytes until it encounters a newline ('\n') or carriage return ('\r') character.
|
||||
* In other modes, it reads bytes until it encounters a null byte (0).
|
||||
*
|
||||
* @note Address: 0x8041438C
|
||||
* @note Size: 0xA8
|
||||
*/
|
||||
void Stream::skipReadingText()
|
||||
{
|
||||
// 'skips' whatever is being streamed byte by byte
|
||||
// need to handle differently if in text or binary mode
|
||||
// skips to next line in text mode
|
||||
// this version doesn't come with a length for binary mode
|
||||
|
||||
// check mode
|
||||
if (mMode == STREAM_MODE_TEXT) { // we're in text mode
|
||||
// 'skip' through, but need to look out for 0xD and 0xA markers
|
||||
if (mMode == STREAM_MODE_TEXT) {
|
||||
while (!eof()) {
|
||||
s8 currByte = _readByte();
|
||||
|
||||
// If it isn't whitespace, continue
|
||||
if (currByte != '\r' && currByte != '\n') {
|
||||
continue;
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
|
||||
// If it is whitespace, return (skipped text)
|
||||
return;
|
||||
}
|
||||
} else { // we're in binary mode
|
||||
// we can just loop through the whole stream and 'skip' it
|
||||
// so long as readByte returns something
|
||||
} else {
|
||||
while (!eof()) {
|
||||
if (!readByte()) {
|
||||
if (readByte() == 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* @note Address: N/A
|
||||
* @note Size: 0x50
|
||||
*/
|
||||
// void Stream::_read(void*, int)
|
||||
// {
|
||||
// // UNUSED FUNCTION
|
||||
// }
|
||||
void Stream::_read(void* buffer, int length)
|
||||
{
|
||||
read(buffer, length);
|
||||
mPosition += length;
|
||||
}
|
||||
|
||||
/**
|
||||
* @note Address: N/A
|
||||
* @note Size: 0x50
|
||||
*/
|
||||
// void Stream::_write(void*, int)
|
||||
// {
|
||||
// // UNUSED FUNCTION
|
||||
// }
|
||||
void Stream::_write(void* buffer, int length)
|
||||
{
|
||||
write(buffer, length);
|
||||
mPosition += length;
|
||||
}
|
||||
|
||||
/**
|
||||
* @note Address: 0x80414434
|
||||
@ -330,29 +329,19 @@ void Stream::textWriteTab(int tabCount)
|
||||
*/
|
||||
u8 Stream::readByte()
|
||||
{
|
||||
// if we're in text mode:
|
||||
// - returns next byte (assuming it's not a comment or special character)
|
||||
// if we're in binary mode:
|
||||
// - returns next byte with no checks
|
||||
|
||||
int scanOut;
|
||||
|
||||
// check if we're in text mode or binary mode
|
||||
if (mMode == STREAM_MODE_TEXT) { // we're in text mode, need to do more checks
|
||||
if (mMode == STREAM_MODE_TEXT) {
|
||||
|
||||
char* nextToken = getNextToken();
|
||||
// if we have a null pointer, panic
|
||||
if (!nextToken) {
|
||||
JUT_PANICLINE(260, "readByte:Token Error\n");
|
||||
}
|
||||
|
||||
// take byte from nextToken and put it into scanOut
|
||||
sscanf(nextToken, "%d", &scanOut);
|
||||
// return byte
|
||||
return (u8)scanOut;
|
||||
}
|
||||
|
||||
// we're in binary mode, who needs checks
|
||||
return _readByte();
|
||||
}
|
||||
|
||||
@ -362,12 +351,8 @@ u8 Stream::readByte()
|
||||
*/
|
||||
u8 Stream::_readByte()
|
||||
{
|
||||
// reads in the next byte with no checks
|
||||
// returns byte being read and increments stream position
|
||||
|
||||
u8 currByte;
|
||||
read(&currByte, 1);
|
||||
mPosition++;
|
||||
_read(&currByte, 1);
|
||||
return currByte;
|
||||
}
|
||||
|
||||
@ -375,38 +360,27 @@ u8 Stream::_readByte()
|
||||
* @note Address: 0x80414764
|
||||
* @note Size: 0x32C
|
||||
*/
|
||||
s16 Stream::readShort()
|
||||
short Stream::readShort()
|
||||
{
|
||||
// if we're in text mode:
|
||||
// - returns next 2 bytes, treated as short (assuming it's not a comment or special character)
|
||||
// if we're in binary mode:
|
||||
// - returns next 2 bytes with no checks
|
||||
|
||||
u16 outVal;
|
||||
|
||||
if (mMode == STREAM_MODE_TEXT) { // we're in text mode, need to do more checks
|
||||
|
||||
if (mMode == STREAM_MODE_TEXT) {
|
||||
char* nextToken = getNextToken();
|
||||
// if we have a null pointer, panic
|
||||
if (!nextToken) {
|
||||
JUT_PANICLINE(284, "readShort:Token Error\n");
|
||||
}
|
||||
|
||||
int scanOut;
|
||||
// take bytes from nextToken and put it into scanOut
|
||||
sscanf(nextToken, "%d", &scanOut);
|
||||
// return result
|
||||
|
||||
outVal = scanOut;
|
||||
return outVal;
|
||||
}
|
||||
|
||||
// we're in binary mode, who needs checks
|
||||
read(&outVal, 2);
|
||||
mPosition += 2;
|
||||
// swap endian if necessary
|
||||
if (mEndian != STREAM_BIG_ENDIAN) {
|
||||
u32 byte1 = (outVal >> 8) & 0x000000FF;
|
||||
u32 byte2 = (outVal << 8) & 0x0000FF00;
|
||||
outVal = (byte2 | byte1);
|
||||
_read(&outVal, sizeof(short));
|
||||
|
||||
if (differentEndian()) {
|
||||
outVal = ((outVal << 8) & 0xFF00 | (outVal >> 8) & 0xFF);
|
||||
}
|
||||
|
||||
return outVal;
|
||||
@ -418,38 +392,27 @@ s16 Stream::readShort()
|
||||
*/
|
||||
int Stream::readInt()
|
||||
{
|
||||
// if we're in text mode:
|
||||
// - returns next 4 bytes, treated as int (assuming it's not a comment or special character)
|
||||
// if we're in binary mode:
|
||||
// - returns next 4 bytes with no checks
|
||||
|
||||
int outVal;
|
||||
|
||||
if (mMode == STREAM_MODE_TEXT) { // we're in text mode, need to do more checks
|
||||
|
||||
if (mMode == STREAM_MODE_TEXT) {
|
||||
char* nextToken = getNextToken();
|
||||
|
||||
// if we have a null pointer, panic
|
||||
if (!nextToken) {
|
||||
JUT_PANICLINE(306, "readInt:Token Error\n");
|
||||
}
|
||||
|
||||
// take bytes from nextToken and put it into outVal
|
||||
sscanf(nextToken, "%d", &outVal);
|
||||
// return result
|
||||
return outVal;
|
||||
}
|
||||
|
||||
// we're in binary mode, who needs checks
|
||||
read(&outVal, 4);
|
||||
mPosition += 4;
|
||||
// swap endian if necessary
|
||||
if (mEndian != STREAM_BIG_ENDIAN) {
|
||||
_read(&outVal, sizeof(int));
|
||||
|
||||
if (differentEndian()) {
|
||||
int byte1 = ((u32)outVal >> 24) & 0x000000FF;
|
||||
int byte2 = ((u32)outVal >> 8) & 0x0000FF00;
|
||||
int byte3 = ((u32)outVal << 8) & 0x00FF0000;
|
||||
int byte4 = ((u32)outVal << 24) & 0xFF000000;
|
||||
outVal = (byte4 | byte3 | byte2 | byte1);
|
||||
|
||||
outVal = (byte4 | byte3 | byte2 | byte1);
|
||||
}
|
||||
|
||||
return outVal;
|
||||
@ -461,39 +424,30 @@ int Stream::readInt()
|
||||
*/
|
||||
f32 Stream::readFloat()
|
||||
{
|
||||
// if we're in text mode:
|
||||
// - returns next 4 bytes, treated as float (assuming it's not a comment or special character)
|
||||
// if we're in binary mode:
|
||||
// - returns next 4 bytes with no checks
|
||||
f32 outFloat;
|
||||
int outInt;
|
||||
|
||||
if (mMode == STREAM_MODE_TEXT) { // we're in text mode, need to do more checks
|
||||
if (mMode == STREAM_MODE_TEXT) {
|
||||
char* nextToken = getNextToken();
|
||||
|
||||
// if we have a null pointer, panic
|
||||
if (!nextToken) {
|
||||
JUT_PANICLINE(324, "readFloat:Token Error\n");
|
||||
}
|
||||
|
||||
// take bytes from bufferPtr and put it into outFloat
|
||||
sscanf(nextToken, "%f", &outFloat);
|
||||
// return result
|
||||
return outFloat;
|
||||
}
|
||||
|
||||
// we're in binary mode, who needs checks
|
||||
read(&outFloat, 4);
|
||||
mPosition += 4;
|
||||
// swap endian if necessary
|
||||
if (mEndian != STREAM_BIG_ENDIAN) {
|
||||
_read(&outFloat, sizeof(float));
|
||||
|
||||
if (differentEndian()) {
|
||||
int outInt = *(u32*)&outFloat;
|
||||
int byte1 = ((u32)outInt >> 24) & 0x000000FF;
|
||||
int byte2 = ((u32)outInt >> 8) & 0x0000FF00;
|
||||
int byte3 = ((u32)outInt << 8) & 0x00FF0000;
|
||||
int byte4 = ((u32)outInt << 24) & 0xFF000000;
|
||||
outInt = (byte4 | byte3 | byte2 | byte1);
|
||||
outFloat = *(f32*)&outInt;
|
||||
|
||||
outInt = (byte4 | byte3 | byte2 | byte1);
|
||||
outFloat = *(f32*)&outInt;
|
||||
}
|
||||
|
||||
return outFloat;
|
||||
@ -503,62 +457,52 @@ f32 Stream::readFloat()
|
||||
* @note Address: 0x804150D4
|
||||
* @note Size: 0x4F8
|
||||
*/
|
||||
// only final for loop not matching
|
||||
char* Stream::readString(char* str, int strLength)
|
||||
{
|
||||
// reads string from stream
|
||||
// if str provided, stores in str text of length strLength
|
||||
// if str 0, returns string to next token
|
||||
|
||||
char* outStr;
|
||||
|
||||
if (mMode == STREAM_MODE_TEXT) { // we're in text mode, need to do more checks
|
||||
|
||||
// get text
|
||||
if (mMode == STREAM_MODE_TEXT) {
|
||||
char* nextToken = getNextToken();
|
||||
int strSize = strlen(nextToken);
|
||||
|
||||
int strSize = strlen(nextToken);
|
||||
if (str) { // str provided, check size compared to text
|
||||
if (str) {
|
||||
P2ASSERTLINE(352, strLength >= strSize);
|
||||
outStr = str;
|
||||
} else { // no str provided, read in whole nextToken
|
||||
} else {
|
||||
outStr = new char[strSize + 1];
|
||||
}
|
||||
|
||||
// put text byte by byte into outStr
|
||||
for (int readLen = 0; readLen < strSize + 1; readLen++) {
|
||||
outStr[readLen] = nextToken[readLen];
|
||||
}
|
||||
|
||||
} else { // we're in binary mode, free-for-all
|
||||
// read max of 0x400 bytes
|
||||
return outStr;
|
||||
} else /* Binary mode */ {
|
||||
char tokenStore[0x400];
|
||||
|
||||
// read up to 0x400 bytes into tokenStore
|
||||
int readLen = 0;
|
||||
for (int i = 0; i < 0x400 || !eof(); i++) {
|
||||
u8 byte = _readByte();
|
||||
tokenStore[i] = byte;
|
||||
if (!(tokenStore[i]))
|
||||
tokenStore[i] = _readByte();
|
||||
if (tokenStore[i] == '\0') {
|
||||
break;
|
||||
}
|
||||
|
||||
readLen++;
|
||||
}
|
||||
|
||||
if (str) { // str provided, check size compared to text
|
||||
if (str) {
|
||||
P2ASSERTLINE(372, strLength >= readLen);
|
||||
outStr = str;
|
||||
} else { // no str provided, read in whole tokenStore
|
||||
} else {
|
||||
outStr = new char[readLen + 1];
|
||||
}
|
||||
|
||||
// put text byte by byte into outStr
|
||||
int i = 0;
|
||||
char* outStrPtr = outStr;
|
||||
for (i; i < readLen; i++) {
|
||||
*outStrPtr = tokenStore[i];
|
||||
outStrPtr++;
|
||||
}
|
||||
*outStrPtr = 0;
|
||||
outStrPtr[0] = '\0';
|
||||
}
|
||||
|
||||
return outStr;
|
||||
@ -568,63 +512,50 @@ char* Stream::readString(char* str, int strLength)
|
||||
* @note Address: N/A
|
||||
* @note Size: 0x64C
|
||||
*/
|
||||
const char UNUSED_readFixedString[] = "can not use readFixedString in text mode\n";
|
||||
// void Stream::readFixedString()
|
||||
// {
|
||||
//
|
||||
// }
|
||||
|
||||
const char UNUSED_readFixedString[] = "can not use readFixedString in text mode\n";
|
||||
|
||||
/**
|
||||
* @note Address: 0x804155CC
|
||||
* @note Size: 0xA4
|
||||
*/
|
||||
void Stream::writeString(char* inputStr)
|
||||
{
|
||||
// write input string byte by byte
|
||||
// binary output ends with 0, text with " "
|
||||
|
||||
// check length of string then loop over length
|
||||
int len = strlen(inputStr);
|
||||
for (int i = 0; i < len; i++) {
|
||||
// write byte with no checks
|
||||
_writeByte(inputStr[i]);
|
||||
}
|
||||
|
||||
if (mMode == STREAM_MODE_TEXT) {
|
||||
// end text mode output with space
|
||||
printf(" ");
|
||||
return;
|
||||
} else {
|
||||
_writeByte('\0');
|
||||
}
|
||||
// end binary mode output with 0
|
||||
_writeByte(0);
|
||||
}
|
||||
|
||||
/**
|
||||
* @note Address: N/A
|
||||
* @note Size: 0xBC
|
||||
*/
|
||||
const char UNUSED_writeFixedString[] = "can not use writeFixedString in text mode\n";
|
||||
// void Stream::writeFixedString(char*)
|
||||
// {
|
||||
// // UNUSED FUNCTION
|
||||
// }
|
||||
|
||||
const char UNUSED_writeFixedString[] = "can not use writeFixedString in text mode\n";
|
||||
|
||||
/**
|
||||
* @note Address: 0x80415670
|
||||
* @note Size: 0x70
|
||||
*/
|
||||
void Stream::writeByte(u8 c)
|
||||
{
|
||||
// write next byte + increment position
|
||||
// check if we're in text or binary and write "%d " if in text
|
||||
u8 buffer = c;
|
||||
if (mMode == 1) {
|
||||
if (mMode == STREAM_MODE_TEXT) {
|
||||
printf("%d ", c);
|
||||
} else {
|
||||
write(&buffer, 1);
|
||||
mPosition++;
|
||||
_write(&c, sizeof(u8));
|
||||
}
|
||||
}
|
||||
|
||||
@ -634,11 +565,8 @@ void Stream::writeByte(u8 c)
|
||||
*/
|
||||
void Stream::_writeByte(u8 c)
|
||||
{
|
||||
// write next byte + increment position
|
||||
// no checks for mode type
|
||||
u8 buffer = c;
|
||||
write(&buffer, 1);
|
||||
mPosition++;
|
||||
_write(&buffer, sizeof(u8));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -647,25 +575,17 @@ void Stream::_writeByte(u8 c)
|
||||
*/
|
||||
void Stream::writeShort(s16 inputShort)
|
||||
{
|
||||
// write s16 (s16)
|
||||
// need to handle text and binary mode differently
|
||||
|
||||
// by default, value to write should be inputShort
|
||||
s16 outVal = inputShort;
|
||||
if (mMode == STREAM_MODE_TEXT) {
|
||||
// in text mode, write with "%d "
|
||||
printf("%d ", inputShort);
|
||||
return;
|
||||
}
|
||||
// make sure stream value is big endian
|
||||
if (mEndian != STREAM_BIG_ENDIAN) {
|
||||
// if it's not big endian, swap bytes to make it big endian
|
||||
outVal = bswap16((s16)inputShort);
|
||||
}
|
||||
|
||||
// write s16 (2 bytes) and increment stream position
|
||||
write(&outVal, 2);
|
||||
mPosition += 2;
|
||||
if (mMode == STREAM_MODE_TEXT) {
|
||||
printf("%d ", inputShort);
|
||||
} else {
|
||||
if (differentEndian()) {
|
||||
outVal = bswap16((s16)inputShort);
|
||||
}
|
||||
|
||||
_write(&outVal, sizeof(s16));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -674,28 +594,21 @@ void Stream::writeShort(s16 inputShort)
|
||||
*/
|
||||
void Stream::writeInt(int inputInt)
|
||||
{
|
||||
// write int (4 bytes)
|
||||
// need to handle text and binary mode differently
|
||||
|
||||
// by default, value to write should be inputInt
|
||||
int outVal = inputInt;
|
||||
|
||||
if (mMode == STREAM_MODE_TEXT) {
|
||||
// in text mode, write with "%d "
|
||||
printf("%d ", inputInt);
|
||||
return;
|
||||
} else {
|
||||
if (differentEndian()) {
|
||||
int byte1 = ((u32)inputInt >> 24) & 0xFF;
|
||||
int byte2 = ((u32)inputInt >> 8) & 0xFF00;
|
||||
int byte3 = ((u32)inputInt << 8) & 0xFF0000;
|
||||
int byte4 = ((u32)inputInt << 24) & 0xFF000000;
|
||||
outVal = (byte4 | byte3 | byte2 | byte1);
|
||||
}
|
||||
|
||||
_write(&outVal, sizeof(int));
|
||||
}
|
||||
// make sure stream value is big endian
|
||||
if (mEndian != STREAM_BIG_ENDIAN) {
|
||||
// if it's not big endian, swap bytes to make it big endian
|
||||
int byte1 = ((u32)inputInt >> 24) & 0x000000FF;
|
||||
int byte2 = ((u32)inputInt >> 8) & 0x0000FF00;
|
||||
int byte3 = ((u32)inputInt << 8) & 0x00FF0000;
|
||||
int byte4 = ((u32)inputInt << 24) & 0xFF000000;
|
||||
outVal = (byte4 | byte3 | byte2 | byte1);
|
||||
}
|
||||
// write int (4 bytes) and increment stream position
|
||||
write(&outVal, 4);
|
||||
mPosition += 4;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -704,33 +617,23 @@ void Stream::writeInt(int inputInt)
|
||||
*/
|
||||
void Stream::writeFloat(f32 inputFloat)
|
||||
{
|
||||
// write float (4 bytes)
|
||||
// need to handle text and binary mode differently
|
||||
|
||||
// by default, value to write should be inputFloat
|
||||
if (mMode == STREAM_MODE_TEXT) {
|
||||
// in text mode, write with "%f "
|
||||
printf("%f ", inputFloat);
|
||||
return;
|
||||
}
|
||||
// check if stream value is big endian
|
||||
if (mEndian != STREAM_BIG_ENDIAN) {
|
||||
// if it's not big endian, swap bytes
|
||||
u32 data = *(u32*)&inputFloat;
|
||||
int byte1 = (data >> 24) & 0x000000FF;
|
||||
int byte2 = (data >> 8) & 0x0000FF00;
|
||||
int byte3 = (data << 8) & 0x00FF0000;
|
||||
int byte4 = (data << 24) & 0xFF000000;
|
||||
int intVal = (byte4 | byte3 | byte2 | byte1);
|
||||
// write float (4 bytes) and increment stream position
|
||||
write(&intVal, 4);
|
||||
mPosition += 4;
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
if (differentEndian()) {
|
||||
u32 data = *(u32*)&inputFloat;
|
||||
int byte1 = (data >> 24) & 0x000000FF;
|
||||
int byte2 = (data >> 8) & 0x0000FF00;
|
||||
int byte3 = (data << 8) & 0x00FF0000;
|
||||
int byte4 = (data << 24) & 0xFF000000;
|
||||
int intVal = (byte4 | byte3 | byte2 | byte1);
|
||||
|
||||
// write float (4 bytes) and increment stream position
|
||||
write(&inputFloat, 4);
|
||||
mPosition += 4;
|
||||
_write(&intVal, sizeof(float));
|
||||
return;
|
||||
}
|
||||
|
||||
_write(&inputFloat, sizeof(float));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -759,10 +662,10 @@ RamStream::RamStream(void* RamBufferPtr, int bounds)
|
||||
*/
|
||||
void RamStream::read(void* destMem, int numBytes)
|
||||
{
|
||||
if (eof()) { // if we're past the end of the file, panic
|
||||
if (eof()) {
|
||||
JUT_PANICLINE(523, "RamStream::read out of bounds (pos=%d,bound=%d)\n", mPosition, mBounds);
|
||||
}
|
||||
// read numBytes bytes from mRamBufferStart + mPosition to destMem in mem
|
||||
|
||||
memcpy(destMem, ((u8*)mRamBufferStart) + mPosition, numBytes);
|
||||
}
|
||||
|
||||
@ -773,10 +676,10 @@ void RamStream::read(void* destMem, int numBytes)
|
||||
|
||||
void RamStream::write(void* srcMem, int numBytes)
|
||||
{
|
||||
if (eof()) { // if we're past the end of the file, panic
|
||||
if (eof()) {
|
||||
JUT_PANICLINE(534, "RamStream::write out of bounds (pos=%d,bound=%d)\n", mPosition, mBounds);
|
||||
}
|
||||
// write numBytes bytes from srcMem to mRamBufferStart + mPosition
|
||||
|
||||
memcpy(((u8*)mRamBufferStart) + mPosition, srcMem, numBytes);
|
||||
}
|
||||
|
||||
@ -786,10 +689,10 @@ void RamStream::write(void* srcMem, int numBytes)
|
||||
*/
|
||||
bool RamStream::eof()
|
||||
{
|
||||
// check if we're at the end of the 'file'
|
||||
if (mBounds != -1) {
|
||||
return (mBounds <= mPosition);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -95,15 +95,15 @@ f32 pikmin2_sqrtf(register f32 x)
|
||||
*/
|
||||
f32 qdist2(f32 x1, f32 y1, f32 x2, f32 y2)
|
||||
{
|
||||
f32 deltaX = x2 - x1;
|
||||
f32 deltaY = y2 - y1;
|
||||
|
||||
f32 xdiff = (x2 - x1);
|
||||
f32 ydiff = (y2 - y1);
|
||||
|
||||
f32 dist = ((xdiff * xdiff) + (ydiff * ydiff));
|
||||
f32 dist = SQUARE(deltaX) + SQUARE(deltaY);
|
||||
if (dist > 0.0f) {
|
||||
vf32 calcDist = dist * (__frsqrte(dist));
|
||||
dist = calcDist;
|
||||
}
|
||||
|
||||
return dist;
|
||||
}
|
||||
|
||||
@ -113,11 +113,7 @@ f32 qdist2(f32 x1, f32 y1, f32 x2, f32 y2)
|
||||
*/
|
||||
f32 qdist3(f32 x1, f32 y1, f32 z1, f32 x2, f32 y2, f32 z2)
|
||||
{
|
||||
f32 xdiff = (x2 - x1);
|
||||
f32 ydiff = (y2 - y1);
|
||||
f32 zdiff = (z2 - z1);
|
||||
Vector3f xyz(xdiff, ydiff, zdiff);
|
||||
|
||||
Vector3f xyz(x2 - x1, y2 - y1, z2 - z1);
|
||||
return xyz.qLength();
|
||||
}
|
||||
|
||||
@ -134,34 +130,34 @@ Vector3f CRSpline(f32 t, Vector3f* controls)
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates the tangent of a Catmull-Rom spline at a given parameter value.
|
||||
*
|
||||
* @param t The parameter value of the spline (between 0 and 1).
|
||||
* @param controls An array of four control points that define the spline.
|
||||
* @return The tangent vector at the given parameter value.
|
||||
*
|
||||
* @note Address: 0x80411858
|
||||
* @note Size: 0xF4
|
||||
*/
|
||||
Vector3f CRSplineTangent(f32 t, Vector3f* controls)
|
||||
/* == Centripetal Catmull-Rom Spline tangent calculation ==
|
||||
Outputs tangent vector of desired point, given:
|
||||
- coords for a set of 4 control points (controls[0] to controls[4]) for the curve, and
|
||||
- a parameter for the curve, t, between 0 and 1
|
||||
- t represents how 'far' between controls[1] and controls[2] the desired point is
|
||||
- so t=0, point will be controls[1]; t=1, point will be controls[2]
|
||||
*/
|
||||
{
|
||||
f32 tSqr = t * t;
|
||||
Vector3f out;
|
||||
|
||||
// set coefficients - the floats are from centripetal CR matrices, assuming no tension
|
||||
// (this is actually just drawn out matrix multiplication)
|
||||
// Calculate the 4 basis functions for the Catmull-Rom spline
|
||||
f32 f0 = (-1.5f * tSqr) + (2.0f * t) - 0.5f;
|
||||
f32 f1 = (4.5f * tSqr) - 5.0f * t;
|
||||
f32 f2 = (-4.5f * tSqr) + (4.0f * t) + 0.5f;
|
||||
f32 f3 = (1.5f * tSqr) - t;
|
||||
|
||||
// Multiply each control point by its corresponding basis function
|
||||
Vector3f ctr0 = controls[0] * f0;
|
||||
Vector3f ctr1 = controls[1] * f1;
|
||||
Vector3f ctr2 = controls[2] * f2;
|
||||
Vector3f ctr3 = controls[3] * f3;
|
||||
out = ctr0 + ctr1 + ctr2 + ctr3;
|
||||
|
||||
// Add the results together to get the tangent
|
||||
out = ctr0 + ctr1 + ctr2 + ctr3;
|
||||
return out;
|
||||
}
|
||||
|
||||
@ -410,83 +406,9 @@ Quat::Quat(f32 _w, Vector3f vec)
|
||||
*/
|
||||
Quat::Quat(RPY& rpy)
|
||||
{
|
||||
FORCE_DONT_INLINE;
|
||||
FORCE_DONT_INLINE;
|
||||
FORCE_DONT_INLINE;
|
||||
FORCE_DONT_INLINE;
|
||||
FORCE_DONT_INLINE;
|
||||
FORCE_DONT_INLINE;
|
||||
FORCE_DONT_INLINE;
|
||||
FORCE_DONT_INLINE;
|
||||
FORCE_DONT_INLINE;
|
||||
FORCE_DONT_INLINE;
|
||||
FORCE_DONT_INLINE;
|
||||
FORCE_DONT_INLINE;
|
||||
FORCE_DONT_INLINE;
|
||||
FORCE_DONT_INLINE;
|
||||
FORCE_DONT_INLINE;
|
||||
FORCE_DONT_INLINE;
|
||||
FORCE_DONT_INLINE;
|
||||
FORCE_DONT_INLINE;
|
||||
FORCE_DONT_INLINE;
|
||||
FORCE_DONT_INLINE;
|
||||
FORCE_DONT_INLINE;
|
||||
FORCE_DONT_INLINE;
|
||||
FORCE_DONT_INLINE;
|
||||
FORCE_DONT_INLINE;
|
||||
FORCE_DONT_INLINE;
|
||||
FORCE_DONT_INLINE;
|
||||
FORCE_DONT_INLINE;
|
||||
FORCE_DONT_INLINE;
|
||||
FORCE_DONT_INLINE;
|
||||
FORCE_DONT_INLINE;
|
||||
FORCE_DONT_INLINE;
|
||||
FORCE_DONT_INLINE;
|
||||
FORCE_DONT_INLINE;
|
||||
FORCE_DONT_INLINE;
|
||||
FORCE_DONT_INLINE;
|
||||
FORCE_DONT_INLINE;
|
||||
FORCE_DONT_INLINE;
|
||||
FORCE_DONT_INLINE;
|
||||
FORCE_DONT_INLINE;
|
||||
FORCE_DONT_INLINE;
|
||||
FORCE_DONT_INLINE;
|
||||
FORCE_DONT_INLINE;
|
||||
FORCE_DONT_INLINE;
|
||||
FORCE_DONT_INLINE;
|
||||
FORCE_DONT_INLINE;
|
||||
FORCE_DONT_INLINE;
|
||||
FORCE_DONT_INLINE;
|
||||
FORCE_DONT_INLINE;
|
||||
FORCE_DONT_INLINE;
|
||||
FORCE_DONT_INLINE;
|
||||
FORCE_DONT_INLINE;
|
||||
FORCE_DONT_INLINE;
|
||||
FORCE_DONT_INLINE;
|
||||
FORCE_DONT_INLINE;
|
||||
FORCE_DONT_INLINE;
|
||||
FORCE_DONT_INLINE;
|
||||
FORCE_DONT_INLINE;
|
||||
FORCE_DONT_INLINE;
|
||||
FORCE_DONT_INLINE;
|
||||
FORCE_DONT_INLINE;
|
||||
FORCE_DONT_INLINE;
|
||||
FORCE_DONT_INLINE;
|
||||
FORCE_DONT_INLINE;
|
||||
FORCE_DONT_INLINE;
|
||||
FORCE_DONT_INLINE;
|
||||
FORCE_DONT_INLINE;
|
||||
FORCE_DONT_INLINE;
|
||||
FORCE_DONT_INLINE;
|
||||
FORCE_DONT_INLINE;
|
||||
FORCE_DONT_INLINE;
|
||||
FORCE_DONT_INLINE;
|
||||
FORCE_DONT_INLINE;
|
||||
Quat quat(0.0f, Vector3f(0.0f, 0.0f, 0.0f));
|
||||
Quat quat2(0.0f, Vector3f(0.0f, 0.0f, 0.0f));
|
||||
*this = quat * quat2;
|
||||
// this needs to spawn the operator* weak function somehow
|
||||
// probably is recursive? this will do for now to match it
|
||||
}
|
||||
|
||||
/**
|
||||
@ -495,24 +417,24 @@ Quat::Quat(RPY& rpy)
|
||||
*/
|
||||
void Quat::set(Vector3f& vec)
|
||||
{
|
||||
Quat q1; // 0x48
|
||||
Quat q2; // 0x38
|
||||
Quat q3; // 0x28
|
||||
Quat quatX;
|
||||
Quat quatY;
|
||||
Quat quatZ;
|
||||
|
||||
f32 cos_x = cos(0.5f * vec.x);
|
||||
f32 sin_x = pikmin2_sinf(0.5f * vec.x);
|
||||
q1.set(cos_x, sin_x, 0.0f, 0.0f);
|
||||
f32 cosHalfX = cos(0.5f * vec.x);
|
||||
f32 sinHalfX = pikmin2_sinf(0.5f * vec.x);
|
||||
quatX.set(cosHalfX, sinHalfX, 0.0f, 0.0f);
|
||||
|
||||
f32 cos_y = cos(0.5f * vec.y);
|
||||
f32 sin_y = pikmin2_sinf(0.5f * vec.y);
|
||||
q2.set(cos_y, 0.0f, sin_y, 0.0f);
|
||||
f32 cosHalfY = cos(0.5f * vec.y);
|
||||
f32 sinHalfY = pikmin2_sinf(0.5f * vec.y);
|
||||
quatY.set(cosHalfY, 0.0f, sinHalfY, 0.0f);
|
||||
|
||||
f32 cos_z = cos(0.5f * vec.z);
|
||||
f32 sin_z = pikmin2_sinf(0.5f * vec.z);
|
||||
q3.set(cos_z, 0.0f, 0.0f, sin_z);
|
||||
f32 cosHalfZ = cos(0.5f * vec.z);
|
||||
f32 sinHalfZ = pikmin2_sinf(0.5f * vec.z);
|
||||
quatZ.set(cosHalfZ, 0.0f, 0.0f, sinHalfZ);
|
||||
|
||||
*this = q3 * q2;
|
||||
*this = *this * q1;
|
||||
*this = quatZ * quatY;
|
||||
*this = *this * quatX;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -620,10 +542,6 @@ void Quat::normalise()
|
||||
*this = quat;
|
||||
}
|
||||
|
||||
/**
|
||||
* @note Address: 0x804128F0
|
||||
* @note Size: 0x348
|
||||
*/
|
||||
/**
|
||||
* Performs Spherical Linear Interpolation (SLERP) between two quaternions.
|
||||
* This function calculates a quaternion that represents a rotation from the start point to the end point
|
||||
@ -632,6 +550,9 @@ void Quat::normalise()
|
||||
* @param q1 The end point of the path.
|
||||
* @param t The linear interpolation parameter (how far from start to end do we want to be).
|
||||
* @param qout The interpolated quaternion on the path, fraction t from start.
|
||||
*
|
||||
* @note Address: 0x804128F0
|
||||
* @note Size: 0x348
|
||||
*/
|
||||
void Quat::slerp(Quat& q1, f32 t, Quat& qout)
|
||||
{
|
||||
@ -983,74 +904,87 @@ void Quat::toMatrix(Matrix3f& m)
|
||||
*/
|
||||
void Quat::fromMatrixf(Matrixf& mtx)
|
||||
{
|
||||
int case_var;
|
||||
f32 temp_norm;
|
||||
int maxElementCase;
|
||||
f32 averageElement = 0.25f * (1.0f + (mtx.mMatrix.mtxView[2][2] + (mtx.mMatrix.mtxView[0][0] + mtx.mMatrix.mtxView[1][1])));
|
||||
f32 element00 = -((0.5f * (mtx.mMatrix.mtxView[1][1] + mtx.mMatrix.mtxView[2][2])) - averageElement);
|
||||
f32 element11 = -((0.5f * (mtx.mMatrix.mtxView[2][2] + mtx.mMatrix.mtxView[0][0])) - averageElement);
|
||||
f32 element22 = -((0.5f * (mtx.mMatrix.mtxView[0][0] + mtx.mMatrix.mtxView[1][1])) - averageElement);
|
||||
|
||||
f32 avg_elem = 0.25f * (1.0f + (mtx.mMatrix.mtxView[2][2] + (mtx.mMatrix.mtxView[0][0] + mtx.mMatrix.mtxView[1][1])));
|
||||
f32 var_00 = -((0.5f * (mtx.mMatrix.mtxView[1][1] + mtx.mMatrix.mtxView[2][2])) - avg_elem);
|
||||
f32 var_11 = -((0.5f * (mtx.mMatrix.mtxView[2][2] + mtx.mMatrix.mtxView[0][0])) - avg_elem);
|
||||
f32 var_22 = -((0.5f * (mtx.mMatrix.mtxView[0][0] + mtx.mMatrix.mtxView[1][1])) - avg_elem);
|
||||
|
||||
if (avg_elem > var_00) {
|
||||
if (avg_elem > var_11) {
|
||||
if (avg_elem > var_22) {
|
||||
case_var = 0; // w norm
|
||||
if (averageElement > element00) {
|
||||
if (averageElement > element11) {
|
||||
if (averageElement > element22) {
|
||||
maxElementCase = 0; // w norm
|
||||
} else {
|
||||
case_var = 3; // z norm
|
||||
maxElementCase = 3; // z norm
|
||||
}
|
||||
} else if (var_11 > var_22) {
|
||||
case_var = 2; // y norm
|
||||
} else if (element11 > element22) {
|
||||
maxElementCase = 2; // y norm
|
||||
} else {
|
||||
case_var = 3; // z norm
|
||||
maxElementCase = 3; // z norm
|
||||
}
|
||||
} else if (var_00 > var_11) {
|
||||
if (var_00 > var_22) {
|
||||
case_var = 1; // x norm
|
||||
} else if (element00 > element11) {
|
||||
if (element00 > element22) {
|
||||
maxElementCase = 1; // x norm
|
||||
} else {
|
||||
case_var = 3; // z norm
|
||||
maxElementCase = 3; // z norm
|
||||
}
|
||||
} else if (var_11 > var_22) {
|
||||
case_var = 2; // y norm
|
||||
} else if (element11 > element22) {
|
||||
maxElementCase = 2; // y norm
|
||||
} else {
|
||||
case_var = 3; // z norm
|
||||
maxElementCase = 3; // z norm
|
||||
}
|
||||
|
||||
switch (case_var) {
|
||||
// Normalise quaternion based on the maximum element index
|
||||
switch (maxElementCase) {
|
||||
case 0: // w norm
|
||||
w = pikmin2_sqrtf(avg_elem);
|
||||
temp_norm = 0.25f / w;
|
||||
v.x = temp_norm * (mtx.mMatrix.mtxView[2][1] - mtx.mMatrix.mtxView[1][2]);
|
||||
v.y = temp_norm * (mtx.mMatrix.mtxView[0][2] - mtx.mMatrix.mtxView[2][0]);
|
||||
v.z = temp_norm * (mtx.mMatrix.mtxView[1][0] - mtx.mMatrix.mtxView[0][1]);
|
||||
break;
|
||||
case 1: // x norm
|
||||
v.x = pikmin2_sqrtf(var_00);
|
||||
temp_norm = 0.25f / v.x;
|
||||
w = temp_norm * (mtx.mMatrix.mtxView[2][1] - mtx.mMatrix.mtxView[1][2]);
|
||||
v.y = temp_norm * (mtx.mMatrix.mtxView[0][1] + mtx.mMatrix.mtxView[1][0]);
|
||||
v.z = temp_norm * (mtx.mMatrix.mtxView[0][2] + mtx.mMatrix.mtxView[2][0]);
|
||||
break;
|
||||
case 2: // y norm
|
||||
v.y = pikmin2_sqrtf(var_11);
|
||||
temp_norm = 0.25f / v.y;
|
||||
w = temp_norm * (mtx.mMatrix.mtxView[0][2] - mtx.mMatrix.mtxView[2][0]);
|
||||
v.z = temp_norm * (mtx.mMatrix.mtxView[1][2] + mtx.mMatrix.mtxView[2][1]);
|
||||
v.x = temp_norm * (mtx.mMatrix.mtxView[1][0] + mtx.mMatrix.mtxView[0][1]);
|
||||
break;
|
||||
case 3: // z norm
|
||||
v.z = pikmin2_sqrtf(var_22);
|
||||
temp_norm = 0.25f / v.z;
|
||||
w = temp_norm * (mtx.mMatrix.mtxView[1][0] - mtx.mMatrix.mtxView[0][1]);
|
||||
v.x = temp_norm * (mtx.mMatrix.mtxView[2][0] + mtx.mMatrix.mtxView[0][2]);
|
||||
v.y = temp_norm * (mtx.mMatrix.mtxView[2][1] + mtx.mMatrix.mtxView[1][2]);
|
||||
{
|
||||
w = pikmin2_sqrtf(averageElement);
|
||||
|
||||
f32 temp_norm = 0.25f / w;
|
||||
v.x = temp_norm * (mtx.mMatrix.mtxView[2][1] - mtx.mMatrix.mtxView[1][2]);
|
||||
v.y = temp_norm * (mtx.mMatrix.mtxView[0][2] - mtx.mMatrix.mtxView[2][0]);
|
||||
v.z = temp_norm * (mtx.mMatrix.mtxView[1][0] - mtx.mMatrix.mtxView[0][1]);
|
||||
break;
|
||||
}
|
||||
case 1: // x norm
|
||||
{
|
||||
v.x = pikmin2_sqrtf(element00);
|
||||
|
||||
f32 temp_norm = 0.25f / v.x;
|
||||
w = temp_norm * (mtx.mMatrix.mtxView[2][1] - mtx.mMatrix.mtxView[1][2]);
|
||||
v.y = temp_norm * (mtx.mMatrix.mtxView[0][1] + mtx.mMatrix.mtxView[1][0]);
|
||||
v.z = temp_norm * (mtx.mMatrix.mtxView[0][2] + mtx.mMatrix.mtxView[2][0]);
|
||||
break;
|
||||
}
|
||||
case 2: // y norm
|
||||
{
|
||||
v.y = pikmin2_sqrtf(element11);
|
||||
|
||||
f32 temp_norm = 0.25f / v.y;
|
||||
w = temp_norm * (mtx.mMatrix.mtxView[0][2] - mtx.mMatrix.mtxView[2][0]);
|
||||
v.z = temp_norm * (mtx.mMatrix.mtxView[1][2] + mtx.mMatrix.mtxView[2][1]);
|
||||
v.x = temp_norm * (mtx.mMatrix.mtxView[1][0] + mtx.mMatrix.mtxView[0][1]);
|
||||
break;
|
||||
}
|
||||
case 3: // z norm
|
||||
{
|
||||
v.z = pikmin2_sqrtf(element22);
|
||||
|
||||
f32 temp_norm = 0.25f / v.z;
|
||||
w = temp_norm * (mtx.mMatrix.mtxView[1][0] - mtx.mMatrix.mtxView[0][1]);
|
||||
v.x = temp_norm * (mtx.mMatrix.mtxView[2][0] + mtx.mMatrix.mtxView[0][2]);
|
||||
v.y = temp_norm * (mtx.mMatrix.mtxView[2][1] + mtx.mMatrix.mtxView[1][2]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (w < 0.0f) {
|
||||
w = -w;
|
||||
v.x = -v.x;
|
||||
v.y = -v.y;
|
||||
v.z = -v.z;
|
||||
}
|
||||
|
||||
f32 len_q = pikmin2_sqrtf(w * w + v.x * v.x + v.y * v.y + v.z * v.z);
|
||||
f32 norm = 1.0f / len_q;
|
||||
w *= norm;
|
||||
|
Loading…
Reference in New Issue
Block a user