mirror of
https://github.com/knightfox75/nds_nflib.git
synced 2025-06-18 16:55:32 -04:00
library: Translate and cleanup more source files
This commit is contained in:
parent
5150862e16
commit
f9d6b71a40
@ -6,8 +6,6 @@
|
||||
// http://www.nightfoxandco.com/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <nds.h>
|
||||
|
||||
@ -15,192 +13,187 @@
|
||||
#include "nf_bitmapbg.h"
|
||||
#include "nf_media.h"
|
||||
|
||||
void NF_LoadBMP(const char* file, u8 slot) {
|
||||
void NF_LoadBMP(const char *file, u8 slot)
|
||||
{
|
||||
// Temporary buffers
|
||||
char *buffer = NULL;
|
||||
|
||||
// Buffers locales
|
||||
char* buffer; // Buffer temporal
|
||||
buffer = NULL;
|
||||
char* palette; // Paleta (requerida por algun modo)
|
||||
palette = NULL;
|
||||
// BMP header
|
||||
typedef struct {
|
||||
u32 bmp_size; // Size of the file in bytes
|
||||
u16 res_a; // Reserved
|
||||
u16 res_b; // Reserved
|
||||
u32 offset; // Offset where data starts
|
||||
u32 header_size; // Size of the header in bytes (40 bytes)
|
||||
u32 width; // Image width in pixels
|
||||
u32 height; // Image height in pixels
|
||||
u16 color_planes; // Number of color planes
|
||||
u16 bpp; // Bits per pixel
|
||||
u32 compression; // Compression
|
||||
u32 raw_size; // Size of raw data after the header
|
||||
u32 dpi_hor; // Dots per inch (horizontal)
|
||||
u32 dpi_ver; // Dots per inch (vertical)
|
||||
u32 pal_colors; // Number of colors in the palette
|
||||
u32 imp_colors; // Important colors
|
||||
} bmp_header_info;
|
||||
|
||||
// Magic ID
|
||||
char magic_id[4];
|
||||
memset(magic_id, 0, 4);
|
||||
bmp_header_info bmp_header = { 0 };
|
||||
|
||||
// Define la estructura para almacenar la cabecera del BMP
|
||||
typedef struct {
|
||||
u32 bmp_size; // Tamaño en bytes del BMP
|
||||
u16 res_a; // Reservado
|
||||
u16 res_b; // Reservado
|
||||
u32 offset; // Offset donde empiezan los datos
|
||||
u32 header_size; // Tamaño de la cabecera (40 bytes)
|
||||
u32 bmp_width; // Ancho de la imagen en pixeles
|
||||
u32 bmp_height; // Altura de la imagen en pixeles
|
||||
u16 color_planes; // Numero de planos de color
|
||||
u16 bpp; // Numero de bits por pixel
|
||||
u32 compression; // Compresion usada
|
||||
u32 raw_size; // Tamaño de los datos en RAW despues de la cabecera
|
||||
u32 dpi_hor; // Puntos por pulgada (horizontal)
|
||||
u32 dpi_ver; // Puntos por pulgada (vertical)
|
||||
u32 pal_colors; // Numero de colores en la paleta
|
||||
u32 imp_colors; // Colores importantes
|
||||
} bmp_header_info;
|
||||
bmp_header_info bmp_header;
|
||||
// File path
|
||||
char filename[256];
|
||||
|
||||
// Pon todos los bytes de la estructura a 0
|
||||
memset(&bmp_header, 0, sizeof(bmp_header));
|
||||
// Load BMP file
|
||||
snprintf(filename, sizeof(filename), "%s/%s.bmp", NF_ROOTFOLDER, file);
|
||||
FILE *file_id = fopen(filename, "rb");
|
||||
if (file_id == NULL) // If the file can't be opened
|
||||
NF_Error(101, filename, 0);
|
||||
|
||||
// Declara los punteros a los ficheros
|
||||
FILE* file_id;
|
||||
// Read magic string "BM" (0x00 - 0x01)
|
||||
char magic_id[2];
|
||||
fread(magic_id, 1, 2, file_id);
|
||||
if ((magic_id[0] != 'B') || (magic_id[1] != 'M')) // If not a valid BMP file
|
||||
NF_Error(101, "BMP", 0);
|
||||
|
||||
// Variable para almacenar el path al archivo
|
||||
char filename[256];
|
||||
// Read the rest of the BMP header (0x02 - 0x36)
|
||||
fread((void *)&bmp_header, 1, sizeof(bmp_header), file_id);
|
||||
|
||||
// Carga el archivo .BMP
|
||||
snprintf(filename, sizeof(filename), "%s/%s.bmp", NF_ROOTFOLDER, file);
|
||||
file_id = fopen(filename, "rb");
|
||||
// Create a temporary buffer
|
||||
buffer = malloc(bmp_header.raw_size);
|
||||
if (buffer == NULL)
|
||||
NF_Error(102, NULL, bmp_header.raw_size);
|
||||
|
||||
if (file_id) { // Si el archivo existe...
|
||||
// Posicionate en el byte 0
|
||||
fseek(file_id, 0, SEEK_SET);
|
||||
// Lee el Magic String del archivo BMP (2 primeros Bytes, "BM") / (0x00 - 0x01)
|
||||
fread(magic_id, 1, 2, file_id);
|
||||
// Si es un archivo BMP... (Magic string == "BM")
|
||||
if (strcmp(magic_id, "BM") == 0) {
|
||||
// Posicionate en el byte 2
|
||||
fseek(file_id, 2, SEEK_SET);
|
||||
// Lee la cabecera del archivo BMP (0x02 - 0x36)
|
||||
fread((void*)&bmp_header, 1, sizeof(bmp_header), file_id);
|
||||
/////////////////////////////////////////////////////////////
|
||||
// Es un archivo BMP valido, cargalo en un buffer temporal //
|
||||
/////////////////////////////////////////////////////////////
|
||||
// Crea un buffer temporal
|
||||
buffer = (char*) calloc (bmp_header.raw_size, sizeof(char));
|
||||
if (buffer == NULL) NF_Error(102, NULL, bmp_header.raw_size);
|
||||
// Si se ha creado con exito, carga el archivo al buffer
|
||||
fseek(file_id, bmp_header.offset, SEEK_SET);
|
||||
fread(buffer, 1, bmp_header.raw_size, file_id);
|
||||
} else {
|
||||
// No es un archivo BMP valido
|
||||
NF_Error(101, "BMP", 0);
|
||||
}
|
||||
} else {
|
||||
// El archivo no existe
|
||||
NF_Error(101, filename, 0);
|
||||
}
|
||||
// Cierra el archivo
|
||||
fclose(file_id);
|
||||
// Read data to RAM
|
||||
fseek(file_id, bmp_header.offset, SEEK_SET);
|
||||
fread(buffer, 1, bmp_header.raw_size, file_id);
|
||||
fclose(file_id);
|
||||
|
||||
// Variables que se usaran a partir de aqui
|
||||
u16 pixel = 0; // Color del pixel
|
||||
u16 x = 0; // Coordemada X
|
||||
u16 y = 0; // Coordenada Y
|
||||
u32 idx = 0; // Indice en el buffer temporal
|
||||
u32 offset = 0; // Indice en el buffer de destino
|
||||
u8 r = 0; // Valores RGB
|
||||
u8 g = 0;
|
||||
u8 b = 0;
|
||||
u16 colors = 0; // En 8 bits, numero de colores
|
||||
u32 size = 0; // Tamaño del buffer de 16 bits (en bytes)
|
||||
// Free the previous buffer and allocate a new one
|
||||
free(NF_BG16B[slot].buffer);
|
||||
|
||||
// Habilita el buffer de destino (u16 de alto x ancho del tamaño de imagen)
|
||||
size = ((bmp_header.bmp_width * bmp_header.bmp_height) << 1);
|
||||
free(NF_BG16B[slot].buffer);
|
||||
NF_BG16B[slot].buffer = NULL;
|
||||
NF_BG16B[slot].buffer = (u16*) calloc ((size >> 1), sizeof(u16));
|
||||
if (NF_BG16B[slot].buffer == NULL) NF_Error(102, NULL, size);
|
||||
u32 size = bmp_header.width * bmp_header.height * 2;
|
||||
NF_BG16B[slot].buffer = malloc(size);
|
||||
if (NF_BG16B[slot].buffer == NULL)
|
||||
NF_Error(102, NULL, size);
|
||||
|
||||
// Segun los BITS por Pixel (8, 16, 24)
|
||||
switch (bmp_header.bpp) {
|
||||
switch (bmp_header.bpp)
|
||||
{
|
||||
case 8: // 8 bits per pixel
|
||||
{
|
||||
// Calculate palette size
|
||||
u32 colors = (bmp_header.offset - 0x36) >> 2;
|
||||
char *palette = malloc(colors << 2);
|
||||
if (palette == NULL)
|
||||
NF_Error(102, NULL, colors << 2);
|
||||
|
||||
case 8: // 8 bits por pixel
|
||||
// Calcula el tamaño de la paleta
|
||||
colors = ((bmp_header.offset - 0x36) >> 2);
|
||||
palette = (char*) calloc ((colors << 2), sizeof(char));
|
||||
if (palette == NULL) NF_Error(102, NULL, (colors << 2));
|
||||
// Abre de nuevo el archivo y carga la paleta
|
||||
file_id = fopen(filename, "rb");
|
||||
if (!file_id) NF_Error(101, filename, 0);
|
||||
fseek(file_id, 0x36, SEEK_SET);
|
||||
fread(palette, 1, (colors << 2), file_id);
|
||||
fclose(file_id);
|
||||
// Convierte el archivo a 16 bits
|
||||
for (y = 0; y < bmp_header.bmp_height; y ++) {
|
||||
for (x = 0; x < bmp_header.bmp_width; x ++) {
|
||||
// Calcula los offsets
|
||||
offset = ((((bmp_header.bmp_height - 1) - y) * bmp_header.bmp_width) + x);
|
||||
// Obten el pixel
|
||||
pixel = (buffer[idx] << 2);
|
||||
// Desglosa el RGB para rotar los colores BGR -> RGB
|
||||
b = (palette[pixel] >> 3);
|
||||
g = (palette[(pixel + 1)] >> 3);
|
||||
r = (palette[(pixel + 2)] >> 3);
|
||||
// Recombina el RGB a 16 bits
|
||||
pixel = ((r)|((g) << 5)|((b) << 10)|(BIT(15)));
|
||||
NF_BG16B[slot].buffer[offset] = pixel;
|
||||
// Siguiente pixel
|
||||
idx ++;
|
||||
}
|
||||
// Ajusta la alineacion a 4 bytes al final de linea
|
||||
while ((idx % 4) != 0) idx ++;
|
||||
}
|
||||
// Elimina la paleta de la RAM
|
||||
free(palette);
|
||||
palette = NULL;
|
||||
break;
|
||||
// Reopen file and read the palette
|
||||
file_id = fopen(filename, "rb");
|
||||
if (file_id == NULL)
|
||||
NF_Error(101, filename, 0);
|
||||
|
||||
case 16: // 16 bits por pixel
|
||||
for (y = 0; y < bmp_header.bmp_height; y ++) {
|
||||
for (x = 0; x < bmp_header.bmp_width; x ++) {
|
||||
// Calcula los offsets
|
||||
offset = ((((bmp_header.bmp_height - 1) - y) * bmp_header.bmp_width) + x);
|
||||
// Obten el pixel
|
||||
pixel = buffer[idx] + (buffer[(idx + 1)] << 8);
|
||||
// Desglosa el RGB para rotar los colores BGR -> RGB
|
||||
b = (pixel & 0x1F);
|
||||
g = ((pixel >> 5) & 0x1F);
|
||||
r = ((pixel >> 10) & 0x1F);
|
||||
// Recombina el RGB a 16 bits
|
||||
pixel = ((r)|((g) << 5)|((b) << 10)|(BIT(15)));
|
||||
NF_BG16B[slot].buffer[offset] = pixel;
|
||||
// Siguiente pixel
|
||||
idx += 2;
|
||||
}
|
||||
// Ajusta la alineacion a 4 bytes al final de linea
|
||||
while ((idx % 4) != 0) idx ++;
|
||||
}
|
||||
break;
|
||||
fseek(file_id, 0x36, SEEK_SET);
|
||||
fread(palette, 1, colors << 2, file_id);
|
||||
fclose(file_id);
|
||||
|
||||
case 24: // 24 bits por pixel
|
||||
for (y = 0; y < bmp_header.bmp_height; y ++) {
|
||||
for (x = 0; x < bmp_header.bmp_width; x ++) {
|
||||
// Calcula los offsets
|
||||
offset = ((((bmp_header.bmp_height - 1) - y) * bmp_header.bmp_width) + x);
|
||||
// Obten el pixel
|
||||
b = ((buffer[idx]) >> 3);
|
||||
g = ((buffer[idx + 1]) >> 3);
|
||||
r = ((buffer[idx + 2]) >> 3);
|
||||
// Recombina el RGB a 16 bits
|
||||
pixel = ((r)|((g) << 5)|((b) << 10)|(BIT(15)));
|
||||
NF_BG16B[slot].buffer[offset] = pixel;
|
||||
// Siguiente pixel
|
||||
idx += 3;
|
||||
}
|
||||
// Ajusta la alineacion a 4 bytes al final de linea
|
||||
while ((idx % 4) != 0) idx ++;
|
||||
}
|
||||
break;
|
||||
u32 idx = 0;
|
||||
|
||||
}
|
||||
// Convert file to 16 bit per pixel
|
||||
for (u32 y = 0; y < bmp_header.height; y++)
|
||||
{
|
||||
for (u32 x = 0; x < bmp_header.width; x++)
|
||||
{
|
||||
u32 offset = (((bmp_header.height - 1) - y) * bmp_header.width) + x;
|
||||
|
||||
// Guarda los parametros del fondo
|
||||
NF_BG16B[slot].size = size; // Guarda el tamaño
|
||||
NF_BG16B[slot].width = bmp_header.bmp_width; // Ancho del fondo
|
||||
NF_BG16B[slot].height = bmp_header.bmp_height; // Altura del fondo
|
||||
NF_BG16B[slot].inuse = true; // Marca que esta en uso
|
||||
u32 pixel = buffer[idx] << 2;
|
||||
|
||||
// Libera el buffer temporal
|
||||
free(buffer);
|
||||
buffer = NULL;
|
||||
// Split BGR (not RGB) value
|
||||
u32 b = palette[pixel] >> 3;
|
||||
u32 g = palette[pixel + 1] >> 3;
|
||||
u32 r = palette[pixel + 2] >> 3;
|
||||
|
||||
// Pack the components as RGB
|
||||
pixel = r | (g << 5) | (b << 10) | BIT(15);
|
||||
NF_BG16B[slot].buffer[offset] = pixel;
|
||||
|
||||
idx++;
|
||||
}
|
||||
|
||||
// Align to 4 bytes at the end of the row
|
||||
while ((idx % 4) != 0)
|
||||
idx ++;
|
||||
}
|
||||
|
||||
// Free palette from RAM
|
||||
free(palette);
|
||||
break;
|
||||
}
|
||||
case 16: // 16 bits per pixel
|
||||
{
|
||||
u32 idx = 0;
|
||||
|
||||
for (u32 y = 0; y < bmp_header.height; y++)
|
||||
{
|
||||
for (u32 x = 0; x < bmp_header.width; x++)
|
||||
{
|
||||
u32 offset = (((bmp_header.height - 1) - y) * bmp_header.width) + x;
|
||||
|
||||
u32 pixel = buffer[idx] + (buffer[idx + 1] << 8);
|
||||
|
||||
// Split BGR (not RGB) value
|
||||
u32 b = pixel & 0x1F;
|
||||
u32 g = (pixel >> 5) & 0x1F;
|
||||
u32 r = (pixel >> 10) & 0x1F;
|
||||
|
||||
// Pack the components as RGB
|
||||
pixel = r | (g << 5) | (b << 10) | BIT(15);
|
||||
NF_BG16B[slot].buffer[offset] = pixel;
|
||||
|
||||
idx += 2;
|
||||
}
|
||||
|
||||
// Align to 4 bytes at the end of the row
|
||||
while ((idx % 4) != 0)
|
||||
idx ++;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 24: // 24 bits per pixel
|
||||
{
|
||||
u32 idx = 0;
|
||||
|
||||
for (u32 y = 0; y < bmp_header.height; y++)
|
||||
{
|
||||
for (u32 x = 0; x < bmp_header.width; x++)
|
||||
{
|
||||
u32 offset = (((bmp_header.height - 1) - y) * bmp_header.width) + x;
|
||||
|
||||
u32 b = buffer[idx] >> 3;
|
||||
u32 g = buffer[idx + 1] >> 3;
|
||||
u32 r = buffer[idx + 2] >> 3;
|
||||
|
||||
// Pack the components as RGB
|
||||
u32 pixel = r | (g << 5) | (b << 10) | BIT(15);
|
||||
NF_BG16B[slot].buffer[offset] = pixel;
|
||||
|
||||
idx += 3;
|
||||
}
|
||||
|
||||
// Align to 4 bytes at the end of the row
|
||||
while ((idx % 4) != 0)
|
||||
idx ++;
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
NF_Error(106, NULL, bmp_header.bpp);
|
||||
break;
|
||||
}
|
||||
|
||||
// Save background information
|
||||
NF_BG16B[slot].size = size;
|
||||
NF_BG16B[slot].width = bmp_header.width;
|
||||
NF_BG16B[slot].height = bmp_header.height;
|
||||
NF_BG16B[slot].inuse = true; // Mark as used
|
||||
|
||||
// Free temporary buffer
|
||||
free(buffer);
|
||||
}
|
||||
|
737
source/nf_text.c
737
source/nf_text.c
@ -7,7 +7,6 @@
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <nds.h>
|
||||
|
||||
@ -16,439 +15,429 @@
|
||||
#include "nf_text.h"
|
||||
#include "nf_tiledbg.h"
|
||||
|
||||
// Define los buffers para almacenar las capas de texto
|
||||
// Structs that hold information about all text layers
|
||||
NF_TYPE_TEXT_INFO NF_TEXT[2][4];
|
||||
|
||||
|
||||
void NF_InitTextSys(u8 screen) {
|
||||
|
||||
// Reinicia las variables
|
||||
for (int n = 0; n < 4; n ++) {
|
||||
NF_TEXT[screen][n].width = 0; // Ancho del mapa de texto
|
||||
NF_TEXT[screen][n].height = 0; // Alto del mapa de texto
|
||||
NF_TEXT[screen][n].rotation = 0; // Rotacion a 0 (ninguna)
|
||||
NF_TEXT[screen][n].slot = 255; // Slot donde esta el tileset
|
||||
NF_TEXT[screen][n].pal = 0; // nº de paleta extendida (0 por defecto)
|
||||
NF_TEXT[screen][n].exist = false; // Marcalo como no existente
|
||||
NF_TEXT[screen][n].update = false; // No es necesario actualizarlo
|
||||
}
|
||||
|
||||
void NF_InitTextSys(u8 screen)
|
||||
{
|
||||
for (int n = 0; n < 4; n++)
|
||||
{
|
||||
NF_TEXT[screen][n].width = 0;
|
||||
NF_TEXT[screen][n].height = 0;
|
||||
NF_TEXT[screen][n].rotation = 0;
|
||||
NF_TEXT[screen][n].slot = 255;
|
||||
NF_TEXT[screen][n].pal = 0;
|
||||
NF_TEXT[screen][n].exist = false;
|
||||
NF_TEXT[screen][n].update = false;
|
||||
}
|
||||
}
|
||||
|
||||
void NF_LoadTextFont(const char* file, const char* name, u16 width, u16 height, u8 rotation) {
|
||||
void NF_LoadTextFont(const char *file, const char *name, u16 width, u16 height,
|
||||
u8 rotation)
|
||||
{
|
||||
// Look for a free slot
|
||||
u32 slot = 255;
|
||||
for (int n = 0; n < NF_SLOTS_TBG; n ++)
|
||||
{
|
||||
// If a slot is free, mark it as in use and stop the search
|
||||
if (NF_TILEDBG[n].available)
|
||||
{
|
||||
NF_TILEDBG[n].available = false;
|
||||
slot = n;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Busca un slot libre
|
||||
u16 n = 0;
|
||||
u8 slot = 255;
|
||||
for (n = 0; n < NF_SLOTS_TBG; n ++) { // Busca en todos los slots
|
||||
if (NF_TILEDBG[n].available) { // Si esta libre
|
||||
NF_TILEDBG[n].available = false; // Marcalo como en uso
|
||||
slot = n; // Guarda el slot a usar
|
||||
n = NF_SLOTS_TBG; // Deja de buscar
|
||||
}
|
||||
}
|
||||
// Si no hay ningun slot libre, error
|
||||
if (slot == 255) {
|
||||
NF_Error(103, "Tiled Bg", NF_SLOTS_TBG);
|
||||
}
|
||||
// If there are no free slots, fail
|
||||
if (slot == 255)
|
||||
NF_Error(103, "Tiled Bg", NF_SLOTS_TBG);
|
||||
|
||||
// Verifica que el fondo sea multiplo de 256px (32 tiles)
|
||||
if (((width % 256) != 0) || ((height % 256) != 0)) {
|
||||
NF_Error(115, file, 0);
|
||||
}
|
||||
// Verify that the background is a multiple of 256 pixels (32 tiles)
|
||||
if (((width % 256) != 0) || ((height % 256) != 0))
|
||||
NF_Error(115, file, 0);
|
||||
|
||||
// Vacia los buffers que se usaran
|
||||
free(NF_BUFFER_BGMAP[slot]); // Buffer para los mapas
|
||||
NF_BUFFER_BGMAP[slot] = NULL;
|
||||
free(NF_BUFFER_BGTILES[slot]); // Buffer para los tiles
|
||||
NF_BUFFER_BGTILES[slot] = NULL;
|
||||
free(NF_BUFFER_BGPAL[slot]); // Buffer para los paletas
|
||||
NF_BUFFER_BGPAL[slot] = NULL;
|
||||
// Free buffers if they are in use
|
||||
free(NF_BUFFER_BGMAP[slot]);
|
||||
NF_BUFFER_BGMAP[slot] = NULL;
|
||||
free(NF_BUFFER_BGTILES[slot]);
|
||||
NF_BUFFER_BGTILES[slot] = NULL;
|
||||
free(NF_BUFFER_BGPAL[slot]);
|
||||
NF_BUFFER_BGPAL[slot] = NULL;
|
||||
|
||||
// Declara los punteros a los ficheros
|
||||
FILE* file_id;
|
||||
// File path
|
||||
char filename[256];
|
||||
|
||||
// Variable para almacenar el path al archivo
|
||||
char filename[256];
|
||||
// Load .FNT file
|
||||
snprintf(filename, sizeof(filename), "%s/%s.fnt", NF_ROOTFOLDER, file);
|
||||
FILE *file_id = fopen(filename, "rb");
|
||||
if (file_id == NULL) // If the file can't be opened
|
||||
NF_Error(101, filename, 0);
|
||||
|
||||
// Carga el archivo .FNT
|
||||
snprintf(filename, sizeof(filename), "%s/%s.fnt", NF_ROOTFOLDER, file);
|
||||
file_id = fopen(filename, "rb");
|
||||
if (file_id) { // Si el archivo existe...
|
||||
// Obten el tamaño del archivo
|
||||
NF_TILEDBG[slot].tilesize = (NF_TEXT_FONT_CHARS << 6); // 100 caracteres x 64 bytes
|
||||
// Reserva el espacio en RAM
|
||||
NF_BUFFER_BGTILES[slot] = (char*) calloc (NF_TILEDBG[slot].tilesize, sizeof(char));
|
||||
if (NF_BUFFER_BGTILES[slot] == NULL) { // Si no hay suficiente RAM libre
|
||||
NF_Error(102, NULL, NF_TILEDBG[slot].tilesize);
|
||||
}
|
||||
fread(NF_BUFFER_BGTILES[slot], 1, NF_TILEDBG[slot].tilesize, file_id); // Lee el resto de caracteres de la fuente
|
||||
} else { // Si el archivo no existe...
|
||||
NF_Error(101, filename, 0);
|
||||
}
|
||||
fclose(file_id); // Cierra el archivo
|
||||
// Get file size
|
||||
NF_TILEDBG[slot].tilesize = NF_TEXT_FONT_CHARS << 6; // 100 chars x 64 bytes
|
||||
|
||||
// Rota los Gfx de los tiles si es necesario
|
||||
if (rotation > 0) {
|
||||
for (n = 0; n < NF_TEXT_FONT_CHARS; n ++) {
|
||||
NF_RotateTileGfx(slot, n, rotation);
|
||||
}
|
||||
}
|
||||
// Allocate space in RAM
|
||||
NF_BUFFER_BGTILES[slot] = malloc(NF_TILEDBG[slot].tilesize);
|
||||
if (NF_BUFFER_BGTILES[slot] == NULL) // If there is not enough RAM
|
||||
NF_Error(102, NULL, NF_TILEDBG[slot].tilesize);
|
||||
|
||||
// Crea un archivo .MAP vacio en RAM
|
||||
// ((ancho / 8) * (alto / 8)) * 2
|
||||
NF_TILEDBG[slot].mapsize = (((width >> 3) * (height >> 3)) << 1);
|
||||
// Reserva el espacio en RAM
|
||||
NF_BUFFER_BGMAP[slot] = (char*) calloc (NF_TILEDBG[slot].mapsize, sizeof(char));
|
||||
if (NF_BUFFER_BGMAP[slot] == NULL) { // Si no hay suficiente RAM libre
|
||||
NF_Error(102, NULL, NF_TILEDBG[slot].mapsize);
|
||||
}
|
||||
// Y ponlo a 0
|
||||
memset(NF_BUFFER_BGMAP[slot], 0, NF_TILEDBG[slot].mapsize);
|
||||
// Read file to RAM
|
||||
fread(NF_BUFFER_BGTILES[slot], 1, NF_TILEDBG[slot].tilesize, file_id);
|
||||
fclose(file_id);
|
||||
|
||||
// Carga el archivo .PAL
|
||||
snprintf(filename, sizeof(filename), "%s/%s.pal", NF_ROOTFOLDER, file);
|
||||
file_id = fopen(filename, "rb");
|
||||
if (file_id) { // Si el archivo existe...
|
||||
// Obten el tamaño del archivo
|
||||
fseek(file_id, 0, SEEK_END);
|
||||
NF_TILEDBG[slot].palsize = ftell(file_id);
|
||||
rewind(file_id);
|
||||
// Reserva el espacio en RAM
|
||||
NF_BUFFER_BGPAL[slot] = (char*) calloc (NF_TILEDBG[slot].palsize, sizeof(char));
|
||||
if (NF_BUFFER_BGPAL[slot] == NULL) { // Si no hay suficiente RAM libre
|
||||
NF_Error(102, NULL, NF_TILEDBG[slot].palsize);
|
||||
}
|
||||
// Lee el archivo y ponlo en la RAM
|
||||
fread(NF_BUFFER_BGPAL[slot], 1, NF_TILEDBG[slot].palsize, file_id);
|
||||
} else { // Si el archivo no existe...
|
||||
NF_Error(101, filename, 0);
|
||||
}
|
||||
fclose(file_id); // Cierra el archivo
|
||||
// Rotate graphics if requested
|
||||
if (rotation > 0)
|
||||
{
|
||||
for (int n = 0; n < NF_TEXT_FONT_CHARS; n++)
|
||||
NF_RotateTileGfx(slot, n, rotation);
|
||||
}
|
||||
|
||||
// Guarda el nombre del Fondo
|
||||
snprintf(NF_TILEDBG[slot].name, sizeof(NF_TILEDBG[slot].name), "%s", name);
|
||||
// Create an empty map in RAM
|
||||
|
||||
// Y las medidas
|
||||
NF_TILEDBG[slot].width = width;
|
||||
NF_TILEDBG[slot].height = height;
|
||||
// (width / 8) * (height / 8) * 2
|
||||
NF_TILEDBG[slot].mapsize = ((width >> 3) * (height >> 3)) << 1;
|
||||
|
||||
// Allocate space in RAM and zero it (calloc returns zeroed memory)
|
||||
NF_BUFFER_BGMAP[slot] = calloc(NF_TILEDBG[slot].mapsize, sizeof(char));
|
||||
if (NF_BUFFER_BGMAP[slot] == NULL) // If there is not enough RAM
|
||||
NF_Error(102, NULL, NF_TILEDBG[slot].mapsize);
|
||||
|
||||
// Load .PAL file
|
||||
snprintf(filename, sizeof(filename), "%s/%s.pal", NF_ROOTFOLDER, file);
|
||||
file_id = fopen(filename, "rb");
|
||||
if (file_id == NULL) // If the file can't be opened
|
||||
NF_Error(101, filename, 0);
|
||||
|
||||
// Get file size
|
||||
fseek(file_id, 0, SEEK_END);
|
||||
NF_TILEDBG[slot].palsize = ftell(file_id);
|
||||
rewind(file_id);
|
||||
|
||||
// Allocate space in RAM
|
||||
NF_BUFFER_BGPAL[slot] = malloc(NF_TILEDBG[slot].palsize);
|
||||
if (NF_BUFFER_BGPAL[slot] == NULL) // If there isn't enough free RAM
|
||||
NF_Error(102, NULL, NF_TILEDBG[slot].palsize);
|
||||
|
||||
// Read file to RAM
|
||||
fread(NF_BUFFER_BGPAL[slot], 1, NF_TILEDBG[slot].palsize, file_id);
|
||||
fclose(file_id);
|
||||
|
||||
// Save background name
|
||||
snprintf(NF_TILEDBG[slot].name, sizeof(NF_TILEDBG[slot].name), "%s", name);
|
||||
|
||||
// Save the size
|
||||
NF_TILEDBG[slot].width = width;
|
||||
NF_TILEDBG[slot].height = height;
|
||||
}
|
||||
|
||||
void NF_UnloadTextFont(const char* name) {
|
||||
NF_UnloadTiledBg(name);
|
||||
void NF_UnloadTextFont(const char *name)
|
||||
{
|
||||
NF_UnloadTiledBg(name);
|
||||
}
|
||||
|
||||
void NF_CreateTextLayer(u8 screen, u8 layer, u8 rotation, const char* name) {
|
||||
void NF_CreateTextLayer(u8 screen, u8 layer, u8 rotation, const char *name)
|
||||
{
|
||||
// Create a background to use it as a text layer
|
||||
NF_CreateTiledBg(screen, layer, name);
|
||||
|
||||
u8 slot = 255; // Slot seleccionado
|
||||
char bg[32]; // Nombre
|
||||
u32 slot = 255;
|
||||
|
||||
// Crea un fondo para usarlo como capa de texto
|
||||
NF_CreateTiledBg(screen, layer, name);
|
||||
// Look for the tiled background with the specified name
|
||||
for (int n = 0; n < NF_SLOTS_TBG; n ++)
|
||||
{
|
||||
if (strcmp(name, NF_TILEDBG[n].name) == 0)
|
||||
{
|
||||
slot = n;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Busca el numero de slot donde esta cargada la fuente
|
||||
snprintf(bg, sizeof(bg), "%s", name); // Obten el nombre del fondo a buscar
|
||||
for (int n = 0; n < NF_SLOTS_TBG; n ++) { // Busca en todos los slots
|
||||
if (strcmp(bg, NF_TILEDBG[n].name) == 0) { // Si lo encuentras
|
||||
slot = n; // Guarda el slot a usar
|
||||
n = NF_SLOTS_TBG; // Deja de buscar
|
||||
}
|
||||
}
|
||||
// If it hasn't been found, fail
|
||||
if (slot == 255)
|
||||
NF_Error(103, "Tiled Bg", NF_SLOTS_TBG);
|
||||
|
||||
// Guarda si el texto debe ser rotado
|
||||
NF_TEXT[screen][layer].rotation = rotation;
|
||||
NF_TEXT[screen][layer].rotation = rotation;
|
||||
|
||||
// Guarda las medidas del fondo en tiles (ultimo numero de tile)
|
||||
NF_TEXT[screen][layer].width = ((NF_TILEDBG[slot].width >> 3) - 1);
|
||||
NF_TEXT[screen][layer].height = ((NF_TILEDBG[slot].height >> 3) - 1);
|
||||
// Save the background size in tiles (save the index of the last row/column)
|
||||
NF_TEXT[screen][layer].width = (NF_TILEDBG[slot].width >> 3) - 1;
|
||||
NF_TEXT[screen][layer].height = (NF_TILEDBG[slot].height >> 3) - 1;
|
||||
|
||||
// Almacena el slot donde esta cargada la fuente
|
||||
NF_TEXT[screen][layer].slot = slot;
|
||||
|
||||
// Y marcalo como creado
|
||||
NF_TEXT[screen][layer].exist = true;
|
||||
// Save slot where the font is stored
|
||||
NF_TEXT[screen][layer].slot = slot;
|
||||
|
||||
// Mark layer as used
|
||||
NF_TEXT[screen][layer].exist = true;
|
||||
}
|
||||
|
||||
void NF_DeleteTextLayer(u8 screen, u8 layer) {
|
||||
void NF_DeleteTextLayer(u8 screen, u8 layer)
|
||||
{
|
||||
// Verify that the selected text layer exists
|
||||
if (!NF_TEXT[screen][layer].exist)
|
||||
NF_Error(114, NULL, screen);
|
||||
|
||||
// Verifica si la capa de texto de destino existe
|
||||
if (!NF_TEXT[screen][layer].exist) {
|
||||
NF_Error(114, NULL, screen);
|
||||
}
|
||||
// Delete the tiled background used as text layer
|
||||
NF_DeleteTiledBg(screen, layer);
|
||||
|
||||
// Borra el fondo usado como capa de texto
|
||||
NF_DeleteTiledBg(screen, layer);
|
||||
|
||||
// Guarda si el texto debe ser rotado
|
||||
NF_TEXT[screen][layer].rotation = 0;
|
||||
|
||||
// Guarda las medidas del fondo en tiles
|
||||
NF_TEXT[screen][layer].width = 0;
|
||||
NF_TEXT[screen][layer].height = 0;
|
||||
|
||||
// Y marcalo como creado
|
||||
NF_TEXT[screen][layer].exist = false;
|
||||
NF_TEXT[screen][layer].rotation = 0;
|
||||
NF_TEXT[screen][layer].width = 0;
|
||||
NF_TEXT[screen][layer].height = 0;
|
||||
|
||||
// Mark layer as unused
|
||||
NF_TEXT[screen][layer].exist = false;
|
||||
}
|
||||
|
||||
void NF_WriteText(u8 screen, u8 layer, u16 x, u16 y, const char* text) {
|
||||
void NF_WriteText(u8 screen, u8 layer, u16 x, u16 y, const char *text)
|
||||
{
|
||||
// Verify that the selected text layer exists
|
||||
if (!NF_TEXT[screen][layer].exist)
|
||||
NF_Error(114, NULL, screen);
|
||||
|
||||
// Verifica si la capa de texto de destino existe
|
||||
if (!NF_TEXT[screen][layer].exist) {
|
||||
NF_Error(114, NULL, screen);
|
||||
}
|
||||
u16 tsize = strlen(text); // Size of the temporary string buffer
|
||||
u8 *string = malloc(tsize); // Temporary string buffer
|
||||
if (string == NULL)
|
||||
NF_Error(102, NULL, tsize);
|
||||
|
||||
u16 n = 0; // Variable de uso general
|
||||
// Store the text string in the temporary buffer
|
||||
for (int n = 0; n < tsize; n++)
|
||||
{
|
||||
int value = text[n] - 32; // Skip the first 32 non-printable characters
|
||||
if (value < 0)
|
||||
value = 0;
|
||||
|
||||
s16 value = 0; // Valor
|
||||
string[n] = value;
|
||||
|
||||
u16 tsize = 0; // Almacena el numero de letras
|
||||
tsize = strlen(text); // Calcula el numero de letras del texto
|
||||
// Handle special characters
|
||||
if (string[n] > 95)
|
||||
{
|
||||
switch (text[n])
|
||||
{
|
||||
case 10: // \n
|
||||
string[n] = 200;
|
||||
break;
|
||||
|
||||
u8* string; // Buffer temporal
|
||||
string = NULL;
|
||||
string = (u8*) calloc (tsize, sizeof(u8));
|
||||
case 199: // Ç
|
||||
string[n] = 96;
|
||||
break;
|
||||
case 231: // ç
|
||||
string[n] = 97;
|
||||
break;
|
||||
case 209: // Ñ
|
||||
string[n] = 98;
|
||||
break;
|
||||
case 241: // ñ
|
||||
string[n] = 99;
|
||||
break;
|
||||
|
||||
// Almacena en el buffer temporal el valor de los caracteres
|
||||
for (n = 0; n < tsize; n ++) {
|
||||
value = ((int)(text[n])) - 32; // Resta 32 al valor entrado
|
||||
if (value < 0) value = 0;
|
||||
string[n] = value;
|
||||
// Si es un caracter especial...
|
||||
if (string[n] > 95) {
|
||||
// Resetea el caracter...
|
||||
string[n] = 0;
|
||||
// Verifica caracteres especiales
|
||||
switch (((int)(text[n]))) {
|
||||
// Salto de linea
|
||||
case 10: // \n
|
||||
string[n] = 200;
|
||||
break;
|
||||
// Caracteres especiales
|
||||
case 199: // Ç
|
||||
string[n] = 96;
|
||||
break;
|
||||
case 231: // ç
|
||||
string[n] = 97;
|
||||
break;
|
||||
case 209: // Ñ
|
||||
string[n] = 98;
|
||||
break;
|
||||
case 241: // ñ
|
||||
string[n] = 99;
|
||||
break;
|
||||
// Acentos Mayusculas
|
||||
case 193: // Á
|
||||
string[n] = 100;
|
||||
break;
|
||||
case 201: // É
|
||||
string[n] = 101;
|
||||
break;
|
||||
case 205: // Í
|
||||
string[n] = 102;
|
||||
break;
|
||||
case 211: // Ó
|
||||
string[n] = 103;
|
||||
break;
|
||||
case 218: // Ú
|
||||
string[n] = 104;
|
||||
break;
|
||||
// Acentos Minusculas
|
||||
case 225: // á
|
||||
string[n] = 105;
|
||||
break;
|
||||
case 233: // é
|
||||
string[n] = 106;
|
||||
break;
|
||||
case 237: // í
|
||||
string[n] = 107;
|
||||
break;
|
||||
case 243: // ó
|
||||
string[n] = 108;
|
||||
break;
|
||||
case 250: // ú
|
||||
string[n] = 109;
|
||||
break;
|
||||
// Dieresis
|
||||
case 239: // ï
|
||||
string[n] = 110;
|
||||
break;
|
||||
case 252: // ü
|
||||
string[n] = 111;
|
||||
break;
|
||||
// Admiracion e interrogante (Español)
|
||||
case 161: // ¡
|
||||
string[n] = 112;
|
||||
break;
|
||||
case 191: // ¿
|
||||
string[n] = 113;
|
||||
break;
|
||||
// Caracter invalido
|
||||
default:
|
||||
string[n] = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
case 193: // Á
|
||||
string[n] = 100;
|
||||
break;
|
||||
case 201: // É
|
||||
string[n] = 101;
|
||||
break;
|
||||
case 205: // Í
|
||||
string[n] = 102;
|
||||
break;
|
||||
case 211: // Ó
|
||||
string[n] = 103;
|
||||
break;
|
||||
case 218: // Ú
|
||||
string[n] = 104;
|
||||
break;
|
||||
|
||||
// Variable para calcular la posicion del texto
|
||||
s16 tx = 0; // X
|
||||
s16 ty = 0; // Y
|
||||
case 225: // á
|
||||
string[n] = 105;
|
||||
break;
|
||||
case 233: // é
|
||||
string[n] = 106;
|
||||
break;
|
||||
case 237: // í
|
||||
string[n] = 107;
|
||||
break;
|
||||
case 243: // ó
|
||||
string[n] = 108;
|
||||
break;
|
||||
case 250: // ú
|
||||
string[n] = 109;
|
||||
break;
|
||||
|
||||
// Escribe los datos en el buffer de texto, segun la rotacion
|
||||
switch (NF_TEXT[screen][layer].rotation) {
|
||||
case 239: // ï
|
||||
string[n] = 110;
|
||||
break;
|
||||
case 252: // ü
|
||||
string[n] = 111;
|
||||
break;
|
||||
|
||||
case 0: // Sin rotacion
|
||||
// Traspasa las coordenadas virtuales a las reales
|
||||
tx = x;
|
||||
ty = y;
|
||||
// Copia el texto al buffer letra a letra
|
||||
for (n = 0; n < tsize; n ++) {
|
||||
// Si es un caracter valido
|
||||
if (string[n] <= NF_TEXT_FONT_LAST_VALID_CHAR) {
|
||||
// Escribe la letra correspondiente
|
||||
NF_SetTileOfMap(screen,layer, tx, ty, ((NF_TEXT[screen][layer].pal << 12) + string[n]));
|
||||
// Siguiente letra
|
||||
tx ++;
|
||||
}
|
||||
if ((tx > NF_TEXT[screen][layer].width) || (string[n] == 200)) { // Si llegas al final de linea,
|
||||
tx = 0; // salto de linea
|
||||
ty ++;
|
||||
if (ty > NF_TEXT[screen][layer].height) { // Si estas en la ultima linea,
|
||||
ty = 0; // vuelve a la primera
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 161: // ¡
|
||||
string[n] = 112;
|
||||
break;
|
||||
case 191: // ¿
|
||||
string[n] = 113;
|
||||
break;
|
||||
|
||||
default:
|
||||
string[n] = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Variables to calculate the position of the text
|
||||
int tx, ty;
|
||||
|
||||
// Write text in the background map, according to the specified rotation
|
||||
switch (NF_TEXT[screen][layer].rotation)
|
||||
{
|
||||
case 0: // No rotation
|
||||
|
||||
tx = x;
|
||||
ty = y;
|
||||
|
||||
for (int n = 0; n < tsize; n++)
|
||||
{
|
||||
// If it's a valid character, put character
|
||||
if (string[n] <= NF_TEXT_FONT_LAST_VALID_CHAR)
|
||||
{
|
||||
NF_SetTileOfMap(screen,layer, tx, ty,
|
||||
(NF_TEXT[screen][layer].pal << 12) + string[n]);
|
||||
tx++;
|
||||
}
|
||||
|
||||
// If the end of the line is reached or a newline character is found
|
||||
if ((tx > NF_TEXT[screen][layer].width) || (string[n] == 200))
|
||||
{
|
||||
tx = 0;
|
||||
ty++;
|
||||
// If the last row is reached, return to the first one
|
||||
if (ty > NF_TEXT[screen][layer].height)
|
||||
ty = 0;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
case 1: // Rotacion 90º a la derecha
|
||||
// Traspasa las coordenadas virtuales a las reales
|
||||
tx = (NF_TEXT[screen][layer].width - y);
|
||||
ty = x;
|
||||
// Copia el texto al buffer letra a letra
|
||||
for (n = 0; n < tsize; n ++) {
|
||||
// Si es un caracter valido
|
||||
if (string[n] <= NF_TEXT_FONT_LAST_VALID_CHAR) {
|
||||
// Escribe la letra correspondiente
|
||||
NF_SetTileOfMap(screen,layer, tx, ty, ((NF_TEXT[screen][layer].pal << 12) + string[n]));
|
||||
// Siguiente letra
|
||||
ty ++;
|
||||
}
|
||||
if ((ty > NF_TEXT[screen][layer].height) || (string[n] == 200)) { // Si llegas al final de linea,
|
||||
ty = 0; // salto de linea
|
||||
tx --;
|
||||
if (tx < 0) { // Si estas en la ultima linea,
|
||||
tx = NF_TEXT[screen][layer].width; // vuelve a la primera
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 1: // 90 degrees of clockwise rotation
|
||||
|
||||
tx = NF_TEXT[screen][layer].width - y;
|
||||
ty = x;
|
||||
|
||||
case 2: // Rotacion 90º a la izquierda
|
||||
// Traspasa las coordenadas virtuales a las reales
|
||||
tx = y;
|
||||
ty = (NF_TEXT[screen][layer].height - x);
|
||||
// Copia el texto al buffer letra a letra
|
||||
for (n = 0; n < tsize; n ++) {
|
||||
// Si es un caracter valido
|
||||
if (string[n] <= NF_TEXT_FONT_LAST_VALID_CHAR) {
|
||||
// Escribe la letra correspondiente
|
||||
NF_SetTileOfMap(screen,layer, tx, ty, ((NF_TEXT[screen][layer].pal << 12) + string[n]));
|
||||
// Siguiente letra
|
||||
ty --;
|
||||
}
|
||||
if ((ty < 0) || (string[n] == 200)) { // Si llegas al final de linea,
|
||||
ty = NF_TEXT[screen][layer].height; // Salto de linea
|
||||
tx ++;
|
||||
if (tx > NF_TEXT[screen][layer].width) { // Si llegas a la ultima linea
|
||||
tx = 0; // vuelve a la primera
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
for (int n = 0; n < tsize; n++)
|
||||
{
|
||||
// If it's a valid character, put character
|
||||
if (string[n] <= NF_TEXT_FONT_LAST_VALID_CHAR)
|
||||
{
|
||||
NF_SetTileOfMap(screen,layer, tx, ty,
|
||||
(NF_TEXT[screen][layer].pal << 12) + string[n]);
|
||||
ty++;
|
||||
}
|
||||
|
||||
}
|
||||
// If the end of the line is reached or a newline character is found
|
||||
if ((ty > NF_TEXT[screen][layer].height) || (string[n] == 200))
|
||||
{
|
||||
ty = 0;
|
||||
tx--;
|
||||
|
||||
// Marca esta capa de texto para actualizar
|
||||
NF_TEXT[screen][layer].update = true;
|
||||
// If the last row is reached, return to the first one
|
||||
if (tx < 0)
|
||||
tx = NF_TEXT[screen][layer].width;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
// Libera el buffer
|
||||
free(string);
|
||||
case 2: // 90 degrees of counter-clockwise rotation
|
||||
|
||||
tx = y;
|
||||
ty = NF_TEXT[screen][layer].height - x;
|
||||
|
||||
for (int n = 0; n < tsize; n ++)
|
||||
{
|
||||
// If it's a valid character, put character
|
||||
if (string[n] <= NF_TEXT_FONT_LAST_VALID_CHAR)
|
||||
{
|
||||
NF_SetTileOfMap(screen,layer, tx, ty,
|
||||
(NF_TEXT[screen][layer].pal << 12) + string[n]);
|
||||
ty --;
|
||||
}
|
||||
|
||||
// If the end of the line is reached or a newline character is found
|
||||
if ((ty < 0) || (string[n] == 200))
|
||||
{
|
||||
ty = NF_TEXT[screen][layer].height;
|
||||
tx ++;
|
||||
|
||||
// If the last row is reached, return to the first one
|
||||
if (tx > NF_TEXT[screen][layer].width)
|
||||
tx = 0;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
// Mark this layer as needing an update
|
||||
NF_TEXT[screen][layer].update = true;
|
||||
|
||||
// Free temporary buffer
|
||||
free(string);
|
||||
}
|
||||
|
||||
void NF_UpdateTextLayers(void) {
|
||||
|
||||
// Variables
|
||||
u8 screen = 0;
|
||||
u8 layer = 0;
|
||||
|
||||
// Verifica si se tiene que actualizar la capa de texto
|
||||
for (screen = 0; screen < 2; screen ++) { // Bucle de pantalla
|
||||
for (layer = 0; layer < 4; layer ++) { // Bucle de capas
|
||||
if (NF_TEXT[screen][layer].update) { // Si estas marcado para actualizar, hazlo
|
||||
NF_UpdateVramMap(screen, layer);
|
||||
// Y marcala como actualizada
|
||||
NF_TEXT[screen][layer].update = false;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
void NF_UpdateTextLayers(void)
|
||||
{
|
||||
for (int screen = 0; screen < 2; screen++)
|
||||
{
|
||||
for (int layer = 0; layer < 4; layer++)
|
||||
{
|
||||
// If the layer needs to be updated, update it and mark it as not
|
||||
// requiring an update.
|
||||
if (NF_TEXT[screen][layer].update)
|
||||
{
|
||||
NF_UpdateVramMap(screen, layer);
|
||||
NF_TEXT[screen][layer].update = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void NF_ClearTextLayer(u8 screen, u8 layer) {
|
||||
void NF_ClearTextLayer(u8 screen, u8 layer)
|
||||
{
|
||||
// Verify that the selected text layer exists
|
||||
if (!NF_TEXT[screen][layer].exist)
|
||||
NF_Error(114, NULL, screen);
|
||||
|
||||
// Verifica si la capa de texto de destino existe
|
||||
if (!NF_TEXT[screen][layer].exist) {
|
||||
NF_Error(114, NULL, screen);
|
||||
}
|
||||
// Calculate buffer size
|
||||
u32 size = (NF_TEXT[screen][layer].width + 1) * (NF_TEXT[screen][layer].height + 1) * 2;
|
||||
|
||||
// Calcula el tamaño del buffer
|
||||
u32 size = (((NF_TEXT[screen][layer].width + 1) * (NF_TEXT[screen][layer].height + 1)) << 1);
|
||||
|
||||
// Pon a 0 todos los bytes del mapa de la capa de texto
|
||||
memset(NF_BUFFER_BGMAP[NF_TEXT[screen][layer].slot], 0, size);
|
||||
|
||||
// Marca esta capa de texto para actualizar
|
||||
NF_TEXT[screen][layer].update = true;
|
||||
// Zero the map
|
||||
memset(NF_BUFFER_BGMAP[NF_TEXT[screen][layer].slot], 0, size);
|
||||
|
||||
// Mark this layer as needing an update
|
||||
NF_TEXT[screen][layer].update = true;
|
||||
}
|
||||
|
||||
void NF_DefineTextColor(u8 screen, u8 layer, u8 color, u8 r, u8 g, u8 b) {
|
||||
void NF_DefineTextColor(u8 screen, u8 layer, u8 color, u8 r, u8 g, u8 b)
|
||||
{
|
||||
// Verify that the selected text layer exists
|
||||
if (!NF_TEXT[screen][layer].exist)
|
||||
NF_Error(114, NULL, screen);
|
||||
|
||||
// Verifica si la capa de texto de destino existe
|
||||
if (!NF_TEXT[screen][layer].exist) {
|
||||
NF_Error(114, NULL, screen);
|
||||
}
|
||||
|
||||
// Calcula el valor RGB
|
||||
u16 rgb = ((r)|((g) << 5)|((b) << 10));
|
||||
// Direccion en VRAM
|
||||
u32 address = 0;
|
||||
|
||||
// Modifica la paleta
|
||||
if (screen == 0) {
|
||||
|
||||
vramSetBankE(VRAM_E_LCD);
|
||||
address = (0x06880000) + (layer << 13) + (color << 9); // Primer color de la paleta
|
||||
*((u16*)address) = (u16)0xFF00FF;
|
||||
address = (0x06880000) + (layer << 13) + (color << 9) + 2; // Segundo color de la paleta
|
||||
*((u16*)address) = rgb;
|
||||
vramSetBankE(VRAM_E_BG_EXT_PALETTE);
|
||||
|
||||
} else { // Paletas de la pantalla 1 (VRAM_H)
|
||||
|
||||
vramSetBankH(VRAM_H_LCD);
|
||||
address = (0x06898000) + (layer << 13) + (color << 9); // Primer color de la paleta
|
||||
*((u16*)address) = (u16)0xFF00FF;
|
||||
address = (0x06898000) + (layer << 13) + (color << 9) + 2; // Segundo color de la paleta
|
||||
*((u16*)address) = rgb;
|
||||
vramSetBankH(VRAM_H_SUB_BG_EXT_PALETTE);
|
||||
|
||||
}
|
||||
// Pack RGB value
|
||||
u16 rgb = r | (g << 5) | (b << 10);
|
||||
|
||||
// Modify the palette of the selected screen
|
||||
if (screen == 0)
|
||||
{
|
||||
vramSetBankE(VRAM_E_LCD); // Enable CPU access to VRAM_E
|
||||
u32 address = 0x06880000 + (layer << 13) + (color << 9); // First color
|
||||
*((u16*)address) = (u16)0xFF00FF;
|
||||
address = 0x06880000 + (layer << 13) + (color << 9) + 2; // Second color
|
||||
*((u16*)address) = rgb;
|
||||
vramSetBankE(VRAM_E_BG_EXT_PALETTE);
|
||||
}
|
||||
else
|
||||
{
|
||||
vramSetBankH(VRAM_H_LCD); // Enable CPU access to VRAM_H
|
||||
u32 address = 0x06898000 + (layer << 13) + (color << 9); // First color
|
||||
*((u16*)address) = (u16)0xFF00FF;
|
||||
address = 0x06898000 + (layer << 13) + (color << 9) + 2; // Second color
|
||||
*((u16*)address) = rgb;
|
||||
vramSetBankH(VRAM_H_SUB_BG_EXT_PALETTE);
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user