void DoInput( void ) { if( _IsOff( SW_WND_DOING_INPUT ) ) { for ( ;; ) { if( ProcInput() ) break; if( !HookPendingPush() ) break; } } }
OVL_EXTERN void Profile( void ) { if( InvokeFile != NULL ) { ProfileInvoke( InvokeFile ); _Free( InvokeFile ); InvokeFile = NULL; ProcInput(); } }
void GameStatePlayUpdate(void) { if (AEInputCheckTriggered(DIK_J)) SendJoinMessage(); MsgInput inputMsg; if(ProcInput(inputMsg)) { strcpy(inputMsg.data_.username_.name_, client.config_.username_.c_str()); NetworkMessage netMsg; netMsg << inputMsg; netMsg.receiverAddress_ = client.remoteAddr_; try { printf("\nSending INPUT message... Input Count = %d\n", inputMsg.data_.key_info_count_); client.udpSock_.Send(netMsg); } catch(iSocket::SockErr& e) { e.Print(); } } char buffer[1000] = { 0 }; sprintf(buffer, "TIME LEFT: %.2f", time); AEGfxPrint(300, 10, 0xFFFFFFFF, buffer); sprintf(buffer, "Round: %u", round); AEGfxPrint(350, 30, 0xFFFFFFFF, buffer); unsigned yPos = 10; unsigned xPos = 10; for(std::vector<ResultStatus>::iterator it = results.begin(); it != results.end(); ++it) { sprintf(buffer, "%s: Score: %u", it->name_.name_, it->score_); AEGfxPrint(xPos, yPos, 0xFFFFFFFF, buffer); yPos += ROW_HEIGHT; } client.udpSock_.Resend(); // check for messages from server NetworkMessage netMsg; if(client.udpSock_.Receive(netMsg)) ProcMessage(netMsg); #if 0 // =============== // update physics // =============== for (u32 i = 0; i < GAME_OBJ_INST_NUM_MAX; i++) { GameObjInst* pInst = sGameObjInstList + i; // skip non-active object if ((pInst->flag & FLAG_ACTIVE) == 0) continue; // update the position AEVec2ScaleAdd(&pInst->posCurr, &pInst->velCurr, &pInst->posCurr, (f32)(gAEFrameTime)); } // =============== // update objects // =============== for (u32 i = 0; i < GAME_OBJ_INST_NUM_MAX; i++) { GameObjInst* pInst = sGameObjInstList + i; // skip non-active object if ((pInst->flag & FLAG_ACTIVE) == 0) continue; // check if the object is a ship if (pInst->pObject->type == TYPE_SHIP) { // warp the ship from one end of the screen to the other pInst->posCurr.x = AEWrap(pInst->posCurr.x, gAEWinMinX - SHIP_SIZE, gAEWinMaxX + SHIP_SIZE); pInst->posCurr.y = AEWrap(pInst->posCurr.y, gAEWinMinY - SHIP_SIZE, gAEWinMaxY + SHIP_SIZE); } // check if the object is an asteroid else if (pInst->pObject->type == TYPE_ASTEROID) { AEVec2 u; f32 uLen; // warp the asteroid from one end of the screen to the other pInst->posCurr.x = AEWrap(pInst->posCurr.x, gAEWinMinX - AST_SIZE_MAX, gAEWinMaxX + AST_SIZE_MAX); pInst->posCurr.y = AEWrap(pInst->posCurr.y, gAEWinMinY - AST_SIZE_MAX, gAEWinMaxY + AST_SIZE_MAX); // pull the asteroid toward the ship a little bit if (spShip) { // apply acceleration propotional to the distance from the asteroid to the ship AEVec2Sub (&u, &spShip->posCurr, &pInst->posCurr); AEVec2Scale (&u, &u, AST_TO_SHIP_ACC * (f32)(gAEFrameTime)); AEVec2Add (&pInst->velCurr, &pInst->velCurr, &u); } // if the asterid velocity is more than its maximum velocity, reduce its speed if ((uLen = AEVec2Length(&pInst->velCurr)) > (AST_VEL_MAX * 2.0f)) { AEVec2Scale (&u, &pInst->velCurr, (1.0f / uLen) * (AST_VEL_MAX * 2.0f - uLen) * pow(AST_VEL_DAMP, (f32)(gAEFrameTime))); AEVec2Add (&pInst->velCurr, &pInst->velCurr, &u); } } // check if the object is a bullet else if (pInst->pObject->type == TYPE_BULLET) { // kill the bullet if it gets out of the screen if (!AEInRange(pInst->posCurr.x, gAEWinMinX - AST_SIZE_MAX, gAEWinMaxX + AST_SIZE_MAX) || !AEInRange(pInst->posCurr.y, gAEWinMinY - AST_SIZE_MAX, gAEWinMaxY + AST_SIZE_MAX)) gameObjInstDestroy(pInst); } // check if the object is a bomb else if (pInst->pObject->type == TYPE_BOMB) { // adjust the life counter pInst->life -= (f32)(gAEFrameTime) / BOMB_LIFE; if (pInst->life < 0.0f) { gameObjInstDestroy(pInst); } else { f32 radius = 1.0f - pInst->life; AEVec2 u; pInst->dirCurr += 2.0f * PI * (f32)(gAEFrameTime); radius = 1.0f - radius; radius *= radius; radius *= radius; radius *= radius; radius *= radius; radius = (1.0f - radius) * BOMB_RADIUS; // generate the particle ring for (u32 j = 0; j < 10; j++) { //f32 dir = AERandFloat() * 2.0f * PI; f32 dir = (j / 9.0f) * 2.0f * PI + pInst->life * 1.5f * 2.0f * PI; u.x = AECos(dir) * radius + pInst->posCurr.x; u.y = AESin(dir) * radius + pInst->posCurr.y; //sparkCreate(PTCL_EXHAUST, &u, 1, dir + 0.8f * PI, dir + 0.9f * PI); sparkCreate(PTCL_EXHAUST, &u, 1, dir + 0.40f * PI, dir + 0.60f * PI); } } } // check if the object is a missile else if (pInst->pObject->type == TYPE_MISSILE) { // adjust the life counter pInst->life -= (f32)(gAEFrameTime) / MISSILE_LIFE; if (pInst->life < 0.0f) { gameObjInstDestroy(pInst); } else { AEVec2 dir; if (pInst->pUserData == 0) { pInst->pUserData = missileAcquireTarget(pInst); } else { GameObjInst* pTarget = (GameObjInst*)(pInst->pUserData); // if the target is no longer valid, reacquire if (((pTarget->flag & FLAG_ACTIVE) == 0) || (pTarget->pObject->type != TYPE_ASTEROID)) pInst->pUserData = missileAcquireTarget(pInst); } if (pInst->pUserData) { GameObjInst* pTarget = (GameObjInst*)(pInst->pUserData); AEVec2 u; f32 uLen; // get the vector from the missile to the target and its length AEVec2Sub(&u, &pTarget->posCurr, &pInst->posCurr); uLen = AEVec2Length(&u); // if the missile is 'close' to target, do nothing if (uLen > 0.1f) { // normalize the vector from the missile to the target AEVec2Scale(&u, &u, 1.0f / uLen); // calculate the missile direction vector AEVec2Set(&dir, AECos(pInst->dirCurr), AESin(pInst->dirCurr)); // calculate the cos and sin of the angle between the target // vector and the missile direction vector f32 cosAngle = AEVec2DotProduct(&dir, &u), sinAngle = AEVec2CrossProductMag(&dir, &u), rotAngle; // calculate how much to rotate the missile if (cosAngle < AECos(MISSILE_TURN_SPEED * (f32)(gAEFrameTime))) rotAngle = MISSILE_TURN_SPEED * (f32)(gAEFrameTime); else rotAngle = AEACos(AEClamp(cosAngle, -1.0f, 1.0f)); // rotate to the left if sine of the angle is positive and vice versa pInst->dirCurr += (sinAngle > 0.0f) ? rotAngle : -rotAngle; } } // adjust the missile velocity AEVec2Set (&dir, AECos(pInst->dirCurr), AESin(pInst->dirCurr)); AEVec2Scale(&dir, &dir, MISSILE_ACCEL * (f32)(gAEFrameTime)); AEVec2Add (&pInst->velCurr, &pInst->velCurr, &dir); AEVec2Scale(&pInst->velCurr, &pInst->velCurr, pow(MISSILE_DAMP, (f32)(gAEFrameTime))); sparkCreate(PTCL_EXHAUST, &pInst->posCurr, 1, pInst->dirCurr + 0.8f * PI, pInst->dirCurr + 1.2f * PI); } } // check if the object is a particle else if ((TYPE_PTCL_WHITE <= pInst->pObject->type) && (pInst->pObject->type <= TYPE_PTCL_RED)) { pInst->scale *= pow(PTCL_SCALE_DAMP, (f32)(gAEFrameTime)); pInst->dirCurr += 0.1f; AEVec2Scale(&pInst->velCurr, &pInst->velCurr, pow(PTCL_VEL_DAMP, (f32)(gAEFrameTime))); if (pInst->scale < PTCL_SCALE_DAMP) gameObjInstDestroy(pInst); } } // ==================== // check for collision // ==================== for (u32 i = 0; i < GAME_OBJ_INST_NUM_MAX; i++) { GameObjInst* pSrc = sGameObjInstList + i; // skip non-active object if ((pSrc->flag & FLAG_ACTIVE) == 0) continue; if ((pSrc->pObject->type == TYPE_BULLET) || (pSrc->pObject->type == TYPE_MISSILE)) { for (u32 j = 0; j < GAME_OBJ_INST_NUM_MAX; j++) { GameObjInst* pDst = sGameObjInstList + j; // skip no-active and non-asteroid object if (((pDst->flag & FLAG_ACTIVE) == 0) || (pDst->pObject->type != TYPE_ASTEROID)) continue; if (AETestPointToRect(&pSrc->posCurr, &pDst->posCurr, pDst->scale, pDst->scale) == false) continue; if (pDst->scale < AST_SIZE_MIN) { sparkCreate(PTCL_EXPLOSION_M, &pDst->posCurr, (u32)(pDst->scale * 10), pSrc->dirCurr - 0.05f * PI, pSrc->dirCurr + 0.05f * PI, pDst->scale); sScore++; if ((sScore % AST_SPECIAL_RATIO) == 0) sSpecialCtr++; if ((sScore % AST_SHIP_RATIO) == 0) sShipCtr++; if (sScore == sAstNum * 5) sAstNum = (sAstNum < AST_NUM_MAX) ? (sAstNum * 2) : sAstNum; // destroy the asteroid gameObjInstDestroy(pDst); } else { sparkCreate(PTCL_EXPLOSION_S, &pSrc->posCurr, 10, pSrc->dirCurr + 0.9f * PI, pSrc->dirCurr + 1.1f * PI); // impart some of the bullet/missile velocity to the asteroid AEVec2Scale(&pSrc->velCurr, &pSrc->velCurr, 0.01f * (1.0f - pDst->scale / AST_SIZE_MAX)); AEVec2Add (&pDst->velCurr, &pDst->velCurr, &pSrc->velCurr); // split the asteroid to 4 if ((pSrc->pObject->type == TYPE_MISSILE) || ((pDst->life -= 1.0f) < 0.0f)) astCreate(pDst); } // destroy the bullet gameObjInstDestroy(pSrc); break; } } else if (TYPE_BOMB == pSrc->pObject->type) { f32 radius = 1.0f - pSrc->life; pSrc->dirCurr += 2.0f * PI * (f32)(gAEFrameTime); radius = 1.0f - radius; radius *= radius; radius *= radius; radius *= radius; radius *= radius; radius *= radius; radius = (1.0f - radius) * BOMB_RADIUS; // check collision for (u32 j = 0; j < GAME_OBJ_INST_NUM_MAX; j++) { GameObjInst* pDst = sGameObjInstList + j; if (((pDst->flag & FLAG_ACTIVE) == 0) || (pDst->pObject->type != TYPE_ASTEROID)) continue; if (AECalcDistPointToRect(&pSrc->posCurr, &pDst->posCurr, pDst->scale, pDst->scale) > radius) continue; if (pDst->scale < AST_SIZE_MIN) { f32 dir = atan2f(pDst->posCurr.y - pSrc->posCurr.y, pDst->posCurr.x - pSrc->posCurr.x); gameObjInstDestroy(pDst); sparkCreate(PTCL_EXPLOSION_M, &pDst->posCurr, 20, dir + 0.4f * PI, dir + 0.45f * PI); sScore++; if ((sScore % AST_SPECIAL_RATIO) == 0) sSpecialCtr++; if ((sScore % AST_SHIP_RATIO) == 0) sShipCtr++; if (sScore == sAstNum * 5) sAstNum = (sAstNum < AST_NUM_MAX) ? (sAstNum * 2) : sAstNum; } else { // split the asteroid to 4 astCreate(pDst); } } } else if (pSrc->pObject->type == TYPE_ASTEROID) { for (u32 j = 0; j < GAME_OBJ_INST_NUM_MAX; j++) { GameObjInst* pDst = sGameObjInstList + j; f32 d; AEVec2 nrm, u; // skip no-active and non-asteroid object if ((pSrc == pDst) || ((pDst->flag & FLAG_ACTIVE) == 0) || (pDst->pObject->type != TYPE_ASTEROID)) continue; // check if the object rectangle overlap d = AECalcDistRectToRect( &pSrc->posCurr, pSrc->scale, pSrc->scale, &pDst->posCurr, pDst->scale, pDst->scale, &nrm); if (d >= 0.0f) continue; // adjust object position so that they do not overlap AEVec2Scale (&u, &nrm, d * 0.25f); AEVec2Sub (&pSrc->posCurr, &pSrc->posCurr, &u); AEVec2Add (&pDst->posCurr, &pDst->posCurr, &u); // calculate new object velocities resolveCollision(pSrc, pDst, &nrm); } } else if (pSrc->pObject->type == TYPE_SHIP) { for (u32 j = 0; j < GAME_OBJ_INST_NUM_MAX; j++) { GameObjInst* pDst = sGameObjInstList + j; // skip no-active and non-asteroid object if ((pSrc == pDst) || ((pDst->flag & FLAG_ACTIVE) == 0) || (pDst->pObject->type != TYPE_ASTEROID)) continue; // check if the object rectangle overlap if (AETestRectToRect( &pSrc->posCurr, pSrc->scale, pSrc->scale, &pDst->posCurr, pDst->scale, pDst->scale) == false) continue; // create the big explosion sparkCreate(PTCL_EXPLOSION_L, &pSrc->posCurr, 100, 0.0f, 2.0f * PI); // reset the ship position and direction AEVec2Zero(&spShip->posCurr); AEVec2Zero(&spShip->velCurr); spShip->dirCurr = 0.0f; sSpecialCtr = SHIP_SPECIAL_NUM; // destroy all asteroid near the ship so that you do not die as soon as the ship reappear for (u32 j = 0; j < GAME_OBJ_INST_NUM_MAX; j++) { GameObjInst* pInst = sGameObjInstList + j; AEVec2 u; // skip no-active and non-asteroid object if (((pInst->flag & FLAG_ACTIVE) == 0) || (pInst->pObject->type != TYPE_ASTEROID)) continue; AEVec2Sub(&u, &pInst->posCurr, &spShip->posCurr); if (AEVec2Length(&u) < (spShip->scale * 10.0f)) { sparkCreate (PTCL_EXPLOSION_M, &pInst->posCurr, 10, -PI, PI); gameObjInstDestroy(pInst); } } // reduce the ship counter sShipCtr--; // if counter is less than 0, game over if (sShipCtr < 0) { sGameStateChangeCtr = 2.0; gameObjInstDestroy(spShip); spShip = 0; } break; } } } #endif // ===================================== // calculate the matrix for all objects // ===================================== for (u32 i = 0; i < GAME_OBJ_INST_NUM_MAX; i++) { GameObjInst* pInst = sGameObjInstList + i; AEMtx33 m; // skip non-active object if ((pInst->flag & FLAG_ACTIVE) == 0) continue; AEMtx33Scale (&pInst->transform, pInst->scale, pInst->scale); AEMtx33Rot (&m, pInst->dirCurr); AEMtx33Concat (&pInst->transform, &m, &pInst->transform); AEMtx33Trans (&m, pInst->posCurr.x, pInst->posCurr.y); AEMtx33Concat (&pInst->transform, &m, &pInst->transform); } }
void Error( dbg_err_flags flg, char *fmt, ... ) { char buff[TXT_LEN]; va_list args; char *ptr; invokes *inv; input_stack *inp; char *where; bool cmderror; va_start( args, fmt ); ptr = buff; if( flg & ERR_INTERNAL ) { ptr = StrCopy( LIT_ENG( Internal_Error ), ptr ); } ptr = FmtStr( ptr, fmt, args ); ptr = StrCopy( ".", ptr ); if( flg & ERR_LOC ) { ptr = StrCopy( "\n ", ptr ); switch( CurrToken ) { case T_CMD_SEPARATOR: ptr = StrCopy( LIT_ENG( ERR_NEAR_END_OF_COMMAND ), ptr ); break; case T_LINE_SEPARATOR: ptr = StrCopy( LIT_ENG( ERR_NEAR_END_OF_LINE ), ptr ); break; default: if( ScanLen() == 0 ) Scan(); ptr = Format( ptr, LIT_ENG( ERR_NEAR_TOKEN ), ScanPos(), ScanLen() ); break; } } SetProgStartHook( TRUE ); UnFreezeRegs(); ScanExpr( NULL ); ExprPurge(); PurgeSymHandles(); /* must be done after ExprPurge */ DIPCancel(); ScanSavePtr = 0; /* clean up previous ScanSave locations */ if( _IsOff( SW_ERROR_PRESERVES_RADIX ) ) { RestoreRadix(); } _SwitchOff( SW_CALL_FATAL ); if( _IsOn( SW_ERROR_STARTUP ) ) { StartupErr( buff ); } if( _IsOn( SW_ERR_IN_TXTBUFF ) ) { PurgeInpStack(); StrCopy( buff, TxtBuff ); DUIArrowCursor(); Suicide(); } if( (flg & ERR_SILENT) == 0 ) { where = LIT_ENG( ERR_EXECUTING_AT ); for( inp = InpStack; inp != NULL; inp = inp->link ) { if( inp->type & INP_CMD_FILE ) { inv = inp->handle; ptr = StrCopy( "\n ", ptr ); ptr = Format( ptr, where, inv->line, inv->name ); where = LIT_ENG( ERR_CALLED_FROM ); } } DUIFlushKeys(); DUIWndDebug(); RingBell(); DUIErrorBox( buff ); } cmderror = FALSE; for( inp = InpStack; inp != NULL; inp = inp->link ) { if( inp->type & INP_BREAK_POINT ) { BrkCmdError(); } if( inp->type & INP_CAPTURED ) { CaptureError(); } if( inp->type & INP_DLG_CMD ) { cmderror = TRUE; } } PurgeInpStack(); if( cmderror && fmt != LIT_ENG( ERR_DBG_INTERRUPT ) ) { DlgCmd(); ProcInput(); } if( _IsOn( SW_ERROR_RETURNS ) ) return; DUIArrowCursor(); Suicide(); }