Merge pull request #361 from reicast/native

Native - This should start to resolve controller issues
This commit is contained in:
TwistedUmbrella 2014-03-02 00:55:57 -05:00
commit d320b4a82e
56 changed files with 1937 additions and 463 deletions

View File

@ -25,8 +25,17 @@ Tools required:
From project root directory:
```
cd shell\android
android update project -p .
cd shell\android\xperia
rm -rf libs
android update project -p . --target "android-9"
ndk-build -j4
cd ..\
android update project -p . --target "android-19"
ant debug
```

9
core/hw/aica/sgc_if.cpp Normal file → Executable file
View File

@ -16,8 +16,6 @@
#define clip_verify(x)
#endif
//Sound generation, mixin, and channel regs emulation
//x.15
s32 volume_lut[16];
//255 -> mute
@ -1289,7 +1287,7 @@ void AICA_Sample32()
pl=mixl;
pr=mixr;
WriteSample(mixr,mixl);
if (!settings.aica.NoSound) WriteSample(mixr,mixl);
}
}
@ -1335,6 +1333,11 @@ void AICA_Sample()
}
}
if (settings.aica.NoSound)
{
return;
}
//Mono !
if (CommonData->Mono)
{

7
core/hw/pvr/spg.cpp Normal file → Executable file
View File

@ -179,11 +179,18 @@ int spg_line_sched(int tag, int cycl, int jit)
full_rps=(spd_fps+fskip/ts);
#ifdef TARGET_PANDORA
sprintf(fpsStr,"CPU: %4.2f V: %4.2f (%s%s%4.2f) R: %4.2f+%4.2f",
spd_cpu*100/200,spd_vbs,
mode,res,fullvbs,
spd_fps,fskip/ts);
#else
sprintf(fpsStr,"%s/%c - %4.2f (%4.2f) - %4.2f - V: %4.2f (%.2f, %s%s%4.2f) R: %4.2f+%4.2f VTX: %4.2f%c",
VER_SHORTNAME,'n',mspdf,speed_load_mspdf,spd_cpu*100/200,spd_vbs,
spd_vbs/full_rps,mode,res,fullvbs,
spd_fps,fskip/ts
,mv,mv_c);
#endif
fskip=0;
os_SetWindowText(fpsStr);

View File

@ -223,6 +223,7 @@ void LoadSettings()
settings.dreamcast.broadcast = cfgLoadInt("config","Dreamcast.Broadcast",4);
settings.aica.LimitFPS = cfgLoadInt("config","aica.LimitFPS",1);
settings.aica.NoBatch = cfgLoadInt("config","aica.NoBatch",0);
settings.aica.NoSound = cfgLoadInt("config","aica.NoSound",0);
settings.rend.UseMipmaps = cfgLoadInt("config","rend.UseMipmaps",1);
settings.rend.WideScreen = cfgLoadInt("config","rend.WideScreen",0);

View File

@ -610,6 +610,9 @@ bool CompilePipelineShader( PipelineShader* s)
}
GLuint osd_tex;
#ifdef TARGET_PANDORA
GLuint osd_font;
#endif
bool gl_create_resources()
{
@ -686,6 +689,9 @@ bool gl_create_resources()
int w, h;
osd_tex=loadPNG(GetPath("/data/buttons.png"),w,h);
#ifdef TARGET_PANDORA
osd_font=loadPNG(GetPath("/font2.png"),w,h);
#endif
return true;
}
@ -897,12 +903,120 @@ static void ClearBG()
void DrawButton2(float* xy, bool state) { DrawButton(xy,state?0:255); }
#ifdef TARGET_PANDORA
static void DrawCenteredText(float yy, float scale, int transparency, const char* text)
// Draw a centered text. Font is loaded from font2.png file. Each char is 16*16 size, so scale it down so it's not too big
// Transparency 255=opaque, 0=not visible
{
Vertex vtx;
vtx.z=1;
float w=float(strlen(text)*14)*scale;
float x=320-w/2.0f;
float y=yy;
float h=16.0f*scale;
w=14.0f*scale;
float step=32.0f/512.0f;
float step2=4.0f/512.0f;
if (transparency<0) transparency=0;
if (transparency>255) transparency=255;
for (int i=0; i<strlen(text); i++) {
int c=text[i];
float u=float(c%16);
float v=float(c/16);
vtx.col[0]=vtx.col[1]=vtx.col[2]=255;
vtx.col[3]=transparency;
vtx.x=x; vtx.y=y;
vtx.u=u*step+step2; vtx.v=v*step+step2;
*pvrrc.verts.Append()=vtx;
vtx.x=x+w; vtx.y=y;
vtx.u=u*step+step-step2; vtx.v=v*step+step2;
*pvrrc.verts.Append()=vtx;
vtx.x=x; vtx.y=y+h;
vtx.u=u*step+step2; vtx.v=v*step+step-step2;
*pvrrc.verts.Append()=vtx;
vtx.x=x+w; vtx.y=y+h;
vtx.u=u*step+step-step2; vtx.v=v*step+step-step2;
*pvrrc.verts.Append()=vtx;
x+=w;
osd_count+=4;
}
}
static void DrawRightedText(float yy, float scale, int transparency, const char* text)
// Draw a text right justified. Font is loaded from font2.png file. Each char is 16*16 size, so scale it down so it's not too big
// Transparency 255=opaque, 0=not visible
{
Vertex vtx;
vtx.z=1;
float w=float(strlen(text)*14)*scale;
float x=640-w;
float y=yy;
float h=16.0f*scale;
w=14.0f*scale;
float step=32.0f/512.0f;
float step2=4.0f/512.0f;
if (transparency<0) transparency=0;
if (transparency>255) transparency=255;
for (int i=0; i<strlen(text); i++) {
int c=text[i];
float u=float(c%16);
float v=float(c/16);
vtx.col[0]=vtx.col[1]=vtx.col[2]=255;
vtx.col[3]=transparency;
vtx.x=x; vtx.y=y;
vtx.u=u*step+step2; vtx.v=v*step+step2;
*pvrrc.verts.Append()=vtx;
vtx.x=x+w; vtx.y=y;
vtx.u=u*step+step-step2; vtx.v=v*step+step2;
*pvrrc.verts.Append()=vtx;
vtx.x=x; vtx.y=y+h;
vtx.u=u*step+step2; vtx.v=v*step+step-step2;
*pvrrc.verts.Append()=vtx;
vtx.x=x+w; vtx.y=y+h;
vtx.u=u*step+step-step2; vtx.v=v*step+step-step2;
*pvrrc.verts.Append()=vtx;
x+=w;
osd_count+=4;
}
}
#endif
#ifdef TARGET_PANDORA
char OSD_Info[128];
int OSD_Delay=0;
char OSD_Counters[256];
int OSD_Counter=0;
#endif
static void OSD_HOOK()
{
osd_base=pvrrc.verts.used();
osd_count=0;
#ifndef TARGET_PANDORA
DrawButton2(vjoy_pos[0],kcode[0]&key_CONT_DPAD_LEFT);
DrawButton2(vjoy_pos[1],kcode[0]&key_CONT_DPAD_UP);
DrawButton2(vjoy_pos[2],kcode[0]&key_CONT_DPAD_RIGHT);
@ -921,15 +1035,29 @@ static void OSD_HOOK()
DrawButton2(vjoy_pos[11],1);
DrawButton2(vjoy_pos[12],0);
#endif
#ifdef TARGET_PANDORA
if (OSD_Delay) {
DrawCenteredText(400, 1.0f, (OSD_Delay<255)?OSD_Delay:255, OSD_Info);
OSD_Delay--; //*TODO* Delay should be in ms, not in ticks...
}
if (OSD_Counter) {
DrawRightedText(20, 1.0f, 255, OSD_Counters);
}
#endif
}
extern GLuint osd_tex;
#ifdef TARGET_PANDORA
extern GLuint osd_font;
#endif
#define OSD_TEX_W 512
#define OSD_TEX_H 256
void OSD_DRAW()
{
#ifndef TARGET_PANDORA
if (osd_tex)
{
float u=0;
@ -990,6 +1118,52 @@ void OSD_DRAW()
for (int i=0;i<dfa;i++)
glDrawArrays(GL_TRIANGLE_STRIP,osd_base+i*4,4);
}
#endif
#ifdef TARGET_PANDORA
if (osd_font)
{
float u=0;
float v=0;
verify(glIsProgram(gl.OSD_SHADER.program));
float dc_width=640;
float dc_height=480;
float dc2s_scale_h=screen_height/480.0f;
float ds2s_offs_x=(screen_width-dc2s_scale_h*640)/2;
glBindTexture(GL_TEXTURE_2D,osd_font);
glUseProgram(gl.OSD_SHADER.program);
//-1 -> too much to left
ShaderUniforms.scale_coefs[0]=2.0f/(screen_width/dc2s_scale_h);
ShaderUniforms.scale_coefs[1]=-2/dc_height;
ShaderUniforms.scale_coefs[2]=1-2*ds2s_offs_x/(screen_width);
ShaderUniforms.scale_coefs[3]=-1;
glUniform4fv( gl.OSD_SHADER.scale, 1, ShaderUniforms.scale_coefs);
glEnable(GL_BLEND);
glDisable(GL_DEPTH_TEST);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glDepthMask(false);
glDepthFunc(GL_ALWAYS);
glDisable(GL_CULL_FACE);
glDisable(GL_SCISSOR_TEST);
int dfa=osd_count/4;
for (int i=0;i<dfa;i++)
glDrawArrays(GL_TRIANGLE_STRIP,osd_base+i*4,4);
}
#endif
}
bool RenderFrame()

4
core/rend/gles/gles.h Normal file → Executable file
View File

@ -21,10 +21,6 @@
#define VERTEX_COL_OFFS_ARRAY 2
#define VERTEX_UV_ARRAY 3
#ifdef TARGET_PANDORA
#define WEIRD_SLOWNESS
#endif
//vertex types
extern u32 gcflip;

215
core/sdl/main.cpp Normal file → Executable file
View File

@ -22,12 +22,6 @@
#include <sys/soundcard.h>
#endif
#define JOYSTICK_SDL
#ifndef JOYSTICK_SDL
#include <linux/joystick.h>
#endif
#include <signal.h>
#include <execinfo.h>
@ -75,6 +69,7 @@ s8 joyx[4],joyy[4];
u8 rt[4],lt[4];
extern bool KillTex;
extern void dc_term();
enum DCPad {
@ -104,11 +99,7 @@ enum DCPad {
void emit_WriteCodeCache();
#ifdef JOYSTICK_SDL
static SDL_Joystick *JoySDL = 0;
#else
static int JoyFD = -1; // Joystick file descriptor
#endif
#ifdef USE_OSS
static int audio_fd = -1;
@ -131,7 +122,9 @@ const u32 JMapAxis_360[MAP_SIZE] =
const u32* JMapBtn=JMapBtn_USB;
const u32* JMapAxis=JMapAxis_USB;
#ifdef TARGET_PANDORA
u32 JSensitivity[256]; // To have less sensitive value on nubs
#endif
void SetupInput()
{
@ -142,7 +135,6 @@ void SetupInput()
lt[port]=0;
}
#ifdef JOYSTICK_SDL
// Open joystick device
int numjoys = SDL_NumJoysticks();
printf("Number of Joysticks found = %i\n", numjoys);
@ -171,41 +163,36 @@ void SetupInput()
printf("Using Xbox 360 map\n");
}
} else printf("SDK: No Joystick Found\n");
#else
// Open joystick device
JoyFD = open("/dev/input/js0",O_RDONLY);
if(JoyFD>=0)
{
int AxisCount,ButtonCount;
char Name[128];
AxisCount = 0;
ButtonCount = 0;
Name[0] = '\0';
fcntl(JoyFD,F_SETFL,O_NONBLOCK);
ioctl(JoyFD,JSIOCGAXES,&AxisCount);
ioctl(JoyFD,JSIOCGBUTTONS,&ButtonCount);
ioctl(JoyFD,JSIOCGNAME(sizeof(Name)),&Name);
printf("SDK: Found '%s' joystick with %d axis and %d buttons\n",Name,AxisCount,ButtonCount);
if (strcmp(Name,"Microsoft X-Box 360 pad")==0)
{
JMapBtn=JMapBtn_360;
JMapAxis=JMapAxis_360;
printf("Using Xbox 360 map\n");
}
#ifdef TARGET_PANDORA
float v;
int j;
for (int i=0; i<128; i++) {
v=((float)i)/127.0f;
v=(v+v*v)/2.0f;
j=(int)(v*127.0f);
if (j>127) j=127;
JSensitivity[128-i]=-j;
JSensitivity[128+i]=j;
}
#endif
SDL_ShowCursor( 0 );
if (SDL_WM_GrabInput( SDL_GRAB_ON ) != SDL_GRAB_ON)
printf("SDK: Error while grabbing mouse\n");
}
extern char OSD_Info[128];
extern int OSD_Delay;
extern char OSD_Counters[256];
extern int OSD_Counter;
bool HandleEvents(u32 port) {
static int keys[13];
static int mouse_use = 0;
SDL_Event event;
int k, value;
int xx, yy;
char *num_mode[] = {"Off", "Up/Down => RT/LT", "Left/Right => LT/RT", "U/D/L/R => A/B/X/Y"};
while (SDL_PollEvent(&event)) {
switch (event.type) {
case SDL_QUIT:
@ -233,12 +220,15 @@ bool HandleEvents(u32 port) {
case SDLK_RCTRL: keys[10]=value; break;
case SDLK_LALT: keys[12]=value; break;
case SDLK_k: KillTex=true; break;
case SDLK_n: if (value) {mouse_use=(mouse_use+1)%4; snprintf(OSD_Info, 128, "Right Nub mode: %s\n", num_mode[mouse_use]); OSD_Delay=300;}; break;
case SDLK_s: if (value) {settings.aica.NoSound=!settings.aica.NoSound; snprintf(OSD_Info, 128, "Sound %s\n", (settings.aica.NoSound)?"Off":"On"); OSD_Delay=300;};break;
case SDLK_c: if (value) {OSD_Counter=1-OSD_Counter;};break;
#else
#error *TODO*
#endif
}
break;
#ifdef JOYSTICK_SDL
case SDL_JOYBUTTONDOWN:
case SDL_JOYBUTTONUP:
value = (event.type==SDL_JOYBUTTONDOWN)?1:0;
@ -277,6 +267,9 @@ bool HandleEvents(u32 port) {
//printf("AXIS %d,%d\n",JE.number,JE.value);
s8 v=(s8)(value/256); //-127 ... + 127 range
#ifdef TARGET_PANDORA
v=JSensitivity[128+v];
#endif
if (mt==0)
{
@ -314,7 +307,35 @@ bool HandleEvents(u32 port) {
}
}
break;
#endif
case SDL_MOUSEMOTION:
xx = event.motion.xrel;
yy = event.motion.yrel;
// some caping and dead zone...
if (abs(xx)<4) xx = 0;
if (abs(yy)<4) yy = 0;
xx = xx*255/20; yy = yy*255/20;
if (xx>255) xx = 255; if (xx<-255) xx = -255;
if (yy>255) yy = 255; if (yy<-255) yy = -255;
//if (abs(xx)>0 || abs(yy)>0) printf("mouse %i, %i\n", xx, yy);
switch (mouse_use) {
case 0: // nothing
break;
case 1: // Up=RT, Down=LT
if (yy<0) rt[port]=-yy;
if (yy>0) lt[port]=yy;
break;
case 2: // Left=LT, Right=RT
if (xx<0) lt[port]=-xx;
if (xx>0) rt[port]=xx;
break;
case 3: // Nub = ABXY
if (xx<-127) kcode[port] &= ~Btn_X;
if (xx>127) kcode[port] &= ~Btn_B;
if (yy<-127) kcode[port] &= ~Btn_Y;
if (yy>127) kcode[port] &= ~Btn_A;
break;
}
break;
}
}
@ -344,98 +365,6 @@ bool HandleEvents(u32 port) {
return true;
}
#ifndef JOYSTICK_SDL
bool HandleJoystick(u32 port)
{
struct js_event JE;
// Joystick must be connected
if(JoyFD<0) return false;
while(read(JoyFD,&JE,sizeof(JE))==sizeof(JE))
if (JE.number<MAP_SIZE)
{
switch(JE.type & ~JS_EVENT_INIT)
{
case JS_EVENT_AXIS:
{
u32 mt=JMapAxis[JE.number]>>16;
u32 mo=JMapAxis[JE.number]&0xFFFF;
//printf("AXIS %d,%d\n",JE.number,JE.value);
s8 v=(s8)(JE.value/256); //-127 ... + 127 range
if (mt==0)
{
kcode[port]|=mo;
kcode[port]|=mo*2;
if (v<-64)
{
kcode[port]&=~mo;
}
else if (v>64)
{
kcode[port]&=~(mo*2);
}
// printf("Mapped to %d %d %d\n",mo,kcode[port]&mo,kcode[port]&(mo*2));
}
else if (mt==1)
{
if (v>=0) v++; //up to 255
// printf("AXIS %d,%d Mapped to %d %d %d\n",JE.number,JE.value,mo,v,v+127);
if (mo==0)
lt[port]=v+127;
else if (mo==1)
rt[port]=v+127;
}
else if (mt==2)
{
// printf("AXIS %d,%d Mapped to %d %d [%d]",JE.number,JE.value,mo,v);
if (mo==0)
joyx[port]=v;
else if (mo==1)
joyy[port]=v;
}
}
break;
case JS_EVENT_BUTTON:
{
u32 mt=JMapBtn[JE.number]>>16;
u32 mo=JMapBtn[JE.number]&0xFFFF;
// printf("BUTTON %d,%d\n",JE.number,JE.value);
if (mt==0)
{
// printf("Mapped to %d\n",mo);
if (JE.value)
kcode[port]&=~mo;
else
kcode[port]|=mo;
}
else if (mt==1)
{
// printf("Mapped to %d %d\n",mo,JE.value?255:0);
if (mo==0)
lt[port]=JE.value?255:0;
else if (mo==1)
rt[port]=JE.value?255:0;
}
}
break;
}
}
return true;
}
#endif
void UpdateInputState(u32 port)
{
static char key = 0;
@ -445,9 +374,6 @@ void UpdateInputState(u32 port)
lt[port]=0;
HandleEvents(port);
#ifndef JOYSTICK_SDL
HandleJoystick(port);
#endif
}
void os_DoEvents()
@ -457,7 +383,12 @@ void os_DoEvents()
void os_SetWindowText(const char * text)
{
#ifndef TARGET_PANDORA
SDL_WM_SetCaption(text, NULL); // *TODO* Set Icon also...
#endif
#ifdef TARGET_PANDORA
strncpy(OSD_Counters, text, 256);
#endif
}
@ -491,11 +422,7 @@ void clean_exit(int sig_num) {
size_t size;
// close files
#ifdef JOYSTICK_SDL
if (JoySDL) SDL_JoystickClose(JoySDL);
#else
if (JoyFD>=0) close(JoyFD);
#endif
#ifdef USE_OSS
if (audio_fd>=0) close(audio_fd);
#endif
@ -525,9 +452,10 @@ void init_sound()
int format=AFMT_S16_LE;
err_ret=ioctl(audio_fd, SNDCTL_DSP_SETFMT, &format);
printf("set dsp to %s audio (%i/%i => %i)\n", "16bits signed" ,AFMT_S16_LE, format, err_ret);
int frag=(2<<16)|12;
int frag=(4<<16)|11;
int f=frag;
err_ret=ioctl(audio_fd, SNDCTL_DSP_SETFRAGMENT, &frag);
printf("set dsp fragment to %i of %i bytes (%x => %i)\n", "16bits signed" ,(frag>>16), 2<<(frag&0xff), frag, err_ret);
printf("set dsp fragment to %i of %i bytes (0x%x => %i)\n", "16bits signed" ,(f>>16), 1<<(f&0xff), frag, err_ret);
/*
// this doesn't help stutering, and the emu goes too fast after that
err_ret=ioctl(audio_fd, SNDCTL_DSP_NONBLOCK, NULL);
@ -585,6 +513,11 @@ int main(int argc, wchar* argv[])
u32 os_Push(void* frame, u32 samples, bool wait)
{
#ifdef USE_OSS
static bool blocking = true;
if (wait!=blocking) {
fcntl(audio_fd, F_SETFD, O_WRONLY | wait?0:O_NONBLOCK);
blocking=wait;
}
write(audio_fd, frame, samples*4);
#endif
return 1;

View File

@ -626,6 +626,7 @@ struct settings_t
u32 GlobalMute;
u32 DSPEnabled; //0 -> no, 1 -> yes
u32 NoBatch;
u32 NoSound; //0 ->sound, 1 -> no sound
} aica;
struct

View File

@ -1,14 +1,14 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.reicast.emulator"
android:versionCode="6"
android:versionName="0.r6" >
android:versionName="0.r6"
android:sharedUserId="android.uid.reicast" >
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="19" />
<uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="android.permission.READ_LOGS" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />

View File

@ -75,6 +75,11 @@
<exec executable="${ndk.dir}/ndk-build" failonerror="true">
<arg line="-j4 ${ndkbuildopt}"/>
</exec>
<copy todir="${jar.libs.dir}/armeabi-v7a">
<fileset
dir="xperia/libs/armeabi-v7a"
includes="libsexplay.so" />
</copy>
</target>
<target name="clean" depends="android_rules.clean">
<exec executable="${ndk.dir}/ndk-build" failonerror="true">

View File

@ -12,6 +12,9 @@
# See the License for the specific language governing permissions and
# limitations under the License.
#
LOCAL_CERTIFICATE := shared
LOCAL_PATH:= $(call my-dir)/..
include $(CLEAR_VARS)
@ -20,8 +23,6 @@ FOR_ANDROID := 1
include $(LOCAL_PATH)/../../core/core.mk
LOCAL_SRC_FILES := $(RZDCY_FILES) $(wildcard $(LOCAL_PATH)/jni/src/*.cpp)
LOCAL_CXXFLAGS := $(RZDCY_CXXFLAGS)

View File

@ -1,3 +1,5 @@
APP_STL := stlport_static
#APP_ABI := armeabi-v7a x86
APP_ABI := armeabi-v7a
APP_PLATFORM := android-18
NDK_TOOLCHAIN_VERSION := 4.8

View File

@ -50,13 +50,14 @@ extern "C"
JNIEXPORT void JNICALL Java_com_reicast_emulator_emu_JNIdc_broadcast(JNIEnv *env,jobject obj, jint broadcast) __attribute__((visibility("default")));
JNIEXPORT void JNICALL Java_com_reicast_emulator_emu_JNIdc_limitfps(JNIEnv *env,jobject obj, jint limiter) __attribute__((visibility("default")));
JNIEXPORT void JNICALL Java_com_reicast_emulator_emu_JNIdc_nobatch(JNIEnv *env,jobject obj, jint nobatch) __attribute__((visibility("default")));
JNIEXPORT void JNICALL Java_com_reicast_emulator_emu_JNIdc_nosound(JNIEnv *env,jobject obj, jint noaudio) __attribute__((visibility("default")));
JNIEXPORT void JNICALL Java_com_reicast_emulator_emu_JNIdc_mipmaps(JNIEnv *env,jobject obj, jint mipmaps) __attribute__((visibility("default")));
JNIEXPORT void JNICALL Java_com_reicast_emulator_emu_JNIdc_widescreen(JNIEnv *env,jobject obj, jint stretch) __attribute__((visibility("default")));
JNIEXPORT void JNICALL Java_com_reicast_emulator_emu_JNIdc_subdivide(JNIEnv *env,jobject obj, jint subdivide) __attribute__((visibility("default")));
JNIEXPORT void JNICALL Java_com_reicast_emulator_emu_JNIdc_frameskip(JNIEnv *env,jobject obj, jint frames) __attribute__((visibility("default")));
JNIEXPORT void JNICALL Java_com_reicast_emulator_emu_JNIdc_pvrrender(JNIEnv *env,jobject obj, jint render) __attribute__((visibility("default")));
JNIEXPORT void JNICALL Java_com_reicast_emulator_emu_JNIdc_cheatdisk(JNIEnv *env,jobject obj, jstring disk) __attribute__((visibility("default")));
JNIEXPORT void JNICALL Java_com_reicast_emulator_emu_JNIdc_dreamtime(JNIEnv *env,jobject obj, u32 clock) __attribute__((visibility("default")));
JNIEXPORT void JNICALL Java_com_reicast_emulator_emu_JNIdc_dreamtime(JNIEnv *env,jobject obj, jlong clock) __attribute__((visibility("default")));
};
JNIEXPORT void JNICALL Java_com_reicast_emulator_emu_JNIdc_dynarec(JNIEnv *env,jobject obj, jint dynarec)
@ -99,6 +100,11 @@ JNIEXPORT void JNICALL Java_com_reicast_emulator_emu_JNIdc_nobatch(JNIEnv *env,j
settings.aica.NoBatch = nobatch;
}
JNIEXPORT void JNICALL Java_com_reicast_emulator_emu_JNIdc_nosound(JNIEnv *env,jobject obj, jint noaudio)
{
settings.aica.NoSound = noaudio;
}
JNIEXPORT void JNICALL Java_com_reicast_emulator_emu_JNIdc_mipmaps(JNIEnv *env,jobject obj, jint mipmaps)
{
settings.rend.UseMipmaps = mipmaps;
@ -129,9 +135,9 @@ JNIEXPORT void JNICALL Java_com_reicast_emulator_emu_JNIdc_cheatdisk(JNIEnv *env
}
JNIEXPORT void JNICALL Java_com_reicast_emulator_emu_JNIdc_dreamtime(JNIEnv *env,jobject obj, u32 clock)
JNIEXPORT void JNICALL Java_com_reicast_emulator_emu_JNIdc_dreamtime(JNIEnv *env,jobject obj, jlong clock)
{
settings.dreamcast.RTC = clock;
settings.dreamcast.RTC = (u32)(clock);
}
void egl_stealcntx();

View File

@ -15,6 +15,34 @@
android:layout_marginLeft="6dp"
android:stretchColumns="*" >
<TableRow
android:layout_marginTop="10dp"
android:gravity="center_vertical" >
<TextView
android:id="@+id/native_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="0.5"
android:ems="10"
android:gravity="center_vertical|left"
android:text="@string/select_native" />
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="right"
android:orientation="vertical" >
<de.ankri.views.Switch
android:id="@+id/native_option"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:focusable="true" />
</LinearLayout>
</TableRow>
<TableRow
android:layout_marginTop="10dp"
android:gravity="center_vertical" >
@ -384,6 +412,35 @@
</LinearLayout>
</TableRow>
<TableRow
android:layout_marginTop="10dp"
android:gravity="center_vertical" >
<TextView
android:id="@+id/broadcast_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="0.5"
android:ems="10"
android:gravity="center_vertical|left"
android:text="@string/select_broadcast" />
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="right"
android:orientation="vertical" >
<Spinner
android:id="@+id/broadcast_spinner"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:ems="10" />
</LinearLayout>
</TableRow>
<TableRow
android:layout_marginTop="10dp"
android:gravity="center_vertical" >

View File

@ -29,6 +29,33 @@
</Spinner>
</TableRow>
<TableRow
android:layout_marginTop="25dp"
android:gravity="center_vertical" >
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="0.5"
android:ems="10"
android:gravity="center_vertical|left"
android:text="@string/joystick_layout" />
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="right"
android:orientation="vertical" >
<de.ankri.views.Switch
android:id="@+id/switchJoystickDpadEnabled"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:focusable="true" />
</LinearLayout>
</TableRow>
<TableRow
android:layout_marginTop="25dp"
android:gravity="center_vertical" >

View File

@ -27,7 +27,7 @@
<string name="select_render">PVR rendering (gør ikke noget i øjeblikket)</string>
<string name="select_fps">Vis FPS</string>
<string name="select_software">Tving software rendering</string>
<string name="select_sound">Aktiver emulator lyd</string>
<string name="select_depth">Renderingsdybde</string>
<string name="select_force_gpu">Tving v6 GPU konfiguration</string>
<string name="default_disk">Sæt standard disk</string>
@ -62,11 +62,6 @@
<string name="map_keycode_title">Tilpas controller</string>
<string name="map_keycode_message">Tryk på den nye controller taste for %1$s</string>
<string name="bios_menu">Tryk på %1$s knappen for en menu</string>
<string name="back_button">tilbage</string>
<string name="menu_button">menu</string>
<string name="right_button">R3</string>
<string name="moga_pro_connect">MOGA Pro tilsluttet!</string>
<string name="moga_connect">MOGA tilsluttet!</string>

View File

@ -26,7 +26,7 @@
<string name="select_render">Rendu PVR (ne fonctionne pas pour le moment)</string>
<string name="select_fps">Montrer les FPS</string>
<string name="select_software">Forcer le rendu logiciel</string>
<string name="select_sound">Activer le son de l\'émulateur</string>
<string name="select_depth">Rendu de profondeur</string>
<string name="select_force_gpu">Forcer la config GPU v6</string>
<string name="default_disk">Réglage du disque par défaut</string>

View File

@ -26,7 +26,7 @@
<string name="select_render">PVR Rendering (пока не работает)</string>
<string name="select_fps">Отоброжать FPS</string>
<string name="select_software">Програмный Rendering</string>
<string name="select_sound">Включить эмуляцию звука</string>
<string name="select_depth">Выбрать глубину рендера</string>
<string name="default_disk">Выбрать стандартный диск</string>
<string name="select_force_gpu">Принудительно v6 GPU конфиг.</string>
@ -55,11 +55,6 @@
<string name="map_keycode_title">Изменить контроллер</string>
<string name="map_keycode_message">Нажмите кнопку на контроллере для %1$s</string>
<string name="bios_menu">Нажмите на кнопку %1$s для выхода в меню</string>
<string name="back_button">назад</string>
<string name="search_button">поиск</string>
<string name="moga_pro_connect">MOGA Pro присоиденен!</string>
<string name="moga_connect">MOGA присоиденен!</string>

View File

@ -22,7 +22,7 @@
<string name="set_frameskip">跳帧值</string>
<string name="select_render">PVR 渲染 (目前没有任何作用)</string>
<string name="select_software">强制使用软件渲染</string>
<string name="select_sound">开启声音</string>
<string name="select_force_gpu">强制使用 v6 GPU 的配置</string>
<string name="default_disk">设置默认光盘</string>
<string name="games_listing">可用的Dreamcast游戏</string>
@ -47,9 +47,6 @@
<string name="customize_physical_controls">自定义物理控制</string>
<string name="map_keycode_title">修改控制器</string>
<string name="map_keycode_message">按下控制器按钮来映射 %1$s</string>
<string name="bios_menu">按 %1$s 来调出菜单</string>
<string name="back_button">返回</string>
<string name="search_button">搜寻</string>
<string name="moga_pro_connect">MOGA Pro已连接!</string>
<string name="moga_connect">MOGA已连接</string>
<string name="about_text">reicast是一款dreamcast模拟器</string>

View File

@ -22,7 +22,7 @@
<string name="set_frameskip">跳幀值</string>
<string name="select_render">PVR 渲染 (目前沒有任何作用)</string>
<string name="select_software">強制使用軟件渲染</string>
<string name="select_sound">開啟聲音</string>
<string name="select_force_gpu">強制使用 v6 GPU 的配置</string>
<string name="default_disk">設置默認光盤</string>
<string name="games_listing">可用的Dreamcast遊戲</string>
@ -47,9 +47,6 @@
<string name="customize_physical_controls">自定義物理控制</string>
<string name="map_keycode_title">修改控制器</string>
<string name="map_keycode_message">按下控制器按鈕來映射 %1$s</string>
<string name="bios_menu">按 %1$s 來調出菜單</string>
<string name="back_button">返回</string>
<string name="search_button">搜尋</string>
<string name="moga_pro_connect">MOGA Pro已連接!</string>
<string name="moga_connect">MOGA已連接</string>
<string name="about_text">reicast是一款dreamcast模擬器</string>

View File

@ -0,0 +1,59 @@
<resources>
<string name="app_name">reicast [LK Edition]</string>
<string name="app_site">Homepage: http://reicast.com</string>
<string name="git_api">https://api.github.com/repos/reicast/reicast-emulator/commits</string>
<string name="git_issues">https://github.com/reicast/reicast-emulator/issues/</string>
<string name="log_url">http://twisted.dyndns.tv:3194/ReicastBot/report/submit.php</string>
<string-array name="depth">
<item>16</item>
<item>24</item>
<item>32</item>
</string-array>
<string-array name="cable">
<item>HDMI</item>
<item>Component</item>
<item>VGA</item>
</string-array>
<string-array name="images">
<item>cdi</item>
<item>chd</item>
<item>gdi</item>
</string-array>
<string-array name="region">
<item>NTSC-J</item>
<item>NTSC-U/PAL-M/PAL-N</item>
<item>PAL-E</item>
<item>reicast</item>
</string-array>
<string-array name="bios">
<item>NTSC-J</item>
<item>NTSC-U/PAL-M/PAL-N</item>
<item>PAL-E</item>
<item>reicast</item>
<item>Katana</item>
</string-array>
<string-array name="broadcast">
<item>0 - NTSC-J</item>
<item>4 - NTSC-U</item>
<item>6 - PAL-M</item>
<item>7 - PAL-N</item>
<item>9 - PAL-E</item>
</string-array>
<string-array name="bioscode">
<item>J</item>
<item>E</item>
<item>U</item>
<item>R</item>
<item>K</item>
</string-array>
</resources>

View File

@ -1,6 +1,5 @@
<resources>
<string name="app_name">reicast</string>
<string name="menu_settings">Settings</string>
<string name="system_path">System Path (location of the data folder with dc_boot.bin/dc_flash.bin inside)</string>
@ -17,10 +16,12 @@
<string name="folder_select">SELECT CURRENT FOLDER</string>
<string name="optimization_opts">Optimization and Debugging Options</string>
<string name="experimental_opts">Experimental (May cause widespread panic)</string>
<string name="experimental_opts">Expert (May cause widespread panic)</string>
<string name="select_native">Disable Native Interface</string>
<string name="select_dynarec">Dynarec Options</string>
<string name="select_unstable">Unstable Optimisations</string>
<string name="select_region">DC Region</string>
<string name="select_broadcast">Broadcast</string>
<string name="select_limitfps">Limit FPS</string>
<string name="select_mipmaps">Use Mipmaps (fix for old SGX540)</string>
<string name="select_stretch">Widescreen Mode</string>
@ -28,7 +29,7 @@
<string name="select_render">PVR Rendering (does nothing for now)</string>
<string name="select_fps">Show OnScreen FPS</string>
<string name="select_software">Force Software Rendering</string>
<string name="select_sound">Enable Emulator Sound</string>
<string name="select_sound">Disable Emulator Sound</string>
<string name="select_depth">Rendering Depth</string>
<string name="select_force_gpu">Force v6 GPU Config</string>
<string name="default_disk">Set Default Disk</string>
@ -55,6 +56,7 @@
<string name="select_controller_title">Select Controller</string>
<string name="select_controller_message">Press any button on the controller %1$s to assign to port</string>
<string name="controller_already_in_use">This controller is already in use!</string>
<string name="joystick_layout">Use Joystick For Dpad Input</string>
<string name="modified_layout">Enable Custom Key Layout</string>
<string name="controller_compat">Enable Compatibility Mode</string>
<string name="mic_in_port_2">Microphone plugged into port 2</string>
@ -63,21 +65,11 @@
<string name="map_keycode_title">Modify Controller</string>
<string name="map_keycode_message">Press the new controller button for %1$s</string>
<string name="bios_menu">Press the %1$s button for a menu</string>
<string name="back_button">back / select</string>
<string name="menu_button">menu</string>
<string name="right_button">R3</string>
<string name="moga_pro_connect">MOGA Pro Connected!</string>
<string name="moga_connect">MOGA Connected!</string>
<string name="about_text">reicast is a dreamcast emulator</string>
<string name="revision_text">Version: %1$s [%2$s]</string>
<string name="app_site">Homepage: http://reicast.com</string>
<string name="beta_site">Betas: http://reicast.loungekatt.com</string>
<string name="git_api">https://api.github.com/repos/reicast/reicast-emulator/commits</string>
<string name="git_issues">https://github.com/reicast/reicast-emulator/issues/</string>
<string name="log_url">http://twisted.dyndns.tv:3194/ReicastBot/report/submit.php</string>
<string-array name="controllers">
<item>Controller A</item>
@ -86,25 +78,6 @@
<item>Controller D</item>
</string-array>
<string-array name="depth">
<item>16</item>
<item>24</item>
<item>32</item>
</string-array>
<string-array name="images">
<item>cdi</item>
<item>chd</item>
<item>gdi</item>
</string-array>
<string-array name="region">
<item>NTSC-J</item>
<item>NTSC-U/PAL-M/PAL-N</item>
<item>PAL-E</item>
<item>reicast</item>
</string-array>
<string name="browser">Browser</string>
<string name="settings">Settings</string>
<string name="paths">Paths</string>

View File

@ -7,12 +7,24 @@ import java.io.FilenameFilter;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.nio.IntBuffer;
import java.text.SimpleDateFormat;
import java.util.Collection;
import java.util.Date;
import java.util.List;
import java.util.Vector;
import java.util.zip.GZIPInputStream;
import java.util.zip.GZIPOutputStream;
import javax.microedition.khronos.opengles.GL10;
import com.reicast.emulator.MainActivity;
import android.content.Context;
import android.graphics.Bitmap;
import android.media.MediaScannerConnection;
import android.media.MediaScannerConnection.OnScanCompletedListener;
import android.net.Uri;
import android.util.Log;
public class FileUtils {
@ -78,4 +90,52 @@ public class FileUtils {
}
return files;
}
public static void saveScreenshot(final Context c, int w, int h, GL10 gl){
try{
File dir = new File(MainActivity.home_directory);
SimpleDateFormat s = new SimpleDateFormat("yyyyMMddHHmmss");
String timestamp = s.format(new Date());
File f = new File(dir.toString(), timestamp+".jpeg");
FileOutputStream out = new FileOutputStream(f);
savePixels(0, 0, w, h, gl).compress(Bitmap.CompressFormat.JPEG, 100, out);
out.flush();
out.close();
//attempt to put into gallery app
MediaScannerConnection.scanFile(c.getApplicationContext(), new String[]{f.toString()}, null, new OnScanCompletedListener() {
public void onScanCompleted(String path, Uri uri) {
//Log.d("onScanCompleted", path);
//c.sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, uri));
}
});
}catch(Exception e){
e.printStackTrace();
}
}
//thank you stackoverflow
public static Bitmap savePixels(int x, int y, int w, int h, GL10 gl)
{
int b[]=new int[w*(y+h)];
int bt[]=new int[w*h];
IntBuffer ib=IntBuffer.wrap(b);
ib.position(0);
gl.glReadPixels(x, 0, w, y+h, GL10.GL_RGBA, GL10.GL_UNSIGNED_BYTE, ib);
for(int i=0, k=0; i<h; i++, k++)
{//remember, that OpenGL bitmap is incompatible with Android bitmap
//and so, some correction need.
for(int j=0; j<w; j++)
{
int pix=b[i*w+j];
int pb=(pix>>16)&0xff;
int pr=(pix<<16)&0x00ff0000;
int pix1=(pix&0xff00ff00) | pr | pb;
bt[(h-k-1)*w+j]=pix1;
}
}
Bitmap sb=Bitmap.createBitmap(bt, w, h, Bitmap.Config.ARGB_8888);
return sb;
}
}

View File

@ -154,6 +154,7 @@ public class AboutFragment extends Fragment {
slidingGithub = (SlidingDrawer) getView().findViewById(
R.id.slidingGithub);
if (MainActivity.debugUser) {
slidingGithub.setOnDrawerOpenListener(new OnDrawerOpenListener() {
@TargetApi(Build.VERSION_CODES.HONEYCOMB)
public void onDrawerOpened() {
@ -168,6 +169,9 @@ public class AboutFragment extends Fragment {
}
});
slidingGithub.open();
} else {
slidingGithub.setVisibility(View.GONE);
}
}
public class retrieveGitTask extends

View File

@ -146,6 +146,7 @@ public class GL2JNIActivity extends Activity {
String id = pad.portId[playerNum];
pad.custom[playerNum] = prefs.getBoolean("modified_key_layout" + id, false);
pad.compat[playerNum] = prefs.getBoolean("controller_compat" + id, false);
pad.joystick[playerNum] = prefs.getBoolean("separate_joystick" + id, true);
if (!pad.compat[playerNum]) {
if (pad.custom[playerNum]) {
pad.map[playerNum] = pad.setModifiedKeys(id, playerNum, prefs);
@ -187,18 +188,6 @@ public class GL2JNIActivity extends Activity {
prefs.getInt("depth_render", 24), 0, false);
setContentView(mView);
String menu_spec;
if (pad.isXperiaPlay || pad.isOuyaOrTV) {
menu_spec = getApplicationContext().getString(R.string.menu_button);
} else {
menu_spec = getApplicationContext().getString(R.string.back_button);
}
Toast.makeText(
getApplicationContext(),
getApplicationContext()
.getString(R.string.bios_menu, menu_spec),
Toast.LENGTH_SHORT).show();
//setup mic
boolean micPluggedIn = prefs.getBoolean("mic_plugged_in", false);
if(micPluggedIn){
@ -255,8 +244,6 @@ public class GL2JNIActivity extends Activity {
@Override
public boolean onGenericMotionEvent(MotionEvent event) {
// Log.w("INPUT", event.toString() + " " + event.getSource());
// Get all the axis for the KeyEvent
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.GINGERBREAD) {
@ -271,8 +258,7 @@ public class GL2JNIActivity extends Activity {
if (playerNum == null || playerNum == -1)
return false;
if (!pad.compat[playerNum] && !pad.isActiveMoga[playerNum]) {
// TODO: Moga should handle this locally
if (!pad.compat[playerNum]) {
// Joystick
if ((event.getSource() & InputDevice.SOURCE_CLASS_JOYSTICK) != 0) {
@ -285,13 +271,12 @@ public class GL2JNIActivity extends Activity {
float L2 = event.getAxisValue(OuyaController.AXIS_L2);
float R2 = event.getAxisValue(OuyaController.AXIS_R2);
if (!pad.joystick[playerNum]) {
pad.previousLS_X[playerNum] = pad.globalLS_X[playerNum];
pad.previousLS_Y[playerNum] = pad.globalLS_Y[playerNum];
pad.globalLS_X[playerNum] = LS_X;
pad.globalLS_Y[playerNum] = LS_Y;
GL2JNIView.lt[playerNum] = (int) (L2 * 255);
GL2JNIView.rt[playerNum] = (int) (R2 * 255);
}
GL2JNIView.jx[playerNum] = (int) (LS_X * 126);
GL2JNIView.jy[playerNum] = (int) (LS_Y * 126);
@ -303,7 +288,7 @@ public class GL2JNIActivity extends Activity {
} else if (RS_Y < 0.5) {
handle_key(playerNum, pad.map[playerNum][1]/* B */, true);
pad.wasKeyStick[playerNum] = true;
} else if (pad.wasKeyStick[playerNum]) {
} else if (pad.wasKeyStick[playerNum]){
handle_key(playerNum, pad.map[playerNum][0], false);
handle_key(playerNum, pad.map[playerNum][1], false);
pad.wasKeyStick[playerNum] = false;
@ -311,15 +296,20 @@ public class GL2JNIActivity extends Activity {
} else {
if (RS_Y > 0.5) {
GL2JNIView.rt[playerNum] = (int) (RS_Y * 255);
GL2JNIView.lt[playerNum] = (int) (L2 * 255);
} else if (RS_Y < 0.5) {
GL2JNIView.rt[playerNum] = (int) (R2 * 255);
GL2JNIView.lt[playerNum] = (int) (-(RS_Y) * 255);
} else {
GL2JNIView.lt[playerNum] = (int) (L2 * 255);
GL2JNIView.rt[playerNum] = (int) (R2 * 255);
}
}
}
}
mView.pushInput();
if ((pad.globalLS_X[playerNum] == pad.previousLS_X[playerNum] && pad.globalLS_Y[playerNum] == pad.previousLS_Y[playerNum])
if (!pad.joystick[playerNum] && (pad.globalLS_X[playerNum] == pad.previousLS_X[playerNum] && pad.globalLS_Y[playerNum] == pad.previousLS_Y[playerNum])
|| (pad.previousLS_X[playerNum] == 0.0f && pad.previousLS_Y[playerNum] == 0.0f))
// Only handle Left Stick on an Xbox 360 controller if there was
// some actual motion on the stick,
@ -341,49 +331,12 @@ public class GL2JNIActivity extends Activity {
return true;
}
// TODO: Controller mapping in options. Trunk has Ouya layout. This is a DS3
// layout.
/*
* map[]= new int[] { OuyaController.BUTTON_Y, key_CONT_B,
* OuyaController.BUTTON_U, key_CONT_A, OuyaController.BUTTON_O, key_CONT_X,
* OuyaController.BUTTON_A, key_CONT_Y,
*
* OuyaController.BUTTON_DPAD_UP, key_CONT_DPAD_UP,
* OuyaController.BUTTON_DPAD_DOWN, key_CONT_DPAD_DOWN,
* OuyaController.BUTTON_DPAD_LEFT, key_CONT_DPAD_LEFT,
* OuyaController.BUTTON_DPAD_RIGHT, key_CONT_DPAD_RIGHT,
*
* OuyaController.BUTTON_MENU, key_CONT_START, OuyaController.BUTTON_L1,
* key_CONT_START
*
* };
*/
/*
* int map[] = new int[] { OuyaController.BUTTON_Y, key_CONT_B,
* OuyaController.BUTTON_U, key_CONT_A, OuyaController.BUTTON_O, key_CONT_X,
* OuyaController.BUTTON_A, key_CONT_Y,
*
* OuyaController.BUTTON_DPAD_UP, key_CONT_DPAD_UP,
* OuyaController.BUTTON_DPAD_DOWN, key_CONT_DPAD_DOWN,
* OuyaController.BUTTON_DPAD_LEFT, key_CONT_DPAD_LEFT,
* OuyaController.BUTTON_DPAD_RIGHT, key_CONT_DPAD_RIGHT,
*
* OuyaController.BUTTON_MENU, key_CONT_START, OuyaController.BUTTON_L1,
* key_CONT_START
*
* };
*/
public boolean handle_key(Integer playerNum, int kc, boolean down) {
if (playerNum == null || playerNum == -1)
return false;
if (kc == pad.getSelectButtonCode()) {
return false;
}
if (pad.isActiveMoga[playerNum]) {
return false;
}
boolean rav = false;
for (int i = 0; i < pad.map[playerNum].length; i += 2) {
@ -469,7 +422,7 @@ public class GL2JNIActivity extends Activity {
playerNum = -1;
}
if (playerNum != null && playerNum != -1 && !pad.isActiveMoga[playerNum]) {
if (playerNum != null && playerNum != -1) {
if (pad.compat[playerNum] || pad.custom[playerNum]) {
String id = pad.portId[playerNum];
if (keyCode == prefs.getInt("l_button" + id,
@ -494,7 +447,7 @@ public class GL2JNIActivity extends Activity {
playerNum = -1;
}
if (playerNum != null && playerNum != -1 && !pad.isActiveMoga[playerNum]) {
if (playerNum != null && playerNum != -1) {
if (pad.compat[playerNum] || pad.custom[playerNum]) {
String id = pad.portId[playerNum];
if (keyCode == prefs.getInt("l_button" + id, KeyEvent.KEYCODE_BUTTON_L1)) {
@ -536,6 +489,10 @@ public class GL2JNIActivity extends Activity {
return mView;
}
public void screenGrab() {
mView.screenGrab();
}
private boolean showMenu() {
if (popUp != null) {
if (!menu.dismissPopUps()) {

View File

@ -0,0 +1,588 @@
package com.reicast.emulator;
import java.util.Arrays;
import java.util.HashMap;
import tv.ouya.console.api.OuyaController;
import android.annotation.TargetApi;
import android.app.NativeActivity;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.res.Configuration;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.util.Log;
import android.view.Gravity;
import android.view.InputDevice;
import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.ViewConfiguration;
import android.view.ViewGroup.LayoutParams;
import android.view.Window;
import android.widget.LinearLayout;
import android.widget.PopupWindow;
import android.widget.Toast;
import com.reicast.emulator.config.Config;
import com.reicast.emulator.emu.GL2JNIView;
import com.reicast.emulator.emu.JNIdc;
import com.reicast.emulator.emu.OnScreenMenu;
import com.reicast.emulator.emu.OnScreenMenu.FpsPopup;
import com.reicast.emulator.emu.OnScreenMenu.MainPopup;
import com.reicast.emulator.emu.OnScreenMenu.VmuPopup;
import com.reicast.emulator.periph.Gamepad;
import com.reicast.emulator.periph.MOGAInput;
import com.reicast.emulator.periph.SipEmulator;
@TargetApi(Build.VERSION_CODES.HONEYCOMB_MR1)
public class GL2JNINative extends NativeActivity {
public GL2JNIView mView;
OnScreenMenu menu;
public MainPopup popUp;
VmuPopup vmuPop;
FpsPopup fpsPop;
MOGAInput moga = new MOGAInput();
private SharedPreferences prefs;
private Config config;
private Gamepad pad = new Gamepad();
public static byte[] syms;
static {
System.loadLibrary("sexplay");
}
public native void registerNative();
public native void registerXperia(int xperia);
@TargetApi(Build.VERSION_CODES.JELLY_BEAN)
@Override
protected void onCreate(Bundle icicle) {
requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().takeSurface(null);
registerNative();
prefs = PreferenceManager.getDefaultSharedPreferences(this);
config = new Config(GL2JNINative.this);
config.getConfigurationPrefs();
menu = new OnScreenMenu(GL2JNINative.this, prefs);
pad.isXperiaPlay = pad.IsXperiaPlay();
pad.isOuyaOrTV = pad.IsOuyaOrTV(GL2JNINative.this);
// isNvidiaShield = Gamepad.IsNvidiaShield();
String fileName = null;
// Call parent onCreate()
super.onCreate(icicle);
OuyaController.init(this);
moga.onCreate(this, pad);
// Populate device descriptor-to-player-map from preferences
pad.deviceDescriptor_PlayerNum.put(
prefs.getString("device_descriptor_player_1", null), 0);
pad.deviceDescriptor_PlayerNum.put(
prefs.getString("device_descriptor_player_2", null), 1);
pad.deviceDescriptor_PlayerNum.put(
prefs.getString("device_descriptor_player_3", null), 2);
pad.deviceDescriptor_PlayerNum.put(
prefs.getString("device_descriptor_player_4", null), 3);
pad.deviceDescriptor_PlayerNum.remove(null);
boolean controllerTwoConnected = false;
boolean controllerThreeConnected = false;
boolean controllerFourConnected = false;
for (HashMap.Entry<String, Integer> e : pad.deviceDescriptor_PlayerNum
.entrySet()) {
String descriptor = e.getKey();
Integer playerNum = e.getValue();
switch (playerNum) {
case 1:
if (descriptor != null)
controllerTwoConnected = true;
break;
case 2:
if (descriptor != null)
controllerThreeConnected = true;
break;
case 3:
if (descriptor != null)
controllerFourConnected = true;
break;
}
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.GINGERBREAD) {
JNIdc.initControllers(new boolean[] { controllerTwoConnected,
controllerThreeConnected, controllerFourConnected });
int joys[] = InputDevice.getDeviceIds();
for (int joy : joys) {
String descriptor = null;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
descriptor = InputDevice.getDevice(joy).getDescriptor();
} else {
descriptor = InputDevice.getDevice(joy).getName();
}
Log.d("reidc", "InputDevice ID: " + joy);
Log.d("reidc",
"InputDevice Name: "
+ InputDevice.getDevice(joy).getName());
if (pad.isXperiaPlay) {
if (InputDevice.getDevice(joy).getName()
.contains("keypad-game-zeus")) {
pad.keypadZeus.add(joy);
}
if (InputDevice.getDevice(joy).getName()
.contains("synaptics_touchpad")) {
registerXperia(joy);
pad.keypadZeus.add(joy);
}
}
Log.d("reidc", "InputDevice Descriptor: " + descriptor);
pad.deviceId_deviceDescriptor.put(joy, descriptor);
}
for (int joy : joys) {
Integer playerNum = pad.deviceDescriptor_PlayerNum
.get(pad.deviceId_deviceDescriptor.get(joy));
if (playerNum != null) {
String id = pad.portId[playerNum];
pad.custom[playerNum] = prefs.getBoolean("modified_key_layout" + id, false);
pad.compat[playerNum] = prefs.getBoolean("controller_compat" + id, false);
pad.joystick[playerNum] = prefs.getBoolean("separate_joystick" + id, false);
if (InputDevice.getDevice(joy).getName()
.contains("keypad-zeus")) {
pad.playerNumX.put(joy, playerNum);
for (int keys : pad.keypadZeus) {
pad.playerNumX.put(keys, playerNum);
}
if (pad.custom[playerNum]) {
setCustomMapping(id, playerNum);
} else {
pad.map[playerNum] = pad.getXPlayController();
}
} else {
if (!pad.compat[playerNum]) {
if (pad.custom[playerNum]) {
setCustomMapping(id, playerNum);
} else if (InputDevice.getDevice(joy).getName()
.equals("Sony PLAYSTATION(R)3 Controller")) {
pad.map[playerNum] = pad.getConsoleController();
} else if (InputDevice.getDevice(joy).getName()
.equals("Microsoft X-Box 360 pad")) {
pad.map[playerNum] = pad.getConsoleController();
} else if (InputDevice.getDevice(joy).getName()
.contains("NVIDIA Corporation NVIDIA Controller")) {
pad.map[playerNum] = pad.getConsoleController();
} else if (!pad.isActiveMoga[playerNum]) { // Ouya controller
pad.map[playerNum] = pad.getOUYAController();
}
} else{
getCompatibilityMap(playerNum, id);
}
initJoyStickLayout(playerNum);
pad.playerNumX.put(joy, playerNum);
}
} else {
runCompatibilityMode(joy);
}
}
}
// When viewing a resource, pass its URI to the native code for opening
Intent intent = getIntent();
if (intent.getAction().equals(Intent.ACTION_VIEW))
fileName = Uri.decode(intent.getData().toString());
// Create the actual GLES view
mView = new GL2JNIView(getApplication(), config, fileName, false,
prefs.getInt("depth_render", 24), 0, false);
setContentView(mView);
//setup mic
boolean micPluggedIn = prefs.getBoolean("mic_plugged_in", false);
if(micPluggedIn){
SipEmulator sip = new SipEmulator();
sip.startRecording();
JNIdc.setupMic(sip);
}
popUp = menu.new MainPopup(this);
vmuPop = menu.new VmuPopup(this);
if(prefs.getBoolean("vmu_floating", false)){
//kind of a hack - if the user last had the vmu on screen
//inverse it and then "toggle"
prefs.edit().putBoolean("vmu_floating", false).commit();
//can only display a popup after onCreate
mView.post(new Runnable() {
public void run() {
toggleVmu();
}
});
}
JNIdc.setupVmu(menu.getVmu());
if (prefs.getBoolean("show_fps", false)) {
fpsPop = menu.new FpsPopup(this);
mView.setFpsDisplay(fpsPop);
mView.post(new Runnable() {
public void run() {
displayFPS();
}
});
}
}
private void setCustomMapping(String id, int playerNum) {
pad.map[playerNum] = pad.setModifiedKeys(id, playerNum, prefs);
}
private void initJoyStickLayout(int playerNum) {
pad.globalLS_X[playerNum] = pad.previousLS_X[playerNum] = 0.0f;
pad.globalLS_Y[playerNum] = pad.previousLS_Y[playerNum] = 0.0f;
}
private void runCompatibilityMode(int joy) {
for (int n = 0; n < 4; n++) {
if (pad.compat[n]) {
getCompatibilityMap(n, pad.portId[n]);
pad.playerNumX.put(joy, n);
initJoyStickLayout(n);
} else {
pad.playerNumX.put(joy, -1);
}
}
}
private void getCompatibilityMap(int playerNum, String id) {
pad.name[playerNum] = prefs.getInt("controller" + id, -1);
if (pad.name[playerNum] != -1) {
pad.map[playerNum] = pad.setModifiedKeys(id, playerNum, prefs);
}
}
public boolean simulatedTouchEvent(int playerNum, float L2, float R2) {
GL2JNIView.lt[playerNum] = (int) (L2 * 255);
GL2JNIView.rt[playerNum] = (int) (R2 * 255);
mView.pushInput();
return true;
}
public void displayPopUp(PopupWindow popUp) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
popUp.showAtLocation(mView, Gravity.BOTTOM, 0, 60);
} else {
popUp.showAtLocation(mView, Gravity.BOTTOM, 0, 0);
}
popUp.update(LayoutParams.WRAP_CONTENT,
LayoutParams.WRAP_CONTENT);
}
public void displayDebug(PopupWindow popUpDebug) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
popUpDebug.showAtLocation(mView, Gravity.BOTTOM, 0, 60);
} else {
popUpDebug.showAtLocation(mView, Gravity.BOTTOM, 0, 0);
}
popUpDebug.update(LayoutParams.WRAP_CONTENT,
LayoutParams.WRAP_CONTENT);
}
public void displayFPS() {
fpsPop.showAtLocation(mView, Gravity.TOP | Gravity.LEFT, 20, 20);
fpsPop.update(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
}
public void toggleVmu() {
boolean showFloating = !prefs.getBoolean("vmu_floating", false);
if(showFloating){
if(popUp.isShowing()){
popUp.dismiss();
}
//remove from popup menu
LinearLayout parent = (LinearLayout) popUp.getContentView();
parent.removeView(menu.getVmu());
//add to floating window
vmuPop.showVmu();
vmuPop.showAtLocation(mView, Gravity.TOP | Gravity.RIGHT, 4, 4);
vmuPop.update(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
}else{
vmuPop.dismiss();
//remove from floating window
LinearLayout parent = (LinearLayout) vmuPop.getContentView();
parent.removeView(menu.getVmu());
//add back to popup menu
popUp.showVmu();
}
prefs.edit().putBoolean("vmu_floating", showFloating).commit();
}
public void displayConfig(PopupWindow popUpConfig) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
popUpConfig.showAtLocation(mView, Gravity.BOTTOM, 0, 60);
} else {
popUpConfig.showAtLocation(mView, Gravity.BOTTOM, 0, 0);
}
popUpConfig.update(LayoutParams.WRAP_CONTENT,
LayoutParams.WRAP_CONTENT);
}
@Override
public boolean onGenericMotionEvent(MotionEvent event) {
// Log.w("INPUT", event.toString() + " " + event.getSource());
// Get all the axis for the KeyEvent
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.GINGERBREAD
&& event.getSource() != Gamepad.Xperia_Touchpad) {
Integer playerNum = Arrays.asList(pad.name).indexOf(event.getDeviceId());
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.GINGERBREAD && playerNum == -1) {
playerNum = pad.deviceDescriptor_PlayerNum
.get(pad.deviceId_deviceDescriptor.get(event.getDeviceId()));
} else {
playerNum = -1;
}
if (playerNum == null || playerNum == -1) {
return false;
}
if (!pad.compat[playerNum]) {
// Joystick
if ((event.getSource() & InputDevice.SOURCE_CLASS_JOYSTICK) != 0) {
// do other things with joystick
float LS_X = event.getAxisValue(OuyaController.AXIS_LS_X);
float LS_Y = event.getAxisValue(OuyaController.AXIS_LS_Y);
float RS_X = event.getAxisValue(OuyaController.AXIS_RS_X);
float RS_Y = event.getAxisValue(OuyaController.AXIS_RS_Y);
float L2 = event.getAxisValue(OuyaController.AXIS_L2);
float R2 = event.getAxisValue(OuyaController.AXIS_R2);
if (!pad.joystick[playerNum]) {
pad.previousLS_X[playerNum] = pad.globalLS_X[playerNum];
pad.previousLS_Y[playerNum] = pad.globalLS_Y[playerNum];
pad.globalLS_X[playerNum] = LS_X;
pad.globalLS_Y[playerNum] = LS_Y;
}
GL2JNIView.jx[playerNum] = (int) (LS_X * 126);
GL2JNIView.jy[playerNum] = (int) (LS_Y * 126);
if (prefs.getBoolean("right_buttons", true)) {
if (RS_Y > 0.5) {
handle_key(playerNum, pad.map[playerNum][0]/* A */, true);
pad.wasKeyStick[playerNum] = true;
} else if (RS_Y < 0.5) {
handle_key(playerNum, pad.map[playerNum][1]/* B */, true);
pad.wasKeyStick[playerNum] = true;
} else if (pad.wasKeyStick[playerNum]){
handle_key(playerNum, pad.map[playerNum][0], false);
handle_key(playerNum, pad.map[playerNum][1], false);
pad.wasKeyStick[playerNum] = false;
}
} else {
if (RS_Y > 0.5) {
GL2JNIView.rt[playerNum] = (int) (RS_Y * 255);
GL2JNIView.lt[playerNum] = (int) (L2 * 255);
} else if (RS_Y < 0.5) {
GL2JNIView.rt[playerNum] = (int) (R2 * 255);
GL2JNIView.lt[playerNum] = (int) (-(RS_Y) * 255);
} else {
GL2JNIView.lt[playerNum] = (int) (L2 * 255);
GL2JNIView.rt[playerNum] = (int) (R2 * 255);
}
}
}
}
mView.pushInput();
if (!pad.joystick[playerNum] && (pad.globalLS_X[playerNum] == pad.previousLS_X[playerNum] && pad.globalLS_Y[playerNum] == pad.previousLS_Y[playerNum])
|| (pad.previousLS_X[playerNum] == 0.0f && pad.previousLS_Y[playerNum] == 0.0f))
// Only handle Left Stick on an Xbox 360 controller if there was
// some actual motion on the stick,
// so otherwise the event can be handled as a DPAD event
return false;
else
return true;
}
return false;
}
boolean handle_key(Integer playerNum, int kc, boolean down) {
if (playerNum == null || playerNum == -1)
return false;
if (kc == pad.getSelectButtonCode()) {
return false;
}
if (pad.isActiveMoga[playerNum]) {
return false;
}
boolean rav = false;
for (int i = 0; i < pad.map[playerNum].length; i += 2) {
if (pad.map[playerNum][i + 0] == kc) {
if (down)
GL2JNIView.kcode_raw[playerNum] &= ~pad.map[playerNum][i + 1];
else
GL2JNIView.kcode_raw[playerNum] |= pad.map[playerNum][i + 1];
rav = true;
break;
}
}
mView.pushInput();
return rav;
}
public boolean onKeyUp(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_VOLUME_UP || keyCode == KeyEvent.KEYCODE_VOLUME_DOWN) {
return super.onKeyUp(keyCode, event);
}
return true;
}
public boolean onKeyDown(int keyCode, KeyEvent event) {
if (keyCode == pad.getSelectButtonCode()) {
return showMenu();
}
if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.GINGERBREAD_MR1
|| (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH
&& ViewConfiguration.get(this).hasPermanentMenuKey())) {
if (keyCode == KeyEvent.KEYCODE_MENU) {
return showMenu();
}
}
if (keyCode == KeyEvent.KEYCODE_BACK) {
if (pad.isXperiaPlay) {
return true;
} else {
return showMenu();
}
}
if (keyCode == KeyEvent.KEYCODE_VOLUME_UP || keyCode == KeyEvent.KEYCODE_VOLUME_DOWN) {
return super.onKeyDown(keyCode, event);
}
return true;
}
public boolean OnNativeKeyPress(int device, int keyCode, int action, int metaState) {
Integer playerNum = pad.playerNumX.get(device);
if (playerNum != null && playerNum != -1) {
String id = pad.portId[playerNum];
if (action == KeyEvent.ACTION_DOWN) {
if (keyCode == prefs.getInt("l_button" + id, KeyEvent.KEYCODE_BUTTON_L1)) {
return simulatedTouchEvent(playerNum, 1.0f, 0.0f);
} else if (keyCode == prefs.getInt("r_button" + id, KeyEvent.KEYCODE_BUTTON_R1)) {
return simulatedTouchEvent(playerNum, 0.0f, 1.0f);
} else if (handle_key(playerNum, keyCode, true)) {
if (playerNum == 0)
JNIdc.hide_osd();
return true;
}
}
if (action == KeyEvent.ACTION_UP) {
if (keyCode == prefs.getInt("l_button" + id,
KeyEvent.KEYCODE_BUTTON_L1)
|| keyCode == prefs.getInt("r_button" + id,
KeyEvent.KEYCODE_BUTTON_R1)) {
return simulatedTouchEvent(playerNum, 0.0f, 0.0f);
} else {
return handle_key(playerNum, keyCode, false);
}
}
}
return false;
}
public boolean OnNativeMotion(int device, int source, int action, int x, int y, boolean newEvent) {
if (newEvent && source == Gamepad.Xperia_Touchpad) {
// Source is Xperia Play touchpad
Integer playerNum = pad.playerNumX.get(device);
if (playerNum != null && playerNum != -1) {
Log.d("reidc", playerNum + " - " + device + ": " + source);
if (action == MotionEvent.ACTION_UP) {
x = 0;
y = 0;
}
// Sensitive! Zero out the touchpad release
if (x > 360 && x < 500) {
x = 360;
} else if (x > 500 && x < 640) {
x = 640;
}
if (x >= 640) {
x = x - 640;
}
y = 366 - y;
// Right stick is an extension of left stick
// 360 to 640 is the live gap between sticks
// The y-axis is inverted from normal layout
// Imagine it as a small MacBook touch mouse
GL2JNIView.jx[playerNum] = (int) (x * 126);
GL2JNIView.jy[playerNum] = (int) (y * 126);
mView.pushInput();
return true;
}
}
return false;
}
public GL2JNIView getGameView() {
return mView;
}
public void screenGrab() {
mView.screenGrab();
}
private boolean showMenu() {
if (popUp != null) {
if (!menu.dismissPopUps()) {
if (!popUp.isShowing()) {
displayPopUp(popUp);
} else {
popUp.dismiss();
}
}
}
return true;
}
@Override
protected void onPause() {
super.onPause();
mView.onPause();
moga.onPause();
}
@Override
protected void onDestroy() {
super.onDestroy();
moga.onDestroy();
}
@Override
protected void onStop() {
JNIdc.stop();
mView.onStop();
super.onStop();
}
@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
}
@Override
protected void onResume() {
super.onResume();
mView.onResume();
moga.onResume();
}
}

View File

@ -31,6 +31,7 @@ import android.widget.TextView;
import com.jeremyfeinstein.slidingmenu.lib.SlidingMenu;
import com.jeremyfeinstein.slidingmenu.lib.SlidingMenu.OnOpenListener;
import com.jeremyfeinstein.slidingmenu.lib.app.SlidingFragmentActivity;
import com.reicast.emulator.config.Config;
import com.reicast.emulator.config.ConfigureFragment;
import com.reicast.emulator.config.InputFragment;
import com.reicast.emulator.config.OptionsFragment;
@ -52,6 +53,8 @@ public class MainActivity extends SlidingFragmentActivity implements
private UncaughtExceptionHandler mUEHandler;
public static boolean debugUser;
Gamepad pad = new Gamepad();
@Override
@ -62,17 +65,28 @@ public class MainActivity extends SlidingFragmentActivity implements
mPrefs = PreferenceManager.getDefaultSharedPreferences(this);
Intent debugger = new Intent("com.reicast.emulator.debug.Debugger");
debugger.setAction("com.reicast.emulator.DEBUG");
if (isCallable(debugger)) {
MainActivity.debugUser = true;
}
String prior_error = mPrefs.getString("prior_error", null);
if (prior_error != null && !prior_error.equals(null)) {
initiateReport(prior_error);
mPrefs.edit().remove("prior_error").commit();
} else {
mUEHandler = new Thread.UncaughtExceptionHandler() {
public void uncaughtException(Thread t, Throwable error) {
if (error != null) {
StringBuilder output = new StringBuilder();
output.append("Thread:\n");
for (StackTraceElement trace : t.getStackTrace()) {
output.append(trace.toString() + " ");
output.append(trace.toString() + "\n");
}
output.append("\n\nError:\n");
output.append("\nError:\n");
for (StackTraceElement trace : error.getStackTrace()) {
output.append(trace.toString() + " ");
output.append(trace.toString() + "\n");
}
String log = output.toString();
mPrefs.edit().putString("prior_error", log).commit();
@ -82,19 +96,12 @@ public class MainActivity extends SlidingFragmentActivity implements
}
};
Thread.setDefaultUncaughtExceptionHandler(mUEHandler);
}
home_directory = mPrefs.getString("home_directory", home_directory);
String prior_error = mPrefs.getString("prior_error", null);
if (prior_error != null && !prior_error.equals(null)) {
initiateReport(prior_error);
mPrefs.edit().remove("prior_error").commit();
}
Intent market = new Intent(Intent.ACTION_VIEW, Uri.parse("market://search?q=dummy"));
PackageManager manager = getPackageManager();
List<ResolveInfo> list = manager.queryIntentActivities(market, 0);
if (list != null && !list.isEmpty()) {
if (isCallable(market)) {
hasAndroidMarket = true;
}
@ -292,21 +299,20 @@ public class MainActivity extends SlidingFragmentActivity implements
/**
* Display a dialog to notify the user of prior crash
*
* @param string
* @param error
* A generalized summary of the crash cause
* @param bundle
* The savedInstanceState passed from onCreate
*/
private void initiateReport(final String error) {
AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this);
builder.setTitle(getString(R.string.report_issue));
builder.setMessage(error);
builder.setNegativeButton("Cancel",
builder.setNegativeButton("Dismiss",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
}
});
if (MainActivity.debugUser) {
builder.setPositiveButton("Report",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
@ -314,6 +320,7 @@ public class MainActivity extends SlidingFragmentActivity implements
dialog.dismiss();
}
});
}
builder.create();
builder.show();
}
@ -407,9 +414,13 @@ public class MainActivity extends SlidingFragmentActivity implements
// show it
alertDialog.show();
} else {
Intent inte = new Intent(Intent.ACTION_VIEW, uri, getBaseContext(),
GL2JNIActivity.class);
startActivity(inte);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.GINGERBREAD && !Config.nonative) {
startActivity(new Intent(Intent.ACTION_VIEW, uri, getBaseContext(),
GL2JNINative.class));
} else {
startActivity(new Intent(Intent.ACTION_VIEW, uri, getBaseContext(),
GL2JNIActivity.class));
}
}
}
@ -553,4 +564,10 @@ public class MainActivity extends SlidingFragmentActivity implements
}
}
}
public boolean isCallable(Intent intent) {
List<ResolveInfo> list = getPackageManager().queryIntentActivities(
intent, PackageManager.MATCH_DEFAULT_ONLY);
return list.size() > 0;
}
}

