void KrButton::PlaceIcon() { GLASSERT( Engine() ); if ( icon ) { int width = bevel.width - 4; // Give some border space. int height = bevel.height - 4; if ( width > 0 && height > 0 ) { KrRect bounds; icon->QueryBoundingBox( &bounds ); GlFixed wScale = GlFixed( width ) / GlFixed( bounds.Width() ); GlFixed hScale = GlFixed( height ) / GlFixed( bounds.Height() ); GlFixed scale = GlMin( wScale, hScale ); GLASSERT( scale > 0 ); iconX = width - ( scale * bounds.Width() ).ToInt(); iconX = iconX / 2 - ( scale * bounds.xmin ).ToInt() + 1; iconY = height - ( scale * bounds.Height() ).ToInt(); iconY = iconY / 2 - ( scale * bounds.ymin ).ToInt() + 1; icon->SetScale( scale, scale ); icon->SetPos( iconX, iconY ); Engine()->Tree()->AddNode( holder, icon ); icon->SetZDepth( ICON_DEPTH ); } } }
void EdStateMovie::ZoomOut() { GlFixed scale = movieNode->XScale(); if ( scale.v > GlFixed_1 / 4 ) { scale /= 2; movieNode->SetScale( scale, scale ); KrImNode* image = shared->Engine()->Tree()->FindNodeById( 0 ); GLASSERT( image ); KrSprite* sprite = image->ToSprite(); GLASSERT( sprite ); shared->Engine()->Tree()->Walk(); //int x = sprite->CompositeXForm(0).x.ToInt(); //int y = sprite->CompositeXForm(0).y.ToInt(); KrRect screen = shared->Engine()->ScreenBounds(); GlFixed scale = movieNode->XScale(); GlFixed inverse = GlFixed( 1 ) / scale; sprite->SetPos( (inverse * screen.Width()).ToInt() / 2, (inverse*screen.Height()).ToInt()/2 ); } }
/* This follows the same pattern as the blit test, but it uses tiles and cavases instead of sprites. Once again, it is used to make sure the basic blts and transformations are correct. */ void TileTest::DrawFrame() { int index = Frame() % NUMCANVAS; int quality = ( Frame() / NUMCANVAS ) % 3 + 1; canvas[ index ]->SetQuality( quality ); //GLOUTPUT( "TileTest Drawframe A\n" ); engine->Validate(); // check validity engine->Draw(); //GLOUTPUT( "TileTest Drawframe B\n" ); engine->Validate(); // check validity //GLOUTPUT( "TileTest Drawframe done\n" ); if ( Frame() > 20 ) { if ( Frame() > SCALEY ) { int vFrame = Frame() - SCALEY + 1; int tFrame = TestFrames() - SCALEY; GlFixed scale = GlFixed( vFrame ) / GlFixed( tFrame ); for( int i=0; i<8; ++i ) { for( int j=0; j<4; ++j ) { alpha[i][j]->SetScale( 1, scale ); noAlpha[i][j]->SetScale( 1, scale ); } } } else if ( Frame() > SCALEX ) { int vFrame = Frame() - SCALEX + 1; int tFrame = SCALEY - SCALEX; GlFixed scale = GlFixed( vFrame ) / GlFixed( tFrame ); for( int i=0; i<8; ++i ) { for( int j=0; j<4; ++j ) { alpha[i][j]->SetScale( scale, 1 ); noAlpha[i][j]->SetScale( scale, 1 ); } } } else if ( Frame() > SCALEBOTH ) { int vFrame = Frame() - SCALEBOTH + 1; int tFrame = SCALEX - SCALEBOTH; GlFixed scale = GlFixed( vFrame ) / GlFixed( tFrame ); for( int i=0; i<8; ++i ) { for( int j=0; j<4; ++j ) { alpha[i][j]->SetScale( scale, scale ); noAlpha[i][j]->SetScale( scale, scale ); } } } } }
void EdStateMovie::FrameTick() { KrImNode* image = shared->Engine()->Tree()->FindNodeById( 0 ); GLASSERT( image ); KrSprite* sprite = image->ToSprite(); GLASSERT( sprite ); sprite->DoStep(); int x = sprite->CompositeXForm(0).x.ToInt(); int y = sprite->CompositeXForm(0).y.ToInt(); KrRect screen = shared->Engine()->ScreenBounds(); GlFixed scale = movieNode->XScale(); GlFixed inverse = GlFixed( 1 ) / scale; if ( x < 0 ) sprite->SetPos( (inverse * screen.Width()).ToInt(), sprite->Y() ); if ( x > screen.Width() ) sprite->SetPos( 0, sprite->Y() ); if ( y < 0 ) sprite->SetPos( sprite->X(), (inverse*screen.Height()).ToInt() ); if ( y > screen.Height() ) sprite->SetPos( sprite->X(), 0 ); }
int main( int argc, char *argv[] ) { const SDL_version* sdlVersion = SDL_Linked_Version(); if ( sdlVersion->minor < 2 ) { printf( "SDL version must be at least 1.2.0\n" ); GLASSERT( 0 ); exit( 254 ); } if ( argc < 2 ) { printf( "Usage: krmapmaker map.xml\n" ); exit( 253 ); } TiXmlDocument doc( argv[1] ); doc.LoadFile(); XmlUtil xmlUtil( &doc ); if ( !xmlUtil.IsValidMap() ) { printf( "Not a valid map file.\n" ); exit( 252 ); } /* Initialize the SDL library */ if ( SDL_Init(SDL_INIT_VIDEO|SDL_INIT_TIMER|SDL_INIT_NOPARACHUTE) < 0 ) { #ifdef DEBUG GLOUTPUT( "Couldn't initialize SDL: %s\n",SDL_GetError()); #endif exit(255); } SDL_WM_SetCaption( "Kyra MapMaker", 0 ); int screenX = 800; int screenY = 600; SDL_Surface* screen = SDL_SetVideoMode( screenX, screenY, 32, SDL_SWSURFACE ); if ( screen ) { KrResourceVault fontVault; //fontVault.LoadDatFileFromMemory( fontDat, sizeof( fontDat ) ); KrFontResource* consoleFontRes = KrEncoder::CreateFixedFontResource( "CONSOLE", CONSOLEFONT_DAT, CONSOLEFONT_SIZE ); Layout layout( screen, consoleFontRes ); if ( layout.Engine()->Vault()->LoadDatFile( xmlUtil.DatFileName().c_str() ) != true ) { printf( "Couldn't load dat file.\n" ); exit( 250 ); } KrSquareWorldMap* worldMap = new KrSquareWorldMap( 100, 100, 100 ); // fixme hardcoded! layout.Engine()->Tree()->AddNode( layout.Map(), worldMap ); worldMap->SetPos( 0, screenY-1, Layout::MAIN_VIEW ); xmlUtil.Init( layout.Engine()->Vault(), layout.Engine(), layout.Map(), worldMap ); // xmlUtil.InsertLayers( layout.LayerBox() ); UILogic logic( &layout, &xmlUtil ); layout.SetLayer( xmlUtil.GetLayer( "null" ), 0 ); KrRGBA white; white.Set( 200, 200, 200 ); KrBox* whereBox = new KrBox( layout.Engine()->ScreenBounds( Layout::MAIN_VIEW ).Width(), layout.Engine()->ScreenBounds( Layout::MAIN_VIEW ).Height(), white, KrBoxResource::OUTLINE ); layout.Engine()->Tree()->AddNode( 0, whereBox ); whereBox->SetVisible( false ); whereBox->SetVisible( true, Layout::MINIMAP_VIEW ); layout.Engine()->Draw(); SDL_Event event; while ( SDL_WaitEvent( &event ) ) { if ( event.type == SDL_QUIT ) break; KrEventManager::Instance()->HandleEvent( event, layout.Engine() ); bool mapChanged = false; if ( ( event.type == SDL_MOUSEMOTION || event.type == SDL_MOUSEBUTTONDOWN ) && layout.Engine()->GetWindowFromPoint( event.motion.x, event.motion.y ) == Layout::MAIN_VIEW ) { KrVector2T< GlFixed > map; worldMap->ScreenToMap( event.motion.x, event.motion.y, &map, Layout::MAIN_VIEW ); layout.DisplayMapCoords( map.x.ToFloat(), map.y.ToFloat() ); if( event.type == SDL_MOUSEBUTTONDOWN || ( event.type == SDL_MOUSEMOTION && event.motion.state == 1 ) ) { if ( logic.CurrentImage() ) { worldMap->SetLoc( map.x.ToInt(), map.y.ToInt(), logic.CurrentImage()->Clone()->ToImage() ); mapChanged = true; } } } else if ( event.type == SDL_KEYDOWN ) { if ( event.key.keysym.sym == SDLK_UP ) { worldMap->SetPos( worldMap->X(), worldMap->Y() + worldMap->TileHeight(), Layout::MAIN_VIEW ); mapChanged = true; } else if ( event.key.keysym.sym == SDLK_DOWN ) { worldMap->SetPos( worldMap->X(), worldMap->Y() - worldMap->TileHeight(), Layout::MAIN_VIEW ); mapChanged = true; } else if ( event.key.keysym.sym == SDLK_RIGHT ) { worldMap->SetPos( worldMap->X() - worldMap->TileWidth(), worldMap->Y(), Layout::MAIN_VIEW ); mapChanged = true; } else if ( event.key.keysym.sym == SDLK_LEFT ) { worldMap->SetPos( worldMap->X() + worldMap->TileWidth(), worldMap->Y(), Layout::MAIN_VIEW ); mapChanged = true; } else if ( event.key.keysym.sym >= SDLK_0 && event.key.keysym.sym <= SDLK_7 ) { layout.SetRotation( event.key.keysym.sym - SDLK_0 ); logic.SetRotation( event.key.keysym.sym - SDLK_0 ); } } if ( mapChanged ) { layout.Engine()->Tree()->Walk(); KrRect bounds = worldMap->CompositeBounds( Layout::MAIN_VIEW ); // layout.Map()->SetPos( -bounds.xmin, // - layout.Engine()->ScreenBounds( Layout::MAIN_VIEW ).xmin, // -bounds.ymin, // - layout.Engine()->ScreenBounds( Layout::MAIN_VIEW ).ymin, // Layout::MINIMAP_VIEW ); GlFixed scale = GlMin( GlFixed( layout.Engine()->ScreenBounds( Layout::MINIMAP_VIEW ).Width() ) / GlFixed( bounds.Width() ), GlFixed( layout.Engine()->ScreenBounds( Layout::MINIMAP_VIEW ).Height() ) / GlFixed( bounds.Height() ) ); layout.Map()->SetPos( 0, ( GlFixed( Layout::UI_WIDTH ) / scale ).ToInt(), Layout::MINIMAP_VIEW ); layout.Engine()->Tree()->Root()->SetScale( scale, scale, Layout::MINIMAP_VIEW ); GLOUTPUT( "Minimap scale set to %f\n", scale.ToFloat() ); whereBox->SetPos( -worldMap->X(), bounds.Height() - 1 - worldMap->Y() ); } layout.Engine()->Draw(); } } SDL_Quit(); return 0; }
void ScalingTest::DrawFrame() { if ( state == BOTH ) { scaleX.v += GlFixed_1 / 64; scaleY.v += GlFixed_1 / 64; if ( scaleX > GlFixed( 1.4 ) ) { scaleX.v = GlFixed_1 / 2; scaleY.v = GlFixed_1 / 2; state = HORIZONTAL; } } else if ( state == HORIZONTAL ) { scaleX.v += GlFixed_1 / 64; if ( scaleX > GlFixed( 1.4 ) ) { scaleX.v = GlFixed_1 / 2; scaleY.v = GlFixed_1 / 2; state = VERTICAL; } } else { scaleY.v += GlFixed_1 / 64; if ( scaleY > GlFixed( 1.4 ) ) { scaleX.v = GlFixed_1 / 8; scaleY.v = GlFixed_1 / 8; state = BOTH; } } ship->SetScale( scaleX, scaleY ); travellingShip->SetPos( travellingShip->X() - 2, travellingShip->Y() ); if ( travellingShip->X() < 0 ) { travellingShip->SetPos( engine->ScreenBounds().Width(), travellingShip->Y() ); } GlFixed tscale; tscale = 1.0 + sin( double( Frame() ) / 25.0 ) / 2.0; travellingShip->SetScale( tscale, tscale ); for( int i=0; i<3; ++i ) { canvas[i]->SetScale( scaleX, scaleY ); } char buffer[ 64 ]; sprintf( buffer, "scale: %.3f X %.3f", scaleX.ToDouble(), scaleY.ToDouble() ); textBox->SetTextChar( buffer, 0 ); textBox->SetTextChar( "Sprite", 1 ); textBox->SetTextChar( "Alpha Blended Canvas: fast -- bi-linear -- adaptive", 2 ); KrRect bounds; KrMatrix2 xForm; xForm.Set( SHIPX, SHIPY, scaleX, scaleY ); ship->SpriteResource()->GetAction( "BODY" )->CalculateBounds( 0, xForm, &bounds ); // Add the background alignment boxes. KrRGBA color;; color.Set( 255, 0, 0, 128 ); KrBoxResource* boxRes = new KrBoxResource( "databox", bounds.Width(), bounds.Height(), &color, 1, KrBoxResource::OUTLINE ); KrBox* box = new KrBox( boxRes ); box->SetPos( bounds.min.x, bounds.min.y ); engine->Tree()->AddNode( 0, box ); engine->Draw(); engine->Tree()->DeleteNode( box ); delete boxRes; }
void KrEncoder::CreateIsoTile( KrPaintInfo* info, KrConsole* console, int x, int y, int width, int height, KrRle* rle, int isoWidth, int rotation ) { if ( isoWidth % 4 ) { console->Print( "ERROR: Isometric tile created with non-multiplo of 4 width (%d).\n", isoWidth ); return; } int isoHeight = isoWidth / 2; KrPainter painter( info ); KrRGBA rgba; // Create a memory buffer to hold the tile: KrRGBA* isoMemory = new KrRGBA[ isoWidth * isoHeight ]; memset( isoMemory, 0, isoWidth * isoHeight * sizeof( KrRGBA ) ); for( int iy = 0; iy < isoHeight; ++iy ) { int rowwidth = 0; if ( iy < isoHeight / 2 ) rowwidth = 2 + 4 * iy; else rowwidth = 2 + 4 * ( isoHeight - iy - 1 ); const int QUALITY = 4; // 2, 4 const int QUALITYAREA = 16; // 4, 16 const int QUALITYBIAS = 7; // 1, 7 const GlFixed increment = GlFixed( 1 ) / GlFixed( QUALITY ); for( int ix = isoWidth / 2 - rowwidth / 2; ix < isoWidth / 2 + rowwidth / 2; ++ix ) { int red = 0, green = 0, blue = 0, alpha = 0; for ( int i=0; i<QUALITY; ++i ) { for ( int j=0; j<QUALITY; ++j ) { GlFixed fsx, fsy; int sx, sy; IsoToSource( ix + increment*i, iy - isoHeight / 2 + increment*j, isoWidth, width, height, &fsx, &fsy, rotation, increment ); //sx = fsx.ToInt(); //sy = fsy.ToInt(); sx = GlClamp( fsx.ToIntRound(), 0, width - 1 ); sy = GlClamp( fsy.ToIntRound(), 0, height - 1 ); painter.BreakPixel( sx + x, sy + y, &rgba ); red += rgba.c.red; green += rgba.c.green; blue += rgba.c.blue; alpha += rgba.c.alpha; } } // Whew! all that for one pixel. // Use rounding on the colors, to gamma-correct rgba.Set( ( red + QUALITYBIAS ) / QUALITYAREA, ( green + QUALITYBIAS ) / QUALITYAREA, ( blue + QUALITYBIAS ) / QUALITYAREA, ( alpha + QUALITYBIAS ) / QUALITYAREA ); GLASSERT( iy >= 0 && iy < isoHeight ); GLASSERT( ix >= 0 && ix < isoWidth ); isoMemory[ iy * isoWidth + ix ] = rgba; } } KrPaintInfo isoInfo( isoMemory, isoWidth, isoHeight ); rle->Create( &isoInfo, 0, 0, isoWidth, isoHeight, ( isoWidth - 1 ) / 2, ( isoHeight - 1 ) / 2, isoWidth, isoHeight ); delete [] isoMemory; }
void KrProgress::Update() { if (!m_progress || !Engine()) return; if (!m_value) { m_progress->SetVisible(false); return; } int yPos; double ScaleY, ScaleX; if (m_vertical) { ScaleX = 1.0; ScaleY = (double)m_value/m_maxValue; yPos = (int)((m_height-2) * (1-ScaleY)) + 1; } else { ScaleX = (double)m_value/m_maxValue; ScaleY = 1.0; yPos = 1; } if (m_multicolor) { float Red1 = m_FillCol.Redf(); float Red2 = m_ChangeCol.Redf(); float Green1 = m_FillCol.Greenf(); float Green2 = m_ChangeCol.Greenf(); float Blue1 = m_FillCol.Bluef(); float Blue2 = m_ChangeCol.Bluef(); float percentage = (float)m_value/(float)m_maxValue; float Red, Green, Blue; if (Red1 < Red2) Red = (Red2-Red1)*percentage + Red1; else Red = (Red1-Red2)*percentage + Red2; if (Green1 < Green2) Green = (Green2-Green1)*percentage + Green1; else Green = (Green1-Green2)*percentage + Green2; if (Blue1 < Blue2) Blue = (Blue2-Blue1)*percentage + Blue1; else Blue = (Blue1-Blue2)*percentage + Blue2; KrRGBA temp; temp.Set (Red*255, Green*255, Blue*255); if (m_progress) { if (Engine()) { Engine()->Tree()->DeleteNode(m_progress); } else { delete m_progress; } } delete m_progressres; m_progressres = new KrBoxResource( "KrProgress Bar", m_width-2, m_height-2, &temp, 1, KrBoxResource::FILL ); m_progress = new KrBox(m_progressres); if (m_progress && Engine()) { Engine()->Tree()->AddNode (this, m_progress); } } m_progress->SetPos (1, yPos); m_progress->SetScale (GlFixed(ScaleX), GlFixed(ScaleY)); m_progress->SetVisible (true); }