Make arrays 1D and get rid of unnecessary bounds checks

This commit is contained in:
UnknownShadow200 2021-07-03 18:51:54 +10:00
parent cc430d45fd
commit e06368be97
1 changed files with 18 additions and 17 deletions

View File

@ -154,20 +154,21 @@ static void WaterAnimation_Tick(void) {
/*########################################################################################################################* /*########################################################################################################################*
*----------------------------------------------------Lava animation-------------------------------------------------------* *----------------------------------------------------Fire animation-------------------------------------------------------*
*#########################################################################################################################*/ *#########################################################################################################################*/
/* Based off the notes in https://github.com/UnknownShadow200/ClassiCube/issues/861
Fire animation documented by ConstaChugga, big thanks!
*/
#define FIRE_SIZE 16 #define FIRE_SIZE 16
#define FIRE_WIDTH FIRE_SIZE #define FIRE_WIDTH FIRE_SIZE
#define FIRE_HEIGHT (FIRE_SIZE + 4) #define FIRE_HEIGHT (FIRE_SIZE + 4)
static float front_buffer[FIRE_HEIGHT][FIRE_WIDTH]; static float front_buffer[FIRE_WIDTH * FIRE_HEIGHT];
static float back_buffer[FIRE_HEIGHT][FIRE_WIDTH]; static float back_buffer[FIRE_WIDTH * FIRE_HEIGHT];
static RNGState F_rnd; static RNGState F_rnd;
#define FIRE_DECAY_BASE 18.0f #define FIRE_DECAY_BASE 18.0f
#define FIRE_DECAY_AMP 1.06f #define FIRE_DECAY_AMP 1.06f
static float mote_neighbor_decay_base = 18.0f;
static float mote_decay_amp = 1.06f;
#include <math.h> #include <math.h>
static BitmapCol Fire_Color(float v) { static BitmapCol Fire_Color(float v) {
@ -193,13 +194,15 @@ static float Fire_Convolute(int x, int y) {
float mote_decay = FIRE_DECAY_BASE * FIRE_DECAY_AMP; float mote_decay = FIRE_DECAY_BASE * FIRE_DECAY_AMP;
mote_decay += (1 * 2 + 1) * (1 + 1); mote_decay += (1 * 2 + 1) * (1 + 1);
float heat = front_buffer[(y + 1) % FIRE_HEIGHT][x] * FIRE_DECAY_BASE; /* bounds check on Y can be eliminated, since Fire_Convolute */
/* is never executed on the bottom/highest row of fire */
float heat = front_buffer[(y + 1)*FIRE_SIZE+x] * FIRE_DECAY_BASE;
int u, v; int u, v;
for (u = x - 1; u <= x + 1; u++) { for (u = x - 1; u <= x + 1; u++) {
for (v = y; v <= y + 1; v++) { for (v = y; v <= y + 1; v++) {
if ((u >= 0 && u < FIRE_WIDTH) && (v >= 0 && v < FIRE_HEIGHT)) if (u >= 0 && u < FIRE_WIDTH)
heat += front_buffer[v][u]; heat += front_buffer[v*FIRE_SIZE+u];
} }
} }
return heat / mote_decay; return heat / mote_decay;
@ -208,27 +211,25 @@ static float Fire_Convolute(int x, int y) {
static void FireAnimation_Tick(void) { static void FireAnimation_Tick(void) {
BitmapCol pixels[FIRE_SIZE * FIRE_SIZE]; BitmapCol pixels[FIRE_SIZE * FIRE_SIZE];
struct Bitmap bmp; struct Bitmap bmp;
int x, y; int i, x, y;
for (x = 0; x < FIRE_WIDTH; x++) { for (x = 0; x < FIRE_WIDTH; x++) {
for (y = 0; y < FIRE_HEIGHT; y++) { for (y = 0; y < FIRE_HEIGHT; y++) {
if (y == FIRE_HEIGHT - 1) { if (y == FIRE_HEIGHT - 1) {
/* base layer is an infinite ignition source */ /* base layer is an infinite ignition source */
back_buffer[y][x] = Fire_Life(); back_buffer[y*FIRE_SIZE+x] = Fire_Life();
} else { } else {
back_buffer[y][x] = Fire_Convolute(x, y); back_buffer[y*FIRE_SIZE+x] = Fire_Convolute(x, y);
} }
} }
} }
for (y = 0; y < FIRE_SIZE; y++) { for (i = 0; i < FIRE_SIZE * FIRE_SIZE; i++) {
for (x = 0; x < FIRE_SIZE; x++) { float v = front_buffer[i];
float v = front_buffer[y][x]; pixels[i] = Fire_Color(v);
pixels[y*FIRE_SIZE + x] = Fire_Color(v);
}
} }
float tmp[FIRE_HEIGHT][FIRE_WIDTH]; float tmp[FIRE_HEIGHT * FIRE_WIDTH];
Mem_Copy(tmp, back_buffer, sizeof(tmp)); Mem_Copy(tmp, back_buffer, sizeof(tmp));
Mem_Copy(back_buffer, front_buffer, sizeof(tmp)); Mem_Copy(back_buffer, front_buffer, sizeof(tmp));
Mem_Copy(front_buffer, tmp, sizeof(tmp)); Mem_Copy(front_buffer, tmp, sizeof(tmp));