Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Sign in / Register
Toggle navigation
Y
YGOMobile-Cn-Ko-En
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Locked Files
Issues
0
Issues
0
List
Boards
Labels
Service Desk
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Security & Compliance
Security & Compliance
Dependency List
License Compliance
Packages
Packages
List
Container Registry
Analytics
Analytics
CI / CD
Code Review
Insights
Issues
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
fallenstardust
YGOMobile-Cn-Ko-En
Commits
a845a361
Commit
a845a361
authored
Oct 05, 2019
by
kenan
Browse files
Options
Browse Files
Download
Plain Diff
Merge remote-tracking branch 'remotes/origin/dev_surface'
parents
2e45d5a3
aa59f65d
Changes
15
Hide whitespace changes
Inline
Side-by-side
Showing
15 changed files
with
223 additions
and
28 deletions
+223
-28
Classes/gframe/game.cpp
Classes/gframe/game.cpp
+18
-2
Classes/gframe/game.h
Classes/gframe/game.h
+23
-3
irrlicht/include/IEventReceiver.h
irrlicht/include/IEventReceiver.h
+9
-0
irrlicht/include/IrrlichtDevice.h
irrlicht/include/IrrlichtDevice.h
+2
-0
irrlicht/source/Irrlicht/Android/CIrrDeviceAndroid.h
irrlicht/source/Irrlicht/Android/CIrrDeviceAndroid.h
+2
-1
irrlicht/source/Irrlicht/CIrrDeviceStub.cpp
irrlicht/source/Irrlicht/CIrrDeviceStub.cpp
+6
-1
irrlicht/source/Irrlicht/CIrrDeviceStub.h
irrlicht/source/Irrlicht/CIrrDeviceStub.h
+4
-0
libcore/android/android_tools.cpp
libcore/android/android_tools.cpp
+13
-4
libcore/android/android_tools.h
libcore/android/android_tools.h
+1
-1
libcore/jni/cn_garymb_ygomobile_core_IrrlichtBridge.cpp
libcore/jni/cn_garymb_ygomobile_core_IrrlichtBridge.cpp
+10
-0
libcore/src/main/java/cn/garymb/ygomobile/YGOMobileActivity.java
.../src/main/java/cn/garymb/ygomobile/YGOMobileActivity.java
+121
-14
libcore/src/main/java/cn/garymb/ygomobile/core/IrrlichtBridge.java
...rc/main/java/cn/garymb/ygomobile/core/IrrlichtBridge.java
+10
-0
mobile/build.gradle
mobile/build.gradle
+1
-0
mobile/src/main/java/cn/garymb/ygomobile/ui/adapters/ServerListAdapter.java
...va/cn/garymb/ygomobile/ui/adapters/ServerListAdapter.java
+2
-1
mobile/src/main/java/cn/garymb/ygomobile/utils/PermissionUtil.java
...c/main/java/cn/garymb/ygomobile/utils/PermissionUtil.java
+1
-1
No files found.
Classes/gframe/game.cpp
View file @
a845a361
...
...
@@ -15,6 +15,7 @@
#include <android/CAndroidGUIEditBox.h>
#include <android/CAndroidGUIComboBox.h>
#include <android/CAndroidGUISkin.h>
#include <Android/CIrrDeviceAndroid.h>
#include <COGLES2ExtensionHandler.h>
#include <COGLESExtensionHandler.h>
#include <COGLES2Driver.h>
...
...
@@ -25,7 +26,18 @@ const unsigned short PRO_VERSION = 0x134B;
namespace
ygo
{
Game
*
mainGame
;
Game
*
mainGame
;
void
Game
::
process
(
irr
::
SEvent
&
event
)
{
if
(
event
.
EventType
==
EET_MOUSE_INPUT_EVENT
)
{
s32
x
=
event
.
MouseInput
.
X
;
s32
y
=
event
.
MouseInput
.
Y
;
event
.
MouseInput
.
X
=
optX
(
x
);
event
.
MouseInput
.
Y
=
optY
(
y
);
// __android_log_print(ANDROID_LOG_DEBUG, "ygo", "Android comman process %d,%d -> %d,%d", x, y,
// event.MouseInput.X, event.MouseInput.Y);
}
}
#ifdef _IRR_ANDROID_PLATFORM_
bool
Game
::
Initialize
(
ANDROID_APP
app
)
{
...
...
@@ -61,10 +73,14 @@ bool Game::Initialize() {
if
(
!
device
)
return
false
;
#ifdef _IRR_ANDROID_PLATFORM_
if
(
!
android
::
perfromTrick
(
app
))
{
return
false
;
}
android
::
initJavaBridge
(
app
,
device
);
core
::
position2di
appPosition
=
android
::
initJavaBridge
(
app
,
device
);
setPositionFix
(
appPosition
);
device
->
setProcessReceiver
(
this
);
soundEffectPlayer
=
new
AndroidSoundEffectPlayer
(
app
);
soundEffectPlayer
->
setSEEnabled
(
options
->
isSoundEffectEnabled
());
app
->
onInputEvent
=
android
::
handleInput
;
...
...
Classes/gframe/game.h
View file @
a845a361
...
...
@@ -107,7 +107,7 @@ struct FadingUnit {
irr
::
core
::
vector2di
fadingDiff
;
};
class
Game
{
class
Game
:
IProcessEventReceiver
{
public:
#ifdef _IRR_ANDROID_PLATFORM_
...
...
@@ -542,10 +542,30 @@ public:
irr
::
android
::
CustomShaderConstantSetCallBack
customShadersCallback
;
Signal
externalSignal
;
#endif
void
setPositionFix
(
core
::
position2di
fix
){
InputFix
=
fix
;
}
float
optX
(
float
x
)
{
float
x2
=
x
-
InputFix
.
X
;
if
(
x2
<
0
)
{
return
0
;
}
return
x2
;
}
};
float
optY
(
float
y
)
{
float
y2
=
y
-
InputFix
.
Y
;
if
(
y2
<
0
)
{
return
0
;
}
return
y2
;
}
void
process
(
irr
::
SEvent
&
event
);
private:
core
::
position2di
InputFix
;
};
extern
Game
*
mainGame
;
extern
Game
*
mainGame
;
}
...
...
irrlicht/include/IEventReceiver.h
View file @
a845a361
...
...
@@ -539,6 +539,15 @@ public:
virtual
bool
OnEvent
(
const
SEvent
&
event
)
=
0
;
};
class
IProcessEventReceiver
{
public:
//! Destructor
virtual
~
IProcessEventReceiver
()
{}
virtual
void
process
(
SEvent
&
event
)
=
0
;
};
//! Information on a joystick, returned from @ref irr::IrrlichtDevice::activateJoysticks()
struct
SJoystickInfo
...
...
irrlicht/include/IrrlichtDevice.h
View file @
a845a361
...
...
@@ -307,6 +307,8 @@ namespace irr
//! Get context manager
virtual
video
::
IContextManager
*
getContextManager
()
=
0
;
virtual
void
setProcessReceiver
(
IProcessEventReceiver
*
receiver
)
=
0
;
//! Set the maximal elapsed time between 2 clicks to generate doubleclicks for the mouse. It also affects tripleclick behavior.
/** When set to 0 no double- and tripleclicks will be generated.
\param timeMs maximal time in milliseconds for two consecutive clicks to be recognized as double click
...
...
irrlicht/source/Irrlicht/Android/CIrrDeviceAndroid.h
View file @
a845a361
...
...
@@ -56,6 +56,8 @@ namespace irr
virtual
E_DEVICE_TYPE
getType
()
const
;
core
::
array
<
EKEY_CODE
>
KeyMap
;
private:
static
void
handleAndroidCommand
(
ANDROID_APP
app
,
int32_t
cmd
);
...
...
@@ -80,7 +82,6 @@ namespace irr
video
::
SExposedVideoData
ExposedVideoData
;
core
::
array
<
EKEY_CODE
>
KeyMap
;
};
}
// end namespace irr
...
...
irrlicht/source/Irrlicht/CIrrDeviceStub.cpp
View file @
a845a361
...
...
@@ -224,10 +224,15 @@ u32 CIrrDeviceStub::checkSuccessiveClicks(s32 mouseX, s32 mouseY, EMOUSE_INPUT_E
//! send the event to the right receiver
bool
CIrrDeviceStub
::
postEventFromUser
(
const
SEvent
&
event
)
bool
CIrrDeviceStub
::
postEventFromUser
(
const
SEvent
&
_
event
)
{
SEvent
event
=
_event
;
bool
absorbed
=
false
;
if
(
ProcessReceiver
){
ProcessReceiver
->
process
(
event
);
}
if
(
UserReceiver
)
absorbed
=
UserReceiver
->
OnEvent
(
event
);
...
...
irrlicht/source/Irrlicht/CIrrDeviceStub.h
View file @
a845a361
...
...
@@ -178,6 +178,9 @@ namespace irr
//! Resize the render window.
virtual
void
setWindowSize
(
const
irr
::
core
::
dimension2d
<
u32
>&
size
)
_IRR_OVERRIDE_
{}
virtual
void
setProcessReceiver
(
IProcessEventReceiver
*
receiver
)
_IRR_OVERRIDE_
{
ProcessReceiver
=
receiver
;
}
protected:
void
createGUIAndScene
();
...
...
@@ -200,6 +203,7 @@ namespace irr
ITimer
*
Timer
;
gui
::
ICursorControl
*
CursorControl
;
IEventReceiver
*
UserReceiver
;
IProcessEventReceiver
*
ProcessReceiver
;
CLogger
*
Logger
;
IOSOperator
*
Operator
;
IRandomizer
*
Randomizer
;
...
...
libcore/android/android_tools.cpp
View file @
a845a361
...
...
@@ -743,20 +743,29 @@ void toggleGlobalIME(ANDROID_APP app, bool pShow) {
app
->
activity
->
vm
->
DetachCurrentThread
();
}
void
initJavaBridge
(
ANDROID_APP
app
,
void
*
handle
)
{
core
::
position2di
initJavaBridge
(
ANDROID_APP
app
,
void
*
handle
)
{
if
(
!
app
||
!
app
->
activity
||
!
app
->
activity
->
vm
)
return
;
return
core
::
position2di
(
0
,
0
)
;
JNIEnv
*
jni
=
0
;
app
->
activity
->
vm
->
AttachCurrentThread
(
&
jni
,
NULL
);
jobject
lNativeActivity
=
app
->
activity
->
clazz
;
jclass
ClassNativeActivity
=
jni
->
GetObjectClass
(
lNativeActivity
);
jmethodID
MethodSetHandle
=
jni
->
GetMethodID
(
ClassNativeActivity
,
"setNativeHandle"
,
"(I)V"
);
"setNativeHandle"
,
"(I)V"
);
jint
code
=
(
int
)
handle
;
jni
->
CallVoidMethod
(
lNativeActivity
,
MethodSetHandle
,
code
);
jmethodID
methodX
=
jni
->
GetMethodID
(
ClassNativeActivity
,
"getPositionX"
,
"()I"
);
jint
posX
=
jni
->
CallIntMethod
(
lNativeActivity
,
methodX
);
jmethodID
methodY
=
jni
->
GetMethodID
(
ClassNativeActivity
,
"getPositionY"
,
"()I"
);
jint
posY
=
jni
->
CallIntMethod
(
lNativeActivity
,
methodY
);
jni
->
DeleteLocalRef
(
ClassNativeActivity
);
app
->
activity
->
vm
->
DetachCurrentThread
();
return
;
__android_log_print
(
ANDROID_LOG_INFO
,
"ygo"
,
"Android command initJavaBridge posX=%d, posY=%d"
,
posX
,
posY
);
return
core
::
position2di
((
int
)
posX
,
(
int
)
posY
);
}
InitOptions
*
getInitOptions
(
ANDROID_APP
app
)
{
...
...
libcore/android/android_tools.h
View file @
a845a361
...
...
@@ -115,7 +115,7 @@ extern void toggleGlobalIME(ANDROID_APP app, bool pShow);
extern
void
toggleIME
(
ANDROID_APP
app
,
bool
pShow
,
const
char
*
hint
);
//Init Java Irrlicht world.
extern
void
initJavaBridge
(
ANDROID_APP
app
,
void
*
handle
);
extern
core
::
position2di
initJavaBridge
(
ANDROID_APP
app
,
void
*
handle
);
//Cause a haptic feedback.
extern
void
perfromHapticFeedback
(
ANDROID_APP
app
);
...
...
libcore/jni/cn_garymb_ygomobile_core_IrrlichtBridge.cpp
View file @
a845a361
...
...
@@ -4,8 +4,10 @@
#include "../Classes/gframe/os.h"
#include <unistd.h>
#include <pthread.h>
#include <Android/CIrrDeviceAndroid.h>
#include "../android/YGOGameOptions.h"
#include "../Classes/gframe/game.h"
#include <android/log.h>
using
namespace
irr
;
using
namespace
gui
;
...
...
@@ -292,6 +294,14 @@ static void* join_game_thread(void* param) {
}
}
JNIEXPORT
void
JNICALL
Java_cn_garymb_ygomobile_core_IrrlichtBridge_nativeSetInputFix
(
JNIEnv
*
env
,
jclass
clazz
,
jint
handle
,
jint
x
,
jint
y
)
{
if
(
ygo
::
mainGame
)
{
__android_log_print
(
ANDROID_LOG_INFO
,
"ygo"
,
"setInputFix posX=%d, posY=%d"
,
x
,
y
);
ygo
::
mainGame
->
setPositionFix
(
core
::
position2di
(
x
,
y
));
}
}
static
void
*
cancel_chain_thread
(
void
*
param
)
{
IrrlichtDevice
*
device
=
(
IrrlichtDevice
*
)
param
;
irr
::
os
::
Printer
::
log
(
"before send cancel chain"
);
...
...
libcore/src/main/java/cn/garymb/ygomobile/YGOMobileActivity.java
View file @
a845a361
...
...
@@ -19,6 +19,8 @@ import android.util.Log;
import
android.view.Gravity
;
import
android.view.HapticFeedbackConstants
;
import
android.view.KeyEvent
;
import
android.view.SurfaceHolder
;
import
android.view.SurfaceView
;
import
android.view.View
;
import
android.widget.FrameLayout
;
import
android.widget.PopupWindow
;
...
...
@@ -78,7 +80,11 @@ public class YGOMobileActivity extends NativeActivity implements
private
GameApplication
mApp
;
private
Handler
handler
=
new
Handler
();
private
FullScreenUtils
mFullScreenUtils
;
private
volatile
int
mPositionX
,
mPositionY
;
private
FrameLayout
mLayout
;
private
SurfaceView
mSurfaceView
;
private
boolean
replaced
=
false
;
private
static
boolean
USE_SURFACE
=
true
;
// public static int notchHeight;
...
...
@@ -100,11 +106,14 @@ public class YGOMobileActivity extends NativeActivity implements
@SuppressWarnings
(
"WrongConstant"
)
@Override
protected
void
onCreate
(
Bundle
savedInstanceState
)
{
super
.
onCreate
(
savedInstanceState
);
Log
.
e
(
"YGOStarter"
,
"跳转完成"
+
System
.
currentTimeMillis
());
if
(
USE_SURFACE
)
{
mSurfaceView
=
new
SurfaceView
(
this
);
}
mFullScreenUtils
=
new
FullScreenUtils
(
this
,
app
().
isImmerSiveMode
());
mFullScreenUtils
.
fullscreen
();
mFullScreenUtils
.
onCreate
();
super
.
onCreate
(
savedInstanceState
);
Log
.
e
(
"YGOStarter"
,
"跳转完成"
+
System
.
currentTimeMillis
());
if
(
sChainControlXPostion
<
0
)
{
initPostion
();
}
...
...
@@ -212,16 +221,18 @@ public class YGOMobileActivity extends NativeActivity implements
if
(
app
().
isImmerSiveMode
())
{
mFullScreenUtils
.
fullscreen
();
app
().
attachGame
(
this
);
//游戏大小
int
[]
size
=
getGameSize
();
if
(
app
().
isKeepScale
())
{
getWindow
().
setLayout
(
size
[
0
],
size
[
1
]);
if
(
USE_SURFACE
)
{
changeGameSize
();
}
else
{
int
[]
size
=
getGameSize
();
if
(
app
().
isKeepScale
())
{
getWindow
().
setLayout
(
size
[
0
],
size
[
1
]);
}
}
}
}
private
int
[]
getGameSize
()
{
private
int
[]
getGameSize
(){
//调整padding
float
xScale
=
app
().
getXScale
();
float
yScale
=
app
().
getYScale
();
...
...
@@ -231,18 +242,74 @@ public class YGOMobileActivity extends NativeActivity implements
return
new
int
[]{
w
,
h
};
}
@Override
public
int
getPositionX
()
{
synchronized
(
this
)
{
return
mPositionX
;
}
}
@Override
public
int
getPositionY
()
{
synchronized
(
this
)
{
return
mPositionY
;
}
}
@Override
public
void
setContentView
(
View
view
)
{
int
[]
size
=
getGameSize
();
int
w
=
size
[
0
];
int
h
=
size
[
1
];
mLayout
=
new
FrameLayout
(
this
);
FrameLayout
.
LayoutParams
lp
=
new
FrameLayout
.
LayoutParams
(
w
,
h
);
FrameLayout
layout
=
new
FrameLayout
(
this
);
lp
.
gravity
=
Gravity
.
CENTER
;
layout
.
addView
(
view
,
lp
);
getWindow
().
setLayout
(
w
,
h
);
getWindow
().
setGravity
(
Gravity
.
CENTER
);
super
.
setContentView
(
layout
);
if
(
USE_SURFACE
)
{
mLayout
.
addView
(
mSurfaceView
,
lp
);
mLayout
.
addView
(
view
,
lp
);
super
.
setContentView
(
mLayout
);
app
().
attachGame
(
this
);
changeGameSize
();
getWindow
().
takeSurface
(
null
);
replaced
=
true
;
mSurfaceView
.
getHolder
().
addCallback
(
this
);
mSurfaceView
.
requestFocus
();
getWindow
().
setGravity
(
Gravity
.
CENTER
);
}
else
{
mLayout
.
addView
(
view
,
lp
);
getWindow
().
setLayout
(
w
,
h
);
getWindow
().
setGravity
(
Gravity
.
CENTER
);
super
.
setContentView
(
mLayout
);
}
}
private
void
changeGameSize
(){
//游戏大小
int
[]
size
=
getGameSize
();
int
w
=
(
int
)
app
().
getScreenHeight
();
int
h
=
(
int
)
app
().
getScreenWidth
();
int
spX
=
(
int
)
((
w
-
size
[
0
])
/
2.0f
);
int
spY
=
(
int
)
((
h
-
size
[
1
])
/
2.0f
);
// Log.i("ygo", "Android command 1:posX=" + spX + ",posY=" + spY);
boolean
update
=
false
;
synchronized
(
this
)
{
if
(
spX
!=
mPositionX
||
spY
!=
mPositionY
)
{
mPositionX
=
spX
;
mPositionY
=
spY
;
update
=
true
;
}
}
if
(
update
)
{
// Log.i("ygo", "Android command setInputFix2:posX=" + spX + ",posY=" + spY);
IrrlichtBridge
.
setInputFix
(
mPositionX
,
mPositionY
);
}
if
(
app
().
isKeepScale
())
{
//设置为屏幕宽高
getWindow
().
setLayout
(
w
,
h
);
}
else
{
//拉伸,画布设置为游戏宽高
getWindow
().
setLayout
(
size
[
0
],
size
[
1
]);
}
}
private
void
initExtraView
()
{
...
...
@@ -419,4 +486,44 @@ public class YGOMobileActivity extends NativeActivity implements
public
void
setNativeHandle
(
int
nativeHandle
)
{
IrrlichtBridge
.
sNativeHandle
=
nativeHandle
;
}
@Override
public
void
surfaceCreated
(
SurfaceHolder
holder
)
{
if
(
USE_SURFACE
)
{
if
(!
replaced
)
{
return
;
}
}
super
.
surfaceCreated
(
holder
);
}
@Override
public
void
surfaceChanged
(
SurfaceHolder
holder
,
int
format
,
int
width
,
int
height
)
{
if
(
USE_SURFACE
)
{
if
(!
replaced
)
{
return
;
}
}
super
.
surfaceChanged
(
holder
,
format
,
width
,
height
);
}
@Override
public
void
surfaceDestroyed
(
SurfaceHolder
holder
)
{
if
(
USE_SURFACE
)
{
if
(!
replaced
)
{
return
;
}
}
super
.
surfaceDestroyed
(
holder
);
}
@Override
public
void
surfaceRedrawNeeded
(
SurfaceHolder
holder
)
{
if
(
USE_SURFACE
)
{
if
(!
replaced
)
{
return
;
}
}
super
.
surfaceRedrawNeeded
(
holder
);
}
}
libcore/src/main/java/cn/garymb/ygomobile/core/IrrlichtBridge.java
View file @
a845a361
...
...
@@ -59,6 +59,8 @@ public final class IrrlichtBridge {
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
();
...
...
@@ -118,6 +120,10 @@ public final class IrrlichtBridge {
}
}
public
static
void
setInputFix
(
int
x
,
int
y
){
nativeSetInputFix
(
sNativeHandle
,
x
,
y
);
}
public
static
void
cancelChain
()
{
nativeCancelChain
(
sNativeHandle
);
}
...
...
@@ -202,5 +208,9 @@ public final class IrrlichtBridge {
int
getLocalAddress
();
void
setNativeHandle
(
int
nativeHandle
);
int
getPositionX
();
int
getPositionY
();
}
}
mobile/build.gradle
View file @
a845a361
...
...
@@ -35,6 +35,7 @@ android {
}
buildTypes
{
debug
{
applicationIdSuffix
".debug"
shrinkResources
false
minifyEnabled
false
proguardFiles
getDefaultProguardFile
(
'proguard-android.txt'
),
'proguard-rules.pro'
...
...
mobile/src/main/java/cn/garymb/ygomobile/ui/adapters/ServerListAdapter.java
View file @
a845a361
...
...
@@ -2,6 +2,7 @@ package cn.garymb.ygomobile.ui.adapters;
import
android.content.Context
;
import
android.content.Intent
;
import
android.net.Uri
;
import
android.provider.Settings
;
import
android.view.ViewGroup
;
...
...
@@ -36,7 +37,7 @@ public class ServerListAdapter extends BaseRecyclerAdapterPlus<ServerInfo, Serve
builder
.
setMessage
(
R
.
string
.
join_helper_tip
);
builder
.
setLeftButtonText
(
R
.
string
.
Open_Alert_Window
);
builder
.
setLeftButtonListener
((
dlg
,
s
)
->
{
getContext
().
startActivity
(
new
Intent
(
Settings
.
ACTION_MANAGE_OVERLAY_PERMISSION
));
getContext
().
startActivity
(
new
Intent
(
Settings
.
ACTION_MANAGE_OVERLAY_PERMISSION
,
Uri
.
parse
(
"package:"
+
context
.
getPackageName
())
));
dlg
.
dismiss
();
});
builder
.
show
();
...
...
mobile/src/main/java/cn/garymb/ygomobile/utils/PermissionUtil.java
View file @
a845a361
...
...
@@ -66,7 +66,7 @@ public class PermissionUtil {
dialog
.
setLeftButtonListener
(
new
DialogInterface
.
OnClickListener
()
{
@Override
public
void
onClick
(
DialogInterface
dialogInterface
,
int
i
)
{
context
.
startActivity
(
new
Intent
(
Settings
.
ACTION_MANAGE_OVERLAY_PERMISSION
));
context
.
startActivity
(
new
Intent
(
Settings
.
ACTION_MANAGE_OVERLAY_PERMISSION
,
Uri
.
parse
(
"package:"
+
context
.
getPackageName
())
));
dialog
.
dismiss
();
}
});
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment