code:
#include "common.h"

#include "Timer.h"
#include "Font.h"
#include "Frontend.h"
#include "RwHelper.h"
#include "Camera.h"
#include "Text.h"
#include "Credits.h"

bool CCredits::bCreditsGoing;
uint32 CCredits::CreditsStartTime;

void
CCredits::Init(void)
{
	Stop();
}

void
CCredits::Start(void)
{
	bCreditsGoing = true;
	CreditsStartTime = CTimer::GetTimeInMilliseconds();
}

void
CCredits::Stop(void)
{
	bCreditsGoing = false;
}

void
CCredits::PrintCreditSpace(float space, uint32 &line)
{
	line += space * 25.0f;
}

void
CCredits::PrintCreditText(float scaleX, float scaleY, wchar *text, uint32 &lineoffset, float scrolloffset)
{
#ifdef FIX_BUGS
	float start = DEFAULT_SCREEN_HEIGHT + 50.0f;
#else
	float start = SCREEN_HEIGHT + 50.0f;
#endif
	float y = lineoffset + start - scrolloffset;
	if(y > -50.0f && y < start){
#ifdef FIX_BUGS
		CFont::SetScale(SCREEN_SCALE_X(scaleX), SCREEN_SCALE_Y(scaleY));
		CFont::PrintString(SCREEN_WIDTH/2.0f, SCREEN_SCALE_Y(y), (uint16*)text);
#else
		CFont::SetScale(scaleX, scaleY);
		CFont::PrintString(SCREEN_WIDTH/2.0f, y, (uint16*)text);
#endif
	}
	lineoffset += scaleY*25.0f;
}

