133 lines
3.2 KiB
C++
133 lines
3.2 KiB
C++
/* The world is a drop chute, arranged horizontally. The coordinate system is
|
|
right-handed, with the following orientation from the top view of the chute:
|
|
|
|
z
|
|
^
|
|
|
|
|
|
|
|
y (x)-----> x
|
|
|
|
The player primarily moves in the +y direction (... although in practice
|
|
objects move towards the player to better use the limited range of fixed-
|
|
point values).
|
|
|
|
We compute directions of rays based on points on the virtual screen placed
|
|
in the world, in front of the camera. We make rays start at the camera
|
|
position so the distance between the camera and screen does not matter; we
|
|
arbitrarily place the screen at a distance which makes the screen height
|
|
correspond to 2*HALF_SCREEN_HEIGHT world units. This is to help avoid
|
|
precision loss with fixed-point numbers. */
|
|
|
|
#include <num/num.h>
|
|
#include <num/vec.h>
|
|
using namespace libnum;
|
|
struct mat3;
|
|
|
|
/* Number of world units that we fix the screen's half height to. The screen is
|
|
placed at the correct distance to make that happen. */
|
|
#define HALF_SCREEN_HEIGHT 2
|
|
/* World boundaries */
|
|
#define WORLD_SIZE 8 /* (± 4) */
|
|
/* Viewport size, in pixels */
|
|
#define VWIDTH 198
|
|
#define VHEIGHT 112
|
|
|
|
struct camera {
|
|
num fov;
|
|
num screen_distance;
|
|
|
|
/* Camera position (usually stays at z=0, objects move towards it) */
|
|
vec3 pos;
|
|
/* Angles of rotation */
|
|
float yaw, pitch, roll;
|
|
num cos_r, sin_r;
|
|
num cos_p, sin_p;
|
|
num cos_y, sin_y;
|
|
/* Corresponding directions, in world coordinates */
|
|
vec3 forward, right, up;
|
|
|
|
int roll_quadrant;
|
|
};
|
|
|
|
struct element_mirror {
|
|
num begin, end;
|
|
};
|
|
enum element_plane_type {
|
|
ELEMENT_PLANE_DAMAGE,
|
|
ELEMENT_PLANE_ARROW,
|
|
};
|
|
struct element_plane {
|
|
num y;
|
|
uint32_t shape;
|
|
uint16_t type;
|
|
uint16_t data; /* ARROW: direction */
|
|
};
|
|
struct element_text {
|
|
num begin, end;
|
|
char const *str;
|
|
};
|
|
|
|
struct level {
|
|
char const *name;
|
|
num finish;
|
|
|
|
int mirror_count;
|
|
struct element_mirror *mirrors;
|
|
|
|
int plane_count;
|
|
struct element_plane *planes;
|
|
|
|
int text_count;
|
|
struct element_text *texts;
|
|
};
|
|
|
|
struct world {
|
|
num16 neon_position;
|
|
num16 neon_period;
|
|
|
|
/* Current objects */
|
|
num depth;
|
|
struct element_mirror *mirror;
|
|
struct element_plane *plane;
|
|
struct element_text *text;
|
|
int mirror_index;
|
|
int plane_index;
|
|
int text_index;
|
|
};
|
|
|
|
void camera_set_fov(struct camera *camera, float fov_degrees);
|
|
mat3 matrix_camera2world(struct camera const *camera);
|
|
void camera_update_angles(struct camera *camera);
|
|
void render_fragment(struct camera const *camera, struct world const *world,
|
|
uint16_t *fragment, int y_start, int y_height);
|
|
bool camera_rolling(struct camera const *camera);
|
|
void camera_roll(struct camera *camera, float snap_factor);
|
|
|
|
//=== Azur shader wrapping the raytracing ===//
|
|
|
|
void cd_raytrace(struct camera const *camera, struct world const *world);
|
|
void cd_raytrace_configure(void);
|
|
|
|
//=== Input management ===//
|
|
|
|
struct input {
|
|
bool left;
|
|
bool right;
|
|
bool up;
|
|
bool down;
|
|
bool OPTN;
|
|
bool roll;
|
|
};
|
|
|
|
//=== Additions to libnum ===//
|
|
|
|
struct mat3
|
|
{
|
|
num x11, x12, x13;
|
|
num x21, x22, x23;
|
|
num x31, x32, x33;
|
|
};
|
|
|
|
mat3 operator *(mat3 const &A, mat3 const &B);
|
|
vec3 operator *(mat3 const &M, vec3 const &u);
|