From 23fa10c869427e0d6ba725085133d38b668fde28 Mon Sep 17 00:00:00 2001 From: GabyPCgeeK Date: Sat, 12 Aug 2017 21:37:16 -0400 Subject: [PATCH] freetype, unicode, icon, cross account, more vWii games Now shows game icon at diferent screens. *Small icon at game list. *Large icon at task selection and in task screen. No longer using OSScreen text rendering. Now uses Freetype2 to load CafeStd.ttf through the OSGetSharedData call. *This means Unicode text support (Japanese game names, Mii names with symbols, etc). Now user can choose which user account to backup (or all accounts). Added "cross account" restore. User can choose which account backed up on SD to restore to which account on Wii U. Now also looks for vWii saves in 00010001 and 00010004. For the vWii the slot 255 now backups/restores to/from the "SaveGame Manager GX" save path. (the default sd:/savegames path) --- Makefile | 2 +- README.md | 3 +- TGAReader_LICENSE | 22 + meta/meta.xml | 4 +- src/draw.c | 519 +++++++++++++++++ src/draw.h | 53 ++ src/dynamic_libs/acp_functions.c | 2 +- src/dynamic_libs/acp_functions.h | 2 +- src/dynamic_libs/aoc_functions.c | 2 +- src/dynamic_libs/aoc_functions.h | 4 +- src/dynamic_libs/ax_functions.c | 10 +- src/dynamic_libs/ax_functions.h | 2 +- src/dynamic_libs/curl_functions.c | 2 +- src/dynamic_libs/fs_defs.h | 19 +- src/dynamic_libs/fs_functions.c | 88 +-- src/dynamic_libs/fs_functions.h | 92 +-- src/dynamic_libs/gx2_functions.c | 6 +- src/dynamic_libs/gx2_functions.h | 5 +- src/dynamic_libs/os_functions.c | 268 +++++---- src/dynamic_libs/os_functions.h | 135 +++-- src/dynamic_libs/padscore_functions.c | 4 +- src/dynamic_libs/padscore_functions.h | 35 +- src/dynamic_libs/socket_functions.c | 51 +- src/dynamic_libs/socket_functions.h | 34 +- src/dynamic_libs/sys_functions.c | 16 +- src/dynamic_libs/sys_functions.h | 10 +- src/dynamic_libs/syshid_functions.c | 30 +- src/dynamic_libs/syshid_functions.h | 60 +- src/dynamic_libs/vpad_functions.c | 16 +- src/dynamic_libs/vpad_functions.h | 32 +- src/entry.c | 1 + src/icon.h | 640 +++++++++++++++++++++ src/lib_easy.c | 30 +- src/lib_easy.h | 2 - src/main.c | 780 ++++++++++++++++++-------- src/savemng.c | 657 +++++++++++++++++----- src/savemng.h | 44 +- src/system/memory.c | 22 +- src/tga_reader.c | 576 +++++++++++++++++++ src/tga_reader.h | 48 ++ 40 files changed, 3535 insertions(+), 793 deletions(-) create mode 100644 TGAReader_LICENSE create mode 100644 src/draw.c create mode 100644 src/draw.h create mode 100644 src/icon.h create mode 100644 src/tga_reader.c create mode 100644 src/tga_reader.h diff --git a/Makefile b/Makefile index a8517cc..9af5e2b 100644 --- a/Makefile +++ b/Makefile @@ -56,7 +56,7 @@ MAKEFLAGS += --no-print-directory #--------------------------------------------------------------------------------- # any extra libraries we wish to link with the project #--------------------------------------------------------------------------------- -LIBS := -lfat -liosuhax +LIBS := -lfat -liosuhax -lfreetype -lpng -lz -lm #--------------------------------------------------------------------------------- # list of directories containing libraries, this must be the top level containing diff --git a/README.md b/README.md index 69a7278..5d4c2e9 100644 --- a/README.md +++ b/README.md @@ -13,8 +13,7 @@ For sorting Titles press R to change sorting method and press L to change betwee Use it at your own risk and please report any issues that may occur. -Known issues: -- some games exhibit unexpected behaviour when the savefile is restored +**Needs freetype-2.8 library for compiling.** TODO: - installable package diff --git a/TGAReader_LICENSE b/TGAReader_LICENSE new file mode 100644 index 0000000..aa9072e --- /dev/null +++ b/TGAReader_LICENSE @@ -0,0 +1,22 @@ +The MIT License (MIT) + +Copyright (c) 2014 Kenji Sasaki + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + diff --git a/meta/meta.xml b/meta/meta.xml index c235fb2..2d552ab 100644 --- a/meta/meta.xml +++ b/meta/meta.xml @@ -2,8 +2,8 @@ SaveMii Mod Ryuzaki_MrL original (GabyPCgeeK mod) - 1.2.0.mod4 - 20170716000000 + 1.2.0.mod5 + 20170812000000 WiiU/vWii Save Manager WiiU/vWii Save Manager diff --git a/src/draw.c b/src/draw.c new file mode 100644 index 0000000..a353517 --- /dev/null +++ b/src/draw.c @@ -0,0 +1,519 @@ +#include "draw.h" + +unsigned char *scrBuffer; +int scr_buf0_size = 0; +int scr_buf1_size = 0; +bool cur_buf1; + +u8 *ttfFont; +RGBAColor fcolor = {0xFFFFFFFF}; +FT_Library library; +FT_Face face; + +void initDraw(char* buf, int size0, int size1) { + scrBuffer = buf; + scr_buf0_size = size0; + scr_buf1_size = size1; + + clearBuffers(); + uint32_t *screen2 = scrBuffer + scr_buf0_size; + OSScreenPutPixelEx(1, 0, 0, 0xABCDEFFF); + + if (screen2[0] == 0xABCDEFFF) cur_buf1 = false; + else cur_buf1 = true; +} + +void flipBuffers() { + //Flush the cache + DCFlushRange(scrBuffer + scr_buf0_size, scr_buf1_size); + DCFlushRange(scrBuffer, scr_buf0_size); + //Flip the buffer + OSScreenFlipBuffersEx(0); + OSScreenFlipBuffersEx(1); + cur_buf1 = !cur_buf1; +} + +void clearBuffers() { + for(int i = 0; i < 2; i++) { + OSScreenClearBufferEx(0, 0); + OSScreenClearBufferEx(1, 0); + flipBuffers(); + } +} + +void drawString(int x, int line, char* string) { + OSScreenPutFontEx(0, x, line, string); + OSScreenPutFontEx(1, x, line, string); +} + +void fillScreen(u8 r, u8 g, u8 b, u8 a) { + RGBAColor color; + color.r = r; color.g = g; color.b = b; color.a = a; + //uint32_t num = (r << 24) | (g << 16) | (b << 8) | a; + OSScreenClearBufferEx(0, color.c); + OSScreenClearBufferEx(1, color.c); +} + +void drawPixel32(int x, int y, RGBAColor color) { + drawPixel(x, y, color.r, color.g, color.b, color.a); +} + +void drawPixel(int x, int y, u8 r, u8 g, u8 b, u8 a) { + /*uint32_t num = (r << 24) | (g << 16) | (b << 8) | a; + OSScreenPutPixelEx(0, x, y, num); + OSScreenPutPixelEx(1, x, y, num);*/ + + int width = 1280; //height = 1024 720? + char *screen = scrBuffer; + int otherBuff0 = scr_buf0_size / 2; + int otherBuff1 = scr_buf1_size / 2; + float opacity = a / 255.0; + + for (int yy = (y * 1.5); yy < ((y * 1.5) + 1); yy++) { + for (int xx = (x * 1.5); xx < ((x * 1.5) + 1); xx++) { + u32 v = (xx + yy * width) * 4; + if (cur_buf1) v += otherBuff0; + screen[v ] = r * opacity + (1 - opacity) * screen[v]; + screen[v + 1] = g * opacity + (1 - opacity) * screen[v + 1]; + screen[v + 2] = b * opacity + (1 - opacity) * screen[v + 2]; + screen[v + 3] = a; + } + } + /*u32 v = (x + y * width) * 4; + if (cur_buf1) v += otherBuff0; + screen[v ] = r * opacity + (1 - opacity) * screen[v]; + screen[v + 1] = g * opacity + (1 - opacity) * screen[v + 1]; + screen[v + 2] = b * opacity + (1 - opacity) * screen[v + 2]; + screen[v + 3] = a;*/ + + width = 896; //height = 480; + char *screen2 = scrBuffer + scr_buf0_size; + u32 v = (x + y * width) * 4; + if (cur_buf1) v += otherBuff1; + screen2[v ] = r * opacity + (1 - opacity) * screen2[v]; + screen2[v + 1] = g * opacity + (1 - opacity) * screen2[v + 1]; + screen2[v + 2] = b * opacity + (1 - opacity) * screen2[v + 2]; + screen2[v + 3] = a; +} + +void drawLine(int x1, int y1, int x2, int y2, u8 r, u8 g, u8 b, u8 a) { + + int x, y; + if (x1 == x2){ + if (y1 < y2) for (y = y1; y <= y2; y++) drawPixel(x1, y, r, g, b, a); + else for (y = y2; y <= y1; y++) drawPixel(x1, y, r, g, b, a); + } + else { + if (x1 < x2) for (x = x1; x <= x2; x++) drawPixel(x, y1, r, g, b, a); + else for (x = x2; x <= x1; x++) drawPixel(x, y1, r, g, b, a); + } +} + +void drawRect(int x1, int y1, int x2, int y2, u8 r, u8 g, u8 b, u8 a) { + drawLine(x1, y1, x2, y1, r, g, b, a); + drawLine(x2, y1, x2, y2, r, g, b, a); + drawLine(x1, y2, x2, y2, r, g, b, a); + drawLine(x1, y1, x1, y2, r, g, b, a); +} + +void drawFillRect(int x1, int y1, int x2, int y2, u8 r, u8 g, u8 b, u8 a) { + int X1, X2, Y1, Y2, i, j; + + if (x1 < x2){ + X1 = x1; + X2 = x2; + } + else { + X1 = x2; + X2 = x1; + } + + if (y1 < y2){ + Y1 = y1; + Y2 = y2; + } + else { + Y1 = y2; + Y2 = y1; + } + for (i = X1; i <= X2; i++){ + for (j = Y1; j <= Y2; j++){ + drawPixel(i, j, r, g, b, a); + } + } +} + +void drawCircle(int xCen, int yCen, int radius, u8 r, u8 g, u8 b, u8 a) { + int x = 0; + int y = radius; + int p = (5 - radius * 4) / 4; + drawCircleCircum(xCen, yCen, x, y, r, g, b, a); + while (x < y){ + x++; + if (p < 0){ + p += 2 * x + 1; + } + else{ + y--; + p += 2 * (x - y) + 1; + } + drawCircleCircum(xCen, yCen, x, y, r, g, b, a); + } +} + +void drawFillCircle(int xCen, int yCen, int radius, u8 r, u8 g, u8 b, u8 a) { + drawCircle(xCen, yCen, radius, r, g, b, a); + int x, y; + for (y = -radius; y <= radius; y++){ + for (x = -radius; x <= radius; x++) + if (x*x + y*y <= radius*radius + radius * .8f) + drawPixel(xCen + x, yCen + y, r, g, b, a); + } +} + +void drawCircleCircum(int cx, int cy, int x, int y, u8 r, u8 g, u8 b, u8 a) { + + if (x == 0){ + drawPixel(cx, cy + y, r, g, b, a); + drawPixel(cx, cy - y, r, g, b, a); + drawPixel(cx + y, cy, r, g, b, a); + drawPixel(cx - y, cy, r, g, b, a); + } + if (x == y){ + drawPixel(cx + x, cy + y, r, g, b, a); + drawPixel(cx - x, cy + y, r, g, b, a); + drawPixel(cx + x, cy - y, r, g, b, a); + drawPixel(cx - x, cy - y, r, g, b, a); + } + if (x < y){ + drawPixel(cx + x, cy + y, r, g, b, a); + drawPixel(cx - x, cy + y, r, g, b, a); + drawPixel(cx + x, cy - y, r, g, b, a); + drawPixel(cx - x, cy - y, r, g, b, a); + drawPixel(cx + y, cy + x, r, g, b, a); + drawPixel(cx - y, cy + x, r, g, b, a); + drawPixel(cx + y, cy - x, r, g, b, a); + drawPixel(cx - y, cy - x, r, g, b, a); + } +} + +void drawPic(int x, int y, u32 w, u32 h, float scale, u32* pixels) { + u32 nw = w, nh = h; + RGBAColor color; + if (scale <= 0) scale = 1; + nw = w * scale; nh = h * scale; + + + for (u32 j = y; j < (y + nh); j++) { + for (u32 i = x; i < (x + nw); i++) { + color.c = pixels[((i - x) * w / nw) + ((j - y) * h / nh) * w]; + drawPixel32(i, j, color); + } + } +} + +void drawTGA(int x, int y, float scale, u8* fileContent) { + u32 w = tgaGetWidth(fileContent), h = tgaGetHeight(fileContent); + u32 nw = w, nh = h; + u32* out = tgaRead(fileContent, TGA_READER_RGBA); + + if (scale <= 0) scale = 1; + nw = w * scale; nh = h * scale; + + drawPic(x, y, w, h, scale, out); + if (scale > 0.5) { + if ((x > 0) && (y > 0)) drawRect(x - 1, y - 1, x + nw, y + nh, 255, 255, 255, 128); + if ((x > 1) && (y > 1)) drawRect(x - 2, y - 2, x + nw + 1, y + nh + 1, 255, 255, 255, 128); + if ((x > 2) && (y > 2)) drawRect(x - 3, y - 3, x + nw + 2, y + nh + 2, 255, 255, 255, 128); + } + free(out); +} + +void drawRGB5A3(int x, int y, float scale, u8* fileContent) { + u32 w = 192, h = 64, num = 0; + u32 nw = w, nh = h; + + if (scale <= 0) scale = 1; + nw = w * scale; nh = h * scale; + + u32 pos = 0, npos = 0; + RGBAColor color; + u16* pixels = (u16*)fileContent; + + u8 sum = (4 * scale); + for (u32 j = y; j < (y + nh); j += sum) { + for (u32 i = x; i < (x + nw); i += sum) { + for (u32 sj = j; sj < (j + sum); sj++, pos++) { + for (u32 si = i; si < (i + sum); si++) { + npos = ((si - i) / scale) + ((pos / scale) * 4); + if (pixels[npos] & 0x8000) + color.c = ((pixels[npos] & 0x7C00) << 17) | ((pixels[npos] & 0x3E0) << 14) | ((pixels[npos] & 0x1F) << 11) | 0xFF; + else + color.c = (((pixels[npos] & 0xF00) * 0x11) << 16) | (((pixels[npos] & 0xF0) * 0x11) << 12) | (((pixels[npos] & 0xF) * 0x11) << 8) | (((pixels[npos] & 0x7000) >> 12) * 0x24); + drawPixel32(si, sj, color); + } + } + } + } + if (scale > 0.5) { + if ((x > 0) && (y > 0)) drawRect(x - 1, y - 1, x + nw, y + nh, 255, 255, 255, 128); + if ((x > 1) && (y > 1)) drawRect(x - 2, y - 2, x + nw + 1, y + nh + 1, 255, 255, 255, 128); + if ((x > 2) && (y > 2)) drawRect(x - 3, y - 3, x + nw + 2, y + nh + 2, 255, 255, 255, 128); + } +} + +void drawBackgroundDRC(u32 w, u32 h, u8* out) { + uint32_t *screen2 = NULL; + int otherBuff1 = scr_buf1_size / 2; + + if (cur_buf1) screen2 = scrBuffer + scr_buf0_size + otherBuff1; + else screen2 = scrBuffer + scr_buf0_size; + memcpy(screen2, out, w * h * 4); +} + +void drawBackgroundTV(u32 w, u32 h, u8* out) { + uint32_t *screen1 = scrBuffer; + int otherBuff0 = scr_buf0_size / 2; + + if (cur_buf1) screen1 = scrBuffer + otherBuff0; + memcpy(screen1, out, w * h * 4); +} + +bool initFont(void* fontBuf, FT_Long fsize) { + FT_Long size = fsize; + if (fontBuf) { + ttfFont = fontBuf; + } else { + OSGetSharedData(2, 0, &ttfFont, &size); + } + + FT_Error error; + error = FT_Init_FreeType(&library); + if (error) return false; + + error = FT_New_Memory_Face(library, ttfFont, size, 0, &face); + if (error) return false; + + /*error = FT_Set_Char_Size(face, 8*64, 10*64, 158, 158); + if (error) return false;*/ + + error = FT_Set_Pixel_Sizes(face, 0, 22); //pixel width, height + if (error) return false; + + return true; +} + +void freeFont(void* fontBuf) { + FT_Done_Face(face); + FT_Done_FreeType(library); + //if (fontBuf) free(fontBuf); +} + +void draw_bitmap(FT_Bitmap* bitmap, FT_Int x, FT_Int y) { + FT_Int i, j, p, q; + FT_Int x_max; + FT_Int y_max = y + bitmap->rows; + + switch(bitmap->pixel_mode) { + case FT_PIXEL_MODE_GRAY: + x_max = x + bitmap->width; + for (i = x, p = 0; i < x_max; i++, p++) { + for (j = y, q = 0; j < y_max; j++, q++) { + if (i < 0 || j < 0 || i >= 854 || j >= 480) continue; + u8 col = bitmap->buffer[q * bitmap->pitch + p]; + if (col == 0) continue; + float opacity = col / 255.0; + /*u8 cr = fcolor.r * opacity + (1 - opacity) * 0; + u8 cg = fcolor.g * opacity + (1 - opacity) * 0; + u8 cb = fcolor.b * opacity + (1 - opacity) * 0; + drawPixel(i, j, cr, cg, cb, fcolor.a);*/ + drawPixel(i, j, fcolor.r, fcolor.g, fcolor.b, (u8)(fcolor.a * opacity)); + } + } + break; + case FT_PIXEL_MODE_LCD: + x_max = x + bitmap->width / 3; + for (i = x, p = 0; i < x_max; i++, p++) { + for (j = y, q = 0; j < y_max; j++, q++) { + if (i < 0 || j < 0 || i >= 854 || j >= 480) continue; + u8 cr = bitmap->buffer[q * bitmap->pitch + p * 3]; + u8 cg = bitmap->buffer[q * bitmap->pitch + p * 3 + 1]; + u8 cb = bitmap->buffer[q * bitmap->pitch + p * 3 + 2]; + + if ((cr | cg | cb) == 0) continue; + drawPixel(i, j, cr, cg, cb, 255); + } + } + break; + case FT_PIXEL_MODE_BGRA: + x_max = x + bitmap->width/2; + for (i = x, p = 0; i < x_max; i++, p++) { + for (j = y, q = 0; j < y_max; j++, q++) { + if (i < 0 || j < 0 || i >= 854 || j >= 480) continue; + u8 cb = bitmap->buffer[q * bitmap->pitch + p * 4]; + u8 cg = bitmap->buffer[q * bitmap->pitch + p * 4 + 1]; + u8 cr = bitmap->buffer[q * bitmap->pitch + p * 4 + 2]; + u8 ca = bitmap->buffer[q * bitmap->pitch + p * 4 + 3]; + + if ((cr | cg | cb) == 0) continue; + drawPixel(i, j, cr, cg, cb, ca); + } + } + break; + } +} + +bool ttfFontSize(u8 w, u8 h) { + FT_Error error; + + /*error = FT_Set_Char_Size(face, 8*64, 10*64, 158, 158); + if (error) return false;*/ + + error = FT_Set_Pixel_Sizes(face, w, h); //pixel width, height + if (error) return false; + return true; +} + +void ttfFontColor32(u32 color) { + fcolor.c = color; +} + +void ttfFontColor(u8 r, u8 g, u8 b, u8 a) { + RGBAColor color = {.r = r, .g = g, .b = b, .a = a}; + ttfFontColor32(color.c); +} + +int ttfPrintString(int x, int y, char *string, bool wWrap, bool ceroX) { + FT_GlyphSlot slot = face->glyph; + FT_Error error; + int pen_x = x, pen_y = y; + FT_UInt previous_glyph; + + while(*string) { + uint32_t buf = *string++; + int dy = 0; + + if ((buf >> 6) == 3) { + if ((buf & 0xF0) == 0xC0) { + uint8_t b1 = buf & 0xFF, b2 = *string++; + if ((b2 & 0xC0) == 0x80) b2 &= 0x3F; + buf = ((b1 & 0xF) << 6) | b2; + } else if ((buf & 0xF0) == 0xD0) { + uint8_t b1 = buf & 0xFF, b2 = *string++; + if ((b2 & 0xC0) == 0x80) b2 &= 0x3F; + buf = 0x400 | ((b1 & 0xF) << 6) | b2; + } else if ((buf & 0xF0) == 0xE0) { + uint8_t b1 = buf & 0xFF, b2 = *string++, b3 = *string++; + if ((b2 & 0xC0) == 0x80) b2 &= 0x3F; + if ((b3 & 0xC0) == 0x80) b3 &= 0x3F; + buf = ((b1 & 0xF) << 12) | (b2 << 6) | b3; + } + } else if (buf & 0x80) { + string++; + continue; + } + + if (buf == '\n') { + pen_y += (face->size->metrics.height >> 6); + if (ceroX) pen_x = 0; + else pen_x = x; + continue; + } + + //error = FT_Load_Char(face, buf, FT_LOAD_RENDER); + + FT_UInt glyph_index; + glyph_index = FT_Get_Char_Index(face, buf); + + if (FT_HAS_KERNING(face)) { + FT_Vector vector; + FT_Get_Kerning(face, previous_glyph, glyph_index, FT_KERNING_DEFAULT, &vector); + pen_x += (vector.x >> 6); + dy = vector.y >> 6; + } + + error = FT_Load_Glyph(face, glyph_index, FT_LOAD_DEFAULT);//FT_LOAD_COLOR);// + if (error) + continue; + + error = FT_Render_Glyph(face->glyph, FT_RENDER_MODE_NORMAL);//FT_RENDER_MODE_LCD);// + if (error) + continue; + + if ((pen_x + (slot->advance.x >> 6)) > 853) { + if (wWrap) { + pen_y += (face->size->metrics.height >> 6); + if (ceroX) pen_x = 0; + else pen_x = x; + } else { + return pen_x; + } + } + + draw_bitmap(&slot->bitmap, pen_x + slot->bitmap_left, (face->height >> 6) + pen_y - slot->bitmap_top); + + pen_x += (slot->advance.x >> 6); + previous_glyph = glyph_index; + } + return pen_x; +} + +int ttfStringWidth(char *string, s8 part) { + FT_GlyphSlot slot = face->glyph; + FT_Error error; + int pen_x = 0, max_x = 0, spart = 1; + FT_UInt previous_glyph; + + while(*string) { + uint32_t buf = *string++; + if ((buf >> 6) == 3) { + if ((buf & 0xF0) == 0xC0) { + uint8_t b1 = buf & 0xFF, b2 = *string++; + if ((b2 & 0xC0) == 0x80) b2 &= 0x3F; + buf = ((b1 & 0xF) << 6) | b2; + } else if ((buf & 0xF0) == 0xD0) { + uint8_t b1 = buf & 0xFF, b2 = *string++; + if ((b2 & 0xC0) == 0x80) b2 &= 0x3F; + buf = 0x400 | ((b1 & 0xF) << 6) | b2; + } else if ((buf & 0xF0) == 0xE0) { + uint8_t b1 = buf & 0xFF, b2 = *string++, b3 = *string++; + if ((b2 & 0xC0) == 0x80) b2 &= 0x3F; + if ((b3 & 0xC0) == 0x80) b3 &= 0x3F; + buf = ((b1 & 0xF) << 12) | (b2 << 6) | b3; + } + } else if (buf & 0x80) { + string++; + continue; + } + + //error = FT_Load_Char(face, buf, FT_LOAD_RENDER); + + FT_UInt glyph_index; + glyph_index = FT_Get_Char_Index(face, buf); + + if (FT_HAS_KERNING(face)) { + FT_Vector vector; + FT_Get_Kerning(face, previous_glyph, glyph_index, FT_KERNING_DEFAULT, &vector); + pen_x += (vector.x >> 6); + } + + if (buf == '\n') { + if (part != 0) { + if ((part > 0) && (spart == part)) return pen_x; + if (part == -2) max_x = max(pen_x, max_x); + pen_x = 0; + spart++; + } + continue; + } + + error = FT_Load_Glyph(face, glyph_index, FT_LOAD_BITMAP_METRICS_ONLY); + if (error) + continue; + + pen_x += (slot->advance.x >> 6); + previous_glyph = glyph_index; + } + if (spart < part) pen_x = 0; + return max(pen_x, max_x); +} diff --git a/src/draw.h b/src/draw.h new file mode 100644 index 0000000..85f92fe --- /dev/null +++ b/src/draw.h @@ -0,0 +1,53 @@ +#ifndef DRAW_H +#define DRAW_H +#include +//#include +#include "lib_easy.h" +#include "tga_reader.h" +#include +#include FT_FREETYPE_H + +typedef union _RGBAColor { + u32 c; + struct { + u8 r; + u8 g; + u8 b; + u8 a; + }; +} RGBAColor; + +#ifndef max +#define max(a, b) (((a) > (b)) ? (a) : (b)) +#endif + +//Function declarations for my graphics library +void initDraw(char* buf, int size0, int size1); +void flipBuffers(); +void clearBuffers(); +void fillScreen(u8 r, u8 g, u8 b, u8 a); +void drawString(int x, int line, char * string); +void drawPixel32(int x, int y, RGBAColor color); +void drawPixel(int x, int y, u8 r, u8 g, u8 b, u8 a); +void drawLine(int x1, int y1, int x2, int y2, u8 r, u8 g, u8 b, u8 a); +void drawRect(int x1, int y1, int x2, int y2, u8 r, u8 g, u8 b, u8 a); +void drawFillRect(int x1, int y1, int x2, int y2, u8 r, u8 g, u8 b, u8 a); +void drawCircle(int xCen, int yCen, int radius, u8 r, u8 g, u8 b, u8 a); +void drawFillCircle(int xCen, int yCen, int radius, u8 r, u8 g, u8 b, u8 a); +void drawCircleCircum(int cx, int cy, int x, int y, u8 r, u8 g, u8 b, u8 a); + +void drawPic(int x, int y, u32 w, u32 h, float scale, u32* pixels); +void drawTGA(int x, int y, float scale, u8* fileContent); +void drawRGB5A3(int x, int y, float scale, u8* pixels); +void drawBackgroundDRC(u32 w, u32 h, u8* out); +void drawBackgroundTV(u32 w, u32 h, u8* out); + +bool initFont(); +void freeFont(); +bool ttfFontSize(u8 w, u8 h); +void ttfFontColor32(u32 color); +void ttfFontColor(u8 r, u8 g, u8 b, u8 a); +int ttfPrintString(int x, int y, char *string, bool wWrap, bool ceroX); +int ttfStringWidth(char *string, s8 part); + +#endif /* DRAW_H */ diff --git a/src/dynamic_libs/acp_functions.c b/src/dynamic_libs/acp_functions.c index eb931f8..beed06a 100644 --- a/src/dynamic_libs/acp_functions.c +++ b/src/dynamic_libs/acp_functions.c @@ -24,7 +24,7 @@ #include "os_functions.h" #include "acp_functions.h" -unsigned int acp_handle __attribute__((section(".data"))) = 0; +u32 acp_handle __attribute__((section(".data"))) = 0; EXPORT_DECL(void, GetMetaXml, void * _ACPMetaXml); diff --git a/src/dynamic_libs/acp_functions.h b/src/dynamic_libs/acp_functions.h index dc1822d..328b9c3 100644 --- a/src/dynamic_libs/acp_functions.h +++ b/src/dynamic_libs/acp_functions.h @@ -30,7 +30,7 @@ extern "C" { #include -extern unsigned int acp_handle; +extern u32 acp_handle; void InitACPFunctionPointers(void); void InitAcquireACP(void); diff --git a/src/dynamic_libs/aoc_functions.c b/src/dynamic_libs/aoc_functions.c index e74306d..e1adc7a 100644 --- a/src/dynamic_libs/aoc_functions.c +++ b/src/dynamic_libs/aoc_functions.c @@ -24,7 +24,7 @@ #include "os_functions.h" #include "aoc_functions.h" -unsigned int aoc_handle __attribute__((section(".data"))) = 0; +u32 aoc_handle __attribute__((section(".data"))) = 0; EXPORT_DECL(s32, AOC_Initialize, void); EXPORT_DECL(s32, AOC_Finalize, void); diff --git a/src/dynamic_libs/aoc_functions.h b/src/dynamic_libs/aoc_functions.h index efca771..f2e8205 100644 --- a/src/dynamic_libs/aoc_functions.h +++ b/src/dynamic_libs/aoc_functions.h @@ -28,7 +28,9 @@ extern "C" { #endif -extern unsigned int aoc_handle; +#include + +extern u32 aoc_handle; #define AOC_TITLE_SIZE 104 diff --git a/src/dynamic_libs/ax_functions.c b/src/dynamic_libs/ax_functions.c index e517f6d..dc49494 100644 --- a/src/dynamic_libs/ax_functions.c +++ b/src/dynamic_libs/ax_functions.c @@ -25,7 +25,7 @@ #include "os_functions.h" #include "ax_functions.h" -unsigned int sound_handle __attribute__((section(".data"))) = 0; +u32 sound_handle __attribute__((section(".data"))) = 0; EXPORT_DECL(void, AXInitWithParams, u32 * params); EXPORT_DECL(void, AXInit, void); @@ -51,7 +51,7 @@ EXPORT_DECL(void, AXSetVoiceLoopOffset, void *v, u32 offset); void InitAcquireAX(void) { - unsigned int *funcPointer = 0; + u32 *funcPointer = 0; if(OS_FIRMWARE >= 400) { @@ -73,7 +73,7 @@ void InitAcquireAX(void) void InitAXFunctionPointers(void) { - unsigned int *funcPointer = 0; + u32 *funcPointer = 0; InitAcquireAX(); @@ -102,8 +102,8 @@ void ProperlyEndTransitionAudio(void) void (* AXInit_old)(void); void (* AXQuit_old)(void); - unsigned int *funcPointer = 0; - unsigned int sound_handle; + u32 *funcPointer = 0; + u32 sound_handle; OSDynLoad_Acquire("snd_core.rpl", &sound_handle); OS_FIND_EXPORT_EX(sound_handle, check_os_audio_transition_flag, check_os_audio_transition_flag_old); diff --git a/src/dynamic_libs/ax_functions.h b/src/dynamic_libs/ax_functions.h index 086346f..206d34f 100644 --- a/src/dynamic_libs/ax_functions.h +++ b/src/dynamic_libs/ax_functions.h @@ -30,7 +30,7 @@ extern "C" { #include -extern unsigned int sound_handle; +extern u32 sound_handle; void InitAXFunctionPointers(void); void InitAcquireAX(void); diff --git a/src/dynamic_libs/curl_functions.c b/src/dynamic_libs/curl_functions.c index 0c2988e..459524d 100644 --- a/src/dynamic_libs/curl_functions.c +++ b/src/dynamic_libs/curl_functions.c @@ -41,7 +41,7 @@ void InitAcquireCurl(void) void InitCurlFunctionPointers(void) { InitAcquireCurl(); - unsigned int *funcPointer = 0; + u32 *funcPointer = 0; OS_FIND_EXPORT_EX(libcurl_handle, curl_global_init, n_curl_global_init); OS_FIND_EXPORT_EX(libcurl_handle, curl_easy_init, n_curl_easy_init); diff --git a/src/dynamic_libs/fs_defs.h b/src/dynamic_libs/fs_defs.h index 9f7b02b..bb98595 100644 --- a/src/dynamic_libs/fs_defs.h +++ b/src/dynamic_libs/fs_defs.h @@ -1,5 +1,5 @@ #ifndef FS_DEFS_H -#define FS_DEFS_H +#define FS_DEFS_H #include @@ -17,7 +17,7 @@ extern "C" { #define FS_STATUS_OK 0 #define FS_RET_UNSUPPORTED_CMD 0x0400 #define FS_RET_NO_ERROR 0x0000 -#define FS_RET_ALL_ERROR (unsigned int)(-1) +#define FS_RET_ALL_ERROR (u32)(-1) #define FS_STAT_FLAG_IS_DIRECTORY 0x80000000 @@ -32,6 +32,8 @@ extern "C" { #define FS_CMD_BLOCK_SIZE 0xA80 #define FSA_STATUS_OK 0 +#define FSA_STATUS_END_OF_DIRECTORY -4 +#define FSA_STATUS_END_OF_FILE -5 #define FSA_STATUS_ALREADY_EXISTS -22 #define FSA_STATUS_NOT_FOUND -23 #define FSA_STATUS_NOT_EMPTY -24 @@ -48,7 +50,7 @@ typedef struct uint32_t ent_id; uint64_t ctime; uint64_t mtime; - uint8_t attributes[48]; + uint8_t attributes[48]; } __attribute__((packed)) FSStat; typedef struct @@ -57,10 +59,17 @@ typedef struct char name[FS_MAX_ENTNAME_SIZE]; } FSDirEntry; +typedef void (*FSAsyncCallback)(void *pClient, void *pCmd, int result, void *context); +typedef struct +{ + FSAsyncCallback userCallback; + void *userContext; + void *ioMsgQueue; +} FSAsyncParams; + #ifdef __cplusplus } #endif -#endif /* FS_DEFS_H */ - +#endif /* FS_DEFS_H */ diff --git a/src/dynamic_libs/fs_functions.c b/src/dynamic_libs/fs_functions.c index 08a4fb6..1da25f3 100644 --- a/src/dynamic_libs/fs_functions.c +++ b/src/dynamic_libs/fs_functions.c @@ -24,65 +24,69 @@ #include "fs_functions.h" #include "os_functions.h" -EXPORT_DECL(int, FSInit, void); -EXPORT_DECL(int, FSShutdown, void); -EXPORT_DECL(int, FSAddClientEx, void *pClient, int unk_zero_param, int errHandling); -EXPORT_DECL(int, FSDelClient, void *pClient); +EXPORT_DECL(s32, FSInit, void); +EXPORT_DECL(s32, FSShutdown, void); +EXPORT_DECL(s32, FSAddClient, void *pClient, s32 errHandling); +EXPORT_DECL(s32, FSAddClientEx, void *pClient, s32 unk_zero_param, s32 errHandling); +EXPORT_DECL(s32, FSDelClient, void *pClient); EXPORT_DECL(void, FSInitCmdBlock, void *pCmd); -EXPORT_DECL(int, FSGetMountSource, void *pClient, void *pCmd, int type, void *source, int errHandling); +EXPORT_DECL(void *, FSGetCurrentCmdBlock, void *pClient); +EXPORT_DECL(s32, FSGetMountSource, void *pClient, void *pCmd, s32 type, void *source, s32 errHandling); -EXPORT_DECL(int, FSMount, void *pClient, void *pCmd, void *source, char *target, uint32_t bytes, int errHandling); -EXPORT_DECL(int, FSUnmount, void *pClient, void *pCmd, const char *target, int errHandling); +EXPORT_DECL(s32, FSMount, void *pClient, void *pCmd, void *source, char *target, u32 bytes, s32 errHandling); +EXPORT_DECL(s32, FSUnmount, void *pClient, void *pCmd, const char *target, s32 errHandling); -EXPORT_DECL(int, FSGetStat, void *pClient, void *pCmd, const char *path, FSStat *stats, int errHandling); -EXPORT_DECL(int, FSGetStatAsync, void *pClient, void *pCmd, const char *path, void *stats, int error, void *asyncParams); -EXPORT_DECL(int, FSRename, void *pClient, void *pCmd, const char *oldPath, const char *newPath, int error); -EXPORT_DECL(int, FSRenameAsync, void *pClient, void *pCmd, const char *oldPath, const char *newPath, int error, void *asyncParams); -EXPORT_DECL(int, FSRemove, void *pClient, void *pCmd, const char *path, int error); -EXPORT_DECL(int, FSRemoveAsync, void *pClient, void *pCmd, const char *path, int error, void *asyncParams); -EXPORT_DECL(int, FSFlushQuota, void *pClient, void *pCmd, const char* path, int error); -EXPORT_DECL(int, FSFlushQuotaAsync, void *pClient, void *pCmd, const char *path, int error, void *asyncParams); -EXPORT_DECL(int, FSGetFreeSpaceSize, void *pClient, void *pCmd, const char *path, uint64_t *returnedFreeSize, int error); -EXPORT_DECL(int, FSGetFreeSpaceSizeAsync, void *pClient, void *pCmd, const char *path, uint64_t *returnedFreeSize, int error, void *asyncParams); -EXPORT_DECL(int, FSRollbackQuota, void *pClient, void *pCmd, const char *path, int error); -EXPORT_DECL(int, FSRollbackQuotaAsync, void *pClient, void *pCmd, const char *path, int error, void *asyncParams); +EXPORT_DECL(s32, FSGetStat, void *pClient, void *pCmd, const char *path, FSStat *stats, s32 errHandling); +EXPORT_DECL(s32, FSGetStatAsync, void *pClient, void *pCmd, const char *path, void *stats, s32 error, void *asyncParams); +EXPORT_DECL(s32, FSRename, void *pClient, void *pCmd, const char *oldPath, const char *newPath, s32 error); +EXPORT_DECL(s32, FSRenameAsync, void *pClient, void *pCmd, const char *oldPath, const char *newPath, s32 error, void *asyncParams); +EXPORT_DECL(s32, FSRemove, void *pClient, void *pCmd, const char *path, s32 error); +EXPORT_DECL(s32, FSRemoveAsync, void *pClient, void *pCmd, const char *path, s32 error, void *asyncParams); +EXPORT_DECL(s32, FSFlushQuota, void *pClient, void *pCmd, const char* path, s32 error); +EXPORT_DECL(s32, FSFlushQuotaAsync, void *pClient, void *pCmd, const char *path, s32 error, void *asyncParams); +EXPORT_DECL(s32, FSGetFreeSpaceSize, void *pClient, void *pCmd, const char *path, uint64_t *returnedFreeSize, s32 error); +EXPORT_DECL(s32, FSGetFreeSpaceSizeAsync, void *pClient, void *pCmd, const char *path, uint64_t *returnedFreeSize, s32 error, void *asyncParams); +EXPORT_DECL(s32, FSRollbackQuota, void *pClient, void *pCmd, const char *path, s32 error); +EXPORT_DECL(s32, FSRollbackQuotaAsync, void *pClient, void *pCmd, const char *path, s32 error, void *asyncParams); -EXPORT_DECL(int, FSOpenDir, void *pClient, void *pCmd, const char *path, int *dh, int errHandling); -EXPORT_DECL(int, FSOpenDirAsync, void *pClient, void* pCmd, const char *path, int *handle, int error, void *asyncParams); -EXPORT_DECL(int, FSReadDir, void *pClient, void *pCmd, int dh, FSDirEntry *dir_entry, int errHandling); -EXPORT_DECL(int, FSRewindDir, void *pClient, void *pCmd, int dh, int errHandling); -EXPORT_DECL(int, FSCloseDir, void *pClient, void *pCmd, int dh, int errHandling); -EXPORT_DECL(int, FSChangeDir, void *pClient, void *pCmd, const char *path, int errHandling); -EXPORT_DECL(int, FSChangeDirAsync, void *pClient, void *pCmd, const char *path, int error, void *asyncParams); -EXPORT_DECL(int, FSMakeDir, void *pClient, void *pCmd, const char *path, int errHandling); -EXPORT_DECL(int, FSMakeDirAsync, void *pClient, void *pCmd, const char *path, int error, void *asyncParams); +EXPORT_DECL(s32, FSOpenDir, void *pClient, void *pCmd, const char *path, s32 *dh, s32 errHandling); +EXPORT_DECL(s32, FSOpenDirAsync, void *pClient, void* pCmd, const char *path, s32 *handle, s32 error, void *asyncParams); +EXPORT_DECL(s32, FSReadDir, void *pClient, void *pCmd, s32 dh, FSDirEntry *dir_entry, s32 errHandling); +EXPORT_DECL(s32, FSRewindDir, void *pClient, void *pCmd, s32 dh, s32 errHandling); +EXPORT_DECL(s32, FSCloseDir, void *pClient, void *pCmd, s32 dh, s32 errHandling); +EXPORT_DECL(s32, FSChangeDir, void *pClient, void *pCmd, const char *path, s32 errHandling); +EXPORT_DECL(s32, FSChangeDirAsync, void *pClient, void *pCmd, const char *path, s32 error, void *asyncParams); +EXPORT_DECL(s32, FSMakeDir, void *pClient, void *pCmd, const char *path, s32 errHandling); +EXPORT_DECL(s32, FSMakeDirAsync, void *pClient, void *pCmd, const char *path, s32 error, void *asyncParams); -EXPORT_DECL(int, FSOpenFile, void *pClient, void *pCmd, const char *path, const char *mode, int *fd, int errHandling); -EXPORT_DECL(int, FSOpenFileAsync, void *pClient, void *pCmd, const char *path, const char *mode, int *handle, int error, const void *asyncParams); -EXPORT_DECL(int, FSReadFile, void *pClient, void *pCmd, void *buffer, int size, int count, int fd, int flag, int errHandling); -EXPORT_DECL(int, FSCloseFile, void *pClient, void *pCmd, int fd, int errHandling); +EXPORT_DECL(s32, FSOpenFile, void *pClient, void *pCmd, const char *path, const char *mode, s32 *fd, s32 errHandling); +EXPORT_DECL(s32, FSOpenFileAsync, void *pClient, void *pCmd, const char *path, const char *mode, s32 *handle, s32 error, const void *asyncParams); +EXPORT_DECL(s32, FSReadFile, void *pClient, void *pCmd, void *buffer, s32 size, s32 count, s32 fd, s32 flag, s32 errHandling); +EXPORT_DECL(s32, FSCloseFile, void *pClient, void *pCmd, s32 fd, s32 errHandling); -EXPORT_DECL(int, FSFlushFile, void *pClient, void *pCmd, int fd, int error); -EXPORT_DECL(int, FSTruncateFile, void *pClient, void *pCmd, int fd, int error); -EXPORT_DECL(int, FSGetStatFile, void *pClient, void *pCmd, int fd, void *buffer, int error); -EXPORT_DECL(int, FSSetPosFile, void *pClient, void *pCmd, int fd, int pos, int error); -EXPORT_DECL(int, FSWriteFile, void *pClient, void *pCmd, const void *source, int block_size, int block_count, int fd, int flag, int error); +EXPORT_DECL(s32, FSFlushFile, void *pClient, void *pCmd, s32 fd, s32 error); +EXPORT_DECL(s32, FSTruncateFile, void *pClient, void *pCmd, s32 fd, s32 error); +EXPORT_DECL(s32, FSGetStatFile, void *pClient, void *pCmd, s32 fd, void *buffer, s32 error); +EXPORT_DECL(s32, FSSetPosFile, void *pClient, void *pCmd, s32 fd, s32 pos, s32 error); +EXPORT_DECL(s32, FSWriteFile, void *pClient, void *pCmd, const void *source, s32 block_size, s32 block_count, s32 fd, s32 flag, s32 error); -EXPORT_DECL(int, FSBindMount, void *pClient, void *pCmd, char *source, char *target, int error); -EXPORT_DECL(int, FSBindUnmount, void *pClient, void *pCmd, char *target, int error); +EXPORT_DECL(s32, FSBindMount, void *pClient, void *pCmd, char *source, char *target, s32 error); +EXPORT_DECL(s32, FSBindUnmount, void *pClient, void *pCmd, char *target, s32 error); -EXPORT_DECL(int, FSMakeQuota, void *pClient, void *pCmd, const char *path,u32 mode, u64 size, int errHandling); -EXPORT_DECL(int, FSMakeQuotaAsync ,void *pClient, void *pCmd, const char *path,u32 mode, u64 size, int errHandling,const void *asyncParams); +EXPORT_DECL(s32, FSMakeQuota, void *pClient, void *pCmd, const char *path,u32 mode, u64 size, s32 errHandling); +EXPORT_DECL(s32, FSMakeQuotaAsync ,void *pClient, void *pCmd, const char *path,u32 mode, u64 size, s32 errHandling,const void *asyncParams); void InitFSFunctionPointers(void) { - unsigned int *funcPointer = 0; + u32 *funcPointer = 0; OS_FIND_EXPORT(coreinit_handle, FSInit); OS_FIND_EXPORT(coreinit_handle, FSShutdown); + OS_FIND_EXPORT(coreinit_handle, FSAddClient); OS_FIND_EXPORT(coreinit_handle, FSAddClientEx); OS_FIND_EXPORT(coreinit_handle, FSDelClient); OS_FIND_EXPORT(coreinit_handle, FSInitCmdBlock); + OS_FIND_EXPORT(coreinit_handle, FSGetCurrentCmdBlock); OS_FIND_EXPORT(coreinit_handle, FSGetMountSource); OS_FIND_EXPORT(coreinit_handle, FSMount); diff --git a/src/dynamic_libs/fs_functions.h b/src/dynamic_libs/fs_functions.h index d024655..24e7403 100644 --- a/src/dynamic_libs/fs_functions.h +++ b/src/dynamic_libs/fs_functions.h @@ -33,59 +33,61 @@ extern "C" { void InitFSFunctionPointers(void); -extern int (* FSInit)(void); -extern int (* FSShutdown)(void); -extern int (* FSAddClientEx)(void *pClient, int unk_zero_param, int errHandling); -extern int (* FSDelClient)(void *pClient); +extern s32 (* FSInit)(void); +extern s32 (* FSShutdown)(void); +extern s32 (* FSAddClient)(void *pClient, s32 errHandling); +extern s32 (* FSAddClientEx)(void *pClient, s32 unk_zero_param, s32 errHandling); +extern s32 (* FSDelClient)(void *pClient); extern void (* FSInitCmdBlock)(void *pCmd); -extern int (* FSGetMountSource)(void *pClient, void *pCmd, int type, void *source, int errHandling); +extern void *(* FSGetCurrentCmdBlock)(void *pClient); +extern s32 (* FSGetMountSource)(void *pClient, void *pCmd, s32 type, void *source, s32 errHandling); -extern int (* FSMount)(void *pClient, void *pCmd, void *source, char *target, uint32_t bytes, int errHandling); -extern int (* FSUnmount)(void *pClient, void *pCmd, const char *target, int errHandling); -extern int (* FSRename)(void *pClient, void *pCmd, const char *oldPath, const char *newPath, int error); -extern int (* FSRenameAsync)(void *pClient, void *pCmd, const char *oldPath, const char *newPath, int error, void *asyncParams); -extern int (* FSRemove)(void *pClient, void *pCmd, const char *path, int error); -extern int (* FSRemoveAsync)(void *pClient, void *pCmd, const char *path, int error, void *asyncParams); +extern s32 (* FSMount)(void *pClient, void *pCmd, void *source, char *target, u32 bytes, s32 errHandling); +extern s32 (* FSUnmount)(void *pClient, void *pCmd, const char *target, s32 errHandling); +extern s32 (* FSRename)(void *pClient, void *pCmd, const char *oldPath, const char *newPath, s32 error); +extern s32 (* FSRenameAsync)(void *pClient, void *pCmd, const char *oldPath, const char *newPath, s32 error, void *asyncParams); +extern s32 (* FSRemove)(void *pClient, void *pCmd, const char *path, s32 error); +extern s32 (* FSRemoveAsync)(void *pClient, void *pCmd, const char *path, s32 error, void *asyncParams); -extern int (* FSGetStat)(void *pClient, void *pCmd, const char *path, FSStat *stats, int errHandling); -extern int (* FSGetStatAsync)(void *pClient, void *pCmd, const char *path, void *stats, int error, void *asyncParams); -extern int (* FSRename)(void *pClient, void *pCmd, const char *oldPath, const char *newPath, int error); -extern int (* FSRenameAsync)(void *pClient, void *pCmd, const char *oldPath, const char *newPath, int error, void *asyncParams); -extern int (* FSRemove)(void *pClient, void *pCmd, const char *path, int error); -extern int (* FSRemoveAsync)(void *pClient, void *pCmd, const char *path, int error, void *asyncParams); -extern int (* FSFlushQuota)(void *pClient, void *pCmd, const char* path, int error); -extern int (* FSFlushQuotaAsync)(void *pClient, void *pCmd, const char *path, int error, void *asyncParams); -extern int (* FSGetFreeSpaceSize)(void *pClient, void *pCmd, const char *path, uint64_t *returnedFreeSize, int error); -extern int (* FSGetFreeSpaceSizeAsync)(void *pClient, void *pCmd, const char *path, uint64_t *returnedFreeSize, int error, void *asyncParams); -extern int (* FSRollbackQuota)(void *pClient, void *pCmd, const char *path, int error); -extern int (* FSRollbackQuotaAsync)(void *pClient, void *pCmd, const char *path, int error, void *asyncParams); +extern s32 (* FSGetStat)(void *pClient, void *pCmd, const char *path, FSStat *stats, s32 errHandling); +extern s32 (* FSGetStatAsync)(void *pClient, void *pCmd, const char *path, void *stats, s32 error, void *asyncParams); +extern s32 (* FSRename)(void *pClient, void *pCmd, const char *oldPath, const char *newPath, s32 error); +extern s32 (* FSRenameAsync)(void *pClient, void *pCmd, const char *oldPath, const char *newPath, s32 error, void *asyncParams); +extern s32 (* FSRemove)(void *pClient, void *pCmd, const char *path, s32 error); +extern s32 (* FSRemoveAsync)(void *pClient, void *pCmd, const char *path, s32 error, void *asyncParams); +extern s32 (* FSFlushQuota)(void *pClient, void *pCmd, const char* path, s32 error); +extern s32 (* FSFlushQuotaAsync)(void *pClient, void *pCmd, const char *path, s32 error, void *asyncParams); +extern s32 (* FSGetFreeSpaceSize)(void *pClient, void *pCmd, const char *path, uint64_t *returnedFreeSize, s32 error); +extern s32 (* FSGetFreeSpaceSizeAsync)(void *pClient, void *pCmd, const char *path, uint64_t *returnedFreeSize, s32 error, void *asyncParams); +extern s32 (* FSRollbackQuota)(void *pClient, void *pCmd, const char *path, s32 error); +extern s32 (* FSRollbackQuotaAsync)(void *pClient, void *pCmd, const char *path, s32 error, void *asyncParams); -extern int (* FSOpenDir)(void *pClient, void *pCmd, const char *path, int *dh, int errHandling); -extern int (* FSOpenDirAsync)(void *pClient, void* pCmd, const char *path, int *handle, int error, void *asyncParams); -extern int (* FSReadDir)(void *pClient, void *pCmd, int dh, FSDirEntry *dir_entry, int errHandling); -extern int (* FSRewindDir)(void *pClient, void *pCmd, int dh, int errHandling); -extern int (* FSCloseDir)(void *pClient, void *pCmd, int dh, int errHandling); -extern int (* FSChangeDir)(void *pClient, void *pCmd, const char *path, int errHandling); -extern int (* FSChangeDirAsync)(void *pClient, void *pCmd, const char *path, int error, void *asyncParams); -extern int (* FSMakeDir)(void *pClient, void *pCmd, const char *path, int errHandling); -extern int (* FSMakeDirAsync)(void *pClient, void *pCmd, const char *path, int error, void *asyncParams); +extern s32 (* FSOpenDir)(void *pClient, void *pCmd, const char *path, s32 *dh, s32 errHandling); +extern s32 (* FSOpenDirAsync)(void *pClient, void* pCmd, const char *path, s32 *handle, s32 error, void *asyncParams); +extern s32 (* FSReadDir)(void *pClient, void *pCmd, s32 dh, FSDirEntry *dir_entry, s32 errHandling); +extern s32 (* FSRewindDir)(void *pClient, void *pCmd, s32 dh, s32 errHandling); +extern s32 (* FSCloseDir)(void *pClient, void *pCmd, s32 dh, s32 errHandling); +extern s32 (* FSChangeDir)(void *pClient, void *pCmd, const char *path, s32 errHandling); +extern s32 (* FSChangeDirAsync)(void *pClient, void *pCmd, const char *path, s32 error, void *asyncParams); +extern s32 (* FSMakeDir)(void *pClient, void *pCmd, const char *path, s32 errHandling); +extern s32 (* FSMakeDirAsync)(void *pClient, void *pCmd, const char *path, s32 error, void *asyncParams); -extern int (* FSOpenFile)(void *pClient, void *pCmd, const char *path, const char *mode, int *fd, int errHandling); -extern int (* FSOpenFileAsync)(void *pClient, void *pCmd, const char *path, const char *mode, int *handle, int error, const void *asyncParams); -extern int (* FSReadFile)(void *pClient, void *pCmd, void *buffer, int size, int count, int fd, int flag, int errHandling); -extern int (* FSCloseFile)(void *pClient, void *pCmd, int fd, int errHandling); +extern s32 (* FSOpenFile)(void *pClient, void *pCmd, const char *path, const char *mode, s32 *fd, s32 errHandling); +extern s32 (* FSOpenFileAsync)(void *pClient, void *pCmd, const char *path, const char *mode, s32 *handle, s32 error, const void *asyncParams); +extern s32 (* FSReadFile)(void *pClient, void *pCmd, void *buffer, s32 size, s32 count, s32 fd, s32 flag, s32 errHandling); +extern s32 (* FSCloseFile)(void *pClient, void *pCmd, s32 fd, s32 errHandling); -extern int (* FSFlushFile)(void *pClient, void *pCmd, int fd, int error); -extern int (* FSTruncateFile)(void *pClient, void *pCmd, int fd, int error); -extern int (* FSGetStatFile)(void *pClient, void *pCmd, int fd, void *buffer, int error); -extern int (* FSSetPosFile)(void *pClient, void *pCmd, int fd, int pos, int error); -extern int (* FSWriteFile)(void *pClient, void *pCmd, const void *source, int block_size, int block_count, int fd, int flag, int error); +extern s32 (* FSFlushFile)(void *pClient, void *pCmd, s32 fd, s32 error); +extern s32 (* FSTruncateFile)(void *pClient, void *pCmd, s32 fd, s32 error); +extern s32 (* FSGetStatFile)(void *pClient, void *pCmd, s32 fd, void *buffer, s32 error); +extern s32 (* FSSetPosFile)(void *pClient, void *pCmd, s32 fd, s32 pos, s32 error); +extern s32 (* FSWriteFile)(void *pClient, void *pCmd, const void *source, s32 block_size, s32 block_count, s32 fd, s32 flag, s32 error); -extern int (* FSBindMount)(void *pClient, void *pCmd, char *source, char *target, int error); -extern int (* FSBindUnmount)(void *pClient, void *pCmd, char *target, int error); +extern s32 (* FSBindMount)(void *pClient, void *pCmd, char *source, char *target, s32 error); +extern s32 (* FSBindUnmount)(void *pClient, void *pCmd, char *target, s32 error); -extern int (* FSMakeQuota)( void *pClient, void *pCmd, const char *path,u32 mode, u64 size, int errHandling); -extern int (* FSMakeQuotaAsync)(void *pClient, void *pCmd, const char *path,u32 mode, u64 size, int errHandling,const void *asyncParams); +extern s32 (* FSMakeQuota)( void *pClient, void *pCmd, const char *path,u32 mode, u64 size, s32 errHandling); +extern s32 (* FSMakeQuotaAsync)(void *pClient, void *pCmd, const char *path,u32 mode, u64 size, s32 errHandling,const void *asyncParams); #ifdef __cplusplus diff --git a/src/dynamic_libs/gx2_functions.c b/src/dynamic_libs/gx2_functions.c index a34807e..501c4d7 100644 --- a/src/dynamic_libs/gx2_functions.c +++ b/src/dynamic_libs/gx2_functions.c @@ -24,7 +24,7 @@ #include "os_functions.h" #include "gx2_types.h" -unsigned int gx2_handle __attribute__((section(".data"))) = 0; +u32 gx2_handle __attribute__((section(".data"))) = 0; EXPORT_DECL(void, GX2Init, u32 * init_attribs); EXPORT_DECL(void, GX2Shutdown, void); @@ -93,7 +93,7 @@ EXPORT_DECL(s32, GX2GetSystemDRCScanMode, void); EXPORT_DECL(void, GX2RSetAllocator, void * (* allocFunc)(u32, u32, u32), void (* freeFunc)(u32, void*)); EXPORT_DECL(void, GX2CopySurface, GX2Surface * srcSurface,u32 srcMip,u32 srcSlice,GX2Surface * dstSurface,u32 dstMip,u32 dstSlice ); -EXPORT_DECL(void, GX2ClearBuffersEx, GX2ColorBuffer * colorBuffer,GX2DepthBuffer * depthBuffer,f32 r, f32 g, f32 b, f32 a,f32 depthValue,u8 stencilValue,int clearFlags); +EXPORT_DECL(void, GX2ClearBuffersEx, GX2ColorBuffer * colorBuffer,GX2DepthBuffer * depthBuffer,f32 r, f32 g, f32 b, f32 a,f32 depthValue,u8 stencilValue,s32 clearFlags); void InitAcquireGX2(void) { @@ -102,7 +102,7 @@ void InitAcquireGX2(void) void InitGX2FunctionPointers(void) { - unsigned int *funcPointer = 0; + u32 *funcPointer = 0; InitAcquireGX2(); OS_FIND_EXPORT(gx2_handle, GX2Init); diff --git a/src/dynamic_libs/gx2_functions.h b/src/dynamic_libs/gx2_functions.h index 0b06826..9133fcc 100644 --- a/src/dynamic_libs/gx2_functions.h +++ b/src/dynamic_libs/gx2_functions.h @@ -28,9 +28,10 @@ extern "C" { #endif +#include #include "gx2_types.h" -extern unsigned int gx2_handle; +extern u32 gx2_handle; void InitGX2FunctionPointers(void); void InitAcquireGX2(void); @@ -101,7 +102,7 @@ extern s32 (* GX2GetSystemTVScanMode)(void); extern s32 (* GX2GetSystemDRCScanMode)(void); extern void (* GX2RSetAllocator)(void * (*allocFunc)(u32, u32, u32), void (*freeFunc)(u32, void*)); extern void (* GX2CopySurface)(GX2Surface * srcSurface,u32 srcMip,u32 srcSlice,GX2Surface * dstSurface,u32 dstMip,u32 dstSlice ); -extern void (* GX2ClearBuffersEx)(GX2ColorBuffer * colorBuffer,GX2DepthBuffer * depthBuffer,f32 r, f32 g, f32 b, f32 a,f32 depthValue,u8 stencilValue,int clearFlags); +extern void (* GX2ClearBuffersEx)(GX2ColorBuffer * colorBuffer,GX2DepthBuffer * depthBuffer,f32 r, f32 g, f32 b, f32 a,f32 depthValue,u8 stencilValue,s32 clearFlags); static inline void GX2InitDepthBuffer(GX2DepthBuffer *depthBuffer, s32 dimension, u32 width, u32 height, u32 depth, s32 format, s32 aa) { diff --git a/src/dynamic_libs/os_functions.c b/src/dynamic_libs/os_functions.c index 2923bcd..7999c63 100644 --- a/src/dynamic_libs/os_functions.c +++ b/src/dynamic_libs/os_functions.c @@ -24,50 +24,55 @@ #include "common/common.h" #include "os_functions.h" -unsigned int coreinit_handle __attribute__((section(".data"))) = 0; +u32 coreinit_handle __attribute__((section(".data"))) = 0; //!---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- //! Lib handle functions //!---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -EXPORT_DECL(int, OSDynLoad_Acquire, const char* rpl, u32 *handle); -EXPORT_DECL(int, OSDynLoad_FindExport, u32 handle, int isdata, const char *symbol, void *address); +EXPORT_DECL(s32, OSDynLoad_Acquire, const char* rpl, u32 *handle); +EXPORT_DECL(s32, OSDynLoad_FindExport, u32 handle, s32 isdata, const char *symbol, void *address); //!---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- //! Security functions //!---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -EXPORT_DECL(int, OSGetSecurityLevel, void); -EXPORT_DECL(int, OSForceFullRelaunch, void); +EXPORT_DECL(s32, OSGetSecurityLevel, void); +EXPORT_DECL(s32, OSForceFullRelaunch, void); //!---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- //! Thread functions //!---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -EXPORT_DECL(int, OSCreateThread, void *thread, s32 (*callback)(s32, void*), s32 argc, void *args, u32 stack, u32 stack_size, s32 priority, u32 attr); -EXPORT_DECL(int, OSResumeThread, void *thread); -EXPORT_DECL(int, OSSuspendThread, void *thread); -EXPORT_DECL(int, OSIsThreadTerminated, void *thread); -EXPORT_DECL(int, OSIsThreadSuspended, void *thread); -EXPORT_DECL(int, OSSetThreadPriority, void * thread, int priority); -EXPORT_DECL(int, OSJoinThread, void * thread, int * ret_val); +EXPORT_DECL(s32, OSCreateThread, void *thread, s32 (*callback)(s32, void*), s32 argc, void *args, u32 stack, u32 stack_size, s32 priority, u32 attr); +EXPORT_DECL(s32, OSResumeThread, void *thread); +EXPORT_DECL(s32, OSSuspendThread, void *thread); +EXPORT_DECL(void, OSExitThread, u32 result); +EXPORT_DECL(s32, OSIsThreadTerminated, void *thread); +EXPORT_DECL(s32, OSIsThreadSuspended, void *thread); +EXPORT_DECL(s32, OSSetThreadPriority, void * thread, s32 priority); +EXPORT_DECL(s32, OSJoinThread, void * thread, s32 * ret_val); EXPORT_DECL(void, OSDetachThread, void * thread); EXPORT_DECL(void, OSSleepTicks, u64 ticks); EXPORT_DECL(u64, OSGetTick, void); EXPORT_DECL(u64, OSGetTime, void); EXPORT_DECL(void, OSTicksToCalendarTime, u64 time, OSCalendarTime * calendarTime); - //!---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- //! Mutex functions //!---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- EXPORT_DECL(void, OSInitMutex, void* mutex); EXPORT_DECL(void, OSLockMutex, void* mutex); EXPORT_DECL(void, OSUnlockMutex, void* mutex); -EXPORT_DECL(int, OSTryLockMutex, void* mutex); +EXPORT_DECL(s32, OSTryLockMutex, void* mutex); + +//!---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +//! Shared Data functions +//!---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +EXPORT_DECL(bool, OSGetSharedData, u32 type, u32 unk_r4, u8 *addr, u32 *size); //!---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- //! System functions //!---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- EXPORT_DECL(u64, OSGetTitleID, void); -EXPORT_DECL(void, OSGetArgcArgv, int* argc, char*** argv); +EXPORT_DECL(void, OSGetArgcArgv, s32* argc, char*** argv); EXPORT_DECL(void, __Exit, void); EXPORT_DECL(void, OSFatal, const char* msg); EXPORT_DECL(void, OSSetExceptionCallback, u8 exceptionType, exception_callback newCallback); @@ -75,47 +80,51 @@ EXPORT_DECL(void, DCFlushRange, const void *addr, u32 length); EXPORT_DECL(void, DCStoreRange, const void *addr, u32 length); EXPORT_DECL(void, ICInvalidateRange, const void *addr, u32 length); EXPORT_DECL(void*, OSEffectiveToPhysical, const void*); -EXPORT_DECL(int, __os_snprintf, char* s, int n, const char * format, ...); -EXPORT_DECL(int *, __gh_errno_ptr, void); +EXPORT_DECL(s32, __os_snprintf, char* s, s32 n, const char * format, ...); +EXPORT_DECL(s32 *, __gh_errno_ptr, void); EXPORT_DECL(void, OSScreenInit, void); -EXPORT_DECL(unsigned int, OSScreenGetBufferSizeEx, unsigned int bufferNum); -EXPORT_DECL(int, OSScreenSetBufferEx, unsigned int bufferNum, void * addr); -EXPORT_DECL(int, OSScreenClearBufferEx, unsigned int bufferNum, unsigned int temp); -EXPORT_DECL(int, OSScreenFlipBuffersEx, unsigned int bufferNum); -EXPORT_DECL(int, OSScreenPutFontEx, unsigned int bufferNum, unsigned int posX, unsigned int posY, const char * buffer); -EXPORT_DECL(int, OSScreenEnableEx, unsigned int bufferNum, int enable); +EXPORT_DECL(u32, OSScreenGetBufferSizeEx, u32 bufferNum); +EXPORT_DECL(s32, OSScreenSetBufferEx, u32 bufferNum, void * addr); +EXPORT_DECL(s32, OSScreenClearBufferEx, u32 bufferNum, u32 temp); +EXPORT_DECL(s32, OSScreenFlipBuffersEx, u32 bufferNum); +EXPORT_DECL(s32, OSScreenPutFontEx, u32 bufferNum, u32 posX, u32 posY, const char * buffer); +EXPORT_DECL(s32, OSScreenEnableEx, u32 bufferNum, s32 enable); +EXPORT_DECL(u32, OSScreenPutPixelEx, u32 bufferNum, u32 posX, u32 posY, u32 color); //!---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- //! Memory functions //!---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -EXPORT_VAR(unsigned int *, pMEMAllocFromDefaultHeapEx); -EXPORT_VAR(unsigned int *, pMEMAllocFromDefaultHeap); -EXPORT_VAR(unsigned int *, pMEMFreeToDefaultHeap); +EXPORT_VAR(u32 *, pMEMAllocFromDefaultHeapEx); +EXPORT_VAR(u32 *, pMEMAllocFromDefaultHeap); +EXPORT_VAR(u32 *, pMEMFreeToDefaultHeap); -EXPORT_DECL(int, MEMGetBaseHeapHandle, int mem_arena); -EXPORT_DECL(unsigned int, MEMGetAllocatableSizeForFrmHeapEx, int heap, int align); -EXPORT_DECL(void *, MEMAllocFromFrmHeapEx, int heap, unsigned int size, int align); -EXPORT_DECL(void, MEMFreeToFrmHeap, int heap, int mode); -EXPORT_DECL(void *, MEMAllocFromExpHeapEx, int heap, unsigned int size, int align); -EXPORT_DECL(int , MEMCreateExpHeapEx, void* address, unsigned int size, unsigned short flags); -EXPORT_DECL(void *, MEMDestroyExpHeap, int heap); -EXPORT_DECL(void, MEMFreeToExpHeap, int heap, void* ptr); +EXPORT_DECL(s32, MEMGetBaseHeapHandle, s32 mem_arena); +EXPORT_DECL(u32, MEMGetAllocatableSizeForFrmHeapEx, s32 heap, s32 align); +EXPORT_DECL(void *, MEMAllocFromFrmHeapEx, s32 heap, u32 size, s32 align); +EXPORT_DECL(void, MEMFreeToFrmHeap, s32 heap, s32 mode); +EXPORT_DECL(void *, MEMAllocFromExpHeapEx, s32 heap, u32 size, s32 align); +EXPORT_DECL(s32 , MEMCreateExpHeapEx, void* address, u32 size, unsigned short flags); +EXPORT_DECL(void *, MEMDestroyExpHeap, s32 heap); +EXPORT_DECL(void, MEMFreeToExpHeap, s32 heap, void* ptr); +EXPORT_DECL(void *, OSAllocFromSystem, int size, int alignment); +EXPORT_DECL(void, OSFreeToSystem, void *addr); +EXPORT_DECL(int, OSIsAddressValid, void *ptr); //!---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- //! MCP functions //!---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -EXPORT_DECL(int, MCP_Open, void); -EXPORT_DECL(int, MCP_Close, int handle); -EXPORT_DECL(int, MCP_TitleCount, int handle); -EXPORT_DECL(int, MCP_TitleList, int handle, int *res, void *data, int count); -EXPORT_DECL(int, MCP_GetOwnTitleInfo, int handle, void * data); +EXPORT_DECL(s32, MCP_Open, void); +EXPORT_DECL(s32, MCP_Close, s32 handle); +EXPORT_DECL(s32, MCP_TitleCount, s32 handle); +EXPORT_DECL(s32, MCP_TitleList, s32 handle, s32 *res, void *data, s32 count); +EXPORT_DECL(s32, MCP_GetOwnTitleInfo, s32 handle, void * data); //!---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- //! Loader functions (not real rpl) //!---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -EXPORT_DECL(int, LiWaitIopComplete, int unknown_syscall_arg_r3, int * remaining_bytes); -EXPORT_DECL(int, LiWaitIopCompleteWithInterrupts, int unknown_syscall_arg_r3, int * remaining_bytes); +EXPORT_DECL(s32, LiWaitIopComplete, s32 unknown_syscall_arg_r3, s32 * remaining_bytes); +EXPORT_DECL(s32, LiWaitIopCompleteWithInterrupts, s32 unknown_syscall_arg_r3, s32 * remaining_bytes); EXPORT_DECL(void, addr_LiWaitOneChunk, void); EXPORT_DECL(void, addr_sgIsLoadingBuffer, void); EXPORT_DECL(void, addr_gDynloadInitialized, void); @@ -128,40 +137,77 @@ EXPORT_DECL(void, addr_PrepareTitle_hook, void); //!---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- //! Other function addresses //!---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -EXPORT_DECL(void, DCInvalidateRange, void *buffer, uint32_t length); +EXPORT_DECL(void, DCInvalidateRange, void *buffer, u32 length); //!---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- //! Energy Saver functions //!---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- //Burn-in Reduction -EXPORT_DECL(int, IMEnableDim,void); -EXPORT_DECL(int, IMDisableDim,void); -EXPORT_DECL(int, IMIsDimEnabled,int * result); +EXPORT_DECL(s32, IMEnableDim,void); +EXPORT_DECL(s32, IMDisableDim,void); +EXPORT_DECL(s32, IMIsDimEnabled,s32 * result); //Auto power down -EXPORT_DECL(int, IMEnableAPD,void); -EXPORT_DECL(int, IMDisableAPD,void); -EXPORT_DECL(int, IMIsAPDEnabled,int * result); -EXPORT_DECL(int, IMIsAPDEnabledBySysSettings,int * result); +EXPORT_DECL(s32, IMEnableAPD,void); +EXPORT_DECL(s32, IMDisableAPD,void); +EXPORT_DECL(s32, IMIsAPDEnabled,s32 * result); +EXPORT_DECL(s32, IMIsAPDEnabledBySysSettings,s32 * result); +EXPORT_DECL(s32, OSSendAppSwitchRequest,s32 param,void* unknown1,void* unknown2); + +//!---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +//! IOS functions +//!---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + +EXPORT_DECL(s32, IOS_Ioctl,s32 fd, u32 request, void *input_buffer,u32 input_buffer_len, void *output_buffer, u32 output_buffer_len); +EXPORT_DECL(s32, IOS_IoctlAsync,s32 fd, u32 request, void *input_buffer,u32 input_buffer_len, void *output_buffer, u32 output_buffer_len, void *cb, void *cbarg); +EXPORT_DECL(s32, IOS_Open,char *path, u32 mode); +EXPORT_DECL(s32, IOS_Close,s32 fd); + +void _os_find_export(u32 handle, const char *funcName, void *funcPointer) +{ + OSDynLoad_FindExport(handle, 0, funcName, funcPointer); + + if(!*(u32 *)funcPointer) { + /* + * This is effectively OSFatal("Function %s is NULL", funcName), + * but we can't rely on any library functions like snprintf or + * strcpy at this point. + * + * Buffer bounds are not checked. Beware! + */ + char buf[256], *bufp = buf; + const char a[] = "Function ", b[] = " is NULL", *p; + unsigned int i; + + for (i = 0; i < sizeof(a) - 1; i++) + *bufp++ = a[i]; + + for (p = funcName; *p; p++) + *bufp++ = *p; + + for (i = 0; i < sizeof(b) - 1; i++) + *bufp++ = b[i]; + + *bufp++ = '\0'; + + OSFatal(buf); + } +} -EXPORT_DECL(int, IOS_Ioctl,int fd, unsigned int request, void *input_buffer,unsigned int input_buffer_len, void *output_buffer, unsigned int output_buffer_len); -EXPORT_DECL(int, IOS_IoctlAsync,int fd, unsigned int request, void *input_buffer,unsigned int input_buffer_len, void *output_buffer, unsigned int output_buffer_len, void *cb, void *cbarg); -EXPORT_DECL(int, IOS_Open,char *path, unsigned int mode); -EXPORT_DECL(int, IOS_Close,int fd); void InitAcquireOS(void) { - //!---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + //!---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- //! Lib handle functions //!---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- - EXPORT_FUNC_WRITE(OSDynLoad_Acquire, (int (*)(const char*, unsigned *))OS_SPECIFICS->addr_OSDynLoad_Acquire); - EXPORT_FUNC_WRITE(OSDynLoad_FindExport, (int (*)(u32, int, const char *, void *))OS_SPECIFICS->addr_OSDynLoad_FindExport); + EXPORT_FUNC_WRITE(OSDynLoad_Acquire, (s32 (*)(const char*, unsigned *))OS_SPECIFICS->addr_OSDynLoad_Acquire); + EXPORT_FUNC_WRITE(OSDynLoad_FindExport, (s32 (*)(u32, s32, const char *, void *))OS_SPECIFICS->addr_OSDynLoad_FindExport); OSDynLoad_Acquire("coreinit.rpl", &coreinit_handle); } void InitOSFunctionPointers(void) { - unsigned int *funcPointer = 0; + u32 *funcPointer = 0; InitAcquireOS(); @@ -171,6 +217,10 @@ void InitOSFunctionPointers(void) OS_FIND_EXPORT(coreinit_handle, OSGetSecurityLevel); OS_FIND_EXPORT(coreinit_handle, OSForceFullRelaunch); //!---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + //! Shared Data functions + //!---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + OS_FIND_EXPORT(coreinit_handle, OSGetSharedData); + //!---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- //! System functions //!---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- OS_FIND_EXPORT(coreinit_handle, OSFatal); @@ -193,12 +243,14 @@ void InitOSFunctionPointers(void) OS_FIND_EXPORT(coreinit_handle, OSScreenFlipBuffersEx); OS_FIND_EXPORT(coreinit_handle, OSScreenPutFontEx); OS_FIND_EXPORT(coreinit_handle, OSScreenEnableEx); + OS_FIND_EXPORT(coreinit_handle, OSScreenPutPixelEx); //!---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- //! Thread functions //!---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- OS_FIND_EXPORT(coreinit_handle, OSCreateThread); OS_FIND_EXPORT(coreinit_handle, OSResumeThread); OS_FIND_EXPORT(coreinit_handle, OSSuspendThread); + OS_FIND_EXPORT(coreinit_handle, OSExitThread); OS_FIND_EXPORT(coreinit_handle, OSIsThreadTerminated); OS_FIND_EXPORT(coreinit_handle, OSIsThreadSuspended); OS_FIND_EXPORT(coreinit_handle, OSJoinThread); @@ -240,6 +292,9 @@ void InitOSFunctionPointers(void) OS_FIND_EXPORT(coreinit_handle, MEMCreateExpHeapEx); OS_FIND_EXPORT(coreinit_handle, MEMDestroyExpHeap); OS_FIND_EXPORT(coreinit_handle, MEMFreeToExpHeap); + OS_FIND_EXPORT(coreinit_handle, OSAllocFromSystem); + OS_FIND_EXPORT(coreinit_handle, OSFreeToSystem); + OS_FIND_EXPORT(coreinit_handle, OSIsAddressValid); //!---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- //! Other function addresses @@ -259,6 +314,11 @@ void InitOSFunctionPointers(void) OS_FIND_EXPORT(coreinit_handle, IMIsAPDEnabled); OS_FIND_EXPORT(coreinit_handle, IMIsAPDEnabledBySysSettings); + OS_FIND_EXPORT(coreinit_handle, OSSendAppSwitchRequest); + + //!---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + //! IOS functions + //!---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- OS_FIND_EXPORT(coreinit_handle, IOS_Ioctl); OS_FIND_EXPORT(coreinit_handle, IOS_IoctlAsync); OS_FIND_EXPORT(coreinit_handle, IOS_Open); @@ -267,75 +327,75 @@ void InitOSFunctionPointers(void) //!---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- //! Special non library functions //!---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- - if(OS_FIRMWARE == 532 || OS_FIRMWARE == 540) + if(OS_FIRMWARE == 550) { - EXPORT_FUNC_WRITE(LiWaitIopComplete, (int (*)(int, int *))0x0100FFA4); // loader.elf - EXPORT_FUNC_WRITE(LiWaitIopCompleteWithInterrupts, (int (*)(int, int *))0x0100FE90); // loader.elf - EXPORT_FUNC_WRITE(addr_LiWaitOneChunk, (int (*)(int, int *))0x010007EC); // loader.elf - EXPORT_FUNC_WRITE(addr_PrepareTitle_hook, (int (*)(int, int *))0xFFF18558); // kernel.elf + EXPORT_FUNC_WRITE(LiWaitIopComplete, (s32 (*)(s32, s32 *))0x01010180); + EXPORT_FUNC_WRITE(LiWaitIopCompleteWithInterrupts, (s32 (*)(s32, s32 *))0x0101006C); + EXPORT_FUNC_WRITE(addr_LiWaitOneChunk, (s32 (*)(s32, s32 *))0x0100080C); + EXPORT_FUNC_WRITE(addr_PrepareTitle_hook, (s32 (*)(s32, s32 *))0xFFF184E4); - EXPORT_FUNC_WRITE(addr_sgIsLoadingBuffer, (int (*)(int, int *))0xEFE19D00); // loader.elf - EXPORT_FUNC_WRITE(addr_gDynloadInitialized, (int (*)(int, int *))0xEFE13C3C); // loader.elf + EXPORT_FUNC_WRITE(addr_sgIsLoadingBuffer, (s32 (*)(s32, s32 *))0xEFE19E80); + EXPORT_FUNC_WRITE(addr_gDynloadInitialized, (s32 (*)(s32, s32 *))0xEFE13DBC); + } + else if(OS_FIRMWARE == 532 || OS_FIRMWARE == 540) + { + EXPORT_FUNC_WRITE(LiWaitIopComplete, (s32 (*)(s32, s32 *))0x0100FFA4); // loader.elf + EXPORT_FUNC_WRITE(LiWaitIopCompleteWithInterrupts, (s32 (*)(s32, s32 *))0x0100FE90); // loader.elf + EXPORT_FUNC_WRITE(addr_LiWaitOneChunk, (s32 (*)(s32, s32 *))0x010007EC); // loader.elf + EXPORT_FUNC_WRITE(addr_PrepareTitle_hook, (s32 (*)(s32, s32 *))0xFFF18558); // kernel.elf + + EXPORT_FUNC_WRITE(addr_sgIsLoadingBuffer, (s32 (*)(s32, s32 *))0xEFE19D00); // loader.elf + EXPORT_FUNC_WRITE(addr_gDynloadInitialized, (s32 (*)(s32, s32 *))0xEFE13C3C); // loader.elf } else if(OS_FIRMWARE == 500 || OS_FIRMWARE == 510) { - EXPORT_FUNC_WRITE(LiWaitIopComplete, (int (*)(int, int *))0x0100FBC4); - EXPORT_FUNC_WRITE(LiWaitIopCompleteWithInterrupts, (int (*)(int, int *))0x0100FAB0); - EXPORT_FUNC_WRITE(addr_LiWaitOneChunk, (int (*)(int, int *))0x010007EC); - EXPORT_FUNC_WRITE(addr_PrepareTitle_hook, (int (*)(int, int *))0xFFF18534); + EXPORT_FUNC_WRITE(LiWaitIopComplete, (s32 (*)(s32, s32 *))0x0100FBC4); + EXPORT_FUNC_WRITE(LiWaitIopCompleteWithInterrupts, (s32 (*)(s32, s32 *))0x0100FAB0); + EXPORT_FUNC_WRITE(addr_LiWaitOneChunk, (s32 (*)(s32, s32 *))0x010007EC); + EXPORT_FUNC_WRITE(addr_PrepareTitle_hook, (s32 (*)(s32, s32 *))0xFFF18534); - EXPORT_FUNC_WRITE(addr_sgIsLoadingBuffer, (int (*)(int, int *))0xEFE19D00); - EXPORT_FUNC_WRITE(addr_gDynloadInitialized, (int (*)(int, int *))0xEFE13C3C); + EXPORT_FUNC_WRITE(addr_sgIsLoadingBuffer, (s32 (*)(s32, s32 *))0xEFE19D00); + EXPORT_FUNC_WRITE(addr_gDynloadInitialized, (s32 (*)(s32, s32 *))0xEFE13C3C); } else if(OS_FIRMWARE == 410) { - EXPORT_FUNC_WRITE(LiWaitIopComplete, (int (*)(int, int *))0x0100F78C); - EXPORT_FUNC_WRITE(LiWaitIopCompleteWithInterrupts, (int (*)(int, int *))0x0100F678); - EXPORT_FUNC_WRITE(addr_LiWaitOneChunk, (int (*)(int, int *))0x010007F8); - EXPORT_FUNC_WRITE(addr_PrepareTitle_hook, (int (*)(int, int *))0xFFF166DC); + EXPORT_FUNC_WRITE(LiWaitIopComplete, (s32 (*)(s32, s32 *))0x0100F78C); + EXPORT_FUNC_WRITE(LiWaitIopCompleteWithInterrupts, (s32 (*)(s32, s32 *))0x0100F678); + EXPORT_FUNC_WRITE(addr_LiWaitOneChunk, (s32 (*)(s32, s32 *))0x010007F8); + EXPORT_FUNC_WRITE(addr_PrepareTitle_hook, (s32 (*)(s32, s32 *))0xFFF166DC); - EXPORT_FUNC_WRITE(addr_sgIsLoadingBuffer, (int (*)(int, int *))0xEFE19CC0); - EXPORT_FUNC_WRITE(addr_gDynloadInitialized, (int (*)(int, int *))0xEFE13BFC); + EXPORT_FUNC_WRITE(addr_sgIsLoadingBuffer, (s32 (*)(s32, s32 *))0xEFE19CC0); + EXPORT_FUNC_WRITE(addr_gDynloadInitialized, (s32 (*)(s32, s32 *))0xEFE13BFC); } else if(OS_FIRMWARE == 400) //same for 402 and 403 { - EXPORT_FUNC_WRITE(LiWaitIopComplete, (int (*)(int, int *))0x0100F78C); - EXPORT_FUNC_WRITE(LiWaitIopCompleteWithInterrupts, (int (*)(int, int *))0x0100F678); - EXPORT_FUNC_WRITE(addr_LiWaitOneChunk, (int (*)(int, int *))0x010007F8); - EXPORT_FUNC_WRITE(addr_PrepareTitle_hook, (int (*)(int, int *))0xFFF15E70); + EXPORT_FUNC_WRITE(LiWaitIopComplete, (s32 (*)(s32, s32 *))0x0100F78C); + EXPORT_FUNC_WRITE(LiWaitIopCompleteWithInterrupts, (s32 (*)(s32, s32 *))0x0100F678); + EXPORT_FUNC_WRITE(addr_LiWaitOneChunk, (s32 (*)(s32, s32 *))0x010007F8); + EXPORT_FUNC_WRITE(addr_PrepareTitle_hook, (s32 (*)(s32, s32 *))0xFFF15E70); - EXPORT_FUNC_WRITE(addr_sgIsLoadingBuffer, (int (*)(int, int *))0xEFE19CC0); - EXPORT_FUNC_WRITE(addr_gDynloadInitialized, (int (*)(int, int *))0xEFE13BFC); - } - else if(OS_FIRMWARE == 550) - { - EXPORT_FUNC_WRITE(LiWaitIopComplete, (int (*)(int, int *))0x01010180); - EXPORT_FUNC_WRITE(LiWaitIopCompleteWithInterrupts, (int (*)(int, int *))0x0101006C); - EXPORT_FUNC_WRITE(addr_LiWaitOneChunk, (int (*)(int, int *))0x0100080C); - EXPORT_FUNC_WRITE(addr_PrepareTitle_hook, (int (*)(int, int *))0xFFF184E4); - - EXPORT_FUNC_WRITE(addr_sgIsLoadingBuffer, (int (*)(int, int *))0xEFE19E80); - EXPORT_FUNC_WRITE(addr_gDynloadInitialized, (int (*)(int, int *))0xEFE13DBC); + EXPORT_FUNC_WRITE(addr_sgIsLoadingBuffer, (s32 (*)(s32, s32 *))0xEFE19CC0); + EXPORT_FUNC_WRITE(addr_gDynloadInitialized, (s32 (*)(s32, s32 *))0xEFE13BFC); } else if(OS_FIRMWARE == 310) { - EXPORT_FUNC_WRITE(LiWaitIopComplete, (int (*)(int, int *))0x0100C4E4); - EXPORT_FUNC_WRITE(LiWaitIopCompleteWithInterrupts, (int (*)(int, int *))0x0100C3D4); - EXPORT_FUNC_WRITE(addr_LiWaitOneChunk, (int (*)(int, int *))0x010004D8); - EXPORT_FUNC_WRITE(addr_PrepareTitle_hook, (int (*)(int, int *))0xFFF15A0C); + EXPORT_FUNC_WRITE(LiWaitIopComplete, (s32 (*)(s32, s32 *))0x0100C4E4); + EXPORT_FUNC_WRITE(LiWaitIopCompleteWithInterrupts, (s32 (*)(s32, s32 *))0x0100C3D4); + EXPORT_FUNC_WRITE(addr_LiWaitOneChunk, (s32 (*)(s32, s32 *))0x010004D8); + EXPORT_FUNC_WRITE(addr_PrepareTitle_hook, (s32 (*)(s32, s32 *))0xFFF15A0C); - EXPORT_FUNC_WRITE(addr_sgIsLoadingBuffer, (int (*)(int, int *))0xEFE19340); - EXPORT_FUNC_WRITE(addr_gDynloadInitialized, (int (*)(int, int *))0xEFE1329C); + EXPORT_FUNC_WRITE(addr_sgIsLoadingBuffer, (s32 (*)(s32, s32 *))0xEFE19340); + EXPORT_FUNC_WRITE(addr_gDynloadInitialized, (s32 (*)(s32, s32 *))0xEFE1329C); } else if(OS_FIRMWARE == 300) { - EXPORT_FUNC_WRITE(LiWaitIopComplete, (int (*)(int, int *))0x0100C4E4); - EXPORT_FUNC_WRITE(LiWaitIopCompleteWithInterrupts, (int (*)(int, int *))0x0100C3D4); - EXPORT_FUNC_WRITE(addr_LiWaitOneChunk, (int (*)(int, int *))0x010004D8); - EXPORT_FUNC_WRITE(addr_PrepareTitle_hook, (int (*)(int, int *))0xFFF15974); + EXPORT_FUNC_WRITE(LiWaitIopComplete, (s32 (*)(s32, s32 *))0x0100C4E4); + EXPORT_FUNC_WRITE(LiWaitIopCompleteWithInterrupts, (s32 (*)(s32, s32 *))0x0100C3D4); + EXPORT_FUNC_WRITE(addr_LiWaitOneChunk, (s32 (*)(s32, s32 *))0x010004D8); + EXPORT_FUNC_WRITE(addr_PrepareTitle_hook, (s32 (*)(s32, s32 *))0xFFF15974); - EXPORT_FUNC_WRITE(addr_sgIsLoadingBuffer, (int (*)(int, int *))0xEFE19340); - EXPORT_FUNC_WRITE(addr_gDynloadInitialized, (int (*)(int, int *))0xEFE1329C); + EXPORT_FUNC_WRITE(addr_sgIsLoadingBuffer, (s32 (*)(s32, s32 *))0xEFE19340); + EXPORT_FUNC_WRITE(addr_gDynloadInitialized, (s32 (*)(s32, s32 *))0xEFE1329C); } else { diff --git a/src/dynamic_libs/os_functions.h b/src/dynamic_libs/os_functions.h index 3d58932..23ff4a3 100644 --- a/src/dynamic_libs/os_functions.h +++ b/src/dynamic_libs/os_functions.h @@ -37,8 +37,9 @@ extern "C" { #define MILLISECS_TO_TICKS(msec) (SECS_TO_TICKS(msec) / 1000) #define MICROSECS_TO_TICKS(usec) (SECS_TO_TICKS(usec) / 1000000) -#define usleep(usecs) OSSleepTicks(MICROSECS_TO_TICKS(usecs)) -#define sleep(secs) OSSleepTicks(SECS_TO_TICKS(secs)) +//To avoid conflicts with the unistd.h +#define os_usleep(usecs) OSSleepTicks(MICROSECS_TO_TICKS(usecs)) +#define os_sleep(secs) OSSleepTicks(SECS_TO_TICKS(secs)) #define FLUSH_DATA_BLOCK(addr) asm volatile("dcbf 0, %0; sync" : : "r"(((addr) & ~31))) #define INVAL_DATA_BLOCK(addr) asm volatile("dcbi 0, %0; sync" : : "r"(((addr) & ~31))) @@ -49,48 +50,44 @@ extern "C" { #define EXPORT_FUNC_WRITE(func, val) *(u32*)(((u32)&func) + 0) = (u32)val -#define OS_FIND_EXPORT(handle, func) funcPointer = 0; \ - OSDynLoad_FindExport(handle, 0, # func, &funcPointer); \ - if(!funcPointer) \ - OSFatal("Function " # func " is NULL"); \ +#define OS_FIND_EXPORT(handle, func) _os_find_export(handle, # func, &funcPointer); \ EXPORT_FUNC_WRITE(func, funcPointer); #define OS_FIND_EXPORT_EX(handle, func, func_p) \ - funcPointer = 0; \ - OSDynLoad_FindExport(handle, 0, # func, &funcPointer); \ - if(!funcPointer) \ - OSFatal("Function " # func " is NULL"); \ + _os_find_export(handle, # func, &funcPointer); \ EXPORT_FUNC_WRITE(func_p, funcPointer); #define OS_MUTEX_SIZE 44 /* Handle for coreinit */ -extern unsigned int coreinit_handle; -void InitOSFunctionPointers(void); -void InitAcquireOS(void); +extern u32 coreinit_handle; +extern void _os_find_export(u32 handle, const char *funcName, void *funcPointer); +extern void InitAcquireOS(void); +extern void InitOSFunctionPointers(void); //!---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- //! Lib handle functions //!---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -extern int (* OSDynLoad_Acquire)(const char* rpl, u32 *handle); -extern int (* OSDynLoad_FindExport)(u32 handle, int isdata, const char *symbol, void *address); +extern s32 (* OSDynLoad_Acquire)(const char* rpl, u32 *handle); +extern s32 (* OSDynLoad_FindExport)(u32 handle, s32 isdata, const char *symbol, void *address); //!---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- //! Security functions //!---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -extern int (* OSGetSecurityLevel)(void); -extern int (* OSForceFullRelaunch)(void); +extern s32 (* OSGetSecurityLevel)(void); +extern s32 (* OSForceFullRelaunch)(void); //!---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- //! Thread functions //!---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -extern int (* OSCreateThread)(void *thread, s32 (*callback)(s32, void*), s32 argc, void *args, u32 stack, u32 stack_size, s32 priority, u32 attr); -extern int (* OSResumeThread)(void *thread); -extern int (* OSSuspendThread)(void *thread); -extern int (* OSIsThreadTerminated)(void *thread); -extern int (* OSIsThreadSuspended)(void *thread); -extern int (* OSJoinThread)(void * thread, int * ret_val); -extern int (* OSSetThreadPriority)(void * thread, int priority); +extern s32 (* OSCreateThread)(void *thread, s32 (*callback)(s32, void*), s32 argc, void *args, u32 stack, u32 stack_size, s32 priority, u32 attr); +extern s32 (* OSResumeThread)(void *thread); +extern s32 (* OSSuspendThread)(void *thread); +extern void (*OSExitThread)(u32 result); +extern s32 (* OSIsThreadTerminated)(void *thread); +extern s32 (* OSIsThreadSuspended)(void *thread); +extern s32 (* OSJoinThread)(void * thread, s32 * ret_val); +extern s32 (* OSSetThreadPriority)(void * thread, s32 priority); extern void (* OSDetachThread)(void * thread); extern void (* OSSleepTicks)(u64 ticks); extern u64 (* OSGetTick)(void); @@ -103,47 +100,72 @@ extern void (*OSTicksToCalendarTime)(u64 time, OSCalendarTime *calendarTime); extern void (* OSInitMutex)(void* mutex); extern void (* OSLockMutex)(void* mutex); extern void (* OSUnlockMutex)(void* mutex); -extern int (* OSTryLockMutex)(void* mutex); +extern s32 (* OSTryLockMutex)(void* mutex); + +//!---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +//! Shared Data functions +//!---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +extern bool (* OSGetSharedData)(u32 type, u32 unk_r4, u8 *addr, u32 *size); //!---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- //! System functions //!---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- extern u64 (* OSGetTitleID)(void); -extern void (* OSGetArgcArgv)(int* argc, char*** argv); +extern void (* OSGetArgcArgv)(s32* argc, char*** argv); extern void (* __Exit)(void); extern void (* OSFatal)(const char* msg); extern void (* DCFlushRange)(const void *addr, u32 length); extern void (* DCStoreRange)(const void *addr, u32 length); extern void (* ICInvalidateRange)(const void *addr, u32 length); extern void* (* OSEffectiveToPhysical)(const void*); -extern int (* __os_snprintf)(char* s, int n, const char * format, ...); -extern int * (* __gh_errno_ptr)(void); +extern s32 (* __os_snprintf)(char* s, s32 n, const char * format, ...); +extern s32 * (* __gh_errno_ptr)(void); extern void (*OSScreenInit)(void); -extern unsigned int (*OSScreenGetBufferSizeEx)(unsigned int bufferNum); -extern int (*OSScreenSetBufferEx)(unsigned int bufferNum, void * addr); -extern int (*OSScreenClearBufferEx)(unsigned int bufferNum, unsigned int temp); -extern int (*OSScreenFlipBuffersEx)(unsigned int bufferNum); -extern int (*OSScreenPutFontEx)(unsigned int bufferNum, unsigned int posX, unsigned int posY, const char * buffer); -extern int (*OSScreenEnableEx)(unsigned int bufferNum, int enable); +extern u32 (*OSScreenGetBufferSizeEx)(u32 bufferNum); +extern s32 (*OSScreenSetBufferEx)(u32 bufferNum, void * addr); +extern s32 (*OSScreenClearBufferEx)(u32 bufferNum, u32 temp); +extern s32 (*OSScreenFlipBuffersEx)(u32 bufferNum); +extern s32 (*OSScreenPutFontEx)(u32 bufferNum, u32 posX, u32 posY, const char * buffer); +extern s32 (*OSScreenEnableEx)(u32 bufferNum, s32 enable); +extern u32 (*OSScreenPutPixelEx)(u32 bufferNum, u32 posX, u32 posY, u32 color); typedef unsigned char (*exception_callback)(void * interruptedContext); extern void (* OSSetExceptionCallback)(u8 exceptionType, exception_callback newCallback); +//!---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +//! Memory functions +//!---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +extern u32 *pMEMAllocFromDefaultHeapEx; +extern u32 *pMEMAllocFromDefaultHeap; +extern u32 *pMEMFreeToDefaultHeap; + +extern s32 (* MEMGetBaseHeapHandle)(s32 mem_arena); +extern u32 (* MEMGetAllocatableSizeForFrmHeapEx)(s32 heap, s32 align); +extern void* (* MEMAllocFromFrmHeapEx)(s32 heap, u32 size, s32 align); +extern void (* MEMFreeToFrmHeap)(s32 heap, s32 mode); +extern void *(* MEMAllocFromExpHeapEx)(s32 heap, u32 size, s32 align); +extern s32 (* MEMCreateExpHeapEx)(void* address, u32 size, unsigned short flags); +extern void *(* MEMDestroyExpHeap)(s32 heap); +extern void (* MEMFreeToExpHeap)(s32 heap, void* ptr); +extern void* (* OSAllocFromSystem)(int size, int alignment); +extern void (* OSFreeToSystem)(void *addr); +extern int (* OSIsAddressValid)(void *ptr); + //!---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- //! MCP functions //!---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -extern int (* MCP_Open)(void); -extern int (* MCP_Close)(int handle); -extern int (* MCP_TitleCount)(int handle); -extern int (* MCP_TitleList)(int handle, int *res, void *data, int count); -extern int (* MCP_GetOwnTitleInfo)(int handle, void * data); +extern s32 (* MCP_Open)(void); +extern s32 (* MCP_Close)(s32 handle); +extern s32 (* MCP_TitleCount)(s32 handle); +extern s32 (* MCP_TitleList)(s32 handle, s32 *res, void *data, s32 count); +extern s32 (* MCP_GetOwnTitleInfo)(s32 handle, void * data); //!---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- //! LOADER functions //!---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -extern int (* LiWaitIopComplete)(int unknown_syscall_arg_r3, int * remaining_bytes); -extern int (* LiWaitIopCompleteWithInterrupts)(int unknown_syscall_arg_r3, int * remaining_bytes); +extern s32 (* LiWaitIopComplete)(s32 unknown_syscall_arg_r3, s32 * remaining_bytes); +extern s32 (* LiWaitIopCompleteWithInterrupts)(s32 unknown_syscall_arg_r3, s32 * remaining_bytes); extern void (* addr_LiWaitOneChunk)(void); extern void (* addr_sgIsLoadingBuffer)(void); extern void (* addr_gDynloadInitialized)(void); @@ -156,25 +178,32 @@ extern void (* addr_PrepareTitle_hook)(void); //!---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- //! Other function addresses //!---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -extern void (*DCInvalidateRange)(void *buffer, uint32_t length); +extern void (*DCInvalidateRange)(void *buffer, u32 length); //!---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- //! Energy Saver functions //!---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- ////Burn-in Reduction -extern int (*IMEnableDim)(void); -extern int (*IMDisableDim)(void); -extern int (*IMIsDimEnabled)(int * result); +extern s32 (*IMEnableDim)(void); +extern s32 (*IMDisableDim)(void); +extern s32 (*IMIsDimEnabled)(s32 * result); //Auto power down -extern int (*IMEnableAPD)(void); -extern int (*IMDisableAPD)(void); -extern int (*IMIsAPDEnabled)(int * result); -extern int (*IMIsAPDEnabledBySysSettings)(int * result); +extern s32 (*IMEnableAPD)(void); +extern s32 (*IMDisableAPD)(void); +extern s32 (*IMIsAPDEnabled)(s32 * result); +extern s32 (*IMIsAPDEnabledBySysSettings)(s32 * result); + +extern s32 (*OSSendAppSwitchRequest)(s32 param,void* unknown1,void* unknown2); + +//!---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +//! IOS functions +//!---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + +extern s32 (*IOS_Ioctl)(s32 fd, u32 request, void *input_buffer,u32 input_buffer_len, void *output_buffer, u32 output_buffer_len); +extern s32 (*IOS_IoctlAsync)(s32 fd, u32 request, void *input_buffer,u32 input_buffer_len, void *output_buffer, u32 output_buffer_len, void *cb, void *cbarg); +extern s32 (*IOS_Open)(char *path, u32 mode); +extern s32 (*IOS_Close)(s32 fd); -extern int (*IOS_Ioctl)(int fd, unsigned int request, void *input_buffer,unsigned int input_buffer_len, void *output_buffer, unsigned int output_buffer_len); -extern int (*IOS_IoctlAsync)(int fd, unsigned int request, void *input_buffer,unsigned int input_buffer_len, void *output_buffer, unsigned int output_buffer_len, void *cb, void *cbarg); -extern int (*IOS_Open)(char *path, unsigned int mode); -extern int (*IOS_Close)(int fd); #ifdef __cplusplus } #endif diff --git a/src/dynamic_libs/padscore_functions.c b/src/dynamic_libs/padscore_functions.c index f7ca8e9..8f774dc 100644 --- a/src/dynamic_libs/padscore_functions.c +++ b/src/dynamic_libs/padscore_functions.c @@ -24,7 +24,7 @@ #include "os_functions.h" #include "padscore_functions.h" -unsigned int padscore_handle __attribute__((section(".data"))) = 0; +u32 padscore_handle __attribute__((section(".data"))) = 0; EXPORT_DECL(void, KPADInit, void); EXPORT_DECL(void, WPADInit, void); @@ -43,7 +43,7 @@ void InitAcquirePadScore(void) void InitPadScoreFunctionPointers(void) { - unsigned int *funcPointer = 0; + u32 *funcPointer = 0; InitAcquirePadScore(); OS_FIND_EXPORT(padscore_handle, WPADInit); diff --git a/src/dynamic_libs/padscore_functions.h b/src/dynamic_libs/padscore_functions.h index 5b000b1..f7f07dc 100644 --- a/src/dynamic_libs/padscore_functions.h +++ b/src/dynamic_libs/padscore_functions.h @@ -30,10 +30,20 @@ extern "C" { #include "dynamic_libs/vpad_functions.h" -extern unsigned int padscore_handle; +extern u32 padscore_handle; #include +#define WPAD_EXT_CORE 0 +#define WPAD_EXT_NUNCHUK 1 +#define WPAD_EXT_CLASSIC 2 +#define WPAD_EXT_MPLUS 5 +#define WPAD_EXT_MPLUS_NUNCHUK 6 +#define WPAD_EXT_MPLUS_CLASSIC 7 +#define WPAD_EXT_PRO_CONTROLLER 31 + +#define WPAD_FMT_PRO_CONTROLLER 22 + #define WPAD_BUTTON_LEFT 0x0001 #define WPAD_BUTTON_RIGHT 0x0002 #define WPAD_BUTTON_DOWN 0x0004 @@ -140,17 +150,36 @@ typedef struct _KPADData f32 lstick_y; f32 rstick_x; f32 rstick_y; - int charging; - int wired; + s32 charging; + s32 wired; } pro; u32 unused_6[20]; }; u32 unused_7[16]; } KPADData; + +typedef struct WPADReadData_ { + u8 unknown[40]; + u8 dev; + u8 err; + u8 unknown1[2]; + u32 buttons; + s16 l_stick_x; + s16 l_stick_y; + s16 r_stick_x; + s16 r_stick_y; + u8 unknown2[8]; + u8 fmt; +}WPADReadData; + +typedef WPADReadData KPADUnifiedWpadData; + void InitPadScoreFunctionPointers(void); void InitAcquirePadScore(void); +typedef void (* wpad_sampling_callback_t)(s32 chan); +typedef void (* wpad_extension_callback_t)(s32 chan, s32 status); typedef void (* wpad_connect_callback_t)(s32 chan, s32 status); extern void (* KPADInit)(void); diff --git a/src/dynamic_libs/socket_functions.c b/src/dynamic_libs/socket_functions.c index de2c31f..06aa769 100644 --- a/src/dynamic_libs/socket_functions.c +++ b/src/dynamic_libs/socket_functions.c @@ -26,26 +26,26 @@ u32 hostIpAddress = 0; -unsigned int nsysnet_handle __attribute__((section(".data"))) = 0; +u32 nsysnet_handle __attribute__((section(".data"))) = 0; EXPORT_DECL(void, socket_lib_init, void); -EXPORT_DECL(int, socket, int domain, int type, int protocol); -EXPORT_DECL(int, socketclose, int s); -EXPORT_DECL(int, connect, int s, void *addr, int addrlen); -EXPORT_DECL(int, bind, s32 s,struct sockaddr *name,s32 namelen); -EXPORT_DECL(int, listen, s32 s,u32 backlog); -EXPORT_DECL(int, accept, s32 s,struct sockaddr *addr,s32 *addrlen); -EXPORT_DECL(int, send, int s, const void *buffer, int size, int flags); -EXPORT_DECL(int, recv, int s, void *buffer, int size, int flags); -EXPORT_DECL(int, recvfrom,int sockfd, void *buf, int len, int flags,struct sockaddr *src_addr, int *addrlen); -EXPORT_DECL(int, sendto, int s, const void *buffer, int size, int flags, const struct sockaddr *dest, int dest_len); -EXPORT_DECL(int, setsockopt, int s, int level, int optname, void *optval, int optlen); +EXPORT_DECL(s32, socket, s32 domain, s32 type, s32 protocol); +EXPORT_DECL(s32, socketclose, s32 s); +EXPORT_DECL(s32, connect, s32 s, void *addr, s32 addrlen); +EXPORT_DECL(s32, bind, s32 s,struct sockaddr *name,s32 namelen); +EXPORT_DECL(s32, listen, s32 s,u32 backlog); +EXPORT_DECL(s32, accept, s32 s,struct sockaddr *addr,s32 *addrlen); +EXPORT_DECL(s32, send, s32 s, const void *buffer, s32 size, s32 flags); +EXPORT_DECL(s32, recv, s32 s, void *buffer, s32 size, s32 flags); +EXPORT_DECL(s32, recvfrom,s32 sockfd, void *buf, s32 len, s32 flags,struct sockaddr *src_addr, s32 *addrlen); +EXPORT_DECL(s32, sendto, s32 s, const void *buffer, s32 size, s32 flags, const struct sockaddr *dest, s32 dest_len); +EXPORT_DECL(s32, setsockopt, s32 s, s32 level, s32 optname, void *optval, s32 optlen); EXPORT_DECL(char *, inet_ntoa, struct in_addr in); -EXPORT_DECL(int, inet_aton, const char *cp, struct in_addr *inp); +EXPORT_DECL(s32, inet_aton, const char *cp, struct in_addr *inp); -EXPORT_DECL(int, NSSLWrite, int connection, const void* buf, int len,int * written); -EXPORT_DECL(int, NSSLRead, int connection, const void* buf, int len,int * read); -EXPORT_DECL(int, NSSLCreateConnection, int context, const char* host, int hotlen,int options,int sock,int block); +EXPORT_DECL(s32, NSSLWrite, s32 connection, const void* buf, s32 len,s32 * written); +EXPORT_DECL(s32, NSSLRead, s32 connection, const void* buf, s32 len,s32 * read); +EXPORT_DECL(s32, NSSLCreateConnection, s32 context, const char* host, s32 hotlen,s32 options,s32 sock,s32 block); void InitAcquireSocket(void) { @@ -54,10 +54,21 @@ void InitAcquireSocket(void) void InitSocketFunctionPointers(void) { - unsigned int *funcPointer = 0; + u32 *funcPointer = 0; InitAcquireSocket(); + u32 nn_ac_handle; + s32(*ACInitialize)(); + s32(*ACGetStartupId) (u32 *id); + s32(*ACConnectWithConfigId) (u32 id); + s32(*ACGetAssignedAddress) (u32 * ip); + OSDynLoad_Acquire("nn_ac.rpl", &nn_ac_handle); + OSDynLoad_FindExport(nn_ac_handle, 0, "ACInitialize", &ACInitialize); + OSDynLoad_FindExport(nn_ac_handle, 0, "ACGetStartupId", &ACGetStartupId); + OSDynLoad_FindExport(nn_ac_handle, 0, "ACConnectWithConfigId",&ACConnectWithConfigId); + OSDynLoad_FindExport(nn_ac_handle, 0, "ACGetAssignedAddress",&ACGetAssignedAddress); + OS_FIND_EXPORT(nsysnet_handle, socket_lib_init); OS_FIND_EXPORT(nsysnet_handle, socket); OS_FIND_EXPORT(nsysnet_handle, socketclose); @@ -77,5 +88,11 @@ void InitSocketFunctionPointers(void) OS_FIND_EXPORT(nsysnet_handle, NSSLRead); OS_FIND_EXPORT(nsysnet_handle, NSSLCreateConnection); + u32 nn_startupid; + ACInitialize(); + ACGetStartupId(&nn_startupid); + ACConnectWithConfigId(nn_startupid); + ACGetAssignedAddress(&hostIpAddress); + socket_lib_init(); } diff --git a/src/dynamic_libs/socket_functions.h b/src/dynamic_libs/socket_functions.h index 1e4df1a..0ab78f7 100644 --- a/src/dynamic_libs/socket_functions.h +++ b/src/dynamic_libs/socket_functions.h @@ -28,7 +28,7 @@ extern "C" { #endif -extern unsigned int nsysnet_handle; +extern u32 nsysnet_handle; #include @@ -61,7 +61,7 @@ extern unsigned int nsysnet_handle; struct in_addr { - unsigned int s_addr; + u32 s_addr; }; struct sockaddr_in { short sin_family; @@ -81,25 +81,25 @@ void InitSocketFunctionPointers(void); void InitAcquireSocket(void); extern void (*socket_lib_init)(void); -extern int (*socket)(int domain, int type, int protocol); -extern int (*socketclose)(int s); -extern int (*connect)(int s, void *addr, int addrlen); -extern int (*bind)(s32 s,struct sockaddr *name,s32 namelen); -extern int (*listen)(s32 s,u32 backlog); -extern int (*accept)(s32 s,struct sockaddr *addr,s32 *addrlen); -extern int (*send)(int s, const void *buffer, int size, int flags); -extern int (*recv)(int s, void *buffer, int size, int flags); -extern int (*recvfrom)(int sockfd, void *buf, int len, int flags,struct sockaddr *src_addr, int *addrlen); +extern s32 (*socket)(s32 domain, s32 type, s32 protocol); +extern s32 (*socketclose)(s32 s); +extern s32 (*connect)(s32 s, void *addr, s32 addrlen); +extern s32 (*bind)(s32 s,struct sockaddr *name,s32 namelen); +extern s32 (*listen)(s32 s,u32 backlog); +extern s32 (*accept)(s32 s,struct sockaddr *addr,s32 *addrlen); +extern s32 (*send)(s32 s, const void *buffer, s32 size, s32 flags); +extern s32 (*recv)(s32 s, void *buffer, s32 size, s32 flags); +extern s32 (*recvfrom)(s32 sockfd, void *buf, s32 len, s32 flags,struct sockaddr *src_addr, s32 *addrlen); -extern int (*sendto)(int s, const void *buffer, int size, int flags, const struct sockaddr *dest, int dest_len); -extern int (*setsockopt)(int s, int level, int optname, void *optval, int optlen); +extern s32 (*sendto)(s32 s, const void *buffer, s32 size, s32 flags, const struct sockaddr *dest, s32 dest_len); +extern s32 (*setsockopt)(s32 s, s32 level, s32 optname, void *optval, s32 optlen); -extern int (* NSSLWrite)(int connection, const void* buf, int len,int * written); -extern int (* NSSLRead)(int connection, const void* buf, int len,int * read); -extern int (* NSSLCreateConnection)(int context, const char* host, int hotlen,int options,int sock,int block); +extern s32 (* NSSLWrite)(s32 connection, const void* buf, s32 len,s32 * written); +extern s32 (* NSSLRead)(s32 connection, const void* buf, s32 len,s32 * read); +extern s32 (* NSSLCreateConnection)(s32 context, const char* host, s32 hotlen,s32 options,s32 sock,s32 block); extern char * (*inet_ntoa)(struct in_addr in); -extern int (*inet_aton)(const char *cp, struct in_addr *inp); +extern s32 (*inet_aton)(const char *cp, struct in_addr *inp); #ifdef __cplusplus } diff --git a/src/dynamic_libs/sys_functions.c b/src/dynamic_libs/sys_functions.c index 2cd44b8..25720c5 100644 --- a/src/dynamic_libs/sys_functions.c +++ b/src/dynamic_libs/sys_functions.c @@ -23,14 +23,14 @@ ***************************************************************************/ #include "os_functions.h" - unsigned int sysapp_handle __attribute__((section(".data"))) = 0; +u32 sysapp_handle __attribute__((section(".data"))) = 0; -EXPORT_DECL(int, _SYSLaunchTitleByPathFromLauncher, const char* path, int len, int zero); -EXPORT_DECL(int, SYSRelaunchTitle, int argc, char** argv); -EXPORT_DECL(int, SYSLaunchMenu, void); -EXPORT_DECL(int, SYSCheckTitleExists, u64 titleId); -EXPORT_DECL(int, SYSLaunchTitle, u64 titleId); -EXPORT_DECL(int, SYSLaunchSettings, int unk); +EXPORT_DECL(s32, _SYSLaunchTitleByPathFromLauncher, const char* path, s32 len, s32 zero); +EXPORT_DECL(s32, SYSRelaunchTitle, s32 argc, char** argv); +EXPORT_DECL(s32, SYSLaunchMenu, void); +EXPORT_DECL(s32, SYSCheckTitleExists, u64 titleId); +EXPORT_DECL(s32, SYSLaunchTitle, u64 titleId); +EXPORT_DECL(s32, SYSLaunchSettings, s32 unk); void InitAcquireSys(void) { @@ -39,7 +39,7 @@ void InitAcquireSys(void) void InitSysFunctionPointers(void) { - unsigned int *funcPointer = 0; + u32 *funcPointer = 0; InitAcquireSys(); OS_FIND_EXPORT(sysapp_handle, _SYSLaunchTitleByPathFromLauncher); diff --git a/src/dynamic_libs/sys_functions.h b/src/dynamic_libs/sys_functions.h index 64fc2c7..8c66e78 100644 --- a/src/dynamic_libs/sys_functions.h +++ b/src/dynamic_libs/sys_functions.h @@ -28,17 +28,19 @@ extern "C" { #endif -extern unsigned int sysapp_handle; +#include + +extern u32 sysapp_handle; void InitSysFunctionPointers(void); void InitAcquireSys(void); -extern int(*_SYSLaunchTitleByPathFromLauncher)(const char* path, int len, int zero); -extern int (* SYSRelaunchTitle)(int argc, char** argv); +extern int(*_SYSLaunchTitleByPathFromLauncher)(const char* path, s32 len, s32 zero); +extern int (* SYSRelaunchTitle)(s32 argc, char** argv); extern int (* SYSLaunchMenu)(void); extern int (* SYSCheckTitleExists)(u64 titleId); extern int (* SYSLaunchTitle)(u64 titleId); -extern int (* SYSLaunchSettings)(int unk); +extern int (* SYSLaunchSettings)(s32 unk); #ifdef __cplusplus diff --git a/src/dynamic_libs/syshid_functions.c b/src/dynamic_libs/syshid_functions.c index 996d39d..b5dbca4 100644 --- a/src/dynamic_libs/syshid_functions.c +++ b/src/dynamic_libs/syshid_functions.c @@ -24,27 +24,27 @@ #include "os_functions.h" #include "syshid_functions.h" -unsigned int syshid_handle __attribute__((section(".data"))) = 0; +u32 syshid_handle __attribute__((section(".data"))) = 0; -EXPORT_DECL(int, HIDSetup,void); -EXPORT_DECL(int, HIDTeardown,void); +EXPORT_DECL(s32, HIDSetup,void); +EXPORT_DECL(s32, HIDTeardown,void); -EXPORT_DECL(int, HIDAddClient,HIDClient *p_client, HIDAttachCallback attach_callback); -EXPORT_DECL(int, HIDDelClient,HIDClient *p_client); +EXPORT_DECL(s32, HIDAddClient,HIDClient *p_client, HIDAttachCallback attach_callback); +EXPORT_DECL(s32, HIDDelClient,HIDClient *p_client); -EXPORT_DECL(int, HIDGetDescriptor,unsigned int handle,u8 descriptor_type,u8 descriptor_index, u16 language_id, unsigned char *p_buffer, unsigned int buffer_length, HIDCallback hc, void *p_user); -EXPORT_DECL(int, HIDSetDescriptor,unsigned int handle,u8 descriptor_type,u8 descriptor_index, u16 language_id, unsigned char *p_buffer, unsigned int buffer_length, HIDCallback hc, void *p_user); +EXPORT_DECL(s32, HIDGetDescriptor,u32 handle,u8 descriptor_type,u8 descriptor_index, u16 language_id, unsigned char *p_buffer, u32 buffer_length, HIDCallback hc, void *p_user); +EXPORT_DECL(s32, HIDSetDescriptor,u32 handle,u8 descriptor_type,u8 descriptor_index, u16 language_id, unsigned char *p_buffer, u32 buffer_length, HIDCallback hc, void *p_user); -EXPORT_DECL(int, HIDSetProtocol,unsigned int handle,u8 interface_index,u8 protocol, HIDCallback hc, void *p_user); -EXPORT_DECL(int, HIDGetProtocol,unsigned int handle,u8 interface_index,u8 * protocol, HIDCallback hc, void *p_user); +EXPORT_DECL(s32, HIDSetProtocol,u32 handle,u8 s32erface_index,u8 protocol, HIDCallback hc, void *p_user); +EXPORT_DECL(s32, HIDGetProtocol,u32 handle,u8 s32erface_index,u8 * protocol, HIDCallback hc, void *p_user); -EXPORT_DECL(int, HIDGetReport,u32 handle, u8 report_type, u8 report_id, u8 *p_buffer, u32 buffer_length, HIDCallback hc, void *p_user); -EXPORT_DECL(int, HIDSetReport,u32 handle, u8 report_type, u8 report_id, u8 *p_buffer, u32 buffer_length, HIDCallback hc, void *p_user); +EXPORT_DECL(s32, HIDGetReport,u32 handle, u8 report_type, u8 report_id, u8 *p_buffer, u32 buffer_length, HIDCallback hc, void *p_user); +EXPORT_DECL(s32, HIDSetReport,u32 handle, u8 report_type, u8 report_id, u8 *p_buffer, u32 buffer_length, HIDCallback hc, void *p_user); -EXPORT_DECL(int, HIDSetIdle,unsigned int handle, u8 interface_index,u8 duration, HIDCallback hc, void *p_user); +EXPORT_DECL(s32, HIDSetIdle,u32 handle, u8 s32erface_index,u8 duration, HIDCallback hc, void *p_user); -EXPORT_DECL(int, HIDRead,unsigned int handle, unsigned char *p_buffer, unsigned int buffer_length, HIDCallback hc, void *p_user); -EXPORT_DECL(int, HIDWrite,unsigned int handle, unsigned char *p_buffer, unsigned int buffer_length, HIDCallback hc, void *p_user); +EXPORT_DECL(s32, HIDRead,u32 handle, unsigned char *p_buffer, u32 buffer_length, HIDCallback hc, void *p_user); +EXPORT_DECL(s32, HIDWrite,u32 handle, unsigned char *p_buffer, u32 buffer_length, HIDCallback hc, void *p_user); void InitAcquireSysHID(void) { @@ -59,7 +59,7 @@ void InitSysHIDFunctionPointers(void) return; } - unsigned int funcPointer = 0; + u32 funcPointer = 0; //! assigning those is not mandatory and it does not always work to load them OS_FIND_EXPORT(syshid_handle, HIDSetup); diff --git a/src/dynamic_libs/syshid_functions.h b/src/dynamic_libs/syshid_functions.h index 08213b4..9e29133 100644 --- a/src/dynamic_libs/syshid_functions.h +++ b/src/dynamic_libs/syshid_functions.h @@ -28,60 +28,62 @@ extern "C" { #endif -extern unsigned int syshid_handle; +#include + +extern u32 syshid_handle; typedef struct { - unsigned int handle; - unsigned int physical_device_inst; - unsigned short vid; - unsigned short pid; - unsigned char interface_index; - unsigned char sub_class; - unsigned char protocol; + u32 handle; + u32 physical_device_inst; + u16 vid; + u16 pid; + u8 interface_index; + u8 sub_class; + u8 protocol; - unsigned short max_packet_size_rx; - unsigned short max_packet_size_tx; + u16 max_packet_size_rx; + u16 max_packet_size_tx; } HIDDevice; typedef struct _HIDClient HIDClient; -#define HID_DEVICE_DETACH 0 -#define HID_DEVICE_ATTACH 1 +#define HID_DEVICE_DETACH 0 +#define HID_DEVICE_ATTACH 1 -typedef int (*HIDAttachCallback)(HIDClient *p_hc,HIDDevice *p_hd,unsigned int attach); +typedef s32 (*HIDAttachCallback)(HIDClient *p_hc,HIDDevice *p_hd,u32 attach); struct _HIDClient { - HIDClient *next; - HIDAttachCallback attach_cb; + HIDClient *next; + HIDAttachCallback attach_cb; }; -typedef void (*HIDCallback)(unsigned int handle,int error,unsigned char *p_buffer,unsigned int bytes_transferred,void *p_user); +typedef void (*HIDCallback)(u32 handle,s32 error,u8 *p_buffer,u32 bytes_transferred,void *p_user); void InitSysHIDFunctionPointers(void); void InitAcquireSysHID(void); -extern int(*HIDSetup)(void); -extern int(*HIDTeardown)(void); +extern s32(*HIDSetup)(void); +extern s32(*HIDTeardown)(void); -extern int(*HIDAddClient)(HIDClient *p_client, HIDAttachCallback attach_callback); -extern int(*HIDDelClient)(HIDClient *p_client); +extern s32(*HIDAddClient)(HIDClient *p_client, HIDAttachCallback attach_callback); +extern s32(*HIDDelClient)(HIDClient *p_client); -extern int(*HIDGetDescriptor)(unsigned int handle,u8 descriptor_type,u8 descriptor_index, u16 language_id, unsigned char *p_buffer, unsigned int buffer_length, HIDCallback hc, void *p_user); -extern int(*HIDSetDescriptor)(unsigned int handle,u8 descriptor_type,u8 descriptor_index, u16 language_id, unsigned char *p_buffer, unsigned int buffer_length, HIDCallback hc, void *p_user); +extern s32(*HIDGetDescriptor)(u32 handle,u8 descriptor_type,u8 descriptor_index, u16 language_id, u8 *p_buffer, u32 buffer_length, HIDCallback hc, void *p_user); +extern s32(*HIDSetDescriptor)(u32 handle,u8 descriptor_type,u8 descriptor_index, u16 language_id, u8 *p_buffer, u32 buffer_length, HIDCallback hc, void *p_user); -extern int(*HIDGetReport)(u32 handle, u8 report_type, u8 report_id, u8 *p_buffer, u32 buffer_length, HIDCallback hc, void *p_user); -extern int(*HIDSetReport)(u32 handle, u8 report_type, u8 report_id, u8 *p_buffer, u32 buffer_length, HIDCallback hc, void *p_user); +extern s32(*HIDGetReport)(u32 handle, u8 report_type, u8 report_id, u8 *p_buffer, u32 buffer_length, HIDCallback hc, void *p_user); +extern s32(*HIDSetReport)(u32 handle, u8 report_type, u8 report_id, u8 *p_buffer, u32 buffer_length, HIDCallback hc, void *p_user); -extern int(*HIDSetIdle)(unsigned int handle, u8 interface_index,u8 duration, HIDCallback hc, void *p_user); +extern s32(*HIDSetIdle)(u32 handle, u8 s32erface_index,u8 duration, HIDCallback hc, void *p_user); -extern int(* HIDSetProtocol)(unsigned int handle,u8 interface_index,u8 protocol, HIDCallback hc, void *p_user); -extern int(* HIDGetProtocol)(unsigned int handle,u8 interface_index,u8 * protocol, HIDCallback hc, void *p_user); +extern s32(* HIDSetProtocol)(u32 handle,u8 s32erface_index,u8 protocol, HIDCallback hc, void *p_user); +extern s32(* HIDGetProtocol)(u32 handle,u8 s32erface_index,u8 * protocol, HIDCallback hc, void *p_user); -extern int(*HIDRead)(unsigned int handle, unsigned char *p_buffer, unsigned int buffer_length, HIDCallback hc, void *p_user); -extern int(*HIDWrite)(unsigned int handle, unsigned char *p_buffer, unsigned int buffer_length, HIDCallback hc, void *p_user); +extern s32(*HIDRead)(u32 handle, u8 *p_buffer, u32 buffer_length, HIDCallback hc, void *p_user); +extern s32(*HIDWrite)(u32 handle, u8 *p_buffer, u32 buffer_length, HIDCallback hc, void *p_user); #ifdef __cplusplus } diff --git a/src/dynamic_libs/vpad_functions.c b/src/dynamic_libs/vpad_functions.c index 201cf34..4af3b49 100644 --- a/src/dynamic_libs/vpad_functions.c +++ b/src/dynamic_libs/vpad_functions.c @@ -24,15 +24,15 @@ #include "os_functions.h" #include "vpad_functions.h" -unsigned int vpad_handle __attribute__((section(".data"))) = 0; -unsigned int vpadbase_handle __attribute__((section(".data"))) = 0; +u32 vpad_handle __attribute__((section(".data"))) = 0; +u32 vpadbase_handle __attribute__((section(".data"))) = 0; EXPORT_DECL(void, VPADInit, void); -EXPORT_DECL(int, VPADRead, int chan, VPADData *buffer, u32 buffer_size, s32 *error); -EXPORT_DECL(int, VPADGetLcdMode, int padnum, int *lcdmode); -EXPORT_DECL(int, VPADSetLcdMode, int padnum, int lcdmode); -EXPORT_DECL(int, VPADBASEGetMotorOnRemainingCount, int padnum); -EXPORT_DECL(int, VPADBASESetMotorOnRemainingCount, int padnum, int counter); +EXPORT_DECL(s32, VPADRead, s32 chan, VPADData *buffer, u32 buffer_size, s32 *error); +EXPORT_DECL(s32, VPADGetLcdMode, s32 padnum, s32 *lcdmode); +EXPORT_DECL(s32, VPADSetLcdMode, s32 padnum, s32 lcdmode); +EXPORT_DECL(s32, VPADBASEGetMotorOnRemainingCount, s32 padnum); +EXPORT_DECL(s32, VPADBASESetMotorOnRemainingCount, s32 padnum, s32 counter); void InitAcquireVPad(void) { @@ -42,7 +42,7 @@ void InitAcquireVPad(void) void InitVPadFunctionPointers(void) { - unsigned int *funcPointer = 0; + u32 *funcPointer = 0; InitAcquireVPad(); diff --git a/src/dynamic_libs/vpad_functions.h b/src/dynamic_libs/vpad_functions.h index 4fafda2..483ccbd 100644 --- a/src/dynamic_libs/vpad_functions.h +++ b/src/dynamic_libs/vpad_functions.h @@ -28,11 +28,11 @@ extern "C" { #endif -extern unsigned int vpad_handle; -extern unsigned int vpadbase_handle; - #include +extern u32 vpad_handle; +extern u32 vpadbase_handle; + #define VPAD_BUTTON_A 0x8000 #define VPAD_BUTTON_B 0x4000 #define VPAD_BUTTON_X 0x2000 @@ -73,6 +73,11 @@ typedef struct f32 x,y; } Vec2D; +typedef struct +{ + f32 x,y,z; +} Vec3D; + typedef struct { u16 x, y; /* Touch coordinates */ @@ -86,26 +91,29 @@ typedef struct u32 btns_d; /* Buttons that are pressed at that instant */ u32 btns_r; /* Released buttons */ Vec2D lstick, rstick; /* Each contains 4-byte X and Y components */ - char unknown1c[0x52 - 0x1c]; /* Contains accelerometer and gyroscope data somewhere */ + char unknown1c[0x38 - 0x1c]; /* Contains accelerometer data somewhere */ + Vec3D gyro; /* Gyro data */ + Vec3D angle; /* Angle data */ + char unknown50[0x52 - 0x50]; /* Two bytes of unknown data */ VPADTPData tpdata; /* Normal touchscreen data */ VPADTPData tpdata1; /* Modified touchscreen data 1 */ VPADTPData tpdata2; /* Modified touchscreen data 2 */ char unknown6a[0xa0 - 0x6a]; - uint8_t volume; - uint8_t battery; /* 0 to 6 */ - uint8_t unk_volume; /* One less than volume */ + u8 volume; + u8 battery; /* 0 to 6 */ + u8 unk_volume; /* One less than volume */ char unknowna4[0xac - 0xa4]; } VPADData; void InitVPadFunctionPointers(void); void InitAcquireVPad(void); -extern int (* VPADRead)(int chan, VPADData *buffer, u32 buffer_size, s32 *error); -extern int (* VPADGetLcdMode)(int padnum, int *lcdmode); -extern int (* VPADSetLcdMode)(int padnum, int lcdmode); +extern s32 (* VPADRead)(s32 chan, VPADData *buffer, u32 buffer_size, s32 *error); +extern s32 (* VPADGetLcdMode)(s32 padnum, s32 *lcdmode); +extern s32 (* VPADSetLcdMode)(s32 padnum, s32 lcdmode); extern void (* VPADInit)(void); -extern int (* VPADBASEGetMotorOnRemainingCount)(int lcdmode); -extern int (* VPADBASESetMotorOnRemainingCount)(int lcdmode,int counter); +extern s32 (* VPADBASEGetMotorOnRemainingCount)(s32 lcdmode); +extern s32 (* VPADBASESetMotorOnRemainingCount)(s32 lcdmode,s32 counter); #ifdef __cplusplus } diff --git a/src/entry.c b/src/entry.c index ef317ff..aad6777 100644 --- a/src/entry.c +++ b/src/entry.c @@ -5,6 +5,7 @@ #include "utils/utils.h" #include "main.h" #include "lib_easy.h" +#include "draw.h" int __entry_menu(int argc, char **argv) { diff --git a/src/icon.h b/src/icon.h new file mode 100644 index 0000000..439bda3 --- /dev/null +++ b/src/icon.h @@ -0,0 +1,640 @@ +#ifndef _ICON_H_ +#define _ICON_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +unsigned char icon_tga[] = { + 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x01, 0x60, 0x00, 0x20, 0x08, 0xff, 0xd8, 0xd8, 0xd8, 0xff, 0xff, + 0xd8, 0xd8, 0xd8, 0xff, 0xff, 0xd8, 0xd8, 0xd8, 0xff, 0xff, 0xd8, 0xd8, + 0xd8, 0xff, 0xff, 0xd8, 0xd8, 0xd8, 0xff, 0xff, 0xd8, 0xd8, 0xd8, 0xff, + 0xff, 0xd8, 0xd8, 0xd8, 0xff, 0xff, 0xd8, 0xd8, 0xd8, 0xff, 0xff, 0xd8, + 0xd8, 0xd8, 0xff, 0xff, 0xd8, 0xd8, 0xd8, 0xff, 0xff, 0xd8, 0xd8, 0xd8, + 0xff, 0xff, 0xd8, 0xd8, 0xd8, 0xff, 0xff, 0xd8, 0xd8, 0xd8, 0xff, 0xff, + 0xd8, 0xd8, 0xd8, 0xff, 0xff, 0xd8, 0xd8, 0xd8, 0xff, 0xff, 0xd8, 0xd8, + 0xd8, 0xff, 0xff, 0xd8, 0xd8, 0xd8, 0xff, 0xff, 0xd8, 0xd8, 0xd8, 0xff, + 0xff, 0xd8, 0xd8, 0xd8, 0xff, 0xff, 0xd8, 0xd8, 0xd8, 0xff, 0xff, 0xd8, + 0xd8, 0xd8, 0xff, 0xff, 0xd8, 0xd8, 0xd8, 0xff, 0xff, 0xd8, 0xd8, 0xd8, + 0xff, 0xff, 0xd8, 0xd8, 0xd8, 0xff, 0x8b, 0xd8, 0xd8, 0xd8, 0xff, 0xbb, + 0x00, 0x00, 0x00, 0xff, 0xff, 0xd8, 0xd8, 0xd8, 0xff, 0xb7, 0xd8, 0xd8, + 0xd8, 0xff, 0x8b, 0xd8, 0xd8, 0xd8, 0xff, 0xbb, 0x00, 0x00, 0x00, 0xff, + 0xff, 0xd8, 0xd8, 0xd8, 0xff, 0xb7, 0xd8, 0xd8, 0xd8, 0xff, 0x8b, 0xd8, + 0xd8, 0xd8, 0xff, 0xbb, 0x00, 0x00, 0x00, 0xff, 0xff, 0xd8, 0xd8, 0xd8, + 0xff, 0xb7, 0xd8, 0xd8, 0xd8, 0xff, 0x8b, 0xd8, 0xd8, 0xd8, 0xff, 0xbb, + 0x00, 0x00, 0x00, 0xff, 0xff, 0xd8, 0xd8, 0xd8, 0xff, 0xb7, 0xd8, 0xd8, + 0xd8, 0xff, 0x8b, 0xd8, 0xd8, 0xd8, 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, + 0x8b, 0xce, 0x56, 0x4d, 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, 0x9b, 0x7f, + 0x7f, 0x7f, 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, 0x87, 0xce, 0x56, 0x4d, + 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, 0xff, 0xd8, 0xd8, 0xd8, 0xff, 0xb3, + 0xd8, 0xd8, 0xd8, 0xff, 0x8b, 0xd8, 0xd8, 0xd8, 0xff, 0x83, 0x00, 0x00, + 0x00, 0xff, 0x8b, 0xce, 0x56, 0x4d, 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, + 0x9b, 0x7f, 0x7f, 0x7f, 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, 0x87, 0xce, + 0x56, 0x4d, 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, 0xff, 0xd8, 0xd8, 0xd8, + 0xff, 0xb3, 0xd8, 0xd8, 0xd8, 0xff, 0x8b, 0xd8, 0xd8, 0xd8, 0xff, 0x83, + 0x00, 0x00, 0x00, 0xff, 0x8b, 0xce, 0x56, 0x4d, 0xff, 0x83, 0x00, 0x00, + 0x00, 0xff, 0x9b, 0x7f, 0x7f, 0x7f, 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, + 0x87, 0xce, 0x56, 0x4d, 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, 0xff, 0xd8, + 0xd8, 0xd8, 0xff, 0xb3, 0xd8, 0xd8, 0xd8, 0xff, 0x8b, 0xd8, 0xd8, 0xd8, + 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, 0x8b, 0xce, 0x56, 0x4d, 0xff, 0x83, + 0x00, 0x00, 0x00, 0xff, 0x9b, 0x7f, 0x7f, 0x7f, 0xff, 0x83, 0x00, 0x00, + 0x00, 0xff, 0x87, 0xce, 0x56, 0x4d, 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, + 0xff, 0xd8, 0xd8, 0xd8, 0xff, 0xb3, 0xd8, 0xd8, 0xd8, 0xff, 0x8b, 0xd8, + 0xd8, 0xd8, 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, 0x8b, 0xce, 0x56, 0x4d, + 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, 0x8f, 0x7f, 0x7f, 0x7f, 0xff, 0x87, + 0xff, 0xff, 0xff, 0xff, 0x83, 0x7f, 0x7f, 0x7f, 0xff, 0x83, 0x00, 0x00, + 0x00, 0xff, 0x8b, 0xce, 0x56, 0x4d, 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, + 0xff, 0xd8, 0xd8, 0xd8, 0xff, 0xaf, 0xd8, 0xd8, 0xd8, 0xff, 0x8b, 0xd8, + 0xd8, 0xd8, 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, 0x8b, 0xce, 0x56, 0x4d, + 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, 0x8f, 0x7f, 0x7f, 0x7f, 0xff, 0x87, + 0xff, 0xff, 0xff, 0xff, 0x83, 0x7f, 0x7f, 0x7f, 0xff, 0x83, 0x00, 0x00, + 0x00, 0xff, 0x8b, 0xce, 0x56, 0x4d, 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, + 0xff, 0xd8, 0xd8, 0xd8, 0xff, 0xaf, 0xd8, 0xd8, 0xd8, 0xff, 0x8b, 0xd8, + 0xd8, 0xd8, 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, 0x8b, 0xce, 0x56, 0x4d, + 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, 0x8f, 0x7f, 0x7f, 0x7f, 0xff, 0x87, + 0xff, 0xff, 0xff, 0xff, 0x83, 0x7f, 0x7f, 0x7f, 0xff, 0x83, 0x00, 0x00, + 0x00, 0xff, 0x8b, 0xce, 0x56, 0x4d, 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, + 0xff, 0xd8, 0xd8, 0xd8, 0xff, 0xaf, 0xd8, 0xd8, 0xd8, 0xff, 0x8b, 0xd8, + 0xd8, 0xd8, 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, 0x8b, 0xce, 0x56, 0x4d, + 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, 0x8f, 0x7f, 0x7f, 0x7f, 0xff, 0x87, + 0xff, 0xff, 0xff, 0xff, 0x83, 0x7f, 0x7f, 0x7f, 0xff, 0x83, 0x00, 0x00, + 0x00, 0xff, 0x8b, 0xce, 0x56, 0x4d, 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, + 0xff, 0xd8, 0xd8, 0xd8, 0xff, 0xaf, 0xd8, 0xd8, 0xd8, 0xff, 0x8b, 0xd8, + 0xd8, 0xd8, 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, 0x8b, 0xce, 0x56, 0x4d, + 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, 0x8f, 0x7f, 0x7f, 0x7f, 0xff, 0x87, + 0xff, 0xff, 0xff, 0xff, 0x83, 0x7f, 0x7f, 0x7f, 0xff, 0x83, 0x00, 0x00, + 0x00, 0xff, 0x8b, 0xce, 0x56, 0x4d, 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, + 0xd3, 0xd8, 0xd8, 0xd8, 0xff, 0x87, 0x00, 0x00, 0x00, 0xff, 0x93, 0xd8, + 0xd8, 0xd8, 0xff, 0x87, 0x00, 0x00, 0x00, 0xff, 0x8b, 0xd8, 0xd8, 0xd8, + 0xff, 0x87, 0x00, 0x00, 0x00, 0xff, 0x8b, 0xd8, 0xd8, 0xd8, 0xff, 0x87, + 0x00, 0x00, 0x00, 0xff, 0x8f, 0xd8, 0xd8, 0xd8, 0xff, 0x8b, 0xd8, 0xd8, + 0xd8, 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, 0x8b, 0xce, 0x56, 0x4d, 0xff, + 0x83, 0x00, 0x00, 0x00, 0xff, 0x8f, 0x7f, 0x7f, 0x7f, 0xff, 0x87, 0xff, + 0xff, 0xff, 0xff, 0x83, 0x7f, 0x7f, 0x7f, 0xff, 0x83, 0x00, 0x00, 0x00, + 0xff, 0x8b, 0xce, 0x56, 0x4d, 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, 0xd3, + 0xd8, 0xd8, 0xd8, 0xff, 0x87, 0x00, 0x00, 0x00, 0xff, 0x93, 0xd8, 0xd8, + 0xd8, 0xff, 0x87, 0x00, 0x00, 0x00, 0xff, 0x8b, 0xd8, 0xd8, 0xd8, 0xff, + 0x87, 0x00, 0x00, 0x00, 0xff, 0x8b, 0xd8, 0xd8, 0xd8, 0xff, 0x87, 0x00, + 0x00, 0x00, 0xff, 0x8f, 0xd8, 0xd8, 0xd8, 0xff, 0x8b, 0xd8, 0xd8, 0xd8, + 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, 0x8b, 0xce, 0x56, 0x4d, 0xff, 0x83, + 0x00, 0x00, 0x00, 0xff, 0x8f, 0x7f, 0x7f, 0x7f, 0xff, 0x87, 0xff, 0xff, + 0xff, 0xff, 0x83, 0x7f, 0x7f, 0x7f, 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, + 0x8b, 0xce, 0x56, 0x4d, 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, 0xd3, 0xd8, + 0xd8, 0xd8, 0xff, 0x87, 0x00, 0x00, 0x00, 0xff, 0x93, 0xd8, 0xd8, 0xd8, + 0xff, 0x87, 0x00, 0x00, 0x00, 0xff, 0x8b, 0xd8, 0xd8, 0xd8, 0xff, 0x87, + 0x00, 0x00, 0x00, 0xff, 0x8b, 0xd8, 0xd8, 0xd8, 0xff, 0x87, 0x00, 0x00, + 0x00, 0xff, 0x8f, 0xd8, 0xd8, 0xd8, 0xff, 0x8b, 0xd8, 0xd8, 0xd8, 0xff, + 0x83, 0x00, 0x00, 0x00, 0xff, 0x8b, 0xce, 0x56, 0x4d, 0xff, 0x83, 0x00, + 0x00, 0x00, 0xff, 0x8f, 0x7f, 0x7f, 0x7f, 0xff, 0x87, 0xff, 0xff, 0xff, + 0xff, 0x83, 0x7f, 0x7f, 0x7f, 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, 0x8b, + 0xce, 0x56, 0x4d, 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, 0xd3, 0xd8, 0xd8, + 0xd8, 0xff, 0x87, 0x00, 0x00, 0x00, 0xff, 0x93, 0xd8, 0xd8, 0xd8, 0xff, + 0x87, 0x00, 0x00, 0x00, 0xff, 0x8b, 0xd8, 0xd8, 0xd8, 0xff, 0x87, 0x00, + 0x00, 0x00, 0xff, 0x8b, 0xd8, 0xd8, 0xd8, 0xff, 0x87, 0x00, 0x00, 0x00, + 0xff, 0x8f, 0xd8, 0xd8, 0xd8, 0xff, 0x8b, 0xd8, 0xd8, 0xd8, 0xff, 0x83, + 0x00, 0x00, 0x00, 0xff, 0x8b, 0xce, 0x56, 0x4d, 0xff, 0x83, 0x00, 0x00, + 0x00, 0xff, 0x8f, 0x7f, 0x7f, 0x7f, 0xff, 0x87, 0xff, 0xff, 0xff, 0xff, + 0x83, 0x7f, 0x7f, 0x7f, 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, 0x8b, 0xce, + 0x56, 0x4d, 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, 0x87, 0xd8, 0xd8, 0xd8, + 0xff, 0xc3, 0x00, 0x00, 0x00, 0xff, 0x83, 0xd8, 0xd8, 0xd8, 0xff, 0x83, + 0x00, 0x00, 0x00, 0xff, 0x87, 0x17, 0xdd, 0x8e, 0xff, 0x83, 0x00, 0x00, + 0x00, 0xff, 0x8b, 0xd8, 0xd8, 0xd8, 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, + 0x87, 0x17, 0xdd, 0x8e, 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, 0x83, 0xd8, + 0xd8, 0xd8, 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, 0x87, 0x17, 0xdd, 0x8e, + 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, 0x83, 0xd8, 0xd8, 0xd8, 0xff, 0x83, + 0x00, 0x00, 0x00, 0xff, 0x87, 0x17, 0xdd, 0x8e, 0xff, 0x83, 0x00, 0x00, + 0x00, 0xff, 0x8b, 0xd8, 0xd8, 0xd8, 0xff, 0x8b, 0xd8, 0xd8, 0xd8, 0xff, + 0x83, 0x00, 0x00, 0x00, 0xff, 0x8b, 0xce, 0x56, 0x4d, 0xff, 0x83, 0x00, + 0x00, 0x00, 0xff, 0x8f, 0x7f, 0x7f, 0x7f, 0xff, 0x87, 0xff, 0xff, 0xff, + 0xff, 0x83, 0x7f, 0x7f, 0x7f, 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, 0x8b, + 0xce, 0x56, 0x4d, 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, 0x87, 0xd8, 0xd8, + 0xd8, 0xff, 0xc3, 0x00, 0x00, 0x00, 0xff, 0x83, 0xd8, 0xd8, 0xd8, 0xff, + 0x83, 0x00, 0x00, 0x00, 0xff, 0x87, 0x17, 0xdd, 0x8e, 0xff, 0x83, 0x00, + 0x00, 0x00, 0xff, 0x8b, 0xd8, 0xd8, 0xd8, 0xff, 0x83, 0x00, 0x00, 0x00, + 0xff, 0x87, 0x17, 0xdd, 0x8e, 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, 0x83, + 0xd8, 0xd8, 0xd8, 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, 0x87, 0x17, 0xdd, + 0x8e, 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, 0x83, 0xd8, 0xd8, 0xd8, 0xff, + 0x83, 0x00, 0x00, 0x00, 0xff, 0x87, 0x17, 0xdd, 0x8e, 0xff, 0x83, 0x00, + 0x00, 0x00, 0xff, 0x8b, 0xd8, 0xd8, 0xd8, 0xff, 0x8b, 0xd8, 0xd8, 0xd8, + 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, 0x8b, 0xce, 0x56, 0x4d, 0xff, 0x83, + 0x00, 0x00, 0x00, 0xff, 0x8f, 0x7f, 0x7f, 0x7f, 0xff, 0x87, 0xff, 0xff, + 0xff, 0xff, 0x83, 0x7f, 0x7f, 0x7f, 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, + 0x8b, 0xce, 0x56, 0x4d, 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, 0x87, 0xd8, + 0xd8, 0xd8, 0xff, 0xc3, 0x00, 0x00, 0x00, 0xff, 0x83, 0xd8, 0xd8, 0xd8, + 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, 0x87, 0x17, 0xdd, 0x8e, 0xff, 0x83, + 0x00, 0x00, 0x00, 0xff, 0x8b, 0xd8, 0xd8, 0xd8, 0xff, 0x83, 0x00, 0x00, + 0x00, 0xff, 0x87, 0x17, 0xdd, 0x8e, 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, + 0x83, 0xd8, 0xd8, 0xd8, 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, 0x87, 0x17, + 0xdd, 0x8e, 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, 0x83, 0xd8, 0xd8, 0xd8, + 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, 0x87, 0x17, 0xdd, 0x8e, 0xff, 0x83, + 0x00, 0x00, 0x00, 0xff, 0x8b, 0xd8, 0xd8, 0xd8, 0xff, 0x8b, 0xd8, 0xd8, + 0xd8, 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, 0x8b, 0xce, 0x56, 0x4d, 0xff, + 0x83, 0x00, 0x00, 0x00, 0xff, 0x8f, 0x7f, 0x7f, 0x7f, 0xff, 0x87, 0xff, + 0xff, 0xff, 0xff, 0x83, 0x7f, 0x7f, 0x7f, 0xff, 0x83, 0x00, 0x00, 0x00, + 0xff, 0x8b, 0xce, 0x56, 0x4d, 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, 0x87, + 0xd8, 0xd8, 0xd8, 0xff, 0xc3, 0x00, 0x00, 0x00, 0xff, 0x83, 0xd8, 0xd8, + 0xd8, 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, 0x87, 0x17, 0xdd, 0x8e, 0xff, + 0x83, 0x00, 0x00, 0x00, 0xff, 0x8b, 0xd8, 0xd8, 0xd8, 0xff, 0x83, 0x00, + 0x00, 0x00, 0xff, 0x87, 0x17, 0xdd, 0x8e, 0xff, 0x83, 0x00, 0x00, 0x00, + 0xff, 0x83, 0xd8, 0xd8, 0xd8, 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, 0x87, + 0x17, 0xdd, 0x8e, 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, 0x83, 0xd8, 0xd8, + 0xd8, 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, 0x87, 0x17, 0xdd, 0x8e, 0xff, + 0x83, 0x00, 0x00, 0x00, 0xff, 0x8b, 0xd8, 0xd8, 0xd8, 0xff, 0x8b, 0xd8, + 0xd8, 0xd8, 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, 0x8b, 0xce, 0x56, 0x4d, + 0xff, 0xa3, 0x00, 0x00, 0x00, 0xff, 0x8b, 0xce, 0x56, 0x4d, 0xff, 0x83, + 0x00, 0x00, 0x00, 0xff, 0x87, 0xd8, 0xd8, 0xd8, 0xff, 0x83, 0x00, 0x00, + 0x00, 0xff, 0x8b, 0xff, 0xff, 0xff, 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, + 0x83, 0xff, 0xff, 0xff, 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, 0x83, 0xff, + 0xff, 0xff, 0xff, 0x87, 0x00, 0x00, 0x00, 0xff, 0x83, 0xff, 0xff, 0xff, + 0xff, 0x87, 0x00, 0x00, 0x00, 0xff, 0x8b, 0xff, 0xff, 0xff, 0xff, 0x83, + 0x00, 0x00, 0x00, 0xff, 0x83, 0xd8, 0xd8, 0xd8, 0xff, 0x83, 0x00, 0x00, + 0x00, 0xff, 0x87, 0x17, 0xdd, 0x8e, 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, + 0x8b, 0xd8, 0xd8, 0xd8, 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, 0x87, 0x17, + 0xdd, 0x8e, 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, 0x83, 0xd8, 0xd8, 0xd8, + 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, 0x87, 0x17, 0xdd, 0x8e, 0xff, 0x83, + 0x00, 0x00, 0x00, 0xff, 0x83, 0xd8, 0xd8, 0xd8, 0xff, 0x83, 0x00, 0x00, + 0x00, 0xff, 0x87, 0x17, 0xdd, 0x8e, 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, + 0x8b, 0xd8, 0xd8, 0xd8, 0xff, 0x8b, 0xd8, 0xd8, 0xd8, 0xff, 0x83, 0x00, + 0x00, 0x00, 0xff, 0x8b, 0xce, 0x56, 0x4d, 0xff, 0xa3, 0x00, 0x00, 0x00, + 0xff, 0x8b, 0xce, 0x56, 0x4d, 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, 0x87, + 0xd8, 0xd8, 0xd8, 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, 0x8b, 0xff, 0xff, + 0xff, 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, 0x83, 0xff, 0xff, 0xff, 0xff, + 0x83, 0x00, 0x00, 0x00, 0xff, 0x83, 0xff, 0xff, 0xff, 0xff, 0x87, 0x00, + 0x00, 0x00, 0xff, 0x83, 0xff, 0xff, 0xff, 0xff, 0x87, 0x00, 0x00, 0x00, + 0xff, 0x8b, 0xff, 0xff, 0xff, 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, 0x83, + 0xd8, 0xd8, 0xd8, 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, 0x87, 0x17, 0xdd, + 0x8e, 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, 0x8b, 0xd8, 0xd8, 0xd8, 0xff, + 0x83, 0x00, 0x00, 0x00, 0xff, 0x87, 0x17, 0xdd, 0x8e, 0xff, 0x83, 0x00, + 0x00, 0x00, 0xff, 0x83, 0xd8, 0xd8, 0xd8, 0xff, 0x83, 0x00, 0x00, 0x00, + 0xff, 0x87, 0x17, 0xdd, 0x8e, 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, 0x83, + 0xd8, 0xd8, 0xd8, 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, 0x87, 0x17, 0xdd, + 0x8e, 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, 0x8b, 0xd8, 0xd8, 0xd8, 0xff, + 0x8b, 0xd8, 0xd8, 0xd8, 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, 0x8b, 0xce, + 0x56, 0x4d, 0xff, 0xa3, 0x00, 0x00, 0x00, 0xff, 0x8b, 0xce, 0x56, 0x4d, + 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, 0x87, 0xd8, 0xd8, 0xd8, 0xff, 0x83, + 0x00, 0x00, 0x00, 0xff, 0x8b, 0xff, 0xff, 0xff, 0xff, 0x83, 0x00, 0x00, + 0x00, 0xff, 0x83, 0xff, 0xff, 0xff, 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, + 0x83, 0xff, 0xff, 0xff, 0xff, 0x87, 0x00, 0x00, 0x00, 0xff, 0x83, 0xff, + 0xff, 0xff, 0xff, 0x87, 0x00, 0x00, 0x00, 0xff, 0x8b, 0xff, 0xff, 0xff, + 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, 0x83, 0xd8, 0xd8, 0xd8, 0xff, 0x83, + 0x00, 0x00, 0x00, 0xff, 0x87, 0x17, 0xdd, 0x8e, 0xff, 0x83, 0x00, 0x00, + 0x00, 0xff, 0x8b, 0xd8, 0xd8, 0xd8, 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, + 0x87, 0x17, 0xdd, 0x8e, 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, 0x83, 0xd8, + 0xd8, 0xd8, 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, 0x87, 0x17, 0xdd, 0x8e, + 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, 0x83, 0xd8, 0xd8, 0xd8, 0xff, 0x83, + 0x00, 0x00, 0x00, 0xff, 0x87, 0x17, 0xdd, 0x8e, 0xff, 0x83, 0x00, 0x00, + 0x00, 0xff, 0x8b, 0xd8, 0xd8, 0xd8, 0xff, 0x8b, 0xd8, 0xd8, 0xd8, 0xff, + 0x83, 0x00, 0x00, 0x00, 0xff, 0x8b, 0xce, 0x56, 0x4d, 0xff, 0xa3, 0x00, + 0x00, 0x00, 0xff, 0x8b, 0xce, 0x56, 0x4d, 0xff, 0x83, 0x00, 0x00, 0x00, + 0xff, 0x87, 0xd8, 0xd8, 0xd8, 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, 0x8b, + 0xff, 0xff, 0xff, 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, 0x83, 0xff, 0xff, + 0xff, 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, 0x83, 0xff, 0xff, 0xff, 0xff, + 0x87, 0x00, 0x00, 0x00, 0xff, 0x83, 0xff, 0xff, 0xff, 0xff, 0x87, 0x00, + 0x00, 0x00, 0xff, 0x8b, 0xff, 0xff, 0xff, 0xff, 0x83, 0x00, 0x00, 0x00, + 0xff, 0x83, 0xd8, 0xd8, 0xd8, 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, 0x87, + 0x17, 0xdd, 0x8e, 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, 0x8b, 0xd8, 0xd8, + 0xd8, 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, 0x87, 0x17, 0xdd, 0x8e, 0xff, + 0x83, 0x00, 0x00, 0x00, 0xff, 0x83, 0xd8, 0xd8, 0xd8, 0xff, 0x83, 0x00, + 0x00, 0x00, 0xff, 0x87, 0x17, 0xdd, 0x8e, 0xff, 0x83, 0x00, 0x00, 0x00, + 0xff, 0x83, 0xd8, 0xd8, 0xd8, 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, 0x87, + 0x17, 0xdd, 0x8e, 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, 0x8b, 0xd8, 0xd8, + 0xd8, 0xff, 0x8b, 0xd8, 0xd8, 0xd8, 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, + 0xbb, 0xce, 0x56, 0x4d, 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, 0x87, 0xd8, + 0xd8, 0xd8, 0xff, 0x8b, 0x00, 0x00, 0x00, 0xff, 0x83, 0xff, 0xff, 0xff, + 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, 0x83, 0xff, 0xff, 0xff, 0xff, 0x83, + 0x00, 0x00, 0x00, 0xff, 0x83, 0xff, 0xff, 0xff, 0xff, 0x83, 0x00, 0x00, + 0x00, 0xff, 0x83, 0xff, 0xff, 0xff, 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, + 0x83, 0xff, 0xff, 0xff, 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, 0x83, 0xff, + 0xff, 0xff, 0xff, 0x8b, 0x00, 0x00, 0x00, 0xff, 0x83, 0xd8, 0xd8, 0xd8, + 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, 0x87, 0x17, 0xdd, 0x8e, 0xff, 0x83, + 0x00, 0x00, 0x00, 0xff, 0x8b, 0xd8, 0xd8, 0xd8, 0xff, 0x83, 0x00, 0x00, + 0x00, 0xff, 0x87, 0x17, 0xdd, 0x8e, 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, + 0x83, 0xd8, 0xd8, 0xd8, 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, 0x87, 0x17, + 0xdd, 0x8e, 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, 0x83, 0xd8, 0xd8, 0xd8, + 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, 0x87, 0x17, 0xdd, 0x8e, 0xff, 0x83, + 0x00, 0x00, 0x00, 0xff, 0x8b, 0xd8, 0xd8, 0xd8, 0xff, 0x8b, 0xd8, 0xd8, + 0xd8, 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, 0xbb, 0xce, 0x56, 0x4d, 0xff, + 0x83, 0x00, 0x00, 0x00, 0xff, 0x87, 0xd8, 0xd8, 0xd8, 0xff, 0x8b, 0x00, + 0x00, 0x00, 0xff, 0x83, 0xff, 0xff, 0xff, 0xff, 0x83, 0x00, 0x00, 0x00, + 0xff, 0x83, 0xff, 0xff, 0xff, 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, 0x83, + 0xff, 0xff, 0xff, 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, 0x83, 0xff, 0xff, + 0xff, 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, 0x83, 0xff, 0xff, 0xff, 0xff, + 0x83, 0x00, 0x00, 0x00, 0xff, 0x83, 0xff, 0xff, 0xff, 0xff, 0x8b, 0x00, + 0x00, 0x00, 0xff, 0x83, 0xd8, 0xd8, 0xd8, 0xff, 0x83, 0x00, 0x00, 0x00, + 0xff, 0x87, 0x17, 0xdd, 0x8e, 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, 0x8b, + 0xd8, 0xd8, 0xd8, 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, 0x87, 0x17, 0xdd, + 0x8e, 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, 0x83, 0xd8, 0xd8, 0xd8, 0xff, + 0x83, 0x00, 0x00, 0x00, 0xff, 0x87, 0x17, 0xdd, 0x8e, 0xff, 0x83, 0x00, + 0x00, 0x00, 0xff, 0x83, 0xd8, 0xd8, 0xd8, 0xff, 0x83, 0x00, 0x00, 0x00, + 0xff, 0x87, 0x17, 0xdd, 0x8e, 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, 0x8b, + 0xd8, 0xd8, 0xd8, 0xff, 0x8b, 0xd8, 0xd8, 0xd8, 0xff, 0x83, 0x00, 0x00, + 0x00, 0xff, 0xbb, 0xce, 0x56, 0x4d, 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, + 0x87, 0xd8, 0xd8, 0xd8, 0xff, 0x8b, 0x00, 0x00, 0x00, 0xff, 0x83, 0xff, + 0xff, 0xff, 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, 0x83, 0xff, 0xff, 0xff, + 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, 0x83, 0xff, 0xff, 0xff, 0xff, 0x83, + 0x00, 0x00, 0x00, 0xff, 0x83, 0xff, 0xff, 0xff, 0xff, 0x83, 0x00, 0x00, + 0x00, 0xff, 0x83, 0xff, 0xff, 0xff, 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, + 0x83, 0xff, 0xff, 0xff, 0xff, 0x8b, 0x00, 0x00, 0x00, 0xff, 0x83, 0xd8, + 0xd8, 0xd8, 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, 0x87, 0x17, 0xdd, 0x8e, + 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, 0x8b, 0xd8, 0xd8, 0xd8, 0xff, 0x83, + 0x00, 0x00, 0x00, 0xff, 0x87, 0x17, 0xdd, 0x8e, 0xff, 0x83, 0x00, 0x00, + 0x00, 0xff, 0x83, 0xd8, 0xd8, 0xd8, 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, + 0x87, 0x17, 0xdd, 0x8e, 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, 0x83, 0xd8, + 0xd8, 0xd8, 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, 0x87, 0x17, 0xdd, 0x8e, + 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, 0x8b, 0xd8, 0xd8, 0xd8, 0xff, 0x8b, + 0xd8, 0xd8, 0xd8, 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, 0xbb, 0xce, 0x56, + 0x4d, 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, 0x87, 0xd8, 0xd8, 0xd8, 0xff, + 0x8b, 0x00, 0x00, 0x00, 0xff, 0x83, 0xff, 0xff, 0xff, 0xff, 0x83, 0x00, + 0x00, 0x00, 0xff, 0x83, 0xff, 0xff, 0xff, 0xff, 0x83, 0x00, 0x00, 0x00, + 0xff, 0x83, 0xff, 0xff, 0xff, 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, 0x83, + 0xff, 0xff, 0xff, 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, 0x83, 0xff, 0xff, + 0xff, 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, 0x83, 0xff, 0xff, 0xff, 0xff, + 0x8b, 0x00, 0x00, 0x00, 0xff, 0x83, 0xd8, 0xd8, 0xd8, 0xff, 0x83, 0x00, + 0x00, 0x00, 0xff, 0x87, 0x17, 0xdd, 0x8e, 0xff, 0x83, 0x00, 0x00, 0x00, + 0xff, 0x8b, 0xd8, 0xd8, 0xd8, 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, 0x87, + 0x17, 0xdd, 0x8e, 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, 0x83, 0xd8, 0xd8, + 0xd8, 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, 0x87, 0x17, 0xdd, 0x8e, 0xff, + 0x83, 0x00, 0x00, 0x00, 0xff, 0x83, 0xd8, 0xd8, 0xd8, 0xff, 0x83, 0x00, + 0x00, 0x00, 0xff, 0x87, 0x17, 0xdd, 0x8e, 0xff, 0x83, 0x00, 0x00, 0x00, + 0xff, 0x8b, 0xd8, 0xd8, 0xd8, 0xff, 0x8b, 0xd8, 0xd8, 0xd8, 0xff, 0x83, + 0x00, 0x00, 0x00, 0xff, 0xbb, 0xce, 0x56, 0x4d, 0xff, 0x83, 0x00, 0x00, + 0x00, 0xff, 0x87, 0xd8, 0xd8, 0xd8, 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, + 0x8b, 0xff, 0xff, 0xff, 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, 0x8b, 0xff, + 0xff, 0xff, 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, 0x83, 0xff, 0xff, 0xff, + 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, 0x83, 0xff, 0xff, 0xff, 0xff, 0x83, + 0x00, 0x00, 0x00, 0xff, 0x8b, 0xff, 0xff, 0xff, 0xff, 0x83, 0x00, 0x00, + 0x00, 0xff, 0x83, 0xd8, 0xd8, 0xd8, 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, + 0x87, 0x17, 0xdd, 0x8e, 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, 0x83, 0xd8, + 0xd8, 0xd8, 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, 0x83, 0xd8, 0xd8, 0xd8, + 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, 0x87, 0x17, 0xdd, 0x8e, 0xff, 0x83, + 0x00, 0x00, 0x00, 0xff, 0x83, 0xd8, 0xd8, 0xd8, 0xff, 0x83, 0x00, 0x00, + 0x00, 0xff, 0x87, 0x17, 0xdd, 0x8e, 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, + 0x83, 0xd8, 0xd8, 0xd8, 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, 0x87, 0x17, + 0xdd, 0x8e, 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, 0x8b, 0xd8, 0xd8, 0xd8, + 0xff, 0x8b, 0xd8, 0xd8, 0xd8, 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, 0xbb, + 0xce, 0x56, 0x4d, 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, 0x87, 0xd8, 0xd8, + 0xd8, 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, 0x8b, 0xff, 0xff, 0xff, 0xff, + 0x83, 0x00, 0x00, 0x00, 0xff, 0x8b, 0xff, 0xff, 0xff, 0xff, 0x83, 0x00, + 0x00, 0x00, 0xff, 0x83, 0xff, 0xff, 0xff, 0xff, 0x83, 0x00, 0x00, 0x00, + 0xff, 0x83, 0xff, 0xff, 0xff, 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, 0x8b, + 0xff, 0xff, 0xff, 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, 0x83, 0xd8, 0xd8, + 0xd8, 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, 0x87, 0x17, 0xdd, 0x8e, 0xff, + 0x83, 0x00, 0x00, 0x00, 0xff, 0x83, 0xd8, 0xd8, 0xd8, 0xff, 0x83, 0x00, + 0x00, 0x00, 0xff, 0x83, 0xd8, 0xd8, 0xd8, 0xff, 0x83, 0x00, 0x00, 0x00, + 0xff, 0x87, 0x17, 0xdd, 0x8e, 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, 0x83, + 0xd8, 0xd8, 0xd8, 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, 0x87, 0x17, 0xdd, + 0x8e, 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, 0x83, 0xd8, 0xd8, 0xd8, 0xff, + 0x83, 0x00, 0x00, 0x00, 0xff, 0x87, 0x17, 0xdd, 0x8e, 0xff, 0x83, 0x00, + 0x00, 0x00, 0xff, 0x8b, 0xd8, 0xd8, 0xd8, 0xff, 0x8b, 0xd8, 0xd8, 0xd8, + 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, 0xbb, 0xce, 0x56, 0x4d, 0xff, 0x83, + 0x00, 0x00, 0x00, 0xff, 0x87, 0xd8, 0xd8, 0xd8, 0xff, 0x83, 0x00, 0x00, + 0x00, 0xff, 0x8b, 0xff, 0xff, 0xff, 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, + 0x8b, 0xff, 0xff, 0xff, 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, 0x83, 0xff, + 0xff, 0xff, 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, 0x83, 0xff, 0xff, 0xff, + 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, 0x8b, 0xff, 0xff, 0xff, 0xff, 0x83, + 0x00, 0x00, 0x00, 0xff, 0x83, 0xd8, 0xd8, 0xd8, 0xff, 0x83, 0x00, 0x00, + 0x00, 0xff, 0x87, 0x17, 0xdd, 0x8e, 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, + 0x83, 0xd8, 0xd8, 0xd8, 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, 0x83, 0xd8, + 0xd8, 0xd8, 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, 0x87, 0x17, 0xdd, 0x8e, + 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, 0x83, 0xd8, 0xd8, 0xd8, 0xff, 0x83, + 0x00, 0x00, 0x00, 0xff, 0x87, 0x17, 0xdd, 0x8e, 0xff, 0x83, 0x00, 0x00, + 0x00, 0xff, 0x83, 0xd8, 0xd8, 0xd8, 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, + 0x87, 0x17, 0xdd, 0x8e, 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, 0x8b, 0xd8, + 0xd8, 0xd8, 0xff, 0x8b, 0xd8, 0xd8, 0xd8, 0xff, 0x83, 0x00, 0x00, 0x00, + 0xff, 0xbb, 0xce, 0x56, 0x4d, 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, 0x87, + 0xd8, 0xd8, 0xd8, 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, 0x8b, 0xff, 0xff, + 0xff, 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, 0x8b, 0xff, 0xff, 0xff, 0xff, + 0x83, 0x00, 0x00, 0x00, 0xff, 0x83, 0xff, 0xff, 0xff, 0xff, 0x83, 0x00, + 0x00, 0x00, 0xff, 0x83, 0xff, 0xff, 0xff, 0xff, 0x83, 0x00, 0x00, 0x00, + 0xff, 0x8b, 0xff, 0xff, 0xff, 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, 0x83, + 0xd8, 0xd8, 0xd8, 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, 0x87, 0x17, 0xdd, + 0x8e, 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, 0x83, 0xd8, 0xd8, 0xd8, 0xff, + 0x83, 0x00, 0x00, 0x00, 0xff, 0x83, 0xd8, 0xd8, 0xd8, 0xff, 0x83, 0x00, + 0x00, 0x00, 0xff, 0x87, 0x17, 0xdd, 0x8e, 0xff, 0x83, 0x00, 0x00, 0x00, + 0xff, 0x83, 0xd8, 0xd8, 0xd8, 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, 0x87, + 0x17, 0xdd, 0x8e, 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, 0x83, 0xd8, 0xd8, + 0xd8, 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, 0x87, 0x17, 0xdd, 0x8e, 0xff, + 0x83, 0x00, 0x00, 0x00, 0xff, 0x8b, 0xd8, 0xd8, 0xd8, 0xff, 0x8b, 0xd8, + 0xd8, 0xd8, 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, 0x87, 0xce, 0x56, 0x4d, + 0xff, 0xab, 0x00, 0x00, 0x00, 0xff, 0x87, 0xce, 0x56, 0x4d, 0xff, 0x83, + 0x00, 0x00, 0x00, 0xff, 0x87, 0xd8, 0xd8, 0xd8, 0xff, 0x83, 0x00, 0x00, + 0x00, 0xff, 0x83, 0xff, 0xff, 0xff, 0xff, 0x8b, 0x00, 0x00, 0x00, 0xff, + 0x83, 0xff, 0xff, 0xff, 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, 0x83, 0xff, + 0xff, 0xff, 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, 0x83, 0xff, 0xff, 0xff, + 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, 0x83, 0xff, 0xff, 0xff, 0xff, 0x83, + 0x00, 0x00, 0x00, 0xff, 0x83, 0xff, 0xff, 0xff, 0xff, 0x8b, 0x00, 0x00, + 0x00, 0xff, 0x83, 0xd8, 0xd8, 0xd8, 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, + 0x87, 0x17, 0xdd, 0x8e, 0xff, 0x87, 0x00, 0x00, 0x00, 0xff, 0x83, 0x17, + 0xdd, 0x8e, 0xff, 0x87, 0x00, 0x00, 0x00, 0xff, 0x87, 0x17, 0xdd, 0x8e, + 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, 0x83, 0xd8, 0xd8, 0xd8, 0xff, 0x83, + 0x00, 0x00, 0x00, 0xff, 0x87, 0x17, 0xdd, 0x8e, 0xff, 0x83, 0x00, 0x00, + 0x00, 0xff, 0x83, 0xd8, 0xd8, 0xd8, 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, + 0x87, 0x17, 0xdd, 0x8e, 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, 0x8b, 0xd8, + 0xd8, 0xd8, 0xff, 0x8b, 0xd8, 0xd8, 0xd8, 0xff, 0x83, 0x00, 0x00, 0x00, + 0xff, 0x87, 0xce, 0x56, 0x4d, 0xff, 0xab, 0x00, 0x00, 0x00, 0xff, 0x87, + 0xce, 0x56, 0x4d, 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, 0x87, 0xd8, 0xd8, + 0xd8, 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, 0x83, 0xff, 0xff, 0xff, 0xff, + 0x8b, 0x00, 0x00, 0x00, 0xff, 0x83, 0xff, 0xff, 0xff, 0xff, 0x83, 0x00, + 0x00, 0x00, 0xff, 0x83, 0xff, 0xff, 0xff, 0xff, 0x83, 0x00, 0x00, 0x00, + 0xff, 0x83, 0xff, 0xff, 0xff, 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, 0x83, + 0xff, 0xff, 0xff, 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, 0x83, 0xff, 0xff, + 0xff, 0xff, 0x8b, 0x00, 0x00, 0x00, 0xff, 0x83, 0xd8, 0xd8, 0xd8, 0xff, + 0x83, 0x00, 0x00, 0x00, 0xff, 0x87, 0x17, 0xdd, 0x8e, 0xff, 0x87, 0x00, + 0x00, 0x00, 0xff, 0x83, 0x17, 0xdd, 0x8e, 0xff, 0x87, 0x00, 0x00, 0x00, + 0xff, 0x87, 0x17, 0xdd, 0x8e, 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, 0x83, + 0xd8, 0xd8, 0xd8, 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, 0x87, 0x17, 0xdd, + 0x8e, 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, 0x83, 0xd8, 0xd8, 0xd8, 0xff, + 0x83, 0x00, 0x00, 0x00, 0xff, 0x87, 0x17, 0xdd, 0x8e, 0xff, 0x83, 0x00, + 0x00, 0x00, 0xff, 0x8b, 0xd8, 0xd8, 0xd8, 0xff, 0x8b, 0xd8, 0xd8, 0xd8, + 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, 0x87, 0xce, 0x56, 0x4d, 0xff, 0xab, + 0x00, 0x00, 0x00, 0xff, 0x87, 0xce, 0x56, 0x4d, 0xff, 0x83, 0x00, 0x00, + 0x00, 0xff, 0x87, 0xd8, 0xd8, 0xd8, 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, + 0x83, 0xff, 0xff, 0xff, 0xff, 0x8b, 0x00, 0x00, 0x00, 0xff, 0x83, 0xff, + 0xff, 0xff, 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, 0x83, 0xff, 0xff, 0xff, + 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, 0x83, 0xff, 0xff, 0xff, 0xff, 0x83, + 0x00, 0x00, 0x00, 0xff, 0x83, 0xff, 0xff, 0xff, 0xff, 0x83, 0x00, 0x00, + 0x00, 0xff, 0x83, 0xff, 0xff, 0xff, 0xff, 0x8b, 0x00, 0x00, 0x00, 0xff, + 0x83, 0xd8, 0xd8, 0xd8, 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, 0x87, 0x17, + 0xdd, 0x8e, 0xff, 0x87, 0x00, 0x00, 0x00, 0xff, 0x83, 0x17, 0xdd, 0x8e, + 0xff, 0x87, 0x00, 0x00, 0x00, 0xff, 0x87, 0x17, 0xdd, 0x8e, 0xff, 0x83, + 0x00, 0x00, 0x00, 0xff, 0x83, 0xd8, 0xd8, 0xd8, 0xff, 0x83, 0x00, 0x00, + 0x00, 0xff, 0x87, 0x17, 0xdd, 0x8e, 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, + 0x83, 0xd8, 0xd8, 0xd8, 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, 0x87, 0x17, + 0xdd, 0x8e, 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, 0x8b, 0xd8, 0xd8, 0xd8, + 0xff, 0x8b, 0xd8, 0xd8, 0xd8, 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, 0x87, + 0xce, 0x56, 0x4d, 0xff, 0xab, 0x00, 0x00, 0x00, 0xff, 0x87, 0xce, 0x56, + 0x4d, 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, 0x87, 0xd8, 0xd8, 0xd8, 0xff, + 0x83, 0x00, 0x00, 0x00, 0xff, 0x83, 0xff, 0xff, 0xff, 0xff, 0x8b, 0x00, + 0x00, 0x00, 0xff, 0x83, 0xff, 0xff, 0xff, 0xff, 0x83, 0x00, 0x00, 0x00, + 0xff, 0x83, 0xff, 0xff, 0xff, 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, 0x83, + 0xff, 0xff, 0xff, 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, 0x83, 0xff, 0xff, + 0xff, 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, 0x83, 0xff, 0xff, 0xff, 0xff, + 0x8b, 0x00, 0x00, 0x00, 0xff, 0x83, 0xd8, 0xd8, 0xd8, 0xff, 0x83, 0x00, + 0x00, 0x00, 0xff, 0x87, 0x17, 0xdd, 0x8e, 0xff, 0x87, 0x00, 0x00, 0x00, + 0xff, 0x83, 0x17, 0xdd, 0x8e, 0xff, 0x87, 0x00, 0x00, 0x00, 0xff, 0x87, + 0x17, 0xdd, 0x8e, 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, 0x83, 0xd8, 0xd8, + 0xd8, 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, 0x87, 0x17, 0xdd, 0x8e, 0xff, + 0x83, 0x00, 0x00, 0x00, 0xff, 0x83, 0xd8, 0xd8, 0xd8, 0xff, 0x83, 0x00, + 0x00, 0x00, 0xff, 0x87, 0x17, 0xdd, 0x8e, 0xff, 0x83, 0x00, 0x00, 0x00, + 0xff, 0x8b, 0xd8, 0xd8, 0xd8, 0xff, 0x8b, 0xd8, 0xd8, 0xd8, 0xff, 0x83, + 0x00, 0x00, 0x00, 0xff, 0x87, 0xce, 0x56, 0x4d, 0xff, 0x83, 0x00, 0x00, + 0x00, 0xff, 0xa3, 0xb0, 0xe4, 0xef, 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, + 0x87, 0xce, 0x56, 0x4d, 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, 0x87, 0xd8, + 0xd8, 0xd8, 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, 0x8b, 0xff, 0xff, 0xff, + 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, 0x8b, 0xff, 0xff, 0xff, 0xff, 0x83, + 0x00, 0x00, 0x00, 0xff, 0x83, 0xff, 0xff, 0xff, 0xff, 0x83, 0x00, 0x00, + 0x00, 0xff, 0x83, 0xff, 0xff, 0xff, 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, + 0x8b, 0xff, 0xff, 0xff, 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, 0x83, 0xd8, + 0xd8, 0xd8, 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, 0x87, 0x17, 0xdd, 0x8e, + 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, 0x8b, 0x17, 0xdd, 0x8e, 0xff, 0x83, + 0x00, 0x00, 0x00, 0xff, 0x87, 0x17, 0xdd, 0x8e, 0xff, 0x83, 0x00, 0x00, + 0x00, 0xff, 0x87, 0xd8, 0xd8, 0xd8, 0xff, 0x87, 0x00, 0x00, 0x00, 0xff, + 0x8b, 0xd8, 0xd8, 0xd8, 0xff, 0x87, 0x00, 0x00, 0x00, 0xff, 0x8f, 0xd8, + 0xd8, 0xd8, 0xff, 0x8b, 0xd8, 0xd8, 0xd8, 0xff, 0x83, 0x00, 0x00, 0x00, + 0xff, 0x87, 0xce, 0x56, 0x4d, 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, 0xa3, + 0xb0, 0xe4, 0xef, 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, 0x87, 0xce, 0x56, + 0x4d, 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, 0x87, 0xd8, 0xd8, 0xd8, 0xff, + 0x83, 0x00, 0x00, 0x00, 0xff, 0x8b, 0xff, 0xff, 0xff, 0xff, 0x83, 0x00, + 0x00, 0x00, 0xff, 0x8b, 0xff, 0xff, 0xff, 0xff, 0x83, 0x00, 0x00, 0x00, + 0xff, 0x83, 0xff, 0xff, 0xff, 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, 0x83, + 0xff, 0xff, 0xff, 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, 0x8b, 0xff, 0xff, + 0xff, 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, 0x83, 0xd8, 0xd8, 0xd8, 0xff, + 0x83, 0x00, 0x00, 0x00, 0xff, 0x87, 0x17, 0xdd, 0x8e, 0xff, 0x83, 0x00, + 0x00, 0x00, 0xff, 0x8b, 0x17, 0xdd, 0x8e, 0xff, 0x83, 0x00, 0x00, 0x00, + 0xff, 0x87, 0x17, 0xdd, 0x8e, 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, 0x87, + 0xd8, 0xd8, 0xd8, 0xff, 0x87, 0x00, 0x00, 0x00, 0xff, 0x8b, 0xd8, 0xd8, + 0xd8, 0xff, 0x87, 0x00, 0x00, 0x00, 0xff, 0x8f, 0xd8, 0xd8, 0xd8, 0xff, + 0x8b, 0xd8, 0xd8, 0xd8, 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, 0x87, 0xce, + 0x56, 0x4d, 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, 0xa3, 0xb0, 0xe4, 0xef, + 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, 0x87, 0xce, 0x56, 0x4d, 0xff, 0x83, + 0x00, 0x00, 0x00, 0xff, 0x87, 0xd8, 0xd8, 0xd8, 0xff, 0x83, 0x00, 0x00, + 0x00, 0xff, 0x8b, 0xff, 0xff, 0xff, 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, + 0x8b, 0xff, 0xff, 0xff, 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, 0x83, 0xff, + 0xff, 0xff, 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, 0x83, 0xff, 0xff, 0xff, + 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, 0x8b, 0xff, 0xff, 0xff, 0xff, 0x83, + 0x00, 0x00, 0x00, 0xff, 0x83, 0xd8, 0xd8, 0xd8, 0xff, 0x83, 0x00, 0x00, + 0x00, 0xff, 0x87, 0x17, 0xdd, 0x8e, 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, + 0x8b, 0x17, 0xdd, 0x8e, 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, 0x87, 0x17, + 0xdd, 0x8e, 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, 0x87, 0xd8, 0xd8, 0xd8, + 0xff, 0x87, 0x00, 0x00, 0x00, 0xff, 0x8b, 0xd8, 0xd8, 0xd8, 0xff, 0x87, + 0x00, 0x00, 0x00, 0xff, 0x8f, 0xd8, 0xd8, 0xd8, 0xff, 0x8b, 0xd8, 0xd8, + 0xd8, 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, 0x87, 0xce, 0x56, 0x4d, 0xff, + 0x83, 0x00, 0x00, 0x00, 0xff, 0xa3, 0xb0, 0xe4, 0xef, 0xff, 0x83, 0x00, + 0x00, 0x00, 0xff, 0x87, 0xce, 0x56, 0x4d, 0xff, 0x83, 0x00, 0x00, 0x00, + 0xff, 0x87, 0xd8, 0xd8, 0xd8, 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, 0x8b, + 0xff, 0xff, 0xff, 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, 0x8b, 0xff, 0xff, + 0xff, 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, 0x83, 0xff, 0xff, 0xff, 0xff, + 0x83, 0x00, 0x00, 0x00, 0xff, 0x83, 0xff, 0xff, 0xff, 0xff, 0x83, 0x00, + 0x00, 0x00, 0xff, 0x8b, 0xff, 0xff, 0xff, 0xff, 0x83, 0x00, 0x00, 0x00, + 0xff, 0x83, 0xd8, 0xd8, 0xd8, 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, 0x87, + 0x17, 0xdd, 0x8e, 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, 0x8b, 0x17, 0xdd, + 0x8e, 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, 0x87, 0x17, 0xdd, 0x8e, 0xff, + 0x83, 0x00, 0x00, 0x00, 0xff, 0x87, 0xd8, 0xd8, 0xd8, 0xff, 0x87, 0x00, + 0x00, 0x00, 0xff, 0x8b, 0xd8, 0xd8, 0xd8, 0xff, 0x87, 0x00, 0x00, 0x00, + 0xff, 0x8f, 0xd8, 0xd8, 0xd8, 0xff, 0x8b, 0xd8, 0xd8, 0xd8, 0xff, 0x83, + 0x00, 0x00, 0x00, 0xff, 0x87, 0xce, 0x56, 0x4d, 0xff, 0x87, 0x00, 0x00, + 0x00, 0xff, 0x83, 0xb0, 0xe4, 0xef, 0xff, 0x97, 0x00, 0x00, 0x00, 0xff, + 0x83, 0xb0, 0xe4, 0xef, 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, 0x87, 0xce, + 0x56, 0x4d, 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, 0x87, 0xd8, 0xd8, 0xd8, + 0xff, 0xc3, 0x00, 0x00, 0x00, 0xff, 0x83, 0xd8, 0xd8, 0xd8, 0xff, 0x83, + 0x00, 0x00, 0x00, 0xff, 0xa3, 0x17, 0xdd, 0x8e, 0xff, 0x83, 0x00, 0x00, + 0x00, 0xff, 0x83, 0xd8, 0xd8, 0xd8, 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, + 0x87, 0x17, 0xdd, 0x8e, 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, 0x83, 0xd8, + 0xd8, 0xd8, 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, 0x87, 0x17, 0xdd, 0x8e, + 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, 0x8b, 0xd8, 0xd8, 0xd8, 0xff, 0x8b, + 0xd8, 0xd8, 0xd8, 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, 0x87, 0xce, 0x56, + 0x4d, 0xff, 0x87, 0x00, 0x00, 0x00, 0xff, 0x83, 0xb0, 0xe4, 0xef, 0xff, + 0x97, 0x00, 0x00, 0x00, 0xff, 0x83, 0xb0, 0xe4, 0xef, 0xff, 0x83, 0x00, + 0x00, 0x00, 0xff, 0x87, 0xce, 0x56, 0x4d, 0xff, 0x83, 0x00, 0x00, 0x00, + 0xff, 0x87, 0xd8, 0xd8, 0xd8, 0xff, 0xc3, 0x00, 0x00, 0x00, 0xff, 0x83, + 0xd8, 0xd8, 0xd8, 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, 0xa3, 0x17, 0xdd, + 0x8e, 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, 0x83, 0xd8, 0xd8, 0xd8, 0xff, + 0x83, 0x00, 0x00, 0x00, 0xff, 0x87, 0x17, 0xdd, 0x8e, 0xff, 0x83, 0x00, + 0x00, 0x00, 0xff, 0x83, 0xd8, 0xd8, 0xd8, 0xff, 0x83, 0x00, 0x00, 0x00, + 0xff, 0x87, 0x17, 0xdd, 0x8e, 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, 0x8b, + 0xd8, 0xd8, 0xd8, 0xff, 0x8b, 0xd8, 0xd8, 0xd8, 0xff, 0x83, 0x00, 0x00, + 0x00, 0xff, 0x87, 0xce, 0x56, 0x4d, 0xff, 0x87, 0x00, 0x00, 0x00, 0xff, + 0x83, 0xb0, 0xe4, 0xef, 0xff, 0x97, 0x00, 0x00, 0x00, 0xff, 0x83, 0xb0, + 0xe4, 0xef, 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, 0x87, 0xce, 0x56, 0x4d, + 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, 0x87, 0xd8, 0xd8, 0xd8, 0xff, 0xc3, + 0x00, 0x00, 0x00, 0xff, 0x83, 0xd8, 0xd8, 0xd8, 0xff, 0x83, 0x00, 0x00, + 0x00, 0xff, 0xa3, 0x17, 0xdd, 0x8e, 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, + 0x83, 0xd8, 0xd8, 0xd8, 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, 0x87, 0x17, + 0xdd, 0x8e, 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, 0x83, 0xd8, 0xd8, 0xd8, + 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, 0x87, 0x17, 0xdd, 0x8e, 0xff, 0x83, + 0x00, 0x00, 0x00, 0xff, 0x8b, 0xd8, 0xd8, 0xd8, 0xff, 0x8b, 0xd8, 0xd8, + 0xd8, 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, 0x87, 0xce, 0x56, 0x4d, 0xff, + 0x87, 0x00, 0x00, 0x00, 0xff, 0x83, 0xb0, 0xe4, 0xef, 0xff, 0x97, 0x00, + 0x00, 0x00, 0xff, 0x83, 0xb0, 0xe4, 0xef, 0xff, 0x83, 0x00, 0x00, 0x00, + 0xff, 0x87, 0xce, 0x56, 0x4d, 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, 0x87, + 0xd8, 0xd8, 0xd8, 0xff, 0xc3, 0x00, 0x00, 0x00, 0xff, 0x83, 0xd8, 0xd8, + 0xd8, 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, 0xa3, 0x17, 0xdd, 0x8e, 0xff, + 0x83, 0x00, 0x00, 0x00, 0xff, 0x83, 0xd8, 0xd8, 0xd8, 0xff, 0x83, 0x00, + 0x00, 0x00, 0xff, 0x87, 0x17, 0xdd, 0x8e, 0xff, 0x83, 0x00, 0x00, 0x00, + 0xff, 0x83, 0xd8, 0xd8, 0xd8, 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, 0x87, + 0x17, 0xdd, 0x8e, 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, 0x8b, 0xd8, 0xd8, + 0xd8, 0xff, 0x8b, 0xd8, 0xd8, 0xd8, 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, + 0x87, 0xce, 0x56, 0x4d, 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, 0xa3, 0xb0, + 0xe4, 0xef, 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, 0x87, 0xce, 0x56, 0x4d, + 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, 0xcf, 0xd8, 0xd8, 0xd8, 0xff, 0x83, + 0x00, 0x00, 0x00, 0xff, 0x8f, 0x17, 0xdd, 0x8e, 0xff, 0x83, 0x00, 0x00, + 0x00, 0xff, 0x8f, 0x17, 0xdd, 0x8e, 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, + 0x83, 0xd8, 0xd8, 0xd8, 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, 0x87, 0x17, + 0xdd, 0x8e, 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, 0x83, 0xd8, 0xd8, 0xd8, + 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, 0x87, 0x17, 0xdd, 0x8e, 0xff, 0x83, + 0x00, 0x00, 0x00, 0xff, 0x8b, 0xd8, 0xd8, 0xd8, 0xff, 0x8b, 0xd8, 0xd8, + 0xd8, 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, 0x87, 0xce, 0x56, 0x4d, 0xff, + 0x83, 0x00, 0x00, 0x00, 0xff, 0xa3, 0xb0, 0xe4, 0xef, 0xff, 0x83, 0x00, + 0x00, 0x00, 0xff, 0x87, 0xce, 0x56, 0x4d, 0xff, 0x83, 0x00, 0x00, 0x00, + 0xff, 0xcf, 0xd8, 0xd8, 0xd8, 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, 0x8f, + 0x17, 0xdd, 0x8e, 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, 0x8f, 0x17, 0xdd, + 0x8e, 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, 0x83, 0xd8, 0xd8, 0xd8, 0xff, + 0x83, 0x00, 0x00, 0x00, 0xff, 0x87, 0x17, 0xdd, 0x8e, 0xff, 0x83, 0x00, + 0x00, 0x00, 0xff, 0x83, 0xd8, 0xd8, 0xd8, 0xff, 0x83, 0x00, 0x00, 0x00, + 0xff, 0x87, 0x17, 0xdd, 0x8e, 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, 0x8b, + 0xd8, 0xd8, 0xd8, 0xff, 0x8b, 0xd8, 0xd8, 0xd8, 0xff, 0x83, 0x00, 0x00, + 0x00, 0xff, 0x87, 0xce, 0x56, 0x4d, 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, + 0xa3, 0xb0, 0xe4, 0xef, 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, 0x87, 0xce, + 0x56, 0x4d, 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, 0xcf, 0xd8, 0xd8, 0xd8, + 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, 0x8f, 0x17, 0xdd, 0x8e, 0xff, 0x83, + 0x00, 0x00, 0x00, 0xff, 0x8f, 0x17, 0xdd, 0x8e, 0xff, 0x83, 0x00, 0x00, + 0x00, 0xff, 0x83, 0xd8, 0xd8, 0xd8, 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, + 0x87, 0x17, 0xdd, 0x8e, 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, 0x83, 0xd8, + 0xd8, 0xd8, 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, 0x87, 0x17, 0xdd, 0x8e, + 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, 0x8b, 0xd8, 0xd8, 0xd8, 0xff, 0x8b, + 0xd8, 0xd8, 0xd8, 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, 0x87, 0xce, 0x56, + 0x4d, 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, 0xa3, 0xb0, 0xe4, 0xef, 0xff, + 0x83, 0x00, 0x00, 0x00, 0xff, 0x87, 0xce, 0x56, 0x4d, 0xff, 0x83, 0x00, + 0x00, 0x00, 0xff, 0xcf, 0xd8, 0xd8, 0xd8, 0xff, 0x83, 0x00, 0x00, 0x00, + 0xff, 0x8f, 0x17, 0xdd, 0x8e, 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, 0x8f, + 0x17, 0xdd, 0x8e, 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, 0x83, 0xd8, 0xd8, + 0xd8, 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, 0x87, 0x17, 0xdd, 0x8e, 0xff, + 0x83, 0x00, 0x00, 0x00, 0xff, 0x83, 0xd8, 0xd8, 0xd8, 0xff, 0x83, 0x00, + 0x00, 0x00, 0xff, 0x87, 0x17, 0xdd, 0x8e, 0xff, 0x83, 0x00, 0x00, 0x00, + 0xff, 0x8b, 0xd8, 0xd8, 0xd8, 0xff, 0x8b, 0xd8, 0xd8, 0xd8, 0xff, 0x83, + 0x00, 0x00, 0x00, 0xff, 0x87, 0xce, 0x56, 0x4d, 0xff, 0x87, 0x00, 0x00, + 0x00, 0xff, 0x83, 0xb0, 0xe4, 0xef, 0xff, 0x97, 0x00, 0x00, 0x00, 0xff, + 0x83, 0xb0, 0xe4, 0xef, 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, 0x87, 0xce, + 0x56, 0x4d, 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, 0xcf, 0xd8, 0xd8, 0xd8, + 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, 0x8b, 0x17, 0xdd, 0x8e, 0xff, 0x83, + 0x00, 0x00, 0x00, 0xff, 0x83, 0xd8, 0xd8, 0xd8, 0xff, 0x83, 0x00, 0x00, + 0x00, 0xff, 0x8b, 0x17, 0xdd, 0x8e, 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, + 0x87, 0xd8, 0xd8, 0xd8, 0xff, 0x87, 0x00, 0x00, 0x00, 0xff, 0x8b, 0xd8, + 0xd8, 0xd8, 0xff, 0x87, 0x00, 0x00, 0x00, 0xff, 0x8f, 0xd8, 0xd8, 0xd8, + 0xff, 0x8b, 0xd8, 0xd8, 0xd8, 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, 0x87, + 0xce, 0x56, 0x4d, 0xff, 0x87, 0x00, 0x00, 0x00, 0xff, 0x83, 0xb0, 0xe4, + 0xef, 0xff, 0x97, 0x00, 0x00, 0x00, 0xff, 0x83, 0xb0, 0xe4, 0xef, 0xff, + 0x83, 0x00, 0x00, 0x00, 0xff, 0x87, 0xce, 0x56, 0x4d, 0xff, 0x83, 0x00, + 0x00, 0x00, 0xff, 0xcf, 0xd8, 0xd8, 0xd8, 0xff, 0x83, 0x00, 0x00, 0x00, + 0xff, 0x8b, 0x17, 0xdd, 0x8e, 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, 0x83, + 0xd8, 0xd8, 0xd8, 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, 0x8b, 0x17, 0xdd, + 0x8e, 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, 0x87, 0xd8, 0xd8, 0xd8, 0xff, + 0x87, 0x00, 0x00, 0x00, 0xff, 0x8b, 0xd8, 0xd8, 0xd8, 0xff, 0x87, 0x00, + 0x00, 0x00, 0xff, 0x8f, 0xd8, 0xd8, 0xd8, 0xff, 0x8b, 0xd8, 0xd8, 0xd8, + 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, 0x87, 0xce, 0x56, 0x4d, 0xff, 0x87, + 0x00, 0x00, 0x00, 0xff, 0x83, 0xb0, 0xe4, 0xef, 0xff, 0x97, 0x00, 0x00, + 0x00, 0xff, 0x83, 0xb0, 0xe4, 0xef, 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, + 0x87, 0xce, 0x56, 0x4d, 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, 0xcf, 0xd8, + 0xd8, 0xd8, 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, 0x8b, 0x17, 0xdd, 0x8e, + 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, 0x83, 0xd8, 0xd8, 0xd8, 0xff, 0x83, + 0x00, 0x00, 0x00, 0xff, 0x8b, 0x17, 0xdd, 0x8e, 0xff, 0x83, 0x00, 0x00, + 0x00, 0xff, 0x87, 0xd8, 0xd8, 0xd8, 0xff, 0x87, 0x00, 0x00, 0x00, 0xff, + 0x8b, 0xd8, 0xd8, 0xd8, 0xff, 0x87, 0x00, 0x00, 0x00, 0xff, 0x8f, 0xd8, + 0xd8, 0xd8, 0xff, 0x8b, 0xd8, 0xd8, 0xd8, 0xff, 0x83, 0x00, 0x00, 0x00, + 0xff, 0x87, 0xce, 0x56, 0x4d, 0xff, 0x87, 0x00, 0x00, 0x00, 0xff, 0x83, + 0xb0, 0xe4, 0xef, 0xff, 0x97, 0x00, 0x00, 0x00, 0xff, 0x83, 0xb0, 0xe4, + 0xef, 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, 0x87, 0xce, 0x56, 0x4d, 0xff, + 0x83, 0x00, 0x00, 0x00, 0xff, 0xcf, 0xd8, 0xd8, 0xd8, 0xff, 0x83, 0x00, + 0x00, 0x00, 0xff, 0x8b, 0x17, 0xdd, 0x8e, 0xff, 0x83, 0x00, 0x00, 0x00, + 0xff, 0x83, 0xd8, 0xd8, 0xd8, 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, 0x8b, + 0x17, 0xdd, 0x8e, 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, 0x87, 0xd8, 0xd8, + 0xd8, 0xff, 0x87, 0x00, 0x00, 0x00, 0xff, 0x8b, 0xd8, 0xd8, 0xd8, 0xff, + 0x87, 0x00, 0x00, 0x00, 0xff, 0x8f, 0xd8, 0xd8, 0xd8, 0xff, 0x8b, 0xd8, + 0xd8, 0xd8, 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, 0x87, 0xce, 0x56, 0x4d, + 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, 0xa3, 0xb0, 0xe4, 0xef, 0xff, 0x83, + 0x00, 0x00, 0x00, 0xff, 0x87, 0xce, 0x56, 0x4d, 0xff, 0x83, 0x00, 0x00, + 0x00, 0xff, 0xd3, 0xd8, 0xd8, 0xd8, 0xff, 0x8b, 0x00, 0x00, 0x00, 0xff, + 0x8b, 0xd8, 0xd8, 0xd8, 0xff, 0x8b, 0x00, 0x00, 0x00, 0xff, 0xb7, 0xd8, + 0xd8, 0xd8, 0xff, 0x8b, 0xd8, 0xd8, 0xd8, 0xff, 0x83, 0x00, 0x00, 0x00, + 0xff, 0x87, 0xce, 0x56, 0x4d, 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, 0xa3, + 0xb0, 0xe4, 0xef, 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, 0x87, 0xce, 0x56, + 0x4d, 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, 0xd3, 0xd8, 0xd8, 0xd8, 0xff, + 0x8b, 0x00, 0x00, 0x00, 0xff, 0x8b, 0xd8, 0xd8, 0xd8, 0xff, 0x8b, 0x00, + 0x00, 0x00, 0xff, 0xb7, 0xd8, 0xd8, 0xd8, 0xff, 0x8b, 0xd8, 0xd8, 0xd8, + 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, 0x87, 0xce, 0x56, 0x4d, 0xff, 0x83, + 0x00, 0x00, 0x00, 0xff, 0xa3, 0xb0, 0xe4, 0xef, 0xff, 0x83, 0x00, 0x00, + 0x00, 0xff, 0x87, 0xce, 0x56, 0x4d, 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, + 0xd3, 0xd8, 0xd8, 0xd8, 0xff, 0x8b, 0x00, 0x00, 0x00, 0xff, 0x8b, 0xd8, + 0xd8, 0xd8, 0xff, 0x8b, 0x00, 0x00, 0x00, 0xff, 0xb7, 0xd8, 0xd8, 0xd8, + 0xff, 0x8b, 0xd8, 0xd8, 0xd8, 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, 0x87, + 0xce, 0x56, 0x4d, 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, 0xa3, 0xb0, 0xe4, + 0xef, 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, 0x87, 0xce, 0x56, 0x4d, 0xff, + 0x83, 0x00, 0x00, 0x00, 0xff, 0xd3, 0xd8, 0xd8, 0xd8, 0xff, 0x8b, 0x00, + 0x00, 0x00, 0xff, 0x8b, 0xd8, 0xd8, 0xd8, 0xff, 0x8b, 0x00, 0x00, 0x00, + 0xff, 0xb7, 0xd8, 0xd8, 0xd8, 0xff, 0x8b, 0xd8, 0xd8, 0xd8, 0xff, 0x83, + 0x00, 0x00, 0x00, 0xff, 0x87, 0xce, 0x56, 0x4d, 0xff, 0x87, 0x00, 0x00, + 0x00, 0xff, 0x83, 0xb0, 0xe4, 0xef, 0xff, 0x97, 0x00, 0x00, 0x00, 0xff, + 0x83, 0xb0, 0xe4, 0xef, 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, 0x87, 0xce, + 0x56, 0x4d, 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, 0xff, 0xd8, 0xd8, 0xd8, + 0xff, 0xaf, 0xd8, 0xd8, 0xd8, 0xff, 0x8b, 0xd8, 0xd8, 0xd8, 0xff, 0x83, + 0x00, 0x00, 0x00, 0xff, 0x87, 0xce, 0x56, 0x4d, 0xff, 0x87, 0x00, 0x00, + 0x00, 0xff, 0x83, 0xb0, 0xe4, 0xef, 0xff, 0x97, 0x00, 0x00, 0x00, 0xff, + 0x83, 0xb0, 0xe4, 0xef, 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, 0x87, 0xce, + 0x56, 0x4d, 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, 0xff, 0xd8, 0xd8, 0xd8, + 0xff, 0xaf, 0xd8, 0xd8, 0xd8, 0xff, 0x8b, 0xd8, 0xd8, 0xd8, 0xff, 0x83, + 0x00, 0x00, 0x00, 0xff, 0x87, 0xce, 0x56, 0x4d, 0xff, 0x87, 0x00, 0x00, + 0x00, 0xff, 0x83, 0xb0, 0xe4, 0xef, 0xff, 0x97, 0x00, 0x00, 0x00, 0xff, + 0x83, 0xb0, 0xe4, 0xef, 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, 0x87, 0xce, + 0x56, 0x4d, 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, 0xff, 0xd8, 0xd8, 0xd8, + 0xff, 0xaf, 0xd8, 0xd8, 0xd8, 0xff, 0x8b, 0xd8, 0xd8, 0xd8, 0xff, 0x83, + 0x00, 0x00, 0x00, 0xff, 0x87, 0xce, 0x56, 0x4d, 0xff, 0x87, 0x00, 0x00, + 0x00, 0xff, 0x83, 0xb0, 0xe4, 0xef, 0xff, 0x97, 0x00, 0x00, 0x00, 0xff, + 0x83, 0xb0, 0xe4, 0xef, 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, 0x87, 0xce, + 0x56, 0x4d, 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, 0xff, 0xd8, 0xd8, 0xd8, + 0xff, 0xaf, 0xd8, 0xd8, 0xd8, 0xff, 0x8b, 0xd8, 0xd8, 0xd8, 0xff, 0x83, + 0x00, 0x00, 0x00, 0xff, 0x87, 0xce, 0x56, 0x4d, 0xff, 0x83, 0x00, 0x00, + 0x00, 0xff, 0xa3, 0xb0, 0xe4, 0xef, 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, + 0x87, 0xce, 0x56, 0x4d, 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, 0xff, 0xd8, + 0xd8, 0xd8, 0xff, 0xaf, 0xd8, 0xd8, 0xd8, 0xff, 0x8b, 0xd8, 0xd8, 0xd8, + 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, 0x87, 0xce, 0x56, 0x4d, 0xff, 0x83, + 0x00, 0x00, 0x00, 0xff, 0xa3, 0xb0, 0xe4, 0xef, 0xff, 0x83, 0x00, 0x00, + 0x00, 0xff, 0x87, 0xce, 0x56, 0x4d, 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, + 0xff, 0xd8, 0xd8, 0xd8, 0xff, 0xaf, 0xd8, 0xd8, 0xd8, 0xff, 0x8b, 0xd8, + 0xd8, 0xd8, 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, 0x87, 0xce, 0x56, 0x4d, + 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, 0xa3, 0xb0, 0xe4, 0xef, 0xff, 0x83, + 0x00, 0x00, 0x00, 0xff, 0x87, 0xce, 0x56, 0x4d, 0xff, 0x83, 0x00, 0x00, + 0x00, 0xff, 0xff, 0xd8, 0xd8, 0xd8, 0xff, 0xaf, 0xd8, 0xd8, 0xd8, 0xff, + 0x8b, 0xd8, 0xd8, 0xd8, 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, 0x87, 0xce, + 0x56, 0x4d, 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, 0xa3, 0xb0, 0xe4, 0xef, + 0xff, 0x83, 0x00, 0x00, 0x00, 0xff, 0x87, 0xce, 0x56, 0x4d, 0xff, 0x83, + 0x00, 0x00, 0x00, 0xff, 0xff, 0xd8, 0xd8, 0xd8, 0xff, 0xaf, 0xd8, 0xd8, + 0xd8, 0xff, 0x8b, 0xd8, 0xd8, 0xd8, 0xff, 0xc3, 0x00, 0x00, 0x00, 0xff, + 0xff, 0xd8, 0xd8, 0xd8, 0xff, 0xaf, 0xd8, 0xd8, 0xd8, 0xff, 0x8b, 0xd8, + 0xd8, 0xd8, 0xff, 0xc3, 0x00, 0x00, 0x00, 0xff, 0xff, 0xd8, 0xd8, 0xd8, + 0xff, 0xaf, 0xd8, 0xd8, 0xd8, 0xff, 0x8b, 0xd8, 0xd8, 0xd8, 0xff, 0xc3, + 0x00, 0x00, 0x00, 0xff, 0xff, 0xd8, 0xd8, 0xd8, 0xff, 0xaf, 0xd8, 0xd8, + 0xd8, 0xff, 0x8b, 0xd8, 0xd8, 0xd8, 0xff, 0xc3, 0x00, 0x00, 0x00, 0xff, + 0xff, 0xd8, 0xd8, 0xd8, 0xff, 0xaf, 0xd8, 0xd8, 0xd8, 0xff, 0xff, 0xd8, + 0xd8, 0xd8, 0xff, 0xff, 0xd8, 0xd8, 0xd8, 0xff, 0xff, 0xd8, 0xd8, 0xd8, + 0xff, 0xff, 0xd8, 0xd8, 0xd8, 0xff, 0xff, 0xd8, 0xd8, 0xd8, 0xff, 0xff, + 0xd8, 0xd8, 0xd8, 0xff, 0xff, 0xd8, 0xd8, 0xd8, 0xff, 0xff, 0xd8, 0xd8, + 0xd8, 0xff, 0xff, 0xd8, 0xd8, 0xd8, 0xff, 0xff, 0xd8, 0xd8, 0xd8, 0xff, + 0xff, 0xd8, 0xd8, 0xd8, 0xff, 0xff, 0xd8, 0xd8, 0xd8, 0xff, 0xff, 0xd8, + 0xd8, 0xd8, 0xff, 0xff, 0xd8, 0xd8, 0xd8, 0xff, 0xff, 0xd8, 0xd8, 0xd8, + 0xff, 0xff, 0xd8, 0xd8, 0xd8, 0xff, 0xff, 0xd8, 0xd8, 0xd8, 0xff, 0xff, + 0xd8, 0xd8, 0xd8, 0xff, 0xff, 0xd8, 0xd8, 0xd8, 0xff, 0xff, 0xd8, 0xd8, + 0xd8, 0xff, 0xff, 0xd8, 0xd8, 0xd8, 0xff, 0xff, 0xd8, 0xd8, 0xd8, 0xff, + 0xff, 0xd8, 0xd8, 0xd8, 0xff, 0xff, 0xd8, 0xd8, 0xd8, 0xff, 0xff, 0xd8, + 0xd8, 0xd8, 0xff, 0xff, 0xd8, 0xd8, 0xd8, 0xff, 0xff, 0xd8, 0xd8, 0xd8, + 0xff, 0xff, 0xd8, 0xd8, 0xd8, 0xff, 0xff, 0xd8, 0xd8, 0xd8, 0xff, 0xff, + 0xd8, 0xd8, 0xd8, 0xff, 0xff, 0xd8, 0xd8, 0xd8, 0xff, 0xff, 0xd8, 0xd8, + 0xd8, 0xff +}; +unsigned int icon_tga_len = 7478; + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/lib_easy.c b/src/lib_easy.c index 00226b6..d7a6bbe 100644 --- a/src/lib_easy.c +++ b/src/lib_easy.c @@ -6,34 +6,18 @@ VPADData vpad; int screen_buf0_size = 0; int screen_buf1_size = 0; -void flipBuffers() { - // Flush the cache - DCFlushRange(screenBuffer, screen_buf0_size); - DCFlushRange((screenBuffer + screen_buf0_size), screen_buf1_size); - // Flip buffers - OSScreenFlipBuffersEx(0); - OSScreenFlipBuffersEx(1); -} - -void ucls() { - for(int i=0;i<2;i++) { - OSScreenClearBufferEx(0, 0); - OSScreenClearBufferEx(1, 0); - flipBuffers(); - } -} - void ScreenInit() { //Init screen and screen buffers OSScreenInit(); screen_buf0_size = OSScreenGetBufferSizeEx(0); screen_buf1_size = OSScreenGetBufferSizeEx(1); - screenBuffer = MEM1_alloc(screen_buf0_size + screen_buf1_size, 0x40); + screenBuffer = MEM1_alloc(screen_buf0_size + screen_buf1_size, 0x100); OSScreenSetBufferEx(0, screenBuffer); OSScreenSetBufferEx(1, (screenBuffer + screen_buf0_size)); OSScreenEnableEx(0, 1); OSScreenEnableEx(1, 1); - ucls(); //Clear screens + clearBuffers(); //Clear screens + initDraw(screenBuffer, screen_buf0_size, screen_buf1_size); } void updatePressedButtons() { @@ -56,11 +40,17 @@ bool stickPos(u8 stick, f32 value) { case 0 : return (value > 0) ? (vpad.lstick.x > value): (vpad.lstick.x < value); case 1 : - return ((value > 0) ? (vpad.lstick.y > value): (vpad.lstick.y < value)); + return (value > 0) ? (vpad.lstick.y > value): (vpad.lstick.y < value); case 2 : return (value > 0) ? (vpad.rstick.x > value): (vpad.rstick.x < value); case 3 : return (value > 0) ? (vpad.rstick.y > value): (vpad.rstick.y < value); + case 4 : + return ((vpad.lstick.x > value) || (vpad.lstick.x < -value)) || \ + ((vpad.lstick.y > value) || (vpad.lstick.y < -value)) || \ + ((vpad.rstick.x > value) || (vpad.rstick.x < -value)) || \ + ((vpad.rstick.y > value) || (vpad.rstick.y < -value)); + default : return 0; } diff --git a/src/lib_easy.h b/src/lib_easy.h index 5b6bef6..e8f46ab 100644 --- a/src/lib_easy.h +++ b/src/lib_easy.h @@ -43,9 +43,7 @@ uint32_t buttons_hold; //Held buttons uint32_t buttons_pressed; //Pressed buttons uint32_t buttons_released; //Released buttons -void ucls(); void ScreenInit(); -void flipBuffers(); void updatePressedButtons(); void updateHeldButtons(); void updateReleasedButtons(); diff --git a/src/main.c b/src/main.c index 0d6e703..520d962 100644 --- a/src/main.c +++ b/src/main.c @@ -2,23 +2,23 @@ #include #include #include -#include -#include -#include #include "main.h" #include "savemng.h" +#include "icon.h" #define VERSION_MAJOR 1 #define VERSION_MINOR 2 #define VERSION_MICRO 0 -#define VERSION_MOD "mod4" +#define VERSION_MOD "mod5" +#define M_OFF 3 u8 slot = 0; -bool allusers = 0, common = 1; +s8 allusers = -1, allusers_d = -1, sdusers = -1; +bool common = 1; int menu = 0, mode = 0, task = 0, targ = 0, tsort = 1, sorta = 1; int cursor = 0, scroll = 0; -int cursorb = 0, scrollb = 0; +int cursorb = 0, cursort = 0, scrollb = 0; int titleswiiu = 0, titlesvwii = 0; const char *sortn[4] = {"None", "Name", "Storage", "Storage+Name"}; @@ -34,7 +34,7 @@ int MCPHookOpen() { if (mcp_hook_fd < 0) return -1; IOS_IoctlAsync(mcp_hook_fd, 0x62, (void*)0, 0, (void*)0, 0, someFunc, (void*)0); //let wupserver start up - sleep(1); + os_sleep(1); if (IOSUHAX_Open("/dev/mcp") < 0) { MCP_Close(mcp_hook_fd); mcp_hook_fd = -1; @@ -48,18 +48,18 @@ void MCPHookClose() { //close down wupserver, return control to mcp IOSUHAX_Close(); //wait for mcp to return - sleep(1); + os_sleep(1); MCP_Close(mcp_hook_fd); mcp_hook_fd = -1; } int titleSort(const void *c1, const void *c2) { - if (tsort==0) { + if (tsort == 0) { return ((Title*)c1)->listID - ((Title*)c2)->listID; - } else if (tsort==1) { + } else if (tsort == 1) { return strcmp(((Title*)c1)->shortName,((Title*)c2)->shortName) * sorta; - } else if (tsort==2) { + } else if (tsort == 2) { if (((Title*)c1)->isTitleOnUSB == ((Title*)c2)->isTitleOnUSB) return 0; if (((Title*)c1)->isTitleOnUSB) @@ -67,7 +67,7 @@ int titleSort(const void *c1, const void *c2) if (((Title*)c2)->isTitleOnUSB) return 1 * sorta; return 0; - } else if (tsort==3) { + } else if (tsort == 3) { if (((Title*)c1)->isTitleOnUSB && !((Title*)c2)->isTitleOnUSB) return -1 * sorta; if (!((Title*)c1)->isTitleOnUSB && ((Title*)c2)->isTitleOnUSB) @@ -111,10 +111,10 @@ Title* loadWiiUTitles(int run, int fsaFd) { savesl[j].found = false; j++; } - savesl = realloc(savesl, usable*sizeof(Saves)); + savesl = realloc(savesl, usable * sizeof(Saves)); int dirUH, dirNH, foundCount = 0, pos = 0, tNoSave = usable; - for(int i = 0; i <= 1; i++) { + for (int i = 0; i <= 1; i++) { char path[255]; sprintf(path, "/vol/storage_%s01/usr/save/00050000", (i == 0) ? "usb" : "mlc"); if (IOSUHAX_FSA_OpenDir(fsaFd, path, &dirUH) >= 0) { @@ -149,7 +149,8 @@ Title* loadWiiUTitles(int run, int fsaFd) { promptError("Out of memory."); return NULL; } - for(int i = 0; i <= 1; i++) { + + for (int i = 0; i <= 1; i++) { char path[255]; sprintf(path, "/vol/storage_%s01/usr/save/00050000", (i == 0) ? "usb" : "mlc"); if (IOSUHAX_FSA_OpenDir(fsaFd, path, &dirUH) >= 0) { @@ -171,6 +172,7 @@ Title* loadWiiUTitles(int run, int fsaFd) { IOSUHAX_FSA_CloseDir(fsaFd, dirUH); } } + for (int i = 0; i < usable; i++) { if (!savesl[i].found) { saves[pos].highID = savesl[i].highID; @@ -200,27 +202,25 @@ Title* loadWiiUTitles(int run, int fsaFd) { sprintf(path, "/vol/storage_%s01/usr/save/%08x/%08x/meta/meta.xml", isTitleOnUSB ? "usb" : "mlc", highID, lowID); titles[titleswiiu].saveInit = !saves[i].found; - int ret = IOSUHAX_FSA_OpenFile(fsaFd, path, "rb", &srcFd); - if (ret >= 0) { - fileStat_s fStat; - IOSUHAX_FSA_StatFile(fsaFd, srcFd, &fStat); - size_t xmlSize = fStat.size; + char* xmlBuf = NULL; + if (loadFile(path, &xmlBuf) > 0) { + char *cptr = strchr(strstr(xmlBuf, "product_code"), '>') + 7; + memset(titles[titleswiiu].productCode, 0, sizeof(titles[titleswiiu].productCode)); + strncpy(titles[titleswiiu].productCode, cptr, strcspn(cptr, "<")); - char* xmlBuf = malloc(xmlSize+1); - if (xmlBuf) { - memset(xmlBuf, 0, xmlSize+1); - IOSUHAX_FSA_ReadFile(fsaFd, xmlBuf, 0x01, xmlSize, srcFd, 0); - IOSUHAX_FSA_CloseFile(fsaFd, srcFd); + cptr = strchr(strstr(xmlBuf, "shortname_en"), '>') + 1; + memset(titles[titleswiiu].shortName, 0, sizeof(titles[titleswiiu].shortName)); + if (strcspn(cptr, "<") == 0) + cptr = strchr(strstr(xmlBuf, "shortname_ja"), '>') + 1; + strncpy(titles[titleswiiu].shortName, cptr, strcspn(cptr, "<")); - char *cptr = strchr(strstr(xmlBuf, "product_code"), '>') + 7; - strncpy(titles[titleswiiu].productCode, cptr, strcspn(cptr, "<")); + cptr = strchr(strstr(xmlBuf, "longname_en"), '>') + 1; + memset(titles[i].longName, 0, sizeof(titles[i].longName)); + if (strcspn(cptr, "<") == 0) + cptr = strchr(strstr(xmlBuf, "longname_ja"), '>') + 1; + strncpy(titles[titleswiiu].longName, cptr, strcspn(cptr, "<")); - cptr = strchr(strstr(xmlBuf, "shortname_en"), '>') + 1; - memset(titles[titleswiiu].shortName, 0, sizeof(titles[titleswiiu].shortName)); - strncpy(titles[titleswiiu].shortName, cptr, strcspn(cptr, "<")); - - free(xmlBuf); - } + free(xmlBuf); } titles[titleswiiu].isTitleDupe = false; @@ -237,13 +237,14 @@ Title* loadWiiUTitles(int run, int fsaFd) { titles[titleswiiu].lowID = lowID; titles[titleswiiu].isTitleOnUSB = isTitleOnUSB; titles[titleswiiu].listID = titleswiiu; + if (loadTitleIcon(&titles[titleswiiu]) < 0) titles[titleswiiu].iconBuf = NULL; titleswiiu++; OSScreenClearBufferEx(0, 0); OSScreenClearBufferEx(1, 0); - console_print_pos(0, 0, "Loaded %i Wii U titles.", titleswiiu); - OSScreenFlipBuffersEx(0); - OSScreenFlipBuffersEx(1); + drawTGA(298, 144, 1, icon_tga); + console_print_pos_aligned(10, 0, 1, "Loaded %i Wii U titles.", titleswiiu); + flipBuffers(); } @@ -256,86 +257,156 @@ Title* loadWiiUTitles(int run, int fsaFd) { Title* loadWiiTitles(int fsaFd) { int dirH; + char* highIDs[3] = {"00010000", "00010001", "00010004"}; + bool found = false; + u32* blacklist[7][2] = {{0x00010000, 0x00555044}, {0x00010000, 0x00555045}, \ + {0x00010000, 0x0055504A}, {0x00010000, 0x524F4E45}, \ + {0x00010000, 0x52543445}, {0x00010001, 0x48424344}, + {0x00010001, 0x554E454F}}; - if (IOSUHAX_FSA_OpenDir(fsaFd, "/vol/storage_slccmpt01/title/00010000", &dirH) < 0) return -1; - while (1) { - directoryEntry_s data; - int ret = IOSUHAX_FSA_ReadDir(fsaFd, dirH, &data); - if (ret != 0) - break; + char pathW[256]; + for (int k = 0; k < 3; k++) { + sprintf(pathW, "/vol/storage_slccmpt01/title/%s", highIDs[k]); + if (IOSUHAX_FSA_OpenDir(fsaFd, pathW, &dirH) >= 0) { + while (1) { + directoryEntry_s data; + int ret = IOSUHAX_FSA_ReadDir(fsaFd, dirH, &data); + if (ret != 0) break; + for (int ii = 0; ii < 7; ii++) { + if (blacklist[ii][0] == strtoul(highIDs[k], NULL, 16)) { + if (blacklist[ii][1] == strtoul(data.name, NULL, 16)) {found = true; break;} + } + } if (found) {found = false; continue;} - titlesvwii++; - } IOSUHAX_FSA_RewindDir(fsaFd, dirH); + titlesvwii++; + } IOSUHAX_FSA_CloseDir(fsaFd, dirH); + } + } + if (titlesvwii == 0) return NULL; - Title* titles = malloc(titlesvwii*sizeof(Title)); + Title* titles = malloc(titlesvwii * sizeof(Title)); if (!titles) { promptError("Out of memory."); return NULL; } int i = 0; - while (1) { - directoryEntry_s data; - int ret = IOSUHAX_FSA_ReadDir(fsaFd, dirH, &data); - if (ret != 0) - break; - - int srcFd = -1; - char path[256]; - sprintf(path, "/vol/storage_slccmpt01/title/00010000/%s/data/banner.bin", data.name); - ret = IOSUHAX_FSA_OpenFile(fsaFd, path, "rb", &srcFd); - if (ret >= 0) { - IOSUHAX_FSA_SetFilePos(fsaFd, srcFd, 0x20); - u16* bnrBuf = (u16*)malloc(0x40); - if (bnrBuf) { - IOSUHAX_FSA_ReadFile(fsaFd, bnrBuf, 0x02, 0x20, srcFd, 0); - IOSUHAX_FSA_CloseFile(fsaFd, srcFd); - - int uni = 0; - for (int j = 0, k = 0; j < 0x20; j++) { - if (bnrBuf[j] > 127) { - titles[i].shortName[k++] = '?'; - uni++; - } else { - titles[i].shortName[k++] = (char)bnrBuf[j]; - if ((char)bnrBuf[j] == 0) - uni++; + for (int k = 0; k < 3; k++) { + sprintf(pathW, "/vol/storage_slccmpt01/title/%s", highIDs[k]); + if (IOSUHAX_FSA_OpenDir(fsaFd, pathW, &dirH) >= 0) { + while (1) { + directoryEntry_s data; + int ret = IOSUHAX_FSA_ReadDir(fsaFd, dirH, &data); + if (ret != 0) break; + for (int ii = 0; ii < 7; ii++) { + if (blacklist[ii][0] == strtoul(highIDs[k], NULL, 16)) { + if (blacklist[ii][1] == strtoul(data.name, NULL, 16)) {found = true; break;} } + } if (found) {found = false; continue;} + + int srcFd = -1; + char path[256]; + sprintf(path, "/vol/storage_slccmpt01/title/%s/%s/data/banner.bin", highIDs[k], data.name); + ret = IOSUHAX_FSA_OpenFile(fsaFd, path, "rb", &srcFd); + if (ret >= 0) { + IOSUHAX_FSA_SetFilePos(fsaFd, srcFd, 0x20); + u16* bnrBuf = (u16*)malloc(0x80); + if (bnrBuf) { + IOSUHAX_FSA_ReadFile(fsaFd, bnrBuf, 0x02, 0x40, srcFd, 0); + IOSUHAX_FSA_CloseFile(fsaFd, srcFd); + + memset(titles[i].shortName, 0, sizeof(titles[i].shortName)); + for (int j = 0, k = 0; j < 0x20; j++) { + if (bnrBuf[j] < 0x80) + titles[i].shortName[k++] = (char)bnrBuf[j]; + else if ((bnrBuf[j] & 0xF000) > 0) { + titles[i].shortName[k++] = 0xE0 | ((bnrBuf[j] & 0xF000) >> 12); + titles[i].shortName[k++] = 0x80 | ((bnrBuf[j] & 0xFC0) >> 6); + titles[i].shortName[k++] = 0x80 | (bnrBuf[j] & 0x3F); + } else if (bnrBuf[j] < 0x400) { + titles[i].shortName[k++] = 0xC0 | ((bnrBuf[j] & 0x3C0) >> 6); + titles[i].shortName[k++] = 0x80 | (bnrBuf[j] & 0x3F); + } else { + titles[i].shortName[k++] = 0xD0 | ((bnrBuf[j] & 0x3C0) >> 6); + titles[i].shortName[k++] = 0x80 | (bnrBuf[j] & 0x3F); + } + } + + memset(titles[i].longName, 0, sizeof(titles[i].longName)); + for (int j = 0x20, k = 0; j < 0x40; j++) { + if (bnrBuf[j] < 0x80) + titles[i].longName[k++] = (char)bnrBuf[j]; + else if ((bnrBuf[j] & 0xF000) > 0) { + titles[i].longName[k++] = 0xE0 | ((bnrBuf[j] & 0xF000) >> 12); + titles[i].longName[k++] = 0x80 | ((bnrBuf[j] & 0xFC0) >> 6); + titles[i].longName[k++] = 0x80 | (bnrBuf[j] & 0x3F); + } else if (bnrBuf[j] < 0x400) { + titles[i].longName[k++] = 0xC0 | ((bnrBuf[j] & 0x3C0) >> 6); + titles[i].longName[k++] = 0x80 | (bnrBuf[j] & 0x3F); + } else { + titles[i].longName[k++] = 0xD0 | ((bnrBuf[j] & 0x3C0) >> 6); + titles[i].longName[k++] = 0x80 | (bnrBuf[j] & 0x3F); + } + } + + free(bnrBuf); + titles[i].saveInit = true; + } + } else { + sprintf(titles[i].shortName, "%s%s (No banner.bin)", highIDs[k], data.name); + memset(titles[i].longName, 0, sizeof(titles[i].longName)); + titles[i].saveInit = false; } - free(bnrBuf); - if (uni == 0x20) - sprintf(titles[i].shortName, "00010000%s (No ASCII char in title)", data.name); + + titles[i].highID = strtoul(highIDs[k], NULL, 16); + titles[i].lowID = strtoul(data.name, NULL, 16); + + titles[i].listID = i; + memcpy(titles[i].productCode, &titles[i].lowID, 4); + for (int ii = 0; ii < 4; ii++) { + if (titles[i].productCode[ii] == 0) titles[i].productCode[ii] = '.'; + } + titles[i].productCode[4] = 0; + titles[i].isTitleOnUSB = false; + titles[i].isTitleDupe = false; + titles[i].dupeID = 0; + if (!titles[i].saveInit || (loadTitleIcon(&titles[i]) < 0)) titles[i].iconBuf = NULL; + i++; + + OSScreenClearBufferEx(0, 0); + OSScreenClearBufferEx(1, 0); + drawTGA(298, 144, 1, icon_tga); + console_print_pos_aligned(10, 0, 1, "Loaded %i Wii U titles.", titleswiiu); + console_print_pos_aligned(11, 0, 1, "Loaded %i Wii titles.", i); + flipBuffers(); } - } else { - sprintf(titles[i].shortName, "00010000%s (No banner.bin)", data.name); + IOSUHAX_FSA_CloseDir(fsaFd, dirH); } - - titles[i].highID = 0x00010000; - titles[i].lowID = strtoul(data.name, NULL, 16); - - titles[i].listID = i; - sprintf(titles[i].productCode, "?"); - titles[i].isTitleOnUSB = false; - titles[i].isTitleDupe = false; - titles[i].dupeID = 0; - i++; - - OSScreenClearBufferEx(0, 0); - OSScreenClearBufferEx(1, 0); - console_print_pos(0, 1, "Loaded %i Wii titles.", i); - OSScreenFlipBuffersEx(0); - OSScreenFlipBuffersEx(1); } - IOSUHAX_FSA_CloseDir(fsaFd, dirH); return titles; - } -void unloadTitles(Title* titles) { +void unloadTitles(Title* titles, int count) { + for (int i = 0; i < count; i++) { + if (titles[i].iconBuf) free(titles[i].iconBuf); + } if (titles) free(titles); } +void disclaimer() { + fillScreen(0, 0, 0, 0); + console_print_pos_aligned(3, 0, 1, "Savemii Mod"); + //drawTGA(298, 36, 1, icon_tga); + console_print_pos_aligned(6, 0, 1, "Created by: Ryuzaki-MrL"); + console_print_pos_aligned(7, 0, 1, "Modded by: GabyPCgeeK"); + console_print_pos_aligned(11, 0, 1, "Disclaimer:"); + console_print_pos_aligned(12, 0, 1, "There is always the potential for a brick."); + console_print_pos_aligned(13, 0, 1, "Everything you do with this software is your own responsibility"); + flipBuffers(); + os_sleep(4); +} + /* Entry point */ int Menu_Main(void) { @@ -348,11 +419,11 @@ int Menu_Main(void) { } if (res < 0) { promptError("IOSUHAX_Open failed."); - unmount_sd_fat("sd"); + //unmount_sd_fat("sd"); return EXIT_SUCCESS; } - //fatInitDefault(); + fatInitDefault(); int fsaFd = IOSUHAX_FSA_Open(); if (fsaFd < 0) { @@ -365,26 +436,64 @@ int Menu_Main(void) { setFSAFD(fsaFd); IOSUHAX_FSA_Mount(fsaFd, "/dev/sdcard01", "/vol/storage_sdcard", 2, (void*)0, 0); - //mount_fs("sd", fsaFd, NULL, "/vol/storage_sdcard"); + mount_fs("sd", fsaFd, NULL, "/vol/storage_sdcard"); mount_fs("slccmpt01", fsaFd, "/dev/slccmpt01", "/vol/storage_slccmpt01"); mount_fs("storage_mlc", fsaFd, NULL, "/vol/storage_mlc01"); mount_fs("storage_usb", fsaFd, NULL, "/vol/storage_usb01"); mount_fs("storage_odd", fsaFd, "/dev/odd03", "/vol/storage_odd_content"); - ucls(); + u8* fontBuf = NULL; + s32 fsize = loadFile("/vol/storage_sdcard/wiiu/apps/savemii_mod/font.ttf", &fontBuf); + if (fsize > 0) { + initFont(fontBuf, fsize); + } else initFont(NULL, 0); + + disclaimer(); + clearBuffers(); Title* wiiutitles = loadWiiUTitles(1, fsaFd); Title* wiititles = loadWiiTitles(fsaFd); - int* versionList = (int*)malloc(0x100*sizeof(int)); + int* versionList = (int*)malloc(0x100 * sizeof(int)); + os_sleep(1); + getAccountsWiiU(); qsort(wiiutitles, titleswiiu, sizeof(Title), titleSort); qsort(wiititles, titlesvwii, sizeof(Title), titleSort); - while(1) { - OSScreenClearBufferEx(0, 0); - OSScreenClearBufferEx(1, 0); + u8* tgaBufDRC = NULL; + u8* tgaBufTV = NULL; + u8* fileContent = NULL; + u32 wDRC = 0, hDRC = 0, wTV = 0, hTV = 0; + + if (loadFile("/vol/storage_sdcard/wiiu/apps/savemii_mod/backgroundDRC.tga", &fileContent) > 0) { + wDRC = tgaGetWidth(fileContent); hDRC = tgaGetHeight(fileContent); + tgaBufDRC = tgaRead(fileContent, TGA_READER_RGBA); + free(fileContent); + fileContent = NULL; + } + + if (loadFile("/vol/storage_sdcard/wiiu/apps/savemii_mod/backgroundTV.tga", &fileContent) > 0) { + wTV = tgaGetWidth(fileContent); hTV = tgaGetHeight(fileContent); + tgaBufTV = tgaRead(fileContent, TGA_READER_RGBA); + free(fileContent); + fileContent = NULL; + } + + while(1) { + //u64 startTime = OSGetTime(); + + if (tgaBufDRC) { + drawBackgroundDRC(wDRC, hDRC, tgaBufDRC); + } else { + OSScreenClearBufferEx(1, 0x00006F00); + } + if (tgaBufTV) { + drawBackgroundTV(wTV, hTV, tgaBufTV); + } else { + OSScreenClearBufferEx(0, 0x00006F00); + } console_print_pos(0, 0, "SaveMii v%u.%u.%u.%s", VERSION_MAJOR, VERSION_MINOR, VERSION_MICRO, VERSION_MOD); - console_print_pos(0, 1, "--------------------------------------------------"); + console_print_pos(0, 1, "----------------------------------------------------------------------------"); Title* titles = mode ? wiititles : wiiutitles; int count = mode ? titlesvwii : titleswiiu; @@ -392,126 +501,323 @@ int Menu_Main(void) { switch(menu) { case 0: { // Main Menu - entrycount = 2; - console_print_pos(0, 2, " Wii U Save Management (%u Title%s)", titleswiiu, (titleswiiu > 1) ? "s": ""); - console_print_pos(0, 3, " vWii Save Management (%u Title%s)", titlesvwii, (titlesvwii > 1) ? "s": ""); - console_print_pos(0, 2 + cursor, "->"); + entrycount = 3; + console_print_pos(M_OFF, 2, " Wii U Save Management (%u Title%s)", titleswiiu, (titleswiiu > 1) ? "s": ""); + console_print_pos(M_OFF, 3, " vWii Save Management (%u Title%s)", titlesvwii, (titlesvwii > 1) ? "s": ""); + console_print_pos(M_OFF, 4, " Batch Backup"); + console_print_pos(M_OFF, 2 + cursor, "\u2192"); + console_print_pos_aligned(17, 4, 2, "\ue000: Select Mode"); } break; case 1: { // Select Title - console_print_pos(30, 0, "Sort: %s %s", sortn[tsort], (tsort > 0) ? ((sorta == 1) ? "v": "^"): ""); - entrycount = count; - for (int i = 0; i < 14; i++) { - if (i+scroll<0 || i+scroll>=count) break; - if (strlen(titles[i+scroll].shortName)) console_print_pos(0, i+2, " %s %s%s%s", titles[i+scroll].shortName, titles[i+scroll].isTitleOnUSB ? "(USB)" : ((mode == 0) ? "(NAND)" : ""), titles[i+scroll].isTitleDupe ? " [D]" : "", titles[i+scroll].saveInit ? "" : " [Not Init]"); - else console_print_pos(0, i+2, " %08lx%08lx", titles[i+scroll].highID, titles[i+scroll].lowID); - } console_print_pos(0, 2 + cursor, "->"); + if (mode == 2) { + entrycount = 3; + console_print_pos(M_OFF, 2, " Backup All (%u Title%s)", titleswiiu + titlesvwii, ((titleswiiu + titlesvwii) > 1) ? "s": ""); + console_print_pos(M_OFF, 3, " Backup Wii U (%u Title%s)", titleswiiu, (titleswiiu > 1) ? "s": ""); + console_print_pos(M_OFF, 4, " Backup vWii (%u Title%s)", titlesvwii, (titlesvwii > 1) ? "s": ""); + console_print_pos(M_OFF, 2 + cursor, "\u2192"); + console_print_pos_aligned(17, 4, 2, "\ue000: Backup \ue001: Back"); + } else { + console_print_pos(40, 0, "\ue084 Sort: %s %s", sortn[tsort], (tsort > 0) ? ((sorta == 1) ? "\u2193 \ue083": "\u2191 \ue083"): ""); + entrycount = count; + for (int i = 0; i < 14; i++) { + if (i + scroll < 0 || i + scroll >= count) break; + ttfFontColor32(0x00FF00FF); + if (!titles[i + scroll].saveInit) ttfFontColor32(0xFFFF00FF); + if (strcmp(titles[i + scroll].shortName, "DONT TOUCH ME") == 0) ttfFontColor32(0xFF0000FF); + if (strlen(titles[i + scroll].shortName)) console_print_pos(M_OFF, i+2, " %s %s%s%s", titles[i + scroll].shortName, titles[i + scroll].isTitleOnUSB ? "(USB)" : ((mode == 0) ? "(NAND)" : ""), titles[i + scroll].isTitleDupe ? " [D]" : "", titles[i + scroll].saveInit ? "" : " [Not Init]"); + else console_print_pos(M_OFF, i+2, " %08lx%08lx", titles[i + scroll].highID, titles[i + scroll].lowID); + ttfFontColor32(0xFFFFFFFF); + if (mode == 0) { + if (titles[i + scroll].iconBuf) drawTGA((M_OFF + 4) * 12 - 2, (i + 3) * 24, 0.18, titles[i + scroll].iconBuf); + } else if (mode == 1) { + if (titles[i + scroll].iconBuf) drawRGB5A3((M_OFF + 2) * 12 - 2, (i + 3) * 24 + 3, 0.25, titles[i + scroll].iconBuf); + } + } + if (mode == 0) { + console_print_pos(0, 2 + cursor, "\u2192"); + } else if (mode == 1) { + console_print_pos(-1, 2 + cursor, "\u2192"); + } + console_print_pos_aligned(17, 4, 2, "\ue000: Select Game \ue001: Back"); + } } break; case 2: { // Select Task - entrycount = 3 + 2*(mode==0) + 1*((mode==0) && (titles[targ].isTitleDupe)); - console_print_pos(0, 2, " [%08X%08X]", titles[targ].highID, titles[targ].lowID); - console_print_pos(0, 3, " [%s] %s", titles[targ].productCode, titles[targ].shortName); - console_print_pos(0, 2+3, " Backup savedata"); - console_print_pos(0, 3+3, " Restore savedata"); - console_print_pos(0, 4+3, " Wipe savedata"); - if (mode==0) { - console_print_pos(0, 5+3, " Import from loadiine"); - console_print_pos(0, 6+3, " Export to loadiine"); - if (titles[targ].isTitleDupe) { - console_print_pos(0, 7+3, " Copy Savedata to Title in %s", titles[targ].isTitleOnUSB ? "NAND" : "USB"); - } + entrycount = 3 + 2 * (mode == 0) + 1 * ((mode == 0) && (titles[targ].isTitleDupe)); + console_print_pos(M_OFF, 2, " [%08X-%08X] [%s]", titles[targ].highID, titles[targ].lowID, titles[targ].productCode); + console_print_pos(M_OFF, 3, " %s", titles[targ].shortName); + //console_print_pos(M_OFF, 4, " %s", titles[targ].longName); + console_print_pos(M_OFF, 5, " Backup savedata"); + console_print_pos(M_OFF, 6, " Restore savedata"); + console_print_pos(M_OFF, 7, " Wipe savedata"); + if (mode == 0) { + console_print_pos(M_OFF, 8, " Import from loadiine"); + console_print_pos(M_OFF, 9, " Export to loadiine"); + if (titles[targ].isTitleDupe) { + console_print_pos(M_OFF, 10, " Copy Savedata to Title in %s", titles[targ].isTitleOnUSB ? "NAND" : "USB"); + } + if (titles[targ].iconBuf) drawTGA(660, 80, 1, titles[targ].iconBuf); + } else if (mode == 1) { + if (titles[targ].iconBuf) drawRGB5A3(650, 80, 1, titles[targ].iconBuf); } - console_print_pos(0, 2+3 + cursor, "->"); + console_print_pos(M_OFF, 2 + 3 + cursor, "\u2192"); + console_print_pos_aligned(17, 4, 2, "\ue000: Select Task \ue001: Back"); } break; case 3: { // Select Options - entrycount = 1 + 2*(mode==0); - console_print_pos(0, 2, "Select %s:", task>2 ? "version" : "slot"); - if (task == 5) console_print_pos(0, 3, " < %s >", titles[targ].isTitleOnUSB ? "NAND" : "USB"); - else if (task > 2) console_print_pos(0, 3, " < v%u >", versionList ? versionList[slot] : 0); - else console_print_pos(0, 3, " < %03u > (%s)", slot, isSlotEmpty(titles[targ].highID, titles[targ].lowID, slot) ? "Empty" : "Used"); - if (mode==0) { - console_print_pos(0, 5, "Select user:"); - char usrPath[16]; - getUserID(usrPath); - console_print_pos(0, 6, " < %s > %s", (allusers&&((task<3) || task==5)) ? "all users" : "this user", (allusers&&((task<3) || task==5)) ? "" : usrPath); - if (hasCommonSave(&titles[targ], (task == 0 ? false : true), ((task < 3) || (task == 5) ? false : true), slot, versionList ? versionList[slot] : 0)) { - console_print_pos(0, 8, "Include 'common' save?"); - console_print_pos(0, 9, " < %s >", common ? "yes" : "no "); + entrycount = 3; + console_print_pos(M_OFF, 2, "[%08X-%08X] %s", titles[targ].highID, titles[targ].lowID, titles[targ].shortName); + + if (task == 5) { + console_print_pos(M_OFF, 4, "Destination:"); + console_print_pos(M_OFF, 5, " (%s)", titles[targ].isTitleOnUSB ? "NAND" : "USB"); + } else if (task > 2) { + entrycount = 2; + console_print_pos(M_OFF, 4, "Select %s:", "version"); + console_print_pos(M_OFF, 5, " < v%u >", versionList ? versionList[slot] : 0); + } else if (task == 2) { + console_print_pos(M_OFF, 4, "Delete from:"); + console_print_pos(M_OFF, 5, " (%s)", titles[targ].isTitleOnUSB ? "USB" : "NAND"); + } else { + console_print_pos(M_OFF, 4, "Select %s:", "slot"); + + if (((titles[targ].highID & 0xFFFFFFF0) == 0x00010000) && (slot == 255)) { + console_print_pos(M_OFF, 5, " < SaveGame Manager GX > (%s)", isSlotEmpty(titles[targ].highID, titles[targ].lowID, slot) ? "Empty" : "Used"); } else { - common = false; - console_print_pos(0, 8, "No 'common' save found."); - entrycount--; + console_print_pos(M_OFF, 5, " < %03u > (%s)", slot, isSlotEmpty(titles[targ].highID, titles[targ].lowID, slot) ? "Empty" : "Used"); } - console_print_pos(0, 3 + cursor*3, "->"); + } + + if (mode == 0) { + if (task == 1) { + if (!isSlotEmpty(titles[targ].highID, titles[targ].lowID, slot)) { + entrycount++; + console_print_pos(M_OFF, 7, "Select SD user to copy from:"); + if (sdusers == -1) + console_print_pos(M_OFF, 8, " < %s >", "all users"); + else + console_print_pos(M_OFF, 8, " < %s > (%s)", sdacc[sdusers].persistentID, hasAccountSave(&titles[targ], true, false, sdacc[sdusers].pID, slot, 0) ? "Has Save" : "Empty"); + } + } + + if (task == 2) { + console_print_pos(M_OFF, 7, "Select Wii U user to delete from:"); + if (allusers == -1) + console_print_pos(M_OFF, 8, " < %s >", "all users"); + else + console_print_pos(M_OFF, 8, " < %s (%s) > (%s)", wiiuacc[allusers].miiName, wiiuacc[allusers].persistentID, hasAccountSave(&titles[targ], false, false, wiiuacc[allusers].pID, slot, 0) ? "Has Save" : "Empty"); + } + + if ((task == 0) || (task == 1) || (task == 5)) { + if ((task == 1) && isSlotEmpty(titles[targ].highID, titles[targ].lowID, slot)) { + entrycount--; + } else { + console_print_pos(M_OFF, (task == 1) ? 10 : 7, "Select Wii U user%s:", (task == 5) ? " to copy from" : ((task == 1) ? " to copy to" : "")); + if (allusers == -1) + console_print_pos(M_OFF, (task == 1) ? 11 : 8, " < %s >", "all users"); + else + console_print_pos(M_OFF, (task == 1) ? 11 : 8, " < %s (%s) > (%s)", wiiuacc[allusers].miiName, wiiuacc[allusers].persistentID, hasAccountSave(&titles[targ], ((task == 0) || (task == 1) || (task == 5) ? false : true), ((task < 3) || (task == 5) ? false : true), wiiuacc[allusers].pID, slot, versionList ? versionList[slot] : 0) ? "Has Save" : "Empty"); + } + } + + if (task == 5) { + entrycount++; + console_print_pos(M_OFF, 10, "Select Wii U user%s:", (task == 5) ? " to copy to" : ""); + if (allusers_d == -1) + console_print_pos(M_OFF, 11, " < %s >", "all users"); + else + console_print_pos(M_OFF, 11, " < %s (%s) > (%s)", wiiuacc[allusers_d].miiName, wiiuacc[allusers_d].persistentID, hasAccountSave(&titles[titles[targ].dupeID], false, false, wiiuacc[allusers_d].pID, 0, 0) ? "Has Save" : "Empty"); + } + + if ((task != 3) && (task != 4)) { + if (allusers > -1) { + if (hasCommonSave(&titles[targ], ((task == 0) || (task == 2) || (task == 5) ? false : true), ((task < 3) || (task == 5) ? false : true), slot, versionList ? versionList[slot] : 0)) { + console_print_pos(M_OFF, (task == 1) || (task == 5) ? 13 : 10, "Include 'common' save?"); + console_print_pos(M_OFF, (task == 1) || (task == 5) ? 14 : 11, " < %s >", common ? "yes" : "no "); + } else { + common = false; + console_print_pos(M_OFF, (task == 1) || (task == 5) ? 13 : 10, "No 'common' save found."); + entrycount--; + } + } else { + common = false; + entrycount--; + } + } else { + if (hasCommonSave(&titles[targ], true, true, slot, versionList ? versionList[slot] : 0)) { + console_print_pos(M_OFF, 7, "Include 'common' save?"); + console_print_pos(M_OFF, 8, " < %s >", common ? "yes" : "no "); + } else { + common = false; + console_print_pos(M_OFF, 7, "No 'common' save found."); + entrycount--; + } + } + + console_print_pos(M_OFF, 5 + cursor * 3, "\u2192"); + if (titles[targ].iconBuf) drawTGA(660, 100, 1, titles[targ].iconBuf); + } else if (mode == 1) { + entrycount = 1; + if (titles[targ].iconBuf) drawRGB5A3(650, 100, 1, titles[targ].iconBuf); + } + + switch(task) { + case 0: console_print_pos_aligned(17, 4, 2, "\ue000: Backup \ue001: Back"); break; + case 1: console_print_pos_aligned(17, 4, 2, "\ue000: Restore \ue001: Back"); break; + case 2: console_print_pos_aligned(17, 4, 2, "\ue000: Wipe \ue001: Back"); break; + case 3: console_print_pos_aligned(17, 4, 2, "\ue000: Import \ue001: Back"); break; + case 4: console_print_pos_aligned(17, 4, 2, "\ue000: Export \ue001: Back"); break; + case 5: console_print_pos_aligned(17, 4, 2, "\ue000: Copy \ue001: Back"); break; } } break; } + console_print_pos(0,16, "----------------------------------------------------------------------------"); + console_print_pos(0,17, "Press \ue044 to exit."); - console_print_pos(0,16, "--------------------------------------------------"); - console_print_pos(0,17, "Press HOME to exit."); - - OSScreenFlipBuffersEx(0); - OSScreenFlipBuffersEx(1); + /*u32 passedMs = (OSGetTime() - startTime) * 4000ULL / BUS_SPEED; + console_print_pos(-4, -1, "%d", passedMs);*/ + flipBuffers(); + while(1) { + updatePressedButtons(); + updateHeldButtons(); + if (isPressed(0xFFFF) || isHeld(0xFFFF) || stickPos(4, 0.7)) break; + } updatePressedButtons(); updateHeldButtons(); - if (isPressed(VPAD_BUTTON_DOWN) || isHeld(VPAD_BUTTON_DOWN) || stickPos(1, -0.7)) { - if (entrycount<=14) cursor = (cursor + 1) % entrycount; + if (isPressed(VPAD_BUTTON_DOWN) || isHeld(VPAD_BUTTON_DOWN) || stickPos(1, -0.7) || stickPos(3, -0.7)) { + if (entrycount <= 14) cursor = (cursor + 1) % entrycount; else if (cursor < 6) cursor++; - else if ((cursor+scroll+1) % entrycount) scroll++; + else if ((cursor + scroll + 1) % entrycount) scroll++; else cursor = scroll = 0; - usleep(100000); - } else if (isPressed(VPAD_BUTTON_UP) || isHeld(VPAD_BUTTON_UP) || stickPos(1, 0.7)) { - if (scroll > 0) cursor -= (cursor>6) ? 1 : 0*(scroll--); + os_usleep(100000); + } else if (isPressed(VPAD_BUTTON_UP) || isHeld(VPAD_BUTTON_UP) || stickPos(1, 0.7) || stickPos(3, 0.7)) { + if (scroll > 0) cursor -= (cursor>6) ? 1 : 0 * (scroll--); else if (cursor > 0) cursor--; - else if (entrycount>14) scroll = entrycount - (cursor = 6) - 1; + else if (entrycount > 14) scroll = entrycount - (cursor = 6) - 1; else cursor = entrycount - 1; - usleep(100000); + os_usleep(100000); } - if (isPressed(VPAD_BUTTON_LEFT) || isHeld(VPAD_BUTTON_LEFT) || stickPos(0, -0.7)) { + if (isPressed(VPAD_BUTTON_LEFT) || isHeld(VPAD_BUTTON_LEFT) || stickPos(0, -0.7) || stickPos(2, -0.7)) { if (menu==3) { - switch(cursor) { - case 0: slot--; break; - case 1: allusers^=1; break; - case 2: common^=1; break; + if (task == 5) { + switch(cursor) { + case 0: break; + case 1: + allusers = ((allusers == -1) ? -1 : (allusers - 1)); + allusers_d = allusers; + break; + case 2: + allusers_d = (((allusers == -1) || (allusers_d == -1)) ? -1 : (allusers_d - 1)); + allusers_d = ((allusers > -1) && (allusers_d == -1)) ? 0 : allusers_d; + break; + case 3: common ^= 1; break; + } + } else if (task == 1) { + switch(cursor) { + case 0: slot--; getAccountsSD(&titles[targ], slot); break; + case 1: + sdusers = ((sdusers == -1) ? -1 : (sdusers - 1)); + allusers = ((sdusers == -1) ? -1 : allusers); + break; + case 2: + allusers = (((allusers == -1) || (sdusers == -1)) ? -1 : (allusers - 1)); + allusers = ((sdusers > -1) && (allusers == -1)) ? 0 : allusers; + break; + case 3: common ^= 1; break; + } + } else if (task == 2) { + switch(cursor) { + case 0: break; + case 1: allusers = ((allusers == -1) ? -1 : (allusers - 1)); break; + case 2: common ^= 1; break; + } + } else if ((task == 3) || (task == 4)) { + switch(cursor) { + case 0: slot--; break; + case 1: common ^= 1; break; + } + } else { + switch(cursor) { + case 0: slot--; break; + case 1: allusers = ((allusers == -1) ? -1 : (allusers - 1)); break; + case 2: common ^= 1; break; + } } } - usleep(100000); - } else if (isPressed(VPAD_BUTTON_RIGHT) || isHeld(VPAD_BUTTON_RIGHT) || stickPos(0, 0.7)) { - if (menu==3) { - switch(cursor) { - case 0: slot++; break; - case 1: allusers^=1; break; - case 2: common^=1; break; + os_usleep(100000); + } else if (isPressed(VPAD_BUTTON_RIGHT) || isHeld(VPAD_BUTTON_RIGHT) || stickPos(0, 0.7) || stickPos(2, 0.7)) { + if (menu == 3) { + if (task == 5) { + switch(cursor) { + case 0: break; + case 1: + allusers = ((allusers == (wiiuaccn - 1)) ? (wiiuaccn - 1) : (allusers + 1)); + allusers_d = allusers; + break; + case 2: + allusers_d = ((allusers_d == (wiiuaccn - 1)) ? (wiiuaccn - 1) : (allusers_d + 1)); + allusers_d = (allusers == -1) ? -1 : allusers_d; + break; + case 3: common ^= 1; break; + } + } else if (task == 1) { + switch(cursor) { + case 0: slot++; getAccountsSD(&titles[targ], slot); break; + case 1: + sdusers = ((sdusers == (sdaccn - 1)) ? (sdaccn - 1) : (sdusers + 1)); + allusers = ((sdusers > -1) && (allusers == -1)) ? 0 : allusers; + break; + case 2: + allusers = ((allusers == (wiiuaccn - 1)) ? (wiiuaccn - 1) : (allusers + 1)); + allusers = (sdusers == -1) ? -1 : allusers; + break; + case 3: common ^= 1; break; + } + } else if (task == 2) { + switch(cursor) { + case 0: break; + case 1: allusers = ((allusers == (wiiuaccn - 1)) ? (wiiuaccn - 1) : (allusers + 1)); break; + case 2: common ^= 1; break; + } + } else if ((task == 3) || (task == 4)) { + switch(cursor) { + case 0: slot++; break; + case 1: common ^= 1; break; + } + } else { + switch(cursor) { + case 0: slot++; break; + case 1: allusers = ((allusers == (wiiuaccn - 1)) ? (wiiuaccn - 1) : (allusers + 1)); break; + case 2: common ^= 1; break; + } } } - usleep(100000); + os_usleep(100000); } - if (isPressed(VPAD_BUTTON_R) && (menu==1)) { - tsort = (tsort + 1) % 4; - qsort(titles, count, sizeof(Title), titleSort); + if (isPressed(VPAD_BUTTON_R)) { + if (menu == 1) { + tsort = (tsort + 1) % 4; + qsort(titles, count, sizeof(Title), titleSort); + } else if (menu == 2) { + + targ = ++targ % count; + } } - if (isPressed(VPAD_BUTTON_L) && (menu==1) && (tsort > 0)) { - sorta *= -1; - qsort(titles, count, sizeof(Title), titleSort); - } - - if (isPressed(VPAD_BUTTON_X) && (menu == 1) && (mode == 0)) { - /*targ = cursor+scroll; - if (titles[targ].highID == 0 || titles[targ].lowID == 0) continue; - SYSCheckTitleExists((uint64_t) titles[targ].highID << 32 | titles[targ].lowID); - - if (SYSCheckTitleExists((uint64_t) titles[targ].highID << 32 | titles[targ].lowID)) { - SYSLaunchTitle((uint64_t) titles[targ].highID << 32 | titles[targ].lowID); - break; - }*/ + if (isPressed(VPAD_BUTTON_L)) { + if ((menu==1) && (tsort > 0)) { + sorta *= -1; + qsort(titles, count, sizeof(Title), titleSort); + } else if (menu == 2) { + targ--; + if (targ < 0) targ = count -1; + } } if (isPressed(VPAD_BUTTON_A)) { - ucls(); + clearBuffers(); if (menu < 3) { if (menu == 0) { mode = cursor; @@ -519,54 +825,89 @@ int Menu_Main(void) { promptError("No Wii U titles found."); continue; } + if (mode == 1 && (!wiititles || !titlesvwii)) { promptError("No vWii saves found."); continue; } } + if (menu == 1) { - targ = cursor+scroll; + targ = cursor + scroll; cursorb = cursor; scrollb = scroll; + if (mode == 2) { + OSCalendarTime dateTime; + switch(cursor) { + case 0: + dateTime.year = 0; + backupAllSave(wiiutitles, titleswiiu, &dateTime); + backupAllSave(wiititles, titlesvwii, &dateTime); + break; + case 1: backupAllSave(wiiutitles, titleswiiu, NULL); break; + case 2: backupAllSave(wiititles, titlesvwii, NULL); break; + } + continue; + } if (titles[targ].highID==0 || titles[targ].lowID==0) continue; if ((mode == 0) && (strcmp(titles[targ].shortName, "DONT TOUCH ME") == 0)) { - if (!promptConfirm("Haxchi/CBHC save. Could be dangerous to modify. Continue?") || !promptConfirm("Are you REALLY sure?")) { + if (!promptConfirm(ST_ERROR, "CBHC save. Could be dangerous to modify. Continue?") || !promptConfirm(ST_WARNING, "Are you REALLY sure?")) { cursor = cursorb; scroll = scrollb; continue; } } if ((mode == 0) && (!titles[targ].saveInit)) { - if (!promptConfirm("Recommended to run Game at least one time. Continue?") || !promptConfirm("Are you REALLY sure?")) { + if (!promptConfirm(ST_WARNING, "Recommended to run Game at least one time. Continue?") || !promptConfirm(ST_WARNING, "Are you REALLY sure?")) { cursor = cursorb; scroll = scrollb; continue; } } } + if (menu == 2) { task = cursor; + cursort = cursor; + if (task == 0) { if (!titles[targ].saveInit) { promptError("No save to Backup."); continue; } } - if (task == 2) { - allusers = promptConfirm("Delete save from all users? A-Yes B-No"); - if (hasCommonSave(&titles[targ], false, false, 0, 0)) { - if (!allusers) promptConfirm("Delete common save? A-Yes B-No"); - } else { - common = false; - } - wipeSavedata(&titles[targ], allusers, common); break; - continue; + + if (task == 1) { + getAccountsSD(&titles[targ], slot); + allusers = ((sdusers == -1) ? -1 : allusers); + sdusers = ((allusers == -1) ? -1 : sdusers); } + + if (task == 2) { + if (!titles[targ].saveInit) { + promptError("No save to Wipe."); + continue; + } + } + if ((task == 3) || (task == 4)) { char gamePath[PATH_SIZE]; - memset(versionList, 0, 0x100*sizeof(int)); - if (getLoadiineGameSaveDir(gamePath, titles[targ].productCode)!=0) continue; + memset(versionList, 0, 0x100 * sizeof(int)); + if (getLoadiineGameSaveDir(gamePath, titles[targ].productCode) != 0) continue; getLoadiineSaveVersionList(versionList, gamePath); + if (task == 4) { + if (!titles[targ].saveInit) { + promptError("No save to Export."); + continue; + } + } + } + + if (task == 5) { + if (!titles[targ].saveInit) { + promptError("No save to Copy."); + continue; + } } } menu++; @@ -574,36 +915,37 @@ int Menu_Main(void) { } else { switch(task) { case 0: backupSavedata(&titles[targ], slot, allusers, common); break; - case 1: restoreSavedata(&titles[targ], slot, allusers, common); break; - case 2: - allusers = promptConfirm("Delete save from all users? A-Yes B-No"); - if (hasCommonSave(&titles[targ], false, false, 0, 0)) { - if (!allusers) promptConfirm("Delete common save? A-Yes B-No"); - } else { - common = false; - } - wipeSavedata(&titles[targ], allusers, common); break; + case 1: restoreSavedata(&titles[targ], slot, sdusers, allusers, common); break; + case 2: wipeSavedata(&titles[targ], allusers, common); break; case 3: importFromLoadiine(&titles[targ], common, versionList ? versionList[slot] : 0); break; case 4: exportToLoadiine(&titles[targ], common, versionList ? versionList[slot] : 0); break; - case 5: copySavedata(&titles[targ], &titles[titles[targ].dupeID], allusers, common); break; + case 5: + for (int i = 0; i < count; i++) { + if (titles[i].listID == titles[targ].dupeID) { + copySavedata(&titles[targ], &titles[i], allusers, allusers_d, common); + break; + } + } break; } } } else if (isPressed(VPAD_BUTTON_B) && menu > 0) { - ucls(); + clearBuffers(); menu--; cursor = scroll = 0; if (menu == 1) { cursor = cursorb; scroll = scrollb; } + if (menu == 2) cursor = cursort; } - if (isPressed(VPAD_BUTTON_HOME)) break; - } - unloadTitles(wiiutitles); - unloadTitles(wiititles); + if (tgaBufDRC) free(tgaBufDRC); + if (tgaBufTV) free(tgaBufTV); + freeFont(fontBuf); + unloadTitles(wiiutitles, titleswiiu); + unloadTitles(wiititles, titlesvwii); free(versionList); fatUnmount("sd"); @@ -617,7 +959,7 @@ int Menu_Main(void) { unmount_fs("storage_usb"); unmount_fs("storage_odd"); - unmount_sd_fat("sd"); + //unmount_sd_fat("sd"); IOSUHAX_FSA_Close(fsaFd); diff --git a/src/savemng.c b/src/savemng.c index 7603982..2d31355 100644 --- a/src/savemng.c +++ b/src/savemng.c @@ -1,10 +1,13 @@ #include "savemng.h" -#define BUFFER_SIZE 0x8020//0x2820 +#define BUFFER_SIZE 0x8020 #define BUFFER_SIZE_STEPS 0x20 int fsaFd = -1; char * p1; +Account* wiiuacc; +Account* sdacc; +u8 wiiuaccn = 0, sdaccn = 5; void setFSAFD(int fd) { @@ -12,29 +15,117 @@ void setFSAFD(int fd) { } void replace_str(char *str, char *orig, char *rep, int start, char *out) { - static char temp[PATH_SIZE]; - static char buffer[PATH_SIZE]; - char *p; + static char temp[PATH_SIZE]; + static char buffer[PATH_SIZE]; + char *p; - strcpy(temp, str + start); + strcpy(temp, str + start); - if (!(p = strstr(temp, orig))) // Is 'orig' even in 'temp'? - return temp; + if (!(p = strstr(temp, orig))) // Is 'orig' even in 'temp'? + return temp; - strncpy(buffer, temp, p-temp); // Copy characters from 'temp' start to 'orig' str - buffer[p-temp] = '\0'; + strncpy(buffer, temp, p-temp); // Copy characters from 'temp' start to 'orig' str + buffer[p-temp] = '\0'; - sprintf(buffer + (p - temp), "%s%s", rep, p + strlen(orig)); - sprintf(out, "%s", buffer); + sprintf(buffer + (p - temp), "%s%s", rep, p + strlen(orig)); + sprintf(out, "%s", buffer); } -void convert_to_string(uint16_t *wide, char *buf) { - // convert wide-char to normal char - while (*buf++ = (char)*wide++); +void show_file_operation(char* file_name, char* file_src, char* file_dest) { + char* dev_s[10], dev_d[10]; + + if (strncmp(strchr(file_src, '_'), "_usb", 4) == 0) { + sprintf(dev_s, " (USB)"); + } else if (strncmp(strchr(file_src, '_'), "_mlc", 4) == 0) { + sprintf(dev_s, " (NAND WiiU)"); + } else if (strncmp(strchr(file_src, '_'), "_slccmpt", 8) == 0) { + sprintf(dev_s, " (NAND vWii)"); + } else if (strncmp(strchr(file_src, '_'), "_sdcard", 7) == 0) { + sprintf(dev_s, " (SD)"); + } + + if (strncmp(strchr(file_dest, '_'), "_usb", 4) == 0) { + sprintf(dev_d, " (USB)"); + } else if (strncmp(strchr(file_dest, '_'), "_mlc", 4) == 0) { + sprintf(dev_d, " (NAND WiiU)"); + } else if (strncmp(strchr(file_dest, '_'), "_slccmpt", 8) == 0) { + sprintf(dev_d, " (NAND vWii)"); + } else if (strncmp(strchr(file_dest, '_'), "_sdcard", 7) == 0) { + sprintf(dev_d, " (SD)"); + } + + console_print_pos(-2, 0, "Copying file: %s", file_name); + console_print_pos_multiline(-2, 2, '/', "From%s: \n%s", dev_s, strstr(strstr(strstr(file_src, "/") + 1,"/") + 1,"/")); + console_print_pos_multiline(-2, 8, '/', "To%s: \n%s", dev_d, strstr(strstr(strstr(file_dest, "/") + 1,"/") + 1,"/")); } -int16_t FSAR(int result) { - return (int16_t) (result & 0xFFFF); +int FSAR(int result) { + if ((result & 0xFFFF0000) == 0xFFFC0000) + return (result & 0xFFFF) | 0xFFFF0000; + else + return result; +} + +s32 loadFile(const char * fPath, u8 **buf) { + int srcFd = -1; + int ret = IOSUHAX_FSA_OpenFile(fsaFd, fPath, "rb", &srcFd); + if (ret >= 0) { + fileStat_s fStat; + IOSUHAX_FSA_StatFile(fsaFd, srcFd, &fStat); + size_t size = fStat.size; + + *buf = malloc(size); + if (*buf) { + memset(*buf, 0, size); + ret = IOSUHAX_FSA_ReadFile(fsaFd, *buf, 0x01, size, srcFd, 0); + } + IOSUHAX_FSA_CloseFile(fsaFd, srcFd); + } + return ret; +} + +s32 loadFilePart(const char * fPath, u32 start, u32 size, u8 **buf) { + int srcFd = -1; + int ret = IOSUHAX_FSA_OpenFile(fsaFd, fPath, "rb", &srcFd); + if (ret >= 0) { + fileStat_s fStat; + IOSUHAX_FSA_StatFile(fsaFd, srcFd, &fStat); + if ((start + size) > fStat.size) { + IOSUHAX_FSA_CloseFile(fsaFd, srcFd); + return -43; + } + IOSUHAX_FSA_SetFilePos(fsaFd, srcFd, start); + + *buf = malloc(size); + if (*buf) { + memset(*buf, 0, size); + ret = IOSUHAX_FSA_ReadFile(fsaFd, *buf, 0x01, size, srcFd, 0); + } + IOSUHAX_FSA_CloseFile(fsaFd, srcFd); + } + return ret; +} + +s32 loadTitleIcon(Title* title) { + u32 highID = title->highID, lowID = title->lowID; + bool isUSB = title->isTitleOnUSB, isWii = ((highID & 0xFFFFFFF0) == 0x00010000); + char path[255]; + memset(path, 0, 255); + + if (isWii) { + if (title->saveInit) { + sprintf(path, "/vol/storage_slccmpt01/title/%08x/%08x/data/banner.bin", highID, lowID); + return loadFilePart(path, 0xA0, 24576, &title->iconBuf); + } + } else { + if (title->saveInit) + sprintf(path, "/vol/storage_%s01/usr/save/%08x/%08x/meta/iconTex.tga", isUSB ? "usb" : "mlc", highID, lowID); + else + sprintf(path, "/vol/storage_%s01/usr/title/%08x/%08x/meta/iconTex.tga", isUSB ? "usb" : "mlc", highID, lowID); + + return loadFile(path, &title->iconBuf); + } + return -23; } int checkEntry(const char * fPath) { @@ -45,7 +136,20 @@ int checkEntry(const char * fPath) { else if (ret < 0) return -1; if (fStat.flag & DIR_ENTRY_IS_DIRECTORY) return 2; - else return 1; + return 1; +} + +int folderEmpty(const char * fPath) { + int dirH; + + if (IOSUHAX_FSA_OpenDir(fsaFd, fPath, &dirH) >= 0) { + directoryEntry_s data; + int ret = FSAR(IOSUHAX_FSA_ReadDir(fsaFd, dirH, &data)); + IOSUHAX_FSA_CloseDir(fsaFd, dirH); + if (ret == FSA_STATUS_END_OF_DIRECTORY) + return 1; + } else return -1; + return 0; } int createFolder(const char * fPath) { //Adapted from mkdir_p made by JonathonReinhart @@ -79,48 +183,122 @@ int createFolder(const char * fPath) { //Adapted from mkdir_p made by JonathonRe return 0; } -void console_print_pos(int x, int y, const char* format, ...) { // Source: ftpiiu +void console_print_pos_aligned(int y, u16 offset, u8 align, const char* format, ...) { + char* tmp = NULL; + int x = 0; + va_list va; + va_start(va, format); + if ((vasprintf(&tmp, format, va) >= 0) && tmp) { + switch(align) { + case 0: x = (offset * 12); break; + case 1: x = (853 - ttfStringWidth(tmp, -2)) / 2; break; + case 2: x = 853 - (offset * 12) - ttfStringWidth(tmp, 0); break; + default: x = (853 - ttfStringWidth(tmp, -2)) / 2; break; + } + ttfPrintString(x, (y + 1) * 24, tmp, false, false); + } + va_end(va); + if (tmp) free(tmp); +} + +void console_print_pos(int x, int y, const char* format, ...) { // Source: ftpiiu char* tmp = NULL; va_list va; va_start(va, format); if ((vasprintf(&tmp, format, va) >= 0) && tmp) { - - if (strlen(tmp) > 79) tmp[79] = 0; - - OSScreenPutFontEx(0, x, y, tmp); - OSScreenPutFontEx(1, x, y, tmp); - + ttfPrintString((x + 4) * 12, (y + 1) * 24, tmp, false, true); + //OSScreenPutFontEx(0, x, y, tmp); + //OSScreenPutFontEx(1, x, y, tmp); } - va_end(va); if (tmp) free(tmp); +} +void console_print_pos_multiline(int x, int y, char cdiv, const char* format, ...) { // Source: ftpiiu + char* tmp = NULL; + u32 len = (66 - x); + + va_list va; + va_start(va, format); + if ((vasprintf(&tmp, format, va) >= 0) && tmp) { + + if ((ttfStringWidth(tmp, -1) / 12) > len) { + char* p = tmp; + if (strrchr(p, '\n') != NULL) p = strrchr(p, '\n') + 1; + while((ttfStringWidth(p, -1) / 12) > len) { + char* q = p; + int l1 = strlen(q); + for(int i = l1; i > 0; i--) { + char o = q[l1]; + q[l1] = '\0'; + if ((ttfStringWidth(p, -1) / 12) <= len) { + if (strrchr(p, cdiv) != NULL) p = strrchr(p, cdiv) + 1; + else p = q + l1; + q[l1] = o; + break; + } + q[l1] = o; + l1--; + } + char* buf[255]; + memset(buf, 0, 255); + strcpy(buf, p); + sprintf(p, "\n%s", buf); + p++; + len = 69; + } + } + ttfPrintString((x + 4) * 12, (y + 1) * 24, tmp, true, true); + //OSScreenPutFontEx(0, x, y, tmp); + //OSScreenPutFontEx(1, x, y, tmp); + } + va_end(va); + if (tmp) free(tmp); } void console_print_pos_va(int x, int y, const char* format, va_list va) { // Source: ftpiiu char* tmp = NULL; if ((vasprintf(&tmp, format, va) >= 0) && tmp) { - if (strlen(tmp) > 79) tmp[79] = 0; - OSScreenPutFontEx(0, x, y, tmp); - OSScreenPutFontEx(1, x, y, tmp); + ttfPrintString((x + 4) * 12, (y + 1) * 24, tmp, false, true); + //OSScreenPutFontEx(0, x, y, tmp); + //OSScreenPutFontEx(1, x, y, tmp); } if (tmp) free(tmp); } -bool promptConfirm(const char* question) { - ucls(); - const char* msg = "(A) Confirm - (B) Cancel"; - int ret = 0; - while(1) { - OSScreenClearBufferEx(0, 0); - OSScreenClearBufferEx(1, 0); - console_print_pos(25 - (strlen(question)>>1), 8, question); - console_print_pos(25 - (strlen(msg)>>1), 10, msg); - OSScreenFlipBuffersEx(0); - OSScreenFlipBuffersEx(1); +bool promptConfirm(Style st, const char* question) { + clearBuffers(); + const char* msg1 = "\ue000 Yes - \ue001 No"; + const char* msg2 = "\ue000 Confirm - \ue001 Cancel"; + const char* msg; + switch(st & 0x0F) { + case ST_YES_NO: msg = msg1; break; + case ST_CONFIRM_CANCEL: msg = msg2; break; + default: msg = msg2; + } + if (st & ST_WARNING) { + OSScreenClearBufferEx(0, 0x7F7F0000); + OSScreenClearBufferEx(1, 0x7F7F0000); + } else if (st & ST_ERROR) { + OSScreenClearBufferEx(0, 0x7F000000); + OSScreenClearBufferEx(1, 0x7F000000); + } else { + OSScreenClearBufferEx(0, 0x007F0000); + OSScreenClearBufferEx(1, 0x007F0000); + } + if (st & ST_MULTILINE) { + + } else { + console_print_pos(31 - (ttfStringWidth(question, 0) / 24), 7, question); + console_print_pos(31 - (ttfStringWidth(msg, -1) / 24), 9, msg); + } + flipBuffers(); + + int ret = 0; + while(1) { updatePressedButtons(); if (isPressed(VPAD_BUTTON_A | VPAD_BUTTON_B | VPAD_BUTTON_HOME)) { ret = isPressed(VPAD_BUTTON_A); @@ -131,14 +309,24 @@ bool promptConfirm(const char* question) { } void promptError(const char* message, ...) { - ucls(); + clearBuffers(); va_list va; va_start(va, message); - OSScreenClearBufferEx(0, 0); - OSScreenClearBufferEx(1, 0); - console_print_pos_va(25 - (strlen(message)>>1), 9, message, va); - OSScreenFlipBuffersEx(0); - OSScreenFlipBuffersEx(1); + OSScreenClearBufferEx(0, 0x7F000000); + OSScreenClearBufferEx(1, 0x7F000000); + + char* tmp = NULL; + if ((vasprintf(&tmp, message, va) >= 0) && tmp) { + //int x = 31 - (strlen(tmp)>>1), y = 9; + int x = 31 - (ttfStringWidth(tmp, -2) / 24), y = 8; + x = (x < -4 ? -4 : x); + ttfPrintString((x + 4) * 12, (y + 1) * 24, tmp, true, false); + //OSScreenPutFontEx(0, x, y, tmp); + //OSScreenPutFontEx(1, x, y, tmp); + } + if (tmp) free(tmp); + + flipBuffers(); va_end(va); while(1) { updatePressedButtons(); @@ -146,10 +334,10 @@ void promptError(const char* message, ...) { } } -void getAccounts() { +void getAccountsWiiU() { /* get persistent ID - thanks to Maschell */ unsigned int nn_act_handle; - unsigned long (*GetPersistentIdEx)(unsigned char); + u32 (*GetPersistentIdEx)(unsigned char); bool (*IsSlotOccupied)(unsigned char); int (*GetSlotNo)(void); int (*GetNumOfAccounts)(void); @@ -167,23 +355,78 @@ void getAccounts() { nn_Initialize(); // To be sure that it is really Initialized - int i = 0, acc = GetNumOfAccounts(); - char acclist[13][9], nlist[13][11]; + int i = 0, accn = 0; + wiiuaccn = GetNumOfAccounts(); + wiiuacc = malloc(wiiuaccn * sizeof(Account)); uint16_t out[11]; - while ((acc > 0) && (i <= 12)) { + while ((accn < wiiuaccn) && (i <= 12)) { if (IsSlotOccupied(i)) { unsigned int persistentID = GetPersistentIdEx(i); - sprintf(acclist[i], "%08X", persistentID); + wiiuacc[accn].pID = persistentID; + sprintf(wiiuacc[accn].persistentID, "%08X", persistentID); GetMiiNameEx(out, i); - convert_to_string(out, nlist[i]); - promptError("%d/%s/%s", i, acclist[i], nlist[i]); - acc--; + //convert_to_ascii(out, wiiuacc[accn].miiName); + memset(wiiuacc[accn].miiName, 0, sizeof(wiiuacc[accn].miiName)); + for (int j = 0, k = 0; j < 10; j++) { + if (out[j] < 0x80) + wiiuacc[accn].miiName[k++] = (char)out[j]; + else if ((out[j] & 0xF000) > 0) { + wiiuacc[accn].miiName[k++] = 0xE0 | ((out[j] & 0xF000) >> 12); + wiiuacc[accn].miiName[k++] = 0x80 | ((out[j] & 0xFC0) >> 6); + wiiuacc[accn].miiName[k++] = 0x80 | (out[j] & 0x3F); + } else if (out[j] < 0x400) { + wiiuacc[accn].miiName[k++] = 0xC0 | ((out[j] & 0x3C0) >> 6); + wiiuacc[accn].miiName[k++] = 0x80 | (out[j] & 0x3F); + } else { + wiiuacc[accn].miiName[k++] = 0xD0 | ((out[j] & 0x3C0) >> 6); + wiiuacc[accn].miiName[k++] = 0x80 | (out[j] & 0x3F); + } + } + wiiuacc[accn].slot = i; + accn++; } i++; } nn_Finalize(); //must be called an equal number of times to nn_Initialize } +void getAccountsSD(Title* title, u8 slot) { + u32 highID = title->highID, lowID = title->lowID; + bool isUSB = title->isTitleOnUSB, isWii = ((highID & 0xFFFFFFF0) == 0x00010000); + int dirH; + sdaccn = 0; + if (sdacc) free(sdacc); + + char path[255]; + sprintf(path, "/vol/storage_sdcard/wiiu/backups/%08x%08x/%u", highID, lowID, slot); + if (IOSUHAX_FSA_OpenDir(fsaFd, path, &dirH) >= 0) { + while (1) { + directoryEntry_s data; + int ret = IOSUHAX_FSA_ReadDir(fsaFd, dirH, &data); + if (ret != 0) break; + + if (strncmp(data.name, "common", 6) == 0) continue; + sdaccn++; + } + IOSUHAX_FSA_CloseDir(fsaFd, dirH); + } + + sdacc = malloc(sdaccn * sizeof(Account)); + if (IOSUHAX_FSA_OpenDir(fsaFd, path, &dirH) >= 0) { + for(int i = 0; i < sdaccn; i++) { + directoryEntry_s data; + int ret = IOSUHAX_FSA_ReadDir(fsaFd, dirH, &data); + if (ret != 0) break; + + if (strncmp(data.name, "common", 6) == 0) continue; + sprintf(sdacc[i].persistentID, "%s", data.name); + sdacc[i].pID = strtoul(data.name, NULL, 16); + sdacc[i].slot = i; + } + IOSUHAX_FSA_CloseDir(fsaFd, dirH); + } +} + int DumpFile(char* pPath, const char* oPath) { int srcFd = -1, destFd = -1; int ret = 0; @@ -225,12 +468,9 @@ int DumpFile(char* pPath, const char* oPath) { OSScreenClearBufferEx(0, 0); OSScreenClearBufferEx(1, 0); - console_print_pos(0, 0, "Copying file: %s", p1); - console_print_pos(0, 1, "From: %s", pPath); - console_print_pos(0, 2, "To: %s", oPath); - console_print_pos(0, 4, "Bytes Copied: %d of %d (%i kB/s)", sizew, sizef, (u32)(((u64)sizew * 1000) / ((u64)1024 * passedMs))); - OSScreenFlipBuffersEx(0); - OSScreenFlipBuffersEx(1); + show_file_operation(p1, pPath, oPath); + console_print_pos(-2, 15, "Bytes Copied: %d of %d (%i kB/s)", sizew, sizef, (u32)(((u64)sizew * 1000) / ((u64)1024 * passedMs))); + flipBuffers(); } } else { promptError("Open File W %d,%s", ret, oPath); @@ -247,7 +487,6 @@ int DumpFile(char* pPath, const char* oPath) { free(pBuffer); return -1; } - return 0; } @@ -287,35 +526,25 @@ int DumpDir(char* pPath, const char* tPath) { // Source: ft2sd snprintf(targetPath, FS_MAX_FULLPATH_SIZE, "%s/%s", tPath, data.name); p1 = data.name; - console_print_pos(0, 0, "Copying file: %s", data.name); - console_print_pos(0, 1, "From: %s", pPath); - console_print_pos(0, 2, "To: %s", targetPath); + ttfFontSize(0, 20); + show_file_operation(data.name, pPath, targetPath); if (DumpFile(pPath, targetPath) != 0) { + ttfFontSize(0, 22); IOSUHAX_FSA_CloseDir(fsaFd, dirH); return -3; } + ttfFontSize(0, 22); free(targetPath); } - OSScreenFlipBuffersEx(0); - OSScreenFlipBuffersEx(1); - pPath[len] = 0; - } - /*if (strcspn(tPath, "_usb") > 0) { - IOSUHAX_FSA_FlushVolume(fsaFd, "/vol/storage_usb01"); - } else if (strcspn(tPath, "_mlc") > 0) { - IOSUHAX_FSA_FlushVolume(fsaFd, "/vol/storage_mlc01"); - }*/ - IOSUHAX_FSA_CloseDir(fsaFd, dirH); return 0; - } int DeleteDir(char* pPath) { @@ -344,17 +573,17 @@ int DeleteDir(char* pPath) { OSScreenClearBufferEx(0, 0); OSScreenClearBufferEx(1, 0); - console_print_pos(0, 0, "Deleting folder %s", data.name); - console_print_pos(0, 1, "From: %s", origPath); + + console_print_pos(-2, 0, "Deleting folder %s", data.name); + console_print_pos_multiline(-2, 2, '/', "From: \n%s", origPath); if (IOSUHAX_FSA_Remove(fsaFd, origPath) != 0) promptError("Failed to delete folder."); } else { - console_print_pos(0, 0, "Deleting file %s", data.name); - console_print_pos(0, 1, "From: %s", pPath); + console_print_pos(-2, 0, "Deleting file %s", data.name); + console_print_pos_multiline(-2, 2, '/', "From: \n%s", pPath); if (IOSUHAX_FSA_Remove(fsaFd, pPath) != 0) promptError("Failed to delete file."); } - OSScreenFlipBuffersEx(0); - OSScreenFlipBuffersEx(1); + flipBuffers(); pPath[len] = 0; } @@ -437,7 +666,7 @@ int getLoadiineUserDir(char* out, const char* fullSavePath, const char* userID) int dirH; if (IOSUHAX_FSA_OpenDir(fsaFd, fullSavePath, &dirH) < 0) { - promptError("Failed to open directory."); + promptError("Failed to open Loadiine game save directory."); return -1; } @@ -455,13 +684,34 @@ int getLoadiineUserDir(char* out, const char* fullSavePath, const char* userID) } sprintf(out, "%s/u", fullSavePath); + if (checkEntry(out) <= 0) return -1; IOSUHAX_FSA_CloseDir(fsaFd, dirH); return 0; } +u64 getSlotDate(u32 highID, u32 lowID, u8 slot) { + char path[PATH_SIZE]; + if (((highID & 0xFFFFFFF0) == 0x00010000) && (slot == 255)) { + sprintf(path, "/vol/storage_sdcard/savegames/%08x%08x", highID, lowID); + } else { + sprintf(path, "/vol/storage_sdcard/wiiu/backups/%08x%08x/%u", highID, lowID, slot); + } + int ret = checkEntry(path); + if (ret <= 0) return 0; + else { + fileStat_s fStat; + int ret = FSAR(IOSUHAX_FSA_GetStat(fsaFd, path, &fStat)); + return fStat.ctime; + } +} + bool isSlotEmpty(u32 highID, u32 lowID, u8 slot) { char path[PATH_SIZE]; - sprintf(path, "/vol/storage_sdcard/wiiu/backups/%08x%08x/%u", highID, lowID, slot); + if (((highID & 0xFFFFFFF0) == 0x00010000) && (slot == 255)) { + sprintf(path, "/vol/storage_sdcard/savegames/%08x%08x", highID, lowID); + } else { + sprintf(path, "/vol/storage_sdcard/wiiu/backups/%08x%08x/%u", highID, lowID, slot); + } int ret = checkEntry(path); if (ret <= 0) return 1; else return 0; @@ -474,42 +724,85 @@ int getEmptySlot(u32 highID, u32 lowID) { return -1; } +bool hasAccountSave(Title* title, bool inSD, bool iine, u32 user, u8 slot, int version) { + u32 highID = title->highID, lowID = title->lowID; + bool isUSB = title->isTitleOnUSB, isWii = ((highID & 0xFFFFFFF0) == 0x00010000); + if (highID == 0 || lowID == 0) return false; + + char srcPath[PATH_SIZE]; + if (!isWii) { + if (!inSD) { + const char* path = (isUSB ? "/vol/storage_usb01/usr/save" : "/vol/storage_mlc01/usr/save"); + if (user == 0) + sprintf(srcPath, "%s/%08x/%08x/%s/common", path, highID, lowID, "user"); + else if (user == 0xFFFFFFFF) + sprintf(srcPath, "%s/%08x/%08x/%s", path, highID, lowID, "user"); + else + sprintf(srcPath, "%s/%08x/%08x/%s/%08X", path, highID, lowID, "user", user); + } else { + if (!iine) + sprintf(srcPath, "/vol/storage_sdcard/wiiu/backups/%08x%08x/%u/%08X", highID, lowID, slot, user); + else { + if (getLoadiineGameSaveDir(srcPath, title->productCode) != 0) return false; + if (version) sprintf(srcPath + strlen(srcPath), "/v%u", version); + if (user == 0) { + u32 srcOffset = strlen(srcPath); + strcpy(srcPath + srcOffset, "/c\0"); + } else { + char usrPath[16]; + sprintf(usrPath, "%08X", user); + getLoadiineUserDir(srcPath, srcPath, usrPath); + } + + } + } + } else { + if (!inSD) { + sprintf(srcPath, "/vol/storage_slccmpt01/title/%08x/%08x/data", highID, lowID); + } else { + sprintf(srcPath, "/vol/storage_sdcard/wiiu/backups/%08x%08x/%u", highID, lowID, slot); + } + } + if (checkEntry(srcPath) == 2) + if (folderEmpty(srcPath) == 0) + return true; + return false; +} + bool hasCommonSave(Title* title, bool inSD, bool iine, u8 slot, int version) { u32 highID = title->highID, lowID = title->lowID; - bool isUSB = title->isTitleOnUSB, isWii = (highID==0x00010000); + bool isUSB = title->isTitleOnUSB, isWii = ((highID & 0xFFFFFFF0) == 0x00010000); if (isWii) return false; char srcPath[PATH_SIZE]; - const char* path = (isUSB ? "/vol/storage_usb01/usr/save" : "/vol/storage_mlc01/usr/save"); - if (!inSD) + if (!inSD) { + const char* path = (isUSB ? "/vol/storage_usb01/usr/save" : "/vol/storage_mlc01/usr/save"); sprintf(srcPath, "%s/%08x/%08x/%s/common", path, highID, lowID, "user"); - else { + } else { if (!iine) sprintf(srcPath, "/vol/storage_sdcard/wiiu/backups/%08x%08x/%u/common", highID, lowID, slot); else { if (getLoadiineGameSaveDir(srcPath, title->productCode) != 0) return false; if (version) sprintf(srcPath + strlen(srcPath), "/v%u", version); - char usrPath[16]; - getUserID(usrPath); u32 srcOffset = strlen(srcPath); - getLoadiineUserDir(srcPath, srcPath, usrPath); strcpy(srcPath + srcOffset, "/c\0"); } } if (checkEntry(srcPath) == 2) - return true; + if (folderEmpty(srcPath) == 0) return true; return false; } -void copySavedata(Title* title, Title* titleb, bool allusers, bool common) { +void copySavedata(Title* title, Title* titleb, s8 allusers, s8 allusers_d, bool common) { + u32 highID = title->highID, lowID = title->lowID; bool isUSB = title->isTitleOnUSB; u32 highIDb = titleb->highID, lowIDb = titleb->lowID; bool isUSBb = titleb->isTitleOnUSB; - if (!promptConfirm("Are you sure?")) return; + if (!promptConfirm(ST_WARNING, "Are you sure?")) return; int slotb = getEmptySlot(titleb->highID, titleb->lowID); - if (slotb>=0 && promptConfirm("Backup current savedata first?")) { + if ((slotb >= 0) && promptConfirm(ST_YES_NO, "Backup current savedata first to next empty slot?")) { backupSavedata(titleb, slotb, allusers, common); promptError("Backup done. Now copying Savedata."); } @@ -522,9 +815,7 @@ void copySavedata(Title* title, Title* titleb, bool allusers, bool common) { sprintf(dstPath, "%s/%08x/%08x/%s", pathb, highIDb, lowIDb, "user"); createFolder(dstPath); - if (!allusers) { - char usrPath[16]; - getUserID(usrPath); + if (allusers > -1) { u32 srcOffset = strlen(srcPath); u32 dstOffset = strlen(dstPath); if (common) { @@ -532,33 +823,71 @@ void copySavedata(Title* title, Title* titleb, bool allusers, bool common) { strcpy(dstPath + dstOffset, "/common"); if (DumpDir(srcPath, dstPath) != 0) promptError("Common save not found."); } - sprintf(srcPath + srcOffset, "/%s", usrPath); - sprintf(dstPath + dstOffset, "/%s", usrPath); + sprintf(srcPath + srcOffset, "/%s", wiiuacc[allusers].persistentID); + sprintf(dstPath + dstOffset, "/%s", wiiuacc[allusers_d].persistentID); } + if (DumpDir(srcPath, dstPath) != 0) promptError("Copy failed."); - if (strcspn(dstPath, "_usb") > 0) { + if (strncmp(strchr(dstPath, '_'), "_usb", 4) == 0) { IOSUHAX_FSA_FlushVolume(fsaFd, "/vol/storage_usb01"); - } else if (strcspn(dstPath, "_mlc") > 0) { + } else if (strncmp(strchr(dstPath, '_'), "_mlc", 4) == 0) { IOSUHAX_FSA_FlushVolume(fsaFd, "/vol/storage_mlc01"); + } else if (strncmp(strchr(dstPath, '_'), "_slccmpt", 8) == 0) { + IOSUHAX_FSA_FlushVolume(fsaFd, "/vol/storage_slccmpt01"); + } else if (strncmp(strchr(dstPath, '_'), "_sdcard", 7) == 0) { + IOSUHAX_FSA_FlushVolume(fsaFd, "/vol/storage_sdcard"); } } -void backupSavedata(Title* title, u8 slot, bool allusers, bool common) { +void backupAllSave(Title* titles, int count, OSCalendarTime* date) { + OSCalendarTime dateTime; + if (date) { + if (date->year == 0) { + OSTicksToCalendarTime(OSGetTime(), date); + date->mon++; + } dateTime = (*date); + } else { + OSTicksToCalendarTime(OSGetTime(), &dateTime); + dateTime.mon++; + } - if (!isSlotEmpty(title->highID, title->lowID, slot) && !promptConfirm("Backup found on this slot. Overwrite it?")) return; + char datetime[24]; + sprintf(datetime, "%04d-%02d-%02dT%02d%02d%02d", dateTime.year, dateTime.mon, dateTime.mday, dateTime.hour, dateTime.min, dateTime.sec); + for (int i = 0; i < count; i++) { + if (titles[i].highID == 0 || titles[i].lowID == 0 || !titles[i].saveInit) continue; + + u32 highID = titles[i].highID, lowID = titles[i].lowID; + bool isUSB = titles[i].isTitleOnUSB, isWii = ((highID & 0xFFFFFFF0) == 0x00010000); + char srcPath[PATH_SIZE]; + char dstPath[PATH_SIZE]; + const char* path = (isWii ? "/vol/storage_slccmpt01/title" : (isUSB ? "/vol/storage_usb01/usr/save" : "/vol/storage_mlc01/usr/save")); + sprintf(srcPath, "%s/%08x/%08x/%s", path, highID, lowID, isWii ? "data" : "user"); + sprintf(dstPath, "/vol/storage_sdcard/wiiu/backups/batch/%s/%08x%08x", datetime, highID, lowID); + + createFolder(dstPath); + if (DumpDir(srcPath, dstPath) != 0) promptError("Backup failed."); + } + return dateTime; +} + +void backupSavedata(Title* title, u8 slot, s8 allusers, bool common) { + + if (!isSlotEmpty(title->highID, title->lowID, slot) && !promptConfirm(ST_WARNING, "Backup found on this slot. Overwrite it?")) return; u32 highID = title->highID, lowID = title->lowID; - bool isUSB = title->isTitleOnUSB, isWii = (highID==0x00010000); + bool isUSB = title->isTitleOnUSB, isWii = ((highID & 0xFFFFFFF0) == 0x00010000); char srcPath[PATH_SIZE]; char dstPath[PATH_SIZE]; const char* path = (isWii ? "/vol/storage_slccmpt01/title" : (isUSB ? "/vol/storage_usb01/usr/save" : "/vol/storage_mlc01/usr/save")); sprintf(srcPath, "%s/%08x/%08x/%s", path, highID, lowID, isWii ? "data" : "user"); - sprintf(dstPath, "/vol/storage_sdcard/wiiu/backups/%08x%08x/%u", highID, lowID, slot); + if (isWii && (slot == 255)) { + sprintf(dstPath, "/vol/storage_sdcard/savegames/%08x%08x", highID, lowID); + } else { + sprintf(dstPath, "/vol/storage_sdcard/wiiu/backups/%08x%08x/%u", highID, lowID, slot); + } createFolder(dstPath); - if (!allusers && !isWii) { - char usrPath[16]; - getUserID(usrPath); + if ((allusers > -1) && !isWii) { u32 srcOffset = strlen(srcPath); u32 dstOffset = strlen(dstPath); if (common) { @@ -566,43 +895,50 @@ void backupSavedata(Title* title, u8 slot, bool allusers, bool common) { strcpy(dstPath + dstOffset, "/common"); if (DumpDir(srcPath, dstPath) != 0) promptError("Common save not found."); } - sprintf(srcPath + srcOffset, "/%s", usrPath); - sprintf(dstPath + dstOffset, "/%s", usrPath); + sprintf(srcPath + srcOffset, "/%s", wiiuacc[allusers].persistentID); + sprintf(dstPath + dstOffset, "/%s", wiiuacc[allusers].persistentID); if (checkEntry(srcPath) == 0) { promptError("No save found for this user."); return; } } - if (DumpDir(srcPath, dstPath) != 0) promptError("Backup failed. DO NOT restore from this slot."); - if (strcspn(dstPath, "_usb") > 0) { + if (DumpDir(srcPath, dstPath) != 0) promptError("Backup failed. DO NOT restore from this slot."); + + if (strncmp(strchr(dstPath, '_'), "_usb", 4) == 0) { IOSUHAX_FSA_FlushVolume(fsaFd, "/vol/storage_usb01"); - } else if (strcspn(dstPath, "_mlc") > 0) { + } else if (strncmp(strchr(dstPath, '_'), "_mlc", 4) == 0) { IOSUHAX_FSA_FlushVolume(fsaFd, "/vol/storage_mlc01"); + } else if (strncmp(strchr(dstPath, '_'), "_slccmpt", 8) == 0) { + IOSUHAX_FSA_FlushVolume(fsaFd, "/vol/storage_slccmpt01"); + } else if (strncmp(strchr(dstPath, '_'), "_sdcard", 7) == 0) { + IOSUHAX_FSA_FlushVolume(fsaFd, "/vol/storage_sdcard"); } } -void restoreSavedata(Title* title, u8 slot, bool allusers, bool common) { +void restoreSavedata(Title* title, u8 slot, s8 sdusers, s8 allusers, bool common) { if (isSlotEmpty(title->highID, title->lowID, slot)) { promptError("No backup found on selected slot."); return; } - if (!promptConfirm("Are you sure?")) return; + if (!promptConfirm(ST_WARNING, "Are you sure?")) return; int slotb = getEmptySlot(title->highID, title->lowID); - if (slotb>=0 && promptConfirm("Backup current savedata first?")) backupSavedata(title, slotb, allusers, common); + if ((slotb >= 0) && promptConfirm(ST_YES_NO, "Backup current savedata first to next empty slot?")) backupSavedata(title, slotb, allusers, common); u32 highID = title->highID, lowID = title->lowID; - bool isUSB = title->isTitleOnUSB, isWii = (highID==0x00010000); + bool isUSB = title->isTitleOnUSB, isWii = ((highID & 0xFFFFFFF0) == 0x00010000); char srcPath[PATH_SIZE]; char dstPath[PATH_SIZE]; const char* path = (isWii ? "/vol/storage_slccmpt01/title" : (isUSB ? "/vol/storage_usb01/usr/save" : "/vol/storage_mlc01/usr/save")); - sprintf(srcPath, "/vol/storage_sdcard/wiiu/backups/%08x%08x/%u", highID, lowID, slot); - sprintf(dstPath, "%s/%08x/%08x/%s", path, highID, lowID, isWii ? "data" : "user"); + if (isWii && (slot == 255)) { + sprintf(srcPath, "/vol/storage_sdcard/savegames/%08x%08x", highID, lowID); + } else { + sprintf(srcPath, "/vol/storage_sdcard/wiiu/backups/%08x%08x/%u", highID, lowID, slot); + } + sprintf(dstPath, "%s/%08x/%08x/%s", path, highID, lowID, isWii ? "data" : "user"); createFolder(dstPath); - if (!allusers && !isWii) { - char usrPath[16]; - getUserID(usrPath); + if ((sdusers > -1) && !isWii) { u32 srcOffset = strlen(srcPath); u32 dstOffset = strlen(dstPath); if (common) { @@ -610,57 +946,67 @@ void restoreSavedata(Title* title, u8 slot, bool allusers, bool common) { strcpy(dstPath + dstOffset, "/common"); if (DumpDir(srcPath, dstPath) != 0) promptError("Common save not found."); } - sprintf(srcPath + srcOffset, "/%s", usrPath); - sprintf(dstPath + dstOffset, "/%s", usrPath); + sprintf(srcPath + srcOffset, "/%s", sdacc[sdusers].persistentID); + sprintf(dstPath + dstOffset, "/%s", wiiuacc[allusers].persistentID); } + if (DumpDir(srcPath, dstPath) != 0) promptError("Restore failed."); - if (strcspn(dstPath, "_usb") > 0) { + if (strncmp(strchr(dstPath, '_'), "_usb", 4) == 0) { IOSUHAX_FSA_FlushVolume(fsaFd, "/vol/storage_usb01"); - } else if (strcspn(dstPath, "_mlc") > 0) { + } else if (strncmp(strchr(dstPath, '_'), "_mlc", 4) == 0) { IOSUHAX_FSA_FlushVolume(fsaFd, "/vol/storage_mlc01"); + } else if (strncmp(strchr(dstPath, '_'), "_slccmpt", 8) == 0) { + IOSUHAX_FSA_FlushVolume(fsaFd, "/vol/storage_slccmpt01"); + } else if (strncmp(strchr(dstPath, '_'), "_sdcard", 7) == 0) { + IOSUHAX_FSA_FlushVolume(fsaFd, "/vol/storage_sdcard"); } } -void wipeSavedata(Title* title, bool allusers, bool common) { - if (!promptConfirm("Are you sure?") || !promptConfirm("Hm, are you REALLY sure?")) return; +void wipeSavedata(Title* title, s8 allusers, bool common) { + + if (!promptConfirm(ST_WARNING, "Are you sure?") || !promptConfirm(ST_WARNING, "Hm, are you REALLY sure?")) return; int slotb = getEmptySlot(title->highID, title->lowID); - if (slotb>=0 && promptConfirm("Backup current savedata first?")) backupSavedata(title, slotb, allusers, common); + if ((slotb >= 0) && promptConfirm(ST_YES_NO, "Backup current savedata first?")) backupSavedata(title, slotb, allusers, common); u32 highID = title->highID, lowID = title->lowID; - bool isUSB = title->isTitleOnUSB, isWii = (highID==0x00010000); + bool isUSB = title->isTitleOnUSB, isWii = ((highID & 0xFFFFFFF0) == 0x00010000); char srcPath[PATH_SIZE]; char origPath[PATH_SIZE]; const char* path = (isWii ? "/vol/storage_slccmpt01/title" : (isUSB ? "/vol/storage_usb01/usr/save" : "/vol/storage_mlc01/usr/save")); sprintf(srcPath, "%s/%08x/%08x/%s", path, highID, lowID, isWii ? "data" : "user"); - if (!allusers && !isWii) { + if ((allusers > -1) && !isWii) { u32 offset = strlen(srcPath); if (common) { strcpy(srcPath + offset, "/common"); sprintf(origPath, "%s", srcPath); - if (DeleteDir(srcPath)!=0) promptError("Common save not found."); + if (DeleteDir(srcPath) != 0) promptError("Common save not found."); if (IOSUHAX_FSA_Remove(fsaFd, origPath) != 0) promptError("Failed to delete common folder."); } - char usrPath[16]; - getUserID(usrPath); - sprintf(srcPath + offset, "/%s", usrPath); + sprintf(srcPath + offset, "/%s", wiiuacc[allusers].persistentID); sprintf(origPath, "%s", srcPath); } + if (DeleteDir(srcPath)!=0) promptError("Failed to delete savefile."); - if (!allusers && !isWii) { + if ((allusers > -1) && !isWii) { if (IOSUHAX_FSA_Remove(fsaFd, origPath) != 0) promptError("Failed to delete user folder."); } - if (strcspn(srcPath, "_usb") > 0) { + + if (strncmp(strchr(srcPath, '_'), "_usb", 4) == 0) { IOSUHAX_FSA_FlushVolume(fsaFd, "/vol/storage_usb01"); - } else if (strcspn(srcPath, "_mlc") > 0) { + } else if (strncmp(strchr(srcPath, '_'), "_mlc", 4) == 0) { IOSUHAX_FSA_FlushVolume(fsaFd, "/vol/storage_mlc01"); + } else if (strncmp(strchr(srcPath, '_'), "_slccmpt", 8) == 0) { + IOSUHAX_FSA_FlushVolume(fsaFd, "/vol/storage_slccmpt01"); + } else if (strncmp(strchr(srcPath, '_'), "_sdcard", 7) == 0) { + IOSUHAX_FSA_FlushVolume(fsaFd, "/vol/storage_sdcard"); } } void importFromLoadiine(Title* title, bool common, int version) { - if (!promptConfirm("Are you sure?")) return; + if (!promptConfirm(ST_WARNING, "Are you sure?")) return; int slotb = getEmptySlot(title->highID, title->lowID); - if (slotb>=0 && promptConfirm("Backup current savedata first?")) backupSavedata(title, slotb, 0, common); + if (slotb>=0 && promptConfirm(ST_YES_NO, "Backup current savedata first?")) backupSavedata(title, slotb, 0, common); u32 highID = title->highID, lowID = title->lowID; bool isUSB = title->isTitleOnUSB; char srcPath[PATH_SIZE]; @@ -675,16 +1021,21 @@ void importFromLoadiine(Title* title, bool common, int version) { createFolder(dstPath); u32 dstOffset = strlen(dstPath); sprintf(dstPath + dstOffset, "/%s", usrPath); + promptError(srcPath); + promptError(dstPath); if (DumpDir(srcPath, dstPath) != 0) promptError("Failed to import savedata from loadiine."); - strcpy(srcPath + srcOffset, "/c\0"); - strcpy(dstPath + dstOffset, "/common\0"); - if (DumpDir(srcPath, dstPath) != 0) promptError("Common save not found."); - + if (common) { + strcpy(srcPath + srcOffset, "/c\0"); + strcpy(dstPath + dstOffset, "/common\0"); + promptError(srcPath); + promptError(dstPath); + if (DumpDir(srcPath, dstPath) != 0) promptError("Common save not found."); + } } void exportToLoadiine(Title* title, bool common, int version) { - if (!promptConfirm("Are you sure?")) return; + if (!promptConfirm(ST_WARNING, "Are you sure?")) return; u32 highID = title->highID, lowID = title->lowID; bool isUSB = title->isTitleOnUSB; char srcPath[PATH_SIZE]; @@ -698,9 +1049,15 @@ void exportToLoadiine(Title* title, bool common, int version) { sprintf(srcPath, "/vol/storage_%s01/usr/save/%08x/%08x/user", isUSB ? "usb" : "mlc", highID, lowID); u32 srcOffset = strlen(srcPath); sprintf(srcPath + srcOffset, "/%s", usrPath); - if (DumpDir(srcPath, dstPath)!=0) promptError("Failed to export savedata to loadiine."); - strcpy(dstPath + dstOffset, "/c\0"); - strcpy(srcPath + srcOffset, "/common\0"); - if (DumpDir(srcPath, dstPath)!=0) promptError("Common save not found."); - + createFolder(dstPath); + promptError(srcPath); + promptError(dstPath); + if (DumpDir(srcPath, dstPath) != 0) promptError("Failed to export savedata to loadiine."); + if (common) { + strcpy(dstPath + dstOffset, "/c\0"); + strcpy(srcPath + srcOffset, "/common\0"); + promptError(srcPath); + promptError(dstPath); + if (DumpDir(srcPath, dstPath) != 0) promptError("Common save not found."); + } } diff --git a/src/savemng.h b/src/savemng.h index b1a357d..acaab93 100644 --- a/src/savemng.h +++ b/src/savemng.h @@ -9,6 +9,7 @@ #include #include "lib_easy.h" +#include "draw.h" #define PATH_SIZE 0x200 @@ -21,11 +22,13 @@ typedef struct { u32 lowID; u16 listID; char shortName[256]; - char productCode[32]; + char longName[512]; + char productCode[5]; bool saveInit; bool isTitleOnUSB; bool isTitleDupe; u16 dupeID; + u8* iconBuf; } Title; typedef struct { @@ -35,27 +38,56 @@ typedef struct { bool found; } Saves; +typedef struct { + char persistentID[9]; + u32 pID; + char miiName[50]; + u8 slot; +} Account; + +typedef enum { + ST_YES_NO = 1, + ST_CONFIRM_CANCEL = 2, + ST_MULTILINE = 16, + ST_WARNING = 32, + ST_ERROR = 64 +} Style; + +extern Account* wiiuacc; +extern Account* sdacc; +extern u8 wiiuaccn, sdaccn; + void console_print_pos(int x, int y, const char* format, ...); -bool promptConfirm(const char* question); +bool promptConfirm(Style st, const char* question); void promptError(const char* message, ...); void getUserID(char* out); +void getAccountsWiiU(); int getLoadiineGameSaveDir(char* out, const char* productCode); int getLoadiineSaveVersionList(int* out, const char* gamePath); int getLoadiineUserDir(char* out, const char* fullSavePath, const char* userID); +u64 getSlotDate(u32 highID, u32 lowID, u8 slot); bool isSlotEmpty(u32 highID, u32 lowID, u8 slot); bool hasCommonSave(Title* title, bool inSD, bool iine, u8 slot, int version); -void copySavedata(Title* title, Title* titled, bool allusers, bool common); -void backupSavedata(Title* title, u8 slot, bool allusers, bool common); -void restoreSavedata(Title* title, u8 slot, bool allusers, bool common); -void wipeSavedata(Title* title, bool allusers, bool common); +void copySavedata(Title* title, Title* titled, s8 allusers, s8 allusers_d, bool common); +void backupAllSave(Title* titles, int count, OSCalendarTime* date); +void backupSavedata(Title* title, u8 slot, s8 allusers, bool common); +void restoreSavedata(Title* title, u8 slot, s8 sdusers, s8 allusers, bool common); +void wipeSavedata(Title* title, s8 allusers, bool common); void importFromLoadiine(Title* title, bool common, int version); void exportToLoadiine(Title* title, bool common, int version); void setFSAFD(int fd); int checkEntry(const char * fPath); +int folderEmpty(const char * fPath); +s32 loadFile(const char * fPath, u8 **buf); +s32 loadFilePart(const char * fPath, u32 start, u32 size, u8 **buf); +s32 loadTitleIcon(Title* title); + +void show_file_operation(char* file_name, char* file_src, char* file_dest); +void console_print_pos_multiline(int x, int y, char cdiv,const char* format, ...); #ifdef __cplusplus } diff --git a/src/system/memory.c b/src/system/memory.c index 91f5392..00f62a3 100644 --- a/src/system/memory.c +++ b/src/system/memory.c @@ -34,18 +34,18 @@ //! Memory functions //! This is the only place where those are needed so lets keep them more or less private //!---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -extern unsigned int * pMEMAllocFromDefaultHeapEx; -extern unsigned int * pMEMAllocFromDefaultHeap; -extern unsigned int * pMEMFreeToDefaultHeap; +extern u32 * pMEMAllocFromDefaultHeapEx; +extern u32 * pMEMAllocFromDefaultHeap; +extern u32 * pMEMFreeToDefaultHeap; -extern int (* MEMGetBaseHeapHandle)(int mem_arena); -extern unsigned int (* MEMGetAllocatableSizeForFrmHeapEx)(int heap, int align); -extern void *(* MEMAllocFromFrmHeapEx)(int heap, unsigned int size, int align); -extern void (* MEMFreeToFrmHeap)(int heap, int mode); -extern void *(* MEMAllocFromExpHeapEx)(int heap, unsigned int size, int align); -extern int (* MEMCreateExpHeapEx)(void* address, unsigned int size, unsigned short flags); -extern void *(* MEMDestroyExpHeap)(int heap); -extern void (* MEMFreeToExpHeap)(int heap, void* ptr); +extern s32 (* MEMGetBaseHeapHandle)(s32 mem_arena); +extern u32 (* MEMGetAllocatableSizeForFrmHeapEx)(s32 heap, s32 align); +extern void *(* MEMAllocFromFrmHeapEx)(s32 heap, u32 size, s32 align); +extern void (* MEMFreeToFrmHeap)(s32 heap, s32 mode); +extern void *(* MEMAllocFromExpHeapEx)(s32 heap, u32 size, s32 align); +extern s32 (* MEMCreateExpHeapEx)(void* address, u32 size, unsigned short flags); +extern void *(* MEMDestroyExpHeap)(s32 heap); +extern void (* MEMFreeToExpHeap)(s32 heap, void* ptr); static int mem1_heap = -1; static int bucket_heap = -1; diff --git a/src/tga_reader.c b/src/tga_reader.c new file mode 100644 index 0000000..4c519fb --- /dev/null +++ b/src/tga_reader.c @@ -0,0 +1,576 @@ +/** + * tga_reader.c + * + * Copyright (c) 2014 Kenji Sasaki + * Released under the MIT license. + * https://github.com/npedotnet/TGAReader/blob/master/LICENSE + * + * English document + * https://github.com/npedotnet/TGAReader/blob/master/README.md + * + * Japanese document + * http://3dtech.jp/wiki/index.php?TGAReader + * + */ + +#include "tga_reader.h" + +static const TGA_ORDER _TGA_READER_ARGB = {16, 8, 0, 24}; +const TGA_ORDER *TGA_READER_ARGB = &_TGA_READER_ARGB; + +static const TGA_ORDER _TGA_READER_ABGR = {0, 8, 16, 24}; +const TGA_ORDER *TGA_READER_ABGR = &_TGA_READER_ABGR; + +static const TGA_ORDER _TGA_READER_RGBA = {24, 16, 8, 0}; +const TGA_ORDER *TGA_READER_RGBA = &_TGA_READER_RGBA; + +void *tgaMalloc(size_t size) { + return malloc(size); +} + +void tgaFree(void *memory) { + free(memory); +} + +int tgaGetWidth(const unsigned char *buffer) { + return (buffer[12] & 0xFF) | (buffer[13] & 0xFF) << 8; +} + +int tgaGetHeight(const unsigned char *buffer) { + return (buffer[14] & 0xFF) | (buffer[15] & 0xFF) << 8; +} + +#define COLORMAP 1 +#define RGB 2 +#define GRAYSCALE 3 +#define COLORMAP_RLE 9 +#define RGB_RLE 10 +#define GRAYSCALE_RLE 11 +#define RIGHT_ORIGIN 0x10 +#define UPPER_ORIGIN 0x20 + +static unsigned char *decodeRLE(int width, int height, int depth, const unsigned char *buffer, int offset); + +static int *createPixelsFromColormap(int width, int height, int depth, const unsigned char *bytes, int offset, const unsigned char *palette, int colormapOrigin, int descriptor, const TGA_ORDER *order); +static int *createPixelsFromRGB(int width, int height, int depth, const unsigned char *bytes, int offset, int descriptor, const TGA_ORDER *order); +static int *createPixelsFromGrayscale(int width, int height, int depth, const unsigned char *bytes, int offset, int descriptor, const TGA_ORDER *order); + +int *tgaRead(const unsigned char *buffer, const TGA_ORDER *order) { + + // header +// int idFieldLength = buffer[0] & 0xFF; +// int colormapType = buffer[1] & 0xFF; + int type = buffer[2] & 0xFF; + int colormapOrigin = (buffer[3] & 0xFF) | (buffer[4] & 0xFF) << 8; + int colormapLength = (buffer[5] & 0xFF) | (buffer[6] & 0xFF) << 8; + int colormapDepth = buffer[7] & 0xFF; +// int originX = (buffer[8] & 0xFF) | (buffer[9] & 0xFF) << 8; // unsupported +// int originY = (buffer[10] & 0xFF) | (buffer[11] & 0xFF) << 8; // unsupported + int width = tgaGetWidth(buffer); + int height = tgaGetHeight(buffer); + int depth = buffer[16] & 0xFF; + int descriptor = buffer[17] & 0xFF; + + int *pixels = NULL; + + // data + switch(type) { + case COLORMAP: { + int imageDataOffset = 18 + (colormapDepth / 8) * colormapLength; + pixels = createPixelsFromColormap(width, height, colormapDepth, buffer, imageDataOffset, buffer, colormapOrigin, descriptor, order); + } break; + case RGB: + pixels = createPixelsFromRGB(width, height, depth, buffer, 18, descriptor, order); + break; + case GRAYSCALE: + pixels = createPixelsFromGrayscale(width, height, depth, buffer, 18, descriptor, order); + break; + case COLORMAP_RLE: { + int imageDataOffset = 18 + (colormapDepth / 8) * colormapLength; + unsigned char *decodeBuffer = decodeRLE(width, height, depth, buffer, imageDataOffset); + pixels = createPixelsFromColormap(width, height, colormapDepth, decodeBuffer, 0, buffer, colormapOrigin, descriptor, order); + tgaFree(decodeBuffer); + } break; + case RGB_RLE: { + unsigned char *decodeBuffer = decodeRLE(width, height, depth, buffer, 18); + pixels = createPixelsFromRGB(width, height, depth, decodeBuffer, 0, descriptor, order); + tgaFree(decodeBuffer); + } break; + case GRAYSCALE_RLE: { + unsigned char *decodeBuffer = decodeRLE(width, height, depth, buffer, 18); + pixels = createPixelsFromGrayscale(width, height, depth, decodeBuffer, 0, descriptor, order); + tgaFree(decodeBuffer); + } break; + default: + break; + } + + return pixels; + +} + +static unsigned char *decodeRLE(int width, int height, int depth, const unsigned char *buffer, int offset) { + int elementCount = depth/8; + unsigned char elements[4]; + int decodeBufferLength = elementCount * width * height; + unsigned char *decodeBuffer = (unsigned char *)tgaMalloc(decodeBufferLength); + int decoded = 0; + while(decoded < decodeBufferLength) { + int packet = buffer[offset++] & 0xFF; + if((packet & 0x80) != 0) { // RLE + int i, j, count; + for(i=0; iredShift; + int gs = order->greenShift; + int bs = order->blueShift; + int as = order->alphaShift; + switch(depth) { + case 24: + pixels = (int *)tgaMalloc(4*width*height); + if((descriptor & RIGHT_ORIGIN) != 0) { + if((descriptor & UPPER_ORIGIN) != 0) { + // UpperRight + int i, j; + for(i=0; i= 0) { + int index = 3*colormapIndex+18; + int b = palette[index+0] & 0xFF; + int g = palette[index+1] & 0xFF; + int r = palette[index+2] & 0xFF; + int a = 0xFF; + color = (r<= 0) { + int index = 3*colormapIndex+18; + int b = palette[index+0] & 0xFF; + int g = palette[index+1] & 0xFF; + int r = palette[index+2] & 0xFF; + int a = 0xFF; + color = (r<= 0) { + int index = 3*colormapIndex+18; + int b = palette[index+0] & 0xFF; + int g = palette[index+1] & 0xFF; + int r = palette[index+2] & 0xFF; + int a = 0xFF; + color = (r<= 0) { + int index = 3*colormapIndex+18; + int b = palette[index+0] & 0xFF; + int g = palette[index+1] & 0xFF; + int r = palette[index+2] & 0xFF; + int a = 0xFF; + color = (r<= 0) { + int index = 4*colormapIndex+18; + int b = palette[index+0] & 0xFF; + int g = palette[index+1] & 0xFF; + int r = palette[index+2] & 0xFF; + int a = palette[index+3] & 0xFF; + color = (r<= 0) { + int index = 4*colormapIndex+18; + int b = palette[index+0] & 0xFF; + int g = palette[index+1] & 0xFF; + int r = palette[index+2] & 0xFF; + int a = palette[index+3] & 0xFF; + color = (r<= 0) { + int index = 4*colormapIndex+18; + int b = palette[index+0] & 0xFF; + int g = palette[index+1] & 0xFF; + int r = palette[index+2] & 0xFF; + int a = palette[index+3] & 0xFF; + color = (r<= 0) { + int index = 4*colormapIndex+18; + int b = palette[index+0] & 0xFF; + int g = palette[index+1] & 0xFF; + int r = palette[index+2] & 0xFF; + int a = palette[index+3] & 0xFF; + color = (r<redShift; + int gs = order->greenShift; + int bs = order->blueShift; + int as = order->alphaShift; + switch(depth) { + case 24: + pixels = (int *)tgaMalloc(4*width*height); + if((descriptor & RIGHT_ORIGIN) != 0) { + if((descriptor & UPPER_ORIGIN) != 0) { + // UpperRight + int i, j; + for(i=0; iredShift; + int gs = order->greenShift; + int bs = order->blueShift; + int as = order->alphaShift; + switch(depth) { + case 8: + pixels = (int *)tgaMalloc(4*width*height); + if((descriptor & RIGHT_ORIGIN) != 0) { + if((descriptor & UPPER_ORIGIN) != 0) { + // UpperRight + int i, j; + for(i=0; i +#include + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct _TGA_ORDER { + int redShift; + int greenShift; + int blueShift; + int alphaShift; +} TGA_ORDER; + +const TGA_ORDER *TGA_READER_ARGB; +const TGA_ORDER *TGA_READER_ABGR; +const TGA_ORDER *TGA_READER_RGBA; + +void *tgaMalloc(size_t size); +void tgaFree(void *memory); + +int tgaGetWidth(const unsigned char *buffer); +int tgaGetHeight(const unsigned char *buffer); +int *tgaRead(const unsigned char *buffer, const TGA_ORDER *order); + +#ifdef __cplusplus +} +#endif + +#endif /* __TGA_READER_H__ */