void
CCredits::Render(void)
{
	uint32 lineoffset;
	float scrolloffset;

	if(!bCreditsGoing || FrontEndMenuManager.m_bMenuActive)
		return;

	DefinedState();
	lineoffset = 0;
	scrolloffset = (CTimer::GetTimeInMilliseconds() - CreditsStartTime) / 24.0f;
	CFont::SetJustifyOff();
	CFont::SetBackgroundOff();
#ifdef FIX_BUGS
	CFont::SetCentreSize(SCREEN_SCALE_X(DEFAULT_SCREEN_WIDTH - 20));
#else
	CFont::SetCentreSize(SCREEN_WIDTH - 20);
#endif
	CFont::SetCentreOn();
	CFont::SetPropOn();
	CFont::SetColor(CRGBA(220, 220, 220, 220));
	CFont::SetFontStyle(FONT_HEADING);

	PrintCreditSpace(2.0f, lineoffset);
	PrintCreditText(1.7f, 1.0f, TheText.Get("CRED002"), lineoffset, scrolloffset);
	PrintCreditText(1.7f, 1.7f, TheText.Get("CRED003"), lineoffset, scrolloffset);
	PrintCreditSpace(2.0f, lineoffset);
	PrintCreditText(1.7f, 1.0f, TheText.Get("CRED004"), lineoffset, scrolloffset);
	PrintCreditText(1.7f, 1.7f, TheText.Get("CRED005"), lineoffset, scrolloffset);
	PrintCreditSpace(2.0f, lineoffset);
	PrintCreditText(1.7f, 1.0f, TheText.Get("CRED006"), lineoffset, scrolloffset);
	PrintCreditText(1.7f, 1.7f, TheText.Get("CRED007"), lineoffset, scrolloffset);
	PrintCreditText(1.7f, 1.7f, TheText.Get("CRED008"), lineoffset, scrolloffset);
	PrintCreditSpace(2.0f, lineoffset);
	PrintCreditSpace(2.0f, lineoffset);
	PrintCreditText(1.7f, 1.0f, TheText.Get("CRED009"), lineoffset, scrolloffset);
	PrintCreditText(1.7f, 1.7f, TheText.Get("CRED010"), lineoffset, scrolloffset);
	PrintCreditText(1.7f, 1.7f, TheText.Get("CRED011"), lineoffset, scrolloffset);
	PrintCreditText(1.7f, 1.7f, TheText.Get("CRED012"), lineoffset, scrolloffset);
	PrintCreditText(1.7f, 1.7f, TheText.Get("CRED013"), lineoffset, scrolloffset);
	PrintCreditSpace(2.0f, lineoffset);
	PrintCreditText(1.7f, 1.0f, TheText.Get("CRED014"), lineoffset, scrolloffset);
	PrintCreditText(1.7f, 1.7f, TheText.Get("CRED015"), lineoffset, scrolloffset);
	PrintCreditText(1.7f, 1.7f, TheText.Get("CRED016"), lineoffset, scrolloffset);
	PrintCreditText(1.7f, 1.7f, TheText.Get("CRED017"), lineoffset, scrolloffset);
	PrintCreditSpace(2.0f, lineoffset);
	PrintCreditSpace(2.0f, lineoffset);
	PrintCreditText(1.7f, 1.0f, TheText.Get("CRED018"), lineoffset, scrolloffset);
	PrintCreditText(1.7f, 1.7f, TheText.Get("CRED019"), lineoffset, scrolloffset);
	PrintCreditSpace(2.0f, lineoffset);
	PrintCreditText(1.4f, 0.82f, TheText.Get("CRED020"), lineoffset, scrolloffset);
	PrintCreditText(1.7f, 1.7f, TheText.Get("CRED021"), lineoffset, scrolloffset);
	PrintCreditText(1.7f, 1.7f, TheText.Get("CRED022"), lineoffset, scrolloffset);
	PrintCreditText(1.7f, 1.7f, TheText.Get("CRED245"), lineoffset, scrolloffset);
	PrintCreditSpace(2.0f, lineoffset);
	PrintCreditText(1.7f, 1.0f, TheText.Get("CRED023"), lineoffset, scrolloffset);
	PrintCreditText(1.7f, 1.7f, TheText.Get("CRED024"), lineoffset, scrolloffset);
	PrintCreditSpace(2.0f, lineoffset);
	PrintCreditText(1.7f, 1.0f, TheText.Get("CRED025"), lineoffset, scrolloffset);
	PrintCreditText(1.7f, 1.7f, TheText.Get("CRED026"), lineoffset, scrolloffset);
	PrintCreditText(1.7f, 1.7f, TheText.Get("CRED027"), lineoffset, scrolloffset);
	PrintCreditText(1.7f, 1.7f, TheText.Get("CRED028"), lineoffset, scrolloffset);
	PrintCreditText(1.7f, 1.7f, TheText.Get("CRED257"), lineoffset, scrolloffset);
	PrintCreditText(1.7f, 1.7f, TheText.Get("CRED029"), lineoffset, scrolloffset);
	PrintCreditText(1.7f, 1.7f, TheText.Get("CRED030"), lineoffset, scrolloffset);
	PrintCreditText(1.7f, 1.7f, TheText.Get("CRED031"), lineoffset, scrolloffset);
	PrintCreditSpace(2.0f, lineoffset);
	PrintCreditSpace(2.0f, lineoffset);
	PrintCreditText(1.7f, 1.0f, TheText.Get("CRED032"), lineoffset, scrolloffset);
	PrintCreditText(1.7f, 1.7f, TheText.Get("CRED033"), lineoffset, scrolloffset);
	PrintCreditText(1.7f, 1.7f, TheText.Get("CRED244"), lineoffset, scrolloffset);
	PrintCreditText(1.7f, 1.7f, TheText.Get("CRED034"), lineoffset, scrolloffset);
	PrintCreditText(1.7f, 1.7f, TheText.Get("CRED035"), lineoffset, scrolloffset);
	PrintCreditText(1.7f, 1.7f, TheText.Get("CRED247"), lineoffset, scrolloffset);
	PrintCreditText(1.7f, 1.7f, TheText.Get("CRED036"), lineoffset, scrolloffset);
	PrintCreditText(1.7f, 1.7f, TheText.Get("CRED037"), lineoffset, scrolloffset);
	PrintCreditSpace(2.0f, lineoffset);
	PrintCreditSpace(2.0f, lineoffset);
	PrintCreditText(1.7f, 1.0f, TheText.Get("CRED038"), lineoffset, scrolloffset);
	PrintCreditText(1.7f, 1.7f, TheText.Get("CRED039"), lineoffset, scrolloffset);
	PrintCreditText(1.7f, 1.7f, TheText.Get("CRED040"), lineoffset, scrolloffset);
	PrintCreditSpace(2.0f, lineoffset);
	PrintCreditText(1.4f, 0.82f, TheText.Get("CRED041"), lineoffset, scrolloffset);
	if(CMenuManager::m_PrefsLanguage == CMenuManager::LANGUAGE_ITALIAN)
	        PrintCreditSpace(1.5f, lineoffset);
	PrintCreditText(1.7f, 1.7f, TheText.Get("CRED042"), lineoffset, scrolloffset);
	PrintCreditSpace(2.0f, lineoffset);
	PrintCreditText(1.7f, 1.0f, TheText.Get("CRED043"), lineoffset, scrolloffset);
	if(CMenuManager::m_PrefsLanguage == CMenuManager::LANGUAGE_ITALIAN)
	        PrintCreditSpace(1.5f, lineoffset);
	PrintCreditText(1.7f, 1.7f, TheText.Get("CRED044"), lineoffset, scrolloffset);
	PrintCreditSpace(2.0f, lineoffset);
	PrintCreditSpace(2.0f, lineoffset);
	PrintCreditText(1.7f, 1.0f, TheText.Get("CRED045"), lineoffset, scrolloffset);
	PrintCreditText(1.7f, 1.7f, TheText.Get("CRED046"), lineoffset, scrolloffset);
	PrintCreditSpace(2.0f, lineoffset);
	PrintCreditText(1.7f, 1.0f, TheText.Get("CRED047"), lineoffset, scrolloffset);
	PrintCreditText(1.7f, 1.7f, TheText.Get("CRED048"), lineoffset, scrolloffset);
	PrintCreditText(1.7f, 1.7f, TheText.Get("CRED049"), lineoffset, scrolloffset);
	PrintCreditText(1.7f, 1.7f, TheText.Get("CRED050"), lineoffset, scrolloffset);
	PrintCreditSpace(2.0f, lineoffset);
	PrintCreditText(1.7f, 1.0f, TheText.Get("CRD050A"), lineoffset, scrolloffset);
	PrintCreditText(1.7f, 1.7f, TheText.Get("CRED051"), lineoffset, scrolloffset);
	PrintCreditText(1.7f, 1.7f, TheText.Get("CRED052"), lineoffset, scrolloffset);
	PrintCreditText(1.7f, 1.7f, TheText.Get("CRED053"), lineoffset, scrolloffset);
	PrintCreditText(1.7f, 1.7f, TheText.Get("CRED054"), lineoffset, scrolloffset);
	PrintCreditText(1.7f, 1.7f, TheText.Get("CRED055"), lineoffset, scrolloffset);
	PrintCreditText(1.7f, 1.7f, TheText.Get("CRED056"), lineoffset, scrolloffset);
	PrintCreditText(1.7f, 1.7f, TheText.Get("CRED248"), lineoffset, scrolloffset);
	PrintCreditText(1.7f, 1.7f, TheText.Get("CRED249"), lineoffset, scrolloffset);
	PrintCreditText(1.7f, 1.7f, TheText.Get("CRED250"), lineoffset, scrolloffset);
	PrintCreditText(1.7f, 1.7f, TheText.Get("CRED251"), lineoffset, scrolloffset);
	PrintCreditText(1.7f, 1.7f, TheText.Get("CRED252"), lineoffset, scrolloffset);
	PrintCreditText(1.7f, 1.7f, TheText.Get("CRED253"), lineoffset, scrolloffset);
	PrintCreditSpace(2.0f, lineoffset);
	PrintCreditSpace(2.0f, lineoffset);
	PrintCreditText(1.7f, 1.0f, TheText.Get("CRED057"), lineoffset, scrolloffset);
	PrintCreditText(1.7f, 1.7f, TheText.Get("CRED058"), lineoffset, scrolloffset);
	PrintCreditText(1.7f, 1.7f, TheText.Get("CRED059"), lineoffset, scrolloffset);
	PrintCreditSpace(2.0f, lineoffset);
	PrintCreditSpace(2.0f, lineoffset);
	PrintCreditText(1.7f, 1.0f, TheText.Get("CRED254"), lineoffset, scrolloffset);
	PrintCreditText(1.7f, 1.7f, TheText.Get("CRED255"), lineoffset, scrolloffset);
	PrintCreditSpace(2.0f, lineoffset);
	PrintCreditSpace(2.0f, lineoffset);
	PrintCreditSpace(2.0f, lineoffset);
	PrintCreditSpace(2.0f, lineoffset);
	PrintCreditText(1.7f, 1.0f, TheText.Get("CRED060"), lineoffset, scrolloffset);
	PrintCreditSpace(2.0f, lineoffset);
	PrintCreditSpace(2.0f, lineoffset);
	PrintCreditText(1.7f, 1.0f, TheText.Get("CRED061"), lineoffset, scrolloffset);
	if(CMenuManager::m_PrefsLanguage == CMenuManager::LANGUAGE_ITALIAN)
	        PrintCreditSpace(1.5f, lineoffset);
	PrintCreditText(1.7f, 1.7f, TheText.Get("CRED062"), lineoffset, scrolloffset);
	PrintCreditSpace(2.0f, lineoffset);
	PrintCreditText(1.7f, 1.0f, TheText.Get("CRED063"), lineoffset, scrolloffset);
	PrintCreditText(1.7f, 1.7f, TheText.Get("CRED064"), lineoffset, scrolloffset);
	PrintCreditSpace(2.0f, lineoffset);
	PrintCreditText(1.7f, 1.0f, TheText.Get("CRED065"), lineoffset, scrolloffset);
	PrintCreditSpace(1.5f, lineoffset);
	PrintCreditText(1.7f, 1.7f, TheText.Get("CRED066"), lineoffset, scrolloffset);
	PrintCreditSpace(2.0f, lineoffset);
	PrintCreditText(1.7f, 1.0f, TheText.Get("CRED067"), lineoffset, scrolloffset);
	PrintCreditText(1.7f, 1.7f, TheText.Get("CRED068"), lineoffset, scrolloffset);
	PrintCreditSpace(2.0f, lineoffset);
	PrintCreditText(1.7f, 1.0f, TheText.Get("CRED069"), lineoffset, scrolloffset);
	if(CMenuManager::m_PrefsLanguage == CMenuManager::LANGUAGE_ITALIAN)
	        PrintCreditSpace(1.5f, lineoffset);
	PrintCreditText(1.7f, 1.7f, TheText.Get("CRED070"), lineoffset, scrolloffset);
	PrintCreditSpace(2.0f, lineoffset);
	PrintCreditText(1.7f, 1.0f, TheText.Get("CRED071"), lineoffset, scrolloffset);
	PrintCreditSpace(1.5f, lineoffset);
	PrintCreditText(1.7f, 1.7f, TheText.Get("CRED072"), lineoffset, scrolloffset);
	PrintCreditSpace(2.0f, lineoffset);
	PrintCreditSpace(2.0f, lineoffset);
	PrintCreditText(1.7f, 1.0f, TheText.Get("CRED073"), lineoffset, scrolloffset);
	PrintCreditSpace(1.5f, lineoffset);
	PrintCreditText(1.7f, 1.7f, TheText.Get("CRED074"), lineoffset, scrolloffset);
	PrintCreditText(1.7f, 1.7f, TheText.Get("CRED075"), lineoffset, scrolloffset);
	PrintCreditText(1.7f, 1.7f, TheText.Get("CRED076"), lineoffset, scrolloffset);
	PrintCreditText(1.7f, 1.7f, TheText.Get("CRED077"), lineoffset, scrolloffset);
	PrintCreditText(1.7f, 1.7f, TheText.Get("CRED078"), lineoffset, scrolloffset);
	PrintCreditText(1.7f, 1.7f, TheText.Get("CRED079"), lineoffset, scrolloffset);
	PrintCreditText(1.7f, 1.7f, TheText.Get("CRED080"), lineoffset, scrolloffset);
	PrintCreditText(1.7f, 1.7f, TheText.Get("CRED081"), lineoffset, scrolloffset);
	PrintCreditText(1.7f, 1.7f, TheText.Get("CRED082"), lineoffset, scrolloffset);
	PrintCreditText(1.7f, 1.7f, TheText.Get("CRED083"), lineoffset, scrolloffset);
	PrintCreditText(1.7f, 1.7f, TheText.Get("CRED084"), lineoffset, scrolloffset);
	PrintCreditText(1.7f, 1.7f, TheText.Get("CRED242"), lineoffset, scrolloffset);
	PrintCreditText(1.7f, 1.7f, TheText.Get("CRED259"), lineoffset, scrolloffset);
	PrintCreditText(1.7f, 1.7f, TheText.Get("CRED260"), lineoffset, scrolloffset);
	PrintCreditText(1.7f, 1.7f, TheText.Get("CRED261"), lineoffset, scrolloffset);
	PrintCreditText(1.7f, 1.7f, TheText.Get("CRED262"), lineoffset, scrolloffset);
	PrintCreditSpace(2.0f, lineoffset);
	PrintCreditText(1.7f, 1.0f, TheText.Get("CRED085"), lineoffset, scrolloffset);
	if(CMenuManager::m_PrefsLanguage == CMenuManager::LANGUAGE_ITALIAN)
	        PrintCreditSpace(1.5f, lineoffset);
	PrintCreditText(1.7f, 1.7f, TheText.Get("CRED086"), lineoffset, scrolloffset);
	PrintCreditSpace(2.0f, lineoffset);
	PrintCreditText(1.4f, 0.82f, TheText.Get("CRED087"), lineoffset, scrolloffset);
	PrintCreditSpace(1.5f, lineoffset);
	PrintCreditText(1.7f, 1.7f, TheText.Get("CRED088"), lineoffset, scrolloffset);
	PrintCreditSpace(2.0f, lineoffset);
	PrintCreditSpace(2.0f, lineoffset);
	PrintCreditText(1.7f, 1.0f, TheText.Get("CRED089"), lineoffset, scrolloffset);
	PrintCreditSpace(1.5f, lineoffset);
	PrintCreditText(1.7f, 1.7f, TheText.Get("CRED090"), lineoffset, scrolloffset);
	PrintCreditSpace(2.0f, lineoffset);
	PrintCreditText(1.7f, 1.0f, TheText.Get("CRED091"), lineoffset, scrolloffset);
	PrintCreditText(1.7f, 1.7f, TheText.Get("CRED094"), lineoffset, scrolloffset);
	PrintCreditSpace(2.0f, lineoffset);
	PrintCreditText(1.7f, 1.0f, TheText.Get("CRED095"), lineoffset, scrolloffset);
	PrintCreditText(1.7f, 1.7f, TheText.Get("CRED096"), lineoffset, scrolloffset);
	PrintCreditText(1.7f, 1.7f, TheText.Get("CRED097"), lineoffset, scrolloffset);
	PrintCreditText(1.7f, 1.7f, TheText.Get("CRED098"), lineoffset, scrolloffset);
	PrintCreditText(1.7f, 1.7f, TheText.Get("CRED099"), lineoffset, scrolloffset);
	PrintCreditText(1.7f, 1.7f, TheText.Get("CRED263"), lineoffset, scrolloffset);
	PrintCreditText(1.7f, 1.7f, TheText.Get("CRED264"), lineoffset, scrolloffset);
	PrintCreditText(1.7f, 1.7f, TheText.Get("CRED265"), lineoffset, scrolloffset);
	PrintCreditText(1.7f, 1.7f, TheText.Get("CRED267"), lineoffset, scrolloffset);
	PrintCreditText(1.7f, 1.7f, TheText.Get("CRED270"), lineoffset, scrolloffset);
	PrintCreditText(1.7f, 1.7f, TheText.Get("CRED266"), lineoffset, scrolloffset);
	PrintCreditSpace(2.0f, lineoffset);
	PrintCreditSpace(2.0f, lineoffset);
	PrintCreditText(1.4f, 0.82f, TheText.Get("CRED100"), lineoffset, scrolloffset);
	PrintCreditSpace(1.5f, lineoffset);
	PrintCreditText(1.7f, 1.7f, TheText.Get("CRED101"), lineoffset, scrolloffset);
	PrintCreditText(1.7f, 1.7f, TheText.Get("CRED102"), lineoffset, scrolloffset);
	PrintCreditText(1.7f, 1.7f, TheText.Get("CRED103"), lineoffset, scrolloffset);
	PrintCreditText(1.7f, 1.7f, TheText.Get("CRED104"), lineoffset, scrolloffset);
	PrintCreditText(1.7f, 1.7f, TheText.Get("CRED105"), lineoffset, scrolloffset);
	PrintCreditText(1.7f, 1.7f, TheText.Get("CRED106"), lineoffset, scrolloffset);
	PrintCreditText(1.7f, 1.7f, TheText.Get("CRED268"), lineoffset, scrolloffset);
	PrintCreditText(1.7f, 1.7f, TheText.Get("CRED269"), lineoffset, scrolloffset);
	PrintCreditSpace(2.0f, lineoffset);
	PrintCreditText(1.7f, 1.0f, TheText.Get("CRED107"), lineoffset, scrolloffset);
	PrintCreditSpace(1.5f, lineoffset);
	PrintCreditText(1.0f, 1.0f, TheText.Get("CRED108"), lineoffset, scrolloffset);
	PrintCreditSpace(1.0f, lineoffset);
	PrintCreditText(1.0f, 1.0f, TheText.Get("CRED109"), lineoffset, scrolloffset);
	if(CMenuManager::m_PrefsLanguage == CMenuManager::LANGUAGE_ITALIAN)
	        PrintCreditSpace(1.0f, lineoffset);
	PrintCreditText(1.0f, 1.0f, TheText.Get("CRED110"), lineoffset, scrolloffset);
	PrintCreditSpace(2.0f, lineoffset);
	PrintCreditText(1.7f, 1.0f, TheText.Get("CRED111"), lineoffset, scrolloffset);
	PrintCreditText(1.0f, 1.0f, TheText.Get("CRED112"), lineoffset, scrolloffset);
	if(CMenuManager::m_PrefsLanguage == CMenuManager::LANGUAGE_ITALIAN)
	        PrintCreditSpace(1.0f, lineoffset);
	PrintCreditText(1.0f, 1.0f, TheText.Get("CRED113"), lineoffset, scrolloffset);
	if(CMenuManager::m_PrefsLanguage == CMenuManager::LANGUAGE_ITALIAN)
	        PrintCreditSpace(1.0f, lineoffset);
	PrintCreditText(1.0f, 1.0f, TheText.Get("CRED114"), lineoffset, scrolloffset);
	if(CMenuManager::m_PrefsLanguage == CMenuManager::LANGUAGE_ITALIAN)
	        PrintCreditSpace(1.0f, lineoffset);
	PrintCreditText(1.0f, 1.0f, TheText.Get("CRED115"), lineoffset, scrolloffset);
	if(CMenuManager::m_PrefsLanguage == CMenuManager::LANGUAGE_ITALIAN)
	        PrintCreditSpace(1.0f, lineoffset);
	PrintCreditText(1.0f, 1.0f, TheText.Get("CRED116"), lineoffset, scrolloffset);
	if(CMenuManager::m_PrefsLanguage == CMenuManager::LANGUAGE_ITALIAN)
	        PrintCreditSpace(1.0f, lineoffset);
	PrintCreditText(1.0f, 1.0f, TheText.Get("CRED117"), lineoffset, scrolloffset);
	if(CMenuManager::m_PrefsLanguage == CMenuManager::LANGUAGE_ITALIAN)
	        PrintCreditSpace(1.0f, lineoffset);
	PrintCreditText(1.0f, 1.0f, TheText.Get("CRED118"), lineoffset, scrolloffset);
	if(CMenuManager::m_PrefsLanguage == CMenuManager::LANGUAGE_ITALIAN)
	        PrintCreditSpace(1.0f, lineoffset);
	PrintCreditText(1.0f, 1.0f, TheText.Get("CRED119"), lineoffset, scrolloffset);
	if(CMenuManager::m_PrefsLanguage == CMenuManager::LANGUAGE_ITALIAN)
	        PrintCreditSpace(1.0f, lineoffset);
	PrintCreditText(1.0f, 1.0f, TheText.Get("CRED120"), lineoffset, scrolloffset);
	if(CMenuManager::m_PrefsLanguage == CMenuManager::LANGUAGE_ITALIAN)
	        PrintCreditSpace(1.0f, lineoffset);
	PrintCreditText(1.0f, 1.0f, TheText.Get("CRED121"), lineoffset, scrolloffset);
	if(CMenuManager::m_PrefsLanguage == CMenuManager::LANGUAGE_ITALIAN)
	        PrintCreditSpace(1.0f, lineoffset);
	PrintCreditText(1.0f, 1.0f, TheText.Get("CRED122"), lineoffset, scrolloffset);
	if(CMenuManager::m_PrefsLanguage == CMenuManager::LANGUAGE_ITALIAN)
	        PrintCreditSpace(1.0f, lineoffset);
	PrintCreditText(1.0f, 1.0f, TheText.Get("CRED123"), lineoffset, scrolloffset);
	if(CMenuManager::m_PrefsLanguage == CMenuManager::LANGUAGE_ITALIAN)
	        PrintCreditSpace(1.0f, lineoffset);
	PrintCreditText(1.0f, 1.0f, TheText.Get("CRED124"), lineoffset, scrolloffset);
	if(CMenuManager::m_PrefsLanguage == CMenuManager::LANGUAGE_ITALIAN)
	        PrintCreditSpace(1.0f, lineoffset);
	PrintCreditText(1.0f, 1.0f, TheText.Get("CRED125"), lineoffset, scrolloffset);
	if(CMenuManager::m_PrefsLanguage == CMenuManager::LANGUAGE_ITALIAN)
	        PrintCreditSpace(1.0f, lineoffset);
	PrintCreditText(1.0f, 1.0f, TheText.Get("CRED126"), lineoffset, scrolloffset);
	if(CMenuManager::m_PrefsLanguage == CMenuManager::LANGUAGE_ITALIAN)
	        PrintCreditSpace(1.0f, lineoffset);
	PrintCreditText(1.0f, 1.0f, TheText.Get("CRED127"), lineoffset, scrolloffset);
	if(CMenuManager::m_PrefsLanguage == CMenuManager::LANGUAGE_ITALIAN)
	        PrintCreditSpace(1.0f, lineoffset);
	PrintCreditText(1.0f, 1.0f, TheText.Get("CRED128"), lineoffset, scrolloffset);
	if(CMenuManager::m_PrefsLanguage == CMenuManager::LANGUAGE_ITALIAN)
	        PrintCreditSpace(1.0f, lineoffset);
	PrintCreditText(1.0f, 1.0f, TheText.Get("CRED129"), lineoffset, scrolloffset);
	if(CMenuManager::m_PrefsLanguage == CMenuManager::LANGUAGE_ITALIAN)
	        PrintCreditSpace(1.0f, lineoffset);
	PrintCreditText(1.0f, 1.0f, TheText.Get("CRED130"), lineoffset, scrolloffset);
	if(CMenuManager::m_PrefsLanguage == CMenuManager::LANGUAGE_ITALIAN)
	        PrintCreditSpace(1.0f, lineoffset);
	PrintCreditText(1.0f, 1.0f, TheText.Get("CRED131"), lineoffset, scrolloffset);
	if(CMenuManager::m_PrefsLanguage == CMenuManager::LANGUAGE_ITALIAN)
	        PrintCreditSpace(1.0f, lineoffset);
	PrintCreditText(1.0f, 1.0f, TheText.Get("CRED132"), lineoffset, scrolloffset);
	if(CMenuManager::m_PrefsLanguage == CMenuManager::LANGUAGE_ITALIAN)
	        PrintCreditSpace(1.0f, lineoffset);
	PrintCreditText(1.0f, 1.0f, TheText.Get("CRED133"), lineoffset, scrolloffset);
	if(CMenuManager::m_PrefsLanguage == CMenuManager::LANGUAGE_ITALIAN)
	        PrintCreditSpace(1.0f, lineoffset);
	PrintCreditText(1.0f, 1.0f, TheText.Get("CRED134"), lineoffset, scrolloffset);
	PrintCreditSpace(2.0f, lineoffset);
	PrintCreditText(1.7f, 1.0f, TheText.Get("CRED135"), lineoffset, scrolloffset);
	PrintCreditText(1.7f, 1.0f, TheText.Get("CRED136"), lineoffset, scrolloffset);
	PrintCreditText(1.7f, 1.7f, TheText.Get("CRD136A"), lineoffset, scrolloffset);
	PrintCreditSpace(2.0f, lineoffset);
	PrintCreditText(1.7f, 1.0f, TheText.Get("CRED137"), lineoffset, scrolloffset);
	PrintCreditText(1.7f, 1.7f, TheText.Get("CRD137A"), lineoffset, scrolloffset);
	PrintCreditSpace(2.0f, lineoffset);
	PrintCreditText(1.7f, 1.0f, TheText.Get("CRED138"), lineoffset, scrolloffset);
	PrintCreditText(1.7f, 1.7f, TheText.Get("CRD138A"), lineoffset, scrolloffset);
	PrintCreditText(1.7f, 1.7f, TheText.Get("CRD138B"), lineoffset, scrolloffset);
	PrintCreditSpace(2.0f, lineoffset);
	PrintCreditText(1.0f, 1.0f, TheText.Get("CRED139"), lineoffset, scrolloffset);
	PrintCreditSpace(2.0f, lineoffset);
	PrintCreditText(1.7f, 1.0f, TheText.Get("CRED140"), lineoffset, scrolloffset);
	PrintCreditText(1.7f, 1.7f, TheText.Get("CRD140A"), lineoffset, scrolloffset);
	PrintCreditText(1.7f, 1.7f, TheText.Get("CRD140B"), lineoffset, scrolloffset);
	PrintCreditText(1.7f, 1.7f, TheText.Get("CRD140C"), lineoffset, scrolloffset);
	PrintCreditText(1.7f, 1.7f, TheText.Get("CRD140D"), lineoffset, scrolloffset);
	PrintCreditText(1.7f, 1.7f, TheText.Get("CRD140E"), lineoffset, scrolloffset);
	PrintCreditSpace(2.0f, lineoffset);
	PrintCreditText(1.4f, 0.82f, TheText.Get("CRED141"), lineoffset, scrolloffset);
	PrintCreditText(1.0f, 1.0f, TheText.Get("CRED142"), lineoffset, scrolloffset);
	PrintCreditSpace(1.0f, lineoffset);
	PrintCreditText(1.0f, 1.0f, TheText.Get("CRED143"), lineoffset, scrolloffset);
	PrintCreditSpace(1.0f, lineoffset);
	PrintCreditText(1.0f, 1.0f, TheText.Get("CRED144"), lineoffset, scrolloffset);
	PrintCreditSpace(1.0f, lineoffset);
	PrintCreditSpace(2.0f, lineoffset);
	PrintCreditText(1.4f, 0.82f, TheText.Get("CRED145"), lineoffset, scrolloffset);
	PrintCreditText(1.4f, 1.4f, TheText.Get("CRED146"), lineoffset, scrolloffset);
	PrintCreditText(1.4f, 1.4f, TheText.Get("CRED147"), lineoffset, scrolloffset);
	PrintCreditText(1.4f, 1.4f, TheText.Get("CRED148"), lineoffset, scrolloffset);
	PrintCreditText(1.4f, 1.4f, TheText.Get("CRED149"), lineoffset, scrolloffset);
	PrintCreditText(1.4f, 1.4f, TheText.Get("CRED150"), lineoffset, scrolloffset);
	PrintCreditText(1.4f, 1.4f, TheText.Get("CRED151"), lineoffset, scrolloffset);
	PrintCreditText(1.4f, 1.4f, TheText.Get("CRED152"), lineoffset, scrolloffset);
	PrintCreditText(1.4f, 1.4f, TheText.Get("CRED153"), lineoffset, scrolloffset);
	PrintCreditText(1.4f, 1.4f, TheText.Get("CRED154"), lineoffset, scrolloffset);
	PrintCreditText(1.4f, 1.4f, TheText.Get("CRED155"), lineoffset, scrolloffset);
	PrintCreditText(1.4f, 1.4f, TheText.Get("CRED156"), lineoffset, scrolloffset);
	PrintCreditText(1.4f, 1.4f, TheText.Get("CRED157"), lineoffset, scrolloffset);
	PrintCreditText(1.4f, 1.4f, TheText.Get("CRED158"), lineoffset, scrolloffset);
	PrintCreditText(1.4f, 1.4f, TheText.Get("CRED159"), lineoffset, scrolloffset);
	PrintCreditText(1.4f, 1.4f, TheText.Get("CRED160"), lineoffset, scrolloffset);
	PrintCreditText(1.4f, 1.4f, TheText.Get("CRED161"), lineoffset, scrolloffset);
	PrintCreditText(1.4f, 1.4f, TheText.Get("CRED162"), lineoffset, scrolloffset);
	PrintCreditText(1.4f, 1.4f, TheText.Get("CRED163"), lineoffset, scrolloffset);
	PrintCreditText(1.4f, 1.4f, TheText.Get("CRED164"), lineoffset, scrolloffset);
	PrintCreditText(1.4f, 1.4f, TheText.Get("CRED165"), lineoffset, scrolloffset);
	PrintCreditText(1.4f, 1.4f, TheText.Get("CRED166"), lineoffset, scrolloffset);
	PrintCreditText(1.4f, 1.4f, TheText.Get("CRED167"), lineoffset, scrolloffset);
	PrintCreditText(1.4f, 1.4f, TheText.Get("CRED168"), lineoffset, scrolloffset);
	PrintCreditText(1.4f, 1.4f, TheText.Get("CRED169"), lineoffset, scrolloffset);
	PrintCreditText(1.4f, 1.4f, TheText.Get("CRED170"), lineoffset, scrolloffset);
	PrintCreditText(1.4f, 1.4f, TheText.Get("CRED171"), lineoffset, scrolloffset);
	PrintCreditText(1.4f, 1.4f, TheText.Get("CRED172"), lineoffset, scrolloffset);
	PrintCreditText(1.4f, 1.4f, TheText.Get("CRED173"), lineoffset, scrolloffset);
	PrintCreditText(1.4f, 1.4f, TheText.Get("CRED174"), lineoffset, scrolloffset);
	PrintCreditText(1.4f, 1.4f, TheText.Get("CRED175"), lineoffset, scrolloffset);
	PrintCreditText(1.4f, 1.4f, TheText.Get("CRED176"), lineoffset, scrolloffset);
	PrintCreditText(1.4f, 1.4f, TheText.Get("CRED177"), lineoffset, scrolloffset);
	PrintCreditText(1.4f, 1.4f, TheText.Get("CRED178"), lineoffset, scrolloffset);
	PrintCreditText(1.4f, 1.4f, TheText.Get("CRED179"), lineoffset, scrolloffset);
	PrintCreditText(1.4f, 1.4f, TheText.Get("CRED180"), lineoffset, scrolloffset);
	PrintCreditText(1.4f, 1.4f, TheText.Get("CRED181"), lineoffset, scrolloffset);
	PrintCreditText(1.4f, 1.4f, TheText.Get("CRED182"), lineoffset, scrolloffset);
	PrintCreditText(1.4f, 1.4f, TheText.Get("CRED183"), lineoffset, scrolloffset);
	PrintCreditText(1.4f, 1.4f, TheText.Get("CRED184"), lineoffset, scrolloffset);
	PrintCreditText(1.4f, 1.4f, TheText.Get("CRED185"), lineoffset, scrolloffset);
	PrintCreditText(1.4f, 1.4f, TheText.Get("CRED186"), lineoffset, scrolloffset);
	PrintCreditText(1.4f, 1.4f, TheText.Get("CRED187"), lineoffset, scrolloffset);
	PrintCreditText(1.4f, 1.4f, TheText.Get("CRED188"), lineoffset, scrolloffset);
	PrintCreditText(1.4f, 1.4f, TheText.Get("CRED189"), lineoffset, scrolloffset);
	PrintCreditText(1.4f, 1.4f, TheText.Get("CRED190"), lineoffset, scrolloffset);
	PrintCreditText(1.4f, 1.4f, TheText.Get("CRED191"), lineoffset, scrolloffset);
	PrintCreditText(1.4f, 1.4f, TheText.Get("CRED192"), lineoffset, scrolloffset);
	PrintCreditText(1.4f, 1.4f, TheText.Get("CRED193"), lineoffset, scrolloffset);
	PrintCreditText(1.4f, 1.4f, TheText.Get("CRED194"), lineoffset, scrolloffset);
	PrintCreditText(1.4f, 1.4f, TheText.Get("CRED195"), lineoffset, scrolloffset);
	PrintCreditText(1.4f, 1.4f, TheText.Get("CRED196"), lineoffset, scrolloffset);
	PrintCreditText(1.4f, 1.4f, TheText.Get("CRED197"), lineoffset, scrolloffset);
	PrintCreditText(1.4f, 1.4f, TheText.Get("CRED198"), lineoffset, scrolloffset);
	PrintCreditText(1.4f, 1.4f, TheText.Get("CRED199"), lineoffset, scrolloffset);
	PrintCreditText(1.4f, 1.4f, TheText.Get("CRED200"), lineoffset, scrolloffset);
	PrintCreditText(1.4f, 1.4f, TheText.Get("CRED201"), lineoffset, scrolloffset);
	PrintCreditText(1.4f, 1.4f, TheText.Get("CRED202"), lineoffset, scrolloffset);
	PrintCreditText(1.4f, 1.4f, TheText.Get("CRED203"), lineoffset, scrolloffset);
	PrintCreditText(1.4f, 1.4f, TheText.Get("CRED204"), lineoffset, scrolloffset);
	PrintCreditText(1.4f, 1.4f, TheText.Get("CRED205"), lineoffset, scrolloffset);
	PrintCreditText(1.4f, 1.4f, TheText.Get("CRED206"), lineoffset, scrolloffset);
	PrintCreditText(1.4f, 1.4f, TheText.Get("CRED207"), lineoffset, scrolloffset);
	PrintCreditText(1.4f, 1.4f, TheText.Get("CRED208"), lineoffset, scrolloffset);
	PrintCreditText(1.4f, 1.4f, TheText.Get("CRED209"), lineoffset, scrolloffset);
	PrintCreditText(1.4f, 1.4f, TheText.Get("CRED210"), lineoffset, scrolloffset);
	PrintCreditText(1.4f, 1.4f, TheText.Get("CRED211"), lineoffset, scrolloffset);
	PrintCreditText(1.4f, 1.4f, TheText.Get("CRED212"), lineoffset, scrolloffset);
	PrintCreditText(1.4f, 1.4f, TheText.Get("CRED213"), lineoffset, scrolloffset);
	PrintCreditText(1.4f, 1.4f, TheText.Get("CRED214"), lineoffset, scrolloffset);
	PrintCreditText(1.4f, 1.4f, TheText.Get("CRED215"), lineoffset, scrolloffset);
	PrintCreditText(1.4f, 1.4f, TheText.Get("CRED216"), lineoffset, scrolloffset);
	PrintCreditText(1.4f, 1.4f, TheText.Get("CRED241"), lineoffset, scrolloffset);
	PrintCreditSpace(2.0f, lineoffset);
	PrintCreditText(1.4f, 0.82f, TheText.Get("CRED217"), lineoffset, scrolloffset);
	PrintCreditSpace(1.5f, lineoffset);
	PrintCreditSpace(2.0f, lineoffset);
	PrintCreditText(1.4f, 0.82f, TheText.Get("CRED218"), lineoffset, scrolloffset);
	PrintCreditSpace(1.5f, lineoffset);
	PrintCreditText(1.7f, 1.7f, TheText.Get("CRD218A"), lineoffset, scrolloffset);
	PrintCreditText(1.7f, 1.7f, TheText.Get("CRD218B"), lineoffset, scrolloffset);
	PrintCreditSpace(2.0f, lineoffset);
	PrintCreditText(1.4f, 0.82f, TheText.Get("CRED219"), lineoffset, scrolloffset);
	PrintCreditSpace(1.5f, lineoffset);
	PrintCreditText(1.7f, 1.7f, TheText.Get("CRED220"), lineoffset, scrolloffset);
	PrintCreditSpace(2.0f, lineoffset);
	PrintCreditText(1.4f, 0.82f, TheText.Get("CRED221"), lineoffset, scrolloffset);
	PrintCreditSpace(1.5f, lineoffset);
	PrintCreditText(1.7f, 1.7f, TheText.Get("CRED222"), lineoffset, scrolloffset);
	PrintCreditSpace(2.0f, lineoffset);
	PrintCreditText(1.4f, 0.82f, TheText.Get("CRED223"), lineoffset, scrolloffset);
	PrintCreditText(1.7f, 1.7f, TheText.Get("CRED224"), lineoffset, scrolloffset);
	PrintCreditText(1.7f, 1.7f, TheText.Get("CRED225"), lineoffset, scrolloffset);
	PrintCreditText(1.7f, 1.7f, TheText.Get("CRED226"), lineoffset, scrolloffset);
	PrintCreditSpace(2.0f, lineoffset);
	PrintCreditText(1.4f, 0.82f, TheText.Get("CRED227"), lineoffset, scrolloffset);
	PrintCreditSpace(1.5f, lineoffset);
	PrintCreditText(1.7f, 1.7f, TheText.Get("CRED228"), lineoffset, scrolloffset);
	PrintCreditText(1.7f, 1.7f, TheText.Get("CRED229"), lineoffset, scrolloffset);
	PrintCreditSpace(2.0f, lineoffset);
	PrintCreditText(1.4f, 0.82f, TheText.Get("CRED230"), lineoffset, scrolloffset);
	PrintCreditText(1.4f, 1.4f, TheText.Get("CRED231"), lineoffset, scrolloffset);
	PrintCreditText(1.4f, 1.4f, TheText.Get("CRED232"), lineoffset, scrolloffset);
	PrintCreditText(1.4f, 1.4f, TheText.Get("CRED233"), lineoffset, scrolloffset);
	PrintCreditText(1.4f, 1.4f, TheText.Get("CRED234"), lineoffset, scrolloffset);
	PrintCreditText(1.4f, 1.4f, TheText.Get("CRED235"), lineoffset, scrolloffset);
	PrintCreditText(1.4f, 1.4f, TheText.Get("CRED236"), lineoffset, scrolloffset);
	PrintCreditText(1.4f, 1.4f, TheText.Get("CRED237"), lineoffset, scrolloffset);
	PrintCreditText(1.4f, 1.4f, TheText.Get("CRED238"), lineoffset, scrolloffset);
	PrintCreditText(1.4f, 1.4f, TheText.Get("CRED239"), lineoffset, scrolloffset);
	PrintCreditText(1.4f, 1.4f, TheText.Get("CRED240"), lineoffset, scrolloffset);
	PrintCreditText(1.4f, 1.4f, TheText.Get("LITTLE"), lineoffset, scrolloffset);
	PrintCreditText(1.4f, 1.4f, TheText.Get("NICK"), lineoffset, scrolloffset);
	PrintCreditText(1.4f, 1.4f, TheText.Get("CRED243"), lineoffset, scrolloffset);
	PrintCreditText(1.4f, 1.4f, TheText.Get("CRED244"), lineoffset, scrolloffset);
	PrintCreditSpace(2.0f, lineoffset);
	PrintCreditSpace(2.0f, lineoffset);

	CFont::DrawFonts();
	if(TheCamera.m_WideScreenOn)
		TheCamera.DrawBordersForWideScreen();

#ifdef FIX_BUGS
	if(lineoffset + DEFAULT_SCREEN_HEIGHT - scrolloffset < -10.0f)
#else
	if(lineoffset + SCREEN_HEIGHT - scrolloffset < -10.0f)
#endif
	{
		bCreditsGoing = false;
	}
}

bool CCredits::AreCreditsDone(void)
{
	return !bCreditsGoing;
}


code:
#pragma once

class CCredits
{
	static bool bCreditsGoing;
	static uint32 CreditsStartTime;
public:
	static void Init(void);
	static void Start(void);
	static void Stop(void);
	static bool AreCreditsDone(void);
	static void Render(void);
	static void PrintCreditSpace(float space, uint32 &line);
	static void PrintCreditText(float scaleX, float scaleY, wchar *text, uint32 &lineoffset, float scrolloffset);
};

license: mit


code:
#include "common.h"

#include "Draw.h"
#include "Frontend.h"
#include "Camera.h"
#include "CutsceneMgr.h"

#ifdef ASPECT_RATIO_SCALE
float CDraw::ms_fAspectRatio = DEFAULT_ASPECT_RATIO;
float CDraw::ms_fScaledFOV = 45.0f;
#endif

float CDraw::ms_fNearClipZ;
float CDraw::ms_fFarClipZ;
float CDraw::ms_fFOV = 45.0f;
float CDraw::ms_fLODDistance;

uint8 CDraw::FadeValue;
uint8 CDraw::FadeRed;
uint8 CDraw::FadeGreen;
uint8 CDraw::FadeBlue;

#ifdef PROPER_SCALING
bool CDraw::ms_bProperScaling = true;
#endif
#ifdef  FIX_RADAR
bool CDraw::ms_bFixRadar = true;
#endif
#ifdef FIX_SPRITES
bool CDraw::ms_bFixSprites = true;
#endif

float
CDraw::FindAspectRatio(void)
{
#ifndef ASPECT_RATIO_SCALE
	if(FrontEndMenuManager.m_PrefsUseWideScreen)
		return 16.0f/9.0f;
	else
		return 4.0f/3.0f;
#else
	switch (FrontEndMenuManager.m_PrefsUseWideScreen) {
	case AR_AUTO:
		return SCREEN_WIDTH / SCREEN_HEIGHT;
	default:
	case AR_4_3:
		return 4.0f / 3.0f;
	case AR_5_4:
		return 5.0f / 4.0f;
	case AR_16_10:
		return 16.0f / 10.0f;
	case AR_16_9:
		return 16.0f / 9.0f;
	case AR_21_9:
		return 21.0f / 9.0f;
	};
#endif
}

#ifdef ASPECT_RATIO_SCALE
// convert a 4:3 hFOV to vFOV,
// then convert that vFOV to hFOV for our aspect ratio,
// i.e. HOR+
float
CDraw::ConvertFOV(float hfov)
{
	// => tan(hFOV/2) = tan(vFOV/2)*aspectRatio
	// => tan(vFOV/2) = tan(hFOV/2)/aspectRatio
	float ar1 = DEFAULT_ASPECT_RATIO;
	float ar2 = GetAspectRatio();
	hfov = DEGTORAD(hfov);
	float vfov = Atan(tan(hfov/2) / ar1) *2;
	hfov = Atan(tan(vfov/2) * ar2) *2;
	return RADTODEG(hfov);
}
#endif

void
CDraw::SetFOV(float fov)
{
#ifdef ASPECT_RATIO_SCALE
	if (!CCutsceneMgr::IsRunning())
		ms_fScaledFOV = ConvertFOV(fov);
	else
		ms_fScaledFOV = fov;
#endif
	ms_fFOV = fov;
}

#ifdef PROPER_SCALING
float CDraw::ScaleY(float y)
{
	return ms_bProperScaling ? y : y * ((float)DEFAULT_SCREEN_HEIGHT/SCREEN_HEIGHT_NTSC);
}
#endif


code:
#pragma once

enum eAspectRatio
{
	// Make sure these work the same as FrontEndMenuManager.m_PrefsUseWideScreen
	// without widescreen support
	AR_AUTO,
	AR_4_3,
	AR_5_4,
	AR_16_10,
	AR_16_9,
	AR_21_9,

	AR_MAX,
};

class CDraw
{
private:
	static float ms_fNearClipZ;
	static float ms_fFarClipZ;
	static float ms_fFOV;
#ifdef ASPECT_RATIO_SCALE
	// we use this variable to scale a lot of 2D elements
	// so better cache it
	static float ms_fAspectRatio;
	// similar thing for 3D rendering
	static float ms_fScaledFOV;
#endif
public:
	static float ms_fLODDistance;	// set but unused?

	static uint8 FadeValue;
	static uint8 FadeRed;
	static uint8 FadeGreen;
	static uint8 FadeBlue;

#ifdef PROPER_SCALING
	static bool ms_bProperScaling;
#endif
#ifdef FIX_RADAR
	static bool ms_bFixRadar;
#endif
#ifdef FIX_SPRITES
	static bool ms_bFixSprites;
#endif

	static void SetNearClipZ(float nearclip) { ms_fNearClipZ = nearclip; }
	static float GetNearClipZ(void) { return ms_fNearClipZ; }
	static void SetFarClipZ(float farclip) { ms_fFarClipZ = farclip; }
	static float GetFarClipZ(void) { return ms_fFarClipZ; }

	static void SetFOV(float fov);
	static float GetFOV(void) { return ms_fFOV; }
#ifdef ASPECT_RATIO_SCALE
	static float GetScaledFOV(void) { return ms_fScaledFOV; }
#else
	static float GetScaledFOV(void) { return ms_fFOV; }
#endif

	static float FindAspectRatio(void);
#ifdef ASPECT_RATIO_SCALE
	static float ConvertFOV(float fov);
	static float GetAspectRatio(void) { return ms_fAspectRatio; }
	static void SetAspectRatio(float ratio) { ms_fAspectRatio = ratio; }
#else
	static float GetAspectRatio(void) { return FindAspectRatio(); }
#endif

#ifdef PROPER_SCALING
	static float ScaleY(float y);
#endif
};


code:
#pragma once
#include "common.h"
#include "Vector.h"

class CMovingThing
{
public:
	CMovingThing *m_pNext;
	CMovingThing *m_pPrev;
	int16 m_nType;
	int16 m_nHidden;
	CVector m_vecPosn;
	CEntity* m_pEntity;

