fix rockets a bit

This commit is contained in:
PoliEcho 2025-08-17 14:37:30 +02:00
parent 91001e09ba
commit 83ef67ad28
8 changed files with 54 additions and 39 deletions

1
.gitignore vendored
View File

@ -1,5 +1,4 @@
build/
.cache/
compile_commands.json
assets/rocket_orig.bmp
src/UEFI_fireworks/rocket.c

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 KiB

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

BIN
assets/rocket_orig.bmp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

View File

@ -19,7 +19,7 @@
#include <Uefi.h>
#include <stdint.h>
EFI_GRAPHICS_OUTPUT_BLT_PIXEL night_sky =
COLOR_FROM_HEX(0x11095e); // this cannot be const becose EDK2 said so
COLOR_FROM_HEX(0x090531); // this cannot be const becose EDK2 said so
firework_instance create_firework();
EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput = NULL;
@ -135,7 +135,7 @@ firework_instance create_firework() {
firework_instance firework;
UINT32 random;
fill_random_bytes(&random, sizeof(random));
firework.max_r = (random % 200) + 1; // 1 to 200, avoiding 0
firework.max_r = (random % 190) + 10; // 10 to 200,
for (UINT8 i = 0; i < ARRAY_SIZE(firework.color); i++) {
fill_random_bytes(&firework.color[i],
@ -152,6 +152,6 @@ firework_instance create_firework() {
firework.rocket.x = firework.x + rocket_asset.width / 2;
firework.rocket.y = GraphicsOutput->Mode->Info->VerticalResolution;
firework.status = LAUNCHING; // TODO set to LAUNCHING when implemented
firework.status = LAUNCHING;
return firework;
}

View File

@ -1,19 +1,23 @@
#include "Base.h"
#include "Library/BaseMemoryLib.h"
#include "Library/MemoryAllocationLib.h"
#include "Library/UefiLib.h"
#include "ProcessorBind.h"
#include "bmp.h"
#include "const.h"
#include "global.h"
#include "time.h"
#include "types.h"
#include <../MdeModulePkg/Include/Library/BmpSupportLib.h>
#include <Library/UefiApplicationEntryPoint.h>
#include <Protocol/GraphicsOutput.h>
#include <alloca.h>
void draw_pixel(const UINT32 x, const UINT32 y,
const EFI_GRAPHICS_OUTPUT_BLT_PIXEL pixel) {
if (x > GraphicsOutput->Mode->Info->HorizontalResolution ||
y > GraphicsOutput->Mode->Info
->VerticalResolution) { // ignore when out of bounds
if (x >= GraphicsOutput->Mode->Info->HorizontalResolution ||
y >= GraphicsOutput->Mode->Info
->VerticalResolution) { // ignore when out of bounds
return;
}
UINTN framebuffer_offset =
@ -109,9 +113,10 @@ BOOLEAN step_firework(firework_instance *firework) {
}
rocket_blt rocket_asset;
EFI_GRAPHICS_OUTPUT_BLT_PIXEL **mask_stack;
BOOLEAN **rocket_alfa_mask;
UINT32 *rocket_clean_up_mask;
void init_rocket_blt() {
EFI_STATUS Status = TranslateBmpToGopBlt(
assets_rocket_bmp, assets_rocket_bmp_len, &rocket_asset.blt,
@ -120,38 +125,49 @@ void init_rocket_blt() {
Print(L"Failed to load rocket asset: %r\n", Status);
Exit(Status);
}
rocket_clean_up_mask = AllocatePool(rocket_asset.width * sizeof(location));
rocket_alfa_mask = AllocateZeroPool(rocket_asset.height * sizeof(BOOLEAN *));
for (UINT32 i = 0; i < rocket_asset.height; i++) {
rocket_alfa_mask[i] = AllocatePool(rocket_asset.width * sizeof(BOOLEAN));
for (UINT32 j = 0; j < rocket_asset.width; j++) {
if (rocket_asset.blt[i * rocket_asset.width + j].Blue == 0 &&
rocket_asset.blt[i * rocket_asset.width + j].Green == 0 &&
rocket_asset.blt[i * rocket_asset.width + j].Red == 0) {
rocket_alfa_mask[i][j] = FALSE;
} else {
rocket_alfa_mask[i][j] = TRUE;
rocket_clean_up_mask[j] = i + 1; // build the cleanup mask
}
}
}
}
void draw_rocket(location *rocket) {
for (UINT32 i = 0; i < rocket_asset.width; i++) {
for (UINT32 j = 0; j < rocket_asset.height; j++) {
if (rocket_alfa_mask[j][i]) {
draw_pixel(i + rocket->x, j + rocket->y,
rocket_asset.blt[j * rocket_asset.width + i]);
}
}
}
}
BOOLEAN step_rocket(rocket_instance *rocket, UINT32 max_y) {
GraphicsOutput->Blt(GraphicsOutput,
rocket_asset.blt, // BltBuffer
EfiBltBufferToVideo, // BltOperation
0, // src X
0, // src Y
rocket->x, // dst X
rocket->y, // dst Y
rocket_asset.width, rocket_asset.height,
0 // unused Delta
);
BOOLEAN step_rocket(location *rocket, UINT32 max_y) {
draw_rocket(rocket);
for (UINT8 i = 0; i < rocket_asset.width; i++) {
draw_pixel(rocket->x + i, rocket->y + rocket_clean_up_mask[i], night_sky);
}
if (rocket->y <= max_y) {
GraphicsOutput->Blt(
GraphicsOutput,
&night_sky, // BltBuffer
EfiBltVideoFill, // BltOperation
0, // SourceX
0, // SourceY
rocket->x, // DestinationX
rocket->y, // DestinationY
rocket_asset.width, // Width
rocket_asset.height + 1, // Height // remove trail from previous frame
0 // Delta (not used for fill operations)
);
// remove rocket
for (UINT32 i = 0; i < rocket_asset.width; i++) {
for (UINT32 j = 0; j < rocket_asset.height; j++) {
if (rocket_alfa_mask[j][i]) {
draw_pixel(i + rocket->x, j + rocket->y, night_sky);
}
}
}
return FALSE;
} else {
for (UINT8 i = 0; i < rocket_asset.width; i++) {
draw_pixel(rocket->x + i, rocket->y + rocket_asset.height, night_sky);
}
rocket->y--;
return TRUE;
}

View File

@ -6,4 +6,4 @@ void draw_circle(int xc, int yc, int r,
void clear_screen();
BOOLEAN step_firework(firework_instance *firework);
void init_rocket_blt();
BOOLEAN step_rocket(rocket_instance *rocket, UINT32 max_y);
BOOLEAN step_rocket(location *rocket, UINT32 max_y);

View File

@ -7,7 +7,7 @@
typedef struct {
UINT32 x;
UINT32 y;
} rocket_instance;
} location;
typedef struct {
enum firework_status status; // IF INACTIVE can be overwriten
@ -17,7 +17,7 @@ typedef struct {
UINT16 r[3];
EFI_GRAPHICS_OUTPUT_BLT_PIXEL color[3];
UINT16 cleanup_r;
rocket_instance rocket;
location rocket;
} firework_instance;
typedef struct {
@ -25,4 +25,4 @@ typedef struct {
UINTN blt_size;
UINTN height;
UINTN width;
} rocket_blt;
} rocket_blt;