mirror of
https://github.com/ZDoom/raze-gles.git
synced 2025-01-23 15:40:39 +00:00
Android UI work. DONT_BUILD.
git-svn-id: https://svn.eduke32.com/eduke32@5663 1a8010ca-5511-0410-912e-c29ae57300e0
This commit is contained in:
parent
18a8e840bb
commit
4ea156822d
8 changed files with 198 additions and 219 deletions
|
@ -1,52 +1,34 @@
|
||||||
# Copyright (C) 2009 The Android Open Source Project
|
|
||||||
#
|
|
||||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
# you may not use this file except in compliance with the License.
|
|
||||||
# You may obtain a copy of the License at
|
|
||||||
#
|
|
||||||
# http://www.apache.crg/licenses/LICENSE-2.0
|
|
||||||
#
|
|
||||||
# Unless required by applicable law or agreed to in writing, software
|
|
||||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
# See the License for the specific language governing permissions and
|
|
||||||
# limitations under the License.
|
|
||||||
#
|
|
||||||
LOCAL_PATH := $(call my-dir)
|
LOCAL_PATH := $(call my-dir)
|
||||||
|
|
||||||
include $(CLEAR_VARS)
|
include $(CLEAR_VARS)
|
||||||
|
|
||||||
LOCAL_MODULE := duke3d
|
LOCAL_MODULE := duke3d
|
||||||
|
|
||||||
# -O2 -fvisibility=hidden
|
LOCAL_CFLAGS := -x c++ -std=gnu++11 -fvisibility=hidden -fPIC -funsigned-char -fno-strict-aliasing -DNO_GCC_BUILTINS -pthread -DHAVE_INTTYPES -D_GNU_SOURCE=1 -D_REENTRANT
|
||||||
|
|
||||||
LOCAL_CFLAGS := -x c++ -std=gnu++11 -fvisibility=hidden -fPIC -fno-stack-protector -funsigned-char -fno-strict-aliasing -DNO_GCC_BUILTINS -D_FORTIFY_SOURCE=0 -pthread -DHAVE_INTTYPES -D_GNU_SOURCE=1 -D_REENTRANT
|
|
||||||
|
|
||||||
ifeq ($(NDK_DEBUG), 1)
|
ifeq ($(NDK_DEBUG), 1)
|
||||||
LOCAL_CFLAGS += -O0 -ggdb -fno-omit-frame-pointer
|
LOCAL_CFLAGS += -O0 -ggdb -fno-omit-frame-pointer -fno-stack-protector -D_FORTIFY_SOURCE=0
|
||||||
else
|
else
|
||||||
LOCAL_CFLAGS += -O2 -DNDEBUG -DUSING_LTO -flto
|
LOCAL_CFLAGS += -O2 -DNDEBUG -DUSING_LTO -flto -D_FORTIFY_SOURCE=2
|
||||||
endif
|
endif
|
||||||
|
|
||||||
LOCAL_CFLAGS += -W -Werror-implicit-function-declaration -Wpointer-arith -Wextra -Wno-unused-result -Wno-char-subscripts -Wno-strict-overflow -Wno-attributes -Wno-write-strings
|
|
||||||
LOCAL_CPPFLAGS := -std=gnu++11
|
LOCAL_CPPFLAGS := -std=gnu++11
|
||||||
|
|
||||||
|
LOCAL_CFLAGS += -W -Werror-implicit-function-declaration -Wpointer-arith -Wextra -Wno-unused-result -Wno-char-subscripts \
|
||||||
|
-Wno-strict-overflow -Wno-attributes -Wno-write-strings -mhard-float -D_NDK_MATH_NO_SOFTFP=1
|
||||||
LOCAL_CFLAGS += -DHAVE_SDL -DHAVE_VORBIS -DHAVE_JWZGLES -DHAVE_ANDROID -DRENDERTYPESDL=1 -DUSE_OPENGL -DNETCODE_DISABLE -DUSE_LIBVPX
|
LOCAL_CFLAGS += -DHAVE_SDL -DHAVE_VORBIS -DHAVE_JWZGLES -DHAVE_ANDROID -DRENDERTYPESDL=1 -DUSE_OPENGL -DNETCODE_DISABLE -DUSE_LIBVPX
|
||||||
|
|
||||||
LOCAL_CFLAGS += -mhard-float -D_NDK_MATH_NO_SOFTFP=1
|
|
||||||
|
|
||||||
LOCAL_LDFLAGS := -fuse-ld=bfd
|
LOCAL_LDFLAGS := -fuse-ld=bfd
|
||||||
TARGET_LDFLAGS += -Wl,--no-warn-mismatch -lm_hard
|
TARGET_LDFLAGS += -Wl,--no-warn-mismatch -lm_hard
|
||||||
LOCAL_ARM_NEON = true
|
LOCAL_ARM_NEON = true
|
||||||
|
|
||||||
LOCAL_C_INCLUDES := $(LOCAL_PATH)/source $(LOCAL_PATH)/source/jmact $(LOCAL_PATH)/source/jaudiolib/include $(LOCAL_PATH)/source/enet/include $(LOCAL_PATH)/build/include
|
LOCAL_C_INCLUDES := $(LOCAL_PATH)/source $(LOCAL_PATH)/source/jmact $(LOCAL_PATH)/source/jaudiolib/include $(LOCAL_PATH)/source/enet/include $(LOCAL_PATH)/build/include
|
||||||
LOCAL_C_INCLUDES += $(TOP_DIR)/ $(TOP_DIR)/Libraries/liboggvorbis/include $(TOP_DIR)/Libraries/ $(TOP_DIR)/Libraries/SDL2/include $(TOP_DIR)/Libraries/SDL2_mixer/include $(TOP_DIR)/Libraries/libpng/include $(TOP_DIR)/Libraries/TinyXML/include $(TOP_DIR)/TouchControls $(TOP_DIR)/Libraries/libvpx/include
|
LOCAL_C_INCLUDES += $(TOP_DIR)/ $(TOP_DIR)/Libraries/liboggvorbis/include $(TOP_DIR)/Libraries/ $(TOP_DIR)/Libraries/SDL2/include $(TOP_DIR)/Libraries/SDL2_mixer/include $(TOP_DIR)/Libraries/TinyXML/include $(TOP_DIR)/TouchControls $(TOP_DIR)/Libraries/libvpx/include
|
||||||
|
|
||||||
ANDROID_SRC = \
|
ANDROID_SRC = \
|
||||||
source/android/android-jni.cpp \
|
|
||||||
source/android/in_android.c \
|
|
||||||
build/src/jwzgles.c \
|
build/src/jwzgles.c \
|
||||||
source/android/rg_etc1.cpp
|
source/android/android-jni.cpp \
|
||||||
|
source/android/in_android.c
|
||||||
|
|
||||||
BUILD_SRC = \
|
BUILD_SRC = \
|
||||||
build/src/a-c.c \
|
build/src/a-c.c \
|
||||||
|
@ -79,12 +61,12 @@ BUILD_SRC = \
|
||||||
build/src/sdlayer.c
|
build/src/sdlayer.c
|
||||||
|
|
||||||
JMACT_SRC=source/jmact/file_lib.c \
|
JMACT_SRC=source/jmact/file_lib.c \
|
||||||
source/jmact//control.c \
|
source/jmact/control.c \
|
||||||
source/jmact//keyboard.c \
|
source/jmact/keyboard.c \
|
||||||
source/jmact//mouse.c \
|
source/jmact/mouse.c \
|
||||||
source/jmact//joystick.c \
|
source/jmact/joystick.c \
|
||||||
source/jmact//scriplib.c \
|
source/jmact/scriplib.c \
|
||||||
source/jmact//animlib.c
|
source/jmact/animlib.c
|
||||||
|
|
||||||
GAME_SRC=source/game.c \
|
GAME_SRC=source/game.c \
|
||||||
source/actors.c \
|
source/actors.c \
|
||||||
|
@ -121,17 +103,17 @@ GAME_SRC=source/game.c \
|
||||||
source/sbar.c
|
source/sbar.c
|
||||||
|
|
||||||
JAUDIO_SRC=source/jaudiolib/src/drivers.c \
|
JAUDIO_SRC=source/jaudiolib/src/drivers.c \
|
||||||
source/jaudiolib/src//fx_man.c \
|
source/jaudiolib/src/fx_man.c \
|
||||||
source/jaudiolib/src//multivoc.c \
|
source/jaudiolib/src/multivoc.c \
|
||||||
source/jaudiolib/src//mix.c \
|
source/jaudiolib/src/mix.c \
|
||||||
source/jaudiolib/src//mixst.c \
|
source/jaudiolib/src/mixst.c \
|
||||||
source/jaudiolib/src//pitch.c \
|
source/jaudiolib/src/pitch.c \
|
||||||
source/jaudiolib/src//formats.c \
|
source/jaudiolib/src/formats.c \
|
||||||
source/jaudiolib/src//vorbis.c \
|
source/jaudiolib/src/vorbis.c \
|
||||||
source/jaudiolib/src//flac.c \
|
source/jaudiolib/src/flac.c \
|
||||||
source/jaudiolib/src//xa.c \
|
source/jaudiolib/src/xa.c \
|
||||||
source/jaudiolib/src//driver_nosound.c \
|
source/jaudiolib/src/driver_nosound.c \
|
||||||
source/jaudiolib/src//driver_sdl.c
|
source/jaudiolib/src/driver_sdl.c
|
||||||
|
|
||||||
|
|
||||||
ENET_SRC=source/enet/src/callbacks.c \
|
ENET_SRC=source/enet/src/callbacks.c \
|
||||||
|
@ -148,12 +130,5 @@ LOCAL_SRC_FILES = $(ANDROID_SRC) $(JAUDIO_SRC) $(JMACT_SRC) $(GAME_SRC) $(BUILD_
|
||||||
LOCAL_LDLIBS := -lGLESv1_CM -lEGL -ldl -llog
|
LOCAL_LDLIBS := -lGLESv1_CM -lEGL -ldl -llog
|
||||||
LOCAL_STATIC_LIBRARIES := touch
|
LOCAL_STATIC_LIBRARIES := touch
|
||||||
LOCAL_SHARED_LIBRARIES := ogg vorbis SDL2 SDL2_mixer libvpx
|
LOCAL_SHARED_LIBRARIES := ogg vorbis SDL2 SDL2_mixer libvpx
|
||||||
# SDL2_image
|
|
||||||
|
|
||||||
include $(BUILD_SHARED_LIBRARY)
|
include $(BUILD_SHARED_LIBRARY)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -369,9 +369,11 @@ static int32_t osdfunc_setrendermode(const osdfuncparm_t *parm)
|
||||||
case REND_POLYMOST:
|
case REND_POLYMOST:
|
||||||
renderer = "polygonal OpenGL";
|
renderer = "polygonal OpenGL";
|
||||||
break;
|
break;
|
||||||
|
#ifdef POLYMER
|
||||||
case REND_POLYMER:
|
case REND_POLYMER:
|
||||||
renderer = "great justice (Polymer)";
|
renderer = "great justice (Polymer)";
|
||||||
break;
|
break;
|
||||||
|
#endif
|
||||||
default:
|
default:
|
||||||
EDUKE32_UNREACHABLE_SECTION(break);
|
EDUKE32_UNREACHABLE_SECTION(break);
|
||||||
}
|
}
|
||||||
|
@ -556,7 +558,9 @@ int32_t baselayer_init(void)
|
||||||
"Mode numbers are:\n"
|
"Mode numbers are:\n"
|
||||||
" 0 - Classic Build software\n"
|
" 0 - Classic Build software\n"
|
||||||
" 3 - Polygonal OpenGL\n"
|
" 3 - Polygonal OpenGL\n"
|
||||||
|
#ifdef POLYMER
|
||||||
" 4 - Great justice renderer (Polymer)\n"
|
" 4 - Great justice renderer (Polymer)\n"
|
||||||
|
#endif
|
||||||
,
|
,
|
||||||
osdfunc_setrendermode);
|
osdfunc_setrendermode);
|
||||||
|
|
||||||
|
|
|
@ -357,6 +357,7 @@ int sdlayer_mobilefilter(void *userdata, SDL_Event *event)
|
||||||
mobile_halted = 1;
|
mobile_halted = 1;
|
||||||
return 0;
|
return 0;
|
||||||
case SDL_APP_DIDENTERBACKGROUND:
|
case SDL_APP_DIDENTERBACKGROUND:
|
||||||
|
gltexinvalidatetype(INVALIDATE_ALL);
|
||||||
// tear down video?
|
// tear down video?
|
||||||
return 0;
|
return 0;
|
||||||
case SDL_APP_WILLENTERFOREGROUND:
|
case SDL_APP_WILLENTERFOREGROUND:
|
||||||
|
@ -1253,7 +1254,7 @@ void sdlayer_setvideomode_opengl(void)
|
||||||
|
|
||||||
bglEnable(GL_TEXTURE_2D);
|
bglEnable(GL_TEXTURE_2D);
|
||||||
bglShadeModel(GL_SMOOTH); // GL_FLAT
|
bglShadeModel(GL_SMOOTH); // GL_FLAT
|
||||||
bglClearColor(0, 0, 0, 0.5); // Black Background
|
bglClearColor(0, 0, 0, 1.0); // Black Background
|
||||||
bglHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); // Use FASTEST for ortho!
|
bglHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); // Use FASTEST for ortho!
|
||||||
// bglHint(GL_LINE_SMOOTH_HINT, GL_NICEST);
|
// bglHint(GL_LINE_SMOOTH_HINT, GL_NICEST);
|
||||||
|
|
||||||
|
@ -2186,7 +2187,6 @@ int32_t handleevents_pollsdl(void)
|
||||||
int32_t handleevents(void)
|
int32_t handleevents(void)
|
||||||
{
|
{
|
||||||
#ifdef __ANDROID__
|
#ifdef __ANDROID__
|
||||||
extern int mobile_halted;
|
|
||||||
if (mobile_halted) return 0;
|
if (mobile_halted) return 0;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -54,7 +54,6 @@ static bool hasTouch = false;
|
||||||
static bool weaponWheelVisible = false;
|
static bool weaponWheelVisible = false;
|
||||||
static bool hwScaling = false;
|
static bool hwScaling = false;
|
||||||
static bool controlsCreated = false;
|
static bool controlsCreated = false;
|
||||||
static bool backButtonEnabled = true;
|
|
||||||
|
|
||||||
TouchControlsContainer controlsContainer;
|
TouchControlsContainer controlsContainer;
|
||||||
|
|
||||||
|
@ -69,9 +68,9 @@ TouchControls *tcAutomap;
|
||||||
TouchStick *touchJoyLeft;
|
TouchStick *touchJoyLeft;
|
||||||
WheelSelect *weaponWheel;
|
WheelSelect *weaponWheel;
|
||||||
|
|
||||||
Button *inv_buttons[GET_MAX];
|
Button *invButtonPtrs[GET_MAX];
|
||||||
|
|
||||||
std::string obbPath, gamePath;
|
std::string gamePath;
|
||||||
|
|
||||||
void AndroidPreDrawButtons()
|
void AndroidPreDrawButtons()
|
||||||
{
|
{
|
||||||
|
@ -124,8 +123,7 @@ void AndroidShowWheel(bool show)
|
||||||
|
|
||||||
// Show inventory buttons
|
// Show inventory buttons
|
||||||
tcGameWeapons->setAllButtonsEnabled(true);
|
tcGameWeapons->setAllButtonsEnabled(true);
|
||||||
tcGameWeapons->fade(FADE_IN, 5);
|
// tcGameWeapons->fade(FADE_IN, 5);
|
||||||
|
|
||||||
weaponWheelVisible = true;
|
weaponWheelVisible = true;
|
||||||
|
|
||||||
AndroidTimer(0);
|
AndroidTimer(0);
|
||||||
|
@ -180,8 +178,8 @@ namespace callbacks
|
||||||
{
|
{
|
||||||
if (!weaponWheelVisible)
|
if (!weaponWheelVisible)
|
||||||
{
|
{
|
||||||
weaponWheel->setTapMode(true);
|
|
||||||
AndroidShowWheel(true);
|
AndroidShowWheel(true);
|
||||||
|
weaponWheel->setTapMode(true);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -217,12 +215,13 @@ namespace callbacks
|
||||||
|
|
||||||
void menu_button(int state, int code)
|
void menu_button(int state, int code)
|
||||||
{
|
{
|
||||||
|
if (weaponWheelVisible)
|
||||||
|
AndroidShowWheel(false);
|
||||||
|
|
||||||
AndroidKeyEvent(state, code, code);
|
AndroidKeyEvent(state, code, code);
|
||||||
|
|
||||||
if (controlsContainer.editingControls)
|
if (controlsContainer.editingControls)
|
||||||
controlsContainer.editorButtonPress();
|
controlsContainer.editorButtonPress();
|
||||||
|
|
||||||
AndroidShowWheel(false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void menu_select(int action, float x, float y, float dx, float dy)
|
void menu_select(int action, float x, float y, float dx, float dy)
|
||||||
|
@ -336,58 +335,62 @@ void AndroidTouchInit(int width, int height, const char *graphics_path)
|
||||||
///////////////////////// BLANK TAP SCREEN //////////////////////
|
///////////////////////// BLANK TAP SCREEN //////////////////////
|
||||||
|
|
||||||
// One button on whole screen with no graphic, send a return key
|
// One button on whole screen with no graphic, send a return key
|
||||||
tcBlankTap->addControl(new Button("whole_screen", RectF(0, 0, 26, 16), "", SDL_SCANCODE_RETURN));
|
tcBlankTap->addControl(new Button("whole_screen", RectF(0, 0, ScaleX, ScaleY), "", SDL_SCANCODE_RETURN));
|
||||||
tcBlankTap->signal_button.connect(sigc::ptr_fun(&callbacks::proceed));
|
tcBlankTap->signal_button.connect(sigc::ptr_fun(&callbacks::proceed));
|
||||||
|
|
||||||
|
|
||||||
///////////////////////// YES NO SCREEN /////////////////////
|
///////////////////////// YES NO SCREEN /////////////////////
|
||||||
|
|
||||||
tcYesNo->addControl(new Button("enter", RectF(16, 9, 18, 11), "button_yes", SDL_SCANCODE_RETURN));
|
tcYesNo->addControl(new Button("enter", RectF(37, 19, 43, 25), "button_yes", SDL_SCANCODE_RETURN));
|
||||||
tcYesNo->addControl(new Button("esc", RectF(8, 9, 10, 11), "button_no", SDL_SCANCODE_ESCAPE));
|
tcYesNo->addControl(new Button("esc", RectF(21, 19, 27, 25), "button_no", SDL_SCANCODE_ESCAPE));
|
||||||
tcYesNo->signal_button.connect(sigc::ptr_fun(&callbacks::menu_button));
|
tcYesNo->signal_button.connect(sigc::ptr_fun(&callbacks::menu_button));
|
||||||
|
|
||||||
|
|
||||||
// menu and shared back button
|
// menu and shared back button
|
||||||
|
|
||||||
MultitouchMouse *mouseMenu = new MultitouchMouse("mouse", RectF(0, 0, 26, 16), "");
|
MultitouchMouse *mouseMenu = new MultitouchMouse("mouse", RectF(0, 0, ScaleX, ScaleY), "");
|
||||||
mouseMenu->signal_action.connect(sigc::ptr_fun(&callbacks::menu_select));
|
mouseMenu->signal_action.connect(sigc::ptr_fun(&callbacks::menu_select));
|
||||||
mouseMenu->setHideGraphics(true);
|
mouseMenu->setHideGraphics(true);
|
||||||
tcMenuMain->addControl(mouseMenu);
|
tcMenuMain->addControl(mouseMenu);
|
||||||
|
|
||||||
Button *console_button = new Button("keyboard", "Development console", RectF(8, 0, 10, 2), "button_console", KEY_SHOW_KBRD, false, true);
|
Button *consoleButton = new Button("keyboard", "Development console", RectF(4, 0, 8, 4), "button_console", KEY_SHOW_KBRD, false, true);
|
||||||
tcMenuMain->addControl(console_button);
|
tcMenuMain->addControl(consoleButton);
|
||||||
|
|
||||||
tcBackButton->addControl(new Button("menu_back", RectF(0, 0, 2, 2), "button_left", SDL_SCANCODE_ESCAPE));
|
tcBackButton->addControl(new Button("menu_back", RectF(0, 0, 4, 4), "button_left", SDL_SCANCODE_ESCAPE));
|
||||||
tcBackButton->signal_button.connect(sigc::ptr_fun(&callbacks::menu_button));
|
tcBackButton->signal_button.connect(sigc::ptr_fun(&callbacks::menu_button));
|
||||||
|
|
||||||
// main controls
|
// main controls
|
||||||
|
|
||||||
tcGameMain->addControl(new Button("use", RectF(20, 4, 23, 7), "button_use", gamefunc_Open));
|
tcGameMain->addControl(new Button("menu_game", RectF(0, 0, 4, 4), "button_menu", SDL_SCANCODE_ESCAPE));
|
||||||
tcGameMain->addControl(new Button("fire", RectF(20, 7, 23, 10), "button_fire", gamefunc_Fire));
|
tcGameMain->signal_button.connect(sigc::ptr_fun(&callbacks::menu_button));
|
||||||
tcGameMain->addControl(new Button("jump", RectF(23, 6, 26, 9), "button_jump", gamefunc_Jump));
|
|
||||||
tcGameMain->addControl(new Button("crouch", RectF(24, 12, 26, 14), "button_crouch", gamefunc_Crouch));
|
|
||||||
tcGameMain->addControl(new Button("kick", "Mighty Foot", RectF(23, 3, 26, 6), "button_kick", gamefunc_Quick_Kick, false, true));
|
|
||||||
|
|
||||||
Button *map_button = new Button("map", "Overhead map", RectF(6, 0, 8, 2), "button_map", gamefunc_Map, false, true);
|
tcGameMain->addControl(new Button("use", RectF(50, 14, 55, 19), "button_use", gamefunc_Open));
|
||||||
tcGameMain->addControl(map_button);
|
tcGameMain->addControl(new Button("fire", RectF(50, 20, 55, 25), "button_fire", gamefunc_Fire));
|
||||||
|
tcGameMain->addControl(new Button("jump", RectF(56, 17, 61, 22), "button_jump", gamefunc_Jump));
|
||||||
|
tcGameMain->addControl(new Button("kick", "Mighty Foot", RectF(56, 11, 61, 16), "button_kick", gamefunc_Quick_Kick, false, true));
|
||||||
|
|
||||||
Button *inv_button = new Button("show_inventory", "Inventory", RectF(24, 0, 26, 2), "button_activate", KEY_SHOW_INVEN);
|
tcGameMain->addControl(new Button("crouch", RectF(59, ScaleY - 5, 62, ScaleY - 2), "button_crouch", gamefunc_Crouch));
|
||||||
tcGameMain->addControl(inv_button);
|
|
||||||
|
Button *mapButton = new Button("map", "Overhead map", RectF(6, 0, 8, 2), "button_map", gamefunc_Map, false, true);
|
||||||
|
tcGameMain->addControl(mapButton);
|
||||||
|
|
||||||
|
Button *invButton = new Button("show_inventory", "Inventory", RectF(60, 0, 64, 4), "button_inv", KEY_SHOW_INVEN);
|
||||||
|
tcGameMain->addControl(invButton);
|
||||||
tcGameMain->addControl(new Button("next_weapon", "Next weapon", RectF(0, 3, 3, 5), "button_up", gamefunc_Next_Weapon, false, true));
|
tcGameMain->addControl(new Button("next_weapon", "Next weapon", RectF(0, 3, 3, 5), "button_up", gamefunc_Next_Weapon, false, true));
|
||||||
tcGameMain->addControl(new Button("prev_weapon", "Previous weapon", RectF(0, 5, 3, 7), "button_down", gamefunc_Previous_Weapon, false, true));
|
tcGameMain->addControl(new Button("prev_weapon", "Previous weapon", RectF(0, 5, 3, 7), "button_down", gamefunc_Previous_Weapon, false, true));
|
||||||
tcGameMain->addControl(new Button("quick_save", "Save game", RectF(22, 0, 24, 2), "button_save", KEY_QUICK_SAVE, false, true));
|
tcGameMain->addControl(new Button("quick_save", "Save game", RectF(22, 0, 24, 2), "button_save", KEY_QUICK_SAVE, false, true));
|
||||||
tcGameMain->addControl(new Button("quick_load", "Load game", RectF(20, 0, 22, 2), "button_load", KEY_QUICK_LOAD, false, true));
|
tcGameMain->addControl(new Button("quick_load", "Load game", RectF(20, 0, 22, 2), "button_load", KEY_QUICK_LOAD, false, true));
|
||||||
|
|
||||||
tcGameMain->addControl(console_button);
|
tcGameMain->addControl(consoleButton);
|
||||||
|
|
||||||
// Left stick
|
// Left stick
|
||||||
touchJoyLeft = new TouchStick("stick", RectF(0, 8, 8, 16), "button_move");
|
touchJoyLeft = new TouchStick("stick", RectF(4, ScaleY - 20, 24, ScaleY), "button_move");
|
||||||
tcGameMain->addControl(touchJoyLeft);
|
tcGameMain->addControl(touchJoyLeft);
|
||||||
touchJoyLeft->signal_move.connect(sigc::ptr_fun(&callbacks::move));
|
touchJoyLeft->signal_move.connect(sigc::ptr_fun(&callbacks::move));
|
||||||
touchJoyLeft->signal_double_tap.connect(sigc::ptr_fun(&callbacks::left_double_tap));
|
touchJoyLeft->signal_double_tap.connect(sigc::ptr_fun(&callbacks::left_double_tap));
|
||||||
|
|
||||||
// Mouse look for whole screen
|
// Mouse look for whole screen
|
||||||
Mouse *mouse = new Mouse("mouse", RectF(3, 0, 26, 16), "");
|
Mouse *mouse = new Mouse("mouse", RectF(3, 0, ScaleX, ScaleY), "");
|
||||||
mouse->signal_action.connect(sigc::ptr_fun(&callbacks::look));
|
mouse->signal_action.connect(sigc::ptr_fun(&callbacks::look));
|
||||||
mouse->signal_double_tap.connect(sigc::ptr_fun(&callbacks::right_double_tap));
|
mouse->signal_double_tap.connect(sigc::ptr_fun(&callbacks::right_double_tap));
|
||||||
|
|
||||||
|
@ -397,33 +400,33 @@ void AndroidTouchInit(int width, int height, const char *graphics_path)
|
||||||
tcGameMain->signal_button.connect(sigc::ptr_fun(&callbacks::in_game));
|
tcGameMain->signal_button.connect(sigc::ptr_fun(&callbacks::in_game));
|
||||||
|
|
||||||
// Automap
|
// Automap
|
||||||
MultitouchMouse *multimouse = new MultitouchMouse("gamemouse", RectF(0, 0, 26, 16), "");
|
MultitouchMouse *mapMouse = new MultitouchMouse("gamemouse", RectF(0, 0, ScaleX, ScaleY), "");
|
||||||
multimouse->setHideGraphics(true);
|
mapMouse->setHideGraphics(true);
|
||||||
tcAutomap->addControl(multimouse);
|
tcAutomap->addControl(mapMouse);
|
||||||
multimouse->signal_action.connect(sigc::ptr_fun(&callbacks::automap_multitouch_mouse_move));
|
mapMouse->signal_action.connect(sigc::ptr_fun(&callbacks::automap_multitouch_mouse_move));
|
||||||
tcAutomap->addControl(map_button);
|
tcAutomap->addControl(mapButton);
|
||||||
tcAutomap->signal_button.connect(sigc::ptr_fun(&callbacks::in_game));
|
tcAutomap->signal_button.connect(sigc::ptr_fun(&callbacks::in_game));
|
||||||
tcAutomap->setAlpha(0.5);
|
tcAutomap->setAlpha(0.5);
|
||||||
|
|
||||||
// Weapons
|
// Weapons
|
||||||
// Now inventory in the weapons control group!
|
// Now inventory in the weapons control group!
|
||||||
|
|
||||||
weaponWheel = new WheelSelect("weapon_wheel", RectF(7, 2, 19, 14), "weapon_wheel_orange_blank", 10);
|
weaponWheel = new WheelSelect("weapon_wheel", RectF(17, (ScaleY / 2) - 15, 47, (ScaleY / 2) + 15), "weapon_wheel_orange_blank", 10);
|
||||||
weaponWheel->signal_selected.connect(sigc::ptr_fun(&callbacks::select_weapon));
|
weaponWheel->signal_selected.connect(sigc::ptr_fun(&callbacks::select_weapon));
|
||||||
weaponWheel->signal_enabled.connect(sigc::ptr_fun(&callbacks::show_wheel));
|
weaponWheel->signal_enabled.connect(sigc::ptr_fun(&callbacks::show_wheel));
|
||||||
tcGameWeapons->addControl(weaponWheel);
|
tcGameWeapons->addControl(weaponWheel);
|
||||||
|
|
||||||
inv_buttons[GET_FIRSTAID] = new Button("medkit", RectF(0, 5, 2, 7), "button_inv1", gamefunc_MedKit, false, false, true);
|
invButtonPtrs[GET_JETPACK] = new Button("jetpack", RectF(0, 6, 4, 10), "button_inv4", gamefunc_Jetpack, false, false, true);
|
||||||
inv_buttons[GET_STEROIDS] = new Button("steroids", RectF(0, 11, 2, 13), "button_inv2", gamefunc_Steroids, false, false, true);
|
invButtonPtrs[GET_STEROIDS] = new Button("steroids", RectF(0, 11, 4, 15), "button_inv2", gamefunc_Steroids, false, false, true);
|
||||||
inv_buttons[GET_HOLODUKE] = new Button("holoduke", RectF(0, 9, 2, 11), "button_inv3", gamefunc_Holo_Duke, false, false, true);
|
invButtonPtrs[GET_HEATS] = new Button("nightv", RectF(0, 16, 4, 20), "button_inv5", gamefunc_NightVision, false, false, true);
|
||||||
inv_buttons[GET_JETPACK] = new Button("jetpack", RectF(0, 3, 2, 5), "button_inv4", gamefunc_Jetpack, false, false, true);
|
invButtonPtrs[GET_HOLODUKE] = new Button("holoduke", RectF(0, 21, 4, 25), "button_inv3", gamefunc_Holo_Duke, false, false, true);
|
||||||
inv_buttons[GET_HEATS] = new Button("nightv", RectF(0, 7, 2, 9), "button_inv5", gamefunc_NightVision, false, false, true);
|
invButtonPtrs[GET_FIRSTAID] = new Button("medkit", RectF(0, 26, 4, 30), "button_inv1", gamefunc_MedKit, false, false, true);
|
||||||
|
|
||||||
tcGameWeapons->addControl(inv_buttons[GET_JETPACK]);
|
tcGameWeapons->addControl(invButtonPtrs[GET_JETPACK]);
|
||||||
tcGameWeapons->addControl(inv_buttons[GET_FIRSTAID]);
|
tcGameWeapons->addControl(invButtonPtrs[GET_FIRSTAID]);
|
||||||
tcGameWeapons->addControl(inv_buttons[GET_HEATS]);
|
tcGameWeapons->addControl(invButtonPtrs[GET_HEATS]);
|
||||||
tcGameWeapons->addControl(inv_buttons[GET_HOLODUKE]);
|
tcGameWeapons->addControl(invButtonPtrs[GET_HOLODUKE]);
|
||||||
tcGameWeapons->addControl(inv_buttons[GET_STEROIDS]);
|
tcGameWeapons->addControl(invButtonPtrs[GET_STEROIDS]);
|
||||||
|
|
||||||
// Inventory are the only buttons so safe to do this
|
// Inventory are the only buttons so safe to do this
|
||||||
tcGameWeapons->signal_button.connect(sigc::ptr_fun(&callbacks::inv_button));
|
tcGameWeapons->signal_button.connect(sigc::ptr_fun(&callbacks::inv_button));
|
||||||
|
@ -442,6 +445,8 @@ void AndroidTouchInit(int width, int height, const char *graphics_path)
|
||||||
tcGameWeapons->resetOutput();
|
tcGameWeapons->resetOutput();
|
||||||
tcGameWeapons->setAllButtonsEnabled(false);
|
tcGameWeapons->setAllButtonsEnabled(false);
|
||||||
weaponWheel->setTapMode(false);
|
weaponWheel->setTapMode(false);
|
||||||
|
int segmap[10] ={ 3, 4, 5, 6, 7, 8, 9, 0, 1, 2 };
|
||||||
|
weaponWheel->setSegmentMap(segmap);
|
||||||
weaponWheelVisible = false;
|
weaponWheelVisible = false;
|
||||||
tcMenuMain->setAlpha(droidinput.gameControlsAlpha);
|
tcMenuMain->setAlpha(droidinput.gameControlsAlpha);
|
||||||
tcBackButton->setAlpha(droidinput.gameControlsAlpha);
|
tcBackButton->setAlpha(droidinput.gameControlsAlpha);
|
||||||
|
@ -485,7 +490,6 @@ void updateTouchScreenMode(touchscreemode_t mode)
|
||||||
break;
|
break;
|
||||||
case TOUCH_SCREEN_GAME:
|
case TOUCH_SCREEN_GAME:
|
||||||
tcGameMain->resetOutput();
|
tcGameMain->resetOutput();
|
||||||
|
|
||||||
tcGameMain->fade(FADE_OUT, DEFAULT_FADE_FRAMES);
|
tcGameMain->fade(FADE_OUT, DEFAULT_FADE_FRAMES);
|
||||||
tcGameWeapons->setEnabled(false);
|
tcGameWeapons->setEnabled(false);
|
||||||
break;
|
break;
|
||||||
|
@ -500,7 +504,9 @@ void updateTouchScreenMode(touchscreemode_t mode)
|
||||||
switch (mode)
|
switch (mode)
|
||||||
{
|
{
|
||||||
case TOUCH_SCREEN_BLANK: // Does not exist yet break;
|
case TOUCH_SCREEN_BLANK: // Does not exist yet break;
|
||||||
case TOUCH_SCREEN_BLANK_TAP: tcBlankTap->setEnabled(true); break;
|
case TOUCH_SCREEN_BLANK_TAP:
|
||||||
|
tcBlankTap->setEnabled(true);
|
||||||
|
break;
|
||||||
case TOUCH_SCREEN_YES_NO:
|
case TOUCH_SCREEN_YES_NO:
|
||||||
tcYesNo->setEnabled(true);
|
tcYesNo->setEnabled(true);
|
||||||
tcYesNo->fade(FADE_IN, DEFAULT_FADE_FRAMES);
|
tcYesNo->fade(FADE_IN, DEFAULT_FADE_FRAMES);
|
||||||
|
@ -530,8 +536,7 @@ void updateTouchScreenMode(touchscreemode_t mode)
|
||||||
lastMode = mode;
|
lastMode = mode;
|
||||||
}
|
}
|
||||||
|
|
||||||
backButtonEnabled = !tcBlankTap->enabled && mode != TOUCH_SCREEN_MENU_NOBACK;
|
tcBackButton->setEnabled(!tcBlankTap->enabled && mode != TOUCH_SCREEN_MENU_NOBACK && mode != TOUCH_SCREEN_GAME);
|
||||||
tcBackButton->setEnabled(backButtonEnabled);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
extern char videomodereset;
|
extern char videomodereset;
|
||||||
|
@ -573,21 +578,28 @@ void AndroidDrawControls()
|
||||||
if (tcBackButton)
|
if (tcBackButton)
|
||||||
tcBackButton->setAlpha(droidinput.gameControlsAlpha);
|
tcBackButton->setAlpha(droidinput.gameControlsAlpha);
|
||||||
|
|
||||||
int inv = AndroidRead(R_PLAYER_INV_AMOUNT);
|
|
||||||
|
|
||||||
if (tcGameWeapons)
|
if (tcGameWeapons)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < GET_MAX; ++i)
|
|
||||||
if (inv_buttons[i])
|
|
||||||
inv_buttons[i]->setAlpha(tcGameWeapons->getFadedAlpha() * ((inv & (1 << i)) ? 1.f : 0.3f));
|
|
||||||
|
|
||||||
tcGameWeapons->setAlpha(droidinput.gameControlsAlpha);
|
tcGameWeapons->setAlpha(droidinput.gameControlsAlpha);
|
||||||
|
|
||||||
|
int inv = AndroidRead(R_PLAYER_INV_AMOUNT);
|
||||||
|
|
||||||
|
for (int i = 0; i < GET_MAX; ++i)
|
||||||
|
if (invButtonPtrs[i])
|
||||||
|
{
|
||||||
|
if (!weaponWheelVisible)
|
||||||
|
invButtonPtrs[i]->setEnabled((inv & (1 << i)));
|
||||||
|
|
||||||
|
invButtonPtrs[i]->setAlpha(tcGameWeapons->getFadedAlpha() * ((inv & (1 << i)) ? 1.f : 0.3f));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
controlsContainer.draw();
|
controlsContainer.draw();
|
||||||
|
|
||||||
|
/*
|
||||||
if (controlsContainer.editingControls)
|
if (controlsContainer.editingControls)
|
||||||
tcBackButton->draw();
|
tcBackButton->draw();
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -625,11 +637,6 @@ jint EXPORT_ME Java_com_voidpoint_duke3d_NativeLib_i(JNIEnv *env, jobject thiz,
|
||||||
|
|
||||||
LOGI("duke3d_path = %s", getGamePath());
|
LOGI("duke3d_path = %s", getGamePath());
|
||||||
|
|
||||||
const char *p = env->GetStringUTFChars(graphics_dir, NULL);
|
|
||||||
obbPath = std::string(p);
|
|
||||||
|
|
||||||
LOGI("obbPath = %s", obbPath.c_str());
|
|
||||||
|
|
||||||
if (hasTouch)
|
if (hasTouch)
|
||||||
AndroidTouchInit(droidinfo.screen_width, droidinfo.screen_height, "/assets/");
|
AndroidTouchInit(droidinfo.screen_width, droidinfo.screen_height, "/assets/");
|
||||||
else LOGI("skipping touch input");
|
else LOGI("skipping touch input");
|
||||||
|
@ -665,12 +672,12 @@ Java_com_voidpoint_duke3d_NativeLib_kp(JNIEnv *env, jobject obj, jint down, jint
|
||||||
void EXPORT_ME Java_com_voidpoint_duke3d_NativeLib_te(JNIEnv *env, jobject obj, jint action, jint pid,
|
void EXPORT_ME Java_com_voidpoint_duke3d_NativeLib_te(JNIEnv *env, jobject obj, jint action, jint pid,
|
||||||
jfloat x, jfloat y)
|
jfloat x, jfloat y)
|
||||||
{
|
{
|
||||||
if (tcBackButton && backButtonEnabled)
|
if (tcBackButton && tcBackButton->enabled)
|
||||||
tcBackButton->processPointer(action, pid, x, y);
|
{
|
||||||
|
if (!tcBackButton->processPointer(action, pid, x, y))
|
||||||
// LOGI("TOUCHED");
|
|
||||||
controlsContainer.processPointer(action, pid, x, y);
|
controlsContainer.processPointer(action, pid, x, y);
|
||||||
|
}
|
||||||
|
else controlsContainer.processPointer(action, pid, x, y);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -701,8 +708,7 @@ void EXPORT_ME Java_com_voidpoint_duke3d_NativeLib_al(JNIEnv *env, jobject obj,
|
||||||
AndroidLookJoystick(yaw, pitch);
|
AndroidLookJoystick(yaw, pitch);
|
||||||
}
|
}
|
||||||
|
|
||||||
void EXPORT_ME
|
void EXPORT_ME Java_com_voidpoint_duke3d_NativeLib_sts(JNIEnv *env, jobject obj, int other)
|
||||||
Java_com_voidpoint_duke3d_NativeLib_sts(JNIEnv *env, jobject obj, int other)
|
|
||||||
{
|
{
|
||||||
// TODO: defined names for these values
|
// TODO: defined names for these values
|
||||||
hasTouch = other & 0x4000 ? true : false;
|
hasTouch = other & 0x4000 ? true : false;
|
||||||
|
@ -733,8 +739,7 @@ jint EXPORT_ME Java_com_voidpoint_duke3d_NativeLib_qc(JNIEnv *env, jobject obj,
|
||||||
AndroidOSD(quickCommandString.c_str());
|
AndroidOSD(quickCommandString.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
void EXPORT_ME
|
void EXPORT_ME Java_com_voidpoint_duke3d_NativeLib_sss(JNIEnv *env, jobject thiz, jint width, jint height)
|
||||||
Java_com_voidpoint_duke3d_NativeLib_sss(JNIEnv *env, jobject thiz, jint width, jint height)
|
|
||||||
{
|
{
|
||||||
droidinfo.screen_width = width;
|
droidinfo.screen_width = width;
|
||||||
droidinfo.screen_height = height;
|
droidinfo.screen_height = height;
|
||||||
|
|
|
@ -245,7 +245,7 @@ int32_t AndroidRead(portableread_t r)
|
||||||
else if (consoleShown)
|
else if (consoleShown)
|
||||||
rv = TOUCH_SCREEN_CONSOLE;
|
rv = TOUCH_SCREEN_CONSOLE;
|
||||||
else if ((g_player[myconnectindex].ps->gm & MODE_MENU) == MODE_MENU && g_currentMenu != MENU_MAIN)
|
else if ((g_player[myconnectindex].ps->gm & MODE_MENU) == MODE_MENU && g_currentMenu != MENU_MAIN)
|
||||||
rv = (m_currentMenu->type == Verify) ? TOUCH_SCREEN_YES_NO : TOUCH_SCREEN_MENU;
|
rv = (m_currentMenu->type == Verify && totalclock > (m_animation.length + m_animation.start)) ? TOUCH_SCREEN_YES_NO : TOUCH_SCREEN_MENU;
|
||||||
else if ((g_player[myconnectindex].ps->gm & MODE_MENU) == MODE_MENU && g_currentMenu == MENU_MAIN)
|
else if ((g_player[myconnectindex].ps->gm & MODE_MENU) == MODE_MENU && g_currentMenu == MENU_MAIN)
|
||||||
rv = TOUCH_SCREEN_MENU_NOBACK;
|
rv = TOUCH_SCREEN_MENU_NOBACK;
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -6105,10 +6105,6 @@ int32_t app_main(int32_t argc, char const * const * argv)
|
||||||
g_numSkills = 4;
|
g_numSkills = 4;
|
||||||
ud.multimode = 1;
|
ud.multimode = 1;
|
||||||
|
|
||||||
#ifdef __ANDROID__
|
|
||||||
G_AddDef("duke3d-android.def");
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// This needs to happen before G_CheckCommandLine() because G_GameExit()
|
// This needs to happen before G_CheckCommandLine() because G_GameExit()
|
||||||
// accesses g_player[0].
|
// accesses g_player[0].
|
||||||
G_MaybeAllocPlayer(0);
|
G_MaybeAllocPlayer(0);
|
||||||
|
|
|
@ -286,7 +286,7 @@ MAKE_MENU_TOP_ENTRYLINK( "Options", MEF_MainMenu, MAIN_OPTIONS, MENU_OPTIONS );
|
||||||
MAKE_MENU_TOP_ENTRYLINK( "Help", MEF_MainMenu, MAIN_HELP, MENU_STORY );
|
MAKE_MENU_TOP_ENTRYLINK( "Help", MEF_MainMenu, MAIN_HELP, MENU_STORY );
|
||||||
#endif
|
#endif
|
||||||
MAKE_MENU_TOP_ENTRYLINK( "Credits", MEF_MainMenu, MAIN_CREDITS, MENU_CREDITS );
|
MAKE_MENU_TOP_ENTRYLINK( "Credits", MEF_MainMenu, MAIN_CREDITS, MENU_CREDITS );
|
||||||
MAKE_MENU_TOP_ENTRYLINK( "Return To Title", MEF_MainMenu, MAIN_QUITTOTITLE, MENU_QUITTOTITLE );
|
MAKE_MENU_TOP_ENTRYLINK( "End Game", MEF_MainMenu, MAIN_QUITTOTITLE, MENU_QUITTOTITLE );
|
||||||
MAKE_MENU_TOP_ENTRYLINK( "Quit", MEF_MainMenu, MAIN_QUIT, MENU_QUIT );
|
MAKE_MENU_TOP_ENTRYLINK( "Quit", MEF_MainMenu, MAIN_QUIT, MENU_QUIT );
|
||||||
#ifndef DROIDMENU
|
#ifndef DROIDMENU
|
||||||
MAKE_MENU_TOP_ENTRYLINK( "Quit Game", MEF_MainMenu, MAIN_QUITGAME, MENU_QUIT );
|
MAKE_MENU_TOP_ENTRYLINK( "Quit Game", MEF_MainMenu, MAIN_QUITGAME, MENU_QUIT );
|
||||||
|
@ -298,8 +298,8 @@ static MenuEntry_t *MEL_MAIN[] = {
|
||||||
&ME_MAIN_OPTIONS,
|
&ME_MAIN_OPTIONS,
|
||||||
#ifndef DROIDMENU
|
#ifndef DROIDMENU
|
||||||
&ME_MAIN_HELP,
|
&ME_MAIN_HELP,
|
||||||
#endif
|
|
||||||
&ME_MAIN_CREDITS,
|
&ME_MAIN_CREDITS,
|
||||||
|
#endif
|
||||||
&ME_MAIN_QUIT,
|
&ME_MAIN_QUIT,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -3447,19 +3447,7 @@ static Menu_t* M_FindMenu(MenuID_t query)
|
||||||
return M_FindMenuBinarySearch(query, 0, numMenus-1);
|
return M_FindMenuBinarySearch(query, 0, numMenus-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef struct MenuAnimation_t
|
MenuAnimation_t m_animation;
|
||||||
{
|
|
||||||
int32_t (*out)(struct MenuAnimation_t *);
|
|
||||||
int32_t (*in)(struct MenuAnimation_t *);
|
|
||||||
|
|
||||||
Menu_t *previous;
|
|
||||||
Menu_t *current;
|
|
||||||
|
|
||||||
int32_t start;
|
|
||||||
int32_t length;
|
|
||||||
} MenuAnimation_t;
|
|
||||||
|
|
||||||
static MenuAnimation_t m_animation;
|
|
||||||
|
|
||||||
int32_t M_Anim_SinOutRight(MenuAnimation_t *animdata)
|
int32_t M_Anim_SinOutRight(MenuAnimation_t *animdata)
|
||||||
{
|
{
|
||||||
|
|
|
@ -115,8 +115,6 @@ typedef enum MenuAnimationType_t
|
||||||
MA_Advance,
|
MA_Advance,
|
||||||
} MenuAnimationType_t;
|
} MenuAnimationType_t;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// a subset of screentext parameters, restricted because menus require accessibility
|
// a subset of screentext parameters, restricted because menus require accessibility
|
||||||
typedef struct MenuFont_t
|
typedef struct MenuFont_t
|
||||||
{
|
{
|
||||||
|
@ -413,6 +411,19 @@ typedef struct Menu_t
|
||||||
MenuType_t type;
|
MenuType_t type;
|
||||||
} Menu_t;
|
} Menu_t;
|
||||||
|
|
||||||
|
typedef struct MenuAnimation_t
|
||||||
|
{
|
||||||
|
int32_t(*out)(struct MenuAnimation_t *);
|
||||||
|
int32_t(*in)(struct MenuAnimation_t *);
|
||||||
|
|
||||||
|
Menu_t *previous;
|
||||||
|
Menu_t *current;
|
||||||
|
|
||||||
|
int32_t start;
|
||||||
|
int32_t length;
|
||||||
|
} MenuAnimation_t;
|
||||||
|
|
||||||
|
extern MenuAnimation_t m_animation;
|
||||||
|
|
||||||
extern MenuID_t g_currentMenu;
|
extern MenuID_t g_currentMenu;
|
||||||
extern Menu_t *m_currentMenu;
|
extern Menu_t *m_currentMenu;
|
||||||
|
|
Loading…
Reference in a new issue