AGS: Remove unused platforms

This commit is contained in:
Paul Gilbert 2021-03-13 10:54:19 -08:00
parent 766d3a5aa9
commit f758d84fe8
19 changed files with 0 additions and 6812 deletions

View File

@ -68,7 +68,6 @@
#include "ags/engine/main/main.h"
#include "ags/engine/main/main_allegro.h"
#include "ags/engine/media/audio/audio_system.h"
#include "ags/engine/platform/util/pe.h"
#include "ags/shared/gfx/image.h"
#include "ags/shared/util/directory.h"
#include "ags/shared/util/error.h"

View File

@ -1,732 +0,0 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
*/
#include "ags/shared/core/platform.h"
#if AGS_PLATFORM_OS_ANDROID
#include "ags/lib/allegro.h"
#include "ags/shared/platform/base/agsplatformdriver.h"
#include "ags/shared/ac/runtime_defines.h"
#include "ags/shared/main/config.h"
#include "ags/shared/plugin/agsplugin.h"
//include <stdio.h>
//include <dirent.h>
//include <sys/stat.h>
//include <ctype.h>
//include <unistd.h>
#include "ags/shared/util/string_compat.h"
//include <jni.h>
//include <android/log.h>
namespace AGS3 {
using namespace AGS::Shared;
#define ANDROID_CONFIG_FILENAME "android.cfg"
bool ReadConfiguration(char *filename, bool read_everything);
void ResetConfiguration();
struct AGSAndroid : AGSPlatformDriver {
virtual int CDPlayerCommand(int cmdd, int datt);
virtual void Delay(int millis);
virtual void DisplayAlert(const char *, ...);
virtual const char *GetAppOutputDirectory();
virtual unsigned long GetDiskFreeSpaceMB();
virtual const char *GetNoMouseErrorString();
virtual bool IsBackendResponsibleForMouseScaling() {
return true;
}
virtual eScriptSystemOSID GetSystemOSID();
virtual int InitializeCDPlayer();
virtual void PostAllegroExit();
virtual void SetGameWindowIcon();
virtual void ShutdownCDPlayer();
virtual void WriteStdOut(const char *fmt, ...);
virtual void WriteStdErr(const char *fmt, ...);
};
//int psp_return_to_menu = 1;
int psp_ignore_acsetup_cfg_file = 1;
int psp_clear_cache_on_room_change = 0;
int psp_rotation = 0;
int psp_config_enabled = 0;
char psp_translation[100];
char *psp_translations[100];
// Mouse option from Allegro.
extern int config_mouse_control_mode;
// Graphic options from the Allegro library.
extern int psp_gfx_scaling;
extern int psp_gfx_smoothing;
// Audio options from the Allegro library.
unsigned int psp_audio_samplerate = 44100;
int psp_audio_enabled = 1;
volatile int psp_audio_multithreaded = 1;
int psp_audio_cachesize = 10;
int psp_midi_enabled = 1;
int psp_midi_preload_patches = 0;
int psp_video_framedrop = 0;
int psp_gfx_renderer = 0;
int psp_gfx_super_sampling = 0;
int psp_gfx_smooth_sprites = 0;
int psp_debug_write_to_logcat = 0;
int config_mouse_longclick = 0;
extern int display_fps;
extern int want_exit;
extern void PauseGame();
extern void UnPauseGame();
extern int main(int argc, char *argv[]);
char android_base_directory[256];
char android_app_directory[256];
char psp_game_file_name[256];
char *psp_game_file_name_pointer = psp_game_file_name;
bool psp_load_latest_savegame = false;
extern char saveGameDirectory[260];
extern const char *loadSaveGameOnStartup;
char lastSaveGameName[200];
extern JavaVM *android_jni_vm;
JNIEnv *java_environment;
jobject java_object;
jclass java_class;
jmethodID java_messageCallback;
jmethodID java_blockExecution;
jmethodID java_swapBuffers;
jmethodID java_setRotation;
jmethodID java_enableLongclick;
bool reset_configuration = false;
extern "C"
{
const int CONFIG_IGNORE_ACSETUP = 0;
const int CONFIG_CLEAR_CACHE = 1;
const int CONFIG_AUDIO_RATE = 2;
const int CONFIG_AUDIO_ENABLED = 3;
const int CONFIG_AUDIO_THREADED = 4;
const int CONFIG_AUDIO_CACHESIZE = 5;
const int CONFIG_MIDI_ENABLED = 6;
const int CONFIG_MIDI_PRELOAD = 7;
const int CONFIG_VIDEO_FRAMEDROP = 8;
const int CONFIG_GFX_RENDERER = 9;
const int CONFIG_GFX_SMOOTHING = 10;
const int CONFIG_GFX_SCALING = 11;
const int CONFIG_GFX_SS = 12;
const int CONFIG_ROTATION = 13;
const int CONFIG_ENABLED = 14;
const int CONFIG_DEBUG_FPS = 15;
const int CONFIG_GFX_SMOOTH_SPRITES = 16;
const int CONFIG_TRANSLATION = 17;
const int CONFIG_DEBUG_LOGCAT = 18;
const int CONFIG_MOUSE_METHOD = 19;
const int CONFIG_MOUSE_LONGCLICK = 20;
extern void android_debug_printf(const char *format, ...);
JNIEXPORT jboolean JNICALL
Java_com_bigbluecup_android_PreferencesActivity_readConfigFile(JNIEnv *env, jobject object, jstring directory) {
const char *cdirectory = env->GetStringUTFChars(directory, NULL);
chdir(cdirectory);
env->ReleaseStringUTFChars(directory, cdirectory);
ResetConfiguration();
return ReadConfiguration(ANDROID_CONFIG_FILENAME, true);
}
JNIEXPORT jboolean JNICALL
Java_com_bigbluecup_android_PreferencesActivity_writeConfigFile(JNIEnv *env, jobject object) {
FILE *config = fopen(ANDROID_CONFIG_FILENAME, "wb");
if (config) {
fprintf(config, "[misc]\n");
fprintf(config, "config_enabled = %d\n", psp_config_enabled);
fprintf(config, "rotation = %d\n", psp_rotation);
fprintf(config, "translation = %s\n", psp_translation);
fprintf(config, "[controls]\n");
fprintf(config, "mouse_method = %d\n", config_mouse_control_mode);
fprintf(config, "mouse_longclick = %d\n", config_mouse_longclick);
fprintf(config, "[compatibility]\n");
// fprintf(config, "ignore_acsetup_cfg_file = %d\n", psp_ignore_acsetup_cfg_file);
fprintf(config, "clear_cache_on_room_change = %d\n", psp_clear_cache_on_room_change);
fprintf(config, "[sound]\n");
fprintf(config, "samplerate = %d\n", psp_audio_samplerate);
fprintf(config, "enabled = %d\n", psp_audio_enabled);
fprintf(config, "threaded = %d\n", psp_audio_multithreaded);
fprintf(config, "cache_size = %d\n", psp_audio_cachesize);
fprintf(config, "[midi]\n");
fprintf(config, "enabled = %d\n", psp_midi_enabled);
fprintf(config, "preload_patches = %d\n", psp_midi_preload_patches);
fprintf(config, "[video]\n");
fprintf(config, "framedrop = %d\n", psp_video_framedrop);
fprintf(config, "[graphics]\n");
fprintf(config, "renderer = %d\n", psp_gfx_renderer);
fprintf(config, "smoothing = %d\n", psp_gfx_smoothing);
fprintf(config, "scaling = %d\n", psp_gfx_scaling);
fprintf(config, "super_sampling = %d\n", psp_gfx_super_sampling);
fprintf(config, "smooth_sprites = %d\n", psp_gfx_smooth_sprites);
fprintf(config, "[debug]\n");
fprintf(config, "show_fps = %d\n", (display_fps == 2) ? 1 : 0);
fprintf(config, "logging = %d\n", psp_debug_write_to_logcat);
fclose(config);
return true;
}
return false;
}
JNIEXPORT jint JNICALL
Java_com_bigbluecup_android_PreferencesActivity_readIntConfigValue(JNIEnv *env, jobject object, jint id) {
switch (id) {
case CONFIG_IGNORE_ACSETUP:
return psp_ignore_acsetup_cfg_file;
break;
case CONFIG_CLEAR_CACHE:
return psp_clear_cache_on_room_change;
break;
case CONFIG_AUDIO_RATE:
return psp_audio_samplerate;
break;
case CONFIG_AUDIO_ENABLED:
return psp_audio_enabled;
break;
case CONFIG_AUDIO_THREADED:
return psp_audio_multithreaded;
break;
case CONFIG_AUDIO_CACHESIZE:
return psp_audio_cachesize;
break;
case CONFIG_MIDI_ENABLED:
return psp_midi_enabled;
break;
case CONFIG_MIDI_PRELOAD:
return psp_midi_preload_patches;
break;
case CONFIG_VIDEO_FRAMEDROP:
return psp_video_framedrop;
break;
case CONFIG_GFX_RENDERER:
return psp_gfx_renderer;
break;
case CONFIG_GFX_SMOOTHING:
return psp_gfx_smoothing;
break;
case CONFIG_GFX_SCALING:
return psp_gfx_scaling;
break;
case CONFIG_GFX_SS:
return psp_gfx_super_sampling;
break;
case CONFIG_GFX_SMOOTH_SPRITES:
return psp_gfx_smooth_sprites;
break;
case CONFIG_ROTATION:
return psp_rotation;
break;
case CONFIG_ENABLED:
return psp_config_enabled;
break;
case CONFIG_DEBUG_FPS:
return (display_fps == 2) ? 1 : 0;
break;
case CONFIG_DEBUG_LOGCAT:
return psp_debug_write_to_logcat;
break;
case CONFIG_MOUSE_METHOD:
return config_mouse_control_mode;
break;
case CONFIG_MOUSE_LONGCLICK:
return config_mouse_longclick;
break;
default:
return 0;
break;
}
}
JNIEXPORT jstring JNICALL
Java_com_bigbluecup_android_PreferencesActivity_readStringConfigValue(JNIEnv *env, jobject object, jint id, jstring value) {
switch (id) {
case CONFIG_TRANSLATION:
return env->NewStringUTF(&psp_translation[0]);
break;
}
}
JNIEXPORT void JNICALL
Java_com_bigbluecup_android_PreferencesActivity_setIntConfigValue(JNIEnv *env, jobject object, jint id, jint value) {
switch (id) {
case CONFIG_IGNORE_ACSETUP:
psp_ignore_acsetup_cfg_file = value;
break;
case CONFIG_CLEAR_CACHE:
psp_clear_cache_on_room_change = value;
break;
case CONFIG_AUDIO_RATE:
psp_audio_samplerate = value;
break;
case CONFIG_AUDIO_ENABLED:
psp_audio_enabled = value;
break;
case CONFIG_AUDIO_THREADED:
psp_audio_multithreaded = value;
break;
case CONFIG_AUDIO_CACHESIZE:
psp_audio_cachesize = value;
break;
case CONFIG_MIDI_ENABLED:
psp_midi_enabled = value;
break;
case CONFIG_MIDI_PRELOAD:
psp_midi_preload_patches = value;
break;
case CONFIG_VIDEO_FRAMEDROP:
psp_video_framedrop = value;
break;
case CONFIG_GFX_RENDERER:
psp_gfx_renderer = value;
break;
case CONFIG_GFX_SMOOTHING:
psp_gfx_smoothing = value;
break;
case CONFIG_GFX_SCALING:
psp_gfx_scaling = value;
break;
case CONFIG_GFX_SS:
psp_gfx_super_sampling = value;
break;
case CONFIG_GFX_SMOOTH_SPRITES:
psp_gfx_smooth_sprites = value;
break;
case CONFIG_ROTATION:
psp_rotation = value;
break;
case CONFIG_ENABLED:
psp_config_enabled = value;
break;
case CONFIG_DEBUG_FPS:
display_fps = (value == 1) ? 2 : 0;
break;
case CONFIG_DEBUG_LOGCAT:
psp_debug_write_to_logcat = value;
break;
case CONFIG_MOUSE_METHOD:
config_mouse_control_mode = value;
break;
case CONFIG_MOUSE_LONGCLICK:
config_mouse_longclick = value;
break;
default:
break;
}
}
JNIEXPORT void JNICALL
Java_com_bigbluecup_android_PreferencesActivity_setStringConfigValue(JNIEnv *env, jobject object, jint id, jstring value) {
const char *cstring = env->GetStringUTFChars(value, NULL);
switch (id) {
case CONFIG_TRANSLATION:
strcpy(psp_translation, cstring);
break;
default:
break;
}
env->ReleaseStringUTFChars(value, cstring);
}
JNIEXPORT jint JNICALL
Java_com_bigbluecup_android_PreferencesActivity_getAvailableTranslations(JNIEnv *env, jobject object, jobjectArray translations) {
int i = 0;
int length;
DIR *dir;
struct dirent *entry;
char buffer[200];
dir = opendir(".");
if (dir) {
while ((entry = readdir(dir)) != 0) {
length = strlen(entry->d_name);
if (length > 4) {
if (ags_stricmp(&entry->d_name[length - 4], ".tra") == 0) {
memset(buffer, 0, 200);
strncpy(buffer, entry->d_name, length - 4);
psp_translations[i] = (char *)malloc(strlen(buffer) + 1);
strcpy(psp_translations[i], buffer);
env->SetObjectArrayElement(translations, i, env->NewStringUTF(&buffer[0]));
i++;
}
}
}
closedir(dir);
}
return i;
}
JNIEXPORT void JNICALL
Java_com_bigbluecup_android_EngineGlue_pauseEngine(JNIEnv *env, jobject object) {
PauseGame();
}
JNIEXPORT void JNICALL
Java_com_bigbluecup_android_EngineGlue_resumeEngine(JNIEnv *env, jobject object) {
UnPauseGame();
}
JNIEXPORT void JNICALL
Java_com_bigbluecup_android_EngineGlue_shutdownEngine(JNIEnv *env, jobject object) {
want_exit = 1;
}
JNIEXPORT jboolean JNICALL
Java_com_bigbluecup_android_EngineGlue_startEngine(JNIEnv *env, jobject object, jclass stringclass, jstring filename, jstring directory, jstring appDirectory, jboolean loadLastSave) {
// Get JNI interfaces.
java_object = env->NewGlobalRef(object);
java_environment = env;
java_class = (jclass)java_environment->NewGlobalRef(java_environment->GetObjectClass(object));
java_messageCallback = java_environment->GetMethodID(java_class, "showMessage", "(Ljava/lang/String;)V");
java_blockExecution = java_environment->GetMethodID(java_class, "blockExecution", "()V");
java_setRotation = java_environment->GetMethodID(java_class, "setRotation", "(I)V");
java_enableLongclick = java_environment->GetMethodID(java_class, "enableLongclick", "()V");
// Initialize JNI for Allegro.
android_allegro_initialize_jni(java_environment, java_class, java_object);
// Get the file to run from Java.
const char *cpath = java_environment->GetStringUTFChars(filename, NULL);
strcpy(psp_game_file_name, cpath);
java_environment->ReleaseStringUTFChars(filename, cpath);
// Get the base directory (usually "/sdcard/ags").
const char *cdirectory = java_environment->GetStringUTFChars(directory, NULL);
chdir(cdirectory);
strcpy(android_base_directory, cdirectory);
java_environment->ReleaseStringUTFChars(directory, cdirectory);
// Get the app directory (something like "/data/data/com.bigbluecup.android.launcher")
const char *cappDirectory = java_environment->GetStringUTFChars(appDirectory, NULL);
strcpy(android_app_directory, cappDirectory);
java_environment->ReleaseStringUTFChars(appDirectory, cappDirectory);
// Reset configuration.
ResetConfiguration();
// Read general configuration.
ReadConfiguration(ANDROID_CONFIG_FILENAME, true);
// Get the games path.
char path[256];
strcpy(path, psp_game_file_name);
int lastindex = strlen(path) - 1;
while (path[lastindex] != '/') {
path[lastindex] = 0;
lastindex--;
}
chdir(path);
setenv("ULTRADIR", "..", 1);
// Read game specific configuration.
ReadConfiguration(ANDROID_CONFIG_FILENAME, false);
// Set the screen rotation.
if (psp_rotation > 0)
java_environment->CallVoidMethod(java_object, java_setRotation, psp_rotation);
if (config_mouse_longclick > 0)
java_environment->CallVoidMethod(java_object, java_enableLongclick);
psp_load_latest_savegame = loadLastSave;
// Start the engine main function.
main(1, &psp_game_file_name_pointer);
// Explicitly quit here, otherwise the app will hang forever.
exit(0);
return true;
}
void selectLatestSavegame() {
DIR *dir;
struct dirent *entry;
struct stat statBuffer;
char buffer[200];
time_t lastTime = 0;
dir = opendir(saveGameDirectory);
if (dir) {
while ((entry = readdir(dir)) != 0) {
if (ags_strnicmp(entry->d_name, "agssave", 7) == 0) {
if (ags_stricmp(entry->d_name, "agssave.999") != 0) {
strcpy(buffer, saveGameDirectory);
strcat(buffer, entry->d_name);
stat(buffer, &statBuffer);
if (statBuffer.st_mtime > lastTime) {
strcpy(lastSaveGameName, buffer);
loadSaveGameOnStartup = lastSaveGameName;
lastTime = statBuffer.st_mtime;
}
}
}
}
closedir(dir);
}
}
}
int ReadInteger(int *variable, const ConfigTree &cfg, char *section, char *name, int minimum, int maximum, int default_value) {
if (reset_configuration) {
*variable = default_value;
return 0;
}
int temp = INIreadint(cfg, section, name);
if (temp == -1)
return 0;
if ((temp < minimum) || (temp > maximum))
temp = default_value;
*variable = temp;
return 1;
}
int ReadString(char *variable, const ConfigTree &cfg, char *section, char *name, char *default_value) {
if (reset_configuration) {
strcpy(variable, default_value);
return 0;
}
String temp;
if (!INIreaditem(cfg, section, name, temp))
temp = default_value;
strcpy(variable, temp);
return 1;
}
void ResetConfiguration() {
reset_configuration = true;
ReadConfiguration(ANDROID_CONFIG_FILENAME, true);
reset_configuration = false;
}
bool ReadConfiguration(char *filename, bool read_everything) {
ConfigTree cfg;
if (IniUtil::Read(filename, cfg) || reset_configuration) {
// ReadInteger((int*)&psp_disable_powersaving, "misc", "disable_power_saving", 0, 1, 1);
// ReadInteger((int*)&psp_return_to_menu, "misc", "return_to_menu", 0, 1, 1);
ReadString(&psp_translation[0], cfg, "misc", "translation", "default");
ReadInteger((int *)&psp_config_enabled, cfg, "misc", "config_enabled", 0, 1, 0);
if (!psp_config_enabled && !read_everything)
return true;
ReadInteger(&psp_debug_write_to_logcat, cfg, "debug", "logging", 0, 1, 0);
ReadInteger(&display_fps, cfg, "debug", "show_fps", 0, 1, 0);
if (display_fps == 1)
display_fps = 2;
ReadInteger((int *)&psp_rotation, cfg, "misc", "rotation", 0, 2, 0);
// ReadInteger((int*)&psp_ignore_acsetup_cfg_file, "compatibility", "ignore_acsetup_cfg_file", 0, 1, 0);
ReadInteger((int *)&psp_clear_cache_on_room_change, cfg, "compatibility", "clear_cache_on_room_change", 0, 1, 0);
ReadInteger((int *)&psp_audio_samplerate, cfg, "sound", "samplerate", 0, 44100, 44100);
ReadInteger((int *)&psp_audio_enabled, cfg, "sound", "enabled", 0, 1, 1);
ReadInteger((int *)&psp_audio_multithreaded, cfg, "sound", "threaded", 0, 1, 1);
ReadInteger((int *)&psp_audio_cachesize, cfg, "sound", "cache_size", 1, 50, 10);
ReadInteger((int *)&psp_midi_enabled, cfg, "midi", "enabled", 0, 1, 1);
ReadInteger((int *)&psp_midi_preload_patches, cfg, "midi", "preload_patches", 0, 1, 0);
ReadInteger((int *)&psp_video_framedrop, cfg, "video", "framedrop", 0, 1, 0);
ReadInteger((int *)&psp_gfx_renderer, cfg, "graphics", "renderer", 0, 2, 0);
ReadInteger((int *)&psp_gfx_smoothing, cfg, "graphics", "smoothing", 0, 1, 1);
ReadInteger((int *)&psp_gfx_scaling, cfg, "graphics", "scaling", 0, 2, 1);
ReadInteger((int *)&psp_gfx_super_sampling, cfg, "graphics", "super_sampling", 0, 1, 0);
ReadInteger((int *)&psp_gfx_smooth_sprites, cfg, "graphics", "smooth_sprites", 0, 1, 0);
ReadInteger((int *)&config_mouse_control_mode, cfg, "controls", "mouse_method", 0, 1, 0);
ReadInteger((int *)&config_mouse_longclick, cfg, "controls", "mouse_longclick", 0, 1, 1);
return true;
}
return false;
}
int AGSAndroid::CDPlayerCommand(int cmdd, int datt) {
return 1;//cd_player_control(cmdd, datt);
}
void AGSAndroid::DisplayAlert(const char *text, ...) {
char displbuf[2000];
va_list ap;
va_start(ap, text);
vsprintf(displbuf, text, ap);
va_end(ap);
// It is possible that this is called from a thread that is not yet known
// to the Java VM. So attach it first before displaying the message.
JNIEnv *thread_env;
android_jni_vm->AttachCurrentThread(&thread_env, NULL);
__android_log_print(ANDROID_LOG_DEBUG, "AGSNative", "%s", displbuf);
jstring java_string = thread_env->NewStringUTF(displbuf);
thread_env->CallVoidMethod(java_object, java_messageCallback, java_string);
usleep(1000 * 1000);
thread_env->CallVoidMethod(java_object, java_blockExecution);
// android_jni_vm->DetachCurrentThread();
}
void AGSAndroid::Delay(int millis) {
usleep(millis * 1000);
}
unsigned long AGSAndroid::GetDiskFreeSpaceMB() {
// placeholder
return 100;
}
const char *AGSAndroid::GetNoMouseErrorString() {
return "This game requires a _GP(mouse). You need to configure and setup your mouse to play this game.\n";
}
eScriptSystemOSID AGSAndroid::GetSystemOSID() {
return eOS_Android;
}
int AGSAndroid::InitializeCDPlayer() {
return 1;//cd_player_init();
}
void AGSAndroid::PostAllegroExit() {
java_environment->DeleteGlobalRef(java_class);
}
void AGSAndroid::SetGameWindowIcon() {
// do nothing
}
void AGSAndroid::WriteStdOut(const char *fmt, ...) {
// TODO: this check should probably be done once when setting up output targets for logging
if (psp_debug_write_to_logcat) {
va_list args;
va_start(args, fmt);
__android_log_vprint(ANDROID_LOG_DEBUG, "AGSNative", fmt, args);
// NOTE: __android_log_* functions add trailing '\n'
va_end(args);
}
}
void AGSAndroid::WriteStdErr(const char *fmt, ...) {
// TODO: find out if Android needs separate implementation for stderr
if (psp_debug_write_to_logcat) {
va_list args;
va_start(args, fmt);
__android_log_vprint(ANDROID_LOG_DEBUG, "AGSNative", fmt, args);
// NOTE: __android_log_* functions add trailing '\n'
va_end(args);
}
}
void AGSAndroid::ShutdownCDPlayer() {
//cd_exit();
}
const char *AGSAndroid::GetAppOutputDirectory() {
return android_base_directory;
}
AGSPlatformDriver *AGSPlatformDriver::GetDriver() {
if (instance == NULL)
instance = new AGSAndroid();
return instance;
}
} // namespace AGS3
#endif

