platform colors and blue platform effect
This commit is contained in:
parent
08411fc90c
commit
b6fb44c80a
15
src/game.cpp
15
src/game.cpp
|
@ -154,19 +154,18 @@ num game_height_at(struct game *game, num z, int face)
|
|||
: -KILL_PLANE_RADIUS;
|
||||
}
|
||||
|
||||
#if 0
|
||||
bool game_player_above_platform(struct game *game, num height)
|
||||
const struct platform *game_platform_under_player(struct game const *game,
|
||||
struct player const *player)
|
||||
{
|
||||
struct player const *player = &game->player;
|
||||
if(player->stance != player::Running)
|
||||
return NULL;
|
||||
|
||||
for(auto const &p: game->level.platform_buffer) {
|
||||
if(player->platform == p.face
|
||||
&& player->z >= p.z && player->z <= p.z + p.length
|
||||
&& height >= space_platform_height(p.height)) {
|
||||
return true;
|
||||
&& player->z >= p.z && player->z <= p.z + p.length) {
|
||||
return &p;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
|
|
13
src/game.h
13
src/game.h
|
@ -6,6 +6,7 @@
|
|||
#include "level.h"
|
||||
|
||||
#include <gint/display.h>
|
||||
#include <libprof.h>
|
||||
|
||||
/* A player's movement and data information. */
|
||||
struct player
|
||||
|
@ -85,6 +86,10 @@ struct game
|
|||
struct {
|
||||
bool footer; /* Show performance footer */
|
||||
} debug;
|
||||
|
||||
struct {
|
||||
prof_t effect_bpp;
|
||||
} perf;
|
||||
};
|
||||
|
||||
//======= Functions on the game world space =======//
|
||||
|
@ -116,10 +121,8 @@ void game_advance(struct game *game);
|
|||
/* Get platform height at the provided position. */
|
||||
num game_height_at(struct game *game, num z, int face);
|
||||
|
||||
#if 0
|
||||
/* Check if the player would be standing over a platform with the provided
|
||||
height coordinate. This ignores player's height value. */
|
||||
bool game_player_above_platform(struct game *game, num height);
|
||||
#endif
|
||||
/* Returns the platform on which the player is running, if any. */
|
||||
const struct platform *game_platform_under_player(struct game const *game,
|
||||
struct player const *player);
|
||||
|
||||
#endif /* __GAME_H__ */
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
#include <stdlib.h>
|
||||
|
||||
/* Geometric parameters */
|
||||
#define G_PLATFORM_LEN num(3.0)
|
||||
#define G_PLATFORM_LEN num(2.5)
|
||||
#define G_PLATFORM_SPC num(0.5)
|
||||
#define G_PLATFORM_LEN_INITIAL num(6.0)
|
||||
/* Probabilities */
|
||||
|
@ -39,7 +39,8 @@ AcceleronGenerator::AcceleronGenerator():
|
|||
....R..... [h=8]
|
||||
....|.....
|
||||
....|.....
|
||||
...B|..... [h=5]
|
||||
....|.....
|
||||
...B...... [h=5]
|
||||
...|.#.... [h=4]
|
||||
...|.|....
|
||||
....#..... [h=1]
|
||||
|
@ -90,22 +91,23 @@ static num generate_ascending_funnel(struct level *level, num z)
|
|||
p.length = G_PLATFORM_LEN * 3;
|
||||
p.height = 8;
|
||||
level->platform_buffer.push_back(p);
|
||||
z += G_PLATFORM_LEN * 3 + G_PLATFORM_SPC;
|
||||
|
||||
p.type = PLATFORM_BLUE;
|
||||
p.face = 3;
|
||||
p.z = z + G_PLATFORM_LEN * 2;
|
||||
p.z = z;
|
||||
p.length = G_PLATFORM_LEN * 3;
|
||||
p.height = 5;
|
||||
level->platform_buffer.push_back(p);
|
||||
|
||||
p.type = PLATFORM_WHITE;
|
||||
p.face = 5;
|
||||
p.z = z + G_PLATFORM_LEN * 3;
|
||||
p.z = z + G_PLATFORM_LEN;
|
||||
p.length = G_PLATFORM_LEN * 2;
|
||||
p.height = 4;
|
||||
level->platform_buffer.push_back(p);
|
||||
|
||||
z += G_PLATFORM_LEN * 5 + G_PLATFORM_SPC;
|
||||
z += G_PLATFORM_LEN * 3 + G_PLATFORM_SPC;
|
||||
|
||||
/* Exit platform */
|
||||
p.type = PLATFORM_WHITE;
|
||||
|
|
23
src/main.cpp
23
src/main.cpp
|
@ -56,6 +56,8 @@ int play_level(int level_id)
|
|||
camera->platform,
|
||||
str(camera->angle_vector));
|
||||
|
||||
image_t *effect_bpp = NULL;
|
||||
|
||||
bool game_run = true;
|
||||
while(game_run) {
|
||||
while(!need_frame) sleep();
|
||||
|
@ -67,10 +69,14 @@ int play_level(int level_id)
|
|||
game.t += dt;
|
||||
prof_t perf_frame = prof_make();
|
||||
prof_enter_norec(perf_frame);
|
||||
game.perf.effect_bpp = prof_make();
|
||||
|
||||
level_update(&game.level, player->z);
|
||||
camera_track(camera, player);
|
||||
|
||||
struct platform const *standing_on = game_platform_under_player(&game,
|
||||
&game.player);
|
||||
|
||||
//======= Rendering =======//
|
||||
|
||||
azrp_perf_clear();
|
||||
|
@ -82,7 +88,7 @@ int play_level(int level_id)
|
|||
for(auto it = game.level.platform_buffer.rbegin();
|
||||
it != game.level.platform_buffer.rend();
|
||||
++it) {
|
||||
int color = camera_platform_color(&game.camera, it->face);
|
||||
int color = render_platform_color(&*it, &game.camera, game.t);
|
||||
struct prect p = space_platform_position(&*it);
|
||||
|
||||
/* Near plane clipping */
|
||||
|
@ -104,6 +110,15 @@ int play_level(int level_id)
|
|||
render_anim_frame((int)player_dot.x, (int)player_dot.y,
|
||||
player_anim, player_frame);
|
||||
|
||||
if(standing_on && standing_on->type == PLATFORM_BLUE) {
|
||||
prof_enter(game.perf.effect_bpp);
|
||||
render_effect_bpp(&effect_bpp, game.t);
|
||||
azrp_image((int)player_dot.x - effect_bpp->width / 2,
|
||||
(int)player_dot.y - effect_bpp->height + 2,
|
||||
effect_bpp);
|
||||
prof_leave(game.perf.effect_bpp);
|
||||
}
|
||||
|
||||
prof_leave_norec(perf_comp);
|
||||
azrp_update();
|
||||
|
||||
|
@ -203,7 +218,7 @@ int play_level(int level_id)
|
|||
&& player->jump_t > TIME_JUMP_THRUST_MIN
|
||||
&& !keydown(player->jump_key)) {
|
||||
player->stance = player::Falling;
|
||||
player->vheight = 0.0;
|
||||
player->vheight = -1;
|
||||
}
|
||||
|
||||
if(player->height >= floor - STEP_HEIGHT
|
||||
|
@ -236,6 +251,9 @@ int play_level(int level_id)
|
|||
last_frame_us = prof_time(perf_frame);
|
||||
}
|
||||
|
||||
if(effect_bpp)
|
||||
image_free(effect_bpp);
|
||||
|
||||
timer_stop(timer);
|
||||
return 0;
|
||||
}
|
||||
|
@ -246,6 +264,7 @@ int main(void)
|
|||
|
||||
__printf_enable_fp();
|
||||
prof_init();
|
||||
render_init();
|
||||
space_init();
|
||||
|
||||
extern font_t font_boson;
|
||||
|
|
101
src/render.cpp
101
src/render.cpp
|
@ -72,7 +72,7 @@ void camera_project_prect(struct camera *camera, struct prect *p)
|
|||
p->fr.y = -p->fr.y * far_f + half_screen.y;
|
||||
}
|
||||
|
||||
int camera_platform_color(struct camera *camera, int platform_id)
|
||||
int camera_platform_color(struct camera const *camera, int platform_id)
|
||||
{
|
||||
/* Accounting for the full angle is too precise and results in weird
|
||||
color jumps at different times across platforms, instead switch at half
|
||||
|
@ -86,6 +86,62 @@ int camera_platform_color(struct camera *camera, int platform_id)
|
|||
return C_RGB(gray, gray, gray);
|
||||
}
|
||||
|
||||
//======= Rendering tools =======//
|
||||
|
||||
static uint16_t blue_ramp[32];
|
||||
|
||||
static void split_RGB(uint32_t RGB, int *R, int *G, int *B)
|
||||
{
|
||||
*R = (RGB >> 16) & 0xff;
|
||||
*G = (RGB >> 8) & 0xff;
|
||||
*B = (RGB >> 0) & 0xff;
|
||||
}
|
||||
|
||||
static uint32_t make_RGB(int R, int G, int B)
|
||||
{
|
||||
return ((R & 0xff) << 16) | ((G & 0xff) << 8) | (B & 0xff);
|
||||
}
|
||||
|
||||
static void gradient(uint32_t RGB1, uint32_t RGB2, uint16_t *gradient, int N)
|
||||
{
|
||||
int R1, G1, B1, R2, G2, B2;
|
||||
split_RGB(RGB1, &R1, &G1, &B1);
|
||||
split_RGB(RGB2, &R2, &G2, &B2);
|
||||
|
||||
for(int i = 0; i < N; i++) {
|
||||
int R = ((N-1-i) * R1 + i * R2) / (N-1);
|
||||
int G = ((N-1-i) * G1 + i * G2) / (N-1);
|
||||
int B = ((N-1-i) * B1 + i * B2) / (N-1);
|
||||
gradient[i] = RGB24(make_RGB(R, G, B));
|
||||
}
|
||||
}
|
||||
|
||||
void render_init(void)
|
||||
{
|
||||
/* Generate a gradient ramp for blue platforms */
|
||||
gradient(0x5090d0, 0x2060b0, blue_ramp, 32);
|
||||
}
|
||||
|
||||
uint16_t render_color_blue_platform(num t)
|
||||
{
|
||||
int step = (int)(32 * t.frac()) & 31;
|
||||
int phase = (int)t & 1;
|
||||
return phase ? blue_ramp[31 - step] : blue_ramp[step];
|
||||
}
|
||||
|
||||
uint16_t render_platform_color(struct platform const *p,
|
||||
struct camera const *camera, num t)
|
||||
{
|
||||
if(p->type == PLATFORM_WHITE)
|
||||
return camera_platform_color(camera, p->face);
|
||||
if(p->type == PLATFORM_BLUE)
|
||||
return render_color_blue_platform(t);
|
||||
if(p->type == PLATFORM_RED)
|
||||
return RGB24(0xd06060);
|
||||
|
||||
return RGB24(0xff00ff);
|
||||
}
|
||||
|
||||
void render_triangle(vec3 *p1, vec3 *p2, vec3 *p3, int color)
|
||||
{
|
||||
azrp_triangle(
|
||||
|
@ -109,3 +165,46 @@ void render_anim_frame(int x, int y, struct anim *anim, int frame)
|
|||
y + anim->y_offsets[frame] - anim->y_anchor,
|
||||
anim->frames[frame]);
|
||||
}
|
||||
|
||||
void render_effect_bpp(image_t **image, num t)
|
||||
{
|
||||
enum { BPP_PARTICLE = 0x81 };
|
||||
static uint16_t bpp_palette[] = {
|
||||
[0] = RGB24(0xff00ff), /* alpha */
|
||||
[BPP_PARTICLE-0x80] = RGB24(0x5090d0),
|
||||
};
|
||||
static int const bpp_W = 34;
|
||||
static int const bpp_H = 68;
|
||||
|
||||
if(!*image) {
|
||||
*image = image_alloc(bpp_W, bpp_H, IMAGE_P8_RGB565A);
|
||||
image_set_palette(*image, bpp_palette, 1, false);
|
||||
}
|
||||
|
||||
image_clear(*image);
|
||||
uint8_t *pixels = (uint8_t *)(*image)->data;
|
||||
|
||||
for(int i = 0; i < 24; i++) {
|
||||
/* Particule #i appears after i 32-th of a second */
|
||||
num start = num(i) / 32;
|
||||
if(t < start)
|
||||
continue;
|
||||
num16 local_time = num16(2 * ((t - start) % num(0.5)));
|
||||
|
||||
int x0_int = (23 * i) % (bpp_W - 2);
|
||||
|
||||
num16 x0 = num16(x0_int);
|
||||
num16 y0 = num16(bpp_H - 1 - ((37 * i) & 15));
|
||||
|
||||
num16 vx = num16(bpp_W / 2 - x0_int) / 4;
|
||||
|
||||
num16 x = x0 + vx * local_time;
|
||||
num16 y = y0 - (bpp_H - 16) * local_time;
|
||||
|
||||
for(int dy = 0; dy <= 3; dy++)
|
||||
for(int dx = 0; dx <= 3; dx++) {
|
||||
pixels[((int)y + dy) * (*image)->stride + (int)x + dx] =
|
||||
BPP_PARTICLE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
19
src/render.h
19
src/render.h
|
@ -69,7 +69,20 @@ vec3 camera_project_point(struct camera *, vec3 point);
|
|||
void camera_project_prect(struct camera *, struct prect *rect);
|
||||
|
||||
/* Compute the platform's color based on the camera's angle. */
|
||||
int camera_platform_color(struct camera *camera, int platform_id);
|
||||
int camera_platform_color(struct camera const *camera, int platform_id);
|
||||
|
||||
//======= Rendering tools =======//
|
||||
|
||||
/* Initialize/precompute globals. */
|
||||
void render_init(void);
|
||||
|
||||
/* Color of a blue platform at the specified world time. */
|
||||
uint16_t render_color_blue_platform(num t);
|
||||
|
||||
/* Color of the provided platform viewed from the provided camera at the given
|
||||
world time. */
|
||||
uint16_t render_platform_color(struct platform const *p,
|
||||
struct camera const *camera, num t);
|
||||
|
||||
/* Queue an Azur command to render the triangle defined by p1/p2/p3. Only the
|
||||
x/y coordinates are used, z is ignored. */
|
||||
|
@ -82,4 +95,8 @@ void render_dots(std::initializer_list<vec3> const &&points);
|
|||
/* Render a frame of an animation. */
|
||||
void render_anim_frame(int x, int y, struct anim *anim, int frame);
|
||||
|
||||
/* Render the blue platform particle effect at time t. If *image is NULL,
|
||||
creates it automatically. */
|
||||
void render_effect_bpp(image_t **image, num t);
|
||||
|
||||
#endif /* __RENDERH__ */
|
||||
|
|
Loading…
Reference in New Issue