DinkSmallwoodHD/source/App.cpp
seth 3998875161 (note: Dink requires a Proton svn commit as well, but I haven't done it yet, it needs a bit more testing first)
* Fixed issue where launching dmods from DFArc with a dmod path not in DFArc's dir or Dink HD's dmod dir would fail
* Fixed compatibility so Freedink.exe and the dink.exe from 1.08 can be run from Dink HD's dir (previously, start.c had been hacked to skip stuff for the HD version,
  it now checks version and if it's being run as a dmod or not and does it right)
* If you run the HD "dink" dir as a mod it now works as expected (it plays the normal game, including the old start up screen)
* Now including story/*.c instead of the .d files.  No reason to hide them, right? (note: if you install over HD without uninstalling, the old .d files will still be there.  But .c files are checked
first so it should be ok anyway)
* DMODs now default to the original .midi files rather than the .ogg CD music, as it changed the desired "feel" of some DMODs to switch to CD music.  Running with -game dink causes Dink itself to
  not use CD music as well, so for people who don't like CD music at all there's an option to play the original game with midis only
* (Bugfix) Dink HD will no longer try to grab missing sprites from the base dink dir, this fixes Dink's pushing anim in Zoltron
* (Bugfix) dmod installer no longer chokes on zero byte files (I'm looking at you, 9gems)
* (Bugfix) Fixed memory leak and possible crash related to script loading
* (Bugfix) Fixed issue with the checkerboard shadow processing where the 8 bit RLE decoder failed because it was expecting an 8 bit target (most bmps don't use RLE, but Alliance does in places)
* Went ahead and decided to accept 252,252,252 as alpha if it's index 255 on an 8bit sprite.  This fixed the white background issue with Alliance dmod as well as Dinkcraft
* FEATURE: Can now download all DMODs from Dink Network directly from inside the game via Dan's php interface.  Can sort by rating, latest update date, or alphabetically

git-svn-id: svn://rtsoft.com/rtsvn/projects/RTDink@1502 353e56fe-9613-0410-8469-b96ad8e6f29c
2017-09-22 12:19:02 +00:00

1020 lines
25 KiB
C++

/*
* App.cpp
* Created by Seth Robinson on 3/6/09.
* For license info, check the license.txt file that should have come with this.
*
*/
#include "PlatformPrecomp.h"
#include "App.h"
#include "GUI/MainMenu.h"
#include "Entity/EntityUtils.h"//create the classes that our globally library expects to exist somewhere.
#include "dink/dink.h"
#include "GUI/GameMenu.h"
#include "util/archive/TarHandler.h"
#include "Renderer/SoftSurface.h"
#include "GUI/BrowseMenu.h"
#include "Entity/SliderComponent.h"
#include "GUI/OptionsMenu.h"
#include "FileSystem/FileSystemZip.h"
#include "Entity/ArcadeInputComponent.h"
#include "GUI/ExpiredMenu.h"
#include <time.h>
#include "Gamepad/GamepadManager.h"
#include "Gamepad/GamepadProvideriCade.h"
#ifdef WINAPI
extern int g_winVideoScreenX;
extern int g_winVideoScreenY;
extern bool g_bUseBorderlessFullscreenOnWindows;
void AddText(const char *tex, const char *filename);
#include "StackWalker/StackUtils.h"
extern bool g_bIsFullScreen;
#endif
extern bool g_script_debug_mode;
extern Surface g_transitionSurf;
#ifdef RT_MOGA_ENABLED
#include "Gamepad/GamepadProviderMoga.h"
#endif
#ifdef RT_CHARTBOOST_ENABLED
#include "Ad/AdProviderChartBoost.h"
#endif
#ifdef RT_IOS_60BEAT_GAMEPAD_SUPPORT
#include "Gamepad/GamepadProvider60Beat.h"
#endif
//#define FORCE_DMOD_SUPPORT
MessageManager g_messageManager;
MessageManager * GetMessageManager() {return &g_messageManager;}
FileManager g_fileManager;
FileManager * GetFileManager() {return &g_fileManager;}
GamepadManager g_gamepadManager;
GamepadManager * GetGamepadManager() {return &g_gamepadManager;}
#ifdef __APPLE__
#if TARGET_OS_IPHONE == 1
//it's an iPhone or iPad
//#include "Audio/AudioManagerOS.h"
//AudioManagerOS g_audioManager;
//#include "Audio/AudioManagerDenshion.h"
//AudioManagerDenshion g_audioManager;
#include "Audio/AudioManagerFMODStudio.h"
AudioManagerFMOD g_audioManager;
#else
//it's being compiled as a native OSX app
#include "Audio/AudioManagerFMODStudio.h"
AudioManagerFMOD g_audioManager; //dummy with no sound
//in theory, CocosDenshion should work for the Mac builds, but right now it seems to want a big chunk of
//Cocos2d included so I'm not fiddling with it for now
//#include "Audio/AudioManagerDenshion.h"
//AudioManagerDenshion g_audioManager;
#endif
#else
#if defined RT_WEBOS || defined RTLINUX
#include "Audio/AudioManagerSDL.h"
AudioManagerSDL g_audioManager; //sound in windows and WebOS
//AudioManager g_audioManager; //to disable sound
#elif defined ANDROID_NDK
#include "Audio/AudioManagerAndroid.h"
AudioManagerAndroid g_audioManager; //sound for android
#elif defined PLATFORM_BBX
#include "Audio/AudioManagerBBX.h"
//AudioManager g_audioManager; //to disable sound
AudioManagerBBX g_audioManager;
#elif defined PLATFORM_HTML5
#include "Audio/AudioManagerSDL.h"
//AudioManager g_audioManager; //to disable sound
AudioManagerSDL g_audioManager;
#elif defined PLATFORM_FLASH
//AudioManager g_audioManager; //to disable sound
#include "Audio/AudioManagerFlash.h"
AudioManagerFlash g_audioManager;
#else
//in windows
//AudioManager g_audioManager; //to disable sound
#ifdef RT_FLASH_TEST
#include "Audio/AudioManagerFlash.h"
AudioManagerFlash g_audioManager;
#else
// #include "Audio/AudioManagerAudiere.h"
// AudioManagerAudiere g_audioManager; //Use Audiere for audio
#include "Gamepad/GamepadProviderDirectX.h"
#include "Audio/AudioManagerFMODStudio.h"
AudioManagerFMOD g_audioManager; //if we wanted FMOD sound in windows
#endif
#endif
#endif
#ifdef ANDROID_NDK
void SetPreferSDCardForStorage(bool bNew);
#endif
AudioManager * GetAudioManager(){return &g_audioManager;}
App *g_pApp = NULL;
BaseApp * GetBaseApp()
{
if (!g_pApp)
{
g_pApp = new App;
}
return g_pApp;
}
App * GetApp()
{
return g_pApp;
}
const char * GetAppName()
{
#ifdef WINAPI
if (GetApp())
{
static char name[64];
sprintf(name, "Dink Smallwood HD %s", GetApp()->GetVersionString().c_str());
return name;
}
#endif
return "Dink Smallwood HD";
};
App::App()
{
http://www.rtsoft.com
m_bGhostMode = false;
#ifdef ANDROID_NDK
SetPreferSDCardForStorage(true);
#endif
m_bDidPostInit = false;
m_bHasDMODSupport = true;
//for mobiles
m_version = 1.78f;
m_versionString = "V1.7.8";
m_build = 1;
m_bCheatsEnabled = false;
//for Win/mac
m_desktopVersion = m_version;
m_desktopVersionString = m_versionString;
m_desktopBuild = 1;
m_bForceAspectRatio = true;
}
App::~App()
{
//L_ParticleSystem::deinit();
}
void App::AddIcadeProvider()
{
GamepadProvider * pProv = GetGamepadManager()->AddProvider(new GamepadProvideriCade); //use iCade, this actually should work with any platform...
GetBaseApp()->SetAllowScreenDimming(false);
if (pProv)
{
pProv->m_sig_failed_to_connect.connect(1, boost::bind(&App::OniCadeDisconnected, this, _1));
}
}
bool App::GetForceAspectRatio()
{
return m_bForceAspectRatio;
}
void App::OniCadeDisconnected(GamepadProvider *pProvider)
{
LogMsg("Dealing with icade disconnect");
GetGamepadManager()->RemoveProviderByName("iCade");
GetApp()->RemoveAndroidKeyboardKeys();
GetApp()->GetVar("check_icade")->Set(uint32(0));
Entity *pOptions = GetEntityRoot()->GetEntityByName("OptionsMenu");
if (pOptions)
{
LogMsg("Found options");
Entity *pCheckBox = pOptions->GetEntityByName("check_icade");
if (pCheckBox)
{
LogMsg("Found checkbox");
SetCheckBoxChecked(pCheckBox, false, true);
}
}
}
bool App::DoesCommandLineParmExist(string parm)
{
vector<string> parms = GetBaseApp()->GetCommandLineParms();
parm = ToLowerCaseString(parm);
for (int i = 0; i < parms.size(); i++)
{
if (ToLowerCaseString(parms[i]) == parm) return true;
}
return false;
}
bool App::Init()
{
#ifdef WINAPI
InitUnhandledExceptionFilter();
#endif
SetDefaultButtonStyle(Button2DComponent::BUTTON_STYLE_CLICK_ON_TOUCH_RELEASE);
SetManualRotationMode(false);
bool bScaleScreenActive = true; //if true, we'll stretch every screen to the coords below
int scaleToX = 480;
int scaleToY = 320;
if (IsTabletSize() || IsDesktop())
{
scaleToX = 1024;
scaleToY = 768;
}
/*
if (IsIphoneSize || IsIphone4Size || IsIPADSize)
{
bScaleScreenActive = false;
}
*/
switch (GetEmulatedPlatformID())
{
//special handling for certain platforms to tweak the video settings
case PLATFORM_ID_WEBOS:
//if we do this, everything will be stretched/zoomed to fit the screen
if (IsIPADSize)
{
//doesn't need rotation
SetLockedLandscape(false); //because it's set in the app manifest, we don't have to rotate ourselves
SetupScreenInfo(GetPrimaryGLX(), GetPrimaryGLY(), ORIENTATION_PORTRAIT);
if (bScaleScreenActive)
SetupFakePrimaryScreenSize(scaleToX,scaleToY); //game will think it's this size, and will be scaled up
}
else
{
//but the phones do
SetLockedLandscape(true); //we don't allow portrait mode for this game
if (bScaleScreenActive)
SetupFakePrimaryScreenSize(scaleToX,scaleToY); //game will think it's this size, and will be scaled up
}
break;
case PLATFORM_ID_IOS:
SetLockedLandscape(true); //we stay in portrait but manually rotate, gives better fps on older devices
if (bScaleScreenActive)
SetupFakePrimaryScreenSize(scaleToX,scaleToY); //game will think it's this size, and will be scaled up
break;
default:
//Default settings for other platforms
SetLockedLandscape(false); //we don't allow portrait mode for this game
SetupScreenInfo(GetPrimaryGLX(), GetPrimaryGLY(), ORIENTATION_PORTRAIT);
if (bScaleScreenActive)
SetupFakePrimaryScreenSize(scaleToX,scaleToY); //game will think it's this size, and will be scaled up
}
//L_ParticleSystem::init(2000);
SetInputMode(INPUT_MODE_SEPARATE_MOVE_TOUCHES); //this game has so much move touching, I handle them separately for performance reasons
if (m_bInitted)
{
return true;
}
if (!BaseApp::Init())
{
return false;
}
LogMsg("Initializing Dink HD %s", GetVersionString().c_str());
vector<string> parm = GetBaseApp()->GetCommandLineParms();
string parms;
for (int i = 0; i < parm.size(); i++)
{
if (i != 0) parms += " ";
parms += parm[i];
}
if (!parm.empty())
{
string text = string("Run with parms: " + string(parms) + "\r\n\r\n");
#ifdef WINAPI
OutputDebugString(text.c_str());
#endif
AddText(text.c_str(), (GetSavePath() + "log.txt").c_str());
}
m_adManager.Init();
#ifdef RT_CHARTBOOST_ENABLED
AdProviderChartBoost *pProvider = new AdProviderChartBoost;
#ifdef PLATFORM_ANDROID
assert(!"No longer using chartboost!");
pProvider->SetupInfo("", ""); //Dink HD Android
#else
pProvider->SetupInfo("", ""); //Dink HD iOS
#endif
m_adManager.AddProvider(pProvider);
pProvider->CacheShowInterstitial();
// pProvider->CacheShowMoreApps();
m_adManager.GetProviderByType(AD_PROVIDER_CHARTBOOST)->ShowInterstitial();
//m_adManager.GetProviderByType(AD_PROVIDER_CHARTBOOST)->ShowMoreApps();
#endif
LogMsg("Save path is %s", GetSavePath().c_str());
if (GetEmulatedPlatformID() == PLATFORM_ID_HTML5)
{
g_dglo.m_bUsingDinkPak = true;
}
if (g_dglo.m_bUsingDinkPak)
{
FileSystemZip *pFileSystem = new FileSystemZip();
if (!pFileSystem->Init(GetBaseAppPath()+ "dink/dink.pak"))
{
LogMsg("Error finding APK file to load resources");
}
//pFileSystem->SetRootDirectory("dink");
GetFileManager()->MountFileSystem(pFileSystem);
}
if (GetPlatformID() != PLATFORM_ID_ANDROID)
{
/*
FileSystemZip *pFileSystem = new FileSystemZip();
if (!pFileSystem->Init(GetBaseAppPath()+ "dink/dink.pak"))
{
LogMsg("Error finding APK file to load resources");
}
GetFileManager()->MountFileSystem(pFileSystem);
*/
/*
vector<string> contents = pFileSystem->GetContents();
LogMsg("Listing all %d files.", contents.size());
for (int i=0; i < contents.size(); i++)
{
LogMsg("%s", contents[i].c_str());
}
*/
RemoveFile(GetDMODRootPath()+"temp.dmod");
RemoveFile("temp.dmod");
}
switch (GetPlatformID())
{
case PLATFORM_ID_WINDOWS:
case PLATFORM_ID_BBX:
case PLATFORM_ID_WEBOS:
case PLATFORM_ID_HTML5:
CreateDirectoryRecursively("", GetDMODRootPath());
break;
default:
CreateAppCacheDirIfNeeded();
break;
}
if (IsLargeScreen())
{
if (!GetFont(FONT_SMALL)->Load("interface/font_normalx2.rtfont")) return false;
if (!GetFont(FONT_LARGE)->Load("interface/font_bigx2.rtfont")) return false;
} else
{
if (!GetFont(FONT_SMALL)->Load("interface/font_normal.rtfont")) return false;
if (!GetFont(FONT_LARGE)->Load("interface/font_big.rtfont")) return false;
}
//GetFont(FONT_SMALL)->SetSmoothing(false);
#ifndef FORCE_DMOD_SUPPORT
if (GetEmulatedPlatformID() == PLATFORM_ID_IOS)
{
//m_bHasDMODSupport = false;
}
#endif
#ifdef _DEBUG
GetBaseApp()->SetFPSVisible(true);
#endif
bool bFileExisted;
m_varDB.Load("save.dat", &bFileExisted);
GetApp()->GetVarWithDefault("smoothing",uint32(0))->GetUINT32();
GetApp()->GetVarWithDefault("buttons",uint32(0));
GetApp()->GetVarWithDefault("music_vol",1.0f)->GetFloat();
GetApp()->GetVarWithDefault("gui_transparency",0.35f)->GetFloat();
#ifdef PLATFORM_WINDOWS
GetApp()->GetVarWithDefault("checkerboard_fix", uint32(1)); //default to on for Windows
//If you don't have directx, just comment out this and remove the dx lib dependency, directx is only used for the
//gamepad input on windows
GetGamepadManager()->AddProvider(new GamepadProviderDirectX); //use directx joysticks
#endif
#ifdef RT_MOGA_ENABLED
GetGamepadManager()->AddProvider( new GamepadProviderMoga);
GetBaseApp()->SetAllowScreenDimming(false);
#endif
if (GetVar("check_icade")->GetUINT32() != 0)
{
AddIcadeProvider();
}
#if defined(PLATFORM_IOS) && defined(RT_IOS_60BEAT_GAMEPAD_SUPPORT)
//startup the 60beat gamepad stuff.. really, we should only do this if they've checked to use it in options
//or such because their driver may slow us down.. unsure
if (GetVar("check_60beat")->GetUINT32() != 0)
{
//startup the 60beat gamepad stuff
GetGamepadManager()->AddProvider(new GamepadProvider60Beat);
GetBaseApp()->SetAllowScreenDimming(false);
}
#endif
if (GetEmulatedPlatformID() == PLATFORM_ID_WINDOWS || GetEmulatedPlatformID() == PLATFORM_ID_OSX || GetEmulatedPlatformID() == PLATFORM_ID_HTML5)
{
//should we draw that onscreen GUI stuff for Dink?
m_bUsingTouchScreen = false;
} else
{
m_bUsingTouchScreen = true;
}
if (IsIPADSize && GetEmulatedPlatformID() != PLATFORM_ID_WEBOS)
{
GetApp()->GetVarWithDefault("fpsLimit", Variant(uint32(VIDEO_FPS_LIMIT_OFF)))->GetUINT32();
}
UpdateVideoSettings();
//preload audio
if (GetEmulatedPlatformID() == PLATFORM_ID_IOS)
{
//use our own DLS, as iPhone/iPad don't have any midi system
g_audioManager.SetDLS("dink/midi/TimGM6mbTiny.dls");
}
#ifdef _DEBUG
#endif
#ifdef _WIN32
//temporary while I make movies
//GetApp()->SetCheatsEnabled(true);
#endif
GetApp()->SetCheatsEnabled(true);
bool bSound = m_varDB.GetVarWithDefault("sound", uint32(1))->GetUINT32() != 0;
GetAudioManager()->SetSoundEnabled(bSound);
//GetAudioManager()->SetMusicEnabled(!GetApp()->GetVar("musicDisabled")->GetUINT32());
GetAudioManager()->SetMusicVol(GetApp()->GetVar("music_vol")->GetFloat());
GetAudioManager()->Preload("audio/click.wav");
InitDinkPaths(GetBaseAppPath(), "dink", "");
GetBaseApp()->m_sig_pre_enterbackground.connect(1, boost::bind(&App::OnPreEnterBackground, this, _1));
GetBaseApp()->m_sig_loadSurfaces.connect(1, boost::bind(&App::OnLoadSurfaces, this));
//when screen size changes we'll unload surfaces
GetBaseApp()->m_sig_unloadSurfaces.connect(1, boost::bind(&App::OnUnloadSurfaces, this));
#ifdef WINAPI
int videox = GetApp()->GetVarWithDefault("video_x", uint32(640))->GetUINT32();
int videoy = GetApp()->GetVarWithDefault("video_y", uint32(480))->GetUINT32();
int fullscreen = GetApp()->GetVarWithDefault("fullscreen", uint32(1))->GetUINT32();
bool borderlessfullscreen = GetApp()->GetVarWithDefault("fullscreen", uint32(0))->GetUINT32();
if (DoesCommandLineParmExist("-window") || DoesCommandLineParmExist("-windowed"))
{
fullscreen = false;
GetApp()->GetVar("fullscreen")->Set(uint32(0));
}
if (DoesCommandLineParmExist("-debug") )
{
g_script_debug_mode = true;
}
if (fullscreen && g_bUseBorderlessFullscreenOnWindows)
{
LogMsg("Setting fullscreen...");
//GetMessageManager()->SendGUI(MESSAGE_TYPE_GUI_TOGGLE_FULLSCREEN, 0, 0); //lParam holds a lot of random data about the press, look it up if
g_bIsFullScreen = false; //because we're using toggle..
OnFullscreenToggleRequest();
}
else
{
/*
if (videox != 0 && videoy != 0)
{
//remember old setup
SetVideoMode(videox, videoy, false, 0);
}
*/
}
#endif
return true;
}
void App::OnPreEnterBackground(VariantList *pVList)
{
SaveAllData();
}
void App::OnExitApp(VariantList *pVarList)
{
LogMsg("Exiting the app");
OSMessage o;
o.m_type = OSMessage::MESSAGE_FINISH_APP;
GetBaseApp()->AddOSMessage(o);
}
void App::Kill()
{
if (!IsInBackground())
{
SaveAllData();
}
finiObjects();
BaseApp::Kill();
g_pApp = NULL; //make sure nobody elses access this
}
void App::RemoveAndAttachAllAvailableGamepads()
{
ArcadeInputComponent *pComp = (ArcadeInputComponent*) GetEntityRoot()->GetComponentByName("ArcadeInput");
assert(pComp);
for (int i=0; i < GetGamepadManager()->GetGamepadCount(); i++)
{
Gamepad *pPad = GetGamepadManager()->GetGamepad((eGamepadID)i);
pPad->ConnectToArcadeComponent(pComp, true, true);
//if we cared about the analog sticks too, we'd do this:
//pPad->m_sig_left_stick.connect(1, boost::bind(&OnGamepadStickUpdate, this, _1));
//pPad->m_sig_right_stick.connect(1, boost::bind(&OnGamepadStickUpdate, this, _1));
}
}
void App::RemoveAndroidKeyboardKeys()
{
ArcadeInputComponent *pComp = (ArcadeInputComponent*) GetEntityRoot()->GetComponentByName("ArcadeInput");
//first clear out all old ones to be safe
VariantList vList((string)"Keyboard");
pComp->GetFunction("RemoveKeyBindingsStartingWith")->sig_function(&vList);
}
void App::AddDroidKeyboardKeys()
{
if (GetEmulatedPlatformID() == PLATFORM_ID_ANDROID)
{
ArcadeInputComponent *pComp = (ArcadeInputComponent*) GetEntityRoot()->GetComponentByName("ArcadeInput");
RemoveAndroidKeyboardKeys();
//I think the ASWZ binding thing is for the control pad on the xperia play??
AddKeyBinding(pComp, "KeyboardLeft",'A', VIRTUAL_KEY_DIR_LEFT);
AddKeyBinding(pComp, "KeyboardRight",'S', VIRTUAL_KEY_DIR_RIGHT);
AddKeyBinding(pComp, "KeyboardUp", 'W', VIRTUAL_KEY_DIR_UP);
AddKeyBinding(pComp, "KeyboardDown", 'Z', VIRTUAL_KEY_DIR_DOWN);
AddKeyBinding(pComp, "KeyboardAltMagic", 8, VIRTUAL_KEY_GAME_MAGIC);
AddKeyBinding(pComp, "KeyboardInventory", 'I', VIRTUAL_KEY_GAME_INVENTORY);
AddKeyBinding(pComp, "KeyboardAltTalk", 13, VIRTUAL_KEY_GAME_TALK);
AddKeyBinding(pComp, "KeyboardFire", VIRTUAL_KEY_DIR_CENTER, VIRTUAL_KEY_GAME_FIRE);
AddKeyBinding(pComp, "KeyboardFire2", 'X', VIRTUAL_KEY_GAME_FIRE);
// AddKeyBinding(pComp, "KeyboardAltFire", VIRTUAL_KEY_SHIFT, VIRTUAL_KEY_GAME_FIRE);
}
}
void App::Update()
{
BaseApp::Update();
m_adManager.Update();
g_gamepadManager.Update();
if (!m_bDidPostInit)
{
m_bDidPostInit = true;
m_special = GetSystemData() != C_PIRATED_NO;
//build a GUI node
Entity *pGUIEnt = GetEntityRoot()->AddEntity(new Entity("GUI"));
#ifdef RT_EXPIRING
time_t rawtime, expiretime;
time(&rawtime);
expiretime = 1290050035 + ((3600)*24)*8; //expire in 8 days from Nov 18
bool bExpired = expiretime < rawtime;
if (bExpired)
{
ExpiredMenuCreate(pGUIEnt);
return;
}
#endif
ArcadeInputComponent *pComp = (ArcadeInputComponent*) GetEntityRoot()->AddComponent(new ArcadeInputComponent);
RemoveAndAttachAllAvailableGamepads();
//add key bindings, I may want to move these later if I add a custom key config...
AddKeyBinding(pComp, "Left", VIRTUAL_KEY_DIR_LEFT, VIRTUAL_KEY_DIR_LEFT);
AddKeyBinding(pComp, "Right", VIRTUAL_KEY_DIR_RIGHT, VIRTUAL_KEY_DIR_RIGHT);
AddKeyBinding(pComp, "Up", VIRTUAL_KEY_DIR_UP, VIRTUAL_KEY_DIR_UP);
AddKeyBinding(pComp, "Down", VIRTUAL_KEY_DIR_DOWN, VIRTUAL_KEY_DIR_DOWN);
AddKeyBinding(pComp, "Talk", ' ', VIRTUAL_KEY_GAME_TALK);
AddKeyBinding(pComp, "GamePadInventory", VIRTUAL_DPAD_SELECT, VIRTUAL_KEY_GAME_INVENTORY);
AddKeyBinding(pComp, "GamePadInventory2", VIRTUAL_DPAD_BUTTON_UP, VIRTUAL_KEY_GAME_INVENTORY);
AddKeyBinding(pComp, "GamePadEscape", VIRTUAL_DPAD_START, VIRTUAL_KEY_BACK, true);
AddKeyBinding(pComp, "GamePadFire", VIRTUAL_DPAD_BUTTON_DOWN, VIRTUAL_KEY_GAME_FIRE);
AddKeyBinding(pComp, "GamePadTalk", VIRTUAL_DPAD_BUTTON_RIGHT, VIRTUAL_KEY_GAME_TALK);
AddKeyBinding(pComp, "GamePadMagic", VIRTUAL_DPAD_BUTTON_LEFT, VIRTUAL_KEY_GAME_MAGIC);
AddKeyBinding(pComp, "GamePadSpeedup", VIRTUAL_DPAD_LBUTTON, 'M', true);
AddKeyBinding(pComp, "GamePadSpeedup2", VIRTUAL_DPAD_RBUTTON, 9);
AddKeyBinding(pComp, "GamePadInventory3", VIRTUAL_DPAD_LTRIGGER, VIRTUAL_KEY_GAME_INVENTORY);
AddKeyBinding(pComp, "GamePadPause", VIRTUAL_DPAD_RTRIGGER, VIRTUAL_KEY_BACK, true);
//if (IsDesktop())
{
AddKeyBinding(pComp, "Inventory", 13, VIRTUAL_KEY_GAME_INVENTORY);
AddKeyBinding(pComp, "Magic", VIRTUAL_KEY_SHIFT, VIRTUAL_KEY_GAME_MAGIC);
AddKeyBinding(pComp, "Fire", VIRTUAL_KEY_CONTROL, VIRTUAL_KEY_GAME_FIRE);
AddKeyBinding(pComp, "Speedup", 9, 9); //handle tab
AddKeyBinding(pComp, "Quicksave", VIRTUAL_KEY_F1, VIRTUAL_KEY_F1);
AddKeyBinding(pComp, "Quickload", VIRTUAL_KEY_F8, VIRTUAL_KEY_F8);
}
if (GetVar("check_icade")->GetUINT32() == 0)
{
AddDroidKeyboardKeys();
}
#ifdef _DEBUG
// BrowseMenuCreate(pGUIEnt);
MainMenuCreate(pGUIEnt);
#else
MainMenuCreate(pGUIEnt);
#endif
}
else
{
CheckForHotkeys();
}
}
void App::Draw()
{
BaseApp::Draw();
}
void App::OnScreenSizeChange()
{
#ifdef _DEBUG
LogMsg("Got OnScreenSizeChange");
#endif
BaseApp::OnScreenSizeChange();
if (GetPrimaryGLX() != 0)
{
SetupOrtho();
DinkOnForeground(); //rebuild lost surfaces
if (GetDinkGameState() != DINK_GAME_STATE_PLAYING)
{
PrepareForGL();
}
}
#ifdef WINAPI
GetApp()->GetVar("fullscreen")->Set(uint32(g_bIsFullScreen));
GetApp()->GetVar("videox")->Set(uint32(GetPrimaryGLX()));
GetApp()->GetVar("videoy")->Set(uint32(GetPrimaryGLY()));
//GetApp()->GetVarWithDefault("borderless_fullscreen", uint32(g_bUseBorderlessFullscreenOnWindows))->Set(uint32(0));
#endif
}
void App::GetServerInfo( string &server, uint32 &port )
{
#if defined (_DEBUG) && defined(WIN32)
// server = "localhost";
// port = 8080;
server = "rtsoft.com";
port = 80;
#else
server = "rtsoft.com";
port = 80;
#endif
}
int App::GetSpecial()
{
return m_special; //1 means pirated copy
}
Variant * App::GetVar( const string &keyName )
{
return GetShared()->GetVar(keyName);
}
std::string App::GetVersionString()
{
if (IsDesktop()) return m_desktopVersionString;
return m_versionString;
}
float App::GetVersion()
{
if (IsDesktop()) return m_desktopVersion;
return m_version;
}
int App::GetBuild()
{
if (IsDesktop()) return m_desktopBuild;
return m_build;
}
void App::OnMemoryWarning()
{
BaseApp::OnMemoryWarning();
GetAudioManager()->KillCachedSounds(false, true, 0, 1, false);
DinkUnloadUnusedGraphicsByUsageTime(100); //unload anything not used in the last second
}
void App::UpdateVideoSettings()
{
eVideoFPS v = (eVideoFPS)GetApp()->GetVarWithDefault("fpsLimit", Variant(uint32(VIDEO_FPS_LIMIT_OFF)))->GetUINT32();
OSMessage o;
o.m_type = OSMessage::MESSAGE_SET_FPS_LIMIT;
switch (v)
{
case VIDEO_FPS_LIMIT_ON:
o.m_x = 30;
break;
case VIDEO_FPS_LIMIT_OFF:
o.m_x = 2000;
break;
}
GetBaseApp()->AddOSMessage(o);
};
void App::SaveAllData()
{
if (GetDinkGameState() == DINK_GAME_STATE_PLAYING)
{
// SaveState(GetSavePath()+"state.dat");
SaveState(g_dglo.m_savePath+"continue_state.dat");
WriteLastPathSaved(g_dglo.m_savePath); //so we know what to reload
}
//GetAudioManager()->StopMusic();
m_varDB.Save("save.dat");
}
void App::OnEnterBackground()
{
//SaveAllData();
// DinkUnloadGraphicsCache();
/*
//I don't think we really need to uncache everything. If low memory is a problem we could though..
GetAudioManager()->KillCachedSounds(false, true, 0, 1, false);
LogMsg("Unloading some graphics");
DinkUnloadUnusedGraphicsByUsageTime(0); //unload anything not used in the last second
*/
BaseApp::OnEnterBackground();
}
void App::OnEnterForeground()
{
if (GetPrimaryGLX() == 0) return; //not ready, probably minimized on Windows
BaseApp::OnEnterForeground();
}
bool App::GetIconsOnLeft()
{
return GetShared()->GetVar("buttons")->GetUINT32() != 0;
}
//below is a sort of hack that allows "release" builds on windows to override the settings of whatever the shared main.cpp is telling
//us for window sizes
#ifdef _WINDOWS_
#include "win/app/main.h"
#endif
bool App::OnPreInitVideo()
{
if (!BaseApp::OnPreInitVideo()) return false;
#ifdef PLATFORM_HTML5
g_winVideoScreenX = 1024;
g_winVideoScreenY = 768;
#endif
//#if !defined(_DEBUG) && defined(WINAPI)
#ifdef WINAPI
#ifdef RT_SCRIPT_BUILD
SetEmulatedPlatformID(PLATFORM_ID_WINDOWS);
g_winVideoScreenX = 640;
g_winVideoScreenY = 480;
#endif
// g_winVideoScreenX = 800;
// g_winVideoScreenY = 1280;
//windows only
VariantDB temp;
temp.Load("save.dat");
Variant *pVarX = temp.GetVarIfExists("videox");
Variant *pVarY = temp.GetVarIfExists("videoy");
if (pVarX && pVarY && pVarX->GetUINT32() != 0 && pVarY->GetUINT32() != 0)
{
g_winVideoScreenX = pVarX->GetUINT32();
g_winVideoScreenY = pVarY->GetUINT32();
}
g_bIsFullScreen = temp.GetVarWithDefault("fullscreen", uint32(1))->GetUINT32();
if (DoesCommandLineParmExist("-window") || DoesCommandLineParmExist("-windowed"))
{
g_bIsFullScreen = false;
GetApp()->GetVar("fullscreen")->Set(uint32(0));
}
g_bUseBorderlessFullscreenOnWindows = temp.GetVarWithDefault("borderless_fullscreen", uint32(0))->GetUINT32() != 0;
#endif
return true;
}
//for palm webos and android
const char * GetBundlePrefix()
{
char * bundlePrefix = "com.rtsoft.";
return bundlePrefix;
}
//applicable to Palm WebOS builds only
const char * GetBundleName()
{
char * bundleName = "rtdink";
return bundleName;
}
void App::OnMessage( Message &m )
{
m_adManager.OnMessage(m); //gives the AdManager a way to handle messages
BaseApp::OnMessage(m);
}
void App::OnLoadSurfaces()
{
LogMsg("Reloading dink engine surfaces");
DinkOnForeground();
}
void App::OnUnloadSurfaces()
{
LogMsg("Unloading dink engine surfaces");
DinkUnloadUnusedGraphicsByUsageTime(0);
//g_transitionSurf.Kill();
}