예제 #1
0
void MenuUpdate()
{
  Uint8 *keys;
  int i,j;
  static float pulse=0.5f;
  static int  flag=0;
  static float fadein =0.0f;
  keys = SDL_GetKeyState(NULL);
  if(inMenu == 1)
  {
    if(fadein < 1) fadein += 0.01f;
    if(flag == 0)
    {
      if(pulse < 1)
      {
        pulse += 0.08f;
      }else flag = 1;
    }
    if(flag == 1)
    {
      if(pulse > 0.5f)
      {
        pulse -= 0.08f;
      }else flag = 0;
    }

    if(keys[SDLK_RETURN])
    {
      testCount = 0;
      inMenu=0;
      SpawnPlayer(0,0,0);
     for(i=0;i<1000;i++)
      {
        testCount = i;
        j=i%4+1;
        if(j==Top)
        {
          SpawnMine(crandom(w),maxy,0.0f, 1*crandom(1),1*crandom(1), 0.0f, j);
        }
        if(j==Bottom)
        {
          SpawnMine(crandom(w),miny,0.0f, 1*crandom(1),1*crandom(1), 0.0f,j);
        }
        if(j==Right)
        {
          SpawnMine(maxx,crandom(h),0.0f, 1*crandom(1),1*crandom(1), 0.0f, j);
        }
        if(j==Left)
        {
          SpawnMine(miny,crandom(h),0.0f, 1*crandom(1),1*crandom(1), 0.0f, j);
        }
      }
    }
    glColor4f(1,1,1,fadein);
    DrawSprite(title,0,0,0,1);
    if(fadein >= 0.6f)
    {
      glColor4f(pulse,0,0,1);
      DrawSprite(newGame,128,S_Data.yres - (700*0.5f),0,0.5f);
    }
    glColor4f(1,1,1,1);
  }

}
예제 #2
0
void Missile::draw(){
    DrawSprite(*missileSprite, misX,misY,FALSE);
}
예제 #3
0
파일: stage.c 프로젝트: jc429/276game
void DrawLayer(StageLayer* layer){
	Sprite* sp = LoadSprite(layer->layerpath,layer->w,layer->h, 1);		
	DrawSprite(sp,screen,layer->x-layer->offx,layer->y-layer->offy,0);
	if(layer->next!=NULL)
		DrawLayer(layer->next);
}
예제 #4
0
파일: main.cpp 프로젝트: nyov/sfxr
void DrawScreen()
{
	bool redraw=true;
	if(!firstframe && mouse_x-mouse_px==0 && mouse_y-mouse_py==0 && !mouse_left && !mouse_right)
		redraw=false;
	if(!mouse_left)
	{
		if(vselected!=NULL || vcurbutton>-1)
		{
			redraw=true;
			refresh_counter=2;
		}
		vselected=NULL;
	}
	if(refresh_counter>0)
	{
		refresh_counter--;
		redraw=true;
	}

	if(playing_sample)
		redraw=true;

	if(drawcount++>20)
	{
		redraw=true;
		drawcount=0;
	}

	if(!redraw)
		return;

	firstframe=false;

	ddkLock();

	ClearScreen(0xC0B090);

	DrawText(10, 10, 0x504030, "GENERATOR");
	for(int i=0;i<7;i++)
	{
		if(Button(5, 35+i*30, false, categories[i].name, 300+i))
		{
			switch(i)
			{
			case 0: // pickup/coin
				ResetParams();
				p_base_freq=0.4f+frnd(0.5f);
				p_env_attack=0.0f;
				p_env_sustain=frnd(0.1f);
				p_env_decay=0.1f+frnd(0.4f);
				p_env_punch=0.3f+frnd(0.3f);
				if(rnd(1))
				{
					p_arp_speed=0.5f+frnd(0.2f);
					p_arp_mod=0.2f+frnd(0.4f);
				}
				break;
			case 1: // laser/shoot
				ResetParams();
				wave_type=rnd(2);
				if(wave_type==2 && rnd(1))
					wave_type=rnd(1);
				p_base_freq=0.5f+frnd(0.5f);
				p_freq_limit=p_base_freq-0.2f-frnd(0.6f);
				if(p_freq_limit<0.2f) p_freq_limit=0.2f;
				p_freq_ramp=-0.15f-frnd(0.2f);
				if(rnd(2)==0)
				{
					p_base_freq=0.3f+frnd(0.6f);
					p_freq_limit=frnd(0.1f);
					p_freq_ramp=-0.35f-frnd(0.3f);
				}
				if(rnd(1))
				{
					p_duty=frnd(0.5f);
					p_duty_ramp=frnd(0.2f);
				}
				else
				{
					p_duty=0.4f+frnd(0.5f);
					p_duty_ramp=-frnd(0.7f);
				}
				p_env_attack=0.0f;
				p_env_sustain=0.1f+frnd(0.2f);
				p_env_decay=frnd(0.4f);
				if(rnd(1))
					p_env_punch=frnd(0.3f);
				if(rnd(2)==0)
				{
					p_pha_offset=frnd(0.2f);
					p_pha_ramp=-frnd(0.2f);
				}
				if(rnd(1))
					p_hpf_freq=frnd(0.3f);
				break;
			case 2: // explosion
				ResetParams();
				wave_type=3;
				if(rnd(1))
				{
					p_base_freq=0.1f+frnd(0.4f);
					p_freq_ramp=-0.1f+frnd(0.4f);
				}
				else
				{
					p_base_freq=0.2f+frnd(0.7f);
					p_freq_ramp=-0.2f-frnd(0.2f);
				}
				p_base_freq*=p_base_freq;
				if(rnd(4)==0)
					p_freq_ramp=0.0f;
				if(rnd(2)==0)
					p_repeat_speed=0.3f+frnd(0.5f);
				p_env_attack=0.0f;
				p_env_sustain=0.1f+frnd(0.3f);
				p_env_decay=frnd(0.5f);
				if(rnd(1)==0)
				{
					p_pha_offset=-0.3f+frnd(0.9f);
					p_pha_ramp=-frnd(0.3f);
				}
				p_env_punch=0.2f+frnd(0.6f);
				if(rnd(1))
				{
					p_vib_strength=frnd(0.7f);
					p_vib_speed=frnd(0.6f);
				}
				if(rnd(2)==0)
				{
					p_arp_speed=0.6f+frnd(0.3f);
					p_arp_mod=0.8f-frnd(1.6f);
				}
				break;
			case 3: // powerup
				ResetParams();
				if(rnd(1))
					wave_type=1;
				else
					p_duty=frnd(0.6f);
				if(rnd(1))
				{
					p_base_freq=0.2f+frnd(0.3f);
					p_freq_ramp=0.1f+frnd(0.4f);
					p_repeat_speed=0.4f+frnd(0.4f);
				}
				else
				{
					p_base_freq=0.2f+frnd(0.3f);
					p_freq_ramp=0.05f+frnd(0.2f);
					if(rnd(1))
					{
						p_vib_strength=frnd(0.7f);
						p_vib_speed=frnd(0.6f);
					}
				}
				p_env_attack=0.0f;
				p_env_sustain=frnd(0.4f);
				p_env_decay=0.1f+frnd(0.4f);
				break;
			case 4: // hit/hurt
				ResetParams();
				wave_type=rnd(2);
				if(wave_type==2)
					wave_type=3;
				if(wave_type==0)
					p_duty=frnd(0.6f);
				p_base_freq=0.2f+frnd(0.6f);
				p_freq_ramp=-0.3f-frnd(0.4f);
				p_env_attack=0.0f;
				p_env_sustain=frnd(0.1f);
				p_env_decay=0.1f+frnd(0.2f);
				if(rnd(1))
					p_hpf_freq=frnd(0.3f);
				break;
			case 5: // jump
				ResetParams();
				wave_type=0;
				p_duty=frnd(0.6f);
				p_base_freq=0.3f+frnd(0.3f);
				p_freq_ramp=0.1f+frnd(0.2f);
				p_env_attack=0.0f;
				p_env_sustain=0.1f+frnd(0.3f);
				p_env_decay=0.1f+frnd(0.2f);
				if(rnd(1))
					p_hpf_freq=frnd(0.3f);
				if(rnd(1))
					p_lpf_freq=1.0f-frnd(0.6f);
				break;
			case 6: // blip/select
				ResetParams();
				wave_type=rnd(1);
				if(wave_type==0)
					p_duty=frnd(0.6f);
				p_base_freq=0.2f+frnd(0.4f);
				p_env_attack=0.0f;
				p_env_sustain=0.1f+frnd(0.1f);
				p_env_decay=frnd(0.2f);
				p_hpf_freq=0.1f;
				break;
			default:
				break;
			}

			PlaySample();
		}
	}
	DrawBar(110, 0, 2, 480, 0x000000);
	DrawText(120, 10, 0x504030, "MANUAL SETTINGS");
	DrawSprite(ld48, 8, 440, 0, 0xB0A080);

	if(Button(130, 30, wave_type==0, "SQUAREWAVE", 10))
		wave_type=0;
	if(Button(250, 30, wave_type==1, "SAWTOOTH", 11))
		wave_type=1;
	if(Button(370, 30, wave_type==2, "SINEWAVE", 12))
		wave_type=2;
	if(Button(490, 30, wave_type==3, "NOISE", 13))
		wave_type=3;

	bool do_play=false;

	DrawBar(5-1-1, 412-1-1, 102+2, 19+2, 0x000000);
	if(Button(5, 412, false, "RANDOMIZE", 40))
	{
		p_base_freq=pow(frnd(2.0f)-1.0f, 2.0f);
		if(rnd(1))
			p_base_freq=pow(frnd(2.0f)-1.0f, 3.0f)+0.5f;
		p_freq_limit=0.0f;
		p_freq_ramp=pow(frnd(2.0f)-1.0f, 5.0f);
		if(p_base_freq>0.7f && p_freq_ramp>0.2f)
			p_freq_ramp=-p_freq_ramp;
		if(p_base_freq<0.2f && p_freq_ramp<-0.05f)
			p_freq_ramp=-p_freq_ramp;
		p_freq_dramp=pow(frnd(2.0f)-1.0f, 3.0f);
		p_duty=frnd(2.0f)-1.0f;
		p_duty_ramp=pow(frnd(2.0f)-1.0f, 3.0f);
		p_vib_strength=pow(frnd(2.0f)-1.0f, 3.0f);
		p_vib_speed=frnd(2.0f)-1.0f;
		p_vib_delay=frnd(2.0f)-1.0f;
		p_env_attack=pow(frnd(2.0f)-1.0f, 3.0f);
		p_env_sustain=pow(frnd(2.0f)-1.0f, 2.0f);
		p_env_decay=frnd(2.0f)-1.0f;
		p_env_punch=pow(frnd(0.8f), 2.0f);
		if(p_env_attack+p_env_sustain+p_env_decay<0.2f)
		{
			p_env_sustain+=0.2f+frnd(0.3f);
			p_env_decay+=0.2f+frnd(0.3f);
		}
		p_lpf_resonance=frnd(2.0f)-1.0f;
		p_lpf_freq=1.0f-pow(frnd(1.0f), 3.0f);
		p_lpf_ramp=pow(frnd(2.0f)-1.0f, 3.0f);
		if(p_lpf_freq<0.1f && p_lpf_ramp<-0.05f)
			p_lpf_ramp=-p_lpf_ramp;
		p_hpf_freq=pow(frnd(1.0f), 5.0f);
		p_hpf_ramp=pow(frnd(2.0f)-1.0f, 5.0f);
		p_pha_offset=pow(frnd(2.0f)-1.0f, 3.0f);
		p_pha_ramp=pow(frnd(2.0f)-1.0f, 3.0f);
		p_repeat_speed=frnd(2.0f)-1.0f;
		p_arp_speed=frnd(2.0f)-1.0f;
		p_arp_mod=frnd(2.0f)-1.0f;
		do_play=true;
	}

	if(Button(5, 382, false, "MUTATE", 30))
	{
		if(rnd(1)) p_base_freq+=frnd(0.1f)-0.05f;
//		if(rnd(1)) p_freq_limit+=frnd(0.1f)-0.05f;
		if(rnd(1)) p_freq_ramp+=frnd(0.1f)-0.05f;
		if(rnd(1)) p_freq_dramp+=frnd(0.1f)-0.05f;
		if(rnd(1)) p_duty+=frnd(0.1f)-0.05f;
		if(rnd(1)) p_duty_ramp+=frnd(0.1f)-0.05f;
		if(rnd(1)) p_vib_strength+=frnd(0.1f)-0.05f;
		if(rnd(1)) p_vib_speed+=frnd(0.1f)-0.05f;
		if(rnd(1)) p_vib_delay+=frnd(0.1f)-0.05f;
		if(rnd(1)) p_env_attack+=frnd(0.1f)-0.05f;
		if(rnd(1)) p_env_sustain+=frnd(0.1f)-0.05f;
		if(rnd(1)) p_env_decay+=frnd(0.1f)-0.05f;
		if(rnd(1)) p_env_punch+=frnd(0.1f)-0.05f;
		if(rnd(1)) p_lpf_resonance+=frnd(0.1f)-0.05f;
		if(rnd(1)) p_lpf_freq+=frnd(0.1f)-0.05f;
		if(rnd(1)) p_lpf_ramp+=frnd(0.1f)-0.05f;
		if(rnd(1)) p_hpf_freq+=frnd(0.1f)-0.05f;
		if(rnd(1)) p_hpf_ramp+=frnd(0.1f)-0.05f;
		if(rnd(1)) p_pha_offset+=frnd(0.1f)-0.05f;
		if(rnd(1)) p_pha_ramp+=frnd(0.1f)-0.05f;
		if(rnd(1)) p_repeat_speed+=frnd(0.1f)-0.05f;
		if(rnd(1)) p_arp_speed+=frnd(0.1f)-0.05f;
		if(rnd(1)) p_arp_mod+=frnd(0.1f)-0.05f;
		do_play=true;
	}

	DrawText(515, 170, 0x000000, "VOLUME");
	DrawBar(490-1-1+60, 180-1+5, 70, 2, 0x000000);
	DrawBar(490-1-1+60+68, 180-1+5, 2, 205, 0x000000);
	DrawBar(490-1-1+60, 180-1, 42+2, 10+2, 0xFF0000);
	Slider(490, 180, sound_vol, false, " ");
	if(Button(490, 200, false, "PLAY SOUND", 20))
		PlaySample();

	if(Button(490, 290, false, "LOAD SOUND", 14))
	{
		char filename[256];
		if(FileSelectorLoad(hWndMain, filename, 1)) // WIN32
		{
			ResetParams();
			LoadSettings(filename);
			PlaySample();
		}
	}
	if(Button(490, 320, false, "SAVE SOUND", 15))
	{
		char filename[256];
		if(FileSelectorSave(hWndMain, filename, 1)) // WIN32
			SaveSettings(filename);
	}

	DrawBar(490-1-1+60, 380-1+9, 70, 2, 0x000000);
	DrawBar(490-1-2, 380-1-2, 102+4, 19+4, 0x000000);
	if(Button(490, 380, false, "EXPORT .WAV", 16))
	{
		char filename[256];
		if(FileSelectorSave(hWndMain, filename, 0)) // WIN32
			ExportWAV(filename);
	}
	char str[10];
	sprintf(str, "%i HZ", wav_freq);
	if(Button(490, 410, false, str, 18))
	{
		if(wav_freq==44100)
			wav_freq=22050;
		else
			wav_freq=44100;
	}
	sprintf(str, "%i-BIT", wav_bits);
	if(Button(490, 440, false, str, 19))
	{
		if(wav_bits==16)
			wav_bits=8;
		else
			wav_bits=16;
	}

	int ypos=4;

	int xpos=350;

	DrawBar(xpos-190, ypos*18-5, 300, 2, 0x0000000);

	Slider(xpos, (ypos++)*18, p_env_attack, false, "ATTACK TIME");
	Slider(xpos, (ypos++)*18, p_env_sustain, false, "SUSTAIN TIME");
	Slider(xpos, (ypos++)*18, p_env_punch, false, "SUSTAIN PUNCH");
	Slider(xpos, (ypos++)*18, p_env_decay, false, "DECAY TIME");

	DrawBar(xpos-190, ypos*18-5, 300, 2, 0x0000000);

	Slider(xpos, (ypos++)*18, p_base_freq, false, "START FREQUENCY");
	Slider(xpos, (ypos++)*18, p_freq_limit, false, "MIN FREQUENCY");
	Slider(xpos, (ypos++)*18, p_freq_ramp, true, "SLIDE");
	Slider(xpos, (ypos++)*18, p_freq_dramp, true, "DELTA SLIDE");

	Slider(xpos, (ypos++)*18, p_vib_strength, false, "VIBRATO DEPTH");
	Slider(xpos, (ypos++)*18, p_vib_speed, false, "VIBRATO SPEED");

	DrawBar(xpos-190, ypos*18-5, 300, 2, 0x0000000);

	Slider(xpos, (ypos++)*18, p_arp_mod, true, "CHANGE AMOUNT");
	Slider(xpos, (ypos++)*18, p_arp_speed, false, "CHANGE SPEED");

	DrawBar(xpos-190, ypos*18-5, 300, 2, 0x0000000);

	Slider(xpos, (ypos++)*18, p_duty, false, "SQUARE DUTY");
	Slider(xpos, (ypos++)*18, p_duty_ramp, true, "DUTY SWEEP");

	DrawBar(xpos-190, ypos*18-5, 300, 2, 0x0000000);

	Slider(xpos, (ypos++)*18, p_repeat_speed, false, "REPEAT SPEED");

	DrawBar(xpos-190, ypos*18-5, 300, 2, 0x0000000);

	Slider(xpos, (ypos++)*18, p_pha_offset, true, "PHASER OFFSET");
	Slider(xpos, (ypos++)*18, p_pha_ramp, true, "PHASER SWEEP");

	DrawBar(xpos-190, ypos*18-5, 300, 2, 0x0000000);

	Slider(xpos, (ypos++)*18, p_lpf_freq, false, "LP FILTER CUTOFF");
	Slider(xpos, (ypos++)*18, p_lpf_ramp, true, "LP FILTER CUTOFF SWEEP");
	Slider(xpos, (ypos++)*18, p_lpf_resonance, false, "LP FILTER RESONANCE");
	Slider(xpos, (ypos++)*18, p_hpf_freq, false, "HP FILTER CUTOFF");
	Slider(xpos, (ypos++)*18, p_hpf_ramp, true, "HP FILTER CUTOFF SWEEP");

	DrawBar(xpos-190, ypos*18-5, 300, 2, 0x0000000);

	DrawBar(xpos-190, 4*18-5, 1, (ypos-4)*18, 0x0000000);
	DrawBar(xpos-190+299, 4*18-5, 1, (ypos-4)*18, 0x0000000);

	if(do_play)
		PlaySample();

	ddkUnlock();

	if(!mouse_left)
		vcurbutton=-1;
}
예제 #5
0
void	HandleDirection( int actcode )
{
Sprite 			*s;
	int		umove=0;
	int		dmove=0;
	int		lmove=0;
	int		rmove=0;
static	int		step=2;
static	int		cnt=0;
static	int		zcnt=0;
static	int		lastc=0;


	if ( realcode == 0xee )
	{
		if ( step == 2 )
			return;
		zcnt++;
		if ( zcnt > 3 )
		{
			step=2;
			cnt=0;
			zcnt=0;
		}
		return;
	}

	cnt++;
	if( cnt > 8 )
		step=32;
	else if( cnt > 6 )
		step=16;
	else if( cnt > 4 )
		step=8;
	else if( cnt > 2 )
		step=4;
	else
		step=2;

	if (( step != 2 ) && ( actcode != lastc )){
		cnt=0;
		step=2;
	}

	lastc=actcode;
	if ( action > 2 )
		return;
	s=deko[0];
	if (!s)
		return;
	switch (actcode){
#ifdef KEY_TOPLEFT
	case KEY_TOPLEFT:
		umove=1;lmove=1;break;
	case KEY_TOPRIGHT:
		umove=1;rmove=1;break;
	case KEY_BOTTOMLEFT:
		dmove=1;lmove=1;break;
	case KEY_BOTTOMRIGHT:
		dmove=1;rmove=1;break;
#endif
	case RC_UP:
		umove=1;break;
	case RC_DOWN:
		dmove=1;break;
	case RC_LEFT:
		lmove=1;break;
	case RC_RIGHT:
		rmove=1;break;
	}

	if ((lmove||rmove)&&(( s->x == main_x - 6 )||(s->x == main_x + 320)))	// move screen
	{
		int new_x;
		if (s->x == main_x - 6){
			main_x -= step;
			new_x = main_x;
			dblXMove( 0, step );
		} else { // (s->x == main_x + 320)
			main_x += step;
			new_x = main_x+328-step;
			dblXMove( step, 0 );
		}
		CopyBg2Screen( new_x, 0, step, 160 );
		SpriteGetBackground( s );
		pic_moved=1;		// mark for redraw unanimated deko-sprites
		return;
	}
	// all other movements
	UndrawSprite( s );
	if ((lmove)&&(s->x >= 32)){
		s->x -= step;
		if ( s->x < main_x - 6 )
			s->x = main_x - 6;
	} 
	if ((rmove)&&(s->x <= 1580)){
		s->x += step;
		if ( s->x > main_x + 320 )
			s->x = main_x + 320;
	}
	if ((umove)&&(s->y > -6)){
		s->y -= step;
		if ( s->y < -6 )
			s->y = -6;
	}
	if ((dmove)&&(s->y < 152)){
		s->y += step;
		if ( s->y > 152 )
			s->y = 152;
	}
	SpriteGetBackground( s );
	DrawSprite( s );
}
예제 #6
0
void TextureManager::DrawSprite(const FRECT *dst, size_t sprite, SpriteColor color, unsigned int frame) const
{
	DrawSprite(sprite, frame, color, dst->left, dst->top, dst->right - dst->left, dst->bottom - dst->top, vec2d(1,0));
}
예제 #7
0
void GraphicsCaptureSource::Render(const Vect2 &pos, const Vect2 &size)
{
    if(capture)
    {
        Shader *lastShader = GetCurrentPixelShader();

        float fGamma = float(-(gamma-100) + 100) * 0.01f;

        LoadPixelShader(drawShader);
        HANDLE hGamma = drawShader->GetParameterByName(TEXT("gamma"));
        if(hGamma)
            drawShader->SetFloat(hGamma, fGamma);

        //----------------------------------------------------------
        // capture mouse

        bMouseCaptured = false;
        if(bCaptureMouse)
        {
            CURSORINFO ci;
            zero(&ci, sizeof(ci));
            ci.cbSize = sizeof(ci);

            if(GetCursorInfo(&ci) && hwndCapture)
            {
                mcpy(&cursorPos, &ci.ptScreenPos, sizeof(cursorPos));

                ScreenToClient(hwndCapture, &cursorPos);

                if(ci.flags & CURSOR_SHOWING)
                {
                    if(ci.hCursor == hCurrentCursor)
                        bMouseCaptured = true;
                    else
                    {
                        HICON hIcon = CopyIcon(ci.hCursor);
                        hCurrentCursor = ci.hCursor;

                        delete cursorTexture;
                        cursorTexture = NULL;

                        if(hIcon)
                        {
                            ICONINFO ii;
                            if(GetIconInfo(hIcon, &ii))
                            {
                                xHotspot = int(ii.xHotspot);
                                yHotspot = int(ii.yHotspot);

                                UINT width, height;
                                LPBYTE lpData = GetCursorData(hIcon, ii, width, height);
                                if(lpData)
                                {
                                    cursorTexture = CreateTexture(width, height, GS_BGRA, lpData, FALSE);
                                    if(cursorTexture)
                                        bMouseCaptured = true;

                                    Free(lpData);
                                }

                                DeleteObject(ii.hbmColor);
                                DeleteObject(ii.hbmMask);
                            }

                            DestroyIcon(hIcon);
                        }
                    }
                }
            }
        }

        //----------------------------------------------------------
        // game texture

        Texture *tex = capture->LockTexture();

        Vect2 texPos = Vect2(0.0f, 0.0f);
        Vect2 texStretch = Vect2(1.0f, 1.0f);

        if(tex)
        {
            Vect2 texSize = Vect2(float(tex->Width()), float(tex->Height()));
            Vect2 totalSize = API->GetBaseSize();

            Vect2 center = totalSize*0.5f;

            BlendFunction(GS_BLEND_ONE, GS_BLEND_ZERO);

            if(bStretch)
            {
                if(bIgnoreAspect)
                    texStretch *= totalSize;
                else
                {
                    float multiplyVal = (texSize.y * (totalSize.x / texSize.x) > totalSize.y) ? totalSize.y / texSize.y : multiplyVal = totalSize.x / texSize.x;
                        
                    texStretch *= texSize*multiplyVal;
                    texPos = center-(texStretch*0.5f);
                }
            }
            else
            {
                texStretch *= texSize;
                texPos = center-(texStretch*0.5f);
            }

            Vect2 sizeAdjust = size/totalSize;
            texPos *= sizeAdjust;
            texPos += pos;
            texStretch *= sizeAdjust;

            RoundVect2(texPos);
            RoundVect2(texSize);

            if(bFlip)
                DrawSprite(tex, 0xFFFFFFFF, texPos.x, texPos.y+texStretch.y, texPos.x+texStretch.x, texPos.y);
            else
                DrawSprite(tex, 0xFFFFFFFF, texPos.x, texPos.y, texPos.x+texStretch.x, texPos.y+texStretch.y);

            capture->UnlockTexture();

            BlendFunction(GS_BLEND_SRCALPHA, GS_BLEND_INVSRCALPHA);

            //----------------------------------------------------------
            // draw mouse

            if(bMouseCaptured && cursorTexture && GetForegroundWindow() == hwndCapture)
            {
                Vect2 newCursorPos  = Vect2(float(cursorPos.x-xHotspot), float(cursorPos.y-xHotspot));
                Vect2 newCursorSize = Vect2(float(cursorTexture->Width()), float(cursorTexture->Height()));

                newCursorPos  /= texSize;
                newCursorSize /= texSize;

                newCursorPos *= texStretch;
                newCursorPos += texPos;

                newCursorSize *= texStretch;

                bool bInvertCursor = false;
                if(invertShader)
                {
                    if(bInvertCursor = ((GetAsyncKeyState(VK_LBUTTON) & 0x8000) != 0 || (GetAsyncKeyState(VK_RBUTTON) & 0x8000) != 0))
                        LoadPixelShader(invertShader);
                }

                DrawSprite(cursorTexture, 0xFFFFFFFF, newCursorPos.x, newCursorPos.y, newCursorPos.x+newCursorSize.x, newCursorPos.y+newCursorSize.y);
            }
        }

        if(lastShader)
            LoadPixelShader(lastShader);
    }
}
예제 #8
0
HRESULT CBSurfaceSDL::DisplayTransOffset(int X, int Y, RECT rect, uint32 Alpha, TSpriteBlendMode BlendMode, bool MirrorX, bool MirrorY, int offsetX, int offsetY) {
	return DrawSprite(X, Y, &rect, 100, 100, Alpha, false, BlendMode, MirrorX, MirrorY, offsetX, offsetY);
}
예제 #9
0
HRESULT CBSurfaceSDL::DisplayZoom(int X, int Y, RECT rect, float ZoomX, float ZoomY, uint32 Alpha, bool Transparent, TSpriteBlendMode BlendMode, bool MirrorX, bool MirrorY) {
	return DrawSprite(X, Y, &rect, ZoomX, ZoomY, Alpha, !Transparent, BlendMode, MirrorX, MirrorY);
}
예제 #10
0
void Spit::Draw()
{	
	if ( active ) 
		DrawSprite(sprite);
}
예제 #11
0
HRESULT CBSurfaceSDL::Display(int X, int Y, RECT rect, TSpriteBlendMode BlendMode, bool MirrorX, bool MirrorY) {
	return DrawSprite(X, Y, &rect, 100, 100, 0xFFFFFFFF, true, BlendMode, MirrorX, MirrorY);
}
예제 #12
0
void AI::DrawAI()
{
	DrawSprite(textureHandler);
}
예제 #13
0
void DrawPause(void)
{
	LevelToDraw();
	DrawSprite(PauseText);
	DrawCollisionList();
}
예제 #14
0
파일: train_gui.cpp 프로젝트: Voxar/OpenTTD
/**
 * Draw the details for the given vehicle at the given position
 *
 * @param v     current vehicle
 * @param left  The left most coordinate to draw
 * @param right The right most coordinate to draw
 * @param y     The y coordinate
 * @param vscroll_pos Position of scrollbar
 * @param vscroll_cap Number of lines currently displayed
 * @param det_tab Selected details tab
 */
void DrawTrainDetails(const Train *v, int left, int right, int y, int vscroll_pos, uint16 vscroll_cap, TrainDetailsWindowTabs det_tab)
{
	/* draw the first 3 details tabs */
	if (det_tab != TDW_TAB_TOTALS) {
		bool rtl = _dynlang.text_dir == TD_RTL;
		Direction dir = rtl ? DIR_E : DIR_W;
		int x = rtl ? right : left;
		int sprite_y_offset = 4 + (FONT_HEIGHT_NORMAL - 10) / 2;
		int line_height = WD_MATRIX_TOP + FONT_HEIGHT_NORMAL + WD_MATRIX_BOTTOM;
		for (; v != NULL && vscroll_pos > -vscroll_cap; v = v->GetNextVehicle()) {
			GetCargoSummaryOfArticulatedVehicle(v, &_cargo_summary);

			/* Draw sprites */
			int dx = 0;
			int px = x;
			const Train *u = v;
			do {
				Point offset;
				int width = u->GetDisplayImageWidth(&offset);
				if (vscroll_pos <= 0 && vscroll_pos > -vscroll_cap) {
					SpriteID pal = (v->vehstatus & VS_CRASHED) ? PALETTE_CRASH : GetVehiclePalette(v);
					DrawSprite(u->GetImage(dir), pal, px + (rtl ? -offset.x : offset.x), y - line_height * vscroll_pos + sprite_y_offset + offset.y);
				}
				px += rtl ? -width : width;
				dx += width;
				u = u->Next();
			} while (u != NULL && u->IsArticulatedPart());

			bool separate_sprite_row = (dx > TRAIN_DETAILS_MAX_INDENT);
			if (separate_sprite_row) {
				vscroll_pos--;
				dx = 0;
			}

			uint num_lines = max(1u, _cargo_summary.Length());
			for (uint i = 0; i < num_lines; i++) {
				int sprite_width = max<int>(dx, TRAIN_DETAILS_MIN_INDENT) + 3;
				int data_left  = left + (rtl ? 0 : sprite_width);
				int data_right = right - (rtl ? sprite_width : 0);
				if (vscroll_pos <= 0 && vscroll_pos > -vscroll_cap) {
					int py = y - line_height * vscroll_pos;
					if (i > 0 || separate_sprite_row) {
						if (vscroll_pos != 0) GfxFillRect(left, py - WD_MATRIX_TOP - 1, right, py - WD_MATRIX_TOP, _colour_gradient[COLOUR_GREY][5]);
					}
					switch (det_tab) {
						case TDW_TAB_CARGO:
							if (i < _cargo_summary.Length()) {
								TrainDetailsCargoTab(&_cargo_summary[i], data_left, data_right, py);
							} else {
								DrawString(data_left, data_right, py, STR_QUANTITY_N_A, TC_LIGHT_BLUE);
							}
							break;

						case TDW_TAB_INFO:
							if (i == 0) TrainDetailsInfoTab(v, data_left, data_right, py);
							break;

						case TDW_TAB_CAPACITY:
							if (i < _cargo_summary.Length()) {
								TrainDetailsCapacityTab(&_cargo_summary[i], data_left, data_right, py);
							} else {
								DrawString(data_left, data_right, py, STR_VEHICLE_INFO_NO_CAPACITY);
							}
							break;

						default: NOT_REACHED();
					}
				}
				vscroll_pos--;
			}
		}
	} else {
		CargoArray act_cargo;
		CargoArray max_cargo;
		Money feeder_share = 0;

		for (const Vehicle *u = v; u != NULL; u = u->Next()) {
			act_cargo[u->cargo_type] += u->cargo.Count();
			max_cargo[u->cargo_type] += u->cargo_cap;
			feeder_share             += u->cargo.FeederShare();
		}

		/* draw total cargo tab */
		DrawString(left, right, y, STR_VEHICLE_DETAILS_TRAIN_TOTAL_CAPACITY_TEXT);
		y += WD_MATRIX_TOP + FONT_HEIGHT_NORMAL + WD_MATRIX_BOTTOM;

		for (CargoID i = 0; i < NUM_CARGO; i++) {
			if (max_cargo[i] > 0 && --vscroll_pos < 0 && vscroll_pos > -vscroll_cap) {
				SetDParam(0, i);            // {CARGO} #1
				SetDParam(1, act_cargo[i]); // {CARGO} #2
				SetDParam(2, i);            // {SHORTCARGO} #1
				SetDParam(3, max_cargo[i]); // {SHORTCARGO} #2
				SetDParam(4, _settings_game.vehicle.freight_trains);
				DrawString(left, right, y, FreightWagonMult(i) > 1 ? STR_VEHICLE_DETAILS_TRAIN_TOTAL_CAPACITY_MULT : STR_VEHICLE_DETAILS_TRAIN_TOTAL_CAPACITY);
				y += WD_MATRIX_TOP + FONT_HEIGHT_NORMAL + WD_MATRIX_BOTTOM;
			}
		}
		SetDParam(0, feeder_share);
		DrawString(left, right, y, STR_VEHICLE_INFO_FEEDER_CARGO_VALUE);
	}
}
예제 #15
0
	void SpriteRenderer3D::EndDrawing()
	{
		DrawSprite();
	}
