mirror of
https://github.com/curioustorvald/Terrarum.git
synced 2026-06-06 08:38:30 +09:00
Compare commits
2 Commits
6118f30d5f
...
8eff89a7cb
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8eff89a7cb | ||
|
|
73c7c8942e |
23
.idea/csv-editor.xml
generated
23
.idea/csv-editor.xml
generated
@@ -1,23 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<project version="4">
|
|
||||||
<component name="CsvFileAttributes">
|
|
||||||
<option name="attributeMap">
|
|
||||||
<map>
|
|
||||||
<entry key="/Terrarum.wiki/Items.md">
|
|
||||||
<value>
|
|
||||||
<Attribute>
|
|
||||||
<option name="separator" value="," />
|
|
||||||
</Attribute>
|
|
||||||
</value>
|
|
||||||
</entry>
|
|
||||||
<entry key="/Terrarum.wiki/Modules:Setup.md">
|
|
||||||
<value>
|
|
||||||
<Attribute>
|
|
||||||
<option name="separator" value="," />
|
|
||||||
</Attribute>
|
|
||||||
</value>
|
|
||||||
</entry>
|
|
||||||
</map>
|
|
||||||
</option>
|
|
||||||
</component>
|
|
||||||
</project>
|
|
||||||
@@ -172,5 +172,5 @@ Both save/restore `camera.position` and call `setToOrtho` with `App.scr.wf/hf` o
|
|||||||
- **`lateinit var` guards**: Use `::prop.isInitialized` checks in `resize()` and `dispose()` for properties set during async loading steps.
|
- **`lateinit var` guards**: Use `::prop.isInitialized` checks in `resize()` and `dispose()` for properties set during async loading steps.
|
||||||
- **`ConsistentUpdateRate`**: Accumulates delta time; may call `updateFunction` multiple times before `renderFunction`. Call `.reset()` before transitioning to active rendering to avoid catch-up storms.
|
- **`ConsistentUpdateRate`**: Accumulates delta time; may call `updateFunction` multiple times before `renderFunction`. Call `.reset()` before transitioning to active rendering to avoid catch-up storms.
|
||||||
- **Textures**: Use TGA format. Images with semitransparency must be TGA; opaque images may be PNG.
|
- **Textures**: Use TGA format. Images with semitransparency must be TGA; opaque images may be PNG.
|
||||||
- **Coordinate system**: Y-down (camera `setToOrtho(true, ...)`). `setCameraPosition(0, 0)` places origin at screen top-left.
|
- **Coordinate system**: Y-down (camera `setToOrtho(true, ...)`). `setCameraPosition(0, 0)` places origin at screen top-left, which is not LibGDX nor OpenGL works natively, hence the existence of `FlippingSpriteBatch`. If the user reports renders are flipped vertically, try draw()/drawFlipped() accordingly.
|
||||||
- **ROUNDWORLD**: World wraps horizontally. `WorldCamera.x` uses `fmod worldWidth`. Lightmap and tile drawing account for wrapping.
|
- **ROUNDWORLD**: World wraps horizontally. `WorldCamera.x` uses `fmod worldWidth`. Lightmap and tile drawing account for wrapping.
|
||||||
|
|||||||
@@ -336,7 +336,7 @@ public class App implements ApplicationListener {
|
|||||||
"xinput", "xbox", "game", "joy", "pad"
|
"xinput", "xbox", "game", "joy", "pad"
|
||||||
};
|
};
|
||||||
|
|
||||||
public static InputStrober inputStrober;
|
public static InputStrober inputStrober; // set by IME.kt loading thread
|
||||||
|
|
||||||
public static long bogoflops = 0L;
|
public static long bogoflops = 0L;
|
||||||
|
|
||||||
@@ -900,7 +900,7 @@ public class App implements ApplicationListener {
|
|||||||
logoBatch.end();
|
logoBatch.end();
|
||||||
}
|
}
|
||||||
|
|
||||||
int logoPosX = (int)(logoPosX0 + Math.round(100 * Math.sin(GLOBAL_RENDER_TIMER / 50.0)));
|
int logoPosX = logoPosX0;//(int)(logoPosX0 + Math.round(100 * Math.sin(GLOBAL_RENDER_TIMER / 50.0)));
|
||||||
|
|
||||||
// draw logo reflection
|
// draw logo reflection
|
||||||
logoBatch.setShader(shaderReflect);
|
logoBatch.setShader(shaderReflect);
|
||||||
@@ -1275,13 +1275,12 @@ public class App implements ApplicationListener {
|
|||||||
false,
|
false,
|
||||||
64, false, 203f/255f, false
|
64, false, 203f/255f, false
|
||||||
);
|
);
|
||||||
Lang.invoke();
|
|
||||||
|
|
||||||
printdbg(this, "Font done at "+((System.nanoTime() - t1) / 1000000000.0)+" seconds");
|
|
||||||
|
|
||||||
fontSmallNumbers = TinyAlphNum.INSTANCE;
|
fontSmallNumbers = TinyAlphNum.INSTANCE;
|
||||||
fontBigNumbers = BigAlphNum.INSTANCE;
|
fontBigNumbers = BigAlphNum.INSTANCE;
|
||||||
|
|
||||||
|
printdbg(this, "Font done at "+((System.nanoTime() - t1) / 1000000000.0)+" seconds");
|
||||||
|
|
||||||
try {
|
try {
|
||||||
audioDevice = Gdx.audio.newAudioDevice(48000, false);
|
audioDevice = Gdx.audio.newAudioDevice(48000, false);
|
||||||
}
|
}
|
||||||
@@ -1290,14 +1289,19 @@ public class App implements ApplicationListener {
|
|||||||
System.err.println("[AppLoader] failed to create audio device: Audio device occupied by Exclusive Mode Device? (e.g. ASIO4all)");
|
System.err.println("[AppLoader] failed to create audio device: Audio device occupied by Exclusive Mode Device? (e.g. ASIO4all)");
|
||||||
}
|
}
|
||||||
|
|
||||||
IME.invoke();
|
printdbg(this, "AudioDevice done at "+((System.nanoTime() - t1) / 1000000000.0)+" seconds");
|
||||||
inputStrober = InputStrober.INSTANCE;
|
|
||||||
printdbg(this, "IME done (loading thread) at "+((System.nanoTime() - t1) / 1000000000.0)+" seconds");
|
IME.invoke(); // calls `App.inputStrober = InputStrober` on our behalf
|
||||||
|
printdbg(this, "IME done at "+((System.nanoTime() - t1) / 1000000000.0)+" seconds");
|
||||||
|
|
||||||
// Set GL thread reference for CommonResourcePool dispatch
|
// Set GL thread reference for CommonResourcePool dispatch
|
||||||
CommonResourcePool.INSTANCE.setGLThread(Thread.currentThread());
|
CommonResourcePool.INSTANCE.setGLThread(Thread.currentThread());
|
||||||
// Launch loading thread for ModMgr + slow resource loading
|
// Launch loading thread for ModMgr + slow resource loading
|
||||||
postInitLoadingThread = new Thread(() -> {
|
postInitLoadingThread = new Thread(() -> {
|
||||||
|
Lang.invoke();
|
||||||
|
|
||||||
|
printdbg(this, "Lang done (loading thread) at "+((System.nanoTime() - t1) / 1000000000.0)+" seconds");
|
||||||
|
|
||||||
ModMgr.INSTANCE.invoke(); // triggers module init block + EntryPoint.invoke() calls
|
ModMgr.INSTANCE.invoke(); // triggers module init block + EntryPoint.invoke() calls
|
||||||
|
|
||||||
printdbg(this, "ModMgr done (loading thread) at "+((System.nanoTime() - t1) / 1000000000.0)+" seconds");
|
printdbg(this, "ModMgr done (loading thread) at "+((System.nanoTime() - t1) / 1000000000.0)+" seconds");
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
package net.torvald.terrarum.gamecontroller
|
package net.torvald.terrarum.gamecontroller
|
||||||
|
|
||||||
import com.badlogic.gdx.Gdx
|
|
||||||
import com.badlogic.gdx.files.FileHandle
|
import com.badlogic.gdx.files.FileHandle
|
||||||
import com.badlogic.gdx.graphics.Pixmap
|
import com.badlogic.gdx.graphics.Pixmap
|
||||||
import com.badlogic.gdx.graphics.g2d.TextureRegion
|
import com.badlogic.gdx.graphics.g2d.TextureRegion
|
||||||
@@ -111,6 +110,8 @@ object IME {
|
|||||||
printdbg(this, "Registering High layer ${it.nameWithoutExtension.lowercase()}")
|
printdbg(this, "Registering High layer ${it.nameWithoutExtension.lowercase()}")
|
||||||
registerHighLayer(it.nameWithoutExtension.lowercase(), parseImeFile(it))
|
registerHighLayer(it.nameWithoutExtension.lowercase(), parseImeFile(it))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
App.inputStrober = InputStrober
|
||||||
}, "Terrarum-IMELoader")
|
}, "Terrarum-IMELoader")
|
||||||
layoutLoadingThread.isDaemon = true
|
layoutLoadingThread.isDaemon = true
|
||||||
layoutLoadingThread.start()
|
layoutLoadingThread.start()
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import com.badlogic.gdx.Input
|
|||||||
import com.badlogic.gdx.InputAdapter
|
import com.badlogic.gdx.InputAdapter
|
||||||
import com.badlogic.gdx.graphics.Color
|
import com.badlogic.gdx.graphics.Color
|
||||||
import com.badlogic.gdx.graphics.OrthographicCamera
|
import com.badlogic.gdx.graphics.OrthographicCamera
|
||||||
|
import com.badlogic.gdx.graphics.Pixmap
|
||||||
import com.badlogic.gdx.graphics.Texture
|
import com.badlogic.gdx.graphics.Texture
|
||||||
import com.badlogic.gdx.graphics.g2d.SpriteBatch
|
import com.badlogic.gdx.graphics.g2d.SpriteBatch
|
||||||
import com.badlogic.gdx.graphics.g2d.TextureRegion
|
import com.badlogic.gdx.graphics.g2d.TextureRegion
|
||||||
@@ -71,6 +72,10 @@ class TitleScreen(batch: FlippingSpriteBatch) : IngameInstance(batch) {
|
|||||||
private var glLoadStep = 0
|
private var glLoadStep = 0
|
||||||
private lateinit var titleLoadingThread: Thread
|
private lateinit var titleLoadingThread: Thread
|
||||||
|
|
||||||
|
private var splashCapture: Texture? = null
|
||||||
|
private var settleFrames = 0
|
||||||
|
private var transitionState = 0 // 0=loading, 1=settling, 2=fading, 3=done
|
||||||
|
|
||||||
private lateinit var demoWorld: GameWorld
|
private lateinit var demoWorld: GameWorld
|
||||||
private lateinit var cameraNodes: FloatArray // camera Y-pos
|
private lateinit var cameraNodes: FloatArray // camera Y-pos
|
||||||
private val cameraNodeWidth = 15
|
private val cameraNodeWidth = 15
|
||||||
@@ -314,23 +319,73 @@ class TitleScreen(batch: FlippingSpriteBatch) : IngameInstance(batch) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private val introUncoverTime: Second = 0.3f
|
private val introFadeTime: Second = 0.5f
|
||||||
private var introUncoverDeltaCounter = 0f
|
private var introFadeDeltaCounter = 0f
|
||||||
|
private val settleFrameCount = 12
|
||||||
|
|
||||||
override fun renderImpl(updateRate: Float) {
|
override fun renderImpl(updateRate: Float) {
|
||||||
if (!loadDone) {
|
when (transitionState) {
|
||||||
App.drawSplash()
|
// Loading phase: show splash, advance GL load steps
|
||||||
processGLLoadStep()
|
0 -> {
|
||||||
return
|
App.drawSplash()
|
||||||
|
processGLLoadStep()
|
||||||
|
if (loadDone) {
|
||||||
|
// capture the current framebuffer (splash) as a texture
|
||||||
|
val pixmap = Pixmap.createFromFrameBuffer(0, 0, App.scr.width, App.scr.height)
|
||||||
|
splashCapture = Texture(pixmap)
|
||||||
|
pixmap.dispose()
|
||||||
|
transitionState = 1
|
||||||
|
settleFrames = 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Settle phase: render title screen normally but paint captured splash on top
|
||||||
|
1 -> {
|
||||||
|
renderTitleScreen()
|
||||||
|
drawSplashCapture(1f)
|
||||||
|
settleFrames++
|
||||||
|
if (settleFrames >= settleFrameCount) {
|
||||||
|
transitionState = 2
|
||||||
|
introFadeDeltaCounter = 0f
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Fade phase: crossfade from captured splash to title screen
|
||||||
|
2 -> {
|
||||||
|
renderTitleScreen()
|
||||||
|
introFadeDeltaCounter += Gdx.graphics.deltaTime
|
||||||
|
val opacity = 1f - (introFadeDeltaCounter / introFadeTime).coerceIn(0f, 1f)
|
||||||
|
drawSplashCapture(opacity)
|
||||||
|
if (introFadeDeltaCounter >= introFadeTime) {
|
||||||
|
splashCapture?.dispose()
|
||||||
|
splashCapture = null
|
||||||
|
transitionState = 3
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Normal rendering
|
||||||
|
3 -> {
|
||||||
|
renderTitleScreen()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun renderTitleScreen() {
|
||||||
IngameRenderer.setRenderedWorld(demoWorld)
|
IngameRenderer.setRenderedWorld(demoWorld)
|
||||||
|
super.renderImpl(0f)
|
||||||
super.renderImpl(updateRate)
|
|
||||||
// async update and render
|
|
||||||
gameUpdateGovernor.update(Gdx.graphics.deltaTime, App.UPDATE_RATE, updateScreen, renderScreen)
|
gameUpdateGovernor.update(Gdx.graphics.deltaTime, App.UPDATE_RATE, updateScreen, renderScreen)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun drawSplashCapture(opacity: Float) {
|
||||||
|
val tex = splashCapture ?: return
|
||||||
|
setCameraPosition(0f, 0f)
|
||||||
|
blendNormalStraightAlpha(batch)
|
||||||
|
batch.inUse {
|
||||||
|
batch.shader = null
|
||||||
|
batch.color = Color(1f, 1f, 1f, opacity)
|
||||||
|
// framebuffer capture is Y-flipped; draw flipped
|
||||||
|
batch.drawFlipped(tex, 0f, 0f)
|
||||||
|
batch.color = Color.WHITE
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private val updateScreen = { delta: Float ->
|
private val updateScreen = { delta: Float ->
|
||||||
|
|
||||||
demoWorld.globalLight = WeatherMixer.globalLightNow
|
demoWorld.globalLight = WeatherMixer.globalLightNow
|
||||||
@@ -586,6 +641,7 @@ class TitleScreen(batch: FlippingSpriteBatch) : IngameInstance(batch) {
|
|||||||
override fun dispose() {
|
override fun dispose() {
|
||||||
if (::uiRemoCon.isInitialized) uiRemoCon.dispose()
|
if (::uiRemoCon.isInitialized) uiRemoCon.dispose()
|
||||||
if (::demoWorld.isInitialized) demoWorld.dispose()
|
if (::demoWorld.isInitialized) demoWorld.dispose()
|
||||||
|
splashCapture?.dispose()
|
||||||
warning32bitJavaIcon.texture.dispose()
|
warning32bitJavaIcon.texture.dispose()
|
||||||
warningAppleRosettaIcon.texture.dispose()
|
warningAppleRosettaIcon.texture.dispose()
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user