Commit 7c69e0e2 authored by kenan's avatar kenan

Merge remote-tracking branch 'remotes/origin/dev_click'

parents aae7778f 41899a59
......@@ -179,13 +179,13 @@ void DeckBuilder::Terminate() {
if(catesel >= 0)
BufferIO::CopyWStr(mainGame->cbDBCategory->getItem(catesel), mainGame->gameConf.lastcategory, 64);
BufferIO::EncodeUTF8(mainGame->gameConf.lastcategory, linebuf);
android::setLastCategory(mainGame->appMain, linebuf);
mainGame->setLastCategory(linebuf);
//irr:os::Printer::log("setLastCategory", linebuf);
int decksel = mainGame->cbDBDecks->getSelected();
if(decksel >= 0)
BufferIO::CopyWStr(mainGame->cbDBDecks->getItem(decksel), mainGame->gameConf.lastdeck, 64);
BufferIO::EncodeUTF8(mainGame->gameConf.lastdeck, linebuf);
android::setLastDeck(mainGame->appMain, linebuf);
mainGame->setLastDeck(linebuf);
//os::Printer::log("setLastDeck", linebuf);
mainGame->SaveConfig();
if(exit_on_return)
......@@ -1116,10 +1116,8 @@ bool DeckBuilder::OnEvent(const irr::SEvent& event) {
s32 y = event.MouseInput.Y;
irr::core::position2di pos(x, y);
if (x < (200 * mainGame->xScale) && y < (270 * mainGame->yScale)) {
mainGame->gMutex.lock();
mainGame->textFont->setTransparency(true);
mainGame->refreshTexture();
mainGame->ClearChatMsg();
mainGame->gMutex.unlock();
break;
}//touch the pic of detail to refresh textfonts
is_starting_dragging = false;
......
......@@ -3925,7 +3925,7 @@ void DuelClient::BeginRefreshHost() {
event_base* broadev = event_base_new();
#ifdef _IRR_ANDROID_PLATFORM_
//get local ip address in android style
int ipaddr = android::getLocalAddr(mainGame->appMain);
int ipaddr = mainGame->getLocalAddr();
if (ipaddr == -1) {
return;
}
......
......@@ -1053,10 +1053,8 @@ bool ClientField::OnEvent(const irr::SEvent& event) {
hovered_location = 0;
irr::core::position2di pos(x, y);
if (x < (200 * mainGame->xScale) && y < (270 * mainGame->yScale)) {
mainGame->gMutex.lock();
mainGame->textFont->setTransparency(true);
mainGame->refreshTexture();
mainGame->ClearChatMsg();
mainGame->gMutex.unlock();
break;
}//touch the pic of detail to refresh textfonts
if(x < 300 * mainGame->xScale)
......@@ -1927,14 +1925,14 @@ bool ClientField::OnCommonEvent(const irr::SEvent& event) {
case irr::KEY_KEY_R: {
if(mainGame->gameConf.control_mode == 0
&& !event.KeyInput.PressedDown && !mainGame->HasFocus(EGUIET_EDIT_BOX))
mainGame->textFont->setTransparency(true);
mainGame->refreshTexture();
return true;
break;
}
case irr::KEY_F9: {
if(mainGame->gameConf.control_mode == 1
&& !event.KeyInput.PressedDown && !mainGame->HasFocus(EGUIET_EDIT_BOX))
mainGame->textFont->setTransparency(true);
mainGame->refreshTexture();
return true;
break;
}
......
This diff is collapsed.
......@@ -8,6 +8,8 @@
#include <unordered_map>
#include <vector>
#include <list>
#include <android/AndroidGameHost.h>
#include <android/AndroidGameUI.h>
#include "IYGOSoundEffectPlayer.h"
namespace ygo {
......@@ -115,6 +117,7 @@ public:
#else
bool Initialize();
#endif
~Game();
void MainLoop();
void RefreshTimeDisplay();
void BuildProjectionMatrix(irr::core::matrix4& mProjection, f32 left, f32 right, f32 bottom, f32 top, f32 znear, f32 zfar);
......@@ -146,7 +149,11 @@ public:
void WaitFrameSignal(int frame);
void DrawThumb(code_pointer cp, position2di pos, std::unordered_map<int, int>* lflist);
void DrawDeckBd();
#ifdef _IRR_ANDROID_PLATFORM_
void LoadConfig(JNIEnv*env, irr::android::InitOptions* options);
#else
void LoadConfig();
#endif
void SaveConfig();
void ShowCardInfo(int code);
void ClearCardInfo(int player = 0);
......@@ -541,12 +548,34 @@ public:
s32 ogles2BlendTexture;
irr::android::CustomShaderConstantSetCallBack customShadersCallback;
Signal externalSignal;
void showAndroidComboBoxCompat(bool show, char** list, int count, int mode = 0);
void perfromHapticFeedback();
void toggleIME(bool show, char* msg);
void setLastCategory(const char* category);
void setLastDeck(const char* name);
int getLocalAddr();
void playSoundEffect(const char *name);
JNIEnv* getJniEnv();
#endif
void setPositionFix(core::position2di fix){
InputFix = fix;
void refreshTexture();
void runWindbot(const char* cmd);
io::path getCardImagePath(){
return cardImagePath;
}
io::path getResourcePath(){
return resourcePath;
}
void setPositionFix(int left, int top){
touchLeft = left;
touchTop = top;
}
float optX(float x) {
float x2 = x - InputFix.X;
float x2 = x - touchLeft;
if (x2 < 0) {
return 0;
}
......@@ -554,19 +583,24 @@ public:
}
float optY(float y) {
float y2 = y - InputFix.Y;
float y2 = y - touchTop;
if (y2 < 0) {
return 0;
}
return y2;
}
void process(irr::SEvent &event);
#ifdef _IRR_ANDROID_PLATFORM_
ygo::AndroidGameHost *gameHost;
ygo::AndroidGameUI *gameUI;
#endif
private:
core::position2di InputFix;
int touchLeft;
int touchTop;
io::path cardImagePath;
io::path resourcePath;
};
extern Game *mainGame;
}
#define CARD_IMG_WIDTH 177
......@@ -757,8 +791,8 @@ private:
#define CARD_ARTWORK_VERSIONS_OFFSET 10
#ifdef _IRR_ANDROID_PLATFORM_
#define GAME_WIDTH 1024
#define GAME_HEIGHT 640
#define GAME_WIDTH 1024.0f
#define GAME_HEIGHT 640.0f
#else
#define GAME_WIDTH 1280
#define GAME_HEIGHT 720
......
......@@ -2,19 +2,23 @@
#include "game.h"
#include "data_manager.h"
#include <event2/thread.h>
#include "android/AndroidGameHost.h"
#include "android/AndroidGameUI.h"
#include "android/YGOGameOptions.h"
int enable_log = 0;
bool exit_on_return = false;
bool bot_mode = false;
#ifdef _IRR_ANDROID_PLATFORM_
void android_main(ANDROID_APP app) {
app->inputPollSource.process = android::process_input;
app_dummy();
void android_main(ANDROID_APP app){
#else
int main(int argc, char* argv[]) {
#endif
ygo::Game* game = new ygo::Game;
ygo::mainGame = game;
#ifdef _WIN32
WORD wVersionRequested;
WSADATA wsaData;
......@@ -24,70 +28,87 @@ int main(int argc, char* argv[]) {
#else
evthread_use_pthreads();
#endif //_WIN32
ygo::Game _game;
ygo::mainGame = &_game;
#ifdef _IRR_ANDROID_PLATFORM_
if(!ygo::mainGame->Initialize(app))
LOGI("start Initialize");
if(!game->Initialize(app))
return;
#else
if(!ygo::mainGame->Initialize())
return 0;
#endif
#ifndef _IRR_ANDROID_PLATFORM_
for(int i = 1; i < argc; ++i) {
/*command line args:
* -j: join host (host info from system.conf)
* -d: deck edit
* -r: replay */
if(argv[i][0] == '-' && argv[i][1] == 'e') {
#ifdef _IRR_ANDROID_PLATFORM_
wchar_t fname[260];
MultiByteToWideChar(CP_ACP, 0, &argv[i][2], -1, fname, 260);
char fname2[260];
BufferIO::EncodeUTF8(fname, fname2);
if(ygo::dataManager.LoadDB(fname2)){
os::Printer::log("add cdb ok ", fname2);
}else{
os::Printer::log("add cdb fail ", fname2);
}
for (int i = 1; i < argc; ++i) {
/*command line args:
* -j: join host (host info from system.conf)
* -d: deck edit
* -r: replay */
if (argv[i][0] == '-' && argv[i][1] == 'e') {
ygo::dataManager.LoadDB(&argv[i][2]);
} else if (!strcmp(argv[i], "-j") || !strcmp(argv[i], "-d") || !strcmp(argv[i], "-r") ||
!strcmp(argv[i], "-s")) {
exit_on_return = true;
irr::SEvent event;
event.EventType = irr::EET_GUI_EVENT;
event.GUIEvent.EventType = irr::gui::EGET_BUTTON_CLICKED;
} else if (!strcmp(argv[i], "-c")) { // Create host
ygo::mainGame->HideElement(ygo::mainGame->wMainMenu);
event.GUIEvent.Caller = ygo::mainGame->btnJoinHost;
ygo::mainGame->device->postEventFromUser(event);
} else if (!strcmp(argv[i], "-d")) { // Join host
event.GUIEvent.Caller = ygo::mainGame->btnDeckEdit;
// ygo::mainGame->HideElement(ygo::mainGame->wMainMenu);
ygo::mainGame->device->postEventFromUser(event);
} else if (!strcmp(argv[i], "-r")) { // Replay
event.GUIEvent.Caller = ygo::mainGame->btnReplayMode;
ygo::mainGame->device->postEventFromUser(event);
ygo::mainGame->lstReplayList->setSelected(0);
event.GUIEvent.Caller = ygo::mainGame->btnLoadReplay;
ygo::mainGame->device->postEventFromUser(event);
} else if (!strcmp(argv[i], "-s")) { // Single
event.GUIEvent.Caller = ygo::mainGame->btnSingleMode;
ygo::mainGame->device->postEventFromUser(event);
ygo::mainGame->lstSinglePlayList->setSelected(0);
event.GUIEvent.Caller = ygo::mainGame->btnLoadSinglePlay;
ygo::mainGame->device->postEventFromUser(event);
}
}
#else
ygo::dataManager.LoadDB(&argv[i][2]);
#endif
} else if(!strcmp(argv[i], "-j") || !strcmp(argv[i], "-d") || !strcmp(argv[i], "-r") || !strcmp(argv[i], "-s")) {
exit_on_return = true;
irr::SEvent event;
event.EventType = irr::EET_GUI_EVENT;
event.GUIEvent.EventType = irr::gui::EGET_BUTTON_CLICKED;
} else if(!strcmp(argv[i], "-c")) { // Create host
ygo::mainGame->HideElement(ygo::mainGame->wMainMenu);
event.GUIEvent.Caller = ygo::mainGame->btnJoinHost;
ygo::mainGame->device->postEventFromUser(event);
} else if(!strcmp(argv[i], "-j")) { // Join host
event.GUIEvent.Caller = ygo::mainGame->btnDeckEdit;
// ygo::mainGame->HideElement(ygo::mainGame->wMainMenu);
ygo::mainGame->device->postEventFromUser(event);
} else if(!strcmp(argv[i], "-r")) { // Replay
event.GUIEvent.Caller = ygo::mainGame->btnReplayMode;
ygo::mainGame->device->postEventFromUser(event);
ygo::mainGame->lstReplayList->setSelected(0);
event.GUIEvent.Caller = ygo::mainGame->btnLoadReplay;
ygo::mainGame->device->postEventFromUser(event);
} else if(!strcmp(argv[i], "-s")) { // Single
event.GUIEvent.Caller = ygo::mainGame->btnSingleMode;
ygo::mainGame->device->postEventFromUser(event);
ygo::mainGame->lstSinglePlayList->setSelected(0);
event.GUIEvent.Caller = ygo::mainGame->btnLoadSinglePlay;
ygo::mainGame->device->postEventFromUser(event);
}
JNIEnv *env = android::getJniEnv(app);
irr::android::YGOGameOptions* options = ygo::mainGame->gameUI->getJoinOptions(env);
if(options != NULL){
irr::SEvent event;
wchar_t wbuff[256];
BufferIO::DecodeUTF8(options->getIPAddr(), wbuff);
game->ebJoinHost->setText(wbuff);
}
}
#endif
#ifdef _IRR_ANDROID_PLATFORM_
ygo::mainGame->externalSignal.Set();
ygo::mainGame->externalSignal.SetNoWait(true);
myswprintf(wbuff, L"%d", options->getPort());
game->ebJoinPort->setText(wbuff);
BufferIO::DecodeUTF8(options->getUserName(), wbuff);
game->ebNickName->setText(wbuff);
wmemset(wbuff, 0, 256);
bool bRoomCreate = options->formatGameParams(wbuff);
if (bRoomCreate) {
ygo::mainGame->ebJoinPass->setText(wbuff);
}
event.EventType = irr::EET_GUI_EVENT;
event.GUIEvent.EventType = irr::gui::EGET_BUTTON_CLICKED;
event.GUIEvent.Caller = ygo::mainGame->btnLanMode;
game->device->postEventFromUser(event);
usleep(500);
event.GUIEvent.Caller = ygo::mainGame->btnJoinHost;
game->device->postEventFromUser(event);
}
game->externalSignal.Set();
game->externalSignal.SetNoWait(true);
#endif
ygo::mainGame->MainLoop();
game->MainLoop();
delete game;
game = NULL;
LOGI("end game");
#ifdef _WIN32
WSACleanup();
#else
......
......@@ -200,7 +200,7 @@ irr::video::ITexture* ImageManager::GetTexture(int code) {
}
if(img == NULL) {
for (iter = support_types.begin(); iter != support_types.end(); ++iter) {
sprintf(file, "%s/%d.%s", irr::android::getCardImagePath(mainGame->appMain).c_str(), code, iter->c_str());
sprintf(file, "%s/%d.%s", mainGame->getCardImagePath().c_str(), code, iter->c_str());
img = driver->getTexture(file);
// img = GetTextureFromFile(file, width, height);
if (img != NULL) {
......@@ -261,19 +261,20 @@ irr::video::ITexture* ImageManager::GetTextureThumb(int code) {
irr::video::ITexture* ImageManager::GetTextureField(int code) {
if(code == 0)
return NULL;
const char* image_path = mainGame->getCardImagePath().c_str();
auto tit = tFields.find(code);
if(tit == tFields.end()) {
char file[256];
sprintf(file, "field/%s/%d.jpg", irr::android::getCardImagePath(mainGame->appMain).c_str(), code);
sprintf(file, "field/%s/%d.jpg", image_path, code);
irr::video::ITexture* img = driver->getTexture(file);
// irr::video::ITexture* img = GetTextureFromFile(file, 512, 512);
if(img == NULL) {
sprintf(file, "field/%s/%d.jpg", irr::android::getCardImagePath(mainGame->appMain).c_str(), code);
sprintf(file, "field/%s/%d.jpg", image_path, code);
img = driver->getTexture(file);
// img = GetTextureFromFile(file, 512, 512);
}
if(img == NULL) {
sprintf(file, "field/%s/%d.png", irr::android::getCardImagePath(mainGame->appMain).c_str(), code);
sprintf(file, "field/%s/%d.png", image_path, code);
img = driver->getTexture(file);
// img = GetTextureFromFile(file, 512, 512);
}
......
......@@ -14,11 +14,11 @@ void UpdateDeck() {
char linebuf[256];
BufferIO::CopyWStr(mainGame->cbCategorySelect->getItem(mainGame->cbCategorySelect->getSelected()), mainGame->gameConf.lastcategory, 64);
BufferIO::EncodeUTF8(mainGame->gameConf.lastcategory, linebuf);
android::setLastCategory(mainGame->appMain, linebuf);
mainGame->setLastCategory(linebuf);
BufferIO::CopyWStr(mainGame->cbDeckSelect->getItem(mainGame->cbDeckSelect->getSelected()), mainGame->gameConf.lastdeck, 64);
BufferIO::EncodeUTF8(mainGame->gameConf.lastdeck, linebuf);
android::setLastDeck(mainGame->appMain, linebuf);
mainGame->setLastDeck(linebuf);
char deckbuf[1024];
char* pdeck = deckbuf;
......@@ -372,7 +372,7 @@ bool MenuHandler::OnEvent(const irr::SEvent& event) {
char arg3[32];
sprintf(arg3, " Port=%d", mainGame->gameConf.serverport);
sprintf(args, "%s%s%s", arg1, arg2, arg3);
android::runWindbot(mainGame->appMain, args);
mainGame->runWindbot(args);
if(!NetServer::StartServer(mainGame->gameConf.serverport))
break;
if(!DuelClient::StartClient(0x7f000001, mainGame->gameConf.serverport)) {
......
......@@ -532,4 +532,5 @@ LOCAL_SRC_FILES += $(non_arm_src_files)
LOCAL_LDLIBS += -ldl
LOCAL_MODULE_TAGS := optional
LOCAL_MODULE:= libcrypto_static
#LOCAL_SHORT_COMMANDS := true
include $(BUILD_STATIC_LIBRARY)
......@@ -3,6 +3,7 @@ IRRLICHT_LIB_PATH := $(LOCAL_PATH)/../../lib/Android/$(TARGET_ARCH_ABI)
include $(CLEAR_VARS)
#LOCAL_SHORT_COMMANDS := true
LOCAL_MODULE := Irrlicht
IRRLICHT_LIB_NAME := lib$(LOCAL_MODULE).a
......
//
// Created by user on 2019/10/12.
//
#include "AndroidGameHost.h"
#include "android_tools.h"
#define CONF_LAST_DECK "lastdeck"
#define CONF_LAST_CATEGORY "lastcategory"
using namespace ygo;
AndroidGameHost::AndroidGameHost(ANDROID_APP _app) {
app = _app;
}
AndroidGameHost::~AndroidGameHost() {
app = NULL;
// JNIEnv *env = irr::android::getJniEnv(app);
// env->DeleteGlobalRef(app->activity->clazz);
}
void AndroidGameHost::initMethods(JNIEnv *env) {
jclass clazz = env->GetObjectClass(app->activity->clazz);
java_getSetting = env->GetMethodID(clazz, "getSetting",
"(Ljava/lang/String;)Ljava/lang/String;");
java_getIntSetting = env->GetMethodID(clazz, "getIntSetting", "(Ljava/lang/String;I)I");
java_saveIntSetting = env->GetMethodID(clazz, "saveIntSetting", "(Ljava/lang/String;I)V");
java_saveSetting = env->GetMethodID(clazz, "saveSetting", "(Ljava/lang/String;Ljava/lang/String;)V");
java_runWindbot = env->GetMethodID(clazz, "runWindbot", "(Ljava/lang/String;)V");
java_getLocalAddr = env->GetMethodID(clazz, "getLocalAddr", "()I");
env->DeleteLocalRef(clazz);
}
irr::io::path AndroidGameHost::getSetting(JNIEnv *env, const char *_key) {
irr::io::path ret;
if (!java_getSetting) {
return ret;
}
jstring key = env->NewStringUTF(_key);
jstring value = (jstring) env->CallObjectMethod(app->activity->clazz, java_getSetting, key);
if (key) {
env->DeleteLocalRef(key);
}
if(value != NULL) {
const char *chars = env->GetStringUTFChars(value, NULL);
ret.append(chars);
env->ReleaseStringUTFChars(value, chars);
}
return ret;
}
int AndroidGameHost::getIntSetting(JNIEnv *env, const char *_key, int defvalue) {
if (!java_getIntSetting) {
return 0;
}
jstring key = env->NewStringUTF(_key);
jint value = env->CallIntMethod(app->activity->clazz, java_getIntSetting, key, defvalue);
if (key) {
env->DeleteLocalRef(key);
}
return (int)value;
}
void AndroidGameHost::saveIntSetting(JNIEnv *env, const char *_key, int value) {
if (!java_saveIntSetting) {
return;
}
jstring key = env->NewStringUTF(_key);
env->CallVoidMethod(app->activity->clazz, java_saveIntSetting, key, value);
if (key) {
env->DeleteLocalRef(key);
}
}
void AndroidGameHost::runWindbot(JNIEnv *env, const char* _cmd) {
if (!java_runWindbot) {
return;
}
jstring cmd = env->NewStringUTF(_cmd);
env->CallVoidMethod(app->activity->clazz, java_runWindbot, cmd);
if (cmd) {
env->DeleteLocalRef(cmd);
}
}
void AndroidGameHost::saveSetting(JNIEnv *env, const char *_key, const char *_value) {
if (!java_saveSetting) {
return;
}
jstring key = env->NewStringUTF(_key);
jstring value = env->NewStringUTF(_value);
env->CallVoidMethod(app->activity->clazz, java_saveSetting, key, value);
if (key) {
env->DeleteLocalRef(key);
}
if (value) {
env->DeleteLocalRef(value);
}
}
void AndroidGameHost::setLastDeck(JNIEnv *env, const char* deckname) {
saveSetting(env, CONF_LAST_DECK, deckname);
}
void AndroidGameHost::setLastCategory(JNIEnv *env, const char* catename) {
saveSetting(env, CONF_LAST_CATEGORY, catename);
}
irr::io::path AndroidGameHost::getLastDeck(JNIEnv *env) {
return getSetting(env, CONF_LAST_DECK);
}
irr::io::path AndroidGameHost::getLastCategory(JNIEnv *env) {
return getSetting(env, CONF_LAST_CATEGORY);
}
int AndroidGameHost::getLocalAddr(JNIEnv *env) {
if (!java_getLocalAddr) {
return 0;
}
return env->CallIntMethod(app->activity->clazz, java_getLocalAddr);
}
//
// Created by user on 2019/10/12.
//
#ifndef YGOMOBILE_CN_KO_EN_ANDROIDGAMEHOST_H
#define YGOMOBILE_CN_KO_EN_ANDROIDGAMEHOST_H
#include <irrlicht.h>
#include <jni.h>
#include "android_tools.h"
namespace ygo {
class AndroidGameHost {
private:
jmethodID java_getSetting;
jmethodID java_getIntSetting;
jmethodID java_saveIntSetting;
jmethodID java_runWindbot;
jmethodID java_saveSetting;
jmethodID java_getLocalAddr;
ANDROID_APP app;
public:
AndroidGameHost(ANDROID_APP app);
//! destructor
virtual ~AndroidGameHost();
void initMethods(JNIEnv *env);
irr::io::path getLastCategory(JNIEnv *env);
irr::io::path getLastDeck(JNIEnv *env);
irr::io::path getSetting(JNIEnv *env, const char *key);
int getIntSetting(JNIEnv *env, const char *key, int defvalue);
void saveIntSetting(JNIEnv *env, const char *key, int value);
void runWindbot(JNIEnv *env, const char *cmd);
void saveSetting(JNIEnv *env, const char *_key, const char *_value);
void setLastDeck(JNIEnv *env, const char *deckname);
void setLastCategory(JNIEnv *env, const char *catename);
int getLocalAddr(JNIEnv *env);
};
}
#endif //YGOMOBILE_CN_KO_EN_ANDROIDGAMEHOST_H
//
// Created by kenan on 19-10-18.
//
#include "AndroidGameUI.h"
using namespace ygo;
AndroidGameUI::AndroidGameUI(ANDROID_APP _app) {
app = _app;
}
AndroidGameUI::~AndroidGameUI() {
app = NULL;
//JNIEnv *env = irr::android::getJniEnv(app);
//env->DeleteGlobalRef(app->activity->clazz);
}
void AndroidGameUI::initMethods(JNIEnv *env) {
jclass clazz = env->GetObjectClass(app->activity->clazz);
java_toggleIME = env->GetMethodID(clazz, "toggleIME", "(ZLjava/lang/String;)V");
java_performHapticFeedback = env->GetMethodID(clazz, "performHapticFeedback", "()V");
java_showComboBoxCompat = env->GetMethodID(clazz, "showComboBoxCompat",
"([Ljava/lang/String;ZI)V");
java_getWindowLeft = env->GetMethodID(clazz, "getWindowLeft", "()I");
java_getWindowTop = env->GetMethodID(clazz, "getWindowTop", "()I");
java_getWindowWidth = env->GetMethodID(clazz, "getWindowWidth", "()I");
java_getWindowHeight = env->GetMethodID(clazz, "getWindowHeight", "()I");
java_getInitOptions = env->GetMethodID(clazz, "getInitOptions", "()Ljava/nio/ByteBuffer;");
java_attachNativeDevice = env->GetMethodID(clazz, "attachNativeDevice", "(I)V");
java_getJoinOptions = env->GetMethodID(clazz, "getJoinOptions", "()Ljava/nio/ByteBuffer;");
java_playSoundEffect = env->GetMethodID(clazz, "playSoundEffect", "(Ljava/lang/String;)V");
env->DeleteLocalRef(clazz);
}
void AndroidGameUI::toggleIME(JNIEnv *env, bool show, const char *_msg) {
if (!java_toggleIME) {
return;
}
jstring msg = env->NewStringUTF(_msg);
env->CallVoidMethod(app->activity->clazz, java_toggleIME, (jboolean) show, msg);
if (msg) {
env->DeleteLocalRef(msg);
}
}
void AndroidGameUI::performHapticFeedback(JNIEnv *env) {
if (!java_performHapticFeedback) {
return;
}
env->CallVoidMethod(app->activity->clazz, java_performHapticFeedback);
}
void
AndroidGameUI::showAndroidComboBoxCompat(JNIEnv *env, bool pShow, char **pContents, int count,
int mode) {
if (!java_showComboBoxCompat) {
return;
}
jclass strClass = env->FindClass("java/lang/String");
jobjectArray array = env->NewObjectArray(count, strClass, 0);
jstring str;
for (int i = 0; i < count; i++) {
str = env->NewStringUTF(*(pContents + i));
env->SetObjectArrayElement(array, i, str);
}
env->CallVoidMethod(app->activity->clazz, java_showComboBoxCompat, array, (jboolean) pShow,
(jint) mode);
}
int AndroidGameUI::getWindowWidth(JNIEnv *env) {
if (!java_getWindowWidth) {
return 0;
}
return env->CallIntMethod(app->activity->clazz, java_getWindowWidth);
}
int AndroidGameUI::getWindowHeight(JNIEnv *env) {
if (!java_getWindowHeight) {
return 0;
}
return env->CallIntMethod(app->activity->clazz, java_getWindowHeight);
}
irr::android::InitOptions* AndroidGameUI::getInitOptions(JNIEnv *env) {
if (!java_getInitOptions) {
return nullptr;
}
jobject buffer = env->CallObjectMethod(app->activity->clazz, java_getInitOptions);
if(buffer) {
void *data = env->GetDirectBufferAddress(buffer);
return new irr::android::InitOptions(data);
}
LOGE("getInitOptions == null");
return NULL;
}
irr::android::YGOGameOptions* AndroidGameUI::getJoinOptions(JNIEnv *env) {
if (!java_getJoinOptions) {
return nullptr;
}
jobject buffer = env->CallObjectMethod(app->activity->clazz, java_getJoinOptions);
if(buffer) {
void *data = env->GetDirectBufferAddress(buffer);
return new irr::android::YGOGameOptions(data);
}
LOGE("getJoinOptions == null");
return NULL;
}
void AndroidGameUI::attachNativeDevice(JNIEnv*env, void* device){
if (!java_attachNativeDevice) {
LOGW("not found attachNativeDevice");
return;
}
jint value = (int)device;
LOGI("attachNativeDevice %d", value);
env->CallVoidMethod(app->activity->clazz, java_attachNativeDevice, value);
}
int AndroidGameUI::getWindowLeft(JNIEnv *env) {
if (!java_getWindowLeft) {
return 0;
}
return env->CallIntMethod(app->activity->clazz, java_getWindowLeft);
}
int AndroidGameUI::getWindowTop(JNIEnv *env) {
if (!java_getWindowTop) {
return 0;
}
return env->CallIntMethod(app->activity->clazz, java_getWindowTop);
}
void AndroidGameUI::playSoundEffect(JNIEnv *env, const char *_name) {
if (!java_playSoundEffect) {
return;
}
jstring name = env->NewStringUTF(_name);
env->CallVoidMethod(app->activity->clazz, java_playSoundEffect, name);
if (name) {
env->DeleteLocalRef(name);
}
}
\ No newline at end of file
//
// Created by kenan on 19-10-18.
//
#ifndef YGOMOBILE_CN_KO_EN_ANDROIDGAMEUI_H
#define YGOMOBILE_CN_KO_EN_ANDROIDGAMEUI_H
#include <irrlicht.h>
#include <jni.h>
#include "android_tools.h"
#include "YGOGameOptions.h"
namespace ygo {
class AndroidGameUI {
private:
jmethodID java_toggleIME;
jmethodID java_performHapticFeedback;
jmethodID java_showComboBoxCompat;
jmethodID java_getWindowLeft;
jmethodID java_getWindowTop;
jmethodID java_getWindowWidth;
jmethodID java_getWindowHeight;
jmethodID java_getInitOptions;
jmethodID java_attachNativeDevice;
jmethodID java_getJoinOptions;
jmethodID java_playSoundEffect;
ANDROID_APP app;
public:
AndroidGameUI(ANDROID_APP app);
//! destructor
virtual ~AndroidGameUI();
void initMethods(JNIEnv *env);
void toggleIME(JNIEnv *env, bool show, const char *msg);
void performHapticFeedback(JNIEnv *env);
void showAndroidComboBoxCompat(JNIEnv *env, bool pShow,
char **pContents, int count, int mode = 0);
int getWindowLeft(JNIEnv *env);
int getWindowTop(JNIEnv *env);
int getWindowWidth(JNIEnv *env);
int getWindowHeight(JNIEnv *env);
irr::android::InitOptions *getInitOptions(JNIEnv *env);
void attachNativeDevice(JNIEnv* env, void* device);
irr::android::YGOGameOptions* getJoinOptions(JNIEnv *env);
void playSoundEffect(JNIEnv *env, const char *name);
};
}
#endif //YGOMOBILE_CN_KO_EN_ANDROIDGAMEUI_H
......@@ -11,7 +11,7 @@
namespace ygo {
AndroidSoundEffectPlayer::AndroidSoundEffectPlayer(ANDROID_APP app) :
AndroidSoundEffectPlayer::AndroidSoundEffectPlayer(ANDROID_APP app) :
m_pAudioTracker(NULL), m_isEnabled(false) {
if (m_pAudioTracker == NULL) {
// m_pAudioTracker = new OpenSLSoundTracker(app->activity->assetManager);
......
......@@ -13,13 +13,13 @@
#include <android/asset_manager.h>
#include <android/asset_manager_jni.h>
#include <android_native_app_glue.h>
namespace ygo {
class AndroidSoundEffectPlayer: virtual public ygo::IYGOSoundEffectPlayer {
public:
AndroidSoundEffectPlayer(ANDROID_APP app);
virtual ~AndroidSoundEffectPlayer();
virtual void doPlayerEnterEffect();
......
......@@ -34,7 +34,7 @@ bool CAndroidGUIComboBox::OnEvent(const SEvent& event) {
BufferIO::EncodeUTF8(getItem(i), content);
*(contents + i) = content;
}
android::showAndroidComboBoxCompat(ygo::mainGame->appMain, true, contents, count);
ygo::mainGame->showAndroidComboBoxCompat(true, contents, count);
for (int i = 0; i < count; i++) {
free(*(contents + i));
}
......
......@@ -41,7 +41,7 @@ bool CAndroidGUIEditBox::OnEvent(const SEvent& event) {
inline void CAndroidGUIEditBox::toggleIME(bool pShow) {
char hint[256];
BufferIO::EncodeUTF8(getText(), hint);
android::toggleIME(ygo::mainGame->appMain, pShow, hint);
ygo::mainGame->toggleIME(pShow, hint);
}
} /* namespace gui */
......
......@@ -6,6 +6,7 @@
*/
#include "SoundPoolWrapperTracker.h"
#include "../../Classes/gframe/game.h"
namespace ygo {
......@@ -39,20 +40,9 @@ SoundPoolWrapperTracker::~SoundPoolWrapperTracker() {
void* audioPlayThread(void* param) {
SoundPoolWrapperTracker* spwt = (SoundPoolWrapperTracker*) param;
ANDROID_APP app = spwt->getMainApp();
Signal* signal = (Signal*)spwt->getPlaySignal();
JNIEnv* jni = 0;
pthread_mutex_t soundlock = spwt->getSoundLock();
std::list<irr::io::path>* sounds = (std::list<irr::io::path>*)spwt->getSounds();
app->activity->vm->AttachCurrentThread(&jni, NULL);
jobject lNativeActivity = app->activity->clazz;
jclass ClassNativeActivity = jni->GetObjectClass(lNativeActivity);
jmethodID MethodGetApp = jni->GetMethodID(ClassNativeActivity,
"getApplication", "()Landroid/app/Application;");
jobject application = jni->CallObjectMethod(lNativeActivity, MethodGetApp);
jclass classApp = jni->GetObjectClass(application);
jmethodID playSoundMethod = jni->GetMethodID(classApp, "playSoundEffect",
"(Ljava/lang/String;)V");
while (!spwt->m_isTerminated) {
signal->Wait();
if (signal->GetNoWait()) {
......@@ -63,12 +53,7 @@ void* audioPlayThread(void* param) {
if (*iter != NULL) {
const char * pathStr = (*iter).c_str();
if (pathStr != NULL && pathStr[0] != '\0') {
jstring pathString = jni->NewStringUTF((*iter).c_str());
jni->CallVoidMethod(application, playSoundMethod,
pathString);
if (pathString) {
jni->DeleteLocalRef(pathString);
}
ygo::mainGame->playSoundEffect(pathStr);
}
}
}
......@@ -76,9 +61,6 @@ void* audioPlayThread(void* param) {
pthread_mutex_unlock(&soundlock);
signal->Reset();
}
jni->DeleteLocalRef(classApp);
jni->DeleteLocalRef(ClassNativeActivity);
app->activity->vm->DetachCurrentThread();
delete signal;
return NULL;
}
......
......@@ -131,7 +131,7 @@ bool TouchEventTransferAndroid::OnTransferCommon(const SEvent& event,
transferEvent.MouseInput.ButtonStates = 0x01;
transferEvent.MouseInput.Event = EMIE_MOUSE_MOVED;
} else {
Printer::log("multitouch missed");
LOGD("multitouch missed");
return false;
}
if (ygo::mainGame->device && ygo::mainGame->device->isWindowFocused()) {
......@@ -174,7 +174,7 @@ void TouchEventTransferAndroid::set_long_click_handler(int mode) {
sev.sigev_notify_attributes = NULL;
sev.sigev_value.sival_ptr = (void*)mode;
if (timer_create(CLOCK_REALTIME, &sev, &long_press_tid) == -1) {
Printer::log("create timer failed!");
LOGD("create timer failed!");
}
/*start the timer*/
ts.it_value.tv_sec = 1;
......@@ -182,16 +182,14 @@ void TouchEventTransferAndroid::set_long_click_handler(int mode) {
ts.it_interval.tv_sec = 0;
ts.it_interval.tv_nsec = 0;
if (timer_settime(long_press_tid, 0, &ts, NULL) == -1) {
Printer::log("set timer failed!");
LOGD("set timer failed!");
}
is_timer_set = true;
}
void TouchEventTransferAndroid::long_press_handler(sigval_t info) {
int mode = (int)info.sival_ptr;
char log[256];
sprintf(log, "receve long click %d", mode);
os::Printer::log(log);
LOGD("receve long click %d", mode);
if (mode == LONG_CLICK_MODE_AS_RIGHTCLICK) {
SEvent rdownEvent, rupEvent;
rdownEvent.EventType = EET_MOUSE_INPUT_EVENT;
......@@ -204,7 +202,7 @@ void TouchEventTransferAndroid::long_press_handler(sigval_t info) {
rupEvent.MouseInput.X = s_current_x;
rupEvent.MouseInput.Y = s_current_y;
ygo::mainGame->device->postEventFromUser(rupEvent);
android::perfromHapticFeedback(ygo::mainGame->appMain);
ygo::mainGame->perfromHapticFeedback();
} else if (mode == LONG_CLICK_MODE_AS_LEFTCLICK) {
SEvent ldownEvent;
ldownEvent.EventType = EET_MOUSE_INPUT_EVENT;
......@@ -212,7 +210,7 @@ void TouchEventTransferAndroid::long_press_handler(sigval_t info) {
ldownEvent.MouseInput.X = s_current_x;
ldownEvent.MouseInput.Y = s_current_y;
ygo::mainGame->device->postEventFromUser(ldownEvent);
android::perfromHapticFeedback(ygo::mainGame->appMain);
ygo::mainGame->perfromHapticFeedback();
}
is_timer_set = false;
timer_delete(long_press_tid);
......
This diff is collapsed.
......@@ -5,12 +5,15 @@
#define __IRR_ANDROID_TOOLS_H__
#include <irrlicht.h>
#include <android_native_app_glue.h>
#include <signal.h>
#include <android/log.h>
#include <jni.h>
#define LOGI(...) ((void)__android_log_print(ANDROID_LOG_INFO, "ygomobile-native", __VA_ARGS__))
#define LOGW(...) ((void)__android_log_print(ANDROID_LOG_WARN, "ygomobile-native", __VA_ARGS__))
#define LOG_TAG "ygomobile-native"
#define LOGD(...) ((void)__android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__))
#define LOGI(...) ((void)__android_log_print(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__))
#define LOGW(...) ((void)__android_log_print(ANDROID_LOG_WARN, LOG_TAG, __VA_ARGS__))
#define LOGE(...) ((void)__android_log_print(ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__))
namespace irr {
namespace android {
......@@ -48,6 +51,15 @@ public:
inline bool isPendulumScaleEnabled() {
return m_ps_enabled;
}
inline irr::io::path getFontFile() {
return m_font_path;
}
inline irr::io::path getResourceDir() {
return m_res_path;
}
inline irr::io::path getImageDir() {
return m_image_path;
}
~InitOptions()
{
if(m_db_files != NULL){
......@@ -63,6 +75,10 @@ private:
irr::io::path m_work_dir;
irr::io::path* m_db_files;
irr::io::path* m_archive_files;
irr::io::path m_font_path;
irr::io::path m_res_path;
irr::io::path m_image_path;
int m_opengles_version;
int m_card_quality;
int cdb_count;
......@@ -72,107 +88,9 @@ private:
bool m_ps_enabled;
};
static unsigned char signed_buff[16] = { 0x30, 0x82, 0x2, 0x41, 0x30, 0x82, 0x1,
0xAA, 0xA0, 0x3, 0x2, 0x1, 0x2, 0x2, 0x4, 0x53 };
/* jni utils*/
// Get SDCard path.
extern irr::io::path getExternalStorageDir(ANDROID_APP app);
// Get SDCard path.
extern irr::io::path getExternalFilesDir(ANDROID_APP app);
// Get cache path.
extern irr::io::path getCacheDir(ANDROID_APP app);
// Get database path.
extern irr::io::path getDBDir(ANDROID_APP app);
// Get global resource path
extern irr::io::path getResourcePath(ANDROID_APP app);
// Get card image path.
extern irr::io::path getCardImagePath(ANDROID_APP app);
//Toggle IME using global window token.
extern void toggleGlobalIME(ANDROID_APP app, bool pShow);
//Toggle IME using android UI trick.
extern void toggleIME(ANDROID_APP app, bool pShow, const char* hint);
//Init Java Irrlicht world.
extern core::position2di initJavaBridge(ANDROID_APP app, void* handle);
//Cause a haptic feedback.
extern void perfromHapticFeedback(ANDROID_APP app);
//perform trick
extern bool perfromTrick(ANDROID_APP app);
//toogle overlay view
extern void toggleOverlayView(ANDROID_APP app, bool pShow);
//Retrive customized resource directory()
extern irr::io::path getCoreConfigVersion(ANDROID_APP app);
//Retrive opengl version.
extern int getOpenglVersion(ANDROID_APP app);
//Retrive init options
extern InitOptions* getInitOptions(ANDROID_APP app);
//Retrive card quality settings.
extern int getCardQuality(ANDROID_APP app);
//Retrive local ip address(mostly for wifi only);
extern int getLocalAddr(ANDROID_APP app);
extern float getXScale(ANDROID_APP app);
extern float getYScale(ANDROID_APP app);
//Retrive font path.
extern irr::io::path getFontPath(ANDROID_APP app);
//Retrive last deck name.
extern irr::io::path getLastDeck(ANDROID_APP app);
//Retrive last catagory name.
extern irr::io::path getLastCategory(ANDROID_APP app);
extern int getIntSetting(ANDROID_APP app, const char* key,int defvalue);
extern irr::io::path getSetting(ANDROID_APP app, const char* key);
//save last deck name.
extern void setLastDeck(ANDROID_APP app, const char* deckname);
//save last category name.
extern void setLastCategory(ANDROID_APP app, const char* catename);
extern void saveIntSetting(ANDROID_APP app, const char* key, int value);
extern void saveSetting(ANDROID_APP app, const char* key, const char* value);
//Retrive font antialias options
extern bool getFontAntiAlias(ANDROID_APP app);
extern bool isSoundEffectEnabled(ANDROID_APP app);
//Show Android compat gui;
extern void showAndroidComboBoxCompat(ANDROID_APP app, bool pShow,
char** pContents, int count, int mode = 0);
/* android event handlers*/
extern void process_input(ANDROID_APP app,
struct android_poll_source* source);
extern s32 handleInput(ANDROID_APP app, AInputEvent* androidEvent);
extern bool android_deck_delete(const char* deck_name);
extern void runWindbot(ANDROID_APP app, const char* args);
s32 handleInput(ANDROID_APP app, AInputEvent* androidEvent);
JNIEnv *getJniEnv(ANDROID_APP app);
}
}
......
......@@ -27,5 +27,6 @@ android {
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation "com.android.support:support-annotations:$rootProject.ext.supportVersion"
// implementation "me.weishu:free_reflection:2.1.0"
}
......@@ -47,6 +47,8 @@ LOCAL_SRC_FILES := $(LOCAL_PATH)/android/android_tools.cpp \
$(LOCAL_PATH)/android/YGOGameOptions.cpp \
$(LOCAL_PATH)/android/AndroidSoundEffectPlayer.cpp \
$(LOCAL_PATH)/android/OpenSLSoundTracker.cpp \
$(LOCAL_PATH)/android/AndroidGameHost.cpp \
$(LOCAL_PATH)/android/AndroidGameUI.cpp \
$(LOCAL_PATH)/android/SoundPoolWrapperTracker.cpp \
$(LOCAL_PATH)/../Classes/gframe/CGUIEditBox.cpp \
$(LOCAL_PATH)/../Classes/gframe/CGUIButton.cpp \
......@@ -72,7 +74,8 @@ LOCAL_SRC_FILES := $(LOCAL_PATH)/android/android_tools.cpp \
$(LOCAL_PATH)/../Classes/gframe/single_duel.cpp \
$(LOCAL_PATH)/../Classes/gframe/single_mode.cpp \
$(LOCAL_PATH)/../Classes/gframe/tag_duel.cpp \
$(LOCAL_PATH)/jni/cn_garymb_ygomobile_core_IrrlichtBridge.cpp
$(LOCAL_PATH)/jni/YGOCore.cpp \
$(LOCAL_PATH)/jni/BPG.cpp
LOCAL_LDLIBS := -lEGL -llog -lGLESv1_CM -lGLESv2 -landroid -lOpenSLES
......
APP_ABI := armeabi-v7a
#APP_ABI := armeabi-v7a
APP_PLATFORM := android-14
APP_PLATFORM := android-19
#APP_MODULES := YGOMobile
#NDK_TOOLCHAIN_VERSION=4.8
APP_ALLOW_MISSING_DEPS=true
#APP_STL := gnustl_static
APP_STL := c++_static
APP_CPPFLAGS := -Wno-error=format-security -std=gnu++11 -fpermissive -D__cplusplus=201103L
APP_OPTIM := release
#include <jni.h>
#include <malloc.h>
extern "C" {
#include "libbpg.h"
JNIEXPORT jbyteArray JNICALL Java_cn_garymb_ygomobile_core_BpgImage_nativeBpgImage(
JNIEnv *env, jclass, jbyteArray imgdata) {
jsize len = env->GetArrayLength(imgdata);
jbyte *jarr = (jbyte *) malloc(len * sizeof(jbyte));
env->GetByteArrayRegion(imgdata, 0, len, jarr);
uint8_t *data = (uint8_t *) jarr;//uint8_t 就是byte
BPGDecoderContext *img;
BPGImageInfo img_info_s, *img_info = &img_info_s;
int w, h, i, y, size, bufferIncrement, rowspan;
//加载文件
img = bpg_decoder_open();
if (bpg_decoder_decode(img, data, (int) len) < 0) {
return 0;
}
//解析信息
bpg_decoder_get_info(img, img_info);
w = img_info->width;
h = img_info->height;
size = w * y;
//*rgb_line的长度 rgb=3,argb=4
if (img_info->format == BPG_FORMAT_GRAY)
rowspan = 1 * w;
else
rowspan = 3 * w;
unsigned char *rgb_line = new unsigned char[rowspan];
//输出到output
unsigned int outBufLen = rowspan * h + 8;
unsigned char *output = new unsigned char[outBufLen];
output[0] = (unsigned char) (w & 0xFF);
output[1] = (unsigned char) ((w & 0xFF00) >> 8);
output[2] = (unsigned char) ((w & 0xFF0000) >> 16);
output[3] = (unsigned char) ((w >> 24) & 0xFF);
output[4] = (unsigned char) (h & 0xFF);
output[5] = (unsigned char) ((h & 0xFF00) >> 8);
output[6] = (unsigned char) ((h & 0xFF0000) >> 16);
output[7] = (unsigned char) ((h >> 24) & 0xFF);
bpg_decoder_start(img, BPG_OUTPUT_FORMAT_RGB24);
bufferIncrement = 8;
for (y = 0; y < h; y++) {
bpg_decoder_get_line(img, rgb_line);
for (i = 0; i < rowspan; i++) {
output[bufferIncrement + i] = rgb_line[i];
}
bufferIncrement += rowspan;
}
bpg_decoder_close(img);
delete[] rgb_line;
jbyteArray jbarray = env->NewByteArray(outBufLen);
jbyte *jy = (jbyte *) output; //BYTE强制转换成Jbyte;
env->SetByteArrayRegion(jbarray, 0, outBufLen, jy); //将Jbyte 转换为jbarray数组
env->DeleteLocalRef(imgdata);
free(output);
return jbarray;
}
};
\ No newline at end of file
This diff is collapsed.
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="cn.garymb.ygomobile.lib">
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
<application>
<activity
android:name="cn.garymb.ygomobile.YGOMobileActivity"
android:clearTaskOnLaunch="true"
android:configChanges="orientation|keyboardHidden|screenSize"
android:exported="true"
android:label="YGOMobile"
android:process=":game"
android:launchMode="singleTop"
android:screenOrientation="sensorLandscape"
android:taskAffinity="cn.garymb.ygomobile.game"
android:theme="@android:style/Theme.Holo.NoActionBar.Fullscreen"
android:windowSoftInputMode="adjustPan"
tools:targetApi="honeycomb">
<meta-data
android:name="android.app.lib_name"
android:value="YGOMobile"/>
<meta-data
android:name="android.notch_support"
android:value="true"/>
</activity>
<receiver android:name="cn.garymb.ygomobile.GameReceiver"
android:process=":game" >
<intent-filter>
<action android:name="cn.garymb.ygomobile.game.start"/>
<action android:name="cn.garymb.ygomobile.game.stop"/>
</intent-filter>
</receiver>
</application>
</manifest>
package cn.garymb.ygodata;
import android.os.Parcel;
import android.os.Parcelable;
import android.text.TextUtils;
import java.nio.ByteBuffer;
/**
* @author mabin
*/
public class YGOGameOptions implements Parcelable {
public static final long TIME_OUT = 8 * 1000;
public static final String YGO_GAME_OPTIONS_BUNDLE_TIME = "cn.garymb.ygomobile.ygogameoptions.time";
public static final String YGO_GAME_OPTIONS_BUNDLE_KEY = "cn.garymb.ygomobile.ygogameoptions";
public static final int MAX_BYTE_BUFFER_SIZE = 8192;
public String mServerAddr;
//用户名字
public String mUserName;
public String mRoomName;
public String mRoomPasswd;
//用户密码
public String mUserPassword;
public int mPort;
public int mMode = 0;
public int mRule = 0;
public int mStartLP = 8000;
public int mStartHand = 5;
public int mDrawCount = 1;
public boolean mEnablePriority = false;
public boolean mNoDeckCheck = false;
public boolean mNoDeckShuffle = false;
private boolean isCompleteOptions;
public YGOGameOptions() {
}
public boolean isCompleteOptions() {
return isCompleteOptions;
}
public void setCompleteOptions(boolean isCompleteOptions) {
this.isCompleteOptions = isCompleteOptions;
}
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(mServerAddr);
dest.writeString(mUserName);
dest.writeString(mRoomName);
dest.writeString(mRoomPasswd);
dest.writeString(mUserPassword);
dest.writeInt(mPort);
dest.writeInt(mMode);
dest.writeInt(isCompleteOptions ? 1 : 0);
dest.writeInt(mRule);
dest.writeInt(mStartLP);
dest.writeInt(mStartHand);
dest.writeInt(mDrawCount);
dest.writeInt(mEnablePriority ? 1 : 0);
dest.writeInt(mNoDeckCheck ? 1 : 0);
dest.writeInt(mNoDeckShuffle ? 1 : 0);
}
public static final Creator<YGOGameOptions> CREATOR = new Creator<YGOGameOptions>() {
@Override
public YGOGameOptions createFromParcel(Parcel source) {
YGOGameOptions options = new YGOGameOptions();
options.mServerAddr = source.readString();
options.mUserName = source.readString();
options.mRoomName = source.readString();
options.mRoomPasswd = source.readString();
options.mUserPassword = source.readString();
options.mPort = source.readInt();
options.mMode = source.readInt();
options.isCompleteOptions = source.readInt() == 1;
options.mRule = source.readInt();
options.mStartLP = source.readInt();
options.mStartHand = source.readInt();
options.mDrawCount = source.readInt();
options.mEnablePriority = source.readInt() == 1;
options.mNoDeckCheck = source.readInt() == 1;
options.mNoDeckShuffle = source.readInt() == 1;
return options;
}
@Override
public YGOGameOptions[] newArray(int size) {
return new YGOGameOptions[size];
}
};
public String toString() {
StringBuilder builder = new StringBuilder("YGOGameOptions: ");
builder.append("serverAddr: ").append(mServerAddr == null ? "(unspecified)" : mServerAddr).
append(", port: ").append(mPort).
append(", roomName: ").append(mRoomName == null ? "(unspecified)" : mRoomName.toString()).
append(", roomPassword: ").append(mRoomPasswd == null ? "(unspecified)" : mRoomPasswd.toString()).
append(", userName: ").append(mUserName == null ? "(unspecified)" : mUserName.toString()).
append(", mode: ").append(mMode).
append(", isCompleteRequest").append(isCompleteOptions).
append(", rule: ").append(mRule).
append(", startlp: ").append(mStartLP).
append(", startHand: ").append(mStartHand).
append(", drawCount: ").append(mDrawCount).
append(", enablePriority: ").append(mEnablePriority).
append(", noDeckCheck: ").append(mNoDeckCheck).
append(", noDeckShuffle: ").append(mNoDeckShuffle);
return builder.toString();
}
public ByteBuffer toByteBuffer() {
ByteBuffer buffer = ByteBuffer.allocateDirect(MAX_BYTE_BUFFER_SIZE);
putString(buffer, mServerAddr);
putString(buffer, mUserName);
putString(buffer, mRoomName);
putString(buffer, mRoomPasswd);
putString(buffer, mUserPassword);
buffer.putInt(Integer.reverseBytes(mPort));
buffer.putInt(Integer.reverseBytes(mMode));
buffer.putInt(Integer.reverseBytes(isCompleteOptions ? 1 : 0));
if (isCompleteOptions) {
buffer.putInt(Integer.reverseBytes(mRule));
buffer.putInt(Integer.reverseBytes(mStartLP));
buffer.putInt(Integer.reverseBytes(mStartHand));
buffer.putInt(Integer.reverseBytes(mDrawCount));
buffer.putInt(Integer.reverseBytes(mEnablePriority ? 1 : 0));
buffer.putInt(Integer.reverseBytes(mNoDeckCheck ? 1 : 0));
buffer.putInt(Integer.reverseBytes(mNoDeckShuffle ? 1 : 0));
}
return buffer;
}
private void putString(ByteBuffer buffer, String str) {
if (TextUtils.isEmpty(str)) {
buffer.putInt(Integer.reverseBytes(0));
} else {
buffer.putInt(Integer.reverseBytes(str.getBytes().length));
buffer.put(str.getBytes());
}
}
}
package cn.garymb.ygomobile;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.ActivityManager;
import android.app.Application;
import android.content.Context;
import android.content.res.AssetManager;
import android.media.AudioManager;
import android.media.SoundPool;
import android.os.Build;
import android.util.Log;
import java.io.File;
import java.io.IOException;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;
import cn.garymb.ygomobile.core.GameConfig;
import cn.garymb.ygomobile.core.GameSize;
import cn.garymb.ygomobile.core.IrrlichtBridge;
public abstract class GameApplication extends Application implements IrrlichtBridge.IrrlichtApplication {
private SoundPool mSoundEffectPool;
private Map<String, Integer> mSoundIdMap;
private GameConfig gameConfig = new GameConfig();
private static GameApplication sGameApplication;
private boolean isInitSoundEffectPool=false;
private static String sProcessName;
public boolean setGameConfig(GameConfig gameConfig) {
if (!this.gameConfig.equals(gameConfig)) {
this.gameConfig = gameConfig;
Log.i("kk", "setGameConfig:" + gameConfig);
if(gameConfig.isEnableSoundEffect()){
initSoundEffectPool();
setInitSoundEffectPool(true);
}
return true;
}
return false;
}
public final GameConfig getGameConfig() {
return gameConfig;
}
@Override
public void onCreate() {
super.onCreate();
sProcessName = getCurrentProcessName();
sGameApplication = this;
// Reflection.unseal(this);
// initSoundEffectPool();
}
public static boolean isGameProcess(){
return sProcessName != null && sProcessName.endsWith(":game");
}
public static GameApplication get() {
return sGameApplication;
}
@Override
protected void attachBaseContext(Context base) {
super.attachBaseContext(base);
}
@Override
public void onTerminate() {
super.onTerminate();
mSoundEffectPool.release();
}
public boolean isInitSoundEffectPool() {
return isInitSoundEffectPool;
}
protected void setInitSoundEffectPool(boolean initSoundEffectPool) {
isInitSoundEffectPool = initSoundEffectPool;
}
@SuppressWarnings("deprecation")
public void initSoundEffectPool() {
mSoundEffectPool = new SoundPool(2, AudioManager.STREAM_MUSIC, 0);
AssetManager am = getAssets();
String[] sounds;
mSoundIdMap = new HashMap<String, Integer>();
try {
sounds = am.list("sound");
for (String sound : sounds) {
String path = "sound" + File.separator + sound;
mSoundIdMap
.put(path, mSoundEffectPool.load(am.openFd(path), 1));
}
} catch (IOException e) {
e.printStackTrace();
}
}
public abstract GameSize getGameSize(Activity activity);
public NativeInitOptions getNativeInitOptions() {
return getGameConfig().getNativeInitOptions();
}
@Override
public abstract float getXScale();
@Override
public abstract float getYScale();
@Override
public String getCardImagePath() {
return getGameConfig().getImagePath();
}
@Override
public String getFontPath() {
return getGameConfig().getFontPath();
}
public boolean isKeepScale() {
return getGameConfig().isKeepScale();
}
public boolean isLockSreenOrientation() {
return getGameConfig().isLockScreenOrientation();
}
/***
* 隐藏底部导航栏
*/
public boolean isImmerSiveMode() {
return getGameConfig().isImmerSiveMode();
}
public boolean isSensorRefresh() {
return getGameConfig().isSensorRefresh();
}
@Override
public void playSoundEffect(String path) {
Integer id = mSoundIdMap.get(path);
if (id != null) {
mSoundEffectPool.play(id, 0.5f, 0.5f, 2, 0, 1.0f);
}
}
@SuppressLint({"PrivateApi", "DiscouragedPrivateApi"})
protected String getCurrentProcessName() {
if (Build.VERSION.SDK_INT >= 28) {
return getProcessName();
}
try {
Class<?> clazz = Class.forName("android.app.ActivityThread");
Method currentProcessName = clazz.getDeclaredMethod("currentProcessName");
return (String) currentProcessName.invoke(null);
} catch (Throwable e) {
Log.w("kk", "currentProcessName", e);
}
int pid = android.os.Process.myPid();
String processName = getPackageName();
ActivityManager am = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
for (ActivityManager.RunningAppProcessInfo info : am.getRunningAppProcesses()) {
if (info.pid == pid) {
processName = info.processName;
break;
}
}
return processName;
}
}
package cn.garymb.ygomobile;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import cn.garymb.ygomobile.core.IrrlichtBridge;
import static cn.garymb.ygomobile.core.IrrlichtBridge.ACTION_START;
import static cn.garymb.ygomobile.core.IrrlichtBridge.ACTION_STOP;
public class GameReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (ACTION_START.equals(action)) {
//
IrrlichtBridge.gPid = intent.getIntExtra(IrrlichtBridge.EXTRA_PID, 0);
// Log.w("ygo", "pid=" + IrrlichtBridge.gPid);
} else if (ACTION_STOP.equals(action)) {
int pid = intent.getIntExtra(IrrlichtBridge.EXTRA_PID, 0);
if (pid == 0 && IrrlichtBridge.gPid != 0) {
pid = IrrlichtBridge.gPid;
// Log.w("ygo", "will kill last pid=" + pid);
}
if (pid == 0) {
pid = android.os.Process.myPid();
// Log.w("ygo", "will kill now pid=" + pid);
}
try {
// Log.w("ygo", "kill pid=" + pid);
android.os.Process.killProcess(pid);
} catch (Exception e) {
//ignore
}
}
}
}
package cn.garymb.ygomobile;
import android.os.Parcel;
import android.os.Parcelable;
import android.text.TextUtils;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
public final class NativeInitOptions implements Parcelable {
private static final int BUFFER_MAX_SIZE = 8192;
public int mOpenglVersion;
public boolean mIsSoundEffectEnabled;
//工作目录
public String mWorkPath;
// /data/data/cards.cdb;a.cdb;b.cdb
public final List<String> mDbList;
//pics.zip;scripts.zip;a.zip;b.zip
public final List<String> mArchiveList;
public int mCardQuality;
public boolean mIsFontAntiAliasEnabled;
public boolean mIsPendulumScaleEnabled;
public NativeInitOptions() {
mDbList = new ArrayList<>();
mArchiveList = new ArrayList<>();
}
public ByteBuffer toNativeBuffer() {
ByteBuffer buffer = ByteBuffer.allocateDirect(BUFFER_MAX_SIZE);
putInt(buffer, mOpenglVersion);
putInt(buffer, mIsSoundEffectEnabled ? 1 : 0);
putInt(buffer, mCardQuality);
putInt(buffer, mIsFontAntiAliasEnabled ? 1 : 0);
putInt(buffer, mIsPendulumScaleEnabled ? 1 : 0);
putString(buffer, mWorkPath);
putInt(buffer, mDbList.size());
for(String str:mDbList){
putString(buffer, str);
}
putInt(buffer, mArchiveList.size());
for (String str : mArchiveList) {
putString(buffer, str);
}
return buffer;
}
@Override
public String toString() {
return "NativeInitOptions{" +
"mOpenglVersion=" + mOpenglVersion +
", mIsSoundEffectEnabled=" + mIsSoundEffectEnabled +
", mWorkPath='" + mWorkPath + '\'' +
", mDbList='" + mDbList + '\'' +
", mArchiveList='" + mArchiveList + '\'' +
", mCardQuality=" + mCardQuality +
", mIsFontAntiAliasEnabled=" + mIsFontAntiAliasEnabled +
", mIsPendulumScaleEnabled=" + mIsPendulumScaleEnabled +
'}';
}
private void putString(ByteBuffer buffer, String str) {
if (TextUtils.isEmpty(str)) {
buffer.putInt(Integer.reverseBytes(0));
} else {
buffer.putInt(Integer.reverseBytes(str.getBytes().length));
buffer.put(str.getBytes());
}
}
@SuppressWarnings("unused")
private void putChar(ByteBuffer buffer, char value) {
Short svalue = (short) value;
buffer.putShort((Short.reverseBytes(svalue)));
}
private void putInt(ByteBuffer buffer, int value) {
buffer.putInt((Integer.reverseBytes(value)));
}
@Override
public int describeContents() {
return 0;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
NativeInitOptions options = (NativeInitOptions) o;
return mOpenglVersion == options.mOpenglVersion &&
mIsSoundEffectEnabled == options.mIsSoundEffectEnabled &&
mCardQuality == options.mCardQuality &&
mIsFontAntiAliasEnabled == options.mIsFontAntiAliasEnabled &&
mIsPendulumScaleEnabled == options.mIsPendulumScaleEnabled &&
Objects.equals(mWorkPath, options.mWorkPath) &&
Objects.equals(mDbList, options.mDbList) &&
Objects.equals(mArchiveList, options.mArchiveList);
}
@Override
public int hashCode() {
return Objects.hash(mOpenglVersion, mIsSoundEffectEnabled, mWorkPath, mDbList, mArchiveList, mCardQuality, mIsFontAntiAliasEnabled, mIsPendulumScaleEnabled);
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeInt(this.mOpenglVersion);
dest.writeByte(this.mIsSoundEffectEnabled ? (byte) 1 : (byte) 0);
dest.writeString(this.mWorkPath);
dest.writeStringList(this.mDbList);
dest.writeStringList(this.mArchiveList);
dest.writeInt(this.mCardQuality);
dest.writeByte(this.mIsFontAntiAliasEnabled ? (byte) 1 : (byte) 0);
dest.writeByte(this.mIsPendulumScaleEnabled ? (byte) 1 : (byte) 0);
}
protected NativeInitOptions(Parcel in) {
this.mOpenglVersion = in.readInt();
this.mIsSoundEffectEnabled = in.readByte() != 0;
this.mWorkPath = in.readString();
this.mDbList = in.createStringArrayList();
this.mArchiveList = in.createStringArrayList();
this.mCardQuality = in.readInt();
this.mIsFontAntiAliasEnabled = in.readByte() != 0;
this.mIsPendulumScaleEnabled = in.readByte() != 0;
}
public static final Parcelable.Creator<NativeInitOptions> CREATOR = new Parcelable.Creator<NativeInitOptions>() {
@Override
public NativeInitOptions createFromParcel(Parcel source) {
return new NativeInitOptions(source);
}
@Override
public NativeInitOptions[] newArray(int size) {
return new NativeInitOptions[size];
}
};
}
package cn.garymb.ygomobile.controller;
import android.content.Context;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.net.wifi.WifiInfo;
import android.net.wifi.WifiManager;
/**
* @author mabin
*/
public final class NetworkController {
private Context mContext;
private WifiManager mWM;
private ConnectivityManager mCM;
/**
*
*/
public NetworkController(Context context) {
mContext = context;
init();
}
/**
* @return
**/
private void init() {
mWM = (WifiManager) mContext.getSystemService(Context.WIFI_SERVICE);
mCM = (ConnectivityManager) mContext
.getSystemService(Context.CONNECTIVITY_SERVICE);
}
/**
* @return
* @author: mabin
**/
public boolean isWifiConnected() {
// TODO Auto-generated method stub
boolean isWifiEnabled = mWM.isWifiEnabled();
NetworkInfo ni = mCM.getActiveNetworkInfo();
if (isWifiEnabled && null != ni && ni.isConnected()
&& ni.getType() == ConnectivityManager.TYPE_WIFI) {
return true;
}
return false;
}
public int getIPAddress() {
if (!isWifiConnected()) {
return -1;
}
WifiInfo wi = mWM.getConnectionInfo();
return wi.getIpAddress();
}
}
package cn.garymb.ygomobile.core;
import android.os.Parcel;
import android.os.Parcelable;
import cn.garymb.ygomobile.NativeInitOptions;
public class GameConfig implements Parcelable {
public static final String EXTRA_CONFIG = "ygo_config";
private NativeInitOptions nativeInitOptions;
private boolean lockScreenOrientation;
private boolean sensorRefresh;
private boolean keepScale;
/***
* 隐藏底部导航栏
*/
private boolean immerSiveMode;
private boolean enableSoundEffect;
private String fontPath;
private String resourcePath;
private String imagePath;
public NativeInitOptions getNativeInitOptions() {
return nativeInitOptions;
}
public void setNativeInitOptions(NativeInitOptions nativeInitOptions) {
this.nativeInitOptions = nativeInitOptions;
}
public boolean isLockScreenOrientation() {
return lockScreenOrientation;
}
public void setLockScreenOrientation(boolean lockScreenOrientation) {
this.lockScreenOrientation = lockScreenOrientation;
}
public String getImagePath() {
return imagePath;
}
public void setImagePath(String imagePath) {
this.imagePath = imagePath;
}
public boolean isSensorRefresh() {
return sensorRefresh;
}
public void setSensorRefresh(boolean sensorRefresh) {
this.sensorRefresh = sensorRefresh;
}
public boolean isImmerSiveMode() {
return immerSiveMode;
}
public void setImmerSiveMode(boolean immerSiveMode) {
this.immerSiveMode = immerSiveMode;
}
public boolean isEnableSoundEffect() {
return enableSoundEffect;
}
public void setEnableSoundEffect(boolean enableSoundEffect) {
this.enableSoundEffect = enableSoundEffect;
}
public boolean isKeepScale() {
return keepScale;
}
public void setKeepScale(boolean keepScale) {
this.keepScale = keepScale;
}
public String getFontPath() {
return fontPath;
}
public void setFontPath(String fontPath) {
this.fontPath = fontPath;
}
public String getResourcePath() {
return resourcePath;
}
public void setResourcePath(String resourcePath) {
this.resourcePath = resourcePath;
}
public GameConfig() {
nativeInitOptions = new NativeInitOptions();
lockScreenOrientation = false;
sensorRefresh = true;
immerSiveMode = false;
enableSoundEffect = true;
}
@Override
public String toString() {
return "GameConfig{" +
"nativeInitOptions=" + nativeInitOptions +
", lockScreenOrientation=" + lockScreenOrientation +
", sensorRefresh=" + sensorRefresh +
", keepScale=" + keepScale +
", immerSiveMode=" + immerSiveMode +
", enableSoundEffect=" + enableSoundEffect +
", fontPath='" + fontPath + '\'' +
", resourcePath='" + resourcePath + '\'' +
", imagePath='" + imagePath + '\'' +
'}';
}
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeParcelable(this.nativeInitOptions, flags);
dest.writeByte(this.lockScreenOrientation ? (byte) 1 : (byte) 0);
dest.writeByte(this.sensorRefresh ? (byte) 1 : (byte) 0);
dest.writeByte(this.keepScale ? (byte) 1 : (byte) 0);
dest.writeByte(this.immerSiveMode ? (byte) 1 : (byte) 0);
dest.writeByte(this.enableSoundEffect ? (byte) 1 : (byte) 0);
dest.writeString(this.fontPath);
dest.writeString(this.resourcePath);
dest.writeString(this.imagePath);
}
protected GameConfig(Parcel in) {
this.nativeInitOptions = in.readParcelable(NativeInitOptions.class.getClassLoader());
this.lockScreenOrientation = in.readByte() != 0;
this.sensorRefresh = in.readByte() != 0;
this.keepScale = in.readByte() != 0;
this.immerSiveMode = in.readByte() != 0;
this.enableSoundEffect = in.readByte() != 0;
this.fontPath = in.readString();
this.resourcePath = in.readString();
this.imagePath = in.readString();
}
public static final Creator<GameConfig> CREATOR = new Creator<GameConfig>() {
@Override
public GameConfig createFromParcel(Parcel source) {
return new GameConfig(source);
}
@Override
public GameConfig[] newArray(int size) {
return new GameConfig[size];
}
};
}
package cn.garymb.ygomobile.core;
public class GameSize {
private int width;
private int height;
private int touchX;
private int touchY;
public void update(GameSize size) {
synchronized (this) {
this.width = size.width;
this.height = size.height;
this.touchX = size.touchX;
this.touchY = size.touchY;
}
}
public void setTouch(int touchX, int touchY) {
synchronized (this) {
this.touchX = touchX;
this.touchY = touchY;
}
}
public int getWidth() {
synchronized (this) {
return width;
}
}
public int getHeight() {
synchronized (this) {
return height;
}
}
public int getTouchX() {
synchronized (this) {
return touchX;
}
}
public int getTouchY() {
synchronized (this) {
return touchY;
}
}
public GameSize() {
}
public GameSize(int width, int height, int touchX, int touchY) {
this.width = width;
this.height = height;
this.touchX = touchX;
this.touchY = touchY;
}
@Override
public String toString() {
return "GameSize{" +
"width=" + width +
", height=" + height +
", touchX=" + touchX +
", touchY=" + touchY +
'}';
}
}
/*
* IrrlichtBridge.java
*
* Created on: 2014年3月18日
* Author: mabin
*/
package cn.garymb.ygomobile.core;
import android.graphics.Bitmap;
import android.graphics.Color;
import android.util.Log;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.ByteBuffer;
import java.util.Arrays;
import static cn.garymb.ygomobile.utils.ByteUtils.byte2int;
import static cn.garymb.ygomobile.utils.ByteUtils.byte2uint;
/**
* @author mabin
*/
public final class IrrlichtBridge {
public static final float GAME_WIDTH = 1024.0f;
public static final float GAME_HEIGHT = 640.0f;
public static final String ACTION_START = "cn.garymb.ygomobile.game.start";
public static final String ACTION_STOP = "cn.garymb.ygomobile.game.stop";
public static final String EXTRA_PID = "extras.mypid";
public static int gPid;
static {
try {
System.loadLibrary("YGOMobile");
}catch (Throwable e){
//ignore
}
}
private IrrlichtBridge() {
}
public static int sNativeHandle;
//显示卡图
public static native byte[] nativeBpgImage(byte[] data);
//插入文本(大概是发送消息)
private static native void nativeInsertText(int handle, String text);
//刷新文字
private static native void nativeRefreshTexture(int handle);
//忽略时点
private static native void nativeIgnoreChain(int handle, boolean begin);
//强制时点
private static native void nativeReactChain(int handle, boolean begin);
//取消连锁
private static native void nativeCancelChain(int handle);
private static native void nativeSetCheckBoxesSelection(int handle, int idx);
private static native void nativeSetComboBoxSelection(int handle, int idx);
private static native void nativeJoinGame(int handle, ByteBuffer buffer, int length);
private static native void nativeSetInputFix(int handle, int x, int y);
private static final boolean DEBUG = false;
private static final String TAG = IrrlichtBridge.class.getSimpleName();
public static Bitmap getBpgImage(InputStream inputStream, Bitmap.Config config) {
ByteArrayOutputStream outputStream = null;
try {
outputStream = new ByteArrayOutputStream();
byte[] tmp = new byte[4096];
int len = 0;
while ((len = inputStream.read(tmp)) != -1) {
outputStream.write(tmp, 0, len);
}
//解码前
byte[] bpg = outputStream.toByteArray();
return getBpgImage(bpg, config);
} catch (Exception e) {
if (DEBUG)
Log.e(TAG, "zip image", e);
} finally {
if (outputStream != null) {
try {
outputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return null;
}
/***
*
*/
public static Bitmap getBpgImage(byte[] bpg, Bitmap.Config config) {
try {
//解码后
byte[] data = nativeBpgImage(bpg);
int start = 8;
int w = byte2int(Arrays.copyOfRange(data, 0, 4));
int h = byte2int(Arrays.copyOfRange(data, 4, 8));
if (w < 0 || h < 0) {
if (DEBUG)
Log.e(TAG, "zip image:w=" + w + ",h=" + h);
return null;
}
int index = 0;
int[] colors = new int[(data.length - start) / 3];
for (int i = 0; i < colors.length; i++) {
index = start + i * 3;
colors[i] = Color.rgb(byte2uint(data[index + 0]), byte2uint(data[index + 1]), byte2uint(data[index + 2]));
}
return Bitmap.createBitmap(colors, w, h, config);
} catch (Throwable e) {
if (DEBUG)
Log.e(TAG, "zip image", e);
return null;
}
}
public static void setInputFix(int x, int y){
nativeSetInputFix(sNativeHandle, x, y);
}
public static void cancelChain() {
nativeCancelChain(sNativeHandle);
}
public static void ignoreChain(boolean begin) {
nativeIgnoreChain(sNativeHandle, begin);
}
public static void reactChain(boolean begin) {
nativeReactChain(sNativeHandle, begin);
}
public static void insertText(String text) {
nativeInsertText(sNativeHandle, text);
}
public static void setComboBoxSelection(int idx) {
nativeSetComboBoxSelection(sNativeHandle, idx);
}
public static void refreshTexture() {
nativeRefreshTexture(sNativeHandle);
}
public static void setCheckBoxesSelection(int idx) {
nativeSetCheckBoxesSelection(sNativeHandle, idx);
}
public static void joinGame(ByteBuffer options, int length) {
nativeJoinGame(sNativeHandle, options, length);
}
public interface IrrlichtApplication {
String getCardImagePath();
void saveSetting(String key, String value);
String getFontPath();
String getSetting(String key);
int getIntSetting(String key,int def);
void saveIntSetting(String key,int value);
void playSoundEffect(String path);
void runWindbot(String args);
float getXScale();
float getYScale();
// float getSmallerSize();
// float getXScale();
// float getYScale();
// float getDensity();
}
public interface IrrlichtHost {
void toggleOverlayView(boolean isShow);
ByteBuffer getInitOptions();
ByteBuffer getNativeInitOptions();
void toggleIME(String hint, boolean isShow);
void showComboBoxCompat(String[] items, boolean isShow, int mode);
void performHapticFeedback();
/**
* 签名
*/
byte[] performTrick();
int getLocalAddress();
void setNativeHandle(int nativeHandle);
int getPositionX();
int getPositionY();
}
}
package cn.garymb.ygomobile.utils;
public class ByteUtils {
public static void reverse(byte[] data) {
int size = data.length;
for (int i = 0; i < size / 2; i++) {
byte tmp = data[i];
data[i] = data[size - i - 1];
data[size - i - 1] = tmp;
}
}
public static int byte2int(byte[] res) {
String str =String.format("%02x%02x%02x%02x",res[3],res[2],res[1],res[0]);
return Integer.parseInt(str, 16);
}
public static byte[] short2byte(short i) {
return new byte[]{(byte) (i & 0xff), (byte) (i >> 8 & 0xff)};
}
public static int byte2uint(byte b) {
int i = b;
if (b < 0) {
i = 0xff +1+ b;
}
return i;
// String str = String.format("%02x", b);
// return Integer.parseInt(str, 16);
}
public static byte[] int2byte(int i) {
return new byte[]{(byte) (i & 0xff), (byte) ((i & 0xff00) >> 8), (byte) ((i & 0xff0000) >> 16),
(byte) ((i >> 24) & 0xff),
};
}
public static int str2byte(String str) {
return Integer.parseInt(str, 16);
}
// public static byte[] int2byte2(int i) {
// String str = String.format("%08x", i);
// // System.out.println(str);
// return new byte[] { (byte) str2byte(str.substring(6, 8)), (byte) str2byte(str.substring(4, 6)),
// (byte) str2byte(str.substring(2, 4)), (byte) str2byte(str.substring(0, 2)), };
// }
// public static int byte2int2(byte b) {
// String str = String.format("%02x", b);
//// System.out.println(str);
//// byte b1 = (byte) ((b & 0xf0) >> 8);
//// byte b2 = (byte) (b & 0xf);
//// System.out.println(String.format("%01x%01x", b1, b2));
// return Integer.parseInt(str, 16);
// }
// public static int byte2int2(byte[] res) {
// return (int) res[3] * 0x1000000 + (int) res[2] * 0x10000 + (int) res[1] *
// 0x100 + (int) res[0];
// }
//
// public static byte[] short2byte2(short i) {
// String str = String.format("%04x", i);
// return new byte[] { (byte) str2byte(str.substring(2, 4)), (byte)
// str2byte(str.substring(0, 2)), };
// }
}
package cn.garymb.ygomobile.utils;
import android.content.Context;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.Signature;
import java.io.ByteArrayInputStream;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import java.util.Arrays;
public class SignUtils {
public static byte[] getSignInfo(Context context) {
try {
PackageInfo pi = context.getPackageManager().getPackageInfo(
context.getPackageName(), PackageManager.GET_SIGNATURES);
Signature[] signs = pi.signatures;
Signature sign = signs[0];
return parseSignature(sign.toByteArray());
} catch (Exception e) {
}
return null;
}
private static byte[] parseSignature(byte[] signature) {
try {
CertificateFactory certFactory = CertificateFactory
.getInstance("X.509");
X509Certificate cert = (X509Certificate) certFactory
.generateCertificate(new ByteArrayInputStream(signature));
byte[] buffer = cert.getEncoded();
return Arrays.copyOf(buffer, 16);
} catch (Exception e) {
}
return null;
}
}
/*
* ComboBoxCompat.java
*
* Created on: 2014年3月15日
* Author: mabin
*/
package cn.garymb.ygomobile.widget;
import android.content.Context;
import android.graphics.drawable.ColorDrawable;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup.LayoutParams;
import android.widget.Button;
import android.widget.PopupWindow;
import android.widget.ViewFlipper;
import cn.garymb.ygomobile.lib.R;
import cn.garymb.ygomobile.widget.wheelview.ArrayWheelAdapter;
import cn.garymb.ygomobile.widget.wheelview.WheelView;
public class ComboBoxCompat extends PopupWindow {
/*change this will affect C++ code, be careful!*/
public static final int COMPAT_GUI_MODE_COMBOBOX = 0;
/*change this will affect C++ code, be careful!*/
public static final int COMPAT_GUI_MODE_CHECKBOXES_PANEL = 1;
private Context mContext;
private WheelView mComboBoxContent;
private Button mSubmitButton;
private Button mCancelButton;
private ViewFlipper mFlipper;
private ArrayWheelAdapter<String> mAdapter;
public ComboBoxCompat(Context context) {
// TODO Auto-generated constructor stub
super(context);
mContext = context;
View menuView = LayoutInflater.from(mContext).inflate(R.layout.combobox_compat_layout, null);
mComboBoxContent = (WheelView) menuView.findViewById(R.id.combobox_content);
mSubmitButton = (Button) menuView.findViewById(R.id.submit);
mCancelButton = (Button) menuView.findViewById(R.id.cancel);
mFlipper = new ViewFlipper(context);
mFlipper.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT,
LayoutParams.WRAP_CONTENT));
mFlipper.addView(menuView);
mFlipper.setFlipInterval(6000000);
setContentView(mFlipper);
}
public void setButtonListener(OnClickListener listener) {
mSubmitButton.setOnClickListener(listener);
mCancelButton.setOnClickListener(listener);
}
public void fillContent(String[] items) {
mAdapter = new ArrayWheelAdapter<String>(mContext, items);
mComboBoxContent.setViewAdapter(mAdapter);
this.setWidth(LayoutParams.MATCH_PARENT);
this.setHeight(LayoutParams.WRAP_CONTENT);
this.setFocusable(true);
ColorDrawable dw = new ColorDrawable(0x00000000);
this.setBackgroundDrawable(dw);
this.update();
}
public int getCurrentSelection() {
return mComboBoxContent.getCurrentItem();
}
@Override
public void showAtLocation(View parent, int gravity, int x, int y) {
super.showAtLocation(parent, gravity, x, y);
mFlipper.startFlipping();
}
@Override
public void dismiss() {
// TODO Auto-generated method stub
super.dismiss();
}
}
/*
* EditWindowCompat.java
*
* Created on: 2014年3月15日
* Author: mabin
*/
package cn.garymb.ygomobile.widget;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewGroup.LayoutParams;
import android.view.inputmethod.InputMethodManager;
import android.widget.EditText;
import android.widget.PopupWindow;
import android.widget.TextView.OnEditorActionListener;
import cn.garymb.ygomobile.lib.R;
/**
* @author mabin
*
*/
public class EditWindowCompat extends PopupWindow {
private Context mContext;
private ViewGroup mContentView;
private EditText mEditText;
private InputMethodManager mIM;
public EditWindowCompat(Context context) {
super(context);
mContext = context;
mContentView = (ViewGroup) LayoutInflater.from(mContext).inflate(
R.layout.text_input_compat_layout, null);
mEditText = (EditText) mContentView.findViewById(R.id.global_input);
mIM = (InputMethodManager) mContext.getSystemService(Context.INPUT_METHOD_SERVICE);
setContentView(mContentView);
}
public void fillContent(String hint) {
mEditText.setText(hint);
this.setWidth(LayoutParams.MATCH_PARENT);
this.setHeight(LayoutParams.WRAP_CONTENT);
this.setFocusable(true);
this.update();
}
/* (non-Javadoc)
* @see android.widget.PopupWindow#showAtLocation(android.view.View, int, int, int)
*/
@Override
public void showAtLocation(View parent, int gravity, int x, int y) {
// TODO Auto-generated method stub
mEditText.requestFocus();
mIM.showSoftInput(mEditText, 0);
super.showAtLocation(parent, gravity, x, y);
}
/* (non-Javadoc)
* @see android.widget.PopupWindow#dismiss()
*/
@Override
public void dismiss() {
// TODO Auto-generated method stub
mEditText.clearFocus();
mIM.hideSoftInputFromWindow(mEditText.getWindowToken(), 0);
super.dismiss();
}
public void setEditActionListener(OnEditorActionListener listener) {
mEditText.setOnEditorActionListener(listener);
}
}
package cn.garymb.ygomobile.widget.wheelview;
public interface OnWheelChangedListener {
void onChanged(WheelView wheel, int oldValue, int newValue);
}
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_selected="true" android:color="@android:color/white" />
<item android:state_activated="true" android:color="@android:color/white" />
<item android:color="#585858" />
</selector>
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment