Introducing vue module, native loader
This commit is contained in:
parent
3dc19b5c9e
commit
b86c046dd5
12
makefile
12
makefile
|
@ -19,6 +19,7 @@ default:
|
||||||
@echo
|
@echo
|
||||||
@echo "Usage: make <recipe>"
|
@echo "Usage: make <recipe>"
|
||||||
@echo " Package recipes:"
|
@echo " Package recipes:"
|
||||||
|
@echo " build Compiles the native modules and desktop application"
|
||||||
@echo " bundle Produces a .jar and deletes all intermediate files"
|
@echo " bundle Produces a .jar and deletes all intermediate files"
|
||||||
@echo " clean Deletes all output files"
|
@echo " clean Deletes all output files"
|
||||||
@echo " core Check the native core library for style errors"
|
@echo " core Check the native core library for style errors"
|
||||||
|
@ -38,12 +39,17 @@ default:
|
||||||
# Package Recipes #
|
# Package Recipes #
|
||||||
###############################################################################
|
###############################################################################
|
||||||
|
|
||||||
# Perform a full build process
|
# Perform a full build process of the native modules and desktop application
|
||||||
.PHONY: bundle
|
.PHONY: build
|
||||||
bundle:
|
build:
|
||||||
@make -s core
|
@make -s core
|
||||||
@make -s desktop
|
@make -s desktop
|
||||||
@make -s native
|
@make -s native
|
||||||
|
|
||||||
|
# Performs a full build and packages it into a .jar
|
||||||
|
.PHONY: bundle
|
||||||
|
bundle:
|
||||||
|
@make -s build
|
||||||
@make -s pack
|
@make -s pack
|
||||||
@echo " Removing temporary files"
|
@echo " Removing temporary files"
|
||||||
@make -s clean_most
|
@make -s clean_most
|
||||||
|
|
|
@ -1,14 +1,47 @@
|
||||||
|
// Java imports
|
||||||
|
import java.io.*;
|
||||||
|
|
||||||
// Project imports
|
// Project imports
|
||||||
import app.*;
|
import app.*;
|
||||||
import util.*;
|
import util.*;
|
||||||
|
import vue.*;
|
||||||
|
|
||||||
// Desktop application primary class
|
// Desktop application primary class
|
||||||
public class Main {
|
public class Main {
|
||||||
|
|
||||||
// Program entry point
|
// Program entry point
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
|
|
||||||
|
// Configure Swing look-and-feel
|
||||||
Util.setSystemLAF();
|
Util.setSystemLAF();
|
||||||
|
|
||||||
|
// Load the native module, if available
|
||||||
|
for (String filename : Util.listFiles("native")) {
|
||||||
|
File file = null;
|
||||||
|
|
||||||
|
// Skip .gitignore
|
||||||
|
if (filename.equals(".gitignore"))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// Write the contents of the native object file
|
||||||
|
FileOutputStream stream = null;
|
||||||
|
try {
|
||||||
|
file = File.createTempFile("native", "." + filename);
|
||||||
|
stream = new FileOutputStream(file);
|
||||||
|
stream.write(Util.fileRead("native/" + filename));
|
||||||
|
} catch (Exception e) { file = null; }
|
||||||
|
try { stream.close(); } catch (Exception e) { }
|
||||||
|
|
||||||
|
// Load the native object file into the JVM
|
||||||
|
try { System.load(file.getAbsolutePath()); break; }
|
||||||
|
catch (Error e) { }
|
||||||
|
}
|
||||||
|
|
||||||
|
// Begin application operations
|
||||||
new App();
|
new App();
|
||||||
|
|
||||||
|
var vue = VUE.create(true);
|
||||||
|
System.out.println(vue.isNative());
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -96,7 +96,9 @@ public class ROM {
|
||||||
|
|
||||||
// Produce a byte array containing the ROM contents
|
// Produce a byte array containing the ROM contents
|
||||||
public byte[] toByteArray() {
|
public byte[] toByteArray() {
|
||||||
return data;
|
var ret = new byte[data.length];
|
||||||
|
System.arraycopy(data, 0, ret, 0, data.length);
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -136,7 +138,8 @@ public class ROM {
|
||||||
int size = 1024;
|
int size = 1024;
|
||||||
int minSize = (head == -1 ? 0 : head + 1) +
|
int minSize = (head == -1 ? 0 : head + 1) +
|
||||||
(tail == -1 ? 0 : 0x01000000 - tail);
|
(tail == -1 ? 0 : 0x01000000 - tail);
|
||||||
if (minSize == 0 || tail == -1 && (minSize - 1 & minSize) != 0)
|
if (minSize == 0 || tail == -1 &&
|
||||||
|
(minSize < 1024 || (minSize - 1 & minSize) != 0))
|
||||||
throw new RuntimeException();
|
throw new RuntimeException();
|
||||||
for (; size < minSize; size <<= 1);
|
for (; size < minSize; size <<= 1);
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,36 @@
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdlib.h>
|
||||||
#include <jni.h>
|
#include <jni.h>
|
||||||
#include "vue_NativeVUE.h"
|
#include "vue_NativeVUE.h"
|
||||||
|
|
||||||
JNIEXPORT jint JNICALL Java_vue_NativeVUE_test(JNIEnv *env, jobject obj,
|
// Retrieve a copy of the ROM data
|
||||||
jint x, jint y) {
|
JNIEXPORT jbyteArray JNICALL Java_vue_NativeVUE_getROM
|
||||||
return x * y;
|
(JNIEnv *env, jobject vue) {
|
||||||
|
}
|
||||||
|
|
||||||
|
// Determine whether the context is native-backed
|
||||||
|
JNIEXPORT jboolean JNICALL Java_vue_NativeVUE_isNative
|
||||||
|
(JNIEnv *env, jobject vue) {
|
||||||
|
return JNI_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Provide new ROM data
|
||||||
|
JNIEXPORT jboolean JNICALL Java_vue_NativeVUE_setROM
|
||||||
|
(JNIEnv *env, jobject vue, jbyteArray data, jint offset, jint length) {
|
||||||
|
jsize data_length = (*env)->GetArrayLength(env, data);
|
||||||
|
|
||||||
|
// Error checking
|
||||||
|
if (data == NULL || offset < 0 || length < 1024 ||
|
||||||
|
offset + length > data_length || (length & length - 1) != 0)
|
||||||
|
return JNI_FALSE;
|
||||||
|
|
||||||
|
// Accept the new ROM data
|
||||||
|
return JNI_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Invoke native code to ensure the module is loaded
|
||||||
|
JNIEXPORT jboolean JNICALL Java_vue_NativeVUE_testNative
|
||||||
|
(JNIEnv *env, jclass vue) {
|
||||||
|
return JNI_TRUE;
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,53 @@
|
||||||
|
package vue;
|
||||||
|
|
||||||
|
// Java emulation core implementation
|
||||||
|
// Native-backed emulation core implementation
|
||||||
|
class JavaVUE implements VUE {
|
||||||
|
|
||||||
|
// Instance fields
|
||||||
|
private byte[] rom; // Cartridge ROM
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////
|
||||||
|
// Constructors //
|
||||||
|
///////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
// Default constructor
|
||||||
|
JavaVUE() {
|
||||||
|
rom = new byte[1024];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////
|
||||||
|
// Public Methods //
|
||||||
|
///////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
// Retrieve a copy of the ROM data
|
||||||
|
public byte[] getROM() {
|
||||||
|
var ret = new byte[rom.length];
|
||||||
|
System.arraycopy(rom, 0, ret, 0, rom.length);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Determine whether the context is native-backed
|
||||||
|
public boolean isNative() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Provide new ROM data
|
||||||
|
public boolean setROM(byte[] data, int offset, int length) {
|
||||||
|
|
||||||
|
// Error checking
|
||||||
|
if (data == null || offset < 0 || length < 1024 ||
|
||||||
|
offset + length > data.length || (length & length - 1) != 0)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// Accept the new ROM data
|
||||||
|
rom = new byte[length];
|
||||||
|
System.arraycopy(data, offset, rom, 0, length);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -1,13 +1,55 @@
|
||||||
package vue;
|
package vue;
|
||||||
|
|
||||||
// Native-backed emulation core implementation
|
// Native-backed emulation core implementation
|
||||||
class NativeVUE extends VUE {
|
class NativeVUE implements VUE {
|
||||||
|
|
||||||
// Retrieve the implementation's name
|
// Instance fields
|
||||||
public String getName() {
|
private byte[] pointer; // Instance address in native memory
|
||||||
return "Native";
|
|
||||||
|
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////
|
||||||
|
// Constructors //
|
||||||
|
///////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
// Default constructor
|
||||||
|
NativeVUE() {
|
||||||
}
|
}
|
||||||
|
|
||||||
native int test(int x, int y);
|
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////
|
||||||
|
// Package Methods //
|
||||||
|
///////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
// Determine whether the native library has been loaded
|
||||||
|
static boolean isLoaded() {
|
||||||
|
try { return testNative(); }
|
||||||
|
catch (Exception e) { return false; }
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////
|
||||||
|
// Public Methods //
|
||||||
|
///////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
// Retrieve a copy of the ROM data
|
||||||
|
public native byte[] getROM();
|
||||||
|
|
||||||
|
// Determine whether the context is native-backed
|
||||||
|
public native boolean isNative();
|
||||||
|
|
||||||
|
// Provide new ROM data
|
||||||
|
public native boolean setROM(byte[] data, int offset, int length);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////
|
||||||
|
// Private Methods //
|
||||||
|
///////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
// Invoke native code to ensure the module is loaded
|
||||||
|
private static native boolean testNative();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,9 +1,31 @@
|
||||||
package vue;
|
package vue;
|
||||||
|
|
||||||
// Template class for emulation core implementations
|
// Template for emulation core implementations
|
||||||
public abstract class VUE {
|
public interface VUE {
|
||||||
|
|
||||||
// Retrieve the implementation's name
|
///////////////////////////////////////////////////////////////////////////
|
||||||
public abstract String getName();
|
// Factory Methods //
|
||||||
|
///////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
// Produce an emulation core context
|
||||||
|
public static VUE create(boolean useNative) {
|
||||||
|
return !useNative ? new JavaVUE() :
|
||||||
|
NativeVUE.isLoaded() ? new NativeVUE() : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////
|
||||||
|
// Public Methods //
|
||||||
|
///////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
// Retrieve a copy of the ROM data
|
||||||
|
byte[] getROM();
|
||||||
|
|
||||||
|
// Determine whether the context is native-backed
|
||||||
|
boolean isNative();
|
||||||
|
|
||||||
|
// Provide new ROM data
|
||||||
|
boolean setROM(byte[] data, int offset, int length);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue