/*----------------------------------------------------------------------------- Name : spScenarioBitmap Description : Inputs : Outputs : Return : ----------------------------------------------------------------------------*/ void spScenarioBitmap(featom *atom, regionhandle region) { rectangle textureRect; sdword index, y; fonthandle oldFont; textureRect.x0 = region->rect.x0 + SCP_TEXTURE_INSET; textureRect.y0 = region->rect.y0 + SCP_TEXTURE_INSET; textureRect.x1 = region->rect.x1 - SCP_TEXTURE_INSET; textureRect.y1 = region->rect.y1 - SCP_TEXTURE_INSET; //draw the bitmap... if (scenarioTexture != TR_InvalidInternalHandle) { if (glcActive()) { glcRectSolidTexturedScaled2(&textureRect, spTextureWidth, spTextureHeight, spTextureData, NULL, TRUE); } else { trRGBTextureMakeCurrent(scenarioTexture); rndPerspectiveCorrection(FALSE); primRectSolidTextured2(&textureRect); //draw the bitmap } feStaticRectangleDraw(region); //draw a border } //draw the description text... if (spDescription != NULL) { //if there is description text dbgAssert(spDescriptionFont != FONT_InvalidFontHandle); oldFont = fontMakeCurrent(spDescriptionFont); //set the font if (spDescriptionShadow) { //optionally enable dropshadow fontShadowSet(FS_SE, colBlack); } for (index = 0, y = textureRect.y0; index < spNDescriptionLines; index++) { //draw each line dbgAssert(spDescriptionLines[index] != NULL); if (y + fontHeight(" ") >= textureRect.y1) { //if this line will extend off bottom of region break; } fontPrint(textureRect.x0, y, spDescriptionColor, spDescriptionLines[index]); y += fontHeight(" ") + 1; } fontShadowSet(FS_NONE, colBlack); fontMakeCurrent(oldFont); } }
/*----------------------------------------------------------------------------- Name : svShipViewRender Description : Callback which draws the main ship view. Inputs : standard FE callback Outputs : .. Return : void ----------------------------------------------------------------------------*/ void svShipViewRender(featom* atom, regionhandle region) { rectangle drawRect; rectangle* rect; rectangle viewRect; fonthandle currentFont; GLint viewPort[4]; GLint box[4]; ShipStaticInfo* info; real32 scale; sdword width, height; sdword x, y; keyindex key; char* keystring; bool resetRender = FALSE; char temp[100]; // facilitates smooth transition between auto/manual rotation of ship static real32 angle_user_rotated_to = 0.0f; static real32 declination_user_rotated_to = 0.0f; static real32 time_user_rotated_view = 0.0f; real32 real_time_angle = 0.0f; static real32 user_real_angle_offset = 0.0f; rect = ®ion->rect; viewRect.x0 = 0; viewRect.y0 = 0; viewRect.x1 = MAIN_WindowWidth - 1; viewRect.y1 = MAIN_WindowHeight - 1; info = NULL; if (svShipType != DefaultShip) { if (universe.curPlayerPtr) { info = GetShipStaticInfoSafe(svShipType, universe.curPlayerPtr->race); } if (info == NULL) { info = GetShipStaticInfoSafe(svShipType, GetValidRaceForShipType(svShipType)); } if (info == NULL) { return; } } svShipViewRegion = region; if (!resetRender) { if (svMouseInside) { ferDrawFocusWindow(region, lw_focus); } else { ferDrawFocusWindow(region, lw_normal); } } soundEventUpdate(); currentFont = fontMakeCurrent(svShipViewFont); if (region->flags == 0 || region->flags == RPE_DrawFunctionAdded) { //if region not processed yet region->flags = RPE_Enter | RPE_Exit | RPE_WheelDown | RPE_WheelUp | RPE_PressLeft | RPE_ReleaseLeft | RPE_PressRight | RPE_ReleaseRight; regFunctionSet(region, (regionfunction) svReadMouseEvent); //set new region handler function } //scale = *svScale[svShipType]; //svCamera.closestZoom = *svMinZoom[svShipType]; //svCamera.farthestZoom = *svMaxZoom[svShipType]; scale = 1.0f; //*svScale[svShipType]; if(svShipType != DefaultShip) { svCamera.closestZoom = info->minimumZoomDistance*svZoomInScalar; svCamera.farthestZoom = (svCamera.closestZoom+info->staticheader.staticCollInfo.approxcollspheresize)*svZoomOutScalar; if(ReZoom) { ReZoom=FALSE; cameraZoom(&svCamera,1.0f,FALSE); } if (svMouseInside && (wheel_down || wheel_up)) { cameraControl(&svCamera, FALSE); } else if (svMouseInside && svMousePressRight) { camMouseX = (svMouseCentreX - mouseCursorX()) * 4; //was 2 camMouseY = (svMouseCentreY - mouseCursorY()) * 4; savecamMouseX = savecamMouseX * SPIN_FEEDBACK + (real32)camMouseX * (1.0f - SPIN_FEEDBACK); cameraControl(&svCamera, FALSE); //update the camera mouseCursorHide(); mousePositionSet(svMouseCentreX, svMouseCentreY); // Reset position so it doesn't walk off region // keep track of where the user left the camera so we can sync auto-rotation with it angle_user_rotated_to = svCamera.angle; declination_user_rotated_to = svCamera.declination; time_user_rotated_view = universe.totaltimeelapsed; } else // auto rotate ship model { // continual 360 degree yaw rotation real_time_angle = DEG_TO_RAD(remainder(universe.totaltimeelapsed, SV_360_ROTATION_SECS) / SV_360_ROTATION_SECS * 360); if (angle_user_rotated_to >= 0.0) { user_real_angle_offset = angle_user_rotated_to - real_time_angle; angle_user_rotated_to = -1.0; } svCamera.angle = real_time_angle + user_real_angle_offset; // collapse pitch to default declination if (time_user_rotated_view > 0.0) { if (universe.totaltimeelapsed > time_user_rotated_view + SV_PITCH_FLATTEN_SECS) { svCamera.declination = DEG_TO_RAD(svDeclination); time_user_rotated_view = 0.0; } else { svCamera.declination = declination_user_rotated_to + (DEG_TO_RAD(svDeclination) - declination_user_rotated_to) * ((universe.totaltimeelapsed - time_user_rotated_view) / SV_PITCH_FLATTEN_SECS); } } if (svMouseInside) mouseCursorShow(); } } //rotation drawRect.x0 = rect->x0 + SV_ViewMargin; drawRect.y0 = rect->y0 + SV_ViewMargin; drawRect.x1 = rect->x1 - SV_ViewMargin; drawRect.y1 = rect->y1 - SV_ViewMargin; width = drawRect.x1 - drawRect.x0; height = drawRect.y1 - drawRect.y0; glGetIntegerv(GL_VIEWPORT, viewPort); glViewport(drawRect.x0, MAIN_WindowHeight - drawRect.y1, width, height); primModeSet2(); if (!resetRender) { primRectSolid2(&viewRect, FEC_Background); } primModeClear2(); glEnable(GL_SCISSOR_TEST); glGetIntegerv(GL_SCISSOR_BOX, box); glScissor(drawRect.x0, MAIN_WindowHeight - drawRect.y1, width, height); glClear(GL_DEPTH_BUFFER_BIT); glDisable(GL_SCISSOR_TEST); rndPerspectiveCorrection(TRUE); //svCamera.lookatpoint.x = -info->staticheader.staticCollInfo.collsphereoffset.z * scale; //svCamera.lookatpoint.y = -info->staticheader.staticCollInfo.collsphereoffset.x * scale; //svCamera.lookatpoint.z = -info->staticheader.staticCollInfo.collsphereoffset.y * scale; if (svShipType == DefaultShip) { svCamera.lookatpoint.x=0.0f; svCamera.lookatpoint.y=0.0f; svCamera.lookatpoint.z=0.0f; } else { svCamera.lookatpoint.x = -info->staticheader.staticCollInfo.collsphereoffset.z; svCamera.lookatpoint.y = -info->staticheader.staticCollInfo.collsphereoffset.x; svCamera.lookatpoint.z = -info->staticheader.staticCollInfo.collsphereoffset.y; } cameraSetEyePosition(&svCamera); rndLightingEnable(TRUE); glMatrixMode(GL_PROJECTION); glLoadIdentity(); rgluPerspective( svCamera.fieldofview, (float)(width) / (float)(height) /*rndAspectRatio*/, //set projection matrix svCamera.clipPlaneNear, svCamera.clipPlaneFar); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); rgluLookAt( svCamera.eyeposition.x, svCamera.eyeposition.y, svCamera.eyeposition.z, svCamera.lookatpoint.x, svCamera.lookatpoint.y, svCamera.lookatpoint.z, svCamera.upvector.x, svCamera.upvector.y, svCamera.upvector.z); glPushMatrix(); glRotatef(-90.0f, 0.0f, 1.0f, 0.0f); glGetFloatv(GL_MODELVIEW_MATRIX, (GLfloat *)(&rndCameraMatrix)); glGetFloatv(GL_PROJECTION_MATRIX, (GLfloat *)(&rndProjectionMatrix)); glEnable(GL_NORMALIZE); glLightfv(GL_LIGHT0, GL_POSITION, lightPosition0); //position light(s) within world glScalef(scale, scale, scale); if (svShipType != DefaultShip) { sdword index; //try player index colours first index = universe.curPlayerIndex; if (info->teamColor[index] == 0) { //colour scheme doesn't exist, search for something valid for (index = 0; index < MAX_MULTIPLAYER_PLAYERS; index++) { if (info->teamColor[index] != 0) { break; } } if (index == MAX_MULTIPLAYER_PLAYERS) { //this ship doesn't have any colour info, //at least avoid a GPF index = universe.curPlayerIndex; } } meshRender((meshdata *)info->staticheader.LOD->level[0].pData, index); } glDisable(GL_NORMALIZE); glPopMatrix(); primModeSet2(); glScissor(box[0], box[1], box[2], box[3]); glViewport(viewPort[0], viewPort[1], viewPort[2], viewPort[3]); rndLightingEnable(FALSE); rndPerspectiveCorrection(FALSE); x = rect->x0 + 2 + SV_ViewMargin; y = rect->y0 + 2 + SV_ViewMargin; if (svShipType != DefaultShip && !resetRender) { fontPrintf( x, y, FEC_ListItemStandard, "%s", ShipTypeToNiceStr(svShipType)); y += fontHeight(" "); sprintf(temp, "%s %d %s",strGetString(strSVCost),info->buildCost, strGetString(strSVRUs)); fontPrintf( x, y, FEC_ListItemStandard, temp); if (cmPrintHotKey) { x = rect->x1 - 2 - SV_ViewMargin; y = rect->y0 + 2 + SV_ViewMargin; key = cmShipTypeToKey(svShipType); keystring = opKeyToNiceString((keyindex)(key & 0x00ff)); if (key & CM_SHIFT) { width = fontWidthf("[SHIFT-%s]",keystring); fontPrintf( x-width, y, FEC_ListItemStandard, "[SHIFT-%s]", keystring); } else if (key) { width = fontWidthf("[%s]",keystring); fontPrintf( x-width, y, FEC_ListItemStandard, "[%s]", keystring); } } } fontMakeCurrent(currentFont); svDirtyShipView(); }
/*----------------------------------------------------------------------------- Name : tmTechImageDraw Description : Loads in, decompresses and draws the tech picture. Inputs : none Outputs : loads in tmTechImage and creates tmTechTexture Return : void ----------------------------------------------------------------------------*/ void tmTechImageDraw(featom *atom, regionhandle region) { char filename[128]; sdword index, lru = 0; real32 time=(real32)1.0e22; rectangle textureRect; tmTechImageRegion = region; feStaticRectangleDraw(region); //draw standard rectangle if (tmtechinfo != -1) { if (tmtechinfo != tmCurTechTexture) { for (index=0;index<TM_TOTALPICS;index++) // RM_TOTALPICS is the size of the cache { // Find least recently used texture if (pictures[index].timestamp < time) { time = pictures[index].timestamp; lru = index; } // If already cached, use it and exit this routine if ( (pictures[index].tech==tmtechinfo) && (pictures[index].race==universe.curPlayerPtr->race) ) { tmTechTexturePrepare(index); tmCurTechTexture = tmtechinfo; tmCurTechImage = pictures[lru].techImage; tmCurIndex = index; pictures[index].timestamp = universe.totaltimeelapsed; textureRect.x0=region->rect.x0+TM_TEXTURE_INSET; textureRect.y0=region->rect.y0+TM_TEXTURE_INSET; textureRect.x1=region->rect.x1-TM_TEXTURE_INSET; textureRect.y1=region->rect.y1-TM_TEXTURE_INSET; rndPerspectiveCorrection(FALSE); primRectSolidTextured2(&textureRect); //if(tmExtendedInfoActive) //{ // primRectTranslucent2(&textureRect, colRGBA(0, 0, 0, 128)); // tmTechInfoDraw(region); //} return; } } // Build filename for loading texture from file strcpy(filename, TechImagePaths[universe.curPlayerPtr->race]); strcat(filename, TechTypeToString(tmtechinfo)); strcat(filename,".lif"); // Remove oldest (least recently used) texture from memory if (pictures[lru].techImage != NULL) { memFree(pictures[lru].techImage); pictures[lru].techImage = NULL; } if (pictures[lru].techTexture != TR_InvalidInternalHandle) { trRGBTextureDelete(pictures[lru].techTexture); pictures[lru].techTexture = TR_InvalidInternalHandle; } // Load the image into LRU cache pictures[lru].techImage = trLIFFileLoad(filename, NonVolatile); dbgAssertOrIgnore(pictures[lru].techImage->flags & TRF_Paletted); tmTechTexturePrepare(lru); tmCurTechTexture = tmtechinfo; tmCurTechImage = pictures[lru].techImage; pictures[lru].tech = tmtechinfo; pictures[lru].race = universe.curPlayerPtr->race; pictures[lru].timestamp = universe.totaltimeelapsed; } else { trPalettedTextureMakeCurrent(pictures[tmCurIndex].techTexture, pictures[tmCurIndex].techImage->palette); } textureRect.x0=region->rect.x0+TM_TEXTURE_INSET; textureRect.y0=region->rect.y0+TM_TEXTURE_INSET; textureRect.x1=region->rect.x1-TM_TEXTURE_INSET; textureRect.y1=region->rect.y1-TM_TEXTURE_INSET; rndPerspectiveCorrection(FALSE); primRectSolidTextured2(&textureRect); } }
/*----------------------------------------------------------------------------- Name : btgRender Description : renders the background. assumes modelview already set Inputs : Outputs : Return : ----------------------------------------------------------------------------*/ void btgRender() { udword nStar; sdword lightOn, index; GLboolean texOn, blendOn, depthOn; udword* dlast; udword* dnext; static sdword lastFade = 255; #if MR_KEYBOARD_CHEATS extern bool gMosaic; #endif if (btgHead == NULL) { #ifdef _WIN32 btgLoad("BTG\\default.btg"); #else btgLoad("BTG/default.btg"); #endif } #if MR_KEYBOARD_CHEATS glShadeModel(gMosaic ? GL_FLAT : GL_SMOOTH); #else glShadeModel(GL_SMOOTH); #endif glGetFloatv(GL_COLOR_CLEAR_VALUE, _bgColor); for (index = 0; index < 4; index++) { _bgByte[index] = (GLubyte)(_bgColor[index] * 255.0f); } dnext = (udword*)_bgByte; dlast = (udword*)lastbg; depthOn = glIsEnabled(GL_DEPTH_TEST); lightOn = rndLightingEnable(FALSE); texOn = glIsEnabled(GL_TEXTURE_2D); blendOn = glIsEnabled(GL_BLEND); glDisable(GL_DEPTH_TEST); glDisable(GL_CULL_FACE); glDisable(GL_TEXTURE_2D); glEnable(GL_BLEND); rndAdditiveBlends(FALSE); if (useVBO) glBindBuffer(GL_ARRAY_BUFFER, vboTransVerts); //polys if (btgFade != lastFade || *dnext != *dlast) { if (btgFade < 0) { btgFade = 255; } #ifndef _WIN32_FIXME btgColorVertices(); #endif if (useVBO) glBufferData(GL_ARRAY_BUFFER, btgHead->numVerts * sizeof(btgTransVertex), btgTransVerts, GL_STATIC_DRAW); *dlast = *dnext; lastFade = btgFade; } //use DrawElements to render the bg polys glEnableClientState(GL_COLOR_ARRAY); glEnableClientState(GL_VERTEX_ARRAY); if (useVBO) { glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(btgTransVertex), 0); glVertexPointer(3, GL_FLOAT, sizeof(btgTransVertex), (GLvoid*)4); glBindBuffer(GL_ARRAY_BUFFER, 0); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vboIndices); glDrawElements(GL_TRIANGLES, 3 * btgHead->numPolys, GL_UNSIGNED_SHORT, 0); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); } else { glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(btgTransVertex), (GLubyte*)btgTransVerts); glVertexPointer(3, GL_FLOAT, sizeof(btgTransVertex), ((GLubyte*)btgTransVerts) + 4); glDrawElements(GL_TRIANGLES, 3 * btgHead->numPolys, GL_UNSIGNED_SHORT, btgIndices); } glDisableClientState(GL_COLOR_ARRAY); //stars rndPerspectiveCorrection(FALSE); rndAdditiveBlends(TRUE); trClearCurrent(); glEnable(GL_TEXTURE_2D); rndTextureEnvironment(RTE_Modulate); glEnableClientState(GL_TEXTURE_COORD_ARRAY); if (useVBO) { glBindBuffer(GL_ARRAY_BUFFER, vboTransStars); glVertexPointer(3, GL_FLOAT, sizeof(GLfloat) * 5, 0); glTexCoordPointer(2, GL_FLOAT, sizeof(GLfloat) * 5, (GLubyte*)sizeof(vector)); glBindBuffer(GL_ARRAY_BUFFER, 0); } else { glVertexPointer(3, GL_FLOAT, sizeof(GLfloat) * 5, (GLubyte*)btgTransStars); glTexCoordPointer(2, GL_FLOAT, sizeof(GLfloat) * 5, ((GLubyte*)btgTransStars) + sizeof(vector)); } for (nStar = 0; nStar < btgHead->numStars; nStar++) { if (btgStars[nStar].glhandle) { glColor4ub((GLubyte)btgStars[nStar].red, (GLubyte)btgStars[nStar].green, (GLubyte)btgStars[nStar].blue, (GLubyte)btgStars[nStar].alpha); glBindTexture(GL_TEXTURE_2D, btgStars[nStar].glhandle); glDrawArrays(GL_TRIANGLE_STRIP, nStar * 4, 4); } } glDisableClientState(GL_TEXTURE_COORD_ARRAY); glDisableClientState(GL_VERTEX_ARRAY); glDisable(GL_BLEND); rndAdditiveBlends(FALSE); rndLightingEnable(lightOn); if (texOn) glEnable(GL_TEXTURE_2D); if (blendOn) { glEnable(GL_BLEND); } else { glDisable(GL_BLEND); } glEnable(GL_CULL_FACE); if (depthOn) { glEnable(GL_DEPTH_TEST); } else { glDisable(GL_DEPTH_TEST); } }
void tutExecute(regionhandle reg) { fonthandle currentfont; sdword texty, bitmap; rectangle rect; // used for translucent boxes behind text rectangle *buttonrect = ®->rect; // used for "next" button bool modeset = FALSE; sdword bitmap_x, bitmap_vel; if(tutorial == 3) return; if(tutRegion->previous) regSiblingMoveToFront(tutRegion); if(tutTransition == 0 && tutLesson != TUT_LESSON_ENTER_BUILD_MANAGER && tutLesson != TUT_LESSON_BUILD_SHIP) // don't draw button on build manager lessons { if(mouseInRect(buttonrect)) { if(mouseLeftButton()) { tutSkip = TRUE; trRGBTextureMakeCurrent(tutButtonTexture[NEXT_ON]); } else trRGBTextureMakeCurrent(tutButtonTexture[NEXT_MOUSE]); } else trRGBTextureMakeCurrent(tutButtonTexture[NEXT_OFF]); rndPerspectiveCorrection(FALSE); // glEnable(GL_BLEND); // needs to be enabled once Keith fixes alpha blending intel compiler optimization bug primRectSolidTextured2(buttonrect); // glDisable(GL_BLEND); // needs to be enabled once Keith fixes alpha blending intel compiler optimization bug } if(tutTransition == 0) { switch(PassedTutorial(tutLesson)) { case 0: // Didn't pass break; case 1: // Perform transition tutTransition = 1; break; case -1: // No Transition tutLesson++; InitTutorial(tutLesson); break; } } else if(tutTransition == 1) { tutTransitionCount++; if(tutTransitionCount == TUT_TransitionFramesOut) { tutTransition = 2; tutTransitionCount = TUT_TransitionFramesIn; tutLesson++; InitTutorial(tutLesson); if((tutLesson >= TUT_ADVANCED_INTRO && tutorial == 1) || (tutLesson >= TUT_TOTAL_LESSONS && tutorial == 2)) { tutorialdone = TRUE; return; } } } else if(tutTransition == 2) { tutTransitionCount--; if(tutTransitionCount == 0) tutTransition = 0; } if(tutBitmapList[tutLesson][2] != -1) { bitmap_x = TUT_BITMAP_X; bitmap_vel = 210; } else if(tutBitmapList[tutLesson][1] != -1) { bitmap_x = TUT_BITMAP_X + (TUT_BITMAP_WIDTH + 8); bitmap_vel = 150; } else { bitmap_x = TUT_BITMAP_X + ((2 * TUT_BITMAP_WIDTH) + 8); bitmap_vel = 90; } if(tutTransition == 0) bitmap_vel = 0; else if(tutTransition == 1) bitmap_vel = (long) (((float)bitmap_vel/(float)TUT_TransitionFramesOut) * (float)tutTransitionCount); else if(tutTransition == 2) bitmap_vel = (long) (((float)bitmap_vel/(float)TUT_TransitionFramesIn) * (float)tutTransitionCount); // glEnable(GL_BLEND); for(bitmap = 0; bitmap < 3; bitmap++) { if(tutBitmapList[tutLesson][bitmap] != -1) { trRGBTextureMakeCurrent(tutButtonTexture[tutBitmapList[tutLesson][bitmap]]); rndPerspectiveCorrection(FALSE); rect.x0 = bitmap_x + ((TUT_BITMAP_WIDTH + 8) * bitmap) + bitmap_vel; rect.y0 = TUT_BITMAP_Y; rect.x1 = bitmap_x + ((TUT_BITMAP_WIDTH + 8) * bitmap) + TUT_BITMAP_WIDTH + bitmap_vel; rect.y1 = TUT_BITMAP_Y + TUT_BITMAP_HEIGHT; primRectSolidTextured2(&rect); } } // glDisable(GL_BLEND); if (!primModeEnabled) // draw translucent polys before text { primModeSet2(); modeset = TRUE; } if(tutLesson != TUT_LESSON_BUILD_SHIP) // default behaviour for lessons { long TitlePos = (long)(TUT_TitleTransMult[tutTransition] * (float)tutTransitionCount); long TextPos = (long)(TUT_TextTransMult[tutTransition] * (float)tutTransitionCount); rect.x0 = 0; rect.y0 = TUT_Title_Y - TitlePos - 7; rect.x1 = 640; rect.y1 = TUT_Title_Y - TitlePos + 22; primRectTranslucent2(&rect, colRGBA(0, 0, 0, 128)); rect.x0 = TUT_Main_X - TextPos - 12; rect.y0 = TUT_Main_Y - 6; rect.x1 = TUT_Main_X - TextPos + TUT_MainTextWidth + 4; rect.y1 = tutLastMainY; primRectTranslucent2(&rect, colRGBA(0, 0, 0, 128)); currentfont = fontMakeCurrent(tutTitleFont); // draw text fontPrintf(TUT_Title_X, TUT_Title_Y - TitlePos, TUT_TitleColor, "%s", strGetString(strTutorial00Title + (tutLesson * 7))); currentfont = fontMakeCurrent(tutMainFont); texty = DrawTextBlock(strGetString(strTutorial00Line01 + (tutLesson * 7)), TUT_Main_X - TextPos, TUT_Main_Y, TUT_MainTextWidth, TUT_MainTextHeight, TUT_MainColor); texty = DrawTextBlock(strGetString(strTutorial00Line02 + (tutLesson * 7)), TUT_Main_X - TextPos, texty, TUT_MainTextWidth, TUT_MainTextHeight, TUT_MainColor); texty = DrawTextBlock(strGetString(strTutorial00Line03 + (tutLesson * 7)), TUT_Main_X - TextPos, texty, TUT_MainTextWidth, TUT_MainTextHeight, TUT_MainColor); texty = DrawTextBlock(strGetString(strTutorial00Line04 + (tutLesson * 7)), TUT_Main_X - TextPos, texty, TUT_MainTextWidth, TUT_MainTextHeight, TUT_MainColor); tutLastMainY = DrawTextBlock(strGetString(strTutorial00Line05 + (tutLesson * 7)), TUT_Main_X - TextPos, texty, TUT_MainTextWidth, TUT_MainTextHeight, TUT_MainColor); fontMakeCurrent(currentfont); } else // special case for build ship lesson { currentfont = fontMakeCurrent(tutMainFont); texty = DrawTextBlock(strGetString(strTutorial17Line01 + tutVar.count), TUT_Build_X, TUT_Build_Y, TUT_BuildTextWidth, TUT_BuildTextHeight, TUT_BuildColor); fontMakeCurrent(currentfont); rect.x0 = TUT_Build_X - 8; // draw outline box around text rect.y0 = TUT_Build_Y - 6; rect.x1 = TUT_Build_X + TUT_BuildTextWidth + 8; rect.y1 = texty; primRectOutline2(&rect, 2, colRGB(tutPulseValue, tutPulseValue, tutPulseValue)); if(tutVar.count == 0) // point to appropriate place on screen tutDrawLinePulse(TUT_Build_X - 8, texty, 160, 100, tutPulseValue, 8); else if(tutVar.count == 1) tutDrawLinePulse(TUT_Build_X - 8, texty, 180, 410, tutPulseValue, 8); else if(tutVar.count == 2) tutDrawLinePulse(TUT_Build_X - 8, texty, 550, 410, tutPulseValue, 8); tutPulseValue -= 8; } if(!FirstWordNULL(strGetString(strTutorial00Tip + (tutLesson * 7)))) { long TipPos = (long)(TUT_TipTransMult[tutTransition] * (float)tutTransitionCount); long TextPos = (long)(TUT_TextTransMult[tutTransition] * (float)tutTransitionCount); if (!primModeEnabled) // draw translucent polys before tip text { primModeSet2(); modeset = TRUE; } rect.x0 = TUT_TipTitle_X - 8; rect.y0 = TUT_TipTitle_Y - TipPos - 6; rect.x1 = TUT_Tip_X - 8; rect.y1 = TUT_TipTitle_Y - TipPos + 18; primRectTranslucent2(&rect, colRGBA(0, 0, 0, 128)); rect.x0 = TUT_Tip_X + TextPos - 8; rect.y0 = TUT_Tip_Y - 6; rect.x1 = TUT_Tip_X + TextPos + TUT_TipTextWidth + 8; rect.y1 = tutLastTipY; primRectTranslucent2(&rect, colRGBA(0, 0, 0, 128)); if(modeset) primModeClear2(); currentfont = fontMakeCurrent(tutTipTitleFont); fontPrintf(TUT_TipTitle_X, TUT_TipTitle_Y - TipPos, TUT_TipTitleColor, "%s", strGetString(strTutorialTip)); currentfont = fontMakeCurrent(tutTipFont); tutLastTipY = DrawTextBlock(strGetString(strTutorial00Tip + (tutLesson * 7)), TUT_Tip_X + TextPos, TUT_Tip_Y, TUT_TipTextWidth, TUT_TipTextHeight, TUT_TipColor); } fontMakeCurrent(currentfont); }