コード例 #1
0
ファイル: WoW.cpp プロジェクト: Tej1106083/wow
void bullet(int i)
{
	setbkcolor(0);
	int j;
	for(j=425;j>=0;j-=25)
	{circle(325+i,j,3); floodfill(327+i,j+1,RED);
	if((322+i<=::x)&&(328+i>=::x)&&(j==::y))
	  {::l++;if(::l<20){blast(i,j);break;}
	   if(::l==20){getch();delay(1000);blast(i,j);score(i,::l,::shots);}}
	delay(15); sound(600);delay(1);nosound(); target(i);}
}
コード例 #2
0
ファイル: EnemyCache.cpp プロジェクト: dongjietan/BattleCity
void EnemyCache::addStar(){
    int index = (20 - GameManager::getInstance()->getEnemyRemain()) % 3;
    GameManager::getInstance()->setCurrentEnemyCount(GameManager::getInstance()->getCurrentEnemyCount() + 1);
    GameManager::getInstance()->setEnemyRemain(GameManager::getInstance()->getEnemyRemain() - 1);
    Vec2 pos;
    switch (index) {
        case 2:
            pos = Vec2(12, 12 * 25);
            break;
        case 0:
            pos = Vec2(12 * 13, 12 * 25);
            break;
        case 1:
            pos = Vec2(12 * 25, 12 * 25);
            break;
        default:
            break;
    }
    
    auto born = Born::createBorn();
    born->setPosition(pos);
    born->blast();
    this->addChild(born);
    
    //移去右上角相应的坦克标志
    this->getChildByTag(100 + GameManager::getInstance()->getEnemyRemain())->removeFromParentAndCleanup(true);
    
    DelayTime *delayAction = DelayTime::create(1.0f);
    auto call = CallFuncN::create(CC_CALLBACK_0(EnemyCache::spawnEnemy, this, born->getPosition()));
    auto seq = Sequence::create(delayAction, call, NULL);
    this->runAction(seq);
}
コード例 #3
0
ファイル: ark-get.c プロジェクト: DanielAtSamraksh/sketchbook
static void ark_get (FILE *ark, const char *ark_name, const char *key) {
    if (0 != fseek (ark, -11, SEEK_END))
	sys_panic (ark_name);
    long catalog_size;
    fscanf (ark, "%ld", &catalog_size);  // XXX check errors
    if (catalog_size <= 0)
	panic ("Bad or empty arkfile");
    if (0 != fseek (ark, -11 - catalog_size, SEEK_END))
	sys_panic (ark_name);
    long offset = 0;
    for (;;) {
	long size;
	fscanf (ark, "%ld ", &size);	// XXX check errors
	char key2[1024];
	if (!fgets (key2, sizeof key2, ark))
	    panic ("Key not found");
	size_t L = strlen (key2);
	if (0 < L)
	    key2[L-1] = '\0';		// strip trailing newline
	if (0 == strcmp (key, key2)) {
	    blast (ark, ark_name, offset, size);
	    return;
	}
	offset += size;
    }
}
コード例 #4
0
ファイル: Network.cpp プロジェクト: MaxDZ8/M8M
NetworkInterface::ServiceSocketInterface& WindowsNetwork::NewServiceSocket(aushort port, aushort numPending) {
	addrinfo hints;
	memset(&hints, 0, sizeof(hints));
	hints.ai_family = AF_INET;
	hints.ai_socktype = SOCK_STREAM;
	hints.ai_protocol = IPPROTO_TCP;
	hints.ai_flags = AI_PASSIVE;
	addrinfo *result = nullptr;
	ScopedFuncCall blast([result]() { if(result) freeaddrinfo(result); });
	char number[8]; // 64*1024+null
	if(port) _itoa_s(port, number, 10);
	if(getaddrinfo(NULL, port? number : NULL, &hints, &result)) throw std::exception("getaddrinfo failed.");
	SOCKET listener = INVALID_SOCKET;
	ScopedFuncCall clearSocket([&listener]() { if(listener != INVALID_SOCKET) closesocket(listener); });
	listener = socket(result->ai_family, result->ai_socktype, result->ai_protocol);
	if(listener == INVALID_SOCKET) throw std::exception("Error creating new Service Socket, creation failed.");
    SetBlocking(listener, false);
	if(bind(listener, result->ai_addr, static_cast<int>(result->ai_addrlen)) == SOCKET_ERROR) throw std::exception("Error creating new Service Socket, could not bind.");
	if(listen(listener, numPending? numPending : SOMAXCONN) == SOCKET_ERROR) throw std::exception("Error creating new Service Socket, could enter listen state.");
	
	std::unique_ptr<ServiceSocket> add(new ServiceSocket(listener, port));
	clearSocket.Dont();
	servers.insert(std::make_pair(static_cast<SocketInterface*>(add.get()), add.get()));
	return *add.release();
}
コード例 #5
0
void BurstShot::collidedWith(const e_ptr &other)
{
    if(other->getType() == ENEMY){
        if(!(static_cast<EnemyEntity *>(other.data())->isDead())){
            hit = true;
            e_ptr blast(new BlastEffect(game,  getX(), getY(), polarity, width()/2,width()));
            game->getEffects().append(blast);
        }
    }
}
コード例 #6
0
ファイル: EnemyShip.cpp プロジェクト: anish18sun/Hyper-visor
void EnemyShip::moveEvent(QMoveEvent *){
    if((!hasBeenHit) && shipHit() && (gunStatus)){
        xPos = x();
        yPos = y();
        emit blast();
        hasBeenHit = true;
    }
    else if((!hasBeenHit) && (!hasCollided) && shipCollided()){
        emit collision();
        hasCollided = true;
    }
}
コード例 #7
0
void EnemyShotEntity::collidedWith(const e_ptr &other)
{
    if(hit){
        return;
    }
    if(other->getType() == PLAYER){
        hit = true;
        removeThis = true;
        if(other->getPolarity() == polarity){
            e_ptr blast(new BlastEffect(game,  getX(), getY(), polarity, width()/2,0));
//            blast->setHorizontalMovement(pos.x() - other->getHorizontalMovement());
//            blast->setVerticalMovement(pos.y() - other->getVerticalMovement());
            game->getEffects().append(blast);
        }else{
            e_ptr blast(new BlastEffect(game,  getX(), getY(), polarity, width()/2,width()));
//            blast->setHorizontalMovement(dir.x());
//            blast->setVerticalMovement(dir.y());
            game->getEffects().append(blast);
        }
    }

}
コード例 #8
0
ファイル: gmail.com.c プロジェクト: kapilkd13/onlinejudge
int crushposition(int a)
{
	int i,k,l,m,n,j,flag,b,y;
	int initial,final,profit[20];
	for(i=0;i<count2;i++)
	{
		for(m=0;m<=4;m++)
		{
			for(n=0;n<=4;n++)
			{
				duplicate[m][n]=arr[m][n];
			}
		}
	
		
		m=crush[i];
		
		extractor(m,&k,&l);
		increaseandoccupy(k,l,p);
		insert(m);
	   initial=duplicateballs(p);
	  
	   
	  
		while(front!=-1)
		{
			m=dele();
			
					if(checkblast(m,p))
		{   
			extractor(m,&j,&k);
			y=cellformat(j,k);
			blast(j,k,y,p);
		}
		
		}
		front=-1;
		rear=-1;
		final=duplicateballs(p);
	
		profit[i]=final-initial;
		
	
		
		
	
	}
コード例 #9
0
ファイル: scene.cpp プロジェクト: crucifix35/base-pro-edition
PxVec3 Scene::getWindAtPoint(const PxVec3& point)
{
    if( !database::LocationInfo::getRecord( _location->getDatabaseId() )->wind )
    {
        return PxVec3( 0,0,0 );
    }

    float windAmbient   = _location->getWindAmbient();
    float windBlast     = _location->getWindBlast();
    float windAmplitude = ( windBlast - windAmbient ) / 2;

    float windMagnitude = windAmbient + windAmplitude + windAmplitude * blast( _windTime );

    PxVec3 windN = wrap( _location->getWindDirection() );
    windN.normalize();

    return windN * windMagnitude;
}
コード例 #10
0
ファイル: actor.c プロジェクト: evktalo/overgod
int detect_collision_actor_enemies(int a)
{
 if (actor[a].grace_period > 0 || actor[a].in_play == 0)
  return -1;

 int x2 = actor[a].x - actor[a].x_speed;
 int y2 = actor[a].y - actor[a].y_speed;
 int i;

 int angle1, angle2, angle3;
 int total_speed;
 int difference;
 int collision_velocity = 0;
 int hurty = 0;
 int passing_colours [5];

 int xs2, ys2;

 for (i = 0; i < NO_ENEMIES; i ++)
 {
  if (enemy[i].type == ENEMY_NONE)
   continue;
  if (enemy[i].radius == 0)
  // enemy has no collision radius - dead wanderer etc
   continue;

  if (actor[a].just_collided > 0 && enemy[i].just_collided > 0)
   continue;

  if (hypot(actor[a].x - enemy[i].x, actor[a].y - enemy[i].y) <= actor[a].radius + enemy[i].radius
      || hypot(x2 - enemy[i].x, y2 - enemy[i].y) <= actor[a].radius + enemy[i].radius)
  {
/*   if (actor[a].x_speed == 0)
    tangent = 1000;
     else
      tangent = tan(actor[a].y_speed / actor[a].x_speed);
*/
   switch(enemy[i].type)
   {
/*    case ENEMY_SWERVER:
    case ENEMY_SWERVER2:
    case ENEMY_SWERVER3:
    case ENEMY_BOUNCER:
    case ENEMY_BOUNCER2:
    case ENEMY_BOUNCER3:
    case ENEMY_BOUNCER4:
    case ENEMY_BOUNCER5:
     hurt_enemy(i, 99999, -1, 1);
     return -1;*/

   }


// Really dodgy collision physics...

   collision_velocity = hypot(abs(actor[a].x_speed - enemy[i].x_speed), abs(actor[a].y_speed - enemy[i].y_speed));

// First calculate actor's post-collision velocity:
   angle1 = radians_to_angle(atan2(actor[a].y_speed, actor[a].x_speed));
   angle2 = radians_to_angle(atan2(actor[a].y - enemy[i].y, actor[a].x - enemy[i].x));

   total_speed = hypot(actor[a].y_speed, actor[a].x_speed);

   angle1 += ANGLE_HALF;
   if (angle2 > ANGLE_FULL)
    angle2 -= ANGLE_FULL;

   angle2 += ANGLE_QUARTER;
   if (angle2 > ANGLE_FULL)
    angle2 -= ANGLE_FULL;

/*   if (angle1 < angle2)
   {
    difference = angle2 - angle1;
   }
    else
    {
     difference = angle1 - angle2;
    }

   angle3 = angle1 - difference;*/

   difference = angle2 - angle1;
   angle3 = angle2 - difference; // or +?

   xs2 = actor[a].x_speed;
   ys2 = actor[a].y_speed;

   actor[a].x_speed = cos(angle_to_radians(angle3)) * total_speed;
   actor[a].y_speed = sin(angle_to_radians(angle3)) * total_speed;
//   actor[a].x_speed = cos(angle_to_radians(angle3)) * total_speed;
//   actor[a].y_speed = sin(angle_to_radians(angle3)) * total_speed;

   actor[a].x_speed += (enemy[i].x_speed / 2) * 100 / actor[a].mass;
   actor[a].y_speed += (enemy[i].y_speed / 2) * 100 / actor[a].mass;

// Now the enemy's
   angle1 = radians_to_angle(atan2(enemy[i].y_speed, enemy[i].x_speed));
   angle2 = radians_to_angle(atan2(enemy[i].y - actor[a].y, enemy[i].x - actor[a].x));

   total_speed = hypot(enemy[i].y_speed, enemy[i].x_speed);

   angle1 += ANGLE_HALF;
   if (angle2 > ANGLE_FULL)
    angle2 -= ANGLE_FULL;

   angle2 += ANGLE_QUARTER;
   if (angle2 > ANGLE_FULL)
    angle2 -= ANGLE_FULL;

   difference = angle2 - angle1;
   angle3 = angle2 - difference; // or +?

   enemy[i].x_speed = xpart(angle3, total_speed);//cos(angle_to_radians(angle3)) * total_speed;
   enemy[i].y_speed = ypart(angle3, total_speed);//sin(angle_to_radians(angle3)) * total_speed;

   enemy[i].x_speed += (xs2 * 25) / enemy[i].mass * actor[a].mass / 100;
   enemy[i].y_speed += (ys2 * 25) / enemy[i].mass * actor[a].mass / 100;


   int sanity = 0;
          
   do
   {
    actor[a].x_speed += xpart(angle2, 100);//grand(101) - 50;
    actor[a].y_speed += ypart(angle2, 100);//grand(101) - 50;
    move_actor(a);
    sanity ++;
    if (sanity >= 5000)
     break; // hmm
   } while (hypot(actor[a].x - enemy[i].x, actor[a].y - enemy[i].y) < actor[a].radius + enemy[i].radius);

   actor[a].just_collided = 7;
   enemy[i].just_collided = 7;

   if (actor[a].ship == SHIP_CURVE)
   {
      passing_colours [0] = TRANS_DGREEN;
      passing_colours [1] = TRANS_LGREEN;
      passing_colours [2] = TRANS_YELLOW;
       
      place_explosion(actor[a].x, actor[a].y, 0,0,
       300 + crandom(150), passing_colours);
      blast(actor[a].x, actor[a].y, 40000, 100 + actor[a].total_power * 15, 20000, a);
      blast(enemy[i].x, enemy[i].y, 40000, 0, 2000, OWNER_ENEMY);
      play_wavf(NWAV_BURSTZ, 300 + grand(300));
//   blast(bullet[b].x, bullet[b].y, 30000, 200, 1200, bullet[b].owner);
   }
    else
    {
      passing_colours [0] = TRANS_DGREY;
      passing_colours [1] = TRANS_LGREY;
      passing_colours [2] = TRANS_WHITE;
       
      place_explosion(actor[a].x, actor[a].y, 0,0,
       200 + crandom(150), passing_colours);
     }  

// we cannot have any references to enemy[i] below as it may have been destroyed by the blast
//  call above.
       
   place_explosion(actor[a].x, actor[a].y, 0,0,
    200 + crandom(150), passing_colours);

   play_wavf(NWAV_BUMP, 700 + grand(800));

   hurty = collision_velocity / 30;
   if (hurty > 50)
    hurty = 50;
   
   if (check_shielder(i) == 0 && actor[a].ship != SHIP_CURVE)
   {
    hurt_enemy(i, hurty, a, 1);
    if (enemy[i].hurt_pulse < 4)
     enemy[i].hurt_pulse = 4;
   }
   
   hurt_actor(a, a, hurty);

   break;
/*
   if ((angle1 < angle2 && angle2 > angle1 + ANGLE_HALF)
       || (angle1 > angle2 && angle2 > angle1 - ANGLE_HALF))
   {
    difference =
    angle -= turning;
    if (angle < 0)
     angle += ANGLE_FULL;
   }
    else
    {
     angle += turning;
     if (angle > ANGLE_FULL)
      angle -= ANGLE_FULL;
    }
*/

  }
 
 }

 return -1;

}
コード例 #11
0
ファイル: fly.c プロジェクト: catufunwa/4.4BSD-Lite
visual()
{
	void moveenemy();

	destroyed = 0;
	if(initscr() == ERR){
		puts("Whoops!  No more memory...");
		return(0);
	}
	oldsig = signal(SIGINT, succumb);
	crmode();
	noecho();
	screen();
	row = rnd(LINES-3) + 1;
	column = rnd(COLS-2) + 1;
	moveenemy();
	for (;;) {
		switch(getchar()){

			case 'h':
			case 'r':
				dc = -1;
				fuel--;
				break;

			case 'H':
			case 'R':
				dc = -5;
				fuel -= 10;
				break;

			case 'l':
				dc = 1;
				fuel--;
				break;

			case 'L':
				dc = 5;
				fuel -= 10;
				break;

			case 'j':
			case 'u':
				dr = 1;
				fuel--;
				break;

			case 'J':
			case 'U':
				dr = 5;
				fuel -= 10;
				break;

			case 'k':
			case 'd':
				dr = -1;
				fuel--;
				break;

			case 'K':
			case 'D':
				dr = -5;
				fuel -= 10;
				break;

			case '+':
				if (cross){
					cross = 0;
					notarget();
				}
				else
					cross = 1;
				break;

			case ' ':
			case 'f':
				if (torps){
					torps -= 2;
					blast();
					if (row == MIDR && column - MIDC < 2 && MIDC - column < 2){
						destroyed = 1;
						alarm(0);
					}
				}
				else
					mvaddstr(0,0,"*** Out of torpedoes. ***");
				break;

			case 'q':
				endfly();
				return(0);

			default:
				mvaddstr(0,26,"Commands = r,R,l,L,u,U,d,D,f,+,q");
				continue;

			case EOF:
				break;
		}
		if (destroyed){
			endfly();
			return(1);
		}
		if (clock <= 0){
			endfly();
			die();
		}
	}
}
コード例 #12
0
ファイル: dbc2dbf.c プロジェクト: albanesere/read.dbc
/*
    dbc2dbf(char** input_file, char** output_file)
    This function decompresses a given .dbc input file into the corresponding .dbf.

    Please provide fully qualified names, including file extension.
 */
void dbc2dbf(char** input_file, char** output_file) {
    FILE          *input = 0, *output = 0;
    int           ret = 0;
    unsigned char rawHeader[2];
    uint16_t      header = 0;

    /* Open input file */
    input  = fopen(input_file[0], "rb");
    if(input == NULL) {
        error("Error reading input file %s: %s", input_file[0], strerror(errno));
    }

    /* Open output file */
    output = fopen(output_file[0], "wb");
    if(output == NULL) {
        cleanup(input, output);
        error("Error reading output file %s: %s", output_file[0], strerror(errno));
    }

    /* Process file header - skip 8 bytes */
    if( fseek(input, 8, SEEK_SET) ) {
        cleanup(input, output);
        error("Error processing input file %s: %s", input_file[0], strerror(errno));
    }

    /* Reads two bytes from the header = header size */
    ret = fread(rawHeader, 2, 1, input);
    if( ferror(input) ) {
        cleanup(input, output);
        error("Error reading input file %s: %s", input_file[0], strerror(errno));
    }

    /* Platform independent code (header is stored in little endian format) */
    header = rawHeader[0] + (rawHeader[1] << 8);
    
    /* Reset file pointer */
    rewind(input);

    /* Copy file header from input to output */
    unsigned char buf[header];

    ret = fread(buf, 1, header, input);
    if( ferror(input) ) {
        cleanup(input, output);
        error("Error reading input file %s: %s", input_file[0], strerror(errno));
    }

    ret = fwrite(buf, 1, header, output);
    if( ferror(output) ) {
        cleanup(input, output);
        error("Error writing output file %s: %s", output_file[0], strerror(errno));
    }

    /* Jump to the data (Skip CRC32) */
    if( fseek(input, header + 4, SEEK_SET) ) {
        cleanup(input, output);
        error("Error processing input file %s: %s", input_file[0], strerror(errno));
    }

    /* decompress */
    ret = blast(inf, input, outf, output);
    if( ret ) {
        cleanup(input, output);
        error("Corrupted file? Blast error code: %d", ret);
    }

    /* see if there are any leftover bytes */
    int n = 0;
    while (fgetc(input) != EOF) n++;
    if (n) {
        cleanup(input, output);
        error("blast warning: %d unused bytes of input\n", n);
    }

    cleanup(input, output);
}
コード例 #13
0
void display(void)
{
glClear(GL_COLOR_BUFFER_BIT);
if(flag==0)
{

	glRasterPos3f(58,58,0);
for(i=0;s[i]!='\0';i++) 
glutBitmapCharacter( GLUT_BITMAP_TIMES_ROMAN_24,s[i]);
glRasterPos3f(45,450,0);
for(i=0;s1[i]!='\0';i++) 
glutBitmapCharacter( GLUT_BITMAP_TIMES_ROMAN_24,s1[i]);
glRasterPos3f(90,358,0);
for(i=0;s2[i]!='\0';i++) 
glutBitmapCharacter( GLUT_BITMAP_TIMES_ROMAN_24,s2[i]);
glRasterPos3f(70,338,0);
for(i=0;s3[i]!='\0';i++) 
glutBitmapCharacter( GLUT_BITMAP_TIMES_ROMAN_24,s3[i]);
glRasterPos3f(218,218,0);
for(i=0;s4[i]!='\0';i++) 
glutBitmapCharacter( GLUT_BITMAP_TIMES_ROMAN_24,s4[i]);
glRasterPos3f(350,218,0);
for(i=0;s5[i]!='\0';i++) 
glutBitmapCharacter( GLUT_BITMAP_TIMES_ROMAN_24,s5[i]);
glRasterPos3f(250,150,0);
for(i=0;s6[i]!='\0';i++) 
glutBitmapCharacter( GLUT_BITMAP_TIMES_ROMAN_24,s6[i]);
glColor3f(1.0,1.0,0.0);
glRasterPos3f(250,130,0);
for(i=0;s7[i]!='\0';i++) 
glutBitmapCharacter( GLUT_BITMAP_TIMES_ROMAN_24,s7[i]);
glRasterPos3f(250,100,0);
for(i=0;s8[i]!='\0';i++) 
glutBitmapCharacter( GLUT_BITMAP_TIMES_ROMAN_24,s8[i]);
glRasterPos3f(58,28,0);
for(i=0;s9[i]!='\0';i++) 
glutBitmapCharacter( GLUT_BITMAP_TIMES_ROMAN_24,s9[i]);




}
else
{

	road();
mountain();


	
//green
glBegin(GL_POLYGON);
glColor3f(0.0,1.0,0.0);
	glVertex2i(-10,300);
	glVertex2i(645,310);
   	glVertex2i(940,100);
	glVertex2i(-10,100);
glEnd();


trees();


//plane construction

glPushMatrix();
glTranslated(a,c,0.0);
glColor3f(1,1,1);
glBegin(GL_POLYGON);//rectangular body
glVertex2f(0.0,30.0);
glVertex2f(0.0,55.0);
glVertex2f(135.0,55.0);
glVertex2f(135.0,30.0);
glEnd();
glPopMatrix();

glPushMatrix();
glTranslated(a,c,0.0);
glColor3f(1.0,1.0,1.0);
glBegin(GL_POLYGON);//upper triangle construction plane
glVertex2f(135.0,55.0);
glVertex2f(150.0,50.0);
glVertex2f(155.0,45.0);
glVertex2f(160.0,40.0);
glVertex2f(135.0,40.0);
glEnd();
glPopMatrix();

glPushMatrix();
glTranslated(a,c,0.0);
glColor3f(0.0,0.0,0.0);
glBegin(GL_LINE_LOOP);//outline of upper triangle plane
glVertex2f(135.0,55.0);
glVertex2f(150.0,50.0);
glVertex2f(155.0,45.0);
glVertex2f(160.0,40.0);
glVertex2f(135.0,40.0);
glEnd();
glPopMatrix();


glPushMatrix();
glTranslated(a,c,0.0);
glColor3f(1.0,0.0,0.0);
glBegin(GL_POLYGON);//lower triangle
glVertex2f(135.0,40.0);
glVertex2f(160.0,40.0);
glVertex2f(160.0,37.0);
glVertex2f(145.0,30.0);
glVertex2f(135.0,30.0);
glEnd();
glPopMatrix();


glPushMatrix();
glTranslated(a,c,0.0);
glColor3f(1.0,0.0,0.0);
glBegin(GL_POLYGON);//back wing 
glVertex2f(0.0,55.0);
glVertex2f(0.0,80.0);
glVertex2f(10.0,80.0);
glVertex2f(40.0,55.0);
glEnd();
glPopMatrix();

glPushMatrix();
glTranslated(a,c,0.0);
glColor3f(1.0,0.0,0.0);
glBegin(GL_POLYGON);//left side wing
glVertex2f(65.0,55.0);
glVertex2f(50.0,70.0);
glVertex2f(75.0,70.0);
glVertex2f(90.0,55.0);
glEnd();
glPopMatrix();

glPushMatrix();
glTranslated(a,c,0.0);
glColor3f(1.0,0.0,0.0);
glBegin(GL_POLYGON);//rightside wing
glVertex2f(70.0,40.0);
glVertex2f(100.0,40.0);
glVertex2f(80.0,15.0);
glVertex2f(50.0,15.0);

glEnd();

glPopMatrix();



	if(c>390)    //timer to jump to next display
{
	display2();
	d+=5;//plane takeoff on x in 2nd display
}

if(a>500.0)//window position during take off
{
	a=0.0;
	b=0.0;
}

if(c>800)//timer to jump to 3rd display
{
	display3();
	e+=5;//plane takeoff on x in 3rd display
	
	if(e>250)//timer to call blast function
	{
		blast();
		e=250;
	}
}

}

glFlush();
glutSwapBuffers();
}
コード例 #14
0
ファイル: unZ.c プロジェクト: Daedolon/d2kinst
int unZ(char *archiveFilename, char *extractPath)
{
	FILE *fp;
	fchunk_t fc;

	unsigned int i, destsize;
	unsigned char header[256], *toc;

	unsigned int numFiles, compsize, tocOffset, tocSize, numDirs;
	direntry_t *dirs;

	destsize = strlen(extractPath);

	fp = fopen(archiveFilename, "rb");

	if (!fp)
	{
		printf("Error opening %s!\n", archiveFilename);
		return;
	}

	fseek(fp, 0, SEEK_END);
	compsize = ftell(fp);
	fseek(fp, 0, SEEK_SET);

	fread(header, 256, 1, fp);

	// check signature
	if (GET_UI32(header) != 0x8C655D13)
	{
		printf("Archive corrupt: Bad signature!\n");
		return 0;
	}

	//numFiles = GET_UI16(header + 12);

	// check size
	if (compsize != GET_UI32(header + 18))
	{
		printf("Archive corrupt: Incorrect size!\n");
		return 0;
	}

	// read toc
	tocOffset = GET_UI32(header + 41);
	tocSize = compsize - tocOffset;

	toc = malloc(tocSize);
	fseek(fp, tocOffset, SEEK_SET);
	fread(toc, 1, tocSize, fp);
	tocOffset = 0;


	// parse dirs
	numDirs = GET_UI16(header + 49);
	dirs = malloc(sizeof(*dirs) * numDirs);

	for (i = 0; i < numDirs; i++)
	{
		unsigned int dir_numFiles  = GET_UI16(toc + tocOffset);
		unsigned int dir_entrySize = GET_UI16(toc + tocOffset + 2);
		unsigned int dir_nameSize  = GET_UI16(toc + tocOffset + 4);

		dirs[i].name = malloc(destsize + 1 + dir_nameSize + 1);
		strcpy(dirs[i].name, extractPath);
		dirs[i].name[destsize] = '\\';
		memcpy(dirs[i].name + destsize + 1, toc + tocOffset + 6, dir_nameSize);
		dirs[i].name[destsize + 1 + dir_nameSize] = '\0';
		dirs[i].numFiles = dir_numFiles;

		tocOffset += dir_entrySize;
	}

	// parse and save files
	fseek(fp, 255, SEEK_SET);
	fc.fp = fp;
	for (i = 0; i < numDirs; i++)
	{
		unsigned int dir_nameSize;
		int j;

		_mkdir(extractPath);
		if (dirs[i].name[0])
			_mkdir(dirs[i].name);

		printf("Dir %s, %d files\n", dirs[i].name, dirs[i].numFiles);
		dir_nameSize = strlen(dirs[i].name);

		for (j = 0; j < dirs[i].numFiles; j++)
		{
			FILE *fpw;
			int blastErr;

			unsigned int file_decompressedSize = GET_UI32(toc + tocOffset + 3);
			unsigned int file_compressedSize   = GET_UI32(toc + tocOffset + 7);
			unsigned int file_modifiedDate     = GET_UI16(toc + tocOffset + 15);
			unsigned int file_modifiedTime     = GET_UI16(toc + tocOffset + 17);
			unsigned int file_entrySize        = GET_UI16(toc + tocOffset + 23);
			unsigned int file_nameSize         = toc[tocOffset + 29];

			char *filename;

			struct tm tmm;
			struct _utimbuf ut;

			filename = malloc(dir_nameSize + file_nameSize + 2);
			strcpy(filename, dirs[i].name);
			filename[dir_nameSize] = '\\';
			strncpy(filename + dir_nameSize + 1, toc + tocOffset + 30, file_nameSize);
			filename[dir_nameSize + 1 + file_nameSize] = '\0';

			printf("%s, %d bytes, %.3f%%\n", filename, file_decompressedSize, (float)file_compressedSize / file_decompressedSize * 100.0f);

			memset(&tmm, 0, sizeof(tmm));
			tmm.tm_year = ( file_modifiedDate           >> 9) + 80;
			tmm.tm_mon  = ((file_modifiedDate & 0x01E0) >> 5) - 1;
			tmm.tm_mday =   file_modifiedDate & 0x001F;
			tmm.tm_hour =   file_modifiedTime           >> 11;
			tmm.tm_min  =  (file_modifiedTime & 0x07E0) >> 5;
			tmm.tm_sec  =  (file_modifiedTime & 0x001F) * 2;

#if defined(SHOWTIME)
			printf("last modified %d %s %d %02d:%02d:%02d\n", 
				tmm.tm_year + 1900, months[tmm.tm_mon], tmm.tm_mday, tmm.tm_hour, tmm.tm_min, tmm.tm_sec);
#endif

			tocOffset += file_entrySize;

			fpw = fopen(filename, "wb");
			fc.size = file_compressedSize;

			blastErr = blast(inf, &fc, outf, fpw);

			if (blastErr == 1)
				printf("Error writing file!\n");
			else if (blastErr != 0)
				printf("Archive corrupt: Error decompressing, trying to continue");

			fclose(fpw);

			ut.actime = time(NULL);
			ut.modtime = mktime(&tmm);
			_utime(filename, &ut);

			free(filename);
		}
	}

	fclose(fp);

	for (i = 0; i < numDirs; i++)
		free(dirs[i].name);

	free(dirs);
	free(toc);

	return 0;
}