Added in-game console for DynOS and Lua errors

This commit is contained in:
MysterD 2023-05-19 04:20:08 -07:00
parent 75861d365e
commit d043fdd22d
35 changed files with 322 additions and 97 deletions

View file

@ -8,6 +8,7 @@ extern "C" {
#include "engine/behavior_script.h"
#include "engine/math_util.h"
#include "src/game/moving_texture.h"
#include "src/pc/djui/djui_console.h"
}
#define FUNCTION_CODE (u32) 0x434E5546
@ -725,9 +726,23 @@ void Print(const char *aFmt, Args... aArgs) {
fflush(stdout);
}
#define PrintError(...) { \
template <typename... Args>
void PrintConsole(const char *aFmt, Args... aArgs) {
snprintf(gDjuiConsoleTmpBuffer, CONSOLE_MAX_TMP_BUFFER, aFmt, aArgs...);
djui_console_message_create(gDjuiConsoleTmpBuffer);
}
template <typename... Args>
void PrintError(const char *aFmt, Args... aArgs) {
printf(aFmt, aArgs...);
printf("\r\n");
fflush(stdout);
PrintConsole(aFmt, aArgs...);
}
#define PrintDataError(...) { \
if (aGfxData->mErrorCount == 0) Print(" ERROR!"); \
Print(__VA_ARGS__); \
PrintConsole(__VA_ARGS__); \
aGfxData->mErrorCount++; \
}

View file

