[Add] Vec2 now uses polor coords.
This commit is contained in:
parent
bf4b1fb02a
commit
a7546372cc
11
src/main.c
11
src/main.c
@ -121,6 +121,10 @@ int main(int argc, char** argv) {
|
||||
else if(strcmp(str, "keyboard")==0) type = KEYBIND_KEYBOARD;
|
||||
else if(strcmp(str, "jaxis")==0) type = KEYBIND_JAXIS;
|
||||
else if(strcmp(str, "jbutton")==0) type = KEYBIND_JBUTTON;
|
||||
else {
|
||||
WARN("Unknown keybinding of type %s", str);
|
||||
continue;
|
||||
}
|
||||
// Set the keybind.
|
||||
input_setKeybind((char*)keybindNames[i], type, key, reverse);
|
||||
} else WARN("Malformed keybind in %s", CONF_FILE);
|
||||
@ -239,9 +243,11 @@ static void update_all(void) {
|
||||
time = SDL_GetTicks();
|
||||
|
||||
if(dt > MINIMUM_FPS) {
|
||||
Vec2 pos = { .x = 10., .y = gl_screen.h-40 };
|
||||
Vec2 pos;
|
||||
vect_cinit(&pos, 10., (double)(gl_screen.h-40));
|
||||
gl_print(NULL, &pos, "FPS is really low! Skipping frames.");
|
||||
SDL_GL_SwapBuffers();
|
||||
return;
|
||||
}
|
||||
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
@ -266,7 +272,8 @@ static void display_fps(const double dt) {
|
||||
fps = fps_cur / fps_dt;
|
||||
fps_dt = fps_cur = 0.;
|
||||
}
|
||||
Vec2 pos = { .x = 10., .y = (double)(gl_screen.h-20) };
|
||||
Vec2 pos;
|
||||
vect_cinit(&pos, 10., (double)(gl_screen.h-20));
|
||||
gl_print(NULL, &pos, "%3.2f", fps);
|
||||
}
|
||||
|
||||
|
12
src/opengl.c
12
src/opengl.c
@ -233,8 +233,8 @@ void gl_freeTexture(gl_texture* texture) {
|
||||
// Blit the sprite at given position.
|
||||
void gl_blitSprite(const gl_texture* sprite, const Vec2* pos, const int sx, const int sy) {
|
||||
// Don't bother drawing if offscreen -- waste of cycles.
|
||||
if(fabs(pos->x - gl_camera->x) > gl_screen.w / 2 + sprite->sw / 2 ||
|
||||
fabs(pos->y-gl_camera->y) > gl_screen.h / 2 + sprite->sh / 2)
|
||||
if(fabs(VX(*pos) -VX(*gl_camera)) > gl_screen.w / 2 + sprite->sw / 2 ||
|
||||
fabs(VY(*pos) -VY(*gl_camera)) > gl_screen.h / 2 + sprite->sh / 2)
|
||||
return;
|
||||
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
@ -245,8 +245,8 @@ void gl_blitSprite(const gl_texture* sprite, const Vec2* pos, const int sx, cons
|
||||
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glPushMatrix(); // Projection translation matrix.
|
||||
glTranslated(pos->x - gl_camera->x - sprite->sw/2.,
|
||||
pos->y - gl_camera->y - sprite->sh/2., 0.);
|
||||
glTranslated(VX(*pos) -VX(*gl_camera) - sprite->sw/2.,
|
||||
VY(*pos) -VY(*gl_camera) - sprite->sh/2., 0.);
|
||||
glScalef((double)gl_screen.w/SCREEN_W, (double)gl_screen.h/SCREEN_H, 0.);
|
||||
|
||||
// Actual blitting....
|
||||
@ -276,7 +276,7 @@ void gl_blitStatic(const gl_texture* texture, const Vec2* pos) {
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glPushMatrix(); // Set up translation matrix.
|
||||
glTranslated(pos->x - (double)gl_screen.w/2., pos->y - (double)gl_screen.h/2., 0);
|
||||
glTranslated(VX(*pos) - (double)gl_screen.w/2., VY(*pos) - (double)gl_screen.h/2., 0);
|
||||
glScaled((double)gl_screen.w/SCREEN_W, (double)gl_screen.h/SCREEN_H, 0.);
|
||||
|
||||
// Actual blitting..
|
||||
@ -327,7 +327,7 @@ void gl_print(const gl_font* ft_font, const Vec2* pos, const char* fmt, ...) {
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
|
||||
glPushMatrix(); // Translation matrix.
|
||||
glTranslated(pos->x - (double)gl_screen.w/2., pos->y - (double)gl_screen.h/2., 0);
|
||||
glTranslated(VX(*pos) - (double)gl_screen.w/2., VY(*pos) - (double)gl_screen.h/2., 0);
|
||||
|
||||
glColor4d(1., 1., 1., 1.);
|
||||
glCallLists(strlen(text), GL_UNSIGNED_BYTE, &text);
|
||||
|
131
src/physics.c
131
src/physics.c
@ -8,9 +8,17 @@
|
||||
#define M_PI 3.14159265358979323846f
|
||||
#endif
|
||||
|
||||
// Pretty efficient, no need for sine table!!
|
||||
#define SIN(dir)(sinf(dir))
|
||||
#define COS(dir)(cosf(dir))
|
||||
// Init cartesian vector.
|
||||
void vect_cinit(Vec2* v, double x, double y) {
|
||||
v->mod = MOD(x,y);
|
||||
v->angle = ANGLE(x, y);
|
||||
}
|
||||
|
||||
// Init polarized vector
|
||||
void vect_pinit(Vec2* v, double mod, double angle) {
|
||||
v->mod = mod;
|
||||
v->angle = angle;
|
||||
}
|
||||
|
||||
// ==Update method.========================================
|
||||
// d^2 x(t) / d t^2 = a, a = constant (acceleration)
|
||||
@ -22,26 +30,38 @@
|
||||
// Since dt isn't actually differential this gives us an
|
||||
// error, so watch out with big values for dt.
|
||||
// ========================================================
|
||||
#if 0
|
||||
#if 0 // Simply commenting this out to avoid silly warnings.
|
||||
static void simple_update(Solid* obj, const double dt) {
|
||||
// Make sure angle doesn't flip.
|
||||
obj->dir += obj->dir_vel/360.0*dt;
|
||||
obj->dir += obj->dir_vel/360.*dt;
|
||||
if(obj->dir > 2*M_PI) obj->dir -= 2*M_PI;
|
||||
if(obj->dir < 0.0) obj->dir += 2*M_PI;
|
||||
if(obj->force) {
|
||||
Vec2 acc;
|
||||
acc.x = obj->force / obj->mass * COS(obj->dir);
|
||||
acc.y = obj->force / obj->mass * SIN(obj->dir);
|
||||
if(obj->dir < 0.) obj->dir += 2*M_PI;
|
||||
|
||||
obj->pos.x += acc.x * dt;
|
||||
obj->vel.y += acc.y * dt;
|
||||
double px, py, vx, vy;
|
||||
px = VX(obj->pos);
|
||||
py = VY(obj->pos);
|
||||
vx = VX(obj->vel);
|
||||
vy = VY(obj->vel);
|
||||
|
||||
obj->pos.x += obj->vel.x * dt + 0.5 * acc.x * dt*dt;
|
||||
obj->pos.y += obj->vel.y * dt + 0.5 * acc.y * dt*dt;
|
||||
if(obj->force.mod) { // Force applied on an object.
|
||||
double ax, ay;
|
||||
ax = VX(obj->force)/obj->mass;
|
||||
ay = VY(obj->force)/obj->mass;
|
||||
|
||||
vx += ax*dt;
|
||||
vy += ay*dt;
|
||||
|
||||
px += vx*dt + 0.5*ax * dt*dt;
|
||||
py += vy*dt + 0.5*ay * dt*dt;
|
||||
|
||||
obj->vel.mod = MOD(vx, vy);
|
||||
obj->vel.angle = ANGLE(vx, vy);
|
||||
} else {
|
||||
obj->pos.x += obj->vel.x * dt;
|
||||
obj->pos.y += obj->vel.y * dt;
|
||||
px += vx*dt;
|
||||
py += vy*dt;
|
||||
}
|
||||
obj->pos.mod = MOD(px, py);
|
||||
obj->pos.angle = ANGLE(px, py);
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -60,72 +80,79 @@ static void simple_update(Solid* obj, const double dt) {
|
||||
// x_{n+1} = x_n + h/6x'_n + 3*h*a, 4*a)
|
||||
// ========================================================
|
||||
|
||||
#define RK4_N 4
|
||||
#define RK4_MIN_H 0.01 // Minimal pass we want.
|
||||
static void rk4_update(Solid* obj, const double dt) {
|
||||
// Make sure angle doesn't flip.
|
||||
obj->dir += obj->dir_vel/360.0*dt;
|
||||
if(obj->dir > 2*M_PI) obj->dir -= 2*M_PI;
|
||||
if(obj->dir < 0.0) obj->dir += 2*M_PI;
|
||||
|
||||
double h = dt / RK4_N; // Step.
|
||||
int N = (dt > RK4_MIN_H) ? (int)(dt/RK4_MIN_H) : 1;
|
||||
double h = dt / (double)N; // Step.
|
||||
|
||||
if(obj->force) { // Force applied on object.
|
||||
double px, py, vx, vy;
|
||||
px = VX(obj->pos);
|
||||
py = VY(obj->pos);
|
||||
vx = VX(obj->vel);
|
||||
vy = VY(obj->vel);
|
||||
|
||||
if(obj->force.mod) { // Force applied on object.
|
||||
int i;
|
||||
Vec2 initial, tmp;
|
||||
double ix, iy, tx, ty; // Initial and temp cartesian vector values.
|
||||
|
||||
Vec2 acc;
|
||||
acc.x = obj->force / obj->mass * COS(obj->dir);
|
||||
acc.y = obj->force / obj->mass * SIN(obj->dir);
|
||||
|
||||
for(i = 0; i < RK4_N; i++) {
|
||||
double ax, ay;
|
||||
ax = VX(obj->force)/obj->mass;
|
||||
ay = VY(obj->force)/obj->mass;
|
||||
for(i = 0; i < N; i++) {
|
||||
// X component.
|
||||
tmp.x = initial.x = obj->vel.x;
|
||||
tmp.x += 2*initial.x + h*tmp.x;
|
||||
tmp.x += 2*initial.x + h*tmp.x;
|
||||
tmp.x += initial.x + h*tmp.x;
|
||||
tmp.x *= h/6;
|
||||
tx = ix = vx;
|
||||
tx += 2*ix + h*tx;
|
||||
tx += 2*ix + h*tx;
|
||||
tx += ix + h*tx;
|
||||
tx *= h/6;
|
||||
|
||||
obj->pos.x += tmp.x;
|
||||
obj->vel.x += acc.x*h;
|
||||
px += tx;
|
||||
vx += ax*h;
|
||||
|
||||
// Y component.
|
||||
tmp.y = initial.y = obj->vel.y;
|
||||
tmp.y += 2*(initial.y + h/2*tmp.y);
|
||||
tmp.y += 2*(initial.y + h/2*tmp.y);
|
||||
tmp.y += initial.y + h*tmp.y;
|
||||
tmp.y *= h/6;
|
||||
ty = iy = vy;
|
||||
ty += 2*(iy + h/2*ty);
|
||||
ty += 2*(iy + h/2*ty);
|
||||
ty += iy +h*ty;
|
||||
ty *= h/6;
|
||||
|
||||
obj->pos.y += tmp.y;
|
||||
obj->pos.y += acc.y*h;
|
||||
py += ty;
|
||||
vy += ay*h;
|
||||
}
|
||||
obj->vel.mod = MOD(vx, vy);
|
||||
obj->vel.angle = ANGLE(vx, vy);
|
||||
} else {
|
||||
obj->pos.x += dt*obj->vel.x;
|
||||
obj->pos.y += dt*obj->vel.y;
|
||||
px += dt*vx;
|
||||
py += dt*vy;
|
||||
}
|
||||
obj->pos.mod = MOD(px, py);
|
||||
obj->pos.angle = ANGLE(px, py);
|
||||
}
|
||||
|
||||
// Initialize a new solid.
|
||||
void solid_init(Solid* dest, const double mass, const Vec2* vel, const Vec2* pos) {
|
||||
dest->mass = mass;
|
||||
|
||||
dest->force = 0;
|
||||
dest->force.mod = 0;
|
||||
dest->dir = 0;
|
||||
|
||||
if(vel == NULL)
|
||||
dest->vel.x = dest->vel.y = 0.0;
|
||||
else {
|
||||
dest->vel.x = vel->x;
|
||||
dest->vel.y = vel->y;
|
||||
}
|
||||
vect_cinit(&dest->vel, 0., 0.);
|
||||
else
|
||||
vect_pinit(&dest->vel, vel->mod, vel->angle);
|
||||
|
||||
if(pos == NULL)
|
||||
dest->pos.x = dest->pos.y = 0.0;
|
||||
else {
|
||||
dest->pos.x = pos->x;
|
||||
dest->pos.y = pos->y;
|
||||
}
|
||||
vect_cinit(&dest->pos, 0., 0.);
|
||||
else
|
||||
vect_pinit(&dest->pos, pos->mod, pos->angle);
|
||||
|
||||
dest->update = rk4_update;
|
||||
//dest->update = simple_update;
|
||||
}
|
||||
|
||||
// Create a new solid.
|
||||
|
@ -1,20 +1,33 @@
|
||||
#pragma once
|
||||
#include "def.h"
|
||||
|
||||
#define VX(v) ((v).mod*cos((v).angle))
|
||||
#define VY(v) ((v).mod*sin((v).angle))
|
||||
#define VMOD(v) ((v).mod)
|
||||
#define VANGLE(v) ((v).angle)
|
||||
|
||||
#define MOD(x,y) (sqrt(x*x + y*y))
|
||||
#define ANGLE(x,y)((x==0.) ? 0. : ((x<0.)?atan(y/x)+M_PI:atan(y/x)))
|
||||
|
||||
// Base of 2D vectors.
|
||||
typedef struct {
|
||||
double x, y; // Basic 2D vector components.
|
||||
double mod, angle; // Basic 2D vector components.
|
||||
} Vec2;
|
||||
|
||||
// Vector manupulation.
|
||||
void vect_cinit(Vec2* v, double x, double y);
|
||||
void vect_pinit(Vec2* v, double mod, double angle);
|
||||
|
||||
// Describe any solid in 2D space.
|
||||
struct Solid {
|
||||
double mass, force, dir, dir_vel; // Properties.
|
||||
Vec2 vel, pos; // Position/velocity vectors.
|
||||
double mass, dir, dir_vel; // Properties.
|
||||
Vec2 vel, pos, force; // Position/velocity vectors.
|
||||
void(*update)(struct Solid*, const double); // Update method.
|
||||
};
|
||||
|
||||
typedef struct Solid Solid;
|
||||
|
||||
// Solid manipulation.
|
||||
void solid_init(Solid* dest, const double mass, const Vec2* vel, const Vec2* pos);
|
||||
Solid* solid_create(const double mass, const Vec2* vel, const Vec2* pos);
|
||||
void solid_free(Solid* src);
|
||||
|
@ -7,9 +7,6 @@
|
||||
#include "log.h"
|
||||
#include "pilot.h"
|
||||
|
||||
#define VMOD(v) (v.x*v.x + v.y*v.y)
|
||||
#define NMOD(n) (n*n)
|
||||
|
||||
// Stack of pilot id's to assure uniqueness.
|
||||
static unsigned int pilot_id = 0;
|
||||
|
||||
@ -57,8 +54,9 @@ static void pilot_update(Pilot* pilot, const double dt) {
|
||||
// Update the solid.
|
||||
pilot->solid->update(pilot->solid, dt);
|
||||
|
||||
if(VMOD(pilot->solid->vel) > NMOD(pilot->ship->speed)) {
|
||||
if(VMOD(pilot->solid->vel) > pilot->ship->speed) {
|
||||
// Should not go faster.
|
||||
VMOD(pilot->solid->vel) = pilot->ship->speed;
|
||||
}
|
||||
|
||||
pilot_render(pilot);
|
||||
|
@ -29,7 +29,8 @@ void player_think(Pilot* player, const double dt) {
|
||||
if(player_turn)
|
||||
player->solid->dir_vel -= player->ship->turn * player_turn;
|
||||
|
||||
player->solid->force = player->ship->thrust * player_acc;
|
||||
player->solid->force.angle = player->solid->dir;
|
||||
player->solid->force.mod = player->ship->thrust * player_acc;
|
||||
}
|
||||
|
||||
// Initialization/exit functions (does not assign keys).
|
||||
|
23
src/space.c
23
src/space.c
@ -1,3 +1,6 @@
|
||||
#include <malloc.h>
|
||||
#include <math.h>
|
||||
|
||||
#include "log.h"
|
||||
#include "physics.h"
|
||||
#include "opengl.h"
|
||||
@ -7,7 +10,7 @@
|
||||
|
||||
#define STAR_BUF 100 // Area to leave around screen.
|
||||
typedef struct {
|
||||
Vec2 pos;
|
||||
double x, y;
|
||||
double brightness;
|
||||
} Star;
|
||||
|
||||
@ -20,8 +23,8 @@ void space_init(void) {
|
||||
stars = malloc(sizeof(Star)*nstars);
|
||||
for(i = 0; i < nstars; i++) {
|
||||
stars[i].brightness = (double)RNG(50, 200)/256.;
|
||||
stars[i].pos.x = (double)RNG(-STAR_BUF, gl_screen.w + STAR_BUF);
|
||||
stars[i].pos.y = (double)RNG(-STAR_BUF, gl_screen.h + STAR_BUF);
|
||||
stars[i].x = (double)RNG(-STAR_BUF, gl_screen.w + STAR_BUF);
|
||||
stars[i].y = (double)RNG(-STAR_BUF, gl_screen.h + STAR_BUF);
|
||||
}
|
||||
}
|
||||
|
||||
@ -33,16 +36,16 @@ void space_render(double dt) {
|
||||
glBegin(GL_POINTS);
|
||||
for(i = 0; i < nstars; i++) {
|
||||
// Update the position.
|
||||
stars[i].pos.x -= player->solid->vel.x/(15.-10.*stars[i].brightness)*dt;
|
||||
stars[i].pos.y -= player->solid->vel.y/(15.-10.*stars[i].brightness)*dt;
|
||||
stars[i].x -= VX(player->solid->vel)/(15.-10.*stars[i].brightness)*dt;
|
||||
stars[i].y -= VY(player->solid->vel)/(15.-10.*stars[i].brightness)*dt;
|
||||
// Scroll those stars bitch!
|
||||
if(stars[i].pos.x > gl_screen.w + STAR_BUF) stars[i].pos.x = -STAR_BUF;
|
||||
else if(stars[i].pos.x < -STAR_BUF) stars[i].pos.x = gl_screen.w + STAR_BUF;
|
||||
if(stars[i].pos.y > gl_screen.h + STAR_BUF) stars[i].pos.y = -STAR_BUF;
|
||||
else if(stars[i].pos.y < -STAR_BUF) stars[i].pos.y = gl_screen.h + STAR_BUF;
|
||||
if(stars[i].x > gl_screen.w + STAR_BUF) stars[i].x = -STAR_BUF;
|
||||
else if(stars[i].x < -STAR_BUF) stars[i].x = gl_screen.w + STAR_BUF;
|
||||
if(stars[i].y > gl_screen.h + STAR_BUF) stars[i].y = -STAR_BUF;
|
||||
else if(stars[i].y < -STAR_BUF) stars[i].y = gl_screen.h + STAR_BUF;
|
||||
// Render.
|
||||
glColor4d(1., 1., 1., stars[i].brightness);
|
||||
glVertex2d(stars[i].pos.x, stars[i].pos.y);
|
||||
glVertex2d(stars[i].x, stars[i].y);
|
||||
}
|
||||
glEnd();
|
||||
glPopMatrix(); // Projection translation matrix.
|
||||
|
Loading…
Reference in New Issue
Block a user