version 1 metricpet is made

This commit is contained in:
klein panic
2025-01-09 21:11:57 -05:00
commit 83bb5a2ead
9 changed files with 1204 additions and 0 deletions

BIN
blackcat.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

54
blackcat.txt Normal file
View File

@@ -0,0 +1,54 @@
const int grid[25][25] = {
{ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
{ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1 },
{ 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1 },
{ 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1 },
{ 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1 },
{ 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1 },
{ 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1 },
{ 1, 1, 1, 1, 1, 1, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 1, 1, 1, 1, 1, 1 },
{ 1, 1, 1, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 1, 1, 1, 1 },
{ 1, 1, 1, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1 },
{ 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1 },
{ 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1 },
{ 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1 },
{ 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1 },
{ 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1 },
{ 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1 },
{ 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1 },
{ 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1 },
{ 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1 },
{ 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1 },
{ 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1 },
{ 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1 },
{ 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1 },
{ 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
{ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }
};
Pixel Art:
#########################
################ #######
##### ######## ######
##### ###### ######
##### ######
##### ## ######
##### ## ## ######
###### # # # # ######
##### # # #####
##### # ### #####
##### ## # #####
##### ######
###### ######
###### #######
####### ########
######## ########
######## #######
######## ######
####### ######
####### ######
###### ######
###### ######
###### #######
######### #########
#########################

BIN
cat_lay.jpeg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.9 KiB

BIN
image_to_grid_convert Executable file

Binary file not shown.

71
image_to_grid_convert.c Normal file
View File

@@ -0,0 +1,71 @@
#include <stdio.h>
#include <stdlib.h>
#include <SDL2/SDL.h>
#include <SDL2/SDL_image.h>
#define GRID_SIZE 25 // 25x25 grid
#define PIXEL_THRESHOLD 128 // Threshold to decide between 0 and 1 for pixel intensity
void convert_image_to_grid(const char *image_path) {
SDL_Init(SDL_INIT_VIDEO);
IMG_Init(IMG_INIT_JPG | IMG_INIT_PNG);
SDL_Surface *image = IMG_Load(image_path);
if (!image) {
fprintf(stderr, "Failed to load image: %s\n", IMG_GetError());
IMG_Quit();
SDL_Quit();
return;
}
int width = image->w;
int height = image->h;
SDL_Surface *scaled_image = SDL_CreateRGBSurface(0, GRID_SIZE, GRID_SIZE, 32, 0x00FF0000, 0x0000FF00, 0x000000FF, 0);
SDL_BlitScaled(image, NULL, scaled_image, NULL);
SDL_FreeSurface(image);
printf("const int grid[%d][%d] = {\n", GRID_SIZE, GRID_SIZE);
for (int y = 0; y < GRID_SIZE; y++) {
printf(" { ");
for (int x = 0; x < GRID_SIZE; x++) {
Uint32 pixel = ((Uint32 *)scaled_image->pixels)[y * GRID_SIZE + x];
Uint8 r, g, b;
SDL_GetRGB(pixel, scaled_image->format, &r, &g, &b);
int intensity = (r + g + b) / 3;
printf("%d%s", intensity < PIXEL_THRESHOLD ? 0 : 1, x == GRID_SIZE - 1 ? "" : ", ");
}
printf(" }%s\n", y == GRID_SIZE - 1 ? "" : ",");
}
printf("};\n\n");
printf("Pixel Art:\n");
for (int y = 0; y < GRID_SIZE; y++) {
for (int x = 0; x < GRID_SIZE; x++) {
Uint32 pixel = ((Uint32 *)scaled_image->pixels)[y * GRID_SIZE + x];
Uint8 r, g, b;
SDL_GetRGB(pixel, scaled_image->format, &r, &g, &b);
int intensity = (r + g + b) / 3;
printf(intensity < PIXEL_THRESHOLD ? " " : "#");
}
printf("\n");
}
SDL_FreeSurface(scaled_image);
IMG_Quit();
SDL_Quit();
}
int main(int argc, char *argv[]) {
if (argc < 2) {
fprintf(stderr, "Usage: %s <image_path>\n", argv[0]);
return 1;
}
convert_image_to_grid(argv[1]);
return 0;
}

227
metricpet.c Normal file
View File

@@ -0,0 +1,227 @@
#include <SDL2/SDL.h>
#include <stdio.h>
#include <stdbool.h>
#include <unistd.h>
#include <stdlib.h>
#include <time.h>
#include <string.h>
#define WINDOW_WIDTH 64
#define WINDOW_HEIGHT 64
#define PIXEL_SIZE 8 // Size of each pixel in the pet's display grid
#define BATTERY_THRESHOLD 20
#define CONNECTION_CHECK_CMD "ping -c 1 google.com > /dev/null 2>&1"
// Pet mood states
typedef enum { HAPPY, NEUTRAL, SAD, ANGRY, SWEATING, TIRED, CONFUSED } Mood;
// Colors for different moods
const SDL_Color colors[] = {
{255, 255, 255, 255}, // HAPPY - white
{200, 200, 200, 255}, // NEUTRAL - grey
{0, 0, 255, 255}, // SAD - blue
{255, 0, 0, 255}, // ANGRY - red
{255, 165, 0, 255}, // SWEATING - orange
{169, 169, 169, 255}, // TIRED - grey
{128, 0, 128, 255} // CONFUSED - purple
};
// Hardcoded pixel art for the cat (3 frames for animation)
const int cat_frames[3][8][8] = {
{ // Frame 1
{0, 1, 1, 0, 0, 1, 1, 0},
{1, 0, 0, 1, 1, 0, 0, 1},
{1, 0, 0, 0, 0, 0, 0, 1},
{1, 0, 1, 0, 0, 1, 0, 1},
{1, 1, 0, 0, 0, 0, 1, 1},
{0, 1, 1, 1, 1, 1, 1, 0},
{0, 0, 1, 1, 1, 1, 0, 0},
{0, 0, 0, 0, 0, 0, 0, 0}
},
{ // Frame 2
{0, 1, 1, 0, 0, 1, 1, 0},
{1, 0, 0, 1, 1, 0, 0, 1},
{1, 0, 0, 0, 0, 0, 0, 1},
{1, 0, 1, 0, 0, 1, 0, 1},
{1, 1, 0, 0, 0, 0, 1, 1},
{0, 0, 1, 1, 1, 1, 0, 0},
{0, 1, 1, 1, 1, 1, 1, 0},
{0, 0, 0, 0, 0, 0, 0, 0}
},
{ // Frame 3
{0, 1, 1, 0, 0, 1, 1, 0},
{1, 0, 0, 1, 1, 0, 0, 1},
{1, 0, 0, 0, 0, 0, 0, 1},
{1, 0, 1, 1, 1, 1, 0, 1},
{1, 1, 0, 0, 0, 0, 1, 1},
{0, 0, 1, 1, 1, 1, 0, 0},
{0, 1, 1, 1, 1, 1, 1, 0},
{0, 0, 0, 0, 0, 0, 0, 0}
}
};
// Function to get CPU usage (simplified)
double get_cpu_usage() {
static long prev_idle = 0, prev_total = 0;
long idle, total;
double usage = 0.0;
FILE *file = fopen("/proc/stat", "r");
if (file == NULL) {
perror("Failed to open /proc/stat");
return 0.0;
}
long user, nice, system, idle_time;
fscanf(file, "cpu %ld %ld %ld %ld", &user, &nice, &system, &idle_time);
fclose(file);
idle = idle_time;
total = user + nice + system + idle;
long delta_idle = idle - prev_idle;
long delta_total = total - prev_total;
if (delta_total != 0) {
usage = (1.0 - ((double)delta_idle / delta_total)) * 100.0;
}
prev_idle = idle;
prev_total = total;
return usage;
}
// Function to get RAM usage percentage
double get_ram_usage() {
long total, free, available;
FILE *file = fopen("/proc/meminfo", "r");
if (file == NULL) {
perror("Failed to open /proc/meminfo");
return 0.0;
}
fscanf(file, "MemTotal: %ld kB\nMemFree: %ld kB\nMemAvailable: %ld kB", &total, &free, &available);
fclose(file);
return ((double)(total - available) / total) * 100.0;
}
// Function to check battery percentage
int get_battery_percentage() {
int percentage = 100;
FILE *file = fopen("/sys/class/power_supply/BAT0/capacity", "r");
if (file) {
fscanf(file, "%d", &percentage);
fclose(file);
}
return percentage;
}
// Function to check internet connection
bool is_connected() {
return system(CONNECTION_CHECK_CMD) == 0;
}
// Function to draw the pet with animation and color based on mood
void draw_pet(SDL_Renderer *renderer, Mood mood, int frame) {
const int (*cat)[8][8] = &cat_frames[frame % 3];
SDL_SetRenderDrawColor(renderer, colors[mood].r, colors[mood].g, colors[mood].b, colors[mood].a);
SDL_RenderClear(renderer);
SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255);
for (int y = 0; y < 8; y++) {
for (int x = 0; x < 8; x++) {
if ((*cat)[y][x] == 1) {
SDL_Rect rect = {x * PIXEL_SIZE, y * PIXEL_SIZE, PIXEL_SIZE, PIXEL_SIZE};
SDL_RenderFillRect(renderer, &rect);
}
}
}
SDL_RenderPresent(renderer);
}
void print_verbose_info(Mood mood, double cpu_usage, double ram_usage, int battery, bool connected) {
const char *mood_names[] = {"HAPPY", "NEUTRAL", "SAD", "ANGRY", "SWEATING", "TIRED", "CONFUSED"};
printf("Mood: %s\n", mood_names[mood]);
printf("CPU Usage: %.2f%%\n", cpu_usage);
printf("RAM Usage: %.2f%%\n", ram_usage);
printf("Battery: %d%%\n", battery);
printf("Internet Connection: %s\n", connected ? "Connected" : "Disconnected");
}
int main(int argc, char *argv[]) {
bool verbose = false;
if (argc > 1 && strcmp(argv[1], "--verbose") == 0) {
verbose = true;
}
if (SDL_Init(SDL_INIT_VIDEO) != 0) {
fprintf(stderr, "SDL_Init Error: %s\n", SDL_GetError());
return 1;
}
SDL_Window *window = SDL_CreateWindow("Cat Pet", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, WINDOW_WIDTH, WINDOW_HEIGHT, SDL_WINDOW_SHOWN);
if (window == NULL) {
fprintf(stderr, "SDL_CreateWindow Error: %s\n", SDL_GetError());
SDL_Quit();
return 1;
}
SDL_Renderer *renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED);
if (renderer == NULL) {
fprintf(stderr, "SDL_CreateRenderer Error: %s\n", SDL_GetError());
SDL_DestroyWindow(window);
SDL_Quit();
return 1;
}
bool running = true;
SDL_Event event;
int frame = 0;
while (running) {
while (SDL_PollEvent(&event)) {
if (event.type == SDL_QUIT) {
running = false;
}
}
double cpu_usage = get_cpu_usage();
double ram_usage = get_ram_usage();
int battery = get_battery_percentage();
bool connected = is_connected();
Mood mood;
if (!connected) {
mood = CONFUSED;
} else if (battery < BATTERY_THRESHOLD) {
mood = TIRED;
} else if (cpu_usage > 80.0) {
mood = ANGRY;
} else if (ram_usage > 80.0) {
mood = SAD;
} else if (cpu_usage > 60.0) {
mood = SWEATING;
} else {
mood = HAPPY;
}
if (verbose) {
print_verbose_info(mood, cpu_usage, ram_usage, battery, connected);
}
draw_pet(renderer, mood, frame);
frame++;
SDL_Delay(500);
}
SDL_DestroyRenderer(renderer);
SDL_DestroyWindow(window);
SDL_Quit();
return 0;
}

BIN
pet_program Executable file

Binary file not shown.

458
pet_program.c Normal file
View File

@@ -0,0 +1,458 @@
#include <SDL2/SDL.h>
#include <stdio.h>
#include <stdbool.h>
#include <unistd.h>
#include <stdlib.h>
#include <time.h>
#include <sys/sysinfo.h>
#include <ifaddrs.h>
#include <string.h>
#include <errno.h>
#define WINDOW_WIDTH 200
#define WINDOW_HEIGHT 200
#define PIXEL_SIZE 8 // Size of each pixel in the pet's display grid
#define GRID_SIZE 25 // 25x25 grid for the cat pixel art
#define BATTERY_THRESHOLD 20
#define EYE_GREEN_CONDITION 100 // Condition for green eyes when battery is fully charged
#define BLINK_INTERVAL 2500 // Interval in milliseconds for blinking
#define CPU_USAGE_THRESHOLD 80
#define RAM_USAGE_THRESHOLD 80
#define METRIC_UPDATE_INTERVAL 60000 // 1 minute in milliseconds
#define VERSION "1.0.0"
// Function prototypes
int get_battery_percentage();
double get_cpu_usage();
double get_ram_usage();
bool is_connected();
void generate_colored_grid(int grid[GRID_SIZE][GRID_SIZE], SDL_Renderer *renderer, SDL_Color color);
void parse_arguments(int argc, char *argv[], bool *verbose, bool *test);
void modify_grid(int grid[GRID_SIZE][GRID_SIZE], bool grey_body, bool red_eyes, bool yellow_eyes, bool green_eyes);
void draw_cat(SDL_Renderer *renderer, int grid[GRID_SIZE][GRID_SIZE]);
void print_help();
void print_version();
// Placeholder for cat pixel art frames and additional views
const int cat_frames[2][GRID_SIZE][GRID_SIZE] = {
// Frame 0: Default cat sitting (add pixel art)
{
{ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
{ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1 },
{ 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1 },
{ 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1 },
{ 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1 },
{ 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1 },
{ 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1, 1, 1, 1, 1, 1 },
{ 1, 1, 1, 1, 1, 1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1, 1, 1, 1, 1 },
{ 1, 1, 1, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 1, 1, 1, 1 },
{ 1, 1, 1, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1 },
{ 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1 },
{ 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1 },
{ 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1 },
{ 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1 },
{ 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1 },
{ 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1 },
{ 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1 },
{ 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1 },
{ 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1 },
{ 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1 },
{ 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1 },
{ 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1 },
{ 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1 },
{ 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
{ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }
},
// Frame 1: Blinking cat (add pixel art)
{
{ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
{ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1 },
{ 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1 },
{ 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1 },
{ 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1 },
{ 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1 },
{ 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1 },
{ 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1 },
{ 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, 1, 1, 1 },
{ 1, 1, 1, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 1, 1, 1, 1 },
{ 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1 },
{ 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1 },
{ 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1 },
{ 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1 },
{ 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1 },
{ 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1 },
{ 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1 },
{ 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1 },
{ 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1 },
{ 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1 },
{ 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1 },
{ 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1 },
{ 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1 },
{ 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
{ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }
}
};
const int sleepy_cat[GRID_SIZE][GRID_SIZE] = {
// Sleepy cat pixel art (add pixel art)
{
{ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
{ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1 },
{ 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1 },
{ 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1 },
{ 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1 },
{ 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1 },
{ 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1 },
{ 1, 1, 1, 1, 1, 1, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 1, 1, 1, 1, 1, 1 },
{ 1, 1, 1, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 1, 1, 1, 1 },
{ 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1 },
{ 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1 },
{ 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1 },
{ 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1 },
{ 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1 },
{ 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1 },
{ 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1 },
{ 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1 },
{ 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1 },
{ 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1 },
{ 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1 },
{ 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1 },
{ 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1 },
{ 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1 },
{ 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
{ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }
}
};
// Function to get battery percentage
int get_battery_percentage() {
FILE *fp = fopen("/sys/class/power_supply/BAT0/capacity", "r");
if (!fp) {
fprintf(stderr, "Error reading battery percentage: %s\n", strerror(errno));
return -1;
}
int battery;
fscanf(fp, "%d", &battery);
fclose(fp);
return battery;
}
// Function to get CPU usage
double get_cpu_usage() {
static long prev_idle = 0, prev_total = 0;
long idle, total;
FILE *fp = fopen("/proc/stat", "r");
if (!fp) {
fprintf(stderr, "Error reading CPU usage: %s\n", strerror(errno));
return 0.0;
}
char buffer[256];
fgets(buffer, sizeof(buffer), fp);
fclose(fp);
long user, nice, system, idle_now, iowait, irq, softirq;
sscanf(buffer, "cpu %ld %ld %ld %ld %ld %ld %ld", &user, &nice, &system, &idle_now, &iowait, &irq, &softirq);
idle = idle_now;
total = user + nice + system + idle_now + iowait + irq + softirq;
double usage = (1.0 - (double)(idle - prev_idle) / (total - prev_total)) * 100.0;
prev_idle = idle;
prev_total = total;
return usage;
}
// Function to get RAM usage
double get_ram_usage() {
struct sysinfo info;
if (sysinfo(&info) != 0) {
fprintf(stderr, "Error reading RAM usage: %s\n", strerror(errno));
return 0.0;
}
double used_ram = (double)(info.totalram - info.freeram) / info.totalram * 100.0;
return used_ram;
}
// Function to check internet connection
bool is_connected() {
struct ifaddrs *ifaddr, *ifa;
bool connected = false;
if (getifaddrs(&ifaddr) == -1) {
fprintf(stderr, "Error checking internet connection: %s\n", strerror(errno));
return false;
}
for (ifa = ifaddr; ifa != NULL; ifa = ifa->ifa_next) {
if (ifa->ifa_addr && ifa->ifa_addr->sa_family == AF_INET) {
connected = true;
break;
}
}
freeifaddrs(ifaddr);
return connected;
}
// Function to parse command line arguments
void parse_arguments(int argc, char *argv[], bool *verbose, bool *test) {
for (int i = 1; i < argc; i++) {
if (strcmp(argv[i], "--verbose") == 0) {
*verbose = true;
} else if (strcmp(argv[i], "--test") == 0) {
*verbose = true;
*test = true;
} else if (strcmp(argv[i], "--version") == 0) {
print_version();
exit(0);
} else if (strcmp(argv[i], "--help") == 0) {
print_help();
exit(0);
} else {
fprintf(stderr, "Unknown option: %s\n", argv[i]);
print_help();
exit(1);
}
}
}
// Function to print help message
void print_help() {
printf("Usage: pet_program [OPTIONS]\n");
printf("Options:\n");
printf(" --verbose Show detailed debug information\n");
printf(" --test Simulate changing metrics for testing\n");
printf(" --version Show program version\n");
printf(" --help Show this help message\n");
}
// Function to print version
void print_version() {
printf("Pet Program Version %s\n", VERSION);
}
// Function to modify grid for high CPU, RAM, or no internet
void modify_grid(int grid[GRID_SIZE][GRID_SIZE], bool grey_body, bool red_eyes, bool yellow_eyes, bool green_eyes) {
for (int y = 0; y < GRID_SIZE; y++) {
for (int x = 0; x < GRID_SIZE; x++) {
if (grey_body) {
if (grid[y][x] == 1) {
grid[y][x] = 2; // Grey for no internet
}
} else if (green_eyes) {
if (y >= 7 && y <= 8 && (x == 8 || x == 16)) { // Eye positions
grid[y][x] = 5; // Green for full battery
}
} else if (red_eyes) {
if (y >= 7 && y <= 8 && (x == 8 || x == 16)) { // Eye positions
grid[y][x] = 3; // Red for high CPU
}
} else if (yellow_eyes) {
if (y >= 7 && y <= 8 && (x == 8 || x == 16)) { // Eye positions
grid[y][x] = 4; // Yellow for high RAM
}
}
}
}
}
// Function to draw the cat with different colors based on system metrics
void draw_cat(SDL_Renderer *renderer, int grid[GRID_SIZE][GRID_SIZE]) {
SDL_Color color;
SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255); // Black background
SDL_RenderClear(renderer);
for (int y = 0; y < GRID_SIZE; y++) {
for (int x = 0; x < GRID_SIZE; x++) {
switch (grid[y][x]) {
case 1:
color = (SDL_Color){255, 255, 255, 255}; // White
break;
case 2:
color = (SDL_Color){169, 169, 169, 255}; // Grey
break;
case 3:
color = (SDL_Color){255, 0, 0, 255}; // Red
break;
case 4:
color = (SDL_Color){255, 255, 0, 255}; // Yellow
break;
case 5:
color = (SDL_Color){0, 255, 0, 255}; // Green
break;
default:
continue;
}
SDL_SetRenderDrawColor(renderer, color.r, color.g, color.b, color.a);
SDL_Rect rect = {x * PIXEL_SIZE, y * PIXEL_SIZE, PIXEL_SIZE, PIXEL_SIZE};
SDL_RenderFillRect(renderer, &rect);
}
}
SDL_RenderPresent(renderer);
}
int main(int argc, char *argv[]) {
srand(time(NULL));
bool verbose = false;
bool test = false;
parse_arguments(argc, argv, &verbose, &test);
if (SDL_Init(SDL_INIT_VIDEO) != 0) {
fprintf(stderr, "SDL_Init Error: %s\n", SDL_GetError());
return 1;
}
SDL_Window *window = SDL_CreateWindow("Cat Pet", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, WINDOW_WIDTH, WINDOW_HEIGHT, SDL_WINDOW_SHOWN);
if (!window) {
fprintf(stderr, "SDL_CreateWindow Error: %s\n", SDL_GetError());
SDL_Quit();
return 1;
}
SDL_Renderer *renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED);
if (!renderer) {
fprintf(stderr, "SDL_CreateRenderer Error: %s\n", SDL_GetError());
SDL_DestroyWindow(window);
SDL_Quit();
return 1;
}
bool running = true;
SDL_Event event;
int frame = 0;
Uint32 last_blink_time = SDL_GetTicks();
Uint32 last_metric_update = SDL_GetTicks();
int test_state = 0; // State counter for cycling through test scenarios
int battery = 100;
double cpu_usage = 0.0;
double ram_usage = 0.0;
bool connected = true;
while (running) {
while (SDL_PollEvent(&event)) {
if (event.type == SDL_QUIT) {
running = false;
}
}
Uint32 current_time = SDL_GetTicks();
if (current_time - last_metric_update >= METRIC_UPDATE_INTERVAL) {
if (test) {
// Cycle through different test scenarios
switch (test_state) {
case 0:
battery = 100; // Full battery (green eyes)
cpu_usage = 0.0;
ram_usage = 0.0;
connected = true;
break;
case 1:
battery = 50;
cpu_usage = 90.0; // High CPU (red eyes)
ram_usage = 0.0;
connected = true;
break;
case 2:
battery = 50;
cpu_usage = 0.0;
ram_usage = 90.0; // High RAM (yellow eyes)
connected = true;
break;
case 3:
battery = 50;
cpu_usage = 0.0;
ram_usage = 0.0;
connected = false; // No internet (grey body)
break;
default:
battery = 100;
cpu_usage = 0.0;
ram_usage = 0.0;
connected = true;
break;
}
test_state = (test_state + 1) % 4;
} else {
battery = get_battery_percentage();
cpu_usage = get_cpu_usage();
ram_usage = get_ram_usage();
connected = is_connected();
}
last_metric_update = current_time;
if (verbose) {
printf("Battery: %d%%\n", battery);
printf("CPU Usage: %.2f%%\n", cpu_usage);
printf("RAM Usage: %.2f%%\n", ram_usage);
printf("Internet Connection: %s\n", connected ? "Connected" : "Disconnected");
}
}
bool green_eyes = (battery >= EYE_GREEN_CONDITION);
bool grey_body = !connected;
bool red_eyes = (cpu_usage >= CPU_USAGE_THRESHOLD);
bool yellow_eyes = (ram_usage >= RAM_USAGE_THRESHOLD);
bool sleepy_mode = (battery < BATTERY_THRESHOLD);
// Ensure logging happens before updating test state
last_metric_update = current_time;
if (test) {
// Cycle through different test scenarios
switch (test_state) {
case 0:
battery = 100; // Full battery (green eyes)
cpu_usage = 0.0;
ram_usage = 0.0;
connected = true;
break;
case 1:
battery = 50;
cpu_usage = 90.0; // High CPU (red eyes)
ram_usage = 0.0;
connected = true;
break;
case 2:
battery = 50;
cpu_usage = 0.0;
ram_usage = 90.0; // High RAM (yellow eyes)
connected = true;
break;
case 3:
battery = 50;
cpu_usage = 0.0;
ram_usage = 0.0;
connected = false; // No internet (grey body)
break;
}
test_state = (test_state + 1) % 4;
}
if (current_time - last_blink_time >= BLINK_INTERVAL) {
frame = (frame + 1) % 2; // Toggle between frame 0 and 1 for blinking
last_blink_time = current_time;
}
int current_grid[GRID_SIZE][GRID_SIZE];
if (sleepy_mode) {
memcpy(current_grid, sleepy_cat, sizeof(current_grid)); // Use sleepy cat grid
} else {
memcpy(current_grid, cat_frames[frame], sizeof(current_grid)); // Use regular/blinking grid
}
modify_grid(current_grid, grey_body, red_eyes && frame == 0, yellow_eyes && frame == 0, green_eyes && frame == 0);
draw_cat(renderer, current_grid);
SDL_Delay(100); // Delay to control frame rate
}
SDL_DestroyRenderer(renderer);
SDL_DestroyWindow(window);
SDL_Quit();
return 0;
}

394
pet_program.c.bak Normal file
View File

@@ -0,0 +1,394 @@
#include <SDL2/SDL.h>
#include <stdio.h>
#include <stdbool.h>
#include <unistd.h>
#include <stdlib.h>
#include <time.h>
#include <sys/sysinfo.h>
#include <ifaddrs.h>
#include <string.h>
#include <errno.h>
#define WINDOW_WIDTH 200
#define WINDOW_HEIGHT 200
#define PIXEL_SIZE 8 // Size of each pixel in the pet's display grid
#define GRID_SIZE 25 // 25x25 grid for the cat pixel art
#define BATTERY_THRESHOLD 20
#define EYE_GREEN_CONDITION 100 // Condition for green eyes when battery is fully charged
#define BLINK_INTERVAL 2500 // Interval in milliseconds for blinking
#define CPU_USAGE_THRESHOLD 80
#define RAM_USAGE_THRESHOLD 80
#define METRIC_UPDATE_INTERVAL 60000 // 1 minute in milliseconds
#define VERSION "1.0.0"
// Function prototypes
int get_battery_percentage();
double get_cpu_usage();
double get_ram_usage();
bool is_connected();
void generate_colored_grid(int grid[GRID_SIZE][GRID_SIZE], SDL_Renderer *renderer, SDL_Color color);
void parse_arguments(int argc, char *argv[], bool *verbose, bool *test);
void modify_grid(int grid[GRID_SIZE][GRID_SIZE], bool grey_body, bool red_eyes, bool yellow_eyes, bool green_eyes);
void draw_cat(SDL_Renderer *renderer, int grid[GRID_SIZE][GRID_SIZE]);
void print_help();
void print_version();
// Placeholder for cat pixel art frames and additional views
const int cat_frames[2][GRID_SIZE][GRID_SIZE] = {
// Frame 0: Default cat sitting (add pixel art)
{
{ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
{ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1 },
{ 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1 },
{ 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1 },
{ 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1 },
{ 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1 },
{ 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1, 1, 1, 1, 1, 1 },
{ 1, 1, 1, 1, 1, 1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1, 1, 1, 1, 1 },
{ 1, 1, 1, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 1, 1, 1, 1 },
{ 1, 1, 1, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1 },
{ 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1 },
{ 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1 },
{ 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1 },
{ 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1 },
{ 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1 },
{ 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1 },
{ 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1 },
{ 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1 },
{ 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1 },
{ 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1 },
{ 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1 },
{ 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1 },
{ 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1 },
{ 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
{ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }
},
// Frame 1: Blinking cat (add pixel art)
{
{ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
{ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1 },
{ 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1 },
{ 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1 },
{ 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1 },
{ 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1 },
{ 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1 },
{ 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1 },
{ 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, 1, 1, 1 },
{ 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 1, 1, 1, 1 },
{ 1, 1, 1, 1, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1 },
{ 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1 },
{ 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1 },
{ 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1 },
{ 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1 },
{ 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1 },
{ 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1 },
{ 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1 },
{ 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1 },
{ 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1 },
{ 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1 },
{ 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1 },
{ 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1 },
{ 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
{ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }
}
};
const int sleepy_cat[GRID_SIZE][GRID_SIZE] = {
// Sleepy cat pixel art (add pixel art)
{}
};
// Function to get battery percentage
int get_battery_percentage() {
FILE *fp = fopen("/sys/class/power_supply/BAT0/capacity", "r");
if (!fp) {
fprintf(stderr, "Error reading battery percentage: %s\n", strerror(errno));
return -1;
}
int battery;
fscanf(fp, "%d", &battery);
fclose(fp);
return battery;
}
// Function to get CPU usage
double get_cpu_usage() {
static long prev_idle = 0, prev_total = 0;
long idle, total;
FILE *fp = fopen("/proc/stat", "r");
if (!fp) {
fprintf(stderr, "Error reading CPU usage: %s\n", strerror(errno));
return 0.0;
}
char buffer[256];
fgets(buffer, sizeof(buffer), fp);
fclose(fp);
long user, nice, system, idle_now, iowait, irq, softirq;
sscanf(buffer, "cpu %ld %ld %ld %ld %ld %ld %ld", &user, &nice, &system, &idle_now, &iowait, &irq, &softirq);
idle = idle_now;
total = user + nice + system + idle_now + iowait + irq + softirq;
double usage = (1.0 - (double)(idle - prev_idle) / (total - prev_total)) * 100.0;
prev_idle = idle;
prev_total = total;
return usage;
}
// Function to get RAM usage
double get_ram_usage() {
struct sysinfo info;
if (sysinfo(&info) != 0) {
fprintf(stderr, "Error reading RAM usage: %s\n", strerror(errno));
return 0.0;
}
double used_ram = (double)(info.totalram - info.freeram) / info.totalram * 100.0;
return used_ram;
}
// Function to check internet connection
bool is_connected() {
struct ifaddrs *ifaddr, *ifa;
bool connected = false;
if (getifaddrs(&ifaddr) == -1) {
fprintf(stderr, "Error checking internet connection: %s\n", strerror(errno));
return false;
}
for (ifa = ifaddr; ifa != NULL; ifa = ifa->ifa_next) {
if (ifa->ifa_addr && ifa->ifa_addr->sa_family == AF_INET) {
connected = true;
break;
}
}
freeifaddrs(ifaddr);
return connected;
}
// Function to parse command line arguments
void parse_arguments(int argc, char *argv[], bool *verbose, bool *test) {
for (int i = 1; i < argc; i++) {
if (strcmp(argv[i], "--verbose") == 0) {
*verbose = true;
} else if (strcmp(argv[i], "--test") == 0) {
*verbose = true;
*test = true;
} else if (strcmp(argv[i], "--version") == 0) {
print_version();
exit(0);
} else if (strcmp(argv[i], "--help") == 0) {
print_help();
exit(0);
} else {
fprintf(stderr, "Unknown option: %s\n", argv[i]);
print_help();
exit(1);
}
}
}
// Function to print help message
void print_help() {
printf("Usage: pet_program [OPTIONS]\n");
printf("Options:\n");
printf(" --verbose Show detailed debug information\n");
printf(" --test Simulate changing metrics for testing\n");
printf(" --version Show program version\n");
printf(" --help Show this help message\n");
}
// Function to print version
void print_version() {
printf("Pet Program Version %s\n", VERSION);
}
// Function to modify grid for high CPU, RAM, or no internet
void modify_grid(int grid[GRID_SIZE][GRID_SIZE], bool grey_body, bool red_eyes, bool yellow_eyes, bool green_eyes) {
for (int y = 0; y < GRID_SIZE; y++) {
for (int x = 0; x < GRID_SIZE; x++) {
if (grey_body) {
if (grid[y][x] == 1) {
grid[y][x] = 2; // Grey for no internet
}
} else if (green_eyes) {
if (y >= 7 && y <= 8 && (x == 8 || x == 16)) { // Eye positions
grid[y][x] = 5; // Green for full battery
}
} else if (red_eyes || yellow_eyes) {
if (y >= 7 && y <= 8 && (x == 8 || x == 16)) { // Eye positions
grid[y][x] = (red_eyes ? 3 : 4); // Red for high CPU, Yellow for high RAM
}
}
}
}
}
// Function to draw the cat with different colors based on system metrics
void draw_cat(SDL_Renderer *renderer, int grid[GRID_SIZE][GRID_SIZE]) {
SDL_Color color;
SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255); // Black background
SDL_RenderClear(renderer);
for (int y = 0; y < GRID_SIZE; y++) {
for (int x = 0; x < GRID_SIZE; x++) {
switch (grid[y][x]) {
case 1:
color = (SDL_Color){255, 255, 255, 255}; // White
break;
case 2:
color = (SDL_Color){169, 169, 169, 255}; // Grey
break;
case 3:
color = (SDL_Color){255, 0, 0, 255}; // Red
break;
case 4:
color = (SDL_Color){255, 255, 0, 255}; // Yellow
break;
case 5:
color = (SDL_Color){0, 255, 0, 255}; // Green
break;
default:
continue;
}
SDL_SetRenderDrawColor(renderer, color.r, color.g, color.b, color.a);
SDL_Rect rect = {x * PIXEL_SIZE, y * PIXEL_SIZE, PIXEL_SIZE, PIXEL_SIZE};
SDL_RenderFillRect(renderer, &rect);
}
}
SDL_RenderPresent(renderer);
}
int main(int argc, char *argv[]) {
srand(time(NULL));
bool verbose = false;
bool test = false;
parse_arguments(argc, argv, &verbose, &test);
if (SDL_Init(SDL_INIT_VIDEO) != 0) {
fprintf(stderr, "SDL_Init Error: %s\n", SDL_GetError());
return 1;
}
SDL_Window *window = SDL_CreateWindow("Cat Pet", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, WINDOW_WIDTH, WINDOW_HEIGHT, SDL_WINDOW_SHOWN);
if (!window) {
fprintf(stderr, "SDL_CreateWindow Error: %s\n", SDL_GetError());
SDL_Quit();
return 1;
}
SDL_Renderer *renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED);
if (!renderer) {
fprintf(stderr, "SDL_CreateRenderer Error: %s\n", SDL_GetError());
SDL_DestroyWindow(window);
SDL_Quit();
return 1;
}
bool running = true;
SDL_Event event;
int frame = 0;
Uint32 last_blink_time = SDL_GetTicks();
Uint32 last_metric_update = SDL_GetTicks();
int test_state = 0; // State counter for cycling through test scenarios
int battery = 100;
double cpu_usage = 0.0;
double ram_usage = 0.0;
bool connected = true;
while (running) {
while (SDL_PollEvent(&event)) {
if (event.type == SDL_QUIT) {
running = false;
}
}
Uint32 current_time = SDL_GetTicks();
if (current_time - last_metric_update >= METRIC_UPDATE_INTERVAL) {
if (test) {
// Cycle through different test scenarios
switch (test_state) {
case 0:
battery = 100; // Full battery (green eyes)
cpu_usage = 0.0;
ram_usage = 0.0;
connected = true;
break;
case 1:
battery = 50;
cpu_usage = 90.0; // High CPU (red eyes)
ram_usage = 0.0;
connected = true;
break;
case 2:
battery = 50;
cpu_usage = 0.0;
ram_usage = 90.0; // High RAM (yellow eyes)
connected = true;
break;
case 3:
battery = 50;
cpu_usage = 0.0;
ram_usage = 0.0;
connected = false; // No internet (grey body)
break;
default:
battery = 100;
cpu_usage = 0.0;
ram_usage = 0.0;
connected = true;
break;
}
test_state = (test_state + 1) % 4;
} else {
battery = get_battery_percentage();
cpu_usage = get_cpu_usage();
ram_usage = get_ram_usage();
connected = is_connected();
}
last_metric_update = current_time;
if (verbose) {
printf("Battery: %d%%\n", battery);
printf("CPU Usage: %.2f%%\n", cpu_usage);
printf("RAM Usage: %.2f%%\n", ram_usage);
printf("Internet Connection: %s\n", connected ? "Connected" : "Disconnected");
}
}
bool green_eyes = (battery >= EYE_GREEN_CONDITION);
bool grey_body = !connected;
bool red_eyes = (cpu_usage >= CPU_USAGE_THRESHOLD);
bool yellow_eyes = (ram_usage >= RAM_USAGE_THRESHOLD);
bool sleepy_mode = (battery < BATTERY_THRESHOLD);
if (current_time - last_blink_time >= BLINK_INTERVAL) {
frame = (frame + 1) % 2; // Toggle between frame 0 and 1 for blinking
last_blink_time = current_time;
}
int current_grid[GRID_SIZE][GRID_SIZE];
if (sleepy_mode) {
memcpy(current_grid, sleepy_cat, sizeof(current_grid)); // Use sleepy cat grid
} else {
memcpy(current_grid, cat_frames[frame], sizeof(current_grid)); // Use regular/blinking grid
}
modify_grid(current_grid, grey_body, red_eyes && frame == 0, yellow_eyes && frame == 0, green_eyes && frame == 0);
draw_cat(renderer, current_grid);
SDL_Delay(100); // Delay to control frame rate
}
SDL_DestroyRenderer(renderer);
SDL_DestroyWindow(window);
SDL_Quit();
return 0;
}