Better error messages and mapy stuff.

This commit is contained in:
Kapendev 2025-04-11 19:34:24 +03:00
parent a41da75d3c
commit 1f9a4c797d
6 changed files with 125 additions and 74 deletions

View file

@ -1,6 +1,7 @@
/// A tile map editor for Parin. /// A tile map editor for Parin.
// TODO: Fix the variable names and try to clean things. // TODO: Fix the variable names and try to clean things.
// TODO: Add modes: brush, random, eraser
import parin; import parin;
@ -27,6 +28,12 @@ enum AppMode {
select, select,
} }
enum EditMode {
brush,
random,
eraser,
}
struct AppCamera { struct AppCamera {
Camera data; Camera data;
Vec2 targetPosition; Vec2 targetPosition;
@ -68,6 +75,10 @@ struct AppState {
IStr mapFile; IStr mapFile;
IStr atlasFile; IStr atlasFile;
AppMode mode; AppMode mode;
EditMode editMode;
GridPair editMainPair;
GridPair editTempPair;
GridPair mainPair; GridPair mainPair;
GridPair tempPair; GridPair tempPair;
} }
@ -134,7 +145,7 @@ struct MouseInfo {
void drawText(IStr text, Vec2 position, DrawOptions options = DrawOptions()) { void drawText(IStr text, Vec2 position, DrawOptions options = DrawOptions()) {
auto font = appState.font.isValid ? appState.font.get() : engineFont; auto font = appState.font.isValid ? appState.font.get() : engineFont;
if (font == engineFont) options.scale = Vec2(2); if (font == engineFont) options.scale = Vec2(2);
parin.drawText(font, text, position, options); drawTextX(font, text, position, options);
} }
void ready() { void ready() {
@ -183,6 +194,7 @@ void ready() {
bool update(float dt) { bool update(float dt) {
if (Keyboard.f11.isPressed) toggleIsFullscreen(); if (Keyboard.f11.isPressed) toggleIsFullscreen();
if (Keyboard.n1.isPressed) appState.mode = cast(AppMode) !appState.mode; if (Keyboard.n1.isPressed) appState.mode = cast(AppMode) !appState.mode;
if (Keyboard.n2.isPressed) appState.editMode = cast(EditMode) !appState.editMode;
auto windowCenter = windowSize * Vec2(0.5f); auto windowCenter = windowSize * Vec2(0.5f);
auto atlasRowCount = appState.atlas.height / appState.map.tileHeight; auto atlasRowCount = appState.atlas.height / appState.map.tileHeight;
@ -204,28 +216,54 @@ bool update(float dt) {
with (AppMode) final switch (appState.mode) { with (AppMode) final switch (appState.mode) {
case edit: case edit:
if (!appState.atlas.isValid) break; if (!appState.atlas.isValid) break;
if (!editMouseInfo.isInGrid) break;
if (0) { if (0) {
} else if (Mouse.left.isPressed) {
appState.editMainPair.a = IVec2(-100000);
} else if (Mouse.left.isDown) { } else if (Mouse.left.isDown) {
if (0) {
} else if (appState.editMode == EditMode.brush) {
auto tileArea = IRect(appState.editMainPair.a, appState.mainPair.diff);
auto userArea = IRect(editMouseInfo.gridPoint, appState.mainPair.diff);
if (tileArea.hasIntersectionInclusive(userArea)) break;
appState.editMainPair.a = editMouseInfo.gridPoint;
foreach (y; appState.mainPair.a.y .. appState.mainPair.b.y + 1) { foreach (y; appState.mainPair.a.y .. appState.mainPair.b.y + 1) {
foreach (x; appState.mainPair.a.x .. appState.mainPair.b.x + 1) { foreach (x; appState.mainPair.a.x .. appState.mainPair.b.x + 1) {
auto targetPoint = editMouseInfo.gridPoint + IVec2(x - appState.mainPair.a.x, y - appState.mainPair.a.y); auto point = editMouseInfo.gridPoint + IVec2(x - appState.mainPair.a.x, y - appState.mainPair.a.y);
if (!appState.map.has(targetPoint)) continue; if (!appState.map.has(point)) continue;
appState.map[targetPoint] = cast(short) jokaFindGridIndex(y, x, atlasColCount); appState.map[point] = cast(short) jokaFindGridIndex(y, x, atlasColCount);
} }
} }
} else if (appState.editMode == EditMode.random) {
if (!editMouseInfo.isInGrid) break;
auto x = appState.mainPair.a.x + randi % (appState.mainPair.diff.x + 1);
auto y = appState.mainPair.a.y + randi % (appState.mainPair.diff.y + 1);
appState.map[editMouseInfo.gridPoint] = cast(short) jokaFindGridIndex(y, x, atlasColCount);
} else if (appState.editMode == EditMode.eraser) {
assert(0, "NOT DONE!");
if (!editMouseInfo.isInGrid) break;
} else {
assert(0, "WTF!");
}
} else if (Mouse.right.isPressed) {
if (!editMouseInfo.isInGrid) break;
appState.editTempPair = GridPair(editMouseInfo.gridPoint);
appState.editMainPair = appState.editTempPair;
} else if (Mouse.right.isDown) { } else if (Mouse.right.isDown) {
appState.map[editMouseInfo.gridPoint] = -1; if (!editMouseInfo.isInGrid) break;
appState.editTempPair.b = editMouseInfo.gridPoint;
appState.editMainPair = appState.editTempPair;
appState.editMainPair.fix();
} }
break; break;
case select: case select:
if (!appState.atlas.isValid) break; if (!appState.atlas.isValid) break;
if (!selectMouseInfo.isInGrid) break;
if (0) { if (0) {
} else if (Mouse.left.isPressed) { } else if (Mouse.left.isPressed || Mouse.right.isPressed) {
if (!selectMouseInfo.isInGrid) break;
appState.tempPair = GridPair(selectMouseInfo.gridPoint); appState.tempPair = GridPair(selectMouseInfo.gridPoint);
appState.mainPair = appState.tempPair; appState.mainPair = appState.tempPair;
} else if (Mouse.left.isDown) { } else if (Mouse.left.isDown || Mouse.right.isDown) {
if (!selectMouseInfo.isInGrid) break;
appState.tempPair.b = selectMouseInfo.gridPoint; appState.tempPair.b = selectMouseInfo.gridPoint;
appState.mainPair = appState.tempPair; appState.mainPair = appState.tempPair;
appState.mainPair.fix(); appState.mainPair.fix();
@ -243,8 +281,13 @@ bool update(float dt) {
Rect(appState.mainPair.a.toVec() * appState.map.tileSize, appState.map.tileSize), Rect(appState.mainPair.a.toVec() * appState.map.tileSize, appState.map.tileSize),
editMouseInfo.worldGridPoint, editMouseInfo.worldGridPoint,
); );
if (appState.editMode == EditMode.brush) {
drawTextureArea(appState.atlas, Rect(appState.mainPair.a.toVec() * appState.map.tileSize, (appState.mainPair.diff + IVec2(1)).toVec() * appState.map.tileSize), editMouseInfo.worldGridPoint); drawTextureArea(appState.atlas, Rect(appState.mainPair.a.toVec() * appState.map.tileSize, (appState.mainPair.diff + IVec2(1)).toVec() * appState.map.tileSize), editMouseInfo.worldGridPoint);
drawHollowRect(Rect(editMouseInfo.worldGridPoint, (appState.mainPair.diff + IVec2(1)).toVec() * appState.map.tileSize), 1, mouseAreaColor); drawHollowRect(Rect(editMouseInfo.worldGridPoint, (appState.mainPair.diff + IVec2(1)).toVec() * appState.map.tileSize), 1, mouseAreaColor);
} else {
drawTextureArea(appState.atlas, Rect(appState.mainPair.a.toVec() * appState.map.tileSize, appState.map.tileSize), editMouseInfo.worldGridPoint);
drawHollowRect(Rect(editMouseInfo.worldGridPoint, appState.map.tileSize), 1, mouseAreaColor);
}
} }
appState.camera.detach(); appState.camera.detach();
@ -319,4 +362,4 @@ bool update(float dt) {
void finish() { } void finish() { }
mixin runGame!(ready, update, finish, 666, 666); mixin runGame!(ready, update, finish, 969, 666);

View file

@ -1,5 +1,9 @@
# This file is used by: https://github.com/Kapendev/closed # This file is used by: https://github.com/Kapendev/closed
[default]
-D=../../source/parin/story.d -D=../../source/parin/story.d
# This line works for me. Use -s=custom to fix any errors. # This line works for me. Use -s=custom to fix any errors.
-I=../../../joka/source -I=../../../joka/source
[custom]
-D=../../source/parin/story.d

View file

@ -1315,6 +1315,15 @@ void openWindow(int width, int height, const(IStr)[] args, IStr title = "Parin")
rl.UnloadImage(monogramImage); rl.UnloadImage(monogramImage);
} }
/// Passes C strings to the window arguments.
/// You should avoid calling this function manually.
@trusted
void openWindowExtraStep(int argc, immutable(char)** argv) {
engineState.envArgsBuffer.clear();
foreach (i; 0 .. argc) engineState.envArgsBuffer.append(argv[i].cStrToStr());
if (engineState.envArgsBuffer.length) engineState.assetsPath.append(pathConcat(engineState.envArgsBuffer[0].pathDirName, "assets"));
}
/// Updates the window every frame with the given function. /// Updates the window every frame with the given function.
/// This function will return when the given function returns true. /// This function will return when the given function returns true.
/// You should avoid calling this function manually. /// You should avoid calling this function manually.
@ -1792,7 +1801,7 @@ float deltaWheel() {
/// Measures the size of the specified text when rendered with the given font and draw options. /// Measures the size of the specified text when rendered with the given font and draw options.
@trusted @trusted
Vec2 measureTextSize(Font font, IStr text, DrawOptions options = DrawOptions(), TextOptions extraOptions = TextOptions()) { Vec2 measureTextSizeX(Font font, IStr text, DrawOptions options = DrawOptions(), TextOptions extraOptions = TextOptions()) {
if (font.isEmpty || text.length == 0) return Vec2(); if (font.isEmpty || text.length == 0) return Vec2();
auto lineCodepointCount = 0; auto lineCodepointCount = 0;
@ -1828,7 +1837,7 @@ Vec2 measureTextSize(Font font, IStr text, DrawOptions options = DrawOptions(),
/// Measures the size of the specified text when rendered with the given font and draw options. /// Measures the size of the specified text when rendered with the given font and draw options.
Vec2 measureTextSize(FontId font, IStr text, DrawOptions options = DrawOptions()) { Vec2 measureTextSize(FontId font, IStr text, DrawOptions options = DrawOptions()) {
return measureTextSize(font.getOr(), text, options); return measureTextSizeX(font.getOr(), text, options);
} }
/// Returns true if the specified key is currently pressed. /// Returns true if the specified key is currently pressed.
@ -1975,9 +1984,9 @@ Vec2 wasdReleased() {
/// Plays the specified sound. /// Plays the specified sound.
@trusted @trusted
void playSound(ref Sound sound) { void playSoundX(ref Sound sound) {
if (sound.isEmpty) return; if (sound.isEmpty) return;
if (sound.isPaused) resumeSound(sound); if (sound.isPaused) resumeSoundX(sound);
if (sound.data.isType!(rl.Sound)) { if (sound.data.isType!(rl.Sound)) {
rl.PlaySound(sound.data.get!(rl.Sound)()); rl.PlaySound(sound.data.get!(rl.Sound)());
} else { } else {
@ -1988,12 +1997,12 @@ void playSound(ref Sound sound) {
/// Plays the specified sound. /// Plays the specified sound.
void playSound(SoundId sound) { void playSound(SoundId sound) {
if (sound.isValid) playSound(sound.get()); if (sound.isValid) playSoundX(sound.get());
} }
/// Stops playback of the specified sound. /// Stops playback of the specified sound.
@trusted @trusted
void stopSound(ref Sound sound) { void stopSoundX(ref Sound sound) {
if (sound.isEmpty) return; if (sound.isEmpty) return;
if (sound.data.isType!(rl.Sound)) { if (sound.data.isType!(rl.Sound)) {
rl.StopSound(sound.data.get!(rl.Sound)()); rl.StopSound(sound.data.get!(rl.Sound)());
@ -2004,12 +2013,12 @@ void stopSound(ref Sound sound) {
/// Stops playback of the specified sound. /// Stops playback of the specified sound.
void stopSound(SoundId sound) { void stopSound(SoundId sound) {
if (sound.isValid) stopSound(sound.get()); if (sound.isValid) stopSoundX(sound.get());
} }
/// Pauses playback of the specified sound. /// Pauses playback of the specified sound.
@trusted @trusted
void pauseSound(ref Sound sound) { void pauseSoundX(ref Sound sound) {
if (sound.isEmpty) return; if (sound.isEmpty) return;
sound.isPaused = true; sound.isPaused = true;
if (sound.data.isType!(rl.Sound)) { if (sound.data.isType!(rl.Sound)) {
@ -2021,12 +2030,12 @@ void pauseSound(ref Sound sound) {
/// Pauses playback of the specified sound. /// Pauses playback of the specified sound.
void pauseSound(SoundId sound) { void pauseSound(SoundId sound) {
if (sound.isValid) pauseSound(sound.get()); if (sound.isValid) pauseSoundX(sound.get());
} }
/// Resumes playback of the specified paused sound. /// Resumes playback of the specified paused sound.
@trusted @trusted
void resumeSound(ref Sound sound) { void resumeSoundX(ref Sound sound) {
if (sound.isEmpty) return; if (sound.isEmpty) return;
sound.isPaused = false; sound.isPaused = false;
if (sound.data.isType!(rl.Sound)) { if (sound.data.isType!(rl.Sound)) {
@ -2038,24 +2047,24 @@ void resumeSound(ref Sound sound) {
/// Resumes playback of the specified paused sound. /// Resumes playback of the specified paused sound.
void resumeSound(SoundId sound) { void resumeSound(SoundId sound) {
if (sound.isValid) resumeSound(sound.get()); if (sound.isValid) resumeSoundX(sound.get());
} }
/// Updates the playback state of the specified sound. /// Updates the playback state of the specified sound.
@trusted @trusted
void updateSound(ref Sound sound) { void updateSoundX(ref Sound sound) {
if (sound.isEmpty) return; if (sound.isEmpty) return;
if (sound.data.isType!(rl.Sound)) { if (sound.data.isType!(rl.Sound)) {
if (sound.isLooping && !sound.isPlaying) playSound(sound); if (sound.isLooping && !sound.isPlaying) playSoundX(sound);
} else { } else {
if (!sound.isLooping && (sound.duration - sound.time) < 0.1f) stopSound(sound); if (!sound.isLooping && (sound.duration - sound.time) < 0.1f) stopSoundX(sound);
rl.UpdateMusicStream(sound.data.get!(rl.Music)()); rl.UpdateMusicStream(sound.data.get!(rl.Music)());
} }
} }
/// Updates the playback state of the specified sound. /// Updates the playback state of the specified sound.
void updateSound(SoundId sound) { void updateSound(SoundId sound) {
if (sound.isValid) updateSound(sound.get()); if (sound.isValid) updateSoundX(sound.get());
} }
/// Draws a rectangle with the specified area and color. /// Draws a rectangle with the specified area and color.
@ -2115,7 +2124,7 @@ void drawLine(Line area, float size, Color color = white) {
/// Draws a portion of the specified texture at the given position with the specified draw options. /// Draws a portion of the specified texture at the given position with the specified draw options.
@trusted @trusted
void drawTextureArea(Texture texture, Rect area, Vec2 position, DrawOptions options = DrawOptions()) { void drawTextureAreaX(Texture texture, Rect area, Vec2 position, DrawOptions options = DrawOptions()) {
if (texture.isEmpty || area.size.x <= 0.0f || area.size.y <= 0.0f) return; if (texture.isEmpty || area.size.x <= 0.0f || area.size.y <= 0.0f) return;
auto target = Rect(position, area.size * options.scale.abs()); auto target = Rect(position, area.size * options.scale.abs());
auto origin = options.origin.isZero ? target.origin(options.hook) : options.origin; auto origin = options.origin.isZero ? target.origin(options.hook) : options.origin;
@ -2156,21 +2165,21 @@ void drawTextureArea(Texture texture, Rect area, Vec2 position, DrawOptions opti
/// Draws a portion of the specified texture at the given position with the specified draw options. /// Draws a portion of the specified texture at the given position with the specified draw options.
void drawTextureArea(TextureId texture, Rect area, Vec2 position, DrawOptions options = DrawOptions()) { void drawTextureArea(TextureId texture, Rect area, Vec2 position, DrawOptions options = DrawOptions()) {
drawTextureArea(texture.getOr(), area, position, options); drawTextureAreaX(texture.getOr(), area, position, options);
} }
/// Draws the texture at the given position with the specified draw options. /// Draws the texture at the given position with the specified draw options.
void drawTexture(Texture texture, Vec2 position, DrawOptions options = DrawOptions()) { void drawTextureX(Texture texture, Vec2 position, DrawOptions options = DrawOptions()) {
drawTextureArea(texture, Rect(texture.size), position, options); drawTextureAreaX(texture, Rect(texture.size), position, options);
} }
/// Draws the texture at the given position with the specified draw options. /// Draws the texture at the given position with the specified draw options.
void drawTexture(TextureId texture, Vec2 position, DrawOptions options = DrawOptions()) { void drawTexture(TextureId texture, Vec2 position, DrawOptions options = DrawOptions()) {
drawTexture(texture.getOr(), position, options); drawTextureX(texture.getOr(), position, options);
} }
/// Draws a 9-patch texture from the specified texture area at the given target area. /// Draws a 9-patch texture from the specified texture area at the given target area.
void drawTexturePatch(Texture texture, Rect area, Rect target, bool isTiled, DrawOptions options = DrawOptions()) { void drawTexturePatchX(Texture texture, Rect area, Rect target, bool isTiled, DrawOptions options = DrawOptions()) {
auto tileSize = (area.size / Vec2(3.0f)).floor(); auto tileSize = (area.size / Vec2(3.0f)).floor();
auto hOptions = options; auto hOptions = options;
auto vOptions = options; auto vOptions = options;
@ -2183,7 +2192,7 @@ void drawTexturePatch(Texture texture, Rect area, Rect target, bool isTiled, Dra
// 1 // 1
auto partPosition = target.position; auto partPosition = target.position;
auto partArea = Rect(area.position, tileSize); auto partArea = Rect(area.position, tileSize);
drawTextureArea(texture, partArea, partPosition, options); drawTextureAreaX(texture, partArea, partPosition, options);
// 2 // 2
partPosition.x += tileSize.x * options.scale.x; partPosition.x += tileSize.x * options.scale.x;
partArea.position.x += tileSize.x; partArea.position.x += tileSize.x;
@ -2191,15 +2200,15 @@ void drawTexturePatch(Texture texture, Rect area, Rect target, bool isTiled, Dra
foreach (i; 0 .. cast(int) cleanScaleX.ceil()) { foreach (i; 0 .. cast(int) cleanScaleX.ceil()) {
auto tempPartPosition = partPosition; auto tempPartPosition = partPosition;
tempPartPosition.x += i * tileSize.x * options.scale.x; tempPartPosition.x += i * tileSize.x * options.scale.x;
drawTextureArea(texture, partArea, tempPartPosition, options); drawTextureAreaX(texture, partArea, tempPartPosition, options);
} }
} else { } else {
drawTextureArea(texture, partArea, partPosition, hOptions); drawTextureAreaX(texture, partArea, partPosition, hOptions);
} }
// 3 // 3
partPosition.x += tileSize.x * hOptions.scale.x; partPosition.x += tileSize.x * hOptions.scale.x;
partArea.position.x += tileSize.x; partArea.position.x += tileSize.x;
drawTextureArea(texture, partArea, partPosition, options); drawTextureAreaX(texture, partArea, partPosition, options);
// 4 // 4
partPosition.x = target.position.x; partPosition.x = target.position.x;
partPosition.y += tileSize.y * options.scale.y; partPosition.y += tileSize.y * options.scale.y;
@ -2209,15 +2218,15 @@ void drawTexturePatch(Texture texture, Rect area, Rect target, bool isTiled, Dra
foreach (i; 0 .. cast(int) cleanScaleY.ceil()) { foreach (i; 0 .. cast(int) cleanScaleY.ceil()) {
auto tempPartPosition = partPosition; auto tempPartPosition = partPosition;
tempPartPosition.y += i * tileSize.y * options.scale.y; tempPartPosition.y += i * tileSize.y * options.scale.y;
drawTextureArea(texture, partArea, tempPartPosition, options); drawTextureAreaX(texture, partArea, tempPartPosition, options);
} }
} else { } else {
drawTextureArea(texture, partArea, partPosition, vOptions); drawTextureAreaX(texture, partArea, partPosition, vOptions);
} }
// 5 // 5
partPosition.x += tileSize.x * options.scale.x; partPosition.x += tileSize.x * options.scale.x;
partArea.position.x += tileSize.x; partArea.position.x += tileSize.x;
drawTextureArea(texture, partArea, partPosition, cOptions); drawTextureAreaX(texture, partArea, partPosition, cOptions);
// 6 // 6
partPosition.x += tileSize.x * hOptions.scale.x; partPosition.x += tileSize.x * hOptions.scale.x;
partArea.position.x += tileSize.x; partArea.position.x += tileSize.x;
@ -2225,17 +2234,17 @@ void drawTexturePatch(Texture texture, Rect area, Rect target, bool isTiled, Dra
foreach (i; 0 .. cast(int) cleanScaleY.ceil()) { foreach (i; 0 .. cast(int) cleanScaleY.ceil()) {
auto tempPartPosition = partPosition; auto tempPartPosition = partPosition;
tempPartPosition.y += i * tileSize.y * options.scale.y; tempPartPosition.y += i * tileSize.y * options.scale.y;
drawTextureArea(texture, partArea, tempPartPosition, options); drawTextureAreaX(texture, partArea, tempPartPosition, options);
} }
} else { } else {
drawTextureArea(texture, partArea, partPosition, vOptions); drawTextureAreaX(texture, partArea, partPosition, vOptions);
} }
// 7 // 7
partPosition.x = target.position.x; partPosition.x = target.position.x;
partPosition.y += tileSize.y * vOptions.scale.y; partPosition.y += tileSize.y * vOptions.scale.y;
partArea.position.x = area.position.x; partArea.position.x = area.position.x;
partArea.position.y += tileSize.y; partArea.position.y += tileSize.y;
drawTextureArea(texture, partArea, partPosition, options); drawTextureAreaX(texture, partArea, partPosition, options);
// 8 // 8
partPosition.x += tileSize.x * options.scale.x; partPosition.x += tileSize.x * options.scale.x;
partArea.position.x += tileSize.x; partArea.position.x += tileSize.x;
@ -2243,20 +2252,20 @@ void drawTexturePatch(Texture texture, Rect area, Rect target, bool isTiled, Dra
foreach (i; 0 .. cast(int) cleanScaleX.ceil()) { foreach (i; 0 .. cast(int) cleanScaleX.ceil()) {
auto tempPartPosition = partPosition; auto tempPartPosition = partPosition;
tempPartPosition.x += i * tileSize.x * options.scale.x; tempPartPosition.x += i * tileSize.x * options.scale.x;
drawTextureArea(texture, partArea, tempPartPosition, options); drawTextureAreaX(texture, partArea, tempPartPosition, options);
} }
} else { } else {
drawTextureArea(texture, partArea, partPosition, hOptions); drawTextureAreaX(texture, partArea, partPosition, hOptions);
} }
// 9 // 9
partPosition.x += tileSize.x * hOptions.scale.x; partPosition.x += tileSize.x * hOptions.scale.x;
partArea.position.x += tileSize.x; partArea.position.x += tileSize.x;
drawTextureArea(texture, partArea, partPosition, options); drawTextureAreaX(texture, partArea, partPosition, options);
} }
/// Draws a 9-patch texture from the specified texture area at the given target area. /// Draws a 9-patch texture from the specified texture area at the given target area.
void drawTexturePatch(TextureId texture, Rect area, Rect target, bool isTiled, DrawOptions options = DrawOptions()) { void drawTexturePatch(TextureId texture, Rect area, Rect target, bool isTiled, DrawOptions options = DrawOptions()) {
drawTexturePatch(texture.getOr(), area, target, isTiled, options); drawTexturePatchX(texture.getOr(), area, target, isTiled, options);
} }
/// Draws a portion of the specified viewport at the given position with the specified draw options. /// Draws a portion of the specified viewport at the given position with the specified draw options.
@ -2268,7 +2277,7 @@ void drawViewportArea(Viewport viewport, Rect area, Vec2 position, DrawOptions o
case Flip.y: options.flip = Flip.none; break; case Flip.y: options.flip = Flip.none; break;
case Flip.xy: options.flip = Flip.x; break; case Flip.xy: options.flip = Flip.x; break;
} }
drawTextureArea(viewport.data.texture.toParin(), area, position, options); drawTextureAreaX(viewport.data.texture.toParin(), area, position, options);
} }
/// Draws the viewport at the given position with the specified draw options. /// Draws the viewport at the given position with the specified draw options.
@ -2278,7 +2287,7 @@ void drawViewport(Viewport viewport, Vec2 position, DrawOptions options = DrawOp
/// Draws a single character from the specified font at the given position with the specified draw options. /// Draws a single character from the specified font at the given position with the specified draw options.
@trusted @trusted
void drawRune(Font font, dchar rune, Vec2 position, DrawOptions options = DrawOptions()) { void drawRuneX(Font font, dchar rune, Vec2 position, DrawOptions options = DrawOptions()) {
if (font.isEmpty) return; if (font.isEmpty) return;
auto rect = toParin(rl.GetGlyphAtlasRec(font.data, rune)); auto rect = toParin(rl.GetGlyphAtlasRec(font.data, rune));
auto origin = options.origin.isZero ? rect.origin(options.hook) : options.origin; auto origin = options.origin.isZero ? rect.origin(options.hook) : options.origin;
@ -2297,13 +2306,13 @@ void drawRune(Font font, dchar rune, Vec2 position, DrawOptions options = DrawOp
/// Draws a single character from the specified font at the given position with the specified draw options. /// Draws a single character from the specified font at the given position with the specified draw options.
void drawRune(FontId font, dchar rune, Vec2 position, DrawOptions options = DrawOptions()) { void drawRune(FontId font, dchar rune, Vec2 position, DrawOptions options = DrawOptions()) {
drawRune(font.getOr(), rune, position, options); drawRuneX(font.getOr(), rune, position, options);
} }
/// Draws the specified text with the given font at the given position using the provided draw options. /// Draws the specified text with the given font at the given position using the provided draw options.
// NOTE: Text drawing needs to go over the text 3 times. This can be made into 2 times in the future if needed by copy-pasting the measureTextSize inside this function. // NOTE: Text drawing needs to go over the text 3 times. This can be made into 2 times in the future if needed by copy-pasting the measureTextSize inside this function.
@trusted @trusted
void drawText(Font font, IStr text, Vec2 position, DrawOptions options = DrawOptions(), TextOptions extraOptions = TextOptions()) { void drawTextX(Font font, IStr text, Vec2 position, DrawOptions options = DrawOptions(), TextOptions extraOptions = TextOptions()) {
static FixedList!(IStr, 128) linesBuffer = void; static FixedList!(IStr, 128) linesBuffer = void;
static FixedList!(short, 128) linesWidthBuffer = void; static FixedList!(short, 128) linesWidthBuffer = void;
@ -2323,7 +2332,7 @@ void drawText(Font font, IStr text, Vec2 position, DrawOptions options = DrawOpt
auto codepoint = rl.GetCodepointNext(&text[textCodepointIndex], &codepointSize); auto codepoint = rl.GetCodepointNext(&text[textCodepointIndex], &codepointSize);
if (codepoint == '\n' || textCodepointIndex == text.length - codepointSize) { if (codepoint == '\n' || textCodepointIndex == text.length - codepointSize) {
linesBuffer.append(text[lineCodepointIndex .. textCodepointIndex + (codepoint != '\n')]); linesBuffer.append(text[lineCodepointIndex .. textCodepointIndex + (codepoint != '\n')]);
linesWidthBuffer.append(cast(ushort) (measureTextSize(font, linesBuffer[$ - 1]).x)); linesWidthBuffer.append(cast(ushort) (measureTextSizeX(font, linesBuffer[$ - 1]).x));
if (textMaxLineWidth < linesWidthBuffer[$ - 1]) textMaxLineWidth = linesWidthBuffer[$ - 1]; if (textMaxLineWidth < linesWidthBuffer[$ - 1]) textMaxLineWidth = linesWidthBuffer[$ - 1];
if (codepoint == '\n') textHeight += font.lineSpacing; if (codepoint == '\n') textHeight += font.lineSpacing;
lineCodepointIndex = cast(ushort) (textCodepointIndex + 1); lineCodepointIndex = cast(ushort) (textCodepointIndex + 1);
@ -2425,12 +2434,12 @@ void drawText(Font font, IStr text, Vec2 position, DrawOptions options = DrawOpt
/// Draws text with the given font at the given position using the provided draw options. /// Draws text with the given font at the given position using the provided draw options.
void drawText(FontId font, IStr text, Vec2 position, DrawOptions options = DrawOptions(), TextOptions extraOptions = TextOptions()) { void drawText(FontId font, IStr text, Vec2 position, DrawOptions options = DrawOptions(), TextOptions extraOptions = TextOptions()) {
drawText(font.getOr(), text, position, options, extraOptions); drawTextX(font.getOr(), text, position, options, extraOptions);
} }
/// Draws debug text at the given position with the provided draw options. /// Draws debug text at the given position with the provided draw options.
void drawDebugText(IStr text, Vec2 position, DrawOptions options = DrawOptions(), TextOptions extraOptions = TextOptions()) { void drawDebugText(IStr text, Vec2 position, DrawOptions options = DrawOptions(), TextOptions extraOptions = TextOptions()) {
drawText(engineFont, text, position, options, extraOptions); drawTextX(engineFont, text, position, options, extraOptions);
} }
/// Mixes in a game loop template with specified functions for initialization, update, and cleanup, and sets window size and title. /// Mixes in a game loop template with specified functions for initialization, update, and cleanup, and sets window size and title.
@ -2438,13 +2447,8 @@ mixin template runGame(alias readyFunc, alias updateFunc, alias finishFunc, int
version (D_BetterC) { version (D_BetterC) {
extern(C) extern(C)
void main(int argc, immutable(char)** argv) { void main(int argc, immutable(char)** argv) {
openWindow(width, height, [], title); openWindow(width, height, null, title);
foreach (i; 0 .. argc) { openWindowExtraStep(argc, argv);
Sz length = 0;
while (argv[i][length] != '\0') length += 1;
engineState.envArgsBuffer.append(argv[i][0 .. length]);
}
engineState.assetsPath.append(pathConcat(engineState.envArgsBuffer[0].pathDir, "assets"));
readyFunc(); readyFunc();
updateWindow(&updateFunc); updateWindow(&updateFunc);
finishFunc(); finishFunc();

View file

@ -312,16 +312,16 @@ Fault saveTileMap(IStr path, TileMap map) {
return saveText(path, csv.items); return saveText(path, csv.items);
} }
void drawTile(Texture texture, Tile tile, DrawOptions options = DrawOptions()) { void drawTileX(Texture texture, Tile tile, DrawOptions options = DrawOptions()) {
if (texture.isEmpty || tile.id < 0 || tile.width <= 0 || tile.height <= 0) return; if (texture.isEmpty || tile.id < 0 || tile.width <= 0 || tile.height <= 0) return;
drawTextureArea(texture, tile.textureArea(texture.width / tile.width), tile.position, options); drawTextureAreaX(texture, tile.textureArea(texture.width / tile.width), tile.position, options);
} }
void drawTile(TextureId texture, Tile tile, DrawOptions options = DrawOptions()) { void drawTile(TextureId texture, Tile tile, DrawOptions options = DrawOptions()) {
drawTile(texture.getOr(), tile, options); drawTileX(texture.getOr(), tile, options);
} }
void drawTileMap(Texture texture, TileMap map, Camera camera, DrawOptions options = DrawOptions()) { void drawTileMapX(Texture texture, TileMap map, Camera camera, DrawOptions options = DrawOptions()) {
if (texture.isEmpty || map.softRowCount == 0 || map.softColCount == 0 || map.tileWidth <= 0 || map.tileHeight <= 0) return; if (texture.isEmpty || map.softRowCount == 0 || map.softColCount == 0 || map.tileWidth <= 0 || map.tileHeight <= 0) return;
auto topLeftWorldPoint = camera.topLeftPoint; auto topLeftWorldPoint = camera.topLeftPoint;
auto bottomRightWorldPoint = camera.bottomRightPoint; auto bottomRightWorldPoint = camera.bottomRightPoint;
@ -344,7 +344,7 @@ void drawTileMap(Texture texture, TileMap map, Camera camera, DrawOptions option
if (id < 0) continue; if (id < 0) continue;
textureArea.position.x = (id % textureColCount) * map.tileWidth; textureArea.position.x = (id % textureColCount) * map.tileWidth;
textureArea.position.y = (id / textureColCount) * map.tileHeight; textureArea.position.y = (id / textureColCount) * map.tileHeight;
drawTextureArea( drawTextureAreaX(
texture, texture,
textureArea, textureArea,
map.position + Vec2(col * targetTileWidth, row * targetTileHeight), map.position + Vec2(col * targetTileWidth, row * targetTileHeight),
@ -355,5 +355,5 @@ void drawTileMap(Texture texture, TileMap map, Camera camera, DrawOptions option
} }
void drawTileMap(TextureId texture, TileMap map, Camera camera, DrawOptions options = DrawOptions()) { void drawTileMap(TextureId texture, TileMap map, Camera camera, DrawOptions options = DrawOptions()) {
drawTileMap(texture.getOr(), map, camera, options); drawTileMapX(texture.getOr(), map, camera, options);
} }

View file

@ -145,7 +145,7 @@ struct Sprite {
} }
} }
void drawSprite(Texture texture, Sprite sprite, DrawOptions options = DrawOptions()) { void drawSpriteX(Texture texture, Sprite sprite, DrawOptions options = DrawOptions()) {
if (sprite.width == 0 || sprite.height == 0) return; if (sprite.width == 0 || sprite.height == 0) return;
auto top = sprite.atlasTop + sprite.animation.frameRow * sprite.height; auto top = sprite.atlasTop + sprite.animation.frameRow * sprite.height;
@ -156,9 +156,9 @@ void drawSprite(Texture texture, Sprite sprite, DrawOptions options = DrawOption
auto row = sprite.frame / gridWidth; auto row = sprite.frame / gridWidth;
auto col = sprite.frame % gridWidth; auto col = sprite.frame % gridWidth;
auto area = Rect(sprite.atlasLeft + col * sprite.width, top + row * sprite.height, sprite.width, sprite.height); auto area = Rect(sprite.atlasLeft + col * sprite.width, top + row * sprite.height, sprite.width, sprite.height);
drawTextureArea(texture, area, sprite.position, options); drawTextureAreaX(texture, area, sprite.position, options);
} }
void drawSprite(TextureId texture, Sprite sprite, DrawOptions options = DrawOptions()) { void drawSprite(TextureId texture, Sprite sprite, DrawOptions options = DrawOptions()) {
drawSprite(texture.getOr(), sprite, options); drawSpriteX(texture.getOr(), sprite, options);
} }

View file

@ -320,7 +320,7 @@ void drawUiText(Rect area, IStr text, UiOptions options = UiOptions()) {
if (options.isDisabled && drawOptions.color.a >= options.fontAlphaOffset) { if (options.isDisabled && drawOptions.color.a >= options.fontAlphaOffset) {
drawOptions.color.a -= options.fontAlphaOffset; drawOptions.color.a -= options.fontAlphaOffset;
} }
drawText(font, text, textPosition, drawOptions, extraOptions); drawTextX(font, text, textPosition, drawOptions, extraOptions);
} }
void uiText(Rect area, IStr text, UiOptions options = UiOptions()) { void uiText(Rect area, IStr text, UiOptions options = UiOptions()) {
@ -534,7 +534,7 @@ void drawUiTextField(Rect area, Str text, UiOptions options = UiOptions()) {
} }
textPosition = textPosition.round(); textPosition = textPosition.round();
// --- // ---
auto textSize = measureTextSize(font, text); auto textSize = measureTextSizeX(font, text);
auto cursorPosition = textPosition; auto cursorPosition = textPosition;
final switch (options.alignment) { final switch (options.alignment) {
case Alignment.left: cursorPosition.x += textSize.x * options.fontScale + defaultUiTextFieldCursorOffset; break; case Alignment.left: cursorPosition.x += textSize.x * options.fontScale + defaultUiTextFieldCursorOffset; break;