commit 8c002299dd041605ea6dcafcdb51037833a5d808 Author: Maksymilian WilczyƄski Date: Sat Aug 16 16:07:43 2025 +0200 working, windows diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..58be050 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,6 @@ +{ + "files.associations": { + "cstdio": "cpp", + "chrono": "cpp" + } +} \ No newline at end of file diff --git a/.vscode/tasks.json b/.vscode/tasks.json new file mode 100644 index 0000000..6532339 --- /dev/null +++ b/.vscode/tasks.json @@ -0,0 +1,28 @@ +{ + "tasks": [ + { + "type": "cppbuild", + "label": "C/C++: cl.exe build active file", + "command": "cl.exe", + "args": [ + "/Zi", + "/EHsc", + "/nologo", + "/Fe${fileDirname}\\${fileBasenameNoExtension}.exe", + "${file}" + ], + "options": { + "cwd": "${fileDirname}" + }, + "problemMatcher": [ + "$msCompile" + ], + "group": { + "kind": "build", + "isDefault": true + }, + "detail": "Task generated by Debugger." + } + ], + "version": "2.0.0" +} \ No newline at end of file diff --git a/bink.h b/bink.h new file mode 100644 index 0000000..6a0b50b --- /dev/null +++ b/bink.h @@ -0,0 +1,1075 @@ +#ifndef __BINKH__ +#define __BINKH__ + +#ifndef EXPMACRO +#define EXPMACRO +#endif + +#ifndef EXPGROUP +#define EXPGROUP(dummy) +#endif + +EXPGROUP(_NullGroup) +#define BinkDate "2014-04-03" EXPMACRO + +#define Bink2Version "2.4d" +#define Bink2MajorVersion 2 +#define Bink2MinorVersion 4 +#define Bink2BuildNumber 3 +#define Bink2Customization 0 + +#define Bink1Version "1.994d" EXPMACRO +#define Bink1MajorVersion 1 EXPMACRO +#define Bink1MinorVersion 999 EXPMACRO +#define Bink1BuildNumber 4 EXPMACRO +#define Bink1Customization 3 EXPMACRO + +#define BinkVersion "2.4d/1.994d" EXPMACRO +#define BinkMajorVersion 0 EXPMACRO +#define BinkMinorVersion 4 EXPMACRO +#define BinkBuildNumber 3 EXPMACRO +#define BinkCustomization 0 EXPMACRO + +EXPGROUP(_RootGroup) + + + +#ifndef __RADRES__ + +#ifndef __RADRR_COREH__ +#include "rrCore.h" +#endif + +RADDEFSTART + +#if defined(BINKUDK) || (defined(UDK) && UDK == 1) + #undef RADEXPFUNC + #define RADEXPFUNC RADDEFFUNC + + #define BinkOpen BinkOpenUDK + #define BinkDoFrame BinkDoFrameUDK +#endif + +typedef struct BINK * HBINK; + +struct BINKIO; +typedef S32 (RADLINK * BINKIOOPEN) (struct BINKIO * Bnkio, const char *name, U32 flags); +typedef U32 (RADLINK * BINKIOREADHEADER) (struct BINKIO * Bnkio, S32 Offset, void * Dest,U32 Size); +typedef U32 (RADLINK * BINKIOREADFRAME) (struct BINKIO * Bnkio, U32 Framenum,S32 origofs,void * dest,U32 size); +typedef U32 (RADLINK * BINKIOGETBUFFERSIZE)(struct BINKIO * Bnkio, U32 Size); +typedef void (RADLINK * BINKIOSETINFO) (struct BINKIO * Bnkio, void * Buf,U32 Size,U32 FileSize,U32 simulate); +typedef U32 (RADLINK * BINKIOIDLE) (struct BINKIO * Bnkio); +typedef void (RADLINK * BINKIOCLOSE) (struct BINKIO * Bnkio); +typedef S32 (RADLINK * BINKIOBGCONTROL) (struct BINKIO * Bnkio, U32 Control); + +typedef void (RADLINK * BINKCBSUSPEND) (struct BINKIO * Bnkio); +typedef S32 (RADLINK * BINKCBTRYSUSPEND) (struct BINKIO * Bnkio); +typedef void (RADLINK * BINKCBRESUME) (struct BINKIO * Bnkio); +typedef void (RADLINK * BINKCBIDLE) (struct BINKIO * Bnkio); +typedef void (RADLINK * BINKCBSIMULATE) (struct BINKIO * Bnkio, U32 amt, U32 timer ); +typedef U32 (RADLINK * BINKCBTIMER) ( void ); +typedef void (RADLINK * BINKCBFLIPENDIAN) ( void * ptr, U32 size ); +typedef U32 (RADLINK * BINKCBLOCKEDADD) ( U32 volatile * ptr, S32 amt ); + +typedef struct BINKIO { + BINKIOREADHEADER ReadHeader; + BINKIOREADFRAME ReadFrame; + BINKIOGETBUFFERSIZE GetBufferSize; + BINKIOSETINFO SetInfo; + + BINKIOIDLE Idle; + BINKIOCLOSE Close; + BINKIOBGCONTROL BGControl; + HBINK bink; + + // filled in by the bink + BINKCBSUSPEND suspend_callback; + BINKCBTRYSUSPEND try_suspend_callback; + BINKCBRESUME resume_callback; + BINKCBIDLE idle_on_callback; + + BINKCBSIMULATE simulate_callback; + BINKCBTIMER timer_callback; + BINKCBFLIPENDIAN flipendian_callback; + BINKCBLOCKEDADD lockedadd_callback; + + volatile U32 ReadError; + volatile U32 DoingARead; + volatile U32 BytesRead; + volatile U32 Working; + + volatile U32 TotalTime; + volatile U32 ForegroundTime; + volatile U32 IdleTime; + volatile U32 ThreadTime; + + volatile U32 BufSize; + volatile U32 BufHighUsed; + volatile U32 CurBufSize; + volatile U32 CurBufUsed; + + volatile U32 Suspended; + U32 align[ 3 ]; + + volatile U8 iodata[128+32]; +} BINKIO; + +struct BINKSND; +typedef S32 (RADLINK * BINKSNDOPEN) (struct BINKSND * BnkSnd, U32 freq, S32 bits, S32 chans, U32 flags, HBINK bink); +typedef S32 (RADLINK * BINKSNDREADY) (struct BINKSND * BnkSnd); +typedef S32 (RADLINK * BINKSNDLOCK) (struct BINKSND * BnkSnd, U8 * * addr, U32 * len); +typedef S32 (RADLINK * BINKSNDUNLOCK) (struct BINKSND * BnkSnd, U32 filled); +typedef void (RADLINK * BINKSNDVOLUME) (struct BINKSND * BnkSnd, S32 volume); +typedef void (RADLINK * BINKSNDPAN) (struct BINKSND * BnkSnd, S32 pan); +typedef void (RADLINK * BINKSNDSPKOUTVOLS) (struct BINKSND * BnkSnd, F32 * volumes, U32 total ); +typedef S32 (RADLINK * BINKSNDONOFF) (struct BINKSND * BnkSnd, S32 status); +typedef S32 (RADLINK * BINKSNDPAUSE) (struct BINKSND * BnkSnd, S32 status); +typedef void (RADLINK * BINKSNDCLOSE) (struct BINKSND * BnkSnd); +typedef S32 (RADLINK * BINKSNDPROP) (struct BINKSND * BnkSnd, S32 prop, UINTa* value); + +typedef U32 (RADLINK * BINKTIMERREAD) (void); +RADEXPFUNC void RADEXPLINK BinkSetTimerRead( BINKTIMERREAD uread ); + +typedef BINKSNDOPEN (RADLINK * BINKSNDSYSOPEN) (UINTa param); +typedef BINKSNDOPEN (RADLINK * BINKSNDSYSOPEN2) (UINTa param1, UINTa param2); + +typedef struct BINKSND { + // for the spu, we *send* through sndreadpos, but we only return sndwritepos + U8 * sndwritepos; // current write position + + U32 audiodecompsize; + + U32 sndbufsize; // sound buffer size + U8 * sndbuf; // sound buffer + U8 * sndend; // end of the sound buffer + UINTa sndcomp; // sound compression handle + + U8 * sndreadpos; // current read position + +#if defined( BINK_SPU_PROCESS ) + struct binksnd_hide // put variables that we don't want to accidentally + { // use on the spu into a structure +#endif + U32 orig_freq; + U32 freq; + S32 bits,chans; + + S32 BestSizeIn16; + U32 BestSizeMask; + S32 OnOff; + U32 Latency; + U32 VideoScale; + + U32 sndendframe; // frame number that the sound ends on + + U32 sndpad; // padded this much audio + S32 sndprime; // amount of data to prime the playahead + + S32 ThreadServiceType; // 0 = normal (calls ready/lock/unlock for each BINKSND) + // -num = global (calls unlock and expects the sound handler + // to mix *all* BINKSNDS) "num" is how often to call + // unlock, for example "-5" is every 5 ms) + // 1 = No background thread processing at all (sound system + // will do it's own threading) + // 2 = No background thread processing at all, but setup + // thread mutexes, so that BinkServiceSound() can be + // call from an external background thread. + + U32 SoundDroppedOut; + U32 sndconvert8; // convert back to 8-bit sound at runtime + U8 snddata[256]; + + //UINTa align; + + BINKSNDREADY Ready; + BINKSNDLOCK Lock; + BINKSNDUNLOCK Unlock; + BINKSNDVOLUME Volume; + BINKSNDPAN Pan; + BINKSNDPAUSE Pause; + BINKSNDONOFF SetOnOff; + BINKSNDCLOSE Close; + BINKSNDSPKOUTVOLS SpeakerVols; + BINKSNDPROP Property; +#if defined( BINK_SPU_PROCESS ) + } spu_hide; +#endif + +} BINKSND; + +typedef struct BINKRECT { + S32 Left,Top,Width,Height; +} BINKRECT; + +#define BINKMAXDIRTYRECTS 8 + +typedef struct BUNDLEPOINTERS { + void* typeptr; + void* type16ptr; + void* colorptr; + void* bits2ptr; + + void* motionXptr; + void* motionYptr; + void* dctptr; + void* mdctptr; + + void* patptr; +} BUNDLEPOINTERS; + +typedef struct BINKPLANE +{ + S32 Allocate; + void * Buffer; + U32 BufferPitch; +} BINKPLANE; + +typedef struct BINKFRAMEPLANESET +{ + BINKPLANE YPlane; + BINKPLANE cRPlane; + BINKPLANE cBPlane; + BINKPLANE APlane; +} BINKFRAMEPLANESET; + +#define BINKMAXFRAMEBUFFERS 2 + +typedef struct BINKFRAMEBUFFERS +{ + S32 TotalFrames; + U32 YABufferWidth; + U32 YABufferHeight; + U32 cRcBBufferWidth; + U32 cRcBBufferHeight; + + U32 FrameNum; + BINKFRAMEPLANESET Frames[ BINKMAXFRAMEBUFFERS ]; +} BINKFRAMEBUFFERS; + +#define BINKMAXPLANES 4 +#define BINKMAXSLICES 13 + +typedef struct BINKGPUDATABUFFERS BINKGPUDATABUFFERS; + +#ifdef __RAD3DS__ + +typedef struct BINKSWIZZLEBUFFERS +{ + U32 Width; + U32 Height; + U8* YBuffer; + U8* ABuffer; + U8* cRBuffer; + U8* cBBuffer; +} BINKSWIZZLEBUFFERS; + +#endif + +typedef struct BINKSLICES +{ + U32 slice_inc; + U32 slice_count; + U32 slice_pitch; + U32 slices[BINKMAXSLICES]; +} BINKSLICES; + +typedef struct BINK { + U32 Width; // Width (1 based, 640 for example) + U32 Height; // Height (1 based, 480 for example) + U32 Frames; // Number of frames (1 based, 100 = 100 frames) + U32 FrameNum; // Frame to *be* displayed (1 based) + + U32 LastFrameNum; // Last frame decompressed or skipped (1 based) + U32 FrameRate; // Frame Rate Numerator + U32 FrameRateDiv; // Frame Rate Divisor (frame rate=numerator/divisor) + U32 ReadError; // Non-zero if a read error has ocurred + + U32 OpenFlags; // flags used on open + U32 BinkType; // Bink flags + U32 Size; // size of file + U32 FrameSize; // The current frame's size in bytes + + U32 SndSize; // The current frame sound tracks' size in bytes + U32 FrameChangePercent; // very rough percentage of the frame that changed + S32 NumTracks; // how many tracks + S32 NumRects; + + U32 soundon; // sound turned on? + U32 videoon; // video turned on? + U32 needio; // set to 1, if we need an io before the next binkframe + S32 closing; // are we closing? + + BINKRECT FrameRects[BINKMAXDIRTYRECTS];// Dirty rects from BinkGetRects + + U64 FileOffset; // Offset into the file where the Bink starts + U32 Highest1SecRate; // Highest 1 sec data rate + U32 Highest1SecFrame; // Highest 1 sec data rate starting frame + + BINKFRAMEBUFFERS * FrameBuffers; // Bink frame buffers that we decompress to + void * MaskPlane; // pointer to the mask plane (Ywidth/16*Yheight/16) + void * AsyncMaskPlane; // pointer to the mask plane for async data + void * InUseMaskPlane; // pointer to the mask plane in use + + // everything below is for internal Bink use + + void * LastMaskPlane; // pointer to the last mask plane + struct BINK * next_bink; // linked list of open binks that are being access from threads + void * compframe; // compressed frame data + S32 * trackindexes; // track indexes + + U32 MaskPitch; // Mask Pitch + U32 MaskLength; // total length of the mask plane + U32 LargestFrameSize; // Largest frame size + U32 InternalFrames; // how many frames were potentially compressed + + S32 async_in_progress[8]; // is an async decompression in progress + + U32 marker; + S32 Paused; // is the bink movie paused? + U32 skippedlastblit; // skipped last frame? + U32 align; + + BINKSLICES slices; + + U32 compframesize; // compressed frame size + U32 compframekey; // if this frame a key frame + U32 playingtracks; // how many tracks are playing + U32 changepercent; // how much roughly did the current frame change? + + BUNDLEPOINTERS bunp; // pointers to internal temporary memory + + // we are at ptr ofs 1 here (bunp has 9 ptrs) + BINKSND * bsnd; // SND structures + + BINKGPUDATABUFFERS * gpu; // pointer to gpu data pointers + +#if defined( BINK_SPU_PROCESS ) + struct bink_hide // put variables that we don't want to accidentally + { // use on the spu into a structure +#endif + + // now we are at ptr ofs 3 here + U32* frameoffsets; // offsets of each of the frames + + U32 bink_unique; // number + S32 in_bink_list; // is this bink in the linked list? + U32 decompwidth; // width not include scaling + U32 decompheight; // height not include scaling + + U32 * tracksizes; // largest single frame of track + U32 * tracktypes; // type of each sound track + S32 * trackIDs; // external track numbers + void * preloadptr; // preloaded compressed frame data + + S32 simulate; // simulate speed variables + S32 adjustsim; + U32 compframeoffset; // compressed frame offset + U32 compframenum; // frame to background load + + BINKIO bio; // IO structure + + U8 pri_io_mutex[ 128 ]; // taken when priority io in progress + + U8 io_mutex[ 128 ]; // taken when background io in progress + + U8 snd_mutex[ 128 ]; // taken when background snd in progress + + U8 * ioptr; // io buffer ptr + U32 * rtframetimes; // start times for runtime frames + U32 * rtadecomptimes; // decompress times for runtime frames + U32 * rtvdecomptimes; // decompress times for runtime frames + + U32 * rtblittimes; // blit times for runtime frames + U32 * rtreadtimes; // read times for runtime frames + U32 * rtidlereadtimes; // idle read times for runtime frames + U32 * rtthreadreadtimes; // thread read times for runtime frames + + U32 runtimeframes; // max frames for runtime analysis + S32 rtindex; // index of where we are in the runtime frames + U32 iosize; // io buffer size + U32 numrects; // number of rects from BinkGetRects + + U32 playedframes; // how many frames have we played + U32 firstframetime; // very first frame start + U32 totalmem; // total memory used + U32 soundskips; // number of sound stops + + U32 startblittime; // start of blit period + U32 startsynctime; // start of synched time + U32 startsyncframe; // frame of startsynctime + U32 twoframestime; // two frames worth of time + + U32 slowestframetime; // slowest frame in ms + U32 slowestframe; // slowest frame number + U32 slowest2frametime; // second slowest frame in ms + U32 slowest2frame; // second slowest frame + + U32 timevdecomp; // total time decompressing video + U32 timeadecomp; // total time decompressing audio + U32 timeblit; // total time blitting + U32 timeopen; // total open time + + U32 fileframerate; // frame rate originally in the file + U32 fileframeratediv; + U32 lastblitflags; // flags used on last blit + U32 lastdecompframe; // last frame number decompressed + + U32 lastfinisheddoframe; // time that the last do frame finished + U32 lastresynctime; // last loop point that we did a resync on + U32 doresync; // should we do a resync in the next doframe? + U32 skipped_status_this_frame;//0=not checked this frame, 1=no skip, 2=skip + + U32 very_delayed; // is this frame more than 725 ms late? + U32 skippedblits; // how many blits were skipped + U32 skipped_in_a_row; // how many frames have we skipped in a row + U32 paused_sync_diff; // sync delta at the time of a pause + + U32 last_time_almost_empty; // time of last almost empty IO buffer + S32 allkeys; // are all frames keyframes? + U32 lastfileread; // last place we read binkfile + U32 limit_speakers; + + void * alloccompframe; // compressed frame data base address + BINKFRAMEBUFFERS * allocatedframebuffers; // pointer to internally allocated buffers + void * seam; + void * binkaudiomem; // memory for the bink audio structures + + void * opt_ptr; + U32 opt_bytes; + +#if defined(__RAD3DS__) + BINKSWIZZLEBUFFERS* swizzle_buffers; +#endif + +#if defined( BINK_SPU_PROCESS ) + } spu_hide; +#endif +} BINK; + + +typedef struct BINKSUMMARY { + U32 Width; // Width of frames + U32 Height; // Height of frames + U32 TotalTime; // total time (ms) + U32 FileFrameRate; // frame rate + U32 FileFrameRateDiv; // frame rate divisor + U32 FrameRate; // frame rate + U32 FrameRateDiv; // frame rate divisor + U32 TotalOpenTime; // Time to open and prepare for decompression + U32 TotalFrames; // Total Frames + U32 TotalPlayedFrames; // Total Frames played + U32 SkippedFrames; // Total number of skipped frames + U32 SkippedBlits; // Total number of skipped blits + U32 SoundSkips; // Total number of sound skips + U32 TotalBlitTime; // Total time spent blitting + U32 TotalReadTime; // Total time spent reading + U32 TotalVideoDecompTime; // Total time spent decompressing video + U32 TotalAudioDecompTime; // Total time spent decompressing audio + U32 TotalIdleReadTime; // Total time spent reading while idle + U32 TotalBackReadTime; // Total time spent reading in background + U32 TotalReadSpeed; // Total io speed (bytes/second) + U32 SlowestFrameTime; // Slowest single frame time (ms) + U32 Slowest2FrameTime; // Second slowest single frame time (ms) + U32 SlowestFrameNum; // Slowest single frame number + U32 Slowest2FrameNum; // Second slowest single frame number + U32 AverageDataRate; // Average data rate of the movie + U32 AverageFrameSize; // Average size of the frame + U32 HighestMemAmount; // Highest amount of memory allocated + U32 TotalIOMemory; // Total extra memory allocated + U32 HighestIOUsed; // Highest extra memory actually used + U32 Highest1SecRate; // Highest 1 second rate + U32 Highest1SecFrame; // Highest 1 second start frame +} BINKSUMMARY; + + +typedef struct BINKREALTIME { + U32 FrameNum; // Current frame number + U32 FrameRate; // frame rate + U32 FrameRateDiv; // frame rate divisor + U32 Frames; // frames in this sample period + U32 FramesTime; // time is ms for these frames + U32 FramesVideoDecompTime; // time decompressing these frames + U32 FramesAudioDecompTime; // time decompressing these frames + U32 FramesReadTime; // time reading these frames + U32 FramesIdleReadTime; // time reading these frames at idle + U32 FramesThreadReadTime; // time reading these frames in background + U32 FramesBlitTime; // time blitting these frames + U32 ReadBufferSize; // size of read buffer + U32 ReadBufferUsed; // amount of read buffer currently used + U32 FramesDataRate; // data rate for these frames +} BINKREALTIME; + +#define BINKMARKER1 'fKIB' +#define BINKMARKER2 'gKIB' // new Bink files use this tag +#define BINKMARKER3 'hKIB' // newer Bink files use this tag +#define BINKMARKER4 'iKIB' // even newer Bink files use this tag + +#define BINKMARKERV2 'f2BK' +#define BINKMARKERV22 'g2BK' // bink 2.2 +#define BINKMARKERV23 'h2BK' // bink 2.3 +#define BINKMARKERV23D 'i2BK' // bink 2.3d version + +typedef struct BINKHDR { + U32 Marker; // Bink marker + U32 Size; // size of the file-8 + U32 Frames; // Number of frames (1 based, 100 = 100 frames) + U32 LargestFrameSize; // Size in bytes of largest frame + U32 InternalFrames; // Number of internal frames + + U32 Width; // Width (1 based, 640 for example) + U32 Height; // Height (1 based, 480 for example) + U32 FrameRate; // frame rate + U32 FrameRateDiv; // frame rate divisor (framerate/frameratediv=fps) + + U32 Flags; // bink flags + U32 NumTracks; // number of tracks +} BINKHDR; + + +typedef struct BINK_OPEN_OPTIONS +{ + U64 FileOffset; + S32 ForceRate; + S32 ForceRateDiv; + S32 IOBufferSize; + S32 Simulate; + U32 TotTracks; + S32 * TrackNums; + BINKIOOPEN UserOpen; +} BINK_OPEN_OPTIONS; + +//======================================================================= +#define BINKYAINVERT 0x00000800L // Reverse Y and A planes when blitting (for debugging) +#define BINKFRAMERATE 0x00001000L // Override fr (call BinkFrameRate first) +#define BINKPRELOADALL 0x00002000L // Preload the entire animation +#define BINKSNDTRACK 0x00004000L // Set the track number to play +#define BINKOLDFRAMEFORMAT 0x00008000L // using the old Bink frame format (internal use only) +#define BINKRBINVERT 0x00010000L // use reversed R and B planes (internal use only) +#define BINKGRAYSCALE 0x00020000L // Force Bink to use grayscale +//#define BINKNOMMX 0x00040000L // Don't use MMX +#define BINKNOSKIP 0x00080000L // Don't skip frames if falling behind +#define BINKALPHA 0x00100000L // Decompress alpha plane (if present) +#define BINKNOFILLIOBUF 0x00200000L // Don't Fill the IO buffer (in BinkOpen and BinkCopyTo) +#define BINKSIMULATE 0x00400000L // Simulate the speed (call BinkSim first) +#define BINKFILEHANDLE 0x00800000L // Use when passing in a file handle +#define BINKIOSIZE 0x01000000L // Set an io size (call BinkIOSize first) +#define BINKIOPROCESSOR 0x02000000L // Set an io processor (call BinkIO first) +#define BINKFROMMEMORY 0x04000000L // Use when passing in a pointer to the file +#define BINKNOTHREADEDIO 0x08000000L // Don't use a background thread for IO +#define BINKNOFRAMEBUFFERS 0x00000400L // Don't allocate internal frame buffers - application must call BinkRegisterFrameBuffers +#define BINKNOYPLANE 0x00000200L // Don't decompress the Y plane (internal flag) +#define BINKGPU 0x00000100L // Open Bink in GPU mode +#define BINKWILLLOOP 0x00000080L // You are planning to loop this Bink. +#define BINKDONTCLOSETHREADS 0x00000040L // Don't close threads on BinkClose (call BinkFreeGlobals to close threads) +#define BINKFILEOFFSET 0x00000020L // Use file offset specified by BinkSetFileOffset +#define BINKYCRCBNEW 0x00000010L // File uses the new ycrcb colorspace (usually Bink 2) +#define BINK_SLICES_2 0x00000000L // Bink 2 file has two slices +#define BINK_SLICES_3 0x00000001L // Bink 2 file has three slices +#define BINK_SLICES_4 0x00000002L // Bink 2 file has four slices +#define BINK_SLICES_8 0x00000003L // Bink 2 file has eight slices +#define BINK_SLICES_MASK 0x00000003L // mask against openflags to get the slice flags + +#define BINKSURFACEFAST 0x00000000L +#define BINKSURFACESLOW 0x08000000L +#define BINKSURFACEDIRECT 0x04000000L + +#define BINKCOPYALL 0x80000000L // copy all pixels (not just changed) +#define BINKCOPY2XH 0x10000000L // Force doubling height scaling +#define BINKCOPY2XHI 0x20000000L // Force interleaving height scaling +#define BINKCOPY2XW 0x30000000L // copy the width zoomed by two +#define BINKCOPY2XWH 0x40000000L // copy the width and height zoomed by two +#define BINKCOPY2XWHI 0x50000000L // copy the width and height zoomed by two +#define BINKCOPY1XI 0x60000000L // copy the width and height zoomed by two +#define BINKCOPYNOSCALING 0x70000000L // Force scaling off + +//#define BINKNOFILLIOBUF 0x00200000L // Don't Fill the IO buffer (in BinkOpen and BinkCopyTo) +//#define BINKALPHA 0x00100000L // Decompress alpha plane (if present) +//#define BINKNOSKIP 0x00080000L // don't skip the blit if behind in sound +//#define BINKNOMMX 0x00040000L // No MMX +//#define BINKGRAYSCALE 0x00020000L // force Bink to use grayscale +//#define BINKRBINVERT 0x00010000L // use reversed R and B planes + +#define BINKSURFACEP8 0 +#define BINKSURFACE24 1 +#define BINKSURFACE24R 2 +#define BINKSURFACE32 3 +#define BINKSURFACE32R 4 +#define BINKSURFACE32A 5 +#define BINKSURFACE32RA 6 +#define BINKSURFACE4444 7 +#define BINKSURFACE5551 8 +#define BINKSURFACE555 9 +#define BINKSURFACE565 10 +#define BINKSURFACE655 11 +#define BINKSURFACE664 12 +#define BINKSURFACEYUY2 13 +#define BINKSURFACEUYVY 14 +#define BINKSURFACEYV12 15 +#define BINKSURFACEMASK 15 + +#define BINKGOTOQUICK 1 +#define BINKGOTOQUICKSOUND 2 + +#define BINKGETKEYPREVIOUS 0 +#define BINKGETKEYNEXT 1 +#define BINKGETKEYCLOSEST 2 +#define BINKGETKEYNOTEQUAL 128 + +#define BINKDOFRAMEALL 1 +#define BINKDOFRAMEHALF 2 +#define BINKDOFRAMETHIRD 3 +#define BINKDOFRAMEFOURTH 4 +#define BINKDOFRAMEEIGHTH 5 +#define BINKDOFRAMESTART 256 +#define BINKDOFRAMEEND 512 + +#define BINKPLATFORMSOUNDTHREAD 1 +#define BINKPLATFORMIOTHREAD 2 +#define BINKPLATFORMSUBMITTHREADCOUNT 3 +#define BINKPLATFORMSUBMITTHREADS 4 + +#ifdef __RADIPHONE__ + #define BINKPLATFORMIOSINTERRUPTEND 5 +#endif + +#define BINKPLATFORMASYNCTHREADS 1024 // +0 to 7 for which async + +//======================================================================= + +#ifdef __RADNDS__ + RADEXPFUNC HBINK RADEXPLINK BinkNDSOpen(void /*FSFileID*/ * fid,U32 flags); +#endif + +RADEXPFUNC void * RADEXPLINK BinkLogoAddress(void); + +RADEXPFUNC void RADEXPLINK BinkSetError(char const * err); +RADEXPFUNC char * RADEXPLINK BinkGetError(void); + +RADEXPFUNC HBINK RADEXPLINK BinkOpen(char const * name,U32 flags); +RADEXPFUNC HBINK RADEXPLINK BinkOpenWithOptions(char const * name, BINK_OPEN_OPTIONS const * boo,U32 flags); + +RADEXPFUNC void RADEXPLINK BinkGetFrameBuffersInfo( HBINK bink, BINKFRAMEBUFFERS * fbset ); +RADEXPFUNC void RADEXPLINK BinkRegisterFrameBuffers( HBINK bink, BINKFRAMEBUFFERS * fbset ); +#ifdef __RAD3DS__ +RADEXPFUNC void RADEXPLINK BinkRegisterSwizzleBuffers( HBINK bink, BINKSWIZZLEBUFFERS* swizzle_buffers); +#endif +RADEXPFUNC S32 RADEXPLINK BinkDoFrame(HBINK bnk); +RADEXPFUNC S32 RADEXPLINK BinkDoFramePlane(HBINK bnk,U32 which_planes); +RADEXPFUNC void RADEXPLINK BinkNextFrame(HBINK bnk); +RADEXPFUNC S32 RADEXPLINK BinkWait(HBINK bnk); +RADEXPFUNC void RADEXPLINK BinkClose(HBINK bnk); +RADEXPFUNC S32 RADEXPLINK BinkPause(HBINK bnk,S32 pause); +RADEXPFUNC S32 RADEXPLINK BinkCopyToBuffer(HBINK bnk,void* dest,S32 destpitch,U32 destheight,U32 destx,U32 desty,U32 flags); +RADEXPFUNC S32 RADEXPLINK BinkCopyToBufferRect(HBINK bnk,void* dest,S32 destpitch,U32 destheight,U32 destx,U32 desty,U32 srcx, U32 srcy, U32 srcw, U32 srch, U32 flags); +RADEXPFUNC S32 RADEXPLINK BinkGetRects(HBINK bnk,U32 flags); +RADEXPFUNC void RADEXPLINK BinkGoto(HBINK bnk,U32 frame,S32 flags); // use 1 for the first frame +RADEXPFUNC U32 RADEXPLINK BinkGetKeyFrame(HBINK bnk,U32 frame,S32 flags); +RADEXPFUNC void RADEXPLINK BinkFreeGlobals( void ); +RADEXPFUNC S32 RADEXPLINK BinkGetPlatformInfo( S32 bink_platform_enum, void * output ); +RADEXPFUNC void RADEXPLINK BinkRegisterGPUDataBuffers( HBINK bink, BINKGPUDATABUFFERS * gpu ); +RADEXPFUNC S32 RADEXPLINK BinkGetGPUDataBuffersInfo( HBINK bink, BINKGPUDATABUFFERS * gpu ); + +RADEXPFUNC S32 RADEXPLINK BinkSetVideoOnOff(HBINK bnk,S32 onoff); +RADEXPFUNC S32 RADEXPLINK BinkSetSoundOnOff(HBINK bnk,S32 onoff); +RADEXPFUNC void RADEXPLINK BinkSetVolume(HBINK bnk, U32 trackid, S32 volume); +RADEXPFUNC void RADEXPLINK BinkSetPan(HBINK bnk,U32 trackid, S32 pan); +RADEXPFUNC void RADEXPLINK BinkSetSpeakerVolumes(HBINK bnk,U32 trackid, U32 * speaker_indexes, S32 * volumes, U32 total); +#define BinkSetMixBins(bnk,trackid,speaker_indexes,total) BinkSetSpeakerVolumes(bnk,trackid,speaker_indexes,0,total) +#define BinkSetMixBinVolumes(bnk,trackid,speaker_indexes,volumes,total) BinkSetSpeakerVolumes(bnk,trackid,speaker_indexes,volumes,total) +RADEXPFUNC void RADEXPLINK BinkService(HBINK bink); + +RADEXPFUNC S32 RADEXPLINK BinkShouldSkip(HBINK bink); + +RADEXPFUNC void RADEXPLINK BinkGetPalette( void * out_pal ); + +#define BINKBGIOSUSPEND 1 +#define BINKBGIORESUME 2 +#define BINKBGIOWAIT 0x80000000 +#define BINKBGIOTRYWAIT 0x40000000 + +RADEXPFUNC S32 RADEXPLINK BinkControlBackgroundIO(HBINK bink,U32 control); + +RADEXPFUNC void RADEXPLINK BinkSetWillLoop(HBINK bink,S32 onoff); + + +#if !defined( __RAD3DS__ ) && !defined (__RADPS2__) || !defined( __RADNDS__ ) + +RADEXPFUNC S32 RADEXPLINK BinkStartAsyncThread( S32 thread_num, void const * param ); +RADEXPFUNC S32 RADEXPLINK BinkDoFrameAsync(HBINK bink, U32 thread_one, U32 thread_two ); +RADEXPFUNC S32 RADEXPLINK BinkDoFrameAsyncMulti(HBINK bink, U32* threads, S32 thread_count ); +RADEXPFUNC S32 RADEXPLINK BinkDoFrameAsyncWait(HBINK bink, S32 us); +RADEXPFUNC S32 RADEXPLINK BinkRequestStopAsyncThread( S32 thread_num ); +RADEXPFUNC S32 RADEXPLINK BinkWaitStopAsyncThread( S32 thread_num ); + +#endif + +#ifdef __RADBIGENDIAN__ + +RADEXPFUNC void RADEXPLINK BinkFlipEndian32( void * buffer, U32 bytes ); + +#endif + + + +typedef struct BINKTRACK * HBINKTRACK; + +typedef struct BINKTRACK +{ + U32 Frequency; + U32 Bits; + U32 Channels; + U32 MaxSize; + + HBINK bink; + UINTa sndcomp; + S32 trackindex; +} BINKTRACK; + + +RADEXPFUNC HBINKTRACK RADEXPLINK BinkOpenTrack(HBINK bnk,U32 trackindex); +RADEXPFUNC void RADEXPLINK BinkCloseTrack(HBINKTRACK bnkt); +RADEXPFUNC U32 RADEXPLINK BinkGetTrackData(HBINKTRACK bnkt,void * dest); + +RADEXPFUNC U32 RADEXPLINK BinkGetTrackType(HBINK bnk,U32 trackindex); +RADEXPFUNC U32 RADEXPLINK BinkGetTrackMaxSize(HBINK bnk,U32 trackindex); +RADEXPFUNC U32 RADEXPLINK BinkGetTrackID(HBINK bnk,U32 trackindex); + +RADEXPFUNC void RADEXPLINK BinkGetSummary(HBINK bnk,BINKSUMMARY * sum); +RADEXPFUNC void RADEXPLINK BinkGetRealtime(HBINK bink,BINKREALTIME * run,U32 frames); + +RADEXPFUNC void RADEXPLINK BinkSetFileOffset(U64 offset); +RADEXPFUNC void RADEXPLINK BinkSetSoundTrack(U32 total_tracks, U32 * tracks); +RADEXPFUNC void RADEXPLINK BinkSetIO(BINKIOOPEN io); +RADEXPFUNC void RADEXPLINK BinkSetFrameRate(U32 forcerate,U32 forceratediv); +RADEXPFUNC void RADEXPLINK BinkSetSimulate(U32 sim); +RADEXPFUNC void RADEXPLINK BinkSetIOSize(U32 iosize); + +RADEXPFUNC S32 RADEXPLINK BinkSetSoundSystem(BINKSNDSYSOPEN open, UINTa param); +RADEXPFUNC S32 RADEXPLINK BinkSetSoundSystem2(BINKSNDSYSOPEN2 open, UINTa param1, UINTa param2); + +#ifdef __RADX86__ +#define BINK_CPU_MMX 1 +#define BINK_CPU_3DNOW 2 +#define BINK_CPU_SSE 4 +#define BINK_CPU_SSE2 8 +#elif defined( __RADMAC__ ) +#define BINK_CPU_ALTIVEC 1 +#endif + +RADEXPFUNC S32 RADEXPLINK BinkControlPlatformFeatures( S32 use, S32 dont_use ); + +#ifdef __RADWIIU__ + RADEXPFUNC void RADEXPLINK BinkSetWiiUFileClient(void* ptr_to_fsclient); +#endif + +#ifdef __RADIPHONE__ + RADEXPFUNC void RADEXPLINK BinkIOSPostAudioInterruptEnd(); +#endif + +#ifdef __RADANDROID__ + RADEXPFUNC void RADEXPLINK BinkSetAssetManager(void* asset_manager); + + RADEXPFUNC BINKSNDOPEN RADEXPLINK BinkOpenRADSS2(UINTa param1, UINTa param2); // don't call directly + + // To use your own sl engine and global mix, pass in the SLObjectItf to BinkSoundSetSLESPtrs + #define BinkSoundUseSLES(engine_ptr, global_mix_ptr) BinkSetSoundSystem2( BinkOpenRADSS2, (UINTa)(engine_ptr), (UINTa)(global_mix_ptr) ) + +#endif + +#ifdef __RADWIN__ + + RADEXPFUNC BINKSNDOPEN RADEXPLINK BinkOpenDirectSound(UINTa param); // don't call directly + #define BinkSoundUseDirectSound(lpDS) BinkSetSoundSystem(BinkOpenDirectSound,(UINTa)(lpDS)) + + RADEXPFUNC BINKSNDOPEN RADEXPLINK BinkOpenWaveOut(UINTa param); // don't call directly + #define BinkSoundUseWaveOut() BinkSetSoundSystem(BinkOpenWaveOut,0) + +#endif + + + RADEXPFUNC BINKSNDOPEN RADEXPLINK BinkOpenXAudio2(UINTa param); // don't call directly + #define BinkSoundUseXAudio2(IXAudio2_ptr) BinkSetSoundSystem(BinkOpenXAudio2,(UINTa)(IXAudio2_ptr)) + + +#ifndef __RADMAC__ + + RADEXPFUNC BINKSNDOPEN RADEXPLINK BinkOpenMiles(UINTa param); // don't call directly + #define BinkSoundUseMiles(hdigdriver) BinkSetSoundSystem(BinkOpenMiles,(UINTa)(hdigdriver)) + +#endif + +#ifdef __RADIPHONE__ + + RADEXPFUNC BINKSNDOPEN RADEXPLINK BinkOpenRADSS(UINTa param); // don't call directly + #define BinkSoundUseCoreAudio() BinkSetSoundSystem(BinkOpenRADSS, 0); + +#endif + +#ifdef __RADMAC__ + + RADEXPFUNC BINKSNDOPEN RADEXPLINK BinkOpenSoundManager(UINTa param); // don't call directly + #define BinkSoundUseSoundManager() BinkSetSoundSystem(BinkOpenSoundManager,0) + + RADEXPFUNC BINKSNDOPEN RADEXPLINK BinkOpenRADSS(UINTa param); // don't call directly + #define BinkSoundUseCoreAudio() BinkSetSoundSystem(BinkOpenRADSS,0) + +#endif + +#ifdef __RADLINUX__ + + RADEXPFUNC BINKSNDOPEN RADEXPLINK BinkOpenRADSS(UINTa param); // don't call directly + #define BinkSoundUseOpenAL() BinkSetSoundSystem(BinkOpenRADSS,0) + +#endif + +#if defined( __RADNGC__ ) || defined( __RADWII__ ) + + typedef void * (RADLINK * RADARAMALLOC) ( U32 num_bytes ); + typedef void (RADLINK * RADARAMFREE) ( void * ptr ); + + typedef struct RADARAMCALLBACKS + { + RADARAMALLOC aram_malloc; + RADARAMFREE aram_free; + } RADARAMCALLBACKS; + + RADEXPFUNC BINKSNDOPEN RADEXPLINK BinkOpenAX(U32 param); // don't call directly + #define BinkSoundUseAX( functions ) BinkSetSoundSystem(BinkOpenAX,(U32)(functions)) // takes a pointer to RADARAMCALLBACKS + + RADEXPFUNC BINKSNDOPEN RADEXPLINK BinkOpenMusyXSound(U32 param); // don't call directly + #define BinkSoundUseMusyX( ) BinkSetSoundSystem(BinkOpenMusyXSound,0) + +#endif + +#ifdef __RADPS2__ + + RADEXPFUNC BINKSNDOPEN RADEXPLINK BinkOpenRAD_IOP(U32 param); // don't call directly + #define BinkSoundUseRAD_IOP( which_sound_core ) BinkSetSoundSystem(BinkOpenRAD_IOP,which_sound_core) + +#endif + +#ifdef __RADPS3__ + + RADEXPFUNC BINKSNDOPEN RADEXPLINK BinkOpenLibAudio( U32 param ); + #define BinkSoundUseLibAudio( number_of_speakers ) BinkSetSoundSystem( BinkOpenLibAudio, number_of_speakers ) + +#endif + +#ifdef __RADPSP__ + + RADEXPFUNC BINKSNDOPEN RADEXPLINK BinkOpenPSPSound( U32 param ); + #define BinkSoundUsePSPSound( which_pcm_channel ) BinkSetSoundSystem( BinkOpenPSPSound, ((U32)(S32)which_pcm_channel) ) + +#endif + +#ifdef __RADPSP2__ + + RADEXPFUNC BINKSNDOPEN RADEXPLINK BinkOpenRADSS( U32 param ); + #define BinkSoundUsePSP2Sound() BinkSetSoundSystem( BinkOpenRADSS, 0 ) + +#endif + + +#ifdef __RADPS4__ + + RADEXPFUNC BINKSNDOPEN RADEXPLINK BinkOpenRADSS( UINTa param ); + + // number_of_speakers is 2 or 8 at the moment. + #define BinkSoundUseSonySound( number_of_speakers ) BinkSetSoundSystem( BinkOpenRADSS, number_of_speakers ) + +#endif + +#ifdef __RADWIIU__ + + RADEXPFUNC BINKSNDOPEN RADEXPLINK BinkOpenRADSS( U32 param ); + #define BinkSoundUseWiiUSound( ) BinkSetSoundSystem( BinkOpenRADSS, 0 ) + +#endif + +#ifdef __RADNDS__ + + RADEXPFUNC BINKSNDOPEN RADEXPLINK BinkOpenNDSSound(U32 param); // don't call directly + #define BinkSoundUseNDSSound( param ) BinkSetSoundSystem(BinkOpenNDSSound, param) + + // Packs channel bitmask into loword and alarm bitmask into lobyte of hiword + #define BINK_PACK_CHANNEL( ch ) ((U32)(1 << ((ch) & 0xFFFF))) + #define BINK_PACK_ALARM( al ) ((U32)(1 << (16 + ((al) & 0xFF)))) + +#endif + +#ifdef __RAD3DS__ + + RADEXPFUNC BINKSNDOPEN RADEXPLINK BinkOpenRADSS(UINTa param); // don't call directly + #define BinkSoundUse3DSSound(DontServiceDSP) BinkSetSoundSystem(BinkOpenRADSS, DontServiceDSP); + +#endif + +#if defined(__RADWIN__) + +RADEXPFUNC S32 RADEXPLINK BinkDX8SurfaceType(void* lpD3Ds); + +#endif + +#if defined(__RADXENON__) || defined(__RADWIN__) + +RADEXPFUNC S32 RADEXPLINK BinkDX9SurfaceType(void* lpD3Ds); + +#endif + + +// The BinkBuffer API is only for Windows and Mac +#if defined(__RADNT__) || defined(__RADMAC__) + +//========================================================================= +typedef struct BINKBUFFER * HBINKBUFFER; + +#define BINKBUFFERSTRETCHXINT 0x80000000 +#define BINKBUFFERSTRETCHX 0x40000000 +#define BINKBUFFERSHRINKXINT 0x20000000 +#define BINKBUFFERSHRINKX 0x10000000 +#define BINKBUFFERSTRETCHYINT 0x08000000 +#define BINKBUFFERSTRETCHY 0x04000000 +#define BINKBUFFERSHRINKYINT 0x02000000 +#define BINKBUFFERSHRINKY 0x01000000 +#define BINKBUFFERSCALES 0xff000000 +#define BINKBUFFERRESOLUTION 0x00800000 + +#ifdef __RADMAC__ + + +typedef struct BINKBUFFER { + U32 Width; + U32 Height; + U32 WindowWidth; + U32 WindowHeight; + U32 SurfaceType; + void* Buffer; + S32 BufferPitch; + U32 ScreenWidth; + U32 ScreenHeight; + U32 ScreenDepth; + U32 ScaleFlags; + + S32 destx,desty; + S32 wndx,wndy; + U32 wnd; + + U32 type; + + void * gw; +} BINKBUFFER; + + +#define BINKBUFFERAUTO 0 +#define BINKBUFFERDIRECT 1 +#define BINKBUFFERGWORLD 2 +#define BINKBUFFERTYPEMASK 31 + +RADEXPFUNC HBINKBUFFER RADEXPLINK BinkBufferOpen( void* /*WindowPtr*/ wnd, U32 width, U32 height, U32 bufferflags); +RADEXPFUNC S32 RADEXPLINK BinkGDSurfaceType( void* /*GDHandle*/ gd ); + +#else + +typedef struct BINKBUFFER { + U32 Width; + U32 Height; + U32 WindowWidth; + U32 WindowHeight; + U32 SurfaceType; + void* Buffer; + S32 BufferPitch; + S32 ClientOffsetX; + S32 ClientOffsetY; + U32 ScreenWidth; + U32 ScreenHeight; + U32 ScreenDepth; + U32 ExtraWindowWidth; + U32 ExtraWindowHeight; + U32 ScaleFlags; + U32 StretchWidth; + U32 StretchHeight; + + S32 surface; + void* ddsurface; + void* ddclipper; + S32 destx,desty; + S32 wndx,wndy; + void* wnd; + S32 minimized; + S32 ddoverlay; + S32 ddoffscreen; + S32 lastovershow; + + S32 issoftcur; + U32 cursorcount; + void* buffertop; + U32 type; + S32 noclipping; + + S32 loadeddd; + S32 loadedwin; + + void* dibh; + void* dibbuffer; + S32 dibpitch; + void* dibinfo; + void* dibdc; + void* diboldbitmap; + +} BINKBUFFER; + + +#define BINKBUFFERAUTO 0 +#define BINKBUFFERPRIMARY 1 +#define BINKBUFFERDIBSECTION 2 +#define BINKBUFFERYV12OVERLAY 3 +#define BINKBUFFERYUY2OVERLAY 4 +#define BINKBUFFERUYVYOVERLAY 5 +#define BINKBUFFERYV12OFFSCREEN 6 +#define BINKBUFFERYUY2OFFSCREEN 7 +#define BINKBUFFERUYVYOFFSCREEN 8 +#define BINKBUFFERRGBOFFSCREENVIDEO 9 +#define BINKBUFFERRGBOFFSCREENSYSTEM 10 +#define BINKBUFFERLAST 10 +#define BINKBUFFERTYPEMASK 31 + +RADEXPFUNC HBINKBUFFER RADEXPLINK BinkBufferOpen( void* /*HWND*/ wnd, U32 width, U32 height, U32 bufferflags); +RADEXPFUNC S32 RADEXPLINK BinkBufferSetHWND( HBINKBUFFER buf, void* /*HWND*/ newwnd); +RADEXPFUNC S32 RADEXPLINK BinkDDSurfaceType(void * lpDDS); +RADEXPFUNC S32 RADEXPLINK BinkIsSoftwareCursor(void * lpDDSP, void* /*HCURSOR*/ cur); +RADEXPFUNC S32 RADEXPLINK BinkCheckCursor(void* /*HWND*/ wnd,S32 x,S32 y,S32 w,S32 h); +RADEXPFUNC S32 RADEXPLINK BinkBufferSetDirectDraw(void * lpDirectDraw, void * lpPrimary); + +#endif + +RADEXPFUNC void RADEXPLINK BinkBufferClose( HBINKBUFFER buf); +RADEXPFUNC S32 RADEXPLINK BinkBufferLock( HBINKBUFFER buf); +RADEXPFUNC S32 RADEXPLINK BinkBufferUnlock( HBINKBUFFER buf); +RADEXPFUNC void RADEXPLINK BinkBufferSetResolution( S32 w, S32 h, S32 bits); +RADEXPFUNC void RADEXPLINK BinkBufferCheckWinPos( HBINKBUFFER buf, S32 * NewWindowX, S32 * NewWindowY); +RADEXPFUNC S32 RADEXPLINK BinkBufferSetOffset( HBINKBUFFER buf, S32 destx, S32 desty); +RADEXPFUNC void RADEXPLINK BinkBufferBlit( HBINKBUFFER buf, BINKRECT * rects, U32 numrects ); +RADEXPFUNC S32 RADEXPLINK BinkBufferSetScale( HBINKBUFFER buf, U32 w, U32 h); +RADEXPFUNC char * RADEXPLINK BinkBufferGetDescription( HBINKBUFFER buf); +RADEXPFUNC char * RADEXPLINK BinkBufferGetError( void ); +RADEXPFUNC void RADEXPLINK BinkRestoreCursor(S32 checkcount); +RADEXPFUNC S32 RADEXPLINK BinkBufferClear(HBINKBUFFER buf, U32 RGB); + +#endif + +typedef void * (RADLINK * BINKMEMALLOC) (U32 bytes); +typedef void (RADLINK * BINKMEMFREE) (void * ptr); + +RADEXPFUNC void RADEXPLINK BinkSetMemory(BINKMEMALLOC a,BINKMEMFREE f); + +RADEXPFUNC void RADEXPLINK BinkUseTelemetry( void * context ); +RADEXPFUNC void RADEXPLINK BinkUseTmLite( void * context ); + +RADDEFEND + +#endif + +// @cdep pre $set(INCs,$INCs -I$clipfilename($file)) $ignore(TakeCPP) + +#endif + diff --git a/bink2w64.dll b/bink2w64.dll new file mode 100644 index 0000000..44111b4 Binary files /dev/null and b/bink2w64.dll differ diff --git a/bink2w64.lib b/bink2w64.lib new file mode 100644 index 0000000..082c406 Binary files /dev/null and b/bink2w64.lib differ diff --git a/bink_loader_gen.c b/bink_loader_gen.c new file mode 100644 index 0000000..a6c77ec --- /dev/null +++ b/bink_loader_gen.c @@ -0,0 +1,131 @@ +#include "bink.h" +#include + +// Macro to define function pointer and global variable +#define DECL_FN(ret, name, args, ptr) typedef ret (__cdecl *name##_t) args; name##_t p##name = NULL; + +DECL_FN(RADEXPFUNC void *, BinkLogoAddress, (void), ) +DECL_FN(RADEXPFUNC void, BinkSetError, (char const * err), *) +DECL_FN(RADEXPFUNC char *, BinkGetError, (void), ) +DECL_FN(RADEXPFUNC HBINK, BinkOpen, (char const * name, U32 flags), *) +DECL_FN(RADEXPFUNC HBINK, BinkOpenWithOptions, (char const * name, BINK_OPEN_OPTIONS const * boo, U32 flags), *) +DECL_FN(RADEXPFUNC void, BinkGetFrameBuffersInfo, (HBINK bink, BINKFRAMEBUFFERS * fbset), *) +DECL_FN(RADEXPFUNC void, BinkRegisterFrameBuffers, (HBINK bink, BINKFRAMEBUFFERS * fbset), *) +DECL_FN(RADEXPFUNC S32, BinkDoFrame, (HBINK bnk), *) +DECL_FN(RADEXPFUNC S32, BinkDoFramePlane, (HBINK bnk, U32 which_planes), *) +DECL_FN(RADEXPFUNC void, BinkNextFrame, (HBINK bnk), *) +DECL_FN(RADEXPFUNC S32, BinkWait, (HBINK bnk), *) +DECL_FN(RADEXPFUNC void, BinkClose, (HBINK bnk), *) +DECL_FN(RADEXPFUNC S32, BinkPause, (HBINK bnk, S32 pause), *) +DECL_FN(RADEXPFUNC S32, BinkCopyToBuffer, (HBINK bnk, void* dest, S32 destpitch, U32 destheight, U32 destx, U32 desty, U32 flags), *) +DECL_FN(RADEXPFUNC S32, BinkCopyToBufferRect, (HBINK bnk, void* dest, S32 destpitch, U32 destheight, U32 destx, U32 desty, U32 srcx, U32 srcy, U32 srcw, U32 srch, U32 flags), *) +DECL_FN(RADEXPFUNC S32, BinkGetRects, (HBINK bnk, U32 flags), *) +DECL_FN(RADEXPFUNC void, BinkGoto, (HBINK bnk, U32 frame, S32 flags), *) +DECL_FN(RADEXPFUNC U32, BinkGetKeyFrame, (HBINK bnk, U32 frame, S32 flags), *) +DECL_FN(RADEXPFUNC void, BinkFreeGlobals, (void), *) +DECL_FN(RADEXPFUNC S32, BinkGetPlatformInfo, (S32 bink_platform_enum, void * output), *) +DECL_FN(RADEXPFUNC void, BinkRegisterGPUDataBuffers, (HBINK bink, BINKGPUDATABUFFERS * gpu), *) +DECL_FN(RADEXPFUNC S32, BinkGetGPUDataBuffersInfo, (HBINK bink, BINKGPUDATABUFFERS * gpu), *) +DECL_FN(RADEXPFUNC S32, BinkSetVideoOnOff, (HBINK bnk, S32 onoff), *) +DECL_FN(RADEXPFUNC S32, BinkSetSoundOnOff, (HBINK bnk, S32 onoff), *) +DECL_FN(RADEXPFUNC void, BinkSetVolume, (HBINK bnk, U32 trackid, S32 volume), *) +DECL_FN(RADEXPFUNC void, BinkSetPan, (HBINK bnk, U32 trackid, S32 pan), *) +DECL_FN(RADEXPFUNC void, BinkSetSpeakerVolumes, (HBINK bnk, U32 trackid, U32 * speaker_indexes, S32 * volumes, U32 total), *) +DECL_FN(RADEXPFUNC void, BinkService, (HBINK bink), *) +DECL_FN(RADEXPFUNC S32, BinkShouldSkip, (HBINK bink), *) +DECL_FN(RADEXPFUNC S32, BinkControlBackgroundIO, (HBINK bink, U32 control), *) +DECL_FN(RADEXPFUNC void, BinkSetWillLoop, (HBINK bink, S32 onoff), *) +DECL_FN(RADEXPFUNC S32, BinkStartAsyncThread, (S32 thread_num, void const * param), *) +DECL_FN(RADEXPFUNC S32, BinkDoFrameAsync, (HBINK bink, U32 thread_one, U32 thread_two), *) +DECL_FN(RADEXPFUNC S32, BinkDoFrameAsyncMulti, (HBINK bink, U32* threads, S32 thread_count), *) +DECL_FN(RADEXPFUNC S32, BinkDoFrameAsyncWait, (HBINK bink, S32 us), *) +DECL_FN(RADEXPFUNC S32, BinkRequestStopAsyncThread, (S32 thread_num), *) +DECL_FN(RADEXPFUNC S32, BinkWaitStopAsyncThread, (S32 thread_num), *) +DECL_FN(RADEXPFUNC HBINKTRACK, BinkOpenTrack, (HBINK bnk, U32 trackindex), *) +DECL_FN(RADEXPFUNC void, BinkCloseTrack, (HBINKTRACK bnkt), *) +DECL_FN(RADEXPFUNC U32, BinkGetTrackData, (HBINKTRACK bnkt, void * dest), *) +DECL_FN(RADEXPFUNC U32, BinkGetTrackType, (HBINK bnk, U32 trackindex), *) +DECL_FN(RADEXPFUNC U32, BinkGetTrackMaxSize, (HBINK bnk, U32 trackindex), *) +DECL_FN(RADEXPFUNC U32, BinkGetTrackID, (HBINK bnk, U32 trackindex), *) +DECL_FN(RADEXPFUNC void, BinkGetSummary, (HBINK bnk, BINKSUMMARY * sum), *) +DECL_FN(RADEXPFUNC void, BinkGetRealtime, (HBINK bink, BINKREALTIME * run, U32 frames), *) +DECL_FN(RADEXPFUNC void, BinkSetFileOffset, (U64 offset), *) +DECL_FN(RADEXPFUNC void, BinkSetSoundTrack, (U32 total_tracks, U32 * tracks), *) +DECL_FN(RADEXPFUNC void, BinkSetIO, (BINKIOOPEN io), *) +DECL_FN(RADEXPFUNC void, BinkSetFrameRate, (U32 forcerate, U32 forceratediv), *) +DECL_FN(RADEXPFUNC void, BinkSetSimulate, (U32 sim), *) +DECL_FN(RADEXPFUNC void, BinkSetIOSize, (U32 iosize), *) +DECL_FN(RADEXPFUNC S32, BinkSetSoundSystem, (BINKSNDSYSOPEN open, UINTa param), *) +DECL_FN(RADEXPFUNC S32, BinkSetSoundSystem2, (BINKSNDSYSOPEN2 open, UINTa param1, UINTa param2), *) +DECL_FN(RADEXPFUNC BINKSNDOPEN, BinkOpenDirectSound, (UINTa param), *) +DECL_FN(RADEXPFUNC BINKSNDOPEN, BinkOpenWaveOut, (UINTa param), *) +DECL_FN(RADEXPFUNC BINKSNDOPEN, BinkOpenXAudio2, (UINTa param), *) +DECL_FN(RADEXPFUNC void, BinkSetMemory, (BINKMEMALLOC a, BINKMEMFREE f), *) + +HMODULE dll = NULL; + +int LoadBinkDLL(void) { + if (dll) return 1; + dll = LoadLibraryA("bink2w64.dll"); + if (!dll) return 0; + + pBinkLogoAddress = (BinkLogoAddress_t)GetProcAddress(dll, "BinkLogoAddress"); + pBinkSetError = (BinkSetError_t)GetProcAddress(dll, "BinkSetError"); + pBinkGetError = (BinkGetError_t)GetProcAddress(dll, "BinkGetError"); + pBinkOpen = (BinkOpen_t)GetProcAddress(dll, "BinkOpen"); + pBinkOpenWithOptions = (BinkOpenWithOptions_t)GetProcAddress(dll, "BinkOpenWithOptions"); + pBinkGetFrameBuffersInfo = (BinkGetFrameBuffersInfo_t)GetProcAddress(dll, "BinkGetFrameBuffersInfo"); + pBinkRegisterFrameBuffers = (BinkRegisterFrameBuffers_t)GetProcAddress(dll, "BinkRegisterFrameBuffers"); + pBinkDoFrame = (BinkDoFrame_t)GetProcAddress(dll, "BinkDoFrame"); + pBinkDoFramePlane = (BinkDoFramePlane_t)GetProcAddress(dll, "BinkDoFramePlane"); + pBinkNextFrame = (BinkNextFrame_t)GetProcAddress(dll, "BinkNextFrame"); + pBinkWait = (BinkWait_t)GetProcAddress(dll, "BinkWait"); + pBinkClose = (BinkClose_t)GetProcAddress(dll, "BinkClose"); + pBinkPause = (BinkPause_t)GetProcAddress(dll, "BinkPause"); + pBinkCopyToBuffer = (BinkCopyToBuffer_t)GetProcAddress(dll, "BinkCopyToBuffer"); + pBinkCopyToBufferRect = (BinkCopyToBufferRect_t)GetProcAddress(dll, "BinkCopyToBufferRect"); + pBinkGetRects = (BinkGetRects_t)GetProcAddress(dll, "BinkGetRects"); + pBinkGoto = (BinkGoto_t)GetProcAddress(dll, "BinkGoto"); + pBinkGetKeyFrame = (BinkGetKeyFrame_t)GetProcAddress(dll, "BinkGetKeyFrame"); + pBinkFreeGlobals = (BinkFreeGlobals_t)GetProcAddress(dll, "BinkFreeGlobals"); + pBinkGetPlatformInfo = (BinkGetPlatformInfo_t)GetProcAddress(dll, "BinkGetPlatformInfo"); + pBinkRegisterGPUDataBuffers = (BinkRegisterGPUDataBuffers_t)GetProcAddress(dll, "BinkRegisterGPUDataBuffers"); + pBinkGetGPUDataBuffersInfo = (BinkGetGPUDataBuffersInfo_t)GetProcAddress(dll, "BinkGetGPUDataBuffersInfo"); + pBinkSetVideoOnOff = (BinkSetVideoOnOff_t)GetProcAddress(dll, "BinkSetVideoOnOff"); + pBinkSetSoundOnOff = (BinkSetSoundOnOff_t)GetProcAddress(dll, "BinkSetSoundOnOff"); + pBinkSetVolume = (BinkSetVolume_t)GetProcAddress(dll, "BinkSetVolume"); + pBinkSetPan = (BinkSetPan_t)GetProcAddress(dll, "BinkSetPan"); + pBinkSetSpeakerVolumes = (BinkSetSpeakerVolumes_t)GetProcAddress(dll, "BinkSetSpeakerVolumes"); + pBinkService = (BinkService_t)GetProcAddress(dll, "BinkService"); + pBinkShouldSkip = (BinkShouldSkip_t)GetProcAddress(dll, "BinkShouldSkip"); + pBinkControlBackgroundIO = (BinkControlBackgroundIO_t)GetProcAddress(dll, "BinkControlBackgroundIO"); + pBinkSetWillLoop = (BinkSetWillLoop_t)GetProcAddress(dll, "BinkSetWillLoop"); + pBinkStartAsyncThread = (BinkStartAsyncThread_t)GetProcAddress(dll, "BinkStartAsyncThread"); + pBinkDoFrameAsync = (BinkDoFrameAsync_t)GetProcAddress(dll, "BinkDoFrameAsync"); + pBinkDoFrameAsyncMulti = (BinkDoFrameAsyncMulti_t)GetProcAddress(dll, "BinkDoFrameAsyncMulti"); + pBinkDoFrameAsyncWait = (BinkDoFrameAsyncWait_t)GetProcAddress(dll, "BinkDoFrameAsyncWait"); + pBinkRequestStopAsyncThread = (BinkRequestStopAsyncThread_t)GetProcAddress(dll, "BinkRequestStopAsyncThread"); + pBinkWaitStopAsyncThread = (BinkWaitStopAsyncThread_t)GetProcAddress(dll, "BinkWaitStopAsyncThread"); + pBinkOpenTrack = (BinkOpenTrack_t)GetProcAddress(dll, "BinkOpenTrack"); + pBinkCloseTrack = (BinkCloseTrack_t)GetProcAddress(dll, "BinkCloseTrack"); + pBinkGetTrackData = (BinkGetTrackData_t)GetProcAddress(dll, "BinkGetTrackData"); + pBinkGetTrackType = (BinkGetTrackType_t)GetProcAddress(dll, "BinkGetTrackType"); + pBinkGetTrackMaxSize = (BinkGetTrackMaxSize_t)GetProcAddress(dll, "BinkGetTrackMaxSize"); + pBinkGetTrackID = (BinkGetTrackID_t)GetProcAddress(dll, "BinkGetTrackID"); + pBinkGetSummary = (BinkGetSummary_t)GetProcAddress(dll, "BinkGetSummary"); + pBinkGetRealtime = (BinkGetRealtime_t)GetProcAddress(dll, "BinkGetRealtime"); + pBinkSetFileOffset = (BinkSetFileOffset_t)GetProcAddress(dll, "BinkSetFileOffset"); + pBinkSetSoundTrack = (BinkSetSoundTrack_t)GetProcAddress(dll, "BinkSetSoundTrack"); + pBinkSetIO = (BinkSetIO_t)GetProcAddress(dll, "BinkSetIO"); + pBinkSetFrameRate = (BinkSetFrameRate_t)GetProcAddress(dll, "BinkSetFrameRate"); + pBinkSetSimulate = (BinkSetSimulate_t)GetProcAddress(dll, "BinkSetSimulate"); + pBinkSetIOSize = (BinkSetIOSize_t)GetProcAddress(dll, "BinkSetIOSize"); + pBinkSetSoundSystem = (BinkSetSoundSystem_t)GetProcAddress(dll, "BinkSetSoundSystem"); + pBinkSetSoundSystem2 = (BinkSetSoundSystem2_t)GetProcAddress(dll, "BinkSetSoundSystem2"); + pBinkOpenDirectSound = (BinkOpenDirectSound_t)GetProcAddress(dll, "BinkOpenDirectSound"); + pBinkOpenWaveOut = (BinkOpenWaveOut_t)GetProcAddress(dll, "BinkOpenWaveOut"); + pBinkOpenXAudio2 = (BinkOpenXAudio2_t)GetProcAddress(dll, "BinkOpenXAudio2"); + pBinkSetMemory = (BinkSetMemory_t)GetProcAddress(dll, "BinkSetMemory"); + + return 1; +} diff --git a/framebuffer.bmp b/framebuffer.bmp new file mode 100644 index 0000000..353a6da Binary files /dev/null and b/framebuffer.bmp differ diff --git a/functions.txt b/functions.txt new file mode 100644 index 0000000..a43bff8 --- /dev/null +++ b/functions.txt @@ -0,0 +1,80 @@ +BinkAllocateFrameBuffers +BinkClose +BinkCloseTrack +BinkControlBackgroundIO +BinkCopyToBuffer +BinkCopyToBufferRect +BinkCurrentSubtitle +BinkDoFrame +BinkDoFrameAsync +BinkDoFrameAsyncMulti +BinkDoFrameAsyncWait +BinkDoFramePlane +BinkFindXAudio2WinDevice +BinkFreeGlobals +BinkGetError +BinkGetFrameBuffersInfo +BinkGetGPUDataBuffersInfo +BinkGetKeyFrame +BinkGetPlatformInfo +BinkGetRealtime +BinkGetRects +BinkGetSubtitleByIndex +BinkGetSummary +BinkGetTrackData +BinkGetTrackID +BinkGetTrackMaxSize +BinkGetTrackType +BinkGoto +BinkLoadSubtitles +BinkLogoAddress +BinkNextFrame +BinkOpen +BinkOpenDirectSound +BinkOpenTrack +BinkOpenWaveOut +BinkOpenWithOptions +BinkOpenXAudio2 +BinkOpenXAudio27 +BinkOpenXAudio28 +BinkOpenXAudio29 +BinkPause +BinkRegisterFrameBuffers +BinkRegisterGPUDataBuffers +BinkRequestStopAsyncThread +BinkRequestStopAsyncThreadsMulti +BinkService +BinkSetError +BinkSetFileOffset +BinkSetFrameRate +BinkSetIO +BinkSetIOSize +BinkSetMemory +BinkSetOSFileCallbacks +BinkSetPan +BinkSetSimulate +BinkSetSoundOnOff +BinkSetSoundSystem +BinkSetSoundSystem2 +BinkSetSoundSystem4 +BinkSetSoundTrack +BinkSetSpeakerVolumes +BinkSetVideoOnOff +BinkSetVolume +BinkSetWillLoop +BinkShouldSkip +BinkStartAsyncThread +BinkUtilCPUs +BinkUtilFree +BinkUtilMalloc +BinkUtilMutexCreate +BinkUtilMutexDestroy +BinkUtilMutexLock +BinkUtilMutexLockTimeOut +BinkUtilMutexUnlock +BinkUtilSoundGlobalLock +BinkUtilSoundGlobalUnlock +BinkWait +BinkWaitStopAsyncThread +BinkWaitStopAsyncThreadsMulti +RADTimerRead \ No newline at end of file diff --git a/gen.py b/gen.py new file mode 100644 index 0000000..5bb65c6 --- /dev/null +++ b/gen.py @@ -0,0 +1,57 @@ +import re + +header_file = "bink.h" +func_list_file = "functions.txt" +out_file = "bink_loader_gen.c" + +# Read function list +with open(func_list_file) as f: + func_names = set(line.strip() for line in f if line.strip()) + +# Read header +with open(header_file) as f: + header = f.read() + +# Remove RADEXPLINK entirely +header = re.sub(r'\bRADEXPLINK\b', '', header) + +functions = [] + +# Regex to match return type + function name + args +prototype_re = re.compile( + r'^[ \t]*(\w[\w\s\*\d]+)[ \t]+(' + '|'.join(func_names) + r')[ \t]*\(([^)]*)\)\s*;', + re.MULTILINE +) + +for match in prototype_re.finditer(header): + ret_type = match.group(1).strip() + name = match.group(2).strip() + args = match.group(3).strip() + args = re.sub(r'\s*,\s*', ', ', args) + + # Only add * if return type is NOT already a pointer + ptr_mark = '' if ret_type.endswith('*') else '*' + + functions.append((ret_type, name, args, ptr_mark)) + +# Generate C file +with open(out_file, "w") as f: + f.write('#include "bink.h"\n#include \n\n') + f.write('// Macro to define function pointer and global variable\n') + f.write('#define DECL_FN(ret, name, args, ptr) typedef ret (__cdecl *name##_t) args; name##_t p##name = NULL;\n\n') + + # Typedefs + globals + for ret, name, args, ptr_mark in functions: + f.write(f'DECL_FN({ret}, {name}, ({args}), {ptr_mark})\n') + + f.write('\nHMODULE dll = NULL;\n\n') + f.write('int LoadBinkDLL(void) {\n') + f.write(' if (dll) return 1;\n') + f.write(' dll = LoadLibraryA("bink2w64.dll");\n') + f.write(' if (!dll) return 0;\n\n') + + # Assign function pointers + for _, name, _, _ in functions: + f.write(f' p{name} = ({name}_t)GetProcAddress(dll, "{name}");\n') + + f.write('\n return 1;\n}\n') diff --git a/kernel32.cpp b/kernel32.cpp new file mode 100644 index 0000000..c7d7b27 --- /dev/null +++ b/kernel32.cpp @@ -0,0 +1,252 @@ +typedef void* HWND; +typedef void* LPUNKNOWN; +typedef void* REFIID; +typedef void* REFCLSID; +typedef long HRESULT; +typedef unsigned long DWORD; +typedef unsigned int UINT; +typedef int BOOL; +typedef void* HANDLE; +typedef void* LPVOID; +typedef long LONG; +typedef long LONG_PTR; +typedef const char* LPCSTR; +typedef size_t SIZE_T; +typedef void* HMODULE; +typedef HMODULE HINSTANCE; +typedef void* FARPROC; +typedef DWORD (*LPTHREAD_START_ROUTINE)(LPVOID lpThreadParameter); +typedef union _LARGE_INTEGER { + struct { + unsigned long LowPart; + long HighPart; + }; + long long QuadPart; +} LARGE_INTEGER; +#define S_OK ((HRESULT)0L) +#define TRUE 1 +#define FALSE 0 +#include +#include + +extern "C" { + +typedef HANDLE (*HeapCreate_t)(DWORD, SIZE_T, SIZE_T); +typedef BOOL (*HeapDestroy_t)(HANDLE); +typedef LPVOID (*HeapAlloc_t)(HANDLE, DWORD, SIZE_T); +typedef BOOL (*HeapFree_t)(HANDLE, DWORD, LPVOID); +typedef LPVOID (*HeapReAlloc_t)(HANDLE a, DWORD b, LPVOID c, SIZE_T d); + +HeapCreate_t pHeapCreate = nullptr; +HeapDestroy_t pHeapDestroy = nullptr; +HeapAlloc_t pHeapAlloc = nullptr; +HeapFree_t pHeapFree = nullptr; +HeapReAlloc_t pHeapReAlloc = nullptr; + +// Memory +__declspec(dllexport) HANDLE HeapCreate(DWORD a, SIZE_T b, SIZE_T c) { return pHeapCreate(a, b, c); } +__declspec(dllexport) BOOL HeapDestroy(HANDLE a) { return pHeapDestroy(a); } +__declspec(dllexport) LPVOID HeapAlloc(HANDLE a, DWORD b, SIZE_T c) { return pHeapAlloc(a, b, c); } +__declspec(dllexport) BOOL HeapFree(HANDLE a, DWORD b, LPVOID c) { return pHeapFree(a, b, c); } +__declspec(dllexport) LPVOID HeapReAlloc(HANDLE a, DWORD b, LPVOID c, SIZE_T d) { return pHeapReAlloc(a, b, c, d); } + +// Threads (fake) +__declspec(dllexport) DWORD GetCurrentThreadId() { return 1; } +__declspec(dllexport) HANDLE GetCurrentThread() { return (HANDLE)1; } +__declspec(dllexport) HANDLE CreateThread(void*, SIZE_T, LPTHREAD_START_ROUTINE, void*, DWORD, DWORD*) { return (HANDLE)1; } +__declspec(dllexport) DWORD WaitForSingleObject(HANDLE, DWORD) { return 0; } +__declspec(dllexport) BOOL CloseHandle(HANDLE) { return 1; } + +typedef DWORD (*GetTickCount_t)(); +typedef BOOL (*QueryPerformanceCounter_t)(LARGE_INTEGER* li); +typedef BOOL (*QueryPerformanceFrequency_t)(LARGE_INTEGER* li); + +GetTickCount_t pGetTickCount = nullptr; +QueryPerformanceCounter_t pQueryPerformanceCounter = nullptr; +QueryPerformanceFrequency_t pQueryPerformanceFrequency = nullptr; + +// Timing +__declspec(dllexport) DWORD GetTickCount() { + return pGetTickCount(); +} + +__declspec(dllexport) BOOL QueryPerformanceCounter(LARGE_INTEGER* li) { + return pQueryPerformanceCounter(li); +} + +__declspec(dllexport) BOOL QueryPerformanceFrequency(LARGE_INTEGER* li) { + return pQueryPerformanceFrequency(li); +} + +// Module / file +__declspec(dllexport) HMODULE GetModuleHandleA(LPCSTR) { return (HMODULE)1; } +__declspec(dllexport) FARPROC GetProcAddress(HMODULE, LPCSTR) { return nullptr; } +__declspec(dllexport) HMODULE LoadLibraryA(LPCSTR) { return (HMODULE)1; } + +// Process +__declspec(dllexport) DWORD GetCurrentProcessId() { return 1; } +__declspec(dllexport) HANDLE GetCurrentProcess() { return (HANDLE)1; } +__declspec(dllexport) void ExitProcess(UINT) { while(1); } + +typedef void (*OutputDebugStringA_t)(LPCSTR lpOutputString); + +OutputDebugStringA_t pOutputDebugStringA = nullptr; + +__declspec(dllexport) void OutputDebugStringA(LPCSTR lpOutputString) { + pOutputDebugStringA(lpOutputString); +} + +HMODULE LoadLibraryExA(LPCSTR lpLibFileName, HANDLE hFile, DWORD dwFlags); + +#define IMAGE_DOS_SIGNATURE 0x5A4D // MZ +#define IMAGE_NT_SIGNATURE 0x00004550 // PE00 +#define IMAGE_DIRECTORY_ENTRY_EXPORT 0 + +struct IMAGE_DOS_HEADER { + uint16_t e_magic; + uint16_t e_cblp; + uint16_t e_cp; + uint16_t e_crlc; + uint16_t e_cparhdr; + uint16_t e_minalloc; + uint16_t e_maxalloc; + uint16_t e_ss; + uint16_t e_sp; + uint16_t e_csum; + uint16_t e_ip; + uint16_t e_cs; + uint16_t e_lfarlc; + uint16_t e_ovno; + uint16_t e_res[4]; + uint16_t e_oemid; + uint16_t e_oeminfo; + uint16_t e_res2[10]; + uint32_t e_lfanew; +}; + +struct IMAGE_FILE_HEADER { + uint16_t Machine; + uint16_t NumberOfSections; + uint32_t TimeDateStamp; + uint32_t PointerToSymbolTable; + uint32_t NumberOfSymbols; + uint16_t SizeOfOptionalHeader; + uint16_t Characteristics; +}; + +struct IMAGE_DATA_DIRECTORY { + uint32_t VirtualAddress; + uint32_t Size; +}; + +struct IMAGE_OPTIONAL_HEADER64 { + uint16_t Magic; + uint8_t MajorLinkerVersion; + uint8_t MinorLinkerVersion; + uint32_t SizeOfCode; + uint32_t SizeOfInitializedData; + uint32_t SizeOfUninitializedData; + uint32_t AddressOfEntryPoint; + uint32_t BaseOfCode; + uint64_t ImageBase; + uint32_t SectionAlignment; + uint32_t FileAlignment; + uint16_t MajorOperatingSystemVersion; + uint16_t MinorOperatingSystemVersion; + uint16_t MajorImageVersion; + uint16_t MinorImageVersion; + uint16_t MajorSubsystemVersion; + uint16_t MinorSubsystemVersion; + uint32_t Win32VersionValue; + uint32_t SizeOfImage; + uint32_t SizeOfHeaders; + uint32_t CheckSum; + uint16_t Subsystem; + uint16_t DllCharacteristics; + uint64_t SizeOfStackReserve; + uint64_t SizeOfStackCommit; + uint64_t SizeOfHeapReserve; + uint64_t SizeOfHeapCommit; + uint32_t LoaderFlags; + uint32_t NumberOfRvaAndSizes; + IMAGE_DATA_DIRECTORY DataDirectory[16]; +}; + +struct IMAGE_NT_HEADERS64 { + uint32_t Signature; + IMAGE_FILE_HEADER FileHeader; + IMAGE_OPTIONAL_HEADER64 OptionalHeader; +}; + +struct IMAGE_EXPORT_DIRECTORY { + uint32_t Characteristics; + uint32_t TimeDateStamp; + uint16_t MajorVersion; + uint16_t MinorVersion; + uint32_t Name; + uint32_t Base; + uint32_t NumberOfFunctions; + uint32_t NumberOfNames; + uint32_t AddressOfFunctions; // RVA from base of image + uint32_t AddressOfNames; // RVA from base of image + uint32_t AddressOfNameOrdinals; // RVA from base of image +}; + +int strcmp(const char* a, const char* b) { + while (*a && (*a == *b)) { + ++a; + ++b; + } + return static_cast(*a) - static_cast(*b); +} + +FARPROC GetRealGetProcAddress(HMODULE hModule) { + auto base = reinterpret_cast(hModule); + auto dos = reinterpret_cast(base); + if (dos->e_magic != IMAGE_DOS_SIGNATURE) return nullptr; + + auto nt = reinterpret_cast(base + dos->e_lfanew); + if (nt->Signature != IMAGE_NT_SIGNATURE) return nullptr; + + auto exportDirRVA = nt->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress; + auto exportDir = reinterpret_cast(base + exportDirRVA); + + auto names = reinterpret_cast(base + exportDir->AddressOfNames); + auto ordinals = reinterpret_cast(base + exportDir->AddressOfNameOrdinals); + auto functions = reinterpret_cast(base + exportDir->AddressOfFunctions); + + for (uint32_t i = 0; i < exportDir->NumberOfNames; i++) { + const char* name = reinterpret_cast(base + names[i]); + if (strcmp(name, "GetProcAddress") == 0) { + uint16_t ord = ordinals[i]; + uint32_t funcRVA = functions[ord]; + return reinterpret_cast(base + funcRVA); + } + } + return nullptr; +} + +typedef FARPROC (*GetProcAddress_t)(HMODULE, LPCSTR); +GetProcAddress_t pGetProcAddress = nullptr; + +BOOL DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) { + if (fdwReason == 1) { // DLL_PROCESS_ATTACH + HMODULE kernel32 = LoadLibraryExA("kernel32.dll", NULL, 0x00000800); + pGetProcAddress = (GetProcAddress_t)GetRealGetProcAddress(kernel32); + + pHeapCreate = (HeapCreate_t)pGetProcAddress(kernel32, "HeapCreate"); + pHeapDestroy = (HeapDestroy_t)pGetProcAddress(kernel32, "HeapDestroy"); + pHeapAlloc = (HeapAlloc_t)pGetProcAddress(kernel32, "HeapAlloc"); + pHeapFree = (HeapFree_t)pGetProcAddress(kernel32, "HeapFree"); + pHeapReAlloc = (HeapReAlloc_t)pGetProcAddress(kernel32, "HeapReAlloc"); + + pGetTickCount = (GetTickCount_t)pGetProcAddress(kernel32, "GetTickCount"); + pQueryPerformanceCounter = (QueryPerformanceCounter_t)pGetProcAddress(kernel32, "QueryPerformanceCounter"); + pQueryPerformanceFrequency = (QueryPerformanceFrequency_t)pGetProcAddress(kernel32, "QueryPerformanceFrequency"); + + pOutputDebugStringA = (OutputDebugStringA_t)pGetProcAddress(kernel32, "OutputDebugStringA"); + } + return TRUE; +} + +} diff --git a/kernel32.dll b/kernel32.dll new file mode 100644 index 0000000..9f01405 Binary files /dev/null and b/kernel32.dll differ diff --git a/kernel32.exp b/kernel32.exp new file mode 100644 index 0000000..9fa5471 Binary files /dev/null and b/kernel32.exp differ diff --git a/kernel32.lib b/kernel32.lib new file mode 100644 index 0000000..3a59495 Binary files /dev/null and b/kernel32.lib differ diff --git a/kernel32.obj b/kernel32.obj new file mode 100644 index 0000000..fe697b2 Binary files /dev/null and b/kernel32.obj differ diff --git a/main.cpp b/main.cpp new file mode 100644 index 0000000..dd5ddea --- /dev/null +++ b/main.cpp @@ -0,0 +1,250 @@ +#include "bink.h" +#include +#include +#include + +// Macro to define function pointer and global variable +#define DECL_FN(ret, name, args, ptr) typedef ret (__cdecl *name##_t) args; name##_t p##name = NULL; + +DECL_FN(void *, BinkLogoAddress, (void), ) +DECL_FN(void, BinkSetError, (char const * err), *) +DECL_FN(char *, BinkGetError, (void), ) +DECL_FN(HBINK, BinkOpen, (char const * name, U32 flags), *) +DECL_FN(HBINK, BinkOpenWithOptions, (char const * name, BINK_OPEN_OPTIONS const * boo, U32 flags), *) +DECL_FN(void, BinkGetFrameBuffersInfo, (HBINK bink, BINKFRAMEBUFFERS * fbset), *) +DECL_FN(void, BinkRegisterFrameBuffers, (HBINK bink, BINKFRAMEBUFFERS * fbset), *) +DECL_FN(S32, BinkDoFrame, (HBINK bnk), *) +DECL_FN(S32, BinkDoFramePlane, (HBINK bnk, U32 which_planes), *) +DECL_FN(void, BinkNextFrame, (HBINK bnk), *) +DECL_FN(S32, BinkWait, (HBINK bnk), *) +DECL_FN(void, BinkClose, (HBINK bnk), *) +DECL_FN(S32, BinkPause, (HBINK bnk, S32 pause), *) +DECL_FN(S32, BinkCopyToBuffer, (HBINK bnk, void* dest, S32 destpitch, U32 destheight, U32 destx, U32 desty, U32 flags), *) +DECL_FN(S32, BinkCopyToBufferRect, (HBINK bnk, void* dest, S32 destpitch, U32 destheight, U32 destx, U32 desty, U32 srcx, U32 srcy, U32 srcw, U32 srch, U32 flags), *) +DECL_FN(S32, BinkGetRects, (HBINK bnk, U32 flags), *) +DECL_FN(void, BinkGoto, (HBINK bnk, U32 frame, S32 flags), *) +DECL_FN(U32, BinkGetKeyFrame, (HBINK bnk, U32 frame, S32 flags), *) +DECL_FN(void, BinkFreeGlobals, (void), *) +DECL_FN(S32, BinkGetPlatformInfo, (S32 bink_platform_enum, void * output), *) +DECL_FN(void, BinkRegisterGPUDataBuffers, (HBINK bink, BINKGPUDATABUFFERS * gpu), *) +DECL_FN(S32, BinkGetGPUDataBuffersInfo, (HBINK bink, BINKGPUDATABUFFERS * gpu), *) +DECL_FN(S32, BinkSetVideoOnOff, (HBINK bnk, S32 onoff), *) +DECL_FN(S32, BinkSetSoundOnOff, (HBINK bnk, S32 onoff), *) +DECL_FN(void, BinkSetVolume, (HBINK bnk, U32 trackid, S32 volume), *) +DECL_FN(void, BinkSetPan, (HBINK bnk, U32 trackid, S32 pan), *) +DECL_FN(void, BinkSetSpeakerVolumes, (HBINK bnk, U32 trackid, U32 * speaker_indexes, S32 * volumes, U32 total), *) +DECL_FN(void, BinkService, (HBINK bink), *) +DECL_FN(S32, BinkShouldSkip, (HBINK bink), *) +DECL_FN(S32, BinkControlBackgroundIO, (HBINK bink, U32 control), *) +DECL_FN(void, BinkSetWillLoop, (HBINK bink, S32 onoff), *) +DECL_FN(S32, BinkStartAsyncThread, (S32 thread_num, void const * param), *) +DECL_FN(S32, BinkDoFrameAsync, (HBINK bink, U32 thread_one, U32 thread_two), *) +DECL_FN(S32, BinkDoFrameAsyncMulti, (HBINK bink, U32* threads, S32 thread_count), *) +DECL_FN(S32, BinkDoFrameAsyncWait, (HBINK bink, S32 us), *) +DECL_FN(S32, BinkRequestStopAsyncThread, (S32 thread_num), *) +DECL_FN(S32, BinkWaitStopAsyncThread, (S32 thread_num), *) +DECL_FN(HBINKTRACK, BinkOpenTrack, (HBINK bnk, U32 trackindex), *) +DECL_FN(void, BinkCloseTrack, (HBINKTRACK bnkt), *) +DECL_FN(U32, BinkGetTrackData, (HBINKTRACK bnkt, void * dest), *) +DECL_FN(U32, BinkGetTrackType, (HBINK bnk, U32 trackindex), *) +DECL_FN(U32, BinkGetTrackMaxSize, (HBINK bnk, U32 trackindex), *) +DECL_FN(U32, BinkGetTrackID, (HBINK bnk, U32 trackindex), *) +DECL_FN(void, BinkGetSummary, (HBINK bnk, BINKSUMMARY * sum), *) +DECL_FN(void, BinkGetRealtime, (HBINK bink, BINKREALTIME * run, U32 frames), *) +DECL_FN(void, BinkSetFileOffset, (U64 offset), *) +DECL_FN(void, BinkSetSoundTrack, (U32 total_tracks, U32 * tracks), *) +DECL_FN(void, BinkSetIO, (BINKIOOPEN io), *) +DECL_FN(void, BinkSetFrameRate, (U32 forcerate, U32 forceratediv), *) +DECL_FN(void, BinkSetSimulate, (U32 sim), *) +DECL_FN(void, BinkSetIOSize, (U32 iosize), *) +DECL_FN(S32, BinkSetSoundSystem, (BINKSNDSYSOPEN open, UINTa param), *) +DECL_FN(S32, BinkSetSoundSystem2, (BINKSNDSYSOPEN2 open, UINTa param1, UINTa param2), *) +DECL_FN(BINKSNDOPEN, BinkOpenDirectSound, (UINTa param), *) +DECL_FN(BINKSNDOPEN, BinkOpenWaveOut, (UINTa param), *) +DECL_FN(BINKSNDOPEN, BinkOpenXAudio2, (UINTa param), *) +DECL_FN(void, BinkSetMemory, (BINKMEMALLOC a, BINKMEMFREE f), *) + +HMODULE dll = NULL; + +int LoadBinkDLL(void) { + if (dll) return 1; + dll = LoadLibraryExA("bink2w64.dll", 0, 0); + if (!dll) return 0; + + pBinkLogoAddress = (BinkLogoAddress_t)GetProcAddress(dll, "BinkLogoAddress"); + pBinkSetError = (BinkSetError_t)GetProcAddress(dll, "BinkSetError"); + pBinkGetError = (BinkGetError_t)GetProcAddress(dll, "BinkGetError"); + pBinkOpen = (BinkOpen_t)GetProcAddress(dll, "BinkOpen"); + pBinkOpenWithOptions = (BinkOpenWithOptions_t)GetProcAddress(dll, "BinkOpenWithOptions"); + pBinkGetFrameBuffersInfo = (BinkGetFrameBuffersInfo_t)GetProcAddress(dll, "BinkGetFrameBuffersInfo"); + pBinkRegisterFrameBuffers = (BinkRegisterFrameBuffers_t)GetProcAddress(dll, "BinkRegisterFrameBuffers"); + pBinkDoFrame = (BinkDoFrame_t)GetProcAddress(dll, "BinkDoFrame"); + pBinkDoFramePlane = (BinkDoFramePlane_t)GetProcAddress(dll, "BinkDoFramePlane"); + pBinkNextFrame = (BinkNextFrame_t)GetProcAddress(dll, "BinkNextFrame"); + pBinkWait = (BinkWait_t)GetProcAddress(dll, "BinkWait"); + pBinkClose = (BinkClose_t)GetProcAddress(dll, "BinkClose"); + pBinkPause = (BinkPause_t)GetProcAddress(dll, "BinkPause"); + pBinkCopyToBuffer = (BinkCopyToBuffer_t)GetProcAddress(dll, "BinkCopyToBuffer"); + pBinkCopyToBufferRect = (BinkCopyToBufferRect_t)GetProcAddress(dll, "BinkCopyToBufferRect"); + pBinkGetRects = (BinkGetRects_t)GetProcAddress(dll, "BinkGetRects"); + pBinkGoto = (BinkGoto_t)GetProcAddress(dll, "BinkGoto"); + pBinkGetKeyFrame = (BinkGetKeyFrame_t)GetProcAddress(dll, "BinkGetKeyFrame"); + pBinkFreeGlobals = (BinkFreeGlobals_t)GetProcAddress(dll, "BinkFreeGlobals"); + pBinkGetPlatformInfo = (BinkGetPlatformInfo_t)GetProcAddress(dll, "BinkGetPlatformInfo"); + pBinkRegisterGPUDataBuffers = (BinkRegisterGPUDataBuffers_t)GetProcAddress(dll, "BinkRegisterGPUDataBuffers"); + pBinkGetGPUDataBuffersInfo = (BinkGetGPUDataBuffersInfo_t)GetProcAddress(dll, "BinkGetGPUDataBuffersInfo"); + pBinkSetVideoOnOff = (BinkSetVideoOnOff_t)GetProcAddress(dll, "BinkSetVideoOnOff"); + pBinkSetSoundOnOff = (BinkSetSoundOnOff_t)GetProcAddress(dll, "BinkSetSoundOnOff"); + pBinkSetVolume = (BinkSetVolume_t)GetProcAddress(dll, "BinkSetVolume"); + pBinkSetPan = (BinkSetPan_t)GetProcAddress(dll, "BinkSetPan"); + pBinkSetSpeakerVolumes = (BinkSetSpeakerVolumes_t)GetProcAddress(dll, "BinkSetSpeakerVolumes"); + pBinkService = (BinkService_t)GetProcAddress(dll, "BinkService"); + pBinkShouldSkip = (BinkShouldSkip_t)GetProcAddress(dll, "BinkShouldSkip"); + pBinkControlBackgroundIO = (BinkControlBackgroundIO_t)GetProcAddress(dll, "BinkControlBackgroundIO"); + pBinkSetWillLoop = (BinkSetWillLoop_t)GetProcAddress(dll, "BinkSetWillLoop"); + pBinkStartAsyncThread = (BinkStartAsyncThread_t)GetProcAddress(dll, "BinkStartAsyncThread"); + pBinkDoFrameAsync = (BinkDoFrameAsync_t)GetProcAddress(dll, "BinkDoFrameAsync"); + pBinkDoFrameAsyncMulti = (BinkDoFrameAsyncMulti_t)GetProcAddress(dll, "BinkDoFrameAsyncMulti"); + pBinkDoFrameAsyncWait = (BinkDoFrameAsyncWait_t)GetProcAddress(dll, "BinkDoFrameAsyncWait"); + pBinkRequestStopAsyncThread = (BinkRequestStopAsyncThread_t)GetProcAddress(dll, "BinkRequestStopAsyncThread"); + pBinkWaitStopAsyncThread = (BinkWaitStopAsyncThread_t)GetProcAddress(dll, "BinkWaitStopAsyncThread"); + pBinkOpenTrack = (BinkOpenTrack_t)GetProcAddress(dll, "BinkOpenTrack"); + pBinkCloseTrack = (BinkCloseTrack_t)GetProcAddress(dll, "BinkCloseTrack"); + pBinkGetTrackData = (BinkGetTrackData_t)GetProcAddress(dll, "BinkGetTrackData"); + pBinkGetTrackType = (BinkGetTrackType_t)GetProcAddress(dll, "BinkGetTrackType"); + pBinkGetTrackMaxSize = (BinkGetTrackMaxSize_t)GetProcAddress(dll, "BinkGetTrackMaxSize"); + pBinkGetTrackID = (BinkGetTrackID_t)GetProcAddress(dll, "BinkGetTrackID"); + pBinkGetSummary = (BinkGetSummary_t)GetProcAddress(dll, "BinkGetSummary"); + pBinkGetRealtime = (BinkGetRealtime_t)GetProcAddress(dll, "BinkGetRealtime"); + pBinkSetFileOffset = (BinkSetFileOffset_t)GetProcAddress(dll, "BinkSetFileOffset"); + pBinkSetSoundTrack = (BinkSetSoundTrack_t)GetProcAddress(dll, "BinkSetSoundTrack"); + pBinkSetIO = (BinkSetIO_t)GetProcAddress(dll, "BinkSetIO"); + pBinkSetFrameRate = (BinkSetFrameRate_t)GetProcAddress(dll, "BinkSetFrameRate"); + pBinkSetSimulate = (BinkSetSimulate_t)GetProcAddress(dll, "BinkSetSimulate"); + pBinkSetIOSize = (BinkSetIOSize_t)GetProcAddress(dll, "BinkSetIOSize"); + pBinkSetSoundSystem = (BinkSetSoundSystem_t)GetProcAddress(dll, "BinkSetSoundSystem"); + pBinkSetSoundSystem2 = (BinkSetSoundSystem2_t)GetProcAddress(dll, "BinkSetSoundSystem2"); + pBinkOpenDirectSound = (BinkOpenDirectSound_t)GetProcAddress(dll, "BinkOpenDirectSound"); + pBinkOpenWaveOut = (BinkOpenWaveOut_t)GetProcAddress(dll, "BinkOpenWaveOut"); + pBinkOpenXAudio2 = (BinkOpenXAudio2_t)GetProcAddress(dll, "BinkOpenXAudio2"); + pBinkSetMemory = (BinkSetMemory_t)GetProcAddress(dll, "BinkSetMemory"); + + return 1; +} + +char* read_binary_file_to_memory(const char* filename, size_t* file_size) { + FILE* file = fopen(filename, "rb"); // Use "rb" for binary mode + if (file == NULL) { + perror("Failed to open file"); + return NULL; + } + + // Get file size + fseek(file, 0, SEEK_END); + long size = ftell(file); + rewind(file); + + if (size < 0) { + perror("Failed to determine file size"); + fclose(file); + return NULL; + } + + // Allocate memory. Note: no need for a null terminator since it's not a string. + char* buffer = (char*)malloc(size); + if (buffer == NULL) { + perror("Memory allocation failed"); + fclose(file); + return NULL; + } + + // Read file into buffer + size_t bytes_read = fread(buffer, 1, size, file); + if (bytes_read != (size_t)size) { + perror("Failed to read file"); + free(buffer); + fclose(file); + return NULL; + } + + fclose(file); + + if (file_size) { + *file_size = (size_t)size; + } + + return buffer; +} + +int main() { + if (!LoadBinkDLL()) { + printf("we fucked up\n"); + return 1; + } + + pBinkSetSoundSystem((BINKSNDSYSOPEN)pBinkOpenDirectSound, 0); + pBinkSetMemory((BINKMEMALLOC)malloc, (BINKMEMFREE)free); + pBinkSetIO(NULL); // no io + //pBinkSetTimerRead() // r.i.p. + + size_t size = 0; + char* buffer = read_binary_file_to_memory("you_are_nothing.bk2", &size); + + HBINK bink = NULL; + bink = pBinkOpen(buffer, BINKFROMMEMORY); + + int width = bink->Width, height = bink->Height; + + // Allocate framebuffer + uint32_t* framebuffer = (uint32_t*)malloc(width * height * sizeof(uint32_t)); + if (!framebuffer) return 1; + + // Decode one frame + pBinkDoFrame(bink); + + // Copy frame to our buffer + pBinkCopyToBuffer( + bink, + framebuffer, // dest + width * 4, // destpitch in bytes + height, // destheight + 0, // destx + 0, // desty + BINKSURFACE32 | BINKCOPYALL // flags + ); + + // Create BMP headers + BITMAPFILEHEADER bfh = {0}; + BITMAPINFOHEADER bih = {0}; + + bfh.bfType = 0x4D42; // 'BM' + bfh.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER); + bfh.bfSize = bfh.bfOffBits + width * height * 4; + + bih.biSize = sizeof(BITMAPINFOHEADER); + bih.biWidth = width; + bih.biHeight = -height; // negative = top-down + bih.biPlanes = 1; + bih.biBitCount = 32; + bih.biCompression = 0; // BI_RGB + bih.biSizeImage = width * height * 4; + + // Write BMP + FILE* f = fopen("framebuffer.bmp", "wb"); + if (!f) return 1; + + fwrite(&bfh, sizeof(bfh), 1, f); + fwrite(&bih, sizeof(bih), 1, f); + fwrite(framebuffer, 4, width * height, f); + + fclose(f); + free(framebuffer); + + printf("Saved framebuffer.bmp\n"); + + pBinkClose(bink); + + free(buffer); + + return 0; +} \ No newline at end of file diff --git a/main.exe b/main.exe new file mode 100644 index 0000000..e1699b1 Binary files /dev/null and b/main.exe differ diff --git a/main.ilk b/main.ilk new file mode 100644 index 0000000..0d0be7f Binary files /dev/null and b/main.ilk differ diff --git a/main.obj b/main.obj new file mode 100644 index 0000000..0cb03f3 Binary files /dev/null and b/main.obj differ diff --git a/main.pdb b/main.pdb new file mode 100644 index 0000000..0fdaa9f Binary files /dev/null and b/main.pdb differ diff --git a/ole32.cpp b/ole32.cpp new file mode 100644 index 0000000..fb3a02f --- /dev/null +++ b/ole32.cpp @@ -0,0 +1,44 @@ +typedef void* HWND; +typedef void* LPUNKNOWN; +typedef void* REFIID; +typedef void* REFCLSID; +typedef long HRESULT; +typedef unsigned long DWORD; +typedef unsigned int UINT; +typedef int BOOL; +typedef void* HANDLE; +typedef void* LPVOID; +typedef long LONG; +typedef long LONG_PTR; +typedef const char* LPCSTR; +typedef size_t SIZE_T; +typedef void* HMODULE; +typedef HMODULE HINSTANCE; +typedef void* FARPROC; +typedef DWORD (*LPTHREAD_START_ROUTINE)(LPVOID lpThreadParameter); +typedef union _LARGE_INTEGER { + struct { + unsigned long LowPart; + long HighPart; + }; + long long QuadPart; +} LARGE_INTEGER; +#define S_OK ((HRESULT)0L) +#define TRUE 1 +#define FALSE 0 + +extern "C" { + +// COM stubs +__declspec(dllexport) HRESULT CoCreateInstance(REFCLSID, LPUNKNOWN, DWORD, REFIID, LPVOID* ppv) { + if (ppv) *ppv = nullptr; + return S_OK; +} +__declspec(dllexport) HRESULT CoInitializeEx(LPVOID, DWORD) { return S_OK; } +__declspec(dllexport) void CoUninitialize() {} +__declspec(dllexport) void CoTaskMemFree(LPVOID) {} +__declspec(dllexport) HRESULT PropVariantClear(LPVOID) { return S_OK; } + +BOOL DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) { return TRUE; } + +} diff --git a/ole32.dll b/ole32.dll new file mode 100644 index 0000000..daec45d Binary files /dev/null and b/ole32.dll differ diff --git a/ole32.exp b/ole32.exp new file mode 100644 index 0000000..7a01f9e Binary files /dev/null and b/ole32.exp differ diff --git a/ole32.lib b/ole32.lib new file mode 100644 index 0000000..08e04f9 Binary files /dev/null and b/ole32.lib differ diff --git a/ole32.obj b/ole32.obj new file mode 100644 index 0000000..e79823f Binary files /dev/null and b/ole32.obj differ diff --git a/rrCore.h b/rrCore.h new file mode 100644 index 0000000..0d830f0 --- /dev/null +++ b/rrCore.h @@ -0,0 +1,2322 @@ +/// ======================================================================== +// (C) Copyright 1994- 2014 RAD Game Tools, Inc. Global types header file +// ======================================================================== + +#ifndef __RADRR_COREH__ +#define __RADRR_COREH__ +#define RADCOPYRIGHT "Copyright (C) 1994-2014, RAD Game Tools, Inc." + +// __RAD16__ means 16 bit code (Win16) +// __RAD32__ means 32 bit code (DOS, Win386, Win32s, Mac AND Win64) +// __RAD64__ means 64 bit code (x64) + +// Note oddness - __RAD32__ essentially means "at *least* 32-bit code". +// So, on 64-bit systems, both __RAD32__ and __RAD64__ will be defined. + +// __RADDOS__ means DOS code (16 or 32 bit) +// __RADWIN__ means Windows API (Win16, Win386, Win32s, Win64, Xbox, Xenon) +// __RADWINEXT__ means Windows 386 extender (Win386) +// __RADNT__ means Win32 or Win64 code +// __RADWINRTAPI__ means Windows RT API (Win 8, Win Phone, ARM, Durango) +// __RADMAC__ means Macintosh +// __RADCARBON__ means Carbon +// __RADMACH__ means MachO +// __RADXBOX__ means the XBox console +// __RADXENON__ means the Xenon console +// __RADDURANGO__ or __RADXBOXONE__ means Xbox One +// __RADNGC__ means the Nintendo GameCube +// __RADWII__ means the Nintendo Wii +// __RADWIIU__ means the Nintendo Wii U +// __RADNDS__ means the Nintendo DS +// __RADTWL__ means the Nintendo DSi (__RADNDS__ also defined) +// __RAD3DS__ means the Nintendo 3DS +// __RADPS2__ means the Sony PlayStation 2 +// __RADPSP__ means the Sony PlayStation Portable +// __RADPS3__ means the Sony PlayStation 3 +// __RADPS4__ means the Sony PlayStation 4 +// __RADANDROID__ means Android NDK +// __RADNACL__ means Native Client SDK +// __RADNTBUILDLINUX__ means building Linux on NT +// __RADLINUX__ means actually building on Linux (most likely with GCC) +// __RADPSP2__ means NGP +// __RADBSD__ means a BSD-style UNIX (OS X, FreeBSD, OpenBSD, NetBSD) +// __RADPOSIX__ means POSIX-compliant +// __RADQNX__ means QNX +// __RADIPHONE__ means iphone +// __RADIPHONESIM__ means iphone simulator + +// __RADX86__ means Intel x86 +// __RADMMX__ means Intel x86 MMX instructions are allowed +// __RADX64__ means Intel/AMD x64 (NOT IA64=Itanium) +// __RAD68K__ means 68K +// __RADPPC__ means PowerPC +// __RADMIPS__ means Mips (only R5900 right now) +// __RADARM__ mean ARM processors + +// __RADLITTLEENDIAN__ means processor is little-endian (x86) +// __RADBIGENDIAN__ means processor is big-endian (680x0, PPC) + +// __RADNOVARARGMACROS__ means #defines can't use ... + + #ifdef WINAPI_FAMILY + // If this is #defined, we might be in a Windows Store App. But + // VC++ by default #defines this to a symbolic name, not an integer + // value, and those names are defined in "winapifamily.h". So if + // WINAPI_FAMILY is #defined, #include the header so we can parse it. + #include + #define RAD_WINAPI_IS_APP (!WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)) + #else + #define RAD_WINAPI_IS_APP 0 + #endif + + #ifndef __RADRES__ + // Theoretically, this is to pad structs on platforms that don't support pragma pack or do it poorly. (PS3, PS2) + // In general it is assumed that your padding is set via pragma, so this is just a struct. + #define RADSTRUCT struct + + #ifdef __GNUC_MINOR__ + // make a combined GCC version for testing : + + #define __RAD_GCC_VERSION__ (__GNUC__ * 10000 \ + + __GNUC_MINOR__ * 100 \ + + __GNUC_PATCHLEVEL__) + + /* Test for GCC > 3.2.0 */ + // #if GCC_VERSION > 30200 + #endif + + #if defined(__RADX32__) + + #define __RADX86__ + #define __RADMMX__ + #define __RAD32__ + #define __RADLITTLEENDIAN__ + #define RADINLINE inline + #define RADRESTRICT __restrict + + // known platforms under the RAD generic build type + #if defined(_WIN32) || defined(_Windows) || defined(WIN32) || defined(__WINDOWS__) || defined(_WINDOWS) + #define __RADNT__ + #define __RADWIN__ + #elif (defined(__MWERKS__) && !defined(__INTEL__)) || defined(__MRC__) || defined(THINK_C) || defined(powerc) || defined(macintosh) || defined(__powerc) || defined(__APPLE__) || defined(__MACH__) + #define __RADMAC__ + #undef RADSTRUCT + #define RADSTRUCT struct __attribute__((__packed__)) + #elif defined(linux) + #define __RADLINUX__ + #undef RADSTRUCT + #define RADSTRUCT struct __attribute__((__packed__)) + #endif + +#elif defined(ANDROID) + #define __RADANDROID__ + #define __RAD32__ + #define __RADLITTLEENDIAN__ + #ifdef __i386__ + #define __RADX86__ + #else + #define __RADARM__ + #endif + #define RADINLINE inline + #define RADRESTRICT __restrict + #undef RADSTRUCT + #define RADSTRUCT struct __attribute__((__packed__)) + +#elif defined(__QNX__) + #define __RAD32__ + #define __RADQNX__ + +#ifdef __arm__ + #define __RADARM__ +#elif defined __i386__ + #define __RADX86__ +#else + #error Unknown processor +#endif + #define __RADLITTLEENDIAN__ + #define RADINLINE inline + #define RADRESTRICT __restrict + + #undef RADSTRUCT + #define RADSTRUCT struct __attribute__((__packed__)) +#elif defined(linux) && defined(__arm__) //This should pull in Raspberry Pi as well + + #define __RAD32__ + #define __RADLINUX__ + #define __RADARM__ + #define __RADLITTLEENDIAN__ + #define RADINLINE inline + #define RADRESTRICT __restrict + + #undef RADSTRUCT + #define RADSTRUCT struct __attribute__((__packed__)) + +#elif defined(__native_client__) + #define __RADNACL__ + #define __RAD32__ + #define __RADLITTLEENDIAN__ + #define __RADX86__ + #define RADINLINE inline + #define RADRESTRICT __restrict + + #undef RADSTRUCT + #define RADSTRUCT struct __attribute__((__packed__)) + + #elif defined(_DURANGO) || defined(_SEKRIT) || defined(_SEKRIT1) || defined(_XBOX_ONE) + + #define __RADDURANGO__ 1 + #define __RADXBOXONE__ 1 + #if !defined(__RADSEKRIT__) // keep sekrit around for a bit for compat + #define __RADSEKRIT__ 1 + #endif + + #define __RADWIN__ + #define __RAD32__ + #define __RAD64__ + #define __RADX64__ + #define __RADMMX__ + #define __RADX86__ + #define __RAD64REGS__ + #define __RADLITTLEENDIAN__ + #define RADINLINE __inline + #define RADRESTRICT __restrict + #define __RADWINRTAPI__ + + #elif defined(__ORBIS__) + + #define __RADPS4__ + #if !defined(__RADSEKRIT2__) // keep sekrit2 around for a bit for compat + #define __RADSEKRIT2__ 1 + #endif + #define __RAD32__ + #define __RAD64__ + #define __RADX64__ + #define __RADMMX__ + #define __RADX86__ + #define __RAD64REGS__ + #define __RADLITTLEENDIAN__ + #define RADINLINE inline + #define RADRESTRICT __restrict + + #undef RADSTRUCT + #define RADSTRUCT struct __attribute__((__packed__)) + + #elif defined(WINAPI_FAMILY) && RAD_WINAPI_IS_APP + + #define __RADWINRTAPI__ + #define __RADWIN__ + #define RADINLINE __inline + #define RADRESTRICT __restrict + + #if defined(_M_IX86) // WinRT on x86 + + #define __RAD32__ + #define __RADX86__ + #define __RADMMX__ + #define __RADLITTLEENDIAN__ + + #elif defined(_M_X64) // WinRT on x64 + #define __RAD32__ + #define __RAD64__ + #define __RADX86__ + #define __RADX64__ + #define __RADMMX__ + #define __RAD64REGS__ + #define __RADLITTLEENDIAN__ + + #elif defined(_M_ARM) // WinRT on ARM + + #define __RAD32__ + #define __RADARM__ + #define __RADLITTLEENDIAN__ + + #else + + #error Unrecognized WinRT platform! + + #endif + + #elif defined(_WIN64) + + #define __RADWIN__ + #define __RADNT__ + // See note at top for why both __RAD32__ and __RAD64__ are defined. + #define __RAD32__ + #define __RAD64__ + #define __RADX64__ + #define __RADMMX__ + #define __RADX86__ + #define __RAD64REGS__ + #define __RADLITTLEENDIAN__ + #define RADINLINE __inline + #define RADRESTRICT __restrict + + #elif defined(GENERIC_ARM) + + #define __RAD32__ + #define __RADARM__ + #define __RADLITTLEENDIAN__ + #define __RADFIXEDPOINT__ + #define RADINLINE inline + #if (defined(__GCC__) || defined(__GNUC__)) + #define RADRESTRICT __restrict + #else + #define RADRESTRICT // __restrict not supported on cw + #endif + #undef RADSTRUCT + #define RADSTRUCT struct __attribute__((__packed__)) + + #elif defined(CAFE) // has to be before HOLLYWOOD_REV since it also defines it + + #define __RADWIIU__ + #define __RAD32__ + #define __RADPPC__ + #define __RADBIGENDIAN__ + #define RADINLINE inline + #define RADRESTRICT __restrict + #undef RADSTRUCT + #define RADSTRUCT struct __attribute__((__packed__)) + + + #elif defined(HOLLYWOOD_REV) || defined(REVOLUTION) + + #define __RADWII__ + #define __RAD32__ + #define __RADPPC__ + #define __RADBIGENDIAN__ + #define RADINLINE inline + #define RADRESTRICT __restrict + + #elif defined(NN_PLATFORM_CTR) + + #define __RAD3DS__ + #define __RAD32__ + #define __RADARM__ + #define __RADLITTLEENDIAN__ + #define RADINLINE inline + #define RADRESTRICT + #undef RADSTRUCT + #define RADSTRUCT struct __attribute__((__packed__)) + + #elif defined(GEKKO) + + #define __RADNGC__ + #define __RAD32__ + #define __RADPPC__ + #define __RADBIGENDIAN__ + #define RADINLINE inline + #define RADRESTRICT // __restrict not supported on cw + + #elif defined(SDK_ARM9) || defined(SDK_TWL) || (defined(__arm) && defined(__MWERKS__)) + + #define __RADNDS__ + #define __RAD32__ + #define __RADARM__ + #define __RADLITTLEENDIAN__ + #define __RADFIXEDPOINT__ + #define RADINLINE inline + #if (defined(__GCC__) || defined(__GNUC__)) + #define RADRESTRICT __restrict + #else + #define RADRESTRICT // __restrict not supported on cw + #endif + + #if defined(SDK_TWL) + #define __RADTWL__ + #endif + + #elif defined(R5900) + + #define __RADPS2__ + #define __RAD32__ + #define __RADMIPS__ + #define __RADLITTLEENDIAN__ + #define RADINLINE inline + #define RADRESTRICT __restrict + #define __RAD64REGS__ + #define U128 u_long128 + + #if !defined(__MWERKS__) + #undef RADSTRUCT + #define RADSTRUCT struct __attribute__((__packed__)) + #endif + + #elif defined(__psp__) + + #define __RADPSP__ + #define __RAD32__ + #define __RADMIPS__ + #define __RADLITTLEENDIAN__ + #define RADINLINE inline + #define RADRESTRICT __restrict + + #undef RADSTRUCT + #define RADSTRUCT struct __attribute__((__packed__)) + + #elif defined(__psp2__) + + #undef RADSTRUCT + #define RADSTRUCT struct __attribute__((__packed__)) + + #define __RADPSP2__ + #define __RAD32__ + #define __RADARM__ + #define __RADLITTLEENDIAN__ + #define RADINLINE inline + #define RADRESTRICT __restrict + + // need packed attribute for struct with snc? + #elif defined(__CELLOS_LV2__) + + // CB change : 10-29-10 : RAD64REGS on PPU but NOT SPU + + #ifdef __SPU__ + #define __RADSPU__ + #define __RAD32__ + #define __RADCELL__ + #define __RADBIGENDIAN__ + #define RADINLINE inline + #define RADRESTRICT __restrict + #else + #define __RAD64REGS__ + #define __RADPS3__ + #define __RADPPC__ + #define __RAD32__ + #define __RADCELL__ + #define __RADBIGENDIAN__ + #define RADINLINE inline + #define RADRESTRICT __restrict + #define __RADALTIVEC__ + #endif + + #undef RADSTRUCT + #define RADSTRUCT struct __attribute__((__packed__)) + + #ifndef __LP32__ + #error "PS3 32bit ABI support only" + #endif + #elif (defined(__MWERKS__) && !defined(__INTEL__)) || defined(__MRC__) || defined(THINK_C) || defined(powerc) || defined(macintosh) || defined(__powerc) || defined(__APPLE__) || defined(__MACH__) + #ifdef __APPLE__ + #include "TargetConditionals.h" + #endif + + #if ((defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE) || (defined(TARGET_IPHONE_SIMULATOR) && TARGET_IPHONE_SIMULATOR)) + + // iPhone/iPad/iOS + #define __RADIPHONE__ + #define __RADMACAPI__ + + #define __RAD32__ + #if defined(__x86_64__) + #define __RAD64__ + #endif + + #define __RADLITTLEENDIAN__ + #define RADINLINE inline + #define RADRESTRICT __restrict + #define __RADMACH__ + + #undef RADSTRUCT + #define RADSTRUCT struct __attribute__((__packed__)) + + #if defined(TARGET_IPHONE_SIMULATOR) && TARGET_IPHONE_SIMULATOR + #if defined( __x86_64__) + #define __RADX64__ + #else + #define __RADX86__ + #endif + #define __RADIPHONESIM__ + #elif defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE + #define __RADARM__ + #endif + #else + + // An actual MacOSX machine + #define __RADMAC__ + #define __RADMACAPI__ + + #if defined(powerc) || defined(__powerc) || defined(__ppc__) + #define __RADPPC__ + #define __RADBIGENDIAN__ + #define __RADALTIVEC__ + #define RADRESTRICT + #elif defined(__i386__) + #define __RADX86__ + #define __RADMMX__ + #define __RADLITTLEENDIAN__ + #define RADRESTRICT __restrict + #elif defined(__x86_64__) + #define __RAD32__ + #define __RAD64__ + #define __RADX86__ + #define __RADX64__ + #define __RAD64REGS__ + #define __RADMMX__ + #define __RADLITTLEENDIAN__ + #define RADRESTRICT __restrict + #else + #define __RAD68K__ + #define __RADBIGENDIAN__ + #define __RADALTIVEC__ + #define RADRESTRICT + #endif + + #define __RAD32__ + + #if defined(__MWERKS__) + #if (defined(__cplusplus) || ! __option(only_std_keywords)) + #define RADINLINE inline + #endif + #ifdef __MACH__ + #define __RADMACH__ + #endif + #elif defined(__MRC__) + #if defined(__cplusplus) + #define RADINLINE inline + #endif + #elif defined(__GNUC__) || defined(__GNUG__) || defined(__MACH__) + #define RADINLINE inline + #define __RADMACH__ + + #undef RADRESTRICT /* could have been defined above... */ + #define RADRESTRICT __restrict + + #undef RADSTRUCT + #define RADSTRUCT struct __attribute__((__packed__)) + #endif + + #ifdef __RADX86__ + #ifndef __RADCARBON__ + #define __RADCARBON__ + #endif + #endif + + #ifdef TARGET_API_MAC_CARBON + #if TARGET_API_MAC_CARBON + #ifndef __RADCARBON__ + #define __RADCARBON__ + #endif + #endif + #endif + #endif + #elif defined(linux) + + #define __RADLINUX__ + #define __RADMMX__ + #define __RADLITTLEENDIAN__ + #define __RADX86__ + #ifdef __x86_64 + #define __RAD32__ + #define __RAD64__ + #define __RADX64__ + #define __RAD64REGS__ + #else + #define __RAD32__ + #endif + #define RADINLINE inline + #define RADRESTRICT __restrict + + #undef RADSTRUCT + #define RADSTRUCT struct __attribute__((__packed__)) + + #else + + #if _MSC_VER >= 1400 + #undef RADRESTRICT + #define RADRESTRICT __restrict + #else + #define RADRESTRICT + #define __RADNOVARARGMACROS__ + #endif + + #if defined(_XENON) || ( defined(_XBOX_VER) && (_XBOX_VER == 200) ) + // Remember that Xenon also defines _XBOX + #define __RADPPC__ + #define __RADBIGENDIAN__ + #define __RADALTIVEC__ + #else + #define __RADX86__ + #define __RADMMX__ + #define __RADLITTLEENDIAN__ + #endif + + #ifdef __MWERKS__ + #define _WIN32 + #endif + + #ifdef __DOS__ + #define __RADDOS__ + #define S64_DEFINED // turn off these types + #define U64_DEFINED + #define S64 double //should error + #define U64 double //should error + #define __RADNOVARARGMACROS__ + #endif + + #ifdef __386__ + #define __RAD32__ + #endif + + #ifdef _Windows //For Borland + #ifdef __WIN32__ + #define WIN32 + #else + #define __WINDOWS__ + #endif + #endif + + #ifdef _WINDOWS //For MS + #ifndef _WIN32 + #define __WINDOWS__ + #endif + #endif + + #ifdef _WIN32 + #if defined(_XENON) || ( defined(_XBOX_VER) && (_XBOX_VER == 200) ) + // Remember that Xenon also defines _XBOX + #define __RADXENON__ + #define __RAD64REGS__ + #elif defined(_XBOX) + #define __RADXBOX__ + #elif !defined(__RADWINRTAPI__) + #define __RADNT__ + #endif + #define __RADWIN__ + #define __RAD32__ + #else + #ifdef __NT__ + #if defined(_XENON) || (_XBOX_VER == 200) + // Remember that Xenon also defines _XBOX + #define __RADXENON__ + #define __RAD64REGS__ + #elif defined(_XBOX) + #define __RADXBOX__ + #else + #define __RADNT__ + #endif + #define __RADWIN__ + #define __RAD32__ + #else + #ifdef __WINDOWS_386__ + #define __RADWIN__ + #define __RADWINEXT__ + #define __RAD32__ + #define S64_DEFINED // turn off these types + #define U64_DEFINED + #define S64 double //should error + #define U64 double //should error + #else + #ifdef __WINDOWS__ + #define __RADWIN__ + #define __RAD16__ + #else + #ifdef WIN32 + #if defined(_XENON) || (_XBOX_VER == 200) + // Remember that Xenon also defines _XBOX + #define __RADXENON__ + #elif defined(_XBOX) + #define __RADXBOX__ + #else + #define __RADNT__ + #endif + #define __RADWIN__ + #define __RAD32__ + #endif + #endif + #endif + #endif + #endif + + #ifdef __WATCOMC__ + #define RADINLINE + #else + #define RADINLINE __inline + #endif + #endif + + #if defined __RADMAC__ || defined __RADIPHONE__ + #define __RADBSD__ + #endif + + #if defined __RADBSD__ || defined __RADLINUX__ + #define __RADPOSIX__ + #endif + + #if (!defined(__RADDOS__) && !defined(__RADWIN__) && !defined(__RADMAC__) && \ + !defined(__RADNGC__) && !defined(__RADNDS__) && !defined(__RADXBOX__) && \ + !defined(__RADXENON__) && !defined(__RADDURANGO__) && !defined(__RADPS4__) && !defined(__RADLINUX__) && !defined(__RADPS2__) && \ + !defined(__RADPSP__) && !defined(__RADPSP2__) && !defined(__RADPS3__) && !defined(__RADSPU__) && \ + !defined(__RADWII__) && !defined(__RADIPHONE__) && !defined(__RADX32__) && !defined(__RADARM__) && \ + !defined(__RADWIIU__) && !defined(__RADANDROID__) && !defined(__RADNACL__) && !defined (__RADQNX__) ) + #error "RAD.H did not detect your platform. Define DOS, WINDOWS, WIN32, macintosh, powerpc, or appropriate console." + #endif + + + #ifdef __RADFINAL__ + #define RADTODO(str) { char __str[0]=str; } + #else + #define RADTODO(str) + #endif + + #ifdef __RADX32__ + #if defined(_MSC_VER) + #define RADLINK __stdcall + #define RADEXPLINK __stdcall + #else + #define RADLINK __attribute__((stdcall)) + #define RADEXPLINK __attribute__((stdcall)) + #endif + #define RADEXPFUNC RADDEFFUNC + + #elif (defined(__RADNGC__) || defined(__RADWII__) || defined( __RADPS2__) || \ + defined(__RADPSP__) || defined(__RADPSP2__) || defined(__RADPS3__) || \ + defined(__RADSPU__) || defined(__RADNDS__) || defined(__RADIPHONE__) || \ + (defined(__RADARM__) && !defined(__RADWINRTAPI__)) || defined(__RADWIIU__) || defined(__RADPS4__) ) + + #define RADLINK + #define RADEXPLINK + #define RADEXPFUNC RADDEFFUNC + #define RADASMLINK + + #elif defined(__RADANDROID__) + #define RADLINK + #define RADEXPLINK + #define RADEXPFUNC RADDEFFUNC + #define RADASMLINK + #elif defined(__RADNACL__) + #define RADLINK + #define RADEXPLINK + #define RADEXPFUNC RADDEFFUNC + #define RADASMLINK + #elif defined(__RADLINUX__) || defined (__RADQNX__) + + #ifdef __RAD64__ + #define RADLINK + #define RADEXPLINK + #else + #define RADLINK __attribute__((cdecl)) + #define RADEXPLINK __attribute__((cdecl)) + #endif + + #define RADEXPFUNC RADDEFFUNC + #define RADASMLINK + + #elif defined(__RADMAC__) + + // this define is for CodeWarrior 11's stupid new libs (even though + // we don't use longlong's). + + #define __MSL_LONGLONG_SUPPORT__ + + #define RADLINK + #define RADEXPLINK + + #if defined(__CFM68K__) || defined(__MWERKS__) + #ifdef __RADINDLL__ + #define RADEXPFUNC RADDEFFUNC __declspec(export) + #else + #define RADEXPFUNC RADDEFFUNC __declspec(import) + #endif + #else + #if defined(__RADMACH__) && !defined(__MWERKS__) + #ifdef __RADINDLL__ + #define RADEXPFUNC RADDEFFUNC __attribute__((visibility("default"))) + #else + #define RADEXPFUNC RADDEFFUNC + #endif + #else + #define RADEXPFUNC RADDEFFUNC + #endif + #endif + #define RADASMLINK + + #else + + #ifdef __RADNT__ + #ifndef _WIN32 + #define _WIN32 + #endif + #ifndef WIN32 + #define WIN32 + #endif + #endif + + #ifdef __RADWIN__ + #ifdef __RAD32__ + + #ifdef __RADXBOX__ + + #define RADLINK __stdcall + #define RADEXPLINK __stdcall + #define RADEXPFUNC RADDEFFUNC + + #elif defined(__RADXENON__) || defined(__RADDURANGO__) + + #define RADLINK __stdcall + #define RADEXPLINK __stdcall + + #define RADEXPFUNC RADDEFFUNC + + #elif defined(__RADWINRTAPI__) + + #define RADLINK __stdcall + #define RADEXPLINK __stdcall + + #if ( defined(__RADINSTATICLIB__) || defined(__RADNOEXPORTS__ ) || ( defined(__RADNOEXEEXPORTS__) && ( !defined(__RADINDLL__) ) && ( !defined(__RADINSTATICLIB__) ) ) ) + #define RADEXPFUNC RADDEFFUNC + #else + #ifndef __RADINDLL__ + #define RADEXPFUNC RADDEFFUNC __declspec(dllimport) + #else + #define RADEXPFUNC RADDEFFUNC __declspec(dllexport) + #endif + #endif + + #elif defined(__RADNTBUILDLINUX__) + + #define RADLINK __cdecl + #define RADEXPLINK __cdecl + #define RADEXPFUNC RADDEFFUNC + + #else + #ifdef __RADNT__ + + #define RADLINK __stdcall + #define RADEXPLINK __stdcall + + #if ( defined(__RADINSTATICLIB__) || defined(__RADNOEXPORTS__ ) || ( defined(__RADNOEXEEXPORTS__) && ( !defined(__RADINDLL__) ) && ( !defined(__RADINSTATICLIB__) ) ) ) + #define RADEXPFUNC RADDEFFUNC + #else + #ifndef __RADINDLL__ + #define RADEXPFUNC RADDEFFUNC __declspec(dllimport) + #ifdef __BORLANDC__ + #if __BORLANDC__<=0x460 + #undef RADEXPFUNC + #define RADEXPFUNC RADDEFFUNC + #endif + #endif + #else + #define RADEXPFUNC RADDEFFUNC __declspec(dllexport) + #endif + #endif + #else + #define RADLINK __pascal + #define RADEXPLINK __far __pascal + #define RADEXPFUNC RADDEFFUNC + #endif + #endif + #else + #define RADLINK __pascal + #define RADEXPLINK __far __pascal __export + #define RADEXPFUNC RADDEFFUNC + #endif + #else + #define RADLINK __pascal + #define RADEXPLINK __pascal + #define RADEXPFUNC RADDEFFUNC + #endif + + #define RADASMLINK __cdecl + + #endif + + #if !defined(__RADXBOX__) && !defined(__RADXENON__) && !defined(__RADDURANGO__) && !defined(__RADXBOXONE__) + #ifdef __RADWIN__ + #ifndef _WINDOWS + #define _WINDOWS + #endif + #endif + #endif + + #ifdef __RADLITTLEENDIAN__ + #ifdef __RADBIGENDIAN__ + #error both endians !? + #endif + #endif + + #if !defined(__RADLITTLEENDIAN__) && !defined(__RADBIGENDIAN__) + #error neither endian! + #endif + + + //----------------------------------------------------------------- + + #ifndef RADDEFFUNC + + #ifdef __cplusplus + #define RADDEFFUNC extern "C" + #define RADDEFSTART extern "C" { + #define RADDEFEND } + #define RADDEFINEDATA extern "C" + #define RADDECLAREDATA extern "C" + #define RADDEFAULT( val ) =val + + #define RR_NAMESPACE rr + #define RR_NAMESPACE_START namespace RR_NAMESPACE { + #define RR_NAMESPACE_END }; + #define RR_NAMESPACE_USE using namespace RR_NAMESPACE; + + #else + #define RADDEFFUNC + #define RADDEFSTART + #define RADDEFEND + #define RADDEFINEDATA + #define RADDECLAREDATA extern + #define RADDEFAULT( val ) + + #define RR_NAMESPACE + #define RR_NAMESPACE_START + #define RR_NAMESPACE_END + #define RR_NAMESPACE_USE + + #endif + + #endif + + // probably s.b: RAD_DECLARE_ALIGNED(type, name, alignment) + #if (defined(__RADWII__) || defined(__RADWIIU__) || defined(__RADPSP__) || defined(__RADPSP2__) || \ + defined(__RADPS3__) || defined(__RADSPU__) || defined(__RADPS4__) || \ + defined(__RADLINUX__) || defined(__RADMAC__)) || defined(__RADNDS__) || defined(__RAD3DS__) || \ + defined(__RADIPHONE__) || defined(__RADANDROID__) || defined (__RADQNX__) + #define RAD_ALIGN(type,var,num) type __attribute__ ((aligned (num))) var + #elif (defined(__RADNGC__) || defined(__RADPS2__)) + #define RAD_ALIGN(type,var,num) __attribute__ ((aligned (num))) type var + #elif (defined(_MSC_VER) && (_MSC_VER >= 1300)) || defined(__RADWINRTAPI__) + #define RAD_ALIGN(type,var,num) type __declspec(align(num)) var + #else + // NOTE: / / is a guaranteed parse error in C/C++. + #define RAD_ALIGN(type,var,num) RAD_ALIGN_USED_BUT_NOT_DEFINED / / + #endif + + // WARNING : RAD_TLS should really only be used for debug/tools stuff + // it's not reliable because even if we are built as a lib, our lib can + // be put into a DLL and then it doesn't work + #if defined(__RADNT__) || defined(__RADXENON__) + #ifndef __RADINDLL__ + // note that you can't use this in windows DLLs + #define RAD_TLS(type,var) __declspec(thread) type var + #endif + #elif defined(__RADPS3__) || defined(__RADLINUX__) || defined(__RADMAC__) + // works on PS3/gcc I believe : + #define RAD_TLS(type,var) __thread type var + #else + // RAD_TLS not defined + #endif + + // Note that __RAD16__/__RAD32__/__RAD64__ refers to the size of a pointer. + // The size of integers is specified explicitly in the code, i.e. u32 or whatever. + + #define RAD_S8 signed char + #define RAD_U8 unsigned char + + #if defined(__RAD64__) + // Remember that __RAD32__ will also be defined! + #if defined(__RADX64__) + // x64 still has 32-bit ints! + #define RAD_U32 unsigned int + #define RAD_S32 signed int + // But pointers are 64 bits. + #if (_MSC_VER >= 1300 && defined(_Wp64) && _Wp64 ) + #define RAD_SINTa __w64 signed __int64 + #define RAD_UINTa __w64 unsigned __int64 + #else // non-vc.net compiler or /Wp64 turned off + #define RAD_UINTa unsigned long long + #define RAD_SINTa signed long long + #endif + #else + #error Unknown 64-bit processor (see radbase.h) + #endif + #elif defined(__RAD32__) + #define RAD_U32 unsigned int + #define RAD_S32 signed int + // Pointers are 32 bits. + + #if ( ( defined(_MSC_VER) && (_MSC_VER >= 1300 ) ) && ( defined(_Wp64) && ( _Wp64 ) ) ) + #define RAD_SINTa __w64 signed long + #define RAD_UINTa __w64 unsigned long + #else // non-vc.net compiler or /Wp64 turned off + #ifdef _Wp64 + #define RAD_SINTa signed long + #define RAD_UINTa unsigned long + #else + #define RAD_SINTa signed int + #define RAD_UINTa unsigned int + #endif + #endif + #else + #define RAD_U32 unsigned long + #define RAD_S32 signed long + // Pointers in 16-bit land are still 32 bits. + #define RAD_UINTa unsigned long + #define RAD_SINTa signed long + #endif + + #define RAD_F32 float + #if defined(__RADPS2__) || defined(__RADPSP__) + typedef RADSTRUCT RAD_F64 // do this so that we don't accidentally use doubles + { // while using the same space + RAD_U32 vals[ 2 ]; + } RAD_F64; + #define RAD_F64_OR_32 float // type is F64 if available, otherwise F32 + #else + #define RAD_F64 double + #define RAD_F64_OR_32 double // type is F64 if available, otherwise F32 + #endif + + #if (defined(__RADMAC__) || defined(__MRC__) || defined( __RADNGC__ ) || \ + defined(__RADLINUX__) || defined( __RADWII__ ) || defined(__RADWIIU__) || \ + defined(__RADNDS__) || defined(__RADPSP__) || defined(__RADPS3__) || defined(__RADPS4__) || \ + defined(__RADSPU__) || defined(__RADIPHONE__) || defined(__RADNACL__) || defined( __RADANDROID__) || defined( __RADQNX__ ) ) + #define RAD_U64 unsigned long long + #define RAD_S64 signed long long + #elif defined(__RADPS2__) + #define RAD_U64 unsigned long + #define RAD_S64 signed long + #elif defined(__RADARM__) + #define RAD_U64 unsigned long long + #define RAD_S64 signed long long + #elif defined(__RADX64__) || defined(__RAD32__) + #define RAD_U64 unsigned __int64 + #define RAD_S64 signed __int64 + #else + // 16-bit + typedef RADSTRUCT RAD_U64 // do this so that we don't accidentally use U64s + { // while using the same space + RAD_U32 vals[ 2 ]; + } RAD_U64; + typedef RADSTRUCT RAD_S64 // do this so that we don't accidentally use S64s + { // while using the same space + RAD_S32 vals[ 2 ]; + } RAD_S64; + #endif + + #if defined(__RAD32__) + #define PTR4 + #define RAD_U16 unsigned short + #define RAD_S16 signed short + #else + #define PTR4 __far + #define RAD_U16 unsigned int + #define RAD_S16 signed int + #endif + + //------------------------------------------------- + // RAD_PTRBITS and such defined here without using sizeof() + // so that they can be used in align() and other macros + + #ifdef __RAD64__ + + #define RAD_PTRBITS 64 + #define RAD_PTRBYTES 8 + #define RAD_TWOPTRBYTES 16 + + #else + + #define RAD_PTRBITS 32 + #define RAD_PTRBYTES 4 + #define RAD_TWOPTRBYTES 8 + + #endif + + + //------------------------------------------------- + // UINTr = int the size of a register + + #ifdef __RAD64REGS__ + + #define RAD_UINTr RAD_U64 + #define RAD_SINTr RAD_S64 + + #else + + #define RAD_UINTr RAD_U32 + #define RAD_SINTr RAD_S32 + + #endif + + //=========================================================================== + + /* + // CB : meh this is enough of a mess that it's probably best to just let each + #if defined(__RADX86__) && defined(_MSC_VER) && _MSC_VER >= 1300 + #define __RADX86INTRIN2003__ + #endif + */ + + // RADASSUME(expr) tells the compiler that expr is always true + // RADUNREACHABLE must never be reachable - even in event of error + // eg. it's okay for compiler to generate completely invalid code after RADUNREACHABLE + + #ifdef _MSC_VER + #define RADFORCEINLINE __forceinline + #if _MSC_VER >= 1300 + #define RADNOINLINE __declspec(noinline) + #else + #define RADNOINLINE + #endif + #define RADUNREACHABLE __assume(0) + #define RADASSUME(exp) __assume(exp) + #elif defined(__clang__) + #ifdef _DEBUG + #define RADFORCEINLINE inline + #else + #define RADFORCEINLINE inline __attribute((always_inline)) + #endif + #define RADNOINLINE __attribute__((noinline)) + + #define RADUNREACHABLE __builtin_unreachable() + + #if __has_builtin(__builtin_assume) + #define RADASSUME(exp) __builtin_assume(exp) + #else + #define RADASSUME(exp) RAD_STATEMENT_WRAPPER( if ( ! (exp) ) __builtin_unreachable(); ) + #endif + #elif (defined(__GCC__) || defined(__GNUC__)) || defined(ANDROID) + #ifdef _DEBUG + #define RADFORCEINLINE inline + #else + #define RADFORCEINLINE inline __attribute((always_inline)) + #endif + #define RADNOINLINE __attribute__((noinline)) + + #if __RAD_GCC_VERSION__ >= 40500 + #define RADUNREACHABLE __builtin_unreachable() + #define RADASSUME(exp) RAD_STATEMENT_WRAPPER( if ( ! (exp) ) __builtin_unreachable(); ) + #else + #define RADUNREACHABLE RAD_INFINITE_LOOP( RR_BREAK(); ) + #define RADASSUME(exp) + #endif + #elif defined(__CWCC__) + #define RADFORCEINLINE inline + #define RADNOINLINE __attribute__((never_inline)) + #define RADUNREACHABLE + #define RADASSUME(x) (void)0 + #else + // ? #define RADFORCEINLINE ? + #define RADFORCEINLINE inline + #define RADNOINLINE + #define RADASSUME(x) (void)0 + #endif + + //=========================================================================== + + // RAD_ALIGN_HINT tells the compiler how a given pointer is aligned + // it *must* be true, but the compiler may or may not use that information + // it is not for cases where the pointer is to an inherently aligned data type, + // it's when the compiler cannot tell the alignment but you have extra information. + // eg : + // U8 * ptr = rrMallocAligned(256,16); + // RAD_ALIGN_HINT(ptr,16,0); + + #ifdef __RADSPU__ + #define RAD_ALIGN_HINT(ptr,alignment,offset) __align_hint(ptr,alignment,offset); RR_ASSERT( ((UINTa)(ptr) & ((alignment)-1)) == (UINTa)(offset) ) + #else + #define RAD_ALIGN_HINT(ptr,alignment,offset) RADASSUME( ((UINTa)(ptr) & ((alignment)-1)) == (UINTa)(offset) ) + #endif + + //=========================================================================== + + // RAD_EXPECT is to tell the compiler the *likely* value of an expression + // different than RADASSUME in that expr might not have that value + // it's use for branch code layout and static branch prediction + // condition can technically be a variable but should usually be 0 or 1 + + #if (defined(__GCC__) || defined(__GNUC__)) || defined(__clang__) + + // __builtin_expect returns value of expr + #define RAD_EXPECT(expr,cond) __builtin_expect(expr,cond) + + #else + + #define RAD_EXPECT(expr,cond) (expr) + + #endif + + // helpers for doing an if ( ) with expect : + // if ( RAD_LIKELY(expr) ) { ... } + + #define RAD_LIKELY(expr) RAD_EXPECT(expr,1) + #define RAD_UNLIKELY(expr) RAD_EXPECT(expr,0) + + //=========================================================================== + + // __RADX86ASM__ means you can use __asm {} style inline assembly + #if defined(__RADX86__) && !defined(__RADX64__) && defined(_MSC_VER) + #define __RADX86ASM__ + #endif + + //------------------------------------------------- + // typedefs : + + #ifndef RADNOTYPEDEFS + + #ifndef S8_DEFINED + #define S8_DEFINED + typedef RAD_S8 S8; + #endif + + #ifndef U8_DEFINED + #define U8_DEFINED + typedef RAD_U8 U8; + #endif + + #ifndef S16_DEFINED + #define S16_DEFINED + typedef RAD_S16 S16; + #endif + + #ifndef U16_DEFINED + #define U16_DEFINED + typedef RAD_U16 U16; + #endif + + #ifndef S32_DEFINED + #define S32_DEFINED + typedef RAD_S32 S32; + #endif + + #ifndef U32_DEFINED + #define U32_DEFINED + typedef RAD_U32 U32; + #endif + + #ifndef S64_DEFINED + #define S64_DEFINED + typedef RAD_S64 S64; + #endif + + #ifndef U64_DEFINED + #define U64_DEFINED + typedef RAD_U64 U64; + #endif + + #ifndef F32_DEFINED + #define F32_DEFINED + typedef RAD_F32 F32; + #endif + + #ifndef F64_DEFINED + #define F64_DEFINED + typedef RAD_F64 F64; + #endif + + #ifndef F64_OR_32_DEFINED + #define F64_OR_32_DEFINED + typedef RAD_F64_OR_32 F64_OR_32; + #endif + + // UINTa and SINTa are the ints big enough for an address + + #ifndef SINTa_DEFINED + #define SINTa_DEFINED + typedef RAD_SINTa SINTa; + #endif + + #ifndef UINTa_DEFINED + #define UINTa_DEFINED + typedef RAD_UINTa UINTa; + #endif + + #ifndef UINTr_DEFINED + #define UINTr_DEFINED + typedef RAD_UINTr UINTr; + #endif + + #ifndef SINTr_DEFINED + #define SINTr_DEFINED + typedef RAD_SINTr SINTr; + #endif + + #elif !defined(RADNOTYPEDEFINES) + + #ifndef S8_DEFINED + #define S8_DEFINED + #define S8 RAD_S8 + #endif + + #ifndef U8_DEFINED + #define U8_DEFINED + #define U8 RAD_U8 + #endif + + #ifndef S16_DEFINED + #define S16_DEFINED + #define S16 RAD_S16 + #endif + + #ifndef U16_DEFINED + #define U16_DEFINED + #define U16 RAD_U16 + #endif + + #ifndef S32_DEFINED + #define S32_DEFINED + #define S32 RAD_S32 + #endif + + #ifndef U32_DEFINED + #define U32_DEFINED + #define U32 RAD_U32 + #endif + + #ifndef S64_DEFINED + #define S64_DEFINED + #define S64 RAD_S64 + #endif + + #ifndef U64_DEFINED + #define U64_DEFINED + #define U64 RAD_U64 + #endif + + #ifndef F32_DEFINED + #define F32_DEFINED + #define F32 RAD_F32 + #endif + + #ifndef F64_DEFINED + #define F64_DEFINED + #define F64 RAD_F64 + #endif + + #ifndef F64_OR_32_DEFINED + #define F64_OR_32_DEFINED + #define F64_OR_32 RAD_F64_OR_32 + #endif + + // UINTa and SINTa are the ints big enough for an address (pointer) + #ifndef SINTa_DEFINED + #define SINTa_DEFINED + #define SINTa RAD_SINTa + #endif + + #ifndef UINTa_DEFINED + #define UINTa_DEFINED + #define UINTa RAD_UINTa + #endif + + #ifndef UINTr_DEFINED + #define UINTr_DEFINED + #define UINTr RAD_UINTr + #endif + + #ifndef SINTr_DEFINED + #define SINTr_DEFINED + #define SINTr RAD_SINTr + #endif + + #endif + + /// Some error-checking. + #if defined(__RAD64__) && !defined(__RAD32__) + // See top of file for why this is. + #error __RAD64__ must not be defined without __RAD32__ (see radbase.h) + #endif + +#ifdef _MSC_VER + // microsoft compilers + + #if _MSC_VER >= 1400 + #define RAD_STATEMENT_START \ + do { + + #define RAD_STATEMENT_END_FALSE \ + __pragma(warning(push)) \ + __pragma(warning(disable:4127)) \ + } while(0) \ + __pragma(warning(pop)) + + #define RAD_STATEMENT_END_TRUE \ + __pragma(warning(push)) \ + __pragma(warning(disable:4127)) \ + } while(1) \ + __pragma(warning(pop)) + + #else + #define RAD_USE_STANDARD_LOOP_CONSTRUCT + #endif +#else + #define RAD_USE_STANDARD_LOOP_CONSTRUCT +#endif + +#ifdef RAD_USE_STANDARD_LOOP_CONSTRUCT + #define RAD_STATEMENT_START \ + do { + + #define RAD_STATEMENT_END_FALSE \ + } while ( (void)0,0 ) + + #define RAD_STATEMENT_END_TRUE \ + } while ( (void)1,1 ) + +#endif + +#define RAD_STATEMENT_WRAPPER( code ) \ + RAD_STATEMENT_START \ + code \ + RAD_STATEMENT_END_FALSE + +#define RAD_INFINITE_LOOP( code ) \ + RAD_STATEMENT_START \ + code \ + RAD_STATEMENT_END_TRUE + + +// Must be placed after variable declarations for code compiled as .c +#if defined(_MSC_VER) && _MSC_VER >= 1700 // in 2012 aka 11.0 and later +# define RR_UNUSED_VARIABLE(x) (void) x +#else +# define RR_UNUSED_VARIABLE(x) (void)(sizeof(x)) +#endif + +//----------------------------------------------- +// RR_UINT3264 is a U64 in 64-bit code and a U32 in 32-bit code +// eg. it's pointer sized and the same type as a U32/U64 of the same size +// +// @@ CB 05/21/2012 : I think RR_UINT3264 may be deprecated +// it was useful back when UINTa was /Wp64 +// but since we removed that maybe it's not anymore ? +// + +#ifdef __RAD64__ +#define RR_UINT3264 U64 +#else +#define RR_UINT3264 U32 +#endif + +//RR_COMPILER_ASSERT( sizeof(RR_UINT3264) == sizeof(UINTa) ); + +//-------------------------------------------------- + +// RR_LINESTRING is the current line number as a string +#define RR_STRINGIZE( L ) #L +#define RR_DO_MACRO( M, X ) M(X) +#define RR_STRINGIZE_DELAY( X ) RR_DO_MACRO( RR_STRINGIZE, X ) +#define RR_LINESTRING RR_STRINGIZE_DELAY( __LINE__ ) + +#define RR_CAT(X,Y) X ## Y + +// RR_STRING_JOIN joins strings in the preprocessor and works with LINESTRING +#define RR_STRING_JOIN(arg1, arg2) RR_STRING_JOIN_DELAY(arg1, arg2) +#define RR_STRING_JOIN_DELAY(arg1, arg2) RR_STRING_JOIN_IMMEDIATE(arg1, arg2) +#define RR_STRING_JOIN_IMMEDIATE(arg1, arg2) arg1 ## arg2 + +// RR_NUMBERNAME is a macro to make a name unique, so that you can use it to declare +// variable names and they won't conflict with each other +// using __LINE__ is broken in MSVC with /ZI , but __COUNTER__ is an MSVC extension that works + +#ifdef _MSC_VER + #define RR_NUMBERNAME(name) RR_STRING_JOIN(name,__COUNTER__) +#else + #define RR_NUMBERNAME(name) RR_STRING_JOIN(name,__LINE__) +#endif + +//-------------------------------------------------- +// current plan is to use "rrbool" with plain old "true" and "false" +// if true and false give us trouble we might have to go to rrtrue and rrfalse +// BTW there's a danger for evil bugs here !! If you're checking == true +// then the rrbool must be set to exactly "1" not just "not zero" !! + +#ifndef RADNOTYPEDEFS + #ifndef RRBOOL_DEFINED + #define RRBOOL_DEFINED + typedef S32 rrbool; + typedef S32 RRBOOL; + #endif +#elif !defined(RADNOTYPEDEFINES) + #ifndef RRBOOL_DEFINED + #define RRBOOL_DEFINED + #define rrbool S32 + #define RRBOOL S32 + #endif +#endif + +//-------------------------------------------------- +// Range macros + + #ifndef RR_MIN + #define RR_MIN(a,b) ( (a) < (b) ? (a) : (b) ) + #endif + + #ifndef RR_MAX + #define RR_MAX(a,b) ( (a) > (b) ? (a) : (b) ) + #endif + + #ifndef RR_ABS + #define RR_ABS(a) ( ((a) < 0) ? -(a) : (a) ) + #endif + + #ifndef RR_CLAMP + #define RR_CLAMP(val,lo,hi) RR_MAX( RR_MIN(val,hi), lo ) + #endif + +//-------------------------------------------------- +// Data layout macros + + #define RR_ARRAY_SIZE(array) ( sizeof(array)/sizeof(array[0]) ) + + // MEMBER_OFFSET tells you the offset of a member in a type + #ifdef __RAD3DS__ + #define RR_MEMBER_OFFSET(type,member) (unsigned int)(( (char *) &(((type *)0)->member) - (char *) 0 )) + #elif defined(__RADANDROID__) || defined(__RADPSP__) || defined(__RADPS3__) || defined(__RADSPU__) + // offsetof() gets mucked with by system headers on android, making things dependent on #include order. + #define RR_MEMBER_OFFSET(type,member) __builtin_offsetof(type, member) + #elif defined(__RADLINUX__) + #define RR_MEMBER_OFFSET(type,member) (offsetof(type, member)) + #else + #define RR_MEMBER_OFFSET(type,member) ( (size_t) (UINTa) &(((type *)0)->member) ) + #endif + + // MEMBER_SIZE tells you the size of a member in a type + #define RR_MEMBER_SIZE(type,member) ( sizeof( ((type *) 0)->member) ) + + // just to make gcc shut up about derefing null : + #define RR_MEMBER_OFFSET_PTR(type,member,ptr) ( (SINTa) &(((type *)(ptr))->member) - (SINTa)(ptr) ) + #define RR_MEMBER_SIZE_PTR(type,member,ptr) ( sizeof( ((type *) (ptr))->member) ) + + // MEMBER_TO_OWNER takes a pointer to a member and gives you back the base of the object + // you should then RR_ASSERT( &(ret->member) == ptr ); + #define RR_MEMBER_TO_OWNER(type,member,ptr) (type *)( ((char *)(ptr)) - RR_MEMBER_OFFSET_PTR(type,member,ptr) ) + +//-------------------------------------------------- +// Cache / prefetch macros : + +// RR_PREFETCH for various platforms : +// +// RR_PREFETCH_SEQUENTIAL : prefetch memory for reading in a sequential scan +// platforms that automatically prefetch sequential (eg. PC) should be a no-op here +// RR_PREFETCH_WRITE_INVALIDATE : prefetch memory for writing - contents of memory are undefined +// (may be a no-op, may be a normal prefetch, may zero memory) +// warning : RR_PREFETCH_WRITE_INVALIDATE may write memory so don't do it past the end of buffers + +#ifdef __RADX86__ + +#define RR_PREFETCH_SEQUENTIAL(ptr,offset) // nop +#define RR_PREFETCH_WRITE_INVALIDATE(ptr,offset) // nop + +#elif defined(__RADXENON__) + +#define RR_PREFETCH_SEQUENTIAL(ptr,offset) __dcbt((int)(offset),(void *)(ptr)) +#define RR_PREFETCH_WRITE_INVALIDATE(ptr,offset) __dcbz128((int)(offset),(void *)(ptr)) + +#elif defined(__RADPS3__) + +#define RR_PREFETCH_SEQUENTIAL(ptr,offset) __dcbt((char *)(ptr) + (int)(offset)) +#define RR_PREFETCH_WRITE_INVALIDATE(ptr,offset) __dcbz((char *)(ptr) + (int)(offset)) + +#elif defined(__RADSPU__) + +#define RR_PREFETCH_SEQUENTIAL(ptr,offset) // intentional NOP +#define RR_PREFETCH_WRITE_INVALIDATE(ptr,offset) // nop + +#elif defined(__RADWII__) || defined(__RADWIIU__) + +#define RR_PREFETCH_SEQUENTIAL(ptr,offset) // intentional NOP for now +#define RR_PREFETCH_WRITE_INVALIDATE(ptr,offset) // nop + +#elif defined(__RAD3DS__) + +#define RR_PREFETCH_SEQUENTIAL(ptr,offset) __pld((char *)(ptr) + (int)(offset)) +#define RR_PREFETCH_WRITE_INVALIDATE(ptr,offset) __pldw((char *)(ptr) + (int)(offset)) + +#else + +// other platform +#define RR_PREFETCH_SEQUENTIAL(ptr,offset) // need_prefetch // compile error +#define RR_PREFETCH_WRITE_INVALIDATE(ptr,offset) // need_writezero // error + +#endif + +//-------------------------------------------------- +// LIGHTWEIGHT ASSERTS without rrAssert.h + +RADDEFSTART + +// set up RR_BREAK : + + #ifdef __RADNGC__ + + #define RR_BREAK() asm(" .long 0x00000001") + #define RR_CACHE_LINE_SIZE xxx + + #elif defined(__RADWII__) + + #define RR_BREAK() __asm__ volatile("trap") + #define RR_CACHE_LINE_SIZE 32 + + #elif defined(__RADWIIU__) + + #define RR_BREAK() asm("trap") + #define RR_CACHE_LINE_SIZE 32 + + #elif defined(__RAD3DS__) + + #define RR_BREAK() *((int volatile*)0)=0 + #define RR_CACHE_LINE_SIZE 32 + + #elif defined(__RADNDS__) + + #define RR_BREAK() asm("BKPT 0") + #define RR_CACHE_LINE_SIZE xxx + + #elif defined(__RADPS2__) + + #define RR_BREAK() __asm__ volatile("break") + #define RR_CACHE_LINE_SIZE 64 + + #elif defined(__RADPSP__) + + #define RR_BREAK() __asm__("break 0") + #define RR_CACHE_LINE_SIZE 64 + + #elif defined(__RADPSP2__) + + #define RR_BREAK() { __asm__ volatile("bkpt 0x0000"); } + #define RR_CACHE_LINE_SIZE 32 + + #elif defined (__RADQNX__) + #define RR_BREAK() __builtin_trap() + #define RR_CACHE_LINE_SIZE 32 + #elif defined (__RADARM__) && defined (__RADLINUX__) + #define RR_BREAK() __builtin_trap() + #define RR_CACHE_LINE_SIZE 32 + #elif defined(__RADSPU__) + + #define RR_BREAK() __asm volatile ("stopd 0,1,1") + #define RR_CACHE_LINE_SIZE 128 + + #elif defined(__RADPS3__) + + // #ifdef snPause // in LibSN.h + // snPause + // __asm__ volatile ( "tw 31,1,1" ) + + #define RR_BREAK() __asm__ volatile ( "tw 31,1,1" ) + //#define RR_BREAK() __asm__ volatile("trap"); + + #define RR_CACHE_LINE_SIZE 128 + + #elif defined(__RADMAC__) + + #if defined(__GNUG__) || defined(__GNUC__) + #ifdef __RADX86__ + #define RR_BREAK() __asm__ volatile ( "int $3" ) + #else + #define RR_BREAK() __builtin_trap() + #endif + #else + #ifdef __RADMACH__ + void DebugStr(unsigned char const *); + #else + void pascal DebugStr(unsigned char const *); + #endif + #define RR_BREAK() DebugStr("\pRR_BREAK() was called") + #endif + + #define RR_CACHE_LINE_SIZE 64 + + #elif defined(__RADIPHONE__) + #define RR_BREAK() __builtin_trap() + #define RR_CACHE_LINE_SIZE 32 + #elif defined(__RADXENON__) + #define RR_BREAK() __debugbreak() + #define RR_CACHE_LINE_SIZE 128 + #elif defined(__RADANDROID__) + #define RR_BREAK() __builtin_trap() + #define RR_CACHE_LINE_SIZE 32 + #elif defined(__RADPS4__) + #define RR_BREAK() __builtin_trap() + #define RR_CACHE_LINE_SIZE 64 + #elif defined(__RADNACL__) + #define RR_BREAK() __builtin_trap() + #define RR_CACHE_LINE_SIZE 64 + #else + // x86 : + #define RR_CACHE_LINE_SIZE 64 + + #ifdef __RADLINUX__ + #define RR_BREAK() __asm__ volatile ( "int $3" ) + #elif defined(__WATCOMC__) + + void RR_BREAK( void ); + #pragma aux RR_BREAK = "int 0x3"; + + #elif defined(__RADWIN__) && defined(_MSC_VER) && _MSC_VER >= 1300 + + #define RR_BREAK __debugbreak + + #else + + #define RR_BREAK() RAD_STATEMENT_WRAPPER( __asm {int 3} ) + + #endif + + #endif + +// simple RR_ASSERT : + +// CB 5-27-10 : use RR_DO_ASSERTS to toggle asserts on and off : +#if (defined(_DEBUG) && !defined(NDEBUG)) || defined(ASSERT_IN_RELEASE) + #define RR_DO_ASSERTS +#endif + +/********* + +rrAsserts : + +RR_ASSERT(exp) - the normal assert thing, toggled with RR_DO_ASSERTS +RR_ASSERT_ALWAYS(exp) - assert that you want to test even in ALL builds (including final!) +RR_ASSERT_RELEASE(exp) - assert that you want to test even in release builds (not for final!) +RR_ASSERT_LITE(exp) - normal assert is not safe from threads or inside malloc; use this instead +RR_DURING_ASSERT(exp) - wrap operations that compute stuff for assert in here +RR_DO_ASSERTS - toggle tells you if asserts are enabled or not + +RR_BREAK() - generate a debug break - always ! +RR_ASSERT_BREAK() - RR_BREAK for asserts ; disable with RAD_NO_BREAK + +RR_ASSERT_FAILURE(str) - just break with a messsage; like assert with no condition +RR_ASSERT_FAILURE_ALWAYS(str) - RR_ASSERT_FAILURE in release builds too +RR_CANT_GET_HERE() - put in spots execution should never go +RR_COMPILER_ASSERT(exp) - checks constant conditions at compile time + +RADTODO - note to search for nonfinal stuff +RR_PRAGMA_MESSAGE - message dealy, use with #pragma in MSVC + +*************/ + +//----------------------------------------------------------- + + +#if defined(__GNUG__) || defined(__GNUC__) || (defined(_MSC_VER) && _MSC_VER > 1200) + #define RR_FUNCTION_NAME __FUNCTION__ +#else + #define RR_FUNCTION_NAME 0 + + // __func__ is in the C99 standard +#endif + +//----------------------------------------------------------- + +// rrDisplayAssertion might just log, or it might pop a message box, depending on settings +// rrDisplayAssertion returns whether you should break or not +typedef rrbool (RADLINK fp_rrDisplayAssertion)(int * Ignored, const char * fileName,const int line,const char * function,const char * message); + +extern fp_rrDisplayAssertion * g_fp_rrDisplayAssertion; + +// if I have func pointer, call it, else true ; true = do int 3 +#define rrDisplayAssertion(i,n,l,f,m) ( ( g_fp_rrDisplayAssertion ) ? (*g_fp_rrDisplayAssertion)(i,n,l,f,m) : 1 ) + +//----------------------------------------------------------- + +// RAD_NO_BREAK : option if you don't like your assert to break +// CB : RR_BREAK is *always* a break ; RR_ASSERT_BREAK is optional +#ifdef RAD_NO_BREAK +#define RR_ASSERT_BREAK() 0 +#else +#define RR_ASSERT_BREAK() RR_BREAK() +#endif + +// assert_always is on FINAL ! +#define RR_ASSERT_ALWAYS(exp) RAD_STATEMENT_WRAPPER( static int Ignored=0; if ( ! (exp) ) { if ( rrDisplayAssertion(&Ignored,__FILE__,__LINE__,RR_FUNCTION_NAME,#exp) ) RR_ASSERT_BREAK(); } ) + +// RR_ASSERT_FAILURE is like an assert without a condition - if you hit it, you're bad +#define RR_ASSERT_FAILURE_ALWAYS(str) RAD_STATEMENT_WRAPPER( static int Ignored=0; if ( rrDisplayAssertion(&Ignored,__FILE__,__LINE__,RR_FUNCTION_NAME,str) ) RR_ASSERT_BREAK(); ) + +#define RR_ASSERT_LITE_ALWAYS(exp) RAD_STATEMENT_WRAPPER( if ( ! (exp) ) { RR_ASSERT_BREAK(); } ) + +//----------------------------------- +#ifdef RR_DO_ASSERTS + +#define RR_ASSERT(exp) RR_ASSERT_ALWAYS(exp) +#define RR_ASSERT_LITE(exp) RR_ASSERT_LITE_ALWAYS(exp) +#define RR_ASSERT_NO_ASSUME(exp) RR_ASSERT_ALWAYS(exp) +// RR_DURING_ASSERT is to set up expressions or declare variables that are only used in asserts +#define RR_DURING_ASSERT(exp) exp + +#define RR_ASSERT_FAILURE(str) RR_ASSERT_FAILURE_ALWAYS(str) + +// RR_CANT_GET_HERE is for like defaults in switches that should never be hit +#define RR_CANT_GET_HERE() RAD_STATEMENT_WRAPPER( RR_ASSERT_FAILURE("can't get here"); RADUNREACHABLE; ) + + +#else // RR_DO_ASSERTS //----------------------------------- + +#define RR_ASSERT(exp) (void)0 +#define RR_ASSERT_LITE(exp) (void)0 +#define RR_ASSERT_NO_ASSUME(exp) (void)0 + +#define RR_DURING_ASSERT(exp) (void)0 + +#define RR_ASSERT_FAILURE(str) (void)0 + +#define RR_CANT_GET_HERE() RADUNREACHABLE + +#endif // RR_DO_ASSERTS //----------------------------------- + +//================================================================= + +// RR_ASSERT_RELEASE is on in release build, but not final + +#ifndef __RADFINAL__ + +#define RR_ASSERT_RELEASE(exp) RR_ASSERT_ALWAYS(exp) +#define RR_ASSERT_LITE_RELEASE(exp) RR_ASSERT_LITE_ALWAYS(exp) + +#else + +#define RR_ASSERT_RELEASE(exp) (void)0 +#define RR_ASSERT_LITE_RELEASE(exp) (void)0 + +#endif + +// BH: This never gets compiled away except for __RADFINAL__ +#define RR_ASSERT_ALWAYS_NO_SHIP RR_ASSERT_RELEASE + +#define rrAssert RR_ASSERT +#define rrassert RR_ASSERT + +#ifdef _MSC_VER + // without this, our assert errors... + #if _MSC_VER >= 1300 + #pragma warning( disable : 4127) // conditional expression is constant + #endif +#endif + +//--------------------------------------- +// Get/Put from memory in little or big endian : +// +// val = RR_GET32_BE(ptr) +// RR_PUT32_BE(ptr,val) +// +// available here : +// RR_[GET/PUT][16/32]_[BE/LE][_UNALIGNED][_OFFSET] +// +// if you don't specify _UNALIGNED , then ptr & offset shoud both be aligned to type size +// _OFFSET is in *bytes* ! + +// you can #define RR_GET_RESTRICT to make all RR_GETs be RESTRICT +// if you set nothing they are not + +#ifdef RR_GET_RESTRICT +#define RR_GET_PTR_POST RADRESTRICT +#endif +#ifndef RR_GET_PTR_POST +#define RR_GET_PTR_POST +#endif + +// native version of get/put is always trivial : + +#define RR_GET16_NATIVE(ptr) *((const U16 * RR_GET_PTR_POST)(ptr)) +#define RR_PUT16_NATIVE(ptr,val) *((U16 * RR_GET_PTR_POST)(ptr)) = (val) + +// offset is in bytes +#define RR_U16_PTR_OFFSET(ptr,offset) ((U16 * RR_GET_PTR_POST)((char *)(ptr) + (offset))) +#define RR_GET16_NATIVE_OFFSET(ptr,offset) *( RR_U16_PTR_OFFSET((ptr),offset) ) +#define RR_PUT16_NATIVE_OFFSET(ptr,val,offset) *( RR_U16_PTR_OFFSET((ptr),offset)) = (val) + +#define RR_GET32_NATIVE(ptr) *((const U32 * RR_GET_PTR_POST)(ptr)) +#define RR_PUT32_NATIVE(ptr,val) *((U32 * RR_GET_PTR_POST)(ptr)) = (val) + +// offset is in bytes +#define RR_U32_PTR_OFFSET(ptr,offset) ((U32 * RR_GET_PTR_POST)((char *)(ptr) + (offset))) +#define RR_GET32_NATIVE_OFFSET(ptr,offset) *( RR_U32_PTR_OFFSET((ptr),offset) ) +#define RR_PUT32_NATIVE_OFFSET(ptr,val,offset) *( RR_U32_PTR_OFFSET((ptr),offset)) = (val) + +#define RR_GET64_NATIVE(ptr) *((const U64 * RR_GET_PTR_POST)(ptr)) +#define RR_PUT64_NATIVE(ptr,val) *((U64 * RR_GET_PTR_POST)(ptr)) = (val) + +// offset is in bytes +#define RR_U64_PTR_OFFSET(ptr,offset) ((U64 * RR_GET_PTR_POST)((char *)(ptr) + (offset))) +#define RR_GET64_NATIVE_OFFSET(ptr,offset) *( RR_U64_PTR_OFFSET((ptr),offset) ) +#define RR_PUT64_NATIVE_OFFSET(ptr,val,offset) *( RR_U64_PTR_OFFSET((ptr),offset)) = (val) + +//--------------------------------------------------- + +#ifdef __RADLITTLEENDIAN__ + +#define RR_GET16_LE RR_GET16_NATIVE +#define RR_PUT16_LE RR_PUT16_NATIVE +#define RR_GET16_LE_OFFSET RR_GET16_NATIVE_OFFSET +#define RR_PUT16_LE_OFFSET RR_PUT16_NATIVE_OFFSET + +#define RR_GET32_LE RR_GET32_NATIVE +#define RR_PUT32_LE RR_PUT32_NATIVE +#define RR_GET32_LE_OFFSET RR_GET32_NATIVE_OFFSET +#define RR_PUT32_LE_OFFSET RR_PUT32_NATIVE_OFFSET + +#define RR_GET64_LE RR_GET64_NATIVE +#define RR_PUT64_LE RR_PUT64_NATIVE +#define RR_GET64_LE_OFFSET RR_GET64_NATIVE_OFFSET +#define RR_PUT64_LE_OFFSET RR_PUT64_NATIVE_OFFSET + +#else + +#define RR_GET16_BE RR_GET16_NATIVE +#define RR_PUT16_BE RR_PUT16_NATIVE +#define RR_GET16_BE_OFFSET RR_GET16_NATIVE_OFFSET +#define RR_PUT16_BE_OFFSET RR_PUT16_NATIVE_OFFSET + +#define RR_GET32_BE RR_GET32_NATIVE +#define RR_PUT32_BE RR_PUT32_NATIVE +#define RR_GET32_BE_OFFSET RR_GET32_NATIVE_OFFSET +#define RR_PUT32_BE_OFFSET RR_PUT32_NATIVE_OFFSET + +#define RR_GET64_BE RR_GET64_NATIVE +#define RR_PUT64_BE RR_PUT64_NATIVE +#define RR_GET64_BE_OFFSET RR_GET64_NATIVE_OFFSET +#define RR_PUT64_BE_OFFSET RR_PUT64_NATIVE_OFFSET + +#endif + +//------------------------- +// non-native Get/Put implementations go here : + +#if defined(__RADX86__) +// good implementation for X86 : + +#if (_MSC_VER >= 1300) + +unsigned short __cdecl _byteswap_ushort (unsigned short _Short); +unsigned long __cdecl _byteswap_ulong (unsigned long _Long); +#pragma intrinsic(_byteswap_ushort, _byteswap_ulong) + +#define RR_BSWAP16 _byteswap_ushort +#define RR_BSWAP32 _byteswap_ulong + +unsigned __int64 __cdecl _byteswap_uint64 (unsigned __int64 val); +#pragma intrinsic(_byteswap_uint64) +#define RR_BSWAP64 _byteswap_uint64 + +#elif defined(_MSC_VER) // VC6 + +RADFORCEINLINE unsigned long RR_BSWAP16 (unsigned long _Long) +{ + __asm { + mov eax, [_Long] + rol ax, 8 + mov [_Long], eax; + } + return _Long; +} + +RADFORCEINLINE unsigned long RR_BSWAP32 (unsigned long _Long) +{ + __asm { + mov eax, [_Long] + bswap eax + mov [_Long], eax + } + return _Long; +} + +RADFORCEINLINE unsigned __int64 RR_BSWAP64 (unsigned __int64 _Long) +{ + __asm { + mov eax, DWORD PTR _Long + mov edx, DWORD PTR _Long+4 + bswap eax + bswap edx + mov DWORD PTR _Long, edx + mov DWORD PTR _Long+4, eax + } + return _Long; +} + +#elif defined(__GNUC__) || defined(__clang__) + +// GCC has __builtin_bswap16, but Clang only seems to have added it recently. +// We use __builtin_bswap32/64 but 16 just uses the macro version. (No big +// deal if that turns into shifts anyway) +#define RR_BSWAP16(u16) ( (U16) ( ((u16) >> 8) | ((u16) << 8) ) ) +#define RR_BSWAP32 __builtin_bswap32 +#define RR_BSWAP64 __builtin_bswap64 + +#endif + +#define RR_GET16_BE(ptr) RR_BSWAP16(*((U16 *)(ptr))) +#define RR_PUT16_BE(ptr,val) *((U16 *)(ptr)) = (U16) RR_BSWAP16(val) +#define RR_GET16_BE_OFFSET(ptr,offset) RR_BSWAP16(*RR_U16_PTR_OFFSET(ptr,offset)) +#define RR_PUT16_BE_OFFSET(ptr,val,offset) *RR_U16_PTR_OFFSET(ptr,offset) = RR_BSWAP16(val) + +#define RR_GET32_BE(ptr) RR_BSWAP32(*((U32 *)(ptr))) +#define RR_PUT32_BE(ptr,val) *((U32 *)(ptr)) = RR_BSWAP32(val) +#define RR_GET32_BE_OFFSET(ptr,offset) RR_BSWAP32(*RR_U32_PTR_OFFSET(ptr,offset)) +#define RR_PUT32_BE_OFFSET(ptr,val,offset) *RR_U32_PTR_OFFSET(ptr,offset) = RR_BSWAP32(val) + +#define RR_GET64_BE(ptr) RR_BSWAP64(*((U64 *)(ptr))) +#define RR_PUT64_BE(ptr,val) *((U64 *)(ptr)) = RR_BSWAP64(val) +#define RR_GET64_BE_OFFSET(ptr,offset) RR_BSWAP64(*RR_U64_PTR_OFFSET(ptr,offset)) +#define RR_PUT64_BE_OFFSET(ptr,val,offset) *RR_U64_PTR_OFFSET(ptr,offset) = RR_BSWAP64(val) + +// end _MSC_VER + +#elif defined(__RADXENON__) // Xenon has built-in funcs for this + +unsigned short __loadshortbytereverse(int offset, const void *base); +unsigned long __loadwordbytereverse (int offset, const void *base); + +void __storeshortbytereverse(unsigned short val, int offset, void *base); +void __storewordbytereverse (unsigned int val, int offset, void *base); + +#define RR_GET16_LE(ptr) __loadshortbytereverse(0, ptr) +#define RR_PUT16_LE(ptr,val) __storeshortbytereverse((U16) (val), 0, ptr) + +#define RR_GET16_LE_OFFSET(ptr,offset) __loadshortbytereverse(offset, ptr) +#define RR_PUT16_LE_OFFSET(ptr,val,offset) __storeshortbytereverse((U16) (val), offset, ptr) + +#define RR_GET32_LE(ptr) __loadwordbytereverse(0, ptr) +#define RR_PUT32_LE(ptr,val) __storewordbytereverse((U32) (val), 0, ptr) + +#define RR_GET32_LE_OFFSET(ptr,offset) __loadwordbytereverse(offset, ptr) +#define RR_PUT32_LE_OFFSET(ptr,val,offset) __storewordbytereverse((U32) (val), offset, ptr) + +#define RR_GET64_LE(ptr) ( ((U64)RR_GET32_OFFSET_LE(ptr,4)<<32) | RR_GET32_LE(ptr) ) +#define RR_PUT64_LE(ptr,val) RR_PUT32_LE(ptr, (U32) (val)), RR_PUT32_OFFSET_LE(ptr, (U32) ((val)>>32),4) + +#elif defined(__RADPS3__) + +#include + +#define RR_GET16_LE(ptr) __lhbrx(ptr) +#define RR_PUT16_LE(ptr,val) __sthbrx(ptr, (U16) (val)) + +#define RR_GET16_LE_OFFSET(ptr,offset) __lhbrx(RR_U16_PTR_OFFSET(ptr, offset)) +#define RR_PUT16_LE_OFFSET(ptr,val,offset) __sthbrx(RR_U16_PTR_OFFSET(ptr, offset), (U16) (val)) + +#define RR_GET32_LE(ptr) __lwbrx(ptr) +#define RR_PUT32_LE(ptr,val) __stwbrx(ptr, (U32) (val)) + +#define RR_GET64_LE(ptr) __ldbrx(ptr) +#define RR_PUT64_LE(ptr,val) __stdbrx(ptr, (U32) (val)) + +#define RR_GET32_LE_OFFSET(ptr,offset) __lwbrx(RR_U32_PTR_OFFSET(ptr, offset)) +#define RR_PUT32_LE_OFFSET(ptr,val,offset) __stwbrx(RR_U32_PTR_OFFSET(ptr, offset), (U32) (val)) + +#elif defined(__RADWII__) + +#define RR_GET16_LE(ptr) __lhbrx(ptr, 0) +#define RR_PUT16_LE(ptr,val) __sthbrx((U16) (val), ptr, 0) + +#define RR_GET16_LE_OFFSET(ptr,offset) __lhbrx(ptr, offset) +#define RR_PUT16_LE_OFFSET(ptr,val,offset) __sthbrx((U16) (val), ptr, offset) + +#define RR_GET32_LE(ptr) __lwbrx(ptr, 0) +#define RR_PUT32_LE(ptr,val) __stwbrx((U32) (val), ptr, 0) + +#define RR_GET32_LE_OFFSET(ptr,offset) __lwbrx(ptr, offset) +#define RR_PUT32_LE_OFFSET(ptr,val,offset) __stwbrx((U32) (val), ptr, offset) + +#elif defined(__RAD3DS__) + +#define RR_GET16_BE(ptr) __rev16(*(U16 *) (ptr)) +#define RR_PUT16_BE(ptr,val) *(U16 *) (ptr) = __rev16(val) + +#define RR_GET16_BE_OFFSET(ptr,offset) __rev16(*RR_U16_PTR_OFFSET(ptr,offset)) +#define RR_PUT16_BE_OFFSET(ptr,offset,val) *RR_U16_PTR_OFFSET(ptr,offset) = __rev16(val) + +#define RR_GET32_BE(ptr) __rev(*(U32 *) (ptr)) +#define RR_PUT32_BE(ptr,val) *(U32 *) (ptr) = __rev(val) + +#define RR_GET32_BE_OFFSET(ptr,offset) __rev(*RR_U32_PTR_OFFSET(ptr,offset)) +#define RR_PUT32_BE_OFFSET(ptr,offset,val) *RR_U32_PTR_OFFSET(ptr,offset) = __rev(val) + +#elif defined(__RADIPHONE__) + +// iPhone does not seem to have intrinsics for this, so use generic fallback! + +// Bswap is just here for use of implementing get/put +// caller should use Get/Put , not bswap +#define RR_BSWAP16(u16) ( (U16) ( ((u16) >> 8) | ((u16) << 8) ) ) +#define RR_BSWAP32(u32) ( (U32) ( ((u32) >> 24) | (((u32)<<8) & 0x00FF0000) | (((u32)>>8) & 0x0000FF00) | ((u32) << 24) ) ) + +#define RR_GET16_BE(ptr) RR_BSWAP16(*((U16 *)(ptr))) +#define RR_PUT16_BE(ptr,val) *((U16 *)(ptr)) = RR_BSWAP16(val) + +#define RR_GET32_BE(ptr) RR_BSWAP32(*((U32 *)(ptr))) +#define RR_PUT32_BE(ptr,val) *((U32 *)(ptr)) = RR_BSWAP32(val) + +#elif defined(__RADWIIU__) + +#include + +#define RR_GET16_LE(ptr) (*(__bytereversed U16 *) (ptr)) +#define RR_PUT16_LE(ptr,val) *(__bytereversed U16 *) (ptr) = val + +#define RR_GET16_LE_OFFSET(ptr,offset) (*(__bytereversed U16 *)RR_U16_PTR_OFFSET(ptr,offset)) +#define RR_PUT16_LE_OFFSET(ptr,val,offset) *(__bytereversed U16 *)RR_U16_PTR_OFFSET(ptr,offset) = val + +#define RR_GET32_LE(ptr) (*(__bytereversed U32 *) (ptr)) +#define RR_PUT32_LE(ptr,val) *(__bytereversed U32 *) (ptr) = val + +#define RR_GET32_LE_OFFSET(ptr,offset) (*(__bytereversed U32 *)RR_U32_PTR_OFFSET(ptr,offset)) +#define RR_PUT32_LE_OFFSET(ptr,val,offset) *(__bytereversed U32 *)RR_U32_PTR_OFFSET(ptr,offset) = val + +#define RR_GET64_LE(ptr) (*(__bytereversed U64 *) (ptr)) +#define RR_PUT64_LE(ptr,val) *(__bytereversed U64 *) (ptr) = val + +#define RR_GET64_LE_OFFSET(ptr,offset) (*(__bytereversed U64 *)RR_U32_PTR_OFFSET(ptr,offset)) +#define RR_PUT64_LE_OFFSET(ptr,val,offset) *(__bytereversed U64 *)RR_U32_PTR_OFFSET(ptr,offset) = val + +#elif defined(__RADWINRTAPI__) && defined(__RADARM__) + +#include + +#define RR_BSWAP16(u16) _arm_rev16(u16) +#define RR_BSWAP32(u32) _arm_rev(u32) + +#define RR_GET16_BE(ptr) RR_BSWAP16(*((U16 *)(ptr))) +#define RR_PUT16_BE(ptr,val) *((U16 *)(ptr)) = RR_BSWAP16(val) + +#define RR_GET32_BE(ptr) RR_BSWAP32(*((U32 *)(ptr))) +#define RR_PUT32_BE(ptr,val) *((U32 *)(ptr)) = RR_BSWAP32(val) + +#elif defined(__RADPSP2__) + +// no rev16 exposed +#define RR_BSWAP16(u16) ( (U16) ( ((u16) >> 8) | ((u16) << 8) ) ) +#define RR_BSWAP32(u32) __builtin_rev(u32) + +#define RR_GET16_BE(ptr) RR_BSWAP16(*((U16 *)(ptr))) +#define RR_PUT16_BE(ptr,val) *((U16 *)(ptr)) = RR_BSWAP16(val) + +#define RR_GET32_BE(ptr) RR_BSWAP32(*((U32 *)(ptr))) +#define RR_PUT32_BE(ptr,val) *((U32 *)(ptr)) = RR_BSWAP32(val) + +#else // other platforms ? + +// fall back : + +// Bswap is just here for use of implementing get/put +// caller should use Get/Put , not bswap +#define RR_BSWAP16(u16) ( (U16) ( ((u16) >> 8) | ((u16) << 8) ) ) +#define RR_BSWAP32(u32) ( (U32) ( ((u32) >> 24) | (((u32)<<8) & 0x00FF0000) | (((u32)>>8) & 0x0000FF00) | ((u32) << 24) ) ) +#define RR_BSWAP64(u64) ( ((U64) RR_BSWAP32((U32) (u64)) << 32) | (U64) RR_BSWAP32((U32) ((u64) >> 32)) ) + +#ifdef __RADLITTLEENDIAN__ + +// comment out fallbacks so users will get errors +//#define RR_GET16_BE(ptr) RR_BSWAP16(*((U16 *)(ptr))) +//#define RR_PUT16_BE(ptr,val) *((U16 *)(ptr)) = RR_BSWAP16(val) +//#define RR_GET32_BE(ptr) RR_BSWAP32(*((U32 *)(ptr))) +//#define RR_PUT32_BE(ptr,val) *((U32 *)(ptr)) = RR_BSWAP32(val) + +#else + +// comment out fallbacks so users will get errors +//#define RR_GET16_LE(ptr) RR_BSWAP16(*((U16 *)(ptr))) +//#define RR_PUT16_LE(ptr,val) *((U16 *)(ptr)) = RR_BSWAP16(val) +//#define RR_GET32_LE(ptr) RR_BSWAP32(*((U32 *)(ptr))) +//#define RR_PUT32_LE(ptr,val) *((U32 *)(ptr)) = RR_BSWAP32(val) + +#endif + +#endif + +//=================================================================== +// @@ TEMP : Aliases for old names : remove me when possible : + +#define RR_GET32_OFFSET_LE RR_GET32_LE_OFFSET +#define RR_GET32_OFFSET_BE RR_GET32_BE_OFFSET +#define RR_PUT32_OFFSET_LE RR_PUT32_LE_OFFSET +#define RR_PUT32_OFFSET_BE RR_PUT32_BE_OFFSET +#define RR_GET16_OFFSET_LE RR_GET16_LE_OFFSET +#define RR_GET16_OFFSET_BE RR_GET16_BE_OFFSET +#define RR_PUT16_OFFSET_LE RR_PUT16_LE_OFFSET +#define RR_PUT16_OFFSET_BE RR_PUT16_BE_OFFSET + + +//=================================================================== +// UNALIGNED VERSIONS : + +#if defined(__RADX86__) || defined(__RADPPC__) // platforms where unaligned is fast : + +#define RR_GET32_BE_UNALIGNED(ptr) RR_GET32_BE(ptr) +#define RR_GET32_BE_UNALIGNED_OFFSET(ptr,offset) RR_GET32_BE_OFFSET(ptr,offset) +#define RR_GET16_BE_UNALIGNED(ptr) RR_GET16_BE(ptr) +#define RR_GET16_BE_UNALIGNED_OFFSET(ptr,offset) RR_GET16_BE_OFFSET(ptr,offset) + +#define RR_GET32_LE_UNALIGNED(ptr) RR_GET32_LE(ptr) +#define RR_GET32_LE_UNALIGNED_OFFSET(ptr,offset) RR_GET32_LE_OFFSET(ptr,offset) +#define RR_GET16_LE_UNALIGNED(ptr) RR_GET16_LE(ptr) +#define RR_GET16_LE_UNALIGNED_OFFSET(ptr,offset) RR_GET16_LE_OFFSET(ptr,offset) + +#elif defined(__RAD3DS__) + +// arm has a "__packed" qualifier to tell the compiler to do unaligned accesses +#define RR_U16_PTR_OFFSET_UNALIGNED(ptr,offset) ((__packed U16 * RR_GET_PTR_POST)((char *)(ptr) + (offset))) +#define RR_U32_PTR_OFFSET_UNALIGNED(ptr,offset) ((__packed U32 * RR_GET_PTR_POST)((char *)(ptr) + (offset))) + +#define RR_GET32_BE_UNALIGNED(ptr) __rev(*RR_U32_PTR_OFFSET_UNALIGNED(ptr,0)) +#define RR_GET32_BE_UNALIGNED_OFFSET(ptr,offset) __rev(*RR_U32_PTR_OFFSET_UNALIGNED(ptr,offset)) +#define RR_GET16_BE_UNALIGNED(ptr) __rev16(*RR_U16_PTR_OFFSET_UNALIGNED(ptr,0)) +#define RR_GET16_BE_UNALIGNED_OFFSET(ptr,offset) __rev16(*RR_U16_PTR_OFFSET_UNALIGNED(ptr,offset)) + +#define RR_GET32_LE_UNALIGNED(ptr) *RR_U32_PTR_OFFSET_UNALIGNED(ptr,0) +#define RR_GET32_LE_UNALIGNED_OFFSET(ptr,offset) *RR_U32_PTR_OFFSET_UNALIGNED(ptr,offset) +#define RR_GET16_LE_UNALIGNED(ptr) *RR_U16_PTR_OFFSET_UNALIGNED(ptr,0) +#define RR_GET16_LE_UNALIGNED_OFFSET(ptr,offset) *RR_U16_PTR_OFFSET_UNALIGNED(ptr,offset) + +#elif defined(__RADPSP2__) + +#define RR_U16_PTR_OFFSET_UNALIGNED(ptr,offset) ((U16 __unaligned * RR_GET_PTR_POST)((char *)(ptr) + (offset))) +#define RR_U32_PTR_OFFSET_UNALIGNED(ptr,offset) ((U32 __unaligned * RR_GET_PTR_POST)((char *)(ptr) + (offset))) + +#define RR_GET32_BE_UNALIGNED(ptr) RR_BSWAP32(*RR_U32_PTR_OFFSET_UNALIGNED(ptr,0)) +#define RR_GET32_BE_UNALIGNED_OFFSET(ptr,offset) RR_BSWAP32(*RR_U32_PTR_OFFSET_UNALIGNED(ptr,offset)) +#define RR_GET16_BE_UNALIGNED(ptr) RR_BSWAP16(*RR_U16_PTR_OFFSET_UNALIGNED(ptr,0)) +#define RR_GET16_BE_UNALIGNED_OFFSET(ptr,offset) RR_BSWAP16(*RR_U16_PTR_OFFSET_UNALIGNED(ptr,offset)) + +#define RR_GET32_LE_UNALIGNED(ptr) *RR_U32_PTR_OFFSET_UNALIGNED(ptr,0) +#define RR_GET32_LE_UNALIGNED_OFFSET(ptr,offset) *RR_U32_PTR_OFFSET_UNALIGNED(ptr,offset) +#define RR_GET16_LE_UNALIGNED(ptr) *RR_U16_PTR_OFFSET_UNALIGNED(ptr,0) +#define RR_GET16_LE_UNALIGNED_OFFSET(ptr,offset) *RR_U16_PTR_OFFSET_UNALIGNED(ptr,offset) + +#else +// Unaligned via bytes : + +#define RR_GET32_BE_UNALIGNED(ptr) ( \ + ( (U32)(((const U8 * RR_GET_PTR_POST)(ptr)))[0] << 24 ) | \ + ( (U32)(((const U8 * RR_GET_PTR_POST)(ptr)))[1] << 16 ) | \ + ( (U32)(((const U8 * RR_GET_PTR_POST)(ptr)))[2] << 8 ) | \ + ( (U32)(((const U8 * RR_GET_PTR_POST)(ptr)))[3] << 0 ) ) + +#define RR_GET32_BE_UNALIGNED_OFFSET(ptr,offset) ( \ + ( (U32)(((const U8 * RR_GET_PTR_POST)(ptr))+(offset))[0] << 24 ) | \ + ( (U32)(((const U8 * RR_GET_PTR_POST)(ptr))+(offset))[1] << 16 ) | \ + ( (U32)(((const U8 * RR_GET_PTR_POST)(ptr))+(offset))[2] << 8 ) | \ + ( (U32)(((const U8 * RR_GET_PTR_POST)(ptr))+(offset))[3] << 0 ) ) + +#define RR_GET16_BE_UNALIGNED(ptr) ( \ + ( (U16)(((const U8 * RR_GET_PTR_POST)(ptr)))[0] << 8 ) | \ + ( (U16)(((const U8 * RR_GET_PTR_POST)(ptr)))[1] << 0 ) ) + +#define RR_GET16_BE_UNALIGNED_OFFSET(ptr,offset) ( \ + ( (U16)(((const U8 * RR_GET_PTR_POST)(ptr))+(offset))[0] << 8 ) | \ + ( (U16)(((const U8 * RR_GET_PTR_POST)(ptr))+(offset))[1] << 0 ) ) + +#define RR_GET32_LE_UNALIGNED(ptr) ( \ + ( (U32)(((const U8 * RR_GET_PTR_POST)(ptr)))[3] << 24 ) | \ + ( (U32)(((const U8 * RR_GET_PTR_POST)(ptr)))[2] << 16 ) | \ + ( (U32)(((const U8 * RR_GET_PTR_POST)(ptr)))[1] << 8 ) | \ + ( (U32)(((const U8 * RR_GET_PTR_POST)(ptr)))[0] << 0 ) ) + +#define RR_GET32_LE_UNALIGNED_OFFSET(ptr,offset) ( \ + ( (U32)(((const U8 * RR_GET_PTR_POST)(ptr))+(offset))[3] << 24 ) | \ + ( (U32)(((const U8 * RR_GET_PTR_POST)(ptr))+(offset))[2] << 16 ) | \ + ( (U32)(((const U8 * RR_GET_PTR_POST)(ptr))+(offset))[1] << 8 ) | \ + ( (U32)(((const U8 * RR_GET_PTR_POST)(ptr))+(offset))[0] << 0 ) ) + +#define RR_GET16_LE_UNALIGNED(ptr) ( \ + ( (U16)(((const U8 * RR_GET_PTR_POST)(ptr)))[1] << 8 ) | \ + ( (U16)(((const U8 * RR_GET_PTR_POST)(ptr)))[0] << 0 ) ) + +#define RR_GET16_LE_UNALIGNED_OFFSET(ptr,offset) ( \ + ( (U16)(((const U8 * RR_GET_PTR_POST)(ptr))+(offset))[1] << 8 ) | \ + ( (U16)(((const U8 * RR_GET_PTR_POST)(ptr))+(offset))[0] << 0 ) ) + +#endif + +//=================================================================== +// RR_ROTL32 : 32-bit rotate +// + +#ifdef _MSC_VER + + unsigned long __cdecl _lrotl(unsigned long, int); + #pragma intrinsic(_lrotl) + + #define RR_ROTL32(x,k) _lrotl((unsigned long)(x),(int)(k)) + +#elif defined(__RADCELL__) || defined(__RADLINUX__) || defined(__RADWII__) || defined(__RADMACAPI__) || defined(__RADWIIU__) || defined(__RADPS4__) || defined(__RADPSP2__) + + // Compiler turns this into rotate correctly : + #define RR_ROTL32(u32,num) ( ( (u32) << (num) ) | ( (u32) >> (32 - (num))) ) + +#elif defined(__RAD3DS__) + + #define RR_ROTL32(u32,num) __ror(u32, (-(num))&31) + +#else + +// comment out fallbacks so users will get errors +// fallback implementation using shift and or : +//#define RR_ROTL32(u32,num) ( ( (u32) << (num) ) | ( (u32) >> (32 - (num))) ) + +#endif + + +//=================================================================== +// RR_ROTL64 : 64-bit rotate + +#if ( defined(_MSC_VER) && _MSC_VER >= 1300) + +unsigned __int64 __cdecl _rotl64(unsigned __int64 _Val, int _Shift); +#pragma intrinsic(_rotl64) + +#define RR_ROTL64(x,k) _rotl64((unsigned __int64)(x),(int)(k)) + +#elif defined(__RADCELL__) + +// PS3 GCC turns this into rotate correctly : +#define RR_ROTL64(u64,num) ( ( (u64) << (num) ) | ( (u64) >> (64 - (num))) ) + +#elif defined(__RADLINUX__) || defined(__RADMACAPI__) + +//APTODO: Just to compile linux. Should we be doing better than this? If not, combine with above. +#define RR_ROTL64(u64,num) ( ( (u64) << (num) ) | ( (u64) >> (64 - (num))) ) + +#else + +// comment out fallbacks so users will get errors +// fallback implementation using shift and or : +//#define RR_ROTL64(u64,num) ( ( (u64) << (num) ) | ( (u64) >> (64 - (num))) ) + +#endif + +//=================================================================== + +RADDEFEND + +//=================================================================== + +// RR_COMPILER_ASSERT +#if defined(__cplusplus) && !defined(RR_COMPILER_ASSERT) + #if defined(_MSC_VER) && (_MSC_VER >=1400) + + // better version of COMPILER_ASSERT using boost technique + template struct RR_COMPILER_ASSERT_FAILURE; + + template <> struct RR_COMPILER_ASSERT_FAILURE<1> { enum { value = 1 }; }; + + template struct rr_compiler_assert_test{}; + + // __LINE__ macro broken when -ZI is used see Q199057 + #define RR_COMPILER_ASSERT( B ) \ + typedef rr_compiler_assert_test<\ + sizeof(RR_COMPILER_ASSERT_FAILURE< (B) ? 1 : 0 >)\ + > rr_compiler_assert_typedef_ + + #endif +#endif + +#ifndef RR_COMPILER_ASSERT + // this happens at declaration time, so if it's inside a function in a C file, drop {} around it + #define RR_COMPILER_ASSERT(exp) typedef char RR_STRING_JOIN(_dummy_array, __LINE__) [ (exp) ? 1 : -1 ] +#endif + +//=================================================================== +// some error checks : + + RR_COMPILER_ASSERT( sizeof(RAD_UINTa) == sizeof( RR_STRING_JOIN(RAD_U,RAD_PTRBITS) ) ); + RR_COMPILER_ASSERT( sizeof(RAD_UINTa) == RAD_PTRBYTES ); + RR_COMPILER_ASSERT( RAD_TWOPTRBYTES == 2* RAD_PTRBYTES ); + +//=================================================================== + + #endif // __RADRES__ + +//include "testconstant.inl" // uncomment and include to test statement constants + +#endif // __RADRR_COREH__ + + diff --git a/user32.cpp b/user32.cpp new file mode 100644 index 0000000..437eb60 --- /dev/null +++ b/user32.cpp @@ -0,0 +1,199 @@ +typedef void* HWND; +typedef void* LPUNKNOWN; +typedef void* REFIID; +typedef void* REFCLSID; +typedef long HRESULT; +typedef unsigned long DWORD; +typedef unsigned int UINT; +typedef int BOOL; +typedef void* HANDLE; +typedef void* LPVOID; +typedef long LONG; +typedef long LONG_PTR; +typedef const char* LPCSTR; +typedef size_t SIZE_T; +typedef void* HMODULE; +typedef HMODULE HINSTANCE; +typedef void* FARPROC; +typedef DWORD (*LPTHREAD_START_ROUTINE)(LPVOID lpThreadParameter); +typedef union _LARGE_INTEGER { + struct { + unsigned long LowPart; + long HighPart; + }; + long long QuadPart; +} LARGE_INTEGER; +#define S_OK ((HRESULT)0L) +#define TRUE 1 +#define FALSE 0 +#include + +extern "C" { + +// Window stubs +__declspec(dllexport) HWND GetDesktopWindow() { return (HWND)1; } +__declspec(dllexport) HWND GetActiveWindow() { return (HWND)1; } +__declspec(dllexport) HWND GetTopWindow(HWND) { return (HWND)1; } +__declspec(dllexport) HWND GetWindow(HWND, UINT) { return (HWND)1; } +__declspec(dllexport) LONG GetWindowLongA(HWND, int) { return 0; } +__declspec(dllexport) LONG_PTR GetWindowLongPtrA(HWND, int) { return 0; } +__declspec(dllexport) void GetWindowThreadProcessId(HWND, DWORD*) {} + +typedef void (*OutputDebugStringA_t)(LPCSTR lpOutputString); + +OutputDebugStringA_t pOutputDebugStringA = nullptr; + +// MessageBox +__declspec(dllexport) int MessageBoxA(HWND, LPCSTR text, LPCSTR caption, UINT) { + pOutputDebugStringA("[MessageBox] "); + pOutputDebugStringA(caption); + pOutputDebugStringA(": "); + pOutputDebugStringA(text); + pOutputDebugStringA("\n"); + return 1; +} + +HMODULE LoadLibraryExA(LPCSTR lpLibFileName, HANDLE hFile, DWORD dwFlags); + +#define IMAGE_DOS_SIGNATURE 0x5A4D // MZ +#define IMAGE_NT_SIGNATURE 0x00004550 // PE00 +#define IMAGE_DIRECTORY_ENTRY_EXPORT 0 + +struct IMAGE_DOS_HEADER { + uint16_t e_magic; + uint16_t e_cblp; + uint16_t e_cp; + uint16_t e_crlc; + uint16_t e_cparhdr; + uint16_t e_minalloc; + uint16_t e_maxalloc; + uint16_t e_ss; + uint16_t e_sp; + uint16_t e_csum; + uint16_t e_ip; + uint16_t e_cs; + uint16_t e_lfarlc; + uint16_t e_ovno; + uint16_t e_res[4]; + uint16_t e_oemid; + uint16_t e_oeminfo; + uint16_t e_res2[10]; + uint32_t e_lfanew; +}; + +struct IMAGE_FILE_HEADER { + uint16_t Machine; + uint16_t NumberOfSections; + uint32_t TimeDateStamp; + uint32_t PointerToSymbolTable; + uint32_t NumberOfSymbols; + uint16_t SizeOfOptionalHeader; + uint16_t Characteristics; +}; + +struct IMAGE_DATA_DIRECTORY { + uint32_t VirtualAddress; + uint32_t Size; +}; + +struct IMAGE_OPTIONAL_HEADER64 { + uint16_t Magic; + uint8_t MajorLinkerVersion; + uint8_t MinorLinkerVersion; + uint32_t SizeOfCode; + uint32_t SizeOfInitializedData; + uint32_t SizeOfUninitializedData; + uint32_t AddressOfEntryPoint; + uint32_t BaseOfCode; + uint64_t ImageBase; + uint32_t SectionAlignment; + uint32_t FileAlignment; + uint16_t MajorOperatingSystemVersion; + uint16_t MinorOperatingSystemVersion; + uint16_t MajorImageVersion; + uint16_t MinorImageVersion; + uint16_t MajorSubsystemVersion; + uint16_t MinorSubsystemVersion; + uint32_t Win32VersionValue; + uint32_t SizeOfImage; + uint32_t SizeOfHeaders; + uint32_t CheckSum; + uint16_t Subsystem; + uint16_t DllCharacteristics; + uint64_t SizeOfStackReserve; + uint64_t SizeOfStackCommit; + uint64_t SizeOfHeapReserve; + uint64_t SizeOfHeapCommit; + uint32_t LoaderFlags; + uint32_t NumberOfRvaAndSizes; + IMAGE_DATA_DIRECTORY DataDirectory[16]; +}; + +struct IMAGE_NT_HEADERS64 { + uint32_t Signature; + IMAGE_FILE_HEADER FileHeader; + IMAGE_OPTIONAL_HEADER64 OptionalHeader; +}; + +struct IMAGE_EXPORT_DIRECTORY { + uint32_t Characteristics; + uint32_t TimeDateStamp; + uint16_t MajorVersion; + uint16_t MinorVersion; + uint32_t Name; + uint32_t Base; + uint32_t NumberOfFunctions; + uint32_t NumberOfNames; + uint32_t AddressOfFunctions; // RVA from base of image + uint32_t AddressOfNames; // RVA from base of image + uint32_t AddressOfNameOrdinals; // RVA from base of image +}; + +int strcmp(const char* a, const char* b) { + while (*a && (*a == *b)) { + ++a; + ++b; + } + return static_cast(*a) - static_cast(*b); +} + +FARPROC GetRealGetProcAddress(HMODULE hModule) { + auto base = reinterpret_cast(hModule); + auto dos = reinterpret_cast(base); + if (dos->e_magic != IMAGE_DOS_SIGNATURE) return nullptr; + + auto nt = reinterpret_cast(base + dos->e_lfanew); + if (nt->Signature != IMAGE_NT_SIGNATURE) return nullptr; + + auto exportDirRVA = nt->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress; + auto exportDir = reinterpret_cast(base + exportDirRVA); + + auto names = reinterpret_cast(base + exportDir->AddressOfNames); + auto ordinals = reinterpret_cast(base + exportDir->AddressOfNameOrdinals); + auto functions = reinterpret_cast(base + exportDir->AddressOfFunctions); + + for (uint32_t i = 0; i < exportDir->NumberOfNames; i++) { + const char* name = reinterpret_cast(base + names[i]); + if (strcmp(name, "GetProcAddress") == 0) { + uint16_t ord = ordinals[i]; + uint32_t funcRVA = functions[ord]; + return reinterpret_cast(base + funcRVA); + } + } + return nullptr; +} + +typedef FARPROC (*GetProcAddress_t)(HMODULE, LPCSTR); +GetProcAddress_t pGetProcAddress = nullptr; + +BOOL DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) { + if (fdwReason == 1) { // DLL_PROCESS_ATTACH + HMODULE kernel32 = LoadLibraryExA("kernel32.dll", 0, 0x00000800); + pGetProcAddress = (GetProcAddress_t)GetRealGetProcAddress(kernel32); + + pOutputDebugStringA = (OutputDebugStringA_t)pGetProcAddress(kernel32, "OutputDebugStringA"); + } + return TRUE; +} + +} diff --git a/user32.dll b/user32.dll new file mode 100644 index 0000000..805702e Binary files /dev/null and b/user32.dll differ diff --git a/user32.exp b/user32.exp new file mode 100644 index 0000000..28edadf Binary files /dev/null and b/user32.exp differ diff --git a/user32.lib b/user32.lib new file mode 100644 index 0000000..f696739 Binary files /dev/null and b/user32.lib differ diff --git a/user32.obj b/user32.obj new file mode 100644 index 0000000..c7c4f48 Binary files /dev/null and b/user32.obj differ diff --git a/vc140.pdb b/vc140.pdb new file mode 100644 index 0000000..1f1947c Binary files /dev/null and b/vc140.pdb differ diff --git a/winmm.cpp b/winmm.cpp new file mode 100644 index 0000000..a81aedf --- /dev/null +++ b/winmm.cpp @@ -0,0 +1,183 @@ +typedef void* HWND; +typedef void* LPUNKNOWN; +typedef void* REFIID; +typedef void* REFCLSID; +typedef long HRESULT; +typedef unsigned long DWORD; +typedef unsigned int UINT; +typedef int BOOL; +typedef void* HANDLE; +typedef void* LPVOID; +typedef long LONG; +typedef long LONG_PTR; +typedef const char* LPCSTR; +typedef size_t SIZE_T; +typedef void* HMODULE; +typedef HMODULE HINSTANCE; +typedef void* FARPROC; +typedef DWORD (*LPTHREAD_START_ROUTINE)(LPVOID lpThreadParameter); +typedef union _LARGE_INTEGER { + struct { + unsigned long LowPart; + long HighPart; + }; + long long QuadPart; +} LARGE_INTEGER; +#define S_OK ((HRESULT)0L) +#define TRUE 1 +#define FALSE 0 +#include + +extern "C" { + +typedef DWORD (*timeGetTime_t)(); +timeGetTime_t ptimeGetTime = nullptr; + +__declspec(dllexport) DWORD timeGetTime() { + return ptimeGetTime(); +} + +HMODULE LoadLibraryExA(LPCSTR lpLibFileName, HANDLE hFile, DWORD dwFlags); + +#define IMAGE_DOS_SIGNATURE 0x5A4D // MZ +#define IMAGE_NT_SIGNATURE 0x00004550 // PE00 +#define IMAGE_DIRECTORY_ENTRY_EXPORT 0 + +struct IMAGE_DOS_HEADER { + uint16_t e_magic; + uint16_t e_cblp; + uint16_t e_cp; + uint16_t e_crlc; + uint16_t e_cparhdr; + uint16_t e_minalloc; + uint16_t e_maxalloc; + uint16_t e_ss; + uint16_t e_sp; + uint16_t e_csum; + uint16_t e_ip; + uint16_t e_cs; + uint16_t e_lfarlc; + uint16_t e_ovno; + uint16_t e_res[4]; + uint16_t e_oemid; + uint16_t e_oeminfo; + uint16_t e_res2[10]; + uint32_t e_lfanew; +}; + +struct IMAGE_FILE_HEADER { + uint16_t Machine; + uint16_t NumberOfSections; + uint32_t TimeDateStamp; + uint32_t PointerToSymbolTable; + uint32_t NumberOfSymbols; + uint16_t SizeOfOptionalHeader; + uint16_t Characteristics; +}; + +struct IMAGE_DATA_DIRECTORY { + uint32_t VirtualAddress; + uint32_t Size; +}; + +struct IMAGE_OPTIONAL_HEADER64 { + uint16_t Magic; + uint8_t MajorLinkerVersion; + uint8_t MinorLinkerVersion; + uint32_t SizeOfCode; + uint32_t SizeOfInitializedData; + uint32_t SizeOfUninitializedData; + uint32_t AddressOfEntryPoint; + uint32_t BaseOfCode; + uint64_t ImageBase; + uint32_t SectionAlignment; + uint32_t FileAlignment; + uint16_t MajorOperatingSystemVersion; + uint16_t MinorOperatingSystemVersion; + uint16_t MajorImageVersion; + uint16_t MinorImageVersion; + uint16_t MajorSubsystemVersion; + uint16_t MinorSubsystemVersion; + uint32_t Win32VersionValue; + uint32_t SizeOfImage; + uint32_t SizeOfHeaders; + uint32_t CheckSum; + uint16_t Subsystem; + uint16_t DllCharacteristics; + uint64_t SizeOfStackReserve; + uint64_t SizeOfStackCommit; + uint64_t SizeOfHeapReserve; + uint64_t SizeOfHeapCommit; + uint32_t LoaderFlags; + uint32_t NumberOfRvaAndSizes; + IMAGE_DATA_DIRECTORY DataDirectory[16]; +}; + +struct IMAGE_NT_HEADERS64 { + uint32_t Signature; + IMAGE_FILE_HEADER FileHeader; + IMAGE_OPTIONAL_HEADER64 OptionalHeader; +}; + +struct IMAGE_EXPORT_DIRECTORY { + uint32_t Characteristics; + uint32_t TimeDateStamp; + uint16_t MajorVersion; + uint16_t MinorVersion; + uint32_t Name; + uint32_t Base; + uint32_t NumberOfFunctions; + uint32_t NumberOfNames; + uint32_t AddressOfFunctions; // RVA from base of image + uint32_t AddressOfNames; // RVA from base of image + uint32_t AddressOfNameOrdinals; // RVA from base of image +}; + +int strcmp(const char* a, const char* b) { + while (*a && (*a == *b)) { + ++a; + ++b; + } + return static_cast(*a) - static_cast(*b); +} + +FARPROC GetRealGetProcAddress(HMODULE hModule) { + auto base = reinterpret_cast(hModule); + auto dos = reinterpret_cast(base); + if (dos->e_magic != IMAGE_DOS_SIGNATURE) return nullptr; + + auto nt = reinterpret_cast(base + dos->e_lfanew); + if (nt->Signature != IMAGE_NT_SIGNATURE) return nullptr; + + auto exportDirRVA = nt->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress; + auto exportDir = reinterpret_cast(base + exportDirRVA); + + auto names = reinterpret_cast(base + exportDir->AddressOfNames); + auto ordinals = reinterpret_cast(base + exportDir->AddressOfNameOrdinals); + auto functions = reinterpret_cast(base + exportDir->AddressOfFunctions); + + for (uint32_t i = 0; i < exportDir->NumberOfNames; i++) { + const char* name = reinterpret_cast(base + names[i]); + if (strcmp(name, "GetProcAddress") == 0) { + uint16_t ord = ordinals[i]; + uint32_t funcRVA = functions[ord]; + return reinterpret_cast(base + funcRVA); + } + } + return nullptr; +} + +typedef FARPROC (*GetProcAddress_t)(HMODULE, LPCSTR); +GetProcAddress_t pGetProcAddress = nullptr; + +BOOL DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) { + if (fdwReason == 1) { // DLL_PROCESS_ATTACH + HMODULE kernel32 = LoadLibraryExA("kernel32.dll", 0, 0x00000800); + pGetProcAddress = (GetProcAddress_t)GetRealGetProcAddress(kernel32); + + ptimeGetTime = (timeGetTime_t)pGetProcAddress(kernel32, "timeGetTime"); + } + return TRUE; +} + +} diff --git a/winmm.dll b/winmm.dll new file mode 100644 index 0000000..fe07a22 Binary files /dev/null and b/winmm.dll differ diff --git a/winmm.exp b/winmm.exp new file mode 100644 index 0000000..81ac7d1 Binary files /dev/null and b/winmm.exp differ diff --git a/winmm.lib b/winmm.lib new file mode 100644 index 0000000..b8731ab Binary files /dev/null and b/winmm.lib differ diff --git a/winmm.obj b/winmm.obj new file mode 100644 index 0000000..718a165 Binary files /dev/null and b/winmm.obj differ diff --git a/you_are_nothing.bk2 b/you_are_nothing.bk2 new file mode 100644 index 0000000..2503128 Binary files /dev/null and b/you_are_nothing.bk2 differ