-fixed a mixed up background (thanks ayatus)

-set wiiflow version to beta 4.2.2
-added another memory manager just for wii games and banners
-changed THP file playback, for sound you now need to have a ogg file with the same name, that fixes all audio shutters and crashes
-optimized THP file playback and JPG extraction alot, it should now work fine with 640x480 30fps without any crash or freeze anymore
This commit is contained in:
fix94.1 2014-02-28 23:11:02 +00:00
parent f0d987f9a4
commit 3bc03871fe
26 changed files with 265 additions and 422 deletions

View File

@ -628,10 +628,15 @@ void PatchRegion(void *Address, int Size)
while(addr_start < addr_end)
{
if(!memcmp(addr_start, sig_setting, sizeof(sig_setting)))
{
gprintf("Patching setting region\n");
memcpy(addr_start, patch_setting, sizeof(patch_setting));
}
if(!memcmp(addr_start, sig_SYSCONF, sizeof(sig_SYSCONF)))
{
gprintf("Patching SYSCONF region\n");
memcpy(addr_start, patch_SYSCONF, sizeof(patch_SYSCONF));
}
addr_start += 4;
}
}

View File

@ -21,7 +21,6 @@ misrepresented as being the original software.
3. This notice may not be removed or altered from any source
distribution.
*/
#include <malloc.h>
#include "LanguageCode.h"
#include "AnimatedBanner.h"
#include "gui/text.hpp"
@ -35,6 +34,7 @@ AnimatedBanner::AnimatedBanner()
{
layout_banner = NULL;
newBanner = NULL;
oriBanner = NULL;
}
void AnimatedBanner::LoadFont(u8 *font1, u8 *font2)
@ -52,8 +52,10 @@ void AnimatedBanner::Clear()
}
if(newBanner != NULL)
{
if(newBanner != oriBanner)
free(newBanner);
newBanner = NULL;
oriBanner = NULL;
}
}
@ -108,6 +110,7 @@ void AnimatedBanner::SetBannerTexture(const char *tex_name, const u8 *data, floa
Layout* AnimatedBanner::LoadLayout(const u8 *bnr, u32 bnr_size, const std::string& lyt_name, const std::string &language)
{
u32 brlyt_size = 0;
oriBanner = bnr;
newBanner = DecompressCopy(bnr, bnr_size, &bnr_size);
if(newBanner == NULL)
return NULL;
@ -186,17 +189,9 @@ u8 *DecompressCopy(const u8 *stuff, u32 len, u32 *size)
if(decompressLZ77content(stuff + 4, len - 4, &ret, &len))
return NULL;
}
else
{
// just copy the data out of the archive
ret = (u8*)MEM2_memalign(32, len);
if( !ret )
{
gprintf( "out of memory\n" );
return NULL;
}
memcpy( ret, stuff, len );
}
else //I hate to do that
ret = (u8*)stuff;
if(size)
*size = len;

View File

@ -45,6 +45,7 @@ protected:
Layout* LoadLayout(const u8 *bnr, u32 bnr_size, const std::string& lyt_name, const std::string &language);
Layout *layout_banner;
u8 *newBanner;
const u8 *oriBanner;
u8 *sysFont1;
u8 *sysFont2;
};

View File

@ -25,13 +25,13 @@ distribution.
#include <set>
#include <string.h>
#include <malloc.h>
#include "memory/mem2.hpp"
#include "BannerTexture.hpp"
Texture::~Texture()
{
if(texture_data)
free(texture_data);
MEM2_lo_free(texture_data);
}
void Texture::Load(const u8 *file )
@ -103,10 +103,10 @@ void Texture::Load(const u8 *file )
void Texture::LoadTextureData(const u8 *data, u16 width, u16 height, u8 fmt)
{
if(texture_data)
free(texture_data);
MEM2_lo_free(texture_data);
int tex_size = GX_GetTexBufferSize(width, height, fmt, GX_FALSE, 0);
texture_data = (u8*) memalign(32, tex_size);
texture_data = (u8*)MEM2_lo_alloc(tex_size);
if(!texture_data)
return;

View File

@ -21,8 +21,7 @@ misrepresented as being the original software.
3. This notice may not be removed or altered from any source
distribution.
*/
#include <malloc.h>
#include "memory/mem2.hpp"
#include "WiiFont.h"
WiiFont::WiiFont()
@ -41,7 +40,7 @@ WiiFont::~WiiFont()
for (itr = textureMap.begin(); itr != textureMap.end(); itr++)
{
if(itr->second.allocated && itr->second.texture_data)
free(itr->second.texture_data);
MEM2_lo_free(itr->second.texture_data);
}
}
@ -370,13 +369,13 @@ u8 *WiiFont::GetUnpackedTexture(u16 sheetNo)
}
// decompress
u8* sheetData = (u8*)memalign( 32, uncompressedSize );// buffer needs to be 32bit aligned
u8* sheetData = (u8*)MEM2_lo_alloc( uncompressedSize );// buffer needs to be 32bit aligned
if( !sheetData )
return NULL;
if( !Decompress_0x28( sheetData, uncompressedSize, ( data + tglp->dataOffset + off + 4 ), compressedSize ) )
{
free( sheetData );
MEM2_lo_free( sheetData );
return NULL;
}

View File

@ -32,6 +32,7 @@
#include <ogc/conf.h>
#include <ogc/isfs.h>
#include <malloc.h>
#include "memory/mem2.hpp"
#include "banner.h"
#include "MD5.h"
#include "nand.hpp"
@ -156,7 +157,7 @@ u8 *Banner::GetFile(const char *name, u32 *size)
return NULL;
//I like to have stuff in a separate memory region
u8 *file = (u8*)malloc(*size);
u8 *file = (u8*)MEM2_lo_alloc(*size);
if(file == NULL)
return NULL;

View File

