666 lines
23 KiB
C
666 lines
23 KiB
C
//Copyright (c) 2011-2020 <>< Charles Lohr - Under the MIT/x11 or NewBSD License you choose.
|
|
// NO WARRANTY! NO GUARANTEE OF SUPPORT! USE AT YOUR OWN RISK
|
|
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <math.h>
|
|
#include <string.h>
|
|
#include "os_generic.h"
|
|
#include <GLES3/gl3.h>
|
|
//A-s-s-e-t-s #include <android/asset_manager.h>
|
|
//A-s-s-e-t-s #include <android/asset_manager_jni.h>
|
|
#include <android_native_app_glue.h>
|
|
//SENSORSTURFF #include <android/sensor.h>
|
|
#include <byteswap.h>
|
|
#include <errno.h>
|
|
#include <fcntl.h>
|
|
#include "CNFGAndroid.h"
|
|
|
|
//#define CNFA_IMPLEMENTATION
|
|
#define CNFG_IMPLEMENTATION
|
|
#define CNFG3D
|
|
|
|
//AUDIO //#include "cnfa/CNFA.h"
|
|
#include "CNFG.h"
|
|
|
|
//webview//#define WEBVIEW_NATIVE_ACTIVITY_IMPLEMENTATION
|
|
//webview//#include "webview_native_activity.h"
|
|
|
|
float mountainangle;
|
|
float mountainoffsetx;
|
|
float mountainoffsety;
|
|
|
|
//SENSORSTURFF ASensorManager * sm;
|
|
//SENSORSTURFF const ASensor * as;
|
|
//SENSORSTURFF bool no_sensor_for_gyro = false;
|
|
//SENSORSTURFF ASensorEventQueue* aeq;
|
|
//SENSORSTURFF ALooper * l;
|
|
|
|
//webview//WebViewNativeActivityObject MyWebView;
|
|
|
|
//AUDIO const uint32_t SAMPLE_RATE = 44100;
|
|
//AUDIO const uint16_t SAMPLE_COUNT = 512;
|
|
//AUDIO uint32_t stream_offset = 0;
|
|
//AUDIO uint16_t audio_frequency;
|
|
|
|
|
|
//SENSORSTURFF // Inertial Measurement Unit (gyroscopes and accelerometer)
|
|
//SENSORSTURFF void SetupIMU()
|
|
//SENSORSTURFF {
|
|
//SENSORSTURFF sm = ASensorManager_getInstanceForPackage("gyroscope");
|
|
//SENSORSTURFF as = ASensorManager_getDefaultSensor( sm, ASENSOR_TYPE_GYROSCOPE );
|
|
//SENSORSTURFF no_sensor_for_gyro = as == NULL;
|
|
//SENSORSTURFF l = ALooper_prepare( ALOOPER_PREPARE_ALLOW_NON_CALLBACKS );
|
|
//SENSORSTURFF aeq = ASensorManager_createEventQueue( sm, (ALooper*)&l, 0, 0, 0 ); //XXX??!?! This looks wrong.
|
|
//SENSORSTURFF if(!no_sensor_for_gyro) {
|
|
//SENSORSTURFF ASensorEventQueue_enableSensor( aeq, as);
|
|
//SENSORSTURFF printf( "setEvent Rate: %d\n", ASensorEventQueue_setEventRate( aeq, as, 10000 ) );
|
|
//SENSORSTURFF }
|
|
//SENSORSTURFF
|
|
//SENSORSTURFF }
|
|
|
|
//SENSORSTURFF float accx, accy, accz;
|
|
//SENSORSTURFF int accs;
|
|
//SENSORSTURFF
|
|
//SENSORSTURFF void AccCheck()
|
|
//SENSORSTURFF {
|
|
//SENSORSTURFF if(no_sensor_for_gyro) {
|
|
//SENSORSTURFF return;
|
|
//SENSORSTURFF }
|
|
//SENSORSTURFF
|
|
//SENSORSTURFF ASensorEvent evt;
|
|
//SENSORSTURFF do
|
|
//SENSORSTURFF {
|
|
//SENSORSTURFF ssize_t s = ASensorEventQueue_getEvents( aeq, &evt, 1 );
|
|
//SENSORSTURFF if( s <= 0 ) break;
|
|
//SENSORSTURFF accx = evt.vector.v[0];
|
|
//SENSORSTURFF accy = evt.vector.v[1];
|
|
//SENSORSTURFF accz = evt.vector.v[2];
|
|
//SENSORSTURFF mountainangle /*degrees*/ -= accz;// * 3.1415 / 360.0;// / 100.0;
|
|
//SENSORSTURFF mountainoffsety += accy;
|
|
//SENSORSTURFF mountainoffsetx += accx;
|
|
//SENSORSTURFF accs++;
|
|
//SENSORSTURFF } while( 1 );
|
|
//SENSORSTURFF }
|
|
|
|
unsigned frames = 0;
|
|
unsigned long iframeno = 0;
|
|
|
|
void AndroidDisplayKeyboard(int pShow);
|
|
|
|
int lastbuttonx = 0;
|
|
int lastbuttony = 0;
|
|
int lastmotionx = 0;
|
|
int lastmotiony = 0;
|
|
int lastbid = 0;
|
|
int lastmask = 0;
|
|
int lastkey, lastkeydown;
|
|
|
|
static int keyboard_up;
|
|
uint8_t buttonstate[8];
|
|
|
|
void HandleKey( int keycode, int bDown )
|
|
{
|
|
lastkey = keycode;
|
|
lastkeydown = bDown;
|
|
if( keycode == 10 && !bDown ) { keyboard_up = 0; AndroidDisplayKeyboard( keyboard_up ); }
|
|
|
|
if( keycode == 4 ) { AndroidSendToBack( 1 ); } //Handle Physical Back Button.
|
|
}
|
|
|
|
void HandleButton( int x, int y, int button, int bDown )
|
|
{
|
|
buttonstate[button] = bDown;
|
|
lastbid = button;
|
|
lastbuttonx = x;
|
|
lastbuttony = y;
|
|
|
|
if( bDown ) { keyboard_up = !keyboard_up; AndroidDisplayKeyboard( keyboard_up ); }
|
|
}
|
|
|
|
void HandleMotion( int x, int y, int mask )
|
|
{
|
|
lastmask = mask;
|
|
lastmotionx = x;
|
|
lastmotiony = y;
|
|
}
|
|
|
|
//writes the text to a file to path (example): /storage/emulated/0/Android/data/org.yourorg.cnfgtest/files
|
|
// You would not normally want to do this, but it's an example of how to do local storage.
|
|
void Log(const char *fmt, ...)
|
|
{
|
|
const char* getpath = AndroidGetExternalFilesDir();
|
|
char buffer[2048];
|
|
snprintf(buffer, sizeof(buffer), "%s/log.txt", getpath);
|
|
FILE *f = fopen(buffer, "w");
|
|
if (f == NULL)
|
|
{
|
|
exit(1);
|
|
}
|
|
|
|
va_list arg;
|
|
va_start(arg, fmt);
|
|
vsnprintf(buffer, sizeof(buffer), fmt, arg);
|
|
va_end(arg);
|
|
|
|
fprintf(f, "%s\n", buffer);
|
|
|
|
fclose(f);
|
|
}
|
|
#define HMX 162
|
|
#define HMY 162
|
|
short screenx, screeny;
|
|
float Heightmap[HMX*HMY];
|
|
|
|
extern struct android_app * gapp;
|
|
|
|
void DrawHeightmap()
|
|
{
|
|
int x, y;
|
|
//float fdt = ((iframeno++)%(360*10))/10.0;
|
|
|
|
mountainangle += .2;
|
|
if( mountainangle < 0 ) mountainangle += 360;
|
|
if( mountainangle > 360 ) mountainangle -= 360;
|
|
|
|
mountainoffsety = mountainoffsety - ((mountainoffsety-100) * .1);
|
|
|
|
float eye[3] = { (float)(sin(mountainangle*(3.14159/180.0))*30*sin(mountainoffsety/100.)), (float)(cos(mountainangle*(3.14159/180.0))*30*sin(mountainoffsety/100.)), (float)(30*cos(mountainoffsety/100.)) };
|
|
float at[3] = { 0,0, 0 };
|
|
float up[3] = { 0,0, 1 };
|
|
|
|
tdSetViewport( -1, -1, 1, 1, screenx, screeny );
|
|
|
|
tdMode( tdPROJECTION );
|
|
tdIdentity( gSMatrix );
|
|
tdPerspective( 30, ((float)screenx)/((float)screeny), .1, 200., gSMatrix );
|
|
|
|
tdMode( tdMODELVIEW );
|
|
tdIdentity( gSMatrix );
|
|
tdTranslate( gSMatrix, 0, 0, -40 );
|
|
tdLookAt( gSMatrix, eye, at, up );
|
|
|
|
float scale = 60./HMX;
|
|
|
|
for( x = 0; x < HMX-1; x++ )
|
|
for( y = 0; y < HMY-1; y++ )
|
|
{
|
|
float tx = x-HMX/2;
|
|
float ty = y-HMY/2;
|
|
float pta[3];
|
|
float ptb[3];
|
|
float ptc[3];
|
|
float ptd[3];
|
|
|
|
float normal[3];
|
|
float lightdir[3] = { .6, -.6, 1 };
|
|
float tmp1[3];
|
|
float tmp2[3];
|
|
|
|
RDPoint pto[6];
|
|
|
|
pta[0] = (tx+0)*scale; pta[1] = (ty+0)*scale; pta[2] = Heightmap[(x+0)+(y+0)*HMX]*scale;
|
|
ptb[0] = (tx+1)*scale; ptb[1] = (ty+0)*scale; ptb[2] = Heightmap[(x+1)+(y+0)*HMX]*scale;
|
|
ptc[0] = (tx+0)*scale; ptc[1] = (ty+1)*scale; ptc[2] = Heightmap[(x+0)+(y+1)*HMX]*scale;
|
|
ptd[0] = (tx+1)*scale; ptd[1] = (ty+1)*scale; ptd[2] = Heightmap[(x+1)+(y+1)*HMX]*scale;
|
|
|
|
tdPSub( pta, ptb, tmp2 );
|
|
tdPSub( ptc, ptb, tmp1 );
|
|
tdCross( tmp1, tmp2, normal );
|
|
tdNormalizeSelf( normal );
|
|
|
|
tdFinalPoint( pta, pta );
|
|
tdFinalPoint( ptb, ptb );
|
|
tdFinalPoint( ptc, ptc );
|
|
tdFinalPoint( ptd, ptd );
|
|
|
|
if( pta[2] >= 1.0 ) continue;
|
|
if( ptb[2] >= 1.0 ) continue;
|
|
if( ptc[2] >= 1.0 ) continue;
|
|
if( ptd[2] >= 1.0 ) continue;
|
|
|
|
if( pta[2] < 0 ) continue;
|
|
if( ptb[2] < 0 ) continue;
|
|
if( ptc[2] < 0 ) continue;
|
|
if( ptd[2] < 0 ) continue;
|
|
|
|
pto[0].x = pta[0]; pto[0].y = pta[1];
|
|
pto[1].x = ptb[0]; pto[1].y = ptb[1];
|
|
pto[2].x = ptd[0]; pto[2].y = ptd[1];
|
|
|
|
pto[3].x = ptc[0]; pto[3].y = ptc[1];
|
|
pto[4].x = ptd[0]; pto[4].y = ptd[1];
|
|
pto[5].x = pta[0]; pto[5].y = pta[1];
|
|
|
|
// CNFGColor(((x+y)&1)?0xFFFFFF:0x000000);
|
|
|
|
float bright = tdDot( normal, lightdir );
|
|
if( bright < 0 ) bright = 0;
|
|
CNFGColor( 0xff | ( ( (int)( bright * 90 ) ) << 24 ) );
|
|
|
|
// CNFGTackPoly( &pto[0], 3 ); CNFGTackPoly( &pto[3], 3 );
|
|
CNFGTackSegment( pta[0], pta[1], ptb[0], ptb[1] );
|
|
CNFGTackSegment( pta[0], pta[1], ptc[0], ptc[1] );
|
|
CNFGTackSegment( ptb[0], ptb[1], ptc[0], ptc[1] );
|
|
|
|
}
|
|
}
|
|
|
|
|
|
int HandleDestroy()
|
|
{
|
|
printf( "Destroying\n" );
|
|
return 0;
|
|
}
|
|
|
|
volatile int suspended;
|
|
|
|
void HandleSuspend()
|
|
{
|
|
suspended = 1;
|
|
}
|
|
|
|
void HandleResume()
|
|
{
|
|
suspended = 0;
|
|
}
|
|
|
|
/*
|
|
void AudioCallback( struct CNFADriver * sd, short * out, short * in, int framesp, int framesr )
|
|
{
|
|
memset(out, 0, framesp*sizeof(uint16_t));
|
|
if(suspended) return;
|
|
if(!buttonstate[1]) return; // play audio only if ~touching with two fingers
|
|
audio_frequency = 440;
|
|
for(uint32_t i = 0; i < framesp; i++) {
|
|
int16_t sample = INT16_MAX * sin(audio_frequency*(2*M_PI)*(stream_offset+i)/SAMPLE_RATE);
|
|
out[i] = sample;
|
|
}
|
|
stream_offset += framesp;
|
|
}
|
|
*/
|
|
|
|
void MakeNotification( const char * channelID, const char * channelName, const char * title, const char * message )
|
|
{
|
|
static int id;
|
|
id++;
|
|
|
|
const struct JNINativeInterface * env = 0;
|
|
const struct JNINativeInterface ** envptr = &env;
|
|
const struct JNIInvokeInterface ** jniiptr = gapp->activity->vm;
|
|
const struct JNIInvokeInterface * jnii = *jniiptr;
|
|
|
|
jnii->AttachCurrentThread( jniiptr, &envptr, NULL);
|
|
env = (*envptr);
|
|
|
|
jstring channelIDStr = env->NewStringUTF( ENVCALL channelID );
|
|
jstring channelNameStr = env->NewStringUTF( ENVCALL channelName );
|
|
|
|
// Runs getSystemService(Context.NOTIFICATION_SERVICE).
|
|
jclass NotificationManagerClass = env->FindClass( ENVCALL "android/app/NotificationManager" );
|
|
jclass activityClass = env->GetObjectClass( ENVCALL gapp->activity->clazz );
|
|
jmethodID MethodGetSystemService = env->GetMethodID( ENVCALL activityClass, "getSystemService", "(Ljava/lang/String;)Ljava/lang/Object;");
|
|
jstring notificationServiceName = env->NewStringUTF( ENVCALL "notification" );
|
|
jobject notificationServiceObj = env->CallObjectMethod( ENVCALL gapp->activity->clazz, MethodGetSystemService, notificationServiceName);
|
|
|
|
// create the Notification channel.
|
|
jclass notificationChannelClass = env->FindClass( ENVCALL "android/app/NotificationChannel" );
|
|
jmethodID notificationChannelConstructorID = env->GetMethodID( ENVCALL notificationChannelClass, "<init>", "(Ljava/lang/String;Ljava/lang/CharSequence;I)V" );
|
|
jobject notificationChannelObj = env->NewObject( ENVCALL notificationChannelClass, notificationChannelConstructorID, channelIDStr, channelNameStr, 3 ); // IMPORTANCE_DEFAULT
|
|
jmethodID createNotificationChannelID = env->GetMethodID( ENVCALL NotificationManagerClass, "createNotificationChannel", "(Landroid/app/NotificationChannel;)V" );
|
|
env->CallVoidMethod( ENVCALL notificationServiceObj, createNotificationChannelID, notificationChannelObj );
|
|
|
|
env->DeleteLocalRef( ENVCALL channelNameStr );
|
|
env->DeleteLocalRef( ENVCALL notificationChannelObj );
|
|
|
|
// Create the Notification builder.
|
|
jclass classBuilder = env->FindClass( ENVCALL "android/app/Notification$Builder" );
|
|
jstring titleStr = env->NewStringUTF( ENVCALL title );
|
|
jstring messageStr = env->NewStringUTF( ENVCALL message );
|
|
jmethodID eventConstructor = env->GetMethodID( ENVCALL classBuilder, "<init>", "(Landroid/content/Context;Ljava/lang/String;)V" );
|
|
jobject eventObj = env->NewObject( ENVCALL classBuilder, eventConstructor, gapp->activity->clazz, channelIDStr );
|
|
jmethodID setContentTitleID = env->GetMethodID( ENVCALL classBuilder, "setContentTitle", "(Ljava/lang/CharSequence;)Landroid/app/Notification$Builder;" );
|
|
jmethodID setContentTextID = env->GetMethodID( ENVCALL classBuilder, "setContentText", "(Ljava/lang/CharSequence;)Landroid/app/Notification$Builder;" );
|
|
jmethodID setSmallIconID = env->GetMethodID( ENVCALL classBuilder, "setSmallIcon", "(I)Landroid/app/Notification$Builder;" );
|
|
|
|
// You could do things like setPriority, or setContentIntent if you want it to do something when you click it.
|
|
|
|
env->CallObjectMethod( ENVCALL eventObj, setContentTitleID, titleStr );
|
|
env->CallObjectMethod( ENVCALL eventObj, setContentTextID, messageStr );
|
|
env->CallObjectMethod( ENVCALL eventObj, setSmallIconID, 17301504 ); // R.drawable.alert_dark_frame
|
|
|
|
// eventObj.build()
|
|
jmethodID buildID = env->GetMethodID( ENVCALL classBuilder, "build", "()Landroid/app/Notification;" );
|
|
jobject notification = env->CallObjectMethod( ENVCALL eventObj, buildID );
|
|
|
|
// NotificationManager.notify(...)
|
|
jmethodID notifyID = env->GetMethodID( ENVCALL NotificationManagerClass, "notify", "(ILandroid/app/Notification;)V" );
|
|
env->CallVoidMethod( ENVCALL notificationServiceObj, notifyID, id, notification );
|
|
|
|
env->DeleteLocalRef( ENVCALL notification );
|
|
env->DeleteLocalRef( ENVCALL titleStr );
|
|
env->DeleteLocalRef( ENVCALL activityClass );
|
|
env->DeleteLocalRef( ENVCALL messageStr );
|
|
env->DeleteLocalRef( ENVCALL channelIDStr );
|
|
env->DeleteLocalRef( ENVCALL NotificationManagerClass );
|
|
env->DeleteLocalRef( ENVCALL notificationServiceObj );
|
|
env->DeleteLocalRef( ENVCALL notificationServiceName );
|
|
|
|
}
|
|
|
|
void HandleThisWindowTermination()
|
|
{
|
|
suspended = 1;
|
|
}
|
|
|
|
|
|
uint32_t randomtexturedata[256*256];
|
|
//webview //uint32_t webviewdata[500*500];
|
|
//webview //char fromJSBuffer[128];
|
|
//webview
|
|
//webview //void CheckWebView( void * v )
|
|
//webview //{
|
|
//webview // static int runno = 0;
|
|
//webview // WebViewNativeActivityObject * wvn = (WebViewNativeActivityObject*)v;
|
|
//webview // if( WebViewGetProgress( wvn ) != 100 ) return;
|
|
//webview //
|
|
//webview // runno++;
|
|
//webview // if( runno == 1 )
|
|
//webview // {
|
|
//webview // // The attach (initial) message payload has no meaning.
|
|
//webview // WebViewPostMessage( wvn, "", 1 );
|
|
//webview // }
|
|
//webview // else
|
|
//webview // {
|
|
//webview // // Invoke JavaScript, which calls a function to send a webmessage
|
|
//webview // // back into C land.
|
|
//webview // WebViewExecuteJavascript( wvn, "SendMessageToC();" );
|
|
//webview //
|
|
//webview // // Send a WebMessage into the JavaScript code.
|
|
//webview // char st[128];
|
|
//webview // sprintf( st, "Into JavaScript %d\n", runno );
|
|
//webview // WebViewPostMessage( wvn, st, 0 );
|
|
//webview // }
|
|
//webview //}
|
|
|
|
//webview//jobject g_attachLooper;
|
|
|
|
//webview //void SetupWebView( void * v )
|
|
//webview //{
|
|
//webview // WebViewNativeActivityObject * wvn = (WebViewNativeActivityObject*)v;
|
|
//webview //
|
|
//webview //
|
|
//webview // const struct JNINativeInterface * env = 0;
|
|
//webview // const struct JNINativeInterface ** envptr = &env;
|
|
//webview // const struct JNIInvokeInterface ** jniiptr = gapp->activity->vm;
|
|
//webview // const struct JNIInvokeInterface * jnii = *jniiptr;
|
|
//webview //
|
|
//webview // jnii->AttachCurrentThread( jniiptr, &envptr, NULL);
|
|
//webview // env = (*envptr);
|
|
//webview //
|
|
//webview // while( g_attachLooper == 0 ) usleep(1);
|
|
//webview // WebViewCreate( wvn, "file:///android_asset/index.html", g_attachLooper, 500, 500 );
|
|
//webview // //WebViewCreate( wvn, "about:blank", g_attachLooper, 500, 500 );
|
|
//webview //}
|
|
|
|
|
|
//webview //pthread_t jsthread;
|
|
//webview //
|
|
//webview //void * JavscriptThread( void * v )
|
|
//webview //{
|
|
//webview // const struct JNINativeInterface * env = 0;
|
|
//webview // const struct JNINativeInterface ** envptr = &env;
|
|
//webview // const struct JNIInvokeInterface ** jniiptr = gapp->activity->vm;
|
|
//webview // const struct JNIInvokeInterface * jnii = *jniiptr;
|
|
//webview //
|
|
//webview // jnii->AttachCurrentThread( jniiptr, &envptr, NULL);
|
|
//webview // env = (*envptr);
|
|
//webview //
|
|
//webview // // Create a looper on this thread...
|
|
//webview // jclass LooperClass = env->FindClass(envptr, "android/os/Looper");
|
|
//webview // jmethodID myLooperMethod = env->GetStaticMethodID(envptr, LooperClass, "myLooper", "()Landroid/os/Looper;");
|
|
//webview // jobject thisLooper = env->CallStaticObjectMethod( envptr, LooperClass, myLooperMethod );
|
|
//webview // if( !thisLooper )
|
|
//webview // {
|
|
//webview // jmethodID prepareMethod = env->GetStaticMethodID(envptr, LooperClass, "prepare", "()V");
|
|
//webview // env->CallStaticVoidMethod( envptr, LooperClass, prepareMethod );
|
|
//webview // thisLooper = env->CallStaticObjectMethod( envptr, LooperClass, myLooperMethod );
|
|
//webview // g_attachLooper = env->NewGlobalRef(envptr, thisLooper);
|
|
//webview // }
|
|
//webview //
|
|
//webview // jmethodID getQueueMethod = env->GetMethodID( envptr, LooperClass, "getQueue", "()Landroid/os/MessageQueue;" );
|
|
//webview // jobject lque = env->CallObjectMethod( envptr, g_attachLooper, getQueueMethod );
|
|
//webview //
|
|
//webview // jclass MessageQueueClass = env->FindClass(envptr, "android/os/MessageQueue");
|
|
//webview // jmethodID nextMethod = env->GetMethodID( envptr, MessageQueueClass, "next", "()Landroid/os/Message;" );
|
|
//webview //
|
|
//webview // jclass MessageClass = env->FindClass(envptr, "android/os/Message");
|
|
//webview // jfieldID objid = env->GetFieldID( envptr, MessageClass, "obj", "Ljava/lang/Object;" );
|
|
//webview // jclass PairClass = env->FindClass(envptr, "android/util/Pair");
|
|
//webview // jfieldID pairfirst = env->GetFieldID( envptr, PairClass, "first", "Ljava/lang/Object;" );
|
|
//webview //
|
|
//webview // while(1)
|
|
//webview // {
|
|
//webview // // Instead of using Looper::loop(), we just call next on the looper object.
|
|
//webview // jobject msg = env->CallObjectMethod( envptr, lque, nextMethod );
|
|
//webview // jobject innerObj = env->GetObjectField( envptr, msg, objid );
|
|
//webview // const char * name;
|
|
//webview // jstring strObj;
|
|
//webview // jclass innerClass;
|
|
//webview //
|
|
//webview // // Check Object Type
|
|
//webview // {
|
|
//webview // innerClass = env->GetObjectClass( envptr, innerObj );
|
|
//webview // jmethodID mid = env->GetMethodID( envptr, innerClass, "getClass", "()Ljava/lang/Class;");
|
|
//webview // jobject clsObj = env->CallObjectMethod( envptr, innerObj, mid );
|
|
//webview // jclass clazzz = env->GetObjectClass( envptr, clsObj );
|
|
//webview // mid = env->GetMethodID(envptr, clazzz, "getName", "()Ljava/lang/String;");
|
|
//webview // strObj = (jstring)env->CallObjectMethod( envptr, clsObj, mid);
|
|
//webview // name = env->GetStringUTFChars( envptr, strObj, 0);
|
|
//webview // env->DeleteLocalRef( envptr, clsObj );
|
|
//webview // env->DeleteLocalRef( envptr, clazzz );
|
|
//webview // }
|
|
//webview //
|
|
//webview // if( strcmp( name, "z5" ) == 0 )
|
|
//webview // {
|
|
//webview // // Special, Some Androids (notably Meta Quest) use a different private message type.
|
|
//webview // jfieldID mstrf = env->GetFieldID( envptr, innerClass, "a", "[B" );
|
|
//webview // jbyteArray jba = (jstring)env->GetObjectField(envptr, innerObj, mstrf );
|
|
//webview // int len = env->GetArrayLength( envptr, jba );
|
|
//webview // jboolean isCopy = 0;
|
|
//webview // jbyte * bufferPtr = env->GetByteArrayElements(envptr, jba, &isCopy);
|
|
//webview //
|
|
//webview // if( len >= 6 )
|
|
//webview // {
|
|
//webview // const char *descr = (const char*)bufferPtr + 6;
|
|
//webview // char tcpy[len-5];
|
|
//webview // memcpy( tcpy, descr, len-6 );
|
|
//webview // tcpy[len-6] = 0;
|
|
//webview // snprintf( fromJSBuffer, sizeof( fromJSBuffer)-1, "WebMessage: %s\n", tcpy );
|
|
//webview //
|
|
//webview // env->DeleteLocalRef( envptr, jba );
|
|
//webview // }
|
|
//webview // }
|
|
//webview // else
|
|
//webview // {
|
|
//webview // jobject MessagePayload = env->GetObjectField( envptr, innerObj, pairfirst );
|
|
//webview // // MessagePayload is a org.chromium.content_public.browser.MessagePayload
|
|
//webview //
|
|
//webview // jclass mpclass = env->GetObjectClass( envptr, MessagePayload );
|
|
//webview //
|
|
//webview // // Get field "b" which is the web message payload.
|
|
//webview // // If you are using binary sockets, it will be in `c` and be a byte array.
|
|
//webview // jfieldID mstrf = env->GetFieldID( envptr, mpclass, "b", "Ljava/lang/String;" );
|
|
//webview // jstring strObjDescr = (jstring)env->GetObjectField(envptr, MessagePayload, mstrf );
|
|
//webview //
|
|
//webview // const char *descr = env->GetStringUTFChars( envptr, strObjDescr, 0);
|
|
//webview // snprintf( fromJSBuffer, sizeof( fromJSBuffer)-1, "WebMessage: %s\n", descr );
|
|
//webview //
|
|
//webview // env->ReleaseStringUTFChars(envptr, strObjDescr, descr);
|
|
//webview // env->DeleteLocalRef( envptr, strObjDescr );
|
|
//webview // env->DeleteLocalRef( envptr, MessagePayload );
|
|
//webview // env->DeleteLocalRef( envptr, mpclass );
|
|
//webview // }
|
|
//webview // env->ReleaseStringUTFChars(envptr, strObj, name);
|
|
//webview // env->DeleteLocalRef( envptr, strObj );
|
|
//webview // env->DeleteLocalRef( envptr, msg );
|
|
//webview // env->DeleteLocalRef( envptr, innerObj );
|
|
//webview // env->DeleteLocalRef( envptr, innerClass );
|
|
//webview // }
|
|
//webview //}
|
|
//webview //
|
|
//webview //void SetupJSThread()
|
|
//webview //{
|
|
//webview // pthread_create( &jsthread, 0, JavscriptThread, 0 );
|
|
//webview //}
|
|
|
|
int main( int argc, char ** argv )
|
|
{
|
|
int x, y;
|
|
double ThisTime;
|
|
double LastFPSTime = OGGetAbsoluteTime();
|
|
|
|
Log( "Starting Up" );
|
|
|
|
CNFGBGColor = 0x000040ff;
|
|
CNFGSetupFullscreen( "Test Bench", 0 );
|
|
|
|
HandleWindowTermination = HandleThisWindowTermination;
|
|
|
|
for( x = 0; x < HMX; x++ )
|
|
for( y = 0; y < HMY; y++ )
|
|
{
|
|
Heightmap[x+y*HMX] = tdPerlin2D( x, y )*8.;
|
|
}
|
|
|
|
//A-s-s-e-t-s const char * assettext = "Not Found,2";
|
|
//A-s-s-e-t-s AAsset * file = AAssetManager_open( gapp->activity->assetManager, "asset.txt", AASSET_MODE_BUFFER );
|
|
//A-s-s-e-t-s if( file )
|
|
//A-s-s-e-t-s {
|
|
//A-s-s-e-t-s size_t fileLength = AAsset_getLength(file);
|
|
//A-s-s-e-t-s char * temp = (char*)malloc( fileLength + 1);
|
|
//A-s-s-e-t-s memcpy( temp, AAsset_getBuffer( file ), fileLength );
|
|
//A-s-s-e-t-s temp[fileLength] = 0;
|
|
//A-s-s-e-t-s assettext = temp;
|
|
//A-s-s-e-t-s }
|
|
|
|
//SENSORSTURFF // Inertial Measurement Unit (gyroscopes and accelerometer)
|
|
//SENSORSTURFF SetupIMU();
|
|
|
|
//SOUND // Disabled, for now.
|
|
//SOUND //InitCNFAAndroid( AudioCallback, "A Name", SAMPLE_RATE, 0, 1, 0, SAMPLE_COUNT, 0, 0, 0 );
|
|
|
|
//webview// SetupJSThread();
|
|
|
|
//webview // Create webview and wait for its completion
|
|
//webview // RunCallbackOnUIThread( SetupWebView, &MyWebView );
|
|
//webview // while( !MyWebView.WebViewObject ) usleep(1);
|
|
|
|
Log( "Startup Complete" );
|
|
|
|
while(1)
|
|
{
|
|
int i;
|
|
iframeno++;
|
|
|
|
if( iframeno == 200 )
|
|
{
|
|
MakeNotification( "default", "rawdraw alerts", "rawdraw", "Hit frame two hundred\nNew Line" );
|
|
}
|
|
|
|
CNFGHandleInput();
|
|
//SENSORSTURFF AccCheck();
|
|
|
|
if( suspended ) { usleep(50000); continue; }
|
|
|
|
//webview // RunCallbackOnUIThread( (void(*)(void*))WebViewRequestRenderToCanvas, &MyWebView );
|
|
//webview // RunCallbackOnUIThread( CheckWebView, &MyWebView );
|
|
|
|
CNFGClearFrame();
|
|
CNFGColor( 0xFFFFFFFF );
|
|
CNFGGetDimensions( &screenx, &screeny );
|
|
|
|
// Mesh in background
|
|
CNFGSetLineWidth( 9 );
|
|
DrawHeightmap();
|
|
CNFGPenX = 0; CNFGPenY = 400;
|
|
CNFGColor( 0xffffffff );
|
|
//A-s-s-e-t-s CNFGDrawText( assettext, 15 );
|
|
CNFGFlushRender();
|
|
|
|
CNFGPenX = 0; CNFGPenY = 480;
|
|
char st[50];
|
|
sprintf( st, "%dx%d %d %d %d %d %d %d\n%d %d", screenx, screeny, lastbuttonx, lastbuttony, lastmotionx, lastmotiony, lastkey, lastkeydown, lastbid, lastmask);
|
|
CNFGDrawText( st, 10 );
|
|
CNFGSetLineWidth( 2 );
|
|
|
|
// Square behind text
|
|
CNFGColor( 0x303030ff );
|
|
CNFGTackRectangle( 600, 0, 950, 350);
|
|
|
|
CNFGPenX = 10; CNFGPenY = 10;
|
|
|
|
// Text
|
|
CNFGColor( 0xffffffff );
|
|
for( i = 0; i < 1; i++ )
|
|
{
|
|
int c;
|
|
char tw[2] = { 0, 0 };
|
|
for( c = 0; c < 256; c++ )
|
|
{
|
|
tw[0] = c;
|
|
|
|
CNFGPenX = ( c % 16 ) * 20+606;
|
|
CNFGPenY = ( c / 16 ) * 20+5;
|
|
CNFGDrawText( tw, 4 );
|
|
}
|
|
}
|
|
|
|
// Green triangles
|
|
CNFGPenX = 0;
|
|
CNFGPenY = 0;
|
|
CNFGColor( 0x00FF00FF );
|
|
|
|
for( i = 0; i < 400; i++ )
|
|
{
|
|
RDPoint pp[3];
|
|
pp[0].x = (short)(50*sin((float)(i+iframeno)*.01) + (i%20)*30);
|
|
pp[0].y = (short)(50*cos((float)(i+iframeno)*.01) + (i/20)*20)+700;
|
|
pp[1].x = (short)(20*sin((float)(i+iframeno)*.01) + (i%20)*30);
|
|
pp[1].y = (short)(50*cos((float)(i+iframeno)*.01) + (i/20)*20)+700;
|
|
pp[2].x = (short)(10*sin((float)(i+iframeno)*.01) + (i%20)*30);
|
|
pp[2].y = (short)(30*cos((float)(i+iframeno)*.01) + (i/20)*20)+700;
|
|
CNFGTackPoly( pp, 3 );
|
|
}
|
|
|
|
// Last WebMessage
|
|
CNFGColor( 0xFFFFFFFF );
|
|
CNFGPenX = 0; CNFGPenY = 100;
|
|
// CNFGDrawText( fromJSBuffer, 6 );
|
|
|
|
int x, y;
|
|
for( y = 0; y < 256; y++ )
|
|
for( x = 0; x < 256; x++ )
|
|
randomtexturedata[x+y*256] = x | ((x*394543L+y*355+iframeno*3)<<8);
|
|
CNFGBlitImage( randomtexturedata, 100, 600, 256, 256 );
|
|
|
|
//webview //WebViewNativeGetPixels( &MyWebView, webviewdata, 500, 500 );
|
|
//webview //CNFGBlitImage( webviewdata, 500, 640, 500, 500 );
|
|
|
|
frames++;
|
|
//On Android, CNFGSwapBuffers must be called, and CNFGUpdateScreenWithBitmap does not have an implied framebuffer swap.
|
|
CNFGSwapBuffers();
|
|
|
|
ThisTime = OGGetAbsoluteTime();
|
|
if( ThisTime > LastFPSTime + 1 )
|
|
{
|
|
printf( "FPS: %d\n", frames );
|
|
frames = 0;
|
|
LastFPSTime+=1;
|
|
}
|
|
|
|
}
|
|
|
|
return(0);
|
|
}
|
|
|