Skip to content

Commit

Permalink
FrankenDrift.GlkRunner.AsyncGlk is beginning to work
Browse files Browse the repository at this point in the history
  • Loading branch information
curiousdannii committed Apr 16, 2023
1 parent 8f22374 commit c0c5eea
Show file tree
Hide file tree
Showing 8 changed files with 253 additions and 19 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,15 @@
<OutputType>Exe</OutputType>
<RuntimeIdentifier>browser-wasm</RuntimeIdentifier>
<TargetFramework>net7.0</TargetFramework>
<WasmMainJSPath>main.js</WasmMainJSPath>
<WasmMainJSPath>frankendrift.js</WasmMainJSPath>
</PropertyGroup>

<ItemGroup>
<ProjectReference Include="..\FrankenDrift.GlkRunner\FrankenDrift.GlkRunner.csproj" />
</ItemGroup>

<ItemGroup>
<WasmExtraFilesToDeploy Include="parchment.html" />
</ItemGroup>

</Project>
13 changes: 10 additions & 3 deletions FrankenDrift.GlkRunner/FrankenDrift.GlkRunner.AsyncGlk/Main.cs
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ internal static partial class AsyncGlk_imports
[JSImport("glk_stream_open_file", "main.js")]
internal static partial IntPtr glk_stream_open_file(IntPtr fileref, int fmode, int rock);
[JSImport("glk_stream_open_memory", "main.js")]
internal static partial IntPtr glk_stream_open_memory([JSMarshalAs<JSType.MemoryView>] ArraySegment<Byte> buf, int mode, int rock);
internal static partial IntPtr glk_stream_open_memory([JSMarshalAs<JSType.MemoryView>] Span<Byte> buf, int mode, int rock);
[JSImport("glk_stream_set_position", "main.js")]
internal static partial void glk_stream_set_position(IntPtr stream, int pos, int seekMode);
[JSImport("glk_stylehint_set", "main.js")]
Expand Down Expand Up @@ -146,7 +146,7 @@ public void glk_select(ref Event ev)
public void glk_set_style(Style s) => AsyncGlk_imports.glk_set_style((int) s);
public void glk_set_window(WindowHandle winId) => AsyncGlk_imports.glk_set_window(winId);
public StreamHandle glk_stream_open_file(FileRefHandle fileref, Glk.FileMode fmode, uint rock) => AsyncGlk_imports.glk_stream_open_file(fileref, (int) fmode, (int) rock);
public unsafe StreamHandle glk_stream_open_memory(byte* buf, uint buflen, Glk.FileMode mode, uint rock) => 0;
public unsafe StreamHandle glk_stream_open_memory(byte* buf, uint buflen, Glk.FileMode mode, uint rock) => AsyncGlk_imports.glk_stream_open_memory(new Span<Byte>(buf, (int) buflen), (int) mode, (int) rock);
public void glk_stream_set_position(StreamHandle stream, int pos, SeekMode seekMode) => AsyncGlk_imports.glk_stream_set_position(stream, (int) pos, (int) seekMode);
public void glk_stylehint_set(WinType wintype, Style styl, StyleHint hint, int val) => AsyncGlk_imports.glk_stylehint_set((int) wintype, (int) styl, (int) hint, (int) val);
public uint glk_style_measure(WindowHandle winid, Style styl, StyleHint hint, ref uint result) => 0;
Expand All @@ -168,7 +168,9 @@ public void glk_window_get_size(WindowHandle winId, out uint width, out uint hei
public StreamHandle glk_window_get_stream(WindowHandle winId) => AsyncGlk_imports.glk_window_get_stream(winId);
public void glk_window_move_cursor(WindowHandle winId, uint xpos, uint ypos) => AsyncGlk_imports.glk_window_move_cursor(winId, (int) xpos, (int) ypos);
public WindowHandle glk_window_open(WindowHandle split, WinMethod method, uint size, WinType wintype, uint rock) => AsyncGlk_imports.glk_window_open(split, (int) method, (int) size, (int) wintype, (int) rock);
public void garglk_set_zcolors(uint fg, uint bg) => AsyncGlk_imports.garglk_set_zcolors((int) fg, (int) bg);
// TODO: fix this
//public void garglk_set_zcolors(uint fg, uint bg) => AsyncGlk_imports.garglk_set_zcolors((int) fg, (int) bg);
public void garglk_set_zcolors(uint fg, uint bg) {}
public string? glkunix_fileref_get_name(FileRefHandle fileref) => AsyncGlk_imports.glkunix_fileref_get_name(fileref);

public void SetGameName(string game) {}
Expand All @@ -184,6 +186,11 @@ public static int Main(string[] args)
return 1;
}

AsyncGlk GlkApi = new AsyncGlk();

var sess = new MainSession(args[^1], GlkApi);
sess.Run();

return 0;
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
#!/bin/sh

dotnet build --configuration Debug
170 changes: 170 additions & 0 deletions FrankenDrift.GlkRunner/FrankenDrift.GlkRunner.AsyncGlk/frankendrift.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,170 @@
/*
FrankenDrift.GlkRunner.AsyncGlk runner
======================================
Copyright (c) 2023 Dannii Willis
MIT licenced
https://github.com/awlck/frankendrift
*/

import {dotnet} from './dotnet.js'

export class FrankenDrift {
init(data, options) {
this.data = data
this.options = options
}

async start() {
const Glk = this.options.Glk
let object_id = 1
const ids_to_objects = {}
const objects_to_ids = new Map()
const results = []

function register_object(obj) {
if (!obj) {
return 0
}
const obj_id = object_id++
ids_to_objects[obj_id] = obj
objects_to_ids.set(obj, obj_id)
return obj_id
}
function unregister_object(obj) {
const obj_id = objects_to_ids.get(obj)
delete ids_to_objects[obj_id]
objects_to_ids.delete(obj)
}
function write_event(ev) {
results[0] = ev.get_field(0)
results[1] = objects_to_ids.get(ev.get_field(1)) || 0
results[2] = ev.get_field(2)
results[3] = ev.get_field(3)
}

const header = String.fromCharCode(...this.data.subarray(0, 12))
const filename = 'storyfile.' + (header.startsWith('FORM') && header.endsWith('IFRS') ? 'blorb' : 'taf')

const runtime = await dotnet
.withApplicationArguments(filename)
.withConfig({
assets: [
{
behavior: 'vfs',
buffer: this.data,
name: filename,
},
],
})
.create()

runtime.setModuleImports('main.js', {
get_val: val => results[val],
glk_cancel_hyperlink_event: winId => Glk.glk_cancel_hyperlink_event(ids_to_objects[winId]),
glk_cancel_line_event: winId => {
const res = new Glk.RefStruct()
Glk.glk_cancel_line_event(ids_to_objects[winId], res)
write_event(res)
},
glk_exit: () => Glk.glk_exit(),
glk_fileref_create_by_name: (usage, name, fmode, rock) => register_object(Glk.glk_fileref_create_by_name(usage, name, fmode, rock)),
glk_fileref_create_by_prompt: async (usage, fmode, rock) => {
const fref = await new Promise(resolve => {
this.resume = resolve
Glk.glk_fileref_create_by_prompt(usage, fmode, rock)
Glk.update()
})
return register_object(fref)
},
glk_fileref_create_temp: (usage, rock) => register_object(Glk.glk_fileref_create_temp(usage, rock)),
glk_fileref_destroy: frefID => {
const fref = ids_to_objects[frefID]
unregister_object(fref)
Glk.glk_fileref_destroy(fref)
},
glk_gestalt: (sel, val) => Glk.glk_gestalt(sel, val),
glk_gestalt_ext: (sel, val, arr) => Glk.glk_gestalt(sel, val, arr._unsafe_create_view()),
glk_image_draw: (winId, imgId, val1, val2) => Glk.glk_image_draw(ids_to_objects[winId], imgId, val1, val2),
glk_image_get_info: imgId => {
const width = new Glk.RefBox()
const height = new Glk.RefBox()
Glk.glk_image_get_info(imgId, width, height)
results[0] = width.get_value()
results[1] = height.get_value()
},
glk_put_buffer: val => Glk.glk_put_buffer(val._unsafe_create_view()),
glk_put_buffer_stream: (strId, val) => Glk.glk_put_buffer_stream(ids_to_objects[strId], val._unsafe_create_view()),
glk_put_buffer_uni: val => Glk.glk_put_buffer_uni(val._unsafe_create_view()),
glk_request_char_event: winId => Glk.glk_request_char_event(ids_to_objects[winId]),
glk_request_hyperlink_event: winId => Glk.glk_request_hyperlink_event(ids_to_objects[winId]),
glk_request_line_event: (winId, buf, initlen) => Glk.glk_request_line_event(ids_to_objects[winId], buf._unsafe_create_view(), initlen),
glk_request_line_event_uni: (winId, buf, initlen) => Glk.glk_request_line_event_uni(ids_to_objects[winId], buf._unsafe_create_view(), initlen),
glk_request_timer_events: msecs => Glk.glk_request_timer_events(msecs),
glk_select: async () => {
const res = new Glk.RefStruct()
await new Promise(resolve => {
this.resume = resolve
Glk.glk_select(res)
Glk.update()
})
write_event(res)
},
glk_set_hyperlink: linkval => Glk.glk_set_hyperlink(linkval),
glk_set_style: style => Glk.glk_set_style(style),
glk_set_window: winId => Glk.glk_set_window(ids_to_objects[winId]),
glk_stream_open_file: (frefId, fmode, rock) => {
const fref = ids_to_objects[frefId]
const str = Glk.glk_stream_open_file(fref, fmode, rock)
if (str) {
return register_object(str)
}
return 0
},
glk_stream_open_memory: (buf, mode, rock) => {
const str = Glk.glk_stream_open_memory(buf._unsafe_create_view(), mode, rock)
if (str) {
return register_object(str)
}
return 0
},
glk_stream_set_position: (stream, pos, seekMode) => Glk.glk_stream_set_position(ids_to_objects[stream], pos, seekMode),
glk_stylehint_set: (wintype, styl, hint, val) => Glk.glk_stylehint_set(wintype, styl, hint, val),
glk_tick: () => Glk.glk_tick(),
glk_window_clear: winId => Glk.glk_window_clear(ids_to_objects[winId]),
glk_window_close: winId => {
const win = ids_to_objects[winId]
unregister_object(win)
unregister_object(Glk.glk_window_get_stream(win))
const res = new Glk.RefStruct()
Glk.glk_window_close(win, res)
results[0] = res.get_field(0)
results[1] = res.get_field(1)
},
glk_window_flow_break: winId => Glk.glk_window_flow_break(ids_to_objects[winId]),
glk_window_get_size: winId => {
const width = new Glk.RefBox()
const height = new Glk.RefBox()
Glk.glk_window_get_size(ids_to_objects[winId], width, height)
results[0] = width.get_value()
results[1] = height.get_value()
},
glk_window_get_stream: winId => objects_to_ids.get(Glk.glk_window_get_stream(ids_to_objects[winId])),
glk_window_move_cursor: (winId, xpos, ypos) => Glk.glk_window_move_cursor(ids_to_objects[winId], xpos, ypos),
glk_window_open: (split, method, size, wintype, rock) => {
const win = Glk.glk_window_open(split ? ids_to_objects[split]: null, method, size, wintype, rock)
if (win) {
register_object(Glk.glk_window_get_stream(win))
return register_object(win)
}
return 0
},
garglk_set_zcolors: (fg, bg) => Glk.garglk_set_zcolors(fg, bg),
glkunix_fileref_get_name: fileref => ids_to_objects[fileref].filename,
})

await dotnet.run()
}
}
11 changes: 0 additions & 11 deletions FrankenDrift.GlkRunner/FrankenDrift.GlkRunner.AsyncGlk/main.js

