// returns handle pointer PreFile::FileHandle *PreFile::GetContainedFile(const char *pName) { _File *pFile = mp_table->GetItem(pName, false); if (!pFile) return NULL; PreFile::FileHandle *pHandle = pFile; //// kinda roundabout, but sets mp_activeFile GetContainedFileByHandle(pHandle); #ifdef __PLAT_NGC__ NsDisplay::doReset(); #endif // __PLAT_NGC__ // do we need to fetch file data? if (!mp_activeFile->pData) { if (mp_activeFile->compressedDataSize) { Mem::PushMemProfile((char*)pName); if (m_use_bottom_up_heap) { mp_activeFile->pData = new (Mem::Manager::sHandle().BottomUpHeap()) uint8[mp_activeFile->m_filesize]; } else { mp_activeFile->pData = new (Mem::Manager::sHandle().TopDownHeap()) uint8[mp_activeFile->m_filesize]; } Mem::PopMemProfile(); // need to uncompress data DecodeLZSS(mp_activeFile->pCompressedData, mp_activeFile->pData, mp_activeFile->compressedDataSize); } #ifdef __PRE_ARAM__ else { // Just DMA to main RAM. Mem::PushMemProfile((char*)pName); if (m_use_bottom_up_heap) { mp_activeFile->pData = new (Mem::Manager::sHandle().BottomUpHeap()) uint8[mp_activeFile->m_filesize]; } else { mp_activeFile->pData = new (Mem::Manager::sHandle().TopDownHeap()) uint8[mp_activeFile->m_filesize]; } Mem::PopMemProfile(); NsDMA::toMRAM( mp_activeFile->pData, (uint32)mp_activeFile->pCompressedData, mp_activeFile->m_filesize ); } #endif // __PRE_ARAM__ } return pHandle; }
// allocate memory and load file directly from a pre file, if it is there // This avoids the problem of having to have the decompressed file in memory twice // when we are loading directly, like with Pip::Load() // using this enables us to actually load network game, where there is 1MB less heap during loading // // returns a pointer to the file in memory // or NULL if the file is not in this pre file. // optional parameter p_dest, if set to anything other then NULL, then load file to this destination void *PreFile::LoadContainedFile(const char *pName,int *p_size, void *p_dest) { // printf ("LoadContainedFile(%s\n",pName); _File *pFile = mp_table->GetItem(pName, false); if (!pFile) { return NULL; } *p_size = pFile->m_filesize; // If destination was passed as NULL, then allocate memory if (!p_dest) { p_dest = Mem::Malloc(pFile->m_filesize); } // do we need to deompress file data? if (!pFile->pData) { if (pFile->compressedDataSize) { // need to uncompress data //DecodeLZSS(mp_activeFile->pCompressedData, mp_activeFile->pData, mp_activeFile->compressedDataSize); DecodeLZSS(pFile->pCompressedData, (uint8*)p_dest, pFile->compressedDataSize); } else { #ifdef __PRE_ARAM__ // Just DMA to main RAM. NsDMA::toMRAM( p_dest, (uint32)pFile->pCompressedData, pFile->m_filesize ); #else memcpy(p_dest,(void*)pFile->pCompressedData,pFile->m_filesize); #endif // __PRE_ARAM__ } } else { // printf ("Copying %d bytes from %p to %p\n",pFile->sky.SOF,p_dest,(void*)pFile->pData); memcpy(p_dest,(void*)pFile->pData,pFile->m_filesize); } return p_dest; }
uint8 *CScriptCache::GetScript(uint32 scriptName) { CSymbolTableEntry *p_entry=Resolve(scriptName); if (p_entry) { Dbg_MsgAssert(p_entry->mType==ESYMBOLTYPE_QSCRIPT,("Symbol %s is not a QScript",FindChecksumName(scriptName))); #ifndef __PLAT_NGC__ Dbg_MsgAssert(p_entry->mpScript,("NULL p_entry->mpScript")); #endif // __PLAT_NGC__ // Change the passed scriptName to be the actual scriptName so that when decompressed it gets registered in // the cache under the correct name. // Otherwise, if a SpawnScript Foo is done after Foo has been changed using the 'change' command, it // will spawn the old script again, since it will be in the cache under Foo. scriptName=p_entry->mNameChecksum; } CScriptCacheEntry *p_cache_entry=mp_cache_hash_table->GetItem(scriptName); if (p_cache_entry) { ++p_cache_entry->mUsage; #ifdef __NOPT_ASSERT__ if (p_cache_entry->mUsage==1) { ++m_num_used_scripts; if (m_num_used_scripts > m_max_used_scripts) { m_max_used_scripts=m_num_used_scripts; } } #endif remove_from_zero_usage_list(p_cache_entry); return p_cache_entry->mpDecompressedScript; } if (p_entry) { #ifdef __PLAT_NGC__ enum { COMPRESS_BUFFER_SIZE=20000, }; uint8 p_compress_buffer[COMPRESS_BUFFER_SIZE]; uint32 header[(SCRIPT_HEADER_SIZE/4)]; NsDMA::toMRAM( header, p_entry->mScriptOffset, SCRIPT_HEADER_SIZE ); uint32 uncompressed_size = header[1]; uint32 compressed_size = header[2]; NsDMA::toMRAM( p_compress_buffer, p_entry->mScriptOffset + SCRIPT_HEADER_SIZE, compressed_size ); #else // Note: The script contents checksum is at offset 0, but it is not needed. uint32 uncompressed_size = *(uint32*)(p_entry->mpScript+4); uint32 compressed_size = *(uint32*)(p_entry->mpScript+8); #endif // __PLAT_NGC__ remove_some_old_scripts(uncompressed_size,scriptName); CScriptCacheEntry *p_cache_entry=new CScriptCacheEntry; Mem::Manager::sHandle().PushContext(Mem::Manager::sHandle().ScriptHeap()); uint8 *p_new_script=(uint8*)Mem::Malloc(uncompressed_size); Mem::Manager::sHandle().PopContext(); if (uncompressed_size > compressed_size) { #ifdef __NOPT_ASSERT__ uint8 *p_end= #endif #ifdef __PLAT_NGC__ DecodeLZSS(p_compress_buffer,p_new_script,compressed_size); #else DecodeLZSS(p_entry->mpScript+SCRIPT_HEADER_SIZE,p_new_script,compressed_size); #endif // __PLAT_NGC__ Dbg_MsgAssert(p_end==p_new_script+uncompressed_size,("Eh? p_end is not right?")); } else { // The script is uncompressed so just copy it over. Saves, errr, 1K altogether, oh well. Dbg_MsgAssert(uncompressed_size == compressed_size,("Expected uncompressed_size==compressed_size")); #ifdef __PLAT_NGC__ uint8 *p_source=p_compress_buffer; #else uint8 *p_source=p_entry->mpScript+SCRIPT_HEADER_SIZE; #endif // __PLAT_NGC__ uint8 *p_dest=p_new_script; for (uint32 i=0; i<uncompressed_size; ++i) { *p_dest++=*p_source++; } } PreProcessScript(p_new_script); p_cache_entry->mpDecompressedScript=p_new_script; p_cache_entry->mUsage=1; p_cache_entry->mScriptNameChecksum=scriptName; #ifdef __NOPT_ASSERT__ ++m_num_used_scripts; if (m_num_used_scripts > m_max_used_scripts) { m_max_used_scripts=m_num_used_scripts; } #endif mp_cache_hash_table->PutItem(scriptName,p_cache_entry); #ifdef __NOPT_ASSERT__ ++mp_decompress_counts[m_current_decompress_count_index]; #endif return p_cache_entry->mpDecompressedScript; } return NULL; }
/**************************************************************************** * Function : main * Description: This is the main function for this program, it validates * the command line input and, if valid, it will either * encode a file using the LZSS algorithm or decode a * file encoded with the LZSS algorithm. * Parameters : argc - number of parameters * argv - parameter list * Effects : Encodes/Decodes input file * Returned : 0 for success, -1 for failure. errno will be set in the * event of a failure. ****************************************************************************/ int main(int argc, char *argv[]) { option_t *optList; option_t *thisOpt; FILE *fpIn; /* pointer to open input file */ FILE *fpOut; /* pointer to open output file */ modes_t mode; /* initialize data */ fpIn = NULL; fpOut = NULL; mode = ENCODE; /* parse command line */ optList = GetOptList(argc, argv, "cdi:o:h?"); thisOpt = optList; while (thisOpt != NULL) { switch(thisOpt->option) { case 'c': /* compression mode */ mode = ENCODE; break; case 'd': /* decompression mode */ mode = DECODE; break; case 'i': /* input file name */ if (fpIn != NULL) { fprintf(stderr, "Multiple input files not allowed.\n"); fclose(fpIn); if (fpOut != NULL) { fclose(fpOut); } FreeOptList(optList); return -1; } /* open input file as binary */ fpIn = fopen(thisOpt->argument, "rb"); if (fpIn == NULL) { perror("Opening input file"); if (fpOut != NULL) { fclose(fpOut); } FreeOptList(optList); return -1; } break; case 'o': /* output file name */ if (fpOut != NULL) { fprintf(stderr, "Multiple output files not allowed.\n"); fclose(fpOut); if (fpIn != NULL) { fclose(fpIn); } FreeOptList(optList); return -1; } /* open output file as binary */ fpOut = fopen(thisOpt->argument, "wb"); if (fpOut == NULL) { perror("Opening output file"); if (fpIn != NULL) { fclose(fpIn); } FreeOptList(optList); return -1; } break; case 'h': case '?': printf("Usage: %s <options>\n\n", FindFileName(argv[0])); printf("options:\n"); printf(" -c : Encode input file to output file.\n"); printf(" -d : Decode input file to output file.\n"); printf(" -i <filename> : Name of input file.\n"); printf(" -o <filename> : Name of output file.\n"); printf(" -h | ? : Print out command line options.\n\n"); printf("Default: %s -c -i stdin -o stdout\n", FindFileName(argv[0])); FreeOptList(optList); return 0; } optList = thisOpt->next; free(thisOpt); thisOpt = optList; } /* use stdin/out if no files are provided */ if (fpIn == NULL) { fpIn = stdin; } if (fpOut == NULL) { fpOut = stdout; } /* we have valid parameters encode or decode */ if (mode == ENCODE) { EncodeLZSS(fpIn, fpOut); } else { DecodeLZSS(fpIn, fpOut); } /* remember to close files */ fclose(fpIn); fclose(fpOut); return 0; }