ohsp

Prototype for a game with dual thruster controls.
Log | Files | Refs | LICENSE

commit 74281c2d2a86be4aec63e6dd16dd722bcd4ef3dc
parent 7ea4f54b70e07ebc229e443cc818e8d2d10d8eac
Author: Amin Mesbah <mesbahamin@gmail.com>
Date:   Sun, 10 Dec 2017 23:04:30 -0800

Render lines in and between any octant

I did this in the most silly and straightforward way possible. It's
begging for some compression.

I had to disable the `-Wfloat-equal` compiler argument because it didn't
like me comparing floats to 0.0f, which is understandable. However this
rendering code will be replaced anyway once I start using Opengl, so
being careful with floats doesn't matter too much in this case.

However, I really do need to read about floats and how to do safe
comparisons...

Diffstat:
MMakefile | 2+-
Msrc/game.c | 178++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-------
2 files changed, 165 insertions(+), 15 deletions(-)

diff --git a/Makefile b/Makefile @@ -1,5 +1,5 @@ CC = gcc -CFLAGS = -std=c99 -Wall -Wextra -Wfloat-equal -Wshadow -Wswitch-enum -Wno-unused-parameter +CFLAGS = -std=c99 -Wall -Wextra -Wshadow -Wswitch-enum -Wno-unused-parameter LDFLAGS = $(SDL_LDFLAGS) -ldl -lm SDL_CFLAGS := $(shell sdl2-config --cflags) diff --git a/src/game.c b/src/game.c @@ -2,6 +2,7 @@ // TODO: remove this #include <math.h> +#include <assert.h> #include <stdbool.h> #include <stdio.h> @@ -133,36 +134,185 @@ void game_render_line(struct OffscreenBuffer *buffer, float x0, float y0, float float delta_x = x1 - x0; float delta_y = y1 - y0; - if (0 == (int)delta_x) + if (0.0f == delta_x) // vertical { - for (int y = y0; y <= y1; ++y) + for (int y = fminf(y0, y1); y <= fmaxf(y0, y1); ++y) { game_set_pixel(buffer, x0, y, color); } } - else if (0 == (int)delta_y) + else if (0.0f == delta_y) // horizontal { - for (int x = x0; x <= x1; ++x) + for (int x = fminf(x0, x1); x <= fmaxf(x0, x1); ++x) { game_set_pixel(buffer, x, y0, color); } } else { - // Bresenham's line algorithm - float delta_err = fabsf(delta_y / delta_x); - float error = 0.0; - int y = y0; - for (int x = x0; x <= x1; ++x) + bool quadrant_01 = (delta_x > 0.0f && delta_y <= 0.0f); + bool quadrant_02 = (delta_x <= 0.0f && delta_y < 0.0f); + bool quadrant_03 = (delta_x < 0.0f && delta_y >= 0.0f); + bool quadrant_04 = (delta_x >= 0.0f && delta_y > 0.0f); + bool bigger_delta_x = fabsf(delta_x) >= fabsf(delta_y); + bool bigger_delta_y = !bigger_delta_x; + + if(bigger_delta_x && quadrant_01) + { + // octant 1 + // Bresenham's line algorithm + assert(0.0f != delta_x); + float delta_err = fabsf(delta_y / delta_x); + float error = 0.0f; + int y = y0; + for (int x = x0; x <= x1; ++x) + { + game_set_pixel(buffer, x, y, color); + error += delta_err; + if (error >= 0.5f) + { + y -= 1; + error -= 1.0f; + } + } + } + else if (bigger_delta_x && quadrant_02) + { + // octant 4 + // Bresenham's line algorithm + assert(0.0f != delta_x); + float delta_err = fabsf(delta_y / delta_x); + float error = 0.0f; + int y = y0; + for (int x = x0; x >= x1; --x) + { + game_set_pixel(buffer, x, y, color); + error += delta_err; + if (error >= 0.5f) + { + y -= 1; + error -= 1.0f; + } + } + } + else if (bigger_delta_x && quadrant_03) + { + // octant 5 + // Bresenham's line algorithm + assert(0.0f != delta_x); + float delta_err = fabsf(delta_y / delta_x); + float error = 0.0f; + int y = y0; + for (int x = x0; x >= x1; --x) + { + game_set_pixel(buffer, x, y, color); + error += delta_err; + if (error >= 0.5f) + { + y += 1; + error -= 1.0f; + } + } + } + else if (bigger_delta_x && quadrant_04) { - game_set_pixel(buffer, x, y, color); - error += delta_err; - if (error >= 0.5f) + // octant 8 + // Bresenham's line algorithm + assert(0.0f != delta_x); + float delta_err = fabsf(delta_y / delta_x); + float error = 0.0f; + int y = y0; + for (int x = x0; x <= x1; ++x) { - y += 1; - error -= 1.0f; + game_set_pixel(buffer, x, y, color); + error += delta_err; + if (error >= 0.5f) + { + y += 1; + error -= 1.0f; + } } } + else if (bigger_delta_y && quadrant_01) + { + // octant 2 + // Bresenham's line algorithm + assert(0.0f != delta_y); + float delta_err = fabsf(delta_x / delta_y); + float error = 0.0f; + int x = x0; + for (int y = y0; y >= y1; --y) + { + game_set_pixel(buffer, x, y, color); + error += delta_err; + if (error >= 0.5f) + { + x += 1; + error -= 1.0f; + } + } + } + else if (bigger_delta_y && quadrant_02) + { + // octant 3 + // Bresenham's line algorithm + assert(0.0f != delta_y); + float delta_err = fabsf(delta_x / delta_y); + float error = 0.0f; + int x = x0; + for (int y = y0; y >= y1; --y) + { + game_set_pixel(buffer, x, y, color); + error += delta_err; + if (error >= 0.5f) + { + x -= 1; + error -= 1.0f; + } + } + } + else if (bigger_delta_y && quadrant_03) + { + // octant 6 + // Bresenham's line algorithm + assert(0.0f != delta_y); + float delta_err = fabsf(delta_x / delta_y); + float error = 0.0f; + int x = x0; + for (int y = y0; y <= y1; ++y) + { + game_set_pixel(buffer, x, y, color); + error += delta_err; + if (error >= 0.5f) + { + x -= 1; + error -= 1.0f; + } + } + } + else if (bigger_delta_y && quadrant_04) + { + // octant 7 + // Bresenham's line algorithm + assert(0.0f != delta_y); + float delta_err = fabsf(delta_x / delta_y); + float error = 0.0f; + int x = x0; + for (int y = y0; y <= y1; ++y) + { + game_set_pixel(buffer, x, y, color); + error += delta_err; + if (error >= 0.5f) + { + x += 1; + error -= 1.0f; + } + } + } + else + { + printf("ERROR: Your vector is as some angle you didn't catch!!!"); + } } }