View File

@ -1,631 +0,0 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
*/
#include "ags/shared/core/platform.h"
#if AGS_PLATFORM_OS_IOS
//include <stdio.h>
//include <dirent.h>
//include <sys/stat.h>
//include <ctype.h>
#include "ags/lib/allegro.h"
#include "ags/shared/platform/base/agsplatformdriver.h"
#include "ags/shared/ac/runtime_defines.h"
#include "ags/shared/main/config.h"
#include "ags/shared/plugin/agsplugin.h"
#include "ags/shared/util/string_utils.h"
namespace AGS3 {
using namespace AGS::Shared;
#define IOS_CONFIG_FILENAME "ios.cfg"
extern char *ios_document_directory;
bool ReadConfiguration(char *filename, bool read_everything);
void ResetConfiguration();
//int psp_return_to_menu = 1;
int psp_ignore_acsetup_cfg_file = 1;
int psp_clear_cache_on_room_change = 0;
int psp_rotation = 0;
int psp_config_enabled = 0;
char psp_translation[100];
char *psp_translations[100];
// Mouse option from Allegro.
extern int config_mouse_control_mode;
// Graphic options from the Allegro library.
extern int psp_gfx_scaling;
extern int psp_gfx_smoothing;
// Audio options from the Allegro library.
unsigned int psp_audio_samplerate = 44100;
int psp_audio_enabled = 1;
volatile int psp_audio_multithreaded = 1;
int psp_audio_cachesize = 10;
int psp_midi_enabled = 1;
int psp_midi_preload_patches = 0;
int psp_video_framedrop = 0;
int psp_gfx_renderer = 0;
int psp_gfx_super_sampling = 0;
int psp_gfx_smooth_sprites = 0;
int psp_debug_write_to_logcat = 0;
int config_mouse_longclick = 0;
extern int display_fps;
extern int want_exit;
extern void PauseGame();
extern void UnPauseGame();
extern int main(int argc, char *argv[]);
char psp_game_file_name[256];
char *psp_game_file_name_pointer = psp_game_file_name;
bool psp_load_latest_savegame = false;
extern char saveGameDirectory[260];
extern const char *loadSaveGameOnStartup;
char lastSaveGameName[200];
bool reset_configuration = false;
const int CONFIG_IGNORE_ACSETUP = 0;
const int CONFIG_CLEAR_CACHE = 1;
const int CONFIG_AUDIO_RATE = 2;
const int CONFIG_AUDIO_ENABLED = 3;
const int CONFIG_AUDIO_THREADED = 4;
const int CONFIG_AUDIO_CACHESIZE = 5;
const int CONFIG_MIDI_ENABLED = 6;
const int CONFIG_MIDI_PRELOAD = 7;
const int CONFIG_VIDEO_FRAMEDROP = 8;
const int CONFIG_GFX_RENDERER = 9;
const int CONFIG_GFX_SMOOTHING = 10;
const int CONFIG_GFX_SCALING = 11;
const int CONFIG_GFX_SS = 12;
const int CONFIG_ROTATION = 13;
const int CONFIG_ENABLED = 14;
const int CONFIG_DEBUG_FPS = 15;
const int CONFIG_GFX_SMOOTH_SPRITES = 16;
const int CONFIG_TRANSLATION = 17;
const int CONFIG_DEBUG_LOGCAT = 18;
const int CONFIG_MOUSE_METHOD = 19;
const int CONFIG_MOUSE_LONGCLICK = 20;
struct AGSIOS : AGSPlatformDriver {
virtual int CDPlayerCommand(int cmdd, int datt);
virtual void Delay(int millis);
virtual void DisplayAlert(const char *, ...);
virtual const char *GetAppOutputDirectory();
virtual unsigned long GetDiskFreeSpaceMB();
virtual const char *GetNoMouseErrorString();
virtual bool IsBackendResponsibleForMouseScaling() {
return true;
}
virtual eScriptSystemOSID GetSystemOSID();
virtual int InitializeCDPlayer();
virtual void PostAllegroExit();
virtual void SetGameWindowIcon();
virtual void ShutdownCDPlayer();
};
bool readConfigFile(char *directory) {
chdir(directory);
ResetConfiguration();
return ReadConfiguration(IOS_CONFIG_FILENAME, true);
}
bool writeConfigFile() {
FILE *config = fopen(IOS_CONFIG_FILENAME, "wb");
if (config) {
fprintf(config, "[misc]\n");
fprintf(config, "config_enabled = %d\n", psp_config_enabled);
fprintf(config, "rotation = %d\n", psp_rotation);
fprintf(config, "translation = %s\n", psp_translation);
fprintf(config, "[controls]\n");
fprintf(config, "mouse_method = %d\n", config_mouse_control_mode);
fprintf(config, "mouse_longclick = %d\n", config_mouse_longclick);
fprintf(config, "[compatibility]\n");
fprintf(config, "clear_cache_on_room_change = %d\n", psp_clear_cache_on_room_change);
fprintf(config, "[sound]\n");
fprintf(config, "samplerate = %d\n", psp_audio_samplerate);
fprintf(config, "enabled = %d\n", psp_audio_enabled);
fprintf(config, "threaded = %d\n", psp_audio_multithreaded);
fprintf(config, "cache_size = %d\n", psp_audio_cachesize);
fprintf(config, "[midi]\n");
fprintf(config, "enabled = %d\n", psp_midi_enabled);
fprintf(config, "preload_patches = %d\n", psp_midi_preload_patches);
fprintf(config, "[video]\n");
fprintf(config, "framedrop = %d\n", psp_video_framedrop);
fprintf(config, "[graphics]\n");
fprintf(config, "renderer = %d\n", psp_gfx_renderer);
fprintf(config, "smoothing = %d\n", psp_gfx_smoothing);
fprintf(config, "scaling = %d\n", psp_gfx_scaling);
fprintf(config, "super_sampling = %d\n", psp_gfx_super_sampling);
fprintf(config, "smooth_sprites = %d\n", psp_gfx_smooth_sprites);
fprintf(config, "[debug]\n");
fprintf(config, "show_fps = %d\n", (display_fps == 2) ? 1 : 0);
fprintf(config, "logging = %d\n", psp_debug_write_to_logcat);
fclose(config);
return true;
}
return false;
}
int readIntConfigValue(int id) {
switch (id) {
case CONFIG_IGNORE_ACSETUP:
return psp_ignore_acsetup_cfg_file;
break;
case CONFIG_CLEAR_CACHE:
return psp_clear_cache_on_room_change;
break;
case CONFIG_AUDIO_RATE:
return psp_audio_samplerate;
break;
case CONFIG_AUDIO_ENABLED:
return psp_audio_enabled;
break;
case CONFIG_AUDIO_THREADED:
return psp_audio_multithreaded;
break;
case CONFIG_AUDIO_CACHESIZE:
return psp_audio_cachesize;
break;
case CONFIG_MIDI_ENABLED:
return psp_midi_enabled;
break;
case CONFIG_MIDI_PRELOAD:
return psp_midi_preload_patches;
break;
case CONFIG_VIDEO_FRAMEDROP:
return psp_video_framedrop;
break;
case CONFIG_GFX_RENDERER:
return psp_gfx_renderer;
break;
case CONFIG_GFX_SMOOTHING:
return psp_gfx_smoothing;
break;
case CONFIG_GFX_SCALING:
return psp_gfx_scaling;
break;
case CONFIG_GFX_SS:
return psp_gfx_super_sampling;
break;
case CONFIG_GFX_SMOOTH_SPRITES:
return psp_gfx_smooth_sprites;
break;
case CONFIG_ROTATION:
return psp_rotation;
break;
case CONFIG_ENABLED:
return psp_config_enabled;
break;
case CONFIG_DEBUG_FPS:
return (display_fps == 2) ? 1 : 0;
break;
case CONFIG_DEBUG_LOGCAT:
return psp_debug_write_to_logcat;
break;
case CONFIG_MOUSE_METHOD:
return config_mouse_control_mode;
break;
case CONFIG_MOUSE_LONGCLICK:
return config_mouse_longclick;
break;
default:
return 0;
break;
}
}
char *readStringConfigValue(int id) {
switch (id) {
case CONFIG_TRANSLATION:
return &psp_translation[0];
break;
}
}
void setIntConfigValue(int id, int value) {
switch (id) {
case CONFIG_IGNORE_ACSETUP:
psp_ignore_acsetup_cfg_file = value;
break;
case CONFIG_CLEAR_CACHE:
psp_clear_cache_on_room_change = value;
break;
case CONFIG_AUDIO_RATE:
psp_audio_samplerate = value;
break;
case CONFIG_AUDIO_ENABLED:
psp_audio_enabled = value;
break;
case CONFIG_AUDIO_THREADED:
psp_audio_multithreaded = value;
break;
case CONFIG_AUDIO_CACHESIZE:
psp_audio_cachesize = value;
break;
case CONFIG_MIDI_ENABLED:
psp_midi_enabled = value;
break;
case CONFIG_MIDI_PRELOAD:
psp_midi_preload_patches = value;
break;
case CONFIG_VIDEO_FRAMEDROP:
psp_video_framedrop = value;
break;
case CONFIG_GFX_RENDERER:
psp_gfx_renderer = value;
break;
case CONFIG_GFX_SMOOTHING:
psp_gfx_smoothing = value;
break;
case CONFIG_GFX_SCALING:
psp_gfx_scaling = value;
break;
case CONFIG_GFX_SS:
psp_gfx_super_sampling = value;
break;
case CONFIG_GFX_SMOOTH_SPRITES:
psp_gfx_smooth_sprites = value;
break;
case CONFIG_ROTATION:
psp_rotation = value;
break;
case CONFIG_ENABLED:
psp_config_enabled = value;
break;
case CONFIG_DEBUG_FPS:
display_fps = (value == 1) ? 2 : 0;
break;
case CONFIG_DEBUG_LOGCAT:
psp_debug_write_to_logcat = value;
break;
case CONFIG_MOUSE_METHOD:
config_mouse_control_mode = value;
break;
case CONFIG_MOUSE_LONGCLICK:
config_mouse_longclick = value;
break;
default:
break;
}
}
void setStringConfigValue(int id, char *value) {
switch (id) {
case CONFIG_TRANSLATION:
strcpy(psp_translation, value);
break;
default:
break;
}
}
/*
int getAvailableTranslations(char* translations)
{
int i = 0;
int length;
DIR* dir;
struct dirent* entry;
char buffer[200];
dir = opendir(".");
if (dir)
{
while ((entry = readdir(dir)) != 0)
{
length = strlen(entry->d_name);
if (length > 4)
{
if (ags_stricmp(&entry->d_name[length - 4], ".tra") == 0)
{
memset(buffer, 0, 200);
strncpy(buffer, entry->d_name, length - 4);
psp_translations[i] = (char*)malloc(strlen(buffer) + 1);
strcpy(psp_translations[i], buffer);
env->SetObjectArrayElement(translations, i, env->NewStringUTF(&buffer[0]));
i++;
}
}
}
closedir(dir);
}
return i;
}
*/
void selectLatestSavegame() {
DIR *dir;
struct dirent *entry;
struct stat statBuffer;
char buffer[200];
time_t lastTime = 0;
dir = opendir(saveGameDirectory);
if (dir) {
while ((entry = readdir(dir)) != 0) {
if (ags_strnicmp(entry->d_name, "agssave", 7) == 0) {
if (ags_stricmp(entry->d_name, "agssave.999") != 0) {
strcpy(buffer, saveGameDirectory);
strcat(buffer, entry->d_name);
stat(buffer, &statBuffer);
if (statBuffer.st_mtime > lastTime) {
strcpy(lastSaveGameName, buffer);
loadSaveGameOnStartup = lastSaveGameName;
lastTime = statBuffer.st_mtime;
}
}
}
}
closedir(dir);
}
}
int ReadInteger(int *variable, const ConfigTree &cfg, char *section, char *name, int minimum, int maximum, int default_value) {
if (reset_configuration) {
*variable = default_value;
return 0;
}
int temp = INIreadint(cfg, section, name);
if (temp == -1)
return 0;
if ((temp < minimum) || (temp > maximum))
temp = default_value;
*variable = temp;
return 1;
}
int ReadString(char *variable, const ConfigTree &cfg, char *section, char *name, char *default_value) {
if (reset_configuration) {
strcpy(variable, default_value);
return 0;
}
String temp;
if (!INIreaditem(cfg, section, name, temp))
temp = default_value;
strcpy(variable, temp);
return 1;
}
void ResetConfiguration() {
reset_configuration = true;
ReadConfiguration(IOS_CONFIG_FILENAME, true);
reset_configuration = false;
}
bool ReadConfiguration(char *filename, bool read_everything) {
ConfigTree cfg;
if (IniUtil::Read(filename, cfg) || reset_configuration) {
// ReadInteger((int*)&psp_disable_powersaving, "misc", "disable_power_saving", 0, 1, 1);
// ReadInteger((int*)&psp_return_to_menu, "misc", "return_to_menu", 0, 1, 1);
ReadString(&psp_translation[0], cfg, "misc", "translation", "default");
ReadInteger((int *)&psp_config_enabled, cfg, "misc", "config_enabled", 0, 1, 0);
if (!psp_config_enabled && !read_everything)
return true;
ReadInteger(&psp_debug_write_to_logcat, cfg, "debug", "logging", 0, 1, 0);
ReadInteger(&display_fps, cfg, "debug", "show_fps", 0, 1, 0);
if (display_fps == 1)
display_fps = 2;
ReadInteger((int *)&psp_rotation, cfg, "misc", "rotation", 0, 2, 0);
// ReadInteger((int*)&psp_ignore_acsetup_cfg_file, "compatibility", "ignore_acsetup_cfg_file", 0, 1, 0);
ReadInteger((int *)&psp_clear_cache_on_room_change, cfg, "compatibility", "clear_cache_on_room_change", 0, 1, 0);
ReadInteger((int *)&psp_audio_samplerate, cfg, "sound", "samplerate", 0, 44100, 44100);
ReadInteger((int *)&psp_audio_enabled, cfg, "sound", "enabled", 0, 1, 1);
ReadInteger((int *)&psp_audio_multithreaded, cfg, "sound", "threaded", 0, 1, 1);
ReadInteger((int *)&psp_audio_cachesize, cfg, "sound", "cache_size", 1, 50, 10);
ReadInteger((int *)&psp_midi_enabled, cfg, "midi", "enabled", 0, 1, 1);
ReadInteger((int *)&psp_midi_preload_patches, cfg, "midi", "preload_patches", 0, 1, 0);
ReadInteger((int *)&psp_video_framedrop, cfg, "video", "framedrop", 0, 1, 0);
ReadInteger((int *)&psp_gfx_renderer, cfg, "graphics", "renderer", 0, 2, 0);
ReadInteger((int *)&psp_gfx_smoothing, cfg, "graphics", "smoothing", 0, 1, 1);
ReadInteger((int *)&psp_gfx_scaling, cfg, "graphics", "scaling", 0, 2, 1);
ReadInteger((int *)&psp_gfx_super_sampling, cfg, "graphics", "super_sampling", 0, 1, 0);
ReadInteger((int *)&psp_gfx_smooth_sprites, cfg, "graphics", "smooth_sprites", 0, 1, 0);
ReadInteger((int *)&config_mouse_control_mode, cfg, "controls", "mouse_method", 0, 1, 0);
ReadInteger((int *)&config_mouse_longclick, cfg, "controls", "mouse_longclick", 0, 1, 1);
return true;
}
return false;
}
extern void ios_show_message_box(char *buffer);
volatile int ios_wait_for_ui = 0;
void startEngine(char *filename, char *directory, int loadLastSave) {
strcpy(psp_game_file_name, filename);
// Get the base directory (usually "/sdcard/ags").
chdir(directory);
// Reset configuration.
ResetConfiguration();
// Read general configuration.
ReadConfiguration(IOS_CONFIG_FILENAME, true);
// Get the games path.
char path[256];
strcpy(path, psp_game_file_name);
int lastindex = strlen(path) - 1;
while (path[lastindex] != '/') {
path[lastindex] = 0;
lastindex--;
}
chdir(path);
setenv("ULTRADIR", "..", 1);
// Read game specific configuration.
ReadConfiguration(IOS_CONFIG_FILENAME, false);
psp_load_latest_savegame = loadLastSave;
// Start the engine main function.
main(1, &psp_game_file_name_pointer);
// Explicitly quit here, otherwise the app will hang forever.
exit(0);
}
int AGSIOS::CDPlayerCommand(int cmdd, int datt) {
return 0;//cd_player_control(cmdd, datt);
}
void AGSIOS::DisplayAlert(const char *text, ...) {
char displbuf[2000];
va_list ap;
va_start(ap, text);
vsprintf(displbuf, text, ap);
va_end(ap);
printf("%s", displbuf);
ios_show_message_box(displbuf);
while (ios_wait_for_ui)
usleep(200);
}
void AGSIOS::Delay(int millis) {
usleep(millis);
}
unsigned long AGSIOS::GetDiskFreeSpaceMB() {
// placeholder
return 100;
}
const char *AGSIOS::GetNoMouseErrorString() {
return "This game requires a _GP(mouse). You need to configure and setup your mouse to play this game.\n";
}
eScriptSystemOSID AGSIOS::GetSystemOSID() {
return eOS_iOS;
}
int AGSIOS::InitializeCDPlayer() {
return 0;//cd_player_init();
}
void AGSIOS::PostAllegroExit() {
// do nothing
}
void AGSIOS::SetGameWindowIcon() {
// do nothing
}
void AGSIOS::ShutdownCDPlayer() {
//cd_exit();
}
const char *AGSIOS::GetAppOutputDirectory() {
return ios_document_directory;
}
AGSPlatformDriver *AGSPlatformDriver::GetDriver() {
if (instance == NULL)
instance = new AGSIOS();
return instance;
}
} // namespace AGS3
#endif

View File

@ -1,155 +0,0 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
*/
#include "ags/shared/core/platform.h"
#if AGS_PLATFORM_OS_MACOS
// ********* MacOS PLACEHOLDER DRIVER *********
//#include "ags/shared/util/wgt2allg.h"
//#include "ags/shared/gfx/ali3d.h"
//#include "ags/shared/ac/runtime_defines.h"
//#include "ags/shared/main/config.h"
//#include "ags/shared/plugin/agsplugin.h"
////include <libcda.h>
////include <pwd.h>
////include <sys/stat.h>
#include "ags/shared/platform/base/agsplatformdriver.h"
#include "ags/shared/util/directory.h"
#include "ags/shared/ac/common.h"
#include "ags/shared/main/main.h"
namespace AGS3 {
void AGSMacInitPaths(char gamename[256], char appdata[PATH_MAX]);
void AGSMacGetBundleDir(char gamepath[PATH_MAX]);
//bool PlayMovie(char const *name, int skipType);
static char libraryApplicationSupport[PATH_MAX];
static char commonDataPath[PATH_MAX];
struct AGSMac : AGSPlatformDriver {
AGSMac();
virtual int CDPlayerCommand(int cmdd, int datt) override;
virtual void DisplayAlert(const char *, ...) override;
virtual unsigned long GetDiskFreeSpaceMB() override;
virtual const char *GetNoMouseErrorString() override;
virtual eScriptSystemOSID GetSystemOSID() override;
virtual int InitializeCDPlayer() override;
virtual void PostAllegroExit() override;
virtual void SetGameWindowIcon() override;
virtual void ShutdownCDPlayer() override;
virtual const char *GetUserSavedgamesDirectory() override;
virtual const char *GetAllUsersDataDirectory() override;
virtual const char *GetUserConfigDirectory() override;
virtual const char *GetAppOutputDirectory() override;
virtual const char *GetIllegalFileChars() override;
};
AGSMac::AGSMac() {
AGSMacInitPaths(psp_game_file_name, libraryApplicationSupport);
snprintf(commonDataPath, PATH_MAX, "%s/uk.co.adventuregamestudio", libraryApplicationSupport);
AGS::Shared::Directory::CreateDirectory(commonDataPath);
strcpy(psp_translation, "default");
}
int AGSMac::CDPlayerCommand(int cmdd, int datt) {
return 0;//cd_player_control(cmdd, datt);
}
void AGSMac::DisplayAlert(const char *text, ...) {
char displbuf[2000];
va_list ap;
va_start(ap, text);
vsprintf(displbuf, text, ap);
va_end(ap);
if (_logToStdErr)
fprintf(stderr, "%s\n", displbuf);
else
fprintf(stdout, "%s\n", displbuf);
}
unsigned long AGSMac::GetDiskFreeSpaceMB() {
// placeholder
return 100;
}
const char *AGSMac::GetNoMouseErrorString() {
return "This game requires a _GP(mouse). You need to configure and setup your mouse to play this game.\n";
}
eScriptSystemOSID AGSMac::GetSystemOSID() {
// override performed if `override.os` is set in config.
return eOS_Mac;
}
int AGSMac::InitializeCDPlayer() {
//return cd_player_init();
return 0;
}
void AGSMac::PostAllegroExit() {
// do nothing
}
void AGSMac::SetGameWindowIcon() {
// do nothing
}
void AGSMac::ShutdownCDPlayer() {
//cd_exit();
}
const char *AGSMac::GetAllUsersDataDirectory() {
return commonDataPath;
}
const char *AGSMac::GetUserSavedgamesDirectory() {
return libraryApplicationSupport;
}
const char *AGSMac::GetUserConfigDirectory() {
return libraryApplicationSupport;
}
const char *AGSMac::GetAppOutputDirectory() {
return commonDataPath;
}
const char *AGSMac::GetIllegalFileChars() {
return "\\/:?\"<>|*"; // keep same as Windows so we can sync.
}
AGSPlatformDriver *AGSPlatformDriver::GetDriver() {
if (instance == NULL)
instance = new AGSMac();
return instance;
}
} // namespace AGS3
#endif

View File

