/*---------------------------------------------------------------------------* Project: Dolphin/Revolution gx demo File: pix-logic.c Copyright 1998-2006 Nintendo. All rights reserved. These coded instructions, statements, and computer programs contain proprietary information of Nintendo of America Inc. and/or Nintendo Company Ltd., and are protected by Federal copyright law. They may not be disclosed to third parties or copied or duplicated in any form, in whole or in part, without the prior written consent of Nintendo. *---------------------------------------------------------------------------*/ #include #include "cmn-model.h" #define SCREEN_WD 1 // Dummy - actual value filled at runtime #define SCREEN_HT 1 // Dummy - actual value filled at runtime #define SCREEN_ZNEAR 0.0f // near plane Z in screen coordinates #define SCREEN_ZFAR 1.0f // far plane Z in screen coordinates #define ZBUFFER_MAX 0x00ffffff /*---------------------------------------------------------------------------* Typedefs *---------------------------------------------------------------------------*/ typedef struct { char* title; GXBlendMode type; GXBlendFactor sfactor; GXBlendFactor dfactor; GXLogicOp logic; } Blend; typedef struct { Model* model; Camera* camera; ViewPort* viewport; Blend* blend; u32 flag; } Scene; #define SCENE_DRAWN (1<<0) #define SCENE_CURSOR (1<<1) /*---------------------------------------------------------------------------* Forward references *---------------------------------------------------------------------------*/ void SceneDraw( Scene* ); void SceneDrawInfo( Scene* ); void SceneControl( DEMOPadStatus* ); static void PrintIntro( void ); /*---------------------------------------------------------------------------* Rendering parameters *---------------------------------------------------------------------------*/ Camera myCamera = { { 0.0f, 0.0f, 30.0f }, // position { 0.0f,1000.0f, 0.0f }, // target { 0.0f, 0.0f, 1.0f }, // upVec 33.3f, // fovy 16.0f, // near plane Z in camera coordinates 1024.0f, // far plane Z in camera coordinates }; ViewPort myViewPort[] = { // full size (these are adjusted in main) { 0, 0, SCREEN_WD*2, SCREEN_HT*2 }, // half size { 0, 0, SCREEN_WD, SCREEN_HT }, { 0, SCREEN_HT, SCREEN_WD, SCREEN_HT }, { SCREEN_WD, 0, SCREEN_WD, SCREEN_HT }, { SCREEN_WD, SCREEN_HT, SCREEN_WD, SCREEN_HT }, }; Blend myBlend[] = { { NULL, GX_BM_LOGIC, GX_BL_ONE, GX_BL_ZERO, GX_LO_COPY }, { NULL, GX_BM_LOGIC, GX_BL_ONE, GX_BL_ZERO, GX_LO_INVCOPY }, { NULL, GX_BM_LOGIC, GX_BL_ONE, GX_BL_ZERO, GX_LO_XOR }, { NULL, GX_BM_LOGIC, GX_BL_ONE, GX_BL_ZERO, GX_LO_AND }, }; GXColor sceneBgColor = { 32, 32, 128,255}; Scene myScene[] = { { &cmModel[3], &myCamera, &myViewPort[0], &myBlend[0], 0 }, { &cmModel[3], &myCamera, &myViewPort[1], &myBlend[0], 0 }, { &cmModel[3], &myCamera, &myViewPort[2], &myBlend[1], 0 }, { &cmModel[3], &myCamera, &myViewPort[3], &myBlend[2], 0 }, { &cmModel[3], &myCamera, &myViewPort[4], &myBlend[3], 0 }, }; #define NUMSCENE (sizeof(myScene)/sizeof(Scene)) /*---------------------------------------------------------------------------* Application main loop *---------------------------------------------------------------------------*/ void main ( void ) { GXRenderModeObj *rmp; u32 i; // initialize render settings and set clear color for first frame DEMOInit( NULL ); // Defined in $(REVOLUTION_SDK_ROOT)/build/libraries/demo/src/DEMOInit.c GXInvalidateTexAll( ); GXSetCopyClear( sceneBgColor, ZBUFFER_MAX ); // Perform dummy copy operation to clear eFB by specified color GXCopyDisp( DEMOGetCurrentBuffer(), GX_TRUE ); rmp = DEMOGetRenderModeObj(); for(i = 0; i < 5; i++) { myViewPort[i].xorg *= rmp->fbWidth/2; myViewPort[i].yorg *= rmp->efbHeight/2; myViewPort[i].width *= rmp->fbWidth/2; myViewPort[i].height *= rmp->efbHeight/2; } PrintIntro(); while( ! ( DEMOPadGetButton(0) & PAD_BUTTON_MENU ) ) { // get pad status DEMOPadRead( ); // General control & model animation SceneControl( &DemoPad[0] ); cmModelAnime( &DemoPad[0], &myCamera ); // Draw scene DEMOBeforeRender( ); for ( i = 0; i < NUMSCENE; i ++ ) { SceneDraw( &myScene[i] ); } DEMODoneRender( ); } OSHalt("End of test"); } /*---------------------------------------------------------------------------* Functions *---------------------------------------------------------------------------*/ //============================================================================ // Scene //============================================================================ typedef struct { GXLogicOp ops; char* name; } Logic; // Bogus id number to test non-logic (subtract) mode #define GX_LO_XXX (GXLogicOp)0xFFFFFFFF Logic myLogic[] = { { GX_LO_CLEAR, "CLEAR 0" }, { GX_LO_SET, "SET 1" }, { GX_LO_COPY, "COPY Src" }, { GX_LO_INVCOPY, "INVCOPY ~Src" }, { GX_LO_NOOP, "NOOP Dst" }, { GX_LO_INV, "INV ~Dst" }, { GX_LO_AND, "AND Src & Dst" }, { GX_LO_NAND, "NAND ~(Src & Dst)" }, { GX_LO_OR, "OR Src | Dst" }, { GX_LO_NOR, "NOR ~(Src & Dst)" }, { GX_LO_XOR, "XOR Src ^ Dst" }, { GX_LO_EQUIV, "EQUIV ~(Src ^ Dst)" }, { GX_LO_REVAND, "REVAND Src & ~Dst" }, { GX_LO_INVAND, "INVAND ~Src ^ Dst" }, { GX_LO_REVOR, "REVOR Src | ~Dst" }, { GX_LO_INVOR, "INVOR ~Src | Dst" }, { GX_LO_XXX, "SUB Dst - Src" }, // subtract mode test }; #define NUMLOGICS (sizeof(myLogic)/sizeof(Logic)) /*---------------------------------------------------------------------------* Name: SceneDrawBegin Description: Update the perspective and view matrices. Arguments: Scene* s Returns: none *---------------------------------------------------------------------------*/ void SceneDraw( Scene* s ) { Camera* c = s->camera; ViewPort* v = s->viewport; Blend* b = s->blend; float aspect = (float) (4.0 / 3.0); GXColor black = {0, 0, 0, 0}; // Check if drawn flag if ( !(s->flag & SCENE_DRAWN) ) return; // Set Perspective Viewing frustum MTXPerspective( c->projMtx, c->fovy, aspect, c->znear, c->zfar ); GXSetProjection( c->projMtx, GX_PERSPECTIVE ); // Set CameraView matrix MTXLookAt( c->viewMtx, &c->position, &c->up, &c->target ); // Set Viewport GXSetViewport( v->xorg, v->yorg, v->width, v->height, SCREEN_ZNEAR, SCREEN_ZFAR ); GXSetScissor( (u32)v->xorg, (u32)v->yorg, (u32)v->width, (u32)v->height ); // Set Pixel Processing Mode GXSetFog( GX_FOG_NONE, 0.0f, 0.0f, 0.0f, 0.0f, black ); GXSetZMode( GX_TRUE, GX_LESS, GX_TRUE ); // Set blend if ( b->logic >= GX_LO_CLEAR && b->logic <= GX_LO_SET ) GXSetBlendMode( b->type, b->sfactor, b->dfactor, b->logic ); else GXSetBlendMode( b->type, b->sfactor, b->dfactor, GX_LO_CLEAR ); // Draw model if ( s->model->draw ) (*s->model->draw)( c ); // draw information SceneDrawInfo( s ); return; } /*---------------------------------------------------------------------------* Name: SceneDrawInfo Description: Draw scene information Arguments: Returns: none *---------------------------------------------------------------------------*/ void SceneDrawInfo( Scene* s ) { Camera* c = s->camera; ViewPort* v = s->viewport; Blend* b = s->blend; s32 lid; // Draw parameters to the window DEMOInitCaption( DM_FT_OPQ, v->width, v->height ); if ( b->title ) { DEMOPuts( 20, 12, 0, b->title ); } else { // get logic id for ( lid = NUMLOGICS-1; lid > 0; lid -- ) { if ( b->logic == myLogic[lid].ops ) break; } DEMOPuts( 20, 12, 0, myLogic[lid].name ); } // Draw cursor if ( s->flag & SCENE_CURSOR ) DEMOPuts( 12, 12,0, "\x7f" ); return; } /*---------------------------------------------------------------------------* Name: SceneControl Description: user interface for parameter control Arguments: Returns: none *---------------------------------------------------------------------------*/ void SceneControl( DEMOPadStatus* pad ) { static s32 zoomMode = 0; static s32 cursor = 0; static u32 modelId = 3; s32 i, lid; Scene* s; Blend* b; // Validate animation cmModel[modelId].flag = MODEL_REFERRED; // zoom mode if ( pad->buttonDown & PAD_BUTTON_A ) zoomMode ^= 1; if ( zoomMode ) { // // *** zoom mode // // show specified scene in full screen and put cursor s = &myScene[cursor+1]; b = s->blend; myScene[0].blend = b; myScene[0].flag = SCENE_DRAWN | SCENE_CURSOR; // turn off another window for ( i = 1; i < NUMSCENE; i ++ ) { myScene[i].flag = 0; } // get logic id for ( lid = NUMLOGICS-1; lid > 0; lid -- ) { if ( b->logic == myLogic[lid].ops ) break; } // change blend parameter if ( pad->dirsNew & ( DEMO_STICK_LEFT | DEMO_STICK_UP ) ) { if ( lid > 0 ) lid --; } if ( pad->dirsNew & ( DEMO_STICK_RIGHT | DEMO_STICK_DOWN ) ) { if ( lid < NUMLOGICS-1 ) lid ++; } // set parameter b->logic = myLogic[lid].ops; // the last bogus id is used for testing subtract mode if ( b->logic == GX_LO_XXX ) { b->type = GX_BM_SUBTRACT; } else { b->type = GX_BM_LOGIC; } } else { // // *** catalog mode // // choose a scene. if ( pad->dirsNew & DEMO_STICK_LEFT ) cursor &= ~2; // left if ( pad->dirsNew & DEMO_STICK_RIGHT ) cursor |= 2; // right if ( pad->dirsNew & DEMO_STICK_UP ) cursor &= ~1; // up : if ( pad->dirsNew & DEMO_STICK_DOWN ) cursor |= 1; // down // show 4 small windows for ( i = 1; i < 5; i ++ ) { myScene[i].flag = SCENE_DRAWN; } // turn off large window myScene[0].flag = 0; // set cursor s = &myScene[cursor+1]; s->flag |= SCENE_CURSOR; } return; } /*---------------------------------------------------------------------------* Name: PrintIntro Description: Prints the directions on how to use this demo. Arguments: none Returns: none *---------------------------------------------------------------------------*/ static void PrintIntro( void ) { OSReport("\n\n"); OSReport("************************************************\n"); OSReport("pix-logic: logic-ops test\n"); OSReport("************************************************\n"); OSReport("to quit hit the menu button\n"); OSReport("\n"); OSReport(" Stick X/Y : move cursor, change option\n"); OSReport(" A button : toggle zoom mode\n"); OSReport("************************************************\n\n"); } /*======== End of pix-logic.c ========*/