HUD: размер экрана из контекста и rsxm-hud
This commit is contained in:
@@ -385,6 +385,16 @@ public final class Rsx {
|
||||
return h.scale();
|
||||
}
|
||||
|
||||
/** Screen width in pixels, 0 when the game did not say. */
|
||||
public int width() {
|
||||
return h == null ? 0 : h.width();
|
||||
}
|
||||
|
||||
/** Screen height in pixels, 0 when the game did not say. */
|
||||
public int height() {
|
||||
return h == null ? 0 : h.height();
|
||||
}
|
||||
|
||||
/** A solid rectangle; alpha 0..1. */
|
||||
public void rect(float x, float y, float w, float height, int rgb,
|
||||
float alpha) {
|
||||
|
||||
@@ -41,18 +41,14 @@ public final class Hud {
|
||||
return Ui.scale();
|
||||
}
|
||||
|
||||
/**
|
||||
* Screen size in HUD units, or 0 when it cannot be read.
|
||||
*
|
||||
* The context does not expose it by name, so this stays 0 until a build
|
||||
* gives us a way; callers fall back to the game's own scale factor.
|
||||
*/
|
||||
/** Screen width, 0 when the game did not say. */
|
||||
public int width() {
|
||||
return 0;
|
||||
return HudHook.width();
|
||||
}
|
||||
|
||||
/** Screen height, 0 when the game did not say. */
|
||||
public int height() {
|
||||
return 0;
|
||||
return HudHook.height();
|
||||
}
|
||||
|
||||
/** A solid rectangle. Colour is 0xRRGGBB, alpha 0..1. */
|
||||
|
||||
@@ -142,6 +142,52 @@ public final class HudHook {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Screen size, read off the context.
|
||||
*
|
||||
* The context offers two no-argument int getters and nothing names them, so
|
||||
* they are told apart by what they can only be: on any window the larger one
|
||||
* is the width. Getting this wrong only mirrors the panel, it cannot break
|
||||
* the frame.
|
||||
*/
|
||||
static int width() {
|
||||
int[] s = size();
|
||||
return s == null ? 0 : Math.max(s[0], s[1]);
|
||||
}
|
||||
|
||||
static int height() {
|
||||
int[] s = size();
|
||||
return s == null ? 0 : Math.min(s[0], s[1]);
|
||||
}
|
||||
|
||||
private static int[] size;
|
||||
|
||||
private static synchronized int[] size() {
|
||||
if (size != null || context == null) {
|
||||
return size;
|
||||
}
|
||||
java.util.List<Integer> found = new ArrayList<Integer>();
|
||||
for (Class<?> c = context.getClass(); c != null; c = c.getSuperclass()) {
|
||||
for (Method m : c.getDeclaredMethods()) {
|
||||
if (m.getParameterTypes().length != 0
|
||||
|| m.getReturnType() != int.class) {
|
||||
continue;
|
||||
}
|
||||
try {
|
||||
m.setAccessible(true);
|
||||
found.add(Integer.valueOf(((Integer) m.invoke(context))
|
||||
.intValue()));
|
||||
} catch (Throwable ignored) {
|
||||
}
|
||||
}
|
||||
}
|
||||
if (found.size() >= 2) {
|
||||
size = new int[] {found.get(0).intValue(), found.get(1).intValue()};
|
||||
Log.info("HUD: screen " + width() + "x" + height());
|
||||
}
|
||||
return size;
|
||||
}
|
||||
|
||||
/** True while a mod callback is running, i.e. Rsx.hud() is meaningful. */
|
||||
public static boolean inside() {
|
||||
return context != null;
|
||||
|
||||
@@ -1,11 +1,20 @@
|
||||
// Test stand-in for the game's HUD render context.
|
||||
//
|
||||
// One method takes a draw command. The bridge finds it by shape rather than by
|
||||
// name, which is what makes the binding survive the next re-obfuscation.
|
||||
// One method takes a draw command, and two no-argument int getters give the
|
||||
// screen size. The bridge finds the submit method by shape and tells the two
|
||||
// getters apart by which is larger, so the names here do not matter.
|
||||
|
||||
public class fakectx {
|
||||
|
||||
public int screenWidth() {
|
||||
return 1920;
|
||||
}
|
||||
|
||||
public int screenHeight() {
|
||||
return 1080;
|
||||
}
|
||||
|
||||
public void accept(fakecmd command) {
|
||||
fakebatch.submit(command);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -18,6 +18,8 @@ public class HudMod implements RsxMod {
|
||||
public static int glyphs;
|
||||
|
||||
private final Runnable draw = new Runnable() {
|
||||
private int reported;
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
frames++;
|
||||
@@ -25,6 +27,11 @@ public class HudMod implements RsxMod {
|
||||
if (hud == null || !hud.available()) {
|
||||
return;
|
||||
}
|
||||
if (reported == 0 && hud.width() > 0) {
|
||||
reported = 1;
|
||||
Rsx.info("HudMod screen: " + hud.width() + "x" + hud.height()
|
||||
+ " scale=" + hud.scale());
|
||||
}
|
||||
hud.rect(8, 8, 40, 12, 0x20201C, 0.85f);
|
||||
rects++;
|
||||
hud.text(8, 8, "42 ms", 0xECE3DB, 1f);
|
||||
|
||||
@@ -288,6 +288,7 @@ def main():
|
||||
("panel drew a rectangle and a label",
|
||||
"color=20201c" in out and "textures/font/ascii.png" in out
|
||||
and "color=ece3db" in out),
|
||||
("screen size read from the context", "HudMod screen: 1920x1080" in out),
|
||||
("panel stops when the game hides the HUD",
|
||||
"HUD hidden (what F3 does)" in out
|
||||
and "frame 0 commands=0" in out and "frame 2 commands=0" in out),
|
||||
|
||||
Reference in New Issue
Block a user