	void Update();
	void AddToList(CMovingThing *pThing);
	void RemoveFromList();
	int16 SizeList();
};

#define NUMMOVINGTHINGS 128

class CMovingThings
{
public:
	static CMovingThing StartCloseList;
	static CMovingThing EndCloseList;
	static int16 Num;
	static CMovingThing aMovingThings[NUMMOVINGTHINGS];

	static void Init();
	static void Shutdown();
	static void Update();
	static void Render();
};

class CScrollBar
{
private:
	uint8       m_Counter;
	const char* m_pMessage;
	CVector     m_Position;
	uint32      m_MessageCurrentChar;
	uint32      m_MessageLength;
	CVector     m_Size;
	float       m_fIntensity;
	uint8       m_MessageBar[40];
	uint8       m_Type;
	bool        m_bVisible;
	uint8       m_uRed;
	uint8       m_uGreen;
	uint8       m_uBlue;
	float       m_fScale;

public:
	void SetVisibility(bool visible) { m_bVisible = visible; }
	bool IsVisible() { return m_bVisible; }

	void Init(CVector, uint8, float, float, float, uint8, uint8, uint8, float);
	void Update();
	void Render();
};

class CTowerClock
{
private:
	CVector m_Position;
	CVector m_Size;
	float   m_fDrawDistance;
	float   m_fScale;
	uint8   m_uRed;
	uint8   m_uGreen;
	uint8   m_uBlue;
	bool    m_bVisible;
	float   m_fIntensity;

public:
	void SetVisibility(bool visible) { m_bVisible = visible; }
	bool IsVisible() { return m_bVisible; }

	void Init(CVector, float, float, uint8, uint8, uint8, float, float);
	void Update();
	void Render();
};

class CDigitalClock
{
private:
	CVector m_Position;
	CVector m_Size;
	float   m_fDrawDistance;
	float   m_fScale;
	uint8   m_uRed;
	uint8   m_uGreen;
	uint8   m_uBlue;
	bool    m_bVisible;
	float   m_fIntensity;

public:
	void SetVisibility(bool visible) { m_bVisible = visible; }
	bool IsVisible() { return m_bVisible; }

	void Init(CVector, float, float, uint8, uint8, uint8, float, float);
	void Update();
	void Render();
};


code:
#pragma once

#include "Sprite2d.h"

void AsciiToUnicode(const char *src, wchar *dst);
void UnicodeStrcpy(wchar *dst, const wchar *src);
void UnicodeStrcat(wchar *dst, wchar *append);
int UnicodeStrlen(const wchar *str);

struct CFontDetails
{
	CRGBA color;
	float scaleX;
	float scaleY;
	float slant;
	float slantRefX;
	float slantRefY;
	bool8 justify;
	bool8 centre;
	bool8 rightJustify;
	bool8 background;
	bool8 backgroundOnlyText;
	bool8 proportional;
	float alphaFade;
	CRGBA backgroundColor;
	float wrapX;
	float centreSize;
	float rightJustifyWrap;
	int16 style;
	int32 bank;
	int16 dropShadowPosition;
	CRGBA dropColor;
};

class CSprite2d;

enum {
	FONT_BANK,
	FONT_PAGER,
	FONT_HEADING,
#ifdef MORE_LANGUAGES
	FONT_JAPANESE,
#endif
	MAX_FONTS
};

enum {
	ALIGN_LEFT,
	ALIGN_CENTER,
	ALIGN_RIGHT,
};

#ifdef MORE_LANGUAGES
enum
{
	FONT_LANGSET_EFIGS,
	FONT_LANGSET_RUSSIAN,
	FONT_LANGSET_POLISH,
	FONT_LANGSET_JAPANESE,
	LANGSET_MAX
};

#define FONT_LOCALE(style) (CFont::IsJapanese() ? FONT_JAPANESE : style)
#else
#define FONT_LOCALE(style) (style)
#endif

#ifdef BUTTON_ICONS
enum
{
	BUTTON_NONE = -1,
#if 0 // unused
	BUTTON_UP,
	BUTTON_DOWN,
	BUTTON_LEFT,
	BUTTON_RIGHT,
#endif
	BUTTON_CROSS,
	BUTTON_CIRCLE,
	BUTTON_SQUARE,
	BUTTON_TRIANGLE,
	BUTTON_L1,
	BUTTON_L2,
	BUTTON_L3,
	BUTTON_R1,
	BUTTON_R2,
	BUTTON_R3,
	MAX_BUTTON_ICONS
};
#endif // BUTTON_ICONS

class CFont
{
#ifdef MORE_LANGUAGES
	static int16 Size[LANGSET_MAX][MAX_FONTS][193];
	static uint8 LanguageSet;
	static int32 Slot;
#else
	static int16 Size[MAX_FONTS][193];
#endif
	static bool16 NewLine;
public:
	static CSprite2d Sprite[MAX_FONTS];
	static CFontDetails Details;

#ifdef BUTTON_ICONS
	static int32 ButtonsSlot;
	static CSprite2d ButtonSprite[MAX_BUTTON_ICONS];
	static int PS2Symbol;

	static void LoadButtons(const char *txdPath);
	static void DrawButton(float x, float y);
#endif // BUTTON_ICONS

	static void Initialise(void);
	static void Shutdown(void);
	static void InitPerFrame(void);
	static void PrintChar(float x, float y, wchar c);
	static void PrintString(float x, float y, wchar *s);
	static void PrintStringFromBottom(float x, float y, wchar *str);
#ifdef XBOX_SUBTITLES
	static void PrintOutlinedString(float x, float y, wchar *str, float outlineStrength, bool fromBottom, CRGBA outlineColor);
#endif
	static int GetNumberLines(float xstart, float ystart, wchar *s);
	static void GetTextRect(CRect *rect, float xstart, float ystart, wchar *s);
#ifdef MORE_LANGUAGES
	static bool PrintString(float x, float y, wchar *start, wchar* &end, float spwidth, float japX);
#else
	static void PrintString(float x, float y, wchar *start, wchar *end, float spwidth);
#endif
	static float GetCharacterWidth(wchar c);
	static float GetCharacterSize(wchar c);
	static float GetStringWidth(wchar *s, bool spaces = false);
#ifdef MORE_LANGUAGES
	static float GetStringWidth_Jap(wchar* s);
#endif
	static uint16 *GetNextSpace(wchar *s);
#ifdef MORE_LANGUAGES
	static uint16 *ParseToken(wchar *s, wchar*, bool japShit = false);
#else
	static uint16 *ParseToken(wchar *s, wchar*);
#endif
	static void DrawFonts(void);
	static uint16 character_code(uint8 c);

	static void SetScale(float x, float y);
	static void SetSlantRefPoint(float x, float y);
	static void SetSlant(float s);
	static void SetJustifyOn(void);
	static void SetJustifyOff(void);
	static void SetRightJustifyOn(void);
	static void SetRightJustifyOff(void);
	static void SetCentreOn(void);
	static void SetCentreOff(void);
	static void SetWrapx(float x);
	static void SetCentreSize(float s);
	static void SetBackgroundOn(void);
	static void SetBackgroundOff(void);
	static void SetBackGroundOnlyTextOn(void);
	static void SetBackGroundOnlyTextOff(void);
	static void SetPropOn(void);
	static void SetPropOff(void);
	static void SetFontStyle(int16 style);
	static void SetRightJustifyWrap(float wrap);
	static void SetAlphaFade(float fade);
	static void SetDropShadowPosition(int16 pos);
	static void SetBackgroundColor(CRGBA col);
	static void SetColor(CRGBA col);
	static void SetDropColor(CRGBA col);

#ifdef MORE_LANGUAGES
	static void ReloadFonts(uint8 set);

	// japanese stuff
	static bool IsAnsiCharacter(wchar* s);
	static bool IsJapanesePunctuation(wchar* str);
	static bool IsJapanese() { return LanguageSet == FONT_LANGSET_JAPANESE; }
	static bool IsJapaneseFont() { return IsJapanese() && (Details.style == FONT_JAPANESE || Details.style == FONT_PAGER);  }
#endif
};


code:
#include "common.h"

#include "Glass.h"
#include "Timer.h"
#include "Object.h"
#include "General.h"
#include "AudioScriptObject.h"
#include "World.h"
#include "Timecycle.h"
#include "Particle.h"
#include "Camera.h"
#include "RenderBuffer.h"
#include "Shadows.h"
#include "ModelIndices.h"
#include "main.h"
#include "soundlist.h"

uint32 CGlass::NumGlassEntities;
CEntity *CGlass::apEntitiesToBeRendered[NUM_GLASSENTITIES];
CFallingGlassPane CGlass::aGlassPanes[NUM_GLASSPANES];

CVector2D CentersWithTriangle[NUM_GLASSTRIANGLES];
const CVector2D CoorsWithTriangle[NUM_GLASSTRIANGLES][3] =
{
	{
		CVector2D(0.0f, 0.0f),
		CVector2D(0.0f, 1.0f),
		CVector2D(0.4f, 0.5f)
	},

	{
		CVector2D(0.0f, 1.0f),
		CVector2D(1.0f, 1.0f),
		CVector2D(0.4f, 0.5f)
	},

	{
		CVector2D(0.0f, 0.0f),
		CVector2D(0.4f, 0.5f),
		CVector2D(0.7f, 0.0f)
	},

	{
		CVector2D(0.7f, 0.0f),
		CVector2D(0.4f, 0.5f),
		CVector2D(1.0f, 1.0f)
	},

	{
		CVector2D(0.7f, 0.0f),
		CVector2D(1.0f, 1.0f),
		CVector2D(1.0f, 0.0f)
	}
};

#define TEMPBUFFERVERTHILIGHTOFFSET     0
#define TEMPBUFFERINDEXHILIGHTOFFSET    0
#define TEMPBUFFERVERTHILIGHTSIZE       128
#define TEMPBUFFERINDEXHILIGHTSIZE      512

#define TEMPBUFFERVERTSHATTEREDOFFSET   TEMPBUFFERVERTHILIGHTSIZE
#define TEMPBUFFERINDEXSHATTEREDOFFSET  TEMPBUFFERINDEXHILIGHTSIZE
#define TEMPBUFFERVERTSHATTEREDSIZE     192
#define TEMPBUFFERINDEXSHATTEREDSIZE    768

#define TEMPBUFFERVERTREFLECTIONOFFSET  TEMPBUFFERVERTSHATTEREDSIZE
#define TEMPBUFFERINDEXREFLECTIONOFFSET TEMPBUFFERINDEXSHATTEREDSIZE
#define TEMPBUFFERVERTREFLECTIONSIZE    256
#define TEMPBUFFERINDEXREFLECTIONSIZE   1024

int32 TempBufferIndicesStoredHiLight     = 0;
int32 TempBufferVerticesStoredHiLight    = 0;
int32 TempBufferIndicesStoredShattered   = 0;
int32 TempBufferVerticesStoredShattered  = 0;
int32 TempBufferIndicesStoredReflection  = 0;
int32 TempBufferVerticesStoredReflection = 0;

void
CFallingGlassPane::Update(void)
{
	if ( CTimer::GetTimeInMilliseconds() >= m_nTimer )
	{
		// Apply MoveSpeed
		GetPosition()    += m_vecMoveSpeed * CTimer::GetTimeStep();

		// Apply Gravity
		m_vecMoveSpeed.z -= 0.02f         *  CTimer::GetTimeStep();

		// Apply TurnSpeed
		GetRight()   += CrossProduct(m_vecTurn, GetRight());
		GetForward() += CrossProduct(m_vecTurn, GetForward());
		GetUp()      += CrossProduct(m_vecTurn, GetUp());

		if ( GetPosition().z < m_fGroundZ )
		{
			CVector pos;
			CVector dir;

			m_bActive = false;

			pos = CVector(GetPosition().x, GetPosition().y, m_fGroundZ);

			PlayOneShotScriptObject(SCRIPT_SOUND_GLASS_LIGHT_BREAK, pos);

			RwRGBA color = { 255, 255, 255, 255 };

			static int32 nFrameGen = 0;

			for ( int32 i = 0; i < 4; i++ )
			{
				dir.x = CGeneral::GetRandomNumberInRange(-0.35f, 0.35f);
				dir.y = CGeneral::GetRandomNumberInRange(-0.35f, 0.35f);
				dir.z = CGeneral::GetRandomNumberInRange(0.05f, 0.20f);

				CParticle::AddParticle(PARTICLE_CAR_DEBRIS,
					pos,
					dir,
					nil,
					CGeneral::GetRandomNumberInRange(0.02f, 0.2f),
					color,
					CGeneral::GetRandomNumberInRange(-40, 40),
					0,
					++nFrameGen & 3,
					500);
			}
		}
	}
}

