mirror of
https://github.com/collinsmith/riiablo.git
synced 2025-01-03 13:30:34 +07:00
Added support for DcParams#combineFrames
Added boolean combineFrames argument to Dc#uploadTextures() Created Dc#numPages() to support combined frames Defined Dc6#PAGE_SIZE and changed constants to reference it Implemented combined frames into Dc6 (Dcc unsupported) Refactored subclass fields into Dc#MISSING_TEXTURE Created Dc#box() methods Improved DccLoader test cases with asset failure to load test case
This commit is contained in:
parent
070295a25c
commit
ffad38ad76
@ -112,7 +112,7 @@ public class DccLoader extends AssetLoader<Dcc> {
|
|||||||
log.traceEntry("loadSync(assets: {}, asset: {}, dcc: {})", assets, asset, dcc);
|
log.traceEntry("loadSync(assets: {}, asset: {}, dcc: {})", assets, asset, dcc);
|
||||||
DcParams params = asset.params(DcParams.class);
|
DcParams params = asset.params(DcParams.class);
|
||||||
if (params.direction < 0) return dcc;
|
if (params.direction < 0) return dcc;
|
||||||
dcc.uploadTextures(params.direction);
|
dcc.uploadTextures(params.direction, params.combineFrames);
|
||||||
return dcc;
|
return dcc;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -7,15 +7,25 @@ import io.netty.util.ReferenceCounted;
|
|||||||
import java.lang.reflect.Array;
|
import java.lang.reflect.Array;
|
||||||
|
|
||||||
import com.badlogic.gdx.files.FileHandle;
|
import com.badlogic.gdx.files.FileHandle;
|
||||||
|
import com.badlogic.gdx.graphics.Texture;
|
||||||
import com.badlogic.gdx.graphics.g2d.TextureRegion;
|
import com.badlogic.gdx.graphics.g2d.TextureRegion;
|
||||||
import com.badlogic.gdx.utils.Disposable;
|
import com.badlogic.gdx.utils.Disposable;
|
||||||
|
|
||||||
import com.riiablo.codec.util.BBox;
|
import com.riiablo.codec.util.BBox;
|
||||||
|
import com.riiablo.logger.LogManager;
|
||||||
|
import com.riiablo.logger.Logger;
|
||||||
|
|
||||||
|
import static com.riiablo.util.ImplUtils.todo;
|
||||||
|
|
||||||
public abstract class Dc<D extends Dc.Direction>
|
public abstract class Dc<D extends Dc.Direction>
|
||||||
extends AbstractReferenceCounted
|
extends AbstractReferenceCounted
|
||||||
implements Disposable
|
implements Disposable
|
||||||
{
|
{
|
||||||
|
private static final Logger log = LogManager.getLogger(Dc.class);
|
||||||
|
|
||||||
|
@SuppressWarnings("GDXJavaStaticResource")
|
||||||
|
public static Texture MISSING_TEXTURE;
|
||||||
|
|
||||||
protected final FileHandle handle;
|
protected final FileHandle handle;
|
||||||
protected final int numDirections;
|
protected final int numDirections;
|
||||||
protected final int numFrames;
|
protected final int numFrames;
|
||||||
@ -74,6 +84,32 @@ public abstract class Dc<D extends Dc.Direction>
|
|||||||
return directions[d];
|
return directions[d];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void uploadTextures(int d, boolean combineFrames) {}
|
||||||
|
|
||||||
|
public BBox box() {
|
||||||
|
return todo();
|
||||||
|
}
|
||||||
|
|
||||||
|
public BBox box(int d) {
|
||||||
|
return direction(d).box();
|
||||||
|
}
|
||||||
|
|
||||||
|
public BBox box(int d, int f) {
|
||||||
|
return direction(d).frame(f).box();
|
||||||
|
}
|
||||||
|
|
||||||
|
public int numPages() {
|
||||||
|
return numFrames;
|
||||||
|
}
|
||||||
|
|
||||||
|
public TextureRegion page(int i) {
|
||||||
|
return page(0, i);
|
||||||
|
}
|
||||||
|
|
||||||
|
public TextureRegion page(int d, int i) {
|
||||||
|
return direction(d).frame(i).texture();
|
||||||
|
}
|
||||||
|
|
||||||
public static abstract class Direction<F extends Dc.Frame> implements Disposable {
|
public static abstract class Direction<F extends Dc.Frame> implements Disposable {
|
||||||
@Override public void dispose() {}
|
@Override public void dispose() {}
|
||||||
public abstract F[] frames();
|
public abstract F[] frames();
|
||||||
@ -90,4 +126,107 @@ public abstract class Dc<D extends Dc.Direction>
|
|||||||
public abstract BBox box();
|
public abstract BBox box();
|
||||||
public abstract TextureRegion texture();
|
public abstract TextureRegion texture();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static int toRealDir(int d, int numDirs) {
|
||||||
|
switch (numDirs) {
|
||||||
|
case 1:
|
||||||
|
case 2:
|
||||||
|
case 4: return d;
|
||||||
|
case 8: return toRealDir8(d);
|
||||||
|
case 16: return toRealDir16(d);
|
||||||
|
case 32: return toRealDir32(d);
|
||||||
|
default: // FIXME: see #113
|
||||||
|
log.error("numDirs({}) invalid: should be one of {1,2,4,8,16,32}", numDirs);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int toRealDir8(int d) {
|
||||||
|
switch (d) {
|
||||||
|
case 0: return 1;
|
||||||
|
case 1: return 3;
|
||||||
|
case 2: return 5;
|
||||||
|
case 3: return 7;
|
||||||
|
|
||||||
|
case 4: return 0;
|
||||||
|
case 5: return 2;
|
||||||
|
case 6: return 4;
|
||||||
|
case 7: return 6;
|
||||||
|
|
||||||
|
default: // FIXME: see #113
|
||||||
|
log.error("d({}) invalid: should be in [{}..{})", d, 0, 8);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int toRealDir16(int d) {
|
||||||
|
switch (d) {
|
||||||
|
case 0: return 2;
|
||||||
|
case 1: return 6;
|
||||||
|
case 2: return 10;
|
||||||
|
case 3: return 14;
|
||||||
|
|
||||||
|
case 4: return 0;
|
||||||
|
case 5: return 4;
|
||||||
|
case 6: return 8;
|
||||||
|
case 7: return 12;
|
||||||
|
|
||||||
|
case 8: return 1;
|
||||||
|
case 9: return 3;
|
||||||
|
case 10: return 5;
|
||||||
|
case 11: return 7;
|
||||||
|
case 12: return 9;
|
||||||
|
case 13: return 11;
|
||||||
|
case 14: return 13;
|
||||||
|
case 15: return 15;
|
||||||
|
|
||||||
|
default: // FIXME: see #113
|
||||||
|
log.error("d({}) invalid: should be in [{}..{})", d, 0, 16);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int toRealDir32(int d) {
|
||||||
|
switch (d) {
|
||||||
|
case 0: return 4;
|
||||||
|
case 1: return 12;
|
||||||
|
case 2: return 20;
|
||||||
|
case 3: return 28;
|
||||||
|
|
||||||
|
case 4: return 0;
|
||||||
|
case 5: return 8;
|
||||||
|
case 6: return 16;
|
||||||
|
case 7: return 24;
|
||||||
|
|
||||||
|
case 8: return 2;
|
||||||
|
case 9: return 6;
|
||||||
|
case 10: return 10;
|
||||||
|
case 11: return 14;
|
||||||
|
case 12: return 18;
|
||||||
|
case 13: return 22;
|
||||||
|
case 14: return 26;
|
||||||
|
case 15: return 30;
|
||||||
|
|
||||||
|
case 16: return 1;
|
||||||
|
case 17: return 3;
|
||||||
|
case 18: return 5;
|
||||||
|
case 19: return 7;
|
||||||
|
case 20: return 9;
|
||||||
|
case 21: return 11;
|
||||||
|
case 22: return 13;
|
||||||
|
case 23: return 15;
|
||||||
|
case 24: return 17;
|
||||||
|
case 25: return 19;
|
||||||
|
case 26: return 21;
|
||||||
|
case 27: return 23;
|
||||||
|
case 28: return 25;
|
||||||
|
case 29: return 27;
|
||||||
|
case 30: return 29;
|
||||||
|
case 31: return 31;
|
||||||
|
|
||||||
|
default: // FIXME: see #113
|
||||||
|
log.error("d({}) invalid: should be in [{}..{})", d, 0, 32);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -19,11 +19,12 @@ import com.riiablo.logger.Logger;
|
|||||||
import com.riiablo.logger.MDC;
|
import com.riiablo.logger.MDC;
|
||||||
import com.riiablo.util.DebugUtils;
|
import com.riiablo.util.DebugUtils;
|
||||||
|
|
||||||
|
import static com.riiablo.graphics.PaletteIndexedPixmap.INDEXED;
|
||||||
|
|
||||||
public class Dc6 extends Dc<Dc6.Dc6Direction> {
|
public class Dc6 extends Dc<Dc6.Dc6Direction> {
|
||||||
private static final Logger log = LogManager.getLogger(Dc6.class);
|
private static final Logger log = LogManager.getLogger(Dc6.class);
|
||||||
|
|
||||||
@SuppressWarnings("GDXJavaStaticResource")
|
public static final int PAGE_SIZE = 256;
|
||||||
public static Texture MISSING_TEXTURE;
|
|
||||||
|
|
||||||
//final FileHandle handle; // Dc#handle
|
//final FileHandle handle; // Dc#handle
|
||||||
final byte[] signature;
|
final byte[] signature;
|
||||||
@ -33,6 +34,7 @@ public class Dc6 extends Dc<Dc6.Dc6Direction> {
|
|||||||
//final int numDirections; // Dc#numDirections
|
//final int numDirections; // Dc#numDirections
|
||||||
//final int numFrames; // Dc#numFrames
|
//final int numFrames; // Dc#numFrames
|
||||||
final int[] frameOffsets;
|
final int[] frameOffsets;
|
||||||
|
int numPages;
|
||||||
|
|
||||||
public static Dc6 read(FileHandle handle, InputStream stream) {
|
public static Dc6 read(FileHandle handle, InputStream stream) {
|
||||||
SwappedDataInputStream in = new SwappedDataInputStream(stream);
|
SwappedDataInputStream in = new SwappedDataInputStream(stream);
|
||||||
@ -83,6 +85,7 @@ public class Dc6 extends Dc<Dc6.Dc6Direction> {
|
|||||||
this.format = format;
|
this.format = format;
|
||||||
this.section = section;
|
this.section = section;
|
||||||
this.frameOffsets = frameOffsets;
|
this.frameOffsets = frameOffsets;
|
||||||
|
numPages = numFrames;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -90,6 +93,11 @@ public class Dc6 extends Dc<Dc6.Dc6Direction> {
|
|||||||
super.dispose();
|
super.dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int numPages() {
|
||||||
|
return numPages;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int dirOffset(int d) {
|
public int dirOffset(int d) {
|
||||||
return frameOffsets[d * numFrames];
|
return frameOffsets[d * numFrames];
|
||||||
@ -107,16 +115,48 @@ public class Dc6 extends Dc<Dc6.Dc6Direction> {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void uploadTextures(int d) {
|
@Override
|
||||||
|
public void uploadTextures(int d, boolean combineFrames) {
|
||||||
final Dc6Direction direction = directions[d];
|
final Dc6Direction direction = directions[d];
|
||||||
final Dc6Frame[] frame = direction.frames;
|
final Dc6Frame[] frame = direction.frames;
|
||||||
final Pixmap[] pixmap = direction.pixmap;
|
final Pixmap[] pixmap = direction.pixmap;
|
||||||
final Texture[] texture = direction.texture;
|
final Texture[] texture = direction.texture;
|
||||||
for (int f = 0; f < numFrames; f++) {
|
if (!combineFrames) {
|
||||||
Texture t = texture[f] = new Texture(pixmap[f]);
|
for (int f = 0; f < numFrames; f++) {
|
||||||
frame[f].texture.setRegion(t);
|
Texture t = texture[f] = new Texture(pixmap[f]);
|
||||||
pixmap[f].dispose();
|
frame[f].texture.setRegion(t);
|
||||||
pixmap[f] = null;
|
pixmap[f].dispose();
|
||||||
|
pixmap[f] = null;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
int rows = 0, columns = 0;
|
||||||
|
int width = 0, height = 0;
|
||||||
|
for (int w = 0, s = numFrames; w < s; w++) {
|
||||||
|
columns++;
|
||||||
|
width += frame[w].width;
|
||||||
|
if (frame[w].width < PAGE_SIZE) break;
|
||||||
|
}
|
||||||
|
for (int h = 0, s = numFrames; h < s; h += columns) {
|
||||||
|
rows++;
|
||||||
|
height += frame[h].height;
|
||||||
|
if (frame[h].height < PAGE_SIZE) break;
|
||||||
|
}
|
||||||
|
|
||||||
|
numPages = numFrames / (rows * columns);
|
||||||
|
for (int p = 0, s = numPages, f = 0; p < s; p++) {
|
||||||
|
int x = 0, y = 0;
|
||||||
|
Texture t = texture[p] = new Texture(width, height, INDEXED);
|
||||||
|
frame[p].texture.setRegion(t);
|
||||||
|
for (int r = 0; r < rows; r++, x = 0) {
|
||||||
|
for (int c = 0; c < columns; c++, f++) {
|
||||||
|
t.draw(pixmap[f], x, y);
|
||||||
|
pixmap[f].dispose();
|
||||||
|
pixmap[f] = null;
|
||||||
|
x += PAGE_SIZE;
|
||||||
|
}
|
||||||
|
y += PAGE_SIZE;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -14,8 +14,8 @@ import com.riiablo.io.ByteInput;
|
|||||||
|
|
||||||
public class Dc6Decoder {
|
public class Dc6Decoder {
|
||||||
static final boolean DEBUG = !true;
|
static final boolean DEBUG = !true;
|
||||||
static final int MAX_WIDTH = 256;
|
static final int MAX_WIDTH = Dc6.PAGE_SIZE;
|
||||||
static final int MAX_HEIGHT = 256;
|
static final int MAX_HEIGHT = Dc6.PAGE_SIZE;
|
||||||
|
|
||||||
final byte[] bmp = PlatformDependent.allocateUninitializedArray(MAX_WIDTH * MAX_HEIGHT); // 256x256 px
|
final byte[] bmp = PlatformDependent.allocateUninitializedArray(MAX_WIDTH * MAX_HEIGHT); // 256x256 px
|
||||||
|
|
||||||
|
@ -24,9 +24,6 @@ import com.riiablo.logger.MDC;
|
|||||||
public final class Dcc extends Dc<Dcc.DccDirection> {
|
public final class Dcc extends Dc<Dcc.DccDirection> {
|
||||||
private static final Logger log = LogManager.getLogger(Dcc.class);
|
private static final Logger log = LogManager.getLogger(Dcc.class);
|
||||||
|
|
||||||
@SuppressWarnings("GDXJavaStaticResource")
|
|
||||||
public static Texture MISSING_TEXTURE;
|
|
||||||
|
|
||||||
static final int ENCODED_BITS[] = {
|
static final int ENCODED_BITS[] = {
|
||||||
0, 1, 2, 4, 6, 8, 10, 12, 14, 16, 20, 24, 26, 28, 30, 32
|
0, 1, 2, 4, 6, 8, 10, 12, 14, 16, 20, 24, 26, 28, 30, 32
|
||||||
};
|
};
|
||||||
@ -102,6 +99,11 @@ public final class Dcc extends Dc<Dcc.DccDirection> {
|
|||||||
return dirOffsets[d];
|
return dirOffsets[d];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BBox box(int d, int f) {
|
||||||
|
return box(d);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Dcc read(ByteBuf buffer, int direction) {
|
public Dcc read(ByteBuf buffer, int direction) {
|
||||||
super.read(buffer, direction);
|
super.read(buffer, direction);
|
||||||
@ -110,7 +112,9 @@ public final class Dcc extends Dc<Dcc.DccDirection> {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void uploadTextures(int d) {
|
@Override
|
||||||
|
public void uploadTextures(int d, boolean combineFrames) {
|
||||||
|
if (combineFrames) throw new UnsupportedOperationException("DCC do not support combined frames");
|
||||||
final DccDirection direction = directions[d];
|
final DccDirection direction = directions[d];
|
||||||
final DccFrame[] frame = direction.frames;
|
final DccFrame[] frame = direction.frames;
|
||||||
final Pixmap[] pixmap = direction.pixmap;
|
final Pixmap[] pixmap = direction.pixmap;
|
||||||
|
@ -139,11 +139,11 @@ public class AssetManagerTest extends RiiabloTest {
|
|||||||
@ParameterizedTest
|
@ParameterizedTest
|
||||||
@ValueSource(strings = {
|
@ValueSource(strings = {
|
||||||
"data\\global\\chars\\ba\\hd\\bahdbhma11hs.dcc",
|
"data\\global\\chars\\ba\\hd\\bahdbhma11hs.dcc",
|
||||||
// "data\\global\\CHARS\\BA\\LG\\BALGLITTNHTH.DCC",
|
"data\\global\\chars\\ba\\lg\\balglittnhth.dcc",
|
||||||
})
|
})
|
||||||
void load_mpq(String path) {
|
void load_mpq(String path) {
|
||||||
AssetDesc<Dcc> asset = AssetDesc.of(path, Dcc.class, DcParams.of(0));
|
AssetDesc<Dcc> asset = AssetDesc.of(path, Dcc.class, DcParams.of(0));
|
||||||
Future<Dcc> handle = assets.load(asset);
|
Future<? extends Dcc> handle = assets.load(asset);
|
||||||
try {
|
try {
|
||||||
assertNotNull(handle);
|
assertNotNull(handle);
|
||||||
assets.sync(100);
|
assets.sync(100);
|
||||||
|
172
core/src/test/java/com/riiablo/asset/loader/Dc6LoaderTest.java
Normal file
172
core/src/test/java/com/riiablo/asset/loader/Dc6LoaderTest.java
Normal file
@ -0,0 +1,172 @@
|
|||||||
|
package com.riiablo.asset.loader;
|
||||||
|
|
||||||
|
import org.junit.jupiter.api.*;
|
||||||
|
import org.junit.jupiter.params.*;
|
||||||
|
import org.junit.jupiter.params.provider.*;
|
||||||
|
|
||||||
|
import io.netty.util.concurrent.EventExecutor;
|
||||||
|
import io.netty.util.concurrent.FutureListener;
|
||||||
|
import io.netty.util.concurrent.ImmediateEventExecutor;
|
||||||
|
import io.netty.util.concurrent.Promise;
|
||||||
|
import org.apache.commons.lang3.math.NumberUtils;
|
||||||
|
|
||||||
|
import com.badlogic.gdx.ApplicationAdapter;
|
||||||
|
import com.badlogic.gdx.ApplicationListener;
|
||||||
|
import com.badlogic.gdx.Gdx;
|
||||||
|
import com.badlogic.gdx.backends.lwjgl.LwjglApplication;
|
||||||
|
import com.badlogic.gdx.backends.lwjgl.LwjglApplicationConfiguration;
|
||||||
|
import com.badlogic.gdx.files.FileHandle;
|
||||||
|
import com.badlogic.gdx.graphics.GL20;
|
||||||
|
import com.badlogic.gdx.graphics.Texture;
|
||||||
|
import com.badlogic.gdx.graphics.glutils.ShaderProgram;
|
||||||
|
import com.badlogic.gdx.utils.GdxRuntimeException;
|
||||||
|
|
||||||
|
import com.riiablo.Riiablo;
|
||||||
|
import com.riiablo.RiiabloTest;
|
||||||
|
import com.riiablo.asset.AssetDesc;
|
||||||
|
import com.riiablo.asset.AssetManager;
|
||||||
|
import com.riiablo.asset.AssetUtils;
|
||||||
|
import com.riiablo.asset.adapter.GdxFileHandleAdapter;
|
||||||
|
import com.riiablo.asset.adapter.MpqFileHandleAdapter;
|
||||||
|
import com.riiablo.asset.param.DcParams;
|
||||||
|
import com.riiablo.asset.param.MpqParams;
|
||||||
|
import com.riiablo.asset.resolver.GdxFileHandleResolver;
|
||||||
|
import com.riiablo.codec.util.BBox;
|
||||||
|
import com.riiablo.file.Dc;
|
||||||
|
import com.riiablo.file.Dc6;
|
||||||
|
import com.riiablo.file.Palette;
|
||||||
|
import com.riiablo.graphics.PaletteIndexedBatch;
|
||||||
|
import com.riiablo.mpq_bytebuf.MpqFileHandle;
|
||||||
|
import com.riiablo.mpq_bytebuf.MpqFileResolver;
|
||||||
|
import com.riiablo.util.InstallationFinder;
|
||||||
|
import com.riiablo.util.InstallationFinder.DefaultNotFound;
|
||||||
|
|
||||||
|
import static com.riiablo.graphics.BlendMode.NONE;
|
||||||
|
import static com.riiablo.graphics.PaletteIndexedPixmap.INDEXED;
|
||||||
|
|
||||||
|
public class Dc6LoaderTest {
|
||||||
|
AssetManager assets;
|
||||||
|
|
||||||
|
@BeforeEach
|
||||||
|
public void beforeEach() throws DefaultNotFound {
|
||||||
|
RiiabloTest.clearGdxContext();
|
||||||
|
final InstallationFinder finder = InstallationFinder.getInstance();
|
||||||
|
Riiablo.home = finder.defaultHomeDir();
|
||||||
|
assets = new AssetManager()
|
||||||
|
.resolver(GdxFileHandleResolver.Internal, 0)
|
||||||
|
.resolver(new MpqFileResolver(), 1)
|
||||||
|
.paramResolver(Dc.class, DcParams.class)
|
||||||
|
.adapter(FileHandle.class, new GdxFileHandleAdapter())
|
||||||
|
.adapter(MpqFileHandle.class, new MpqFileHandleAdapter())
|
||||||
|
.loader(Dc6.class, new Dc6Loader())
|
||||||
|
.loader(Palette.class, new PaletteLoader())
|
||||||
|
;
|
||||||
|
}
|
||||||
|
|
||||||
|
@AfterEach
|
||||||
|
public void afterEach() {
|
||||||
|
AssetUtils.dispose(assets);
|
||||||
|
}
|
||||||
|
|
||||||
|
@ParameterizedTest
|
||||||
|
@CsvSource(value = {
|
||||||
|
"data\\global\\monsters\\ty\\ra\\tyralitnuhth.dc6,0,false",
|
||||||
|
"data\\global\\ui\\panel\\invchar6.dc6,0,true",
|
||||||
|
}, delimiter = ',')
|
||||||
|
void load(String dccName, String szDirection, String szCombineFrames) throws Throwable {
|
||||||
|
int direction = NumberUtils.toInt(szDirection);
|
||||||
|
boolean combineFrames = Boolean.parseBoolean(szCombineFrames);
|
||||||
|
AssetDesc<Dc6> asset = AssetDesc.of(dccName, Dc6.class, DcParams.of(direction, combineFrames));
|
||||||
|
EventExecutor executor = ImmediateEventExecutor.INSTANCE;
|
||||||
|
final Promise<Throwable> promise = executor.newPromise();
|
||||||
|
LwjglApplicationConfiguration config = new LwjglApplicationConfiguration() {{
|
||||||
|
title = dccName;
|
||||||
|
forceExit = false;
|
||||||
|
}};
|
||||||
|
ApplicationListener listener = new ApplicationAdapter() {
|
||||||
|
Throwable throwable;
|
||||||
|
PaletteIndexedBatch batch;
|
||||||
|
ShaderProgram shader;
|
||||||
|
int frame = 0;
|
||||||
|
float updater = 0f;
|
||||||
|
Dc6 dc6;
|
||||||
|
Palette palette;
|
||||||
|
AssetDesc<Palette> paletteAsset;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void create() {
|
||||||
|
try {
|
||||||
|
create0();
|
||||||
|
} catch (Throwable t) {
|
||||||
|
t.printStackTrace(System.err);
|
||||||
|
throwable = t;
|
||||||
|
Gdx.app.exit();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void create0() throws InterruptedException {
|
||||||
|
Dc.MISSING_TEXTURE = new Texture(0, 0, INDEXED);
|
||||||
|
|
||||||
|
assets.load(asset)
|
||||||
|
.addListener((FutureListener<Dc6>) future -> dc6 = future.getNow());
|
||||||
|
|
||||||
|
String paletteName = "data\\global\\palette\\ACT1\\pal.dat";
|
||||||
|
paletteAsset = AssetDesc.of(paletteName, Palette.class, MpqParams.of());
|
||||||
|
assets.load(paletteAsset)
|
||||||
|
.addListener((FutureListener<Palette>) future -> palette = future.getNow());
|
||||||
|
|
||||||
|
ShaderProgram.pedantic = false;
|
||||||
|
shader = new ShaderProgram(
|
||||||
|
Gdx.files.internal("shaders/indexpalette3.vert"),
|
||||||
|
Gdx.files.internal("shaders/indexpalette3.frag"));
|
||||||
|
if (!shader.isCompiled()) {
|
||||||
|
throw new GdxRuntimeException("Error compiling shader: " + shader.getLog());
|
||||||
|
}
|
||||||
|
batch = new PaletteIndexedBatch(1024, shader);
|
||||||
|
batch.setGamma(1.2f);
|
||||||
|
|
||||||
|
assets.awaitAll(asset, paletteAsset);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void render() {
|
||||||
|
Gdx.gl.glClearColor(0.3f, 0.3f, 0.3f, 1);
|
||||||
|
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
|
||||||
|
batch.setBlendMode(NONE);
|
||||||
|
batch.begin(palette.texture());
|
||||||
|
if (combineFrames) {
|
||||||
|
batch.draw(dc6.page(0), 0, 0);
|
||||||
|
batch.end();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
updater += Gdx.graphics.getDeltaTime();
|
||||||
|
if (updater > 0.25f) {
|
||||||
|
updater -= 0.25f;
|
||||||
|
frame++;
|
||||||
|
if (frame >= dc6.numFrames()) {
|
||||||
|
frame = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Dc6.Dc6Direction dir = dc6.direction(0);
|
||||||
|
BBox box = dir.frame(frame).box();
|
||||||
|
batch.draw(dc6.direction(0).frame(frame).texture(),
|
||||||
|
dir.box().width + box.xMin, -box.yMax,
|
||||||
|
box.width, box.height);
|
||||||
|
batch.end();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void dispose() {
|
||||||
|
assets.unload(paletteAsset);
|
||||||
|
assets.unload(asset);
|
||||||
|
AssetUtils.dispose(Dc.MISSING_TEXTURE);
|
||||||
|
AssetUtils.dispose(shader);
|
||||||
|
AssetUtils.dispose(batch);
|
||||||
|
promise.setSuccess(throwable);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
new LwjglApplication(listener, config);
|
||||||
|
Throwable throwable = promise.awaitUninterruptibly().getNow();
|
||||||
|
if (throwable != null) throw throwable;
|
||||||
|
}
|
||||||
|
}
|
@ -3,6 +3,7 @@ package com.riiablo.asset.loader;
|
|||||||
import org.junit.jupiter.api.*;
|
import org.junit.jupiter.api.*;
|
||||||
import org.junit.jupiter.params.*;
|
import org.junit.jupiter.params.*;
|
||||||
import org.junit.jupiter.params.provider.*;
|
import org.junit.jupiter.params.provider.*;
|
||||||
|
import static org.junit.jupiter.api.Assertions.*;
|
||||||
|
|
||||||
import io.netty.util.concurrent.EventExecutor;
|
import io.netty.util.concurrent.EventExecutor;
|
||||||
import io.netty.util.concurrent.FutureListener;
|
import io.netty.util.concurrent.FutureListener;
|
||||||
@ -25,6 +26,7 @@ import com.riiablo.RiiabloTest;
|
|||||||
import com.riiablo.asset.AssetDesc;
|
import com.riiablo.asset.AssetDesc;
|
||||||
import com.riiablo.asset.AssetManager;
|
import com.riiablo.asset.AssetManager;
|
||||||
import com.riiablo.asset.AssetUtils;
|
import com.riiablo.asset.AssetUtils;
|
||||||
|
import com.riiablo.asset.InvalidParams;
|
||||||
import com.riiablo.asset.adapter.GdxFileHandleAdapter;
|
import com.riiablo.asset.adapter.GdxFileHandleAdapter;
|
||||||
import com.riiablo.asset.adapter.MpqFileHandleAdapter;
|
import com.riiablo.asset.adapter.MpqFileHandleAdapter;
|
||||||
import com.riiablo.asset.param.DcParams;
|
import com.riiablo.asset.param.DcParams;
|
||||||
@ -34,6 +36,8 @@ import com.riiablo.file.Dc;
|
|||||||
import com.riiablo.file.Dcc;
|
import com.riiablo.file.Dcc;
|
||||||
import com.riiablo.file.Palette;
|
import com.riiablo.file.Palette;
|
||||||
import com.riiablo.graphics.PaletteIndexedBatch;
|
import com.riiablo.graphics.PaletteIndexedBatch;
|
||||||
|
import com.riiablo.logger.Level;
|
||||||
|
import com.riiablo.logger.LogManager;
|
||||||
import com.riiablo.mpq_bytebuf.MpqFileHandle;
|
import com.riiablo.mpq_bytebuf.MpqFileHandle;
|
||||||
import com.riiablo.mpq_bytebuf.MpqFileResolver;
|
import com.riiablo.mpq_bytebuf.MpqFileResolver;
|
||||||
import com.riiablo.util.InstallationFinder;
|
import com.riiablo.util.InstallationFinder;
|
||||||
@ -45,6 +49,11 @@ import static com.riiablo.graphics.PaletteIndexedPixmap.INDEXED;
|
|||||||
public class DccLoaderTest {
|
public class DccLoaderTest {
|
||||||
AssetManager assets;
|
AssetManager assets;
|
||||||
|
|
||||||
|
@BeforeAll
|
||||||
|
public static void beforeAll() {
|
||||||
|
LogManager.setLevel("com.riiablo.asset.AssetManager", Level.TRACE);
|
||||||
|
}
|
||||||
|
|
||||||
@BeforeEach
|
@BeforeEach
|
||||||
public void beforeEach() throws DefaultNotFound {
|
public void beforeEach() throws DefaultNotFound {
|
||||||
RiiabloTest.clearGdxContext();
|
RiiabloTest.clearGdxContext();
|
||||||
@ -66,6 +75,60 @@ public class DccLoaderTest {
|
|||||||
AssetUtils.dispose(assets);
|
AssetUtils.dispose(assets);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests that loading DCC with combine frames flag throws IllegalParams exception
|
||||||
|
*/
|
||||||
|
@ParameterizedTest
|
||||||
|
@ValueSource(strings = {
|
||||||
|
"data\\global\\chars\\ba\\hd\\bahdbhma11hs.dcc",
|
||||||
|
"data\\global\\chars\\ba\\lg\\balglittnhth.dcc",
|
||||||
|
"data\\global\\chars\\ba\\hd\\bahdlittnhth.dcc",
|
||||||
|
"data\\global\\chars\\ba\\tr\\batrlittnhth.dcc",
|
||||||
|
})
|
||||||
|
void fail(String dccName) throws Throwable {
|
||||||
|
AssetDesc<Dcc> asset = AssetDesc.of(dccName, Dcc.class, DcParams.of(0, true));
|
||||||
|
EventExecutor executor = ImmediateEventExecutor.INSTANCE;
|
||||||
|
final Promise<Throwable> promise = executor.newPromise();
|
||||||
|
LwjglApplicationConfiguration config = new LwjglApplicationConfiguration() {{
|
||||||
|
title = dccName;
|
||||||
|
forceExit = false;
|
||||||
|
}};
|
||||||
|
ApplicationListener listener = new ApplicationAdapter() {
|
||||||
|
Throwable failure;
|
||||||
|
Throwable success;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void create() {
|
||||||
|
try {
|
||||||
|
create0();
|
||||||
|
} catch (Throwable t) {
|
||||||
|
t.printStackTrace(System.err);
|
||||||
|
failure = t;
|
||||||
|
} finally {
|
||||||
|
Gdx.app.exit();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void create0() throws InterruptedException {
|
||||||
|
assets.load(asset)
|
||||||
|
.addListener((FutureListener<Dcc>) future -> success = future.cause());
|
||||||
|
assets.awaitAll(asset);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void dispose() {
|
||||||
|
assets.unload(asset);
|
||||||
|
if (failure != null) promise.setFailure(failure);
|
||||||
|
else promise.setSuccess(success);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
new LwjglApplication(listener, config);
|
||||||
|
Throwable success = promise.awaitUninterruptibly().getNow();
|
||||||
|
if (success == null) throw promise.cause();
|
||||||
|
assertEquals(InvalidParams.class, success.getClass());
|
||||||
|
success.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
@ParameterizedTest
|
@ParameterizedTest
|
||||||
@ValueSource(strings = {
|
@ValueSource(strings = {
|
||||||
"data\\global\\chars\\ba\\hd\\bahdbhma11hs.dcc",
|
"data\\global\\chars\\ba\\hd\\bahdbhma11hs.dcc",
|
||||||
@ -103,7 +166,7 @@ public class DccLoaderTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void create0() throws InterruptedException {
|
public void create0() throws InterruptedException {
|
||||||
Dcc.MISSING_TEXTURE = new Texture(0, 0, INDEXED);
|
Dc.MISSING_TEXTURE = new Texture(0, 0, INDEXED);
|
||||||
|
|
||||||
assets.load(asset)
|
assets.load(asset)
|
||||||
.addListener((FutureListener<Dcc>) future -> dcc = future.getNow());
|
.addListener((FutureListener<Dcc>) future -> dcc = future.getNow());
|
||||||
@ -150,7 +213,7 @@ public class DccLoaderTest {
|
|||||||
public void dispose() {
|
public void dispose() {
|
||||||
assets.unload(paletteAsset);
|
assets.unload(paletteAsset);
|
||||||
assets.unload(asset);
|
assets.unload(asset);
|
||||||
AssetUtils.dispose(Dcc.MISSING_TEXTURE);
|
AssetUtils.dispose(Dc.MISSING_TEXTURE);
|
||||||
AssetUtils.dispose(shader);
|
AssetUtils.dispose(shader);
|
||||||
AssetUtils.dispose(batch);
|
AssetUtils.dispose(batch);
|
||||||
promise.setSuccess(throwable);
|
promise.setSuccess(throwable);
|
||||||
|
@ -83,7 +83,7 @@ public class Dc6DecoderTest {
|
|||||||
|
|
||||||
void create0() {
|
void create0() {
|
||||||
decoder.decode(dc6, 0);
|
decoder.decode(dc6, 0);
|
||||||
dc6.uploadTextures(0);
|
dc6.uploadTextures(0, false);
|
||||||
|
|
||||||
String paletteName = "data\\global\\palette\\ACT1\\pal.dat";
|
String paletteName = "data\\global\\palette\\ACT1\\pal.dat";
|
||||||
AssetDesc<Palette> paletteDesc = AssetDesc.of(paletteName, Palette.class, MpqParams.of());
|
AssetDesc<Palette> paletteDesc = AssetDesc.of(paletteName, Palette.class, MpqParams.of());
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
package com.riiablo.file;
|
package com.riiablo.file;
|
||||||
|
|
||||||
import org.junit.jupiter.api.*;
|
import org.junit.jupiter.api.*;
|
||||||
|
import org.junit.jupiter.params.*;
|
||||||
|
import org.junit.jupiter.params.provider.*;
|
||||||
|
|
||||||
import io.netty.buffer.ByteBuf;
|
import io.netty.buffer.ByteBuf;
|
||||||
import io.netty.util.ReferenceCountUtil;
|
import io.netty.util.ReferenceCountUtil;
|
||||||
@ -22,13 +24,16 @@ public class Dc6Test extends RiiabloTest {
|
|||||||
LogManager.setLevel("com.riiablo.file.Dc6", Level.TRACE);
|
LogManager.setLevel("com.riiablo.file.Dc6", Level.TRACE);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@ParameterizedTest
|
||||||
@DisplayName("dc6_buffers w/ data\\global\\monsters\\ty\\ra\\tyralitnuhth.dc6")
|
@ValueSource(strings = {
|
||||||
void dc6_buffers() throws Exception {
|
"data\\global\\monsters\\ty\\ra\\tyralitnuhth.dc6",
|
||||||
|
"data\\global\\ui\\panel\\invchar6.dc6",
|
||||||
|
"data\\global\\ui\\Loading\\loadingscreen.dc6",
|
||||||
|
})
|
||||||
|
void test(String dc6Name) throws Exception {
|
||||||
EventExecutor executor = ImmediateEventExecutor.INSTANCE;
|
EventExecutor executor = ImmediateEventExecutor.INSTANCE;
|
||||||
MpqFileResolver resolver = new MpqFileResolver();
|
MpqFileResolver resolver = new MpqFileResolver();
|
||||||
try {
|
try {
|
||||||
final String dc6Name = "data\\global\\monsters\\ty\\ra\\tyralitnuhth.dc6";
|
|
||||||
AssetDesc<Dc6> parent = AssetDesc.of(dc6Name, Dc6.class, DcParams.of(-1));
|
AssetDesc<Dc6> parent = AssetDesc.of(dc6Name, Dc6.class, DcParams.of(-1));
|
||||||
MpqFileHandle dc6Handle = resolver.resolve(parent);
|
MpqFileHandle dc6Handle = resolver.resolve(parent);
|
||||||
try {
|
try {
|
||||||
|
@ -191,7 +191,7 @@ public class DccDecoderTest {
|
|||||||
|
|
||||||
void create0() {
|
void create0() {
|
||||||
decoder.decode(dcc, 0);
|
decoder.decode(dcc, 0);
|
||||||
dcc.uploadTextures(0);
|
dcc.uploadTextures(0, false);
|
||||||
|
|
||||||
String paletteName = "data\\global\\palette\\ACT1\\pal.dat";
|
String paletteName = "data\\global\\palette\\ACT1\\pal.dat";
|
||||||
AssetDesc<Palette> paletteDesc = AssetDesc.of(paletteName, Palette.class, MpqParams.of());
|
AssetDesc<Palette> paletteDesc = AssetDesc.of(paletteName, Palette.class, MpqParams.of());
|
||||||
|
Loading…
Reference in New Issue
Block a user