void BemGame::DrawMiniMap() { int k, m, n; KrResource* res = engine->Vault()->GetResource( KYRATAG_CANVAS, "minimap" ); KrCanvasResource* cres = res->ToCanvasResource(); GLASSERT( cres ); KrRGBA* target = cres->Pixels(); int factorX = cres->Width() / MAPX; int factorY = cres->Height() / MAPY; memset( target, 0, sizeof( KrRGBA ) * cres->Height() * cres->Width() ); // Draw the floor tiles on the map. for( m=0; m<MAPX; m++ ) { for( n=0; n<MAPY; n++ ) { if ( GetMap( m, MAPY - 1 - n ) == FLOOR ) // The map is stored upside down. { KrRGBA color; color.Set( 0, 0, 255, 255 ); int x = factorX * m; int y = factorY * n; DrawMiniMapBox( cres, color, x+1, y+1, factorX-1, factorY-1 ); } } } // Draw a box for each actor: for( k=0; k<numActors; k++ ) { // Draw a box for each actor. KrRGBA color; if ( actor[k].sprite->SpriteResource()->ResourceName() == "DRONE" ) color.Set( 255, 0, 0, 180 ); else color.Set( 0, 255, 0, 180 ); int x = factorX * actor[k].mapX; int y = factorY * ( MAPY - actor[k].mapY - 1); // The map is stored upside down. DrawMiniMapBox( cres, color, x+1, y+1, factorX-1, factorY-1 ); } // Remember we have to refresh a canvas after we draw! cres->Refresh(); }
BemGame::BemGame( SDL_Surface* screen, bool useWindows ) { random.SetSeed( 0 ); KrRGBA green; green.Set( 0, 200, 0 ); if ( useWindows ) { KrRect rects[5]; const int lW = 280; const int lH = 180; const int r = 200; const int pad = 10; rects[0].Set( 0, 0, screen->w - 1 - pad - r, r + pad - 1 ); rects[1].Set( 0, r + pad, screen->w-1, screen->h - 1 - pad - lH ); rects[2].Set( lW + pad, screen->h - pad - lH, screen->w-1, screen->h - 1 ); rects[3].Set( 0, screen->h - lH, lW-1, screen->h - 1 ); rects[4].Set( screen->w - r, 0, screen->w-1, r-1 ); engine = new KrEngine( screen, 5, rects, &green ); } else { engine = new KrEngine( screen ); } GLASSERT( engine ); // The vault contains all the resources used by this // demo. if (!engine->Vault()->LoadDatFile( "bem.dat" ) ) { GLOUTPUT(( "Error loading dat file: 'bem.dat'!\n" )); exit( 100 ); } KrRGBA black; black.Set( 0, 0, 0 ); if ( useWindows ) { engine->FillBackgroundWindow( 0, 0 ); // main engine->FillBackgroundWindow( 1, 0 ); // main engine->FillBackgroundWindow( 2, 0 ); // main engine->FillBackgroundWindow( 3, &black ); // zoomed out engine->FillBackgroundWindow( 4, &black ); // moving zoom } else { // We have a space image so the engine should not draw // the background. Performance enhancement. engine->FillBackground( 0 ); } // Set up some depth categories: backgroundTree = new KrImNode; underTree = new KrImNode; floorTree = new KrImNode; standingTree = new KrImNode; overTree = new KrImNode; // Depth sort by order of addition. All the z-depths are // left at 0. In other words, when added at the same Z-depth (0 // in this case) the object added most recently is on top. engine->Tree()->AddNode( 0, backgroundTree ); engine->Tree()->AddNode( 0, underTree ); engine->Tree()->AddNode( 0, floorTree ); engine->Tree()->AddNode( 0, standingTree ); engine->Tree()->AddNode( 0, overTree ); // Store the floor size. Due to the way the sprites are defined, // the size in terms of positioning the tiles is slightly different // than the size in terms of the tile bitmap. KrSpriteResource* resource = engine->Vault()->GetSpriteResource( BEM_ROOM | BEM_FLOOR ); GLASSERT( resource ); tileWidth = resource->GetActionByIndex( 0 )->Frame( 0 ).Width() +2; tileHeight = resource->GetActionByIndex( 0 )->Frame( 0 ).Height(); isoMath = new GlIsoMath( tileWidth, tileHeight ); isoMath->SetScreenCenterToTile( screen->w, screen->h, MAPX / 2, MAPY / 2, 0 ); AddSpaceTiles(); AddFloor(); AddRoomObjects(); AddActors( useWindows ); // Add the mini-map KrCanvasResource* canvasResource = new KrCanvasResource( "minimap", 140, 140, true ); GLASSERT( canvasResource ); // An example of a user-defined resource getting added to a vault. engine->Vault()->AddResource( canvasResource ); canvas = new KrCanvas( canvasResource ); canvas->SetPos( screen->w - canvasResource->Width(), screen->h - canvasResource->Height() ); engine->Tree()->AddNode( overTree, canvas ); subtick = 0; tick = 0; teleFrame = 0; teleSprite = 0; DrawMiniMap(); if ( useWindows ) { // Set the 3 "band" windows to be positioned // to the first. engine->Tree()->Root()->SetPos( 0, 0, 0 ); engine->Tree()->Root()->SetPos( -engine->ScreenBounds(1).min.x, -engine->ScreenBounds(1).min.y, 1 ); engine->Tree()->Root()->SetPos( -engine->ScreenBounds(2).min.x, -engine->ScreenBounds(2).min.y, 2 ); SetupLeftWindow(); SetupRightWindow(); } }
ScalingTest::ScalingTest( SDL_Surface* screen ) { int i, j; //KrMatrix2 xForm; state = BOTH; // // Create the engine, load the dat files, get the resource. // engine = new KrEngine( screen ); GLASSERT( engine ); if ( !engine->Vault()->LoadDatFile( "space.dat" ) ) { GLOUTPUT(( "Error loading 'space.dat'\n" )); exit(100); } fontVault = new KrResourceVault(); if ( !fontVault->LoadDatFile( "font.dat" ) ) { GLOUTPUT(( "Error loading 'font.dat'\n" )); exit(100); } KrSpriteResource* shipRes = engine->Vault()->GetSpriteResource( "MED" ); GLASSERT( shipRes ); KrSpriteResource* smallShipRes = engine->Vault()->GetSpriteResource( "SMALL" ); GLASSERT( smallShipRes ); KrFontResource* fontConsole = fontVault->GetFontResource( "CONSOLE" ); GLASSERT( fontConsole ); KrRGBA white, red; white.Set( 255, 255, 255 ); red.Set( 255, 0, 0 ); AddBackground(); // A group of travelling ships. travellingShip = new KrSprite( shipRes ); travellingShip->SetAction( "BODY" ); travellingShip->SetPos( 500, 390 ); engine->Tree()->AddNode( 0, travellingShip ); for ( i=0; i<4; ++i ) { KrSprite* escort = new KrSprite( smallShipRes ); escort->SetPos( 10 + i*30, -55 + i*30 ); engine->Tree()->AddNode( travellingShip, escort ); } travelText = new KrTextBox( fontConsole, 300, 300, 1 ); engine->Tree()->AddNode( travellingShip, travelText ); travelText->SetPos( -60, 30 ); travelText->SetTextChar( "sin wave motion", 0 ); // // Zoom 3 canvases to compare. The canvas are set up by drawing // a sprite to a canvas. // int hotx, hoty; KrCanvasResource* canvasRes = shipRes->CreateCanvasResource( "BODY", 0, &hotx, &hoty ); GLASSERT( canvasRes ); GLASSERT( canvasRes->Alpha() ); engine->Vault()->AddResource( canvasRes ); for( i=0; i<canvasRes->Width(); ++i ) { for( j=0; j<canvasRes->Height(); ++j ) { KrRGBA* pixel = canvasRes->Pixels() + j*canvasRes->Width() + i; if ( pixel->c.alpha ) pixel->c.alpha = i * 256 / canvasRes->Width(); } } for( i=0; i<3; ++i ) { canvas[i] = new KrCanvas( canvasRes ); canvas[i]->SetPos( 50 + i * 200, 170 ); engine->Tree()->AddNode( 0, canvas[i] ); } canvas[0]->SetQuality( KrQualityFast ); canvas[1]->SetQuality( KrQualityLinear ); canvas[2]->SetQuality( KrQualityAdaptive ); // A sprite that scales in the upper left. // A resource to mark the center of the sprite. KrBoxResource* centerRes = new KrBoxResource( "Center", 5, 5, &red, 1, KrBoxResource::CROSSHAIR ); engine->Vault()->AddResource( centerRes ); // The ship that scales in the upper left ship = new KrSprite( shipRes ); ship->SetAction( "BODY" ); ship->SetPos( SHIPX, SHIPY ); engine->Tree()->AddNode( 0, ship ); // Center marker of the sprite center = new KrBox( centerRes ); engine->Tree()->AddNode( 0, center ); center->SetPos( SHIPX, SHIPY ); // Some text info. textBox = new KrTextBox( fontConsole, 1024, 1024, 0 ); textBox->SetPos( 10, 10 ); engine->Tree()->AddNode( 0, textBox ); scaleX.v = GlFixed_1 - GlFixed_1 / 8; scaleY.v = GlFixed_1 - GlFixed_1 / 8; AddText( engine ); }
TileTest::TileTest( SDL_Surface* _screen ) { drawn = false; screen = _screen; engine = new KrEngine( screen ); //GLOUTPUT( "TileTest::TileTest\n" ); engine->Validate(); // check validity int i, j; // Classes to hold other objects: engine->Vault()->LoadDatFile( "standardtest.dat" ); KrTileResource* noAlphaRes = engine->Vault()->GetTileResource( "NOALPHA" ); KrTileResource* alphaRes = engine->Vault()->GetTileResource( "ALPHA" ); GLASSERT( noAlphaRes && alphaRes ); // Transforms: KrColorTransform alphaCForm; alphaCForm.SetAlpha( 255 * 70 / 100 ); KrColorTransform redCForm; redCForm.SetRed( 255 * 50 / 100, 127 ); KrColorTransform blueCForm; blueCForm.SetBlue( 255 * 50 / 100, 127 ); KrColorTransform greenAlphaCForm; greenAlphaCForm.SetGreen( 255 * 50 / 100, 127 ); greenAlphaCForm.SetAlpha( 255 * 70 / 100 ); KrColorTransform blueAlphaCForm; blueAlphaCForm.SetBlue( 255 * 50 / 100, 127 ); blueAlphaCForm.SetAlpha( 255 * 70 / 100 ); // Containers: KrImNode* c0 = new KrImNode; // background KrImNode* c1 = new KrImNode; // tiles KrImNode* c2 = new KrImNode; // canvas engine->Tree()->AddNode( 0, c0 ); engine->Tree()->AddNode( c0, c1 ); engine->Tree()->AddNode( c0, c2 ); c1->SetPos( 0, 0 ); c2->SetPos( 420, 0 ); c1->SetZDepth( 1 ); c2->SetZDepth( 1 ); // ---------- Background ----------- // KrSpriteResource* backSpriteRes = engine->Vault()->GetSpriteResource( "BACKGROUND" ); GLASSERT( backSpriteRes ); KrAction* action = backSpriteRes->GetActionByIndex( 0 ); GLASSERT( action ); const KrRle& rle = action->Frame( 0 ); for ( i=0; i <= (screen->w) / rle.Width(); i++ ) { for ( j=0; j <= (screen->h) / rle.Height(); j++ ) { KrSprite* sprite = new KrSprite( backSpriteRes ); sprite->SetPos( i*rle.Width(), j*rle.Height() ); GLASSERT( sprite ); engine->Tree()->AddNode( c0, sprite ); } } // ---------- The "no alpha" tile. // no transform: for ( i=0; i<8; i++ ) { noAlpha[i][0] = new KrTile( noAlphaRes ); noAlpha[i][0]->SetPos( i*noAlpha[i][0]->Size(), 0 ); noAlpha[i][0]->SetRotation( i ); GLASSERT( noAlpha ); engine->Tree()->AddNode( c1, noAlpha[i][0] ); } // alpha: for ( i=0; i<8; i++ ) { noAlpha[i][1] = new KrTile( noAlphaRes ); noAlpha[i][1]->SetColor( alphaCForm ); noAlpha[i][1]->SetPos( i*noAlpha[i][1]->Size(), 1*noAlpha[i][1]->Size() ); noAlpha[i][1]->SetRotation( i ); GLASSERT( noAlpha[i][1] ); engine->Tree()->AddNode( c1, noAlpha[i][1] ); } // red: for ( i=0; i<8; i++ ) { noAlpha[i][2] = new KrTile( noAlphaRes ); noAlpha[i][2]->SetColor( redCForm ); noAlpha[i][2]->SetPos( i*noAlpha[i][2]->Size(), 2*noAlpha[i][2]->Size() ); noAlpha[i][2]->SetRotation( i ); GLASSERT( noAlpha[i][2] ); engine->Tree()->AddNode( c1, noAlpha[i][2] ); } // combination: for ( i=0; i<8; i++ ) { noAlpha[i][3] = new KrTile( noAlphaRes ); noAlpha[i][3]->SetColor( blueAlphaCForm ); noAlpha[i][3]->SetPos( i*noAlpha[i][3]->Size(), 3*noAlpha[i][3]->Size() ); noAlpha[i][3]->SetRotation( i ); GLASSERT( noAlpha ); engine->Tree()->AddNode( c1, noAlpha[i][3] ); } // ---------- The "alpha" tile. // no transform: for ( i=0; i<8; i++ ) { // i=6; alpha[i][0] = new KrTile( alphaRes ); alpha[i][0]->SetPos( i*alpha[i][0]->Size(), 4*alpha[i][0]->Size() ); alpha[i][0]->SetRotation( i ); GLASSERT( alpha[i][0] ); engine->Tree()->AddNode( c1, alpha[i][0] ); } // alpha: for ( i=0; i<8; i++ ) { alpha[i][1] = new KrTile( alphaRes ); alpha[i][1]->SetColor( alphaCForm ); alpha[i][1]->SetPos( i*alpha[i][1]->Size(), 5*alpha[i][1]->Size() ); alpha[i][1]->SetRotation( i ); GLASSERT( alpha[i][1] ); engine->Tree()->AddNode( c1, alpha[i][1] ); } // red: for ( i=0; i<8; i++ ) { alpha[i][2] = new KrTile( alphaRes ); alpha[i][2]->SetColor( redCForm ); alpha[i][2]->SetPos( i*alpha[i][2]->Size(), 6*alpha[i][2]->Size() ); alpha[i][2]->SetRotation( i ); GLASSERT( alpha[i][2] ); engine->Tree()->AddNode( c1, alpha[i][2] ); } // combination: for ( i=0; i<8; i++ ) { alpha[i][3] = new KrTile( alphaRes ); alpha[i][3]->SetColor( blueAlphaCForm ); alpha[i][3]->SetPos( i*alpha[i][3]->Size(), 7*alpha[i][3]->Size() ); alpha[i][3]->SetRotation( i ); GLASSERT( alpha[i][3] ); engine->Tree()->AddNode( c1, alpha[i][3] ); } // ----------- A canvas ----------------- // KrCanvasResource* canvasResource = new KrCanvasResource( "mycanvas", 50, 50, true ); engine->Vault()->AddResource( canvasResource ); KrRGBA* pixels = canvasResource->Pixels(); KrRGBA color; for( i=0; i<canvasResource->Width(); i++ ) { for( j=0; j<canvasResource->Height(); j++ ) { color.c.red = i*4 + 50; color.c.green = j*4 + 50; color.c.blue = 0; color.c.alpha = 255 - i; pixels[ j*canvasResource->Width() + i ] = color; } // Put in a diagonal line: color.Set( 0, 0, 255 ); pixels[ i*canvasResource->Width() + i ] = color; } const int NUMCANVASDIV2 = NUMCANVAS / 2; for ( i=0; i<NUMCANVASDIV2; i++ ) { GlFixed sx; GlFixed sy; // The left canvas: canvas[i*2] = new KrCanvas( canvasResource ); engine->Tree()->AddNode( c2, canvas[i*2] ); canvas[i*2]->SetPos( 0, i * canvas[i*2]->Height() * 3 / 2 ); sx.v = GlFixed_1 * (i+1) / 3; sy.v = GlFixed_1 * (i+1) / 3; canvas[i*2]->SetScale( sx, sy ); // The right canvas: canvas[i*2+1] = new KrCanvas( canvasResource ); engine->Tree()->AddNode( c2, canvas[i*2+1] ); canvas[i*2+1]->SetPos( 100, i * canvas[i*2+1]->Height() * 3 / 2 ); sx.v = GlFixed_1 * (NUMCANVASDIV2 + 1 - i) / 3; sy.v = GlFixed_1 * (i+1) / 3; canvas[i*2+1]->SetScale( sx, sy ); } }
KrCanvasResource* KrEncoder::Load32Canvas( const char* filename, const KrRGBA* transparent, int nTrans, gedString* error ) { if ( !filename ) { if ( error ) *error = "No filename for a surface specified"; return 0; } // Try to load the file. SDL_Surface* surface = ImageLoader( filename ); if ( !surface ) { char buf[256]; sprintf( buf, "Failed to load surface '%s'.", filename ); if ( error ) *error = buf; return 0; } // The image can be 32 bits or less. A NON-32 bit image has // color(s) that are marked transparent. A 32 bit image // simply uses the alpha channel. Canvas's are always 32 bit, // and we always use a canvas that supports alpha. KrCanvasResource* canvas = new KrCanvasResource( "encoder", surface->w, surface->h, true ); if ( !canvas ) { if ( error ) *error = "Failed to create canvas."; return 0; } // Copy from the surface to the canvas. int x, y; int i; KrPaintInfo canvasPaintInfo( canvas->Pixels(), canvas->Width(), canvas->Height() ); KrPainter canvasPainter( &canvasPaintInfo ); KrPainter surfacePainter( surface ); for( x=0; x<surface->w; x++ ) { for( y=0; y<surface->h; y++ ) { KrRGBA rgba; surfacePainter.BreakPixel( x, y, &rgba ); for ( i=0; i<nTrans; i++ ) { if ( rgba.c.red == transparent[i].c.red && rgba.c.green == transparent[i].c.green && rgba.c.blue == transparent[i].c.blue ) { // Set the surface alpha to transparent. rgba.c.alpha = KrRGBA::KR_TRANSPARENT; break; } } canvasPainter.SetPixel( x, y, rgba ); } } return canvas; }