This file was deleted.

Large diffs are not rendered by default.

8 changes: 4 additions & 4 deletions FrankenDrift.GlkRunner/FrankenDrift.GlkRunner/GlkApi.cs
Original file line number Diff line number Diff line change
Expand Up @@ -204,31 +204,31 @@ public struct StreamResult
public record struct WindowHandle(IntPtr hwnd)
{
internal bool IsValid => hwnd != IntPtr.Zero;
public static implicit operator IntPtr(WindowHandle hwnd) => hwnd;
public static implicit operator IntPtr(WindowHandle h) => h.hwnd;
public static implicit operator WindowHandle(IntPtr hwnd) => new WindowHandle(hwnd);
}

[StructLayout(LayoutKind.Sequential)]
public record struct FileRefHandle(IntPtr hfref)
{
internal bool IsValid => hfref != IntPtr.Zero;
public static implicit operator IntPtr(FileRefHandle hfref) => hfref;
public static implicit operator IntPtr(FileRefHandle h) => h.hfref;
public static implicit operator FileRefHandle(IntPtr hfref) => new FileRefHandle(hfref);
}

[StructLayout(LayoutKind.Sequential)]
public record struct StreamHandle(IntPtr hstrm)
{
internal bool IsValid => hstrm != IntPtr.Zero;
public static implicit operator IntPtr(StreamHandle hstrm) => hstrm;
public static implicit operator IntPtr(StreamHandle h) => h.hstrm;
public static implicit operator StreamHandle(IntPtr hstrm) => new StreamHandle(hstrm);
}

[StructLayout(LayoutKind.Sequential)]
public record struct SoundChannel(IntPtr schan)
{
internal bool IsValid => schan != IntPtr.Zero;
public static implicit operator IntPtr(SoundChannel schan) => schan;
public static implicit operator IntPtr(SoundChannel h) => h.schan;
public static implicit operator SoundChannel(IntPtr schan) => new SoundChannel(schan);
}

Expand Down
4 changes: 4 additions & 0 deletions FrankenDrift.GlkRunner/FrankenDrift.GlkRunner/GlkSession.cs
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,10 @@ public void EnableButtons() { }

public void ErrMsg(string message, Exception ex = null)
{
Console.WriteLine("Fatal error: " + message);
if (_output is null) {
_output = new GlkHtmlWin(GlkApi);
}
_output.AppendHTML($"<b>ADRIFT Fatal Error: {message}</b><br>");
}

Expand Down

0 comments on commit c0c5eea

Please sign in to comment.