diff --git a/README.md b/README.md index 44ca59a..40f0c67 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,41 @@ -Arch uefi_run fix: sudo ln -s /usr/share/edk2/x64/OVMF_CODE.4m.fd /usr/share/qemu/OVMF.fd +# UEFI Fireworks + +## How to build + +```bash +git submodule update --init --recursive cd edk2 source edksetup.sh -make -C BaseTools # if first run \ No newline at end of file +make -C BaseTools +cd .. +./build.sh +``` + +## How to use + +### On VM + +run ```./test.sh``` to run in VM using QEMU + +### On Real hardware + +copy ```edk2/Build/UEFI_fireworks/DEBUG_GCC5//UEFI_fireworks.efi``` to FAT32 or FAT16 USB at 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` | + +## Controling + +| Key | Action | Note | +|-----|--------|------| +| ARROW_UP | speed up | delays under 1ms may be unrelayable | +| ARROW_DOWN | slow down | max delay is about UINT32_MAXμs | +| PAGE_UP | speed up | 10x step | +| PAGE_DOWN | speed down | 10x step | +| Home key | reset speed | reset frame delay to 10ms | +| Delete key | clear screen | | diff --git a/src/UEFI_fireworks/UefiMain.c b/src/UEFI_fireworks/UefiMain.c index 16e7b70..efb1878 100644 --- a/src/UEFI_fireworks/UefiMain.c +++ b/src/UEFI_fireworks/UefiMain.c @@ -1,4 +1,6 @@ #include "ProcessorBind.h" +#include "Protocol/SimpleTextIn.h" +#include "Uefi/UefiBaseType.h" #include "const.h" #include "drawing.h" #include "global.h" @@ -20,7 +22,7 @@ #include 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_BLT_PIXEL *framebuffer = NULL; @@ -71,16 +73,10 @@ EFI_STATUS EFIAPI UefiMain(IN EFI_HANDLE imgHandle, SERIAL_PRINT("DOES it work?\n"); Print(L"If you see this message for long time, timer does not work\n"); - milisleep(1); + microsleep(1); clear_screen(); - /*rocket_instance rocket = { - .x = GraphicsOutput->Mode->Info->HorizontalResolution / 2, - .y = GraphicsOutput->Mode->Info->VerticalResolution - 50}; - while (step_rocket(&rocket, 100)) { - milisleep(10); - }*/ - + UINTN sleep_time = DEFAULT_SLEEP_TIME; while (TRUE) { UINT8 random; fill_random_bytes(&random, sizeof(random)); @@ -124,8 +120,71 @@ EFI_STATUS EFIAPI UefiMain(IN EFI_HANDLE imgHandle, } } } + 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 - milisleep(10); + 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; diff --git a/src/UEFI_fireworks/rng.c b/src/UEFI_fireworks/rng.c index d10666a..6854eaf 100644 --- a/src/UEFI_fireworks/rng.c +++ b/src/UEFI_fireworks/rng.c @@ -68,7 +68,7 @@ void init_rng() { Status = gRT->GetTime(&Time, NULL); if (EFI_ERROR(Status)) { Print(L"failed to get time\r\n"); - milisleep(2000); + microsleep(2000000); starting = 1; } else { starting = Time.Second; diff --git a/src/UEFI_fireworks/time.c b/src/UEFI_fireworks/time.c index d64b681..9f22e80 100644 --- a/src/UEFI_fireworks/time.c +++ b/src/UEFI_fireworks/time.c @@ -1,7 +1,7 @@ #include "Library/UefiLib.h" #include EFI_STATUS -milisleep(UINTN Milliseconds) { +microsleep(UINTN n) { EFI_STATUS Status; EFI_EVENT TimerEvent; @@ -13,7 +13,7 @@ milisleep(UINTN Milliseconds) { } Status = gBS->SetTimer(TimerEvent, TimerRelative, - EFI_TIMER_PERIOD_MILLISECONDS(Milliseconds)); + EFI_TIMER_PERIOD_MICROSECONDS(n)); if (!EFI_ERROR(Status)) { gBS->WaitForEvent(1, &TimerEvent, NULL); diff --git a/src/UEFI_fireworks/time.h b/src/UEFI_fireworks/time.h index 361d210..4fa866d 100644 --- a/src/UEFI_fireworks/time.h +++ b/src/UEFI_fireworks/time.h @@ -1,2 +1,2 @@ #pragma once -void milisleep(UINTN n); \ No newline at end of file +void microsleep(UINTN n); \ No newline at end of file