Skip to content

Commit

Permalink
[ADD] psf font basic string implementation #2
Browse files Browse the repository at this point in the history
  • Loading branch information
lg-epitech committed Oct 30, 2024
1 parent e1e3092 commit 2505bbd
Show file tree
Hide file tree
Showing 12 changed files with 262 additions and 15 deletions.
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
*.o
*.bin
build/boot/grub/grub.cfg
modos.iso
14 changes: 9 additions & 5 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
SRC = src/kernel.c \
src/string.c \
src/pixel.c \
src/debug.c \
SRC = src/kernel.c \
src/string.c \
src/pixel.c \
src/debug.c \
src/font.c \

# objcopy -O elf32-i386 -B i386 -I binary assets/zap-ext-light32.psf assets/zap-ext-light32.o
FONTS = assets/zap-ext-light32.o

CFLAGS += -std=gnu99 -ffreestanding -O2 -Wall -Wextra
CC = i686-elf-gcc
Expand All @@ -22,7 +26,7 @@ all: $(EXEC)

$(EXEC): ${OBJ}
$(ASMC) $(BOOT_FILE) -o $(BOOT_BIN)
$(CC) -T $(LINKER_FILE) -o $(KERNEL_BIN) $(BOOT_BIN) $(OBJ) -lgcc -ffreestanding -O2 -nostdlib
$(CC) -T $(LINKER_FILE) -o $(KERNEL_BIN) $(BOOT_BIN) $(OBJ) $(FONTS) -lgcc -ffreestanding -O2 -nostdlib

grub-file --is-x86-multiboot $(KERNEL_BIN)

Expand Down
Binary file added assets/zap-ext-light32.psf
Binary file not shown.
14 changes: 14 additions & 0 deletions include/config.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
/*
** EPITECH PROJECT, 2024
** ModOS
** File description:
** config.h
*/

// TODO: implement config structure instead of macros so that it can be changed at runtime
#ifndef CONFIG_H_
#define CONFIG_H_
#define TEXT_COLOR 0xffffff
#define BACKGROUND_COLOR 0x111111

#endif /* !CONFIG_H_ */
12 changes: 10 additions & 2 deletions include/font.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@
#define PSF_FONT_MAGIC 0x864ab572

typedef struct {
uint16_t magic; // Magic bytes for identification.
uint8_t fontMode; // PSF font mode.
uint16_t magic; // Magic bytes for identification.
uint8_t fontMode; // PSF font mode.
uint8_t characterSize; // PSF character size.
} psf1_header_t;

Expand All @@ -28,4 +28,12 @@ typedef struct {
uint32_t width; /* width in pixels */
} psf_font_t;

extern uint8_t _binary_zap_ext_light32_psf_start;
extern uint8_t _binary_zap_ext_light32_psf_end;
extern uint8_t _binary_zap_ext_light32_psf_size;

void __os_putchar(unsigned short int c, int cx, int cy, uint32_t fg,
uint32_t bg, psf_font_t *font, uint8_t *font_start);
// , psf_font_t *font, uint8_t font_start[]);

#endif /* !FONT_H_ */
4 changes: 2 additions & 2 deletions include/pixel.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@
#define PIXEL_H_
#include <stdint.h>

typedef uint32_t argb_t;
typedef uint32_t argb_pixel_t;

void put_pixel(uint32_t x, uint32_t y, argb_t color);
void put_pixel(uint32_t x, uint32_t y, argb_pixel_t color);
void clear_screen(uint32_t color);

#endif /* !PIXEL_H_ */
11 changes: 11 additions & 0 deletions include/string.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,16 @@

#ifndef STRING_H_
#define STRING_H_
#include <stdint.h>
#include <stddef.h>
#include <stdarg.h>
#include "config.h"
#include "font.h"

void putchar(uint32_t unicode_char);
void puts(const char *str);
void put_uint(uint32_t value);
void put_uint_hex(uint32_t value);
void printf(const char *format, ...);

#endif /* !STRING_H_ */
14 changes: 14 additions & 0 deletions reconnect.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
#!/bin/bash

PORT=4444
HOST=localhost
DELAY=1

while true; do
clear
echo "Connecting to QEMU serial port at $HOST:$PORT..."
nc $HOST $PORT
echo "Disconnected from QEMU serial port."
echo "Reconnecting in $DELAY seconds..."
sleep $DELAY
done
100 changes: 100 additions & 0 deletions src/font.c
Original file line number Diff line number Diff line change
@@ -1 +1,101 @@
#include "../include/font.h"
#include "../include/kernel.h"
#include "../include/pixel.h"
#include "stddef.h"

uint16_t *unicode;

// NOTE: Optional unicode decoding
// Needs calloc which we don't have right now.
//
// void psf_init()
// {
// uint16_t glyph = 0;
// psf_font_t *font = (psf_font_t*)&font_start;
//
// if (font->flags) {
// unicode = NULL;
// return;
// }
//
// char *s = (char *)(
// (unsigned char*)&font_start +
// font->headersize +
// font->numglyph * font->bytesperglyph
// );
// unicode = calloc(USHRT_MAX, 2);
// while(s>_binary_zap_ext_light32_psf_end) {
// uint16_t uc = (uint16_t)((unsigned char *)s[0]);
// if(uc == 0xFF) {
// glyph++;
// s++;
// continue;
// } else if(uc & 128) {
// /* UTF-8 to unicode */
// if((uc & 32) == 0 ) {
// uc = ((s[0] & 0x1F)<<6)+(s[1] & 0x3F);
// s++;
// } else
// if((uc & 16) == 0 ) {
// uc = ((((s[0] & 0xF)<<6)+(s[1] & 0x3F))<<6)+(s[2] & 0x3F);
// s+=2;
// } else
// if((uc & 8) == 0 ) {
// uc = ((((((s[0] & 0x7)<<6)+(s[1] & 0x3F))<<6)+(s[2] &
// 0x3F))<<6)+(s[3] & 0x3F); s+=3;
// } else
// uc = 0;
// }
// unicode[uc] = glyph;
// s++;
// }
// }

/**
* @brief Unicode putchar
*
* @param c This is an int, not char as it's a unicode character
* @param cx Horizontal position on screen, in characters not in pixels
* @param cy Vertical position on screen, in characters not in pixels
* @param fg ARGB foreground color
* @param bg ARGB background color
*/
void __os_putchar(
unsigned short int c,
int cx, int cy,
uint32_t fg, uint32_t bg,
psf_font_t *font,
uint8_t *font_start)
{
uint32_t bytesperline = (font->width + 7) / 8;

if (unicode != NULL) {
c = unicode[c];
}

uint8_t *glyph =
(uint8_t *)font_start + font->headersize +
(c > 0 && c < font->numglyph ? c : 0) * font->bytesperglyph;
uint32_t offset = (cy * font->height * framebuffer_pitch) +
(cx * font->width * sizeof(argb_pixel_t));

for (uint32_t y = 0; y < font->height; y++) {
uint32_t line = offset;
uint8_t *glyph_row = glyph + y * bytesperline;
uint32_t bits_left = font->width;

for (uint32_t b = 0; b < bytesperline; b++) {
uint8_t byte = glyph_row[b];

for (int bit = 7; bit >= 0 && bits_left > 0; bit--) {
uint32_t color = (byte & (1 << bit)) ? fg : bg;

*((argb_pixel_t *)(framebuffer + line)) = color;

line += sizeof(argb_pixel_t);
bits_left--;
}
}
offset += framebuffer_pitch;
}
}
9 changes: 6 additions & 3 deletions src/kernel.c
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,12 @@
#include "../include/kernel.h"
#include "../include/multiboot.h"
#include "../include/pixel.h"
#include "../include/config.h"
#include "../include/string.h"

