1
I have a project of a CHIP-8 emulator that I’m trying to port to android, the entire emulator is written in C++ so I created a C++ library in android studio and added it to my project, the problem is, I need to manipulate it via Activity, whenever a user for example presses the back button the emulation loop should be paused, and whenever a button on the screen is pressed the loop should pause, check which "key" was pressed, perform the proper action in the emulator and finally summarize the loop, the problem is, the loop I created is running when it goes back to the previous Activity or crashes if I put it in the background to access another application, the loop model I think is similar to the SDL_PollEvent
which allows you to handle incoming events even with the running loop.
package com.samuelives.chipeight;
import android.os.Bundle;
import android.widget.Toast;
import com.samuelives.chipeight.emulator.RenderSurface;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
public class Emulator extends AppCompatActivity {
static {
System.loadLibrary("CHIP-8");
}
private RenderSurface svEmulator = null;
private boolean isRunning = true;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_emulator);
svEmulator = (RenderSurface)findViewById(R.id.svEmulator);
initEmulator();
if(!loadROM(getIntent().getStringExtra("gamePath"))){
Toast.makeText(this, "Could not load game", Toast.LENGTH_LONG).show();
stopEmulator();
finish();
}
cpuThread.start();
}
@Override
protected void onResume() {
super.onResume();
svEmulator.onResume();
isRunning = true;
if(!cpuThread.isAlive()){
cpuThread.notify();
}
}
@Override
protected void onPause() {
super.onPause();
svEmulator.onPause();
isRunning = false;
if(cpuThread.isAlive()) {
try {
cpuThread.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
//stopEmulator();
}
@Override
protected void onDestroy() {
super.onDestroy();
isRunning = false;
cpuThread.interrupt();
stopEmulator();
}
@Override
public void onBackPressed() {
super.onBackPressed();
isRunning = false;
cpuThread.interrupt();
stopEmulator();
}
private Thread cpuThread = new Thread(new Runnable() {
@Override
public void run() {
while(isRunning){
execute();
if(hasDraw()){
svEmulator.requestRender();
}
}
}
});
public native void initEmulator();
public native boolean loadROM(String path);
public native void execute();
public native void stopEmulator();
public native boolean hasDraw();
}