Add: new homepage pic, naval battle game, PCI driver #7
@@ -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;
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
#include "kheap.h"
|
||||
#include "initrd.h"
|
||||
#include "../programs/programs.h"
|
||||
#include "../libc/crypto.h"
|
||||
|
||||
void kmain(multiboot2_info *mb_info)
|
||||
{
|
||||
|
||||
@@ -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 (;;)
|
||||
{
|
||||
|
||||
@@ -12,5 +12,4 @@ char* strtok(char* str, const char* delimiter);
|
||||
int atoi(char* str);
|
||||
void strcat(char* dest, const char* src);
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
@@ -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
334
src/programs/navalbattle.c
Normal 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;
|
||||
}
|
||||
36
src/programs/navalbattle.h
Normal file
36
src/programs/navalbattle.h
Normal 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
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user