Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -42,9 +42,15 @@ kotlin {
linuxTest {
}
}
}

task copyResources(type: Copy) {
from('res')
into('build/bin/linux/main/release/executable/res')
}

compileKotlinLinux.finalizedBy(copyResources)

task runProgram {
def buildType = 'release' // Change to 'debug' to run application with debug symbols.
dependsOn "link${buildType.capitalize()}ExecutableLinux"
Expand Down
Binary file added res/images/spaceShips_001.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
6 changes: 6 additions & 0 deletions src/linuxMain/kotlin/sample/GameState.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package sample

sealed class GameState {
object Running : GameState()
object Done : GameState()
}
41 changes: 41 additions & 0 deletions src/linuxMain/kotlin/sample/SDLRenderer.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package sample

import cnames.structs.SDL_Window
import cnames.structs.SDL_Texture
import kotlinx.cinterop.CPointer
import kotlinx.cinterop.toKString
import sdl2.*

@ExperimentalUnsignedTypes
class SDLRenderer(window: CPointer<SDL_Window>) {

private val renderer: CPointer<SDL_Renderer> =
SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED or SDL_RENDERER_PRESENTVSYNC) ?: throw NullPointerException("SDL Renderer returned null")

init {
SDL_SetRenderDrawColor(renderer, 0xFF, 0xFF, 0xFF, 0xFF)
}

fun render(vararg textures: CPointer<SDL_Texture>) {
SDL_RenderClear(renderer)
for (texture in textures)
SDL_RenderCopy(renderer, texture, null, null)

SDL_RenderPresent(renderer)
}


@ExperimentalUnsignedTypes
fun loadImage(path: String): CPointer<SDL_Texture>? {

val img = IMG_Load(path)!!
val finalSurface = SDL_CreateTextureFromSurface(renderer, img) ?: throw Exception("SDL Error when trying to load texture: ${SDL_GetError()?.toKString()}")
SDL_FreeSurface(img)
return finalSurface
}

fun destroy() {
SDL_DestroyRenderer(renderer)
}

}
108 changes: 1 addition & 107 deletions src/linuxMain/kotlin/sample/Sample.kt
Original file line number Diff line number Diff line change
@@ -1,112 +1,6 @@
package sample

import kotlinx.cinterop.*
import kotlinx.coroutines.runBlocking
import sdl2.*
import kotlin.math.roundToInt
import kotlin.system.getTimeMillis

@ExperimentalUnsignedTypes
fun main(): Unit = runBlocking {
memScoped {
val window = SDL_CreateWindow(
title = "Hello Kotlin/Native",
x = SDL_WINDOWPOS_CENTERED.toInt(),
y = SDL_WINDOWPOS_CENTERED.toInt(),
w = 640,
h = 480,
flags = SDL_WINDOW_SHOWN
)!!

val gameContext = GameContext(window)
val ship: SDL_Surface = alloc()

paintScreen(gameContext)

val sdlEvent: SDL_Event = alloc()

gameContext.loop {
sdlEvent.resolveInputs { event ->
when(event) {
SDL_QUIT -> gameContext.quit()
}
}



}


SDL_DestroyWindow(window)
SDL_Quit()

}
}

@ExperimentalUnsignedTypes
data class GameContext(
val window: CPointer<SDL_Window>,
val primarySurface: CPointer<SDL_Surface> = SDL_GetWindowSurface(window)!!
) {
private var state: GameState = GameState.Running

fun loop(function: () -> Unit) {
val tickrate = 1000 / 60

while (state is GameState.Running) {
val startTime = getTimeMillis()
function()
val endTime = getTimeMillis()
val timeDiff = endTime - startTime

if (timeDiff < tickrate)
SDL_Delay((tickrate - timeDiff).toUInt())
}
}

fun quit() {
state = GameState.Done
}

fun currentState() = state
}

sealed class GameState {
object Running : GameState()
object Done : GameState()
}

@ExperimentalUnsignedTypes
fun SDL_Event.resolveInputs(func: (Uint32) -> Unit) {
SDL_PollEvent(this.ptr)

func(this.type)

}


fun CPointer<SDL_Surface>.fill(rect: CValue<SDL_Rect>, r: Uint8, g: Uint8, b: Uint8) =
SDL_FillRect(this, rect, SDL_MapRGB(this.pointed.format, r, g, b))

@ExperimentalUnsignedTypes
fun paintScreen(context: GameContext) = memScoped {
val step: Float = 255f / 639

val rect = alloc<SDL_Rect>()

for (line in 0..639) {
val color = (line * step).roundToInt()

rect.apply {
x = line
y = 0
w = 1
h = 480
}

context.primarySurface.fill(rect.readValue(), color.toUByte(), color.toUByte(), color.toUByte())
}


SDL_UpdateWindowSurface(context.window)
}
fun main(): Unit = runBlocking { ShootumsGame().run() }
69 changes: 69 additions & 0 deletions src/linuxMain/kotlin/sample/ShootumsGame.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
package sample

import cnames.structs.SDL_Window
import kotlinx.cinterop.*
import platform.posix.EXDEV
import sdl2.*
import kotlin.math.roundToInt
import kotlin.system.getTimeMillis

@ExperimentalUnsignedTypes
class ShootumsGame {
private val arena = Arena()
val window: CPointer<SDL_Window> = SDL_CreateWindow(
title = "SHIPPPPPPPPPPPPPPPPPPPPPPPP",
x = SDL_WINDOWPOS_CENTERED.toInt(),
y = SDL_WINDOWPOS_CENTERED.toInt(),
w = 640,
h = 480,
flags = SDL_WINDOW_SHOWN
)!!
private val renderer = SDLRenderer(window)
private var state: GameState = GameState.Running
private val sdlEvent: SDL_Event = arena.alloc()


fun run() = memScoped {
val tickrate = 1000 / 60
val ship = renderer.loadImage("res/images/spaceShips_001.png") ?: throw Exception("Could not load ship: ${SDL_GetError()?.toKString()}")

while (state is GameState.Running) {
val startTime = getTimeMillis()

sdlEvent.resolveInputs { event ->
when (event) {
SDL_QUIT -> quit()
}
}

renderer.render(ship)


val endTime = getTimeMillis()
val timeDiff = endTime - startTime

if (timeDiff < tickrate)
SDL_Delay((tickrate - timeDiff).toUInt())
}

renderer.destroy()
SDL_DestroyWindow(window)
SDL_Quit()
}

fun quit() {
state = GameState.Done
}

fun currentState() = state

@ExperimentalUnsignedTypes
private fun SDL_Event.resolveInputs(func: (Uint32) -> Unit) {
SDL_PollEvent(this.ptr)

func(this.type)

}


}
4 changes: 2 additions & 2 deletions src/nativeInterop/cinterop/sdl2.def
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
headers = SDL.h stdlib.h time.h
headers = SDL.h stdlib.h time.h SDL_image.h
entryPoint = SDL_main

headerFilter = SDL* stdlib.h time.h
Expand All @@ -9,4 +9,4 @@ compilerOpts.linux = -D_REENTRANT
compilerOpts.ios =

linkerOpts.osx = -F ${System.getProperty("user.home")}/Library/Frameworks -F /Library/Frameworks -framework SDL2
linkerOpts.linux = -L/usr/lib64 -L/usr/lib/x86_64-linux-gnu -L/lib/x86_64-linux-gnu/ -lSDL2
linkerOpts.linux = -L/usr/lib64 -L/usr/lib/x86_64-linux-gnu -L/lib/x86_64-linux-gnu/ -lSDL2 -lSDL2_image