code style and arrangement change
This commit is contained in:
parent
7339ca69a7
commit
45344c589c
|
@ -4,6 +4,10 @@
|
|||
<option name="RIGHT_MARGIN" value="80" />
|
||||
<option name="WRAP_WHEN_TYPING_REACHES_RIGHT_MARGIN" value="true" />
|
||||
<option name="ENABLE_SECOND_REFORMAT" value="true" />
|
||||
<JavaCodeStyleSettings>
|
||||
<option name="ANNOTATION_PARAMETER_WRAP" value="5" />
|
||||
<option name="NEW_LINE_AFTER_LPAREN_IN_ANNOTATION" value="true" />
|
||||
</JavaCodeStyleSettings>
|
||||
<editorconfig>
|
||||
<option name="ENABLED" value="false" />
|
||||
</editorconfig>
|
||||
|
@ -26,12 +30,301 @@
|
|||
<option name="PARENTHESES_EXPRESSION_LPAREN_WRAP" value="true" />
|
||||
<option name="PARENTHESES_EXPRESSION_RPAREN_WRAP" value="true" />
|
||||
<option name="BINARY_OPERATION_WRAP" value="5" />
|
||||
<option name="FOR_STATEMENT_WRAP" value="5" />
|
||||
<option name="FOR_STATEMENT_RPAREN_ON_NEXT_LINE" value="true" />
|
||||
<option name="ARRAY_INITIALIZER_WRAP" value="5" />
|
||||
<option name="ARRAY_INITIALIZER_LBRACE_ON_NEXT_LINE" value="true" />
|
||||
<option name="WHILE_BRACE_FORCE" value="3" />
|
||||
<option name="FOR_BRACE_FORCE" value="3" />
|
||||
<option name="WRAP_LONG_LINES" value="true" />
|
||||
<indentOptions>
|
||||
<option name="CONTINUATION_INDENT_SIZE" value="4" />
|
||||
<option name="USE_TAB_CHARACTER" value="true" />
|
||||
</indentOptions>
|
||||
<arrangement>
|
||||
<groups />
|
||||
<rules>
|
||||
<section>
|
||||
<rule>
|
||||
<match>
|
||||
<AND>
|
||||
<FIELD>true</FIELD>
|
||||
<FINAL>true</FINAL>
|
||||
<PUBLIC>true</PUBLIC>
|
||||
<STATIC>true</STATIC>
|
||||
</AND>
|
||||
</match>
|
||||
<order>BY_NAME</order>
|
||||
</rule>
|
||||
</section>
|
||||
<section>
|
||||
<rule>
|
||||
<match>
|
||||
<AND>
|
||||
<FIELD>true</FIELD>
|
||||
<FINAL>true</FINAL>
|
||||
<PROTECTED>true</PROTECTED>
|
||||
<STATIC>true</STATIC>
|
||||
</AND>
|
||||
</match>
|
||||
<order>BY_NAME</order>
|
||||
</rule>
|
||||
</section>
|
||||
<section>
|
||||
<rule>
|
||||
<match>
|
||||
<AND>
|
||||
<FIELD>true</FIELD>
|
||||
<FINAL>true</FINAL>
|
||||
<PACKAGE_PRIVATE>true</PACKAGE_PRIVATE>
|
||||
<STATIC>true</STATIC>
|
||||
</AND>
|
||||
</match>
|
||||
<order>BY_NAME</order>
|
||||
</rule>
|
||||
</section>
|
||||
<section>
|
||||
<rule>
|
||||
<match>
|
||||
<AND>
|
||||
<FIELD>true</FIELD>
|
||||
<FINAL>true</FINAL>
|
||||
<PRIVATE>true</PRIVATE>
|
||||
<STATIC>true</STATIC>
|
||||
</AND>
|
||||
</match>
|
||||
<order>BY_NAME</order>
|
||||
</rule>
|
||||
</section>
|
||||
<section>
|
||||
<rule>
|
||||
<match>
|
||||
<AND>
|
||||
<FIELD>true</FIELD>
|
||||
<PUBLIC>true</PUBLIC>
|
||||
<STATIC>true</STATIC>
|
||||
</AND>
|
||||
</match>
|
||||
<order>BY_NAME</order>
|
||||
</rule>
|
||||
</section>
|
||||
<section>
|
||||
<rule>
|
||||
<match>
|
||||
<AND>
|
||||
<FIELD>true</FIELD>
|
||||
<PROTECTED>true</PROTECTED>
|
||||
<STATIC>true</STATIC>
|
||||
</AND>
|
||||
</match>
|
||||
<order>BY_NAME</order>
|
||||
</rule>
|
||||
</section>
|
||||
<section>
|
||||
<rule>
|
||||
<match>
|
||||
<AND>
|
||||
<FIELD>true</FIELD>
|
||||
<PACKAGE_PRIVATE>true</PACKAGE_PRIVATE>
|
||||
<STATIC>true</STATIC>
|
||||
</AND>
|
||||
</match>
|
||||
<order>BY_NAME</order>
|
||||
</rule>
|
||||
</section>
|
||||
<section>
|
||||
<rule>
|
||||
<match>
|
||||
<AND>
|
||||
<FIELD>true</FIELD>
|
||||
<PRIVATE>true</PRIVATE>
|
||||
<STATIC>true</STATIC>
|
||||
</AND>
|
||||
</match>
|
||||
<order>BY_NAME</order>
|
||||
</rule>
|
||||
</section>
|
||||
<section>
|
||||
<rule>
|
||||
<match>
|
||||
<AND>
|
||||
<INITIALIZER_BLOCK>true</INITIALIZER_BLOCK>
|
||||
<STATIC>true</STATIC>
|
||||
</AND>
|
||||
</match>
|
||||
</rule>
|
||||
</section>
|
||||
<section>
|
||||
<rule>
|
||||
<match>
|
||||
<AND>
|
||||
<FIELD>true</FIELD>
|
||||
<FINAL>true</FINAL>
|
||||
<PUBLIC>true</PUBLIC>
|
||||
</AND>
|
||||
</match>
|
||||
<order>BY_NAME</order>
|
||||
</rule>
|
||||
</section>
|
||||
<section>
|
||||
<rule>
|
||||
<match>
|
||||
<AND>
|
||||
<FIELD>true</FIELD>
|
||||
<FINAL>true</FINAL>
|
||||
<PROTECTED>true</PROTECTED>
|
||||
</AND>
|
||||
</match>
|
||||
<order>BY_NAME</order>
|
||||
</rule>
|
||||
</section>
|
||||
<section>
|
||||
<rule>
|
||||
<match>
|
||||
<AND>
|
||||
<FIELD>true</FIELD>
|
||||
<FINAL>true</FINAL>
|
||||
<PACKAGE_PRIVATE>true</PACKAGE_PRIVATE>
|
||||
</AND>
|
||||
</match>
|
||||
<order>BY_NAME</order>
|
||||
</rule>
|
||||
</section>
|
||||
<section>
|
||||
<rule>
|
||||
<match>
|
||||
<AND>
|
||||
<FIELD>true</FIELD>
|
||||
<FINAL>true</FINAL>
|
||||
<PRIVATE>true</PRIVATE>
|
||||
</AND>
|
||||
</match>
|
||||
<order>BY_NAME</order>
|
||||
</rule>
|
||||
</section>
|
||||
<section>
|
||||
<rule>
|
||||
<match>
|
||||
<AND>
|
||||
<FIELD>true</FIELD>
|
||||
<PUBLIC>true</PUBLIC>
|
||||
</AND>
|
||||
</match>
|
||||
<order>BY_NAME</order>
|
||||
</rule>
|
||||
</section>
|
||||
<section>
|
||||
<rule>
|
||||
<match>
|
||||
<AND>
|
||||
<FIELD>true</FIELD>
|
||||
<PROTECTED>true</PROTECTED>
|
||||
</AND>
|
||||
</match>
|
||||
<order>BY_NAME</order>
|
||||
</rule>
|
||||
</section>
|
||||
<section>
|
||||
<rule>
|
||||
<match>
|
||||
<AND>
|
||||
<FIELD>true</FIELD>
|
||||
<PACKAGE_PRIVATE>true</PACKAGE_PRIVATE>
|
||||
</AND>
|
||||
</match>
|
||||
<order>BY_NAME</order>
|
||||
</rule>
|
||||
</section>
|
||||
<section>
|
||||
<rule>
|
||||
<match>
|
||||
<AND>
|
||||
<FIELD>true</FIELD>
|
||||
<PRIVATE>true</PRIVATE>
|
||||
</AND>
|
||||
</match>
|
||||
<order>BY_NAME</order>
|
||||
</rule>
|
||||
</section>
|
||||
<section>
|
||||
<rule>
|
||||
<match>
|
||||
<FIELD>true</FIELD>
|
||||
</match>
|
||||
<order>BY_NAME</order>
|
||||
</rule>
|
||||
</section>
|
||||
<section>
|
||||
<rule>
|
||||
<match>
|
||||
<INITIALIZER_BLOCK>true</INITIALIZER_BLOCK>
|
||||
</match>
|
||||
</rule>
|
||||
</section>
|
||||
<section>
|
||||
<rule>
|
||||
<match>
|
||||
<CONSTRUCTOR>true</CONSTRUCTOR>
|
||||
</match>
|
||||
<order>BY_NAME</order>
|
||||
</rule>
|
||||
</section>
|
||||
<section>
|
||||
<rule>
|
||||
<match>
|
||||
<AND>
|
||||
<METHOD>true</METHOD>
|
||||
<STATIC>true</STATIC>
|
||||
</AND>
|
||||
</match>
|
||||
<order>BY_NAME</order>
|
||||
</rule>
|
||||
</section>
|
||||
<section>
|
||||
<rule>
|
||||
<match>
|
||||
<METHOD>true</METHOD>
|
||||
</match>
|
||||
<order>BY_NAME</order>
|
||||
</rule>
|
||||
</section>
|
||||
<section>
|
||||
<rule>
|
||||
<match>
|
||||
<ENUM>true</ENUM>
|
||||
</match>
|
||||
<order>BY_NAME</order>
|
||||
</rule>
|
||||
</section>
|
||||
<section>
|
||||
<rule>
|
||||
<match>
|
||||
<INTERFACE>true</INTERFACE>
|
||||
</match>
|
||||
<order>BY_NAME</order>
|
||||
</rule>
|
||||
</section>
|
||||
<section>
|
||||
<rule>
|
||||
<match>
|
||||
<AND>
|
||||
<CLASS>true</CLASS>
|
||||
<STATIC>true</STATIC>
|
||||
</AND>
|
||||
</match>
|
||||
<order>BY_NAME</order>
|
||||
</rule>
|
||||
</section>
|
||||
<section>
|
||||
<rule>
|
||||
<match>
|
||||
<CLASS>true</CLASS>
|
||||
</match>
|
||||
<order>BY_NAME</order>
|
||||
</rule>
|
||||
</section>
|
||||
</rules>
|
||||
</arrangement>
|
||||
</codeStyleSettings>
|
||||
<codeStyleSettings language="Markdown">
|
||||
<option name="RIGHT_MARGIN" value="60" />
|
||||
|
|
|
@ -13,13 +13,13 @@ import com.danitheskunk.skunkworks.nodes.NodeRoot;
|
|||
import org.lwjgl.glfw.GLFW;
|
||||
|
||||
public abstract class BaseGame {
|
||||
protected Engine engine;
|
||||
protected AudioEngine audioEngine;
|
||||
protected IFont debugFont;
|
||||
protected Engine engine;
|
||||
protected Mixer mixer;
|
||||
protected NodeRoot rootNode;
|
||||
protected SamplePlayer samplePlayer;
|
||||
protected IWindow window;
|
||||
protected IFont debugFont;
|
||||
protected NodeRoot rootNode;
|
||||
|
||||
public BaseGame(Vec2i windowSize, String windowTitle) {
|
||||
this.audioEngine = new AudioEngine(44100, 256, 8);
|
||||
|
@ -36,6 +36,39 @@ public abstract class BaseGame {
|
|||
init();
|
||||
}
|
||||
|
||||
protected void init() {
|
||||
|
||||
}
|
||||
|
||||
protected ISample loadSample(String path) {
|
||||
return audioEngine.loadSample(path);
|
||||
}
|
||||
|
||||
protected ITexture loadTexture(String path) {
|
||||
return window.loadTexture(path);
|
||||
}
|
||||
|
||||
protected void playSample(ISample sample) {
|
||||
samplePlayer.play(sample);
|
||||
}
|
||||
|
||||
protected void playSample(ISample sample, boolean looping) {
|
||||
samplePlayer.play(sample, looping);
|
||||
}
|
||||
|
||||
protected void render(IRenderContext rc) {
|
||||
//rc.drawString(new Vec2i(8, 8), "Welcome to Skunkworks, please
|
||||
// overide the render method to get started", debugFont, Color
|
||||
// .LIGHT_GRAY);
|
||||
}
|
||||
|
||||
protected void render3D(IRenderContext3D rc3d) {
|
||||
}
|
||||
|
||||
protected void renderPre(IRenderContext rc) {
|
||||
|
||||
}
|
||||
|
||||
public void run() {
|
||||
double lastTime, currentTime, delta;
|
||||
|
||||
|
@ -63,40 +96,7 @@ public abstract class BaseGame {
|
|||
}
|
||||
}
|
||||
|
||||
protected void render3D(IRenderContext3D rc3d) {
|
||||
}
|
||||
|
||||
protected void init() {
|
||||
|
||||
}
|
||||
|
||||
protected void renderPre(IRenderContext rc) {
|
||||
|
||||
}
|
||||
|
||||
protected void render(IRenderContext rc) {
|
||||
//rc.drawString(new Vec2i(8, 8), "Welcome to Skunkworks, please
|
||||
// overide the render method to get started", debugFont, Color
|
||||
// .LIGHT_GRAY);
|
||||
}
|
||||
|
||||
protected void update(double delta) {
|
||||
|
||||
}
|
||||
|
||||
protected ISample loadSample(String path) {
|
||||
return audioEngine.loadSample(path);
|
||||
}
|
||||
|
||||
protected void playSample(ISample sample) {
|
||||
samplePlayer.play(sample);
|
||||
}
|
||||
|
||||
protected void playSample(ISample sample, boolean looping) {
|
||||
samplePlayer.play(sample, looping);
|
||||
}
|
||||
|
||||
protected ITexture loadTexture(String path) {
|
||||
return window.loadTexture(path);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -20,6 +20,13 @@ abstract public class BaseWindow implements IWindow {
|
|||
return engine;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IFont loadFontTTF(String path, float size) {
|
||||
var bytes = engine.loadBytes(path);
|
||||
|
||||
return new FontTTF(bytes, size, this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public IFont loadFontTileset(String path) {
|
||||
var img = engine.loadImage(path);
|
||||
|
@ -29,13 +36,6 @@ abstract public class BaseWindow implements IWindow {
|
|||
return new FontTileset(tex);
|
||||
}
|
||||
|
||||
@Override
|
||||
public IFont loadFontTTF(String path, float size) {
|
||||
var bytes = engine.loadBytes(path);
|
||||
|
||||
return new FontTTF(bytes, size, this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public NineSlice loadNineSlice(Image image) {
|
||||
int x1 = -1;
|
||||
|
@ -73,34 +73,29 @@ abstract public class BaseWindow implements IWindow {
|
|||
}
|
||||
var tl = image.getSubImage(new Recti(1, 1, x1 - 1, y1 - 1));
|
||||
var top = image.getSubImage(new Recti(x1, 1, x2 - x1, y1 - 1));
|
||||
var tr = image.getSubImage(new Recti(
|
||||
x2,
|
||||
var tr = image.getSubImage(new Recti(x2,
|
||||
1,
|
||||
image.getWidth() - x2,
|
||||
y1 - 1
|
||||
));
|
||||
var left = image.getSubImage(new Recti(1, y1, x1 - 1, y2 - y1));
|
||||
var center = image.getSubImage(new Recti(x1, y1, x2 - x1, y2 - y1));
|
||||
var right = image.getSubImage(new Recti(
|
||||
x2,
|
||||
var right = image.getSubImage(new Recti(x2,
|
||||
y1,
|
||||
image.getWidth() - x2,
|
||||
y2 - y1
|
||||
));
|
||||
var bl = image.getSubImage(new Recti(
|
||||
1,
|
||||
var bl = image.getSubImage(new Recti(1,
|
||||
y2,
|
||||
x1 - 1,
|
||||
image.getHeight() - y2
|
||||
));
|
||||
var bottom = image.getSubImage(new Recti(
|
||||
x1,
|
||||
var bottom = image.getSubImage(new Recti(x1,
|
||||
y2,
|
||||
x2 - x1,
|
||||
image.getHeight() - y2
|
||||
));
|
||||
var br = image.getSubImage(new Recti(
|
||||
x2,
|
||||
var br = image.getSubImage(new Recti(x2,
|
||||
y2,
|
||||
image.getWidth() - x2,
|
||||
image.getHeight() - y2
|
||||
|
|
|
@ -1,16 +1,13 @@
|
|||
package com.danitheskunk.skunkworks;
|
||||
|
||||
import java.io.BufferedInputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.charset.Charset;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.LinkedHashMap;
|
||||
|
||||
public class Data {
|
||||
private LinkedHashMap<String, LinkedHashMap<String, String>> data;
|
||||
private String currentCategory;
|
||||
private Runnable callback;
|
||||
private String currentCategory;
|
||||
private final LinkedHashMap<String, LinkedHashMap<String, String>> data;
|
||||
|
||||
public Data(ByteBuffer data) {
|
||||
this.data = new LinkedHashMap<>();
|
||||
|
@ -19,13 +16,8 @@ public class Data {
|
|||
StandardCharsets.UTF_8.decode(data).toString().lines().forEach(this::processLine);
|
||||
}
|
||||
|
||||
public void reload(ByteBuffer data) {
|
||||
this.data.clear();
|
||||
this.data.put("", new LinkedHashMap<>());
|
||||
StandardCharsets.UTF_8.decode(data).toString().lines().forEach(this::processLine);
|
||||
if(callback != null) {
|
||||
callback.run();
|
||||
}
|
||||
public String get(String category, String key) {
|
||||
return data.get(category).get(key);
|
||||
}
|
||||
|
||||
public void onReload(Runnable callback) {
|
||||
|
@ -44,7 +36,12 @@ public class Data {
|
|||
}
|
||||
}
|
||||
|
||||
public String get(String category, String key) {
|
||||
return data.get(category).get(key);
|
||||
public void reload(ByteBuffer data) {
|
||||
this.data.clear();
|
||||
this.data.put("", new LinkedHashMap<>());
|
||||
StandardCharsets.UTF_8.decode(data).toString().lines().forEach(this::processLine);
|
||||
if(callback != null) {
|
||||
callback.run();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,9 +17,9 @@ import static com.danitheskunk.skunkworks.gfx.GraphicsBackend.OPENGL;
|
|||
|
||||
public class Engine {
|
||||
private final GraphicsBackend graphicsBackend;
|
||||
private final WatchService watchService;
|
||||
private final Map<WatchKey, Callable<Boolean>> watchCallbacks;
|
||||
private final Map<WatchKey, Path> watchPaths;
|
||||
private final WatchService watchService;
|
||||
|
||||
//Constructors
|
||||
public Engine() {
|
||||
|
@ -52,10 +52,6 @@ public class Engine {
|
|||
return buf;
|
||||
}
|
||||
|
||||
public Image loadImage(String path) {
|
||||
return new Image(loadBytes(path));
|
||||
}
|
||||
|
||||
public Data loadData(String path) {
|
||||
return new Data(loadBytes(path));
|
||||
}
|
||||
|
@ -69,19 +65,8 @@ public class Engine {
|
|||
return data;
|
||||
}
|
||||
|
||||
//requires engine.tick() to be called regularly
|
||||
public void watchFile(String path, Callable<Boolean> callback) {
|
||||
var p = Paths.get(path);
|
||||
var dir = p.getParent();
|
||||
try {
|
||||
var key = dir.register(watchService,
|
||||
StandardWatchEventKinds.ENTRY_MODIFY
|
||||
);
|
||||
watchCallbacks.put(key, callback);
|
||||
watchPaths.put(key, p.getFileName());
|
||||
} catch(IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
public Image loadImage(String path) {
|
||||
return new Image(loadBytes(path));
|
||||
}
|
||||
|
||||
public IWindow openWindow(Vec2i size, String title) {
|
||||
|
@ -107,4 +92,19 @@ public class Engine {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
//requires engine.tick() to be called regularly
|
||||
public void watchFile(String path, Callable<Boolean> callback) {
|
||||
var p = Paths.get(path);
|
||||
var dir = p.getParent();
|
||||
try {
|
||||
var key = dir.register(watchService,
|
||||
StandardWatchEventKinds.ENTRY_MODIFY
|
||||
);
|
||||
watchCallbacks.put(key, callback);
|
||||
watchPaths.put(key, p.getFileName());
|
||||
} catch(IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,10 +8,16 @@ import java.util.List;
|
|||
public interface IWindow {
|
||||
Engine getEngine();
|
||||
|
||||
IFont loadFontTileset(String path);
|
||||
Vec2i getMousePos();
|
||||
|
||||
boolean isMouseClicked(int button);
|
||||
|
||||
boolean isMouseDown(int button);
|
||||
|
||||
IFont loadFontTTF(String path, float size);
|
||||
|
||||
IFont loadFontTileset(String path);
|
||||
|
||||
NineSlice loadNineSlice(Image image);
|
||||
|
||||
NineSlice loadNineSlice(String path);
|
||||
|
@ -26,10 +32,10 @@ public interface IWindow {
|
|||
|
||||
void renderFinish(IRenderContext context);
|
||||
|
||||
IRenderContext renderStart();
|
||||
|
||||
void renderFinish3D(IRenderContext3D context);
|
||||
|
||||
IRenderContext renderStart();
|
||||
|
||||
IRenderContext3D renderStart3D();
|
||||
|
||||
//needs to be run after rendering
|
||||
|
@ -37,15 +43,9 @@ public interface IWindow {
|
|||
|
||||
void setDebug(boolean on);
|
||||
|
||||
boolean shouldClose();
|
||||
|
||||
void setStretchMode(WindowStretchMode mode);
|
||||
|
||||
Vec2i getMousePos();
|
||||
|
||||
boolean isMouseClicked(int button);
|
||||
|
||||
boolean isMouseDown(int button);
|
||||
boolean shouldClose();
|
||||
|
||||
void tick();
|
||||
}
|
||||
|
|
|
@ -11,26 +11,6 @@ public final class Mat4f {
|
|||
set(3, 3, 1.0);
|
||||
}
|
||||
|
||||
public double get(int x, int y) {
|
||||
return data[x + y * 4];
|
||||
}
|
||||
|
||||
public void set(int x, int y, double val) {
|
||||
data[x + y * 4] = val;
|
||||
}
|
||||
|
||||
public double[] asArray() {
|
||||
return data;
|
||||
}
|
||||
|
||||
public float[] asFloatArray() {
|
||||
var arr = new float[16];
|
||||
for(int i = 0; i < 16; ++i) {
|
||||
arr[i] = (float)data[i];
|
||||
}
|
||||
return arr;
|
||||
}
|
||||
|
||||
public static Mat4f perspective(
|
||||
double fovy, double aspect, double zNear, double zFar
|
||||
) {
|
||||
|
@ -65,4 +45,24 @@ public final class Mat4f {
|
|||
//mat.set(3, 3, 0);
|
||||
return mat;
|
||||
}
|
||||
|
||||
public double[] asArray() {
|
||||
return data;
|
||||
}
|
||||
|
||||
public float[] asFloatArray() {
|
||||
var arr = new float[16];
|
||||
for(int i = 0; i < 16; ++i) {
|
||||
arr[i] = (float) data[i];
|
||||
}
|
||||
return arr;
|
||||
}
|
||||
|
||||
public double get(int x, int y) {
|
||||
return data[x + y * 4];
|
||||
}
|
||||
|
||||
public void set(int x, int y, double val) {
|
||||
data[x + y * 4] = val;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -14,37 +14,12 @@ public final class Recti {
|
|||
this.size = size;
|
||||
}
|
||||
|
||||
//getters
|
||||
public Vec2i getPos() {
|
||||
return pos;
|
||||
}
|
||||
|
||||
public Vec2i getSize() {
|
||||
return size;
|
||||
}
|
||||
|
||||
public int getX() {
|
||||
return pos.getX();
|
||||
}
|
||||
|
||||
public int getY() {
|
||||
return pos.getY();
|
||||
}
|
||||
|
||||
public int getWidth() {
|
||||
return size.getX();
|
||||
}
|
||||
|
||||
public int getHeight() {
|
||||
return size.getY();
|
||||
}
|
||||
|
||||
public Vec2i getTopLeft() {
|
||||
return pos;
|
||||
}
|
||||
|
||||
public Vec2i getTopRight() {
|
||||
return new Vec2i(pos.getX() + size.getX(), pos.getY());
|
||||
public boolean contains(Vec2i vec) {
|
||||
var br = getBottomRight();
|
||||
return vec.getX() >= pos.getX() &&
|
||||
vec.getY() >= pos.getY() &&
|
||||
vec.getX() < br.getX() &&
|
||||
vec.getY() < br.getY();
|
||||
}
|
||||
|
||||
public Vec2i getBottomLeft() {
|
||||
|
@ -55,11 +30,36 @@ public final class Recti {
|
|||
return Vec2i.add(pos, size);
|
||||
}
|
||||
|
||||
public boolean contains(Vec2i vec) {
|
||||
var br = getBottomRight();
|
||||
return vec.getX() >= pos.getX() &&
|
||||
vec.getY() >= pos.getY() &&
|
||||
vec.getX() < br.getX() &&
|
||||
vec.getY() < br.getY();
|
||||
public int getHeight() {
|
||||
return size.getY();
|
||||
}
|
||||
|
||||
//getters
|
||||
public Vec2i getPos() {
|
||||
return pos;
|
||||
}
|
||||
|
||||
public Vec2i getSize() {
|
||||
return size;
|
||||
}
|
||||
|
||||
public Vec2i getTopLeft() {
|
||||
return pos;
|
||||
}
|
||||
|
||||
public Vec2i getTopRight() {
|
||||
return new Vec2i(pos.getX() + size.getX(), pos.getY());
|
||||
}
|
||||
|
||||
public int getWidth() {
|
||||
return size.getX();
|
||||
}
|
||||
|
||||
public int getX() {
|
||||
return pos.getX();
|
||||
}
|
||||
|
||||
public int getY() {
|
||||
return pos.getY();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
package com.danitheskunk.skunkworks;
|
||||
|
||||
import com.danitheskunk.skunkworks.gfx.IRenderContext;
|
||||
import com.danitheskunk.skunkworks.gfx.IRenderContext3D;
|
||||
|
||||
public class Test3D extends BaseGame {
|
||||
|
|
|
@ -4,8 +4,8 @@ import com.danitheskunk.skunkworks.audio.ISample;
|
|||
import com.danitheskunk.skunkworks.nodes.NodeSprite;
|
||||
|
||||
public class TestNode extends BaseGame {
|
||||
NodeSprite sprite;
|
||||
ISample kick;
|
||||
NodeSprite sprite;
|
||||
|
||||
public TestNode() {
|
||||
super(new Vec2i(1280, 720), "Skunkworks");
|
||||
|
|
|
@ -5,21 +5,9 @@ import com.danitheskunk.skunkworks.audio.nodes.Mixer;
|
|||
import com.danitheskunk.skunkworks.audio.nodes.Node;
|
||||
import com.danitheskunk.skunkworks.audio.nodes.SamplePlayer;
|
||||
import com.danitheskunk.skunkworks.audio.nodes.Sine;
|
||||
import org.lwjgl.openal.AL;
|
||||
import org.lwjgl.openal.ALC;
|
||||
|
||||
import javax.sound.sampled.*;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.IntBuffer;
|
||||
|
||||
import static org.lwjgl.openal.AL10.*;
|
||||
import static org.lwjgl.openal.ALC10.*;
|
||||
|
||||
public class TestSound {
|
||||
public static void main(String args[]) throws InterruptedException {
|
||||
public static void main(String[] args) throws InterruptedException {
|
||||
var engine = new AudioEngine(44100, 256, 16);
|
||||
var mix = new Mixer(engine, 4);
|
||||
var sin1 = new Sine(engine, 440);
|
||||
|
|
|
@ -15,25 +15,10 @@ public final class Vec2f {
|
|||
return new Vec2f(a.x + b.x, a.y + b.y);
|
||||
}
|
||||
|
||||
public static Vec2f sub(Vec2f a, Vec2f b) {
|
||||
return new Vec2f(a.x - b.x, a.y - b.y);
|
||||
}
|
||||
|
||||
public static Vec2f mul(Vec2f a, double b) {
|
||||
return new Vec2f(a.x * b, a.y * b);
|
||||
}
|
||||
|
||||
public static Vec2f div(Vec2f a, double b) {
|
||||
return new Vec2f(a.x / b, a.y / b);
|
||||
}
|
||||
|
||||
public static Vec2f tween(Vec2f a, Vec2f b, double amount) {
|
||||
return new Vec2f(
|
||||
Util.tweenDouble(a.x, b.x, amount),
|
||||
Util.tweenDouble(a.y, b.y, amount)
|
||||
);
|
||||
}
|
||||
|
||||
public static Vec2f div(Vec2i a, Vec2i b) {
|
||||
return new Vec2f(
|
||||
(double) a.getX() / (double) b.getX(),
|
||||
|
@ -41,6 +26,21 @@ public final class Vec2f {
|
|||
);
|
||||
}
|
||||
|
||||
public static Vec2f mul(Vec2f a, double b) {
|
||||
return new Vec2f(a.x * b, a.y * b);
|
||||
}
|
||||
|
||||
public static Vec2f sub(Vec2f a, Vec2f b) {
|
||||
return new Vec2f(a.x - b.x, a.y - b.y);
|
||||
}
|
||||
|
||||
public static Vec2f tween(Vec2f a, Vec2f b, double amount) {
|
||||
return new Vec2f(
|
||||
Util.tweenDouble(a.x, b.x, amount),
|
||||
Util.tweenDouble(a.y, b.y, amount)
|
||||
);
|
||||
}
|
||||
|
||||
//getters and setters
|
||||
public double getX() {
|
||||
return x;
|
||||
|
|
|
@ -28,19 +28,6 @@ public final class Vec2i {
|
|||
return new Vec2i(a.x + b.x + c.x + d.x, a.y + b.y + c.y + d.y);
|
||||
}
|
||||
|
||||
public static Vec2i sub(Vec2i a, Vec2i b) {
|
||||
return new Vec2i(a.x - b.x, a.y - b.y);
|
||||
}
|
||||
|
||||
public static Vec2i mul(Vec2i a, int b) {
|
||||
return new Vec2i(a.x * b, a.y * b);
|
||||
}
|
||||
|
||||
public static Vec2i mul(Vec2i a, Vec2i b) {
|
||||
return new Vec2i(a.x * b.x, a.y * b.y);
|
||||
}
|
||||
|
||||
|
||||
public static Vec2i div(Vec2i a, int b) {
|
||||
return new Vec2i(a.x / b, a.y / b);
|
||||
}
|
||||
|
@ -65,18 +52,20 @@ public final class Vec2i {
|
|||
return new Vec2f(a.x / (double) b.x, a.y / (double) b.y);
|
||||
}
|
||||
|
||||
public static Vec2i min(Vec2i a, Vec2i b) {
|
||||
return new Vec2i(Math.min(a.x, b.x), Math.min(a.y, b.y));
|
||||
}
|
||||
|
||||
public static Vec2i max(Vec2i a, Vec2i b) {
|
||||
return new Vec2i(Math.max(a.x, b.x), Math.max(a.y, b.y));
|
||||
}
|
||||
|
||||
public static Vec2i tween(Vec2i a, Vec2i b, double amount) {
|
||||
return new Vec2i(Util.tweenInt(a.x, b.x, amount),
|
||||
Util.tweenInt(a.y, b.y, amount)
|
||||
);
|
||||
public static Vec2i min(Vec2i a, Vec2i b) {
|
||||
return new Vec2i(Math.min(a.x, b.x), Math.min(a.y, b.y));
|
||||
}
|
||||
|
||||
public static Vec2i mul(Vec2i a, int b) {
|
||||
return new Vec2i(a.x * b, a.y * b);
|
||||
}
|
||||
|
||||
public static Vec2i mul(Vec2i a, Vec2i b) {
|
||||
return new Vec2i(a.x * b.x, a.y * b.y);
|
||||
}
|
||||
|
||||
public static Vec2i mul(Vec2f a, Vec2i b) {
|
||||
|
@ -89,6 +78,15 @@ public final class Vec2i {
|
|||
return new Vec2i((int) (a.x / b), (int) (a.y / b));
|
||||
}
|
||||
|
||||
public static Vec2i sub(Vec2i a, Vec2i b) {
|
||||
return new Vec2i(a.x - b.x, a.y - b.y);
|
||||
}
|
||||
|
||||
public static Vec2i tween(Vec2i a, Vec2i b, double amount) {
|
||||
return new Vec2i(Util.tweenInt(a.x, b.x, amount),
|
||||
Util.tweenInt(a.y, b.y, amount)
|
||||
);
|
||||
}
|
||||
|
||||
public int getX() {
|
||||
return x;
|
||||
|
@ -99,6 +97,6 @@ public final class Vec2i {
|
|||
}
|
||||
|
||||
public Vec2f toVec2f() {
|
||||
return new Vec2f((double) x, (double) y);
|
||||
return new Vec2f(x, y);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
package com.danitheskunk.skunkworks;
|
||||
|
||||
public final class Vec3f {
|
||||
public static Vec3f ZERO = new Vec3f(0, 0, 0);
|
||||
public static Vec3f ONE = new Vec3f(1, 1, 1);
|
||||
public static Vec3f ZERO = new Vec3f(0, 0, 0);
|
||||
private final double x, y, z;
|
||||
|
||||
public Vec3f(double x, double y, double z) {
|
||||
|
|
|
@ -1,14 +1,22 @@
|
|||
package com.danitheskunk.skunkworks.audio;
|
||||
|
||||
public class AudioBuffer {
|
||||
private double[] left;
|
||||
private double[] right;
|
||||
private final double[] left;
|
||||
private final double[] right;
|
||||
|
||||
public AudioBuffer(int size) {
|
||||
left = new double[size];
|
||||
right = new double[size];
|
||||
}
|
||||
|
||||
public double getLeft(int pos) {
|
||||
return left[pos];
|
||||
}
|
||||
|
||||
public double getRight(int pos) {
|
||||
return right[pos];
|
||||
}
|
||||
|
||||
public int getSize() {
|
||||
return left.length;
|
||||
}
|
||||
|
@ -17,12 +25,4 @@ public class AudioBuffer {
|
|||
this.left[pos] = left;
|
||||
this.right[pos] = right;
|
||||
}
|
||||
|
||||
public double getLeft(int pos) {
|
||||
return left[pos];
|
||||
}
|
||||
|
||||
public double getRight(int pos) {
|
||||
return right[pos];
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,13 +18,14 @@ import static org.lwjgl.openal.AL10.*;
|
|||
import static org.lwjgl.openal.ALC10.*;
|
||||
|
||||
public class AudioEngine {
|
||||
private int sampleRate;
|
||||
private int bufferSize;
|
||||
private int bufferCount;
|
||||
private long device;
|
||||
private long context;
|
||||
private int source;
|
||||
private final int bufferCount;
|
||||
private final int bufferSize;
|
||||
private final long context;
|
||||
private final long device;
|
||||
private Node node;
|
||||
private final int sampleRate;
|
||||
private final int source;
|
||||
|
||||
public AudioEngine(int sampleRate, int bufferSize, int bufferCount) {
|
||||
this.sampleRate = sampleRate;
|
||||
this.bufferSize = bufferSize;
|
||||
|
@ -50,8 +51,10 @@ public class AudioEngine {
|
|||
alSourcePlay(source);
|
||||
}
|
||||
|
||||
public int getBufferSize() {
|
||||
return bufferSize;
|
||||
private void addEmptyBuffer() {
|
||||
var buf = alGenBuffers();
|
||||
fillBuffer(buf);
|
||||
alSourceQueueBuffers(source, buf);
|
||||
}
|
||||
|
||||
public void close() {
|
||||
|
@ -72,37 +75,16 @@ public class AudioEngine {
|
|||
alBufferData(buffer, AL_FORMAT_STEREO16, shortBuffer, sampleRate);
|
||||
}
|
||||
|
||||
private void addEmptyBuffer() {
|
||||
var buf = alGenBuffers();
|
||||
fillBuffer(buf);
|
||||
alSourceQueueBuffers(source, buf);
|
||||
}
|
||||
|
||||
public void refill() {
|
||||
var bufCount = alGetSourcei(source, AL_BUFFERS_PROCESSED);
|
||||
var bufs = new int[bufCount];
|
||||
alSourceUnqueueBuffers(source, bufs);
|
||||
for(int i = 0; i < bufCount; ++i) {
|
||||
fillBuffer(bufs[i]);
|
||||
alSourceQueueBuffers(source, bufs[i]);
|
||||
}
|
||||
if(alGetSourcei(source, AL_SOURCE_STATE) != AL_PLAYING) {
|
||||
System.out.println("buffer underrun, addng buffer");
|
||||
addEmptyBuffer();
|
||||
alSourcePlay(source);
|
||||
}
|
||||
}
|
||||
|
||||
public int getSampleRate() {
|
||||
return sampleRate;
|
||||
public int getBufferSize() {
|
||||
return bufferSize;
|
||||
}
|
||||
|
||||
public Node getNode() {
|
||||
return node;
|
||||
}
|
||||
|
||||
public void setNode(Node node) {
|
||||
this.node = node;
|
||||
public int getSampleRate() {
|
||||
return sampleRate;
|
||||
}
|
||||
|
||||
public ISample loadSample(String path) {
|
||||
|
@ -154,4 +136,23 @@ public class AudioEngine {
|
|||
}
|
||||
return sample;
|
||||
}
|
||||
|
||||
public void refill() {
|
||||
var bufCount = alGetSourcei(source, AL_BUFFERS_PROCESSED);
|
||||
var bufs = new int[bufCount];
|
||||
alSourceUnqueueBuffers(source, bufs);
|
||||
for(int i = 0; i < bufCount; ++i) {
|
||||
fillBuffer(bufs[i]);
|
||||
alSourceQueueBuffers(source, bufs[i]);
|
||||
}
|
||||
if(alGetSourcei(source, AL_SOURCE_STATE) != AL_PLAYING) {
|
||||
System.out.println("buffer underrun, addng buffer");
|
||||
addEmptyBuffer();
|
||||
alSourcePlay(source);
|
||||
}
|
||||
}
|
||||
|
||||
public void setNode(Node node) {
|
||||
this.node = node;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,9 +8,9 @@ public interface ISample {
|
|||
|
||||
double getSampleRight(int pos);
|
||||
|
||||
void setSamplei(int pos, short left);
|
||||
boolean isStereo();
|
||||
|
||||
void setSamplei(int pos, short left, short right);
|
||||
|
||||
boolean isStereo();
|
||||
void setSamplei(int pos, short left);
|
||||
}
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
package com.danitheskunk.skunkworks.audio;
|
||||
|
||||
public class Samplei implements ISample {
|
||||
private short[] left;
|
||||
private short[] right;
|
||||
private final short[] left;
|
||||
private final short[] right;
|
||||
|
||||
public Samplei(int length, boolean stereo) {
|
||||
left = new short[length];
|
||||
|
@ -30,8 +30,8 @@ public class Samplei implements ISample {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void setSamplei(int pos, short left) {
|
||||
this.left[pos] = left;
|
||||
public boolean isStereo() {
|
||||
return left != right;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -41,7 +41,7 @@ public class Samplei implements ISample {
|
|||
}
|
||||
|
||||
@Override
|
||||
public boolean isStereo() {
|
||||
return left != right;
|
||||
public void setSamplei(int pos, short left) {
|
||||
this.left[pos] = left;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,7 +4,7 @@ import com.danitheskunk.skunkworks.audio.AudioBuffer;
|
|||
import com.danitheskunk.skunkworks.audio.AudioEngine;
|
||||
|
||||
public class Mixer extends Node {
|
||||
private int channels;
|
||||
private final int channels;
|
||||
|
||||
public Mixer(AudioEngine engine, int channels) {
|
||||
super(engine, channels, 1);
|
||||
|
|
|
@ -4,12 +4,12 @@ import com.danitheskunk.skunkworks.audio.AudioBuffer;
|
|||
import com.danitheskunk.skunkworks.audio.AudioEngine;
|
||||
|
||||
public abstract class Node {
|
||||
private int inCount;
|
||||
private int outCount;
|
||||
private boolean[] isOutConnected;
|
||||
private Node[] inConnections;
|
||||
private int[] inConnectionSlots;
|
||||
private AudioEngine engine;
|
||||
private final AudioEngine engine;
|
||||
private final int[] inConnectionSlots;
|
||||
private final Node[] inConnections;
|
||||
private final int inCount;
|
||||
private final boolean[] isOutConnected;
|
||||
private final int outCount;
|
||||
|
||||
public Node(AudioEngine engine, int inCount, int outCount) {
|
||||
this.inCount = inCount;
|
||||
|
@ -43,6 +43,13 @@ public abstract class Node {
|
|||
dst.inConnectionSlots[dstSlot] = srcSlot;
|
||||
}
|
||||
|
||||
public abstract AudioBuffer getBuffer(int slot);
|
||||
|
||||
protected AudioBuffer getBufferFromInput(int inSlot) {
|
||||
if(inConnections[inSlot] == null) return null;
|
||||
return inConnections[inSlot].getBuffer(inConnectionSlots[inSlot]);
|
||||
}
|
||||
|
||||
public AudioEngine getEngine() {
|
||||
return engine;
|
||||
}
|
||||
|
@ -54,11 +61,4 @@ public abstract class Node {
|
|||
public int getOutCount() {
|
||||
return outCount;
|
||||
}
|
||||
|
||||
public abstract AudioBuffer getBuffer(int slot);
|
||||
|
||||
protected AudioBuffer getBufferFromInput(int inSlot) {
|
||||
if(inConnections[inSlot] == null) return null;
|
||||
return inConnections[inSlot].getBuffer(inConnectionSlots[inSlot]);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,7 +8,7 @@ import java.util.ArrayList;
|
|||
import java.util.List;
|
||||
|
||||
public class SamplePlayer extends Node {
|
||||
private List<PlayingSample> samples;
|
||||
private final List<PlayingSample> samples;
|
||||
|
||||
public SamplePlayer(AudioEngine engine) {
|
||||
super(engine, 0, 1);
|
||||
|
@ -57,8 +57,8 @@ public class SamplePlayer extends Node {
|
|||
}
|
||||
|
||||
private static class PlayingSample {
|
||||
boolean loop;
|
||||
ISample sample;
|
||||
int tick;
|
||||
boolean loop;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,8 +4,8 @@ import com.danitheskunk.skunkworks.audio.AudioBuffer;
|
|||
import com.danitheskunk.skunkworks.audio.AudioEngine;
|
||||
|
||||
public class Sine extends Node {
|
||||
private final double freq;
|
||||
private int tick;
|
||||
private double freq;
|
||||
|
||||
public Sine(AudioEngine engine, double freq) {
|
||||
super(engine, 0, 1);
|
||||
|
|
|
@ -3,9 +3,9 @@ package com.danitheskunk.skunkworks.backends.gl;
|
|||
import static org.lwjgl.opengl.GL46.*;
|
||||
|
||||
public class Program {
|
||||
Shader vertex;
|
||||
Shader fragment;
|
||||
int program;
|
||||
Shader vertex;
|
||||
|
||||
public Program(String vertexSource, String fragmentSource) {
|
||||
vertex = new Shader(vertexSource, GL_VERTEX_SHADER);
|
||||
|
@ -17,14 +17,14 @@ public class Program {
|
|||
glLinkProgram(program);
|
||||
}
|
||||
|
||||
public void use() {
|
||||
glUseProgram(program);
|
||||
}
|
||||
|
||||
public int getAttribLocation(String attrib) {
|
||||
return glGetAttribLocation(program, attrib);
|
||||
}
|
||||
|
||||
public Shader getFragment() {
|
||||
return fragment;
|
||||
}
|
||||
|
||||
public int getUniformLocation(String attrib) {
|
||||
return glGetUniformLocation(program, attrib);
|
||||
}
|
||||
|
@ -33,7 +33,7 @@ public class Program {
|
|||
return vertex;
|
||||
}
|
||||
|
||||
public Shader getFragment() {
|
||||
return fragment;
|
||||
public void use() {
|
||||
glUseProgram(program);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -41,15 +41,17 @@ class RenderContext extends BaseRenderContext implements IRenderContext {
|
|||
var size = rect.getSize();
|
||||
|
||||
drawTexture(pos, slice.getTopLeft());
|
||||
drawTexture(
|
||||
new Vec2i(pos.getX() + slice.getLeft().getWidth() + centerWidth,
|
||||
drawTexture(new Vec2i(pos.getX() +
|
||||
slice.getLeft().getWidth() +
|
||||
centerWidth,
|
||||
pos.getY()
|
||||
),
|
||||
slice.getTopRight()
|
||||
);
|
||||
drawTexture(new Vec2i(pos.getX(),
|
||||
), slice.getTopRight());
|
||||
drawTexture(
|
||||
new Vec2i(pos.getX(),
|
||||
pos.getY() + slice.getTop().getHeight() + centerHeight
|
||||
), slice.getBottomLeft());
|
||||
),
|
||||
slice.getBottomLeft()
|
||||
);
|
||||
drawTexture(Vec2i.add(pos,
|
||||
slice.getTopLeft().getSize(),
|
||||
new Vec2i(centerWidth, centerHeight)
|
||||
|
|
|
@ -2,6 +2,7 @@ package com.danitheskunk.skunkworks.backends.gl;
|
|||
|
||||
import com.danitheskunk.skunkworks.Vec3f;
|
||||
import com.danitheskunk.skunkworks.gfx.BaseRenderContext3D;
|
||||
|
||||
import static org.lwjgl.opengl.GL46.*;
|
||||
|
||||
public class RenderContext3D extends BaseRenderContext3D {
|
||||
|
|
|
@ -3,8 +3,8 @@ package com.danitheskunk.skunkworks.backends.gl;
|
|||
import static org.lwjgl.opengl.GL46.*;
|
||||
|
||||
public class Shader {
|
||||
private int shader;
|
||||
private int type;
|
||||
private final int shader;
|
||||
private final int type;
|
||||
|
||||
public Shader(String source, int type) {
|
||||
this.type = type;
|
||||
|
|
|
@ -14,6 +14,11 @@ class Texture implements ITexture {
|
|||
this.img = img;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getHeight() {
|
||||
return img.getHeight();
|
||||
}
|
||||
|
||||
//setters
|
||||
Image getImg() {
|
||||
return img;
|
||||
|
@ -24,20 +29,15 @@ class Texture implements ITexture {
|
|||
return this.img.getSize();
|
||||
}
|
||||
|
||||
Recti getTexArea() {
|
||||
return texArea;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getWidth() {
|
||||
return img.getWidth();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getHeight() {
|
||||
return img.getHeight();
|
||||
}
|
||||
|
||||
Recti getTexArea() {
|
||||
return texArea;
|
||||
}
|
||||
|
||||
void setTexArea(Recti texArea) {
|
||||
this.texArea = texArea;
|
||||
}
|
||||
|
|
|
@ -13,11 +13,11 @@ import java.util.List;
|
|||
import static org.lwjgl.opengl.GL11.*;
|
||||
|
||||
class TextureAtlas {
|
||||
final private int textureID;
|
||||
private final List<Texture> textures;
|
||||
private Texture atlasTexture; //for debugging
|
||||
private Image img;
|
||||
private boolean shouldUpdate;
|
||||
final private int textureID;
|
||||
|
||||
TextureAtlas() {
|
||||
img = new Image(new Vec2i(32, 32));
|
||||
|
@ -33,15 +33,10 @@ class TextureAtlas {
|
|||
|
||||
}
|
||||
|
||||
public void bind() {
|
||||
glBindTexture(GL_TEXTURE_2D, textureID);
|
||||
}
|
||||
|
||||
ITexture addTexture(Image img) {
|
||||
//todo: do the actual texture stuff
|
||||
//this.img = img;
|
||||
var texture = new Texture(
|
||||
new Recti(new Vec2i(0, 0), img.getSize()),
|
||||
var texture = new Texture(new Recti(new Vec2i(0, 0), img.getSize()),
|
||||
img
|
||||
);
|
||||
textures.add(texture);
|
||||
|
@ -49,23 +44,25 @@ class TextureAtlas {
|
|||
return texture;
|
||||
}
|
||||
|
||||
public void bind() {
|
||||
glBindTexture(GL_TEXTURE_2D, textureID);
|
||||
}
|
||||
|
||||
void doubleAtlasSize() {
|
||||
img = new Image(Vec2i.mul(img.getSize(), 2));
|
||||
System.out.printf(
|
||||
"Resized atlas to %dx%d\n",
|
||||
System.out.printf("Resized atlas to %dx%d\n",
|
||||
img.getSize().getX(),
|
||||
img.getSize().getY()
|
||||
);
|
||||
atlasTexture = new Texture(new Recti(Vec2i.ZERO, img.getSize()), img);
|
||||
}
|
||||
|
||||
public void update() {
|
||||
if(shouldUpdate) {
|
||||
repack();
|
||||
updateImage();
|
||||
uploadToGpu();
|
||||
shouldUpdate = false;
|
||||
public Texture getAtlasTexture() {
|
||||
return atlasTexture;
|
||||
}
|
||||
|
||||
public Vec2i getSize() {
|
||||
return img.getSize();
|
||||
}
|
||||
|
||||
void repack() {
|
||||
|
@ -108,6 +105,15 @@ class TextureAtlas {
|
|||
}
|
||||
}
|
||||
|
||||
public void update() {
|
||||
if(shouldUpdate) {
|
||||
repack();
|
||||
updateImage();
|
||||
uploadToGpu();
|
||||
shouldUpdate = false;
|
||||
}
|
||||
}
|
||||
|
||||
void updateImage() {
|
||||
for(var tex : textures) {
|
||||
img.drawImage(tex.getImg(), tex.getTexArea().getPos());
|
||||
|
@ -131,14 +137,6 @@ class TextureAtlas {
|
|||
);
|
||||
}
|
||||
|
||||
public Texture getAtlasTexture() {
|
||||
return atlasTexture;
|
||||
}
|
||||
|
||||
public Vec2i getSize() {
|
||||
return img.getSize();
|
||||
}
|
||||
|
||||
private static class TextureHeightComparator implements Comparator<Texture> {
|
||||
@Override
|
||||
public int compare(Texture o1, Texture o2) {
|
||||
|
|
|
@ -18,18 +18,7 @@ import static org.lwjgl.opengl.GL46.*;
|
|||
import static org.lwjgl.system.MemoryUtil.NULL;
|
||||
|
||||
public class Window extends BaseWindow {
|
||||
private static String vertexSource = """
|
||||
#version 450
|
||||
layout(location = 0) in vec2 pos;
|
||||
layout(location = 1) in ivec2 texCoord;
|
||||
layout(location = 2) uniform vec2 windowSize;
|
||||
layout(location = 1) out vec2 out_texCoord;
|
||||
void main() {
|
||||
gl_Position = vec4(pos / windowSize * vec2(2.0f, -2.0f) + vec2(-1.0f, 1.0f), 0.0f, 1.0f);
|
||||
out_texCoord = texCoord;
|
||||
}
|
||||
""";
|
||||
private static String fragmentSource = """
|
||||
private static final String fragmentSource = """
|
||||
#version 450
|
||||
layout(location = 1) in vec2 texCoord;
|
||||
layout(binding = 0) uniform sampler2D tex;
|
||||
|
@ -47,18 +36,7 @@ public class Window extends BaseWindow {
|
|||
}
|
||||
}
|
||||
""";
|
||||
private static String vertexSource3D = """
|
||||
#version 450
|
||||
layout(location = 0) in vec3 pos;
|
||||
//layout(location = 1) in ivec2 texCoord;
|
||||
layout(location = 2) uniform mat4 projection;
|
||||
layout(location = 1) out vec2 out_texCoord;
|
||||
void main() {
|
||||
gl_Position = projection * vec4(pos, 1.0f);
|
||||
out_texCoord.x = pos.z;
|
||||
}
|
||||
""";
|
||||
private static String fragmentSource3D = """
|
||||
private static final String fragmentSource3D = """
|
||||
#version 450
|
||||
layout(location = 1) in vec2 texCoord;
|
||||
//layout(binding = 0) uniform sampler2D tex;
|
||||
|
@ -69,18 +47,7 @@ public class Window extends BaseWindow {
|
|||
color = vec4(1.0, texCoord.x / 2, 1.0, 1.0);
|
||||
}
|
||||
""";
|
||||
private static String vertexSourceScaler = """
|
||||
#version 450
|
||||
layout(location = 0) in vec2 pos;
|
||||
layout(location = 1) in vec2 texCoord;
|
||||
layout(location = 2) uniform vec2 windowSize;
|
||||
layout(location = 1) out vec2 out_texCoord;
|
||||
void main() {
|
||||
gl_Position = vec4(pos / windowSize * vec2(2.0f, 2.0f) + vec2(-1.0f, -1.0f), 0.0f, 1.0f);
|
||||
out_texCoord = texCoord;
|
||||
}
|
||||
""";
|
||||
private static String fragmentSourceScaler = """
|
||||
private static final String fragmentSourceScaler = """
|
||||
#version 450
|
||||
layout(location = 1) in vec2 texCoord;
|
||||
layout(binding = 0) uniform sampler2D tex;
|
||||
|
@ -96,22 +63,55 @@ public class Window extends BaseWindow {
|
|||
//color = vec4(texCoord.xy, 0.0, 1.0);
|
||||
}
|
||||
""";
|
||||
private static final String vertexSource = """
|
||||
#version 450
|
||||
layout(location = 0) in vec2 pos;
|
||||
layout(location = 1) in ivec2 texCoord;
|
||||
layout(location = 2) uniform vec2 windowSize;
|
||||
layout(location = 1) out vec2 out_texCoord;
|
||||
void main() {
|
||||
gl_Position = vec4(pos / windowSize * vec2(2.0f, -2.0f) + vec2(-1.0f, 1.0f), 0.0f, 1.0f);
|
||||
out_texCoord = texCoord;
|
||||
}
|
||||
""";
|
||||
private static final String vertexSource3D = """
|
||||
#version 450
|
||||
layout(location = 0) in vec3 pos;
|
||||
//layout(location = 1) in ivec2 texCoord;
|
||||
layout(location = 2) uniform mat4 projection;
|
||||
layout(location = 1) out vec2 out_texCoord;
|
||||
void main() {
|
||||
gl_Position = projection * vec4(pos, 1.0f);
|
||||
out_texCoord.x = pos.z;
|
||||
}
|
||||
""";
|
||||
private static final String vertexSourceScaler = """
|
||||
#version 450
|
||||
layout(location = 0) in vec2 pos;
|
||||
layout(location = 1) in vec2 texCoord;
|
||||
layout(location = 2) uniform vec2 windowSize;
|
||||
layout(location = 1) out vec2 out_texCoord;
|
||||
void main() {
|
||||
gl_Position = vec4(pos / windowSize * vec2(2.0f, 2.0f) + vec2(-1.0f, -1.0f), 0.0f, 1.0f);
|
||||
out_texCoord = texCoord;
|
||||
}
|
||||
""";
|
||||
private final int framebuffer;
|
||||
private final int framebufferTex;
|
||||
private final Program program;
|
||||
private final Program program3D;
|
||||
private final Program programScaler;
|
||||
private final RenderContext renderContext;
|
||||
private final RenderContext3D renderContext3D;
|
||||
private final Vec2i size;
|
||||
private Vec2i windowSize;
|
||||
private final TextureAtlas textureAtlas;
|
||||
private final long window;
|
||||
private boolean debug;
|
||||
private final Mat4f projection;
|
||||
private boolean shouldClose;
|
||||
private final int framebuffer;
|
||||
private final int framebufferTex;
|
||||
private boolean[] stateMouseClicked;
|
||||
private boolean[] stateMouseDown;
|
||||
private Mat4f projection;
|
||||
private final boolean[] stateMouseClicked;
|
||||
private final boolean[] stateMouseDown;
|
||||
private Vec2i windowSize;
|
||||
|
||||
public Window(Vec2i size, String title, Engine engine) {
|
||||
super(engine);
|
||||
|
@ -201,26 +201,53 @@ public class Window extends BaseWindow {
|
|||
System.out.println(GL11.glGetInteger(GL_MAX_TEXTURE_SIZE));
|
||||
}
|
||||
|
||||
private void mouseButtonCallback(
|
||||
long window, int button, int action, int mods
|
||||
) {
|
||||
switch(action) {
|
||||
case GLFW_PRESS -> {
|
||||
this.stateMouseClicked[button] = true;
|
||||
this.stateMouseDown[button] = true;
|
||||
@Override
|
||||
public Vec2i getMousePos() {
|
||||
//todo: scale mouse to stretchMode
|
||||
double[] x = {0.0};
|
||||
double[] y = {0.0};
|
||||
glfwGetCursorPos(window, x, y);
|
||||
var mousePos = new Vec2i((int) x[0], (int) y[0]);
|
||||
|
||||
var scaledMousePos = switch(this.stretchMode) {
|
||||
case STRETCH -> {
|
||||
var stretch = Vec2f.div(this.size, this.windowSize);
|
||||
yield Vec2i.mul(stretch, mousePos);
|
||||
}
|
||||
case GLFW_RELEASE -> {
|
||||
this.stateMouseDown[button] = false;
|
||||
case ASPECT -> {
|
||||
var scale = Vec2f.div(this.size, this.windowSize);
|
||||
var scalef = Math.max(scale.getX(), scale.getY());
|
||||
|
||||
var off = Vec2f.div(Vec2i.sub(windowSize,
|
||||
Vec2f.mul(size.toVec2f(), 1.0 / scalef).toVec2i()
|
||||
).toVec2f(), 2).toVec2i();
|
||||
|
||||
yield Vec2i.mul(Vec2i.sub(mousePos, off), 1.0 / scalef);
|
||||
}
|
||||
case INTEGER -> {
|
||||
var scale = Vec2i.div(this.windowSize, this.size);
|
||||
var scalei = Math.max(1, Math.min(scale.getX(), scale.getY()));
|
||||
|
||||
var off = Vec2i.div(Vec2i.sub(windowSize,
|
||||
Vec2i.mul(size, scalei)
|
||||
), 2);
|
||||
|
||||
yield Vec2i.div(Vec2i.sub(mousePos, off), scalei);
|
||||
}
|
||||
};
|
||||
return Vec2i.max(Vec2i.ZERO,
|
||||
Vec2i.min(Vec2i.sub(size, new Vec2i(1, 1)), scaledMousePos)
|
||||
);
|
||||
}
|
||||
|
||||
private void windowSizeCallback(long window, int width, int height) {
|
||||
System.out.printf("new window size %d x %d\n", width, height);
|
||||
windowSize = new Vec2i(width, height);
|
||||
glViewport(0, 0, width, height);
|
||||
//glLoadIdentity();
|
||||
//glOrtho(0.0f, width, height, 0.0f, 0.0f, 1.0f);
|
||||
@Override
|
||||
public boolean isMouseClicked(int button) {
|
||||
return this.stateMouseClicked[button];
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isMouseDown(int button) {
|
||||
return this.stateMouseDown[button];
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -258,6 +285,20 @@ public class Window extends BaseWindow {
|
|||
return loadTextureArray(img, tileSize);
|
||||
}
|
||||
|
||||
private void mouseButtonCallback(
|
||||
long window, int button, int action, int mods
|
||||
) {
|
||||
switch(action) {
|
||||
case GLFW_PRESS -> {
|
||||
this.stateMouseClicked[button] = true;
|
||||
this.stateMouseDown[button] = true;
|
||||
}
|
||||
case GLFW_RELEASE -> {
|
||||
this.stateMouseDown[button] = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void renderFinish(IRenderContext context) {
|
||||
if(debug) {
|
||||
|
@ -268,6 +309,10 @@ public class Window extends BaseWindow {
|
|||
}
|
||||
}
|
||||
|
||||
public void renderFinish3D(IRenderContext3D context) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public IRenderContext renderStart() {
|
||||
program.use();
|
||||
|
@ -281,10 +326,6 @@ public class Window extends BaseWindow {
|
|||
return renderContext;
|
||||
}
|
||||
|
||||
public void renderFinish3D(IRenderContext3D context) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public IRenderContext3D renderStart3D() {
|
||||
program3D.use();
|
||||
|
@ -295,8 +336,7 @@ public class Window extends BaseWindow {
|
|||
glClearColor(0.f, 1.f, 0.f, 1.0f);
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
//glBegin(GL_TRIANGLES);
|
||||
glUniformMatrix4fv(
|
||||
program3D.getUniformLocation("projection"),
|
||||
glUniformMatrix4fv(program3D.getUniformLocation("projection"),
|
||||
true,
|
||||
projection.asFloatArray()
|
||||
);
|
||||
|
@ -391,7 +431,6 @@ public class Window extends BaseWindow {
|
|||
glfwSwapBuffers(window);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void setDebug(boolean on) {
|
||||
this.debug = on;
|
||||
|
@ -402,55 +441,6 @@ public class Window extends BaseWindow {
|
|||
return shouldClose;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Vec2i getMousePos() {
|
||||
//todo: scale mouse to stretchMode
|
||||
double[] x = {0.0};
|
||||
double[] y = {0.0};
|
||||
glfwGetCursorPos(window, x, y);
|
||||
var mousePos = new Vec2i((int) x[0], (int) y[0]);
|
||||
|
||||
var scaledMousePos = switch(this.stretchMode) {
|
||||
case STRETCH -> {
|
||||
var stretch = Vec2f.div(this.size, this.windowSize);
|
||||
yield Vec2i.mul(stretch, mousePos);
|
||||
}
|
||||
case ASPECT -> {
|
||||
var scale = Vec2f.div(this.size, this.windowSize);
|
||||
var scalef = Math.max(scale.getX(), scale.getY());
|
||||
|
||||
var off = Vec2f.div(Vec2i.sub(windowSize,
|
||||
Vec2f.mul(size.toVec2f(), 1.0 / scalef).toVec2i()
|
||||
).toVec2f(), 2).toVec2i();
|
||||
|
||||
yield Vec2i.mul(Vec2i.sub(mousePos, off), 1.0 / scalef);
|
||||
}
|
||||
case INTEGER -> {
|
||||
var scale = Vec2i.div(this.windowSize, this.size);
|
||||
var scalei = Math.max(1, Math.min(scale.getX(), scale.getY()));
|
||||
|
||||
var off = Vec2i.div(Vec2i.sub(windowSize,
|
||||
Vec2i.mul(size, scalei)
|
||||
), 2);
|
||||
|
||||
yield Vec2i.div(Vec2i.sub(mousePos, off), scalei);
|
||||
}
|
||||
};
|
||||
return Vec2i.max(Vec2i.ZERO,
|
||||
Vec2i.min(Vec2i.sub(size, new Vec2i(1, 1)), scaledMousePos)
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isMouseClicked(int button) {
|
||||
return this.stateMouseClicked[button];
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isMouseDown(int button) {
|
||||
return this.stateMouseDown[button];
|
||||
}
|
||||
|
||||
@Override
|
||||
public void tick() { //one tick per update call?
|
||||
glfwMakeContextCurrent(window);
|
||||
|
@ -462,4 +452,12 @@ public class Window extends BaseWindow {
|
|||
Arrays.fill(stateMouseClicked, false);
|
||||
glfwPollEvents();
|
||||
}
|
||||
|
||||
private void windowSizeCallback(long window, int width, int height) {
|
||||
System.out.printf("new window size %d x %d\n", width, height);
|
||||
windowSize = new Vec2i(width, height);
|
||||
glViewport(0, 0, width, height);
|
||||
//glLoadIdentity();
|
||||
//glOrtho(0.0f, width, height, 0.0f, 0.0f, 1.0f);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -33,10 +33,12 @@ abstract public class BaseRenderContext implements IRenderContext {
|
|||
int ch = buf.get(i);
|
||||
var tex = font.getTexture(ch);
|
||||
var off = font.getOffset(ch);
|
||||
drawTextureRectangle(new Recti(
|
||||
Vec2i.add(new Vec2i(x, y), off),
|
||||
tex.getSize()
|
||||
), tex, color, true);
|
||||
drawTextureRectangle(
|
||||
new Recti(Vec2i.add(new Vec2i(x, y), off), tex.getSize()),
|
||||
tex,
|
||||
color,
|
||||
true
|
||||
);
|
||||
x += font.getXAdvance(ch);
|
||||
}
|
||||
}
|
||||
|
@ -63,22 +65,18 @@ abstract public class BaseRenderContext implements IRenderContext {
|
|||
|
||||
drawTexture(pixelPos, fullFont.getTexture(0xdb), bgColor);
|
||||
if(isHalfWidth && halfFont != null) {
|
||||
drawTexture(
|
||||
pixelPos,
|
||||
drawTexture(pixelPos,
|
||||
halfFont.getTexture(terminal.getLeftHalfChar(charPos)),
|
||||
fgColor
|
||||
);
|
||||
drawTexture(
|
||||
new Vec2i(
|
||||
pixelPos.getX() + halfCharSize.getX(),
|
||||
drawTexture(new Vec2i(pixelPos.getX() + halfCharSize.getX(),
|
||||
pixelPos.getY()
|
||||
),
|
||||
halfFont.getTexture(terminal.getRightHalfChar(charPos)),
|
||||
fgColor
|
||||
);
|
||||
} else {
|
||||
drawTexture(
|
||||
pixelPos,
|
||||
drawTexture(pixelPos,
|
||||
fullFont.getTexture(terminal.getChar(charPos)),
|
||||
fgColor
|
||||
);
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
package com.danitheskunk.skunkworks.gfx;
|
||||
|
||||
import com.danitheskunk.skunkworks.Mat4f;
|
||||
|
||||
abstract public class BaseRenderContext3D implements IRenderContext3D {
|
||||
|
||||
}
|
||||
|
|
|
@ -1,18 +1,18 @@
|
|||
package com.danitheskunk.skunkworks.gfx;
|
||||
|
||||
public final class Color {
|
||||
public final static Color WHITE = new Color(255, 255, 255);
|
||||
public final static Color LIGHT_GRAY = new Color(192, 192, 192);
|
||||
public final static Color GRAY = new Color(128, 128, 128);
|
||||
public final static Color DARK_GRAY = new Color(64, 64, 64);
|
||||
public final static Color BLACK = new Color(0, 0, 0);
|
||||
public final static Color RED = new Color(255, 0, 0);
|
||||
public final static Color GREEN = new Color(0, 255, 0);
|
||||
public final static Color BLUE = new Color(0, 0, 255);
|
||||
public final static Color YELLOW = new Color(255, 255, 0);
|
||||
public final static Color MAGENTA = new Color(255, 0, 255);
|
||||
public final static Color CYAN = new Color(0, 255, 255);
|
||||
public final static Color DARK_GRAY = new Color(64, 64, 64);
|
||||
public final static Color GRAY = new Color(128, 128, 128);
|
||||
public final static Color GREEN = new Color(0, 255, 0);
|
||||
public final static Color LIGHT_GRAY = new Color(192, 192, 192);
|
||||
public final static Color MAGENTA = new Color(255, 0, 255);
|
||||
public final static Color RED = new Color(255, 0, 0);
|
||||
public final static Color TRANS_BLACK = new Color(0, 0, 0, 0);
|
||||
public final static Color WHITE = new Color(255, 255, 255);
|
||||
public final static Color YELLOW = new Color(255, 255, 0);
|
||||
private final int r, g, b, a;
|
||||
|
||||
|
||||
|
@ -30,20 +30,20 @@ public final class Color {
|
|||
this.a = a;
|
||||
}
|
||||
|
||||
public int getR() {
|
||||
return r;
|
||||
}
|
||||
|
||||
public int getG() {
|
||||
return g;
|
||||
public int getA() {
|
||||
return a;
|
||||
}
|
||||
|
||||
public int getB() {
|
||||
return b;
|
||||
}
|
||||
|
||||
public int getA() {
|
||||
return a;
|
||||
public int getG() {
|
||||
return g;
|
||||
}
|
||||
|
||||
public int getR() {
|
||||
return r;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -14,17 +14,18 @@ public interface IRenderContext {
|
|||
|
||||
void drawString(Vec2i pos, String string, IFont font, Color color);
|
||||
|
||||
void drawTerminal(Terminal terminal);
|
||||
|
||||
void drawTerminal(Terminal terminal, Vec2i pos);
|
||||
|
||||
void drawTexture(Vec2i pos, ITexture texture);
|
||||
|
||||
void drawTexture(Vec2i pos, ITexture texture, Color color);
|
||||
|
||||
void drawTextureRectangle(Recti rect, ITexture texture, boolean repeat);
|
||||
|
||||
void drawTextureRectangle(Recti rect, ITexture texture, Color color,
|
||||
boolean repeat);
|
||||
|
||||
void drawTerminal(Terminal terminal);
|
||||
|
||||
void drawTerminal(Terminal terminal, Vec2i pos);
|
||||
void drawTextureRectangle(
|
||||
Recti rect, ITexture texture, Color color, boolean repeat
|
||||
);
|
||||
//todo: drawTextureRectangleRepeat
|
||||
}
|
||||
|
|
|
@ -3,9 +3,9 @@ package com.danitheskunk.skunkworks.gfx;
|
|||
import com.danitheskunk.skunkworks.Vec2i;
|
||||
|
||||
public interface ITexture {
|
||||
int getHeight();
|
||||
|
||||
Vec2i getSize();
|
||||
|
||||
int getWidth();
|
||||
|
||||
int getHeight();
|
||||
}
|
||||
|
|
|
@ -32,41 +32,6 @@ public class Image {
|
|||
this.size = size;
|
||||
}
|
||||
|
||||
//getters
|
||||
public byte[] getData() {
|
||||
return data;
|
||||
}
|
||||
|
||||
public Vec2i getSize() {
|
||||
return size;
|
||||
}
|
||||
|
||||
public int getWidth() {
|
||||
return size.getX();
|
||||
}
|
||||
|
||||
public int getHeight() {
|
||||
return size.getY();
|
||||
}
|
||||
|
||||
public Color getPixel(Vec2i pos) {
|
||||
int i = pos.getX() * 4 + pos.getY() * 4 * size.getX();
|
||||
return new Color(
|
||||
((int) data[i]) & 0xFF,
|
||||
((int) data[i + 1]) & 0xFF,
|
||||
((int) data[i + 2]) & 0xFF,
|
||||
((int) data[i + 3]) & 0xFF
|
||||
);
|
||||
}
|
||||
|
||||
public void setPixel(Vec2i pos, Color col) {
|
||||
int i = pos.getX() * 4 + pos.getY() * 4 * size.getX();
|
||||
data[i] = (byte) (col.getR() & 0xFF);
|
||||
data[i + 1] = (byte) (col.getG() & 0xFF);
|
||||
data[i + 2] = (byte) (col.getB() & 0xFF);
|
||||
data[i + 3] = (byte) (col.getA() & 0xFF);
|
||||
}
|
||||
|
||||
public void drawImage(Image srcImage, Vec2i destPos) {
|
||||
drawImage(srcImage, destPos, new Recti(Vec2i.ZERO,
|
||||
srcImage.getSize()));
|
||||
|
@ -85,9 +50,43 @@ public class Image {
|
|||
}
|
||||
}
|
||||
|
||||
//getters
|
||||
public byte[] getData() {
|
||||
return data;
|
||||
}
|
||||
|
||||
public int getHeight() {
|
||||
return size.getY();
|
||||
}
|
||||
|
||||
public Color getPixel(Vec2i pos) {
|
||||
int i = pos.getX() * 4 + pos.getY() * 4 * size.getX();
|
||||
return new Color(((int) data[i]) & 0xFF,
|
||||
((int) data[i + 1]) & 0xFF,
|
||||
((int) data[i + 2]) & 0xFF,
|
||||
((int) data[i + 3]) & 0xFF
|
||||
);
|
||||
}
|
||||
|
||||
public Vec2i getSize() {
|
||||
return size;
|
||||
}
|
||||
|
||||
public Image getSubImage(Recti rect) {
|
||||
Image img = new Image(rect.getSize());
|
||||
img.drawImage(this, Vec2i.ZERO, rect);
|
||||
return img;
|
||||
}
|
||||
|
||||
public int getWidth() {
|
||||
return size.getX();
|
||||
}
|
||||
|
||||
public void setPixel(Vec2i pos, Color col) {
|
||||
int i = pos.getX() * 4 + pos.getY() * 4 * size.getX();
|
||||
data[i] = (byte) (col.getR() & 0xFF);
|
||||
data[i + 1] = (byte) (col.getG() & 0xFF);
|
||||
data[i + 2] = (byte) (col.getB() & 0xFF);
|
||||
data[i + 3] = (byte) (col.getA() & 0xFF);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,19 +1,21 @@
|
|||
package com.danitheskunk.skunkworks.gfx;
|
||||
|
||||
public class NineSlice {
|
||||
private ITexture topLeft;
|
||||
private ITexture topRight;
|
||||
private ITexture bottomLeft;
|
||||
private ITexture bottomRight;
|
||||
private ITexture top;
|
||||
private ITexture right;
|
||||
private ITexture bottom;
|
||||
private ITexture left;
|
||||
private ITexture center;
|
||||
private final ITexture bottom;
|
||||
private final ITexture bottomLeft;
|
||||
private final ITexture bottomRight;
|
||||
private final ITexture center;
|
||||
private final ITexture left;
|
||||
private final ITexture right;
|
||||
private final ITexture top;
|
||||
private final ITexture topLeft;
|
||||
private final ITexture topRight;
|
||||
|
||||
public NineSlice(ITexture topLeft, ITexture topRight, ITexture bottomLeft,
|
||||
public NineSlice(
|
||||
ITexture topLeft, ITexture topRight, ITexture bottomLeft,
|
||||
ITexture bottomRight, ITexture top, ITexture right, ITexture bottom,
|
||||
ITexture left, ITexture center) {
|
||||
ITexture left, ITexture center
|
||||
) {
|
||||
this.topLeft = topLeft;
|
||||
this.topRight = topRight;
|
||||
this.bottomLeft = bottomLeft;
|
||||
|
@ -25,12 +27,8 @@ public class NineSlice {
|
|||
this.center = center;
|
||||
}
|
||||
|
||||
public ITexture getTopLeft() {
|
||||
return topLeft;
|
||||
}
|
||||
|
||||
public ITexture getTopRight() {
|
||||
return topRight;
|
||||
public ITexture getBottom() {
|
||||
return bottom;
|
||||
}
|
||||
|
||||
public ITexture getBottomLeft() {
|
||||
|
@ -41,23 +39,27 @@ public class NineSlice {
|
|||
return bottomRight;
|
||||
}
|
||||
|
||||
public ITexture getTop() {
|
||||
return top;
|
||||
}
|
||||
|
||||
public ITexture getRight() {
|
||||
return right;
|
||||
}
|
||||
|
||||
public ITexture getBottom() {
|
||||
return bottom;
|
||||
public ITexture getCenter() {
|
||||
return center;
|
||||
}
|
||||
|
||||
public ITexture getLeft() {
|
||||
return left;
|
||||
}
|
||||
|
||||
public ITexture getCenter() {
|
||||
return center;
|
||||
public ITexture getRight() {
|
||||
return right;
|
||||
}
|
||||
|
||||
public ITexture getTop() {
|
||||
return top;
|
||||
}
|
||||
|
||||
public ITexture getTopLeft() {
|
||||
return topLeft;
|
||||
}
|
||||
|
||||
public ITexture getTopRight() {
|
||||
return topRight;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,48 +2,48 @@ package com.danitheskunk.skunkworks.gfx.font;
|
|||
|
||||
public class Cp437 {
|
||||
|
||||
public final static int BOX_DOUBLE_BOTTOM_LEFT = 0xBB;
|
||||
public final static int BOX_DOUBLE_BOTTOM_SINGLE_LEFT = 0xB7;
|
||||
public final static int BOX_DOUBLE_CROSS = 0xCE;
|
||||
public final static int BOX_DOUBLE_HORIZONTAL = 0xCD;
|
||||
public final static int BOX_DOUBLE_HORIZONTAL_BOTTOM = 0xCB;
|
||||
public final static int BOX_DOUBLE_HORIZONTAL_SINGLE_BOTTOM = 0xD1;
|
||||
public final static int BOX_DOUBLE_HORIZONTAL_SINGLE_TOP = 0xCF;
|
||||
public final static int BOX_DOUBLE_RIGHT_BOTTOM = 0xC9;
|
||||
public final static int BOX_DOUBLE_RIGHT_SINGLE_BOTTOM = 0xD5;
|
||||
public final static int BOX_DOUBLE_TOP_LEFT = 0xBC;
|
||||
public final static int BOX_DOUBLE_TOP_RIGHT = 0xC8;
|
||||
public final static int BOX_DOUBLE_TOP_SINGLE_LEFT = 0xBD;
|
||||
public final static int BOX_DOUBLE_TOP_SINGLE_RIGHT = 0xD3;
|
||||
public final static int BOX_DOUBLE_VERTICAL = 0xBA;
|
||||
public final static int BOX_DOUBLE_VERTICAL_LEFT = 0xB9;
|
||||
public final static int BOX_DOUBLE_VERTICAL_RIGHT = 0xCC;
|
||||
public final static int BOX_DOUBLE_VERTICAL_SINGLE_HORIZONTAL = 0xD7;
|
||||
public final static int BOX_DOUBLE_VERTICAL_SINGLE_LEFT = 0xB6;
|
||||
public final static int BOX_DOUBLE_VERTICAL_SINGLE_RIGHT = 0xC7;
|
||||
public final static int BOX_DOUBlE_HORIZONTAL_TOP = 0xCA;
|
||||
public final static int BOX_SINGLE_BOTTOM_DOUBLE_LEFT = 0xB8;
|
||||
public final static int BOX_SINGLE_BOTTOM_LEFT = 0xBF;
|
||||
public final static int BOX_SINGLE_CROSS = 0xC5;
|
||||
public final static int BOX_SINGLE_HORIZONTAL = 0xC4;
|
||||
public final static int BOX_SINGLE_HORIZONTAL_BOTTOM = 0xC2;
|
||||
public final static int BOX_SINGLE_HORIZONTAL_DOUBLE_BOTTOM = 0xD2;
|
||||
public final static int BOX_SINGLE_HORIZONTAL_DOUBLE_TOP = 0xD0;
|
||||
public final static int BOX_SINGLE_HORIZONTAL_TOP = 0xC1;
|
||||
public final static int BOX_SINGLE_RIGHT_BOTTOM = 0xDA;
|
||||
public final static int BOX_SINGLE_RIGHT_DOUBLE_BOTTOM = 0xD6;
|
||||
public final static int BOX_SINGLE_TOP_DOUBLE_LEFT = 0xBE;
|
||||
public final static int BOX_SINGLE_TOP_DOUBLE_RIGHT = 0xD4;
|
||||
public final static int BOX_SINGLE_TOP_LEFT = 0xD9;
|
||||
public final static int BOX_SINGLE_TOP_RIGHT = 0xC0;
|
||||
//box drawing names... name part priority: (SINGLE/DOUBLE modifier first,
|
||||
// only when it changes), CROSS, VERTICAL, HORIZONTAL, TOP, RIGHT, BOTTOM,
|
||||
// LEFT
|
||||
public final static int BOX_SINGLE_VERTICAL = 0xB3;
|
||||
public final static int BOX_SINGLE_VERTICAL_LEFT = 0xB4;
|
||||
public final static int BOX_SINGLE_VERTICAL_DOUBLE_LEFT = 0xB5;
|
||||
public final static int BOX_DOUBLE_VERTICAL_SINGLE_LEFT = 0xB6;
|
||||
public final static int BOX_DOUBLE_BOTTOM_SINGLE_LEFT = 0xB7;
|
||||
public final static int BOX_SINGLE_BOTTOM_DOUBLE_LEFT = 0xB8;
|
||||
public final static int BOX_DOUBLE_VERTICAL_LEFT = 0xB9;
|
||||
public final static int BOX_DOUBLE_VERTICAL = 0xBA;
|
||||
public final static int BOX_DOUBLE_BOTTOM_LEFT = 0xBB;
|
||||
public final static int BOX_DOUBLE_TOP_LEFT = 0xBC;
|
||||
public final static int BOX_DOUBLE_TOP_SINGLE_LEFT = 0xBD;
|
||||
public final static int BOX_SINGLE_TOP_DOUBLE_LEFT = 0xBE;
|
||||
public final static int BOX_SINGLE_BOTTOM_LEFT = 0xBF;
|
||||
public final static int BOX_SINGLE_TOP_RIGHT = 0xC0;
|
||||
public final static int BOX_SINGLE_HORIZONTAL_TOP = 0xC1;
|
||||
public final static int BOX_SINGLE_HORIZONTAL_BOTTOM = 0xC2;
|
||||
public final static int BOX_SINGLE_VERTICAL_RIGHT = 0xC3;
|
||||
public final static int BOX_SINGLE_HORIZONTAL = 0xC4;
|
||||
public final static int BOX_SINGLE_CROSS = 0xC5;
|
||||
public final static int BOX_SINGLE_VERTICAL_DOUBLE_RIGHT = 0xC6;
|
||||
public final static int BOX_DOUBLE_VERTICAL_SINGLE_RIGHT = 0xC7;
|
||||
public final static int BOX_DOUBLE_TOP_RIGHT = 0xC8;
|
||||
public final static int BOX_DOUBLE_RIGHT_BOTTOM = 0xC9;
|
||||
public final static int BOX_DOUBlE_HORIZONTAL_TOP = 0xCA;
|
||||
public final static int BOX_DOUBLE_HORIZONTAL_BOTTOM = 0xCB;
|
||||
public final static int BOX_DOUBLE_VERTICAL_RIGHT = 0xCC;
|
||||
public final static int BOX_DOUBLE_HORIZONTAL = 0xCD;
|
||||
public final static int BOX_DOUBLE_CROSS = 0xCE;
|
||||
public final static int BOX_DOUBLE_HORIZONTAL_SINGLE_TOP = 0xCF;
|
||||
public final static int BOX_SINGLE_HORIZONTAL_DOUBLE_TOP = 0xD0;
|
||||
public final static int BOX_DOUBLE_HORIZONTAL_SINGLE_BOTTOM = 0xD1;
|
||||
public final static int BOX_SINGLE_HORIZONTAL_DOUBLE_BOTTOM = 0xD2;
|
||||
public final static int BOX_DOUBLE_TOP_SINGLE_RIGHT = 0xD3;
|
||||
public final static int BOX_SINGLE_TOP_DOUBLE_RIGHT = 0xD4;
|
||||
public final static int BOX_DOUBLE_RIGHT_SINGLE_BOTTOM = 0xD5;
|
||||
public final static int BOX_SINGLE_RIGHT_DOUBLE_BOTTOM = 0xD6;
|
||||
public final static int BOX_DOUBLE_VERTICAL_SINGLE_HORIZONTAL = 0xD7;
|
||||
public final static int BOX_SINGLE_VERTICAL_DOUBLE_HORIZONTAL = 0xD8;
|
||||
public final static int BOX_SINGLE_TOP_LEFT = 0xD9;
|
||||
public final static int BOX_SINGLE_RIGHT_BOTTOM = 0xDA;
|
||||
public final static int BOX_SINGLE_VERTICAL_DOUBLE_LEFT = 0xB5;
|
||||
public final static int BOX_SINGLE_VERTICAL_DOUBLE_RIGHT = 0xC6;
|
||||
public final static int BOX_SINGLE_VERTICAL_LEFT = 0xB4;
|
||||
public final static int BOX_SINGLE_VERTICAL_RIGHT = 0xC3;
|
||||
|
||||
}
|
||||
|
|
|
@ -13,10 +13,10 @@ import static org.lwjgl.stb.STBTruetype.*;
|
|||
|
||||
public class FontTTF implements IFont {
|
||||
HashMap<Integer, Char> chars;
|
||||
STBTTFontinfo info;
|
||||
int lineHeight;
|
||||
float size;
|
||||
float unscaled_size;
|
||||
STBTTFontinfo info;
|
||||
IWindow window;
|
||||
|
||||
public FontTTF(ByteBuffer buffer, float size, IWindow window) {
|
||||
|
@ -39,9 +39,10 @@ public class FontTTF implements IFont {
|
|||
this.size = stbtt_ScaleForPixelHeight(info, size);
|
||||
|
||||
//precache ascii characters
|
||||
for(int i = 32; i < 128; ++i)
|
||||
for(int i = 32; i < 128; ++i) {
|
||||
cacheChar(i);
|
||||
}
|
||||
}
|
||||
|
||||
void cacheChar(int ch) {
|
||||
if(chars.containsKey(ch)) return;
|
||||
|
@ -54,8 +55,7 @@ public class FontTTF implements IFont {
|
|||
int[] leftSideBearing = {0};
|
||||
ITexture tex;
|
||||
|
||||
var bufmono = stbtt_GetCodepointBitmap(
|
||||
info,
|
||||
var bufmono = stbtt_GetCodepointBitmap(info,
|
||||
size,
|
||||
size,
|
||||
ch,
|
||||
|
@ -74,22 +74,43 @@ public class FontTTF implements IFont {
|
|||
buf.put(b);
|
||||
}
|
||||
buf.flip();
|
||||
tex = window.loadTexture(new Image(
|
||||
buf,
|
||||
tex = window.loadTexture(new Image(buf,
|
||||
new Vec2i(width[0], height[0])
|
||||
));
|
||||
} else {
|
||||
tex = window.loadTexture(new Image(Vec2i.ZERO));
|
||||
}
|
||||
stbtt_GetCodepointHMetrics(info, ch, advanceWidth, leftSideBearing);
|
||||
var c = new Char(
|
||||
tex,
|
||||
var c = new Char(tex,
|
||||
(int) (advanceWidth[0] * size),
|
||||
new Vec2i(xoff[0], yoff[0])
|
||||
);
|
||||
chars.put(ch, c);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getLineHeight(int ch) {
|
||||
cacheChar(ch);
|
||||
return lineHeight;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Vec2i getMonospaceSize() {
|
||||
throw new RuntimeException("Not a monospace font");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Vec2i getOffset(int ch) {
|
||||
cacheChar(ch);
|
||||
return chars.get(ch).off;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ITexture getTexture(int ch) {
|
||||
cacheChar(ch);
|
||||
return chars.get(ch).tex;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getXAdvance(int ch) {
|
||||
cacheChar(ch);
|
||||
|
@ -106,33 +127,10 @@ public class FontTTF implements IFont {
|
|||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Vec2i getMonospaceSize() {
|
||||
throw new RuntimeException("Not a monospace font");
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getLineHeight(int ch) {
|
||||
cacheChar(ch);
|
||||
return lineHeight;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Vec2i getOffset(int ch) {
|
||||
cacheChar(ch);
|
||||
return chars.get(ch).off;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ITexture getTexture(int ch) {
|
||||
cacheChar(ch);
|
||||
return chars.get(ch).tex;
|
||||
}
|
||||
|
||||
private class Char {
|
||||
ITexture tex;
|
||||
int advance;
|
||||
Vec2i off;
|
||||
ITexture tex;
|
||||
|
||||
Char(ITexture tex, int advance, Vec2i off) {
|
||||
this.tex = tex;
|
||||
|
|
|
@ -6,14 +6,37 @@ import com.danitheskunk.skunkworks.gfx.ITexture;
|
|||
import java.util.List;
|
||||
|
||||
public class FontTileset implements IFont {
|
||||
private List<ITexture> textures;
|
||||
private Vec2i charSize;
|
||||
private final Vec2i charSize;
|
||||
private final List<ITexture> textures;
|
||||
|
||||
public FontTileset(List<ITexture> textures) {
|
||||
this.textures = textures;
|
||||
this.charSize = textures.get(0).getSize();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getLineHeight(int ch) {
|
||||
return charSize.getY();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Vec2i getMonospaceSize() {
|
||||
return charSize;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Vec2i getOffset(int ch) {
|
||||
return Vec2i.ZERO;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ITexture getTexture(int ch) {
|
||||
if(ch >= 256 || ch < 0) {
|
||||
ch = 0;
|
||||
}
|
||||
return textures.get(ch);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getXAdvance(int ch) {
|
||||
return charSize.getX();
|
||||
|
@ -28,27 +51,4 @@ public class FontTileset implements IFont {
|
|||
public boolean isMonospace() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Vec2i getMonospaceSize() {
|
||||
return charSize;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getLineHeight(int ch) {
|
||||
return charSize.getY();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Vec2i getOffset(int ch) {
|
||||
return Vec2i.ZERO;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ITexture getTexture(int ch) {
|
||||
if(ch >= 256 || ch < 0) {
|
||||
ch = 0;
|
||||
}
|
||||
return textures.get(ch);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,6 +6,8 @@ import com.danitheskunk.skunkworks.gfx.ITexture;
|
|||
public interface IFont {
|
||||
int getLineHeight(int ch);
|
||||
|
||||
Vec2i getMonospaceSize();
|
||||
|
||||
Vec2i getOffset(int ch);
|
||||
|
||||
ITexture getTexture(int ch);
|
||||
|
@ -15,6 +17,4 @@ public interface IFont {
|
|||
boolean isCP437();
|
||||
|
||||
boolean isMonospace();
|
||||
|
||||
Vec2i getMonospaceSize();
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,9 +1,9 @@
|
|||
package com.danitheskunk.skunkworks.nodes;
|
||||
|
||||
public abstract class BaseTween {
|
||||
protected int endFrame;
|
||||
protected double progress;
|
||||
protected int startFrame;
|
||||
protected int endFrame;
|
||||
protected Runnable thenFunc;
|
||||
|
||||
public BaseTween() {
|
||||
|
@ -11,9 +11,7 @@ public abstract class BaseTween {
|
|||
thenFunc = null;
|
||||
}
|
||||
|
||||
public void setProgress(double progress) {
|
||||
this.progress = progress;
|
||||
}
|
||||
protected abstract void apply();
|
||||
|
||||
public BaseTween delay(int frames) {
|
||||
startFrame += frames;
|
||||
|
@ -21,10 +19,12 @@ public abstract class BaseTween {
|
|||
return this;
|
||||
}
|
||||
|
||||
public void setProgress(double progress) {
|
||||
this.progress = progress;
|
||||
}
|
||||
|
||||
public BaseTween then(Runnable func) {
|
||||
thenFunc = func;
|
||||
return this;
|
||||
}
|
||||
|
||||
protected abstract void apply();
|
||||
}
|
||||
|
|
|
@ -20,18 +20,6 @@ public class Node implements Iterable<Node> {
|
|||
pos = Vec2f.ZERO;
|
||||
}
|
||||
|
||||
public Node getParent() {
|
||||
return parent;
|
||||
}
|
||||
|
||||
public Vec2f getPos() {
|
||||
return pos;
|
||||
}
|
||||
|
||||
public void setPos(Vec2f pos) {
|
||||
this.pos = pos;
|
||||
}
|
||||
|
||||
public void add(Node node) {
|
||||
if(node.parent != null) {
|
||||
throw new RuntimeException("Can't add node to two nodes");
|
||||
|
@ -40,22 +28,23 @@ public class Node implements Iterable<Node> {
|
|||
children.add(node);
|
||||
}
|
||||
|
||||
public void remove(Node node) {
|
||||
node.parent = null;
|
||||
children.remove(node);
|
||||
}
|
||||
|
||||
public void render(IRenderContext rc) {
|
||||
for(var child : this) {
|
||||
child.render(rc);
|
||||
}
|
||||
}
|
||||
|
||||
public Vec2f getAbsolutePos() {
|
||||
if(parent == null) return pos;
|
||||
return Vec2f.add(parent.getAbsolutePos(), pos);
|
||||
}
|
||||
|
||||
public int getCurrentFrame() {
|
||||
return getRoot().getCurrentFrame();
|
||||
}
|
||||
|
||||
public Node getParent() {
|
||||
return parent;
|
||||
}
|
||||
|
||||
public Vec2f getPos() {
|
||||
return pos;
|
||||
}
|
||||
|
||||
public NodeRoot getRoot() {
|
||||
var node = this;
|
||||
while(node.parent != null) {
|
||||
|
@ -70,16 +59,27 @@ public class Node implements Iterable<Node> {
|
|||
return children.iterator();
|
||||
}
|
||||
|
||||
public int getCurrentFrame() {
|
||||
return getRoot().getCurrentFrame();
|
||||
}
|
||||
|
||||
protected void prepareTween(BaseTween tween, int frames) {
|
||||
var root = getRoot();
|
||||
tween.startFrame = root.getCurrentFrame();
|
||||
tween.endFrame = tween.startFrame + frames;
|
||||
}
|
||||
|
||||
public void remove(Node node) {
|
||||
node.parent = null;
|
||||
children.remove(node);
|
||||
}
|
||||
|
||||
public void render(IRenderContext rc) {
|
||||
for(var child : this) {
|
||||
child.render(rc);
|
||||
}
|
||||
}
|
||||
|
||||
public void setPos(Vec2f pos) {
|
||||
this.pos = pos;
|
||||
}
|
||||
|
||||
public TweenPos tweenPos(Vec2f to, int frames) {
|
||||
var tween = new TweenPos();
|
||||
tween.start = pos;
|
||||
|
@ -91,8 +91,8 @@ public class Node implements Iterable<Node> {
|
|||
|
||||
|
||||
public class TweenPos extends BaseTween {
|
||||
private Vec2f start;
|
||||
private Vec2f end;
|
||||
private Vec2f start;
|
||||
|
||||
@Override
|
||||
protected void apply() {
|
||||
|
|
|
@ -1,10 +1,9 @@
|
|||
package com.danitheskunk.skunkworks.nodes;
|
||||
|
||||
import com.danitheskunk.skunkworks.Timestep;
|
||||
import com.danitheskunk.skunkworks.Vec2f;
|
||||
|
||||
public class NodeRoot extends Node {
|
||||
private Tweener tweener;
|
||||
private final Tweener tweener;
|
||||
|
||||
public NodeRoot() {
|
||||
tweener = new Tweener(Timestep.FIXED);
|
||||
|
@ -15,11 +14,11 @@ public class NodeRoot extends Node {
|
|||
return tweener.getCurrentFrame();
|
||||
}
|
||||
|
||||
public void tick() {
|
||||
tweener.tick();
|
||||
}
|
||||
|
||||
public Tweener getTweener() {
|
||||
return tweener;
|
||||
}
|
||||
|
||||
public void tick() {
|
||||
tweener.tick();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,12 +15,12 @@ public class NodeSprite extends Node {
|
|||
return texture;
|
||||
}
|
||||
|
||||
public void setTexture(ITexture texture) {
|
||||
this.texture = texture;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void render(IRenderContext rc) {
|
||||
rc.drawTexture(getAbsolutePos().toVec2i(), texture);
|
||||
}
|
||||
|
||||
public void setTexture(ITexture texture) {
|
||||
this.texture = texture;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,9 +6,9 @@ import java.util.ArrayList;
|
|||
import java.util.List;
|
||||
|
||||
public class Tweener {
|
||||
private Timestep timestepMode;
|
||||
private List<BaseTween> tweens;
|
||||
private int currentFrame;
|
||||
private final Timestep timestepMode;
|
||||
private final List<BaseTween> tweens;
|
||||
|
||||
public Tweener(Timestep timestepMode) {
|
||||
this.timestepMode = timestepMode;
|
||||
|
@ -16,6 +16,10 @@ public class Tweener {
|
|||
this.currentFrame = 0;
|
||||
}
|
||||
|
||||
public void add(BaseTween tween) {
|
||||
tweens.add(tween);
|
||||
}
|
||||
|
||||
public int getCurrentFrame() {
|
||||
return currentFrame;
|
||||
}
|
||||
|
@ -43,8 +47,4 @@ public class Tweener {
|
|||
}
|
||||
++currentFrame;
|
||||
}
|
||||
|
||||
public void add(BaseTween tween) {
|
||||
tweens.add(tween);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,45 +8,44 @@ import com.sun.jna.platform.win32.WinNT;
|
|||
import com.sun.jna.win32.W32APIOptions;
|
||||
|
||||
public interface Dwm extends Library {
|
||||
Dwm INSTANCE = Native.load(
|
||||
"dwmapi",
|
||||
WinDef.DWORD DWMWA_ALLOW_NCPAINT = new WinDef.DWORD(4);
|
||||
WinDef.DWORD DWMWA_CAPTION_BUTTON_BOUNDS = new WinDef.DWORD(5);
|
||||
WinDef.DWORD DWMWA_CLOAK = new WinDef.DWORD(13);
|
||||
WinDef.DWORD DWMWA_CLOAKED = new WinDef.DWORD(14);
|
||||
WinDef.DWORD DWMWA_DISALLOW_PEEK = new WinDef.DWORD(11);
|
||||
WinDef.DWORD DWMWA_EXCLUDED_FROM_PEEK = new WinDef.DWORD(12);
|
||||
WinDef.DWORD DWMWA_EXTENDED_FRAME_BOUNDS = new WinDef.DWORD(9);
|
||||
WinDef.DWORD DWMWA_FLIP3D_POLICY = new WinDef.DWORD(8);
|
||||
WinDef.DWORD DWMWA_FORCE_ICONIC_REPRESENTATION = new WinDef.DWORD(7);
|
||||
WinDef.DWORD DWMWA_FREEZE_REPRESENTATION = new WinDef.DWORD(15);
|
||||
WinDef.DWORD DWMWA_HAS_ICONIC_BITMAP = new WinDef.DWORD(10);
|
||||
WinDef.DWORD DWMWA_LAST = new WinDef.DWORD(16);
|
||||
WinDef.DWORD DWMWA_NCRENDERING_ENABLED = new WinDef.DWORD(1);
|
||||
WinDef.DWORD DWMWA_NCRENDERING_POLICY = new WinDef.DWORD(2);
|
||||
WinDef.DWORD DWMWA_NONCLIENT_RTL_LAYOUT = new WinDef.DWORD(6);
|
||||
WinDef.DWORD DWMWA_TRANSITIONS_FORCEDISABLED = new WinDef.DWORD(3);
|
||||
WinDef.DWORD DWMWA_WINDOW_CORNER_PREFERENCE = new WinDef.DWORD(33);
|
||||
WinDef.DWORD DWMWCP_DEFAULT = new WinDef.DWORD(0);
|
||||
//todo: fix/complete DWMWA list
|
||||
WinDef.DWORD DWMWCP_DONOTROUND = new WinDef.DWORD(1);
|
||||
WinDef.DWORD DWMWCP_ROUND = new WinDef.DWORD(2);
|
||||
WinDef.DWORD DWMWCP_ROUNDSMALL = new WinDef.DWORD(3);
|
||||
Dwm INSTANCE = Native.load("dwmapi",
|
||||
Dwm.class,
|
||||
W32APIOptions.DEFAULT_OPTIONS
|
||||
);
|
||||
|
||||
WinNT.HRESULT DwmExtendFrameIntoClientArea(
|
||||
WinDef.HWND hwnd, MARGINS pMarInset
|
||||
);
|
||||
|
||||
WinDef.DWORD DWMWA_NCRENDERING_ENABLED = new WinDef.DWORD(1);
|
||||
WinDef.DWORD DWMWA_NCRENDERING_POLICY = new WinDef.DWORD(2);
|
||||
WinDef.DWORD DWMWA_TRANSITIONS_FORCEDISABLED = new WinDef.DWORD(3);
|
||||
WinDef.DWORD DWMWA_ALLOW_NCPAINT = new WinDef.DWORD(4);
|
||||
WinDef.DWORD DWMWA_CAPTION_BUTTON_BOUNDS = new WinDef.DWORD(5);
|
||||
WinDef.DWORD DWMWA_NONCLIENT_RTL_LAYOUT = new WinDef.DWORD(6);
|
||||
WinDef.DWORD DWMWA_FORCE_ICONIC_REPRESENTATION = new WinDef.DWORD(7);
|
||||
WinDef.DWORD DWMWA_FLIP3D_POLICY = new WinDef.DWORD(8);
|
||||
WinDef.DWORD DWMWA_EXTENDED_FRAME_BOUNDS = new WinDef.DWORD(9);
|
||||
WinDef.DWORD DWMWA_HAS_ICONIC_BITMAP = new WinDef.DWORD(10);
|
||||
WinDef.DWORD DWMWA_DISALLOW_PEEK = new WinDef.DWORD(11);
|
||||
WinDef.DWORD DWMWA_EXCLUDED_FROM_PEEK = new WinDef.DWORD(12);
|
||||
WinDef.DWORD DWMWA_CLOAK = new WinDef.DWORD(13);
|
||||
WinDef.DWORD DWMWA_CLOAKED = new WinDef.DWORD(14);
|
||||
WinDef.DWORD DWMWA_FREEZE_REPRESENTATION = new WinDef.DWORD(15);
|
||||
WinDef.DWORD DWMWA_LAST = new WinDef.DWORD(16);
|
||||
WinDef.DWORD DWMWA_WINDOW_CORNER_PREFERENCE = new WinDef.DWORD(33);
|
||||
//todo: fix/complete DWMWA list
|
||||
WinNT.HRESULT DwmGetWindowAttribute(
|
||||
WinDef.HWND hwnd, WinDef.DWORD dwAttribute, Pointer pvAttribute,
|
||||
WinDef.DWORD cbAttribute
|
||||
);
|
||||
|
||||
WinDef.DWORD DWMWCP_DEFAULT = new WinDef.DWORD(0);
|
||||
WinDef.DWORD DWMWCP_DONOTROUND = new WinDef.DWORD(1);
|
||||
WinDef.DWORD DWMWCP_ROUND = new WinDef.DWORD(2);
|
||||
WinDef.DWORD DWMWCP_ROUNDSMALL = new WinDef.DWORD(3);
|
||||
|
||||
WinNT.HRESULT DwmExtendFrameIntoClientArea(WinDef.HWND hwnd,
|
||||
MARGINS pMarInset);
|
||||
|
||||
WinNT.HRESULT DwmGetWindowAttribute(WinDef.HWND hwnd,
|
||||
WinDef.DWORD dwAttribute, Pointer pvAttribute,
|
||||
WinDef.DWORD cbAttribute);
|
||||
|
||||
WinNT.HRESULT DwmSetWindowAttribute(WinDef.HWND hwnd,
|
||||
WinDef.DWORD dwAttribute, Pointer pvAttribute,
|
||||
WinDef.DWORD cbAttribute);
|
||||
WinNT.HRESULT DwmSetWindowAttribute(
|
||||
WinDef.HWND hwnd, WinDef.DWORD dwAttribute, Pointer pvAttribute,
|
||||
WinDef.DWORD cbAttribute
|
||||
);
|
||||
}
|
||||
|
|
|
@ -9,13 +9,12 @@ public class MARGINS extends Structure implements Structure.ByReference {
|
|||
|
||||
public int cxLeftWidth;
|
||||
public int cxRightWidth;
|
||||
public int cyTopHeight;
|
||||
public int cyBottomHeight;
|
||||
public int cyTopHeight;
|
||||
|
||||
@Override
|
||||
protected List<String> getFieldOrder() {
|
||||
return Arrays.asList(
|
||||
"cxLeftWidth",
|
||||
return Arrays.asList("cxLeftWidth",
|
||||
"cxRightWidth",
|
||||
"cyTopHeight",
|
||||
"cyBottomHeight"
|
||||
|
|
|
@ -5,15 +5,15 @@ import com.sun.jna.platform.win32.WinDef;
|
|||
|
||||
@Structure.FieldOrder({"cbSize", "rcTitleBar", "rgstate"})
|
||||
public class TITLEBARINFO extends Structure {
|
||||
// Index constants
|
||||
public static final int TITLE_BAR = 0;
|
||||
public static final int RESERVED = 1;
|
||||
public static final int MINIMIZE_BUTTON = 2;
|
||||
public static final int MAXIMIZE_BUTTON = 3;
|
||||
public static final int HELP_BUTTON = 4;
|
||||
public static final int CLOSE_BUTTON = 5;
|
||||
// Child amount constant
|
||||
public static final int CCHILDREN_TITLEBAR = 5;
|
||||
public static final int CLOSE_BUTTON = 5;
|
||||
public static final int HELP_BUTTON = 4;
|
||||
public static final int MAXIMIZE_BUTTON = 3;
|
||||
public static final int MINIMIZE_BUTTON = 2;
|
||||
public static final int RESERVED = 1;
|
||||
// Index constants
|
||||
public static final int TITLE_BAR = 0;
|
||||
public int cbSize;
|
||||
public WinDef.RECT rcTitleBar;
|
||||
public int[] rgstate;
|
||||
|
|
|
@ -6,19 +6,26 @@ import com.sun.jna.platform.win32.WinDef;
|
|||
import com.sun.jna.win32.W32APIOptions;
|
||||
|
||||
public interface User32Extra extends User32 {
|
||||
User32Extra INSTANCE = Native.load(
|
||||
"user32",
|
||||
int HSHELL_WINDOWCREATED = 1;
|
||||
User32Extra INSTANCE = Native.load("user32",
|
||||
User32Extra.class,
|
||||
W32APIOptions.DEFAULT_OPTIONS
|
||||
);
|
||||
|
||||
int PM_NOREMOVE = 0x00;
|
||||
int PM_NOYIELD = 0x02;
|
||||
int PM_REMOVE = 0x01;
|
||||
// States
|
||||
int STATE_SYSTEM_FOCUSABLE = 0x00100000;
|
||||
int STATE_SYSTEM_INVISIBLE = 0x00008000;
|
||||
int STATE_SYSTEM_OFFSCREEN = 0x00010000;
|
||||
int STATE_SYSTEM_UNAVAILABLE = 0x00000001;
|
||||
int STATE_SYSTEM_PRESSED = 0x00000008;
|
||||
|
||||
int STATE_SYSTEM_UNAVAILABLE = 0x00000001;
|
||||
// https://docs.microsoft.com/en-us/windows/desktop/inputdev/virtual-key-codes
|
||||
int VK_LBUTTON = 0x01;
|
||||
int VK_MBUTTON = 0x04;
|
||||
int VK_RBUTTON = 0x02;
|
||||
int WH_SHELL = 10;
|
||||
int WM_TIMER = 0x0113;
|
||||
// Extended Styles
|
||||
// https://docs.microsoft.com/en-gb/windows/desktop/winmsg/extended-window-styles
|
||||
int WS_EX_ACCEPTFILES = 0x00000010;
|
||||
|
@ -46,40 +53,23 @@ public interface User32Extra extends User32 {
|
|||
int WS_EX_TOPMOST = 0x00000008;
|
||||
int WS_EX_TRANSPARENT = 0x00000020;
|
||||
int WS_EX_WINDOWEDGE = 0x00000100;
|
||||
|
||||
long WS_EX_OVERLAPPEDWINDOW = (WS_EX_WINDOWEDGE | WS_EX_CLIENTEDGE);
|
||||
long WS_EX_PALETTEWINDOW = (
|
||||
WS_EX_WINDOWEDGE |
|
||||
WS_EX_TOOLWINDOW |
|
||||
WS_EX_TOPMOST
|
||||
WS_EX_WINDOWEDGE | WS_EX_TOOLWINDOW | WS_EX_TOPMOST
|
||||
);
|
||||
|
||||
int WH_SHELL = 10;
|
||||
|
||||
int WM_TIMER = 0x0113;
|
||||
|
||||
int HSHELL_WINDOWCREATED = 1;
|
||||
// https://docs.microsoft.com/en-us/windows/desktop/inputdev/virtual-key-codes
|
||||
int VK_LBUTTON = 0x01;
|
||||
int VK_RBUTTON = 0x02;
|
||||
int VK_MBUTTON = 0x04;
|
||||
|
||||
int PM_NOREMOVE = 0x00;
|
||||
int PM_REMOVE = 0x01;
|
||||
int PM_NOYIELD = 0x02;
|
||||
|
||||
// https://docs.microsoft.com/en-us/windows/desktop/api/winuser/nf-winuser-gettitlebarinfo
|
||||
boolean GetTitleBarInfo(WinDef.HWND hwnd, TITLEBARINFO titlebarinfo);
|
||||
HCURSOR GetCursor();
|
||||
|
||||
// https://docs.microsoft.com/en-us/windows/desktop/api/winuser/nf-winuser-getlastactivepopup
|
||||
WinDef.HWND GetLastActivePopup(WinDef.HWND hwnd);
|
||||
|
||||
// https://docs.microsoft.com/en-us/windows/desktop/api/winuser/nf-winuser-isiconic
|
||||
boolean IsIconic(WinDef.HWND hwnd);
|
||||
|
||||
HCURSOR GetCursor();
|
||||
// https://docs.microsoft.com/en-us/windows/desktop/api/winuser/nf-winuser-gettitlebarinfo
|
||||
boolean GetTitleBarInfo(WinDef.HWND hwnd, TITLEBARINFO titlebarinfo);
|
||||
|
||||
WinDef.HWND GetTopWindow(HWND hWnd);
|
||||
|
||||
WinDef.HWND GetWindow(HWND hWnd, int flag);
|
||||
|
||||
// https://docs.microsoft.com/en-us/windows/desktop/api/winuser/nf-winuser-isiconic
|
||||
boolean IsIconic(WinDef.HWND hwnd);
|
||||
}
|
||||
|
|
|
@ -6,12 +6,12 @@ import com.sun.jna.win32.W32APIOptions;
|
|||
|
||||
public interface WinUserExtra extends WinUser,
|
||||
com.sun.jna.win32.StdCallLibrary {
|
||||
WinUserExtra INSTANCE = Native.load(
|
||||
"user32",
|
||||
WinUserExtra INSTANCE = Native.load("user32",
|
||||
WinUserExtra.class,
|
||||
W32APIOptions.DEFAULT_OPTIONS
|
||||
);
|
||||
|
||||
//todo: lpTimerFunc should be TIMERPROC
|
||||
UINT_PTR SetTimer(HWND hWnd, UINT_PTR nIDEvent, UINT uElapse, PVOID lpTimerFunc);
|
||||
UINT_PTR SetTimer(HWND hWnd, UINT_PTR nIDEvent, UINT uElapse,
|
||||
PVOID lpTimerFunc);
|
||||
}
|
||||
|
|
|
@ -12,7 +12,7 @@ import java.util.ArrayList;
|
|||
import java.util.List;
|
||||
|
||||
public class Window {
|
||||
private WinDef.HWND hwnd;
|
||||
private final WinDef.HWND hwnd;
|
||||
|
||||
public Window(WinDef.HWND hwnd) {
|
||||
this.hwnd = hwnd;
|
||||
|
@ -62,13 +62,13 @@ public class Window {
|
|||
public static void onKey() {
|
||||
var user32 = User32Extra.INSTANCE;
|
||||
var kernel32 = Kernel32.INSTANCE;
|
||||
var res = user32.SetWindowsHookEx(
|
||||
User32Extra.WH_KEYBOARD_LL,
|
||||
var res = user32.SetWindowsHookEx(User32Extra.WH_KEYBOARD_LL,
|
||||
new WinUser.HOOKPROC() {
|
||||
public WinDef.LRESULT callback(int nCode, WinDef.WPARAM wparam
|
||||
, WinDef.LPARAM lparam) {
|
||||
var kb = new WinUser.KBDLLHOOKSTRUCT().newInstance(
|
||||
WinUser.KBDLLHOOKSTRUCT.class,
|
||||
public WinDef.LRESULT callback(
|
||||
int nCode, WinDef.WPARAM wparam, WinDef.LPARAM lparam
|
||||
) {
|
||||
var kb =
|
||||
new WinUser.KBDLLHOOKSTRUCT().newInstance(WinUser.KBDLLHOOKSTRUCT.class,
|
||||
lparam.toPointer()
|
||||
);
|
||||
System.out.println(kb.vkCode);
|
||||
|
@ -105,11 +105,11 @@ public class Window {
|
|||
var kernel32 = Kernel32.INSTANCE;
|
||||
var hmod = kernel32.GetModuleHandle("kernel32.dll");
|
||||
//todo: try RegisterShellHookWindow instead
|
||||
var res = user32.SetWindowsHookEx(
|
||||
User32Extra.WH_SHELL,
|
||||
var res = user32.SetWindowsHookEx(User32Extra.WH_SHELL,
|
||||
new WinUser.HOOKPROC() {
|
||||
public WinDef.LRESULT callback(int nCode, WinDef.WPARAM wparam
|
||||
, WinDef.LPARAM lparam) {
|
||||
public WinDef.LRESULT callback(
|
||||
int nCode, WinDef.WPARAM wparam, WinDef.LPARAM lparam
|
||||
) {
|
||||
System.out.println("got some message b");
|
||||
if(nCode == User32Extra.HSHELL_WINDOWCREATED) {
|
||||
System.out.println("window created");
|
||||
|
@ -163,7 +163,7 @@ public class Window {
|
|||
if((style & User32.WS_TILED) != 0) str.append("ws_tiled, ");
|
||||
if((style & User32.WS_VISIBLE) != 0) str.append("ws_visible, ");
|
||||
if((style & User32.WS_VSCROLL) != 0) str.append("ws_vscroll, ");
|
||||
System.out.println(str.toString());
|
||||
System.out.println(str);
|
||||
}
|
||||
|
||||
public void debugPrintStylesEx() {
|
||||
|
@ -218,7 +218,184 @@ public class Window {
|
|||
"ws_ex_transparent, ");
|
||||
if((style & User32Extra.WS_EX_WINDOWEDGE) != 0) str.append(
|
||||
"ws_ex_windowedge, ");
|
||||
System.out.println(str.toString());
|
||||
System.out.println(str);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if(!(o instanceof Window)) {
|
||||
return false;
|
||||
}
|
||||
return ((Window) o).hwnd.equals(this.hwnd);
|
||||
}
|
||||
|
||||
public String getClassName() {
|
||||
var user32 = User32Extra.INSTANCE;
|
||||
char[] chars = new char[1024];
|
||||
|
||||
user32.GetClassName(hwnd, chars, 1024);
|
||||
return Util.nullTerminatedCharArrayToString(chars);
|
||||
}
|
||||
|
||||
public String getExecutableName() {
|
||||
var user32 = User32Extra.INSTANCE;
|
||||
var kernel32 = Kernel32.INSTANCE;
|
||||
var handle =
|
||||
kernel32.OpenProcess(WinNT.PROCESS_QUERY_LIMITED_INFORMATION,
|
||||
false,
|
||||
getProcessId()
|
||||
);
|
||||
char[] chars = new char[1024];
|
||||
var len = new IntByReference();
|
||||
len.setValue(1024);
|
||||
|
||||
kernel32.QueryFullProcessImageName(handle, 0, chars, len);
|
||||
return Util.nullTerminatedCharArrayToString(chars);
|
||||
}
|
||||
|
||||
public String getKey() {
|
||||
return getExecutableName() + " $ " + getClassName();
|
||||
}
|
||||
|
||||
private int getProcessId() {
|
||||
var user32 = User32Extra.INSTANCE;
|
||||
var ref = new IntByReference();
|
||||
user32.GetWindowThreadProcessId(hwnd, ref);
|
||||
return ref.getValue();
|
||||
}
|
||||
|
||||
private int getStyle() {
|
||||
var user32 = User32Extra.INSTANCE;
|
||||
return user32.GetWindowLong(hwnd, WinUser.GWL_STYLE);
|
||||
}
|
||||
|
||||
private int getStyleEx() {
|
||||
var user32 = User32Extra.INSTANCE;
|
||||
return user32.GetWindowLong(hwnd, WinUser.GWL_EXSTYLE);
|
||||
}
|
||||
|
||||
public String getTitle() {
|
||||
var user32 = User32Extra.INSTANCE;
|
||||
char[] chars = new char[1024];
|
||||
|
||||
user32.GetWindowText(hwnd, chars, 1024);
|
||||
return Util.nullTerminatedCharArrayToString(chars);
|
||||
}
|
||||
|
||||
private TITLEBARINFO getTitleBarInfo() {
|
||||
var user32 = User32Extra.INSTANCE;
|
||||
var tb = new TITLEBARINFO();
|
||||
user32.GetTitleBarInfo(hwnd, tb);
|
||||
return tb;
|
||||
}
|
||||
|
||||
public boolean isClass(String str) {
|
||||
return str.equals(getClassName());
|
||||
}
|
||||
|
||||
public boolean isDwmCloaked() {
|
||||
var user32 = User32Extra.INSTANCE;
|
||||
var dwm = Dwm.INSTANCE;
|
||||
var out = new IntByReference();
|
||||
dwm.DwmGetWindowAttribute(hwnd,
|
||||
Dwm.DWMWA_CLOAKED,
|
||||
out.getPointer(),
|
||||
new WinDef.DWORD(WinDef.DWORD.SIZE)
|
||||
);
|
||||
var val = out.getValue();
|
||||
return val != 0;
|
||||
}
|
||||
|
||||
public boolean isExecutableName(String str) {
|
||||
return str.equals(getExecutableName());
|
||||
}
|
||||
|
||||
public boolean isInAltTabList() {
|
||||
var user32 = User32Extra.INSTANCE;
|
||||
var walk = user32.GetAncestor(hwnd, WinUser.GA_ROOTOWNER);
|
||||
WinDef.HWND test;
|
||||
|
||||
var window = new Window(hwnd);
|
||||
if(walk == null) return false;
|
||||
return walk.equals(hwnd) &&
|
||||
user32.IsWindowVisible(hwnd) &&
|
||||
window.getTitle().length() > 0 &&
|
||||
!window.isToolWindow() &&
|
||||
!window.isDwmCloaked() &&
|
||||
!window.getClassName().equals("Progman");
|
||||
}
|
||||
|
||||
private boolean isTitleBarVisible() {
|
||||
var tb = getTitleBarInfo();
|
||||
return (tb.rgstate[0] & User32Extra.STATE_SYSTEM_INVISIBLE) == 0;
|
||||
}
|
||||
|
||||
public boolean isToolWindow() {
|
||||
return (getStyleEx() & User32Extra.WS_EX_TOOLWINDOW) != 0;
|
||||
}
|
||||
|
||||
public void move(Recti rectangle) {
|
||||
var user32 = User32Extra.INSTANCE;
|
||||
var dwm = Dwm.INSTANCE;
|
||||
var pos = rectangle.getPos();
|
||||
var size = rectangle.getSize();
|
||||
|
||||
var rect_with_shadow = new WinDef.RECT();
|
||||
var rect_without_shadow = new WinDef.RECT();
|
||||
var rect = new WinDef.RECT();
|
||||
|
||||
user32.GetWindowRect(hwnd, rect_with_shadow);
|
||||
dwm.DwmGetWindowAttribute(hwnd,
|
||||
Dwm.DWMWA_EXTENDED_FRAME_BOUNDS,
|
||||
rect_without_shadow.getPointer(),
|
||||
new WinDef.DWORD(rect_without_shadow.size())
|
||||
);
|
||||
rect_without_shadow.read();
|
||||
var left_shadow = rect_without_shadow.left - rect_with_shadow.left;
|
||||
var right_shadow = rect_with_shadow.right - rect_without_shadow.right;
|
||||
var top_shadow = rect_without_shadow.top - rect_with_shadow.top;
|
||||
var bottom_shaddow = rect_with_shadow.bottom -
|
||||
rect_without_shadow.bottom;
|
||||
|
||||
|
||||
rect.left = pos.getX() - left_shadow;
|
||||
rect.top = pos.getY() - top_shadow;
|
||||
rect.right = pos.getX() + size.getX() + right_shadow;
|
||||
rect.bottom = pos.getY() + size.getY() + bottom_shaddow;
|
||||
//user32.AdjustWindowRect(rect, new WinDef.DWORD(WinUser
|
||||
// .WS_OVERLAPPEDWINDOW), new WinDef.BOOL(false));
|
||||
//var style = getStyle();
|
||||
//var styleex = getStyleEx();
|
||||
//style &= ~(User32Extra.WS_CAPTION | User32Extra.WS_MINIMIZEBOX |
|
||||
// User32Extra.WS_SYSMENU);
|
||||
//styleex &= ~(User32Extra.WS_EX_DLGMODALFRAME | User32Extra
|
||||
// .WS_EX_CLIENTEDGE | User32Extra.WS_EX_STATICEDGE);
|
||||
//style |= User32Extra.WS_POPUP;
|
||||
//user32.AdjustWindowRectEx(rect, new WinDef.DWORD(style), new WinDef
|
||||
// .BOOL(false), new WinDef.DWORD(styleex));
|
||||
user32.MoveWindow(hwnd,
|
||||
rect.left,
|
||||
rect.top,
|
||||
rect.right - rect.left,
|
||||
rect.bottom - rect.top,
|
||||
true
|
||||
);
|
||||
//user32.MoveWindow(hwnd, pos.getX(), pos.getY(), size.getX(), size
|
||||
// .getY(), true);
|
||||
|
||||
user32.SetWindowPos(hwnd,
|
||||
null,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
WinUser.SWP_FRAMECHANGED |
|
||||
WinUser.SWP_NOZORDER |
|
||||
WinUser.SWP_NOOWNERZORDER |
|
||||
WinUser.SWP_NOMOVE |
|
||||
WinUser.SWP_NOSIZE |
|
||||
WinUser.SWP_NOACTIVATE
|
||||
);
|
||||
}
|
||||
|
||||
public void setBorder(boolean border) {
|
||||
|
@ -259,202 +436,20 @@ public class Window {
|
|||
public void setBorderRounded(boolean rounded) {
|
||||
var round = rounded ? Dwm.DWMWCP_ROUND : Dwm.DWMWCP_DONOTROUND;
|
||||
var roundref = new WinDef.DWORDByReference(round);
|
||||
Dwm.INSTANCE.DwmSetWindowAttribute(
|
||||
hwnd,
|
||||
Dwm.INSTANCE.DwmSetWindowAttribute(hwnd,
|
||||
Dwm.DWMWA_WINDOW_CORNER_PREFERENCE,
|
||||
roundref.getPointer(),
|
||||
new WinDef.DWORD(WinDef.DWORD.SIZE)
|
||||
);
|
||||
}
|
||||
|
||||
public String getClassName() {
|
||||
var user32 = User32Extra.INSTANCE;
|
||||
char[] chars = new char[1024];
|
||||
|
||||
user32.GetClassName(hwnd, chars, 1024);
|
||||
return Util.nullTerminatedCharArrayToString(chars);
|
||||
}
|
||||
|
||||
public String getExecutableName() {
|
||||
var user32 = User32Extra.INSTANCE;
|
||||
var kernel32 = Kernel32.INSTANCE;
|
||||
var handle = kernel32.OpenProcess(
|
||||
WinNT.PROCESS_QUERY_LIMITED_INFORMATION,
|
||||
false,
|
||||
getProcessId()
|
||||
);
|
||||
char[] chars = new char[1024];
|
||||
var len = new IntByReference();
|
||||
len.setValue(1024);
|
||||
|
||||
kernel32.QueryFullProcessImageName(handle, 0, chars, len);
|
||||
return Util.nullTerminatedCharArrayToString(chars);
|
||||
}
|
||||
|
||||
public String getKey() {
|
||||
return getExecutableName() + " $ " + getClassName();
|
||||
}
|
||||
|
||||
private int getStyle() {
|
||||
var user32 = User32Extra.INSTANCE;
|
||||
return user32.GetWindowLong(hwnd, WinUser.GWL_STYLE);
|
||||
}
|
||||
|
||||
private void setStyle(int style) {
|
||||
var user32 = User32Extra.INSTANCE;
|
||||
user32.SetWindowLong(hwnd, WinUser.GWL_STYLE, style);
|
||||
}
|
||||
|
||||
private int getStyleEx() {
|
||||
var user32 = User32Extra.INSTANCE;
|
||||
return user32.GetWindowLong(hwnd, WinUser.GWL_EXSTYLE);
|
||||
}
|
||||
|
||||
private void setStyleEx(int style) {
|
||||
var user32 = User32Extra.INSTANCE;
|
||||
user32.SetWindowLong(hwnd, WinUser.GWL_EXSTYLE, style);
|
||||
}
|
||||
|
||||
private boolean isTitleBarVisible() {
|
||||
var tb = getTitleBarInfo();
|
||||
return (tb.rgstate[0] & User32Extra.STATE_SYSTEM_INVISIBLE) == 0;
|
||||
}
|
||||
|
||||
public String getTitle() {
|
||||
var user32 = User32Extra.INSTANCE;
|
||||
char[] chars = new char[1024];
|
||||
|
||||
user32.GetWindowText(hwnd, chars, 1024);
|
||||
return Util.nullTerminatedCharArrayToString(chars);
|
||||
}
|
||||
|
||||
private TITLEBARINFO getTitleBarInfo() {
|
||||
var user32 = User32Extra.INSTANCE;
|
||||
var tb = new TITLEBARINFO();
|
||||
user32.GetTitleBarInfo(hwnd, tb);
|
||||
return tb;
|
||||
}
|
||||
|
||||
private int getProcessId() {
|
||||
var user32 = User32Extra.INSTANCE;
|
||||
var ref = new IntByReference();
|
||||
user32.GetWindowThreadProcessId(hwnd, ref);
|
||||
return ref.getValue();
|
||||
}
|
||||
|
||||
public boolean isDwmCloaked() {
|
||||
var user32 = User32Extra.INSTANCE;
|
||||
var dwm = Dwm.INSTANCE;
|
||||
var out = new IntByReference();
|
||||
dwm.DwmGetWindowAttribute(
|
||||
hwnd,
|
||||
Dwm.DWMWA_CLOAKED,
|
||||
out.getPointer(),
|
||||
new WinDef.DWORD(WinDef.DWORD.SIZE)
|
||||
);
|
||||
var val = out.getValue();
|
||||
return val != 0;
|
||||
}
|
||||
|
||||
public boolean isClass(String str) {
|
||||
return str.equals(getClassName());
|
||||
}
|
||||
|
||||
public boolean isExecutableName(String str) {
|
||||
return str.equals(getExecutableName());
|
||||
}
|
||||
|
||||
public boolean isInAltTabList() {
|
||||
var user32 = User32Extra.INSTANCE;
|
||||
var walk = user32.GetAncestor(hwnd, WinUser.GA_ROOTOWNER);
|
||||
WinDef.HWND test;
|
||||
|
||||
var window = new Window(hwnd);
|
||||
if(walk == null) return false;
|
||||
return walk.equals(hwnd) &&
|
||||
user32.IsWindowVisible(hwnd) &&
|
||||
window.getTitle().length() > 0 &&
|
||||
!window.isToolWindow() &&
|
||||
!window.isDwmCloaked() &&
|
||||
!window.getClassName().equals("Progman");
|
||||
}
|
||||
|
||||
public boolean isToolWindow() {
|
||||
return (getStyleEx() & User32Extra.WS_EX_TOOLWINDOW) != 0;
|
||||
}
|
||||
|
||||
public void move(Recti rectangle) {
|
||||
var user32 = User32Extra.INSTANCE;
|
||||
var dwm = Dwm.INSTANCE;
|
||||
var pos = rectangle.getPos();
|
||||
var size = rectangle.getSize();
|
||||
|
||||
var rect_with_shadow = new WinDef.RECT();
|
||||
var rect_without_shadow = new WinDef.RECT();
|
||||
var rect = new WinDef.RECT();
|
||||
|
||||
user32.GetWindowRect(hwnd, rect_with_shadow);
|
||||
dwm.DwmGetWindowAttribute(
|
||||
hwnd,
|
||||
Dwm.DWMWA_EXTENDED_FRAME_BOUNDS,
|
||||
rect_without_shadow.getPointer(),
|
||||
new WinDef.DWORD(rect_without_shadow.size())
|
||||
);
|
||||
rect_without_shadow.read();
|
||||
var left_shadow = rect_without_shadow.left - rect_with_shadow.left;
|
||||
var right_shadow = rect_with_shadow.right - rect_without_shadow.right;
|
||||
var top_shadow = rect_without_shadow.top - rect_with_shadow.top;
|
||||
var bottom_shaddow = rect_with_shadow.bottom -
|
||||
rect_without_shadow.bottom;
|
||||
|
||||
|
||||
rect.left = pos.getX() - left_shadow;
|
||||
rect.top = pos.getY() - top_shadow;
|
||||
rect.right = pos.getX() + size.getX() + right_shadow;
|
||||
rect.bottom = pos.getY() + size.getY() + bottom_shaddow;
|
||||
//user32.AdjustWindowRect(rect, new WinDef.DWORD(WinUser
|
||||
// .WS_OVERLAPPEDWINDOW), new WinDef.BOOL(false));
|
||||
//var style = getStyle();
|
||||
//var styleex = getStyleEx();
|
||||
//style &= ~(User32Extra.WS_CAPTION | User32Extra.WS_MINIMIZEBOX |
|
||||
// User32Extra.WS_SYSMENU);
|
||||
//styleex &= ~(User32Extra.WS_EX_DLGMODALFRAME | User32Extra
|
||||
// .WS_EX_CLIENTEDGE | User32Extra.WS_EX_STATICEDGE);
|
||||
//style |= User32Extra.WS_POPUP;
|
||||
//user32.AdjustWindowRectEx(rect, new WinDef.DWORD(style), new WinDef
|
||||
// .BOOL(false), new WinDef.DWORD(styleex));
|
||||
user32.MoveWindow(
|
||||
hwnd,
|
||||
rect.left,
|
||||
rect.top,
|
||||
rect.right - rect.left,
|
||||
rect.bottom - rect.top,
|
||||
true
|
||||
);
|
||||
//user32.MoveWindow(hwnd, pos.getX(), pos.getY(), size.getX(), size
|
||||
// .getY(), true);
|
||||
|
||||
user32.SetWindowPos(
|
||||
hwnd,
|
||||
null,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
WinUser.SWP_FRAMECHANGED |
|
||||
WinUser.SWP_NOZORDER |
|
||||
WinUser.SWP_NOOWNERZORDER |
|
||||
WinUser.SWP_NOMOVE |
|
||||
WinUser.SWP_NOSIZE |
|
||||
WinUser.SWP_NOACTIVATE
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if(!(o instanceof Window)) {
|
||||
return false;
|
||||
}
|
||||
return ((Window) o).hwnd.equals(this.hwnd);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue