Skip to content

Commit

Permalink
FXCompiled bug
Browse files Browse the repository at this point in the history
FXCompiler made the program crash on start if Microsoft SDK is not installed.
  • Loading branch information
emd4600 committed Mar 3, 2019
1 parent bc47389 commit 7489dde
Show file tree
Hide file tree
Showing 14 changed files with 483 additions and 54 deletions.
2 changes: 1 addition & 1 deletion src/sporemodder/UpdateManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ public class UpdateManager {

private static final String GITHUB_URL = "https://api.github.com";

public final VersionInfo versionInfo = new VersionInfo(2, 0, 3, null);
public final VersionInfo versionInfo = new VersionInfo(2, 0, 4, null);

public static UpdateManager get() {
return MainApp.get().getUpdateManager();
Expand Down
68 changes: 68 additions & 0 deletions src/sporemodder/file/anim/Animation.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
package sporemodder.file.anim;

import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.util.ArrayList;
import java.util.List;

import emord.filestructures.MemoryStream;
import emord.filestructures.StreamReader;
import sporemodder.MainApp;
import sporemodder.file.argscript.ArgScriptWriter;

public class Animation {

private static final int MAGIC = 0x4D494E41;

private final List<AnimationChannel> channels = new ArrayList<>();

public void read(StreamReader stream) throws IOException {
int magic = stream.readLEInt();
if (magic != MAGIC) {
throw new IOException("Unsupported animation magic: 0x" + Integer.toHexString(magic));
}

DataStructure data = new DataStructure(stream);
data.setPointer(0);

int channelCount = data.getInt(0x144);
long channelPtr = data.getUInt(0x148);

for (int i = 0; i < channelCount; ++i) {
data.setPointer(channelPtr);
long ptr = data.getUInt(4 * i);

data.setPointer(ptr);
AnimationChannel channel = new AnimationChannel();
channel.read(data);
channels.add(channel);
}
}

public void toArgScript(ArgScriptWriter writer, StreamReader stream) throws IOException {
DataStructure data = new DataStructure(stream);
data.setPointer(0);

for (AnimationChannel channel : channels) {
channel.toArgScript(writer, data);
writer.blankLine();
}
}

public static void main(String[] args) throws IOException {
String path = "C:\\Users\\Eric\\Desktop\\#30EF4216.animation";
MainApp.testInit();

try (MemoryStream stream = new MemoryStream(Files.readAllBytes(new File(path).toPath()))) {

Animation animation = new Animation();
animation.read(stream);

ArgScriptWriter writer = new ArgScriptWriter();
animation.toArgScript(writer, stream);

System.out.println(writer.toString());
}
}
}
76 changes: 76 additions & 0 deletions src/sporemodder/file/anim/AnimationChannel.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
package sporemodder.file.anim;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import emord.filestructures.Stream.StringEncoding;
import sporemodder.file.argscript.ArgScriptWriter;

public class AnimationChannel {

private final static int MAGIC = 0x4E414843;

public String name;
public int field_8C;
public int keyframeCount;
public long keyframePtr;
public final List<ChannelComponent> components = new ArrayList<>();

public void read(DataStructure stream) throws IOException {
stream.getStream().seek(stream.getPointer());

int magic = stream.getStream().readLEInt();
if (magic != MAGIC) {
throw new IOException("Unsupported channel magic: 0x" + Integer.toHexString(magic));
}

stream.getStream().skip(4);
name = stream.getStream().readCString(StringEncoding.ASCII);

field_8C = stream.getInt(0x8C);

keyframeCount = stream.getInt(0xD4); // ?
keyframePtr = stream.getUInt(0xD8);
int count = stream.getInt(0xDC);
long ptr = stream.getUInt(0xE0);
System.out.println(name + " " + field_8C + "\tkeyframes[" + keyframeCount + "] 0x" + Integer.toHexString(stream.getInt(0xD8)));

// each item of size 32

for (int i = 0; i < count; ++i) {
stream.setPointer(ptr + 32*i);

ChannelComponent comp = new ChannelComponent();
comp.read(stream, keyframePtr);
components.add(comp);
}

System.out.println();
}

public void toArgScript(ArgScriptWriter writer, DataStructure stream) throws IOException {
writer.command("channel").arguments(name).startBlock();

for (int i = 0; i < components.size(); ++i) {
ChannelComponent comp = components.get(i);

writer.command("component");
if (comp.id == ChannelComponent.TYPE_POS) {
writer.arguments("POS").startBlock();

for (int j = 0; j < keyframeCount; ++j) {
stream.getStream().seek(keyframePtr + comp.keyframeStride*j + comp.keyframeOffset);
float[] dst = new float[3];
stream.getStream().readLEFloats(dst);

writer.command("").vector(dst).floats(stream.getStream().readLEFloat(), stream.getStream().readLEFloat());
}

writer.endBlock().commandEND();
}
}

writer.endBlock().commandEND();
}
}
22 changes: 22 additions & 0 deletions src/sporemodder/file/anim/ChannelComponent.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package sporemodder.file.anim;

import java.io.IOException;

public class ChannelComponent {

public static final int TYPE_INFO = 0x4F464E49;
public static final int TYPE_POS = 0x534F50;
public static final int TYPE_ROT = 0x544F52;

public int id;
public int keyframeOffset;
public int keyframeStride;

public void read(DataStructure stream, long dataPtr) throws IOException {
id = stream.getInt(4);
keyframeOffset = stream.getInt(8);
keyframeStride = stream.getInt(12);

System.out.println("\t0x" + Long.toHexString(dataPtr + keyframeOffset) + "\tid: 0x" + Integer.toHexString(id));
}
}
46 changes: 46 additions & 0 deletions src/sporemodder/file/anim/DataStructure.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
package sporemodder.file.anim;

import java.io.IOException;

import emord.filestructures.StreamReader;

/**
* A convenience class used to read data from a file without any order. It is meant
* to be equivalent to accessing certain fields of an structure.
*/
public class DataStructure {

private final StreamReader stream;
private long pointer;

public DataStructure(StreamReader stream) {
this.stream = stream;
}

public StreamReader getStream() {
return stream;
}

public long getPointer() {
return pointer;
}

public void setPointer(long pointer) {
this.pointer = pointer;
}

public long getUInt(int offset) throws IOException {
stream.seek(pointer + offset);
return stream.readLEUInt();
}

public int getInt(int offset) throws IOException {
stream.seek(pointer + offset);
return stream.readLEInt();
}

public float getFloat(int offset) throws IOException {
stream.seek(pointer + offset);
return stream.readLEFloat();
}
}
16 changes: 16 additions & 0 deletions src/sporemodder/file/argscript/ArgScriptWriter.java
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,22 @@ public ArgScriptWriter blankLine() {
return this;
}

public ArgScriptWriter tabulatedText(String text, boolean newLine) {
String[] lines = text.split("\n");
for (String line : lines) {
if (sb.length() != 0 && newLine) {
sb.append('\n');
}
if (newLine) for (int i = 0; i < indentationLevel; i++) {
sb.append('\t');
}
newLine = true;
sb.append(line);
}

return this;
}

public ArgScriptWriter command(String name) {
if (sb.length() != 0) {
sb.append('\n');
Expand Down
25 changes: 15 additions & 10 deletions src/sporemodder/file/shaders/CompiledShaders.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
import sporemodder.FileManager;
import sporemodder.HashManager;
import sporemodder.MainApp;
import sporemodder.file.argscript.ArgScriptWriter;
import sporemodder.file.shaders.StandardShader.StandardShaderEntry;

public class CompiledShaders {
Expand Down Expand Up @@ -88,6 +89,11 @@ public void write(StreamWriter out) throws IOException {
out.writeString(name, StringEncoding.ASCII);
}

public ShaderSelector getSelector(int id) {
for (ShaderSelector shader : shaderSelectors) if (shader.id == id) return shader;
return null;
}

public void unpack(File outputFolder) throws IOException {
FileManager.get().deleteDirectory(outputFolder);
outputFolder.mkdir();
Expand Down Expand Up @@ -162,18 +168,17 @@ public static void main(String[] args) throws IOException {
try (StreamReader stream = new FileStream(file, "r")) {
CompiledShaders shaders = new CompiledShaders();
shaders.read(stream);
//shaders.unpack(outputFolder);

ShaderFragments fragments = ShaderFragments.readShaderFragments(fragmentsFile);
for (int i = 0; i < shaders.vertexShaders.size(); ++i) {
CompiledShader entry = shaders.vertexShaders.get(i);
for (int index : entry.fragmentIndices) {
if (index == 0) break;
System.out.print(fragments.getFragment(index).getName() + " ");
}
System.out.println();
}
List<String> fragmentNames = new ArrayList<String>();
fragmentNames.add(null); // index 0 is never used
for (ShaderFragment fragment : fragments.shaders) fragmentNames.add(fragment.getName());

ArgScriptWriter writer = new ArgScriptWriter();

shaders.getSelector(0x80000004).toArgScript(writer, fragmentNames);

System.out.print(writer.toString());

// for (int i = 0; i < shaders.vertexShaders.size(); ++i) {
// CompiledShader entry = shaders.vertexShaders.get(i);
Expand Down
18 changes: 9 additions & 9 deletions src/sporemodder/file/shaders/FXCompiler.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,6 @@
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.lang.ProcessBuilder.Redirect;
import java.lang.reflect.InvocationTargetException;
import java.util.List;
import java.util.Properties;

Expand Down Expand Up @@ -49,17 +47,19 @@ public boolean autoDetectPath() {
String path = WinRegistry.valueForKey(WinRegistry.HKEY_LOCAL_MACHINE, "SOFTWARE\\WOW6432Node\\Microsoft\\Windows Kits\\Installed Roots", "KitsRoot10");

File versionFolder = new File(path, "bin");
for (File folder : versionFolder.listFiles()) {
File file = new File(folder, "x86\\fxc.exe");
if (file.exists()) {
fxcFile = file;
isAutoPath = true;
return true;
if (versionFolder.exists()) {
for (File folder : versionFolder.listFiles()) {
File file = new File(folder, "x86\\fxc.exe");
if (file.exists()) {
fxcFile = file;
isAutoPath = true;
return true;
}
}
}

return false;
} catch (IllegalArgumentException | IllegalAccessException | InvocationTargetException | IOException e) {
} catch (Exception e) {
e.printStackTrace();
return false;
}
Expand Down
44 changes: 41 additions & 3 deletions src/sporemodder/file/shaders/ShaderFragment.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

import emord.filestructures.Stream.StringEncoding;
import emord.filestructures.StreamReader;
import sporemodder.file.argscript.ArgScriptWriter;

public class ShaderFragment {
public static class ShaderVariable {
Expand Down Expand Up @@ -77,9 +78,9 @@ public void writeHLSL(BufferedWriter out, int startRegister) throws IOException

public int input;
public int output;
public byte numRegisters;
public byte numOutputTexcoords; // only for vertex shader
public byte type; // only for vertex shader, 4, sometimes 3?
public byte numRegisters; // 28h
public byte numOutputTexcoords; // only for vertex shader // 29h
public byte type; // only for vertex shader, 4, sometimes 3? // 2Ah
public int flags; // -18h

public String shaderName;
Expand Down Expand Up @@ -109,6 +110,43 @@ public void read(StreamReader in) throws IOException {
}
}

public void toArgScript(ArgScriptWriter writer) {
writer.command("fragment").arguments(shaderName).startBlock();

writer.command("input").arguments("0x" + Integer.toHexString(input));
writer.command("output").arguments("0x" + Integer.toHexString(output));
writer.command("numOutputTexcoords").ints(numOutputTexcoords);
writer.command("type").ints(type);
writer.command("numRegisters").ints(numRegisters);

if (!declareCode.isEmpty() || !variables.isEmpty()) {
writer.blankLine();
writer.command("declareCode").startBlock();
int startRegister = 0;
for (ShaderVariable variable : variables) {
writer.command("extern").arguments("uniform");
writer.tabulatedText(variable.name, false);
writer.arguments(":", "register(c" + startRegister + ");");
startRegister += variable.registerSize;
}
if (!variables.isEmpty()) {
writer.blankLine();
}
if (!declareCode.trim().isEmpty()) {
writer.tabulatedText(declareCode, true);
}
writer.endBlock().command("endCode");
}

if (!mainCode.isEmpty()) {
writer.blankLine();
writer.command("code").startBlock();
writer.tabulatedText(mainCode, true);
writer.endBlock().command("endCode");
}
writer.endBlock().commandEND();
}

public void writeHLSL(BufferedWriter out) throws IOException {

if (type == 0) {
Expand Down
Loading

0 comments on commit 7489dde

Please sign in to comment.