diff --git a/Common/Common.h b/Common/Common.h index fe4a6e9586..df4b22acba 100644 --- a/Common/Common.h +++ b/Common/Common.h @@ -151,6 +151,46 @@ private: # define _M_SSE 0x402 #endif + +#ifdef _MSC_VER +inline unsigned long long bswap64(unsigned long long x) { return _byteswap_uint64(x); } +inline unsigned int bswap32(unsigned int x) { return _byteswap_ulong(x); } +inline unsigned int bswap16(unsigned int x) { return _byteswap_ushort(x); } +#else +// TODO: speedup +inline unsigned short bswap16(unsigned short x) { return (x << 8) | (x >> 8); } +inline unsigned int bswap32(unsigned int x) { return (x >> 24) | ((x & 0xFF0000) >> 8) | ((x & 0xFF00) << 8) | (x << 24);} +inline unsigned long long bswap64(unsigned long long x) {return ((unsigned long long)bswap32(x) << 32) | bswap32(x >> 32); } +#endif + +inline float bswapf( float f ) +{ + union + { + float f; + unsigned int u32; + } dat1, dat2; + + dat1.f = f; + dat2.u32 = bswap32(dat1.u32); + + return dat2.f; +} + +inline double bswapd( double f ) +{ + union + { + double f; + unsigned long long u64; + } dat1, dat2; + + dat1.f = f; + dat2.u64 = bswap64(dat1.u64); + + return dat2.f; +} + #include "Swap.h" #endif // _COMMON_H_ diff --git a/Common/CommonFuncs.h b/Common/CommonFuncs.h index 73a0a3cfda..cae36a2cc7 100644 --- a/Common/CommonFuncs.h +++ b/Common/CommonFuncs.h @@ -29,6 +29,11 @@ template<> struct CompileTimeAssert {}; #include #include +#ifdef __linux__ +#include +#elif defined __FreeBSD__ +#include +#endif // go to debugger mode #ifdef GEKKO @@ -101,3 +106,41 @@ extern "C" { // Defined in Misc.cpp. const char* GetLastErrorMsg(); +namespace Common +{ +inline u8 swap8(u8 _data) {return _data;} + +#ifdef _WIN32 +#undef swap32 +inline u16 swap16(u16 _data) {return _byteswap_ushort(_data);} +inline u32 swap32(u32 _data) {return _byteswap_ulong (_data);} +inline u64 swap64(u64 _data) {return _byteswap_uint64(_data);} +/* +#elif __linux__ +inline u16 swap16(u16 _data) {return bswap_16(_data);} +inline u32 swap32(u32 _data) {return bswap_32(_data);} +inline u64 swap64(u64 _data) {return bswap_64(_data);} +#elif __APPLE__ +inline __attribute__((always_inline)) u16 swap16(u16 _data) + {return (_data >> 8) | (_data << 8);} +inline __attribute__((always_inline)) u32 swap32(u32 _data) + {return __builtin_bswap32(_data);} +inline __attribute__((always_inline)) u64 swap64(u64 _data) + {return __builtin_bswap64(_data);} +#elif __FreeBSD__ +inline u16 swap16(u16 _data) {return bswap16(_data);} +inline u32 swap32(u32 _data) {return bswap32(_data);} +inline u64 swap64(u64 _data) {return bswap64(_data);} +*/ +#else +// Slow generic implementation. +//inline u16 swap16(u16 data) {return (data >> 8) | (data << 8);} +//inline u32 swap32(u32 data) {return (swap16(data) << 16) | swap16(data >> 16);} +//inline u64 swap64(u64 data) {return ((u64)swap32(data) << 32) | swap32(data >> 32);} +#endif + +//inline u16 swap16(const u8* _pData) {return swap16(*(const u16*)_pData);} +//inline u32 swap32(const u8* _pData) {return swap32(*(const u32*)_pData);} +//inline u64 swap64(const u8* _pData) {return swap64(*(const u64*)_pData);} + +} // Namespace Common diff --git a/Common/Swap.h b/Common/Swap.h index 0563cf381f..b937f9ed1e 100644 --- a/Common/Swap.h +++ b/Common/Swap.h @@ -17,8 +17,6 @@ #pragma once -#include "base/basictypes.h" - // Android #if defined(ANDROID) #include @@ -63,34 +61,6 @@ #define COMMON_LITTLE_ENDIAN 1 #endif -inline float swapf( float f ) -{ - union - { - float f; - unsigned int u32; - } dat1, dat2; - - dat1.f = f; - dat2.u32 = swap32(dat1.u32); - - return dat2.f; -} - -inline double swapd( double f ) -{ - union - { - double f; - unsigned long long u64; - } dat1, dat2; - - dat1.f = f; - dat2.u64 = swap64(dat1.u64); - - return dat2.f; -} - template struct swap_struct_t { typedef swap_struct_t swapped_t; @@ -483,35 +453,35 @@ bool operator==(const S &p, const swap_struct_t v) { template struct swap_64_t { static T swap(T x) { - return (T)swap64(*(u64 *)&x); + return (T)bswap64(*(u64 *)&x); } }; template struct swap_32_t { static T swap(T x) { - return (T)swap32(*(u32 *)&x); + return (T)bswap32(*(u32 *)&x); } }; template struct swap_16_t { static T swap(T x) { - return (T)swap16(*(u16 *)&x); + return (T)bswap16(*(u16 *)&x); } }; template struct swap_float_t { static T swap(T x) { - return (T)swapf(*(float *)&x); + return (T)bswapf(*(float *)&x); } }; template struct swap_double_t { static T swap(T x) { - return (T)swapd(*(double *)&x); + return (T)bswapd(*(double *)&x); } }; @@ -562,4 +532,4 @@ typedef s64 s64_be; typedef float float_be; typedef double double_be; -#endif +#endif \ No newline at end of file diff --git a/Core/HLE/sceMpeg.cpp b/Core/HLE/sceMpeg.cpp index b700507c2b..5b0e0cc25e 100644 --- a/Core/HLE/sceMpeg.cpp +++ b/Core/HLE/sceMpeg.cpp @@ -261,8 +261,8 @@ void AnalyzeMpeg(u8 *buffer, MpegContext *ctx) { ctx->mpegVersion = -1; break; } - ctx->mpegOffset = swap32(*(u32_le*)(buffer + PSMF_STREAM_OFFSET_OFFSET)); - ctx->mpegStreamSize = swap32(*(u32_le*)(buffer + PSMF_STREAM_SIZE_OFFSET)); + ctx->mpegOffset = bswap32(*(u32_le*)(buffer + PSMF_STREAM_OFFSET_OFFSET)); + ctx->mpegStreamSize = bswap32(*(u32_le*)(buffer + PSMF_STREAM_SIZE_OFFSET)); ctx->mpegFirstTimestamp = getMpegTimeStamp(buffer + PSMF_FIRST_TIMESTAMP_OFFSET); ctx->mpegLastTimestamp = getMpegTimeStamp(buffer + PSMF_LAST_TIMESTAMP_OFFSET); ctx->mpegFirstDate = convertTimestampToDate(ctx->mpegFirstTimestamp); diff --git a/Core/HLE/scePsmf.cpp b/Core/HLE/scePsmf.cpp index 862edc63f1..e65c065edd 100644 --- a/Core/HLE/scePsmf.cpp +++ b/Core/HLE/scePsmf.cpp @@ -203,8 +203,8 @@ public: int streamId = Memory::Read_U8(addr); int privateStreamId = Memory::Read_U8(addr + 1); // two unknowns here - psmf->EPMapOffset = swap32(Memory::Read_U32(addr + 4)); - psmf->EPMapEntriesNum = swap32(Memory::Read_U32(addr + 8)); + psmf->EPMapOffset = bswap32(Memory::Read_U32(addr + 4)); + psmf->EPMapEntriesNum = bswap32(Memory::Read_U32(addr + 8)); psmf->videoWidth = Memory::Read_U8(addr + 12) * 16; psmf->videoHeight = Memory::Read_U8(addr + 13) * 16; @@ -239,14 +239,14 @@ Psmf::Psmf(u32 data) { headerOffset = data; magic = Memory::Read_U32(data); version = Memory::Read_U32(data + 4); - streamOffset = swap32(Memory::Read_U32(data + 8)); - streamSize = swap32(Memory::Read_U32(data + 12)); - streamDataTotalSize = swap32(Memory::Read_U32(data + 0x50)); + streamOffset = bswap32(Memory::Read_U32(data + 8)); + streamSize = bswap32(Memory::Read_U32(data + 12)); + streamDataTotalSize = bswap32(Memory::Read_U32(data + 0x50)); presentationStartTime = getMpegTimeStamp(Memory::GetPointer(data + PSMF_FIRST_TIMESTAMP_OFFSET)); presentationEndTime = getMpegTimeStamp(Memory::GetPointer(data + PSMF_LAST_TIMESTAMP_OFFSET)); - streamDataNextBlockSize = swap32(Memory::Read_U32(data + 0x6A)); - streamDataNextInnerBlockSize = swap32(Memory::Read_U32(data + 0x7C)); - numStreams = swap16(Memory::Read_U16(data + 0x80)); + streamDataNextBlockSize = bswap32(Memory::Read_U32(data + 0x6A)); + streamDataNextInnerBlockSize = bswap32(Memory::Read_U32(data + 0x7C)); + numStreams = bswap16(Memory::Read_U16(data + 0x80)); currentStreamNum = -1; currentAudioStreamNum = -1; @@ -604,7 +604,7 @@ u32 scePsmfQueryStreamOffset(u32 bufferAddr, u32 offsetAddr) { WARN_LOG(ME, "scePsmfQueryStreamOffset(%08x, %08x)", bufferAddr, offsetAddr); if (Memory::IsValidAddress(offsetAddr)) { - Memory::Write_U32(swap32(Memory::Read_U32(bufferAddr + PSMF_STREAM_OFFSET_OFFSET)), offsetAddr); + Memory::Write_U32(bswap32(Memory::Read_U32(bufferAddr + PSMF_STREAM_OFFSET_OFFSET)), offsetAddr); } return 0; } @@ -613,7 +613,7 @@ u32 scePsmfQueryStreamSize(u32 bufferAddr, u32 sizeAddr) { WARN_LOG(ME, "scePsmfQueryStreamSize(%08x, %08x)", bufferAddr, sizeAddr); if (Memory::IsValidAddress(sizeAddr)) { - Memory::Write_U32(swap32(Memory::Read_U32(bufferAddr + PSMF_STREAM_SIZE_OFFSET)), sizeAddr); + Memory::Write_U32(bswap32(Memory::Read_U32(bufferAddr + PSMF_STREAM_SIZE_OFFSET)), sizeAddr); } return 0; } @@ -838,9 +838,9 @@ int _PsmfPlayerSetPsmfOffset(PsmfPlayer *psmfplayer, const char * filename, int u8* buf = psmfplayer->tempbuf; u32 tempbufSize = sizeof(psmfplayer->tempbuf); int size = (int)pspFileSystem.ReadFile(psmfplayer->filehandle, buf, 2048); - int mpegoffset = swap32(*(u32*)(buf + PSMF_STREAM_OFFSET_OFFSET)); + int mpegoffset = bswap32(*(u32*)(buf + PSMF_STREAM_OFFSET_OFFSET)); psmfplayer->readSize = size - mpegoffset; - psmfplayer->streamSize = swap32(*(u32*)(buf + PSMF_STREAM_SIZE_OFFSET)); + psmfplayer->streamSize = bswap32(*(u32*)(buf + PSMF_STREAM_SIZE_OFFSET)); psmfplayer->fileoffset = offset + mpegoffset; psmfplayer->mediaengine->loadStream(buf, 2048, std::max(2048 * 500, (int)tempbufSize)); _PsmfPlayerFillRingbuffer(psmfplayer); diff --git a/Core/HW/MediaEngine.cpp b/Core/HW/MediaEngine.cpp index 6cf0079dad..52c1a27da9 100644 --- a/Core/HW/MediaEngine.cpp +++ b/Core/HW/MediaEngine.cpp @@ -327,7 +327,7 @@ int MediaEngine::addStreamData(u8* buffer, int addSize) { #ifdef USE_FFMPEG if (!m_pFormatCtx) { m_pdata->get_front(m_mpegheader, sizeof(m_mpegheader)); - int mpegoffset = swap32(*(int*)(m_mpegheader + 8)); + int mpegoffset = bswap32(*(int*)(m_mpegheader + 8)); m_pdata->pop_front(0, mpegoffset); openContext(); } diff --git a/Core/MIPS/MIPSInt.cpp b/Core/MIPS/MIPSInt.cpp index d8ef64248a..43ae88496f 100644 --- a/Core/MIPS/MIPSInt.cpp +++ b/Core/MIPS/MIPSInt.cpp @@ -790,7 +790,7 @@ namespace MIPSInt R(rd) = ((R(rt) & 0xFF00FF00) >> 8) | ((R(rt) & 0x00FF00FF) << 8); break; case 0xE0: //wsbw - R(rd) = swap32(R(rt)); + R(rd) = _byteswap_ulong(R(rt)); break; default: _dbg_assert_msg_(CPU,0,"Trying to interpret ALLEGREX instruction that can't be interpreted"); diff --git a/Globals.h b/Globals.h index 8701c4601e..85a6a33e8c 100644 --- a/Globals.h +++ b/Globals.h @@ -30,6 +30,15 @@ #define IS_LITTLE_ENDIAN (*(const u16 *)"\0\xff" >= 0x100) #define IS_BIG_ENDIAN (*(const u16 *)"\0\xff" < 0x100) +#ifndef _WIN32 + +inline u32 _byteswap_ulong(u32 data) +{ + return ((data << 24)) | ((data >> 24)) | ((data >> 8) & 0x0000FF00) | ((data << 8) & 0x00FF0000); +} + +#endif + inline u8 Convert4To8(u8 v) { // Swizzle bits: 00012345 -> 12345123