void AboutTimer(HWND hwnd, UINT id) { HWND hwndBitmap; HDC hdc; int i, j, k, x, y; RECT r; PDIB pdib; BYTE *bits, index; object_node *obj; // Copy bits to offscreen area for (i=0; i < scroll_height; i++) { int yBitmap = (scroll_y + i) % DibHeight(credits_pdib); BYTE *pSource = DibPtr(credits_pdib) + (yBitmap * DibWidth(credits_pdib)); BYTE *pDest = gBits + i*DIBWIDTH(gbits_width); memcpy(pDest,pSource,scroll_width); } scroll_y++; if (scroll_y >= DibHeight(credits_pdib)) scroll_y = 0; hwndBitmap = GetDlgItem(hwnd, IDC_SCROLL); hdc = GetDC(hwndBitmap); SelectPalette(hdc, hPal, FALSE); BitBlt(hdc, 0, 0, scroll_width, scroll_height, gDC, 0, 0, SRCCOPY); ReleaseDC(hwndBitmap, hdc); // Draw animated characters r.left = r.top = 0; r.right = gbits_width; r.bottom = gbits_height; FillRect(gDC, &r, GetSysColorBrush(COLOR_3DFACE)); GdiFlush(); hdc = GetDC(hwnd); for (i=0; i < NUM_DUDES; i++) { if (dudes[i].obj != NULL) { obj = dudes[i].obj; if (rand() % 30 == 0) { obj->animate->animation = ANIMATE_ONCE; obj->animate->group = obj->animate->group_low = 3; obj->animate->group_high = 4; obj->animate->group_final = 0; obj->animate->period = obj->animate->tick = 400; if (config.play_sound) { switch (dudes[i].obj->icon_res) { case ABOUT_RSC1: index = 3; break; case ABOUT_RSC2: index = 4; break; case ABOUT_RSC3: index = 5; break; default: index = rand() % num_sounds; break; } SoundPlayFile(sounds[index], SF_RANDOM_PITCH); } } AnimateObject(dudes[i].obj, ABOUT_INTERVAL); pdib = GetObjectPdib(dudes[i].obj->icon_res, dudes[i].angle, dudes[i].obj->animate->group); if (pdib == NULL) continue; bits = DibPtr(pdib); x = dudes[i].x - DibWidth(pdib) / 2; y = DUDE_MAX_HEIGHT - DibHeight(pdib); for (j=0; j < DibHeight(pdib); j++) { for (k=0; k < DibWidth(pdib); k++) { index = *(bits + j * DibWidth(pdib) + k); if (index != TRANSPARENT_INDEX) *(gBits + (j + y) * DIBWIDTH(gbits_width) + x + k) = index; } } } } SelectPalette(hdc, hPal, FALSE); BitBlt(hdc, dude_x, dude_y, DUDE_AREA_WIDTH, DUDE_MAX_HEIGHT, gDC, 0, 0, SRCCOPY); ReleaseDC(hwnd, hdc); }
/* * D3DParticleSystemUpdateBurst: This functions updates any 'burst' updating * particle systems, such as fireworks. Particles are built-up and then * released all at once. */ void D3DParticleSystemUpdateBurst(particle_system *pParticleSystem, d3d_render_pool_new *pPool, d3d_render_cache_system *pCacheSystem, Draw3DParams *params) { int curParticle; list_type list; emitter *pEmitter; particle *pParticle; bool playedSound = false; D3DCacheSystemReset(pCacheSystem); D3DRenderPoolReset(pPool, &D3DMaterialParticlePool); for (list = pParticleSystem->emitterList; list != NULL; list = list->next) { pEmitter = (emitter *)list->data; if (pEmitter->numParticles >= pEmitter->maxParticles && pEmitter->numAlive > 0) { //debug(("numparticles is %i\n",pEmitter->numParticles)); for (curParticle = 0; curParticle < pEmitter->numParticles; curParticle++) { pParticle = &pEmitter->particles[curParticle]; if (!D3DParticleIsAlive(pEmitter, pParticle)) continue; // TODO: standardize particle sound effects, for now hardcoded fireworks sound. if (!playedSound && curParticle == 0 && pParticle->energy == pEmitter->energy - 1 && rand() % 2) { SoundPlayFile("firework.ogg", 0, pParticle->pos.x, pParticle->pos.y); playedSound = true; } D3DParticleVelocityUpdate(pEmitter, pParticle); // If this particle is hidden from the player's view, don't let D3D try to draw it. if (!IsHidden(params, (long)pParticle->pos.x, (long)pParticle->pos.y, (long)pParticle->pos.x, (long)pParticle->pos.y)) D3DParticleAddToRenderer(pPool, params, pParticleSystem, pParticle); // 10% chance to dim color. if ((int)rand() % 10 == 1) { --pParticle->bgra.b; --pParticle->bgra.g; --pParticle->bgra.r; } } // Emitter moves x, y coords for random fireworks positions. D3DParticleRandomizeEmitterPosition(pEmitter); } // Check timer. if (--pEmitter->timer <= 0) { // Only start another batch if none remaining alive in old. if (pEmitter->numAlive <= 0) { pEmitter->numAlive = 0; pEmitter->numParticles = 0; // Re-randomize the color. pEmitter->bgra.b = FIREWORKS_B; pEmitter->bgra.g = FIREWORKS_G; pEmitter->bgra.r = FIREWORKS_R; for (curParticle = 0; curParticle < pEmitter->maxParticles; curParticle++) { pParticle = &pEmitter->particles[curParticle]; if (pParticle->energy == 0) { D3DParticleInitPosSpeedSphere(pEmitter, pParticle); D3DParticleInitRotation(pEmitter, pParticle); D3DParticleInitColorEnergy(pEmitter, pParticle); } } } pEmitter->timer = pEmitter->timerBase; } } D3DCacheFill(pCacheSystem, pPool, 0); D3DCacheFlush(pCacheSystem, pPool, 0, D3DPT_LINESTRIP); }