jni: Render directly to the java frame buffer
Former-commit-id: 1647ad7859ad4558ba9626a1ef7afe2ceb1967f4
This commit is contained in:
parent
ef70f3bafc
commit
fc8b066191
|
@ -22,11 +22,24 @@ use rustboyadvance_ng::prelude::*;
|
||||||
|
|
||||||
struct Hardware {
|
struct Hardware {
|
||||||
jvm: JavaVM,
|
jvm: JavaVM,
|
||||||
|
frame_buffer_global_ref: GlobalRef,
|
||||||
// frame_buffer: [u32; DISPLAY_WIDTH * DISPLAY_HEIGHT],
|
// frame_buffer: [u32; DISPLAY_WIDTH * DISPLAY_HEIGHT],
|
||||||
key_state: u16,
|
key_state: u16,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl VideoInterface for Hardware {}
|
impl VideoInterface for Hardware {
|
||||||
|
fn render(&mut self, buffer: &[u32]) {
|
||||||
|
let env = self.jvm.get_env().unwrap();
|
||||||
|
unsafe {
|
||||||
|
env.set_int_array_region(
|
||||||
|
self.frame_buffer_global_ref.as_obj().into_inner(),
|
||||||
|
0,
|
||||||
|
std::mem::transmute::<&[u32], &[i32]>(buffer),
|
||||||
|
)
|
||||||
|
.unwrap();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
impl AudioInterface for Hardware {}
|
impl AudioInterface for Hardware {}
|
||||||
impl InputInterface for Hardware {
|
impl InputInterface for Hardware {
|
||||||
fn poll(&mut self) -> u16 {
|
fn poll(&mut self) -> u16 {
|
||||||
|
@ -48,6 +61,7 @@ unsafe fn internal_open_context(
|
||||||
env: &JNIEnv,
|
env: &JNIEnv,
|
||||||
bios: jbyteArray,
|
bios: jbyteArray,
|
||||||
rom: jbyteArray,
|
rom: jbyteArray,
|
||||||
|
frame_buffer: jintArray,
|
||||||
save_file: JString,
|
save_file: JString,
|
||||||
) -> Result<Context, String> {
|
) -> Result<Context, String> {
|
||||||
let bios = env
|
let bios = env
|
||||||
|
@ -71,8 +85,13 @@ unsafe fn internal_open_context(
|
||||||
|
|
||||||
info!("Loaded ROM file {:?}", gamepak.header);
|
info!("Loaded ROM file {:?}", gamepak.header);
|
||||||
|
|
||||||
|
let frame_buffer_global_ref = env
|
||||||
|
.new_global_ref(JObject::from(frame_buffer))
|
||||||
|
.map_err(|e| format!("failed to add new global ref, error: {:?}", e))?;
|
||||||
|
|
||||||
let hw = Hardware {
|
let hw = Hardware {
|
||||||
jvm: env.get_java_vm().unwrap(),
|
jvm: env.get_java_vm().unwrap(),
|
||||||
|
frame_buffer_global_ref: frame_buffer_global_ref,
|
||||||
key_state: 0xffff,
|
key_state: 0xffff,
|
||||||
};
|
};
|
||||||
let hw = Rc::new(RefCell::new(hw));
|
let hw = Rc::new(RefCell::new(hw));
|
||||||
|
@ -138,9 +157,10 @@ pub mod bindings {
|
||||||
_obj: JClass,
|
_obj: JClass,
|
||||||
bios: jbyteArray,
|
bios: jbyteArray,
|
||||||
rom: jbyteArray,
|
rom: jbyteArray,
|
||||||
|
frame_buffer: jintArray,
|
||||||
save_file: JString,
|
save_file: JString,
|
||||||
) -> jlong {
|
) -> jlong {
|
||||||
match internal_open_context(&env, bios, rom, save_file) {
|
match internal_open_context(&env, bios, rom, frame_buffer, save_file) {
|
||||||
Ok(ctx) => Box::into_raw(Box::new(Mutex::new(ctx))) as jlong,
|
Ok(ctx) => Box::into_raw(Box::new(Mutex::new(ctx))) as jlong,
|
||||||
Err(msg) => {
|
Err(msg) => {
|
||||||
env.throw_new(NATIVE_EXCEPTION_CLASS, msg).unwrap();
|
env.throw_new(NATIVE_EXCEPTION_CLASS, msg).unwrap();
|
||||||
|
@ -151,7 +171,7 @@ pub mod bindings {
|
||||||
|
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub unsafe extern "C" fn Java_com_mrmichel_rustboyadvance_EmulatorBindings_closeEmulator(
|
pub unsafe extern "C" fn Java_com_mrmichel_rustboyadvance_EmulatorBindings_closeEmulator(
|
||||||
_env: JNIEnv,
|
env: JNIEnv,
|
||||||
_obj: JClass,
|
_obj: JClass,
|
||||||
ctx: jlong,
|
ctx: jlong,
|
||||||
) {
|
) {
|
||||||
|
@ -170,16 +190,16 @@ pub mod bindings {
|
||||||
let mut ctx = lock_ctx(ctx);
|
let mut ctx = lock_ctx(ctx);
|
||||||
|
|
||||||
ctx.gba.frame();
|
ctx.gba.frame();
|
||||||
let gpu_buffer =
|
// let gpu_buffer =
|
||||||
std::mem::transmute::<&[u32], &[i32]>(&ctx.gba.get_frame_buffer() as &[u32]);
|
// std::mem::transmute::<&[u32], &[i32]>(&ctx.gba.get_frame_buffer() as &[u32]);
|
||||||
let result = env.set_int_array_region(frame_buffer, 0, gpu_buffer);
|
// let result = env.set_int_array_region(frame_buffer, 0, gpu_buffer);
|
||||||
if let Err(e) = result {
|
// if let Err(e) = result {
|
||||||
env.throw_new(
|
// env.throw_new(
|
||||||
NATIVE_EXCEPTION_CLASS,
|
// NATIVE_EXCEPTION_CLASS,
|
||||||
format!("failed to copy framebuffer into Java, error: {}", e),
|
// format!("failed to copy framebuffer into Java, error: {}", e),
|
||||||
)
|
// )
|
||||||
.unwrap();
|
// .unwrap();
|
||||||
}
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
|
@ -225,6 +245,26 @@ pub mod bindings {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
pub unsafe extern "C" fn Java_com_mrmichel_rustboyadvance_EmulatorBindings_getGameTitle(
|
||||||
|
env: JNIEnv,
|
||||||
|
_obj: JClass,
|
||||||
|
ctx: jlong,
|
||||||
|
) -> jstring {
|
||||||
|
let ctx = lock_ctx(ctx);
|
||||||
|
env.new_string(ctx.gba.get_game_title()).unwrap().into_inner()
|
||||||
|
}
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
pub unsafe extern "C" fn Java_com_mrmichel_rustboyadvance_EmulatorBindings_getGameCode(
|
||||||
|
env: JNIEnv,
|
||||||
|
_obj: JClass,
|
||||||
|
ctx: jlong,
|
||||||
|
) -> jstring {
|
||||||
|
let ctx = lock_ctx(ctx);
|
||||||
|
env.new_string(ctx.gba.get_game_code()).unwrap().into_inner()
|
||||||
|
}
|
||||||
|
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub unsafe extern "C" fn Java_com_mrmichel_rustboyadvance_EmulatorBindings_log(
|
pub unsafe extern "C" fn Java_com_mrmichel_rustboyadvance_EmulatorBindings_log(
|
||||||
_env: JNIEnv,
|
_env: JNIEnv,
|
||||||
|
|
|
@ -29,11 +29,11 @@ use std::str::from_utf8;
|
||||||
#[derive(Serialize, Deserialize, Clone, Debug)]
|
#[derive(Serialize, Deserialize, Clone, Debug)]
|
||||||
pub struct CartridgeHeader {
|
pub struct CartridgeHeader {
|
||||||
// rom_entry_point: Addr,
|
// rom_entry_point: Addr,
|
||||||
game_title: String,
|
pub game_title: String,
|
||||||
game_code: String,
|
pub game_code: String,
|
||||||
maker_code: String,
|
pub maker_code: String,
|
||||||
software_version: u8,
|
pub software_version: u8,
|
||||||
checksum: u8,
|
pub checksum: u8,
|
||||||
// ram_entry_point: Addr,
|
// ram_entry_point: Addr,
|
||||||
// joybus_entry_point: Addr,
|
// joybus_entry_point: Addr,
|
||||||
}
|
}
|
||||||
|
|
|
@ -89,6 +89,14 @@ impl GameBoyAdvance {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn get_game_title(&self) -> String {
|
||||||
|
self.sysbus.cartridge.header.game_title.clone()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_game_code(&self) -> String {
|
||||||
|
self.sysbus.cartridge.header.game_code.clone()
|
||||||
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn key_poll(&mut self) {
|
pub fn key_poll(&mut self) {
|
||||||
self.sysbus.io.keyinput = self.input_device.borrow_mut().poll();
|
self.sysbus.io.keyinput = self.input_device.borrow_mut().poll();
|
||||||
|
|
Reference in a new issue