[BUG FIXES UPDATE]
-Fix wrong calculations in the calculator
-Properly save paint files to where they were opened instead of just the desktop.
This commit is contained in:
Chris 2026-02-08 15:20:00 +01:00
parent 9728222d3c
commit a053e7ccc2
17 changed files with 196 additions and 210 deletions

View file

@ -1,4 +1,4 @@
# Brew OS 1.40 Beta
# Brew OS 1.42 Beta
BrewOS is now in a Beta stage as i have brought over all apps from brewkernel and have made the DE a lot more usable and stable.
## Brewkernel is now BrewOS!
@ -84,6 +84,7 @@ qemu-system-x86_64 -m 2G -serial stdio -cdrom brewos.iso -boot d
3. **Boot**: Insert the USB drive and select it in the boot menu during startup
**Networking requires an Intel E1000 network card or similar while using Ethernet.**
4. **Tested Hardware**:
- HP EliteDesk 705 G4 DM (AMD Ryzen 5 PRO 2400G, Radeon Vega) **Tested, no networking.**
- Lenovo ThinkPad A475 20KL002VMH (AMD Pro A12-8830B, Radeon R7) **Tested, no networking.**

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View file

@ -1,4 +1,4 @@
# Brew OS 1.40 Beta
# Brew OS 1.42 Beta
BrewOS is now in a Beta stage as i have brought over all apps from brewkernel and have made the DE a lot more usable and stable.
## Brewkernel is now BrewOS!
@ -84,6 +84,7 @@ qemu-system-x86_64 -m 2G -serial stdio -cdrom brewos.iso -boot d
3. **Boot**: Insert the USB drive and select it in the boot menu during startup
**Networking requires an Intel E1000 network card or similar while using Ethernet.**
4. **Tested Hardware**:
- HP EliteDesk 705 G4 DM (AMD Ryzen 5 PRO 2400G, Radeon Vega) **Tested, no networking.**
- Lenovo ThinkPad A475 20KL002VMH (AMD Pro A12-8830B, Radeon R7) **Tested, no networking.**

Binary file not shown.

View file

@ -1,99 +0,0 @@
#ifndef NET_DEFS_H
#define NET_DEFS_H
#include <stdint.h>
#include <stddef.h>
#include <stdbool.h>
// Ensure we have the IP type from your existing stack
#include "network.h"
// Protocol Numbers
#define IP_PROTO_ICMP 1
#define IP_PROTO_TCP 6
#define IP_PROTO_UDP 17
// Byte Order Utils
static inline uint16_t htons(uint16_t v) {
return (v << 8) | (v >> 8);
}
static inline uint16_t ntohs(uint16_t v) {
return (v << 8) | (v >> 8);
}
static inline uint32_t htonl(uint32_t v) {
return ((v & 0xFF) << 24) | ((v & 0xFF00) << 8) | ((v & 0xFF0000) >> 8) | ((v >> 24) & 0xFF);
}
static inline uint32_t ntohl(uint32_t v) {
return htonl(v);
}
// Checksum Calculation
static inline uint16_t net_checksum(void *data, int len) {
uint32_t sum = 0;
uint16_t *p = (uint16_t *)data;
while (len > 1) {
sum += *p++;
len -= 2;
}
if (len) {
sum += *(uint8_t *)p;
}
while (sum >> 16) {
sum = (sum & 0xFFFF) + (sum >> 16);
}
return (uint16_t)~sum;
}
// --- Headers ---
typedef struct {
uint8_t type;
uint8_t code;
uint16_t checksum;
uint16_t id;
uint16_t sequence;
} __attribute__((packed)) icmp_header_t;
typedef struct {
uint16_t src_port;
uint16_t dst_port;
uint32_t seq_num;
uint32_t ack_num;
uint8_t data_offset; // High 4 bits: offset, Low 4 bits: reserved/NS
uint8_t flags;
uint16_t window_size;
uint16_t checksum;
uint16_t urgent_ptr;
} __attribute__((packed)) tcp_header_t;
#define TCP_FIN 0x01
#define TCP_SYN 0x02
#define TCP_RST 0x04
#define TCP_PSH 0x08
#define TCP_ACK 0x10
#define TCP_URG 0x20
typedef struct {
uint16_t id;
uint16_t flags;
uint16_t q_count;
uint16_t ans_count;
uint16_t auth_count;
uint16_t add_count;
} __attribute__((packed)) dns_header_t;
// External dependencies from your existing IP layer
// You must ensure these are implemented in network.c
extern int ip_send_packet(ipv4_address_t dst, uint8_t protocol, const void *data, uint16_t len);
extern ipv4_address_t get_local_ip(void);
// New functions exposed by modules
void icmp_handle_packet(ipv4_address_t src, void *data, uint16_t len);
void tcp_handle_packet(ipv4_address_t src, void *data, uint16_t len);
// CLI Commands
void cli_cmd_ping(char *args);
void cli_cmd_dns(char *args);
void cli_cmd_httpget(char *args);
#endif

