Compare commits

...

8 Commits

Author SHA1 Message Date
PoliEcho 92e474853b Update README.md 2025-08-19 19:33:50 +00:00
PoliEcho 24e7c443a1 fix aarch64 compilation 2025-08-19 21:13:02 +02:00
PoliEcho 37f63d51b9 README additions 2025-08-19 20:11:57 +02:00
PoliEcho 09ff9f8f19 some misc changes 2025-08-19 19:30:50 +02:00
PoliEcho 83df1a6048 Update README.md 2025-08-19 17:05:27 +02:00
PoliEcho 36a7c9066a misc changes 2025-08-19 16:38:32 +02:00
PoliEcho 9b768a4e9e README and build.sh changes 2025-08-19 16:35:16 +02:00
PoliEcho 868d27cecb update edk2 2025-08-18 23:16:58 +02:00
7 changed files with 184 additions and 35 deletions
+66 -19
View File
@@ -1,41 +1,88 @@
# UEFI Fireworks # UEFI Fireworks
### Retro fireworks you can run on your modern UEFI system
Simple automatic fireworks app that runs on your UEFI firmware with basic controls.
Primary purpose of this app is just to look at something nice.
> [!CAUTION]
> This app may cause epileptic seizures in people with epilepsy.
> $\color{red}{\text{!!!If you have a history of seizures, do not use this program!!!}}$
> I don't know if colorful expanding circles can cause seizures and i don't want for anyone to get hurt
## How to build ## How to build
> [!IMPORTANT]
> You will need these programs to compile:
> - git
> - gcc
> - xxd
> - ImageMagick (if you changed the firework image)
```bash ```bash
git submodule update --init --recursive git submodule update --init --recursive
cd edk2 cd edk2
source edksetup.sh source edksetup.sh
make -C BaseTools make -C BaseTools
cd .. cd ..
./build.sh ./build.sh # to build for a different arch than X64 change TARGET_ARCH in build.sh
``` ```
## How to use ## How to use
### On VM ### Download release
run ```./test.sh # only works on AMD64``` to run in VM using QEMU #### On real hardware
### On Real hardware If you have an amd64 (x86_64) UEFI computer,
download the release and copy UEFI_fireworks.efi to /EFI/BOOT/bootx64.efi (case-insensitive).
copy ```edk2/Build/UEFI_fireworks/DEBUG_GCC5/<YOUR ARCH>/UEFI_fireworks.efi``` to FAT32 or FAT16 USB at location: #### On VM
You will need OVMF firmware; you can get it here: https://qemu.weilnetz.de/test/ovmf/usr/share/OVMF/OVMF_CODE_4M.fd
Run:
```bash
qemu-system-x86_64 -machine type=q35,accel=kvm -drive if=pflash,format=raw,readonly=on,file="$OVMF_CODE_PATH" -hda fat:rw:build -boot order=c -smp 4 -s -serial mon:stdio
```
### Build
#### On VM
You will need OVMF firmware; you can get it here: https://qemu.weilnetz.de/test/ovmf/usr/share/OVMF/OVMF_CODE_4M.fd
Run:
```bash
./test.sh $OVMF_CODE_PATH # only works on AMD64
```
to run in a VM using QEMU.
#### On real hardware
Copy:
```
edk2/Build/UEFI_fireworks/DEBUG_GCC5//UEFI_fireworks.efi
```
to a FAT32 or FAT16 USB at the following location:
| Architecture | Default Boot Path | | Architecture | Default Boot Path |
|--------------|-------------------| | --------------- | ------------------------ |
| **x86_64 (AMD64)** | `\EFI\BOOT\BOOTX64.EFI` | | x86_64 (AMD64) | `/EFI/BOOT/BOOTX64.EFI` |
| **x86 (IA32)** | `\EFI\BOOT\BOOTIA32.EFI` | | x86 (IA32) | `/EFI/BOOT/BOOTIA32.EFI` |
| **ARM64 (AArch64)** | `\EFI\BOOT\BOOTAA64.EFI` | | ARM64 (AARCH64) | `/EFI/BOOT/BOOTAA64.EFI` |
| **ARM (32-bit)** | `\EFI\BOOT\BOOTARM.EFI` | | ARM (32-bit) | `/EFI/BOOT/BOOTARM.EFI` |
## Controling ## Controlling
| Key | Action | Note | | Key | Action | Note |
|-----|--------|------| | ---------- | ------------ | ---------------------------------- |
| ARROW_UP | speed up | delays under 1ms may be unrelayable | | ARROW_UP | speed up | delays under 1ms may be unreliable |
| ARROW_DOWN | slow down | max delay is about UINT32_MAXμs | | ARROW_DOWN | slow down | max delay is about UINT32_MAX μs |
| PAGE_UP | speed up | 10x step | | PAGE_UP | speed up | 10× step |
| PAGE_DOWN | speed down | 10x step | | PAGE_DOWN | slow down | 10× step |
| Home key | reset speed | reset frame delay to 10ms | | Home | reset speed | reset frame delay to 10ms |
| Delete key | clear screen | | | Delete | clear screen | |
## Showcase
In QEMU/KVM
https://github.com/user-attachments/assets/275e28aa-eb2e-4348-ac08-95f909c46a1f
+1 -1
View File
@@ -4,7 +4,7 @@
PLATFORM_VERSION = 1.0 PLATFORM_VERSION = 1.0
DSC_SPECIFICATION = 0x00010005 DSC_SPECIFICATION = 0x00010005
OUTPUT_DIRECTORY = Build/UEFI_fireworks OUTPUT_DIRECTORY = Build/UEFI_fireworks
SUPPORTED_ARCHITECTURES = X64 SUPPORTED_ARCHITECTURES = X64|IA32|AARCH64
BUILD_TARGETS = DEBUG|RELEASE BUILD_TARGETS = DEBUG|RELEASE
SKUID_IDENTIFIER = DEFAULT SKUID_IDENTIFIER = DEFAULT
+9 -6
View File
@@ -1,17 +1,20 @@
#!/bin/bash #!/bin/bash
export PACKAGES_PATH=$PWD:$PWD/edk2 export PACKAGES_PATH=$PWD:$PWD/edk2
export TARGET_ARCH=X64
# export GCC5_AARCH64_PREFIX=aarch64-linux-gnu- # uncomment for AARCH64 crosscompilation or you can use
# export GCC5_AARCH64_PREFIX=aarch64-none-elf-
magick assets/rocket_orig.bmp -type TrueColor -define bmp:format=bmp3 -compress None assets/rocket.bmp magick assets/rocket_orig.bmp -type TrueColor -define bmp:format=bmp3 -compress None assets/rocket.bmp
xxd -i assets/rocket.bmp > src/UEFI_fireworks/rocket.c xxd -i assets/rocket.bmp > src/UEFI_fireworks/rocket.c
if [ "$1" == "debug" ]; then if [ "$1" == "debug" ]; then
build -a X64 -t GCC5 -p UEFI_fireworks.dsc -b DEBUG build -a $TARGET_ARCH -t GCC5 -p UEFI_fireworks.dsc -b DEBUG
else else
build -a X64 -t GCC5 -p UEFI_fireworks.dsc -b RELEASE build -a $TARGET_ARCH -t GCC5 -p UEFI_fireworks.dsc -b RELEASE
fi fi
mkdir -p build/EFI/BOOT/ mkdir -p build/EFI/BOOT/
if [ "$1" == "debug" ]; then if [ "$1" == "debug" ]; then
cp edk2/Build/UEFI_fireworks/DEBUG_GCC5/X64/UEFI_fireworks.efi build/ cp -v $(find edk2/Build/UEFI_fireworks/DEBUG_GCC5/ -name "UEFI_fireworks.efi" -type f | head -1) build/
cp edk2/Build/UEFI_fireworks/DEBUG_GCC5/X64/UEFI_fireworks.efi build/EFI/BOOT/BOOTX64.EFI cp -v $(find edk2/Build/UEFI_fireworks/DEBUG_GCC5/ -name "UEFI_fireworks.efi" -type f | head -1) build/EFI/BOOT/BOOTX64.EFI
else else
cp edk2/Build/UEFI_fireworks/RELEASE_GCC5/X64/UEFI_fireworks.efi build/ cp -v $(find edk2/Build/UEFI_fireworks/RELEASE_GCC5/ -name "UEFI_fireworks.efi" -type f | head -1) build/
cp edk2/Build/UEFI_fireworks/RELEASE_GCC5/X64/UEFI_fireworks.efi build/EFI/BOOT/BOOTX64.EFI cp -v $(find edk2/Build/UEFI_fireworks/RELEASE_GCC5/ -name "UEFI_fireworks.efi" -type f | head -1) build/EFI/BOOT/BOOTX64.EFI
fi fi
+1 -1
Submodule edk2 updated: 808f1f1f87...d46aa46c83
+4 -1
View File
@@ -6,13 +6,16 @@
VERSION_STRING = 1.0 VERSION_STRING = 1.0
ENTRY_POINT = UefiMain ENTRY_POINT = UefiMain
[Sources] [Sources.Common]
UefiMain.c UefiMain.c
drawing.c drawing.c
rng.c rng.c
time.c time.c
rocket.c rocket.c
[Sources.AARCH64]
memcpy.c
[Packages] [Packages]
edk2/MdePkg/MdePkg.dec edk2/MdePkg/MdePkg.dec
+2 -2
View File
@@ -52,8 +52,8 @@ EFI_STATUS EFIAPI UefiMain(IN EFI_HANDLE imgHandle,
return EFI_NOT_FOUND; return EFI_NOT_FOUND;
} }
framebuffer = framebuffer = (EFI_GRAPHICS_OUTPUT_BLT_PIXEL *)(UINTN)
(EFI_GRAPHICS_OUTPUT_BLT_PIXEL *)GraphicsOutput->Mode->FrameBufferBase; GraphicsOutput->Mode->FrameBufferBase;
init_rng(); init_rng();
init_rocket_blt(); init_rocket_blt();
+96
View File
@@ -0,0 +1,96 @@
#include <Library/BaseLib.h>
#include <Uefi.h>
VOID *memcpy(VOID *CONST Destination, CONST VOID *Source, UINTN Length) {
UINT8 *Dest = (UINT8 *)Destination;
CONST UINT8 *Src = (CONST UINT8 *)Source;
if (Length < 16) {
switch (Length) {
case 15:
*Dest++ = *Src++;
case 14:
*Dest++ = *Src++;
case 13:
*Dest++ = *Src++;
case 12:
*Dest++ = *Src++;
case 11:
*Dest++ = *Src++;
case 10:
*Dest++ = *Src++;
case 9:
*Dest++ = *Src++;
case 8:
*Dest++ = *Src++;
case 7:
*Dest++ = *Src++;
case 6:
*Dest++ = *Src++;
case 5:
*Dest++ = *Src++;
case 4:
*Dest++ = *Src++;
case 3:
*Dest++ = *Src++;
case 2:
*Dest++ = *Src++;
case 1:
*Dest++ = *Src++;
case 0:
break;
}
return Destination;
}
#ifdef MDE_CPU_X64
typedef UINT64 WORD_T;
#else
typedef UINT32 WORD_T;
#endif
while ((UINTN)Dest & (sizeof(WORD_T) - 1)) {
*Dest++ = *Src++;
Length--;
}
WORD_T *WordDest = (WORD_T *)Dest;
CONST WORD_T *WordSrc = (CONST WORD_T *)Src;
while (Length >= 8 * sizeof(WORD_T)) {
WordDest[0] = WordSrc[0];
WordDest[1] = WordSrc[1];
WordDest[2] = WordSrc[2];
WordDest[3] = WordSrc[3];
WordDest[4] = WordSrc[4];
WordDest[5] = WordSrc[5];
WordDest[6] = WordSrc[6];
WordDest[7] = WordSrc[7];
WordDest += 8;
WordSrc += 8;
Length -= 8 * sizeof(WORD_T);
}
while (Length >= 4 * sizeof(WORD_T)) {
WordDest[0] = WordSrc[0];
WordDest[1] = WordSrc[1];
WordDest[2] = WordSrc[2];
WordDest[3] = WordSrc[3];
WordDest += 4;
WordSrc += 4;
Length -= 4 * sizeof(WORD_T);
}
while (Length >= sizeof(WORD_T)) {
*WordDest++ = *WordSrc++;
Length -= sizeof(WORD_T);
}
Dest = (UINT8 *)WordDest;
Src = (CONST UINT8 *)WordSrc;
while (Length--) {
*Dest++ = *Src++;
}
return Destination;
}