AfterBurner/src/afterburner.h

189 lines
5.1 KiB
C++

#ifndef AFTERBURNER_H
#define AFTERBURNER_H
#include <gint/display.h>
#include <stdint.h>
#include <stddef.h>
#include <string.h>
#include <num/num.h>
#include <num/vec.h>
#include <libprof.h>
using namespace libnum;
//---
// Horizon shader
//---
/* Render the horizon line with a palette. The horizon line passes through
(x,y) and has the specified angle. This is an Azur shader, the function only
queues a command and delays the rendering to azrp_update(). */
void ab_horizon(int x, int y, float alpha, uint16_t *palette);
/* Configuration call, to be performed at every scale update */
void ab_horizon_configure(void);
//---
// Image utilities
//---
/* Allocate a new image from a rotation + upscaling of a square image img.
The source image must be RGB565A, P8_RGB565A or P4_RGB565A. */
bopti_image_t *image_rotate_scale_square
(bopti_image_t const *img, float alpha, num gamma);
/* Same but optimized for P8_RGB565A. *anchor_x and *anchor_y should be set to
the coordinates of the "anchor" within the source image, and are updated to
reflect the coordinates of that same spot in the rotated image. */
bopti_image_t *image_rotate_scale_square_p8_rgb565a
(bopti_image_t const *img,
float alpha, num gamma,
int *anchor_x, int *anchor_y);
/* An image with all upscaled variations from 0.125x to 2x. */
class DynamicImage
{
public:
DynamicImage(bopti_image_t const *source, float m_alpha, prof_t *prof_ctx,
int anchor_x, int anchor_y);
~DynamicImage();
/* Get the closest scaled version, generating it on demand. */
bopti_image_t *getAtScale(num scale, int *anchor_x, int *anchor_y);
private:
bopti_image_t *m_images[16];
int m_anchor_x, m_anchor_y;
int8_t m_ax[16], m_ay[16];
bopti_image_t const *m_source;
float m_alpha;
prof_t *m_prof;
};
//---
// 3D transforms and projections
//---
struct plane
{
plane() {
memset(this, 0, sizeof *this);
}
/* Position in space */
vec3 pos;
/* Euler angles with aviation terminology */
float roll, pitch, yaw;
/* Air speed */
num air_speed;
// The following are automatically set by plane_update()
/* Sine and cosine of every angle */
num cos_r, sin_r, cos_p, sin_p, cos_y, sin_y;
/* Vector looking forward and to the right */
vec3 forward, right;
/* Vector looking forward but parallel to the ground */
vec3 forward_ground;
};
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);
num distance2(vec3 u, vec3 v);
num64 distance2_64(vec3 u, vec3 v);
/* Update computationally-derived parameters of a plane */
void plane_update(struct plane *plane);
/* Pixels per world unit (primitive control for FOV) */
#define SCREEN_SCALING 200
/* Minimum and maximum distance of visible objects */
#define NEAR_CLIP_PLANE 8
#define FAR_CLIP_PLANE 50
#define SIDE_CLIP_PLANE 25
/* Margin around the screen where a center point is considered visible */
#define SCREEN_MARGIN 20
/* A 3D point with a handle to some sprite/information/etc. */
struct ref_point
{
/* Position of the point in 3D space (evolves during transformations) */
vec3 pos;
/* Unique identifier (used to identify point properties in world map) */
int id;
};
void transform_world2camera(struct plane const *plane, vec3 camera_pos,
struct ref_point *points, int size);
void transform_camera2screen(struct ref_point *points, int size);
//---
// World map
//---
/* Needs to be larger than FAR_CLIP_PLANE for culling optimisations to work */
#define CHUNK_SIZE 64
struct chunk
{
struct ref_point *points;
int count;
};
struct world
{
int w, h;
int chunks_x, chunks_y;
struct chunk *chunks;
};
/* Make a world structure using the specified set of points. The points are
split into chunks, which allows faster lookup later on. The points are all
copied, to the original array is safe to free after this call. */
struct world *world_make(int w, int h, struct ref_point *points, int count);
/* Destroy a world structure and its copied points. */
void world_destroy(struct world *w);
/* Select the points in the world that are "close" to the specified anchor.
These are points from the anchor's chunk and up to 8 neighboring chunks. The
size of the array is returned in *size. free() the array after use.
This function rotates chunks, so that for instance if position.x is 0.5 and
forward.x < 0 (ie. we look at a region of space with x<0), chunks from the
other side of the map are rotated in to provide a wrap-around effect.
extra_size entries are left uninitialized at the end of the array so that
any dynamic sprites can be added. *size does *not* count extra_size. */
struct ref_point *world_select(struct world const *w, vec3 position,
vec3 forward, int *size, int extra_size);
//---
// Game mechanics
//---
/* Distance forward where bombs drop */
#define BOMB_DISTANCE 15
struct objective
{
vec3 pos;
bool destroyed;
int type;
};
struct explosion
{
vec3 pos;
num time; /* if negative, no explosion */
};
#endif /* AFTERBURNER_H */