Skip to content

Commit

Permalink
Allow examples to load custom sprite and level
Browse files Browse the repository at this point in the history
  • Loading branch information
dwursteisen committed Jan 4, 2024
1 parent 7fc8b73 commit a272b11
Show file tree
Hide file tree
Showing 13 changed files with 144 additions and 29 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -32,18 +32,28 @@ annotation class TinyFunction(
* This code will be injected in the web documentation.
*/
val example: String = "",

/**
* Expected sprite path associated to the example.
*/
val spritePath: String = "",

/**
* Expected level path associated to the example.
*/
val levelPath: String = "",
)

@Target(AnnotationTarget.VALUE_PARAMETER, AnnotationTarget.FUNCTION)
@Retention(AnnotationRetention.SOURCE)
@Repeatable
annotation class TinyArg(
/**
* Name of the argument
* Name of the argument.
*/
val name: String,
/**
* Description of the argument
* Description of the argument.
*/
val description: String = "",
)
Expand All @@ -56,6 +66,9 @@ annotation class TinyArgs(
* Name of the arguments, in order.
*/
val names: Array<String>,
/**
* Documentations associated to arguments, in order.
*/
val documentations: Array<String> = [],
)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -120,12 +120,14 @@ class AsciidocLibSection(val title: String?) {
)
}

fun example(lua: String?) {
fun example(lua: String?, spritePath: String? = null, levelPath: String? = null) {
if (lua == null) return
val spr = spritePath?.let { """sprite="$it"""" } ?: ""
val lvl = levelPath?.let { """level="$it"""" } ?: ""
paragraph(
"""
>++++
><tiny-editor style="display: none;">
><tiny-editor style="display: none;" $spr $lvl>
>$lua
></tiny-editor>
>++++
Expand Down Expand Up @@ -164,6 +166,8 @@ data class TinyFunctionDescriptor(
var description: String = "",
var calls: List<TinyCallDescriptor> = emptyList(),
var example: String? = null,
var spritePath: String? = null,
var levelPath: String? = null,
)

class TinyLibDescriptor(
Expand Down Expand Up @@ -306,10 +310,14 @@ class KspProcessor(
}

val example = function.example.ifBlank { null }
val levelPath = function.levelPath.ifBlank { null }
val spritePath = function.spritePath.ifBlank { null }
TinyFunctionDescriptor(
example = example,
name = name.ifBlank { defaultName },
description = function.description,
levelPath = levelPath,
spritePath = spritePath,
calls = calls,
)
}
Expand Down Expand Up @@ -388,7 +396,7 @@ class KspProcessor(
)
}

example(func.example)
example(func.example, func.spritePath, func.levelPath)
}
}
}
Expand Down
7 changes: 6 additions & 1 deletion tiny-doc/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -58,8 +58,13 @@ val copySample = tasks.create("copy-sample", Copy::class) {
into(project.buildDir.resolve("docs/asciidoc/sample"))
}

val copyResources = tasks.create("copy-resources", Copy::class) {
from(project.projectDir.resolve("src/docs/asciidoc/resources"))
into(project.buildDir.resolve("docs/asciidoc/resources"))
}

tasks.withType(AsciidoctorTask::class.java).configureEach {
this.baseDirFollowsSourceDir()

this.dependsOn(unzipAsciidoctorResources, copyAsciidoctorDependencies, copySample)
this.dependsOn(unzipAsciidoctorResources, copyAsciidoctorDependencies, copySample, copyResources)
}
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,8 @@ class PixelArray(val width: Pixel, val height: Pixel, val pixelFormat: Int = Pix
}

fun set(x: Pixel, y: Pixel, vararg pixel: Int) {
assert(x in 0 until width) { "x ($x) has to be between 0 and $width " }
assert(y in 0 until height) { "y ($y) has to be between 0 and $height " }
assert(x in 0 until width) { "x ($x) has to be between 0 and $width (excluded)" }
assert(y in 0 until height) { "y ($y) has to be between 0 and $height (excluded)" }
assert(pixel.size == pixelFormat) { "the assigned pixel needs to conform the pixel format ($pixelFormat)" }

val correctedX = min(max(0, x), width - 1)
Expand All @@ -52,8 +52,8 @@ class PixelArray(val width: Pixel, val height: Pixel, val pixelFormat: Int = Pix
}

fun get(x: Pixel, y: Pixel): Array<Int> {
assert(x in 0 until width) { "x ($x) has to be between 0 and $width " }
assert(y in 0 until height) { "y ($y) has to be between 0 and $height " }
assert(x in 0 until width) { "x ($x) has to be between 0 and $width (excluded)" }
assert(y in 0 until height) { "y ($y) has to be between 0 and $height (excluded)" }
val position = (x + y * width) * pixelFormat
tmp.forEachIndexed { index, _ ->
tmp[index] = pixels[position + index]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,17 +32,35 @@ class SprLib(val gameOptions: GameOptions, val resourceAccess: GameResourceAcces
return sprTable
}

@TinyFunction("Get the color index at the coordinate (x,y) from the current spritesheet.")
@TinyFunction(
"Get the color index at the coordinate (x,y) from the current spritesheet.",
example = SPR_PGET_EXAMPLE,
spritePath = "resources/tiny-town.png",
)
private inner class pget : TwoArgFunction() {
@TinyCall("get the color index at the coordinate (x,y) from the current spritesheet.")
override fun call(@TinyArg("x") arg1: LuaValue, @TinyArg("y") arg2: LuaValue): LuaValue {
val index = resourceAccess.spritesheet(currentSpritesheet)?.pixels?.get(arg1.checkint(), arg2.checkint())
val colorIndex = index?.get(0) ?: 0
return valueOf(colorIndex)
val pixelArray = resourceAccess.spritesheet(currentSpritesheet)?.pixels ?: return NIL

val x = arg1.checkint()
val y = arg2.checkint()

if (x in 0 until pixelArray.width && y in 0 until pixelArray.height) {
val index = pixelArray.get(x, y)

val colorIndex = index.get(0)
return valueOf(colorIndex)
} else {
return NIL
}
}
}

@TinyFunction("Set the color index at the coordinate (x,y) in the current spritesheet.")
@TinyFunction(
"Set the color index at the coordinate (x,y) in the current spritesheet.",
example = SPR_PSET_EXAMPLE,
spritePath = "resources/tiny-dungeon.png",
)
private inner class pset : ThreeArgFunction() {
@TinyCall("Set the color index at the coordinate (x,y) in the current spritesheet.")
override fun call(
Expand Down Expand Up @@ -80,7 +98,11 @@ class SprLib(val gameOptions: GameOptions, val resourceAccess: GameResourceAcces
}
}

@TinyFunction("S(uper) Draw a fragment from the spritesheet.")
@TinyFunction(
"S(uper) Draw a fragment from the spritesheet.",
example = SPR_PGET_EXAMPLE,
spritePath = "resources/tiny-town.png",
)
internal inner class sdraw : LibFunction() {
@TinyCall("Draw the full spritesheet at default coordinate (0, 0)")
override fun call(): LuaValue {
Expand Down Expand Up @@ -141,24 +163,27 @@ class SprLib(val gameOptions: GameOptions, val resourceAccess: GameResourceAcces
}
}

@TinyFunction("Draw a sprite.")
@TinyFunction("Draw a sprite.", example = SPR_DRAW_EXAMPLE, spritePath = "resources/tiny-town.png")
internal inner class draw : LibFunction() {
// sprn, x, y, flip x, flip y

@TinyCall("Draw a sprite at the default coordinate (0, 0).")
override fun call(
@TinyArg("sprN") a: LuaValue,
): LuaValue = super.call(a)

@TinyCall("Draw a sprite.")
override fun call(
@TinyArg("sprN") a: LuaValue,
@TinyArg("x") b: LuaValue,
@TinyArg("y") c: LuaValue,
): LuaValue {
return invoke(arrayOf(a, b, c, valueOf(false), valueOf(false))).arg1()
}
): LuaValue = super.call(a, b, c)

@TinyCall("Draw a sprite and allow flip on x or y axis.")
override fun invoke(@TinyArgs(["sprN", "x", "y", "flipX", "flipY"]) args: Varargs): Varargs {
if (args.narg() < 3) return NONE
if (args.narg() < 1) return NIL
val sprN = args.arg(1).checkint()
val x = args.arg(2).checkint()
val y = args.arg(3).checkint()
val x = args.arg(2).optint(0)
val y = args.arg(3).optint(0)
val flipX = args.arg(4).optboolean(false)
val flipY = args.arg(5).optboolean(false)

Expand All @@ -181,7 +206,7 @@ class SprLib(val gameOptions: GameOptions, val resourceAccess: GameResourceAcces
reverseY = flipY,
)

return NONE
return NIL
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
package com.github.minigdx.tiny.lua

//language=Lua
const val SPR_PGET_EXAMPLE = """
function _draw()
local pos = ctrl.touch()
gfx.cls()
spr.sdraw()
shape.circlef(pos.x - 4, pos.y - 4, 8, 3)
local color = spr.pget(pos.x, pos.y)
if(color ~= nil) then
print("index color: "..color, 7, 0)
shape.rectf(0, 0, 6, 6, color)
shape.circlef(pos.x - 4, pos.y - 4, 6, color)
end
end
"""

//language=Lua
const val SPR_PSET_EXAMPLE = """
function _draw()
local pos = ctrl.touch()
local touching = ctrl.touching(0)
gfx.cls()
spr.sdraw()
if touching ~= nil then
spr.pset(touching.x, touching.y, 9)
end
print("click to alter", 45, 96)
shape.circle(64 + 8, 128 + 8, 32, 1)
shape.circlef(128 + 8, 128 + 8, 32, 1)
spr.draw(100, 128, 128)
shape.circlef(pos.x, pos.y, 2, 3)
end
"""

//language=Lua
const val SPR_DRAW_EXAMPLE = """
function _init()
id = 1
end
function _draw()
if ctrl.pressed(keys.left) then
id = id - 1
elseif ctrl.pressed(keys.right) then
id = id + 1
end
gfx.cls()
print("sprite index "..id.. " (press left or right to change)", 50, 112)
spr.draw(id, 120, 120)
end
"""
12 changes: 8 additions & 4 deletions tiny-web-editor/src/jsMain/kotlin/Main.kt
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@ fun main() {

elts.forEachIndexed { index, game ->
val code = game.textContent ?: ""
val spritePath = game.getAttribute("sprite")
val levelPath = game.getAttribute("level")

val link = document.createElement("a") {
setAttribute("id", "link-editor-$index")
Expand All @@ -60,15 +62,15 @@ fun main() {
link.textContent = "\uD83D\uDC7E ▶ Run and tweak an example"
link.onclick = { _ ->
if (!clicked) {
createGame(playLink, index, codeToUse, rootPath)
createGame(playLink, index, codeToUse, spritePath, levelPath, rootPath)
clicked = true
}
true
}

// There is a user code. Let's unfold the game.
if (savedCode != null) {
createGame(playLink, index, codeToUse, rootPath)
createGame(playLink, index, codeToUse, spritePath, levelPath, rootPath)
}
}
}
Expand All @@ -77,6 +79,8 @@ private fun createGame(
container: Element,
index: Int,
code: String,
spritePath: String?,
levelPath: String?,
rootPath: String,
) {
val canvas = document.createElement("canvas").apply {
Expand Down Expand Up @@ -130,8 +134,8 @@ private fun createGame(
"#CC1424",
),
gameScripts = listOf("#editor-$index"),
spriteSheets = emptyList(),
gameLevels = emptyList(),
spriteSheets = spritePath?.let { listOf(it) } ?: emptyList(),
gameLevels = levelPath?.let { listOf(it) } ?: emptyList(),
zoom = 2,
gutter = 0 to 0,
spriteSize = 16 to 16,
Expand Down

0 comments on commit a272b11

Please sign in to comment.