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);
    }
}
Exemple #4
0
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();
}