From f383cfd4a8295b2d3a723dc82a2f4f66776fe209 Mon Sep 17 00:00:00 2001 From: janwas Date: Sat, 8 May 2004 01:11:51 +0000 Subject: [PATCH] fix for vc7 (incomplete type in container). also some updates to vfs This was SVN commit r221. --- source/lib/adts.cpp | 3 +- source/lib/adts.h | 11 +- source/lib/detect.cpp | 7 +- source/lib/detect.h | 2 +- source/lib/input.cpp | 3 +- source/lib/lib.cpp | 11 +- source/lib/lib.h | 3 + source/lib/memcpy.cpp | 2 + source/lib/misc.cpp | 6 +- source/lib/ogl.cpp | 4 +- source/lib/res/file.cpp | 34 +-- source/lib/res/file.h | 6 +- source/lib/res/font.cpp | 5 +- source/lib/res/h_mgr.cpp | 18 +- source/lib/res/h_mgr.h | 2 +- source/lib/res/mem.cpp | 13 +- source/lib/res/res.cpp | 1 + source/lib/res/tex.cpp | 55 ++-- source/lib/res/vfs.cpp | 453 ++++++++++++------------------ source/lib/res/vfs.h | 6 +- source/lib/res/zip.cpp | 28 +- source/lib/res/zip.h | 2 +- source/lib/sysdep/ia32.cpp | 11 +- source/lib/sysdep/sysdep.cpp | 4 +- source/lib/sysdep/win/hrt.cpp | 12 +- source/lib/sysdep/win/waio.cpp | 26 +- source/lib/sysdep/win/wdetect.cpp | 127 +-------- source/lib/sysdep/win/win.cpp | 12 +- source/lib/sysdep/win/wposix.cpp | 37 +-- source/lib/sysdep/win/wsdl.cpp | 111 +++----- source/lib/sysdep/x.cpp | 4 +- source/lib/timer.cpp | 2 +- 32 files changed, 395 insertions(+), 626 deletions(-) diff --git a/source/lib/adts.cpp b/source/lib/adts.cpp index ae1c5a627c..f5a761bf2b 100755 --- a/source/lib/adts.cpp +++ b/source/lib/adts.cpp @@ -1,6 +1,7 @@ +#include "precompiled.h" + #include "adts.h" -#include template class DynArray { diff --git a/source/lib/adts.h b/source/lib/adts.h index 6cf0d45867..b8e3325ec8 100755 --- a/source/lib/adts.h +++ b/source/lib/adts.h @@ -1,11 +1,10 @@ #ifndef ADTS_H__ #define ADTS_H__ +#include "precompiled.h" #include "lib.h" -#include -#include #include @@ -135,7 +134,7 @@ public: { if(find_line(id)) { - assert(0 && "assign: id already in cache!"); + debug_warn("assign: id already in cache!"); return 0; } @@ -150,7 +149,7 @@ public: // all are locked and cannot be displaced. // caller should grow() enough lines so that this never happens. - assert(0 && "assign: all lines locked - grow() more lines"); + debug_warn("assign: all lines locked - grow() more lines"); return 0; have_line: @@ -170,7 +169,7 @@ public: // invalid: id 0 denotes not-yet-associated lines if(id == 0) { - assert(0 && "retrieve: id 0 not allowed"); + debug_warn("retrieve: id 0 not allowed"); return 0; } Line* l = find_line(id); @@ -264,7 +263,7 @@ public: if(!res.second) { - assert(0 && "add: already in container"); + debug_warn("add: already in container"); return 0; } diff --git a/source/lib/detect.cpp b/source/lib/detect.cpp index 219b0f7e2f..4fd78be7ff 100755 --- a/source/lib/detect.cpp +++ b/source/lib/detect.cpp @@ -20,16 +20,15 @@ // large platform-specific routines (e.g. CPU or gfx card info) // are split out of here. -#include -#include -#include +#include "precompiled.h" #include "lib.h" #include "detect.h" +#include "timer.h" #ifdef _M_IX86 # include "sysdep/ia32.h" #endif -#include "timer.h" + extern int win_get_gfx_card(); extern int win_get_gfx_drv(); diff --git a/source/lib/detect.h b/source/lib/detect.h index 8e736fd363..9f6df37afd 100755 --- a/source/lib/detect.h +++ b/source/lib/detect.h @@ -32,7 +32,7 @@ extern int get_cur_resolution(int& xres, int& yres); // useful for determining aspect ratio. not called by detect(). // if we fail, outputs are unchanged (assumed initialized to defaults) -extern int get_monitor_size(int& width_cm, int& height_cm); +extern int get_monitor_size(int& width_mm, int& height_mm); diff --git a/source/lib/input.cpp b/source/lib/input.cpp index 0e66d24fca..138f39856a 100755 --- a/source/lib/input.cpp +++ b/source/lib/input.cpp @@ -18,8 +18,7 @@ * http://www.stud.uni-karlsruhe.de/~urkt/ */ -#include -#include +#include "precompiled.h" #include "input.h" diff --git a/source/lib/lib.cpp b/source/lib/lib.cpp index 50ee7518d4..609ed40eac 100755 --- a/source/lib/lib.cpp +++ b/source/lib/lib.cpp @@ -14,12 +14,11 @@ // Jan.Wassenberg@stud.uni-karlsruhe.de // http://www.stud.uni-karlsruhe.de/~urkt/ +#include "precompiled.h" + #include "types.h" #include "lib.h" -#include -#include - // more powerful atexit, with 0 or 1 parameters. // callable before libc initialized, frees up the real atexit table, @@ -37,7 +36,7 @@ // - call atexit (our exit handler would be called before its handler, // so we may have shut down something important already). -const int MAX_EXIT_FUNCS = 8; +const int MAX_EXIT_FUNCS = 32; static struct ExitFunc @@ -74,7 +73,7 @@ static void call_exit_funcs(void) break; #endif default: - assert(0 && "call_exit_funcs: invalid calling convention in ExitFunc!"); + debug_warn("call_exit_funcs: invalid calling convention in ExitFunc!"); } p++; } @@ -86,7 +85,7 @@ int atexit2(void* func, uintptr_t arg, CallConvention cc) { if(num_exit_funcs >= MAX_EXIT_FUNCS) { - assert("atexit2: too many functions registered. increase MAX_EXIT_FUNCS"); + debug_warn("atexit2: too many functions registered. increase MAX_EXIT_FUNCS"); return -1; } ExitFunc* p = &exit_funcs[num_exit_funcs++]; diff --git a/source/lib/lib.h b/source/lib/lib.h index a958778c50..051258767b 100755 --- a/source/lib/lib.h +++ b/source/lib/lib.h @@ -108,6 +108,9 @@ enum LibError +#define debug_warn(str) assert(0 && (str)) + + // converts 4 character string to u32 for easy comparison diff --git a/source/lib/memcpy.cpp b/source/lib/memcpy.cpp index 3d095f4370..1a3059b1dc 100755 --- a/source/lib/memcpy.cpp +++ b/source/lib/memcpy.cpp @@ -4,6 +4,8 @@ * src and len must be multiples of CHUNK_SIZE. */ +#include "precompiled.h" + #if _MSC_VER >= 0x1300 void memcpy_nt(void* dst, void* src, int len) diff --git a/source/lib/misc.cpp b/source/lib/misc.cpp index 71b845dc52..5a55a97013 100755 --- a/source/lib/misc.cpp +++ b/source/lib/misc.cpp @@ -16,11 +16,7 @@ // Jan.Wassenberg@stud.uni-karlsruhe.de // http://www.stud.uni-karlsruhe.de/~urkt/ - -#include -#include -#include -#include +#include "precompiled.h" #include "lib.h" #include "misc.h" diff --git a/source/lib/ogl.cpp b/source/lib/ogl.cpp index 5a0409c604..c4e8b5b962 100755 --- a/source/lib/ogl.cpp +++ b/source/lib/ogl.cpp @@ -1,6 +1,4 @@ -#include -#include -#include +#include "precompiled.h" #include "sdl.h" #include "ogl.h" diff --git a/source/lib/res/file.cpp b/source/lib/res/file.cpp index aa1d5f3b22..976c430ff4 100755 --- a/source/lib/res/file.cpp +++ b/source/lib/res/file.cpp @@ -17,6 +17,8 @@ // Jan.Wassenberg@stud.uni-karlsruhe.de // http://www.stud.uni-karlsruhe.de/~urkt/ +#include "precompiled.h" + #include "lib.h" #include "file.h" #include "h_mgr.h" @@ -24,12 +26,6 @@ #include "detect.h" #include "adts.h" -#include - -#include -#include -#include - // block := power-of-two sized chunk of a file. // all transfers are expanded to naturally aligned, whole blocks @@ -110,7 +106,7 @@ int file_set_root_dir(const char* argv0, const char* root_dir) static bool already_attempted; if(already_attempted) { - assert(0 && "vfs_set_root called more than once"); + debug_warn("vfs_set_root called more than once"); return -1; } already_attempted = true; @@ -166,7 +162,7 @@ typedef DirEnts::iterator DirEntsIt; static bool dirent_less(DirEnt& d1, DirEnt& d2) { return d1.name.compare(d2.name) < 0; } -int file_enum_dirents(const char* dir, DirEntCB cb, uintptr_t user) +int file_enum(const char* dir, FileCB cb, uintptr_t user) { char n_path[PATH_MAX+1]; n_path[PATH_MAX] = '\0'; @@ -321,7 +317,7 @@ static int file_validate(const uint line, File* const f) // failed somewhere - err is the error code, // or -1 if not set specifically above. debug_out("file_validate at line %d failed: %s\n", line, msg); - assert(0 && "file_validate failed"); + debug_warn("file_validate failed"); return err; } @@ -336,7 +332,7 @@ do\ while(0); -int file_open(const char* p_fn, int flags, File* f) +int file_open(const char* p_fn, uint flags, File* f) { memset(f, 0, sizeof(File)); @@ -422,12 +418,12 @@ int ll_start_io(File* f, size_t ofs, size_t size, void* p, ll_cb* lcb) if(size == 0) { - assert(0 && "ll_start_io: size = 0 - why?"); + debug_warn("ll_start_io: size = 0 - why?"); return ERR_INVALID_PARAM; } if(ofs >= f->size) { - assert(0 && "ll_start_io: ofs beyond f->size"); + debug_warn("ll_start_io: ofs beyond f->size"); return -1; } @@ -537,7 +533,7 @@ static void* block_alloc(const u64 id) for(size_t i = 0; i < num_blocks; i++) { if(c.grow(p) < 0) - assert(0 && "block_alloc: Cache::grow failed!"); + debug_warn("block_alloc: Cache::grow failed!"); // currently can't fail. p = (char*)p + BLOCK_SIZE; } @@ -551,7 +547,7 @@ static void* block_alloc(const u64 id) void* block = *entry; if(c.lock(id, true) < 0) - assert(0 && "block_alloc: Cache::lock failed!"); + debug_warn("block_alloc: Cache::lock failed!"); // can't happen: only cause is tag not found, but we successfully // added it above. if it did fail, that'd be bad: we leak the block, // and/or the buffer may be displaced while in use. hence, assert. @@ -747,7 +743,7 @@ static int io_free(Handle hio) if(io->pending) { - assert(0 && "io_free: IO pending"); + debug_warn("io_free: IO pending"); return -1; } @@ -783,7 +779,7 @@ struct FindBlock : public std::binary_function IO* io = (IO*)h_user_data(hio, H_IO); if(!io) { - assert(0 && "invalid handle in all_ios list!"); + debug_warn("invalid handle in all_ios list!"); return false; } return io->block_id == block_id; @@ -823,12 +819,12 @@ Handle file_start_io(File* f, size_t user_ofs, size_t user_size, void* user_p) if(user_size == 0) { - assert(0 && "file_start_io: user_size = 0 - why?"); + debug_warn("file_start_io: user_size = 0 - why?"); return ERR_INVALID_PARAM; } if(user_ofs >= f->size) { - assert(0 && "file_start_io: user_ofs beyond f->size"); + debug_warn("file_start_io: user_ofs beyond f->size"); return -1; } @@ -1026,7 +1022,7 @@ debug_out("file_io fd=%d size=%d ofs=%d\n", f->fd, raw_size, raw_ofs); // temp buffer OR supposed to be allocated here: invalid if(!p || !*p) { - assert(0 && "file_io: write to file from 0 buffer"); + debug_warn("file_io: write to file from 0 buffer"); return ERR_INVALID_PARAM; } } diff --git a/source/lib/res/file.h b/source/lib/res/file.h index d55bde0045..16d1e4336f 100755 --- a/source/lib/res/file.h +++ b/source/lib/res/file.h @@ -66,13 +66,13 @@ enum FILE_CB_FLAGS extern int file_set_root_dir(const char* argv0, const char* root); -typedef int(*DirEntCB)(const char* name, uint flags, ssize_t size, uintptr_t user); +typedef int(*FileCB)(const char* name, uint flags, ssize_t size, uintptr_t user); -extern int file_enum_dirents(const char* dir, DirEntCB cb, uintptr_t user); +extern int file_enum(const char* dir, FileCB cb, uintptr_t user); extern int file_stat(const char* path, struct stat*); -extern int file_open(const char* fn, int flags, File* f); +extern int file_open(const char* fn, uint flags, File* f); extern int file_close(File* f); extern int file_map(File* f, void*& p, size_t& size); diff --git a/source/lib/res/font.cpp b/source/lib/res/font.cpp index 758bd42693..05f4027572 100755 --- a/source/lib/res/font.cpp +++ b/source/lib/res/font.cpp @@ -18,10 +18,7 @@ * http://www.stud.uni-karlsruhe.de/~urkt/ */ -#include -#include -#include -#include +#include "precompiled.h" #include "lib.h" #include "mem.h" diff --git a/source/lib/res/h_mgr.cpp b/source/lib/res/h_mgr.cpp index 5ec58b1fca..986453502d 100755 --- a/source/lib/res/h_mgr.cpp +++ b/source/lib/res/h_mgr.cpp @@ -16,11 +16,7 @@ // Jan.Wassenberg@stud.uni-karlsruhe.de // http://www.stud.uni-karlsruhe.de/~urkt/ -#include -#include -#include -#include -#include +#include "precompiled.h" #include "lib.h" #include "misc.h" @@ -377,17 +373,17 @@ Handle h_alloc(H_Type type, const char* fn, uint flags, ...) // verify type if(!type) { - assert(0 && "h_alloc: type param is 0"); + debug_warn("h_alloc: type param is 0"); return 0; } if(type->user_size > HDATA_USER_SIZE) { - assert(0 && "h_alloc: type's user data is too large for HDATA"); + debug_warn("h_alloc: type's user data is too large for HDATA"); return 0; } if(type->name == 0) { - assert(0 && "h_alloc: type's name field is 0"); + debug_warn("h_alloc: type's name field is 0"); return 0; } @@ -414,7 +410,7 @@ Handle h_alloc(H_Type type, const char* fn, uint flags, ...) hd = h_data(h, type); if(hd->refs == REF_MAX) { - assert(0 && "h_alloc: too many references to a handle - increase REF_BITS"); + debug_warn("h_alloc: too many references to a handle - increase REF_BITS"); return 0; } hd->refs++; @@ -431,7 +427,7 @@ Handle h_alloc(H_Type type, const char* fn, uint flags, ...) static u32 tag; if(++tag >= TAG_MASK) { - assert(0 && "h_alloc: tag overflow - allocations are no longer unique."\ + debug_warn("h_alloc: tag overflow - allocations are no longer unique."\ "may not notice stale handle reuse. increase TAG_BITS."); tag = 1; } @@ -485,7 +481,7 @@ int h_reload(const char* fn) { if(!fn) { - assert(0 && "h_reload: fn = 0"); + debug_warn("h_reload: fn = 0"); return ERR_INVALID_PARAM; } diff --git a/source/lib/res/h_mgr.h b/source/lib/res/h_mgr.h index ba67c000ad..d441556e11 100755 --- a/source/lib/res/h_mgr.h +++ b/source/lib/res/h_mgr.h @@ -248,7 +248,7 @@ guide to defining and using resources struct Res1 { void* data1; // data loaded from file - int flags; // set when resource is created + uint flags; // set when resource is created }; 3) build its vtbl: diff --git a/source/lib/res/mem.cpp b/source/lib/res/mem.cpp index f03660f9ef..ac0298735c 100755 --- a/source/lib/res/mem.cpp +++ b/source/lib/res/mem.cpp @@ -1,7 +1,6 @@ // malloc layer for less fragmentation, alignment, and automatic release -#include -#include +#include "precompiled.h" #include "lib.h" #include "types.h" @@ -71,7 +70,7 @@ static void* pool_alloc(const size_t size, const uint align, uintptr_t& ctx, MEM if(ofs+size > POOL_CAP) { - assert(0 && "pool_alloc: not enough memory in pool"); + debug_warn("pool_alloc: not enough memory in pool"); return 0; } @@ -102,7 +101,7 @@ static PtrToH& get_ptr_to_h() if(!_ptr_to_h) { if(has_shutdown) - assert("mem.cpp: ptr -> handle lookup used after module shutdown"); + debug_warn("mem.cpp: ptr -> handle lookup used after module shutdown"); // crash + burn _ptr_to_h = new PtrToH; @@ -131,7 +130,7 @@ static Handle remove_alloc(void* p) PtrToH::iterator it = ptr_to_h.find(p); if(it == ptr_to_h.end()) { - assert("remove_alloc: pointer not in map"); + debug_warn("remove_alloc: pointer not in map"); return 0; } @@ -213,7 +212,7 @@ Handle mem_assign(void* p, size_t size, uint flags /* = 0 */, MEM_DTOR dtor /* = if(!p || !size) { - assert(0 && "mem_assign: invalid p or size"); + debug_warn("mem_assign: invalid p or size"); return 0; } @@ -240,7 +239,7 @@ void* mem_alloc(size_t size, const uint align, uint flags, Handle* phm) if(size == 0) { - assert(0 && "mem_alloc: why is size = 0?"); + debug_warn("mem_alloc: why is size = 0?"); size = 1; } diff --git a/source/lib/res/res.cpp b/source/lib/res/res.cpp index e69de29bb2..5f656a45da 100755 --- a/source/lib/res/res.cpp +++ b/source/lib/res/res.cpp @@ -0,0 +1 @@ +#include "precompiled.h" diff --git a/source/lib/res/tex.cpp b/source/lib/res/tex.cpp index 717bc8e866..2b7b43efda 100755 --- a/source/lib/res/tex.cpp +++ b/source/lib/res/tex.cpp @@ -18,11 +18,7 @@ // supported formats: DDS, TGA, PNG, JP2, BMP, RAW - -#include -#include -#include -#include +#include "precompiled.h" #include "lib.h" #include "vfs.h" @@ -491,7 +487,8 @@ static inline bool png_valid(const u8* ptr, size_t size) // requirement: direct color static int png_load(const char* fn, const u8* ptr, size_t size, Tex* t) { - const char* err = 0; + const char* msg = 0; + int err = -1; // allocate PNG structures png_structp png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, 0, 0, 0); @@ -500,19 +497,22 @@ static int png_load(const char* fn, const u8* ptr, size_t size, Tex* t) png_infop info_ptr = png_create_info_struct(png_ptr); if(!info_ptr) { - png_destroy_read_struct(&png_ptr, 0, 0); - return ERR_NO_MEM; + err = ERR_NO_MEM; + goto fail; } // setup error handling if(setjmp(png_jmpbuf(png_ptr))) { fail: - debug_out("png_load: %s: %s\n", fn, err? err : ""); - png_destroy_read_struct(&png_ptr, &info_ptr, 0); - return -1; + debug_out("png_load: %s: %s\n", fn, msg? msg : "unknown"); + goto ret; } + u8** rows; + + { + MemRange mr = { ptr, size }; png_set_read_fn(png_ptr, &mr, png_read_fn); @@ -529,15 +529,17 @@ fail: const u32 ofs = 0; // libpng returns decoded image data; no header if(prec != 8) - err = "channel precision != 8 bits"; + msg = "channel precision != 8 bits"; if(fmt == ~0) - err = "color type is invalid (must be direct color)"; - if(err) + msg = "color type is invalid (must be direct color)"; + if(msg) + { + err = -1; goto fail; + } // allocate mem for image - rows point into buffer (sequential) - // .. (rows is freed in png_destroy_read_struct) - u8** rows = (u8**)png_malloc(png_ptr, (h+1)*sizeof(void*)); + rows = (u8**)malloc((h+1)*sizeof(void*)); if(!rows) goto fail; size_t img_size = pitch * (h+1); @@ -554,8 +556,8 @@ fail: png_read_image(png_ptr, rows); - png_read_end(png_ptr, 0); - png_destroy_read_struct(&png_ptr, &info_ptr, 0); + png_read_end(png_ptr, info_ptr); + mem_free_h(t->hm); @@ -564,9 +566,18 @@ fail: t->fmt = fmt; t->bpp = bpp; t->ofs = ofs; - t->hm = img_hm; + t->hm = img_hm; - return 0; + err = 0; + + } + + // shared cleanup +ret: + free(rows); + png_destroy_read_struct(&png_ptr, &info_ptr, 0); + + return err; } #endif @@ -765,7 +776,7 @@ int tex_bind(const Handle h) #ifndef NDEBUG if(!t->id) { - assert(0 && "tex_bind: Tex.id is not a valid texture"); + debug_warn("tex_bind: Tex.id is not a valid texture"); return -1; } #endif @@ -842,7 +853,7 @@ int tex_upload(const Handle ht, int filter, int int_fmt) assert(0); } debug_out("tex_upload: %s: %s\n", fn, err); - assert(0 && "tex_upload failed"); + debug_warn("tex_upload failed"); return -1; } diff --git a/source/lib/res/vfs.cpp b/source/lib/res/vfs.cpp index 9ddc3742b2..b43cd6ea6a 100755 --- a/source/lib/res/vfs.cpp +++ b/source/lib/res/vfs.cpp @@ -17,10 +17,7 @@ // Jan.Wassenberg@stud.uni-karlsruhe.de // http://www.stud.uni-karlsruhe.de/~urkt/ -#include -#include -#include -#include +#include "precompiled.h" #include "lib.h" #include "file.h" @@ -30,12 +27,6 @@ #include "mem.h" #include "adts.h" -#include -#include -#include -#include -#include -#include // currently not thread safe, but that will most likely change // (if prefetch thread is to be used). @@ -160,7 +151,7 @@ static int path_validate(const uint line, const char* const path) // or -1 if not set specifically above. fail: debug_out("path_validate at line %d failed: %s", err); - assert(0 && "path_validate failed"); + debug_warn("path_validate failed"); return err; ok: @@ -173,97 +164,49 @@ ok: /////////////////////////////////////////////////////////////////////////////// // -// file location +// "file system" (tree structure; stores location of each file) // /////////////////////////////////////////////////////////////////////////////// + // the VFS stores the location (archive or directory) of each file; // this allows multiple search paths without having to check each one // when opening a file (slow). // -// one Loc is allocated for each archive or directory mounted, and all -// real subdirectories; all files in an archive share the same location. +// one Loc is allocated for each archive or directory mounted. // therefore, files only /point/ to a (possibly shared) Loc. // if a file's location changes (e.g. after mounting a higher-priority // directory), the VFS entry will point to the new Loc; the priority // of both locations is unchanged. // -// allocate via loc_create, passing the location. do not free! +// allocate via mnt_create, passing the location. do not free! // we keep track of all Locs allocated; they are freed at exit, -// and by loc_free_all (useful when rebuilding the VFS). +// and by mnt_free_all (useful when rebuilding the VFS). // this is much easier and safer than walking the VFS tree and // freeing every location we find. -struct Loc; -typedef std::vector Locs; -// not many instances and allocated via new => -// don't worry about struct size / alignment. +// not many instances => don't worry about struct size / alignment. struct Loc { - Handle ha; + Handle archive; - std::string path; + std::string dir; uint pri; - - Loc(Handle _ha, const char* _path, uint _pri) - : ha(_ha), path(_path), pri(_pri) - { - ONCE(atexit2(loc_free_all)); - - // add to list for later deletion - locs.push_back(this); - } - - friend int loc_free_all(); - -private: - static Locs locs; + Loc() {} + Loc(Handle _archive, const char* _dir, uint _pri) + : archive(_archive), dir(_dir), pri(_pri) {} }; -Locs Loc::locs; -static inline void loc_free(Loc* const loc) - { delete loc; } - -static int loc_free_all() -{ - // we don't expect many Locs to be added (one per loose-file dir - // or archive), so don't worry about reallocating memory. - // return value is also irrelevant - can't fail as currently implemented. - - Locs& locs = Loc::locs; - std::for_each(locs.begin(), locs.end(), loc_free); - // could use smart ptr (boost or loki) instead, but this'll do - - locs.clear(); - return 0; -} - - -// wrapper on top of new + ctor to emphasize that -// the caller must not free the Loc pointer. -// (if they do, VFS entries point to freed memory => disaster) -static Loc* loc_create(const Handle ha, const char* const path, const uint pri) -{ - return new Loc(ha, path, pri); -} - - -/////////////////////////////////////////////////////////////////////////////// -// -// "file system" (tree structure; stores location of each file) -// -/////////////////////////////////////////////////////////////////////////////// - struct VDir; -typedef std::map SubDirs; +typedef std::map SubDirs; typedef SubDirs::iterator SubDirIt; typedef std::map Files; @@ -317,20 +260,21 @@ struct VDir return it->second; } - VDir* subdir_add(const char* fn, VDir& _dir) + VDir* subdir_add(const char* name) { - std::string _fn(fn); - _dir.v_name = _fn; + VDir* vdir = new VDir; + std::string _name(name); + vdir->v_name = _name; - std::pair item = std::make_pair(_fn, _dir); + std::pair item = std::make_pair(_name, vdir); std::pair res; res = subdirs.insert(item); // already in container if(!res.second) - assert(0 && "already in subdir"); + debug_warn("already in subdir"); SubDirIt it = res.first; - return &it->second; + return it->second; } VDir* subdir_find(const char* fn) @@ -339,40 +283,31 @@ struct VDir SubDirIt it = subdirs.find(_fn); if(it == subdirs.end()) return 0; - return &it->second; + return it->second; } - void clear_tree() - { - SubDirIt it; - for(it = subdirs.begin(); it != subdirs.end(); ++it) - { - VDir& dir = it->second; - dir.clear_tree(); - } - - files.clear(); - subdirs.clear(); - } + friend void tree_clearR(VDir*); SubDirs subdirs; // can't make private; needed for iterator - -private: - Files files; + + +private:; + + }; -VDir vfs_root; +static VDir vfs_root; enum LookupFlags { - PF_DEFAULT, + LF_DEFAULT, LF_CREATE_MISSING_COMPONENTS = 1 }; -static int tree_lookup(const char* vfs_path, Loc** loc = 0, VDir** dir = 0, LookupFlags flags = PF_DEFAULT) +static int tree_lookup(const char* vfs_path, Loc** loc = 0, VDir** dir = 0, LookupFlags flags = LF_DEFAULT) { CHECK_PATH(vfs_path); @@ -419,10 +354,7 @@ static int tree_lookup(const char* vfs_path, Loc** loc = 0, VDir** dir = 0, Look if(!subdir) { if(create_missing_components) - { - VDir _dir; - subdir = cur_dir->subdir_add(subdir_name, _dir); - } + subdir = cur_dir->subdir_add(subdir_name); else return ERR_PATH_NOT_FOUND; } @@ -434,24 +366,24 @@ static int tree_lookup(const char* vfs_path, Loc** loc = 0, VDir** dir = 0, Look } +static void tree_clearR(VDir* const dir) +{ + SubDirIt it; + for(it = dir->subdirs.begin(); it != dir->subdirs.end(); ++it) + { + VDir* subdir = it->second; + tree_clearR(subdir); + } + + dir->files.clear(); + dir->subdirs.clear(); +} - - - - - - - - - - - -typedef std::vector Archives; -typedef Archives::iterator ArchiveIt; - - - +static inline void tree_clear() +{ + tree_clearR(&vfs_root); +} @@ -464,13 +396,13 @@ struct FileCBParams { VDir* dir; Loc* loc; +}; // somewhat of a hack. which archives are mounted into the VFS is stored // in an Archives list in the Mount struct; they don't have anything to // do with a VFS dir. we want to enumerate the archives in a dir via the // normal populate(), though, so have to pass this to its callback. - Archives* archives; -}; + // called for each OS dir ent. @@ -484,111 +416,64 @@ struct FileCBParams // to try to open it as an archive - not good. // this restriction also simplifies the code a bit, but if it's a problem, // just generate a list of archives here and mount them from the caller. -static int file_cb(const char* fn, uint flags, ssize_t size, uintptr_t user) +static int add_dirent_cb(const char* fn, uint flags, ssize_t size, uintptr_t user) { FileCBParams* params = (FileCBParams*)user; VDir* cur_dir = params->dir; Loc* cur_loc = params->loc; - Archives* archives = params->archives; // directory if(flags & LOC_DIR) - { - VDir _dir; - cur_dir->subdir_add(fn, _dir); - } + cur_dir->subdir_add(fn); // file else - { - // only add to list; don't enumerate its files yet for easier debugging - // (we see which files are in a dir / archives) - // also somewhat faster, due to better locality. - // - // don't check filename extension - archives won't necessarily - // be called .zip (example: Quake III .pk3). - // just try to open the file. - if(archives) - { - const Handle ha = zip_archive_open(fn); - if(ha > 0) - archives->push_back(ha); - } - cur_dir->file_add(fn, cur_loc->pri, cur_loc); - } return 0; } - -static int vdir_add_from_archive(VDir* dir, const Handle ha, const uint pri, Archives* archives) -{ - // all files in the archive share this location - Loc* loc = loc_create(ha, 0, pri-1); - - // add all files in archive to the VFS dir - FileCBParams params = { dir, loc, archives }; - CHECK_ERR(zip_enum_files(ha, file_cb, (uintptr_t)¶ms)); - - return 0; -} - - - -static int addR(VDir* vdir, const char* path, Loc* loc, const uint pri, Archives* archives) +static int tree_add_dirR(VDir* vdir, const char* dir, Loc* loc) { // add watch if(!vdir->watch) vdir->watch = 0; - // add files and subdirs to dir; gather list of all archives - FileCBParams params = { vdir, loc, archives }; - file_enum_dirents(path, file_cb, (uintptr_t)¶ms); - - // loc will now be used for files in Zip archives - loc->pri--; -// loc->path = 0; + // add files and subdirs to dir + FileCBParams params = { vdir, loc }; + file_enum(dir, add_dirent_cb, (uintptr_t)¶ms); for(SubDirIt it = vdir->subdirs.begin(); it != vdir->subdirs.end(); ++it) { - VDir* subdir = &it->second; + VDir* subdir = it->second; char v_subdir_path[PATH_MAX]; const char* v_subdir_name_c = subdir->v_name.c_str(); - CHECK_ERR(path_append(v_subdir_path, path, v_subdir_name_c)); + CHECK_ERR(path_append(v_subdir_path, dir, v_subdir_name_c)); - addR(subdir, v_subdir_path, loc, pri, archives); + tree_add_dirR(subdir, v_subdir_path, loc); } - // for each archive: - // (already sorted due to file_enum_dirents) -/* - { - for(ArchiveIt it = archives->begin(); it != archives->end(); ++it) - { - const Handle ha = *it; - CHECK_ERR(vdir_add_from_archive(vdir, ha, pri, archives)); - } - } -*/ return 0; } -// parent param not reference to allow passing 0 root node? -static int vdir_add_from_dir(VDir* vdir, const char* path, const uint pri, Archives* archives) +static int tree_add_loc(VDir* vdir, Loc* loc) { - // all loose files in the new dir and its subdirs share this location - Loc* loc = loc_create(0, path, pri+1); + const char* dir = loc->dir.c_str(); - return addR(vdir, path, loc, pri, archives); + FileCBParams params = { vdir, loc }; + + if(loc->archive > 0) + return zip_enum(loc->archive, add_dirent_cb, (uintptr_t)¶ms); + else + { + CHECK_PATH(dir); + return tree_add_dirR(vdir, dir, loc); + } } - - - /////////////////////////////////////////////////////////////////////////////// // // mount archives and directories into the VFS @@ -596,114 +481,144 @@ static int vdir_add_from_dir(VDir* vdir, const char* path, const uint pri, Archi /////////////////////////////////////////////////////////////////////////////// -// need a list of all mounted dirs or archives so we can vfs_reload at -// any time. it's also nice, but not necessary, to unmount at exit -// (so resources aren't reported as leaked). + +typedef std::vector Locs; +typedef Locs::iterator LocIt; struct Mount { - std::string vfs_path; - std::string name; // of OS dir or archive being mounted + std::string vfs_mount_point; + std::string name; + uint pri; - Archives archives; + Loc loc; + Locs archive_locs; - Mount(const char* _vfs_path, const char* _name, uint _pri) - : vfs_path(_vfs_path), name(_name), pri(_pri), archives() {} + Mount() {} + Mount(const char* _vfs_mount_point, const char* _name, uint _pri) + : vfs_mount_point(_vfs_mount_point), name(_name), pri(_pri) {} }; -typedef std::list Mounts; +typedef std::vector Mounts; typedef Mounts::iterator MountIt; - static Mounts mounts; + +// called for each OS dir ent. +// add each archive to list. +static int archive_cb(const char* fn, uint flags, ssize_t size, uintptr_t user) +{ + Locs* archive_locs = (Locs*)user; + // only add to list; don't enumerate its files yet for easier debugging + // (we see which files are in a dir / archives) + // also somewhat faster, due to better locality. + // + // don't check filename extension - archives won't necessarily + // be called .zip (example: Quake III .pk3). + // just try to open the file. + const Handle archive = zip_archive_open(fn); + if(archive > 0) + archive_locs->push_back(Loc(archive, "", 0)); + +/// HACK HACK HACK pass along pri + + + // tree_add_loc them here? + + return 0; +} + + + // actually mount the specified entry (either Zip archive or dir). // split out of vfs_mount because we need to mount without changing the // mount list, when invalidating (reloading) the VFS. static int remount(Mount& m) { - const char* vfs_path = m.vfs_path.c_str(); - const char* name = m.name.c_str(); - const uint pri = m.pri; - - CHECK_PATH(name); - - VDir* vdir; - CHECK_ERR(tree_lookup(vfs_path, 0, &vdir, LF_CREATE_MISSING_COMPONENTS)); - int err; - // add files and subdirectories to the VFS dir - err = vdir_add_from_dir(vdir, name, pri, &m.archives); - // success -// if(err == 0) - return 0; + const char* vfs_mount_point = m.vfs_mount_point.c_str(); + const char* name = m.name.c_str(); + const uint pri = m.pri; - const Handle ha = zip_archive_open(name); - err = vdir_add_from_archive(vdir, ha, pri, &m.archives); - if(err == 0) - return 0; + VDir* vdir; + CHECK_ERR(tree_lookup(vfs_mount_point, 0, &vdir, LF_CREATE_MISSING_COMPONENTS)); - return ERR_PATH_NOT_FOUND; + // check if target is a single Zip archive + // order doesn't matter; can't have both an archive and dir + + const Handle archive = zip_archive_open(name); + if(archive > 0) + { + m.archive_locs.push_back(Loc(archive, "", pri)); + LocIt it = m.archive_locs.end(); + Loc* loc = &*(--it); + return tree_add_loc(vdir, loc); + } + + m.loc.dir.assign(m.name); + err = tree_add_loc(vdir, &m.loc); + if(err < 0) + err = err; + + // enumerate all archives + return file_enum(name, archive_cb, (uintptr_t)&m.archive_locs); } static int unmount(Mount& m) { - std::for_each(m.archives.begin(), m.archives.end(), zip_archive_close); + for(LocIt it = m.archive_locs.begin(); it != m.archive_locs.end(); ++it) + { + Loc& loc = *it; + zip_archive_close(loc.archive); + } + + m.archive_locs.clear(); return 0; } static void unmount_all(void) -{ - std::for_each(mounts.begin(), mounts.end(), unmount); -} + { std::for_each(mounts.begin(), mounts.end(), unmount); } + +static void remount_all() + { std::for_each(mounts.begin(), mounts.end(), remount); } -int vfs_mount(const char* const vfs_path, const char* const name, const uint pri) +int vfs_mount(const char* const vfs_mount_point, const char* const name, const uint pri) { ONCE(atexit(unmount_all)); + MountIt it; + // make sure it's not already mounted, i.e. in mounts - { - for(MountIt it = mounts.begin(); it != mounts.end(); ++it) + for(it = mounts.begin(); it != mounts.end(); ++it) if(it->name == name) { - assert(0 && "vfs_mount: already mounted"); + debug_warn("vfs_mount: already mounted"); return -1; } - } - mounts.push_back(Mount(vfs_path, name, pri)); + mounts.push_back(Mount(vfs_mount_point, name, pri)); // actually mount the entry - MountIt it = mounts.end(); + it = mounts.end(); Mount& m = *(--it); return remount(m); } -// eventually returns the first error that occurred; does not abort. int vfs_rebuild() { - int err = 0; + tree_clear(); - vfs_root.clear_tree(); - - loc_free_all(); - - // need error return. manual loop is easier than functor + for_each. - for(MountIt it = mounts.begin(); it != mounts.end(); ++it) - { - int ret = remount(*it); - if(err == 0) - err = ret; - } - - return err; + unmount_all(); + remount_all(); + return 0; } @@ -713,19 +628,19 @@ int vfs_unmount(const char* name) // found the corresponding entry if(it->name == name) { - int unmount_err = unmount(*it); + Mount& m = *it; + unmount(m); mounts.erase(it); - - int rebuild_err = vfs_rebuild(); - - return (unmount_err < 0)? unmount_err : rebuild_err; + return vfs_rebuild(); } return ERR_PATH_NOT_FOUND; } + + /////////////////////////////////////////////////////////////////////////////// // // @@ -746,17 +661,17 @@ int vfs_realpath(const char* fn, char* full_path) Loc* loc; CHECK_ERR(tree_lookup(fn, &loc)); - if(loc->ha <= 0) + if(loc->archive > 0) { - strncpy(full_path, loc->path.c_str(), PATH_MAX); - } - else - { - const char* archive_fn = h_filename(loc->ha); + const char* archive_fn = h_filename(loc->archive); if(!archive_fn) return -1; strncpy(full_path, archive_fn, PATH_MAX); } + else + { + strncpy(full_path, loc->dir.c_str(), PATH_MAX); + } return 0; } @@ -767,10 +682,13 @@ int vfs_stat(const char* fn, struct stat* s) Loc* loc; CHECK_ERR(tree_lookup(fn, &loc)); - if(loc->ha <= 0) - return stat(loc->path.c_str(), s); + if(loc->archive > 0) + return zip_stat(loc->archive, fn, s); else - return zip_stat(loc->ha, fn, s); + { + const char* dir = loc->dir.c_str(); + return file_stat(dir, s); + } } @@ -871,31 +789,22 @@ static int VFile_reload(VFile* vf, const char* fn) Loc* loc; CHECK_ERR(tree_lookup(fn, &loc)); - if(loc->ha <= 0) + if(loc->archive <= 0) { - const char* path; - char buf[PATH_MAX+1]; - // (it's in the VFS root dir) - if(loc->path[0] == '\0') - path = fn; - else - { - const char* loc_path = loc->path.c_str(); - CHECK_ERR(path_append(buf, loc_path, fn)); - path = buf; - } - + char path[PATH_MAX]; + const char* dir = loc->dir.c_str(); + CHECK_ERR(path_append(path, dir, fn)); CHECK_ERR(file_open(path, vf_flags(vf), &vf->f)); } else { if(flags & VFS_WRITE) { - assert(0 && "requesting write access to file in archive"); + debug_warn("requesting write access to file in archive"); return -1; } - CHECK_ERR(zip_open(loc->ha, fn, &vf->zf)); + CHECK_ERR(zip_open(loc->archive, fn, &vf->zf)); flags |= VF_ZIP; } @@ -907,7 +816,7 @@ static int VFile_reload(VFile* vf, const char* fn) } -Handle vfs_open(const char* fn, int flags /* = 0 */) +Handle vfs_open(const char* fn, uint flags /* = 0 */) { Handle h = h_alloc(H_VFile, fn, 0, flags); // pass file flags to init @@ -966,7 +875,7 @@ debug_out("vfs_load fn=%s\n", fn); goto skip_read; } else - assert(0 && "vfs_load: invalid MEM attached to vfile (0 pointer)"); + debug_warn("vfs_load: invalid MEM attached to vfile (0 pointer)"); // happens if someone frees the pointer. not an error! } @@ -1003,7 +912,7 @@ int vfs_store(const char* fn, void* p, size_t size) -Handle vfs_map(const char* fn, int flags, void*& p, size_t& size) +Handle vfs_map(const char* fn, uint flags, void*& p, size_t& size) { Handle hf = vfs_open(fn, flags); H_DEREF(hf, VFile, vf); diff --git a/source/lib/res/vfs.h b/source/lib/res/vfs.h index cac9c75eed..f9f6bb187a 100755 --- a/source/lib/res/vfs.h +++ b/source/lib/res/vfs.h @@ -25,7 +25,7 @@ #define VFS_MAX_PATH 256 // includes trailing '\0' -extern int vfs_mount(const char* vfs_path, const char* name, uint pri); +extern int vfs_mount(const char* vfs_mount_point, const char* name, uint pri); extern int vfs_umount(const char* name); extern int vfs_stat(const char* fn, struct stat*); @@ -33,10 +33,10 @@ extern int vfs_realpath(const char* fn, char* realpath); extern Handle vfs_load(const char* fn, void*& p, size_t& size); -extern Handle vfs_open(const char* fn, int flags = 0); +extern Handle vfs_open(const char* fn, uint flags = 0); extern int vfs_close(Handle& h); -extern Handle vfs_map(Handle hf, int flags, void*& p, size_t& size); +extern Handle vfs_map(Handle hf, uint flags, void*& p, size_t& size); diff --git a/source/lib/res/zip.cpp b/source/lib/res/zip.cpp index e7f4b3dcb7..c168f9fb29 100755 --- a/source/lib/res/zip.cpp +++ b/source/lib/res/zip.cpp @@ -16,9 +16,7 @@ // Jan.Wassenberg@stud.uni-karlsruhe.de // http://www.stud.uni-karlsruhe.de/~urkt/ -#include -#include -#include +#include "precompiled.h" #include "lib.h" #include "res.h" @@ -68,7 +66,7 @@ static int zip_find_ecdr(const void* const file, const size_t size, const u8*& e if(size < ECDR_SIZE) { - assert(0 && "zip_find_ecdr: size is way too small"); + debug_warn("zip_find_ecdr: size is way too small"); return -1; } const u8* ecdr = (const u8*)file + size - ECDR_SIZE; @@ -118,7 +116,7 @@ static int zip_verify_lfh(const void* const file, const size_t lfh_ofs, const si if(*(u32*)lfh != *(u32*)lfh_id) { - assert(0 && "LFH corrupt! (signature doesn't match)"); + debug_warn("LFH corrupt! (signature doesn't match)"); return -1; } @@ -129,7 +127,7 @@ static int zip_verify_lfh(const void* const file, const size_t lfh_ofs, const si if(file_ofs != lfh_file_ofs) { - assert(0 && "warning: CDFH and LFH data differ! normal builds will"\ + debug_warn("warning: CDFH and LFH data differ! normal builds will"\ "return incorrect file offsets. check Zip file!"); return -1; } @@ -149,7 +147,7 @@ static int zip_read_cdfh(const u8*& cdfh, const char*& fn, size_t& fn_len, ZFile if(*(u32*)cdfh != *(u32*)cdfh_id) { - assert(0 && "CDFH corrupt! (signature doesn't match)"); + debug_warn("CDFH corrupt! (signature doesn't match)"); goto skip_file; } @@ -167,7 +165,7 @@ static int zip_read_cdfh(const u8*& cdfh, const char*& fn, size_t& fn_len, ZFile // compression method: neither deflated nor stored if(method & ~8) { - assert(0 && "warning: unknown compression method"); + debug_warn("warning: unknown compression method"); goto skip_file; } @@ -443,7 +441,7 @@ static int lookup_get_file_info(LookupInfo* const li, const i32 idx, const char* { if(idx < 0 || idx >= li->num_files-1) { - assert(0 && "lookup_get_file_info: index out of bounds"); + debug_warn("lookup_get_file_info: index out of bounds"); return -1; } @@ -557,7 +555,7 @@ int zip_archive_close(Handle& ha) // would be nice to pass along a key (allowing for O(1) lookup in archive), // but then the callback is no longer compatible to file / vfs enum files. -int zip_enum_files(const Handle ha, const ZipFileCB cb, const uintptr_t user) +int zip_enum(const Handle ha, const ZipFileCB cb, const uintptr_t user) { H_DEREF(ha, ZArchive, za); @@ -592,7 +590,7 @@ int inf_start_read(uintptr_t ctx, void* out, size_t out_size) if(stream->next_out || stream->avail_out) { - assert(0 && "zip_start_read: ctx already in use!"); + debug_warn("zip_start_read: ctx already in use!"); return -1; } stream->next_out = (Byte*)out; @@ -636,7 +634,7 @@ int inf_finish_read(uintptr_t ctx) if(stream->avail_in || stream->avail_out) { - assert("zip_finish_read: input or input buffer has space remaining"); + debug_warn("zip_finish_read: input or input buffer has space remaining"); stream->avail_in = stream->avail_out = 0; return -1; } @@ -703,7 +701,7 @@ static int zfile_validate(uint line, ZFile* zf) // failed somewhere - err is the error code, // or -1 if not set specifically above. debug_out("zfile_validate at line %d failed: %s\n", line, msg); - assert(0 && "zfile_validate failed"); + debug_warn("zfile_validate failed"); return err; } @@ -841,7 +839,7 @@ ssize_t zip_read(ZFile* zf, size_t raw_ofs, size_t size, void*& p) // problem: partial reads if(raw_ofs != zf->last_raw_ofs) { - assert(0 && "zip_read: compressed read offset is non-continuous"); + debug_warn("zip_read: compressed read offset is non-continuous"); return -1; } @@ -893,7 +891,7 @@ int zip_map(ZFile* zf, void*& p, size_t& size) // doesn't really make sense to map compressed files, so disallow it. if(is_compressed(zf)) { - assert(0 && "mapping a compressed file from archive. why?"); + debug_warn("mapping a compressed file from archive. why?"); return -1; } diff --git a/source/lib/res/zip.h b/source/lib/res/zip.h index ec44fb9792..5fdce45bde 100755 --- a/source/lib/res/zip.h +++ b/source/lib/res/zip.h @@ -57,7 +57,7 @@ enum ZIP_CB_FLAGS }; typedef int(*ZipFileCB)(const char* const fn, const uint flags, const ssize_t size, const uintptr_t user); -extern int zip_enum_files(const Handle ha, const ZipFileCB cb, const uintptr_t user); +extern int zip_enum(const Handle ha, const ZipFileCB cb, const uintptr_t user); // // file diff --git a/source/lib/sysdep/ia32.cpp b/source/lib/sysdep/ia32.cpp index c08cb4168e..2ff4945d1b 100755 --- a/source/lib/sysdep/ia32.cpp +++ b/source/lib/sysdep/ia32.cpp @@ -15,17 +15,10 @@ // Jan.Wassenberg@stud.uni-karlsruhe.de // http://www.stud.uni-karlsruhe.de/~urkt/ +#include "precompiled.h" + #ifdef _M_IX86 -#include -#include // sscanf -#include -#include -#include - -#include -#include - #include "ia32.h" #include "lib.h" #include "detect.h" diff --git a/source/lib/sysdep/sysdep.cpp b/source/lib/sysdep/sysdep.cpp index 30b86f8bb9..be2e34c39d 100755 --- a/source/lib/sysdep/sysdep.cpp +++ b/source/lib/sysdep/sysdep.cpp @@ -1,6 +1,4 @@ -#include -#include -#include +#include "precompiled.h" #include "sysdep.h" diff --git a/source/lib/sysdep/win/hrt.cpp b/source/lib/sysdep/win/hrt.cpp index 14a084c3d6..d825568520 100755 --- a/source/lib/sysdep/win/hrt.cpp +++ b/source/lib/sysdep/win/hrt.cpp @@ -15,11 +15,7 @@ // Jan.Wassenberg@stud.uni-karlsruhe.de // http://www.stud.uni-karlsruhe.de/~urkt/ -#include -#include -#include - -#include +#include "precompiled.h" #include "hrt.h" #include "lib.h" @@ -171,7 +167,7 @@ static void choose_impl() } // no warning here - doesn't inspire confidence in VC dead code removal. - assert(0 && "hrt_choose_impl: no safe timer found!"); + debug_warn("hrt_choose_impl: no safe timer found!"); hrt_impl = HRT_NONE; hrt_nominal_freq = -1; return; @@ -214,7 +210,7 @@ static i64 ticks_lk() // add further timers here. default: - assert(0 && "hrt_ticks: invalid impl"); + debug_warn("hrt_ticks: invalid impl"); // fall through case HRT_NONE: @@ -375,7 +371,7 @@ 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_TGT && impl != HRT_NONE)) { - assert(0 && "hrt_override: invalid ovr or impl param"); + debug_warn("hrt_override: invalid ovr or impl param"); return -1; } diff --git a/source/lib/sysdep/win/waio.cpp b/source/lib/sysdep/win/waio.cpp index 2400a5838c..1cf2ee1f47 100755 --- a/source/lib/sysdep/win/waio.cpp +++ b/source/lib/sysdep/win/waio.cpp @@ -16,9 +16,7 @@ // Jan.Wassenberg@stud.uni-karlsruhe.de // http://www.stud.uni-karlsruhe.de/~urkt/ -#include -#include -#include +#include "precompiled.h" #include @@ -128,12 +126,12 @@ int aio_h_set(int fd, HANDLE h) { if(aio_hs[fd] != INVALID_HANDLE_VALUE) { - assert("AioHandles::set: handle already set!"); + debug_warn("AioHandles::set: handle already set!"); goto fail; } if(!is_valid_file_handle(h)) { - assert("AioHandles::set: setting invalid handle"); + debug_warn("AioHandles::set: setting invalid handle"); goto fail; } } @@ -145,7 +143,7 @@ int aio_h_set(int fd, HANDLE h) fail: win_unlock(WAIO_CS); - assert(0 && "aio_h_set failed"); + debug_warn("aio_h_set failed"); return -1; } @@ -307,14 +305,14 @@ int aio_assign_handle(uintptr_t handle) HANDLE h = CreateEvent(0,0,0,0); if(h == INVALID_HANDLE_VALUE) { - assert(0 && "aio_assign_handle failed"); + debug_warn("aio_assign_handle failed"); return -1; } int fd = _open_osfhandle((intptr_t)h, 0); if(fd < 0) { - assert(0 && "aio_assign_handle failed"); + debug_warn("aio_assign_handle failed"); return fd; } @@ -347,13 +345,13 @@ WIN_ONCE(init()); // TODO: need to do this elsewhere in case other routines call HANDLE h = CreateFile(fn, access, share, 0, create, flags, 0); if(h == INVALID_HANDLE_VALUE) { - assert(0 && "aio_open failed"); + debug_warn("aio_open failed"); return -1; } if(aio_h_set(fd, h) < 0) { - assert(0 && "aio_open failed"); + debug_warn("aio_open failed"); CloseHandle(h); return -1; } @@ -368,7 +366,7 @@ int aio_close(int fd) HANDLE h = aio_h_get(fd); if(h == INVALID_HANDLE_VALUE) // out of bounds or already closed { - assert(0 && "aio_close failed"); + debug_warn("aio_close failed"); return -1; } @@ -407,21 +405,21 @@ debug_out("aio_rw cb=%p\n", cb); HANDLE h = aio_h_get(cb->aio_fildes); if(h == INVALID_HANDLE_VALUE) { - assert(0 && "aio_rw: associated handle is invalid"); + debug_warn("aio_rw: associated handle is invalid"); return -EINVAL; } if(cb->req_) { // SUSv3 says this has undefined results; we fail the attempt. - assert(0 && "aio_rw: aiocb is already in use"); + debug_warn("aio_rw: aiocb is already in use"); return -1; } Req* r = req_alloc(cb); if(!r) { - assert(0 && "aio_rw: cannot allocate a Req (too many concurrent IOs)"); + debug_warn("aio_rw: cannot allocate a Req (too many concurrent IOs)"); return -1; } diff --git a/source/lib/sysdep/win/wdetect.cpp b/source/lib/sysdep/win/wdetect.cpp index fdcf7e687c..4ee60902c8 100755 --- a/source/lib/sysdep/win/wdetect.cpp +++ b/source/lib/sysdep/win/wdetect.cpp @@ -16,8 +16,7 @@ // Jan.Wassenberg@stud.uni-karlsruhe.de // http://www.stud.uni-karlsruhe.de/~urkt/ -#include -#include +#include "precompiled.h" #include "detect.h" #include "lib.h" @@ -31,8 +30,8 @@ #endif -// EnumDisplayDevices (used in get_monitor_size and win_get_gfx_card) -// is not available on Win95 or NT. try to import it manually here. +// EnumDisplayDevices is not available on Win95 or NT. +// try to import it manually here; return -1 if not available. // note: FreeLibrary at exit avoids BoundsChecker resource leak warnings. static BOOL (WINAPI *pEnumDisplayDevicesA)(void*, DWORD, void*, DWORD); static int import_EnumDisplayDevices() @@ -68,113 +67,15 @@ int get_cur_resolution(int& xres, int& yres) // useful for determining aspect ratio. not called by detect(). // if we fail, outputs are unchanged (assumed initialized to defaults) -int get_monitor_size(int& width_cm, int& height_cm) +int get_monitor_size(int& width_mm, int& height_mm) { - DISPLAY_DEVICE adapter = { sizeof(DISPLAY_DEVICE) }; - DISPLAY_DEVICE monitor = { sizeof(DISPLAY_DEVICE) }; - // need to be distinct (EnumDisplayDevices requirement) + HDC dc = GetDC(0); // dc for entire screen - LONG err; - char key_name[256]; - DWORD key_name_len; - DWORD key_type; + width_mm = GetDeviceCaps(dc, HORZSIZE); + height_mm = GetDeviceCaps(dc, VERTSIZE); - bool found = false; - - - // make sure EnumDisplayDevices is available (as pEnumDisplayDevicesA) - CHECK_ERR(import_EnumDisplayDevices()); - - HKEY hkDisplay; - if(RegOpenKeyEx(HKEY_LOCAL_MACHINE, "SYSTEM\\CurrentControlSet\\Enum\\Display", 0, KEY_READ, &hkDisplay) != 0) - return -1; - - // we only look at the first monitor of the first display adapter - // attached to the desktop, assumed to be the primary monitor. - - // for each display adapter - for(int adapter_idx = 0; !found; adapter_idx++) - { - // get display adapter - if(!pEnumDisplayDevicesA(0, adapter_idx, &adapter, 0)) - break; - if(!(adapter.StateFlags & DISPLAY_DEVICE_ATTACHED_TO_DESKTOP)) - continue; - - // get its associated monitor; - // will search for its DeviceID in the registry - if(!pEnumDisplayDevicesA(adapter.DeviceName, 0, &monitor, 0)) - continue; - - // for each class in registry - for(int class_idx = 0; !found; class_idx++) - { - // open next key - HKEY hkClass; - key_name_len = sizeof(key_name); - if(RegEnumKeyEx(hkDisplay, class_idx, key_name, &key_name_len, 0, 0, 0, 0) != 0) - break; - if(RegOpenKeyEx(hkDisplay, key_name, 0, KEY_READ, &hkClass) != 0) - break; - - // for each device in registry - for(int dev_idx = 0; !found; dev_idx++) - { - // open next key - HKEY hkDev; - key_name_len = sizeof(key_name); - if(RegEnumKeyEx(hkClass, dev_idx, key_name, &key_name_len, 0, 0, 0, 0) != 0) - break; - if(RegOpenKeyEx(hkClass, key_name, 0, KEY_READ, &hkDev) != 0) - break; - - // build dev_id: (%s\\%s, HardwareID, Driver) - // example: "Monitor\NEC6604\{4D36E96E-E325-11CE-BFC1-08002BE10318}\0001" - // will compare this against monitor.DeviceID - char dev_id[256]; - DWORD dev_id_len = sizeof(dev_id); - err = RegQueryValueEx(hkDev, "HardwareID", 0, &key_type, (BYTE*)dev_id, &dev_id_len); - if(err != 0 || (key_type != REG_MULTI_SZ && key_type != REG_SZ)) - goto skip_dev; - char* p = (char*)dev_id + strlen((const char*)dev_id); - *p++ = '\\'; - dev_id_len = sizeof(dev_id) - dev_id_len; - err = RegQueryValueEx(hkDev, "Driver", 0, &key_type, (BYTE*)p, &dev_id_len); - if(err != 0 || (key_type != REG_MULTI_SZ && key_type != REG_SZ)) - goto skip_dev; - - // this (hkDev) is not the monitor you're looking for.. - if(strcmp(monitor.DeviceID, (const char*)dev_id) != 0) - goto skip_dev; - - HKEY hkDevParams; - if(RegOpenKeyEx(hkDev, "Device Parameters", 0, KEY_READ, &hkDevParams) != 0) - goto skip_dev; - - // read EDID - BYTE edid[256]; - DWORD edid_len = sizeof(edid); - if(RegQueryValueEx(hkDevParams, "EDID", 0, &key_type, edid, &edid_len) == 0) - { - width_cm = edid[21]; - height_cm = edid[22]; - found = true; - // break out of all loops; all keys will be closed - } - - RegCloseKey(hkDevParams); - - skip_dev: - RegCloseKey(hkDev); - } - - RegCloseKey(hkClass); - } - } - - RegCloseKey(hkDisplay); - - return found? 0 : -1; + ReleaseDC(0, dc); + return 0; } @@ -184,8 +85,7 @@ int win_get_gfx_card() if(import_EnumDisplayDevices() < 0) return -1; - DISPLAY_DEVICEA dev; - dev.cb = sizeof(dev); + DISPLAY_DEVICEA dev = { sizeof(dev) }; if(!pEnumDisplayDevicesA(0, 0, &dev, 0)) return -1; @@ -199,9 +99,12 @@ int win_get_gfx_card() int win_get_gfx_drv() { // get driver DLL name - static DEVMODE dm; // note: dmDriverVersion is something else + DEVMODEA dm; + // note: dmDriverVersion is not what we're looking for + memset(&dm, 0, sizeof(dm)); dm.dmSize = sizeof(dm); - if(!EnumDisplaySettings(0, ENUM_CURRENT_SETTINGS, &dm)) + // note: dmSize isn't the first member! + if(!EnumDisplaySettingsA(0, ENUM_CURRENT_SETTINGS, &dm)) return -1; char drv_name[CCHDEVICENAME+5]; // we add ".dll" strcpy(drv_name, (const char*)dm.dmDeviceName); diff --git a/source/lib/sysdep/win/win.cpp b/source/lib/sysdep/win/win.cpp index dec02da767..819d445107 100755 --- a/source/lib/sysdep/win/win.cpp +++ b/source/lib/sysdep/win/win.cpp @@ -15,13 +15,11 @@ // Jan.Wassenberg@stud.uni-karlsruhe.de // http://www.stud.uni-karlsruhe.de/~urkt/ +#include "precompiled.h" + #include "lib.h" #include "win_internal.h" -#include // __argc -#include -#include - #include // malloc debug #include @@ -133,6 +131,10 @@ static void at_exit(void) { for(int i = 0; i < NUM_CS; i++) DeleteCriticalSection(&cs[i]); + + // redirected to stdout.txt in pre_main_init; + // close to avoid BoundsChecker warning. + fclose(stdout); } @@ -162,7 +164,7 @@ static inline void pre_main_init() atexit(at_exit); - // SDL will do this as well. no matter. + // real SDL will do this as well. no matter. // ignore BoundsChecker warning here. freopen("stdout.txt", "wt", stdout); } diff --git a/source/lib/sysdep/win/wposix.cpp b/source/lib/sysdep/win/wposix.cpp index f2fff6b754..34cde82b88 100755 --- a/source/lib/sysdep/win/wposix.cpp +++ b/source/lib/sysdep/win/wposix.cpp @@ -18,10 +18,7 @@ // collection of hacks :P -#include -#include -#include -#include +#include "precompiled.h" #include @@ -305,7 +302,11 @@ int pthread_create(pthread_t* /* thread */, const void* /* attr */, void*(*func) pthread_mutex_t pthread_mutex_initializer() { - return CreateMutex(0, 0, 0); + HANDLE h = CreateMutex(0, 0, 0); + if(h == INVALID_HANDLE_VALUE) + return 0; + atexit2(CloseHandle, (uintptr_t)h, CC_STDCALL_1); + return h; } int pthread_mutex_init(pthread_mutex_t* m, const pthread_mutexattr_t*) @@ -313,7 +314,7 @@ int pthread_mutex_init(pthread_mutex_t* m, const pthread_mutexattr_t*) if(!m) return -1; *m = pthread_mutex_initializer(); - return 0; + return *m? 0 : -1; } int pthread_mutex_lock(pthread_mutex_t* m) @@ -464,7 +465,7 @@ int clock_gettime(clockid_t clock, struct timespec* t) #ifndef NDEBUG if(clock != CLOCK_REALTIME || !t) { - assert(0 && "clock_gettime: invalid clock or t param"); + debug_warn("clock_gettime: invalid clock or t param"); return -1; } #endif @@ -481,7 +482,7 @@ int clock_getres(clockid_t clock, struct timespec* res) #ifndef NDEBUG if(clock != CLOCK_REALTIME || !res) { - assert(0 && "clock_getres: invalid clock or res param"); + debug_warn("clock_getres: invalid clock or res param"); return -1; } #endif @@ -510,7 +511,7 @@ int gettimeofday(struct timeval* tv, void* tzp) #ifndef NDEBUG if(!tv) { - assert(0 && "gettimeofday: invalid t param"); + debug_warn("gettimeofday: invalid t param"); return -1; } #endif @@ -625,14 +626,18 @@ long sysconf(int name) if(!page_size) sysconf(_SC_PAGESIZE); // sets page_size - MEMORYSTATUS ms; - GlobalMemoryStatus(&ms); + { + MEMORYSTATUSEX ms = { sizeof(ms) }; + GlobalMemoryStatusEx(&ms); if(name == _SC_PHYS_PAGES) - return (long)(round_up(ms.dwTotalPhys, 2*MB) / page_size); - // this is 528 KB less than it should be on Win2k and WinXP. - // is it DOS low mem? mem command shows more free, though. - else - return (long)(ms.dwAvailPhys / page_size); + return (long)(round_up((uintptr_t)ms.ullTotalPhys, 2*MB) / page_size); + // Richter, "Programming Applications for Windows": + // reported value doesn't include non-paged pool reserved + // during boot; it's not considered available to kernel. + // it's 528 KB on my 512 MB machine (WinXP and Win2k). + else + return (long)(ms.ullAvailPhys / page_size); + } default: return -1; diff --git a/source/lib/sysdep/win/wsdl.cpp b/source/lib/sysdep/win/wsdl.cpp index e7312adbec..910bad1923 100755 --- a/source/lib/sysdep/win/wsdl.cpp +++ b/source/lib/sysdep/win/wsdl.cpp @@ -17,10 +17,14 @@ * Jan.Wassenberg@stud.uni-karlsruhe.de * http://www.stud.uni-karlsruhe.de/~urkt/ */ + +// TODO: should use GetMessage when not active to reduce CPU load. +// where to do this? +// - force the app to check for SDL's activation messages, and call +// sdl-wait-message? +// - do it here, just make SDL_PollEvent block until message received? -#include -#include -#include +#include "precompiled.h" #include @@ -28,6 +32,7 @@ #include "lib.h" #include "win_internal.h" #include "misc.h" + #include #ifdef _MSC_VER @@ -70,12 +75,6 @@ static LRESULT CALLBACK wndproc(HWND hWnd, unsigned int uMsg, WPARAM wParam, LPA case WM_ERASEBKGND: return 0; - // prevent screensaver / monitor power off - case WM_SYSCOMMAND: - if(wParam == SC_SCREENSAVE || wParam == SC_MONITORPOWER) - return 0; - break; - case WM_ACTIVATE: app_active = (wParam & 0xffff) != 0; @@ -90,6 +89,26 @@ static LRESULT CALLBACK wndproc(HWND hWnd, unsigned int uMsg, WPARAM wParam, LPA case WM_CLOSE: exit(0); + + // prevent moving, sizing, screensaver, and power-off in fullscreen mode + case WM_SYSCOMMAND: + switch(wParam) + { + case SC_MOVE: + case SC_SIZE: + case SC_MAXIMIZE: + case SC_MONITORPOWER: + if(fullscreen) + return 1; + } + break; + + + // prevent selecting menu in fullscreen mode + case WM_NCHITTEST: + if(fullscreen) + return HTCLIENT; + // else: fall through to DefWindowProc } return DefWindowProc(hWnd, uMsg, wParam, lParam); @@ -123,16 +142,8 @@ static void init_vkmap(SDLKey (&VK_keymap)[256]) VK_keymap[VK_OEM_MINUS] = SDLK_MINUS; VK_keymap[VK_OEM_PERIOD] = SDLK_PERIOD; VK_keymap[VK_OEM_2] = SDLK_SLASH; - VK_keymap[VK_0] = SDLK_0; - VK_keymap[VK_1] = SDLK_1; - VK_keymap[VK_2] = SDLK_2; - VK_keymap[VK_3] = SDLK_3; - VK_keymap[VK_4] = SDLK_4; - VK_keymap[VK_5] = SDLK_5; - VK_keymap[VK_6] = SDLK_6; - VK_keymap[VK_7] = SDLK_7; - VK_keymap[VK_8] = SDLK_8; - VK_keymap[VK_9] = SDLK_9; + for(i = 0; i < 10; i++) + VK_keymap[VK_0+i] = (SDLKey)(SDLK_0+i); VK_keymap[VK_OEM_1] = SDLK_SEMICOLON; VK_keymap[VK_OEM_PLUS] = SDLK_EQUALS; VK_keymap[VK_OEM_4] = SDLK_LEFTBRACKET; @@ -140,44 +151,15 @@ static void init_vkmap(SDLKey (&VK_keymap)[256]) VK_keymap[VK_OEM_6] = SDLK_RIGHTBRACKET; VK_keymap[VK_OEM_3] = SDLK_BACKQUOTE; VK_keymap[VK_OEM_8] = SDLK_BACKQUOTE; - VK_keymap[VK_A] = SDLK_a; - VK_keymap[VK_B] = SDLK_b; - VK_keymap[VK_C] = SDLK_c; - VK_keymap[VK_D] = SDLK_d; - VK_keymap[VK_E] = SDLK_e; - VK_keymap[VK_F] = SDLK_f; - VK_keymap[VK_G] = SDLK_g; - VK_keymap[VK_H] = SDLK_h; - VK_keymap[VK_I] = SDLK_i; - VK_keymap[VK_J] = SDLK_j; - VK_keymap[VK_K] = SDLK_k; - VK_keymap[VK_L] = SDLK_l; - VK_keymap[VK_M] = SDLK_m; - VK_keymap[VK_N] = SDLK_n; - VK_keymap[VK_O] = SDLK_o; - VK_keymap[VK_P] = SDLK_p; - VK_keymap[VK_Q] = SDLK_q; - VK_keymap[VK_R] = SDLK_r; - VK_keymap[VK_S] = SDLK_s; - VK_keymap[VK_T] = SDLK_t; - VK_keymap[VK_U] = SDLK_u; - VK_keymap[VK_V] = SDLK_v; - VK_keymap[VK_W] = SDLK_w; - VK_keymap[VK_X] = SDLK_x; - VK_keymap[VK_Y] = SDLK_y; - VK_keymap[VK_Z] = SDLK_z; + + for(i = 0; i < 26; i++) + VK_keymap[VK_A+i] = (SDLKey)(SDLK_a+i); + VK_keymap[VK_DELETE] = SDLK_DELETE; - VK_keymap[VK_NUMPAD0] = SDLK_KP0; - VK_keymap[VK_NUMPAD1] = SDLK_KP1; - VK_keymap[VK_NUMPAD2] = SDLK_KP2; - VK_keymap[VK_NUMPAD3] = SDLK_KP3; - VK_keymap[VK_NUMPAD4] = SDLK_KP4; - VK_keymap[VK_NUMPAD5] = SDLK_KP5; - VK_keymap[VK_NUMPAD6] = SDLK_KP6; - VK_keymap[VK_NUMPAD7] = SDLK_KP7; - VK_keymap[VK_NUMPAD8] = SDLK_KP8; - VK_keymap[VK_NUMPAD9] = SDLK_KP9; + for(i = 0; i < 10; i++) + VK_keymap[VK_NUMPAD0+i] = (SDLKey)(SDLK_KP0+i); + VK_keymap[VK_DECIMAL] = SDLK_KP_PERIOD; VK_keymap[VK_DIVIDE] = SDLK_KP_DIVIDE; VK_keymap[VK_MULTIPLY] = SDLK_KP_MULTIPLY; @@ -194,21 +176,8 @@ static void init_vkmap(SDLKey (&VK_keymap)[256]) VK_keymap[VK_PRIOR] = SDLK_PAGEUP; VK_keymap[VK_NEXT] = SDLK_PAGEDOWN; - VK_keymap[VK_F1] = SDLK_F1; - VK_keymap[VK_F2] = SDLK_F2; - VK_keymap[VK_F3] = SDLK_F3; - VK_keymap[VK_F4] = SDLK_F4; - VK_keymap[VK_F5] = SDLK_F5; - VK_keymap[VK_F6] = SDLK_F6; - VK_keymap[VK_F7] = SDLK_F7; - VK_keymap[VK_F8] = SDLK_F8; - VK_keymap[VK_F9] = SDLK_F9; - VK_keymap[VK_F10] = SDLK_F10; - VK_keymap[VK_F11] = SDLK_F11; - VK_keymap[VK_F12] = SDLK_F12; - VK_keymap[VK_F13] = SDLK_F13; - VK_keymap[VK_F14] = SDLK_F14; - VK_keymap[VK_F15] = SDLK_F15; + for(i = 0; i < 12; i++) + VK_keymap[VK_F1+i] = (SDLKey)(SDLK_F1+i); VK_keymap[VK_NUMLOCK] = SDLK_NUMLOCK; VK_keymap[VK_CAPITAL] = SDLK_CAPSLOCK; @@ -275,7 +244,7 @@ return_char: return 1; } else - assert(0 && "SDL_PollEvent: next_char_idx invalid"); + debug_warn("SDL_PollEvent: next_char_idx invalid"); } diff --git a/source/lib/sysdep/x.cpp b/source/lib/sysdep/x.cpp index 4a80ded860..181cb9aa76 100755 --- a/source/lib/sysdep/x.cpp +++ b/source/lib/sysdep/x.cpp @@ -15,6 +15,8 @@ // Jan.Wassenberg@stud.uni-karlsruhe.de // http://www.stud.uni-karlsruhe.de/~urkt/ +#include "precompiled.h" + #ifdef HAVE_X #include @@ -38,7 +40,7 @@ int get_cur_resolution(int& xres, int& yres) // useful for determining aspect ratio. not called by detect(). // if we fail, outputs are unchanged (assumed initialized to defaults) -int get_monitor_size(int& width_cm, int& height_cm) +int get_monitor_size(int& width_mm, int& height_mm) { return -1; } diff --git a/source/lib/timer.cpp b/source/lib/timer.cpp index 183db4dd43..f925da2c67 100755 --- a/source/lib/timer.cpp +++ b/source/lib/timer.cpp @@ -15,7 +15,7 @@ // Jan.Wassenberg@stud.uni-karlsruhe.de // http://www.stud.uni-karlsruhe.de/~urkt/ -#include +#include "precompiled.h" #include "timer.h" #include "types.h"