Compare commits
3 Commits
933819a219
...
39310e7e2e
Author | SHA1 | Date |
---|---|---|
Lephenixnoir | 39310e7e2e | |
Lephenixnoir | cca75b89a6 | |
Lephenixnoir | 8c952c9e66 |
|
@ -21,7 +21,6 @@ endif()
|
|||
|
||||
if(AZUR_PLATFORM STREQUAL linux)
|
||||
list(APPEND SOURCES
|
||||
src/backend/linux/render.cc
|
||||
src/backend/linux/programs.cc)
|
||||
endif()
|
||||
|
||||
|
@ -34,7 +33,8 @@ if(AZUR_PLATFORM STREQUAL emscripten)
|
|||
endif()
|
||||
|
||||
add_executable(chaos-drop ${SOURCES} ${ASSETS})
|
||||
target_compile_options(chaos-drop PRIVATE -Wall -Wextra -O2)
|
||||
target_compile_options(chaos-drop PRIVATE -Wall -Wextra -O3
|
||||
-fmodulo-sched -fmodulo-sched-allow-regmoves)
|
||||
|
||||
if(AZUR_PLATFORM STREQUAL gint)
|
||||
find_package(Gint 2.10 REQUIRED)
|
||||
|
|
|
@ -9,8 +9,9 @@ struct cd_raytrace_cmd
|
|||
uint8_t shader_id;
|
||||
uint8_t _[3];
|
||||
|
||||
/* Camera used for rendering */
|
||||
/* Camera and world used for rendering */
|
||||
struct camera const *camera;
|
||||
struct world const *world;
|
||||
/* Current y value */
|
||||
int y;
|
||||
};
|
||||
|
@ -26,7 +27,7 @@ void cd_raytrace_shader(void *uniforms0, void *cmd0, void *fragment)
|
|||
|
||||
int frag_height = uniforms;
|
||||
int h = (frag_height > 112 - cmd->y) ? 112 - cmd->y : frag_height;
|
||||
render_fragment(cmd->camera, (uint16_t *)fragment, cmd->y, h);
|
||||
render_fragment(cmd->camera, cmd->world, (uint16_t *)fragment, cmd->y, h);
|
||||
cmd->y += h;
|
||||
}
|
||||
|
||||
|
@ -36,13 +37,14 @@ static void register_shader(void)
|
|||
CD_RAYTRACE_SHADER_ID = azrp_register_shader(cd_raytrace_shader);
|
||||
}
|
||||
|
||||
void cd_raytrace(struct camera const *camera)
|
||||
void cd_raytrace(struct camera const *camera, struct world const *world)
|
||||
{
|
||||
prof_enter(azrp_perf_cmdgen);
|
||||
|
||||
struct cd_raytrace_cmd cmd;
|
||||
cmd.shader_id = CD_RAYTRACE_SHADER_ID;
|
||||
cmd.camera = camera;
|
||||
cmd.world = world;
|
||||
cmd.y = 0;
|
||||
|
||||
azrp_queue_command(&cmd, sizeof cmd, 0, azrp_frag_count);
|
||||
|
|
|
@ -46,20 +46,63 @@ struct camera {
|
|||
/* Corresponding directions, in world coordinates */
|
||||
vec3 forward, right, up;
|
||||
|
||||
/* Game stuff... */
|
||||
int roll_quadrant;
|
||||
};
|
||||
|
||||
num neon_position;
|
||||
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 {
|
||||
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, uint16_t *fragment,
|
||||
int y_start, int y_height);
|
||||
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);
|
||||
void cd_raytrace(struct camera const *camera, struct world const *world);
|
||||
void cd_raytrace_configure(void);
|
||||
|
||||
//=== Input management ===//
|
||||
|
@ -70,6 +113,7 @@ struct input {
|
|||
bool up;
|
||||
bool down;
|
||||
bool OPTN;
|
||||
bool roll;
|
||||
};
|
||||
|
||||
//=== Additions to libnum ===//
|
||||
|
|
111
src/main.cc
111
src/main.cc
|
@ -72,6 +72,7 @@ static int platform_update(struct input *input)
|
|||
input->down = state[SDL_SCANCODE_DOWN];
|
||||
input->left = state[SDL_SCANCODE_LEFT];
|
||||
input->right = state[SDL_SCANCODE_RIGHT];
|
||||
input->roll = state[SDL_SCANCODE_RETURN];
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -113,6 +114,8 @@ static int platform_update(struct input *input)
|
|||
gint_osmenu();
|
||||
if(e.key == KEY_OPTN)
|
||||
input->OPTN = true;
|
||||
if(e.key == KEY_SHIFT)
|
||||
input->roll = true;
|
||||
}
|
||||
|
||||
input->left = keydown(KEY_LEFT);
|
||||
|
@ -172,13 +175,15 @@ vec3 operator * (mat3 const &M, vec3 const &u)
|
|||
}
|
||||
|
||||
static struct camera *camera = NULL;
|
||||
static struct world *world = NULL;
|
||||
static struct level *level = NULL;
|
||||
static bool debug = false;
|
||||
|
||||
void render(void)
|
||||
{
|
||||
#ifdef AZUR_TOOLKIT_GINT
|
||||
azrp_perf_clear();
|
||||
cd_raytrace(camera);
|
||||
cd_raytrace(camera, world);
|
||||
platform_render();
|
||||
|
||||
if(debug) {
|
||||
|
@ -189,7 +194,7 @@ void render(void)
|
|||
r61524_display(gint_vram, DHEIGHT-20, 20, R61524_DMA_WAIT);
|
||||
}
|
||||
#else
|
||||
render_fragment(camera, vram, 0, VHEIGHT);
|
||||
render_fragment(camera, world, vram, 0, VHEIGHT);
|
||||
platform_render();
|
||||
#endif
|
||||
}
|
||||
|
@ -199,58 +204,107 @@ int update(void)
|
|||
struct input input = {};
|
||||
if(platform_update(&input))
|
||||
return 1;
|
||||
if(input.OPTN)
|
||||
debug = !debug;
|
||||
|
||||
/* Yes I'm aware I'm always changing the angles */
|
||||
bool changed = false;
|
||||
|
||||
static num const mv_speed = 0.35;
|
||||
static num const mv_speed = 0.45;
|
||||
static num const wall = WORLD_SIZE * 0.45; /* margin */
|
||||
static float const rot_speed = 0.01;
|
||||
static float const rot_snap = 0.6;
|
||||
static float const rot_max = 0.2;
|
||||
static num const neon_speed = 2;
|
||||
static num const fall_speed = 2;
|
||||
static float const barrel_snap = 0.5;
|
||||
|
||||
if(input.left) {
|
||||
camera->pos.x = max(camera->pos.x - mv_speed, -wall);
|
||||
camera->pos -= mv_speed * camera->right;
|
||||
camera->yaw = fmaxf(camera->yaw - rot_speed, -rot_max);
|
||||
changed = true;
|
||||
}
|
||||
else if(input.right) {
|
||||
camera->pos.x = min(camera->pos.x + mv_speed, wall);
|
||||
camera->pos += mv_speed * camera->right;
|
||||
camera->yaw = fminf(camera->yaw + rot_speed, rot_max);
|
||||
changed = true;
|
||||
}
|
||||
else {
|
||||
camera->yaw *= rot_snap;
|
||||
changed = true;
|
||||
}
|
||||
|
||||
if(input.up) {
|
||||
camera->pos.z = min(camera->pos.z + mv_speed, wall);
|
||||
camera->pos += mv_speed * camera->up;
|
||||
camera->pitch = fmaxf(camera->pitch - rot_speed, -rot_max);
|
||||
changed = true;
|
||||
}
|
||||
else if(input.down) {
|
||||
camera->pos.z = max(camera->pos.z - mv_speed, -wall);
|
||||
camera->pos -= mv_speed * camera->up;
|
||||
camera->pitch = fminf(camera->pitch + rot_speed, rot_max);
|
||||
changed = true;
|
||||
}
|
||||
else {
|
||||
camera->pitch *= rot_snap;
|
||||
changed = true;
|
||||
}
|
||||
|
||||
if(changed)
|
||||
camera_update_angles(camera);
|
||||
camera->pos.x = clamp(camera->pos.x, -wall, wall);
|
||||
camera->pos.z = clamp(camera->pos.z, -wall, wall);
|
||||
|
||||
camera->neon_position =
|
||||
(camera->neon_position + num(32) - neon_speed) % num(32);
|
||||
if(input.roll && input.left && !camera_rolling(camera)) {
|
||||
camera->roll_quadrant = (camera->roll_quadrant + 4 - 1) % 4;
|
||||
}
|
||||
else if(input.roll && input.right && !camera_rolling(camera)) {
|
||||
camera->roll_quadrant = (camera->roll_quadrant + 1) % 4;
|
||||
}
|
||||
|
||||
camera_roll(camera, barrel_snap);
|
||||
camera_update_angles(camera);
|
||||
|
||||
world->depth += fall_speed;
|
||||
world->neon_position += world->neon_period - num16(fall_speed);
|
||||
world->neon_position %= world->neon_period;
|
||||
|
||||
// Remove old world elements
|
||||
|
||||
struct world *w = world;
|
||||
|
||||
if(w->mirror && w->depth > w->mirror->end)
|
||||
w->mirror = NULL;
|
||||
if(w->plane && w->depth > w->plane->y) {
|
||||
// TODO: Check collision
|
||||
w->plane = NULL;
|
||||
}
|
||||
if(w->text && w->depth > w->text->end)
|
||||
w->text = NULL;
|
||||
|
||||
// Load incoming world elements
|
||||
|
||||
if(!w->mirror && w->mirror_index < level->mirror_count
|
||||
&& level->mirrors[w->mirror_index].begin < w->depth + num(64)) {
|
||||
w->mirror = &level->mirrors[w->mirror_index++];
|
||||
}
|
||||
if(!w->plane && w->plane_index < level->plane_count
|
||||
&& level->planes[w->plane_index].y < w->depth + num(64)) {
|
||||
w->plane = &level->planes[w->plane_index++];
|
||||
}
|
||||
if(!w->text && w->text_index < level->text_count
|
||||
&& level->texts[w->text_index].begin < w->depth + num(64)) {
|
||||
w->text = &level->texts[w->text_index++];
|
||||
}
|
||||
|
||||
if(input.OPTN)
|
||||
debug = !debug;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Basic basic level */
|
||||
struct level lv1 = {
|
||||
.mirror_count = 1,
|
||||
.mirrors = (struct element_mirror[]){
|
||||
{ .begin = 256, .end = 512 },
|
||||
},
|
||||
.plane_count = 2,
|
||||
.planes = (struct element_plane[]){
|
||||
{ .y = 64, .shape = 0b01010'10101'01010'10101'01010,
|
||||
.type = ELEMENT_PLANE_DAMAGE, .data = 0 },
|
||||
{ .y = 128, .shape = 0b11111'10001'10001'10001'11111,
|
||||
.type = ELEMENT_PLANE_DAMAGE, .data = 0 },
|
||||
},
|
||||
.text_count = 0,
|
||||
.texts = (struct element_text[]){
|
||||
},
|
||||
};
|
||||
|
||||
int main(void)
|
||||
{
|
||||
if(azur_init("Chaos Drop!", 3*VWIDTH, 3*VHEIGHT))
|
||||
|
@ -262,6 +316,17 @@ int main(void)
|
|||
camera_set_fov(camera, 80.0);
|
||||
camera_update_angles(camera);
|
||||
|
||||
level = &lv1;
|
||||
|
||||
struct world w = {};
|
||||
w.neon_position = 0;
|
||||
w.depth = 0;
|
||||
w.neon_period = 64;
|
||||
w.mirror = NULL;
|
||||
w.plane = NULL;
|
||||
w.text = NULL;
|
||||
world = &w;
|
||||
|
||||
init();
|
||||
int rc = azur_main_loop(render, 30, update, -1, AZUR_MAIN_LOOP_TIED);
|
||||
quit();
|
||||
|
|
|
@ -3,6 +3,9 @@
|
|||
#include <stdio.h>
|
||||
#include <math.h>
|
||||
|
||||
/* 5-bit channels to RGB565 */
|
||||
#define RGB(R, G, B) ((R << 11) | (G << 6) | (B))
|
||||
|
||||
void camera_set_fov(struct camera *camera, float fov_degrees)
|
||||
{
|
||||
camera->fov = num(fov_degrees);
|
||||
|
@ -15,6 +18,45 @@ void camera_set_fov(struct camera *camera, float fov_degrees)
|
|||
camera->screen_distance = num(sd);
|
||||
}
|
||||
|
||||
bool camera_rolling(struct camera const *camera)
|
||||
{
|
||||
float target_roll = camera->roll_quadrant * M_PI / 2;
|
||||
float distance = fabsf(target_roll - camera->roll);
|
||||
|
||||
/* Wrap-around case */
|
||||
if(camera->roll > 6.0 && camera->roll_quadrant == 0)
|
||||
distance = fabsf(target_roll - (camera->roll - 2*M_PI));
|
||||
|
||||
return distance > 0.2;
|
||||
}
|
||||
|
||||
void camera_roll(struct camera *camera, float snap_factor)
|
||||
{
|
||||
float target_roll = camera->roll_quadrant * M_PI / 2;
|
||||
float distance_nowrap = target_roll - camera->roll;
|
||||
float distance_wrap_up = (target_roll + 2*M_PI) - camera->roll;
|
||||
float distance_wrap_down = (target_roll - 2*M_PI) - camera->roll;
|
||||
|
||||
/* Snap with closest direction */
|
||||
if(fabsf(distance_nowrap) < fabsf(distance_wrap_up)) {
|
||||
if(fabsf(distance_nowrap) < fabsf(distance_wrap_down))
|
||||
camera->roll += distance_nowrap * snap_factor;
|
||||
else
|
||||
camera->roll += distance_wrap_down * snap_factor;
|
||||
}
|
||||
else {
|
||||
if(fabsf(distance_wrap_down) < fabsf(distance_wrap_down))
|
||||
camera->roll += distance_wrap_down * snap_factor;
|
||||
else
|
||||
camera->roll += distance_wrap_up * snap_factor;
|
||||
}
|
||||
|
||||
if(camera->roll < 0)
|
||||
camera->roll += 2 * M_PI;
|
||||
else if(camera->roll > 2 * M_PI)
|
||||
camera->roll -= 2 * M_PI;
|
||||
}
|
||||
|
||||
mat3 matrix_camera2world(struct camera const *camera)
|
||||
{
|
||||
num cos_r = camera->cos_r;
|
||||
|
@ -93,9 +135,12 @@ svec3 svec3_of_vec3(vec3 v)
|
|||
enum object {
|
||||
/* Wall sides */
|
||||
LEFT = 1, TOP, RIGHT, BOTTOM,
|
||||
/* Object plane */
|
||||
OBJECT_PLANE,
|
||||
};
|
||||
|
||||
static int cast_ray(svec3 const &origin, svec3 const &rayDir, snum *t)
|
||||
static int cast_ray(struct world const *world, svec3 const &origin,
|
||||
svec3 const &rayDir, snum *t, num *collision_y)
|
||||
{
|
||||
snum tx_rx_rz, tz_rx_rz;
|
||||
int hitx = 0, hitz = 0;
|
||||
|
@ -104,7 +149,7 @@ static int cast_ray(svec3 const &origin, svec3 const &rayDir, snum *t)
|
|||
tx_rx_rz = (snum(WORLD_SIZE / 2) - origin.x) * rayDir.z;
|
||||
hitx = RIGHT;
|
||||
}
|
||||
else if(rayDir.x < 0) {
|
||||
else if(__builtin_expect(rayDir.x < 0, 1)) {
|
||||
tx_rx_rz = (snum(-WORLD_SIZE / 2) - origin.x) * rayDir.z;
|
||||
hitx = LEFT;
|
||||
}
|
||||
|
@ -113,47 +158,63 @@ static int cast_ray(svec3 const &origin, svec3 const &rayDir, snum *t)
|
|||
tz_rx_rz = (snum(WORLD_SIZE / 2) - origin.z) * rayDir.x;
|
||||
hitz = TOP;
|
||||
}
|
||||
else if(rayDir.z < 0) {
|
||||
else if(__builtin_expect(rayDir.z < 0, 1)) {
|
||||
tz_rx_rz = (snum(-WORLD_SIZE / 2) - origin.z) * rayDir.x;
|
||||
hitz = BOTTOM;
|
||||
}
|
||||
|
||||
// static int done = 0;
|
||||
// if(++done <= 4)
|
||||
// printf("tx=%f tz=%f rx=%f rz=%f tx_rx_rz=%f tz_rx_rz=%f\n",
|
||||
// (float)tx, (float)tz, (float)rayDir.x, (float)rayDir.z,
|
||||
// (float)tx_rx_rz, (float)tz_rx_rz);
|
||||
|
||||
int rx_rz_sign = (rayDir.x < 0) ^ (rayDir.z < 0);
|
||||
int hit = 0;
|
||||
|
||||
if(hitz && (!hitx || (tz_rx_rz < tx_rx_rz) ^ rx_rz_sign)) {
|
||||
if(t) {
|
||||
if(hitz == TOP)
|
||||
*t = num16::div_positive(snum(WORLD_SIZE / 2) - origin.z,
|
||||
rayDir.z);
|
||||
else
|
||||
*t = num16::div_positive(origin.z + snum(WORLD_SIZE / 2),
|
||||
-rayDir.z);
|
||||
}
|
||||
return hitz;
|
||||
if(hitz == TOP)
|
||||
*t = num16::div_positive(snum(WORLD_SIZE / 2) - origin.z,
|
||||
rayDir.z);
|
||||
else
|
||||
*t = num16::div_positive(origin.z + snum(WORLD_SIZE / 2),
|
||||
-rayDir.z);
|
||||
hit = hitz;
|
||||
}
|
||||
else if(hitx) {
|
||||
if(t) {
|
||||
if(hitx == RIGHT)
|
||||
*t = num16::div_positive(snum(WORLD_SIZE / 2) - origin.x,
|
||||
rayDir.x);
|
||||
else
|
||||
*t = num16::div_positive(origin.x + snum(WORLD_SIZE / 2),
|
||||
-rayDir.x);
|
||||
else if(__builtin_expect(hitx, 1)) {
|
||||
if(hitx == RIGHT)
|
||||
*t = num16::div_positive(snum(WORLD_SIZE / 2) - origin.x,
|
||||
rayDir.x);
|
||||
else
|
||||
*t = num16::div_positive(origin.x + snum(WORLD_SIZE / 2),
|
||||
-rayDir.x);
|
||||
hit = hitx;
|
||||
}
|
||||
else return 0;
|
||||
|
||||
/* Compute intersection with object plane */
|
||||
*collision_y = num(origin.y) + num(*t) * num(rayDir.y);
|
||||
|
||||
if(__builtin_expect(world->plane &&
|
||||
(*collision_y > world->plane->y - world->depth), 0)) {
|
||||
snum plane_y = snum(world->plane->y - world->depth);
|
||||
snum plane_t = (plane_y - origin.y) / rayDir.y;
|
||||
snum plane_x = origin.x + plane_t * rayDir.x;
|
||||
snum plane_z = origin.z + plane_t * rayDir.z;
|
||||
|
||||
plane_x = (plane_x + snum(WORLD_SIZE / 2)) * snum(5.0 / WORLD_SIZE);
|
||||
plane_z = (plane_z + snum(WORLD_SIZE / 2)) * snum(5.0 / WORLD_SIZE);
|
||||
int cell_x = plane_x.ifloor();
|
||||
int cell_z = plane_z.ifloor();
|
||||
|
||||
if((unsigned)cell_x < 5 && (unsigned)cell_z < 5) {
|
||||
if((world->plane->shape >> (5*cell_z + cell_x)) & 1) {
|
||||
*t = plane_t;
|
||||
*collision_y = world->plane->y - world->depth;
|
||||
return OBJECT_PLANE;
|
||||
}
|
||||
}
|
||||
return hitx;
|
||||
}
|
||||
|
||||
return 0;
|
||||
return hit;
|
||||
}
|
||||
|
||||
void render_fragment(struct camera const *camera, uint16_t *fragment,
|
||||
int y_start, int y_height)
|
||||
void render_fragment(struct camera const *camera, struct world const *world,
|
||||
uint16_t *fragment, int y_start, int y_height)
|
||||
{
|
||||
svec3 origin = svec3_of_vec3(camera->pos);
|
||||
svec3 forward = svec3_of_vec3(camera->forward);
|
||||
|
@ -170,74 +231,79 @@ void render_fragment(struct camera const *camera, uint16_t *fragment,
|
|||
svec3 rayDir_row = screen_center - origin
|
||||
+ snum(VHEIGHT/2 - y_start) * pixel_dy
|
||||
+ snum(0 - VWIDTH/2) * pixel_dx;
|
||||
/* printf("%f %f %f\n",
|
||||
(float)rayDir_row.x,
|
||||
(float)rayDir_row.y,
|
||||
(float)rayDir_row.z); */
|
||||
|
||||
for(int y = y_start; y < y_start + y_height; y++) {
|
||||
svec3 rayDir = rayDir_row;
|
||||
|
||||
for(int x = 0; x < VWIDTH; x++) {
|
||||
snum t;
|
||||
int obj = cast_ray(origin, rayDir, &t);
|
||||
int recolor = 0;
|
||||
snum collision_y;
|
||||
num coll_y;
|
||||
int obj = cast_ray(world, origin, rayDir, &t, &coll_y);
|
||||
bool darken = false;
|
||||
|
||||
if(obj == LEFT || obj == RIGHT) {
|
||||
if(__builtin_expect(
|
||||
world->mirror && (obj == LEFT || obj == RIGHT), 0)) {
|
||||
svec3 collision;
|
||||
collision.z = origin.z + t * rayDir.z;
|
||||
|
||||
if(collision.z >= snum(-WORLD_SIZE / 4)
|
||||
&& collision.z < snum(WORLD_SIZE / 4)) {
|
||||
/* Mirror covers only part of width of wall */
|
||||
bool ok_z = collision.z >= snum(-WORLD_SIZE / 4)
|
||||
&& collision.z < snum(WORLD_SIZE / 4);
|
||||
/* Mirror also does not go on forever */
|
||||
bool ok_y = world->mirror
|
||||
&& coll_y >= (world->mirror->begin - world->depth)
|
||||
&& coll_y < (world->mirror->end - world->depth);
|
||||
|
||||
if(ok_z && ok_y) {
|
||||
collision.x = origin.x + t * rayDir.x;
|
||||
collision.y = origin.y + t * rayDir.y;
|
||||
collision.y = snum(coll_y);
|
||||
rayDir.x = -rayDir.x;
|
||||
obj = cast_ray(collision, rayDir, &t);
|
||||
recolor = 1 + (obj == RIGHT);
|
||||
collision_y = collision.y + t * rayDir.y;
|
||||
obj = cast_ray(world, collision, rayDir, &t, &coll_y);
|
||||
darken = true;
|
||||
rayDir.x = -rayDir.x;
|
||||
}
|
||||
else {
|
||||
collision_y = origin.y + t * rayDir.y;
|
||||
}
|
||||
}
|
||||
else {
|
||||
collision_y = origin.y + t * rayDir.y;
|
||||
}
|
||||
|
||||
static uint16_t const colors[5] = {
|
||||
0x0000, 0xf800, 0x07e0, 0x001f, 0xffe0,
|
||||
static uint16_t const colors[6] = {
|
||||
RGB(3, 4, 8),
|
||||
RGB(3, 4, 8), /* Left */
|
||||
RGB(5, 6, 9), /* Top */
|
||||
RGB(7, 8, 11), /* Right */
|
||||
RGB(5, 6, 9), /* Bottom */
|
||||
RGB(31, 0, 0), /* Object plane */
|
||||
};
|
||||
uint16_t color = colors[obj];
|
||||
|
||||
/* Don't show neons that are too far to avoid flickering */
|
||||
if(collision_y < 64) {
|
||||
snum neon_pos = snum(camera->neon_position);
|
||||
if(coll_y < 64 && obj != OBJECT_PLANE) {
|
||||
snum neon_pos = world->neon_position;
|
||||
if(obj == TOP || obj == BOTTOM)
|
||||
neon_pos += snum(16);
|
||||
snum neon = collision_y - neon_pos;
|
||||
neon.v = neon.v & (snum(32).v - 1);
|
||||
neon_pos += world->neon_period * snum(0.5);
|
||||
snum neon = snum(coll_y) - neon_pos;
|
||||
neon.v = neon.v & (world->neon_period.v - 1);
|
||||
/* Also make neons larger when they're far to further avoid
|
||||
flickering */
|
||||
snum neon_size = 1;
|
||||
if(collision_y > 20)
|
||||
neon_size += ((collision_y-snum(20)) * snum(1.0/4));
|
||||
if(coll_y > 20)
|
||||
neon_size += ((snum(coll_y)-snum(20)) * snum(1.0/4));
|
||||
if(neon <= neon_size)
|
||||
color = 0xffff;
|
||||
}
|
||||
else if(__builtin_expect(coll_y >= 64, 0)) {
|
||||
if(coll_y > 128)
|
||||
color = (color & 0xc718) >> 3;
|
||||
else if(coll_y > 96)
|
||||
color = (color & 0xe79c) >> 2;
|
||||
else
|
||||
color = (color & 0xf7de) >> 1;
|
||||
}
|
||||
|
||||
if(recolor == 1)
|
||||
color = ((color & 0xf7de) >> 1) + (0xf000 >> 1);
|
||||
if(recolor == 2)
|
||||
color = ((color & 0xf7de) >> 1) + (0x001f >> 1);
|
||||
|
||||
if(darken)
|
||||
color = (color & 0xf7de) >> 1;
|
||||
*fragment++ = color;
|
||||
rayDir += pixel_dx;
|
||||
}
|
||||
|
||||
rayDir_row -= pixel_dy;
|
||||
}
|
||||
|
||||
// printf("%f %f %f\n", (float)rayDir.x, (float)rayDir.y, (float)rayDir.z);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue