lawless-legends/Platform/Apple/tools/jace/src/main/java/jace/ui/Watch.java

131 lines
4.3 KiB
Java

/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package jace.ui;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;
import jace.Emulator;
import jace.cheat.MemoryCell;
import jace.core.RAMListener;
import javafx.application.Platform;
import javafx.beans.property.BooleanProperty;
import javafx.geometry.Insets;
import javafx.scene.canvas.Canvas;
import javafx.scene.canvas.GraphicsContext;
import javafx.scene.control.CheckBox;
import javafx.scene.control.Label;
import javafx.scene.layout.Background;
import javafx.scene.layout.BackgroundFill;
import javafx.scene.layout.CornerRadii;
import javafx.scene.layout.VBox;
import javafx.scene.paint.Color;
import javafx.scene.text.Font;
import javafx.scene.text.TextAlignment;
/**
*
* @author blurry
*/
class Watch extends VBox {
private static final int GRAPH_WIDTH = 50;
private static final double GRAPH_HEIGHT = 50;
int address;
ScheduledFuture redraw;
Canvas graph;
List<Integer> samples = Collections.synchronizedList(new ArrayList<>());
int value = 0;
BooleanProperty holding = null;
private final MetacheatUI outer;
MemoryCell cell;
public Watch(int address, final MetacheatUI outer) {
super();
this.outer = outer;
this.address = address;
cell = outer.cheatEngine.getMemoryCell(address);
redraw = outer.animationTimer.scheduleAtFixedRate(this::redraw, MetacheatUI.FRAME_RATE, MetacheatUI.FRAME_RATE, TimeUnit.MILLISECONDS);
setBackground(new Background(new BackgroundFill(Color.NAVY, CornerRadii.EMPTY, Insets.EMPTY)));
Label addrLabel = new Label("$" + Integer.toHexString(address));
addrLabel.setOnMouseClicked((evt)-> outer.inspectAddress(address));
addrLabel.setTextAlignment(TextAlignment.CENTER);
addrLabel.setMinWidth(GRAPH_WIDTH);
addrLabel.setFont(new Font(Font.getDefault().getFamily(), 14));
addrLabel.setTextFill(Color.WHITE);
graph = new Canvas(GRAPH_WIDTH, GRAPH_HEIGHT);
getChildren().add(addrLabel);
getChildren().add(graph);
CheckBox hold = new CheckBox("Hold");
holding = hold.selectedProperty();
holding.addListener((prop, oldVal, newVal) -> this.updateHold());
getChildren().add(hold);
hold.setTextFill(Color.WHITE);
}
public int getValue() {
return value;
}
public void redraw() {
boolean isRunning = Emulator.withComputer(c->c.getRunningProperty().get(), false);
if (!isRunning) return;
int val = cell.value.get() & 0x0ff;
if (!holding.get()) {
value = val;
}
if (samples.size() >= GRAPH_WIDTH) {
samples.remove(0);
}
samples.add(val);
Platform.runLater(() -> {
GraphicsContext g = graph.getGraphicsContext2D();
g.setFill(Color.BLACK);
g.fillRect(0, 0, GRAPH_WIDTH, GRAPH_HEIGHT);
if (samples.size() > 1) {
g.setLineWidth(1);
g.setStroke(Color.LAWNGREEN);
int y = (int) (GRAPH_HEIGHT - ((samples.get(0) / 255.0) * GRAPH_HEIGHT));
g.beginPath();
g.moveTo(0, y);
for (int i = 1; i < samples.size(); i++) {
y = (int) (GRAPH_HEIGHT - ((samples.get(i) / 255.0) * GRAPH_HEIGHT));
g.lineTo(i, y);
}
g.stroke();
}
g.beginPath();
g.setStroke(Color.WHITE);
g.strokeText(String.valueOf(val), GRAPH_WIDTH - 25, GRAPH_HEIGHT - 5);
});
}
RAMListener holdListener;
public BooleanProperty holdingProperty() {
return holding;
}
private void updateHold() {
if (!holding.get()) {
outer.cheatEngine.removeListener(holdListener);
holdListener = null;
} else {
value = Emulator.withComputer(c->c.getMemory().readRaw(address) & 0x0ff, 0);
holdListener = outer.cheatEngine.forceValue(value, address);
}
}
public void disconnect() {
holding.set(false);
redraw.cancel(false);
}
}