From b17fbf003d19fd1128bdbe271b7368d35be8c2cb Mon Sep 17 00:00:00 2001 From: janwas Date: Wed, 19 Oct 2005 03:06:54 +0000 Subject: [PATCH] -move app-specific stuff out of lib/ and into "hooks". see new lib/app_hooks* (note X macro goodness) -move tex_codec stuff out of tex.cpp and into tex_codec.cpp -tex_codec: use linked list of codecs instead of array (simplifies code and removes limit) -ogl_tex: add override mechanism for s3tc/automipmapgen extension detect -tired of keeping of debug_warn text in sync with function name; now use __func__ everywhere (and emulate that with __FUNCTION__ on MSC) -add ONCE_NOT (opposite of ONCE) -fix 3!! stupid bugs in ia32_control87, its caller and the header that were canceling each other out. float exceptions now enabled except for "inexact result" (too common). (update: nicolai had already fixed 2 of these) This was SVN commit r2964. --- source/lib/allocators.cpp | 8 +- source/lib/app_hooks.cpp | 163 ++++++++++++++++++++++++++ source/lib/app_hooks.h | 128 ++++++++++++++++++++ source/lib/debug.cpp | 56 ++------- source/lib/detect.cpp | 16 +-- source/lib/input.cpp | 9 +- source/lib/lib.h | 17 +++ source/lib/ogl.cpp | 10 +- source/lib/res/file/file.cpp | 20 ++-- source/lib/res/file/vfs.cpp | 8 +- source/lib/res/file/vfs_mount.cpp | 32 ++--- source/lib/res/file/vfs_path.cpp | 4 +- source/lib/res/file/vfs_tree.cpp | 6 +- source/lib/res/file/zip.cpp | 12 +- source/lib/res/graphics/ogl_tex.cpp | 19 +-- source/lib/res/graphics/ogl_tex.h | 2 + source/lib/res/graphics/tex.cpp | 156 +----------------------- source/lib/res/graphics/tex.h | 6 + source/lib/res/graphics/tex_bmp.cpp | 2 +- source/lib/res/graphics/tex_codec.cpp | 133 +++++++++++++++++++++ source/lib/res/graphics/tex_codec.h | 13 +- source/lib/res/graphics/tex_jpg.cpp | 4 +- source/lib/res/graphics/tex_png.cpp | 4 +- source/lib/res/graphics/tex_tga.cpp | 2 +- source/lib/res/h_mgr.cpp | 30 ++--- source/lib/res/mem.cpp | 6 +- source/lib/res/sound/snd.cpp | 14 +-- source/lib/sysdep/ia32.asm | 10 +- source/lib/sysdep/ia32.h | 20 ++-- source/lib/sysdep/sysdep.h | 12 +- source/lib/sysdep/win/waio.cpp | 20 ++-- source/lib/sysdep/win/wdbg.cpp | 50 +------- source/lib/sysdep/win/wdbg_sym.cpp | 2 +- source/lib/sysdep/win/wdetect.cpp | 4 +- source/lib/sysdep/win/wdir_watch.cpp | 4 +- source/lib/sysdep/win/win.cpp | 6 - source/lib/sysdep/win/wtime.cpp | 6 +- 37 files changed, 619 insertions(+), 395 deletions(-) create mode 100644 source/lib/app_hooks.cpp create mode 100644 source/lib/app_hooks.h create mode 100644 source/lib/res/graphics/tex_codec.cpp diff --git a/source/lib/allocators.cpp b/source/lib/allocators.cpp index fa10c54b28..55514a7a85 100644 --- a/source/lib/allocators.cpp +++ b/source/lib/allocators.cpp @@ -135,7 +135,7 @@ int da_free(DynArray* da) if(da->prot & DA_NOT_OUR_MEM) { - debug_warn("da_free: da is marked DA_NOT_OUR_MEM, must not be altered"); + debug_warn(__func__": da is marked DA_NOT_OUR_MEM, must not be altered"); return -1; } @@ -156,7 +156,7 @@ int da_set_size(DynArray* da, size_t new_size) if(da->prot & DA_NOT_OUR_MEM) { - debug_warn("da_set_size: da is marked DA_NOT_OUR_MEM, must not be altered"); + debug_warn(__func__": da is marked DA_NOT_OUR_MEM, must not be altered"); return -1; } @@ -191,7 +191,7 @@ int da_set_prot(DynArray* da, int prot) // mmap-ed, which it probably wasn't here. if(da->prot & DA_NOT_OUR_MEM) { - debug_warn("da_set_prot: da is marked DA_NOT_OUR_MEM, must not be altered"); + debug_warn(__func__": da is marked DA_NOT_OUR_MEM, must not be altered"); return -1; } @@ -336,7 +336,7 @@ void pool_free(Pool* p, void* el) if(pool_contains(p, el)) freelist_push(&p->freelist, el); else - debug_warn("pool_free: invalid pointer (not in pool)"); + debug_warn(__func__": invalid pointer (not in pool)"); } diff --git a/source/lib/app_hooks.cpp b/source/lib/app_hooks.cpp new file mode 100644 index 0000000000..2452af72db --- /dev/null +++ b/source/lib/app_hooks.cpp @@ -0,0 +1,163 @@ +// Hooks to allow application-specific behavior +// Copyright (c) 2005 Jan Wassenberg +// +// 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. +// +// Contact info: +// Jan.Wassenberg@stud.uni-karlsruhe.de +// http://www.stud.uni-karlsruhe.de/~urkt/ + +#include "precompiled.h" + +#include +#include + +#include "detect.h" +#include "res/graphics/ogl_tex.h" +#include "res/file/file.h" + +#include "app_hooks.h" + + +//----------------------------------------------------------------------------- +// default implementations +//----------------------------------------------------------------------------- + +static void override_gl_upload_caps() +{ + if(gfx_card[0] == '\0') + debug_warn("get_gfx_info 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); + } +} + + +// convert contents of file from char to wchar_t and +// append to 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); +} + +static void 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"); +} + + +// TODO: leaks memory returned by wcsdup +static const wchar_t* translate(const wchar_t* text) +{ +#if HAVE_I18N + // make sure i18n system is (already|still) initialized. + if(g_CurrentLocale) + { + // be prepared for this to fail, because translation potentially + // involves script code and the JS context might be corrupted. +#if OS_WIN + __try +#endif + { + const wchar_t* text2 = wcsdup(I18n::translate(text).c_str()); + // only overwrite if wcsdup succeeded, i.e. not out of memory. + if(text2) + text = text2; + } +#if OS_WIN + __except(EXCEPTION_EXECUTE_HANDLER) +#endif + { + } + } +#endif + + return text; +} + + +static void log(const wchar_t* text) +{ + wprintf(text); +} + + +//----------------------------------------------------------------------------- + +// contains the current set of hooks. starts with the stub values and +// may be changed via set_app_hooks. +// +// 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. +static AppHooks ah = +{ +#define FUNC(ret, name, params, param_names, call_prefix) name, +#include "app_hooks.h" +#undef FUNC + + // int dummy; used to terminate list, since last entry ended with ','. + 0 +}; + +// 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). +void set_app_hooks(AppHooks* ah_) +{ + debug_assert(ah_); + ONCE_NOT(debug_warn(__func__": app hooks already set")); + + // override members in if they are non-zero in + // (otherwise, we stick with the defaults set above) +#define FUNC(ret, name, params, param_names, call_prefix) if(ah_->name) ah.name = ah_->name; +#include "app_hooks.h" +#undef FUNC +} + +// trampolines used by lib code; they call the hooks or fall back to the +// default implementation if not set. +#define FUNC(ret, name, params, param_names, call_prefix) inline ret ah_##name params { call_prefix ah.name param_names; } +#include "app_hooks.h" +#undef FUNC diff --git a/source/lib/app_hooks.h b/source/lib/app_hooks.h new file mode 100644 index 0000000000..5303ddd4cf --- /dev/null +++ b/source/lib/app_hooks.h @@ -0,0 +1,128 @@ +// Hooks to allow application-specific behavior +// Copyright (c) 2005 Jan Wassenberg +// +// 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. +// +// Contact info: +// Jan.Wassenberg@stud.uni-karlsruhe.de +// http://www.stud.uni-karlsruhe.de/~urkt/ + +/* + +Background +---------- + +This codebase is shared between several projects, each with differing needs. +Some of them have e.g. complicated i18n/translation facilities and require +all text output to go through it; others strive to minimize size and +therefore do not want to include that. +Since commenting things out isn't an option with shared source and +conditional compilation is ugly, we bridge the differences via "hooks". +These are functions whose behavior is expected to differ between projects; +they are defined by the app, registered here and called from lib code via +our trampolines. + + +Introduction +------------ + +This module provides a clean interface for other code to call hooks +and allows the app to register them. It also defines default stub +implementations. + + +Usage +----- + +In the simplest case, the stubs are already acceptable. Otherwise, +you need to implement a new version of some hooks, fill an +AppHooks struct with pointers to those functions (zero the rest), +and call set_app_hooks. + +*/ + +// X macros that define the individual hooks. All function pointers, +// struct contents, trampoline functions etc. are automatically +// generated from them to ease maintenance. +// When adding a new hook, you need only update this and write a +// default (stub) implementation. +// +// params: +// - ret: return value type +// - name: function name identifier +// - params: parameter declarations, used when declaring the function; +// enclosed in parentheses. +// - param_names: names of parameters, used when calling the function; +// enclosed in parentheses. +// - call_prefix: precedes the call to this function. +// must be (without quotes) '(void)' if ret is void, else 'return'. +// this is to allow generating trampoline functions with or without +// a return value. +#ifdef FUNC + +// override default decision on using OpenGL extensions relating to +// texture upload. this should call ogl_tex_override to disable/force +// their use if the current card/driver combo respectively crashes or +// supports it even though the extension isn't advertised. +// +// default implementation works but is hardwired in code and therefore +// not expandable. +FUNC(void, override_gl_upload_caps, (void), (), (void)) + +// gather all app-related logs/information and write it into . +// used when writing a crashlog so that all relevant info is in one file. +// +// default implementation gathers 0ad data but is fail-safe. +FUNC(void, bundle_logs, (FILE* f), (f), (void)) + +// return localized version of if i18n functionality is available. +// +// default implementation just returns the pointer unchanged. +FUNC(const wchar_t*, translate, (const wchar_t* text), (text), return) + +// write to the app's log. +// +// default implementation uses stdout. +FUNC(void, log, (const wchar_t* text), (text), (void)) + +#endif // #ifdef FUNC + + +//----------------------------------------------------------------------------- +// normal header part + +#ifndef APP_HOOKS_H__ +#define APP_HOOKS_H__ + +// holds a function pointer for each hook. passed to set_app_hooks. +struct AppHooks +{ +#define FUNC(ret, name, params, param_names, call_prefix) ret(*name) params; +#include "app_hooks.h" +#undef FUNC + + // used to safely terminate initializer list + int dummy; +}; + +// 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). +extern void set_app_hooks(AppHooks* ah); + + +// trampolines used by lib code to call the hooks. they encapsulate +// the details of how exactly to do this. +#define FUNC(ret, name, params, param_names, call_prefix) extern ret ah_##name params; +#include "app_hooks.h" +#undef FUNC + +#endif // #ifndef APP_HOOKS_H__ \ No newline at end of file diff --git a/source/lib/debug.cpp b/source/lib/debug.cpp index 33fa1e2bf1..61eb725e62 100644 --- a/source/lib/debug.cpp +++ b/source/lib/debug.cpp @@ -28,8 +28,7 @@ // so that our allocations don't cause infinite recursion. #include "nommgr.h" #include "self_test.h" -// file_make_full_native_path is needed when bundling game data files. -#include "lib/res/file/file.h" +#include "app_hooks.h" // needed when writing crashlog static const size_t LOG_CHARS = 16384; @@ -60,7 +59,7 @@ void debug_wprintf_mem(const wchar_t* fmt, ...) va_end(args); if(len < 0) { - debug_warn("debug_wprintf_mem: vswprintf failed"); + debug_warn(__func__": vswprintf failed"); return; } debug_log_pos += len+2; @@ -68,59 +67,22 @@ void debug_wprintf_mem(const wchar_t* fmt, ...) } - - -// convert contents of file from char to wchar_t and -// append to file. used by debug_write_crashlog. -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); -} - - int debug_write_crashlog(const wchar_t* text) { - const wchar_t divider[] = L"\n\n====================================\n\n"; -#define WRITE_DIVIDER fwprintf(f, divider); - FILE* f = fopen("crashlog.txt", "w"); if(!f) + { + DISPLAY_ERROR(L"debug_write_crashlog: unable to open file"); return -1; + } fputwc(0xfeff, f); // BOM - fwprintf(f, L"%ls\n", text); - WRITE_DIVIDER + fwprintf(f, L"\n\n====================================\n\n"); - // 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); - WRITE_DIVIDER - fwprintf(f, L"Main log:\n\n"); - (void)file_make_full_native_path("../logs/mainlog.html", N_path); - cat_atow(f, N_path); - WRITE_DIVIDER + // allow user to bundle whatever information they want + ah_bundle_logs(f); + fwprintf(f, L"Last known activity:\n\n %ls\n", debug_log); diff --git a/source/lib/detect.cpp b/source/lib/detect.cpp index c5e4c87218..afd3f70ba7 100755 --- a/source/lib/detect.cpp +++ b/source/lib/detect.cpp @@ -149,8 +149,8 @@ static void get_cpu_info() void cpu_init() { #if CPU_IA32 + // must come before any uses of ia32.asm, e.g. by get_cpu_info ia32_init(); -#endif // no longer set 24 bit (float) precision by default: for // very long game uptimes (> 1 day; e.g. dedicated server), @@ -159,19 +159,19 @@ void cpu_init() // we can temporarily change precision there. //_control87(_PC_24, _MCW_PC); - // disable all floating-point exceptions except zero-divide - // Note that most exceptions are triggered by the JS engine. + // to help catch bugs, enable as many floating-point exceptions as + // possible. that means only zero-divide, because the JS engine is + // triggering the rest. _control87(_MCW_PM|_MCW_IM|_MCW_UM|_MCW_OM|_MCW_DM, _MCW_EM); + // If possible, hook up capability-sensitive assembler routines + ia32_hook_capabilities(); +#endif + // detects CPU clock frequency and capabilities, which are prerequisites // for using the TSC as a timer (desirable due to its high resolution). // do this before lengthy init so we can time those accurately. get_cpu_info(); - -#if CPU_IA32 - // If possible, hook up capability-sensitive assembler routines - ia32_hook_capabilities(); -#endif } diff --git a/source/lib/input.cpp b/source/lib/input.cpp index 493b111cea..f729a8904a 100755 --- a/source/lib/input.cpp +++ b/source/lib/input.cpp @@ -36,14 +36,15 @@ static int handler_stack_top = 0; int in_add_handler(EventHandler handler) { - if(handler_stack_top >= MAX_HANDLERS || !handler) + debug_assert(handler); + + if(handler_stack_top >= MAX_HANDLERS) { - debug_warn("in_add_handler"); + debug_warn(__func__": increase MAX_HANDLERS"); return -1; } handler_stack[handler_stack_top++] = handler; - return 0; } @@ -62,7 +63,7 @@ void dispatch_event(const SDL_Event* event) continue; // .. invalid return value else - debug_warn("dispatch_event: invalid handler return value"); + debug_warn(__func__": invalid handler return value"); } } diff --git a/source/lib/lib.h b/source/lib/lib.h index 9a3efb9fb0..077fceb06c 100755 --- a/source/lib/lib.h +++ b/source/lib/lib.h @@ -60,6 +60,7 @@ scope #include "lib/types.h" #include "sysdep/sysdep.h" +#include "sysdep/cpu.h" // CAS #if defined(__cplusplus) @@ -78,6 +79,8 @@ scope // squelch the warning (unfortunately non-portable). #define STMT(STMT_code__) do { STMT_code__; } while(false) +// execute the code passed as a parameter only the first time this is +// reached. // may be called at any time (in particular before main), but is not // thread-safe. if that's important, use pthread_once() instead. #define ONCE(ONCE_code__)\ @@ -90,6 +93,20 @@ STMT(\ }\ ) +// execute the code passed as a parameter except the first time this is +// reached. +// may be called at any time (in particular before main), but is not +// thread-safe. +#define ONCE_NOT(ONCE_code__)\ +STMT(\ + static bool ONCE_done__ = false;\ + if(!ONCE_done__)\ + ONCE_done__ = true;\ + else\ + ONCE_code__;\ +) + + // be careful here. the given expression (e.g. variable or // function return value) may be a Handle (=i64), so it needs to be diff --git a/source/lib/ogl.cpp b/source/lib/ogl.cpp index 32e9bd4100..2b981883e9 100755 --- a/source/lib/ogl.cpp +++ b/source/lib/ogl.cpp @@ -174,7 +174,7 @@ bool oglHaveVersion(const char* desired_version) int desired_major, desired_minor; if(sscanf(desired_version, "%d.%d", &desired_major, &desired_minor) != 2) { - debug_warn("oglHaveVersion: invalid version string"); + debug_warn(__func__": invalid version string"); return false; } @@ -182,7 +182,7 @@ bool oglHaveVersion(const char* desired_version) const char* version = (const char*)glGetString(GL_VERSION); if(!version || sscanf(version, "%d.%d", &major, &minor) != 2) { - debug_warn("oglHaveVersion: GL_VERSION invalid"); + debug_warn(__func__": GL_VERSION invalid"); return false; } @@ -288,7 +288,7 @@ void oglCheck() } if(error_enountered) - debug_warn("oglCheck reports error(s)"); + debug_warn(__func__": OpenGL error(s) occurred"); } #endif @@ -319,7 +319,7 @@ void oglSquelchError(GLenum err_to_ignore) } if(error_enountered) - debug_warn("oglSquelchError reports other error(s)"); + debug_warn(__func__": OpenGL error(s) occurred"); } @@ -360,7 +360,7 @@ void oglInit() // time-critical) than centralizing the 'OpenGL is ready' check. exts = (const char*)glGetString(GL_EXTENSIONS); if(!exts) - debug_warn("oglInit called before OpenGL is ready for use"); + debug_warn(__func__": called before OpenGL is ready for use"); have_12 = oglHaveVersion("1.2"); have_13 = oglHaveVersion("1.3"); have_14 = oglHaveVersion("1.4"); diff --git a/source/lib/res/file/file.cpp b/source/lib/res/file/file.cpp index f8f61ca7b6..96e97f314c 100755 --- a/source/lib/res/file/file.cpp +++ b/source/lib/res/file/file.cpp @@ -288,10 +288,10 @@ int file_set_root_dir(const char* argv0, const char* rel_path) } fail: - debug_warn("file_set_root_dir failed"); + debug_warn(__func__" failed"); if(msg) { - debug_printf("file_set_root_dir: %s\n", msg); + debug_printf(__func__": %s\n", msg); return -1; } @@ -781,7 +781,7 @@ int file_io_issue(File* f, off_t ofs, size_t size, void* p, FileIo* io) const off_t bytes_left = f->size - ofs; if(bytes_left < 0) { - debug_warn("file_io_issue: EOF"); + debug_warn(__func__": EOF"); return ERR_EOF; } if((off_t)size > bytes_left) @@ -832,7 +832,7 @@ int file_io_has_completed(FileIo* io) if(ret == 0) return 1; - debug_warn("file_io_has_completed: unexpected aio_error return"); + debug_warn(__func__": unexpected aio_error return"); return -1; } @@ -840,7 +840,7 @@ int file_io_has_completed(FileIo* io) int file_io_wait(FileIo* io, void*& p, size_t& size) { #if CONFIG_PARANOIA -debug_printf("file_io_wait: hio=%p\n", io); +debug_printf(__func__": hio=%p\n", io); #endif // zero output params in case something (e.g. H_DEREF) fails. @@ -857,7 +857,7 @@ debug_printf("file_io_wait: hio=%p\n", io); // query number of bytes transferred (-1 if the transfer failed) const ssize_t bytes_transferred = aio_return(cb); #if CONFIG_PARANOIA - debug_printf("file_io_wait: bytes_transferred=%d aio_nbytes=%d\n", + debug_printf(__func__": bytes_transferred=%d aio_nbytes=%d\n", bytes_transferred, cb->aio_nbytes); #endif // (size was clipped to EOF in file_io => this is an actual IO error) @@ -1004,7 +1004,7 @@ static void* block_find(u64 block_id) static void block_add(u64 block_id, void* block) { if(block_find(block_id)) - debug_warn("block_add: already in cache"); + debug_warn(__func__": already in cache"); else block_cache[block_id] = block; } @@ -1115,7 +1115,7 @@ debug_printf("file_io fd=%d size=%d ofs=%d\n", f->fd, data_size, data_ofs); // (not reading OR using lowio OR no callback) if(temp && (is_write || no_aio || !cb)) { - debug_warn("file_io: invalid parameter"); + debug_warn(__func__": invalid parameter"); return ERR_INVALID_PARAM; } @@ -1334,7 +1334,7 @@ int file_map(File* f, void*& p, size_t& size) // prevent overflow; if we have this many refs, should find out why. if(f->map_refs >= MAX_MAP_REFS) { - debug_warn("file_map: too many references to mapping"); + debug_warn(__func__": too many references to mapping"); return -1; } f->map_refs++; @@ -1374,7 +1374,7 @@ int file_unmap(File* f) // file is not currently mapped if(f->map_refs == 0) { - debug_warn("file_unmap: not currently mapped"); + debug_warn(__func__": not currently mapped"); return -1; } diff --git a/source/lib/res/file/vfs.cpp b/source/lib/res/file/vfs.cpp index f28d11e6a1..b2957ef637 100755 --- a/source/lib/res/file/vfs.cpp +++ b/source/lib/res/file/vfs.cpp @@ -196,7 +196,7 @@ int vfs_dir_next_ent(const Handle hd, DirEnt* ent, const char* filter) vd->filter_latched = 1; } if(vd->filter != filter) - debug_warn("vfs_dir_next_ent: filter has changed for this directory. are you scanning it twice?"); + debug_warn(__func__": filter has changed for this directory. are you scanning it twice?"); #endif bool want_dir = true; @@ -269,7 +269,7 @@ static void file_listing_add(const char* v_fn) // we've already shut down - complain. if(file_listing_enabled == -1) { - debug_warn("file_listing_add: called after file_listing_shutdown atexit"); + debug_warn(__func__": called after file_listing_shutdown atexit"); return; } @@ -296,7 +296,7 @@ void vfs_enable_file_listing(bool want_enabled) // already shut down - don't allow enabling if(file_listing_enabled == -1 && want_enabled) { - debug_warn("vfs_enable_file_listing: enabling after shutdown"); + debug_warn(__func__": enabling after shutdown"); return; } @@ -567,7 +567,7 @@ debug_printf("vfs_load v_fn=%s\n", v_fn); goto ret; } else - debug_warn("vfs_load: invalid MEM attached to vfile (0 pointer)"); + debug_warn(__func__": invalid MEM attached to vfile (0 pointer)"); // happens if someone frees the pointer. not an error! } /* diff --git a/source/lib/res/file/vfs_mount.cpp b/source/lib/res/file/vfs_mount.cpp index 2191fa719f..8ad125bf38 100644 --- a/source/lib/res/file/vfs_mount.cpp +++ b/source/lib/res/file/vfs_mount.cpp @@ -543,7 +543,7 @@ static int remount(const Mount& m) case MT_FILE: return mount_dir_tree(td, m); default: - debug_warn("remount: invalid type"); + debug_warn(__func__": invalid type"); return ERR_CORRUPTED; } } @@ -578,7 +578,7 @@ int vfs_mount(const char* V_mount_point, const char* P_real_path, int flags, uin #ifndef NDEBUG const size_t len = strlen(V_mount_point); if(len && V_mount_point[len-1] != '/') - debug_warn("vfs_mount: path doesn't end in '/'"); + debug_warn(__func__": path doesn't end in '/'"); #endif // make sure it's not already mounted, i.e. in mounts. @@ -591,7 +591,7 @@ int vfs_mount(const char* V_mount_point, const char* P_real_path, int flags, uin { if(file_is_subpath(P_real_path, it->P_name.c_str())) { - debug_warn("vfs_mount: already mounted"); + debug_warn(__func__": already mounted"); return -1; } } @@ -601,7 +601,7 @@ int vfs_mount(const char* V_mount_point, const char* P_real_path, int flags, uin // "./" and "/." are caught by CHECK_PATH. if(!strcmp(P_real_path, ".")) { - debug_warn("vfs_mount: mounting . not allowed"); + debug_warn(__func__": mounting . not allowed"); return -1; } @@ -874,7 +874,7 @@ int x_realpath(const Mount* m, const char* V_exact_path, char* P_real_path) P_parent_path = m->P_name.c_str(); break; default: - debug_warn("x_realpath: invalid type"); + debug_warn(__func__": invalid type"); return -1; } @@ -895,7 +895,7 @@ int x_open(const Mount* m, const char* V_exact_path, int flags, TFile* tf, XFile case MT_ARCHIVE: if(flags & FILE_WRITE) { - debug_warn("requesting write access to file in archive"); + debug_warn(__func__": requesting write access to file in archive"); return -1; } RETURN_ERR(zip_open(m->archive, V_exact_path, flags, &xf->u.zf)); @@ -905,7 +905,7 @@ int x_open(const Mount* m, const char* V_exact_path, int flags, TFile* tf, XFile RETURN_ERR(file_open(P_path, flags, &xf->u.f)); break; default: - debug_warn("VFile_reload: invalid type"); + debug_warn(__func__": invalid type"); return ERR_CORRUPTED; } @@ -933,7 +933,7 @@ int x_close(XFile* xf) (void)file_close(&xf->u.f); break; default: - debug_warn("x_close: invalid type"); + debug_warn(__func__": invalid type"); break; } @@ -1022,7 +1022,7 @@ int x_io(XFile* xf, off_t ofs, size_t size, void* buf, FileIOCB cb, uintptr_t ct return file_io(&xf->u.f, ofs, size, buf, cb, ctx); default: - debug_warn("vfs_io: invalid file type"); + debug_warn(__func__": invalid file type"); return ERR_CORRUPTED; } } @@ -1037,7 +1037,7 @@ int x_map(XFile* xf, void*& p, size_t& size) case MT_FILE: return file_map(&xf->u.f, p, size); default: - debug_warn("vfs_map: invalid type"); + debug_warn(__func__": invalid file type"); return ERR_CORRUPTED; } } @@ -1052,7 +1052,7 @@ int x_unmap(XFile* xf) case MT_FILE: return file_unmap(&xf->u.f); default: - debug_warn("vfs_unmap: invalid type"); + debug_warn(__func__": invalid file type"); return ERR_CORRUPTED; } } @@ -1068,7 +1068,7 @@ int x_io_issue(XFile* xf, off_t ofs, size_t size, void* buf, XIo* xio) case MT_FILE: return file_io_issue(&xf->u.f, ofs, size, buf, &xio->u.fio); default: - debug_warn("vfs_io_issue: invalid file type"); + debug_warn(__func__": invalid file type"); return ERR_CORRUPTED; } } @@ -1083,7 +1083,7 @@ int x_io_has_completed(XIo* xio) case MT_FILE: return file_io_has_completed(&xio->u.fio); default: - debug_warn("vfs_io_has_completed: invalid type"); + debug_warn(__func__": invalid file type"); return ERR_CORRUPTED; } } @@ -1098,7 +1098,7 @@ int x_io_wait(XIo* xio, void*& p, size_t& size) case MT_FILE: return file_io_wait(&xio->u.fio, p, size); default: - debug_warn("vfs_io_wait: invalid type"); + debug_warn(__func__": invalid file type"); return ERR_CORRUPTED; } } @@ -1113,7 +1113,7 @@ int x_io_discard(XIo* xio) case MT_FILE: return file_io_discard(&xio->u.fio); default: - debug_warn("VIo_dtor: invalid type"); + debug_warn(__func__": invalid file type"); return ERR_CORRUPTED; } } @@ -1128,7 +1128,7 @@ int x_io_validate(const XIo* xio) case MT_FILE: return file_io_validate(&xio->u.fio); default: - return -103; // invalid type + return -100; // invalid type } UNREACHABLE; } \ No newline at end of file diff --git a/source/lib/res/file/vfs_path.cpp b/source/lib/res/file/vfs_path.cpp index 00754b71c1..1980a64a9a 100644 --- a/source/lib/res/file/vfs_path.cpp +++ b/source/lib/res/file/vfs_path.cpp @@ -81,8 +81,8 @@ int path_validate(const uint line, const char* path) // failed somewhere - err is the error code, // or -1 if not set specifically above. fail: - debug_printf("path_validate at line %d failed: %s (error code %d)\n", line, msg, err); - debug_warn("path_validate failed"); + debug_printf(__func__" at line %d failed: %s (error code %d)\n", line, msg, err); + debug_warn(__func__" failed"); return err; ok: diff --git a/source/lib/res/file/vfs_tree.cpp b/source/lib/res/file/vfs_tree.cpp index 9655a6cc8f..68a44b77a9 100644 --- a/source/lib/res/file/vfs_tree.cpp +++ b/source/lib/res/file/vfs_tree.cpp @@ -106,7 +106,7 @@ TNode* node_alloc(size_t size) // would overflow a bucket if(size > BUCKET_SIZE-sizeof(u8*)) { - debug_warn("node_alloc: size doesn't fit in a bucket"); + debug_warn(__func__": size doesn't fit in a bucket"); return 0; } @@ -458,7 +458,7 @@ int TDir::add(const char* name, TNodeType new_type, TNode** pnode) if(!children.add(name, node)) { - debug_warn("failed to expand table"); + debug_warn(__func__": failed to expand table"); // node will be freed by node_free_all return 0; } @@ -816,7 +816,7 @@ int tree_dir_next_ent(TreeDirIterator* d_, DirEnt* ent) ent->mtime = node->u.file.mtime; break; default: - debug_warn("invalid TNode type"); + debug_warn(__func__": invalid TNode type"); } return 0; // success diff --git a/source/lib/res/file/zip.cpp b/source/lib/res/file/zip.cpp index 36f7bbce13..30bc1e9e82 100755 --- a/source/lib/res/file/zip.cpp +++ b/source/lib/res/file/zip.cpp @@ -139,7 +139,7 @@ static const u8* z_find_id(const u8* file, size_t size, const u8* start, const c { #ifndef NDEBUG if(p != start) - debug_warn("z_find_id: archive damaged, but still found next record."); + debug_warn(__func__": archive damaged, but still found next record."); #endif return p; } @@ -150,7 +150,7 @@ static const u8* z_find_id(const u8* file, size_t size, const u8* start, const c } // passed EOF, didn't find it. - debug_warn("z_find_id: archive corrupted, next record not found."); + debug_warn(__func__": archive corrupted, next record not found."); return 0; } @@ -203,7 +203,7 @@ static time_t convert_dos_date(u16 fatdate, u16 fattime) time_t ret = mktime(&t); if(ret == (time_t)-1) - debug_warn("convert_dos_date: mktime failed"); + debug_warn(__func__": mktime failed"); return ret; } @@ -764,7 +764,7 @@ int inf_set_dest(uintptr_t _ctx, void* out, size_t out_size) if(zs->next_out || zs->avail_out) { - debug_warn("zip_set_dest: ctx already in use!"); + debug_warn(__func__": ctx already in use!"); return -1; } zs->next_out = (Byte*)out; @@ -804,7 +804,7 @@ double t0 = get_time(); if(in) { if(ctx->in_buf) - debug_warn("inf_inflate: previous input buffer not empty"); + debug_warn(__func__": previous input buffer not empty"); zs->avail_in = (uInt)in_size; zs->next_in = (Byte*)in; @@ -1231,7 +1231,7 @@ int zip_map(ZFile* zf, void*& p, size_t& size) // compression algorithm is unspecified - disallow it. if(zfile_compressed(zf)) { - debug_warn("zip_map: file is compressed"); + debug_warn(__func__": file is compressed"); return -1; } diff --git a/source/lib/res/graphics/ogl_tex.cpp b/source/lib/res/graphics/ogl_tex.cpp index 17fe60f6d9..6e6ca17b76 100755 --- a/source/lib/res/graphics/ogl_tex.cpp +++ b/source/lib/res/graphics/ogl_tex.cpp @@ -118,7 +118,7 @@ static GLint choose_fmt(uint bpp, uint flags) case 5: return GL_COMPRESSED_RGBA_S3TC_DXT5_EXT; default: - debug_warn("choose_fmt: invalid DXT value"); + debug_warn(__func__": invalid DXT value"); return 0; } } @@ -138,7 +138,7 @@ static GLint choose_fmt(uint bpp, uint flags) debug_assert(alpha); return bgr? GL_BGRA : GL_RGBA; default: - debug_warn("choose_fmt: invalid bpp"); + debug_warn(__func__": invalid bpp"); return 0; } @@ -227,7 +227,7 @@ static GLint choose_int_fmt(GLenum fmt, uint q_flags) return half_bpp? GL_RGBA4 : GL_RGBA8; default: - debug_warn("choose_int_fmt doesn't cover the given fmt! please add it."); + debug_warn(__func__": given fmt isn't covered! please add it."); // fall back to a reasonable default return half_bpp? GL_RGB4 : GL_RGB8; } @@ -615,7 +615,7 @@ void ogl_tex_override(OglTexOverrides what, OglTexAllow allow) have_auto_mipmap_gen = enable; break; default: - debug_warn("ogl_tex_override: invalid "); + debug_warn(__func__": invalid "); break; } } @@ -640,15 +640,6 @@ static void detect_gl_upload_caps() } //apphook - call back into override if app thinks anything should be disabled - // disable features if we're on a card/driver combo on which they - // are known to break. - if(gfx_card[0] == '\0') - debug_warn("ogl_tex requires get_gfx_info be called before ogl_tex_upload"); - if(!strcmp(gfx_card, "S3 SuperSavage/IXC 1014")) - { - if(strstr(gfx_drv_ver, "ssicdnt.dll (2.60.115)")) - have_s3tc = false; - } // warn if more-or-less essential features are missing if(!have_s3tc) @@ -871,7 +862,7 @@ int ogl_tex_get_format(Handle ht, uint* flags, GLenum* fmt) if(fmt) { if(!ot->is_currently_uploaded) - debug_warn("ogl_tex_get_format: hasn't been defined yet!"); + debug_warn(__func__": hasn't been defined yet!"); *fmt = ot->fmt; } return 0; diff --git a/source/lib/res/graphics/ogl_tex.h b/source/lib/res/graphics/ogl_tex.h index 503deb524b..8d389e4ea4 100755 --- a/source/lib/res/graphics/ogl_tex.h +++ b/source/lib/res/graphics/ogl_tex.h @@ -249,6 +249,8 @@ enum OglTexAllow OGL_TEX_ENABLE }; +// override the default decision and force/disallow use of the +// given feature. should be called from ah_override_gl_upload_caps. extern void ogl_tex_override(OglTexOverrides what, OglTexAllow allow); // upload the texture to OpenGL. diff --git a/source/lib/res/graphics/tex.cpp b/source/lib/res/graphics/tex.cpp index 85bb779466..a3509f3563 100755 --- a/source/lib/res/graphics/tex.cpp +++ b/source/lib/res/graphics/tex.cpp @@ -331,7 +331,7 @@ static void flip_to_global_orientation(Tex* t) // dst_orientation (if the latter is 0, then the global_orientation). // (we ask for src_flags instead of src_orientation so callers don't // have to mask off TEX_ORIENTATION) -static bool orientations_match(uint src_flags, uint dst_orientation) +bool tex_orientations_match(uint src_flags, uint dst_orientation) { const uint src_orientation = src_flags & TEX_ORIENTATION; if(dst_orientation == 0) @@ -344,51 +344,6 @@ static bool orientations_match(uint src_flags, uint dst_orientation) // util //----------------------------------------------------------------------------- -// allocate an array of row pointers that point into the given texture data. -// indicates whether the file format is top-down or -// bottom-up; the row array is inverted if necessary to match global -// orienatation. (this is more efficient than "transforming" later) -// -// used by PNG and JPG codecs; caller must free() rows when done. -// -// note: we don't allocate the data param ourselves because this function is -// needed for encoding, too (where data is already present). -int tex_util_alloc_rows(const u8* data, size_t h, size_t pitch, - uint src_flags, uint dst_orientation, RowArray& rows) -{ - const bool flip = !orientations_match(src_flags, dst_orientation); - - rows = (RowArray)malloc(h * sizeof(RowPtr)); - if(!rows) - return ERR_NO_MEM; - - // determine start position and direction - RowPtr pos = flip? data+pitch*(h-1) : data; - const ssize_t add = flip? -(ssize_t)pitch : (ssize_t)pitch; - const RowPtr end = flip? data-pitch : data+pitch*h; - - for(size_t i = 0; i < h; i++) - { - rows[i] = pos; - pos += add; - } - - debug_assert(pos == end); - return 0; -} - - -int tex_util_write(Tex* t, uint transforms, const void* hdr, size_t hdr_size, DynArray* da) -{ - RETURN_ERR(tex_transform(t, transforms)); - - void* img_data = tex_get_data(t); const size_t img_size = tex_img_size(t); - RETURN_ERR(da_append(da, hdr, hdr_size)); - RETURN_ERR(da_append(da, img_data, img_size)); - return 0; -} - - void tex_util_foreach_mipmap(uint w, uint h, uint bpp, const u8* restrict data, int levels_to_skip, uint data_padding, MipmapCB cb, void* restrict ctx) { @@ -433,109 +388,6 @@ void tex_util_foreach_mipmap(uint w, uint h, uint bpp, const u8* restrict data, } -//----------------------------------------------------------------------------- -// support routines for codecs -//----------------------------------------------------------------------------- - -// should be a tight bound because we iterate this many times (for convenience) -static const uint MAX_CODECS = 8; -static const TexCodecVTbl* codecs[MAX_CODECS]; - -// add this vtbl to the codec list. called at NLSO init time by the -// TEX_CODEC_REGISTER in each codec file. note that call order and therefore -// order in the list is undefined, but since each codec only steps up if it -// can handle the given format, this is not a problem. -int tex_codec_register(const TexCodecVTbl* c) -{ - debug_assert(c != 0 && "tex_codec_register(0) - why?"); - - for(uint i = 0; i < MAX_CODECS; i++) - { - // slot available - if(codecs[i] == 0) - { - codecs[i] = c; - return 0; // success - } - } - - // didn't find a free slot. - debug_warn("tex_codec_register: increase MAX_CODECS"); - return 0; // failure, but caller ignores return value -} - - -// find codec that recognizes the desired output file extension -int tex_codec_for_filename(const char* fn, const TexCodecVTbl** c) -{ - const char* ext = strrchr(fn, '.'); - if(!ext) - return ERR_UNKNOWN_FORMAT; - ext++; // skip '.' - - for(uint i = 0; i < MAX_CODECS; i++) - { - *c = codecs[i]; - // skip if 0 (e.g. if MAX_CODECS != num codecs) - if(!*c) - continue; - // we found it - if((*c)->is_ext(ext)) - return 0; - } - - return ERR_UNKNOWN_FORMAT; -} - - -// find codec that recognizes the header's magic field -int tex_codec_for_header(const u8* file, size_t file_size, const TexCodecVTbl** c) -{ - // we guarantee at least 4 bytes for is_hdr to look at - if(file_size < 4) - return ERR_TEX_HEADER_NOT_COMPLETE; - for(uint i = 0; i < MAX_CODECS; i++) - { - *c = codecs[i]; - // skip if 0 (e.g. if MAX_CODECS != num codecs) - if(!*c) - continue; - // we found it - if((*c)->is_hdr(file)) - return 0; - } - - return ERR_UNKNOWN_FORMAT; -} - - -static int tex_codec_transform(Tex* t, uint transforms) -{ - int ret = TEX_CODEC_CANNOT_HANDLE; - - // find codec that understands the data, and transform - for(int i = 0; i < MAX_CODECS; i++) - { - // MAX_CODECS isn't a tight bound and we have hit a 0 entry - if(!codecs[i]) - continue; - - int err = codecs[i]->transform(t, transforms); - if(err == 0) - return 0; - else if(err == TEX_CODEC_CANNOT_HANDLE) - continue; - else - { - ret = err; - debug_warn("tex_codec_transform: codec indicates error"); - } - } - - return ret; -} - - //----------------------------------------------------------------------------- // API //----------------------------------------------------------------------------- @@ -587,7 +439,7 @@ int tex_load(const char* fn, Tex* t) if(ret < 0) { (void)tex_free(t); - debug_warn("tex_load failed"); + debug_warn(__func__" failed"); } // do not free hm! it either still holds the image data (i.e. texture @@ -772,8 +624,8 @@ int tex_write(Tex* t, const char* fn) err = c->encode(t, &da); if(err < 0) { - debug_printf("tex_write (%s): %d", c->name, err); - debug_warn("tex_writefailed"); + debug_printf(__func__" (%s): %d", c->name, err); + debug_warn(__func__"failed"); goto fail; } diff --git a/source/lib/res/graphics/tex.h b/source/lib/res/graphics/tex.h index 61ffc38346..e943037f26 100755 --- a/source/lib/res/graphics/tex.h +++ b/source/lib/res/graphics/tex.h @@ -261,6 +261,12 @@ extern int tex_write(Tex* t, const char* fn); // internal use only: extern int tex_validate(const Tex* t); +// indicate if the orientation specified by matches +// dst_orientation (if the latter is 0, then the global_orientation). +// (we ask for src_flags instead of src_orientation so callers don't +// have to mask off TEX_ORIENTATION) +extern bool tex_orientations_match(uint src_flags, uint dst_orientation); + typedef void(*MipmapCB)(uint level, uint level_w, uint level_h, const u8* level_data, size_t level_data_size, void* ctx); diff --git a/source/lib/res/graphics/tex_bmp.cpp b/source/lib/res/graphics/tex_bmp.cpp index ccc6cff520..ea6fbad437 100644 --- a/source/lib/res/graphics/tex_bmp.cpp +++ b/source/lib/res/graphics/tex_bmp.cpp @@ -129,7 +129,7 @@ static int bmp_encode(Tex* restrict t, DynArray* restrict da) (u32)img_size, // biSizeImage 0, 0, 0, 0 // unused (bi?PelsPerMeter, biClr*) }; - return tex_util_write(t, transforms, &hdr, hdr_size, da); + return tex_codec_write(t, transforms, &hdr, hdr_size, da); } TEX_CODEC_REGISTER(bmp); diff --git a/source/lib/res/graphics/tex_codec.cpp b/source/lib/res/graphics/tex_codec.cpp new file mode 100644 index 0000000000..b00ffaf13e --- /dev/null +++ b/source/lib/res/graphics/tex_codec.cpp @@ -0,0 +1,133 @@ +#include "precompiled.h" + +#include +#include + +#include "tex_codec.h" +#include "tex.h" + +static const TexCodecVTbl* codecs; + +// add this vtbl to the codec list. called at NLSO init time by the +// TEX_CODEC_REGISTER in each codec file. note that call order and therefore +// order in the list is undefined, but since each codec only steps up if it +// can handle the given format, this is not a problem. +int tex_codec_register(TexCodecVTbl* c) +{ + debug_assert(c); + + // insert at front of list. + c->next = codecs; + codecs = c; + + return 0; // (assigned to dummy variable) +} + + +// find codec that recognizes the desired output file extension +int tex_codec_for_filename(const char* fn, const TexCodecVTbl** c) +{ + const char* ext = strrchr(fn, '.'); + if(!ext) + return ERR_UNKNOWN_FORMAT; + ext++; // skip '.' + + for(*c = codecs; *c; *c = (*c)->next) + { + // we found it + if((*c)->is_ext(ext)) + return 0; + } + + return ERR_UNKNOWN_FORMAT; +} + + +// find codec that recognizes the header's magic field +int tex_codec_for_header(const u8* file, size_t file_size, const TexCodecVTbl** c) +{ + // we guarantee at least 4 bytes for is_hdr to look at + if(file_size < 4) + return ERR_TEX_HEADER_NOT_COMPLETE; + + for(*c = codecs; *c; *c = (*c)->next) + { + // we found it + if((*c)->is_hdr(file)) + return 0; + } + + return ERR_UNKNOWN_FORMAT; +} + + +int tex_codec_transform(Tex* t, uint transforms) +{ + int ret = TEX_CODEC_CANNOT_HANDLE; + + // find codec that understands the data, and transform + for(const TexCodecVTbl* c = codecs; c; c = c->next) + { + int err = c->transform(t, transforms); + // success + if(err == 0) + return 0; + // something went wrong + else if(err != TEX_CODEC_CANNOT_HANDLE) + { + ret = err; + debug_warn(__func__": codec indicates error"); + } + } + + return ret; +} + + +//----------------------------------------------------------------------------- +// helper functions used by codecs +//----------------------------------------------------------------------------- + +// allocate an array of row pointers that point into the given texture data. +// indicates whether the file format is top-down or +// bottom-up; the row array is inverted if necessary to match global +// orienatation. (this is more efficient than "transforming" later) +// +// used by PNG and JPG codecs; caller must free() rows when done. +// +// note: we don't allocate the data param ourselves because this function is +// needed for encoding, too (where data is already present). +int tex_codec_alloc_rows(const u8* data, size_t h, size_t pitch, + uint src_flags, uint dst_orientation, RowArray& rows) +{ + const bool flip = !tex_orientations_match(src_flags, dst_orientation); + + rows = (RowArray)malloc(h * sizeof(RowPtr)); + if(!rows) + return ERR_NO_MEM; + + // determine start position and direction + RowPtr pos = flip? data+pitch*(h-1) : data; + const ssize_t add = flip? -(ssize_t)pitch : (ssize_t)pitch; + const RowPtr end = flip? data-pitch : data+pitch*h; + + for(size_t i = 0; i < h; i++) + { + rows[i] = pos; + pos += add; + } + + debug_assert(pos == end); + return 0; +} + + +int tex_codec_write(Tex* t, uint transforms, const void* hdr, size_t hdr_size, DynArray* da) +{ + RETURN_ERR(tex_transform(t, transforms)); + + void* img_data = tex_get_data(t); const size_t img_size = tex_img_size(t); + RETURN_ERR(da_append(da, hdr, hdr_size)); + RETURN_ERR(da_append(da, img_data, img_size)); + return 0; +} diff --git a/source/lib/res/graphics/tex_codec.h b/source/lib/res/graphics/tex_codec.h index 50f38c8e89..ded7683542 100644 --- a/source/lib/res/graphics/tex_codec.h +++ b/source/lib/res/graphics/tex_codec.h @@ -37,11 +37,15 @@ struct TexCodecVTbl size_t (*hdr_size)(const u8* file); const char* name; + + // intrusive linked-list of codecs: more convenient than fixed-size + // static storage. + const TexCodecVTbl* next; }; #define TEX_CODEC_REGISTER(name)\ - static const TexCodecVTbl vtbl = { name##_decode, name##_encode, name##_transform, name##_is_hdr, name##_is_ext, name##_hdr_size, #name};\ + static TexCodecVTbl vtbl = { name##_decode, name##_encode, name##_transform, name##_is_hdr, name##_is_ext, name##_hdr_size, #name};\ static int dummy = tex_codec_register(&vtbl); @@ -53,7 +57,7 @@ const int TEX_CODEC_CANNOT_HANDLE = 1; // TEX_CODEC_REGISTER in each codec file. note that call order and therefore // order in the list is undefined, but since each codec only steps up if it // can handle the given format, this is not a problem. -extern int tex_codec_register(const TexCodecVTbl* c); +extern int tex_codec_register(TexCodecVTbl* c); // find codec that recognizes the desired output file extension @@ -62,6 +66,7 @@ extern int tex_codec_for_filename(const char* fn, const TexCodecVTbl** c); // find codec that recognizes the header's magic field extern int tex_codec_for_header(const u8* file, size_t file_size, const TexCodecVTbl** c); +extern int tex_codec_transform(Tex* t, uint transforms); // allocate an array of row pointers that point into the given texture data. @@ -75,9 +80,9 @@ extern int tex_codec_for_header(const u8* file, size_t file_size, const TexCodec // needed for encoding, too (where data is already present). typedef const u8* RowPtr; typedef RowPtr* RowArray; -extern int tex_util_alloc_rows(const u8* data, size_t h, size_t pitch, +extern int tex_codec_alloc_rows(const u8* data, size_t h, size_t pitch, uint src_flags, uint dst_orientation, RowArray& rows); -extern int tex_util_write(Tex* t, uint transforms, const void* hdr, size_t hdr_size, DynArray* da); +extern int tex_codec_write(Tex* t, uint transforms, const void* hdr, size_t hdr_size, DynArray* da); #endif // #ifndef TEX_CODEC_H__ diff --git a/source/lib/res/graphics/tex_jpg.cpp b/source/lib/res/graphics/tex_jpg.cpp index 39434b3f56..cec05bd392 100644 --- a/source/lib/res/graphics/tex_jpg.cpp +++ b/source/lib/res/graphics/tex_jpg.cpp @@ -459,7 +459,7 @@ static int jpg_decode_impl(DynArray* da, return ERR_NO_MEM; // read rows - RETURN_ERR(tex_util_alloc_rows(img, h, pitch, TEX_TOP_DOWN, 0, rows)); + RETURN_ERR(tex_codec_alloc_rows(img, h, pitch, TEX_TOP_DOWN, 0, rows)); // could use cinfo->output_scanline to keep track of progress, // but we need to count lines_left anyway (paranoia). JSAMPARRAY row = (JSAMPARRAY)rows; @@ -520,7 +520,7 @@ static int jpg_encode_impl(Tex* t, const size_t pitch = t->w * t->bpp / 8; u8* data = tex_get_data(t); - RETURN_ERR(tex_util_alloc_rows(data, t->h, pitch, t->flags, TEX_TOP_DOWN, rows)); + RETURN_ERR(tex_codec_alloc_rows(data, t->h, pitch, t->flags, TEX_TOP_DOWN, rows)); // could use cinfo->output_scanline to keep track of progress, diff --git a/source/lib/res/graphics/tex_png.cpp b/source/lib/res/graphics/tex_png.cpp index 1bcc7378f3..4af76e702a 100644 --- a/source/lib/res/graphics/tex_png.cpp +++ b/source/lib/res/graphics/tex_png.cpp @@ -105,7 +105,7 @@ static int png_decode_impl(DynArray* da, if(!img) return ERR_NO_MEM; - RETURN_ERR(tex_util_alloc_rows(img, h, pitch, TEX_TOP_DOWN, 0, rows)); + RETURN_ERR(tex_codec_alloc_rows(img, h, pitch, TEX_TOP_DOWN, 0, rows)); png_read_image(png_ptr, (png_bytepp)rows); png_read_end(png_ptr, info_ptr); @@ -158,7 +158,7 @@ static int png_encode_impl(Tex* t, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT); u8* data = tex_get_data(t); - RETURN_ERR(tex_util_alloc_rows(data, h, pitch, t->flags, TEX_TOP_DOWN, rows)); + RETURN_ERR(tex_codec_alloc_rows(data, h, pitch, t->flags, TEX_TOP_DOWN, rows)); // PNG is native RGB. const int png_transforms = (t->flags & TEX_BGR)? PNG_TRANSFORM_BGR : PNG_TRANSFORM_IDENTITY; diff --git a/source/lib/res/graphics/tex_tga.cpp b/source/lib/res/graphics/tex_tga.cpp index bd60ee2e54..1635a25713 100644 --- a/source/lib/res/graphics/tex_tga.cpp +++ b/source/lib/res/graphics/tex_tga.cpp @@ -146,7 +146,7 @@ static int tga_encode(Tex* restrict t, DynArray* restrict da) img_desc }; const size_t hdr_size = sizeof(hdr); - return tex_util_write(t, transforms, &hdr, hdr_size, da); + return tex_codec_write(t, transforms, &hdr, hdr_size, da); } TEX_CODEC_REGISTER(tga); diff --git a/source/lib/res/h_mgr.cpp b/source/lib/res/h_mgr.cpp index 35f31ee515..3a880553ef 100755 --- a/source/lib/res/h_mgr.cpp +++ b/source/lib/res/h_mgr.cpp @@ -286,7 +286,7 @@ static int alloc_idx(i32& idx, HDATA*& hd) // add another if(last_in_use >= hdata_cap) { - debug_warn("alloc_idx: too many open handles (increase IDX_BITS)"); + debug_warn(__func__": too many open handles (increase IDX_BITS)"); return ERR_LIMIT; } idx = last_in_use+1; // just incrementing idx would start it at 1 @@ -296,7 +296,7 @@ static int alloc_idx(i32& idx, HDATA*& hd) // can't fail for any other reason - idx is checked above. { // VC6 goto fix bool is_unused = !hd->tag; - debug_assert(is_unused && "alloc_idx: invalid last_in_use"); + debug_assert(is_unused && __func__": invalid last_in_use"); } have_idx:; @@ -491,17 +491,17 @@ static int type_validate(H_Type type) if(!type) { - debug_warn("h_alloc: type is 0"); + debug_warn(__func__": type is 0"); goto fail; } if(type->user_size > HDATA_USER_SIZE) { - debug_warn("h_alloc: type's user data is too large for HDATA"); + debug_warn(__func__": type's user data is too large for HDATA"); goto fail; } if(type->name == 0) { - debug_warn("h_alloc: type's name field is 0"); + debug_warn(__func__": type's name field is 0"); goto fail; } @@ -539,7 +539,7 @@ static Handle reuse_existing_handle(uintptr_t key, H_Type type, uint flags) HDATA* hd = h_data_tag_type(h, type); if(hd->refs == REF_MAX) { - debug_warn("reuse_existing: too many references to a handle - increase REF_BITS"); + debug_warn(__func__": too many references to a handle - increase REF_BITS"); return ERR_LIMIT; } @@ -761,7 +761,7 @@ void* h_user_data(const Handle h, const H_Type type) if(!hd->refs) { // note: resetting the tag is not enough (user might pass in its value) - debug_warn("h_user_data: no references to resource (it's cached, but someone is accessing it directly)"); + debug_warn(__func__": no references to resource (it's cached, but someone is accessing it directly)"); return 0; } @@ -777,7 +777,7 @@ const char* h_filename(const Handle h) HDATA* hd = h_data_tag(h); if(!hd) { - debug_warn("h_filename failed"); + debug_warn(__func__" failed"); return 0; } return hd->fn; @@ -789,7 +789,9 @@ int h_reload(const char* fn) { if(!fn) { - debug_warn("h_reload: fn = 0"); + debug_warn(__func__": fn = 0"); + // must not continue - some resources not backed by files have + // key = 0 and reloading those would be disastrous. return ERR_INVALID_PARAM; } @@ -871,13 +873,13 @@ void h_add_ref(Handle h) HDATA* hd = h_data_tag(h); if(!hd) { - debug_warn("h_add_ref: invalid handle"); + debug_warn(__func__": invalid handle"); return; } // if there are no refs, how did the caller manage to keep a Handle?! if(!hd->refs) - debug_warn("h_add_ref: no refs open - resource is cached"); + debug_warn(__func__": no refs open - resource is cached"); hd->refs++; } @@ -894,13 +896,13 @@ int h_get_refcnt(Handle h) HDATA* hd = h_data_tag(h); if(!hd) { - debug_warn("h_get_refcnt: invalid handle"); + debug_warn(__func__": invalid handle"); return ERR_INVALID_PARAM; } // if there are no refs, how did the caller manage to keep a Handle?! if(!hd->refs) - debug_warn("h_get_refcnt: no refs open - resource is cached"); + debug_warn(__func__": no refs open - resource is cached"); return hd->refs; } @@ -916,7 +918,7 @@ void h_mgr_shutdown() // each HDATA entry has already been allocated. if(!hd) { - debug_warn("h_mgr_shutdown: h_data_from_idx failed - why?!"); + debug_warn(__func__": h_data_from_idx failed - why?!"); continue; } diff --git a/source/lib/res/mem.cpp b/source/lib/res/mem.cpp index adedb304a9..19f94eef2b 100755 --- a/source/lib/res/mem.cpp +++ b/source/lib/res/mem.cpp @@ -106,7 +106,7 @@ static void remove_alloc(void* raw_p) { size_t num_removed = ptr_to_h.erase(raw_p); if(num_removed != 1) - debug_warn("remove_alloc: not in map"); + debug_warn(__func__": not in map"); } @@ -118,7 +118,7 @@ static void set_alloc(void* raw_p, Handle hm) It it = ptr_to_h.find(raw_p); if(it != ptr_to_h.end()) { - debug_warn("set_alloc: already in map"); + debug_warn(__func__": already in map"); return; } #endif @@ -360,7 +360,7 @@ void* mem_alloc(size_t size, const size_t align, uint flags, Handle* phm) Handle hm = mem_wrap(p, size, flags, raw_p, raw_size, dtor, ctx); if(!hm) // failed to allocate a handle { - debug_warn("mem_alloc: mem_wrap failed"); + debug_warn(__func__": mem_wrap failed"); dtor(p, size, ctx); return 0; } diff --git a/source/lib/res/sound/snd.cpp b/source/lib/res/sound/snd.cpp index 47170dd4f2..c9affc5955 100755 --- a/source/lib/res/sound/snd.cpp +++ b/source/lib/res/sound/snd.cpp @@ -291,7 +291,7 @@ int snd_set_master_gain(float gain) { if(gain < 0) { - debug_warn("snd_set_master_gain: gain < 0"); + debug_warn(__func__": gain < 0"); return ERR_INVALID_PARAM; } @@ -373,7 +373,7 @@ static void al_buf_free(ALuint al_buf) static void al_buf_shutdown() { if(al_bufs_outstanding != 0) - debug_warn("al_buf_shutdown: not all buffers freed!"); + debug_warn(__func__": not all buffers freed!"); } @@ -655,9 +655,9 @@ static void* io_buf_alloc() if(!buf) { if(!io_bufs) - debug_warn("io_buf_alloc: not enough memory to allocate buffer pool"); + debug_warn(__func__": not enough memory to allocate buffer pool"); else - debug_warn("io_buf_alloc: max #streams exceeded"); + debug_warn(__func__": max #streams exceeded"); // can't happen (tm) because stream_open enforces MAX_STREAMS. return 0; } @@ -766,7 +766,7 @@ static int stream_open(Stream* s, const char* fn) { if(active_streams >= MAX_STREAMS) { - debug_warn("stream_open: MAX_STREAMS exceeded - why?"); + debug_warn(__func__": MAX_STREAMS exceeded - why?"); return -1; // fail, because we wouldn't have enough IO buffers for all } @@ -1418,7 +1418,7 @@ static void list_remove(VSrc* vs) return; } - debug_warn("list_remove: VSrc not found"); + debug_warn(__func__": VSrc not found"); } @@ -1832,7 +1832,7 @@ int snd_disable(bool disabled) if(snd_disabled) { if(al_initialized) - debug_warn("snd_disable: already initialized => disable is pointless"); + debug_warn(__func__": already initialized => disable is pointless"); return 0; } else diff --git a/source/lib/sysdep/ia32.asm b/source/lib/sysdep/ia32.asm index cf8cd723d1..f34ce06832 100644 --- a/source/lib/sysdep/ia32.asm +++ b/source/lib/sysdep/ia32.asm @@ -346,18 +346,18 @@ sym(ia32_control87): push eax fnstcw [esp] pop eax ; old_cw - mov ecx, [esp+4] ; new_cw + mov ecx, [esp+4] ; new_val mov edx, [esp+8] ; mask - and ecx, edx ; new_cw & mask + and ecx, edx ; new_val & mask not edx ; ~mask and eax, edx ; old_cw & ~mask - or eax, ecx ; (old_cw & ~mask) | (new_cw & mask) - push eax + or eax, ecx ; (old_cw & ~mask) | (new_val & mask) + push eax ; = new_cw fldcw [esp] pop eax xor eax, eax ; return value ret - + ;------------------------------------------------------------------------------- ; init ;------------------------------------------------------------------------------- diff --git a/source/lib/sysdep/ia32.h b/source/lib/sysdep/ia32.h index 35fbe82007..0b033c9c91 100755 --- a/source/lib/sysdep/ia32.h +++ b/source/lib/sysdep/ia32.h @@ -39,15 +39,16 @@ extern double _ceil(double); extern u64 rdtsc(void); -#ifndef _MCW_PC -# define _MCW_PC 0x0300 // Precision Control -#endif -#ifndef _PC_24 -# define _PC_24 0x0000 // 24 bits -#endif -#ifndef _MCW_EM -# define _MCW_EM 0x003f // Exception Mask -#endif +// these may have been defined by system headers; we redefine them to +// the real IA-32 values for use with ia32_control87. +#undef _MCW_PC +#define _MCW_PC 0x0300 // Precision Control +#undef _PC_24 +#define _PC_24 0x0000 // 24 bits +#undef _MCW_EM +#define _MCW_EM 0x003f // Exception Mask +#undef _MCW_PM +#define _MCW_PM BIT(5) #ifndef _MCW_IM # define _MCW_IM 0x0001 // Invalid Operation Mask #endif @@ -72,7 +73,6 @@ extern void ia32_debug_break(void); extern void ia32_memcpy(void* dst, const void* src, size_t nbytes); - // CPU caps (128 bits) // do not change the order! enum CpuCap diff --git a/source/lib/sysdep/sysdep.h b/source/lib/sysdep/sysdep.h index 6f93c0c21d..0b5de6660c 100755 --- a/source/lib/sysdep/sysdep.h +++ b/source/lib/sysdep/sysdep.h @@ -46,7 +46,7 @@ extern void* alloca(size_t size); # define finite __finite #endif -// restrict +// C99 restrict // .. for some reason, g++-3.3 claims to support C99 (according to // __STDC_VERSION__) but doesn't have the restrict keyword. // use the extension __restrict__ instead. @@ -59,6 +59,16 @@ extern void* alloca(size_t size); # define restrict #endif +// C99 __func__ +// .. already available; need do nothing +#if HAVE_C99 +// .. VC supports something similar +#elif MSC_VERSION +# define __func__ __FUNCTION__ +// .. unsupported; remove it from code +#else +# define __func__ +#endif // diff --git a/source/lib/sysdep/win/waio.cpp b/source/lib/sysdep/win/waio.cpp index a4c2ccd6bc..bdee4d474d 100755 --- a/source/lib/sysdep/win/waio.cpp +++ b/source/lib/sysdep/win/waio.cpp @@ -181,7 +181,7 @@ static int aio_h_set(const int fd, const HANDLE h) fail: unlock(); - debug_warn("aio_h_set failed"); + debug_warn(__func__" failed"); return -1; } @@ -225,7 +225,7 @@ WIN_RESTORE_LAST_ERROR; return 0; fail: - debug_warn("aio_reopen failed"); + debug_warn(__func__" failed"); return -1; } @@ -250,7 +250,7 @@ int aio_close(int fd) return 0; fail: - debug_warn("aio_close failed"); + debug_warn(__func__" failed"); return -1; } @@ -382,7 +382,7 @@ static int aio_rw(struct aiocb* cb) // fail if aiocb is already in use (forbidden by SUSv3) if(req_find(cb)) { - debug_warn("aio_rw: aiocb is already in use"); + debug_warn(__func__": aiocb is already in use"); goto fail; } @@ -398,14 +398,14 @@ static int aio_rw(struct aiocb* cb) r = req_alloc(cb); if(!r) { - debug_warn("aio_rw: cannot allocate a Req (too many concurrent IOs)"); + debug_warn(__func__": cannot allocate a Req (too many concurrent IOs)"); goto fail; } HANDLE h = aio_h_get(fd); if(h == INVALID_HANDLE_VALUE) { - debug_warn("aio_rw: associated handle is invalid"); + debug_warn(__func__": associated handle is invalid"); ret = -EINVAL; goto fail; } @@ -531,7 +531,7 @@ int aio_error(const struct aiocb* cb) // must not pass 0 to req_find - we'd look for a free cb! if(!cb) { - debug_warn("aio_error: invalid cb"); + debug_warn(__func__": invalid cb"); return -1; } @@ -557,14 +557,14 @@ ssize_t aio_return(struct aiocb* cb) // must not pass 0 to req_find - we'd look for a free cb! if(!cb) { - debug_warn("aio_return: invalid cb"); + debug_warn(__func__": invalid cb"); return -1; } Req* r = req_find(cb); if(!r) { - debug_warn("aio_return: cb not found (already called aio_return?)"); + debug_warn(__func__": cb not found (already called aio_return?)"); return -1; } @@ -574,7 +574,7 @@ ssize_t aio_return(struct aiocb* cb) DWORD bytes_transferred; if(!GetOverlappedResult(r->hFile, &r->ovl, &bytes_transferred, wait)) { - debug_warn("aio_return: GetOverlappedResult failed"); + debug_warn(__func__": GetOverlappedResult failed"); return -1; } diff --git a/source/lib/sysdep/win/wdbg.cpp b/source/lib/sysdep/win/wdbg.cpp index 086cf3bc57..9f5ea9f7cb 100755 --- a/source/lib/sysdep/win/wdbg.cpp +++ b/source/lib/sysdep/win/wdbg.cpp @@ -26,11 +26,7 @@ #include "sysdep/cpu.h" #include "wdbg.h" #include "byte_order.h" // FOURCC - -// optional: enables translation of the "unhandled exception" dialog. -#if HAVE_I18N -#include "ps/i18n.h" -#endif +#include "app_hooks.h" #pragma data_seg(WIN_CALLBACK_PRE_MAIN(b)) @@ -61,44 +57,6 @@ static bool is_locked() } - -// return localized version of , if i18n functionality is available. -// this is used to translate the "unhandled exception" dialog strings. -// WARNING: leaks memory returned by wcsdup, but that's ok since the -// program will terminate soon after. fixing this is hard and senseless. -static const wchar_t* translate(const wchar_t* text) -{ -#if HAVE_I18N - // make sure i18n system is (already|still) initialized. - if(g_CurrentLocale) - { - // be prepared for this to fail, because translation potentially - // involves script code and the JS context might be corrupted. - __try - { - const wchar_t* text2 = wcsdup(I18n::translate(text).c_str()); - // only overwrite if wcsdup succeeded, i.e. not out of memory. - if(text2) - text = text2; - } - __except(EXCEPTION_EXECUTE_HANDLER) - { - } - } -#endif - - return text; -} - - -// convenience wrapper using translate. -static void translate_and_display_msg(const wchar_t* caption, const wchar_t* text) -{ - wdisplay_msg(translate(caption), translate(text)); -} - - - ////////////////////////////////////////////////////////////////////////////// @@ -412,7 +370,7 @@ have_reg: case DBG_BREAK_DATA_WRITE: rw = 3; break; default: - debug_warn("brk_enable_in_ctx: invalid type"); + debug_warn(__func__": invalid type"); } // .. length (determine from addr's alignment). // note: IA-32 requires len=0 for code breakpoints. @@ -641,13 +599,13 @@ static const wchar_t* get_SEH_exception_description(const EXCEPTION_RECORD* er) { const wchar_t* op = (ei[0])? L"writing" : L"reading"; const wchar_t* fmt = L"Access violation %s 0x%08X"; - swprintf(description_buf, ARRAY_SIZE(description_buf), translate(fmt), translate(op), ei[1]); + swprintf(description_buf, ARRAY_SIZE(description_buf), ah_translate(fmt), ah_translate(op), ei[1]); return description_buf; } // rationale: we don't use FormatMessage because it is unclear whether // NTDLL's symbol table will always include English-language strings - // (we don't want crashlogs in foreign gobbledygook). + // (we don't want to receive crashlogs in foreign gobbledygook). // it also adds unwanted formatting (e.g. {EXCEPTION} and trailing .). switch(code) diff --git a/source/lib/sysdep/win/wdbg_sym.cpp b/source/lib/sysdep/win/wdbg_sym.cpp index 708a57e324..548bc2fe7c 100755 --- a/source/lib/sysdep/win/wdbg_sym.cpp +++ b/source/lib/sysdep/win/wdbg_sym.cpp @@ -562,7 +562,7 @@ static void out(const wchar_t* fmt, ...) // make sure out_chars_left remains nonnegative if((size_t)len > out_chars_left) { - debug_warn("out: apparently wrote more than out_chars_left"); + debug_warn(__func__": apparently wrote more than out_chars_left"); len = (int)out_chars_left; } out_chars_left -= len; diff --git a/source/lib/sysdep/win/wdetect.cpp b/source/lib/sysdep/win/wdetect.cpp index 82f029d6cd..eac3390768 100755 --- a/source/lib/sysdep/win/wdetect.cpp +++ b/source/lib/sysdep/win/wdetect.cpp @@ -203,7 +203,7 @@ static int dll_list_add(const char* name) // make sure we're allowed to be called. if(!dll_list_pos) { - debug_warn("dll_list_add: called before dll_list_init or after failure"); + debug_warn(__func__": called before dll_list_init or after failure"); return -1; } @@ -247,7 +247,7 @@ static int dll_list_add(const char* name) // didn't fit; complain sprintf(dll_list_pos, "..."); // (room was reserved above) dll_list_pos = 0; // poison pill, prevent further calls - debug_warn("dll_list_add: not enough room"); + debug_warn(__func__": not enough room"); return ERR_BUF_SIZE; } diff --git a/source/lib/sysdep/win/wdir_watch.cpp b/source/lib/sysdep/win/wdir_watch.cpp index 848a69db94..b50f59eeb6 100755 --- a/source/lib/sysdep/win/wdir_watch.cpp +++ b/source/lib/sysdep/win/wdir_watch.cpp @@ -218,7 +218,7 @@ int dir_add_watch(const char* dir, intptr_t* _reqnum) // need it before binding dir to IOCP because it is our "key". if(last_reqnum == INT_MAX) { - debug_warn("dir_add_watch: request numbers are no longer unique"); + debug_warn(__func__": request numbers are no longer unique"); CloseHandle(hDir); goto fail; } @@ -280,7 +280,7 @@ int dir_cancel_watch(const intptr_t reqnum) Watch* w = find_watch(reqnum); if(!w) { - debug_warn("dir_cancel_watch: watches[reqnum] invalid"); + debug_warn(__func__": watches[reqnum] invalid"); return -1; } diff --git a/source/lib/sysdep/win/win.cpp b/source/lib/sysdep/win/win.cpp index a868c01076..c379275bf6 100755 --- a/source/lib/sysdep/win/win.cpp +++ b/source/lib/sysdep/win/win.cpp @@ -793,12 +793,6 @@ static #endif void win_pre_main_init() { - // enable FPU exceptions -#if CPU_IA32 - const int bits = _EM_INVALID|_EM_DENORMAL|_EM_ZERODIVIDE|_EM_OVERFLOW|_EM_UNDERFLOW|_EM_INEXACT; - _control87(bits, _MCW_EM); -#endif - // enable memory tracking and leak detection; // no effect if !HAVE_VC_DEBUG_ALLOC. #if CONFIG_PARANOIA diff --git a/source/lib/sysdep/win/wtime.cpp b/source/lib/sysdep/win/wtime.cpp index 33e1e5a14e..fb417e1249 100755 --- a/source/lib/sysdep/win/wtime.cpp +++ b/source/lib/sysdep/win/wtime.cpp @@ -278,7 +278,7 @@ static int choose_impl() return 0; } - debug_warn("hrt_choose_impl: no safe timer found!"); + debug_warn(__func__": no safe timer found!"); hrt_impl = HRT_NONE; hrt_nominal_freq = -1.0; return -1; @@ -320,7 +320,7 @@ static i64 ticks_lk() case HRT_NUM_IMPLS: default: - debug_warn("ticks_lk: invalid impl"); + debug_warn(__func__": invalid impl"); //-fallthrough case HRT_NONE: @@ -460,7 +460,7 @@ static int hrt_override_impl(HRTOverride ovr, HRTImpl impl) if((ovr != HRT_DISABLE && ovr != HRT_FORCE && ovr != HRT_DEFAULT) || (impl != HRT_TSC && impl != HRT_QPC && impl != HRT_GTC && impl != HRT_NONE)) { - debug_warn("hrt_override: invalid ovr or impl param"); + debug_warn(__func__": invalid ovr or impl param"); return -1; }