diff --git a/.gitignore b/.gitignore index 5fa985f..cbc9d2a 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,4 @@ build/ .cache/ compile_commands.json -assets/rocket_orig.bmp src/UEFI_fireworks/rocket.c \ No newline at end of file diff --git a/assets/rocket.bmp b/assets/rocket.bmp index e9c991a..82d9b91 100644 Binary files a/assets/rocket.bmp and b/assets/rocket.bmp differ diff --git a/assets/rocket.xcf b/assets/rocket.xcf index 8944cba..34917a2 100644 Binary files a/assets/rocket.xcf and b/assets/rocket.xcf differ diff --git a/assets/rocket_orig.bmp b/assets/rocket_orig.bmp new file mode 100644 index 0000000..aa9f6cf Binary files /dev/null and b/assets/rocket_orig.bmp differ diff --git a/src/UEFI_fireworks/UefiMain.c b/src/UEFI_fireworks/UefiMain.c index 5205d7e..16e7b70 100644 --- a/src/UEFI_fireworks/UefiMain.c +++ b/src/UEFI_fireworks/UefiMain.c @@ -19,7 +19,7 @@ #include #include 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; } \ No newline at end of file diff --git a/src/UEFI_fireworks/drawing.c b/src/UEFI_fireworks/drawing.c index 8a154bc..8a4a210 100644 --- a/src/UEFI_fireworks/drawing.c +++ b/src/UEFI_fireworks/drawing.c @@ -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 #include +#include 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; } diff --git a/src/UEFI_fireworks/drawing.h b/src/UEFI_fireworks/drawing.h index cbb8d5d..74d5088 100644 --- a/src/UEFI_fireworks/drawing.h +++ b/src/UEFI_fireworks/drawing.h @@ -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); \ No newline at end of file +BOOLEAN step_rocket(location *rocket, UINT32 max_y); \ No newline at end of file diff --git a/src/UEFI_fireworks/types.h b/src/UEFI_fireworks/types.h index eae1714..df5b71b 100644 --- a/src/UEFI_fireworks/types.h +++ b/src/UEFI_fireworks/types.h @@ -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; \ No newline at end of file +} rocket_blt;