@ -1,30 +0,0 @@
#import <Cocoa/Cocoa.h>
//include <stdio.h>
void AGSMacInitPaths(char gamename[256], char appdata[PATH_MAX])
{
strcpy(gamename, "game.ags");
@autoreleasepool {
NSBundle *bundle = [NSBundle mainBundle];
NSString *resourcedir = [bundle resourcePath];
[[NSFileManager defaultManager] changeCurrentDirectoryPath:resourcedir];
NSURL *path = [[NSFileManager defaultManager] URLForDirectory:NSApplicationSupportDirectory inDomain:NSUserDomainMask appropriateForURL:nil create:YES error:NULL];
snprintf(appdata, PATH_MAX, "%s", [[path path] UTF8String]);
}
}
// e.g. "/Users/<username>/Library/Application Support/Steam/steamapps/common/<gamename>"
void AGSMacGetBundleDir(char gamepath[PATH_MAX])
{
@autoreleasepool {
NSBundle *bundle = [NSBundle mainBundle];
NSString *bundleDir = [bundle bundlePath];
NSString *parentDir = [bundleDir stringByDeletingLastPathComponent];
strcpy(gamepath, [parentDir UTF8String]);
}
}

View File

@ -1,54 +0,0 @@
//=============================================================================
//
// Adventure Game Studio (AGS)
//
// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others
// The full list of copyright holders can be found in the Copyright.txt
// file, which is part of this source code distribution.
//
// The AGS source code is provided under the Artistic License 2.0.
// A copy of this license can be found in the file License.txt and at
// http://www.opensource.org/licenses/artistic-license-2.0.php
//
//=============================================================================
//
// Implementations for missing libc functions
//
//=============================================================================
#include "ags/shared/core/platform.h"
#if ! AGS_PLATFORM_OS_WINDOWS
//include <string.h>
//include <stdio.h>
//include <stdlib.h>
//include <wchar.h>
//include <ctype.h>
size_t mbstowcs(wchar_t *wcstr, const char *mbstr, size_t max)
{
int count = 0;
while ((count < max) && (*mbstr != 0))
{
*wcstr++ = *mbstr++;
count++;
}
return count;
}
size_t wcstombs(char* mbstr, const wchar_t *wcstr, size_t max)
{
int count = 0;
while ((count < max) && (*wcstr != 0))
{
*mbstr++ = *wcstr++;
count++;
}
return count;
}
#endif // ! AGS_PLATFORM_OS_WINDOWS

View File

@ -1,311 +0,0 @@
//=============================================================================
//
// Adventure Game Studio (AGS)
//
// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others
// The full list of copyright holders can be found in the Copyright.txt
// file, which is part of this source code distribution.
//
// The AGS source code is provided under the Artistic License 2.0.
// A copy of this license can be found in the file License.txt and at
// http://www.opensource.org/licenses/artistic-license-2.0.php
//
//=============================================================================
//
// Functions for reading version information from PE (Windows EXE) files
//
//=============================================================================
#if defined(ANDROID) || defined(PSP)
#include "ags/shared/pe.h"
//include <string.h>
//include <stdlib.h>
#include "ags/shared/util/stdio_compat.h"
// Simplified structs for PE files
typedef struct {
char padding[60];
unsigned int e_lfanew;
} IMAGE_DOS_HEADER;
typedef struct {
char padding[2];
unsigned short NumberOfSections;
char padding1[16];
} IMAGE_FILE_HEADER;
typedef struct {
unsigned int Signature;
IMAGE_FILE_HEADER FileHeader;
char padding[224];
} IMAGE_NT_HEADERS;
typedef struct {
char Name[8];
char padding[4];
unsigned int VirtualAddress;
char padding1[4];
unsigned int PointerToRawData;
char padding2[16];
} IMAGE_SECTION_HEADER;
// These structs are original
typedef struct {
unsigned int Characteristics;
unsigned int TimeDateStamp;
unsigned short MajorVersion;
unsigned short MinorVersion;
unsigned short NumberOfNamedEntries;
unsigned short NumberOfIdEntries;
} IMAGE_RESOURCE_DIRECTORY;
typedef struct {
union {
struct {
unsigned int NameOffset:31;
unsigned int NameIsString:1;
};
unsigned int Name;
unsigned short Id;
};
union {
unsigned int OffsetToData;
struct {
unsigned int OffsetToDirectory:31;
unsigned int DataIsDirectory:1;
};
};
} IMAGE_RESOURCE_DIRECTORY_ENTRY;
typedef struct {
unsigned int OffsetToData;
unsigned int Size;
unsigned int CodePage;
unsigned int Reserved;
} IMAGE_RESOURCE_DATA_ENTRY;
// Version information
typedef struct {
unsigned int dwSignature;
unsigned int dwStrucVersion;
unsigned int dwFileVersionMS;
unsigned int dwFileVersionLS;
unsigned int dwProductVersionMS;
unsigned int dwProductVersionLS;
unsigned int dwFileFlagsMask;
unsigned int dwFileFlags;
unsigned int dwFileOS;
unsigned int dwFileType;
unsigned int dwFileSubtype;
unsigned int dwFileDateMS;
unsigned int dwFileDateLS;
} VS_FIXEDFILEINFO;
typedef struct {
unsigned short wLength;
unsigned short wValueLength;
unsigned short wType;
} STRINGFILEINFO_HEADER;
IMAGE_DOS_HEADER dos_header;
IMAGE_NT_HEADERS nt_headers;
IMAGE_SECTION_HEADER section_header;
IMAGE_RESOURCE_DIRECTORY resource_directory;
IMAGE_RESOURCE_DIRECTORY_ENTRY resource_directory_entry;
IMAGE_RESOURCE_DATA_ENTRY resource_data_entry;
unsigned int resource_virtual_address;
unsigned int resource_start;
void fillBufferFromWidechar(unsigned short* inputBuffer, char* outputText)
{
unsigned short* input = inputBuffer;
char* output = outputText;
while (*input)
*output++ = *input++;
*output = '\0';
}
int getVersionString(char* version_data, unsigned int size, char* buffer, char* name)
{
char* current = version_data;
char* last = version_data + size;
char temp[200];
// Skip header
current += 0x28;
// Skip VS_FIXEDFILEINFO
current += sizeof(VS_FIXEDFILEINFO);
// Now comes either "StringFileInfo" or "VarFileInfo"
STRINGFILEINFO_HEADER* stringfileinfo_header = (STRINGFILEINFO_HEADER*)current;
current += sizeof(STRINGFILEINFO_HEADER);
fillBufferFromWidechar((unsigned short*)current, temp);
if (strcmp(temp, "VarFileInfo") == 0)
{
current += (stringfileinfo_header->wLength - sizeof(STRINGFILEINFO_HEADER));
// Skip "StringFileInfo" header too
stringfileinfo_header = (STRINGFILEINFO_HEADER*)current;
current += 0x3C;
}
else
current += (0x3C - sizeof(STRINGFILEINFO_HEADER));
while (current < last)
{
STRINGFILEINFO_HEADER* header = (STRINGFILEINFO_HEADER*)current;
current += sizeof(STRINGFILEINFO_HEADER);
// Read name
fillBufferFromWidechar((unsigned short*)current, temp);
if (strcmp(temp, name) == 0)
{
current += (2 + 2 * strlen(temp));
// Next value is 32 bit aligned
current = (char*)((unsigned long)(current + 3) & (~3));
// Read value
fillBufferFromWidechar((unsigned short*)current, buffer);
return 1;
}
else
current += (header->wLength - sizeof(STRINGFILEINFO_HEADER));
// Next value is 32 bit aligned
current = (char*)((unsigned long)(current + 3) & (~3));
}
return 0;
}
int seekToResource(FILE* pe, int id)
{
int i;
// Read in resource directory
fread(&resource_directory, sizeof(IMAGE_RESOURCE_DIRECTORY), 1, pe);
// Loop through root node entries till we find the entry with the given id
for (i = 0; i < resource_directory.NumberOfIdEntries + resource_directory.NumberOfNamedEntries; i++)
{
// Read in resource node
fread(&resource_directory_entry, sizeof(IMAGE_RESOURCE_DIRECTORY_ENTRY), 1, pe);
if ((!resource_directory_entry.NameIsString) && (resource_directory_entry.Id == id))
{
// Seek to end of subdirectory
ags_fseek(pe, resource_start + resource_directory_entry.OffsetToDirectory, SEEK_SET);
return 1;
}
}
return 0;
}
int getVersionInformation(char* filename, version_info_t* version_info)
{
FILE* pe = fopen(filename, "rb");
if (!pe)
return 0;
// Read in the DOS header, get the offset to the PE header and seek
fread(&dos_header, sizeof(IMAGE_DOS_HEADER), 1, pe);
ags_fseek(pe, dos_header.e_lfanew, SEEK_SET);
// Read in the PE header
fread(&nt_headers, sizeof(IMAGE_NT_HEADERS), 1, pe);
// Loop through sections till we find the resource section
int i;
for (i = 0; i < nt_headers.FileHeader.NumberOfSections; i++)
{
fread(&section_header, sizeof(IMAGE_SECTION_HEADER), 1, pe);
if (strcmp(".rsrc", (char*)section_header.Name) == 0)
break;
}
if (i == nt_headers.FileHeader.NumberOfSections)
goto error_exit;
// Save virtual address of the resource section
resource_virtual_address = section_header.VirtualAddress;
// Seek to the resource section
ags_fseek(pe, section_header.PointerToRawData, SEEK_SET);
// Save file offset to the resource section
resource_start = section_header.PointerToRawData;
// Search for the version resource in the resource tree
if (!seekToResource(pe, 16))
goto error_exit;
// Enter the first subdirectory in the version resource
if (!seekToResource(pe, 1))
goto error_exit;
// Hopefully found the resource
fread(&resource_directory, sizeof(IMAGE_RESOURCE_DATA_ENTRY), 1, pe);
// Read in resource node
fread(&resource_directory_entry, sizeof(IMAGE_RESOURCE_DIRECTORY_ENTRY), 1, pe);
// Seek to the resource data
ags_fseek(pe, resource_start + resource_directory_entry.OffsetToData, SEEK_SET);
// Read in version info
fread(&resource_data_entry, sizeof(IMAGE_RESOURCE_DATA_ENTRY), 1, pe);
// Finally we got a virtual address of the resource, now seek to it
ags_fseek(pe, resource_start + resource_data_entry.OffsetToData - resource_virtual_address, SEEK_SET);
// Read version resource
char* version_data = (char*)malloc(resource_data_entry.Size);
fread(version_data, resource_data_entry.Size, 1, pe);
memset(version_info, 0, sizeof(version_info_t));
getVersionString(version_data, resource_data_entry.Size, version_info->version, "FileVersion");
getVersionString(version_data, resource_data_entry.Size, version_info->description, "FileDescription");
getVersionString(version_data, resource_data_entry.Size, version_info->internal_name, "InternalName");
free(version_data);
fclose(pe);
return 1;
error_exit:
fclose(pe);
return 0;
}
#endif

View File

@ -1,46 +0,0 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
*/
#ifndef AGS_ENGINE_PLATFORM_UTIL_PE_H
#define AGS_ENGINE_PLATFORM_UTIL_PE_H
namespace AGS3 {
#ifdef __cplusplus
extern "C" {
#endif
typedef struct {
char version[15];
char description[100];
char internal_name[100];
} version_info_t;
int getVersionInformation(char *filename, version_info_t *version_info);
#ifdef __cplusplus
}
#endif
} // namespace AGS3
#endif

View File