View File

@ -17,12 +17,14 @@ public class Config {
public static int broadcast = 4;
public static boolean limitfps = true;
public static boolean nobatch = false;
public static boolean nosound = false;
public static boolean mipmaps = true;
public static boolean widescreen = false;
public static boolean subdivide = false;
public static int frameskip = 0;
public static boolean pvrrender = false;
public static String cheatdisk = "null";
public static boolean nonative = false;
private SharedPreferences mPrefs;
@ -41,11 +43,13 @@ public class Config {
Config.dcregion = mPrefs.getInt("dc_region", dcregion);
Config.broadcast = mPrefs.getInt("dc_broadcast", broadcast);
Config.limitfps = mPrefs.getBoolean("limit_fps", limitfps);
Config.nosound = mPrefs.getBoolean("sound_disabled", nosound);
Config.mipmaps = mPrefs.getBoolean("use_mipmaps", mipmaps);
Config.widescreen = mPrefs.getBoolean("stretch_view", widescreen);
Config.frameskip = mPrefs.getInt("frame_skip", frameskip);
Config.pvrrender = mPrefs.getBoolean("pvr_render", pvrrender);
Config.cheatdisk = mPrefs.getString("cheat_disk", cheatdisk);
Config.nonative = mPrefs.getBoolean("native_override", nonative);
}
/**
@ -61,6 +65,7 @@ public class Config {
JNIdc.broadcast(Config.broadcast);
JNIdc.limitfps(Config.limitfps ? 1 : 0);
JNIdc.nobatch(Config.nobatch ? 1 : 0);
JNIdc.nosound(Config.nosound ? 1 : 0);
JNIdc.mipmaps(Config.mipmaps ? 1 : 0);
JNIdc.widescreen(Config.widescreen ? 1 : 0);
JNIdc.subdivide(Config.subdivide ? 1 : 0);

View File

@ -20,6 +20,7 @@ import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemSelectedListener;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.CompoundButton;
import android.widget.CompoundButton.OnCheckedChangeListener;
import android.widget.EditText;
@ -28,6 +29,7 @@ import android.widget.SeekBar.OnSeekBarChangeListener;
import android.widget.Spinner;
import android.widget.TextView;
import com.reicast.emulator.MainActivity;
import com.reicast.emulator.R;
import com.reicast.emulator.debug.GenerateLogs;
import com.reicast.emulator.emu.GL2JNIView;
@ -76,6 +78,19 @@ public class ConfigureFragment extends Fragment {
// Generate the menu options and fill in existing settings
OnCheckedChangeListener native_options = new OnCheckedChangeListener() {
public void onCheckedChanged(CompoundButton buttonView,
boolean isChecked) {
mPrefs.edit().putBoolean("native_override", isChecked).commit();
Config.nonative = isChecked;
}
};
Switch native_opt = (Switch) getView().findViewById(
R.id.native_option);
native_opt.setChecked(Config.nonative);
native_opt.setOnCheckedChangeListener(native_options);
OnCheckedChangeListener dynarec_options = new OnCheckedChangeListener() {
public void onCheckedChanged(CompoundButton buttonView,
@ -133,6 +148,43 @@ public class ConfigureFragment extends Fragment {
});
String[] broadcasts = parentActivity.getResources().getStringArray(
R.array.broadcast);
Spinner broadcast_spnr = (Spinner) getView().findViewById(
R.id.broadcast_spinner);
ArrayAdapter<String> broadcastAdapter = new ArrayAdapter<String>(
parentActivity, R.layout.spinner_selected, broadcasts);
broadcastAdapter
.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
broadcast_spnr.setAdapter(broadcastAdapter);
int select = 0;
String cast = String.valueOf(Config.broadcast);
for (int i = 0; i < broadcasts.length; i++) {
if (broadcasts[i].startsWith(cast + " - "))
select = i;
}
broadcast_spnr.setSelection(select, true);
broadcast_spnr.setOnItemSelectedListener(new OnItemSelectedListener() {
public void onItemSelected(AdapterView<?> parent, View view,
int pos, long id) {
String item = parent.getItemAtPosition(pos).toString();
String selection = item.substring(0, item.indexOf(" - "));
mPrefs.edit()
.putInt("dc_broadcast", Integer.valueOf(selection))
.commit();
Config.broadcast = Integer.valueOf(selection);
}
public void onNothingSelected(AdapterView<?> arg0) {
}
});
OnCheckedChangeListener limitfps_option = new OnCheckedChangeListener() {
public void onCheckedChanged(CompoundButton buttonView,
@ -299,10 +351,11 @@ public class ConfigureFragment extends Fragment {
public void onCheckedChanged(CompoundButton buttonView,
boolean isChecked) {
mPrefs.edit().putBoolean("sound_enabled", isChecked).commit();
mPrefs.edit().putBoolean("sound_disabled", isChecked).commit();
Config.nosound = isChecked;
}
};
boolean sound = mPrefs.getBoolean("sound_enabled", true);
boolean sound = mPrefs.getBoolean("sound_disabled", false);
sound_opt.setChecked(sound);
sound_opt.setOnCheckedChangeListener(emu_sound);
@ -335,6 +388,17 @@ public class ConfigureFragment extends Fragment {
}
});
Button debug = (Button) getView().findViewById(R.id.debug_button);
if (MainActivity.debugUser) {
debug.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
generateErrorLog();
}
});
} else {
debug.setVisibility(View.GONE);
}
}
public void generateErrorLog() {

View File

@ -45,6 +45,7 @@ public class InputModFragment extends Fragment {
private Activity parentActivity;
private SharedPreferences mPrefs;
private Switch switchJoystickDpadEnabled;
private Switch switchModifiedLayoutEnabled;
private Switch switchCompatibilityEnabled;
@ -99,6 +100,18 @@ public class InputModFragment extends Fragment {
playerNum = b.getInt("portNumber", -1);
}
OnCheckedChangeListener joystick_mode = new OnCheckedChangeListener() {
public void onCheckedChanged(CompoundButton buttonView,
boolean isChecked) {
mPrefs.edit()
.putBoolean("separate_joystick" + player, isChecked)
.commit();
}
};
switchJoystickDpadEnabled = (Switch) getView().findViewById(
R.id.switchJoystickDpadEnabled);
switchJoystickDpadEnabled.setOnCheckedChangeListener(joystick_mode);
OnCheckedChangeListener modified_layout = new OnCheckedChangeListener() {
public void onCheckedChanged(CompoundButton buttonView,
boolean isChecked) {
@ -559,6 +572,8 @@ public class InputModFragment extends Fragment {
}
private void updateController(String player) {
switchJoystickDpadEnabled.setChecked(mPrefs.getBoolean(
"separate_joystick" + player, false));
switchModifiedLayoutEnabled.setChecked(mPrefs.getBoolean(
"modified_key_layout" + player, false));
switchCompatibilityEnabled.setChecked(mPrefs.getBoolean(

View File

@ -3,11 +3,11 @@ package com.reicast.emulator.emu;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;
import android.annotation.TargetApi;
import android.app.Activity;
import android.content.Context;
import android.content.SharedPreferences;
import android.content.res.Configuration;
@ -21,13 +21,17 @@ import android.os.Build;
import android.os.Vibrator;
import android.preference.PreferenceManager;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.MotionEvent;
import android.view.ScaleGestureDetector;
import android.view.ScaleGestureDetector.SimpleOnScaleGestureListener;
import android.view.View;
import android.view.WindowManager;
import com.android.util.FileUtils;
import com.reicast.emulator.GL2JNIActivity;
import com.reicast.emulator.GL2JNINative;
import com.reicast.emulator.config.Config;
import com.reicast.emulator.emu.OnScreenMenu.FpsPopup;
import com.reicast.emulator.periph.VJoy;
@ -60,6 +64,9 @@ public class GL2JNIView extends GLSurfaceView
//private AudioThread audioThread;
private EmuThread ethd;
private static int sWidth;
private static int sHeight;
Vibrator vib;
private boolean editVjoyMode = false;
@ -103,17 +110,6 @@ public class GL2JNIView extends GLSurfaceView
this.editVjoyMode = editVjoyMode;
setKeepScreenOn(true);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
setOnSystemUiVisibilityChangeListener (new OnSystemUiVisibilityChangeListener() {
public void onSystemUiVisibilityChange(int visibility) {
if ((visibility & SYSTEM_UI_FLAG_FULLSCREEN) == 0) {
GL2JNIView.this.setSystemUiVisibility(
SYSTEM_UI_FLAG_FULLSCREEN
| SYSTEM_UI_FLAG_HIDE_NAVIGATION);
}
}
});
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
setOnSystemUiVisibilityChangeListener (new OnSystemUiVisibilityChangeListener() {
public void onSystemUiVisibilityChange(int visibility) {
@ -138,9 +134,17 @@ public class GL2JNIView extends GLSurfaceView
System.gc();
}
DisplayMetrics metrics = new DisplayMetrics();
//((Activity) context).getWindowManager().getDefaultDisplay().getMetrics(metrics);
((WindowManager) context.getSystemService(Context.WINDOW_SERVICE))
.getDefaultDisplay().getMetrics(metrics);
final float scale = context.getResources().getDisplayMetrics().density;
sWidth = (int) (metrics.widthPixels * scale + 0.5f);
sHeight = (int) (metrics.heightPixels * scale + 0.5f);
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
boolean soundEndabled = prefs.getBoolean("sound_enabled", true);
ethd = new EmuThread(soundEndabled);
ethd = new EmuThread(!Config.nosound);
touchVibrationEnabled = prefs.getBoolean("touch_vibration_enabled", true);
@ -169,8 +173,13 @@ public class GL2JNIView extends GLSurfaceView
// This is the game we are going to run
fileName = newFileName;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.GINGERBREAD) {
if (GL2JNINative.syms != null)
JNIdc.data(1, GL2JNINative.syms);
} else {
if (GL2JNIActivity.syms != null)
JNIdc.data(1, GL2JNIActivity.syms);
}
JNIdc.init(fileName);
@ -542,11 +551,15 @@ public class GL2JNIView extends GLSurfaceView
fps.logFrame();
}
JNIdc.rendframe();
if(mView.takeScreenshot){
mView.takeScreenshot = false;
FileUtils.saveScreenshot(mView.getContext(), mView.getWidth(), mView.getHeight(), gl);
}
}
public void onSurfaceChanged(GL10 gl,int width,int height)
{
JNIdc.rendinit(width,height);
JNIdc.rendinit(sWidth,sHeight);
}
public void onSurfaceCreated(GL10 gl,EGLConfig config)
@ -670,13 +683,6 @@ public class GL2JNIView extends GLSurfaceView
@Override
public void onWindowFocusChanged(boolean hasFocus) {
super.onWindowFocusChanged(hasFocus);
if (hasFocus && Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
GL2JNIView.this.setSystemUiVisibility(
View.SYSTEM_UI_FLAG_LAYOUT_STABLE
| View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
| View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
| View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
| View.SYSTEM_UI_FLAG_FULLSCREEN);}
if (hasFocus && Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
GL2JNIView.this.setSystemUiVisibility(
View.SYSTEM_UI_FLAG_LAYOUT_STABLE
@ -686,4 +692,10 @@ public class GL2JNIView extends GLSurfaceView
| View.SYSTEM_UI_FLAG_FULLSCREEN
| View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY);}
}
private boolean takeScreenshot = false;
public void screenGrab() {
takeScreenshot = true;
}
}

View File

@ -34,6 +34,7 @@ public class JNIdc
public static native void broadcast(int broadcast);
public static native void limitfps(int limiter);
public static native void nobatch(int nobatch);
public static native void nosound(int noaudio);
public static native void mipmaps(int mipmaps);
public static native void widescreen(int stretch);
public static native void subdivide(int subdivide);

View File

@ -1,6 +1,7 @@
package com.reicast.emulator.emu;
import java.io.File;
import java.util.ArrayList;
import java.util.Vector;
import android.app.Activity;
@ -19,6 +20,7 @@ import android.widget.PopupWindow;
import android.widget.TextView;
import com.reicast.emulator.GL2JNIActivity;
import com.reicast.emulator.GL2JNINative;
import com.reicast.emulator.MainActivity;
import com.reicast.emulator.R;
import com.reicast.emulator.config.Config;
@ -46,6 +48,9 @@ public class OnScreenMenu {
private boolean boosted = false;
public OnScreenMenu(Activity context, SharedPreferences prefs) {
if (context instanceof GL2JNINative) {
this.mContext = (GL2JNINative) context;
}
if (context instanceof GL2JNIActivity) {
this.mContext = (GL2JNIActivity) context;
}
@ -53,12 +58,15 @@ public class OnScreenMenu {
if (prefs != null) {
this.prefs = prefs;
home_directory = prefs.getString("home_directory", home_directory);
masteraudio = prefs.getBoolean("sound_enabled", true);
masteraudio = !Config.nosound;
audio = masteraudio;
}
vmuLcd = new VmuLcd(mContext);
vmuLcd.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
if (mContext instanceof GL2JNINative) {
((GL2JNINative) OnScreenMenu.this.mContext).toggleVmu();
}
if (mContext instanceof GL2JNIActivity) {
((GL2JNIActivity) OnScreenMenu.this.mContext).toggleVmu();
}
@ -67,9 +75,13 @@ public class OnScreenMenu {
}
void displayDebugPopup(final PopupWindow popUp) {
if (mContext instanceof GL2JNINative) {
((GL2JNINative) mContext).displayDebug(new DebugPopup(mContext));
}
if (mContext instanceof GL2JNIActivity) {
((GL2JNIActivity) mContext).displayDebug(new DebugPopup(mContext));
}
}
public class FpsPopup extends PopupWindow {
@ -95,6 +107,10 @@ public class OnScreenMenu {
private void removePopUp(PopupWindow window) {
window.dismiss();
popups.remove(window);
if (mContext instanceof GL2JNINative) {
((GL2JNINative) mContext)
.displayPopUp(((GL2JNINative) OnScreenMenu.this.mContext).popUp);
}
if (mContext instanceof GL2JNIActivity) {
((GL2JNIActivity) mContext)
.displayPopUp(((GL2JNIActivity) OnScreenMenu.this.mContext).popUp);
@ -160,6 +176,9 @@ public class OnScreenMenu {
}
void displayConfigPopup(final PopupWindow popUp) {
if (mContext instanceof GL2JNINative) {
((GL2JNINative) mContext).displayConfig(new ConfigPopup(mContext));
}
if (mContext instanceof GL2JNIActivity) {
((GL2JNIActivity) mContext)
.displayConfig(new ConfigPopup(mContext));
@ -174,6 +193,7 @@ public class OnScreenMenu {
private View fastforward;
private View fdown;
private View fup;
ArrayList<View> menuItems = new ArrayList<View>();
public ConfigPopup(Context c) {
super(c);
@ -185,11 +205,13 @@ public class OnScreenMenu {
hlay.setOrientation(LinearLayout.HORIZONTAL);
hlay.addView(addbut(R.drawable.up, new OnClickListener() {
View up = addbut(R.drawable.up, new OnClickListener() {
public void onClick(View v) {
removePopUp(ConfigPopup.this);
}
}), configParams);
});
hlay.addView(up, configParams);
menuItems.add(up);
fullscreen = addbut(R.drawable.widescreen, new OnClickListener() {
public void onClick(View v) {
@ -212,6 +234,7 @@ public class OnScreenMenu {
}
hlay.addView(fullscreen, params);
menuItems.add(fullscreen);
fdown = addbut(R.drawable.frames_down, new OnClickListener() {
public void onClick(View v) {
@ -233,7 +256,9 @@ public class OnScreenMenu {
});
hlay.addView(fdown, params);
menuItems.add(fdown);
hlay.addView(fup, params);
menuItems.add(fup);
enableState(fdown, fup);
framelimit = addbut(R.drawable.frames_limit_on,
@ -257,26 +282,35 @@ public class OnScreenMenu {
.setImageResource(R.drawable.frames_limit_off);
}
hlay.addView(framelimit, params);
menuItems.add(framelimit);
audiosetting = addbut(R.drawable.enable_sound,
new OnClickListener() {
public void onClick(View v) {
if (audio) {
if (mContext instanceof GL2JNINative) {
((GL2JNINative) mContext).mView
.audioDisable(true);
}
if (mContext instanceof GL2JNIActivity) {
((GL2JNIActivity) mContext).mView
.audioDisable(true);
}
audio = false;
((ImageButton) audiosetting)
.setImageResource(R.drawable.enable_sound);
audio = false;
} else {
if (mContext instanceof GL2JNINative) {
((GL2JNINative) mContext).mView
.audioDisable(false);
}
if (mContext instanceof GL2JNIActivity) {
((GL2JNIActivity) mContext).mView
.audioDisable(false);
}
audio = true;
((ImageButton) audiosetting)
.setImageResource(R.drawable.mute_sound);
audio = true;
}
}
});
@ -288,19 +322,28 @@ public class OnScreenMenu {
audiosetting.setEnabled(false);
}
hlay.addView(audiosetting, params);
menuItems.add(audiosetting);
fastforward = addbut(R.drawable.star, new OnClickListener() {
public void onClick(View v) {
if (boosted) {
if (mContext instanceof GL2JNINative) {
((GL2JNINative) mContext).mView
.audioDisable(!audio);
}
if (mContext instanceof GL2JNIActivity) {
((GL2JNIActivity) mContext).mView
.audioDisable(!audio);
}
JNIdc.nosound(!audio ? 1 : 0);
audiosetting.setEnabled(true);
JNIdc.limitfps(limit ? 1 : 0);
framelimit.setEnabled(true);
JNIdc.frameskip(frames);
enableState(fdown, fup);
if (mContext instanceof GL2JNINative) {
((GL2JNINative) mContext).mView.fastForward(false);
}
if (mContext instanceof GL2JNIActivity) {
((GL2JNIActivity) mContext).mView.fastForward(false);
}
@ -308,16 +351,24 @@ public class OnScreenMenu {
((ImageButton) fastforward)
.setImageResource(R.drawable.star);
} else {
if (mContext instanceof GL2JNINative) {
((GL2JNINative) mContext).mView
.audioDisable(true);
}
if (mContext instanceof GL2JNIActivity) {
((GL2JNIActivity) mContext).mView
.audioDisable(true);
}
JNIdc.nosound(1);
audiosetting.setEnabled(false);
JNIdc.limitfps(0);
framelimit.setEnabled(false);
JNIdc.frameskip(5);
fdown.setEnabled(false);
fup.setEnabled(false);
if (mContext instanceof GL2JNINative) {
((GL2JNINative) mContext).mView.fastForward(true);
}
if (mContext instanceof GL2JNIActivity) {
((GL2JNIActivity) mContext).mView.fastForward(true);
}
@ -332,17 +383,31 @@ public class OnScreenMenu {
.setImageResource(R.drawable.reset);
}
hlay.addView(fastforward, params);
menuItems.add(fastforward);
hlay.addView(addbut(R.drawable.close, new OnClickListener() {
View close = addbut(R.drawable.close, new OnClickListener() {
public void onClick(View v) {
popups.remove(ConfigPopup.this);
dismiss();
}
}), configParams);
});
hlay.addView(close, configParams);
menuItems.add(close);
setContentView(hlay);
getFocusedItem();
popups.add(this);
}
public void getFocusedItem() {
for (View menuItem : menuItems) {
if (menuItem.hasFocus()) {
// do something to the focused item
} else {
// do something to the rest of them
}
}
}
}
/**
@ -491,6 +556,18 @@ public class OnScreenMenu {
}
}), params);
hlay.addView(addbut(R.drawable.print_stats, new OnClickListener() {
public void onClick(View v) {
//screenshot
if (mContext instanceof GL2JNINative) {
((GL2JNINative) OnScreenMenu.this.mContext).screenGrab();
}
if (mContext instanceof GL2JNIActivity) {
((GL2JNIActivity) OnScreenMenu.this.mContext).screenGrab();
}
}
}), params);
hlay.addView(addbut(R.drawable.close, new OnClickListener() {
public void onClick(View v) {
Intent inte = new Intent(mContext, MainActivity.class);

View File

@ -6,7 +6,6 @@ import java.util.List;
import tv.ouya.console.api.OuyaController;
import tv.ouya.console.api.OuyaFacade;
import android.annotation.TargetApi;
import android.content.Context;
import android.content.SharedPreferences;
import android.content.pm.PackageManager;
@ -19,6 +18,7 @@ public class Gamepad {
public String[] portId = { "_A", "_B", "_C", "_D" };
public boolean[] compat = { false, false, false, false };
public boolean[] custom = { false, false, false, false };
public boolean[] joystick = { false, false, false, false };
public int[] name = { -1, -1, -1, -1 };
public float[] globalLS_X = new float[4], globalLS_Y = new float[4],
previousLS_X = new float[4], previousLS_Y = new float[4];
@ -103,7 +103,6 @@ public class Gamepad {
};
}
@TargetApi(Build.VERSION_CODES.GINGERBREAD)
public int[] getMogaController() {
return new int[] {
KeyEvent.KEYCODE_BUTTON_A, key_CONT_A,

View File

@ -3,12 +3,8 @@ package com.reicast.emulator.periph;
/******************************************************************************/
import java.util.Arrays;
import tv.ouya.console.api.OuyaController;
import android.app.Activity;
import android.content.SharedPreferences;
import android.os.Build;
import android.os.Handler;
import android.preference.PreferenceManager;
import android.widget.Toast;
@ -18,9 +14,7 @@ import com.bda.controller.ControllerListener;
import com.bda.controller.KeyEvent;
import com.bda.controller.MotionEvent;
import com.bda.controller.StateEvent;
import com.reicast.emulator.GL2JNIActivity;
import com.reicast.emulator.R;
import com.reicast.emulator.emu.GL2JNIView;
import com.reicast.emulator.emu.JNIdc;
/******************************************************************************/
@ -135,100 +129,12 @@ public class MOGAInput
{
public void onKeyEvent(KeyEvent event)
{
Integer playerNum = Arrays.asList(pad.name).indexOf(event.getControllerId());
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.GINGERBREAD && playerNum == -1) {
playerNum = pad.deviceDescriptor_PlayerNum
.get(pad.deviceId_deviceDescriptor.get(event.getControllerId()));
} else {
playerNum = -1;
}
if (playerNum == null || playerNum == -1)
return;
if (playerNum != null && playerNum != -1) {
String id = pad.portId[playerNum];
if (event.getAction() == KeyEvent.ACTION_DOWN) {
if (event.getKeyCode() == prefs.getInt("l_button" + id, KeyEvent.KEYCODE_BUTTON_L1)) {
simulatedTouchEvent(playerNum, 1.0f, 0.0f);
} else if (event.getKeyCode() == prefs.getInt("r_button" + id, KeyEvent.KEYCODE_BUTTON_R1)) {
simulatedTouchEvent(playerNum, 0.0f, 1.0f);
} else if (((GL2JNIActivity) act).handle_key(playerNum, event.getKeyCode(), true)) {
if (playerNum == 0)
JNIdc.hide_osd();
}
}
if (event.getAction() == KeyEvent.ACTION_UP) {
if (event.getKeyCode() == prefs.getInt("l_button" + id,
KeyEvent.KEYCODE_BUTTON_L1)
|| event.getKeyCode() == prefs.getInt("r_button" + id,
KeyEvent.KEYCODE_BUTTON_R1)) {
simulatedTouchEvent(playerNum, 0.0f, 0.0f);
} else {
((GL2JNIActivity) act).handle_key(playerNum, event.getKeyCode(), false);
}
}
}
// Handled by the primary controller interface
}
public void onMotionEvent(MotionEvent event)
{
Integer playerNum = Arrays.asList(pad.name).indexOf(event.getControllerId());
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.GINGERBREAD && playerNum == -1) {
playerNum = pad.deviceDescriptor_PlayerNum
.get(pad.deviceId_deviceDescriptor.get(event.getControllerId()));
} else {
playerNum = -1;
}
if (playerNum == null || playerNum == -1)
return;
if (!pad.compat[playerNum]) {
// Joystick
// do other things with joystick
float LS_X = event.getAxisValue(OuyaController.AXIS_LS_X);
float LS_Y = event.getAxisValue(OuyaController.AXIS_LS_Y);
float RS_X = event.getAxisValue(OuyaController.AXIS_RS_X);
float RS_Y = event.getAxisValue(OuyaController.AXIS_RS_Y);
float L2 = event.getAxisValue(OuyaController.AXIS_L2);
float R2 = event.getAxisValue(OuyaController.AXIS_R2);
pad.previousLS_X[playerNum] = pad.globalLS_X[playerNum];
pad.previousLS_Y[playerNum] = pad.globalLS_Y[playerNum];
pad.globalLS_X[playerNum] = LS_X;
pad.globalLS_Y[playerNum] = LS_Y;
GL2JNIView.lt[playerNum] = (int) (L2 * 255);
GL2JNIView.rt[playerNum] = (int) (R2 * 255);
GL2JNIView.jx[playerNum] = (int) (LS_X * 126);
GL2JNIView.jy[playerNum] = (int) (LS_Y * 126);
if (prefs.getBoolean("right_buttons", true)) {
if (RS_Y > 0.5) {
((GL2JNIActivity) act).handle_key(playerNum, pad.map[playerNum][0]/* A */, true);
pad.wasKeyStick[playerNum] = true;
} else if (RS_Y < 0.5) {
((GL2JNIActivity) act).handle_key(playerNum, pad.map[playerNum][1]/* B */, true);
pad.wasKeyStick[playerNum] = true;
} else if (pad.wasKeyStick[playerNum]){
((GL2JNIActivity) act).handle_key(playerNum, pad.map[playerNum][0], false);
((GL2JNIActivity) act).handle_key(playerNum, pad.map[playerNum][1], false);
pad.wasKeyStick[playerNum] = false;
}
} else {
if (RS_Y > 0.5) {
GL2JNIView.rt[playerNum] = (int) (RS_Y * 255);
} else if (RS_Y < 0.5) {
GL2JNIView.lt[playerNum] = (int) (-(RS_Y) * 255);
}
}
((GL2JNIActivity) act).getGameView().pushInput();
}
}
public boolean simulatedTouchEvent(int playerNum, float L2, float R2) {
GL2JNIView.lt[playerNum] = (int) (L2 * 255);
GL2JNIView.rt[playerNum] = (int) (R2 * 255);
((GL2JNIActivity) act).getGameView().pushInput();
return true;
// Handled by the primary controller interface
}
public void onStateEvent(StateEvent event)

