- Added ads support for Android

- basic "message" system between JGE and java through jni 
- Fixed pause/resume on android/sdl
This commit is contained in:
wagic.the.homebrew
2011-09-04 02:45:18 +00:00
parent 269934fe1e
commit 33691d1f13
21 changed files with 396 additions and 114 deletions

View File

@@ -24,10 +24,12 @@ extern "C" void Java_org_libsdl_app_SDLActivity_nativeInit(JNIEnv* env, jclass c
/* Run the application code! */
int status;
char *argv[2];
char *argv[4];
argv[0] = strdup("SDL_app");
argv[1] = NULL;
status = SDL_main(1, argv);
argv[1] = (char *)env;
argv[2] = (char *)&cls;
argv[3] = NULL;
status = SDL_main(3, argv);
/* We exit here for consistency with other platforms. */
exit(status);

View File

@@ -55,6 +55,10 @@ typedef u32 LocalKeySym;
#endif
#if defined(ANDROID)
#include <jni.h>
#endif
bool JGEGetButtonState(const JButton button);
bool JGEGetButtonClick(const JButton button);
void JGECreateDefaultBindings();
@@ -121,6 +125,12 @@ class JGE
private:
#endif
#if defined (ANDROID)
JNIEnv * mJNIEnv;
jclass mJNIClass;
jmethodID midSendCommand;
#endif
bool mDone;
float mDeltaTime;
bool mDebug;
@@ -356,6 +366,16 @@ class JGE
void Assert(const char *filename, long lineNumber);
/// Sends a message through JGE
/// Currently used only to communicate with the JNI Layer in Android
void SendCommand(std::string command);
#if defined (ANDROID)
/// Access to JNI Environment
void SetJNIEnv(JNIEnv * env, jclass cls);
void sendJNICommand(std::string command);
#endif
protected:
JGE();
~JGE();

View File

@@ -315,6 +315,11 @@ JGE::JGE()
strcpy(mDebuggingMsg, "");
mCurrentMusic = NULL;
#endif
#if defined (ANDROID)
mJNIEnv = NULL;
#endif
Init();
}
@@ -567,5 +572,29 @@ void JGE::Scroll(int inXVelocity, int inYVelocity)
}
}
void JGE::SendCommand(string command)
{
#if defined (ANDROID)
sendJNICommand(command);
#endif
}
#if defined (ANDROID)
/// Access to JNI Environment
void JGE::SetJNIEnv(JNIEnv * env, jclass cls)
{
mJNIEnv = env;
mJNIClass = cls;
midSendCommand = mJNIEnv->GetStaticMethodID(mJNIClass,"jgeSendCommand","(Ljava/lang/String;)V");
}
void JGE::sendJNICommand(string command)
{
if (midSendCommand) {
mJNIEnv->CallStaticVoidMethod(mJNIClass, midSendCommand, mJNIEnv->NewStringUTF(command.c_str()));
}
}
#endif
std::queue< pair< pair<LocalKeySym, JButton>, bool> > JGE::keyBuffer;
std::multimap<LocalKeySym, JButton> JGE::keyBinds;

View File

@@ -50,12 +50,39 @@ uint64_t lastTickCount;
JGE* g_engine = NULL;
JApp* g_app = NULL;
JGameLauncher* g_launcher = NULL;
#ifdef ANDROID
JNIEnv * mJNIEnv = NULL;
jclass * mJNIClass = NULL;
#endif
class SdlApp;
SdlApp *g_SdlApp = NULL;
#ifdef ANDROID
// Pause
extern "C" void Java_org_libsdl_app_SDLActivity_nativePause(
JNIEnv* env, jclass cls)
{
DebugTrace("Attempt pause");
if (!g_engine)
return;
g_engine->Pause();
DebugTrace("Pause done");
}
// Resume
extern "C" void Java_org_libsdl_app_SDLActivity_nativeResume(
JNIEnv* env, jclass cls)
{
if (!g_engine)
return;
g_engine->Resume();
}
#endif
class SdlApp
{
public: /* For easy interfacing with JGE static functions */
@@ -89,11 +116,14 @@ public:
while(Running)
{
while(SDL_WaitEventTimeout(&Event, 0))
if (g_engine && !g_engine->IsPaused())
{
OnEvent(&Event);
while(SDL_WaitEventTimeout(&Event, 0))
{
OnEvent(&Event);
}
OnUpdate();
}
OnUpdate();
}
OnCleanup();
@@ -348,6 +378,16 @@ bool InitGame(void)
g_app = g_launcher->GetGameApp();
g_app->Create();
g_engine->SetApp(g_app);
#ifdef ANDROID
DebugTrace("Can I Set JNI Params ?");
if (mJNIEnv)
DebugTrace("mJNIEnv is ok");
if (mJNIEnv && mJNIClass)
{
DebugTrace("Setting JNI Params");
g_engine->SetJNIEnv(mJNIEnv, *mJNIClass);
}
#endif
JRenderer::GetInstance()->Enable2D();
lastTickCount = JGEGetTime();
@@ -686,6 +726,15 @@ int SDL_main(int argc, char * argv[])
int main(int argc, char* argv[])
#endif //ANDROID
{
#if (defined ANDROID)
if (argc > 2)
{
mJNIEnv = (JNIEnv * )argv[1];
mJNIClass = (jclass * )argv[2];
}
#endif
DebugTrace("I R in da native");
g_launcher = new JGameLauncher();

View File

@@ -3,16 +3,22 @@
package="org.libsdl.app"
android:versionCode="1"
android:versionName="1.0">
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"></uses-permission>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<application android:label="@string/app_name" android:icon="@drawable/icon" android:debuggable="true" android:theme="@android:style/Theme.NoTitleBar.Fullscreen">
<activity android:name="SDLActivity"
android:configChanges="orientation"
android:label="@string/app_name">
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name="com.google.ads.AdActivity"
android:configChanges="keyboard|keyboardHidden|orientation"/>
</application>
<uses-sdk android:minSdkVersion="4" />
<uses-sdk android:minSdkVersion="8" />
</manifest>

View File

@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<project name="Wagic" default="help">
<project name="Wagic">
<!-- The local.properties file is created and updated by the 'android' tool.
It contains the path to the SDK. It should *NOT* be checked in in Version

View File

@@ -1,13 +1,14 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:id="@+id/mainLayout"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Hello World, Wagic"
android:text="Wagic"
/>
</LinearLayout>

View File

@@ -21,12 +21,18 @@ import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.Gravity;
import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.VelocityTracker;
import android.view.View;
import android.widget.FrameLayout;
import android.widget.FrameLayout.LayoutParams;
import com.google.ads.*;
/**
@@ -35,9 +41,10 @@ import android.view.View;
public class SDLActivity extends Activity {
// Main components
private static AdView mAdView;
private static SDLActivity mSingleton;
private static SDLSurface mSurface;
// Audio
private static Thread mAudioThread;
private static AudioTrack mAudioTrack;
@@ -52,6 +59,7 @@ public class SDLActivity extends Activity {
}
// Setup
@Override
protected void onCreate(Bundle savedInstanceState) {
//Log.v("SDL", "onCreate()");
super.onCreate(savedInstanceState);
@@ -59,33 +67,96 @@ public class SDLActivity extends Activity {
// So we can call stuff from static callbacks
mSingleton = this;
FrameLayout _videoLayout = new FrameLayout(this);
//mGLView = new DemoGLSurfaceView(this);
// Set up the surface
mSurface = new SDLSurface(getApplication());
setContentView(mSurface);
//setContentView(mSurface);
SurfaceHolder holder = mSurface.getHolder();
holder.setType(SurfaceHolder.SURFACE_TYPE_GPU);
// Create the adView
mAdView = new AdView(this, AdSize.BANNER, "a14dc0ab7b27413");
_videoLayout.addView(mSurface, new LayoutParams(LayoutParams.FILL_PARENT,
LayoutParams.FILL_PARENT));
_videoLayout.addView(mAdView, new LayoutParams(LayoutParams.WRAP_CONTENT
, LayoutParams.WRAP_CONTENT, Gravity.BOTTOM + Gravity.CENTER_HORIZONTAL) );
// mGLView.setFocusableInTouchMode(true);
// mGLView.setFocusable(true);
// adView.requestFreshAd();
setContentView(_videoLayout,
new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT));
mSurface.requestFocus();
AdRequest request = new AdRequest();
request.addTestDevice(AdRequest.TEST_EMULATOR);
request.addTestDevice("1DA1E070BC7D4ABE8BA77EB73C2CB0AA"); //wololo's phone
// Initiate a generic request to load it with an ad
mAdView.loadAd(request);
}
// Events
@Override
protected void onPause() {
//Log.v("SDL", "onPause()");
super.onPause();
SDLActivity.nativePause();
}
@Override
protected void onResume() {
//Log.v("SDL", "onResume()");
Log.v("SDL", "onResume()");
super.onResume();
SDLActivity.nativeResume();
}
@Override
public void onDestroy() {
Log.v("SDL", "onDestroy()");
super.onDestroy();
mSurface.onDestroy();
}
// Handler for Messages coming from JGE
// Suggested syntax for JGE messages is a string separated by the ":" symbol
protected void processJGEMsg (String command)
{
if (null == command) {
return;
}
if ((command.compareTo("entergamestate:menu") == 0)
|| (command.compareTo("enterduelphase:end") == 0)) {
mAdView.setVisibility(View.VISIBLE);
} else if (command.compareTo("leavegamestate:menu") == 0) {
mAdView.setVisibility(View.INVISIBLE);
}
}
// Messages from the SDLMain thread
static int COMMAND_CHANGE_TITLE = 1;
static int COMMAND_JGE_MSG = 2;
// Handler for the messages
Handler commandHandler = new Handler() {
public void handleMessage(Message msg) {
if (msg.arg1 == COMMAND_CHANGE_TITLE) {
setTitle((String)msg.obj);
}
}
if (msg.arg1 == COMMAND_JGE_MSG) {
processJGEMsg((String)msg.obj);
}
}
};
@@ -96,10 +167,12 @@ public class SDLActivity extends Activity {
msg.obj = data;
commandHandler.sendMessage(msg);
}
// C functions we call
public static native void nativeInit();
public static native void nativeQuit();
public static native void nativePause();
public static native void nativeResume();
public static native void onNativeResize(int x, int y, int format);
public static native void onNativeKeyDown(int keycode);
public static native void onNativeKeyUp(int keycode);
@@ -111,7 +184,11 @@ public class SDLActivity extends Activity {
// Java functions called from C
// Receive a message from the SDLMain thread
public static void jgeSendCommand(String command) {
mSingleton.sendCommand(COMMAND_JGE_MSG, command);
}
public static boolean createGLContext(int majorVersion, int minorVersion) {
return mSurface.initEGL(majorVersion, minorVersion);
}
@@ -119,7 +196,7 @@ public class SDLActivity extends Activity {
public static void flipBuffers() {
mSurface.flipEGL();
}
public static void setActivityTitle(String title) {
// Called from SDLMain() thread and can't directly affect the view
mSingleton.sendCommand(COMMAND_CHANGE_TITLE, title);
@@ -223,19 +300,6 @@ public class SDLActivity extends Activity {
}
}
/**
Simple nativeInit() runnable
*/
class SDLMain implements Runnable {
public void run() {
// Runs SDL_main()
SDLActivity.nativeInit();
//Log.v("SDL", "SDL thread terminated");
}
}
/**
SDLSurface. This is what we draw on, so we need to know when it's created
in order to do anything useful.
@@ -246,21 +310,52 @@ class SDLSurface extends SurfaceView implements SurfaceHolder.Callback,
View.OnKeyListener, View.OnTouchListener, SensorEventListener {
// This is what SDL runs in. It invokes SDL_main(), eventually
private Thread mSDLThread;
private Thread mSDLThread;
// EGL private objects
private EGLContext mEGLContext;
private EGLSurface mEGLSurface;
private EGLDisplay mEGLDisplay;
private EGLConfig mEGLConfig;
// Sensors
private static SensorManager mSensorManager;
private static VelocityTracker mVelocityTracker;
final private Object mSemSurface;
private Boolean mSurfaceValid;
void startSDLThread() {
if (mSDLThread == null) {
mSDLThread = new Thread(new SDLMain(), "SDLThread");
mSDLThread.start();
}
}
/**
Simple nativeInit() runnable
*/
class SDLMain implements Runnable {
public void run() {
// Runs SDL_main()
SDLActivity.nativeInit();
SDLActivity.nativeQuit();
Log.v("SDL", "SDL thread terminated");
// On exit, tear everything down for a fresh restart next time.
System.exit(0);
}
}
// Startup
public SDLSurface(Context context) {
super(context);
mSemSurface = new Object();
mSurfaceValid = false;
getHolder().addCallback(this);
setFocusable(true);
@@ -269,21 +364,20 @@ class SDLSurface extends SurfaceView implements SurfaceHolder.Callback,
setOnKeyListener(this);
setOnTouchListener(this);
mSensorManager = (SensorManager)context.getSystemService("sensor");
mSensorManager = (SensorManager)context.getSystemService("sensor");
}
// Called when we have a valid drawing surface
public void surfaceCreated(SurfaceHolder holder) {
//Log.v("SDL", "surfaceCreated()");
Log.v("SDL", "surfaceCreated()");
enableSensor(Sensor.TYPE_ACCELEROMETER, true);
}
// Called when we lose the surface
public void surfaceDestroyed(SurfaceHolder holder) {
//Log.v("SDL", "surfaceDestroyed()");
public void onDestroy() {
// Send a quit message to the application
//should that be in SDLActivity "onDestroy" instead ?
SDLActivity.nativeQuit();
// Now wait for the SDL thread to quit
@@ -294,17 +388,25 @@ class SDLSurface extends SurfaceView implements SurfaceHolder.Callback,
Log.v("SDL", "Problem stopping thread: " + e);
}
mSDLThread = null;
//Log.v("SDL", "Finished waiting for SDL thread");
}
}
// Called when we lose the surface
public void surfaceDestroyed(SurfaceHolder holder) {
Log.v("SDL", "surfaceDestroyed()");
synchronized(mSemSurface) {
mSurfaceValid = false;
mSemSurface.notifyAll();
}
enableSensor(Sensor.TYPE_ACCELEROMETER, false);
}
// Called when the surface is resized
public void surfaceChanged(SurfaceHolder holder,
int format, int width, int height) {
//Log.v("SDL", "surfaceChanged()");
Log.v("SDL", "surfaceChanged()");
int sdlFormat = 0x85151002; // SDL_PIXELFORMAT_RGB565 by default
switch (format) {
@@ -350,13 +452,10 @@ class SDLSurface extends SurfaceView implements SurfaceHolder.Callback,
Log.v("SDL", "pixel format unknown " + format);
break;
}
SDLActivity.onNativeResize(width, height, sdlFormat);
SDLActivity.onNativeResize(width, height, sdlFormat);
// Now start up the C app thread
if (mSDLThread == null) {
mSDLThread = new Thread(new SDLMain(), "SDLThread");
mSDLThread.start();
}
startSDLThread();
}
// unused
@@ -368,6 +467,7 @@ class SDLSurface extends SurfaceView implements SurfaceHolder.Callback,
Log.v("SDL", "Starting up OpenGL ES " + majorVersion + "." + minorVersion);
try {
EGL10 egl = (EGL10)EGLContext.getEGL();
EGLDisplay dpy = egl.eglGetDisplay(EGL10.EGL_DEFAULT_DISPLAY);
@@ -394,28 +494,20 @@ class SDLSurface extends SurfaceView implements SurfaceHolder.Callback,
Log.e("SDL", "No EGL config available");
return false;
}
EGLConfig config = configs[0];
mEGLConfig = configs[0];
EGLContext ctx = egl.eglCreateContext(dpy, config, EGL10.EGL_NO_CONTEXT, null);
EGLContext ctx = egl.eglCreateContext(dpy, mEGLConfig, EGL10.EGL_NO_CONTEXT, null);
if (ctx == EGL10.EGL_NO_CONTEXT) {
Log.e("SDL", "Couldn't create context");
return false;
}
EGLSurface surface = egl.eglCreateWindowSurface(dpy, config, this, null);
if (surface == EGL10.EGL_NO_SURFACE) {
Log.e("SDL", "Couldn't create surface");
return false;
}
if (!egl.eglMakeCurrent(dpy, surface, surface, ctx)) {
Log.e("SDL", "Couldn't make context current");
return false;
}
mEGLContext = ctx;
mEGLDisplay = dpy;
mEGLSurface = surface;
if (!createSurface(this.getHolder())) {
return false;
}
} catch(Exception e) {
Log.v("SDL", e + "");
@@ -426,9 +518,56 @@ class SDLSurface extends SurfaceView implements SurfaceHolder.Callback,
return true;
}
public Boolean createSurface(SurfaceHolder holder) {
/*
* The window size has changed, so we need to create a new
* surface.
*/
EGL10 egl = (EGL10)EGLContext.getEGL();
if (mEGLSurface != null) {
/*
* Unbind and destroy the old EGL surface, if
* there is one.
*/
egl.eglMakeCurrent(mEGLDisplay, EGL10.EGL_NO_SURFACE, EGL10.EGL_NO_SURFACE, EGL10.EGL_NO_CONTEXT);
egl.eglDestroySurface(mEGLDisplay, mEGLSurface);
}
/*
* Create an EGL surface we can render into.
*/
mEGLSurface = egl.eglCreateWindowSurface(mEGLDisplay, mEGLConfig, holder, null);
if (mEGLSurface == EGL10.EGL_NO_SURFACE) {
Log.e("SDL", "Couldn't create surface");
return false;
}
/*
* Before we can issue GL commands, we need to make sure
* the context is current and bound to a surface.
*/
if (!egl.eglMakeCurrent(mEGLDisplay, mEGLSurface, mEGLSurface, mEGLContext)) {
Log.e("SDL", "Couldn't make context current");
return false;
}
mSurfaceValid = true;
return true;
}
// EGL buffer flip
public void flipEGL() {
if (!mSurfaceValid)
{
createSurface(this.getHolder());
}
try {
EGL10 egl = (EGL10)EGLContext.getEGL();
@@ -447,6 +586,7 @@ class SDLSurface extends SurfaceView implements SurfaceHolder.Callback,
Log.v("SDL", s.toString());
}
}
}
// Key events

View File

@@ -93,6 +93,7 @@ public:
void LoadGameStates();
void SetNextState(int state);
void SetCurrentState(GameState * state);
void DoTransition(int trans, int tostate, float dur = -1, bool animonly = false);
void DoAnimation(int trans, float dur = -1);
static hgeParticleSystem * Particles[6];

View File

@@ -44,9 +44,10 @@ class GameState
protected:
GameApp* mParent;
JGE* mEngine;
string mStringID;
public:
GameState(GameApp* parent);
GameState(GameApp* parent, string id);
virtual ~GameState(){}
virtual void Create(){}
@@ -62,6 +63,8 @@ public:
virtual void Update(float dt) = 0;
virtual void Render() = 0;
string getStringID() {return mStringID;};
// deck manipulation methods
// 2010/09/15:
// this was originally one method to do everything. That has been split up into two distinct

View File

@@ -45,6 +45,7 @@ private:
void loadPlayer(int playerId, int decknb = 0, bool isAI = false, bool isNetwork = false);
void ConstructOpponentMenu(); //loads the opponentMenu if it doesn't exist
void initScroller();
void setGamePhase(int newGamePhase);
public:
GameStateDuel(GameApp* parent);

View File

@@ -40,8 +40,8 @@ string GameApp::systemError = "";
JQuadPtr manaIcons[7];
GameState::GameState(GameApp* parent) :
mParent(parent)
GameState::GameState(GameApp* parent, string id) :
mParent(parent), mStringID(id)
{
mEngine = JGE::GetInstance();
}
@@ -341,13 +341,13 @@ void GameApp::Update()
mTrans->End();
if (mTrans->to != NULL && !mTrans->bAnimationOnly)
{
mCurrentState = mTrans->to;
SetCurrentState(mTrans->to);
SAFE_DELETE(mGameStates[GAME_STATE_TRANSITION]);
mCurrentState->Start();
}
else
{
mCurrentState = mTrans->from;
SetCurrentState(mTrans->from);
SAFE_DELETE(mGameStates[GAME_STATE_TRANSITION]);
}
}
@@ -356,7 +356,7 @@ void GameApp::Update()
if (mCurrentState != NULL)
mCurrentState->End();
mCurrentState = mNextState;
SetCurrentState(mNextState);
#if defined (PSP)
/*
@@ -423,6 +423,20 @@ void GameApp::SetNextState(int state)
mNextState = mGameStates[state];
}
void GameApp::SetCurrentState(GameState * state)
{
if (mCurrentState == state)
return;
if (mCurrentState)
JGE::GetInstance()->SendCommand("leavegamestate:" + mCurrentState->getStringID());
mCurrentState = state;
if (mCurrentState)
JGE::GetInstance()->SendCommand("entergamestate:" + mCurrentState->getStringID());
}
void GameApp::Pause()
{
stopMusic();
@@ -471,7 +485,7 @@ void GameApp::DoTransition(int trans, int tostate, float dur, bool animonly)
tb->bAnimationOnly = animonly;
mGameStates[GAME_STATE_TRANSITION] = tb;
mGameStates[GAME_STATE_TRANSITION]->Start();
mCurrentState = tb; //The old current state is ended inside our transition.
SetCurrentState(tb); //The old current state is ended inside our transition.
}
else if (toState)
{ //Somehow failed, just do standard SetNextState behavior

View File

@@ -23,7 +23,7 @@ namespace
}
GameStateAwards::GameStateAwards(GameApp* parent) :
GameState(parent)
GameState(parent, "trophies")
{
}

View File

@@ -39,7 +39,7 @@ void StringExplode(string str, string separator, vector<string>* results)
}
GameStateDeckViewer::GameStateDeckViewer(GameApp* parent) :
GameState(parent)
GameState(parent, "deckeditor")
{
bgMusic = NULL;
useFilter = 0;

View File

@@ -32,6 +32,7 @@ const float MENU_FONT_SCALE = 1.0f;
enum ENUM_DUEL_STATE
{
DUEL_STATE_UNSET = 0,
DUEL_STATE_START,
DUEL_STATE_END,
DUEL_STATE_CHOOSE_DECK1,
@@ -45,12 +46,13 @@ enum ENUM_DUEL_STATE
DUEL_STATE_PLAY,
DUEL_STATE_BACK_TO_MAIN_MENU,
DUEL_STATE_MENU,
#ifdef NETWORK_SUPPORT
DUEL_STATE_OPPONENT_WAIT,
#endif //NETWORK_SUPPORT
DUEL_STATE_OPPONENT_WAIT, // used For Network only
DUEL_STATE_ERROR
};
const char * stateStrings[] = { "unset", "start", "end", "choose_deck1", "deck1_detailed_info", "deck2_detailed_info", "choose_deck1_to_2", "choose_deck2", "choose_deck2_to_play",
"error_no_deck", "cancel", "play", "back_to_main_menu", "menu", "oponent_wait", "error" };
enum ENUM_DUEL_MENUS
{
DUEL_MENU_GAME_MENU,
@@ -64,7 +66,7 @@ int GameStateDuel::selectedPlayerDeckId = 0;
int GameStateDuel::selectedAIDeckId = 0;
GameStateDuel::GameStateDuel(GameApp* parent) :
GameState(parent)
GameState(parent, "duel")
{
for (int i = 0; i < 2; i++)
{
@@ -76,6 +78,7 @@ GameState(parent)
opponentMenu = NULL;
menu = NULL;
popupScreen = NULL;
mGamePhase = DUEL_STATE_UNSET;
#ifdef TESTSUITE
testSuite = NULL;
@@ -105,7 +108,7 @@ void GameStateDuel::Start()
testSuite = NEW TestSuite("test/_tests.txt",MTGCollection());
#endif
mGamePhase = DUEL_STATE_CHOOSE_DECK1;
setGamePhase(DUEL_STATE_CHOOSE_DECK1);
credits = NEW Credits();
menu = NULL;
@@ -308,6 +311,19 @@ void GameStateDuel::ConstructOpponentMenu()
}
}
void GameStateDuel::setGamePhase(int newGamePhase) {
if (mGamePhase == newGamePhase)
return;
if (mGamePhase)
JGE::GetInstance()->SendCommand("leaveduelphase:" + string(stateStrings[mGamePhase]));
mGamePhase = newGamePhase;
if (mGamePhase )
JGE::GetInstance()->SendCommand("enterduelphase:" + string(stateStrings[mGamePhase]));
}
void GameStateDuel::Update(float dt)
{
switch (mGamePhase)
@@ -324,7 +340,7 @@ void GameStateDuel::Update(float dt)
case DUEL_STATE_CHOOSE_DECK1:
if (!mParent->rules->canChooseDeck())
{
mGamePhase = DUEL_STATE_PLAY;
setGamePhase(DUEL_STATE_PLAY);
}
#ifdef TESTSUITE
else if (mParent->players[1] == PLAYER_TYPE_TESTSUITE)
@@ -332,7 +348,7 @@ void GameStateDuel::Update(float dt)
if (testSuite && testSuite->loadNext())
{
loadTestSuitePlayers();
mGamePhase = DUEL_STATE_PLAY;
setGamePhase(DUEL_STATE_PLAY);
testSuite->pregameTests();
testSuite->initGame();
}
@@ -340,11 +356,11 @@ void GameStateDuel::Update(float dt)
{
if (!game)
{
mGamePhase = DUEL_STATE_ERROR;
setGamePhase(DUEL_STATE_ERROR);
}
else
{
mGamePhase = DUEL_STATE_END;
setGamePhase(DUEL_STATE_END);
}
}
}
@@ -358,13 +374,13 @@ void GameStateDuel::Update(float dt)
else
{
loadPlayer(0);
mGamePhase = DUEL_STATE_CHOOSE_DECK2;
setGamePhase(DUEL_STATE_CHOOSE_DECK2);
}
}
break;
case DUEL_STATE_CHOOSE_DECK1_TO_2:
if (deckmenu->isClosed())
mGamePhase = DUEL_STATE_CHOOSE_DECK2;
setGamePhase(DUEL_STATE_CHOOSE_DECK2);
else
deckmenu->Update(dt);
break;
@@ -381,7 +397,7 @@ void GameStateDuel::Update(float dt)
else
{
loadPlayer(1);
mGamePhase = DUEL_STATE_PLAY;
setGamePhase(DUEL_STATE_PLAY);
}
}
break;
@@ -389,7 +405,7 @@ void GameStateDuel::Update(float dt)
if (mParent->players[1] == PLAYER_TYPE_HUMAN)
{
if (deckmenu->isClosed())
mGamePhase = DUEL_STATE_PLAY;
setGamePhase(DUEL_STATE_PLAY);
else
deckmenu->Update(dt);
}
@@ -397,7 +413,7 @@ void GameStateDuel::Update(float dt)
{
ConstructOpponentMenu();
if (opponentMenu->isClosed())
mGamePhase = DUEL_STATE_PLAY;
setGamePhase(DUEL_STATE_PLAY);
else
opponentMenu->Update(dt);
}
@@ -448,18 +464,18 @@ void GameStateDuel::Update(float dt)
if (game->gameOver)
{
if (game->players[1]->playMode != Player::MODE_TEST_SUITE) credits->compute(game->players[0], game->players[1], mParent);
mGamePhase = DUEL_STATE_END;
setGamePhase(DUEL_STATE_END);
#ifdef TESTSUITE
if (mParent->players[1] == PLAYER_TYPE_TESTSUITE)
{
if (testSuite->loadNext())
{
loadTestSuitePlayers();
mGamePhase = DUEL_STATE_PLAY;
setGamePhase(DUEL_STATE_PLAY);
testSuite->initGame();
}
else
mGamePhase = DUEL_STATE_END;
setGamePhase(DUEL_STATE_END);
}
else
#endif
@@ -489,7 +505,7 @@ void GameStateDuel::Update(float dt)
menu->Add(MENUITEM_MAIN_MENU, "Back to main menu");
menu->Add(MENUITEM_CANCEL, "Cancel");
}
mGamePhase = DUEL_STATE_MENU;
setGamePhase(DUEL_STATE_MENU);
}
break;
#ifdef NETWORK_SUPPORT
@@ -499,7 +515,7 @@ void GameStateDuel::Update(float dt)
{ // Player loaded
menu->Close();
SAFE_DELETE(menu);
mGamePhase = DUEL_STATE_PLAY;
setGamePhase(DUEL_STATE_PLAY);
} else if(menu == NULL)
{
loadPlayer(1, 42/* 0 not good*/, false, true);
@@ -522,7 +538,7 @@ void GameStateDuel::Update(float dt)
menu->Update(dt);
if (menu->isClosed())
{
mGamePhase = DUEL_STATE_PLAY;
setGamePhase(DUEL_STATE_PLAY);
SAFE_DELETE(menu);
}
break;
@@ -665,7 +681,7 @@ void GameStateDuel::ButtonPressed(int controllerId, int controlId)
if (!popupScreen->isClosed())
{
popupScreen->Close();
mGamePhase = DUEL_STATE_CHOOSE_DECK1;
setGamePhase(DUEL_STATE_CHOOSE_DECK1);
SAFE_DELETE( popupScreen );
}
else
@@ -682,7 +698,7 @@ void GameStateDuel::ButtonPressed(int controllerId, int controlId)
if (!popupScreen->isClosed())
{
popupScreen->Close();
mGamePhase = DUEL_STATE_CHOOSE_DECK2_TO_PLAY;
setGamePhase(DUEL_STATE_CHOOSE_DECK2_TO_PLAY);
SAFE_DELETE( popupScreen );
}
else
@@ -700,7 +716,7 @@ void GameStateDuel::ButtonPressed(int controllerId, int controlId)
case MENUITEM_RANDOM_AI:
loadPlayer(1);
opponentMenu->Close();
mGamePhase = DUEL_STATE_CHOOSE_DECK2_TO_PLAY;
setGamePhase(DUEL_STATE_CHOOSE_DECK2_TO_PLAY);
break;
default:
// cancel option. return to player deck selection
@@ -710,7 +726,7 @@ void GameStateDuel::ButtonPressed(int controllerId, int controlId)
opponentMenu->Close();
deckmenu->Close();
mParent->SetNextState(DUEL_STATE_CHOOSE_DECK1);
mGamePhase = DUEL_STATE_CHOOSE_DECK1;
setGamePhase(DUEL_STATE_CHOOSE_DECK1);
break;
}
@@ -728,7 +744,7 @@ void GameStateDuel::ButtonPressed(int controllerId, int controlId)
{
popupScreen->Update(selectedDeck);
}
mGamePhase = DUEL_STATE_DECK2_DETAILED_INFO;
setGamePhase(DUEL_STATE_DECK2_DETAILED_INFO);
break;
}
else if (controlId == MENUITEM_MORE_INFO && !opponentMenu->showDetailsScreen())
@@ -741,7 +757,7 @@ void GameStateDuel::ButtonPressed(int controllerId, int controlId)
loadPlayer(1, deckNumber, 1);
OpponentsDeckid = deckNumber;
opponentMenu->Close();
mGamePhase = DUEL_STATE_CHOOSE_DECK2_TO_PLAY;
setGamePhase(DUEL_STATE_CHOOSE_DECK2_TO_PLAY);
break;
}
break;
@@ -754,13 +770,13 @@ void GameStateDuel::ButtonPressed(int controllerId, int controlId)
deckNumber = playerDeckList->at(WRand() % (playerDeckList->size()))->getDeckId();
loadPlayer(0, deckNumber);
deckmenu->Close();
mGamePhase = DUEL_STATE_CHOOSE_DECK2_TO_PLAY;
setGamePhase(DUEL_STATE_CHOOSE_DECK2_TO_PLAY);
break;
}
else if (controlId == MENUITEM_MAIN_MENU || controlId == MENUITEM_CANCEL) // user clicked on "Cancel"
{
if (deckmenu) deckmenu->Close();
mGamePhase = DUEL_STATE_BACK_TO_MAIN_MENU;
setGamePhase(DUEL_STATE_BACK_TO_MAIN_MENU);
break;
}
else if (controlId == MENUITEM_MORE_INFO && deckmenu->showDetailsScreen())
@@ -777,7 +793,7 @@ void GameStateDuel::ButtonPressed(int controllerId, int controlId)
{
popupScreen->Update(selectedDeck);
}
mGamePhase = DUEL_STATE_DECK1_DETAILED_INFO;
setGamePhase(DUEL_STATE_DECK1_DETAILED_INFO);
break;
}
else if (controlId == MENUITEM_MORE_INFO)
@@ -804,12 +820,12 @@ void GameStateDuel::ButtonPressed(int controllerId, int controlId)
#ifdef NETWORK_SUPPORT
if(mParent->players[1] == PLAYER_TYPE_REMOTE)
{ // no need to choose an opponent deck in network mode
mGamePhase = DUEL_STATE_OPPONENT_WAIT;
setGamePhase(DUEL_STATE_OPPONENT_WAIT);
}
else
#endif //NETWORK_SUPPORT
{
mGamePhase = DUEL_STATE_CHOOSE_DECK1_TO_2;
setGamePhase(DUEL_STATE_CHOOSE_DECK1_TO_2);
}
playerDeck = NULL;
}
@@ -817,7 +833,7 @@ void GameStateDuel::ButtonPressed(int controllerId, int controlId)
{
loadPlayer(1, controlId);
deckmenu->Close();
mGamePhase = DUEL_STATE_CHOOSE_DECK2_TO_PLAY;
setGamePhase(DUEL_STATE_CHOOSE_DECK2_TO_PLAY);
}
break;
@@ -828,18 +844,18 @@ void GameStateDuel::ButtonPressed(int controllerId, int controlId)
case MENUITEM_MAIN_MENU:
menu->Close();
mGamePhase = DUEL_STATE_BACK_TO_MAIN_MENU;
setGamePhase(DUEL_STATE_BACK_TO_MAIN_MENU);
break;
case MENUITEM_CANCEL:
menu->Close();
mGamePhase = DUEL_STATE_CANCEL;
setGamePhase(DUEL_STATE_CANCEL);
break;
case MENUITEM_MULLIGAN:
//almosthumane - mulligan
game->currentPlayer->takeMulligan();
menu->Close();
mGamePhase = DUEL_STATE_CANCEL;
setGamePhase(DUEL_STATE_CANCEL);
break;
//END almosthumane - mulligan

