mirror of
https://github.com/hrydgard/ppsspp.git
synced 2024-10-08 19:43:40 +00:00
add NPUMDIMG support
This commit is contained in:
parent
34da6f983a
commit
c9af16e332
@ -170,6 +170,7 @@
|
||||
<ClCompile Include="FileSystems\DirectoryFileSystem.cpp" />
|
||||
<ClCompile Include="FileSystems\ISOFileSystem.cpp" />
|
||||
<ClCompile Include="FileSystems\MetaFileSystem.cpp" />
|
||||
<ClCompile Include="FileSystems\tlzrc.cpp" />
|
||||
<ClCompile Include="Font\PGF.cpp" />
|
||||
<ClCompile Include="HLE\HLE.cpp" />
|
||||
<ClCompile Include="HLE\HLETables.cpp" />
|
||||
|
@ -407,6 +407,10 @@
|
||||
<ClCompile Include="HLE\sceNp.cpp">
|
||||
<Filter>HLE\Libraries</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="HLE\sceMp3.cpp" />
|
||||
<ClCompile Include="FileSystems\tlzrc.cpp">
|
||||
<Filter>FileSystems</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="ELF\ElfReader.h">
|
||||
@ -752,6 +756,7 @@
|
||||
<ClInclude Include="HLE\sceNp.h">
|
||||
<Filter>HLE\Libraries</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="HLE\sceMp3.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="CMakeLists.txt" />
|
||||
|
@ -15,15 +15,18 @@
|
||||
// Official git repository and contact information can be found at
|
||||
// https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/.
|
||||
|
||||
extern "C"
|
||||
{
|
||||
#include "zlib.h"
|
||||
};
|
||||
|
||||
#include "BlockDevices.h"
|
||||
#include <cstdio>
|
||||
#include <cstring>
|
||||
|
||||
extern "C"
|
||||
{
|
||||
#include "zlib.h"
|
||||
#include "ext/libkirk/amctrl.h"
|
||||
|
||||
};
|
||||
|
||||
BlockDevice *constructBlockDevice(const char *filename) {
|
||||
// Check for CISO
|
||||
FILE *f = fopen(filename, "rb");
|
||||
@ -34,6 +37,8 @@ BlockDevice *constructBlockDevice(const char *filename) {
|
||||
fclose(f);
|
||||
if (!memcmp(buffer, "CISO", 4) && size == 4)
|
||||
return new CISOFileBlockDevice(filename);
|
||||
else if (!memcmp(buffer, "\x00PBP", 4) && size == 4)
|
||||
return new NPDRMDemoBlockDevice(filename);
|
||||
else
|
||||
return new FileBlockDevice(filename);
|
||||
}
|
||||
@ -201,19 +206,143 @@ bool CISOFileBlockDevice::ReadBlock(int blockNumber, u8 *outPtr)
|
||||
}
|
||||
|
||||
|
||||
NPDRMDemoBlockDevice::NPDRMDemoBlockDevice(std::string _filename)
|
||||
: filename_(_filename), pbpReader_(_filename.c_str()) {
|
||||
std::string paramSfo;
|
||||
pbpReader_.GetSubFileAsString(PBP_PARAM_SFO, ¶mSfo);
|
||||
}
|
||||
NPDRMDemoBlockDevice::NPDRMDemoBlockDevice(std::string _filename)
|
||||
: filename_(_filename)
|
||||
{
|
||||
MAC_KEY mkey;
|
||||
CIPHER_KEY ckey;
|
||||
u8 np_header[256];
|
||||
u32 tableOffset, tableSize;
|
||||
u32 lbaStart, lbaEnd;
|
||||
|
||||
NPDRMDemoBlockDevice::~NPDRMDemoBlockDevice() {
|
||||
f = fopen(_filename.c_str(), "rb");
|
||||
|
||||
fseek(f, 0x24, SEEK_SET);
|
||||
fread(&psarOffset, 1, 4, f);
|
||||
fseek(f, psarOffset, SEEK_SET);
|
||||
size_t readSize = fread(&np_header, 1, 256, f);
|
||||
if(readSize!=256){
|
||||
ERROR_LOG(LOADER, "Invalid NPUMDIMG header!");
|
||||
}
|
||||
|
||||
// getkey
|
||||
sceDrmBBMacInit(&mkey, 3);
|
||||
sceDrmBBMacUpdate(&mkey, np_header, 0xc0);
|
||||
bbmac_getkey(&mkey, np_header+0xc0, vkey);
|
||||
|
||||
// decrypt NP header
|
||||
memcpy(hkey, np_header+0xa0, 0x10);
|
||||
sceDrmBBCipherInit(&ckey, 1, 2, hkey, vkey, 0);
|
||||
sceDrmBBCipherUpdate(&ckey, np_header+0x40, 0x60);
|
||||
sceDrmBBCipherFinal(&ckey);
|
||||
|
||||
lbaStart = *(u32*)(np_header+0x54); // LBA start
|
||||
lbaEnd = *(u32*)(np_header+0x64); // LBA end
|
||||
lbaSize = (lbaEnd-lbaStart+1); // LBA size of ISO
|
||||
blockLBAs = *(u32*)(np_header+0x0c); // block size in LBA
|
||||
blockSize = blockLBAs*2048;
|
||||
numBlocks = (lbaSize+blockLBAs-1)/blockLBAs; // total blocks;
|
||||
|
||||
blockBuf = new u8[blockSize];
|
||||
tempBuf = new u8[blockSize];
|
||||
|
||||
tableOffset = *(u32*)(np_header+0x6c); // table offset
|
||||
fseek(f, psarOffset+tableOffset, SEEK_SET);
|
||||
|
||||
tableSize = numBlocks*32;
|
||||
table = new table_info[numBlocks];
|
||||
|
||||
readSize = fread(table, 1, tableSize, f);
|
||||
if(readSize!=tableSize){
|
||||
ERROR_LOG(LOADER, "Invalid NPUMDIMG table!");
|
||||
}
|
||||
|
||||
u32 *p = (u32*)table;
|
||||
u32 i, k0, k1, k2, k3;
|
||||
for(i=0; i<numBlocks; i++){
|
||||
k0 = p[0]^p[1];
|
||||
k1 = p[1]^p[2];
|
||||
k2 = p[0]^p[3];
|
||||
k3 = p[2]^p[3];
|
||||
p[4] ^= k3;
|
||||
p[5] ^= k1;
|
||||
p[6] ^= k2;
|
||||
p[7] ^= k0;
|
||||
p += 8;
|
||||
}
|
||||
|
||||
currentBlock = -1;
|
||||
|
||||
}
|
||||
|
||||
bool NPDRMDemoBlockDevice::ReadBlock(int blockNumber, u8 *outPtr) {
|
||||
// TODO: Fill in decryption code here. Use pbpReader to read the file - might need to
|
||||
// extend its functionality to do it efficiently.
|
||||
|
||||
return false;
|
||||
NPDRMDemoBlockDevice::~NPDRMDemoBlockDevice()
|
||||
{
|
||||
fclose(f);
|
||||
delete [] table;
|
||||
delete [] tempBuf;
|
||||
delete [] blockBuf;
|
||||
}
|
||||
|
||||
int lzrc_decompress(void *out, int out_len, void *in, int in_len);
|
||||
|
||||
bool NPDRMDemoBlockDevice::ReadBlock(int blockNumber, u8 *outPtr)
|
||||
{
|
||||
CIPHER_KEY ckey;
|
||||
int block, lba, lzsize;
|
||||
size_t readSize;
|
||||
u8 *readBuf;
|
||||
|
||||
lba = blockNumber-currentBlock;
|
||||
if(lba>=0 && lba<blockLBAs){
|
||||
memcpy(outPtr, blockBuf+lba*2048, 2048);
|
||||
return true;
|
||||
}
|
||||
|
||||
block = blockNumber/blockLBAs;
|
||||
lba = blockNumber%blockLBAs;
|
||||
currentBlock = block*blockLBAs;
|
||||
|
||||
if(table[block].unk_1c!=0){
|
||||
if(block==(numBlocks-1))
|
||||
return true; // demos make by fake_np
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
fseek(f, psarOffset+table[block].offset, SEEK_SET);
|
||||
|
||||
if(table[block].size<blockSize)
|
||||
readBuf = tempBuf;
|
||||
else
|
||||
readBuf = blockBuf;
|
||||
|
||||
readSize = fread(readBuf, 1, table[block].size, f);
|
||||
if(readSize!=table[block].size){
|
||||
if(block==(numBlocks-1))
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
if((table[block].flag&1)==0){
|
||||
// skip mac check
|
||||
}
|
||||
|
||||
if((table[block].flag&4)==0){
|
||||
sceDrmBBCipherInit(&ckey, 1, 2, hkey, vkey, table[block].offset>>4);
|
||||
sceDrmBBCipherUpdate(&ckey, readBuf, table[block].size);
|
||||
sceDrmBBCipherFinal(&ckey);
|
||||
}
|
||||
|
||||
if(table[block].size<blockSize){
|
||||
lzsize = lzrc_decompress(blockBuf, 0x00100000, readBuf, table[block].size);
|
||||
if(lzsize!=blockSize){
|
||||
ERROR_LOG(LOADER, "LZRC decompress error! lzsize=%d\n", lzsize);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
memcpy(outPtr, blockBuf+lba*2048, 2048);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -73,6 +73,14 @@ private:
|
||||
|
||||
// For encrypted ISOs in PBP files.
|
||||
|
||||
struct table_info {
|
||||
u8 mac[16];
|
||||
u32 offset;
|
||||
int size;
|
||||
int flag;
|
||||
int unk_1c;
|
||||
};
|
||||
|
||||
class NPDRMDemoBlockDevice : public BlockDevice
|
||||
{
|
||||
public:
|
||||
@ -80,14 +88,25 @@ public:
|
||||
~NPDRMDemoBlockDevice();
|
||||
|
||||
bool ReadBlock(int blockNumber, u8 *outPtr);
|
||||
u32 GetNumBlocks() {return (u32)numBlocks_;}
|
||||
u32 GetNumBlocks() {return (u32)lbaSize;}
|
||||
|
||||
private:
|
||||
std::string filename_;
|
||||
PBPReader pbpReader_;
|
||||
FILE *file_;
|
||||
size_t size_;
|
||||
size_t numBlocks_;
|
||||
FILE *f;
|
||||
u32 lbaSize;
|
||||
|
||||
u32 psarOffset;
|
||||
int blockSize;
|
||||
int blockLBAs;
|
||||
u32 numBlocks;
|
||||
|
||||
u8 vkey[16];
|
||||
u8 hkey[16];
|
||||
struct table_info *table;
|
||||
|
||||
int currentBlock;
|
||||
u8 *blockBuf;
|
||||
u8 *tempBuf;
|
||||
};
|
||||
|
||||
|
||||
|
295
Core/FileSystems/tlzrc.cpp
Normal file
295
Core/FileSystems/tlzrc.cpp
Normal file
@ -0,0 +1,295 @@
|
||||
|
||||
// tlzrc.c: LZRC decodeer
|
||||
// based on benhur's code, rewrite by tpu
|
||||
|
||||
// Copyright (c) 2012- PPSSPP Project.
|
||||
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, version 2.0 or later versions.
|
||||
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License 2.0 for more details.
|
||||
|
||||
// A copy of the GPL 2.0 should have been included with the program.
|
||||
// If not, see http://www.gnu.org/licenses/
|
||||
|
||||
// Official git repository and contact information can be found at
|
||||
// https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/.
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <malloc.h>
|
||||
|
||||
#include "Common.h"
|
||||
|
||||
/*************************************************************/
|
||||
|
||||
typedef unsigned int u32;
|
||||
typedef unsigned short u16;
|
||||
typedef unsigned char u8;
|
||||
|
||||
/*************************************************************/
|
||||
|
||||
typedef struct{
|
||||
|
||||
// input stream
|
||||
u8 *input;
|
||||
int in_ptr;
|
||||
int in_len;
|
||||
|
||||
// output stream
|
||||
u8 *output;
|
||||
int out_ptr;
|
||||
int out_len;
|
||||
|
||||
// range decode
|
||||
u32 range;
|
||||
u32 code;
|
||||
u32 out_code;
|
||||
u8 lc;
|
||||
|
||||
u8 bm_literal[8][256];
|
||||
u8 bm_dist_bits[8][39];
|
||||
u8 bm_dist[18][8];
|
||||
u8 bm_match[8][8];
|
||||
u8 bm_len[8][31];
|
||||
}LZRC_DECODE;
|
||||
|
||||
/*************************************************************/
|
||||
|
||||
static u8 rc_getbyte(LZRC_DECODE *rc)
|
||||
{
|
||||
if(rc->in_ptr == rc->in_len){
|
||||
_dbg_assert_msg_(LOADER, false, "LZRC: End of input!");
|
||||
}
|
||||
|
||||
return rc->input[rc->in_ptr++];
|
||||
}
|
||||
|
||||
static void rc_putbyte(LZRC_DECODE *rc, u8 byte)
|
||||
{
|
||||
if(rc->out_ptr == rc->out_len){
|
||||
_dbg_assert_msg_(LOADER, false, "LZRC: Output overflow!");
|
||||
}
|
||||
|
||||
rc->output[rc->out_ptr++] = byte;
|
||||
}
|
||||
|
||||
static void rc_init(LZRC_DECODE *rc, void *out, int out_len, void *in, int in_len)
|
||||
{
|
||||
rc->input = (u8*)in;
|
||||
rc->in_len = in_len;
|
||||
rc->in_ptr = 0;
|
||||
|
||||
rc->output = (u8*)out;
|
||||
rc->out_len = out_len;
|
||||
rc->out_ptr = 0;
|
||||
|
||||
rc->range = 0xffffffff;
|
||||
rc->lc = rc_getbyte(rc);
|
||||
rc->code = (rc_getbyte(rc)<<24) |
|
||||
(rc_getbyte(rc)<<16) |
|
||||
(rc_getbyte(rc)<< 8) |
|
||||
(rc_getbyte(rc)<< 0) ;
|
||||
rc->out_code = 0xffffffff;
|
||||
|
||||
memset(rc->bm_literal, 0x80, 2048);
|
||||
memset(rc->bm_dist_bits, 0x80, 312);
|
||||
memset(rc->bm_dist, 0x80, 144);
|
||||
memset(rc->bm_match, 0x80, 64);
|
||||
memset(rc->bm_len, 0x80, 248);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*************************************************************/
|
||||
|
||||
/* range decode */
|
||||
|
||||
static void normalize(LZRC_DECODE *rc)
|
||||
{
|
||||
if(rc->range<0x01000000){
|
||||
rc->range <<= 8;
|
||||
rc->code = (rc->code<<8)+rc->input[rc->in_ptr];
|
||||
rc->in_ptr++;
|
||||
}
|
||||
}
|
||||
|
||||
/* Decode a bit */
|
||||
static int rc_bit(LZRC_DECODE *rc, u8 *prob)
|
||||
{
|
||||
u32 bound;
|
||||
|
||||
normalize(rc);
|
||||
|
||||
bound = (rc->range>>8)*(*prob);
|
||||
*prob -= *prob>>3;
|
||||
|
||||
if(rc->code < bound){
|
||||
rc->range = bound;
|
||||
*prob += 31;
|
||||
return 1;
|
||||
}else{
|
||||
rc->code -= bound;
|
||||
rc->range -= bound;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* Decode a bittree starting from MSB */
|
||||
static int rc_bittree(LZRC_DECODE *rc, u8 *probs, int limit)
|
||||
{
|
||||
int number = 1;
|
||||
|
||||
do{
|
||||
number = (number<<1)+rc_bit(rc, probs+number);
|
||||
}while(number<limit);
|
||||
|
||||
return number;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* decode a number
|
||||
*
|
||||
* a number are divide into three part:
|
||||
* MSB 2bits
|
||||
* direct bits (don't use probability modle)
|
||||
* LSB 3bits
|
||||
*/
|
||||
static int rc_number(LZRC_DECODE *rc, u8 *prob, int n)
|
||||
{
|
||||
int i, number = 1;
|
||||
|
||||
if(n>3){
|
||||
number = (number<<1)+rc_bit(rc, prob+3);
|
||||
if(n>4){
|
||||
number = (number<<1)+rc_bit(rc, prob+3);
|
||||
if(n>5){
|
||||
// direct bits
|
||||
normalize(rc);
|
||||
|
||||
for(i=0; i<n-5; i++){
|
||||
rc->range >>= 1;
|
||||
number <<= 1;
|
||||
if (rc->code < rc->range){
|
||||
number += 1;
|
||||
}else{
|
||||
rc->code -= rc->range;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(n>0){
|
||||
number = (number<<1)+rc_bit(rc, prob);
|
||||
if(n>1){
|
||||
number = (number<<1)+rc_bit(rc, prob+1);
|
||||
if(n>2){
|
||||
number = (number<<1)+rc_bit(rc, prob+2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return number;
|
||||
}
|
||||
|
||||
|
||||
int lzrc_decompress(void *out, int out_len, void *in, int in_len)
|
||||
{
|
||||
LZRC_DECODE rc;
|
||||
int match_step, rc_state, len_state, dist_state;
|
||||
int i, bit, byte, last_byte;
|
||||
int match_len, len_bits;
|
||||
int match_dist, dist_bits, limit;
|
||||
u8 *match_src;
|
||||
int round = -1;
|
||||
|
||||
rc_init(&rc, out, out_len, in, in_len);
|
||||
|
||||
if(rc.lc&0x80){
|
||||
/* plain text */
|
||||
memcpy(rc.output, rc.input+5, rc.code);
|
||||
return rc.code;
|
||||
}
|
||||
|
||||
rc_state = 0;
|
||||
last_byte = 0;
|
||||
|
||||
|
||||
while (1) {
|
||||
round += 1;
|
||||
match_step = 0;
|
||||
|
||||
bit = rc_bit(&rc, &rc.bm_match[rc_state][match_step]);
|
||||
if (bit==0) {
|
||||
/* 0 -> raw char */
|
||||
if(rc_state>0)
|
||||
rc_state -= 1;
|
||||
|
||||
byte = rc_bittree(&rc, &rc.bm_literal[((last_byte>>rc.lc)&0x07)][0], 0x100);
|
||||
byte -= 0x100;
|
||||
|
||||
rc_putbyte(&rc, byte);
|
||||
} else {
|
||||
/* 1 -> a match */
|
||||
|
||||
/* find bits of match length */
|
||||
len_bits = 0;
|
||||
for(i=0; i<7; i++){
|
||||
match_step += 1;
|
||||
bit = rc_bit(&rc, &rc.bm_match[rc_state][match_step]);
|
||||
if(bit==0)
|
||||
break;
|
||||
len_bits += 1;
|
||||
}
|
||||
|
||||
/* find match length */
|
||||
if(len_bits==0){
|
||||
match_len = 1;
|
||||
}else{
|
||||
len_state = ((len_bits-1)<<2)+((rc.out_ptr<<(len_bits-1))&0x03);
|
||||
match_len = rc_number(&rc, &rc.bm_len[rc_state][len_state], len_bits);
|
||||
if (match_len == 0xFF){
|
||||
//end of stream
|
||||
return rc.out_ptr;
|
||||
}
|
||||
}
|
||||
|
||||
/* find number of bits of match distance */
|
||||
dist_state = 0;
|
||||
limit = 8;
|
||||
if(match_len>2){
|
||||
dist_state += 7;
|
||||
limit = 44;
|
||||
}
|
||||
dist_bits = rc_bittree(&rc, &rc.bm_dist_bits[len_bits][dist_state], limit);
|
||||
dist_bits -= limit;
|
||||
|
||||
/* find match distance */
|
||||
if(dist_bits>0){
|
||||
match_dist = rc_number(&rc, &rc.bm_dist[dist_bits][0], dist_bits);
|
||||
} else {
|
||||
match_dist = 1;
|
||||
}
|
||||
|
||||
/* copy match bytes */
|
||||
if(match_dist>rc.out_ptr || match_dist<0){
|
||||
printf("match_dist out of range! %08x\n", match_dist);
|
||||
return -1;
|
||||
}
|
||||
match_src = rc.output+rc.out_ptr-match_dist;
|
||||
for(i=0; i<match_len+1; i++){
|
||||
rc_putbyte(&rc, *match_src++);
|
||||
}
|
||||
rc_state = 6+((rc.out_ptr+1)&1);
|
||||
}
|
||||
last_byte = rc.output[rc.out_ptr-1];
|
||||
}
|
||||
}
|
@ -37,12 +37,20 @@ EmuFileType Identify_File(const char *filename)
|
||||
return FILETYPE_ERROR;
|
||||
}
|
||||
u32 id;
|
||||
size_t readSize = fread(&id,4,1,f);
|
||||
fclose(f);
|
||||
u32 psar_offset, psar_id;
|
||||
|
||||
size_t readSize = fread(&id,4,1,f);
|
||||
if(readSize != 1)
|
||||
return FILETYPE_ERROR;
|
||||
|
||||
psar_id = 0;
|
||||
fseek(f, 0x24, SEEK_SET);
|
||||
fread(&psar_offset, 4, 1, f);
|
||||
fseek(f, psar_offset, SEEK_SET);
|
||||
fread(&psar_id, 4, 1, f);
|
||||
|
||||
fclose(f);
|
||||
|
||||
if (strlen(filename) < 5) {
|
||||
ERROR_LOG(LOADER, "invalid filename %s", filename);
|
||||
}
|
||||
@ -60,7 +68,10 @@ EmuFileType Identify_File(const char *filename)
|
||||
}
|
||||
else if (id == 'PBP\x00')
|
||||
{
|
||||
return FILETYPE_PSP_PBP;
|
||||
if(psar_id == 'MUPN')
|
||||
return FILETYPE_PSP_ISO_NP;
|
||||
else
|
||||
return FILETYPE_PSP_PBP;
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -101,6 +112,7 @@ bool LoadFile(const char *filename, std::string *error_string)
|
||||
return Load_PSP_ELF_PBP(filename, error_string);
|
||||
}
|
||||
case FILETYPE_PSP_ISO:
|
||||
case FILETYPE_PSP_ISO_NP:
|
||||
pspFileSystem.SetStartingDirectory("disc0:/PSP_GAME/USRDIR");
|
||||
return Load_PSP_ISO(filename, error_string);
|
||||
case FILETYPE_ERROR:
|
||||
|
@ -24,6 +24,7 @@ enum EmuFileType
|
||||
FILETYPE_PSP_PBP,
|
||||
FILETYPE_PSP_ELF,
|
||||
FILETYPE_PSP_ISO,
|
||||
FILETYPE_PSP_ISO_NP,
|
||||
|
||||
FILETYPE_UNKNOWN_BIN,
|
||||
FILETYPE_UNKNOWN_ELF,
|
||||
|
@ -126,47 +126,26 @@ bool Load_PSP_ISO(const char *filename, std::string *error_string)
|
||||
|
||||
bool Load_PSP_ELF_PBP(const char *filename, std::string *error_string)
|
||||
{
|
||||
// Figure out if this is a "DEMO" PBP. In that case we want to mount it
|
||||
// on UMD0:.
|
||||
PBPReader reader(filename);
|
||||
// This is really just for headless, might need tweaking later.
|
||||
if (!PSP_CoreParameter().mountIso.empty())
|
||||
{
|
||||
ISOFileSystem *umd2 = new ISOFileSystem(&pspFileSystem, constructBlockDevice(PSP_CoreParameter().mountIso.c_str()));
|
||||
|
||||
// Hacky check, should find something better
|
||||
if (reader.IsValid() && reader.GetSubFileSize(PBP_UNKNOWN_PSAR) > 0x100000) {
|
||||
// Yay, got a demo.
|
||||
ISOFileSystem *umd0 = new ISOFileSystem(&pspFileSystem, new NPDRMDemoBlockDevice(filename));
|
||||
|
||||
pspFileSystem.Mount("umd1:", umd0);
|
||||
pspFileSystem.Mount("disc0:", umd0);
|
||||
pspFileSystem.Mount("umd:", umd0);
|
||||
pspFileSystem.Mount("umd0:", umd0);
|
||||
pspFileSystem.Mount("umd1:", umd2);
|
||||
pspFileSystem.Mount("disc0:", umd2);
|
||||
pspFileSystem.Mount("umd:", umd2);
|
||||
}
|
||||
|
||||
std::string bootpath = "disc0:/PSP_GAME/SYSDIR/EBOOT.BIN";
|
||||
INFO_LOG(LOADER,"Loading %s from demo iso...", bootpath.c_str());
|
||||
return __KernelLoadExec(bootpath.c_str(), 0, error_string);
|
||||
} else {
|
||||
// Classic homebrew PBP.
|
||||
|
||||
// This is really just for headless, might need tweaking later.
|
||||
if (!PSP_CoreParameter().mountIso.empty())
|
||||
{
|
||||
ISOFileSystem *umd2 = new ISOFileSystem(&pspFileSystem, constructBlockDevice(PSP_CoreParameter().mountIso.c_str()));
|
||||
|
||||
pspFileSystem.Mount("umd1:", umd2);
|
||||
pspFileSystem.Mount("disc0:", umd2);
|
||||
pspFileSystem.Mount("umd:", umd2);
|
||||
}
|
||||
|
||||
std::string full_path = filename;
|
||||
std::string path, file, extension;
|
||||
SplitPath(ReplaceAll(full_path, "\\", "/"), &path, &file, &extension);
|
||||
std::string full_path = filename;
|
||||
std::string path, file, extension;
|
||||
SplitPath(ReplaceAll(full_path, "\\", "/"), &path, &file, &extension);
|
||||
#ifdef _WIN32
|
||||
path = ReplaceAll(path, "/", "\\");
|
||||
path = ReplaceAll(path, "/", "\\");
|
||||
#endif
|
||||
|
||||
DirectoryFileSystem *fs = new DirectoryFileSystem(&pspFileSystem, path);
|
||||
pspFileSystem.Mount("umd0:", fs);
|
||||
DirectoryFileSystem *fs = new DirectoryFileSystem(&pspFileSystem, path);
|
||||
pspFileSystem.Mount("umd0:", fs);
|
||||
|
||||
std::string finalName = "umd0:/" + file + extension;
|
||||
return __KernelLoadExec(finalName.c_str(), 0, error_string);
|
||||
}
|
||||
std::string finalName = "umd0:/" + file + extension;
|
||||
return __KernelLoadExec(finalName.c_str(), 0, error_string);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user