View File

@ -98,8 +98,7 @@ public class SipEmulator extends Thread {
while(continueRecording){
byte[] freshData = new byte[ONE_BLIP_SIZE];
// read blocks
int bytesRead = record.read(freshData, 0, ONE_BLIP_SIZE);
//Log.d(TAG, "recordThread recorded: "+bytesRead);
record.read(freshData, 0, ONE_BLIP_SIZE);
if(!firstGet){
bytesReadBuffer.add(freshData);
}

View File

@ -0,0 +1,15 @@
LOCAL_CERTIFICATE := shared
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := sexplay
LOCAL_SRC_FILES := XperiaPlay.c
LOCAL_LDLIBS := -llog -landroid -lEGL -lGLESv1_CM
LOCAL_STATIC_LIBRARIES := android_native_app_glue
include $(BUILD_SHARED_LIBRARY)
$(call import-module,android/native_app_glue)

View File

@ -0,0 +1,4 @@
#APP_ABI := armeabi-v7a x86
APP_ABI := armeabi-v7a
APP_PLATFORM := android-9
NDK_TOOLCHAIN_VERSION := 4.8

View File

@ -0,0 +1,282 @@
/*
* Copyright (c) 2011, Sony Ericsson Mobile Communications AB.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the Sony Ericsson Mobile Communications AB nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#include <dlfcn.h>
#include <stdio.h>
#include <stdbool.h>
#include <string.h>
#include <android/log.h>
#include <jni.h>
#include <errno.h>
#include <android_native_app_glue.h>
#include <time.h>
#include <unistd.h>
#include <sys/system_properties.h>
#define EXPORT_XPLAY __attribute__ ((visibility("default")))
static JavaVM *jVM;
typedef unsigned char BOOL;
#define FALSE 0
#define TRUE 1
static jobject g_pActivity = 0;
static jmethodID javaOnNDKTouch = 0;
static jmethodID javaOnNDKKey = 0;
int target;
/**
* Our saved state data.
*/
struct TOUCHSTATE
{
int down;
int x;
int y;
};
/**
* Shared state for our app.
*/
struct ENGINE
{
struct android_app* app;
int render;
int width;
int height;
int has_focus;
//ugly way to track touch states
struct TOUCHSTATE touchstate_screen[64];
struct TOUCHSTATE touchstate_pad[64];
};
void attach(){
}
/**
* Process the next input event.
*/
static
int32_t
engine_handle_input( struct android_app* app, AInputEvent* event )
{
JNIEnv *jni;
(*jVM)->AttachCurrentThread(jVM, &jni, NULL);
struct ENGINE* engine = (struct ENGINE*)app->userData;
if (AInputEvent_getType(event) == AINPUT_EVENT_TYPE_KEY){
int device = AInputEvent_getDeviceId(event);
int action = AKeyEvent_getAction(event);
int keyCode = AKeyEvent_getKeyCode(event);
if(jni && g_pActivity){
if((*jni)->ExceptionCheck(jni)) {
(*jni)->ExceptionDescribe(jni);
(*jni)->ExceptionClear(jni);
}
(*jni)->CallIntMethod(jni, g_pActivity, javaOnNDKKey, device, keyCode, action, AKeyEvent_getMetaState(event));
if (!(keyCode == AKEYCODE_MENU || keyCode == AKEYCODE_BACK || keyCode == AKEYCODE_BUTTON_THUMBR || keyCode == AKEYCODE_VOLUME_UP || keyCode == AKEYCODE_VOLUME_DOWN || keyCode == AKEYCODE_BUTTON_SELECT)) {
return 1;
}
}
} else if( AInputEvent_getType(event) == AINPUT_EVENT_TYPE_MOTION ) {
int device = AInputEvent_getDeviceId( event );
int nSourceId = AInputEvent_getSource( event );
int nPointerCount = AMotionEvent_getPointerCount( event );
int n;
jboolean newTouch = JNI_TRUE;
for( n = 0 ; n < nPointerCount ; ++n )
{
int nPointerId = AMotionEvent_getPointerId( event, n );
int nAction = AMOTION_EVENT_ACTION_MASK & AMotionEvent_getAction( event );
int nRawAction = AMotionEvent_getAction( event );
struct TOUCHSTATE *touchstate = 0;
if( nSourceId == AINPUT_SOURCE_TOUCHPAD ) {
touchstate = engine->touchstate_pad;
} else {
touchstate = engine->touchstate_screen;
}
if( nAction == AMOTION_EVENT_ACTION_POINTER_DOWN || nAction == AMOTION_EVENT_ACTION_POINTER_UP )
{
int nPointerIndex = (AMotionEvent_getAction( event ) & AMOTION_EVENT_ACTION_POINTER_INDEX_MASK) >> AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT;
nPointerId = AMotionEvent_getPointerId( event, nPointerIndex );
}
if( nAction == AMOTION_EVENT_ACTION_DOWN || nAction == AMOTION_EVENT_ACTION_POINTER_DOWN )
{
touchstate[nPointerId].down = 1;
}
else if( nAction == AMOTION_EVENT_ACTION_UP || nAction == AMOTION_EVENT_ACTION_POINTER_UP || nAction == AMOTION_EVENT_ACTION_CANCEL )
{
touchstate[nPointerId].down = 0;
}
if (touchstate[nPointerId].down == 1)
{
touchstate[nPointerId].x = AMotionEvent_getX( event, n );
touchstate[nPointerId].y = AMotionEvent_getY( event, n );
}
if( jni && g_pActivity && device == target ) {
(*jni)->CallVoidMethod( jni, g_pActivity, javaOnNDKTouch, device, nSourceId, nRawAction, touchstate[nPointerId].x, touchstate[nPointerId].y, newTouch);
}
newTouch = JNI_FALSE;
}
if( device == target ) {
return 1;
} else {
return 0;
}
}
return 0;
}
/**
* Process the next main command.
*/
static
void
engine_handle_cmd( struct android_app* app, int32_t cmd )
{
struct ENGINE* engine = (struct ENGINE*)app->userData;
switch( cmd )
{
case APP_CMD_SAVE_STATE:
// The system has asked us to save our current state. Do so if needed
break;
case APP_CMD_INIT_WINDOW:
// The window is being shown, get it ready.
if( engine->app->window != NULL )
{
engine->has_focus = 1;
}
break;
case APP_CMD_GAINED_FOCUS:
engine->has_focus = 1;
break;
case APP_CMD_LOST_FOCUS:
// When our app loses focus, we stop rendering.
engine->render = 0;
engine->has_focus = 0;
//engine_draw_frame( engine );
break;
}
}
static
bool
IsXperiaPlay() {
char mod[PROP_VALUE_MAX + 1];
int lmod = __system_property_get("ro.product.model", mod);
return mod == "R800a" || mod == "R800i" || mod == "R800x" || mod == "R800at" || mod == "SO-01D" || mod == "zeus";
}
/**
* This is the main entry point of a native application that is using
* android_native_app_glue. It runs in its own thread, with its own
* event loop for receiving input events and doing other things (rendering).
*/
void
android_main( struct android_app* state )
{
struct ENGINE engine;
// Make sure glue isn't stripped.
app_dummy();
memset( &engine, 0, sizeof(engine) );
state->userData = &engine;
state->onAppCmd = engine_handle_cmd;
state->onInputEvent = engine_handle_input;
engine.app = state;
//setup(state);
//JNIEnv *env;
//(*jVM)->AttachCurrentThread(jVM, &env, NULL);
if( state->savedState != NULL )
{
// We are starting with a previous saved state; restore from it.
}
// our 'main loop'
while( 1 )
{
// Read all pending events.
int ident;
int events;
struct android_poll_source* source;
// If not rendering, we will block forever waiting for events.
// If rendering, we loop until all events are read, then continue
// to draw the next frame.
while( (ident = ALooper_pollAll( 250, NULL, &events, (void**)&source) ) >= 0 )
{
// Process this event.
// This will call the function pointer android_app:nInputEvent() which in our case is
// engine_handle_input()
if( source != NULL )
{
source->process( state, source );
}
// Check if we are exiting.
if( state->destroyRequested != 0 )
{
return;
}
//usleep(20000); //20 miliseconds
}
}
}
void EXPORT_XPLAY JNICALL Java_com_reicast_emulator_GL2JNINative_registerNative(JNIEnv *env, jobject clazz)
{
g_pActivity = (jobject)(*env)->NewGlobalRef(env, clazz);
}
void EXPORT_XPLAY JNICALL Java_com_reicast_emulator_GL2JNINative_registerXperia(JNIEnv *env, jobject clazz, jint xperia)
{
target = xperia;
}
jint EXPORT_XPLAY JNICALL JNI_OnLoad(JavaVM * vm, void * reserved)
{
JNIEnv *env;
jVM = vm;
if((*vm)->GetEnv(vm, (void**) &env, JNI_VERSION_1_4) != JNI_OK)
{
return -1;
}
const char* interface_path = "com/reicast/emulator/GL2JNINative";
jclass java_activity_class = (*env)->FindClass( env, interface_path );
javaOnNDKTouch = (*env)->GetMethodID( env, java_activity_class, "OnNativeMotion", "(IIIIIZ)Z");
javaOnNDKKey = (*env)->GetMethodID( env, java_activity_class, "OnNativeKeyPress", "(IIII)Z");
return JNI_VERSION_1_4;
}

9
shell/debug/.classpath Normal file
View File

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="src" path="src"/>
<classpathentry kind="src" path="gen"/>
<classpathentry kind="con" path="com.android.ide.eclipse.adt.ANDROID_FRAMEWORK"/>
<classpathentry exported="true" kind="con" path="com.android.ide.eclipse.adt.LIBRARIES"/>
<classpathentry exported="true" kind="con" path="com.android.ide.eclipse.adt.DEPENDENCIES"/>
<classpathentry kind="output" path="bin/classes"/>
</classpath>

33
shell/debug/.project Normal file
View File

@ -0,0 +1,33 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>ReicastDebug</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>com.android.ide.eclipse.adt.ResourceManagerBuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>com.android.ide.eclipse.adt.PreCompilerBuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.jdt.core.javabuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>com.android.ide.eclipse.adt.ApkBuilder</name>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>com.android.ide.eclipse.adt.AndroidNature</nature>
<nature>org.eclipse.jdt.core.javanature</nature>
</natures>
</projectDescription>

View File

@ -0,0 +1,26 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.reicast.emulator.debug"
android:sharedUserId="android.uid.reicast"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="18" />
<uses-permission android:name="android.permission.READ_LOGS" />
<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name" >
<activity android:name=".Debugger" >
<intent-filter>
<action android:name="com.reicast.emulator.DEBUG" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
</application>
</manifest>

95
shell/debug/build.xml Normal file
View File

@ -0,0 +1,95 @@
<?xml version="1.0" encoding="UTF-8"?>
<project name="reicast-debugger" default="help">
<!-- The local.properties file is created and updated by the 'android' tool.
It contains the path to the SDK. It should *NOT* be checked into
Version Control Systems. -->
<property file="local.properties" />
<!-- The ant.properties file can be created by you. It is only edited by the
'android' tool to add properties to it.
This is the place to change some Ant specific build properties.
Here are some properties you may want to change/update:
source.dir
The name of the source directory. Default is 'src'.
out.dir
The name of the output directory. Default is 'bin'.
For other overridable properties, look at the beginning of the rules
files in the SDK, at tools/ant/build.xml
Properties related to the SDK location or the project target should
be updated using the 'android' tool with the 'update' action.
This file is an integral part of the build system for your
application and should be checked into Version Control Systems.
-->
<property file="ant.properties" />
<!-- if sdk.dir was not set from one of the property file, then
get it from the ANDROID_HOME env var.
This must be done before we load project.properties since
the proguard config can use sdk.dir -->
<property environment="env" />
<condition property="sdk.dir" value="${env.ANDROID_HOME}">
<isset property="env.ANDROID_HOME" />
</condition>
<condition property="ndk.dir" value="${env.ANDROID_NDK}">
<isset property="env.ANDROID_NDK" />
</condition>
<!-- The project.properties file is created and updated by the 'android'
tool, as well as ADT.
This contains project specific properties such as project target, and library
dependencies. Lower level build properties are stored in ant.properties
(or in .classpath for Eclipse projects).
This file is an integral part of the build system for your
application and should be checked into Version Control Systems. -->
<loadproperties srcFile="project.properties" />
<!-- quick check on sdk.dir -->
<fail
message="sdk.dir is missing. Make sure to generate local.properties using 'android update project' or to inject it through the ANDROID_HOME environment variable."
unless="sdk.dir"
/>
<!--
Import per project custom build rules if present at the root of the project.
This is the place to put custom intermediary targets such as:
-pre-build
-pre-compile
-post-compile (This is typically used for code obfuscation.
Compiled code location: ${out.classes.absolute.dir}
If this is not done in place, override ${out.dex.input.absolute.dir})
-post-package
-post-build
-pre-clean
-->
<import file="custom_rules.xml" optional="true" />
<!-- Import the actual build file.
To customize existing targets, there are two options:
- Customize only one target:
- copy/paste the target into this file, *before* the
<import> task.
- customize it to your needs.
- Customize the whole content of build.xml
- copy/paste the content of the rules files (minus the top node)
into this file, replacing the <import> task.
- customize to your needs.
***********************
****** IMPORTANT ******
***********************
In all cases you must update the value of version-tag below to read 'custom' instead of an integer,
in order to avoid having your file be overridden by tools such as "android update project"
-->
<!-- version-tag: 1 -->
<import file="${sdk.dir}/tools/ant/build.xml" />
</project>

Binary file not shown.

View File

@ -0,0 +1,20 @@
# To enable ProGuard in your project, edit project.properties
# to define the proguard.config property as described in that file.
#
# Add project specific ProGuard rules here.
# By default, the flags in this file are appended to flags specified
# in ${sdk.dir}/tools/proguard/proguard-android.txt
# You can edit the include path and order by changing the ProGuard
# include property in project.properties.
#
# For more details, see
# http://developer.android.com/guide/developing/tools/proguard.html
# Add any project specific keep options here:
# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
# public *;
#}

View File

@ -0,0 +1,14 @@
# This file is automatically generated by Android Tools.
# Do not modify this file -- YOUR CHANGES WILL BE ERASED!
#
# This file must be checked in Version Control Systems.
#
# To customize properties used by the Ant build system edit
# "ant.properties", and override values to adapt the script to your
# project structure.
#
# To enable ProGuard to shrink and obfuscate your code, uncomment this (available properties: sdk.dir, user.home):
#proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt
# Project target.
target=android-19

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.7 KiB

View File

@ -0,0 +1,4 @@
<resources>
<string name="app_name">reicast debugger</string>
</resources>

View File

@ -0,0 +1,28 @@
package com.reicast.emulator.debug;
import android.app.Activity;
import android.os.Bundle;
public class Debugger extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
@Override
protected void onPause() {
super.onPause();
}
@Override
protected void onDestroy() {
super.onDestroy();
}
@Override
protected void onResume() {
super.onResume();
}
}

View File

@ -5,6 +5,8 @@ FOR_ARM :=1
FOR_PANDORA :=1
USE_SDL :=1
USE_OSS :=1
#PGO_MAKE :=1
PGO_USE :=1
RZDCY_SRC_DIR = ../../newdc
@ -29,9 +31,9 @@ SOURCES := cfg/ hw/arm7/ hw/aica/ hw/asic/ hw/ hw/gdrom/ hw/maple/ \
hw/extdev/ hw/arm/ imgread/ linux/ linux-dist/ ./ rec-ARM/ deps/zlib/ deps/chdr/ deps/crypto/ arm_emitter/
CXXFLAGS := -g -O3 -D RELEASE -c -D TARGET_PANDORA -D WEIRD_SLOWNESS -D HAS_VMU
CXXFLAGS := -std=gnu++11 -g -O3 -D RELEASE -c -D TARGET_PANDORA -D WEIRD_SLOWNESS
CXXFLAGS += -frename-registers -fno-strict-aliasing -fsingle-precision-constant
CXXFLAGS += -ffast-math -ftree-vectorize -fprefetch-loop-arrays
CXXFLAGS += -ffast-math -ftree-vectorize -fprefetch-loop-arrays -Wno-write-strings
#-std=c++0x
CXXFLAGS += $(CFLAGS) $(MFLAGS) -fno-exceptions -fno-rtti

BIN
shell/pandora/font.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 88 KiB