Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

Already on GitHub? Sign in to your account

Master (Xbox 360 support) #2885

Closed
wants to merge 3 commits into
from

Conversation

Projects
None yet
4 participants
Contributor

Ced2911 commented Jul 22, 2013

360 Support

@hrydgard hrydgard and 1 other commented on an outdated diff Jul 22, 2013

Common/ppcEmitter.h
+ R18, R19, R20, R21, R22, R23,
+ R24, R25, R26, R27, R28, R29,
+ R30, R31,
+
+ // SPRs
+
+
+ // FPRs
+ FR0, FR1, FR2, FR3, FR4, FR5, FR6,
+ FR7, FR8, FR9, FR10, FR11, FR12, FR13,
+ FR14, FR15, FR16, FR17, FR18, FR19, FR20,
+ FR21, FR22, FR23, FR24, FR25, FR26, FR27,
+ FR28, FR29, FR30, FR31,
+};
+
+enum CCFlags
@hrydgard

hrydgard Jul 22, 2013

Owner

These look like ARM flags?

@Ced2911

Ced2911 Jul 22, 2013

Contributor

yes copy/pasted ^^

Collaborator

unknownbrackets commented Jul 22, 2013

I think we really need to use some magic structs to make this happen more seamlessly. As it is, this makes the code a lot more complicated and brittle. Since I don't have things setup for Xbox 360, I'm likely to either avoid changing code even if I know how to fix it, or else just break Xbox 360 and not care.

-[Unknown]

Collaborator

unknownbrackets commented Jul 22, 2013

What I mean by the magic struct is something like this (possibly using a template for int, u16, maybe even be types, etc.):

#ifndef BIG_ENDIAN
typedef u32 u32_le;
#else
struct u32_le {
   u32_le() {}
   u32_le(const u32 &v) : v_(bswap32(v)) {}

   operator u32() const {
      return bswap32(v_);
   }

   u32 operator+(u32 i) const {
      return bswap32(bswap32(v_) + i);
   }

   ...

private:
   u32 v_;
};
#endif

Then in e.g. NativeLwMutexWorkarea, just declare the fields as u32_le instead of u32.

-[Unknown]

Contributor

Ced2911 commented Jul 22, 2013

thanks i'm gonna take a look soon, i'm looking at making commit cleaner,
and merging the gpu renderer correctly

2013/7/22 Unknown W. Brackets notifications@github.com

What I mean by the magic struct is something like this (possibly using a
template for int, u16, maybe even be types, etc.):

#ifndef BIG_ENDIANtypedef u32 u32_le;#elsestruct u32_le {
u32_le() {}
u32_le(const u32 &v) : v_(bswap32(v)) {}

operator u32() const {
return bswap32(v_);
}

u32 operator+(u32 i) const {
return bswap32(bswap32(v_) + i);
}

...
private:
u32 v_;};#endif

Then in e.g. NativeLwMutexWorkarea, just declare the fields as u32_le
instead of u32.

-[Unknown]


Reply to this email directly or view it on GitHubhttps://github.com/hrydgard/ppsspp/pull/2885#issuecomment-21348377
.

Contributor

Ced2911 commented Jul 22, 2013

i added a new branch https://github.com/Ced2911/ppsspp/tree/xbcleanup_2 do
you think it's cleaner for pull request ?

2013/7/22 Cedric Emond ced2911@gmail.com

thanks i'm gonna take a look soon, i'm looking at making commit cleaner,
and merging the gpu renderer correctly

2013/7/22 Unknown W. Brackets notifications@github.com

What I mean by the magic struct is something like this (possibly using a

template for int, u16, maybe even be types, etc.):

#ifndef BIG_ENDIANtypedef u32 u32_le;#elsestruct u32_le {
u32_le() {}
u32_le(const u32 &v) : v_(bswap32(v)) {}

operator u32() const {
return bswap32(v_);
}

u32 operator+(u32 i) const {
return bswap32(bswap32(v_) + i);
}

...
private:
u32 v_;};#endif

Then in e.g. NativeLwMutexWorkarea, just declare the fields as u32_le
instead of u32.

-[Unknown]


Reply to this email directly or view it on GitHubhttps://github.com/hrydgard/ppsspp/pull/2885#issuecomment-21348377
.

Contributor

Ced2911 commented Jul 23, 2013

it's a bit better, i separed commit, but it's still not fine with the "auto endian type"

Contributor

Ced2911 commented Jul 24, 2013

Hi i can't get the endian struct working correctly, can help me ?

this is the code i use to create the type

#ifndef BIG_ENDIAN
typedef u64 u64_le;
typedef s64 s64_le;

typedef u32 u32_le;
typedef s32 s32_le;

typedef u16 u16_le;
typedef s16 s16_le;
#else


template <typename T>
struct swap_64_t {
    static T swap(T x) {
        return (T)bswap64(x);
    }
};

template <typename T>
struct swap_32_t {
    static T swap(T x) {
        return (T)bswap32(x);
    }
};

template <typename T>
struct swap_16_t {
    static T swap(T x) {
        return (T)bswap16(x);
    }
};

template <typename T, typename F>
struct swap_struct_t {
protected:
    T value;
    virtual T swap(T v) {
        return F::swap(v);
    }
public:
    swap_struct_t() :value(0) {}
    swap_struct_t(const T &v): value(swap(v)) {}
    T& operator=(T &source) { value = swap((T)source); return value; }
    operator T() { return swap(value); }
    // v + 5
    T operator+(T i) {
        return swap(swap(value) + i);
    }
    // v += 5
    T operator+=(int i) {
        return swap(swap(value) + i);
    }
    // v--
    T operator++()  {
        T tmp = swap(value);
        value = swap(swap(value)++);
        return tmp;
    }
    // v++
    T operator++(int)  {
        T tmp = swap(value);
        value = swap(tmp+1);
        return tmp;
    }
};

typedef swap_struct_t<u64, swap_64_t<u64>> u64_le;
typedef swap_struct_t<s64, swap_64_t<s64>> s64_le;

typedef swap_struct_t<u32, swap_32_t<u32>> u32_le;
typedef swap_struct_t<s32, swap_32_t<s32>> s32_le;

typedef swap_struct_t<u16, swap_32_t<u32>> u16_le;
typedef swap_struct_t<s16, swap_32_t<s32>> s16_le;

#endif

the code compile until i use PSPPointer

PSPPointer<NativeLwMutexWorkarea> workarea;

i got this errors,
MemMap.h(293): error C2679: binary '+' : no operator found which takes a right-hand operand of type 'const u32_le' (or there is no acceptable conversion) could be 'built-in C++ operator+(u8 *, int)'

while trying to match the argument list '(u8 *, const u32_le)'
d:\document\ppsspp_081\core\MemMap.h(292) : while compiling class template member function 'NativeLwMutexWorkarea *PSPPointer::operator ->(void) const'
with
[
T=NativeLwMutexWorkarea
]
HLE\sceKernelMutex.cpp(148) : see reference to class template instantiation 'PSPPointer' being compiled
with
[
T=NativeLwMutexWorkarea
]

Contributor

VIRGINKLM commented Jul 24, 2013

I'm gonna applaud this pull request.
I'm sooo proud of the attention the project gets.

Collaborator

unknownbrackets commented Jul 25, 2013

So that would be this:

return (T *)(Memory::base + ptr);

Not sure the cleanest way, this makes it compile:

    template <typename TT>
    friend TT *operator+(TT *p, swap_struct_t<T, F> v);

...

template <typename TT>
TT *operator+(TT *p, u32_le v) {
    return p + bswap32(v.value);
}

-[Unknown]

Collaborator

unknownbrackets commented Jul 25, 2013

Anyway, I might recommend something more along these lines:

