Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
alexbevi
GitHub Repository: alexbevi/BizHawk
Path: blob/master/yabause/src/android/jni/yui.c
2 views
1
/* Copyright 2011 Guillaume Duhamel
2
3
This file is part of Yabause.
4
5
Yabause is free software; you can redistribute it and/or modify
6
it under the terms of the GNU General Public License as published by
7
the Free Software Foundation; either version 2 of the License, or
8
(at your option) any later version.
9
10
Yabause is distributed in the hope that it will be useful,
11
but WITHOUT ANY WARRANTY; without even the implied warranty of
12
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
GNU General Public License for more details.
14
15
You should have received a copy of the GNU General Public License
16
along with Yabause; if not, write to the Free Software
17
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18
*/
19
20
#include <jni.h>
21
#include <android/bitmap.h>
22
#include <android/log.h>
23
24
#include "../../config.h"
25
#include "yabause.h"
26
#include "scsp.h"
27
#include "vidsoft.h"
28
#include "peripheral.h"
29
#include "m68kcore.h"
30
#include "sh2core.h"
31
#include "sh2int.h"
32
#include "cdbase.h"
33
#include "cs2.h"
34
#include "debug.h"
35
36
#include <stdio.h>
37
#include <dlfcn.h>
38
39
#define _ANDROID_2_2_
40
#ifdef _ANDROID_2_2_
41
#include "miniegl.h"
42
#else
43
#include <EGL/egl.h>
44
#endif
45
46
#include <GLES/gl.h>
47
#include <GLES/glext.h>
48
#include <pthread.h>
49
50
#include "sndaudiotrack.h"
51
52
JavaVM * yvm;
53
static jobject yabause;
54
static jobject ybitmap;
55
56
static char biospath[256] = "/mnt/sdcard/jap.rom";
57
static char cdpath[256] = "\0";
58
static char buppath[256] = "\0";
59
static char mpegpath[256] = "\0";
60
static char cartpath[256] = "\0";
61
62
EGLDisplay g_Display = EGL_NO_DISPLAY;
63
EGLSurface g_Surface = EGL_NO_SURFACE;
64
EGLContext g_Context = EGL_NO_CONTEXT;
65
GLuint g_FrameBuffer = 0;
66
GLuint g_VertexBuffer = 0;
67
int g_buf_width = -1;
68
int g_buf_height = -1;
69
pthread_mutex_t g_mtxGlLock = PTHREAD_MUTEX_INITIALIZER;
70
float vertices [] = {
71
0, 0, 0, 0,
72
320, 0, 0, 0,
73
320, 224, 0, 0,
74
0, 224, 0, 0
75
};
76
77
78
M68K_struct * M68KCoreList[] = {
79
&M68KDummy,
80
#ifdef HAVE_C68K
81
&M68KC68K,
82
#endif
83
#ifdef HAVE_Q68
84
&M68KQ68,
85
#endif
86
NULL
87
};
88
89
SH2Interface_struct *SH2CoreList[] = {
90
&SH2Interpreter,
91
&SH2DebugInterpreter,
92
#ifdef SH2_DYNAREC
93
&SH2Dynarec,
94
#endif
95
NULL
96
};
97
98
PerInterface_struct *PERCoreList[] = {
99
&PERDummy,
100
NULL
101
};
102
103
CDInterface *CDCoreList[] = {
104
&DummyCD,
105
&ISOCD,
106
NULL
107
};
108
109
SoundInterface_struct *SNDCoreList[] = {
110
&SNDDummy,
111
&SNDAudioTrack,
112
NULL
113
};
114
115
VideoInterface_struct *VIDCoreList[] = {
116
&VIDDummy,
117
&VIDSoft,
118
NULL
119
};
120
121
122
#define LOG_TAG "yabause"
123
124
/* Override printf for debug*/
125
int printf( const char * fmt, ... )
126
{
127
va_list ap;
128
va_start(ap, fmt);
129
int result = __android_log_vprint(ANDROID_LOG_INFO, LOG_TAG, fmt, ap);
130
va_end(ap);
131
return result;
132
}
133
134
void YuiErrorMsg(const char *string)
135
{
136
jclass yclass;
137
jmethodID errorMsg;
138
jstring message;
139
JNIEnv * env;
140
if ((*yvm)->GetEnv(yvm, (void**) &env, JNI_VERSION_1_6) != JNI_OK)
141
return;
142
143
yclass = (*env)->GetObjectClass(env, yabause);
144
errorMsg = (*env)->GetMethodID(env, yclass, "errorMsg", "(Ljava/lang/String;)V");
145
message = (*env)->NewStringUTF(env, string);
146
(*env)->CallVoidMethod(env, yabause, errorMsg, message);
147
}
148
149
void YuiSwapBuffers(void)
150
{
151
int buf_width, buf_height;
152
int error;
153
154
155
pthread_mutex_lock(&g_mtxGlLock);
156
if( g_Display == EGL_NO_DISPLAY )
157
{
158
pthread_mutex_unlock(&g_mtxGlLock);
159
return;
160
}
161
162
if( eglMakeCurrent(g_Display,g_Surface,g_Surface,g_Context) == EGL_FALSE )
163
{
164
printf( "eglMakeCurrent fail %04x",eglGetError());
165
pthread_mutex_unlock(&g_mtxGlLock);
166
return;
167
}
168
169
glClearColor( 0.0f,0.0f,0.0f,1.0f);
170
glClear(GL_COLOR_BUFFER_BIT);
171
172
173
if( g_FrameBuffer == 0 )
174
{
175
glEnable(GL_TEXTURE_2D);
176
glGenTextures(1,&g_FrameBuffer);
177
glBindTexture(GL_TEXTURE_2D, g_FrameBuffer);
178
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1024, 1024, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
179
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
180
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
181
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
182
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );
183
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
184
error = glGetError();
185
if( error != GL_NO_ERROR )
186
{
187
printf("gl error %d", error );
188
return;
189
}
190
}else{
191
glBindTexture(GL_TEXTURE_2D, g_FrameBuffer);
192
}
193
194
195
VIDCore->GetGlSize(&buf_width, &buf_height);
196
glTexSubImage2D(GL_TEXTURE_2D, 0,0,0,buf_width,buf_height,GL_RGBA,GL_UNSIGNED_BYTE,dispbuffer);
197
198
199
if( g_VertexBuffer == 0 )
200
{
201
glGenBuffers(1, &g_VertexBuffer);
202
glBindBuffer(GL_ARRAY_BUFFER, g_VertexBuffer);
203
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices),vertices,GL_STATIC_DRAW);
204
error = glGetError();
205
if( error != GL_NO_ERROR )
206
{
207
printf("gl error %d", error );
208
return;
209
}
210
}else{
211
glBindBuffer(GL_ARRAY_BUFFER, g_VertexBuffer);
212
}
213
214
if( buf_width != g_buf_width || buf_height != g_buf_height )
215
{
216
vertices[6]=vertices[10]=(float)buf_width/1024.f;
217
vertices[11]=vertices[15]=(float)buf_height/1024.f;
218
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices),vertices,GL_STATIC_DRAW);
219
glVertexPointer(2, GL_FLOAT, sizeof(float)*4, 0);
220
glTexCoordPointer(2, GL_FLOAT, sizeof(float)*4, (void*)(sizeof(float)*2));
221
glEnableClientState(GL_VERTEX_ARRAY);
222
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
223
g_buf_width = buf_width;
224
g_buf_height = buf_height;
225
}
226
227
glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
228
eglSwapBuffers(g_Display,g_Surface);
229
230
pthread_mutex_unlock(&g_mtxGlLock);
231
}
232
233
int Java_org_yabause_android_YabauseRunnable_initViewport( int width, int height)
234
{
235
int swidth;
236
int sheight;
237
int error;
238
char * buf;
239
240
g_Display = eglGetCurrentDisplay();
241
g_Surface = eglGetCurrentSurface(EGL_READ);
242
g_Context = eglGetCurrentContext();
243
244
eglQuerySurface(g_Display,g_Surface,EGL_WIDTH,&swidth);
245
eglQuerySurface(g_Display,g_Surface,EGL_HEIGHT,&sheight);
246
247
glViewport(0,0,swidth,sheight);
248
249
glMatrixMode(GL_PROJECTION);
250
glLoadIdentity();
251
glOrthof(0, 320, 224, 0, 1, 0);
252
253
glMatrixMode(GL_MODELVIEW);
254
glLoadIdentity();
255
256
glMatrixMode(GL_TEXTURE);
257
glLoadIdentity();
258
259
glDisable(GL_BLEND);
260
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
261
262
printf(glGetString(GL_VENDOR));
263
printf(glGetString(GL_RENDERER));
264
printf(glGetString(GL_VERSION));
265
printf(glGetString(GL_EXTENSIONS));
266
printf(eglQueryString(g_Display,EGL_EXTENSIONS));
267
eglSwapInterval(g_Display,0);
268
eglMakeCurrent(g_Display,EGL_NO_SURFACE,EGL_NO_SURFACE,EGL_NO_CONTEXT);
269
return 0;
270
}
271
272
#ifdef _ANDROID_2_2_
273
int initEGLFunc()
274
{
275
void * handle;
276
char *error;
277
278
handle = dlopen("libEGL.so",RTLD_LAZY);
279
if( handle == NULL )
280
{
281
printf(dlerror());
282
return -1;
283
}
284
285
eglGetCurrentDisplay = dlsym(handle, "eglGetCurrentDisplay");
286
if( eglGetCurrentDisplay == NULL){ printf(dlerror()); return -1; }
287
288
eglGetCurrentSurface = dlsym(handle, "eglGetCurrentSurface");
289
if( eglGetCurrentSurface == NULL){ printf(dlerror()); return -1; }
290
291
eglGetCurrentContext = dlsym(handle, "eglGetCurrentContext");
292
if( eglGetCurrentContext == NULL){ printf(dlerror()); return -1; }
293
294
eglQuerySurface = dlsym(handle, "eglQuerySurface");
295
if( eglQuerySurface == NULL){ printf(dlerror()); return -1; }
296
297
eglSwapInterval = dlsym(handle, "eglSwapInterval");
298
if( eglSwapInterval == NULL){ printf(dlerror()); return -1; }
299
300
eglMakeCurrent = dlsym(handle, "eglMakeCurrent");
301
if( eglMakeCurrent == NULL){ printf(dlerror()); return -1; }
302
303
eglSwapBuffers = dlsym(handle, "eglSwapBuffers");
304
if( eglSwapBuffers == NULL){ printf(dlerror()); return -1; }
305
306
eglQueryString = dlsym(handle, "eglQueryString");
307
if( eglQueryString == NULL){ printf(dlerror()); return -1; }
308
309
eglGetError = dlsym(handle, "eglGetError");
310
if( eglGetError == NULL){ printf(dlerror()); return -1; }
311
312
return 0;
313
}
314
#else
315
int initEGLFunc()
316
{
317
return 0;
318
}
319
#endif
320
321
int Java_org_yabause_android_YabauseRunnable_lockGL()
322
{
323
pthread_mutex_lock(&g_mtxGlLock);
324
}
325
326
int Java_org_yabause_android_YabauseRunnable_unlockGL()
327
{
328
pthread_mutex_unlock(&g_mtxGlLock);
329
}
330
331
332
jint
333
Java_org_yabause_android_YabauseRunnable_init( JNIEnv* env, jobject obj, jobject yab, jobject bitmap )
334
{
335
yabauseinit_struct yinit;
336
int res;
337
void * padbits;
338
339
if( initEGLFunc() == -1 ) return -1;
340
341
yabause = (*env)->NewGlobalRef(env, yab);
342
ybitmap = (*env)->NewGlobalRef(env, bitmap);
343
344
yinit.m68kcoretype = M68KCORE_C68K;
345
yinit.percoretype = PERCORE_DUMMY;
346
#ifdef SH2_DYNAREC
347
yinit.sh2coretype = 2;
348
#else
349
yinit.sh2coretype = SH2CORE_DEFAULT;
350
#endif
351
yinit.vidcoretype = VIDCORE_SOFT;
352
yinit.sndcoretype = SNDCORE_AUDIOTRACK;
353
yinit.cdcoretype = CDCORE_DEFAULT;
354
yinit.carttype = CART_NONE;
355
yinit.regionid = 0;
356
yinit.biospath = biospath;
357
yinit.cdpath = cdpath;
358
yinit.buppath = buppath;
359
yinit.mpegpath = mpegpath;
360
yinit.cartpath = cartpath;
361
yinit.videoformattype = VIDEOFORMATTYPE_NTSC;
362
363
res = YabauseInit(&yinit);
364
365
PerPortReset();
366
padbits = PerPadAdd(&PORTDATA1);
367
PerSetKey(1, PERPAD_LEFT, padbits);
368
PerSetKey(4, PERPAD_UP, padbits);
369
PerSetKey(6, PERPAD_DOWN, padbits);
370
PerSetKey(9, PERPAD_RIGHT, padbits);
371
372
ScspSetFrameAccurate(1);
373
374
return res;
375
}
376
377
void
378
Java_org_yabause_android_YabauseRunnable_deinit( JNIEnv* env )
379
{
380
YabauseDeInit();
381
}
382
383
void
384
Java_org_yabause_android_YabauseRunnable_exec( JNIEnv* env )
385
{
386
YabauseExec();
387
}
388
389
void
390
Java_org_yabause_android_YabauseRunnable_press( JNIEnv* env, jobject obj, jint key )
391
{
392
PerKeyDown(key);
393
}
394
395
void
396
Java_org_yabause_android_YabauseRunnable_release( JNIEnv* env, jobject obj, jint key )
397
{
398
PerKeyUp(key);
399
}
400
401
void log_callback(char * message)
402
{
403
__android_log_print(ANDROID_LOG_INFO, "yabause", "%s", message);
404
}
405
406
jint JNI_OnLoad(JavaVM * vm, void * reserved)
407
{
408
JNIEnv * env;
409
if ((*vm)->GetEnv(vm, (void**) &env, JNI_VERSION_1_6) != JNI_OK)
410
return -1;
411
412
yvm = vm;
413
414
LogStart();
415
LogChangeOutput(DEBUG_CALLBACK, (char *) log_callback);
416
417
return JNI_VERSION_1_6;
418
}
419
420
421