@ -1,983 +0,0 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
*/
#include "ags/shared/core/platform.h"
#if AGS_PLATFORM_OS_WINDOWS
// ********* WINDOWS *********
//include <string.h>
#include "ags/lib/allegro.h"
//include <allegro/platform/aintwin.h>
#include "ags/shared/ac/common.h"
#include "ags/shared/ac/draw.h"
#include "ags/shared/ac/gamesetup.h"
#include "ags/shared/ac/gamesetupstruct.h"
#include "ags/shared/ac/global_display.h"
#include "ags/shared/ac/runtime_defines.h"
#include "ags/shared/ac/string.h"
#include "ags/shared/debugging/out.h"
#include "ags/shared/gfx/graphicsdriver.h"
#include "ags/shared/gfx/bitmap.h"
#include "ags/shared/main/engine.h"
#include "ags/shared/platform/base/agsplatformdriver.h"
#include "ags/shared/platform/windows/setup/winsetup.h"
#include "ags/shared/plugin/agsplugin.h"
#include "ags/shared/util/file.h"
#include "ags/shared/util/stream.h"
#include "ags/shared/util/string_compat.h"
#include "ags/shared/media/audio/audio_system.h"
namespace AGS3 {
using namespace AGS::Shared;
using namespace AGS::Engine;
extern GameSetup usetup;
extern color palette[256];
//include <shlobj.h>
//include <time.h>
//include <shlwapi.h>
//include <windows.h>
//include <rpcsal.h>
//include <gameux.h>
//include <libcda.h>
#ifndef CSIDL_LOCAL_APPDATA
#define CSIDL_LOCAL_APPDATA 0x001C
#define CSIDL_COMMON_APPDATA 0x0023
#endif
typedef struct BMP_EXTRA_INFO {
LPDIRECTDRAWSURFACE2 surf;
struct BMP_EXTRA_INFO *next;
struct BMP_EXTRA_INFO *prev;
int flags;
int lock_nesting;
} BMP_EXTRA_INFO;
// from Allegro DDraw driver
extern "C" extern LPDIRECTDRAW2 directdraw;
extern "C" extern LPDIRECTSOUND directsound;
extern "C" extern LPDIRECTINPUTDEVICE mouse_dinput_device;
extern "C" extern LPDIRECTINPUTDEVICE key_dinput_device;
char win32SavedGamesDirectory[MAX_PATH] = "\0";
char win32AppDataDirectory[MAX_PATH] = "\0";
String win32OutputDirectory;
const unsigned int win32TimerPeriod = 1;
extern SetupReturnValue acwsetup(const ConfigTree &cfg_in, ConfigTree &cfg_out, const String &game_data_dir, const char *, const char *);
struct AGSWin32 : AGSPlatformDriver {
AGSWin32();
~AGSWin32();
virtual void AboutToQuitGame();
virtual int CDPlayerCommand(int cmdd, int datt);
virtual void AttachToParentConsole();
virtual void DisplayAlert(const char *, ...);
virtual int GetLastSystemError();
virtual const char *GetAllUsersDataDirectory();
virtual const char *GetUserSavedgamesDirectory();
virtual const char *GetUserConfigDirectory();
virtual const char *GetUserGlobalConfigDirectory();
virtual const char *GetAppOutputDirectory();
virtual const char *GetIllegalFileChars();
virtual const char *GetGraphicsTroubleshootingText();
virtual unsigned long GetDiskFreeSpaceMB();
virtual const char *GetNoMouseErrorString();
virtual bool IsMouseControlSupported(bool windowed);
virtual const char *GetAllegroFailUserHint();
virtual eScriptSystemOSID GetSystemOSID();
virtual int InitializeCDPlayer();
virtual void PostAllegroInit(bool windowed);
virtual void PostAllegroExit();
virtual SetupReturnValue RunSetup(const ConfigTree &cfg_in, ConfigTree &cfg_out);
virtual void SetGameWindowIcon();
virtual void ShutdownCDPlayer();
virtual void WriteStdOut(const char *fmt, ...);
virtual void WriteStdErr(const char *fmt, ...);
virtual void DisplaySwitchOut();
virtual void DisplaySwitchIn();
virtual void PauseApplication();
virtual void ResumeApplication();
virtual void GetSystemDisplayModes(std::vector<Engine::DisplayMode> &dms);
virtual bool EnterFullscreenMode(const Engine::DisplayMode &dm);
virtual bool ExitFullscreenMode();
virtual void AdjustWindowStyleForFullscreen();
virtual void AdjustWindowStyleForWindowed();
virtual void RegisterGameWithGameExplorer();
virtual void UnRegisterGameWithGameExplorer();
virtual int ConvertKeycodeToScanCode(int keyCode);
virtual void ValidateWindowSize(int &x, int &y, bool borderless) const;
virtual bool LockMouseToWindow();
virtual void UnlockMouse();
private:
void add_game_to_game_explorer(IGameExplorer *pFwGameExplorer, GUID *guid, const char *guidAsText, bool allUsers);
void remove_game_from_game_explorer(IGameExplorer *pFwGameExplorer, GUID *guid, const char *guidAsText, bool allUsers);
void add_tasks_for_game(const char *guidAsText, const char *gameEXE, const char *workingFolder, bool allUsers);
void get_tasks_directory(char *directoryNameBuffer, const char *guidAsText, bool allUsers);
void update_game_explorer(bool add);
void create_shortcut(const char *pathToEXE, const char *workingFolder, const char *arguments, const char *shortcutPath);
void register_file_extension(const char *exePath);
void unregister_file_extension();
bool SetSystemDisplayMode(const DisplayMode &dm, bool fullscreen);
bool _isDebuggerPresent; // indicates if the win app is running in the context of a debugger
DisplayMode _preFullscreenMode; // saved display mode before switching system to fullscreen
bool _isAttachedToParentConsole; // indicates if the win app is attached to the parent console
};
AGSWin32::AGSWin32() :
_isDebuggerPresent(::IsDebuggerPresent() != FALSE),
_isAttachedToParentConsole(false) {
// Do nothing.
}
AGSWin32::~AGSWin32() {
if (_isAttachedToParentConsole) {
::FreeConsole();
}
}
void check_parental_controls() {
/* this doesn't work, it always just returns access depedning
on whether unrated games are allowed because of digital signature
BOOL bHasAccess = FALSE;
IGameExplorer* pFwGameExplorer = NULL;
CoInitialize(NULL);
// Create an instance of the Game Explorer Interface
HRESULT hr = CoCreateInstance( __uuidof(GameExplorer), NULL, CLSCTX_INPROC_SERVER, __uuidof(IGameExplorer), (void**)&pFwGameExplorer);
if( FAILED(hr) || pFwGameExplorer == NULL ) {
// not Vista, do nothing
}
else {
char theexename[MAX_PATH] = "e:\\code\\ags\\acwin\\release\\acwin.exe";
WCHAR wstrBinPath[MAX_PATH] = {0};
MultiByteToWideChar(CP_ACP, 0, theexename, MAX_PATH, wstrBinPath, MAX_PATH);
BSTR bstrGDFBinPath = SysAllocString(wstrBinPath);
hr = pFwGameExplorer->VerifyAccess( bstrGDFBinPath, &bHasAccess );
SysFreeString(bstrGDFBinPath);
if( FAILED(hr) || !bHasAccess ) {
char buff[300];
sprintf(buff, "Parental controls block: %X b: %d", hr, bHasAccess);
quit(buff);
}
else {
platform->DisplayAlert("Parental controls: Access granted.");
}
}
if( pFwGameExplorer ) pFwGameExplorer->Release();
CoUninitialize();
*/
}
void AGSWin32::create_shortcut(const char *pathToEXE, const char *workingFolder, const char *arguments, const char *shortcutPath) {
IShellLink *pShellLink = NULL;
HRESULT hr = CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, IID_IShellLink, (void **)&pShellLink);
if ((SUCCEEDED(hr)) && (pShellLink != NULL)) {
IPersistFile *pPersistFile = NULL;
if (FAILED(pShellLink->QueryInterface(IID_IPersistFile, (void **)&pPersistFile))) {
this->DisplayAlert("Unable to add game tasks: QueryInterface for IPersistFile failed");
pShellLink->Release();
return;
}
// Set the path to the shortcut target and add the description
if (FAILED(pShellLink->SetPath(pathToEXE))) {
this->DisplayAlert("Unable to add game tasks: SetPath failed");
} else if (FAILED(pShellLink->SetWorkingDirectory(workingFolder))) {
this->DisplayAlert("Unable to add game tasks: SetWorkingDirectory failed");
} else if ((arguments != NULL) && (FAILED(pShellLink->SetArguments(arguments)))) {
this->DisplayAlert("Unable to add game tasks: SetArguments failed");
} else {
WCHAR wstrTemp[MAX_PATH] = {0};
MultiByteToWideChar(CP_ACP, 0, shortcutPath, -1, wstrTemp, MAX_PATH);
if (FAILED(pPersistFile->Save(wstrTemp, TRUE))) {
this->DisplayAlert("Unable to add game tasks: IPersistFile::Save failed");
}
}
pPersistFile->Release();
}
if (pShellLink) pShellLink->Release();
}
void CopyStringAndRemoveInvalidFilenameChars(const char *source, char *destinationBuffer) {
int destIdx = 0;
for (int i = 0; i < (int)strlen(source); i++) {
if ((source[i] != '/') &&
(source[i] != '\\') &&
(source[i] != ':') &&
(source[i] != '*') &&
(source[i] != '?') &&
(source[i] != '"') &&
(source[i] != '<') &&
(source[i] != '>') &&
(source[i] != '|') &&
(source[i] >= 32)) {
destinationBuffer[destIdx] = source[i];
destIdx++;
}
}
destinationBuffer[destIdx] = 0;
}
void AGSWin32::get_tasks_directory(char *pathBuffer, const char *guidAsText, bool allUsers) {
if (SHGetSpecialFolderPath(NULL, pathBuffer, allUsers ? CSIDL_COMMON_APPDATA : CSIDL_LOCAL_APPDATA, FALSE) == FALSE) {
this->DisplayAlert("Unable to register game: SHGetSpecialFolderPath failed");
return;
}
if (pathBuffer[strlen(pathBuffer) - 1] != '\\') {
strcat(pathBuffer, "\\");
}
strcat(pathBuffer, "Microsoft\\Windows\\GameExplorer\\");
strcat(pathBuffer, guidAsText);
mkdir(pathBuffer);
strcat(pathBuffer, "\\");
strcat(pathBuffer, "PlayTasks");
mkdir(pathBuffer);
}
void AGSWin32::add_tasks_for_game(const char *guidAsText, const char *gameEXE, const char *workingFolder, bool allUsers) {
char pathBuffer[MAX_PATH];
get_tasks_directory(pathBuffer, guidAsText, allUsers);
strcat(pathBuffer, "\\");
strcat(pathBuffer, "0");
mkdir(pathBuffer);
// Remove any existing "Play.lnk" from a previous version
char shortcutLocation[MAX_PATH];
sprintf(shortcutLocation, "%s\\Play.lnk", pathBuffer);
::remove(shortcutLocation);
// Generate the shortcut file name (because it can appear on
// the start menu's Recent area)
char sanitisedGameName[MAX_PATH];
CopyStringAndRemoveInvalidFilenameChars(game.gamename, sanitisedGameName);
if (sanitisedGameName[0] == 0)
strcpy(sanitisedGameName, "Play");
sprintf(shortcutLocation, "%s\\%s.lnk", pathBuffer, sanitisedGameName);
create_shortcut(gameEXE, workingFolder, NULL, shortcutLocation);
pathBuffer[strlen(pathBuffer) - 1] = '1';
mkdir(pathBuffer);
sprintf(shortcutLocation, "%s\\Setup game.lnk", pathBuffer);
create_shortcut(gameEXE, workingFolder, "--setup", shortcutLocation);
}
void AGSWin32::add_game_to_game_explorer(IGameExplorer *pFwGameExplorer, GUID *guid, const char *guidAsText, bool allUsers) {
WCHAR wstrTemp[MAX_PATH] = {0};
bool hadError = false;
char theexename[MAX_PATH];
GetModuleFileName(NULL, theexename, MAX_PATH);
MultiByteToWideChar(CP_ACP, 0, theexename, MAX_PATH, wstrTemp, MAX_PATH);
BSTR bstrGDFBinPath = SysAllocString(wstrTemp);
char gameDirectory[MAX_PATH];
strcpy(gameDirectory, theexename);
strrchr(gameDirectory, '\\')[0] = 0;
MultiByteToWideChar(CP_ACP, 0, gameDirectory, MAX_PATH, wstrTemp, MAX_PATH);
BSTR bstrGameDirectory = SysAllocString(wstrTemp);
HRESULT hr = pFwGameExplorer->AddGame(bstrGDFBinPath, bstrGameDirectory, allUsers ? GIS_ALL_USERS : GIS_CURRENT_USER, guid);
if ((FAILED(hr)) || (hr == S_FALSE)) {
if (hr == 0x80070715) {
// No GDF XML -- do nothing. This means the game was compiled
// without Game Explorer support.
hadError = true;
} else {
// Game already exists or error
HRESULT updateHr = pFwGameExplorer->UpdateGame(*guid);
if (FAILED(updateHr)) {
this->DisplayAlert("Failed to add the game to the game explorer: %08X, %08X", hr, updateHr);
hadError = true;
}
}
} else {
add_tasks_for_game(guidAsText, theexename, gameDirectory, allUsers);
}
BOOL bHasAccess = FALSE;
hr = pFwGameExplorer->VerifyAccess(bstrGDFBinPath, &bHasAccess);
if ((FAILED(hr) || !bHasAccess) && (!hadError)) {
this->DisplayAlert("Windows Parental Controls will not allow you to run this game.");
}
SysFreeString(bstrGDFBinPath);
SysFreeString(bstrGameDirectory);
}
#define FA_SEARCH -1
void delete_files_in_directory(const char *directoryName, const char *fileMask) {
char srchBuffer[MAX_PATH];
sprintf(srchBuffer, "%s\\%s", directoryName, fileMask);
al_ffblk dfb;
int dun = al_findfirst(srchBuffer, &dfb, FA_SEARCH);
while (!dun) {
::remove(dfb.name);
dun = al_findnext(&dfb);
}
al_findclose(&dfb);
}
void AGSWin32::remove_game_from_game_explorer(IGameExplorer *pFwGameExplorer, GUID *guid, const char *guidAsText, bool allUsers) {
HRESULT hr = pFwGameExplorer->RemoveGame(*guid);
if (FAILED(hr)) {
this->DisplayAlert("Failed to un-register game: 0x%08X", hr);
}
}
void AGSWin32::update_game_explorer(bool add) {
IGameExplorer *pFwGameExplorer = NULL;
CoInitialize(NULL);
// Create an instance of the Game Explorer Interface
HRESULT hr = CoCreateInstance(__uuidof(GameExplorer), NULL, CLSCTX_INPROC_SERVER, __uuidof(IGameExplorer), (void **)&pFwGameExplorer);
if (FAILED(hr) || pFwGameExplorer == NULL) {
Debug::Printf(kDbgMsg_Warn, "Game Explorer not found to register game, Windows Vista required");
} else {
ags_strupr(game.guid);
WCHAR wstrTemp[MAX_PATH] = {0};
GUID guid = GUID_NULL;
MultiByteToWideChar(CP_ACP, 0, game.guid, MAX_GUID_LENGTH, wstrTemp, MAX_GUID_LENGTH);
if (IIDFromString(wstrTemp, &guid) != S_OK) {
this->DisplayAlert("Failed to register game: IIDFromString failed");
} else if (add) {
add_game_to_game_explorer(pFwGameExplorer, &guid, game.guid, true);
} else {
remove_game_from_game_explorer(pFwGameExplorer, &guid, game.guid, true);
}
}
if (pFwGameExplorer) pFwGameExplorer->Release();
CoUninitialize();
}
void AGSWin32::unregister_file_extension() {
char keyname[MAX_PATH];
sprintf(keyname, ".%s", game.saveGameFileExtension);
if (SHDeleteKey(HKEY_CLASSES_ROOT, keyname) != ERROR_SUCCESS) {
this->DisplayAlert("Unable to un-register the file extension. Make sure you are running this with admin rights.");
return;
}
sprintf(keyname, "AGS.SaveGames.%s", game.saveGameFileExtension);
SHDeleteKey(HKEY_CLASSES_ROOT, keyname);
sprintf(keyname, "Software\\Microsoft\\Windows\\CurrentVersion\\PropertySystem\\PropertyHandlers\\.%s", game.saveGameFileExtension);
SHDeleteKey(HKEY_LOCAL_MACHINE, keyname);
// Tell Explorer to refresh its file association data
SHChangeNotify(SHCNE_ASSOCCHANGED, SHCNF_IDLIST, NULL, NULL);
}
void AGSWin32::register_file_extension(const char *exePath) {
DWORD valType, valBufLen = MAX_PATH;
valType = REG_SZ;
char valBuf[MAX_PATH], keyname[MAX_PATH];
char saveGameRegistryType[MAX_PATH];
sprintf(saveGameRegistryType, "AGS.SaveGames.%s", game.saveGameFileExtension);
// write HKEY_CLASSES_ROOT\.Extension = AGS.SaveGames.Extension
strcpy(valBuf, saveGameRegistryType);
sprintf(keyname, ".%s", game.saveGameFileExtension);
if (RegSetValue(HKEY_CLASSES_ROOT, keyname, valType, valBuf, valBufLen)) {
this->DisplayAlert("Unable to register file type. Make sure you are running this with Administrator rights.");
return;
}
// create HKEY_CLASSES_ROOT\AGS.SaveGames.Extension
strcpy(keyname, saveGameRegistryType);
sprintf(valBuf, "%s Saved Game", game.gamename);
RegSetValue(HKEY_CLASSES_ROOT, keyname, REG_SZ, valBuf, strlen(valBuf));
// write HKEY_CLASSES_ROOT\AGS.SaveGames.Extension\DefaultIcon
sprintf(keyname, "%s\\DefaultIcon", saveGameRegistryType);
sprintf(valBuf, "\"%s\", 0", exePath);
RegSetValue(HKEY_CLASSES_ROOT, keyname, REG_SZ, valBuf, strlen(valBuf));
// write HKEY_CLASSES_ROOT\AGS.SaveGames.Extension\Shell\Open\Command
sprintf(keyname, "%s\\Shell\\Open\\Command", saveGameRegistryType);
sprintf(valBuf, "\"%s\" -loadSavedGame \"%%1\"", exePath);
RegSetValue(HKEY_CLASSES_ROOT, keyname, REG_SZ, valBuf, strlen(valBuf));
// ** BELOW IS VISTA-ONLY
// write HKEY_CLASSES_ROOT\AGS.SaveGames.Extension, PreviewTitle
strcpy(keyname, saveGameRegistryType);
strcpy(valBuf, "prop:System.Game.RichSaveName;System.Game.RichApplicationName");
SHSetValue(HKEY_CLASSES_ROOT, keyname, "PreviewTitle", REG_SZ, valBuf, strlen(valBuf));
// write HKEY_CLASSES_ROOT\AGS.SaveGames.Extension, PreviewDetails
strcpy(keyname, saveGameRegistryType);
strcpy(valBuf, "prop:System.Game.RichLevel;System.DateChanged;System.Game.RichComment;System.DisplayName;System.DisplayType");
SHSetValue(HKEY_CLASSES_ROOT, keyname, "PreviewDetails", REG_SZ, valBuf, strlen(valBuf));
// write HKEY_CLASSES_ROOT\.Extension\ShellEx\{BB2E617C-0920-11D1-9A0B-00C04FC2D6C1}
sprintf(keyname, ".%s\\ShellEx\\{BB2E617C-0920-11D1-9A0B-00C04FC2D6C1}", game.saveGameFileExtension);
strcpy(valBuf, "{4E5BFBF8-F59A-4E87-9805-1F9B42CC254A}");
RegSetValue(HKEY_CLASSES_ROOT, keyname, REG_SZ, valBuf, strlen(valBuf));
// write HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\PropertySystem\PropertyHandlers\.Extension
sprintf(keyname, "Software\\Microsoft\\Windows\\CurrentVersion\\PropertySystem\\PropertyHandlers\\.%s", game.saveGameFileExtension);
strcpy(valBuf, "{ECDD6472-2B9B-4B4B-AE36-F316DF3C8D60}");
RegSetValue(HKEY_LOCAL_MACHINE, keyname, REG_SZ, valBuf, strlen(valBuf));
// Tell Explorer to refresh its file association data
SHChangeNotify(SHCNE_ASSOCCHANGED, SHCNF_IDLIST, NULL, NULL);
}
void AGSWin32::RegisterGameWithGameExplorer() {
update_game_explorer(true);
if (game.saveGameFileExtension[0] != 0) {
char theexename[MAX_PATH];
GetModuleFileName(NULL, theexename, MAX_PATH);
register_file_extension(theexename);
}
}
void AGSWin32::UnRegisterGameWithGameExplorer() {
update_game_explorer(false);
if (game.saveGameFileExtension[0] != 0) {
unregister_file_extension();
}
}
void AGSWin32::PostAllegroInit(bool windowed) {
check_parental_controls();
// Set the Windows timer resolution to 1 ms so that calls to
// Sleep() don't take more time than specified
MMRESULT result = timeBeginPeriod(win32TimerPeriod);
if (result != TIMERR_NOERROR)
Debug::Printf(kDbgMsg_Error, "Failed to set the timer resolution to %d ms", win32TimerPeriod);
}
typedef UINT(CALLBACK *Dynamic_SHGetKnownFolderPathType)(GUID &rfid, DWORD dwFlags, HANDLE hToken, PWSTR *ppszPath);
GUID FOLDERID_SAVEDGAMES = {0x4C5C32FF, 0xBB9D, 0x43b0, {0xB5, 0xB4, 0x2D, 0x72, 0xE5, 0x4E, 0xAA, 0xA4}};
#define _WIN32_WINNT_VISTA 0x0600
#define VER_MINORVERSION 0x0000001
#define VER_MAJORVERSION 0x0000002
#define VER_SERVICEPACKMAJOR 0x0000020
#define VER_GREATER_EQUAL 3
// These helpers copied from VersionHelpers.h in the Windows 8.1 SDK
bool IsWindowsVersionOrGreater(WORD wMajorVersion, WORD wMinorVersion, WORD wServicePackMajor) {
OSVERSIONINFOEXW osvi = { sizeof(osvi), 0, 0, 0, 0, { 0 }, 0, 0 };
DWORDLONG const dwlConditionMask = VerSetConditionMask(
VerSetConditionMask(
VerSetConditionMask(
0, VER_MAJORVERSION, VER_GREATER_EQUAL),
VER_MINORVERSION, VER_GREATER_EQUAL),
VER_SERVICEPACKMAJOR, VER_GREATER_EQUAL);
osvi.dwMajorVersion = wMajorVersion;
osvi.dwMinorVersion = wMinorVersion;
osvi.wServicePackMajor = wServicePackMajor;
return VerifyVersionInfoW(&osvi, VER_MAJORVERSION | VER_MINORVERSION | VER_SERVICEPACKMAJOR, dwlConditionMask) != FALSE;
}
bool IsWindowsVistaOrGreater() {
return IsWindowsVersionOrGreater(HIBYTE(_WIN32_WINNT_VISTA), LOBYTE(_WIN32_WINNT_VISTA), 0);
}
void determine_app_data_folder() {
if (win32AppDataDirectory[0] != 0) {
// already discovered
return;
}
WCHAR unicodePath[MAX_PATH];
WCHAR unicodeShortPath[MAX_PATH];
SHGetSpecialFolderPathW(NULL, unicodePath, CSIDL_COMMON_APPDATA, FALSE);
if (GetShortPathNameW(unicodePath, unicodeShortPath, MAX_PATH) == 0) {
platform->DisplayAlert("Unable to get App Data dir: GetShortPathNameW failed");
return;
}
WideCharToMultiByte(CP_ACP, 0, unicodeShortPath, -1, win32AppDataDirectory, MAX_PATH, NULL, NULL);
strcat(win32AppDataDirectory, "\\Adventure Game Studio");
mkdir(win32AppDataDirectory);
}
void determine_saved_games_folder() {
if (win32SavedGamesDirectory[0] != 0) {
// already discovered
return;
}
WCHAR unicodeSaveGameDir[MAX_PATH] = L"";
WCHAR unicodeShortSaveGameDir[MAX_PATH] = L"";
if (IsWindowsVistaOrGreater()) {
HINSTANCE hShellDLL = LoadLibrary("shell32.dll");
Dynamic_SHGetKnownFolderPathType Dynamic_SHGetKnownFolderPath = (Dynamic_SHGetKnownFolderPathType)GetProcAddress(hShellDLL, "SHGetKnownFolderPath");
if (Dynamic_SHGetKnownFolderPath != NULL) {
PWSTR path = NULL;
if (SUCCEEDED(Dynamic_SHGetKnownFolderPath(FOLDERID_SAVEDGAMES, 0, NULL, &path))) {
if (GetShortPathNameW(path, unicodeShortSaveGameDir, MAX_PATH) > 0) {
WideCharToMultiByte(CP_ACP, 0, unicodeShortSaveGameDir, -1, win32SavedGamesDirectory, MAX_PATH, NULL, NULL);
}
CoTaskMemFree(path);
}
}
FreeLibrary(hShellDLL);
} else {
// Windows XP didn't have a "My Saved Games" folder, so create one under "My Documents"
SHGetSpecialFolderPathW(NULL, unicodeSaveGameDir, CSIDL_PERSONAL, FALSE);
// workaround for case where My Documents path has unicode chars (eg.
// with Russian Windows) -- so use Short File Name instead
if (GetShortPathNameW(unicodeSaveGameDir, unicodeShortSaveGameDir, MAX_PATH) > 0) {
WideCharToMultiByte(CP_ACP, 0, unicodeShortSaveGameDir, -1, win32SavedGamesDirectory, MAX_PATH, NULL, NULL);
strcat(win32SavedGamesDirectory, "\\My Saved Games");
mkdir(win32SavedGamesDirectory);
}
}
// Fallback to a subdirectory of the app data directory
if (win32SavedGamesDirectory[0] == '\0') {
determine_app_data_folder();
strcpy(win32SavedGamesDirectory, win32AppDataDirectory);
strcat(win32SavedGamesDirectory, "\\Saved Games");
mkdir(win32SavedGamesDirectory);
}
}
void DetermineAppOutputDirectory() {
if (!win32OutputDirectory.IsEmpty()) {
return;
}
determine_saved_games_folder();
bool log_to_saves_dir = false;
if (win32SavedGamesDirectory[0]) {
win32OutputDirectory = win32SavedGamesDirectory;
win32OutputDirectory.Append("\\.ags");
log_to_saves_dir = mkdir(win32OutputDirectory) == 0 || errnum == EEXIST;
}
if (!log_to_saves_dir) {
char theexename[MAX_PATH + 1] = {0};
GetModuleFileName(NULL, theexename, MAX_PATH);
PathRemoveFileSpec(theexename);
win32OutputDirectory = theexename;
}
}
const char *AGSWin32::GetAllUsersDataDirectory() {
determine_app_data_folder();
return &win32AppDataDirectory[0];
}
const char *AGSWin32::GetUserSavedgamesDirectory() {
determine_saved_games_folder();
return win32SavedGamesDirectory;
}
const char *AGSWin32::GetUserConfigDirectory() {
determine_saved_games_folder();
return win32SavedGamesDirectory;
}
const char *AGSWin32::GetUserGlobalConfigDirectory() {
DetermineAppOutputDirectory();
return win32OutputDirectory;
}
const char *AGSWin32::GetAppOutputDirectory() {
DetermineAppOutputDirectory();
return win32OutputDirectory;
}
const char *AGSWin32::GetIllegalFileChars() {
return "\\/:?\"<>|*";
}
const char *AGSWin32::GetGraphicsTroubleshootingText() {
return "\n\nPossible causes:\n"
"* your graphics card drivers do not support requested resolution. "
"Run the game setup program and try another resolution.\n"
"* the graphics driver you have selected does not work. Try switching to another graphics driver.\n"
"* the graphics filter you have selected does not work. Try another filter.\n"
"* your graphics card drivers are out of date. "
"Try downloading updated graphics card drivers from your manufacturer's website.\n"
"* there is a problem with your graphics card driver configuration. "
"Run DXDiag using the Run command (Start->Run, type \"dxdiag.exe\") and correct any problems reported there.";
}
void AGSWin32::DisplaySwitchOut() {
// If we have explicitly set up fullscreen mode then minimize the window
if (_preFullscreenMode.IsValid())
ShowWindow(win_get_window(), SW_MINIMIZE);
}
void AGSWin32::DisplaySwitchIn() {
// If we have explicitly set up fullscreen mode then restore the window
if (_preFullscreenMode.IsValid())
ShowWindow(win_get_window(), SW_RESTORE);
}
void AGSWin32::PauseApplication() {
}
void AGSWin32::ResumeApplication() {
}
void AGSWin32::GetSystemDisplayModes(std::vector<DisplayMode> &dms) {
dms.clear();
GFX_MODE_LIST *gmlist = get_gfx_mode_list(GFX_DIRECTX);
for (int i = 0; i < gmlist->num_modes; ++i) {
const GFX_MODE &m = gmlist->mode[i];
dms.push_back(DisplayMode(GraphicResolution(m.width, m.height, m.bpp)));
}
destroy_gfx_mode_list(gmlist);
}
bool AGSWin32::SetSystemDisplayMode(const DisplayMode &dm, bool fullscreen) {
DEVMODE devmode;
memset(&devmode, 0, sizeof(devmode));
devmode.dmSize = sizeof(devmode);
devmode.dmPelsWidth = dm.Width;
devmode.dmPelsHeight = dm.Height;
devmode.dmBitsPerPel = dm.ColorDepth;
devmode.dmFields = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT;
return ChangeDisplaySettings(&devmode, fullscreen ? CDS_FULLSCREEN : 0) == DISP_CHANGE_SUCCESSFUL;
}
bool AGSWin32::EnterFullscreenMode(const DisplayMode &dm) {
// Remember current mode
get_desktop_resolution(&_preFullscreenMode.Width, &_preFullscreenMode.Height);
_preFullscreenMode.ColorDepth = desktop_color_depth();
// Set requested desktop mode
return SetSystemDisplayMode(dm, true);
}
bool AGSWin32::ExitFullscreenMode() {
if (!_preFullscreenMode.IsValid())
return false;
DisplayMode dm = _preFullscreenMode;
_preFullscreenMode = DisplayMode();
return SetSystemDisplayMode(dm, false);
}
void AGSWin32::AdjustWindowStyleForFullscreen() {
// Remove the border in full-screen mode
Size sz;
get_desktop_resolution(&sz.Width, &sz.Height);
HWND allegro_wnd = win_get_window();
LONG winstyle = GetWindowLong(allegro_wnd, GWL_STYLE);
SetWindowLong(allegro_wnd, GWL_STYLE, (winstyle & ~WS_OVERLAPPEDWINDOW) | WS_POPUP);
SetWindowPos(allegro_wnd, HWND_TOP, 0, 0, sz.Width, sz.Height, 0);
}
void AGSWin32::AdjustWindowStyleForWindowed() {
// Make a regular window with a border
HWND allegro_wnd = win_get_window();
LONG winstyle = GetWindowLong(allegro_wnd, GWL_STYLE);
SetWindowLong(allegro_wnd, GWL_STYLE, (winstyle & ~WS_POPUP) | (WS_SYSMENU | WS_CAPTION | WS_MINIMIZEBOX));
// Make window go on top, but at the same time remove WS_EX_TOPMOST style (applied by Direct3D fullscreen mode)
SetWindowPos(allegro_wnd, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_FRAMECHANGED);
}
int AGSWin32::CDPlayerCommand(int cmdd, int datt) {
#if defined (AGS_HAS_CD_AUDIO)
return cd_player_control(cmdd, datt);
#else
return -1;
#endif
}
void AGSWin32::AttachToParentConsole() {
if (_isAttachedToParentConsole)
return;
_isAttachedToParentConsole = ::AttachConsole(ATTACH_PARENT_PROCESS) != FALSE;
if (_isAttachedToParentConsole) {
// Require that both STDOUT and STDERR are valid handles from the parent process.
if (::GetStdHandle(STD_OUTPUT_HANDLE) != INVALID_HANDLE_VALUE &&
::GetStdHandle(STD_ERROR_HANDLE) != INVALID_HANDLE_VALUE) {
// Re-open STDOUT and STDERR to the parent's.
FILE *fp = NULL;
freopen_s(&fp, "CONOUT$", "w", stdout);
setvbuf(stdout, NULL, _IONBF, 0);
freopen_s(&fp, "CONOUT$", "w", stderr);
setvbuf(stderr, NULL, _IONBF, 0);
} else {
::FreeConsole();
_isAttachedToParentConsole = false;
}
}
}
void AGSWin32::DisplayAlert(const char *text, ...) {
char displbuf[2500];
va_list ap;
va_start(ap, text);
vsprintf(displbuf, text, ap);
va_end(ap);
if (_guiMode)
MessageBox(win_get_window(), displbuf, "Adventure Game Studio", MB_OK | MB_ICONEXCLAMATION);
// Always write to either stderr or stdout, even if message boxes are enabled.
if (_logToStdErr)
AGSWin32::WriteStdErr("%s", displbuf);
else
AGSWin32::WriteStdOut("%s", displbuf);
}
int AGSWin32::GetLastSystemError() {
return ::GetLastError();
}
unsigned long AGSWin32::GetDiskFreeSpaceMB() {
DWORD returnMb = 0;
BOOL fResult;
_G(our_eip) = -1891;
// On Win9x, the last 3 params cannot be null, so need to supply values for all
__int64 i64FreeBytesToCaller, i64Unused1, i64Unused2;
// Win95 OSR2 or higher - use GetDiskFreeSpaceEx, since the
// normal GetDiskFreeSpace returns erroneous values if the
// free space is > 2 GB
fResult = GetDiskFreeSpaceEx(NULL,
(PULARGE_INTEGER)&i64FreeBytesToCaller,
(PULARGE_INTEGER)&i64Unused1,
(PULARGE_INTEGER)&i64Unused2);
_G(our_eip) = -1893;
// convert down to MB so we can fit it in a 32-bit long
i64FreeBytesToCaller /= 1000000;
returnMb = i64FreeBytesToCaller;
return returnMb;
}
const char *AGSWin32::GetNoMouseErrorString() {
return "No mouse was detected on your system, or your mouse is not configured to work with DirectInput. You must have a mouse to play this game.";
}
bool AGSWin32::IsMouseControlSupported(bool windowed) {
return true; // supported for both fullscreen and windowed modes
}
const char *AGSWin32::GetAllegroFailUserHint() {
return "Make sure you have DirectX 5 or above installed.";
}
eScriptSystemOSID AGSWin32::GetSystemOSID() {
return eOS_Win;
}
int AGSWin32::InitializeCDPlayer() {
#if defined (AGS_HAS_CD_AUDIO)
return cd_player_init();
#else
return -1;
#endif
}
void AGSWin32::AboutToQuitGame() {
}
void AGSWin32::PostAllegroExit() {
// Release the timer setting
timeEndPeriod(win32TimerPeriod);
}
SetupReturnValue AGSWin32::RunSetup(const ConfigTree &cfg_in, ConfigTree &cfg_out) {
String version_str = String::FromFormat("Adventure Game Studio v%s setup", get_engine_version());
return AGS::Engine::WinSetup(cfg_in, cfg_out, usetup.data_files_dir, version_str);
}
void AGSWin32::SetGameWindowIcon() {
SetWinIcon();
}
void AGSWin32::WriteStdOut(const char *fmt, ...) {
va_list ap;
va_start(ap, fmt);
if (_isDebuggerPresent) {
// Add "AGS:" prefix when outputting to debugger, to make it clear that this
// is a text from the program log
char buf[STD_BUFFER_SIZE] = "AGS: ";
vsnprintf(buf + 5, STD_BUFFER_SIZE - 5, fmt, ap);
OutputDebugString(buf);
OutputDebugString("\n");
} else {
vprintf(fmt, ap);
printf("\n");
}
va_end(ap);
}
void AGSWin32::WriteStdErr(const char *fmt, ...) {
va_list ap;
va_start(ap, fmt);
if (_isDebuggerPresent) {
// Add "AGS:" prefix when outputting to debugger, to make it clear that this
// is a text from the program log
char buf[STD_BUFFER_SIZE] = "AGS ERR: ";
vsnprintf(buf + 9, STD_BUFFER_SIZE - 9, fmt, ap);
OutputDebugString(buf);
OutputDebugString("\n");
} else {
vfprintf(stderr, fmt, ap);
fprintf(stderr, "\n");
}
va_end(ap);
}
void AGSWin32::ShutdownCDPlayer() {
cd_exit();
}
extern "C" const unsigned char hw_to_mycode[256];
int AGSWin32::ConvertKeycodeToScanCode(int keycode) {
// ** HIDEOUS HACK TO WORK AROUND ALLEGRO BUG
// the key[] array is hardcoded to qwerty keyboards, so we
// have to re-map it to make it work on other keyboard layouts
keycode += ('a' - 'A');
int vkey = VkKeyScan(keycode);
int scancode = MapVirtualKey(vkey, MAPVK_VK_TO_VSC);
if ((scancode >= 0) && (scancode < 256))
keycode = hw_to_mycode[scancode];
return keycode;
}
void AGSWin32::ValidateWindowSize(int &x, int &y, bool borderless) const {
RECT wa_rc, nc_rc;
// This is the size of the available workspace on user's desktop
SystemParametersInfo(SPI_GETWORKAREA, 0, &wa_rc, 0);
// This is the maximal size that OS can reliably resize the window to (including any frame)
const Size max_win(GetSystemMetrics(SM_CXMAXTRACK), GetSystemMetrics(SM_CYMAXTRACK));
// This is the size of window's non-client area (frame, caption, etc)
HWND allegro_wnd = win_get_window();
LONG winstyle = borderless ? WS_POPUP : WS_SYSMENU | WS_CAPTION | WS_MINIMIZEBOX;
LONG winstyle_al = GetWindowLong(allegro_wnd, GWL_STYLE);
SetRectEmpty(&nc_rc);
AdjustWindowRect(&nc_rc, winstyle, FALSE);
// Limit the window's full size to the system's window size limit,
// and limit window's client size to the work space (visible area)
x = Math::Min(x, (int)(max_win.Width - (nc_rc.right - nc_rc.left)));
y = Math::Min(y, (int)(max_win.Height - (nc_rc.bottom - nc_rc.top)));
x = Math::Clamp(x, 1, (int)(wa_rc.right - wa_rc.left));
y = Math::Clamp(y, 1, (int)(wa_rc.bottom - wa_rc.top));
}
bool AGSWin32::LockMouseToWindow() {
RECT rc;
HWND allegro_wnd = win_get_window();
GetClientRect(allegro_wnd, &rc);
ClientToScreen(allegro_wnd, (POINT *)&rc);
ClientToScreen(allegro_wnd, (POINT *)&rc.right);
--rc.right;
--rc.bottom;
return ::ClipCursor(&rc) != 0;
}
void AGSWin32::UnlockMouse() {
::ClipCursor(NULL);
}
AGSPlatformDriver *AGSPlatformDriver::GetDriver() {
if (instance == NULL)
instance = new AGSWin32();
return instance;
}
// *********** WINDOWS-SPECIFIC PLUGIN API FUNCTIONS *************
HWND IAGSEngine::GetWindowHandle() {
return win_get_window();
}
LPDIRECTDRAW2 IAGSEngine::GetDirectDraw2() {
if (directdraw == NULL)
quit("!This plugin requires DirectDraw based graphics driver (software driver).");
return directdraw;
}
LPDIRECTDRAWSURFACE2 IAGSEngine::GetBitmapSurface(BITMAP *bmp) {
if (directdraw == NULL)
quit("!This plugin requires DirectDraw based graphics driver (software driver).");
BMP_EXTRA_INFO *bei = (BMP_EXTRA_INFO *)bmp->extra;
if (bmp == _G(gfxDriver)->GetMemoryBackBuffer()->GetAllegroBitmap())
invalidate_screen();
return bei->surf;
}
LPDIRECTSOUND IAGSEngine::GetDirectSound() {
return directsound;
}
LPDIRECTINPUTDEVICE IAGSEngine::GetDirectInputKeyboard() {
return key_dinput_device;
}
LPDIRECTINPUTDEVICE IAGSEngine::GetDirectInputMouse() {
return mouse_dinput_device;
}
} // namespace AGS3
#endif

