bits: avoid sign conversion warning
debug: cleanup ogl_tex, tex: use full-width types to avoid truncation warnings wdbg_sym.cpp: skip __suppress and __profile symbols; add additional hex display for floats; cleanup wdll_ver.cpp: cppdoc+cleanup (remove non-reentrant C interface, replace with std::string) sysdep: add cppdoc everything else: flag parameters are now consistently size_t instead of int (avoids warnings, allows slightly better code on x64) This was SVN commit r6392.
This commit is contained in:
parent
34f1817869
commit
c4654fd8fa
@ -59,7 +59,7 @@ static void def_log(const wchar_t* text)
|
||||
}
|
||||
|
||||
|
||||
static ErrorReaction def_display_error(const wchar_t* UNUSED(text), int UNUSED(flags))
|
||||
static ErrorReaction def_display_error(const wchar_t* UNUSED(text), size_t UNUSED(flags))
|
||||
{
|
||||
return ER_NOT_IMPLEMENTED;
|
||||
}
|
||||
@ -153,7 +153,7 @@ void ah_log(const wchar_t* text)
|
||||
ah.log(text);
|
||||
}
|
||||
|
||||
ErrorReaction ah_display_error(const wchar_t* text, int flags)
|
||||
ErrorReaction ah_display_error(const wchar_t* text, size_t flags)
|
||||
{
|
||||
return ah.display_error(text, flags);
|
||||
}
|
||||
|
@ -154,7 +154,7 @@ extern void ah_log(const wchar_t* text);
|
||||
* the default implementation just returns ER_NOT_IMPLEMENTED, which
|
||||
* causes the normal sys_display_error to be used.
|
||||
**/
|
||||
extern ErrorReaction ah_display_error(const wchar_t* text, int flags);
|
||||
extern ErrorReaction ah_display_error(const wchar_t* text, size_t flags);
|
||||
|
||||
|
||||
/**
|
||||
@ -169,7 +169,7 @@ struct AppHooks
|
||||
const wchar_t* (*translate)(const wchar_t* text);
|
||||
void (*translate_free)(const wchar_t* text);
|
||||
void (*log)(const wchar_t* text);
|
||||
ErrorReaction (*display_error)(const wchar_t* text, int flags);
|
||||
ErrorReaction (*display_error)(const wchar_t* text, size_t flags);
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -58,10 +58,13 @@ T bit_mask(size_t numBits)
|
||||
{
|
||||
if(numBits == 0) // prevent shift count == bitsInT, which would be undefined.
|
||||
return 0;
|
||||
// note: the perhaps more intuitive (1 << numBits)-1 cannot
|
||||
// handle numBits == bitsInT, but this implementation does.
|
||||
// notes:
|
||||
// - the perhaps more intuitive (1 << numBits)-1 cannot
|
||||
// handle numBits == bitsInT, but this implementation does.
|
||||
// - though bulky, the below statements avoid sign-conversion warnings.
|
||||
const T bitsInT = sizeof(T)*CHAR_BIT;
|
||||
T mask = ~T(0);
|
||||
T mask(0);
|
||||
mask = ~mask;
|
||||
mask >>= T(bitsInT-numBits);
|
||||
return mask;
|
||||
}
|
||||
|
@ -231,10 +231,10 @@ LibError debug_write_crashlog(const wchar_t* text)
|
||||
// translates and displays the given strings in a dialog.
|
||||
// this is typically only used when debug_display_error has failed or
|
||||
// is unavailable because that function is much more capable.
|
||||
// implemented via sys_display_msgw; see documentation there.
|
||||
// implemented via sys_display_msg; see documentation there.
|
||||
void debug_display_msgw(const wchar_t* caption, const wchar_t* msg)
|
||||
{
|
||||
sys_display_msgw(ah_translate(caption), ah_translate(msg));
|
||||
sys_display_msg(ah_translate(caption), ah_translate(msg));
|
||||
}
|
||||
|
||||
|
||||
@ -344,7 +344,7 @@ fail:
|
||||
return buf;
|
||||
}
|
||||
|
||||
static ErrorReaction call_display_error(const wchar_t* text, int flags)
|
||||
static ErrorReaction call_display_error(const wchar_t* text, size_t flags)
|
||||
{
|
||||
// first try app hook implementation
|
||||
ErrorReaction er = ah_display_error(text, flags);
|
||||
@ -355,7 +355,7 @@ static ErrorReaction call_display_error(const wchar_t* text, int flags)
|
||||
return er;
|
||||
}
|
||||
|
||||
static ErrorReaction carry_out_ErrorReaction(ErrorReaction er, int flags, u8* suppress)
|
||||
static ErrorReaction carry_out_ErrorReaction(ErrorReaction er, size_t flags, u8* suppress)
|
||||
{
|
||||
const bool manual_break = (flags & DE_MANUAL_BREAK) != 0;
|
||||
|
||||
@ -392,7 +392,7 @@ static ErrorReaction carry_out_ErrorReaction(ErrorReaction er, int flags, u8* su
|
||||
}
|
||||
|
||||
ErrorReaction debug_display_error(const wchar_t* description,
|
||||
int flags, size_t skip, void* context,
|
||||
size_t flags, size_t skip, void* context,
|
||||
const char* file, int line, const char* func,
|
||||
u8* suppress)
|
||||
{
|
||||
|
@ -52,7 +52,7 @@ LIB_API void debug_printf(const wchar_t* fmt, ...);
|
||||
* translates and displays the given strings in a dialog.
|
||||
* this is typically only used when debug_display_error has failed or
|
||||
* is unavailable because that function is much more capable.
|
||||
* implemented via sys_display_msgw; see documentation there.
|
||||
* implemented via sys_display_msg; see documentation there.
|
||||
**/
|
||||
LIB_API void debug_display_msgw(const wchar_t* caption, const wchar_t* msg);
|
||||
|
||||
@ -148,7 +148,7 @@ enum ErrorReaction
|
||||
* @return ErrorReaction (user's choice: continue running or stop?)
|
||||
**/
|
||||
LIB_API ErrorReaction debug_display_error(const wchar_t* description,
|
||||
int flags, size_t skip, void* context,
|
||||
size_t flags, size_t skip, void* context,
|
||||
const char* file, int line, const char* func,
|
||||
u8* suppress);
|
||||
|
||||
|
@ -6,7 +6,7 @@
|
||||
#include "lib/file/io/io.h"
|
||||
|
||||
|
||||
RealDirectory::RealDirectory(const Path& path, size_t priority, int flags)
|
||||
RealDirectory::RealDirectory(const Path& path, size_t priority, size_t flags)
|
||||
: m_path(path), m_priority(priority), m_flags(flags)
|
||||
{
|
||||
}
|
||||
|
@ -7,7 +7,7 @@
|
||||
class RealDirectory : public IFileLoader
|
||||
{
|
||||
public:
|
||||
RealDirectory(const Path& path, size_t priority, int flags);
|
||||
RealDirectory(const Path& path, size_t priority, size_t flags);
|
||||
|
||||
const Path& GetPath() const
|
||||
{
|
||||
@ -19,7 +19,7 @@ public:
|
||||
return m_priority;
|
||||
}
|
||||
|
||||
int Flags() const
|
||||
size_t Flags() const
|
||||
{
|
||||
return m_flags;
|
||||
}
|
||||
@ -44,7 +44,7 @@ private:
|
||||
|
||||
const size_t m_priority;
|
||||
|
||||
const int m_flags;
|
||||
const size_t m_flags;
|
||||
|
||||
// note: watches are needed in each directory because some APIs
|
||||
// (e.g. FAM) cannot watch entire trees with one call.
|
||||
|
@ -63,7 +63,7 @@ void fs_SortDirectories(DirectoryNames& directories)
|
||||
}
|
||||
|
||||
|
||||
LibError fs_ForEachFile(const PIVFS& fs, const VfsPath& path, FileCallback cb, uintptr_t cbData, const char* pattern, int flags)
|
||||
LibError fs_ForEachFile(const PIVFS& fs, const VfsPath& path, FileCallback cb, uintptr_t cbData, const char* pattern, size_t flags)
|
||||
{
|
||||
debug_assert(vfs_path_IsDirectory(path));
|
||||
|
||||
|
@ -47,7 +47,7 @@ enum DirFlags
|
||||
* @param flags see DirFlags
|
||||
* @param LibError
|
||||
**/
|
||||
extern LibError fs_ForEachFile(const PIVFS& fs, const VfsPath& path, FileCallback cb, uintptr_t cbData, const char* pattern = 0, int flags = 0);
|
||||
extern LibError fs_ForEachFile(const PIVFS& fs, const VfsPath& path, FileCallback cb, uintptr_t cbData, const char* pattern = 0, size_t flags = 0);
|
||||
|
||||
|
||||
/**
|
||||
|
@ -32,7 +32,7 @@ public:
|
||||
{
|
||||
}
|
||||
|
||||
virtual LibError Mount(const VfsPath& mountPoint, const Path& path, int flags /* = 0 */, size_t priority /* = 0 */)
|
||||
virtual LibError Mount(const VfsPath& mountPoint, const Path& path, size_t flags /* = 0 */, size_t priority /* = 0 */)
|
||||
{
|
||||
debug_assert(vfs_path_IsDirectory(mountPoint));
|
||||
// note: mounting subdirectories is now allowed.
|
||||
|
@ -54,7 +54,7 @@ struct IVFS
|
||||
* if files with archive extensions are seen, their contents are added
|
||||
* as well.
|
||||
**/
|
||||
virtual LibError Mount(const VfsPath& mountPoint, const Path& path, int flags = 0, size_t priority = 0) = 0;
|
||||
virtual LibError Mount(const VfsPath& mountPoint, const Path& path, size_t flags = 0, size_t priority = 0) = 0;
|
||||
|
||||
/**
|
||||
* retrieve information about a file (similar to POSIX stat)
|
||||
|
@ -20,7 +20,7 @@
|
||||
TIMER_ADD_CLIENT(tc_lookup);
|
||||
|
||||
|
||||
LibError vfs_Lookup(const VfsPath& pathname, VfsDirectory* startDirectory, VfsDirectory*& directory, VfsFile** pfile, int flags)
|
||||
LibError vfs_Lookup(const VfsPath& pathname, VfsDirectory* startDirectory, VfsDirectory*& directory, VfsFile** pfile, size_t flags)
|
||||
{
|
||||
TIMER_ACCRUE(tc_lookup);
|
||||
|
||||
|
@ -42,6 +42,6 @@ enum VfsLookupFlags
|
||||
*
|
||||
* to allow noiseless file-existence queries, this does not raise warnings.
|
||||
**/
|
||||
extern LibError vfs_Lookup(const VfsPath& pathname, VfsDirectory* startDirectory, VfsDirectory*& directory, VfsFile** pfile, int flags = 0);
|
||||
extern LibError vfs_Lookup(const VfsPath& pathname, VfsDirectory* startDirectory, VfsDirectory*& directory, VfsFile** pfile, size_t flags = 0);
|
||||
|
||||
#endif // #ifndef INCLUDED_VFS_LOOKUP
|
||||
|
@ -64,7 +64,7 @@ private:
|
||||
|
||||
// (we have to create missing subdirectoryNames because archivers
|
||||
// don't always place directory entries before their files)
|
||||
const int flags = VFS_LOOKUP_ADD;
|
||||
const size_t flags = VFS_LOOKUP_ADD;
|
||||
VfsDirectory* directory;
|
||||
WARN_ERR(vfs_Lookup(pathname, this_->m_directory, directory, 0, flags));
|
||||
const VfsFile file(fileInfo.Name(), fileInfo.Size(), fileInfo.MTime(), this_->m_realDirectory->Priority(), archiveFile);
|
||||
|
@ -204,7 +204,7 @@ void path_copy(char* dst, const char* src)
|
||||
// if necessary, a directory separator is added between the paths.
|
||||
// each may be empty, filenames, or full paths.
|
||||
// total path length (including '\0') must not exceed PATH_MAX.
|
||||
void path_append(char* dst, const char* path1, const char* path2, int flags)
|
||||
void path_append(char* dst, const char* path1, const char* path2, size_t flags)
|
||||
{
|
||||
const size_t len1 = strlen(path1);
|
||||
const size_t len2 = strlen(path2);
|
||||
|
@ -106,7 +106,7 @@ enum PathAppendFlags
|
||||
* total resulting string must not exceed PATH_MAX chars.
|
||||
* @param flags see PathAppendFlags.
|
||||
**/
|
||||
extern void path_append(char* dst, const char* path1, const char* path2, int flags = 0);
|
||||
extern void path_append(char* dst, const char* path1, const char* path2, size_t flags = 0);
|
||||
|
||||
/**
|
||||
* get the name component of a path.
|
||||
|
@ -48,7 +48,7 @@ static LibError load_sys_cursor(const VfsPath& pathname, int hx, int hy, sys_cur
|
||||
RETURN_ERR(tex_decode(file, fileSize, &t));
|
||||
|
||||
// convert to required BGRA format.
|
||||
const int flags = (t.flags | TEX_BGR) & ~TEX_DXT;
|
||||
const size_t flags = (t.flags | TEX_BGR) & ~TEX_DXT;
|
||||
RETURN_ERR(tex_transform_to(&t, flags));
|
||||
void* bgra_img = tex_get_data(&t);
|
||||
if(!bgra_img)
|
||||
|
@ -92,7 +92,7 @@ static bool fmt_is_s3tc(GLenum fmt)
|
||||
|
||||
|
||||
// determine OpenGL texture format, given <bpp> and Tex <flags>.
|
||||
static GLint choose_fmt(size_t bpp, int flags)
|
||||
static GLint choose_fmt(size_t bpp, size_t flags)
|
||||
{
|
||||
const bool alpha = (flags & TEX_ALPHA) != 0;
|
||||
const bool bgr = (flags & TEX_BGR ) != 0;
|
||||
@ -357,12 +357,12 @@ struct OglTex
|
||||
OglTexState state;
|
||||
|
||||
// OglTexQualityFlags
|
||||
int q_flags : 8;
|
||||
int q_flags;
|
||||
|
||||
// to which Texture Mapping Unit was this bound?
|
||||
size_t tmu : 8;
|
||||
size_t tmu;
|
||||
|
||||
int flags : 16;
|
||||
size_t flags;
|
||||
};
|
||||
|
||||
H_TYPE_DEFINE(OglTex);
|
||||
@ -475,7 +475,7 @@ static LibError OglTex_to_string(const OglTex* ot, char* buf)
|
||||
|
||||
// load and return a handle to the texture given in <pathname>.
|
||||
// for a list of supported formats, see tex.h's tex_load.
|
||||
Handle ogl_tex_load(const VfsPath& pathname, int flags)
|
||||
Handle ogl_tex_load(const VfsPath& pathname, size_t flags)
|
||||
{
|
||||
Tex* wrapped_tex = 0; // we're loading from file
|
||||
return h_alloc(H_OglTex, pathname, flags, wrapped_tex);
|
||||
@ -503,7 +503,7 @@ Handle ogl_tex_find(const VfsPath& pathname)
|
||||
// note: because we cannot guarantee that callers will pass distinct
|
||||
// "filenames", caching is disabled for the created object. this avoids
|
||||
// mistakenly reusing previous objects that share the same comment.
|
||||
Handle ogl_tex_wrap(Tex* t, const char* fn, int flags)
|
||||
Handle ogl_tex_wrap(Tex* t, const char* fn, size_t flags)
|
||||
{
|
||||
// this object may not be backed by a file ("may", because
|
||||
// someone could do tex_load and then ogl_tex_wrap).
|
||||
@ -888,7 +888,7 @@ LibError ogl_tex_get_size(Handle ht, size_t* w, size_t* h, size_t* bpp)
|
||||
// retrieve TexFlags and the corresponding OpenGL format.
|
||||
// the latter is determined during ogl_tex_upload and is 0 before that.
|
||||
// all params are optional and filled if non-NULL.
|
||||
LibError ogl_tex_get_format(Handle ht, int* flags, GLenum* fmt)
|
||||
LibError ogl_tex_get_format(Handle ht, size_t* flags, GLenum* fmt)
|
||||
{
|
||||
H_DEREF(ht, OglTex, ot);
|
||||
|
||||
|
@ -108,7 +108,7 @@ the next function to fail, but real apps should check and report errors.
|
||||
specify internal_format and use multitexturing.
|
||||
|
||||
Tex t;
|
||||
const int flags = 0; * image is plain RGB, default orientation
|
||||
const size_t flags = 0; * image is plain RGB, default orientation
|
||||
void* data = [pre-existing image]
|
||||
(void)tex_wrap(w, h, 24, flags, data, &t);
|
||||
Handle hCompositeAlphaMap = ogl_tex_wrap(&t, "(alpha map composite)");
|
||||
@ -203,7 +203,7 @@ extern void ogl_tex_set_defaults(int q_flags, GLint filter);
|
||||
* @return Handle to texture or negative LibError
|
||||
* for a list of supported formats, see tex.h's tex_load.
|
||||
*/
|
||||
extern Handle ogl_tex_load(const VfsPath& pathname, int flags = 0);
|
||||
extern Handle ogl_tex_load(const VfsPath& pathname, size_t flags = 0);
|
||||
|
||||
/**
|
||||
* Find and return an existing texture object, if it has already been
|
||||
@ -232,7 +232,7 @@ extern Handle ogl_tex_find(const VfsPath& pathname);
|
||||
* we need only add bookkeeping information and "wrap" it in
|
||||
* a resource object (accessed via Handle), hence the name.
|
||||
*/
|
||||
extern Handle ogl_tex_wrap(Tex* t, const char* fn = 0, int flags = 0);
|
||||
extern Handle ogl_tex_wrap(Tex* t, const char* fn = 0, size_t flags = 0);
|
||||
|
||||
/**
|
||||
* Release this texture reference. When the count reaches zero, all of
|
||||
@ -343,7 +343,7 @@ extern LibError ogl_tex_get_size(Handle ht, size_t* w, size_t* h, size_t* bpp);
|
||||
* (it is determined during ogl_tex_upload and 0 before then)
|
||||
* @return LibError
|
||||
*/
|
||||
extern LibError ogl_tex_get_format(Handle ht, int* flags, GLenum* fmt);
|
||||
extern LibError ogl_tex_get_format(Handle ht, size_t* flags, GLenum* fmt);
|
||||
|
||||
/**
|
||||
* Retrieve pixel data of the texture.
|
||||
@ -394,7 +394,7 @@ extern LibError ogl_tex_bind(Handle ht, size_t unit = 0);
|
||||
*
|
||||
* Must be called before uploading (raises a warning if called afterwards).
|
||||
*/
|
||||
extern LibError ogl_tex_transform(Handle ht, int flags);
|
||||
extern LibError ogl_tex_transform(Handle ht, size_t flags);
|
||||
|
||||
/**
|
||||
* Transform pixel format of the texture.
|
||||
|
@ -6,7 +6,7 @@
|
||||
|
||||
class TestTex : public CxxTest::TestSuite
|
||||
{
|
||||
void generate_encode_decode_compare(size_t w, size_t h, int flags, size_t bpp, const std::string& extension)
|
||||
void generate_encode_decode_compare(size_t w, size_t h, size_t flags, size_t bpp, const std::string& extension)
|
||||
{
|
||||
// generate test data
|
||||
const size_t size = w*h*bpp/8;
|
||||
@ -67,7 +67,7 @@ public:
|
||||
// for each bit depth
|
||||
for(size_t bpp = 8; bpp <= 32; bpp += 8)
|
||||
{
|
||||
int flags = 0;
|
||||
size_t flags = 0;
|
||||
if(!strcmp(extension, ".dds"))
|
||||
flags |= (TEX_DXT&3); // DXT3
|
||||
if(bpp == 8)
|
||||
|
@ -191,7 +191,7 @@ static LibError UniFont_to_string(const UniFont* f, char* buf)
|
||||
}
|
||||
|
||||
|
||||
Handle unifont_load(const VfsPath& pathname, int flags)
|
||||
Handle unifont_load(const VfsPath& pathname, size_t flags)
|
||||
{
|
||||
return h_alloc(H_UniFont, pathname, flags);
|
||||
}
|
||||
|
@ -19,7 +19,7 @@
|
||||
* @param pathname path and basename of the font definition file
|
||||
* (.fnt) and its texture (.tga)
|
||||
**/
|
||||
extern Handle unifont_load(const VfsPath& pathname, int flags = 0);
|
||||
extern Handle unifont_load(const VfsPath& pathname, size_t flags = 0);
|
||||
|
||||
/**
|
||||
* Release a handle to a previously loaded font
|
||||
|
@ -444,7 +444,7 @@ static u32 gen_tag()
|
||||
}
|
||||
|
||||
|
||||
static Handle reuse_existing_handle(uintptr_t key, H_Type type, int flags)
|
||||
static Handle reuse_existing_handle(uintptr_t key, H_Type type, size_t flags)
|
||||
{
|
||||
if(flags & RES_NO_CACHE)
|
||||
return 0;
|
||||
@ -506,7 +506,7 @@ static LibError call_init_and_reload(Handle h, H_Type type, HDATA* hd, const Vfs
|
||||
}
|
||||
|
||||
|
||||
static Handle alloc_new_handle(H_Type type, const VfsPath& pathname, uintptr_t key, int flags, va_list* init_args)
|
||||
static Handle alloc_new_handle(H_Type type, const VfsPath& pathname, uintptr_t key, size_t flags, va_list* init_args)
|
||||
{
|
||||
ssize_t idx;
|
||||
HDATA* hd;
|
||||
@ -549,7 +549,7 @@ fail:
|
||||
|
||||
|
||||
// any further params are passed to type's init routine
|
||||
Handle h_alloc(H_Type type, const VfsPath& pathname, int flags, ...)
|
||||
Handle h_alloc(H_Type type, const VfsPath& pathname, size_t flags, ...)
|
||||
{
|
||||
RETURN_ERR(type_validate(type));
|
||||
|
||||
|
@ -67,7 +67,7 @@ your actual definition must match.
|
||||
struct Res1
|
||||
{
|
||||
void* data; // data loaded from file
|
||||
int flags; // set when resource is created
|
||||
size_t flags; // set when resource is created
|
||||
};
|
||||
|
||||
Note that all control blocks are stored in fixed-size slots
|
||||
@ -376,7 +376,7 @@ const size_t H_STRING_LEN = 256;
|
||||
//// user_size is checked to make sure the user data fits in the handle data space.
|
||||
// dtor is associated with type and called when the object is freed.
|
||||
// handle data is initialized to 0; optionally, a pointer to it is returned.
|
||||
extern Handle h_alloc(H_Type type, const VfsPath& pathname, int flags = 0, ...);
|
||||
extern Handle h_alloc(H_Type type, const VfsPath& pathname, size_t flags = 0, ...);
|
||||
extern LibError h_free(Handle& h, H_Type type);
|
||||
|
||||
|
||||
|
@ -1158,7 +1158,7 @@ struct VSrc
|
||||
ALboolean relative;
|
||||
|
||||
/// controls vsrc_update behavior (VSrcFlags)
|
||||
int flags;
|
||||
size_t flags;
|
||||
|
||||
ALuint al_src;
|
||||
|
||||
@ -1284,7 +1284,7 @@ static LibError VSrc_to_string(const VSrc* vs, char * buf)
|
||||
*/
|
||||
Handle snd_open(const VfsPath& pathname, bool is_stream)
|
||||
{
|
||||
int flags = 0;
|
||||
size_t flags = 0;
|
||||
if(is_stream)
|
||||
flags |= VS_IS_STREAM;
|
||||
// note: RES_UNIQUE forces each instance to get a new resource
|
||||
|
@ -5,7 +5,7 @@
|
||||
#define GNU_SOURCE
|
||||
#include <dlfcn.h>
|
||||
|
||||
LibError sys_get_executable_name(char* n_path, size_t buf_size)
|
||||
LibError sys_get_executable_name(char* n_path, size_t max_chars)
|
||||
{
|
||||
Dl_info dl_info;
|
||||
|
||||
@ -16,7 +16,7 @@ LibError sys_get_executable_name(char* n_path, size_t buf_size)
|
||||
return ERR::NO_SYS;
|
||||
}
|
||||
|
||||
strncpy(n_path, dl_info.dli_fname, buf_size);
|
||||
strncpy(n_path, dl_info.dli_fname, max_chars);
|
||||
return INFO::OK;
|
||||
}
|
||||
|
||||
|
@ -55,7 +55,7 @@ LibError gfx_get_video_mode(int* xres, int* yres, int* bpp, int* freq)
|
||||
}
|
||||
|
||||
|
||||
LibError sys_get_executable_name(char* n_path, size_t buf_size)
|
||||
LibError sys_get_executable_name(char* n_path, size_t max_chars)
|
||||
{
|
||||
static char name[PATH_MAX];
|
||||
static bool init = false;
|
||||
@ -81,7 +81,7 @@ LibError sys_get_executable_name(char* n_path, size_t buf_size)
|
||||
debug_printf("app bundle name: %s\n", name);
|
||||
}
|
||||
|
||||
strncpy(n_path, name, buf_size);
|
||||
strncpy(n_path, name, max_chars);
|
||||
debug_printf("returning exe name: %s\n", name);
|
||||
|
||||
return INFO::OK;
|
||||
|
@ -16,17 +16,12 @@
|
||||
// these are basic POSIX-compatible backends for the sysdep.h functions.
|
||||
// Win32 has better versions which override these.
|
||||
|
||||
void sys_display_msg(const char* caption, const char* msg)
|
||||
{
|
||||
fprintf(stderr, "%s: %s\n", caption, msg);
|
||||
}
|
||||
|
||||
void sys_display_msgw(const wchar_t* caption, const wchar_t* msg)
|
||||
void sys_display_msg(const wchar_t* caption, const wchar_t* msg)
|
||||
{
|
||||
fwprintf(stderr, L"%ls: %ls\n", caption, msg);
|
||||
}
|
||||
|
||||
ErrorReaction sys_display_error(const wchar_t* text, int flags)
|
||||
ErrorReaction sys_display_error(const wchar_t* text, size_t flags)
|
||||
{
|
||||
printf("%ls\n\n", text);
|
||||
|
||||
|
@ -982,104 +982,108 @@ static LibError dump_sym_base_type(DWORD type_id, const u8* p, DumpState state)
|
||||
|
||||
switch(base_type)
|
||||
{
|
||||
// boolean
|
||||
case btBool:
|
||||
debug_assert(size == sizeof(bool));
|
||||
fmt = L"%hs";
|
||||
data = (u64)(data? "true " : "false");
|
||||
break;
|
||||
// boolean
|
||||
case btBool:
|
||||
debug_assert(size == sizeof(bool));
|
||||
out(L"%hs", data? "true " : "false");
|
||||
return INFO::OK;
|
||||
|
||||
// floating-point
|
||||
case btFloat:
|
||||
// C calling convention casts float params to doubles, so printf
|
||||
// expects one when we indicate %g. there are no width flags,
|
||||
// so we have to manually convert the float data to double.
|
||||
if(size == sizeof(float))
|
||||
*(double*)&data = (double)*(float*)&data;
|
||||
else if(size != sizeof(double))
|
||||
debug_assert(0); // invalid float size
|
||||
fmt = L"%g";
|
||||
break;
|
||||
// floating-point
|
||||
case btFloat:
|
||||
if(size == sizeof(float))
|
||||
{
|
||||
// NB: the C calling convention calls for float arguments to be
|
||||
// converted to double. passing `data' wouldn't work because it's
|
||||
// merely a zero-extended 32-bit representation of the float.
|
||||
float value;
|
||||
memcpy(&value, p, sizeof(value));
|
||||
out(L"%f (0x%08X)", value, value);
|
||||
}
|
||||
else if(size == sizeof(double))
|
||||
out(L"%g (0x%016X)", data, data);
|
||||
else
|
||||
debug_assert(0); // invalid float size
|
||||
return INFO::OK;
|
||||
|
||||
// signed integers (displayed as decimal)
|
||||
case btInt:
|
||||
case btLong:
|
||||
if(size != 1 && size != 2 && size != 4 && size != 8)
|
||||
debug_assert(0); // invalid int size
|
||||
// need to re-load and sign-extend, because we output 64 bits.
|
||||
data = movsx_le64(p, size);
|
||||
fmt = L"%I64d";
|
||||
break;
|
||||
// signed integers (displayed as decimal)
|
||||
case btInt:
|
||||
case btLong:
|
||||
if(size != 1 && size != 2 && size != 4 && size != 8)
|
||||
debug_assert(0); // invalid int size
|
||||
// need to re-load and sign-extend, because we output 64 bits.
|
||||
data = movsx_le64(p, size);
|
||||
fmt = L"%I64d";
|
||||
break;
|
||||
|
||||
// unsigned integers (displayed as hex)
|
||||
// note: 0x00000000 can get annoying (0 would be nicer),
|
||||
// but it indicates the variable size and makes for consistently
|
||||
// formatted structs/arrays. (0x1234 0 0x5678 is ugly)
|
||||
case btUInt:
|
||||
case btULong:
|
||||
// unsigned integers (displayed as hex)
|
||||
// note: 0x00000000 can get annoying (0 would be nicer),
|
||||
// but it indicates the variable size and makes for consistently
|
||||
// formatted structs/arrays. (0x1234 0 0x5678 is ugly)
|
||||
case btUInt:
|
||||
case btULong:
|
||||
display_as_hex:
|
||||
if(size == 1)
|
||||
{
|
||||
// _TUCHAR
|
||||
if(state.indirection)
|
||||
{
|
||||
state.indirection = 0;
|
||||
return dump_array(p, 8, type_id, size, state);
|
||||
}
|
||||
fmt = L"0x%02X";
|
||||
}
|
||||
else if(size == 2)
|
||||
fmt = L"0x%04X";
|
||||
else if(size == 4)
|
||||
fmt = L"0x%08X";
|
||||
else if(size == 8)
|
||||
fmt = L"0x%016I64X";
|
||||
else
|
||||
debug_assert(0); // invalid size_t size
|
||||
break;
|
||||
|
||||
// character
|
||||
case btChar:
|
||||
case btWChar:
|
||||
debug_assert(size == sizeof(char) || size == sizeof(wchar_t));
|
||||
// char*, wchar_t*
|
||||
if(size == 1)
|
||||
{
|
||||
// _TUCHAR
|
||||
if(state.indirection)
|
||||
{
|
||||
state.indirection = 0;
|
||||
return dump_array(p, 8, type_id, size, state);
|
||||
}
|
||||
// either integer or character;
|
||||
// if printable, the character will be appended below.
|
||||
fmt = L"%d";
|
||||
break;
|
||||
fmt = L"0x%02X";
|
||||
}
|
||||
else if(size == 2)
|
||||
fmt = L"0x%04X";
|
||||
else if(size == 4)
|
||||
fmt = L"0x%08X";
|
||||
else if(size == 8)
|
||||
fmt = L"0x%016I64X";
|
||||
else
|
||||
debug_assert(0); // invalid size_t size
|
||||
break;
|
||||
|
||||
// note: void* is sometimes indicated as (pointer, btNoType).
|
||||
case btVoid:
|
||||
case btNoType:
|
||||
// void* - cannot display what it's pointing to (type unknown).
|
||||
if(state.indirection)
|
||||
{
|
||||
out_erase(4); // " -> "
|
||||
fmt = L"";
|
||||
}
|
||||
else
|
||||
debug_assert(0); // non-pointer btVoid or btNoType
|
||||
break;
|
||||
// character
|
||||
case btChar:
|
||||
case btWChar:
|
||||
debug_assert(size == sizeof(char) || size == sizeof(wchar_t));
|
||||
// char*, wchar_t*
|
||||
if(state.indirection)
|
||||
{
|
||||
state.indirection = 0;
|
||||
return dump_array(p, 8, type_id, size, state);
|
||||
}
|
||||
// either integer or character;
|
||||
// if printable, the character will be appended below.
|
||||
fmt = L"%d";
|
||||
break;
|
||||
|
||||
default:
|
||||
debug_warn("dump_sym_base_type: unknown type");
|
||||
//-fallthrough
|
||||
// note: void* is sometimes indicated as (pointer, btNoType).
|
||||
case btVoid:
|
||||
case btNoType:
|
||||
// void* - cannot display what it's pointing to (type unknown).
|
||||
if(state.indirection)
|
||||
{
|
||||
out_erase(4); // " -> "
|
||||
fmt = L"";
|
||||
}
|
||||
else
|
||||
debug_assert(0); // non-pointer btVoid or btNoType
|
||||
break;
|
||||
|
||||
// unsupported complex types
|
||||
case btBCD:
|
||||
case btCurrency:
|
||||
case btDate:
|
||||
case btVariant:
|
||||
case btComplex:
|
||||
case btBit:
|
||||
case btBSTR:
|
||||
case btHresult:
|
||||
return ERR::SYM_UNSUPPORTED; // NOWARN
|
||||
default:
|
||||
debug_warn("dump_sym_base_type: unknown type");
|
||||
//-fallthrough
|
||||
|
||||
// unsupported complex types
|
||||
case btBCD:
|
||||
case btCurrency:
|
||||
case btDate:
|
||||
case btVariant:
|
||||
case btComplex:
|
||||
case btBit:
|
||||
case btBSTR:
|
||||
case btHresult:
|
||||
return ERR::SYM_UNSUPPORTED; // NOWARN
|
||||
}
|
||||
|
||||
out(fmt, data);
|
||||
@ -1113,8 +1117,6 @@ static LibError dump_sym_base_class(DWORD type_id, const u8* p, DumpState state)
|
||||
return ERR::SYM_UNSUPPORTED; // NOWARN
|
||||
|
||||
return dump_sym(base_class_type_id, p, state);
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
@ -1747,10 +1749,22 @@ struct IMAGEHLP_STACK_FRAME2 : public IMAGEHLP_STACK_FRAME
|
||||
}
|
||||
};
|
||||
|
||||
static bool ShouldSkipSymbol(const wchar_t* name)
|
||||
{
|
||||
if(!wcscmp(name, L"__suppress"))
|
||||
return true;
|
||||
if(!wcscmp(name, L"__profile"))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
// output the symbol's name and value via dump_sym*.
|
||||
// called from dump_frame_cb for each local symbol; lock is held.
|
||||
static BOOL CALLBACK dump_sym_cb(SYMBOL_INFO* sym, ULONG UNUSED(size), void* UNUSED(ctx))
|
||||
static BOOL CALLBACK dump_sym_cb(SYMBOL_INFOW* sym, ULONG UNUSED(size), void* UNUSED(ctx))
|
||||
{
|
||||
if(ShouldSkipSymbol(sym->Name))
|
||||
return TRUE; // continue
|
||||
|
||||
out_latch_pos(); // see decl
|
||||
mod_base = sym->ModBase;
|
||||
const u8* p = (const u8*)(uintptr_t)sym->Address;
|
||||
@ -1782,7 +1796,9 @@ static LibError dump_frame_cb(const _tagSTACKFRAME64* sf, uintptr_t UNUSED(cbDat
|
||||
// function name isn't future-proof, but not stopping is no big deal.
|
||||
// an alternative would be to check if module=kernel32, but
|
||||
// that would cut off callbacks as well.
|
||||
if(!strcmp(func_name, "_BaseProcessStart@4"))
|
||||
// note: the stdcall mangled name includes parameter size, which is
|
||||
// different in 64-bit, so only check the first characters.
|
||||
if(!strncmp(func_name, "_BaseProcessStart", 17))
|
||||
return INFO::OK;
|
||||
|
||||
out(L"%hs (%hs:%d)\r\n", func_name, file, line);
|
||||
@ -1796,10 +1812,11 @@ static LibError dump_frame_cb(const _tagSTACKFRAME64* sf, uintptr_t UNUSED(cbDat
|
||||
// declared in sub-blocks. we'd have to pass an address in that block,
|
||||
// which isn't worth the trouble. since
|
||||
IMAGEHLP_STACK_FRAME2 imghlp_frame(sf);
|
||||
SymSetContext(hProcess, &imghlp_frame, 0); // last param is ignored
|
||||
const PIMAGEHLP_CONTEXT context = 0; // ignored
|
||||
SymSetContext(hProcess, &imghlp_frame, context);
|
||||
|
||||
const ULONG64 base = 0; const char* const mask = 0; // use scope set by SymSetContext
|
||||
SymEnumSymbols(hProcess, base, mask, dump_sym_cb, 0);
|
||||
const ULONG64 base = 0; const wchar_t* const mask = 0; // use scope set by SymSetContext
|
||||
SymEnumSymbolsW(hProcess, base, mask, dump_sym_cb, 0);
|
||||
|
||||
out(L"\r\n");
|
||||
return INFO::CB_CONTINUE;
|
||||
|
@ -33,74 +33,50 @@ static LibError ReadVersionString(const OsPath& modulePathname_, char* out_ver,
|
||||
|
||||
const std::string modulePathname = modulePathname_.external_file_string();
|
||||
|
||||
#ifndef NDEBUG
|
||||
// make sure the file exists (rules out that problem as a cause of
|
||||
// GetFileVersionInfoSize failing, since it doesn't SetLastError)
|
||||
HMODULE hModule = LoadLibraryEx(modulePathname.c_str(), 0, LOAD_LIBRARY_AS_DATAFILE);
|
||||
debug_assert(hModule != 0);
|
||||
FreeLibrary(hModule);
|
||||
#endif
|
||||
|
||||
// determine size of and allocate memory for version information.
|
||||
DWORD unused;
|
||||
const DWORD ver_size = GetFileVersionInfoSize(modulePathname.c_str(), &unused);
|
||||
if(!ver_size)
|
||||
WARN_RETURN(ERR::FAIL);
|
||||
{
|
||||
// check if the failure is due to not finding modulePathname
|
||||
// (necessary since GetFileVersionInfoSize doesn't SetLastError)
|
||||
HMODULE hModule = LoadLibraryEx(modulePathname.c_str(), 0, LOAD_LIBRARY_AS_DATAFILE);
|
||||
FreeLibrary(hModule);
|
||||
const LibError err = hModule? ERR::_1 : ERR::_2;
|
||||
WARN_RETURN(err);
|
||||
}
|
||||
|
||||
shared_ptr<u8> mem = Allocate(ver_size);
|
||||
if(!GetFileVersionInfo(modulePathname.c_str(), 0, ver_size, mem.get()))
|
||||
WARN_RETURN(ERR::FAIL);
|
||||
WARN_RETURN(ERR::_3);
|
||||
|
||||
u16* lang; // -> 16 bit language ID, 16 bit codepage
|
||||
UINT lang_len;
|
||||
const BOOL ok = VerQueryValue(mem.get(), "\\VarFileInfo\\Translation", (void**)&lang, &lang_len);
|
||||
if(!ok || !lang || lang_len != 4)
|
||||
WARN_RETURN(ERR::FAIL);
|
||||
WARN_RETURN(ERR::_4);
|
||||
|
||||
char subblock[64];
|
||||
sprintf(subblock, "\\StringFileInfo\\%04X%04X\\FileVersion", lang[0], lang[1]);
|
||||
const char* in_ver;
|
||||
UINT in_ver_len;
|
||||
if(!VerQueryValue(mem.get(), subblock, (void**)&in_ver, &in_ver_len))
|
||||
WARN_RETURN(ERR::FAIL);
|
||||
WARN_RETURN(ERR::_5);
|
||||
|
||||
strcpy_s(out_ver, out_ver_len, in_ver);
|
||||
return INFO::OK;
|
||||
}
|
||||
|
||||
//
|
||||
// build a string containing DLL filename(s) and their version info.
|
||||
//
|
||||
|
||||
static char* ver_list_buf;
|
||||
static size_t ver_list_chars;
|
||||
static char* ver_list_pos;
|
||||
|
||||
// set output buffer into which DLL names and their versions will be written.
|
||||
void wdll_ver_list_init(char* buf, size_t chars)
|
||||
void wdll_ver_Append(const OsPath& pathname, std::string& list)
|
||||
{
|
||||
ver_list_pos = ver_list_buf = buf;
|
||||
ver_list_chars = chars;
|
||||
}
|
||||
|
||||
|
||||
// read DLL file version and append that and its name to the list.
|
||||
//
|
||||
// name should preferably be the complete path to DLL, to make sure
|
||||
// we don't inadvertently load another one on the library search path.
|
||||
// we add the .dll extension if necessary.
|
||||
LibError wdll_ver_list_add(const OsPath& pathname)
|
||||
{
|
||||
// not be called before wdll_ver_list_init or after failure
|
||||
if(!ver_list_pos)
|
||||
WARN_RETURN(ERR::LOGIC);
|
||||
|
||||
// pathname may not have an extension (e.g. driver names from the
|
||||
// registry). note that always appending ".dll" would be incorrect
|
||||
// since some have ".sys" extension.
|
||||
OsPath modulePathname(pathname);
|
||||
if(fs::extension(modulePathname).empty())
|
||||
modulePathname = fs::change_extension(modulePathname, ".dll");
|
||||
const std::string moduleName(modulePathname.leaf());
|
||||
|
||||
// read file version.
|
||||
// (note: we can ignore the return value since the default
|
||||
@ -108,25 +84,11 @@ LibError wdll_ver_list_add(const OsPath& pathname)
|
||||
char versionString[500] = "unknown"; // enclosed in () below
|
||||
(void)ReadVersionString(modulePathname, versionString, ARRAY_SIZE(versionString));
|
||||
|
||||
// reserve enough room for subsequent comma and "..." strings.
|
||||
const ssize_t max_chars_to_write = (ssize_t)ver_list_chars - (ver_list_pos-ver_list_buf) - 10;
|
||||
|
||||
// not first time: prepend comma to string (room was reserved above).
|
||||
if(ver_list_pos != ver_list_buf)
|
||||
ver_list_pos += sprintf(ver_list_pos, ", ");
|
||||
|
||||
// extract filename.
|
||||
const std::string moduleName(modulePathname.leaf());
|
||||
int len = snprintf(ver_list_pos, max_chars_to_write, "%s (%s)", moduleName.c_str(), versionString);
|
||||
// success
|
||||
if(len > 0)
|
||||
{
|
||||
ver_list_pos += len;
|
||||
return INFO::OK;
|
||||
}
|
||||
|
||||
// didn't fit; complain
|
||||
sprintf(ver_list_pos, "..."); // (room was reserved above)
|
||||
ver_list_pos = 0; // poison pill, prevent further calls
|
||||
WARN_RETURN(ERR::BUF_SIZE);
|
||||
if(!list.empty())
|
||||
list += ", ";
|
||||
|
||||
list += moduleName;
|
||||
list += " (";
|
||||
list += versionString;
|
||||
list += ")";
|
||||
}
|
||||
|
@ -13,16 +13,16 @@
|
||||
|
||||
#include "lib/os_path.h"
|
||||
|
||||
// WARNING: not re-entrant or thread-safe!
|
||||
|
||||
// set output buffer into which DLL names and their versions will be written.
|
||||
extern void wdll_ver_list_init(char* buf, size_t chars);
|
||||
|
||||
// read DLL file version and append that and its name to the list.
|
||||
//
|
||||
// name should preferably be the complete path to DLL, to make sure
|
||||
// we don't inadvertently load another one on the library search path.
|
||||
// we add the .dll extension if necessary.
|
||||
extern LibError wdll_ver_list_add(const OsPath& name);
|
||||
/**
|
||||
* read DLL version information and append it to a string.
|
||||
*
|
||||
* @param pathname of DLL (preferably the complete path, so that we don't
|
||||
* inadvertently load another one on the library search path.)
|
||||
* if no extension is given, .dll will be appended.
|
||||
*
|
||||
* the text output includes the module name.
|
||||
* on failure, the version is given as "unknown".
|
||||
**/
|
||||
extern void wdll_ver_Append(const OsPath& pathname, std::string& list);
|
||||
|
||||
#endif // #ifndef INCLUDED_WDLL_VER
|
||||
|
@ -100,11 +100,9 @@ static LibError win_get_gfx_drv_ver()
|
||||
// gfx_card which one is correct; we thus avoid driver-specific
|
||||
// name checks and reporting incorrectly.
|
||||
|
||||
LibError ret = ERR::FAIL; // single point of exit (for RegCloseKey)
|
||||
DWORD i;
|
||||
char drv_name[MAX_PATH+1];
|
||||
|
||||
wdll_ver_list_init(gfx_drv_ver, GFX_DRV_VER_LEN);
|
||||
std::string versionList;
|
||||
|
||||
HKEY hkOglDrivers;
|
||||
const char* key = "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\OpenGLDrivers";
|
||||
@ -116,20 +114,21 @@ static LibError win_get_gfx_drv_ver()
|
||||
{
|
||||
char set_name[32];
|
||||
DWORD set_name_len = ARRAY_SIZE(set_name);
|
||||
LONG err = RegEnumKeyEx(hkOglDrivers, i, set_name, &set_name_len, 0, 0,0, 0);
|
||||
if(err != ERROR_SUCCESS) // error or no more items - bail
|
||||
const LONG err = RegEnumKeyEx(hkOglDrivers, i, set_name, &set_name_len, 0, 0,0, 0);
|
||||
if(err == ERROR_NO_MORE_ITEMS)
|
||||
break;
|
||||
debug_assert(err == ERROR_SUCCESS);
|
||||
|
||||
HKEY hkSet;
|
||||
if(RegOpenKeyEx(hkOglDrivers, set_name, 0, KEY_QUERY_VALUE, &hkSet) == 0)
|
||||
{
|
||||
DWORD drv_name_len = ARRAY_SIZE(drv_name)-5; // for ".dll"
|
||||
if(RegQueryValueEx(hkSet, "Dll", 0, 0, (LPBYTE)drv_name, &drv_name_len) == 0)
|
||||
ret = wdll_ver_list_add(drv_name);
|
||||
wdll_ver_Append(drv_name, versionList);
|
||||
|
||||
RegCloseKey(hkSet);
|
||||
}
|
||||
} // for each subkey
|
||||
}
|
||||
|
||||
// for each value:
|
||||
// (some old drivers, e.g. S3 Super Savage, store their ICD name in a
|
||||
@ -140,16 +139,18 @@ static LibError win_get_gfx_drv_ver()
|
||||
DWORD value_name_len = ARRAY_SIZE(value_name);
|
||||
DWORD type;
|
||||
DWORD drv_name_len = ARRAY_SIZE(drv_name)-5; // for ".dll"
|
||||
DWORD err = RegEnumValue(hkOglDrivers, i, value_name,&value_name_len,
|
||||
0, &type, (LPBYTE)drv_name,&drv_name_len);
|
||||
if(err != ERROR_SUCCESS) // error or no more items - bail
|
||||
const DWORD err = RegEnumValue(hkOglDrivers, i, value_name, &value_name_len, 0, &type, (LPBYTE)drv_name, &drv_name_len);
|
||||
if(err == ERROR_NO_MORE_ITEMS)
|
||||
break;
|
||||
debug_assert(err == ERROR_SUCCESS);
|
||||
if(type == REG_SZ)
|
||||
ret = wdll_ver_list_add(drv_name);
|
||||
} // for each value
|
||||
wdll_ver_Append(drv_name, versionList);
|
||||
}
|
||||
|
||||
RegCloseKey(hkOglDrivers);
|
||||
return ret;
|
||||
|
||||
strcpy_s(gfx_drv_ver, GFX_DRV_VER_LEN, versionList.c_str());
|
||||
return INFO::OK;
|
||||
}
|
||||
|
||||
|
||||
|
@ -35,7 +35,6 @@ static DWORD win32_prot(int prot)
|
||||
return PAGE_EXECUTE_READWRITE;
|
||||
case PROT_READ|PROT_WRITE|PROT_EXEC:
|
||||
return PAGE_EXECUTE_READWRITE;
|
||||
NODEFAULT;
|
||||
}
|
||||
|
||||
return 0; // UNREACHABLE
|
||||
|
@ -264,7 +264,7 @@ long __stdcall wseh_ExceptionFilter(struct _EXCEPTION_POINTERS* ep)
|
||||
L"Details: unhandled exception (%s)\r\n";
|
||||
swprintf(message, ARRAY_SIZE(message), messageFormat, description);
|
||||
|
||||
int flags = 0;
|
||||
size_t flags = 0;
|
||||
if(ep->ExceptionRecord->ExceptionFlags & EXCEPTION_NONCONTINUABLE)
|
||||
flags = DE_NO_CONTINUE;
|
||||
ErrorReaction er = debug_display_error(message, flags, 1,ep->ContextRecord, file,line,func, 0);
|
||||
|
@ -37,7 +37,7 @@ typedef std::set<std::string> StringSet;
|
||||
// call in library search order (exe dir, then win sys dir); otherwise,
|
||||
// DLLs in the executable's starting directory hide those of the
|
||||
// same name in the system directory.
|
||||
static void add_oal_dlls_in_dir(const OsPath& path, StringSet& dlls)
|
||||
static void add_oal_dlls_in_dir(const OsPath& path, StringSet& dlls, std::string& versionList)
|
||||
{
|
||||
for(OsDirectoryIterator it(path); it != OsDirectoryIterator(); ++it)
|
||||
{
|
||||
@ -54,7 +54,7 @@ static void add_oal_dlls_in_dir(const OsPath& path, StringSet& dlls)
|
||||
if(!ret.second) // insert failed - element already there
|
||||
continue;
|
||||
|
||||
(void)wdll_ver_list_add(pathname);
|
||||
wdll_ver_Append(pathname, versionList);
|
||||
}
|
||||
}
|
||||
|
||||
@ -116,13 +116,14 @@ LibError win_get_snd_info()
|
||||
if(wmi_GetClass("Win32_SoundDevice", wmiMap) == INFO::OK)
|
||||
sprintf_s(snd_card, SND_CARD_LEN, "%ls", wmiMap[L"ProductName"].bstrVal);
|
||||
|
||||
// find all DLLs related to OpenAL, retrieve their versions,
|
||||
// and store in snd_drv_ver string.
|
||||
wdll_ver_list_init(snd_drv_ver, SND_DRV_VER_LEN);
|
||||
// find all DLLs related to OpenAL and retrieve their versions.
|
||||
std::string versionList;
|
||||
if(wutil_WindowsVersion() < WUTIL_VERSION_VISTA)
|
||||
(void)wdll_ver_list_add(GetDirectSoundDriverPath());
|
||||
wdll_ver_Append(GetDirectSoundDriverPath(), versionList);
|
||||
StringSet dlls; // ensures uniqueness
|
||||
(void)add_oal_dlls_in_dir(win_exe_dir, dlls);
|
||||
(void)add_oal_dlls_in_dir(win_sys_dir, dlls);
|
||||
(void)add_oal_dlls_in_dir(win_exe_dir, dlls, versionList);
|
||||
(void)add_oal_dlls_in_dir(win_sys_dir, dlls, versionList);
|
||||
strcpy_s(snd_drv_ver, SND_DRV_VER_LEN, versionList.c_str());
|
||||
|
||||
return INFO::OK;
|
||||
}
|
||||
|
@ -25,12 +25,7 @@
|
||||
#endif
|
||||
|
||||
|
||||
void sys_display_msg(const char* caption, const char* msg)
|
||||
{
|
||||
MessageBoxA(0, msg, caption, MB_ICONEXCLAMATION|MB_TASKMODAL|MB_SETFOREGROUND);
|
||||
}
|
||||
|
||||
void sys_display_msgw(const wchar_t* caption, const wchar_t* msg)
|
||||
void sys_display_msg(const wchar_t* caption, const wchar_t* msg)
|
||||
{
|
||||
MessageBoxW(0, msg, caption, MB_ICONEXCLAMATION|MB_TASKMODAL|MB_SETFOREGROUND);
|
||||
}
|
||||
@ -120,7 +115,7 @@ static void dlg_resize(HWND hDlg, WPARAM wParam, LPARAM lParam)
|
||||
struct DialogParams
|
||||
{
|
||||
const wchar_t* text;
|
||||
int flags;
|
||||
size_t flags;
|
||||
};
|
||||
|
||||
|
||||
@ -225,9 +220,7 @@ static INT_PTR CALLBACK error_dialog_proc(HWND hDlg, unsigned int msg, WPARAM wP
|
||||
}
|
||||
|
||||
|
||||
// show error dialog with the given text and return user's reaction.
|
||||
// exits directly if 'exit' is clicked.
|
||||
ErrorReaction sys_display_error(const wchar_t* text, int flags)
|
||||
ErrorReaction sys_display_error(const wchar_t* text, size_t flags)
|
||||
{
|
||||
// note: other threads might still be running, crash and take down the
|
||||
// process before we have a chance to display this error message.
|
||||
@ -304,12 +297,7 @@ LibError sys_error_description_r(int user_err, char* buf, size_t max_chars)
|
||||
}
|
||||
|
||||
|
||||
// determine filename of the module to whom the given address belongs.
|
||||
// useful for handling exceptions in other modules.
|
||||
// <path> receives full path to module; it must hold at least MAX_PATH chars.
|
||||
// on error, it is set to L"".
|
||||
// return path for convenience.
|
||||
wchar_t* sys_get_module_filename(void* addr, wchar_t* path)
|
||||
void sys_get_module_filename(void* addr, wchar_t* path, size_t max_chars)
|
||||
{
|
||||
path[0] = '\0'; // in case either API call below fails
|
||||
wchar_t* module_filename = path;
|
||||
@ -318,21 +306,17 @@ wchar_t* sys_get_module_filename(void* addr, wchar_t* path)
|
||||
if(VirtualQuery(addr, &mbi, sizeof(mbi)))
|
||||
{
|
||||
HMODULE hModule = (HMODULE)mbi.AllocationBase;
|
||||
if(GetModuleFileNameW(hModule, path, MAX_PATH))
|
||||
if(GetModuleFileNameW(hModule, path, (DWORD)max_chars))
|
||||
module_filename = wcsrchr(path, '\\')+1;
|
||||
// note: GetModuleFileName returns full path => a '\\' exists
|
||||
}
|
||||
|
||||
return module_filename;
|
||||
}
|
||||
|
||||
|
||||
// store full path to the current executable.
|
||||
// useful for determining installation directory, e.g. for VFS.
|
||||
inline LibError sys_get_executable_name(char* n_path, size_t buf_size)
|
||||
LibError sys_get_executable_name(char* n_path, size_t max_chars)
|
||||
{
|
||||
DWORD nbytes = GetModuleFileName(0, n_path, (DWORD)buf_size);
|
||||
return nbytes? INFO::OK : ERR::FAIL;
|
||||
const DWORD num_chars = GetModuleFileName(0, n_path, (DWORD)max_chars);
|
||||
return num_chars? INFO::OK : ERR::FAIL;
|
||||
}
|
||||
|
||||
|
||||
@ -350,13 +334,10 @@ static int CALLBACK browse_cb(HWND hWnd, unsigned int msg, LPARAM UNUSED(lParam)
|
||||
return 0;
|
||||
}
|
||||
|
||||
// have the user specify a directory via OS dialog.
|
||||
// stores its full path in the given buffer, which must hold at least
|
||||
// PATH_MAX chars.
|
||||
LibError sys_pick_directory(char* path, size_t buf_size)
|
||||
LibError sys_pick_directory(char* path, size_t max_chars)
|
||||
{
|
||||
// bring up dialog; set starting directory to current working dir.
|
||||
WARN_IF_FALSE(GetCurrentDirectory((DWORD)buf_size, path));
|
||||
WARN_IF_FALSE(GetCurrentDirectory((DWORD)max_chars, path));
|
||||
BROWSEINFOA bi;
|
||||
memset(&bi, 0, sizeof(bi));
|
||||
bi.ulFlags = BIF_RETURNONLYFSDIRS;
|
||||
@ -366,7 +347,7 @@ LibError sys_pick_directory(char* path, size_t buf_size)
|
||||
|
||||
// translate ITEMIDLIST to string. note: SHGetPathFromIDList doesn't
|
||||
// support a user-specified char limit *sigh*
|
||||
debug_assert(buf_size >= MAX_PATH); //
|
||||
debug_assert(max_chars >= MAX_PATH);
|
||||
BOOL ok = SHGetPathFromIDList(pidl, path);
|
||||
|
||||
// free the ITEMIDLIST
|
||||
|
@ -20,77 +20,111 @@
|
||||
// output
|
||||
//
|
||||
|
||||
// raise a message box with the given text or (depending on platform)
|
||||
// otherwise inform the user.
|
||||
// called from debug_display_msgw.
|
||||
extern void sys_display_msg(const char* caption, const char* msg);
|
||||
extern void sys_display_msgw(const wchar_t* caption, const wchar_t* msg);
|
||||
/**
|
||||
* display a message.
|
||||
*
|
||||
* @param caption title message
|
||||
* @param msg message contents
|
||||
*
|
||||
* implemented as a MessageBox on Win32 and printf on Unix.
|
||||
* called from debug_display_msgw.
|
||||
**/
|
||||
extern void sys_display_msg(const wchar_t* caption, const wchar_t* msg);
|
||||
|
||||
// show the error dialog. flags: see DebugDisplayErrorFlags.
|
||||
// called from debug_display_error.
|
||||
// can be overridden by means of ah_display_error.
|
||||
extern ErrorReaction sys_display_error(const wchar_t* text, int flags);
|
||||
/**
|
||||
* show the error dialog.
|
||||
*
|
||||
* @param text to display (practically unlimited length)
|
||||
* @param flags: see DebugDisplayErrorFlags.
|
||||
* @return ErrorReaction (except ER_EXIT, which is acted on immediately)
|
||||
*
|
||||
* called from debug_display_error unless overridden by means of
|
||||
* ah_display_error.
|
||||
**/
|
||||
extern ErrorReaction sys_display_error(const wchar_t* text, size_t flags);
|
||||
|
||||
|
||||
//
|
||||
// misc
|
||||
//
|
||||
|
||||
// sys_vsnprintf: doesn't quite follow the standard for vsnprintf, but works
|
||||
// better across compilers:
|
||||
// - handles positional parameters and %lld
|
||||
// - always null-terminates the buffer
|
||||
// - returns -1 on overflow (if the output string (including null) does not fit in the buffer)
|
||||
/**
|
||||
* sys_vsnprintf: doesn't quite follow the standard for vsnprintf, but works
|
||||
* better across compilers:
|
||||
* - handles positional parameters and %lld
|
||||
* - always null-terminates the buffer
|
||||
* - returns -1 on overflow (if the output string (including null) does not fit in the buffer)
|
||||
**/
|
||||
extern int sys_vsnprintf(char* buffer, size_t count, const char* format, va_list argptr);
|
||||
|
||||
|
||||
// describe the current OS error state.
|
||||
//
|
||||
// err: if not 0, use that as the error code to translate; otherwise,
|
||||
// uses GetLastError or similar.
|
||||
// rationale: it is expected to be rare that OS return/error codes are
|
||||
// actually seen by user code, but we leave the possibility open.
|
||||
/**
|
||||
* describe the current OS error state.
|
||||
*
|
||||
* @param err: if not 0, use that as the error code to translate; otherwise,
|
||||
* uses GetLastError or similar.
|
||||
* @param buf output buffer
|
||||
* @param max_chars
|
||||
*
|
||||
* rationale: it is expected to be rare that OS return/error codes are
|
||||
* actually seen by user code, but we leave the possibility open.
|
||||
**/
|
||||
extern LibError sys_error_description_r(int err, char* buf, size_t max_chars);
|
||||
|
||||
// determine filename of the module to whom the given address belongs.
|
||||
// useful for handling exceptions in other modules.
|
||||
// <path> receives full path to module; it must hold at least MAX_PATH chars.
|
||||
// on error, it is set to L"".
|
||||
// return path for convenience.
|
||||
wchar_t* sys_get_module_filename(void* addr, wchar_t* path);
|
||||
/**
|
||||
* determine filename of the module to whom an address belongs.
|
||||
*
|
||||
* @param path receives full path to module or L"" on error.
|
||||
* @param max_chars
|
||||
*
|
||||
* note: this is useful for handling exceptions in other modules.
|
||||
**/
|
||||
void sys_get_module_filename(void* addr, wchar_t* path, size_t max_chars);
|
||||
|
||||
// store full path to the current executable.
|
||||
// useful for determining installation directory, e.g. for VFS.
|
||||
extern LibError sys_get_executable_name(char* n_path, size_t buf_size);
|
||||
/**
|
||||
* get path to the current executable.
|
||||
*
|
||||
* @param n_path receives the full native path.
|
||||
* @param max_chars
|
||||
*
|
||||
* this is useful for determining installation directory, e.g. for VFS.
|
||||
**/
|
||||
extern LibError sys_get_executable_name(char* n_path, size_t max_chars);
|
||||
|
||||
// have the user specify a directory via OS dialog.
|
||||
// stores its full path in the given buffer, which must hold at least
|
||||
// PATH_MAX chars.
|
||||
extern LibError sys_pick_directory(char* n_path, size_t buf_size);
|
||||
/**
|
||||
* have the user choose a directory via OS dialog.
|
||||
*
|
||||
* @param n_path receives the full native path.
|
||||
* @param max_chars must be at least PATH_MAX due to a Win32 limitation.
|
||||
**/
|
||||
extern LibError sys_pick_directory(char* n_path, size_t max_chars);
|
||||
|
||||
|
||||
// return the largest sector size [bytes] of any storage medium
|
||||
// (HD, optical, etc.) in the system.
|
||||
//
|
||||
// this may be a bit slow to determine (iterates over all drives),
|
||||
// but caches the result so subsequent calls are free.
|
||||
// (caveat: device changes won't be noticed during this program run)
|
||||
//
|
||||
// sector size is relevant because Windows aio requires all IO
|
||||
// buffers, offsets and lengths to be a multiple of it. this requirement
|
||||
// is also carried over into the vfs / file.cpp interfaces for efficiency
|
||||
// (avoids the need for copying to/from align buffers).
|
||||
//
|
||||
// waio uses the sector size to (in some cases) align IOs if
|
||||
// they aren't already, but it's also needed by user code when
|
||||
// aligning their buffers to meet the requirements.
|
||||
//
|
||||
// the largest size is used so that we can read from any drive. while this
|
||||
// is a bit wasteful (more padding) and requires iterating over all drives,
|
||||
// it is the only safe way: this may be called before we know which
|
||||
// drives will be needed, and hardlinks may confuse things.
|
||||
/**
|
||||
* return the largest sector size [bytes] of any storage medium
|
||||
* (HD, optical, etc.) in the system.
|
||||
*
|
||||
* this may be a bit slow to determine (iterates over all drives),
|
||||
* but caches the result so subsequent calls are free.
|
||||
* (caveat: device changes won't be noticed during this program run)
|
||||
*
|
||||
* sector size is relevant because Windows aio requires all IO
|
||||
* buffers, offsets and lengths to be a multiple of it. this requirement
|
||||
* is also carried over into the vfs / file.cpp interfaces for efficiency
|
||||
* (avoids the need for copying to/from align buffers).
|
||||
*
|
||||
* waio uses the sector size to (in some cases) align IOs if
|
||||
* they aren't already, but it's also needed by user code when
|
||||
* aligning their buffers to meet the requirements.
|
||||
*
|
||||
* the largest size is used so that we can read from any drive. while this
|
||||
* is a bit wasteful (more padding) and requires iterating over all drives,
|
||||
* it is the only safe way: this may be called before we know which
|
||||
* drives will be needed, and hardlinks may confuse things.
|
||||
**/
|
||||
extern size_t sys_max_sector_size();
|
||||
|
||||
/**
|
||||
* directory separation character
|
||||
**/
|
||||
#if OS_WIN
|
||||
# define SYS_DIR_SEP '\\'
|
||||
#else
|
||||
|
@ -78,7 +78,7 @@ LibError tex_validate(const Tex* t)
|
||||
// 24bpp color or 32bpp color+alpha (BGR / upside down are permitted).
|
||||
// basically, this is the "plain" format understood by all codecs and
|
||||
// tex_codec_plain_transform.
|
||||
LibError tex_validate_plain_format(size_t bpp, int flags)
|
||||
LibError tex_validate_plain_format(size_t bpp, size_t flags)
|
||||
{
|
||||
const bool alpha = (flags & TEX_ALPHA ) != 0;
|
||||
const bool grey = (flags & TEX_GREY ) != 0;
|
||||
@ -273,7 +273,7 @@ TIMER_ACCRUE(tc_plain_transform);
|
||||
|
||||
// extract texture info
|
||||
const size_t w = t->w, h = t->h, bpp = t->bpp;
|
||||
const int flags = t->flags;
|
||||
const size_t flags = t->flags;
|
||||
u8* const data = tex_get_data(t);
|
||||
const size_t data_size = tex_img_size(t);
|
||||
|
||||
@ -496,7 +496,7 @@ bool tex_is_known_extension(const char* filename)
|
||||
//
|
||||
// we need only add bookkeeping information and "wrap" it in
|
||||
// our Tex struct, hence the name.
|
||||
LibError tex_wrap(size_t w, size_t h, size_t bpp, int flags, const shared_ptr<u8>& data, size_t ofs, Tex* t)
|
||||
LibError tex_wrap(size_t w, size_t h, size_t bpp, size_t flags, const shared_ptr<u8>& data, size_t ofs, Tex* t)
|
||||
{
|
||||
t->w = w;
|
||||
t->h = h;
|
||||
|
@ -208,12 +208,12 @@ struct Tex
|
||||
**/
|
||||
size_t ofs;
|
||||
|
||||
size_t w : 16;
|
||||
size_t h : 16;
|
||||
size_t bpp : 16;
|
||||
size_t w;
|
||||
size_t h;
|
||||
size_t bpp;
|
||||
|
||||
/// see TexFlags and "Format Conversion" in docs.
|
||||
int flags : 16;
|
||||
size_t flags;
|
||||
};
|
||||
|
||||
|
||||
@ -291,7 +291,7 @@ extern LibError tex_encode(Tex* t, const std::string& extension, DynArray* da);
|
||||
* @param t output texture object.
|
||||
* @return LibError
|
||||
**/
|
||||
extern LibError tex_wrap(size_t w, size_t h, size_t bpp, int flags, const shared_ptr<u8>& data, size_t ofs, Tex* t);
|
||||
extern LibError tex_wrap(size_t w, size_t h, size_t bpp, size_t flags, const shared_ptr<u8>& data, size_t ofs, Tex* t);
|
||||
|
||||
/**
|
||||
* free all resources associated with the image and make further
|
||||
|
@ -91,7 +91,7 @@ static LibError bmp_decode(DynArray* RESTRICT da, Tex* RESTRICT t)
|
||||
|
||||
const long h = abs(h_);
|
||||
|
||||
int flags = 0;
|
||||
size_t flags = 0;
|
||||
flags |= (h_ < 0)? TEX_TOP_DOWN : TEX_BOTTOM_UP;
|
||||
if(bpp > 16)
|
||||
flags |= TEX_BGR;
|
||||
@ -117,7 +117,7 @@ static LibError bmp_encode(Tex* RESTRICT t, DynArray* RESTRICT da)
|
||||
const size_t file_size = hdr_size + img_size;
|
||||
const long h = (t->flags & TEX_TOP_DOWN)? -(long)t->h : (long)t->h;
|
||||
|
||||
int transforms = t->flags;
|
||||
size_t transforms = t->flags;
|
||||
transforms &= ~TEX_ORIENTATION; // no flip needed - we can set top-down bit.
|
||||
transforms ^= TEX_BGR; // BMP is native BGR.
|
||||
|
||||
@ -131,10 +131,10 @@ static LibError bmp_encode(Tex* RESTRICT t, DynArray* RESTRICT da)
|
||||
|
||||
// BITMAPINFOHEADER
|
||||
40, // biSize = sizeof(BITMAPINFOHEADER)
|
||||
t->w,
|
||||
(long)t->w,
|
||||
h,
|
||||
1, // biPlanes
|
||||
t->bpp,
|
||||
(u16)t->bpp,
|
||||
BI_RGB, // biCompression
|
||||
(u32)img_size, // biSizeImage
|
||||
0, 0, 0, 0 // unused (bi?PelsPerMeter, biClr*)
|
||||
|
@ -483,8 +483,7 @@ static LibError decode_pf(const DDPIXELFORMAT* pf, size_t& bpp, size_t& flags)
|
||||
// sd points to the DDS file's header; all fields must be endian-converted
|
||||
// before use.
|
||||
// output parameters invalid on failure.
|
||||
static LibError decode_sd(const DDSURFACEDESC2* sd, size_t* w_, size_t* h_,
|
||||
size_t* bpp_, size_t* flags_)
|
||||
static LibError decode_sd(const DDSURFACEDESC2* sd, size_t* w_, size_t* h_, size_t* bpp_, size_t* flags_)
|
||||
{
|
||||
// check header size
|
||||
if(read_le32(&sd->dwSize) != sizeof(*sd))
|
||||
@ -604,8 +603,8 @@ static LibError dds_decode(DynArray* RESTRICT da, Tex* RESTRICT t)
|
||||
u8* file = da->base;
|
||||
const DDSURFACEDESC2* sd = (const DDSURFACEDESC2*)(file+4);
|
||||
|
||||
size_t w, h;
|
||||
size_t bpp, flags;
|
||||
size_t w, h, bpp;
|
||||
size_t flags;
|
||||
RETURN_ERR(decode_sd(sd, &w, &h, &bpp, &flags));
|
||||
// note: cannot pass address of these directly to decode_sd because
|
||||
// they are bitfields.
|
||||
|
@ -23,7 +23,7 @@
|
||||
* @param flags TexFlags
|
||||
* @return LibError
|
||||
**/
|
||||
extern LibError tex_validate_plain_format(size_t bpp, int flags);
|
||||
extern LibError tex_validate_plain_format(size_t bpp, size_t flags);
|
||||
|
||||
|
||||
/**
|
||||
|
@ -436,7 +436,7 @@ static LibError jpg_decode_impl(DynArray* da, jpeg_decompress_struct* cinfo, Tex
|
||||
|
||||
// set libjpg output format. we cannot go with the default because
|
||||
// Photoshop writes non-standard CMYK files that must be converted to RGB.
|
||||
int flags = 0;
|
||||
size_t flags = 0;
|
||||
cinfo->out_color_space = JCS_RGB;
|
||||
if(cinfo->num_components == 1)
|
||||
{
|
||||
@ -528,7 +528,7 @@ static LibError jpg_encode_impl(Tex* t, jpeg_compress_struct* cinfo, DynArray* d
|
||||
// could use cinfo->output_scanline to keep track of progress,
|
||||
// but we need to count lines_left anyway (paranoia).
|
||||
JSAMPARRAY row = (JSAMPARRAY)rows.get();
|
||||
JDIMENSION lines_left = t->h;
|
||||
JDIMENSION lines_left = (JDIMENSION)t->h;
|
||||
while(lines_left != 0)
|
||||
{
|
||||
JDIMENSION lines_read = jpeg_write_scanlines(cinfo, row, lines_left);
|
||||
|
@ -82,7 +82,7 @@ static LibError png_decode_impl(DynArray* da, png_structp png_ptr, png_infop inf
|
||||
const size_t pitch = png_get_rowbytes(png_ptr, info_ptr);
|
||||
const u32 bpp = (u32)(pitch/w * 8);
|
||||
|
||||
int flags = 0;
|
||||
size_t flags = 0;
|
||||
if(bpp == 32)
|
||||
flags |= TEX_ALPHA;
|
||||
if(colour_type == PNG_COLOR_TYPE_GRAY)
|
||||
@ -121,7 +121,7 @@ static LibError png_decode_impl(DynArray* da, png_structp png_ptr, png_infop inf
|
||||
// "dtor / setjmp interaction" warning.
|
||||
static LibError png_encode_impl(Tex* t, png_structp png_ptr, png_infop info_ptr, DynArray* da)
|
||||
{
|
||||
const png_uint_32 w = t->w, h = t->h;
|
||||
const png_uint_32 w = (png_uint_32)t->w, h = (png_uint_32)t->h;
|
||||
const size_t pitch = w * t->bpp / 8;
|
||||
|
||||
int colour_type;
|
||||
|
@ -107,7 +107,7 @@ static LibError tga_decode(DynArray* RESTRICT da, Tex* RESTRICT t)
|
||||
const size_t bpp = hdr->bpp;
|
||||
const u8 desc = hdr->img_desc;
|
||||
|
||||
int flags = 0;
|
||||
size_t flags = 0;
|
||||
flags |= (desc & TGA_TOP_DOWN)? TEX_TOP_DOWN : TEX_BOTTOM_UP;
|
||||
if(desc & 0x0F) // alpha bits
|
||||
flags |= TEX_ALPHA;
|
||||
@ -139,7 +139,7 @@ static LibError tga_encode(Tex* RESTRICT t, DynArray* RESTRICT da)
|
||||
img_desc |= 8; // size of alpha channel
|
||||
TgaImgType img_type = (t->flags & TEX_GREY)? TGA_GREY : TGA_TRUE_COLOUR;
|
||||
|
||||
int transforms = t->flags;
|
||||
size_t transforms = t->flags;
|
||||
transforms &= ~TEX_ORIENTATION; // no flip needed - we can set top-down bit.
|
||||
transforms ^= TEX_BGR; // TGA is native BGR.
|
||||
|
||||
@ -150,9 +150,9 @@ static LibError tga_encode(Tex* RESTRICT t, DynArray* RESTRICT da)
|
||||
(u8)img_type,
|
||||
{0,0,0,0,0}, // unused (colour map)
|
||||
0, 0, // unused (origin)
|
||||
t->w,
|
||||
t->h,
|
||||
t->bpp,
|
||||
(u16)t->w,
|
||||
(u16)t->h,
|
||||
(u8)t->bpp,
|
||||
img_desc
|
||||
};
|
||||
const size_t hdr_size = sizeof(hdr);
|
||||
|
Loading…
Reference in New Issue
Block a user