static boolean currentColor(player_t* player, float color[3]) { if(!player || !color) return false; if(cfg.xhairVitality) { // Color the crosshair according to how close the player is to death. /// @todo These colors should be cvars. #define HUE_DEAD 0.f #define HUE_LIVE .3f M_HSVToRGB(color, HUE_DEAD + (HUE_LIVE - HUE_DEAD) * MINMAX_OF(0, (float) player->plr->mo->health / maxHealth, 1), 1, 1); #undef HUE_DEAD #undef HUE_LIVE } else { // Custom color. color[CR] = MINMAX_OF(0, cfg.xhairColor[CR], 1); color[CG] = MINMAX_OF(0, cfg.xhairColor[CG], 1); color[CB] = MINMAX_OF(0, cfg.xhairColor[CB], 1); } return true; }
void X_Drawer(int pnum) { #define XHAIR_LINE_WIDTH 1.f player_t* player = players + pnum; int xhair = MINMAX_OF(0, cfg.xhair, NUM_XHAIRS); float scale, oldLineWidth, color[4]; Point2Rawf origin; RectRaw win; if(pnum < 0 || pnum >= MAXPLAYERS) return; // Is there a crosshair to draw? if(xhair == 0) return; color[CA] = currentOpacity(player); if(!(color[CA] > 0)) return; R_ViewWindowGeometry(pnum, &win); origin.x = win.origin.x + (win.size.width / 2); origin.y = win.origin.y + (win.size.height / 2); scale = .125f + MINMAX_OF(0, cfg.xhairSize, 1) * .125f * win.size.height * ((float)80/SCREENHEIGHT); oldLineWidth = DGL_GetFloat(DGL_LINE_WIDTH); DGL_SetFloat(DGL_LINE_WIDTH, XHAIR_LINE_WIDTH); currentColor(player, color); DGL_Color4fv(color); GL_DrawSvg3(VG_XHAIR1 + (xhair-1), &origin, scale, MINMAX_OF(0.f, cfg.xhairAngle, 1.f) * 360); // Restore the previous state. DGL_SetFloat(DGL_LINE_WIDTH, oldLineWidth); #undef XHAIR_LINE_WIDTH }
static float currentOpacity(player_t* player) { float opacity = MINMAX_OF(0, cfg.xhairColor[3], 1); // Dead players are incapable of aiming so we want to fade out the crosshair on death. if(player->plr->flags & DDPF_DEAD) { // Make use of the reborn timer to implement the fade out. if(player->rebornWait <= 0) return 0; if(player->rebornWait < PLAYER_REBORN_TICS) { opacity *= (float)player->rebornWait / PLAYER_REBORN_TICS; } } return opacity; }
KdTreeNode *KdTreeNode_AddChild(KdTreeNode *kdn, double distance, int vertical, int left, void *userData) { KdTreeNode *child; AABox sub; DENG_ASSERT(kdn); distance = MINMAX_OF(-1, distance, 1); if(distance < 0) distance = -distance; if(!vertical) { int division = (int) (kdn->aaBox.minX + 0.5 + distance * (kdn->aaBox.maxX - kdn->aaBox.minX)); sub.minX = (left? division : kdn->aaBox.minX); sub.minY = kdn->aaBox.minY; sub.maxX = (left? kdn->aaBox.maxX : division); sub.maxY = kdn->aaBox.maxY; } else { int division = (int) (kdn->aaBox.minY + 0.5 + distance * (kdn->aaBox.maxY - kdn->aaBox.minY)); sub.minX = kdn->aaBox.minX; sub.minY = (left? division : kdn->aaBox.minY); sub.maxX = kdn->aaBox.maxX; sub.maxY = (left? kdn->aaBox.maxY : division); } child = kdn->subs[left?1:0]; if(!child) { child = kdn->subs[left?1:0] = KdTreeNode_New(kdn->kdTree, &sub); child->parent = kdn; } child->userData = userData; return child; }
void DM_Music_Set(int prop, float value) { if(!midiAvail) return; switch(prop) { case MUSIP_VOLUME: { int val = MINMAX_OF(0, (byte) (value * 255 + .5f), 255); // Straighten the volume curve. val <<= 8; // Make it a word. val = (int) (255.9980469 * sqrt(value)); mixer4i(MIX_MIDI, MIX_SET, MIX_VOLUME, val); break; } default: break; } }
void ColorPalette_Color(const colorpalette_t* pal, int colorIdx, uint8_t rgb[3]) { DENG_ASSERT(pal && rgb); #if _DEBUG if(colorIdx < 0 || colorIdx >= pal->_colorCount) Con_Message("Warning: ColorPalette::Color: ColorIdx %u out of range [0..%u).", colorIdx, pal->_colorCount); #endif if(0 == pal->_colorCount) { rgb[CR] = rgb[CG] = rgb[CB] = 0; return; } size_t offset = 3 * (size_t)MINMAX_OF(0, colorIdx, pal->_colorCount-1); rgb[CR] = pal->_colorData[offset + CR]; rgb[CG] = pal->_colorData[offset + CG]; rgb[CB] = pal->_colorData[offset + CB]; }
void P_SectorModifyLight(Sector* sector, float value) { float level = MINMAX_OF(0.f, P_SectorLight(sector) + value, 1.f); P_SectorSetLight(sector, level); }
/** * @param plr Player being given item. * @param item Type of item being given. * @param dropped @c true = the item was dropped by some entity. * * @return @c true iff the item should be destroyed. */ static dd_bool pickupItem(player_t *plr, itemtype_t item, dd_bool dropped) { if(!plr) return false; switch(item) { case IT_ARMOR_GREEN: if(!P_GiveArmor(plr, armorClass[0], armorPoints[MINMAX_OF(0, armorClass[0] - 1, 1)])) return false; P_SetMessage(plr, 0, GOTARMOR); if(!mapSetup) S_ConsoleSound(SFX_ITEMUP, NULL, plr - players); break; case IT_ARMOR_BLUE: if(!P_GiveArmor(plr, armorClass[1], armorPoints[MINMAX_OF(0, armorClass[1] - 1, 1)])) return false; P_SetMessage(plr, 0, GOTMEGA); if(!mapSetup) S_ConsoleSound(SFX_ITEMUP, NULL, plr - players); break; case IT_ARMOR_BONUS: if(!plr->armorType) P_PlayerSetArmorType(plr, armorClass[0]); if(plr->armorPoints < armorPoints[1]) P_PlayerGiveArmorBonus(plr, 1); P_SetMessage(plr, 0, GOTARMBONUS); if(!mapSetup) { S_ConsoleSound(SFX_ITEMUP, NULL, plr - players); // Maybe unhide the HUD? ST_HUDUnHide(plr - players, HUE_ON_PICKUP_ARMOR); } break; case IT_HEALTH_PACK: if(!P_GiveHealth(plr, 10)) return false; P_SetMessage(plr, 0, GOTSTIM); if(!mapSetup) S_ConsoleSound(SFX_ITEMUP, NULL, plr - players); break; case IT_HEALTH_KIT: { int oldHealth = plr->health; /** * DOOM bug: * The following test was originaly placed AFTER the call to * P_GiveHealth thereby making the first outcome impossible as * the medikit gives 25 points of health. This resulted that * the GOTMEDINEED "Picked up a medikit that you REALLY need" * was never used. */ if(!P_GiveHealth(plr, 25)) return false; P_SetMessage(plr, 0, GET_TXT((oldHealth < 25)? TXT_GOTMEDINEED : TXT_GOTMEDIKIT)); if(!mapSetup) S_ConsoleSound(SFX_ITEMUP, NULL, plr - players); break; } case IT_HEALTH_BONUS: plr->health++; // Can go over 100%. if(plr->health > healthLimit) plr->health = healthLimit; plr->plr->mo->health = plr->health; plr->update |= PSF_HEALTH; P_SetMessage(plr, 0, GOTHTHBONUS); if(!mapSetup) { S_ConsoleSound(SFX_ITEMUP, NULL, plr - players); // Maybe unhide the HUD? ST_HUDUnHide(plr - players, HUE_ON_PICKUP_HEALTH); } break; case IT_HEALTH_SOULSPHERE: plr->health += soulSphereHealth; if(plr->health > soulSphereLimit) plr->health = soulSphereLimit; plr->plr->mo->health = plr->health; plr->update |= PSF_HEALTH; P_SetMessage(plr, 0, GOTSUPER); if(!mapSetup) { S_ConsoleSound(SFX_GETPOW, NULL, plr - players); // Maybe unhide the HUD? ST_HUDUnHide(plr - players, HUE_ON_PICKUP_HEALTH); } break; case IT_KEY_BLUE: if(!plr->keys[KT_BLUECARD]) { P_GiveKey(plr, KT_BLUECARD); P_SetMessage(plr, 0, GOTBLUECARD); if(!mapSetup) S_ConsoleSound(SFX_ITEMUP, NULL, plr - players); } if(IS_NETGAME) return false; break; case IT_KEY_YELLOW: if(!plr->keys[KT_YELLOWCARD]) { P_GiveKey(plr, KT_YELLOWCARD); P_SetMessage(plr, 0, GOTYELWCARD); if(!mapSetup) S_ConsoleSound(SFX_ITEMUP, NULL, plr - players); } if(IS_NETGAME) return false; break; case IT_KEY_RED: if(!plr->keys[KT_REDCARD]) { P_GiveKey(plr, KT_REDCARD); P_SetMessage(plr, 0, GOTREDCARD); if(!mapSetup) S_ConsoleSound(SFX_ITEMUP, NULL, plr - players); } if(IS_NETGAME) return false; break; case IT_KEY_BLUESKULL: if(!plr->keys[KT_BLUESKULL]) { P_GiveKey(plr, KT_BLUESKULL); P_SetMessage(plr, 0, GOTBLUESKUL); if(!mapSetup) S_ConsoleSound(SFX_ITEMUP, NULL, plr - players); } if(IS_NETGAME) return false; break; case IT_KEY_YELLOWSKULL: if(!plr->keys[KT_YELLOWSKULL]) { P_GiveKey(plr, KT_YELLOWSKULL); P_SetMessage(plr, 0, GOTYELWSKUL); if(!mapSetup) S_ConsoleSound(SFX_ITEMUP, NULL, plr - players); } if(IS_NETGAME) return false; break; case IT_KEY_REDSKULL: if(!plr->keys[KT_REDSKULL]) { P_GiveKey(plr, KT_REDSKULL); P_SetMessage(plr, 0, GOTREDSKULL); if(!mapSetup) S_ConsoleSound(SFX_ITEMUP, NULL, plr - players); } if(IS_NETGAME) return false; break; case IT_MEGASPHERE: if(!(gameModeBits & GM_ANY_DOOM2)) return false; plr->health = megaSphereHealth; plr->plr->mo->health = plr->health; plr->update |= PSF_HEALTH; P_GiveArmor(plr, armorClass[1], armorPoints[MINMAX_OF(0, armorClass[1] - 1, 1)]); P_SetMessage(plr, 0, GOTMSPHERE); if(!mapSetup) { S_ConsoleSound(SFX_GETPOW, NULL, plr - players); // Maybe unhide the HUD? ST_HUDUnHide(plr - players, HUE_ON_PICKUP_HEALTH); } break; case IT_INVUL: if(!P_GivePower(plr, PT_INVULNERABILITY)) return false; P_SetMessage(plr, 0, GOTINVUL); if(!mapSetup) S_ConsoleSound(SFX_GETPOW, NULL, plr - players); break; case IT_BERSERK: if(!P_GivePower(plr, PT_STRENGTH)) return false; P_SetMessage(plr, 0, GOTBERSERK); if(plr->readyWeapon != WT_FIRST && cfg.berserkAutoSwitch) { plr->pendingWeapon = WT_FIRST; plr->update |= PSF_PENDING_WEAPON | PSF_READY_WEAPON; } if(!mapSetup) S_ConsoleSound(SFX_GETPOW, NULL, plr - players); break; case IT_INVIS: if(!P_GivePower(plr, PT_INVISIBILITY)) return false; P_SetMessage(plr, 0, GOTINVIS); if(!mapSetup) S_ConsoleSound(SFX_GETPOW, NULL, plr - players); break; case IT_SUIT: if(!P_GivePower(plr, PT_IRONFEET)) return false; P_SetMessage(plr, 0, GOTSUIT); if(!mapSetup) S_ConsoleSound(SFX_GETPOW, NULL, plr - players); break; case IT_ALLMAP: if(!P_GivePower(plr, PT_ALLMAP)) return false; P_SetMessage(plr, 0, GOTMAP); if(!mapSetup) S_ConsoleSound(SFX_GETPOW, NULL, plr - players); break; case IT_VISOR: if(!P_GivePower(plr, PT_INFRARED)) return false; P_SetMessage(plr, 0, GOTVISOR); if(!mapSetup) S_ConsoleSound(SFX_GETPOW, NULL, plr - players); break; case IT_BACKPACK: P_GiveBackpack(plr); if(!mapSetup) S_ConsoleSound(SFX_ITEMUP, NULL, plr - players); break; case IT_AMMO_CLIP: if(!P_GiveAmmo(plr, AT_CLIP, dropped? 0 /*half a clip*/ : 1)) return false; P_SetMessage(plr, 0, GOTCLIP); if(!mapSetup) S_ConsoleSound(SFX_ITEMUP, NULL, plr - players); break; case IT_AMMO_CLIP_BOX: if(!P_GiveAmmo(plr, AT_CLIP, 5)) return false; P_SetMessage(plr, 0, GOTCLIPBOX); if(!mapSetup) S_ConsoleSound(SFX_ITEMUP, NULL, plr - players); break; case IT_AMMO_ROCKET: if(!P_GiveAmmo(plr, AT_MISSILE, 1)) return false; P_SetMessage(plr, 0, GOTROCKET); if(!mapSetup) S_ConsoleSound(SFX_ITEMUP, NULL, plr - players); break; case IT_AMMO_ROCKET_BOX: if(!P_GiveAmmo(plr, AT_MISSILE, 5)) return false; P_SetMessage(plr, 0, GOTROCKBOX); if(!mapSetup) S_ConsoleSound(SFX_ITEMUP, NULL, plr - players); break; case IT_AMMO_CELL: if(!P_GiveAmmo(plr, AT_CELL, 1)) return false; P_SetMessage(plr, 0, GOTCELL); if(!mapSetup) S_ConsoleSound(SFX_ITEMUP, NULL, plr - players); break; case IT_AMMO_CELL_BOX: if(!P_GiveAmmo(plr, AT_CELL, 5)) return false; P_SetMessage(plr, 0, GOTCELLBOX); if(!mapSetup) S_ConsoleSound(SFX_ITEMUP, NULL, plr - players); break; case IT_AMMO_SHELL: if(!P_GiveAmmo(plr, AT_SHELL, 1)) return false; P_SetMessage(plr, 0, GOTSHELLS); if(!mapSetup) S_ConsoleSound(SFX_ITEMUP, NULL, plr - players); break; case IT_AMMO_SHELL_BOX: if(!P_GiveAmmo(plr, AT_SHELL, 5)) return false; P_SetMessage(plr, 0, GOTSHELLBOX); if(!mapSetup) S_ConsoleSound(SFX_ITEMUP, NULL, plr - players); break; case IT_WEAPON_BFG: return pickupWeapon(plr, WT_SEVENTH, dropped, GOTBFG9000); case IT_WEAPON_CHAINGUN: return pickupWeapon(plr, WT_FOURTH, dropped, GOTCHAINGUN); case IT_WEAPON_CHAINSAW: return pickupWeapon(plr, WT_EIGHTH, dropped, GOTCHAINSAW); case IT_WEAPON_RLAUNCHER: return pickupWeapon(plr, WT_FIFTH, dropped, GOTLAUNCHER); case IT_WEAPON_PLASMARIFLE: return pickupWeapon(plr, WT_SIXTH, dropped, GOTPLASMA); case IT_WEAPON_SHOTGUN: return pickupWeapon(plr, WT_THIRD, dropped, GOTSHOTGUN); case IT_WEAPON_SSHOTGUN: return pickupWeapon(plr, WT_NINETH, dropped, GOTSHOTGUN2); default: Con_Error("pickupItem: Unknown item %i.", (int) item); } return true; }
static void prepareColorTable(colorpalette_t* pal, const int compOrder[3], const uint8_t compBits[3], const uint8_t* colorData, int colorCount) { assert(pal); { uint8_t order[3], bits[3], cb; const uint8_t* src; // Ensure input is in range. order[0] = MINMAX_OF(0, compOrder[0], 2); order[1] = MINMAX_OF(0, compOrder[1], 2); order[2] = MINMAX_OF(0, compOrder[2], 2); bits[CR] = MIN_OF(compBits[CR], COLORPALETTE_MAX_COMPONENT_BITS); bits[CG] = MIN_OF(compBits[CG], COLORPALETTE_MAX_COMPONENT_BITS); bits[CB] = MIN_OF(compBits[CB], COLORPALETTE_MAX_COMPONENT_BITS); if(NULL != pal->_colorData) { free(pal->_colorData); pal->_colorData = NULL; pal->_colorCount = 0; } if(NULL != pal->_18To8LUT) { free(pal->_18To8LUT); pal->_18To8LUT = NULL; pal->_flags |= CPF_UPDATE_18TO8; } pal->_colorCount = colorCount; if(NULL == (pal->_colorData = (uint8_t*) malloc(pal->_colorCount * 3 * sizeof(uint8_t)))) Con_Error("ColorPalette::prepareColorTable: Failed on allocation of %lu bytes for " "color table.", (unsigned long) (pal->_colorCount * 3 * sizeof(uint8_t))); // Already in the format we want? if(8 == bits[CR] && 8 == bits[CG] && 8 == bits[CB]) { // Great! Just copy it as-is. memcpy(pal->_colorData, colorData, pal->_colorCount * 3); // Do we need to adjust the order? if(0 != order[CR]|| 1 != order[CG] || 2 != order[CB]) { int i; for(i = 0; i < pal->_colorCount; ++i) { uint8_t* dst = &pal->_colorData[i * 3]; uint8_t tmp[3]; tmp[0] = dst[0]; tmp[1] = dst[1]; tmp[2] = dst[2]; dst[CR] = tmp[order[CR]]; dst[CG] = tmp[order[CG]]; dst[CB] = tmp[order[CB]]; } } return; } // Conversion is necessary. src = colorData; cb = 0; { int i; for(i = 0; i < pal->_colorCount; ++i) { uint8_t* dst = &pal->_colorData[i * 3]; int tmp[3]; tmp[CR] = tmp[CG] = tmp[CB] = 0; M_ReadBits(bits[order[CR]], &src, &cb, (uint8_t*) &(tmp[order[CR]])); M_ReadBits(bits[order[CG]], &src, &cb, (uint8_t*) &(tmp[order[CG]])); M_ReadBits(bits[order[CB]], &src, &cb, (uint8_t*) &(tmp[order[CB]])); // Need to do any scaling? if(8 != bits[CR]) { if(bits[CR] < 8) tmp[CR] <<= 8 - bits[CR]; else tmp[CR] >>= bits[CR] - 8; } if(8 != bits[CG]) { if(bits[CG] < 8) tmp[CG] <<= 8 - bits[CG]; else tmp[CG] >>= bits[CG] - 8; } if(8 != bits[CB]) { if(bits[CB] < 8) tmp[CB] <<= 8 - bits[CB]; else tmp[CB] >>= bits[CB] - 8; } // Store the final color. dst[CR] = (uint8_t) MINMAX_OF(0, tmp[CR], 255); dst[CG] = (uint8_t) MINMAX_OF(0, tmp[CG], 255); dst[CB] = (uint8_t) MINMAX_OF(0, tmp[CB], 255); }} } }
void FR_SetGlitterStrength(float value) { errorIfNotInited("FR_SetGlitterStrength"); currentAttribs()->glitterStrength = MINMAX_OF(0, value, 1); }
void FR_SetShadowStrength(float value) { errorIfNotInited("FR_SetShadowStrength"); currentAttribs()->shadowStrength = MINMAX_OF(0, value, 1); }