Пример #1
1
/**
 * ParamList = "(" [ ( Param [{ "," Param }] [ "," "..." ] ) | "..." | "void" ] ")"
 */
void parserParamList (parserCtx* ctx, ast* Node, bool inDecl) {
    debugEnter("ParamList");

    tokenMatchPunct(ctx, punctLParen);

    if (!tokenIsPunct(ctx, punctRParen)) {
        tokenLocation voidloc = ctx->location;

        bool end = false;

        /*Either an empty prototype declaration,
          or the beginning of a void* parameter*/
        if (tokenTryMatchKeyword(ctx, keywordVoid)) {
            if (!tokenIsPunct(ctx, punctRParen)) {
                ast* basic = astCreateLiteralIdent(voidloc, strdup("void"));
                ast* expr = parserDeclExpr(ctx, inDecl, symParam);
                ast* param = astCreateParam(voidloc, basic, expr);
                param->symbol = basic->symbol = symFind(ctx->scope, "void");
                astAddChild(Node, param);

                if (!tokenTryMatchPunct(ctx, punctComma))
                    end = true;

            } else
                end = true;
        }

        if (!end) do {
            if (tokenIsPunct(ctx, punctEllipsis)) {
                astAddChild(Node, astCreate(astEllipsis, ctx->location));
                tokenMatch(ctx);
                break;

            } else
                astAddChild(Node, parserParam(ctx, inDecl));

        } while (tokenTryMatchPunct(ctx, punctComma));
    }

    tokenMatchPunct(ctx, punctRParen);

    debugLeave();
}
Пример #2
0
int main()
{
	ASTREE* root,*ast1,*ast2,*ast3,*ast4,*ast5,*ast6;

	//DICT_NODE *symbol = malloc(sizeof(DICT_NODE*));

	ast1=astCreate(5,0,0, 0, 0, 0);

	ast2=astCreate(6,0,0, 0, 0, 0);

	ast3=astCreate(7,0,0, 0, 0, 0);

	ast4=astCreate(7,0,0, 0, 0, 0);

	ast5=astCreate(7,0,0, 0, 0, 0);

	ast6=astCreate(7,0,0, 0, 0, 0);

	ast4=astCreate(7,0,0, ast5, ast6, 0);

	root=astCreate(5,0,ast1, ast2, ast3, ast4);

	//------------------------------------------------

	gv_init("testando.dot");

	astReadTree(root);


	gv_close();


	return 0;
}
Пример #3
0
Файл: ast.c Проект: 8l/fcc
ast* astCreateTOP (tokenLocation location, ast* cond, ast* l, ast* r) {
    ast* Node = astCreate(astTOP, location);
    astAddChild(Node, cond);
    Node->l = l;
    Node->r = r;
    return Node;
}
Пример #4
0
Файл: ast.c Проект: 8l/fcc
ast* astCreateBOP (tokenLocation location, ast* l, opTag o, ast* r) {
    ast* Node = astCreate(astBOP, location);
    Node->l = l;
    Node->o = o;
    Node->r = r;
    return Node;
}
Пример #5
0
Файл: ast.c Проект: 8l/fcc
ast* astCreateUsing (tokenLocation location, char* name) {
    ast* Node = astCreate(astUsing, location);
    Node->litTag = literalStr;
    Node->literal = (void*) name;
    return Node;
}
Пример #6
0
Файл: ast.c Проект: 8l/fcc
ast* astCreateEmpty (tokenLocation location) {
    return astCreate(astEmpty, location);
}
Пример #7
0
Файл: ast.c Проект: 8l/fcc
ast* astCreateMarker (tokenLocation location, markerTag marker) {
    ast* Node = astCreate(astMarker, location);
    Node->marker = marker;
    return Node;
}
Пример #8
0
Файл: ast.c Проект: 8l/fcc
ast* astCreateConst (tokenLocation location, ast* r) {
    ast* Node = astCreate(astConst, location);
    Node->r = r;
    return Node;
}
Пример #9
0
Файл: ast.c Проект: 8l/fcc
ast* astCreateEnum (tokenLocation location, ast* name) {
    ast* Node = astCreate(astEnum, location);
    Node->l = name;
    return Node;
}
Пример #10
0
Файл: ast.c Проект: 8l/fcc
ast* astCreateStruct (tokenLocation location, ast* name) {
    ast* Node = astCreate(astStruct, location);
    Node->l = name;
    return Node;
}
Пример #11
0
Файл: ast.c Проект: 8l/fcc
ast* astCreateDecl (tokenLocation location, ast* basic) {
    ast* Node = astCreate(astDecl, location);
    Node->l = basic;
    return Node;
}
Пример #12
0
Файл: ast.c Проект: 8l/fcc
ast* astCreateCast (tokenLocation location, ast* result, ast* r) {
    ast* Node = astCreate(astCast, location);
    Node->l = result;
    Node->r = r;
    return Node;
}
Пример #13
0
Файл: ast.c Проект: 8l/fcc
ast* astCreateCall (tokenLocation location, ast* function) {
    ast* Node = astCreate(astCall, location);
    Node->l = function;
    return Node;
}
Пример #14
0
Файл: ast.c Проект: 8l/fcc
ast* astCreateIndex (tokenLocation location, ast* base, ast* index) {
    ast* Node = astCreate(astIndex, location);
    Node->l = base;
    Node->r = index;
    return Node;
}
Пример #15
0
Файл: ast.c Проект: 8l/fcc
ast* astCreateUOP (tokenLocation location, opTag o, ast* r) {
    ast* Node = astCreate(astUOP, location);
    Node->o = o;
    Node->r = r;
    return Node;
}
Пример #16
0
Файл: ast.c Проект: 8l/fcc
ast* astCreateFnImpl (tokenLocation location, ast* decl) {
    ast* Node = astCreate(astFnImpl, location);
    Node->l = decl;
    return Node;
}
Пример #17
0
Файл: ast.c Проект: 8l/fcc
ast* astCreateSizeof (tokenLocation location, ast* r) {
    ast* Node = astCreate(astSizeof, location);
    Node->r = r;
    return Node;
}
Пример #18
0
Файл: ast.c Проект: 8l/fcc
ast* astCreateType (tokenLocation location, ast* basic, ast* expr) {
    ast* Node = astCreate(astType, location);
    Node->l = basic;
    Node->r = expr;
    return Node;
}
Пример #19
0
Файл: ast.c Проект: 8l/fcc
ast* astCreateLiteral (tokenLocation location, literalTag litTag) {
    ast* Node = astCreate(astLiteral, location);
    Node->litTag = litTag;
    return Node;
}
Пример #20
0
Файл: ast.c Проект: 8l/fcc
ast* astCreateParam (tokenLocation location, ast* basic, ast* expr) {
    ast* Node = astCreate(astParam, location);
    Node->l = basic;
    Node->r = expr;
    return Node;
}
Пример #21
0
GameObjInst* astCreate(GameObjInst* pSrc)
{
    GameObjInst* pInst;
    AEVec2		 pos, vel;
    f32			 t, angle, size;

    if (pSrc)
    {
        f32		posOffset = pSrc->scale * 0.25f;
        f32		velOffset = (AST_SIZE_MAX - pSrc->scale + 1.0f) * 0.25f;
        f32		scaleNew  = pSrc->scale * 0.5f;

        sparkCreate(PTCL_EXPLOSION_L, &pSrc->posCurr, 5, 0.0f * PI - 0.01f * PI, 0.0f * PI + 0.01f * PI, 0.0f, pSrc->scale / AST_SIZE_MAX, &pSrc->velCurr);
        sparkCreate(PTCL_EXPLOSION_L, &pSrc->posCurr, 5, 0.5f * PI - 0.01f * PI, 0.5f * PI + 0.01f * PI, 0.0f, pSrc->scale / AST_SIZE_MAX, &pSrc->velCurr);
        sparkCreate(PTCL_EXPLOSION_L, &pSrc->posCurr, 5, 1.0f * PI - 0.01f * PI, 1.0f * PI + 0.01f * PI, 0.0f, pSrc->scale / AST_SIZE_MAX, &pSrc->velCurr);
        sparkCreate(PTCL_EXPLOSION_L, &pSrc->posCurr, 5, 1.5f * PI - 0.01f * PI, 1.5f * PI + 0.01f * PI, 0.0f, pSrc->scale / AST_SIZE_MAX, &pSrc->velCurr);

        pInst = astCreate(0);
        pInst->scale = scaleNew;
        AEVec2Set(&pInst->posCurr, pSrc->posCurr.x - posOffset, pSrc->posCurr.y - posOffset);
        AEVec2Set(&pInst->velCurr, pSrc->velCurr.x - velOffset, pSrc->velCurr.y - velOffset);

        pInst = astCreate(0);
        pInst->scale = scaleNew;
        AEVec2Set(&pInst->posCurr, pSrc->posCurr.x + posOffset, pSrc->posCurr.y - posOffset);
        AEVec2Set(&pInst->velCurr, pSrc->velCurr.x + velOffset, pSrc->velCurr.y - velOffset);

        pInst = astCreate(0);
        pInst->scale = scaleNew;
        AEVec2Set(&pInst->posCurr, pSrc->posCurr.x - posOffset, pSrc->posCurr.y + posOffset);
        AEVec2Set(&pInst->velCurr, pSrc->velCurr.x - velOffset, pSrc->velCurr.y + velOffset);

        pSrc->scale = scaleNew;
        AEVec2Set(&pSrc->posCurr, pSrc->posCurr.x + posOffset, pSrc->posCurr.y + posOffset);
        AEVec2Set(&pSrc->velCurr, pSrc->velCurr.x + velOffset, pSrc->velCurr.y + velOffset);

        return pSrc;
    }

    // pick a random angle and velocity magnitude
    angle = AERandFloat() * 2.0f * PI;
    size  = AERandFloat() * (AST_SIZE_MAX - AST_SIZE_MIN) + AST_SIZE_MIN;

    // pick a random position along the top or left edge
    if ((t = AERandFloat()) < 0.5f)
        AEVec2Set(&pos, gAEWinMinX + (t * 2.0f) * (gAEWinMaxX - gAEWinMinX), gAEWinMinY - size * 0.5f);
    else
        AEVec2Set(&pos, gAEWinMinX - size * 0.5f, gAEWinMinY + ((t - 0.5f) * 2.0f) * (gAEWinMaxY - gAEWinMinY));

    // calculate the velocity vector
    AEVec2Set	(&vel, AECos(angle), AESin(angle));
    AEVec2Scale	(&vel, &vel, AERandFloat() * (AST_VEL_MAX - AST_VEL_MIN) + AST_VEL_MIN);

    // create the object instance
    pInst = gameObjInstCreate(TYPE_ASTEROID, size, &pos, &vel, 0.0f, true);
    AE_ASSERT(pInst);

    // set the life based on the size
    pInst->life = size / AST_SIZE_MAX * AST_LIFE_MAX;

    return pInst;
}
Пример #22
0
Файл: ast.c Проект: 8l/fcc
ast* astCreateUnion (tokenLocation location, ast* name) {
    ast* Node = astCreate(astUnion, location);
    Node->l = name;
    return Node;
}
Пример #23
0
Файл: ast.c Проект: 8l/fcc
ast* astCreateInvalid (tokenLocation location) {
    return astCreate(astInvalid, location);
}
Пример #24
0
Файл: ast.c Проект: 8l/fcc
ast* astCreateAssert (tokenLocation location, ast* expr) {
    ast* Node = astCreate(astAssert, location);
    Node->r = expr;
    return Node;
}
Пример #25
0
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);
    }
}