void
CFallingGlassPane::Render(void)
{
	float distToCamera = (TheCamera.GetPosition() - GetPosition()).Magnitude();

	CVector fwdNorm = GetForward();
	fwdNorm.Normalise();
	uint8 alpha = CGlass::CalcAlphaWithNormal(&fwdNorm);

#ifdef FIX_BUGS
	uint16 time = Clamp(CTimer::GetTimeInMilliseconds() > m_nTimer ? CTimer::GetTimeInMilliseconds() - m_nTimer : 0u, 0u, 500u);
#else
	uint16 time = Clamp(CTimer::GetTimeInMilliseconds() - m_nTimer, 0, 500);
#endif

	uint8 color = int32( float(alpha) * (float(time) / 500) );

	if ( TempBufferIndicesStoredHiLight >= TEMPBUFFERINDEXHILIGHTSIZE-7 || TempBufferVerticesStoredHiLight >= TEMPBUFFERVERTHILIGHTSIZE-4 )
		CGlass::RenderHiLightPolys();

	// HiLight Polys

	RwIm3DVertexSetRGBA (&TempBufferRenderVertices[TempBufferVerticesStoredHiLight + 0], color, color, color, color);
	RwIm3DVertexSetRGBA (&TempBufferRenderVertices[TempBufferVerticesStoredHiLight + 1], color, color, color, color);
	RwIm3DVertexSetRGBA (&TempBufferRenderVertices[TempBufferVerticesStoredHiLight + 2], color, color, color, color);

	RwIm3DVertexSetU    (&TempBufferRenderVertices[TempBufferVerticesStoredHiLight + 0], 0.5f);
	RwIm3DVertexSetV    (&TempBufferRenderVertices[TempBufferVerticesStoredHiLight + 0], 0.5f);
	RwIm3DVertexSetU    (&TempBufferRenderVertices[TempBufferVerticesStoredHiLight + 1], 0.5f);
	RwIm3DVertexSetV    (&TempBufferRenderVertices[TempBufferVerticesStoredHiLight + 1], 0.6f);
	RwIm3DVertexSetU    (&TempBufferRenderVertices[TempBufferVerticesStoredHiLight + 2], 0.6f);
	RwIm3DVertexSetV    (&TempBufferRenderVertices[TempBufferVerticesStoredHiLight + 2], 0.6f);

	ASSERT(m_nTriIndex < NUM_GLASSTRIANGLES);

	CVector2D p0 = CoorsWithTriangle[m_nTriIndex][0] - CentersWithTriangle[m_nTriIndex];
	CVector2D p1 = CoorsWithTriangle[m_nTriIndex][1] - CentersWithTriangle[m_nTriIndex];
	CVector2D p2 = CoorsWithTriangle[m_nTriIndex][2] - CentersWithTriangle[m_nTriIndex];
	CVector v0 = *this * CVector(p0.x, 0.0f, p0.y);
	CVector v1 = *this * CVector(p1.x, 0.0f, p1.y);
	CVector v2 = *this * CVector(p2.x, 0.0f, p2.y);

	RwIm3DVertexSetPos  (&TempBufferRenderVertices[TempBufferVerticesStoredHiLight + 0], v0.x, v0.y, v0.z);
	RwIm3DVertexSetPos  (&TempBufferRenderVertices[TempBufferVerticesStoredHiLight + 1], v1.x, v1.y, v1.z);
	RwIm3DVertexSetPos  (&TempBufferRenderVertices[TempBufferVerticesStoredHiLight + 2], v2.x, v2.y, v2.z);

	TempBufferRenderIndexList[TempBufferIndicesStoredHiLight + 0] = TempBufferVerticesStoredHiLight + 0;
	TempBufferRenderIndexList[TempBufferIndicesStoredHiLight + 1] = TempBufferVerticesStoredHiLight + 1;
	TempBufferRenderIndexList[TempBufferIndicesStoredHiLight + 2] = TempBufferVerticesStoredHiLight + 2;
	TempBufferRenderIndexList[TempBufferIndicesStoredHiLight + 3] = TempBufferVerticesStoredHiLight + 0;
	TempBufferRenderIndexList[TempBufferIndicesStoredHiLight + 4] = TempBufferVerticesStoredHiLight + 2;
	TempBufferRenderIndexList[TempBufferIndicesStoredHiLight + 5] = TempBufferVerticesStoredHiLight + 1;

	TempBufferVerticesStoredHiLight += 3;
	TempBufferIndicesStoredHiLight  += 6;

	if ( m_bShattered )
	{
		if ( TempBufferIndicesStoredShattered >= TEMPBUFFERINDEXSHATTEREDSIZE-7 || TempBufferVerticesStoredShattered >= TEMPBUFFERVERTSHATTEREDSIZE-4 )
			CGlass::RenderShatteredPolys();

		uint8 shatteredColor = 255;
		if ( distToCamera > 30.0f )
			shatteredColor = int32((1.0f - (distToCamera - 30.0f) * 4.0f / 40.0f) * 255);

		RwIm3DVertexSetRGBA (&TempBufferRenderVertices[TempBufferVerticesStoredShattered + 0], shatteredColor, shatteredColor, shatteredColor, shatteredColor);
		RwIm3DVertexSetRGBA (&TempBufferRenderVertices[TempBufferVerticesStoredShattered + 1], shatteredColor, shatteredColor, shatteredColor, shatteredColor);
		RwIm3DVertexSetRGBA (&TempBufferRenderVertices[TempBufferVerticesStoredShattered + 2], shatteredColor, shatteredColor, shatteredColor, shatteredColor);

		RwIm3DVertexSetU    (&TempBufferRenderVertices[TempBufferVerticesStoredShattered + 0], 4.0f * CoorsWithTriangle[m_nTriIndex][0].x * m_fStep);
		RwIm3DVertexSetV    (&TempBufferRenderVertices[TempBufferVerticesStoredShattered + 0], 4.0f * CoorsWithTriangle[m_nTriIndex][0].y * m_fStep);
		RwIm3DVertexSetU    (&TempBufferRenderVertices[TempBufferVerticesStoredShattered + 1], 4.0f * CoorsWithTriangle[m_nTriIndex][1].x * m_fStep);
		RwIm3DVertexSetV    (&TempBufferRenderVertices[TempBufferVerticesStoredShattered + 1], 4.0f * CoorsWithTriangle[m_nTriIndex][1].y * m_fStep);
		RwIm3DVertexSetU    (&TempBufferRenderVertices[TempBufferVerticesStoredShattered + 2], 4.0f * CoorsWithTriangle[m_nTriIndex][2].x * m_fStep);
		RwIm3DVertexSetV    (&TempBufferRenderVertices[TempBufferVerticesStoredShattered + 2], 4.0f * CoorsWithTriangle[m_nTriIndex][2].y * m_fStep);

		RwIm3DVertexSetPos  (&TempBufferRenderVertices[TempBufferVerticesStoredShattered + 0], v0.x, v0.y, v0.z);
		RwIm3DVertexSetPos  (&TempBufferRenderVertices[TempBufferVerticesStoredShattered + 1], v1.x, v1.y, v1.z);
		RwIm3DVertexSetPos  (&TempBufferRenderVertices[TempBufferVerticesStoredShattered + 2], v2.x, v2.y, v2.z);

		TempBufferRenderIndexList[TempBufferIndicesStoredShattered + 0] = TempBufferVerticesStoredShattered - TEMPBUFFERVERTSHATTEREDOFFSET + 0;
		TempBufferRenderIndexList[TempBufferIndicesStoredShattered + 1] = TempBufferVerticesStoredShattered - TEMPBUFFERVERTSHATTEREDOFFSET + 1;
		TempBufferRenderIndexList[TempBufferIndicesStoredShattered + 2] = TempBufferVerticesStoredShattered - TEMPBUFFERVERTSHATTEREDOFFSET + 2;
		TempBufferRenderIndexList[TempBufferIndicesStoredShattered + 3] = TempBufferVerticesStoredShattered - TEMPBUFFERVERTSHATTEREDOFFSET + 0;
		TempBufferRenderIndexList[TempBufferIndicesStoredShattered + 4] = TempBufferVerticesStoredShattered - TEMPBUFFERVERTSHATTEREDOFFSET + 2;
		TempBufferRenderIndexList[TempBufferIndicesStoredShattered + 5] = TempBufferVerticesStoredShattered - TEMPBUFFERVERTSHATTEREDOFFSET + 1;

		TempBufferIndicesStoredShattered  += 6;
		TempBufferVerticesStoredShattered += 3;
	}
}

void
CGlass::Init(void)
{
	for ( int32 i = 0; i < NUM_GLASSPANES; i++ )
		aGlassPanes[i].m_bActive = false;

	for ( int32 i = 0; i < NUM_GLASSTRIANGLES; i++  )
		CentersWithTriangle[i] = (CoorsWithTriangle[i][0] + CoorsWithTriangle[i][1] + CoorsWithTriangle[i][2]) / 3;
}

void
CGlass::Update(void)
{
	for ( int32 i = 0; i < NUM_GLASSPANES; i++ )
	{
		if ( aGlassPanes[i].m_bActive )
			aGlassPanes[i].Update();
	}
}

void
CGlass::Render(void)
{
	TempBufferVerticesStoredHiLight    = 0;
	TempBufferIndicesStoredHiLight     = 0;

	TempBufferVerticesStoredShattered  = TEMPBUFFERVERTSHATTEREDOFFSET;
	TempBufferIndicesStoredShattered   = TEMPBUFFERINDEXSHATTEREDOFFSET;

	TempBufferVerticesStoredReflection = TEMPBUFFERVERTREFLECTIONOFFSET;
	TempBufferIndicesStoredReflection  = TEMPBUFFERINDEXREFLECTIONOFFSET;

	RwRenderStateSet(rwRENDERSTATEZWRITEENABLE,      (void *)FALSE);
	RwRenderStateSet(rwRENDERSTATETEXTUREFILTER,     (void *)rwFILTERLINEAR);
	RwRenderStateSet(rwRENDERSTATEFOGENABLE,         (void *)TRUE);
	RwRenderStateSet(rwRENDERSTATEFOGCOLOR,          (void *)RWRGBALONG(CTimeCycle::GetFogRed(), CTimeCycle::GetFogGreen(), CTimeCycle::GetFogBlue(), 255));
	RwRenderStateSet(rwRENDERSTATESRCBLEND,          (void *)rwBLENDONE);
	RwRenderStateSet(rwRENDERSTATEDESTBLEND,         (void *)rwBLENDONE);
	RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void *)TRUE);

	PUSH_RENDERGROUP("CGlass::Render");

	for ( int32 i = 0; i < NUM_GLASSPANES; i++ )
	{
		if ( aGlassPanes[i].m_bActive )
			aGlassPanes[i].Render();
	}

	for ( uint32 i = 0; i < NumGlassEntities; i++ )
		RenderEntityInGlass(apEntitiesToBeRendered[i]);

	POP_RENDERGROUP();

	NumGlassEntities = 0;

	RenderHiLightPolys();
	RenderShatteredPolys();
	RenderReflectionPolys();

	RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, (void *)TRUE);
	RwRenderStateSet(rwRENDERSTATEZTESTENABLE,  (void *)TRUE);
	RwRenderStateSet(rwRENDERSTATESRCBLEND,     (void *)rwBLENDSRCALPHA);
	RwRenderStateSet(rwRENDERSTATEDESTBLEND,    (void *)rwBLENDINVSRCALPHA);
	RwRenderStateSet(rwRENDERSTATEFOGENABLE,    (void *)FALSE);
}

CFallingGlassPane *
CGlass::FindFreePane(void)
{
	for ( int32 i = 0; i < NUM_GLASSPANES; i++ )
	{
		if ( !aGlassPanes[i].m_bActive )
			return &aGlassPanes[i];
	}

	return nil;
}

