mirror of
https://github.com/curioustorvald/Terrarum.git
synced 2026-06-12 03:24:06 +09:00
thread pooling actor update, updated kotlin lib
Former-commit-id: 17dc75ada5a6652fa555c3a34214704897ca9afe Former-commit-id: 75ddbe0187f978958cc5c1208a0cfb85bfdcdfaf
This commit is contained in:
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -13,6 +13,7 @@ object DefaultConfig {
|
|||||||
jsonObject.addProperty("imtooyoungtodie", false)
|
jsonObject.addProperty("imtooyoungtodie", false)
|
||||||
jsonObject.addProperty("language", Terrarum.sysLang)
|
jsonObject.addProperty("language", Terrarum.sysLang)
|
||||||
jsonObject.addProperty("notificationshowuptime", 6500)
|
jsonObject.addProperty("notificationshowuptime", 6500)
|
||||||
|
jsonObject.addProperty("multithread", false) // experimental!
|
||||||
|
|
||||||
return jsonObject
|
return jsonObject
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package net.torvald.terrarum
|
package net.torvald.terrarum
|
||||||
|
|
||||||
import net.torvald.imagefont.GameFontBase
|
import net.torvald.imagefont.GameFontBase
|
||||||
|
import net.torvald.terrarum.concurrent.ThreadPool
|
||||||
import net.torvald.terrarum.gameactors.*
|
import net.torvald.terrarum.gameactors.*
|
||||||
import net.torvald.terrarum.console.Authenticator
|
import net.torvald.terrarum.console.Authenticator
|
||||||
import net.torvald.terrarum.gameactors.physicssolver.CollisionSolver
|
import net.torvald.terrarum.gameactors.physicssolver.CollisionSolver
|
||||||
@@ -70,6 +71,7 @@ constructor() : BasicGameState() {
|
|||||||
private val useShader: Boolean = false
|
private val useShader: Boolean = false
|
||||||
private val shaderProgram = 0
|
private val shaderProgram = 0
|
||||||
|
|
||||||
|
private val CORES = ThreadPool.POOL_SIZE
|
||||||
|
|
||||||
val memInUse: Long
|
val memInUse: Long
|
||||||
get() = ManagementFactory.getMemoryMXBean().heapMemoryUsage.used shr 20
|
get() = ManagementFactory.getMemoryMXBean().heapMemoryUsage.used shr 20
|
||||||
@@ -128,7 +130,7 @@ constructor() : BasicGameState() {
|
|||||||
(Terrarum.WIDTH - notifier.UI.width) / 2, Terrarum.HEIGHT - notifier.UI.height)
|
(Terrarum.WIDTH - notifier.UI.width) / 2, Terrarum.HEIGHT - notifier.UI.height)
|
||||||
notifier.setVisibility(true)
|
notifier.setVisibility(true)
|
||||||
|
|
||||||
if (Terrarum.gameConfig.getAsBoolean("smoothlighting") == true)
|
if (Terrarum.getConfigBoolean("smoothlighting") == true)
|
||||||
KeyToggler.forceSet(KEY_LIGHTMAP_SMOOTH, true)
|
KeyToggler.forceSet(KEY_LIGHTMAP_SMOOTH, true)
|
||||||
else
|
else
|
||||||
KeyToggler.forceSet(KEY_LIGHTMAP_SMOOTH, false)
|
KeyToggler.forceSet(KEY_LIGHTMAP_SMOOTH, false)
|
||||||
@@ -154,11 +156,14 @@ constructor() : BasicGameState() {
|
|||||||
wakeDormantActors()
|
wakeDormantActors()
|
||||||
|
|
||||||
// determine whether the actor should be active or dormant
|
// determine whether the actor should be active or dormant
|
||||||
// also updates active actors
|
InactivateDistantActors()
|
||||||
updateAndInactivateDistantActors(gc, delta)
|
|
||||||
|
|
||||||
|
updateActors(gc, delta)
|
||||||
|
|
||||||
|
// TODO thread pool
|
||||||
CollisionSolver.process()
|
CollisionSolver.process()
|
||||||
|
|
||||||
|
// TODO thread pool
|
||||||
uiContainer.forEach { ui -> ui.update(gc, delta) }
|
uiContainer.forEach { ui -> ui.update(gc, delta) }
|
||||||
consoleHandler.update(gc, delta)
|
consoleHandler.update(gc, delta)
|
||||||
debugWindow.update(gc, delta)
|
debugWindow.update(gc, delta)
|
||||||
@@ -194,7 +199,7 @@ constructor() : BasicGameState() {
|
|||||||
|
|
||||||
// draw actors
|
// draw actors
|
||||||
actorContainer.forEach { actor ->
|
actorContainer.forEach { actor ->
|
||||||
if (actor is Visible && actor.inScreen()) { // if visible and within screen
|
if (actor is Visible && actor.inScreen() && actor !is Player) { // if visible and within screen
|
||||||
actor.drawBody(gc, g)
|
actor.drawBody(gc, g)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -216,7 +221,7 @@ constructor() : BasicGameState() {
|
|||||||
|
|
||||||
// draw actor glows
|
// draw actor glows
|
||||||
actorContainer.forEach { actor ->
|
actorContainer.forEach { actor ->
|
||||||
if (actor is Visible && actor.inScreen()) { // if visible and within screen
|
if (actor is Visible && actor.inScreen() && actor !is Player) { // if visible and within screen
|
||||||
actor.drawGlow(gc, g)
|
actor.drawGlow(gc, g)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -348,7 +353,7 @@ constructor() : BasicGameState() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun updateAndInactivateDistantActors(gc: GameContainer, delta: Int) {
|
fun InactivateDistantActors() {
|
||||||
var actorContainerSize = actorContainer.size
|
var actorContainerSize = actorContainer.size
|
||||||
var i = 0
|
var i = 0
|
||||||
// determine whether the actor should be active or dormant by its distance from the player.
|
// determine whether the actor should be active or dormant by its distance from the player.
|
||||||
@@ -363,13 +368,33 @@ constructor() : BasicGameState() {
|
|||||||
actorContainerSize -= 1
|
actorContainerSize -= 1
|
||||||
i-- // array removed 1 elem, so also decrement counter by 1
|
i-- // array removed 1 elem, so also decrement counter by 1
|
||||||
}
|
}
|
||||||
else {
|
|
||||||
actorContainer[i].update(gc, delta)
|
|
||||||
}
|
|
||||||
i++
|
i++
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun updateActors(gc: GameContainer, delta: Int) {
|
||||||
|
if (CORES >= 2 && Terrarum.getConfigBoolean("multithread")) {
|
||||||
|
val actors = actorContainer.size.toFloat()
|
||||||
|
// set up indices
|
||||||
|
for (i in 0..ThreadPool.POOL_SIZE - 1) {
|
||||||
|
ThreadPool.map(
|
||||||
|
i,
|
||||||
|
ThreadActorUpdate(
|
||||||
|
((actors / CORES) * i).toInt(),
|
||||||
|
((actors / CORES) * i.plus(1)).toInt() - 1,
|
||||||
|
gc, delta
|
||||||
|
),
|
||||||
|
"ActorUpdate"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
ThreadPool.startAll()
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
actorContainer.forEach { it.update(gc, delta) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private val globalLightByTime: Int
|
private val globalLightByTime: Int
|
||||||
get() = getGradientColour(2).getRGB24().rgb24ExpandToRgb30()
|
get() = getGradientColour(2).getRGB24().rgb24ExpandToRgb30()
|
||||||
fun globalLightByTime(t: Int): Int = getGradientColourByTime(2, t).getRGB24().rgb24ExpandToRgb30()
|
fun globalLightByTime(t: Int): Int = getGradientColourByTime(2, t).getRGB24().rgb24ExpandToRgb30()
|
||||||
|
|||||||
@@ -111,6 +111,9 @@ constructor(gamename: String) : StateBasedGame(gamename) {
|
|||||||
var hasController = false
|
var hasController = false
|
||||||
val CONTROLLER_DEADZONE = 0.1f
|
val CONTROLLER_DEADZONE = 0.1f
|
||||||
|
|
||||||
|
/** Available CPU cores */
|
||||||
|
val CORES = Runtime.getRuntime().availableProcessors();
|
||||||
|
|
||||||
private lateinit var configDir: String
|
private lateinit var configDir: String
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
15
src/net/torvald/terrarum/ThreadActorUpdate.kt
Normal file
15
src/net/torvald/terrarum/ThreadActorUpdate.kt
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
package net.torvald.terrarum
|
||||||
|
|
||||||
|
import net.torvald.terrarum.gameactors.Player
|
||||||
|
import org.newdawn.slick.GameContainer
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by minjaesong on 16-05-25.
|
||||||
|
*/
|
||||||
|
class ThreadActorUpdate(val startIndex: Int, val endIndex: Int,
|
||||||
|
val gc: GameContainer, val delta: Int) : Runnable {
|
||||||
|
override fun run() {
|
||||||
|
for (i in startIndex..endIndex)
|
||||||
|
Terrarum.game.actorContainer[i].update(gc, delta)
|
||||||
|
}
|
||||||
|
}
|
||||||
37
src/net/torvald/terrarum/concurrent/ThreadPool.kt
Normal file
37
src/net/torvald/terrarum/concurrent/ThreadPool.kt
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
package net.torvald.terrarum.concurrent
|
||||||
|
|
||||||
|
import net.torvald.terrarum.Terrarum
|
||||||
|
import java.util.*
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by minjaesong on 16-05-25.
|
||||||
|
*/
|
||||||
|
object ThreadPool {
|
||||||
|
private val pool = Array<Thread>(Terrarum.CORES, { Thread() })
|
||||||
|
val POOL_SIZE = Terrarum.CORES
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param prefix : will name each thread as "Foo-1"
|
||||||
|
* @param runnables : vararg
|
||||||
|
*/
|
||||||
|
fun mapAll(prefix: String, vararg runnables: Runnable) {
|
||||||
|
if (runnables.size != Terrarum.CORES)
|
||||||
|
throw RuntimeException("Thread pool argument size mismatch. If you have four cores, you must use four runnables.")
|
||||||
|
|
||||||
|
for (i in 0..runnables.size)
|
||||||
|
pool[i] = Thread(runnables[i], "$prefix-$i")
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param index of the runnable
|
||||||
|
* @param runnable
|
||||||
|
* @param prefix Will name each thread like "Foo-1", "Foo-2", etc.
|
||||||
|
*/
|
||||||
|
fun map(index: Int, runnable: Runnable, prefix: String) {
|
||||||
|
pool[index] = Thread(runnable, "$prefix-$index")
|
||||||
|
}
|
||||||
|
|
||||||
|
fun startAll() {
|
||||||
|
pool.forEach { it.start() }
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -10,7 +10,7 @@ import org.newdawn.slick.GameContainer
|
|||||||
*/
|
*/
|
||||||
abstract class Actor : Comparable<Actor>, Runnable {
|
abstract class Actor : Comparable<Actor>, Runnable {
|
||||||
|
|
||||||
abstract fun update(gc: GameContainer, delta_t: Int)
|
abstract fun update(gc: GameContainer, delta: Int)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Valid RefID is equal to or greater than 32768.
|
* Valid RefID is equal to or greater than 32768.
|
||||||
|
|||||||
@@ -183,9 +183,9 @@ open class ActorWithBody constructor() : Actor(), Visible {
|
|||||||
|
|
||||||
@Transient internal val BASE_FRICTION = 0.3
|
@Transient internal val BASE_FRICTION = 0.3
|
||||||
|
|
||||||
@Transient val KINEMATIC = 1
|
@Transient val KINEMATIC = 1 // does not be budged by external forces
|
||||||
@Transient val DYNAMIC = 2
|
@Transient val DYNAMIC = 2
|
||||||
@Transient val STATIC = 3
|
@Transient val STATIC = 3 // does not be budged by external forces, target of collision
|
||||||
|
|
||||||
private val SLEEP_THRE = 1.0 / 16.0
|
private val SLEEP_THRE = 1.0 / 16.0
|
||||||
private val CCD_TICK = 1.0 / 16.0
|
private val CCD_TICK = 1.0 / 16.0
|
||||||
@@ -287,15 +287,11 @@ open class ActorWithBody constructor() : Actor(), Visible {
|
|||||||
// Set 'next' position (hitbox) to fiddle with
|
// Set 'next' position (hitbox) to fiddle with
|
||||||
setNewNextHitbox()
|
setNewNextHitbox()
|
||||||
|
|
||||||
// if not horizontally moving then ...
|
/**
|
||||||
//if (Math.abs(veloX) < 0.5) { // fix for special situations (see fig. 1 at the bottom of the source)
|
* Solve collision
|
||||||
// updateVerticalPos();
|
* If and only if:
|
||||||
// updateHorizontalPos();
|
* This body is NON-STATIC and the other body is STATIC
|
||||||
//}
|
*/
|
||||||
//else {
|
|
||||||
// compensate for colliding
|
|
||||||
//updateHorizontalCollision()
|
|
||||||
//updateVerticalCollision()
|
|
||||||
applyNormalForce()
|
applyNormalForce()
|
||||||
adjustHit()
|
adjustHit()
|
||||||
|
|
||||||
@@ -551,15 +547,15 @@ open class ActorWithBody constructor() : Actor(), Visible {
|
|||||||
val delta: Vector2 = Vector2(hitbox.toVector() - nextHitbox.toVector()) // we need to traverse back, so may as well negate at the first place
|
val delta: Vector2 = Vector2(hitbox.toVector() - nextHitbox.toVector()) // we need to traverse back, so may as well negate at the first place
|
||||||
val ccdDelta = delta.setMagnitude(CCD_TICK)
|
val ccdDelta = delta.setMagnitude(CCD_TICK)
|
||||||
|
|
||||||
if (ccdDelta.x.abs() >= SLEEP_THRE || ccdDelta.y.abs() >= SLEEP_THRE) { // regular situation
|
//if (ccdDelta.x.abs() >= SLEEP_THRE || ccdDelta.y.abs() >= SLEEP_THRE) { // regular situation
|
||||||
// CCD to delta while still colliding
|
// CCD to delta while still colliding
|
||||||
while (isColliding(CONTACT_AREA_LEFT) || isColliding(CONTACT_AREA_RIGHT)
|
while (isColliding(CONTACT_AREA_LEFT) || isColliding(CONTACT_AREA_RIGHT)
|
||||||
|| isColliding(CONTACT_AREA_TOP) || isColliding(CONTACT_AREA_BOTTOM)
|
|| isColliding(CONTACT_AREA_TOP) || isColliding(CONTACT_AREA_BOTTOM)
|
||||||
) {
|
) {
|
||||||
nextHitbox.translate(ccdDelta)
|
nextHitbox.translate(ccdDelta)
|
||||||
}
|
}
|
||||||
}
|
//}
|
||||||
else { // stuck while standing still
|
/*else { // stuck while standing still
|
||||||
// CCD upward
|
// CCD upward
|
||||||
var upwardDelta = 0.0
|
var upwardDelta = 0.0
|
||||||
while (isColliding(CONTACT_AREA_LEFT) || isColliding(CONTACT_AREA_RIGHT)
|
while (isColliding(CONTACT_AREA_LEFT) || isColliding(CONTACT_AREA_RIGHT)
|
||||||
@@ -579,7 +575,7 @@ open class ActorWithBody constructor() : Actor(), Visible {
|
|||||||
until the stucking is resolved
|
until the stucking is resolved
|
||||||
*/
|
*/
|
||||||
}
|
}
|
||||||
}
|
}*/
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -31,6 +31,7 @@ object CollisionSolver {
|
|||||||
* [this link](https://www.toptal.com/game/video-game-physics-part-ii-collision-detection-for-solid-objects)
|
* [this link](https://www.toptal.com/game/video-game-physics-part-ii-collision-detection-for-solid-objects)
|
||||||
*/
|
*/
|
||||||
fun process() {
|
fun process() {
|
||||||
|
// TODO threading X and Y
|
||||||
// clean up before we go
|
// clean up before we go
|
||||||
collListX.clear()
|
collListX.clear()
|
||||||
collListY.clear()
|
collListY.clear()
|
||||||
|
|||||||
@@ -77,8 +77,8 @@ object LightmapRenderer {
|
|||||||
for_x_start = MapCamera.cameraX / TSIZE - 1 // fix for premature lightmap rendering
|
for_x_start = MapCamera.cameraX / TSIZE - 1 // fix for premature lightmap rendering
|
||||||
for_y_start = MapCamera.cameraY / TSIZE - 1 // on topmost/leftmost side
|
for_y_start = MapCamera.cameraY / TSIZE - 1 // on topmost/leftmost side
|
||||||
|
|
||||||
for_x_end = for_x_start + MapCamera.getRenderWidth() / TSIZE + 3
|
for_x_end = for_x_start + MapCamera.renderWidth / TSIZE + 3
|
||||||
for_y_end = for_y_start + MapCamera.getRenderHeight() / TSIZE + 2 // same fix as above
|
for_y_end = for_y_start + MapCamera.renderHeight / TSIZE + 2 // same fix as above
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* * true: overscanning is limited to 8 tiles in width (overscan_opaque)
|
* * true: overscanning is limited to 8 tiles in width (overscan_opaque)
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import net.torvald.terrarum.Terrarum
|
|||||||
import net.torvald.terrarum.tileproperties.TileNameCode
|
import net.torvald.terrarum.tileproperties.TileNameCode
|
||||||
import net.torvald.terrarum.tileproperties.TilePropCodex
|
import net.torvald.terrarum.tileproperties.TilePropCodex
|
||||||
import com.jme3.math.FastMath
|
import com.jme3.math.FastMath
|
||||||
|
import net.torvald.terrarum.concurrent.ThreadPool
|
||||||
import net.torvald.terrarum.setBlendMul
|
import net.torvald.terrarum.setBlendMul
|
||||||
import net.torvald.terrarum.setBlendNormal
|
import net.torvald.terrarum.setBlendNormal
|
||||||
import org.lwjgl.opengl.GL11
|
import org.lwjgl.opengl.GL11
|
||||||
@@ -19,7 +20,7 @@ import java.util.*
|
|||||||
* Created by minjaesong on 16-01-19.
|
* Created by minjaesong on 16-01-19.
|
||||||
*/
|
*/
|
||||||
object MapCamera {
|
object MapCamera {
|
||||||
private val map: GameMap = Terrarum.game.map;
|
val map: GameMap = Terrarum.game.map;
|
||||||
|
|
||||||
var cameraX = 0
|
var cameraX = 0
|
||||||
private set
|
private set
|
||||||
@@ -28,17 +29,23 @@ object MapCamera {
|
|||||||
|
|
||||||
private val TSIZE = MapDrawer.TILE_SIZE
|
private val TSIZE = MapDrawer.TILE_SIZE
|
||||||
|
|
||||||
private var tilesWall: SpriteSheet = SpriteSheet("./res/graphics/terrain/wall.png", TSIZE, TSIZE)
|
var tilesWall: SpriteSheet = SpriteSheet("./res/graphics/terrain/wall.png", TSIZE, TSIZE)
|
||||||
private var tilesTerrain: SpriteSheet = SpriteSheet("./res/graphics/terrain/terrain.png", TSIZE, TSIZE)
|
private set
|
||||||
private var tilesWire: SpriteSheet = SpriteSheet("./res/graphics/terrain/wire.png", TSIZE, TSIZE)
|
var tilesTerrain: SpriteSheet = SpriteSheet("./res/graphics/terrain/terrain.png", TSIZE, TSIZE)
|
||||||
private var tilesetBook: Array<SpriteSheet> = arrayOf(tilesWall, tilesTerrain, tilesWire)
|
private set
|
||||||
|
var tilesWire: SpriteSheet = SpriteSheet("./res/graphics/terrain/wire.png", TSIZE, TSIZE)
|
||||||
|
private set
|
||||||
|
var tilesetBook: Array<SpriteSheet> = arrayOf(tilesWall, tilesTerrain, tilesWire)
|
||||||
|
private set
|
||||||
|
|
||||||
private val WALL = GameMap.WALL
|
val WALL = GameMap.WALL
|
||||||
private val TERRAIN = GameMap.TERRAIN
|
val TERRAIN = GameMap.TERRAIN
|
||||||
private val WIRE = GameMap.WIRE
|
val WIRE = GameMap.WIRE
|
||||||
|
|
||||||
private var renderWidth: Int = 0
|
var renderWidth: Int = 0
|
||||||
private var renderHeight: Int = 0
|
private set
|
||||||
|
var renderHeight: Int = 0
|
||||||
|
private set
|
||||||
|
|
||||||
private val NEARBY_TILE_KEY_UP = 0
|
private val NEARBY_TILE_KEY_UP = 0
|
||||||
private val NEARBY_TILE_KEY_RIGHT = 1
|
private val NEARBY_TILE_KEY_RIGHT = 1
|
||||||
@@ -55,7 +62,7 @@ object MapCamera {
|
|||||||
* It holds different shading rule to discriminate with group 02, index 0 is single tile.
|
* It holds different shading rule to discriminate with group 02, index 0 is single tile.
|
||||||
* These are the tiles that only connects to itself, will not connect to colour variants
|
* These are the tiles that only connects to itself, will not connect to colour variants
|
||||||
*/
|
*/
|
||||||
private val TILES_CONNECT_SELF = arrayOf(
|
val TILES_CONNECT_SELF = arrayOf(
|
||||||
TileNameCode.ICE_MAGICAL
|
TileNameCode.ICE_MAGICAL
|
||||||
, TileNameCode.ILLUMINATOR_BLACK
|
, TileNameCode.ILLUMINATOR_BLACK
|
||||||
, TileNameCode.ILLUMINATOR_BLUE
|
, TileNameCode.ILLUMINATOR_BLUE
|
||||||
@@ -102,7 +109,7 @@ object MapCamera {
|
|||||||
* Connectivity group 02 : natural tiles
|
* Connectivity group 02 : natural tiles
|
||||||
* It holds different shading rule to discriminate with group 01, index 0 is middle tile.
|
* It holds different shading rule to discriminate with group 01, index 0 is middle tile.
|
||||||
*/
|
*/
|
||||||
private val TILES_CONNECT_MUTUAL = arrayOf(
|
val TILES_CONNECT_MUTUAL = arrayOf(
|
||||||
TileNameCode.STONE
|
TileNameCode.STONE
|
||||||
, TileNameCode.DIRT
|
, TileNameCode.DIRT
|
||||||
, TileNameCode.GRASS
|
, TileNameCode.GRASS
|
||||||
@@ -164,7 +171,7 @@ object MapCamera {
|
|||||||
/**
|
/**
|
||||||
* Torches, levers, switches, ...
|
* Torches, levers, switches, ...
|
||||||
*/
|
*/
|
||||||
private val TILES_WALL_STICKER = arrayOf(
|
val TILES_WALL_STICKER = arrayOf(
|
||||||
TileNameCode.TORCH
|
TileNameCode.TORCH
|
||||||
, TileNameCode.TORCH_FROST
|
, TileNameCode.TORCH_FROST
|
||||||
, TileNameCode.TORCH_OFF
|
, TileNameCode.TORCH_OFF
|
||||||
@@ -174,7 +181,7 @@ object MapCamera {
|
|||||||
/**
|
/**
|
||||||
* platforms, ...
|
* platforms, ...
|
||||||
*/
|
*/
|
||||||
private val TILES_WALL_STICKER_CONNECT_SELF = arrayOf<Int>(
|
val TILES_WALL_STICKER_CONNECT_SELF = arrayOf<Int>(
|
||||||
|
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -183,7 +190,7 @@ object MapCamera {
|
|||||||
* will blend colour using colour multiplication
|
* will blend colour using colour multiplication
|
||||||
* i.e. red hues get lost if you dive into the water
|
* i.e. red hues get lost if you dive into the water
|
||||||
*/
|
*/
|
||||||
private val TILES_BLEND_MUL = arrayOf(
|
val TILES_BLEND_MUL = arrayOf(
|
||||||
TileNameCode.WATER
|
TileNameCode.WATER
|
||||||
, TileNameCode.WATER_1
|
, TileNameCode.WATER_1
|
||||||
, TileNameCode.WATER_2
|
, TileNameCode.WATER_2
|
||||||
@@ -247,40 +254,40 @@ object MapCamera {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun drawTiles(mode: Int, drawModeTilesBlendMul: Boolean) {
|
private fun drawTiles(mode: Int, drawModeTilesBlendMul: Boolean) {
|
||||||
val for_y_start = div16(cameraY)
|
val for_y_start = MapCamera.div16(MapCamera.cameraY)
|
||||||
val for_x_start = div16(cameraX)
|
val for_y_end = MapCamera.clampHTile(for_y_start + MapCamera.div16(MapCamera.renderHeight) + 2)
|
||||||
|
|
||||||
val for_y_end = clampHTile(for_y_start + div16(renderHeight) + 2)
|
val for_x_start = MapCamera.div16(MapCamera.cameraX)
|
||||||
val for_x_end = clampWTile(for_x_start + div16(renderWidth) + 2)
|
val for_x_end = MapCamera.clampWTile(for_x_start + MapCamera.div16(MapCamera.renderWidth) + 2)
|
||||||
|
|
||||||
// initialise
|
// initialise
|
||||||
tilesetBook[mode].startUse()
|
MapCamera.tilesetBook[mode].startUse()
|
||||||
|
|
||||||
// loop
|
// loop
|
||||||
for (y in for_y_start..for_y_end - 1) {
|
for (y in for_y_start..for_y_end) {
|
||||||
for (x in for_x_start..for_x_end - 1) {
|
for (x in for_x_start..for_x_end - 1) {
|
||||||
|
|
||||||
val thisTile: Int?
|
val thisTile: Int?
|
||||||
if (mode % 3 == WALL)
|
if (mode % 3 == MapCamera.WALL)
|
||||||
thisTile = map.getTileFromWall(x, y)
|
thisTile = MapCamera.map.getTileFromWall(x, y)
|
||||||
else if (mode % 3 == TERRAIN)
|
else if (mode % 3 == MapCamera.TERRAIN)
|
||||||
thisTile = map.getTileFromTerrain(x, y)
|
thisTile = MapCamera.map.getTileFromTerrain(x, y)
|
||||||
else if (mode % 3 == WIRE)
|
else if (mode % 3 == MapCamera.WIRE)
|
||||||
thisTile = map.getTileFromWire(x, y)
|
thisTile = MapCamera.map.getTileFromWire(x, y)
|
||||||
else
|
else
|
||||||
throw IllegalArgumentException()
|
throw IllegalArgumentException()
|
||||||
|
|
||||||
val noDamageLayer = mode % 3 == WIRE
|
val noDamageLayer = mode % 3 == MapCamera.WIRE
|
||||||
|
|
||||||
// draw
|
// draw
|
||||||
try {
|
try {
|
||||||
if (
|
if (
|
||||||
|
|
||||||
(mode == WALL || mode == TERRAIN) // not an air tile
|
(mode == MapCamera.WALL || mode == MapCamera.TERRAIN) // not an air tile
|
||||||
|
|
||||||
&& (thisTile ?: 0) > 0
|
&& (thisTile ?: 0) > 0
|
||||||
&&
|
&&
|
||||||
// check if light level of nearby or this tile is illuminated
|
// check if light level of nearby or this tile is illuminated
|
||||||
( LightmapRenderer.getValueFromMap(x, y) ?: 0 > 0
|
( LightmapRenderer.getValueFromMap(x, y) ?: 0 > 0
|
||||||
|| LightmapRenderer.getValueFromMap(x - 1, y) ?: 0 > 0
|
|| LightmapRenderer.getValueFromMap(x - 1, y) ?: 0 > 0
|
||||||
|| LightmapRenderer.getValueFromMap(x + 1, y) ?: 0 > 0
|
|| LightmapRenderer.getValueFromMap(x + 1, y) ?: 0 > 0
|
||||||
@@ -293,12 +300,12 @@ object MapCamera {
|
|||||||
) {
|
) {
|
||||||
|
|
||||||
val nearbyTilesInfo: Int
|
val nearbyTilesInfo: Int
|
||||||
if (isWallSticker(thisTile)) {
|
if (MapCamera.isWallSticker(thisTile)) {
|
||||||
nearbyTilesInfo = getNearbyTilesInfoWallSticker(x, y)
|
nearbyTilesInfo = MapCamera.getNearbyTilesInfoWallSticker(x, y)
|
||||||
} else if (isConnectMutual(thisTile)) {
|
} else if (MapCamera.isConnectMutual(thisTile)) {
|
||||||
nearbyTilesInfo = getNearbyTilesInfoNonSolid(x, y, mode)
|
nearbyTilesInfo = MapCamera.getNearbyTilesInfoNonSolid(x, y, mode)
|
||||||
} else if (isConnectSelf(thisTile)) {
|
} else if (MapCamera.isConnectSelf(thisTile)) {
|
||||||
nearbyTilesInfo = getNearbyTilesInfo(x, y, mode, thisTile)
|
nearbyTilesInfo = MapCamera.getNearbyTilesInfo(x, y, mode, thisTile)
|
||||||
} else {
|
} else {
|
||||||
nearbyTilesInfo = 0
|
nearbyTilesInfo = 0
|
||||||
}
|
}
|
||||||
@@ -313,7 +320,7 @@ object MapCamera {
|
|||||||
val thisTileY = (thisTile ?: 0) / PairedMapLayer.RANGE
|
val thisTileY = (thisTile ?: 0) / PairedMapLayer.RANGE
|
||||||
|
|
||||||
if (drawModeTilesBlendMul) {
|
if (drawModeTilesBlendMul) {
|
||||||
if (isBlendMul(thisTile)) {
|
if (MapCamera.isBlendMul(thisTile)) {
|
||||||
drawTile(mode, x, y, thisTileX, thisTileY)
|
drawTile(mode, x, y, thisTileX, thisTileY)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -323,13 +330,13 @@ object MapCamera {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (e: NullPointerException) {
|
} catch (e: NullPointerException) {
|
||||||
// do nothing. This exception handling may hide erratic behaviour completely.
|
// do nothing. WARNING: This exception handling may hide erratic behaviour completely.
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
tilesetBook[mode].endUse()
|
MapCamera.tilesetBook[mode].endUse()
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -340,7 +347,7 @@ object MapCamera {
|
|||||||
* *
|
* *
|
||||||
* @return binary [0-15] 1: up, 2: right, 4: down, 8: left
|
* @return binary [0-15] 1: up, 2: right, 4: down, 8: left
|
||||||
*/
|
*/
|
||||||
private fun getNearbyTilesInfo(x: Int, y: Int, mode: Int, mark: Int?): Int {
|
fun getNearbyTilesInfo(x: Int, y: Int, mode: Int, mark: Int?): Int {
|
||||||
val nearbyTiles = IntArray(4)
|
val nearbyTiles = IntArray(4)
|
||||||
nearbyTiles[NEARBY_TILE_KEY_LEFT] = map.getTileFrom(mode, x - 1, y) ?: 4096
|
nearbyTiles[NEARBY_TILE_KEY_LEFT] = map.getTileFrom(mode, x - 1, y) ?: 4096
|
||||||
nearbyTiles[NEARBY_TILE_KEY_RIGHT] = map.getTileFrom(mode, x + 1, y) ?: 4096
|
nearbyTiles[NEARBY_TILE_KEY_RIGHT] = map.getTileFrom(mode, x + 1, y) ?: 4096
|
||||||
@@ -358,7 +365,7 @@ object MapCamera {
|
|||||||
return ret
|
return ret
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getNearbyTilesInfoNonSolid(x: Int, y: Int, mode: Int): Int {
|
fun getNearbyTilesInfoNonSolid(x: Int, y: Int, mode: Int): Int {
|
||||||
val nearbyTiles = IntArray(4)
|
val nearbyTiles = IntArray(4)
|
||||||
nearbyTiles[NEARBY_TILE_KEY_LEFT] = map.getTileFrom(mode, x - 1, y) ?: 4096
|
nearbyTiles[NEARBY_TILE_KEY_LEFT] = map.getTileFrom(mode, x - 1, y) ?: 4096
|
||||||
nearbyTiles[NEARBY_TILE_KEY_RIGHT] = map.getTileFrom(mode, x + 1, y) ?: 4096
|
nearbyTiles[NEARBY_TILE_KEY_RIGHT] = map.getTileFrom(mode, x + 1, y) ?: 4096
|
||||||
@@ -380,7 +387,7 @@ object MapCamera {
|
|||||||
return ret
|
return ret
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getNearbyTilesInfoWallSticker(x: Int, y: Int): Int {
|
fun getNearbyTilesInfoWallSticker(x: Int, y: Int): Int {
|
||||||
val nearbyTiles = IntArray(4)
|
val nearbyTiles = IntArray(4)
|
||||||
val NEARBY_TILE_KEY_BACK = NEARBY_TILE_KEY_UP
|
val NEARBY_TILE_KEY_BACK = NEARBY_TILE_KEY_UP
|
||||||
nearbyTiles[NEARBY_TILE_KEY_LEFT] = map.getTileFrom(TERRAIN, x - 1, y) ?: 4096
|
nearbyTiles[NEARBY_TILE_KEY_LEFT] = map.getTileFrom(TERRAIN, x - 1, y) ?: 4096
|
||||||
@@ -469,20 +476,16 @@ object MapCamera {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getRenderWidth(): Int = renderWidth
|
|
||||||
fun getRenderHeight(): Int = renderHeight
|
|
||||||
|
|
||||||
fun getRenderStartX(): Int = div16(cameraX)
|
fun getRenderStartX(): Int = div16(cameraX)
|
||||||
fun getRenderStartY(): Int = div16(cameraY)
|
fun getRenderStartY(): Int = div16(cameraY)
|
||||||
|
|
||||||
fun getRenderEndX(): Int = clampWTile(getRenderStartX() + div16(renderWidth) + 2)
|
fun getRenderEndX(): Int = clampWTile(getRenderStartX() + div16(renderWidth) + 2)
|
||||||
fun getRenderEndY(): Int = clampHTile(getRenderStartY() + div16(renderHeight) + 2)
|
fun getRenderEndY(): Int = clampHTile(getRenderStartY() + div16(renderHeight) + 2)
|
||||||
|
|
||||||
private fun isConnectSelf(b: Int?): Boolean = TILES_CONNECT_SELF.contains(b)
|
fun isConnectSelf(b: Int?): Boolean = TILES_CONNECT_SELF.contains(b)
|
||||||
private fun isConnectMutual(b: Int?): Boolean = TILES_CONNECT_MUTUAL.contains(b)
|
fun isConnectMutual(b: Int?): Boolean = TILES_CONNECT_MUTUAL.contains(b)
|
||||||
private fun isWallSticker(b: Int?): Boolean = TILES_WALL_STICKER.contains(b)
|
fun isWallSticker(b: Int?): Boolean = TILES_WALL_STICKER.contains(b)
|
||||||
private fun isPlatform(b: Int?): Boolean = TILES_WALL_STICKER_CONNECT_SELF.contains(b)
|
fun isPlatform(b: Int?): Boolean = TILES_WALL_STICKER_CONNECT_SELF.contains(b)
|
||||||
|
fun isBlendMul(b: Int?): Boolean = TILES_BLEND_MUL.contains(b)
|
||||||
private fun isBlendMul(b: Int?): Boolean = TILES_BLEND_MUL.contains(b)
|
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -135,21 +135,32 @@ class BasicDebugInfoWindow:UICanvas {
|
|||||||
Terrarum.HEIGHT - histogramH - 30
|
Terrarum.HEIGHT - histogramH - 30
|
||||||
)
|
)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Top right
|
||||||
|
*/
|
||||||
|
|
||||||
g.color = GameFontBase.codeToCol["y"]
|
g.color = GameFontBase.codeToCol["y"]
|
||||||
g.drawString("${ccY}MEM ", (Terrarum.WIDTH - 15 * 8 - 2).toFloat(), 2f)
|
g.drawString("${ccY}MEM ", (Terrarum.WIDTH - 15 * 8 - 2).toFloat(), 2f)
|
||||||
//g.drawString("${ccY}FPS $ccG${Terrarum.appgc.fps}", (Terrarum.WIDTH - 6 * 8 - 2).toFloat(), 10f)
|
//g.drawString("${ccY}FPS $ccG${Terrarum.appgc.fps}", (Terrarum.WIDTH - 6 * 8 - 2).toFloat(), 10f)
|
||||||
g.drawString("${ccY}Actors total $ccG${Terrarum.game.actorContainer.size + Terrarum.game.actorContainerInactive.size}",
|
g.drawString("${ccY}CPUs ${if (Terrarum.getConfigBoolean("multithread")) ccG else ccR}${Terrarum.CORES}",
|
||||||
2f, Terrarum.HEIGHT - 10f)
|
(Terrarum.WIDTH - 2 - 6*8).toFloat(), 10f)
|
||||||
g.drawString("${ccY}Active $ccG${Terrarum.game.actorContainer.size}",
|
|
||||||
(2 + 17*8).toFloat(), Terrarum.HEIGHT - 10f)
|
|
||||||
g.drawString("${ccY}Dormant $ccG${Terrarum.game.actorContainerInactive.size}",
|
|
||||||
(2 + 28*8).toFloat(), Terrarum.HEIGHT - 10f)
|
|
||||||
|
|
||||||
g.color = GameFontBase.codeToCol["g"]
|
g.color = GameFontBase.codeToCol["g"]
|
||||||
g.drawString("${Terrarum.game.memInUse}M",
|
g.drawString("${Terrarum.game.memInUse}M",
|
||||||
(Terrarum.WIDTH - 11 * 8 - 2).toFloat(), 2f)
|
(Terrarum.WIDTH - 11 * 8 - 2).toFloat(), 2f)
|
||||||
g.drawString("/${Terrarum.game.totalVMMem}M",
|
g.drawString("/${Terrarum.game.totalVMMem}M",
|
||||||
(Terrarum.WIDTH - 6 * 8 - 2).toFloat(), 2f)
|
(Terrarum.WIDTH - 6 * 8 - 2).toFloat(), 2f)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Bottom left
|
||||||
|
*/
|
||||||
|
|
||||||
|
g.drawString("${ccY}Actors total $ccG${Terrarum.game.actorContainer.size + Terrarum.game.actorContainerInactive.size}",
|
||||||
|
2f, Terrarum.HEIGHT - 10f)
|
||||||
|
g.drawString("${ccY}Active $ccG${Terrarum.game.actorContainer.size}",
|
||||||
|
(2 + 17*8).toFloat(), Terrarum.HEIGHT - 10f)
|
||||||
|
g.drawString("${ccY}Dormant $ccG${Terrarum.game.actorContainerInactive.size}",
|
||||||
|
(2 + 28*8).toFloat(), Terrarum.HEIGHT - 10f)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun printLine(g: Graphics, l: Int, s: String) {
|
private fun printLine(g: Graphics, l: Int, s: String) {
|
||||||
|
|||||||
Reference in New Issue
Block a user