Initial import of ViperOS

This commit is contained in:
Viper
2026-07-19 12:38:20 +08:00
commit 6813947181
104 changed files with 26710 additions and 0 deletions

39
Apps/Gargantua/linker.ld Normal file
View File

@@ -0,0 +1,39 @@
ENTRY(__entry)
SECTIONS {
. = 0x400000;
.text : {
__entry = .;
*(.text.startup)
*(.text)
*(.text.*)
}
.rodata : {
*(.rodata)
*(.rodata.*)
}
.data : {
*(.data)
*(.data.*)
}
.bss : {
__bss_start = .;
*(.bss)
*(.bss.*)
__bss_end = .;
}
/DISCARD/ : {
*(.comment)
*(.note)
*(.eh_frame)
*(.eh_frame_hdr)
*(.reloc)
*(.rela)
*(.debug*)
}
}

316
Apps/Gargantua/main.py Normal file
View File

@@ -0,0 +1,316 @@
import vpsdk.window as window
import vpsdk.process as process
import vpsdk.vpui as vpui
import string
import vipermath as vm
import viperlib
from stdint import *
import memhub
import t, c
GW: t.CDefine = 160
GH: t.CDefine = 90
GW_F: t.CDefine = 160.0
GH_F: t.CDefine = 90.0
MAX_STEPS: t.CDefine = 100
ESCAPE_R: t.CDefine = 60.0
DISK_IN: t.CDefine = 2.6
DISK_OUT: t.CDefine = 11.0
CAM_DIST: t.CDefine = 22.0
CAM_ELEV: t.CDefine = 9.0
FOVF: t.CDefine = 0.55
YIELD_ROWS: t.CDefine = 4
V3_POOL_SIZE: t.CDefine = 8192
V3_POOL_BYTES: t.CDefine = V3_POOL_SIZE * 24 + 512
_v3_mem: t.CArray[t.CUInt8T, V3_POOL_BYTES]
_v3_pool: memhub.MemPool | t.CPtr
_fb_mem: t.CArray[t.CUInt32T, GW * GH]
class V3:
x: t.CFloat64T
y: t.CFloat64T
z: t.CFloat64T
def __new__() -> 'V3' | t.CPtr:
return t.CVoid(t.CUInt64T(_v3_pool.alloc(24)), t.CPtr)
def __init__(self, x: t.CFloat64T, y: t.CFloat64T, z: t.CFloat64T):
self.x = x
self.y = y
self.z = z
def __add__(self, b: 'V3' | t.CPtr) -> 'V3' | t.CPtr:
return V3(self.x + b.x, self.y + b.y, self.z + b.z)
def __sub__(self, b: 'V3' | t.CPtr) -> 'V3' | t.CPtr:
return V3(self.x - b.x, self.y - b.y, self.z - b.z)
def __mul__(self, s: t.CFloat64T) -> 'V3' | t.CPtr:
return V3(self.x * s, self.y * s, self.z * s)
def __neg__(self) -> 'V3' | t.CPtr:
return V3(-self.x, -self.y, -self.z)
def dot(self, b: 'V3' | t.CPtr) -> t.CFloat64T:
return self.x * b.x + self.y * b.y + self.z * b.z
def cross(self, b: 'V3' | t.CPtr) -> 'V3' | t.CPtr:
return V3(self.y * b.z - self.z * b.y, self.z * b.x - self.x * b.z, self.x * b.y - self.y * b.x)
def nrm(self) -> 'V3' | t.CPtr:
l: t.CFloat64T = vm.sqrt(self.dot(self))
if l > 1e-12:
return self * (1.0 / l)
return V3(0.0, 0.0, 0.0)
def lerp(self, b: 'V3' | t.CPtr, t_val: t.CFloat64T) -> 'V3' | t.CPtr:
return self * (1.0 - t_val) + b * t_val
_g_cam: t.CArray[t.CFloat64T, 3]
_g_fwd: t.CArray[t.CFloat64T, 3]
_g_right: t.CArray[t.CFloat64T, 3]
_g_up: t.CArray[t.CFloat64T, 3]
CAM: V3 | t.CPtr
FWD: V3 | t.CPtr
RIGHT: V3 | t.CPtr
UP: V3 | t.CPtr
def v3_pool_reset():
_v3_pool.reset()
def clmp(x: t.CFloat64T, a: t.CFloat64T, b: t.CFloat64T) -> t.CFloat64T:
if x < a: return a
if x > b: return b
return x
def smoothstep(a: t.CFloat64T, b: t.CFloat64T, x: t.CFloat64T) -> t.CFloat64T:
t_val: t.CFloat64T = clmp((x - a) / (b - a), 0.0, 1.0)
return t_val * t_val * (3.0 - 2.0 * t_val)
def setup_camera():
global CAM, FWD, RIGHT, UP
e: t.CFloat64T = CAM_ELEV * 3.14159265358979323846 / 180.0
CAM = t.CVoid(c.Addr(_g_cam), t.CPtr)
CAM.x = CAM_DIST * vm.cos(e)
CAM.y = CAM_DIST * vm.sin(e)
CAM.z = 0.0
tmp0: V3 | t.CPtr = V3(0.0, 0.0, 0.0)
FWD = t.CVoid(c.Addr(_g_fwd), t.CPtr)
tmp1: V3 | t.CPtr = tmp0 - CAM
n1: V3 | t.CPtr = tmp1.nrm()
FWD.x = n1.x
FWD.y = n1.y
FWD.z = n1.z
tmp2: V3 | t.CPtr = V3(0.0, 1.0, 0.0)
RIGHT = t.CVoid(c.Addr(_g_right), t.CPtr)
tmp3: V3 | t.CPtr = FWD.cross(tmp2)
tmp4: V3 | t.CPtr = tmp3.nrm()
RIGHT.x = tmp4.x
RIGHT.y = tmp4.y
RIGHT.z = tmp4.z
UP = t.CVoid(c.Addr(_g_up), t.CPtr)
tmp5: V3 | t.CPtr = RIGHT.cross(FWD)
UP.x = tmp5.x
UP.y = tmp5.y
UP.z = tmp5.z
def hash3(x: t.CFloat64T, y: t.CFloat64T, z: t.CFloat64T) -> t.CFloat64T:
n: t.CFloat64T = vm.sin(x * 127.1 + y * 311.7 + z * 74.7) * 43758.5453
return n - vm.floor(n)
def stars(d: V3 | t.CPtr) -> V3 | t.CPtr:
col: V3 | t.CPtr = V3(0.0, 0.0, 0.0)
i: t.CInt = 0
while i < 3:
s: t.CFloat64T = 80.0 + t.CFloat64T(i) * 90.0
px: t.CFloat64T = d.x * s
py: t.CFloat64T = d.y * s
pz: t.CFloat64T = d.z * s
ix: t.CFloat64T = vm.floor(px)
iy: t.CFloat64T = vm.floor(py)
iz: t.CFloat64T = vm.floor(pz)
h: t.CFloat64T = hash3(ix, iy, iz)
if h > 0.991:
fx: t.CFloat64T = px - ix - 0.5
fy: t.CFloat64T = py - iy - 0.5
fz: t.CFloat64T = pz - iz - 0.5
d2: t.CFloat64T = fx * fx + fy * fy + fz * fz
br: t.CFloat64T = (h - 0.991) / 0.009 * vm.exp(-d2 * 9.0) * 1.4
tv: t.CFloat64T = hash3(iy, iz, ix)
tint: V3 | t.CPtr = V3(0.0, 0.0, 0.0)
if tv < 0.3:
tint = V3(0.7, 0.8, 1.0)
elif tv > 0.8:
tint = V3(1.0, 0.8, 0.6)
else:
tint = V3(1.0, 1.0, 1.0)
col = col + tint * br
i += 1
return col
def disk_shade(cp: V3 | t.CPtr, rr: t.CFloat64T, gT: t.CFloat64T) -> V3 | t.CPtr:
tt: t.CFloat64T = (rr - DISK_IN) / (DISK_OUT - DISK_IN)
edge: t.CFloat64T = smoothstep(0.0, 0.07, tt) * smoothstep(0.0, 0.18, 1.0 - tt)
ang: t.CFloat64T = vm.atan2(cp.z, cp.x)
w: t.CFloat64T = 1.0 / vm.pow(rr, 1.5)
ph: t.CFloat64T = ang - gT * 0.0011 * w * 9.0
n: t.CFloat64T = 0.5 + 0.5 * vm.sin(ph * 5.0 - rr * 1.6)
n2: t.CFloat64T = 0.5 + 0.5 * vm.sin(ph * 13.0 + rr * 0.8 + 1.7)
dens: t.CFloat64T = (0.35 + 0.65 * n) * (0.55 + 0.45 * n2)
bright: t.CFloat64T = (0.45 + 1.7 * vm.pow(1.0 - tt, 1.8)) * edge
vdir: V3 | t.CPtr = V3(-cp.z, 0.0, cp.x).nrm()
beta: t.CFloat64T = 0.46 / vm.sqrt(rr)
to_cam: V3 | t.CPtr = (CAM - cp).nrm()
mu: t.CFloat64T = vdir.dot(to_cam)
dop: t.CFloat64T = 1.0 / (1.0 - beta * mu)
beam: t.CFloat64T = vm.pow(dop, 3.0)
c1: V3 | t.CPtr = V3(1.0, 0.92, 0.68)
c2: V3 | t.CPtr = V3(1.0, 0.42, 0.13)
base: V3 | t.CPtr = c1.lerp(c2, tt)
base.z += (dop - 1.0) * 0.35
base.x -= (dop - 1.0) * 0.05
inten: t.CFloat64T = bright * dens * beam * 1.25
return base * inten
def trace(dir_v: V3 | t.CPtr, gT: t.CFloat64T) -> V3 | t.CPtr:
v3_pool_reset()
pos: V3 | t.CPtr = V3(CAM.x, CAM.y, CAM.z)
vel: V3 | t.CPtr = V3(dir_v.x, dir_v.y, dir_v.z)
hvec: V3 | t.CPtr = pos.cross(vel)
h2: t.CFloat64T = hvec.dot(hvec)
T: t.CFloat64T = 1.0
col: V3 | t.CPtr = V3(0.0, 0.0, 0.0)
i: t.CInt = 0
while i < MAX_STEPS:
r2: t.CFloat64T = pos.dot(pos)
r: t.CFloat64T = vm.sqrt(r2)
if r < 1.0:
break
if r > ESCAPE_R:
col = col + stars(vel.nrm()) * T
break
dt: t.CFloat64T = clmp(r * 0.08, 0.03, 2.2)
r5: t.CFloat64T = vm.pow(r2, 2.5)
coeff: t.CFloat64T = -1.5 * h2 / r5
k1v: V3 | t.CPtr = pos * coeff
k2p_a: V3 | t.CPtr = vel + k1v * (dt * 0.5)
k2v_a: V3 | t.CPtr = pos + vel * (dt * 0.5)
r2_a: t.CFloat64T = k2v_a.dot(k2v_a)
coeff_a: t.CFloat64T = -1.5 * h2 / vm.pow(r2_a, 2.5)
k2v: V3 | t.CPtr = k2v_a * coeff_a
k3p_a: V3 | t.CPtr = vel + k2v * (dt * 0.5)
k3v_a: V3 | t.CPtr = pos + k2p_a * (dt * 0.5)
r2_b: t.CFloat64T = k3v_a.dot(k3v_a)
coeff_b: t.CFloat64T = -1.5 * h2 / vm.pow(r2_b, 2.5)
k3v: V3 | t.CPtr = k3v_a * coeff_b
k4p_a: V3 | t.CPtr = vel + k3v * dt
k4v_a: V3 | t.CPtr = pos + k3p_a * dt
r2_c: t.CFloat64T = k4v_a.dot(k4v_a)
coeff_c: t.CFloat64T = -1.5 * h2 / vm.pow(r2_c, 2.5)
k4v: V3 | t.CPtr = k4v_a * coeff_c
npos: V3 | t.CPtr = pos + (vel + k2p_a * 2.0 + k3p_a * 2.0 + k4p_a) * (dt / 6.0)
nvel: V3 | t.CPtr = vel + (k1v + k2v * 2.0 + k3v * 2.0 + k4v) * (dt / 6.0)
if pos.y * npos.y < 0.0:
f: t.CFloat64T = pos.y / (pos.y - npos.y)
cp: V3 | t.CPtr = pos.lerp(npos, f)
rr: t.CFloat64T = vm.sqrt(cp.x * cp.x + cp.z * cp.z)
if rr > DISK_IN and rr < DISK_OUT:
emit: V3 | t.CPtr = disk_shade(cp, rr, gT)
col = col + emit * T
a: t.CFloat64T = clmp(smoothstep(0.0, 0.07, (rr - DISK_IN) / (DISK_OUT - DISK_IN)) * smoothstep(0.0, 0.18, 1.0 - (rr - DISK_IN) / (DISK_OUT - DISK_IN)) * 0.92, 0.0, 1.0)
T = T * (1.0 - a)
if T < 0.01:
break
pos = npos
vel = nvel
i += 1
return col
def shade_pixel(px: t.CInt, py: t.CInt, gT: t.CFloat64T) -> t.CUInt32T:
aspect: t.CFloat64T = GW_F / GH_F
sx: t.CFloat64T = (2.0 * (t.CFloat64T(px) + 0.5) / GW_F - 1.0) * aspect * FOVF
sy: t.CFloat64T = (1.0 - 2.0 * (t.CFloat64T(py) + 0.5) / GH_F) * FOVF
dir_v: V3 | t.CPtr = (FWD + RIGHT * sx + UP * sy).nrm()
c: V3 | t.CPtr = trace(dir_v, gT)
ex: t.CFloat64T = 1.15
c = c * ex
c.x = c.x / (1.0 + c.x)
c.y = c.y / (1.0 + c.y)
c.z = c.z / (1.0 + c.z)
c.x = vm.pow(c.x, 1.0 / 2.2)
c.y = vm.pow(c.y, 1.0 / 2.2)
c.z = vm.pow(c.z, 1.0 / 2.2)
R: t.CInt = t.CInt(clmp(c.x, 0.0, 1.0) * 255.0)
G: t.CInt = t.CInt(clmp(c.y, 0.0, 1.0) * 255.0)
B: t.CInt = t.CInt(clmp(c.z, 0.0, 1.0) * 255.0)
return t.CUInt32T((R << 16) | (G << 8) | B)
@c.Attribute(t.attr.section(".text.startup"), t.attr.aligned(16))
def _start() -> t.CInt | t.CExport:
_v3_pool = memhub.MemPool(c.Addr(_v3_mem), V3_POOL_BYTES)
setup_camera()
root: vpui.Tk = vpui.Tk()
root.title("Gargantua")
root.set_style(window.STYLE_WIN7)
root.bg_color = t.CUInt32T(0x000000)
master: vpui.Tk | t.CPtr = c.Addr(root)
canvas: vpui.FBCanvas = vpui.FBCanvas(master, GW, GH)
root.pack(0, vpui.PACK_TOP, vpui.FILL_BOTH, 1, 0, 0)
fb: UINT32PTR = c.Addr(_fb_mem)
string.memset(fb, 0, GW * GH * 4)
canvas.set_fb(fb, GW, GH)
root.geometry(100, 30, GW, GH + 32)
gT: t.CFloat64T = 0.0
rendered: t.CInt = 0
evt: window.InputEvent
while window.is_active(root.win_id):
result: t.CInt = window.poll_event(c.Addr(evt))
if result != 0:
if evt.type == window.EVENT_TYPE_PING:
window.flush(root.win_id)
elif evt.type == window.EVENT_TYPE_RESIZE:
sz: t.CInt = window.get_win_size(root.win_id)
new_w: t.CInt = sz >> 16
new_h: t.CInt = sz & 0xFFFF
canvas.set_fb(fb, new_w, new_h)
if rendered == 0:
y: t.CInt = 0
while y < GH:
x: t.CInt = 0
while x < GW:
pixel: t.CUInt32T = shade_pixel(x, y, gT)
fb[y * GW + x] = pixel
x += 1
y += 1
if y % YIELD_ROWS == 0:
root.redraw()
process.yield_cpu()
result2: t.CInt = window.poll_event(c.Addr(evt))
if result2 != 0:
if evt.type == window.EVENT_TYPE_PING:
window.flush(root.win_id)
root.redraw()
rendered = 1
gT += 50.0
process.yield_cpu()
process.exit(0)
return 0

