lod *lodLevelGet(void *spaceObj, vector *camera, vector *ship) { real32 distance; SpaceObj *obj = (SpaceObj *)spaceObj; lodinfo *info = obj->staticinfo->staticheader.LOD; dbgAssert(info != NULL); //verify the LOD table exists vecSub(obj->cameraDistanceVector,*camera,*ship); obj->cameraDistanceSquared = distance = vecMagnitudeSquared(obj->cameraDistanceVector); #if LOD_SCALE_DEBUG if (lodDebugScaleFactor != 0.0f) { lodScaleFactor = lodDebugScaleFactor; } #endif if (distance > info->level[obj->currentLOD].bOff * lodScaleFactor) { //if drop a level of detail do { obj->currentLOD++; //go to lower level if (obj->currentLOD >= info->nLevels) { obj->currentLOD = info->nLevels-1; break; } } while (distance > info->level[obj->currentLOD].bOff * lodScaleFactor); } else { while (obj->currentLOD > 0 && distance < info->level[obj->currentLOD - 1].bOn * lodScaleFactor) { //if go higher level of detail obj->currentLOD--; //go to higher level } } dbgAssert(obj->currentLOD >= 0); dbgAssert(obj->currentLOD < info->nLevels); //verify we are within the available levels of detail #if LOD_PRINT_DISTANCE if (keyIsStuck(WKEY)) { keyClearSticky(WKEY); lodScaleFactor *= 0.99f; dbgMessagef("\nlodScaleFactor = %.3f", lodScaleFactor); } if (keyIsStuck(OKEY)) { keyClearSticky(OKEY); lodScaleFactor *= 1.01f; dbgMessagef("\nlodScaleFactor = %.3f", lodScaleFactor); } if (lodTuningMode) { obj->currentLOD = min(rndLOD, info->nLevels - 1); return(&info->level[min(rndLOD, info->nLevels - 1)]); } #endif return(&info->level[obj->currentLOD]); //return pointer to lod structure }
//load in a tiny sprite file static void lodSpriteFileRead(char *directory,char *field,void *dataToFillIn) { #if LOD_VERBOSE_LEVEL >= 1 dbgMessagef("\nlodSpriteFileRead: %s", field); #endif dbgFatal(DBG_Loc, "Can't load sprite images yet!"); }
/*----------------------------------------------------------------------------- Name : tmLeave Description : Callback function to close the trade manager Inputs : Outputs : Deletes all regions associated with trade manager Return : ----------------------------------------------------------------------------*/ void tmLeave(char *string, featom *atom) { //close the construction manager #if TM_VERBOSE_LEVEL >= 1 dbgMessagef("Close trade manager."); #endif feScreenDeleteFlags(tmBaseRegion,FE_DONT_DELETE_REGION_IF_SCREEN_NOT_FOUND); tmBaseRegion = NULL; if (tmIoSaveState) ioEnable(); // enable rendering of main game screen mrRenderMainScreen = TRUE; /* play the exit sound */ soundEvent(NULL, UI_ManagerExit); //restart the sound of space ambient soundEvent(NULL, UI_SoundOfSpace); spUnlockout(); bitClear(tbDisable,TBDISABLE_TRADEMGR_USE); tmReset(); tmTradeActive = FALSE; svClose(); }
void DefenseFighterDied(Ship *ship) { DefenseFighterSpec *spec = (DefenseFighterSpec *)ship->ShipSpecifics; Node *bulletnode; Node *tempnode; DefenseStruct *defensestruct; bulletnode = spec->DefenseList.head; dbgMessagef("DefenseFighter Died: Cleaning up."); while(bulletnode != NULL) { defensestruct = (DefenseStruct *)listGetStructOfNode(bulletnode); if(defensestruct->LaserDead != TRUE) { //listRemoveNode(&defensestruct->laser->bulletlink); //removefrom bullet list too? if (defensestruct->laser != NULL) { univRemoveObjFromRenderList((SpaceObj *) defensestruct->laser); defensestruct->laser->timelived = 10000.0f; bitSet(defensestruct->laser->flags,SOF_Hide); } //listDeleteNode(&defensestruct->laser->objlink); //dbgMessagef("Defense Dead: Deleting Laser from existance"); soundEventBurstStop(ship, &ship->gunInfo->guns[0]); } tempnode = bulletnode->next; listDeleteNode(bulletnode); //dbgMessagef("Defense Dead: Deleting defense node."); bulletnode = tempnode; } }
/*----------------------------------------------------------------------------- Name : madAnimationStop Description : Stop an animation from playing. Inputs : ship - ship to stop animating Outputs : Return : ----------------------------------------------------------------------------*/ void madAnimationStop(Ship *ship) { dbgAssertOrIgnore(ship->madBindings != NULL); ship->bindings = ship->madBindings->saveBindings; //restore the saved gun bindings, if any #if MAD_VERBOSE_LEVEL >= 2 dbgMessagef("madAnimationStop: stopped animation #%d('%s') on ship 0x%x", ship->madBindings->nCurrentAnim, ship->madBindings->header->anim[ship->madBindings->nCurrentAnim].name, ship); #endif ship->madBindings->nCurrentAnim = MAD_NoAnimation; }
/*----------------------------------------------------------------------------- Name : madAnimationStart Description : Start an animation playing for a given ship Inputs : ship - ship to play the animation for animNumber - index of the animation rate - rate of the animation 1.0 is normal animation speed. -1 plays animation in reverse. Outputs : sets time, rate and splinecurves up for an animation. Return : void ----------------------------------------------------------------------------*/ void madAnimationStart(Ship *ship, sdword animNumber) { madanim *anim = ship->madBindings; madheader *header = anim->header; shipbindings *bindings = &anim->bindings; sdword index, j, startPoint; splinecurve *curve; madanimation *animation; udword animBit = (1 << animNumber); //if the ship has gun bindings, swap the animation bindings with the gun bindings anim->saveBindings = ship->bindings; ship->bindings = bindings; dbgAssertOrIgnore(animNumber < header->nAnimations); anim->nCurrentAnim = animNumber; animation = &header->anim[animNumber]; anim->startTime = anim->time = animation->startTime; anim->timeElapsed = 0.0f; //start all the b-splines. They've already been set up, //we just need to initialize the time and current point. curve = anim->curves; for (index = 0; index < header->nObjects; index++) { if (!bitTest(header->objPath[index].animationBits, animBit)) { //if this object doesn't need to participate in the animation curve->currentPoint = BS_NoPoint; //set the curves to not update curve += 6; continue; } for (startPoint = 0; startPoint < curve->nPoints; startPoint++) { if (curve->times[startPoint] == anim->time) { goto foundTime; } } #if MAD_ERROR_CHECKING dbgFatalf(DBG_Loc, "madAnimationStart: Object #%d ('%s') has no keyframe at frame %.0f", index, header->objPath[index].name, anim->time / header->framesPerSecond); #endif foundTime: for (j = 0; j < 6; j++, curve++) { curve->timeElapsed = anim->time; curve->currentPoint = startPoint; } } #if MAD_VERBOSE_LEVEL >= 2 dbgMessagef("madAnimationStart: started animation #%d('%s') on ship 0x%x", animNumber, animation->name, ship); #endif }
void DefaultShipAttack(Ship *ship,SpaceObjRotImpTarg *target, real32 maxdist) { ShipStaticInfo *shipstaticinfo = (ShipStaticInfo *)ship->staticinfo; if (ship->gunInfo == NULL) { dbgMessagef("\nWARNING: %s tried to attack but has no guns",ShipTypeToStr(ship->shiptype)); return; } attackStraightForward(ship,target,shipstaticinfo->bulletRange[ship->tacticstype],shipstaticinfo->minBulletRange[ship->tacticstype]*0.9f); }
void tutBasicTutorial(char *name, featom *atom) { dbgAssert(startingGame == FALSE); tutorial = 1; tutLesson = -1; tutTransition = 1; tutTransitionCount = TUT_TransitionFramesOut - 1; dbgMessagef("\nBasic Tutorial started"); utySinglePlayerGameStart(name,atom); }
void tutAdvancedTutorial(char *name, featom *atom) { dbgAssert(startingGame == FALSE); tutorial = 2; tutLesson = TUT_BASIC_FINALE; tutTransition = 1; tutTransitionCount = TUT_TransitionFramesOut - 1; dbgMessagef("\nAdvanced Tutorial started"); utySinglePlayerGameStart(name,atom); }
/*----------------------------------------------------------------------------- Name : liImageDelete Description : Deletes a layered image and all data associated therewith. Inputs : image - layered image to delete Outputs : Frees all memory, including the image itself (which must therefore have been independently allocated). Return : void ----------------------------------------------------------------------------*/ void liImageDelete(layerimage *image) { sdword index, j; #if LI_VERBOSE_LEVEL >= 1 dbgMessagef("\nliImageDelete: deleting image 0x%x, filename '%s'", image, #if LI_RETAIN_NAME image->fileName); #else "<no name available>"); #endif //LI_RETAIN_NAME #endif //LI_VERBOSE_LEVEL for (index = 0; index < image->nLayers; index++) { //for each layer if (bitTest(image->layers[index].flags, LFF_Deleted)) { continue; } if (image->layers[index].flags & LFF_Channeled) { //if layer is channeled for (j = 0; j < image->layers[index].nChannels; j++) { //for each channel of each layer if (image->layers[index].channels[j].scanLength != NULL) { //if a RLE encoded channel memFree(image->layers[index].channels[j].scanLength);//free the channel image data } else { //else a RAW channel memFree(image->layers[index].channels[j].scanData);//free the channel image data } } if (image->layers[index].channels) { memFree(image->layers[index].channels); //free the channel list } } else { if (image->layers[index].decompressed) { //if decompressed, free decompressed buffer memFree(image->layers[index].decompressed); } } if (image->layers[index].name) { memFree(image->layers[index].name); //free the name } } #if LI_RETAIN_NAME memFree(image->fileName); //free image file name #endif memFree(image); //free the actual image }
sdword memNameSetFunction(memcookie *cookie, char *name) { memInitCheck(); memCookieVerify(cookie); strncpy(cookie->name, name, MEM_NameLength); cookie->name[MEM_NameLength - 1] = 0; #if MEM_VERBOSE_LEVEL >= 3 dbgMessagef("\nmemNameSet: Cookie at 0x%x named to '%s'", cookie, cookie->name); #endif return(OKAY); }
/*----------------------------------------------------------------------------- Name : liLayerDecompress Description : Decompress a layer Inputs : layer - pointer to layer to decompress Outputs : Allocates memory for decompressed layer and frees old compressed version. Newly decompressed layer will have the size of the layer bounds, not full image size. It will be referenced by layer->channels (cast to color *). Return : void ----------------------------------------------------------------------------*/ void liLayerDecompress(lilayer *layer) { color *newBuffer; sdword width = layer->bounds.x1 - layer->bounds.x0; sdword height = layer->bounds.y1 - layer->bounds.y0; sdword index, offset; #if LI_VERBOSE_LEVEL >= 2 dbgMessagef("\nliLayerDecompress: decompressing '%s' bounds (%d, %d), (%d, %d)", layer->name, layer->bounds.x0, layer->bounds.y0, layer->bounds.x1, layer->bounds.x1); #endif //LI_VERBOSE_LEVEL //create new buffer newBuffer = memAlloc(width * height * sizeof(color), "Decompressed layer", 0); memset(newBuffer, 0, width * height * sizeof(color)); //set buffer to fully transparent black dbgAssert(layer->channels); for (index = 0; index < layer->nChannels; index++) { //for all channels if (layer->channels[index].type == LCT_Invalid) { continue; } if (layer->channels[index].type == LCT_LayerMask) { //compute color-element offset offset = 3; } else { offset = (sdword)layer->channels[index].type; } if (layer->channels[index].compressed) { //if RLE channel liChannelDecompressRLE((ubyte *)newBuffer, layer->channels[index].scanLength, layer->channels[index].scanData,//decompress the channel layer->bounds.x1 - layer->bounds.x0, layer->bounds.y1 - layer->bounds.y0, offset); memFree(layer->channels[index].scanLength); //free channel image data } else { //else it's a raw channel liChannelDecompressRaw((ubyte *)newBuffer, //decompress the channel layer->channels[index].scanData, layer->bounds.x1 - layer->bounds.x0, layer->bounds.y1 - layer->bounds.y0, offset); memFree(layer->channels[index].scanData); //free channel image data } } memFree(layer->channels); //free the channel list bitClear(layer->flags, LFF_Channeled); //set state to non-channeled layer->decompressed = newBuffer; //store newly decompressed layer }
// FIXME void CirclePoints(int x, int y, color c, int cx, int cy) { glColor3ub(colRed(c), colGreen(c), colBlue(c)); glPointSize(4.0f); glBegin(GL_POINTS); dbgMessagef("\nCirclePoints %d %d %d %d", x, y, cx, cy); glVertex2i(x + cx, y + cy); glVertex2i(y + cx, x + cy); glVertex2i(y + cx, -x + cy); glVertex2i(x + cx, -y + cy); glVertex2i(-x + cx, -y + cy); glVertex2i(-y + cx, x + cy); glVertex2i(-x + cx, y + cy); glEnd(); glPointSize(1.0f); }
/*----------------------------------------------------------------------------- Name : liLayerDelete Description : Delete all data for a given layer Inputs : layer - layer to delete Outputs : frees all memory associated with layer and sets pointers to NULL. Return : ----------------------------------------------------------------------------*/ void liLayerDelete(lilayer *layer) { sdword index; #if LI_VERBOSE_LEVEL >= 2 dbgMessagef("\nliLayerDelete: deleting '%s' bounds (%d, %d), (%d, %d)", layer->name, layer->bounds.x0, layer->bounds.y0, layer->bounds.x1, layer->bounds.x1); #endif //LI_VERBOSE_LEVEL if (layer->flags & LFF_Channeled) { //if layer is channeled if (layer->channels) { for (index = 0; index < layer->nChannels; index++) { //for each channel of each layer if (layer->channels[index].type == LCT_Invalid) { continue; } if (layer->channels[index].scanLength != NULL) { memFree(layer->channels[index].scanLength);//free the channel image data layer->channels[index].scanLength = NULL; } else { memFree(layer->channels[index].scanData); layer->channels[index].scanData = NULL; } } memFree(layer->channels); //free the channel list layer->channels = NULL; } } else { if (layer->decompressed) { //if decompressed, free decompressed buffer memFree(layer->decompressed); layer->decompressed = NULL; } layer->channels = NULL; } if (layer->name) { memFree(layer->name); //free the name } bitSet(layer->flags, LFF_Deleted); }
void HeavyCorvetteHouseKeep(Ship *ship) { HeavyCorvetteSpec *spec = (HeavyCorvetteSpec *)ship->ShipSpecifics; if(spec->cooldown == TRUE) { spec->burstChargeState2-=universe.phystimeelapsed; #if DEBUG_HEAVY_CORVETTE dbgMessagef("Cooling Down..."); #endif if(spec->burstChargeState2 <= 0.0f) { spec->burstChargeState = 0.0f; spec->cooldown = FALSE; } } }
void aivarShutdown(void) { if (vars != NULL) { sdword i; for (i=0;i<varsUsed;i++) { dbgMessagef("\nWarning Var %s not closed",vars[i]->label); memFree(vars[i]); } memFree(vars); vars = NULL; } varsAllocated = 0; varsUsed = 0; aivRenderMainScreen = NULL; }
//This one not a perfect copy, but pretty close void liBlendColor(color *buffer, color *layer, real32 opacity, sdword nPixels) { real32 redSource, greenSource, blueSource, alpha; real32 redDest, greenDest, blueDest;//, alphaDest; real32 oneMinusAlpha; real32 hueS, satS, hueD, satD, lumS, lumD; real32 clumD, clumS; real32 redTemp, greenTemp, blueTemp; #if LI_VERBOSE_LEVEL >= 2 dbgMessagef("\nColor: Blending mode not implemented perfectly."); #endif while (nPixels > 0) { alpha = colUbyteToReal(colAlpha(*layer)) * opacity; oneMinusAlpha = 1.0f - alpha; redSource = colUbyteToReal(colRed(*layer)); //read pixel to floating point greenSource = colUbyteToReal(colGreen(*layer)); blueSource = colUbyteToReal(colBlue(*layer)); redDest = colUbyteToReal(colRed(*buffer)); greenDest = colUbyteToReal(colGreen(*buffer)); blueDest = colUbyteToReal(colBlue(*buffer)); clumS = (redSource * LI_RedGamma + greenSource * LI_GreenGamma + blueSource * LI_BlueGamma) / LI_TotalGamma; clumD = (redDest * LI_RedGamma + greenDest * LI_GreenGamma + blueDest * LI_BlueGamma) / LI_TotalGamma; colRGBToHLS(&hueS, &lumS, &satS, redSource, greenSource, blueSource); colRGBToHLS(&hueD, &lumD, &satD, redDest, greenDest, blueDest); colHLSToRGB(&redTemp, &greenTemp, &blueTemp, hueS, clumD, satS); redDest = redTemp * alpha + redDest * oneMinusAlpha; greenDest = greenTemp * alpha + greenDest * oneMinusAlpha; blueDest = blueTemp * alpha + blueDest * oneMinusAlpha; redDest = min(redDest, 1.0f); greenDest = min(greenDest, 1.0f); blueDest = min(blueDest, 1.0f); *buffer = colRGB(colRealToUbyte(redDest), colRealToUbyte(greenDest), colRealToUbyte(blueDest)); buffer++; layer++; nPixels--; } }
/*----------------------------------------------------------------------------- Name : frShutdown Description : Shuts down the font registry module Inputs : Outputs : Frees all fonts in the registry Return : ----------------------------------------------------------------------------*/ void frShutdown(void) { sdword index; for (index = FR_NumberFonts - 1; index >= 1; index--) { //for all of the registry if (frFontRegistry[index].name != NULL) { //if non-NULL name, it has been registered #if FR_VERBOSE_LEVEL >= 2 dbgMessagef("frShutdown: Deleting font %s with a usage count of %d", frFontRegistry[index].name, frFontRegistry[index].nUsageCount); #endif memFree(frFontRegistry[index].name); //free previously allocated name frFontRegistry[index].name = NULL; //no longer registered fontDiscard(frFontRegistry[index].handle); //free the font frFontRegistry[index].handle = 0; //no longer registered } frFontRegistry[index].name = NULL; //nothing registered in this slot } }
/*----------------------------------------------------------------------------- Name : taskStartName Description : Start a specific task Inputs : function - entry point of task name - a string describing the task for debugging period - period between consecutive calls stacksize - size of task's local stack flags - control execution of task Outputs : taskdata structure allocated and initialized Return : handle to task for later manipulation of task Note : if a taskdata structure or stack RAM cannot be allocated, the function will generate a fatal error. name must be caller-allocated and outlive the task. This is usually invoked with the taskStart macro. The task is executed once immediately and must yield rather than exit at this first call. ----------------------------------------------------------------------------*/ taskhandle taskStartName(taskfunction function, char *name, real32 period, udword flags) { static taskhandle handle = ERROR; taskdata *newTask; taskInitCheck(); dbgAssertOrIgnore(function != NULL); dbgAssertOrIgnore(period > 0.0f); newTask = memAlloc(sizeof(taskdata), "taskData", NonVolatile); handle = taskPointerAlloc(); taskData[handle] = newTask; #if TASK_VERBOSE_LEVEL >= 2 dbgMessagef("%s: starting task at 0x%x at %d Hz, flags 0x%x using handle %d at 0x%x", __FUNCTION__, function, 1.0f/period, flags, handle, taskData[handle]); #endif //make task in use and running newTask->flags = flags | TF_Allocated; newTask->function = function; newTask->context = NULL; newTask->name = name; newTask->ticks = 0; //no residual ticks dbgAssertOrIgnore(period * taskFrequency < (real32)SDWORD_Max); newTask->ticksPerCall = (udword)(period * taskFrequency); function(&newTask->context); if (newTask->context == NULL) { // Exited already? #if TASK_ERROR_CHECKING dbgFatalf(DBG_Loc, "taskStart: stillborn task %s", name); #endif taskStop(handle); return ERROR; } return handle; }
//this function charges the ship for burst fire. Specialized for //heavy corvette. // //Function also creates effect for charging bool doBurstCharging(Ship *ship) { HeavyCorvetteSpec *spec = (HeavyCorvetteSpec *)ship->ShipSpecifics; if(spec->chargeEffect == NULL) { //start charging effect if not playing allready } if(spec->burstChargeState < burstChargeTime) { spec->burstChargeState += universe.phystimeelapsed; return(FALSE); } #if DEBUG_HEAVY_CORVETTE dbgMessagef("Burst Fire Charged!"); #endif return(TRUE); }
/*----------------------------------------------------------------------------- Name : memInit Description : Starts the memory allocation module. Call before any other functions. Inputs : heapStart - start of heap to use. Should be aligned on at lease 4-bit boundary. heapSize - size of heap to create Outputs : Global heap set up and (optionally) cleared. Return : OKAY if success. ----------------------------------------------------------------------------*/ sdword memInit(void *heapStart, sdword heapSize) { #if MEM_ERROR_CHECKING if (memModuleInit == TRUE) dbgFatal(DBG_Loc, "Memory module started more than once."); #endif //MEM_ERROR_CHECKING dbgAssert(heapStart != NULL && heapSize > MEM_BlockSize * 20); #if MEM_VERBOSE_LEVEL >= 1 dbgMessagef("\nMemory module init. Heap = 0x%x, Length = %d", heapStart, heapSize); #endif //MEM_VERBOSE_LEVEL >= 1 memPool = (ubyte *)(((udword)((ubyte *)heapStart + sizeof(memcookie) - 1)) & (~(sizeof(memcookie) - 1))); memPoolLength = heapSize; memModuleInit = TRUE; return(memReset()); }
void aivarShutdown(void) { if (vars != NULL) { sdword i; for (i=0;i<varsUsed;i++) { #if AI_VERBOSE_LOGGING dbgMessagef("WARNING: vars[%d] %s not closed", i, vars[i]->label); #endif memFree(vars[i]); } memFree(vars); vars = NULL; } varsAllocated = 0; varsUsed = 0; aivRenderMainScreen = NULL; }
/*----------------------------------------------------------------------------- Name : tmAcceptOffer Description : Callback function to accept the offered technologies Inputs : Outputs : Get the technologies Return : ----------------------------------------------------------------------------*/ void tmAcceptOffer(char *string, featom *atom) { udword price; if (tmTechSelected == -1) return; price = (tmTechPrice[tmTechSelected] * tmPriceScale) / 100; #if TM_VERBOSE_LEVEL >= 1 dbgMessagef("Received the technologies..."); #endif //if the player can't afford the technology selected, bugger out. if (price > universe.curPlayerPtr->resourceUnits) { tmDialogPhrase = DialogCantAffordThat; tmDirtyTechInfo(); return; } universe.curPlayerPtr->resourceUnits -= price; tmTechForSale[tmTechSelected] = TM_TECH_IS_ALREADY_OWNED; //rmAddTechToPlayer(universe.curPlayerPtr, tmTechSelected); universe.curPlayerPtr->researchinfo.HasTechnology |= TechToBit(tmTechSelected); tmtechinfo = -1; tmTechSelected = -1; if (tmStuffToBuy) { tmDialogPhrase = DialogPurchaseMade; //"want some more?" } else { tmDialogPhrase = DialogCantAffordAnything; //"bye!" } tmDirtyTechInfo(); }
sdword tmSelectAvailable(regionhandle region, sdword ID, udword event, udword data) { sdword index; sdword price; if (multiPlayerGame) { if (!multiPlayerGameUnderWay) { return (0); } } index = tmSelectTechType(region, mouseCursorY()); dbgMessagef("Selected %i",index); price = (tmTechPrice[index] * tmPriceScale) / 100; if ( (event == RPE_PressLeft) && (index!=-1) ) { //left press (select/add job) if (universe.curPlayerPtr->resourceUnits >= price) { tmTechSelected = index; tmtechinfo = index; tmDialogPhrase = DialogFirstClick; } else { tmDialogPhrase = DialogCantAffordThat; } } else if ( (event == RPE_PressRight) && (index!=-1) ) { tmtechinfo = index; } tmDirtyTechInfo(); return(0); }
void hrChatTextEntry(char *name, featom *atom) { char *string; ChatPacket temp; sdword width; fonthandle fhsave; char testwidth[MAX_CHATSTRING_LENGTH+40]; if (FEFIRSTCALL(atom)) { // initialize button here ChatTextEntryBox = (textentryhandle)atom->pData; uicTextEntryInit(ChatTextEntryBox,UICTE_NoLossOfFocus|UICTE_ChatTextEntry); uicTextBufferResize(ChatTextEntryBox,MAX_CHATSTRING_LENGTH-2); return; } switch (uicTextEntryMessage(atom)) { case CM_AcceptText : string = ((textentryhandle)atom->pData)->textBuffer; sendChatMessage(ALL_PLAYER_MASK^PLAYER_MASK(sigsPlayerIndex),string,(uword)sigsPlayerIndex); dbgMessagef("text entry: %s",string); strcpy(temp.message,string); temp.packetheader.frame = (uword)sigsPlayerIndex; hrProcessPacket((struct ChatPacket *)&temp); uicTextEntrySet(ChatTextEntryBox,"",0); break; case CM_KeyPressed : fhsave = fontMakeCurrent(((textentryhandle)atom->pData)->currentFont); //select the appropriate font sprintf(testwidth, "%s > %s", playerNames[sigsPlayerIndex], ((textentryhandle)atom->pData)->textBuffer); width = fontWidth(testwidth); fontMakeCurrent(fhsave); if (width > (atom->width-30)) { uicBackspaceCharacter((textentryhandle)atom->pData); } break; } }
/*----------------------------------------------------------------------------- Name : liLayerBlendTo Description : Blend a given layer to the destination buffer. Inputs : destBuffer - destination buffer, dimensions given by image->width,height. image - image we are blending layerIndex - index of layer to blend. Must already be decompressed. Outputs : dest modified to reflect new blending. Return : ----------------------------------------------------------------------------*/ void liLayerBlendTo(color *destBuffer, sdword layerIndex, layerimage *image) { lilayer *layer = &image->layers[layerIndex]; color *source, *dest; sdword width, height, sourceStride; #if LI_VERBOSE_LEVEL >= 2 dbgMessagef("\nliLayerBlendTo: blending layer %d ('%s')", layerIndex, layer->name); #endif //LI_VERBOSE_LEVEL dbgAssert(layer->decompressed != NULL && ((layer->flags & LFF_Channeled) == 0)); dbgAssert(liBlender[layer->blendMode]); source = layer->decompressed; //first layer pixel dest = destBuffer + image->width * layer->bounds.y0 + layer->bounds.x0; //first dest pixel liClipLayer(layer, image, &source, &dest, &width, &height, &sourceStride); for (; height > 0; height--) { //for each scanline in our range liBlender[layer->blendMode](dest, source, layer->opacity, width); dest += image->width; source += sourceStride; } }
/*----------------------------------------------------------------------------- Name : taskStop Description : Destroy the specified task (stop and deallocate) Inputs : handle - handle of task returned from taskStart() Outputs : .. Return : void ----------------------------------------------------------------------------*/ void taskStop(taskhandle handle) { taskInitCheck(); dbgAssertOrIgnore(handle >= 0); dbgAssertOrIgnore(handle < taskMaxTask); dbgAssertOrIgnore(taskData[handle] != NULL); #if TASK_VERBOSE_LEVEL >= 2 dbgMessagef("%s: destroying task %d", __FUNCTION__, handle); #endif if (taskData[handle]->context != NULL) { free(taskData[handle]->context); } memFree(taskData[handle]); taskData[handle] = NULL; if (handle == taskMaxTask - 1) { taskMaxTask--; } }
/*----------------------------------------------------------------------------- Name : taskStartup Description : Initialize the task module. Inputs : frequency - frequency, in Hz of the timer to be used. Outputs : All taskData structures cleared Return : OKAY on success, ERROR if failure ----------------------------------------------------------------------------*/ sdword taskStartup(udword frequency) { sdword index; #if TASK_VERBOSE_LEVEL >= 1 dbgMessagef("%s: Task module started using a frequency of %dHz", __FUNCTION__, frequency); #endif dbgAssertOrIgnore(taskModuleInit == FALSE); for (index = 0; index < TSK_NumberTasks; index++) { taskData[index] = NULL; } taskMaxTask = 0; //no tasks taskFrequency = (real32)frequency; //save the frequency taskModuleInit = TRUE; //and say module init //call the task handler dispatcher once so that it will set return pointers OK taskExecuteAllPending(0); #if TASK_TEST //test this crazy module { taskhandle handle; handle = taskStart(taskTestFunction, 1, TF_OncePerFrame); taskRename(handle, "Task this you commie bastards!"); taskExecuteAllPending(1); taskExecuteAllPending(1); taskExecuteAllPending(1); taskExecuteAllPending(1); taskExecuteAllPending(1); taskExecuteAllPending(1); } #endif //TASK_TEST return(OKAY); }
/*----------------------------------------------------------------------------- Name : memDefragment Description : Defragments the heap by combining adjacent free blocks. Inputs : void Outputs : Adjacent free blocks combined. Resets value of memFreeFirst Return : OKAY ----------------------------------------------------------------------------*/ sdword memDefragment(void) { memcookie *thisCookie, *nextCookie; thisCookie = memFirst; //start walk from very start of heap while (thisCookie < memLast) //scan for free cookies in heap { memCookieVerify(thisCookie); //verify this cookie nextCookie = (memcookie *)((ubyte *)thisCookie + //next cookie sizeof(memcookie) + memBlocksToBytes(thisCookie->blocksNext)); if (nextCookie >= memLast) //if cookie pointed past end of heap { goto noMoreFree; //no more free structures } while ((!bitTest(thisCookie->flags, MBF_AllocatedNext)) && (!bitTest(nextCookie->flags, MBF_AllocatedNext)))//while these 2 blocks are both free { #if MEM_VERBOSE_LEVEL >= 3 dbgMessagef("\nmemDefragment: combined blocks 0x%x(%d) and 0x%x(%d) into one.", thisCookie, memBlocksToBytes(thisCookie->blocksNext), nextCookie, memBlocksToBytes(nextCookie->blocksNext)); #endif thisCookie->blocksNext += nextCookie->blocksNext + MEM_BlocksPerCookie; nextCookie = (memcookie *)((ubyte *)thisCookie +//next cookie sizeof(memcookie) + memBlocksToBytes(thisCookie->blocksNext)); if (nextCookie >= memLast) //if cookie pointed past end of heap { goto noMoreFree; //no more free structures } memCookieVerify(nextCookie); //verify next cookie } thisCookie = nextCookie; //next update } noMoreFree:; return(OKAY); }
void MineLayerAttackRun(Ship *ship,SpaceObjRotImpTarg *target,AttackSideStep *attacksidestep,AttackSideStepParameters *parameters) { vector trajectory; //real32 dist; real32 range; //real32 temp; // bool didshoot; ShipStaticInfo *shipstaticinfo = (ShipStaticInfo *)ship->staticinfo; Gun *gun; udword numGuns,target_class; GunInfo *guninfo = ship->gunInfo; //vector tmpvec; //real32 randegf; //sdword randeg; //matrix tmpmat; //vector targetheading; MinelayerCorvetteSpec *spec = (MinelayerCorvetteSpec *)ship->ShipSpecifics; MinelayerCorvetteStatics *minelayercorvettestatics; minelayercorvettestatics = (MinelayerCorvetteStatics *) ((ShipStaticInfo *)(ship->staticinfo))->custstatinfo; numGuns = guninfo->numGuns; gun = &guninfo->guns[0]; if(target != NULL) { if(target->objtype == OBJ_ShipType) target_class = ((Ship *)target)->staticinfo->shipclass; else target_class = CLASS_NonCombat; } switch (ship->aistateattack) { case ATTACK_INIT: case APPROACH: #ifdef DEBUG_ATTACK dbgMessagef("\nShip %x MINELAYER_ATTACK_APPROACH",(udword)ship); #endif aishipGetTrajectory(ship,target,&trajectory); aishipFlyToShipAvoidingObjs(ship,target,AISHIP_PointInDirectionFlying,0.0f); range = RangeToTarget(ship,target,&trajectory); //lets check if we want to force drop... if(target->objtype == OBJ_ShipType) { if(((Ship *)target)->shiptype == Mothership) { //its a mothership vector tempvec; real32 tempreal; vecSub(tempvec,target->collInfo.collPosition,ship->collInfo.collPosition); tempreal = vecMagnitudeSquared(tempvec); if(tempreal < mothershipDistSqr) { //we're within range of force dropping! ship->aistateattack = DROP_MOTHERSHIP; } break; } } if (range < minelayercorvettestatics->breakInAwayDist) { ship->aistateattack = BREAKPOSITION; spec->aivec.x = 0.0f; spec->aivec.y = 0.0f; spec->aivec.z = 0.0f; } break; case DROP_MOTHERSHIP: { vector tempvec; real32 tempreal; vecSub(tempvec,ship->collInfo.collPosition,target->collInfo.collPosition); tempreal = vecMagnitudeSquared(tempvec); vecNormalize(&tempvec); if(tempreal > mothershipDistSqr2) { ship->aistateattack = ATTACK_INIT; } if(aitrackHeadingWithFlags(ship,&tempvec,0.97f,AITRACKHEADING_IGNOREUPVEC)) { if(MinelayerCorvetteStaticMineDrop(ship,target)) //problem...there will be other targets...bah..lets see.. { MinelayerCorvetteOrderChangedCleanUp(ship); } } break; } case BREAKPOSITION: #ifdef DEBUG_ATTACK dbgMessagef("\nShip %x BREAKPOSITION",(udword)ship); #endif aishipGetTrajectory(ship,target,&trajectory); range = RangeToTarget(ship,target,&trajectory); vecNormalize(&trajectory); SetAIVecHeading(ship,target,&trajectory); ship->aistateattack = BREAK1; case BREAK1: #ifdef DEBUG_ATTACK dbgMessagef("\nShip %x BREAK1",(udword)ship); #endif aishipGetTrajectory(ship,target,&trajectory); range = RangeToTarget(ship,target,&trajectory); //aishipFlyToPointAvoidingObjs(ship,&spec->aivec,AISHIP_FastAsPossible | AISHIP_PointInDirectionFlying,INTERCEPTORBREAK_MINVELOCITY); aishipFlyToPointAvoidingObjs(ship,&target->posinfo.position,AISHIP_FastAsPossible | AISHIP_PointInDirectionFlying,INTERCEPTORBREAK_MINVELOCITY); if(range < minelayercorvettestatics->DropRange) { //temp vecNormalize(&trajectory); SetAIVecHeading(ship,target,&trajectory); //temp ship->aistateattack = KILL; //within mining range so start dropping spec->aispheretime=0.0f; //reset time; } break; case KILL: #ifdef DEBUG_ATTACK dbgMessagef("\nShip %x KILL",(udword)ship); #endif aishipGetTrajectory(ship,target,&trajectory); range = RangeToTarget(ship,target,&trajectory); spec->aispheretime += universe.phystimeelapsed; if(gunCanShoot(ship, gun)) { if(gun->numMissiles > 0) { spec->mineaistate = MINE_DROP_ATTACK; MinelayerCorvetteFire(ship,target); } } if(range > minelayercorvettestatics->DropStopRange) { //out of range.... ship->aistateattack = BREAK2; } if(spec->aispheretime > minelayercorvettestatics->Break2SphereizeFreq) { //time to sphereize; spec->aivec.x =0.0f; spec->aivec.y =0.0f; spec->aivec.z =0.0f; spec->aispheretime = -1000000.0f; // Reset, and never do again till next attack pass... vecNormalize(&trajectory); SetAIVecHeading(ship,target,&trajectory); #ifdef DEBUG_ATTACK dbgMessagef("\nShip %x KILL: Adjust for Break2 Sphereizing Godliness Maneuver :)",(udword)ship); #endif } aishipFlyToPointAvoidingObjs(ship,&spec->aivec,AISHIP_FastAsPossible | AISHIP_PointInDirectionFlying,INTERCEPTORBREAK_MINVELOCITY); break; case BREAK2: #ifdef DEBUG_ATTACK dbgMessagef("\nShip %x BREAK2",(udword)ship); #endif aishipGetTrajectory(ship,target,&trajectory); range = RangeToTarget(ship,target,&trajectory); aishipFlyToPointAvoidingObjs(ship,&spec->aivec,AISHIP_FastAsPossible | AISHIP_PointInDirectionFlying,INTERCEPTORBREAK_MINVELOCITY); if(range > minelayercorvettestatics->FlyAwayDist[target_class] || (MoveReachedDestinationVariable(ship,&spec->aivec,minelayercorvettestatics->FlyAwayTolerance))) { //turn around and start over ship->aistateattack = APPROACH; } break; default: dbgAssert(FALSE); break; } }