diff --git a/Makefile b/Makefile index f115e80..b09cae9 100644 --- a/Makefile +++ b/Makefile @@ -42,7 +42,7 @@ LIBRARY_DIRS := $(PORTLIBS) $(CTRULIB) LIBRARIES := citro3d ctru png z m VERSION_MAJOR := 2 -VERSION_MINOR := 12 +VERSION_MINOR := 13 VERSION_MICRO := 0 diff --git a/source/appInfo.c b/source/appInfo.c index 2a0ee53..54cfdb4 100644 --- a/source/appInfo.c +++ b/source/appInfo.c @@ -1,10 +1,12 @@ #include "appInfo.h" +#include "graphics.h" -static bool autoUpdate = true; +static bool autoUpdate = false; static bool showBackground = true; +extern appInfoObject_t *appTop; void appInfoDisableAutoUpdate(void) -{ +{ autoUpdate = false; } @@ -58,6 +60,7 @@ void deleteAppInfoObject(appInfoObject_t *object) void appInfoSetTextBoundaries(appInfoObject_t *object, float posX, float posY) { + if (!object) return; object->boundX = posX; object->boundY = posY; @@ -167,6 +170,56 @@ void clearAppInfo(appInfoObject_t *object, bool updateScreen) updateUI(); } +void drawMultilineText(u32 color, u32 flags, char* txt) { + float textWidth; + float totalWidth = appTop->boundX - appTop->cursor.posX; + float scaleX, scaleY; + //Set the font size + if (flags & BIG) scaleX = scaleY = 0.6f; + else if (flags & MEDIUM) scaleX = scaleY = 0.55f; + else if (flags & SMALL) scaleX = scaleY = 0.45f; + else if (flags & TINY) scaleX = scaleY = 0.4f; + else scaleX = scaleY = 0.5f; + + int textLen = strlen(txt) + 1; + char* copy = malloc(textLen); + char* copyCurr = copy; + memset(copy, 0, textLen); + char* breakpos = copy; + char* txtCurr = txt; + while (*txtCurr != '\0') { + *copyCurr = *txtCurr; + if (*copyCurr == ' ') breakpos = copyCurr; + getTextSizeInfos(&textWidth, scaleX, scaleY, copy); + if (textWidth >= totalWidth) { + if (breakpos == copy) { + *(copyCurr - 1) = '\0'; + newAppTop(color, flags, copy); + memset(copy, 0, textLen); + copyCurr = copy; + breakpos = copy; + txtCurr--; + } + else { + *breakpos = '\0'; + newAppTop(color, flags, copy); + memset(copy, 0, textLen); + txtCurr = (txtCurr - (copyCurr - breakpos)) + 1; + copyCurr = copy; + breakpos = copy; + } + } + else { + copyCurr++; + txtCurr++; + } + } + if (copy != copyCurr) { + newAppTop(color, flags, copy); + } + free(copy); +} + static void getDrawParameters(appInfoObject_t *object, int index, float *sizeX, float *sizeY) { appInfoEntry_t *entry; @@ -213,7 +266,7 @@ static void getDrawParameters(appInfoObject_t *object, int index, float *sizeX, } if (flags & NEWLINE) - cursor->posY += 0.3f * fontGetInfo()->lineFeed; + cursor->posY += 0.3f * fontGetInfo(NULL)->lineFeed; //Return the size *sizeX = scaleX; @@ -232,12 +285,12 @@ void drawAppInfoEntry(appInfoObject_t *object, int index) cursor = &object->cursor; sizeX = sizeY = 0.0f; getDrawParameters(object, index, &sizeX, &sizeY); - lineFeed = sizeY * fontGetInfo()->lineFeed; + lineFeed = sizeY * fontGetInfo(NULL)->lineFeed; setTextColor(entry->color); renderText(cursor->posX, cursor->posY, sizeX, sizeY, false, entry->buffer, cursor); cursor->posY += lineFeed; exit: - return; + return; } void drawAppInfo(appInfoObject_t *object) diff --git a/source/draw.c b/source/draw.c index 7bb202e..9d096f6 100644 --- a/source/draw.c +++ b/source/draw.c @@ -29,14 +29,14 @@ unsigned int nextPow2(unsigned int v) return (v >= TEX_MIN_SIZE ? v : TEX_MIN_SIZE); } -static void addTextVertex(float vx, float vy, float tx, float ty) +static void addTextVertex(float vx, float vy, float vz, float tx, float ty) { textVertex_s *vtx; vtx = &textVtxArray[textVtxArrayPos++]; vtx->position[0] = vx; vtx->position[1] = vy; - vtx->position[2] = 0.5f; + vtx->position[2] = 0.0f; vtx->texcoord[0] = tx; vtx->texcoord[1] = ty; } @@ -52,15 +52,69 @@ void printVertex(textVertex_s *vtx) ); } -static void bindTexture(C3D_Tex *texture) -{ - C3D_TexEnv *env; +static void resetC3Denv() { + C3D_TexEnv *env; + for (int i = 0; i < 4; i++) { + env = C3D_GetTexEnv(i); + C3D_TexEnvInit(env); + } +} - C3D_TexBind(0, texture); - env = C3D_GetTexEnv(0); - C3D_TexEnvSrc(env, C3D_Both, GPU_TEXTURE0, 0, 0); - C3D_TexEnvOp(env, C3D_Both, 0, 0, 0); - C3D_TexEnvFunc(env, C3D_Both, GPU_REPLACE); +static void bindImageGreyScale(C3D_Tex *texture, u32 texture_color) { + //((0.3 * R) + (0.59 * G) + (0.11 * B)). -> 0xFF1C964C + C3D_TexEnv *env; + u32 greyMask = 0xFF1C964C; + resetC3Denv(); + + C3D_TexBind(0, texture); + env = C3D_GetTexEnv(0); + C3D_TexEnvSrc(env, C3D_RGB, GPU_TEXTURE0, GPU_CONSTANT, 0); + C3D_TexEnvSrc(env, C3D_Alpha, GPU_TEXTURE0, 0, 0); + C3D_TexEnvOpRgb(env, 0, 0, 0); + C3D_TexEnvOpAlpha(env, 0, 0, 0); + C3D_TexEnvFunc(env, C3D_RGB, GPU_MODULATE); + C3D_TexEnvFunc(env, C3D_Alpha, GPU_REPLACE); + C3D_TexEnvColor(env, texture_color); + env = C3D_GetTexEnv(1); + C3D_TexEnvSrc(env, C3D_RGB, GPU_PREVIOUS, GPU_CONSTANT, 0); + C3D_TexEnvSrc(env, C3D_Alpha, GPU_PREVIOUS, 0, 0); + C3D_TexEnvOpRgb(env, 0, 0, 0); + C3D_TexEnvOpAlpha(env, 0, 0, 0); + C3D_TexEnvFunc(env, C3D_RGB, GPU_MODULATE); + C3D_TexEnvFunc(env, C3D_Alpha, GPU_REPLACE); + C3D_TexEnvColor(env, greyMask); + C3D_TexEnvBufUpdate(C3D_RGB, 0b0010); + env = C3D_GetTexEnv(2); + C3D_TexEnvSrc(env, C3D_RGB, GPU_PREVIOUS, GPU_PREVIOUS, 0); + C3D_TexEnvSrc(env, C3D_Alpha, GPU_PREVIOUS, 0, 0); + C3D_TexEnvOpRgb(env, GPU_TEVOP_RGB_SRC_R, GPU_TEVOP_RGB_SRC_G, 0); + C3D_TexEnvOpAlpha(env, 0, 0, 0); + C3D_TexEnvFunc(env, C3D_RGB, GPU_ADD); + C3D_TexEnvFunc(env, C3D_Alpha, GPU_REPLACE); + env = C3D_GetTexEnv(3); + C3D_TexEnvSrc(env, C3D_RGB, GPU_PREVIOUS, GPU_PREVIOUS_BUFFER, 0); + C3D_TexEnvSrc(env, C3D_Alpha, GPU_PREVIOUS, 0, 0); + C3D_TexEnvOpRgb(env, 0, GPU_TEVOP_RGB_SRC_B, 0); + C3D_TexEnvOpAlpha(env, 0, 0, 0); + C3D_TexEnvFunc(env, C3D_RGB, GPU_ADD); + C3D_TexEnvFunc(env, C3D_Alpha, GPU_REPLACE); +} + +static void bindTexture(C3D_Tex *texture, u32 texture_color) +{ + C3D_TexEnv *env; + resetC3Denv(); + + C3D_TexBind(0, texture); + env = C3D_GetTexEnv(0); + C3D_TexEnvBufUpdate(C3D_RGB, 0); + C3D_TexEnvSrc(env, C3D_RGB, GPU_TEXTURE0, GPU_CONSTANT, 0); + C3D_TexEnvSrc(env, C3D_Alpha, GPU_TEXTURE0, 0, 0); + C3D_TexEnvOpRgb(env, 0, 0, 0); + C3D_TexEnvOpAlpha(env, 0, 0, 0); + C3D_TexEnvFunc(env, C3D_RGB, GPU_MODULATE); + C3D_TexEnvFunc(env, C3D_Alpha, GPU_REPLACE); + C3D_TexEnvColor(env, texture_color); } void setSpritePos(sprite_t *sprite, float posX, float posY) @@ -81,7 +135,7 @@ void drawSprite(sprite_t *sprite) int arrayIndex; C3D_Tex *texture; - if (!sprite) return; + if (!sprite || sprite->isHidden) return; texture = &sprite->texture; height = sprite->height; width = sprite->width; @@ -90,22 +144,71 @@ void drawSprite(sprite_t *sprite) u = width / (float)texture->width; v = height / (float)texture->height; - //Bind the sprite's texture - bindTexture(texture); + width = floor(width * sprite->amount); + u *= sprite->amount; + C3D_BufInfo *bufInfo = C3D_GetBufInfo(); BufInfo_Init(bufInfo); BufInfo_Add(bufInfo, textVtxArray, sizeof(textVertex_s), 2, 0x10); //Set the vertices arrayIndex = textVtxArrayPos; - addTextVertex(x, y + height, 0.0f, v); //left bottom - addTextVertex(x + width, y + height, u, v); //right bottom - addTextVertex(x, y, 0.0f, 0.0f); //left top - addTextVertex(x + width, y, u, 0.0f); //right top + addTextVertex(x, y + height, sprite->depth, 0.0f, v); //left bottom + addTextVertex(x + width, y + height, sprite->depth, u, v); //right bottom + addTextVertex(x, y, sprite->depth, 0.0f, 0.0f); //left top + addTextVertex(x + width, y, sprite->depth, u, 0.0f); //right top + + //Bind the sprite's texture + if (sprite->isGreyedOut) { + bindImageGreyScale(texture, sprite->drawColor); + } + else { + bindTexture(texture, sprite->drawColor); + } //Draw C3D_DrawArrays(GPU_TRIANGLE_STRIP, arrayIndex, 4); } +void drawRectangle(rectangle_t *rectangle) +{ + float height; + float width; + float x; + float y; + int arrayIndex; + C3D_TexEnv *env; + + if (!rectangle) return; + height = rectangle->height; + width = ceil(rectangle->width * rectangle->amount); + x = rectangle->posX; + y = rectangle->posY; + + C3D_BufInfo *bufInfo = C3D_GetBufInfo(); + BufInfo_Init(bufInfo); + BufInfo_Add(bufInfo, textVtxArray, sizeof(textVertex_s), 2, 0x10); + //Set the vertices + arrayIndex = textVtxArrayPos; + addTextVertex(x, y + height, rectangle->depth, 0.0f, 1.f); //left bottom + addTextVertex(x + width, y + height, rectangle->depth, 1.f, 1.f); //right bottom + addTextVertex(x, y, rectangle->depth, 0.0f, 0.0f); //left top + addTextVertex(x + width, y, rectangle->depth, 1.f, 0.0f); //right top + + resetC3Denv(); + env = C3D_GetTexEnv(0); + C3D_TexBind(0, &(rectangle->sprite->texture)); + C3D_TexEnvBufUpdate(C3D_RGB, 0); + C3D_TexEnvSrc(env, C3D_RGB, GPU_TEXTURE0, 0, 0); + C3D_TexEnvSrc(env, C3D_Alpha, GPU_CONSTANT, 0, 0); + C3D_TexEnvOpRgb(env, 0, 0, 0); + C3D_TexEnvOpAlpha(env, 0, 0, 0); + C3D_TexEnvFunc(env, C3D_Both, GPU_REPLACE); + C3D_TexEnvColor(env, 0xFFFFFFFF); + + //Draw + C3D_DrawArrays(GPU_TRIANGLE_STRIP, arrayIndex, 4); +} + sprite_t *newSprite(int width, int height) { sprite_t *sprite; @@ -126,6 +229,11 @@ sprite_t *newSprite(int width, int height) sprite->width = (float)width; sprite->height = (float)height; + sprite->drawColor = 0xFFFFFFFF; + sprite->isGreyedOut = false; + sprite->isHidden = false; + sprite->depth = 0.0f; + sprite->amount = 1.f; return (sprite); texInitError: free(sprite); @@ -171,12 +279,12 @@ static void sceneInit(void) C3D_DepthTest(true, GPU_GEQUAL, GPU_WRITE_ALL); // Load the glyph texture sheets - glyphInfo = fontGetGlyphInfo(); + glyphInfo = fontGetGlyphInfo(NULL); glyphSheets = malloc(sizeof(C3D_Tex) * glyphInfo->nSheets); for (i = 0; i < glyphInfo->nSheets; i++) { tex = &glyphSheets[i]; - tex->data = fontGetGlyphSheetTex(i); + tex->data = fontGetGlyphSheetTex(NULL, i); tex->fmt = glyphInfo->sheetFmt; tex->size = glyphInfo->sheetSize; tex->width = glyphInfo->sheetWidth; @@ -207,13 +315,13 @@ void drawInit(void) // Initialize the top render target target = C3D_RenderTargetCreate(240, 400, GPU_RB_RGBA8, GPU_RB_DEPTH24_STENCIL8); - C3D_RenderTargetSetClear(target, C3D_CLEAR_ALL, CLEAR_COLOR, 0); + C3D_RenderTargetClear(target, C3D_CLEAR_ALL, CLEAR_COLOR, 0); C3D_RenderTargetSetOutput(target, GFX_TOP, GFX_LEFT, DISPLAY_TRANSFER_FLAGS); top.target = target; // Initialize the bottom render target target = C3D_RenderTargetCreate(240, 320, GPU_RB_RGBA8, GPU_RB_DEPTH24_STENCIL8); - C3D_RenderTargetSetClear(target, C3D_CLEAR_ALL, CLEAR_COLOR, 0); + C3D_RenderTargetClear(target, C3D_CLEAR_ALL, CLEAR_COLOR, 0); C3D_RenderTargetSetOutput(target, GFX_BOTTOM, GFX_LEFT, DISPLAY_TRANSFER_FLAGS); bottom.target = target; @@ -235,7 +343,6 @@ void drawEndFrame(void) void drawExit(void) { - drawEndFrame(); sceneExit(); C3D_Fini(); } @@ -248,7 +355,8 @@ void setTextColor(u32 color) env = C3D_GetTexEnv(0); C3D_TexEnvSrc(env, C3D_RGB, GPU_CONSTANT, 0, 0); C3D_TexEnvSrc(env, C3D_Alpha, GPU_TEXTURE0, GPU_CONSTANT, 0); - C3D_TexEnvOp(env, C3D_Both, 0, 0, 0); + C3D_TexEnvOpRgb(env, 0, 0, 0); + C3D_TexEnvOpAlpha(env, 0, 0, 0); C3D_TexEnvFunc(env, C3D_RGB, GPU_REPLACE); C3D_TexEnvFunc(env, C3D_Alpha, GPU_MODULATE); C3D_TexEnvColor(env, color); @@ -276,8 +384,8 @@ void getTextSizeInfos(float *width, float scaleX, float scaleY, const char *text c += units; if (code > 0) { - glyphIndex = fontGlyphIndexFromCodePoint(code); - fontCalcGlyphPos(&data, glyphIndex, GLYPH_POS_CALC_VTXCOORD, scaleX, scaleY); + glyphIndex = fontGlyphIndexFromCodePoint(NULL, code); + fontCalcGlyphPos(&data, NULL, glyphIndex, GLYPH_POS_CALC_VTXCOORD, scaleX, scaleY); w += data.xAdvance; } } while (code > 0); @@ -309,8 +417,10 @@ void findBestSize(float *sizeX, float *sizeY, float posXMin, float posXMax, f if (sizeY) *sizeY = scale; } + void renderText(float x, float y, float scaleX, float scaleY, bool baseline, const char *text, cursor_t *cursor) { + float depth = 0; u32 flags; u32 code; int lastSheet; @@ -340,12 +450,12 @@ void renderText(float x, float y, float scaleX, float scaleY, bool baseline, con if (code == '\n') { x = firstX; - y += scaleY * fontGetInfo()->lineFeed; + y += scaleY * fontGetInfo(NULL)->lineFeed; } else if (code > 0) { - glyphIdx = fontGlyphIndexFromCodePoint(code); - fontCalcGlyphPos(&data, glyphIdx, flags, scaleX, scaleY); + glyphIdx = fontGlyphIndexFromCodePoint(NULL, code); + fontCalcGlyphPos(&data, NULL, glyphIdx, flags, scaleX, scaleY); // Bind the correct texture sheet if (data.sheetIndex != lastSheet) @@ -359,10 +469,10 @@ void renderText(float x, float y, float scaleX, float scaleY, bool baseline, con break; // We can't render more characters // Add the vertices to the array - addTextVertex(x + data.vtxcoord.left, y + data.vtxcoord.bottom, data.texcoord.left, data.texcoord.bottom); - addTextVertex(x + data.vtxcoord.right, y + data.vtxcoord.bottom, data.texcoord.right, data.texcoord.bottom); - addTextVertex(x + data.vtxcoord.left, y + data.vtxcoord.top, data.texcoord.left, data.texcoord.top); - addTextVertex(x + data.vtxcoord.right, y + data.vtxcoord.top, data.texcoord.right, data.texcoord.top); + addTextVertex(x + data.vtxcoord.left, y + data.vtxcoord.bottom, depth, data.texcoord.left, data.texcoord.bottom); + addTextVertex(x + data.vtxcoord.right, y + data.vtxcoord.bottom, depth, data.texcoord.right, data.texcoord.bottom); + addTextVertex(x + data.vtxcoord.left, y + data.vtxcoord.top, depth, data.texcoord.left, data.texcoord.top); + addTextVertex(x + data.vtxcoord.right, y + data.vtxcoord.top, depth, data.texcoord.right, data.texcoord.top); // Draw the glyph C3D_DrawArrays(GPU_TRIANGLE_STRIP, arrayIndex, 4); diff --git a/source/draw.h b/source/draw.h index 809a66a..050012f 100644 --- a/source/draw.h +++ b/source/draw.h @@ -8,6 +8,36 @@ #include <3ds.h> #include +typedef struct sprite_s +{ + C3D_Tex texture; + float posX; + float posY; + float height; + float width; + u32 drawColor; + bool isGreyedOut; + bool isHidden; + float depth; + float amount; // from 0 to 1 +} sprite_t; + +typedef struct rectangle_s +{ + /* herited from drawableObject_t */ + bool(*draw)(void *self); + + float posX; + float posY; + float width; + float height; + sprite_t* sprite; + float amount; //Range from 0 to 1 + float depth; +} rectangle_t; + +#include "drawableObject.h" + // These headers are generated by the build process #include "vshader_shbin.h" @@ -48,14 +78,6 @@ typedef struct float posY; } cursor_t; -typedef struct sprite_s -{ - C3D_Tex texture; - float posX; - float posY; - float height; - float width; -} sprite_t; typedef u32 screenPos_t; @@ -75,10 +97,15 @@ Result newSpriteFromPNG(sprite_t **out, const char *filename); void deleteSprite(sprite_t *sprite); void setSpritePos(sprite_t *sprite, float posX, float posY); void drawSprite(sprite_t *sprite); +void drawRectangle(rectangle_t *rect); #define COLOR_BLUE 0xFFFF0000 #define COLOR_RED 0xFF0000FF #define COLOR_GREEN 0xFF00FF00 +#define COLOR_YELLOW 0xFF00FFFF +#define COLOR_CYAN 0xFFFFFF00 +#define COLOR_PURPLE 0xFF800080 +#define COLOR_FUCHSIA 0xFFFF00FF #define COLOR_BLANK 0xFFFFFFFF #define COLOR_BLACK 0xFF000000 #define COLOR_GREY 0xFF989898 diff --git a/source/firmware.c b/source/firmware.c index 1af45a0..1f908d7 100644 --- a/source/firmware.c +++ b/source/firmware.c @@ -100,7 +100,7 @@ Result bnInitParamsByFirmware(void) bnConfig->FSPatchAddr = 0x0010F024; bnConfig->SMPatchAddr = 0x0010189C; } - else if (kernelVersion == SYSTEM_VERSION(2, 54, 0) || kernelVersion == SYSTEM_VERSION(2, 55, 0)) + else if (kernelVersion == SYSTEM_VERSION(2, 54, 0) || kernelVersion == SYSTEM_VERSION(2, 55, 0) || kernelVersion == SYSTEM_VERSION(2, 56, 0)) { // old3ds 11.4.0 and 11.8 if (kernelVersion == SYSTEM_VERSION(2, 54, 0)) @@ -233,7 +233,7 @@ Result bnInitParamsByFirmware(void) bnConfig->FSPatchAddr = 0x0010F024; bnConfig->SMPatchAddr = 0x0010189C; } - else if (kernelVersion == SYSTEM_VERSION(2, 54, 0) || kernelVersion == SYSTEM_VERSION(2, 55, 0)) + else if (kernelVersion == SYSTEM_VERSION(2, 54, 0) || kernelVersion == SYSTEM_VERSION(2, 55, 0) || kernelVersion == SYSTEM_VERSION(2, 56, 0)) { // new3ds 11.4 and 11.8 if (kernelVersion == SYSTEM_VERSION(2, 54, 0)) diff --git a/source/graphics.c b/source/graphics.c index fc29e39..549afa9 100644 --- a/source/graphics.c +++ b/source/graphics.c @@ -44,7 +44,6 @@ void initUI(void) sprintf(appVersion, "Version: %d.%d", APP_VERSION_MAJOR, APP_VERSION_MINOR); else sprintf(appVersion, "Version: %d.%d.%d", APP_VERSION_MAJOR, APP_VERSION_MINOR, APP_VERSION_REVISION); - updateUI(); } void exitUI(void) diff --git a/source/main.c b/source/main.c index d0ab623..49c9cd1 100644 --- a/source/main.c +++ b/source/main.c @@ -30,7 +30,7 @@ int main(void) configInit(); // If keys == X or if config say we should check an update - if (keys & KEY_X || bnConfig->checkForUpdate) + /*if (keys & KEY_X || bnConfig->checkForUpdate) { // Check if the 3DS is connected acInit(); @@ -48,12 +48,11 @@ int main(void) } } - } - + }*/ kernelVersion = osGetKernelVersion(); - initMainMenu(); waitAllKeysReleased(); + initMainMenu(); ret = mainMenu(); if (ret == 2) goto waitForExit; if (!g_exit) diff --git a/source/png.c b/source/png.c index 422d283..e50484b 100644 --- a/source/png.c +++ b/source/png.c @@ -27,9 +27,8 @@ Result textureTile32(C3D_Tex *texture) } GSPGPU_FlushDataCache(tmp, width * height * 4); GSPGPU_FlushDataCache(texture->data, width * height * 4); - C3D_SafeDisplayTransfer((u32 *)tmp, GX_BUFFER_DIM(width, height), \ + C3D_SyncDisplayTransfer((u32 *)tmp, GX_BUFFER_DIM(width, height), \ (u32*)texture->data, GX_BUFFER_DIM(width, height), TEXTURE_TRANSFER_FLAGS); - gspWaitForPPF(); linearFree(tmp); return (MAKERESULT(RL_SUCCESS, RS_SUCCESS, RM_COMMON, RD_SUCCESS)); error: