// ----------------------------------------------------------------------------------- void dispAdditionalInfo( void ) { /* We now need to display the mission time, game time, average unit experience level an number of artefacts found */ /* Firstly, top of the screen, number of artefacts found */ sprintf( text, _("ARTIFACTS RECOVERED: %d"), missionData.artefactsFound ); iV_DrawText( text, (pie_GetVideoBufferWidth() - iV_GetTextWidth(text))/2, 300 + D_H ); /* Get the mission result time in a string - and write it out */ getAsciiTime( (char*)&text2, gameTime - missionData.missionStarted ); sprintf( text, _("Mission Time - %s"), text2 ); iV_DrawText( text, (pie_GetVideoBufferWidth() - iV_GetTextWidth(text))/2, 320 + D_H); /* Write out total game time so far */ getAsciiTime( (char*)&text2, gameTime ); sprintf( text, _("Total Game Time - %s"), text2 ); iV_DrawText( text, (pie_GetVideoBufferWidth() - iV_GetTextWidth(text))/2, 340 + D_H ); if (Cheated) { // A quick way to flash the text ((gameTime2 / 250) % 2) ? iV_SetTextColour(WZCOL_RED) : iV_SetTextColour(WZCOL_YELLOW); sprintf( text, _("You cheated!")); iV_DrawText( text, (pie_GetVideoBufferWidth() - iV_GetTextWidth(text))/2, 360 + D_H ); iV_SetTextColour(WZCOL_TEXT_BRIGHT); } }
bool pie_Initialise(void) { pie_TexInit(); /* Find texture compression extension */ if (GLEW_ARB_texture_compression && wz_texture_compression != GL_RGBA) { debug(LOG_TEXTURE, "Texture compression: Yes"); wz_texture_compression = GL_COMPRESSED_RGBA_ARB; } else { debug(LOG_TEXTURE, "Texture compression: No"); wz_texture_compression = GL_RGBA; } pie_MatInit(); _TEX_INDEX = 0; rendSurface.width = pie_GetVideoBufferWidth(); rendSurface.height = pie_GetVideoBufferHeight(); rendSurface.xcentre = pie_GetVideoBufferWidth()/2; rendSurface.ycentre = pie_GetVideoBufferHeight()/2; rendSurface.clip.left = 0; rendSurface.clip.top = 0; rendSurface.clip.right = pie_GetVideoBufferWidth(); rendSurface.clip.bottom = pie_GetVideoBufferHeight(); pie_SetDefaultStates(); debug(LOG_3D, "xcentre %d; ycentre %d", rendSurface.xcentre, rendSurface.ycentre); return true; }
UDWORD pie_GetResScalingFactor(void) { if (pie_GetVideoBufferWidth() * 4 > pie_GetVideoBufferHeight() * 5) { return pie_GetVideoBufferHeight()*5/4/6; } else { return pie_GetVideoBufferWidth()/6; } }
void pie_UpdateSurfaceGeometry() { rendSurface.width = pie_GetVideoBufferWidth(); rendSurface.height = pie_GetVideoBufferHeight(); rendSurface.xcentre = pie_GetVideoBufferWidth() / 2; rendSurface.ycentre = pie_GetVideoBufferHeight() / 2; rendSurface.clip.left = 0; rendSurface.clip.top = 0; rendSurface.clip.right = pie_GetVideoBufferWidth(); rendSurface.clip.bottom = pie_GetVideoBufferHeight(); }
//----------------------------------------------------------------------------------- static void getTrackingConcerns(SDWORD *x, SDWORD *y, SDWORD *z, UDWORD groupNumber, bool bOnScreen) { SDWORD xTotals = 0, yTotals = 0, zTotals = 0; DROID *psDroid; UDWORD count; for (count = 0, psDroid = apsDroidLists[selectedPlayer]; psDroid; psDroid = psDroid->psNext) { if (groupNumber == GROUP_SELECTED ? psDroid->selected : psDroid->group == groupNumber) { if (!bOnScreen || droidOnScreen(psDroid, pie_GetVideoBufferWidth() / 4)) { count++; xTotals += psDroid->pos.x; yTotals += psDroid->pos.z; // note the flip zTotals += psDroid->pos.y; } } } if (count) // necessary!!!!!!! { *x = xTotals / count; *y = yTotals / count; *z = zTotals / count; } }
/*! * 3D vector perspective projection * Projects 3D vector into 2D screen space * \param v3d 3D vector to project * \param[out] v2d resulting 2D vector * \return projected z component of v2d */ int32_t pie_RotateProject(const Vector3i *v3d, const glm::mat4& matrix, Vector2i *v2d) { float hackScaleFactor = 1.0f / (3 * 330); // HACK: This seems to work by experimentation, not sure why. /* * v = curMatrix . v3d */ glm::vec4 v(pie_PerspectiveGet() * matrix * glm::vec4(*v3d, 1.f)); const float xx = v.x / v.w; const float yy = v.y / v.w; if (v.w < 256 * hackScaleFactor) { v2d->x = LONG_WAY; //just along way off screen v2d->y = LONG_WAY; } else { v2d->x = (.5 + .5 * xx) * pie_GetVideoBufferWidth(); v2d->y = (.5 - .5 * yy) * pie_GetVideoBufferHeight(); } return v.w; }
static void pie_DrawShadows(void) { const float width = pie_GetVideoBufferWidth(); const float height = pie_GetVideoBufferHeight(); pie_SetTexturePage(TEXPAGE_NONE); glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); glDepthFunc(GL_LESS); glDepthMask(GL_FALSE); glEnable(GL_STENCIL_TEST); ShadowStencilFunc(); glEnable(GL_CULL_FACE); glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP); glStencilMask(~0); glStencilFunc(GL_LESS, 0, ~0); glDisable(GL_DEPTH_TEST); PIELIGHT grey; grey.byte = { 0, 0, 0, 128 }; pie_BoxFill(0, 0, width, height, grey, REND_ALPHA); pie_SetRendMode(REND_OPAQUE); glDisable(GL_STENCIL_TEST); glEnable(GL_DEPTH_TEST); glDepthMask(GL_TRUE); scshapes.resize(0); }
static void setupLoadingScreen(void) { unsigned int i; int w = pie_GetVideoBufferWidth(); int h = pie_GetVideoBufferHeight(); int offset; boxHeight = h / 40.0; offset = boxHeight; boxWidth = w - 2.0 * offset; barRightX = w - offset; barRightY = h - offset; barLeftX = barRightX - boxWidth; barLeftY = barRightY - boxHeight; starsNum = boxWidth / boxHeight; starHeight = 2.0 * h / 640.0; if (!stars) { stars = (STAR *)malloc(sizeof(STAR) * starsNum); } for (i = 0; i < starsNum; ++i) { stars[i] = newStar(); } }
void SetMousePos(UDWORD nowt,UDWORD x,UDWORD y) { POINT point; FRACT divX,divY; UDWORD scrX,scrY; UDWORD mXPos,mYPos; UNUSEDPARAMETER(nowt); if(pie_GetRenderEngine()==ENGINE_GLIDE) { scrX = GetSystemMetrics(SM_CXFULLSCREEN); scrY = GetSystemMetrics(SM_CYFULLSCREEN); divX = MAKEFRACT(x) / pie_GetVideoBufferWidth(); divY = MAKEFRACT(y) / pie_GetVideoBufferHeight(); mXPos = MAKEINT(divX*scrX); mYPos = MAKEINT(divY*scrY); SetCursorPos(mXPos,mYPos); } else { point.x = x; point.y = y; ClientToScreen(frameGetWinHandle(),&point); SetCursorPos(point.x,point.y); } }
static STAR newStar(void) { STAR s; s.xPos = rand() % barRightX; s.speed = (rand() % 30 + 6) * pie_GetVideoBufferWidth() / 640.0; s.colour = pal_SetBrightness(150 + rand() % 100); return s; }
static void radarSize(int ZoomLevel) { float zoom = (float)ZoomLevel * RadarZoomMultiplier / 16.0; radarWidth = radarTexWidth * zoom; radarHeight = radarTexHeight * zoom; if (rotateRadar) { radarCenterX = pie_GetVideoBufferWidth() - BASE_GAP * 4 - MAX(radarHeight, radarWidth) / 2; radarCenterY = pie_GetVideoBufferHeight() - BASE_GAP * 4 - MAX(radarWidth, radarHeight) / 2; } else { radarCenterX = pie_GetVideoBufferWidth() - BASE_GAP * 4 - radarWidth / 2; radarCenterY = pie_GetVideoBufferHeight() - BASE_GAP * 4 - radarHeight / 2; } debug(LOG_WZ, "radar=(%u,%u) tex=(%u,%u) size=(%u,%u)", radarCenterX, radarCenterY, radarTexWidth, radarTexHeight, radarWidth, radarHeight); }
bool wzMainScreenSetup(int antialiasing, bool fullscreen, bool vsync, bool highDPI) { debug(LOG_MAIN, "Qt initialization"); //QGL::setPreferredPaintEngine(QPaintEngine::OpenGL); // Workaround for incorrect text rendering on many platforms, doesn't exist in Qt5… // Register custom WZ app event type wzAppQEventType = QEvent::registerEventType(); // Setting up OpenGL QGLFormat format; format.setDoubleBuffer(true); //format.setAlpha(true); int w = pie_GetVideoBufferWidth(); int h = pie_GetVideoBufferHeight(); if (antialiasing) { format.setSampleBuffers(true); format.setSamples(antialiasing); } mainWindowPtr = new WzMainWindow(QSize(w, h), format, wzAppQEventType.load()); WzMainWindow &mainwindow = *(mainWindowPtr.load()); mainwindow.setMinimumResolution(QSize(800, 600)); if (!mainwindow.context()->isValid()) { QMessageBox::critical(nullptr, "Oops!", "Warzone2100 failed to create an OpenGL context. This probably means that your graphics drivers are out of date. Try updating them!"); return false; } screenWidth = w; screenHeight = h; if (fullscreen) { mainwindow.resize(w, h); mainwindow.showFullScreen(); if (w > mainwindow.width()) { w = mainwindow.width(); } if (h > mainwindow.height()) { h = mainwindow.height(); } pie_SetVideoBufferWidth(w); pie_SetVideoBufferHeight(h); } else { mainwindow.show(); mainwindow.setMinimumSize(w, h); mainwindow.setMaximumSize(w, h); } mainwindow.setSwapInterval(vsync); mainwindow.setReadyToPaint(); return true; }
/** Sets the system up */ void initConsoleMessages(void) { iV_SetFont(font_regular); linePitch = iV_GetTextLineSize(); // NOTE: if font changes, this must also be changed! bConsoleDropped = false; setConsoleMessageDuration(DEFAULT_MESSAGE_DURATION); // Setup how long messages are displayed for setConsoleBackdropStatus(true); // No box under the text enableConsoleDisplay(true); // Turn on the console display // Set up the main console size and position x,y,width setConsoleSizePos(16, 32, pie_GetVideoBufferWidth() - 32); historyConsole.topX = HISTORYBOX_X; historyConsole.topY = HISTORYBOX_Y; historyConsole.width = pie_GetVideoBufferWidth() - 32; setConsoleLineInfo(MAX_CONSOLE_MESSAGES / 4 + 4); setConsolePermanence(false, true); // We're not initially having permanent messages permitNewConsoleMessages(true); // Allow new messages }
/** Sets the system up */ void initConsoleMessages( void ) { int TextLineSize = iV_GetTextLineSize(); messageIndex = 0; /* Console can extend to half screen height */ if (TextLineSize) { maxDrop = ((pie_GetVideoBufferHeight() / TextLineSize)/2); } else { debug(LOG_FATAL, "Something is wrong with the fonts? Aborting."); abort(); } if(maxDrop>32) maxDrop = 32; consoleDrop = maxDrop;//MAX_DROP; dropState = DROP_CLOSED; /* No active messages to begin with */ numActiveMessages = 0; lastDropChange = 0; bConsoleDropped = false; /* Linked list is empty */ consoleMessages = NULL; /* Setup how long messages are displayed for... */ setConsoleMessageDuration(DEFAULT_MESSAGE_DURATION); /* No box under the text */ setConsoleBackdropStatus(true); /* Turn on the console display */ enableConsoleDisplay(true); /* Set left justification as default */ setDefaultConsoleJust(LEFT_JUSTIFY); /* Set up the console size and postion x,y,width */ setConsoleSizePos(16, 16, pie_GetVideoBufferWidth()-32); setConsoleLineInfo(MAX_CONSOLE_MESSAGES/4 + 4); /* We're not initially having permanent messages */ setConsolePermanence(false,true); /* Allow new messages */ permitNewConsoleMessages(true); }
static bool seq_AddTextFromFile(const char *pTextName, SEQ_TEXT_POSITIONING textJustification) { char aTextName[MAX_STR_LENGTH]; char *pTextBuffer, *pCurrentLine, *pText; UDWORD fileSize; SDWORD xOffset, yOffset; double startTime, endTime; const char *seps = "\n"; // NOTE: The original game never had a fullscreen mode for FMVs on >640x480 screens. // They would just use double sized videos, and move the text to that area. // We just use the full screen for text right now, instead of using offsets. // However, depending on reaction, we may use the old style again. D_H2 = 0; //( pie_GetVideoBufferHeight()- 480)/2; D_W2 = 0; //( pie_GetVideoBufferWidth() - 640)/2; ssprintf(aTextName, "sequenceaudio/%s", pTextName); if (loadFileToBufferNoError(aTextName, fileLoadBuffer, FILE_LOAD_BUFFER_SIZE, &fileSize) == false) //Did I mention this is lame? -Q { return false; } pTextBuffer = fileLoadBuffer; pCurrentLine = strtok(pTextBuffer, seps); while (pCurrentLine != NULL) { if (*pCurrentLine != '/') { if (sscanf(pCurrentLine, "%d %d %lf %lf", &xOffset, &yOffset, &startTime, &endTime) == 4) { // Since all the positioning was hardcoded to specific values, we now calculate the // ratio of our screen, compared to what the game expects and multiply that to x, y. // This makes the text always take up the full screen, instead of original style. xOffset = (double)pie_GetVideoBufferWidth() / 640. * (double)xOffset; yOffset = (double)pie_GetVideoBufferHeight() / 480. * (double)yOffset; //get the text pText = strrchr(pCurrentLine, '"'); ASSERT(pText != NULL, "error parsing text file"); if (pText != NULL) { *pText = (UBYTE)0; } pText = strchr(pCurrentLine, '"'); ASSERT(pText != NULL, "error parsing text file"); if (pText != NULL) { seq_AddTextForVideo(_(&pText[1]), xOffset, yOffset, startTime, endTime, textJustification); } } } //get next line pCurrentLine = strtok(NULL, seps); } return true; }
bool wzMain2() { debug(LOG_MAIN, "Qt initialization"); QGL::setPreferredPaintEngine(QPaintEngine::OpenGL); // Workaround for incorrect text rendering on nany platforms. // Setting up OpenGL QGLFormat format; format.setDoubleBuffer(true); format.setAlpha(true); int w = pie_GetVideoBufferWidth(); int h = pie_GetVideoBufferHeight(); if (war_getFSAA()) { format.setSampleBuffers(true); format.setSamples(war_getFSAA()); } mainWindowPtr = new WzMainWindow(QSize(w, h), format); WzMainWindow &mainwindow = *mainWindowPtr; mainwindow.setMinimumResolution(QSize(800, 600)); if (!mainwindow.context()->isValid()) { QMessageBox::critical(NULL, "Oops!", "Warzone2100 failed to create an OpenGL context. This probably means that your graphics drivers are out of date. Try updating them!"); return false; } screenWidth = w; screenHeight = h; if (war_getFullscreen()) { mainwindow.resize(w,h); mainwindow.showFullScreen(); if(w>mainwindow.width()) { w = mainwindow.width(); } if(h>mainwindow.height()) { h = mainwindow.height(); } pie_SetVideoBufferWidth(w); pie_SetVideoBufferHeight(h); } else { mainwindow.show(); mainwindow.setMinimumSize(w, h); mainwindow.setMaximumSize(w, h); } mainwindow.setSwapInterval(war_GetVsync()); war_SetVsync(mainwindow.swapInterval() > 0); mainwindow.setReadyToPaint(); return true; }
bool InitRadar() { // Ally/enemy/me colors colRadarAlly = WZCOL_YELLOW; colRadarEnemy = WZCOL_RED; colRadarMe = WZCOL_WHITE; if (mapWidth < 150) // too small! { RadarZoom = pie_GetVideoBufferWidth() <= 640 ? 14 : DEFAULT_RADARZOOM * 2; } return true; }
void addBackdrop(void) { W_FORMINIT sFormInit; // Backdrop sFormInit.formID = 0; sFormInit.id = FRONTEND_BACKDROP; sFormInit.style = WFORM_PLAIN; sFormInit.x = (SWORD)( (pie_GetVideoBufferWidth() - HIDDEN_FRONTEND_WIDTH)/2); sFormInit.y = (SWORD)( (pie_GetVideoBufferHeight() - HIDDEN_FRONTEND_HEIGHT)/2); sFormInit.width = HIDDEN_FRONTEND_WIDTH-1; sFormInit.height = HIDDEN_FRONTEND_HEIGHT-1; sFormInit.pDisplay = displayTitleBitmap; widgAddForm(psWScreen, &sFormInit); }
void pie_UploadDisplayBuffer(UBYTE *DisplayBuffer) { switch (pie_GetRenderEngine()) { case ENGINE_4101: case ENGINE_SR: UploadDisplayBuffer(DisplayBuffer); break; case ENGINE_GLIDE: gl_UploadDisplayBuffer(DisplayBuffer); screen_SetBackDrop(DisplayBuffer, pie_GetVideoBufferWidth(), pie_GetVideoBufferHeight()); break; case ENGINE_D3D: //only call inside D3D render pie_GlobalRenderEnd(FALSE); screen_Upload(DisplayBuffer); screen_SetBackDrop(DisplayBuffer, pie_GetVideoBufferWidth(), pie_GetVideoBufferHeight()); pie_GlobalRenderBegin(); default: break; } }
// show a background piccy (currently used for version and mods labels) static void displayTitleBitmap(WZ_DECL_UNUSED WIDGET *psWidget, WZ_DECL_UNUSED UDWORD xOffset, WZ_DECL_UNUSED UDWORD yOffset, WZ_DECL_UNUSED PIELIGHT *pColours) { char modListText[MAX_STR_LENGTH] = ""; iV_SetFont(font_regular); iV_SetTextColour(WZCOL_GREY); iV_DrawTextRotated(version_getFormattedVersionString(), pie_GetVideoBufferWidth() - 9, pie_GetVideoBufferHeight() - 14, 270.f); if (*getModList()) { sstrcat(modListText, _("Mod: ")); sstrcat(modListText, getModList()); iV_DrawText(modListText, 9, 14); } iV_SetTextColour(WZCOL_TEXT_BRIGHT); iV_DrawTextRotated(version_getFormattedVersionString(), pie_GetVideoBufferWidth() - 10, pie_GetVideoBufferHeight() - 15, 270.f); if (*getModList()) { iV_DrawText(modListText, 10, 15); } }
/** Displays all the console messages */ void displayConsoleMessages(void) { // Check if we have any messages we want to show if (!getNumberConsoleMessages() && !bConsoleDropped && !InfoMessages.size()) { return; } // scripts can disable the console if (!bConsoleDisplayEnabled && !InfoMessages.size()) { return; } iV_SetFont(font_regular); pie_SetDepthBufferStatus(DEPTH_CMP_ALWAYS_WRT_ON); pie_SetFogStatus(false); if (bConsoleDropped) { displayOldMessages(HistoryMode); } std::lock_guard<wz::mutex> lck(mtx); // Don't iterate without a lock. if (InfoMessages.size()) { auto i = InfoMessages.end() - 1; // we can only show the last one... setConsoleTextColor(i->player); int tmp = pie_GetVideoBufferWidth(); drawBlueBox(0, 0,tmp, 18); tmp -= iV_GetTextWidth(i->text.c_str()); iV_DrawFormattedText(i->text.c_str(), tmp - 6, linePitch - 2, iV_GetTextWidth(i->text.c_str()), i->JustifyType); } int TextYpos = mainConsole.topY; // Draw the blue background for the text (only in game, not lobby) if (bTextBoxActive && GetGameMode() == GS_NORMAL) { iV_TransBoxFill(mainConsole.topX - CON_BORDER_WIDTH, mainConsole.topY - mainConsole.textDepth - CON_BORDER_HEIGHT, mainConsole.topX + mainConsole.width, mainConsole.topY + (getNumberConsoleMessages() * linePitch) + CON_BORDER_HEIGHT - linePitch); } for (auto i = ActiveMessages.begin(); i != ActiveMessages.end(); ++i) { setConsoleTextColor(i->player); TextYpos = iV_DrawFormattedText(i->text.c_str(), mainConsole.topX, TextYpos, mainConsole.width, i->JustifyType); } }
static void pie_DrawShadows(void) { const float width = pie_GetVideoBufferWidth(); const float height = pie_GetVideoBufferHeight(); pie_SetTexturePage(TEXPAGE_NONE); glPushMatrix(); pie_SetAlphaTest(false); glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); glDepthFunc(GL_LESS); glDepthMask(GL_FALSE); glEnable(GL_STENCIL_TEST); ShadowStencilFunc(); pie_SetRendMode(REND_ALPHA); glEnable(GL_CULL_FACE); glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP); glStencilMask(~0); glStencilFunc(GL_LESS, 0, ~0); glColor4f(0, 0, 0, 0.5); pie_PerspectiveEnd(); glLoadIdentity(); glDisable(GL_DEPTH_TEST); glBegin(GL_TRIANGLE_STRIP); glVertex2f(0, 0); glVertex2f(width, 0); glVertex2f(0, height); glVertex2f(width, height); glEnd(); pie_PerspectiveBegin(); pie_SetRendMode(REND_OPAQUE); glDisable(GL_STENCIL_TEST); glEnable(GL_DEPTH_TEST); glDepthMask(GL_TRUE); glPopMatrix(); scshapes.clear(); }
//----------------------------------------------------------------------------------- bool droidOnScreen(DROID *psDroid, SDWORD tolerance) { SDWORD dX, dY; if (DrawnInLastFrame(psDroid->sDisplay.frameNumber) == true) { dX = psDroid->sDisplay.screenX; dY = psDroid->sDisplay.screenY; /* Is it on screen */ if (dX > (0 - tolerance) && dY > (0 - tolerance) && dX < (SDWORD)(pie_GetVideoBufferWidth() + tolerance) && dY < (SDWORD)(pie_GetVideoBufferHeight() + tolerance)) { return (true); } } return (false); }
int32 iV_VideoMemorySize(int mode) { int32 size; switch (mode) { case iV_MODE_4101: case REND_D3D_RGB: case REND_D3D_HAL: case REND_D3D_REF: case REND_GLIDE_3DFX: size = pie_GetVideoBufferWidth() * pie_GetVideoBufferHeight(); break; default: size = 0; } return size; }
const glm::mat4& pie_PerspectiveGet() { const float width = std::max(pie_GetVideoBufferWidth(), 1); // Require width > 0 && height > 0, to avoid glScalef(1, 1, -1) crashing in some graphics drivers. const float height = std::max(pie_GetVideoBufferHeight(), 1); if (width != perspectiveCache._width || height != perspectiveCache._height || rendSurface.xcentre != perspectiveCache._rendSurface_xcentre || rendSurface.ycentre != perspectiveCache._rendSurface_ycentre) { // update the current perspective matrix (can be a semi-costly operation) const float xangle = width / 6.0f; const float yangle = height / 6.0f; perspectiveCache.currentPerspectiveMatrix = glm::translate(glm::vec3((2.f * rendSurface.xcentre - width) / width, (height - 2.f * rendSurface.ycentre) / height, 0.f)) * glm::frustum(-xangle, xangle, -yangle, yangle, 330.f, 100000.f) * glm::scale(glm::vec3(1.f, 1.f, -1.f)); perspectiveCache._width = width; perspectiveCache._height = height; perspectiveCache._rendSurface_xcentre = rendSurface.xcentre; perspectiveCache._rendSurface_ycentre = rendSurface.ycentre; } return perspectiveCache.currentPerspectiveMatrix; }
void screen_Display() { pie_SetDepthBufferStatus(DEPTH_CMP_ALWAYS_WRT_OFF); // Draw backdrop backdropGfx->draw(glm::ortho(0.f, (float)pie_GetVideoBufferWidth(), (float)pie_GetVideoBufferHeight(), 0.f)); if (mappreview) { int s1 = screenWidth / preview_width; int s2 = screenHeight / preview_height; int scale = MIN(s1, s2); int w = preview_width * scale; int h = preview_height * scale; for (int i = 0; i < MAX_PLAYERS; i++) { int x = player_pos[i].x; int y = player_pos[i].y; char text[5]; if (x == 0x77777777) { continue; } x = screenWidth / 2 - w / 2 + x * scale; y = screenHeight / 2 - h / 2 + y * scale; ssprintf(text, "%d", i); iV_SetFont(font_large); iV_SetTextColour(WZCOL_BLACK); iV_DrawText(text, x - 1, y - 1); iV_DrawText(text, x + 1, y - 1); iV_DrawText(text, x - 1, y + 1); iV_DrawText(text, x + 1, y + 1); iV_SetTextColour(WZCOL_WHITE); iV_DrawText(text, x, y); } } pie_SetDepthBufferStatus(DEPTH_CMP_LEQ_WRT_ON); }
//----------------------------------------------------------------------------------- static uint16_t getAverageTrackAngle(unsigned groupNumber, bool bCheckOnScreen) { DROID *psDroid; int32_t xTotal = 0, yTotal = 0; /* Got thru' all droids */ for (psDroid = apsDroidLists[selectedPlayer]; psDroid; psDroid = psDroid->psNext) { /* Is he worth selecting? */ if (groupNumber == GROUP_SELECTED ? psDroid->selected : psDroid->group == groupNumber) { if (bCheckOnScreen ? droidOnScreen(psDroid, pie_GetVideoBufferWidth() / 6) : true) { xTotal += iSin(psDroid->rot.direction); yTotal += iCos(psDroid->rot.direction); } } } presAvAngle = iAtan2(xTotal, yTotal); return presAvAngle; }
void drawRadar() { float pixSizeH, pixSizeV; CalcRadarPixelSize(&pixSizeH, &pixSizeV); ASSERT_OR_RETURN(, radarBuffer, "No radar buffer allocated"); // Do not recalculate frustum window coordinates if position or zoom does not change if (playerpos.x != player.p.x || playerpos.y != player.p.y || playerpos.z != player.p.z) { setViewingWindow(); } playerpos = player.p; // cache position if (frameSkip <= 0) { DrawRadarTiles(); DrawRadarObjects(); pie_DownLoadRadar(radarBuffer); frameSkip = RADAR_FRAME_SKIP; } frameSkip--; pie_SetRendMode(REND_ALPHA); glm::mat4 radarMatrix = glm::translate(radarCenterX, radarCenterY, 0); glm::mat4 orthoMatrix = glm::ortho(0.f, static_cast<float>(pie_GetVideoBufferWidth()), static_cast<float>(pie_GetVideoBufferHeight()), 0.f); if (rotateRadar) { // rotate the map radarMatrix *= glm::rotate(UNDEG(player.r.y), glm::vec3(0.f, 0.f, 1.f)); DrawNorth(orthoMatrix * radarMatrix); } pie_RenderRadar(orthoMatrix * radarMatrix); DrawRadarExtras(orthoMatrix * radarMatrix * glm::translate(-radarWidth / 2.f - 1.f, -radarHeight / 2.f - 1.f, 0.f)); drawRadarBlips(-radarWidth / 2.0 - 1, -radarHeight / 2.0 - 1, pixSizeH, pixSizeV, orthoMatrix * radarMatrix); }
int realmain(int argc, char *argv[]) { // The libcrypto startup stuff... May or may not actually be needed for anything at all. ERR_load_crypto_strings(); // This is needed for descriptive error messages. OpenSSL_add_all_algorithms(); // Don't actually use the EVP functions, so probably not needed. OPENSSL_config(nullptr); // What does this actually do? #ifdef WZ_OS_WIN RAND_screen(); // Uses a screenshot as a random seed, on systems lacking /dev/random. #endif wzMain(argc, argv); int utfargc = argc; const char** utfargv = (const char**)argv; #ifdef WZ_OS_MAC cocoaInit(); #endif debug_init(); debug_register_callback( debug_callback_stderr, NULL, NULL, NULL ); #if defined(WZ_OS_WIN) && defined(DEBUG_INSANE) debug_register_callback( debug_callback_win32debug, NULL, NULL, NULL ); #endif // WZ_OS_WIN && DEBUG_INSANE // ***** // NOTE: Try *NOT* to use debug() output routines without some other method of informing the user. All this output is sent to /dev/nul at this point on some platforms! // ***** if (!getUTF8CmdLine(&utfargc, &utfargv)) { return EXIT_FAILURE; } QTextCodec::setCodecForCStrings(QTextCodec::codecForName("UTF-8")); // make Qt treat all C strings in Warzone as UTF-8 setupExceptionHandler(utfargc, utfargv, version_getFormattedVersionString()); /*** Initialize PhysicsFS ***/ initialize_PhysicsFS(utfargv[0]); /*** Initialize translations ***/ initI18n(); // find early boot info if (!ParseCommandLineEarly(utfargc, utfargv)) { return EXIT_FAILURE; } /* Initialize the write/config directory for PhysicsFS. * This needs to be done __after__ the early commandline parsing, * because the user might tell us to use an alternative configuration * directory. */ initialize_ConfigDir(); /*** Initialize directory structure ***/ make_dir(ScreenDumpPath, "screenshots", NULL); make_dir(SaveGamePath, "savegames", NULL); PHYSFS_mkdir("savegames/campaign"); PHYSFS_mkdir("savegames/skirmish"); make_dir(MultiCustomMapsPath, "maps", NULL); // MUST have this to prevent crashes when getting map PHYSFS_mkdir("music"); PHYSFS_mkdir("logs"); // a place to hold our netplay, mingw crash reports & WZ logs PHYSFS_mkdir("userdata"); // a place to store per-mod data user generated data memset(rulesettag, 0, sizeof(rulesettag)); // tag to add to userdata to find user generated stuff make_dir(MultiPlayersPath, "multiplay", NULL); make_dir(MultiPlayersPath, "multiplay", "players"); if (!customDebugfile) { // there was no custom debug file specified (--debug-file=blah) // so we use our write directory to store our logs. time_t aclock; struct tm *newtime; char buf[PATH_MAX]; time( &aclock ); // Get time in seconds newtime = localtime( &aclock ); // Convert time to struct // Note: We are using fopen(), and not physfs routines to open the file // log name is logs/(or \)WZlog-MMDD_HHMMSS.txt snprintf(buf, sizeof(buf), "%slogs%sWZlog-%02d%02d_%02d%02d%02d.txt", PHYSFS_getWriteDir(), PHYSFS_getDirSeparator(), newtime->tm_mon + 1, newtime->tm_mday, newtime->tm_hour, newtime->tm_min, newtime->tm_sec ); debug_register_callback( debug_callback_file, debug_callback_file_init, debug_callback_file_exit, buf ); // FIXME: Change this to LOG_WZ on next release debug(LOG_INFO, "Using %s debug file", buf); } // NOTE: it is now safe to use debug() calls to make sure output gets captured. check_Physfs(); debug(LOG_WZ, "Warzone 2100 - %s", version_getFormattedVersionString()); debug(LOG_WZ, "Using language: %s", getLanguage()); debug(LOG_WZ, "Backend: %s", BACKEND); debug(LOG_MEMORY, "sizeof: SIMPLE_OBJECT=%ld, BASE_OBJECT=%ld, DROID=%ld, STRUCTURE=%ld, FEATURE=%ld, PROJECTILE=%ld", (long)sizeof(SIMPLE_OBJECT), (long)sizeof(BASE_OBJECT), (long)sizeof(DROID), (long)sizeof(STRUCTURE), (long)sizeof(FEATURE), (long)sizeof(PROJECTILE)); /* Put in the writedir root */ sstrcpy(KeyMapPath, "keymap.map"); // initialise all the command line states war_SetDefaultStates(); debug(LOG_MAIN, "initializing"); PhysicsEngineHandler engine; // register abstract physfs filesystem loadConfig(); // parse the command line if (!ParseCommandLine(utfargc, utfargv)) { return EXIT_FAILURE; } // Save new (commandline) settings saveConfig(); // Find out where to find the data scanDataDirs(); // Now we check the mods to see if they exist or not (specified on the command line) // They are all capped at 100 mods max(see clparse.c) // FIX ME: I know this is a bit hackish, but better than nothing for now? { char *modname; char modtocheck[256]; int i = 0; int result = 0; // check global mods for(i=0; i < 100; i++) { modname = global_mods[i]; if (modname == NULL) { break; } ssprintf(modtocheck, "mods/global/%s", modname); result = PHYSFS_exists(modtocheck); result |= PHYSFS_isDirectory(modtocheck); if (!result) { debug(LOG_ERROR, "The (global) mod (%s) you have specified doesn't exist!", modname); } else { info("(global) mod (%s) is enabled", modname); } } // check campaign mods for(i=0; i < 100; i++) { modname = campaign_mods[i]; if (modname == NULL) { break; } ssprintf(modtocheck, "mods/campaign/%s", modname); result = PHYSFS_exists(modtocheck); result |= PHYSFS_isDirectory(modtocheck); if (!result) { debug(LOG_ERROR, "The mod_ca (%s) you have specified doesn't exist!", modname); } else { info("mod_ca (%s) is enabled", modname); } } // check multiplay mods for(i=0; i < 100; i++) { modname = multiplay_mods[i]; if (modname == NULL) { break; } ssprintf(modtocheck, "mods/multiplay/%s", modname); result = PHYSFS_exists(modtocheck); result |= PHYSFS_isDirectory(modtocheck); if (!result) { debug(LOG_ERROR, "The mod_mp (%s) you have specified doesn't exist!", modname); } else { info("mod_mp (%s) is enabled", modname); } } } if (!wzMain2(war_getFSAA(), war_getFullscreen(), war_GetVsync())) { return EXIT_FAILURE; } int w = pie_GetVideoBufferWidth(); int h = pie_GetVideoBufferHeight(); char buf[256]; ssprintf(buf, "Video Mode %d x %d (%s)", w, h, war_getFullscreen() ? "fullscreen" : "window"); addDumpInfo(buf); debug(LOG_MAIN, "Final initialization"); if (!frameInitialise()) { return EXIT_FAILURE; } if (!screenInitialise()) { return EXIT_FAILURE; } if (!pie_LoadShaders()) { return EXIT_FAILURE; } war_SetWidth(pie_GetVideoBufferWidth()); war_SetHeight(pie_GetVideoBufferHeight()); pie_SetFogStatus(false); pie_ScreenFlip(CLEAR_BLACK); pal_Init(); pie_LoadBackDrop(SCREEN_RANDOMBDROP); pie_SetFogStatus(false); pie_ScreenFlip(CLEAR_BLACK); if (!systemInitialise()) { return EXIT_FAILURE; } //set all the pause states to false setAllPauseStates(false); // Copy this info to be used by the crash handler for the dump file ssprintf(buf,"Using Backend: %s", BACKEND); addDumpInfo(buf); ssprintf(buf,"Using language: %s", getLanguageName()); addDumpInfo(buf); // Do the game mode specific initialisation. switch(GetGameMode()) { case GS_TITLE_SCREEN: startTitleLoop(); break; case GS_SAVEGAMELOAD: initSaveGameLoad(); break; case GS_NORMAL: startGameLoop(); break; default: debug(LOG_ERROR, "Weirdy game status, I'm afraid!!"); break; } #if defined(WZ_CC_MSVC) && defined(DEBUG) debug_MEMSTATS(); #endif debug(LOG_MAIN, "Entering main loop"); wzMain3(); saveConfig(); systemShutdown(); #ifdef WZ_OS_WIN // clean up the memory allocated for the command line conversion for (int i=0; i<argc; i++) { const char*** const utfargvF = &utfargv; free((void *)(*utfargvF)[i]); } free(utfargv); #endif wzShutdown(); debug(LOG_MAIN, "Completed shutting down Warzone 2100"); return EXIT_SUCCESS; }
// This stage, we handle display mode setting bool wzMainScreenSetup(int antialiasing, bool fullscreen, bool vsync) { // populate with the saved values (if we had any) int width = pie_GetVideoBufferWidth(); int height = pie_GetVideoBufferHeight(); int bitDepth = pie_GetVideoBufferDepth(); if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_TIMER) != 0) { debug(LOG_ERROR, "Error: Could not initialise SDL (%s).", SDL_GetError()); return false; } // Populated our resolution list (does all displays now) SDL_DisplayMode displaymode; struct screeninfo screenlist; for (int i = 0; i < SDL_GetNumVideoDisplays(); ++i) // How many monitors we got { int numdisplaymodes = SDL_GetNumDisplayModes(i); // Get the number of display modes on this monitor for (int j = 0; j < numdisplaymodes; j++) { displaymode.format = displaymode.w = displaymode.h = displaymode.refresh_rate = 0; displaymode.driverdata = 0; if (SDL_GetDisplayMode(i, j, &displaymode) < 0) { debug(LOG_FATAL, "SDL_LOG_CATEGORY_APPLICATION error:%s", SDL_GetError()); SDL_Quit(); exit(EXIT_FAILURE); } debug(LOG_WZ, "Monitor[%d]%dx%d %d %s", i, displaymode.w, displaymode.h, displaymode.refresh_rate, getSDL_fmt_string(displaymode.format)); if (displaymode.refresh_rate < 59) { continue; // only store 60Hz & higher modes, some display report 59 on linux } screenlist.height = displaymode.h; screenlist.width = displaymode.w; screenlist.refresh_rate = displaymode.refresh_rate; screenlist.screen = i; // which monitor this belongs to displaylist.push_back(screenlist); } } SDL_DisplayMode current = { 0, 0, 0, 0, 0 }; for (int i = 0; i < SDL_GetNumVideoDisplays(); ++i) { int display = SDL_GetCurrentDisplayMode(i, ¤t); if (display != 0) { debug(LOG_FATAL, "Can't get the current display mode, because: %s", SDL_GetError()); SDL_Quit(); exit(EXIT_FAILURE); } debug(LOG_WZ, "Monitor[%d]%dx%d %d", i, current.w, current.h, current.refresh_rate); } if (width == 0 || height == 0) { pie_SetVideoBufferWidth(width = screenWidth = current.w); pie_SetVideoBufferHeight(height = screenHeight = current.h); } else { screenWidth = width; screenHeight = height; } screenWidth = MAX(screenWidth, 640); screenHeight = MAX(screenHeight, 480); //// The flags to pass to SDL_CreateWindow int video_flags = SDL_WINDOW_OPENGL | SDL_WINDOW_SHOWN; if (war_getFullscreen()) { video_flags |= SDL_WINDOW_FULLSCREEN; } SDL_Rect bounds; for (int i = 0; i < SDL_GetNumVideoDisplays(); i++) { SDL_GetDisplayBounds(i, &bounds); debug(LOG_WZ, "Monitor %d: pos %d x %d : res %d x %d", i, (int)bounds.x, (int)bounds.y, (int)bounds.w, (int)bounds.h); } if (war_GetScreen() > SDL_GetNumVideoDisplays()) { debug(LOG_FATAL, "Invalid screen defined in configuration"); SDL_Quit(); exit(EXIT_FAILURE); } SDL_GetDisplayBounds(war_GetScreen(), &bounds); bounds.w -= (bounds.w + screenWidth) / 2; bounds.h -= (bounds.h + screenHeight) / 2; WZwindow = SDL_CreateWindow(PACKAGE_NAME, bounds.x + bounds.w, bounds.y + bounds.h, screenWidth, screenHeight, video_flags); if (!WZwindow) { debug(LOG_FATAL, "Can't create a window, because: %s", SDL_GetError()); SDL_Quit(); exit(EXIT_FAILURE); } WZglcontext = SDL_GL_CreateContext(WZwindow); if (!WZglcontext) { debug(LOG_ERROR, "Failed to create a openGL context! [%s]", SDL_GetError()); return false; } // Set the double buffer OpenGL attribute. SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); // Enable FSAA anti-aliasing if and at the level requested by the user if (antialiasing) { SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 1); SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, antialiasing); } int bpp = SDL_BITSPERPIXEL(SDL_GetWindowPixelFormat(WZwindow)); debug(LOG_WZ, "Bpp = %d format %s" , bpp, getSDL_fmt_string(SDL_GetWindowPixelFormat(WZwindow))); if (!bpp) { debug(LOG_ERROR, "Video mode %dx%d@%dbpp is not supported!", width, height, bitDepth); return false; } switch (bpp) { case 32: case 24: // all is good... break; case 16: info("Using colour depth of %i instead of a 32/24 bit depth (True color).", bpp); info("You will experience graphics glitches!"); break; case 8: debug(LOG_FATAL, "You don't want to play Warzone with a bit depth of %i, do you?", bpp); SDL_Quit(); exit(1); break; default: debug(LOG_FATAL, "Unsupported bit depth: %i", bpp); exit(1); break; } // Enable/disable vsync if requested by the user wzSetSwapInterval(war_GetVsync()); int value = 0; if (SDL_GL_GetAttribute(SDL_GL_DOUBLEBUFFER, &value) == -1 || value == 0) { debug(LOG_FATAL, "OpenGL initialization did not give double buffering!"); debug(LOG_FATAL, "Double buffering is required for this game!"); SDL_Quit(); exit(1); } #if SDL_BYTEORDER == SDL_BIG_ENDIAN uint32_t rmask = 0xff000000; uint32_t gmask = 0x00ff0000; uint32_t bmask = 0x0000ff00; uint32_t amask = 0x000000ff; #else uint32_t rmask = 0x000000ff; uint32_t gmask = 0x0000ff00; uint32_t bmask = 0x00ff0000; uint32_t amask = 0xff000000; #endif SDL_Surface *surface_icon = SDL_CreateRGBSurfaceFrom((void *)wz2100icon.pixel_data, wz2100icon.width, wz2100icon.height, wz2100icon.bytes_per_pixel * 8, wz2100icon.width * wz2100icon.bytes_per_pixel, rmask, gmask, bmask, amask); if (surface_icon) { SDL_SetWindowIcon(WZwindow, surface_icon); SDL_FreeSurface(surface_icon); } else { debug(LOG_ERROR, "Could not set window icon because %s", SDL_GetError()); } SDL_SetWindowTitle(WZwindow, PACKAGE_NAME); /* initialise all cursors */ if (war_GetColouredCursor()) { sdlInitColoredCursors(); } else { sdlInitCursors(); } // FIXME: aspect ratio glViewport(0, 0, width, height); glMatrixMode(GL_PROJECTION); glPushMatrix(); glLoadIdentity(); glOrtho(0, width, height, 0, 1, -1); glMatrixMode(GL_TEXTURE); glLoadIdentity(); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); glCullFace(GL_FRONT); glEnable(GL_CULL_FACE); return true; }