예제 #16
0
HRESULT CBSurfaceSDL::DisplayTransform(int X, int Y, int HotX, int HotY, RECT Rect, float ZoomX, float ZoomY, uint32 Alpha, float Rotate, TSpriteBlendMode BlendMode, bool MirrorX, bool MirrorY) {
	return DrawSprite(X, Y, &Rect, ZoomX, ZoomY, Alpha, false, BlendMode, MirrorX, MirrorY);
}
예제 #17
0
/**
 * Draw the icon of a company.
 * @param c Company that needs its icon drawn.
 * @param x Horizontal coordinate of the icon.
 * @param y Vertical coordinate of the icon.
 */
void DrawCompanyIcon(CompanyID c, int x, int y)
{
	DrawSprite(SPR_COMPANY_ICON, COMPANY_SPRITE_COLOUR(c), x, y);
}
예제 #18
0
//-----------------------------------------------------------------------------
// Purpose: Third-person function call to render world model
//-----------------------------------------------------------------------------
int CWeaponGravityGun::DrawModel( int flags )
{
	// Only render these on the transparent pass
	if ( flags & STUDIO_TRANSPARENCY )
	{
		if ( !m_active )
			return 0;

		C_BasePlayer *pOwner = ToBasePlayer( GetOwner() );

		if ( !pOwner )
			return 0;

		Vector points[3];
		QAngle tmpAngle;

		C_BaseEntity *pObject = m_hObject;
		//if ( pObject == NULL )
		//	return 0;

		GetAttachment( 1, points[0], tmpAngle );

		// a little noise 11t & 13t should be somewhat non-periodic looking
		//points[1].z += 4*sin( gpGlobals->curtime*11 ) + 5*cos( gpGlobals->curtime*13 );
		if ( pObject == NULL )
		{
			//points[2] = m_targetPosition;
			trace_t tr;
			TraceLine( &tr );
			points[2] = tr.endpos;
		}
		else
		{
			pObject->EntityToWorldSpace( m_worldPosition, &points[2] );
		}

		Vector forward, right, up;
		QAngle playerAngles = pOwner->EyeAngles();
		AngleVectors( playerAngles, &forward, &right, &up );
		if ( pObject == NULL )
		{
			Vector vecDir = points[2] - points[0];
			VectorNormalize( vecDir );
			points[1] = points[0] + 0.5f * (vecDir * points[2].DistTo(points[0]));
		}
		else
		{
			Vector vecSrc = pOwner->Weapon_ShootPosition( );
			points[1] = vecSrc + 0.5f * (forward * points[2].DistTo(points[0]));
		}
		
		IMaterial *pMat = materials->FindMaterial( "sprites/physbeam1", TEXTURE_GROUP_CLIENT_EFFECTS );
		if ( pObject )
			pMat = materials->FindMaterial( "sprites/physbeam", TEXTURE_GROUP_CLIENT_EFFECTS );
		Vector color;
		color.Init(1,1,1);

		float scrollOffset = gpGlobals->curtime - (int)gpGlobals->curtime;
		CMatRenderContextPtr pRenderContext( materials );
		pRenderContext->Bind( pMat );
		DrawBeamQuadratic( points[0], points[1], points[2], pObject ? 13/3.0f : 13/5.0f, color, scrollOffset );
		DrawBeamQuadratic( points[0], points[1], points[2], pObject ? 13/3.0f : 13/5.0f, color, -scrollOffset );

		IMaterial *pMaterial = materials->FindMaterial( "sprites/physglow", TEXTURE_GROUP_CLIENT_EFFECTS );

		color32 clr={0,64,255,255};
		if ( pObject )
		{
			clr.r = 186;
			clr.g = 253;
			clr.b = 247;
			clr.a = 255;
		}

		float scale = random->RandomFloat( 3, 5 ) * ( pObject ? 3 : 2 );

		// Draw the sprite
		pRenderContext->Bind( pMaterial );
		for ( int i = 0; i < 3; i++ )
		{
			DrawSprite( points[2], scale, scale, clr );
		}
		return 1;
	}

	// Only do this on the opaque pass
	return BaseClass::DrawModel( flags );
}
예제 #19
0
    void ParticleManager::DrawParticle( Particle *p )
    {
        if (p->GetAge() != 0 || p->GetEmitter()->IsSingleParticle())
        {
            _px = TweenValues(p->GetOldWX(), p->GetWX(), _currentTween);
            _py = TweenValues(p->GetOldWY(), p->GetWY(), _currentTween);

            if (_angle != 0)
            {
                Vector2 rotVec = _matrix.TransformVector(Vector2(_px, _py));
                _px = (rotVec.x * _camtz) + _centerX + (_camtz * _camtx);
                _py = (rotVec.y * _camtz) + _centerY + (_camtz * _camty);
            }
            else
            {
                _px = (_px * _camtz) + _centerX + (_camtz * _camtx);
                _py = (_py * _camtz) + _centerY + (_camtz * _camty);
            }

            if (_px > _vpX - p->GetImageDiameter() && _px < _vpX + _vpW + p->GetImageDiameter() && _py > _vpY - p->GetImageDiameter() && _py < _vpY + _vpH + p->GetImageDiameter())
            {
                if (p->GetAvatar())
                {
                    AnimImage *sprite;
                    float x, y;

                    if (p->GetEmitter()->IsHandleCenter())
                    {
                        if (p->GetAvatar()->GetFramesCount() == 1)
                        {
                            //MidHandleImage(p->GetAvatar()->GetImage());
                            sprite = p->GetAvatar();
                            x = sprite->GetWidth() / 2.0f;
                            y = sprite->GetHeight() / 2.0f;
                        }
                        else
                        {
                            //SetImageHandle(p->GetAvatar()->GetImage(), p->GetAvatar()->GetWidth() / 2.f, p->GetAvatar()->GetHeight() / 2.f);
                            sprite = p->GetAvatar();
                            x = sprite->GetWidth() / 2.0f;
                            y = sprite->GetHeight() / 2.0f;
                        }
                    }
                    else
                    {
                        //SetImageHandle(p->GetAvatar()->GetImage(), p->GetHandleX(), p->GetHandleY());
                        sprite = p->GetAvatar();
                        x = (float)p->GetHandleX();
                        y = (float)p->GetHandleY();
                    }

                    //SetBlend(p->GetEmitter()->GetBlendMode());
                    Emitter::BlendMode blend = p->GetEmitter()->GetBlendMode();

                    float rotation;

                    _tv = TweenValues(p->GetOldAngle(), p->GetAngle(), _currentTween);
                    if (p->GetEmitter()->IsAngleRelative())
                    {
                        if (fabsf(p->GetOldRelativeAngle() - p->GetRelativeAngle()) > 180)
                            _tx = TweenValues(p->GetOldRelativeAngle() - 360, p->GetRelativeAngle(), _currentTween);
                        else
                            _tx = TweenValues(p->GetOldRelativeAngle(), p->GetRelativeAngle(), _currentTween);
                        //SetRotation(_tv + _tx + _angleTweened);
                        rotation = _tv + _tx + _angleTweened;
                    }
                    else
                    {
                        //SetRotation(_tv + _angleTweened);
                        rotation = _tv + _angleTweened;
                    }

                    float scaleX, scaleY;

                    _tx = TweenValues(p->GetOldScaleX(), p->GetScaleX(), _currentTween);
                    _ty = TweenValues(p->GetOldScaleY(), p->GetScaleY(), _currentTween);
                    _tz = TweenValues(p->GetOldZ(), p->GetZ(), _currentTween);
                    if (_tz != 1.0f)
                    {
                        //SetScale(_tx * _tz * _camtz, _ty * _tz * _camtz);
                        scaleX = _tx * _tz * _camtz;
                        scaleY = _ty * _tz * _camtz;
                    }
                    else
                    {
                        //SetScale(_tx * _camtz, _ty * _camtz);
                        scaleX = _tx * _camtz;
                        scaleY = _ty * _camtz;
                    }

                    unsigned char r, g, b;
                    float a;
                    //SetAlpha(p->GetAlpha());
                    //SetColor(p->GetRed(), p->GetGreen(), p->GetBlue());
                    a = p->GetEntityAlpha();
                    r = p->GetRed();
                    g = p->GetGreen();
                    b = p->GetBlue();

                    if (p->IsAnimating())
                    {
                        _tv = TweenValues(p->GetOldCurrentFrame(), p->GetCurrentFrame(), _currentTween);
                        if (_tv < 0)
                        {
                            _tv = p->GetAvatar()->GetFramesCount() + (fmodf(_tv, (float)p->GetAvatar()->GetFramesCount()));
                            if (_tv == p->GetAvatar()->GetFramesCount())
                                _tv = 0;
                        }
                        else
                        {
                            _tv = fmodf(_tv, (float)p->GetAvatar()->GetFramesCount());
                        }
                    }
                    else
                    {
                        _tv = p->GetCurrentFrame();
                    }
                    DrawSprite(sprite, _px, _py, _tv, x, y, rotation, scaleX, scaleY, r, g, b, a, blend == Emitter::BMLightBlend);
                    // ++rendercount
                }
            }
        }
    }