@ -16,7 +16,7 @@ void ClearGfxDataNodes(DataNodes<T> &aDataNodes) {
static bool DynOS_Actor_WriteBinary(const SysPath &aOutputFilename, GfxData *aGfxData) {
BinFile *_File = BinFile::OpenW(aOutputFilename.c_str());
if (!_File) {
PrintError(" ERROR: Unable to create file \"%s\"", aOutputFilename.c_str());
PrintDataError(" ERROR: Unable to create file \"%s\"", aOutputFilename.c_str());
return false;
}
@ -182,6 +182,7 @@ static void DynOS_Actor_Generate(const SysPath &aPackFolder, Array<Pair<u64, Str
// Parse data
PrintNoNewLine("%s.bin: Model identifier: %X - Processing... ", _GeoRootName.begin(), _GfxData->mModelIdentifier);
PrintConsole("%s.bin: Model identifier: %X - Processing... ", _GeoRootName.begin(), _GfxData->mModelIdentifier);
DynOS_Geo_Parse(_GfxData, _GeoNode, true);
// Init animation data
@ -215,7 +216,7 @@ static void DynOS_Actor_Generate(const SysPath &aPackFolder, Array<Pair<u64, Str
if (_GfxData->mErrorCount == 0) {
DynOS_Actor_WriteBinary(_BinFilename, _GfxData);
} else {
Print(" %u error(s): Unable to parse data", _GfxData->mErrorCount);
PrintError(" %u error(s): Unable to parse data", _GfxData->mErrorCount);
}
// Clear data pointers
ClearGfxDataNodes(_GfxData->mLights);

View file

@ -9,7 +9,7 @@ DataNode<Ambient_t>* DynOS_AmbientT_Parse(GfxData* aGfxData, DataNode<Ambient_t>
// Check tokens count
if (aNode->mTokens.Count() < 8) {
PrintError(" ERROR: %s: not enough data", aNode->mName.begin());
PrintDataError(" ERROR: %s: not enough data", aNode->mName.begin());
return aNode;
}

View file

@ -7,7 +7,7 @@
static void ScanAnimationDataFile(GfxData *aGfxData, const SysPath &aFilename) {
FILE *_File = fopen(aFilename.c_str(), "rb");
if (!_File) {
PrintError(" ERROR: Unable to open file \"%s\"", aFilename.c_str());
PrintDataError(" ERROR: Unable to open file \"%s\"", aFilename.c_str());
}
// Load file into a buffer while removing all comments
@ -70,7 +70,7 @@ static void ScanAnimationDataFile(GfxData *aGfxData, const SysPath &aFilename) {
case DATA_TYPE_ANIMATION: {
if (_Data.Count() < 10) {
PrintError(" ERROR: %s: Not enough data", _DataName.begin());
PrintDataError(" ERROR: %s: Not enough data", _DataName.begin());
break;
}
@ -104,7 +104,7 @@ static void ScanAnimationDataFile(GfxData *aGfxData, const SysPath &aFilename) {
static void ScanAnimationTableFile(GfxData *aGfxData, const SysPath &aFilename) {
FILE *_File = fopen(aFilename.c_str(), "rb");
if (!_File) {
PrintError(" ERROR: Unable to open file \"%s\"", aFilename.c_str());
PrintDataError(" ERROR: Unable to open file \"%s\"", aFilename.c_str());
}
// Load file into a buffer while removing all comments

View file

@ -1973,7 +1973,7 @@ static BehaviorScript ParseBehaviorScriptSymbolArg(GfxData *aGfxData, DataNode<B
BehaviorScript value = ParseBehaviorScriptSymbolArgInternal(aGfxData, aNode, aTokenIndex, &found);
if (!found) {
const String &_Arg = aNode->mTokens[aTokenIndex - 1];
PrintError(" ERROR: Unknown bhv arg: %s", _Arg.begin());
PrintDataError(" ERROR: Unknown bhv arg: %s", _Arg.begin());
}
return value;
}
@ -2262,7 +2262,7 @@ static void ParseBehaviorScriptSymbol(GfxData *aGfxData, DataNode<BehaviorScript
//BehaviorScript _Bs[] = { LOAD_ANIMATIONS_EXT(field, animIndex) };
//memcpy(aHead, _Bs, sizeof(_Bs));
//aHead += (sizeof(_Bs) / sizeof(_Bs[0]));
PrintError(" ERROR: : Custom external animations are currently not supported. Skipping LOAD_ANIMATIONS_EXT.");
PrintDataError(" ERROR: : Custom external animations are currently not supported. Skipping LOAD_ANIMATIONS_EXT.");
}
return;
}
@ -2403,7 +2403,7 @@ static void ParseBehaviorScriptSymbol(GfxData *aGfxData, DataNode<BehaviorScript
}
// Unknown
PrintError(" ERROR: Unknown behavior symbol: %s", _Symbol.begin());
PrintDataError(" ERROR: Unknown behavior symbol: %s", _Symbol.begin());
}
DataNode<BehaviorScript> *DynOS_Bhv_Parse(GfxData *aGfxData, DataNode<BehaviorScript> *aNode, bool aDisplayPercent) {
@ -2466,7 +2466,7 @@ static void DynOS_Bhv_Write(BinFile* aFile, GfxData* aGfxData, DataNode<Behavior
static bool DynOS_Bhv_WriteBinary(const SysPath &aOutputFilename, GfxData *aGfxData) {
BinFile *_File = BinFile::OpenW(aOutputFilename.c_str());
if (!_File) {
PrintError(" ERROR: Unable to create file \"%s\"", aOutputFilename.c_str());
PrintDataError(" ERROR: Unable to create file \"%s\"", aOutputFilename.c_str());
return false;
}
@ -2490,7 +2490,7 @@ static DataNode<BehaviorScript> *DynOS_Bhv_Load(BinFile *aFile, GfxData *aGfxDat
// Sanity check the files size. The minimum valid size is 9 bytes.
// 1 byte for the type, 1 bytes for the name length, 3 bytes for the version, And 4 bytes for the behaviors size.
if (aFile->Size() < 9) {
PrintError(" ERROR: Behavior file is smaller then it should be, Rejecting '%s'.", aFile->GetFilename());
PrintDataError(" ERROR: Behavior file is smaller then it should be, Rejecting '%s'.", aFile->GetFilename());
// We have nothing to return, So return NULL.
return NULL;
}
@ -2512,7 +2512,7 @@ static DataNode<BehaviorScript> *DynOS_Bhv_Load(BinFile *aFile, GfxData *aGfxDat
// we can't read it no matter what. If it's just minor or patch. We might have
// code to support it.
if (majorVersion != BEHAVIOR_MIN_MAJOR_VER || (minorVersion < BEHAVIOR_MIN_MINOR_VER || patchVersion < BEHAVIOR_MIN_PATCH_VER)) {
PrintError(" ERROR: Behavior file is version %u.%u.%u, which is not supported! Rejecting '%s'.", majorVersion, minorVersion, patchVersion, aFile->GetFilename());
PrintDataError(" ERROR: Behavior file is version %u.%u.%u, which is not supported! Rejecting '%s'.", majorVersion, minorVersion, patchVersion, aFile->GetFilename());
// We don't return this since we failed to read the behavior.
Delete(_Node);
// We have nothing to return, So return NULL.
@ -2523,7 +2523,7 @@ static DataNode<BehaviorScript> *DynOS_Bhv_Load(BinFile *aFile, GfxData *aGfxDat
// We also check if the specified behavior size is valid for the file.
u32 dataSize = aFile->Read<u32>();
if (dataSize == 0 || (dataSize > (aFile->Size() - aFile->Offset()))) {
PrintError(" ERROR: Behavior file has a invalid behavior in it! Rejecting '%s'.", aFile->GetFilename());
PrintDataError(" ERROR: Behavior file has a invalid behavior in it! Rejecting '%s'.", aFile->GetFilename());
// We don't return this since we failed to read the behavior.
Delete(_Node);
// We have nothing to return, So return NULL.
@ -2537,7 +2537,7 @@ static DataNode<BehaviorScript> *DynOS_Bhv_Load(BinFile *aFile, GfxData *aGfxDat
// Read it
for (u32 i = 0; i != _Node->mSize; ++i) {
if (aFile->EoF()) {
PrintError(" ERROR: Reached EOF when reading file! Expected %llx bytes!", _Node->mSize * sizeof(u32));
PrintDataError(" ERROR: Reached EOF when reading file! Expected %llx bytes!", _Node->mSize * sizeof(u32));
break;
}
u32 _Value = aFile->Read<u32>();
@ -2626,13 +2626,14 @@ static void DynOS_Bhv_Generate(const SysPath &aPackFolder, Array<Pair<u64, Strin
// Parse data
PrintNoNewLine("%s.bhv: Model identifier: %X - Processing... ", _BhvRootName.begin(), _GfxData->mModelIdentifier);
PrintConsole("%s.bhv: Model identifier: %X - Processing... ", _BhvRootName.begin(), _GfxData->mModelIdentifier);
DynOS_Bhv_Parse(_GfxData, _BhvNode, true);
// Write if no error
if (_GfxData->mErrorCount == 0) {
DynOS_Bhv_WriteBinary(_BinFilename, _GfxData);
} else {
Print(" %u error(s): Unable to parse data", _GfxData->mErrorCount);
PrintError(" %u error(s): Unable to parse data", _GfxData->mErrorCount);
}
// Clear data pointers

View file

@ -42,21 +42,21 @@ struct CollisionValidationData {
static void ValidateColSectionChange(GfxData* aGfxData, struct CollisionValidationData& aColValData, u8 section) {
if (aColValData.section == COL_SECTION_END) {
PrintError("Found new col section after COL_END");
PrintDataError("Found new col section after COL_END");
}
if (aColValData.section != section) {
if (aColValData.vtxAlloc != aColValData.vtxCount) {
PrintError("Improper vtx count found in section. Allocated: %u, Defined: %u", aColValData.vtxAlloc, aColValData.vtxCount);
PrintDataError("Improper vtx count found in section. Allocated: %u, Defined: %u", aColValData.vtxAlloc, aColValData.vtxCount);
}
if (aColValData.triAlloc != aColValData.triCount) {
PrintError("Improper triangle count found in section. Allocated: %u, Defined: %u", aColValData.triAlloc, aColValData.triCount);
PrintDataError("Improper triangle count found in section. Allocated: %u, Defined: %u", aColValData.triAlloc, aColValData.triCount);
}
if (aColValData.specialAlloc != aColValData.specialCount) {
PrintError("Improper sepcial count found in section. Allocated: %u, Defined: %u", aColValData.triAlloc, aColValData.triCount);
PrintDataError("Improper sepcial count found in section. Allocated: %u, Defined: %u", aColValData.triAlloc, aColValData.triCount);
}
if (aColValData.waterBoxAlloc != aColValData.waterBoxCount) {
PrintError("Improper water box count found in section. Allocated: %u, Defined: %u", aColValData.waterBoxAlloc, aColValData.waterBoxCount);
PrintDataError("Improper water box count found in section. Allocated: %u, Defined: %u", aColValData.waterBoxAlloc, aColValData.waterBoxCount);
}
}
@ -65,17 +65,17 @@ static void ValidateColSectionChange(GfxData* aGfxData, struct CollisionValidati
static void ValidateColInit(GfxData* aGfxData, struct CollisionValidationData& aColValData) {
if (aColValData.tokenIndex != 0) {
PrintError("COL_INIT found after the first token");
PrintDataError("COL_INIT found after the first token");
}
ValidateColSectionChange(aGfxData, aColValData, COL_SECTION_VTX);
}
static void ValidateColVertexInit(GfxData* aGfxData, struct CollisionValidationData& aColValData, s16 arg0) {
if (strcmp(aColValData.lastSymbol, "COL_INIT") != 0) {
PrintError("COL_VERTEX_INIT found outside of vertex section");
PrintDataError("COL_VERTEX_INIT found outside of vertex section");
}
if (arg0 < 0) {
PrintError("COL_VERTEX_INIT with a negative count: %d", arg0);
PrintDataError("COL_VERTEX_INIT with a negative count: %d", arg0);
}
aColValData.vtxAlloc = arg0;
aColValData.vtxCount = 0;
@ -83,14 +83,14 @@ static void ValidateColVertexInit(GfxData* aGfxData, struct CollisionValidationD
static void ValidateColVertex(GfxData* aGfxData, struct CollisionValidationData& aColValData, s16 arg0, s16 arg1, s16 arg2) {
if (aColValData.section != COL_SECTION_VTX) {
PrintError("COL_VERTEX found outside of vertex section");
PrintDataError("COL_VERTEX found outside of vertex section");
}
aColValData.vtxCount++;
}
static void ValidateColTriInit(GfxData* aGfxData, struct CollisionValidationData& aColValData, s16 arg0, s16 arg1) {
if (arg1 < 0) {
PrintError("COL_TRI_INIT with a negative count: %d", arg1);
PrintDataError("COL_TRI_INIT with a negative count: %d", arg1);
}
ValidateColSectionChange(aGfxData, aColValData, COL_SECTION_TRI);
aColValData.triAlloc = arg1;
@ -99,16 +99,16 @@ static void ValidateColTriInit(GfxData* aGfxData, struct CollisionValidationData
static void ValidateColTri(GfxData* aGfxData, struct CollisionValidationData& aColValData, s16 arg0, s16 arg1, s16 arg2) {
if (aColValData.section != COL_SECTION_TRI) {
PrintError("COL_TRI found outside of triangle section");
PrintDataError("COL_TRI found outside of triangle section");
}
if (arg0 < 0 || arg0 > aColValData.vtxCount) {
PrintError("COL_TRI used vertex outside of known range for first param: %d", arg0);
PrintDataError("COL_TRI used vertex outside of known range for first param: %d", arg0);
}
if (arg1 < 0 || arg1 > aColValData.vtxCount) {
PrintError("COL_TRI used vertex outside of known range for second param: %d", arg1);
PrintDataError("COL_TRI used vertex outside of known range for second param: %d", arg1);
}
if (arg2 < 0 || arg2 > aColValData.vtxCount) {
PrintError("COL_TRI used vertex outside of known range for third param: %d", arg2);
PrintDataError("COL_TRI used vertex outside of known range for third param: %d", arg2);
}
aColValData.triCount++;
}
@ -127,7 +127,7 @@ static void ValidateColEnd(GfxData* aGfxData, struct CollisionValidationData& aC
static void ValidateColSpecialInit(GfxData* aGfxData, struct CollisionValidationData& aColValData, s16 arg0) {
if (arg0 < 0) {
PrintError("COL_SPECIAL_INIT with a negative count: %d", arg0);
PrintDataError("COL_SPECIAL_INIT with a negative count: %d", arg0);
}
ValidateColSectionChange(aGfxData, aColValData, COL_SECTION_SPECIAL);
aColValData.specialAlloc = arg0;
@ -136,7 +136,7 @@ static void ValidateColSpecialInit(GfxData* aGfxData, struct CollisionValidation
static void ValidateColWaterBoxInit(GfxData* aGfxData, struct CollisionValidationData& aColValData, s16 arg0) {
if (arg0 < 0) {
PrintError("COL_WATER_BOX_INIT with a negative count: %d", arg0);
PrintDataError("COL_WATER_BOX_INIT with a negative count: %d", arg0);
}
ValidateColSectionChange(aGfxData, aColValData, COL_SECTION_WATER_BOX);
aColValData.waterBoxAlloc = arg0;
@ -145,28 +145,28 @@ static void ValidateColWaterBoxInit(GfxData* aGfxData, struct CollisionValidatio
static void ValidateColWaterBox(GfxData* aGfxData, struct CollisionValidationData& aColValData, s16 arg0, s16 arg1, s16 arg2, s16 arg3, s16 arg4, s16 arg5) {
if (aColValData.section != COL_SECTION_WATER_BOX) {
PrintError("COL_WATER_BOX found outside of water box section");
PrintDataError("COL_WATER_BOX found outside of water box section");
}
aColValData.waterBoxCount++;
}
static void ValidateColSpecialObject(GfxData* aGfxData, struct CollisionValidationData& aColValData, s16 arg0, s16 arg1, s16 arg2, s16 arg3) {
if (aColValData.section != COL_SECTION_SPECIAL) {
PrintError("SPECIAL_OBJECT found outside of special section");
PrintDataError("SPECIAL_OBJECT found outside of special section");
}
aColValData.specialCount++;
}
static void ValidateColSpecialObjectWithYaw(GfxData* aGfxData, struct CollisionValidationData& aColValData, s16 arg0, s16 arg1, s16 arg2, s16 arg3, s16 arg4) {
if (aColValData.section != COL_SECTION_SPECIAL) {
PrintError("SPECIAL_OBJECT_WITH_YAW found outside of special section");
PrintDataError("SPECIAL_OBJECT_WITH_YAW found outside of special section");
}
aColValData.specialCount++;
}
static void ValidateColSpecialObjectWithYawAndParam(GfxData* aGfxData, struct CollisionValidationData& aColValData, s16 arg0, s16 arg1, s16 arg2, s16 arg3, s16 arg4, s16 arg5) {
if (aColValData.section != COL_SECTION_SPECIAL) {
PrintError("SPECIAL_OBJECT_WITH_YAW_AND_PARAM found outside of special section");
PrintDataError("SPECIAL_OBJECT_WITH_YAW_AND_PARAM found outside of special section");
}
aColValData.specialCount++;
}
@ -458,7 +458,7 @@ static s16 ParseColSymbolArg(GfxData* aGfxData, DataNode<Collision>* aNode, u64&
}
// Unknown
PrintError(" ERROR: Unknown col arg: %s", _Arg.begin());
PrintDataError(" ERROR: Unknown col arg: %s", _Arg.begin());
return 0;
}
@ -575,7 +575,7 @@ static void ParseCollisionSymbol(GfxData* aGfxData, DataNode<Collision>* aNode,
col_symbol_6(SPECIAL_OBJECT_WITH_YAW_AND_PARAM, ValidateColSpecialObjectWithYawAndParam);
// Unknown
PrintError(" ERROR: Unknown col symbol: %s", _Symbol.begin());
PrintDataError(" ERROR: Unknown col symbol: %s", _Symbol.begin());
}
DataNode<Collision>* DynOS_Col_Parse(GfxData* aGfxData, DataNode<Collision>* aNode, bool aDisplayPercent) {
@ -595,7 +595,7 @@ DataNode<Collision>* DynOS_Col_Parse(GfxData* aGfxData, DataNode<Collision>* aNo
}
if (colValData.section != COL_SECTION_END) {
PrintError("Collision did not end with COL_END");
PrintDataError("Collision did not end with COL_END");
}
if (aDisplayPercent && aGfxData->mErrorCount == 0) { Print("100%%"); }
@ -603,7 +603,7 @@ DataNode<Collision>* DynOS_Col_Parse(GfxData* aGfxData, DataNode<Collision>* aNo
aNode->mLoadIndex = aGfxData->mLoadIndex++;
if (aGfxData->mErrorCount > 0) {
Print("Failed to parse collision: '%s'", aNode->mName.begin());
PrintDataError("Failed to parse collision: '%s'", aNode->mName.begin());
}
return aNode;
@ -630,7 +630,7 @@ void DynOS_Col_Write(BinFile* aFile, GfxData* aGfxData, DataNode<Collision> *aNo
static bool DynOS_Col_WriteBinary(const SysPath &aOutputFilename, GfxData *aGfxData, DataNode<Collision>* _Node) {
BinFile *_File = BinFile::OpenW(aOutputFilename.c_str());
if (!_File) {
PrintError(" ERROR: Unable to create file \"%s\"", aOutputFilename.c_str());
PrintDataError(" ERROR: Unable to create file \"%s\"", aOutputFilename.c_str());
return false;
}
@ -706,13 +706,14 @@ void DynOS_Col_Generate(const SysPath &aPackFolder, Array<Pair<u64, String>> _Ac
// Parse data
PrintNoNewLine("%s.col: Model identifier: %X - Processing... ", _ColRootName.begin(), _GfxData->mModelIdentifier);
PrintConsole("%s.col: Model identifier: %X - Processing... ", _ColRootName.begin(), _GfxData->mModelIdentifier);
DynOS_Col_Parse(_GfxData, _ColNode, true);
// Write if no error
if (_GfxData->mErrorCount == 0) {
DynOS_Col_WriteBinary(_ColFilename, _GfxData, _ColNode);
} else {
Print(" %u error(s): Unable to parse data", _GfxData->mErrorCount);
PrintError(" %u error(s): Unable to parse data", _GfxData->mErrorCount);
}
// Clear data pointers

View file

@ -29,7 +29,7 @@ static inline void DynOS_Bin_Compress_Free() {
static inline bool DynOS_Bin_Compress_Check(bool condition, const char *function, const char *filename, const char *message) {
if (!condition) {
Print("ERROR: %s: File \"%s\": %s", function, filename, message);
PrintError("ERROR: %s: File \"%s\": %s", function, filename, message);
DynOS_Bin_Compress_Free();
return false;
}
@ -223,7 +223,7 @@ BinFile *DynOS_Bin_Decompress(const SysPath &aFilename) {
uncompressRc == Z_OK,
__FUNCTION__, aFilename.c_str(), "Cannot uncompress data"
)) {
Print("ERROR: uncompress rc: %d, length uncompressed: %lu, length compressed: %lu, length header: %lu", uncompressRc, sLengthUncompressed, sLengthCompressed, _LengthHeader);
PrintError("ERROR: uncompress rc: %d, length uncompressed: %lu, length compressed: %lu, length header: %lu", uncompressRc, sLengthUncompressed, sLengthCompressed, _LengthHeader);
return NULL;
}
Print("uncompress rc: %d, length uncompressed: %lu, length compressed: %lu, length header: %lu", uncompressRc, sLengthUncompressed, sLengthCompressed, _LengthHeader);

View file

@ -148,7 +148,7 @@ static s64 ParseGeoSymbolArg(GfxData* aGfxData, DataNode<GeoLayout>* aNode, u64&
}
// Unknown
PrintError(" ERROR: Unknown geo arg: %s", _Arg.begin());
PrintDataError(" ERROR: Unknown geo arg: %s", _Arg.begin());
return 0;
}
@ -405,7 +405,7 @@ static void ParseGeoSymbol(GfxData* aGfxData, DataNode<GeoLayout>* aNode, GeoLay
}
// Unknown
PrintError(" ERROR: Unknown geo symbol: %s", _Symbol.begin());
PrintDataError(" ERROR: Unknown geo symbol: %s", _Symbol.begin());
}
DataNode<GeoLayout>* DynOS_Geo_Parse(GfxData* aGfxData, DataNode<GeoLayout>* aNode, bool aDisplayPercent) {

View file

@ -480,7 +480,7 @@ static s64 ParseGfxSymbolArg(GfxData* aGfxData, DataNode<Gfx>* aNode, u64* pToke
}
// Unknown
PrintError(" ERROR: Unknown gfx arg: %s", _Arg.begin());
PrintDataError(" ERROR: Unknown gfx arg: %s", _Arg.begin());
return 0;
}
@ -673,7 +673,7 @@ static String ConvertSetCombineModeArgToString(GfxData *aGfxData, const String&
gfx_set_combine_mode_arg(G_CC_HILITERGBA2);
gfx_set_combine_mode_arg(G_CC_HILITERGBDECALA2);
gfx_set_combine_mode_arg(G_CC_HILITERGBPASSA2);
PrintError(" ERROR: Unknown gfx gsDPSetCombineMode arg: %s", _Arg.begin());
PrintDataError(" ERROR: Unknown gfx gsDPSetCombineMode arg: %s", _Arg.begin());
return "";
}
@ -693,7 +693,7 @@ static Array<s64> ParseGfxSetCombineMode(GfxData* aGfxData, DataNode<Gfx>* aNode
}
}
if (_Args.Count() < 8) {
PrintError(" ERROR: gsDPSetCombineMode %s: Not enough arguments", _Buffer.begin());
PrintDataError(" ERROR: gsDPSetCombineMode %s: Not enough arguments", _Buffer.begin());
}
return _Args;
}
@ -935,7 +935,7 @@ static void ParseGfxSymbol(GfxData* aGfxData, DataNode<Gfx>* aNode, Gfx*& aHead,
}
// Unknown
PrintError(" ERROR: Unknown gfx symbol: %s", _Symbol.begin());
PrintDataError(" ERROR: Unknown gfx symbol: %s", _Symbol.begin());
}
DataNode<Gfx>* DynOS_Gfx_Parse(GfxData* aGfxData, DataNode<Gfx>* aNode) {

View file

@ -9,7 +9,7 @@ DataNode<Light_t>* DynOS_LightT_Parse(GfxData* aGfxData, DataNode<Light_t>* aNod
// Check tokens count
if (aNode->mTokens.Count() < 12) {
PrintError(" ERROR: %s: not enough data", aNode->mName.begin());
PrintDataError(" ERROR: %s: not enough data", aNode->mName.begin());
return aNode;
}

View file

@ -9,13 +9,13 @@ DataNode<Lights1>* DynOS_Lights_Parse(GfxData* aGfxData, DataNode<Lights1>* aNod
// Check tokens count
if (aNode->mTokens.Count() < 10) {
PrintError(" ERROR: %s: not enough data", aNode->mName.begin());
PrintDataError(" ERROR: %s: not enough data", aNode->mName.begin());
return aNode;
}
// Parse def token
if (aNode->mTokens[0] != "gdSPDefLights1") {
PrintError(" ERROR: Invalid def token: should be gdSPDefLights1, is %s", aNode->mTokens[0].begin());
PrintDataError(" ERROR: Invalid def token: should be gdSPDefLights1, is %s", aNode->mTokens[0].begin());
return aNode;
}

View file

@ -523,7 +523,7 @@ static LevelScript ParseLevelScriptSymbolArg(GfxData* aGfxData, DataNode<LevelSc
LevelScript value = ParseLevelScriptSymbolArgInternal(aGfxData, aNode, aTokenIndex, &found);
if (!found) {
const String& _Arg = aNode->mTokens[aTokenIndex - 1];
PrintError(" ERROR: Unknown lvl arg: %s", _Arg.begin());
PrintDataError(" ERROR: Unknown lvl arg: %s", _Arg.begin());
}
return value;
}
@ -827,7 +827,7 @@ static void ParseLevelScriptSymbol(GfxData* aGfxData, DataNode<LevelScript>* aNo
}
// Unknown
PrintError(" ERROR: Unknown lvl symbol: %s", _Symbol.begin());
PrintDataError(" ERROR: Unknown lvl symbol: %s", _Symbol.begin());
}
DataNode<LevelScript>* DynOS_Lvl_Parse(GfxData* aGfxData, DataNode<LevelScript>* aNode, bool aDisplayPercent) {
@ -884,7 +884,7 @@ static void DynOS_Lvl_Write(BinFile* aFile, GfxData* aGfxData, DataNode<LevelScr
static bool DynOS_Lvl_WriteBinary(const SysPath &aOutputFilename, GfxData *aGfxData) {
BinFile *_File = BinFile::OpenW(aOutputFilename.c_str());
if (!_File) {
PrintError(" ERROR: Unable to create file \"%s\"", aOutputFilename.c_str());
PrintDataError(" ERROR: Unable to create file \"%s\"", aOutputFilename.c_str());
return false;
}
@ -1078,6 +1078,7 @@ static bool DynOS_Lvl_GeneratePack_Internal(const SysPath &aPackFolder, Array<Pa
// Parse data
PrintNoNewLine("%s.lvl: Model identifier: %X - Processing... ", _LvlRootName.begin(), _GfxData->mModelIdentifier);
PrintConsole("%s.lvl: Model identifier: %X - Processing... ", _LvlRootName.begin(), _GfxData->mModelIdentifier);
DynOS_Lvl_Parse(_GfxData, _LvlRoot, true);
// Force all of the movtexs, collisions, and trajectories into the compiled lvl
@ -1102,7 +1103,7 @@ static bool DynOS_Lvl_GeneratePack_Internal(const SysPath &aPackFolder, Array<Pa
if (_GfxData->mErrorCount == 0) {
DynOS_Lvl_WriteBinary(_LvlFilename, _GfxData);
} else {
Print(" %u error(s): Unable to parse data", _GfxData->mErrorCount);
PrintError(" %u error(s): Unable to parse data", _GfxData->mErrorCount);
}
// Clear data pointers

View file

@ -404,7 +404,7 @@ static s64 ParseMacroObjectSymbolArg(GfxData* aGfxData, DataNode<MacroObject>* a
}
// Unknown
PrintError(" ERROR: Unknown macro object arg: %s", _Arg.begin());
PrintDataError(" ERROR: Unknown macro object arg: %s", _Arg.begin());
return 0;
}
@ -451,7 +451,7 @@ static void ParseMacroObjectSymbol(GfxData* aGfxData, DataNode<MacroObject>* aNo
macro_object_symbol_0(MACRO_OBJECT_END);
// Unknown
PrintError(" ERROR: Unknown macro object symbol: %s", _Symbol.begin());
PrintDataError(" ERROR: Unknown macro object symbol: %s", _Symbol.begin());
}
DataNode<MacroObject>* DynOS_MacroObject_Parse(GfxData* aGfxData, DataNode<MacroObject>* aNode, bool aDisplayPercent) {

View file

@ -40,7 +40,7 @@ static s64 ParseMovtexSymbolArg(GfxData* aGfxData, DataNode<Movtex>* aNode, u64&
movtex_constant(NULL);
// Unknown
PrintError(" ERROR: Unknown movtex arg: %s", _Arg.begin());
PrintDataError(" ERROR: Unknown movtex arg: %s", _Arg.begin());
return 0;
}
@ -143,7 +143,7 @@ static void ParseMovtexSymbol(GfxData* aGfxData, DataNode<Movtex>* aNode, Movtex
}
// Unknown
PrintError(" ERROR: Unknown movtex symbol: %s", _Symbol.begin());
PrintDataError(" ERROR: Unknown movtex symbol: %s", _Symbol.begin());
}
DataNode<Movtex>* DynOS_Movtex_Parse(GfxData* aGfxData, DataNode<Movtex>* aNode, bool aDisplayPercent) {

View file

@ -27,7 +27,7 @@ static Movtex* ParseMovtexQCSymbolArg(GfxData* aGfxData, DataNode<MovtexQC>* aNo
}
// Unknown
PrintError(" ERROR: Unknown movtexqc arg: %s", _Arg.begin());
PrintDataError(" ERROR: Unknown movtexqc arg: %s", _Arg.begin());
return NULL;
}

View file

@ -183,7 +183,7 @@ static PointerData GetDataFromPointer(const void* aPtr, GfxData* aGfxData) {
}
}
PrintError("Unable to find pointer %x!", aPtr);
PrintDataError("Unable to find pointer %x!", aPtr);
return { "", 0 };
}

View file

@ -217,7 +217,7 @@ void DynOS_Read_Source(GfxData *aGfxData, const SysPath &aFilename) {
} else if (_Buffer == "BehaviorScript") {
_DataType = DATA_TYPE_BEHAVIOR_SCRIPT;
} else {
PrintError(" ERROR: Unknown type name: %s", _Buffer.begin());
PrintDataError(" ERROR: Unknown type name: %s", _Buffer.begin());
}
_Buffer.Clear();
}
@ -266,7 +266,7 @@ void DynOS_Read_Source(GfxData *aGfxData, const SysPath &aFilename) {
if (*c == '=') {
pDataStart = c + 1;
} else if (*c == ';') {
PrintError(" ERROR: %s: Unexpected end of data", pDataName->begin());
PrintDataError(" ERROR: %s: Unexpected end of data", pDataName->begin());
}
}

View file

@ -52,7 +52,7 @@ static TexData* LoadTextureFromFile(GfxData *aGfxData, const char* aFile) {
// The file does not exist in either spot!
if (!_File) {
PrintError(" ERROR: Unable to open file at \"%s\" or \"%s\"", _Filename.c_str(), _ActorFilename.c_str());
PrintDataError(" ERROR: Unable to open file at \"%s\" or \"%s\"", _Filename.c_str(), _ActorFilename.c_str());
return NULL;
}
}
@ -72,7 +72,7 @@ void DynOS_Tex_ConvertTextureDataToPng(GfxData *aGfxData, TexData* aTexture) {
const u8 *_Palette = (aGfxData->mGfxContext.mCurrentPalette ? aGfxData->mGfxContext.mCurrentPalette->mData->mRawData.begin() : NULL);
u8 *_Buffer = DynOS_Tex_ConvertToRGBA32(aTexture->mRawData.begin(), aTexture->mRawData.Count(), aTexture->mRawFormat, aTexture->mRawSize, _Palette);
if (_Buffer == NULL) {
PrintError(" ERROR: Unknown texture format");
PrintDataError(" ERROR: Unknown texture format");
return;
}
@ -80,7 +80,7 @@ void DynOS_Tex_ConvertTextureDataToPng(GfxData *aGfxData, TexData* aTexture) {
s32 _PngLength = 0;
u8 *_PngData = stbi_write_png_to_mem(_Buffer, 0, aTexture->mRawWidth, aTexture->mRawHeight, 4, &_PngLength);
if (!_PngData || !_PngLength) {
PrintError(" ERROR: Cannot convert texture to PNG");
PrintDataError(" ERROR: Cannot convert texture to PNG");
return;
}
@ -97,7 +97,7 @@ DataNode<TexData>* DynOS_Tex_Parse(GfxData* aGfxData, DataNode<TexData>* aNode)
// Check tokens Count
if (aNode->mTokens.Count() < 1) {
PrintError(" ERROR: %s: not enough data", aNode->mName.begin());
PrintDataError(" ERROR: %s: not enough data", aNode->mName.begin());
return aNode;
}
@ -106,7 +106,7 @@ DataNode<TexData>* DynOS_Tex_Parse(GfxData* aGfxData, DataNode<TexData>* aNode)
if (i0 != -1) {
s32 i1 = aNode->mTokens[0].Find(".inc.c");
if (i1 == -1) {
PrintError(" ERROR: %s: missing .inc.c in String %s", aNode->mName.begin(), aNode->mTokens[0].begin());
PrintDataError(" ERROR: %s: missing .inc.c in String %s", aNode->mName.begin(), aNode->mTokens[0].begin());
return aNode;
}
@ -122,7 +122,7 @@ DataNode<TexData>* DynOS_Tex_Parse(GfxData* aGfxData, DataNode<TexData>* aNode)
if (dq0 != -1) {
s32 dq1 = aNode->mTokens[0].Find('\"', dq0 + 1);
if (dq1 == -1) {
PrintError(" ERROR: %s: missing second quote in String %s", aNode->mName.begin(), aNode->mTokens[0].begin());
PrintDataError(" ERROR: %s: missing second quote in String %s", aNode->mName.begin(), aNode->mTokens[0].begin());
return aNode;
}
@ -181,7 +181,7 @@ void DynOS_Tex_Write(BinFile* aFile, GfxData* aGfxData, DataNode<TexData> *aNode
static bool DynOS_Tex_WriteBinary(GfxData* aGfxData, const SysPath &aOutputFilename, String& aName, TexData* aTexData, bool aRawTexture) {
BinFile *_File = BinFile::OpenW(aOutputFilename.c_str());
if (!_File) {
PrintError(" ERROR: Unable to create file \"%s\"", aOutputFilename.c_str());
PrintDataError(" ERROR: Unable to create file \"%s\"", aOutputFilename.c_str());
return false;
}
@ -411,7 +411,7 @@ static void DynOS_Tex_GeneratePack_Recursive(const SysPath &aPackFolder, SysPath
aGfxData->mModelIdentifier++;
TexData* _TexData = LoadTextureFromFile(aGfxData, _Path.c_str());
if (_TexData == NULL) {
PrintError("Error reading texture from file: %s", _Path.c_str());
PrintDataError("Error reading texture from file: %s", _Path.c_str());
continue;
}

View file

@ -13,7 +13,7 @@ static TexData* ParseTexListSymbol(GfxData* aGfxData, DataNode<TexData*>* aNode,
}
// Unknown
PrintError(" ERROR: Unknown texlist arg: %s", aToken.begin());
PrintDataError(" ERROR: Unknown texlist arg: %s", aToken.begin());
return NULL;
}
@ -56,7 +56,7 @@ void DynOS_TexList_Write(BinFile* aFile, GfxData* aGfxData, DataNode<TexData*> *
}
}
if (!found) {
PrintError("Could not write texture in texlist");
PrintDataError("Could not write texture in texlist");
}
}
}
@ -78,7 +78,7 @@ DataNode<TexData*>* DynOS_TexList_Load(BinFile *aFile, GfxData *aGfxData) {
u32 _Value = aFile->Read<u32>();
void *_Ptr = DynOS_Pointer_Load(aFile, aGfxData, _Value, &_Node->mFlags);
if (_Ptr == NULL) {
PrintError("Could not read texture in texlist");
PrintDataError("Could not read texture in texlist");
} else {
_Node->mData[i] = ((DataNode<TexData>*)_Ptr)->mData;
}

View file

@ -28,7 +28,7 @@ static s64 ParseTrajectorySymbolArg(GfxData* aGfxData, DataNode<Trajectory>* aNo
trajectory_constant(NULL);
// Unknown
PrintError(" ERROR: Unknown trajectory arg: %s", _Arg.begin());
PrintDataError(" ERROR: Unknown trajectory arg: %s", _Arg.begin());
return 0;
}
@ -59,7 +59,7 @@ static void ParseTrajectorySymbol(GfxData* aGfxData, DataNode<Trajectory>* aNode
trajectory_symbol_0(TRAJECTORY_END);
// Unknown
PrintError(" ERROR: Unknown trajectory symbol: %s", _Symbol.begin());
PrintDataError(" ERROR: Unknown trajectory symbol: %s", _Symbol.begin());
}
DataNode<Trajectory>* DynOS_Trajectory_Parse(GfxData* aGfxData, DataNode<Trajectory>* aNode, bool aDisplayPercent) {

View file

@ -33,14 +33,14 @@ void DynOS_Actor_AddCustom(const SysPath &aFilename, const char *aActorName) {
GfxData *_GfxData = DynOS_Actor_LoadFromBinary(aFilename, actorName, aFilename, false);
if (!_GfxData) {
Print(" ERROR: Couldn't load Actor Binary \"%s\" from \"%s\"", actorName, aFilename.c_str());
PrintError(" ERROR: Couldn't load Actor Binary \"%s\" from \"%s\"", actorName, aFilename.c_str());
free(actorName);
return;
}
void* geoLayout = (*(_GfxData->mGeoLayouts.end() - 1))->mData;
if (!geoLayout) {
Print(" ERROR: Couldn't load geo layout for \"%s\"", actorName);
PrintError(" ERROR: Couldn't load geo layout for \"%s\"", actorName);
free(actorName);
return;
}
@ -52,7 +52,7 @@ void DynOS_Actor_AddCustom(const SysPath &aFilename, const char *aActorName) {
actorGfx.mPackIndex = MOD_PACK_INDEX;
actorGfx.mGraphNode = (GraphNode *) DynOS_Model_LoadGeo(&id, MODEL_POOL_SESSION, geoLayout, true);
if (!actorGfx.mGraphNode) {
Print(" ERROR: Couldn't load graph node for \"%s\"", actorName);
PrintError(" ERROR: Couldn't load graph node for \"%s\"", actorName);
free(actorName);
return;
}

View file

@ -105,7 +105,7 @@ void DynOS_Bhv_HookAllCustomBehaviors() {
// Theres currently no better place but to do this here.
if (smlua_hook_custom_bhv(script, scriptName) == 0) {
PrintError(" ERROR: Failed to add custom behavior '%s'!", scriptName);
PrintDataError(" ERROR: Failed to add custom behavior '%s'!", scriptName);
}
}
}

View file

@ -86,7 +86,7 @@ void DynOS_Lvl_Activate(s32 modIndex, const SysPath &aFilename, const char *aLev
auto& newScriptNode = newScripts[newScripts.Count() - 1];
const void* originalScript = DynOS_Builtin_ScriptPtr_GetFromName(newScriptNode->mName.begin());
if (originalScript == NULL) {
Print("Could not find level to override: '%s'", newScriptNode->mName.begin());
PrintError("Could not find level to override: '%s'", newScriptNode->mName.begin());
return;
}
@ -155,7 +155,7 @@ void DynOS_Lvl_LoadBackground(void *aPtr) {
double_break:
if (foundList == NULL) {
Print("Could not find custom background");
PrintError("Could not find custom background");
return;
}

View file

@ -5,6 +5,7 @@
#include "djui_panel_pause.h"
#include "djui_panel_join.h"
#include "djui_panel_join_message.h"
#include "djui_console.h"
#include "../debuglog.h"
#include "pc/cliopts.h"
#include "game/level_update.h"
@ -66,6 +67,10 @@ void djui_init(void) {
djui_panel_playerlist_create(NULL);
djui_console_create();
}
void djui_init_late(void) {
if (gCLIOpts.Network != NT_SERVER) {
djui_panel_main_create(NULL);
if (configLanguage[0] == '\0') {
@ -130,6 +135,7 @@ void djui_render(void) {
}
djui_cursor_update();
djui_base_render(&gDjuiConsole->base);
djui_interactable_update();
djui_gfx_displaylist_end();
}

View file

@ -40,6 +40,7 @@ extern bool gDjuiDisabled;
extern bool gDjuiRenderBehindHud;
void djui_init(void);
void djui_init_late(void);
void djui_connect_menu_open(void);
void djui_lua_error(char* text);
void djui_render(void);

View file

@ -414,6 +414,24 @@ void djui_base_destroy_children(struct DjuiBase* base) {
base->child = NULL;
}
void djui_base_destroy_one_child(struct DjuiBase* base) {
// destroy last child in our linked list
struct DjuiBaseChild* prev = NULL;
struct DjuiBaseChild* child = base->child;
while (child != NULL) {
if (!child->next) { break; }
prev = child;
child = child->next;
}
if (child) {
child->base->parent = NULL;
djui_base_destroy(child->base);
free(child);
if (prev) { prev->next = NULL; }
}
}
void djui_base_init(struct DjuiBase* parent, struct DjuiBase* base, bool (*render)(struct DjuiBase*), void (*destroy)(struct DjuiBase*)) {
memset(base, 0, sizeof(struct DjuiBase));
base->parent = parent;

View file

@ -70,4 +70,5 @@ void djui_base_compute_tree(struct DjuiBase* base);
bool djui_base_render(struct DjuiBase* base);
void djui_base_destroy(struct DjuiBase* base);
void djui_base_destroy_children(struct DjuiBase* base);
void djui_base_destroy_one_child(struct DjuiBase* base);
void djui_base_init(struct DjuiBase* parent, struct DjuiBase* base, bool (*render)(struct DjuiBase*), void (*destroy)(struct DjuiBase*));

144
src/pc/djui/djui_console.c Normal file
View file

@ -0,0 +1,144 @@
#include <stdio.h>
#include <string.h>
#include "djui.h"
#include "djui_console.h"
#define MAX_CONSOLE_MESSAGES 500
struct DjuiConsole* gDjuiConsole = NULL;
bool gDjuiConsoleFocus = false;
char gDjuiConsoleTmpBuffer[CONSOLE_MAX_TMP_BUFFER] = "";
u32 sDjuiConsoleMessages = 0;
bool djui_console_render(struct DjuiBase* base) {
djui_base_set_size(base, gDjuiRoot->base.width.value, gDjuiRoot->base.height.value * 0.6f);
djui_rect_render(base);
return true;
}
static void djui_console_destroy(struct DjuiBase* base) {
struct DjuiConsole* console = (struct DjuiConsole*)base;
free(console);
}
void djui_console_toggle(void) {
if (gDjuiConsole == NULL) { return; }
gDjuiConsoleFocus = !gDjuiConsoleFocus;
djui_base_set_visible(&gDjuiConsole->base, gDjuiConsoleFocus);
if (gDjuiConsoleFocus) {
if (gDjuiChatBoxFocus) { djui_chat_box_toggle(); }
djui_interactable_set_input_focus(&gDjuiConsole->base);
} else {
djui_interactable_set_input_focus(NULL);
}
}
static bool djui_console_on_key_down(UNUSED struct DjuiBase* base, int scancode) {
if (gDjuiConsole == NULL) { return false; }
f32 yMax = gDjuiConsole->base.comp.height - gDjuiConsole->flow->base.height.value;
f32* yValue = &gDjuiConsole->flow->base.y.value;
bool canScrollUp = (*yValue > yMax);
bool canScrollDown = (*yValue < 0);
f32 pageAmount = gDjuiConsole->base.comp.height * 3.0f / 4.0f;
switch (scancode) {
case SCANCODE_UP:
if (canScrollUp) { *yValue = fmax(*yValue - 15, yMax); }
break;
case SCANCODE_DOWN:
if (canScrollDown) { *yValue = fmin(*yValue + 15, 0); }
break;
case SCANCODE_PAGE_UP:
if (canScrollUp) { *yValue = fmax(*yValue - pageAmount, yMax); }
break;
case SCANCODE_PAGE_DOWN:
if (canScrollDown) { *yValue = fmin(*yValue + pageAmount, 0); }
break;
case SCANCODE_ESCAPE: djui_console_toggle(); break;
default: break;
}
gDjuiConsole->scrolling = (*yValue != yMax);
return true;
}
void djui_console_message_create(char* message) {
djui_base_compute_tree(&gDjuiConsole->base);
struct DjuiBase* cfBase = &gDjuiConsole->flow->base;
f32 maxTextWidth = gDjuiConsole->base.comp.width - gDjuiConsole->base.padding.left.value - gDjuiConsole->base.padding.right.value;
struct DjuiText* text = djui_text_create(cfBase, message);
struct DjuiBase* tBase = &text->base;
djui_base_set_alignment(tBase, DJUI_HALIGN_LEFT, DJUI_VALIGN_BOTTOM);
djui_base_set_size_type(tBase, DJUI_SVT_ABSOLUTE, DJUI_SVT_ABSOLUTE);
djui_base_set_size(tBase, maxTextWidth, 32);
djui_base_set_color(tBase, 255, 255, 255, 255);
// figure out chat message height
text->base.comp.width = maxTextWidth;
f32 messageHeight = djui_text_count_lines(text, 10) * (text->font->lineHeight * text->font->defaultFontScale) + 8;
djui_base_set_size(tBase, maxTextWidth, messageHeight);
f32 heightAdjust = messageHeight + gDjuiConsole->flow->margin.value;
cfBase->height.value += heightAdjust;
if (gDjuiConsole->scrolling) {
cfBase->y.value -= heightAdjust;
}
sDjuiConsoleMessages++;
if (sDjuiConsoleMessages >= MAX_CONSOLE_MESSAGES) {
if (cfBase->child) {
heightAdjust = cfBase->child->base->height.value + gDjuiConsole->flow->margin.value;
cfBase->height.value -= heightAdjust;
if (gDjuiConsole->scrolling) {
cfBase->y.value += heightAdjust;
}
}
djui_base_destroy_one_child(cfBase);
sDjuiConsoleMessages--;
}
}
struct DjuiConsole* djui_console_create(void) {
if (gDjuiConsole != NULL) {
djui_base_destroy(&gDjuiConsole->base);
gDjuiConsole = NULL;
}
struct DjuiConsole* console = calloc(1, sizeof(struct DjuiConsole));
struct DjuiBase* base = &console->base;
djui_base_init(NULL, base, djui_console_render, djui_console_destroy);
djui_base_set_size_type(base, DJUI_SVT_ABSOLUTE, DJUI_SVT_ABSOLUTE);
djui_base_set_size(base, gDjuiRoot->base.width.value, gDjuiRoot->base.height.value * 0.6f);
djui_base_set_alignment(base, DJUI_HALIGN_LEFT, DJUI_VALIGN_TOP);
djui_base_set_color(base, 0, 0, 0, 250);
djui_base_set_padding(base, 0, 8, 8, 8);
djui_base_set_visible(base, false);
djui_interactable_create(base, NULL);
djui_interactable_hook_key(base, djui_console_on_key_down, NULL);
struct DjuiFlowLayout* flow = djui_flow_layout_create(base);
struct DjuiBase* cfBase = &flow->base;
djui_base_set_alignment(cfBase, DJUI_HALIGN_LEFT, DJUI_VALIGN_BOTTOM);
djui_base_set_location(cfBase, 0, 0);
djui_base_set_size_type(cfBase, DJUI_SVT_RELATIVE, DJUI_SVT_ABSOLUTE);
djui_base_set_size(cfBase, 1.0f, 0);
djui_base_set_color(cfBase, 0, 0, 0, 0);
djui_base_set_padding(cfBase, 2, 2, 2, 2);
djui_flow_layout_set_margin(flow, 2);
djui_flow_layout_set_flow_direction(flow, DJUI_FLOW_DIR_UP);
cfBase->addChildrenToHead = true;
cfBase->abandonAfterChildRenderFail = true;
console->flow = flow;
gDjuiConsole = console;
return console;
}

View file

@ -0,0 +1,17 @@
#pragma once
#include "djui.h"
struct DjuiConsole {
struct DjuiBase base;
struct DjuiFlowLayout* flow;
bool scrolling;
};
#define CONSOLE_MAX_TMP_BUFFER 256
extern struct DjuiConsole* gDjuiConsole;
extern bool gDjuiConsoleFocus;
extern char gDjuiConsoleTmpBuffer[];
void djui_console_message_create(char* message);
void djui_console_toggle(void);
struct DjuiConsole* djui_console_create(void);

View file

@ -23,10 +23,12 @@ void djui_cursor_set_visible(bool visible) {
djui_base_set_visible(&sMouseCursor->base, visible);
}
if (configWindow.fullscreen) {
wm_api->set_cursor_visible(false);
} else {
wm_api->set_cursor_visible(!visible);
if (wm_api) {
if (configWindow.fullscreen) {
wm_api->set_cursor_visible(false);
} else {
wm_api->set_cursor_visible(!visible);
}
}
sSavedMouseX = mouse_window_x;
sSavedMouseY = mouse_window_y;

View file

@ -4,6 +4,7 @@
#include "djui_panel_pause.h"
#include "djui_panel_modlist.h"
#include "djui_panel_playerlist.h"
#include "djui_console.h"
#include "src/pc/controller/controller_sdl.h"
#include "src/pc/controller/controller_mouse.h"
@ -17,6 +18,8 @@
#define CALL_CALLBACK(x) if (base->interactable->x != NULL) { base->interactable->x(base); }
#define CALL_CALLBACK_PARAM(x, y) if (base->interactable->x != NULL) { base->interactable->x(base, y); }
#define SCANCODE_F1 59
enum PadHoldDirection { PAD_HOLD_DIR_NONE, PAD_HOLD_DIR_UP, PAD_HOLD_DIR_DOWN, PAD_HOLD_DIR_LEFT, PAD_HOLD_DIR_RIGHT };
static enum PadHoldDirection sKeyboardHoldDirection = PAD_HOLD_DIR_NONE;
static u16 sKeyboardButtons = 0;
@ -32,6 +35,7 @@ bool gInteractableOverridePad = false;
OSContPad gInteractablePad = { 0 };
static OSContPad sLastInteractablePad = { 0 };
static int sLastMouseButtons = 0;
static bool sControlDown = false;
static void djui_interactable_update_style(struct DjuiBase* base) {
if (base == NULL) { return; }
@ -180,6 +184,10 @@ void djui_interactable_set_binding(struct DjuiBase* base) {
}
void djui_interactable_set_input_focus(struct DjuiBase* base) {
if (gDjuiConsoleFocus && base != &gDjuiConsole->base) {
return;
}
djui_interactable_on_focus_end(gInteractableFocus);
gInteractableFocus = base;
djui_interactable_on_focus_begin(base);
@ -195,6 +203,12 @@ bool djui_interactable_on_key_down(int scancode) {
return true;
}
if (scancode == SCANCODE_CONTROL_LEFT) {
sControlDown = true;
} else if (sControlDown && scancode == SCANCODE_F1) {
djui_console_toggle();
}
bool keyFocused = (gInteractableFocus != NULL)
&& (gInteractableFocus->interactable != NULL)
&& (gInteractableFocus->interactable->on_key_down != NULL);
@ -220,7 +234,7 @@ bool djui_interactable_on_key_down(int scancode) {
if (scancode == (int)configKeyChat[i]) { pressChat = true; }
}
if (pressChat) {
if (pressChat && !gDjuiConsoleFocus) {
djui_chat_box_toggle();
return true;
}
@ -273,6 +287,10 @@ void djui_interactable_on_key_up(int scancode) {
}
}
if (scancode == SCANCODE_CONTROL_LEFT) {
sControlDown = false;
}
if (keyFocused) {
gInteractableFocus->interactable->on_key_up(gInteractableFocus, scancode);
sKeyboardHoldDirection = PAD_HOLD_DIR_NONE;

View file

@ -28,11 +28,8 @@ struct DjuiRoot* djui_root_create(void) {
djui_base_init(NULL, base, djui_root_render, djui_root_destroy);
u32 windowWidth, windowHeight;
wm_api->get_dimensions(&windowWidth, &windowHeight);
djui_base_set_location(base, 0, 0);
djui_base_set_size(base, windowWidth, windowHeight);
djui_base_set_size(base, 1280, 720);
djui_base_set_color(base, 0, 0, 0, 0);
return root;

View file

@ -18,9 +18,10 @@
#include "smlua_sync_table.h"
#include "pc/debuglog.h"
#include "pc/djui/djui_console.h"
#define LOG_LUA(...) { if (!gSmLuaSuppressErrors) { _debuglog_print_log("LUA ", __FILE__), printf(__VA_ARGS__), printf("\n"), smlua_mod_error(); } }
#define LOG_LUA_LINE(...) { if (!gSmLuaSuppressErrors) { _debuglog_print_log("LUA ", __FILE__), printf(__VA_ARGS__), printf("\n"), smlua_mod_error(); smlua_logline(); } }
#define LOG_LUA(...) { if (!gSmLuaSuppressErrors) { _debuglog_print_log("LUA ", __FILE__), printf(__VA_ARGS__), printf("\n"), smlua_mod_error(), snprintf(gDjuiConsoleTmpBuffer, CONSOLE_MAX_TMP_BUFFER, __VA_ARGS__), djui_console_message_create(gDjuiConsoleTmpBuffer); } }
#define LOG_LUA_LINE(...) { if (!gSmLuaSuppressErrors) { _debuglog_print_log("LUA ", __FILE__), printf(__VA_ARGS__), printf("\n"), smlua_mod_error(); snprintf(gDjuiConsoleTmpBuffer, CONSOLE_MAX_TMP_BUFFER, __VA_ARGS__), djui_console_message_create(gDjuiConsoleTmpBuffer), smlua_logline(); } }
#ifdef DEVELOPMENT
#define LUA_STACK_CHECK_BEGIN() int __LUA_STACK_TOP = lua_gettop(gLuaState)

View file

@ -752,7 +752,7 @@ void smlua_logline(void) {
int level = 0;
while (lua_getstack(L, level, &info)) {
lua_getinfo(L, "nSl", &info);
LOG_INFO(" [%d] %s:%d -- %s [%s]",
LOG_LUA(" [%d] %s:%d -- %s [%s]",
level, info.short_src, info.currentline,
(info.name ? info.name : "<unknown>"), info.what);
++level;

View file

@ -290,6 +290,7 @@ void main_func(void) {
sync_objects_init_system();
djui_unicode_init();
djui_init();
mods_init();
// load config
@ -367,7 +368,7 @@ void main_func(void) {
audio_api = &audio_null;
}
djui_init();
djui_init_late();
if (gCLIOpts.Network == NT_CLIENT) {
network_set_system(NS_SOCKET);