diff options
author | Slendi <slendi@socopon.com> | 2023-09-29 17:01:07 +0300 |
---|---|---|
committer | Slendi <slendi@socopon.com> | 2023-09-29 17:01:07 +0300 |
commit | 4d318bda3f14a3f67aa9214349d0149426e5f8ed (patch) | |
tree | 4b304fb4fb1a9e207b29f6ed664e1eea1038833b | |
parent | dfb1a30d16f3ca38bdab1abaf44339a1a0e92194 (diff) |
Add a image that bounces on the corners.
Signed-off-by: Slendi <slendi@socopon.com>
-rw-r--r-- | efi.odin | 26 | ||||
-rw-r--r-- | efi_console.odin | 19 | ||||
-rw-r--r-- | main.odin | 141 | ||||
-rw-r--r-- | odin.raw | bin | 0 -> 395280 bytes | |||
-rw-r--r-- | std.odin | 49 | ||||
-rw-r--r-- | stub.c | 1 |
6 files changed, 190 insertions, 46 deletions
@@ -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, } @@ -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 Binary files differnew file mode 100644 index 0000000..ca9eca8 --- /dev/null +++ b/odin.raw 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 +} @@ -1,4 +1,3 @@ - void RaiseException() {} void GetStdHandle() {} void SetHandleInformation() {} |