@ -1045,7 +1045,7 @@ s32 Nand::PreNandCfg(bool miis, bool realconfig)
bool Nand::Do_Region_Change(string id, bool realnand)
{
if(__configread())
if(__configread() == 1)
{
switch(id[3])
{

View File

@ -129,6 +129,7 @@ bool NandSave::CheckSave()
goto error;
}
free(certBuffer);
if(u8_bin != save_bin)
free(u8_bin);
gprintf("Created WiiFlow Save\n");
done:

View File

@ -1,5 +1,5 @@
#define APP_NAME "WiiFlow"
#define APP_VERSION "Beta 4.2.1"
#define APP_VERSION "Beta 4.2.2"
#define APPDATA_DIR "wiiflow"
#define APPDATA_DIR2 "apps/wiiflow"
@ -38,7 +38,7 @@
#define THANKS \
"Lustar, CedWii, Benjay, Domi78, Oops, \
Celtiore, Jiiwah, FluffyKiwi, Roku93, Yardape8000, \
Spayrosam, Bluescreen81, Chappy23, mamule, \
Spayrosam, Bluescreen81, Chappy23, mamule, seam, \
BlindDude, Bubba, DJTaz, OggZee, entropy, Ayatus, \
Usptactical, WiiPower, Hermes, Spidy1000, megazig, \
Dimok, Kovani, Drexyl, DvZ, Etheboss, stfour, \

View File

@ -26,62 +26,39 @@
* for WiiXplorer 2010
***************************************************************************/
#include <unistd.h>
#include <asndlib.h>
#include <malloc.h>
#include "WiiMovie.hpp"
#include "gecko/gecko.hpp"
#define SND_BUFFERS 8
#define FRAME_BUFFERS 8
WiiMovie movie;
static BufferCircle * soundBuffer = NULL;
WiiMovie::WiiMovie(const char * filepath)
void WiiMovie::Init(const char *filepath)
{
VideoFrameCount = 0;
fps = 0.0f;
ExitRequested = false;
fullScreen = false;
Playing = false;
volume = 128;
ThreadStack = NULL;
PlayThread = LWP_THREAD_NULL;
rendered = false;
gprintf("Opening video '%s'\n", filepath);
string file(filepath);
Video = openVideo(file);
if(!Video)
ReadThread = LWP_THREAD_NULL;
vFile = fopen(filepath, "rb");
if(!vFile)
{
gprintf("Open video failed\n");
ExitRequested = true;
return;
}
SndChannels = (Video->getNumChannels() > 1) ? VOICE_STEREO_16BIT : VOICE_MONO_16BIT;
SndFrequence = Video->getFrequency();
fps = Video->getFps();
maxSoundSize = Video->getMaxAudioSamples()*Video->getNumChannels()*2;
gprintf("Open video succeeded: sound channels: %d, Frequency: %d, FPS: %4.3f\n", SndChannels, SndFrequence, fps);
if(Video->hasSound())
if(Video.Init(vFile) == false)
{
gprintf("Video has sound\n");
soundBuffer = &SoundBuffer;
soundBuffer->Resize(SND_BUFFERS);
soundBuffer->SetBufferBlockSize(maxSoundSize * FRAME_BUFFERS);
}
PlayThreadStack = NULL;
ThreadStack = (u8 *)malloc(32768);
if(!ThreadStack)
gprintf("Memory Allocation failed\n");
ExitRequested = true;
return;
LWP_MutexInit(&mutex, true);
LWP_CreateThread (&ReadThread, UpdateThread, this, ThreadStack, 32768, LWP_PRIO_HIGHEST);
gprintf("Reading frames thread started\n");
}
fps = Video.getFps();
}
WiiMovie::~WiiMovie()
void WiiMovie::DeInit()
{
gprintf("Destructing WiiMovie object\n");
Playing = false;
@ -89,54 +66,41 @@ WiiMovie::~WiiMovie()
Stop();
LWP_ResumeThread(ReadThread);
LWP_JoinThread(ReadThread, NULL);
LWP_MutexDestroy(mutex);
ASND_StopVoice(10);
if(ReadThread != LWP_THREAD_NULL)
{
LWP_ResumeThread(ReadThread);
LWP_JoinThread(ReadThread, NULL);
}
if(mutex != LWP_MUTEX_NULL)
{
LWP_MutexUnlock(mutex);
LWP_MutexDestroy(mutex);
}
if(ThreadStack != NULL)
{
free(ThreadStack);
ThreadStack = NULL;
}
soundBuffer = NULL;
Frames.clear();
if(Video)
closeVideo(Video);
Video.DeInit();
if(vFile != NULL)
fclose(vFile);
vFile = NULL;
}
bool WiiMovie::Play(bool loop)
bool WiiMovie::Play(TexData *Background, bool loop)
{
if(!Video)
if(!vFile)
return false;
ThreadStack = (u8 *)malloc(32768);
if(!ThreadStack)
return false;
gprintf("Start playing video\n");
PlayThreadStack = (u8 *)malloc(32768);
if(PlayThreadStack == NULL)
return false;
Playing = true;
Video.loop = loop;
Frame = Background;
rendered = true;
PlayTime.reset();
Playing = true;
Video->loop = loop;
gprintf("Start playing thread\n");
LWP_ResumeThread(ReadThread);
LWP_CreateThread(&PlayThread, PlayingThread, this, PlayThreadStack, 32768, 70);
LWP_CreateThread (&ReadThread, UpdateThread, this, ThreadStack, 32768, LWP_PRIO_HIGHEST);
gprintf("Reading frames thread started\n");
return true;
}
@ -144,93 +108,6 @@ void WiiMovie::Stop()
{
gprintf("Stopping WiiMovie video\n");
ExitRequested = true;
if(PlayThread != LWP_THREAD_NULL)
LWP_JoinThread(PlayThread, NULL);
PlayThread = LWP_THREAD_NULL;
gprintf("Playing thread stopped\n");
if(PlayThreadStack != NULL)
free(PlayThreadStack);
}
void WiiMovie::SetVolume(int vol)
{
volume = 255 * vol/100;
ASND_ChangeVolumeVoice(10, volume, volume);
}
void WiiMovie::SetScreenSize(int width, int height, int top, int left)
{
screenwidth = width;
screenheight = height;
screenleft = left;
screentop = top;
}
void WiiMovie::SetFullscreen()
{
if(!Video)
return;
float newscale = 1000.0f;
float vidwidth = (float) width * 1.0f;
float vidheight = (float) height * 1.0f;
int retries = 100;
fullScreen = true;
while(vidheight * newscale > screenheight || vidwidth * newscale > screenwidth)
{
if(vidheight * newscale > screenheight)
newscale = screenheight/vidheight;
if(vidwidth * newscale > screenwidth)
newscale = screenwidth/vidwidth;
retries--;
if(retries == 0)
{
newscale = 1.0f;
break;
}
}
scaleX = scaleY = newscale;
}
void WiiMovie::SetFrameSize(int w, int h)
{
if(!Video)
return;
scaleX = (float) w /(float) width;
scaleY = (float) h /(float) height;
}
void WiiMovie::SetAspectRatio(float Aspect)
{
if(!Video)
return;
float vidwidth = (float) height*scaleY*Aspect;
scaleX = (float) width/vidwidth;
}
extern "C" void THPSoundCallback(int voice)
{
if(!soundBuffer || !soundBuffer->IsBufferReady())
return;
if(ASND_AddVoice(voice, soundBuffer->GetBuffer(), soundBuffer->GetBufferSize()) != SND_OK)
return;
soundBuffer->LoadNext();
}
void WiiMovie::FrameLoadLoop()
{
while(!ExitRequested)
{
LoadNextFrame();
while(Frames.size() > FRAME_BUFFERS && !ExitRequested)
usleep(100);
}
}
void * WiiMovie::UpdateThread(void *arg)
@ -239,105 +116,42 @@ void * WiiMovie::UpdateThread(void *arg)
while(!movie->ExitRequested)
{
movie->ReadNextFrame();
if(movie->rendered == true)
movie->LoadNextFrame();
usleep(100);
}
return NULL;
}
void * WiiMovie::PlayingThread(void *arg)
{
WiiMovie *movie = static_cast<WiiMovie *>(arg);
movie->FrameLoadLoop();
return NULL;
}
void WiiMovie::ReadNextFrame()
{
if(!Playing)
LWP_SuspendThread(ReadThread);
u32 FramesNeeded = (u32) (PlayTime.elapsed()*fps);
//gprintf("Reading needed frames: %d\n", FramesNeeded);
while(VideoFrameCount < FramesNeeded)
for(u32 FramesNeeded = (u32)(PlayTime.elapsed()*fps); VideoFrameCount <= FramesNeeded; ++VideoFrameCount)
{
LWP_MutexLock(mutex);
Video->loadNextFrame();
LWP_MutexUnlock(mutex);
++VideoFrameCount;
//gprintf("Loaded video frame: %d\n", VideoFrameCount);
if(Video->hasSound())
{
u32 newWhich = SoundBuffer.Which();
int i = 0;
for(i = 0; i < SoundBuffer.Size()-2; ++i)
{
if(!SoundBuffer.IsBufferReady(newWhich))
break;
newWhich = (newWhich + 1) % SoundBuffer.Size();
}
if(i == SoundBuffer.Size() - 2)
return;
int currentSize = SoundBuffer.GetBufferSize(newWhich);
currentSize += Video->getCurrentBuffer((s16 *) (&SoundBuffer.GetBuffer(newWhich)[currentSize]))*SndChannels*2;
SoundBuffer.SetBufferSize(newWhich, currentSize);
if(currentSize >= (FRAME_BUFFERS-1)*maxSoundSize)
SoundBuffer.SetBufferReady(newWhich, true);
if(ASND_StatusVoice(10) == SND_UNUSED && SoundBuffer.IsBufferReady())
{
ASND_StopVoice(10);
ASND_SetVoice(10, SndChannels, SndFrequence, 0, SoundBuffer.GetBuffer(), SoundBuffer.GetBufferSize(), volume, volume, THPSoundCallback);
SoundBuffer.LoadNext();
}
}
if(VideoFrameCount == FramesNeeded)
Playing = Video.loadNextFrame();
else
Video.loadNextFrame(true);
}
}
void WiiMovie::LoadNextFrame()
{
if(!Video || !Playing)
if(!vFile || !Playing)
return;
VideoFrame VideoF;
LWP_MutexLock(mutex);
Video->getCurrentFrame(VideoF);
LWP_MutexUnlock(mutex);
Video.getCurrentFrame(VideoF);
if(!VideoF.getData())
return;
if(width != VideoF.getWidth())
{
width = VideoF.getWidth();
height = VideoF.getHeight();
if(fullScreen)
SetFullscreen();
else
{
// Calculate new top and left
screenleft = (screenwidth - width) / 2;
screentop = (screenheight - height) / 2;
}
}
TexData frame;
if(TexHandle.fromTHP(frame, VideoF.getData(), VideoF.getWidth(), VideoF.getHeight()) == TE_OK)
Frames.push_back(frame);
if(TexHandle.fromTHP(Frame, VideoF.getData(), VideoF.getWidth(), VideoF.getHeight()) == TE_OK)
rendered = false;
VideoF.dealloc();
}
bool WiiMovie::GetNextFrame(TexData *tex)
bool WiiMovie::Continue()
{
if(!Video || !Playing || Frames.size() == 0)
if(!vFile || !Playing || Frame->data == NULL)
return false;
*tex = Frames.at(0);
Frames.erase(Frames.begin());
return true;
}

