1
0
forked from 0ad/0ad

# improvements to app_hooks

thesis pointed out more dependencies that had to be stomped on.
0ad-specific apphooks are now in pyrogenesis.
added function AH_IS_DEFINED (useful for ogl_tex, which now has its own
default version of a hook)

This was SVN commit r4765.
This commit is contained in:
janwas 2007-01-13 18:37:51 +00:00
parent f5bcb031ff
commit 38755cc589
7 changed files with 122 additions and 75 deletions

View File

@ -23,14 +23,7 @@
#include "precompiled.h"
#include "app_hooks.h"
#include <string.h>
#include <stdio.h>
#include "lib/path_util.h"
#include "lib/sysdep/gfx.h"
#include "lib/res/graphics/ogl_tex.h"
#include "lib/res/file/file.h"
#include "lib/res/file/vfs.h"
//-----------------------------------------------------------------------------
@ -39,14 +32,6 @@
static void def_override_gl_upload_caps()
{
if(gfx_card[0] == '\0')
debug_warn("gfx_detect must be called before ogl_tex_upload");
if(!strcmp(gfx_card, "S3 SuperSavage/IXC 1014"))
{
if(strstr(gfx_drv_ver, "ssicdnt.dll (2.60.115)"))
ogl_tex_override(OGL_TEX_S3TC, OGL_TEX_DISABLE);
}
}
@ -54,56 +39,16 @@ static const char* def_get_log_dir()
{
static char N_log_dir[PATH_MAX];
ONCE(\
char N_exe_name[PATH_MAX];\
(void)sys_get_executable_name(N_exe_name, ARRAY_SIZE(N_exe_name));\
(void)sys_get_executable_name(N_log_dir, ARRAY_SIZE(N_log_dir));\
/* strip app name (we only want its path) */\
path_strip_fn(N_exe_name);\
(void)path_append(N_log_dir, N_exe_name, "../logs/");
path_strip_fn(N_log_dir);\
);
return N_log_dir;
}
// convert contents of file <in_filename> from char to wchar_t and
// append to <out> file.
static void cat_atow(FILE* out, const char* in_filename)
static void def_bundle_logs(FILE* UNUSED(f))
{
FILE* in = fopen(in_filename, "rb");
if(!in)
{
fwprintf(out, L"(unavailable)");
return;
}
const size_t buf_size = 1024;
char buf[buf_size+1]; // include space for trailing '\0'
while(!feof(in))
{
size_t bytes_read = fread(buf, 1, buf_size, in);
if(!bytes_read)
break;
buf[bytes_read] = 0; // 0-terminate
fwprintf(out, L"%hs", buf);
}
fclose(in);
}
static void def_bundle_logs(FILE* f)
{
// for user convenience, bundle all logs into this file:
char N_path[PATH_MAX];
fwprintf(f, L"System info:\n\n");
(void)file_make_full_native_path("../logs/system_info.txt", N_path);
cat_atow(f, N_path);
fwprintf(f, L"\n\n====================================\n\n");
fwprintf(f, L"Main log:\n\n");
(void)file_make_full_native_path("../logs/mainlog.html", N_path);
cat_atow(f, N_path);
fwprintf(f, L"\n\n====================================\n\n");
}
@ -137,8 +82,8 @@ static ErrorReaction def_display_error(const wchar_t* UNUSED(text), uint UNUSED(
// may be changed via app_hooks_update.
//
// rationale: we don't ever need to switch "hook sets", so one global struct
// is fine. by always having one defined, we also avoid having to check
// if anything was registered yet.
// is fine. by always having one defined, we also avoid the trampolines
// having to check whether their function pointer is valid.
static AppHooks ah =
{
def_override_gl_upload_caps,
@ -150,6 +95,11 @@ static AppHooks ah =
def_display_error
};
// separate copy of ah; used to determine if a particular hook has been
// redefined. the additional storage needed is negligible and this is
// easier than comparing each value against its corresponding def_ value.
static AppHooks default_ah = ah;
// register the specified hook function pointers. any of them that
// are non-zero override the previous function pointer value
// (these default to the stub hooks which are functional but basic).
@ -167,6 +117,16 @@ void app_hooks_update(AppHooks* new_ah)
OVERRIDE_IF_NONZERO(display_error)
}
bool app_hook_was_redefined(size_t offset_in_struct)
{
const u8* ah_bytes = (const u8*)&ah;
const u8* default_ah_bytes = (const u8*)&default_ah;
typedef void(*FP)(); // a bit safer than comparing void* pointers
if(*(FP)(ah_bytes+offset_in_struct) != *(FP)(default_ah_bytes+offset_in_struct))
return true;
return false;
}
//-----------------------------------------------------------------------------
// trampoline implementations
@ -175,7 +135,8 @@ void app_hooks_update(AppHooks* new_ah)
void ah_override_gl_upload_caps(void)
{
ah.override_gl_upload_caps();
if(ah.override_gl_upload_caps)
ah.override_gl_upload_caps();
}
const char* ah_get_log_dir(void)

View File

@ -193,4 +193,14 @@ struct AppHooks
**/
extern void app_hooks_update(AppHooks* ah);
/**
* was the app hook changed via app_hooks_update from its default value?
*
* @param offset_in_struct byte offset within AppHooks (determined via
* offsetof) of the app hook function pointer.
**/
extern bool app_hook_was_redefined(size_t offset_in_struct);
// name is identifier of the function pointer within AppHooks to test.
#define AH_IS_DEFINED(name) app_hook_was_redefined(offsetof(AppHooks, name))
#endif // #ifndef APP_HOOKS_H__

View File

@ -650,6 +650,10 @@ void ogl_tex_override(OglTexOverrides what, OglTexAllow allow)
// called once from the first ogl_tex_upload.
static void detect_gl_upload_caps()
{
// make sure us and the app hook have graphics card info available
if(gfx_card[0] == '\0')
debug_warn("gfx_detect must be called before ogl_tex_upload");
// detect features, but only change the variables if they were at
// "undecided" (if overrides were set before this, they must remain).
if(have_auto_mipmap_gen == -1)
@ -663,7 +667,23 @@ static void detect_gl_upload_caps()
have_s3tc = oglHaveExtensions(0, "GL_ARB_texture_compression", "GL_EXT_texture_compression_s3tc", 0) == 0;
}
ah_override_gl_upload_caps();
// allow app hook to make ogl_tex_override calls
if(AH_IS_DEFINED(override_gl_upload_caps))
{
ah_override_gl_upload_caps();
}
// no app hook defined - have our own crack at blacklisting some hardware.
else
{
// rationale: janwas's laptop's S3 card blows up if S3TC is used
// (oh, the irony). it'd be annoying to have to share this between all
// projects, hence this default implementation here.
if(!strcmp(gfx_card, "S3 SuperSavage/IXC 1014"))
{
if(strstr(gfx_drv_ver, "ssicdnt.dll (2.60.115)"))
ogl_tex_override(OGL_TEX_S3TC, OGL_TEX_DISABLE);
}
}
// warn if more-or-less essential features are missing
if(!have_s3tc)

View File

@ -141,16 +141,15 @@ static void aio_h_cleanup()
lock();
for(int i = 0; i < aio_hs_size; i++)
{
if(aio_hs[i] != INVALID_HANDLE_VALUE)
{
if(!CloseHandle(aio_hs[i]))
debug_warn("CloseHandle failed");
WARN_IF_FALSE(CloseHandle(aio_hs[i]));
aio_hs[i] = INVALID_HANDLE_VALUE;
}
}
free(aio_hs);
aio_hs = 0;
SAFE_FREE(aio_hs);
aio_hs_size = 0;
unlock();
@ -170,16 +169,9 @@ static bool is_valid_file_handle(const HANDLE h)
// used by aio_close.
static bool aio_h_is_set(const int fd)
{
bool is_set = false;
lock();
if(0 <= fd && fd < aio_hs_size)
if(aio_hs[fd] != INVALID_HANDLE_VALUE)
is_set = true;
bool is_set = (0 <= fd && fd < aio_hs_size && aio_hs[fd] != INVALID_HANDLE_VALUE);
unlock();
return is_set;
}

View File

@ -923,6 +923,8 @@ void Init(const CmdLineArgs& args, uint flags)
AppHooks hooks = {0};
hooks.translate = psTranslate;
hooks.translate_free = psTranslateFree;
hooks.bundle_logs = psBundleLogs;
hooks.get_log_dir = psGetLogDir;
app_hooks_update(&hooks);
// Set up the console early, so that debugging

View File

@ -3,6 +3,9 @@
#include "Pyrogenesis.h"
#include "ps/i18n.h"
#include "lib/path_util.h"
#include "lib/res/file/file.h"
DEFINE_ERROR(PS_OK, "OK");
DEFINE_ERROR(PS_FAIL, "Fail");
@ -38,3 +41,60 @@ void psTranslateFree(const wchar_t* text)
if(text != translate_no_mem)
free((void*)text);
}
// convert contents of file <in_filename> from char to wchar_t and
// append to <out> file.
static void cat_atow(FILE* out, const char* in_filename)
{
FILE* in = fopen(in_filename, "rb");
if(!in)
{
fwprintf(out, L"(unavailable)");
return;
}
const size_t buf_size = 1024;
char buf[buf_size+1]; // include space for trailing '\0'
while(!feof(in))
{
size_t bytes_read = fread(buf, 1, buf_size, in);
if(!bytes_read)
break;
buf[bytes_read] = 0; // 0-terminate
fwprintf(out, L"%hs", buf);
}
fclose(in);
}
void psBundleLogs(FILE* f)
{
// for user convenience, bundle all logs into this file:
char N_path[PATH_MAX];
fwprintf(f, L"System info:\n\n");
(void)file_make_full_native_path("../logs/system_info.txt", N_path);
cat_atow(f, N_path);
fwprintf(f, L"\n\n====================================\n\n");
fwprintf(f, L"Main log:\n\n");
(void)file_make_full_native_path("../logs/mainlog.html", N_path);
cat_atow(f, N_path);
fwprintf(f, L"\n\n====================================\n\n");
}
const char* psGetLogDir()
{
static char N_log_dir[PATH_MAX];
ONCE(\
char N_exe_name[PATH_MAX];\
(void)sys_get_executable_name(N_exe_name, ARRAY_SIZE(N_exe_name));\
/* strip app name (we only want its path) */\
path_strip_fn(N_exe_name);\
(void)path_append(N_log_dir, N_exe_name, "../logs/");
);
return N_log_dir;
}

View File

@ -26,5 +26,7 @@ DECLARE_ERROR(PS_FAIL);
// overrides ah_translate. registered in GameSetup.cpp
extern const wchar_t* psTranslate(const wchar_t* text);
extern void psTranslateFree(const wchar_t* text);
extern void psBundleLogs(FILE* f);
extern const char* psGetLogDir();
#endif