template <typename T, typename F>
struct swap_struct_t {
    typedef swap_struct_t<T, F> swapped_t;

protected:
    T value;
    static T swap(const T v) {
        return F::swap(v);
    }
    T swap() const {
        return F::swap(value);
    }
public:
    swap_struct_t() :value(0) {}
    swap_struct_t(const T &v): value(swap(v)) {}
    T& operator=(const T &source) { value = swap((const T)source); return value; }
    operator T() const { return swap(); }
    // v + 5
    swapped_t operator+(const T i) const {
        return swap() + i;
    }
    swapped_t operator+(const swapped_t i) const {
        return swap() + i.swap();
    }
    // v += 5
    swapped_t operator+=(const int i) {
        value = swap(swap() + i);
        return *this;
    }
    // --v
    swapped_t operator--()  {
        value = swap(swap() - 1);
        return *this;
    }
    // v--
    swapped_t operator--(int)  {
        T tmp = swap();
        value = swap(swap() - 1);
        return tmp;
    }
    // ++v
    swapped_t operator++()  {
        value = swap(swap() + 1);
        return *this;
    }
    // v++
    swapped_t operator++(int)  {
        T tmp = swap();
        value = swap(swap() + 1);
        return tmp;
    }

    template <typename TT, typename T, typename F>
    friend TT *operator+(TT *p, swapped_t v);
};

template <typename TT, typename T, typename F>
TT *operator+(TT *p, const swap_struct_t<T, F> v) {
    return p + v.swap();
}

-[Unknown]

Collaborator

unknownbrackets commented Jul 25, 2013

