RectRawf *Rectf_United(Rectf const *rect, Rectf const *other, RectRawf *united) { RectRawf normA, normB; if(!united) return NULL; if(!other) { united->origin.x = Point2f_X(rect->origin); united->origin.y = Point2f_Y(rect->origin); united->size.width = Size2f_Width(rect->size); united->size.height = Size2f_Height(rect->size); return united; } Rectf_Normalized(rect, &normA); Rectf_Normalized(other, &normB); united->origin.x = MIN_OF(normA.origin.x, normB.origin.x); united->origin.y = MIN_OF(normA.origin.y, normB.origin.y); united->size.width = MAX_OF(normA.origin.x + normA.size.width, normB.origin.x + normB.size.width) - united->origin.x; united->size.height = MAX_OF(normA.origin.y + normA.size.height, normB.origin.y + normB.size.height) - united->origin.y; return united; }
size_t Zip::readLump(int lumpIdx, uint8_t* buffer, size_t startOffset, size_t length, bool tryCache) { LOG_AS("Zip::readLump"); ZipFile const& file = reinterpret_cast<ZipFile&>(lump(lumpIdx)); LOG_TRACE("\"%s:%s\" (%u bytes%s) [%u +%u]") << de::NativePath(composePath()).pretty() << de::NativePath(file.composePath()).pretty() << (unsigned long) file.size() << (file.isCompressed()? ", compressed" : "") << startOffset << length; // Try to avoid a file system read by checking for a cached copy. if(tryCache) { uint8_t const* data = d->lumpCache? d->lumpCache->data(lumpIdx) : 0; LOG_TRACE("Cache %s on #%i") << (data? "hit" : "miss") << lumpIdx; if(data) { size_t readBytes = MIN_OF(file.size(), length); memcpy(buffer, data + startOffset, readBytes); return readBytes; } } size_t readBytes; if(!startOffset && length == file.size()) { // Read it straight to the caller's data buffer. readBytes = d->bufferLump(file, buffer); } else { // Allocate a temporary buffer and read the whole lump into it(!). uint8_t* lumpData = (uint8_t*) M_Malloc(file.size()); if(!lumpData) throw Error("Zip::readLumpSection", QString("Failed on allocation of %1 bytes for work buffer").arg(file.size())); if(d->bufferLump(file, lumpData)) { readBytes = MIN_OF(file.size(), length); memcpy(buffer, lumpData + startOffset, readBytes); } else { readBytes = 0; } M_Free(lumpData); } /// @todo Do not check the read length here. if(readBytes < MIN_OF(file.size(), length)) throw Error("Zip::readLumpSection", QString("Only read %1 of %2 bytes of lump #%3").arg(readBytes).arg(length).arg(lumpIdx)); return readBytes; }
static void timeDeltaStatistics(int deltaMs) { timeDeltas[timeDeltasIndex++] = deltaMs; if(timeDeltasIndex == NUM_FRAMETIME_DELTAS) { timeDeltasIndex = 0; if(devShowFrameTimeDeltas) { int maxDelta = timeDeltas[0], minDelta = timeDeltas[0]; float average = 0, variance = 0; int lateCount = 0; int i; for(i = 0; i < NUM_FRAMETIME_DELTAS; ++i) { maxDelta = MAX_OF(timeDeltas[i], maxDelta); minDelta = MIN_OF(timeDeltas[i], minDelta); average += timeDeltas[i]; variance += timeDeltas[i] * timeDeltas[i]; if(timeDeltas[i] > 0) lateCount++; } average /= NUM_FRAMETIME_DELTAS; variance /= NUM_FRAMETIME_DELTAS; Con_Message("Time deltas [%i frames]: min=%-6i max=%-6i avg=%-11.7f late=%5.1f%% var=%12.10f", NUM_FRAMETIME_DELTAS, minDelta, maxDelta, average, lateCount/(float)NUM_FRAMETIME_DELTAS*100, variance); } } }
void *Z_Realloc(void *ptr, size_t n, int mallocTag) { int tag = ptr ? Z_GetTag(ptr) : mallocTag; void *p; lockZone(); n = ALIGNED(n); p = Z_Malloc(n, tag, 0); // User always 0; if (ptr) { size_t bsize; // Has old data; copy it. memblock_t *block = Z_GetBlock(ptr); #ifdef LIBDENG_FAKE_MEMORY_ZONE bsize = block->areaSize; #else bsize = block->size - sizeof(memblock_t); #endif memcpy(p, ptr, MIN_OF(n, bsize)); Z_Free(ptr); } unlockZone(); return p; }
/** * Reads a block of data from the buffer. * * @param data The read data will be written here. * @param length Number of bytes to read. If there aren't this many * bytes currently available, reads all the available * data instead. * * @return Actual number of bytes read. */ int read(void* data, int length) { Sys_Lock(_mutex); // We'll read as much as we have. int avail = availableForReading(); length = MIN_OF(length, avail); const int remainder = _end - _readPos; if(length <= remainder) { memcpy(data, _readPos, length); _readPos += length; if(_readPos == _end) _readPos = _buf; // May wrap around. } else { memcpy(data, _readPos, remainder); memcpy((byte*)data + remainder, _buf, length - remainder); _readPos = _buf + length - remainder; } Sys_Unlock(_mutex); // This is how much we were able to read. return length; }
/** * Expected: * <pre> * "<whitespace> = <whitespace> [|"]<string>[|"]" * </pre> */ static boolean parseString(char** str, char* buf, size_t bufLen) { size_t len; char* end; if(!buf || bufLen == 0) return false; *str = M_SkipWhite(*str); if(**str != '=') return false; // Now I'm confused! // Skip over any leading whitespace. *str = M_SkipWhite(*str + 1); // Skip over any opening '"' character. if(**str == '"') (*str)++; // Find the end of the string. end = *str; while(*end && *end != '}' && *end != ',' && *end !='"') { end++; } len = end - *str; if(len != 0) { dd_snprintf(buf, MIN_OF(len+1, bufLen), "%s", *str); *str = end; } // Skip over any closing '"' character. if(**str == '"') (*str)++; return true; }
char* M_LimitedStrCat(char* buf, const char* str, size_t maxWidth, char separator, size_t bufLength) { dd_bool isEmpty = !buf[0]; size_t length; // How long is this name? length = MIN_OF(maxWidth, strlen(str)); // A separator is included if this is not the first name. if (separator && !isEmpty) ++length; // Does it fit? if (strlen(buf) + length < bufLength) { if (separator && !isEmpty) { char sepBuf[2]; sepBuf[0] = separator; sepBuf[1] = 0; strcat(buf, sepBuf); } strncat(buf, str, length); } return buf; }
/// @pre This and @a other have been normalized. static Rectf *Rectf_UniteRaw2(Rectf *r, RectRawf const *other) { Point2Rawf oldOrigin; DENG_ASSERT(r && other); Point2f_Raw(r->origin, &oldOrigin); Rectf_SetXY(r, MIN_OF(Point2f_X(r->origin), other->origin.x), MIN_OF(Point2f_Y(r->origin), other->origin.y)); Rectf_SetWidthHeight(r, MAX_OF(oldOrigin.x + Size2f_Width(r->size), other->origin.x + other->size.width) - Point2f_X(r->origin), MAX_OF(oldOrigin.y + Size2f_Height(r->size), other->origin.y + other->size.height) - Point2f_Y(r->origin)); return r; }
void Loop_RunTics(void) { double elapsedTime, ticLength, nowTime; // Do a network update first. N_Update(); Net_Update(); // Check the clock. if(firstTic) { // On the first tic, no time actually passes. firstTic = false; lastRunTicsTime = Timer_Seconds(); return; } // Let's see how much time has passed. This is affected by "settics". nowTime = Timer_Seconds(); elapsedTime = nowTime - lastRunTicsTime; // Remember when this frame started. lastRunTicsTime = nowTime; // Tic until all the elapsed time has been processed. while(elapsedTime > 0) { ticLength = MIN_OF(MAX_FRAME_TIME, elapsedTime); elapsedTime -= ticLength; // Will this be a sharp tick? DD_CheckSharpTick(ticLength); #ifdef __CLIENT__ // Process input events. DD_ProcessEvents(ticLength); if(!processSharpEventsAfterTickers) { // We are allowed to process sharp events before tickers. DD_ProcessSharpEvents(ticLength); } #endif // Call all the tickers. baseTicker(ticLength); #ifdef __CLIENT__ if(processSharpEventsAfterTickers) { // This is done after tickers for compatibility with ye olde game logic. DD_ProcessSharpEvents(ticLength); } #endif // Various global variables are used for counting time. advanceTime(ticLength); } }
static void DataIn(void) { int iChunk; iChunk = MIN_OF(MAX_PACKET_SIZE0, iResidue); USBHwEPWrite(0x80, pbData, iChunk); pbData += iChunk; iResidue -= iChunk; }
/** * SDL's events are all returned from the same routine. This function * is called periodically, and the events we are interested in a saved * into our own buffer. */ void I_PollEvents(void) { SDL_Event event; keyevent_t *e; while(SDL_PollEvent(&event)) { switch(event.type) { case SDL_KEYDOWN: case SDL_KEYUP: e = I_NewKeyEvent(); e->event = (event.type == SDL_KEYDOWN ? IKE_DOWN : IKE_UP); e->ddkey = I_TranslateKeyCode(event.key.keysym.sym); /*printf("sdl:%i ddkey:%i\n", event.key.keysym.scancode, e->ddkey);*/ break; case SDL_MOUSEBUTTONDOWN: mouseClickers[MIN_OF(event.button.button - 1, IMB_MAXBUTTONS - 1)].down++; break; case SDL_MOUSEBUTTONUP: mouseClickers[MIN_OF(event.button.button - 1, IMB_MAXBUTTONS - 1)].up++; break; case SDL_JOYBUTTONDOWN: joyClickers[MIN_OF(event.jbutton.button, IJOY_MAXBUTTONS - 1)].down++; break; case SDL_JOYBUTTONUP: joyClickers[MIN_OF(event.jbutton.button, IJOY_MAXBUTTONS - 1)].up++; break; case SDL_QUIT: // The system wishes to close the program immediately... Sys_Quit(); break; default: // The rest of the events are ignored. break; } } }
/** * Takes a copy of the engine's entry points and exported data. Returns * a pointer to the structure that contains our entry points and exports. */ game_export_t *GetGameAPI(game_import_t *imports) { // Take a copy of the imports, but only copy as much data as is // allowed and legal. memset(&gi, 0, sizeof(gi)); memcpy(&gi, imports, MIN_OF(sizeof(game_import_t), imports->apiSize)); // Clear all of our exports. memset(&gx, 0, sizeof(gx)); // Fill in the data for the exports. gx.apiSize = sizeof(gx); gx.PreInit = G_PreInit; gx.PostInit = G_PostInit; gx.Shutdown = G_Shutdown; gx.Ticker = G_Ticker; gx.G_Drawer = D_Display; gx.G_Drawer2 = D_Display2; gx.PrivilegedResponder = (boolean (*)(event_t *)) G_PrivilegedResponder; gx.FallbackResponder = Hu_MenuResponder; gx.G_Responder = G_Responder; gx.MobjThinker = P_MobjThinker; gx.MobjFriction = (float (*)(void *)) P_MobjGetFriction; gx.EndFrame = G_EndFrame; gx.ConsoleBackground = D_ConsoleBg; gx.UpdateState = G_UpdateState; #undef Get gx.GetInteger = G_GetInteger; gx.GetVariable = G_GetVariable; gx.NetServerStart = D_NetServerStarted; gx.NetServerStop = D_NetServerClose; gx.NetConnect = D_NetConnect; gx.NetDisconnect = D_NetDisconnect; gx.NetPlayerEvent = D_NetPlayerEvent; gx.NetWorldEvent = D_NetWorldEvent; gx.HandlePacket = D_HandlePacket; gx.NetWriteCommands = D_NetWriteCommands; gx.NetReadCommands = D_NetReadCommands; // Data structure sizes. gx.ticcmdSize = sizeof(ticcmd_t); gx.mobjSize = sizeof(mobj_t); gx.polyobjSize = sizeof(polyobj_t); gx.SetupForMapData = P_SetupForMapData; // These really need better names. Ideas? gx.HandleMapDataPropertyValue = P_HandleMapDataPropertyValue; gx.HandleMapObjectStatusReport = P_HandleMapObjectStatusReport; return &gx; }
static dd_bool giveOneAmmo(player_t *plr, ammotype_t ammoType, int numClips) { int numRounds = 0; DENG_ASSERT(plr != 0); DENG_ASSERT((ammoType >= 0 && ammoType < NUM_AMMO_TYPES) || ammoType == AT_NOAMMO); // Giving the special 'unlimited ammo' type always succeeds. if(ammoType == AT_NOAMMO) return true; // Already fully stocked? if(plr->ammo[ammoType].owned >= plr->ammo[ammoType].max) return false; // Translate number of clips to individual rounds. if(numClips >= 1) { numRounds = numClips * clipAmmo[ammoType]; } else if(numClips == 0) { // Half of one clip. numRounds = clipAmmo[ammoType] / 2; } else { // Fully replenish. numRounds = plr->ammo[ammoType].max; } // Give double the number of rounds at easy/nightmare skill levels. if(G_Ruleset_Skill() == SM_BABY || G_Ruleset_Skill() == SM_NIGHTMARE) { numRounds *= 2; } // Given the new ammo the player may want to change weapon automatically. P_MaybeChangeWeapon(plr, WT_NOCHANGE, ammoType, false /*don't force*/); // Restock the player. plr->ammo[ammoType].owned = MIN_OF(plr->ammo[ammoType].max, plr->ammo[ammoType].owned + numRounds); plr->update |= PSF_AMMO; // Maybe unhide the HUD? ST_HUDUnHide(plr - players, HUE_ON_PICKUP_AMMO); return true; }
int usbd_fifo_get(struct fifo_descriptor *pfifodesc, void *buf, int bufsize, int user_mode_buffer) { int result = 0; if( !pfifodesc ) return -EINVAL; if( !buf ) return -EINVAL; if( !bufsize ) return -EINVAL; spin_lock(&pfifodesc->lock); if( !list_empty(&pfifodesc->entrylist) ) { struct fifo_entry *pfifoentry; pfifoentry = (struct fifo_entry*)pfifodesc->entrylist.next; // calc the nuber of bytes to copy result = MIN_OF(bufsize, pfifoentry->size - pfifoentry->read); if( user_mode_buffer ) { if( copy_to_user(buf, pfifoentry->data+pfifoentry->read, result) != 0 ) { TRACE("usbd_fifo_get: cannot copy to user buffer\n"); } } else { memcpy(buf, pfifoentry->data+pfifoentry->read, result); } pfifoentry->read += result; // is all event copied? if( pfifoentry->read == pfifoentry->size ) { list_del(&pfifoentry->entry); kfree(pfifoentry); pfifodesc->num_entries--; } } spin_unlock(&pfifodesc->lock); return result; }
/** * Handles IN/OUT transfers on EP0 * * @param [in] bEP Endpoint address * @param [in] bEPStat Endpoint status */ void USBHandleControlTransfer(U8 bEP, U8 bEPStat) { int iChunk, iType; if (bEP == 0x00) { // OUT transfer if (bEPStat & EP_STATUS_SETUP) { // setup packet, reset request message state machine USBHwEPRead(0x00, (U8 *)&Setup, sizeof(Setup)); // DBG("S%x", Setup.bRequest); // defaults for data pointer and residue iType = REQTYPE_GET_TYPE(Setup.bmRequestType); pbData = apbDataStore[iType]; iResidue = Setup.wLength; iLen = Setup.wLength; if ((Setup.wLength == 0) || (REQTYPE_GET_DIR(Setup.bmRequestType) == REQTYPE_DIR_TO_HOST)) { // ask installed handler to process request if (!_HandleRequest(&Setup, &iLen, &pbData)) { DBG("_HandleRequest1 failed\n"); StallControlPipe(bEPStat); return; } // send smallest of requested and offered length iResidue = MIN_OF(iLen, Setup.wLength); // send first part (possibly a zero-length status message) DataIn(); } } else { if (iResidue > 0) { // store data iChunk = USBHwEPRead(0x00, pbData, iResidue); if (iChunk < 0) { StallControlPipe(bEPStat); return; } pbData += iChunk; iResidue -= iChunk; if (iResidue == 0) { // received all, send data to handler iType = REQTYPE_GET_TYPE(Setup.bmRequestType); pbData = apbDataStore[iType]; if (!_HandleRequest(&Setup, &iLen, &pbData)) { DBG("_HandleRequest2 failed\n"); StallControlPipe(bEPStat); return; } // send status to host DataIn(); } } else { // absorb zero-length status message iChunk = USBHwEPRead(0x00, NULL, 0); DBG(iChunk > 0 ? "?" : ""); } } } else if (bEP == 0x80) { // IN transfer // send more data if available (possibly a 0-length packet) DataIn(); } else { ASSERT(FALSE); } }
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); }} } }
// Fully replenish. numRounds = plr->ammo[ammoType].max; } // Give extra rounds at easy/nightmare skill levels. if(G_Ruleset_Skill() == SM_BABY || G_Ruleset_Skill() == SM_NIGHTMARE) { numRounds += numRounds >> 1; } // Given the new ammo the player may want to change weapon automatically. P_MaybeChangeWeapon(plr, WT_NOCHANGE, ammoType, false /*don't force*/); // Restock the player. plr->ammo[ammoType].owned = MIN_OF(plr->ammo[ammoType].max, plr->ammo[ammoType].owned + numRounds); plr->update |= PSF_AMMO; // Maybe unhide the HUD? ST_HUDUnHide(plr - players, HUE_ON_PICKUP_AMMO); return true; } dd_bool P_GiveAmmo(player_t *plr, ammotype_t ammoType, int numRounds) { int gaveAmmos = 0; if(ammoType == NUM_AMMO_TYPES) { // Give all ammos.