/* This is free and unencumbered software released into the public domain. * * Anyone is free to copy, modify, publish, use, compile, sell, or * distribute this software, either in source code form or as a compiled * binary, for any purpose, commercial or non-commercial, and by any * means. * * In jurisdictions that recognize copyright laws, the author or authors * of this software dedicate any and all copyright interest in the * software to the public domain. We make this dedication for the benefit * of the public at large and to the detriment of our heirs and * successors. We intend this dedication to be an overt act of * relinquishment in perpetuity of all present and future rights to this * software under copyright law. * * 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 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. * * For more information, please refer to */ /* To build: * gcc bannerpng.c lodepng.c -o bannerpng * https://lodev.org/lodepng/ */ #include "lodepng.h" #include #include #include #include /** * @param input path to the DS ROM * @param output path to write to * @return true if successful */ bool bannergif(const char *input, const char *output) { FILE *rom = fopen(input, "rb"); if(!rom) return false; // Seek to banner fseek(rom, 0x68, SEEK_SET); uint32_t bannerOfs; fread(&bannerOfs, sizeof(uint32_t), 1, rom); fseek(rom, bannerOfs, SEEK_SET); // Load banner data uint8_t palette[0x10][4]; // 16 colors RGBA uint8_t bitmap[32 * 32 * 4]; // 32×32 RGBA // Read palette fseek(rom, bannerOfs + 0x220, SEEK_SET); for(int i = 0; i < 0x10; i++) { uint16_t color; fread(&color, sizeof(uint16_t), 1, rom); palette[i][0] = lroundf((color & 0x1F) * 255.0f / 31.0f); palette[i][1] = lroundf(((color >> 5) & 0x1F) * 255.0f / 31.0f); palette[i][2] = lroundf(((color >> 10) & 0x1F) * 255.0f / 31.0f); palette[i][3] = i == 0 ? 0x00 : 0xFF; } // Read bitmap fseek(rom, bannerOfs + 0x20, SEEK_SET); for(int ty = 0; ty < 4; ty++) { for(int tx = 0; tx < 4; tx++) { for(int y = 0; y < 8; y++) { for(int x = 0; x < 4; x++) { uint8_t byte = fgetc(rom); memcpy(bitmap + ((ty * 8 + y) * 32 * 4) + (tx * 8 + x * 2) * 4, palette[byte & 0xF], 4); memcpy(bitmap + ((ty * 8 + y) * 32 * 4) + (tx * 8 + x * 2) * 4 + 4, palette[byte >> 4], 4); } } } } fclose(rom); lodepng_encode32_file(output, bitmap, 32, 32); return true; } int main(int argc, char **argv) { if(argc < 3) { printf("Usage: %s input.nds output.png\n", argv[0]); return 1; } bool success = bannergif(argv[1], argv[2]); return success ? 0 : 1; }