View File

@ -1,100 +0,0 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
*/
#include "ags/shared/core/platform.h"
#if AGS_PLATFORM_OS_WINDOWS
#include "ags/shared/platform/windows/debug/namedpipesagsdebugger.h"
//include <stdio.h> // sprintf
namespace AGS3 {
void NamedPipesAGSDebugger::SendAcknowledgement() {
DWORD bytesWritten;
WriteFile(_hPipeSending, "MSGACK", 6, &bytesWritten, NULL);
}
NamedPipesAGSDebugger::NamedPipesAGSDebugger(const char *instanceToken) {
_hPipeSending = NULL;
_hPipeReading = NULL;
_instanceToken = instanceToken;
}
bool NamedPipesAGSDebugger::Initialize() {
// can't use a single duplex pipe as it was deadlocking
char pipeNameBuffer[MAX_PATH];
sprintf(pipeNameBuffer, "\\\\.\\pipe\\AGSEditorDebuggerGameToEd%s", _instanceToken);
_hPipeSending = CreateFile(pipeNameBuffer, GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);
sprintf(pipeNameBuffer, "\\\\.\\pipe\\AGSEditorDebuggerEdToGame%s", _instanceToken);
_hPipeReading = CreateFile(pipeNameBuffer, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL);
if ((_hPipeReading == INVALID_HANDLE_VALUE) ||
(_hPipeSending == INVALID_HANDLE_VALUE))
return false;
return true;
}
void NamedPipesAGSDebugger::Shutdown() {
if (_hPipeReading != NULL) {
CloseHandle(_hPipeReading);
CloseHandle(_hPipeSending);
_hPipeReading = NULL;
}
}
bool NamedPipesAGSDebugger::SendMessageToEditor(const char *message) {
DWORD bytesWritten;
return (WriteFile(_hPipeSending, message, strlen(message), &bytesWritten, NULL) != 0);
}
bool NamedPipesAGSDebugger::IsMessageAvailable() {
DWORD bytesAvailable = 0;
PeekNamedPipe(_hPipeReading, NULL, 0, NULL, &bytesAvailable, NULL);
return (bytesAvailable > 0);
}
char *NamedPipesAGSDebugger::GetNextMessage() {
DWORD bytesAvailable = 0;
PeekNamedPipe(_hPipeReading, NULL, 0, NULL, &bytesAvailable, NULL);
if (bytesAvailable > 0) {
char *buffer = (char *)malloc(bytesAvailable + 1);
DWORD bytesRead = 0;
ReadFile(_hPipeReading, buffer, bytesAvailable, &bytesRead, NULL);
buffer[bytesRead] = 0;
SendAcknowledgement();
return buffer;
} else {
return NULL;
}
}
} // namespace AGS3
#endif

