146 lines
2.1 KiB
C++
146 lines
2.1 KiB
C++
#ifndef SDLUTIL_H
|
|
#define SDLUTIL_H
|
|
|
|
#include <SDL_atomic.h>
|
|
#include <SDL_thread.h>
|
|
#include <SDL_rwops.h>
|
|
|
|
#include <string>
|
|
#include <iostream>
|
|
|
|
struct AtomicFlag
|
|
{
|
|
AtomicFlag()
|
|
{
|
|
clear();
|
|
}
|
|
|
|
void set()
|
|
{
|
|
SDL_AtomicSet(&atom, 1);
|
|
}
|
|
|
|
void clear()
|
|
{
|
|
SDL_AtomicSet(&atom, 0);
|
|
}
|
|
|
|
operator bool() const
|
|
{
|
|
return SDL_AtomicGet(&atom);
|
|
}
|
|
|
|
private:
|
|
mutable SDL_atomic_t atom;
|
|
};
|
|
|
|
template<class C, void (C::*func)()>
|
|
int __sdlThreadFun(void *obj)
|
|
{
|
|
(static_cast<C*>(obj)->*func)();
|
|
return 0;
|
|
}
|
|
|
|
template<class C, void (C::*func)()>
|
|
SDL_Thread *createSDLThread(C *obj, const std::string &name = std::string())
|
|
{
|
|
return SDL_CreateThread(__sdlThreadFun<C, func>, name.c_str(), obj);
|
|
}
|
|
|
|
inline bool readFileSDL(const char *path,
|
|
std::string &out)
|
|
{
|
|
SDL_RWops *f = SDL_RWFromFile(path, "rb");
|
|
|
|
if (!f)
|
|
return false;
|
|
|
|
long size = SDL_RWsize(f);
|
|
size_t back = out.size();
|
|
|
|
out.resize(back+size);
|
|
size_t read = SDL_RWread(f, &out[back], 1, size);
|
|
SDL_RWclose(f);
|
|
|
|
if (read != (size_t) size)
|
|
out.resize(back+read);
|
|
|
|
return true;
|
|
}
|
|
|
|
template<size_t bufSize = 248, size_t pbSize = 8>
|
|
class SDLRWBuf : public std::streambuf
|
|
{
|
|
public:
|
|
SDLRWBuf(SDL_RWops *ops)
|
|
: ops(ops)
|
|
{
|
|
char *end = buf + bufSize + pbSize;
|
|
setg(end, end, end);
|
|
}
|
|
|
|
private:
|
|
int_type underflow()
|
|
{
|
|
if (!ops)
|
|
return traits_type::eof();
|
|
|
|
if (gptr() < egptr())
|
|
return traits_type::to_int_type(*gptr());
|
|
|
|
char *base = buf;
|
|
char *start = base;
|
|
|
|
if (eback() == base)
|
|
{
|
|
memmove(base, egptr() - pbSize, pbSize);
|
|
start += pbSize;
|
|
}
|
|
|
|
size_t n = SDL_RWread(ops, start, 1, bufSize - (start - base));
|
|
if (n == 0)
|
|
return traits_type::eof();
|
|
|
|
setg(base, start, start + n);
|
|
|
|
return underflow();
|
|
}
|
|
|
|
SDL_RWops *ops;
|
|
char buf[bufSize+pbSize];
|
|
};
|
|
|
|
class SDLRWStream
|
|
{
|
|
public:
|
|
SDLRWStream(const char *filename,
|
|
const char *mode)
|
|
: ops(SDL_RWFromFile(filename, mode)),
|
|
buf(ops),
|
|
s(&buf)
|
|
{}
|
|
|
|
~SDLRWStream()
|
|
{
|
|
if (ops)
|
|
SDL_RWclose(ops);
|
|
}
|
|
|
|
operator bool() const
|
|
{
|
|
return ops != 0;
|
|
}
|
|
|
|
std::istream &stream()
|
|
{
|
|
return s;
|
|
}
|
|
|
|
private:
|
|
SDL_RWops *ops;
|
|
SDLRWBuf<> buf;
|
|
std::istream s;
|
|
};
|
|
|
|
#endif // SDLUTIL_H
|