View File

@@ -0,0 +1,31 @@
{
"name": "Gargantua",
"version": "1.0.0",
"source_dir": "./",
"temp_dir": "./temp",
"output_dir": "./output",
"compiler": {
"cmd": "llc",
"flags": ["-filetype=obj", "-mtriple=x86_64-none-elf", "-relocation-model=static", "-O2"]
},
"linker": {
"cmd": "ld.lld.exe",
"flags": [
"-m", "elf_x86_64",
"-T", "linker.ld",
"--oformat", "elf64-x86-64",
"--strip-all"
],
"output": "gargantua.elf"
},
"includes": ["../.."],
"target": {
"triple": "x86_64-none-elf",
"datalayout": "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
},
"options": {
"slice_level": 3,
"target": "llvm",
"strict_mode": true
}
}

39
Apps/HelloWorld/linker.ld Normal file
View File

@@ -0,0 +1,39 @@
ENTRY(__entry)
SECTIONS {
. = 0x400000;
.text : {
__entry = .;
*(.text.startup)
*(.text)
*(.text.*)
}
.rodata : {
*(.rodata)
*(.rodata.*)
}
.data : {
*(.data)
*(.data.*)
}
.bss : {
__bss_start = .;
*(.bss)
*(.bss.*)
__bss_end = .;
}
/DISCARD/ : {
*(.comment)
*(.note)
*(.eh_frame)
*(.eh_frame_hdr)
*(.reloc)
*(.rela)
*(.debug*)
}
}

51
Apps/HelloWorld/main.py Normal file
View File

@@ -0,0 +1,51 @@
import vpsdk.vpui as vpui
import vpsdk.window as window
import vpsdk.process as process
import vpsdk.dynlib as dynlib
from stdint import *
import t, c
@c.Attribute(t.attr.section(".text.startup"), t.attr.aligned(16))
def _start() -> t.CInt | t.CExport:
base: t.CUInt64T = dynlib.load_so("/LIBS/SLOG.SO")
if base != 0:
dynlib.so_call1("log_info", "Hello from dynamic library!")
root: vpui.Tk = vpui.Tk()
root.title("Input Demo")
root.set_style(window.STYLE_WIN7)
root.geometry(290, 30, 300, 200)
root.bg_color = t.CUInt32T(0x1E1E32)
master: vpui.Tk | t.CPtr = c.Addr(root)
entry: vpui.Entry = vpui.Entry(master, 260, 28)
root.pack(0, vpui.PACK_TOP, vpui.FILL_X, 0, 20, 10)
result: vpui.Label = vpui.Label(master, "", t.CUInt32T(0x00FF00))
root.pack(1, vpui.PACK_BOTTOM, 0, 0, 0, 10)
def _on_submit() -> t.CInt:
text: t.CConst | str = entry.get()
result.config(text)
entry.delete(0, -1)
return 0
lbl: vpui.Label = vpui.Label(master, "Name:", 0xFFFFFFFF)
root.pack(2, vpui.PACK_TOP, 0, 0, 20, 0)
btn: vpui.Button = vpui.Button(master, 100, 36, "Submit", c.Addr(_on_submit))
root.pack(3, vpui.PACK_TOP, 0, 0, 0, 10)
root2: vpui.Tk = vpui.Tk()
root2.title("Test No-Resp")
root2.set_style(window.STYLE_WIN10)
root2.geometry(200, 50, 300, 150)
root2.bg_color = t.CUInt32T(0x1E1E32)
master2: vpui.Tk | t.CPtr = c.Addr(root2)
lbl2: vpui.Label = vpui.Label(master2, "This window will NOT respond!", 0xFFFFFFFF)
lbl2.place(10, 10)
root2.update()
root.mainloop()
process.exit(0)
return 0

View File

@@ -0,0 +1,31 @@
{
"name": "HelloWorld",
"version": "1.0.0",
"source_dir": "./",
"temp_dir": "./temp",
"output_dir": "./output",
"compiler": {
"cmd": "llc",
"flags": ["-filetype=obj", "-mtriple=x86_64-none-elf", "-relocation-model=static", "-O2"]
},
"linker": {
"cmd": "ld.lld.exe",
"flags": [
"-m", "elf_x86_64",
"-T", "linker.ld",
"--oformat", "elf64-x86-64",
"--strip-all"
],
"output": "helloworld.elf"
},
"includes": ["../.."],
"target": {
"triple": "x86_64-none-elf",
"datalayout": "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
},
"options": {
"slice_level": 3,
"target": "llvm",
"strict_mode": true
}
}

305
Apps/Scene3D/gfx.py Normal file
View File

@@ -0,0 +1,305 @@
from stdint import *
import vipermath
import string
import t, c
PI: t.CDefine = float(3.14159265358979323846)
SPHERE_SLICES: t.CDefine = (24 * 1)
SPHERE_STACKS: t.CDefine = (16 * 1)
SIN_WAVE_GRID: t.CDefine = (40 * 1)
def COLOR_RGB(r: int, g: int, b: int) -> t.CInline | t.CInt:
return (255 << 24) | (r << 16) | (g << 8) | (b)
@t.Object
class Vec3:
x: float
y: float
z: float
def __init__(self, x: float, y: float, z: float):
self.x = x
self.y = y
self.z = z
def Sub(self, b: 'Vec3') -> 'Vec3':
return Vec3(self.x - b.x, self.y - b.y, self.z - b.z)
def Cross(self, b: 'Vec3') -> 'Vec3':
return Vec3(self.y * b.z - self.z * b.y, self.z * b.x - self.x * b.z, self.x * b.y - self.y * b.x)
def Dot(self, b: 'Vec3') -> float:
return self.x * b.x + self.y * b.y + self.z * b.z
def Norm(self) -> 'Vec3':
l = vipermath.sqrtf(self.Dot(self))
return Vec3(self.x / l, self.y / l, self.z / l)
class Mat4:
m: t.CArray[t.CArray[float, 4], 4]
def Mat4_Identity() -> Mat4:
m: Mat4 = Mat4()
string.memset(c.Addr(m), 0, Mat4.__sizeof__())
m.m[0][0] = 1; m.m[1][1] = 1; m.m[2][2] = 1; m.m[3][3] = 1
return m
def Mat4_Mul(a: Mat4, b: Mat4) -> Mat4:
res: Mat4 = Mat4()
string.memset(c.Addr(res), 0, Mat4.__sizeof__())
for i in range(4):
for j in range(4):
for k in range(4):
res.m[i][j] += a.m[i][k] * b.m[k][j]
return res
def Mat4_MulVec(m: Mat4, v: Vec3) -> Vec3:
x: float = m.m[0][0] * v.x + m.m[0][1] * v.y + m.m[0][2] * v.z + m.m[0][3]
y: float = m.m[1][0] * v.x + m.m[1][1] * v.y + m.m[1][2] * v.z + m.m[1][3]
z: float = m.m[2][0] * v.x + m.m[2][1] * v.y + m.m[2][2] * v.z + m.m[2][3]
w: float = m.m[3][0] * v.x + m.m[3][1] * v.y + m.m[3][2] * v.z + m.m[3][3]
if w != 0:
x /= w; y /= w; z /= w
return Vec3(x, y, z)
def Mat4_Perspective(fov: float, aspect: float, zn: float, zf: float) -> Mat4:
m: Mat4 = Mat4()
string.memset(c.Addr(m), 0, Mat4.__sizeof__())
f: float = float(1.0) / vipermath.tanf(fov / float(2.0))
m.m[0][0] = f / aspect; m.m[1][1] = f
m.m[2][2] = zf / (zn - zf); m.m[2][3] = (zf * zn) / (zn - zf); m.m[3][2] = -1
return m
def Mat4_LookAt(eye: Vec3, target: Vec3, up: Vec3) -> Mat4:
zaxis: Vec3 = eye.Sub(target).Norm()
xaxis: Vec3 = up.Cross(zaxis).Norm()
yaxis: Vec3 = zaxis.Cross(xaxis)
m: Mat4 = Mat4_Identity()
m.m[0][0]=xaxis.x; m.m[0][1]=xaxis.y; m.m[0][2]=xaxis.z; m.m[0][3]= -xaxis.Dot(eye)
m.m[1][0]=yaxis.x; m.m[1][1]=yaxis.y; m.m[1][2]=yaxis.z; m.m[1][3]= -yaxis.Dot(eye)
m.m[2][0]=zaxis.x; m.m[2][1]=zaxis.y; m.m[2][2]=zaxis.z; m.m[2][3]= -zaxis.Dot(eye)
m.m[3][3] = 1
return m
def Mat4_Translate(x: float, y: float, z: float) -> Mat4:
m: Mat4 = Mat4_Identity()
m.m[0][3] = x; m.m[1][3] = y; m.m[2][3] = z
return m
def Mat4_RotateY(a: float) -> Mat4:
m: Mat4 = Mat4_Identity()
m.m[0][0] = vipermath.cosf(a); m.m[0][2] = vipermath.sinf(a)
m.m[2][0] = -vipermath.sinf(a); m.m[2][2] = vipermath.cosf(a)
return m
@t.Object
class Surface:
fb: UINT32PTR
zb: float | t.CPtr
w: int
h: int
def __init__(self, fb: UINT32PTR, zb: float | t.CPtr, w: int, h: int):
self.fb = fb
self.zb = zb
self.w = w
self.h = h
@t.Object
class Renderer:
_fb: UINT32PTR
_zb: float | t.CPtr
_w: int
_h: int
def __init__(self, fb: UINT32PTR, zb: float | t.CPtr, w: int, h: int):
self._fb = fb
self._zb = zb
self._w = w
self._h = h
def Clear(self, color: t.CUInt32T):
fb: UINT32PTR = self._fb
zb: float | t.CPtr = self._zb
size: int = self._w * self._h
for i in range(size):
fb[i] = color
zb[i] = float(1.0)
def DrawLine2D(self, x0: int, y0: int, x1: int, y1: int, col: t.CUInt32T):
fb: UINT32PTR = self._fb
w: int = self._w; h: int = self._h
dx: int = abs(x1-x0); dy: int = abs(y1-y0)
sx: int = 1 if x0 < x1 else -1; sy: int = 1 if y0 < y1 else -1
err: int = dx - dy
while True:
if x0 >= 0 and x0 < w and y0 >= 0 and y0 < h: fb[y0 * w + x0] = col
if x0 == x1 and y0 == y1: break
e2: int = 2 * err
if e2 > -dy: err -= dy; x0 += sx
if e2 < dx: err += dx; y0 += sy
def DrawTriangle(self, v0: Vec3, v1: Vec3, v2: Vec3, col: t.CUInt32T):
if v0.z < float(0.0) or v1.z < float(0.0) or v2.z < float(0.0): return
if (v0.x > float(10.0) or v0.x < float(-10.0) or v0.y > float(10.0) or v0.y < float(-10.0) or
v1.x > float(10.0) or v1.x < float(-10.0) or v1.y > float(10.0) or v1.y < float(-10.0) or
v2.x > float(10.0) or v2.x < float(-10.0) or v2.y > float(10.0) or v2.y < float(-10.0)): return
fb: UINT32PTR = self._fb
zb: float | t.CPtr = self._zb
w: int = self._w
h: int = self._h
sx0: float = (v0.x + float(1.0)) * float(0.5) * w; sy0: float = (float(1.0) - v0.y) * float(0.5) * h
sx1: float = (v1.x + float(1.0)) * float(0.5) * w; sy1: float = (float(1.0) - v1.y) * float(0.5) * h
sx2: float = (v2.x + float(1.0)) * float(0.5) * w; sy2: float = (float(1.0) - v2.y) * float(0.5) * h
minX: int = max(0, int(vipermath.floorf(min(min(sx0, sx1), sx2))))
maxX: int = min(w - 1, int(vipermath.ceilf(max(max(sx0, sx1), sx2))))
minY: int = max(0, int(vipermath.floorf(min(min(sy0, sy1), sy2))))
maxY: int = min(h - 1, int(vipermath.ceilf(max(max(sy0, sy1), sy2))))
dx12: float = sx1 - sx2; dy12: float = sy1 - sy2
dx02: float = sx0 - sx2; dy02: float = sy0 - sy2
denom: float = dx12 * dy02 - dy12 * dx02
if denom < float(0.001) and denom > float(-0.001): return
invDenom: float = float(1.0) / denom
row_dxP_start: float = float(minX) - sx2
for y in range(minY, maxY + 1):
dyP: float = float(y) - sy2
dxP: float = row_dxP_start
row_base: int = y * w
for x in range(minX, maxX + 1):
w0: float = (dx12 * dyP - dy12 * dxP) * invDenom
w1: float = (dxP * dy02 - dyP * dx02) * invDenom
w2: float = float(1.0) - w0 - w1
if w0 >= 0 and w1 >= 0 and w2 >= 0:
z: float = w0 * v0.z + w1 * v1.z + w2 * v2.z
idx: int = row_base + x
if z < zb[idx]:
zb[idx] = z
fb[idx] = col
dxP += float(1.0)
def DrawGlowDot(self, x: float, y: float, radius: float, core_col: t.CUInt32T, intensity: float):
fb: UINT32PTR = self._fb; w: int = self._w; h: int = self._h
r: int = int(radius) + 4
ix: int = int(x); iy: int = int(y)
for dy in range(-r, r + 1):
py: int = iy + dy
if py < 0 or py >= h: continue
for dx in range(-r, r + 1):
px: int = ix + dx
if px < 0 or px >= w: continue
dist: float = vipermath.sqrtf(float(dx*dx + dy*dy))
if dist < radius:
self.BlendPixel(px, py, core_col, intensity)
elif dist < float(r):
fade: float = 1.0 - (dist - radius) / 4.0
self.BlendPixel(px, py, core_col, intensity * fade * 0.5)
def BlendPixel(self, x: int, y: int, col: t.CUInt32T, alpha: float):
if alpha <= 0.0: return
fb: UINT32PTR = self._fb; w: int = self._w; h: int = self._h
if x < 0 or x >= w or y < 0 or y >= h: return
idx: int = y * w + x
bg: t.CUInt32T = fb[idx]
bg_b: int = bg & 0xFF; bg_g: int = (bg >> 8) & 0xFF; bg_r: int = (bg >> 16) & 0xFF
f_b: int = col & 0xFF; f_g: int = (col >> 8) & 0xFF; f_r: int = (col >> 16) & 0xFF
a: int = int(alpha * 255.0)
inv_a: int = 255 - a
nr: int = (f_r * a + bg_r * inv_a) >> 8
ng: int = (f_g * a + bg_g * inv_a) >> 8
nb: int = (f_b * a + bg_b * inv_a) >> 8
fb[idx] = COLOR_RGB(255 if (nr > 255) else nr,
255 if (ng > 255) else ng,
255 if (nb > 255) else nb)
@t.Object
class Scene3D:
renderer: Renderer
def __init__(self, fb: UINT32PTR, zb: float | t.CPtr, w: int, h: int):
self.renderer = Renderer(fb, zb, w, h)
def Render(self, time: float):
rw: int = self.renderer._w
rh: int = self.renderer._h
self.renderer.Clear(COLOR_RGB(15, 15, 25))
yaw: float = float(45.0) * PI / float(180.0); pitch: float = float(45.0) * PI / float(180.0); radius: float = float(10.0)
eye: Vec3 = Vec3(radius*vipermath.cosf(pitch)*vipermath.cosf(yaw), radius*vipermath.sinf(pitch), radius*vipermath.cosf(pitch)*vipermath.sinf(yaw))
target: Vec3 = Vec3(0, 0, 0); up: Vec3 = Vec3(0, 1, 0)
view: Mat4 = Mat4_LookAt(eye, target, up)
proj: Mat4 = Mat4_Perspective(PI / float(3.0), float(rw)/float(rh), float(0.1), float(100.0))
vp: Mat4 = Mat4_Mul(proj, view)
cubeX: float = float(-3.5)
cubeMVP: Mat4 = Mat4_Mul(vp, Mat4_Translate(cubeX, 0, 0))
self._DrawCube(cubeMVP, COLOR_RGB(180, 180, 180))
colors: t.CArray[t.CUInt32T, 4] = [COLOR_RGB(255,50,50), COLOR_RGB(50,50,255), COLOR_RGB(255,255,50), COLOR_RGB(50,255,255)]
for i in range(4):
a: float = time * float(1.5) + i * (PI / float(2.0)); r: float = float(3.0)
pos: Vec3 = Vec3(vipermath.cosf(a) * r + cubeX, 0, vipermath.sinf(a) * r)
sphereMVP: Mat4 = Mat4_Mul(vp, Mat4_Translate(pos.x, pos.y, pos.z))
self._DrawSphere(sphereMVP, Vec3(0,0,0), float(0.5), colors[i])
self._Draw3DSinWave(vp, Vec3(float(3.5), 0, 0), time)
self.renderer.DrawLine2D(50, rh - 150, rw - 50, rh - 150, COLOR_RGB(80, 80, 80))
self.renderer.DrawLine2D(50, rh - 50, 50, rh - 250, COLOR_RGB(80, 80, 80))
wave_shift: float = time * float(2.0)
prev_x: int = 50; prev_y: int = rh - 150 - int(vipermath.sinf(0 - wave_shift) * float(100.0))
for i in range(1, rw - 100):
tr: float = float(i) / float(rw-100) * float(4.0) * PI
cx: int = 50 + i; cy: int = rh - 150 - int(vipermath.sinf(tr - wave_shift) * float(100.0))
self.renderer.DrawLine2D(prev_x, prev_y, cx, cy, COLOR_RGB(0, 255, 100))
prev_x = cx; prev_y = cy
def _DrawCube(self, mvp: Mat4, col: t.CUInt32T):
v: t.CArray[Vec3, 8] = [
Vec3(-1, -1, -1), Vec3(-1, -1, 1), Vec3(-1, 1, -1), Vec3(-1, 1, 1),
Vec3( 1, -1, -1), Vec3( 1, -1, 1), Vec3( 1, 1, -1), Vec3( 1, 1, 1)
]
for i in range(8): v[i] = Mat4_MulVec(mvp, v[i])
faces: t.CArray[t.CArray[int, 3], 12] = [
[0, 2, 1], [1, 2, 3], [4, 1, 5], [4, 0, 1], [6, 3, 2], [6, 7, 3],
[4, 6, 0], [0, 6, 2], [5, 7, 4], [4, 7, 6], [1, 3, 5], [5, 3, 7]
]
for i in range(12): self.renderer.DrawTriangle(v[faces[i][0]], v[faces[i][1]], v[faces[i][2]], col)
def _DrawSphere(self, mvp: Mat4, center: Vec3, radius: float, col: t.CUInt32T):
step_pi: float = PI / SPHERE_STACKS; step_2pi: float = float(2.0) * PI / SPHERE_SLICES
for i in range(SPHERE_STACKS):
for j in range(SPHERE_SLICES):
theta1: float = i * step_pi; theta2: float = (i + 1) * step_pi
phi1: float = j * step_2pi; phi2: float = (j + 1) * step_2pi
v: t.CArray[Vec3, 4]
v[0] = Vec3(center.x+radius*vipermath.sinf(theta1)*vipermath.cosf(phi1), center.y+radius*vipermath.cosf(theta1), center.z+radius*vipermath.sinf(theta1)*vipermath.sinf(phi1))
v[1] = Vec3(center.x+radius*vipermath.sinf(theta1)*vipermath.cosf(phi2), center.y+radius*vipermath.cosf(theta1), center.z+radius*vipermath.sinf(theta1)*vipermath.sinf(phi2))
v[2] = Vec3(center.x+radius*vipermath.sinf(theta2)*vipermath.cosf(phi1), center.y+radius*vipermath.cosf(theta2), center.z+radius*vipermath.sinf(theta2)*vipermath.sinf(phi1))
v[3] = Vec3(center.x+radius*vipermath.sinf(theta2)*vipermath.cosf(phi2), center.y+radius*vipermath.cosf(theta2), center.z+radius*vipermath.sinf(theta2)*vipermath.sinf(phi2))
for k in range(4): v[k] = Mat4_MulVec(mvp, v[k])
self.renderer.DrawTriangle(v[0], v[1], v[2], col)
self.renderer.DrawTriangle(v[1], v[3], v[2], col)
def _Draw3DSinWave(self, vp: Mat4, pos: Vec3, time: float):
_range: float = float(2.0) * PI; step: float = _range / SIN_WAVE_GRID; scale: float = float(0.5)
mvp: Mat4 = Mat4_Mul(vp, Mat4_Mul(Mat4_Translate(pos.x, pos.y, pos.z), Mat4_RotateY(time * float(1.0))))
for i in range(SIN_WAVE_GRID):
for j in range(SIN_WAVE_GRID):
x0: float = -PI + i * step; z0 = -PI + j * step; x1: float = x0 + step; z1 = z0 + step
y00: float = vipermath.sinf(x0) * vipermath.cosf(z0) * scale; y10: float = vipermath.sinf(x1) * vipermath.cosf(z0) * scale
y01: float = vipermath.sinf(x0) * vipermath.cosf(z1) * scale; y11: float = vipermath.sinf(x1) * vipermath.cosf(z1) * scale
t1: float = (y00 / scale + float(1.0)) * float(0.5); r1: int = int(50 + 205 * t1); g1: int = int(80 + 120 * vipermath.sinf(t1 * PI)); b1: int = int(255 - 205 * t1)
col1: t.CUInt32T = COLOR_RGB(255 if (r1 > 255) else (0 if (r1 < 0) else r1), 255 if (g1 > 255) else (0 if (g1 < 0) else g1), 255 if (b1 > 255) else (0 if (b1 < 0) else b1))
t2: float = (y11 / scale + float(1.0)) * float(0.5); r2: int = int(50 + 205 * t2); g2: int = int(80 + 120 * vipermath.sinf(t2 * PI)); b2: int = int(255 - 205 * t2)
col2: t.CUInt32T = COLOR_RGB(255 if (r2 > 255) else (0 if (r2 < 0) else r2), 255 if (g2 > 255) else (0 if (g2 < 0) else g2), 255 if (b2 > 255) else (0 if (b2 < 0) else b2))
v00: Vec3 = Mat4_MulVec(mvp, Vec3(x0, y00, z0)); v10: Vec3 = Mat4_MulVec(mvp, Vec3(x1, y10, z0))
v01: Vec3 = Mat4_MulVec(mvp, Vec3(x0, y01, z1)); v11: Vec3 = Mat4_MulVec(mvp, Vec3(x1, y11, z1))
self.renderer.DrawTriangle(v00, v10, v11, col1); self.renderer.DrawTriangle(v00, v11, v01, col2)

39
Apps/Scene3D/linker.ld Normal file
View File

@@ -0,0 +1,39 @@
ENTRY(__entry)
SECTIONS {
. = 0x400000;
.text : {
__entry = .;
*(.text.startup)
*(.text)
*(.text.*)
}
.rodata : {
*(.rodata)
*(.rodata.*)
}
.data : {
*(.data)
*(.data.*)
}
.bss : {
__bss_start = .;
*(.bss)
*(.bss.*)
__bss_end = .;
}
/DISCARD/ : {
*(.comment)
*(.note)
*(.eh_frame)
*(.eh_frame_hdr)
*(.reloc)
*(.rela)
*(.debug*)
}
}

62
Apps/Scene3D/main.py Normal file
View File

@@ -0,0 +1,62 @@
import vpsdk.window as window
import vpsdk.process as process
import vpsdk.vpui as vpui
import viperstring as string
import vipermath
from stdint import *
import gfx
import t, c
SCENE_W: t.CDefine = 640
SCENE_H: t.CDefine = 360
_zbuf_mem: t.CArray[t.CUInt8T, SCENE_W * SCENE_H * 8]
_fb_mem: t.CArray[t.CUInt32T, SCENE_W * SCENE_H]
_root_ptr: vpui.Tk | t.CPtr
_canvas_ptr: vpui.FBCanvas | t.CPtr
_s3d_ptr: gfx.Scene3D | t.CPtr
_time_val: float = float(0.0)
def _render_thread(arg: t.CVoid | t.CPtr) -> t.CVoid:
root: vpui.Tk | t.CPtr = _root_ptr
canvas: vpui.FBCanvas | t.CPtr = _canvas_ptr
s3d: gfx.Scene3D | t.CPtr = _s3d_ptr
while root.winfo_exists():
s3d.Render(_time_val)
_time_val += float(0.02)
root.update()
process.yield_cpu()
@c.Attribute(t.attr.section(".text.startup"), t.attr.aligned(16))
def _start() -> t.CInt | t.CExport:
root: vpui.Tk = vpui.Tk()
root.title("3D Scene")
root.set_style(window.STYLE_WIN11)
root.bg_color = t.CUInt32T(0x0F0F19)
master: vpui.Tk | t.CPtr = c.Addr(root)
canvas: vpui.FBCanvas = vpui.FBCanvas(master, SCENE_W, SCENE_H)
root.pack(0, vpui.PACK_TOP, vpui.FILL_BOTH, 1, 0, 0)
zbuf: float | t.CPtr = t.CVoid(c.Addr(_zbuf_mem), t.CPtr)
string.memset(zbuf, 0, SCENE_W * SCENE_H * 8)
fb: UINT32PTR = c.Addr(_fb_mem)
string.memset(fb, 0, SCENE_W * SCENE_H * 4)
canvas.set_fb(fb, SCENE_W, SCENE_H)
s3d: gfx.Scene3D = gfx.Scene3D(fb, zbuf, SCENE_W, SCENE_H)
root.geometry(100, 30, SCENE_W, SCENE_H + 32)
_root_ptr = c.Addr(root)
_canvas_ptr = c.Addr(canvas)
_s3d_ptr = c.Addr(s3d)
process.thread_create(_render_thread, None)
root.mainloop()
process.exit(0)
return 0