View File

@ -1,51 +0,0 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
*/
#ifndef AGS_ENGINE_DEBUGGING_NAMEDPIPESAGSDEBUGGER_H
#define AGS_ENGINE_DEBUGGING_NAMEDPIPESAGSDEBUGGER_H
//include <windows.h>
//include <io.h>
#include "ags/shared/debugging/agseditordebugger.h"
namespace AGS3 {
struct NamedPipesAGSDebugger : IAGSEditorDebugger {
private:
HANDLE _hPipeSending;
HANDLE _hPipeReading;
const char *_instanceToken;
void SendAcknowledgement();
public:
NamedPipesAGSDebugger(const char *instanceToken);
virtual bool Initialize() override;
virtual void Shutdown() override;
virtual bool SendMessageToEditor(const char *message) override;
virtual bool IsMessageAvailable() override;
virtual char *GetNextMessage() override;
};
} // namespace AGS3
#endif

File diff suppressed because it is too large Load Diff

View File

@ -1,352 +0,0 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
*/
//=============================================================================
//
// Direct3D graphics factory
//
//=============================================================================
#ifndef AGS_ENGINE_PLATFORM_WINDOWS_ALI3DD3D_H
#define AGS_ENGINE_PLATFORM_WINDOWS_ALI3DD3D_H
#include "ags/shared/core/platform.h"
#if ! AGS_PLATFORM_OS_WINDOWS
#error This file should only be included on the Windows build
#endif
#include "ags/lib/std/memory.h"
#include "ags/lib/allegro.h"
//include <winalleg.h>
//include <d3d9.h>
#include "ags/shared/gfx/bitmap.h"
#include "ags/shared/gfx/ddb.h"
#include "ags/shared/gfx/gfxdriverfactorybase.h"
#include "ags/shared/gfx/gfxdriverbase.h"
#include "ags/shared/util/library.h"
#include "ags/shared/util/string.h"
namespace AGS3 {
namespace AGS {
namespace Engine {
namespace D3D {
using AGS::Shared::Bitmap;
using AGS::Shared::String;
class D3DGfxFilter;
struct D3DTextureTile : public TextureTile {
IDirect3DTexture9 *texture;
};
class D3DBitmap : public VideoMemDDB {
public:
// Transparency is a bit counter-intuitive
// 0=not transparent, 255=invisible, 1..254 barely visible .. mostly visible
void SetTransparency(int transparency) override {
_transparency = transparency;
}
void SetFlippedLeftRight(bool isFlipped) override {
_flipped = isFlipped;
}
void SetStretch(int width, int height, bool useResampler = true) override {
_stretchToWidth = width;
_stretchToHeight = height;
_useResampler = useResampler;
}
void SetLightLevel(int lightLevel) override {
_lightLevel = lightLevel;
}
void SetTint(int red, int green, int blue, int tintSaturation) override {
_red = red;
_green = green;
_blue = blue;
_tintSaturation = tintSaturation;
}
bool _flipped;
int _stretchToWidth, _stretchToHeight;
bool _useResampler;
int _red, _green, _blue;
int _tintSaturation;
int _lightLevel;
bool _hasAlpha;
int _transparency;
IDirect3DVertexBuffer9 *_vertex;
D3DTextureTile *_tiles;
int _numTiles;
D3DBitmap(int width, int height, int colDepth, bool opaque) {
_width = width;
_height = height;
_colDepth = colDepth;
_flipped = false;
_hasAlpha = false;
_stretchToWidth = 0;
_stretchToHeight = 0;
_useResampler = false;
_red = _green = _blue = 0;
_tintSaturation = 0;
_lightLevel = 0;
_transparency = 0;
_opaque = opaque;
_vertex = NULL;
_tiles = NULL;
_numTiles = 0;
}
int GetWidthToRender() {
return (_stretchToWidth > 0) ? _stretchToWidth : _width;
}
int GetHeightToRender() {
return (_stretchToHeight > 0) ? _stretchToHeight : _height;
}
void Dispose();
~D3DBitmap() override {
Dispose();
}
};
class D3DGfxModeList : public IGfxModeList {
public:
D3DGfxModeList(IDirect3D9 *direct3d, D3DFORMAT d3dformat)
: _direct3d(direct3d)
, _pixelFormat(d3dformat) {
_modeCount = _direct3d ? _direct3d->GetAdapterModeCount(D3DADAPTER_DEFAULT, _pixelFormat) : 0;
}
~D3DGfxModeList() override {
if (_direct3d)
_direct3d->Release();
}
int GetModeCount() const override {
return _modeCount;
}
bool GetMode(int index, DisplayMode &mode) const override;
private:
IDirect3D9 *_direct3d;
D3DFORMAT _pixelFormat;
int _modeCount;
};
struct CUSTOMVERTEX {
D3DVECTOR position; // The position.
D3DVECTOR normal;
FLOAT tu, tv; // The texture coordinates.
};
typedef SpriteDrawListEntry<D3DBitmap> D3DDrawListEntry;
// D3D renderer's sprite batch
struct D3DSpriteBatch {
// List of sprites to render
std::vector<D3DDrawListEntry> List;
// Clipping viewport
Rect Viewport;
// Transformation matrix, built from the batch description
D3DMATRIX Matrix;
};
typedef std::vector<D3DSpriteBatch> D3DSpriteBatches;
class D3DGraphicsDriver : public VideoMemoryGraphicsDriver {
public:
const char *GetDriverName() override {
return "Direct3D 9";
}
const char *GetDriverID() override {
return "D3D9";
}
void SetTintMethod(TintMethod method) override;
bool SetDisplayMode(const DisplayMode &mode, volatile int *loopTimer) override;
bool SetNativeSize(const Size &src_size) override;
bool SetRenderFrame(const Rect &dst_rect) override;
int GetDisplayDepthForNativeDepth(int native_color_depth) const override;
IGfxModeList *GetSupportedModeList(int color_depth) override;
bool IsModeSupported(const DisplayMode &mode) override;
PGfxFilter GetGraphicsFilter() const override;
// Clears the screen rectangle. The coordinates are expected in the **native game resolution**.
void ClearRectangle(int x1, int y1, int x2, int y2, RGB *colorToUse) override;
int GetCompatibleBitmapFormat(int color_depth) override;
IDriverDependantBitmap *CreateDDBFromBitmap(Bitmap *bitmap, bool hasAlpha, bool opaque) override;
void UpdateDDBFromBitmap(IDriverDependantBitmap *bitmapToUpdate, Bitmap *bitmap, bool hasAlpha) override;
void DestroyDDB(IDriverDependantBitmap *bitmap) override;
void DrawSprite(int x, int y, IDriverDependantBitmap *bitmap) override;
void SetScreenFade(int red, int green, int blue) override;
void SetScreenTint(int red, int green, int blue) override;
void RenderToBackBuffer() override;
void Render() override;
void Render(int xoff, int yoff, GlobalFlipType flip) override;
bool GetCopyOfScreenIntoBitmap(Bitmap *destination, bool at_native_res, GraphicResolution *want_fmt) override;
void EnableVsyncBeforeRender(bool enabled) override {
}
void Vsync() override;
void RenderSpritesAtScreenResolution(bool enabled, int supersampling) override {
_renderSprAtScreenRes = enabled;
};
void FadeOut(int speed, int targetColourRed, int targetColourGreen, int targetColourBlue) override;
void FadeIn(int speed, PALETTE p, int targetColourRed, int targetColourGreen, int targetColourBlue) override;
void BoxOutEffect(bool blackingOut, int speed, int delay) override;
bool SupportsGammaControl() override;
void SetGamma(int newGamma) override;
void UseSmoothScaling(bool enabled) override {
_smoothScaling = enabled;
}
bool RequiresFullRedrawEachFrame() override {
return true;
}
bool HasAcceleratedTransform() override {
return true;
}
typedef std::shared_ptr<D3DGfxFilter> PD3DFilter;
// Clears screen rect, coordinates are expected in display resolution
void ClearScreenRect(const Rect &r, RGB *colorToUse);
void UnInit();
void SetGraphicsFilter(PD3DFilter filter);
// Internal; TODO: find a way to hide these
int _initDLLCallback(const DisplayMode &mode);
int _resetDeviceIfNecessary();
D3DGraphicsDriver(IDirect3D9 *d3d);
~D3DGraphicsDriver() override;
private:
PD3DFilter _filter;
IDirect3D9 *direct3d;
D3DPRESENT_PARAMETERS d3dpp;
IDirect3DDevice9 *direct3ddevice;
D3DGAMMARAMP defaultgammaramp;
D3DGAMMARAMP currentgammaramp;
D3DCAPS9 direct3ddevicecaps;
IDirect3DVertexBuffer9 *vertexbuffer;
IDirect3DSurface9 *pNativeSurface;
IDirect3DTexture9 *pNativeTexture;
RECT viewport_rect;
UINT availableVideoMemory;
CUSTOMVERTEX defaultVertices[4];
String previousError;
IDirect3DPixelShader9 *pixelShader;
bool _smoothScaling;
bool _legacyPixelShader;
float _pixelRenderXOffset;
float _pixelRenderYOffset;
bool _renderSprAtScreenRes;
D3DSpriteBatches _spriteBatches;
// TODO: these draw list backups are needed only for the fade-in/out effects
// find out if it's possible to reimplement these effects in main drawing routine.
SpriteBatchDescs _backupBatchDescs;
D3DSpriteBatches _backupBatches;
D3DVIEWPORT9 _d3dViewport;
// Called after new mode was successfully initialized
void OnModeSet(const DisplayMode &mode) override;
void InitSpriteBatch(size_t index, const SpriteBatchDesc &desc) override;
void ResetAllBatches() override;
// Called when the direct3d device is created for the first time
int FirstTimeInit();
void initD3DDLL(const DisplayMode &mode);
void InitializeD3DState();
void SetupViewport();
HRESULT ResetD3DDevice();
// Unset parameters and release resources related to the display mode
void ReleaseDisplayMode();
void set_up_default_vertices();
void AdjustSizeToNearestSupportedByCard(int *width, int *height);
void UpdateTextureRegion(D3DTextureTile *tile, Bitmap *bitmap, D3DBitmap *target, bool hasAlpha);
void CreateVirtualScreen();
void do_fade(bool fadingOut, int speed, int targetColourRed, int targetColourGreen, int targetColourBlue);
bool IsTextureFormatOk(D3DFORMAT TextureFormat, D3DFORMAT AdapterFormat);
// Backup all draw lists in the temp storage
void BackupDrawLists();
// Restore draw lists from the temp storage
void RestoreDrawLists();
// Deletes draw list backups
void ClearDrawBackups();
void _renderAndPresent(bool clearDrawListAfterwards);
void _render(bool clearDrawListAfterwards);
void _reDrawLastFrame();
void RenderSpriteBatches();
void RenderSpriteBatch(const D3DSpriteBatch &batch);
void _renderSprite(const D3DDrawListEntry *entry, const D3DMATRIX &matGlobal);
void _renderFromTexture();
};
class D3DGraphicsFactory : public GfxDriverFactoryBase<D3DGraphicsDriver, D3DGfxFilter> {
public:
~D3DGraphicsFactory() override;
size_t GetFilterCount() const override;
const GfxFilterInfo *GetFilterInfo(size_t index) const override;
String GetDefaultFilterID() const override;
static D3DGraphicsFactory *GetFactory();
static D3DGraphicsDriver *GetD3DDriver();
private:
D3DGraphicsFactory();
D3DGraphicsDriver *EnsureDriverCreated() override;
D3DGfxFilter *CreateFilter(const String &id) override;
bool Init();
static D3DGraphicsFactory *_factory;
//
// IMPORTANT NOTE: since the Direct3d9 device is created with
// D3DCREATE_MULTITHREADED behavior flag, once it is created the d3d9.dll may
// only be unloaded after window is destroyed, as noted in the MSDN's article
// on "D3DCREATE"
// (http://msdn.microsoft.com/en-us/library/windows/desktop/bb172527.aspx).
// Otherwise window becomes either destroyed prematurely or broken (details
// are unclear), which causes errors during Allegro deinitialization.
//
// Curiously, this problem was only confirmed under WinXP so far.
//
// For the purpose of avoiding this problem, we have a static library wrapper
// that unloads library only at the very program exit (except cases of device
// creation failure).
//
// TODO: find out if there is better solution.
//
static Library _library;
IDirect3D9 *_direct3d;
};
} // namespace D3D
} // namespace Engine
} // namespace AGS
} // namespace AGS3
#endif

