changed formatting rules

This commit is contained in:
DaniTheSkunk 2022-10-11 07:49:22 +00:00
parent 661fc6d275
commit 74b2c36243
30 changed files with 960 additions and 447 deletions

View File

@ -1,7 +1,15 @@
<component name="ProjectCodeStyleConfiguration">
<code_scheme name="Project" version="173">
<option name="AUTODETECT_INDENTS" value="false" />
<option name="RIGHT_MARGIN" value="80" />
<option name="WRAP_WHEN_TYPING_REACHES_RIGHT_MARGIN" value="true" />
<option name="ENABLE_SECOND_REFORMAT" value="true" />
<editorconfig>
<option name="ENABLED" value="false" />
</editorconfig>
<codeStyleSettings language="JAVA">
<option name="KEEP_LINE_BREAKS" value="false" />
<option name="ALIGN_MULTILINE_PARAMETERS" value="false" />
<option name="SPACE_BEFORE_IF_PARENTHESES" value="false" />
<option name="SPACE_BEFORE_WHILE_PARENTHESES" value="false" />
<option name="SPACE_BEFORE_FOR_PARENTHESES" value="false" />
@ -9,8 +17,16 @@
<option name="SPACE_BEFORE_CATCH_PARENTHESES" value="false" />
<option name="SPACE_BEFORE_SWITCH_PARENTHESES" value="false" />
<option name="SPACE_BEFORE_SYNCHRONIZED_PARENTHESES" value="false" />
<option name="CALL_PARAMETERS_WRAP" value="5" />
<option name="PREFER_PARAMETERS_WRAP" value="true" />
<option name="CALL_PARAMETERS_LPAREN_ON_NEXT_LINE" value="true" />
<option name="CALL_PARAMETERS_RPAREN_ON_NEXT_LINE" value="true" />
<option name="METHOD_PARAMETERS_LPAREN_ON_NEXT_LINE" value="true" />
<option name="METHOD_PARAMETERS_RPAREN_ON_NEXT_LINE" value="true" />
<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="WRAP_LONG_LINES" value="true" />
<indentOptions>
<option name="CONTINUATION_INDENT_SIZE" value="4" />
<option name="USE_TAB_CHARACTER" value="true" />

View File

@ -1,6 +1,5 @@
package com.danitheskunk.skunkworks;
import com.danitheskunk.skunkworks.gfx.Color;
import com.danitheskunk.skunkworks.gfx.IRenderContext;
import com.danitheskunk.skunkworks.gfx.font.IFont;
import com.danitheskunk.skunkworks.nodes.Node;
@ -42,7 +41,9 @@ public abstract class BaseGame {
}
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);
//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) {

View File

