diff --git a/source/lib/adts.cpp b/source/lib/adts.cpp index 335206b198..02c62c1b05 100755 --- a/source/lib/adts.cpp +++ b/source/lib/adts.cpp @@ -16,7 +16,7 @@ namespace test { static void test_ringbuf() { const size_t N = 49; // RingBuf capacity - const size_t S = 100; // number of test items + const int S = 100; // number of test items // insert and remove immediately { diff --git a/source/lib/adts.h b/source/lib/adts.h index 37327a6856..9db6e60b29 100755 --- a/source/lib/adts.h +++ b/source/lib/adts.h @@ -8,7 +8,7 @@ #include #include - +#include template class DHT_Traits @@ -41,7 +41,8 @@ public: // intended for pointer types -template > class DynHashTbl +template > +class DynHashTbl { T* tbl; u16 num_entries; diff --git a/source/lib/res/file/vfs_optimizer.cpp b/source/lib/res/file/vfs_optimizer.cpp index f3eb10006b..698eb79411 100644 --- a/source/lib/res/file/vfs_optimizer.cpp +++ b/source/lib/res/file/vfs_optimizer.cpp @@ -1,10 +1,13 @@ #include "precompiled.h" +#include +#include + #include "lib/allocators.h" #include "lib/timer.h" #include "file_internal.h" -# include "ps/VFSUtil.h" +#include "ps/VFSUtil.h" static uintptr_t trace_initialized; // set via CAS static Pool trace_pool; @@ -546,18 +549,21 @@ public: Trace t; THROW_ERR(trace_read_from_file(trace_filename, &t)); - // reserve memory for worst-case amount of connections (happens if - // all accesses are unique). this is necessary because we store - // pointers to Connection in the map, which would be invalidated if - // connections[] ever expands. - // may waste up to ~3x the memory (about 1mb) for a short time, - // which is ok. - connections.reserve(t.num_ents-1); + if (t.num_ents) + { + // reserve memory for worst-case amount of connections (happens if + // all accesses are unique). this is necessary because we store + // pointers to Connection in the map, which would be invalidated if + // connections[] ever expands. + // may waste up to ~3x the memory (about 1mb) for a short time, + // which is ok. + connections.reserve(t.num_ents-1); - Runs runs; - split_trace_into_runs(&t, runs); + Runs runs; + split_trace_into_runs(&t, runs); - add_connections_from_runs(runs, connections); + add_connections_from_runs(runs, connections); + } } }; @@ -706,6 +712,8 @@ archive.insert(atom_fn); static bool should_rebuild_main_archive(const char* P_archive_path, const char* trace_filename) { + UNUSED2(P_archive_path); + // if there's no trace file, no point in building a main archive. struct stat s; if(file_stat(trace_filename, &s) != ERR_OK) @@ -860,4 +868,5 @@ int vfs_opt_auto_build(const char* P_dst_path, } UNREACHABLE; + return ERR_OK; // To quelch gcc "control reaches end of non-void function" } diff --git a/source/lib/res/graphics/cursor.cpp b/source/lib/res/graphics/cursor.cpp index bf85d6faac..50e758387d 100755 --- a/source/lib/res/graphics/cursor.cpp +++ b/source/lib/res/graphics/cursor.cpp @@ -18,10 +18,34 @@ #include "ogl_tex.h" #include "cursor.h" +/* + This is used to create the sys cursor to use together with the OpenGL + cursor. I.e. to set a transparent cursor on X-windows where we don't use + the X11 cursor, and on windows should the hardware cursor setup fail. + + Shouldn't be called when both hardware/software cursor fails (i.e. invalid + cursor file given) - in that case we'd rather use the default cursor. +*/ +static void *load_empty_sys_cursor() +{ + void *sys_cursor = 0; + + if(sys_cursor_create_empty(&sys_cursor) < 0) + { + debug_warn("sys_cursor_create_empty failed"); + return NULL; + } + + return sys_cursor; +} static void* load_sys_cursor(const char* filename, int hx, int hy) { #if !ALLOW_SYS_CURSOR + UNUSED2(filename); + UNUSED2(hx); + UNUSED2(hy); + return 0; #else Tex t; @@ -123,6 +147,8 @@ struct Cursor // valid iff sys_cursor == 0. GLCursor gl_cursor; + // a system cursor to use together with the gl_cursor + void *gl_sys_cursor; }; H_TYPE_DEFINE(Cursor); @@ -163,7 +189,14 @@ static LibError Cursor_reload(Cursor* c, const char* name, Handle) c->sys_cursor = load_sys_cursor(filename, hotspotx, hotspoty); // .. fall back to GLCursor (system cursor code is disabled or failed) if(!c->sys_cursor) - RETURN_ERR(c->gl_cursor.create(filename, hotspotx, hotspoty)); + { + LibError err=c->gl_cursor.create(filename, hotspotx, hotspoty); + + if (err == ERR_OK) + c->gl_sys_cursor = load_empty_sys_cursor(); + + return err; + } return ERR_OK; } @@ -223,7 +256,14 @@ LibError cursor_draw(const char* name, int x, int y) if(c->sys_cursor) WARN_ERR(sys_cursor_set(c->sys_cursor)); else + { c->gl_cursor.draw(x, y); + // Here, gl_sys_cursor is either a pointer to a valid cursor or NULL. + // It is NULL if the gl_cursor init failed or if load_empty_sys_cursor + // failed - in the first case, we want to use the default system cursor, + // in the second case setting the default cursor yields no change. + WARN_ERR(sys_cursor_set(c->gl_sys_cursor)); + } (void)cursor_free(hc); return ERR_OK; diff --git a/source/lib/res/sound/snd.cpp b/source/lib/res/sound/snd.cpp index 9c3abbe80c..7b23956579 100755 --- a/source/lib/res/sound/snd.cpp +++ b/source/lib/res/sound/snd.cpp @@ -1214,6 +1214,24 @@ static FadeRet fade(FadeInfo& fi, double cur_time, float& out_val) if(fi.type == FT_NONE) return FADE_NO_CHANGE; + // end reached - if fi.length is 0, but the fade is "in progress", do the + // processing here, and skip the dangerous division + if(fi.type == FT_ABORT || (cur_time >= fi.start_time + fi.length)) + { + // make sure exact value is hit + out_val = fi.final_val; + + // special case: we were fading out; caller will free the sound. + if(fi.final_val == 0.0f) + return FADE_TO_0_FINISHED; + + // wipe out all values amd mark as no longer actively fading + memset(&fi, 0, sizeof(fi)); + fi.type = FT_NONE; + + return FADE_CHANGED; + } + // how far into the fade are we? [0,1] const float t = (cur_time - fi.start_time) / fi.length; @@ -1242,21 +1260,6 @@ static FadeRet fade(FadeInfo& fi, double cur_time, float& out_val) out_val = fi.initial_val + factor*(fi.final_val - fi.initial_val); - // end reached - if(fi.type == FT_ABORT || (cur_time >= fi.start_time + fi.length)) - { - // make sure exact value is hit - out_val = fi.final_val; - - // special case: we were fading out; caller will free the sound. - if(fi.final_val == 0.0f) - return FADE_TO_0_FINISHED; - - // wipe out all values amd mark as no longer actively fading - memset(&fi, 0, sizeof(fi)); - fi.type = FT_NONE; - } - return FADE_CHANGED; } diff --git a/source/lib/sysdep/sysdep.h b/source/lib/sysdep/sysdep.h index f4d0054e42..d3358bd400 100755 --- a/source/lib/sysdep/sysdep.h +++ b/source/lib/sysdep/sysdep.h @@ -177,6 +177,10 @@ extern LibError sys_clipboard_free(wchar_t* copy); extern LibError sys_cursor_create(uint w, uint h, void* bgra_img, uint hx, uint hy, void** cursor); +// create a fully transparent cursor (i.e. one that when passed to set hides +// the system cursor) +extern LibError sys_cursor_create_empty(void **cursor); + // replaces the current system cursor with the one indicated. need only be // called once per cursor; pass 0 to restore the default. extern LibError sys_cursor_set(void* cursor); diff --git a/source/lib/sysdep/unix/unix.cpp b/source/lib/sysdep/unix/unix.cpp index 22d261c7df..34827a684a 100644 --- a/source/lib/sysdep/unix/unix.cpp +++ b/source/lib/sysdep/unix/unix.cpp @@ -4,6 +4,7 @@ #include #include +#include "sdl.h" #include "lib.h" #include "sysdep/sysdep.h" #include "udbg.h" @@ -113,14 +114,23 @@ ErrorReaction sys_display_error(const wchar_t* text, int flags) } -// mouse cursor stubs (required by lib/res/cursor.cpp) +LibError sys_error_description_r(int err, char* buf, size_t max_chars) +{ + UNUSED2(err); + UNUSED2(buf); + UNUSED2(max_chars); + + // don't need to do anything: lib/errors.cpp already queries + // libc's strerror(). if we ever end up needing translation of + // e.g. Qt or X errors, that'd go here. + return ERR_FAIL; +} + +// stub for sys_cursor_create - we don't need to implement this (SDL/X11 only +// has monochrome cursors so we need to use the software cursor anyways) + // note: do not return ERR_NOT_IMPLEMENTED or similar because that // would result in WARN_ERRs. -// -// TODO: implementing these would be nice because then the game can -// take advantage of hardware mouse cursors instead of the (jerky when -// loading) OpenGL cursor. - LibError sys_cursor_create(uint w, uint h, void* bgra_img, uint hx, uint hy, void** cursor) { @@ -134,28 +144,53 @@ LibError sys_cursor_create(uint w, uint h, void* bgra_img, return ERR_OK; } +// creates an empty cursor +LibError sys_cursor_create_empty(void **cursor) +{ + /* bitmap for a fully transparent cursor */ + u8 data[] = {0}; + u8 mask[] = {0}; + + // size 8x1 (cursor size must be a whole number of bytes ^^) + // hotspot at 0,0 + // SDL will make its own copies of data and mask + *cursor=SDL_CreateCursor(data, mask, 8, 1, 0, 0); + + return cursor?ERR_OK:ERR_FAIL; +} + +SDL_Cursor *defaultCursor=NULL; +// replaces the current system cursor with the one indicated. need only be +// called once per cursor; pass 0 to restore the default. LibError sys_cursor_set(void* cursor) { - UNUSED2(cursor); - + // Gaah, SDL doesn't have a good API for setting the default cursor + // SetCursor(NULL) just /repaints/ the cursor (well, obviously! or...) + ONCE(defaultCursor = SDL_GetCursor()); + + // restore default cursor. + if(!cursor) + SDL_SetCursor(defaultCursor); + + SDL_SetCursor((SDL_Cursor *)cursor); + return ERR_OK; } +// destroys the indicated cursor and frees its resources. if it is +// currently the system cursor, the default cursor is restored first. LibError sys_cursor_free(void* cursor) { - UNUSED2(cursor); - + // bail now to prevent potential confusion below; there's nothing to do. + if(!cursor) + return ERR_OK; + + // if the cursor being freed is active, restore the default cursor + // (just for safety). + if (SDL_GetCursor() == (SDL_Cursor *)cursor) + WARN_ERR(sys_cursor_set(NULL)); + + SDL_FreeCursor((SDL_Cursor *)cursor); + return ERR_OK; } - -LibError sys_error_description_r(int err, char* buf, size_t max_chars) -{ - UNUSED2(err); - UNUSED2(buf); - UNUSED2(max_chars); - - // don't need to do anything: lib/errors.cpp already queries - // libc's strerror(). if we ever end up needing translation of - // e.g. Qt or X errors, that'd go here. - return ERR_FAIL; -} diff --git a/source/lib/sysdep/win/wsysdep.cpp b/source/lib/sysdep/win/wsysdep.cpp index 5664ab9843..2809b31276 100644 --- a/source/lib/sysdep/win/wsysdep.cpp +++ b/source/lib/sysdep/win/wsysdep.cpp @@ -500,7 +500,12 @@ LibError sys_cursor_create(uint w, uint h, void* bgra_img, return ERR_OK; } - +LibError sys_cursor_create_empty(void **cursor) +{ + // TODO: High alpha value = opaque, low = transparent? + u8 bgra_img = {0, 0, 0, 0}; + return sys_cursor_create(1, 1, bgra_img, 0, 0, cursor); +} // replaces the current system cursor with the one indicated. need only be // called once per cursor; pass 0 to restore the default. @@ -678,4 +683,4 @@ LibError sys_on_each_cpu(void (*cb)()) SetProcessAffinityMask(hProcess, process_affinity); return ERR_OK; -} \ No newline at end of file +}