Skip to content

Commit

Permalink
Fix swapping battle stages causing one frame of texture animation to …
Browse files Browse the repository at this point in the history
…apply to the new stage's texture (closes #1931)
  • Loading branch information
LordMonoxide committed Feb 1, 2025
1 parent 579d2d8 commit 8fc5cb6
Show file tree
Hide file tree
Showing 3 changed files with 48 additions and 8 deletions.
18 changes: 18 additions & 0 deletions src/main/java/legend/core/RenderEngine.java
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,9 @@
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.Deque;
import java.util.EnumMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Locale;
import java.util.Map;
Expand Down Expand Up @@ -287,6 +289,8 @@ public class RenderEngine {

private int frameSkipIndex;

private final Deque<Runnable> tasks = new LinkedList<>();

public RenderEngine() {
this.mainBatch = new RenderBatch(this, () -> this.vdfUniform, this.vdfBuffer, this.lightBuffer);
this.scissorStack = new ScissorStack(this, this.mainBatch);
Expand Down Expand Up @@ -437,6 +441,13 @@ public Texture getLastFrame() {
return this.renderTextures[Math.floorMod(this.renderBufferIndex - 1, RENDER_BUFFER_COUNT)];
}

/** Submit a task to be run at the start of the next frame */
public void addTask(final Runnable task) {
synchronized(this.tasks) {
this.tasks.push(task);
}
}

public void init() {
this.camera2d = new BasicCamera(0.0f, 0.0f);
this.camera3d = new QuaternionCamera(0.0f, 0.0f, 0.0f);
Expand Down Expand Up @@ -553,6 +564,13 @@ public void init() {
this.renderBufferQuad.persistent = true;

this.window.events.onDraw(() -> {
synchronized(this.tasks) {
Runnable task;
while((task = this.tasks.poll()) != null) {
task.run();
}
}

if(this.frameSkipIndex == 0) {
this.pre();
}
Expand Down
36 changes: 28 additions & 8 deletions src/main/java/legend/game/combat/Battle.java
Original file line number Diff line number Diff line change
Expand Up @@ -1899,10 +1899,13 @@ public void FUN_800c8748() {

@Method(0x800c8774L)
public void loadStageTmdAndAnim(final String modelName, final List<FileData> files) {
LOGGER.info("Battle stage %s loaded", modelName);

this.setStageHasNoModel();

if(files.get(0).size() > 0 && files.get(1).size() > 0 && files.get(2).size() > 0) {
final BattleStage stage = battlePreloadedEntities_1f8003f4.stage_963c;
stage.name = modelName;
this.loadStageTmd(stage, new CContainer(modelName, files.get(0), 10), new TmdAnimationFile(files.get(1)));
stage.coord2_558.coord.transfer.set(0, 0, 0);
stage.param_5a8.rotate.set(0.0f, MathHelper.TWO_PI / 4.0f, 0.0f);
Expand Down Expand Up @@ -1974,28 +1977,43 @@ public void renderSkybox() {

@Method(0x800c8b20L)
public void loadStage(final int stage) {
LOGGER.info("Loading battle stage %d", stage);

if(battlePreloadedEntities_1f8003f4.skyboxObj != null) {
battlePreloadedEntities_1f8003f4.skyboxObj.delete();
battlePreloadedEntities_1f8003f4.skyboxObj = null;
}

loadDrgnDir(0, 2497 + stage, files -> {
if(files.get(1).hasVirtualSize()) {
this.loadStageMcq(new McqHeader(files.get(1)));
// GH#1931
// Disable texture animations so we don't corrupt the texture of the loading stage due to the old stage model still being loaded...
if(stage_800bda0c != null) {
for(int i = 0; i < 10; i++) {
stage_800bda0c._618[i] = 0;
}
}

if(files.get(2).size() != 0) {
this.loadStageTim(files.get(2));
}
});
// ... and defer loading to the next frame so that any texture animations currently in the pipeline finish
RENDERER.addTask(() -> {
loadDrgnDir(0, 2497 + stage, files -> {
if(files.get(1).hasVirtualSize()) {
this.loadStageMcq(new McqHeader(files.get(1)));
}

loadDrgnDir(0, (2497 + stage) + "/0", files -> this.loadStageTmdAndAnim("DRGN0/" + (2497 + stage) + "/0", files));
if(files.get(2).size() != 0) {
this.loadStageTim(files.get(2));
}
});

loadDrgnDir(0, (2497 + stage) + "/0", files -> this.loadStageTmdAndAnim("DRGN0/" + (2497 + stage) + "/0", files));
});

this.currentStage_800c66a4 = stage;
}

@Method(0x800c8c84L)
public void loadStageTim(final FileData data) {
LOGGER.info("Battle stage texture loaded");

final Tim tim = new Tim(data);

GPU.uploadData15(tim.getImageRect(), tim.getImageData());
Expand Down Expand Up @@ -2025,6 +2043,8 @@ public void rotateAndRenderBattleStage() {

@Method(0x800c8d64L)
public void loadStageMcq(final McqHeader mcq) {
LOGGER.info("Battle stage skybox loaded");

final int x;
if((battleFlags_800bc960 & 0x80) != 0) {
x = 320;
Expand Down
2 changes: 2 additions & 0 deletions src/main/java/legend/game/combat/environment/BattleStage.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
import legend.game.types.Keyframe0c;

public class BattleStage {
public String name;

public ModelPart10[] dobj2s_00;
// public final GsCOORDINATE2[] coord2s_a0 = new GsCOORDINATE2[10]; // Use coord2 on dobj2
// public final Transforms[] params_3c0 = new Transforms[10]; // Use dobj2.coord2.transforms
Expand Down

0 comments on commit 8fc5cb6

Please sign in to comment.