diff --git a/build.gradle.kts b/build.gradle.kts index 8565a6b575..7fa7149d98 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -93,10 +93,3 @@ tasks { ) } } - -afterEvaluate { - println("-----------") - println(tasks.findByPath(":korge:jvmMainClasses")!!::class) - println(tasks.findByPath(":korge:compileKotlinJvm")!!::class) - //org.jetbrains.kotlin.gradle.tasks.KotlinCompile -} diff --git a/korge-core/src/korlibs/render/GameWindow.kt b/korge-core/src/korlibs/render/GameWindow.kt index 98500029b8..10d6a96ce8 100644 --- a/korge-core/src/korlibs/render/GameWindow.kt +++ b/korge-core/src/korlibs/render/GameWindow.kt @@ -43,6 +43,8 @@ data class GameWindowCreationConfig( val transparent: Boolean = false, /** Allows window to be resizable */ val resizable: Boolean = true, + /** */ + val title: String = "", //val allowMinimize: Boolean = true, //val allowMaximize: Boolean = true, ) { diff --git a/korge-core/src/korlibs/sdl/SDL.kt b/korge-core/src/korlibs/sdl/SDL.kt new file mode 100644 index 0000000000..a709e6c067 --- /dev/null +++ b/korge-core/src/korlibs/sdl/SDL.kt @@ -0,0 +1,36 @@ +package korlibs.sdl + +import korlibs.annotations.* +import korlibs.ffi.* + +val SDLPath by lazy { + //"https://github.com/libsdl-org/SDL/releases/download/release-2.30.5/SDL2-2.30.5-win32-x64.zip" + //"SDL" + "C:\\temp\\SDL2.dll" +} + +@KeepNames +open class SDL : FFILib(SDLPath) { + companion object { + const val SDL_WINDOWPOS_UNDEFINED = 0x1FFF0000 + const val SDL_WINDOWPOS_CENTERED = 0x2FFF0000 + + // https://wiki.libsdl.org/SDL2/SDL_WindowFlags + // SDL_WindowFlags + const val SDL_WINDOW_OPENGL = 0x2 + const val SDL_WINDOW_RESIZABLE = 0x20 + + // https://wiki.libsdl.org/SDL2/SDL_Event + // SDL_Event + const val SDL_QUIT = 0x100 + } + + val SDL_Init by func<(flags: Int) -> Int>() + val SDL_CreateWindow by func<(title: String, x: Int, y: Int, w: Int, h: Int, flags: Int) -> FFIPointer>() + val SDL_SetWindowTitle by func<(window: FFIPointer, title: String) -> Unit>() + val SDL_SetWindowSize by func<(window: FFIPointer, w: Int, h: Int) -> Unit>() + val SDL_ShowWindow by func<(window: FFIPointer) -> Unit>() + val SDL_RaiseWindow by func<(window: FFIPointer) -> Unit>() + val SDL_PollEvent by func<(event: FFIPointer) -> Boolean>() + val SDL_Quit by func<() -> Unit>() +} diff --git a/korge-core/src/korlibs/sdl/SDLGameWindow.kt b/korge-core/src/korlibs/sdl/SDLGameWindow.kt new file mode 100644 index 0000000000..68b32cde3d --- /dev/null +++ b/korge-core/src/korlibs/sdl/SDLGameWindow.kt @@ -0,0 +1,60 @@ +package korlibs.sdl + +import korlibs.ffi.* +import korlibs.graphics.* +import korlibs.graphics.log.* +import korlibs.math.geom.* +import korlibs.render.* + +abstract class SDLGameWindow( + var size: Size = Size(640, 480), + val config: GameWindowCreationConfig = GameWindowCreationConfig.DEFAULT, +) : GameWindow() { + val sdl: SDL = SDL() + val window = sdl.SDL_CreateWindow( + config.title, + SDL.SDL_WINDOWPOS_CENTERED, SDL.SDL_WINDOWPOS_CENTERED, + size.width.toInt(), size.height.toInt(), + SDL.SDL_WINDOW_RESIZABLE or SDL.SDL_WINDOW_OPENGL + ) + init { + sdl.SDL_ShowWindow(window) + } + + override val ag: AG = AGDummy() + + //override var title: String = "" + // set(value) { + // field = value + // sdl.SDL_SetWindowTitle(window, title) + // } +// + //override fun setSize(width: Int, height: Int) { + // sdl.SDL_SetWindowSize(window, width, height) + //} + + fun init() { + //SDL.SDL_WINDOWPOS_CENTERED + } + + val event = CreateFFIMemory(1024) + + fun updateSDLEvents() { + event.usePointer { + while (sdl.SDL_PollEvent(it)) { + val type = it.getS32(0) + when (type) { + SDL.SDL_QUIT -> { + close() + } + } + println("EVENT: type=$type") + } + } + } + + override fun close(exitCode: Int) { + super.close(exitCode) + sdl.SDL_Quit() + } +} diff --git a/korge-core/src@js/korlibs/render/DefaultGameWindowJs.kt b/korge-core/src@js/korlibs/render/DefaultGameWindowJs.kt index 50f416c9b8..c001ba3112 100644 --- a/korge-core/src@js/korlibs/render/DefaultGameWindowJs.kt +++ b/korge-core/src@js/korlibs/render/DefaultGameWindowJs.kt @@ -552,10 +552,8 @@ private external interface JsGamepadEvent { class NodeJsGameWindow : JsGameWindow() -class DenoJsGameWindow : JsGameWindow() - actual fun CreateDefaultGameWindow(config: GameWindowCreationConfig): GameWindow = when { - Platform.isJsDenoJs -> DenoJsGameWindow() + Platform.isJsDenoJs -> DenoJsGameWindow(config = config) Platform.isJsNodeJs -> NodeJsGameWindow() else -> BrowserCanvasJsGameWindow() } diff --git a/korge-core/src@js/korlibs/render/DenoJsGameWindow.kt b/korge-core/src@js/korlibs/render/DenoJsGameWindow.kt new file mode 100644 index 0000000000..f893052b4a --- /dev/null +++ b/korge-core/src@js/korlibs/render/DenoJsGameWindow.kt @@ -0,0 +1,34 @@ +package korlibs.render + +import korlibs.io.async.* +import korlibs.js.* +import korlibs.math.geom.* +import korlibs.platform.* +import korlibs.sdl.* +import kotlinx.coroutines.* +import org.w3c.dom.* +import kotlin.js.* + +class DenoJsGameWindow( + size: Size = Size(640, 480), + config: GameWindowCreationConfig = GameWindowCreationConfig.DEFAULT, +) : SDLGameWindow(size, config) { + override suspend fun loop(entry: suspend GameWindow.() -> Unit) { + launchImmediately(getCoroutineDispatcherWithCurrentContext()) { + entry() + } + + jsGlobalThis.setInterval({ + //println("INTERVAL") + updateSDLEvents() + frame() + }, 16) + + //CompletableDeferred().await() + } + + override fun close(exitCode: Int) { + super.close(exitCode) + Deno.exit(exitCode) + } +} diff --git a/korge-core/test/korlibs/sdl/SDLTest.kt b/korge-core/test/korlibs/sdl/SDLTest.kt new file mode 100644 index 0000000000..e458cf57d1 --- /dev/null +++ b/korge-core/test/korlibs/sdl/SDLTest.kt @@ -0,0 +1,36 @@ +package korlibs.sdl + +import korlibs.concurrent.thread.* +import korlibs.ffi.* +import korlibs.io.async.* +import korlibs.time.* +import kotlinx.coroutines.* +import kotlin.test.* + +class SDLTest { + @Ignore + @Test + fun test() = suspendTest { + val sdl = SDL() + try { + sdl.SDL_Init(0) + val window = sdl.SDL_CreateWindow("hello world", SDL.SDL_WINDOWPOS_CENTERED, SDL.SDL_WINDOWPOS_CENTERED, 300, 300, SDL.SDL_WINDOW_RESIZABLE or SDL.SDL_WINDOW_OPENGL) + sdl.SDL_ShowWindow(window) + sdl.SDL_RaiseWindow(window) + + val event = CreateFFIMemory(1024) + for (n in 0 until 10000) { + event.usePointer { + while (sdl.SDL_PollEvent(it)) { + println(it.getS32(0)) + } + //NativeThread.sleep(1.milliseconds) + delay(1.milliseconds) + } + } + sdl.SDL_Quit() + } finally { + //sdl.close() // @TODO: enable after korlibs -alpha8 + } + } +} diff --git a/korge/src/korlibs/korge/Korge.kt b/korge/src/korlibs/korge/Korge.kt index f22b410a3f..f2c4aa7f20 100644 --- a/korge/src/korlibs/korge/Korge.kt +++ b/korge/src/korlibs/korge/Korge.kt @@ -186,7 +186,9 @@ object KorgeRunner { if (!Platform.isJsBrowser) { configureLoggerFromProperties(localCurrentDirVfs["klogger.properties"]) } - val realGameWindow = (config.gameWindow ?: coroutineContext[GameWindow] ?: CreateDefaultGameWindow(config.windowCreationConfig)) + val realGameWindow = (config.gameWindow ?: coroutineContext[GameWindow] ?: CreateDefaultGameWindow( + config.windowCreationConfig.copy(title = config.title) + )) realGameWindow.bgcolor = config.backgroundColor ?: Colors.BLACK realGameWindow.loop { val gameWindow = this