diff --git a/build.gradle.kts b/build.gradle.kts index 9b67b7e..7761093 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -1,4 +1,14 @@ import org.jetbrains.kotlin.gradle.tasks.KotlinCompile +import org.gradle.internal.os.OperatingSystem.* + +val lwjglVersion = "3.2.3" + +val lwjglNatives = when (current()) { + LINUX -> "natives-linux" + MAC_OS -> "natives-macos" + WINDOWS -> "natives-windows" + else -> throw Error("Unrecognized or unsupported Operating system. Please set \"lwjglNatives\" manually") +} plugins { kotlin("jvm") version "1.4.10" @@ -10,6 +20,22 @@ repositories { mavenCentral() } +dependencies { + implementation(platform("org.lwjgl:lwjgl-bom:$lwjglVersion")) + + implementation("org.lwjgl", "lwjgl") + implementation("org.lwjgl", "lwjgl-glfw") + implementation("org.lwjgl", "lwjgl-opengl") + implementation("org.lwjgl", "lwjgl-stb") + runtimeOnly("org.lwjgl", "lwjgl", classifier = lwjglNatives) + runtimeOnly("org.lwjgl", "lwjgl-glfw", classifier = lwjglNatives) + runtimeOnly("org.lwjgl", "lwjgl-opengl", classifier = lwjglNatives) + runtimeOnly("org.lwjgl", "lwjgl-stb", classifier = lwjglNatives) +} + tasks.withType() { - kotlinOptions.jvmTarget = "1.8" + kotlinOptions { + jvmTarget = "1.8" + freeCompilerArgs = listOf("-Xallow-result-return-type") + } } \ No newline at end of file diff --git a/src/main/kotlin/Kape.kt b/src/main/kotlin/Kape.kt deleted file mode 100644 index 52ec9da..0000000 --- a/src/main/kotlin/Kape.kt +++ /dev/null @@ -1,5 +0,0 @@ -class Kape { - - - -} \ No newline at end of file diff --git a/src/main/kotlin/me/zeroeightsix/kape/Kape.kt b/src/main/kotlin/me/zeroeightsix/kape/Kape.kt new file mode 100644 index 0000000..a07c956 --- /dev/null +++ b/src/main/kotlin/me/zeroeightsix/kape/Kape.kt @@ -0,0 +1,7 @@ +package me.zeroeightsix.kape + +class Kape { + + + +} \ No newline at end of file diff --git a/src/main/kotlin/me/zeroeightsix/kape/math/Vec2.kt b/src/main/kotlin/me/zeroeightsix/kape/math/Vec2.kt new file mode 100644 index 0000000..d1903e5 --- /dev/null +++ b/src/main/kotlin/me/zeroeightsix/kape/math/Vec2.kt @@ -0,0 +1,7 @@ +package me.zeroeightsix.kape.math + +class Vec2(val x: T, val y: T) + +typealias Vec2f = Vec2 +typealias Vec2d = Vec2 +typealias Vec2i = Vec2 \ No newline at end of file diff --git a/src/main/kotlin/me/zeroeightsix/kape/window/GlfwWindow.kt b/src/main/kotlin/me/zeroeightsix/kape/window/GlfwWindow.kt new file mode 100644 index 0000000..e6a30a1 --- /dev/null +++ b/src/main/kotlin/me/zeroeightsix/kape/window/GlfwWindow.kt @@ -0,0 +1,68 @@ +package me.zeroeightsix.kape.window + +import me.zeroeightsix.kape.math.Vec2 +import me.zeroeightsix.kape.math.Vec2i +import org.lwjgl.glfw.Callbacks.glfwFreeCallbacks +import org.lwjgl.glfw.GLFW +import org.lwjgl.glfw.GLFW.* +import org.lwjgl.glfw.GLFWKeyCallback +import org.lwjgl.system.MemoryUtil.NULL + +private fun Boolean.asGlfwBool() = if (this) GLFW_TRUE else GLFW_FALSE + +class GlfwWindow private constructor(private val handle: Long) { + + fun freeCallbacks() = glfwFreeCallbacks(this.handle) + fun destroy() = glfwDestroyWindow(this.handle) + + fun freeAndDestroy() { + freeCallbacks() + destroy() + } + + companion object { + private fun installCallbacks(handle: Long) { + glfwSetKeyCallback(handle, glfwKeyCallback { window, key, scancode, action, mods -> + println("$window: $key#$scancode ($action) mods $mods") + }) + } + + fun fromHandle(handle: Long, installCallbacks: Boolean = true) = + GlfwWindow(handle).also { if (installCallbacks) installCallbacks(it.handle) } + + fun createWindow( + title: String = "me.zeroeightsix.kape.Kape window", + makeVisible: Boolean = true, + resizable: Boolean = true, + size: Vec2i = Vec2(300, 300) + ): Result { + if (!glfwInit()) return Result.failure(IllegalStateException("Unable to initialise GLFW")) + + glfwWindowHint(GLFW_VISIBLE, GLFW_FALSE) + glfwWindowHint(GLFW_RESIZABLE, resizable.asGlfwBool()) + val handle = glfwCreateWindow(size.x, size.y, title, NULL, NULL) + + if (handle == NULL) return Result.failure(IllegalStateException("Failed to create GLFW window!")) + + installCallbacks(handle) + + if (makeVisible) { + glfwShowWindow(handle) + } + + return Result.success(GlfwWindow(handle)) + } + + fun terminate() { + glfwTerminate() + glfwSetErrorCallback(null)?.free() + } + + private fun glfwKeyCallback(onInvoke: (Long, Int, Int, Int, Int) -> Unit) = object : GLFWKeyCallback() { + override fun invoke(window: Long, key: Int, scancode: Int, action: Int, mods: Int) { + onInvoke(window, key, scancode, action, mods) + } + } + } + +} \ No newline at end of file diff --git a/src/test/kotlin/Main.kt b/src/test/kotlin/Main.kt new file mode 100644 index 0000000..ba1444f --- /dev/null +++ b/src/test/kotlin/Main.kt @@ -0,0 +1,12 @@ +import me.zeroeightsix.kape.window.GlfwWindow + +fun main() { + + val window = GlfwWindow.createWindow().getOrThrow() + + Thread.sleep(1000) + println("Exiting") + window.destroy() + GlfwWindow.terminate() + +} \ No newline at end of file