// Call a function by name static bool callFunction(QScriptEngine *engine, const QString &function, const QScriptValueList &args, bool required = false) { code_part level = required ? LOG_ERROR : LOG_WARNING; QScriptValue value = engine->globalObject().property(function); if (!value.isValid() || !value.isFunction()) { // not necessarily an error, may just be a trigger that is not defined (ie not needed) // or it could be a typo in the function name or ... debug(level, "called function (%s) not defined", function.toUtf8().constData()); return false; } int ticks = wzGetTicks(); QScriptValue result = value.call(QScriptValue(), args); ticks = wzGetTicks() - ticks; if (ticks > MAX_MS) { debug(LOG_SCRIPT, "%s took %d ms at time %d", function.toAscii().constData(), ticks, wzGetTicks()); } if (engine->hasUncaughtException()) { int line = engine->uncaughtExceptionLineNumber(); QStringList bt = engine->uncaughtExceptionBacktrace(); for (int i = 0; i < bt.size(); i++) { debug(LOG_ERROR, "%d : %s", i, bt.at(i).toAscii().constData()); } ASSERT(false, "Uncaught exception calling function \"%s\" at line %d: %s", function.toAscii().constData(), line, result.toString().toAscii().constData()); engine->clearExceptions(); return false; } return true; }
void SDL_framerateDelay(FPSmanager * manager) { uint32_t current_ticks; uint32_t target_ticks; uint32_t the_delay; /* * Next frame */ manager->framecount++; /* * Get/calc ticks */ current_ticks = wzGetTicks(); target_ticks = manager->lastticks + (uint32_t) ((float) manager->framecount * manager->rateticks); if (current_ticks <= target_ticks) { the_delay = target_ticks - current_ticks; #if defined(WZ_OS_WIN32) || defined(WZ_OS_WIN64) Sleep(the_delay / 1000); #else usleep(the_delay); #endif } else { manager->framecount = 0; manager->lastticks = wzGetTicks(); } }
/* The main game loop */ GAMECODE gameLoop() { static uint32_t lastFlushTime = 0; static int renderBudget = 0; // Scaled time spent rendering minus scaled time spent updating. static bool previousUpdateWasRender = false; const Rational renderFraction(2, 5); // Minimum fraction of time spent rendering. const Rational updateFraction = Rational(1) - renderFraction; countUpdate(false); // kick off with correct counts while (true) { // Receive NET_BLAH messages. // Receive GAME_BLAH messages, and if it's time, process exactly as many GAME_BLAH messages as required to be able to tick the gameTime. recvMessage(); // Update gameTime and graphicsTime, and corresponding deltas. Note that gameTime and graphicsTime pause, if we aren't getting our GAME_GAME_TIME messages. gameTimeUpdate(renderBudget > 0 || previousUpdateWasRender); if (deltaGameTime == 0) { break; // Not doing a game state update. } ASSERT(!paused && !gameUpdatePaused(), "Nonsensical pause values."); unsigned before = wzGetTicks(); syncDebug("Begin game state update, gameTime = %d", gameTime); gameStateUpdate(); syncDebug("End game state update, gameTime = %d", gameTime); unsigned after = wzGetTicks(); renderBudget -= (after - before) * renderFraction.n; renderBudget = std::max(renderBudget, (-updateFraction * 500).floor()); previousUpdateWasRender = false; ASSERT(deltaGraphicsTime == 0, "Shouldn't update graphics and game state at once."); } if (realTime - lastFlushTime >= 400u) { lastFlushTime = realTime; NETflush(); // Make sure that we aren't waiting too long to send data. } unsigned before = wzGetTicks(); GAMECODE renderReturn = renderLoop(); unsigned after = wzGetTicks(); renderBudget += (after - before) * updateFraction.n; renderBudget = std::min(renderBudget, (renderFraction * 500).floor()); previousUpdateWasRender = true; return renderReturn; }
/* Respond to a mouse click */ void W_EDITBOX::clicked(W_CONTEXT *psContext, WIDGET_KEY) { if (state & WEDBS_DISABLE) // disabled button. { return; } // Set cursor position to the click location. iV_SetFont(FontID); setCursorPosPixels(psContext->mx - x); // Cursor should be visible instantly. blinkOffset = wzGetTicks(); if ((state & WEDBS_MASK) == WEDBS_FIXED) { if (AudioCallback) { AudioCallback(ClickedAudioID); } /* Set up the widget state */ state = (state & ~WEDBS_MASK) | WEDBS_INSERT; /* Calculate how much of the string can appear in the box */ fitStringEnd(); /* Clear the input buffer */ inputClearBuffer(); /* Tell the form that the edit box has focus */ screenSetFocus(psContext->psScreen, this); } }
// reset the game time modifiers void gameTimeResetMod(void) { timeOffset = graphicsTime; baseTime = wzGetTicks(); modifier = 1.0f; }
W_EDITBOX::W_EDITBOX(W_EDBINIT const *init) : WIDGET(init, WIDG_EDITBOX) , state(WEDBS_FIXED) , FontID(init->FontID) , blinkOffset(wzGetTicks()) , maxStringSize(EB_MAX_STRINGSIZE) , insPos(0) , printStart(0) , printChars(0) , printWidth(0) , pBoxDisplay(init->pBoxDisplay) , HilightAudioID(WidgGetHilightAudioID()) , ClickedAudioID(WidgGetClickedAudioID()) , ErrorAudioID(WidgGetErrorAudioID()) , AudioCallback(WidgGetAudioCallback()) , boxColourFirst(WZCOL_FORM_DARK) , boxColourSecond(WZCOL_FORM_LIGHT) , boxColourBackground(WZCOL_FORM_BACKGROUND) { char const *text = init->pText; if (!text) { text = ""; } aText = QString::fromUtf8(text); initialise(); ASSERT((init->style & ~(WEDB_PLAIN | WIDG_HIDDEN)) == 0, "Unknown edit box style"); }
void recvPlayerGameTime(NETQUEUE queue) { uint32_t latencyTicks = 0; uint32_t checkTime = 0; uint32_t checkCrc = 0; NETbeginDecode(queue, GAME_GAME_TIME); NETuint32_t(&latencyTicks); NETuint32_t(&checkTime); NETuint32_tLarge(&checkCrc); NETuint16_t(&wantedLatencies[queue.index]); NETend(); gameQueueTime[queue.index] = checkTime + latencyTicks * GAME_TICKS_PER_UPDATE; // gameTime when future messages shall be processed. gameQueueCheckTime[queue.index] = checkTime; gameQueueCheckCrc[queue.index] = checkCrc; if (!checkDebugSync(checkTime, checkCrc)) { crcError = true; if (NetPlay.players[queue.index].allocated) { NETsetPlayerConnectionStatus(CONNECTIONSTATUS_DESYNC, queue.index); } } if (updateReadyTime == 0 && checkPlayerGameTime(NET_ALL_PLAYERS)) { updateReadyTime = wzGetTicks(); // This is the time we were able to tick. } }
/* Call this to reset the game timer */ void gameTimeReset(UDWORD time) { // reset the game timers setGameTime(time); gameTimeResetMod(); realTime = wzGetTicks(); deltaRealTime = 0; }
/* Call this to stop the game timer */ void gameTimeStop(void) { if (stopCount == 0) { pauseStart = wzGetTicks(); debug( LOG_NEVER, "Clock paused at %d\n", pauseStart); } stopCount += 1; }
//////////////////////////////// // at the end of every game. bool multiGameShutdown(void) { PLAYERSTATS st; uint32_t time; debug(LOG_NET, "%s is shutting down.", getPlayerName(selectedPlayer)); sendLeavingMsg(); // say goodbye updateMultiStatsGames(); // update games played. st = getMultiStats(selectedPlayer); // save stats saveMultiStats(getPlayerName(selectedPlayer), getPlayerName(selectedPlayer), &st); // if we terminate the socket too quickly, then, it is possible not to get the leave message time = wzGetTicks(); while (wzGetTicks() - time < 1000) { wzYieldCurrentThread(); // TODO Make a wzDelay() function? } // close game NETclose(); NETremRedirects(); if (ingame.numStructureLimits) { ingame.numStructureLimits = 0; free(ingame.pStructureLimits); ingame.pStructureLimits = NULL; } ingame.flags = 0; ingame.localJoiningInProgress = false; // Clean up ingame.localOptionsReceived = false; ingame.bHostSetup = false; // Dont attempt a host ingame.TimeEveryoneIsInGame = 0; ingame.startTime = 0; NetPlay.isHost = false; bMultiPlayer = false; // Back to single player mode bMultiMessages = false; selectedPlayer = 0; // Back to use player 0 (single player friendly) return true; }
/* * Setup a tool tip. * The tip module will then wait until the correct points to * display and then remove the tool tip. * i.e. The tip will not be displayed immediately. * Calling this while another tip is being displayed will restart * the tip system. * psSource is the widget that started the tip. * x,y,width,height - specify the position of the button to place the * tip by. */ void tipStart(WIDGET *psSource, QString pNewTip, iV_fonts NewFontID, int x, int y, int width, int height) { ASSERT(psSource != NULL, "Invalid widget pointer"); tipState = TIP_WAIT; startTime = wzGetTicks(); mx = mouseX(); my = mouseY(); wx = x; wy = y; ww = width; wh = height; pTip = pNewTip.split('\n'); psWidget = psSource; FontID = NewFontID; }
void realTimeUpdate(void) { uint32_t currTime = wzGetTicks(); // now update realTime which does not pause // Store the real time deltaRealTime = currTime - realTime; realTime += deltaRealTime; deltaRealTime = MIN(deltaRealTime, GTIME_MAXFRAME); // Don't scroll across the map suddenly, if computer freezes for a moment. // Pre-calculate fraction used in timeAdjustedIncrement realTimeFraction = (float)deltaRealTime / (float)GAME_TICKS_PER_SEC; }
/* Call this to restart the game timer after a call to gameTimeStop */ void gameTimeStart(void) { if (stopCount == 1) { // shift the base time to now timeOffset = gameTime; baseTime = wzGetTicks(); } if (stopCount > 0) { stopCount --; } }
extern void setGameTime(uint32_t newGameTime) { // Setting game time. gameTime = newGameTime; setPlayerGameTime(NET_ALL_PLAYERS, newGameTime); deltaGameTime = 0; // Setting graphics time to game time. graphicsTime = gameTime; deltaGraphicsTime = gameTime; graphicsTimeFraction = 0.f; timeOffset = graphicsTime; baseTime = wzGetTicks(); // Not setting real time. }
W_EDITBOX::W_EDITBOX(WIDGET *parent) : WIDGET(parent) , state(WEDBS_FIXED) , FontID(font_regular) , blinkOffset(wzGetTicks()) , maxStringSize(EB_MAX_STRINGSIZE) , insPos(0) , printStart(0) , printChars(0) , printWidth(0) , pBoxDisplay(nullptr) , HilightAudioID(WidgGetHilightAudioID()) , ClickedAudioID(WidgGetClickedAudioID()) , ErrorAudioID(WidgGetErrorAudioID()) , AudioCallback(WidgGetAudioCallback()) , boxColourFirst(WZCOL_FORM_DARK) , boxColourSecond(WZCOL_FORM_LIGHT) , boxColourBackground(WZCOL_FORM_BACKGROUND) {}
//loadbar update void loadingScreenCallback(void) { const PIELIGHT loadingbar_background = WZCOL_LOADING_BAR_BACKGROUND; const uint32_t currTick = wzGetTicks(); unsigned int i; if (currTick - lastTick < 50) { return; } lastTick = currTick; /* Draw the black rectangle at the bottom, with a two pixel border */ pie_UniTransBoxFill(barLeftX - 2, barLeftY - 2, barRightX + 2, barRightY + 2, loadingbar_background); for (i = 1; i < starsNum; ++i) { stars[i].xPos = stars[i].xPos + stars[i].speed; if (stars[i].xPos >= barRightX) { stars[i] = newStar(); stars[i].xPos = 1; } { const int topX = barLeftX + stars[i].xPos; const int topY = barLeftY + i * (boxHeight - starHeight) / starsNum; const int botX = MIN(topX + stars[i].speed, barRightX); const int botY = topY + starHeight; pie_UniTransBoxFill(topX, topY, botX, botY, stars[i].colour); } } pie_ScreenFlip(CLEAR_OFF_AND_NO_BUFFER_DOWNLOAD);//loading callback // dont clear. audio_Update(); }
W_EDITBOX::W_EDITBOX(W_EDBINIT const *init) : WIDGET(init, WIDG_EDITBOX) , FontID(init->FontID) , blinkOffset(wzGetTicks()) , pBoxDisplay(init->pBoxDisplay) , pFontDisplay(init->pFontDisplay) , HilightAudioID(WidgGetHilightAudioID()) , ClickedAudioID(WidgGetClickedAudioID()) , AudioCallback(WidgGetAudioCallback()) { char const *text = init->pText; if (!text) { text = ""; } aText = QString::fromUtf8(text); if (display == NULL) { display = editBoxDisplay; } initialise(); }
void W_EDITBOX::display(int xOffset, int yOffset) { int x0 = x() + xOffset; int y0 = y() + yOffset; int x1 = x0 + width(); int y1 = y0 + height(); if (pBoxDisplay != nullptr) { pBoxDisplay(this, xOffset, yOffset); } else { iV_ShadowBox(x0, y0, x1, y1, 0, boxColourFirst, boxColourSecond, boxColourBackground); } int fx = x0 + WEDB_XGAP;// + (psEdBox->width - fw) / 2; iV_SetTextColour(WZCOL_FORM_TEXT); int fy = y0 + (height() - iV_GetTextLineSize(FontID)) / 2 - iV_GetTextAboveBase(FontID); /* If there is more text than will fit into the box, display the bit with the cursor in it */ QString tmp = aText; tmp.remove(0, printStart); // Erase anything there isn't room to display. tmp.remove(printChars, tmp.length()); iV_DrawText(tmp.toUtf8().constData(), fx, fy, FontID); // Display the cursor if editing #if CURSOR_BLINK bool blink = !(((wzGetTicks() - blinkOffset) / WEDB_BLINKRATE) % 2); if ((state & WEDBS_MASK) == WEDBS_INSERT && blink) #else if ((state & WEDBS_MASK) == WEDBS_INSERT) #endif { // insert mode QString tmp = aText; tmp.remove(insPos, tmp.length()); // Erase from the cursor on, to find where the cursor should be. tmp.remove(0, printStart); int cx = x0 + WEDB_XGAP + iV_GetTextWidth(tmp.toUtf8().constData(), FontID); cx += iV_GetTextWidth("-", FontID); int cy = fy; iV_Line(cx, cy + iV_GetTextAboveBase(FontID), cx, cy - iV_GetTextBelowBase(FontID), WZCOL_FORM_CURSOR); } #if CURSOR_BLINK else if ((state & WEDBS_MASK) == WEDBS_OVER && blink) #else else if ((state & WEDBS_MASK) == WEDBS_OVER) #endif { // overwrite mode QString tmp = aText; tmp.remove(insPos, tmp.length()); // Erase from the cursor on, to find where the cursor should be. tmp.remove(0, printStart); int cx = x0 + WEDB_XGAP + iV_GetTextWidth(tmp.toUtf8().constData(), FontID); int cy = fy; iV_Line(cx, cy, cx + WEDB_CURSORSIZE, cy, WZCOL_FORM_CURSOR); } if (pBoxDisplay == nullptr) { if ((state & WEDBS_HILITE) != 0) { /* Display the button hilite */ iV_Box(x0 - 2, y0 - 2, x1 + 2, y1 + 2, WZCOL_FORM_HILITE); } } }
bool runMultiRequester(UDWORD id, UDWORD *mode, char *chosen, UDWORD *chosenValue, bool *isHoverPreview) { static unsigned hoverId = 0; static unsigned hoverStartTime = 0; if( (id == M_REQUEST_CLOSE) || CancelPressed() ) // user hit close box || hit the cancel key { closeMultiRequester(); *mode = 0; return true; } bool hoverPreview = false; if (id == 0 && context == MULTIOP_MAP) { id = widgGetMouseOver(psRScreen); if (id != hoverId) { hoverId = id; hoverStartTime = wzGetTicks() + HOVER_PREVIEW_TIME; } if (id == hoverPreviewId || hoverStartTime > wzGetTicks()) { id = 0; // Don't re-render preview nor render preview before HOVER_PREVIEW_TIME. } hoverPreview = true; } if (id >= M_REQUEST_BUT && id <= M_REQUEST_BUTM) // chose a file. { strcpy(chosen,((W_BUTTON *)widgGetFromID(psRScreen,id))->pText ); *chosenValue = ((W_BUTTON *)widgGetFromID(psRScreen,id))->UserData ; *mode = context; *isHoverPreview = hoverPreview; hoverPreviewId = id; if (!hoverPreview) { closeMultiRequester(); } return true; } if (hoverPreview) { id = 0; } switch (id) { case M_REQUEST_C1: closeMultiRequester(); addMultiRequest(MultiCustomMapsPath, ".wrf", MULTIOP_MAP, 1, current_numplayers); break; case M_REQUEST_C2: closeMultiRequester(); addMultiRequest(MultiCustomMapsPath, ".wrf", MULTIOP_MAP, 2, current_numplayers); break; case M_REQUEST_C3: closeMultiRequester(); addMultiRequest(MultiCustomMapsPath, ".wrf", MULTIOP_MAP, 3, current_numplayers); break; case M_REQUEST_AP: closeMultiRequester(); addMultiRequest(MultiCustomMapsPath, ".wrf", MULTIOP_MAP, current_tech, 0); break; default: for (unsigned numPlayers = 2; numPlayers <= MAX_PLAYERS_IN_GUI; ++numPlayers) { if (id == M_REQUEST_NP[numPlayers - 2]) { closeMultiRequester(); addMultiRequest(MultiCustomMapsPath, ".wrf", MULTIOP_MAP, current_tech, numPlayers); break; } } break; } return false; }
void W_EDITBOX::run(W_CONTEXT *psContext) { /* Note the edit state */ unsigned editState = state & WEDBS_MASK; /* Only have anything to do if the widget is being edited */ if ((editState & WEDBS_MASK) == WEDBS_FIXED) { return; } /* If there is a mouse click outside of the edit box - stop editing */ int mx = psContext->mx; int my = psContext->my; if (mousePressed(MOUSE_LMB) && (mx < x || mx > x + width || my < y || my > y + height)) { screenClearFocus(psContext->psScreen); return; } /* note the widget state */ iV_SetFont(FontID); /* Loop through the characters in the input buffer */ bool done = false; utf_32_char unicode; for (unsigned key = inputGetKey(&unicode); key != 0 && !done; key = inputGetKey(&unicode)) { // Don't blink while typing. blinkOffset = wzGetTicks(); int len = 0; /* Deal with all the control keys, assume anything else is a printable character */ switch (key) { case INPBUF_LEFT : /* Move the cursor left */ insPos = MAX(insPos - 1, 0); /* If the cursor has gone off the left of the edit box, * need to update the printable text. */ if (insPos < printStart) { printStart = MAX(printStart - WEDB_CHARJUMP, 0); fitStringStart(); } debug(LOG_INPUT, "EditBox cursor left"); break; case INPBUF_RIGHT : /* Move the cursor right */ len = aText.length(); insPos = MIN(insPos + 1, len); /* If the cursor has gone off the right of the edit box, * need to update the printable text. */ if (insPos > printStart + printChars) { printStart = MIN(printStart + WEDB_CHARJUMP, len - 1); fitStringStart(); } debug(LOG_INPUT, "EditBox cursor right"); break; case INPBUF_UP : debug(LOG_INPUT, "EditBox cursor up"); break; case INPBUF_DOWN : debug(LOG_INPUT, "EditBox cursor down"); break; case INPBUF_HOME : /* Move the cursor to the start of the buffer */ insPos = 0; printStart = 0; fitStringStart(); debug(LOG_INPUT, "EditBox cursor home"); break; case INPBUF_END : /* Move the cursor to the end of the buffer */ insPos = aText.length(); if (insPos != printStart + printChars) { fitStringEnd(); } debug(LOG_INPUT, "EditBox cursor end"); break; case INPBUF_INS : if (editState == WEDBS_INSERT) { editState = WEDBS_OVER; } else { editState = WEDBS_INSERT; } debug(LOG_INPUT, "EditBox cursor insert"); break; case INPBUF_DEL : delCharRight(); /* Update the printable text */ fitStringStart(); debug(LOG_INPUT, "EditBox cursor delete"); break; case INPBUF_PGUP : debug(LOG_INPUT, "EditBox cursor page up"); break; case INPBUF_PGDN : debug(LOG_INPUT, "EditBox cursor page down"); break; case INPBUF_BKSPACE : /* Delete the character to the left of the cursor */ delCharLeft(); /* Update the printable text */ if (insPos <= printStart) { printStart = MAX(printStart - WEDB_CHARJUMP, 0); } fitStringStart(); debug(LOG_INPUT, "EditBox cursor backspace"); break; case INPBUF_TAB : debug(LOG_INPUT, "EditBox cursor tab"); break; case INPBUF_CR : case KEY_KPENTER: // either normal return key || keypad enter /* Finish editing */ focusLost(psContext->psScreen); screenClearFocus(psContext->psScreen); debug(LOG_INPUT, "EditBox cursor return"); return; break; case INPBUF_ESC : debug(LOG_INPUT, "EditBox cursor escape"); break; default: if (keyDown(KEY_LCTRL) || keyDown(KEY_RCTRL)) { switch (key) { case KEY_V: aText = wzGetSelection(); insPos = aText.length(); /* Update the printable text */ fitStringEnd(); debug(LOG_INPUT, "EditBox paste"); break; default: break; } break; } /* Dealt with everything else this must be a printable character */ if (editState == WEDBS_INSERT) { insertChar(unicode); } else { overwriteChar(unicode); } len = aText.length(); /* Update the printable chars */ if (insPos == len) { fitStringEnd(); } else { fitStringStart(); if (insPos > printStart + printChars) { printStart = MIN(printStart + WEDB_CHARJUMP, len - 1); if (printStart >= len) { fitStringStart(); } } } break; } } /* Store the current widget state */ state = (state & ~WEDBS_MASK) | editState; }
/* Call this each loop to update the game timer */ void gameTimeUpdate() { uint32_t currTime = wzGetTicks(); if (currTime < baseTime) { // Warzone 2100, the first relativistic computer game! // Exhibit A: Time travel // force a rebase debug(LOG_WARNING, "Time travel is occurring! Clock went back in time a bit from %d to %d!\n", baseTime, currTime); baseTime = currTime; timeOffset = graphicsTime; } // Do not update the game time if gameTimeStop has been called if (stopCount == 0) { bool mayUpdate = true; // Calculate the new game time uint32_t scaledCurrTime = (currTime - baseTime)*modifier + timeOffset; if (scaledCurrTime < graphicsTime) // Make sure the clock doesn't step back at all. { debug(LOG_WARNING, "Rescaled clock went back in time a bit from %d to %d!\n", graphicsTime, scaledCurrTime); scaledCurrTime = graphicsTime; baseTime = currTime; timeOffset = graphicsTime; } if (updateWantedTime == 0 && scaledCurrTime >= gameTime) { updateWantedTime = currTime; // This is the time that we wanted to tick. } if (scaledCurrTime >= gameTime && !checkPlayerGameTime(NET_ALL_PLAYERS)) { unsigned player; // Pause time at current game time, since we are waiting GAME_GAME_TIME from other players. scaledCurrTime = gameTime; baseTime = currTime; timeOffset = gameTime; debug(LOG_SYNC, "Waiting for other players. gameTime = %u, player times are {%s}", gameTime, listToString("%u", ", ", gameQueueTime, gameQueueTime + game.maxPlayers).c_str()); mayUpdate = false; for (player = 0; player < game.maxPlayers; ++player) { if (!checkPlayerGameTime(player)) { NETsetPlayerConnectionStatus(CONNECTIONSTATUS_WAITING_FOR_PLAYER, player); break; // GAME_GAME_TIME is processed serially, so don't know if waiting for more players. } } } // Calculate the time for this frame deltaGraphicsTime = scaledCurrTime - graphicsTime; // Adjust deltas. if (scaledCurrTime >= gameTime && mayUpdate) { if (scaledCurrTime > gameTime + GAME_TICKS_PER_SEC*MAXIMUM_SPF) { // Game isn't updating fast enough... uint32_t slideBack = deltaGraphicsTime - GAME_TICKS_PER_SEC*MAXIMUM_SPF; baseTime += slideBack / modifier; // adjust the addition to base time deltaGraphicsTime -= slideBack; } deltaGameTime = GAME_TICKS_PER_UPDATE; updateLatency(); if (crcError) { debug(LOG_ERROR, "Synch error, gameTimes were: {%s}", listToString("%10u", ", ", gameQueueCheckTime, gameQueueCheckTime + game.maxPlayers).c_str()); debug(LOG_ERROR, "Synch error, CRCs were: {%s}", listToString("0x%08X", ", ", gameQueueCheckCrc, gameQueueCheckCrc + game.maxPlayers).c_str()); crcError = false; } } else { deltaGameTime = 0; } if (deltaGameTime != 0) { deltaGraphicsTime = 0; // Don't update graphics until game state is updated. } // Store the game and graphics times gameTime += deltaGameTime; graphicsTime += deltaGraphicsTime; } else { // The game is paused, so the change in time is zero. deltaGameTime = 0; deltaGraphicsTime = 0; } // Pre-calculate fraction used in timeAdjustedIncrement graphicsTimeFraction = (float)deltaGraphicsTime / (float)GAME_TICKS_PER_SEC; ASSERT(graphicsTime <= gameTime, "Trying to see the future."); }
/* The edit box display function */ void editBoxDisplay(WIDGET *psWidget, UDWORD xOffset, UDWORD yOffset, PIELIGHT *pColours) { W_EDITBOX *psEdBox; SDWORD x0,y0,x1,y1, fx,fy, cx,cy; enum iV_fonts CurrFontID; #if CURSOR_BLINK bool blink; #endif psEdBox = (W_EDITBOX *)psWidget; CurrFontID = psEdBox->FontID; x0=psEdBox->x + xOffset; y0=psEdBox->y + yOffset; x1=x0 + psEdBox->width; y1=y0 + psEdBox->height; if(psEdBox->pBoxDisplay) { psEdBox->pBoxDisplay((WIDGET *)psEdBox, xOffset, yOffset, pColours); } else { pie_BoxFill(x0, y0, x1, y1, pColours[WCOL_BKGRND]); iV_Line(x0,y0, x1,y0, pColours[WCOL_DARK]); iV_Line(x0,y0, x0,y1, pColours[WCOL_DARK]); iV_Line(x0,y1, x1,y1, pColours[WCOL_LIGHT]); iV_Line(x1,y1, x1,y0, pColours[WCOL_LIGHT]); } fx = x0 + WEDB_XGAP;// + (psEdBox->width - fw) / 2; iV_SetFont(CurrFontID); iV_SetTextColour(pColours[WCOL_TEXT]); fy = y0 + (psEdBox->height - iV_GetTextLineSize())/2 - iV_GetTextAboveBase(); /* If there is more text than will fit into the box, display the bit with the cursor in it */ QString tmp = psEdBox->aText; tmp.remove(0, psEdBox->printStart); // Erase anything there isn't room to display. tmp.remove(psEdBox->printChars, tmp.length()); // if(psEdBox->pFontDisplay) { // psEdBox->pFontDisplay(fx,fy, pPrint); // } else { iV_DrawText(tmp.toUtf8().constData(), fx, fy); // } // Display the cursor if editing #if CURSOR_BLINK blink = !(((wzGetTicks() - psEdBox->blinkOffset)/WEDB_BLINKRATE) % 2); if ((psEdBox->state & WEDBS_MASK) == WEDBS_INSERT && blink) #else if ((psEdBox->state & WEDBS_MASK) == WEDBS_INSERT) #endif { // insert mode QString tmp = psEdBox->aText; tmp.remove(psEdBox->insPos, tmp.length()); // Erase from the cursor on, to find where the cursor should be. tmp.remove(0, psEdBox->printStart); cx = x0 + WEDB_XGAP + iV_GetTextWidth(tmp.toUtf8().constData()); cx += iV_GetTextWidth("-"); cy = fy; iV_Line(cx, cy + iV_GetTextAboveBase(), cx, cy - iV_GetTextBelowBase(), pColours[WCOL_CURSOR]); } #if CURSOR_BLINK else if ((psEdBox->state & WEDBS_MASK) == WEDBS_OVER && blink) #else else if ((psEdBox->state & WEDBS_MASK) == WEDBS_OVER) #endif { // overwrite mode QString tmp = psEdBox->aText; tmp.remove(psEdBox->insPos, tmp.length()); // Erase from the cursor on, to find where the cursor should be. tmp.remove(0, psEdBox->printStart); cx = x0 + WEDB_XGAP + iV_GetTextWidth(tmp.toUtf8().constData()); cy = fy; iV_Line(cx, cy, cx + WEDB_CURSORSIZE, cy, pColours[WCOL_CURSOR]); } if(psEdBox->pBoxDisplay == NULL) { if (psEdBox->state & WEDBS_HILITE) { /* Display the button hilite */ iV_Line(x0-2,y0-2, x1+2,y0-2, pColours[WCOL_HILITE]); iV_Line(x0-2,y0-2, x0-2,y1+2, pColours[WCOL_HILITE]); iV_Line(x0-2,y1+2, x1+2,y1+2, pColours[WCOL_HILITE]); iV_Line(x1+2,y1+2, x1+2,y0-2, pColours[WCOL_HILITE]); } } }
/* Update and possibly display the tip */ void tipDisplay() { SDWORD newMX, newMY; SDWORD currTime; SDWORD fw, topGap; switch (tipState) { case TIP_WAIT: /* See if the tip has to be shown */ newMX = mouseX(); newMY = mouseY(); currTime = wzGetTicks(); if (newMX == mx && newMY == my && (currTime - startTime > TIP_PAUSE)) { /* Activate the tip */ tipState = TIP_ACTIVE; /* Calculate the size of the tip box */ topGap = TIP_VGAP; iV_SetFont(FontID); lineHeight = iV_GetTextLineSize(); fw = 0; for (int n = 0; n < pTip.size(); ++n) { fw = std::max<int>(fw, iV_GetTextWidth(pTip[n].toUtf8().constData())); } tw = fw + TIP_HGAP * 2; th = topGap * 2 + lineHeight * pTip.size() + iV_GetTextBelowBase(); /* Position the tip box */ tx = clip(wx + ww / 2, 0, screenWidth - tw - 1); ty = std::max(wy + wh + TIP_VGAP, 0); if (ty + th >= (int)screenHeight) { /* Position the tip above the button */ ty = wy - th - TIP_VGAP; } /* Position the text */ fx = tx + TIP_HGAP; fy = ty + (th - lineHeight * pTip.size()) / 2 - iV_GetTextAboveBase(); /* Note the time */ startTime = wzGetTicks(); } else if (newMX != mx || newMY != my || mousePressed(MOUSE_LMB)) { mx = newMX; my = newMY; startTime = currTime; } break; case TIP_ACTIVE: /* Draw the tool tip */ pie_BoxFill(tx, ty, tx + tw, ty + th, WZCOL_FORM_TIP_BACKGROUND); iV_Line(tx + 1, ty + th - 2, tx + 1, ty + 1, WZCOL_FORM_DARK); iV_Line(tx + 2, ty + 1, tx + tw - 2, ty + 1, WZCOL_FORM_DARK); iV_Line(tx, ty + th, tx + tw, ty + th, WZCOL_FORM_DARK); iV_Line(tx + tw, ty + th - 1, tx + tw, ty, WZCOL_FORM_DARK); iV_Box(tx, ty, tx + tw - 1, ty + th - 1, WZCOL_FORM_LIGHT); iV_SetFont(FontID); iV_SetTextColour(TipColour); for (int n = 0; n < pTip.size(); ++n) { iV_DrawText(pTip[n].toUtf8().constData(), fx, fy + lineHeight * n); } break; default: break; } }