189 lines
5.1 KiB
C++
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 */
|