void BuildSaveListNand() { for( u32 j = 0; j < 3; j++ ) { u32 type; switch( j ) { case 0: type = 0x10000; break; case 1: type = 0x10001; break; case 2: type = 0x10004; break; } u32 cnt = NandTitles.SetType( type ); for( u32 i = 0; i < cnt; i++ ) { u64 tid = NandTitles.Next(); char pathBuf[ 65 ]__attribute__((aligned( 32 ))); snprintf( pathBuf, sizeof( pathBuf ), "/title/%08x/%08x/data/banner.bin", TITLE_UPPER( tid ), TITLE_LOWER( tid ) ); u8* buf; u32 len; int ret = -1234; if( ( ret = NandTitle::LoadFileFromNand( pathBuf, &buf, &len ) ) < 0 || !buf ) { //gprintf( "error loading: \"%s\" %i %p\n", pathBuf, ret, buf ); continue; } //gprintf( "load %016llx\n", tid ); BannerBin *save = new BannerBin( NULL, 0, tid ); if( !save->SetData( buf, len ) ) { gprintf( "error creating save: \"%s\"\n", pathBuf ); delete save; continue; } // get size u32 s1 = 0, s2 = 0; snprintf( pathBuf, sizeof( pathBuf ), "/title/%08x/%08x/data", TITLE_UPPER( tid ), TITLE_LOWER( tid ) ); if( !(ret = ISFS_GetUsage( pathBuf, &s1, &s2 )) ) { save->blocks = RU( s1, 8 ) / 8; } else { gprintf( "ISFS_GetUsage( \"%s\" ): %i\n", pathBuf, ret ); save->blocks = 0; } save->tid = tid; saveList << save; //return; } } }
double sin_wave( double d, MyState *s ) { double r=0; double i = 2*3.14/S_SIZE; int v = (int) RU(d/i)%S_SIZE; r = s->wave[v]; return r; }
Vec3f MeshCutting::getCenterBox(arrayInt voxelIdxs) { std::vector<voxelBox> * boxes = &s_voxelObj->m_boxes; // Get current bounding box Vec3f LD(MAX, MAX, MAX); Vec3f RU(MIN, MIN, MIN); Box b(LD, RU); for (int i = 0; i < voxelIdxs.size(); i++) { voxelBox curB = boxes->at(voxelIdxs[i]); b = combineBox(b, Box(curB.leftDown, curB.rightUp)); } return (b.leftDown + b.rightUp)/2.0; }
void BuildSaveListSD() { DirList dir( "sd:/private/wii/title", NULL, DirList::Dirs ); int cnt = dir.GetFilecount(); for( int i = 0; i < cnt; i++ ) { // check for data.bin char path[ 65 ]; snprintf( path, sizeof( path ), "%s/data.bin", dir.GetFilepath( i ) ); FILE *f = fopen( path, "rb" ); if( !f ) { //gprintf( "no data.bin\n" ); continue; } u32 len; u64 tid; u32 installedBytes; u8* bannerData = DataBin::GetSaveBanner( f, len, tid, installedBytes ); fclose( f ); if( !bannerData ) { continue; } BannerBin *save = new BannerBin( NULL, 0, tid ); if( !save->SetData( bannerData, len ) ) { gprintf( "error creating save: \"%s\"\n", path ); delete save; continue; } #define KiB ( 1024 ) #define MiB ( KiB * 1024 ) #define BLOCK ( MiB / 8 ) save->blocks = RU( installedBytes, BLOCK ) / BLOCK; save->tid = tid; saveList << save; } }
u8 *Alloc( u32 bytes, u32* off ) { if( !Lock() ) return NULL; sysMutexLock( rsxMutex, 0 ); //align bytes = RU( bytes, 4 ); //printf("ptrs.size(): %i\n", (int)ptrs.size() ); //find the first available chunk of memory big enough u32 offset = 0; u32 i = 0; vector<MemItr>::iterator ptr = ptrs.begin(); while( ptr < ptrs.end() ) { //if there is another chunk of allocated memory after this one, check the space between them if( i + 1 < ptrs.size() ) { if( ( ptrs.at( i + 1 ).start - (*ptr).end ) >= bytes ) { //printf("%08x - %08x >= %08x 2\n", ptrs.at( i + 1 ).start, (*ptr).end, bytes ); offset = ptrs.at( i ).end; i++; break; } } //if this is the last texture else if( i == ptrs.size() - 1 ) { if( ( memSize - (*ptr).end ) >= bytes ) { //printf("%08x - %08x >= %08x 1\n", memSize, (*ptr).end, bytes ); offset = (*ptr).end; i++; } else { printf("RsxMem::Alloc() :didnt find enough free space for %08x\n", bytes ); UnLock(); return NULL; } break; } ++ptr; ++i; } MemItr newPtr; newPtr.start = offset; newPtr.end = offset + bytes; ptrs.insert( ptrs.begin() + i, newPtr ); //printf("inserting new chunk in list @ %u\n", i ); if( off ) { *off = tiny3d_TextureOffset( (u8*)memStart + offset ); } u8 *ret = ((u8*)memStart) + offset; UnLock(); return ret; }
void mul(zz_pX& U, zz_pX& V, const zz_pXMatrix& M) // (U, V)^T = M*(U, V)^T { long d = deg(U) - deg(M(1,1)); long k = NextPowerOfTwo(d - 1); // When the GCD algorithm is run on polynomials of degree n, n-1, // where n is a power of two, then d-1 is likely to be a power of two. // It would be more natural to set k = NextPowerOfTwo(d+1), but this // would be much less efficient in this case. long n = (1L << k); long xx; zz_p a0, a1, b0, b1, c0, d0, u0, u1, v0, v1, nu0, nu1, nv0; zz_p t1, t2; if (n == d-1) xx = 1; else if (n == d) xx = 2; else xx = 3; switch (xx) { case 1: GetCoeff(a0, M(0,0), 0); GetCoeff(a1, M(0,0), 1); GetCoeff(b0, M(0,1), 0); GetCoeff(b1, M(0,1), 1); GetCoeff(c0, M(1,0), 0); GetCoeff(d0, M(1,1), 0); GetCoeff(u0, U, 0); GetCoeff(u1, U, 1); GetCoeff(v0, V, 0); GetCoeff(v1, V, 1); mul(t1, (a0), (u0)); mul(t2, (b0), (v0)); add(t1, t1, t2); nu0 = t1; mul(t1, (a1), (u0)); mul(t2, (a0), (u1)); add(t1, t1, t2); mul(t2, (b1), (v0)); add(t1, t1, t2); mul(t2, (b0), (v1)); add(t1, t1, t2); nu1 = t1; mul(t1, (c0), (u0)); mul(t2, (d0), (v0)); add (t1, t1, t2); nv0 = t1; break; case 2: GetCoeff(a0, M(0,0), 0); GetCoeff(b0, M(0,1), 0); GetCoeff(u0, U, 0); GetCoeff(v0, V, 0); mul(t1, (a0), (u0)); mul(t2, (b0), (v0)); add(t1, t1, t2); nu0 = t1; break; case 3: break; } fftRep RU(INIT_SIZE, k), RV(INIT_SIZE, k), R1(INIT_SIZE, k), R2(INIT_SIZE, k); TofftRep(RU, U, k); TofftRep(RV, V, k); TofftRep(R1, M(0,0), k); mul(R1, R1, RU); TofftRep(R2, M(0,1), k); mul(R2, R2, RV); add(R1, R1, R2); FromfftRep(U, R1, 0, d); TofftRep(R1, M(1,0), k); mul(R1, R1, RU); TofftRep(R2, M(1,1), k); mul(R2, R2, RV); add(R1, R1, R2); FromfftRep(V, R1, 0, d-1); // now fix-up results switch (xx) { case 1: GetCoeff(u0, U, 0); sub(u0, u0, nu0); SetCoeff(U, d-1, u0); SetCoeff(U, 0, nu0); GetCoeff(u1, U, 1); sub(u1, u1, nu1); SetCoeff(U, d, u1); SetCoeff(U, 1, nu1); GetCoeff(v0, V, 0); sub(v0, v0, nv0); SetCoeff(V, d-1, v0); SetCoeff(V, 0, nv0); break; case 2: GetCoeff(u0, U, 0); sub(u0, u0, nu0); SetCoeff(U, d, u0); SetCoeff(U, 0, nu0); break; } }
void mul(ZZ_pX& U, ZZ_pX& V, const ZZ_pXMatrix& M) // (U, V)^T = M*(U, V)^T { long d = deg(U) - deg(M(1,1)); long k = NextPowerOfTwo(d - 1); // When the GCD algorithm is run on polynomials of degree n, n-1, // where n is a power of two, then d-1 is likely to be a power of two. // It would be more natural to set k = NextPowerOfTwo(d+1), but this // would be much less efficient in this case. // We optimize this case, as it does sometimes arise naturally // in some situations. long n = (1L << k); long xx; ZZ_p a0, a1, b0, b1, c0, d0, u0, u1, v0, v1, nu0, nu1, nv0; NTL_ZZRegister(t1); NTL_ZZRegister(t2); if (n == d-1) xx = 1; else if (n == d) xx = 2; else xx = 3; switch (xx) { case 1: GetCoeff(a0, M(0,0), 0); GetCoeff(a1, M(0,0), 1); GetCoeff(b0, M(0,1), 0); GetCoeff(b1, M(0,1), 1); GetCoeff(c0, M(1,0), 0); GetCoeff(d0, M(1,1), 0); GetCoeff(u0, U, 0); GetCoeff(u1, U, 1); GetCoeff(v0, V, 0); GetCoeff(v1, V, 1); mul(t1, rep(a0), rep(u0)); mul(t2, rep(b0), rep(v0)); add(t1, t1, t2); conv(nu0, t1); mul(t1, rep(a1), rep(u0)); mul(t2, rep(a0), rep(u1)); add(t1, t1, t2); mul(t2, rep(b1), rep(v0)); add(t1, t1, t2); mul(t2, rep(b0), rep(v1)); add(t1, t1, t2); conv(nu1, t1); mul(t1, rep(c0), rep(u0)); mul(t2, rep(d0), rep(v0)); add (t1, t1, t2); conv(nv0, t1); break; case 2: GetCoeff(a0, M(0,0), 0); GetCoeff(b0, M(0,1), 0); GetCoeff(u0, U, 0); GetCoeff(v0, V, 0); mul(t1, rep(a0), rep(u0)); mul(t2, rep(b0), rep(v0)); add(t1, t1, t2); conv(nu0, t1); break; case 3: break; } FFTRep RU(INIT_SIZE, k), RV(INIT_SIZE, k), R1(INIT_SIZE, k), R2(INIT_SIZE, k); ToFFTRep(RU, U, k); ToFFTRep(RV, V, k); ToFFTRep(R1, M(0,0), k); mul(R1, R1, RU); ToFFTRep(R2, M(0,1), k); mul(R2, R2, RV); add(R1, R1, R2); FromFFTRep(U, R1, 0, d); ToFFTRep(R1, M(1,0), k); mul(R1, R1, RU); ToFFTRep(R2, M(1,1), k); mul(R2, R2, RV); add(R1, R1, R2); FromFFTRep(V, R1, 0, d-1); // now fix-up results switch (xx) { case 1: GetCoeff(u0, U, 0); sub(u0, u0, nu0); SetCoeff(U, d-1, u0); SetCoeff(U, 0, nu0); GetCoeff(u1, U, 1); sub(u1, u1, nu1); SetCoeff(U, d, u1); SetCoeff(U, 1, nu1); GetCoeff(v0, V, 0); sub(v0, v0, nv0); SetCoeff(V, d-1, v0); SetCoeff(V, 0, nv0); break; case 2: GetCoeff(u0, U, 0); sub(u0, u0, nu0); SetCoeff(U, d, u0); SetCoeff(U, 0, nu0); break; } }
u8* U8NandArchive::GetFileAllocated( const char *path, u32 *size ) const { //gprintf( "U8NandArchive::GetFileAllocated( %s )\n" ); if( !path || !fst ) { return NULL; } // find file int f = EntryFromPath( path, 0 ); if( f < 1 || f >= (int)fst[ 0 ].filelen ) { gprintf( "U8: \"%s\" wasn't found in the archive.\n", path ); return NULL; } if( fst[ f ].filetype ) { gprintf( "U8: \"%s\" is a folder\n", path ); return NULL; } // create a buffer u8* ret = (u8*)memalign( 32, RU( fst[ f ].filelen, 32 ) ); if( !ret ) { gprintf( "U8: out of memory\n" ); return NULL; } // seek and read if( ISFS_Seek( fd, dataOffset + fst[ f ].fileoffset, SEEK_SET ) != (s32)( dataOffset + fst[ f ].fileoffset ) || ISFS_Read( fd, ret, fst[ f ].filelen ) != (s32)fst[ f ].filelen ) { free( ret ); gprintf( "U8: error reading data from nand\n" ); gprintf( "fd: %i fst[ fd ].filelen: %08x\n", fd, fst[ f ].filelen ); return NULL; } u32 len = fst[ f ].filelen; u8* ret2; // determine if it needs to be decompressed if( IsAshCompressed( ret, len ) ) { // ASH0 ret2 = DecompressAsh( ret, len ); if( !ret2 ) { free( ret ); gprintf( "out of memory\n" ); return NULL; } free( ret ); } else if( isLZ77compressed( ret ) ) { // LZ77 with no magic word if( decompressLZ77content( ret, len, &ret2, &len ) ) { free( ret ); return NULL; } free( ret ); } else if( *(u32*)( ret ) == 0x4C5A3737 )// LZ77 { // LZ77 with a magic word if( decompressLZ77content( ret + 4, len - 4, &ret2, &len ) ) { free( ret ); return NULL; } free( ret ); } else { // already got what we are after ret2 = ret; } if( size ) { *size = len; } // flush the cache so if there are any textures in this data, it will be ready for the GX DCFlushRange( ret2, len ); return ret2; }
bool U8NandArchive::SetFile( const char* nandPath ) { if(fst) free(fst); if(name_table) free(name_table); CloseFile(); // open file if( (fd = ISFS_Open( nandPath, ISFS_OPEN_READ ) ) < 0 ) { gprintf( "U8NandArchive: ISFS_Open( \"%s\" ) failed\n", nandPath ); return false; } // get file size fstats stats __attribute__(( aligned( 32 ) )); int ret = ISFS_GetFileStats( fd, &stats ); if( ret < 0 ) { CloseFile(); gprintf( "U8NandArchive: ISFS_GetFileStats( \"%s\" ) failed\n", nandPath ); return false; } // buffer for reading the header and stuff u8* buffer = (u8*)memalign( 32, 0x800 ); if( !buffer ) { CloseFile(); gprintf( "U8NandArchive: enomem\n" ); return false; } // read a chunk big enough that it should contain the U8 header if there is going to be one if( (ret = ISFS_Read( fd, buffer, 0x800 )) != 0x800 ) { free( buffer ); CloseFile(); gprintf( "U8NandArchive: ISFS_Read( 0x800 ) = %i\n", ret ); return false; } // find the start of the U8 data U8Header* tagStart = (U8Header*)FindU8Tag( buffer, ret ); if( !tagStart ) { free( buffer ); CloseFile(); gprintf( "U8NandArchive: didn't see a U8 tag\n" ); return false; } // remember where in the file the U8 starts dataOffset = ( (u8*)tagStart - buffer ); // allocate memory and read the fst if( !(fst = (FstEntry *)memalign( 32, RU( tagStart->dataOffset - dataOffset, 32 ) ) ) || ( ISFS_Seek( fd, dataOffset + tagStart->rootNodeOffset, SEEK_SET ) != (s32)( dataOffset + tagStart->rootNodeOffset ) ) || ( ISFS_Read( fd, fst, tagStart->dataOffset - dataOffset ) != (s32)( tagStart->dataOffset - dataOffset ) ) || ( fst->filelen * 0xC > tagStart->dataOffset ) ) { dataOffset = 0; free( buffer ); if( fst ) free( fst ); CloseFile(); gprintf( "U8NandArchive: error reading fst\n" ); } // set name table pointer u32 name_table_offset = fst->filelen * 0xC; name_table = ((char *)fst) + name_table_offset; free( buffer ); return true; }
bool GameManager::IsCollision(Target* target, Collider* collider) { float rotation = target->getRotation(); const Rect colliderBoundingBox = static_cast<Bullet*>(collider)->GetBoundingArea(); const Rect targetBoundingBox = target->GetBoundingArea(); if (rotation< 3 && rotation > -3 || rotation < 93 && rotation > 87 || rotation < 183 && rotation > 177 || rotation < 273 && rotation > 267){ //회전이 거의 없는 경우 //예전 사각형 충돌 판정 if (targetBoundingBox.intersectsRect(colliderBoundingBox)) return true; return false; } float colliderX = collider->getPosition().x; float colliderY = collider->getPosition().y; float minX = targetBoundingBox.getMinX(); // left margin float maxX = targetBoundingBox.getMaxX(); // right margin float minY = targetBoundingBox.getMinY(); // lower margin float maxY = targetBoundingBox.getMaxY(); // upper margin Point LL(minX, minY); Point LU(minX, maxY); Point RL(maxX, minY); Point RU(maxX, maxY); //회전사각형만들기 LL.rotate(target->getPosition(), -CC_DEGREES_TO_RADIANS(target->getRotation())); LU.rotate(target->getPosition(), -CC_DEGREES_TO_RADIANS(target->getRotation())); RL.rotate(target->getPosition(), -CC_DEGREES_TO_RADIANS(target->getRotation())); RU.rotate(target->getPosition(), -CC_DEGREES_TO_RADIANS(target->getRotation())); // y = Ax + upperB // y = Ax + lowerB // y = -1/Ax + leftB // y = -1/Ax + rightB float a = (RU.y - LU.y) / (RU.x - LU.x); //기울기 // RU.y = a * RU.x + upperB float upperB = RU.y - a * (RU.x); float lowerB = LL.y - a * (LL.x); // LL.y = (-1/a) * LL.x + leftB float leftB = LL.y - (-1 / a) * LL.x; float rightB = RU.y - (-1 / a) * RU.x; if ( ((colliderX * a + upperB) - colliderY) * ((colliderX * a + lowerB) - colliderY) < 0 && ((colliderX * (-1 / a) + leftB) - colliderY) * ((colliderX * (-1 / a) + rightB) - colliderY) < 0 ) { return true; } else { return false; } }
bool U8FileArchive::SetFile( const char* filePath ) { FREE( fst ); FREE( name_table ); CloseFile(); // open file if( !(fd = fopen( filePath, "rb" ) ) ) { gprintf( "U8FileArchive: fopen( \"%s\" ) failed\n",filePath ); return false; } int ret; // buffer for reading the header and stuff u8* buffer = (u8*)memalign( 32, 0x800 ); if( !buffer ) { CloseFile(); gprintf( "U8FileArchive: enomem\n" ); return false; } // read a chunk big enough that it should contain the U8 header if there is going to be one if( (ret = fread( buffer, 0x800, 1, fd )) != 1 ) { free( buffer ); CloseFile(); gprintf( "U8FileArchive: fread( 0x800 ) = %i\n", ret ); return false; } // find the start of the U8 data U8Header* tagStart = (U8Header*)FindU8Tag( buffer, 0x800 ); if( !tagStart ) { free( buffer ); CloseFile(); gprintf( "U8FileArchive: didn't see a U8 tag\n" ); return false; } // remember where in the file the U8 starts dataOffset = ( (u8*)tagStart - buffer ); // allocate memory and read the fst if( !(fst = (FstEntry *)memalign( 32, RU( tagStart->dataOffset - dataOffset, 32 ) ) ) || ( fseek( fd, dataOffset + tagStart->rootNodeOffset, SEEK_SET ) ) || ( fread( fst, tagStart->dataOffset - dataOffset, 1, fd ) != 1 ) || ( fst->filelen * 0xC > tagStart->dataOffset ) ) { gprintf( "U8FileArchive: error reading fst\n" ); gprintf( "%08x, %p, %p, %08x\n", dataOffset, buffer, fst, ftell( fd ) ); dataOffset = 0; free( buffer ); FREE( fst ); CloseFile(); return false; } // set name table pointer u32 name_table_offset = fst->filelen * 0xC; name_table = ((char *)fst) + name_table_offset; free( buffer ); return true; }
struct mem_buf * template_get_chunk(struct template_chunk *chunk, const gwc_full_stats_t *stats) { char buf[1024], *p = buf; size_t avail = sizeof buf; switch (chunk->type) { case chunk_http_response: case chunk_http_header: case chunk_data: /* Must be handled elsewhere */ p = NULL; RUNTIME_ASSERT(0); break; case crab_stats_total_updates: p = append_uint64(buf, &avail, stats->total.updates); break; case crab_stats_total_updates_ip: p = append_uint64(buf, &avail, stats->total.ip_updates); break; case crab_stats_total_updates_url: p = append_uint64(buf, &avail, stats->total.url_updates); break; case crab_stats_total_requests: p = append_uint64(buf, &avail, stats->total.requests); break; case crab_stats_total_requests_base: p = append_uint64(buf, &avail, stats->total.base_requests); break; case crab_stats_total_requests_data: p = append_uint64(buf, &avail, stats->total.data_requests); break; case crab_stats_total_requests_get: p = append_uint64(buf, &avail, stats->total.get_requests); break; case crab_stats_total_requests_hostfile: p = append_uint64(buf, &avail, stats->total.hostfile_requests); break; case crab_stats_total_requests_urlfile: p = append_uint64(buf, &avail, stats->total.urlfile_requests); break; case crab_stats_total_requests_ping: p = append_uint64(buf, &avail, stats->total.ping_requests); break; case crab_stats_total_requests_statfile: p = append_uint64(buf, &avail, stats->total.statfile_requests); break; case crab_stats_total_accepts: p = append_uint64(buf, &avail, stats->total.accepts); break; case crab_stats_total_blocked: p = append_uint64(buf, &avail, stats->total.blocked); break; case crab_stats_total_errors: p = append_uint64(buf, &avail, stats->total.errors); break; case crab_stats_total_http_400s: p = append_uint64(buf, &avail, stats->total.http_400s); break; case crab_stats_total_http_404s: p = append_uint64(buf, &avail, stats->total.http_404s); break; case crab_stats_total_too_early: p = append_uint64(buf, &avail, stats->total.too_early); break; case crab_stats_total_rx: p = append_size(buf, &avail, stats->total.rx); break; case crab_stats_total_tx: p = append_size(buf, &avail, stats->total.tx); break; case crab_stats_hourly_updates: p = append_uint64(buf, &avail, stats->hourly.updates); break; case crab_stats_hourly_updates_ip: p = append_uint64(buf, &avail, stats->hourly.ip_updates); break; case crab_stats_hourly_updates_url: p = append_uint64(buf, &avail, stats->hourly.url_updates); break; case crab_stats_hourly_requests: p = append_uint64(buf, &avail, stats->hourly.requests); break; case crab_stats_hourly_requests_base: p = append_uint64(buf, &avail, stats->hourly.base_requests); break; case crab_stats_hourly_requests_data: p = append_uint64(buf, &avail, stats->hourly.data_requests); break; case crab_stats_hourly_requests_get: p = append_uint64(buf, &avail, stats->hourly.get_requests); break; case crab_stats_hourly_requests_hostfile: p = append_uint64(buf, &avail, stats->hourly.hostfile_requests); break; case crab_stats_hourly_requests_urlfile: p = append_uint64(buf, &avail, stats->hourly.urlfile_requests); break; case crab_stats_hourly_requests_ping: p = append_uint64(buf, &avail, stats->hourly.ping_requests); break; case crab_stats_hourly_requests_statfile: p = append_uint64(buf, &avail, stats->hourly.statfile_requests); break; case crab_stats_hourly_accepts: p = append_uint64(buf, &avail, stats->hourly.accepts); break; case crab_stats_hourly_blocked: p = append_uint64(buf, &avail, stats->hourly.blocked); break; case crab_stats_hourly_errors: p = append_uint64(buf, &avail, stats->hourly.errors); break; case crab_stats_hourly_http_400s: p = append_uint64(buf, &avail, stats->hourly.http_400s); break; case crab_stats_hourly_http_404s: p = append_uint64(buf, &avail, stats->hourly.http_404s); break; case crab_stats_hourly_too_early: p = append_uint64(buf, &avail, stats->hourly.too_early); break; case crab_stats_hourly_rx: p = append_size(buf, &avail, stats->hourly.rx); break; case crab_stats_hourly_tx: p = append_size(buf, &avail, stats->hourly.tx); break; case crab_startup_time: p = append_date(buf, &avail, stats->start_time.tv_sec); break; case crab_user_agent: p = append_string(buf, &avail, GWC_USER_AGENT); break; case crab_uri: p = append_string(buf, &avail, OPTION(gwc_uri)); break; case crab_url: p = append_string(buf, &avail, OPTION(gwc_url)); break; case crab_network_id: p = append_string(buf, &avail, OPTION(network_id) ? OPTION(network_id) : "gnutella"); break; case crab_contact_address: p = append_string(buf, &avail, OPTION(contact_address) ? OPTION(contact_address) : ""); break; #if defined(HAVE_GETRUSAGE) #define RU_TIME(x) stats->ru.x #else #define RU_TIME(x) 0 #endif /* HAVE_GETRUSAGE */ case crab_rusage_utime: { uint64_t v; v = (uint64_t) RU_TIME(ru_utime.tv_sec) * 1000000 + RU_TIME(ru_utime.tv_usec); p = append_uint64(buf, &avail, v); } break; case crab_rusage_stime: { uint64_t v; v = (uint64_t) RU_TIME(ru_stime.tv_sec) * 1000000 + RU_TIME(ru_stime.tv_usec); p = append_uint64(buf, &avail, v); } break; case crab_rusage_utime_percent: { uint64_t v; v = (uint64_t) RU_TIME(ru_utime.tv_sec) * 1000000 + RU_TIME(ru_utime.tv_usec); p = append_uint64(buf, &avail, v); } break; case crab_rusage_stime_percent: { uint64_t v; v = (uint64_t) RU_TIME(ru_stime.tv_sec) * 1000000 + RU_TIME(ru_stime.tv_usec); p = append_uint64(buf, &avail, v); } break; #if defined(HAVE_GETRUSAGE) && defined(HAVE_BSD_STRUCT_RUSAGE) #define RU(x) stats->ru.x #else #define RU(x) 0 #endif /* HAVE_GETRUSAGE && HAVE_BSD_STRUCT_RUSAGE */ case crab_rusage_maxrss: p = append_uint64(buf, &avail, RU(ru_maxrss)); break; case crab_rusage_ixrss: p = append_uint64(buf, &avail, RU(ru_ixrss)); break; case crab_rusage_idrss: p = append_uint64(buf, &avail, RU(ru_idrss)); break; case crab_rusage_isrss: p = append_uint64(buf, &avail, RU(ru_isrss)); break; case crab_rusage_minflt: p = append_uint64(buf, &avail, RU(ru_minflt)); break; case crab_rusage_majflt: p = append_uint64(buf, &avail, RU(ru_majflt)); break; case crab_rusage_nswap: p = append_uint64(buf, &avail, RU(ru_nswap)); break; case crab_rusage_inblock: p = append_uint64(buf, &avail, RU(ru_inblock)); break; case crab_rusage_oublock: p = append_uint64(buf, &avail, RU(ru_oublock)); break; case crab_rusage_msgsnd: p = append_uint64(buf, &avail, RU(ru_msgsnd)); break; case crab_rusage_msgrcv: p = append_uint64(buf, &avail, RU(ru_msgrcv)); break; case crab_rusage_nsignals: p = append_uint64(buf, &avail, RU(ru_nsignals)); break; case crab_rusage_nvcsw: p = append_uint64(buf, &avail, RU(ru_nvcsw)); break; case crab_rusage_nivcsw: p = append_uint64(buf, &avail, RU(ru_nivcsw)); break; #undef RU default: CRIT("Unknown chunk type (%u)", (unsigned) chunk->type); p = NULL; RUNTIME_ASSERT(0); } if (p && p != buf) { return mem_buf_new_copy(buf, p - buf); } return NULL; }
void *DiHandler::ThreadMain( void *arg ) { enum State { St_Init, St_Reset, St_WaitForDisc, St_CheckDiscType, St_OpenPartition, St_WaitForDiscEject, // some error happened, dont do anything until the current disc is ejected St_Idle }; State state = St_Init; u32 coverState = 0; while( !threadExit ) { usleep( 1000 ); if( threadSleep ) LWP_SuspendThread( thread ); if( state == St_Init ) { if( WDVD_Init() ) { instance->ErrorHappened( E_Init, true ); threadExit = true; } state = St_Reset; continue; } else if( state == St_Reset ) { if( WDVD_Reset() ) { instance->ErrorHappened( E_Init, false ); continue; } state = St_WaitForDisc; } // check for disc u32 cover = 0; if( WDVD_GetCoverStatus( &cover ) ) { gprintf( "WDVD_GetCoverStatus() failed\n" ); WDVD_Close(); state = St_Init; continue; } // check if disc status is changed if( cover != coverState ) { //gprintf( "cover status: %08x %08x\n", cover, coverState ); if( cover & 2 )// disc is present and wasnt before { //gprintf( "disc inserted\n" ); instance->StartingToReadDisc(); WDVD_Reset(); state = St_CheckDiscType; } else if( coverState & 2 )// disc was present before isnt is gone now { instance->DiscEjected(); //gprintf( "disc ejected\n" ); state = St_WaitForDisc; } coverState = cover; } if( !( cover & 2 ) )// if theres no disc inserted, then loop { continue; } if( state == St_WaitForDiscEject ) { continue; } else if( state == St_CheckDiscType ) { s32 ret = WDVD_ReadDiskId( (void*)0x80000000 ); if( ret < 0 ) { gprintf("WDVD_ReadDiskId(): %d\n", ret ); instance->ErrorHappened( E_DVD_ReadError, false ); //state = St_WaitForDiscEject; WDVD_Close(); state = St_Init; //coverState = 0; continue; } // check disc type if( *(u32*)( 0x80000018 ) == 0x5d1c9ea3 ) { //gprintf( "disc is wii\n" ); state = St_OpenPartition; //instance->DiscInserted( T_Wii ); } else if( *(u32*)( 0x8000001c ) == 0xc2339f3d ) { //gprintf( "disc is gamecube\n" ); instance->DiscInserted( T_GC ); state = St_Idle; } else { //gprintf( "disc is unknown\n" ); instance->DiscInserted( T_Unknown ); state = St_WaitForDiscEject; //hexdump( (void*)0x80000000, 0x20 ); } } else if( state == St_OpenPartition ) { if( WDVD_OpenDataPartition() < 0 ) { instance->ErrorHappened( E_OpenPartition, false ); state = St_WaitForDiscEject; continue; } //gprintf( "partition is open\n" ); // search for the opening.bnr s32 ret; FST_INFO fst_info __attribute(( aligned( 32 ) )); //find FST inside partition ret = WDVD_Read( (u8*)&fst_info, sizeof( FST_INFO ), 0x420LL ); if( ret < 0 ) { gprintf("WDVD_Read( fst_info ): %d\n", ret ); instance->ErrorHappened( E_DVD_ReadError, false ); state = St_WaitForDiscEject; WDVD_ClosePartition(); continue; } fst_info.fst_offset <<= 2; fst_info.fst_size <<= 2; //gprintf( "%s %i\n", __FILE__, __LINE__ ); fst_buffer = (u8*)memalign( 32, RU( fst_info.fst_size, 0x40 ) ); if( !fst_buffer ) { instance->ErrorHappened( E_NoMem, true ); threadExit = true; WDVD_ClosePartition(); continue; } //gprintf( "%s %i\n", __FILE__, __LINE__ ); //gprintf( " %p %08x %08x\n", fst_buffer, fst_info.fst_size, fst_info.fst_offset ); //read fst into memory ret = WDVD_Read( fst_buffer, fst_info.fst_size, fst_info.fst_offset ); if( ret < 0 ) { gprintf("WDVD_Read( fst_buffer ): %d\n", ret ); instance->ErrorHappened( E_DVD_ReadError, false ); state = St_WaitForDiscEject; WDVD_ClosePartition(); continue; } //gprintf( "%s %i\n", __FILE__, __LINE__ ); //set the pointers fst = (FST_ENTRY *)fst_buffer; u32 name_table_offset = fst->filelen * 0xC; name_table = (char *)( fst_buffer + name_table_offset ); //gprintf( "%s %i\n", __FILE__, __LINE__ ); // find the opening.bnr int fd = EntryFromPath( "/opening.bnr", 0 ); if( fd < 2 ) { instance->ErrorHappened( E_NoOpeningBnr, false ); instance->DiscInserted( T_Wii ); FREE( fst ); name_table = NULL; state = St_Idle; WDVD_ClosePartition(); continue; } //gprintf( "%s %i\n", __FILE__, __LINE__ ); u32 len = fst[ fd ].filelen; u8 *buf = (u8*)memalign( 32, RU( len, 0x40 ) ); if( !buf ) { instance->ErrorHappened( E_NoMem, true ); threadExit = true; FREE( fst ); name_table = NULL; WDVD_ClosePartition(); continue; } //gprintf( "%s %i\n", __FILE__, __LINE__ ); ret = WDVD_Read( buf, len, (u64)( fst[ fd ].fileoffset ) << 2 ); if( ret < 0 ) { gprintf("WDVD_Read( opening.bnr ): %d\n", ret ); instance->ErrorHappened( E_DVD_ReadError, false ); state = St_WaitForDiscEject; FREE( fst ); name_table = NULL; free( buf ); WDVD_ClosePartition(); continue; } //gprintf( "%s %i\n", __FILE__, __LINE__ ); // done with these FREE( fst ); name_table = NULL; WDVD_ClosePartition(); //gprintf( "%s %i\n", __FILE__, __LINE__ ); bool rec = false; // got the opening.bnr. send it to whoever cares instance->OpeningBnrReady( buf, len, rec ); if( !rec ) { gprintf( "nobody got the banner. freeing it\n" ); free( buf ); } instance->DiscInserted( T_Wii ); //gprintf( "%s %i\n", __FILE__, __LINE__ ); state = St_Idle; } } return NULL; }
Wad::Wad( const QByteArray &stuff ) { ok = false; if( !stuff.size() )//prevent error text when it isnt required return; if( stuff.size() < 0x80 )//less than this and there is definitely nothing there { Err( "Size is < 0x80" ); return; } QByteArray copy = stuff; QBuffer b( © ); b.open( QIODevice::ReadOnly ); quint32 tmp; if(b.read( (char*)&tmp, 4 ) != 4) { b.close(); Err( "Can't read header size" ); return; } if( qFromBigEndian( tmp ) != 0x20 ) { b.close(); hexdump(stuff, 0, 0x10); Err( "Bad header size" ); return; } b.read( (char*)&tmp, 4 ); tmp = qFromBigEndian( tmp ); if( tmp != 0x49730000 && tmp != 0x69620000 && tmp != 0x426b0000 ) { b.close(); hexdump( stuff, 0, 0x40 ); Err( "Bad file magic word" ); return; } quint32 certSize; quint32 tikSize; quint32 tmdSize; quint32 appSize; quint32 footerSize; b.read( (char*)&certSize, 4 ); certSize = qFromBigEndian( certSize ); b.seek( 0x10 ); b.read( (char*)&tikSize, 4 ); tikSize = qFromBigEndian( tikSize ); b.read( (char*)&tmdSize, 4 ); tmdSize = qFromBigEndian( tmdSize ); b.read( (char*)&appSize, 4 ); appSize = qFromBigEndian( appSize ); b.read( (char*)&footerSize, 4 ); footerSize = qFromBigEndian( footerSize ); b.close();//close the buffer, the rest of the data can be checked without it //sanity check this thing quint32 s = stuff.size(); if( s < ( RU( certSize, 0x40 ) + RU( tikSize, 0x40 ) + RU( tmdSize, 0x40 ) + RU( appSize, 0x40 ) + RU( footerSize, 0x40 ) ) ) { Err( "Total size is less than the combined sizes of all the parts that it is supposed to contain" ); return; } quint32 pos = 0x40; certData = stuff.mid( pos, certSize ); pos += RU( certSize, 0x4 ); tikData = stuff.mid( pos, tikSize ); pos += RU( tikSize, 0x40 ); tmdData = stuff.mid( pos, tmdSize ); pos += RU( tmdSize, 0x40 ); Ticket ticket( tikData ); Tmd t( tmdData ); //the constructor for Ticket may have fixed a bad key index. replace the data just incase it did tikData = ticket.Data(); //hexdump( tikData ); //hexdump( tmdData ); if( ticket.Tid() != t.Tid() ) qWarning() << "wad contains 2 different TIDs"; quint32 cnt = t.Count(); //qDebug() << "Wad contains" << hex << cnt << "contents"; //another quick sanity check quint32 totalSize = 0; for( quint32 i = 0; i < cnt; i++ ) totalSize += t.Size( i ); if( totalSize > appSize ) { Err( "Size of all the apps in the tmd is greater than the size in the wad header" ); return; } //read all the contents, check the hash, and remember the data ( still encrypted ) for( quint32 i = 0; i < cnt; i++ ) { quint32 s = RU( t.Size( i ), 0x40 ); //qDebug() << "content" << i << "is at" << hex << pos // << "with size" << s; QByteArray encData = stuff.mid( pos, s ); pos += s; //doing this here in case there is some other object that //is using the AES that would change the key on us AesSetKey( ticket.DecryptedKey() ); QByteArray decData = AesDecrypt( t.Index( i ), encData ); decData.resize( t.Size( i ) ); QByteArray realHash = GetSha1( decData ); if( realHash != t.Hash( i ) ) { Err( QString( "hash doesnt match for content %1" ).arg( i ) ); } partsEnc << encData; } //wtf? some VC titles have a full banner as the footer? maybe somebody's wad packer is busted //QByteArray footer = stuff.mid( pos, stuff.size() - pos ); //qDebug() << "footer"; //hexdump( footer ); ok = true; }
const QByteArray Wad::Data( quint32 magicWord, const QByteArray &footer ) { //qDebug() << "Wad::Data" << hex << magicWord << footer.size(); if( !partsEnc.size() || tmdData.isEmpty() || tikData.isEmpty() || ( certData.isEmpty() && globalCert.isEmpty() ) ) { Err( "Dont have all the parts to make a wad" ); return QByteArray(); } //do some brief checks to make sure that wad is good Ticket ticket( tikData ); Tmd t( tmdData ); if( t.Tid() != ticket.Tid() ) { Err( "Ticket and TMD have different TID" ); return QByteArray(); } if( partsEnc.size() != t.Count() ) { Err( "Dont have enough contents according to the TMD" ); return QByteArray(); } //everything seems in order, try to make the thing QByteArray cert = certData.isEmpty() ? globalCert : certData; quint32 certSize = cert.size(); quint32 tikSize = ticket.SignedSize(); quint32 tmdSize = t.SignedSize(); quint32 appSize = 0; quint32 footerSize = footer.size(); //add all the app sizes together and check that they match the TMD quint16 cnt = t.Count(); for( quint16 i = 0; i < cnt; i++ ) { quint32 s = RU( partsEnc.at( i ).size(), 0x40 ); if( RU( t.Size( i ), 0x40 ) != s ) { Err( QString( "Size of content %1 is bad ( %2, %3, %4 )" ) .arg( i ) .arg( t.Size( i ), 0, 16 ) .arg( RU( t.Size( i ), 0x40 ), 0, 16 ) .arg( s, 0, 16 ) ); return QByteArray(); } appSize += s; } QByteArray header( 0x20, '\0' ); QBuffer buf( &header ); buf.open( QIODevice::WriteOnly ); quint32 tmp = qFromBigEndian( 0x20 );//header size buf.write( (const char*)&tmp, 4 ); tmp = qFromBigEndian( magicWord );//magic word buf.write( (const char*)&tmp, 4 ); tmp = qFromBigEndian( certSize ); buf.write( (const char*)&tmp, 4 ); buf.seek( 0x10 ); tmp = qFromBigEndian( tikSize ); buf.write( (const char*)&tmp, 4 ); tmp = qFromBigEndian( tmdSize ); buf.write( (const char*)&tmp, 4 ); tmp = qFromBigEndian( appSize ); buf.write( (const char*)&tmp, 4 ); tmp = qFromBigEndian( footerSize ); buf.write( (const char*)&tmp, 4 ); buf.close(); //hexdump( header, 0, 0x20 ); QByteArray ret = PaddedByteArray( header, 0x40 ) + PaddedByteArray( cert, 0x40 ); //make sure we dont have the huge ticket and TMD that come when downloading from NUS QByteArray tik = tikData; tik.resize( tikSize ); tik = PaddedByteArray( tik, 0x40 ); QByteArray tm = tmdData; tm.resize( tmdSize ); tm = PaddedByteArray( tm, 0x40 ); //hexdump( tik ); //hexdump( tm ); ret += tik + tm; for( quint16 i = 0; i < cnt; i++ ) { ret += PaddedByteArray( partsEnc.at( i ), 0x40 ); } ret += footer; return ret; }