Skip to content

Commit 861c3f3

Browse files
authored
Merge pull request #21 from minigdx/full-shaders
Add new commands and new palette colors
2 parents 5f4e7ae + 39eb9af commit 861c3f3

File tree

7 files changed

+644
-40
lines changed

7 files changed

+644
-40
lines changed

tiny-cli/src/main/kotlin/com/github/minigdx/tiny/cli/GamePalette.kt

Lines changed: 146 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
package com.github.minigdx.tiny.cli
22

3-
class GamePalette(val name: String, val colors: List<String>) {
3+
class GamePalette(val name: String, val colors: List<String>, val source: String? = null) {
44
companion object {
55
val ONE_BIT =
66
GamePalette(
@@ -28,6 +28,7 @@ class GamePalette(val name: String, val colors: List<String>) {
2828
"#FF77A8",
2929
"#FFCCAA",
3030
),
31+
"https://lospec.com/palette-list/pico-8",
3132
)
3233

3334
val GAMEBOY =
@@ -65,7 +66,150 @@ class GamePalette(val name: String, val colors: List<String>) {
6566
"#FFBF40",
6667
"#CC1424",
6768
),
69+
"https://lospec.com/palette-list/rgr-proto16",
6870
)
69-
val ALL = listOf(ONE_BIT, PICO8, GAMEBOY, RGR_PROTO16)
71+
72+
// Oil 6 Palette
73+
val OIL_6 = GamePalette(
74+
"oil-6",
75+
listOf(
76+
"#fbf5ef",
77+
"#f2d3ab",
78+
"#c69fa5",
79+
"#8b6d9c",
80+
"#494d7e",
81+
"#272744",
82+
),
83+
"https://lospec.com/palette-list/oil-6",
84+
)
85+
86+
// Blessing Palette
87+
val BLESSING = GamePalette(
88+
"blessing",
89+
listOf(
90+
"#74569b",
91+
"#96fbc7",
92+
"#f7ffae",
93+
"#ffb3cb",
94+
"#d8bfd8",
95+
),
96+
"https://lospec.com/palette-list/blessing",
97+
)
98+
99+
// Ice Cream GB Palette
100+
val ICE_CREAM_GB = GamePalette(
101+
"ice-cream-gb",
102+
listOf(
103+
"#7c3f58",
104+
"#eb6b6f",
105+
"#f9a875",
106+
"#fff6d3",
107+
),
108+
"https://lospec.com/palette-list/ice-cream-gb",
109+
)
110+
111+
// 2bit demichrome Palette
112+
val _2BIT_DEMICHROME = GamePalette(
113+
"2bit-demichrome",
114+
listOf(
115+
"#211e20",
116+
"#555568",
117+
"#a0a08b",
118+
"#e9efec",
119+
),
120+
"https://lospec.com/palette-list/2bit-demichrome",
121+
)
122+
123+
// Eulbink Palette
124+
val EULBINK = GamePalette(
125+
"eulbink",
126+
listOf(
127+
"#ffffff",
128+
"#0ce6f2",
129+
"#0098db",
130+
"#1e579c",
131+
"#203562",
132+
"#252446",
133+
"#201533",
134+
),
135+
"https://lospec.com/palette-list/eulbink",
136+
)
137+
138+
// Curiosities Palette
139+
val CURIOSITIES = GamePalette(
140+
"curiosities",
141+
listOf(
142+
"#46425e",
143+
"#15788c",
144+
"#00b9be",
145+
"#ffeecc",
146+
"#ffb0a3",
147+
"#ff6973",
148+
),
149+
"https://lospec.com/palette-list/curiosities",
150+
)
151+
152+
// Vanilla Milkshake Palette
153+
val VANILLA_MILKSHAKE = GamePalette(
154+
"vanilla-milkshake",
155+
listOf(
156+
"#28282e", "#6c5671", "#d9c8bf", "#f98284", "#b0a9e4", "#accce4",
157+
"#b3e3da", "#feaae4", "#87a889", "#b0eb93", "#e9f59d", "#ffe6c6",
158+
"#dea38b", "#ffc384", "#fff7a0", "#fff7e4",
159+
),
160+
"https://lospec.com/palette-list/vanilla-milkshake",
161+
)
162+
163+
// Mushroom Palette
164+
val MUSHROOM = GamePalette(
165+
"mushroom",
166+
listOf(
167+
"#2e222f", "#45293f", "#7a3045", "#993d41", "#cd683d", "#fbb954",
168+
"#f2ec8b", "#b0a987", "#997f73", "#665964", "#443846", "#576069",
169+
"#788a87", "#a9b2a2",
170+
),
171+
"https://lospec.com/palette-list/mushroom",
172+
)
173+
174+
// Resurrect 32 Palette
175+
val RESURRECT_32 = GamePalette(
176+
"resurrect-32",
177+
listOf(
178+
"#ffffff", "#fb6b1d", "#e83b3b", "#831c5d", "#c32454", "#f04f78",
179+
"#f68181", "#fca790", "#e3c896", "#ab947a", "#966c6c", "#625565",
180+
"#3e3546", "#0b5e65", "#0b8a8f", "#1ebc73", "#91db69", "#fbff86",
181+
"#fbb954", "#cd683d", "#9e4539", "#7a3045", "#6b3e75", "#905ea9",
182+
"#a884f3", "#eaaded", "#8fd3ff", "#4d9be6", "#4d65b4", "#484a77",
183+
"#30e1b9", "#8ff8e2",
184+
),
185+
"https://lospec.com/palette-list/resurrect-32",
186+
)
187+
188+
// Bubblegum 16 Palette
189+
val BUBBLEGUM_16 = GamePalette(
190+
"bubblegum-16",
191+
listOf(
192+
"#16171a", "#7f0622", "#d62411", "#ff8426", "#ffd100", "#fafdff",
193+
"#ff80a4", "#ff2674", "#94216a", "#430067", "#234975", "#68aed4",
194+
"#bfff3c", "#10d275", "#007899", "#002859",
195+
),
196+
"https://lospec.com/palette-list/bubblegum-16",
197+
)
198+
val ALL = listOf(
199+
ONE_BIT,
200+
PICO8,
201+
GAMEBOY,
202+
RGR_PROTO16,
203+
OIL_6,
204+
BLESSING,
205+
ICE_CREAM_GB,
206+
_2BIT_DEMICHROME,
207+
EULBINK,
208+
CURIOSITIES,
209+
VANILLA_MILKSHAKE,
210+
MUSHROOM,
211+
RESURRECT_32,
212+
BUBBLEGUM_16,
213+
)
70214
}
71215
}

tiny-cli/src/main/kotlin/com/github/minigdx/tiny/cli/command/CreateCommand.kt

Lines changed: 37 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,10 @@ import com.github.ajalt.clikt.parameters.options.prompt
99
import com.github.ajalt.clikt.parameters.options.validate
1010
import com.github.ajalt.clikt.parameters.types.file
1111
import com.github.ajalt.clikt.parameters.types.int
12+
import com.github.ajalt.mordant.rendering.TextStyles
1213
import com.github.minigdx.tiny.cli.GamePalette
14+
import com.github.minigdx.tiny.cli.command.utils.ColorUtils
15+
import com.github.minigdx.tiny.cli.command.utils.ColorUtils.brightness
1316
import com.github.minigdx.tiny.cli.config.GameParameters
1417
import com.github.minigdx.tiny.cli.config.GameParameters.Companion.JSON
1518
import com.github.minigdx.tiny.cli.config.GameParametersV1
@@ -22,15 +25,15 @@ import java.io.FileOutputStream
2225
@Language("Lua")
2326
private const val DEFAULT_GAME_SCRIPT = """
2427
function _init()
25-
28+
2629
end
27-
28-
30+
31+
2932
function _update()
30-
33+
3134
end
32-
33-
35+
36+
3437
function _draw()
3538
gfx.cls()
3639
print("Congratulation! Your game is running!")
@@ -77,7 +80,7 @@ class CreateCommand : CliktCommand(name = "create") {
7780
"""🎨 Please choose a game color palette:
7881
${
7982
GamePalette.ALL.mapIndexed { index, gamePalette ->
80-
"[${index + 1}] ${gamePalette.name}"
83+
formatPaletteDisplay(gamePalette, index)
8184
}.joinToString("\n")
8285
}
8386
""",
@@ -96,16 +99,15 @@ ${
9699
echo("\uFE0F Sprite Sheet Filenames: ${spritesheets.ifBlank { "No spritesheet added!" }}")
97100
echo("\uFE0F Color palette: ${GamePalette.ALL[palette - 1].name}")
98101

99-
val configuration =
100-
GameParametersV1(
101-
name = gameName,
102-
resolution = gameResolution.toSize(),
103-
sprites = spriteSize.toSize(),
104-
zoom = zoom,
105-
colors = GamePalette.ALL[palette - 1].colors,
106-
scripts = listOf(gameScript),
107-
hideMouseCursor = hideMouseCursor == "yes".lowercase(),
108-
) as GameParameters
102+
val configuration = GameParametersV1(
103+
name = gameName,
104+
resolution = gameResolution.toSize(),
105+
sprites = spriteSize.toSize(),
106+
zoom = zoom,
107+
colors = GamePalette.ALL[palette - 1].colors.sortedBy { brightness(it) },
108+
scripts = listOf(gameScript),
109+
hideMouseCursor = hideMouseCursor == "yes".lowercase(),
110+
) as GameParameters
109111

110112
if (!gameDirectory.exists()) gameDirectory.mkdirs()
111113

@@ -139,4 +141,22 @@ ${
139141
val currentPath = File(".")
140142
return gamePath.relativeTo(currentPath).path
141143
}
144+
145+
companion object {
146+
private const val MAX_COLOR_PALETTE_DISPLAYED = 28
147+
148+
private fun formatPaletteDisplay(
149+
palette: GamePalette,
150+
index: Int,
151+
): String {
152+
val colorsText = ColorUtils.formatCurrentPaletteDisplay(palette.colors, maxColors = MAX_COLOR_PALETTE_DISPLAYED)
153+
154+
return if (palette.source != null) {
155+
val invoke = TextStyles.hyperlink(palette.source).invoke(palette.name)
156+
"[${index + 1}] $invoke $colorsText"
157+
} else {
158+
"[${index + 1}] ${palette.name} $colorsText"
159+
}
160+
}
161+
}
142162
}

tiny-cli/src/main/kotlin/com/github/minigdx/tiny/cli/command/MainCommand.kt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@ class MainCommand : CliktCommand() {
1616
ServeCommand(),
1717
PaletteCommand(),
1818
SfxCommand(),
19+
UpdateCommand(),
20+
ResourcesCommand(),
1921
)
2022
}
2123

tiny-cli/src/main/kotlin/com/github/minigdx/tiny/cli/command/PaletteCommand.kt

Lines changed: 26 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,12 @@ import com.github.ajalt.clikt.core.CliktCommand
44
import com.github.ajalt.clikt.core.Context
55
import com.github.ajalt.clikt.parameters.arguments.argument
66
import com.github.ajalt.clikt.parameters.arguments.default
7+
import com.github.ajalt.clikt.parameters.arguments.optional
78
import com.github.ajalt.clikt.parameters.options.flag
89
import com.github.ajalt.clikt.parameters.options.option
910
import com.github.ajalt.clikt.parameters.types.file
11+
import com.github.minigdx.tiny.cli.command.utils.ColorUtils
12+
import com.github.minigdx.tiny.cli.command.utils.ColorUtils.brightness
1013
import com.github.minigdx.tiny.cli.config.GameParameters
1114
import com.github.minigdx.tiny.cli.exception.MissingTinyConfigurationException
1215
import com.github.minigdx.tiny.file.CommonVirtualFileSystem
@@ -23,31 +26,41 @@ class PaletteCommand : CliktCommand(name = "palette") {
2326

2427
val image by argument(help = "The image used to extract the palette.")
2528
.file(mustExist = true, canBeFile = true, canBeDir = false)
29+
.optional()
2630

2731
val append by option(help = "Append, instead of replacing, the palette information in the game file.")
2832
.flag()
2933

3034
val print by option(help = "Print in the console the palette information, without updating the game.")
3135
.flag()
3236

33-
override fun help(context: Context) = "Extract the color palette from an image."
37+
override fun help(context: Context) = "Extract the color palette from an image or display current colors."
3438

3539
override fun run() {
3640
val tiny = gameDirectory.resolve("_tiny.json")
3741
if (!tiny.exists()) {
3842
throw MissingTinyConfigurationException(tiny)
3943
}
44+
4045
// Open the _tiny.json
4146
val gameParameters = GameParameters.read(tiny)
4247
val gameOptions = gameParameters.toGameOptions()
48+
49+
if (image == null) {
50+
// No image provided - display current colors
51+
displayCurrentColors(gameOptions.palette)
52+
return
53+
}
54+
55+
// Image provided - extract colors and process
4356
val platform = GlfwPlatform(
4457
gameOptions = gameOptions,
4558
logger = StdOutLogger("whatever"),
4659
vfs = CommonVirtualFileSystem(),
4760
workdirectory = gameDirectory,
4861
)
4962
val imageData = runBlocking {
50-
platform.createImageStream(image.relativeTo(gameDirectory).path).read()
63+
platform.createImageStream(image!!.relativeTo(gameDirectory).path).read()
5164
}
5265

5366
val colors = mutableSetOf<String>()
@@ -74,10 +87,13 @@ class PaletteCommand : CliktCommand(name = "palette") {
7487
}
7588

7689
if (print) {
77-
echo("\uD83C\uDFA8 ${extractedColors.size} colors extracted from the file ${image.name}:")
90+
echo("\uD83C\uDFA8 ${extractedColors.size} colors extracted from the file ${image!!.name}:")
7891
extractedColors.forEachIndexed { index, color ->
7992
echo("- ${index + 1} \t-> \t$color")
8093
}
94+
// Display current colors at the end
95+
echo()
96+
displayCurrentColors(gameOptions.palette)
8197
return
8298
}
8399

@@ -90,25 +106,14 @@ class PaletteCommand : CliktCommand(name = "palette") {
90106
val sortedColors = replacedColors.sortedBy { brightness(it) }
91107
gameParameters.setPalette(sortedColors).write(tiny)
92108
echo("\uD83C\uDFA8 Game has been updated with the new color palette (with ${replacedColors.size} colors)")
93-
}
94-
95-
private fun brightness(hexColor: String): Float {
96-
// Remove the '#' prefix
97-
val colorWithoutHash = hexColor.removePrefix("#")
98109

99-
// Parse R, G, B components from the hex string
100-
// Use 16 as the radix for hexadecimal parsing
101-
val r = colorWithoutHash.substring(0, 2).toInt(16)
102-
val g = colorWithoutHash.substring(2, 4).toInt(16)
103-
val b = colorWithoutHash.substring(4, 6).toInt(16)
104-
105-
// Calculate brightness. A common formula for perceived brightness (luminance) is:
106-
// 0.299*R + 0.587*G + 0.114*B
107-
// The components R, G, B are already in the range [0, 255].
108-
val brightness = 0.299f * r + 0.587f * g + 0.114f * b
110+
// Display current colors at the end
111+
echo()
112+
displayCurrentColors(sortedColors)
113+
}
109114

110-
// The sortedByDescending function will use this brightness value
111-
// to order the colors from highest brightness to lowest.
112-
return brightness
115+
private fun displayCurrentColors(colors: List<String>) {
116+
echo("\uD83C\uDFA8 Current colors:")
117+
echo(ColorUtils.formatCurrentPaletteDisplay(colors, withIndex = true))
113118
}
114119
}

0 commit comments

Comments
 (0)