Add: new homepage pic, naval battle game, PCI driver #7

Merged
xamidev merged 3 commits from dev into main 2024-09-09 22:29:29 +02:00
8 changed files with 379 additions and 7 deletions
Showing only changes of commit 2fa918bc87 - Show all commits

View File

@@ -70,6 +70,7 @@ void scan_pci_bus()
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;

View File

@@ -16,6 +16,7 @@
#include "kheap.h"
#include "initrd.h"
#include "../programs/programs.h"
#include "../libc/crypto.h"
void kmain(multiboot2_info *mb_info)
{

View File

@@ -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 (;;)
{

View File

@@ -12,5 +12,4 @@ char* strtok(char* str, const char* delimiter);
int atoi(char* str);
void strcat(char* dest, const char* src);
#endif

View File

@@ -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

334
src/programs/navalbattle.c Normal file
View File

@@ -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; i<SIZE; i++)
{
for (size_t j=0; j<SIZE; j++)
{
grid[i][j] = (grid_t*)malloc(sizeof(grid_t));
serial_printf(3, "malloc'd x=%d y=%d at 0x%x", i, j, grid[i][j]);
grid[i][j]->x = 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; i<SIZE; i++)
{
printf("%d ", i);
for (size_t j=0; j<SIZE; j++)
{
char roleChar = 0;
switch(grid[i][j]->state)
{
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<BOATS; i++)
{
int posX = 0, posY = 0;
do
{
printf("Ship %d\n------\n", i);
puts("X coord: ");
char input_buffer[BUFFER_SIZE];
get_input(input_buffer, BUFFER_SIZE);
posY = atoi(input_buffer);
puts("\nY coord: ");
char input_buffer2[BUFFER_SIZE];
get_input(input_buffer2, BUFFER_SIZE);
posX = atoi(input_buffer2);
puts("\n");
if (posX < 0 || posX >= 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; i<BOATS; i++)
{
int posX = 0, posY = 0;
do
{
posX = rand() % SIZE;
posY = rand() % SIZE;
} while (grid[posX][posY]->role != 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; i<SIZE; i++)
{
printf("%d ", i);
for (size_t j=0; j<SIZE; j++)
{
char roleChar = 0;
switch(grid[i][j]->state)
{
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; i<SIZE; i++)
{
for (size_t j=0; j<SIZE; j++)
{
if (allyGrid[i][j]->state == 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; i<SIZE; i++)
{
for (size_t j=0; j<SIZE; j++)
{
if (allyGrid[i][j]->state == 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;
}

View File

@@ -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

View File

@@ -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