|
/* 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 <http://unlicense.org/> |
|
*/ |
|
|
|
/* To build: |
|
* gcc bannerpng.c lodepng.c -o bannerpng |
|
* https://lodev.org/lodepng/ |
|
*/ |
|
|
|
#include "lodepng.h" |
|
|
|
#include <math.h> |
|
#include <stdbool.h> |
|
#include <stdint.h> |
|
#include <stdio.h> |
|
|
|
/** |
|
* @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; |
|
} |