Skip to content

Commit

Permalink
Move android platform code into Platform_Android.c
Browse files Browse the repository at this point in the history
  • Loading branch information
UnknownShadow200 committed Sep 26, 2021
1 parent f10596a commit d1f9797
Show file tree
Hide file tree
Showing 7 changed files with 254 additions and 212 deletions.
7 changes: 1 addition & 6 deletions src/Game.c
Expand Up @@ -533,12 +533,7 @@ void Game_TakeScreenshot(void) {
Chat_Add1("&eTaken screenshot as: %s", &filename);

#ifdef CC_BUILD_ANDROID
path.length = 0;
JavaCall_String_String("shareScreenshot", &filename, &path);
if (!path.length) return;

Chat_AddRaw("&cError sharing screenshot");
Chat_Add1(" &c%s", &path);
Platform_ShareScreenshot(&filename);
#endif
#endif
}
Expand Down
2 changes: 1 addition & 1 deletion src/Graphics_D3D11.c
Expand Up @@ -494,7 +494,7 @@ static void RS_CreateRasterState(void) {
desc.CullMode = D3D11_CULL_NONE;
desc.FillMode = D3D11_FILL_SOLID;
desc.FrontCounterClockwise = true;
desc.DepthClipEnable = true; // otherwise vertices beyond far plane are still wrongly rendered
desc.DepthClipEnable = true; // otherwise vertices/pixels beyond far plane are still wrongly rendered
ID3D11Device_CreateRasterizerState(device, &desc, &rs_state);
}

