not64/main/ROM-Cache-MEM2.c
Extrems 6d9c01a485
2017-10-06 13:35:48 -04:00

142 lines
3.4 KiB
C

/**
* Wii64 - ROM-Cache-MEM2.c (Wii ROM Cache)
* Copyright (C) 2007, 2008, 2009 Mike Slegeir
* Copyright (C) 2007, 2008, 2009 emu_kidid
*
* This is how the ROM should be accessed, this way the ROM doesn't waste RAM
*
* Wii64 homepage: http://www.emulatemii.com
* email address: tehpola@gmail.com
* emukidid@gmail.com
*
*
* This program is free software; you can redistribute it and/
* or modify it under the terms of the GNU General Public Li-
* cence as published by the Free Software Foundation; either
* version 2 of the Licence, or any later version.
*
* This program is distributed in the hope that it will be use-
* ful, but WITHOUT ANY WARRANTY; without even the implied war-
* ranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public Licence for more details.
*
**/
#include <stdio.h>
#include <string.h>
#include "../gc_memory/MEM2.h"
#include "ROM-Cache.h"
#include "rom.h"
#include "gczip.h"
#include "wii_vm.h"
void LoadingBar_showBar(float percent, const char* string);
static char ROMTooBig;
static char ROMCompressed;
static char* ROMBase = ROMCACHE_LO;
void ROMCache_init(fileBrowser_file* file)
{
PKZIPHEADER pkzip;
romFile_readFile(file, &pkzip, sizeof(PKZIPHEADER));
romFile_seekFile(file, 0, FILE_BROWSER_SEEK_SET);
if (pkzip.zipid == PKZIPID) {
rom_length = bswap32(pkzip.uncompressedSize);
inflate_init(&pkzip);
ROMCompressed = 1;
} else {
rom_length = file->size;
ROMCompressed = 0;
}
ROMTooBig = rom_length > ROMCACHE_SIZE;
}
void ROMCache_deinit()
{
if (ROMTooBig) {
ROMBase = ROMCACHE_LO;
VM_Deinit();
}
}
void* ROMCache_pointer(u32 rom_offset)
{
return ROMBase + rom_offset;
}
void ROMCache_read(u8* ram_dest, u32 rom_offset, u32 length)
{
memcpy(ram_dest, ROMBase + rom_offset, length);
}
void ROMCache_write(u8* ram_src, u32 rom_offset, u32 length)
{
memcpy(ROMBase + rom_offset, ram_src, length);
}
int ROMCache_load(fileBrowser_file* file)
{
char txt[128];
int bytes_read;
unsigned i = 0, count = 0;
if (ROMTooBig) {
void* VMBase = VM_Init(rom_length, ROMCACHE_SIZE);
if (VMBase == NULL)
return ROM_CACHE_ERROR_READ;
ROMBase = VMBase;
}
sprintf(txt, "Loading ROM %s into MEM2", ROMTooBig ? "partially" : "fully");
if (ROMCompressed) {
unsigned char buf[ZIPCHUNK];
do {
bytes_read = romFile_readFile(file, buf, ZIPCHUNK);
if (bytes_read < 0)
return ROM_CACHE_ERROR_READ;
bytes_read = inflate_chunk(ROMBase + i, buf, bytes_read);
if (bytes_read < 0)
return ROM_CACHE_ERROR_READ;
if (i == 0 && init_byte_swap(*(u32*)ROMBase) == BYTE_SWAP_BAD) {
romFile_deinit(file);
return ROM_CACHE_INVALID_ROM;
}
byte_swap(ROMBase + (i & ~3), bytes_read + (i & 3));
i += bytes_read;
if (VIDEO_GetRetraceCount() - count > 2) {
LoadingBar_showBar((float)i / rom_length, txt);
count = VIDEO_GetRetraceCount();
}
} while (i < rom_length);
} else {
do {
bytes_read = romFile_readFile(file, ROMBase + i, 32*KB);
if (bytes_read < 0)
return ROM_CACHE_ERROR_READ;
if (i == 0 && init_byte_swap(*(u32*)ROMBase) == BYTE_SWAP_BAD) {
romFile_deinit(file);
return ROM_CACHE_INVALID_ROM;
}
byte_swap(ROMBase + (i & ~3), bytes_read + (i & 3));
i += bytes_read;
if (VIDEO_GetRetraceCount() - count > 2) {
LoadingBar_showBar((float)i / rom_length, txt);
count = VIDEO_GetRetraceCount();
}
} while (i < rom_length);
}
return 0;
}