예제 #20
0
//-----------------------------------------------------------------------------
// Purpose: First-person function call after viewmodel has been drawn
//-----------------------------------------------------------------------------
void CWeaponGravityGun::ViewModelDrawn( C_BaseViewModel *pBaseViewModel )
{
	if ( !m_active )
		return;

	// Render our effects
	C_BasePlayer *pOwner = ToBasePlayer( GetOwner() );

	if ( !pOwner )
		return;

	Vector points[3];
	QAngle tmpAngle;

	C_BaseEntity *pObject = m_hObject;
	//if ( pObject == NULL )
	//	return;

	pBaseViewModel->GetAttachment( 1, points[0], tmpAngle );

	// a little noise 11t & 13t should be somewhat non-periodic looking
	//points[1].z += 4*sin( gpGlobals->curtime*11 ) + 5*cos( gpGlobals->curtime*13 );
	if ( pObject == NULL )
	{
		//points[2] = m_targetPosition;
		trace_t tr;
		TraceLine( &tr );
		points[2] = tr.endpos;
	}
	else
	{
		pObject->EntityToWorldSpace(m_worldPosition, &points[2]);
	}

	Vector forward, right, up;
	QAngle playerAngles = pOwner->EyeAngles();
	AngleVectors( playerAngles, &forward, &right, &up );
	Vector vecSrc = pOwner->Weapon_ShootPosition( );
	points[1] = vecSrc + 0.5f * (forward * points[2].DistTo(points[0]));
	
	IMaterial *pMat = materials->FindMaterial( "sprites/physbeam1", TEXTURE_GROUP_CLIENT_EFFECTS );
	if ( pObject )
		pMat = materials->FindMaterial( "sprites/physbeam", TEXTURE_GROUP_CLIENT_EFFECTS );
	Vector color;
	color.Init(1,1,1);

	// Now draw it.
	CViewSetup beamView = *view->GetPlayerViewSetup();

	Frustum dummyFrustum;
	render->Push3DView( beamView, 0, NULL, dummyFrustum );

	float scrollOffset = gpGlobals->curtime - (int)gpGlobals->curtime;
	CMatRenderContextPtr pRenderContext( materials );
	pRenderContext->Bind( pMat );
#if 1
	// HACK HACK:  Munge the depth range to prevent view model from poking into walls, etc.
	// Force clipped down range
	pRenderContext->DepthRange( 0.1f, 0.2f );
#endif
	DrawBeamQuadratic( points[0], points[1], points[2], pObject ? 13/3.0f : 13/5.0f, color, scrollOffset );
	DrawBeamQuadratic( points[0], points[1], points[2], pObject ? 13/3.0f : 13/5.0f, color, -scrollOffset );

	IMaterial *pMaterial = materials->FindMaterial( "sprites/physglow", TEXTURE_GROUP_CLIENT_EFFECTS );

	color32 clr={0,64,255,255};
	if ( pObject )
	{
		clr.r = 186;
		clr.g = 253;
		clr.b = 247;
		clr.a = 255;
	}

	float scale = random->RandomFloat( 3, 5 ) * ( pObject ? 3 : 2 );

	// Draw the sprite
	pRenderContext->Bind( pMaterial );
	for ( int i = 0; i < 3; i++ )
	{
		DrawSprite( points[2], scale, scale, clr );
	}
#if 1
	pRenderContext->DepthRange( 0.0f, 1.0f );
#endif

	render->PopView( dummyFrustum );

	// Pass this back up
	BaseClass::ViewModelDrawn( pBaseViewModel );
}
/**
 * Engine drawing loop
 * @param type Type of vehicle (VEH_*)
 * @param l The left most location of the list
 * @param r The right most location of the list
 * @param y The top most location of the list
 * @param eng_list What engines to draw
 * @param min where to start in the list
 * @param max where in the list to end
 * @param selected_id what engine to highlight as selected, if any
 * @param show_count Whether to show the amount of engines or not
 * @param selected_group the group to list the engines of
 */
