Compare commits
18 Commits
1b0f312834
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
| 92e474853b | |||
| 24e7c443a1 | |||
| 37f63d51b9 | |||
| 09ff9f8f19 | |||
| 83df1a6048 | |||
| 36a7c9066a | |||
| 9b768a4e9e | |||
| 868d27cecb | |||
| c72a80832b | |||
| 54a54de423 | |||
| 8af36091ba | |||
| fa35f79e34 | |||
| 83ef67ad28 | |||
| 91001e09ba | |||
| 8c53885621 | |||
| 887e393d92 | |||
| f2ad30047a | |||
| 24edc2599b |
@@ -1,3 +1,4 @@
|
|||||||
build/
|
build/
|
||||||
.cache/
|
.cache/
|
||||||
compile_commands.json
|
compile_commands.json
|
||||||
|
src/UEFI_fireworks/rocket.c
|
||||||
@@ -1,5 +1,88 @@
|
|||||||
Arch uefi_run fix: sudo ln -s /usr/share/edk2/x64/OVMF_CODE.4m.fd /usr/share/qemu/OVMF.fd
|
# 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.
|
||||||
|
|
||||||
cd edk2
|
> [!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
|
||||||
|
|
||||||
|
> [!IMPORTANT]
|
||||||
|
> You will need these programs to compile:
|
||||||
|
> - git
|
||||||
|
> - gcc
|
||||||
|
> - xxd
|
||||||
|
> - ImageMagick (if you changed the firework image)
|
||||||
|
|
||||||
|
```bash
|
||||||
|
git submodule update --init --recursive
|
||||||
|
cd edk2
|
||||||
source edksetup.sh
|
source edksetup.sh
|
||||||
make -C BaseTools # if first run
|
make -C BaseTools
|
||||||
|
cd ..
|
||||||
|
./build.sh # to build for a different arch than X64 change TARGET_ARCH in build.sh
|
||||||
|
```
|
||||||
|
|
||||||
|
## How to use
|
||||||
|
|
||||||
|
### Download release
|
||||||
|
|
||||||
|
#### 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).
|
||||||
|
|
||||||
|
#### 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 |
|
||||||
|
| --------------- | ------------------------ |
|
||||||
|
| x86_64 (AMD64) | `/EFI/BOOT/BOOTX64.EFI` |
|
||||||
|
| x86 (IA32) | `/EFI/BOOT/BOOTIA32.EFI` |
|
||||||
|
| ARM64 (AARCH64) | `/EFI/BOOT/BOOTAA64.EFI` |
|
||||||
|
| ARM (32-bit) | `/EFI/BOOT/BOOTARM.EFI` |
|
||||||
|
|
||||||
|
## Controlling
|
||||||
|
|
||||||
|
| Key | Action | Note |
|
||||||
|
| ---------- | ------------ | ---------------------------------- |
|
||||||
|
| ARROW_UP | speed up | delays under 1ms may be unreliable |
|
||||||
|
| ARROW_DOWN | slow down | max delay is about UINT32_MAX μs |
|
||||||
|
| PAGE_UP | speed up | 10× step |
|
||||||
|
| PAGE_DOWN | slow down | 10× step |
|
||||||
|
| Home | reset speed | reset frame delay to 10ms |
|
||||||
|
| Delete | clear screen | |
|
||||||
|
|
||||||
|
## Showcase
|
||||||
|
In QEMU/KVM
|
||||||
|
|
||||||
|
https://github.com/user-attachments/assets/275e28aa-eb2e-4348-ac08-95f909c46a1f
|
||||||
|
|||||||
+9
-4
@@ -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
|
||||||
|
|
||||||
@@ -17,16 +17,21 @@ MemoryAllocationLib|edk2/MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAlloca
|
|||||||
DevicePathLib|edk2/MdePkg/Library/UefiDevicePathLib/UefiDevicePathLib.inf
|
DevicePathLib|edk2/MdePkg/Library/UefiDevicePathLib/UefiDevicePathLib.inf
|
||||||
UefiBootServicesTableLib|edk2/MdePkg/Library/UefiBootServicesTableLib/UefiBootServicesTableLib.inf
|
UefiBootServicesTableLib|edk2/MdePkg/Library/UefiBootServicesTableLib/UefiBootServicesTableLib.inf
|
||||||
UefiRuntimeServicesTableLib|edk2/MdePkg/Library/UefiRuntimeServicesTableLib/UefiRuntimeServicesTableLib.inf
|
UefiRuntimeServicesTableLib|edk2/MdePkg/Library/UefiRuntimeServicesTableLib/UefiRuntimeServicesTableLib.inf
|
||||||
DebugLib|edk2/MdePkg/Library/BaseDebugLibNull/BaseDebugLibNull.inf
|
DebugLib|edk2/MdePkg/Library/BaseDebugLibSerialPort/BaseDebugLibSerialPort.inf
|
||||||
PrintLib|edk2/MdePkg/Library/BasePrintLib/BasePrintLib.inf
|
PrintLib|edk2/MdePkg/Library/BasePrintLib/BasePrintLib.inf
|
||||||
PcdLib|edk2/MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf
|
PcdLib|edk2/MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf
|
||||||
RegisterFilterLib|edk2/MdePkg/Library/RegisterFilterLibNull/RegisterFilterLibNull.inf
|
RegisterFilterLib|edk2/MdePkg/Library/RegisterFilterLibNull/RegisterFilterLibNull.inf
|
||||||
StackCheckLib|edk2/MdePkg/Library/StackCheckLibNull/StackCheckLibNull.inf
|
StackCheckLib|edk2/MdePkg/Library/StackCheckLibNull/StackCheckLibNull.inf
|
||||||
TimerLib|edk2/MdePkg/Library/SecPeiDxeTimerLibCpu/SecPeiDxeTimerLibCpu.inf
|
|
||||||
IoLib|edk2/MdePkg/Library/BaseIoLibIntrinsic/BaseIoLibIntrinsic.inf
|
IoLib|edk2/MdePkg/Library/BaseIoLibIntrinsic/BaseIoLibIntrinsic.inf
|
||||||
RngLib|edk2/MdePkg/Library/BaseRngLib/BaseRngLib.inf
|
RngLib|edk2/MdePkg/Library/BaseRngLib/BaseRngLib.inf
|
||||||
SerialPortLib|edk2/MdePkg/Library/BaseSerialPortLibNull/BaseSerialPortLibNull.inf
|
SerialPortLib|edk2/MdePkg/Library/BaseSerialPortLibNull/BaseSerialPortLibNull.inf
|
||||||
|
DebugPrintErrorLevelLib|edk2/MdePkg/Library/BaseDebugPrintErrorLevelLib/BaseDebugPrintErrorLevelLib.inf
|
||||||
|
LocalApicLib|edk2/UefiCpuPkg/Library/BaseXApicLib/BaseXApicLib.inf
|
||||||
|
CpuLib|edk2/MdePkg/Library/BaseCpuLib/BaseCpuLib.inf
|
||||||
|
UefiRuntimeServicesTableLib|edk2/MdePkg/Library/UefiRuntimeServicesTableLib/UefiRuntimeServicesTableLib.inf
|
||||||
|
TimerLib|edk2/MdePkg/Library/BaseTimerLibNullTemplate/BaseTimerLibNullTemplate.inf
|
||||||
|
BmpSupportLib|edk2/MdeModulePkg/Library/BaseBmpSupportLib/BaseBmpSupportLib.inf
|
||||||
|
SafeIntLib|edk2/MdePkg/Library/BaseSafeIntLib/BaseSafeIntLib.inf
|
||||||
|
|
||||||
[Components]
|
[Components]
|
||||||
src/UEFI_fireworks/UEFI_fireworks.inf
|
src/UEFI_fireworks/UEFI_fireworks.inf
|
||||||
|
|||||||
Binary file not shown.
|
After Width: | Height: | Size: 1.2 KiB |
Binary file not shown.
Binary file not shown.
|
After Width: | Height: | Size: 1.3 KiB |
@@ -1,9 +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
|
||||||
|
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
|
build -a $TARGET_ARCH -t GCC5 -p UEFI_fireworks.dsc -b RELEASE
|
||||||
|
fi
|
||||||
|
mkdir -p build/EFI/BOOT/
|
||||||
|
if [ "$1" == "debug" ]; then
|
||||||
|
cp -v $(find edk2/Build/UEFI_fireworks/DEBUG_GCC5/ -name "UEFI_fireworks.efi" -type f | head -1) build/
|
||||||
|
cp -v $(find edk2/Build/UEFI_fireworks/DEBUG_GCC5/ -name "UEFI_fireworks.efi" -type f | head -1) build/EFI/BOOT/BOOTX64.EFI
|
||||||
|
else
|
||||||
|
cp -v $(find edk2/Build/UEFI_fireworks/RELEASE_GCC5/ -name "UEFI_fireworks.efi" -type f | head -1) build/
|
||||||
|
cp -v $(find edk2/Build/UEFI_fireworks/RELEASE_GCC5/ -name "UEFI_fireworks.efi" -type f | head -1) build/EFI/BOOT/BOOTX64.EFI
|
||||||
fi
|
fi
|
||||||
mkdir -p build
|
|
||||||
cp edk2/Build/UEFI_fireworks/DEBUG_GCC5/X64/UEFI_fireworks.efi build/
|
|
||||||
|
|||||||
+1
-1
Submodule edk2 updated: 808f1f1f87...d46aa46c83
@@ -6,9 +6,15 @@
|
|||||||
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
|
||||||
|
time.c
|
||||||
|
rocket.c
|
||||||
|
|
||||||
|
[Sources.AARCH64]
|
||||||
|
memcpy.c
|
||||||
|
|
||||||
[Packages]
|
[Packages]
|
||||||
edk2/MdePkg/MdePkg.dec
|
edk2/MdePkg/MdePkg.dec
|
||||||
@@ -27,6 +33,8 @@
|
|||||||
TimerLib
|
TimerLib
|
||||||
RngLib
|
RngLib
|
||||||
SerialPortLib
|
SerialPortLib
|
||||||
|
UefiRuntimeServicesTableLib
|
||||||
|
BmpSupportLib
|
||||||
|
|
||||||
[Protocols]
|
[Protocols]
|
||||||
gEfiRngProtocolGuid
|
gEfiRngProtocolGuid
|
||||||
|
|||||||
+163
-46
@@ -1,8 +1,12 @@
|
|||||||
#include "Library/UefiApplicationEntryPoint.h"
|
|
||||||
#include "ProcessorBind.h"
|
#include "ProcessorBind.h"
|
||||||
|
#include "Protocol/SimpleTextIn.h"
|
||||||
|
#include "Uefi/UefiBaseType.h"
|
||||||
|
#include "const.h"
|
||||||
#include "drawing.h"
|
#include "drawing.h"
|
||||||
#include "global.h"
|
#include "global.h"
|
||||||
#include "macros.h"
|
#include "macros.h"
|
||||||
|
#include "rng.h"
|
||||||
|
#include "time.h"
|
||||||
#include "types.h"
|
#include "types.h"
|
||||||
#include <Base.h>
|
#include <Base.h>
|
||||||
#include <Library/BaseLib.h>
|
#include <Library/BaseLib.h>
|
||||||
@@ -10,20 +14,26 @@
|
|||||||
#include <Library/MemoryAllocationLib.h>
|
#include <Library/MemoryAllocationLib.h>
|
||||||
#include <Library/RngLib.h>
|
#include <Library/RngLib.h>
|
||||||
#include <Library/SerialPortLib.h>
|
#include <Library/SerialPortLib.h>
|
||||||
#include <Library/TimerLib.h>
|
|
||||||
#include <Library/UefiBootServicesTableLib.h>
|
#include <Library/UefiBootServicesTableLib.h>
|
||||||
#include <Library/UefiLib.h>
|
#include <Library/UefiLib.h>
|
||||||
|
#include <Library/UefiRuntimeServicesTableLib.h>
|
||||||
#include <Protocol/GraphicsOutput.h>
|
#include <Protocol/GraphicsOutput.h>
|
||||||
#include <Uefi.h>
|
#include <Uefi.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
EFI_GRAPHICS_OUTPUT_BLT_PIXEL night_sky =
|
||||||
|
COLOR_FROM_HEX(0x090531); // this cannot be const becose EDK2 said so
|
||||||
|
#define DEFAULT_SLEEP_TIME 10000
|
||||||
|
firework_instance create_firework();
|
||||||
EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput = NULL;
|
EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput = NULL;
|
||||||
EFI_GRAPHICS_OUTPUT_BLT_PIXEL *framebuffer = NULL;
|
EFI_GRAPHICS_OUTPUT_BLT_PIXEL *framebuffer = NULL;
|
||||||
|
|
||||||
EFI_STATUS EFIAPI UefiMain(IN EFI_HANDLE imgHandle,
|
EFI_STATUS EFIAPI UefiMain(IN EFI_HANDLE imgHandle,
|
||||||
IN EFI_SYSTEM_TABLE *sysTable) {
|
IN EFI_SYSTEM_TABLE *sysTable) {
|
||||||
|
Print(L"Starting program\n");
|
||||||
gST = sysTable;
|
gST = sysTable;
|
||||||
gBS = sysTable->BootServices;
|
gBS = sysTable->BootServices;
|
||||||
gImageHandle = imgHandle;
|
gImageHandle = imgHandle;
|
||||||
|
gRT = sysTable->RuntimeServices;
|
||||||
|
|
||||||
// UEFI apps automatically exit after 5 minutes. Stop that here
|
// UEFI apps automatically exit after 5 minutes. Stop that here
|
||||||
gBS->SetWatchdogTimer(0, 0, 0, NULL);
|
gBS->SetWatchdogTimer(0, 0, 0, NULL);
|
||||||
@@ -37,63 +47,170 @@ EFI_STATUS EFIAPI UefiMain(IN EFI_HANDLE imgHandle,
|
|||||||
gBS->LocateProtocol(&gEfiGraphicsOutputProtocolGuid, NULL,
|
gBS->LocateProtocol(&gEfiGraphicsOutputProtocolGuid, NULL,
|
||||||
(VOID **)&GraphicsOutput);
|
(VOID **)&GraphicsOutput);
|
||||||
|
|
||||||
framebuffer =
|
if (GraphicsOutput == NULL) {
|
||||||
(EFI_GRAPHICS_OUTPUT_BLT_PIXEL *)GraphicsOutput->Mode->FrameBufferBase;
|
Print(L"GraphicsOutput protocol not found!\n");
|
||||||
|
return EFI_NOT_FOUND;
|
||||||
|
}
|
||||||
|
|
||||||
clear_screen(GraphicsOutput);
|
framebuffer = (EFI_GRAPHICS_OUTPUT_BLT_PIXEL *)(UINTN)
|
||||||
|
GraphicsOutput->Mode->FrameBufferBase;
|
||||||
|
|
||||||
LIST_ENTRY firework_list;
|
init_rng();
|
||||||
InitializeListHead(&firework_list);
|
init_rocket_blt();
|
||||||
|
|
||||||
if (SerialPortInitialize() == RETURN_SUCCESS) {
|
if (SerialPortInitialize() == RETURN_SUCCESS) {
|
||||||
SERIAL_PRINT("Serial initialized");
|
SERIAL_PRINT("Serial initialized\n");
|
||||||
} else {
|
} else {
|
||||||
Print(L"Failed to initialize Serial");
|
Print(L"Failed to initialize Serial!\n");
|
||||||
Exit(RETURN_DEVICE_ERROR);
|
|
||||||
}
|
}
|
||||||
|
SerialPortSetControl(EFI_SERIAL_CLEAR_TO_SEND |
|
||||||
|
EFI_SERIAL_DATA_TERMINAL_READY |
|
||||||
|
EFI_SERIAL_REQUEST_TO_SEND);
|
||||||
|
|
||||||
|
firework_instance *firework_array[UINT8_MAX];
|
||||||
|
gBS->SetMem(firework_array, sizeof(firework_array),
|
||||||
|
0); // make all pointers null
|
||||||
|
|
||||||
|
SERIAL_PRINT("DOES it work?\n");
|
||||||
|
Print(L"If you see this message for long time, timer does not work\n");
|
||||||
|
microsleep(1);
|
||||||
|
clear_screen();
|
||||||
|
|
||||||
|
UINTN sleep_time = DEFAULT_SLEEP_TIME;
|
||||||
while (TRUE) {
|
while (TRUE) {
|
||||||
UINT32 random;
|
UINT8 random;
|
||||||
GetRandomNumber32(&random);
|
fill_random_bytes(&random, sizeof(random));
|
||||||
if (random % 6 == 0) {
|
if (random % 30 == 0) {
|
||||||
// spawn new firework
|
// spawn new firework
|
||||||
firework_node *new_firework_node =
|
firework_instance *new_firework_instence =
|
||||||
AllocateZeroPool(sizeof(firework_node));
|
AllocateZeroPool(sizeof(firework_instance));
|
||||||
if (new_firework_node == NULL) {
|
if (new_firework_instence == NULL) {
|
||||||
return EFI_OUT_OF_RESOURCES;
|
return EFI_OUT_OF_RESOURCES;
|
||||||
}
|
}
|
||||||
new_firework_node->Signature = FIREWORK_NODE_SIGNATURE;
|
|
||||||
GetRandomNumber32(&random);
|
*new_firework_instence = create_firework();
|
||||||
new_firework_node->Firework.max_r =
|
|
||||||
random % 501; // so max number can be 500
|
for (UINT8 i = 0; i < ARRAY_SIZE(firework_array); i++) {
|
||||||
for (UINT8 i = 0; i < ARRAY_SIZE(new_firework_node->Firework.color);
|
if (firework_array[i] == NULL ||
|
||||||
i++) {
|
firework_array[i]->status == INACTIVE) {
|
||||||
GetRandomNumber32(
|
if (firework_array[i] != NULL) {
|
||||||
(UINT32 *)&new_firework_node->Firework.color[i]); // belive
|
FreePool(firework_array[i]); // free firework
|
||||||
new_firework_node->Firework.r[i] = 0;
|
firework_array[i] = NULL;
|
||||||
|
}
|
||||||
|
firework_array[i] = new_firework_instence;
|
||||||
|
goto assgned;
|
||||||
|
} // firework will not be created if if all slots are full
|
||||||
}
|
}
|
||||||
new_firework_node->Firework.cleanup_r = 0;
|
SERIAL_PRINT("NO free slots\n");
|
||||||
GetRandomNumber32(&random);
|
|
||||||
new_firework_node->Firework.x =
|
|
||||||
random % GraphicsOutput->Mode->Info->HorizontalResolution + 1;
|
|
||||||
GetRandomNumber32(&random);
|
|
||||||
new_firework_node->Firework.y =
|
|
||||||
random % GraphicsOutput->Mode->Info->VerticalResolution + 1;
|
|
||||||
|
|
||||||
InsertTailList(&firework_list, &new_firework_node->Link);
|
|
||||||
}
|
}
|
||||||
|
assgned:
|
||||||
firework_node *current_node = NULL;
|
for (UINT8 i = 0; i < ARRAY_SIZE(firework_array); i++) {
|
||||||
for (LIST_ENTRY *node = GetFirstNode(&firework_list);
|
if (firework_array[i] != NULL) {
|
||||||
!IsNodeAtEnd(&firework_list, node);
|
if (firework_array[i]->status == ACTIVE) {
|
||||||
node = GetNextNode(&firework_list, node)) {
|
if (!step_firework(firework_array[i])) {
|
||||||
// Print(L"Processing firework\r\n");
|
firework_array[i]->status = INACTIVE;
|
||||||
|
}
|
||||||
current_node = CR(node, firework_node, Link, FIREWORK_NODE_SIGNATURE);
|
} else if (firework_array[i]->status == LAUNCHING) {
|
||||||
if (!step_firework(¤t_node->Firework)) {
|
if (!step_rocket(&firework_array[i]->rocket, firework_array[i]->y)) {
|
||||||
RemoveEntryList(node); // remove if firework ended
|
firework_array[i]->status = ACTIVE;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
FreePool(firework_array[i]); // free firework
|
||||||
|
firework_array[i] = NULL;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
MicroSecondDelay(500000);
|
EFI_INPUT_KEY key;
|
||||||
|
EFI_STATUS status = gST->ConIn->ReadKeyStroke(gST->ConIn, &key);
|
||||||
|
gST->ConIn->Reset(gST->ConIn, FALSE);
|
||||||
|
if (status == EFI_SUCCESS) {
|
||||||
|
switch (key.ScanCode) {
|
||||||
|
case SCAN_UP: // increase simulation speed
|
||||||
|
|
||||||
|
if (sleep_time > 100) {
|
||||||
|
sleep_time = sleep_time - 100;
|
||||||
|
} else if (sleep_time > 10) {
|
||||||
|
sleep_time = sleep_time - 10;
|
||||||
|
} else if (sleep_time > 1) {
|
||||||
|
sleep_time = sleep_time - 1;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case SCAN_DOWN:
|
||||||
|
if (sleep_time < UINT32_MAX - 100) {
|
||||||
|
sleep_time = sleep_time + 100;
|
||||||
|
} else if (sleep_time < UINT32_MAX - 10) {
|
||||||
|
sleep_time = sleep_time + 10;
|
||||||
|
} else if (sleep_time < UINT32_MAX - 1) {
|
||||||
|
sleep_time = sleep_time + 1;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case SCAN_PAGE_UP:
|
||||||
|
if (sleep_time > 1000) {
|
||||||
|
sleep_time = sleep_time - 1000;
|
||||||
|
} else if (sleep_time > 100) {
|
||||||
|
sleep_time = sleep_time - 100;
|
||||||
|
} else if (sleep_time > 10) {
|
||||||
|
sleep_time = sleep_time - 10;
|
||||||
|
} else if (sleep_time > 1) {
|
||||||
|
sleep_time = sleep_time - 1;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case SCAN_PAGE_DOWN:
|
||||||
|
if (sleep_time < UINT32_MAX - 1000) {
|
||||||
|
sleep_time = sleep_time + 1000;
|
||||||
|
} else if (sleep_time < UINT32_MAX - 100) {
|
||||||
|
sleep_time = sleep_time + 100;
|
||||||
|
} else if (sleep_time < UINT32_MAX - 10) {
|
||||||
|
sleep_time = sleep_time + 10;
|
||||||
|
} else if (sleep_time < UINT32_MAX - 1) {
|
||||||
|
sleep_time = sleep_time + 1;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case SCAN_HOME:
|
||||||
|
sleep_time = DEFAULT_SLEEP_TIME;
|
||||||
|
break;
|
||||||
|
case SCAN_DELETE:
|
||||||
|
for (UINT8 i = 0; i < ARRAY_SIZE(firework_array); i++) {
|
||||||
|
if (firework_array[i] != NULL) {
|
||||||
|
FreePool(firework_array[i]);
|
||||||
|
firework_array[i] = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// clear_screen(); does not work on real hardware here for some unknown
|
||||||
|
// reason
|
||||||
|
for (UINTN i = 0; i < GraphicsOutput->Mode->FrameBufferSize; i++) {
|
||||||
|
framebuffer[i] = night_sky;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
microsleep(sleep_time);
|
||||||
}
|
}
|
||||||
|
|
||||||
return EFI_SUCCESS;
|
return EFI_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
firework_instance create_firework() {
|
||||||
|
firework_instance firework;
|
||||||
|
UINT32 random;
|
||||||
|
fill_random_bytes(&random, sizeof(random));
|
||||||
|
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],
|
||||||
|
sizeof(EFI_GRAPHICS_OUTPUT_BLT_PIXEL) - 1);
|
||||||
|
firework.r[i] = 0;
|
||||||
|
}
|
||||||
|
firework.cleanup_r = 0;
|
||||||
|
|
||||||
|
fill_random_bytes(&random, sizeof(random));
|
||||||
|
firework.x = random % GraphicsOutput->Mode->Info->HorizontalResolution;
|
||||||
|
fill_random_bytes(&random, sizeof(random));
|
||||||
|
firework.y = random % GraphicsOutput->Mode->Info->VerticalResolution /
|
||||||
|
2; // spawn only on upper half of the screen
|
||||||
|
|
||||||
|
firework.rocket.x = firework.x + rocket_asset.width / 2;
|
||||||
|
firework.rocket.y = GraphicsOutput->Mode->Info->VerticalResolution;
|
||||||
|
firework.status = LAUNCHING;
|
||||||
|
return firework;
|
||||||
|
}
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
#pragma once
|
||||||
|
extern unsigned char assets_rocket_bmp[];
|
||||||
|
extern unsigned int assets_rocket_bmp_len;
|
||||||
@@ -2,5 +2,6 @@
|
|||||||
#include "macros.h"
|
#include "macros.h"
|
||||||
#include <Protocol/GraphicsOutput.h>
|
#include <Protocol/GraphicsOutput.h>
|
||||||
|
|
||||||
EFI_GRAPHICS_OUTPUT_BLT_PIXEL night_sky =
|
extern EFI_GRAPHICS_OUTPUT_BLT_PIXEL night_sky;
|
||||||
COLOR_FROM_HEX(0x11095e); // this cannot be const becose EDK2 said so
|
|
||||||
|
enum firework_status { INACTIVE, ACTIVE, LAUNCHING };
|
||||||
@@ -1,20 +1,29 @@
|
|||||||
#include "Base.h"
|
#include "Base.h"
|
||||||
|
#include "Library/BaseMemoryLib.h"
|
||||||
|
#include "Library/MemoryAllocationLib.h"
|
||||||
#include "Library/UefiLib.h"
|
#include "Library/UefiLib.h"
|
||||||
#include "ProcessorBind.h"
|
#include "ProcessorBind.h"
|
||||||
|
#include "bmp.h"
|
||||||
#include "const.h"
|
#include "const.h"
|
||||||
#include "global.h"
|
#include "global.h"
|
||||||
|
#include "time.h"
|
||||||
#include "types.h"
|
#include "types.h"
|
||||||
|
#include <../MdeModulePkg/Include/Library/BmpSupportLib.h>
|
||||||
#include <Library/UefiApplicationEntryPoint.h>
|
#include <Library/UefiApplicationEntryPoint.h>
|
||||||
#include <Protocol/GraphicsOutput.h>
|
#include <Protocol/GraphicsOutput.h>
|
||||||
|
#include <alloca.h>
|
||||||
|
|
||||||
void draw_pixel(const UINT32 x, const UINT32 y,
|
void draw_pixel(const UINT32 x, const UINT32 y,
|
||||||
const EFI_GRAPHICS_OUTPUT_BLT_PIXEL pixel) {
|
const EFI_GRAPHICS_OUTPUT_BLT_PIXEL pixel) {
|
||||||
|
if (x >= GraphicsOutput->Mode->Info->HorizontalResolution ||
|
||||||
|
y >= GraphicsOutput->Mode->Info
|
||||||
|
->VerticalResolution) { // ignore when out of bounds
|
||||||
|
return;
|
||||||
|
}
|
||||||
UINTN framebuffer_offset =
|
UINTN framebuffer_offset =
|
||||||
(y * GraphicsOutput->Mode->Info->PixelsPerScanLine) + x;
|
(y * GraphicsOutput->Mode->Info->PixelsPerScanLine) + x;
|
||||||
if (framebuffer_offset <
|
|
||||||
GraphicsOutput->Mode->FrameBufferSize) { // ignre when out of bounds
|
framebuffer[framebuffer_offset] = pixel;
|
||||||
framebuffer[framebuffer_offset] = pixel;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// uses Mid-Point Circle Drawing Algorithm
|
// uses Mid-Point Circle Drawing Algorithm
|
||||||
@@ -82,7 +91,7 @@ void clear_screen() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOLEAN step_firework(struct firework_instance *firework) {
|
BOOLEAN step_firework(firework_instance *firework) {
|
||||||
for (UINT8 i = 0; i < ARRAY_SIZE(firework->r); i++) {
|
for (UINT8 i = 0; i < ARRAY_SIZE(firework->r); i++) {
|
||||||
if (firework->r[i] < firework->max_r) {
|
if (firework->r[i] < firework->max_r) {
|
||||||
if (i == 0 || (firework->max_r / 3.5) * i <= firework->r[i - 1]) {
|
if (i == 0 || (firework->max_r / 3.5) * i <= firework->r[i - 1]) {
|
||||||
@@ -102,3 +111,64 @@ BOOLEAN step_firework(struct firework_instance *firework) {
|
|||||||
}
|
}
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
rocket_blt rocket_asset;
|
||||||
|
|
||||||
|
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,
|
||||||
|
&rocket_asset.blt_size, &rocket_asset.height, &rocket_asset.width);
|
||||||
|
if (EFI_ERROR(Status)) {
|
||||||
|
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(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) {
|
||||||
|
// 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 {
|
||||||
|
rocket->y--;
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -3,5 +3,7 @@
|
|||||||
#include <Protocol/GraphicsOutput.h>
|
#include <Protocol/GraphicsOutput.h>
|
||||||
void draw_circle(int xc, int yc, int r,
|
void draw_circle(int xc, int yc, int r,
|
||||||
const EFI_GRAPHICS_OUTPUT_BLT_PIXEL color);
|
const EFI_GRAPHICS_OUTPUT_BLT_PIXEL color);
|
||||||
void clear_screen(EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput);
|
void clear_screen();
|
||||||
BOOLEAN step_firework(struct firework_instance *firework);
|
BOOLEAN step_firework(firework_instance *firework);
|
||||||
|
void init_rocket_blt();
|
||||||
|
BOOLEAN step_rocket(location *rocket, UINT32 max_y);
|
||||||
@@ -1,4 +1,6 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
#include "types.h"
|
||||||
#include <Protocol/GraphicsOutput.h>
|
#include <Protocol/GraphicsOutput.h>
|
||||||
extern EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput;
|
extern EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput;
|
||||||
extern EFI_GRAPHICS_OUTPUT_BLT_PIXEL *framebuffer;
|
extern EFI_GRAPHICS_OUTPUT_BLT_PIXEL *framebuffer;
|
||||||
|
extern rocket_blt rocket_asset;
|
||||||
@@ -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;
|
||||||
|
}
|
||||||
@@ -0,0 +1,119 @@
|
|||||||
|
#include "rng.h"
|
||||||
|
#include "Library/UefiBootServicesTableLib.h"
|
||||||
|
#include "Library/UefiLib.h"
|
||||||
|
#include "ProcessorBind.h"
|
||||||
|
#include "Uefi/UefiBaseType.h"
|
||||||
|
#include "time.h"
|
||||||
|
#include <Library/BaseLib.h>
|
||||||
|
#include <Library/RngLib.h>
|
||||||
|
#include <Library/TimerLib.h>
|
||||||
|
#include <Library/UefiRuntimeServicesTableLib.h>
|
||||||
|
#include <Uefi.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
void (*fill_random_bytes)(void *dst, UINTN n);
|
||||||
|
|
||||||
|
UINT16 shift_LFSR(UINT16 LFSR) {
|
||||||
|
UINT16 lsb = LFSR & 1;
|
||||||
|
LFSR >>= 1;
|
||||||
|
if (lsb) {
|
||||||
|
LFSR ^= 0xB400;
|
||||||
|
}
|
||||||
|
return LFSR;
|
||||||
|
}
|
||||||
|
|
||||||
|
void fill_random_bytes_TRUE(void *dst, UINTN n) {
|
||||||
|
UINT16 rand;
|
||||||
|
if (n % 2 != 0) {
|
||||||
|
GetRandomNumber16(&rand);
|
||||||
|
*(UINT8 *)dst = (UINT8)rand;
|
||||||
|
dst++;
|
||||||
|
n--;
|
||||||
|
}
|
||||||
|
while (n != 0) {
|
||||||
|
GetRandomNumber16(&rand);
|
||||||
|
*(UINT16 *)dst = rand;
|
||||||
|
dst += 2;
|
||||||
|
n -= 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
UINT16 LFSR;
|
||||||
|
void fill_random_bytes_LFSR(void *dst, UINTN n) {
|
||||||
|
if (n % 2 != 0) {
|
||||||
|
LFSR = shift_LFSR(LFSR);
|
||||||
|
*(UINT8 *)dst = (UINT8)LFSR;
|
||||||
|
dst++;
|
||||||
|
n--;
|
||||||
|
}
|
||||||
|
while (n != 0) {
|
||||||
|
LFSR = shift_LFSR(LFSR);
|
||||||
|
*(UINT16 *)dst = LFSR;
|
||||||
|
dst += 2;
|
||||||
|
n -= 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void init_rng() {
|
||||||
|
UINT16 test_var;
|
||||||
|
if (GetRandomNumber16(&test_var)) {
|
||||||
|
fill_random_bytes = fill_random_bytes_TRUE;
|
||||||
|
} else {
|
||||||
|
gST->ConOut->SetAttribute(gST->ConOut, EFI_YELLOW);
|
||||||
|
Print(L"[WARNING]");
|
||||||
|
gST->ConOut->SetAttribute(gST->ConOut, EFI_WHITE);
|
||||||
|
Print(L" RNG device not available falling back to LFSR!\r\n");
|
||||||
|
|
||||||
|
EFI_TIME Time;
|
||||||
|
EFI_STATUS Status;
|
||||||
|
UINT32 starting;
|
||||||
|
Status = gRT->GetTime(&Time, NULL);
|
||||||
|
if (EFI_ERROR(Status)) {
|
||||||
|
Print(L"failed to get time\r\n");
|
||||||
|
microsleep(2000000);
|
||||||
|
starting = 1;
|
||||||
|
} else {
|
||||||
|
starting = Time.Second;
|
||||||
|
}
|
||||||
|
|
||||||
|
Print(L"Press any key to seed the LFSR\r\n");
|
||||||
|
EFI_INPUT_KEY Key;
|
||||||
|
UINTN Index;
|
||||||
|
Status = gBS->WaitForEvent(1, &(gST->ConIn->WaitForKey), &Index);
|
||||||
|
if (EFI_ERROR(Status)) {
|
||||||
|
Print(L"failed to wait key\r\n");
|
||||||
|
Key.ScanCode = 1;
|
||||||
|
Key.UnicodeChar = 1;
|
||||||
|
} else {
|
||||||
|
|
||||||
|
Status = gST->ConIn->ReadKeyStroke(gST->ConIn, &Key);
|
||||||
|
if (EFI_ERROR(Status)) {
|
||||||
|
Print(L"failed to read key\r\n");
|
||||||
|
Key.ScanCode = 1;
|
||||||
|
Key.UnicodeChar = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (Key.ScanCode == 0) {
|
||||||
|
Key.ScanCode = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
Status = gRT->GetTime(&Time, NULL);
|
||||||
|
if (EFI_ERROR(Status)) {
|
||||||
|
Print(L"failed to get time\r\n");
|
||||||
|
Time.Second = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
UINT8 time_diff = (Time.Second - starting);
|
||||||
|
if (time_diff == 0) {
|
||||||
|
time_diff = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
LFSR = (typeof(LFSR))(((UINTN)Key.ScanCode * (UINTN)Key.UnicodeChar *
|
||||||
|
(UINTN)(time_diff)) %
|
||||||
|
UINT16_MAX);
|
||||||
|
|
||||||
|
if (LFSR <= 1) {
|
||||||
|
LFSR = 0xf5d7;
|
||||||
|
}
|
||||||
|
|
||||||
|
fill_random_bytes = fill_random_bytes_LFSR;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
#pragma once
|
||||||
|
extern void (*fill_random_bytes)(void *dst, UINTN n);
|
||||||
|
void init_rng();
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
#include "Library/UefiLib.h"
|
||||||
|
#include <Library/UefiBootServicesTableLib.h>
|
||||||
|
EFI_STATUS
|
||||||
|
microsleep(UINTN n) {
|
||||||
|
EFI_STATUS Status;
|
||||||
|
EFI_EVENT TimerEvent;
|
||||||
|
|
||||||
|
Status =
|
||||||
|
gBS->CreateEvent(EVT_TIMER, TPL_APPLICATION, NULL, NULL, &TimerEvent);
|
||||||
|
|
||||||
|
if (EFI_ERROR(Status)) {
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
Status = gBS->SetTimer(TimerEvent, TimerRelative,
|
||||||
|
EFI_TIMER_PERIOD_MICROSECONDS(n));
|
||||||
|
|
||||||
|
if (!EFI_ERROR(Status)) {
|
||||||
|
gBS->WaitForEvent(1, &TimerEvent, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
gBS->CloseEvent(TimerEvent);
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
#pragma once
|
||||||
|
void microsleep(UINTN n);
|
||||||
@@ -1,19 +1,28 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include "ProcessorBind.h"
|
#include "ProcessorBind.h"
|
||||||
#include "Protocol/GraphicsOutput.h"
|
#include "Protocol/GraphicsOutput.h"
|
||||||
|
#include "const.h"
|
||||||
#include <Library/BaseLib.h>
|
#include <Library/BaseLib.h>
|
||||||
struct firework_instance {
|
|
||||||
|
typedef struct {
|
||||||
|
UINT32 x;
|
||||||
|
UINT32 y;
|
||||||
|
} location;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
enum firework_status status; // IF INACTIVE can be overwriten
|
||||||
UINT32 x;
|
UINT32 x;
|
||||||
UINT32 y;
|
UINT32 y;
|
||||||
UINT16 max_r;
|
UINT16 max_r;
|
||||||
UINT16 r[3];
|
UINT16 r[3];
|
||||||
EFI_GRAPHICS_OUTPUT_BLT_PIXEL color[3];
|
EFI_GRAPHICS_OUTPUT_BLT_PIXEL color[3];
|
||||||
UINT16 cleanup_r;
|
UINT16 cleanup_r;
|
||||||
};
|
location rocket;
|
||||||
|
} firework_instance;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
UINTN Signature;
|
EFI_GRAPHICS_OUTPUT_BLT_PIXEL *blt;
|
||||||
struct firework_instance Firework;
|
UINTN blt_size;
|
||||||
LIST_ENTRY Link;
|
UINTN height;
|
||||||
} firework_node;
|
UINTN width;
|
||||||
#define FIREWORK_NODE_SIGNATURE SIGNATURE_32('f', 'w', 'r', 'k')
|
} rocket_blt;
|
||||||
|
|||||||
@@ -1,14 +1,16 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
|
||||||
cp /usr/share/edk2/x64/OVMF_VARS.4m.fd ./my_ovmf_vars.fd
|
if [ $# -ge 1 ]; then
|
||||||
|
OVMF_CODE_PATH=$1
|
||||||
|
else
|
||||||
|
OVMF_CODE_PATH=/usr/share/edk2/x64/OVMF_CODE.4m.fd
|
||||||
|
fi
|
||||||
|
|
||||||
qemu-system-x86_64 \
|
qemu-system-x86_64 \
|
||||||
-machine type=q35,accel=kvm \
|
-machine type=q35,accel=kvm \
|
||||||
-drive if=pflash,format=raw,readonly=on,file=/usr/share/edk2/x64/OVMF_CODE.4m.fd \
|
-drive if=pflash,format=raw,readonly=on,file="$OVMF_CODE_PATH" \
|
||||||
-drive if=pflash,format=raw,file=./my_ovmf_vars.fd \
|
-hda fat:rw:build \
|
||||||
-hda fat:rw:$(dirname build/UEFI_fireworks.efi) \
|
-boot order=c \
|
||||||
-smp 4 \
|
-smp 4 \
|
||||||
-s \
|
-s \
|
||||||
-serial mon:stdio
|
-serial mon:stdio
|
||||||
|
|
||||||
rm ./my_ovmf_vars.fd
|
|
||||||
|
|||||||
Reference in New Issue
Block a user