View File

@ -4,58 +4,38 @@
#include "gcvid.h"
#include "Timer.h"
#include "texture.hpp"
#include "music/BufferCircle.hpp"
using namespace std;
class WiiMovie
{
public:
WiiMovie(const char * filepath);
~WiiMovie();
bool Play(bool loop = false);
void Init(const char * filepath);
void DeInit();
bool Play(TexData *Background, bool loop = false);
void Stop();
void SetVolume(int vol);
void SetScreenSize(int width, int height, int top, int left);
void SetFullscreen();
void SetFrameSize(int w, int h);
void SetAspectRatio(float Aspect);
bool GetNextFrame(TexData *tex);
bool Continue();
volatile bool loaded;
volatile bool rendered;
protected:
static void * UpdateThread(void *arg);
static void * PlayingThread(void *arg);
void FrameLoadLoop();
void ReadNextFrame();
void LoadNextFrame();
u8 * ThreadStack;
u8 * PlayThreadStack;
lwp_t ReadThread;
lwp_t PlayThread;
mutex_t mutex;
VideoFile *Video;
BufferCircle SoundBuffer;
ThpVideoFile Video;
FILE *vFile;
float fps;
Timer PlayTime;
u32 VideoFrameCount;
vector<TexData> Frames;
TexData *Frame;
bool Playing;
bool ExitRequested;
bool fullScreen;
int maxSoundSize;
int SndChannels;
int SndFrequence;
int volume;
int screentop;
int screenleft;
int screenwidth;
int screenheight;
float scaleX;
float scaleY;
int width;
int height;
};
extern WiiMovie movie;
#endif

View File

@ -272,7 +272,7 @@ void VideoFrame::resize(int width, int height)
_p = 3*width;
_p += (4 - _p%4)%4;
_data = (u8 *)malloc(_p * _h);
_data = (u8 *)MEM2_alloc(_p * _h);
}
int VideoFrame::getWidth() const
@ -400,17 +400,17 @@ void VideoFile::loadFrame(VideoFrame& frame, const u8* data, int size) const
decodeJpeg(data, size, frame);
}
ThpVideoFile::ThpVideoFile(FILE* f)
: VideoFile(f)
bool ThpVideoFile::Init(FILE *f)
{
readThpHeader(f, _head);
_f = f;
loop = false;
readThpHeader(_f, _head);
//this is just to find files that have this field != 0, i
//have no such a file
assert(_head.offsetsDataOffset == 0);
readThpComponents(f, _components);
readThpComponents(_f, _components);
for(u32 i = 0; i < _components.numComponents; ++i)
{
if(_components.componentTypes[i] == 0) //video
@ -429,8 +429,18 @@ ThpVideoFile::ThpVideoFile(FILE* f)
_currFrameNr = -1;
_nextFrameOffset = _head.firstFrameOffset;
_nextFrameSize = _head.firstFrameSize;
_currFrameData.resize(_head.maxBufferSize); //include some padding
_currFrameData = (u8*)MEM2_alloc(_head.maxBufferSize); //include some padding
if(_currFrameData == NULL)
return false;
loadNextFrame();
return true;
}
void ThpVideoFile::DeInit()
{
if(_currFrameData != NULL)
free(_currFrameData);
_currFrameData = NULL;
}
int ThpVideoFile::getWidth() const
@ -448,7 +458,7 @@ int ThpVideoFile::getFrameCount() const
int ThpVideoFile::getCurrentFrameNr() const
{ return _currFrameNr; }
bool ThpVideoFile::loadNextFrame()
bool ThpVideoFile::loadNextFrame(bool skip)
{
++_currFrameNr;
if(_currFrameNr >= (int) _head.numFrames)
@ -462,17 +472,17 @@ bool ThpVideoFile::loadNextFrame()
}
fseek(_f, _nextFrameOffset, SEEK_SET);
fread(&_currFrameData[0], 1, _nextFrameSize, _f);
fread(_currFrameData, 1, (skip ? 4 : _nextFrameSize), _f);
_nextFrameOffset += _nextFrameSize;
_nextFrameSize = *(u32*)&_currFrameData[0];
_nextFrameSize = *(u32*)_currFrameData;
return true;
}
void ThpVideoFile::getCurrentFrame(VideoFrame& f) const
{
int size = *(u32*)(&_currFrameData[0] + 8);
loadFrame(f, &_currFrameData[0] + 4*_numInts, size);
int size = *(u32*)(_currFrameData + 8);
loadFrame(f, _currFrameData + 4 * _numInts, size);
}
bool ThpVideoFile::hasSound() const
@ -502,8 +512,8 @@ int ThpVideoFile::getCurrentBuffer(s16* data) const
if(!hasSound())
return 0;
int jpegSize = *(u32*)(&_currFrameData[0] + 8);
const u8* src = &_currFrameData[0] + _numInts*4 + jpegSize;
int jpegSize = *(u32*)(_currFrameData + 8);
const u8* src = _currFrameData + _numInts*4 + jpegSize;
return thpAudioDecode(data, src, false, _audioInfo.numChannels == 2);
}
@ -542,7 +552,7 @@ int MthVideoFile::getFrameCount() const
int MthVideoFile::getCurrentFrameNr() const
{ return _currFrameNr; }
bool MthVideoFile::loadNextFrame()
bool MthVideoFile::loadNextFrame(bool skip)
{
++_currFrameNr;
if(_currFrameNr >= (int) _head.numFrames)
@ -556,7 +566,7 @@ bool MthVideoFile::loadNextFrame()
fseek(_f, _nextFrameOffset, SEEK_SET);
_currFrameData.resize(_nextFrameSize);
fread(&_currFrameData[0], 1, _nextFrameSize, _f);
fread(&_currFrameData[0], 1, (skip ? 4 : _nextFrameSize), _f);
_thisFrameSize = _nextFrameSize;
u32 nextSize;

View File

@ -227,7 +227,7 @@ class VideoFile
virtual int getFrameCount() const;
virtual int getCurrentFrameNr() const;
virtual bool loadNextFrame() = 0;
virtual bool loadNextFrame(bool skip = false) = 0;
virtual void getCurrentFrame(VideoFrame& frame) const = 0;
@ -255,7 +255,10 @@ void closeVideo(VideoFile*& vf);
class ThpVideoFile : public VideoFile
{
public:
ThpVideoFile(FILE* f);
ThpVideoFile() : VideoFile(NULL) { };
ThpVideoFile(FILE* f) : VideoFile(f) { Init(f); };
bool Init(FILE *f);
void DeInit();
virtual int getWidth() const;
virtual int getHeight() const;
@ -264,7 +267,7 @@ class ThpVideoFile : public VideoFile
virtual int getCurrentFrameNr() const;
virtual bool loadNextFrame();
virtual bool loadNextFrame(bool skip = false);
virtual void getCurrentFrame(VideoFrame& frame) const;
@ -285,7 +288,7 @@ class ThpVideoFile : public VideoFile
int _currFrameNr;
int _nextFrameOffset;
int _nextFrameSize;
vector<u8> _currFrameData;
u8 *_currFrameData;
};
class MthVideoFile : public VideoFile
@ -300,7 +303,7 @@ class MthVideoFile : public VideoFile
virtual int getCurrentFrameNr() const;
virtual bool loadNextFrame();
virtual bool loadNextFrame(bool skip = false);
virtual void getCurrentFrame(VideoFrame& frame) const;
@ -323,7 +326,7 @@ class JpgVideoFile : public VideoFile
virtual int getHeight() const;
virtual int getFrameCount() const;
virtual bool loadNextFrame() { return false; }
virtual bool loadNextFrame(bool skip = false) { return skip; }
virtual void getCurrentFrame(VideoFrame& frame) const;
private:

View File

@ -261,21 +261,24 @@ TexErr STexture::fromImageFile(TexData &dest, const char *filename, u8 f, u32 mi
return result;
}
TexErr STexture::fromTHP(TexData &dest, const u8 *src, u32 w, u32 h)
TexErr STexture::fromTHP(TexData *dest, const u8 *src, u32 w, u32 h)
{
dest.width = w;
dest.height = h;
dest.format = GX_TF_RGBA8;
dest.dataSize = GX_GetTexBufferSize(dest.width, dest.height, dest.format, GX_FALSE, 0);
dest.data = (u8*)MEM2_alloc(dest.dataSize);
if(dest.data == NULL)
if(dest->width != w || dest->height != h || dest->data == NULL)
{
Cleanup(dest);
dest->width = w;
dest->height = h;
dest->format = GX_TF_RGBA8;
dest->dataSize = GX_GetTexBufferSize(dest->width, dest->height, dest->format, GX_FALSE, 0);
dest->data = (u8*)MEM2_alloc(dest->dataSize);
if(dest->data == NULL)
{
Cleanup(*dest);
return TE_NOMEM;
}
for(u32 block = 0; block < dest.height; block += 4)
}
for(u32 block = 0; block < dest->height; block += 4)
{
for(u32 i = 0; i < dest.width; i += 4)
for(u32 i = 0; i < dest->width; i += 4)
{
for(u32 c = 0; c < 4; ++c)
{
@ -283,19 +286,19 @@ TexErr STexture::fromTHP(TexData &dest, const u8 *src, u32 w, u32 h)
{
u32 y = h - 1 - (c + block);
u32 x = argb + i;
u32 src_offset = ((i + argb) + ((block + c) * dest.width)) * 3;
u32 dst_offset = coordsRGBA8(x, y, dest.width);
u32 src_offset = ((i + argb) + ((block + c) * dest->width)) * 3;
u32 dst_offset = coordsRGBA8(x, y, dest->width);
/* Alpha */
dest.data[dst_offset] = 0xFF;
dest->data[dst_offset] = 0xFF;
/* RGB */
dest.data[dst_offset + 1] = src[src_offset];
dest.data[dst_offset + 32] = src[src_offset + 1];
dest.data[dst_offset + 33] = src[src_offset + 2];
dest->data[dst_offset + 1] = src[src_offset];
dest->data[dst_offset + 32] = src[src_offset + 1];
dest->data[dst_offset + 33] = src[src_offset + 2];
}
}
}
}
DCFlushRange(dest.data, dest.dataSize);
DCFlushRange(dest->data, dest->dataSize);
return TE_OK;
}

View File

@ -34,7 +34,7 @@ public:
TexErr fromPNG(TexData &dest, const u8 *buffer, u8 f = -1, u32 minMipSize = 0, u32 maxMipSize = 0, bool reduce_alpha = false);
TexErr fromJPG(TexData &dest, const u8 *buffer, const u32 buffer_size, u8 f = -1, u32 minMipSize = 0, u32 maxMipSize = 0);
/* Just for THP */
TexErr fromTHP(TexData &dest, const u8 *buffer, u32 w, u32 h);
TexErr fromTHP(TexData *dest, const u8 *buffer, u32 w, u32 h);
private:
void _reduceAlpha(TexData &dest, bool reduce_alpha);
void _resize(u8 *dst, u32 dstWidth, u32 dstHeight, const u8 *src, u32 srcWidth, u32 srcHeight);

View File

@ -128,6 +128,7 @@ void writeStub()
DCFlushRange((void*)0x80001800, StubSize);
/* And free the memory again */
if(Stub != stub_bin)
free(Stub);
}

View File

@ -33,14 +33,14 @@ static inline void wbfs_error(const char *x)
static inline void *wbfs_malloc(size_t size)
{
void *p = MEM2_alloc(size);
void *p = MEM2_lo_alloc(size);
if(p) memset(p, 0, size);
return p;
}
static inline void wbfs_free(void *ptr)
{
MEM2_free(ptr);
MEM2_lo_free(ptr);
}
#ifdef __cplusplus

View File

@ -185,13 +185,13 @@ static u32 do_fst(wiidisc_t *d, u8 *fst, const char *names, u32 i)
static void do_files(wiidisc_t*d)
{
u8 *b = wbfs_malloc(0x480); // XXX: determine actual header size
u8 b[0x480]; // XXX: determine actual header size
u32 dol_offset;
u32 fst_offset;
u32 fst_size;
u32 apl_offset;
u32 apl_size;
u8 *apl_header = wbfs_malloc(0x20);
u8 apl_header[0x20];
u8 *fst;
u32 n_files;
partition_read(d, 0, b, 0x480, 0);
@ -215,7 +215,6 @@ static void do_files(wiidisc_t*d)
partition_read(d, fst_offset, fst, fst_size,0);
n_files = _be32(fst + 8);
if (d->extract_pathname && strcmp(d->extract_pathname, "FST") == 0)
{
// if empty pathname requested return fst
@ -227,18 +226,18 @@ static void do_files(wiidisc_t*d)
}
if (12 * n_files <= fst_size)
if (n_files > 1) do_fst(d, fst, (char *)fst + 12 * n_files, 0);
if (n_files > 1)
do_fst(d, fst, (char *)fst + 12 * n_files, 0);
if (fst != d->extracted_buffer) wbfs_free( fst );
if (fst != d->extracted_buffer)
wbfs_free( fst );
}
wbfs_free(b);
wbfs_free(apl_header);
}
static void do_partition(wiidisc_t*d)
{
u8 *tik = wbfs_malloc(0x2a4);
u8 *b = wbfs_malloc(0x1c);
u8 tik[0x2a4];
u8 b[0x1c];
u64 tmd_offset;
u32 tmd_size;
u8 *tmd;
@ -278,8 +277,6 @@ static void do_partition(wiidisc_t*d)
partition_raw_read(d, h3_offset, 0, 0x18000);
wbfs_free(b);
wbfs_free(tik);
wbfs_free(cert);
if(tmd != d->extracted_buffer)
wbfs_free( tmd );
@ -304,21 +301,19 @@ static int test_parition_skip(u32 partition_type, partition_selector_t part_sel)
static void do_disc(wiidisc_t *d)
{
u8 *b = wbfs_malloc(0x100);
if(b == NULL)
goto out;
u8 b[0x100];
u64 partition_offset[32]; // XXX: don't know the real maximum
u64 partition_type[32]; // XXX: don't know the real maximum
u32 n_partitions;
u32 magic;
u32 i;
if(disc_read(d, 0, b, 0x100) < 0)
goto out;
return;
magic = _be32(b + 24);
if (magic != WII_MAGIC)
{
wbfs_error("not a wii disc");
goto out;
return;
}
disc_read(d, 0x40000 >> 2, b, 0x100);
n_partitions = _be32(b);
@ -333,8 +328,6 @@ static void do_disc(wiidisc_t *d)
d->partition_raw_offset = partition_offset[i];
if (!test_parition_skip(partition_type[i], d->part_sel)) do_partition(d);
}
out:
wbfs_free(b);
}
wiidisc_t *wd_open_disc(read_wiidisc_callback_t read, void *fp)

View File

@ -169,9 +169,9 @@ int get_frag_list(u8 *id, char *path, const u32 hdd_sector_size)
bool isWBFS = strrchr(fname,'.') != NULL && strcasecmp(strrchr(fname,'.'), ".wbfs") == 0;
struct stat st;
FragList *fs = MEM1_lo_alloc(sizeof(FragList));
FragList *fa = MEM1_lo_alloc(sizeof(FragList));
FragList *fw = MEM1_lo_alloc(sizeof(FragList));
FragList *fs = MEM2_lo_alloc(sizeof(FragList));
FragList *fa = MEM2_lo_alloc(sizeof(FragList));
FragList *fw = MEM2_lo_alloc(sizeof(FragList));
if(fs == NULL || fa == NULL || fw == NULL)
goto out;
@ -240,7 +240,7 @@ int get_frag_list(u8 *id, char *path, const u32 hdd_sector_size)
frag_concat(fa, fs);
}
frag_list = MEM1_lo_alloc(sizeof(FragList));
frag_list = MEM2_lo_alloc(sizeof(FragList));
if(frag_list == NULL)
goto out;
@ -275,22 +275,22 @@ int get_frag_list(u8 *id, char *path, const u32 hdd_sector_size)
out:
if(ret_val && frag_list != NULL)
{
MEM1_lo_free(frag_list);
MEM2_lo_free(frag_list);
frag_list = NULL;
}
if(fs != NULL)
{
MEM1_lo_free(fs);
MEM2_lo_free(fs);
fs = NULL;
}
if(fa != NULL)
{
MEM1_lo_free(fa);
MEM2_lo_free(fa);
fa = NULL;
}
if(fw != NULL)
{
MEM1_lo_free(fw);
MEM2_lo_free(fw);
fw = NULL;
}
return ret_val;

View File

@ -15,14 +15,19 @@ static const u32 MEM2_PRIORITY_SIZE = 0x1000;
u32 MALLOC_MEM2 = 0;
u8 *MEM1_lo_start = (u8*)0x80004000;
u8 *MEM1_lo_end = (u8*)0x80620000;
u8 *MEM1_lo_list = (u8*)0x93280000;
u8 *MEM1_lo_end = (u8*)0x8061ff00;
u8 *MEM1_lo_list = (u8*)0x932B0000;
u8 *MEM2_start = (u8*)0x90200000;
u8 *MEM2_end = (u8*)0x93200000;
u8 *MEM2_lo_start = (u8*)0x90200000;
u8 *MEM2_lo_end = (u8*)0x905fff00;
u8 *MEM2_lo_list = (u8*)0x932D0000;
u8 *MEM2_start = (u8*)0x90600000;
u8 *MEM2_end = (u8*)0x931fff00;
u8 *MEM2_list = (u8*)0x93200000;
MemManager g_mem1lo;
MemManager g_mem2lo;
MemManager g_mem2gp;
extern "C"
@ -42,7 +47,10 @@ void MEM_init()
g_mem1lo.Init(MEM1_lo_start, MEM1_lo_list, (u32)(MEM1_lo_end-MEM1_lo_start)); //about 6mb
g_mem1lo.ClearMem();
g_mem2gp.Init(MEM2_start, MEM2_list, (u32)(MEM2_end-MEM2_start)); //about 48mb
g_mem2lo.Init(MEM2_lo_start, MEM2_lo_list, (u32)(MEM2_lo_end-MEM2_lo_start)); //about 4mb
g_mem2lo.ClearMem();
g_mem2gp.Init(MEM2_start, MEM2_list, (u32)(MEM2_end-MEM2_start)); //about 44mb
g_mem2gp.ClearMem();
}
@ -92,6 +100,19 @@ unsigned int MEM1_freesize()
}
void MEM2_lo_free(void *p)
{
if(!p)
return;
g_mem2lo.Free(p);
}
void *MEM2_lo_alloc(unsigned int s)
{
return g_mem2lo.Alloc(s);
}
void MEM2_free(void *p)
{
if(!p)
@ -191,10 +212,10 @@ void __wrap_free(void *p)
if(((u32)p & 0x10000000) != 0)
{
//if(p > MEM2_start)
if(p > MEM2_start)
g_mem2gp.Free(p);
//else
//g_mem2lo_gp.Free(p);
else
g_mem2lo.Free(p);
}
else
MEM1_free(p);
@ -237,7 +258,12 @@ void *__wrap_realloc(void *p, size_t size)
size_t __wrap_malloc_usable_size(void *p)
{
if(((u32)p & 0x10000000) != 0)
{
if(p > MEM2_start)
return g_mem2gp.MemBlockSize(p);
else
return g_mem2lo.MemBlockSize(p);
}
return __real_malloc_usable_size(p);
}

View File

@ -19,6 +19,9 @@ void *MEM1_realloc(void *p, unsigned int s);
void MEM1_free(void *p);
unsigned int MEM1_freesize();
void MEM2_lo_free(void *p);
void *MEM2_lo_alloc(unsigned int s);
void MEM2_free(void *p);
void *MEM2_alloc(unsigned int s);
void *MEM2_memalign(unsigned int /* alignment */, unsigned int s);

View File

@ -21,7 +21,7 @@
#include "loader/utils.h"
static mutex_t memMutex = 0;
static const u32 MEM_BLOCK_SIZE = 256;
static const u32 MEM_BLOCK_SIZE = 128;
void MemMutexInit()
{

View File

@ -318,7 +318,7 @@ void CMenu::_showGame(void)
CoverFlow.hideCover();
}
else
_setBg(m_mainBg, m_mainBgLQ);
_setBg(m_gameBg, m_gameBgLQ);
if(!m_zoom_banner)
{
@ -417,36 +417,42 @@ void CMenu::_game(bool launch)
const char *videoPath = fmt("%s/%.3s.thp", m_videoDir.c_str(), CoverFlow.getId());
if(fsop_FileExist(videoPath))
{
MusicPlayer.Stop();
GuiSound OggFile;
m_gameSound.Stop();
MusicPlayer.Stop();
m_banner.SetShowBanner(false);
_hideGame();
/* Set Background empty */
TexData EmptyBG;
_setBg(EmptyBG, EmptyBG);
/* Lets play the movie */
WiiMovie movie(videoPath);
movie.SetScreenSize(m_cfg.getInt("GENERAL", "tv_width", 640), m_cfg.getInt("GENERAL", "tv_height", 480), m_cfg.getInt("GENERAL", "tv_x", 0), m_cfg.getInt("GENERAL", "tv_y", 0));
movie.SetVolume(m_cfg.getInt("GENERAL", "sound_volume_bnr", 255));
movie.Init(videoPath);
OggFile.Load(fmt("%s/%.3s.ogg", m_videoDir.c_str(), CoverFlow.getId()));
OggFile.SetVolume(m_cfg.getInt("GENERAL", "sound_volume_bnr", 255));
m_video_playing = true;
movie.Play();
m_banner.ReSetup_GX();
m_vid.setup2DProjection();
while(!BTN_B_PRESSED && !BTN_A_PRESSED && !BTN_HOME_PRESSED && movie.GetNextFrame(&m_curBg))
OggFile.Play();
movie.Play(&m_curBg);
while(!BTN_B_PRESSED && !BTN_A_PRESSED && !BTN_HOME_PRESSED && movie.Continue() == true)
{
/* Draw movie BG and render */
if(movie.rendered == false)
{
_drawBg();
m_vid.render();
free(m_curBg.data);
movie.rendered = true;
}
/* Check if we want to stop */
WPAD_ScanPads();
PAD_ScanPads();
ButtonsPressed();
}
movie.Stop();
movie.DeInit();
OggFile.FreeMemory();
TexHandle.Cleanup(m_curBg);
/* Finished, so lets re-setup the background */
_setBg(m_mainBg, m_mainBgLQ);
_setBg(m_gameBg, m_gameBgLQ);
_updateBg();
/* Get back into our coverflow */
_showGame();
@ -576,6 +582,7 @@ void CMenu::_game(bool launch)
}
gprintf("Launching game %s\n", hdr->id);
CurrentBanner.ClearBanner();
/* Finally boot it */
_launch(hdr);
@ -633,7 +640,7 @@ void CMenu::_game(bool launch)
m_gameSelected = false;
m_fa.unload();
m_banner.DeleteBanner(true);
_setBg(m_mainBg, m_mainBgLQ);
_setBg(m_gameBg, m_gameBgLQ);
}
if(m_show_zone_game && !m_zoom_banner)
{
@ -1410,11 +1417,6 @@ void CMenu::_launchGame(dir_discHdr *hdr, bool dvd)
else
emulate_mode = 0;
bool patchregion = false;
if(emulate_mode <= 2 && !neek2o() && m_cfg.getBool("GENERAL", "tempregionrn", true))
patchregion = NandHandle.Do_Region_Change(id, true);
bool use_led = m_gcfg2.getBool(id, "led", false);
bool cheat = m_gcfg2.testOptBool(id, "cheat", m_cfg.getBool(WII_DOMAIN, "cheat", false));
debuggerselect = m_gcfg2.getInt(id, "debugger", 0); // debuggerselect is defined in fst.h
@ -1455,6 +1457,13 @@ void CMenu::_launchGame(dir_discHdr *hdr, bool dvd)
m_cfg.save(true);
cleanup(); // wifi and sd gecko doesnt work anymore after cleanup
bool patchregion = false;
if(emulate_mode <= 2 && !neek2o() && m_cfg.getBool("GENERAL", "tempregionrn", false))
{
gprintf("Check\n");
patchregion = NandHandle.Do_Region_Change(id, true);
}
if(ExternalBooter_LoadBooter(fmt("%s/ext_booter.bin", m_binsDir.c_str())) == false)
Sys_Exit();
if((!dvd || neek2o()) && !Sys_DolphinMode())
@ -1600,9 +1609,6 @@ struct IMD5Header
u8 crypto[16];
} ATTRIBUTE_PACKED;
static const u32 BNR_MAX_SIZE = 0x00200000; /* 2MB */
static u8 *BNR_LOC = (u8*)0x90000000;
void CMenu::_gameSoundThread(CMenu *m)
{
m->m_soundThrdBusy = true;
@ -1632,19 +1638,21 @@ void CMenu::_gameSoundThread(CMenu *m)
/* check custom ID6 first */
strncpy(custom_banner, fmt("%s/%s.bnr", m->m_customBnrDir.c_str(), GameHdr->id), 255);
fsop_GetFileSizeBytes(custom_banner, &custom_bnr_size);
if(custom_bnr_size > 0 && custom_bnr_size < BNR_MAX_SIZE)
if(custom_bnr_size > 0)
{
custom_bnr_file = BNR_LOC;
fsop_ReadFileLoc(custom_banner, custom_bnr_size, BNR_LOC);
custom_bnr_file = (u8*)MEM2_lo_alloc(custom_bnr_size);
if(custom_bnr_file != NULL)
fsop_ReadFileLoc(custom_banner, custom_bnr_size, (void*)custom_bnr_file);
}
else /* no custom ID6 or too big, try ID3 */
{
strncpy(custom_banner, fmt("%s/%.3s.bnr", m->m_customBnrDir.c_str(), GameHdr->id), 255);
fsop_GetFileSizeBytes(custom_banner, &custom_bnr_size);
if(custom_bnr_size > 0 && custom_bnr_size < BNR_MAX_SIZE)
if(custom_bnr_size > 0)
{
custom_bnr_file = BNR_LOC;
fsop_ReadFileLoc(custom_banner, custom_bnr_size, BNR_LOC);
custom_bnr_file = (u8*)MEM2_lo_alloc(custom_bnr_size);
if(custom_bnr_file != NULL)
fsop_ReadFileLoc(custom_banner, custom_bnr_size, (void*)custom_bnr_file);
}
}
if(custom_bnr_file == NULL && GameHdr->type == TYPE_GC_GAME)
@ -1667,17 +1675,18 @@ void CMenu::_gameSoundThread(CMenu *m)
{
strncpy(cached_banner, fmt("%s/%s.bnr", m->m_bnrCacheDir.c_str(), GameHdr->id), 255);
fsop_GetFileSizeBytes(cached_banner, &cached_bnr_size);
if(cached_bnr_size > 0 && cached_bnr_size < BNR_MAX_SIZE)
if(cached_bnr_size > 0)
{
cached_bnr_file = BNR_LOC;
fsop_ReadFileLoc(cached_banner, cached_bnr_size, BNR_LOC);
cached_bnr_file = (u8*)MEM2_lo_alloc(cached_bnr_size);
if(cached_bnr_file != NULL)
fsop_ReadFileLoc(cached_banner, cached_bnr_size, (void*)cached_bnr_file);
}
}
if(custom_bnr_file != NULL)
CurrentBanner.SetBanner(custom_bnr_file, custom_bnr_size, true);
CurrentBanner.SetBanner(custom_bnr_file, custom_bnr_size, true, true);
else if(cached_bnr_file != NULL)
CurrentBanner.SetBanner(cached_bnr_file, cached_bnr_size);
CurrentBanner.SetBanner(cached_bnr_file, cached_bnr_size, false, true);
else if(GameHdr->type == TYPE_WII_GAME)
_extractBnr(GameHdr);
else if(GameHdr->type == TYPE_CHANNEL)
@ -1713,7 +1722,6 @@ void CMenu::_gameSoundThread(CMenu *m)
m->m_soundThrdBusy = false;
return;
}
free(soundBin);
}
else
m->m_gameSound.Load(soundBin, sndSize);

View File

@ -60,7 +60,7 @@ start_main:
#endif
m_vid.set2DViewport(m_cfg.getInt("GENERAL", "tv_width", 640), m_cfg.getInt("GENERAL", "tv_height", 480),
m_cfg.getInt("GENERAL", "tv_x", 0), m_cfg.getInt("GENERAL", "tv_y", 0));
_setBg(m_gameBg, m_gameBgLQ);
_setBg(m_mainBg, m_mainBgLQ);
m_btnMgr.show(m_mainBtnInfo);
m_btnMgr.show(m_mainBtnConfig);
m_btnMgr.show(m_mainBtnQuit);
@ -306,7 +306,7 @@ int CMenu::main(void)
}
}
}
gprintf("start\n");
while(!m_exit)
{
/* IMPORTANT check if a disc is inserted */

View File

@ -16,8 +16,8 @@
****************************************************************************/
#include <stdlib.h>
#include <stdio.h>
//#include <memory.h>
#include <malloc.h>
#include <memory/mem2.hpp>
//#include <malloc.h>
#include <string.h>
#include "ash.h"
@ -50,7 +50,7 @@ u8* DecompressAsh( const u8 *stuff, u32 &len )
u32 size = r[5];
//gprintf("Decompressed size: %d\n", size);
u8* buf1 = (u8*)memalign( 32, size );
u8* buf1 = (u8*)MEM2_lo_alloc(size);
if( !buf1 )
{
gprintf( "ASH: no memory\n" );
@ -71,11 +71,11 @@ u8* DecompressAsh( const u8 *stuff, u32 &len )
r[28] = r[28] + 4;
//r[8] = 0x8108<<16;
//HACK, pointer to RAM
u8* workingBuffer = (u8*)memalign( 32, 0x100000 );
u8* workingBuffer = (u8*)MEM2_lo_alloc(0x100000);
if( !workingBuffer )
{
gprintf( "ASH: no memory 2\n" );
free( buf1 );
MEM2_lo_free(buf1);
return NULL;
}
r[8] = (u32)workingBuffer;
@ -448,6 +448,6 @@ loc_81332434:
len = r[3];
//gprintf("Decompressed %d bytes\n", r[3]);
free( workingBuffer );
MEM2_lo_free(workingBuffer);
return buf1;
}

View File

@ -1,9 +1,9 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<app version="4.2">
<app version="4.2.1">
<name> WiiFlow</name>
<coder>OverjoY, FIX94</coder>
<version>4.2</version>
<release_date>20130908000000</release_date>
<version>4.2.1</version>
<release_date>20131231000000</release_date>
<short_description>USB Loader / Nand Emulator</short_description>
<long_description>
WiiFlow is a Wii Game, Channel, Wiiware, Virtual Console, and Savegame Emulator intended for use with legal backups.