/* Check if the compiler thinks you are targeting the wrong operating system. */
#if defined(__linux__)
#error \
"You are not using a cross-compiler, you will most certainly run into trouble"
#error "You are not using a cross-compiler, you will most certainly run into trouble"
#endif

/* This tutorial will only work for the 32-bit ix86 targets. */
Expand Down Expand Up @@ -55,5 +56,7 @@ void kernel_main(unsigned long magic, multiboot_info_t *mbi) {
framebuffer_height = mbi->framebuffer_height;
framebuffer_bpp = mbi->framebuffer_bpp;

clear_screen(0xffff0000);
clear_screen(BACKGROUND_COLOR);

printf("Hello %d\n", 42);
}
4 changes: 2 additions & 2 deletions src/pixel.c
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ static inline uint32_t position(uint32_t x, uint32_t y)
* x and y indicate the pixel position
* color is a 32 bit unsigned integer such as 0xAARRGGBB
*/
void put_pixel(uint32_t x, uint32_t y, argb_t color)
void put_pixel(uint32_t x, uint32_t y, argb_pixel_t color)
{
const uint32_t index = position(x, y);

Expand Down Expand Up @@ -52,7 +52,7 @@ void put_pixel(uint32_t x, uint32_t y, argb_t color)
}
}

void clear_screen(argb_t color)
void clear_screen(argb_pixel_t color)
{
for (uint32_t y = 0; y < framebuffer_height; ++y) {
for (uint32_t x = 0; x < framebuffer_width; ++x) {
Expand Down
91 changes: 90 additions & 1 deletion src/string.c
Original file line number Diff line number Diff line change
@@ -1,4 +1,93 @@
#include "../include/string.h"
#include "../include/kernel.h"

void putchar(char c) {
uint32_t cx, cy = 0;
psf_font_t *font = (psf_font_t *)&_binary_zap_ext_light32_psf_start;

void putchar(uint32_t unicode_char)
{
if (unicode_char == '\n') {
cx = 0; ++cy;
return;
}
__os_putchar(unicode_char, cx, cy, TEXT_COLOR, BACKGROUND_COLOR, font, (uint8_t *)&_binary_zap_ext_light32_psf_start);
if (++cx > (uint32_t)framebuffer_pitch / font->bytesperglyph) {
cx = 0; ++cy;
}
}

void put_uint(uint32_t value)
{
char buffer[11];
int i = 10;
buffer[i] = '\0';

if (value == 0) {
putchar('0');
return;
}

while (value > 0 && i > 0) {
buffer[--i] = '0' + (value % 10);
value /= 10;
}

puts(&buffer[i]);
}


void put_uint_hex(uint32_t value)
{
char buffer[9];
const char *hex_chars = "0123456789abcdef";
int i = 8;
buffer[i] = '\0';

if (value == 0) {
puts("0x0");
return;
}

while (value > 0 && i > 0) {
buffer[--i] = hex_chars[value & 0xF];
value >>= 4;
}

puts("0x");
puts(&buffer[i]);
}

void printf(const char *format, ...)
{
va_list params; va_start(params, format);
for (uint32_t i = 0; format[i] != '\0'; ++i) {
if (!(format[i] == '%')) {
putchar(format[i]);
continue;
}
switch (format[++i]) {
case 'd': // idc for now
case 'u':
put_uint((uint32_t)va_arg(params, uint32_t));
break;
case 'x':
put_uint_hex((uint32_t)va_arg(params, uint32_t));
break;
case 'c':
putchar((uint8_t)va_arg(params, uint32_t));
break;
case 's':
puts((char *)va_arg(params, char *));
break;
default:
putchar(format[i]);
break;
}
}
va_end(params);
}

void puts(const char *str)
{
for (uint32_t i = 0; str[i] != '\0'; ++i) putchar(str[i]);
}

0 comments on commit 2505bbd

Please sign in to comment.