@ -69,17 +69,41 @@ abstract public class BaseWindow implements IWindow {
if(x1 == -1 || x2 == -1 || y1 == -1 || y2 == -1) {
throw new RuntimeException("NineSlice error");
}
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, 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, y1, image.getWidth()-x2, y2-y1));
var bl = image.getSubImage(new Recti(1, y2, x1-1, image.getHeight()-y2));
var bottom = image.getSubImage(new Recti(x1, y2, x2-x1, image.getHeight()-y2));
var br = image.getSubImage(new Recti(x2, y2, image.getWidth()-x2, image.getHeight()-y2));
var slice = new NineSlice(
loadTexture(tl),
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,
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,
y1,
image.getWidth() - x2,
y2 - y1
));
var bl = image.getSubImage(new Recti(
1,
y2,
x1 - 1,
image.getHeight() - y2
));
var bottom = image.getSubImage(new Recti(
x1,
y2,
x2 - x1,
image.getHeight() - y2
));
var br = image.getSubImage(new Recti(
x2,
y2,
image.getWidth() - x2,
image.getHeight() - y2
));
var slice = new NineSlice(loadTexture(tl),
loadTexture(tr),
loadTexture(bl),
loadTexture(br),
@ -94,7 +118,7 @@ abstract public class BaseWindow implements IWindow {
@Override
public NineSlice loadNineSlice(String path) {
return loadNineSlice(engine.loadImage(path));
return loadNineSlice(engine.loadImage(path));
}
}

View File

@ -9,7 +9,7 @@ import java.io.FileInputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
import static com.danitheskunk.skunkworks.gfx.GraphicsBackend.*;
import static com.danitheskunk.skunkworks.gfx.GraphicsBackend.OPENGL;
public class Engine {
private final GraphicsBackend graphicsBackend;
@ -37,6 +37,7 @@ public class Engine {
buf.flip();
return buf;
}
public Image loadImage(String path) {
return new Image(loadBytes(path));
}

View File

@ -10,17 +10,30 @@ import java.util.List;
public interface IWindow {
Engine getEngine();
IFont loadFontTileset(String path);
IFont loadFontTTF(String path, float size);
NineSlice loadNineSlice(Image image);
NineSlice loadNineSlice(String path);
ITexture loadTexture(Image image);
ITexture loadTexture(String path);
List<ITexture> loadTextureArray(Image image, Vec2i tileSize);
List<ITexture> loadTextureArray(String path, Vec2i tileSize);
void renderFinish(IRenderContext context);
IRenderContext renderStart();
void setDebug(boolean on);
boolean shouldClose();
void tick();
}

View File

@ -10,7 +10,8 @@ public final class Recti {
}
public Recti(Vec2i pos, Vec2i size) {
this.pos = pos; this.size = size;
this.pos = pos;
this.size = size;
}
//getters

View File

@ -6,6 +6,7 @@ public class Program {
Shader vertex;
Shader fragment;
int program;
public Program(String vertexSource, String fragmentSource) {
vertex = new Shader(vertexSource, GL_VERTEX_SHADER);
fragment = new Shader(fragmentSource, GL_FRAGMENT_SHADER);

View File

@ -1,6 +1,7 @@
package com.danitheskunk.skunkworks.backends.gl;
import com.danitheskunk.skunkworks.*;
import com.danitheskunk.skunkworks.Recti;
import com.danitheskunk.skunkworks.Vec2i;
import com.danitheskunk.skunkworks.gfx.*;
import static org.lwjgl.opengl.GL46.*;
@ -12,7 +13,10 @@ class RenderContext extends BaseRenderContext implements IRenderContext {
private final int texSizeIndex;
private final int tintIndex;
public RenderContext(Vec2i size, TextureAtlas atlas, int texCoordIndex, int texOffsetIndex, int texSizeIndex, int tintIndex) {
public RenderContext(
Vec2i size, TextureAtlas atlas, int texCoordIndex, int texOffsetIndex,
int texSizeIndex, int tintIndex
) {
super(size);
this.atlas = atlas;
this.texCoordIndex = texCoordIndex;
@ -23,62 +27,66 @@ class RenderContext extends BaseRenderContext implements IRenderContext {
@Override
public void drawNineSlice(NineSlice slice, Recti rect) {
var centerWidth = Math.max(0, rect.getWidth() - slice.getLeft().getSize().getX() - slice.getRight().getSize().getX());
var centerHeight = Math.max(0, rect.getHeight() - slice.getTop().getSize().getY() - slice.getBottom().getSize().getY());
var centerWidth = Math.max(0,
rect.getWidth() -
slice.getLeft().getSize().getX() -
slice.getRight().getSize().getX()
);
var centerHeight = Math.max(0,
rect.getHeight() -
slice.getTop().getSize().getY() -
slice.getBottom().getSize().getY()
);
var pos = rect.getPos();
var size = rect.getSize();
drawTexture(pos, slice.getTopLeft());
drawTexture(new Vec2i(pos.getX() + slice.getLeft().getWidth() + centerWidth, pos.getY()), slice.getTopRight());
drawTexture(new Vec2i(pos.getX(), pos.getY() + slice.getTop().getHeight() + centerHeight), slice.getBottomLeft());
drawTexture(Vec2i.add(pos, slice.getTopLeft().getSize(), new Vec2i(centerWidth, centerHeight)), slice.getBottomRight());
drawTexture(
new Vec2i(pos.getX() + slice.getLeft().getWidth() + centerWidth,
pos.getY()
),
slice.getTopRight()
);
drawTexture(new Vec2i(pos.getX(),
pos.getY() + slice.getTop().getHeight() + centerHeight
), slice.getBottomLeft());
drawTexture(Vec2i.add(pos,
slice.getTopLeft().getSize(),
new Vec2i(centerWidth, centerHeight)
), slice.getBottomRight());
drawTextureRectangle(new Recti(Vec2i.add(pos, slice.getTopLeft().getSize()), new Vec2i(centerWidth, centerHeight)), slice.getCenter(), true);
drawTextureRectangle(new Recti(Vec2i.add(pos,
slice.getTopLeft().getSize()
),
new Vec2i(centerWidth, centerHeight)
), slice.getCenter(), true);
//top
drawTextureRectangle(
new Recti(
pos.getX() + slice.getLeft().getWidth(),
pos.getY(),
centerWidth,
slice.getTop().getHeight()
),
slice.getTop(),
true
);
drawTextureRectangle(new Recti(pos.getX() + slice.getLeft().getWidth(),
pos.getY(),
centerWidth,
slice.getTop().getHeight()
), slice.getTop(), true);
//bottom
drawTextureRectangle(
new Recti(
pos.getX() + slice.getLeft().getWidth(),
pos.getY() + slice.getTop().getHeight() + centerHeight,
centerWidth,
slice.getTop().getHeight()
),
slice.getBottom(),
true
);
drawTextureRectangle(new Recti(pos.getX() + slice.getLeft().getWidth(),
pos.getY() + slice.getTop().getHeight() + centerHeight,
centerWidth,
slice.getTop().getHeight()
), slice.getBottom(), true);
//left
drawTextureRectangle(
new Recti(
pos.getX(),
pos.getY() + slice.getTop().getHeight(),
slice.getLeft().getWidth(),
centerHeight
),
slice.getLeft(),
true
);
drawTextureRectangle(new Recti(pos.getX(),
pos.getY() + slice.getTop().getHeight(),
slice.getLeft().getWidth(),
centerHeight
), slice.getLeft(), true);
//right
drawTextureRectangle(
new Recti(
pos.getX() + slice.getLeft().getWidth() + centerWidth,
pos.getY() + slice.getTop().getHeight(),
slice.getLeft().getWidth(),
centerHeight
),
slice.getRight(),
true
);
drawTextureRectangle(new Recti(pos.getX() +
slice.getLeft().getWidth() +
centerWidth,
pos.getY() + slice.getTop().getHeight(),
slice.getLeft().getWidth(),
centerHeight
), slice.getRight(), true);
}
@Override
@ -90,8 +98,7 @@ class RenderContext extends BaseRenderContext implements IRenderContext {
//todo: make work with enabled textures
glColor4f(
color.getR() / 255.0f,
glColor4f(color.getR() / 255.0f,
color.getG() / 255.0f,
color.getB() / 255.0f,
color.getA() / 255.0f
@ -114,16 +121,24 @@ class RenderContext extends BaseRenderContext implements IRenderContext {
@Override
public void drawTexture(Vec2i pos, ITexture texture, Color color) {
drawTextureRectangle(new Recti(pos, texture.getSize()), texture, color, true);
drawTextureRectangle(new Recti(pos, texture.getSize()),
texture,
color,
true
);
}
@Override
public void drawTextureRectangle(Recti rect, ITexture texture, boolean repeat) {
public void drawTextureRectangle(
Recti rect, ITexture texture, boolean repeat
) {
drawTextureRectangle(rect, texture, Color.WHITE, repeat);
}
@Override
public void drawTextureRectangle(Recti rect, ITexture texture, Color color, boolean repeat) {
public void drawTextureRectangle(
Recti rect, ITexture texture, Color color, boolean repeat
) {
var tex = (Texture) texture;
var tl = rect.getTopLeft();
@ -132,10 +147,14 @@ class RenderContext extends BaseRenderContext implements IRenderContext {
var br = rect.getBottomRight();
/*
var ttl = Vec2i.divf(tex.getTexArea().getTopLeft(), atlas.getSize());
var ttr = Vec2i.divf(tex.getTexArea().getTopRight(), atlas.getSize());
var tbl = Vec2i.divf(tex.getTexArea().getBottomLeft(), atlas.getSize());
var tbr = Vec2i.divf(tex.getTexArea().getBottomRight(), atlas.getSize());
var ttl = Vec2i.divf(tex.getTexArea().getTopLeft(), atlas.getSize
());
var ttr = Vec2i.divf(tex.getTexArea().getTopRight(), atlas.getSize
());
var tbl = Vec2i.divf(tex.getTexArea().getBottomLeft(), atlas.getSize
());
var tbr = Vec2i.divf(tex.getTexArea().getBottomRight(), atlas.getSize
());
*/
var topleft = tex.getTexArea().getTopLeft();
@ -157,13 +176,12 @@ class RenderContext extends BaseRenderContext implements IRenderContext {
tbr = Vec2i.sub(tex.getTexArea().getBottomRight(), topleft);
}
glUniform3f(
tintIndex,
glUniform3f(tintIndex,
color.getR() / 255.0f,
color.getG() / 255.0f,
color.getB() / 255.0f
//color.getA() / 255.0f
);
//color.getA() / 255.0f);
glUniform2i(texOffsetIndex, topleft.getX(), topleft.getY());
glUniform2i(texSizeIndex, size.getX(), size.getY());

View File

@ -1,15 +1,13 @@
package com.danitheskunk.skunkworks.backends.gl;
import com.danitheskunk.skunkworks.gfx.ITexture;
import com.danitheskunk.skunkworks.gfx.Image;
import com.danitheskunk.skunkworks.Recti;
import com.danitheskunk.skunkworks.Vec2i;
import com.danitheskunk.skunkworks.gfx.ITexture;
import com.danitheskunk.skunkworks.gfx.Image;
class Texture implements ITexture {
private Recti texArea;
private final Image img; //for re-blitting onto texture atlas
private Recti texArea;
Texture(Recti texArea, Image img) {
this.texArea = texArea;
@ -20,8 +18,11 @@ class Texture implements ITexture {
Image getImg() {
return img;
}
@Override
public Vec2i getSize() { return this.img.getSize(); }
public Vec2i getSize() {
return this.img.getSize();
}
@Override
public int getWidth() {
@ -33,12 +34,11 @@ class Texture implements ITexture {
return img.getHeight();
}
void setTexArea(Recti texArea) {
this.texArea = texArea;
}
Recti getTexArea() {
return texArea;
}
void setTexArea(Recti texArea) {
this.texArea = texArea;
}
}

View File

@ -1,9 +1,9 @@
package com.danitheskunk.skunkworks.backends.gl;
import com.danitheskunk.skunkworks.gfx.ITexture;
import com.danitheskunk.skunkworks.gfx.Image;
import com.danitheskunk.skunkworks.Recti;
import com.danitheskunk.skunkworks.Vec2i;
import com.danitheskunk.skunkworks.gfx.ITexture;
import com.danitheskunk.skunkworks.gfx.Image;
import org.lwjgl.BufferUtils;
import java.util.ArrayList;
@ -13,10 +13,10 @@ import java.util.List;
import static org.lwjgl.opengl.GL11.*;
class TextureAtlas {
private final List<Texture> textures;
private Texture atlasTexture; //for debugging
private Image img;
private boolean shouldUpdate;
private final List<Texture> textures;
TextureAtlas() {
img = new Image(new Vec2i(32, 32));
@ -35,7 +35,10 @@ class TextureAtlas {
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()), img);
var texture = new Texture(
new Recti(new Vec2i(0, 0), img.getSize()),
img
);
textures.add(texture);
shouldUpdate = true;
return texture;
@ -43,7 +46,11 @@ class TextureAtlas {
void doubleAtlasSize() {
img = new Image(Vec2i.mul(img.getSize(), 2));
System.out.printf("Resized atlas to %dx%d\n", img.getSize().getX(), img.getSize().getY());
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);
}
@ -55,6 +62,7 @@ class TextureAtlas {
shouldUpdate = false;
}
}
void repack() {
int x = 0;
int y = 0;
@ -66,7 +74,8 @@ class TextureAtlas {
for(var tex : textures) {
var texImg = tex.getImg();
//texture larger than atlas? resize atlas and try again
if(texImg.getHeight() > img.getHeight() || texImg.getWidth() > img.getWidth()) {
if(texImg.getHeight() > img.getHeight() ||
texImg.getWidth() > img.getWidth()) {
System.out.println("Texture too large");
doubleAtlasSize();
repack();
@ -105,8 +114,7 @@ class TextureAtlas {
buf.put(img.getData());
buf.flip();
glTexImage2D(
GL_TEXTURE_2D,
glTexImage2D(GL_TEXTURE_2D,
0,
GL_RGBA,
img.getWidth(),

View File

@ -1,6 +1,9 @@
package com.danitheskunk.skunkworks.backends.gl;
import com.danitheskunk.skunkworks.*;
import com.danitheskunk.skunkworks.BaseWindow;
import com.danitheskunk.skunkworks.Engine;
import com.danitheskunk.skunkworks.Recti;
import com.danitheskunk.skunkworks.Vec2i;
import com.danitheskunk.skunkworks.gfx.IRenderContext;
import com.danitheskunk.skunkworks.gfx.ITexture;
import com.danitheskunk.skunkworks.gfx.Image;
@ -16,25 +19,52 @@ import static org.lwjgl.opengl.GL46.*;
import static org.lwjgl.system.MemoryUtil.NULL;
public class Window extends BaseWindow {
private boolean debug;
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 = """
#version 450
layout(location = 1) in vec2 texCoord;
layout(binding = 0) uniform sampler2D tex;
layout(location = 3) uniform ivec2 texOffset;
layout(location = 4) uniform ivec2 texSize;
layout(location = 5) uniform vec3 tint;
out vec4 color;
void main() {
//color = vec4(vec2(texCoord).x/1000.f, 0.2f, 0.7f, 1.0f);
//color = texture(tex, texCoord);
color = texelFetch(tex, ivec2(mod(texCoord, texSize)) + texOffset, 0) * vec4(tint, 1.0f);
}
""";
private final Program program;
private final RenderContext renderContext;
private boolean shouldClose;
private final Vec2i size;
private final TextureAtlas textureAtlas;
private final long window;
private boolean debug;
private boolean shouldClose;
public Window(Vec2i size, String title, Engine engine) {
super(engine);
GLFWErrorCallback.createPrint(System.err).set();
if(!glfwInit()) throw new IllegalStateException("Unable to initialize GLFW");
if(!glfwInit()) throw new IllegalStateException(
"Unable to initialize GLFW");
glfwDefaultWindowHints();
this.debug = false;
this.size = size;
window = glfwCreateWindow(size.getX(), size.getY(), title, NULL, NULL);
if(window == NULL) throw new RuntimeException("Failed to create GLFW window");
if(window == NULL) throw new RuntimeException(
"Failed to create GLFW window");
glfwShowWindow(window);
@ -52,15 +82,19 @@ public class Window extends BaseWindow {
textureAtlas = new TextureAtlas();
program = new Program(vertexSource, fragmentSource);
program.use();
renderContext = new RenderContext(
size,
renderContext = new RenderContext(size,
textureAtlas,
program.getAttribLocation("texCoord"),
program.getUniformLocation("texOffset"),
program.getUniformLocation("texSize"),
program.getUniformLocation("tint")
);
glProgramUniform2f(program.program, program.getUniformLocation("windowSize"), size.getX(), size.getY());
glProgramUniform2f(
program.program,
program.getUniformLocation("windowSize"),
size.getX(),
size.getY()
);
shouldClose = false;
@ -87,7 +121,10 @@ public class Window extends BaseWindow {
for(int y = 0; y < tileCount.getY(); ++y) {
for(int x = 0; x < tileCount.getX(); ++x) {
var rect = new Recti(Vec2i.mul(new Vec2i(x, y), tileSize), tileSize);
var rect = new Recti(
Vec2i.mul(new Vec2i(x, y), tileSize),
tileSize
);
var img = image.getSubImage(rect);
tiles.add(loadTexture(img));
}
@ -105,7 +142,11 @@ public class Window extends BaseWindow {
@Override
public void renderFinish(IRenderContext context) {
if(debug) {
context.drawTextureRectangle(new Recti(Vec2i.ZERO, size), textureAtlas.getAtlasTexture(), true);
context.drawTextureRectangle(
new Recti(Vec2i.ZERO, size),
textureAtlas.getAtlasTexture(),
true
);
}
//glEnd();
glfwSwapBuffers(window);
@ -141,31 +182,4 @@ public class Window extends BaseWindow {
glfwPollEvents();
}
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 = """
#version 450
layout(location = 1) in vec2 texCoord;
layout(binding = 0) uniform sampler2D tex;
layout(location = 3) uniform ivec2 texOffset;
layout(location = 4) uniform ivec2 texSize;
layout(location = 5) uniform vec3 tint;
out vec4 color;
void main() {
//color = vec4(vec2(texCoord).x/1000.f, 0.2f, 0.7f, 1.0f);
//color = texture(tex, texCoord);
color = texelFetch(tex, ivec2(mod(texCoord, texSize)) + texOffset, 0) * vec4(tint, 1.0f);
}
""";
}

View File

@ -33,7 +33,10 @@ 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);
}
}
@ -60,10 +63,25 @@ abstract public class BaseRenderContext implements IRenderContext {
drawTexture(pixelPos, fullFont.getTexture(0xdb), bgColor);
if(isHalfWidth) {
drawTexture(pixelPos, halfFont.getTexture(terminal.getLeftHalfChar(charPos)), fgColor);
drawTexture(new Vec2i(pixelPos.getX() + halfCharSize.getX(), pixelPos.getY()), halfFont.getTexture(terminal.getRightHalfChar(charPos)), fgColor);
drawTexture(
pixelPos,
halfFont.getTexture(terminal.getLeftHalfChar(charPos)),
fgColor
);
drawTexture(
new Vec2i(
pixelPos.getX() + halfCharSize.getX(),
pixelPos.getY()
),
halfFont.getTexture(terminal.getRightHalfChar(charPos)),
fgColor
);
} else {
drawTexture(pixelPos, fullFont.getTexture(terminal.getChar(charPos)), fgColor);
drawTexture(
pixelPos,
fullFont.getTexture(terminal.getChar(charPos)),
fgColor
);
}
}
}

View File

@ -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);
private final int r, g, b, a;
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 Color(int r, int g, int b) {
@ -45,7 +45,8 @@ public final class Color {
return a;
}
@Override public String toString() {
@Override
public String toString() {
return String.format("#%02X%02X%02X%02X", r, g, b, a);
}
}

View File

@ -20,7 +20,8 @@ public interface IRenderContext {
void drawTextureRectangle(Recti rect, ITexture texture, boolean repeat);
void drawTextureRectangle(Recti rect, ITexture texture, Color color, boolean repeat);
void drawTextureRectangle(Recti rect, ITexture texture, Color color,
boolean repeat);
void drawTerminal(Terminal terminal);

View File

@ -4,6 +4,8 @@ import com.danitheskunk.skunkworks.Vec2i;
public interface ITexture {
Vec2i getSize();
int getWidth();
int getHeight();
}

View File

@ -68,7 +68,8 @@ public class Image {
}
public void drawImage(Image srcImage, Vec2i destPos) {
drawImage(srcImage, destPos, new Recti(Vec2i.ZERO, srcImage.getSize()));
drawImage(srcImage, destPos, new Recti(Vec2i.ZERO,
srcImage.getSize()));
}
public void drawImage(Image srcImage, Vec2i destPos, Recti srcRect) {

View File

@ -1,7 +1,5 @@
package com.danitheskunk.skunkworks.gfx;
import com.danitheskunk.skunkworks.gfx.ITexture;
public class NineSlice {
private ITexture topLeft;
private ITexture topRight;
@ -12,7 +10,10 @@ public class NineSlice {
private ITexture bottom;
private ITexture left;
private ITexture center;
public NineSlice(ITexture topLeft, ITexture topRight, ITexture bottomLeft, ITexture bottomRight, ITexture top, ITexture right, ITexture bottom, ITexture left, ITexture center) {
public NineSlice(ITexture topLeft, ITexture topRight, ITexture bottomLeft,
ITexture bottomRight, ITexture top, ITexture right, ITexture bottom,
ITexture left, ITexture center) {
this.topLeft = topLeft;
this.topRight = topRight;
this.bottomLeft = bottomLeft;

View File

@ -2,7 +2,9 @@ package com.danitheskunk.skunkworks.gfx.font;
public class Cp437 {
//box drawing names... name part priority: (SINGLE/DOUBLE modifier first, only when it changes), CROSS, VERTICAL, HORIZONTAL, TOP, RIGHT, BOTTOM, LEFT
//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;

View File

@ -10,7 +10,6 @@ import java.nio.ByteBuffer;
import java.util.HashMap;
import static org.lwjgl.stb.STBTruetype.*;
import static org.lwjgl.stb.STBTruetype.stbtt_ScaleForPixelHeight;
public class FontTTF implements IFont {
HashMap<Integer, Char> chars;
@ -30,7 +29,8 @@ public class FontTTF implements IFont {
this.info = STBTTFontinfo.create();
if(!stbtt_InitFont(info, buffer)) {
throw new IllegalStateException("Failed to initialize font information.");
throw new IllegalStateException(
"Failed to initialize font information.");
}
//todo: save these
stbtt_GetFontVMetrics(info, ascent, descent, lineGap);
@ -44,8 +44,7 @@ public class FontTTF implements IFont {
}
void cacheChar(int ch) {
if(chars.containsKey(ch))
return;
if(chars.containsKey(ch)) return;
int[] width = {0};
int[] height = {0};
@ -55,7 +54,16 @@ public class FontTTF implements IFont {
int[] leftSideBearing = {0};
ITexture tex;
var bufmono = stbtt_GetCodepointBitmap(info, size, size, ch, width, height, xoff, yoff);
var bufmono = stbtt_GetCodepointBitmap(
info,
size,
size,
ch,
width,
height,
xoff,
yoff
);
if(bufmono != null) {
var buf = ByteBuffer.allocate(bufmono.remaining() * 4);
while(bufmono.hasRemaining()) {
@ -66,12 +74,19 @@ public class FontTTF implements IFont {
buf.put(b);
}
buf.flip();
tex = window.loadTexture(new Image(buf, new Vec2i(width[0], height[0])));
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, (int)(advanceWidth[0] * size), new Vec2i(xoff[0], yoff[0]));
var c = new Char(
tex,
(int) (advanceWidth[0] * size),
new Vec2i(xoff[0], yoff[0])
);
chars.put(ch, c);
}
@ -118,6 +133,7 @@ public class FontTTF implements IFont {
ITexture tex;
int advance;
Vec2i off;
Char(ITexture tex, int advance, Vec2i off) {
this.tex = tex;
this.advance = advance;

View File

@ -5,10 +5,16 @@ import com.danitheskunk.skunkworks.gfx.ITexture;
public interface IFont {
int getLineHeight(int ch);
Vec2i getOffset(int ch);
ITexture getTexture(int ch);
int getXAdvance(int ch);
boolean isCP437();
boolean isMonospace();
Vec2i getMonospaceSize();
}

View File

@ -33,8 +33,10 @@ public class Terminal {
this.fullCharSize = fullFont.getMonospaceSize();
this.halfCharSize = halfFont.getMonospaceSize();
if(fullCharSize.getY() != halfCharSize.getY() || fullCharSize.getX() != halfCharSize.getX() * 2) {
throw new RuntimeException("halfFont needs to be half width of fullFont");
if(fullCharSize.getY() != halfCharSize.getY() ||
fullCharSize.getX() != halfCharSize.getX() * 2) {
throw new RuntimeException(
"halfFont needs to be half width of fullFont");
}
for(int i = 0; i < size.getY() * size.getX(); ++i) {
@ -73,7 +75,8 @@ public class Terminal {
cell.fgColor = foregroundColor;
}
public void setChar(Vec2i pos, int ch, Color foregroundColor, Color backgroundColor) {
public void setChar(Vec2i pos, int ch, Color foregroundColor,
Color backgroundColor) {
var cell = cells.get(vecToPos(pos));
cell.fullChar = ch;
cell.halfWidth = false;
@ -88,7 +91,8 @@ public class Terminal {
cell.halfWidth = true;
}
public void setHalfChars(Vec2i pos, int chLeft, int chRight, Color foregroundColor) {
public void setHalfChars(Vec2i pos, int chLeft, int chRight,
Color foregroundColor) {
var cell = cells.get(vecToPos(pos));
cell.fullChar = chLeft;
cell.secondChar = chRight;
@ -96,7 +100,8 @@ public class Terminal {
cell.fgColor = foregroundColor;
}
public void setHalfChars(Vec2i pos, int chLeft, int chRight, Color foregroundColor, Color backgroundColor) {
public void setHalfChars(Vec2i pos, int chLeft, int chRight,
Color foregroundColor, Color backgroundColor) {
var cell = cells.get(vecToPos(pos));
cell.fullChar = chLeft;
cell.secondChar = chRight;
@ -163,7 +168,8 @@ public class Terminal {
drawString(pos, str, foregroundColor, null);
}
public void drawString(Vec2i pos, String str, Color foregroundColor, Color backgroundColor) {
public void drawString(Vec2i pos, String str, Color foregroundColor,
Color backgroundColor) {
IntBuffer buf;
try {
@ -195,7 +201,8 @@ public class Terminal {
drawHalfString(pos, str, foregroundColor, null);
}
public void drawHalfString(Vec2i pos, String str, Color foregroundColor, Color backgroundColor) {
public void drawHalfString(Vec2i pos, String str, Color foregroundColor,
Color backgroundColor) {
IntBuffer buf;
try {
@ -231,19 +238,30 @@ public class Terminal {
}
}
public void drawHorizontalSingleLine(Vec2i pos, int len, Color foregroundColor) {
public void drawHorizontalSingleLine(Vec2i pos, int len,
Color foregroundColor) {
var x = pos.getX();
var y = pos.getY();
for(int i = 0; i < len; ++i) {
setChar(new Vec2i(x + i, y), Cp437.BOX_SINGLE_HORIZONTAL, foregroundColor);
setChar(
new Vec2i(x + i, y),
Cp437.BOX_SINGLE_HORIZONTAL,
foregroundColor
);
}
}
public void drawHorizontalSingleLine(Vec2i pos, int len, Color foregroundColor, Color backgroundColor) {
public void drawHorizontalSingleLine(Vec2i pos, int len,
Color foregroundColor, Color backgroundColor) {
var x = pos.getX();
var y = pos.getY();
for(int i = 0; i < len; ++i) {
setChar(new Vec2i(x + i, y), Cp437.BOX_SINGLE_HORIZONTAL, foregroundColor, backgroundColor);
setChar(
new Vec2i(x + i, y),
Cp437.BOX_SINGLE_HORIZONTAL,
foregroundColor,
backgroundColor
);
}
}
@ -255,19 +273,30 @@ public class Terminal {
}
}
public void drawHorizontalDoubleLine(Vec2i pos, int len, Color foregroundColor) {
public void drawHorizontalDoubleLine(Vec2i pos, int len,
Color foregroundColor) {
var x = pos.getX();
var y = pos.getY();
for(int i = 0; i < len; ++i) {
setChar(new Vec2i(x + i, y), Cp437.BOX_DOUBLE_HORIZONTAL, foregroundColor);
setChar(
new Vec2i(x + i, y),
Cp437.BOX_DOUBLE_HORIZONTAL,
foregroundColor
);
}
}
public void drawHorizontalDoubleLine(Vec2i pos, int len, Color foregroundColor, Color backgroundColor) {
public void drawHorizontalDoubleLine(Vec2i pos, int len,
Color foregroundColor, Color backgroundColor) {
var x = pos.getX();
var y = pos.getY();
for(int i = 0; i < len; ++i) {
setChar(new Vec2i(x + i, y), Cp437.BOX_DOUBLE_HORIZONTAL, foregroundColor, backgroundColor);
setChar(
new Vec2i(x + i, y),
Cp437.BOX_DOUBLE_HORIZONTAL,
foregroundColor,
backgroundColor
);
}
}
@ -279,19 +308,30 @@ public class Terminal {
}
}
public void drawVerticalSingleLine(Vec2i pos, int len, Color foregroundColor) {
public void drawVerticalSingleLine(Vec2i pos, int len,
Color foregroundColor) {
var x = pos.getX();
var y = pos.getY();
for(int i = 0; i < len; ++i) {
setChar(new Vec2i(x, y + i), Cp437.BOX_SINGLE_VERTICAL, foregroundColor);
setChar(
new Vec2i(x, y + i),
Cp437.BOX_SINGLE_VERTICAL,
foregroundColor
);
}
}
public void drawVerticalSingleLine(Vec2i pos, int len, Color foregroundColor, Color backgroundColor) {
public void drawVerticalSingleLine(Vec2i pos, int len,
Color foregroundColor, Color backgroundColor) {
var x = pos.getX();
var y = pos.getY();
for(int i = 0; i < len; ++i) {
setChar(new Vec2i(x, y + i), Cp437.BOX_SINGLE_VERTICAL, foregroundColor, backgroundColor);
setChar(
new Vec2i(x, y + i),
Cp437.BOX_SINGLE_VERTICAL,
foregroundColor,
backgroundColor
);
}
}
@ -303,60 +343,153 @@ public class Terminal {
}
}
public void drawVerticalDoubleLine(Vec2i pos, int len, Color foregroundColor) {
public void drawVerticalDoubleLine(Vec2i pos, int len,
Color foregroundColor) {
var x = pos.getX();
var y = pos.getY();
for(int i = 0; i < len; ++i) {
setChar(new Vec2i(x, y + i), Cp437.BOX_DOUBLE_VERTICAL, foregroundColor);
setChar(
new Vec2i(x, y + i),
Cp437.BOX_DOUBLE_VERTICAL,
foregroundColor
);
}
}
public void drawVerticalDoubleLine(Vec2i pos, int len, Color foregroundColor, Color backgroundColor) {
public void drawVerticalDoubleLine(Vec2i pos, int len,
Color foregroundColor, Color backgroundColor) {
var x = pos.getX();
var y = pos.getY();
for(int i = 0; i < len; ++i) {
setChar(new Vec2i(x, y + i), Cp437.BOX_DOUBLE_VERTICAL, foregroundColor, backgroundColor);
setChar(
new Vec2i(x, y + i),
Cp437.BOX_DOUBLE_VERTICAL,
foregroundColor,
backgroundColor
);
}
}
public void drawBoxSingle(Recti rect) {
var pos = rect.getPos();
setChar(pos, Cp437.BOX_SINGLE_RIGHT_BOTTOM);
setChar(Vec2i.add(pos, new Vec2i(rect.getWidth() - 1, 0)), Cp437.BOX_SINGLE_BOTTOM_LEFT);
setChar(Vec2i.add(pos, new Vec2i(0, rect.getHeight() - 1)), Cp437.BOX_SINGLE_TOP_RIGHT);
setChar(Vec2i.add(pos, new Vec2i(rect.getWidth() - 1, rect.getHeight() - 1)), Cp437.BOX_SINGLE_TOP_LEFT);
drawHorizontalSingleLine(Vec2i.add(pos, new Vec2i(1, 0)), rect.getWidth() - 2);
drawHorizontalSingleLine(Vec2i.add(pos, new Vec2i(1, rect.getHeight() - 1)), rect.getWidth() - 2);
drawVerticalSingleLine(Vec2i.add(pos, new Vec2i(0, 1)), rect.getHeight() - 2);
drawVerticalSingleLine(Vec2i.add(pos, new Vec2i(rect.getWidth() - 1, 1)), rect.getHeight() - 2);
setChar(
Vec2i.add(pos, new Vec2i(rect.getWidth() - 1, 0)),
Cp437.BOX_SINGLE_BOTTOM_LEFT
);
setChar(
Vec2i.add(pos, new Vec2i(0, rect.getHeight() - 1)),
Cp437.BOX_SINGLE_TOP_RIGHT
);
setChar(Vec2i.add(
pos,
new Vec2i(rect.getWidth() - 1, rect.getHeight() - 1)
), Cp437.BOX_SINGLE_TOP_LEFT);
drawHorizontalSingleLine(
Vec2i.add(pos, new Vec2i(1, 0)),
rect.getWidth() - 2
);
drawHorizontalSingleLine(Vec2i.add(
pos,
new Vec2i(1, rect.getHeight() - 1)
), rect.getWidth() - 2);
drawVerticalSingleLine(
Vec2i.add(pos, new Vec2i(0, 1)),
rect.getHeight() - 2
);
drawVerticalSingleLine(Vec2i.add(
pos,
new Vec2i(rect.getWidth() - 1, 1)
), rect.getHeight() - 2);
}
public void drawBoxSingle(Recti rect, Color foregroundColor) {
var pos = rect.getPos();
setChar(pos, Cp437.BOX_SINGLE_RIGHT_BOTTOM, foregroundColor);
setChar(Vec2i.add(pos, new Vec2i(rect.getWidth() - 1, 0)), Cp437.BOX_SINGLE_BOTTOM_LEFT, foregroundColor);
setChar(Vec2i.add(pos, new Vec2i(0, rect.getHeight() - 1)), Cp437.BOX_SINGLE_TOP_RIGHT, foregroundColor);
setChar(Vec2i.add(pos, new Vec2i(rect.getWidth() - 1, rect.getHeight() - 1)), Cp437.BOX_SINGLE_TOP_LEFT, foregroundColor);
drawHorizontalSingleLine(Vec2i.add(pos, new Vec2i(1, 0)), rect.getWidth() - 2, foregroundColor);
drawHorizontalSingleLine(Vec2i.add(pos, new Vec2i(1, rect.getHeight() - 1)), rect.getWidth() - 2, foregroundColor);
drawVerticalSingleLine(Vec2i.add(pos, new Vec2i(0, 1)), rect.getHeight() - 2, foregroundColor);
drawVerticalSingleLine(Vec2i.add(pos, new Vec2i(rect.getWidth() - 1, 1)), rect.getHeight() - 2, foregroundColor);
setChar(
Vec2i.add(pos, new Vec2i(rect.getWidth() - 1, 0)),
Cp437.BOX_SINGLE_BOTTOM_LEFT,
foregroundColor
);
setChar(
Vec2i.add(pos, new Vec2i(0, rect.getHeight() - 1)),
Cp437.BOX_SINGLE_TOP_RIGHT,
foregroundColor
);
setChar(Vec2i.add(
pos,
new Vec2i(rect.getWidth() - 1, rect.getHeight() - 1)
), Cp437.BOX_SINGLE_TOP_LEFT, foregroundColor);
drawHorizontalSingleLine(
Vec2i.add(pos, new Vec2i(1, 0)),
rect.getWidth() - 2,
foregroundColor
);
drawHorizontalSingleLine(Vec2i.add(
pos,
new Vec2i(1, rect.getHeight() - 1)
), rect.getWidth() - 2, foregroundColor);
drawVerticalSingleLine(
Vec2i.add(pos, new Vec2i(0, 1)),
rect.getHeight() - 2,
foregroundColor
);
drawVerticalSingleLine(Vec2i.add(
pos,
new Vec2i(rect.getWidth() - 1, 1)
), rect.getHeight() - 2, foregroundColor);
}
public void drawBoxSingle(Recti rect, Color foregroundColor, Color backgroundColor) {
public void drawBoxSingle(Recti rect, Color foregroundColor,
Color backgroundColor) {
drawBoxSingle(rect, foregroundColor, backgroundColor, true);
}
public void drawBoxSingle(Recti rect, Color foregroundColor, Color backgroundColor, boolean fill) {
public void drawBoxSingle(Recti rect, Color foregroundColor,
Color backgroundColor, boolean fill) {
var pos = rect.getPos();
setChar(pos, Cp437.BOX_SINGLE_RIGHT_BOTTOM, foregroundColor, backgroundColor);
setChar(Vec2i.add(pos, new Vec2i(rect.getWidth() - 1, 0)), Cp437.BOX_SINGLE_BOTTOM_LEFT, foregroundColor, backgroundColor);
setChar(Vec2i.add(pos, new Vec2i(0, rect.getHeight() - 1)), Cp437.BOX_SINGLE_TOP_RIGHT, foregroundColor, backgroundColor);
setChar(Vec2i.add(pos, new Vec2i(rect.getWidth() - 1, rect.getHeight() - 1)), Cp437.BOX_SINGLE_TOP_LEFT, foregroundColor, backgroundColor);
drawHorizontalSingleLine(Vec2i.add(pos, new Vec2i(1, 0)), rect.getWidth() - 2, foregroundColor, backgroundColor);
drawHorizontalSingleLine(Vec2i.add(pos, new Vec2i(1, rect.getHeight() - 1)), rect.getWidth() - 2, foregroundColor, backgroundColor);
drawVerticalSingleLine(Vec2i.add(pos, new Vec2i(0, 1)), rect.getHeight() - 2, foregroundColor, backgroundColor);
drawVerticalSingleLine(Vec2i.add(pos, new Vec2i(rect.getWidth() - 1, 1)), rect.getHeight() - 2, foregroundColor, backgroundColor);
setChar(
pos,
Cp437.BOX_SINGLE_RIGHT_BOTTOM,
foregroundColor,
backgroundColor
);
setChar(
Vec2i.add(pos, new Vec2i(rect.getWidth() - 1, 0)),
Cp437.BOX_SINGLE_BOTTOM_LEFT,
foregroundColor,
backgroundColor
);
setChar(
Vec2i.add(pos, new Vec2i(0, rect.getHeight() - 1)),
Cp437.BOX_SINGLE_TOP_RIGHT,
foregroundColor,
backgroundColor
);
setChar(Vec2i.add(
pos,
new Vec2i(rect.getWidth() - 1, rect.getHeight() - 1)
), Cp437.BOX_SINGLE_TOP_LEFT, foregroundColor, backgroundColor);
drawHorizontalSingleLine(
Vec2i.add(pos, new Vec2i(1, 0)),
rect.getWidth() - 2,
foregroundColor,
backgroundColor
);
drawHorizontalSingleLine(Vec2i.add(
pos,
new Vec2i(1, rect.getHeight() - 1)
), rect.getWidth() - 2, foregroundColor, backgroundColor);
drawVerticalSingleLine(
Vec2i.add(pos, new Vec2i(0, 1)),
rect.getHeight() - 2,
foregroundColor,
backgroundColor
);
drawVerticalSingleLine(Vec2i.add(
pos,
new Vec2i(rect.getWidth() - 1, 1)
), rect.getHeight() - 2, foregroundColor, backgroundColor);
if(fill) {
//todo: use draw rect
@ -364,7 +497,10 @@ public class Terminal {
var y = rect.getY() + 1;
for(int iy = 0; iy < rect.getWidth() - 2; ++iy) {
for(int ix = 0; ix < rect.getWidth() - 2; ++ix) {
setBackgroundColor(new Vec2i(x + ix, y + iy), backgroundColor);
setBackgroundColor(
new Vec2i(x + ix, y + iy),
backgroundColor
);
}
}
}
@ -374,41 +510,123 @@ public class Terminal {
public void drawBoxDouble(Recti rect) {
var pos = rect.getPos();
setChar(pos, Cp437.BOX_DOUBLE_RIGHT_BOTTOM);
setChar(Vec2i.add(pos, new Vec2i(rect.getWidth() - 1, 0)), Cp437.BOX_DOUBLE_BOTTOM_LEFT);
setChar(Vec2i.add(pos, new Vec2i(0, rect.getHeight() - 1)), Cp437.BOX_DOUBLE_TOP_RIGHT);
setChar(Vec2i.add(pos, new Vec2i(rect.getWidth() - 1, rect.getHeight() - 1)), Cp437.BOX_DOUBLE_TOP_LEFT);
drawHorizontalDoubleLine(Vec2i.add(pos, new Vec2i(1, 0)), rect.getWidth() - 2);
drawHorizontalDoubleLine(Vec2i.add(pos, new Vec2i(1, rect.getHeight() - 1)), rect.getWidth() - 2);
drawVerticalDoubleLine(Vec2i.add(pos, new Vec2i(0, 1)), rect.getHeight() - 2);
drawVerticalDoubleLine(Vec2i.add(pos, new Vec2i(rect.getWidth() - 1, 1)), rect.getHeight() - 2);
setChar(
Vec2i.add(pos, new Vec2i(rect.getWidth() - 1, 0)),
Cp437.BOX_DOUBLE_BOTTOM_LEFT
);
setChar(
Vec2i.add(pos, new Vec2i(0, rect.getHeight() - 1)),
Cp437.BOX_DOUBLE_TOP_RIGHT
);
setChar(Vec2i.add(
pos,
new Vec2i(rect.getWidth() - 1, rect.getHeight() - 1)
), Cp437.BOX_DOUBLE_TOP_LEFT);
drawHorizontalDoubleLine(
Vec2i.add(pos, new Vec2i(1, 0)),
rect.getWidth() - 2
);
drawHorizontalDoubleLine(Vec2i.add(
pos,
new Vec2i(1, rect.getHeight() - 1)
), rect.getWidth() - 2);
drawVerticalDoubleLine(
Vec2i.add(pos, new Vec2i(0, 1)),
rect.getHeight() - 2
);
drawVerticalDoubleLine(Vec2i.add(
pos,
new Vec2i(rect.getWidth() - 1, 1)
), rect.getHeight() - 2);
}
public void drawBoxDouble(Recti rect, Color foregroundColor) {
var pos = rect.getPos();
setChar(pos, Cp437.BOX_DOUBLE_RIGHT_BOTTOM, foregroundColor);
setChar(Vec2i.add(pos, new Vec2i(rect.getWidth() - 1, 0)), Cp437.BOX_DOUBLE_BOTTOM_LEFT, foregroundColor);
setChar(Vec2i.add(pos, new Vec2i(0, rect.getHeight() - 1)), Cp437.BOX_DOUBLE_TOP_RIGHT, foregroundColor);
setChar(Vec2i.add(pos, new Vec2i(rect.getWidth() - 1, rect.getHeight() - 1)), Cp437.BOX_DOUBLE_TOP_LEFT, foregroundColor);
drawHorizontalDoubleLine(Vec2i.add(pos, new Vec2i(1, 0)), rect.getWidth() - 2, foregroundColor);
drawHorizontalDoubleLine(Vec2i.add(pos, new Vec2i(1, rect.getHeight() - 1)), rect.getWidth() - 2, foregroundColor);
drawVerticalDoubleLine(Vec2i.add(pos, new Vec2i(0, 1)), rect.getHeight() - 2, foregroundColor);
drawVerticalDoubleLine(Vec2i.add(pos, new Vec2i(rect.getWidth() - 1, 1)), rect.getHeight() - 2, foregroundColor);
setChar(
Vec2i.add(pos, new Vec2i(rect.getWidth() - 1, 0)),
Cp437.BOX_DOUBLE_BOTTOM_LEFT,
foregroundColor
);
setChar(
Vec2i.add(pos, new Vec2i(0, rect.getHeight() - 1)),
Cp437.BOX_DOUBLE_TOP_RIGHT,
foregroundColor
);
setChar(Vec2i.add(
pos,
new Vec2i(rect.getWidth() - 1, rect.getHeight() - 1)
), Cp437.BOX_DOUBLE_TOP_LEFT, foregroundColor);
drawHorizontalDoubleLine(
Vec2i.add(pos, new Vec2i(1, 0)),
rect.getWidth() - 2,
foregroundColor
);
drawHorizontalDoubleLine(Vec2i.add(
pos,
new Vec2i(1, rect.getHeight() - 1)
), rect.getWidth() - 2, foregroundColor);
drawVerticalDoubleLine(
Vec2i.add(pos, new Vec2i(0, 1)),
rect.getHeight() - 2,
foregroundColor
);
drawVerticalDoubleLine(Vec2i.add(
pos,
new Vec2i(rect.getWidth() - 1, 1)
), rect.getHeight() - 2, foregroundColor);
}
public void drawBoxDouble(Recti rect, Color foregroundColor, Color backgroundColor) {
public void drawBoxDouble(Recti rect, Color foregroundColor,
Color backgroundColor) {
drawBoxDouble(rect, foregroundColor, backgroundColor, true);
}
public void drawBoxDouble(Recti rect, Color foregroundColor, Color backgroundColor, boolean fill) {
public void drawBoxDouble(Recti rect, Color foregroundColor,
Color backgroundColor, boolean fill) {
var pos = rect.getPos();
setChar(pos, Cp437.BOX_DOUBLE_RIGHT_BOTTOM, foregroundColor, backgroundColor);
setChar(Vec2i.add(pos, new Vec2i(rect.getWidth() - 1, 0)), Cp437.BOX_DOUBLE_BOTTOM_LEFT, foregroundColor, backgroundColor);
setChar(Vec2i.add(pos, new Vec2i(0, rect.getHeight() - 1)), Cp437.BOX_DOUBLE_TOP_RIGHT, foregroundColor, backgroundColor);
setChar(Vec2i.add(pos, new Vec2i(rect.getWidth() - 1, rect.getHeight() - 1)), Cp437.BOX_DOUBLE_TOP_LEFT, foregroundColor, backgroundColor);
drawHorizontalDoubleLine(Vec2i.add(pos, new Vec2i(1, 0)), rect.getWidth() - 2, foregroundColor, backgroundColor);
drawHorizontalDoubleLine(Vec2i.add(pos, new Vec2i(1, rect.getHeight() - 1)), rect.getWidth() - 2, foregroundColor, backgroundColor);
drawVerticalDoubleLine(Vec2i.add(pos, new Vec2i(0, 1)), rect.getHeight() - 2, foregroundColor, backgroundColor);
drawVerticalDoubleLine(Vec2i.add(pos, new Vec2i(rect.getWidth() - 1, 1)), rect.getHeight() - 2, foregroundColor, backgroundColor);
setChar(
pos,
Cp437.BOX_DOUBLE_RIGHT_BOTTOM,
foregroundColor,
backgroundColor
);
setChar(
Vec2i.add(pos, new Vec2i(rect.getWidth() - 1, 0)),
Cp437.BOX_DOUBLE_BOTTOM_LEFT,
foregroundColor,
backgroundColor
);
setChar(
Vec2i.add(pos, new Vec2i(0, rect.getHeight() - 1)),
Cp437.BOX_DOUBLE_TOP_RIGHT,
foregroundColor,
backgroundColor
);
setChar(Vec2i.add(
pos,
new Vec2i(rect.getWidth() - 1, rect.getHeight() - 1)
), Cp437.BOX_DOUBLE_TOP_LEFT, foregroundColor, backgroundColor);
drawHorizontalDoubleLine(
Vec2i.add(pos, new Vec2i(1, 0)),
rect.getWidth() - 2,
foregroundColor,
backgroundColor
);
drawHorizontalDoubleLine(Vec2i.add(
pos,
new Vec2i(1, rect.getHeight() - 1)
), rect.getWidth() - 2, foregroundColor, backgroundColor);
drawVerticalDoubleLine(
Vec2i.add(pos, new Vec2i(0, 1)),
rect.getHeight() - 2,
foregroundColor,
backgroundColor
);
drawVerticalDoubleLine(Vec2i.add(
pos,
new Vec2i(rect.getWidth() - 1, 1)
), rect.getHeight() - 2, foregroundColor, backgroundColor);
if(fill) {
//todo: use draw rect
@ -416,7 +634,10 @@ public class Terminal {
var y = rect.getY() + 1;
for(int iy = 0; iy < rect.getWidth() - 2; ++iy) {
for(int ix = 0; ix < rect.getWidth() - 2; ++ix) {
setBackgroundColor(new Vec2i(x + ix, y + iy), backgroundColor);
setBackgroundColor(
new Vec2i(x + ix, y + iy),
backgroundColor
);
}
}
}

View File

@ -3,8 +3,9 @@ package com.danitheskunk.skunkworks.nodes;
import com.danitheskunk.skunkworks.Vec2f;
import com.danitheskunk.skunkworks.gfx.IRenderContext;
import java.sql.Array;
import java.util.*;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
//todo: figure out the whole translation position thingie
@ -47,8 +48,7 @@ public class Node implements Iterable<Node> {
}
public Vec2f getAbsolutePos() {
if(parent == null)
return pos;
if(parent == null) return pos;
return Vec2f.add(parent.getAbsolutePos(), pos);
}

View File

@ -1,6 +1,5 @@
package com.danitheskunk.skunkworks.nodes;
import com.danitheskunk.skunkworks.Vec2f;
import com.danitheskunk.skunkworks.gfx.IRenderContext;
import com.danitheskunk.skunkworks.gfx.ITexture;

View File

@ -8,34 +8,45 @@ import com.sun.jna.platform.win32.WinNT;
import com.sun.jna.win32.W32APIOptions;
public interface Dwm extends Library {
Dwm INSTANCE = Native.load("dwmapi", Dwm.class, W32APIOptions.DEFAULT_OPTIONS);
Dwm INSTANCE = Native.load(
"dwmapi",
Dwm.class,
W32APIOptions.DEFAULT_OPTIONS
);
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_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);
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
WinDef.DWORD DWMWCP_DEFAULT = new WinDef.DWORD(0);
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_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 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);
}

View File

@ -14,6 +14,11 @@ public class MARGINS extends Structure implements Structure.ByReference {
@Override
protected List<String> getFieldOrder() {
return Arrays.asList("cxLeftWidth", "cxRightWidth", "cyTopHeight", "cyBottomHeight");
return Arrays.asList(
"cxLeftWidth",
"cxRightWidth",
"cyTopHeight",
"cyBottomHeight"
);
}
}

View File

@ -5,6 +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 int cbSize;
public WinDef.RECT rcTitleBar;
public int[] rgstate;
@ -13,15 +22,4 @@ public class TITLEBARINFO extends Structure {
rgstate = new int[CCHILDREN_TITLEBAR + 1];
cbSize = size();
}
// 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;
}

View File

@ -6,7 +6,11 @@ import com.sun.jna.platform.win32.WinDef;
import com.sun.jna.win32.W32APIOptions;
public interface User32Extra extends User32 {
User32Extra INSTANCE = Native.load("user32", User32Extra.class, W32APIOptions.DEFAULT_OPTIONS);
User32Extra INSTANCE = Native.load(
"user32",
User32Extra.class,
W32APIOptions.DEFAULT_OPTIONS
);
// States
int STATE_SYSTEM_FOCUSABLE = 0x00100000;
@ -44,7 +48,11 @@ public interface User32Extra extends User32 {
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);
long WS_EX_PALETTEWINDOW = (
WS_EX_WINDOWEDGE |
WS_EX_TOOLWINDOW |
WS_EX_TOPMOST
);
int WH_SHELL = 10;
@ -72,5 +80,6 @@ public interface User32Extra extends User32 {
HCURSOR GetCursor();
WinDef.HWND GetTopWindow(HWND hWnd);
WinDef.HWND GetWindow(HWND hWnd, int flag);
}

View File

@ -4,8 +4,13 @@ import com.sun.jna.Native;
import com.sun.jna.platform.win32.WinUser;
import com.sun.jna.win32.W32APIOptions;
public interface WinUserExtra extends WinUser, com.sun.jna.win32.StdCallLibrary {
WinUserExtra INSTANCE = Native.load("user32", WinUserExtra.class, W32APIOptions.DEFAULT_OPTIONS);
public interface WinUserExtra extends WinUser,
com.sun.jna.win32.StdCallLibrary {
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);

View File

@ -18,35 +18,151 @@ public class Window {
this.hwnd = hwnd;
}
//static functions
public static List<Window> getAllVisible() {
var user32 = User32Extra.INSTANCE;
var windows = new ArrayList<Window>();
user32.EnumWindows(new WinUser.WNDENUMPROC() {
@Override
public boolean callback(WinDef.HWND hwnd, Pointer pointer) {
var window = new Window(hwnd);
if(window.isInAltTabList()) windows.add(window);
return true;
}
}, null);
return windows;
}
public static void messageLoop() {
var user32 = User32Extra.INSTANCE;
var msg = new WinUser.MSG();
while(user32.GetMessage(msg, null, 0, 0) != 0) {
System.out.println("msg pump");
user32.TranslateMessage(msg);
user32.DispatchMessage(msg);
if(msg.message == User32Extra.WM_TIMER) return;
}
}
public static void messageTick() {
//todo: check if this even works (switch to getmessage, and add timer
// function?)
var user32 = User32Extra.INSTANCE;
var msg = new WinUser.MSG();
//while(user32.PeekMessage(msg, null, 0, 0, User32Extra.PM_NOREMOVE)) {
user32.GetMessage(msg, null, 0, 0);
System.out.println("msg pump");
user32.TranslateMessage(msg);
user32.DispatchMessage(msg);
//}
}
public static void onKey() {
var user32 = User32Extra.INSTANCE;
var kernel32 = Kernel32.INSTANCE;
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,
lparam.toPointer()
);
System.out.println(kb.vkCode);
switch(wparam.intValue()) {
case User32Extra.WM_KEYDOWN:
System.out.println("WM_KEYDOWN");
break;
case User32Extra.WM_KEYUP:
System.out.println("WM_KEYUP");
break;
case User32Extra.WM_SYSKEYDOWN:
System.out.println("WM_SYSKEYDOWN");
break;
case User32Extra.WM_SYSKEYUP:
System.out.println("WM_SYSKEYUP");
break;
}
System.out.println("got some message a");
return user32.CallNextHookEx(null, nCode, wparam, lparam);
}
},
null,
0
);
if(res == null) {
throw new RuntimeException("Couldn't setwindowhookex: " +
Native.getLastError());
}
}
public static void onNewWindow() {
var user32 = User32Extra.INSTANCE;
var kernel32 = Kernel32.INSTANCE;
var hmod = kernel32.GetModuleHandle("kernel32.dll");
//todo: try RegisterShellHookWindow instead
var res = user32.SetWindowsHookEx(
User32Extra.WH_SHELL,
new WinUser.HOOKPROC() {
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");
}
return new WinDef.LRESULT(0);
}
},
hmod,
0
);
if(res == null) {
throw new RuntimeException("Couldn't setwindowhookex: " +
Native.getLastError());
}
}
public static void onTimer(int ms) {
WinUserExtra.INSTANCE.SetTimer(null, null, new WinDef.UINT(ms), null);
}
public void debugPrintStyles() {
var str = new StringBuilder();
var style = getStyle();
str.append("Window Styles: ");
if((style & User32.WS_BORDER) != 0) str.append("ws_border, ");
if((style & User32.WS_CAPTION) != 0) str.append("ws_caption, ");
if((style & User32.WS_CHILD) != 0) str.append("ws_child, ");
if((style & User32.WS_CHILDWINDOW) != 0) str.append("ws_childwindow, ");
if((style & User32.WS_CLIPCHILDREN) != 0) str.append("ws_clipchildren, ");
if((style & User32.WS_CLIPSIBLINGS) != 0) str.append("ws_clipsiblings, ");
if((style & User32.WS_DISABLED) != 0) str.append("ws_disabled, ");
if((style & User32.WS_DLGFRAME) != 0) str.append("ws_dlgframe, ");
if((style & User32.WS_GROUP) != 0) str.append("ws_group, ");
if((style & User32.WS_HSCROLL) != 0) str.append("ws_hscroll, ");
if((style & User32.WS_ICONIC) != 0) str.append("ws_iconic, ");
if((style & User32.WS_MAXIMIZE) != 0) str.append("ws_maximize, ");
if((style & User32.WS_MAXIMIZEBOX) != 0) str.append("ws_maximizebox, ");
if((style & User32.WS_MINIMIZE) != 0) str.append("ws_minimize, ");
if((style & User32.WS_MINIMIZEBOX) != 0) str.append("ws_minimizebox, ");
if((style & User32.WS_OVERLAPPED) != 0) str.append("ws_overlapped, ");
if((style & User32.WS_POPUP) != 0) str.append("ws_popup, ");
if((style & User32.WS_SIZEBOX) != 0) str.append("ws_sizebox, ");
if((style & User32.WS_SYSMENU) != 0) str.append("ws_sysmenu, ");
if((style & User32.WS_TABSTOP) != 0) str.append("ws_tabstop, ");
if((style & User32.WS_THICKFRAME) != 0) str.append("ws_thickframe, ");
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, ");
if((style & User32.WS_BORDER) != 0) str.append("ws_border, ");
if((style & User32.WS_CAPTION) != 0) str.append("ws_caption, ");
if((style & User32.WS_CHILD) != 0) str.append("ws_child, ");
if((style & User32.WS_CHILDWINDOW) != 0) str.append("ws_childwindow," +
" ");
if((style & User32.WS_CLIPCHILDREN) != 0)
str.append("ws_clipchildren, ");
if((style & User32.WS_CLIPSIBLINGS) != 0)
str.append("ws_clipsiblings, ");
if((style & User32.WS_DISABLED) != 0) str.append("ws_disabled, ");
if((style & User32.WS_DLGFRAME) != 0) str.append("ws_dlgframe, ");
if((style & User32.WS_GROUP) != 0) str.append("ws_group, ");
if((style & User32.WS_HSCROLL) != 0) str.append("ws_hscroll, ");
if((style & User32.WS_ICONIC) != 0) str.append("ws_iconic, ");
if((style & User32.WS_MAXIMIZE) != 0) str.append("ws_maximize, ");
if((style & User32.WS_MAXIMIZEBOX) != 0) str.append("ws_maximizebox," +
" ");
if((style & User32.WS_MINIMIZE) != 0) str.append("ws_minimize, ");
if((style & User32.WS_MINIMIZEBOX) != 0) str.append("ws_minimizebox," +
" ");
if((style & User32.WS_OVERLAPPED) != 0) str.append("ws_overlapped, ");
if((style & User32.WS_POPUP) != 0) str.append("ws_popup, ");
if((style & User32.WS_SIZEBOX) != 0) str.append("ws_sizebox, ");
if((style & User32.WS_SYSMENU) != 0) str.append("ws_sysmenu, ");
if((style & User32.WS_TABSTOP) != 0) str.append("ws_tabstop, ");
if((style & User32.WS_THICKFRAME) != 0) str.append("ws_thickframe, ");
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());
}
@ -54,39 +170,68 @@ public class Window {
var str = new StringBuilder();
var style = getStyleEx();
str.append("Window Styles EX: ");
if((style & User32Extra.WS_EX_ACCEPTFILES) != 0) str.append("ws_ex_acceptfiles, ");
if((style & User32Extra.WS_EX_APPWINDOW) != 0) str.append("ws_ex_appwindow, ");
if((style & User32Extra.WS_EX_CLIENTEDGE) != 0) str.append("ws_ex_clientedge, ");
if((style & User32Extra.WS_EX_COMPOSITED) != 0) str.append("ws_ex_composited, ");
if((style & User32Extra.WS_EX_CONTEXTHELP) != 0) str.append("ws_ex_contexthelp, ");
if((style & User32Extra.WS_EX_CONTROLPARENT) != 0) str.append("ws_ex_controlparent, ");
if((style & User32Extra.WS_EX_DLGMODALFRAME) != 0) str.append("ws_ex_dlgmodalframe, ");
if((style & User32Extra.WS_EX_LAYERED) != 0) str.append("ws_ex_layered, ");
if((style & User32Extra.WS_EX_LAYOUTRTL) != 0) str.append("ws_ex_layoutrtl, ");
if((style & User32Extra.WS_EX_LEFT) != 0) str.append("ws_ex_left, ");
if((style & User32Extra.WS_EX_LEFTSCROLLBAR) != 0) str.append("ws_ex_leftscrollbar, ");
if((style & User32Extra.WS_EX_LTRREADING) != 0) str.append("ws_ex_ltrreading, ");
if((style & User32Extra.WS_EX_MDICHILD) != 0) str.append("ws_ex_mdichild, ");
if((style & User32Extra.WS_EX_NOACTIVATE) != 0) str.append("ws_ex_noactivate, ");
if((style & User32Extra.WS_EX_NOINHERITLAYOUT) != 0) str.append("ws_ex_noinheritedlayout, ");
if((style & User32Extra.WS_EX_NOPARENTNOTIFY) != 0) str.append("ws_ex_noparentnotify, ");
if((style & User32Extra.WS_EX_NOREDIRECTIONBITMAP) != 0) str.append("ws_ex_noredirectionbitmap, ");
if((style & User32Extra.WS_EX_RIGHT) != 0) str.append("ws_ex_right, ");
if((style & User32Extra.WS_EX_RIGHTSCROLLBAR) != 0) str.append("ws_ex_rightscrollbar, ");
if((style & User32Extra.WS_EX_RTLREADING) != 0) str.append("ws_ex_rtlreading, ");
if((style & User32Extra.WS_EX_STATICEDGE) != 0) str.append("ws_ex_staticedge, ");
if((style & User32Extra.WS_EX_TOOLWINDOW) != 0) str.append("ws_ex_toolwindow, ");
if((style & User32Extra.WS_EX_TOPMOST) != 0) str.append("ws_ex_topmost, ");
if((style & User32Extra.WS_EX_TRANSPARENT) != 0) str.append("ws_ex_transparent, ");
if((style & User32Extra.WS_EX_WINDOWEDGE) != 0) str.append("ws_ex_windowedge, ");
if((style & User32Extra.WS_EX_ACCEPTFILES) != 0) str.append(
"ws_ex_acceptfiles, ");
if((style & User32Extra.WS_EX_APPWINDOW) != 0) str.append(
"ws_ex_appwindow, ");
if((style & User32Extra.WS_EX_CLIENTEDGE) != 0) str.append(
"ws_ex_clientedge, ");
if((style & User32Extra.WS_EX_COMPOSITED) != 0) str.append(
"ws_ex_composited, ");
if((style & User32Extra.WS_EX_CONTEXTHELP) != 0) str.append(
"ws_ex_contexthelp, ");
if((style & User32Extra.WS_EX_CONTROLPARENT) != 0) str.append(
"ws_ex_controlparent, ");
if((style & User32Extra.WS_EX_DLGMODALFRAME) != 0) str.append(
"ws_ex_dlgmodalframe, ");
if((style & User32Extra.WS_EX_LAYERED) != 0) str.append(
"ws_ex_layered, ");
if((style & User32Extra.WS_EX_LAYOUTRTL) != 0) str.append(
"ws_ex_layoutrtl, ");
if((style & User32Extra.WS_EX_LEFT) != 0) str.append("ws_ex_left, ");
if((style & User32Extra.WS_EX_LEFTSCROLLBAR) != 0) str.append(
"ws_ex_leftscrollbar, ");
if((style & User32Extra.WS_EX_LTRREADING) != 0) str.append(
"ws_ex_ltrreading, ");
if((style & User32Extra.WS_EX_MDICHILD) != 0) str.append(
"ws_ex_mdichild, ");
if((style & User32Extra.WS_EX_NOACTIVATE) != 0) str.append(
"ws_ex_noactivate, ");
if((style & User32Extra.WS_EX_NOINHERITLAYOUT) != 0) str.append(
"ws_ex_noinheritedlayout, ");
if((style & User32Extra.WS_EX_NOPARENTNOTIFY) != 0) str.append(
"ws_ex_noparentnotify, ");
if((style & User32Extra.WS_EX_NOREDIRECTIONBITMAP) != 0) str.append(
"ws_ex_noredirectionbitmap, ");
if((style & User32Extra.WS_EX_RIGHT) != 0) str.append("ws_ex_right, ");
if((style & User32Extra.WS_EX_RIGHTSCROLLBAR) != 0) str.append(
"ws_ex_rightscrollbar, ");
if((style & User32Extra.WS_EX_RTLREADING) != 0) str.append(
"ws_ex_rtlreading, ");
if((style & User32Extra.WS_EX_STATICEDGE) != 0) str.append(
"ws_ex_staticedge, ");
if((style & User32Extra.WS_EX_TOOLWINDOW) != 0) str.append(
"ws_ex_toolwindow, ");
if((style & User32Extra.WS_EX_TOPMOST) != 0) str.append(
"ws_ex_topmost, ");
if((style & User32Extra.WS_EX_TRANSPARENT) != 0) str.append(
"ws_ex_transparent, ");
if((style & User32Extra.WS_EX_WINDOWEDGE) != 0) str.append(
"ws_ex_windowedge, ");
System.out.println(str.toString());
}
public void setBorder(boolean border) {
var STYLES = User32Extra.WS_CAPTION | User32Extra.WS_THICKFRAME | User32Extra.WS_MINIMIZEBOX | User32Extra.WS_SYSMENU;
//var STYLES = User32Extra.WS_THICKFRAME | User32Extra.WS_MINIMIZEBOX | User32Extra.WS_SYSMENU;
var STYLESEX = User32Extra.WS_EX_DLGMODALFRAME | User32Extra.WS_EX_CLIENTEDGE | User32Extra.WS_EX_STATICEDGE;
var STYLES = User32Extra.WS_CAPTION |
User32Extra.WS_THICKFRAME |
User32Extra.WS_MINIMIZEBOX |
User32Extra.WS_SYSMENU;
//var STYLES = User32Extra.WS_THICKFRAME | User32Extra.WS_MINIMIZEBOX
// | User32Extra.WS_SYSMENU;
var STYLESEX = User32Extra.WS_EX_DLGMODALFRAME |
User32Extra.WS_EX_CLIENTEDGE |
User32Extra.WS_EX_STATICEDGE;
//var STYLES = User32Extra.WS_POPUP;
var style = getStyle();
@ -114,7 +259,12 @@ 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.DWMWA_WINDOW_CORNER_PREFERENCE, roundref.getPointer(), new WinDef.DWORD(WinDef.DWORD.SIZE));
Dwm.INSTANCE.DwmSetWindowAttribute(
hwnd,
Dwm.DWMWA_WINDOW_CORNER_PREFERENCE,
roundref.getPointer(),
new WinDef.DWORD(WinDef.DWORD.SIZE)
);
}
public String getClassName() {
@ -128,7 +278,11 @@ public class Window {
public String getExecutableName() {
var user32 = User32Extra.INSTANCE;
var kernel32 = Kernel32.INSTANCE;
var handle = kernel32.OpenProcess(WinNT.PROCESS_QUERY_LIMITED_INFORMATION, false, getProcessId());
var handle = kernel32.OpenProcess(
WinNT.PROCESS_QUERY_LIMITED_INFORMATION,
false,
getProcessId()
);
char[] chars = new char[1024];
var len = new IntByReference();
len.setValue(1024);
@ -192,7 +346,12 @@ public class Window {
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));
dwm.DwmGetWindowAttribute(
hwnd,
Dwm.DWMWA_CLOAKED,
out.getPointer(),
new WinDef.DWORD(WinDef.DWORD.SIZE)
);
var val = out.getValue();
return val != 0;
}
@ -212,7 +371,12 @@ public class Window {
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");
return walk.equals(hwnd) &&
user32.IsWindowVisible(hwnd) &&
window.getTitle().length() > 0 &&
!window.isToolWindow() &&
!window.isDwmCloaked() &&
!window.getClassName().equals("Progman");
}
public boolean isToolWindow() {
@ -230,30 +394,60 @@ public class Window {
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()));
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;
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));
//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_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.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);
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
@ -261,101 +455,6 @@ public class Window {
if(!(o instanceof Window)) {
return false;
}
return ((Window)o).hwnd.equals(this.hwnd);
}
//static functions
public static List<Window> getAllVisible() {
var user32 = User32Extra.INSTANCE;
var windows = new ArrayList<Window>();
user32.EnumWindows(new WinUser.WNDENUMPROC() {
@Override
public boolean callback(WinDef.HWND hwnd, Pointer pointer) {
var window = new Window(hwnd);
if(window.isInAltTabList()) windows.add(window);
return true;
}
}, null);
return windows;
}
public static void messageLoop() {
var user32 = User32Extra.INSTANCE;
var msg = new WinUser.MSG();
while(user32.GetMessage(msg, null, 0, 0) != 0) {
System.out.println("msg pump");
user32.TranslateMessage(msg);
user32.DispatchMessage(msg);
if(msg.message == User32Extra.WM_TIMER)
return;
}
}
public static void messageTick() {
//todo: check if this even works (switch to getmessage, and add timer function?)
var user32 = User32Extra.INSTANCE;
var msg = new WinUser.MSG();
//while(user32.PeekMessage(msg, null, 0, 0, User32Extra.PM_NOREMOVE)) {
user32.GetMessage(msg, null, 0, 0);
System.out.println("msg pump");
user32.TranslateMessage(msg);
user32.DispatchMessage(msg);
//}
}
public static void onKey() {
var user32 = User32Extra.INSTANCE;
var kernel32 = Kernel32.INSTANCE;
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, lparam.toPointer());
System.out.println(kb.vkCode);
switch(wparam.intValue()) {
case User32Extra.WM_KEYDOWN:
System.out.println("WM_KEYDOWN");
break;
case User32Extra.WM_KEYUP:
System.out.println("WM_KEYUP");
break;
case User32Extra.WM_SYSKEYDOWN:
System.out.println("WM_SYSKEYDOWN");
break;
case User32Extra.WM_SYSKEYUP:
System.out.println("WM_SYSKEYUP");
break;
}
System.out.println("got some message a");
return user32.CallNextHookEx(null, nCode, wparam, lparam);
}
}, null, 0);
if(res == null) {
throw new RuntimeException("Couldn't setwindowhookex: " + Native.getLastError());
}
}
public static void onNewWindow() {
var user32 = User32Extra.INSTANCE;
var kernel32 = Kernel32.INSTANCE;
var hmod = kernel32.GetModuleHandle("kernel32.dll");
//todo: try RegisterShellHookWindow instead
var res = user32.SetWindowsHookEx(User32Extra.WH_SHELL, new WinUser.HOOKPROC() {
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");
}
return new WinDef.LRESULT(0);
}
}, hmod, 0);
if(res == null) {
throw new RuntimeException("Couldn't setwindowhookex: " + Native.getLastError());
}
}
public static void onTimer(int ms) {
WinUserExtra.INSTANCE.SetTimer(null, null, new WinDef.UINT(ms), null);
return ((Window) o).hwnd.equals(this.hwnd);
}
}

View File

@ -1,31 +1,52 @@
# Modules
## Graphics Backends
### Opengl (simple)
Just a basic oldschool opengl backend. Not about
performance, just about simple implementation. Acting as
a proof of concept, and a fallback backend.
## Modding
### Java-style
Not sandboxed, exposing internals and OS apis.
### Scripting-style
Sandboxed, could auto download from server. Which
scripting language to use? Lua? Ruby? Javascript? A
system that allows all of them?
## Networking
### Message style
Serialise class, send over network in binary form.
### Replication style
In style of unreal engine 1-3, or enet. Figure out some
sort of class decoration for automatic replication?
# Todo
## Gui Toolkit
### Themes
Theme system based on 9-slice.
#### Default theme
#### Fancy themes, like scifi or fantasy
#### CDE? giggle
## Fake terminal mode
Any font possible, but tilesetfonts are perfect for it.
What about multi resolution terminal? like half-width
characters, so text for text, and text for map/actors is