void DrawEngineList(VehicleType type, int l, int r, int y, const GUIEngineList *eng_list, uint16 min, uint16 max, EngineID selected_id, bool show_count, GroupID selected_group)
{
	static const int sprite_y_offsets[] = { -1, -1, -2, -2 };

	/* Obligatory sanity checks! */
	assert(max <= eng_list->Length());

	bool rtl = _current_text_dir == TD_RTL;
	int step_size = GetEngineListHeight(type);
	int sprite_left  = GetVehicleImageCellSize(type, EIT_PURCHASE).extend_left;
	int sprite_right = GetVehicleImageCellSize(type, EIT_PURCHASE).extend_right;
	int sprite_width = sprite_left + sprite_right;

	int sprite_x        = rtl ? r - sprite_right - 1 : l + sprite_left + 1;
	int sprite_y_offset = sprite_y_offsets[type] + step_size / 2;

	Dimension replace_icon = {0, 0};
	int count_width = 0;
	if (show_count) {
		replace_icon = GetSpriteSize(SPR_GROUP_REPLACE_ACTIVE);
		SetDParamMaxDigits(0, 3);
		count_width = GetStringBoundingBox(STR_TINY_BLACK_COMA).width;
	}

	int text_left  = l + (rtl ? WD_FRAMERECT_LEFT + replace_icon.width + 8 + count_width : sprite_width + WD_FRAMETEXT_LEFT);
	int text_right = r - (rtl ? sprite_width + WD_FRAMETEXT_RIGHT : WD_FRAMERECT_RIGHT + replace_icon.width + 8 + count_width);
	int replace_icon_left = rtl ? l + WD_FRAMERECT_LEFT : r - WD_FRAMERECT_RIGHT - replace_icon.width;
	int count_left = l;
	int count_right = rtl ? text_left : r - WD_FRAMERECT_RIGHT - replace_icon.width - 8;

	int normal_text_y_offset = (step_size - FONT_HEIGHT_NORMAL) / 2;
	int small_text_y_offset  = step_size - FONT_HEIGHT_SMALL - WD_FRAMERECT_BOTTOM - 1;
	int replace_icon_y_offset = (step_size - replace_icon.height) / 2 - 1;

	for (; min < max; min++, y += step_size) {
		const EngineID engine = (*eng_list)[min];
		/* Note: num_engines is only used in the autoreplace GUI, so it is correct to use _local_company here. */
		const uint num_engines = GetGroupNumEngines(_local_company, selected_group, engine);

		SetDParam(0, engine);
		DrawString(text_left, text_right, y + normal_text_y_offset, STR_ENGINE_NAME, engine == selected_id ? TC_WHITE : TC_BLACK, SA_STRIP | (rtl ? SA_RIGHT : SA_LEFT));
		DrawVehicleEngine(l, r, sprite_x, y + sprite_y_offset, engine, (show_count && num_engines == 0) ? PALETTE_CRASH : GetEnginePalette(engine, _local_company), EIT_PURCHASE);
		if (show_count) {
			SetDParam(0, num_engines);
			DrawString(count_left, count_right, y + small_text_y_offset, STR_TINY_BLACK_COMA, TC_FROMSTRING, SA_RIGHT | SA_FORCE);
			if (EngineHasReplacementForCompany(Company::Get(_local_company), engine, selected_group)) DrawSprite(SPR_GROUP_REPLACE_ACTIVE, num_engines == 0 ? PALETTE_CRASH : PAL_NONE, replace_icon_left, y + replace_icon_y_offset);
		}
	}
}
예제 #22
0
파일: window.c 프로젝트: FratStar/AlienRush
void DrawMouse()
{
  DrawSprite(Mouse.sprite,screen,Mouse.mx,Mouse.my,Mouse.mframe);
}
예제 #23
0
void	RunLemm( void )
{
static	int		counter1=0;
static	int		blinkc=0;
	int			i;
	int			f;
	int			b;
	Sprite		*s;
	int			cursor_get=0;
	int			kab=0;
	int			hbk=0;	// hat boden kontakt
//int			hhy=0;

	blinkc++;

	if ( action==3 )
	{
		counter1=0;
		action=4;
		DrawSprite( deko[0] );
		return;
	}
	if ( action==4 )
	{
		counter1++;
		if ( counter1 < 24 )
			return;

		if ( to_rescue > lem_in )
		{
			FBDrawString( 252, 142, 64, "You lost !", WHITE, 0 );
			FBDrawString( 250, 140, 64, "You lost !", RED, 0 );
		}
		else
		{
			level++;
			if ( level>LASTLEVEL )
			{
				FBDrawString( 252, 142, 64, "all level solved", WHITE, 0 );
				FBDrawString( 250, 140, 64, "all level solved", GREEN, 0 );
				FBDrawString( 240, 250, 36, "thanx to emuman for his javacode,", WHITE, 0 );
				FBDrawString( 240, 286, 36, "Psygnosis and DMA for artwork...", WHITE, 0 );
				level=1;
				doexit=2;
				return;
			}
			else
			{
				FBDrawString( 252, 142, 64, "Level solved", WHITE, 0 );
				FBDrawString( 250, 140, 64, "Level solved", GREEN, 0 );
			}
		}
		if ( afunc != -1 )
			FBCopyImage( (afunc+2)*32+32, 384, 32, 48, svdimage[afunc+2] );
		action=5;
		doexit=1;
	}

	if ( action != 2 )
	{
		DrawSprite( deko[0] );
		return;
	}
	if ( pause )
	{
		UndrawSprite( deko[0] );
		for( i=0; i<lem_run; i++ )
		{
			if ( !lemm[i] )
				continue;
			UndrawSprite( lemm[i] );
		}
		DrawSprite( deko[1] );		// ziel
		DrawSprite( deko[2] );		// ziel
		for( i=0; i<lem_run; i++ )
		{
			if ( !lemm[i] )
				continue;
			s=lemm[i];
			if (( s->type & TYP_EXPLODE ) && ( s->countdown > 0 ))
			{
				DrawSimpleNumber( s->x-main_x, s->y-6, s->countdown, 1 );
			}
			SpriteGetBackground( s );
			DrawSprite( s );
		}
		SpriteSelPic( deko[0], 0 );
		SpriteGetBackground( deko[0] );
		DrawSprite( deko[0] );

		if ( blinkc%5 )
			return;
		if ( pause == 1 )
		{
			FBCopyImage( 10*32+32, 384, 32, 48, svdimage[10] );
			pause=2;
		}
		else
		{
			FBDrawRect( 10*32+32, 384, 31, 47, BLUE );
			FBDrawRect( 10*32+33, 385, 29, 45, BLUE );
			pause=1;
		}
		return;
	}

	sel_sprite=-1;

	if (( lem_run < lem_cnt ) && !( counter1%((newspeed/2)+3) ) && !killall )
	{
		lemm[ lem_run ] = CreateSprite(3,0,deko[1]->x+19,deko[1]->y);
		lemm[ lem_run ]->dir=0;		// rechts
		lemm[ lem_run ]->type = TYP_WALKER;

		in_level++;
		lem_run++;
		DrawInfo(1);
	}
	if ( in_level )
		UndrawSprite( deko[0] );
	for( i=0; i<lem_run; i++ )
	{
		if ( !lemm[i] )
			continue;
		s=lemm[i];
		if ( s->type & TYP_EXPLODE )
			restorecd( i );
		else if (( s->type & TYP_FALLEN ) && s->partikel )
			restorecd( i );
		UndrawSprite( s );
		s->counter1++;
		if ( !( s->counter1 % 10 ) && ( s->type & TYP_EXPLODE ) )
		{
			s->countdown--;
			if ( s->countdown == -1 )
			{
				s->counter1=0;
				bg2CopyImage( s->x-7, s->y-4, 21, 21, pbomb );
				CopyBg2Screen( s->x-7,s->y-4, 21, 21);
			}
		}
		if (( s->counter1 == 2 ) && ( s->type & TYP_STOPPER ) &&
			!( s->type & TYP_EXPLODE ))
			bgRect( s->x+1, s->y, s->width-1, s->height-2, 150 );
	}
//	DrawSprite( deko[2] );		// ziel
	UnanimatedDeko();
	for( i=0; i<lem_run; i++ )
	{
		if ( !lemm[i] )
			continue;

		s=lemm[i];

		if ( killall && !kab )
		{
			if ( !(s->type & TYP_EXPLODE ) )
			{
				s->type |= TYP_EXPLODE;
				s->counter1=1;
				kab++;
			}
		}

		if ( (s->countdown==-1) && ( s->type & TYP_EXPLODE ) )
		{
			s->partikel=1;
			partikel(i,1);
		}
		if ( !( s->counter1 % 10 ) && ( s->type & TYP_EXPLODE ) )
		{
			if ( s->countdown == -1 )
			{
				s->y-=4;
				s->x-=4;
				SpriteChangePic( s, 8 );		// explosion
				SpriteGetBackground( s );
				DrawSprite(s);
				SoundPlay( SND_EXPLODE );
			}
			if ( s->countdown == -2 )
			{
				partikel(i,0);
				killlem( i );
				s=0;
				DrawInfo(1);
			}
		}

		if ( s && ( s->countdown < 0 ))
			s=0;

		if ( s && ( s->type & TYP_FALLEN ) )
		{
			if ( s->counter1 < 10 )
			{
				s->partikel=1;
				partikel(i,1);
			}
			else
			{
				killlem( i );
				DrawInfo(1);
			}
			s=0;
		}

		if ( s&&(s->countdown>0) )
		{
			SpriteNextPic( s );
			if ( s->type&TYP_ATHOME )
			{
				s->y-=1;
				if(s->ani==4)
				{
					lem_in++;
					killlem(i);
					SoundPlay( SND_OING );
					DrawInfo(3);
				}
			}
			else
			{	/* lemming im ziel ? */
				if((s->x==haus_x)&&(s->y>haus_y1)&&
					(s->y<haus_y2))
				{
					s->type=TYP_ATHOME;
					s->counter2=0;
					SpriteChangePic( s, 6 );	// lemming4
				}
				else
				{	/* kein bodenkontakt ? */
					switch( s->type & TYP_WORK )
					{
					case TYP_WALKER :
					case TYP_DIGDOWN :
						hbk=isBrick(s->x+1,s->y+s->height,0)||
								isBrick(s->x-2+s->width,s->y+s->height,0);
						break;
					case TYP_STOPPER :
						hbk=isBrick(s->x+1,s->y+s->height+1,0)||
								isBrick(s->x-2+s->width,s->y+s->height+1,0);
						break;
					case TYP_DIGDIAG :
						hbk=isBrick(s->x+10,s->y+s->height-2,0)||
								isBrick(s->x+11,s->y+s->height-2,0);
						break;
					case TYP_BUILDER :
						hbk=1;
						break;
					}
					if ( !hbk )
					{
#if 0
if ( s->type & TYP_DIGDIAG )
{
hhy=s->y+s->height-2;
printf("kein boden on %d, %d\n",s->x,s->y+s->height);
}
#endif
						if( !( s->type&TYP_WALKER ) )
						{
							switch( s->type & TYP_WORK )
							{
							case TYP_STOPPER :
								bgRect(s->x+1,s->y,s->width-1,s->height-2,14);
								break;
							case TYP_DIGDIAG :
								s->y+=5;
								if ( !s->dir )
									s->x+=7;
								break;
							case TYP_DIGDOWN :
								s->y+=2;
								break;
							}
							s->type=TYP_WALKER|(s->type&TYP_UTILS);
							SpriteChangePic( s, 3 );	// lemming1-faller
							if ( s->dir )
								MirrorSprite( s );
						}
						// freier fall
						s->y += 2;
						s->counter2++;
						// aus bild gefallen
						if(s->y>=160)
						{
							SoundPlay( SND_DIE );
							killlem(i);
							DrawInfo(1);
						}
					}
					else
					{
						if(s->type&TYP_WALKER)
						{	/* aufgeschlagen */
							if(s->counter2>=40)
							{
								s->counter1=0;
								s->type=TYP_FALLEN;
								SoundPlay( SND_DIE );
								s->partikel=1;
								partikel(i,1);
								s=0;
							}
							else
							{	/* wieder auf boden */
								s->counter2=0;
								/* laeufer - getestet wird oben */
								if((isBrick(s->x,s->y+1,1)&&
									(s->dir==1))||
								   (isBrick(s->x+s->width,s->y+1,1)&&
									(s->dir==0)))
								{
									MirrorSprite( s );
									s->dir^=1;
								}
								else
								{
									s->x += (s->dir?-1:1);
									if ( s->dir )
									{
										for(b=8;b>0;b--)
										{
											if(isBrick(s->x,
												s->y+s->height-b,0))
											{
												s->y-=1;
												b=0;
											}
										}
									}
									else
									{
										for(b=8;b>0;b--)
										{
											if(isBrick(s->x+s->width,
												s->y+s->height-b,0))
											{
												s->y-=1;
												b=0;
											}
										}
									}
								}
							} /* else, kein matsch */
						} /** walker **/
						else if(s&&(s->type&TYP_BUILDER))
						{
							unsigned char	c=118;	// stair
							if ( !s->ani )
							{
								s->counter2++;
								s->y--;
								if ( s->counter2 != 13 )
								{
									if ( s->dir )
									{
										s->x-=2;
										bghLine(s->x+2,s->y+s->height,6,&c,1);
										CopyBg2Screen( s->x+2,s->y+s->height,6,1);
										if ( isBrick(s->x+1,s->y+2,1) )
										{
											s->y+=2;
											s->dir=0;
											s->counter2=13;
										}
									}
									else
									{
										s->x+=2;
										bghLine(s->x+1,s->y+s->height,6,&c,1);
										CopyBg2Screen( s->x+1,s->y+s->height,6,1);
										if ( isBrick(s->x+s->width,s->y+2,1) )
										{
											s->y+=2;
											s->dir=1;
											s->counter2=13;
										}
									}
								}
								if ( s->counter2 == 12 )
								{
									s->y+=2;
									SpriteChangePic( s, 32 );//keinesteine
									if ( s->dir )
										MirrorSprite( s );
								}
								if ( s->counter2 == 13 )
								{
									s->type&=TYP_UTILS;
									s->type|=TYP_WALKER;
									SpriteChangePic( s, 3 );// lemming1
									if ( s->dir )
										MirrorSprite( s );
								}
							}
						}
						else if(s&&(s->type&TYP_DIGDOWN))
						{
							if(!(s->counter1%8))
							{
								if(s->y<160)
								{
									bgRect( s->x+1, s->y+4, 10,
										8-max(0,s->y-152), STEELBLUE );
									s->y+=1;
									cursor_get=1;
								}
							}
						}	/* digger */
						else if(s&&(s->type&TYP_DIGDIAG))
						{
							if ( s->ani == 8 )
							{
								if ( s->dir )
								{
									unsigned char *data = GetMirrorPic(34);
									bg2CopyImage(s->x+1,s->y+2,6,14,data);
								}
								else
								{
									inBg(34,0,s->x+11,s->y+2);
								}
							}
							if ( !s->ani )
							{
								s->y+=1;
								if ( s->dir )
									s->x-=2;
								else
									s->x+=2;
							}
						}
					}	/* freier fall */
				}	/* nicht am ziel */
			}	/* countdown */
			if ( s&&(level==5) )
			{ /* ab ins feuer ? */
				for( f=5; f<11; f++ )
				{
					if ( SpriteCollide( deko[f], s->x+s->width, s->y ) )
					{
						SoundPlay( SND_DIE );
						killlem(i);
						s=0;
						break;
					}
				}
			}
		}	/* typ-fallen */

		if ( !lemm[i] || !s )
			continue;

		if (( s->type & TYP_EXPLODE ) && ( s->countdown > 0 ))
		{
			DrawSimpleNumber( s->x-main_x, s->y-6, s->countdown, 1 );
		}

		SpriteGetBackground( s );
		DrawSprite( s );
		if ( SpriteCollide( s, deko[0]->x+7, deko[0]->y+7 ) )
		{
			sel_sprite=i;
		}
	}
	if ( cursor_get )
		SpriteGetBackground( deko[0] );
	if ( sel_sprite != -1 )
	{
		SpriteSelPic( deko[0], 1 );
	}
	else
	{
		SpriteSelPic( deko[0], 0 );
	}
	DrawSprite( deko[0] );
#if 0
if ( hhy )
FBDrawLine(32,hhy+hhy+32,656,hhy+hhy+32,RED);
#endif
	counter1++;
}
예제 #24
0
파일: UI.cpp 프로젝트: Skweek/Old-Projects
void UI::Draw()
{
	MoveSprite( m_uiUI, 0.f, 0.f );
	DrawSprite( m_uiUI );
}
예제 #25
0
void Player::Draw()
{
	MoveSprite(m_sprite,m_x, m_y);
	DrawSprite(m_sprite);
}
예제 #26
0
void drawSplash()
{
	DrawSprite(splashbackground.sprite);
	DrawSprite(splashbackground2.sprite);
	DrawSprite(splashoverlay.sprite);
	DrawSprite(splashoverlay2.sprite);
	DrawSprite(title.sprite);
	DrawSprite(bulletOne.sprite);
	DrawSprite(bulletTwo.sprite);
	DrawSprite(bulletThree.sprite);
	DrawSprite(enemyOne.sprite);
	DrawSprite(enemyTwo.sprite);
	DrawSprite(enemyThree.sprite);
	DrawSprite(explodeOne.sprite);
	DrawSprite(explodeTwo.sprite);
	DrawSprite(explodeThree.sprite);
	DrawSprite(ship.sprite);
	DrawSprite(huge.sprite);

}
예제 #27
0
int main(int argc, char *argv[])
{
	SDL_Init(SDL_INIT_VIDEO);
	displayWindow = SDL_CreateWindow("Shunman Tse Assignment 1 - My Scene", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 800, 600, SDL_WINDOW_OPENGL);
	SDL_GLContext context = SDL_GL_CreateContext(displayWindow);
	SDL_GL_MakeCurrent(displayWindow, context);

	bool done = false;

	SDL_Event event;

	// Basic setup for the rendering pipeline
	glViewport(0, 0, 800, 600);
	glMatrixMode(GL_PROJECTION);
	glOrtho(-1.33, 1.33, -1.0, 1.0, -1.0, 1.0);
	glMatrixMode(GL_MODELVIEW);

	// Load Textures
	GLuint spinningLollipop = LoadTexture("lollipopRed.png");
	GLuint asteroid = LoadTexture("meteorBig.png");
	GLuint player = LoadTexture("player.png");
	GLuint enemy = LoadTexture("enemyShip.png");

	// Set up timing variables
	float lastFrameTicks = 0.0f;
	float starRotation = 0.0f;
	float asteroidRotation = 0.0f;
	float asteroid2Rotation = 45.0f;

	while (!done) {
		while (SDL_PollEvent(&event)) {
			if (event.type == SDL_QUIT || event.type == SDL_WINDOWEVENT_CLOSE) {
				done = true;
			}
		}

		// Keeping time in the while loop
		float ticks = (float)SDL_GetTicks()/ 1000.0f;
		float elapsed = ticks - lastFrameTicks;
		lastFrameTicks = ticks;

		// Clear screen
		glClearColor(0.5f, 0.4f, 0.7f, 1.0f); // Purple Screen
		//glClearColor(1.0f, 1.0f, 1.0f, 1.0f); // White Screen
		glClear(GL_COLOR_BUFFER_BIT);

		//-- Natural Elements 
		// Spinning Candy Star (top left)
		starRotation += (elapsed * 20.0f);
		DrawSprite(spinningLollipop, -1.1, 0.8, starRotation, 0.3);

		// Asteroids
		asteroidRotation += (elapsed * 30.0f);
		DrawSprite(asteroid, 0.0, -0.4, asteroidRotation, 0.4); 

		asteroid2Rotation += (elapsed * 35.0f);
		DrawSprite(asteroid, 0.6, -0.2, asteroid2Rotation, 0.3); 
		DrawSprite(asteroid, -0.6, -0.2, asteroid2Rotation, 0.3);
		DrawSprite(asteroid, 1.2, -0.2, 0, 0.5);
		DrawSprite(asteroid, -1.2, -0.2, 180, 0.5);
			
		//-- Player Forces
		// 2 Player Ships (bottom)
		DrawSprite(player, -0.5, -0.8, 0, 0.2);
		DrawSprite(player, 0.5, -0.8, 0, 0.2);

		//-- Enemy Forces
		// 5 Enemy Ships (top)
		DrawSprite(enemy, 0.0, 0.0, 0, 0.2);
		DrawSprite(enemy, 0.2, 0.2, 0, 0.2);
		DrawSprite(enemy, -0.2, 0.2, 0, 0.2);
		DrawSprite(enemy, 0.6, 0.4, 0, 0.2);
		DrawSprite(enemy, -0.6, 0.4, 0, 0.2);

		// Rainbow Capital Ship (triangle with vertex colors)
		// Resize the ship accordingly
		glLoadIdentity();
		glScalef(0.1, 0.1, 0.1);
		glTranslatef(0.0, 6.5, 0.0);

		// Array of vertex position data
		GLfloat capitalShip [] = { 0.0, 3.0, 1.0, 3.0, 3.0, 2.0, 2.0, 1.0, 1.0, -2.0, 0.0, -3.0, -1.0, -2.0, -2.0, 1.0, -3.0, 2.0, -1.0, 3.0 }; // 10 points 
		glVertexPointer(2, GL_FLOAT, 0, capitalShip);
		glEnableClientState(GL_VERTEX_ARRAY);

		// Array of Vertex Color Data
		GLfloat capitalShipColors[] = { 
			1.0, 0.0, 0.0,
			1.0, 0.0, 0.0,
			0.0, 0.0, 1.0,
			0.5, 0.5, 0.5,
			0.0, 1.0, 0.0,
			1.0, 1.0, 1.0,
			0.0, 1.0, 0.0,
			0.5, 0.5, 0.5,
			0.0, 0.0, 1.0,
			1.0, 0.0, 0.0 };
		glColorPointer(3, GL_FLOAT, 0, capitalShipColors);
		glEnableClientState(GL_COLOR_ARRAY);
		glDrawArrays(GL_POLYGON, 0, 10);
		glDisableClientState(GL_COLOR_ARRAY);
		
		SDL_GL_SwapWindow(displayWindow);
	}

	SDL_Quit();
	return 0;
}
예제 #28
0
void DrawPCs(fighter* f1, mage* m1, SDL_Surface* screen)
{
	DrawSprite(f1->fsprite,screen,f1->x,f1->y,0);
	DrawSprite(m1->msprite,screen,m1->x,m1->y,0);

}
예제 #29
0
void Bullet::Draw()
{
	MoveSprite(iBulletSpriteID, fPositionX, fPositionY);
	DrawSprite(this->iBulletSpriteID);
}
예제 #30
0
//todo: this function is an abomination, this is just disgusting.  fix it.
//...seriously, this is really, really horrible.  I mean this is amazingly bad.
void OBS::MainCaptureLoop()
{
    int curRenderTarget = 0, curYUVTexture = 0, curCopyTexture = 0;
    int copyWait = NUM_RENDER_BUFFERS-1;

    bSentHeaders = false;
    bFirstAudioPacket = true;

    bool bLogLongFramesProfile = GlobalConfig->GetInt(TEXT("General"), TEXT("LogLongFramesProfile"), LOGLONGFRAMESDEFAULT) != 0;
    float logLongFramesProfilePercentage = GlobalConfig->GetFloat(TEXT("General"), TEXT("LogLongFramesProfilePercentage"), 10.f);

    Vect2 baseSize    = Vect2(float(baseCX), float(baseCY));
    Vect2 outputSize  = Vect2(float(outputCX), float(outputCY));
    Vect2 scaleSize   = Vect2(float(scaleCX), float(scaleCY));

    HANDLE hScaleVal = yuvScalePixelShader->GetParameterByName(TEXT("baseDimensionI"));

    //----------------------------------------
    // x264 input buffers

    int curOutBuffer = 0;

    bool bUsingQSV = videoEncoder->isQSV();//GlobalConfig->GetInt(TEXT("Video Encoding"), TEXT("UseQSV")) != 0;
    if(bUsingQSV)
        bUsing444 = false;

    EncoderPicture lastPic;
    EncoderPicture outPics[NUM_OUT_BUFFERS];
    DWORD outTimes[NUM_OUT_BUFFERS] = {0, 0, 0};

    for(int i=0; i<NUM_OUT_BUFFERS; i++)
    {
        if(bUsingQSV)
        {
            outPics[i].mfxOut = new mfxFrameSurface1;
            memset(outPics[i].mfxOut, 0, sizeof(mfxFrameSurface1));
            mfxFrameData& data = outPics[i].mfxOut->Data;
            videoEncoder->RequestBuffers(&data);
        }
        else
        {
            outPics[i].picOut = new x264_picture_t;
            x264_picture_init(outPics[i].picOut);
        }
    }

    if(bUsing444)
    {
        for(int i=0; i<NUM_OUT_BUFFERS; i++)
        {
            outPics[i].picOut->img.i_csp   = X264_CSP_BGRA; //although the x264 input says BGR, x264 actually will expect packed UYV
            outPics[i].picOut->img.i_plane = 1;
        }
    }
    else
    {
        if(!bUsingQSV)
            for(int i=0; i<NUM_OUT_BUFFERS; i++)
                x264_picture_alloc(outPics[i].picOut, X264_CSP_NV12, outputCX, outputCY);
    }

    int bCongestionControl = AppConfig->GetInt (TEXT("Video Encoding"), TEXT("CongestionControl"), 0);
    bool bDynamicBitrateSupported = App->GetVideoEncoder()->DynamicBitrateSupported();
    int defaultBitRate = AppConfig->GetInt(TEXT("Video Encoding"), TEXT("MaxBitrate"), 1000);
    int currentBitRate = defaultBitRate;
    QWORD lastAdjustmentTime = 0;
    UINT adjustmentStreamId = 0;

    //----------------------------------------
    // time/timestamp stuff

    bufferedTimes.Clear();
    ctsOffsets.Clear();
    int bufferedFrames = 1; //to avoid constantly polling number of frames

#ifdef USE_100NS_TIME
    QWORD streamTimeStart = GetQPCTime100NS();
    QWORD frameTime100ns = 10000000/fps;

    QWORD sleepTargetTime = 0;
    bool bWasLaggedFrame = false;
#else
    DWORD streamTimeStart = OSGetTime();
    DWORD fpsTimeAdjust = 0;
#endif
    totalStreamTime = 0;

    lastAudioTimestamp = 0;

    latestVideoTime = firstSceneTimestamp = GetQPCTimeMS();

    DWORD fpsTimeNumerator = 1000-(frameTime*fps);
    DWORD fpsTimeDenominator = fps;
    DWORD cfrTime = 0;
    DWORD cfrTimeAdjust = 0;

    //----------------------------------------
    // start audio capture streams

    desktopAudio->StartCapture();
    if(micAudio) micAudio->StartCapture();

    //----------------------------------------
    // status bar/statistics stuff

    DWORD fpsCounter = 0;

    int numLongFrames = 0;
    int numTotalFrames = 0;

    int numTotalDuplicatedFrames = 0;

    bytesPerSec = 0;
    captureFPS = 0;
    curFramesDropped = 0;
    curStrain = 0.0;
    PostMessage(hwndMain, OBS_UPDATESTATUSBAR, 0, 0);

    QWORD lastBytesSent[3] = {0, 0, 0};
    DWORD lastFramesDropped = 0;
#ifdef USE_100NS_TIME
    double bpsTime = 0.0;
#else
    float bpsTime = 0.0f;
#endif
    double lastStrain = 0.0f;
    DWORD numSecondsWaited = 0;

    //----------------------------------------
    // 444->420 thread data

    int numThreads = MAX(OSGetTotalCores()-2, 1);
    HANDLE *h420Threads = (HANDLE*)Allocate(sizeof(HANDLE)*numThreads);
    Convert444Data *convertInfo = (Convert444Data*)Allocate(sizeof(Convert444Data)*numThreads);

    zero(h420Threads, sizeof(HANDLE)*numThreads);
    zero(convertInfo, sizeof(Convert444Data)*numThreads);

    for(int i=0; i<numThreads; i++)
    {
        convertInfo[i].width  = outputCX;
        convertInfo[i].height = outputCY;
        convertInfo[i].hSignalConvert  = CreateEvent(NULL, FALSE, FALSE, NULL);
        convertInfo[i].hSignalComplete = CreateEvent(NULL, FALSE, FALSE, NULL);
        convertInfo[i].bNV12 = bUsingQSV;

        if(i == 0)
            convertInfo[i].startY = 0;
        else
            convertInfo[i].startY = convertInfo[i-1].endY;

        if(i == (numThreads-1))
            convertInfo[i].endY = outputCY;
        else
            convertInfo[i].endY = ((outputCY/numThreads)*(i+1)) & 0xFFFFFFFE;
    }

    bool bFirstFrame = true;
    bool bFirstImage = true;
    bool bFirst420Encode = true;
    bool bUseThreaded420 = bUseMultithreadedOptimizations && (OSGetTotalCores() > 1) && !bUsing444;

    List<HANDLE> completeEvents;

    if(bUseThreaded420)
    {
        for(int i=0; i<numThreads; i++)
        {
            h420Threads[i] = OSCreateThread((XTHREAD)Convert444Thread, convertInfo+i);
            completeEvents << convertInfo[i].hSignalComplete;
        }
    }

    //----------------------------------------

    QWORD curStreamTime = 0, lastStreamTime, firstFrameTime = GetQPCTimeMS();

#ifdef USE_100NS_TIME
    lastStreamTime = GetQPCTime100NS()-frameTime100ns;
#else
    lastStreamTime = firstFrameTime-frameTime;
#endif

    //bool bFirstAudioPacket = true;

    List<ProfilerNode> threadedProfilers;
    bool bUsingThreadedProfilers = false;

    while(bRunning || bufferedFrames)
    {
#ifdef USE_100NS_TIME
        QWORD renderStartTime = GetQPCTime100NS();
        totalStreamTime = DWORD((renderStartTime-streamTimeStart)/10000);

        if(sleepTargetTime == 0 || bWasLaggedFrame)
            sleepTargetTime = renderStartTime;
#else
        DWORD renderStartTime = OSGetTime();
        totalStreamTime = renderStartTime-streamTimeStart;

        DWORD frameTimeAdjust = frameTime;
        fpsTimeAdjust += fpsTimeNumerator;
        if(fpsTimeAdjust > fpsTimeDenominator)
        {
            fpsTimeAdjust -= fpsTimeDenominator;
            ++frameTimeAdjust;
        }
#endif

        bool bRenderView = !IsIconic(hwndMain) && bRenderViewEnabled;

        profileIn("frame");

#ifdef USE_100NS_TIME
        QWORD qwTime = renderStartTime/10000;
        latestVideoTime = qwTime;

        QWORD frameDelta = renderStartTime-lastStreamTime;
        double fSeconds = double(frameDelta)*0.0000001;

        //Log(TEXT("frameDelta: %f"), fSeconds);

        lastStreamTime = renderStartTime;
#else
        QWORD qwTime = GetQPCTimeMS();
        latestVideoTime = qwTime;

        QWORD frameDelta = qwTime-lastStreamTime;
        float fSeconds = float(frameDelta)*0.001f;

        //Log(TEXT("frameDelta: %llu"), frameDelta);

        lastStreamTime = qwTime;
#endif

        bool bUpdateBPS = false;
        profileIn("frame preprocessing and rendering");

        //------------------------------------

        if(bRequestKeyframe && keyframeWait > 0)
        {
            keyframeWait -= int(frameDelta);

            if(keyframeWait <= 0)
            {
                GetVideoEncoder()->RequestKeyframe();
                bRequestKeyframe = false;
            }
        }

        if(!bPushToTalkDown && pushToTalkTimeLeft > 0)
        {
            pushToTalkTimeLeft -= int(frameDelta);
            OSDebugOut(TEXT("time left: %d\r\n"), pushToTalkTimeLeft);
            if(pushToTalkTimeLeft <= 0)
            {
                pushToTalkTimeLeft = 0;
                bPushToTalkOn = false;
            }
        }

        //------------------------------------

        OSEnterMutex(hSceneMutex);

        if(bResizeRenderView)
        {
            GS->ResizeView();
            bResizeRenderView = false;
        }

        //------------------------------------

        if(scene)
        {
            profileIn("scene->Preprocess");
            scene->Preprocess();

            for(UINT i=0; i<globalSources.Num(); i++)
                globalSources[i].source->Preprocess();

            profileOut;

            scene->Tick(float(fSeconds));

            for(UINT i=0; i<globalSources.Num(); i++)
                globalSources[i].source->Tick(float(fSeconds));
        }

        //------------------------------------

        QWORD curBytesSent = network->GetCurrentSentBytes();
        curFramesDropped = network->NumDroppedFrames();

        bpsTime += fSeconds;
        if(bpsTime > 1.0f)
        {
            if(numSecondsWaited < 3)
                ++numSecondsWaited;

            //bytesPerSec = DWORD(curBytesSent - lastBytesSent);
            bytesPerSec = DWORD(curBytesSent - lastBytesSent[0]) / numSecondsWaited;

            if(bpsTime > 2.0)
                bpsTime = 0.0f;
            else
                bpsTime -= 1.0;

            if(numSecondsWaited == 3)
            {
                lastBytesSent[0] = lastBytesSent[1];
                lastBytesSent[1] = lastBytesSent[2];
                lastBytesSent[2] = curBytesSent;
            }
            else
                lastBytesSent[numSecondsWaited] = curBytesSent;

            captureFPS = fpsCounter;
            fpsCounter = 0;

            bUpdateBPS = true;
        }

        fpsCounter++;

        curStrain = network->GetPacketStrain();

        EnableBlending(TRUE);
        BlendFunction(GS_BLEND_SRCALPHA, GS_BLEND_INVSRCALPHA);

        //------------------------------------
        // render the mini render texture

        LoadVertexShader(mainVertexShader);
        LoadPixelShader(mainPixelShader);

        SetRenderTarget(mainRenderTextures[curRenderTarget]);

        Ortho(0.0f, baseSize.x, baseSize.y, 0.0f, -100.0f, 100.0f);
        SetViewport(0, 0, baseSize.x, baseSize.y);

        if(scene)
            scene->Render();

        //------------------------------------

        if(bTransitioning)
        {
            if(!transitionTexture)
            {
                transitionTexture = CreateTexture(baseCX, baseCY, GS_BGRA, NULL, FALSE, TRUE);
                if(transitionTexture)
                {
                    D3D10Texture *d3dTransitionTex = static_cast<D3D10Texture*>(transitionTexture);
                    D3D10Texture *d3dSceneTex = static_cast<D3D10Texture*>(mainRenderTextures[lastRenderTarget]);
                    GetD3D()->CopyResource(d3dTransitionTex->texture, d3dSceneTex->texture);
                }
                else
                    bTransitioning = false;
            }
            else if(transitionAlpha >= 1.0f)
            {
                delete transitionTexture;
                transitionTexture = NULL;

                bTransitioning = false;
            }
        }

        if(bTransitioning)
        {
            EnableBlending(TRUE);
            transitionAlpha += float(fSeconds)*5.0f;
            if(transitionAlpha > 1.0f)
                transitionAlpha = 1.0f;
        }
        else
            EnableBlending(FALSE);

        //------------------------------------
        // render the mini view thingy

        if(bRenderView)
        {
            // Cache
            const Vect2 renderFrameSize = GetRenderFrameSize();
            const Vect2 renderFrameOffset = GetRenderFrameOffset();
            const Vect2 renderFrameCtrlSize = GetRenderFrameControlSize();

            SetRenderTarget(NULL);

            LoadVertexShader(mainVertexShader);
            LoadPixelShader(mainPixelShader);

            Ortho(0.0f, renderFrameCtrlSize.x, renderFrameCtrlSize.y, 0.0f, -100.0f, 100.0f);
            if(renderFrameCtrlSize.x != oldRenderFrameCtrlWidth || renderFrameCtrlSize.y != oldRenderFrameCtrlHeight)
            {
                // User is drag resizing the window. We don't recreate the swap chains so our coordinates are wrong
                SetViewport(0.0f, 0.0f, (float)oldRenderFrameCtrlWidth, (float)oldRenderFrameCtrlHeight);
            }
            else
                SetViewport(0.0f, 0.0f, renderFrameCtrlSize.x, renderFrameCtrlSize.y);

            // Draw background (Black if fullscreen, window colour otherwise)
            if(bFullscreenMode)
                ClearColorBuffer(0x000000);
            else
                ClearColorBuffer(GetSysColor(COLOR_BTNFACE));

            if(bTransitioning)
            {
                BlendFunction(GS_BLEND_ONE, GS_BLEND_ZERO);
                DrawSprite(transitionTexture, 0xFFFFFFFF,
                        renderFrameOffset.x, renderFrameOffset.y,
                        renderFrameOffset.x + renderFrameSize.x, renderFrameOffset.y + renderFrameSize.y);
                BlendFunction(GS_BLEND_FACTOR, GS_BLEND_INVFACTOR, transitionAlpha);
            }

            DrawSprite(mainRenderTextures[curRenderTarget], 0xFFFFFFFF,
                    renderFrameOffset.x, renderFrameOffset.y,
                    renderFrameOffset.x + renderFrameSize.x, renderFrameOffset.y + renderFrameSize.y);

            //draw selections if in edit mode
            if(bEditMode && !bSizeChanging)
            {
                if(scene) {
                    LoadVertexShader(solidVertexShader);
                    LoadPixelShader(solidPixelShader);
                    solidPixelShader->SetColor(solidPixelShader->GetParameter(0), 0xFF0000);
                    scene->RenderSelections(solidPixelShader);
                }
            }
        }
        else if(bForceRenderViewErase)
        {
            InvalidateRect(hwndRenderFrame, NULL, TRUE);
            UpdateWindow(hwndRenderFrame);
            bForceRenderViewErase = false;
        }

        //------------------------------------
        // actual stream output

        LoadVertexShader(mainVertexShader);
        LoadPixelShader(yuvScalePixelShader);

        Texture *yuvRenderTexture = yuvRenderTextures[curRenderTarget];
        SetRenderTarget(yuvRenderTexture);

        if(downscale < 2.01)
            yuvScalePixelShader->SetVector2(hScaleVal, 1.0f/baseSize);
        else if(downscale < 3.01)
            yuvScalePixelShader->SetVector2(hScaleVal, 1.0f/(outputSize*3.0f));

        Ortho(0.0f, outputSize.x, outputSize.y, 0.0f, -100.0f, 100.0f);
        SetViewport(0.0f, 0.0f, outputSize.x, outputSize.y);

        //why am I using scaleSize instead of outputSize for the texture?
        //because outputSize can be trimmed by up to three pixels due to 128-bit alignment.
        //using the scale function with outputSize can cause slightly inaccurate scaled images
        if(bTransitioning)
        {
            BlendFunction(GS_BLEND_ONE, GS_BLEND_ZERO);
            DrawSpriteEx(transitionTexture, 0xFFFFFFFF, 0.0f, 0.0f, scaleSize.x, scaleSize.y, 0.0f, 0.0f, 1.0f, 1.0f);
            BlendFunction(GS_BLEND_FACTOR, GS_BLEND_INVFACTOR, transitionAlpha);
        }

        DrawSpriteEx(mainRenderTextures[curRenderTarget], 0xFFFFFFFF, 0.0f, 0.0f, outputSize.x, outputSize.y, 0.0f, 0.0f, 1.0f, 1.0f);

        //------------------------------------

        if(bRenderView && !copyWait)
            static_cast<D3D10System*>(GS)->swap->Present(0, 0);

        OSLeaveMutex(hSceneMutex);

        profileOut;

        //------------------------------------
        // present/upload

        profileIn("video encoding and uploading");

        bool bEncode = true;

        if(copyWait)
        {
            copyWait--;
            bEncode = false;
        }
        else
        {
            //audio sometimes takes a bit to start -- do not start processing frames until audio has started capturing
            if(!bRecievedFirstAudioFrame)
            {
                static bool bWarnedAboutNoAudio = false;
                if (qwTime-firstFrameTime > 10000 && !bWarnedAboutNoAudio)
                {
                    bWarnedAboutNoAudio = true;
                    //AddStreamInfo (TEXT ("WARNING: OBS is not receiving audio frames. Please check your audio devices."), StreamInfoPriority_Critical); 
                }
                bEncode = false;
            }
            else if(bFirstFrame)
            {
                firstFrameTime = qwTime;
                bFirstFrame = false;
            }

            if(!bEncode)
            {
                if(curYUVTexture == (NUM_RENDER_BUFFERS-1))
                    curYUVTexture = 0;
                else
                    curYUVTexture++;
            }
        }

        if(bEncode)
        {
            curStreamTime = qwTime-firstFrameTime;

            UINT prevCopyTexture = (curCopyTexture == 0) ? NUM_RENDER_BUFFERS-1 : curCopyTexture-1;

            ID3D10Texture2D *copyTexture = copyTextures[curCopyTexture];
            profileIn("CopyResource");

            if(!bFirst420Encode && bUseThreaded420)
            {
                WaitForMultipleObjects(completeEvents.Num(), completeEvents.Array(), TRUE, INFINITE);
                copyTexture->Unmap(0);
            }

            D3D10Texture *d3dYUV = static_cast<D3D10Texture*>(yuvRenderTextures[curYUVTexture]);
            GetD3D()->CopyResource(copyTexture, d3dYUV->texture);
            profileOut;

            ID3D10Texture2D *prevTexture = copyTextures[prevCopyTexture];

            if(bFirstImage) //ignore the first frame
                bFirstImage = false;
            else
            {
                HRESULT result;
                D3D10_MAPPED_TEXTURE2D map;
                if(SUCCEEDED(result = prevTexture->Map(0, D3D10_MAP_READ, 0, &map)))
                {
                    int prevOutBuffer = (curOutBuffer == 0) ? NUM_OUT_BUFFERS-1 : curOutBuffer-1;
                    int nextOutBuffer = (curOutBuffer == NUM_OUT_BUFFERS-1) ? 0 : curOutBuffer+1;

                    EncoderPicture &prevPicOut = outPics[prevOutBuffer];
                    EncoderPicture &picOut = outPics[curOutBuffer];
                    EncoderPicture &nextPicOut = outPics[nextOutBuffer];

                    if(!bUsing444)
                    {
                        profileIn("conversion to 4:2:0");

                        if(bUseThreaded420)
                        {
                            outTimes[nextOutBuffer] = (DWORD)curStreamTime;

                            bool firstRun = threadedProfilers.Num() == 0;
                            if(firstRun)
                                threadedProfilers.SetSize(numThreads);

                            for(int i=0; i<numThreads; i++)
                            {
                                convertInfo[i].input     = (LPBYTE)map.pData;
                                convertInfo[i].inPitch   = map.RowPitch;
                                if(bUsingQSV)
                                {
                                    mfxFrameData& data = nextPicOut.mfxOut->Data;
                                    videoEncoder->RequestBuffers(&data);
                                    convertInfo[i].outPitch  = data.Pitch;
                                    convertInfo[i].output[0] = data.Y;
                                    convertInfo[i].output[1] = data.UV;
                                }
                                else
                                {
                                    convertInfo[i].output[0] = nextPicOut.picOut->img.plane[0];
                                    convertInfo[i].output[1] = nextPicOut.picOut->img.plane[1];
                                    convertInfo[i].output[2] = nextPicOut.picOut->img.plane[2];
								}
                                if(!firstRun)
                                    threadedProfilers[i].~ProfilerNode();
                                ::new (&threadedProfilers[i]) ProfilerNode(TEXT("Convert444Threads"), true);
                                threadedProfilers[i].MonitorThread(h420Threads[i]);
                                bUsingThreadedProfilers = true;
                                SetEvent(convertInfo[i].hSignalConvert);
                            }

                            if(bFirst420Encode)
                                bFirst420Encode = bEncode = false;
                        }
                        else
                        {
                            outTimes[curOutBuffer] = (DWORD)curStreamTime;
                            if(bUsingQSV)
                            {
                                mfxFrameData& data = picOut.mfxOut->Data;
                                videoEncoder->RequestBuffers(&data);
                                LPBYTE output[] = {data.Y, data.UV};
                                Convert444toNV12((LPBYTE)map.pData, outputCX, map.RowPitch, data.Pitch, outputCY, 0, outputCY, output);
                            }
                            else
                                Convert444toNV12((LPBYTE)map.pData, outputCX, map.RowPitch, outputCX, outputCY, 0, outputCY, picOut.picOut->img.plane);
                            prevTexture->Unmap(0);
                        }

                        profileOut;
                    }
                    else
                    {
                        outTimes[curOutBuffer] = (DWORD)curStreamTime;

                        picOut.picOut->img.i_stride[0] = map.RowPitch;
                        picOut.picOut->img.plane[0]    = (uint8_t*)map.pData;
                    }

                    if(bEncode)
                    {
                        DWORD curFrameTimestamp = outTimes[prevOutBuffer];
                        //Log(TEXT("curFrameTimestamp: %u"), curFrameTimestamp);

                        //------------------------------------

                        FrameProcessInfo frameInfo;
                        frameInfo.firstFrameTime = firstFrameTime;
                        frameInfo.prevTexture = prevTexture;

                        if(bDupeFrames)
                        {
                            while(cfrTime < curFrameTimestamp)
                            {
                                DWORD frameTimeAdjust = frameTime;
                                cfrTimeAdjust += fpsTimeNumerator;
                                if(cfrTimeAdjust > fpsTimeDenominator)
                                {
                                    cfrTimeAdjust -= fpsTimeDenominator;
                                    ++frameTimeAdjust;
                                }

                                DWORD halfTime = (frameTimeAdjust+1)/2;

                                EncoderPicture &nextPic = (curFrameTimestamp-cfrTime <= halfTime) ? picOut : prevPicOut;
                                //Log(TEXT("cfrTime: %u, time: %u"), cfrTime, curFrameTimestamp);

                                //these lines are just for counting duped frames
                                if(nextPic == lastPic)
                                    ++numTotalDuplicatedFrames;
                                else
                                    lastPic = nextPic;

                                frameInfo.pic = &nextPic;
                                if(bUsingQSV)
                                    frameInfo.pic->mfxOut->Data.TimeStamp = cfrTime;
                                else
                                    frameInfo.pic->picOut->i_pts = cfrTime;
                                frameInfo.frameTimestamp = cfrTime;
                                ProcessFrame(frameInfo);

                                cfrTime += frameTimeAdjust;

                                //Log(TEXT("cfrTime: %u, chi frame: %u"), cfrTime, (curFrameTimestamp-cfrTime <= halfTime));
                            }
                        }
                        else
                        {
                            if(bUsingQSV)
                                picOut.mfxOut->Data.TimeStamp = curFrameTimestamp;
                            else
                                picOut.picOut->i_pts = curFrameTimestamp;

                            frameInfo.pic = &picOut;
                            frameInfo.frameTimestamp = curFrameTimestamp;

                            ProcessFrame(frameInfo);
                        }

                        if (!bRunning)
                            bufferedFrames = videoEncoder->GetBufferedFrames ();
                    }

                    if(bUsing444)
                    {
                        prevTexture->Unmap(0);
                    }

                    curOutBuffer = nextOutBuffer;
                }
                else
                {
                    //We have to crash, or we end up deadlocking the thread when the convert threads are never signalled
                    if (result == DXGI_ERROR_DEVICE_REMOVED)
                    {
                        String message;

                        HRESULT reason = GetD3D()->GetDeviceRemovedReason();

                        switch (reason)
                        {
                        case DXGI_ERROR_DEVICE_RESET:
                        case DXGI_ERROR_DEVICE_HUNG:
                            message = TEXT("Your video card or driver froze and was reset. Please check for possible hardware / driver issues.");
                            break;
                        case DXGI_ERROR_DEVICE_REMOVED:
                            message = TEXT("Your video card disappeared from the system. Please check for possible hardware / driver issues.");
                            break;
                        case DXGI_ERROR_DRIVER_INTERNAL_ERROR:
                            message = TEXT("Your video driver reported an internal error. Please check for possible hardware / driver issues.");
                            break;
                        case DXGI_ERROR_INVALID_CALL:
                            message = TEXT("Your video driver reported an invalid call. Please check for possible driver issues.");
                            break;
                        default:
                            message = TEXT("DXGI_ERROR_DEVICE_REMOVED");
                            break;
                        }

                        CrashError (TEXT("Texture->Map failed: 0x%08x 0x%08x\r\n\r\n%s"), result, reason, message.Array());
                    }
                    else
                        CrashError (TEXT("Texture->Map failed: 0x%08x"), result);
                }
            }

            if(curCopyTexture == (NUM_RENDER_BUFFERS-1))
                curCopyTexture = 0;
            else
                curCopyTexture++;

            if(curYUVTexture == (NUM_RENDER_BUFFERS-1))
                curYUVTexture = 0;
            else
                curYUVTexture++;

            if (bCongestionControl && bDynamicBitrateSupported && !bTestStream)
            {
                if (curStrain > 25)
                {
                    if (qwTime - lastAdjustmentTime > 1500)
                    {
                        if (currentBitRate > 100)
                        {
                            currentBitRate = (int)(currentBitRate * (1.0 - (curStrain / 400)));
                            App->GetVideoEncoder()->SetBitRate(currentBitRate, -1);
                            if (!adjustmentStreamId)
                                adjustmentStreamId = App->AddStreamInfo (FormattedString(TEXT("Congestion detected, dropping bitrate to %d kbps"), currentBitRate).Array(), StreamInfoPriority_Low);
                            else
                                App->SetStreamInfo(adjustmentStreamId, FormattedString(TEXT("Congestion detected, dropping bitrate to %d kbps"), currentBitRate).Array());

                            bUpdateBPS = true;
                        }

                        lastAdjustmentTime = qwTime;
                    }
                }
                else if (currentBitRate < defaultBitRate && curStrain < 5 && lastStrain < 5)
                {
                    if (qwTime - lastAdjustmentTime > 5000)
                    {
                        if (currentBitRate < defaultBitRate)
                        {
                            currentBitRate += (int)(defaultBitRate * 0.05);
                            if (currentBitRate > defaultBitRate)
                                currentBitRate = defaultBitRate;
                        }

                        App->GetVideoEncoder()->SetBitRate(currentBitRate, -1);
                        /*if (!adjustmentStreamId)
                            App->AddStreamInfo (FormattedString(TEXT("Congestion clearing, raising bitrate to %d kbps"), currentBitRate).Array(), StreamInfoPriority_Low);
                        else
                            App->SetStreamInfo(adjustmentStreamId, FormattedString(TEXT("Congestion clearing, raising bitrate to %d kbps"), currentBitRate).Array());*/

                        bUpdateBPS = true;

                        lastAdjustmentTime = qwTime;
                    }
                }
            }
        }

        lastRenderTarget = curRenderTarget;

        if(curRenderTarget == (NUM_RENDER_BUFFERS-1))
            curRenderTarget = 0;
        else
            curRenderTarget++;

        if(bUpdateBPS || !CloseDouble(curStrain, lastStrain) || curFramesDropped != lastFramesDropped)
        {
            PostMessage(hwndMain, OBS_UPDATESTATUSBAR, 0, 0);
            lastStrain = curStrain;

            lastFramesDropped = curFramesDropped;
        }

        //------------------------------------
        // we're about to sleep so we should flush the d3d command queue
        profileIn("flush");
        GetD3D()->Flush();
        profileOut;

        profileOut; //video encoding and uploading
        profileOut; //frame

        //------------------------------------
        // frame sync

#ifdef USE_100NS_TIME
        QWORD renderStopTime = GetQPCTime100NS();
        sleepTargetTime += frameTime100ns;

        if(bWasLaggedFrame = (sleepTargetTime <= renderStopTime))
        {
            numLongFrames++;
            if(bLogLongFramesProfile && (numLongFrames/float(max(1, numTotalFrames)) * 100.) > logLongFramesProfilePercentage)
                DumpLastProfileData();
        }
        else
            SleepTo(sleepTargetTime);
#else
        DWORD renderStopTime = OSGetTime();
        DWORD totalTime = renderStopTime-renderStartTime;

        if(totalTime > frameTimeAdjust)
        {
            numLongFrames++;
            if(bLogLongFramesProfile && (numLongFrames/float(max(1, numTotalFrames)) * 100.) > logLongFramesProfilePercentage)
                DumpLastProfileData();
        }
        else if(totalTime < frameTimeAdjust)
            OSSleep(frameTimeAdjust-totalTime);
#endif

        //OSDebugOut(TEXT("Frame adjust time: %d, "), frameTimeAdjust-totalTime);

        numTotalFrames++;
    }

    if(!bUsing444)
    {
        if(bUseThreaded420)
        {
            for(int i=0; i<numThreads; i++)
            {
                if(h420Threads[i])
                {
                    convertInfo[i].bKillThread = true;
                    SetEvent(convertInfo[i].hSignalConvert);
                    if(bUsingThreadedProfilers)
                        threadedProfilers[i].~ProfilerNode();

                    OSTerminateThread(h420Threads[i], 10000);
                    h420Threads[i] = NULL;
                }

                if(convertInfo[i].hSignalConvert)
                {
                    CloseHandle(convertInfo[i].hSignalConvert);
                    convertInfo[i].hSignalConvert = NULL;
                }

                if(convertInfo[i].hSignalComplete)
                {
                    CloseHandle(convertInfo[i].hSignalComplete);
                    convertInfo[i].hSignalComplete = NULL;
                }
            }

            if(!bFirst420Encode)
            {
                ID3D10Texture2D *copyTexture = copyTextures[curCopyTexture];
                copyTexture->Unmap(0);
            }
        }

        if(bUsingQSV)
            for(int i = 0; i < NUM_OUT_BUFFERS; i++)
                delete outPics[i].mfxOut;
        else
            for(int i=0; i<NUM_OUT_BUFFERS; i++)
            {
                x264_picture_clean(outPics[i].picOut);
                delete outPics[i].picOut;
            }
    }

    Free(h420Threads);
    Free(convertInfo);

    Log(TEXT("Total frames rendered: %d, number of frames that lagged: %d (%0.2f%%) (it's okay for some frames to lag)"), numTotalFrames, numLongFrames, (double(numLongFrames)/double(numTotalFrames))*100.0);
    if(bDupeFrames)
        Log(TEXT("Total duplicated frames: %d (%0.2f%%)"), numTotalDuplicatedFrames, (double(numTotalDuplicatedFrames)/double(numTotalFrames))*100.0);
}