31
Apps/Scene3D/project.json Normal file
View File

@@ -0,0 +1,31 @@
{
"name": "Scene3D",
"version": "1.0.0",
"source_dir": "./",
"temp_dir": "./temp",
"output_dir": "./output",
"compiler": {
"cmd": "llc",
"flags": ["-filetype=obj", "-mtriple=x86_64-none-elf", "-relocation-model=static", "-O2"]
},
"linker": {
"cmd": "ld.lld.exe",
"flags": [
"-m", "elf_x86_64",
"-T", "linker.ld",
"--oformat", "elf64-x86-64",
"--strip-all"
],
"output": "scene3d.elf"
},
"includes": ["../.."],
"target": {
"triple": "x86_64-none-elf",
"datalayout": "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
},
"options": {
"slice_level": 3,
"target": "llvm",
"strict_mode": true
}
}

39
Apps/Terminal/linker.ld Normal file
View File

@@ -0,0 +1,39 @@
ENTRY(__entry)
SECTIONS {
. = 0x400000;
.text : {
__entry = .;
*(.text.startup)
*(.text)
*(.text.*)
}
.rodata : {
*(.rodata)
*(.rodata.*)
}
.data : {
*(.data)
*(.data.*)
}
.bss : {
__bss_start = .;
*(.bss)
*(.bss.*)
__bss_end = .;
}
/DISCARD/ : {
*(.comment)
*(.note)
*(.eh_frame)
*(.eh_frame_hdr)
*(.reloc)
*(.rela)
*(.debug*)
}
}

