Workaround for unsupported texture sizes

This commit is contained in:
Sean Maas 2021-02-13 23:25:34 -05:00
parent f2ff7b97e5
commit a8d7a34f82
1 changed files with 47 additions and 53 deletions

View File

@ -110,51 +110,37 @@ static void load_texture() {
cur->original = texture_address;
// The DS only supports texture sizes of 8 << x, but the N64 is less restricted
// If a size is unsupported, the next size up is used and the texture is repeated to fill extra space
// Determine the width of the new texture
const int width = texture_row_size << (4 - texture_bit_width);
switch (width) {
case 8: cur->size_x = TEXTURE_SIZE_8; break;
case 16: cur->size_x = TEXTURE_SIZE_16; break;
case 32: cur->size_x = TEXTURE_SIZE_32; break;
case 64: cur->size_x = TEXTURE_SIZE_64; break;
case 128: cur->size_x = TEXTURE_SIZE_128; break;
default:
//printf("Unsupported texture width: %d\n", width);
glBindTexture(GL_TEXTURE_2D, cur->name = no_texture);
return;
};
for (cur->size_x = 0; (width - 1) >> (cur->size_x + 3) != 0; cur->size_x++);
const int conv_width = 8 << cur->size_x;
// Determine the height of the new texture
const int height = ((texture_size << 1) >> texture_bit_width) / width;
switch (height) {
case 8: cur->size_y = TEXTURE_SIZE_8; break;
case 16: cur->size_y = TEXTURE_SIZE_16; break;
case 32: cur->size_y = TEXTURE_SIZE_32; break;
case 64: cur->size_y = TEXTURE_SIZE_64; break;
case 128: cur->size_y = TEXTURE_SIZE_128; break;
default:
//printf("Unsupported texture height: %d\n", height);
glBindTexture(GL_TEXTURE_2D, cur->name = no_texture);
return;
};
for (cur->size_y = 0; (height - 1) >> (cur->size_y + 3) != 0; cur->size_y++);
const int conv_height = 8 << cur->size_y;
// Convert the texture to a format the DS understands
switch (texture_format) {
case G_IM_FMT_RGBA:
switch (texture_bit_width) {
case G_IM_SIZ_16b:
cur->converted = (uint8_t*)malloc(texture_size);
for (uint32_t x = 0; x < texture_size / 2; x++) {
const uint16_t color = (texture_address[x * 2] << 8) | texture_address[x * 2 + 1];
const uint8_t r = ((color >> 11) & 0x1F);
const uint8_t g = ((color >> 6) & 0x1F);
const uint8_t b = ((color >> 1) & 0x1F);
const uint8_t a = ((color >> 0) & 0x01);
((uint16_t*)cur->converted)[x] = (a << 15) | (b << 10) | (g << 5) | r;
cur->converted = (uint8_t*)malloc(conv_width * conv_height * 2);
for (int y = 0; y < conv_height; y++) {
for (int x = 0; x < conv_width; x++) {
const int index = ((y % height) * width + (x % width)) * 2;
const uint16_t color = (texture_address[index] << 8) | texture_address[index + 1];
const uint8_t r = ((color >> 11) & 0x1F);
const uint8_t g = ((color >> 6) & 0x1F);
const uint8_t b = ((color >> 1) & 0x1F);
const uint8_t a = ((color >> 0) & 0x01);
((uint16_t*)cur->converted)[y * conv_width + x] = (a << 15) | (b << 10) | (g << 5) | r;
}
}
DC_FlushRange(cur->converted, texture_size);
DC_FlushRange(cur->converted, conv_width * conv_height * 2);
cur->type = GL_RGBA;
break;
@ -168,37 +154,45 @@ static void load_texture() {
case G_IM_FMT_IA:
switch (texture_bit_width) {
case G_IM_SIZ_4b:
cur->converted = (uint8_t*)malloc(texture_size * 2);
for (uint32_t x = 0; x < texture_size * 2; x++) {
const uint8_t color = (texture_address[x / 2] >> ((x & 1) ? 0 : 4)) & 0x0F;
const uint8_t i = ((color >> 1) & 0x07);
const uint8_t a = ((color >> 0) & 0x01) ? 31 : 0;
cur->converted[x] = (a << 3) | i;
cur->converted = (uint8_t*)malloc(conv_width * conv_height);
for (int y = 0; y < conv_height; y++) {
for (int x = 0; x < conv_width; x++) {
const int index = (y % height) * width + (x % width);
const uint8_t color = (texture_address[index / 2] >> ((index & 1) ? 0 : 4)) & 0x0F;
const uint8_t i = ((color >> 1) & 0x07);
const uint8_t a = ((color >> 0) & 0x01) ? 31 : 0;
cur->converted[y * conv_width + x] = (a << 3) | i;
}
}
DC_FlushRange(cur->converted, texture_size * 2);
DC_FlushRange(cur->converted, conv_width * conv_height);
cur->type = GL_RGB8_A5;
break;
case G_IM_SIZ_8b:
cur->converted = (uint8_t*)malloc(texture_size);
for (uint32_t x = 0; x < texture_size; x++) {
const uint8_t color = texture_address[x];
const uint8_t i = ((color >> 4) & 0x0F) * 7 / 15;
const uint8_t a = ((color >> 0) & 0x0F) * 31 / 15;
cur->converted[x] = (a << 3) | i;
cur->converted = (uint8_t*)malloc(conv_width * conv_height);
for (int y = 0; y < conv_height; y++) {
for (int x = 0; x < conv_width; x++) {
const uint8_t color = texture_address[(y % height) * width + (x % width)];
const uint8_t i = ((color >> 4) & 0x0F) * 7 / 15;
const uint8_t a = ((color >> 0) & 0x0F) * 31 / 15;
cur->converted[y * conv_width + x] = (a << 3) | i;
}
}
DC_FlushRange(cur->converted, texture_size);
DC_FlushRange(cur->converted, conv_width * conv_height);
cur->type = GL_RGB8_A5;
break;
case G_IM_SIZ_16b:
cur->converted = (uint8_t*)malloc(texture_size / 2);
for (uint32_t x = 0; x < texture_size / 2; x++) {
const uint8_t i = texture_address[x * 2 + 0] * 7 / 255;
const uint8_t a = texture_address[x * 2 + 1] * 31 / 255;
cur->converted[x] = (a << 3) | i;
cur->converted = (uint8_t*)malloc(conv_width * conv_height);
for (int y = 0; y < conv_height; y++) {
for (int x = 0; x < conv_width; x++) {
const int index = ((y % height) * width + (x % width)) * 2;
const uint8_t i = texture_address[index + 0] * 7 / 255;
const uint8_t a = texture_address[index + 1] * 31 / 255;
cur->converted[y * conv_width + x] = (a << 3) | i;
}
}
DC_FlushRange(cur->converted, texture_size / 2);
DC_FlushRange(cur->converted, conv_width * conv_height);
cur->type = GL_RGB8_A5;
break;