And also something like this:
https://github.com/unknownbrackets/ppsspp/compare/endian
(basically untested, still passes tests on LE at least... and shouldn't lose any semantic information or etc.)

We could merge that already now probably and get your branch closer. The less we have to change at once the better imho.

-[Unknown]

Contributor

Ced2911 commented Jul 25, 2013

I tried this sample code to test

#include <stdint.h>
#include <stdlib.h>

typedef unsigned __int8 u8;
typedef unsigned __int16 u16;
typedef unsigned __int32 u32;
typedef unsigned __int64 u64;

typedef signed __int8 s8;
typedef signed __int16 s16;
typedef signed __int32 s32;
typedef signed __int64 s64;

inline unsigned int bswap32(unsigned int x) { return _byteswap_ulong(x); }
inline unsigned short bswap16(unsigned short x) { return _byteswap_ushort(x); }
inline unsigned long long bswap64(unsigned long long x) {return _byteswap_uint64(x);}

template <typename T>
struct swap_double_t {
    static T swap(T x) {
        return (T)LE_D(x);
    }
};

template <typename T>
struct swap_float_t {
    static T swap(T x) {
        return (T)LE_F(x);
    }
};

template <typename T>
struct swap_64_t {
    static T swap(T x) {
        return (T)bswap64(x);
    }
};

template <typename T>
struct swap_32_t {
    static T swap(T x) {
        return (T)bswap32(x);
    }
};

template <typename T>
struct swap_16_t {
    static T swap(T x) {
        return (T)bswap16(x);
    }
};

template <typename T, typename F>
struct swap_struct_t {
    typedef swap_struct_t<T, F> swapped_t;

protected:
    T value;
    T swap(T v) {
        return F::swap(v);
    }
public:
    T const swap() {
        return swap(value);
    }

    swap_struct_t() :value(0) {}
    swap_struct_t(const T &v): value(swap(v)) {}

    T& operator=(const T &source) { value = swap((T)source); return value; }

    template <typename S>
    operator S() { return (S)swap(); }

    // v + 5    
    template <typename S>
    T operator+(S i) {
        return swap() + i;
    }
    // v - 5    
    template <typename S>
    T operator-(S i) {
        return swap() - i;
    }

    // v += 5
    template <typename S>
    swapped_t& operator+=(S i) {
        value = swap(swap() + i);
        return *this;
    }
    // v -= 5
    template <typename S>
    swapped_t& operator-=(S i) {
        value = swap(swap() - i);
        return *this;
    }

    // ++v
    swapped_t operator++()  {
        value = swap(swap()+1);
        return *this;
    }
    // --v
    swapped_t operator--()  {
        value = swap(swap()-1);
        return *this;
    }

    // v++
    template <typename S>
    swapped_t operator++(S i)  {
        T old = value;
        value = swap(swap()+i);
        return swapped_t(old);
    }
    // v--
    template <typename S>
    swapped_t operator--(S i)  {
        T old = value;
        value = swap(swap()-i);
        return swapped_t(old);
    }
    // Comparaison
    // v == i   
    template <typename S>
    T operator==(S i) {
        return swap() == i;
    }

    // v == i   
    template <typename S>
    T operator!=(S i)  {
        return swap() != i;
    }

    // v > i    
    template <typename S>
    T operator>(S i) {
        return swap() > i;
    }

    // v < i
    template <typename S>
    T operator<(S i) {
        return swap() < i;
    }

    // v >= i   
    template <typename S>
    T operator>=(S i) {
        return swap() >= i;
    }

    // v <= i
    template <typename S>
    T operator<=(S i) {
        return swap() <= i;
    }

    template <typename TT, typename T, typename F>
    friend TT *operator+(TT *p, swapped_t v);
};

template <typename TT, typename T, typename F>
TT *operator+(TT *p, const swap_struct_t<T, F> v) {
    return p + v.swap();
}


typedef swap_struct_t<u64, swap_64_t<u64>> u64_le;
typedef swap_struct_t<s64, swap_64_t<s64>> s64_le;

typedef swap_struct_t<u32, swap_32_t<u32>> u32_le;
typedef swap_struct_t<s32, swap_32_t<s32>> s32_le;

typedef swap_struct_t<u16, swap_16_t<u32>> u16_le;
typedef swap_struct_t<s16, swap_16_t<s32>> s16_le;


///////////////////////////////////////////////////////////
//  PPSSPP 
///////////////////////////////////////////////////////////
extern u8 * base;

bool MemoryIsValid(const u32 address) {
    if ((address & 0x3E000000) == 0x08000000)
    {
        return true;
    }
    else if ((address & 0x3F800000) == 0x04000000)
    {
        return true;
    }
    else if ((address & 0xBFFF0000) == 0x00010000)
    {
        return true;
    }
    else
        return false;
}

template <typename T>
struct PSPPointer
{
    u32_le ptr;

    inline T &operator*() const
    {
        return *(T *)(base + ptr);
    }

    inline T &operator[](int i) const
    {
        return *((T *)(base + ptr) + i);
    }

    inline T *operator->() const
    {
        return (T *)(base + ptr);
    }

    inline PSPPointer<T> operator+(int i) const
    {
        PSPPointer other;
        other.ptr = ptr + i * sizeof(T);
        return other;
    }

    inline PSPPointer<T> &operator=(u32 p)
    {
        ptr = p;
        return *this;
    }

    inline PSPPointer<T> &operator+=(int i)
    {
        ptr = ptr + i * sizeof(T);
        return *this;
    }

    inline PSPPointer<T> operator-(int i) const
    {
        PSPPointer other;
        other.ptr = ptr - i * sizeof(T);
        return other;
    }

    inline PSPPointer<T> &operator-=(int i)
    {
        ptr = ptr - i * sizeof(T);
        return *this;
    }

    inline PSPPointer<T> &operator++()
    {
        ptr += sizeof(T);
        return *this;
    }

    inline PSPPointer<T> operator++(int i)
    {
        PSPPointer<T> other;
        other.ptr = ptr;
        ptr += sizeof(T);
        return other;
    }

    inline PSPPointer<T> &operator--()
    {
        ptr -= sizeof(T);
        return *this;
    }

    inline PSPPointer<T> operator--(int i)
    {
        PSPPointer<T> other;
        other.ptr = ptr;
        ptr -= sizeof(T);
        return other;
    }

    inline operator T*()
    {
        return (T *)(base + ptr);
    }

    bool IsValid() const
    {
        return MemoryIsValid(ptr);
    }
};

with this sample code

PSPPointer<test_t> pptr;
    base = new u8[0x1000];

    u32_le i = 0x10;
    printf("i: %08x\r\n", i);

    i = 0x500;
    printf("i: %08x\r\n", i);

    i += 0x500;
    printf("i: %08x\r\n", ++i);
    printf("i: %08x\r\n", --i);
    printf("i: %08x\r\n", i - 0x10);
    printf("i: %08x\r\n", i > (u32)0x1000);

    u32 t = 100;

    if (t - i) { // Fail to compile
        printf("Something !\n");
    }

    pptr+=5;
    pptr++;
    pptr--;
    pptr.IsValid(); // Fail to compile

but i'm having issues on " if (t - i) " and "pptr.IsValid();", i'm sorry i'm not very good with those templates code ^^

Collaborator

unknownbrackets commented Jul 25, 2013

Const correctness does matter. Try this:

template <typename T, typename F>
struct swap_struct_t {
    typedef swap_struct_t<T, F> swapped_t;

protected:
    T value;
    static T swap(T v) {
        return F::swap(v);
    }
public:
    T const swap() const {
        return swap(value);
    }

    swap_struct_t() :value(0) {}
    swap_struct_t(const T &v): value(swap(v)) {}

    template <typename S>
    swapped_t& operator=(const S &source) {
        value = swap((T)source);
        return *this;
    }

    template <typename S>
    operator S() const { return (S)swap(); }

    // v + 5
    swapped_t operator+(const swapped_t &i) const {
        return swap() + i.swap();
    }
    template <typename S>
    swapped_t operator+(const S &i) const {
        return swap() + (T)i;
    }
    // v - 5
    swapped_t operator-(const swapped_t &i) const {
        return swap() - i.swap();
    }
    template <typename S>
    swapped_t operator-(const S &i) const {
        return swap() - (T)i;
    }

    // v += 5
    swapped_t operator+=(const swapped_t &i) {
        value = swap(swap() + i.swap());
        return *this;
    }
    template <typename S>
    swapped_t& operator+=(const S &i) {
        value = swap(swap() + (T)i);
        return *this;
    }
    // v -= 5
    swapped_t operator-=(const swapped_t &i) {
        value = swap(swap() - i.swap());
        return *this;
    }
    template <typename S>
    swapped_t& operator-=(const S &i) {
        value = swap(swap() - (T)i);
        return *this;
    }

    // ++v
    swapped_t operator++()  {
        value = swap(swap()+1);
        return *this;
    }
    // --v
    swapped_t operator--()  {
        value = swap(swap()-1);
        return *this;
    }

    // v++
    swapped_t operator++(int)  {
        T old = value;
        value = swap(swap()+1);
        return old;
    }
    // v--
    swapped_t operator--(int)  {
        T old = value;
        value = swap(swap()-1);
        return old;
    }
    // Comparaison
    // v == i   
    template <typename S>
    bool operator==(const S &i) {
        return swap() == i;
    }

    // v != i
    bool operator!=(const swapped_t &i) const {
        return value != i.value;
    }
    template <typename S>
    bool operator!=(const S &i) const {
        return swap() != i;
    }

    // v > i
    bool operator>(const swapped_t &i) const {
        return swap() > i.swap();
    }
    template <typename S>
    bool operator>(const S &i) const {
        return swap() > i;
    }

    // v < i
    bool operator<(const swapped_t &i) const {
        return swap() < i.swap();
    }
    template <typename S>
    bool operator<(const S &i) const {
        return swap() < i;
    }

    // v >= i
    bool operator>=(const swapped_t &i) const {
        return swap() >= i.swap();
    }
    template <typename S>
    bool operator>=(const S &i) const {
        return swap() >= i;
    }

    // v <= i
    bool operator<=(const swapped_t &i) const {
        return swap() <= i.swap();
    }
    template <typename S>
    bool operator<=(const S &i) const {
        return swap() <= i;
    }

    template <typename S, typename T, typename F>
    friend S operator+(const S &p, const swapped_t v);

    template <typename S, typename T, typename F>
    friend S operator+=(const S &p, const swapped_t v);

    template <typename S, typename T, typename F>
    friend S operator-(const S &p, const swapped_t v);

    template <typename S, typename T, typename F>
    friend S operator-=(const S &p, const swapped_t v);
};

template <typename S, typename T, typename F>
S operator+(const S &i, const swap_struct_t<T, F> v) {
    return i + v.swap();
}

template <typename S, typename T, typename F>
S &operator+=(S &i, const swap_struct_t<T, F> v) {
    i += v.swap();
    return i;
}

template <typename S, typename T, typename F>
S operator-(const S &i, const swap_struct_t<T, F> v) {
    return i - v.swap();
}

template <typename S, typename T, typename F>
S &operator-=(S &i, const swap_struct_t<T, F> v) {
    i -= v.swap();
    return i;
}

-[Unknown]

Contributor

Ced2911 commented Jul 26, 2013

I'm still getting some error, when passing value by reference (__KernelCreateThread when doing t->AllocateStack), it need a temporary value ? also when using union, and i have some issues with PointerWrap, could it be better to use only needed the swapped type (Memory::GetStruct etc...) and for Read/WriteStruct use the structure swapped ?

Collaborator

unknownbrackets commented Jul 26, 2013

Hmm. I think we should just change AllocateStack(). It looks wrong anyway, since it takes a reference to a value, but sets nt.stackSize anyway. If you change from bool AllocateStack(u32 &stackSize) to bool AllocateStack(u32 stackSize) it should work fine.

What about unions? The Elf32_Dyn stuff? Doesn't even seem like that's used?

What are the errors with PointerWrap? We may have to use is_standard_layout when _XBOX is defined, or something.

I don't understand the swapped type part. One of the problems is that there are sometimes situations like this (PSP code, just an example):

typedef char SavedataName[20];
typedef char SavedataFilename[13];

typedef struct SavedataItem
{
   SavedataFilename filename;
   int flags;
} SavedataItem;

typedef struct SavedataOther
{
   SavedataName *names;
   SavedataItem *items;
} SavedataOther;

typedef struct Savedata
{
   int blah1;
   SavedataOther *otherdata;
} Savedata;

You can imagine this is complicated to deal with. But using PSPPointer, it gets a lot easier, because it looks like this (PPSSPP code, just an example):

typedef char SavedataName[20];
typedef char SavedataFilename[13];

struct SavedataItem
{
   SavedataFilename filename;
   int flags;
};

struct SavedataOther
{
   PSPPointer<SavedataName> names;
   PSPPointer<SavedataItem> items;
};

struct Savedata
{
   int blah1;
   PSPPointer<SavedataOther> otherdata;
};

This allows you to do:

Savedata savedata;
savedata = u32ArgFromMIPS;

printf("%s\n", savedata->otherdata->items[5].filename);

This makes the code (imho) significantly clearer to work with, which also means it's easier to make sure it doesn't have bugs.

However, if we're swapping, this becomes:

Savedata savedata;
// Assume u32ArgFromMIPS is a BE value (syscall arg, MIPS shouldn't be able to tell.)
savedata = u32ArgFromMIPS;

auto otherptr = savedata->otherdata;
// WARNING: this damages PSP memory, we need to swap back.
otherptr.swap();
auto items = otherptr->items;
// WARNING: this damages PSP memory, we need to swap back.
items.swap();
printf("%s\n", items[5].filename);

// Okay, now unbreak PSP memory.
items.swap();
otherptr.swap();

You can see how much more non-trivial that is. Leaving the pointer wrong will cause bugs in games, and it'll be hard to spot. Also, since this is BE-only, the code will actually be:

Savedata savedata;
// Assume u32ArgFromMIPS is a BE value (syscall arg, MIPS shouldn't be able to tell.)
savedata = u32ArgFromMIPS;

auto otherptr = savedata->otherdata;
#if COMMON_BIG_ENDIAN
// WARNING: this damages PSP memory, we need to swap back.
otherptr.swap();
#endif
auto items = otherptr->items;
#if COMMON_BIG_ENDIAN
// WARNING: this damages PSP memory, we need to swap back.
items.swap();
#endif
printf("%s\n", items[5].filename);

#if COMMON_BIG_ENDIAN
// Okay, now unbreak PSP memory.
items.swap();
otherptr.swap();
#endif

Good news. We turned 3 SLOC into 15 SLOC, a 5x increase in code size. Assuming a fixed % of bugs per line of code, and a fixed productivity/understanding rate per line of code, we've added 400% chance of bugs and reduced productivity by 80%. That is not a win, that's a mega loss.

From what I can see, the majority of these structs are not going to be performance critical, although we should definitely check fonts and elf loading. Using a couple temporaries (which can be used the same on LE and BE) could probably improve that. Do you know if there are profilers for Xbox 360?

-[Unknown]

@unknownbrackets unknownbrackets commented on an outdated diff Jul 28, 2013

Common/ChunkFile.h
@@ -488,7 +488,7 @@ class PointerWrap
template<class T>
void Do(T &x) {
- DoHelper<T>::Do(this, x);
+// DoHelper<T>::Do(this, x);
@unknownbrackets

unknownbrackets Jul 28, 2013

Collaborator

What errors do you get? I think we can fix them by changing this part:

#ifdef _MSC_VER
template<typename T, bool isPOD = std::is_pod<T>::value, bool isPointer = std::is_pointer<T>::value>
#else
template<typename T, bool isPOD = __is_pod(T), bool isPointer = std::is_pointer<T>::value>
#endif

Since _XBOX is MSVC, we could probably check is_standard_layout, which is really the goal here anyway. Although, if you have a constructor it's probably good to do things carefully. Maybe something like:

#ifdef _XBOX
// TODO: Other big endian platforms will also have trouble here.
template<typename T, bool isPOD = std::is_standard_layout<T>::value, bool isPointer = std::is_pointer<T>::value>
#ifdef _MSC_VER
// It's a good thing to warn when there's a constructor anyway, so is_pod should be fine for Intel Windows.
template<typename T, bool isPOD = std::is_pod<T>::value, bool isPointer = std::is_pointer<T>::value>
#else
template<typename T, bool isPOD = __is_pod(T), bool isPointer = std::is_pointer<T>::value>
#endif

Can't merge with this as is, since it will break savestates for everyone.

-[Unknown]

@unknownbrackets unknownbrackets commented on an outdated diff Jul 28, 2013

Common/Common.h
#else
// TODO: speedup
inline unsigned int bswap32(unsigned int x) { return (x >> 24) | ((x & 0xFF0000) >> 8) | ((x & 0xFF00) << 8) | (x << 24);}
inline unsigned short bswap16(unsigned short x) { return (x << 8) | (x >> 8); }
#endif
+#ifdef BIG_ENDIAN
@unknownbrackets

unknownbrackets Jul 28, 2013

Collaborator

This will cause problems on Android. Need to use COMMON_BIG_ENDIAN.

-[Unknown]

Contributor

Ced2911 commented Jul 29, 2013

i've updated the files, only common and core are commited.

for libkirk, i'm doing it the old way (Ced2911/ppsspp@5e71e08) is it correct ?

Collaborator

unknownbrackets commented Jul 30, 2013

Well, I'm staying away from that code, dunno if there's any reason it should or shouldn't use the _le stuff.

-[Unknown]

Owner

hrydgard commented Aug 24, 2013

I assume this one is pretty outdated so closing. We've merged parts separetely and hopefully we can later merge much of the D3D stuff as well.

@hrydgard hrydgard closed this Aug 24, 2013

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment