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
# API
- Font Loader
- VGA fonts
- Colour operations:
- Alpha Composite
- Invert
- Surface Operations:
- FlipV
- FlipH
- Wrap the colour operations
- Tile
@ -19,8 +16,8 @@
- Draw operations:
- Curve raster algorithm
- VGA font fast blit
- VGA font render
- Polygon
- Rounded rects
# Backend
- SVGA Driver

View file

@ -36,7 +36,7 @@ surface_from_bmp := fn(bmp: ^u8): Surface {
file_header := @as(^BitmapFileHeader, @bitcast(bmp))
if file_header.img_type != 0x4D42 {
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)))
bmp += file_header.offset
@ -68,7 +68,7 @@ new_surface_from_bmp := fn(bmp: ^u8): Surface {
file_header := @as(^BitmapFileHeader, @bitcast(bmp))
if file_header.img_type != 0x4D42 {
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)))
bmp += file_header.offset

View file

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

View file

@ -1,5 +1,6 @@
.{math, memory, dt, log} := @use("../../stn/src/lib.hb");
.{Color} := @use("lib.hb");
.{math, memory, dt} := @use("../../stn/src/lib.hb");
.{Color, text} := @use("lib.hb");
.{get_glyph, Font} := text;
.{Vec2} := math
Surface := struct {
@ -475,3 +476,63 @@ put_textured_circle := fn(surface: Surface, source: Surface, source_pos: Vec2(ui
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}
}
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 {
theta := theta_deg % 360
sin := fn(theta: int, amplitude: uint): int {
if theta < 0 {
theta += 360
theta += (-theta / 360 + 1) * 360
} else if theta >= 360 {
theta -= theta / 360 * 360
}
quadrant := theta / 90
theta = theta % 90
index := theta % 90
sign := @as(int, 1) - ((quadrant & 2) >> 1) * 2
complement := quadrant & 1
index := theta * (1 - complement) + (90 - theta) * complement
sin_value := SIN_TABLE[@intcast(index)] * sign
return (sin_value * amplitude + 5000) / 10000
if @as(u8, @intcast(quadrant)) == @as(u8, 1) {
index = 90 - index
}
cos_i := fn(theta_deg: int, amplitude: int): int {
return @inline(sin_i, theta_deg + 90, amplitude)
value := SIN_TABLE[@bitcast(index)]
if quadrant >= 2 {
value = -value
}
return (value * @bitcast(amplitude) + 5000) / 10000
}
cos := fn(theta: int, amplitude: uint): int {
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]
path = "boot:///render_example.hbf"
# [boot.limine.ableos.modules.serial_driver]
# path = "boot:///serial_driver.hbf"
# [boot.limine.ableos.modules.serial_driver_test]
# path = "boot:///serial_driver_test.hbf"