Compare commits
14
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1ae867d929 | ||
|
|
40a1c05728 | ||
|
|
2bfbb44cfb | ||
|
|
8ab2d0d04f | ||
|
|
b51881ced7 | ||
|
|
0d6f1e006c | ||
|
|
6902a406b0 | ||
|
|
36ec7bfdb6 | ||
|
|
6c3c0e63d5 | ||
|
|
df71c59aea | ||
|
|
97244a2b95 | ||
|
|
ecca496978 | ||
|
|
e52b4a9763 | ||
|
|
f78eaa3811 |
No files matched your search
+2
-1
@@ -16,4 +16,5 @@ dockerout.txt
|
|||||||
AGENTS.md
|
AGENTS.md
|
||||||
lessons_learnt.md
|
lessons_learnt.md
|
||||||
*.log
|
*.log
|
||||||
/doc/*.md
|
/doc/*.md
|
||||||
|
wasuro
|
||||||
@@ -24,6 +24,7 @@ declare -a run_steps=(
|
|||||||
"compile_stub.sh" "Failed to compile stub!"
|
"compile_stub.sh" "Failed to compile stub!"
|
||||||
"compile_vergen.sh" "Versions failed to compile"
|
"compile_vergen.sh" "Versions failed to compile"
|
||||||
"compile_lvgl.sh" "Failed to compile LVGL!"
|
"compile_lvgl.sh" "Failed to compile LVGL!"
|
||||||
|
"compile_wasuro.sh" "Failed to pull Wasuro!"
|
||||||
"compile_sources.sh" "Failed to compile FPC Sources!"
|
"compile_sources.sh" "Failed to compile FPC Sources!"
|
||||||
"compile_link.sh" "Failed linking!"
|
"compile_link.sh" "Failed linking!"
|
||||||
"compile_isogen.sh" "Failed to create ISO!"
|
"compile_isogen.sh" "Failed to create ISO!"
|
||||||
|
|||||||
+1
-1
@@ -10,4 +10,4 @@ for dir in $(find src wasuro -type d 2>/dev/null); do
|
|||||||
FU_PATHS="$FU_PATHS -Fu$dir"
|
FU_PATHS="$FU_PATHS -Fu$dir"
|
||||||
done
|
done
|
||||||
|
|
||||||
fpc -Aelf -gw -g -gl -n -v0ew -O3 -OpPENTIUM3 -Si -Sc -Sg -Xd -CX -XXs -CfSSE -CfSSE2 -Rintel -Pi386 -Tlinux -FElib/ $FU_PATHS src/kernel.pas
|
fpc -Aelf -gw -g -gl -n -v0e -O3 -OpPENTIUM3 -Si -Sc -Sg -Xd -CX -XXs -CfSSE -CfSSE2 -Rintel -Pi386 -Tlinux -FElib/ $FU_PATHS src/kernel.pas
|
||||||
+2
-1
@@ -4,4 +4,5 @@ echo "======================="
|
|||||||
echo " "
|
echo " "
|
||||||
echo "Compiling Stub..."
|
echo "Compiling Stub..."
|
||||||
echo " "
|
echo " "
|
||||||
nasm -f elf src/stub/stub.asm -o lib/stub.o
|
nasm -f elf src/stub/stub.asm -o lib/stub.o
|
||||||
|
nasm -f elf src/stub/splash_tga.asm -o lib/splash_tga.o
|
||||||
@@ -0,0 +1,43 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
# compile_wasuro.sh — Pull Wasuro WASM runtime source into wasuro/
|
||||||
|
# Clones the repo (sparse, src/wasm only) and copies the Pascal sources
|
||||||
|
# into $PWD/wasuro so the FPC build can reference them via -Fu.
|
||||||
|
set -e
|
||||||
|
|
||||||
|
WASURO_REPO="https://gitea.spexeah.com/Spexeah/Wasuro.git"
|
||||||
|
WASURO_BRANCH="develop"
|
||||||
|
WASURO_TMP="/tmp/wasuro"
|
||||||
|
WASURO_OUT="$(pwd)/wasuro"
|
||||||
|
|
||||||
|
echo " "
|
||||||
|
echo "======================="
|
||||||
|
echo " "
|
||||||
|
echo "Pulling Wasuro WASM runtime..."
|
||||||
|
echo " "
|
||||||
|
|
||||||
|
# Skip if wasuro/ already has .pas files (cached from previous build)
|
||||||
|
if [ -n "$(find "${WASURO_OUT}" -name '*.pas' 2>/dev/null | head -1)" ]; then
|
||||||
|
echo "Wasuro sources already present in ${WASURO_OUT}, skipping pull."
|
||||||
|
echo " "
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Clone sparse checkout (only src/wasm)
|
||||||
|
rm -rf "$WASURO_TMP"
|
||||||
|
git clone --depth 1 --branch "${WASURO_BRANCH}" --filter=blob:none --sparse \
|
||||||
|
"${WASURO_REPO}" "${WASURO_TMP}" 2>&1
|
||||||
|
cd "$WASURO_TMP"
|
||||||
|
git sparse-checkout set src/wasm 2>&1
|
||||||
|
cd -
|
||||||
|
|
||||||
|
echo "Copying src/wasm to ${WASURO_OUT}..."
|
||||||
|
rm -rf "$WASURO_OUT"
|
||||||
|
mkdir -p "$WASURO_OUT"
|
||||||
|
cp -a "${WASURO_TMP}/src/wasm/"* "$WASURO_OUT"/
|
||||||
|
rm -rf "$WASURO_TMP"
|
||||||
|
|
||||||
|
TOTAL=$(find "$WASURO_OUT" -name '*.pas' | wc -l)
|
||||||
|
echo "Copied ${TOTAL} Pascal source files."
|
||||||
|
echo " "
|
||||||
|
echo "Wasuro pull complete."
|
||||||
|
echo " "
|
||||||
Binary file not shown.
|
After Width: | Height: | Size: 1.0 MiB |
@@ -29,11 +29,14 @@ unit contextswitcher;
|
|||||||
interface
|
interface
|
||||||
|
|
||||||
uses
|
uses
|
||||||
idt, isrmanager, processmanager, proctypes, util, tracer;
|
idt, isrmanager, processmanager, proctypes, util, syslog, tracer;
|
||||||
|
|
||||||
{ Initialise: overwrite IDT gate 32 with our custom ISR. }
|
{ Initialise: overwrite IDT gate 32 with our custom ISR. }
|
||||||
procedure init;
|
procedure init;
|
||||||
|
|
||||||
|
{ No idle ESP variable needed — idle is now a formal process (PID 0)
|
||||||
|
with its SavedESP managed like any other process. }
|
||||||
|
|
||||||
implementation
|
implementation
|
||||||
|
|
||||||
{ -----------------------------------------------------------------------
|
{ -----------------------------------------------------------------------
|
||||||
|
|||||||
File diff suppressed because it is too large.
Load diff
+64
-10
@@ -1157,6 +1157,13 @@ var
|
|||||||
pvVol : PStorage_Volume;
|
pvVol : PStorage_Volume;
|
||||||
pvStatus : puint32;
|
pvStatus : puint32;
|
||||||
pvDirList: PLinkedListBase;
|
pvDirList: PLinkedListBase;
|
||||||
|
pvSplitRel : PLinkedListBase;
|
||||||
|
pvSegCount : uint32;
|
||||||
|
pvIdx : uint32;
|
||||||
|
pvLeafName : pchar;
|
||||||
|
pvParentDir : pchar;
|
||||||
|
pvTmpConcat : pchar;
|
||||||
|
pvEntry : PDirectory_Entry;
|
||||||
|
|
||||||
begin
|
begin
|
||||||
tracer.push_trace('vfs.PathValid.enter');
|
tracer.push_trace('vfs.PathValid.enter');
|
||||||
@@ -1175,22 +1182,69 @@ begin
|
|||||||
RelPath[0] := '/';
|
RelPath[0] := '/';
|
||||||
end;
|
end;
|
||||||
pvVol := PStorage_Volume(Obj^.Reference);
|
pvVol := PStorage_Volume(Obj^.Reference);
|
||||||
{ Actually verify the path exists on the volume }
|
{ Verify the path exists on the volume }
|
||||||
if (pvVol^.filesystem <> nil) and (pvVol^.filesystem^.readDirCallback <> nil) then begin
|
if (pvVol^.filesystem <> nil) and (pvVol^.filesystem^.readDirCallback <> nil) then begin
|
||||||
{ If RelPath is just '/' we're at volume root — always valid }
|
{ If RelPath is just '/' we're at volume root — always valid }
|
||||||
if StringEquals(RelPath, '/') then begin
|
if StringEquals(RelPath, '/') then begin
|
||||||
PathValid := pvDirectory;
|
PathValid := pvDirectory;
|
||||||
end else begin
|
end else begin
|
||||||
{ Ask the filesystem if this directory actually exists }
|
{ Split RelPath into parent directory and leaf name,
|
||||||
pvStatus := puint32(kalloc(4));
|
then list the parent and look for the leaf entry. }
|
||||||
pvStatus^ := 0;
|
pvSplitRel := STRLL_FromString(RelPath, '/');
|
||||||
pvDirList := pvVol^.filesystem^.readDirCallback(pvVol, RelPath, pvStatus);
|
pvSegCount := STRLL_Size(pvSplitRel);
|
||||||
if pvStatus^ = 0 then
|
if pvSegCount = 0 then begin
|
||||||
PathValid := pvDirectory
|
|
||||||
else
|
|
||||||
PathValid := pvInvalid;
|
PathValid := pvInvalid;
|
||||||
if pvDirList <> nil then LL_Free(pvDirList);
|
end else begin
|
||||||
kfree(puint32(pvStatus));
|
pvLeafName := STRLL_Get(pvSplitRel, pvSegCount - 1);
|
||||||
|
{ Build parent directory path from all segments except the last }
|
||||||
|
if pvSegCount <= 1 then begin
|
||||||
|
pvParentDir := stringNew(1);
|
||||||
|
pvParentDir[0] := '/';
|
||||||
|
end else begin
|
||||||
|
pvParentDir := stringNew(0);
|
||||||
|
for pvIdx := 0 to pvSegCount - 2 do begin
|
||||||
|
if stringSize(pvParentDir) > 0 then begin
|
||||||
|
pvTmpConcat := stringConcat(pvParentDir, '/');
|
||||||
|
kfree(void(pvParentDir));
|
||||||
|
pvParentDir := pvTmpConcat;
|
||||||
|
end;
|
||||||
|
pvTmpConcat := stringConcat(pvParentDir, STRLL_Get(pvSplitRel, pvIdx));
|
||||||
|
kfree(void(pvParentDir));
|
||||||
|
pvParentDir := pvTmpConcat;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
{ List parent directory }
|
||||||
|
pvStatus := puint32(kalloc(4));
|
||||||
|
pvStatus^ := 0;
|
||||||
|
pvDirList := pvVol^.filesystem^.readDirCallback(pvVol, pvParentDir, pvStatus);
|
||||||
|
PathValid := pvInvalid;
|
||||||
|
if (pvDirList <> nil) and (pvStatus^ = 0) and (LL_Size(pvDirList) > 0) then begin
|
||||||
|
for pvIdx := 0 to LL_Size(pvDirList) - 1 do begin
|
||||||
|
pvEntry := PDirectory_Entry(LL_Get(pvDirList, pvIdx));
|
||||||
|
if (pvEntry <> nil) and (pvEntry^.fileName <> nil) then begin
|
||||||
|
if stringEquals(pvEntry^.fileName, pvLeafName) then begin
|
||||||
|
case pvEntry^.entryType of
|
||||||
|
fileEntry: PathValid := pvFile;
|
||||||
|
directoryEntry: PathValid := pvDirectory;
|
||||||
|
mountEntry: PathValid := pvDirectory;
|
||||||
|
end;
|
||||||
|
break;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
{ Free entry file names and list }
|
||||||
|
for pvIdx := 0 to LL_Size(pvDirList) - 1 do begin
|
||||||
|
pvEntry := PDirectory_Entry(LL_Get(pvDirList, pvIdx));
|
||||||
|
if (pvEntry <> nil) and (pvEntry^.fileName <> nil) then
|
||||||
|
kfree(void(pvEntry^.fileName));
|
||||||
|
end;
|
||||||
|
LL_Free(pvDirList);
|
||||||
|
end else if pvDirList <> nil then
|
||||||
|
LL_Free(pvDirList);
|
||||||
|
kfree(puint32(pvStatus));
|
||||||
|
kfree(void(pvParentDir));
|
||||||
|
end;
|
||||||
|
STRLL_Free(pvSplitRel);
|
||||||
end;
|
end;
|
||||||
end else
|
end else
|
||||||
PathValid := pvInvalid;
|
PathValid := pvInvalid;
|
||||||
|
|||||||
File diff suppressed because it is too large.
Load diff
File diff suppressed because it is too large.
Load diff
File diff suppressed because it is too large.
Load diff
@@ -13,7 +13,7 @@ interface
|
|||||||
|
|
||||||
uses
|
uses
|
||||||
video, videotypes, color, serial, tracer, lmemorymanager,
|
video, videotypes, color, serial, tracer, lmemorymanager,
|
||||||
mouse, keyboard, TMR_0_ISR, util;
|
mouse, keyboard, TMR_0_ISR, util, syslog, gpu;
|
||||||
|
|
||||||
{ ============================================================
|
{ ============================================================
|
||||||
Opaque LVGL pointer types (internal C structs)
|
Opaque LVGL pointer types (internal C structs)
|
||||||
@@ -1670,6 +1670,7 @@ function lvgl_get_display: Plv_display;
|
|||||||
procedure lvgl_set_mouse_cursor(cursor: Plv_obj);
|
procedure lvgl_set_mouse_cursor(cursor: Plv_obj);
|
||||||
function lvgl_get_ticks: uint32;
|
function lvgl_get_ticks: uint32;
|
||||||
function lvgl_get_kb_group: Plv_group;
|
function lvgl_get_kb_group: Plv_group;
|
||||||
|
procedure lvgl_update_resolution(screen_w, screen_h: uint32);
|
||||||
|
|
||||||
{ Color helper (Pascal wrapper for inline C function) }
|
{ Color helper (Pascal wrapper for inline C function) }
|
||||||
function lv_color_make(r, g, b: uint8): lv_color_t;
|
function lv_color_make(r, g, b: uint8): lv_color_t;
|
||||||
@@ -1909,6 +1910,14 @@ begin
|
|||||||
tick_accumulator := tick_accumulator + 1;
|
tick_accumulator := tick_accumulator + 1;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
{ ============================================================
|
||||||
|
GPU mode-change callback — updates LVGL display resolution
|
||||||
|
============================================================ }
|
||||||
|
procedure lvglModeChanged(const info : TGPUModeInfo);
|
||||||
|
begin
|
||||||
|
lvgl_update_resolution(info.Width, info.Height);
|
||||||
|
end;
|
||||||
|
|
||||||
{ ============================================================
|
{ ============================================================
|
||||||
High-level init
|
High-level init
|
||||||
============================================================ }
|
============================================================ }
|
||||||
@@ -1962,9 +1971,45 @@ begin
|
|||||||
{ Hook 1024Hz timer for accurate LVGL tick }
|
{ Hook 1024Hz timer for accurate LVGL tick }
|
||||||
TMR_0_ISR.hook(uint32(@lvgl_timer_tick));
|
TMR_0_ISR.hook(uint32(@lvgl_timer_tick));
|
||||||
|
|
||||||
|
{ Register for GPU mode-change notifications so LVGL resolution updates automatically }
|
||||||
|
gpu.registerModeChangeCallback(@lvglModeChanged);
|
||||||
|
|
||||||
tracer.push_trace('lvgl.init.exit');
|
tracer.push_trace('lvgl.init.exit');
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
procedure lvgl_update_resolution(screen_w, screen_h: uint32);
|
||||||
|
var
|
||||||
|
new_buf : pointer;
|
||||||
|
new_size : uint32;
|
||||||
|
|
||||||
|
begin
|
||||||
|
tracer.push_trace('lvgl.update_resolution.enter');
|
||||||
|
|
||||||
|
{ Allocate new render buffer for the new width }
|
||||||
|
new_size := screen_w * LV_BUF_LINES * SizeOf(lv_color_t);
|
||||||
|
new_buf := pointer(kalloc(new_size));
|
||||||
|
|
||||||
|
if new_buf <> nil then begin
|
||||||
|
{ Free old render buffer }
|
||||||
|
if lv_buf1 <> nil then
|
||||||
|
kfree(lv_buf1);
|
||||||
|
|
||||||
|
lv_buf1 := new_buf;
|
||||||
|
lv_buf1_size := new_size;
|
||||||
|
|
||||||
|
{ Update LVGL display resolution and buffers }
|
||||||
|
lv_display_set_resolution(disp, sint32(screen_w), sint32(screen_h));
|
||||||
|
lv_display_set_buffers(disp, lv_buf1, nil,
|
||||||
|
lv_buf1_size, LV_DISPLAY_RENDER_MODE_PARTIAL);
|
||||||
|
|
||||||
|
syslog.logln('LVGL', 'Resolution updated successfully.');
|
||||||
|
end else begin
|
||||||
|
syslog.logln('LVGL', 'Failed to allocate new render buffer.');
|
||||||
|
end;
|
||||||
|
|
||||||
|
tracer.push_trace('lvgl.update_resolution.exit');
|
||||||
|
end;
|
||||||
|
|
||||||
function lvgl_handler: uint32;
|
function lvgl_handler: uint32;
|
||||||
var
|
var
|
||||||
elapsed: uint32;
|
elapsed: uint32;
|
||||||
|
|||||||
+162
-2
File diff suppressed because it is too large.
Load diff
@@ -22,7 +22,7 @@ unit video;
|
|||||||
interface
|
interface
|
||||||
|
|
||||||
uses
|
uses
|
||||||
lmemorymanager, tracer, color, videotypes, hashmap, util, texture;
|
lmemorymanager, tracer, color, videotypes, hashmap, util, texture, gpu;
|
||||||
|
|
||||||
procedure init();
|
procedure init();
|
||||||
procedure DrawPixel(X : uint32; Y : uint32; Pixel : TRGB32);
|
procedure DrawPixel(X : uint32; Y : uint32; Pixel : TRGB32);
|
||||||
@@ -30,6 +30,7 @@ procedure DrawLine(x1,y1,x2,y2 : uint32; thickness : uint32; Color : TRGB32);
|
|||||||
procedure DrawRect(x1,y1,x2,y2 : uint32; line_thickness : uint32; Color : TRGB32);
|
procedure DrawRect(x1,y1,x2,y2 : uint32; line_thickness : uint32; Color : TRGB32);
|
||||||
procedure FillRect(x1,y1,x2,y2 : uint32; line_thickness : uint32; Line_Color : TRGB32; Fill_Color : TRGB32);
|
procedure FillRect(x1,y1,x2,y2 : uint32; line_thickness : uint32; Line_Color : TRGB32; Fill_Color : TRGB32);
|
||||||
procedure Flush();
|
procedure Flush();
|
||||||
|
procedure reinit(fb_addr, width, height, pitch : uint32; bpp : uint8);
|
||||||
|
|
||||||
function register(DriverIdentifier : pchar; EnableCallback : FEnableDriver) : boolean;
|
function register(DriverIdentifier : pchar; EnableCallback : FEnableDriver) : boolean;
|
||||||
function enable(DriverIdentifier : pchar) : boolean;
|
function enable(DriverIdentifier : pchar) : boolean;
|
||||||
@@ -47,6 +48,9 @@ Procedure basicFDrawTexture(Buffer : PVideoBuffer; X : uint32; Y : uint32; Textu
|
|||||||
|
|
||||||
implementation
|
implementation
|
||||||
|
|
||||||
|
uses
|
||||||
|
VESA8, VESA16, VESA24, VESA32;
|
||||||
|
|
||||||
Procedure dummyFDrawPixel(Buffer : PVideoBuffer; X : uint32; Y : uint32; Pixel : TRGB32);
|
Procedure dummyFDrawPixel(Buffer : PVideoBuffer; X : uint32; Y : uint32; Pixel : TRGB32);
|
||||||
begin
|
begin
|
||||||
tracer.push_trace('video.dummyFDrawPixel.enter');
|
tracer.push_trace('video.dummyFDrawPixel.enter');
|
||||||
@@ -191,6 +195,14 @@ var
|
|||||||
VideoInterface : TVideoInterface;
|
VideoInterface : TVideoInterface;
|
||||||
DriverMap : PHashMap;
|
DriverMap : PHashMap;
|
||||||
|
|
||||||
|
{ ============================================================
|
||||||
|
GPU mode-change callback — reinits front/back buffers
|
||||||
|
============================================================ }
|
||||||
|
procedure videoModeChanged(const info : TGPUModeInfo);
|
||||||
|
begin
|
||||||
|
reinit(info.Framebuffer, info.Width, info.Height, info.Pitch, info.BPP);
|
||||||
|
end;
|
||||||
|
|
||||||
procedure init();
|
procedure init();
|
||||||
var
|
var
|
||||||
RGB : TRGB32;
|
RGB : TRGB32;
|
||||||
@@ -226,6 +238,9 @@ begin
|
|||||||
//Initialize our 'DriverMap', a hashmap of loadable display drivers.
|
//Initialize our 'DriverMap', a hashmap of loadable display drivers.
|
||||||
DriverMap:= hashmap.new;
|
DriverMap:= hashmap.new;
|
||||||
|
|
||||||
|
{ Register for GPU mode-change notifications so reinit fires automatically }
|
||||||
|
gpu.registerModeChangeCallback(@videoModeChanged);
|
||||||
|
|
||||||
tracer.push_trace('video.init.exit');
|
tracer.push_trace('video.init.exit');
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@@ -327,4 +342,47 @@ begin
|
|||||||
frontBufferLocation:= VideoInterface.FrontBuffer.Location;
|
frontBufferLocation:= VideoInterface.FrontBuffer.Location;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
procedure reinit(fb_addr, width, height, pitch : uint32; bpp : uint8);
|
||||||
|
begin
|
||||||
|
tracer.push_trace('video.reinit.enter');
|
||||||
|
{ Free old back buffer if allocated }
|
||||||
|
if VideoInterface.BackBuffer.Initialized then begin
|
||||||
|
kfree(void(VideoInterface.BackBuffer.Location));
|
||||||
|
VideoInterface.BackBuffer.Initialized := false;
|
||||||
|
VideoInterface.BackBuffer.Location := 0;
|
||||||
|
VideoInterface.BackBuffer.Width := 0;
|
||||||
|
VideoInterface.BackBuffer.Height := 0;
|
||||||
|
end;
|
||||||
|
|
||||||
|
{ Reset front buffer so it can be re-initialized }
|
||||||
|
VideoInterface.FrontBuffer.Initialized := false;
|
||||||
|
VideoInterface.FrontBuffer.Location := 0;
|
||||||
|
VideoInterface.FrontBuffer.Width := 0;
|
||||||
|
VideoInterface.FrontBuffer.Height := 0;
|
||||||
|
|
||||||
|
{ Point default buffer back to front (in case doublebuffer re-enable fails) }
|
||||||
|
VideoInterface.DefaultBuffer := @VideoInterface.FrontBuffer;
|
||||||
|
|
||||||
|
{ Set front buffer directly from GPU mode info }
|
||||||
|
VideoInterface.FrontBuffer.Location := fb_addr;
|
||||||
|
VideoInterface.FrontBuffer.Width := width;
|
||||||
|
VideoInterface.FrontBuffer.Height := height;
|
||||||
|
VideoInterface.FrontBuffer.BitsPerPixel := bpp;
|
||||||
|
if fb_addr <> 0 then
|
||||||
|
VideoInterface.FrontBuffer.Initialized := true;
|
||||||
|
|
||||||
|
{ Set up BPP-specific draw routines }
|
||||||
|
case bpp of
|
||||||
|
08: VESA8.init(@VideoInterface.DrawRoutines);
|
||||||
|
16: VESA16.init(@VideoInterface.DrawRoutines);
|
||||||
|
24: VESA24.init(@VideoInterface.DrawRoutines);
|
||||||
|
32: VESA32.init(@VideoInterface.DrawRoutines);
|
||||||
|
end;
|
||||||
|
|
||||||
|
{ Re-enable double buffer (allocates new back buffer matching front) }
|
||||||
|
enable('BASIC_DOUBLE_BUFFER');
|
||||||
|
|
||||||
|
tracer.push_trace('video.reinit.exit');
|
||||||
|
end;
|
||||||
|
|
||||||
end.
|
end.
|
||||||
File diff suppressed because it is too large.
Load diff
+203
-18
File diff suppressed because it is too large.
Load diff
+31
-21
@@ -12,7 +12,7 @@ type
|
|||||||
PTARGAColor = ^TTARGAColor;
|
PTARGAColor = ^TTARGAColor;
|
||||||
|
|
||||||
TTARGAHeader = packed record
|
TTARGAHeader = packed record
|
||||||
Magic: uint8;
|
IDLength: uint8;
|
||||||
ColorMapType: uint8;
|
ColorMapType: uint8;
|
||||||
ImageType: uint8;
|
ImageType: uint8;
|
||||||
ColorMapOrigin: uint16;
|
ColorMapOrigin: uint16;
|
||||||
@@ -24,7 +24,6 @@ type
|
|||||||
Height: uint16;
|
Height: uint16;
|
||||||
PixelDepth: uint8;
|
PixelDepth: uint8;
|
||||||
ImageDescriptor: uint8;
|
ImageDescriptor: uint8;
|
||||||
Data : PTARGAColor;
|
|
||||||
end;
|
end;
|
||||||
PTARGAHeader = ^TTARGAHeader;
|
PTARGAHeader = ^TTARGAHeader;
|
||||||
|
|
||||||
@@ -35,29 +34,40 @@ implementation
|
|||||||
Function Parse(buffer : puint8; len : uint32) : PTexture;
|
Function Parse(buffer : puint8; len : uint32) : PTexture;
|
||||||
var
|
var
|
||||||
header : PTARGAHeader;
|
header : PTARGAHeader;
|
||||||
i, j : uint32;
|
src : PTARGAColor;
|
||||||
data : PTARGAColor;
|
tex : PTexture;
|
||||||
tex : PTexture;
|
x, y : uint32;
|
||||||
|
dstRow : uint32;
|
||||||
|
topDown: boolean;
|
||||||
|
|
||||||
begin
|
begin
|
||||||
if (len < sizeof(TTARGAHeader)) then exit;
|
Parse := nil;
|
||||||
|
if len < sizeof(TTARGAHeader) then exit;
|
||||||
|
|
||||||
header := PTARGAHeader(buffer);
|
header := PTARGAHeader(buffer);
|
||||||
if (header^.Magic <> $0) or (header^.ImageType <> 2) or (header^.PixelDepth <> 32) then exit;
|
if (header^.ImageType <> 2) or (header^.PixelDepth <> 32) then exit;
|
||||||
|
|
||||||
//Create a new texture
|
{ Pixel data starts after the 18-byte header + any ID field. }
|
||||||
tex:= texture.newTexture(header^.Width, header^.Height);
|
src := PTARGAColor(buffer + sizeof(TTARGAHeader) + header^.IDLength);
|
||||||
tex^.Width:= header^.Width;
|
|
||||||
tex^.Height:= header^.Height;
|
{ Bit 5 of ImageDescriptor: 1 = top-to-bottom, 0 = bottom-to-top. }
|
||||||
|
topDown := (header^.ImageDescriptor AND $20) <> 0;
|
||||||
//Copy the data
|
|
||||||
data := PTARGAColor(header^.Data);
|
tex := texture.newTexture(header^.Width, header^.Height);
|
||||||
for i := 0 to header^.Height - 1 do begin
|
|
||||||
for j := 0 to header^.Width - 1 do begin
|
for y := 0 to header^.Height - 1 do begin
|
||||||
tex^.Pixels[i * header^.Width + j].r := data^.r;
|
{ Flip vertically when origin is bottom-left (the TGA default). }
|
||||||
tex^.Pixels[i * header^.Width + j].g := data^.g;
|
if topDown then
|
||||||
tex^.Pixels[i * header^.Width + j].b := data^.b;
|
dstRow := y
|
||||||
tex^.Pixels[i * header^.Width + j].a := data^.a;
|
else
|
||||||
|
dstRow := (header^.Height - 1) - y;
|
||||||
|
|
||||||
|
for x := 0 to header^.Width - 1 do begin
|
||||||
|
tex^.Pixels[dstRow * header^.Width + x].b := src^.b;
|
||||||
|
tex^.Pixels[dstRow * header^.Width + x].g := src^.g;
|
||||||
|
tex^.Pixels[dstRow * header^.Width + x].r := src^.r;
|
||||||
|
tex^.Pixels[dstRow * header^.Width + x].a := src^.a;
|
||||||
|
Inc(src);
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|||||||
+74
-44
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,83 @@
|
|||||||
|
{
|
||||||
|
Prog->setres - Set display resolution via GPU driver framework.
|
||||||
|
|
||||||
|
Usage: SETRES <width> <height>
|
||||||
|
Example: SETRES 1024 768
|
||||||
|
|
||||||
|
Uses the GPU driver framework to switch display modes. Tries BGA first,
|
||||||
|
then falls back to VBE/VESA.
|
||||||
|
|
||||||
|
@author(Kieron Morris <[email protected]>)
|
||||||
|
}
|
||||||
|
unit setres;
|
||||||
|
|
||||||
|
interface
|
||||||
|
|
||||||
|
uses
|
||||||
|
stdio, gpu, util, strings, tracer, syslog;
|
||||||
|
|
||||||
|
procedure init();
|
||||||
|
|
||||||
|
implementation
|
||||||
|
|
||||||
|
procedure run(Params : PParamList; stdin_buf, stdout_buf, stderr_buf : POutBuf);
|
||||||
|
var
|
||||||
|
w, h : uint32;
|
||||||
|
wStr, hStr : pchar;
|
||||||
|
info : TGPUModeInfo;
|
||||||
|
|
||||||
|
begin
|
||||||
|
tracer.push_trace('setres.run');
|
||||||
|
|
||||||
|
if paramCount(params) < 2 then begin
|
||||||
|
stdio.bufWriteStrLn(stderr_buf, 'Usage: SETRES <width> <height>');
|
||||||
|
stdio.bufWriteStrLn(stderr_buf, 'Example: SETRES 1024 768');
|
||||||
|
tracer.pop_trace;
|
||||||
|
exit;
|
||||||
|
end;
|
||||||
|
|
||||||
|
wStr := getParam(0, params);
|
||||||
|
hStr := getParam(1, params);
|
||||||
|
|
||||||
|
w := stringToInt(wStr);
|
||||||
|
h := stringToInt(hStr);
|
||||||
|
|
||||||
|
if (w = 0) or (h = 0) then begin
|
||||||
|
stdio.bufWriteStrLn(stderr_buf, 'Error: Invalid resolution values.');
|
||||||
|
tracer.pop_trace;
|
||||||
|
exit;
|
||||||
|
end;
|
||||||
|
|
||||||
|
stdio.bufWriteStr(stdout_buf, 'Setting resolution to ');
|
||||||
|
stdio.bufWriteInt(stdout_buf, w);
|
||||||
|
stdio.bufWriteStr(stdout_buf, 'x');
|
||||||
|
stdio.bufWriteInt(stdout_buf, h);
|
||||||
|
stdio.bufWriteStrLn(stdout_buf, 'x32...');
|
||||||
|
|
||||||
|
{ Step 1: Set display mode via GPU framework (tries BGA first, then VBE) }
|
||||||
|
if not gpu.setMode(w, h, 32, info) then begin
|
||||||
|
stdio.bufWriteStrLn(stderr_buf, 'Error: Mode switch failed. Mode may not be supported.');
|
||||||
|
tracer.pop_trace;
|
||||||
|
exit;
|
||||||
|
end;
|
||||||
|
|
||||||
|
stdio.bufWriteStr(stdout_buf, 'Mode set via ');
|
||||||
|
stdio.bufWriteStrLn(stdout_buf, gpu.activeDriverName());
|
||||||
|
|
||||||
|
stdio.bufWriteStr(stdout_buf, 'Resolution set to ');
|
||||||
|
stdio.bufWriteInt(stdout_buf, w);
|
||||||
|
stdio.bufWriteStr(stdout_buf, 'x');
|
||||||
|
stdio.bufWriteInt(stdout_buf, h);
|
||||||
|
stdio.bufWriteStrLn(stdout_buf, 'x32 successfully.');
|
||||||
|
|
||||||
|
tracer.pop_trace;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure init();
|
||||||
|
begin
|
||||||
|
tracer.push_trace('setres.init');
|
||||||
|
stdio.registerCommand('SETRES', @Run, 'Set display resolution. Usage: SETRES <width> <height>');
|
||||||
|
tracer.pop_trace;
|
||||||
|
end;
|
||||||
|
|
||||||
|
end.
|
||||||
Loaded 20 of 30 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user