void
CGlass::GeneratePanesForWindow(uint32 type, CVector pos, CVector up, CVector right, CVector speed, CVector point,
								float moveSpeed, bool cracked, bool explosion)
{
	float upLen    = up.Magnitude();
	float rightLen = right.Magnitude();

	float upSteps = upLen + 0.75f;
	if ( upSteps < 1.0f ) upSteps = 1.0f;

	float rightSteps = rightLen + 0.75f;
	if ( rightSteps < 1.0f ) rightSteps = 1.0f;

	uint32 ysteps = (uint32)upSteps;
	if ( ysteps > 3 ) ysteps = 3;

	uint32 xsteps = (uint32)rightSteps;
	if ( xsteps > 3 ) xsteps = 3;

	if ( explosion )
	{
		if ( ysteps > 1 ) ysteps = 1;
		if ( xsteps > 1 ) xsteps = 1;
	}

	float upScl    = upLen    / float(ysteps);
	float rightScl = rightLen / float(xsteps);

	bool bZFound;
	float groundZ = CWorld::FindGroundZFor3DCoord(pos.x, pos.y, pos.z, &bZFound);
	if ( !bZFound ) groundZ = pos.z - 2.0f;

	for ( uint32 y = 0; y < ysteps; y++  )
	{
		for ( uint32 x = 0; x < xsteps; x++ )
		{
			float stepy = float(y) * upLen    / float(ysteps);
			float stepx = float(x) * rightLen / float(xsteps);

			for ( int32 i = 0; i < NUM_GLASSTRIANGLES; i++ )
			{
				CFallingGlassPane *pane = FindFreePane();
				if ( pane )
				{
					pane->m_nTriIndex = i;

					pane->GetRight()  = (right * rightScl) / rightLen;
#ifdef FIX_BUGS
					pane->GetUp()     = (up    * upScl)    / upLen;
#else
					pane->GetUp()     = (up    * upScl)    / rightLen; // copypaste bug
#endif
					CVector fwd = CrossProduct(pane->GetRight(), pane->GetUp());
					fwd.Normalise();

					pane->GetForward() = fwd;

					pane->GetPosition() = right / rightLen * (rightScl * CentersWithTriangle[i].x + stepx)
										+ up    / upLen    * (upScl    * CentersWithTriangle[i].y + stepy)
										+ pos;

					pane->m_vecMoveSpeed.x = float((CGeneral::GetRandomNumber() & 127) - 64) * 0.0015f + speed.x;
					pane->m_vecMoveSpeed.y = float((CGeneral::GetRandomNumber() & 127) - 64) * 0.0015f + speed.y;
					pane->m_vecMoveSpeed.z = 0.0f + speed.z;

					if ( moveSpeed != 0.0f )
					{
						CVector dist = pane->GetPosition() - point;
						dist.Normalise();

						pane->m_vecMoveSpeed += moveSpeed * dist;
					}

					pane->m_vecTurn.x = float((CGeneral::GetRandomNumber() & 127) - 64) * 0.002f;
					pane->m_vecTurn.y = float((CGeneral::GetRandomNumber() & 127) - 64) * 0.002f;
					pane->m_vecTurn.z = float((CGeneral::GetRandomNumber() & 127) - 64) * 0.002f;

					switch ( type )
					{
						case 0:
							pane->m_nTimer = CTimer::GetTimeInMilliseconds();
							break;
						case 1:
							float dist = (pane->GetPosition() - point).Magnitude();
							pane->m_nTimer = uint32(dist*100 + CTimer::GetTimeInMilliseconds());
							break;
					}

					pane->m_fGroundZ = groundZ;
					pane->m_bShattered = cracked;
					pane->m_fStep = upLen / float(ysteps);
					pane->m_bActive = true;
				}
			}
		}
	}
}

void
CGlass::AskForObjectToBeRenderedInGlass(CEntity *entity)
{
#ifdef FIX_BUGS
	if ( NumGlassEntities < NUM_GLASSENTITIES )
#else
	if ( NumGlassEntities < NUM_GLASSENTITIES-1 )
#endif
	{
		apEntitiesToBeRendered[NumGlassEntities++] = entity;
	}
}

void
CGlass::RenderEntityInGlass(CEntity *entity)
{
	ASSERT(entity!=nil);
	CObject *object = (CObject *)entity;

	if ( object->bGlassBroken )
		return;

	float distToCamera = (TheCamera.GetPosition() - object->GetPosition()).Magnitude();

	if ( distToCamera > 40.0f )
		return;

	CVector fwdNorm = object->GetForward();
	fwdNorm.Normalise();
	uint8 alpha = CalcAlphaWithNormal(&fwdNorm);

	CColModel *col = object->GetColModel();
	ASSERT(col!=nil);
	if ( col->numTriangles >= 2 )
	{
		CVector a = object->GetMatrix() * col->vertices[0].Get();
		CVector b = object->GetMatrix() * col->vertices[1].Get();
		CVector c = object->GetMatrix() * col->vertices[2].Get();
		CVector d = object->GetMatrix() * col->vertices[3].Get();

		if ( object->bGlassCracked )
		{
			uint8 color = 255;
			if ( distToCamera > 30.0f )
				color = int32((1.0f - (distToCamera - 30.0f) * 4.0f / 40.0f) * 255);

			if ( TempBufferIndicesStoredShattered >= TEMPBUFFERINDEXSHATTEREDSIZE-13 || TempBufferVerticesStoredShattered >= TEMPBUFFERVERTSHATTEREDSIZE-5 )
				RenderShatteredPolys();

			RwIm3DVertexSetRGBA (&TempBufferRenderVertices[TempBufferVerticesStoredShattered + 0], color, color, color, color);
			RwIm3DVertexSetRGBA (&TempBufferRenderVertices[TempBufferVerticesStoredShattered + 1], color, color, color, color);
			RwIm3DVertexSetRGBA (&TempBufferRenderVertices[TempBufferVerticesStoredShattered + 2], color, color, color, color);
			RwIm3DVertexSetRGBA (&TempBufferRenderVertices[TempBufferVerticesStoredShattered + 3], color, color, color, color);

			RwIm3DVertexSetU    (&TempBufferRenderVertices[TempBufferVerticesStoredShattered + 0], 0.0f);
			RwIm3DVertexSetV    (&TempBufferRenderVertices[TempBufferVerticesStoredShattered + 0], 0.0f);
			RwIm3DVertexSetU    (&TempBufferRenderVertices[TempBufferVerticesStoredShattered + 1], 16.0f);
			RwIm3DVertexSetV    (&TempBufferRenderVertices[TempBufferVerticesStoredShattered + 1], 0.0f);
			RwIm3DVertexSetU    (&TempBufferRenderVertices[TempBufferVerticesStoredShattered + 2], 0.0f);
			RwIm3DVertexSetV    (&TempBufferRenderVertices[TempBufferVerticesStoredShattered + 2], 16.0f);
			RwIm3DVertexSetU    (&TempBufferRenderVertices[TempBufferVerticesStoredShattered + 3], 16.0f);
			RwIm3DVertexSetV    (&TempBufferRenderVertices[TempBufferVerticesStoredShattered + 3], 16.0f);

			RwIm3DVertexSetPos  (&TempBufferRenderVertices[TempBufferVerticesStoredShattered + 0], a.x, a.y, a.z);
			RwIm3DVertexSetPos  (&TempBufferRenderVertices[TempBufferVerticesStoredShattered + 1], b.x, b.y, b.z);
			RwIm3DVertexSetPos  (&TempBufferRenderVertices[TempBufferVerticesStoredShattered + 2], c.x, c.y, c.z);
			RwIm3DVertexSetPos  (&TempBufferRenderVertices[TempBufferVerticesStoredShattered + 3], d.x, d.y, d.z);

			TempBufferRenderIndexList[TempBufferIndicesStoredShattered + 0]  = col->triangles[0].a + TempBufferVerticesStoredShattered - TEMPBUFFERVERTSHATTEREDOFFSET;
			TempBufferRenderIndexList[TempBufferIndicesStoredShattered + 1]  = col->triangles[0].b + TempBufferVerticesStoredShattered - TEMPBUFFERVERTSHATTEREDOFFSET;
			TempBufferRenderIndexList[TempBufferIndicesStoredShattered + 2]  = col->triangles[0].c + TempBufferVerticesStoredShattered - TEMPBUFFERVERTSHATTEREDOFFSET;
			TempBufferRenderIndexList[TempBufferIndicesStoredShattered + 3]  = col->triangles[1].a + TempBufferVerticesStoredShattered - TEMPBUFFERVERTSHATTEREDOFFSET;
			TempBufferRenderIndexList[TempBufferIndicesStoredShattered + 4]  = col->triangles[1].b + TempBufferVerticesStoredShattered - TEMPBUFFERVERTSHATTEREDOFFSET;
			TempBufferRenderIndexList[TempBufferIndicesStoredShattered + 5]  = col->triangles[1].c + TempBufferVerticesStoredShattered - TEMPBUFFERVERTSHATTEREDOFFSET;
			TempBufferRenderIndexList[TempBufferIndicesStoredShattered + 6]  = col->triangles[0].a + TempBufferVerticesStoredShattered - TEMPBUFFERVERTSHATTEREDOFFSET;
			TempBufferRenderIndexList[TempBufferIndicesStoredShattered + 7]  = col->triangles[0].c + TempBufferVerticesStoredShattered - TEMPBUFFERVERTSHATTEREDOFFSET;
			TempBufferRenderIndexList[TempBufferIndicesStoredShattered + 8]  = col->triangles[0].b + TempBufferVerticesStoredShattered - TEMPBUFFERVERTSHATTEREDOFFSET;
			TempBufferRenderIndexList[TempBufferIndicesStoredShattered + 9]  = col->triangles[1].a + TempBufferVerticesStoredShattered - TEMPBUFFERVERTSHATTEREDOFFSET;
			TempBufferRenderIndexList[TempBufferIndicesStoredShattered + 10] = col->triangles[1].c + TempBufferVerticesStoredShattered - TEMPBUFFERVERTSHATTEREDOFFSET;
			TempBufferRenderIndexList[TempBufferIndicesStoredShattered + 11] = col->triangles[1].b + TempBufferVerticesStoredShattered - TEMPBUFFERVERTSHATTEREDOFFSET;

			TempBufferIndicesStoredShattered  += 12;
			TempBufferVerticesStoredShattered += 4;
		}

		if ( TempBufferIndicesStoredReflection >= TEMPBUFFERINDEXREFLECTIONSIZE-13 || TempBufferVerticesStoredReflection >= TEMPBUFFERVERTREFLECTIONSIZE-5 )
			RenderReflectionPolys();

		uint8 color = 100;
		if ( distToCamera > 30.0f )
			color = int32((1.0f - (distToCamera - 30.0f) * 4.0f / 40.0f) * 100);

		RwIm3DVertexSetRGBA (&TempBufferRenderVertices[TempBufferVerticesStoredReflection + 0], color, color, color, color);
		RwIm3DVertexSetRGBA (&TempBufferRenderVertices[TempBufferVerticesStoredReflection + 1], color, color, color, color);
		RwIm3DVertexSetRGBA (&TempBufferRenderVertices[TempBufferVerticesStoredReflection + 2], color, color, color, color);
		RwIm3DVertexSetRGBA (&TempBufferRenderVertices[TempBufferVerticesStoredReflection + 3], color, color, color, color);

		float FwdAngle = CGeneral::GetATanOfXY(TheCamera.GetForward().x, TheCamera.GetForward().y);
		float v = 2.0f * TheCamera.GetForward().z * 0.2f;
		float u = float(object->m_randomSeed & 15) * 0.02f + (FwdAngle / TWOPI);

		RwIm3DVertexSetU    (&TempBufferRenderVertices[TempBufferVerticesStoredReflection + 0], u);
		RwIm3DVertexSetV    (&TempBufferRenderVertices[TempBufferVerticesStoredReflection + 0], v);
		RwIm3DVertexSetU    (&TempBufferRenderVertices[TempBufferVerticesStoredReflection + 1], u+0.2f);
		RwIm3DVertexSetV    (&TempBufferRenderVertices[TempBufferVerticesStoredReflection + 1], v);
		RwIm3DVertexSetU    (&TempBufferRenderVertices[TempBufferVerticesStoredReflection + 2], u);
		RwIm3DVertexSetV    (&TempBufferRenderVertices[TempBufferVerticesStoredReflection + 2], v+0.2f);
		RwIm3DVertexSetU    (&TempBufferRenderVertices[TempBufferVerticesStoredReflection + 3], u+0.2f);
		RwIm3DVertexSetV    (&TempBufferRenderVertices[TempBufferVerticesStoredReflection + 3], v+0.2f);

		RwIm3DVertexSetPos  (&TempBufferRenderVertices[TempBufferVerticesStoredReflection + 0], a.x, a.y, a.z);
		RwIm3DVertexSetPos  (&TempBufferRenderVertices[TempBufferVerticesStoredReflection + 1], b.x, b.y, b.z);
		RwIm3DVertexSetPos  (&TempBufferRenderVertices[TempBufferVerticesStoredReflection + 2], c.x, c.y, c.z);
		RwIm3DVertexSetPos  (&TempBufferRenderVertices[TempBufferVerticesStoredReflection + 3], d.x, d.y, d.z);

		TempBufferRenderIndexList[TempBufferIndicesStoredReflection + 0]  = col->triangles[0].a + TempBufferVerticesStoredReflection - TEMPBUFFERVERTREFLECTIONOFFSET;
		TempBufferRenderIndexList[TempBufferIndicesStoredReflection + 1]  = col->triangles[0].b + TempBufferVerticesStoredReflection - TEMPBUFFERVERTREFLECTIONOFFSET;
		TempBufferRenderIndexList[TempBufferIndicesStoredReflection + 2]  = col->triangles[0].c + TempBufferVerticesStoredReflection - TEMPBUFFERVERTREFLECTIONOFFSET;
		TempBufferRenderIndexList[TempBufferIndicesStoredReflection + 3]  = col->triangles[1].a + TempBufferVerticesStoredReflection - TEMPBUFFERVERTREFLECTIONOFFSET;
		TempBufferRenderIndexList[TempBufferIndicesStoredReflection + 4]  = col->triangles[1].b + TempBufferVerticesStoredReflection - TEMPBUFFERVERTREFLECTIONOFFSET;
		TempBufferRenderIndexList[TempBufferIndicesStoredReflection + 5]  = col->triangles[1].c + TempBufferVerticesStoredReflection - TEMPBUFFERVERTREFLECTIONOFFSET;
		TempBufferRenderIndexList[TempBufferIndicesStoredReflection + 6]  = col->triangles[0].a + TempBufferVerticesStoredReflection - TEMPBUFFERVERTREFLECTIONOFFSET;
		TempBufferRenderIndexList[TempBufferIndicesStoredReflection + 7]  = col->triangles[0].c + TempBufferVerticesStoredReflection - TEMPBUFFERVERTREFLECTIONOFFSET;
		TempBufferRenderIndexList[TempBufferIndicesStoredReflection + 8]  = col->triangles[0].b + TempBufferVerticesStoredReflection - TEMPBUFFERVERTREFLECTIONOFFSET;
		TempBufferRenderIndexList[TempBufferIndicesStoredReflection + 9]  = col->triangles[1].a + TempBufferVerticesStoredReflection - TEMPBUFFERVERTREFLECTIONOFFSET;
		TempBufferRenderIndexList[TempBufferIndicesStoredReflection + 10] = col->triangles[1].c + TempBufferVerticesStoredReflection - TEMPBUFFERVERTREFLECTIONOFFSET;
		TempBufferRenderIndexList[TempBufferIndicesStoredReflection + 11] = col->triangles[1].b + TempBufferVerticesStoredReflection - TEMPBUFFERVERTREFLECTIONOFFSET;

		TempBufferIndicesStoredReflection  += 12;
		TempBufferVerticesStoredReflection += 4;
	}
}

int32
CGlass::CalcAlphaWithNormal(CVector *normal)
{
	ASSERT(normal!=nil);

	float fwdDir = 2.0f * DotProduct(*normal, TheCamera.GetForward());
	float fwdDot = DotProduct(TheCamera.GetForward()-fwdDir*(*normal), CVector(0.57f, 0.57f, -0.57f));
	return int32(lerp(fwdDot*fwdDot*fwdDot*fwdDot*fwdDot*fwdDot, 20.0f, 255.0f));
}

void
CGlass::RenderHiLightPolys(void)
{
	if ( TempBufferVerticesStoredHiLight != TEMPBUFFERVERTHILIGHTOFFSET )
	{
		RwRenderStateSet(rwRENDERSTATESRCBLEND,      (void *)rwBLENDONE);
		RwRenderStateSet(rwRENDERSTATEDESTBLEND,     (void *)rwBLENDONE);
		RwRenderStateSet(rwRENDERSTATETEXTURERASTER, (void *)RwTextureGetRaster(gpShadowExplosionTex));

		LittleTest();

		if ( RwIm3DTransform(TempBufferRenderVertices, TempBufferVerticesStoredHiLight, nil, rwIM3D_VERTEXUV) )
		{
			RwIm3DRenderIndexedPrimitive(rwPRIMTYPETRILIST, TempBufferRenderIndexList, TempBufferIndicesStoredHiLight);
			RwIm3DEnd();
		}

		TempBufferVerticesStoredHiLight = TEMPBUFFERVERTHILIGHTOFFSET;
		TempBufferIndicesStoredHiLight  = TEMPBUFFERINDEXHILIGHTOFFSET;
	}
}

void
CGlass::RenderShatteredPolys(void)
{
	if ( TempBufferVerticesStoredShattered != TEMPBUFFERVERTSHATTEREDOFFSET )
	{
		RwRenderStateSet(rwRENDERSTATETEXTURERASTER, (void *)RwTextureGetRaster(gpCrackedGlassTex));
		RwRenderStateSet(rwRENDERSTATESRCBLEND,      (void *)rwBLENDSRCALPHA);
		RwRenderStateSet(rwRENDERSTATEDESTBLEND,     (void *)rwBLENDINVSRCALPHA);

		LittleTest();

		if ( RwIm3DTransform(&TempBufferRenderVertices[TEMPBUFFERVERTSHATTEREDOFFSET], TempBufferVerticesStoredShattered - TEMPBUFFERVERTSHATTEREDOFFSET, nil, rwIM3D_VERTEXUV) )
		{
			RwIm3DRenderIndexedPrimitive(rwPRIMTYPETRILIST, &TempBufferRenderIndexList[TEMPBUFFERINDEXSHATTEREDOFFSET], TempBufferIndicesStoredShattered - TEMPBUFFERINDEXSHATTEREDOFFSET);
			RwIm3DEnd();
		}

		TempBufferIndicesStoredShattered  = TEMPBUFFERINDEXSHATTEREDOFFSET;
		TempBufferVerticesStoredShattered = TEMPBUFFERVERTSHATTEREDOFFSET;
	}
}

void
CGlass::RenderReflectionPolys(void)
{
	if ( TempBufferVerticesStoredReflection != TEMPBUFFERVERTREFLECTIONOFFSET )
	{
		RwRenderStateSet(rwRENDERSTATETEXTURERASTER, (void *)RwTextureGetRaster(gpShadowHeadLightsTex));
		RwRenderStateSet(rwRENDERSTATESRCBLEND,      (void *)rwBLENDSRCALPHA);
		RwRenderStateSet(rwRENDERSTATEDESTBLEND,     (void *)rwBLENDINVSRCALPHA);

		LittleTest();

		if ( RwIm3DTransform(&TempBufferRenderVertices[TEMPBUFFERVERTREFLECTIONOFFSET], TempBufferVerticesStoredReflection - TEMPBUFFERVERTREFLECTIONOFFSET, nil, rwIM3D_VERTEXUV) )
		{
			RwIm3DRenderIndexedPrimitive(rwPRIMTYPETRILIST, &TempBufferRenderIndexList[TEMPBUFFERINDEXREFLECTIONOFFSET], TempBufferIndicesStoredReflection - TEMPBUFFERINDEXREFLECTIONOFFSET);
			RwIm3DEnd();
		}

		TempBufferIndicesStoredReflection  = TEMPBUFFERINDEXREFLECTIONOFFSET;
		TempBufferVerticesStoredReflection = TEMPBUFFERVERTREFLECTIONOFFSET;
	}
}

void
CGlass::WindowRespondsToCollision(CEntity *entity, float amount, CVector speed, CVector point, bool explosion)
{
	ASSERT(entity!=nil);

	CObject *object = (CObject *)entity;

	if ( object->bGlassBroken )
		return;

	object->bGlassCracked = true;

	CColModel *col = object->GetColModel();
	ASSERT(col!=nil);

	CVector a = object->GetMatrix() * col->vertices[0].Get();
	CVector b = object->GetMatrix() * col->vertices[1].Get();
	CVector c = object->GetMatrix() * col->vertices[2].Get();
	CVector d = object->GetMatrix() * col->vertices[3].Get();

	float minx = Min(Min(a.x, b.x), Min(c.x, d.x));
	float maxx = Max(Max(a.x, b.x), Max(c.x, d.x));
	float miny = Min(Min(a.y, b.y), Min(c.y, d.y));
	float maxy = Max(Max(a.y, b.y), Max(c.y, d.y));
	float minz = Min(Min(a.z, b.z), Min(c.z, d.z));
	float maxz = Max(Max(a.z, b.z), Max(c.z, d.z));

	if ( amount > 300.0f )
	{
		PlayOneShotScriptObject(SCRIPT_SOUND_GLASS_BREAK_L, object->GetPosition());

		GeneratePanesForWindow(0,
			CVector(minx,      miny,      minz),
			CVector(0.0f,      0.0f,      maxz-minz),
			CVector(maxx-minx, maxy-miny, 0.0f),
			speed, point, 0.1f, !!object->bGlassCracked, explosion);
	}
	else
	{
		PlayOneShotScriptObject(SCRIPT_SOUND_GLASS_BREAK_S, object->GetPosition());

		GeneratePanesForWindow(1,
			CVector(minx,      miny,      minz),
			CVector(0.0f,      0.0f,      maxz-minz),
			CVector(maxx-minx, maxy-miny, 0.0f),
			speed, point, 0.1f, !!object->bGlassCracked, explosion);
	}

	object->bGlassBroken = true;
	object->GetMatrix().GetPosition().z = -100.0f;
}

void
CGlass::WindowRespondsToSoftCollision(CEntity *entity, float amount)
{
	ASSERT(entity!=nil);

	CObject *object = (CObject *)entity;

	if ( amount > 50.0f && !object->bGlassCracked )
	{
		PlayOneShotScriptObject(SCRIPT_SOUND_GLASS_CRACK, object->GetPosition());
		object->bGlassCracked = true;
	}
}

void
CGlass::WasGlassHitByBullet(CEntity *entity, CVector point)
{
	ASSERT(entity!=nil);

	CObject *object = (CObject *)entity;

	if ( IsGlass(object->GetModelIndex()) )
	{
		if ( !object->bGlassCracked )
		{
			PlayOneShotScriptObject(SCRIPT_SOUND_GLASS_CRACK, object->GetPosition());
			object->bGlassCracked = true;
		}
		else
		{
			if ( (CGeneral::GetRandomNumber() & 3) == 2 )
				WindowRespondsToCollision(object, 0.0f, CVector(0.0f, 0.0f, 0.0f), point, false);
		}
	}
}

void
CGlass::WindowRespondsToExplosion(CEntity *entity, CVector point)
{
	ASSERT(entity!=nil);

	CObject *object = (CObject *)entity;

	CVector distToGlass = object->GetPosition() - point;

	float fDistToGlass = distToGlass.Magnitude();

	if ( fDistToGlass < 10.0f )
	{
		distToGlass *= (0.3f / fDistToGlass); // normalise
		WindowRespondsToCollision(object, 10000.0f, distToGlass, object->GetPosition(), true);
	}
	else
	{
		if ( fDistToGlass < 30.0f )
			object->bGlassCracked = true;
	}
}


code:
#pragma once

class CEntity;

class CFallingGlassPane : public CMatrix
{
public:
	CVector m_vecMoveSpeed;
	CVector m_vecTurn;
	uint32 m_nTimer;
	float m_fGroundZ;
	float m_fStep;
	uint8 m_nTriIndex;
	bool m_bActive;
	bool m_bShattered;

	CFallingGlassPane()  { }
	~CFallingGlassPane() { }

	void Update(void);
	void Render(void);
};

VALIDATE_SIZE(CFallingGlassPane, 0x70);

enum
{
	NUM_GLASSTRIANGLES = 5,
};

class CGlass
{
	static uint32 NumGlassEntities;
	static CEntity *apEntitiesToBeRendered[NUM_GLASSENTITIES];
	static CFallingGlassPane aGlassPanes[NUM_GLASSPANES];
public:
	static void Init(void);
	static void Update(void);
	static void Render(void);
	static CFallingGlassPane *FindFreePane(void);
	static void GeneratePanesForWindow(uint32 type, CVector pos, CVector up, CVector right, CVector speed, CVector point, float moveSpeed, bool cracked, bool explosion);
	static void AskForObjectToBeRenderedInGlass(CEntity *entity);
	static void RenderEntityInGlass(CEntity *entity);
	static int32 CalcAlphaWithNormal(CVector *normal);
	static void RenderHiLightPolys(void);
	static void RenderShatteredPolys(void);
	static void RenderReflectionPolys(void);
	static void WindowRespondsToCollision(CEntity *entity, float amount, CVector speed, CVector point, bool explosion);
	static void WindowRespondsToSoftCollision(CEntity *entity, float amount);
	static void WasGlassHitByBullet(CEntity *entity, CVector point);
	static void WindowRespondsToExplosion(CEntity *entity, CVector point);
};