Reformat to something more readable for me :3
Build libsm64 / Build libsm64 for linux (push) Failing after 27s
Build libsm64 / Build libsm64 for web (push) Failing after 31s
Build libsm64 / Build libsm64 for windows (push) Failing after 22s

This commit is contained in:
2026-05-24 11:31:35 -05:00
parent 4328104536
commit 0406c215d2
156 changed files with 31087 additions and 21344 deletions
+51 -47
View File
@@ -5,73 +5,77 @@
#include <unistd.h>
#include <sys/time.h>
extern "C" {
#include "../src/libsm64.h"
#include "context.h"
extern "C"
{
#include "../src/libsm64.h"
#include "context.h"
}
static SDL_AudioDeviceID dev;
pthread_t gSoundThread;
long long timeInMilliseconds(void)
{
struct timeval tv;
gettimeofday(&tv, NULL);
struct timeval tv;
gettimeofday(&tv, nullptr);
return(((long long)tv.tv_sec)*1000)+(tv.tv_usec/1000);
return (long long)tv.tv_sec * 1000 + tv.tv_usec / 1000;
}
void* audio_thread(void* keepAlive)
void *audio_thread(void *keepAlive)
{
// from https://github.com/ckosmic/libsm64/blob/audio/src/libsm64.c#L535-L555
// except keepAlive is a null pointer here, so don't use it
// from https://github.com/ckosmic/libsm64/blob/audio/src/libsm64.c#L535-L555
// except keepAlive is a null pointer here, so don't use it
pthread_setcancelstate(PTHREAD_CANCEL_ENABLE,NULL);
pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED,NULL);
pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, nullptr);
pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, nullptr);
long long currentTime = timeInMilliseconds();
long long targetTime = 0;
while(1)
{
//if(!*((bool*)keepAlive)) return NULL;
long long currentTime = timeInMilliseconds();
long long targetTime = 0;
while (1)
{
//if(!*((bool*)keepAlive)) return nullptr;
int16_t audioBuffer[544 * 2 * 2];
uint32_t numSamples = sm64_audio_tick(SDL_GetQueuedAudioSize(dev)/4, 1100, audioBuffer);
if (SDL_GetQueuedAudioSize(dev)/4 < 6000)
SDL_QueueAudio(dev, audioBuffer, numSamples * 2 * 4);
int16_t audioBuffer[544 * 2 * 2];
uint32_t numSamples = sm64_audio_tick(SDL_GetQueuedAudioSize(dev) / 4, 1100, audioBuffer);
if (SDL_GetQueuedAudioSize(dev) / 4 < 6000)
SDL_QueueAudio(dev, audioBuffer, numSamples * 2 * 4);
targetTime = currentTime + 33;
while (timeInMilliseconds() < targetTime)
{
usleep(100);
//if(!*((bool*)keepAlive)) return NULL;
}
currentTime = timeInMilliseconds();
}
targetTime = currentTime + 33;
while (timeInMilliseconds() < targetTime)
{
usleep(100);
//if(!*((bool*)keepAlive)) return nullptr;
}
currentTime = timeInMilliseconds();
}
}
void audio_init()
{
if (SDL_InitSubSystem(SDL_INIT_AUDIO) < 0) {
fprintf(stderr, "SDL_InitSubSystem(SDL_INIT_AUDIO) failed: %s\n", SDL_GetError());
return;
}
if (SDL_InitSubSystem(SDL_INIT_AUDIO) < 0)
{
fprintf(stderr, "SDL_InitSubSystem(SDL_INIT_AUDIO) failed: %s\n", SDL_GetError());
return;
}
SDL_AudioSpec want, have;
SDL_zero(want);
want.freq = 32000;
want.format = AUDIO_S16;
want.channels = 2;
want.samples = 512;
want.callback = NULL;
dev = SDL_OpenAudioDevice(NULL, 0, &want, &have, 0);
if (dev == 0) {
fprintf(stderr, "SDL_OpenAudio error: %s\n", SDL_GetError());
return;
}
SDL_PauseAudioDevice(dev, 0);
SDL_AudioSpec want, have;
SDL_zero(want);
want.freq = 32000;
want.format = AUDIO_S16;
want.channels = 2;
want.samples = 512;
want.callback = nullptr;
dev = SDL_OpenAudioDevice(nullptr, 0, &want, &have, 0);
if (dev == 0)
{
fprintf(stderr, "SDL_OpenAudio error: %s\n", SDL_GetError());
return;
}
SDL_PauseAudioDevice(dev, 0);
// it's best to run audio in a separate thread
pthread_create(&gSoundThread, NULL, audio_thread, NULL);
// it's best to run audio in a separate thread
pthread_create(&gSoundThread, nullptr, audio_thread, nullptr);
}
+101 -101
View File
@@ -12,150 +12,150 @@ typedef float vec3[3];
typedef float vec4[4];
typedef float mat4[4][4];
static void
glm_mat4_zero( mat4 m )
static void glm_mat4_zero(mat4 m)
{
memset( m, 0, sizeof(mat4) );
memset(m, 0, sizeof(mat4));
}
static void
glm_mat4_identity( mat4 m )
static void glm_mat4_identity(mat4 m)
{
glm_mat4_zero( m );
glm_mat4_zero(m);
m[0][0] = 1.0f;
m[1][1] = 1.0f;
m[2][2] = 1.0f;
m[3][3] = 1.0f;
}
static void
glm_vec4_scale(vec4 v, float s, vec4 dest) {
dest[0] = v[0] * s;
dest[1] = v[1] * s;
dest[2] = v[2] * s;
dest[3] = v[3] * s;
static void glm_vec4_scale(vec4 v, float s, vec4 dest)
{
dest[0] = v[0] * s;
dest[1] = v[1] * s;
dest[2] = v[2] * s;
dest[3] = v[3] * s;
}
static void
glm_vec4_add(vec4 a, vec4 b, vec4 dest) {
dest[0] = a[0] + b[0];
dest[1] = a[1] + b[1];
dest[2] = a[2] + b[2];
dest[3] = a[3] + b[3];
static void glm_vec4_add(vec4 a, vec4 b, vec4 dest)
{
dest[0] = a[0] + b[0];
dest[1] = a[1] + b[1];
dest[2] = a[2] + b[2];
dest[3] = a[3] + b[3];
}
static void
glm_vec3_scale(vec3 v, float s, vec3 dest) {
dest[0] = v[0] * s;
dest[1] = v[1] * s;
dest[2] = v[2] * s;
static void glm_vec3_scale(vec3 v, float s, vec3 dest)
{
dest[0] = v[0] * s;
dest[1] = v[1] * s;
dest[2] = v[2] * s;
}
static void
glm_vec3_sub(vec3 a, vec3 b, vec3 dest) {
dest[0] = a[0] - b[0];
dest[1] = a[1] - b[1];
dest[2] = a[2] - b[2];
static void glm_vec3_sub(vec3 a, vec3 b, vec3 dest)
{
dest[0] = a[0] - b[0];
dest[1] = a[1] - b[1];
dest[2] = a[2] - b[2];
}
static float
glm_vec3_dot(vec3 a, vec3 b) {
return a[0] * b[0] + a[1] * b[1] + a[2] * b[2];
static float glm_vec3_dot(vec3 a, vec3 b)
{
return a[0] * b[0] + a[1] * b[1] + a[2] * b[2];
}
static float
glm_vec3_norm2(vec3 v) {
return glm_vec3_dot(v, v);
static float glm_vec3_norm2(vec3 v)
{
return glm_vec3_dot(v, v);
}
static float
glm_vec3_norm(vec3 v) {
return sqrtf(glm_vec3_norm2(v));
static float glm_vec3_norm(vec3 v)
{
return sqrtf(glm_vec3_norm2(v));
}
static void
glm_vec3_normalize(vec3 v) {
float norm;
static void glm_vec3_normalize(vec3 v)
{
float norm;
norm = glm_vec3_norm(v);
norm = glm_vec3_norm(v);
if (norm == 0.0f) {
v[0] = v[1] = v[2] = 0.0f;
return;
}
if (norm == 0.0f)
{
v[0] = v[1] = v[2] = 0.0f;
return;
}
glm_vec3_scale(v, 1.0f / norm, v);
glm_vec3_scale(v, 1.0f / norm, v);
}
static void
glm_vec3_cross(vec3 a, vec3 b, vec3 dest) {
/* (u2.v3 - u3.v2, u3.v1 - u1.v3, u1.v2 - u2.v1) */
dest[0] = a[1] * b[2] - a[2] * b[1];
dest[1] = a[2] * b[0] - a[0] * b[2];
dest[2] = a[0] * b[1] - a[1] * b[0];
static void glm_vec3_cross(vec3 a, vec3 b, vec3 dest)
{
/* (u2.v3 - u3.v2, u3.v1 - u1.v3, u1.v2 - u2.v1) */
dest[0] = a[1] * b[2] - a[2] * b[1];
dest[1] = a[2] * b[0] - a[0] * b[2];
dest[2] = a[0] * b[1] - a[1] * b[0];
}
static void
glm_vec3_crossn(vec3 a, vec3 b, vec3 dest) {
glm_vec3_cross(a, b, dest);
glm_vec3_normalize(dest);
static void glm_vec3_crossn(vec3 a, vec3 b, vec3 dest)
{
glm_vec3_cross(a, b, dest);
glm_vec3_normalize(dest);
}
static void
glm_perspective(float fovy,
float aspect,
float nearVal,
float farVal,
mat4 dest) {
float f, fn;
static void glm_perspective(
float fovy,
float aspect,
float nearVal,
float farVal,
mat4 dest)
{
float f, fn;
glm_mat4_zero(dest);
glm_mat4_zero(dest);
f = 1.0f / tanf(fovy * 0.5f);
fn = 1.0f / (nearVal - farVal);
f = 1.0f / tanf(fovy * 0.5f);
fn = 1.0f / (nearVal - farVal);
dest[0][0] = f / aspect;
dest[1][1] = f;
dest[2][2] = (nearVal + farVal) * fn;
dest[2][3] =-1.0f;
dest[3][2] = 2.0f * nearVal * farVal * fn;
dest[0][0] = f / aspect;
dest[1][1] = f;
dest[2][2] = (nearVal + farVal) * fn;
dest[2][3] = -1.0f;
dest[3][2] = 2.0f * nearVal * farVal * fn;
}
static void
glm_translate(mat4 m, vec3 v) {
vec4 v1, v2, v3;
static void glm_translate(mat4 m, vec3 v)
{
vec4 v1, v2, v3;
glm_vec4_scale(m[0], v[0], v1);
glm_vec4_scale(m[1], v[1], v2);
glm_vec4_scale(m[2], v[2], v3);
glm_vec4_scale(m[0], v[0], v1);
glm_vec4_scale(m[1], v[1], v2);
glm_vec4_scale(m[2], v[2], v3);
glm_vec4_add(v1, m[3], m[3]);
glm_vec4_add(v2, m[3], m[3]);
glm_vec4_add(v3, m[3], m[3]);
glm_vec4_add(v1, m[3], m[3]);
glm_vec4_add(v2, m[3], m[3]);
glm_vec4_add(v3, m[3], m[3]);
}
static void
glm_lookat(vec3 eye, vec3 center, vec3 up, mat4 dest) {
vec3 f, u, s;
static void glm_lookat(vec3 eye, vec3 center, vec3 up, mat4 dest)
{
vec3 f, u, s;
glm_vec3_sub(center, eye, f);
glm_vec3_normalize(f);
glm_vec3_sub(center, eye, f);
glm_vec3_normalize(f);
glm_vec3_crossn(f, up, s);
glm_vec3_cross(s, f, u);
glm_vec3_crossn(f, up, s);
glm_vec3_cross(s, f, u);
dest[0][0] = s[0];
dest[0][1] = u[0];
dest[0][2] =-f[0];
dest[1][0] = s[1];
dest[1][1] = u[1];
dest[1][2] =-f[1];
dest[2][0] = s[2];
dest[2][1] = u[2];
dest[2][2] =-f[2];
dest[3][0] =-glm_vec3_dot(s, eye);
dest[3][1] =-glm_vec3_dot(u, eye);
dest[3][2] = glm_vec3_dot(f, eye);
dest[0][3] = dest[1][3] = dest[2][3] = 0.0f;
dest[3][3] = 1.0f;
dest[0][0] = s[0];
dest[0][1] = u[0];
dest[0][2] = -f[0];
dest[1][0] = s[1];
dest[1][1] = u[1];
dest[1][2] = -f[1];
dest[2][0] = s[2];
dest[2][1] = u[2];
dest[2][2] = -f[2];
dest[3][0] = -glm_vec3_dot(s, eye);
dest[3][1] = -glm_vec3_dot(u, eye);
dest[3][2] = glm_vec3_dot(f, eye);
dest[0][3] = dest[1][3] = dest[2][3] = 0.0f;
dest[3][3] = 1.0f;
}
+48 -49
View File
@@ -8,107 +8,106 @@ static SDL_GameController *s_controller;
int WINDOW_WIDTH;
int WINDOW_HEIGHT;
void context_init( const char *title, int width, int height, int major, int minor )
void context_init(const char *title, int width, int height, int major, int minor)
{
if( SDL_Init( SDL_INIT_VIDEO | SDL_INIT_JOYSTICK ) < 0 ) goto err;
if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_JOYSTICK) < 0) goto err;
int profile = (major < 3) ? SDL_GL_CONTEXT_PROFILE_COMPATIBILITY : SDL_GL_CONTEXT_PROFILE_CORE;
int profile = major < 3 ? SDL_GL_CONTEXT_PROFILE_COMPATIBILITY : SDL_GL_CONTEXT_PROFILE_CORE;
SDL_GL_SetAttribute( SDL_GL_CONTEXT_MAJOR_VERSION, major );
SDL_GL_SetAttribute( SDL_GL_CONTEXT_MINOR_VERSION, minor );
SDL_GL_SetAttribute( SDL_GL_CONTEXT_PROFILE_MASK, profile );
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, major);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, minor);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, profile);
WINDOW_WIDTH = width;
WINDOW_HEIGHT = height;
s_sdlWindow = SDL_CreateWindow(
s_sdlWindow = SDL_CreateWindow(
title,
SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED,
width, height,
SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE
);
if( !s_sdlWindow ) goto err;
if (!s_sdlWindow) goto err;
s_sdlGlContext = SDL_GL_CreateContext( s_sdlWindow );
SDL_GL_SetSwapInterval( 1 );
s_sdlGlContext = SDL_GL_CreateContext(s_sdlWindow);
SDL_GL_SetSwapInterval(1);
if( !s_sdlGlContext ) goto err;
if (!s_sdlGlContext) goto err;
#ifndef __APPLE__
glewExperimental = GL_TRUE;
const GLenum glewInitResult = glewInit();
if( glewInitResult != GLEW_OK ) goto err;
glewExperimental = GL_TRUE;
const GLenum glewInitResult = glewInit();
if (glewInitResult != GLEW_OK) goto err;
#endif
s_controller = NULL;
s_controller = nullptr;
for( int i = 0; i < SDL_NumJoysticks(); ++i )
for (int i = 0; i < SDL_NumJoysticks(); ++i)
{
if( ! SDL_IsGameController( i ) ) continue;
s_controller = SDL_GameControllerOpen( i );
printf( "Using game controller: %s", SDL_GameControllerName( s_controller ) );
if( s_controller ) break;
if (!SDL_IsGameController(i)) continue;
s_controller = SDL_GameControllerOpen(i);
printf("Using game controller: %s", SDL_GameControllerName(s_controller));
if (s_controller) break;
}
return;
err:
SDL_GL_DeleteContext( s_sdlGlContext );
SDL_DestroyWindow( s_sdlWindow );
err: SDL_GL_DeleteContext(s_sdlGlContext);
SDL_DestroyWindow(s_sdlWindow);
SDL_Quit();
}
SDL_GameController *context_get_controller( void )
SDL_GameController *context_get_controller(void)
{
return s_controller;
}
bool context_flip_frame_poll_events( void )
bool context_flip_frame_poll_events(void)
{
bool still_running = true;
SDL_GL_SwapWindow( s_sdlWindow );
SDL_GL_SwapWindow(s_sdlWindow);
SDL_Event event;
while( SDL_PollEvent( &event ) )
while (SDL_PollEvent(&event))
{
switch( event.type )
switch (event.type)
{
case SDL_QUIT:
still_running = false;
break;
case SDL_KEYDOWN:
if( event.key.keysym.sym == SDLK_ESCAPE )
case SDL_QUIT:
still_running = false;
break;
case SDL_WINDOWEVENT:
if( event.window.event == SDL_WINDOWEVENT_SIZE_CHANGED )
{
WINDOW_WIDTH = event.window.data1;
WINDOW_HEIGHT = event.window.data2;
glViewport( 0, 0, WINDOW_WIDTH, WINDOW_HEIGHT );
}
break;
case SDL_KEYDOWN:
if (event.key.keysym.sym == SDLK_ESCAPE)
still_running = false;
case SDL_WINDOWEVENT:
if (event.window.event == SDL_WINDOWEVENT_SIZE_CHANGED)
{
WINDOW_WIDTH = event.window.data1;
WINDOW_HEIGHT = event.window.data2;
glViewport(0, 0, WINDOW_WIDTH, WINDOW_HEIGHT);
}
break;
}
}
return still_running;
}
void context_terminate( void )
void context_terminate(void)
{
if( !s_sdlWindow )
if (!s_sdlWindow)
return;
if( s_controller )
SDL_GameControllerClose( s_controller );
if (s_controller)
SDL_GameControllerClose(s_controller);
SDL_GL_DeleteContext( s_sdlGlContext );
SDL_DestroyWindow( s_sdlWindow );
SDL_GL_DeleteContext(s_sdlGlContext);
SDL_DestroyWindow(s_sdlWindow);
SDL_Quit();
s_sdlWindow = NULL;
s_sdlWindow = nullptr;
}
+7 -4
View File
@@ -17,7 +17,10 @@
extern int WINDOW_WIDTH;
extern int WINDOW_HEIGHT;
extern void context_init( const char *title, int width, int height, int major, int minor );
extern bool context_flip_frame_poll_events( void );
extern SDL_GameController *context_get_controller( void );
extern void context_terminate( void );
extern void context_init(const char *title, int width, int height, int major, int minor);
extern bool context_flip_frame_poll_events(void);
extern SDL_GameController *context_get_controller(void);
extern void context_terminate(void);
+169 -162
View File
@@ -16,213 +16,220 @@ uint8_t *worldTextureRaw;
int worldTextureSize[2] = {256, 256};
float *worldUv;
static void load_collision_mesh( CollisionMesh *mesh )
static void load_collision_mesh(CollisionMesh *mesh)
{
mesh->num_vertices = 3 * surfaces_count;
mesh->position = malloc( sizeof( float ) * surfaces_count * 9 );
mesh->normal = malloc( sizeof( float ) * surfaces_count * 9 );
mesh->color = malloc( sizeof( float ) * surfaces_count * 9 );
worldUv = malloc(sizeof(float) * surfaces_count * 6);
mesh->index = malloc( sizeof( uint16_t ) * surfaces_count * 3 );
mesh->num_vertices = 3 * surfaces_count;
mesh->position = malloc(sizeof(float) * surfaces_count * 9);
mesh->normal = malloc(sizeof(float) * surfaces_count * 9);
mesh->color = malloc(sizeof(float) * surfaces_count * 9);
worldUv = malloc(sizeof(float) * surfaces_count * 6);
mesh->index = malloc(sizeof(uint16_t) * surfaces_count * 3);
for( size_t i = 0; i < surfaces_count; ++i )
{
const struct SM64Surface *surf = &surfaces[i];
for (size_t i = 0; i < surfaces_count; ++i)
{
const struct SM64Surface *surf = &surfaces[i];
float x1 = mesh->position[9*i+0] = surf->vertices[0][0];
float y1 = mesh->position[9*i+1] = surf->vertices[0][1];
float z1 = mesh->position[9*i+2] = surf->vertices[0][2];
float x2 = mesh->position[9*i+3] = surf->vertices[1][0];
float y2 = mesh->position[9*i+4] = surf->vertices[1][1];
float z2 = mesh->position[9*i+5] = surf->vertices[1][2];
float x3 = mesh->position[9*i+6] = surf->vertices[2][0];
float y3 = mesh->position[9*i+7] = surf->vertices[2][1];
float z3 = mesh->position[9*i+8] = surf->vertices[2][2];
float x1 = mesh->position[9 * i + 0] = surf->vertices[0][0];
float y1 = mesh->position[9 * i + 1] = surf->vertices[0][1];
float z1 = mesh->position[9 * i + 2] = surf->vertices[0][2];
float x2 = mesh->position[9 * i + 3] = surf->vertices[1][0];
float y2 = mesh->position[9 * i + 4] = surf->vertices[1][1];
float z2 = mesh->position[9 * i + 5] = surf->vertices[1][2];
float x3 = mesh->position[9 * i + 6] = surf->vertices[2][0];
float y3 = mesh->position[9 * i + 7] = surf->vertices[2][1];
float z3 = mesh->position[9 * i + 8] = surf->vertices[2][2];
float nx = (y2 - y1) * (z3 - z2) - (z2 - z1) * (y3 - y2);
float ny = (z2 - z1) * (x3 - x2) - (x2 - x1) * (z3 - z2);
float nz = (x2 - x1) * (y3 - y2) - (y2 - y1) * (x3 - x2);
float mag = sqrtf(nx * nx + ny * ny + nz * nz);
nx /= mag;
ny /= mag;
nz /= mag;
float nx = (y2 - y1) * (z3 - z2) - (z2 - z1) * (y3 - y2);
float ny = (z2 - z1) * (x3 - x2) - (x2 - x1) * (z3 - z2);
float nz = (x2 - x1) * (y3 - y2) - (y2 - y1) * (x3 - x2);
float mag = sqrtf(nx * nx + ny * ny + nz * nz);
nx /= mag;
ny /= mag;
nz /= mag;
mesh->normal[9*i+0] = nx;
mesh->normal[9*i+1] = ny;
mesh->normal[9*i+2] = nz;
mesh->normal[9*i+3] = nx;
mesh->normal[9*i+4] = ny;
mesh->normal[9*i+5] = nz;
mesh->normal[9*i+6] = nx;
mesh->normal[9*i+7] = ny;
mesh->normal[9*i+8] = nz;
mesh->normal[9 * i + 0] = nx;
mesh->normal[9 * i + 1] = ny;
mesh->normal[9 * i + 2] = nz;
mesh->normal[9 * i + 3] = nx;
mesh->normal[9 * i + 4] = ny;
mesh->normal[9 * i + 5] = nz;
mesh->normal[9 * i + 6] = nx;
mesh->normal[9 * i + 7] = ny;
mesh->normal[9 * i + 8] = nz;
for (int j=0; j<9; j++)
mesh->color[9*i+j] = (0.5 + 0.25 * 1) * (.5+.5*mesh->normal[9*i+j]);
for (int j = 0; j < 9; j++)
mesh->color[9 * i + j] = (0.5 + 0.25 * 1) * (.5 + .5 * mesh->normal[9 * i + j]);
mesh->index[3*i+0] = 3*i+0;
mesh->index[3*i+1] = 3*i+1;
mesh->index[3*i+2] = 3*i+2;
}
mesh->index[3 * i + 0] = 3 * i + 0;
mesh->index[3 * i + 1] = 3 * i + 1;
mesh->index[3 * i + 2] = 3 * i + 2;
}
for( size_t i = 0; i < surfaces_count/2; i++ )
{
worldUv[12*i+0] = 0.f;
worldUv[12*i+1] = 0.f;
worldUv[12*i+2] = 4.f;
worldUv[12*i+3] = 0.f;
worldUv[12*i+4] = 0.f;
worldUv[12*i+5] = 4.f;
for (size_t i = 0; i < surfaces_count / 2; i++)
{
worldUv[12 * i + 0] = 0.f;
worldUv[12 * i + 1] = 0.f;
worldUv[12 * i + 2] = 4.f;
worldUv[12 * i + 3] = 0.f;
worldUv[12 * i + 4] = 0.f;
worldUv[12 * i + 5] = 4.f;
worldUv[12*i+6] = 0.f;
worldUv[12*i+7] = 4.f;
worldUv[12*i+8] = 4.f;
worldUv[12*i+9] = 0.f;
worldUv[12*i+10] = 0.f;
worldUv[12*i+11] = 0.f;
}
worldUv[12 * i + 6] = 0.f;
worldUv[12 * i + 7] = 4.f;
worldUv[12 * i + 8] = 4.f;
worldUv[12 * i + 9] = 0.f;
worldUv[12 * i + 10] = 0.f;
worldUv[12 * i + 11] = 0.f;
}
}
static void load_mario_mesh( MarioMesh *mesh, struct SM64MarioGeometryBuffers *marioGeo )
static void load_mario_mesh(MarioMesh *mesh, struct SM64MarioGeometryBuffers *marioGeo)
{
mesh->index = malloc( 3 * SM64_GEO_MAX_TRIANGLES * sizeof(uint16_t) );
for( int i = 0; i < 3 * SM64_GEO_MAX_TRIANGLES; ++i )
mesh->index[i] = i;
mesh->index = malloc(3 * SM64_GEO_MAX_TRIANGLES * sizeof(uint16_t));
for (int i = 0; i < 3 * SM64_GEO_MAX_TRIANGLES; ++i)
mesh->index[i] = i;
mesh->num_vertices = 3 * SM64_GEO_MAX_TRIANGLES;
mesh->num_vertices = 3 * SM64_GEO_MAX_TRIANGLES;
}
static void update_mario_mesh( MarioMesh *mesh, struct SM64MarioGeometryBuffers *marioGeo )
static void update_mario_mesh(MarioMesh *mesh, struct SM64MarioGeometryBuffers *marioGeo)
{
if( mesh->index == NULL )
load_mario_mesh( mesh, marioGeo );
if (mesh->index == nullptr)
load_mario_mesh(mesh, marioGeo);
mesh->num_vertices = 3 * marioGeo->numTrianglesUsed;
mesh->num_vertices = 3 * marioGeo->numTrianglesUsed;
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_NORMAL_ARRAY);
glEnableClientState(GL_COLOR_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_NORMAL_ARRAY);
glEnableClientState(GL_COLOR_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glVertexPointer(3, GL_FLOAT, 0, marioGeo->position);
glNormalPointer(GL_FLOAT, 0, marioGeo->normal);
glColorPointer(3, GL_FLOAT, 0, marioGeo->color);
glTexCoordPointer(2, GL_FLOAT, 0, marioGeo->uv);
glVertexPointer(3, GL_FLOAT, 0, marioGeo->position);
glNormalPointer(GL_FLOAT, 0, marioGeo->normal);
glColorPointer(3, GL_FLOAT, 0, marioGeo->color);
glTexCoordPointer(2, GL_FLOAT, 0, marioGeo->uv);
}
static void gl20_init(RenderState *renderState, uint8_t *marioTexture)
{
load_collision_mesh( &renderState->collision );
load_collision_mesh(&renderState->collision);
glEnable( GL_CULL_FACE );
glCullFace( GL_BACK );
glClearColor( 0.2f, 0.2f, 0.2f, 1.0f );
glDepthMask( GL_TRUE );
glDepthFunc( GL_LEQUAL );
glEnable( GL_DEPTH_TEST );
glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
glEnable( GL_BLEND );
glColor4f(1,1,1,1);
glEnable(GL_CULL_FACE);
glCullFace(GL_BACK);
glClearColor(0.2f, 0.2f, 0.2f, 1.0f);
glDepthMask(GL_TRUE);
glDepthFunc(GL_LEQUAL);
glEnable(GL_DEPTH_TEST);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glEnable(GL_BLEND);
glColor4f(1, 1, 1, 1);
glGenTextures( 1, &renderState->mario_texture );
glBindTexture( GL_TEXTURE_2D, renderState->mario_texture );
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, SM64_TEXTURE_WIDTH, SM64_TEXTURE_HEIGHT, 0, GL_RGBA, GL_UNSIGNED_BYTE, marioTexture);
glGenTextures(1, &renderState->mario_texture);
glBindTexture(GL_TEXTURE_2D, renderState->mario_texture);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, SM64_TEXTURE_WIDTH, SM64_TEXTURE_HEIGHT, 0, GL_RGBA, GL_UNSIGNED_BYTE, marioTexture);
// make a custom world texture programatically
worldTextureRaw = (uint8_t*)malloc(worldTextureSize[0] * worldTextureSize[1] * 4);
memset(worldTextureRaw, 255, worldTextureSize[0] * worldTextureSize[1] * 4);
// make a custom world texture programatically
worldTextureRaw = (uint8_t *)malloc(worldTextureSize[0] * worldTextureSize[1] * 4);
memset(worldTextureRaw, 255, worldTextureSize[0] * worldTextureSize[1] * 4);
for (int y=0; y<worldTextureSize[1]/2; y++)
{
for (int x = worldTextureSize[1]/2 - (y+1); x<worldTextureSize[1]/2 + (y+1); x++)
{
int i1 = y * worldTextureSize[0] + x;
int i2 = (worldTextureSize[1]-1-y) * worldTextureSize[0] + x;
worldTextureRaw[i1*4+0] = 192;
worldTextureRaw[i1*4+1] = 192;
worldTextureRaw[i1*4+2] = 192;
worldTextureRaw[i2*4+0] = 192;
worldTextureRaw[i2*4+1] = 192;
worldTextureRaw[i2*4+2] = 192;
}
}
for (int y = 0; y < worldTextureSize[1] / 2; y++)
{
for (int x = worldTextureSize[1] / 2 - (y + 1); x < worldTextureSize[1] / 2 + (y + 1); x++)
{
int i1 = y * worldTextureSize[0] + x;
int i2 = (worldTextureSize[1] - 1 - y) * worldTextureSize[0] + x;
worldTextureRaw[i1 * 4 + 0] = 192;
worldTextureRaw[i1 * 4 + 1] = 192;
worldTextureRaw[i1 * 4 + 2] = 192;
worldTextureRaw[i2 * 4 + 0] = 192;
worldTextureRaw[i2 * 4 + 1] = 192;
worldTextureRaw[i2 * 4 + 2] = 192;
}
}
glGenTextures(1, &worldTexture );
glBindTexture(GL_TEXTURE_2D, worldTexture);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, worldTextureSize[0], worldTextureSize[1], 0, GL_RGBA, GL_UNSIGNED_BYTE, worldTextureRaw);
glGenTextures(1, &worldTexture);
glBindTexture(GL_TEXTURE_2D, worldTexture);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, worldTextureSize[0], worldTextureSize[1], 0, GL_RGBA, GL_UNSIGNED_BYTE, worldTextureRaw);
}
static void gl20_draw(RenderState *renderState, const vec3 camPos, const struct SM64MarioState *marioState, struct SM64MarioGeometryBuffers *marioGeo)
{
mat4 model, view, projection;
glm_perspective( 45.0f, (float)WINDOW_WIDTH / (float)WINDOW_HEIGHT, 100.0f, 20000.0f, projection );
glm_translate( view, (float*)camPos );
glm_lookat( (float*)camPos, (float*)marioState->position, (vec3){0,1,0}, view );
glm_mat4_identity( model );
mat4 model, view, projection;
glm_perspective(45.0f, (float)WINDOW_WIDTH / (float)WINDOW_HEIGHT, 100.0f, 20000.0f, projection);
glm_translate(view, (float *)camPos);
glm_lookat((float *)camPos, (float *)marioState->position, (vec3)
{
0, 1, 0
}
,
view
)
;
glm_mat4_identity(model);
glMatrixMode(GL_PROJECTION);
glLoadMatrixf((GLfloat*)projection);
glMatrixMode(GL_PROJECTION);
glLoadMatrixf((GLfloat *)projection);
glMatrixMode(GL_MODELVIEW);
glLoadMatrixf((GLfloat*)view);
glMatrixMode(GL_MODELVIEW);
glLoadMatrixf((GLfloat *)view);
glEnable(GL_TEXTURE_2D);
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
glEnable(GL_TEXTURE_2D);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// draw world
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_NORMAL_ARRAY);
glEnableClientState(GL_COLOR_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_NORMAL_ARRAY);
glEnableClientState(GL_COLOR_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glVertexPointer(3, GL_FLOAT, 0, renderState->collision.position);
glNormalPointer(GL_FLOAT, 0, renderState->collision.normal);
glColorPointer(3, GL_FLOAT, 0, renderState->collision.color);
glTexCoordPointer(2, GL_FLOAT, 0, worldUv);
glVertexPointer(3, GL_FLOAT, 0, renderState->collision.position);
glNormalPointer(GL_FLOAT, 0, renderState->collision.normal);
glColorPointer(3, GL_FLOAT, 0, renderState->collision.color);
glTexCoordPointer(2, GL_FLOAT, 0, worldUv);
glBindTexture(GL_TEXTURE_2D, worldTexture);
glMatrixMode(GL_TEXTURE);
glLoadIdentity();
glDrawElements(GL_TRIANGLES, renderState->collision.num_vertices, GL_UNSIGNED_SHORT, renderState->collision.index);
glBindTexture(GL_TEXTURE_2D, worldTexture);
glMatrixMode(GL_TEXTURE);
glLoadIdentity();
glDrawElements(GL_TRIANGLES, renderState->collision.num_vertices, GL_UNSIGNED_SHORT, renderState->collision.index);
// create lighting on the scene
GLfloat light_position[] = { camPos[0], camPos[1], camPos[2], 1 };
GLfloat light_diffuse[] = { 0.6f, 0.6f, 0.6f, 1 };
GLfloat light_model[] = { 0.5f, 0.5f, 0.5f, 1 };
glLightfv(GL_LIGHT0, GL_POSITION, light_position);
glLightfv(GL_LIGHT0, GL_DIFFUSE, light_diffuse);
glLightModelfv(GL_LIGHT_MODEL_AMBIENT, light_model);
glShadeModel(GL_SMOOTH);
glEnable(GL_COLOR_MATERIAL);
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
// create lighting on the scene
GLfloat light_position[] = {camPos[0], camPos[1], camPos[2], 1};
GLfloat light_diffuse[] = {0.6f, 0.6f, 0.6f, 1};
GLfloat light_model[] = {0.5f, 0.5f, 0.5f, 1};
glLightfv(GL_LIGHT0, GL_POSITION, light_position);
glLightfv(GL_LIGHT0, GL_DIFFUSE, light_diffuse);
glLightModelfv(GL_LIGHT_MODEL_AMBIENT, light_model);
glShadeModel(GL_SMOOTH);
glEnable(GL_COLOR_MATERIAL);
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
// first, draw geometry without Mario's texture.
glBindTexture(GL_TEXTURE_2D, 0);
update_mario_mesh( &renderState->mario, marioGeo );
uint32_t triangleSize = renderState->mario.num_vertices;
// first, draw geometry without Mario's texture.
glBindTexture(GL_TEXTURE_2D, 0);
update_mario_mesh(&renderState->mario, marioGeo);
uint32_t triangleSize = renderState->mario.num_vertices;
glDrawElements(GL_TRIANGLES, triangleSize, GL_UNSIGNED_SHORT, renderState->mario.index);
glDrawElements(GL_TRIANGLES, triangleSize, GL_UNSIGNED_SHORT, renderState->mario.index);
// now disable the color array and enable the texture.
glDisableClientState(GL_COLOR_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glBindTexture(GL_TEXTURE_2D, renderState->mario_texture);
glMatrixMode(GL_TEXTURE);
glLoadIdentity();
// now disable the color array and enable the texture.
glDisableClientState(GL_COLOR_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glBindTexture(GL_TEXTURE_2D, renderState->mario_texture);
glMatrixMode(GL_TEXTURE);
glLoadIdentity();
glDrawElements(GL_TRIANGLES, triangleSize, GL_UNSIGNED_SHORT, renderState->mario.index);
glDrawElements(GL_TRIANGLES, triangleSize, GL_UNSIGNED_SHORT, renderState->mario.index);
glDisable(GL_TEXTURE_2D);
glDisable(GL_LIGHTING);
glDisable(GL_TEXTURE_2D);
glDisable(GL_LIGHTING);
}
struct Renderer gl20_renderer = {
+238 -233
View File
@@ -9,302 +9,307 @@
#include "../level.h"
static const char *MARIO_SHADER =
"\n uniform mat4 view;"
"\n uniform mat4 projection;"
"\n uniform sampler2D marioTex;"
"\n "
"\n v2f vec3 v_color;"
"\n v2f vec3 v_normal;"
"\n v2f vec3 v_light;"
"\n v2f vec2 v_uv;"
"\n "
"\n #ifdef VERTEX"
"\n "
"\n layout(location = 0) in vec3 position;"
"\n layout(location = 1) in vec3 normal;"
"\n layout(location = 2) in vec3 color;"
"\n layout(location = 3) in vec2 uv;"
"\n "
"\n void main()"
"\n {"
"\n v_color = color;"
"\n v_normal = normal;"
"\n v_light = transpose( mat3( view )) * normalize( vec3( 1 ));"
"\n v_uv = uv;"
"\n "
"\n gl_Position = projection * view * vec4( position, 1. );"
"\n }"
"\n "
"\n #endif"
"\n #ifdef FRAGMENT"
"\n "
"\n out vec4 color;"
"\n "
"\n void main() "
"\n {"
"\n float light = .5 + .5 * clamp( dot( v_normal, v_light ), 0., 1. );"
"\n vec4 texColor = texture2D( marioTex, v_uv );"
"\n vec3 mainColor = mix( v_color, texColor.rgb, texColor.a ); // v_uv.x >= 0. ? texColor.a : 0. );"
"\n color = vec4( mainColor * light, 1 );"
"\n }"
"\n "
"\n #endif"
;
"\n uniform mat4 view;"
"\n uniform mat4 projection;"
"\n uniform sampler2D marioTex;"
"\n "
"\n v2f vec3 v_color;"
"\n v2f vec3 v_normal;"
"\n v2f vec3 v_light;"
"\n v2f vec2 v_uv;"
"\n "
"\n #ifdef VERTEX"
"\n "
"\n layout(location = 0) in vec3 position;"
"\n layout(location = 1) in vec3 normal;"
"\n layout(location = 2) in vec3 color;"
"\n layout(location = 3) in vec2 uv;"
"\n "
"\n void main()"
"\n {"
"\n v_color = color;"
"\n v_normal = normal;"
"\n v_light = transpose( mat3( view )) * normalize( vec3( 1 ));"
"\n v_uv = uv;"
"\n "
"\n gl_Position = projection * view * vec4( position, 1. );"
"\n }"
"\n "
"\n #endif"
"\n #ifdef FRAGMENT"
"\n "
"\n out vec4 color;"
"\n "
"\n void main() "
"\n {"
"\n float light = .5 + .5 * clamp( dot( v_normal, v_light ), 0., 1. );"
"\n vec4 texColor = texture2D( marioTex, v_uv );"
"\n vec3 mainColor = mix( v_color, texColor.rgb, texColor.a ); // v_uv.x >= 0. ? texColor.a : 0. );"
"\n color = vec4( mainColor * light, 1 );"
"\n }"
"\n "
"\n #endif";
static const char *WORLD_SHADER =
"\n uniform mat4 model;"
"\n uniform mat4 view;"
"\n uniform mat4 projection;"
"\n uniform sampler2D tex;"
"\n "
"\n v2f vec3 v_normal;"
"\n v2f vec3 v_worldPos;"
"\n "
"\n #ifdef VERTEX"
"\n "
"\n layout(location = 0) in vec3 position;"
"\n layout(location = 1) in vec3 normal;"
"\n "
"\n void main()"
"\n {"
"\n v_normal = inverse(mat3(model)) * normal;"
"\n vec4 worldPos4 = model * vec4(position, 1.);"
"\n v_worldPos = worldPos4.xyz;"
"\n gl_Position = projection * view * worldPos4;"
"\n }"
"\n "
"\n #endif"
"\n #ifdef FRAGMENT"
"\n "
"\n vec3 tri( vec3 x )"
"\n {"
"\n return abs(x-floor(x)-.5);"
"\n } "
"\n float surfFunc( vec3 p )"
"\n {"
"\n float n = dot(tri(p*.15 + tri(p.yzx*.075)), vec3(.444));"
"\n p = p*1.5773 - n;"
"\n p.yz = vec2(p.y + p.z, p.z - p.y) * .866;"
"\n p.xz = vec2(p.x + p.z, p.z - p.x) * .866;"
"\n n += dot(tri(p*.225 + tri(p.yzx*.1125)), vec3(.222)); "
"\n return abs(n-.5)*1.9 + (1.-abs(sin(n*9.)))*.05;"
"\n }"
"\n "
"\n const vec3 light_x = vec3(-1.0, 0.4, 0.9);"
"\n "
"\n out vec4 color;"
"\n "
"\n void main() "
"\n {"
"\n float surfy = surfFunc( v_worldPos / 50. );"
"\n float brightness = smoothstep( .2, .3, surfy );"
"\n "
"\n color = vec4( (0.5 + 0.25 * brightness) * (.5+.5*v_normal), 1 );"
"\n }"
"\n "
"\n #endif"
;
"\n uniform mat4 model;"
"\n uniform mat4 view;"
"\n uniform mat4 projection;"
"\n uniform sampler2D tex;"
"\n "
"\n v2f vec3 v_normal;"
"\n v2f vec3 v_worldPos;"
"\n "
"\n #ifdef VERTEX"
"\n "
"\n layout(location = 0) in vec3 position;"
"\n layout(location = 1) in vec3 normal;"
"\n "
"\n void main()"
"\n {"
"\n v_normal = inverse(mat3(model)) * normal;"
"\n vec4 worldPos4 = model * vec4(position, 1.);"
"\n v_worldPos = worldPos4.xyz;"
"\n gl_Position = projection * view * worldPos4;"
"\n }"
"\n "
"\n #endif"
"\n #ifdef FRAGMENT"
"\n "
"\n vec3 tri( vec3 x )"
"\n {"
"\n return abs(x-floor(x)-.5);"
"\n } "
"\n float surfFunc( vec3 p )"
"\n {"
"\n float n = dot(tri(p*.15 + tri(p.yzx*.075)), vec3(.444));"
"\n p = p*1.5773 - n;"
"\n p.yz = vec2(p.y + p.z, p.z - p.y) * .866;"
"\n p.xz = vec2(p.x + p.z, p.z - p.x) * .866;"
"\n n += dot(tri(p*.225 + tri(p.yzx*.1125)), vec3(.222)); "
"\n return abs(n-.5)*1.9 + (1.-abs(sin(n*9.)))*.05;"
"\n }"
"\n "
"\n const vec3 light_x = vec3(-1.0, 0.4, 0.9);"
"\n "
"\n out vec4 color;"
"\n "
"\n void main() "
"\n {"
"\n float surfy = surfFunc( v_worldPos / 50. );"
"\n float brightness = smoothstep( .2, .3, surfy );"
"\n "
"\n color = vec4( (0.5 + 0.25 * brightness) * (.5+.5*v_normal), 1 );"
"\n }"
"\n "
"\n #endif";
static void load_collision_mesh( CollisionMesh *mesh )
static void load_collision_mesh(CollisionMesh *mesh)
{
mesh->num_vertices = 3 * surfaces_count;
mesh->position = malloc( sizeof( float ) * surfaces_count * 9 );
mesh->normal = malloc( sizeof( float ) * surfaces_count * 9 );
mesh->index = malloc( sizeof( uint16_t ) * surfaces_count * 3 );
mesh->num_vertices = 3 * surfaces_count;
mesh->position = malloc(sizeof(float) * surfaces_count * 9);
mesh->normal = malloc(sizeof(float) * surfaces_count * 9);
mesh->index = malloc(sizeof(uint16_t) * surfaces_count * 3);
for( size_t i = 0; i < surfaces_count; ++i )
{
const struct SM64Surface *surf = &surfaces[i];
for (size_t i = 0; i < surfaces_count; ++i)
{
const struct SM64Surface *surf = &surfaces[i];
float x1 = mesh->position[9*i+0] = surf->vertices[0][0];
float y1 = mesh->position[9*i+1] = surf->vertices[0][1];
float z1 = mesh->position[9*i+2] = surf->vertices[0][2];
float x2 = mesh->position[9*i+3] = surf->vertices[1][0];
float y2 = mesh->position[9*i+4] = surf->vertices[1][1];
float z2 = mesh->position[9*i+5] = surf->vertices[1][2];
float x3 = mesh->position[9*i+6] = surf->vertices[2][0];
float y3 = mesh->position[9*i+7] = surf->vertices[2][1];
float z3 = mesh->position[9*i+8] = surf->vertices[2][2];
float x1 = mesh->position[9 * i + 0] = surf->vertices[0][0];
float y1 = mesh->position[9 * i + 1] = surf->vertices[0][1];
float z1 = mesh->position[9 * i + 2] = surf->vertices[0][2];
float x2 = mesh->position[9 * i + 3] = surf->vertices[1][0];
float y2 = mesh->position[9 * i + 4] = surf->vertices[1][1];
float z2 = mesh->position[9 * i + 5] = surf->vertices[1][2];
float x3 = mesh->position[9 * i + 6] = surf->vertices[2][0];
float y3 = mesh->position[9 * i + 7] = surf->vertices[2][1];
float z3 = mesh->position[9 * i + 8] = surf->vertices[2][2];
float nx = (y2 - y1) * (z3 - z2) - (z2 - z1) * (y3 - y2);
float ny = (z2 - z1) * (x3 - x2) - (x2 - x1) * (z3 - z2);
float nz = (x2 - x1) * (y3 - y2) - (y2 - y1) * (x3 - x2);
float mag = sqrtf(nx * nx + ny * ny + nz * nz);
nx /= mag;
ny /= mag;
nz /= mag;
float nx = (y2 - y1) * (z3 - z2) - (z2 - z1) * (y3 - y2);
float ny = (z2 - z1) * (x3 - x2) - (x2 - x1) * (z3 - z2);
float nz = (x2 - x1) * (y3 - y2) - (y2 - y1) * (x3 - x2);
float mag = sqrtf(nx * nx + ny * ny + nz * nz);
nx /= mag;
ny /= mag;
nz /= mag;
mesh->normal[9*i+0] = nx;
mesh->normal[9*i+1] = ny;
mesh->normal[9*i+2] = nz;
mesh->normal[9*i+3] = nx;
mesh->normal[9*i+4] = ny;
mesh->normal[9*i+5] = nz;
mesh->normal[9*i+6] = nx;
mesh->normal[9*i+7] = ny;
mesh->normal[9*i+8] = nz;
mesh->normal[9 * i + 0] = nx;
mesh->normal[9 * i + 1] = ny;
mesh->normal[9 * i + 2] = nz;
mesh->normal[9 * i + 3] = nx;
mesh->normal[9 * i + 4] = ny;
mesh->normal[9 * i + 5] = nz;
mesh->normal[9 * i + 6] = nx;
mesh->normal[9 * i + 7] = ny;
mesh->normal[9 * i + 8] = nz;
mesh->index[3*i+0] = 3*i+0;
mesh->index[3*i+1] = 3*i+1;
mesh->index[3*i+2] = 3*i+2;
}
mesh->index[3 * i + 0] = 3 * i + 0;
mesh->index[3 * i + 1] = 3 * i + 1;
mesh->index[3 * i + 2] = 3 * i + 2;
}
glGenVertexArrays( 1, &mesh->vao );
glBindVertexArray( mesh->vao );
glGenVertexArrays(1, &mesh->vao);
glBindVertexArray(mesh->vao);
#define X( loc, buff, arr, type ) do { \
#define X( loc, buff, arr, type ) do { \
glGenBuffers( 1, &buff ); \
glBindBuffer( GL_ARRAY_BUFFER, buff ); \
glBufferData( GL_ARRAY_BUFFER, mesh->num_vertices*sizeof( type ), arr, GL_STATIC_DRAW ); \
glEnableVertexAttribArray( loc ); \
glVertexAttribPointer( loc, sizeof( type ) / sizeof( float ), GL_FLOAT, GL_FALSE, sizeof( type ), NULL ); \
glVertexAttribPointer( loc, sizeof( type ) / sizeof( float ), GL_FLOAT, GL_FALSE, sizeof( type ), nullptr ); \
} while( 0 )
X( 0, mesh->position_buffer, mesh->position, vec3 );
X( 1, mesh->normal_buffer, mesh->normal, vec3 );
X(0, mesh->position_buffer, mesh->position, vec3);
X(1, mesh->normal_buffer, mesh->normal, vec3);
#undef X
#undef X
}
static void load_mario_mesh( MarioMesh *mesh, struct SM64MarioGeometryBuffers *marioGeo )
static void load_mario_mesh(MarioMesh *mesh, struct SM64MarioGeometryBuffers *marioGeo)
{
mesh->index = malloc( 3 * SM64_GEO_MAX_TRIANGLES * sizeof(uint16_t) );
for( int i = 0; i < 3 * SM64_GEO_MAX_TRIANGLES; ++i )
mesh->index[i] = i;
mesh->index = malloc(3 * SM64_GEO_MAX_TRIANGLES * sizeof(uint16_t));
for (int i = 0; i < 3 * SM64_GEO_MAX_TRIANGLES; ++i)
mesh->index[i] = i;
mesh->num_vertices = 3 * SM64_GEO_MAX_TRIANGLES;
mesh->num_vertices = 3 * SM64_GEO_MAX_TRIANGLES;
glGenVertexArrays( 1, &mesh->vao );
glBindVertexArray( mesh->vao );
glGenVertexArrays(1, &mesh->vao);
glBindVertexArray(mesh->vao);
#define X( loc, buff, arr, type ) do { \
#define X( loc, buff, arr, type ) do { \
glGenBuffers( 1, &buff ); \
glBindBuffer( GL_ARRAY_BUFFER, buff ); \
glBufferData( GL_ARRAY_BUFFER, sizeof( type ) * 3 * SM64_GEO_MAX_TRIANGLES, arr, GL_DYNAMIC_DRAW ); \
glEnableVertexAttribArray( loc ); \
glVertexAttribPointer( loc, sizeof( type ) / sizeof( float ), GL_FLOAT, GL_FALSE, sizeof( type ), NULL ); \
glVertexAttribPointer( loc, sizeof( type ) / sizeof( float ), GL_FLOAT, GL_FALSE, sizeof( type ), nullptr ); \
} while( 0 )
X( 0, mesh->position_buffer, marioGeo->position, vec3 );
X( 1, mesh->normal_buffer, marioGeo->normal, vec3 );
X( 2, mesh->color_buffer, marioGeo->color, vec3 );
X( 3, mesh->uv_buffer, marioGeo->uv, vec2 );
X(0, mesh->position_buffer, marioGeo->position, vec3);
X(1, mesh->normal_buffer, marioGeo->normal, vec3);
X(2, mesh->color_buffer, marioGeo->color, vec3);
X(3, mesh->uv_buffer, marioGeo->uv, vec2);
#undef X
#undef X
}
static void update_mario_mesh( MarioMesh *mesh, struct SM64MarioGeometryBuffers *marioGeo )
static void update_mario_mesh(MarioMesh *mesh, struct SM64MarioGeometryBuffers *marioGeo)
{
if( mesh->index == NULL )
load_mario_mesh( mesh, marioGeo );
if (mesh->index == nullptr)
load_mario_mesh(mesh, marioGeo);
mesh->num_vertices = 3 * marioGeo->numTrianglesUsed;
mesh->num_vertices = 3 * marioGeo->numTrianglesUsed;
glBindBuffer( GL_ARRAY_BUFFER, mesh->position_buffer );
glBufferData( GL_ARRAY_BUFFER, sizeof( vec3 ) * 3 * SM64_GEO_MAX_TRIANGLES, marioGeo->position, GL_DYNAMIC_DRAW );
glBindBuffer( GL_ARRAY_BUFFER, mesh->normal_buffer );
glBufferData( GL_ARRAY_BUFFER, sizeof( vec3 ) * 3 * SM64_GEO_MAX_TRIANGLES, marioGeo->normal, GL_DYNAMIC_DRAW );
glBindBuffer( GL_ARRAY_BUFFER, mesh->color_buffer );
glBufferData( GL_ARRAY_BUFFER, sizeof( vec3 ) * 3 * SM64_GEO_MAX_TRIANGLES, marioGeo->color, GL_DYNAMIC_DRAW );
glBindBuffer( GL_ARRAY_BUFFER, mesh->uv_buffer );
glBufferData( GL_ARRAY_BUFFER, sizeof( vec2 ) * 3 * SM64_GEO_MAX_TRIANGLES, marioGeo->uv, GL_DYNAMIC_DRAW );
glBindBuffer(GL_ARRAY_BUFFER, mesh->position_buffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(vec3) * 3 * SM64_GEO_MAX_TRIANGLES, marioGeo->position, GL_DYNAMIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, mesh->normal_buffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(vec3) * 3 * SM64_GEO_MAX_TRIANGLES, marioGeo->normal, GL_DYNAMIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, mesh->color_buffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(vec3) * 3 * SM64_GEO_MAX_TRIANGLES, marioGeo->color, GL_DYNAMIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, mesh->uv_buffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(vec2) * 3 * SM64_GEO_MAX_TRIANGLES, marioGeo->uv, GL_DYNAMIC_DRAW);
}
static GLuint shader_compile( const char *shaderContents, size_t shaderContentsLength, GLenum shaderType )
static GLuint shader_compile(const char *shaderContents, size_t shaderContentsLength, GLenum shaderType)
{
const GLchar *shaderDefine = shaderType == GL_VERTEX_SHADER
? "\n#version 330\n#define VERTEX \n#define v2f out\n"
: "\n#version 330\n#define FRAGMENT\n#define v2f in \n";
const GLchar *shaderDefine = shaderType == GL_VERTEX_SHADER
? "\n#version 330\n#define VERTEX \n#define v2f out\n"
: "\n#version 330\n#define FRAGMENT\n#define v2f in \n";
const GLchar *shaderStrings[2] = { shaderDefine, shaderContents };
GLint shaderStringLengths[2] = { strlen( shaderDefine ), (GLint)shaderContentsLength };
const GLchar *shaderStrings[2] = {shaderDefine, shaderContents};
GLint shaderStringLengths[2] = {strlen(shaderDefine), (GLint)shaderContentsLength};
GLuint shader = glCreateShader( shaderType );
glShaderSource( shader, 2, shaderStrings, shaderStringLengths );
glCompileShader( shader );
GLuint shader = glCreateShader(shaderType);
glShaderSource(shader, 2, shaderStrings, shaderStringLengths);
glCompileShader(shader);
GLint isCompiled;
glGetShaderiv( shader, GL_COMPILE_STATUS, &isCompiled );
if( isCompiled == GL_FALSE )
{
GLint maxLength;
glGetShaderiv( shader, GL_INFO_LOG_LENGTH, &maxLength );
char *log = (char*)malloc( maxLength );
glGetShaderInfoLog( shader, maxLength, &maxLength, log );
GLint isCompiled;
glGetShaderiv(shader, GL_COMPILE_STATUS, &isCompiled);
if (isCompiled == GL_FALSE)
{
GLint maxLength;
glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &maxLength);
char *log = malloc(maxLength);
glGetShaderInfoLog(shader, maxLength, &maxLength, log);
printf( "Error in shader: %s\n%s\n%s\n", log, shaderStrings[0], shaderStrings[1] );
exit( 1 );
}
printf("Error in shader: %s\n%s\n%s\n", log, shaderStrings[0], shaderStrings[1]);
exit(1);
}
return shader;
return shader;
}
static GLuint shader_load( const char *shaderContents )
static GLuint shader_load(const char *shaderContents)
{
GLuint result;
GLuint vert = shader_compile( shaderContents, strlen( shaderContents ), GL_VERTEX_SHADER );
GLuint frag = shader_compile( shaderContents, strlen( shaderContents ), GL_FRAGMENT_SHADER );
GLuint result;
GLuint vert = shader_compile(shaderContents, strlen(shaderContents), GL_VERTEX_SHADER);
GLuint frag = shader_compile(shaderContents, strlen(shaderContents), GL_FRAGMENT_SHADER);
GLuint ref = glCreateProgram();
glAttachShader( ref, vert );
glAttachShader( ref, frag );
GLuint ref = glCreateProgram();
glAttachShader(ref, vert);
glAttachShader(ref, frag);
glLinkProgram ( ref );
glDetachShader( ref, vert );
glDetachShader( ref, frag );
result = ref;
glLinkProgram(ref);
glDetachShader(ref, vert);
glDetachShader(ref, frag);
result = ref;
return result;
return result;
}
static void gl33core_init(RenderState *renderState, uint8_t *marioTexture)
{
load_collision_mesh( &renderState->collision );
renderState->world_shader = shader_load( WORLD_SHADER );
renderState->mario_shader = shader_load( MARIO_SHADER );
load_collision_mesh(&renderState->collision);
renderState->world_shader = shader_load(WORLD_SHADER);
renderState->mario_shader = shader_load(MARIO_SHADER);
glEnable( GL_CULL_FACE );
glCullFace( GL_BACK );
glClearColor( 0.2f, 0.2f, 0.2f, 1.0f );
glDepthMask( GL_TRUE );
glDepthFunc( GL_LEQUAL );
glEnable( GL_DEPTH_TEST );
glEnable(GL_CULL_FACE);
glCullFace(GL_BACK);
glClearColor(0.2f, 0.2f, 0.2f, 1.0f);
glDepthMask(GL_TRUE);
glDepthFunc(GL_LEQUAL);
glEnable(GL_DEPTH_TEST);
glGenTextures( 1, &renderState->mario_texture );
glBindTexture( GL_TEXTURE_2D, renderState->mario_texture );
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, SM64_TEXTURE_WIDTH, SM64_TEXTURE_HEIGHT, 0, GL_RGBA, GL_UNSIGNED_BYTE, marioTexture);
glGenTextures(1, &renderState->mario_texture);
glBindTexture(GL_TEXTURE_2D, renderState->mario_texture);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, SM64_TEXTURE_WIDTH, SM64_TEXTURE_HEIGHT, 0, GL_RGBA, GL_UNSIGNED_BYTE, marioTexture);
}
static void gl33core_draw(RenderState *renderState, const vec3 camPos, const struct SM64MarioState *marioState, struct SM64MarioGeometryBuffers *marioGeo)
{
update_mario_mesh( &renderState->mario, marioGeo );
update_mario_mesh(&renderState->mario, marioGeo);
mat4 model, view, projection;
glm_perspective( 45.0f, (float)WINDOW_WIDTH / (float)WINDOW_HEIGHT, 100.0f, 20000.0f, projection );
glm_translate( view, (float*)camPos );
glm_lookat( (float*)camPos, (float*)marioState->position, (vec3){0,1,0}, view );
glm_mat4_identity( model );
mat4 model, view, projection;
glm_perspective(45.0f, (float)WINDOW_WIDTH / (float)WINDOW_HEIGHT, 100.0f, 20000.0f, projection);
glm_translate(view, (float *)camPos);
glm_lookat((float *)camPos, (float *)marioState->position, (vec3)
{
0, 1, 0
}
,
view
)
;
glm_mat4_identity(model);
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glUseProgram( renderState->world_shader );
glBindVertexArray( renderState->collision.vao );
glUniformMatrix4fv( glGetUniformLocation( renderState->world_shader, "model" ), 1, GL_FALSE, (GLfloat*)model );
glUniformMatrix4fv( glGetUniformLocation( renderState->world_shader, "view" ), 1, GL_FALSE, (GLfloat*)view );
glUniformMatrix4fv( glGetUniformLocation( renderState->world_shader, "projection" ), 1, GL_FALSE, (GLfloat*)projection );
glDrawElements( GL_TRIANGLES, renderState->collision.num_vertices, GL_UNSIGNED_SHORT, renderState->collision.index );
glUseProgram(renderState->world_shader);
glBindVertexArray(renderState->collision.vao);
glUniformMatrix4fv(glGetUniformLocation(renderState->world_shader, "model"), 1, GL_FALSE, (GLfloat *)model);
glUniformMatrix4fv(glGetUniformLocation(renderState->world_shader, "view"), 1, GL_FALSE, (GLfloat *)view);
glUniformMatrix4fv(glGetUniformLocation(renderState->world_shader, "projection"), 1, GL_FALSE, (GLfloat *)projection);
glDrawElements(GL_TRIANGLES, renderState->collision.num_vertices, GL_UNSIGNED_SHORT, renderState->collision.index);
glUseProgram( renderState->mario_shader );
glActiveTexture( GL_TEXTURE0 );
glBindTexture( GL_TEXTURE_2D, renderState->mario_texture );
glBindVertexArray( renderState->mario.vao );
glUniformMatrix4fv( glGetUniformLocation( renderState->mario_shader, "view" ), 1, GL_FALSE, (GLfloat*)view );
glUniformMatrix4fv( glGetUniformLocation( renderState->mario_shader, "projection" ), 1, GL_FALSE, (GLfloat*)projection );
glUniform1i( glGetUniformLocation( renderState->mario_shader, "marioTex" ), 0 );
glDrawElements( GL_TRIANGLES, renderState->mario.num_vertices, GL_UNSIGNED_SHORT, renderState->mario.index );
glUseProgram(renderState->mario_shader);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, renderState->mario_texture);
glBindVertexArray(renderState->mario.vao);
glUniformMatrix4fv(glGetUniformLocation(renderState->mario_shader, "view"), 1, GL_FALSE, (GLfloat *)view);
glUniformMatrix4fv(glGetUniformLocation(renderState->mario_shader, "projection"), 1, GL_FALSE, (GLfloat *)projection);
glUniform1i(glGetUniformLocation(renderState->mario_shader, "marioTex"), 0);
glDrawElements(GL_TRIANGLES, renderState->mario.num_vertices, GL_UNSIGNED_SHORT, renderState->mario.index);
}
struct Renderer gl33core_renderer = {
+57 -55
View File
@@ -11,41 +11,42 @@
#include "../src/libsm64.h"
extern "C" {
#define SDL_MAIN_HANDLED
#include "level.h"
#include "context.h"
#include "renderer.h"
#include "gl33core/gl33core_renderer.h"
#include "gl20/gl20_renderer.h"
extern "C"
{
#define SDL_MAIN_HANDLED
#include "level.h"
#include "context.h"
#include "renderer.h"
#include "gl33core/gl33core_renderer.h"
#include "gl20/gl20_renderer.h"
}
#include "audio.h"
uint8_t *utils_read_file_alloc( const char *path, size_t *fileLength )
uint8_t *utils_read_file_alloc(const char *path, size_t *fileLength)
{
FILE *f = fopen( path, "rb" );
FILE *f = fopen(path, "rb");
if( !f ) return NULL;
if (!f) return nullptr;
fseek( f, 0, SEEK_END );
size_t length = (size_t)ftell( f );
rewind( f );
uint8_t *buffer = (uint8_t*)malloc( length + 1 );
fread( buffer, 1, length, f );
fseek(f, 0, SEEK_END);
size_t length = (size_t)ftell(f);
rewind(f);
uint8_t *buffer = (uint8_t *)malloc(length + 1);
fread(buffer, 1, length, f);
buffer[length] = 0;
fclose( f );
fclose(f);
if( fileLength ) *fileLength = length;
if (fileLength) *fileLength = length;
return buffer;
}
static float read_axis( int16_t val )
static float read_axis(int16_t val)
{
float result = (float)val / 32767.0f;
if( result < 0.2f && result > -0.2f )
if (result < 0.2f && result > -0.2f)
return 0.0f;
return result > 0.0f ? (result - 0.2f) / 0.8f : (result + 0.2f) / 0.8f;
@@ -67,50 +68,51 @@ static void DebugPrint(const char *message)
fflush(stdout);
}
int main( void )
int main(void)
{
size_t romSize;
uint8_t *rom = utils_read_file_alloc( "baserom.us.z64", &romSize );
uint8_t *rom = utils_read_file_alloc("baserom.us.z64", &romSize);
if( rom == NULL )
if (rom == nullptr)
{
printf("\nFailed to read ROM file \"baserom.us.z64\"\n\n");
return 1;
}
uint8_t *texture = (uint8_t*)malloc( 4 * SM64_TEXTURE_WIDTH * SM64_TEXTURE_HEIGHT );
uint8_t *texture = (uint8_t *)malloc(4 * SM64_TEXTURE_WIDTH * SM64_TEXTURE_HEIGHT);
sm64_global_terminate();
sm64_global_init( rom, texture );
sm64_global_init(rom, texture);
sm64_audio_init(rom);
// sm64_register_debug_print_function(DebugPrint);
sm64_static_surfaces_load( surfaces, surfaces_count );
int32_t marioId = sm64_mario_create( 0, 1000, 0 );
sm64_static_surfaces_load(surfaces, surfaces_count);
int32_t marioId = sm64_mario_create(0, 1000, 0);
printf("MarioID: %i\n", marioId);
free( rom );
free(rom);
RenderState renderState;
renderState.mario.index = NULL;
vec3 cameraPos = { 0, 0, 0 };
renderState.mario.index = nullptr;
vec3 cameraPos = {0, 0, 0};
float cameraRot = 0.0f;
struct Renderer *renderer;
int major, minor;
#ifdef GL33_CORE
#ifdef GL33_CORE
major = 3; minor = 3;
renderer = &gl33core_renderer;
#else
major = 2; minor = 0;
#else
major = 2;
minor = 0;
renderer = &gl20_renderer;
#endif
#endif
context_init( "libsm64", 1280, 720, major, minor );
renderer->init( &renderState, texture );
context_init("libsm64", 1280, 720, major, minor);
renderer->init(&renderState, texture);
struct SM64MarioInputs marioInputs;
struct SM64MarioState marioState;
@@ -120,10 +122,10 @@ int main( void )
float lastPos[3], currPos[3];
float lastGeoPos[9 * SM64_GEO_MAX_TRIANGLES], currGeoPos[9 * SM64_GEO_MAX_TRIANGLES];
marioGeometry.position = (float*)malloc( sizeof(float) * 9 * SM64_GEO_MAX_TRIANGLES );
marioGeometry.color = (float*)malloc( sizeof(float) * 9 * SM64_GEO_MAX_TRIANGLES );
marioGeometry.normal = (float*)malloc( sizeof(float) * 9 * SM64_GEO_MAX_TRIANGLES );
marioGeometry.uv = (float*)malloc( sizeof(float) * 6 * SM64_GEO_MAX_TRIANGLES );
marioGeometry.position = (float *)malloc(sizeof(float) * 9 * SM64_GEO_MAX_TRIANGLES);
marioGeometry.color = (float *)malloc(sizeof(float) * 9 * SM64_GEO_MAX_TRIANGLES);
marioGeometry.normal = (float *)malloc(sizeof(float) * 9 * SM64_GEO_MAX_TRIANGLES);
marioGeometry.uv = (float *)malloc(sizeof(float) * 6 * SM64_GEO_MAX_TRIANGLES);
marioGeometry.numTrianglesUsed = 0;
float tick = 0;
@@ -144,7 +146,7 @@ int main( void )
if (!controller) // keyboard
{
const Uint8* state = SDL_GetKeyboardState(NULL);
const Uint8 *state = SDL_GetKeyboardState(nullptr);
float dir;
float spd = 0;
@@ -199,43 +201,43 @@ int main( void )
}
else
{
x_axis = read_axis( SDL_GameControllerGetAxis( controller, SDL_CONTROLLER_AXIS_LEFTX ));
y_axis = read_axis( SDL_GameControllerGetAxis( controller, SDL_CONTROLLER_AXIS_LEFTY ));
x0_axis = read_axis( SDL_GameControllerGetAxis( controller, SDL_CONTROLLER_AXIS_RIGHTX ));
x_axis = read_axis(SDL_GameControllerGetAxis(controller, SDL_CONTROLLER_AXIS_LEFTX));
y_axis = read_axis(SDL_GameControllerGetAxis(controller, SDL_CONTROLLER_AXIS_LEFTY));
x0_axis = read_axis(SDL_GameControllerGetAxis(controller, SDL_CONTROLLER_AXIS_RIGHTX));
marioInputs.buttonA = SDL_GameControllerGetButton( controller, SDL_CONTROLLER_BUTTON_A );
marioInputs.buttonB = SDL_GameControllerGetButton( controller, SDL_CONTROLLER_BUTTON_X );
marioInputs.buttonZ = SDL_GameControllerGetButton( controller, SDL_CONTROLLER_BUTTON_LEFTSHOULDER );
marioInputs.buttonA = SDL_GameControllerGetButton(controller, SDL_CONTROLLER_BUTTON_A);
marioInputs.buttonB = SDL_GameControllerGetButton(controller, SDL_CONTROLLER_BUTTON_X);
marioInputs.buttonZ = SDL_GameControllerGetButton(controller, SDL_CONTROLLER_BUTTON_LEFTSHOULDER);
}
cameraRot += x0_axis * dt * 2;
cameraPos[0] = marioState.position[0] + 1000.0f * cosf( cameraRot );
cameraPos[0] = marioState.position[0] + 1000.0f * cosf(cameraRot);
cameraPos[1] = marioState.position[1] + 200.0f;
cameraPos[2] = marioState.position[2] + 1000.0f * sinf( cameraRot );
cameraPos[2] = marioState.position[2] + 1000.0f * sinf(cameraRot);
marioInputs.camLookX = marioState.position[0] - cameraPos[0];
marioInputs.camLookZ = marioState.position[2] - cameraPos[2];
marioInputs.stickX = x_axis;
marioInputs.stickY = y_axis;
while (tick >= 1.f/30)
while (tick >= 1.f / 30)
{
memcpy(lastPos, currPos, sizeof(currPos));
memcpy(lastGeoPos, currGeoPos, sizeof(currGeoPos));
tick -= 1.f/30;
sm64_mario_tick( marioId, &marioInputs, &marioState, &marioGeometry );
tick -= 1.f / 30;
sm64_mario_tick(marioId, &marioInputs, &marioState, &marioGeometry);
memcpy(currPos, marioState.position, sizeof(currPos));
memcpy(currGeoPos, marioGeometry.position, sizeof(currGeoPos));
}
for (int i=0; i<3; i++) marioState.position[i] = lerp(lastPos[i], currPos[i], tick / (1.f/30));
for (int i=0; i<marioGeometry.numTrianglesUsed*9; i++) marioGeometry.position[i] = lerp(lastGeoPos[i], currGeoPos[i], tick / (1.f/30));
for (int i = 0; i < 3; i++) marioState.position[i] = lerp(lastPos[i], currPos[i], tick / (1.f / 30));
for (int i = 0; i < marioGeometry.numTrianglesUsed * 9; i++) marioGeometry.position[i] = lerp(lastGeoPos[i], currGeoPos[i], tick / (1.f / 30));
renderer->draw( &renderState, cameraPos, &marioState, &marioGeometry );
renderer->draw(&renderState, cameraPos, &marioState, &marioGeometry);
}
while( context_flip_frame_poll_events() );
while (context_flip_frame_poll_events());
sm64_stop_background_music(sm64_get_current_background_music());
sm64_global_terminate();
+20 -16
View File
@@ -23,38 +23,42 @@
# define WIN32_LEAN_AND_MEAN
# include <windows.h>
#endif
static uint64_t ns_clock() {
static uint64_t is_init = 0;
#if defined(__APPLE__)
static uint64_t ns_clock()
{
static uint64_t is_init = 0;
#if defined(__APPLE__)
static mach_timebase_info_data_t info;
if (0 == is_init) {
mach_timebase_info(&info);
is_init = 1;
if (0 == is_init)
{
mach_timebase_info(&info);
is_init = 1;
}
uint64_t now;
now = mach_absolute_time();
now *= info.numer;
now /= info.denom;
return now;
#elif defined(__linux)
#elif defined(__linux)
static struct timespec linux_rate;
if (0 == is_init) {
clock_getres(CLOCKID, &linux_rate);
is_init = 1;
if (0 == is_init)
{
clock_getres(CLOCKID, &linux_rate);
is_init = 1;
}
uint64_t now;
struct timespec spec;
clock_gettime(CLOCKID, &spec);
now = spec.tv_sec * 1.0e9 + spec.tv_nsec;
return now;
#elif defined(_WIN32)
#elif defined(_WIN32)
static LARGE_INTEGER win_frequency;
if (0 == is_init) {
QueryPerformanceFrequency(&win_frequency);
is_init = 1;
if (0 == is_init)
{
QueryPerformanceFrequency(&win_frequency);
is_init = 1;
}
LARGE_INTEGER now;
QueryPerformanceCounter(&now);
return (uint64_t) ((1e9 * now.QuadPart) / win_frequency.QuadPart);
#endif
return (uint64_t)((1e9 * now.QuadPart) / win_frequency.QuadPart);
#endif
}
+8 -6
View File
@@ -6,12 +6,13 @@
#include <stddef.h>
#ifdef __cplusplus
extern "C" {
#endif
extern "C"
{
#endif
#include "../src/libsm64.h"
#include "../src/libsm64.h"
#ifdef __cplusplus
#ifdef __cplusplus
}
#endif
@@ -58,8 +59,9 @@ RenderState;
struct Renderer
{
void (*init)(RenderState *renderState, uint8_t *marioTexture);
void (*draw)(RenderState *renderState, const vec3 camPos, const struct SM64MarioState *marioState, struct SM64MarioGeometryBuffers *marioGeo);
void (*init)(RenderState *renderState, uint8_t *marioTexture);
void (*draw)(RenderState *renderState, const vec3 camPos, const struct SM64MarioState *marioState, struct SM64MarioGeometryBuffers *marioGeo);
};
#endif