View file

@ -35,7 +35,7 @@ static void about_paint(Window *win) {
// Version info
draw_string(offset_x, offset_y + 105, "BrewOS", COLOR_BLACK);
draw_string(offset_x, offset_y + 120, "BrewOS Version 1.40", COLOR_BLACK);
draw_string(offset_x, offset_y + 120, "BrewOS Version 1.42", COLOR_BLACK);
draw_string(offset_x, offset_y + 135, "Kernel Version 2.3.1", COLOR_BLACK);
// Copyright

View file

@ -6,32 +6,84 @@
Window win_calculator;
#define SCALE 1000000LL
static long long calc_acc = 0;
static long long calc_curr = 0;
static char calc_op = 0;
static bool calc_new_entry = true;
static bool calc_error = false;
static bool calc_decimal_mode = false;
static long long calc_decimal_divisor = 10;
// Helper to convert int to string
static void int_to_str(long long n, char *buf) {
// Simple integer square root
static long long isqrt(long long n) {
if (n < 0) return -1;
if (n == 0) return 0;
long long x = n;
long long y = 1;
while (x > y) {
x = (x + y) / 2;
y = n / x;
}
return x;
}
// Convert fixed point to string
static void fixed_to_str(long long n, char *buf) {
if (n == 0) {
buf[0] = '0'; buf[1] = 0; return;
}
int i = 0;
char temp[64];
int pos = 0;
bool neg = n < 0;
if (neg) n = -n;
char temp[32];
while (n > 0) {
temp[i++] = '0' + (n % 10);
n /= 10;
}
if (neg) temp[i++] = '-';
long long int_part = n / SCALE;
long long frac_part = n % SCALE;
// Fraction part
char frac_buf[16];
int f_idx = 0;
// Fill exactly 6 digits
for(int k=0; k<6; k++) {
long long div = 100000;
for(int m=0; m<k; m++) div /= 10;
frac_buf[f_idx++] = '0' + ((frac_part / div) % 10);
}
frac_buf[f_idx] = 0;
// Trim trailing zeros
while (f_idx > 0 && frac_buf[f_idx-1] == '0') {
f_idx--;
}
frac_buf[f_idx] = 0;
// If we have a fraction, add it to buffer (reversed first)
if (f_idx > 0) {
for (int i = f_idx - 1; i >= 0; i--) {
temp[pos++] = frac_buf[i];
}
temp[pos++] = '.';
}
// Integer part
if (int_part == 0) {
temp[pos++] = '0';
} else {
while (int_part > 0) {
temp[pos++] = '0' + (int_part % 10);
int_part /= 10;
}
}
if (neg) temp[pos++] = '-';
// Reverse into buf
int j = 0;
while (i > 0) {
buf[j++] = temp[--i];
while (pos > 0) {
buf[j++] = temp[--pos];
}
buf[j] = 0;
}
@ -42,7 +94,7 @@ static void update_display(Window *win) {
int i = 0; while(err[i]) { win->buffer[i] = err[i]; i++; }
win->buffer[i] = 0;
} else {
int_to_str(calc_curr, win->buffer);
fixed_to_str(calc_curr, win->buffer);
}
win->buf_len = 0; while(win->buffer[win->buf_len]) win->buf_len++;
}
@ -59,22 +111,26 @@ static void calculator_paint(Window *win) {
draw_string(text_x, win->y + 38, win->buffer, COLOR_BLACK);
// Buttons
// Layout 4 columns x 5 rows
const char *labels[] = {
"7", "8", "9", "/",
"4", "5", "6", "*",
"1", "2", "3", "-",
"0", "C", "=", "+"
"C", "sqr", "rt", "/",
"7", "8", "9", "*",
"4", "5", "6", "-",
"1", "2", "3", "+",
"0", ".", "BS", "="
};
int bw = 30;
int bw = 35;
int bh = 25;
int gap = 5;
int start_x = win->x + 10;
int start_y = win->y + 65;
for (int i = 0; i < 16; i++) {
for (int i = 0; i < 20; i++) {
int r = i / 4;
int c = i % 4;
// Special drawing for some buttons?
draw_button(start_x + c*(bw+gap), start_y + r*(bh+gap), bw, bh, labels[i], false);
}
}
@ -82,64 +138,112 @@ static void calculator_paint(Window *win) {
static void do_op(void) {
if (calc_op == '+') calc_acc += calc_curr;
else if (calc_op == '-') calc_acc -= calc_curr;
else if (calc_op == '*') calc_acc *= calc_curr;
else if (calc_op == '*') {
calc_acc = (calc_acc * calc_curr) / SCALE;
}
else if (calc_op == '/') {
if (calc_curr == 0) calc_error = true;
else calc_acc /= calc_curr;
else {
calc_acc = (calc_acc * SCALE) / calc_curr;
}
} else {
calc_acc = calc_curr;
}
}
static void calculator_click(Window *win, int x, int y) {
int bw = 30;
int bw = 35;
int bh = 25;
int gap = 5;
int start_x = 10;
int start_y = 65;
for (int i = 0; i < 16; i++) {
for (int i = 0; i < 20; i++) {
int r = i / 4;
int c = i % 4;
int bx = start_x + c*(bw+gap);
int by = start_y + r*(bh+gap);
if (x >= bx && x < bx + bw && y >= by && y < by + bh) {
// Clicked button i
const char *labels[] = {
"7", "8", "9", "/",
"4", "5", "6", "*",
"1", "2", "3", "-",
"0", "C", "=", "+"
"C", "sqr", "rt", "/",
"7", "8", "9", "*",
"4", "5", "6", "-",
"1", "2", "3", "+",
"0", ".", "BS", "="
};
char lbl = labels[i][0];
const char *lbl_str = labels[i];
char lbl = lbl_str[0];
if (lbl >= '0' && lbl <= '9') {
if (calc_new_entry || calc_curr == 0) {
calc_curr = lbl - '0';
if (calc_new_entry || calc_error) {
calc_curr = (lbl - '0') * SCALE;
calc_new_entry = false;
calc_decimal_mode = false;
} else {
calc_curr = calc_curr * 10 + (lbl - '0');
if (calc_decimal_mode) {
// Add digit to fraction
if (calc_decimal_divisor <= SCALE) {
long long digit_val = ((long long)(lbl - '0') * SCALE) / calc_decimal_divisor;
if (calc_curr >= 0) calc_curr += digit_val;
else calc_curr -= digit_val;
calc_decimal_divisor *= 10;
}
} else {
// Integer shift
if (calc_curr >= 0) calc_curr = calc_curr * 10 + (lbl - '0') * SCALE;
else calc_curr = calc_curr * 10 - (lbl - '0') * SCALE;
}
}
calc_error = false;
} else if (lbl == '.') {
if (calc_new_entry) {
calc_curr = 0;
calc_new_entry = false;
}
if (!calc_decimal_mode) {
calc_decimal_mode = true;
calc_decimal_divisor = 10;
}
} else if (lbl == 'C') {
calc_curr = 0;
calc_acc = 0;
calc_op = 0;
calc_new_entry = true;
calc_error = false;
calc_decimal_mode = false;
} else if (lbl == 'B') { // BS (Backspace)
if (!calc_new_entry && !calc_error) {
if (calc_decimal_mode) {
calc_curr = 0;
calc_new_entry = true;
} else {
calc_curr /= 10;
}
}
} else if (lbl == 's') { // sqr
calc_curr = (calc_curr * calc_curr) / SCALE;
calc_new_entry = true;
} else if (lbl == 'r') { // rt (sqrt)
long long s = isqrt(calc_curr);
if (s == -1) calc_error = true;
else calc_curr = s * 1000;
calc_new_entry = true;
} else if (lbl == '=') {
do_op();
calc_curr = calc_acc;
calc_op = 0;
calc_new_entry = true;
calc_decimal_mode = false;
} else {
// Operator
if (!calc_new_entry) {
if (calc_op) do_op();
else calc_acc = calc_curr;
}
calc_op = lbl;
calc_new_entry = true;
calc_decimal_mode = false;
}
update_display(win);
@ -153,8 +257,8 @@ void calculator_init(void) {
win_calculator.title = "Calculator";
win_calculator.x = 200;
win_calculator.y = 200;
win_calculator.w = 160;
win_calculator.h = 200;
win_calculator.w = 180; // Slightly wider for 4 cols with gaps
win_calculator.h = 230; // Taller for 5 rows
win_calculator.visible = false;
win_calculator.focused = false;
win_calculator.z_index = 0;

View file

@ -2,6 +2,6 @@
void cli_cmd_brewver(char *args) {
(void)args;
cli_write("BrewOS v1.40 Beta\n");
cli_write("BrewOS v1.42 Beta\n");
cli_write("BrewOS Kernel V2.3.1 Beta\n");
}

View file

@ -5,7 +5,6 @@
#include <stddef.h>
#include <stdbool.h>
// Ensure we have the IP type from your existing stack
#include "network.h"
// Protocol Numbers
@ -27,7 +26,6 @@ static inline uint32_t ntohl(uint32_t v) {
return htonl(v);
}
// Checksum Calculation
static inline uint16_t net_checksum(void *data, int len) {
uint32_t sum = 0;
uint16_t *p = (uint16_t *)data;
@ -59,7 +57,7 @@ typedef struct {
uint16_t dst_port;
uint32_t seq_num;
uint32_t ack_num;
uint8_t data_offset; // High 4 bits: offset, Low 4 bits: reserved/NS
uint8_t data_offset;
uint8_t flags;
uint16_t window_size;
uint16_t checksum;

View file

@ -13,6 +13,12 @@ static uint32_t *canvas_buffer = NULL;
static uint32_t current_color = COLOR_BLACK;
static int last_mx = -1;
static int last_my = -1;
static char current_file_path[256] = "/Desktop/drawing.pnt";
static void paint_strcpy(char *dest, const char *src) {
while (*src) *dest++ = *src++;
*dest = 0;
}
static void paint_paint(Window *win) {
// Background
@ -117,11 +123,12 @@ static void paint_save(const char *path) {
fat32_write(fh, header, sizeof(header));
fat32_write(fh, canvas_buffer, CANVAS_W * CANVAS_H * sizeof(uint32_t));
fat32_close(fh);
wm_show_message("Paint", "Image saved to Desktop.");
wm_show_message("Paint", "Image saved.");
}
}
void paint_load(const char *path) {
paint_strcpy(current_file_path, path);
FAT32_FileHandle *fh = fat32_open(path, "r");
if (fh) {
uint32_t header[3];
@ -145,7 +152,7 @@ static void paint_click(Window *win, int x, int y) {
return;
}
if (y >= win->h - 40 && y < win->h - 20) {
paint_save("/Desktop/drawing.pnt");
paint_save(current_file_path);
return;
}
}

View file

@ -888,6 +888,23 @@ bool rect_contains(int x, int y, int w, int h, int px, int py) {
return px >= x && px < x + w && py >= y && py < y + h;
}
static void wm_bring_to_front(Window *win) {
// Clear focus from all windows
for (int i = 0; i < window_count; i++) {
all_windows[i]->focused = false;
}
// Find current max z-index
int max_z = 0;
for (int i = 0; i < window_count; i++) {
if (all_windows[i]->z_index > max_z) max_z = all_windows[i]->z_index;
}
win->visible = true;
win->focused = true;
win->z_index = max_z + 1;
}
void wm_handle_click(int x, int y) {
int sh = get_screen_height();
int sw = get_screen_width();
@ -1020,20 +1037,7 @@ void wm_handle_click(int x, int y) {
// If a window was clicked
if (topmost != NULL) {
// Clear focus from all windows
for (int i = 0; i < window_count; i++) {
all_windows[i]->focused = false;
}
// Bring it to front
int max_z = 0;
for (int i = 0; i < window_count; i++) {
if (all_windows[i]->z_index > max_z) {
max_z = all_windows[i]->z_index;
}
}
topmost->z_index = max_z + 1;
topmost->focused = true;
wm_bring_to_front(topmost);
// Check close button
if (rect_contains(topmost->x + topmost->w - 20, topmost->y + 5, 14, 14, x, y)) {
@ -1256,44 +1260,29 @@ void wm_handle_right_click(int x, int y) {
if (start_menu_pending_app) {
// Launch App
if (str_starts_with(start_menu_pending_app, "Explorer")) {
win_explorer.visible = true; win_explorer.focused = true; explorer_reset();
explorer_reset(); wm_bring_to_front(&win_explorer);
} else if (str_starts_with(start_menu_pending_app, "Notepad")) {
win_notepad.visible = true; win_notepad.focused = true;
wm_bring_to_front(&win_notepad);
} else if (str_starts_with(start_menu_pending_app, "Editor")) {
win_editor.visible = true; win_editor.focused = true;
wm_bring_to_front(&win_editor);
} else if (str_starts_with(start_menu_pending_app, "Terminal")) {
win_cmd.visible = true; win_cmd.focused = true; cmd_reset();
cmd_reset(); wm_bring_to_front(&win_cmd);
} else if (str_starts_with(start_menu_pending_app, "Calculator")) {
win_calculator.visible = true; win_calculator.focused = true;
wm_bring_to_front(&win_calculator);
} else if (str_starts_with(start_menu_pending_app, "Minesweeper")) {
win_minesweeper.visible = true; win_minesweeper.focused = true;
wm_bring_to_front(&win_minesweeper);
} else if (str_starts_with(start_menu_pending_app, "Control Panel")) {
win_control_panel.visible = true; win_control_panel.focused = true;
wm_bring_to_front(&win_control_panel);
} else if (str_starts_with(start_menu_pending_app, "Paint")) {
win_paint.visible = true; win_paint.focused = true;
wm_bring_to_front(&win_paint);
} else if (str_starts_with(start_menu_pending_app, "About")) {
win_about.visible = true; win_about.focused = true;
wm_bring_to_front(&win_about);
} else if (str_starts_with(start_menu_pending_app, "Shutdown")) {
cli_cmd_shutdown(NULL);
} else if (str_starts_with(start_menu_pending_app, "Restart")) {
cli_cmd_reboot(NULL);
}
// Bring launched window to front
int max_z = 0;
for (int i = 0; i < window_count; i++) {
if (all_windows[i]->z_index > max_z) max_z = all_windows[i]->z_index;
}
if (win_explorer.visible && win_explorer.focused) win_explorer.z_index = max_z + 1;
if (win_notepad.visible && win_notepad.focused) win_notepad.z_index = max_z + 1;
if (win_editor.visible && win_editor.focused) win_editor.z_index = max_z + 1;
if (win_cmd.visible && win_cmd.focused) win_cmd.z_index = max_z + 1;
if (win_calculator.visible && win_calculator.focused) win_calculator.z_index = max_z + 1;
if (win_minesweeper.visible && win_minesweeper.focused) win_minesweeper.z_index = max_z + 1;
if (win_control_panel.visible && win_control_panel.focused) win_control_panel.z_index = max_z + 1;
if (win_paint.visible && win_paint.focused) win_paint.z_index = max_z + 1;
if (win_about.visible && win_about.focused) win_about.z_index = max_z + 1;
start_menu_open = false;
start_menu_pending_app = NULL;
force_redraw = true;
@ -1307,25 +1296,23 @@ void wm_handle_right_click(int x, int y) {
if (icon->type == 2) { // App Shortcut
// Check name to launch app
if (str_ends_with(icon->name, "Notepad.shortcut")) {
win_notepad.visible = true; win_notepad.focused = true;
notepad_reset();
notepad_reset(); wm_bring_to_front(&win_notepad);
} else if (str_ends_with(icon->name, "Calculator.shortcut")) {
win_calculator.visible = true; win_calculator.focused = true;
wm_bring_to_front(&win_calculator);
} else if (str_ends_with(icon->name, "Minesweeper.shortcut")) {
win_minesweeper.visible = true; win_minesweeper.focused = true;
wm_bring_to_front(&win_minesweeper);
} else if (str_ends_with(icon->name, "Control Panel.shortcut")) {
win_control_panel.visible = true; win_control_panel.focused = true;
wm_bring_to_front(&win_control_panel);
} else if (str_ends_with(icon->name, "Terminal.shortcut")) {
win_cmd.visible = true; win_cmd.focused = true;
wm_bring_to_front(&win_cmd);
} else if (str_ends_with(icon->name, "About.shortcut")) {
win_about.visible = true; win_about.focused = true;
wm_bring_to_front(&win_about);
} else if (str_ends_with(icon->name, "Explorer.shortcut")) {
win_explorer.visible = true; win_explorer.focused = true;
explorer_reset();
explorer_reset(); wm_bring_to_front(&win_explorer);
} else if (str_ends_with(icon->name, "Recycle Bin.shortcut")) {
explorer_open_directory("/RecycleBin");
explorer_open_directory("/RecycleBin"); wm_bring_to_front(&win_explorer);
} else if (str_ends_with(icon->name, "Paint.shortcut")) {
win_paint.visible = true; win_paint.focused = true;
wm_bring_to_front(&win_paint);
}
// Generic Shortcut Handling
@ -1342,9 +1329,10 @@ void wm_handle_right_click(int x, int y) {
buf[len] = 0;
if (fat32_is_directory(buf)) {
explorer_open_directory(buf);
wm_bring_to_front(&win_explorer);
} else {
win_editor.visible = true; win_editor.focused = true;
editor_open_file(buf);
wm_bring_to_front(&win_editor);
}
pending_desktop_icon_click = -1;
return;
@ -1355,36 +1343,22 @@ void wm_handle_right_click(int x, int y) {
char path[128] = "/Desktop/";
int p=9; int n=0; while(icon->name[n]) path[p++] = icon->name[n++]; path[p]=0;
explorer_open_directory(path);
wm_bring_to_front(&win_explorer);
} else { // File
char path[128] = "/Desktop/";
int p=9; int n=0; while(icon->name[n]) path[p++] = icon->name[n++]; path[p]=0;
if (str_ends_with(icon->name, ".pnt")) {
paint_load(path);
wm_bring_to_front(&win_paint);
} else if (str_ends_with(icon->name, ".md")) {
win_markdown.visible = true; win_markdown.focused = true;
markdown_open_file(path);
wm_bring_to_front(&win_markdown);
} else {
win_editor.visible = true; win_editor.focused = true;
editor_open_file(path);
wm_bring_to_front(&win_editor);
}
}
// Bring launched window to front
int max_z = 0;
for (int w = 0; w < window_count; w++) {
if (all_windows[w]->z_index > max_z) max_z = all_windows[w]->z_index;
}
if (win_notepad.visible && win_notepad.focused) win_notepad.z_index = max_z + 1;
if (win_calculator.visible && win_calculator.focused) win_calculator.z_index = max_z + 1;
if (win_minesweeper.visible && win_minesweeper.focused) win_minesweeper.z_index = max_z + 1;
if (win_control_panel.visible && win_control_panel.focused) win_control_panel.z_index = max_z + 1;
if (win_cmd.visible && win_cmd.focused) win_cmd.z_index = max_z + 1;
if (win_paint.visible && win_paint.focused) win_paint.z_index = max_z + 1;
if (win_about.visible && win_about.focused) win_about.z_index = max_z + 1;
if (win_explorer.visible && win_explorer.focused) win_explorer.z_index = max_z + 1;
if (win_editor.visible && win_editor.focused) win_editor.z_index = max_z + 1;
if (win_markdown.visible && win_markdown.focused) win_markdown.z_index = max_z + 1;
}
pending_desktop_icon_click = -1;
}