Compare commits
9 Commits
main
...
alpha-0-3-
Author | SHA1 | Date | |
---|---|---|---|
122b07639e | |||
ce6170c475 | |||
0786c6f999 | |||
5144d5c00c | |||
1bf4ac775f | |||
4f1b5ee53c | |||
da498451c2 | |||
37422eb337 | |||
![]() |
1f36fa9599 |
2566
Docs/Doxyfile
Normal file
2566
Docs/Doxyfile
Normal file
File diff suppressed because it is too large
Load Diff
13
Docs/custom.css
Normal file
13
Docs/custom.css
Normal file
@ -0,0 +1,13 @@
|
||||
#projectlogo img{
|
||||
max-height: 70px;
|
||||
}
|
||||
img[src="logotype.svg"]{
|
||||
width:10cm;
|
||||
}
|
||||
div.contents{
|
||||
max-width: 85%;
|
||||
margin-left: 2%;
|
||||
}
|
||||
.textblock h1{
|
||||
border-bottom: 1px solid #666;
|
||||
}
|
@ -1,2 +1,5 @@
|
||||
# RenderD7
|
||||
# RenderD7 030
|
||||
Simple and Easey to use UI and Graphics helper.
|
||||
|
||||
|
||||
|
||||
|
59
log.cpp
Normal file
59
log.cpp
Normal file
@ -0,0 +1,59 @@
|
||||
#include "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)
|
||||
{
|
||||
this->filename = filename;
|
||||
if ((access(filename, F_OK) == 0))
|
||||
{
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
FILE* logfile = fopen((filename), "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()
|
||||
{
|
||||
|
||||
}
|
19
log.hpp
Normal file
19
log.hpp
Normal file
@ -0,0 +1,19 @@
|
||||
|
||||
#include <fstream>
|
||||
#include <stdarg.h>
|
||||
#include <string>
|
||||
#include <time.h>
|
||||
#include <unistd.h>
|
||||
|
||||
class Log
|
||||
{
|
||||
public:
|
||||
Log();
|
||||
~Log();
|
||||
void Init(const char *filename);
|
||||
void Write(std::string debug_text);
|
||||
std::string logDate(void);
|
||||
std::string format(const std::string& fmt_str, ...);
|
||||
private:
|
||||
std::string filename;
|
||||
};
|
566
renderd7.cpp
Normal file
566
renderd7.cpp
Normal file
@ -0,0 +1,566 @@
|
||||
#include "renderd7.hpp"
|
||||
#include "log.hpp"
|
||||
#include <regex>
|
||||
|
||||
#define RGBA8(r, g, b, a) ((((r) & 0xFF) << 0) | (((g) & 0xFF) << 8) | (((b) & 0xFF) << 16) | (((a) & 0xFF) << 24))
|
||||
#define D7_NOTHING C2D_Color32(0, 0, 0, 0)
|
||||
Log renderd7log;
|
||||
float animtime;
|
||||
bool isndspinit = false;
|
||||
bool running = true;
|
||||
std::stack<std::unique_ptr<RenderD7::Scene>> RenderD7::Scene::scenes;
|
||||
|
||||
u32 d7_hDown;
|
||||
u32 d7_hHeld;
|
||||
u32 d7_hUp;
|
||||
touchPosition d7_touch;
|
||||
|
||||
C2D_TextBuf TextBuf;
|
||||
C2D_Font Font;
|
||||
|
||||
// Fps Calc
|
||||
static float current_fps = 0.0f;
|
||||
static unsigned int frames = 0;
|
||||
static u64 last_time = 0;
|
||||
float d11framerate = 0;
|
||||
//-----------------
|
||||
|
||||
bool currentScreen = false;
|
||||
|
||||
C3D_RenderTarget* Top;
|
||||
C3D_RenderTarget* TopRight;
|
||||
C3D_RenderTarget* Bottom;
|
||||
|
||||
#define DSEVENBLACK C2D_Color32(0, 0 ,0, 255)
|
||||
#define DSEVENWHITE C2D_Color32(255, 255, 255, 255)
|
||||
RenderD7::SpriteSheetAnimation::SpriteSheetAnimation()
|
||||
{
|
||||
renderd7log.Write("SpriteSheetAnimation createt!");
|
||||
}
|
||||
RenderD7::SpriteSheetAnimation::~SpriteSheetAnimation()
|
||||
{
|
||||
|
||||
}
|
||||
bool RenderD7::DrawImageFromSheet(RenderD7::Sheet* sheet, size_t index, float x, float y, float scaleX, float scaleY)
|
||||
{
|
||||
if (sheet->spritesheet != nullptr)
|
||||
{
|
||||
if (C2D_SpriteSheetCount(sheet->spritesheet) >= index)
|
||||
{
|
||||
return C2D_DrawImageAt(C2D_SpriteSheetGetImage(sheet->spritesheet, index), x, y, 0.5f, nullptr, scaleX, scaleY);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
void RenderD7::Init::NdspFirm(bool useit)
|
||||
{
|
||||
if (useit)
|
||||
{
|
||||
if ( access( "sdmc:/3ds/dspfirm.cdc", F_OK ) != -1 )
|
||||
{
|
||||
ndspInit();
|
||||
isndspinit = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
renderd7log.Write("RenderD7: SoundEngine Error! ndspfirm not found!");
|
||||
}
|
||||
}
|
||||
}
|
||||
void RenderD7::Exit::NdspFirm()
|
||||
{
|
||||
if (isndspinit)
|
||||
{
|
||||
ndspExit();
|
||||
}
|
||||
}
|
||||
void RenderD7::Msg::Display(std::string titletxt, std::string txt, C3D_RenderTarget *target)
|
||||
{
|
||||
C3D_FrameBegin(C3D_FRAME_SYNCDRAW);
|
||||
C2D_TargetClear(Top, DSEVENBLACK);
|
||||
C2D_TargetClear(Bottom, DSEVENBLACK);
|
||||
RenderD7::ClearTextBufs();
|
||||
RenderD7::OnScreen(Top);
|
||||
RenderD7::DrawRect(0, 0, 400, 240, RenderD7::Color::Hex("#111111"));
|
||||
RenderD7::OnScreen(Bottom);
|
||||
RenderD7::DrawRect(0, 0, 320, 240, RenderD7::Color::Hex("#111111"));
|
||||
RenderD7::OnScreen(target);
|
||||
RenderD7::DrawRect(0, 0, 400, 26, RenderD7::Color::Hex("#333333", 200));
|
||||
RenderD7::DrawText(5, 2, 0.7f, DSEVENWHITE, titletxt);
|
||||
RenderD7::DrawText(5, 30, 0.6f, DSEVENWHITE, txt);
|
||||
|
||||
C3D_FrameEnd(0);
|
||||
}
|
||||
void RenderD7::SetupLog()
|
||||
{
|
||||
renderd7log.Init("sdmc:/Flappy-Bird-RenderD7.log");
|
||||
}
|
||||
void RenderD7::SpriteSheetAnimation::Setup(RenderD7::Sheet *sheet, size_t imagecount, size_t startimage, float frame_begin, float frame_finish)
|
||||
{
|
||||
|
||||
D_totaltime = frame_begin;
|
||||
renderd7log.Write("frame_begin success");
|
||||
this->images = imagecount;
|
||||
renderd7log.Write("imagecount success");
|
||||
this->sheet = sheet;
|
||||
renderd7log.Write("sheet success");
|
||||
this->time = frame_finish;
|
||||
renderd7log.Write("frame_finish success");
|
||||
RenderD7::SpriteSheetAnimation::FromSheet(this->sheet, startimage);
|
||||
}
|
||||
void RenderD7::SpriteSheetAnimation::Play(float timespeed)
|
||||
{
|
||||
D_totaltime += timespeed;
|
||||
if (D_totaltime >= time)
|
||||
{
|
||||
D_totaltime -= time;
|
||||
imgs++;
|
||||
if (imgs == images)
|
||||
{
|
||||
imgs = 0;
|
||||
}
|
||||
}
|
||||
RenderD7::SpriteSheetAnimation::FromSheet(sheet, imgs);
|
||||
//RenderD7::SpriteSheetAnimation::Draw();
|
||||
|
||||
|
||||
}
|
||||
|
||||
void RenderD7::Error::DisplayError(std::string toptext, std::string errortext)
|
||||
{
|
||||
RenderD7::ClearTextBufs();
|
||||
C3D_FrameBegin(C3D_FRAME_SYNCDRAW);
|
||||
C2D_TargetClear(Top, DSEVENBLACK);
|
||||
C2D_TargetClear(Bottom, DSEVENBLACK);
|
||||
RenderD7::DrawTextCentered(0, 0, 0.7f, DSEVENWHITE, toptext, 400);
|
||||
RenderD7::DrawTextCentered(0, 100, 0.6f, DSEVENWHITE, errortext, 400);
|
||||
C3D_FrameEnd(0);
|
||||
for (int i = 0; i < 60*20; i++) {
|
||||
gspWaitForVBlank();
|
||||
}
|
||||
}
|
||||
u32 RenderD7::Color::Hex(const std::string color, u8 a)
|
||||
{
|
||||
if (color.length() < 7 || std::regex_search(color.substr(1), std::regex("[^0-9A-Fa-f]"))) { // invalid color.
|
||||
return D7_NOTHING;
|
||||
}
|
||||
int r = std::stoi(color.substr(1, 2), nullptr, 16);
|
||||
int g = std::stoi(color.substr(3, 2), nullptr, 16);
|
||||
int b = std::stoi(color.substr(5, 2), nullptr, 16);
|
||||
return RGBA8(r, g, b, a);
|
||||
}
|
||||
|
||||
void RenderD7::Scene::doDraw() {
|
||||
if(!RenderD7::Scene::scenes.empty())
|
||||
RenderD7::Scene::scenes.top()->Draw();
|
||||
}
|
||||
|
||||
void RenderD7::Scene::doLogic(u32 hDown, u32 hHeld, u32 hUp, touchPosition touch) {
|
||||
if(!RenderD7::Scene::scenes.empty())
|
||||
RenderD7::Scene::scenes.top()->Logic(hDown, hHeld, hUp, touch);
|
||||
}
|
||||
|
||||
void RenderD7::Scene::Load(std::unique_ptr<Scene> scene)
|
||||
{
|
||||
Scene::scenes.push(std::move(scene));
|
||||
}
|
||||
|
||||
void RenderD7::Scene::Back() {
|
||||
if(RenderD7::Scene::scenes.size() > 0)
|
||||
RenderD7::Scene::scenes.pop();
|
||||
}
|
||||
|
||||
void RenderD7::OnScreen(C3D_RenderTarget *target)
|
||||
{
|
||||
C2D_SceneBegin(target);
|
||||
}
|
||||
|
||||
bool RenderD7::MainLoop()
|
||||
{
|
||||
if (!aptMainLoop()) return false;
|
||||
hidScanInput();
|
||||
d7_hDown = hidKeysDown();
|
||||
d7_hUp = hidKeysUp();
|
||||
d7_hHeld = hidKeysHeld();
|
||||
hidTouchRead(&d7_touch);
|
||||
|
||||
RenderD7::ClearTextBufs();
|
||||
C3D_FrameBegin(C3D_FRAME_SYNCDRAW);
|
||||
C2D_TargetClear(Top, C2D_Color32(0, 0, 0, 0));
|
||||
C2D_TargetClear(Bottom, C2D_Color32(0, 0, 0, 0));
|
||||
|
||||
return running;
|
||||
}
|
||||
|
||||
|
||||
RenderD7::Sheet::Sheet()
|
||||
{
|
||||
|
||||
}
|
||||
RenderD7::Sheet::~Sheet()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
Result RenderD7::Sheet::Load(const char *path)
|
||||
{
|
||||
this->spritesheet = C2D_SpriteSheetLoad(path);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void RenderD7::Sheet::Free()
|
||||
{
|
||||
C2D_SpriteSheetFree(this->spritesheet);
|
||||
}
|
||||
|
||||
RenderD7::Sprite::Sprite()
|
||||
{
|
||||
|
||||
}
|
||||
RenderD7::Sprite::~Sprite()
|
||||
{
|
||||
|
||||
}
|
||||
void RenderD7::Sprite::FromSheet(RenderD7::Sheet *sheet, size_t index)
|
||||
{
|
||||
C2D_SpriteFromSheet(&this->sprite, sheet->spritesheet, index);
|
||||
}
|
||||
bool RenderD7::Sprite::Draw()
|
||||
{
|
||||
return C2D_DrawSprite(&this->sprite);
|
||||
}
|
||||
void RenderD7::Sprite::SetCenter(float x, float y)
|
||||
{
|
||||
C2D_SpriteSetCenter(&this->sprite, x, y);
|
||||
}
|
||||
void RenderD7::Sprite::SetPos(float x, float y)
|
||||
{
|
||||
C2D_SpriteSetPos(&this->sprite, x, y);
|
||||
}
|
||||
void RenderD7::Sprite::SetRotation(float rotation)
|
||||
{
|
||||
C2D_SpriteSetRotation(&this->sprite, rotation);
|
||||
}
|
||||
void RenderD7::Sprite::Rotate(float speed)
|
||||
{
|
||||
C2D_SpriteRotateDegrees(&this->sprite, speed);
|
||||
}
|
||||
float RenderD7::Sprite::getHeigh()
|
||||
{
|
||||
return this->sprite.params.pos.h;
|
||||
}
|
||||
float RenderD7::Sprite::getWidth()
|
||||
{
|
||||
return this->sprite.params.pos.w;
|
||||
}
|
||||
float RenderD7::Sprite::getPosX()
|
||||
{
|
||||
return this->sprite.params.pos.x;
|
||||
}
|
||||
float RenderD7::Sprite::getPosY()
|
||||
{
|
||||
return this->sprite.params.pos.y;
|
||||
}
|
||||
|
||||
void RenderD7::ClearTextBufs(void)
|
||||
{
|
||||
C2D_TextBufClear(TextBuf);
|
||||
}
|
||||
|
||||
void frameloop()
|
||||
{
|
||||
frames++;
|
||||
u64 delta_time = osGetTime() - last_time;
|
||||
if (delta_time >= 1000) {
|
||||
current_fps = frames/(delta_time/1000.0f)+1;
|
||||
frames = 0;
|
||||
last_time = osGetTime();
|
||||
}
|
||||
d11framerate = current_fps;
|
||||
}
|
||||
float getframerate()
|
||||
{
|
||||
frameloop();
|
||||
return d11framerate;
|
||||
}
|
||||
|
||||
bool RenderD7::DrawRect(float x, float y, float w, float h, u32 color)
|
||||
{
|
||||
return C2D_DrawRectSolid(x, y, 0.5f, w, h, color);
|
||||
}
|
||||
|
||||
void RenderD7::DrawTextCentered(float x, float y, float size, u32 color, std::string Text, int maxWidth, int maxHeight, C2D_Font fnt) {
|
||||
float lineHeight, widthScale;
|
||||
|
||||
// Check for the lineHeight.
|
||||
if (fnt != nullptr) {
|
||||
lineHeight = RenderD7::GetTextHeight(size, " ", fnt);
|
||||
} else {
|
||||
lineHeight = RenderD7::GetTextHeight(size, " ");
|
||||
}
|
||||
|
||||
int line = 0;
|
||||
while(Text.find('\n') != Text.npos) {
|
||||
if (maxWidth == 0) {
|
||||
// Do the widthScale.
|
||||
if (fnt != nullptr) {
|
||||
widthScale = RenderD7::GetTextWidth(size, Text.substr(0, Text.find('\n')), fnt);
|
||||
} else {
|
||||
widthScale = RenderD7::GetTextWidth(size, Text.substr(0, Text.find('\n')));
|
||||
}
|
||||
|
||||
} else {
|
||||
// Do the widthScale 2.
|
||||
if (fnt != nullptr) {
|
||||
widthScale = std::min((float)maxWidth, RenderD7::GetTextWidth(size, Text.substr(0, Text.find('\n')), fnt));
|
||||
} else {
|
||||
widthScale = std::min((float)maxWidth, RenderD7::GetTextWidth(size, Text.substr(0, Text.find('\n'))));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (fnt != nullptr) {
|
||||
RenderD7::DrawText((currentScreen ? 200 : 160)+x-(widthScale/2), y+(lineHeight*line), size, color, Text.substr(0, Text.find('\n')), maxWidth, maxHeight, fnt);
|
||||
} else {
|
||||
RenderD7::DrawText((currentScreen ? 200 : 160)+x-(widthScale/2), y+(lineHeight*line), size, color, Text.substr(0, Text.find('\n')), maxWidth, maxHeight);
|
||||
}
|
||||
|
||||
Text = Text.substr(Text.find('\n')+1);
|
||||
line++;
|
||||
}
|
||||
|
||||
if (maxWidth == 0) {
|
||||
// Do the next WidthScale.
|
||||
if (fnt != nullptr) {
|
||||
widthScale = RenderD7::GetTextWidth(size, Text.substr(0, Text.find('\n')), fnt);
|
||||
} else {
|
||||
widthScale = RenderD7::GetTextWidth(size, Text.substr(0, Text.find('\n')));
|
||||
}
|
||||
|
||||
} else {
|
||||
// And again.
|
||||
if (fnt != nullptr) {
|
||||
widthScale = std::min((float)maxWidth, RenderD7::GetTextWidth(size, Text.substr(0, Text.find('\n')), fnt));
|
||||
} else {
|
||||
widthScale = std::min((float)maxWidth, RenderD7::GetTextWidth(size, Text.substr(0, Text.find('\n'))));
|
||||
}
|
||||
|
||||
}
|
||||
if (fnt != nullptr) {
|
||||
RenderD7::DrawText((currentScreen ? 200 : 160)+x-(widthScale/2), y+(lineHeight*line), size, color, Text.substr(0, Text.find('\n')), maxWidth, maxHeight, fnt);
|
||||
} else {
|
||||
RenderD7::DrawText((currentScreen ? 200 : 160)+x-(widthScale/2), y+(lineHeight*line), size, color, Text.substr(0, Text.find('\n')), maxWidth, maxHeight);
|
||||
}
|
||||
}
|
||||
|
||||
// Draw String or Text.
|
||||
void RenderD7::DrawText(float x, float y, float size, u32 color, std::string Text, int maxWidth, int maxHeight, C2D_Font fnt) {
|
||||
C2D_Text c2d_text;
|
||||
|
||||
if (fnt != nullptr) {
|
||||
C2D_TextFontParse(&c2d_text, fnt, TextBuf, Text.c_str());
|
||||
} else {
|
||||
C2D_TextFontParse(&c2d_text, Font, TextBuf, Text.c_str());
|
||||
}
|
||||
|
||||
C2D_TextOptimize(&c2d_text);
|
||||
|
||||
float heightScale;
|
||||
if (maxHeight == 0) {
|
||||
heightScale = size;
|
||||
} else {
|
||||
|
||||
if (fnt != nullptr) {
|
||||
heightScale = std::min(size, size*(maxHeight/RenderD7::GetTextHeight(size, Text, fnt)));
|
||||
} else {
|
||||
heightScale = std::min(size, size*(maxHeight/RenderD7::GetTextHeight(size, Text)));
|
||||
}
|
||||
}
|
||||
|
||||
if (maxWidth == 0) {
|
||||
C2D_DrawText(&c2d_text, C2D_WithColor, x, y, 0.5f, size, heightScale, color);
|
||||
} else {
|
||||
if (fnt != nullptr) {
|
||||
C2D_DrawText(&c2d_text, C2D_WithColor, x, y, 0.5f, std::min(size, size*(maxWidth/RenderD7::GetTextWidth(size, Text, fnt))), heightScale, color);
|
||||
} else {
|
||||
C2D_DrawText(&c2d_text, C2D_WithColor, x, y, 0.5f, std::min(size, size*(maxWidth/RenderD7::GetTextWidth(size, Text))), heightScale, color);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Get String or Text Width.
|
||||
float RenderD7::GetTextWidth(float size, std::string Text, C2D_Font fnt) {
|
||||
float width = 0;
|
||||
if (fnt != nullptr) {
|
||||
GetTextSize(size, &width, NULL, Text, fnt);
|
||||
} else {
|
||||
GetTextSize(size, &width, NULL, Text);
|
||||
}
|
||||
return width;
|
||||
}
|
||||
|
||||
// Get String or Text Size.
|
||||
void RenderD7::GetTextSize(float size, float *width, float *height, std::string Text, C2D_Font fnt) {
|
||||
C2D_Text c2d_text;
|
||||
if (fnt != nullptr) {
|
||||
C2D_TextFontParse(&c2d_text, fnt, TextBuf, Text.c_str());
|
||||
} else {
|
||||
C2D_TextFontParse(&c2d_text, Font, TextBuf, Text.c_str());
|
||||
}
|
||||
C2D_TextGetDimensions(&c2d_text, size, size, width, height);
|
||||
}
|
||||
|
||||
|
||||
// Get String or Text Height.
|
||||
float RenderD7::GetTextHeight(float size, std::string Text, C2D_Font fnt) {
|
||||
float height = 0;
|
||||
if (fnt != nullptr) {
|
||||
GetTextSize(size, NULL, &height, Text.c_str(), fnt);
|
||||
} else {
|
||||
GetTextSize(size, NULL, &height, Text.c_str());
|
||||
}
|
||||
return height;
|
||||
}
|
||||
|
||||
Result RenderD7::loadFont(C2D_Font &fnt, const char* Path) {
|
||||
fnt = C2D_FontLoad(Path); // Only load if found.
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Unload a Font.
|
||||
Result RenderD7::unloadFont(C2D_Font &fnt) {
|
||||
if (fnt != nullptr) {
|
||||
C2D_FontFree(fnt); // Make sure to only unload if not nullptr.
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool RenderD7::DrawCircle(float x, float y, float radius, u32 color)
|
||||
{
|
||||
return C2D_DrawCircleSolid(x, y, 0.5f, radius, color);
|
||||
}
|
||||
|
||||
Result RenderD7::Init::Main()
|
||||
{
|
||||
gfxInitDefault();
|
||||
aptInit();
|
||||
romfsInit();
|
||||
cfguInit();
|
||||
osSetSpeedupEnable(true);
|
||||
C3D_Init(C3D_DEFAULT_CMDBUF_SIZE);
|
||||
C2D_Init(C2D_DEFAULT_MAX_OBJECTS);
|
||||
C2D_Prepare();
|
||||
Top = C2D_CreateScreenTarget(GFX_TOP, GFX_LEFT);
|
||||
TopRight = C2D_CreateScreenTarget(GFX_TOP, GFX_RIGHT);
|
||||
Bottom = C2D_CreateScreenTarget(GFX_BOTTOM, GFX_LEFT);
|
||||
TextBuf = C2D_TextBufNew(4096);
|
||||
Font = C2D_FontLoadSystem(CFG_REGION_USA);
|
||||
return 0;
|
||||
|
||||
}
|
||||
void RenderD7::Exit::Main()
|
||||
{
|
||||
C2D_TextBufDelete(TextBuf);
|
||||
C2D_Fini();
|
||||
C3D_Fini();
|
||||
aptExit();
|
||||
romfsExit();
|
||||
cfguExit();
|
||||
}
|
||||
|
||||
std::string RenderD7::GetFramerate()
|
||||
{
|
||||
frameloop();
|
||||
return (std::to_string(d11framerate).substr(0, 2));
|
||||
}
|
||||
|
||||
void RenderD7::DrawTObjects(std::vector<RenderD7::TObject> tobjects, u32 color, u32 txtcolor, int selection, u32 selbgcolor, u32 selcolor)
|
||||
{
|
||||
for(int i = 0; i < (int)tobjects.size(); i++)
|
||||
{
|
||||
if (selection == i)
|
||||
{
|
||||
RenderD7::DrawRect(tobjects[i].x - 2, tobjects[i].y - 2, tobjects[i].w + 4, tobjects[i].h + 4, selbgcolor);
|
||||
RenderD7::DrawRect(tobjects[i].x, tobjects[i].y, tobjects[i].w, tobjects[i].h, color);
|
||||
RenderD7::DrawRect(tobjects[i].x, tobjects[i].y, tobjects[i].w, tobjects[i].h, selcolor);
|
||||
RenderD7::DrawText(tobjects[i].x + (tobjects[i].w/2) - RenderD7::GetTextHeight(tobjects[i].txtsize , tobjects[i].text) + tobjects[i].correctx, tobjects[i].y + (tobjects[i].h/2) - RenderD7::GetTextHeight(tobjects[i].txtsize, tobjects[i].text) + tobjects[i].correcty, tobjects[i].txtsize, txtcolor, tobjects[i].text);
|
||||
}
|
||||
else
|
||||
{
|
||||
RenderD7::DrawRect(tobjects[i].x, tobjects[i].y - 1, tobjects[i].w, tobjects[i].h, color);
|
||||
RenderD7::DrawText(tobjects[i].x + (tobjects[i].w/2) - RenderD7::GetTextHeight(tobjects[i].txtsize , tobjects[i].text) + tobjects[i].correctx, tobjects[i].y + (tobjects[i].h/2) - RenderD7::GetTextHeight(tobjects[i].txtsize, tobjects[i].text) + tobjects[i].correcty, tobjects[i].txtsize, txtcolor, tobjects[i].text);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
void RenderD7::ExitApp()
|
||||
{
|
||||
running = false;
|
||||
}
|
||||
|
||||
bool RenderD7::touchTObj(touchPosition touch, RenderD7::TObject button)
|
||||
{
|
||||
if (touch.px >= button.x && touch.px <= (button.x + button.w) && touch.py >= button.y && touch.py <= (button.y + button.h)) return true;
|
||||
else return false;
|
||||
}
|
||||
|
||||
void RenderD7::DrawSTObject(std::vector<RenderD7::TObject> tobject, int tobjectindex, u32 color, u32 txtcolor)
|
||||
{
|
||||
RenderD7::DrawRect(tobject[tobjectindex].x, tobject[tobjectindex].y, tobject[tobjectindex].w, tobject[tobjectindex].h, color);
|
||||
RenderD7::DrawText(tobject[tobjectindex].x + (tobject[tobjectindex].w/2) - RenderD7::GetTextHeight(tobject[tobjectindex].txtsize , tobject[tobjectindex].text) + tobject[tobjectindex].correctx, tobject[tobjectindex].y + (tobject[tobjectindex].h/2) - RenderD7::GetTextHeight(tobject[tobjectindex].txtsize, tobject[tobjectindex].text) + tobject[tobjectindex].correcty, tobject[tobjectindex].txtsize, txtcolor, tobject[tobjectindex].text);
|
||||
}
|
||||
|
||||
bool RenderD7::NameIsEndingWith(const std::string &name, const std::vector<std::string> &extensions) {
|
||||
if (name.substr(0, 2) == "._") return false;
|
||||
|
||||
if (name.size() == 0) return false;
|
||||
|
||||
if (extensions.size() == 0) return true;
|
||||
|
||||
for(int i = 0; i < (int)extensions.size(); i++) {
|
||||
const std::string ext = extensions.at(i);
|
||||
if (strcasecmp(name.c_str() + name.size() - ext.size(), ext.c_str()) == 0) return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool dirEntryPredicate(const RenderD7::DirContent &lhs, const RenderD7::DirContent &rhs) {
|
||||
if (!lhs.isDir && rhs.isDir) return false;
|
||||
if (lhs.isDir && !rhs.isDir) return true;
|
||||
|
||||
return strcasecmp(lhs.name.c_str(), rhs.name.c_str()) < 0;
|
||||
}
|
||||
|
||||
void RenderD7::GetDirContentsExt(std::vector<RenderD7::DirContent> &dircontent, const std::vector<std::string> &extensions) {
|
||||
struct stat st;
|
||||
|
||||
dircontent.clear();
|
||||
|
||||
DIR *pdir = opendir(".");
|
||||
|
||||
if (pdir != nullptr) {
|
||||
while(true) {
|
||||
RenderD7::DirContent dirEntry;
|
||||
|
||||
struct dirent *pent = readdir(pdir);
|
||||
if (pent == NULL) break;
|
||||
|
||||
stat(pent->d_name, &st);
|
||||
dirEntry.name = pent->d_name;
|
||||
dirEntry.isDir = (st.st_mode & S_IFDIR) ? true : false;
|
||||
|
||||
if (dirEntry.name.compare(".") != 0 && (dirEntry.isDir || RenderD7::NameIsEndingWith(dirEntry.name, extensions))) {
|
||||
dircontent.push_back(dirEntry);
|
||||
}
|
||||
}
|
||||
|
||||
closedir(pdir);
|
||||
}
|
||||
|
||||
sort(dircontent.begin(), dircontent.end(), dirEntryPredicate);
|
||||
}
|
||||
|
||||
void RenderD7::GetDirContents(std::vector<RenderD7::DirContent> &dircontent) {
|
||||
RenderD7::GetDirContentsExt(dircontent, {});
|
||||
}
|
158
renderd7.hpp
Normal file
158
renderd7.hpp
Normal file
@ -0,0 +1,158 @@
|
||||
#include <3ds.h>
|
||||
#include <citro2d.h>
|
||||
#include <citro3d.h>
|
||||
#include <memory>
|
||||
#include <stack>
|
||||
#include <string>
|
||||
#include <functional>
|
||||
#include <vector>
|
||||
#include <dirent.h>
|
||||
#include <unistd.h>
|
||||
#include <stdio.h>
|
||||
#include <cstring>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#define DEFAULT_CENTER 0.5f
|
||||
|
||||
extern C3D_RenderTarget* Top;
|
||||
extern C3D_RenderTarget* TopRight;
|
||||
extern C3D_RenderTarget* Bottom;
|
||||
|
||||
extern u32 d7_hDown;
|
||||
extern u32 d7_hHeld;
|
||||
extern u32 d7_hUp;
|
||||
extern touchPosition d7_touch;
|
||||
|
||||
namespace RenderD7
|
||||
{
|
||||
void OnScreen(C3D_RenderTarget *target);
|
||||
class Sheet
|
||||
{
|
||||
public:
|
||||
Sheet();
|
||||
~Sheet();
|
||||
Result Load(const char *path);
|
||||
void Free();
|
||||
C2D_SpriteSheet spritesheet;
|
||||
|
||||
};
|
||||
class Sprite
|
||||
{
|
||||
public:
|
||||
Sprite();
|
||||
~Sprite();
|
||||
void FromSheet(RenderD7::Sheet *sheet, size_t index);
|
||||
bool Draw();
|
||||
void SetCenter(float x, float y);
|
||||
void SetPos(float x, float y);
|
||||
void SetRotation(float rotation);
|
||||
void Rotate(float speed);
|
||||
float getWidth();
|
||||
float getHeigh();
|
||||
float getPosX();
|
||||
float getPosY();
|
||||
private:
|
||||
C2D_ImageTint tint;
|
||||
C2D_Sprite sprite;
|
||||
};
|
||||
class Scene {
|
||||
public:
|
||||
static std::stack<std::unique_ptr<Scene>> scenes;
|
||||
virtual ~Scene() {}
|
||||
virtual void Logic(u32 hDown, u32 hHeld, u32 hUp, touchPosition touch) = 0;
|
||||
virtual void Draw() const = 0;
|
||||
static void Load(std::unique_ptr<Scene> scene);
|
||||
static void Back();
|
||||
static void doDraw();
|
||||
static void doLogic(u32 hDown, u32 hHeld, u32 hUp, touchPosition touch);
|
||||
|
||||
};
|
||||
namespace Color
|
||||
{
|
||||
u32 Hex(const std::string color, u8 a = 255);
|
||||
}
|
||||
bool DrawImageFromSheet(RenderD7::Sheet* sheet, size_t index, float x, float y, float scaleX = 1.0, float scaleY = 1.0);
|
||||
namespace Error
|
||||
{
|
||||
void DisplayError(std::string toptext, std::string errortext);
|
||||
void DisplayFatalError(std::string toptext, std::string errortext);
|
||||
}
|
||||
namespace Init
|
||||
{
|
||||
Result Main();
|
||||
void NdspFirm(bool useit = false);
|
||||
}
|
||||
namespace Exit
|
||||
{
|
||||
void Main();
|
||||
void NdspFirm();
|
||||
}
|
||||
namespace Msg
|
||||
{
|
||||
void Display(std::string titletxt, std::string, C3D_RenderTarget *target);
|
||||
}
|
||||
|
||||
|
||||
void SetupLog(void);
|
||||
std::string GetFramerate();
|
||||
bool MainLoop();
|
||||
void ExitApp();
|
||||
|
||||
void ClearTextBufs(void);
|
||||
|
||||
bool DrawRect(float x, float y, float w, float h, u32 color);
|
||||
void DrawTextCentered(float x, float y, float size, u32 color, std::string Text, int maxWidth = 0, int maxHeight = 0, C2D_Font fnt = nullptr);
|
||||
void DrawText(float x, float y, float size, u32 color, std::string Text, int maxWidth = 0, int maxHeight = 0, C2D_Font fnt = nullptr);
|
||||
float GetTextWidth(float size, std::string Text, C2D_Font fnt = nullptr);
|
||||
void GetTextSize(float size, float *width, float *height, std::string Text, C2D_Font fnt = nullptr);
|
||||
float GetTextHeight(float size, std::string Text, C2D_Font fnt = nullptr);
|
||||
Result loadFont(C2D_Font &fnt, const char * Path = "");
|
||||
Result unloadFont(C2D_Font &fnt);
|
||||
bool DrawCircle(float x, float y, float radius, u32 color);
|
||||
|
||||
|
||||
class SpriteSheetAnimation : public RenderD7::Sprite
|
||||
{
|
||||
|
||||
public:
|
||||
SpriteSheetAnimation();
|
||||
~SpriteSheetAnimation();
|
||||
void Setup(RenderD7::Sheet *sheet, size_t imagecount, size_t startimage, float frame_begin, float frame_finish);
|
||||
void Play(float timespeed);
|
||||
private:
|
||||
size_t images;
|
||||
size_t imgs = 0;
|
||||
float D_totaltime;
|
||||
RenderD7::Sheet *sheet;
|
||||
float time;
|
||||
|
||||
};
|
||||
struct TObject
|
||||
{
|
||||
int x;
|
||||
int y;
|
||||
int w;
|
||||
int h;
|
||||
std::string text = "";
|
||||
float correctx = 0;
|
||||
float correcty = 0;
|
||||
float txtsize = 0.7f;
|
||||
|
||||
};
|
||||
void DrawTObjects(std::vector<RenderD7::TObject> tobjects, u32 color, u32 txtcolor, int selection = -1, u32 selbgcolor = RenderD7::Color::Hex("#2D98AF"), u32 selcolor = RenderD7::Color::Hex("#000000"));
|
||||
void DrawSTObject(std::vector<RenderD7::TObject> tobject, int tobjectindex, u32 color, u32 txtcolor);
|
||||
bool touchTObj(touchPosition touch, RenderD7::TObject button);
|
||||
|
||||
struct DirContent
|
||||
{
|
||||
std::string name;
|
||||
std::string path;
|
||||
bool isDir;
|
||||
};
|
||||
|
||||
bool NameIsEndingWith(const std::string &name, const std::vector<std::string> &extensions);
|
||||
void GetDirContentsExt(std::vector<RenderD7::DirContent> &dircontent, const std::vector<std::string> &extensions);
|
||||
void GetDirContents(std::vector<RenderD7::DirContent> &dircontent);
|
||||
|
||||
|
||||
}
|
125
sound.cpp
Normal file
125
sound.cpp
Normal file
@ -0,0 +1,125 @@
|
||||
#include "sound.hpp"
|
||||
|
||||
#include <cstdio>
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
#include <string>
|
||||
|
||||
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) {
|
||||
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() {
|
||||
waveBuf.data_vaddr = 0;
|
||||
waveBuf.nsamples = 0;
|
||||
waveBuf.looping = false;
|
||||
waveBuf.status = 0;
|
||||
ndspChnWaveBufClear(chnl);
|
||||
|
||||
if (data) {
|
||||
linearFree(data);
|
||||
}
|
||||
}
|
||||
|
||||
void sound::play() {
|
||||
if (!data) return;
|
||||
DSP_FlushDataCache(data, dataSize);
|
||||
ndspChnWaveBufAdd(chnl, &waveBuf);
|
||||
}
|
||||
|
||||
void sound::stop() {
|
||||
if (!data) return;
|
||||
ndspChnWaveBufClear(chnl);
|
||||
}
|
21
sound.hpp
Normal file
21
sound.hpp
Normal file
@ -0,0 +1,21 @@
|
||||
#ifndef _UNIVERSAL_UPDATER_SOUND_H
|
||||
#define _UNIVERSAL_UPDATER_SOUND_H
|
||||
|
||||
#include <3ds.h>
|
||||
#include <string>
|
||||
|
||||
class sound {
|
||||
public:
|
||||
sound(const std::string& path, int channel = 1, bool toloop = false);
|
||||
~sound();
|
||||
void play();
|
||||
void stop();
|
||||
|
||||
private:
|
||||
u32 dataSize;
|
||||
ndspWaveBuf waveBuf;
|
||||
u8* data = NULL;
|
||||
int chnl;
|
||||
};
|
||||
|
||||
#endif
|
Loading…
Reference in New Issue
Block a user