added doomplayer
This commit is contained in:
parent
8c12242304
commit
98a2f6577f
|
|
@ -0,0 +1,25 @@
|
|||
const std = @import("std");
|
||||
|
||||
pub fn build(b: *std.Build) void {
|
||||
const target = b.standardTargetOptions(.{});
|
||||
const optimize = b.standardOptimizeOption(.{});
|
||||
|
||||
const mod = b.addModule("doomplayer", .{
|
||||
.target = target,
|
||||
.optimize = optimize,
|
||||
.root_source_file = b.path("src/doom.zig"),
|
||||
});
|
||||
|
||||
mod.addIncludePath(b.path("src/"));
|
||||
mod.addCSourceFile(.{
|
||||
.file = b.path("src/impl.c"),
|
||||
.flags = &.{
|
||||
"-fno-sanitize=undefined",
|
||||
},
|
||||
});
|
||||
|
||||
{
|
||||
const dep = b.dependency("Backlog", .{ .target = target, .optimize = optimize });
|
||||
mod.addImport("Backlog", dep.module("Backlog"));
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
.{
|
||||
.name = .gameExtras,
|
||||
.version = "0.0.0",
|
||||
.dependencies = .{
|
||||
.Backlog = .{ .path = "../../" },
|
||||
},
|
||||
.paths = .{
|
||||
"",
|
||||
},
|
||||
.fingerprint = 0x993cf5f4ca155aa6,
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
|
|
@ -0,0 +1,3 @@
|
|||
pub const c = @cImport({
|
||||
@cInclude("pureDOOM.h");
|
||||
});
|
||||
|
|
@ -0,0 +1,420 @@
|
|||
allocator: std.mem.Allocator,
|
||||
|
||||
doomSampler: *gpu.GPUTexture = undefined,
|
||||
|
||||
gpuTransferBuffer: *gpu.GPUTransferBuffer = undefined,
|
||||
texture: *gpu.GPUTexture = undefined,
|
||||
|
||||
width: u32,
|
||||
height: u32,
|
||||
|
||||
fn log(comptime fmt: []const u8, args: anytype) void {
|
||||
core.engine_log("[Doomplayer] " ++ fmt, args);
|
||||
}
|
||||
|
||||
pub fn create(allocator: std.mem.Allocator) !*@This() {
|
||||
const self = try allocator.create(@This());
|
||||
self.* = .{
|
||||
.allocator = allocator,
|
||||
.width = 320,
|
||||
.height = 200,
|
||||
};
|
||||
|
||||
log("initialized", .{});
|
||||
|
||||
try self.setup();
|
||||
|
||||
gDoom = self;
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
pub fn setup(self: *@This()) !void {
|
||||
try self.createTextures();
|
||||
try backlog.platform.context().addSDLProcessFunction(processFunc);
|
||||
c.doom_set_resolution(320, 200);
|
||||
c.doom_set_default_int("key_up", c.DOOM_KEY_W);
|
||||
c.doom_set_default_int("key_down", c.DOOM_KEY_S);
|
||||
c.doom_set_default_int("key_strafeleft", c.DOOM_KEY_A);
|
||||
c.doom_set_default_int("key_straferight", c.DOOM_KEY_D);
|
||||
c.doom_set_default_int("key_use", c.DOOM_KEY_E);
|
||||
c.doom_set_default_int("mouse_move", 0); // Mouse will not move forward
|
||||
|
||||
c.doom_init(1, @constCast(@ptrCast(@alignCast(&.{"doom"}))), 8);
|
||||
}
|
||||
|
||||
fn sdlToDoomScancode(sdlScancode: c_uint) c_int {
|
||||
switch (sdlScancode) {
|
||||
sdl3_c.SDL_SCANCODE_TAB => {
|
||||
return c.DOOM_KEY_TAB;
|
||||
},
|
||||
sdl3_c.SDL_SCANCODE_RETURN => {
|
||||
return c.DOOM_KEY_ENTER;
|
||||
},
|
||||
sdl3_c.SDL_SCANCODE_ESCAPE => {
|
||||
return c.DOOM_KEY_ESCAPE;
|
||||
},
|
||||
sdl3_c.SDL_SCANCODE_SPACE => {
|
||||
return c.DOOM_KEY_SPACE;
|
||||
},
|
||||
sdl3_c.SDL_SCANCODE_APOSTROPHE => {
|
||||
return c.DOOM_KEY_APOSTROPHE;
|
||||
},
|
||||
sdl3_c.SDL_SCANCODE_KP_MULTIPLY => {
|
||||
return c.DOOM_KEY_MULTIPLY;
|
||||
},
|
||||
sdl3_c.SDL_SCANCODE_COMMA => {
|
||||
return c.DOOM_KEY_COMMA;
|
||||
},
|
||||
sdl3_c.SDL_SCANCODE_MINUS => {
|
||||
return c.DOOM_KEY_MINUS;
|
||||
},
|
||||
sdl3_c.SDL_SCANCODE_PERIOD => {
|
||||
return c.DOOM_KEY_PERIOD;
|
||||
},
|
||||
sdl3_c.SDL_SCANCODE_SLASH => {
|
||||
return c.DOOM_KEY_SLASH;
|
||||
},
|
||||
sdl3_c.SDL_SCANCODE_0 => {
|
||||
return c.DOOM_KEY_0;
|
||||
},
|
||||
sdl3_c.SDL_SCANCODE_1 => {
|
||||
return c.DOOM_KEY_1;
|
||||
},
|
||||
sdl3_c.SDL_SCANCODE_2 => {
|
||||
return c.DOOM_KEY_2;
|
||||
},
|
||||
sdl3_c.SDL_SCANCODE_3 => {
|
||||
return c.DOOM_KEY_3;
|
||||
},
|
||||
sdl3_c.SDL_SCANCODE_4 => {
|
||||
return c.DOOM_KEY_4;
|
||||
},
|
||||
sdl3_c.SDL_SCANCODE_5 => {
|
||||
return c.DOOM_KEY_5;
|
||||
},
|
||||
sdl3_c.SDL_SCANCODE_6 => {
|
||||
return c.DOOM_KEY_6;
|
||||
},
|
||||
sdl3_c.SDL_SCANCODE_7 => {
|
||||
return c.DOOM_KEY_7;
|
||||
},
|
||||
sdl3_c.SDL_SCANCODE_8 => {
|
||||
return c.DOOM_KEY_8;
|
||||
},
|
||||
sdl3_c.SDL_SCANCODE_9 => {
|
||||
return c.DOOM_KEY_9;
|
||||
},
|
||||
sdl3_c.SDL_SCANCODE_SEMICOLON => {
|
||||
return c.DOOM_KEY_SEMICOLON;
|
||||
},
|
||||
sdl3_c.SDL_SCANCODE_EQUALS => {
|
||||
return c.DOOM_KEY_EQUALS;
|
||||
},
|
||||
sdl3_c.SDL_SCANCODE_LEFTBRACKET => {
|
||||
return c.DOOM_KEY_LEFT_BRACKET;
|
||||
},
|
||||
sdl3_c.SDL_SCANCODE_RIGHTBRACKET => {
|
||||
return c.DOOM_KEY_RIGHT_BRACKET;
|
||||
},
|
||||
sdl3_c.SDL_SCANCODE_A => {
|
||||
return c.DOOM_KEY_A;
|
||||
},
|
||||
sdl3_c.SDL_SCANCODE_B => {
|
||||
return c.DOOM_KEY_B;
|
||||
},
|
||||
sdl3_c.SDL_SCANCODE_C => {
|
||||
return c.DOOM_KEY_C;
|
||||
},
|
||||
sdl3_c.SDL_SCANCODE_D => {
|
||||
return c.DOOM_KEY_D;
|
||||
},
|
||||
sdl3_c.SDL_SCANCODE_E => {
|
||||
return c.DOOM_KEY_E;
|
||||
},
|
||||
sdl3_c.SDL_SCANCODE_F => {
|
||||
return c.DOOM_KEY_F;
|
||||
},
|
||||
sdl3_c.SDL_SCANCODE_G => {
|
||||
return c.DOOM_KEY_G;
|
||||
},
|
||||
sdl3_c.SDL_SCANCODE_H => {
|
||||
return c.DOOM_KEY_H;
|
||||
},
|
||||
sdl3_c.SDL_SCANCODE_I => {
|
||||
return c.DOOM_KEY_I;
|
||||
},
|
||||
sdl3_c.SDL_SCANCODE_J => {
|
||||
return c.DOOM_KEY_J;
|
||||
},
|
||||
sdl3_c.SDL_SCANCODE_K => {
|
||||
return c.DOOM_KEY_K;
|
||||
},
|
||||
sdl3_c.SDL_SCANCODE_L => {
|
||||
return c.DOOM_KEY_L;
|
||||
},
|
||||
sdl3_c.SDL_SCANCODE_M => {
|
||||
return c.DOOM_KEY_M;
|
||||
},
|
||||
sdl3_c.SDL_SCANCODE_N => {
|
||||
return c.DOOM_KEY_N;
|
||||
},
|
||||
sdl3_c.SDL_SCANCODE_O => {
|
||||
return c.DOOM_KEY_O;
|
||||
},
|
||||
sdl3_c.SDL_SCANCODE_P => {
|
||||
return c.DOOM_KEY_P;
|
||||
},
|
||||
sdl3_c.SDL_SCANCODE_Q => {
|
||||
return c.DOOM_KEY_Q;
|
||||
},
|
||||
sdl3_c.SDL_SCANCODE_R => {
|
||||
return c.DOOM_KEY_R;
|
||||
},
|
||||
sdl3_c.SDL_SCANCODE_S => {
|
||||
return c.DOOM_KEY_S;
|
||||
},
|
||||
sdl3_c.SDL_SCANCODE_T => {
|
||||
return c.DOOM_KEY_T;
|
||||
},
|
||||
sdl3_c.SDL_SCANCODE_U => {
|
||||
return c.DOOM_KEY_U;
|
||||
},
|
||||
sdl3_c.SDL_SCANCODE_V => {
|
||||
return c.DOOM_KEY_V;
|
||||
},
|
||||
sdl3_c.SDL_SCANCODE_W => {
|
||||
return c.DOOM_KEY_W;
|
||||
},
|
||||
sdl3_c.SDL_SCANCODE_X => {
|
||||
return c.DOOM_KEY_X;
|
||||
},
|
||||
sdl3_c.SDL_SCANCODE_Y => {
|
||||
return c.DOOM_KEY_Y;
|
||||
},
|
||||
sdl3_c.SDL_SCANCODE_Z => {
|
||||
return c.DOOM_KEY_Z;
|
||||
},
|
||||
sdl3_c.SDL_SCANCODE_BACKSPACE => {
|
||||
return c.DOOM_KEY_BACKSPACE;
|
||||
},
|
||||
sdl3_c.SDL_SCANCODE_LCTRL => {},
|
||||
sdl3_c.SDL_SCANCODE_RCTRL => {
|
||||
return c.DOOM_KEY_CTRL;
|
||||
},
|
||||
sdl3_c.SDL_SCANCODE_LEFT => {
|
||||
return c.DOOM_KEY_LEFT_ARROW;
|
||||
},
|
||||
sdl3_c.SDL_SCANCODE_UP => {
|
||||
return c.DOOM_KEY_UP_ARROW;
|
||||
},
|
||||
sdl3_c.SDL_SCANCODE_RIGHT => {
|
||||
return c.DOOM_KEY_RIGHT_ARROW;
|
||||
},
|
||||
sdl3_c.SDL_SCANCODE_DOWN => {
|
||||
return c.DOOM_KEY_DOWN_ARROW;
|
||||
},
|
||||
sdl3_c.SDL_SCANCODE_LSHIFT, sdl3_c.SDL_SCANCODE_RSHIFT => {
|
||||
return c.DOOM_KEY_SHIFT;
|
||||
},
|
||||
sdl3_c.SDL_SCANCODE_LALT => {},
|
||||
sdl3_c.SDL_SCANCODE_RALT => {
|
||||
return c.DOOM_KEY_ALT;
|
||||
},
|
||||
sdl3_c.SDL_SCANCODE_F1 => {
|
||||
return c.DOOM_KEY_F1;
|
||||
},
|
||||
sdl3_c.SDL_SCANCODE_F2 => {
|
||||
return c.DOOM_KEY_F2;
|
||||
},
|
||||
sdl3_c.SDL_SCANCODE_F3 => {
|
||||
return c.DOOM_KEY_F3;
|
||||
},
|
||||
sdl3_c.SDL_SCANCODE_F4 => {
|
||||
return c.DOOM_KEY_F4;
|
||||
},
|
||||
sdl3_c.SDL_SCANCODE_F5 => {
|
||||
return c.DOOM_KEY_F5;
|
||||
},
|
||||
sdl3_c.SDL_SCANCODE_F6 => {
|
||||
return c.DOOM_KEY_F6;
|
||||
},
|
||||
sdl3_c.SDL_SCANCODE_F7 => {
|
||||
return c.DOOM_KEY_F7;
|
||||
},
|
||||
sdl3_c.SDL_SCANCODE_F8 => {
|
||||
return c.DOOM_KEY_F8;
|
||||
},
|
||||
sdl3_c.SDL_SCANCODE_F9 => {
|
||||
return c.DOOM_KEY_F9;
|
||||
},
|
||||
sdl3_c.SDL_SCANCODE_F10 => {
|
||||
return c.DOOM_KEY_F10;
|
||||
},
|
||||
sdl3_c.SDL_SCANCODE_F11 => {
|
||||
return c.DOOM_KEY_F11;
|
||||
},
|
||||
sdl3_c.SDL_SCANCODE_F12 => {
|
||||
return c.DOOM_KEY_F12;
|
||||
},
|
||||
sdl3_c.SDL_SCANCODE_PAUSE => {
|
||||
return c.DOOM_KEY_PAUSE;
|
||||
},
|
||||
else => {
|
||||
return c.DOOM_KEY_UNKNOWN;
|
||||
},
|
||||
}
|
||||
|
||||
return c.DOOM_KEY_UNKNOWN;
|
||||
}
|
||||
|
||||
var gDoom: *@This() = undefined;
|
||||
|
||||
pub fn processFunc(e: *sdl3.Event) void {
|
||||
switch (e.type) {
|
||||
else => {},
|
||||
sdl3_c.SDL_EVENT_MOUSE_MOTION => {
|
||||
c.doom_mouse_move(@intFromFloat(e.motion.xrel * 4), @intFromFloat(e.motion.yrel * 4));
|
||||
},
|
||||
sdl3_c.SDL_EVENT_MOUSE_BUTTON_DOWN => {
|
||||
c.doom_key_down(sdlToDoomScancode(e.button.button));
|
||||
},
|
||||
sdl3_c.SDL_EVENT_MOUSE_BUTTON_UP => {
|
||||
c.doom_key_down(sdlToDoomScancode(e.button.button));
|
||||
},
|
||||
sdl3_c.SDL_EVENT_KEY_DOWN => {
|
||||
if (!e.key.repeat) {
|
||||
c.doom_key_down(sdlToDoomScancode(e.key.scancode));
|
||||
}
|
||||
},
|
||||
sdl3_c.SDL_EVENT_KEY_UP => {
|
||||
if (!e.key.repeat) {
|
||||
c.doom_key_up(sdlToDoomScancode(e.key.scancode));
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
fn getFrameLength(self: @This()) c_int {
|
||||
return self.width * self.height;
|
||||
}
|
||||
|
||||
fn acquireVideoFrameBuffer(self: *@This()) []u8 {
|
||||
var slice: []u8 = undefined;
|
||||
slice.ptr = rend.context().device.mapGPUTransferBuffer(self.gpuTransferBuffer, false);
|
||||
slice.len = @intCast(self.width * self.width * 4);
|
||||
return slice;
|
||||
}
|
||||
|
||||
fn releaseAndUploadFrameBuffer(self: *@This(), cmd: *gpu.GPUCommandBuffer) void {
|
||||
const copyPass = cmd.beginGPUCopyPass();
|
||||
|
||||
copyPass.uploadToGPUTexture(
|
||||
&.{
|
||||
.transfer_buffer = self.gpuTransferBuffer,
|
||||
.offset = 0,
|
||||
.pixels_per_row = self.width,
|
||||
.rows_per_layer = self.height,
|
||||
},
|
||||
&std.mem.zeroInit(gpu.GPUTextureRegion, .{
|
||||
.texture = self.texture,
|
||||
.w = self.width,
|
||||
.h = self.height,
|
||||
.d = 1,
|
||||
}),
|
||||
true,
|
||||
);
|
||||
|
||||
copyPass.endGPUCopyPass();
|
||||
}
|
||||
|
||||
fn createTextureInner(width: u32, height: u32) !*gpu.GPUTexture {
|
||||
const ctx = rend.context();
|
||||
|
||||
const gpuTexture = ctx.device.createGPUTexture(&std.mem.zeroInit(gpu.GPUTextureCreateInfo, .{
|
||||
.type = .texturetype2d,
|
||||
.format = .textureformatR8g8b8a8Unorm,
|
||||
.usage = .{ .textureusageSampler = true },
|
||||
.width = @as(u32, @intCast(width)),
|
||||
.height = @as(u32, @intCast(height)),
|
||||
.layer_count_or_depth = 1,
|
||||
.num_levels = 1,
|
||||
}));
|
||||
|
||||
return gpuTexture;
|
||||
}
|
||||
|
||||
pub fn createTextures(self: *@This()) !void {
|
||||
self.texture = try createTextureInner(self.width, self.height);
|
||||
|
||||
// create transfer Buffer
|
||||
self.gpuTransferBuffer = rend.context().device.createGPUTransferBuffer(&.{
|
||||
.usage = .transferbufferusageUpload,
|
||||
.size = @as(u32, @intCast(self.width * self.height * 4)),
|
||||
.props = 0,
|
||||
});
|
||||
}
|
||||
|
||||
pub fn tick(self: *@This(), dt: f64) void {
|
||||
_ = dt;
|
||||
c.doom_update();
|
||||
|
||||
const frame = self.acquireVideoFrameBuffer();
|
||||
|
||||
const doomFb = c.doom_get_framebuffer(4);
|
||||
|
||||
var i: usize = 0;
|
||||
while (i < self.width * self.height * 4) : (i += 1) {
|
||||
frame[i] = doomFb[i];
|
||||
}
|
||||
|
||||
rend.context().device.unmapGPUTransferBuffer(self.gpuTransferBuffer);
|
||||
|
||||
const cmd = rend.context().device.acquireGPUCommandBuffer();
|
||||
self.releaseAndUploadFrameBuffer(cmd);
|
||||
_ = cmd.submitGPUCommandBuffer();
|
||||
}
|
||||
|
||||
fn bindVideoTextures(p: ?*anyopaque) void {
|
||||
const self: *@This() = @ptrCast(@alignCast(p));
|
||||
const ctx = rend.context();
|
||||
const renderpass: *gpu.GPURenderPass = ctx.state.pass.?;
|
||||
renderpass.bindGPUFragmentSamplers(0, &.{ .sampler = ctx.blockySampler, .texture = self.texture }, 1);
|
||||
}
|
||||
|
||||
// creates a video player entity
|
||||
pub fn createEntity(self: *@This()) !core.Entity {
|
||||
const entity = try core.createEntity();
|
||||
const scene = entity.addComponent(core.Scene).?;
|
||||
const size = 5.0;
|
||||
const h: f32 = @floatFromInt(self.height);
|
||||
const w: f32 = @floatFromInt(self.width);
|
||||
|
||||
scene.setScale(size, size, size * (h / w));
|
||||
scene.setRotation(core.Rotation.eulerX(core.radians(90.0)));
|
||||
scene.setPosition(.{ .z = 30 });
|
||||
|
||||
if (entity.addComponent(rend.MeshComponent)) |mesh| {
|
||||
mesh.cmrf = bindVideoTextures;
|
||||
mesh.cmrf_ctx = self;
|
||||
mesh.textureMode = 0x1;
|
||||
mesh.setMesh("m_plane");
|
||||
}
|
||||
return entity;
|
||||
}
|
||||
|
||||
pub fn destroy(self: *@This()) void {
|
||||
core.engine_logs("[Videoplayer] destroying player");
|
||||
|
||||
self.allocator.destroy(self);
|
||||
}
|
||||
|
||||
const std = @import("std");
|
||||
const backlog = @import("Backlog");
|
||||
const core = backlog.core;
|
||||
const rend = backlog.rend;
|
||||
const sdl3 = backlog.platform.windowing.sdl3;
|
||||
const sdl3_c = sdl3.c;
|
||||
const c = @import("c.zig").c;
|
||||
const gpu = rend.renderer.gpu;
|
||||
const ig = backlog.imgui.api;
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
|
||||
#define DOOM_IMPLEMENTATION
|
||||
#define DOOM_IMPLEMENT_MALLOC
|
||||
#define DOOM_IMPLEMENT_PRINT
|
||||
#define DOOM_IMPLEMENT_MALLOC
|
||||
#define DOOM_IMPLEMENT_FILE_IO
|
||||
#define DOOM_IMPLEMENT_SOCKETS
|
||||
#define DOOM_IMPLEMENT_GETTIME
|
||||
#define DOOM_IMPLEMENT_GETENV
|
||||
|
||||
#include "PureDOOM.h"
|
||||
|
||||
Loading…
Reference in New Issue