MicroGUI release (Early Alpha version)
Today marks the day of the first MicroGUI release. It is still a early alpha version tough!
What is MicroGUI?
MicroGUI is a desktop extension for MicroOS. The extension currently is in a very early alpha stage! USE AT YOUR OWN RISK. This extension is proprietary and the source code will not be released, but don't worry the main OS will always stay open source.
How to use MicroGUI?
To use MicroGUI you will need to configure the MicroOS kernel and install MicroOS onto a disk.
Configuring the kernel
In the root of the MicroOS project type make config_kernel
. The activate the
following options:
Output->TEXT_MODE_EMULATION
Output->RAW_FRAMEBUFFER_ACCESS
It is also highly recommended to activate the Output->FULL_SCREEN_TERMINAL
option. In future releases this option might even be required.
Installing MicroOS (using a virtual machine)
First type make
to compile the OS. Then type make format_disk_gpt
to format
a disk file using fat32 and gpt. After that type make run
to run MicroOS. Once
MicroOS is booted type terminal autoinstall.msh
in the MicroOS terminal to
automatically install to the previously formatted disk. The virtual machine will
automatically shut down once the installation is finished.
Testing MicroOS
Use the command qemu-system-i386 -hda res/foxos.img
to test if the
installation was successful.
Installing MicroGUI
First unzip the microgui.zip file. You should now have a folder named publish. Now type the following commands to create a disk file containing the install files for MicroGUI:
dd if=/dev/zero of=publish.img bs=512 count=93750
mkfs.vfat publish.img -F32
mcopy -i publish.img publish/*.elf ::
printf publish > /tmp/LABEL
mcopy -i publish.img /tmp/LABEL ::
Now use the command
qemu-system-i386 -hda res/foxos.img -hdb publish.img --enable-kvm
to boot
MicroOS. Once MicroOS is booted type publish:/desktop_install.elf
to start the
installer. If you first want to check if the kernel is configured right you can
run publish:/syscheck.elf
before installing. The installer will ask a few
questions. If you plan to use the terminal you should also install the terminal
extension making command output work correctly. To do this type
publish:/desktop_terminal_install.elf
. After the installation is done reboot
the virtual machine (Either rerunning the command or using the Reset button qemu
provides).
Creating software for MicroGUI
Using FireStorm
First make sure you have flc
installed. You can get it
here. Just clone the
repository and run the install.sh
file. Now unzip the libs.zip
provided in
the publish
directory. You can do this using unzip publish/libs.zip
.
Now create a file named hello.fl
with the following content:
$include <std.fl>
$include <window.fl>
$include <window/font.fl>>
function spark(int argc, str[] argv) -> int {
window_init(200, 400, 50, 50, "Hello FireStorm world!");
int font = load_psf1_font("EFI/BOOT/zap-light16.psf");
loop {
window_optimize();
if window_redrawn() {
window_clear(0);
draw_string_window(font, 0, 0, "Hello World!", window_color_encode(255, 255, 255), 0);
}
}
}
and then use flc -t bytecode -o hello.flbb -i res/libs/include/ hello.fl
to
compile it. Now use mcopy -i publish.img hello.flbb ::
to copy the compiled
file into the image we created previously and boot the virtual machine using the
same command as we used before. Now use the explorer to navigate to publish:/
and run the file by clicking on it.
A more complex example
This is a more complex example implementing a 2 player tic tac toe game. The assets are already a part of the installation.
$include <std.fl>
$include <window.fl>
$include <window/fpic.fl>
$include <window/font.fl>
$include <window/clickarea.fl>
$define ASSET_SIZE 8 * 10
$define ASSET_SCALE 10
int x_pic;
int o_pic;
int empty_pic;
chr[] game_field;
int current_player = 'x';
function game_field_get(int x, int y) -> chr {
return game_field[x + y * 3];
}
function game_field_set(int x, int y, chr tile) -> void {
game_field[x + y * 3] = tile;
}
function game_field_draw() -> void {
for int x = 0; x < 3; x++ {
for int y = 0; y < 3; y++ {
chr tile = game_field_get(x, y);
if tile == 'o' {
draw_fpic_scaled_window(o_pic, x * ASSET_SIZE, y * ASSET_SIZE, ASSET_SCALE);
} else if tile == 'x' {
draw_fpic_scaled_window(x_pic, x * ASSET_SIZE, y * ASSET_SIZE, ASSET_SCALE);
} else {
draw_fpic_scaled_window(empty_pic, x * ASSET_SIZE, y * ASSET_SIZE, ASSET_SCALE);
}
}
}
}
function check_input(int[] info) -> void {
for int x = 0; x < 3; x++ {
for int y = 0; y < 3; y++ {
if check_click_area_window(x * ASSET_SIZE, y * ASSET_SIZE, ASSET_SIZE, ASSET_SIZE, info) {
if game_field_get(x, y) == 0 {
game_field_set(x, y, current_player);
if current_player == 'x' {
current_player = 'o';
} else {
current_player = 'x';
}
game_field_draw();
}
}
}
}
}
function check_winner() -> chr {
for int i = 0; i < 3; i++ {
if (game_field_get(i, 0) == game_field_get(i, 1)) &
(game_field_get(i, 1) == game_field_get(i, 2)) &
(game_field_get(i, 0) != 0) {
return game_field_get(i, 0);
}
if (game_field_get(0, i) == game_field_get(1, i)) &
(game_field_get(1, i) == game_field_get(2, i)) &
(game_field_get(0, i) != 0) {
return game_field_get(0, i);
}
}
if (game_field_get(0, 0) == game_field_get(1, 1)) &
(game_field_get(1, 1) == game_field_get(2, 2)) &
(game_field_get(0, 0) != 0) {
return game_field_get(0, 0);
}
if (game_field_get(0, 2) == game_field_get(1, 1)) &
(game_field_get(1, 1) == game_field_get(2, 0)) &
(game_field_get(0, 2) != 0) {
return game_field_get(0, 2);
}
for int x = 0; x < 3; x++ {
for int y = 0; y < 3; y++ {
if game_field_get(x, y) == 0 {
return 0;
}
}
}
return '-';
}
function reset_game() -> void {
memory_area_set_8(game_field, 0, 3 * 3);
current_player = 'x';
}
function spark(int argc, str[] argv) -> int {
int window_size = ASSET_SIZE * 3;
window_init(window_size, window_size, 50, 50, "Tic Tac Toe!");
x_pic = load_fpic_window("icons/tic_tac_toe/x.fpic");
o_pic = load_fpic_window("icons/tic_tac_toe/o.fpic");
empty_pic = load_fpic_window("icons/tic_tac_toe/empty.fpic");
int font = load_psf1_font("EFI/BOOT/zap-light16.psf");
game_field = allocate(3 * 3);
reset_game();
int[] info = window_mouse_info_new();
loop {
window_optimize();
if window_redrawn() {
window_clear(0);
game_field_draw();
}
window_mouse_info(info);
check_input(info);
chr winner = check_winner();
if winner {
chr[] winner_str = string_duplicate("The winner is -");
winner_str[14] = winner;
int initial = 1;
while window_async_getc() != ' ' {
window_optimize();
if window_redrawn() | initial {
window_clear(0);
draw_string_window(font, 0, 0, winner_str, window_color_encode(255, 255, 255), 0);
draw_string_window(font, 0, 16, "<space> to start new game", window_color_encode(255, 255, 255), 0);
initial = 0;
}
}
string_delete(winner_str);
reset_game();
game_field_draw();
}
}
}
I found a bug or i have a question
You can contact me using Discord or Instagram. I'm always happy to help you!