// credits menu Class SWWMCreditsEntry ui { String title; TextureID Sprite; int sheight; int tics, cur; BrokenLines btext; int width, height; int titlecol, btextcol; Font mSmallFont; SWWMCreditsEntry Init( String t, String b = "", int c1 = Font.CR_SAPPHIRE, int c2 = Font.CR_WHITE, String s = "" ) { mSmallFont = Font.GetFont('TewiFont'); if ( s != "" ) { Sprite = TexMan.CheckForTexture(s); Vector2 ofs = TexMan.GetScaledOffset(Sprite); sheight = int(ofs.y); } titlecol = c1; btextcol = c2; title = StringTable.Localize(t); if ( b == "" ) { width = CalcWidth(); height = CalcHeight(); return self; } String b2 = StringTable.Localize(b); btext = mSmallFont.BreakLines(b2,320); width = CalcWidth(); height = CalcHeight(); return self; } override void OnDestroy() { Super.OnDestroy(); if ( btext ) btext.Destroy(); } private int CalcWidth() { int len = mSmallFont.StringWidth(title); if ( !btext ) return len; for ( int i=0; i len ) len = len2; } return len; } private int CalcHeight() { int h = 0; if ( Sprite.IsValid() ) h = sheight; h += mSmallFont.GetHeight(); if ( !btext ) return h; h += 6; h += mSmallFont.GetHeight()*btext.Count(); return h; } double Draw( Vector2 ss, double x, double y ) { // don't draw if we're offscreen, saves time if ( (y+height < 0) || (y > ss.y) ) return height; double yy = y; if ( Sprite.IsValid() ) { yy += sheight; Screen.DrawTexture(Sprite,true,x+1,yy+1,DTA_VirtualWidthF,ss.x,DTA_VirtualHeightF,ss.y,DTA_KeepRatio,true,DTA_ColorOverlay,Color(255,0,0,0)); Screen.DrawTexture(Sprite,true,x,yy,DTA_VirtualWidthF,ss.x,DTA_VirtualHeightF,ss.y,DTA_KeepRatio,true); } int w = mSmallFont.StringWidth(title); double xx = x-w/2; Screen.DrawText(mSmallFont,titlecol,xx,yy,title,DTA_VirtualWidthF,ss.x,DTA_VirtualHeightF,ss.y,DTA_KeepRatio,true); if ( !btext ) return height; // underline int cw = int(ceil((w+8)/6.))*6; xx = x-cw/2; for ( int i=0; i cdev, cassets, cmusic, cvoice, clocal, cpatrons, cthanks; Vector2 ss; double hs; Vector2 logosz; double logow, logoh; Font mSmallFont, mBigFont; String oldmus; int oldorder; bool oldloop; const ENTRY_PAD = 8; const SECTION_PAD = 20; const SECTION_SHIFT = -4; double spos, speed; int theight; void UpdateSize() { hs = max(min(floor(Screen.GetWidth()/640.),floor(Screen.GetHeight()/360.)),1.); ss = (Screen.GetWidth(),Screen.GetHeight())/hs; } override void Init( Menu parent ) { Super.Init(parent); Animated = true; mSmallFont = Font.GetFont('TewiFont'); mBigFont = Font.GetFont('TewiFontOutline'); bgtex = TexMan.CheckForTexture("graphics/tempbg.png"); UpdateSize(); logo = TexMan.CheckForTexture("graphics/M_DEMOLITIONIST.png"); logosz = TexMan.GetScaledSize(logo); logosz *= (2./3.); logosz.y += 36.; stitle = StringTable.Localize("$SWWM_CSTITLE"); stitle2 = StringTable.Localize("$SWWM_CSTITLE2"); sdev = StringTable.Localize("$SWWM_CLEAD"); sassets = StringTable.Localize("$SWWM_CASSETS"); smusic = StringTable.Localize("$SWWM_CMUSIC"); svoice = StringTable.Localize("$SWWM_CVOICE"); slocal = StringTable.Localize("$SWWM_CLOCAL"); spatrons = StringTable.Localize("$SWWM_CPATRON"); sthanks = StringTable.Localize("$SWWM_CTHANK"); cdev.Push(new('SWWMCreditsEntry').Init("Mari the Deer","$SWWM_CDEV2",s:"graphics/Credits/MariSprite.png")); cassets.Push(new('SWWMCreditsEntry').Init("Bethesda Game Studios","Fallout: New Vegas\nFallout 4")); cassets.Push(new('SWWMCreditsEntry').Init("Epic Games","Unreal\nUnreal Tournament\nUnreal Tournament 2004\nUnreal Tournament 3")); cassets.Push(new('SWWMCreditsEntry').Init("Ion Storm","Deus Ex")); cassets.Push(new('SWWMCreditsEntry').Init("Looking Glass Studios","Thief\nSystem Shock 2")); cassets.Push(new('SWWMCreditsEntry').Init("People Can Fly","Painkiller")); cassets.Push(new('SWWMCreditsEntry').Init("Tripwire Interactive","Killing Floor")); cassets.Push(new('SWWMCreditsEntry').Init("From Software","Dark Souls\nDark Souls II\nDark Souls III")); cassets.Push(new('SWWMCreditsEntry').Init("SiFi270","$SWWM_ASSKEEN")); cassets.Push(new('SWWMCreditsEntry').Init("Nash","WidePix")); cmusic.Push(new('SWWMCreditsEntry').Init("Teque","Traumatic State\nDragony\nHidden Tune #242\nHypercardish 1.1")); cmusic.Push(new('SWWMCreditsEntry').Init("BouncyTEM","Solitary Apprehension")); cmusic.Push(new('SWWMCreditsEntry').Init("KynikossDragonn","Credits Theme")); cvoice.Push(new('SWWMCreditsEntry').Init("Vyolette","$T_DEMOLITIONIST")); clocal.Push(new('SWWMCreditsEntry').Init("Mari the Deer","$SWWM_LOCES")); cpatrons.Push(new('SWWMCreditsEntry').Init("Bean")); cpatrons.Push(new('SWWMCreditsEntry').Init("Snacks")); cpatrons.Push(new('SWWMCreditsEntry').Init("bouncytem")); cpatrons.Push(new('SWWMCreditsEntry').Init("Fantasmita")); cpatrons.Push(new('SWWMCreditsEntry').Init("Pietro Gagliardi")); cpatrons.Push(new('SWWMCreditsEntry').Init("NekoMithos")); cpatrons.Push(new('SWWMCreditsEntry').Init("Antlason Widowz")); cpatrons.Push(new('SWWMCreditsEntry').Init("YaGirlJuniper")); cthanks.Push(new('SWWMCreditsEntry').Init("KynikossDragonn","$SWWM_CDRAGON2")); cthanks.Push(new('SWWMCreditsEntry').Init("Vyolette","$SWWM_CVYOLETTE2")); cthanks.Push(new('SWWMCreditsEntry').Init("Lucy","$SWWM_CLUCY2")); cthanks.Push(new('SWWMCreditsEntry').Init("Mikolah","$SWWM_CMIKO2")); cthanks.Push(new('SWWMCreditsEntry').Init("KeksDose","$SWWM_CKEKS2")); cthanks.Push(new('SWWMCreditsEntry').Init("ZZYZX & Nash","$SWWM_CZN2")); cthanks.Push(new('SWWMCreditsEntry').Init("BouncyTEM","$SWWM_CBOUNCY2")); cthanks.Push(new('SWWMCreditsEntry').Init("a1337spy","$SWWM_CSPY2")); cthanks.Push(new('SWWMCreditsEntry').Init("\ctCptSledge\c- & \cdBunray\c-","$SWWM_CSLEDGE2")); cthanks.Push(new('SWWMCreditsEntry').Init("$SWWM_CINSP1","$SWWM_CINSP2")); cthanks.Push(new('SWWMCreditsEntry').Init("$SWWM_CCOMMUNITY1","$SWWM_CCOMMUNITY2")); cthanks.Push(new('SWWMCreditsEntry').Init("$SWWM_CYOU1","$SWWM_CYOU2")); speed = 16.; spos = ss.y-logosz.y; // calc total height theight = int(logosz.y); theight += 8*(SECTION_PAD+mBigFont.GetHeight()*2); foreach ( c:cdev ) { theight += ENTRY_PAD; theight += c.height; } foreach ( c:cassets ) { theight += ENTRY_PAD; theight += c.height; } foreach ( c:cmusic ) { theight += ENTRY_PAD; theight += c.height; } foreach ( c:cvoice ) { theight += ENTRY_PAD; theight += c.height; } foreach ( c:clocal ) { theight += ENTRY_PAD; theight += c.height; } foreach ( c:cpatrons ) { theight += ENTRY_PAD; theight += c.height; } foreach ( c:cthanks ) { theight += ENTRY_PAD; theight += c.height; } // music swap oldmus = musplaying.name; oldorder = musplaying.baseorder; oldloop = musplaying.loop; S_ChangeMusic("music/swwmgz_c.it"); } double DrawLogo( double x, double y ) { // don't draw if we're offscreen, saves time if ( (y+logosz.y < 0) || (y > ss.y) ) return logosz.y; Screen.DrawTexture(logo,true,x-logosz.x/2,y,DTA_VirtualWidthF,ss.x,DTA_VirtualHeightF,ss.y,DTA_KeepRatio,true,DTA_ScaleX,(2./3.),DTA_ScaleY,(2./3.)); Screen.DrawText(mSmallFont,Font.CR_SAPPHIRE,x-mSmallFont.StringWidth(stitle)/2,y+(logosz.y-28),stitle,DTA_VirtualWidthF,ss.x,DTA_VirtualHeightF,ss.y,DTA_KeepRatio,true); // underline int w = max(mSmallFont.StringWidth(stitle),mSmallFont.StringWidth(stitle2)); int cw = int(ceil((w+8)/6.))*6; double xx = x-cw/2; for ( int i=0; i ss.y) ) return mBigFont.GetHeight()*2; Screen.DrawText(mBigFont,Font.CR_BLUE,x-mBigFont.StringWidth(txt),y,txt,DTA_VirtualWidthF,ss.x,DTA_VirtualHeightF,ss.y,DTA_KeepRatio,true,DTA_ScaleX,2,DTA_ScaleY,2); return mBigFont.GetHeight()*2; } override void Drawer() { if ( swwm_fuzz ) { Vector2 tsize = TexMan.GetScaledSize(bgtex); double zoom = max(ceil(Screen.GetWidth()/tsize.x),ceil(Screen.GetHeight()/tsize.y)); Vector2 vsize = (Screen.GetWidth(),Screen.GetHeight())/zoom; Screen.DrawTexture(bgtex,false,(vsize.x-tsize.x)/2,(vsize.y-tsize.y)/2,DTA_VirtualWidthF,vsize.x,DTA_VirtualHeightF,vsize.y,DTA_KeepRatio,true,DTA_ColorOverlay,Color(192,0,0,0),DTA_Alpha,.8); } else Screen.Dim(0xFF000000,.8,0,0,Screen.GetWidth(),Screen.GetHeight()); Super.Drawer(); UpdateSize(); // logo double yy = spos-((speed*System.GetTimeFrac())/GameTicRate); double xx = ss.x/2.; yy += DrawLogo(xx,yy); // developer yy += SECTION_PAD; yy += DrawSection(xx,yy,sdev); foreach ( c:cdev ) { yy += ENTRY_PAD; yy += c.Draw(ss,xx,yy); } // assets yy += SECTION_PAD; yy += DrawSection(xx,yy,sassets); foreach ( c:cassets ) { yy += ENTRY_PAD; yy += c.Draw(ss,xx,yy); } // music yy += SECTION_PAD; yy += DrawSection(xx,yy,smusic); foreach ( c:cmusic ) { yy += ENTRY_PAD; yy += c.Draw(ss,xx,yy); } // voices yy += SECTION_PAD; yy += DrawSection(xx,yy,svoice); foreach ( c:cvoice ) { yy += ENTRY_PAD; yy += c.Draw(ss,xx,yy); } // localization yy += SECTION_PAD; yy += DrawSection(xx,yy,slocal); foreach ( c:clocal ) { yy += ENTRY_PAD; yy += c.Draw(ss,xx,yy); } // patrons yy += SECTION_PAD; yy += DrawSection(xx,yy,spatrons); foreach ( c:cpatrons ) { yy += ENTRY_PAD; yy += c.Draw(ss,xx,yy); } // thanks yy += SECTION_PAD; yy += DrawSection(xx,yy,sthanks); foreach ( c:cthanks ) { yy += ENTRY_PAD; yy += c.Draw(ss,xx,yy); } } override void Ticker() { spos -= speed/GameTicRate; if ( spos < -theight ) spos = ss.y; if ( spos > ss.y ) spos = -theight; } override bool TranslateKeyboardEvents() { return false; } override bool OnUIEvent( UIEvent ev ) { switch ( ev.type ) { case UIEvent.Type_KeyDown: if ( ev.KeyChar == UIEvent.Key_Escape ) { // gotta manually send this one MenuEvent(MKEY_Back,false); return true; } if ( ev.KeyChar == UIEvent.Key_Backspace ) { spos = (ss.y-logoh)/2; speed = 16.; return true; } if ( ev.KeyChar == UIEvent.Key_Down ) { speed = 48.; return true; } if ( ev.KeyChar == UIEvent.Key_PgDn ) { speed = 96.; return true; } if ( ev.KeyChar == UIEvent.Key_Up ) { speed = -48.; return true; } if ( ev.KeyChar == UIEvent.Key_PgUp ) { speed = -96.; return true; } if ( ev.KeyChar == UIEvent.Key_Return ) { speed = 0.; return true; } break; case UIEvent.Type_KeyUp: if ( (ev.KeyChar == UIEvent.Key_Down) || (ev.KeyChar == UIEvent.Key_Up) || (ev.KeyChar == UIEvent.Key_PgDn) || (ev.KeyChar == UIEvent.Key_PgUp) || (ev.KeyChar == UIEvent.Key_Return) ) { speed = 16.; return true; } break; } return Super.OnUIEvent(ev); } override bool MenuEvent( int mkey, bool fromcontroller ) { switch ( mkey ) { case MKEY_Back: // reset music S_ChangeMusic(oldmus,oldorder,oldloop); Close(); let m = GetCurrentMenu(); MenuSound(m?"menu/backup":"menu/clear"); if ( !m ) menuDelegate.MenuDismissed(); return true; } return false; } }