112 lines
2.9 KiB
C++
112 lines
2.9 KiB
C++
/*
|
|
* Copyright 2015 - 2025 gary@drinkingtea.net
|
|
*
|
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
|
*/
|
|
|
|
#if defined(OX_USE_STDLIB)
|
|
|
|
#include <iomanip>
|
|
#include <iostream>
|
|
|
|
static const auto OxPrintTrace = std::getenv("OXTRACE") != nullptr;
|
|
#endif
|
|
|
|
#include "strops.hpp"
|
|
|
|
#include "math.hpp"
|
|
#include "stringview.hpp"
|
|
#include "types.hpp"
|
|
|
|
#define REG_MGBA_DEBUG_ENABLE *reinterpret_cast<volatile uint16_t*>(0x4FFF780)
|
|
#define REG_MGBA_DEBUG_FLAGS *reinterpret_cast<volatile uint16_t*>(0x4FFF700)
|
|
#define REG_MGBA_DEBUG_STRING (reinterpret_cast<char*>(0x4FFF600))
|
|
|
|
inline void nullLog(ox::StringViewCR) {}
|
|
inline void (*infoLog)(ox::StringViewCR) = nullLog;
|
|
inline void (*debugLog)(ox::StringViewCR) = nullLog;
|
|
inline void (*errorLog)(ox::StringViewCR) = nullLog;
|
|
|
|
namespace mgba {
|
|
|
|
enum LogChan {
|
|
Fatal = 0,
|
|
Error = 1,
|
|
Warn = 2,
|
|
Info = 3,
|
|
Debug = 4,
|
|
};
|
|
|
|
OX_ALLOW_UNSAFE_BUFFERS_BEGIN
|
|
|
|
template<LogChan chan>
|
|
static void log(ox::StringViewCR str) {
|
|
const auto sz = ox::min<std::size_t>(0x100, str.bytes());
|
|
ox::strncpy(REG_MGBA_DEBUG_STRING, str.data(), sz);
|
|
REG_MGBA_DEBUG_FLAGS = chan | 0x100;
|
|
}
|
|
|
|
void initConsole() {
|
|
REG_MGBA_DEBUG_ENABLE = 0xC0DE;
|
|
if (REG_MGBA_DEBUG_ENABLE == 0x1DEA) {
|
|
infoLog = log<LogChan::Info>;
|
|
debugLog = log<LogChan::Info>; // use INFO because mGBA disables DEBUG on start
|
|
errorLog = log<LogChan::Info>;
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
extern "C" {
|
|
|
|
void oxTraceInitHook() {
|
|
}
|
|
|
|
void oxTraceHook([[maybe_unused]] const char *file, [[maybe_unused]] int line,
|
|
[[maybe_unused]] const char *ch, [[maybe_unused]] const char *msg) {
|
|
#if defined(OX_USE_STDLIB)
|
|
auto const chv = ox::StringView{ch};
|
|
if (OxPrintTrace) {
|
|
auto m = std::string_view{msg};
|
|
if (m.ends_with('\n')) {
|
|
m = std::string_view{msg, m.size() - 1};
|
|
}
|
|
std::cout << std::setw(53) << std::left << ch << "| ";
|
|
std::cout << std::setw(65) << std::left << m << '|';
|
|
std::cout << " " << file << ':' << line << "\n";
|
|
} else if (chv == "debug" || chv == "info") {
|
|
printf("%s\n", msg);
|
|
std::ignore = fflush(stdout);
|
|
} else if (chv == "stdout") {
|
|
printf("%s", msg);
|
|
std::ignore = fflush(stdout);
|
|
} else if (chv == "stderr") {
|
|
std::ignore = fprintf(stderr, "%s", msg);
|
|
std::ignore = fflush(stderr);
|
|
} else if (chv == "error") {
|
|
//std::cerr << "\033[31;1;1mERROR:\033[0m (" << file << ':' << line << "): " << msg << '\n';
|
|
std::ignore = fprintf(stderr, "\033[31;1;1mERROR:\033[0m (%s:%d): %s\n", file, line, msg);
|
|
std::ignore = fflush(stderr);
|
|
}
|
|
#else
|
|
if (ox::strcmp(ch, "info") == 0) {
|
|
infoLog(msg);
|
|
} else if (ox::strcmp(ch, "debug") == 0) {
|
|
debugLog(msg);
|
|
} else if (ox::strcmp(ch, "stdout") == 0) {
|
|
infoLog(msg);
|
|
} else if (ox::strcmp(ch, "stderr") == 0) {
|
|
errorLog(msg);
|
|
} else if (ox::strcmp(ch, "error") == 0) {
|
|
errorLog(msg);
|
|
}
|
|
#endif
|
|
}
|
|
|
|
OX_ALLOW_UNSAFE_BUFFERS_END
|
|
|
|
}
|
|
|