326
Apps/Terminal/main.py Normal file
View File

@@ -0,0 +1,326 @@
import vpsdk.vpui as vpui
import vpsdk.window as window
import vpsdk.process as process
import vpsdk.fs as fs
import vpsdk.syscall as _syscall
import vpsdk.stdlib as stdlib
import string
import viperlib
from stdint import *
import t, c
@c.Attribute(t.attr.section(".text.startup"), t.attr.aligned(16))
def _start() -> t.CInt | t.CExport:
root: vpui.Tk = vpui.Tk()
root.title("Terminal")
root.set_style(window.STYLE_WIN7)
root.geometry(80, 30, 640, 480)
root.bg_color = t.CUInt32T(0x0C0C0C)
master: vpui.Tk | t.CPtr = c.Addr(root)
def _sdbg(msg: str):
_syscall._syscall1(t.CUInt64T(18), t.CUInt64T(msg))
_sdbg("[term] start\n")
_cwd: t.CArray[t.CChar, 64]
_cwd[0] = 47
for i in range(1, 64):
_cwd[i] = 0
sbar: vpui.Scrollbar = vpui.Scrollbar(master, 16, 446, vpui.VERTICAL)
root.pack(0, vpui.PACK_RIGHT, vpui.FILL_Y, 0, 0, 0)
term: vpui.Text = vpui.Text(master, 624, 446)
root.pack(1, vpui.PACK_LEFT, vpui.FILL_BOTH, 1, 0, 0)
term.insert("ViperOS Terminal v1.1")
term.insert("Type 'help' for commands.")
term.insert("")
term.yscrollbar = t.CType(sbar, vpui.Widget, t.CPtr)
def _on_scroll():
act: t.CInt = sbar.action
if act == 1:
term.scroll_offset -= 1
elif act == 2:
term.scroll_offset += 1
elif act == 3:
vis: t.CInt = term._visible_lines()
term.scroll_offset -= vis
elif act == 4:
vis2: t.CInt = term._visible_lines()
term.scroll_offset += vis2
elif act == 5:
aval: t.CInt = sbar.action_value
if term.line_count > 0:
term.scroll_offset = aval * term.line_count / 1000
vis3: t.CInt = term._visible_lines()
max_off: t.CInt = term.line_count - vis3
if max_off < 0: max_off = 0
if term.scroll_offset < 0: term.scroll_offset = 0
if term.scroll_offset > max_off: term.scroll_offset = max_off
term._update_scrollbar()
sbar.command = c.Addr(_on_scroll)
def _startswith(s: str, prefix: str) -> t.CInt:
plen: t.CSizeT = string.strlen(prefix)
if string.strncmp(s, prefix, plen) == 0:
return 1
return 0
def _build_path(out: str, out_size: t.CInt, rel: str):
if c.Deref(rel) == 47:
string.strncpy(out, rel, out_size - 1)
else:
i: t.CInt = 0
for i in range(63):
ch: t.CChar = _cwd[i]
c.DerefAs(out + i, ch)
if ch == 0: break
cwd_len: t.CInt = i
if cwd_len > 0 and _cwd[cwd_len - 1] != 47:
c.DerefAs(out + cwd_len, t.CChar(47))
cwd_len += 1
j: t.CInt = 0
for j in range(out_size - 1 - cwd_len):
ch2: t.CChar = c.Deref(rel + j)
c.DerefAs(out + cwd_len + j, ch2)
if ch2 == 0: break
c.DerefAs(out + out_size - 1, t.CChar(0))
def _print_dir_entry(name: str, is_dir: t.CInt):
buf: t.CArray[t.CChar, 80]
j: t.CInt = 0
for j in range(78):
ch: t.CChar = c.Deref(name + j)
buf[j] = ch
if ch == 0: break
if is_dir and j < 78:
buf[j] = 47
j += 1
buf[j] = 0
term.insert_ptr(c.Addr(buf[0]))
def _cmd_cd(path: str):
if path is None or c.Deref(path) == 0:
_cwd[0] = 47
for i in range(1, 64):
_cwd[i] = 0
return
full: t.CArray[t.CChar, 256]
_build_path(c.Addr(full[0]), 256, path)
dd: t.CInt = fs.opendir(c.Addr(full[0]))
if dd < 0:
term.insert("Error: dir not found")
return
fs.closedir(dd)
string.strncpy(c.Addr(_cwd[0]), c.Addr(full[0]), 63)
_cwd[63] = 0
def _cmd_ls():
dd: t.CInt = fs.opendir(c.Addr(_cwd[0]))
if dd < 0:
term.insert("Error: cannot open dir")
return
info: t.CArray[t.CChar, 320]
string.memset(c.Addr(info[0]), 0, 320)
while True:
result: t.CInt = fs.readdir(dd, c.Addr(info[0]))
if result != 0: break
attr_val: t.CUInt8T = t.CUInt8T(c.Deref(c.Addr(info[4])))
name_off: t.CInt = 16
name_ptr: str = c.Addr(info[name_off])
if c.Deref(name_ptr) == 0: break
if c.Deref(name_ptr) == 46:
if c.Deref(name_ptr + 1) == 0:
string.memset(c.Addr(info[0]), 0, 320)
continue
if c.Deref(name_ptr + 1) == 46 and c.Deref(name_ptr + 2) == 0:
string.memset(c.Addr(info[0]), 0, 320)
continue
if (attr_val & 0x10) != 0:
_print_dir_entry(name_ptr, 1)
else:
_print_dir_entry(name_ptr, 0)
string.memset(c.Addr(info[0]), 0, 320)
fs.closedir(dd)
def _cmd_cat(path: str):
full: t.CArray[t.CChar, 256]
_build_path(c.Addr(full[0]), 256, path)
fd: t.CInt = fs.open(c.Addr(full[0]), fs.O_RDONLY)
if fd < 0:
term.insert("Error: file not found")
return
buf: t.CArray[t.CChar, 80]
while True:
string.memset(c.Addr(buf[0]), 0, 80)
n: t.CInt = fs.read(fd, c.Addr(buf[0]), 78)
if n <= 0: break
if n > 78: n = 78
buf[n] = 0
term.insert_ptr(c.Addr(buf[0]))
fs.close(fd)
def _cmd_mkdir(path: str):
full: t.CArray[t.CChar, 256]
_build_path(c.Addr(full[0]), 256, path)
result: t.CInt = fs.mkdir(c.Addr(full[0]))
if result < 0:
term.insert("Error: mkdir failed")
else:
term.insert("Directory created")
def _cmd_rm(path: str):
full: t.CArray[t.CChar, 256]
_build_path(c.Addr(full[0]), 256, path)
result: t.CInt = fs.remove(c.Addr(full[0]))
if result < 0:
term.insert("Error: remove failed")
else:
term.insert("Removed")
def _cmd_touch(path: str):
full: t.CArray[t.CChar, 256]
_build_path(c.Addr(full[0]), 256, path)
fd: t.CInt = fs.open(c.Addr(full[0]), fs.O_WRONLY | fs.O_CREAT)
if fd < 0:
term.insert("Error: touch failed")
return
fs.close(fd)
term.insert("File created")
def _cmd_sysinfo():
term.insert("ViperOS v1.0 (x86_64)")
term.insert("Framebuffer: 32bpp")
term.insert("Compiler: TransPyC")
def _cmd_hexdump(path: str):
full: t.CArray[t.CChar, 256]
_build_path(c.Addr(full[0]), 256, path)
fd: t.CInt = fs.open(c.Addr(full[0]), fs.O_RDONLY)
if fd < 0:
term.insert("Error: file not found")
return
offset: t.CInt = 0
buf: t.CArray[t.CChar, 16]
while True:
string.memset(c.Addr(buf[0]), 0, 16)
n: t.CInt = fs.read(fd, c.Addr(buf[0]), 16)
if n <= 0: break
if n > 16: n = 16
line: t.CArray[t.CChar, 80]
string.memset(c.Addr(line[0]), 0, 80)
viperlib.snprintf(c.Addr(line[0]), 80, "%08x: ", offset)
pos: t.CInt = 10
j: t.CInt = 0
for j in range(16):
if j < n:
ub: t.CUInt32T = t.CUInt32T(buf[j]) & 0xFF
hi: t.CInt = t.CInt(ub >> 4)
lo: t.CInt = t.CInt(ub & 0xF)
if hi < 10:
line[pos] = t.CChar(48 + hi)
else:
line[pos] = t.CChar(65 + hi - 10)
pos += 1
if lo < 10:
line[pos] = t.CChar(48 + lo)
else:
line[pos] = t.CChar(65 + lo - 10)
pos += 1
else:
line[pos] = 32
pos += 1
line[pos] = 32
pos += 1
line[pos] = 32
pos += 1
if j == 7:
line[pos] = 32
pos += 1
line[pos] = 124
pos += 1
for j in range(n):
b2: t.CUInt32T = t.CUInt32T(buf[j]) & 0xFF
if b2 >= 32 and b2 < 127:
line[pos] = t.CChar(b2)
else:
line[pos] = 46
pos += 1
line[pos] = 0
term.insert_ptr(c.Addr(line[0]))
offset += n
fs.close(fd)
def _cmd_run(path: str, blocking: t.CInt):
full: t.CArray[t.CChar, 256]
_build_path(c.Addr(full[0]), 256, path)
pid: t.CInt = process.spawn(c.Addr(full[0]), blocking)
if pid < 0:
term.insert("Error: cannot spawn")
elif blocking:
term.insert("Process exited")
else:
msg: t.CArray[t.CChar, 32]
viperlib.snprintf(c.Addr(msg[0]), 32, "Spawned pid=%d", pid)
term.insert_ptr(c.Addr(msg[0]))
def _on_command() -> t.CInt:
_sdbg("[cmd] enter\n")
text: str = term.get()
_sdbg("[cmd] text=")
_sdbg(text)
_sdbg("\n")
if _startswith(text, "echo "):
term.insert_ptr(text + 5)
elif string.samestr(text, "echo"):
pass
elif string.samestr(text, "clear"):
term.delete(0, -1)
elif string.samestr(text, "help"):
term.insert("File: ls cd cat pwd mkdir rm touch")
term.insert("Sys: ver about sysinfo reboot")
term.insert("Util: echo clear help hexdump run runb")
elif string.samestr(text, "ver"):
term.insert("ViperOS Terminal v1.1")
elif string.samestr(text, "about"):
term.insert("ViperOS - A tiny OS in Viper lang")
elif string.samestr(text, "pwd"):
term.insert_ptr(c.Addr(_cwd[0]))
elif string.samestr(text, "ls"):
_cmd_ls()
elif string.samestr(text, "cd"):
_cmd_cd("")
elif _startswith(text, "cd "):
_cmd_cd(text + 3)
elif _startswith(text, "cat "):
_cmd_cat(text + 4)
elif _startswith(text, "mkdir "):
_cmd_mkdir(text + 6)
elif _startswith(text, "rm "):
_cmd_rm(text + 3)
elif _startswith(text, "touch "):
_cmd_touch(text + 6)
elif string.samestr(text, "sysinfo"):
_cmd_sysinfo()
elif string.samestr(text, "reboot"):
process.exit(0)
elif _startswith(text, "hexdump "):
_cmd_hexdump(text + 8)
elif _startswith(text, "run "):
_cmd_run(text + 4, 0)
elif _startswith(text, "runb "):
_cmd_run(text + 5, 1)
else:
if text is not None and c.Deref(text) != 0:
term.insert("Unknown command. Type 'help'.")
return 0
term.on_command = c.Addr(_on_command)
root.mainloop()
process.exit(0)
return 0

View File

@@ -0,0 +1,31 @@
{
"name": "Terminal",
"version": "1.0.0",
"source_dir": "./",
"temp_dir": "./temp",
"output_dir": "./output",
"compiler": {
"cmd": "llc",
"flags": ["-filetype=obj", "-mtriple=x86_64-none-elf", "-relocation-model=static", "-O2"]
},
"linker": {
"cmd": "ld.lld.exe",
"flags": [
"-m", "elf_x86_64",
"-T", "linker.ld",
"--oformat", "elf64-x86-64",
"--strip-all"
],
"output": "terminal.elf"
},
"includes": ["../.."],
"target": {
"triple": "x86_64-none-elf",
"datalayout": "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
},
"options": {
"slice_level": 3,
"target": "llvm",
"strict_mode": true
}
}