RenderD7 is now LibRenderD7
This commit is contained in:
20
source/Clock.cpp
Normal file
20
source/Clock.cpp
Normal file
@ -0,0 +1,20 @@
|
||||
#include <renderd7/Clock.hpp>
|
||||
|
||||
namespace rnd7 {
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
Time Clock::getElapsedTime() const {
|
||||
return getCurrentTime() - m_startTime;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
Time Clock::restart() {
|
||||
Time now = getCurrentTime();
|
||||
Time elapsed = now - m_startTime;
|
||||
m_startTime = now;
|
||||
|
||||
return elapsed;
|
||||
}
|
||||
|
||||
}
|
200
source/Time.cpp
Normal file
200
source/Time.cpp
Normal file
@ -0,0 +1,200 @@
|
||||
#include <renderd7/Time.hpp>
|
||||
|
||||
|
||||
namespace rnd7 {
|
||||
////////////////////////////////////////////////////////////
|
||||
const Time Time::Zero_;
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
Time::Time() :
|
||||
m_microseconds(0) {
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
float Time::asSeconds() const {
|
||||
return m_microseconds / 1000000.f;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
int Time::asMilliseconds() const {
|
||||
return static_cast<int>(m_microseconds / 1000);
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
long Time::asMicroseconds() const {
|
||||
return m_microseconds;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
Time::Time(long microseconds) :
|
||||
m_microseconds(microseconds) {
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
Time seconds(float amount) {
|
||||
return Time(static_cast<long>(amount * 1000000));
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
Time milliseconds(int amount) {
|
||||
return Time(static_cast<long>(amount) * 1000);
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
Time microseconds(long amount) {
|
||||
return Time(amount);
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
bool operator==(Time left, Time right) {
|
||||
return left.asMicroseconds() == right.asMicroseconds();
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
bool operator!=(Time left, Time right) {
|
||||
return left.asMicroseconds() != right.asMicroseconds();
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
bool operator<(Time left, Time right) {
|
||||
return left.asMicroseconds() < right.asMicroseconds();
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
bool operator>(Time left, Time right) {
|
||||
return left.asMicroseconds() > right.asMicroseconds();
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
bool operator<=(Time left, Time right) {
|
||||
return left.asMicroseconds() <= right.asMicroseconds();
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
bool operator>=(Time left, Time right) {
|
||||
return left.asMicroseconds() >= right.asMicroseconds();
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
Time operator-(Time right) {
|
||||
return microseconds(-right.asMicroseconds());
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
Time operator+(Time left, Time right) {
|
||||
return microseconds(left.asMicroseconds() + right.asMicroseconds());
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
Time &operator+=(Time &left, Time right) {
|
||||
return left = left + right;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
Time operator-(Time left, Time right) {
|
||||
return microseconds(left.asMicroseconds() - right.asMicroseconds());
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
Time &operator-=(Time &left, Time right) {
|
||||
return left = left - right;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
Time operator*(Time left, float right) {
|
||||
return seconds(left.asSeconds() * right);
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
Time operator*(Time left, long right) {
|
||||
return microseconds(left.asMicroseconds() * right);
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
Time operator*(float left, Time right) {
|
||||
return right * left;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
Time operator*(long left, Time right) {
|
||||
return right * left;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
Time &operator*=(Time &left, float right) {
|
||||
return left = left * right;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
Time &operator*=(Time &left, long right) {
|
||||
return left = left * right;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
Time operator/(Time left, float right) {
|
||||
return seconds(left.asSeconds() / right);
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
Time operator/(Time left, long right) {
|
||||
return microseconds(left.asMicroseconds() / right);
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
Time &operator/=(Time &left, float right) {
|
||||
return left = left / right;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
Time &operator/=(Time &left, long right) {
|
||||
return left = left / right;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
float operator/(Time left, Time right) {
|
||||
return left.asSeconds() / right.asSeconds();
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
Time operator%(Time left, Time right) {
|
||||
return microseconds(left.asMicroseconds() % right.asMicroseconds());
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
Time &operator%=(Time &left, Time right) {
|
||||
return left = left % right;
|
||||
}
|
||||
|
||||
}
|
106
source/bmpconverter.cpp
Normal file
106
source/bmpconverter.cpp
Normal file
@ -0,0 +1,106 @@
|
||||
#include <renderd7/bmpconverter.hpp>
|
||||
|
||||
namespace BitmapConverter{
|
||||
|
||||
//returns 0 if all went ok, non-0 if error
|
||||
//output image is always given in RGBA (with alpha channel), even if it's a BMP without alpha channel
|
||||
unsigned decodeBMP(std::vector<unsigned char>& image, unsigned& w, unsigned& h, const std::vector<unsigned char>& bmp) {
|
||||
static const unsigned MINHEADER = 54; //minimum BMP header size
|
||||
|
||||
if(bmp.size() < MINHEADER) return -1;
|
||||
if(bmp[0] != 'B' || bmp[1] != 'M') return 1; //It's not a BMP file if it doesn't start with marker 'BM'
|
||||
unsigned pixeloffset = bmp[10] + 256 * bmp[11]; //where the pixel data starts
|
||||
//read width and height from BMP header
|
||||
w = bmp[18] + bmp[19] * 256;
|
||||
h = bmp[22] + bmp[23] * 256;
|
||||
//read number of channels from BMP header
|
||||
if(bmp[28] != 24 && bmp[28] != 32) return 2; //only 24-bit and 32-bit BMPs are supported.
|
||||
unsigned numChannels = bmp[28] / 8;
|
||||
|
||||
//The amount of scanline bytes is width of image times channels, with extra bytes added if needed
|
||||
//to make it a multiple of 4 bytes.
|
||||
unsigned scanlineBytes = w * numChannels;
|
||||
if(scanlineBytes % 4 != 0) scanlineBytes = (scanlineBytes / 4) * 4 + 4;
|
||||
|
||||
unsigned dataSize = scanlineBytes * h;
|
||||
if(bmp.size() < dataSize + pixeloffset) return 3; //BMP file too small to contain all pixels
|
||||
|
||||
image.resize(w * h * 4);
|
||||
|
||||
/*
|
||||
There are 3 differences between BMP and the raw image buffer for LodePNG:
|
||||
-it's upside down
|
||||
-it's in BGR instead of RGB format (or BRGA instead of RGBA)
|
||||
-each scanline has padding bytes to make it a multiple of 4 if needed
|
||||
The 2D for loop below does all these 3 conversions at once.
|
||||
*/
|
||||
for(unsigned y = 0; y < h; y++)
|
||||
for(unsigned x = 0; x < w; x++) {
|
||||
//pixel start byte position in the BMP
|
||||
unsigned bmpos = pixeloffset + (h - y - 1) * scanlineBytes + numChannels * x;
|
||||
//pixel start byte position in the new raw image
|
||||
unsigned newpos = 4 * y * w + 4 * x;
|
||||
if(numChannels == 3) {
|
||||
image[newpos + 0] = bmp[bmpos + 2]; //R
|
||||
image[newpos + 1] = bmp[bmpos + 1]; //G
|
||||
image[newpos + 2] = bmp[bmpos + 0]; //B
|
||||
image[newpos + 3] = 255; //A
|
||||
} else {
|
||||
image[newpos + 0] = bmp[bmpos + 2]; //R
|
||||
image[newpos + 1] = bmp[bmpos + 1]; //G
|
||||
image[newpos + 2] = bmp[bmpos + 0]; //B
|
||||
image[newpos + 3] = bmp[bmpos + 3]; //A
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
std::vector<unsigned char> ConvertFile(std::string filename) {
|
||||
|
||||
std::vector<unsigned char> bmp;
|
||||
lodepng::load_file(bmp, filename);
|
||||
|
||||
std::vector<unsigned char> image;
|
||||
unsigned w, h;
|
||||
unsigned error = BitmapConverter::decodeBMP(image, w, h, bmp);
|
||||
|
||||
if(error) {
|
||||
std::cout << "BMP decoding error " << error << std::endl;
|
||||
|
||||
}
|
||||
|
||||
std::vector<unsigned char> png;
|
||||
error = lodepng::encode(png, image, w, h);
|
||||
|
||||
if(error) {
|
||||
std::cout << "PNG encoding error " << error << ": " << lodepng_error_text(error) << std::endl;
|
||||
|
||||
}
|
||||
|
||||
return png;
|
||||
|
||||
}
|
||||
|
||||
std::vector<unsigned char> ConvertData(std::vector<unsigned char> data) {
|
||||
|
||||
std::vector<unsigned char> image;
|
||||
unsigned w, h;
|
||||
unsigned error = BitmapConverter::decodeBMP(image, w, h, data);
|
||||
|
||||
if(error) {
|
||||
std::cout << "BMP decoding error " << error << std::endl;
|
||||
|
||||
}
|
||||
|
||||
std::vector<unsigned char> png;
|
||||
error = lodepng::encode(png, image, w, h);
|
||||
|
||||
if(error) {
|
||||
std::cout << "PNG encoding error " << error << ": " << lodepng_error_text(error) << std::endl;
|
||||
|
||||
}
|
||||
|
||||
return png;
|
||||
|
||||
}
|
||||
}
|
98
source/lang.cpp
Normal file
98
source/lang.cpp
Normal file
@ -0,0 +1,98 @@
|
||||
#include <renderd7/lang.hpp>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <3ds.h>
|
||||
static nlohmann::json appJson;
|
||||
|
||||
std::string RenderD7::Lang::getSys()
|
||||
{
|
||||
|
||||
u8 language = 1;
|
||||
CFGU_GetSystemLanguage(&language);
|
||||
|
||||
switch(language) {
|
||||
case 0:
|
||||
return "jp"; // Japanese
|
||||
break;
|
||||
|
||||
case 1:
|
||||
return "en"; // English
|
||||
break;
|
||||
|
||||
case 2:
|
||||
return "fr"; // French
|
||||
break;
|
||||
|
||||
case 3:
|
||||
return "de"; // German
|
||||
break;
|
||||
|
||||
case 4:
|
||||
return "it"; // Italian
|
||||
break;
|
||||
|
||||
case 5:
|
||||
return "es"; // Spanish
|
||||
break;
|
||||
|
||||
case 6:
|
||||
return "zh-CN"; // Chinese (Simplified)
|
||||
break;
|
||||
|
||||
// case 7:
|
||||
// return "ko"; // Korean
|
||||
// break;
|
||||
|
||||
// case 8:
|
||||
// return "nl"; // Dutch
|
||||
// break;
|
||||
|
||||
case 9:
|
||||
return "pt"; // Portuguese
|
||||
break;
|
||||
|
||||
case 10:
|
||||
return "ru"; // Russian
|
||||
break;
|
||||
|
||||
case 11:
|
||||
return "zh-TW"; // Chinese (Traditional)
|
||||
break;
|
||||
|
||||
default:
|
||||
return "en"; // Fall back to English if missing
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
std::string RenderD7::Lang::get(const std::string &key) {
|
||||
if (!appJson.contains(key)) return key;
|
||||
|
||||
return appJson.at(key).get_ref<const std::string&>();
|
||||
}
|
||||
|
||||
void RenderD7::Lang::load(const std::string &lang) {
|
||||
FILE *values;
|
||||
|
||||
if (access(("romfs:/lang/" + lang + "/app.json").c_str(), F_OK) == 0) {
|
||||
values = fopen(("romfs:/lang/" + lang + "/app.json").c_str(), "rt");
|
||||
if (values) {
|
||||
appJson = nlohmann::json::parse(values, nullptr, false);
|
||||
fclose(values);
|
||||
}
|
||||
if (appJson.is_discarded())
|
||||
appJson = { };
|
||||
return;
|
||||
|
||||
} else {
|
||||
values = fopen("romfs:/lang/en/app.json", "rt");
|
||||
if (values) {
|
||||
appJson = nlohmann::json::parse(values, nullptr, false);
|
||||
fclose(values);
|
||||
}
|
||||
if (appJson.is_discarded())
|
||||
appJson = { };
|
||||
return;
|
||||
}
|
||||
}
|
60
source/log.cpp
Normal file
60
source/log.cpp
Normal file
@ -0,0 +1,60 @@
|
||||
#include <renderd7/log.hpp>
|
||||
|
||||
#include <memory>
|
||||
|
||||
std::string Log::format(const std::string& fmt_str, ...)
|
||||
{
|
||||
va_list ap;
|
||||
char* fp = NULL;
|
||||
va_start(ap, fmt_str);
|
||||
vasprintf(&fp, fmt_str.c_str(), ap);
|
||||
va_end(ap);
|
||||
std::unique_ptr<char, decltype(free)*> formatted(fp, free);
|
||||
return std::string(formatted.get());
|
||||
}
|
||||
|
||||
std::string Log::logDate(void)
|
||||
{
|
||||
time_t unixTime;
|
||||
struct tm timeStruct;
|
||||
time(&unixTime);
|
||||
localtime_r(&unixTime, &timeStruct);
|
||||
return format("%04i-%02i-%02i_%02i-%02i-%02i", timeStruct.tm_year + 1900, timeStruct.tm_mon + 1, timeStruct.tm_mday,
|
||||
timeStruct.tm_hour, timeStruct.tm_min, timeStruct.tm_sec);
|
||||
}
|
||||
|
||||
Log::Log()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void Log::Init(const char *filename)
|
||||
{
|
||||
std::string name = "sdmc:/" + Log::logDate() + filename + ".txt";
|
||||
this->filename = name.c_str();
|
||||
if ((access(name.c_str(), F_OK) == 0))
|
||||
{
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
FILE* logfile = fopen((name.c_str()), "w");
|
||||
fclose(logfile);
|
||||
}
|
||||
}
|
||||
|
||||
void Log::Write(std::string debug_text)
|
||||
{
|
||||
std::ofstream logFile;
|
||||
logFile.open((this->filename), std::ofstream::app);
|
||||
std::string writeDebug = "[";
|
||||
writeDebug += logDate();
|
||||
writeDebug += "] ";
|
||||
writeDebug += debug_text.c_str();
|
||||
logFile << writeDebug << std::endl;
|
||||
logFile.close();
|
||||
}
|
||||
Log::~Log()
|
||||
{
|
||||
|
||||
}
|
1730
source/renderd7.cpp
Normal file
1730
source/renderd7.cpp
Normal file
File diff suppressed because it is too large
Load Diff
130
source/sound.cpp
Normal file
130
source/sound.cpp
Normal file
@ -0,0 +1,130 @@
|
||||
#include <renderd7/sound.hpp>
|
||||
|
||||
#include <cstdio>
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
#include <string>
|
||||
|
||||
extern bool isndspinit;
|
||||
using std::string;
|
||||
|
||||
// Reference: http://yannesposito.com/Scratch/en/blog/2010-10-14-Fun-with-wav/
|
||||
typedef struct _WavHeader {
|
||||
char magic[4]; // "RIFF"
|
||||
u32 totallength; // Total file length, minus 8.
|
||||
char wavefmt[8]; // Should be "WAVEfmt "
|
||||
u32 format; // 16 for PCM format
|
||||
u16 pcm; // 1 for PCM format
|
||||
u16 channels; // Channels
|
||||
u32 frequency; // Sampling frequency
|
||||
u32 bytes_per_second;
|
||||
u16 bytes_by_capture;
|
||||
u16 bits_per_sample;
|
||||
char data[4]; // "data"
|
||||
u32 bytes_in_data;
|
||||
} WavHeader;
|
||||
static_assert(sizeof(WavHeader) == 44, "WavHeader size is not 44 bytes.");
|
||||
|
||||
sound::sound(const string& path, int channel, bool toloop) {
|
||||
if (isndspinit){
|
||||
ndspSetOutputMode(NDSP_OUTPUT_STEREO);
|
||||
ndspSetOutputCount(2); // Num of buffers
|
||||
|
||||
// Reading wav file
|
||||
FILE* fp = fopen(path.c_str(), "rb");
|
||||
|
||||
if (!fp) {
|
||||
printf("Could not open the WAV file: %s\n", path.c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
WavHeader wavHeader;
|
||||
size_t read = fread(&wavHeader, 1, sizeof(wavHeader), fp);
|
||||
if (read != sizeof(wavHeader)) {
|
||||
// Short read.
|
||||
printf("WAV file header is too short: %s\n", path.c_str());
|
||||
fclose(fp);
|
||||
return;
|
||||
}
|
||||
|
||||
// Verify the header.
|
||||
static const char RIFF_magic[4] = {'R','I','F','F'};
|
||||
if (memcmp(wavHeader.magic, RIFF_magic, sizeof(wavHeader.magic)) != 0) {
|
||||
// Incorrect magic number.
|
||||
printf("Wrong file format.\n");
|
||||
fclose(fp);
|
||||
return;
|
||||
}
|
||||
|
||||
if (wavHeader.totallength == 0 ||
|
||||
(wavHeader.channels != 1 && wavHeader.channels != 2) ||
|
||||
(wavHeader.bits_per_sample != 8 && wavHeader.bits_per_sample != 16)) {
|
||||
// Unsupported WAV file.
|
||||
printf("Corrupted wav file.\n");
|
||||
fclose(fp);
|
||||
return;
|
||||
}
|
||||
|
||||
// Get the file size.
|
||||
fseek(fp, 0, SEEK_END);
|
||||
dataSize = ftell(fp) - sizeof(wavHeader);
|
||||
|
||||
// Allocating and reading samples
|
||||
data = static_cast<u8*>(linearAlloc(dataSize));
|
||||
fseek(fp, 44, SEEK_SET);
|
||||
fread(data, 1, dataSize, fp);
|
||||
fclose(fp);
|
||||
dataSize /= 2; // FIXME: 16-bit or stereo?
|
||||
|
||||
// Find the right format
|
||||
u16 ndspFormat;
|
||||
if (wavHeader.bits_per_sample == 8) {
|
||||
ndspFormat = (wavHeader.channels == 1) ?
|
||||
NDSP_FORMAT_MONO_PCM8 :
|
||||
NDSP_FORMAT_STEREO_PCM8;
|
||||
} else {
|
||||
ndspFormat = (wavHeader.channels == 1) ?
|
||||
NDSP_FORMAT_MONO_PCM16 :
|
||||
NDSP_FORMAT_STEREO_PCM16;
|
||||
}
|
||||
|
||||
ndspChnReset(channel);
|
||||
ndspChnSetInterp(channel, NDSP_INTERP_NONE);
|
||||
ndspChnSetRate(channel, float(wavHeader.frequency));
|
||||
ndspChnSetFormat(channel, ndspFormat);
|
||||
|
||||
// Create and play a wav buffer
|
||||
memset(&waveBuf, 0, sizeof(waveBuf));
|
||||
|
||||
waveBuf.data_vaddr = reinterpret_cast<u32*>(data);
|
||||
waveBuf.nsamples = dataSize / (wavHeader.bits_per_sample >> 3);
|
||||
waveBuf.looping = toloop;
|
||||
waveBuf.status = NDSP_WBUF_FREE;
|
||||
chnl = channel;}
|
||||
}
|
||||
|
||||
sound::~sound() {
|
||||
if (isndspinit){
|
||||
waveBuf.data_vaddr = 0;
|
||||
waveBuf.nsamples = 0;
|
||||
waveBuf.looping = false;
|
||||
waveBuf.status = 0;
|
||||
ndspChnWaveBufClear(chnl);
|
||||
|
||||
if (data) {
|
||||
linearFree(data);
|
||||
}}
|
||||
}
|
||||
|
||||
void sound::play() {
|
||||
if (isndspinit){
|
||||
if (!data) return;
|
||||
DSP_FlushDataCache(data, dataSize);
|
||||
ndspChnWaveBufAdd(chnl, &waveBuf);}
|
||||
}
|
||||
|
||||
void sound::stop() {
|
||||
if (isndspinit){
|
||||
if (!data) return;
|
||||
ndspChnWaveBufClear(chnl);}
|
||||
}
|
81
source/thread.cpp
Normal file
81
source/thread.cpp
Normal file
@ -0,0 +1,81 @@
|
||||
#include <renderd7/thread.hpp>
|
||||
namespace RenderD7 {
|
||||
void Threads::Exit()
|
||||
{
|
||||
|
||||
}
|
||||
Thread::Thread() :
|
||||
m_started(false),
|
||||
m_running(false) { /* do nothing */ }
|
||||
|
||||
Thread::Thread(std::function<void(RenderD7::Parameter)> t_function, RenderD7::Parameter t_parameter, bool t_autostart, bool t_detached, unsigned long long int t_stackSize) :
|
||||
m_started(false),
|
||||
m_running(false) {
|
||||
initialize(t_function, t_parameter, t_autostart, t_detached, t_stackSize);
|
||||
}
|
||||
|
||||
Thread::~Thread() {
|
||||
join();
|
||||
|
||||
if (m_started) threadFree(m_thread);
|
||||
}
|
||||
|
||||
void Thread::initialize(std::function<void(RenderD7::Parameter)> t_function, RenderD7::Parameter t_parameter, bool t_autostart, bool t_detached, unsigned long long int t_stackSize) {
|
||||
m_stackSize = t_stackSize;
|
||||
m_data.m_parameter = t_parameter;
|
||||
m_data.m_function = t_function;
|
||||
m_data.m_running = &m_running;
|
||||
|
||||
if (t_autostart) {
|
||||
start(t_detached);
|
||||
}
|
||||
}
|
||||
|
||||
void Thread::setStackSize(unsigned long long int t_stackSize) {
|
||||
m_stackSize = t_stackSize;
|
||||
}
|
||||
|
||||
void Thread::start(bool t_detached) {
|
||||
if (!m_running) {
|
||||
m_started = true;
|
||||
m_running = true;
|
||||
s32 prio;
|
||||
svcGetThreadPriority(&prio, CUR_THREAD_HANDLE);
|
||||
m_thread = threadCreate(threadFunction, &m_data, m_stackSize, prio + 1, -2, t_detached);
|
||||
}
|
||||
}
|
||||
|
||||
void Thread::kill() {
|
||||
threadDetach(m_thread);
|
||||
m_running = false;
|
||||
m_started = false;
|
||||
}
|
||||
|
||||
void Thread::join(long long unsigned int t_timeout) {
|
||||
if (m_running) {
|
||||
threadJoin(m_thread, t_timeout);
|
||||
threadFree(m_thread);
|
||||
m_running = false;
|
||||
m_started = false;
|
||||
}
|
||||
}
|
||||
|
||||
bool Thread::isRunning() {
|
||||
return m_running;
|
||||
}
|
||||
|
||||
void Thread::sleep() {
|
||||
svcSleepThread(0);
|
||||
}
|
||||
|
||||
void Thread::sleep(int t_milliseconds) {
|
||||
svcSleepThread(1000000 * t_milliseconds);
|
||||
}
|
||||
|
||||
// private methods
|
||||
void Thread::threadFunction(void* arg) {
|
||||
RenderD7::Thread::ThreadData data = *static_cast<RenderD7::Thread::ThreadData*>(arg);
|
||||
data.m_function(data.m_parameter);
|
||||
*data.m_running = false;
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user