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); } }
void Missile::draw(){ DrawSprite(*missileSprite, misX,misY,FALSE); }
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); }
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; }
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 ); }
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)); }
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); } }
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); }
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); }
void Spit::Draw() { if ( active ) DrawSprite(sprite); }
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); }
void AI::DrawAI() { DrawSprite(textureHandler); }
void DrawPause(void) { LevelToDraw(); DrawSprite(PauseText); DrawCollisionList(); }
/** * 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); } }
void SpriteRenderer3D::EndDrawing() { DrawSprite(); }
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); }
/** * 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); }
//----------------------------------------------------------------------------- // 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 ); }
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 } } } }
//----------------------------------------------------------------------------- // 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); } } }
void DrawMouse() { DrawSprite(Mouse.sprite,screen,Mouse.mx,Mouse.my,Mouse.mframe); }
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++; }
void UI::Draw() { MoveSprite( m_uiUI, 0.f, 0.f ); DrawSprite( m_uiUI ); }
void Player::Draw() { MoveSprite(m_sprite,m_x, m_y); DrawSprite(m_sprite); }
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); }
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; }
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); }
void Bullet::Draw() { MoveSprite(iBulletSpriteID, fPositionX, fPositionY); DrawSprite(this->iBulletSpriteID); }
//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); }