diff --git a/src/drivers/pci.c b/src/drivers/pci.c index ba6e210..18d05b6 100644 --- a/src/drivers/pci.c +++ b/src/drivers/pci.c @@ -69,7 +69,8 @@ void scan_pci_bus() pci_device_t dev = pci_get_device(bus, device, function); if (dev.vendor_id != 0xFFFF) { - + + // Maybe put that in a database in initrd.tar? char* vendor_string; switch(dev.vendor_id) { @@ -87,9 +88,6 @@ void scan_pci_bus() char* device_string; switch(dev.device_id) { - case 0x1237: - device_string = "440FX - 82441FX PMC"; - break; default: device_string = "Unknown"; break; diff --git a/src/kernel/kmain.c b/src/kernel/kmain.c index 5805abf..ac7f6c3 100644 --- a/src/kernel/kmain.c +++ b/src/kernel/kmain.c @@ -16,6 +16,7 @@ #include "kheap.h" #include "initrd.h" #include "../programs/programs.h" +#include "../libc/crypto.h" void kmain(multiboot2_info *mb_info) { diff --git a/src/kernel/shell.c b/src/kernel/shell.c index 0aab0aa..4635483 100644 --- a/src/kernel/shell.c +++ b/src/kernel/shell.c @@ -144,6 +144,7 @@ void shell_install() register_command("cat", program_cat); register_command("bmp", program_bmp); register_command("lspci", program_lspci); + register_command("naval", program_navalbattle); for (;;) { diff --git a/src/libc/string.h b/src/libc/string.h index 496950a..590d29a 100644 --- a/src/libc/string.h +++ b/src/libc/string.h @@ -12,5 +12,4 @@ char* strtok(char* str, const char* delimiter); int atoi(char* str); void strcat(char* dest, const char* src); - #endif diff --git a/src/programs/misc.c b/src/programs/misc.c index 94c1ec5..3a4ecca 100644 --- a/src/programs/misc.c +++ b/src/programs/misc.c @@ -74,7 +74,7 @@ void program_uptime() void program_help() { - printf("help\tpanic\twords\tprimes\trainbow\tclear\nmath\tbf\t uptime echo\t sysinfo\tconway\nrot13 morse\tcowsay time\t read\t reboot\npi\t ls\t cat\t bmp\t lspci\n"); + printf("help\tpanic\twords\tprimes\trainbow\tclear\nmath\tbf\t uptime echo\t sysinfo\tconway\nrot13 morse\tcowsay time\t read\t reboot\npi\t ls\t cat\t bmp\t lspci\t naval\n"); } // Panic diff --git a/src/programs/navalbattle.c b/src/programs/navalbattle.c new file mode 100644 index 0000000..ad6c898 --- /dev/null +++ b/src/programs/navalbattle.c @@ -0,0 +1,334 @@ +// Simplified naval battle game +// Author: xamidev +// Licensed under the Unlicense. See the repo below. +// https://github.com/xamidev/blankos + +#include "navalbattle.h" +#include "../libc/stdio.h" +#include "../kernel/system.h" +#include "../kernel/kheap.h" +#include "../libc/string.h" +#include "../libc/crypto.h" +#include "../drivers/serial.h" + +// Porting problems: +// - Color printf? (Need to implement ANSI escape sequences). +// - Scanf? +// - Malloc? (proof of concept) + +void program_navalbattle() +{ + clear(); + + grid_t* grid[SIZE][SIZE]; + grid_t* enemyGrid[SIZE][SIZE]; + + init_battlefield(grid); + init_battlefield(enemyGrid); + + placing_ally_ships(grid); + puts("Now, time for the enemies to prepare...\n"); + placing_enemy_ships(enemyGrid); + + delay((rand()%MAX_WAIT_TIME)+10); + + puts("Here we go!\n"); + show_game_stats(grid, enemyGrid); + + do + { + ally_do_attack(enemyGrid); + enemy_do_attack(grid); + show_game_stats(grid, enemyGrid); + } while (check_victory(grid, enemyGrid) == 0); + + return; +} + +void init_battlefield(grid_t* grid[SIZE][SIZE]) +{ + for (size_t i=0; ix = i; + grid[i][j]->y = j; + grid[i][j]->role = 0; + grid[i][j]->state = -2; + } + } +} + +void show_ally_battlefield(grid_t* grid[SIZE][SIZE]) +{ + puts("\n*** Ally grid ***\n"); + puts(" 0 1 2 3 4 5\n"); + + for (size_t i=0; istate) + { + case -2: + roleChar = 32; // space + break; + case -1: + roleChar = 120; + break; + case 0: + roleChar = 79; + break; + case 1: + roleChar = 88; + break; + default: + printf("Error: bad value in grid at x=%d y=%d\n", grid[i][j]->x, grid[i][j]->y); + shell_install(); + break; + } + + if (j == SIZE-1) + { + printf("%c]", roleChar); + } else if (j == 0) { + printf("[%c|", roleChar); + } else { + printf("%c|", roleChar); + } + } + puts("\n"); + } +} + +void placing_ally_ships(grid_t* grid[SIZE][SIZE]) +{ + puts("==== Allied preparation phase =====\nPlease enter the positions for your ships, sir.\n"); + + for (size_t i=0; i= SIZE || posY < 0 || posY >= SIZE) + { + printf("Invalid position x=%d y=%d, please retry.\n", posX, posY); + } + if (grid[posX][posY]->role == 1) + { + printf("A ship is already in x=%d y=%d, please retry.\n", posX, posY); + } + } while (posX < 0 || posX >= SIZE || posY < 0 || posY >= SIZE || grid[posX][posY]->role == 1); + + grid[posX][posY]->role = 1; + grid[posX][posY]->state = 0; + } +} + +void placing_enemy_ships(grid_t* grid[SIZE][SIZE]) +{ + for (size_t i=0; irole != 0); + + grid[posX][posY]->role = 1; + grid[posX][posY]->state = 0; + } +} + +void show_enemy_battlefield(grid_t* grid[SIZE][SIZE]) +{ + puts("\n*** Enemy grid ***\n"); + puts(" 0 1 2 3 4 5\n"); + + for (size_t i=0; istate) + { + case -2: + case 0: + roleChar = 32; + break; + case -1: + roleChar = 120; + break; + case 1: + roleChar = 88; + break; + default: + printf("Error: bad value in battlefield at x=%d y=%d\n", grid[i][j]->x, grid[i][j]->y); + shell_install(); + break; + } + if (j == SIZE-1) + { + printf("%c]", roleChar); + } else if (j == 0) { + printf("[%c|", roleChar); + } else { + printf("%c|", roleChar); + } + } + puts("\n"); + } + puts("\n"); +} + +void show_remaining_boats(grid_t* allyGrid[SIZE][SIZE], grid_t* enemyGrid[SIZE][SIZE]) +{ + int allyShips = 0; + int enemyShips = 0; + + for (size_t i=0; istate == 0) + { + allyShips++; + } + + if (enemyGrid[i][j]->state == 0) + { + enemyShips++; + } + } + } + + printf("%d ally ships and %d enemy ships remaining.\n", allyShips, enemyShips); + allyShips >= enemyShips ? colorputs("The allies are in a good posture.\n", yellow, black) : colorputs("The allies are losing terrain...\n", salmon, black); +} + +void show_game_stats(grid_t* allyGrid[SIZE][SIZE], grid_t* enemyGrid[SIZE][SIZE]) +{ + clear(); + colorputs("\n\n\nShowing known information:\n\n", cyan, black); + show_ally_battlefield(allyGrid); + show_enemy_battlefield(enemyGrid); + show_remaining_boats(allyGrid, enemyGrid); +} + +void do_attack(grid_t* grid[SIZE][SIZE], int x, int y) +{ + switch(grid[x][y]->state) + { + case -2: // Untouched ocean + colorputs("The torpedo explodes in water. Missed.\n", orange, black); + grid[x][y]->state = -1; + delay(30); + break; + case -1: // Already hit ocean + colorputs("We already striked here, sir... Too late.\n", orange, black); + break; + case 0: // Ship + colorputs("Hit! Well done!\n", green, black); + grid[x][y]->state = 1; + delay(30); + break; + case 1: // Already hit ship + colorputs("Sir, we already sunk that ship... (looser)\n", orange, black); + break; + } +} + +void ally_do_attack(grid_t* enemyGrid[SIZE][SIZE]) +{ + int x = 0, y = 0; + colorputs("\n* Ally attack preparation *\n", blue, black); + do + { + // yes, x and y are inverted. + puts("X coord: "); + char input_buffer[BUFFER_SIZE]; + get_input(input_buffer, BUFFER_SIZE); + y = atoi(input_buffer); + + puts("\nY coord: "); + char input_buffer2[BUFFER_SIZE]; + get_input(input_buffer2, BUFFER_SIZE); + x = atoi(input_buffer2); + + puts("\n"); + + if (x < 0 || x >= SIZE || y < 0 || y >= SIZE) + { + puts("Sir, this zone is not in our operation area! Please retry.\n"); + } + } while (x < 0 || x >= SIZE || y < 0 || y >= SIZE); + + do_attack(enemyGrid, x, y); +} + +void enemy_do_attack(grid_t* allyGrid[SIZE][SIZE]) +{ + int x = 0, y = 0; + colorputs("\n* Enemies are preparing for attack, everyone take shelter! *\n", blue, black); + + do + { + x = rand() % SIZE; + y = rand() % SIZE; + } while (allyGrid[x][y]->state == -1 || allyGrid[x][y]->state == 1); + + delay((rand()%MAX_WAIT_TIME)+10); + do_attack(allyGrid, x, y); +} + +int check_victory(grid_t* allyGrid[SIZE][SIZE], grid_t* enemyGrid[SIZE][SIZE]) +{ + int allyShips = 0; + int enemyShips = 0; + + for (size_t i=0; istate == 0) + { + allyShips++; + } + + if (enemyGrid[i][j]->state == 0) + { + enemyShips++; + } + } + } + + if (allyShips > 0 && enemyShips == 0) + { + colorputs("The allies have won! Congratulations, chief!\n", green, black); + return 1; + } else if (enemyShips > 0 && allyShips == 0) + { + colorputs("The ennemies have won.. We must retreat.\n", red, black); + return 1; + } + return 0; +} diff --git a/src/programs/navalbattle.h b/src/programs/navalbattle.h new file mode 100644 index 0000000..d75db9a --- /dev/null +++ b/src/programs/navalbattle.h @@ -0,0 +1,36 @@ +// Simplified naval battle game header +// Author: xamidev +// Licensed under the Unlicense. See the repo below. +// https://github.com/xamidev/blankos + +#ifndef NAVALBATTLE_H +#define NAVALBATTLE_H + +#include "../drivers/framebuffer.h" + +typedef struct +{ + int x; + int y; + int role; + int state; +} grid_t; + +#define SIZE 6 +#define BOATS 5 +#define MAX_WAIT_TIME 20 +#define BUFFER_SIZE 16 + +void init_battlefield(grid_t* grid[SIZE][SIZE]); +void show_ally_battlefield(grid_t* grid[SIZE][SIZE]); +void placing_ally_ships(grid_t* grid[SIZE][SIZE]); +void placing_enemy_ships(grid_t* grid[SIZE][SIZE]); +void show_enemy_battlefield(grid_t* grid[SIZE][SIZE]); +void show_remaining_boats(grid_t* allyGrid[SIZE][SIZE], grid_t* enemyGrid[SIZE][SIZE]); +void show_game_stats(grid_t* allyGrid[SIZE][SIZE], grid_t* enemyGrid[SIZE][SIZE]); +void do_attack(grid_t* grid[SIZE][SIZE], int x, int y); +void ally_do_attack(grid_t* enemyGrid[SIZE][SIZE]); +void enemy_do_attack(grid_t* allyGrid[SIZE][SIZE]); +int check_victory(grid_t* allyGrid[SIZE][SIZE], grid_t* enemyGrid[SIZE][SIZE]); + +#endif diff --git a/src/programs/programs.h b/src/programs/programs.h index 81cbbc3..fca21de 100644 --- a/src/programs/programs.h +++ b/src/programs/programs.h @@ -14,7 +14,6 @@ void program_sysinfo(); void get_cpuid(); void get_meminfo(unsigned int multiboot_info_address); // to be fixed: cannot get full memory map (sysinfo -v) -void program_conway(); void program_cowsay(); void cowsay(); // Splash screen void program_pi(); @@ -41,4 +40,8 @@ void program_cat(); void program_bmp(); void program_lspci(); +// Games +void program_navalbattle(); +void program_conway(); + #endif