mirror of
https://github.com/curioustorvald/Terrarum.git
synced 2026-03-08 12:51:51 +09:00
rename TARGET_FPS to PHYS_TIME_FRAME; shader to use multiple atlas tex; and things
This commit is contained in:
@@ -1,3 +1,13 @@
|
||||
/*
|
||||
|
||||
Texture binding:
|
||||
|
||||
0 <- Tiles atlas
|
||||
1 <- Tiles buffer that holds tiles to be drawn
|
||||
2 <- Fluid tiles atlas
|
||||
|
||||
*/
|
||||
|
||||
#version 120
|
||||
#ifdef GL_ES
|
||||
precision mediump float;
|
||||
@@ -16,7 +26,7 @@ uniform vec2 screenDimension;
|
||||
uniform vec2 tilesInAxes; // vec2(tiles_in_horizontal, tiles_in_vertical)
|
||||
|
||||
uniform ivec2 tilemapDimension;
|
||||
uniform sampler2D tilemap; // RGB888, A is optional and will be completely ignored
|
||||
uniform sampler2D tilemap; // RGBA8888
|
||||
|
||||
uniform sampler2D tilesAtlas;
|
||||
uniform sampler2D backgroundTexture;
|
||||
@@ -34,23 +44,29 @@ ivec2 getTileXY(int tileNumber) {
|
||||
return ivec2(tileNumber % int(tilesInAtlas.x), tileNumber / int(tilesInAtlas.x));
|
||||
}
|
||||
|
||||
// return: int=0xrrggbb
|
||||
// return: int=0xaarrggbb
|
||||
int _colToInt(vec4 color) {
|
||||
return int(color.b * 255) | (int(color.g * 255) << 8) | (int(color.r * 255) << 16);
|
||||
return int(color.b * 255) | (int(color.g * 255) << 8) | (int(color.r * 255) << 16) | (int(color.a * 255) << 24);
|
||||
}
|
||||
|
||||
// 0x0rggbb where int=0xaarrggbb
|
||||
// return: [0..1048575]
|
||||
int getTileFromColor(vec4 color) {
|
||||
return _colToInt(color) & 0x0FFFFF;
|
||||
return _colToInt(color) & 0xFFFFF;
|
||||
}
|
||||
|
||||
// 0xr00000 where int=0xaarrggbb
|
||||
// 0x00r00000 where int=0xaarrggbb
|
||||
// return: [0..15]
|
||||
int getBreakageFromColor(vec4 color) {
|
||||
return (_colToInt(color) >> 20) & 0xF;
|
||||
}
|
||||
|
||||
// 0xa0000000 where int=0xaarrggbb
|
||||
// return: [0..15]
|
||||
int getTextureIndexFromColor(vec4 color) {
|
||||
return (_colToInt(color) >> 28) & 0xF;
|
||||
}
|
||||
|
||||
void main() {
|
||||
|
||||
// READ THE FUCKING MANUAL, YOU DONKEY !! //
|
||||
|
||||
@@ -31,30 +31,57 @@ public class AppLoader implements ApplicationListener {
|
||||
* BB: Minor version
|
||||
* XXXX: Revision (Repository commits, or something arbitrary)
|
||||
*
|
||||
* e.g. 0x02010034 can be translated as 2.1.52
|
||||
* e.g. 0x02010034 will be translated as 2.1.52
|
||||
*/
|
||||
public static final int VERSION_RAW = 0x00_02_027C;
|
||||
public static final String getVERSION_STRING() {
|
||||
return String.format("%d.%d.%d", VERSION_RAW >>> 24, (VERSION_RAW & 0xff0000) >>> 16, VERSION_RAW & 0xFFFF);
|
||||
}
|
||||
|
||||
/**
|
||||
* when FALSE, some assertion and print code will not execute
|
||||
*/
|
||||
public static final boolean IS_DEVELOPMENT_BUILD = true;
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Singleton instance
|
||||
*/
|
||||
private static AppLoader INSTANCE = null;
|
||||
|
||||
/**
|
||||
* Screen injected at init, so that you run THAT screen instead of the main game.
|
||||
*/
|
||||
private static Screen injectScreen = null;
|
||||
|
||||
/**
|
||||
* Initialise the application with the alternative Screen you choose
|
||||
* @param appConfig LWJGL(2) Application Configuration
|
||||
* @param injectScreen GDX Screen you want to run
|
||||
*/
|
||||
public AppLoader(LwjglApplicationConfiguration appConfig, Screen injectScreen) {
|
||||
AppLoader.injectScreen = injectScreen;
|
||||
AppLoader.appConfig = appConfig;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialise the application with default game screen
|
||||
* @param appConfig LWJGL(2) Application Configuration
|
||||
*/
|
||||
public AppLoader(LwjglApplicationConfiguration appConfig) {
|
||||
AppLoader.appConfig = appConfig;
|
||||
}
|
||||
|
||||
/**
|
||||
* Default null constructor. Don't use it.
|
||||
*/
|
||||
public AppLoader() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Singleton pattern implementation in Java.
|
||||
* @return
|
||||
*/
|
||||
public static AppLoader getINSTANCE() {
|
||||
if (INSTANCE == null) {
|
||||
INSTANCE = new AppLoader();
|
||||
@@ -66,6 +93,9 @@ public class AppLoader implements ApplicationListener {
|
||||
public static final String COPYRIGHT_DATE_NAME = "Copyright 2013-2018 Torvald (minjaesong)";
|
||||
public static String GAME_LOCALE = System.getProperty("user.language") + System.getProperty("user.country");
|
||||
|
||||
/**
|
||||
* These languages won't distinguish regional differences (e.g. enUS and enUK, frFR and frCA)
|
||||
*/
|
||||
private static final String[] localeSimple = {"de", "en", "es", "it"}; // must be sorted!!
|
||||
|
||||
public static String getSysLang() {
|
||||
@@ -93,10 +123,6 @@ public class AppLoader implements ApplicationListener {
|
||||
}
|
||||
}
|
||||
|
||||
public static final String getVERSION_STRING() {
|
||||
return String.format("%d.%d.%d", VERSION_RAW >>> 24, (VERSION_RAW & 0xff0000) >>> 16, VERSION_RAW & 0xFFFF);
|
||||
}
|
||||
|
||||
public static LwjglApplicationConfiguration appConfig;
|
||||
|
||||
public static GameFontBase fontGame;
|
||||
|
||||
@@ -86,17 +86,17 @@ object Terrarum : Screen {
|
||||
/**
|
||||
* To be used with physics simulator
|
||||
*/
|
||||
val TARGET_FPS: Double = 26.0 + (2.0 / 3.0)
|
||||
val PHYS_TIME_FRAME: Double = 26.0 + (2.0 / 3.0)
|
||||
// 26.0 + (2.0 / 3.0) // lower value == faster gravity response (IT WON'T HOTSWAP!!)
|
||||
// protip: using METER, game unit and SI unit will have same number
|
||||
|
||||
/**
|
||||
* To be used with render, to achieve smooth frame drawing
|
||||
* TARGET_INTERNAL_FPS > TARGET_FPS for smooth frame drawing
|
||||
* TARGET_INTERNAL_FPS > PHYS_TIME_FRAME for smooth frame drawing
|
||||
*/
|
||||
val TARGET_INTERNAL_FPS: Double = 60.0
|
||||
|
||||
internal val UPDATE_CATCHUP_MAX_TRIES = 10
|
||||
internal val UPDATE_CATCHUP_MAX_TRIES = 4
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -506,7 +506,7 @@ open class ActorWBMovable(renderOrder: RenderOrder, val immobileBody: Boolean =
|
||||
* weight; gravitational force in action
|
||||
* W = mass * G (9.8 [m/s^2])
|
||||
*/
|
||||
val W: Vector2 = gravitation * Terrarum.TARGET_FPS.toDouble()
|
||||
val W: Vector2 = gravitation * Terrarum.PHYS_TIME_FRAME.toDouble()
|
||||
/**
|
||||
* Area
|
||||
*/
|
||||
@@ -517,7 +517,7 @@ open class ActorWBMovable(renderOrder: RenderOrder, val immobileBody: Boolean =
|
||||
*/
|
||||
val D: Vector2 = Vector2(externalForce.x.magnSqr(), externalForce.y.magnSqr()) * dragCoefficient * 0.5 * A// * tileDensityFluid.toDouble()
|
||||
|
||||
val V: Vector2 = (W - D) / Terrarum.TARGET_FPS * SI_TO_GAME_ACC
|
||||
val V: Vector2 = (W - D) / Terrarum.PHYS_TIME_FRAME * SI_TO_GAME_ACC
|
||||
|
||||
return V
|
||||
}
|
||||
@@ -833,7 +833,7 @@ open class ActorWBMovable(renderOrder: RenderOrder, val immobileBody: Boolean =
|
||||
|
||||
// slam-into-whatever damage (such dirty; much hack; wow)
|
||||
// vvvv hack (supposed to be 1.0) vvv 50% hack
|
||||
val collisionDamage = mass * (vectorSum.magnitude / (10.0 / Terrarum.TARGET_FPS).sqr()) / fallDamageDampening.sqr() * GAME_TO_SI_ACC
|
||||
val collisionDamage = mass * (vectorSum.magnitude / (10.0 / Terrarum.PHYS_TIME_FRAME).sqr()) / fallDamageDampening.sqr() * GAME_TO_SI_ACC
|
||||
// kg * m / s^2 (mass * acceleration), acceleration -> (vectorMagn / (0.01)^2).gameToSI()
|
||||
if (collisionDamage != 0.0) debug1("Collision damage: $collisionDamage N")
|
||||
// FIXME instead of 0.5mv^2, we can model after "change of velocity (aka accel)", just as in real-life; big change of accel on given unit time is what kills
|
||||
@@ -1492,16 +1492,16 @@ open class ActorWBMovable(renderOrder: RenderOrder, val immobileBody: Boolean =
|
||||
/**
|
||||
* [m / s^2] * SI_TO_GAME_ACC -> [px / InternalFrame^2]
|
||||
*/
|
||||
@Transient val SI_TO_GAME_ACC = METER / (Terrarum.TARGET_FPS * Terrarum.TARGET_FPS)
|
||||
@Transient val SI_TO_GAME_ACC = METER / (Terrarum.PHYS_TIME_FRAME * Terrarum.PHYS_TIME_FRAME)
|
||||
/**
|
||||
* [m / s] * SI_TO_GAME_VEL -> [px / InternalFrame]
|
||||
*/
|
||||
@Transient val SI_TO_GAME_VEL = METER / Terrarum.TARGET_FPS
|
||||
@Transient val SI_TO_GAME_VEL = METER / Terrarum.PHYS_TIME_FRAME
|
||||
|
||||
/**
|
||||
* [px / InternalFrame^2] * GAME_TO_SI_ACC -> [m / s^2]
|
||||
*/
|
||||
@Transient val GAME_TO_SI_ACC = (Terrarum.TARGET_FPS * Terrarum.TARGET_FPS) / METER
|
||||
@Transient val GAME_TO_SI_ACC = (Terrarum.PHYS_TIME_FRAME * Terrarum.PHYS_TIME_FRAME) / METER
|
||||
|
||||
|
||||
/**
|
||||
|
||||
@@ -481,6 +481,7 @@ open class Ingame(batch: SpriteBatch) : IngameInstance(batch) {
|
||||
}
|
||||
else {
|
||||
var updateTries = 0
|
||||
val oldDeltaCtr = updateDeltaCounter
|
||||
while (updateDeltaCounter >= renderRate) {
|
||||
|
||||
//updateGame(delta)
|
||||
@@ -490,6 +491,7 @@ open class Ingame(batch: SpriteBatch) : IngameInstance(batch) {
|
||||
updateTries++
|
||||
|
||||
if (updateTries >= Terrarum.UPDATE_CATCHUP_MAX_TRIES) {
|
||||
printdbg(this, "Update couldn't catch up -- delta-T buildup was $oldDeltaCtr seconds")
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
@@ -533,7 +533,7 @@ open class ActorHumanoid(
|
||||
}
|
||||
|
||||
|
||||
field = frames * (1.0 / Terrarum.TARGET_FPS)
|
||||
field = frames * (1.0 / Terrarum.PHYS_TIME_FRAME)
|
||||
// fixme: looks good but return value is wrong -- 2.25 seconds? when I jump it barely goes past 1 sec
|
||||
|
||||
|
||||
|
||||
@@ -50,6 +50,8 @@ object WorldSimulator {
|
||||
|
||||
private val world = (Terrarum.ingame!!.world)
|
||||
|
||||
|
||||
|
||||
operator fun invoke(p: ActorHumanoid?, delta: Float) {
|
||||
//printdbg(this, "============================")
|
||||
|
||||
@@ -77,8 +79,8 @@ object WorldSimulator {
|
||||
fun moveFluids(delta: Float) {
|
||||
makeFluidMapFromWorld()
|
||||
|
||||
//simCompression()
|
||||
for (y in 1 until fluidMap.size - 1) {
|
||||
simCompression()
|
||||
/*for (y in 1 until fluidMap.size - 1) {
|
||||
for (x in 1 until fluidMap[0].size - 1) {
|
||||
val worldX = x + updateXFrom
|
||||
val worldY = y + updateYFrom
|
||||
@@ -105,7 +107,7 @@ object WorldSimulator {
|
||||
fluidNewTypeMap[y + 1][x] = remainingType
|
||||
}
|
||||
}
|
||||
}
|
||||
}*/
|
||||
|
||||
if (AppLoader.IS_DEVELOPMENT_BUILD) {
|
||||
monitorIllegalFluidSetup() // non-air non-zero fluid is kinda inevitable
|
||||
@@ -183,6 +185,7 @@ object WorldSimulator {
|
||||
// after data: fluidNewMap/fluidNewTypeMap
|
||||
var flow = 0f
|
||||
var remainingMass = 0f
|
||||
var remainingType = Fluid.NULL
|
||||
|
||||
for (y in 1 until fluidMap.size - 1) {
|
||||
for (x in 1 until fluidMap[0].size - 1) {
|
||||
@@ -197,12 +200,13 @@ object WorldSimulator {
|
||||
|
||||
// Custom push-only flow
|
||||
flow = 0f
|
||||
remainingMass = fluidMap[y][x]
|
||||
remainingMass = fluidNewMap[y][x]
|
||||
remainingType = fluidNewTypeMap[y][x]
|
||||
if (remainingMass <= 0) continue
|
||||
|
||||
// The block below this one
|
||||
if (!isSolid(worldX, worldY + 1)) { // TODO use isFlowable
|
||||
flow = getStableStateB(remainingMass + fluidMap[y + 1][x]) - fluidMap[y + 1][x]
|
||||
flow = getStableStateB(remainingMass + fluidNewMap[y + 1][x]) - fluidNewMap[y + 1][x]
|
||||
if (flow > minFlow) {
|
||||
flow *= 0.5f // leads to smoother flow
|
||||
}
|
||||
@@ -210,6 +214,7 @@ object WorldSimulator {
|
||||
|
||||
fluidNewMap[y][x] -= flow
|
||||
fluidNewMap[y + 1][x] += flow
|
||||
fluidNewTypeMap[y + 1][x] = remainingType
|
||||
remainingMass -= flow
|
||||
}
|
||||
|
||||
@@ -218,7 +223,7 @@ object WorldSimulator {
|
||||
// Left
|
||||
if (!isSolid(worldX - 1, worldY)) { // TODO use isFlowable
|
||||
// Equalise the amount fo water in this block and its neighbour
|
||||
flow = (fluidMap[y][x] - fluidMap[y][x - 1]) / 4f
|
||||
flow = (fluidNewMap[y][x] - fluidNewMap[y][x - 1]) / 4f
|
||||
if (flow > minFlow) {
|
||||
flow *= 0.5f
|
||||
}
|
||||
@@ -226,6 +231,7 @@ object WorldSimulator {
|
||||
|
||||
fluidNewMap[y][x] -= flow
|
||||
fluidNewMap[y][x - 1] += flow
|
||||
fluidNewTypeMap[y][x - 1] = remainingType
|
||||
remainingMass -= flow
|
||||
}
|
||||
|
||||
@@ -234,7 +240,7 @@ object WorldSimulator {
|
||||
// Right
|
||||
if (!isSolid(worldX + 1, worldY)) { // TODO use isFlowable
|
||||
// Equalise the amount fo water in this block and its neighbour
|
||||
flow = (fluidMap[y][x] - fluidMap[y][x + 1]) / 4f
|
||||
flow = (fluidNewMap[y][x] - fluidNewMap[y][x + 1]) / 4f
|
||||
if (flow > minFlow) {
|
||||
flow *= 0.5f
|
||||
}
|
||||
@@ -242,6 +248,7 @@ object WorldSimulator {
|
||||
|
||||
fluidNewMap[y][x] -= flow
|
||||
fluidNewMap[y][x + 1] += flow
|
||||
fluidNewTypeMap[y][x + 1] = remainingType
|
||||
remainingMass -= flow
|
||||
}
|
||||
|
||||
@@ -249,7 +256,7 @@ object WorldSimulator {
|
||||
|
||||
// Up; only compressed water flows upwards
|
||||
if (!isSolid(worldX, worldY - 1)) { // TODO use isFlowable
|
||||
flow = remainingMass - getStableStateB(remainingMass + fluidMap[y - 1][x])
|
||||
flow = remainingMass - getStableStateB(remainingMass + fluidNewMap[y - 1][x])
|
||||
if (flow > minFlow) {
|
||||
flow *= 0.5f
|
||||
}
|
||||
@@ -257,6 +264,7 @@ object WorldSimulator {
|
||||
|
||||
fluidNewMap[y][x] -= flow
|
||||
fluidNewMap[y - 1][x] += flow
|
||||
fluidNewTypeMap[y - 1][x] = remainingType
|
||||
remainingMass -= flow
|
||||
}
|
||||
|
||||
|
||||
@@ -128,11 +128,13 @@ class BasicDebugInfoWindow : UICanvas() {
|
||||
printLine(batch, 8, "light@cursor $ccG$lightVal")
|
||||
|
||||
val tileNum = ingame.world.getTileFromTerrain(mouseTileX, mouseTileY) ?: -1
|
||||
val fluid = ingame.world.getFluid(mouseTileX, mouseTileY)
|
||||
|
||||
printLine(batch, 9, "tile@cursor $ccG$tileNum ($mtX, $mtY)")
|
||||
printLine(batch, 10, "fluid@cursor ${ccY}Type $ccM${fluid.type.value} ${ccY}Fill $ccG${fluid.amount}f")
|
||||
|
||||
|
||||
var dbgCnt = 11
|
||||
var dbgCnt = 12
|
||||
Terrarum.debugTimers.forEach { t, u ->
|
||||
printLine(batch, dbgCnt, "$ccM$t $ccG$u$ccY ns")
|
||||
dbgCnt++
|
||||
|
||||
@@ -72,7 +72,7 @@ internal object BlocksDrawer {
|
||||
private lateinit var terrainTilesBuffer: Array<IntArray>
|
||||
private lateinit var wallTilesBuffer: Array<IntArray>
|
||||
private lateinit var wireTilesBuffer: Array<IntArray>
|
||||
private var tilesBuffer: Pixmap = Pixmap(1, 1, Pixmap.Format.RGB888)
|
||||
private var tilesBuffer: Pixmap = Pixmap(1, 1, Pixmap.Format.RGBA8888)
|
||||
|
||||
|
||||
private lateinit var tilesQuad: Mesh
|
||||
@@ -793,7 +793,7 @@ internal object BlocksDrawer {
|
||||
wireTilesBuffer = Array<IntArray>(tilesInVertical, { kotlin.IntArray(tilesInHorizontal) })
|
||||
|
||||
tilesBuffer.dispose()
|
||||
tilesBuffer = Pixmap(tilesInHorizontal, tilesInVertical, Pixmap.Format.RGB888)
|
||||
tilesBuffer = Pixmap(tilesInHorizontal, tilesInVertical, Pixmap.Format.RGBA8888)
|
||||
}
|
||||
|
||||
if (oldScreenW != screenW || oldScreenH != screenH) {
|
||||
|
||||
Reference in New Issue
Block a user