View File

@ -1,119 +0,0 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
*/
#include "ags/shared/core/platform.h"
#if AGS_PLATFORM_OS_WINDOWS && !AGS_PLATFORM_DEBUG
#define UNICODE
//include <stdio.h> // sprintf
#include "ags/shared/windows.h"
//include <crtdbg.h>
#include "ags/shared/main/main.h"
namespace AGS3 {
CONTEXT cpustate;
EXCEPTION_RECORD excinfo;
int miniDumpResultCode = 0;
typedef enum _MINIDUMP_TYPE {
MiniDumpNormal = 0x0000,
MiniDumpWithDataSegs = 0x0001,
MiniDumpWithFullMemory = 0x0002,
MiniDumpWithHandleData = 0x0004,
MiniDumpFilterMemory = 0x0008,
MiniDumpScanMemory = 0x0010,
MiniDumpWithUnloadedModules = 0x0020,
MiniDumpWithIndirectlyReferencedMemory = 0x0040,
MiniDumpFilterModulePaths = 0x0080,
MiniDumpWithProcessThreadData = 0x0100,
MiniDumpWithPrivateReadWriteMemory = 0x0200,
MiniDumpWithoutOptionalData = 0x0400,
} MINIDUMP_TYPE;
typedef struct _MINIDUMP_EXCEPTION_INFORMATION {
DWORD ThreadId;
PEXCEPTION_POINTERS ExceptionPointers;
BOOL ClientPointers;
} MINIDUMP_EXCEPTION_INFORMATION, *PMINIDUMP_EXCEPTION_INFORMATION;
typedef BOOL (WINAPI *MINIDUMPWRITEDUMP)(HANDLE hProcess, DWORD ProcessId,
HANDLE hFile, MINIDUMP_TYPE DumpType,
CONST PMINIDUMP_EXCEPTION_INFORMATION ExceptionParam,
CONST void *UserStreamParam,
CONST void *CallbackParam);
MINIDUMPWRITEDUMP _MiniDumpWriteDump;
void CreateMiniDump(EXCEPTION_POINTERS *pep) {
HMODULE dllHandle = LoadLibrary(L"dbghelp.dll");
if (dllHandle == NULL) {
miniDumpResultCode = 1;
return;
}
_MiniDumpWriteDump = (MINIDUMPWRITEDUMP)GetProcAddress(dllHandle, "MiniDumpWriteDump");
if (_MiniDumpWriteDump == NULL) {
FreeLibrary(dllHandle);
miniDumpResultCode = 2;
return;
}
char fileName[80];
sprintf(fileName, "CrashInfo.%s.dmp", EngineVersion.LongString.GetCStr());
HANDLE hFile = CreateFileA(fileName, GENERIC_READ | GENERIC_WRITE,
0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
if ((hFile != NULL) && (hFile != INVALID_HANDLE_VALUE)) {
MINIDUMP_EXCEPTION_INFORMATION mdei;
mdei.ThreadId = GetCurrentThreadId();
mdei.ExceptionPointers = pep;
mdei.ClientPointers = FALSE;
MINIDUMP_TYPE mdt = MiniDumpNormal; //MiniDumpWithPrivateReadWriteMemory;
BOOL rv = _MiniDumpWriteDump(GetCurrentProcess(), GetCurrentProcessId(),
hFile, mdt, (pep != 0) ? &mdei : 0, NULL, NULL);
if (!rv)
miniDumpResultCode = 4;
CloseHandle(hFile);
} else
miniDumpResultCode = 3;
FreeLibrary(dllHandle);
}
int CustomExceptionHandler(LPEXCEPTION_POINTERS exinfo) {
cpustate = exinfo->ContextRecord[0];
excinfo = exinfo->ExceptionRecord[0];
CreateMiniDump(exinfo);
return EXCEPTION_EXECUTE_HANDLER;
}
} // namespace AGS3
#endif // AGS_PLATFORM_OS_WINDOWS && !AGS_PLATFORM_DEBUG

File diff suppressed because it is too large Load Diff

View File

@ -1,49 +0,0 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
*/
//=============================================================================
//
// Built-in setup dialog for Windows version
//
//=============================================================================
#ifndef AGS_ENGINE_PLATFORM_WINDOWS_SETUP_WINSETUP_H
#define AGS_ENGINE_PLATFORM_WINDOWS_SETUP_WINSETUP_H
#include "ags/shared/util/ini_util.h"
namespace AGS3 {
namespace AGS {
namespace Engine {
using namespace Shared;
void SetWinIcon();
SetupReturnValue WinSetup(const ConfigTree &cfg_in, ConfigTree &cfg_out,
const String &game_data_dir, const String &version_str);
} // namespace Engine
} // namespace AGS
} // namespace AGS3
#endif

View File

@ -1,100 +0,0 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
*/
#include "ags/shared/core/platform.h"
#if AGS_PLATFORM_OS_WINDOWS
//include <new.h>
#include "ags/lib/allegro.h"
//include <winalleg.h>
#include "ags/shared/ac/common.h"
#include "ags/shared/ac/common_defines.h"
#include "ags/shared/debugging/debugger.h"
#include "ags/shared/debugging/out.h"
#include "ags/shared/main/main.h"
#include "ags/shared/util/ini_util.h"
#if !AGS_PLATFORM_DEBUG
#define USE_CUSTOM_EXCEPTION_HANDLER
#endif
namespace AGS3 {
using namespace AGS::Shared;
extern int proper_exit;
char tempmsg[100];
char *printfworkingspace;
#ifdef USE_CUSTOM_EXCEPTION_HANDLER
void CreateMiniDump(EXCEPTION_POINTERS *pep);
extern int CustomExceptionHandler(LPEXCEPTION_POINTERS exinfo);
extern EXCEPTION_RECORD excinfo;
extern int miniDumpResultCode;
static void DisplayException() {
String script_callstack = get_cur_script(5);
sprintf(printfworkingspace, "An exception 0x%X occurred in ACWIN.EXE at EIP = 0x%08X; program pointer is %+d, ACI version %s, gtags (%d,%d)\n\n"
"AGS cannot continue, this exception was fatal. Please note down the numbers above, remember what you were doing at the time and post the details on the AGS Technical Forum.\n\n%s\n\n"
"Most versions of Windows allow you to press Ctrl+C now to copy this entire message to the clipboard for easy reporting.\n\n%s (code %d)",
excinfo.ExceptionCode, (intptr_t)excinfo.ExceptionAddress, _G(our_eip), EngineVersion.LongString.GetCStr(), _G(eip_guinum), _G(eip_guiobj), script_callstack.GetCStr(),
(miniDumpResultCode == 0) ? "An error file CrashInfo.dmp has been created. You may be asked to upload this file when reporting this problem on the AGS Forums." :
"Unable to create an error dump file.", miniDumpResultCode);
MessageBoxA(win_get_window(), printfworkingspace, "Illegal exception", MB_ICONSTOP | MB_OK);
}
int initialize_engine_with_exception_handling(
int (initialize_engine)(const AGS::Shared::ConfigTree &startup_opts),
const ConfigTree &startup_opts) {
__try {
Debug::Printf(kDbgMsg_Info, "Installing exception handler");
return initialize_engine(startup_opts);
} __except (CustomExceptionHandler(GetExceptionInformation())) {
DisplayException();
proper_exit = 1;
}
return EXIT_CRASH;
}
#endif // USE_CUSTOM_EXCEPTION_HANDLER
int malloc_fail_handler(size_t amountwanted) {
#ifdef USE_CUSTOM_EXCEPTION_HANDLER
CreateMiniDump(NULL);
#endif
free(printfworkingspace);
sprintf(tempmsg, "Out of memory: failed to allocate %ld bytes (at PP=%d)", amountwanted, _G(our_eip));
quit(tempmsg);
return 0;
}
void setup_malloc_handling() {
_set_new_handler(malloc_fail_handler);
_set_new_mode(1);
printfworkingspace = (char *)malloc(7000);
}
} // namespace AGS3
#endif // AGS_PLATFORM_OS_WINDOWS

View File

@ -1,37 +0,0 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
*/
#ifndef AGS_ENGINE_PLATFORM_WINDOWS_WIN_EX_HANDLING_H
#define AGS_ENGINE_PLATFORM_WINDOWS_WIN_EX_HANDLING_H
#include "ags/shared/util/ini_util.h"
namespace AGS3 {
void setup_malloc_handling();
int initialize_engine_with_exception_handling(
int (initialize_engine)(const AGS::Shared::ConfigTree &startup_opts),
const AGS::Shared::ConfigTree &startup_opts);
} // namespace AGS3
#endif

View File

@ -1,66 +0,0 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
*/
//=============================================================================
//
// An excerpt from <windows.h>, declaring most commonly used WinAPI types
// and attributes. Meant to avoid including <windows.h> itself when it may
// cause naming conflicts with its dreaded heap of macros.
//
//=============================================================================
#ifndef AGS_ENGINE_PLATFORM_WINDOWS_WINAPI_EXCLUSIVE_H
#define AGS_ENGINE_PLATFORM_WINDOWS_WINAPI_EXCLUSIVE_H
namespace AGS3 {
#ifndef _WINDOWS_ // do not include if windows.h was included first
#define _WINDOWS_ // there can be only one
typedef unsigned long DWORD;
typedef int BOOL;
typedef unsigned char BYTE;
typedef unsigned short WORD;
typedef char CHAR;
#define CONST const
typedef CONST CHAR *LPCSTR, *PCSTR;
#define DECLSPEC_IMPORT __declspec(dllimport)
#define WINBASEAPI DECLSPEC_IMPORT
#define WINAPI __stdcall
typedef void *PVOID;
typedef PVOID HANDLE;
typedef HANDLE HINSTANCE;
typedef HANDLE HMODULE;
typedef HANDLE HWND;
#define FAR
#define NEAR
typedef int (FAR WINAPI *FARPROC)();
#endif
} // namespace AGS3
#endif