mirror of
https://github.com/vcmi/vcmi.git
synced 2024-12-24 22:14:36 +02:00
Merge vcmi/beta into vcmi/develop
This commit is contained in:
commit
57ee9a9bf3
@ -1,3 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
"$1/ios/zip2ipa.sh" "$2"
|
@ -729,6 +729,7 @@ elseif(APPLE_MACOS AND NOT ENABLE_MONOLITHIC_INSTALL)
|
||||
add_subdirectory(osx)
|
||||
elseif(APPLE_IOS)
|
||||
set(CPACK_GENERATOR ZIP)
|
||||
set(CPACK_ARCHIVE_FILE_EXTENSION ipa)
|
||||
set(CPACK_INCLUDE_TOPLEVEL_DIRECTORY OFF)
|
||||
set(CPACK_INSTALL_CMAKE_PROJECTS "${CMAKE_CURRENT_BINARY_DIR};${CMAKE_PROJECT_NAME};app;/")
|
||||
else()
|
||||
|
@ -376,7 +376,8 @@ int main(int argc, char * argv[])
|
||||
SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 0);
|
||||
#endif // VCMI_ANDROID
|
||||
|
||||
GH.mainFPSmng->init(); //(!)init here AFTER SDL_Init() while using SDL for FPS management
|
||||
//(!)init here AFTER SDL_Init() while using SDL for FPS management
|
||||
GH.init();
|
||||
|
||||
SDL_LogSetOutputFunction(&SDLLogCallback, nullptr);
|
||||
|
||||
@ -432,11 +433,20 @@ int main(int argc, char * argv[])
|
||||
CCS->musich->setVolume((ui32)settings["general"]["music"].Float());
|
||||
logGlobal->info("Initializing screen and sound handling: %d ms", pomtime.getDiff());
|
||||
}
|
||||
|
||||
#ifdef VCMI_MAC
|
||||
// Ctrl+click should be treated as a right click on Mac OS X
|
||||
SDL_SetHint(SDL_HINT_MAC_CTRL_CLICK_EMULATE_RIGHT_CLICK, "1");
|
||||
#endif
|
||||
|
||||
#ifdef SDL_HINT_MOUSE_TOUCH_EVENTS
|
||||
if(GH.isPointerRelativeMode)
|
||||
{
|
||||
SDL_SetHint(SDL_HINT_MOUSE_TOUCH_EVENTS, "0");
|
||||
SDL_SetHint(SDL_HINT_TOUCH_MOUSE_EVENTS, "0");
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef VCMI_NO_THREADED_LOAD
|
||||
//we can properly play intro only in the main thread, so we have to move loading to the separate thread
|
||||
boost::thread loading(init);
|
||||
|
@ -263,8 +263,7 @@ elseif(APPLE_IOS)
|
||||
set_source_files_properties(${XCODE_RESOURCE_PATH} PROPERTIES MACOSX_PACKAGE_LOCATION Resources)
|
||||
|
||||
# workaround to prevent CMAKE_SKIP_PRECOMPILE_HEADERS being added as compile flag
|
||||
# add max version condition when https://gitlab.kitware.com/cmake/cmake/-/merge_requests/7562 is merged
|
||||
if(CMAKE_VERSION VERSION_GREATER_EQUAL "3.22.0")
|
||||
if(CMAKE_VERSION VERSION_GREATER_EQUAL "3.22.0" AND CMAKE_VERSION VERSION_LESS "3.25.0")
|
||||
set_source_files_properties(${XCODE_RESOURCE_PATH} PROPERTIES LANGUAGE CXX)
|
||||
endif()
|
||||
endforeach()
|
||||
|
@ -775,14 +775,14 @@ void CClient::removeGUI()
|
||||
}
|
||||
|
||||
#ifdef VCMI_ANDROID
|
||||
extern "C" JNIEXPORT void JNICALL Java_eu_vcmi_vcmi_NativeMethods_clientSetupJNI(JNIEnv * env, jobject cls)
|
||||
extern "C" JNIEXPORT void JNICALL Java_eu_vcmi_vcmi_NativeMethods_clientSetupJNI(JNIEnv * env, jclass cls)
|
||||
{
|
||||
logNetwork->info("Received clientSetupJNI");
|
||||
|
||||
CAndroidVMHelper::cacheVM(env);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL Java_eu_vcmi_vcmi_NativeMethods_notifyServerClosed(JNIEnv * env, jobject cls)
|
||||
extern "C" JNIEXPORT void JNICALL Java_eu_vcmi_vcmi_NativeMethods_notifyServerClosed(JNIEnv * env, jclass cls)
|
||||
{
|
||||
logNetwork->info("Received server closed signal");
|
||||
if (CSH) {
|
||||
@ -790,13 +790,13 @@ extern "C" JNIEXPORT void JNICALL Java_eu_vcmi_vcmi_NativeMethods_notifyServerCl
|
||||
}
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL Java_eu_vcmi_vcmi_NativeMethods_notifyServerReady(JNIEnv * env, jobject cls)
|
||||
extern "C" JNIEXPORT void JNICALL Java_eu_vcmi_vcmi_NativeMethods_notifyServerReady(JNIEnv * env, jclass cls)
|
||||
{
|
||||
logNetwork->info("Received server ready signal");
|
||||
androidTestServerReadyFlag.store(true);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT bool JNICALL Java_eu_vcmi_vcmi_NativeMethods_tryToSaveTheGame(JNIEnv * env, jobject cls)
|
||||
extern "C" JNIEXPORT jboolean JNICALL Java_eu_vcmi_vcmi_NativeMethods_tryToSaveTheGame(JNIEnv * env, jclass cls)
|
||||
{
|
||||
logGlobal->info("Received emergency save game request");
|
||||
if(!LOCPLINT || !LOCPLINT->cb)
|
||||
|
@ -79,6 +79,13 @@ void CGuiHandler::processLists(const ui16 activityFlag, std::function<void (std:
|
||||
processList(CIntObject::TEXTINPUT,activityFlag,&textInterested,cb);
|
||||
}
|
||||
|
||||
void CGuiHandler::init()
|
||||
{
|
||||
mainFPSmng->init();
|
||||
isPointerRelativeMode = settings["general"]["userRelativePointer"].Bool();
|
||||
pointerSpeedMultiplier = settings["general"]["relativePointerSpeedMultiplier"].Float();
|
||||
}
|
||||
|
||||
void CGuiHandler::handleElementActivate(CIntObject * elem, ui16 activityFlag)
|
||||
{
|
||||
processLists(activityFlag,[&](std::list<CIntObject*> * lst){
|
||||
@ -207,7 +214,79 @@ void CGuiHandler::handleEvents()
|
||||
}
|
||||
}
|
||||
|
||||
void CGuiHandler::handleCurrentEvent(const SDL_Event & current )
|
||||
void CGuiHandler::convertTouchToMouse(SDL_Event * current)
|
||||
{
|
||||
int rLogicalWidth, rLogicalHeight;
|
||||
|
||||
SDL_RenderGetLogicalSize(mainRenderer, &rLogicalWidth, &rLogicalHeight);
|
||||
|
||||
int adjustedMouseY = (int)(current->tfinger.y * rLogicalHeight);
|
||||
int adjustedMouseX = (int)(current->tfinger.x * rLogicalWidth);
|
||||
|
||||
current->button.x = adjustedMouseX;
|
||||
current->motion.x = adjustedMouseX;
|
||||
current->button.y = adjustedMouseY;
|
||||
current->motion.y = adjustedMouseY;
|
||||
}
|
||||
|
||||
void CGuiHandler::fakeMoveCursor(float dx, float dy)
|
||||
{
|
||||
int x, y, w, h;
|
||||
|
||||
SDL_Event event;
|
||||
SDL_MouseMotionEvent sme = {SDL_MOUSEMOTION, 0, 0, 0, 0, 0, 0, 0, 0};
|
||||
|
||||
sme.state = SDL_GetMouseState(&x, &y);
|
||||
SDL_GetWindowSize(mainWindow, &w, &h);
|
||||
|
||||
sme.x = CCS->curh->position().x + (int)(GH.pointerSpeedMultiplier * w * dx);
|
||||
sme.y = CCS->curh->position().y + (int)(GH.pointerSpeedMultiplier * h * dy);
|
||||
|
||||
vstd::abetween(sme.x, 0, w);
|
||||
vstd::abetween(sme.y, 0, h);
|
||||
|
||||
event.motion = sme;
|
||||
SDL_PushEvent(&event);
|
||||
}
|
||||
|
||||
void CGuiHandler::fakeMouseMove()
|
||||
{
|
||||
fakeMoveCursor(0, 0);
|
||||
}
|
||||
|
||||
void CGuiHandler::fakeMouseButtonEventRelativeMode(bool down, bool right)
|
||||
{
|
||||
SDL_Event event;
|
||||
SDL_MouseButtonEvent sme = {SDL_MOUSEBUTTONDOWN, 0, 0, 0, 0, 0, 0, 0, 0, 0};
|
||||
|
||||
if(!down)
|
||||
{
|
||||
sme.type = SDL_MOUSEBUTTONUP;
|
||||
}
|
||||
|
||||
sme.button = right ? SDL_BUTTON_RIGHT : SDL_BUTTON_LEFT;
|
||||
|
||||
sme.x = CCS->curh->position().x;
|
||||
sme.y = CCS->curh->position().y;
|
||||
|
||||
float xScale, yScale;
|
||||
int w, h, rLogicalWidth, rLogicalHeight;
|
||||
|
||||
SDL_GetWindowSize(mainWindow, &w, &h);
|
||||
SDL_RenderGetLogicalSize(mainRenderer, &rLogicalWidth, &rLogicalHeight);
|
||||
SDL_RenderGetScale(mainRenderer, &xScale, &yScale);
|
||||
|
||||
SDL_EventState(SDL_MOUSEMOTION, SDL_IGNORE);
|
||||
CSDL_Ext::warpMouse(
|
||||
(int)(sme.x * xScale) + (w - rLogicalWidth * xScale) / 2,
|
||||
(int)(sme.y * yScale + (h - rLogicalHeight * yScale) / 2));
|
||||
SDL_EventState(SDL_MOUSEMOTION, SDL_ENABLE);
|
||||
|
||||
event.button = sme;
|
||||
SDL_PushEvent(&event);
|
||||
}
|
||||
|
||||
void CGuiHandler::handleCurrentEvent( SDL_Event & current )
|
||||
{
|
||||
if(current.type == SDL_KEYDOWN || current.type == SDL_KEYUP)
|
||||
{
|
||||
@ -344,22 +423,78 @@ void CGuiHandler::handleCurrentEvent(const SDL_Event & current )
|
||||
it->textEdited(current.edit);
|
||||
}
|
||||
}
|
||||
//todo: muiltitouch
|
||||
else if(current.type == SDL_MOUSEBUTTONUP)
|
||||
{
|
||||
switch(current.button.button)
|
||||
if(!multifinger)
|
||||
{
|
||||
case SDL_BUTTON_LEFT:
|
||||
handleMouseButtonClick(lclickable, EIntObjMouseBtnType::LEFT, false);
|
||||
break;
|
||||
case SDL_BUTTON_RIGHT:
|
||||
handleMouseButtonClick(rclickable, EIntObjMouseBtnType::RIGHT, false);
|
||||
break;
|
||||
case SDL_BUTTON_MIDDLE:
|
||||
handleMouseButtonClick(mclickable, EIntObjMouseBtnType::MIDDLE, false);
|
||||
break;
|
||||
switch(current.button.button)
|
||||
{
|
||||
case SDL_BUTTON_LEFT:
|
||||
handleMouseButtonClick(lclickable, EIntObjMouseBtnType::LEFT, false);
|
||||
break;
|
||||
case SDL_BUTTON_RIGHT:
|
||||
handleMouseButtonClick(rclickable, EIntObjMouseBtnType::RIGHT, false);
|
||||
break;
|
||||
case SDL_BUTTON_MIDDLE:
|
||||
handleMouseButtonClick(mclickable, EIntObjMouseBtnType::MIDDLE, false);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if(current.type == SDL_FINGERMOTION)
|
||||
{
|
||||
if(isPointerRelativeMode)
|
||||
{
|
||||
fakeMoveCursor(current.tfinger.dx, current.tfinger.dy);
|
||||
}
|
||||
}
|
||||
else if(current.type == SDL_FINGERDOWN)
|
||||
{
|
||||
auto fingerCount = SDL_GetNumTouchFingers(current.tfinger.touchId);
|
||||
|
||||
multifinger = fingerCount > 1;
|
||||
|
||||
if(isPointerRelativeMode)
|
||||
{
|
||||
if(current.tfinger.x > 0.5)
|
||||
{
|
||||
bool isRightClick = current.tfinger.y < 0.5;
|
||||
|
||||
fakeMouseButtonEventRelativeMode(true, isRightClick);
|
||||
}
|
||||
}
|
||||
#ifndef VCMI_IOS
|
||||
else if(fingerCount == 2)
|
||||
{
|
||||
convertTouchToMouse(¤t);
|
||||
handleMouseMotion(current);
|
||||
handleMouseButtonClick(rclickable, EIntObjMouseBtnType::RIGHT, true);
|
||||
}
|
||||
#endif //VCMI_IOS
|
||||
}
|
||||
else if(current.type == SDL_FINGERUP)
|
||||
{
|
||||
auto fingerCount = SDL_GetNumTouchFingers(current.tfinger.touchId);
|
||||
|
||||
if(isPointerRelativeMode)
|
||||
{
|
||||
if(current.tfinger.x > 0.5)
|
||||
{
|
||||
bool isRightClick = current.tfinger.y < 0.5;
|
||||
|
||||
fakeMouseButtonEventRelativeMode(false, isRightClick);
|
||||
}
|
||||
}
|
||||
#ifndef VCMI_IOS
|
||||
else if(multifinger)
|
||||
{
|
||||
convertTouchToMouse(¤t);
|
||||
handleMouseMotion(current);
|
||||
handleMouseButtonClick(rclickable, EIntObjMouseBtnType::RIGHT, false);
|
||||
multifinger = fingerCount != 0;
|
||||
}
|
||||
#endif //VCMI_IOS
|
||||
}
|
||||
} //event end
|
||||
|
||||
void CGuiHandler::handleMouseButtonClick(CIntObjectList & interestedObjs, EIntObjMouseBtnType btn, bool isPressed)
|
||||
@ -431,20 +566,6 @@ void CGuiHandler::handleMoveInterested(const SDL_MouseMotionEvent & motion)
|
||||
}
|
||||
}
|
||||
|
||||
void CGuiHandler::fakeMouseMove()
|
||||
{
|
||||
SDL_Event event;
|
||||
SDL_MouseMotionEvent sme = {SDL_MOUSEMOTION, 0, 0, 0, 0, 0, 0, 0, 0};
|
||||
int x, y;
|
||||
|
||||
sme.state = SDL_GetMouseState(&x, &y);
|
||||
sme.x = x;
|
||||
sme.y = y;
|
||||
|
||||
event.motion = sme;
|
||||
SDL_PushEvent(&event);
|
||||
}
|
||||
|
||||
void CGuiHandler::renderFrame()
|
||||
{
|
||||
|
||||
@ -486,7 +607,8 @@ void CGuiHandler::renderFrame()
|
||||
|
||||
|
||||
CGuiHandler::CGuiHandler()
|
||||
: lastClick(-500, -500),lastClickTime(0), defActionsDef(0), captureChildren(false)
|
||||
: lastClick(-500, -500),lastClickTime(0), defActionsDef(0), captureChildren(false),
|
||||
multifinger(false)
|
||||
{
|
||||
continueEventHandling = true;
|
||||
curInt = nullptr;
|
||||
|
@ -92,9 +92,12 @@ private:
|
||||
|
||||
void handleMouseButtonClick(CIntObjectList & interestedObjs, EIntObjMouseBtnType btn, bool isPressed);
|
||||
void processLists(const ui16 activityFlag, std::function<void (std::list<CIntObject*> *)> cb);
|
||||
void handleCurrentEvent(const SDL_Event & current);
|
||||
void handleCurrentEvent(SDL_Event ¤t);
|
||||
void handleMouseMotion(const SDL_Event & current);
|
||||
void handleMoveInterested( const SDL_MouseMotionEvent & motion );
|
||||
void convertTouchToMouse(SDL_Event * current);
|
||||
void fakeMoveCursor(float dx, float dy);
|
||||
void fakeMouseButtonEventRelativeMode(bool down, bool right);
|
||||
|
||||
public:
|
||||
void handleElementActivate(CIntObject * elem, ui16 activityFlag);
|
||||
@ -110,6 +113,9 @@ public:
|
||||
|
||||
Point lastClick;
|
||||
unsigned lastClickTime;
|
||||
bool multifinger;
|
||||
bool isPointerRelativeMode;
|
||||
float pointerSpeedMultiplier;
|
||||
|
||||
ui8 defActionsDef; //default auto actions
|
||||
bool captureChildren; //all newly created objects will get their parents from stack and will be added to parents children list
|
||||
@ -118,6 +124,7 @@ public:
|
||||
CGuiHandler();
|
||||
~CGuiHandler();
|
||||
|
||||
void init();
|
||||
void renderFrame();
|
||||
|
||||
void totalRedraw(); //forces total redraw (using showAll), sets a flag, method gets called at the end of the rendering
|
||||
|
@ -889,22 +889,10 @@ SDL_Color CSDL_Ext::makeColor(ui8 r, ui8 g, ui8 b, ui8 a)
|
||||
|
||||
void CSDL_Ext::startTextInput(const Rect & whereInput)
|
||||
{
|
||||
const SDL_Rect where = CSDL_Ext::toSDL(whereInput);
|
||||
|
||||
auto impl = [](SDL_Rect where)
|
||||
{
|
||||
if (SDL_IsTextInputActive() == SDL_FALSE)
|
||||
{
|
||||
SDL_StartTextInput();
|
||||
}
|
||||
SDL_SetTextInputRect(&where);
|
||||
};
|
||||
|
||||
#ifdef VCMI_APPLE
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
#endif
|
||||
|
||||
#ifdef VCMI_IOS
|
||||
// TODO ios: looks like SDL bug actually, try fixing there
|
||||
auto renderer = SDL_GetRenderer(mainWindow);
|
||||
float scaleX, scaleY;
|
||||
@ -912,17 +900,25 @@ void CSDL_Ext::startTextInput(const Rect & whereInput)
|
||||
SDL_RenderGetScale(renderer, &scaleX, &scaleY);
|
||||
SDL_RenderGetViewport(renderer, &viewport);
|
||||
|
||||
#ifdef VCMI_IOS
|
||||
const auto nativeScale = iOS_utils::screenScale();
|
||||
auto rectInScreenCoordinates = where;
|
||||
rectInScreenCoordinates.x = (viewport.x + rectInScreenCoordinates.x) * scaleX / nativeScale;
|
||||
rectInScreenCoordinates.y = (viewport.y + rectInScreenCoordinates.y) * scaleY / nativeScale;
|
||||
rectInScreenCoordinates.w = rectInScreenCoordinates.w * scaleX / nativeScale;
|
||||
rectInScreenCoordinates.h = rectInScreenCoordinates.h * scaleY / nativeScale;
|
||||
impl(rectInScreenCoordinates);
|
||||
#else
|
||||
impl(where);
|
||||
scaleX /= nativeScale;
|
||||
scaleY /= nativeScale;
|
||||
#endif
|
||||
|
||||
SDL_Rect rectInScreenCoordinates;
|
||||
rectInScreenCoordinates.x = (viewport.x + whereInput.x) * scaleX;
|
||||
rectInScreenCoordinates.y = (viewport.y + whereInput.y) * scaleY;
|
||||
rectInScreenCoordinates.w = whereInput.w * scaleX;
|
||||
rectInScreenCoordinates.h = whereInput.h * scaleY;
|
||||
|
||||
SDL_SetTextInputRect(&rectInScreenCoordinates);
|
||||
|
||||
if (SDL_IsTextInputActive() == SDL_FALSE)
|
||||
{
|
||||
SDL_StartTextInput();
|
||||
}
|
||||
|
||||
#ifdef VCMI_APPLE
|
||||
});
|
||||
#endif
|
||||
|
@ -10,11 +10,13 @@
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
#include <SDL_events.h>
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@interface GameChatKeyboardHandler : NSObject
|
||||
|
||||
- (void)triggerInput;
|
||||
+ (void)sendKeyEventWithKeyCode:(SDL_KeyCode)keyCode;
|
||||
|
||||
@end
|
||||
|
||||
|
@ -10,20 +10,8 @@
|
||||
|
||||
#import "GameChatKeyboardHandler.h"
|
||||
|
||||
#include <SDL_events.h>
|
||||
|
||||
static int watchReturnKey(void * userdata, SDL_Event * event);
|
||||
|
||||
static void sendKeyEvent(SDL_KeyCode keyCode)
|
||||
{
|
||||
SDL_Event keyEvent;
|
||||
keyEvent.key = (SDL_KeyboardEvent){
|
||||
.type = SDL_KEYDOWN,
|
||||
.keysym.sym = keyCode,
|
||||
};
|
||||
SDL_PushEvent(&keyEvent);
|
||||
}
|
||||
|
||||
|
||||
@interface GameChatKeyboardHandler ()
|
||||
@property (nonatomic) BOOL wasChatMessageSent;
|
||||
@ -31,28 +19,40 @@ static void sendKeyEvent(SDL_KeyCode keyCode)
|
||||
|
||||
@implementation GameChatKeyboardHandler
|
||||
|
||||
- (void)triggerInput {
|
||||
+ (void)sendKeyEventWithKeyCode:(SDL_KeyCode)keyCode
|
||||
{
|
||||
SDL_Event keyEvent;
|
||||
keyEvent.key = (SDL_KeyboardEvent){
|
||||
.type = SDL_KEYDOWN,
|
||||
.state = SDL_PRESSED,
|
||||
.keysym.sym = keyCode,
|
||||
};
|
||||
SDL_PushEvent(&keyEvent);
|
||||
}
|
||||
|
||||
- (instancetype)init {
|
||||
self = [super init];
|
||||
|
||||
__auto_type notificationCenter = NSNotificationCenter.defaultCenter;
|
||||
[notificationCenter addObserver:self selector:@selector(textDidBeginEditing:) name:UITextFieldTextDidBeginEditingNotification object:nil];
|
||||
[notificationCenter addObserver:self selector:@selector(textDidEndEditing:) name:UITextFieldTextDidEndEditingNotification object:nil];
|
||||
|
||||
self.wasChatMessageSent = NO;
|
||||
sendKeyEvent(SDLK_TAB);
|
||||
return self;
|
||||
}
|
||||
|
||||
#pragma mark - Notifications
|
||||
|
||||
- (void)textDidBeginEditing:(NSNotification *)n {
|
||||
self.wasChatMessageSent = NO;
|
||||
|
||||
// watch for pressing Return to ignore sending Escape key after keyboard is closed
|
||||
SDL_AddEventWatch(watchReturnKey, (__bridge void *)self);
|
||||
}
|
||||
|
||||
- (void)textDidEndEditing:(NSNotification *)n {
|
||||
[NSNotificationCenter.defaultCenter removeObserver:self];
|
||||
|
||||
// discard chat message
|
||||
if(!self.wasChatMessageSent)
|
||||
sendKeyEvent(SDLK_ESCAPE);
|
||||
[[self class] sendKeyEventWithKeyCode:SDLK_ESCAPE];
|
||||
}
|
||||
|
||||
@end
|
||||
|
@ -95,7 +95,7 @@
|
||||
- (void)handlePinch:(UIGestureRecognizer *)gesture {
|
||||
if(gesture.state != UIGestureRecognizerStateBegan || CSH->state != EClientState::GAMEPLAY)
|
||||
return;
|
||||
[self.gameChatHandler triggerInput];
|
||||
[GameChatKeyboardHandler sendKeyEventWithKeyCode:SDLK_SPACE];
|
||||
}
|
||||
|
||||
#pragma mark - UIGestureRecognizerDelegate
|
||||
|
@ -177,7 +177,7 @@ void CTerrainRect::mouseMoved(const SDL_MouseMotionEvent & sEvent)
|
||||
void CTerrainRect::handleSwipeMove(const SDL_MouseMotionEvent & sEvent)
|
||||
{
|
||||
#if defined(VCMI_ANDROID) || defined(VCMI_IOS)
|
||||
if(sEvent.state == 0) // any "button" is enough on mobile
|
||||
if(sEvent.state == 0 || GH.multifinger) // any "button" is enough on mobile
|
||||
#else
|
||||
if((sEvent.state & SDL_BUTTON_MMASK) == 0) // swipe only works with middle mouse on other platforms
|
||||
#endif
|
||||
|
@ -101,7 +101,7 @@ void QuickRecruitmentWindow::maxAllCards(std::vector<std::shared_ptr<CreaturePur
|
||||
|
||||
void QuickRecruitmentWindow::purchaseUnits()
|
||||
{
|
||||
for(auto selected : cards)
|
||||
for(auto selected : boost::adaptors::reverse(cards))
|
||||
{
|
||||
if(selected->slider->getValue())
|
||||
{
|
||||
|
@ -17,7 +17,21 @@
|
||||
"type" : "object",
|
||||
"default": {},
|
||||
"additionalProperties" : false,
|
||||
"required" : [ "playerName", "showfps", "music", "sound", "encoding", "language", "swipe", "saveRandomMaps", "saveFrequency", "notifications", "extraDump" ],
|
||||
"required" : [
|
||||
"playerName",
|
||||
"showfps",
|
||||
"music",
|
||||
"sound",
|
||||
"encoding",
|
||||
"language",
|
||||
"swipe",
|
||||
"saveRandomMaps",
|
||||
"saveFrequency",
|
||||
"notifications",
|
||||
"extraDump",
|
||||
"userRelativePointer",
|
||||
"relativePointerSpeedMultiplier"
|
||||
],
|
||||
"properties" : {
|
||||
"playerName" : {
|
||||
"type":"string",
|
||||
@ -75,6 +89,14 @@
|
||||
"extraDump" : {
|
||||
"type" : "boolean",
|
||||
"default" : false
|
||||
},
|
||||
"userRelativePointer" : {
|
||||
"type" : "boolean",
|
||||
"default" : false
|
||||
},
|
||||
"relativePointerSpeedMultiplier" : {
|
||||
"type" : "number",
|
||||
"default" : 1
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -1,9 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
generatedZip="$1"
|
||||
if [[ -z "$generatedZip" ]]; then
|
||||
echo 'generated zip not provided as param'
|
||||
exit 1
|
||||
fi
|
||||
|
||||
mv "$generatedZip" "$(basename "$generatedZip" .zip).ipa"
|
@ -96,7 +96,7 @@ jclass CAndroidVMHelper::findClass(const std::string & name, bool classloaded)
|
||||
return get()->FindClass(name.c_str());
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL Java_eu_vcmi_vcmi_NativeMethods_initClassloader(JNIEnv * baseEnv, jobject * cls)
|
||||
extern "C" JNIEXPORT void JNICALL Java_eu_vcmi_vcmi_NativeMethods_initClassloader(JNIEnv * baseEnv, jclass cls)
|
||||
{
|
||||
CAndroidVMHelper::cacheVM(baseEnv);
|
||||
CAndroidVMHelper envHelper;
|
||||
|
@ -1583,7 +1583,7 @@ bool NBonus::hasOfType(const CBonusSystemNode *obj, Bonus::BonusType type, int s
|
||||
return false;
|
||||
}
|
||||
|
||||
std::string Bonus::Description() const
|
||||
std::string Bonus::Description(boost::optional<si32> customValue) const
|
||||
{
|
||||
std::ostringstream str;
|
||||
|
||||
@ -1622,8 +1622,8 @@ std::string Bonus::Description() const
|
||||
str << description;
|
||||
}
|
||||
|
||||
if(val != 0)
|
||||
str << " " << std::showpos << val;
|
||||
if(auto value = customValue.value_or(val))
|
||||
str << " " << std::showpos << value;
|
||||
|
||||
return str.str();
|
||||
}
|
||||
|
@ -510,7 +510,7 @@ struct DLL_LINKAGE Bonus : public std::enable_shared_from_this<Bonus>
|
||||
return (high << 16) + low;
|
||||
}
|
||||
|
||||
std::string Description() const;
|
||||
std::string Description(boost::optional<si32> customValue = {}) const;
|
||||
JsonNode toJsonNode() const;
|
||||
std::string nameForBonus() const; // generate suitable name for bonus - e.g. for storing in json struct
|
||||
|
||||
|
@ -554,24 +554,26 @@ GrowthInfo CGTownInstance::getGrowthInfo(int level) const
|
||||
if(hasBuilt(BuildingID::HORDE_2))
|
||||
ret.entries.push_back(GrowthInfo::Entry(subID, BuildingID::HORDE_2, creature->hordeGrowth));
|
||||
|
||||
int dwellingBonus = 0;
|
||||
if(const PlayerState *p = cb->getPlayerState(tempOwner, false))
|
||||
//statue-of-legion-like bonus: % to base+castle
|
||||
TConstBonusListPtr bonuses2 = getBonuses(Selector::type()(Bonus::CREATURE_GROWTH_PERCENT));
|
||||
for(const auto & b : *bonuses2)
|
||||
{
|
||||
dwellingBonus = getDwellingBonus(creatures[level].second, p->dwellings);
|
||||
const auto growth = b->val * (base + castleBonus) / 100;
|
||||
ret.entries.push_back(GrowthInfo::Entry(growth, b->Description(growth)));
|
||||
}
|
||||
|
||||
if(dwellingBonus)
|
||||
ret.entries.push_back(GrowthInfo::Entry(VLC->generaltexth->allTexts[591], dwellingBonus));// \nExternal dwellings %+d
|
||||
|
||||
//other *-of-legion-like bonuses (%d to growth cumulative with grail)
|
||||
TConstBonusListPtr bonuses = getBonuses(Selector::type()(Bonus::CREATURE_GROWTH).And(Selector::subtype()(level)));
|
||||
for(const auto & b : *bonuses)
|
||||
ret.entries.push_back(GrowthInfo::Entry(b->val, b->Description()));
|
||||
|
||||
//statue-of-legion-like bonus: % to base+castle
|
||||
TConstBonusListPtr bonuses2 = getBonuses(Selector::type()(Bonus::CREATURE_GROWTH_PERCENT));
|
||||
for(const auto & b : *bonuses2)
|
||||
ret.entries.push_back(GrowthInfo::Entry(b->val * (base + castleBonus) / 100, b->Description()));
|
||||
int dwellingBonus = 0;
|
||||
if(const PlayerState *p = cb->getPlayerState(tempOwner, false))
|
||||
{
|
||||
dwellingBonus = getDwellingBonus(creatures[level].second, p->dwellings);
|
||||
}
|
||||
if(dwellingBonus)
|
||||
ret.entries.push_back(GrowthInfo::Entry(VLC->generaltexth->allTexts[591], dwellingBonus));// \nExternal dwellings %+d
|
||||
|
||||
if(hasBuilt(BuildingID::GRAIL)) //grail - +50% to ALL (so far added) growth
|
||||
ret.entries.push_back(GrowthInfo::Entry(subID, BuildingID::GRAIL, ret.totalGrowth() / 2));
|
||||
|
@ -1326,10 +1326,10 @@ std::string CMapSaverJson::writeTerrainTile(const TerrainTile & tile)
|
||||
out << tile.terType->shortIdentifier << (int)tile.terView << flipCodes[tile.extTileFlags % 4];
|
||||
|
||||
if(tile.roadType->getId() != Road::NO_ROAD)
|
||||
out << tile.roadType << (int)tile.roadDir << flipCodes[(tile.extTileFlags >> 4) % 4];
|
||||
out << tile.roadType->shortIdentifier << (int)tile.roadDir << flipCodes[(tile.extTileFlags >> 4) % 4];
|
||||
|
||||
if(tile.riverType->getId() != River::NO_RIVER)
|
||||
out << tile.riverType << (int)tile.riverDir << flipCodes[(tile.extTileFlags >> 2) % 4];
|
||||
out << tile.riverType->shortIdentifier << (int)tile.riverDir << flipCodes[(tile.extTileFlags >> 2) % 4];
|
||||
|
||||
return out.str();
|
||||
}
|
||||
|
@ -28,6 +28,8 @@
|
||||
#include "../lib/mapping/CMap.h"
|
||||
#include "../lib/rmg/CMapGenOptions.h"
|
||||
#ifdef VCMI_ANDROID
|
||||
#include <jni.h>
|
||||
#include <android/log.h>
|
||||
#include "lib/CAndroidVMHelper.h"
|
||||
#elif !defined(VCMI_IOS)
|
||||
#include "../lib/Interprocess.h"
|
||||
@ -1122,12 +1124,21 @@ int main(int argc, char * argv[])
|
||||
}
|
||||
|
||||
#ifdef VCMI_ANDROID
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL Java_eu_vcmi_vcmi_NativeMethods_createServer(JNIEnv * env, jclass cls)
|
||||
{
|
||||
__android_log_write(ANDROID_LOG_INFO, "VCMI", "Got jni call to init server");
|
||||
CAndroidVMHelper::cacheVM(env);
|
||||
CVCMIServer::create();
|
||||
}
|
||||
|
||||
void CVCMIServer::create()
|
||||
{
|
||||
const char * foo = "android-server";
|
||||
std::vector<const void *> argv = {foo};
|
||||
main(argv.size(), reinterpret_cast<char **>(const_cast<void **>(&*argv.begin())));
|
||||
}
|
||||
|
||||
#elif defined(SINGLE_PROCESS_APP)
|
||||
void CVCMIServer::create(boost::condition_variable * cond, const std::vector<std::string> & args)
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user