updated metricpet

This commit is contained in:
klein panic
2025-01-10 13:49:44 -05:00
parent efec2bbd59
commit c60843f9ff
14 changed files with 487 additions and 1114 deletions

1
.gitignore vendored Normal file
View File

@@ -0,0 +1 @@
tests/

22
LICENSE Normal file
View File

@@ -0,0 +1,22 @@
MIT License
Copyright (c) [year] [fullname]
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

20
Makefile Normal file
View File

@@ -0,0 +1,20 @@
CC = gcc
CFLAGS = -Wall -Wextra -O3 `sdl2-config --cflags`
LDFLAGS = `sdl2-config --libs` -lSDL2_image
TARGET = metricpet
SRC = metricpet.c
BIN_DIR = /usr/local/bin
all: $(TARGET)
$(TARGET): $(SRC)
$(CC) $(CFLAGS) $(SRC) -o $(TARGET) $(LDFLAGS)
clean:
rm -f $(TARGET)
install: $(TARGET)
sudo mv $(TARGET) $(BIN_DIR)
.PHONY: all clean install

View File

@@ -1 +1,77 @@
# metriccat
# MetricPet
**MetricPet** is a fun, visual terminal program that displays a pixel-art pet cat whose appearance changes dynamically based on your system's metrics. The cat will display different moods and eye colors based on CPU usage, RAM usage, battery percentage, and internet connection status.
## Features
- **Dynamic Appearance**: The cat changes its eye color or body color based on system metrics:
- **Green Eyes**: Full battery.
- **Red Eyes**: High CPU usage.
- **Yellow Eyes**: High RAM usage.
- **Grey Body**: No internet connection.
- **Blinking Animation**: The cat blinks every few seconds.
- **Test Mode**: Simulates different system conditions to visualize how the pet reacts.
- **Verbose Mode**: Shows detailed debug information about current system metrics.
## Installation
1. Clone the repository and navigate to the directory.
2. Build and install the program using the following commands:
```bash
make
sudo make install
```
This will move the compiled binary to `/usr/local/bin`, making it accessible from anywhere.
3. To clean up the build files, run:
```bash
make clean
```
## Usage
```bash
metricpet [OPTIONS]
```
### Available Options
- `--verbose`: Show detailed debug information about system metrics.
- `--test`: Simulate changing metrics to see how the pet reacts.
- `--version`: Display the program version.
- `--help`: Display the help message.
## Example
```bash
metricpet --verbose
```
This command will display the pet while showing detailed metric information in the terminal.
```bash
metricpet --test
```
This command will simulate high CPU, high RAM, low battery, and no internet states in sequence.
## Requirements
- SDL2 library
- SDL2_image library
You can install these libraries using the following commands:
### On Debian/Ubuntu:
```bash
sudo apt update
sudo apt install libsdl2-dev libsdl2-image-dev
```
### On Arch Linux:
```bash
sudo pacman -S sdl2 sdl2_image
```
---

Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

View File

@@ -1,54 +0,0 @@
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:
#########################
################ #######
##### ######## ######
##### ###### ######
##### ######
##### ## ######
##### ## ## ######
###### # # # # ######
##### # # #####
##### # ### #####
##### ## # #####
##### ######
###### ######
###### #######
####### ########
######## ########
######## #######
######## ######
####### ######
####### ######
###### ######
###### ######
###### #######
######### #########
#########################

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.9 KiB

Binary file not shown.

View File

@@ -1,71 +0,0 @@
#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;
}

BIN
metricpet Executable file

Binary file not shown.

View File

@@ -4,159 +4,300 @@
#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 64
#define WINDOW_HEIGHT 64
#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 CONNECTION_CHECK_CMD "ping -c 1 google.com > /dev/null 2>&1"
#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"
// Pet mood states
typedef enum { HAPPY, NEUTRAL, SAD, ANGRY, SWEATING, TIRED, CONFUSED } Mood;
// 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();
// 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}
// 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 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}
// 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 }
}
};
// Function to get CPU usage (simplified)
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;
double usage = 0.0;
FILE *file = fopen("/proc/stat", "r");
if (file == NULL) {
perror("Failed to open /proc/stat");
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_time;
fscanf(file, "cpu %ld %ld %ld %ld", &user, &nice, &system, &idle_time);
fclose(file);
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_time;
total = user + nice + system + idle;
idle = idle_now;
total = user + nice + system + idle_now + iowait + irq + softirq;
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;
}
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 percentage
// Function to get RAM usage
double get_ram_usage() {
long total, free, available;
FILE *file = fopen("/proc/meminfo", "r");
if (file == NULL) {
perror("Failed to open /proc/meminfo");
struct sysinfo info;
if (sysinfo(&info) != 0) {
fprintf(stderr, "Error reading RAM usage: %s\n", strerror(errno));
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;
double used_ram = (double)(info.totalram - info.freeram) / info.totalram * 100.0;
return used_ram;
}
// Function to check internet connection
bool is_connected() {
return system(CONNECTION_CHECK_CMD) == 0;
}
struct ifaddrs *ifaddr, *ifa;
bool connected = false;
// 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);
if (getifaddrs(&ifaddr) == -1) {
fprintf(stderr, "Error checking internet connection: %s\n", strerror(errno));
return false;
}
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);
}
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);
}
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[]) {
srand(time(NULL));
bool verbose = false;
if (argc > 1 && strcmp(argv[1], "--verbose") == 0) {
verbose = true;
}
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());
@@ -164,14 +305,14 @@ int main(int argc, char *argv[]) {
}
SDL_Window *window = SDL_CreateWindow("Cat Pet", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, WINDOW_WIDTH, WINDOW_HEIGHT, SDL_WINDOW_SHOWN);
if (window == NULL) {
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 == NULL) {
if (!renderer) {
fprintf(stderr, "SDL_CreateRenderer Error: %s\n", SDL_GetError());
SDL_DestroyWindow(window);
SDL_Quit();
@@ -181,6 +322,14 @@ int main(int argc, char *argv[]) {
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)) {
@@ -189,33 +338,115 @@ int main(int argc, char *argv[]) {
}
}
double cpu_usage = get_cpu_usage();
double ram_usage = get_ram_usage();
int battery = get_battery_percentage();
bool connected = is_connected();
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;
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;
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 {
mood = HAPPY;
memcpy(current_grid, cat_frames[frame], sizeof(current_grid)); // Use regular/blinking grid
}
if (verbose) {
print_verbose_info(mood, cpu_usage, ram_usage, battery, connected);
}
modify_grid(current_grid, grey_body, red_eyes && frame == 0, yellow_eyes && frame == 0, green_eyes && frame == 0);
draw_cat(renderer, current_grid);
draw_pet(renderer, mood, frame);
frame++;
SDL_Delay(500);
SDL_Delay(100); // Delay to control frame rate
}
SDL_DestroyRenderer(renderer);

Binary file not shown.

View File

@@ -1,458 +0,0 @@
#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;
}

View File

@@ -1,394 +0,0 @@
#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;
}