summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSlendi <slendi@socopon.com>2023-09-29 17:01:07 +0300
committerSlendi <slendi@socopon.com>2023-09-29 17:01:07 +0300
commit4d318bda3f14a3f67aa9214349d0149426e5f8ed (patch)
tree4b304fb4fb1a9e207b29f6ed664e1eea1038833b
parentdfb1a30d16f3ca38bdab1abaf44339a1a0e92194 (diff)
Add a image that bounces on the corners.
Signed-off-by: Slendi <slendi@socopon.com>
-rw-r--r--efi.odin26
-rw-r--r--efi_console.odin19
-rw-r--r--main.odin141
-rw-r--r--odin.rawbin0 -> 395280 bytes
-rw-r--r--std.odin49
-rw-r--r--stub.c1
6 files changed, 190 insertions, 46 deletions
diff --git a/efi.odin b/efi.odin
index 1b7eac9..1a75a35 100644
--- a/efi.odin
+++ b/efi.odin
@@ -390,6 +390,28 @@ EfiGetMemoryMap :: proc "c" (
map_key, descriptor_size: ^uint,
descriptor_version: u32,
) -> EfiStatus
+
+// Allocates pool memory.
+//
+// Inputs:
+// - pool_type: The type of pool to allocate. Type EFI_MEMORY_TYPE is defined
+// in the EFI_BOOT_SERVICES.AllocatePages() function description. PoolType
+// values in the range 0x70000000..0x7FFFFFFF are reserved for OEM use.
+// PoolType values in the range 0x80000000..0xFFFFFFFF are reserved for use
+// by UEFI OS loaders that are provided by operating system vendors.
+// - size: The number of bytes to allocate from the pool.
+//
+// Outputs:
+// - buffer: A pointer to a pointer to the allocated buffer if the call
+// succeeds; undefined otherwise.
+EfiAllocatePool :: proc "c" (pool_type: EfiMemoryType, size: uint, buffer: ^rawptr) -> EfiStatus
+
+// Returns pool memory to the system.
+//
+// Inputs:
+// - buffer: Pointer to the buffer to free.
+EfiFreePool :: proc "c" (buffer: rawptr) -> EfiStatus
+
// Loads an EFI image into memory.
//
// Inputs:
@@ -506,8 +528,8 @@ EfiBootServices :: struct {
allocate_pages: EfiAllocatePages, // EFI 1.0+
free_pages: EfiAllocatePages, // EFI 1.0+
get_memory_map: EfiGetMemoryMap, // EFI 1.0+
- allocate_pool: EfiUnimplementedFunction, // EFI 1.0+
- free_pool: EfiUnimplementedFunction, // EFI 1.0+
+ allocate_pool: EfiAllocatePool, // EFI 1.0+
+ free_pool: EfiFreePool, // EFI 1.0+
// Event & Timer Services
create_event: EfiUnimplementedFunction, // EFI 1.0+
diff --git a/efi_console.odin b/efi_console.odin
index 8caaf31..f3ef53f 100644
--- a/efi_console.odin
+++ b/efi_console.odin
@@ -97,9 +97,28 @@ EFI_GRAPHICS_OUTPUT_BLT_PIXEL :: struct {
}
EFI_GRAPHICS_OUTPUT_BLT_OPERATION :: enum {
+ // Write data from the BltBuffer pixel (0,0) directly to every pixel of the
+ // video display rectangle (DestinationX, DestinationY) (DestinationX +
+ // Width, DestinationY + Height). Only one pixel will be used from the
+ // BltBuffer. Delta is NOT used.
EfiBltVideoFill,
+ // Read data from the video display rectangle (SourceX, SourceY) (SourceX +
+ // Width, SourceY + Height) and place it in the BltBuffer rectangle
+ // (DestinationX, DestinationY ) (DestinationX + Width, DestinationY +
+ // Height). If DestinationX or DestinationY is not zero then Delta must be
+ // set to the length in bytes of a row in the BltBuffer.
EfiBltVideoToBltBuffer,
+ // Write data from the BltBuffer rectangle (SourceX, SourceY) (SourceX +
+ // Width, SourceY + Height) directly to the video display rectangle
+ // (DestinationX, DestinationY) (DestinationX + Width, DestinationY +
+ // Height). If SourceX or SourceY is not zero then Delta must be set to the
+ // length in bytes of a row in the BltBuffer.
EfiBltBufferToVideo,
+ // Copy from the video display rectangle (SourceX, SourceY) (SourceX + Width,
+ // SourceY + Height) to the video display rectangle(DestinationX,
+ // DestinationY) (DestinationX + Width, DestinationY + Height. The BltBuffer
+ // and Delta are not used in this mode. There is no limitation on the
+ // overlapping of the source and destination rectangles.
EfiBltVideoToVideo,
EfiGraphicsOutputBltOperationMax,
}
diff --git a/main.odin b/main.odin
index 385ee60..c763572 100644
--- a/main.odin
+++ b/main.odin
@@ -4,45 +4,66 @@ import "core:intrinsics"
L :: intrinsics.constant_utf16_cstring
-hsv2rgb::proc(H, S, V: f32) -> EFI_GRAPHICS_OUTPUT_BLT_PIXEL{
- r, g, b: f32;
-
- h: f32= H / 1
- s: f32= S / 1
- v: f32= V / 1
-
- i: int= auto_cast (h * 6)
- f: f32= h * 6 - f32(i)
- p: f32= v * (1 - s)
- q: f32= v * (1 - f * s)
- t: f32= v * (1 - (1 - f) * s)
-
+IMAGE_W :: 540
+IMAGE_H :: 183
+IMAGE: []EFI_GRAPHICS_OUTPUT_BLT_PIXEL : #load("odin.raw")
+
+h2rgb :: proc(H: f32) -> EFI_GRAPHICS_OUTPUT_BLT_PIXEL {
+ r, g, b: f32
+
+ h: f32 = H / 1
+
+ i: int = auto_cast (h * 6)
+ f: f32 = h * 6 - f32(i)
+ q: f32 = 1 - f
+
switch (i % 6) {
- case 0: r = v; g = t; b = p; break
- case 1: r = q; g = v; b = p; break
- case 2: r = p; g = v; b = t; break
- case 3: r = p; g = q; b = v; break
- case 4: r = t; g = p; b = v; break
- case 5: r = v; g = p; b = q; break
+ case 0:
+ r = 1;g = f;b = 0;break
+ case 1:
+ r = q;g = 1;b = 0;break
+ case 2:
+ r = 0;g = 1;b = f;break
+ case 3:
+ r = 0;g = q;b = 1;break
+ case 4:
+ r = f;g = 0;b = 1;break
+ case 5:
+ r = 1;g = 0;b = q;break
}
-
+
color: EFI_GRAPHICS_OUTPUT_BLT_PIXEL
color.red = auto_cast (r * 255)
color.green = auto_cast (g * 255)
color.blue = auto_cast (b * 255)
color.reserved = 0xff
-
+
return color
}
main_ :: proc(efi_handle: rawptr, system_table: ^EfiSystemTable) -> u64 {
system_table.console_out.reset(system_table.console_out, true)
+ buffer: [1024]u16
+ printf(
+ &buffer[0],
+ 1024,
+ L("Hello from Odin! Firmware vendor: %s\r\n"),
+ system_table.firmware_vendor,
+ )
+ system_table.console_out.output_string(system_table.console_out, &buffer[0])
system_table.console_out.output_string(
system_table.console_out,
- L("Hello from Odin! Firmware vendor: "),
+ L("Starting GOP demo in 5..."),
)
- system_table.console_out.output_string(system_table.console_out, system_table.firmware_vendor)
- system_table.console_out.output_string(system_table.console_out, L("\nLoading GOP demo.\n"))
+ system_table.boot_services.stall(1000 * 1000)
+ system_table.console_out.output_string(system_table.console_out, L(" 4..."))
+ system_table.boot_services.stall(1000 * 1000)
+ system_table.console_out.output_string(system_table.console_out, L(" 3..."))
+ system_table.boot_services.stall(1000 * 1000)
+ system_table.console_out.output_string(system_table.console_out, L(" 2..."))
+ system_table.boot_services.stall(1000 * 1000)
+ system_table.console_out.output_string(system_table.console_out, L(" 1...\r\n"))
+ system_table.boot_services.stall(1000 * 1000)
gopUuid := EFI_GRAPHICS_OUTPUT_PROTOCOL_GUID
gop: ^EFI_GRAPHICS_OUTPUT_PROTOCOL = nil
@@ -68,32 +89,66 @@ main_ :: proc(efi_handle: rawptr, system_table: ^EfiSystemTable) -> u64 {
native_move = auto_cast gop.mode.mode
num_modes = auto_cast gop.mode.max_mode
- pixel: EFI_GRAPHICS_OUTPUT_BLT_PIXEL = {
- 0xff, 0xff, 0xff, 0
- }
+ pixel: EFI_GRAPHICS_OUTPUT_BLT_PIXEL
hue: f32 = 0.0
+ position_logo_x := 30
+ position_logo_y := 0
+ dir_x := 1
+ dir_y := 1
+ logo_speed := 20 // Adjust the speed of the logo movement
+
for {
- pixel = hsv2rgb(hue, 1, 1)
+ pixel = h2rgb(hue)
- system_table.boot_services.stall(50 * 000);
- hue += 0.001
- if (hue > 1) {hue = 0}
+ system_table.boot_services.stall(50 * 1000)
+ hue += 0.002
+
+ // Check for X-axis bounce
+ if (position_logo_x + dir_x * logo_speed > int(info.horizontal_resolution - IMAGE_W)) ||
+ (position_logo_x + dir_x * logo_speed < 0) {
+ dir_x = -dir_x
+ }
+
+ // Check for Y-axis bounce
+ if (position_logo_y + dir_y * logo_speed > int(info.vertical_resolution - IMAGE_H)) ||
+ (position_logo_y + dir_y * logo_speed < 0) {
+ dir_y = -dir_y
+ }
+
+ position_logo_x += dir_x * logo_speed
+ position_logo_y += dir_y * logo_speed
+
+ if (hue > 1) {
+ hue = 0
+ }
gop.blt(
- gop,
- &pixel,
- EFI_GRAPHICS_OUTPUT_BLT_OPERATION.EfiBltVideoFill,
- 0,
- 0,
- 0,
- 0,
- auto_cast gop.mode.info.horizontal_resolution,
- auto_cast gop.mode.info.vertical_resolution,
- 0,
- )
- }
+ gop,
+ &pixel,
+ EFI_GRAPHICS_OUTPUT_BLT_OPERATION.EfiBltVideoFill,
+ 0,
+ 0,
+ 0,
+ 0,
+ auto_cast gop.mode.info.horizontal_resolution,
+ auto_cast gop.mode.info.vertical_resolution,
+ 0,
+ )
+ gop.blt(
+ gop,
+ raw_data(IMAGE),
+ EFI_GRAPHICS_OUTPUT_BLT_OPERATION.EfiBltBufferToVideo,
+ 0,
+ 0,
+ uint(position_logo_x),
+ uint(position_logo_y),
+ IMAGE_W,
+ IMAGE_H,
+ 0,
+ )
+ }
for {}
return 0
}
diff --git a/odin.raw b/odin.raw
new file mode 100644
index 0000000..ca9eca8
--- /dev/null
+++ b/odin.raw
Binary files differ
diff --git a/std.odin b/std.odin
new file mode 100644
index 0000000..1cdb585
--- /dev/null
+++ b/std.odin
@@ -0,0 +1,49 @@
+package main
+
+import "core:mem"
+
+strlen :: proc(string: [^]u16) -> uint {
+ len: uint = 0
+ for string[len] != 0 {
+ len += 1
+ }
+ return len
+}
+
+printf :: proc(buffer: [^]u16, buffer_len: uint, format: [^]u16, args: ..any) -> [^]u16 {
+ format_len := strlen(format)
+ idx: uint = 0
+ idx_args: uint = 0
+
+ for i: uint = 0; i < format_len; i += 1 {
+ ch := format[i]
+ if ch == '%' {
+ i += 1
+ ch = format[i]
+
+ switch ch {
+ case '%':
+ buffer[idx] = '%'
+ idx += 1
+ case 's':
+ arg := args[idx_args].([^]u16)
+ str_len := strlen(arg)
+ idx_args += 1
+ for i2 in 0 ..< str_len {
+ buffer[idx] = arg[i2]
+ idx += 1
+ if idx >= buffer_len {break}
+ }
+ }
+ } else {
+ buffer[idx] = format[i]
+ idx += 1
+ }
+
+ if idx >= buffer_len {break}
+ }
+
+ //printf_buffer[idx + 1] = 0
+
+ return buffer
+}
diff --git a/stub.c b/stub.c
index b1b745f..67b7232 100644
--- a/stub.c
+++ b/stub.c
@@ -1,4 +1,3 @@
-
void RaiseException() {}
void GetStdHandle() {}
void SetHandleInformation() {}