raze-gles/polymer/eduke32/source/android/android-jni.cpp

766 lines
24 KiB
C++
Raw Normal View History

//-------------------------------------------------------------------------
/*
Copyright (C) 2015 EDuke32 developers and contributors
Copyright (C) 2015 Voidpoint, LLC
This file is part of EDuke32.
EDuke32 is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License version 2
as published by the Free Software Foundation.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
//-------------------------------------------------------------------------
#include <jni.h>
#include <android/log.h>
#include "SDL_scancode.h"
#include "SDL_main.h"
#include "TouchControlsContainer.h"
#include "JNITouchControlsUtils.h"
using namespace touchcontrols;
extern "C" {
#define DEFAULT_FADE_FRAMES 10
#include "in_android.h"
#include "function.h"
enum dukeinv_t
{
GET_STEROIDS, // 0
GET_SHIELD,
GET_SCUBA,
GET_HOLODUKE,
GET_JETPACK,
GET_DUMMY1, // 5
GET_ACCESS,
GET_HEATS,
GET_DUMMY2,
GET_FIRSTAID,
GET_BOOTS, // 10
GET_MAX
};
#ifndef LOGI
#define LOGI(...) ((void)__android_log_print(ANDROID_LOG_INFO, "DUKE", __VA_ARGS__))
#define LOGW(...) ((void)__android_log_print(ANDROID_LOG_WARN, "DUKE", __VA_ARGS__))
#define LOGE(...) ((void)__android_log_print(ANDROID_LOG_ERROR, "DUKE", __VA_ARGS__))
#endif
droidsysinfo_t droidinfo;
static bool hideTouchControls = true;
static bool hasTouch = false;
static bool weaponWheelVisible = false;
static bool hwScaling = false;
static bool controlsCreated = false;
static bool backButtonEnabled = true;
TouchControlsContainer controlsContainer;
TouchControls *tcBlankTap;
TouchControls *tcYesNo;
TouchControls *tcMenuMain;
TouchControls *tcBackButton;
TouchControls *tcGameMain;
TouchControls *tcGameWeapons;
TouchControls *tcAutomap;
TouchStick *touchJoyLeft;
WheelSelect *weaponWheel;
extern JNIEnv *env_;
JavaVM *jvm_;
Button *inv_buttons[GET_MAX];
std::string obbPath, gamePath;
void AndroidPreDrawButtons()
{
glPushMatrix();
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrthof(0, droidinfo.screen_width, droidinfo.screen_height, 0, 0, 1);
// glClearColor(1.0f, 1.0f, 0.0f, 1.0f);
// glClear(GL_COLOR_BUFFER_BIT);
// LOGI("AndroidPreDrawButtons");
glDisable(GL_ALPHA_TEST);
glDisable(GL_DEPTH_TEST);
glDisable(GL_FOG);
glEnable(GL_TEXTURE_2D);
glEnable(GL_BLEND);
glColor4f(1, 1, 1, 1);
glDisableClientState(GL_COLOR_ARRAY);
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glDisable(GL_CULL_FACE);
glMatrixMode(GL_MODELVIEW);
}
void AndroidPostDrawButtons()
{
glPopMatrix();
}
void AndroidShowWheel(bool show)
{
if (!controlsCreated)
return;
if (show)
{
for (int n = 0; n < 10; n++)
weaponWheel->setSegmentEnabled(n, (AndroidRead(R_PLAYER_GOTWEAPON) >> n) & 0x1);
// Show inventory buttons
tcGameWeapons->setAllButtonsEnabled(true);
tcGameWeapons->fade(FADE_IN, 5);
weaponWheelVisible = true;
AndroidTimer(0);
}
else // hide
{
tcGameWeapons->setAllButtonsEnabled(false);
weaponWheel->setTapMode(false);
weaponWheelVisible = false;
AndroidTimer(120);
}
}
void AndroidShowKeyboard(int onf)
{
JNI_ShowKeyboard(onf);
}
namespace callbacks
{
void in_game(int state, int code)
{
if (!controlsCreated)
return;
switch (code)
{
case gamefunc_Fire:
if (state && AndroidRead(R_SOMETHINGONPLAYER))
{
AndroidAction(1, gamefunc_Quick_Kick);
AndroidAction(0, gamefunc_Quick_Kick);
}
else AndroidAction(state, code);
break;
case KEY_SHOW_KBRD:
if (state)
JNI_ToggleKeyboard();
AndroidKeyEvent(state, SDL_SCANCODE_GRAVE, 0);
break;
case KEY_QUICK_CMD:
if (state == 1)
JNI_ShowCustomCommands();
break;
case KEY_SHOW_INVEN:
if (state)
{
if (!weaponWheelVisible)
{
weaponWheel->setTapMode(true);
AndroidShowWheel(true);
}
else
{
AndroidShowWheel(false);
}
}
break;
case KEY_QUICK_SAVE:
LOGI("QUICK SAVE");
AndroidKeyEvent(state, SDL_SCANCODE_F6, 0);
break;
case KEY_QUICK_LOAD:
LOGI("QUICK LOAD");
AndroidKeyEvent(state, SDL_SCANCODE_F9, 0);
break;
default: AndroidAction(state, code); break;
}
}
void inv_button(int state, int code)
{
AndroidAction(state, code);
if (state == 0)
{
// Inventory chosen, hide them and wheel
AndroidShowWheel(false);
}
}
void menu_button(int state, int code)
{
AndroidKeyEvent(state, code, code);
if (controlsContainer.editingControls)
controlsContainer.editorButtonPress();
}
void menu_select(int action, float x, float y, float dx, float dy)
{
AndroidMouseMenu(x * droidinfo.screen_width, y * droidinfo.screen_height);
if (action == MULTITOUCHMOUSE_DOWN || action == MULTITOUCHMOUSE_UP)
AndroidMouseMenuButton(action == MULTITOUCHMOUSE_DOWN, 0);
}
void proceed(int state, int code)
{
if (AndroidRead(R_PLAYER_DEAD_FLAG))
{
if (state)
{
AndroidAction(1, gamefunc_Open);
AndroidAction(0, gamefunc_Open);
}
}
else
AndroidKeyEvent(state, SDL_SCANCODE_RETURN, 0);
}
void show_wheel(int enabled) { AndroidShowWheel(enabled ? true : false); }
void select_weapon(int segment)
{
// LOGI("weaponWheel %d",segment);
if (segment == -1 && droidinput.quickSelectWeapon)
segment = AndroidRead(R_PLAYER_LASTWEAPON);
if (segment != -1)
AndroidAction(2, gamefunc_Weapon_1 + segment);
}
void left_double_tap(int state)
{
// LOGI("L double %d, droidinput.left_double_action = %d",state,droidinput.left_double_action);
if (droidinput.left_double_action != -1)
AndroidAction(state, droidinput.left_double_action);
}
void right_double_tap(int state)
{
// LOGTOUCH("R double %d",state);
if (droidinput.right_double_action != -1)
AndroidAction(state, droidinput.right_double_action);
}
void look(int action, float x, float y, float dx, float dy)
{
// LOGI(" mouse dx = %f, dy = %f",dx,dy);
if (weaponWheelVisible)
return;
float const scale = .1f;
AndroidLook(dx * droidinput.yaw_sens * scale, -dy * droidinput.pitch_sens * scale * (droidinput.invertLook ? -1.f : 1.f));
}
void automap_multitouch_mouse_move(int action, float x, float y, float dx, float dy)
{
if (action == MULTITOUCHMOUSE_MOVE)
AndroidAutomapControl(0, dx, dy);
else if (action == MULTITOUCHMOUSE_ZOOM)
AndroidAutomapControl(x, 0, 0);
}
void move(float joy_x, float joy_y, float mouse_x, float mouse_y)
{
// LOGI("left_stick joy_x = %f, joy_y = %f",joy_x,joy_y);
AndroidMove(joy_y * droidinput.forward_sens, -joy_x * droidinput.strafe_sens);
}
}
void AndroidToggleButtonEditor(void)
{
controlsContainer.editorButtonPress();
}
void AndroidTouchInit(int width, int height, const char *graphics_path)
{
GLScaleWidth = (float)width;
GLScaleHeight = (float)-height;
ScaleY = nearbyintf(((float) height/(float) width) * ScaleX);
LOGI("initControls %d x %d,x path = %s", width, height, graphics_path);
if (controlsCreated)
return;
LOGI("creating controls");
setGraphicsBasePath(graphics_path);
controlsContainer.pre_draw.connect(sigc::ptr_fun(&AndroidPreDrawButtons));
controlsContainer.post_draw.connect(sigc::ptr_fun(&AndroidPostDrawButtons));
tcBlankTap = new TouchControls("blank_tap", false, false);
tcYesNo = new TouchControls("yes_no", false, false);
tcMenuMain = new TouchControls("menu", false, false);
tcBackButton = new TouchControls("back", false, false);
tcGameMain = new TouchControls("game", false, true, 1);
tcGameWeapons = new TouchControls("weapons", false, false);
tcAutomap = new TouchControls("automap", false, false);
///////////////////////// BLANK TAP SCREEN //////////////////////
// One button on whole screen with no graphic, send a return key
tcBlankTap->addControl(new Button("whole_screen", RectF(0, 0, 26, 16), "", SDL_SCANCODE_RETURN));
tcBlankTap->signal_button.connect(sigc::ptr_fun(&callbacks::proceed));
///////////////////////// YES NO SCREEN /////////////////////
tcYesNo->addControl(new Button("enter", RectF(16, 9, 18, 11), "yes", SDL_SCANCODE_RETURN));
tcYesNo->addControl(new Button("esc", RectF(8, 9, 10, 11), "no", SDL_SCANCODE_ESCAPE));
tcYesNo->signal_button.connect(sigc::ptr_fun(&callbacks::menu_button));
// menu and shared back button
MultitouchMouse *mouseMenu = new MultitouchMouse("mouse", RectF(0, 0, 26, 16), "");
mouseMenu->signal_action.connect(sigc::ptr_fun(&callbacks::menu_select));
mouseMenu->setHideGraphics(true);
tcMenuMain->addControl(mouseMenu);
Button *console_button = new Button("keyboard", "Development console", RectF(8, 0, 10, 2), "keyboard", KEY_SHOW_KBRD, false, true);
tcMenuMain->addControl(console_button);
tcBackButton->addControl(new Button("menu_back", RectF(0, 0, 2, 2), "arrow_left", SDL_SCANCODE_ESCAPE));
tcBackButton->signal_button.connect(sigc::ptr_fun(&callbacks::menu_button));
// main controls
tcGameMain->setAlpha(droidinput.gameControlsAlpha);
tcGameMain->addControl(new Button("use", RectF(20, 4, 23, 7), "use", gamefunc_Open));
tcGameMain->addControl(new Button("fire", RectF(20, 7, 23, 10), "fire2", gamefunc_Fire));
tcGameMain->addControl(new Button("jump", RectF(23, 6, 26, 9), "jump", gamefunc_Jump));
tcGameMain->addControl(new Button("crouch", RectF(24, 12, 26, 14), "crouch", gamefunc_Crouch));
tcGameMain->addControl(new Button("kick", "Mighty Foot", RectF(23, 3, 26, 6), "boot", gamefunc_Quick_Kick, false, true));
Button *map_button = new Button("map", "Overhead map", RectF(6, 0, 8, 2), "map", gamefunc_Map, false, true);
tcGameMain->addControl(map_button);
Button *inv_button = new Button("show_inventory", "Inventory", RectF(24, 0, 26, 2), "inv", KEY_SHOW_INVEN);
tcGameMain->addControl(inv_button);
tcGameMain->addControl(new Button("next_weapon", "Next weapon", RectF(0, 3, 3, 5), "next_weap", gamefunc_Next_Weapon, false, true));
tcGameMain->addControl(new Button("prev_weapon", "Previous weapon", RectF(0, 5, 3, 7), "prev_weap", gamefunc_Previous_Weapon, false, true));
tcGameMain->addControl(new Button("quick_save", "Save game", RectF(22, 0, 24, 2), "save", KEY_QUICK_SAVE, false, true));
tcGameMain->addControl(new Button("quick_load", "Load game", RectF(20, 0, 22, 2), "load", KEY_QUICK_LOAD, false, true));
tcGameMain->addControl(console_button);
// Left stick
touchJoyLeft = new TouchStick("stick", RectF(0, 7, 8, 16), "strafe_arrow");
tcGameMain->addControl(touchJoyLeft);
touchJoyLeft->signal_move.connect(sigc::ptr_fun(&callbacks::move));
touchJoyLeft->signal_double_tap.connect(sigc::ptr_fun(&callbacks::left_double_tap));
// Mouse look for whole screen
Mouse *mouse = new Mouse("mouse", RectF(3, 0, 26, 16), "");
mouse->signal_action.connect(sigc::ptr_fun(&callbacks::look));
mouse->signal_double_tap.connect(sigc::ptr_fun(&callbacks::right_double_tap));
mouse->setHideGraphics(true);
tcGameMain->addControl(mouse);
tcGameMain->signal_button.connect(sigc::ptr_fun(&callbacks::in_game));
// Automap
MultitouchMouse *multimouse = new MultitouchMouse("gamemouse", RectF(0, 0, 26, 16), "");
multimouse->setHideGraphics(true);
tcAutomap->addControl(multimouse);
multimouse->signal_action.connect(sigc::ptr_fun(&callbacks::automap_multitouch_mouse_move));
tcAutomap->addControl(map_button);
tcAutomap->signal_button.connect(sigc::ptr_fun(&callbacks::in_game));
tcAutomap->setAlpha(0.5);
// Now inventory in the weapons control group!
inv_buttons[GET_JETPACK] = new Button("jetpack", RectF(0, 3, 2, 5), "jetpack", gamefunc_Jetpack, false, false, true);
inv_buttons[GET_FIRSTAID] = new Button("medkit", RectF(0, 5, 2, 7), "medkit", gamefunc_MedKit, false, false, true);
inv_buttons[GET_HEATS] = new Button("nightv", RectF(0, 7, 2, 9), "nightvision", gamefunc_NightVision, false, false, true);
inv_buttons[GET_HOLODUKE] = new Button("holoduke", RectF(0, 9, 2, 11), "holoduke", gamefunc_Holo_Duke, false, false, true);
inv_buttons[GET_STEROIDS] = new Button("steroids", RectF(0, 11, 2, 13), "steroids", gamefunc_Steroids, false, false, true);
tcGameWeapons->addControl(inv_buttons[GET_JETPACK]);
tcGameWeapons->addControl(inv_buttons[GET_FIRSTAID]);
tcGameWeapons->addControl(inv_buttons[GET_HEATS]);
tcGameWeapons->addControl(inv_buttons[GET_HOLODUKE]);
tcGameWeapons->addControl(inv_buttons[GET_STEROIDS]);
// tcGameWeapons->addControl(inv_button);
// Inventory are the only buttons so safe to do this
tcGameWeapons->signal_button.connect(sigc::ptr_fun(&callbacks::inv_button));
// Weapons
weaponWheel = new WheelSelect("weapon_wheel", RectF(7, 2, 19, 14), "weapon_wheel_orange_blank", 10);
weaponWheel->signal_selected.connect(sigc::ptr_fun(&callbacks::select_weapon));
weaponWheel->signal_enabled.connect(sigc::ptr_fun(&callbacks::show_wheel));
tcGameWeapons->addControl(weaponWheel);
tcGameWeapons->setAlpha(0.9);
controlsContainer.addControlGroup(tcMenuMain);
controlsContainer.addControlGroup(tcBackButton);
controlsContainer.addControlGroup(tcGameMain);
controlsContainer.addControlGroup(tcGameWeapons);
controlsContainer.addControlGroup(tcAutomap);
controlsContainer.addControlGroup(tcYesNo);
controlsContainer.addControlGroup(tcBlankTap);
tcGameMain->setAlpha(droidinput.gameControlsAlpha);
tcGameWeapons->setAlpha(droidinput.gameControlsAlpha);
tcMenuMain->setAlpha(droidinput.gameControlsAlpha);
tcBackButton->setAlpha(droidinput.gameControlsAlpha);
tcGameMain->setXMLFile(gamePath + "/control_layout_main.xml");
tcGameWeapons->setXMLFile(gamePath + "/control_layout_weapons.xml");
tcAutomap->setXMLFile(gamePath + "/control_layout_automap.xml");
setControlsContainer(&controlsContainer);
controlsCreated = true;
}
void updateTouchScreenMode(touchscreemode_t mode)
{
// LOGI("updateTouchScreenModeA %d",mode);
if (!controlsCreated)
return;
static touchscreemode_t lastMode = TOUCH_SCREEN_BLANK;
if (mode != lastMode)
{
// first disable the last screen and fade out is necessary
switch (lastMode)
{
case TOUCH_SCREEN_BLANK: // Does not exist yet break;
case TOUCH_SCREEN_BLANK_TAP:
tcBlankTap->resetOutput();
tcBlankTap->setEnabled(false); // Dont fade out as no graphics
break;
case TOUCH_SCREEN_YES_NO:
tcYesNo->resetOutput();
tcYesNo->setEnabled(false);
break;
case TOUCH_SCREEN_MENU_NOBACK:
tcBackButton->fade(FADE_IN, DEFAULT_FADE_FRAMES);
case TOUCH_SCREEN_MENU:
tcMenuMain->resetOutput();
tcMenuMain->fade(FADE_OUT, DEFAULT_FADE_FRAMES);
break;
case TOUCH_SCREEN_GAME:
tcGameMain->resetOutput();
tcGameMain->fade(FADE_OUT, DEFAULT_FADE_FRAMES);
tcGameWeapons->setEnabled(false);
break;
case TOUCH_SCREEN_AUTOMAP:
tcAutomap->resetOutput();
tcAutomap->fade(FADE_OUT, DEFAULT_FADE_FRAMES);
break;
case TOUCH_SCREEN_CONSOLE: break;
}
// Enable the current new screen
switch (mode)
{
case TOUCH_SCREEN_BLANK: // Does not exist yet break;
case TOUCH_SCREEN_BLANK_TAP: tcBlankTap->setEnabled(true); break;
case TOUCH_SCREEN_YES_NO:
tcYesNo->setEnabled(true);
tcYesNo->fade(FADE_IN, DEFAULT_FADE_FRAMES);
break;
case TOUCH_SCREEN_MENU_NOBACK:
tcBackButton->fade(FADE_OUT, DEFAULT_FADE_FRAMES);
case TOUCH_SCREEN_MENU:
tcMenuMain->setEnabled(true);
tcMenuMain->fade(FADE_IN, DEFAULT_FADE_FRAMES);
// This is a bit of a hack, we need to enable the inventory buttons so they can be edited, they will not
// be seen anyway
break;
case TOUCH_SCREEN_GAME:
tcGameMain->setEnabled(true);
tcGameMain->fade(FADE_IN, DEFAULT_FADE_FRAMES);
tcGameWeapons->setEnabled(true);
break;
case TOUCH_SCREEN_AUTOMAP:
tcAutomap->setEnabled(true);
tcAutomap->fade(FADE_IN, DEFAULT_FADE_FRAMES);
break;
case TOUCH_SCREEN_CONSOLE: break;
}
lastMode = mode;
}
int inv = AndroidRead(R_PLAYER_INV_AMOUNT);
for (int i = 0; i < GET_MAX; ++i)
if (inv_buttons[i])
inv_buttons[i]->setAlpha(tcGameWeapons->getFadedAlpha() * ((inv & (1 << i)) ? 1.f : 0.3f));
backButtonEnabled = !tcBlankTap->enabled && mode != TOUCH_SCREEN_MENU_NOBACK;
tcBackButton->setEnabled(backButtonEnabled);
}
extern char videomodereset;
void AndroidDrawControls()
{
static int loadedGLImages = 0;
if (videomodereset)
{
loadedGLImages = -1;
return;
}
// We need to do this here now because duke loads a new gl context
if (loadedGLImages <= 0)
{
controlsContainer.initGL(loadedGLImages == -1);
loadedGLImages = 1;
}
// LOGI("AndroidDrawControls");
if (!controlsCreated)
return;
updateTouchScreenMode((touchscreemode_t)AndroidRead(R_TOUCH_MODE));
if (touchJoyLeft)
touchJoyLeft->setHideGraphics(droidinput.hideStick);
if (tcGameMain)
tcGameMain->setAlpha(droidinput.gameControlsAlpha);
if (tcGameWeapons)
tcGameWeapons->setAlpha(droidinput.gameControlsAlpha);
if (tcMenuMain)
tcMenuMain->setAlpha(droidinput.gameControlsAlpha);
if (tcBackButton)
tcBackButton->setAlpha(droidinput.gameControlsAlpha);
controlsContainer.draw();
if (controlsContainer.editingControls)
tcBackButton->draw();
}
#define EXPORT_ME __NDK_FPABI__ __attribute__((visibility("default")))
JNIEnv *env_;
int argc = 1;
const char *argv[32];
static inline const char *getGamePath() { return gamePath.c_str(); }
jint EXPORT_ME Java_com_voidpoint_duke3d_engine_NativeLib_init(JNIEnv *env, jobject thiz, jstring graphics_dir,
jint audio_rate, jint audio_buffer_size,
jobjectArray argsArray,
jstring jduke3d_path)
{
env_ = env;
droidinfo.audio_sample_rate = audio_rate;
droidinfo.audio_buffer_size = audio_buffer_size;
argv[0] = "eduke32";
int argCount = (env)->GetArrayLength(argsArray);
LOGI("argCount = %d", argCount);
for (int i = 0; i < argCount; i++)
{
jstring string = (jstring)(env)->GetObjectArrayElement(argsArray, i);
argv[argc] = (char *)(env)->GetStringUTFChars(string, 0);
LOGI("arg = %s", argv[argc]);
argc++;
}
gamePath = std::string(env->GetStringUTFChars(jduke3d_path, NULL));
// Change working dir, save games etc
// FIXME: potentially conflicts with chdirs in -game_dir support
chdir(getGamePath());
LOGI("duke3d_path = %s", getGamePath());
const char *p = env->GetStringUTFChars(graphics_dir, NULL);
obbPath = std::string(p);
LOGI("obbPath = %s", obbPath.c_str());
if (hasTouch)
AndroidTouchInit(droidinfo.screen_width, droidinfo.screen_height, (obbPath + "/assets/").c_str());
else LOGI("skipping touch input");
main(argc, (char **)argv);
return 0;
}
__attribute__((visibility("default"))) jint JNI_OnLoad(JavaVM *vm, void *reserved)
{
LOGI("JNI_OnLoad");
setTCJNIEnv(vm);
jvm_ = vm;
return JNI_VERSION_1_4;
}
void EXPORT_ME
Java_com_voidpoint_duke3d_engine_NativeLib_keyPress(JNIEnv *env, jobject obj, jint down, jint keycode, jint unicode)
{
LOGI("keypress %d", keycode);
if (controlsContainer.isEditing())
{
if (down && (keycode == SDL_SCANCODE_ESCAPE))
controlsContainer.finishEditing();
return;
}
AndroidKeyEvent(down, keycode, unicode);
}
void EXPORT_ME Java_com_voidpoint_duke3d_engine_NativeLib_touchEvent(JNIEnv *env, jobject obj, jint action, jint pid,
jfloat x, jfloat y)
{
if (tcBackButton && backButtonEnabled)
tcBackButton->processPointer(action, pid, x, y);
// LOGI("TOUCHED");
controlsContainer.processPointer(action, pid, x, y);
}
void EXPORT_ME Java_com_voidpoint_duke3d_engine_NativeLib_doAction(JNIEnv *env, jobject obj, jint state, jint action)
{
LOGI("doAction %d %d", state, action);
// gamepadButtonPressed();
if (controlsCreated && hideTouchControls && tcGameMain)
{
if (tcGameMain->isEnabled())
tcGameMain->setEnabled(false);
if (tcGameWeapons && tcGameWeapons->isEnabled())
tcGameWeapons->setEnabled(false);
}
AndroidAction(state, action);
}
void EXPORT_ME Java_com_voidpoint_duke3d_engine_NativeLib_analogMove(JNIEnv *env, jobject obj, jfloat fwd, jfloat strafe)
{
AndroidMove(fwd, strafe);
}
void EXPORT_ME Java_com_voidpoint_duke3d_engine_NativeLib_analogLook(JNIEnv *env, jobject obj, jfloat pitch, jfloat yaw)
{
AndroidLookJoystick(yaw, pitch);
}
void EXPORT_ME
Java_com_voidpoint_duke3d_engine_NativeLib_setTouchSettings(JNIEnv *env, jobject obj, int other)
{
// TODO: defined names for these values
hasTouch = other & 0x4000 ? true : false;
hideTouchControls = other & 0x8000 ? true : false;
hwScaling = other & 0x10000 ? true : false;
// keep in sync with Duke3d/res/values/strings.xml
int doubletap_options[4] ={ -1, gamefunc_Quick_Kick, gamefunc_MedKit, gamefunc_Jetpack };
droidinput.left_double_action = doubletap_options[((other >> 4) & 0xF)];
droidinput.right_double_action = doubletap_options[((other >> 8) & 0xF)];
LOGI("setTouchSettings left_double_action = %d", droidinput.left_double_action);
}
void EXPORT_ME Java_com_voidpoint_duke3d_engine_NativeLib_resetTouchSettings(JNIEnv *env, jobject obj)
{
controlsContainer.resetDefaults();
}
std::string quickCommandString;
jint EXPORT_ME Java_com_voidpoint_duke3d_engine_NativeLib_quickCommand(JNIEnv *env, jobject obj, jstring command)
{
const char *p = env->GetStringUTFChars(command, NULL);
quickCommandString = std::string(p) + "\n";
env->ReleaseStringUTFChars(command, p);
AndroidOSD(quickCommandString.c_str());
}
void EXPORT_ME
Java_com_voidpoint_duke3d_engine_NativeLib_setScreenSize(JNIEnv *env, jobject thiz, jint width, jint height)
{
droidinfo.screen_width = width;
droidinfo.screen_height = height;
}
extern void SDL_Android_Init(JNIEnv *env, jclass cls);
void EXPORT_ME Java_org_libsdl_app_SDLActivity_nativeInit(JNIEnv *env, jclass cls)
{
/* This interface could expand with ABI negotiation, calbacks, etc. */
SDL_Android_Init(env, cls);
SDL_SetMainReady();
// SDL_EventState(SDL_TEXTINPUT,SDL_ENABLE);
}
}