Skip to content

Instantly share code, notes, and snippets.

@peterhellberg
Created September 9, 2024 08:34
Show Gist options
  • Select an option

  • Save peterhellberg/1b4bd8274bda3bcdfca86263a2f930d5 to your computer and use it in GitHub Desktop.

Select an option

Save peterhellberg/1b4bd8274bda3bcdfca86263a2f930d5 to your computer and use it in GitHub Desktop.
Example of using dos-like from Zig
const std = @import("std");
const c = @cImport({
@cInclude("dos.h");
});
pub const videomode_40x25_8x8: usize = 0;
pub const videomode_40x25_9x16: usize = 1;
pub const videomode_80x25_8x8: usize = 2;
pub const videomode_80x25_8x16: usize = 3;
pub const videomode_80x25_9x16: usize = 4;
pub const videomode_80x43_8x8: usize = 5;
pub const videomode_80x50_8x8: usize = 6;
pub const videomode_320x200: usize = 7;
pub const videomode_320x240: usize = 8;
pub const videomode_320x400: usize = 9;
pub const videomode_640x200: usize = 10;
pub const videomode_640x350: usize = 11;
pub const videomode_640x400: usize = 12;
pub const videomode_640x480: usize = 13;
pub fn setvideomode(mode: usize) void {
c.setvideomode(@intCast(mode));
}
pub fn setdoublebuffer(enabled: bool) void {
c.setdoublebuffer(@intFromBool(enabled));
}
pub fn loadgif(filename: [*c]const u8, width: *i32, height: *i32, palcount: *i32, palette: [*c]u8) [*c]u8 {
return c.loadgif(filename, @ptrCast(width), @ptrCast(height), @ptrCast(palcount), palette);
}
pub fn setpal(index: i32, r: i32, g: i32, b: i32) void {
c.setpal(@intCast(index), @intCast(r), @intCast(g), @intCast(b));
}
pub fn screenbuffer() [*c]u8 {
return c.screenbuffer();
}
pub fn shuttingdown() bool {
return c.shuttingdown() == 1;
}
pub fn waitvbl() void {
c.waitvbl();
}
pub fn swapbuffers() [*c]u8 {
return c.swapbuffers();
}
pub const KEY_INVALID: u32 = 0;
pub const KEY_LBUTTON: u32 = 1;
pub const KEY_RBUTTON: u32 = 2;
pub const KEY_CANCEL: u32 = 3;
pub const KEY_MBUTTON: u32 = 4;
pub const KEY_XBUTTON1: u32 = 5;
pub const KEY_XBUTTON2: u32 = 6;
pub const KEY_BACK: u32 = 7;
pub const KEY_TAB: u32 = 8;
pub const KEY_CLEAR: u32 = 9;
pub const KEY_RETURN: u32 = 10;
pub const KEY_SHIFT: u32 = 11;
pub const KEY_CONTROL: u32 = 12;
pub const KEY_MENU: u32 = 13;
pub const KEY_PAUSE: u32 = 14;
pub const KEY_CAPITAL: u32 = 15;
pub const KEY_KANA: u32 = 16;
pub const KEY_HANGUL: u32 = 16;
pub const KEY_JUNJA: u32 = 17;
pub const KEY_FINAL: u32 = 18;
pub const KEY_HANJA: u32 = 19;
pub const KEY_KANJI: u32 = 19;
pub const KEY_ESCAPE: u32 = 20;
pub const KEY_CONVERT: u32 = 21;
pub const KEY_NONCONVERT: u32 = 22;
pub const KEY_ACCEPT: u32 = 23;
pub const KEY_MODECHANGE: u32 = 24;
pub const KEY_SPACE: u32 = 25;
pub const KEY_PRIOR: u32 = 26;
pub const KEY_NEXT: u32 = 27;
pub const KEY_END: u32 = 28;
pub const KEY_HOME: u32 = 29;
pub const KEY_LEFT: u32 = 30;
pub const KEY_UP: u32 = 31;
pub const KEY_RIGHT: u32 = 32;
pub const KEY_DOWN: u32 = 33;
pub const KEY_SELECT: u32 = 34;
pub const KEY_PRINT: u32 = 35;
pub const KEY_EXEC: u32 = 36;
pub const KEY_SNAPSHOT: u32 = 37;
pub const KEY_INSERT: u32 = 38;
pub const KEY_DELETE: u32 = 39;
pub const KEY_HELP: u32 = 40;
pub const KEY_0: u32 = 41;
pub const KEY_1: u32 = 42;
pub const KEY_2: u32 = 43;
pub const KEY_3: u32 = 44;
pub const KEY_4: u32 = 45;
pub const KEY_5: u32 = 46;
pub const KEY_6: u32 = 47;
pub const KEY_7: u32 = 48;
pub const KEY_8: u32 = 49;
pub const KEY_9: u32 = 50;
pub const KEY_A: u32 = 51;
pub const KEY_B: u32 = 52;
pub const KEY_C: u32 = 53;
pub const KEY_D: u32 = 54;
pub const KEY_E: u32 = 55;
pub const KEY_F: u32 = 56;
pub const KEY_G: u32 = 57;
pub const KEY_H: u32 = 58;
pub const KEY_I: u32 = 59;
pub const KEY_J: u32 = 60;
pub const KEY_K: u32 = 61;
pub const KEY_L: u32 = 62;
pub const KEY_M: u32 = 63;
pub const KEY_N: u32 = 64;
pub const KEY_O: u32 = 65;
pub const KEY_P: u32 = 66;
pub const KEY_Q: u32 = 67;
pub const KEY_R: u32 = 68;
pub const KEY_S: u32 = 69;
pub const KEY_T: u32 = 70;
pub const KEY_U: u32 = 71;
pub const KEY_V: u32 = 72;
pub const KEY_W: u32 = 73;
pub const KEY_X: u32 = 74;
pub const KEY_Y: u32 = 75;
pub const KEY_Z: u32 = 76;
pub const KEY_LWIN: u32 = 77;
pub const KEY_RWIN: u32 = 78;
pub const KEY_APPS: u32 = 79;
pub const KEY_SLEEP: u32 = 80;
pub const KEY_NUMPAD0: u32 = 81;
pub const KEY_NUMPAD1: u32 = 82;
pub const KEY_NUMPAD2: u32 = 83;
pub const KEY_NUMPAD3: u32 = 84;
pub const KEY_NUMPAD4: u32 = 85;
pub const KEY_NUMPAD5: u32 = 86;
pub const KEY_NUMPAD6: u32 = 87;
pub const KEY_NUMPAD7: u32 = 88;
pub const KEY_NUMPAD8: u32 = 89;
pub const KEY_NUMPAD9: u32 = 90;
pub const KEY_MULTIPLY: u32 = 91;
pub const KEY_ADD: u32 = 92;
pub const KEY_SEPARATOR: u32 = 93;
pub const KEY_SUBTRACT: u32 = 94;
pub const KEY_DECIMAL: u32 = 95;
pub const KEY_DIVIDE: u32 = 96;
pub const KEY_F1: u32 = 97;
pub const KEY_F2: u32 = 98;
pub const KEY_F3: u32 = 99;
pub const KEY_F4: u32 = 100;
pub const KEY_F5: u32 = 101;
pub const KEY_F6: u32 = 102;
pub const KEY_F7: u32 = 103;
pub const KEY_F8: u32 = 104;
pub const KEY_F9: u32 = 105;
pub const KEY_F10: u32 = 106;
pub const KEY_F11: u32 = 107;
pub const KEY_F12: u32 = 108;
pub const KEY_F13: u32 = 109;
pub const KEY_F14: u32 = 110;
pub const KEY_F15: u32 = 111;
pub const KEY_F16: u32 = 112;
pub const KEY_F17: u32 = 113;
pub const KEY_F18: u32 = 114;
pub const KEY_F19: u32 = 115;
pub const KEY_F20: u32 = 116;
pub const KEY_F21: u32 = 117;
pub const KEY_F22: u32 = 118;
pub const KEY_F23: u32 = 119;
pub const KEY_F24: u32 = 120;
pub const KEY_NUMLOCK: u32 = 121;
pub const KEY_SCROLL: u32 = 122;
pub const KEY_LSHIFT: u32 = 123;
pub const KEY_RSHIFT: u32 = 124;
pub const KEY_LCONTROL: u32 = 125;
pub const KEY_RCONTROL: u32 = 126;
pub const KEY_LMENU: u32 = 127;
pub const KEY_RMENU: u32 = 128;
pub const KEY_BROWSER_BACK: u32 = 129;
pub const KEY_BROWSER_FORWARD: u32 = 130;
pub const KEY_BROWSER_REFRESH: u32 = 131;
pub const KEY_BROWSER_STOP: u32 = 132;
pub const KEY_BROWSER_SEARCH: u32 = 133;
pub const KEY_BROWSER_FAVORITES: u32 = 134;
pub const KEY_BROWSER_HOME: u32 = 135;
pub const KEY_VOLUME_MUTE: u32 = 136;
pub const KEY_VOLUME_DOWN: u32 = 137;
pub const KEY_VOLUME_UP: u32 = 138;
pub const KEY_MEDIA_NEXT_TRACK: u32 = 139;
pub const KEY_MEDIA_PREV_TRACK: u32 = 140;
pub const KEY_MEDIA_STOP: u32 = 141;
pub const KEY_MEDIA_PLAY_PAUSE: u32 = 142;
pub const KEY_LAUNCH_MAIL: u32 = 143;
pub const KEY_LAUNCH_MEDIA_SELECT: u32 = 144;
pub const KEY_LAUNCH_APP1: u32 = 145;
pub const KEY_LAUNCH_APP2: u32 = 146;
pub const KEY_OEM_1: u32 = 147;
pub const KEY_OEM_PLUS: u32 = 148;
pub const KEY_OEM_COMMA: u32 = 149;
pub const KEY_OEM_MINUS: u32 = 150;
pub const KEY_OEM_PERIOD: u32 = 151;
pub const KEY_OEM_2: u32 = 152;
pub const KEY_OEM_3: u32 = 153;
pub const KEY_OEM_4: u32 = 154;
pub const KEY_OEM_5: u32 = 155;
pub const KEY_OEM_6: u32 = 156;
pub const KEY_OEM_7: u32 = 157;
pub const KEY_OEM_8: u32 = 158;
pub const KEY_OEM_102: u32 = 159;
pub const KEY_PROCESSKEY: u32 = 160;
pub const KEY_ATTN: u32 = 161;
pub const KEY_CRSEL: u32 = 162;
pub const KEY_EXSEL: u32 = 163;
pub const KEY_EREOF: u32 = 164;
pub const KEY_PLAY: u32 = 165;
pub const KEY_ZOOM: u32 = 166;
pub const KEY_NONAME: u32 = 167;
pub const KEY_PA1: u32 = 168;
pub const KEY_OEM_CLEAR: u32 = 169;
pub const KEYCOUNT: u32 = 170;
pub const KEYPADDING: u32 = 4294967295;
pub fn keystate(key: u32) bool {
return c.keystate(key) == 1;
}
const ctr = std.zig.c_translation;
pub fn signedRemainder(numerator: anytype, denominator: anytype) @TypeOf(numerator, denominator) {
return ctr.signedRemainder(numerator, denominator);
}
const std = @import("std");
const dos = @import("dos.zig");
pub extern fn main() u8;
pub export fn dosmain() u8 {
dos.setvideomode(dos.videomode_320x200);
dos.setdoublebuffer(true);
var gifw: i32 = 0;
var gifh: i32 = 0;
var palcount: i32 = 0;
var palette: [768]u8 = undefined;
const gif = dos.loadgif(
"files/rotozoom.gif",
&gifw,
&gifh,
&palcount,
&palette,
);
var i: i32 = 0;
while (i < palcount) : (i += 1) {
dos.setpal(
i,
@as(u8, @bitCast(palette[@as(usize, @intCast(3 * i + 0))])),
@as(u8, @bitCast(palette[@as(usize, @intCast(3 * i + 1))])),
@as(u8, @bitCast(palette[@as(usize, @intCast(3 * i + 2))])),
);
}
var buffer: [*c]u8 = dos.screenbuffer();
var angle: i32 = 0;
while (!dos.shuttingdown()) {
dos.waitvbl();
const s: f32 = std.math.sin(@as(f32, @floatFromInt(angle)) * std.math.pi / 180);
const c: f32 = std.math.cos(@as(f32, @floatFromInt(angle)) * std.math.pi / 180);
angle = dos.signedRemainder(angle + 1, 360);
var destOfs: i32 = 0;
var y: i32 = 0;
while (y < 200) : (y += 1) {
var x: i32 = 0;
while (x < 320) : (x += 1) {
var u: i32 = dos.signedRemainder(
@as(i32, @intFromFloat(
(((@as(f32, @floatFromInt(x)) * c) -
(@as(f32, @floatFromInt(y)) * s)) * s + 1) + 64,
)),
gifw,
);
var v: i32 = dos.signedRemainder(
@as(i32, @intFromFloat(
(((@as(f32, @floatFromInt(x)) * s) +
(@as(f32, @floatFromInt(y)) * c)) * s + 1) + 64,
)),
gifh,
);
if (u < 0) u += gifw;
if (v < 0) v += gifh;
const srcOfs: i32 = u + v * gifw;
(blk: {
const tmp = blk_1: {
const ref = &destOfs;
const tmp_2 = ref.*;
ref.* += 1;
break :blk_1 tmp_2;
};
if (tmp >= 0) break :blk buffer +
@as(usize, @intCast(tmp)) else break :blk buffer -
~@as(usize, @bitCast(@as(isize, @intCast(tmp)) +% -1));
}).* = (blk: {
const tmp = srcOfs;
if (tmp >= 0) break :blk gif +
@as(usize, @intCast(tmp)) else break :blk gif -
~@as(usize, @bitCast(@as(isize, @intCast(tmp)) +% -1));
}).*;
}
}
buffer = dos.swapbuffers();
if (dos.keystate(dos.KEY_ESCAPE)) break;
}
return 0;
}
@peterhellberg

Copy link
Copy Markdown
Author

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment