mirror of
https://github.com/AntonioND/dsma-library.git
synced 2025-06-18 16:45:33 -04:00
221 lines
5.3 KiB
C
221 lines
5.3 KiB
C
// SPDX-License-Identifier: CC0-1.0
|
|
//
|
|
// SPDX-FileContributor: Antonio Niño Díaz, 2022
|
|
|
|
#include <stdbool.h>
|
|
#include <stdio.h>
|
|
|
|
#include <filesystem.h>
|
|
#include <nds.h>
|
|
|
|
#include "dsma/dsma.h"
|
|
|
|
int file_load(const char *filename, void **buffer, size_t *size_)
|
|
{
|
|
FILE *f = fopen(filename, "rb");
|
|
size_t size;
|
|
|
|
*buffer = NULL;
|
|
if (size_)
|
|
*size_ = 0;
|
|
|
|
if (f == NULL)
|
|
{
|
|
iprintf("%s couldn't be opened!\n", filename);
|
|
return -1;
|
|
}
|
|
|
|
fseek(f, 0, SEEK_END);
|
|
size = ftell(f);
|
|
if (size_)
|
|
*size_ = size;
|
|
|
|
if (size == 0)
|
|
{
|
|
iprintf("Size of %s is 0!\n", filename);
|
|
fclose(f);
|
|
return -1;
|
|
}
|
|
|
|
rewind(f);
|
|
*buffer = malloc(size);
|
|
if (*buffer == NULL)
|
|
{
|
|
iprintf("Not enought memory to load %s!\n", filename);
|
|
fclose(f);
|
|
return -1;
|
|
}
|
|
|
|
if (fread(*buffer, size, 1, f) != 1)
|
|
{
|
|
iprintf("Error while reading: %s\n", filename);
|
|
fclose(f);
|
|
free(*buffer);
|
|
return -1;
|
|
}
|
|
|
|
fclose(f);
|
|
|
|
return 0;
|
|
}
|
|
|
|
void setup_video(void)
|
|
{
|
|
videoSetMode(MODE_0_3D);
|
|
|
|
vramSetBankA(VRAM_A_TEXTURE);
|
|
|
|
consoleDemoInit();
|
|
|
|
glInit();
|
|
|
|
glEnable(GL_ANTIALIAS);
|
|
glEnable(GL_TEXTURE_2D);
|
|
|
|
// Setup the rear plane
|
|
glClearColor(2, 2, 2, 31); // BG must be opaque for AA to work
|
|
glClearPolyID(63); // BG must have a unique polygon ID for AA to work
|
|
glClearDepth(0x7FFF);
|
|
|
|
glViewport(0, 0, 255, 191);
|
|
|
|
glMatrixMode(GL_PROJECTION);
|
|
glLoadIdentity();
|
|
gluPerspective(70, 256.0 / 192.0, 0.1, 40);
|
|
|
|
glLight(0, RGB15(0, 31, 0), 0, floattov10(0.8), floattov10(-0.2));
|
|
glLight(1, RGB15(31, 0, 0), 0, floattov10(-0.8), floattov10(-0.2));
|
|
glLight(2, RGB15(31, 31, 0), floattov10(0.7), 0, floattov10(-0.7));
|
|
glLight(3, RGB15(0, 0, 31), floattov10(-0.7), 0, floattov10(-0.7));
|
|
|
|
glMaterialf(GL_AMBIENT, RGB15(0, 0, 0));
|
|
glMaterialf(GL_DIFFUSE, RGB15(31, 31, 31));
|
|
glMaterialf(GL_SPECULAR, BIT(15) | RGB15(0, 0, 0));
|
|
glMaterialf(GL_EMISSION, RGB15(0, 0, 0));
|
|
glMaterialShinyness();
|
|
|
|
glMatrixMode(GL_MODELVIEW);
|
|
//glMatrixMode(GL_POSITION); // This rotates lights with the model
|
|
|
|
glPolyFmt(POLY_ALPHA(31) | POLY_CULL_BACK | POLY_FORMAT_LIGHT0 |
|
|
POLY_FORMAT_LIGHT1 | POLY_FORMAT_LIGHT2 | POLY_FORMAT_LIGHT3);
|
|
}
|
|
|
|
int main(void)
|
|
{
|
|
// Basic 3D setup, mostly from libnds examples
|
|
setup_video();
|
|
|
|
if (!nitroFSInit(NULL))
|
|
{
|
|
iprintf("nitroFSInit failed.\nPress START to exit");
|
|
while(1)
|
|
{
|
|
swiWaitForVBlank();
|
|
scanKeys();
|
|
if (keysHeld()&KEY_START)
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
// Load files from the filesystem
|
|
void *texture128, *dsa_file, *dsm_file;
|
|
size_t texture128_size, dsa_file_size, dsm_file_size;
|
|
|
|
int ret = 0;
|
|
ret |= file_load("robot.dsm", &dsm_file, &dsm_file_size);
|
|
ret |= file_load("robot_walk.dsa", &dsa_file, &dsa_file_size);
|
|
ret |= file_load("texture128.bin", &texture128, &texture128_size);
|
|
if (ret)
|
|
{
|
|
iprintf("Press START to exit");
|
|
while(1)
|
|
{
|
|
swiWaitForVBlank();
|
|
scanKeys();
|
|
if (keysHeld()&KEY_START)
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
printf("\x1b[20;0HLoaded files:");
|
|
printf("\x1b[21;0HDSM: %8zu bytes", dsm_file_size);
|
|
printf("\x1b[22;0HDSA: %8zu bytes", dsa_file_size);
|
|
printf("\x1b[23;0HTexture: %8zu bytes", texture128_size);
|
|
|
|
// Load texture
|
|
int textureID;
|
|
glGenTextures(1, &textureID);
|
|
glBindTexture(0, textureID);
|
|
glTexImage2D(0, 0, GL_RGB, TEXTURE_SIZE_128, TEXTURE_SIZE_128, 0,
|
|
TEXGEN_TEXCOORD, texture128);
|
|
|
|
// Obtain number of frames in the animation
|
|
const uint32_t num_frames = DSMA_GetNumFrames(dsa_file);
|
|
|
|
printf("\x1b[1;0HAnimate model: L/R");
|
|
printf("\x1b[2;0HRotate model: Direction pad");
|
|
printf("\x1b[3;0HExit demo: START");
|
|
|
|
int32_t frame = 0;
|
|
float rotateY = 0.0;
|
|
float rotateZ = 0.0;
|
|
|
|
while(1)
|
|
{
|
|
glLoadIdentity();
|
|
|
|
gluLookAt(8.0, 3.0, 0.0, // camera possition
|
|
0.0, 3.0, 0.0, // look at
|
|
0.0, 1.0, 0.0); // up
|
|
|
|
// Draw animated model
|
|
glPushMatrix();
|
|
{
|
|
glRotateY(rotateY);
|
|
glRotateZ(rotateZ);
|
|
|
|
glBindTexture(0, textureID);
|
|
|
|
DSMA_DrawModel(dsm_file, dsa_file, frame);
|
|
}
|
|
glPopMatrix(1);
|
|
|
|
scanKeys();
|
|
u16 keys_held = keysHeld();
|
|
|
|
if (keys_held & KEY_UP)
|
|
rotateZ += 3;
|
|
if (keys_held & KEY_DOWN)
|
|
rotateZ -= 3;
|
|
if (keys_held & KEY_LEFT)
|
|
rotateY -= 3;
|
|
if (keys_held & KEY_RIGHT)
|
|
rotateY += 3;
|
|
|
|
printf("\x1b[11;0HCurrent frame: %.2f ", f32tofloat(frame));
|
|
|
|
if (keys_held & KEY_R)
|
|
{
|
|
frame += 1 << 9;
|
|
if (frame >= (num_frames << 12))
|
|
frame -= num_frames << 12;
|
|
}
|
|
if (keys_held & KEY_L)
|
|
{
|
|
frame -= 1 << 9;
|
|
if (frame < 0)
|
|
frame += num_frames << 12;
|
|
}
|
|
|
|
glFlush(0);
|
|
|
|
swiWaitForVBlank();
|
|
|
|
if (keys_held & KEY_START)
|
|
break;
|
|
}
|
|
|
|
return 0;
|
|
}
|