library: Translate and cleanup some source files

This commit is contained in:
Antonio Niño Díaz 2023-05-21 22:29:57 +01:00
parent c3d6122d95
commit dc67afb8c9
4 changed files with 534 additions and 534 deletions

View File

@ -34,7 +34,7 @@ typedef struct {
bool available; ///< True if this slot is available bool available; ///< True if this slot is available
u32 size; ///< Size of the sound effect in bytes u32 size; ///< Size of the sound effect in bytes
u16 freq; ///< Frecuency of the sample u16 freq; ///< Frecuency of the sample
u8 format; ///< Format of the sample u8 format; ///< Format of the sample (0: 8 bits, 1: 16 bits, 2: ADPCM)
} NF_TYPE_RAWSOUND_INFO; } NF_TYPE_RAWSOUND_INFO;
/// Information of all sound effects. /// Information of all sound effects.

View File

@ -5,9 +5,6 @@
// NightFox LIB - Funciones 2D comunes // NightFox LIB - Funciones 2D comunes
// http://www.nightfoxandco.com/ // http://www.nightfoxandco.com/
#include <stdio.h>
#include <string.h>
#include <nds.h> #include <nds.h>
#include "nf_2d.h" #include "nf_2d.h"
@ -15,400 +12,427 @@
#include "nf_sprite256.h" #include "nf_sprite256.h"
#include "nf_tiledbg.h" #include "nf_tiledbg.h"
void NF_Set2D(u8 screen, u8 mode) { void NF_Set2D(u8 screen, u8 mode)
{
if (screen == 0) { // Pantalla Superior if (screen == 0)
{
switch (mode) { // Selecciona modo // Top screen
case 0: switch (mode)
videoSetMode(MODE_0_2D); {
break; case 0:
case 2: videoSetMode(MODE_0_2D);
videoSetMode(MODE_2_2D); break;
break; case 2:
case 5: videoSetMode(MODE_2_2D);
videoSetMode(MODE_5_2D); break;
break; case 5:
} videoSetMode(MODE_5_2D);
break;
} else { // Pantalla inferior }
}
switch (mode) { // Seleccion modo else
case 0: {
videoSetModeSub(MODE_0_2D); // Bottom screen
break; switch (mode)
case 2: {
videoSetModeSub(MODE_2_2D); case 0:
break; videoSetModeSub(MODE_0_2D);
case 5: break;
videoSetModeSub(MODE_5_2D); case 2:
break; videoSetModeSub(MODE_2_2D);
} break;
case 5:
} videoSetModeSub(MODE_5_2D);
break;
}
}
} }
void NF_ShowBg(u8 screen, u8 layer) { void NF_ShowBg(u8 screen, u8 layer)
{
if (screen == 0) { // Pantalla Superior if (screen == 0)
{
switch (layer) { // Segun la capa // Top screen
case 0: switch (layer)
REG_DISPCNT |= (DISPLAY_BG0_ACTIVE); {
break; case 0:
case 1: REG_DISPCNT |= DISPLAY_BG0_ACTIVE;
REG_DISPCNT |= (DISPLAY_BG1_ACTIVE); break;
break; case 1:
case 2: REG_DISPCNT |= DISPLAY_BG1_ACTIVE;
REG_DISPCNT |= (DISPLAY_BG2_ACTIVE); break;
break; case 2:
case 3: REG_DISPCNT |= DISPLAY_BG2_ACTIVE;
REG_DISPCNT |= (DISPLAY_BG3_ACTIVE); break;
break; case 3:
} REG_DISPCNT |= DISPLAY_BG3_ACTIVE;
break;
} else { // Pantalla Inferior }
}
switch (layer) { // Segun la capa else
case 0: {
REG_DISPCNT_SUB |= (DISPLAY_BG0_ACTIVE); // Bottom screen
break; switch (layer)
case 1: {
REG_DISPCNT_SUB |= (DISPLAY_BG1_ACTIVE); case 0:
break; REG_DISPCNT_SUB |= DISPLAY_BG0_ACTIVE;
case 2: break;
REG_DISPCNT_SUB |= (DISPLAY_BG2_ACTIVE); case 1:
break; REG_DISPCNT_SUB |= DISPLAY_BG1_ACTIVE;
case 3: break;
REG_DISPCNT_SUB |= (DISPLAY_BG3_ACTIVE); case 2:
break; REG_DISPCNT_SUB |= DISPLAY_BG2_ACTIVE;
} break;
case 3:
} REG_DISPCNT_SUB |= DISPLAY_BG3_ACTIVE;
break;
}
}
} }
void NF_HideBg(u8 screen, u8 layer) { void NF_HideBg(u8 screen, u8 layer)
{
if (screen == 0) { // Pantalla Superior if (screen == 0)
{
switch (layer) { // Segun la capa // Top screen
case 0: switch (layer)
REG_DISPCNT &= ~(DISPLAY_BG0_ACTIVE); {
break; case 0:
case 1: REG_DISPCNT &= ~DISPLAY_BG0_ACTIVE;
REG_DISPCNT &= ~(DISPLAY_BG1_ACTIVE); break;
break; case 1:
case 2: REG_DISPCNT &= ~DISPLAY_BG1_ACTIVE;
REG_DISPCNT &= ~(DISPLAY_BG2_ACTIVE); break;
break; case 2:
case 3: REG_DISPCNT &= ~DISPLAY_BG2_ACTIVE;
REG_DISPCNT &= ~(DISPLAY_BG3_ACTIVE); break;
break; case 3:
} REG_DISPCNT &= ~DISPLAY_BG3_ACTIVE;
break;
} else { // Pantalla Inferior }
}
switch (layer) { // Segun la capa else
case 0: {
REG_DISPCNT_SUB &= ~(DISPLAY_BG0_ACTIVE); // Bottom screen
break; switch (layer)
case 1: {
REG_DISPCNT_SUB &= ~(DISPLAY_BG1_ACTIVE); case 0:
break; REG_DISPCNT_SUB &= ~DISPLAY_BG0_ACTIVE;
case 2: break;
REG_DISPCNT_SUB &= ~(DISPLAY_BG2_ACTIVE); case 1:
break; REG_DISPCNT_SUB &= ~DISPLAY_BG1_ACTIVE;
case 3: break;
REG_DISPCNT_SUB &= ~(DISPLAY_BG3_ACTIVE); case 2:
break; REG_DISPCNT_SUB &= ~DISPLAY_BG2_ACTIVE;
} break;
case 3:
} REG_DISPCNT_SUB &= ~DISPLAY_BG3_ACTIVE;
break;
}
}
} }
void NF_ScrollBg(u8 screen, u8 layer, s16 x, s16 y) { void NF_ScrollBg(u8 screen, u8 layer, s16 x, s16 y)
{
// Temporary variables
s16 sx = x;
s16 sy = y;
// Variables temporales // If the map is infinite (> 512 tiles)
s16 sx = x; if (NF_TILEDBG_LAYERS[screen][layer].bgtype > 0)
s16 sy = y; {
// Temporary variables for infinite backgrounds
u32 address = 0; // VRAM address
u16 blockx = 0; // Number of block in the screen
u16 blocky = 0;
u32 mapmovex = 0; // Data copy offset (block x 2048)
u32 mapmovey = 0;
u16 rowsize = 0; // Size used by each row in RAM
// Si el mapa es infinito... > 512 // Calculate base address of the map in VRAM
if (NF_TILEDBG_LAYERS[screen][layer].bgtype > 0) { if (screen == 0) // VRAM_A
address = 0x6000000 + (NF_TILEDBG_LAYERS[screen][layer].mapbase << 11);
else // VRAM_C
address = 0x6200000 + (NF_TILEDBG_LAYERS[screen][layer].mapbase << 11);
// Variables temporales de Fondos infinitos // Limit scroll variables
u32 address = 0; // Puntero a la VRAM if (sx < 0)
u16 blockx = 0; // Nº de bloque en pantalla sx = 0;
u16 blocky = 0; if (sx > (NF_TILEDBG_LAYERS[screen][layer].bgwidth - 256))
u32 mapmovex = 0; // Desplazamiento de la copia de datos (block x 2048) sx = NF_TILEDBG_LAYERS[screen][layer].bgwidth - 256;
u32 mapmovey = 0;
u16 rowsize = 0; // Calcula el espacio ocupado en RAM por cada fila
// Calcula la direccion base del mapa if (sy < 0)
if (screen == 0) { // (VRAM_A) sy = 0;
address = (0x6000000) + (NF_TILEDBG_LAYERS[screen][layer].mapbase << 11); if (sy > (NF_TILEDBG_LAYERS[screen][layer].bgheight - 192))
} else { // (VRAM_C) sy = NF_TILEDBG_LAYERS[screen][layer].bgheight - 192;
address = (0x6200000) + (NF_TILEDBG_LAYERS[screen][layer].mapbase << 11);
}
// Ajusta el valor maximo de las variables a los limites del scroll // Handle the different types of map
if (sx < 0) { switch (NF_TILEDBG_LAYERS[screen][layer].bgtype)
sx = 0; {
} // 512x256 - Block A and B (32x32) + (32x32) (2kb x 2 = 4kb)
if (sx > (NF_TILEDBG_LAYERS[screen][layer].bgwidth - 256)) { case 1:
sx = (NF_TILEDBG_LAYERS[screen][layer].bgwidth - 256); // Calculate block
} blockx = x >> 8;
if (sy < 0) {
sy = 0;
}
if (sy > (NF_TILEDBG_LAYERS[screen][layer].bgheight - 192)) {
sy = (NF_TILEDBG_LAYERS[screen][layer].bgheight - 192);
}
// Segun el tipo de mapa... // If you have changed block...
switch (NF_TILEDBG_LAYERS[screen][layer].bgtype) { if (NF_TILEDBG_LAYERS[screen][layer].blockx != blockx)
{
// Calculate data offset
mapmovex = blockx << 11;
case 1: // 512x256 - Bloque A y B (32x32) + (32x32) (2kb x 2 = 4kb) // Copy blocks A and B (32x32) + (32x32) (2kb x 2 = 4kb)
// Calcula el bloque NF_DmaMemCopy((void *)address,
blockx = (x >> 8); NF_BUFFER_BGMAP[NF_TILEDBG_LAYERS[screen][layer].bgslot] + mapmovex,
// Si has cambiado de bloque... 4096);
if (NF_TILEDBG_LAYERS[screen][layer].blockx != blockx) {
// Calcula el desplazamiento de datos
mapmovex = (blockx << 11);
// Copias los Bloques A y B (32x32) + (32x32) (2kb x 2 = 4kb)
NF_DmaMemCopy((void*)address, (NF_BUFFER_BGMAP[NF_TILEDBG_LAYERS[screen][layer].bgslot] + mapmovex), 4096);
// Y actualiza el bloque actual
NF_TILEDBG_LAYERS[screen][layer].blockx = blockx;
}
// Calcula la X del fondo
sx = x - (blockx << 8);
break;
case 2: // 256x512 - Bloque A (32x64) (2kb x 2 = 4kb) // Update the current block
// Calcula el bloque NF_TILEDBG_LAYERS[screen][layer].blockx = blockx;
blocky = (y >> 8); }
// Si has cambiado de bloque...
if (NF_TILEDBG_LAYERS[screen][layer].blocky != blocky) {
// Calcula el desplazamiento de datos
mapmovey = (blocky << 11);
// Copias los Bloques A y B (32x32) + (32x32) (2kb x 2 = 4kb)
NF_DmaMemCopy((void*)address, (NF_BUFFER_BGMAP[NF_TILEDBG_LAYERS[screen][layer].bgslot] + mapmovey), 4096);
// Y actualiza el bloque actual
NF_TILEDBG_LAYERS[screen][layer].blocky = blocky;
}
// Calcula la X del fondo
sy = y - (blocky << 8);
break;
case 3: // >512x>512 // Calculate horizontal scroll
rowsize = (((((NF_TILEDBG_LAYERS[screen][layer].bgwidth - 1) >> 8)) + 1) << 11); sx = x - (blockx << 8);
// Calcula los bloques break;
blockx = (x >> 8);
blocky = (y >> 8);
if ( // Si se ha cambiado de bloque en alguna direccion...
(NF_TILEDBG_LAYERS[screen][layer].blockx != blockx)
||
(NF_TILEDBG_LAYERS[screen][layer].blocky != blocky)
) {
// Y el desplazamiento de datos
mapmovex = (blocky * rowsize) + (blockx << 11);
mapmovey = mapmovex + rowsize;
// Bloque A y B (32x32) + (32x32) (2kb x 2 = 4kb)
NF_DmaMemCopy((void*)address, (NF_BUFFER_BGMAP[NF_TILEDBG_LAYERS[screen][layer].bgslot] + mapmovex), 4096);
// Bloque (+4096) C y D (32x32) + (32x32) (2kb x 2 = 4kb)
NF_DmaMemCopy((void*)(address + 4096), (NF_BUFFER_BGMAP[NF_TILEDBG_LAYERS[screen][layer].bgslot] + mapmovey), 4096);
// Y actualiza el bloque actual
NF_TILEDBG_LAYERS[screen][layer].blockx = blockx;
NF_TILEDBG_LAYERS[screen][layer].blocky = blocky;
}
// Calcula la X e Y del fondo
sx = x - (blockx << 8);
sy = y - (blocky << 8);
break;
} // 256x512 - Block A (32x64) (2kb x 2 = 4kb)
case 2:
// Calculate block
blocky = y >> 8;
} // If you have changed block...
if (NF_TILEDBG_LAYERS[screen][layer].blocky != blocky)
{
// Calculate data offset
mapmovey = blocky << 11;
// Mueve el fondo usando los registros // Copy blocks A and B (32x32) + (32x32) (2kb x 2 = 4kb)
if (screen == 0) { // Pantalla Superior NF_DmaMemCopy((void *)address,
NF_BUFFER_BGMAP[NF_TILEDBG_LAYERS[screen][layer].bgslot] + mapmovey,
4096);
switch (layer) { // Segun la capa // Update the current block
case 0: NF_TILEDBG_LAYERS[screen][layer].blocky = blocky;
REG_BG0HOFS = sx; }
REG_BG0VOFS = sy;
break;
case 1:
REG_BG1HOFS = sx;
REG_BG1VOFS = sy;
break;
case 2:
REG_BG2HOFS = sx;
REG_BG2VOFS = sy;
break;
case 3:
REG_BG3HOFS = sx;
REG_BG3VOFS = sy;
break;
}
} else { // Calculate vertical scroll
sy = y - (blocky << 8);
break;
switch (layer) { // Segun la capa // >512 x >512
case 0: case 3:
REG_BG0HOFS_SUB = sx; rowsize = (((NF_TILEDBG_LAYERS[screen][layer].bgwidth - 1) >> 8) + 1) << 11;
REG_BG0VOFS_SUB = sy;
break;
case 1:
REG_BG1HOFS_SUB = sx;
REG_BG1VOFS_SUB = sy;
break;
case 2:
REG_BG2HOFS_SUB = sx;
REG_BG2VOFS_SUB = sy;
break;
case 3:
REG_BG3HOFS_SUB = sx;
REG_BG3VOFS_SUB = sy;
break;
}
} // Calculate blocks
blockx = x >> 8;
blocky = y >> 8;
// If you have changed block in any direction...
if ((NF_TILEDBG_LAYERS[screen][layer].blockx != blockx)
|| (NF_TILEDBG_LAYERS[screen][layer].blocky != blocky))
{
// Calculate data offset
mapmovex = (blocky * rowsize) + (blockx << 11);
mapmovey = mapmovex + rowsize;
// Blocks A and B (32x32) + (32x32) (2kb x 2 = 4kb)
NF_DmaMemCopy((void *)address,
NF_BUFFER_BGMAP[NF_TILEDBG_LAYERS[screen][layer].bgslot] + mapmovex,
4096);
// Blocks (+4096) C and D (32x32) + (32x32) (2kb x 2 = 4kb)
NF_DmaMemCopy((void *)(address + 4096),
NF_BUFFER_BGMAP[NF_TILEDBG_LAYERS[screen][layer].bgslot] + mapmovey,
4096);
// Update the current block
NF_TILEDBG_LAYERS[screen][layer].blockx = blockx;
NF_TILEDBG_LAYERS[screen][layer].blocky = blocky;
}
// Calculate horizontal and vertical scrolls
sx = x - (blockx << 8);
sy = y - (blocky << 8);
break;
}
}
// Set the scroll in the hardware registers
if (screen == 0)
{
// Top screen
switch (layer)
{
case 0:
REG_BG0HOFS = sx;
REG_BG0VOFS = sy;
break;
case 1:
REG_BG1HOFS = sx;
REG_BG1VOFS = sy;
break;
case 2:
REG_BG2HOFS = sx;
REG_BG2VOFS = sy;
break;
case 3:
REG_BG3HOFS = sx;
REG_BG3VOFS = sy;
break;
}
}
else
{
// Bottom screen
switch (layer)
{
case 0:
REG_BG0HOFS_SUB = sx;
REG_BG0VOFS_SUB = sy;
break;
case 1:
REG_BG1HOFS_SUB = sx;
REG_BG1VOFS_SUB = sy;
break;
case 2:
REG_BG2HOFS_SUB = sx;
REG_BG2VOFS_SUB = sy;
break;
case 3:
REG_BG3HOFS_SUB = sx;
REG_BG3VOFS_SUB = sy;
break;
}
}
} }
void NF_SpriteFrame(u8 screen, u8 id, u16 frame) { void NF_SpriteFrame(u8 screen, u8 id, u16 frame)
{
// Verify that the sprite ID is valid
if (id > 127)
NF_Error(106, "Sprite", 127);
// Verifica el rango de Id's de Sprites // Verify that the frame index exists
if (id > 127) { if (frame > NF_SPRITEOAM[screen][id].lastframe)
NF_Error(106, "Sprite", 127); NF_Error(106, "Sprite frame", NF_SPRITEOAM[screen][id].lastframe);
}
// Verifica el rango de frames del Sprite // Check if the frame needs to be updated
if (frame > NF_SPRITEOAM[screen][id].lastframe) { if (NF_SPRITEOAM[screen][id].frame != frame)
NF_Error(106, "Sprite frame", NF_SPRITEOAM[screen][id].lastframe); {
} if (NF_SPR256VRAM[screen][NF_SPRITEOAM[screen][id].gfxid].keepframes)
{
// If we need to automatically copy frames from RAM to VRAM because
// they haven't been copied to VRAM when loading the sprite.
// Temporary variables
char *source; // Source pointer
u32 destination = 0; // Destination pointer
u16 ramid = 0; // RAM slot that contains the graphics of the frame
// Verifica si el frame necesita ser actualizado // Calculate source and destination for the copy
if (NF_SPRITEOAM[screen][id].frame != frame) { ramid = NF_SPR256VRAM[screen][NF_SPRITEOAM[screen][id].gfxid].ramid;
source = NF_BUFFER_SPR256GFX[ramid] + (NF_SPRITEOAM[screen][id].framesize * frame);
destination = NF_SPR256VRAM[screen][NF_SPRITEOAM[screen][id].gfxid].address;
// Si debes de copiar el nuevo frame desde la RAM a la VRAM... NF_DmaMemCopy((void *)destination, source, NF_SPRITEOAM[screen][id].framesize);
if (NF_SPR256VRAM[screen][NF_SPRITEOAM[screen][id].gfxid].keepframes) { }
else
{
// If all frames are in VRAM
// Variables temporales // Calculate the address of the graphics of the frame
char* source; // Puntero de origen u32 address = 0;
u32 destination = 0; // Puntero de destino address = NF_SPR256VRAM[screen][NF_SPRITEOAM[screen][id].gfxid].address
u16 ramid = 0; // Slot de RAM donde se encuentra el Gfx + (NF_SPRITEOAM[screen][id].framesize * frame);
NF_SPRITEOAM[screen][id].gfx = (u32*)address;
// Calcula el origen y destino del nuevo frame a copiar }
ramid = NF_SPR256VRAM[screen][NF_SPRITEOAM[screen][id].gfxid].ramid;
source = NF_BUFFER_SPR256GFX[ramid] + (NF_SPRITEOAM[screen][id].framesize * frame);
destination = NF_SPR256VRAM[screen][NF_SPRITEOAM[screen][id].gfxid].address;
// Copialo
NF_DmaMemCopy((void*)destination, source, NF_SPRITEOAM[screen][id].framesize);
} else { // Si todos los frames ya estan en VRAM...
// Calcula la direccion del Gfx del frame
u32 address = 0;
address = NF_SPR256VRAM[screen][NF_SPRITEOAM[screen][id].gfxid].address + (NF_SPRITEOAM[screen][id].framesize * frame);
NF_SPRITEOAM[screen][id].gfx = (u32*)address;
}
// Almacena el frame actual
NF_SPRITEOAM[screen][id].frame = frame;
}
// Set the current frame
NF_SPRITEOAM[screen][id].frame = frame;
}
} }
void NF_EnableSpriteRotScale(u8 screen, u8 sprite, u8 id, bool doublesize) { void NF_EnableSpriteRotScale(u8 screen, u8 sprite, u8 id, bool doublesize)
{
// Verify that the sprite ID is valid
if (sprite > 127)
NF_Error(106, "Sprite", 127);
// Verifica el rango de Id's de Sprites // Verifica el rango de Id's de Rotacion
if (sprite > 127) { if (id > 31) {
NF_Error(106, "Sprite", 127); NF_Error(106, "RotScale", 127);
} }
// Verifica el rango de Id's de Rotacion // Verify that the sprite has been created
if (id > 31) { if (!NF_SPRITEOAM[screen][sprite].created)
NF_Error(106, "RotScale", 127); {
} char text[4];
snprintf(text, sizeof(text), "%d", screen);
// Verifica si el Sprite esta creado NF_Error(112, text, sprite);
if (!NF_SPRITEOAM[screen][sprite].created) { }
char text[4];
snprintf(text, sizeof(text), "%d", screen);
NF_Error(112, text, sprite);
}
NF_SPRITEOAM[screen][sprite].rot = id; // Id de rotacion (-1 ninguno) (0 - 31 Id de rotacion)
NF_SPRITEOAM[screen][sprite].doublesize = doublesize; // Usar el "double size" al rotar ? ("NO" por defecto)
// Rotation ID (-1 means none). Valid IDs are 0 to 31
NF_SPRITEOAM[screen][sprite].rot = id;
// Enable or disable "double size" mode when rotating
NF_SPRITEOAM[screen][sprite].doublesize = doublesize;
} }
void NF_DisableSpriteRotScale(u8 screen, u8 sprite) { void NF_DisableSpriteRotScale(u8 screen, u8 sprite)
{
// Verify that the sprite ID is valid
if (sprite > 127)
NF_Error(106, "Sprite", 127);
// Verifica el rango de Id's de Sprites // Verify that the sprite has been created
if (sprite > 127) { if (!NF_SPRITEOAM[screen][sprite].created)
NF_Error(106, "Sprite", 127); {
} char text[4];
snprintf(text, sizeof(text), "%d", screen);
// Verifica si el Sprite esta creado NF_Error(112, text, sprite);
if (!NF_SPRITEOAM[screen][sprite].created) { }
char text[4];
snprintf(text, sizeof(text), "%d", screen);
NF_Error(112, text, sprite);
}
NF_SPRITEOAM[screen][sprite].rot = -1; // Id de rotacion (-1 ninguno) (0 - 31 Id de rotacion)
NF_SPRITEOAM[screen][sprite].doublesize = false; // Usar el "double size" al rotar ? ("NO" por defecto)
// Rotation ID (-1 means none). Valid IDs are 0 to 31
NF_SPRITEOAM[screen][sprite].rot = -1;
// Disable "double size" mode when rotating
NF_SPRITEOAM[screen][sprite].doublesize = false;
} }
void NF_SpriteRotScale(u8 screen, u8 id, s16 angle, u16 sx, u16 sy) { void NF_SpriteRotScale(u8 screen, u8 id, s16 angle, u16 sx, u16 sy)
{
// Temporary variables
s16 in = 0; // Input angle
s16 out = 0; // Converted angle
// Variables temporales in = angle;
s16 in = 0; // Angulo dado
s16 out = 0; // Angulo convertido
in = angle; // Angle limits
if (in < -512)
in += 512;
if (in > 512)
in -= 512;
// Limites del angulo // Scale X limits
if (in < -512) { if (sx > 512)
in += 512; sx = 512;
}
if (in > 512) {
in -= 512;
}
// Limites del factor X
if (sx > 512) {
sx = 512;
}
// Limites del factor Y
if (sy > 512) {
sy = 512;
}
// Si es un numero negativo... // Scale Y limits
if (in < 0) { if (sy > 512)
in = -in; // Pasa a positivo (para poder hacer el bitshift) sy = 512;
out = (in << 6); // (in * 64); Pasa de base 512 a base 32768
// Dejalo en positivo para que <0 gire a la izquierda
} else {
out = (in << 6);
out = -out; // Pasalo a negativo para que >0 gire a la derecha
}
// Actualiza el RotScale del OAM if (in < 0) // If the angle is negative
if (screen == 0) { {
oamRotateScale(&oamMain, id, out, (512 - sx), (512 - sy)); in = -in; // Make it positive (to be able to do a bitshift)
} else { out = in << 6; // (in * 64); Switch from base 512 to base 32768
oamRotateScale(&oamSub, id, out, (512 - sx), (512 - sy)); // Leave it positive so that <0 rotates counter-clockwise
} }
else
{
out = in << 6;
out = -out; // Make it negative so that <0 rotates clockwise
}
// Update rotation and scale in OAM
if (screen == 0)
oamRotateScale(&oamMain, id, out, 512 - sx, 512 - sy);
else
oamRotateScale(&oamSub, id, out, 512 - sx, 512 - sy);
} }

View File

@ -5,113 +5,92 @@
// NightFox LIB - Funciones 2D comunes // NightFox LIB - Funciones 2D comunes
// http://www.nightfoxandco.com/ // http://www.nightfoxandco.com/
#include <stdio.h>
#include <string.h>
#include <nds.h> #include <nds.h>
#include "nf_2d.h" #include "nf_2d.h"
#include "nf_3d.h" #include "nf_3d.h"
#include "nf_basic.h" #include "nf_basic.h"
void NF_Set3D(u8 screen, u8 mode) { void NF_Set3D(u8 screen, u8 mode)
{
// Especifica en que pantalla estara el main engine (unico que puede usar 3D) // Only the main engine can use 3D, so we need to swap the screens if the
if (screen == 0) { // user wants the 3D output to be in the screen that isn't the main one.
lcdMainOnTop(); if (screen == 0)
} else { lcdMainOnTop();
lcdMainOnBottom(); else
} lcdMainOnBottom();
// Selecciona modo 3D
switch (mode) {
case 0:
videoSetMode(MODE_0_3D);
break;
case 2:
videoSetMode(MODE_2_3D);
break;
case 5:
videoSetMode(MODE_5_3D);
break;
}
// Use the selected 3D mode
switch (mode)
{
case 0:
videoSetMode(MODE_0_3D);
break;
case 2:
videoSetMode(MODE_2_3D);
break;
case 5:
videoSetMode(MODE_5_3D);
break;
}
} }
void NF_InitOpenGL(void) { void NF_InitOpenGL(void)
{
// Initialize internal OpenGL state
glInit();
// Inicializa el OpenGL de Libnds // Define viewport to the complete screen
glInit(); glViewport(0, 0, 255, 191);
// Define el tamaño de la ventana 3D (toda la pantalla) // Setup projection matrix as an orthographic projection
glViewport(0, 0, 255, 191); glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrthof32(0, 256, 192, 0, 1024, -1024);
// Configura la matriz de proyeccion // Setup modelview matrix as an identity matrix
glMatrixMode(GL_PROJECTION); // Selecciona la matriz glMatrixMode(GL_MODELVIEW);
glLoadIdentity(); // Y reseteala glLoadIdentity();
// Ajusta OpenGL para proyeccion Ortografica // Disable transparency and culling for new polygons
glOrthof32(0, 256, 192, 0, 1024, -1024); glPolyFmt(POLY_ALPHA(31) | POLY_CULL_NONE);
// Configura la matriz de visualizacion de modelos // Setup background as transparent, and set it at the maximum distance
glMatrixMode(GL_MODELVIEW); // Selecciona la matriz glClearColor(0, 0, 0, 0);
glLoadIdentity(); // Y reseteala glClearDepth(0x7FFF);
// Por defecto, todos los poligonos son opacos // Set the default vertex color as white
glPolyFmt(POLY_ALPHA(31) | POLY_CULL_NONE); glColor(RGB15(31, 31, 31));
// Configura el fondo // Enable textures and alpha blending
glClearColor(0, 0, 0, 0); // Fondo transparente glEnable(GL_TEXTURE_2D | GL_BLEND);
glClearDepth(0x7FFF); // Define la distancia de vision
// Configura la iluminacion global
glColor(RGB15(31, 31, 31));
// Habilita las texturas
glEnable(GL_TEXTURE_2D | GL_BLEND);
// Habilita la capa de dibujado
NF_ShowBg(0, 0);
// 3D output is sent to layer 0, so enable it
NF_ShowBg(0, 0);
} }
u16 NF_GetTextureSize(u16 textel) { u16 NF_GetTextureSize(u16 textel)
{
// Variables // Return the texel size as a base 2 log: Real size = 8 << Returned size
u16 size = 0; switch (textel)
{
// Devuelve el tamaño del textel, segun su base2 case 8:
switch (textel) { return 0;
case 8: case 16:
size = 0; return 1;
break; case 32:
case 16: return 2;
size = 1; case 64:
break; return 3;
case 32: case 128:
size = 2; return 4;
break; case 256:
case 64: return 5;
size = 3; case 512:
break; return 6;
case 128: case 1024:
size = 4; return 7;
break; default:
case 256: return 255;
size = 5; }
break;
case 512:
size = 6;
break;
case 1024:
size = 7;
break;
default:
size = 255;
break;
}
// Devuelve el valor
return size;
} }

View File

@ -7,131 +7,128 @@
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#include <unistd.h>
#include <nds.h> #include <nds.h>
#include "nf_basic.h" #include "nf_basic.h"
#include "nf_sound.h" #include "nf_sound.h"
// Define los Buffers para almacenar los archivos de audio // Buffers of all sound effects
char* NF_BUFFER_RAWSOUND[NF_SLOTS_RAWSOUND]; char *NF_BUFFER_RAWSOUND[NF_SLOTS_RAWSOUND];
// Datos de los sonidos cargado // Information about all loaded sound effects
NF_TYPE_RAWSOUND_INFO NF_RAWSOUND[NF_SLOTS_RAWSOUND]; NF_TYPE_RAWSOUND_INFO NF_RAWSOUND[NF_SLOTS_RAWSOUND];
void NF_InitRawSoundBuffers(void)
void NF_InitRawSoundBuffers(void) { {
// Initialize buffers for RAW sound files
// Inicializa Buffers de sonido en RAW for (int n = 0; n < NF_SLOTS_RAWSOUND; n++)
for (int n = 0; n < NF_SLOTS_RAWSOUND; n ++) { {
NF_BUFFER_RAWSOUND[n] = NULL; // Inicializa puntero NF_BUFFER_RAWSOUND[n] = NULL; // Pointer to the data
NF_RAWSOUND[n].available = true; // Disponibilidad del slot NF_RAWSOUND[n].available = true; // Availability of this slot
NF_RAWSOUND[n].size = 0; // Tamaño del archivo NF_RAWSOUND[n].size = 0; // File size
NF_RAWSOUND[n].freq = 0; // Frecuencia del sample NF_RAWSOUND[n].freq = 0; // Frecuency of the sample
NF_RAWSOUND[n].format = 0; // Formato del sample NF_RAWSOUND[n].format = 0; // Format of the sample
} }
} }
void NF_ResetRawSoundBuffers(void) { void NF_ResetRawSoundBuffers(void)
// Borra los datos de los buffers de sonido en RAW {
for (int n = 0; n < NF_SLOTS_RAWSOUND; n ++) { // Free all buffers of RAW sound files
free(NF_BUFFER_RAWSOUND[n]); // Borra el contenido puntero for (int n = 0; n < NF_SLOTS_RAWSOUND; n ++)
} free(NF_BUFFER_RAWSOUND[n]);
// Reinicia las estructuras de datos
NF_InitRawSoundBuffers();
// Reset data structures
NF_InitRawSoundBuffers();
} }
void NF_LoadRawSound(const char* file, u16 id, u16 freq, u8 format) { void NF_LoadRawSound(const char *file, u16 id, u16 freq, u8 format)
{
// Verify that the ID is inside the valid range
if (id >= NF_SLOTS_RAWSOUND)
NF_Error(106, "Raw Sound", NF_SLOTS_RAWSOUND);
// Verifica el rango de Id's // Verify that the ID is free
if (id >= NF_SLOTS_RAWSOUND) { if (!NF_RAWSOUND[id].available)
NF_Error(106, "Raw Sound", NF_SLOTS_RAWSOUND); NF_Error(109, "Raw Sound", id);
}
// Verifica si la Id esta libre // Free the buffer in case it already has data
if (!NF_RAWSOUND[id].available) { free(NF_BUFFER_RAWSOUND[id]);
NF_Error(109, "Raw Sound", id); NF_BUFFER_RAWSOUND[id] = NULL;
}
// Vacia los buffers que se usaran // File path
free(NF_BUFFER_RAWSOUND[id]); char filename[256];
NF_BUFFER_RAWSOUND[id] = NULL;
// Declara los punteros a los ficheros // Try to load the .RAW file
FILE* file_id; snprintf(filename, sizeof(filename), "%s/%s.raw", NF_ROOTFOLDER, file);
FILE *file_id = fopen(filename, "rb");
if (file_id == NULL)
{
// The file doesn't exist
NF_Error(101, filename, 0);
}
// Variable para almacenar el path al archivo // Get file size
char filename[256]; fseek(file_id, 0, SEEK_END);
NF_RAWSOUND[id].size = ftell(file_id);
rewind(file_id);
// Carga el archivo .RAW // If the size is over the limit
snprintf(filename, sizeof(filename), "%s/%s.raw", NF_ROOTFOLDER, file); if (NF_RAWSOUND[id].size > (1 << 18))
file_id = fopen(filename, "rb"); NF_Error(116, filename, (1 << 18));
if (file_id) { // Si el archivo existe...
// Obten el tamaño del archivo
fseek(file_id, 0, SEEK_END);
NF_RAWSOUND[id].size = ftell(file_id);
rewind(file_id);
// Si excede del tamaño maximo, error
if (NF_RAWSOUND[id].size > (1 << 18)) NF_Error(116, filename, (1 << 18));
// Reserva el espacio en RAM
NF_BUFFER_RAWSOUND[id] = (char*) calloc (NF_RAWSOUND[id].size, sizeof(char));
if (NF_BUFFER_RAWSOUND[id] == NULL) { // Si no hay suficiente RAM libre
NF_Error(102, NULL, NF_RAWSOUND[id].size);
}
// Lee el archivo y ponlo en la RAM
fread(NF_BUFFER_RAWSOUND[id], 1, NF_RAWSOUND[id].size, file_id);
} else { // Si el archivo no existe...
NF_Error(101, filename, 0);
}
fclose(file_id); // Cierra el archivo
// swiWaitForVBlank(); // Espera al cierre del archivo (Usar en caso de corrupcion de datos)
// Guarda los parametros del archivo de sonido // Allocate space in RAM
NF_RAWSOUND[id].freq = freq; // Frequencia del sample (en Hz) NF_BUFFER_RAWSOUND[id] = calloc(NF_RAWSOUND[id].size, sizeof(char));
NF_RAWSOUND[id].format = format; // Formato del sample (0 - > 8 bits, 1 - > 16 bits, 2 -> ADPCM) if (NF_BUFFER_RAWSOUND[id] == NULL) // Not enough RAM
NF_Error(102, NULL, NF_RAWSOUND[id].size);
// Y marca esta ID como usada // Read file and save it in RAM
NF_RAWSOUND[id].available = false; fread(NF_BUFFER_RAWSOUND[id], 1, NF_RAWSOUND[id].size, file_id);
// Close file
fclose(file_id);
// Save sound parameters
NF_RAWSOUND[id].freq = freq;
NF_RAWSOUND[id].format = format;
// Mark this slot as used
NF_RAWSOUND[id].available = false;
} }
void NF_UnloadRawSound(u8 id) { void NF_UnloadRawSound(u8 id)
{
// Verify that the ID is inside the valid range
if (id >= NF_SLOTS_RAWSOUND)
NF_Error(106, "RAW Sound", NF_SLOTS_RAWSOUND);
// Verifica el rango de Id's // Verify that the sound exists
if (id >= NF_SLOTS_RAWSOUND) if (NF_RAWSOUND[id].available)
NF_Error(106, "RAW Sound", NF_SLOTS_RAWSOUND); NF_Error(110, "RAW Sound", id);
// Verifica si el sonido existe // Free the data of this slot
if (NF_RAWSOUND[id].available) free(NF_BUFFER_RAWSOUND[id]);
NF_Error(110, "RAW Sound", id); NF_BUFFER_RAWSOUND[id] = NULL;
// Vacia los buffers de la Id. seleccionada // Reset variables
free(NF_BUFFER_RAWSOUND[id]); NF_RAWSOUND[id].freq = 0;
NF_BUFFER_RAWSOUND[id] = NULL; NF_RAWSOUND[id].format = 0;
// Resetea las variables
NF_RAWSOUND[id].freq = 0; // Frequencia del sample (en Hz)
NF_RAWSOUND[id].format = 0; // Formato del sample (0 - > 8 bits, 1 - > 16 bits, 2 -> ADPCM)
// Y marca esta ID como libre
NF_RAWSOUND[id].available = true;
// Mark this slot as free
NF_RAWSOUND[id].available = true;
} }
u8 NF_PlayRawSound(u8 id, u8 volume, u8 pan, bool loop, u16 loopfrom) { u8 NF_PlayRawSound(u8 id, u8 volume, u8 pan, bool loop, u16 loopfrom)
{
// Verify that the ID is inside the valid range
if (id >= NF_SLOTS_RAWSOUND)
NF_Error(106, "RAW Sound", NF_SLOTS_RAWSOUND);
// Verifica el rango de Id's // Verify that the sound exists
if (id >= NF_SLOTS_RAWSOUND) if (NF_RAWSOUND[id].available)
NF_Error(106, "RAW Sound", NF_SLOTS_RAWSOUND); NF_Error(110, "RAW Sound", id);
// Verifica si el sonido existe
if (NF_RAWSOUND[id].available)
NF_Error(110, "RAW Sound", id);
return soundPlaySample(NF_BUFFER_RAWSOUND[id], NF_RAWSOUND[id].format, NF_RAWSOUND[id].size, NF_RAWSOUND[id].freq, volume, pan, loop, loopfrom);
return soundPlaySample(NF_BUFFER_RAWSOUND[id], NF_RAWSOUND[id].format,
NF_RAWSOUND[id].size, NF_RAWSOUND[id].freq,
volume, pan, loop, loopfrom);
} }