/*@Function============================================================ @Desc: BounceInfluencer: prueft Kollisionen mit Tueren und Mauer mit DruidPassable() und wirft Influencer entsprechend zurueck NEW: This functions HAS to take into account the current framerate! @Ret: void @Int: * $Function----------------------------------------------------------*/ void BounceInfluencer (void) { int sign; float SX = Me.speed.x * Frame_Time (); float SY = Me.speed.y * Frame_Time (); finepoint lastpos; int res; /* Ergebnis aus DruidPassable() */ int NumberOfShifts=0; int safty_sx = 0, safty_sy = 0; /* wegstoss - Geschwindigkeiten (falls noetig) */ int crashx = FALSE, crashy = FALSE; /* Merker wo kollidiert wurde */ lastpos.x = Me.pos.x - SX; lastpos.y = Me.pos.y - SY; res = DruidPassable (Me.pos.x, Me.pos.y); switch (res) { case -1: /* Influence ist blockiert: zurueckwerfen */ /* Festellen, in welcher Richtung die Mauer lag, und den Influencer entsprechend stoppen */ if (SX && (DruidPassable (lastpos.x + SX, lastpos.y) != CENTER)) { crashx = TRUE; /* In X wurde gecrasht */ sign = (SX < 0) ? -1 : 1; SX = abs (SX); NumberOfShifts=0; while (--SX && (DruidPassable (lastpos.x + sign * SX, lastpos.y) != CENTER) && (NumberOfShifts++ < 4)); Me.pos.x = lastpos.x + SX * sign; Me.speed.x = 0; /* falls Influencer weggestossen werden muss ! */ safty_sx = (-1) * sign * PUSHSPEED; } if (SY && (DruidPassable (lastpos.x, lastpos.y + SY) != CENTER)) { crashy = TRUE; /* in Y wurde gecrasht */ sign = (SY < 0) ? -1 : 1; SY = abs (SY); NumberOfShifts=0; while (--SY && (DruidPassable (lastpos.x, lastpos.y + sign * SY) != CENTER) && (NumberOfShifts++ < 4)); Me.pos.y = lastpos.y + SY * sign; Me.speed.y = 0; /* Falls Influencer weggestossen werden muss */ safty_sy = (-1) * sign * PUSHSPEED; } /* Hat das nichts geholfen, noch etwas wegschubsen */ if (DruidPassable (Me.pos.x, Me.pos.y) != CENTER) { if (crashx) { Me.speed.x = safty_sx; Me.pos.x += Me.speed.x * Frame_Time() ; } if (crashy) { Me.speed.y = safty_sy; Me.pos.y += Me.speed.y * Frame_Time() ; } } break; /* Von Tuerrand wegschubsen */ case OBEN: Me.speed.y = -PUSHSPEED; Me.pos.y += Me.speed.y * Frame_Time() ; break; case UNTEN: Me.speed.y = PUSHSPEED; Me.pos.y += Me.speed.y * Frame_Time() ; break; case RECHTS: Me.speed.x = PUSHSPEED; Me.pos.x += Me.speed.x * Frame_Time() ; break; case LINKS: Me.speed.x = -PUSHSPEED; Me.pos.x += Me.speed.x * Frame_Time() ; break; /* Not blocked at all ! */ case CENTER: break; default: DebugPrintf ("Illegal return value from DruidPassable() "); Terminate (-1); break; } /* switch */ } /* BounceInfluencer */
//======================================================= // FUNCTION: Collision // PURPOSE: Handle the collisions //======================================================= void Collision(MobileNode *node, WGN_802_11_Mac_Frame *frame) { WGNflag flag; switch(GetRxStatus(node)) { case MAC_RECV: SetRxStatus(node, MAC_COLL); // NOTE: NO BREAK here!!! case MAC_COLL: // Update the RXTimeout time if(SecToNsec(Frame_Time(node, frame)) > RXTimer_Remain(node)) { RXTimer_Stop(node); flag = EventDestroy(node->Id, RXTimeOut); if (flag == FALSE) { printf("[Collision]:: Error, Can not find the entry which will be destroyed!\n"); exit(1); } switch(GetFcSubtype(node->nodeMac->pktRx)) { case MAC_SUBTYPE_RTS: node->nodeStats->RtsDropForCollision += 1; break; case MAC_SUBTYPE_CTS: node->nodeStats->CtsDropForCollision += 1; break; case MAC_SUBTYPE_ACK: node->nodeStats->AckDropForCollision += 1; break; case MAC_SUBTYPE_DATA: node->nodeStats->DataDropForCollision += 1; break; default: printf("[Collision]:: Error, Invalid subtype!\n"); exit(1); } Dot11FrameFree(node->nodeMac->pktRx); node->nodeMac->pktRx = NULL; node->nodeMac->pktRx = frame; frame = NULL; RXTimer_Start(node, SecToNsec(RX_Time(node))); //here we need not mark the frame with collision error, it will be drop after //reception for the MAC rx state of MAC_COLL } else { switch(GetFcSubtype(frame)) { case MAC_SUBTYPE_RTS: node->nodeStats->RtsDropForCollision += 1; break; case MAC_SUBTYPE_CTS: node->nodeStats->CtsDropForCollision += 1; break; case MAC_SUBTYPE_ACK: node->nodeStats->AckDropForCollision += 1; break; case MAC_SUBTYPE_DATA: node->nodeStats->DataDropForCollision += 1; break; default: printf("[Collision]:: Error, Invalid frame subtype!\n"); exit(1); } Dot11FrameFree(frame); } break; default: printf("[Collision]:: Error, unpredictable rx status comes out!\n"); } }
void Assemble_Combat_Picture (int mask) { int MapBrick; int line, col; int i; static float TimeSinceLastFPSUpdate=10; static int FPS_Displayed=1; SDL_Rect TargetRectangle; SDL_Rect TxtRect; finepoint pos, vect; float len; bool vis = TRUE; grob_point upleft, downright; #define UPDATE_FPS_HOW_OFTEN 0.75 DebugPrintf (2, "\nvoid Assemble_Combat_Picture(...): Real function call confirmed."); SDL_SetClipRect (ne_screen , &User_Rect); if ( !GameConfig.AllMapVisible ) Fill_Rect (User_Rect, Black); if ( (mask & SHOW_FULL_MAP) != 0 ) { upleft.x = -5; upleft.y = -5; downright.x = CurLevel->xlen + 5; downright.y = CurLevel->ylen + 5; } else { upleft.x = Me.pos.x - 6; upleft.y = Me.pos.y - 5; downright.x = Me.pos.x + 7; downright.y = Me.pos.y + 5; } for (line = (int)upleft.y; line < (int)downright.y; line++) { for (col = (int)upleft.x; col < (int)downright.x; col++) { vis = TRUE; if ( !GameConfig.AllMapVisible && ( (mask & SHOW_FULL_MAP) == 0x0) ) { pos.x = col; pos.y = line; vect.x = Me.pos.x - pos.x; vect.y = Me.pos.y - pos.y; len = sqrt( vect.x * vect.x + vect.y * vect.y) + 0.01; vect.x /= len; vect.y /= len; if (len > 0.5) { pos.x += vect.x; pos.y += vect.y; } if ( !IsVisible (&pos) ) continue; } MapBrick = GetMapBrick( CurLevel, col , line ); TargetRectangle.x = UserCenter_x + (int)rint( (-Me.pos.x+1.0*col-0.5 )*Block_Rect.w); TargetRectangle.y = UserCenter_y + (int)rint( (-Me.pos.y+1.0*line-0.5 )*Block_Rect.h); SDL_BlitSurface( MapBlockSurfacePointer[CurLevel->color][MapBrick], NULL, ne_screen, &TargetRectangle); } // for(col) } // for(line) // if we don't use Fullscreen mode, we have to clear the text-background manually // for the info-line text: TxtRect.x = Full_User_Rect.x; TxtRect.y = Full_User_Rect.y+Full_User_Rect.h - FontHeight (Font0_BFont); TxtRect.h = FontHeight (Font0_BFont); TxtRect.w = Full_User_Rect.w; SDL_SetClipRect (ne_screen, &TxtRect); if (!GameConfig.FullUserRect) SDL_FillRect(ne_screen, &TxtRect, 0); if ( GameConfig.Draw_Position ) { PrintStringFont( ne_screen , Font0_BFont , Full_User_Rect.x+Full_User_Rect.w/6 , Full_User_Rect.y+Full_User_Rect.h - FontHeight( Font0_BFont ), "GPS: X=%d Y=%d Lev=%d" , (int) rintf(Me.pos.x) , (int) rintf(Me.pos.y) , CurLevel->levelnum ); } if (!(mask & ONLY_SHOW_MAP) ) { if ( GameConfig.Draw_Framerate ) { TimeSinceLastFPSUpdate += Frame_Time(); if ( TimeSinceLastFPSUpdate > UPDATE_FPS_HOW_OFTEN ) { FPS_Displayed=(int)(1.0/Frame_Time()); TimeSinceLastFPSUpdate=0; } PrintStringFont( ne_screen , Font0_BFont , Full_User_Rect.x , Full_User_Rect.y+Full_User_Rect.h - FontHeight( Font0_BFont ), "FPS: %d " , FPS_Displayed ); } if ( GameConfig.Draw_Energy ) { PrintStringFont( ne_screen , Font0_BFont , Full_User_Rect.x+Full_User_Rect.w/2 , Full_User_Rect.y+Full_User_Rect.h - FontHeight( Font0_BFont ), "Energy: %d" , (int)Me.energy); } if (GameConfig.Draw_DeathCount) { PrintStringFont( ne_screen , Font0_BFont , Full_User_Rect.x+2*Full_User_Rect.w/3 , Full_User_Rect.y+Full_User_Rect.h - FontHeight( Font0_BFont ), "Deathcount: %d", (int)DeathCount ); } SDL_SetClipRect (ne_screen, &User_Rect); // make sure Ashes are displayed _before_ droids, so that they are _under_ them! for (i = 0; i < NumEnemys ; i++) if ( (AllEnemys[i].status == TERMINATED) && (AllEnemys[i].levelnum == CurLevel->levelnum) ) { if (IsVisible (&(AllEnemys[i].pos) ) ) PutAshes (AllEnemys[i].pos.x, AllEnemys[i].pos.y); } for (i = 0; i < NumEnemys ; i++) if ( (AllEnemys[i].levelnum != CurLevel->levelnum) || (AllEnemys[i].status == OUT) || (AllEnemys[i].status == TERMINATED) ) continue; else PutEnemy (i , -1 , -1 ); if (Me.energy > 0) PutInfluence ( -1 , -1 ); for (i = 0; i < (MAXBULLETS); i++) if (AllBullets[i].type != OUT) PutBullet (i); for (i = 0; i < (MAXBLASTS); i++) if (AllBlasts[i].type != OUT) PutBlast (i); } // At this point we are done with the drawing procedure // and all that remains to be done is updating the screen. if ( mask & DO_SCREEN_UPDATE ) { SDL_UpdateRect (ne_screen, User_Rect.x, User_Rect.y, User_Rect.w, User_Rect.h); SDL_UpdateRect (ne_screen, TxtRect.x, TxtRect.y, TxtRect.w, TxtRect.h); } SDL_SetClipRect (ne_screen, NULL); return; } // void Assemble_Combat_Picture(...)
//======================================================= // FUNCTION: MacDownPortRecv // PURPOSE: Receive the frame from the physical layer //======================================================= void S80211DcfMacDownPortRecv(MobileNode *node, WGN_802_11_Mac_Frame *frame) { unsigned int time; double sec; double rxpktpwr; // (W) WGNTime end_time; //********************************FOR TEST ONLY***********************************// //PrintLine(); //printf("NODE %d: MAC LAYER RECEIVE A PACKET FROM PHYSICAL LAYER.\n",node->Id); //PrintLine(); rxpktpwr = DBToW(GetPktRxPwr(frame)); //if the packet power is below CSThreshold, treat it as noise. if (IsOverCSThresh(rxpktpwr, node)==FALSE) { //Add the frame power into the total interference power. node->nodePhy->nodeAntenna->intPwr += rxpktpwr; if (IsOverCSThresh(node->nodePhy->nodeAntenna->intPwr, node)==TRUE) { //if greater than the carrier sense range, change the MAC state to MAC_RECV. SetRxStatus(node, MAC_RECV); } //Set inteference timeout event end_time = LocalTimeAdd (GetTime(), Frame_Time(node, frame)); AddNewEventToList(node->Id, INTTimeOut, end_time, (void*)frame); } //If the frame power is bigger than the CSThreshold, treat it as a normal frame. else { node->nodeStats->TotPktRxed += 1; // If the node is transmitting, mark the frame as collision error. if ( (GetTxActiveSign(node) == TRUE) && ( GetColErrorSign(frame)== FALSE) ) { SetColErrorSign(frame); } if ( GetRxStatus(node) == MAC_IDLE ) { SetRxStatus(node, MAC_RECV); node->nodeMac->pktRx = frame; sec = RX_Time(node); time = SecToNsec(sec); RXTimer_Start(node, time); } else { node->nodeStats->DropForCollision += 1; // If the busy state of the MAC layer is caused by the interference, // Treat the new incoming frame as interference. if (node->nodeMac->pktRx == NULL) { node->nodePhy->nodeAntenna->intPwr += rxpktpwr; end_time = LocalTimeAdd (GetTime(), Frame_Time(node, frame)); AddNewEventToList(node->Id, INTTimeOut, end_time, (void*)frame); } else if (GetCapSign(node) == ON) { //If the power difference in dB scale between the currently being received //frame and the new incoming one is greater than the capture threshold, //the new frame is treated as interference. if(IsOverCPThreshold(node, node->nodeMac->pktRx, frame) == TRUE) { node->nodeStats->AptCaptureNo += 1; Capture(node, frame); node->nodePhy->nodeAntenna->intPwr += rxpktpwr; end_time = LocalTimeAdd (GetTime(), Frame_Time(node, frame)); AddNewEventToList(node->Id, INTTimeOut, end_time, (void*)frame); } else { Collision(node, frame); // Note: Here it is uneccessary to add the pkt power to intPwr. // The pkt with the longest living time will stay in the pktRx buffer // which will keep the "MAC_COLL" status for mac layer. // The only purpose we compute the interference is for after the total // interference value above the CSThres, we should change the mac // layer status to "MAC_RECV". In this case, all the dropped pkt for // collison will be freed before the "MAC_COLL" status is over. So the // interference power which contributed by the collision packets will not // impact on the GINI performance. } } else { Collision(node, frame); } }//3 }//4 }