I found myself wanting to draw a sprite but flipped on the x-axis. Yes, I know that for the best performance, I should create the flipped sprite and draw it directly.
Anyway, here's what I came up with at first:
Code:
The above is inefficient: the framerate dropped by 10%. After pleading the #c-on-the-ce channel on the Cemetech Discord, calc84maniac, LogicalJoe, c4ooo, and fghsgh gave me some tips to optimize it a little. I now have this:
Code:
I managed to claw back a few frames!
I do plan on writing a no-clip version and a non-transparency version for even faster performance, as well as variants for flipping on the y-axis. And a few more nice-to-have graphics functions... I'll post them here once I get them working. And I'll prepare a few carving knives so that you guys can gut me thoroughly for being so wasteful with my calculator's CPU cycles.
Is there anything else that I can do to make this faster? Is there a faster way of drawing a sprite flipped on the x-axis without generating a flipped sprite beforehand?
Anyway, here's what I came up with at first:
Code:
void draw_x_flipped_sprite(gfx_sprite_t* sprite, int dest_x, int dest_y, bool transparency) {
char* data = (char*) sprite;
uint8_t width = data[0];
uint8_t height = data[1];
for (int y = 0; y < height; y++) {
int draw_y = dest_y + y;
// clipping check in the y direction
if (draw_y < 0 || draw_y >= LCD_HEIGHT) {
continue;
}
for (int x = 0; x < width; x++) {
int draw_x = dest_x + x;
// clipping check in the x direction
if (draw_x < 0 || draw_x >= LCD_WIDTH) {
continue;
}
char pixel = data[y * width + width - x + 1];
// transparency check
if (transparency && pixel == MAGENTA) {
continue;
} else {
gfx_vbuffer[draw_y][draw_x] = pixel;
}
}
}
}
The above is inefficient: the framerate dropped by 10%. After pleading the #c-on-the-ce channel on the Cemetech Discord, calc84maniac, LogicalJoe, c4ooo, and fghsgh gave me some tips to optimize it a little. I now have this:
Code:
void draw_x_flipped_sprite(gfx_sprite_t* sprite, int dest_x, int dest_y, bool transparency) {
// kinda optimized compared to the inefficient version
// thanks, calc84maniac, c4ooo, LogicalJoe, fghsgh!
// all of you helped me to squeeze a few more frames out
char* data = (char*) sprite;
uint8_t width = data[0];
uint8_t height = data[1];
// clipping checks
// we might end up drawing out of the bounds of uint8_t in the x direction
int start_x = 0 > dest_x ? 0 : dest_x;
int start_y = 0 > dest_y ? 0 : dest_y;
int end_x = LCD_WIDTH <= (dest_x + width) ? (LCD_WIDTH - 1) : (dest_x + width);
int end_y = LCD_HEIGHT <= (dest_y + width) ? (LCD_HEIGHT - 1) : (dest_y + height);
int source_x_left_bound = dest_x < 0 ? (width + dest_x - 1) : 0;
int source_x_right_bound = (dest_x + width) >= LCD_WIDTH ? (LCD_WIDTH - dest_x) : width;
int source_y_top_bound = dest_y < 0 ? (height + dest_y - 1) : 0;
int source_y_bottom_bound = (dest_y + height) >= LCD_HEIGHT ? (LCD_HEIGHT - dest_y) : height;
int source_pixel_pointer = source_y_top_bound * width + 1;
uint8_t* destination_pointer = &(gfx_vbuffer[start_y][start_x]);
int destination_offset = &(gfx_vbuffer[1][start_x]) - &(gfx_vbuffer[0][end_x]);
for (int y = start_y; y < end_y; y++, source_pixel_pointer += width + source_x_right_bound, destination_pointer += destination_offset) {
for (int x = start_x; x < end_x; x++, source_pixel_pointer--, destination_pointer++) {
char pixel = data[source_pixel_pointer];
if (transparency && (pixel == MAGENTA)) {
continue;
} else {
*(destination_pointer) = pixel;
}
}
}
}
I managed to claw back a few frames!

Is there anything else that I can do to make this faster? Is there a faster way of drawing a sprite flipped on the x-axis without generating a flipped sprite beforehand?