lots of restructuring... LOTS.
parent
8796331efa
commit
2f146a9a14
|
Before Width: | Height: | Size: 47 KiB After Width: | Height: | Size: 47 KiB |
142
build.zig
142
build.zig
|
|
@ -1,121 +1,65 @@
|
|||
const std = @import("std");
|
||||
|
||||
// Although this function looks imperative, note that its job is to
|
||||
// declaratively construct a build graph that will be executed by an external
|
||||
// runner.
|
||||
|
||||
|
||||
// const GL_TYPE = enum([]const u8) {
|
||||
// COMPAT = "compat",
|
||||
// CORE = "core",
|
||||
// };
|
||||
//
|
||||
// const GL_VERSION = enum([]const u8) {
|
||||
// GL33 = "3.3",
|
||||
// GL46 = "4.6",
|
||||
// };
|
||||
|
||||
|
||||
const glad_folder = "glad-4.6-compat";
|
||||
|
||||
pub fn build(b: *std.Build) void {
|
||||
// Standard target options allows the person running `zig build` to choose
|
||||
// what target to build for. Here we do not override the defaults, which
|
||||
// means any target is allowed, and the default is native. Other options
|
||||
// for restricting supported target set are available.
|
||||
const target = b.standardTargetOptions(.{});
|
||||
const target = b.standardTargetOptions(.{});
|
||||
const optimize = b.standardOptimizeOption(.{});
|
||||
|
||||
// Standard optimization options allow the person running `zig build` to select
|
||||
// between Debug, ReleaseSafe, ReleaseFast, and ReleaseSmall. Here we do not
|
||||
// set a preferred release mode, allowing the user to decide how to optimize.
|
||||
const optimize = b.standardOptimizeOption(.{});
|
||||
|
||||
// const lib = b.addStaticLibrary(.{
|
||||
// .name = "test-game",
|
||||
// // In this case the main source file is merely a path, however, in more
|
||||
// // complicated build scripts, this could be a generated file.
|
||||
// .root_source_file = b.path("src/root.zig"),
|
||||
// .target = target,
|
||||
// .optimize = optimize,
|
||||
// });
|
||||
//
|
||||
// // This declares intent for the library to be installed into the standard
|
||||
// // location when the user invokes the "install" step (the default step when
|
||||
// // running `zig build`).
|
||||
// b.installArtifact(lib);
|
||||
|
||||
const exe = b.addExecutable(.{
|
||||
.name = "test-game",
|
||||
.root_source_file = b.path("src/main.zig"),
|
||||
.target = target,
|
||||
.optimize = optimize,
|
||||
});
|
||||
exe.addCSourceFile(.{
|
||||
.file = b.path(glad_folder ++ "/src/glad.c")
|
||||
const c = b.addModule("c", .{
|
||||
.root_source_file = b.path("src/c.zig"),
|
||||
.target = target,
|
||||
.optimize = optimize,
|
||||
});
|
||||
exe.addIncludePath(b.path(glad_folder ++ "/include"));
|
||||
// c.addLibraryPath(b.path("/usr/local/lib"));
|
||||
c.linkSystemLibrary("SDL3", .{});
|
||||
c.addIncludePath(b.path("open-simplex/include"));
|
||||
c.linkSystemLibrary("SDL3_image", .{});
|
||||
|
||||
exe.addCSourceFile(.{
|
||||
.file = b.path("open-simplex/src/OpenSimplex2F.c")
|
||||
const engine = b.addModule("engine", .{
|
||||
.root_source_file = b.path("src/engine/root.zig"),
|
||||
.target = target,
|
||||
.optimize = optimize,
|
||||
});
|
||||
engine.addImport("engine", engine);
|
||||
engine.addImport("c", c);
|
||||
|
||||
const exe = b.addExecutable(.{
|
||||
.name = "hadean",
|
||||
.root_source_file = b.path("src/hadean/main.zig"),
|
||||
.target = target,
|
||||
.optimize = optimize,
|
||||
});
|
||||
|
||||
exe.root_module.addImport("engine", engine);
|
||||
exe.root_module.addImport("c", c);
|
||||
exe.addCSourceFile(.{ .file = b.path("open-simplex/src/OpenSimplex2F.c") });
|
||||
exe.addIncludePath(b.path("open-simplex/include"));
|
||||
|
||||
exe.linkLibC();
|
||||
exe.linkSystemLibrary("glfw");
|
||||
exe.linkSystemLibrary("GL");
|
||||
exe.linkSystemLibrary("z");
|
||||
exe.linkSystemLibrary("spng");
|
||||
exe.root_module.addRPathSpecial("$ORIGIN/../lib");
|
||||
|
||||
// This declares intent for the executable to be installed into the
|
||||
// standard location when the user invokes the "install" step (the default
|
||||
// step when running `zig build`).
|
||||
b.installArtifact(exe);
|
||||
b.getInstallStep().dependOn(&(b.addInstallFile(.{
|
||||
.cwd_relative = "/usr/local/lib/libSDL3.so.0.1.7"
|
||||
}, "lib/libSDL3.so.0")).step);
|
||||
b.getInstallStep().dependOn(&(b.addInstallFile(.{
|
||||
.cwd_relative = "/usr/local/lib/libSDL3_image.so.0.1.0"
|
||||
}, "lib/libSDL3_image.so.0")).step);
|
||||
b.getInstallStep().dependOn(&(b.addInstallFile(
|
||||
b.path("assets/textures.png"),
|
||||
"assets/textures.png"
|
||||
)).step);
|
||||
|
||||
// This *creates* a Run step in the build graph, to be executed when another
|
||||
// step is evaluated that depends on it. The next line below will establish
|
||||
// such a dependency.
|
||||
b.installArtifact(exe);
|
||||
const run_cmd = b.addRunArtifact(exe);
|
||||
|
||||
// By making the run step depend on the install step, it will be run from the
|
||||
// installation directory rather than directly from within the cache directory.
|
||||
// This is not necessary, however, if the application depends on other installed
|
||||
// files, this ensures they will be present and in the expected location.
|
||||
run_cmd.step.dependOn(b.getInstallStep());
|
||||
|
||||
// This allows the user to pass arguments to the application in the build
|
||||
// command itself, like this: `zig build run -- arg1 arg2 etc`
|
||||
if (b.args) |args| {
|
||||
run_cmd.addArgs(args);
|
||||
}
|
||||
|
||||
// This creates a build step. It will be visible in the `zig build --help` menu,
|
||||
// and can be selected like this: `zig build run`
|
||||
// This will evaluate the `run` step rather than the default, which is "install".
|
||||
const run_step = b.step("run", "Run the app");
|
||||
run_step.dependOn(&run_cmd.step);
|
||||
|
||||
// // Creates a step for unit testing. This only builds the test executable
|
||||
// // but does not run it.
|
||||
// const lib_unit_tests = b.addTest(.{
|
||||
// .root_source_file = b.path("src/root.zig"),
|
||||
// .target = target,
|
||||
// .optimize = optimize,
|
||||
// });
|
||||
//
|
||||
// const run_lib_unit_tests = b.addRunArtifact(lib_unit_tests);
|
||||
|
||||
// const exe_unit_tests = b.addTest(.{
|
||||
// .root_source_file = b.path("src/main.zig"),
|
||||
// .target = target,
|
||||
// .optimize = optimize,
|
||||
// });
|
||||
|
||||
// const run_exe_unit_tests = b.addRunArtifact(exe_unit_tests);
|
||||
|
||||
// Similar to creating the run step earlier, this exposes a `test` step to
|
||||
// the `zig build --help` menu, providing a way for the user to request
|
||||
// running the unit tests.
|
||||
// const test_step = b.step("test", "Run unit tests");
|
||||
// test_step.dependOn(&run_lib_unit_tests.step);
|
||||
// test_step.dependOn(&run_exe_unit_tests.step);
|
||||
// because engine and hadean are diff modules their c modules
|
||||
// get different caches, causing opaques to be different between them.
|
||||
// kinda makes sense, because zig is namespacy and c is not!
|
||||
// it would be nice to in some way ensure both got the same version, though.
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,311 +0,0 @@
|
|||
#ifndef __khrplatform_h_
|
||||
#define __khrplatform_h_
|
||||
|
||||
/*
|
||||
** Copyright (c) 2008-2018 The Khronos Group Inc.
|
||||
**
|
||||
** Permission is hereby granted, free of charge, to any person obtaining a
|
||||
** copy of this software and/or associated documentation files (the
|
||||
** "Materials"), to deal in the Materials without restriction, including
|
||||
** without limitation the rights to use, copy, modify, merge, publish,
|
||||
** distribute, sublicense, and/or sell copies of the Materials, and to
|
||||
** permit persons to whom the Materials are furnished to do so, subject to
|
||||
** the following conditions:
|
||||
**
|
||||
** The above copyright notice and this permission notice shall be included
|
||||
** in all copies or substantial portions of the Materials.
|
||||
**
|
||||
** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
|
||||
*/
|
||||
|
||||
/* Khronos platform-specific types and definitions.
|
||||
*
|
||||
* The master copy of khrplatform.h is maintained in the Khronos EGL
|
||||
* Registry repository at https://github.com/KhronosGroup/EGL-Registry
|
||||
* The last semantic modification to khrplatform.h was at commit ID:
|
||||
* 67a3e0864c2d75ea5287b9f3d2eb74a745936692
|
||||
*
|
||||
* Adopters may modify this file to suit their platform. Adopters are
|
||||
* encouraged to submit platform specific modifications to the Khronos
|
||||
* group so that they can be included in future versions of this file.
|
||||
* Please submit changes by filing pull requests or issues on
|
||||
* the EGL Registry repository linked above.
|
||||
*
|
||||
*
|
||||
* See the Implementer's Guidelines for information about where this file
|
||||
* should be located on your system and for more details of its use:
|
||||
* http://www.khronos.org/registry/implementers_guide.pdf
|
||||
*
|
||||
* This file should be included as
|
||||
* #include <KHR/khrplatform.h>
|
||||
* by Khronos client API header files that use its types and defines.
|
||||
*
|
||||
* The types in khrplatform.h should only be used to define API-specific types.
|
||||
*
|
||||
* Types defined in khrplatform.h:
|
||||
* khronos_int8_t signed 8 bit
|
||||
* khronos_uint8_t unsigned 8 bit
|
||||
* khronos_int16_t signed 16 bit
|
||||
* khronos_uint16_t unsigned 16 bit
|
||||
* khronos_int32_t signed 32 bit
|
||||
* khronos_uint32_t unsigned 32 bit
|
||||
* khronos_int64_t signed 64 bit
|
||||
* khronos_uint64_t unsigned 64 bit
|
||||
* khronos_intptr_t signed same number of bits as a pointer
|
||||
* khronos_uintptr_t unsigned same number of bits as a pointer
|
||||
* khronos_ssize_t signed size
|
||||
* khronos_usize_t unsigned size
|
||||
* khronos_float_t signed 32 bit floating point
|
||||
* khronos_time_ns_t unsigned 64 bit time in nanoseconds
|
||||
* khronos_utime_nanoseconds_t unsigned time interval or absolute time in
|
||||
* nanoseconds
|
||||
* khronos_stime_nanoseconds_t signed time interval in nanoseconds
|
||||
* khronos_boolean_enum_t enumerated boolean type. This should
|
||||
* only be used as a base type when a client API's boolean type is
|
||||
* an enum. Client APIs which use an integer or other type for
|
||||
* booleans cannot use this as the base type for their boolean.
|
||||
*
|
||||
* Tokens defined in khrplatform.h:
|
||||
*
|
||||
* KHRONOS_FALSE, KHRONOS_TRUE Enumerated boolean false/true values.
|
||||
*
|
||||
* KHRONOS_SUPPORT_INT64 is 1 if 64 bit integers are supported; otherwise 0.
|
||||
* KHRONOS_SUPPORT_FLOAT is 1 if floats are supported; otherwise 0.
|
||||
*
|
||||
* Calling convention macros defined in this file:
|
||||
* KHRONOS_APICALL
|
||||
* KHRONOS_APIENTRY
|
||||
* KHRONOS_APIATTRIBUTES
|
||||
*
|
||||
* These may be used in function prototypes as:
|
||||
*
|
||||
* KHRONOS_APICALL void KHRONOS_APIENTRY funcname(
|
||||
* int arg1,
|
||||
* int arg2) KHRONOS_APIATTRIBUTES;
|
||||
*/
|
||||
|
||||
#if defined(__SCITECH_SNAP__) && !defined(KHRONOS_STATIC)
|
||||
# define KHRONOS_STATIC 1
|
||||
#endif
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* Definition of KHRONOS_APICALL
|
||||
*-------------------------------------------------------------------------
|
||||
* This precedes the return type of the function in the function prototype.
|
||||
*/
|
||||
#if defined(KHRONOS_STATIC)
|
||||
/* If the preprocessor constant KHRONOS_STATIC is defined, make the
|
||||
* header compatible with static linking. */
|
||||
# define KHRONOS_APICALL
|
||||
#elif defined(_WIN32)
|
||||
# define KHRONOS_APICALL __declspec(dllimport)
|
||||
#elif defined (__SYMBIAN32__)
|
||||
# define KHRONOS_APICALL IMPORT_C
|
||||
#elif defined(__ANDROID__)
|
||||
# define KHRONOS_APICALL __attribute__((visibility("default")))
|
||||
#else
|
||||
# define KHRONOS_APICALL
|
||||
#endif
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* Definition of KHRONOS_APIENTRY
|
||||
*-------------------------------------------------------------------------
|
||||
* This follows the return type of the function and precedes the function
|
||||
* name in the function prototype.
|
||||
*/
|
||||
#if defined(_WIN32) && !defined(_WIN32_WCE) && !defined(__SCITECH_SNAP__)
|
||||
/* Win32 but not WinCE */
|
||||
# define KHRONOS_APIENTRY __stdcall
|
||||
#else
|
||||
# define KHRONOS_APIENTRY
|
||||
#endif
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* Definition of KHRONOS_APIATTRIBUTES
|
||||
*-------------------------------------------------------------------------
|
||||
* This follows the closing parenthesis of the function prototype arguments.
|
||||
*/
|
||||
#if defined (__ARMCC_2__)
|
||||
#define KHRONOS_APIATTRIBUTES __softfp
|
||||
#else
|
||||
#define KHRONOS_APIATTRIBUTES
|
||||
#endif
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* basic type definitions
|
||||
*-----------------------------------------------------------------------*/
|
||||
#if (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) || defined(__GNUC__) || defined(__SCO__) || defined(__USLC__)
|
||||
|
||||
|
||||
/*
|
||||
* Using <stdint.h>
|
||||
*/
|
||||
#include <stdint.h>
|
||||
typedef int32_t khronos_int32_t;
|
||||
typedef uint32_t khronos_uint32_t;
|
||||
typedef int64_t khronos_int64_t;
|
||||
typedef uint64_t khronos_uint64_t;
|
||||
#define KHRONOS_SUPPORT_INT64 1
|
||||
#define KHRONOS_SUPPORT_FLOAT 1
|
||||
/*
|
||||
* To support platform where unsigned long cannot be used interchangeably with
|
||||
* inptr_t (e.g. CHERI-extended ISAs), we can use the stdint.h intptr_t.
|
||||
* Ideally, we could just use (u)intptr_t everywhere, but this could result in
|
||||
* ABI breakage if khronos_uintptr_t is changed from unsigned long to
|
||||
* unsigned long long or similar (this results in different C++ name mangling).
|
||||
* To avoid changes for existing platforms, we restrict usage of intptr_t to
|
||||
* platforms where the size of a pointer is larger than the size of long.
|
||||
*/
|
||||
#if defined(__SIZEOF_LONG__) && defined(__SIZEOF_POINTER__)
|
||||
#if __SIZEOF_POINTER__ > __SIZEOF_LONG__
|
||||
#define KHRONOS_USE_INTPTR_T
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#elif defined(__VMS ) || defined(__sgi)
|
||||
|
||||
/*
|
||||
* Using <inttypes.h>
|
||||
*/
|
||||
#include <inttypes.h>
|
||||
typedef int32_t khronos_int32_t;
|
||||
typedef uint32_t khronos_uint32_t;
|
||||
typedef int64_t khronos_int64_t;
|
||||
typedef uint64_t khronos_uint64_t;
|
||||
#define KHRONOS_SUPPORT_INT64 1
|
||||
#define KHRONOS_SUPPORT_FLOAT 1
|
||||
|
||||
#elif defined(_WIN32) && !defined(__SCITECH_SNAP__)
|
||||
|
||||
/*
|
||||
* Win32
|
||||
*/
|
||||
typedef __int32 khronos_int32_t;
|
||||
typedef unsigned __int32 khronos_uint32_t;
|
||||
typedef __int64 khronos_int64_t;
|
||||
typedef unsigned __int64 khronos_uint64_t;
|
||||
#define KHRONOS_SUPPORT_INT64 1
|
||||
#define KHRONOS_SUPPORT_FLOAT 1
|
||||
|
||||
#elif defined(__sun__) || defined(__digital__)
|
||||
|
||||
/*
|
||||
* Sun or Digital
|
||||
*/
|
||||
typedef int khronos_int32_t;
|
||||
typedef unsigned int khronos_uint32_t;
|
||||
#if defined(__arch64__) || defined(_LP64)
|
||||
typedef long int khronos_int64_t;
|
||||
typedef unsigned long int khronos_uint64_t;
|
||||
#else
|
||||
typedef long long int khronos_int64_t;
|
||||
typedef unsigned long long int khronos_uint64_t;
|
||||
#endif /* __arch64__ */
|
||||
#define KHRONOS_SUPPORT_INT64 1
|
||||
#define KHRONOS_SUPPORT_FLOAT 1
|
||||
|
||||
#elif 0
|
||||
|
||||
/*
|
||||
* Hypothetical platform with no float or int64 support
|
||||
*/
|
||||
typedef int khronos_int32_t;
|
||||
typedef unsigned int khronos_uint32_t;
|
||||
#define KHRONOS_SUPPORT_INT64 0
|
||||
#define KHRONOS_SUPPORT_FLOAT 0
|
||||
|
||||
#else
|
||||
|
||||
/*
|
||||
* Generic fallback
|
||||
*/
|
||||
#include <stdint.h>
|
||||
typedef int32_t khronos_int32_t;
|
||||
typedef uint32_t khronos_uint32_t;
|
||||
typedef int64_t khronos_int64_t;
|
||||
typedef uint64_t khronos_uint64_t;
|
||||
#define KHRONOS_SUPPORT_INT64 1
|
||||
#define KHRONOS_SUPPORT_FLOAT 1
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* Types that are (so far) the same on all platforms
|
||||
*/
|
||||
typedef signed char khronos_int8_t;
|
||||
typedef unsigned char khronos_uint8_t;
|
||||
typedef signed short int khronos_int16_t;
|
||||
typedef unsigned short int khronos_uint16_t;
|
||||
|
||||
/*
|
||||
* Types that differ between LLP64 and LP64 architectures - in LLP64,
|
||||
* pointers are 64 bits, but 'long' is still 32 bits. Win64 appears
|
||||
* to be the only LLP64 architecture in current use.
|
||||
*/
|
||||
#ifdef KHRONOS_USE_INTPTR_T
|
||||
typedef intptr_t khronos_intptr_t;
|
||||
typedef uintptr_t khronos_uintptr_t;
|
||||
#elif defined(_WIN64)
|
||||
typedef signed long long int khronos_intptr_t;
|
||||
typedef unsigned long long int khronos_uintptr_t;
|
||||
#else
|
||||
typedef signed long int khronos_intptr_t;
|
||||
typedef unsigned long int khronos_uintptr_t;
|
||||
#endif
|
||||
|
||||
#if defined(_WIN64)
|
||||
typedef signed long long int khronos_ssize_t;
|
||||
typedef unsigned long long int khronos_usize_t;
|
||||
#else
|
||||
typedef signed long int khronos_ssize_t;
|
||||
typedef unsigned long int khronos_usize_t;
|
||||
#endif
|
||||
|
||||
#if KHRONOS_SUPPORT_FLOAT
|
||||
/*
|
||||
* Float type
|
||||
*/
|
||||
typedef float khronos_float_t;
|
||||
#endif
|
||||
|
||||
#if KHRONOS_SUPPORT_INT64
|
||||
/* Time types
|
||||
*
|
||||
* These types can be used to represent a time interval in nanoseconds or
|
||||
* an absolute Unadjusted System Time. Unadjusted System Time is the number
|
||||
* of nanoseconds since some arbitrary system event (e.g. since the last
|
||||
* time the system booted). The Unadjusted System Time is an unsigned
|
||||
* 64 bit value that wraps back to 0 every 584 years. Time intervals
|
||||
* may be either signed or unsigned.
|
||||
*/
|
||||
typedef khronos_uint64_t khronos_utime_nanoseconds_t;
|
||||
typedef khronos_int64_t khronos_stime_nanoseconds_t;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Dummy value used to pad enum types to 32 bits.
|
||||
*/
|
||||
#ifndef KHRONOS_MAX_ENUM
|
||||
#define KHRONOS_MAX_ENUM 0x7FFFFFFF
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Enumerated boolean type
|
||||
*
|
||||
* Values other than zero should be considered to be true. Therefore
|
||||
* comparisons should not be made against KHRONOS_TRUE.
|
||||
*/
|
||||
typedef enum {
|
||||
KHRONOS_FALSE = 0,
|
||||
KHRONOS_TRUE = 1,
|
||||
KHRONOS_BOOLEAN_ENUM_FORCE_SIZE = KHRONOS_MAX_ENUM
|
||||
} khronos_boolean_enum_t;
|
||||
|
||||
#endif /* __khrplatform_h_ */
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
186
src/Engine.zig
186
src/Engine.zig
|
|
@ -1,186 +0,0 @@
|
|||
const std = @import("std");
|
||||
const Recti = @import("geometry/Recti.zig");
|
||||
const Matrix4f = @import("geometry/Matrix4f.zig");
|
||||
const shaders = @import("shaders.zig");
|
||||
const Texture = @import("Texture.zig");
|
||||
const Sprite = @import("Sprite.zig");
|
||||
const Layer = @import("Layer.zig");
|
||||
const Color = @import("Color.zig");
|
||||
const Scene = @import("Scene.zig");
|
||||
const assets = @import("assets.zig");
|
||||
const Vec2i = @import("geometry/Vec2i.zig");
|
||||
|
||||
const c = @cImport({
|
||||
@cInclude("glad/glad.h");
|
||||
@cInclude("GLFW/glfw3.h");
|
||||
});
|
||||
const AutoHashMap = std.AutoHashMap;
|
||||
|
||||
const Error = error {
|
||||
WindowNotInitialized,
|
||||
WindowAlreadyInitialized,
|
||||
NoScene,
|
||||
AlreadyRunning
|
||||
};
|
||||
|
||||
pub const Debug = struct {
|
||||
pub var CAMERA = true;
|
||||
};
|
||||
|
||||
var mouse_x: i32 = 0;
|
||||
var mouse_y: i32 = 0;
|
||||
var hovered: bool = true;
|
||||
var window: ?*c.GLFWwindow = null;
|
||||
var current_scene: ?Scene = null;
|
||||
var next_scene: ?Scene = null;
|
||||
var projection: Matrix4f = undefined;
|
||||
pub var mouse_pos: ?Vec2i = null;
|
||||
|
||||
fn glfw_on_error(err: c_int, desc_c: [*c]const u8) callconv(.C) void {
|
||||
const desc: *const u8 = @ptrCast(desc_c);
|
||||
std.log.err("[Engine:glfw_on_error] glfw error {x:0>8}: {s}\n", .{ err, desc });
|
||||
}
|
||||
|
||||
fn glfw_on_resize(_: ?*c.GLFWwindow, width: c_int, height: c_int) callconv(.C) void {
|
||||
std.debug.print("[Engine:glfw_on_resize] {d} x {d}\n", .{ width, height });
|
||||
c.glViewport(0, 0, width, height);
|
||||
projection = Matrix4f.orthographic(0, @floatFromInt(width), @floatFromInt(height), 0, 0, 100);
|
||||
shaders.set_projection_matrix(&projection);
|
||||
if (current_scene != null) current_scene.?.resize(width, height);
|
||||
}
|
||||
|
||||
fn glfw_on_mouse_move(_: ?*c.GLFWwindow, fx: f64, fy: f64) callconv(.C) void {
|
||||
const x: i32 = @intFromFloat(fx);
|
||||
const y: i32 = @intFromFloat(fy);
|
||||
mouse_pos = Vec2i { .x = x, .y = y };
|
||||
if (current_scene != null and hovered) {
|
||||
current_scene.?.mouse_move(x, y);
|
||||
}
|
||||
}
|
||||
|
||||
fn glfw_on_mouse_enter(_: ?*c.GLFWwindow, mouse_within: c_int) callconv(.C) void {
|
||||
hovered = mouse_within == c.GLFW_TRUE;
|
||||
if (!hovered) mouse_pos = null;
|
||||
}
|
||||
|
||||
fn glfw_on_mouse_button(_: ?*c.GLFWwindow, button: i32, pressed: i32, _: i32) callconv(.C) void {
|
||||
// std.debug.print("[Engine:glfw_on_mouse_button] {}, {}, {}\n", .{ x, y, z });
|
||||
if (current_scene != null) {
|
||||
if (pressed == c.GLFW_TRUE) {
|
||||
current_scene.?.mouse_down(button);
|
||||
} else {
|
||||
current_scene.?.mouse_up(button);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn get_window_size() struct { i32, i32 } {
|
||||
var width: c_int = undefined;
|
||||
var height: c_int = undefined;
|
||||
c.glfwGetFramebufferSize(window, @ptrCast(&width), @ptrCast(&height));
|
||||
return .{ width, height };
|
||||
}
|
||||
|
||||
pub fn setup() !void {
|
||||
if (window != null) return Error.WindowAlreadyInitialized;
|
||||
|
||||
// in case of errors, set callback early!
|
||||
// for some reason this returns an error function as well??
|
||||
_ = c.glfwSetErrorCallback(glfw_on_error);
|
||||
|
||||
// initialize glfw capabilities & cleanup
|
||||
if (c.glfwInit() != 1) {
|
||||
std.log.err("Failed to init glfw", .{});
|
||||
return error.Initialization;
|
||||
}
|
||||
|
||||
// ensure glfw knows what we're about
|
||||
// c.glfwWindowHint(c.GLFW_CONTEXT_VERSION_MAJOR, 3);
|
||||
c.glfwDefaultWindowHints();
|
||||
c.glfwWindowHint(c.GLFW_SAMPLES, 4);
|
||||
// c.glfwWindowHint(c.GLFW_CONTEXT_VERSION_MINOR, 3);
|
||||
// c.glfwWindowHint(c.GLFW_OPENGL_PROFILE, c.GLFW_OPENGL_CORE_PROFILE);
|
||||
|
||||
// create the window & cleanup
|
||||
window = c.glfwCreateWindow(1920, 1080, "Hadean, maybe", null, null) orelse {
|
||||
std.log.err("Failed to open window", .{});
|
||||
return error.Initialization;
|
||||
};
|
||||
|
||||
// load opengl into the window
|
||||
c.glfwMakeContextCurrent(window);
|
||||
if (c.gladLoadGL() != 1) {
|
||||
std.log.err("Failed to load GL context", .{});
|
||||
return error.Initialization;
|
||||
}
|
||||
|
||||
// configure the context!
|
||||
c.glfwSwapInterval(1);
|
||||
|
||||
// compile shaders...
|
||||
try shaders.load();
|
||||
try assets.load();
|
||||
|
||||
_ = c.glfwSetWindowSizeCallback(window, glfw_on_resize);
|
||||
_ = c.glfwSetCursorPosCallback(window, glfw_on_mouse_move);
|
||||
_ = c.glfwSetCursorEnterCallback(window, glfw_on_mouse_enter);
|
||||
_ = c.glfwSetMouseButtonCallback(window, glfw_on_mouse_button);
|
||||
|
||||
const clearBrightness: f32 = 0.09;
|
||||
c.glClearColor(clearBrightness, clearBrightness, clearBrightness, 1.0);
|
||||
// c.glEnable(c.GL_MULTISAMPLE);
|
||||
c.glDisable(c.GL_MULTISAMPLE);
|
||||
c.glEnable(c.GL_BLEND);
|
||||
c.glBlendFunc(c.GL_SRC_ALPHA, c.GL_ONE_MINUS_SRC_ALPHA);
|
||||
c.glEnable(c.GL_DEPTH_TEST);
|
||||
c.glDepthFunc(c.GL_LEQUAL);
|
||||
c.glDepthMask(c.GL_TRUE);
|
||||
|
||||
const width, const height = get_window_size();
|
||||
c.glViewport(0, 0, width, height);
|
||||
projection = Matrix4f.orthographic(0, @floatFromInt(width), @floatFromInt(height), 0, 0, 100);
|
||||
shaders.set_projection_matrix(&projection);
|
||||
}
|
||||
|
||||
pub fn destroy() void {
|
||||
c.glfwDestroyWindow(window);
|
||||
c.glfwTerminate();
|
||||
}
|
||||
|
||||
pub fn set_scene(scene: Scene) void {
|
||||
next_scene = scene;
|
||||
}
|
||||
|
||||
pub fn run() !void {
|
||||
if (window == null) return Error.WindowNotInitialized;
|
||||
if (current_scene != null) return Error.AlreadyRunning;
|
||||
if (next_scene == null) return Error.NoScene;
|
||||
|
||||
// run the main loop
|
||||
while (c.glfwWindowShouldClose(window) == 0) {
|
||||
// switch scenes if need be
|
||||
if (next_scene != null) {
|
||||
if (current_scene != null) current_scene.?.destroy();
|
||||
current_scene = next_scene;
|
||||
next_scene = null;
|
||||
// start our scene
|
||||
try current_scene.?.start();
|
||||
// and send it the appropriate resize.
|
||||
const width, const height = get_window_size();
|
||||
current_scene.?.resize(width, height);
|
||||
if(hovered) {
|
||||
current_scene.?.mouse_enter();
|
||||
current_scene.?.mouse_move(mouse_x, mouse_y);
|
||||
}
|
||||
}
|
||||
// setup for drawing
|
||||
c.glClear(c.GL_COLOR_BUFFER_BIT | c.GL_DEPTH_BUFFER_BIT);
|
||||
current_scene.?.draw();
|
||||
c.glFlush();
|
||||
|
||||
c.glfwSwapBuffers(window);
|
||||
c.glfwPollEvents();
|
||||
|
||||
current_scene.?.update(0.0042);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,46 +0,0 @@
|
|||
const Rectf = @import("geometry/Rectf.zig");
|
||||
const Recti = @import("geometry/Recti.zig");
|
||||
const Vec2f = @import("geometry/Vec2f.zig");
|
||||
const Color = @import("Color.zig");
|
||||
const Texture = @import("Texture.zig");
|
||||
const Layer = @import("Layer.zig");
|
||||
const shaders = @import("shaders.zig");
|
||||
const c = @cImport({
|
||||
@cInclude("glad/glad.h");
|
||||
@cInclude("GLFW/glfw3.h");
|
||||
});
|
||||
const Sprite = @This();
|
||||
|
||||
texture_area: Rectf = undefined,
|
||||
texture: *const Texture = undefined,
|
||||
|
||||
pub fn create(tex: *const Texture, rect: Recti) Sprite {
|
||||
return .{
|
||||
.texture_area = rect.scalef(Vec2f.create(
|
||||
@floatFromInt(tex.width),
|
||||
@floatFromInt(tex.height)
|
||||
)),
|
||||
.texture = tex,
|
||||
};
|
||||
}
|
||||
|
||||
pub fn draw(self: *const Sprite, screen_pos: Recti, layer: Layer, color: Color) void {
|
||||
self.texture.bind(c.GL_TEXTURE0);
|
||||
shaders.enable_textures();
|
||||
c.glBegin(c.GL_QUADS);
|
||||
{
|
||||
c.glVertexAttrib2f(shaders.TEXCOORD_ATTRIBUTE_ID, self.texture_area.a.x, self.texture_area.a.y);
|
||||
c.glVertexAttrib4f(shaders.COLOR_ATTRIBUTE_ID, color.r, color.g, color.b, color.a);
|
||||
c.glVertex3i(screen_pos.a.x, screen_pos.a.y, layer.z_index);
|
||||
c.glVertexAttrib2f(shaders.TEXCOORD_ATTRIBUTE_ID, self.texture_area.b.x, self.texture_area.a.y);
|
||||
c.glVertexAttrib4f(shaders.COLOR_ATTRIBUTE_ID, color.r, color.g, color.b, color.a);
|
||||
c.glVertex3i(screen_pos.b.x, screen_pos.a.y, layer.z_index);
|
||||
c.glVertexAttrib2f(shaders.TEXCOORD_ATTRIBUTE_ID, self.texture_area.b.x, self.texture_area.b.y);
|
||||
c.glVertexAttrib4f(shaders.COLOR_ATTRIBUTE_ID, color.r, color.g, color.b, color.a);
|
||||
c.glVertex3i(screen_pos.b.x, screen_pos.b.y, layer.z_index);
|
||||
c.glVertexAttrib2f(shaders.TEXCOORD_ATTRIBUTE_ID, self.texture_area.a.x, self.texture_area.b.y);
|
||||
c.glVertexAttrib4f(shaders.COLOR_ATTRIBUTE_ID, color.r, color.g, color.b, color.a);
|
||||
c.glVertex3i(screen_pos.a.x, screen_pos.b.y, layer.z_index);
|
||||
}
|
||||
c.glEnd();
|
||||
}
|
||||
|
|
@ -1,71 +0,0 @@
|
|||
const c = @cImport({
|
||||
// @cInclude("png.h");
|
||||
@cInclude("spng.h");
|
||||
// @cInclude("zlib.h");
|
||||
// @cInclude("stdio.h");
|
||||
|
||||
@cInclude("glad/glad.h");
|
||||
@cInclude("GLFW/glfw3.h");
|
||||
});
|
||||
const std = @import("std");
|
||||
const File = std.fs.File;
|
||||
const Dir = std.fs.Dir;
|
||||
const heap = std.heap.page_allocator;
|
||||
|
||||
const Texture = @This();
|
||||
|
||||
const Error = error {
|
||||
Fuck
|
||||
};
|
||||
|
||||
handle: u32,
|
||||
width: u32,
|
||||
height: u32,
|
||||
|
||||
pub fn bind(self: *const Texture, unit: u32) void {
|
||||
c.glActiveTexture(unit);
|
||||
c.glBindTexture(c.GL_TEXTURE_2D, self.handle);
|
||||
}
|
||||
|
||||
pub fn create(path: []const u8) !Texture {
|
||||
|
||||
var file = try std.fs.cwd().openFile(path, .{});
|
||||
defer file.close();
|
||||
|
||||
const file_size = (try file.stat()).size;
|
||||
const buffer: []u8 = try heap.alloc(u8, file_size);
|
||||
defer heap.free(buffer);
|
||||
const reader = file.reader();
|
||||
_ = try reader.readAll(buffer);
|
||||
|
||||
const context = c.spng_ctx_new(0);
|
||||
defer c.spng_ctx_free(context);
|
||||
_ = c.spng_set_png_buffer(context, @ptrCast(buffer), buffer.len);
|
||||
|
||||
var out_size: usize = undefined;
|
||||
_ = c.spng_decoded_image_size(context, c.SPNG_FMT_RGBA8, &out_size);
|
||||
const out_buf: []u8 = try heap.alloc(u8, out_size);
|
||||
defer heap.free(out_buf);
|
||||
_ = c.spng_decode_image(context, @ptrCast(out_buf), out_size, c.SPNG_FMT_RGBA8, 0);
|
||||
var ihdr = c.struct_spng_ihdr {};
|
||||
_ = c.spng_get_ihdr(context, &ihdr);
|
||||
|
||||
var tex_id: u32 = undefined;
|
||||
c.glGenTextures(1, &tex_id);
|
||||
c.glBindTexture(c.GL_TEXTURE_2D, tex_id);
|
||||
c.glActiveTexture(c.GL_TEXTURE0);
|
||||
c.glTexParameteri(c.GL_TEXTURE_2D, c.GL_TEXTURE_MIN_FILTER, c.GL_NEAREST);
|
||||
c.glTexParameteri(c.GL_TEXTURE_2D, c.GL_TEXTURE_MAG_FILTER, c.GL_NEAREST);
|
||||
c.glTexImage2D(c.GL_TEXTURE_2D, 0, c.GL_RGBA, @intCast(ihdr.width), @intCast(ihdr.height), 0, c.GL_RGBA, c.GL_UNSIGNED_BYTE, @ptrCast(out_buf));
|
||||
c.glBindTexture(c.GL_TEXTURE_2D, 0);
|
||||
|
||||
std.debug.print("[Texture:create] texture generated: ID={} Path={s}\n", .{ tex_id, path });
|
||||
|
||||
return .{
|
||||
.handle = @intCast(tex_id),
|
||||
.width = ihdr.width,
|
||||
.height = ihdr.height,
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
|
||||
const c = @cImport({
|
||||
@cInclude("SDL3/SDL.h");
|
||||
@cInclude("SDL3_image/SDL_image.h");
|
||||
@cInclude("OpenSimplex2F.h");
|
||||
});
|
||||
|
||||
pub usingnamespace c;
|
||||
|
|
@ -0,0 +1,90 @@
|
|||
const std = @import("std");
|
||||
const Recti = @import("geometry/Recti.zig");
|
||||
const Matrix4f = @import("geometry/Matrix4f.zig");
|
||||
const Layer = @import("Layer.zig");
|
||||
const Color = @import("Color.zig");
|
||||
const Scene = @import("Scene.zig");
|
||||
const Vec2i = @import("geometry/Vec2i.zig");
|
||||
const c = @import("c");
|
||||
|
||||
const SDL_GetError = c.SDL_GetError;
|
||||
const SDL_Log = c.SDL_Log;
|
||||
|
||||
const SDL_Init = c.SDL_Init;
|
||||
const SDL_INIT_VIDEO = c.SDL_INIT_VIDEO;
|
||||
|
||||
const SDL_PollEvent = c.SDL_PollEvent;
|
||||
const SDL_Event = c.SDL_Event;
|
||||
const SDL_EVENT_QUIT = c.SDL_EVENT_QUIT;
|
||||
|
||||
const SDL_SetRenderDrawColor = c.SDL_SetRenderDrawColor;
|
||||
const SDL_RenderClear = c.SDL_RenderClear;
|
||||
const SDL_RenderPresent = c.SDL_RenderPresent;
|
||||
const SDL_Quit = c.SDL_Quit;
|
||||
|
||||
pub const Error = error {
|
||||
WindowNotInitialized,
|
||||
WindowAlreadyInitialized,
|
||||
RendererNotInitialized,
|
||||
RendererAlreadyInitialized,
|
||||
NoScene,
|
||||
AlreadyRunning
|
||||
};
|
||||
|
||||
var window: ?*c.SDL_Window = null;
|
||||
var renderer: ?*c.SDL_Renderer = null;
|
||||
|
||||
var current_scene: ?Scene = null;
|
||||
var next_scene: ?Scene = null;
|
||||
var running: bool = false;
|
||||
|
||||
const LoaderFn = *const fn (*c.SDL_Window, *c.SDL_Renderer) void;
|
||||
var loader: ?LoaderFn = null;
|
||||
|
||||
pub fn setup() !void {
|
||||
if (window != null) return Error.WindowAlreadyInitialized;
|
||||
if (renderer != null) return Error.RendererAlreadyInitialized;
|
||||
|
||||
if (!SDL_Init(SDL_INIT_VIDEO)) {
|
||||
std.debug.panic("SDL failed to initialize with error: {s}", .{ SDL_GetError() });
|
||||
}
|
||||
if (!c.SDL_CreateWindowAndRenderer("SDL3", 800, 600, 0, &window, &renderer)) {
|
||||
std.debug.panic("SDL failed to initialize window or renderer with error: {s}", .{ SDL_GetError() });
|
||||
}
|
||||
if (loader) |loader_fn| {
|
||||
loader_fn(window.?, renderer.?);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn set_loader(loader_fn: LoaderFn) void {
|
||||
loader = loader_fn;
|
||||
}
|
||||
|
||||
pub fn destroy() void {
|
||||
SDL_Quit();
|
||||
}
|
||||
|
||||
pub fn set_scene(scene: Scene) void {
|
||||
next_scene = scene;
|
||||
}
|
||||
|
||||
pub fn run() !void {
|
||||
if (window == null) return Error.WindowNotInitialized;
|
||||
if (renderer == null) return Error.RendererNotInitialized;
|
||||
if (current_scene != null) return Error.AlreadyRunning;
|
||||
if (next_scene == null) return Error.NoScene;
|
||||
running = true;
|
||||
|
||||
var event: SDL_Event = undefined;
|
||||
while (running) {
|
||||
_ = c.SDL_SetRenderDrawColor(renderer, 127, 127, 127, 255);
|
||||
_ = c.SDL_RenderClear(renderer);
|
||||
_ = c.SDL_RenderPresent(renderer);
|
||||
|
||||
while(c.SDL_PollEvent(&event)) {
|
||||
if (event.type == c.SDL_EVENT_QUIT) {
|
||||
running = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,13 +1,15 @@
|
|||
const assets = @import("assets.zig");
|
||||
const Layer = @import("Layer.zig");
|
||||
const Color = @import("Color.zig");
|
||||
const Recti = @import("geometry/Recti.zig");
|
||||
const std = @import("std");
|
||||
const Tag = @import("Tag.zig");
|
||||
const Scene = @import("Scene.zig");
|
||||
|
||||
const Entity = @This();
|
||||
|
||||
const std = @import("std");
|
||||
const engine = @import("engine");
|
||||
const Tag = engine.Tag;
|
||||
const Scene = engine.Scene;
|
||||
const Recti = engine.geometry.Recti;
|
||||
const Layer = engine.Layer;
|
||||
|
||||
|
||||
|
||||
|
||||
const EntityOptions = struct {
|
||||
tag: Tag = Tag.NONE,
|
||||
};
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
const engine = @import("engine");
|
||||
const Vec2i = engine.geometry.Vec2i;
|
||||
|
||||
|
||||
|
||||
pub var mouse_pos: ?Vec2i = Vec2i.create(0, 0);
|
||||
|
|
@ -0,0 +1,120 @@
|
|||
|
||||
const std = @import("std");
|
||||
|
||||
pub fn create(comptime functions: anytype) type {
|
||||
|
||||
const functions_typeinfo = @typeInfo(@TypeOf(functions));
|
||||
|
||||
if (functions_typeinfo != .Struct)
|
||||
@compileError("Interface must be an anonymous struct type");
|
||||
|
||||
for (functions_typeinfo.Struct.fields) |field| {
|
||||
const function_type = @field(functions, field.name);
|
||||
if (@typeInfo(function_type) != .Fn) {
|
||||
@compileError("Interface must only have Fn fields.");
|
||||
}
|
||||
}
|
||||
|
||||
const VTable = comptime blk: {
|
||||
var fields: [functions_typeinfo.Struct.fields.len]std.builtin.Type.StructField = undefined;
|
||||
for (functions_typeinfo.Struct.fields, 0..) |field, idx| {
|
||||
const passed_function_type = @field(functions, field.name);
|
||||
const passed_function_typeinfo = @typeInfo(passed_function_type);
|
||||
|
||||
const function_typeinfo: std.builtin.Type = .{
|
||||
.Fn = .{
|
||||
.params = &[_]std.builtin.Type.Fn.Param {
|
||||
std.builtin.Type.Fn.Param {
|
||||
.type = *anyopaque,
|
||||
.is_generic = false,
|
||||
.is_noalias = false,
|
||||
},
|
||||
std.builtin.Type.Fn.Param {
|
||||
.type = std.meta.ArgsTuple(passed_function_type),
|
||||
.is_generic = false,
|
||||
.is_noalias = false,
|
||||
},
|
||||
},
|
||||
.is_var_args = passed_function_typeinfo.Fn.is_var_args,
|
||||
.is_generic = passed_function_typeinfo.Fn.is_generic,
|
||||
.return_type = passed_function_typeinfo.Fn.return_type,
|
||||
.calling_convention = passed_function_typeinfo.Fn.calling_convention,
|
||||
}
|
||||
};
|
||||
|
||||
const VTFunction = @Type(function_typeinfo);
|
||||
|
||||
fields[idx] = std.builtin.Type.StructField{
|
||||
.name = field.name,
|
||||
.type = *const VTFunction,
|
||||
.is_comptime = false,
|
||||
.default_value = null,
|
||||
.alignment = @alignOf(*const anyopaque),
|
||||
};
|
||||
}
|
||||
const VTableType = @Type(.{
|
||||
.Struct = .{
|
||||
.layout = .auto,
|
||||
.decls = &[0]std.builtin.Type.Declaration {},
|
||||
.fields = &fields,
|
||||
.is_tuple = false,
|
||||
}
|
||||
});
|
||||
|
||||
break :blk VTableType;
|
||||
};
|
||||
|
||||
return struct {
|
||||
const Self = @This();
|
||||
const VTableEnum = std.meta.FieldEnum(VTable);
|
||||
|
||||
ptr: *anyopaque,
|
||||
vtable: VTable = undefined,
|
||||
|
||||
pub fn call(
|
||||
self: *Self,
|
||||
comptime tag: VTableEnum,
|
||||
args: std.meta.ArgsTuple(@field(functions, @tagName(tag)))
|
||||
)
|
||||
@typeInfo(@field(functions, @tagName(tag))).Fn.return_type.?
|
||||
{
|
||||
return @call(.auto, @field(self.vtable, @tagName(tag)), .{ self.ptr, args });
|
||||
}
|
||||
|
||||
pub fn init(impl: anytype) Self {
|
||||
|
||||
const ImplPointer = @TypeOf(impl);
|
||||
const impl_typeinfo = @typeInfo(ImplPointer);
|
||||
|
||||
if (impl_typeinfo != .Pointer)
|
||||
@compileError("Cannot initialize interface for non-pointer type");
|
||||
if (impl_typeinfo.Pointer.size != .One)
|
||||
@compileError("Cannot initialize interface for multi-item pointer");
|
||||
if (impl_typeinfo.Pointer.is_const)
|
||||
@compileError("Cannot initialize interface for non-mutable pointer");
|
||||
if (@typeInfo(impl_typeinfo.Pointer.child) != .Struct)
|
||||
@compileError("Cannot initialize interface for pointer to non-struct");
|
||||
|
||||
const Impl = impl_typeinfo.Pointer.child;
|
||||
|
||||
const vtable = comptime blk: {
|
||||
var vtable: VTable = undefined;
|
||||
for (functions_typeinfo.Struct.fields) |field_type| {
|
||||
const Args = std.meta.ArgsTuple(@field(functions, field_type.name));
|
||||
const wrapper = struct {
|
||||
pub fn invoke(ptr: *anyopaque, args: Args) @typeInfo(@field(functions, field_type.name)).Fn.return_type.? {
|
||||
const self: ImplPointer = @ptrCast(@alignCast(ptr));
|
||||
return @call(.auto, @field(Impl, field_type.name), .{ self } ++ args);
|
||||
}
|
||||
};
|
||||
@field(vtable, field_type.name) = wrapper.invoke;
|
||||
}
|
||||
break :blk vtable;
|
||||
};
|
||||
const interface: Self = .{ .ptr = impl, .vtable = vtable };
|
||||
return interface;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -1,6 +1,4 @@
|
|||
const c = @cImport({
|
||||
@cInclude("OpenSimplex2F.h");
|
||||
});
|
||||
const c = @import("c");
|
||||
const std = @import("std");
|
||||
const ArrayList = std.ArrayList;
|
||||
const RealColor = @import("Color.zig");
|
||||
|
|
@ -1,11 +1,10 @@
|
|||
const Scene = @This();
|
||||
|
||||
const assets = @import("assets.zig");
|
||||
const Recti = @import("geometry/Recti.zig");
|
||||
const Layer = @import("Layer.zig");
|
||||
const Color = @import("Color.zig");
|
||||
const Entity = @import("Entity.zig");
|
||||
const Terrain = @import("Terrain.zig");
|
||||
const engine = @import("engine");
|
||||
const Entity = engine.Entity;
|
||||
const Vec2i = @import("geometry/Vec2i.zig");
|
||||
const Tag = @import("Tag.zig");
|
||||
const std = @import("std");
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
const Rectf = @import("geometry/Rectf.zig");
|
||||
const Recti = @import("geometry/Recti.zig");
|
||||
const Vec2f = @import("geometry/Vec2f.zig");
|
||||
const Color = @import("Color.zig");
|
||||
const Texture = @import("Texture.zig");
|
||||
const Layer = @import("Layer.zig");
|
||||
const Sprite = @This();
|
||||
|
||||
texture_area: Rectf = undefined,
|
||||
texture: *const Texture = undefined,
|
||||
|
||||
pub fn create(tex: *const Texture, rect: Recti) Sprite {
|
||||
return .{
|
||||
.texture_area = rect.scalef(Vec2f.create(
|
||||
@floatFromInt(tex.width),
|
||||
@floatFromInt(tex.height)
|
||||
)),
|
||||
.texture = tex,
|
||||
};
|
||||
}
|
||||
|
||||
pub fn draw(self: *const Sprite, screen_pos: Recti, layer: Layer, color: Color) void {
|
||||
_ = self;
|
||||
_ = screen_pos;
|
||||
_ = layer;
|
||||
_ = color;
|
||||
@panic("Not Implemented");
|
||||
}
|
||||
|
|
@ -0,0 +1,54 @@
|
|||
const Texture = @This();
|
||||
|
||||
const std = @import("std");
|
||||
const c = @import("c");
|
||||
|
||||
var gpa = std.heap.GeneralPurposeAllocator(.{}) {};
|
||||
// var gpa = Allocator {};
|
||||
var alloc = gpa.allocator();
|
||||
|
||||
// var alloc: std.mem.Allocator = (std.heap.GeneralPurposeAllocator(.{}) {}).allocator();
|
||||
var exe_dir: []const u8 = undefined;
|
||||
var exe_dir_valid = false;
|
||||
|
||||
handle: *c.SDL_Texture,
|
||||
width: u32,
|
||||
height: u32,
|
||||
|
||||
fn ensure_lazy_dir() void {
|
||||
if (!exe_dir_valid)
|
||||
exe_dir = std.fs.selfExeDirPathAlloc(alloc)
|
||||
catch @panic("Couldnt get directory of executable.");
|
||||
}
|
||||
|
||||
pub fn create(renderer: *c.SDL_Renderer, path: []const u8) Texture {
|
||||
ensure_lazy_dir();
|
||||
|
||||
// allocPrintZ includes null terminator! :D
|
||||
const new_path: [:0]const u8 = std.fmt.allocPrintZ(alloc, "{s}/../assets/{s}", .{ exe_dir, path })
|
||||
catch @panic("OOM");
|
||||
defer alloc.free(new_path);
|
||||
|
||||
// std.debug.print("{s} length {}\n", .{ new_path, new_path.len });
|
||||
|
||||
const io: *c.SDL_IOStream = c.SDL_IOFromFile(new_path, "r") orelse {
|
||||
std.debug.print("SDL Error: {s}\n", .{ c.SDL_GetError() });
|
||||
@panic("Failed to create IO for Texture");
|
||||
};
|
||||
const surface: *c.SDL_Surface = c.IMG_LoadPNG_IO(io) orelse {
|
||||
std.debug.print("SDL Error: {s}\n", .{ c.SDL_GetError() });
|
||||
@panic("Failed to create Surface for Texture");
|
||||
};
|
||||
const texture = c.SDL_CreateTextureFromSurface(renderer, surface) orelse {
|
||||
std.debug.print("SDL Error: {s}\n", .{ c.SDL_GetError() });
|
||||
@panic("Failed to create Texture");
|
||||
};
|
||||
|
||||
return .{
|
||||
.handle = texture,
|
||||
.width = @intCast(texture.*.w),
|
||||
.height = @intCast(texture.*.h),
|
||||
};
|
||||
}
|
||||
// *const fn (*const cimport.struct_SDL_Window, *const cimport.struct_SDL_Renderer) void
|
||||
// *const fn (*const cimport.struct_SDL_Window, *const cimport.struct_SDL_Renderer) void
|
||||
|
|
@ -0,0 +1,84 @@
|
|||
const std = @import("std");
|
||||
const engine = @import("engine");
|
||||
const Color = engine.Color;
|
||||
const Layer = engine.Layer;
|
||||
const Vec2i = engine.geometry.Vec2i;
|
||||
const Vec2f = engine.geometry.Vec2f;
|
||||
const Rectf = engine.geometry.Rectf;
|
||||
|
||||
const Recti = @This();
|
||||
|
||||
x: i32,
|
||||
y: i32,
|
||||
w: i32,
|
||||
h: i32,
|
||||
a: Vec2i,
|
||||
b: Vec2i,
|
||||
|
||||
pub fn from_xywh(x: i32, y: i32, w: i32, h: i32) Recti {
|
||||
return .{
|
||||
.x = x,
|
||||
.y = y,
|
||||
.w = w,
|
||||
.h = h,
|
||||
.a = Vec2i.create(x, y),
|
||||
.b = Vec2i.create(x + w, y + h),
|
||||
};
|
||||
}
|
||||
|
||||
pub fn from_ab(a: Vec2i, b: Vec2i) Recti {
|
||||
const tlx = @min(a.x, b.x);
|
||||
const tly = @min(a.y, b.y);
|
||||
const brx = @max(a.x, b.x);
|
||||
const bry = @max(a.y, b.y);
|
||||
const width = brx - tlx;
|
||||
const height = bry - tly;
|
||||
return .{
|
||||
.x = tlx,
|
||||
.y = tly,
|
||||
.w = width,
|
||||
.h = height,
|
||||
.a = Vec2i.create(tlx, tly),
|
||||
.b = Vec2i.create(brx, bry),
|
||||
};
|
||||
}
|
||||
|
||||
pub fn contains(self: *const Recti, point: Vec2i) bool {
|
||||
return point.x >= self.a.x
|
||||
and point.x < self.b.x
|
||||
and point.y >= self.a.y
|
||||
and point.y < self.b.y;
|
||||
}
|
||||
|
||||
pub fn to_rectf(self: *const Recti) Rectf {
|
||||
return Rectf.from_ab(
|
||||
self.a.to_vec2f(),
|
||||
self.b.to_vec2f()
|
||||
);
|
||||
}
|
||||
|
||||
pub fn scalef(self: *const Recti, scale: Vec2f) Rectf {
|
||||
return Rectf.from_xywh(
|
||||
@as(f32, @floatFromInt(self.x)) / scale.x,
|
||||
@as(f32, @floatFromInt(self.y)) / scale.y,
|
||||
@as(f32, @floatFromInt(self.w)) / scale.x,
|
||||
@as(f32, @floatFromInt(self.h)) / scale.y,
|
||||
);
|
||||
}
|
||||
|
||||
pub fn draw(self: *const Recti, layer: Layer, color: Color) void {
|
||||
self.draw_filled(layer, color.with_opacity(0.2));
|
||||
self.draw_outline(layer, color);
|
||||
}
|
||||
|
||||
pub fn draw_filled(self: *const Recti, layer: Layer, color: Color) void {
|
||||
_ = self;
|
||||
_ = layer;
|
||||
_ = color;
|
||||
}
|
||||
|
||||
pub fn draw_outline(self: *const Recti, layer: Layer, color: Color) void {
|
||||
_ = self;
|
||||
_ = layer;
|
||||
_ = color;
|
||||
}
|
||||
|
|
@ -2,12 +2,7 @@ const Vec2f = @This();
|
|||
const Vec2i = @import("Vec2i.zig");
|
||||
const Layer = @import("../Layer.zig");
|
||||
const Color = @import("../Color.zig");
|
||||
const shaders = @import("../shaders.zig");
|
||||
const std = @import("std");
|
||||
const c = @cImport({
|
||||
@cInclude("glad/glad.h");
|
||||
@cInclude("GLFW/glfw3.h");
|
||||
});
|
||||
|
||||
x: f32,
|
||||
y: f32,
|
||||
|
|
@ -27,25 +22,10 @@ pub fn to_vec2i(self: *const Vec2f) Vec2i {
|
|||
}
|
||||
|
||||
pub fn draw(self: *const Vec2f, radius: f32, layer: Layer, color: Color) void {
|
||||
shaders.disable_textures();
|
||||
|
||||
const segments = 8;
|
||||
|
||||
c.glBegin(c.GL_POLYGON);
|
||||
{
|
||||
for (0..segments) |segment| {
|
||||
const theta = (2.0 * std.math.pi * @as(f32, @floatFromInt(segment))) / segments;
|
||||
const x = radius * std.math.cos(theta);
|
||||
const y = radius * std.math.sin(theta);
|
||||
c.glVertexAttrib4f(shaders.COLOR_ATTRIBUTE_ID, color.r, color.g, color.b, color.a);
|
||||
c.glVertex3f(
|
||||
self.x + x,
|
||||
self.y + y,
|
||||
@as(f32, @floatFromInt(layer.z_index))
|
||||
);
|
||||
}
|
||||
}
|
||||
c.glEnd();
|
||||
_ = self;
|
||||
_ = radius;
|
||||
_ = layer;
|
||||
_ = color;
|
||||
}
|
||||
|
||||
pub const ZERO = create(0, 0);
|
||||
|
|
@ -4,12 +4,7 @@ const Recti = @import("Recti.zig");
|
|||
const Vec2f = @import("Vec2f.zig");
|
||||
const Layer = @import("../Layer.zig");
|
||||
const Color = @import("../Color.zig");
|
||||
const shaders = @import("../shaders.zig");
|
||||
const std = @import("std");
|
||||
const c = @cImport({
|
||||
@cInclude("glad/glad.h");
|
||||
@cInclude("GLFW/glfw3.h");
|
||||
});
|
||||
|
||||
x: i32,
|
||||
y: i32,
|
||||
|
|
@ -40,25 +35,10 @@ pub fn add(self: Vec2i, other: Vec2i) Vec2i {
|
|||
}
|
||||
|
||||
pub fn draw(self: *const Vec2i, radius: f32, layer: Layer, color: Color) void {
|
||||
shaders.disable_textures();
|
||||
|
||||
const segments = 8;
|
||||
|
||||
c.glBegin(c.GL_POLYGON);
|
||||
{
|
||||
for (0..segments) |segment| {
|
||||
const theta = (2.0 * std.math.pi * @as(f32, @floatFromInt(segment))) / segments;
|
||||
const x = radius * std.math.cos(theta);
|
||||
const y = radius * std.math.sin(theta);
|
||||
c.glVertexAttrib4f(shaders.COLOR_ATTRIBUTE_ID, color.r, color.g, color.b, color.a);
|
||||
c.glVertex3f(
|
||||
@as(f32, @floatFromInt(self.x)) + x,
|
||||
@as(f32, @floatFromInt(self.y)) + y,
|
||||
@as(f32, @floatFromInt(layer.z_index))
|
||||
);
|
||||
}
|
||||
}
|
||||
c.glEnd();
|
||||
_ = self;
|
||||
_ = radius;
|
||||
_ = layer;
|
||||
_ = color;
|
||||
}
|
||||
|
||||
pub fn to_vec2f(self: *const Vec2i) Vec2f {
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
|
||||
pub const Vec2f = @import("Vec2f.zig");
|
||||
pub const Vec2i = @import("Vec2i.zig");
|
||||
pub const Rectf = @import("Rectf.zig");
|
||||
pub const Recti = @import("Recti.zig");
|
||||
|
||||
pub const Matrix4f = @import("Matrix4f.zig");
|
||||
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
pub const Control = @import("Control.zig");
|
||||
pub const Scene = @import("Scene.zig");
|
||||
pub const Tag = @import("Tag.zig");
|
||||
pub const Layer = @import("Layer.zig");
|
||||
pub const Interface = @import("Interface.zig");
|
||||
pub const Entity = @import("Entity.zig");
|
||||
pub const Color = @import("Color.zig");
|
||||
pub const Noise = @import("Noise.zig");
|
||||
pub const Input = @import("Input.zig");
|
||||
pub const Sprite = @import("Sprite.zig");
|
||||
pub const Texture = @import("Texture.zig");
|
||||
|
||||
pub const geometry = @import("geometry/root.zig");
|
||||
|
||||
|
||||
pub const Debug = struct {
|
||||
pub const camera = false;
|
||||
};
|
||||
|
|
@ -1,137 +0,0 @@
|
|||
const Vec2i = @import("./Vec2i.zig");
|
||||
const Vec2f = @import("./Vec2f.zig");
|
||||
const Rectf = @import("./Rectf.zig");
|
||||
const std = @import("std");
|
||||
const c = @cImport({
|
||||
@cInclude("glad/glad.h");
|
||||
@cInclude("GLFW/glfw3.h");
|
||||
});
|
||||
|
||||
const Recti = @This();
|
||||
|
||||
x: i32,
|
||||
y: i32,
|
||||
w: i32,
|
||||
h: i32,
|
||||
a: Vec2i,
|
||||
b: Vec2i,
|
||||
|
||||
pub fn from_xywh(x: i32, y: i32, w: i32, h: i32) Recti {
|
||||
return .{
|
||||
.x = x,
|
||||
.y = y,
|
||||
.w = w,
|
||||
.h = h,
|
||||
.a = Vec2i.create(x, y),
|
||||
.b = Vec2i.create(x + w, y + h),
|
||||
};
|
||||
}
|
||||
|
||||
pub fn from_ab(a: Vec2i, b: Vec2i) Recti {
|
||||
const tlx = @min(a.x, b.x);
|
||||
const tly = @min(a.y, b.y);
|
||||
const brx = @max(a.x, b.x);
|
||||
const bry = @max(a.y, b.y);
|
||||
const width = brx - tlx;
|
||||
const height = bry - tly;
|
||||
return .{
|
||||
.x = tlx,
|
||||
.y = tly,
|
||||
.w = width,
|
||||
.h = height,
|
||||
.a = Vec2i.create(tlx, tly),
|
||||
.b = Vec2i.create(brx, bry),
|
||||
};
|
||||
}
|
||||
|
||||
pub fn contains(self: *const Recti, point: Vec2i) bool {
|
||||
return point.x >= self.a.x
|
||||
and point.x < self.b.x
|
||||
and point.y >= self.a.y
|
||||
and point.y < self.b.y;
|
||||
}
|
||||
|
||||
pub fn to_rectf(self: *const Recti) Rectf {
|
||||
return Rectf.from_ab(
|
||||
self.a.to_vec2f(),
|
||||
self.b.to_vec2f()
|
||||
);
|
||||
}
|
||||
|
||||
pub fn scalef(self: *const Recti, scale: Vec2f) Rectf {
|
||||
return Rectf.from_xywh(
|
||||
@as(f32, @floatFromInt(self.x)) / scale.x,
|
||||
@as(f32, @floatFromInt(self.y)) / scale.y,
|
||||
@as(f32, @floatFromInt(self.w)) / scale.x,
|
||||
@as(f32, @floatFromInt(self.h)) / scale.y,
|
||||
);
|
||||
}
|
||||
|
||||
const Color = @import("../Color.zig");
|
||||
const Layer = @import("../Layer.zig");
|
||||
const shaders = @import("../shaders.zig");
|
||||
const assets = @import("../assets.zig");
|
||||
|
||||
pub fn draw(self: *const Recti, layer: Layer, color: Color) void {
|
||||
self.draw_filled(layer, color.with_opacity(0.2));
|
||||
self.draw_outline(layer, color);
|
||||
}
|
||||
|
||||
pub fn draw_filled(self: *const Recti, layer: Layer, color: Color) void {
|
||||
shaders.disable_textures();
|
||||
|
||||
c.glBegin(c.GL_QUADS);
|
||||
|
||||
{
|
||||
c.glVertexAttrib4f(shaders.COLOR_ATTRIBUTE_ID, color.r, color.g, color.b, color.a);
|
||||
c.glVertex3i(self.a.x, self.a.y, layer.z_index);
|
||||
|
||||
c.glVertexAttrib4f(shaders.COLOR_ATTRIBUTE_ID, color.r, color.g, color.b, color.a);
|
||||
c.glVertex3i(self.b.x, self.a.y, layer.z_index);
|
||||
|
||||
c.glVertexAttrib4f(shaders.COLOR_ATTRIBUTE_ID, color.r, color.g, color.b, color.a);
|
||||
c.glVertex3i(self.b.x, self.b.y, layer.z_index);
|
||||
|
||||
c.glVertexAttrib4f(shaders.COLOR_ATTRIBUTE_ID, color.r, color.g, color.b, color.a);
|
||||
c.glVertex3i(self.a.x, self.b.y, layer.z_index);
|
||||
}
|
||||
|
||||
c.glEnd();
|
||||
}
|
||||
|
||||
pub fn draw_outline(self: *const Recti, layer: Layer, color: Color) void {
|
||||
|
||||
shaders.disable_textures();
|
||||
|
||||
c.glBegin(c.GL_LINES);
|
||||
{
|
||||
// top
|
||||
c.glVertexAttrib4f(shaders.COLOR_ATTRIBUTE_ID, color.r, color.g, color.b, color.a);
|
||||
c.glVertex3i(self.a.x, self.a.y, layer.z_index);
|
||||
|
||||
c.glVertexAttrib4f(shaders.COLOR_ATTRIBUTE_ID, color.r, color.g, color.b, color.a);
|
||||
c.glVertex3i(self.b.x, self.a.y, layer.z_index);
|
||||
|
||||
// right
|
||||
c.glVertexAttrib4f(shaders.COLOR_ATTRIBUTE_ID, color.r, color.g, color.b, color.a);
|
||||
c.glVertex3i(self.b.x, self.a.y, layer.z_index);
|
||||
|
||||
c.glVertexAttrib4f(shaders.COLOR_ATTRIBUTE_ID, color.r, color.g, color.b, color.a);
|
||||
c.glVertex3i(self.b.x, self.b.y, layer.z_index);
|
||||
|
||||
// bottom
|
||||
c.glVertexAttrib4f(shaders.COLOR_ATTRIBUTE_ID, color.r, color.g, color.b, color.a);
|
||||
c.glVertex3i(self.b.x, self.b.y, layer.z_index);
|
||||
|
||||
c.glVertexAttrib4f(shaders.COLOR_ATTRIBUTE_ID, color.r, color.g, color.b, color.a);
|
||||
c.glVertex3i(self.a.x, self.b.y, layer.z_index);
|
||||
|
||||
// left
|
||||
c.glVertexAttrib4f(shaders.COLOR_ATTRIBUTE_ID, color.r, color.g, color.b, color.a);
|
||||
c.glVertex3i(self.a.x, self.b.y, layer.z_index);
|
||||
|
||||
c.glVertexAttrib4f(shaders.COLOR_ATTRIBUTE_ID, color.r, color.g, color.b, color.a);
|
||||
c.glVertex3i(self.a.x, self.a.y, layer.z_index);
|
||||
}
|
||||
c.glEnd();
|
||||
}
|
||||
|
|
@ -1,22 +1,19 @@
|
|||
const Camera = @This();
|
||||
pub const TAG = @import("Tag.zig").create(Camera);
|
||||
|
||||
const std = @import("std");
|
||||
const Entity = @import("Entity.zig");
|
||||
const Scene = @import("Scene.zig");
|
||||
const Engine = @import("Engine.zig");
|
||||
const Sprite = @import("Sprite.zig");
|
||||
const Layer = @import("Layer.zig");
|
||||
const Color = @import("Color.zig");
|
||||
const Vec2i = @import("geometry/Vec2i.zig");
|
||||
const Vec2f = @import("geometry/Vec2f.zig");
|
||||
const Recti = @import("geometry/Recti.zig");
|
||||
const Rectf = @import("geometry/Rectf.zig");
|
||||
const shaders = @import("shaders.zig");
|
||||
const c = @cImport({
|
||||
@cInclude("glad/glad.h");
|
||||
@cInclude("GLFW/glfw3.h");
|
||||
});
|
||||
const engine = @import("engine");
|
||||
const Entity = engine.Entity;
|
||||
const Scene = engine.Scene;
|
||||
const Input = engine.Input;
|
||||
const Sprite = engine.Sprite;
|
||||
const Color = engine.Color;
|
||||
const Layer = engine.Layer;
|
||||
const Vec2i = engine.geometry.Vec2i;
|
||||
const Vec2f = engine.geometry.Vec2f;
|
||||
const Recti = engine.geometry.Recti;
|
||||
const Rectf = engine.geometry.Rectf;
|
||||
|
||||
pub const TAG = engine.Tag.create(Camera);
|
||||
|
||||
// focus: Vec2i = Vec2i.EAST.scale(100),
|
||||
focus: Vec2f = Vec2f.ZERO,
|
||||
|
|
@ -28,33 +25,17 @@ drag_pos: ?Vec2i = null,
|
|||
drag_focus: ?Vec2f = null,
|
||||
|
||||
fn draw_line_vec2i(a: Vec2i, b: Vec2i, layer: Layer, color: Color) void {
|
||||
shaders.disable_textures();
|
||||
|
||||
c.glBegin(c.GL_LINES);
|
||||
{
|
||||
c.glVertexAttrib4f(shaders.COLOR_ATTRIBUTE_ID, color.r, color.g, color.b, color.a);
|
||||
c.glVertex3i(a.x, a.y, layer.z_index);
|
||||
|
||||
c.glVertexAttrib4f(shaders.COLOR_ATTRIBUTE_ID, color.r, color.g, color.b, color.a);
|
||||
c.glVertex3i(b.x, b.y, layer.z_index);
|
||||
}
|
||||
|
||||
c.glEnd();
|
||||
_ = a;
|
||||
_ = b;
|
||||
_ = layer;
|
||||
_ = color;
|
||||
}
|
||||
|
||||
fn draw_line_vec2f(a: Vec2f, b: Vec2f, layer: Layer, color: Color) void {
|
||||
shaders.disable_textures();
|
||||
|
||||
c.glBegin(c.GL_LINES);
|
||||
{
|
||||
c.glVertexAttrib4f(shaders.COLOR_ATTRIBUTE_ID, color.r, color.g, color.b, color.a);
|
||||
c.glVertex3f(a.x, a.y, @as(f32, @floatFromInt(layer.z_index)));
|
||||
|
||||
c.glVertexAttrib4f(shaders.COLOR_ATTRIBUTE_ID, color.r, color.g, color.b, color.a);
|
||||
c.glVertex3f(b.x, b.y, @as(f32, @floatFromInt(layer.z_index)));
|
||||
}
|
||||
|
||||
c.glEnd();
|
||||
_ = a;
|
||||
_ = b;
|
||||
_ = layer;
|
||||
_ = color;
|
||||
}
|
||||
|
||||
pub fn create() !*Camera {
|
||||
|
|
@ -78,10 +59,10 @@ pub fn entity(self: *Camera) Entity {
|
|||
}
|
||||
|
||||
pub fn update(self: *Camera, _: f32) void {
|
||||
if (self.drag_pos != null and self.drag_focus != null and Engine.mouse_pos != null) {
|
||||
if (self.drag_pos != null and self.drag_focus != null and Input.mouse_pos != null) {
|
||||
// new focus = OG focus + difference between drag start and drag now
|
||||
const drag_start_world = self.screen_to_world_vec2i(self.drag_pos.?);
|
||||
const drag_current_world = self.screen_to_world_vec2i(Engine.mouse_pos.?);
|
||||
const drag_current_world = self.screen_to_world_vec2i(Input.mouse_pos.?);
|
||||
|
||||
self.focus = Vec2f {
|
||||
.x = self.drag_focus.?.x + (drag_start_world.x - drag_current_world.x),
|
||||
|
|
@ -91,10 +72,10 @@ pub fn update(self: *Camera, _: f32) void {
|
|||
}
|
||||
|
||||
pub fn draw(self: *const Camera) void {
|
||||
if (Engine.Debug.CAMERA and self.drag_pos != null and self.drag_focus != null) {
|
||||
if(Engine.mouse_pos != null) {
|
||||
draw_line_vec2i(self.drag_pos.?, Engine.mouse_pos.?, Layer.CAMERA, Color.WHITE);
|
||||
Engine.mouse_pos.?.draw(4, Layer.CAMERA, Color.CYAN);
|
||||
if (engine.Debug.camera and self.drag_pos != null and self.drag_focus != null) {
|
||||
if(Input.mouse_pos != null) {
|
||||
draw_line_vec2i(self.drag_pos.?, Input.mouse_pos.?, Layer.CAMERA, Color.WHITE);
|
||||
Input.mouse_pos.?.draw(4, Layer.CAMERA, Color.CYAN);
|
||||
}
|
||||
self.drag_pos.?.draw(4, Layer.CAMERA, Color.RED);
|
||||
|
||||
|
|
@ -170,8 +151,8 @@ pub fn mouse_area(_: *const Camera) Recti {
|
|||
pub fn mouse_down(self: *Camera, button: i32) bool {
|
||||
// middle mouse
|
||||
if (button == 2) {
|
||||
if (Engine.mouse_pos == null) return false;
|
||||
self.drag_pos = Engine.mouse_pos.?;
|
||||
if (Input.mouse_pos == null) return false;
|
||||
self.drag_pos = Input.mouse_pos.?;
|
||||
self.drag_focus = self.focus;
|
||||
return true;
|
||||
} else return false;
|
||||
|
|
@ -1,21 +1,26 @@
|
|||
const Selection = @This();
|
||||
|
||||
const Scene = @import("./Scene.zig");
|
||||
const Entity = @import("./Entity.zig");
|
||||
const Tag = @import("./Tag.zig");
|
||||
const Layer = @import("./Layer.zig");
|
||||
const Engine = @import("./Engine.zig");
|
||||
const Recti = @import("./geometry/Recti.zig");
|
||||
const std = @import("std");
|
||||
const engine = @import("engine");
|
||||
const Recti = engine.geometry.Recti;
|
||||
const Rectf = engine.geometry.Rectf;
|
||||
const Tag = engine.Tag;
|
||||
const Scene = engine.Scene;
|
||||
const Layer = engine.Layer;
|
||||
const Entity = engine.Entity;
|
||||
|
||||
const TAG = Tag.create(Selection);
|
||||
|
||||
selection: std.ArrayList(Selectable),
|
||||
const ISelectable = engine.Interface.create(.{
|
||||
.get_hitbox = fn () Rectf,
|
||||
});
|
||||
|
||||
selection: std.ArrayList(ISelectable),
|
||||
focused: bool = false,
|
||||
|
||||
pub fn create() !*Selection {
|
||||
return try Scene.EntityPool.allocate(Selection {
|
||||
.selection = std.ArrayList(Selectable).init(std.heap.page_allocator),
|
||||
.selection = std.ArrayList(ISelectable).init(std.heap.page_allocator),
|
||||
});
|
||||
}
|
||||
|
||||
|
|
@ -51,15 +56,3 @@ pub fn mouse_move(_: *Selection, _: i32, _: i32) void {
|
|||
// std.debug.print("[Selection:mouse_move] {}, {}\n", .{ x, y });
|
||||
}
|
||||
|
||||
const Selectable = struct {
|
||||
ptr: *anyopaque,
|
||||
|
||||
pub fn init(item: anytype) Selectable {
|
||||
// const target_type = @typeInfo(@TypeOf(item));
|
||||
// const MutablePointer = @typeInfo(@TypeOf(item));
|
||||
|
||||
return Selectable {
|
||||
.ptr = item
|
||||
};
|
||||
}
|
||||
};
|
||||
|
|
@ -1,19 +1,22 @@
|
|||
const Terrain = @This();
|
||||
const assets = @import("assets.zig");
|
||||
const Layer = @import("Layer.zig");
|
||||
const Color = @import("Color.zig");
|
||||
const Recti = @import("geometry/Recti.zig");
|
||||
const Vec2f = @import("geometry/Vec2f.zig");
|
||||
const Vec2i = @import("geometry/Vec2i.zig");
|
||||
const Entity = @import("Entity.zig");
|
||||
const Scene = @import("Scene.zig");
|
||||
const Camera = @import("Camera.zig");
|
||||
|
||||
const engine = @import("engine");
|
||||
const Scene = engine.Scene;
|
||||
const Entity = engine.Entity;
|
||||
const Vec2i = engine.geometry.Vec2i;
|
||||
const Color = engine.Color;
|
||||
const Recti = engine.geometry.Recti;
|
||||
const Noise = engine.Noise;
|
||||
const Layer = engine.Layer;
|
||||
|
||||
const std = @import("std");
|
||||
const allocator = std.heap.page_allocator;
|
||||
var prng = std.rand.DefaultPrng.init(0);
|
||||
const Noise = @import("Noise.zig");
|
||||
|
||||
const TAG = @import("Tag.zig").create(Terrain);
|
||||
const Camera = @import("Camera.zig");
|
||||
const assets = @import("assets.zig");
|
||||
|
||||
const TAG = @import("engine").Tag.create(Terrain);
|
||||
|
||||
pub const CHUNK_SIZE = 48;
|
||||
const CHUNK_LENGTH = CHUNK_SIZE * CHUNK_SIZE;
|
||||
|
|
@ -1,7 +1,9 @@
|
|||
const Texture = @import("Texture.zig");
|
||||
const Sprite = @import("Sprite.zig");
|
||||
const Recti = @import("geometry/Recti.zig");
|
||||
const engine = @import("engine");
|
||||
const Texture = engine.Texture;
|
||||
const Sprite = engine.Sprite;
|
||||
const Recti = engine.geometry.Recti;
|
||||
const std = @import("std");
|
||||
const c = @import("c");
|
||||
|
||||
const Assets = struct {
|
||||
tree: Sprite,
|
||||
|
|
@ -18,11 +20,10 @@ inline fn make8 (x: i32, y: i32, w: i32, h: i32) Sprite {
|
|||
return Sprite.create(&texture, Recti.from_xywh(x * 8, y * 8, w * 8, h * 8));
|
||||
}
|
||||
|
||||
pub fn load() !void {
|
||||
pub fn load(window: *c.SDL_Window, renderer: *c.SDL_Renderer) void {
|
||||
_ = window;
|
||||
|
||||
// @compileLog(@TypeOf(terrain));
|
||||
|
||||
texture = try Texture.create("textures.png");
|
||||
texture = Texture.create(renderer, "textures.png");
|
||||
|
||||
assets = .{
|
||||
.tree = make8(27, 4, 1, 2),
|
||||
|
|
@ -59,13 +60,28 @@ pub const tree: *const Sprite = &assets.tree;
|
|||
pub const heart: *const Sprite = &assets.heart;
|
||||
pub const pawn: *const Sprite = &assets.pawn;
|
||||
pub const terrain = [4]*const [4]*const Sprite {
|
||||
// make pointers turns an array of things into an array
|
||||
// of pointers to those things.
|
||||
// my question, is, why does this need to happen?
|
||||
// in theory, all these public exported things are
|
||||
// pointers because they need to be const and point to
|
||||
// the var stuff stored above. thats fine, but, why cant
|
||||
// we just have a const pointer to the array itself?
|
||||
// *const [4][4]Sprite?
|
||||
// i assume a const pointer into an array doesnt let
|
||||
// you change the data in the array?
|
||||
&make_pointers(&assets.terrain[0]),
|
||||
&make_pointers(&assets.terrain[1]),
|
||||
&make_pointers(&assets.terrain[2]),
|
||||
&make_pointers(&assets.terrain[3]),
|
||||
};
|
||||
// this type seems wrong?
|
||||
// i suppose its still a pointer to a sprite, but is it not a pointer
|
||||
// to a const array of sprites?
|
||||
//
|
||||
// pub const rocks: *const [4]Sprite = &assets.rocks;
|
||||
pub const rocks: *const Sprite = make_pointers(&assets.rocks);
|
||||
|
||||
// this new one builds fine?
|
||||
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
|
||||
const std = @import("std");
|
||||
const Engine = @import("engine");
|
||||
// const assets = @import("assets.zig");
|
||||
const scenes = @import("scenes.zig");
|
||||
const assets = @import("assets.zig");
|
||||
|
||||
pub fn main() !void {
|
||||
Engine.Control.set_loader(assets.load);
|
||||
try Engine.Control.setup();
|
||||
defer Engine.Control.destroy();
|
||||
|
||||
Engine.Control.set_scene(try scenes.game());
|
||||
try Engine.Control.run();
|
||||
}
|
||||
|
|
@ -1,8 +1,8 @@
|
|||
const Scene = @import("Scene.zig");
|
||||
const Terrain = @import("Terrain.zig");
|
||||
const Pawn = @import("Pawn.zig");
|
||||
const engine = @import("engine");
|
||||
const Scene = engine.Scene;
|
||||
const Camera = @import("Camera.zig");
|
||||
const Selection = @import("Selection.zig");
|
||||
const Terrain = @import("Terrain.zig");
|
||||
|
||||
pub fn game() !Scene {
|
||||
var scene = Scene.create();
|
||||
13
src/main.zig
13
src/main.zig
|
|
@ -1,13 +0,0 @@
|
|||
|
||||
const std = @import("std");
|
||||
const Engine = @import("Engine.zig");
|
||||
// const assets = @import("assets.zig");
|
||||
const scenes = @import("scenes.zig");
|
||||
|
||||
pub fn main() !void {
|
||||
// engine.preload(assets.load);
|
||||
try Engine.setup();
|
||||
Engine.set_scene(try scenes.game());
|
||||
try Engine.run();
|
||||
Engine.destroy();
|
||||
}
|
||||
|
|
@ -1,6 +0,0 @@
|
|||
const std = @import("std");
|
||||
|
||||
export fn add(a: i32, b: i32) i32 {
|
||||
return a + b;
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue