1
0
Fork 0
forked from AbleOS/ableos
This commit is contained in:
peony 2024-10-27 16:59:03 +01:00
commit 20bb741bf1
25 changed files with 195 additions and 20 deletions

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.

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

@ -0,0 +1,10 @@
Tamsyn font is free. You are hereby granted permission to use, copy, modify,
and distribute it as you see fit.
Tamsyn font is provided "as is" without any express or implied warranty.
The author makes no representations about the suitability of this font for
a particular purpose.
In no event will the author be held liable for damages arising from the use
of this font.

View file

@ -5,13 +5,10 @@
- Animation - Animation
# API # API
- Font Loader
- VGA fonts
- Colour operations: - Colour operations:
- Alpha Composite - Alpha Composite
- Invert - Invert
- Surface Operations: - Surface Operations:
- FlipV
- FlipH - FlipH
- Wrap the colour operations - Wrap the colour operations
- Tile - Tile
@ -19,8 +16,8 @@
- Draw operations: - Draw operations:
- Curve raster algorithm - Curve raster algorithm
- VGA font fast blit - VGA font fast blit
- VGA font render
- Polygon - Polygon
- Rounded rects
# Backend # Backend
- SVGA Driver - SVGA Driver

View file

@ -36,7 +36,7 @@ surface_from_bmp := fn(bmp: ^u8): Surface {
file_header := @as(^BitmapFileHeader, @bitcast(bmp)) file_header := @as(^BitmapFileHeader, @bitcast(bmp))
if file_header.img_type != 0x4D42 { if file_header.img_type != 0x4D42 {
log.error("failed to load bmp image: not a bmp image, idiot\0") log.error("failed to load bmp image: not a bmp image, idiot\0")
return @as(Surface, idk) return idk
} }
info_header := @as(^BitmapInfoHeader, @bitcast(bmp + @sizeof(BitmapFileHeader))) info_header := @as(^BitmapInfoHeader, @bitcast(bmp + @sizeof(BitmapFileHeader)))
bmp += file_header.offset bmp += file_header.offset
@ -68,7 +68,7 @@ new_surface_from_bmp := fn(bmp: ^u8): Surface {
file_header := @as(^BitmapFileHeader, @bitcast(bmp)) file_header := @as(^BitmapFileHeader, @bitcast(bmp))
if file_header.img_type != 0x4D42 { if file_header.img_type != 0x4D42 {
log.error("failed to load bmp image: not a bmp image, idiot\0") log.error("failed to load bmp image: not a bmp image, idiot\0")
return @as(Surface, idk) return idk
} }
info_header := @as(^BitmapInfoHeader, @bitcast(bmp + @sizeof(BitmapFileHeader))) info_header := @as(^BitmapInfoHeader, @bitcast(bmp + @sizeof(BitmapFileHeader)))
bmp += file_header.offset bmp += file_header.offset

View file

@ -1,5 +1,6 @@
software := @use("software.hb") software := @use("software.hb")
image := @use("image.hb") image := @use("image.hb")
text := @use("text.hb")
// default mode // default mode
mode := software mode := software
@ -46,6 +47,7 @@ put_surface := mode.put_surface
put_scaled := mode.put_scaled put_scaled := mode.put_scaled
put_tri := mode.put_tri put_tri := mode.put_tri
put_filled_tri := mode.put_filled_tri put_filled_tri := mode.put_filled_tri
put_text := mode.put_text
// thanks peony for these three! // thanks peony for these three!
put_trirect := mode.put_trirect put_trirect := mode.put_trirect
put_vline := mode.put_vline put_vline := mode.put_vline

View file

@ -1,5 +1,6 @@
.{math, memory, dt, log} := @use("../../stn/src/lib.hb"); .{math, memory, dt} := @use("../../stn/src/lib.hb");
.{Color} := @use("lib.hb"); .{Color, text} := @use("lib.hb");
.{get_glyph, Font} := text;
.{Vec2} := math .{Vec2} := math
Surface := struct { Surface := struct {
@ -475,3 +476,63 @@ put_textured_circle := fn(surface: Surface, source: Surface, source_pos: Vec2(ui
return return
} }
put_text := fn(surface: Surface, font: Font, pos: Vec2(uint), color: Color, str: ^u8): void {
cursor := Vec2(uint).(pos.x, pos.y)
current_char := str
loop if *current_char == 0 break else {
if *current_char == 10 {
cursor.x = pos.x
cursor.y += font.height + font.line_gap
current_char += 1
continue
}
glyph_data := @inline(get_glyph, font, @intcast(*current_char))
if glyph_data == idk {
current_char += 1
continue
}
if cursor.x % surface.width + font.width >= surface.width {
cursor.x = pos.x
cursor.y += font.height + font.line_gap
}
if cursor.y + font.height > surface.height break
dest := @inline(indexptr, surface, cursor.x, cursor.y)
src := glyph_data
rows_remaining := font.height
loop if rows_remaining == 0 break else {
byte := *glyph_data
pixel_dest := dest
mask := @as(u8, 0x80)
bits_remaining := font.width
loop if bits_remaining == 0 break else {
if (byte & mask) != 0 {
*pixel_dest = color
}
pixel_dest += 1
mask >>= 1
if mask == 0 {
glyph_data += 1
byte = *glyph_data
mask = 0x80
}
bits_remaining -= 1
}
glyph_data += 1
dest += surface.width
rows_remaining -= 1
}
cursor.x += font.width + font.char_gap
current_char += 1
}
return
}

View file

@ -0,0 +1,75 @@
.{log} := @use("../../stn/src/lib.hb")
PSF1Header := packed struct {
magic: u16,
font_mode: u8,
character_size: u8,
}
PSF2Header := packed struct {
magic: u32,
version: u32,
header_size: u32,
flags: u32,
num_glyph: u32,
bytes_per_glyph: u32,
height: u32,
width: u32,
}
Font := struct {
data: ^u8,
width: uint,
height: uint,
num_glyphs: uint,
bytes_per_glyph: uint,
has_unicode_table: bool,
line_gap: uint,
char_gap: uint,
}
font_from_psf1 := fn(psf: ^u8): Font {
header := @as(^PSF1Header, @bitcast(psf))
if header.magic != 0x436 {
log.error("failed to load psf font: not a psf1 font, idiot\0")
return idk
}
psf += @sizeof(PSF1Header)
return .(
psf,
8,
@intcast(header.character_size),
256,
@intcast(header.character_size),
false,
0,
0,
)
}
font_from_psf2 := fn(psf: ^u8): Font {
header := @as(^PSF2Header, @bitcast(psf))
if header.magic != 0x864AB572 {
log.error("failed to load psf font: not a psf2 font, idiot\0")
return idk
}
psf += header.header_size
return .(
psf,
@intcast(header.width),
@intcast(header.height),
@intcast(header.num_glyph),
@intcast(header.bytes_per_glyph),
(header.flags & 1) != 0,
0,
0,
)
}
get_glyph := fn(font: Font, index: uint): ^u8 {
return font.data + index * font.bytes_per_glyph
}

Binary file not shown.

View file

@ -30,26 +30,30 @@ Vec2 := fn($Expr: type): type {
return struct {x: Expr, y: Expr} return struct {x: Expr, y: Expr}
} }
SIN_TABLE := [int].(0, 174, 348, 523, 697, 871, 1045, 1218, 1391, 1564, 1736, 1908, 2079, 2249, 2419, 2588, 2756, 2923, 3090, 3255, 3420, 3583, 3746, 3907, 4067, 4226, 4384, 4540, 4695, 4848, 5000, 5150, 5299, 5446, 5591, 5735, 5877, 6018, 6156, 6293, 6427, 6560, 6691, 6819, 6946, 7071, 7193, 7313, 7431, 7547, 7660, 7771, 7880, 7986, 8090, 8191, 8290, 8386, 8480, 8571, 8660, 8746, 8829, 8910, 8987, 9063, 9135, 9205, 9271, 9335, 9396, 9455, 9510, 9563, 9612, 9659, 9702, 9743, 9781, 9816, 9848, 9877, 9902, 9925, 9945, 9961, 9975, 9986, 9993, 9998, 10000) SIN_TABLE := @as([int; 91], @bitcast(@embed("./assets/sin_table")))
sin_i := fn(theta_deg: int, amplitude: int): int { sin := fn(theta: int, amplitude: uint): int {
theta := theta_deg % 360
if theta < 0 { if theta < 0 {
theta += 360 theta += (-theta / 360 + 1) * 360
} else if theta >= 360 {
theta -= theta / 360 * 360
} }
quadrant := theta / 90 quadrant := theta / 90
theta = theta % 90 index := theta % 90
sign := @as(int, 1) - ((quadrant & 2) >> 1) * 2 if @as(u8, @intcast(quadrant)) == @as(u8, 1) {
complement := quadrant & 1 index = 90 - index
}
index := theta * (1 - complement) + (90 - theta) * complement value := SIN_TABLE[@bitcast(index)]
sin_value := SIN_TABLE[@intcast(index)] * sign if quadrant >= 2 {
value = -value
}
return (sin_value * amplitude + 5000) / 10000 return (value * @bitcast(amplitude) + 5000) / 10000
} }
cos_i := fn(theta_deg: int, amplitude: int): int { cos := fn(theta: int, amplitude: uint): int {
return @inline(sin_i, theta_deg + 90, amplitude) return @inline(sin, theta + 90, amplitude)
} }

View file

@ -0,0 +1,23 @@
.{Vec2, sin, cos} := @use("../../../../libraries/stn/src/lib.hb").math
render := @use("../../../../libraries/render/src/lib.hb")
/* expected result:
words */
psf := @embed("../../../../consolefonts/tamsyn/10x20r.psf")
example := fn(): void {
screen := render.init(true)
font := render.text.font_from_psf2(@bitcast(&psf))
t := 0
str := "Hello, World!
This is a test
of multiline rendering\0"
loop {
render.clear(screen, render.black)
render.put_text(screen, font, .(t, t % screen.height), render.red, str)
render.sync(screen)
t += 1
}
return
}

View file

@ -29,6 +29,9 @@ resolution = "1600x900x24"
[boot.limine.ableos.modules.render_example] [boot.limine.ableos.modules.render_example]
path = "boot:///render_example.hbf" path = "boot:///render_example.hbf"
# [boot.limine.ableos.modules.serial_driver]
# path = "boot:///serial_driver.hbf"
# [boot.limine.ableos.modules.serial_driver_test] # [boot.limine.ableos.modules.serial_driver_test]
# path = "boot:///serial_driver_test.hbf" # path = "boot:///serial_driver_test.hbf"