jni: Render directly to the java frame buffer

Former-commit-id: 1647ad7859ad4558ba9626a1ef7afe2ceb1967f4
This commit is contained in:
Michel Heily 2020-02-27 11:03:34 +02:00
parent ef70f3bafc
commit fc8b066191
3 changed files with 66 additions and 18 deletions

View file

@ -22,11 +22,24 @@ use rustboyadvance_ng::prelude::*;
struct Hardware {
jvm: JavaVM,
frame_buffer_global_ref: GlobalRef,
// frame_buffer: [u32; DISPLAY_WIDTH * DISPLAY_HEIGHT],
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 InputInterface for Hardware {
fn poll(&mut self) -> u16 {
@ -48,6 +61,7 @@ unsafe fn internal_open_context(
env: &JNIEnv,
bios: jbyteArray,
rom: jbyteArray,
frame_buffer: jintArray,
save_file: JString,
) -> Result<Context, String> {
let bios = env
@ -71,8 +85,13 @@ unsafe fn internal_open_context(
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 {
jvm: env.get_java_vm().unwrap(),
frame_buffer_global_ref: frame_buffer_global_ref,
key_state: 0xffff,
};
let hw = Rc::new(RefCell::new(hw));
@ -138,9 +157,10 @@ pub mod bindings {
_obj: JClass,
bios: jbyteArray,
rom: jbyteArray,
frame_buffer: jintArray,
save_file: JString,
) -> 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,
Err(msg) => {
env.throw_new(NATIVE_EXCEPTION_CLASS, msg).unwrap();
@ -151,7 +171,7 @@ pub mod bindings {
#[no_mangle]
pub unsafe extern "C" fn Java_com_mrmichel_rustboyadvance_EmulatorBindings_closeEmulator(
_env: JNIEnv,
env: JNIEnv,
_obj: JClass,
ctx: jlong,
) {
@ -170,16 +190,16 @@ pub mod bindings {
let mut ctx = lock_ctx(ctx);
ctx.gba.frame();
let gpu_buffer =
std::mem::transmute::<&[u32], &[i32]>(&ctx.gba.get_frame_buffer() as &[u32]);
let result = env.set_int_array_region(frame_buffer, 0, gpu_buffer);
if let Err(e) = result {
env.throw_new(
NATIVE_EXCEPTION_CLASS,
format!("failed to copy framebuffer into Java, error: {}", e),
)
.unwrap();
}
// let gpu_buffer =
// std::mem::transmute::<&[u32], &[i32]>(&ctx.gba.get_frame_buffer() as &[u32]);
// let result = env.set_int_array_region(frame_buffer, 0, gpu_buffer);
// if let Err(e) = result {
// env.throw_new(
// NATIVE_EXCEPTION_CLASS,
// format!("failed to copy framebuffer into Java, error: {}", e),
// )
// .unwrap();
// }
}
#[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]
pub unsafe extern "C" fn Java_com_mrmichel_rustboyadvance_EmulatorBindings_log(
_env: JNIEnv,

View file

@ -29,11 +29,11 @@ use std::str::from_utf8;
#[derive(Serialize, Deserialize, Clone, Debug)]
pub struct CartridgeHeader {
// rom_entry_point: Addr,
game_title: String,
game_code: String,
maker_code: String,
software_version: u8,
checksum: u8,
pub game_title: String,
pub game_code: String,
pub maker_code: String,
pub software_version: u8,
pub checksum: u8,
// ram_entry_point: Addr,
// joybus_entry_point: Addr,
}

View file

@ -89,6 +89,14 @@ impl GameBoyAdvance {
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]
pub fn key_poll(&mut self) {
self.sysbus.io.keyinput = self.input_device.borrow_mut().poll();