Expand Down
20 changes: 10 additions & 10 deletions src/Http_Worker.c
Expand Up @@ -643,7 +643,7 @@ cc_bool Http_DescribeError(cc_result res, cc_string* dst) {

JavaGetCurrentEnv(env);
args[0].i = res;
obj = JavaInstanceCall_Obj(env, JAVA_httpDescribeError, args);
obj = JavaICall_Obj(env, JAVA_httpDescribeError, args);
if (!obj) return false;

err = JavaGetString(env, obj, buffer);
Expand All @@ -660,7 +660,7 @@ static void Http_AddHeader(struct HttpRequest* req, const char* key, const cc_st
args[0].l = JavaMakeConst(env, key);
args[1].l = JavaMakeString(env, value);

JavaInstanceCall_Void(env, JAVA_httpSetHeader, args);
JavaICall_Void(env, JAVA_httpSetHeader, args);
(*env)->DeleteLocalRef(env, args[0].l);
(*env)->DeleteLocalRef(env, args[1].l);
}
Expand All @@ -687,12 +687,12 @@ static const JNINativeMethod methods[] = {
{ "httpAppendData", "([BI)V", java_HttpAppendData }
};
static void CacheMethodRefs(JNIEnv* env) {
JAVA_httpInit = JavaGetMethod(env, "httpInit", "(Ljava/lang/String;Ljava/lang/String;)I");
JAVA_httpSetHeader = JavaGetMethod(env, "httpSetHeader", "(Ljava/lang/String;Ljava/lang/String;)V");
JAVA_httpPerform = JavaGetMethod(env, "httpPerform", "()I");
JAVA_httpSetData = JavaGetMethod(env, "httpSetData", "([B)I");
JAVA_httpInit = JavaGetIMethod(env, "httpInit", "(Ljava/lang/String;Ljava/lang/String;)I");
JAVA_httpSetHeader = JavaGetIMethod(env, "httpSetHeader", "(Ljava/lang/String;Ljava/lang/String;)V");
JAVA_httpPerform = JavaGetIMethod(env, "httpPerform", "()I");
JAVA_httpSetData = JavaGetIMethod(env, "httpSetData", "([B)I");

JAVA_httpDescribeError = JavaGetMethod(env, "httpDescribeError", "(I)Ljava/lang/String;");
JAVA_httpDescribeError = JavaGetIMethod(env, "httpDescribeError", "(I)Ljava/lang/String;");
}

static void HttpBackend_Init(void) {
Expand All @@ -710,7 +710,7 @@ static cc_result Http_InitReq(JNIEnv* env, struct HttpRequest* req, cc_string* u
args[0].l = JavaMakeString(env, url);
args[1].l = JavaMakeConst(env, verbs[req->requestType]);

res = JavaInstanceCall_Int(env, JAVA_httpInit, args);
res = JavaICall_Int(env, JAVA_httpInit, args);
(*env)->DeleteLocalRef(env, args[0].l);
(*env)->DeleteLocalRef(env, args[1].l);
return res;
Expand All @@ -721,7 +721,7 @@ static cc_result Http_SetData(JNIEnv* env, struct HttpRequest* req) {
jint res;

args[0].l = JavaMakeBytes(env, req->data, req->size);
res = JavaInstanceCall_Int(env, JAVA_httpSetData, args);
res = JavaICall_Int(env, JAVA_httpSetData, args);
(*env)->DeleteLocalRef(env, args[0].l);
return res;
}
Expand All @@ -741,7 +741,7 @@ static cc_result HttpBackend_Do(struct HttpRequest* req, cc_string* url) {

req->_capacity = 0;
http_curProgress = HTTP_PROGRESS_FETCHING_DATA;
res = JavaInstanceCall_Int(env, JAVA_httpPerform, NULL);
res = JavaICall_Int(env, JAVA_httpPerform, NULL);
http_curProgress = 100;
return res;
}
Expand Down
15 changes: 7 additions & 8 deletions src/Platform.h
Expand Up @@ -243,12 +243,13 @@ CC_API cc_result Socket_Poll(cc_socket s, int mode, cc_bool* success);
extern jclass App_Class;
extern jobject App_Instance;
extern JavaVM* VM_Ptr;
void Platform_ShareScreenshot(const cc_string* filename);

#define JavaGetCurrentEnv(env) (*VM_Ptr)->AttachCurrentThread(VM_Ptr, &env, NULL)
#define JavaMakeConst(env, str) (*env)->NewStringUTF(env, str)

#define JavaRegisterNatives(env, methods) (*env)->RegisterNatives(env, App_Class, methods, Array_Elems(methods));
#define JavaGetMethod(env, name, sig) (*env)->GetMethodID(env, App_Class, name, sig)
#define JavaGetIMethod(env, name, sig) (*env)->GetMethodID(env, App_Class, name, sig)

/* Creates a string from the given java string. buffer must be at least NATIVE_STR_LEN long. */
/* NOTE: Don't forget to call env->ReleaseStringUTFChars. Only works with ASCII strings. */
Expand All @@ -261,8 +262,6 @@ jbyteArray JavaMakeBytes(JNIEnv* env, const void* src, cc_uint32 len);
void JavaCallVoid(JNIEnv* env, const char* name, const char* sig, jvalue* args);
/* Calls a method in the activity class that returns a jint. */
jlong JavaCallLong(JNIEnv* env, const char* name, const char* sig, jvalue* args);
/* Calls a method in the activity class that returns a jint. */
jfloat JavaCallFloat(JNIEnv* env, const char* name, const char* sig, jvalue* args);
/* Calls a method in the activity class that returns a jobject. */
jobject JavaCallObject(JNIEnv* env, const char* name, const char* sig, jvalue* args);
/* Calls a method in the activity class that takes a string and returns nothing. */
Expand All @@ -272,12 +271,12 @@ void JavaCall_Void_String(const char* name, cc_string* dst);
/* Calls a method in the activity class that takes a string and returns a string. */
void JavaCall_String_String(const char* name, const cc_string* arg, cc_string* dst);

#define JavaInstanceCall_Void(env, method, args) (*env)->CallVoidMethodA(env, App_Instance, method, args)
#define JavaICall_Void(env, method, args) (*env)->CallVoidMethodA(env, App_Instance, method, args)
/* Calls an instance method in the activity class that returns a jint */
#define JavaInstanceCall_Int(env, method, args) (*env)->CallIntMethodA(env, App_Instance, method, args)
#define JavaInstanceCall_Long(env, method, args) (*env)->CallLongMethodA(env, App_Instance, method, args)
#define JavaICall_Int(env, method, args) (*env)->CallIntMethodA(env, App_Instance, method, args)
#define JavaICall_Long(env, method, args) (*env)->CallLongMethodA(env, App_Instance, method, args)
/* Calls an instance method in the activity class that returns a jfloat */
#define JavaInstanceCall_Float(env,method, args) (*env)->CallFloatMethodA(env, App_Instance, method, args)
#define JavaInstanceCall_Obj(env, method, args) (*env)->CallObjectMethodA(env,App_Instance, method, args)
#define JavaICall_Float(env,method, args) (*env)->CallFloatMethodA(env, App_Instance, method, args)
#define JavaICall_Obj(env, method, args) (*env)->CallObjectMethodA(env,App_Instance, method, args)
#endif
#endif
201 changes: 201 additions & 0 deletions src/Platform_Android.c
@@ -0,0 +1,201 @@
#include "Core.h"
#if defined CC_BUILD_ANDROID
#include "Chat.h"
#include "Constants.h"
#include "Errors.h"
#include "Funcs.h"
#include "String.h"
#include "Platform.h"
#include <unistd.h>
#include <android/log.h>


/*########################################################################################################################*
*------------------------------------------------------Logging/Time-------------------------------------------------------*
*#########################################################################################################################*/
void Platform_Log(const char* msg, int len) {
char tmp[2048 + 1];
len = min(len, 2048);

Mem_Copy(tmp, msg, len); tmp[len] = '\0';
/* log using logchat */
__android_log_write(ANDROID_LOG_DEBUG, "ClassiCube", tmp);
}


/*########################################################################################################################*
*-----------------------------------------------------Process/Module------------------------------------------------------*
*#########################################################################################################################*/
static char gameArgsBuffer[512];
static cc_string gameArgs = String_FromArray(gameArgsBuffer);

cc_result Process_StartGame(const cc_string* args) {
String_Copy(&gameArgs, args);
return 0;
}

cc_result Process_StartOpen(const cc_string* args) {
JavaCall_String_Void("startOpen", args);
return 0;
}


/*########################################################################################################################*
*--------------------------------------------------------Updater----------------------------------------------------------*
*#########################################################################################################################*/
const char* const Updater_OGL = NULL;
const char* const Updater_D3D9 = NULL;
cc_bool Updater_Clean(void) { return true; }

cc_result Updater_GetBuildTime(cc_uint64* t) {
JNIEnv* env;
JavaGetCurrentEnv(env);
*t = JavaCallLong(env, "getApkUpdateTime", "()J", NULL);
return 0;
}

cc_result Updater_Start(const char** action) { *action = "Updating game"; return ERR_NOT_SUPPORTED; }
cc_result Updater_MarkExecutable(void) { return 0; }
cc_result Updater_SetNewBuildTime(cc_uint64 t) { return ERR_NOT_SUPPORTED; }


/*########################################################################################################################*
*--------------------------------------------------------Platform---------------------------------------------------------*
*#########################################################################################################################*/
void Platform_ShareScreenshot(const cc_string* filename) {
cc_string path; char pathBuffer[FILENAME_SIZE];
String_InitArray(path, pathBuffer);

JavaCall_String_String("shareScreenshot", filename, &path);
if (!path.length) return;

Chat_AddRaw("&cError sharing screenshot");
Chat_Add1(" &c%s", &path);
}


/*########################################################################################################################*
*-----------------------------------------------------Configuration-------------------------------------------------------*
*#########################################################################################################################*/
int Platform_GetCommandLineArgs(int argc, STRING_REF char** argv, cc_string* args) {
int count = 0;
if (gameArgs.length) {
count = String_UNSAFE_Split(&gameArgs, ' ', args, GAME_MAX_CMDARGS);
/* clear arguments so after game is closed, launcher is started */
gameArgs.length = 0;
}
return count;
}

cc_result Platform_SetDefaultCurrentDirectory(int argc, char **argv) {
cc_string dir; char dirBuffer[FILENAME_SIZE + 1];
String_InitArray_NT(dir, dirBuffer);

JavaCall_Void_String("getExternalAppDir", &dir);
dir.buffer[dir.length] = '\0';
Platform_Log1("EXTERNAL DIR: %s|", &dir);
return chdir(dir.buffer) == -1 ? errno : 0;
}


/*########################################################################################################################*
*-----------------------------------------------------Java Interop--------------------------------------------------------*
*#########################################################################################################################*/
jclass App_Class;
jobject App_Instance;
JavaVM* VM_Ptr;

/* JNI helpers */
cc_string JavaGetString(JNIEnv* env, jstring str, char* buffer) {
const char* src; int len;
cc_string dst;
src = (*env)->GetStringUTFChars(env, str, NULL);
len = (*env)->GetStringUTFLength(env, str);

dst.buffer = buffer;
dst.length = 0;
dst.capacity = NATIVE_STR_LEN;
String_AppendUtf8(&dst, src, len);

(*env)->ReleaseStringUTFChars(env, str, src);
return dst;
}

jobject JavaMakeString(JNIEnv* env, const cc_string* str) {
cc_uint8 tmp[2048 + 4];
cc_uint8* cur;
int i, len = 0;

for (i = 0; i < str->length && len < 2048; i++) {
cur = tmp + len;
len += Convert_CP437ToUtf8(str->buffer[i], cur);
}
tmp[len] = '\0';
return (*env)->NewStringUTF(env, (const char*)tmp);
}

jbyteArray JavaMakeBytes(JNIEnv* env, const void* src, cc_uint32 len) {
if (!len) return NULL;
jbyteArray arr = (*env)->NewByteArray(env, len);
(*env)->SetByteArrayRegion(env, arr, 0, len, src);
return arr;
}

void JavaCallVoid(JNIEnv* env, const char* name, const char* sig, jvalue* args) {
jmethodID method = (*env)->GetMethodID(env, App_Class, name, sig);
(*env)->CallVoidMethodA(env, App_Instance, method, args);
}

jlong JavaCallLong(JNIEnv* env, const char* name, const char* sig, jvalue* args) {
jmethodID method = (*env)->GetMethodID(env, App_Class, name, sig);
return (*env)->CallLongMethodA(env, App_Instance, method, args);
}

jobject JavaCallObject(JNIEnv* env, const char* name, const char* sig, jvalue* args) {
jmethodID method = (*env)->GetMethodID(env, App_Class, name, sig);
return (*env)->CallObjectMethodA(env, App_Instance, method, args);
}

void JavaCall_String_Void(const char* name, const cc_string* value) {
JNIEnv* env;
jvalue args[1];
JavaGetCurrentEnv(env);

args[0].l = JavaMakeString(env, value);
JavaCallVoid(env, name, "(Ljava/lang/String;)V", args);
(*env)->DeleteLocalRef(env, args[0].l);
}

static void ReturnString(JNIEnv* env, jobject obj, cc_string* dst) {
const jchar* src;
jsize len;
if (!obj) return;

src = (*env)->GetStringChars(env, obj, NULL);
len = (*env)->GetStringLength(env, obj);
String_AppendUtf16(dst, src, len * 2);
(*env)->ReleaseStringChars(env, obj, src);
(*env)->DeleteLocalRef(env, obj);
}

void JavaCall_Void_String(const char* name, cc_string* dst) {
JNIEnv* env;
jobject obj;
JavaGetCurrentEnv(env);

obj = JavaCallObject(env, name, "()Ljava/lang/String;", NULL);
ReturnString(env, obj, dst);
}

void JavaCall_String_String(const char* name, const cc_string* arg, cc_string* dst) {
JNIEnv* env;
jobject obj;
jvalue args[1];
JavaGetCurrentEnv(env);

args[0].l = JavaMakeString(env, arg);
obj = JavaCallObject(env, name, "(Ljava/lang/String;)Ljava/lang/String;", args);
ReturnString(env, obj, dst);
(*env)->DeleteLocalRef(env, args[0].l);
}
#endif

0 comments on commit d1f9797

Please sign in to comment.