View File

@@ -52,7 +52,7 @@ enum ENUM_MENU_STATE_MINOR
};
GameStateMenu::GameStateMenu(GameApp* parent) :
GameState(parent)
GameState(parent, "menu")
{
mGuiController = NULL;
subMenuController = NULL;
@@ -437,7 +437,7 @@ void GameStateMenu::ensureMGuiController()
mGuiController->Add(NEW MenuItem(
item->mActionId,
mFont, item->mDisplayName,
startX + (i * space), 50 + SCREEN_HEIGHT / 2,
startX + (i * space), 40 + SCREEN_HEIGHT / 2,
mIcons[iconId].get(), mIcons[iconId + 1].get(),
item->mParticleFile.c_str(), WResourceManager::Instance()->GetQuad("particles").get(),
(i == 0)));

View File

@@ -17,7 +17,7 @@ namespace
}
GameStateOptions::GameStateOptions(GameApp* parent) :
GameState(parent), mReload(false), grabber(NULL), optionsMenu(NULL), optionsTabs(NULL)
GameState(parent, "options"), mReload(false), grabber(NULL), optionsMenu(NULL), optionsTabs(NULL)
{
}
GameStateOptions::~GameStateOptions()

View File

@@ -49,7 +49,7 @@ bool BoosterDisplay::CheckUserInput(JButton key)
}
GameStateShop::GameStateShop(GameApp* parent) :
GameState(parent)
GameState(parent, "shop")
{
menu = NULL;
for (int i = 0; i < 8; i++)

View File

@@ -7,7 +7,7 @@
#include <dirent.h>
GameStateStory::GameStateStory(GameApp* parent) :
GameState(parent)
GameState(parent, "story")
{
flow = NULL;
menu = NULL;

View File

@@ -9,7 +9,7 @@
#include "OptionItem.h"
TransitionBase::TransitionBase(GameApp* parent, GameState* _from, GameState* _to, float duration) :
GameState(parent)
GameState(parent, "transition")
{
from = _from;
to = _to;

View File

@@ -51,7 +51,7 @@ void MenuItem::Render()
onQuad->SetColor(ARGB(70,255,255,255));
renderer->RenderQuad(onQuad, SCREEN_WIDTH, SCREEN_HEIGHT / 2, 0, 8, 8);
onQuad->SetColor(ARGB(255,255,255,255));
mFont->DrawString(mText.c_str(), SCREEN_WIDTH / 2, 20 + 3 * SCREEN_HEIGHT / 4, JGETEXT_CENTER);
mFont->DrawString(mText.c_str(), SCREEN_WIDTH / 2, 3 * SCREEN_HEIGHT / 4, JGETEXT_CENTER);
renderer->RenderQuad(onQuad, mX, mY, 0, mScale, mScale);
}