Example #1
0
void ShutDown()
{
#if BUILD_DEV
	PRINTF( "SimCount: %d RenderCount: %d\n", g_DEBUGTickSimCount, g_DEBUGTickRenderCount );
#endif

	g_Statuses.Clear();
	g_HTTPResultBuffer.Clear();
	g_FilesInManifest.Clear();
	g_CommandLineArguments.Clear();

	SafeDelete( g_CommandLine );

	SafeDelete( g_Clock );

	SafeDelete( g_Keyboard );

	SafeDelete( g_Renderer );
	SafeDelete( g_MenuSurface );
	SafeDelete( g_BackBufferSurface );

	SafeDelete( g_HTTPSocket );

	StringManager::DeleteInstance();
	PrintManager::DeleteInstance();
	ConfigManager::DeleteInstance();
	PackStream::StaticShutDown();
}
	void OvrOutOfSpaceMenu::BuildMenu( int memoryInKB )
	{
		const VRMenuFontParms fontParms( true, true, false, false, true, 0.505f, 0.43f, 1.0f );
		Array< VRMenuObjectParms const * > parms;
		int menuId = 9000;

		// ---
		// Icon
		{
			VRMenuSurfaceParms iconSurfParms( "",
					"res/raw/out_of_disk_space_warning.png", SURFACE_TEXTURE_DIFFUSE,
					"", SURFACE_TEXTURE_MAX,
					"", SURFACE_TEXTURE_MAX );
			VRMenuObjectParms iconParms(
					VRMENU_STATIC, Array< VRMenuComponent* >(), iconSurfParms, "",
					Posef( Quatf(), Vector3f( 0.0f, CENTER_TO_ICON_Y_OFFSET, 0.0f ) ),
					Vector3f( 1.0f ), fontParms, VRMenuId_t( ++menuId ),
					VRMenuObjectFlags_t( VRMENUOBJECT_DONT_HIT_ALL ),
					VRMenuObjectInitFlags_t( VRMENUOBJECT_INIT_FORCE_POSITION ) );
			parms.PushBack( &iconParms );
			AddItems( AppPtr->GetVRMenuMgr(), AppPtr->GetDefaultFont(), parms, GetRootHandle(), true );
			parms.Clear();
		}

		// ---
		// Message
		{
			String outOfSpaceMsg;
			VrLocale::GetString( AppPtr->GetVrJni(), AppPtr->GetJavaObject(),
					"@string/out_of_memory",
					"To use this app, please free up at least %dKB of storage space on your phone.",
					outOfSpaceMsg );

			char charBuff[10];
			sprintf( charBuff, "%d", memoryInKB );
			outOfSpaceMsg = VrLocale::GetXliffFormattedString( outOfSpaceMsg, charBuff );

			BitmapFont & font = AppPtr->GetDefaultFont();
			font.WordWrapText( outOfSpaceMsg, 1.4f );

			VRMenuObjectParms titleParms(
				VRMENU_STATIC,
				Array< VRMenuComponent* >(),
				VRMenuSurfaceParms(),
				(const char*)outOfSpaceMsg,
				Posef( Quatf(), Vector3f( 0.0f, CENTER_TO_TEXT_Y_OFFSET, 0.0f ) ),
				Vector3f( 1.0f ),
				fontParms,
				VRMenuId_t( ++menuId ),
				VRMenuObjectFlags_t( VRMENUOBJECT_DONT_HIT_TEXT ),
				VRMenuObjectInitFlags_t( VRMENUOBJECT_INIT_FORCE_POSITION ) );
			parms.PushBack( &titleParms );
			AddItems( AppPtr->GetVRMenuMgr(), AppPtr->GetDefaultFont(), parms, GetRootHandle(), true );
			parms.Clear();
		}

		this->SetMenuPose( Posef( Quatf(), Vector3f( 0.0f, 0.0f, -3.0f ) ) );
	}
Example #3
0
// Get fake Poisson taps in one-third sections of
// the unit hemisphere for doing directional AO.
void MeshCompiler::GetAmbientOcclusionTaps( Array< Vector >& Taps, const Matrix& TangentSpace )
{
	Taps.Clear();
	Taps.Resize( 51 );
	Taps[0] = Vector( 0.0f, 0.81649700000000003f, 0.57735000000000003f );
	Taps[1] = Vector( -0.74401973459062531f, 0.57783472685691717f, 0.33547229837631554f );
	Taps[2] = Vector( 0.25901018724643815f, 0.68792466879887804f, 0.67799216290494024f );
	Taps[3] = Vector( -0.58988856970793446f, 0.80685558587873407f, 0.031867520521874151f );
	Taps[4] = Vector( 0.26882545565790789f, 0.93007621426021569f, 0.25038192837683715f );
	Taps[5] = Vector( 0.0041285378312679675f, 0.52339192756451713f, 0.85208206490670535f );
	Taps[6] = Vector( 0.52300845383744843f, 0.83589430002845266f, 0.16656192960729299f );
	Taps[7] = Vector( 0.67164601369536103f, 0.61759181590387924f, 0.40923340676889991f );
	Taps[8] = Vector( -0.38725619624135338f, 0.76349261896781795f, 0.51682846211711353f );
	Taps[9] = Vector( 0.55273004695713479f, 0.56155706754364609f, 0.61574601507646354f );
	Taps[10] = Vector( 0.72493806462362065f, 0.68525434936331431f, 0.069937680390617263f );
	Taps[11] = Vector( -0.57003909323433155f, 0.74767366048824102f, 0.34064575382161405f );
	Taps[12] = Vector( -0.4883240745402157f, 0.56430943593345706f, 0.66565340736820811f );
	Taps[13] = Vector( 0.24691230716222037f, 0.50036658190736905f, 0.82985998595074195f );
	Taps[14] = Vector( -0.26737561786638481f, 0.53293155768514677f, 0.80280398217363869f );
	Taps[15] = Vector( -0.33103794538084164f, 0.93594428249487172f, 0.12009237604107406f );
	Taps[16] = Vector( 0.076679712920537185f, 0.99461859155774424f, 0.069671220414983512f );

	Matrix FirstSection = Matrix::CreateRotationAboutZ( -TWOPI / 3.0f );
	Matrix ThirdSection = Matrix::CreateRotationAboutZ( TWOPI / 3.0f );

	for( uint i = 0; i < 17; ++i )
	{
		Vector Tap = Taps[ i ];
		Taps[ i ] = ( Tap * FirstSection ) * TangentSpace;
		Taps[ i + 17 ] = Tap * TangentSpace;
		Taps[ i + 34 ] = ( Tap * ThirdSection ) * TangentSpace;
	}
}
Example #4
0
void Ctrl::GetWorkArea(Array<Rect>& rc)
{
	GuiLock __;
	GdkScreen *s = gdk_screen_get_default();
	int n = gdk_screen_get_n_monitors(s);
	rc.Clear();
	Vector<int> netwa;
	for(int i = 0; i < n; i++) {
		GdkRectangle rr;
		Rect r;
#if GTK_CHECK_VERSION (3, 3, 5) // U++ does not work with gtk3 yet, but be prepared
		gdk_screen_get_monitor_workarea(s, i, &rr);
		r = RectC(r.x, r.y, r.width, r.height);
#else
		gdk_screen_get_monitor_geometry (s, i, &rr);
		r = RectC(rr.x, rr.y, rr.width, rr.height);
	#ifdef GDK_WINDOWING_X11
		if(i == 0)
			netwa = GetPropertyInts(gdk_screen_get_root_window(gdk_screen_get_default()),
			                        "_NET_WORKAREA");
		if(netwa.GetCount())
			r = r & RectC(netwa[0], netwa[1], netwa[2], netwa[3]);
	#endif
#endif
		rc.Add(r);
	}
}
Example #5
0
// Add a bunch of strings together to produce a more robust key
void Crypto::ConstructKeyFromStrings( const Array< SimpleString >& Keys, Array< char >& OutKey )
{
	ASSERT( Keys.Size() );

	Array< Array< char > > KeyArrays;
	uint Length = Keys[0].Length();

	// Push arrays one at a time instead of resizing, so they are constructed and not simply allocated
	for( uint KeyIndex = 0; KeyIndex < Keys.Size(); ++KeyIndex )
	{
		const SimpleString& Key = Keys[ KeyIndex ];
		KeyArrays.PushBack( Array< char >() );
		Key.FillArray( KeyArrays[ KeyIndex ] );
		Length = Min( Length, Key.Length() );
	}

	OutKey.Clear();
	for( uint Index = 0; Index < Length; ++Index )
	{
		OutKey.PushBack( 0 );
		for( uint KeyIndex = 0; KeyIndex < Keys.Size(); ++KeyIndex )
		{
			OutKey[ Index ] = ( OutKey[ Index ] + KeyArrays[ KeyIndex ][ Index ] ) & 255;
		}
	}
}
Example #6
0
void SimpleString::FillArray( Array<char>& OutArray, bool WithNull /*= false*/ ) const
{
	const uint Length = WithNull ? m_Length + 1 : m_Length;
	OutArray.Clear();
	OutArray.Resize( Length );
	memcpy_s( OutArray.GetData(), Length, m_String, Length );
}
Example #7
0
/*virtual*/ void D3D9Renderer::EnumerateDisplayModes(
    Array<SDisplayMode>& DisplayModes) {
  DisplayModes.Clear();

  EnumerateDisplayModes(DisplayModes, D3DFMT_X8R8G8B8);
  EnumerateDisplayModes(DisplayModes, D3DFMT_A8R8G8B8);

  ASSERT(DisplayModes.Size());
}
Example #8
0
//==============================
// ovrFileSysLocal::Shutdown
void ovrFileSysLocal::Shutdown()
{
	for ( int i = 0; i < Schemes.GetSizeI(); ++i )
	{
		Schemes[i]->Shutdown();
		delete Schemes[i];
		Schemes[i] = NULL;
	}
	Schemes.Clear();
}
// From http://stackoverflow.com/questions/9524309/enumdisplaydevices-function-not-working-for-me
void GetGraphicsCardList( Array< String > &gpus)
{
    gpus.Clear();
    DISPLAY_DEVICEW dd;
    dd.cb = sizeof(dd);

    DWORD deviceNum = 0;
    while( EnumDisplayDevicesW(NULL, deviceNum, &dd, 0) )
    {
        if (dd.StateFlags & DISPLAY_DEVICE_PRIMARY_DEVICE)
            gpus.PushBack(String(dd.DeviceString));
        deviceNum++;
    }
}
Example #10
0
/*static*/ void Display::EnumerateDisplayModes( Array<SDisplayMode>& DisplayModes )
{
	DisplayModes.Clear();

#if BUILD_WINDOWS_NO_SDL
	DEVMODE	DevMode;
	uint	ModeIndex	= 0;
	BOOL	Valid		= TRUE;
	for( ; Valid; ++ModeIndex )
	{
		Valid = EnumDisplaySettings( NULL, ModeIndex, &DevMode );

		// Some users have problems if their refresh rate is set to 59 Hz. Maybe I should reconsider this?
		if( DevMode.dmBitsPerPel == 32 )
		{
			SDisplayMode Mode;
			Mode.Width	= DevMode.dmPelsWidth;
			Mode.Height	= DevMode.dmPelsHeight;
			DisplayModes.PushBackUnique( Mode );
		}
	}
#endif
#if BUILD_SDL
	PRINTF( "Enumerating SDL display modes...\n" );
	const int NumDisplays		= SDL_GetNumVideoDisplays();
	for( int DisplayIndex = 0; DisplayIndex < NumDisplays; ++DisplayIndex )
	{
		const int NumModes = SDL_GetNumDisplayModes( DisplayIndex );
		for( int ModeIndex = 0; ModeIndex < NumModes; ++ModeIndex )
		{
			SDL_DisplayMode DisplayMode;
			SDL_GetDisplayMode( DisplayIndex, ModeIndex, &DisplayMode );

			if( SDL_BYTESPERPIXEL( DisplayMode.format ) == 4 )
			{
				SDisplayMode Mode;
				Mode.Width	= DisplayMode.w;
				Mode.Height	= DisplayMode.h;
				DisplayModes.PushBackUnique( Mode );

				PRINTF( "Enumerated mode %dx%d\n", Mode.Width, Mode.Height );
			}
		}
	}
#endif

	ASSERT( DisplayModes.Size() );
}
Example #11
0
void StreamReader::ReadString(String *result, const String &delimiter) {
    Array<Char> retString;
    Array<Char> delString;
    String strDelimiter = delimiter;
    Char c;
    if (strDelimiter.IsEmpty()) {
        strDelimiter.Resize(1);
        strDelimiter.Append("\0");
    }
    while (true) {
        c = ReadByte();
        if (this->GetError())
            break;
        if (c == strDelimiter.GetData()[0]) {
            delString.Clear();
            delString.Append(c);
            for (Int i = 1; i < strDelimiter.GetSizeInBytes(); i++) {
                c = ReadByte();
                if (this->GetError()) {
                    for (Int j = 0; j < delString.GetElementCount(); j++)
                        retString.Append(delString[j]);
                    break;
                }
                delString.Append(c);
                if (c != strDelimiter.GetData()[i])
                    break;
            }
            if (strDelimiter.GetSizeInBytes() > delString.GetElementCount())
                for (Int i = 0; i < delString.GetElementCount(); i++)
                    retString.Append(delString[i]);
            else {
                if (memcmp(strDelimiter.GetData(),
                           delString.GetData(), delString.GetElementCount()))
                {
                    for (Int i = 0; i < delString.GetElementCount(); i++)
                        retString.Append(delString[i]);
                }
                else
                    break;
            }
        } else {
            retString.Append(c);
        }
    }
    result->Resize(retString.GetElementCount());
    memcpy((Char*)result->GetData(),
           retString.GetData(), retString.GetElementCount());
}
Example #12
0
// [TODO] Comment/Cleanup
void CubicSpline::CalculateCubicSpline(uint32 n, Array<TransferControlPoint> &v, Array<CubicSpline> &cubic)
{
	if (n) {
		// From: http://graphicsrunner.blogspot.com/2009/01/volume-rendering-102-transfer-functions.html

		float *gamma = new float[n + 1];
		float *delta = new float[n + 1];
		float *D = new float[n + 1];

		// We need to solve the equation
		//	* taken from: http://mathworld.wolfram.com/CubicSpline.html
		//	[2 1       ] [D[0]]   [3(v[1] - v[0])  ]
		//	|1 4 1     | |D[1]|   |3(v[2] - v[0])  |
		//	|  1 4 1   | | .  | = |      .         |
		//	|    ..... | | .  |   |      .         |
		//	|     1 4 1| | .  |   |3(v[n] - v[n-2])|
		//	[       1 2] [D[n]]   [3(v[n] - v[n-1])]

		//	by converting the matrix to upper triangular.
		//	The D[i] are the derivatives at the control points.

		// This builds the coefficients of the left matrix
		gamma[0] = 1.0f / 2.0f;
		for (uint32 i=1; i<n; i++)
			gamma[i] = 1.0f / ((4 * 1.0f) - gamma[i - 1]);
		gamma[n] = 1.0f / ((2 * 1.0f) - gamma[n - 1]);

		delta[0] = 3 * (v[1].GetValue() - v[0].GetValue()) * gamma[0];
		for (uint32 i=1; i<n; i++)
			delta[i] = (3 * (v[i + 1].GetValue() - v[i - 1].GetValue()) - delta[i - 1]) * gamma[i];
		delta[n] = (3 * (v[n].GetValue() - v[n - 1].GetValue()) - delta[n - 1]) * gamma[n];

		D[n] = delta[n];
		for (int i=n-1; i>= 0; i--)
			D[i] = delta[i] - gamma[i] * D[i + 1];

		// Now compute the coefficients of the cubics
		cubic.Clear();
		for (uint32 i=0; i<n; i++)
			cubic.Add(CubicSpline(v[i].GetValue(), D[i], 3*(v[i + 1].GetValue() - v[i].GetValue()) - 2*D[i] - D[i + 1], 2*(v[i].GetValue() - v[i + 1].GetValue()) + D[i] + D[i + 1]));

		delete [] gamma;
		delete [] delta;
		delete [] D;
	}
}
Example #13
0
void Crypto::Decrypt( const Array< char >& Ciphertext, const Array< char >& Key, Array< char >& OutPlaintext )
{
	ARC4Initialize( Key );

	uint8 Nonce = Ciphertext[ Ciphertext.Size() - 1 ];
	for( uint Step = 0; Step < Nonce + FixedStep; ++Step )
	{
		ARC4Step();
	}

	OutPlaintext.Clear();
	OutPlaintext.Resize( Ciphertext.Size() - Overhead );

	for( uint Index = 0; Index < Ciphertext.Size() - Overhead; ++Index )
	{
		OutPlaintext[ Index ] = Ciphertext[ Index ] ^ ARC4Step();
	}
}
Example #14
0
void ProcessList::Fill() {
	Process.Reset();
	Process.AddColumn("Id", 6);
	Process.AddColumn("Priority", 6);
	Process.AddColumn("Program", 12);
	Array<int64> pidL;
	pidL.Clear(); 
	Array<String> pNames;
	if (!GetProcessList(pidL, pNames))
		Process.Add("Error getting process info");
	else {
		for (int i = 0; i < pidL.GetCount(); ++i) {
			int priority = GetProcessPriority(pidL[i]);
			Process.Add(Format64(pidL[i]), priority >= 0? FormatInt(priority): "Not accesible", pNames[i]);
		}
	}
	ButUpdate.WhenPush = THISBACK(ButUpdate_Push);
}
//==============================
// VRMenuEventHandler::HandleEvents
void VRMenuEventHandler::HandleEvents( OvrGuiSys & guiSys, VrFrame const & vrFrame, 
		menuHandle_t const rootHandle, Array< VRMenuEvent > const & events ) const
{
	VRMenuObject * root = guiSys.GetVRMenuMgr().ToObject( rootHandle );
	if ( root == NULL )
	{
		return;
	}

	// find the list of all objects that are in the focused path
	Array< menuHandle_t > focusPath;
	FindTargetPath( guiSys, rootHandle, FocusedHandle, focusPath );
    
	Array< menuHandle_t > targetPath;

	for ( int i = 0; i < events.GetSizeI(); ++i )
	{
		VRMenuEvent const & event = events[i];
		switch ( event.DispatchType )
		{
			case EVENT_DISPATCH_BROADCAST:
			{
				// broadcast to everything
				BroadcastEvent( guiSys, vrFrame, event, root );
			}
			break;
			case EVENT_DISPATCH_FOCUS:
				// send to the focus path only -- this list should be parent -> child order
				DispatchToPath( guiSys, vrFrame, event, focusPath, false );
				break;
			case EVENT_DISPATCH_TARGET:
				if ( targetPath.GetSizeI() == 0 || event.TargetHandle != targetPath.Back() )
				{
					targetPath.Clear();
					FindTargetPath( guiSys, rootHandle, event.TargetHandle, targetPath );
				}
				DispatchToPath( guiSys, vrFrame, event, targetPath, false );
				break;
			default:
				OVR_ASSERT( !"unknown dispatch type" );
				break;
		}
	}
}
Example #16
0
void Crypto::Encrypt( const Array< char >& Plaintext, const Array< char >& Key, Array< char >& OutCiphertext )
{
	ARC4Initialize( Key );

	uint8 Nonce = (char)Math::Random( 256 );
	for( uint Step = 0; Step < Nonce + FixedStep; ++Step )
	{
		ARC4Step();
	}

	OutCiphertext.Clear();
	OutCiphertext.Resize( Plaintext.Size() + Overhead );

	for( uint Index = 0; Index < Plaintext.Size(); ++Index )
	{
		OutCiphertext[ Index ] = Plaintext[ Index ] ^ ARC4Step();
	}

	// Sign the array with the nonce we chose
	OutCiphertext[ OutCiphertext.Size() - 1 ] = Nonce;
}
Example #17
0
void Patcher_HandleReceipt_ManifestFile()
{
	g_FilesInManifest.Clear();
	g_NextPatchFileIndex = 0;

	char* MessageContent = strstr( g_HTTPResultBuffer.GetData(), CRLF CRLF );
	if( !MessageContent )
	{
		AddStatus( "Error receiving manifest file.", g_StatusWarningColor );
		++g_NumWarnings;
		return;
	}

	MessageContent += 4;

	uint Offset = ( uint )( MessageContent - g_HTTPResultBuffer.GetData() );
	uint ContentSize = g_HTTPSocket->AsyncGetBytesReceived() - Offset;

	Array<SimpleString>	Lines;
	SplitIntoLines( MessageContent, ContentSize, Lines );

	for( uint LinesIndex = 0; LinesIndex + 2 < Lines.Size(); LinesIndex += 3 )
	{
		SManifestFile ManifestFile;
		ManifestFile.m_Filename = Lines[ LinesIndex ];
		ManifestFile.m_Length = Lines[ LinesIndex + 1 ];
		ManifestFile.m_Checksum = Lines[ LinesIndex + 2 ];
		ManifestFile.m_Validated = false;

		g_FilesInManifest.PushBack( ManifestFile );
	}

	AddStatus( "Manifest file received.", g_StatusColor );

	if( g_NextPatchFileIndex < g_FilesInManifest.Size() )
	{
		Patcher_GetNextPatchFile();
	}
}
void MoviePlayerView::CreateMenu( App * app, OvrVRMenuMgr & menuMgr, BitmapFont const & font )
{
	Menu = VRMenu::Create( "MoviePlayerMenu" );

    Array< VRMenuObjectParms const * > parms;

	Posef moveScreenPose( Quatf( Vector3f( 0.0f, 1.0f, 0.0f ), 0.0f ),
			Vector3f(  0.0f, 0.0f,  -1.8f ) );

	VRMenuFontParms moveScreenFontParms( true, true, false, false, false, 0.5f );

	VRMenuSurfaceParms moveScreenSurfParms( "",
			NULL, SURFACE_TEXTURE_MAX,
			NULL, SURFACE_TEXTURE_MAX,
			NULL, SURFACE_TEXTURE_MAX );

	VRMenuObjectParms moveScreenParms( VRMENU_BUTTON, Array< VRMenuComponent* >(), moveScreenSurfParms,
			Strings::MoviePlayer_Reorient, moveScreenPose, Vector3f( 1.0f ), moveScreenFontParms, ID_MOVE_SCREEN,
			VRMenuObjectFlags_t(), VRMenuObjectInitFlags_t( VRMENUOBJECT_INIT_FORCE_POSITION ) );

	parms.PushBack( &moveScreenParms );

	Menu->InitWithItems(menuMgr, font, 0.0f, VRMenuFlags_t( VRMENU_FLAG_TRACK_GAZE ) | VRMENU_FLAG_BACK_KEY_DOESNT_EXIT, parms);
	parms.Clear();

	MoveScreenHandle = Menu->HandleForId( menuMgr, ID_MOVE_SCREEN );
	MoveScreenObj = menuMgr.ToObject( MoveScreenHandle );

    MoveScreenObj->AddFlags( VRMENUOBJECT_DONT_RENDER );
	Vector3f moveScreenTextPosition = Vector3f( 0.0f, -24 * VRMenuObject::DEFAULT_TEXEL_SCALE, 0.0f );
    MoveScreenObj->SetTextLocalPosition( moveScreenTextPosition );

    // ==============================================================================
    //
    // finalize
    //
    Cinema.app->GetGuiSys().AddMenu( Menu );
}
Example #19
0
void Raytracer::SetParams(Camera* camera, const char* path, int w, int h, AntiAlias aa)
{
	//Timer timer;
	raycount = 0;
	mode = aa;
	width = w;
	height = h;

	visualnodes.Clear();
	visualtransforms.Clear();
	visualboxes.Clear();
	lightnodes.Clear();
	lighttransforms.Clear();

	// go through the scene graph and cache stuff
	Node* root = camera->GetRoot();
	for(Node* node = root; node; node=node->GetNext())
	{
		if(node->HasFlag(Node::VISUAL))
		{
			Visual* visual = static_cast<Visual*>(node);
			visualnodes.PushBack(visual);
			visualtransforms.PushBack(visual->GetWorldTransform());
			visualboxes.PushBack(visual->GetWorldBox());
		}
		else if(node->HasFlag(Node::LIGHT))
		{
			Light* light = static_cast<Light*>(node);
			lightnodes.PushBack(light);
			lighttransforms.PushBack(light->GetWorldTransform());
		}
	}

	if(mode == ADAPTIVE)
	{
		width++;
		height++;
	}
	else if(mode == SUPERSAMPLE2X)
	{
		width *= 2;
		height *= 2;
	}
   
    // calculate image plane stuff
    float d = 10;     // distance from camera to plane (n'importe quoi...)        
    float sj = 2 * d * math::Tan(math::ToRadians(camera->GetHorizontalFov() / 2));	// width of plane
    float sk = sj * ((float)height/(float)width);	// height
	origin = camera->GetWorldTransform().GetTranslation(); 
    vector3f dirz = camera->GetWorldTransform().GetDirection();	// forward vector
    vector3f diry = vector3f(0,1,0);    // up vector
    vector3f dirx = Normalize(CrossProduct(dirz,diry));    // side vector
    p = origin + (d * dirz) - ((sj/2) * dirx) + ((sk/2) * diry);	// upper-left pixel of image plane
	incrementx = (sj*(1.f/(width-1))*dirx);	// one-pixel increment in x direction
	incrementy = (sk*(1.f/(height-1))*diry);	// one-pixel increment in y direction

	delete[] buffer;
	buffer = new vector3f[width * height];

	setparams = true;
}
Example #20
0
bool ContextLinux::QueryDisplayModes(Array<const PLRenderer::DisplayMode*> &lstDisplayModeList)
{
	bool bResult = false;	// Error by default

	// Clear old list of display modes
	for (uint32 i=0; i<lstDisplayModeList.GetNumOfElements(); i++)
		delete lstDisplayModeList[i];
	lstDisplayModeList.Clear();

	// Get list of display modes
	PL_LOG(Info, "Query available display modes")

	// Get XRR screen configuration (don't forget "XRRFreeScreenConfigInfo()" if you no longer need it)
	const int nScreen = XDefaultScreen(m_pDisplay);
	XRRScreenConfiguration *pXRRScreenConfiguration = XRRGetScreenInfo(m_pDisplay, RootWindow(m_pDisplay, nScreen));

	// Get specific configuration information out of our screen configuration
	int nNumOfModes = 0;
	XRRScreenSize *pXRRScreenSize = XRRConfigSizes(pXRRScreenConfiguration, &nNumOfModes);

	// Loop through all modes
	for (int nMode=0; nMode<nNumOfModes; nMode++) {
		// First at all, we're only interested in some of the settings - as a result, we really should check if there's
		// already a display mode within our list with the interesting settings of the current found display mode
		bool bNewMode = true;
		for (uint32 i=0; i<lstDisplayModeList.GetNumOfElements(); i++) {
			const PLRenderer::DisplayMode *pDisplayMode = lstDisplayModeList[i];
			if (pDisplayMode->vSize.x == pXRRScreenSize[nMode].width && pDisplayMode->vSize.y == pXRRScreenSize[nMode].height) {
				// We already have such a display mode within our list!
				bNewMode = false;

				// Get us out of this loop right now!
				i = lstDisplayModeList.GetNumOfElements();
			}
		}
		if (bNewMode) {
			// Get required information
			PLRenderer::DisplayMode *pDisplayMode = new PLRenderer::DisplayMode;
			pDisplayMode->vSize.x	  = pXRRScreenSize[nMode].width;
			pDisplayMode->vSize.y	  = pXRRScreenSize[nMode].height;
			pDisplayMode->nColorBits  = XDefaultDepth(m_pDisplay, nScreen);

			// [TODO] Under Linux there is currently no real 32 bit visual (RGBA)
			// only 24 bit (RGB) which is equal to 32 bit in RGB (without alpha value)
			if (pDisplayMode->nColorBits == 24)
				pDisplayMode->nColorBits = 32;
			pDisplayMode->nFrequency = 0;

			// Give out a log message
			String sTemp;
			if (pDisplayMode->nFrequency) {
				sTemp = String::Format("Found: %dx%dx%d %d Hz", pDisplayMode->vSize.x, pDisplayMode->vSize.y, pDisplayMode->nColorBits, pDisplayMode->nFrequency);
			} else {
				sTemp = String::Format("Found: %dx%dx%d", pDisplayMode->vSize.x, pDisplayMode->vSize.y, pDisplayMode->nColorBits);
			}

			// Add found display mode to list
			PL_LOG(Info, sTemp)
			lstDisplayModeList.Add(pDisplayMode);
		}
	}

	// Was at least one display mode found?
	if (lstDisplayModeList.GetNumOfElements())
		bResult = true; // Success! :D
	else
		PL_LOG(Error, "No available & supported display modes found!")

	// Free XRR screen configuration
	XRRFreeScreenConfigInfo(pXRRScreenConfiguration);

	// Done
	return bResult;
}
Example #21
0
void Mesh::_CalculateNormalsAndTangents()
{
	if (mT.IsValid() || mV.IsEmpty()) return;

	// Don't bother with points or lines
	if (mPrimitive == IGraphics::Primitive::Point	||
		mPrimitive == IGraphics::Primitive::Line	||
		mPrimitive == IGraphics::Primitive::LineStrip) return;

	// Allocate a temporary buffer to store binormals
	Array<Vector3f> binormals (mV.GetSize());

	// Remember whether we already have normals to work with
	bool calculateNormals  = (mV.GetSize() != mN.GetSize());

	// We can only calculate tangents if the texture coordinates are available
	bool calculateTangents = (mV.GetSize() == mTc0.GetSize());

	// If we should calculate normals, clear the existing normal array
	if (calculateNormals)
	{
		mN.Clear();
		mN.ExpandTo(mV.GetSize());
	}

	// Expand the tangent array
	if (calculateTangents) mT.ExpandTo(mV.GetSize());

	// The number of indices
	uint size = mIndices.IsValid() ? mIndices.GetSize() : GetNumberOfVertices();

	// Triangles
	if (size > 2)
	{
		bool even = true;
		uint i0, i1, i2;

		for (uint i = 0; i + 2 < size; )
		{
			i0 = i;
			i1 = i+1;
			i2 = i+2;

			if (mIndices.IsValid())
			{
				i0 = mIndices[i0];
				i1 = mIndices[i1];
				i2 = mIndices[i2];
			}

			ASSERT(i0 < mV.GetSize(), "Index out of bounds!");
			ASSERT(i1 < mV.GetSize(), "Index out of bounds!");
			ASSERT(i2 < mV.GetSize(), "Index out of bounds!");

			const Vector3f& v0 ( mV[i0] );
			const Vector3f& v1 ( mV[i1] );
			const Vector3f& v2 ( mV[i2] );

			Vector3f v10 (v1 - v0);
			Vector3f v20 (v2 - v0);

			if (calculateNormals)
			{
				Vector3f normal (Cross(v10, v20));

				mN[i0] += normal;
				mN[i1] += normal;
				mN[i2] += normal;
			}

			if (calculateTangents)
			{
				const Vector2f& t0 ( mTc0[i0] );
				const Vector2f& t1 ( mTc0[i1] );
				const Vector2f& t2 ( mTc0[i2] );

				Vector2f t10 (t1 - t0);
				Vector2f t20 (t2 - t0);

				float denominator = t10.x * t20.y - t20.x * t10.y;

				if ( Float::IsNotZero(denominator) )
				{
					float scale = 1.0f / denominator;

					Vector3f tangent ((v10.x * t20.y - v20.x * t10.y) * scale,
									  (v10.y * t20.y - v20.y * t10.y) * scale,
									  (v10.z * t20.y - v20.z * t10.y) * scale);

					Vector3f binormal((v20.x * t10.x - v10.x * t20.x) * scale,
									  (v20.y * t10.x - v10.y * t20.x) * scale,
									  (v20.z * t10.x - v10.z * t20.x) * scale);

					mT[i0] += tangent;
					mT[i1] += tangent;
					mT[i2] += tangent;

					binormals[i0] += binormal;
					binormals[i1] += binormal;
					binormals[i2] += binormal;
				}
			}

			if (mPrimitive == IGraphics::Primitive::Triangle)
			{
				i += 3;
			}
			else if (mPrimitive == IGraphics::Primitive::Quad)
			{
				if (even) ++i;
				else i += 3;
				even = !even;
			}
			else ++i;
		}

		// If we're calculating normals we need to match all normals with identical vertices
		if (calculateNormals)
		{
			Array<uint> matches;

			for (uint i = 0; i < mV.GetSize(); ++i)
			{
				matches.Clear();
				matches.Expand() = i;
				Vector3f N = mN[i];

				const Vector3f& V (mV[i]);

				for (uint b = 0; b < mV.GetSize(); ++b)
				{
					if (i != b && V == mV[b])
					{
						matches.Expand() = b;
						N += mN[b];
					}
				}

				N.Normalize();

				for (uint b = 0; b < matches.GetSize(); ++b)
				{
					mN[ matches[b] ] = N;
				}
			}
		}
	}

	if (calculateTangents)
	{
		// Normalize all tangents
		for (uint i = 0; i < mV.GetSize(); ++i)
		{
			Vector3f&  T (mT[i]);
			Vector3f&  B (binormals[i]);
			Vector3f&  N (mN[i]);

			// In order to avoid visible seams, the tangent should be 90 degrees to the normal
			// Note to self: Gram-Schmidt formula for the cross product below: T = T - N * Dot(N, T);
			T = Cross(B, N);
			T.Normalize();

			// Flip the tangent if the handedness is incorrect
			if (Dot(Cross(T, B), N) < 0.0f) T.Flip();
		}
	}
}
Example #22
0
void ConfigParser::Parse( const IDataStream& Stream )
{
	Array< SToken >	Tokens;
	SToken			Token;
	Token.m_TokenType						= SToken::ET_Name;
	char			StrMark					= 0;	// Stores the character (either ' or ") that opened a string
	SToken			MacroToken;
	List<int>		ArrayCounters;
	Array<char>		CounterCharArray;
	int				LineCount				= 1;

	for(;;)
	{
		char c = Stream.ReadInt8();

		// Skip the UTF-8 byte order mark if present.
		if( UTF8_BOM_0 == static_cast<byte>( c ) )
		{
			CHECK( UTF8_BOM_1 == static_cast<byte>( Stream.ReadInt8() ) );
			CHECK( UTF8_BOM_2 == static_cast<byte>( Stream.ReadInt8() ) );
			c = Stream.ReadInt8();
		}

		if( Stream.EOS() )
		{
			if( Token.m_TokenString.Empty() )
			{
				Token.m_TokenType = SToken::ET_None;
				Tokens.PushBack( Token );
				DEBUGCATPRINTF( "Core", 2, "%s\n", SToken::m_TokenNames[ Token.m_TokenType ] );
			}
			else
			{
				Token.m_TokenString.PushBack( '\0' );
				Tokens.PushBack( Token );
				DEBUGCATPRINTF( "Core", 2, "%s: %s\n", SToken::m_TokenNames[ Token.m_TokenType ], Token.m_TokenString.GetData() );
				Token.m_TokenString.Clear();
			}

			break;
		}

		if( c == '&' )
		{
			if( Token.m_TokenType == SToken::ET_Name )
			{
				// Increment the current counter and add it to the current name.
				ASSERT( ArrayCounters.Size() > 0 );
				List<int>::Iterator CounterIter = ArrayCounters.Back();
				( *CounterIter )++;
				SimpleString CounterString = SimpleString::PrintF( "%d", *CounterIter );
				CounterCharArray.Clear();
				CounterString.FillArray( CounterCharArray );
				Token.m_TokenString.Append( CounterCharArray );
			}
			else if( Token.m_TokenType == SToken::ET_None )
			{
				// Add a new counter
				// Push a counter token that will be replaced with the count int later.
				ArrayCounters.PushBack( -1 );
				Token.m_TokenType = SToken::ET_Counter;
			}
			else if( Token.m_TokenType == SToken::ET_String )
			{
				Token.m_TokenString.PushBack( c );
			}
			else
			{
				WARNDESC( "Unexpected character '&' in token." );
			}
		}
		else if( c == '^' )
		{
			if( Token.m_TokenType == SToken::ET_Name )
			{
				// Add the current counter to the current name.
				ASSERT( ArrayCounters.Size() > 0 );
				List<int>::Iterator CounterIter = ArrayCounters.Back();
				ASSERT( ( *CounterIter ) >= 0 );
				SimpleString CounterString = SimpleString::PrintF( "%d", *CounterIter );
				CounterCharArray.Clear();
				CounterString.FillArray( CounterCharArray );
				Token.m_TokenString.Append( CounterCharArray );
			}
			else if( Token.m_TokenType == SToken::ET_String )
			{
				Token.m_TokenString.PushBack( c );
			}
			else
			{
				WARNDESC( "Unexpected character '^' in token." );
			}
		}
		else if( c == ' ' || c == '\t' )
		{
			switch( Token.m_TokenType )
			{
			case SToken::ET_None:
			case SToken::ET_Equals:
				// Ignore whitespace
				break;
			case SToken::ET_Name:
			case SToken::ET_Context:
			case SToken::ET_Macro:
				if( Token.m_TokenString.Empty() )
				{
					// If the name is empty, ignore whitespace (before the name)
				}
				else
				{
					// Close current token, push it, and expect an equals

					// If we're closing a macro, save it as such
					if( Token.m_TokenType == SToken::ET_Macro )
					{
						MacroToken = Token;
					}

					Token.m_TokenString.PushBack( '\0' );
					Tokens.PushBack( Token );
					DEBUGCATPRINTF( "Core", 2, "%s: %s\n", SToken::m_TokenNames[ Token.m_TokenType ], Token.m_TokenString.GetData() );
					Token.m_TokenString.Clear();

					if( Token.m_TokenType == SToken::ET_Name )
					{
						Token.m_TokenType = SToken::ET_Equals;
					}
					else if( Token.m_TokenType == SToken::ET_Context || Token.m_TokenType == SToken::ET_Macro )
					{
						Token.m_TokenType = SToken::ET_Name;
					}
				}
				break;
			case SToken::ET_Bool:
			case SToken::ET_Int:
			case SToken::ET_Float:
				// Close current token, push it, and expect nothing
				Token.m_TokenString.PushBack( '\0' );
				Tokens.PushBack( Token );
				DEBUGCATPRINTF( "Core", 2, "%s: %s\n", SToken::m_TokenNames[ Token.m_TokenType ], Token.m_TokenString.GetData() );
				Token.m_TokenString.Clear();

				Token.m_TokenType = SToken::ET_None;
				break;
			case SToken::ET_String:
				Token.m_TokenString.PushBack( c );
				break;
			default:
				WARNDESC( "Unexpected token" );
				break;
			}
		}
		else if( c == '=' )
		{
			switch( Token.m_TokenType )
			{
			case SToken::ET_Name:
				// Close current token, push it and an equals
				Token.m_TokenString.PushBack( '\0' );
				Tokens.PushBack( Token );
				DEBUGCATPRINTF( "Core", 2, "%s: %s\n", SToken::m_TokenNames[ Token.m_TokenType ], Token.m_TokenString.GetData() );
				Token.m_TokenString.Clear();

				Token.m_TokenType = SToken::ET_Equals;
				DEBUGCATPRINTF( "Core", 2, "%s\n", SToken::m_TokenNames[ Token.m_TokenType ] );
				Tokens.PushBack( Token );

				Token.m_TokenType = SToken::ET_None;
				break;
			case SToken::ET_Equals:
				// Already expecting =, just push it
				Tokens.PushBack( Token );
				DEBUGCATPRINTF( "Core", 2, "%s\n", SToken::m_TokenNames[ Token.m_TokenType ] );

				Token.m_TokenType = SToken::ET_None;
				break;
			case SToken::ET_String:
				Token.m_TokenString.PushBack( c );
				break;
			default:
				WARNDESC( "Unexpected token" );
				break;
			}
		}
		else if( c == '#' )
		{
			// # starts a comment

			// Allow # inside a string
			if( Token.m_TokenType == SToken::ET_String )
			{
				Token.m_TokenString.PushBack( c );
			}
			else
			{
				c = Stream.ReadInt8();
				
				if( c == '!' )	// #! and !# indicate the start and end of block comments
				{
					while( !Stream.EOS() )
					{
						if( Stream.ReadInt8() == '!' && Stream.ReadInt8() == '#' )
						{
							break;
						}
					}
				}
				else
				{
					// Read to end of line
					while( c != '\n' && c!= '\v' && !Stream.EOS() )	// Vertical tab stupidity again
					{
						c = Stream.ReadInt8();
					}

					// Change the context because we're on a new line
					Token.m_TokenType = SToken::ET_Name;

					++LineCount;
				}
			}
		}
		else if( c == '\\' && Token.m_TokenType == SToken::ET_String )
		{
			// Escape sequence, intended to insert linebreaks (and maybe other things in the future)
			// Config string escape sequences are not the same as C++ escape sequences. They can be
			// \\, \n, \?, \", or \xx (where x are hex digits, to specify any character by hex).

			char next = Stream.ReadInt8();
			if( next == 'n' )
			{
				Token.m_TokenString.PushBack( '\n' );
			}
			else if( next == '\"' )
			{
				Token.m_TokenString.PushBack( '\"' );
			}
			else if( next == '\\' )
			{
				Token.m_TokenString.PushBack( '\\' );
			}
			else if( next == 'x' )
			{
				char Hex = 0;
				for( uint HexIndex = 0; HexIndex < 2; ++HexIndex )
				{
					next = Stream.ReadInt8();
					ASSERT( IsHex( next ) );
					Hex = ( Hex << 4 ) | GetHex( next );
				}
				Token.m_TokenString.PushBack( Hex );
			}
			else if( next == 'u' )
			{
				// First, extract a unicode code point (e.g. \u00d7 for U+00D7)
				// NOTE: This only support the first Unicode plane, and is strict about
				// using four characters, so \ud7 is not a valid substitute for \u00d7.
				unicode_t CodePoint = 0;
				for( uint UnicodeIndex = 0; UnicodeIndex < 4; ++UnicodeIndex )
				{
					next = Stream.ReadInt8();
					ASSERT( IsHex( next ) );
					CodePoint = ( CodePoint << 4 ) | GetHex( next );
				}

				// Then convert the two-byte code point to UTF-8.
				Array<unicode_t> CodePointArray;
				CodePointArray.PushBack( CodePoint );
				const SimpleString UTF8String = SimpleString::SetUTF8( CodePointArray );

				for( uint CharIndex = 0; CharIndex < UTF8String.Length(); ++CharIndex )
				{
					const char NextChar = UTF8String.GetChar( CharIndex );
					Token.m_TokenString.PushBack( NextChar );
				}
			}
			else
			{
				PRINTF( "Unrecognized escape sequence \\%c at line %d\n", next, LineCount );
				WARNDESC( "Unrecognized escape sequence" );
			}
		}
		else if( c == 0x0d )
		{
			// DOS linebreak is 0D 0A, so ignore and expect \n to follow
		}
		else if( c == '\0' )
		{
			// Don't know how these are getting in either, but ignore them
		}
		else if( c == '\n' || c == '\v' )
		{
			if( Token.m_TokenType == SToken::ET_Macro )
			{
				MacroToken = Token;
			}

			// Dunno how vertical tabs are getting in, but treat them as linebreaks
			if( Token.m_TokenString.Empty() )
			{
				if( Token.m_TokenType != SToken::ET_Counter )
				{
					Token.m_TokenType = SToken::ET_None;
				}
				Tokens.PushBack( Token );
				DEBUGCATPRINTF( "Core", 2, "%s\n", SToken::m_TokenNames[ Token.m_TokenType ] );

				Token.m_TokenType = SToken::ET_Name;
			}
			else
			{
				Token.m_TokenString.PushBack( '\0' );
				Tokens.PushBack( Token );
				DEBUGCATPRINTF( "Core", 2, "%s: %s\n", SToken::m_TokenNames[ Token.m_TokenType ], Token.m_TokenString.GetData() );
				Token.m_TokenString.Clear();

				Token.m_TokenType = SToken::ET_Name;
			}

			++LineCount;
		}
		else if( c == '[' )
		{
			if( Token.m_TokenType == SToken::ET_String )
			{
				Token.m_TokenString.PushBack( c );
			}
			else
			{
				// We should only ever open a context when we're expecting a name
				ASSERT( Token.m_TokenType == SToken::ET_Name );
				Token.m_TokenType = SToken::ET_Context;

				// Opening a new context, clear the macro token.
				MacroToken = SToken();
			}
		}
		else if( c == ']' )
		{
			// If we've already closed the context, ignore; else, push token
			if( Token.m_TokenType == SToken::ET_String )
			{
				Token.m_TokenString.PushBack( c );
			}
			else
			{
				ASSERT( Token.m_TokenType == SToken::ET_Context );
				Token.m_TokenString.PushBack( '\0' );
				Tokens.PushBack( Token );
				DEBUGCATPRINTF( "Core", 2, "%s: %s\n", SToken::m_TokenNames[ Token.m_TokenType ], Token.m_TokenString.GetData() );
				Token.m_TokenString.Clear();
			}
		}
		else if( c == '@' )
		{
			if( Token.m_TokenType == SToken::ET_String )
			{
				Token.m_TokenString.PushBack( c );
			}
			else
			{
				// We should only ever declare or insert a macro when we're expecting a name
				ASSERT( Token.m_TokenType == SToken::ET_Name );
				c = Stream.ReadInt8();
				if( c == '@' )
				{
					// @@... means we're inserting the current macro into a name

					// Make sure there is a current macro. If this fails, a macro probably
					// wasn't opened in the current context.
					ASSERT( MacroToken.m_TokenString.Size() > 0 );

					const uint MacroLength = MacroToken.m_TokenString.Size();
					for( uint MacroIndex = 0; MacroIndex < MacroLength; ++MacroIndex )
					{
						Token.m_TokenString.PushBack( MacroToken.m_TokenString[ MacroIndex ] );
					}
				}
				else
				{
					// @... means we're declaring a new macro
					Token.m_TokenType = SToken::ET_Macro;
					if( c == ' ' || c == '\t' )
					{
						// Ignore whitespace at the front of macro
					}
					else
					{
						Token.m_TokenString.PushBack( c );
					}
				}
			}
		}
		else
		{
			bool ClosedString = false;
			InnerParse( c, StrMark, Token.m_TokenString, LineCount, Token.m_TokenType, &ClosedString );
			if( ClosedString )
			{
				Tokens.PushBack( Token );
				DEBUGCATPRINTF( "Core", 2, "%s: %s\n", SToken::m_TokenNames[ Token.m_TokenType ], Token.m_TokenString.GetData() );
				Token.m_TokenString.Clear();
				Token.m_TokenType = SToken::ET_None;
			}
		}
	}

	SimpleString Context = "";

	// Tokens are made, now create config vars
	for( uint i = 0; i < Tokens.Size(); ++i )
	{
		SToken& NameToken = Tokens[i];
		SimpleString Name = "";
		const char* ValueString = NULL;
		if( NameToken.m_TokenType == SToken::ET_Name )
		{
			Name = NameToken.m_TokenString.GetData();
			ASSERT( Tokens[ i + 1 ].m_TokenType == SToken::ET_Equals );

			SToken& ValueToken = Tokens[ i + 2 ];
			ValueString = ValueToken.m_TokenString.GetData();

			if( Context != "" )
			{
				CATPRINTF( "Core", 2, "%s:", Context.CStr() );
			}
			CATPRINTF( "Core", 2, "%s: %s: %s\n", Name.CStr(), SToken::m_TokenNames[ ValueToken.m_TokenType ], ValueString );

			switch( ValueToken.m_TokenType )
			{
			case SToken::ET_Bool:
				{
					// Just use the first character to determine truth
					bool Value = false;
					char first = ValueString[0];
					if( first == 't' || first == 'T' )
					{
						Value = true;
					}
					ConfigManager::SetBool( Name, Value, Context );
				}
				break;
			case SToken::ET_Int:
				{
					int Value = atoi( ValueString );
					ConfigManager::SetInt( Name, Value, Context );
				}
				break;
			case SToken::ET_Counter:
				{
					List<int>::Iterator NextCounterIter = ArrayCounters.Front();
					( *NextCounterIter )++;	// Add one to the last value we incremented, and that's the total for this array
					ConfigManager::SetInt( Name, *NextCounterIter, Context );
					ArrayCounters.PopFront();
				}
				break;
			case SToken::ET_Float:
				{
					float Value = (float)atof( ValueString );
					ConfigManager::SetFloat( Name, Value, Context );
				}
				break;
			case SToken::ET_String:
				{
					// Make a permanent copy of the string
					uint Length = (uint)strlen( ValueString );
					char* pString = new char[ Length + 1];
					memcpy_s( pString, Length + 1, ValueString, Length );
					pString[ Length ] = '\0';
					StringManager::AddString( StringManager::ESL_Permanent, pString );

					ConfigManager::SetString( Name, pString, Context );
				}

				break;
			default:
				WARNDESC( "Unexpected token" );
				break;
			}

			i += 2;
		}
		else if( NameToken.m_TokenType == SToken::ET_Context )
		{
			Context = NameToken.m_TokenString.GetData();
			//CATPRINTF( "Core", 2, "Pushed context %s\n", Context.CStr() );
		}
		else
		{
			DEBUGCATPRINTF( "Core", 2, "Skipped unexpected token %s (expected ET_Name)\n", SToken::m_TokenNames[ NameToken.m_TokenType ] );
		}
	}

	// Clean up
	for( uint i = 0; i < Tokens.Size(); ++i )
	{
		Tokens[i].m_TokenString.Clear();
	}
	Tokens.Clear();
}
Example #23
0
	void MeshGroup::_genMesh(const Array<Mesh *> & arr, int first, int last, bool hasLightingColor)
	{
		MeshSourcePtr source = arr[0]->GetSource();
		Mesh * mesh = new Mesh;

		for (int i = 0; i < source->GetMeshBufferCount(); ++i)
		{
			SubMesh * submesh = mesh->NewSubMesh();
			VertexBufferPtr srcVB = source->GetMeshBuffer(i)->GetRenderOp()->vertexBuffers[0];
			IndexBufferPtr srcIB = source->GetMeshBuffer(i)->GetRenderOp()->indexBuffer;
			int p_offset = source->GetMeshBuffer(i)->GetRenderOp()->vertexDeclarations[0].GetElementOffset(eVertexSemantic::POSITION);
			int n_offset = source->GetMeshBuffer(i)->GetRenderOp()->vertexDeclarations[0].GetElementOffset(eVertexSemantic::NORMAL);
			int stride = srcVB->GetStride();

			VertexBufferPtr vb = HWBufferManager::Instance()->NewVertexBuffer(stride, srcVB->GetCount() * (last - first));
			
			const char * v_src = (const char *)srcVB->Lock(eLockFlag::READ);
			char * v_dest = (char *)vb->Lock(eLockFlag::WRITE);
			for (int j = first; j < last; ++j)
			{
				const Mat4 & worldTM = arr[j]->GetWorldTM();
				bool hasScale = arr[j]->GetWorldScale() != Float3(1, 1, 1);

				for (int k = 0; k < srcVB->GetCount(); ++k)
				{
					memcpy(v_dest, v_src, stride);

					Float3 * position = (Float3 *)(v_dest + p_offset);
					position->TransformA(worldTM);
					
					if (n_offset != -1)
					{
						Float3 * normal = (Float3 *)(v_dest + n_offset);
						normal->TransformN(worldTM);

						if (hasScale)
						{
							normal->Normalize();
						}
					}

					v_dest += stride;
					v_src += stride;
				}
			}
			vb->Unlock();
			srcVB->Unlock();

			IndexBufferPtr ib = HWBufferManager::Instance()->NewIndexBuffer(srcIB->GetCount() * (last - first));

			int startVertex = 0;
			const short * i_src = (const short *)srcIB->Lock(eLockFlag::READ);
			char * i_dest = (char *)ib->Lock(eLockFlag::WRITE);
			for (int j = first; j < last; ++j)
			{
				for (int k = 0; k < srcIB->GetCount(); ++k)
				{
					*i_dest++ = (*i_src++) + startVertex;
				}

				startVertex += srcVB->GetCount();
			}
			ib->Unlock();
			srcIB->Unlock();
			
			submesh->GetRenderOp()->vertexDeclarations[0] = source->GetMeshBuffer(i)->GetRenderOp()->vertexDeclarations[0];
			submesh->GetRenderOp()->vertexBuffers[0] = vb;
			submesh->GetRenderOp()->indexBuffer = ib;
			submesh->GetRenderOp()->primCount = ib->GetCount() / 3;
			submesh->GetRenderOp()->primType = ePrimType::TRIANGLE_LIST;

			if (hasLightingColor)
			{
				int count = submesh->GetRenderOp()->vertexBuffers[0]->GetCount();
				submesh->GetRenderOp()->vertexDeclarations[LIGHTING_COLOR_STREAM].AddElement(eVertexSemantic::LIGHTING_COLOR, eVertexType::UBYTE4);
				submesh->GetRenderOp()->vertexBuffers[LIGHTING_COLOR_STREAM] = HWBufferManager::Instance()->NewVertexBuffer(4, count);

				Array<Rgba32> lightColors;
				Rgba32 * data = (Rgba32 *)submesh->GetRenderOp()->vertexBuffers[LIGHTING_COLOR_STREAM]->Lock(eLockFlag::WRITE);
				for (int j = first; j < last; ++j)
				{
					arr[j]->GetLightingColor(lightColors);
					d_assert (lightColors.Size() > 0);

					memcpy(data, &lightColors[0], 4 * count);

					startVertex += count;
					lightColors.Clear();
				}
				submesh->GetRenderOp()->vertexBuffers[LIGHTING_COLOR_STREAM]->Unlock();
			}

			*submesh->GetMaterial() = *source->GetMeshBuffer(i)->GetMaterial();

			submesh->SetMeshShader(source->GetMeshBuffer(i)->GetShader());
		}

		mesh->SetSLMode(hasLightingColor ? eStaticLightingMode::LIGHTING_COLOR : eStaticLightingMode::NONE);

		mMeshes.PushBack(mesh);
	}
Example #24
0
// NOTE: This is a lot of duplicated code from the value parsing parts
// of Parse(). Could do to clean this up and use common functions.
void ConfigParser::ParseTiny( const IDataStream& Stream )
{
	Array< char >		FirstPart;	// Could be name or context
	Array< char >		SecondPart;	// Name if first part is context
	Array< char >		ValuePart;
	SToken::ETokenType	Type = SToken::ET_None;
	char				QuoteType = '\"';
	bool				StringClosed = false;

	enum EParseState
	{
		EPS_FirstPart,
		EPS_SecondPart,
		EPS_ValuePart,
	} ParseState = EPS_FirstPart;

	while( !Stream.EOS() )
	{
		char c = Stream.ReadInt8();

		if( ParseState == EPS_FirstPart )
		{
			if( c == ' ' || c == '\t' || c == '\n' || c == '\0' )
			{
				// Ignore whitespace
				continue;
			}
			else if( c == ':' )
			{
				FirstPart.PushBack( '\0' );
				ParseState = EPS_SecondPart;
				continue;
			}
			else if( c == '=' )
			{
				FirstPart.PushBack( '\0' );
				ParseState = EPS_ValuePart;
				continue;
			}
			else
			{
				FirstPart.PushBack( c );
			}
		}
		else if( ParseState == EPS_SecondPart )
		{
			if( c == ' ' || c == '\t' || c == '\n' || c == '\0' )
			{
				// Ignore whitespace
				continue;
			}
			else if( c == '=' )
			{
				SecondPart.PushBack( '\0' );
				ParseState = EPS_ValuePart;
				continue;
			}
			else
			{
				SecondPart.PushBack( c );
			}
		}
		else if( ParseState == EPS_ValuePart )
		{
			if( ( ( Type != SToken::ET_String || StringClosed ) && ( c == ' ' || c == '\t' ) ) || c == '\n' || c == '\0' )
			{
				// Parse the value and set the config var
				ValuePart.PushBack( '\0' );

				SimpleString Name = ( SecondPart.Size() > 1 ) ? SecondPart.GetData() : FirstPart.GetData();
				SimpleString Context = ( SecondPart.Size() > 1 ) ? FirstPart.GetData() : "";

				switch( Type )
				{
				case SToken::ET_Bool:
					{
						// Just use the first character to determine truth
						bool Value = false;
						char first = ValuePart[0];
						if( first == 't' || first == 'T' )
						{
							Value = true;
						}
						ConfigManager::SetBool( Name, Value, Context );
					}
					break;
				case SToken::ET_Int:
					{
						int Value = atoi( ValuePart.GetData() );
						ConfigManager::SetInt( Name, Value, Context );
					}
					break;
				case SToken::ET_Float:
					{
						float Value = (float)atof( ValuePart.GetData() );
						ConfigManager::SetFloat( Name, Value, Context );
					}
					break;
				case SToken::ET_String:
					{
						// Make a permanent copy of the string
						uint Length = (uint)strlen( ValuePart.GetData() );
						char* pString = new char[ Length + 1];
						memcpy_s( pString, Length + 1, ValuePart.GetData(), Length );
						pString[ Length ] = '\0';
						StringManager::AddString( StringManager::ESL_Permanent, pString );

						ConfigManager::SetString( Name, pString, Context );
					}

					break;
				default:
					WARNDESC( "Unexpected token" );
					break;
				}

				// Prepare for next variable
				FirstPart.Clear();
				SecondPart.Clear();
				ValuePart.Clear();
				Type = SToken::ET_None;
				ParseState = EPS_FirstPart;
				StringClosed = false;
				continue;
			}
			else
			{
				InnerParse( c, QuoteType, ValuePart, 0, Type, &StringClosed );
			}
		}
	}
}
Example #25
0
String RichPara::Pack(const RichPara::Format& style, Array<RichObject>& obj) const
{
	StringStream out;
	dword pattr = 0;
	if(format.align != style.align)             pattr |= 1;
	if(format.before != style.before)           pattr |= 2;
	if(format.lm != style.lm)                   pattr |= 4;
	if(format.indent != style.indent)           pattr |= 8;
	if(format.rm != style.rm)                   pattr |= 0x10;
	if(format.after != style.after)             pattr |= 0x20;
	if(format.bullet != style.bullet)           pattr |= 0x40;
	if(format.keep != style.keep)               pattr |= 0x80;
	if(format.newpage != style.newpage)         pattr |= 0x100;
	if(format.tabsize != style.tabsize)         pattr |= 0x200;
	if(!IsNull(format.label))                   pattr |= 0x400;
	if(format.keepnext != style.keepnext)       pattr |= 0x800;
	if(format.orphan != style.orphan)           pattr |= 0x1000;
	if(NumberingDiffers(format, style))         pattr |= 0x2000;
	if(format.linespacing != style.linespacing) pattr |= 0x4000;
	if(format.tab != style.tab)                 pattr |= 0x8000;
	if(format.ruler != style.ruler)             pattr |= 0x10000;
	if(format.rulerink != style.rulerink)       pattr |= 0x20000;
	out.Put32(pattr);
	if(pattr & 1)      out.Put16(format.align);
	if(pattr & 2)      out.Put16(format.before);
	if(pattr & 4)      out.Put16(format.lm);
	if(pattr & 8)      out.Put16(format.indent);
	if(pattr & 0x10)   out.Put16(format.rm);
	if(pattr & 0x20)   out.Put16(format.after);
	if(pattr & 0x40)   out.Put16(format.bullet);
	if(pattr & 0x80)   out.Put(format.keep);
	if(pattr & 0x100)  out.Put(format.newpage);
	if(pattr & 0x200)  out.Put16(format.tabsize);
	if(pattr & 0x400)  { String t = format.label; out % t; }
	if(pattr & 0x800)  out.Put(format.keepnext);
	if(pattr & 0x1000) out.Put(format.orphan);
	if(pattr & 0x2000) {
		String b = format.before_number, a = format.after_number;
		out % b % a;
		out.Put(format.reset_number);
		out.Put(format.number, 8);
	}
	if(pattr & 0x4000)
		out.Put(format.linespacing);
	if(pattr & 0x8000) {
		int c = 0;
		int i;
		for(i = 0; i < format.tab.GetCount(); i++) {
			if(!IsNull(format.tab[i].pos))
				c++;
		}
		out.Put16(c);
		for(i = 0; i < format.tab.GetCount(); i++) {
			const RichPara::Tab& w = format.tab[i];
			if(!IsNull(w.pos)) {
				out.Put32(w.pos);
				out.Put(w.align);
				out.Put(w.fillchar);
			}
		}
	}
	if(pattr & 0x10000)
		out.Put16(format.ruler);
	if(pattr & 0x20000) {
		Color c = format.rulerink;
		c.Serialize(out);
	}
	obj.Clear();
	CharFormat cf = style;
	if(part.GetCount())
		PackParts(out, style, part, cf, obj);
	else
		Charformat(out, style, format, cf);
	String r = out;
	r.Shrink();
	return r;
}
Example #26
0
		void Clear()
		{
			m_name.Clear();
			m_imports.Clear();
		}
OvrVideoMenu::OvrVideoMenu( OvrGuiSys & guiSys, OvrMetaData & metaData, float radius )
	: VRMenu( MENU_NAME )
	, MetaData( metaData )
	, LoadingIconHandle( 0 )
	, AttributionHandle( 0 )
	, BrowserButtonHandle( 0 )
	, VideoControlButtonHandle( 0 )
	, Radius( radius )
	, ButtonCoolDown( 0.0f )
	, OpenTime( 0.0 )
{
	// Init with empty root
	Init( guiSys, 0.0f, VRMenuFlags_t() );

	// Create Attribution info view
	Array< VRMenuObjectParms const * > parms;
	Array< VRMenuComponent* > comps;
	VRMenuId_t attributionPanelId( ID_CENTER_ROOT.Get() + 10 );

	comps.PushBack( new OvrVideoMenuRootComponent( *this ) );

	Quatf rot( DOWN, 0.0f );
	Vector3f dir( -FWD );
	Posef panelPose( rot, dir * Radius );
	Vector3f panelScale( 1.0f );

	const VRMenuFontParms fontParms( true, true, false, false, true, 0.525f, 0.45f, 1.0f );

	VRMenuObjectParms attrParms( VRMENU_STATIC, comps,
		VRMenuSurfaceParms(), "Attribution Panel", panelPose, panelScale, Posef(), Vector3f( 1.0f ), fontParms, attributionPanelId,
		VRMenuObjectFlags_t(), VRMenuObjectInitFlags_t( VRMENUOBJECT_INIT_FORCE_POSITION ) );

	parms.PushBack( &attrParms );

	AddItems( guiSys, parms, GetRootHandle(), false );
	parms.Clear();
	comps.Clear();

	AttributionHandle = HandleForId( guiSys.GetVRMenuMgr(), attributionPanelId );
	VRMenuObject * attributionObject = guiSys.GetVRMenuMgr().ToObject( AttributionHandle );
	OVR_ASSERT( attributionObject != NULL );

	//Browser button
	float const ICON_HEIGHT = 80.0f * VRMenuObject::DEFAULT_TEXEL_SCALE;
	Array< VRMenuSurfaceParms > surfParms;

	Posef browserButtonPose( Quatf(), UP * ICON_HEIGHT * 2.0f );

	comps.PushBack( new OvrDefaultComponent( Vector3f( 0.0f, 0.0f, 0.05f ), 1.05f, 0.25f, 0.0f, Vector4f( 1.0f ), Vector4f( 1.0f ) ) );
	comps.PushBack( new OvrButton_OnUp( this, ID_BROWSER_BUTTON ) );
	comps.PushBack( new OvrSurfaceToggleComponent( ) );
	surfParms.PushBack( VRMenuSurfaceParms( "browser",
		"apk:///assets/nav_home_off.png", SURFACE_TEXTURE_DIFFUSE,
		NULL, SURFACE_TEXTURE_MAX, NULL, SURFACE_TEXTURE_MAX ) );
	surfParms.PushBack( VRMenuSurfaceParms( "browser",
		"apk:///assets/nav_home_on.png", SURFACE_TEXTURE_DIFFUSE,
		NULL, SURFACE_TEXTURE_MAX, NULL, SURFACE_TEXTURE_MAX ) );
	VRMenuObjectParms browserButtonParms( VRMENU_BUTTON, comps, surfParms, "",
		browserButtonPose, Vector3f( 1.0f ), Posef(), Vector3f( 1.0f ), fontParms,
		ID_BROWSER_BUTTON, VRMenuObjectFlags_t( VRMENUOBJECT_DONT_HIT_TEXT ),
		VRMenuObjectInitFlags_t( VRMENUOBJECT_INIT_FORCE_POSITION ) );
	parms.PushBack( &browserButtonParms );

	AddItems( guiSys, parms, AttributionHandle, false );
	parms.Clear();
	comps.Clear();
	surfParms.Clear();

	BrowserButtonHandle = attributionObject->ChildHandleForId( guiSys.GetVRMenuMgr(), ID_BROWSER_BUTTON );
	VRMenuObject * browserButtonObject = guiSys.GetVRMenuMgr().ToObject( BrowserButtonHandle );
	OVR_ASSERT( browserButtonObject != NULL );
	OVR_UNUSED( browserButtonObject );

	//Video control button 
	Posef videoButtonPose( Quatf(), DOWN * ICON_HEIGHT * 2.0f );

	comps.PushBack( new OvrDefaultComponent( Vector3f( 0.0f, 0.0f, 0.05f ), 1.05f, 0.25f, 0.0f, Vector4f( 1.0f ), Vector4f( 1.0f ) ) );
	comps.PushBack( new OvrButton_OnUp( this, ID_VIDEO_BUTTON ) );
	comps.PushBack( new OvrSurfaceToggleComponent( ) );
	surfParms.PushBack( VRMenuSurfaceParms( "browser",
		"apk:///assets/nav_restart_off.png", SURFACE_TEXTURE_DIFFUSE,
		NULL, SURFACE_TEXTURE_MAX, NULL, SURFACE_TEXTURE_MAX ) );
	surfParms.PushBack( VRMenuSurfaceParms( "browser",
		"apk:///assets/nav_restart_on.png", SURFACE_TEXTURE_DIFFUSE,
		NULL, SURFACE_TEXTURE_MAX, NULL, SURFACE_TEXTURE_MAX ) );
	VRMenuObjectParms controlButtonParms( VRMENU_BUTTON, comps, surfParms, "",
		videoButtonPose, Vector3f( 1.0f ), Posef(), Vector3f( 1.0f ), fontParms,
		ID_VIDEO_BUTTON, VRMenuObjectFlags_t( VRMENUOBJECT_DONT_HIT_TEXT ),
		VRMenuObjectInitFlags_t( VRMENUOBJECT_INIT_FORCE_POSITION ) );
	parms.PushBack( &controlButtonParms );

	AddItems( guiSys, parms, AttributionHandle, false );
	parms.Clear();
	comps.Clear();

	VideoControlButtonHandle = attributionObject->ChildHandleForId( guiSys.GetVRMenuMgr(), ID_VIDEO_BUTTON );
	VRMenuObject * controlButtonObject = guiSys.GetVRMenuMgr().ToObject( VideoControlButtonHandle );
	OVR_ASSERT( controlButtonObject != NULL );
	OVR_UNUSED( controlButtonObject );

}
Example #28
0
// Tokenize
//------------------------------------------------------------------------------
void AString::Tokenize( Array< AString > & tokens, char splitChar ) const
{
	Array< const char * > tokenStarts;
	Array< const char * > tokenEnds;

	const char * pos = Get();
	const char * end = GetEnd();
	bool lookingForStart = true;
	char quoteChar = 0;
	while ( pos < end )
	{
		if ( lookingForStart )
		{
			if ( *pos == splitChar )
			{
				++pos;
				continue;
			}

			// found the start of a new token
			tokenStarts.Append( pos );
			lookingForStart = false;
		}

		// hit a quote?
		char c = *pos;
		if ( ( c == '"' ) || ( c == '\'' ) )
		{
			if ( quoteChar == 0 )
			{
				// opening quote
				quoteChar = c;
			}
			else if ( quoteChar == c )
			{
				// closing quote
				quoteChar = 0;
			}
			else
			{
				// quote of the 'other' type - consider as part of token
			}
		} 
		else if ( c == splitChar )
		{
			if ( quoteChar == 0 )
			{
				tokenEnds.Append( pos );
				lookingForStart = true;
			}
			else
			{
				// space inside quoted token - consider as part of token
			}
		}
		else
		{
			// normal character part of token
		}
		++pos;
	}
	ASSERT( ( tokenStarts.GetSize() == tokenEnds.GetSize() ) ||
			( tokenStarts.GetSize() == ( tokenEnds.GetSize() + 1 ) ) );
	if ( tokenStarts.GetSize() > tokenEnds.GetSize() )
	{
		tokenEnds.Append( pos );
	}
	ASSERT( tokenStarts.GetSize() == tokenEnds.GetSize() );

	// pre-size output to avoid reallocations
	tokens.Clear();
	const size_t numTokens( tokenStarts.GetSize() );
	if ( tokens.GetCapacity() < numTokens )
	{
		tokens.SetCapacity( numTokens );
	}
	tokens.SetSize( numTokens );

	// copy tokens
	for ( size_t i=0; i<numTokens; ++i )
	{
		tokens[ i ].Assign( tokenStarts[ i ], tokenEnds[ i ] );
	}
}
Example #29
0
OvrPanoMenu::OvrPanoMenu( App * app, Oculus360Photos * photos, OvrVRMenuMgr & menuMgr, BitmapFont const & font,
		OvrMetaData & metaData, float fadeOutTime, float radius )
	: VRMenu( MENU_NAME )
	, AppPtr( app )
	, MenuMgr( menuMgr )
	, Font( font )
	, Photos( photos )
	, MetaData( metaData )
	, LoadingIconHandle( 0 )
	, AttributionHandle( 0 )
	, BrowserButtonHandle( 0 )
	, SwipeLeftIndicatorHandle( 0 )
	, SwipeRightIndicatorHandle( 0 )
	, Fader( 1.0f )
	, FadeOutTime( fadeOutTime )
	, currentFadeRate( 0.0f )
	, Radius( radius )
	, ButtonCoolDown( 0.0f )
{	
	currentFadeRate = 1.0f / FadeOutTime;

	// Init with empty root
	Init( menuMgr, font, 0.0f, VRMenuFlags_t() );
	
	// Create Attribution info view
	Array< VRMenuObjectParms const * > parms;
	Array< VRMenuComponent* > comps;
	VRMenuId_t attributionPanelId( ID_CENTER_ROOT.Get() + 10 );

	comps.PushBack( new OvrPanoMenuRootComponent( *this ) );

	Quatf rot( DOWN, 0.0f );
	Vector3f dir( -FWD );
	Posef panelPose( rot, dir * Radius );
	Vector3f panelScale( 1.0f );

	//const Posef textPose( Quatf(), Vector3f( 0.0f, 0.0f, 0.0f ) );

	const VRMenuFontParms fontParms( true, true, false, false, true, 0.525f, 0.45f, 1.0f );
	
	VRMenuObjectParms attrParms( VRMENU_STATIC, comps,
		VRMenuSurfaceParms(), "Attribution Panel", panelPose, panelScale, Posef(), Vector3f( 1.0f ), fontParms, attributionPanelId,
		VRMenuObjectFlags_t( VRMENUOBJECT_DONT_HIT_TEXT ), VRMenuObjectInitFlags_t( VRMENUOBJECT_INIT_FORCE_POSITION ) );

	parms.PushBack( &attrParms );

	AddItems( MenuMgr, Font, parms, GetRootHandle(), false );
	parms.Clear();
	comps.Clear();

	AttributionHandle = HandleForId( MenuMgr, attributionPanelId );
	VRMenuObject * attributionObject = MenuMgr.ToObject( AttributionHandle );
	OVR_ASSERT( attributionObject != NULL );

	//Browser button
	float const ICON_HEIGHT = 80.0f * VRMenuObject::DEFAULT_TEXEL_SCALE;
	Array< VRMenuSurfaceParms > surfParms;

	Posef browserButtonPose( Quatf( ), UP * ICON_HEIGHT * 2.0f );

	comps.PushBack( new OvrDefaultComponent( Vector3f( 0.0f, 0.0f, 0.05f ), 1.05f, 0.25f, 0.0f, Vector4f( 1.0f ), Vector4f( 1.0f ) ) );
	comps.PushBack( new OvrButton_OnUp( this, ID_BROWSER_BUTTON ) );
	comps.PushBack( new OvrSurfaceToggleComponent( ) );
	surfParms.PushBack( VRMenuSurfaceParms ( "browser",
		"assets/nav_home_off.png", SURFACE_TEXTURE_DIFFUSE,
		NULL, SURFACE_TEXTURE_MAX, NULL, SURFACE_TEXTURE_MAX ) );
	surfParms.PushBack( VRMenuSurfaceParms( "browser",
		"assets/nav_home_on.png", SURFACE_TEXTURE_DIFFUSE,
		NULL, SURFACE_TEXTURE_MAX, NULL, SURFACE_TEXTURE_MAX ) );
	VRMenuObjectParms browserButtonParms( VRMENU_BUTTON, comps, surfParms, "",
		browserButtonPose, Vector3f( 1.0f ), Posef( ), Vector3f( 1.0f ), fontParms,
		ID_BROWSER_BUTTON, VRMenuObjectFlags_t( VRMENUOBJECT_DONT_HIT_TEXT ),
		VRMenuObjectInitFlags_t( VRMENUOBJECT_INIT_FORCE_POSITION ) );
	parms.PushBack( &browserButtonParms );

	AddItems( MenuMgr, Font, parms, AttributionHandle, false );
	parms.Clear();
	comps.Clear();
	surfParms.Clear();

	BrowserButtonHandle = attributionObject->ChildHandleForId( MenuMgr, ID_BROWSER_BUTTON );
	VRMenuObject * browserButtonObject = MenuMgr.ToObject( BrowserButtonHandle );
	OVR_ASSERT( browserButtonObject != NULL );
	OVR_UNUSED( browserButtonObject );

	//Favorites button
	Posef favoritesButtonPose( Quatf( ), DOWN * ICON_HEIGHT * 2.0f );

	comps.PushBack( new OvrDefaultComponent( Vector3f( 0.0f, 0.0f, 0.05f ), 1.05f, 0.25f, 0.0f, Vector4f( 1.0f ), Vector4f( 1.0f ) ) );
	comps.PushBack( new OvrButton_OnUp( this, ID_FAVORITES_BUTTON ) );
	comps.PushBack( new OvrSurfaceToggleComponent() );
	
	surfParms.PushBack( VRMenuSurfaceParms( "favorites_off",
		"assets/nav_star_off.png", SURFACE_TEXTURE_DIFFUSE,
		NULL, SURFACE_TEXTURE_MAX, NULL, SURFACE_TEXTURE_MAX ) );

	surfParms.PushBack( VRMenuSurfaceParms( "favorites_on",
		"assets/nav_star_on.png", SURFACE_TEXTURE_DIFFUSE,
		NULL, SURFACE_TEXTURE_MAX, NULL, SURFACE_TEXTURE_MAX ) );

	surfParms.PushBack( VRMenuSurfaceParms( "favorites_active_off",
		"assets/nav_star_active_off.png", SURFACE_TEXTURE_DIFFUSE,
		NULL, SURFACE_TEXTURE_MAX, NULL, SURFACE_TEXTURE_MAX ) );

	surfParms.PushBack( VRMenuSurfaceParms( "favorites_active_on",
		"assets/nav_star_active_on.png", SURFACE_TEXTURE_DIFFUSE,
		NULL, SURFACE_TEXTURE_MAX, NULL, SURFACE_TEXTURE_MAX ) );

	VRMenuObjectParms favoritesButtonParms( VRMENU_BUTTON, comps, surfParms, "",
		favoritesButtonPose, Vector3f( 1.0f ), Posef( ), Vector3f( 1.0f ), fontParms,
		ID_FAVORITES_BUTTON, VRMenuObjectFlags_t( VRMENUOBJECT_DONT_HIT_TEXT ),
		VRMenuObjectInitFlags_t( VRMENUOBJECT_INIT_FORCE_POSITION ) );
	parms.PushBack( &favoritesButtonParms );

	AddItems( MenuMgr, Font, parms, AttributionHandle, false );
	parms.Clear();
	comps.Clear();

	FavoritesButtonHandle = attributionObject->ChildHandleForId( MenuMgr, ID_FAVORITES_BUTTON );
	VRMenuObject * favoritesButtonObject = MenuMgr.ToObject( FavoritesButtonHandle );
	OVR_ASSERT( favoritesButtonObject != NULL );
	OVR_UNUSED( favoritesButtonObject );

	// Swipe icons
	const int numFrames = 10;
	const int numTrails = 3;
	const int numChildren = 5;
	const float swipeFPS = 3.0f;
	const float factor = 1.0f / 8.0f;

	// Right container
	VRMenuId_t swipeRightId( ID_CENTER_ROOT.Get() + 401 );
	Quatf rotRight( DOWN, ( Mathf::TwoPi * factor ) );
	Vector3f rightDir( -FWD * rotRight );	
	comps.PushBack( new OvrTrailsAnimComponent( swipeFPS, true, numFrames, numTrails, numTrails ) );
	VRMenuObjectParms swipeRightRoot( VRMENU_CONTAINER, comps, VRMenuSurfaceParms( ), "",
		Posef( rotRight, rightDir * Radius ), Vector3f( 1.0f ), Posef( ), Vector3f( 1.0f ), fontParms, swipeRightId,
		VRMenuObjectFlags_t( VRMENUOBJECT_DONT_HIT_ALL ), VRMenuObjectInitFlags_t( VRMENUOBJECT_INIT_FORCE_POSITION ) );
	parms.PushBack( &swipeRightRoot );
	AddItems( MenuMgr, Font, parms, AttributionHandle, false );
	parms.Clear();
	comps.Clear();

	SwipeRightIndicatorHandle = attributionObject->ChildHandleForId( MenuMgr, swipeRightId );
	VRMenuObject * swipeRightRootObject = MenuMgr.ToObject( SwipeRightIndicatorHandle );
	OVR_ASSERT( swipeRightRootObject != NULL );

	// Left container
	VRMenuId_t swipeLeftId( ID_CENTER_ROOT.Get( ) + 402 );
	Quatf rotLeft( DOWN, ( Mathf::TwoPi * -factor ) );
	Vector3f leftDir( -FWD * rotLeft );
	comps.PushBack( new OvrTrailsAnimComponent( swipeFPS, true, numFrames, numTrails, numTrails ) );
	VRMenuObjectParms swipeLeftRoot( VRMENU_CONTAINER, comps, VRMenuSurfaceParms( ), "",
		Posef( rotLeft, leftDir * Radius ), Vector3f( 1.0f ), Posef( ), Vector3f( 1.0f ), fontParms, swipeLeftId,
		VRMenuObjectFlags_t( VRMENUOBJECT_DONT_HIT_ALL ), VRMenuObjectInitFlags_t( VRMENUOBJECT_INIT_FORCE_POSITION ) );
	parms.PushBack( &swipeLeftRoot );
	AddItems( MenuMgr, Font, parms, AttributionHandle, false );
	parms.Clear();
	comps.Clear();

	SwipeLeftIndicatorHandle = attributionObject->ChildHandleForId( MenuMgr, swipeLeftId );
	VRMenuObject * swipeLeftRootObject = MenuMgr.ToObject( SwipeLeftIndicatorHandle );
	OVR_ASSERT( swipeLeftRootObject != NULL );
	
	// Arrow frame children
	const char * swipeRightIcon = "assets/nav_arrow_right.png";
	const char * swipeLeftIcon = "assets/nav_arrow_left.png";

	VRMenuSurfaceParms rightIndicatorSurfaceParms( "swipeRightSurface",
		swipeRightIcon, SURFACE_TEXTURE_DIFFUSE,
		NULL, SURFACE_TEXTURE_MAX, NULL, SURFACE_TEXTURE_MAX );

	VRMenuSurfaceParms leftIndicatorSurfaceParms( "swipeLeftSurface",
		swipeLeftIcon, SURFACE_TEXTURE_DIFFUSE,
		NULL, SURFACE_TEXTURE_MAX, NULL, SURFACE_TEXTURE_MAX );
	
	const float surfaceWidth = 25 * VRMenuObject::DEFAULT_TEXEL_SCALE;

	for ( int i = 0; i < numChildren; ++i )
	{
 		//right frame
		const Vector3f rightPos = ( RIGHT * surfaceWidth * i ) - ( FWD * i * 0.1f );
		VRMenuObjectParms swipeRightFrame( VRMENU_STATIC, Array< VRMenuComponent* >(), rightIndicatorSurfaceParms, "",
			Posef( Quatf( ), rightPos ), Vector3f( 1.0f ), Posef( ), Vector3f( 1.0f ), fontParms, VRMenuId_t( ),
			VRMenuObjectFlags_t(), VRMenuObjectInitFlags_t( VRMENUOBJECT_INIT_FORCE_POSITION ) );
		parms.PushBack( &swipeRightFrame );
		AddItems( MenuMgr, Font, parms, SwipeRightIndicatorHandle, false );
		parms.Clear();

		// left frame
		const Vector3f leftPos = ( (-RIGHT) * surfaceWidth * i ) - ( FWD * i * 0.1f );
		VRMenuObjectParms swipeLeftFrame( VRMENU_STATIC, Array< VRMenuComponent* >(), leftIndicatorSurfaceParms, "",
			Posef( Quatf( ), leftPos ), Vector3f( 1.0f ), Posef( ), Vector3f( 1.0f ), fontParms, VRMenuId_t( ),
			VRMenuObjectFlags_t(), VRMenuObjectInitFlags_t( VRMENUOBJECT_INIT_FORCE_POSITION ) );
		parms.PushBack( &swipeLeftFrame );
		AddItems( MenuMgr, Font, parms, SwipeLeftIndicatorHandle, false );
		parms.Clear();
	}

	if ( OvrTrailsAnimComponent* animRightComp = swipeRightRootObject->GetComponentByName< OvrTrailsAnimComponent >( ) )
	{
		animRightComp->Play( );
	}
	
	if ( OvrTrailsAnimComponent* animLeftComp = swipeLeftRootObject->GetComponentByName< OvrTrailsAnimComponent >( ) )
	{
		animLeftComp->Play( );
	}
}
Example #30
0
void CompilePPUProgram::Compile()
{
	if(m_err_list)
	{
		m_err_list->Freeze();
		m_err_list->Clear();
	}
		
	if(m_analyze && m_hex_list)
	{
		m_hex_list->Freeze();
		m_hex_list->Clear();
	}

	m_code.Clear();

	for(u32 i=0; i<m_branches.GetCount(); ++i)
	{
		m_branches[i].m_name.clear();
	}

	m_branches.Clear();

	u32 text_size = 0;
	while(!IsEnd())
	{
		wxString op;
		if(GetOp(op) && !IsFuncOp(op) && !IsBranchOp(op) && !IsSpOp(op))
		{
			text_size += 4;
		}

		NextLn();
	}

	Elf64_Ehdr elf_info;
	memset(&elf_info, 0, sizeof(Elf64_Ehdr));
	elf_info.e_phentsize = sizeof(Elf64_Phdr);
	elf_info.e_shentsize = sizeof(Elf64_Shdr);
	elf_info.e_ehsize = sizeof(Elf64_Ehdr);
	elf_info.e_phnum = 5;
	elf_info.e_shnum = 15;
	elf_info.e_shstrndx = elf_info.e_shnum - 1;
	elf_info.e_phoff = elf_info.e_ehsize;
	u32 section_offset = Memory.AlignAddr(elf_info.e_phoff + elf_info.e_phnum * elf_info.e_phentsize, 0x100);

	static const u32 sceStub_text_block = 8 * 4;

	Elf64_Shdr s_null;
	memset(&s_null, 0, sizeof(Elf64_Shdr));

	wxArrayString sections_names;
	u32 section_name_offset = 1;

	Elf64_Shdr s_text;
	memset(&s_text, 0, sizeof(Elf64_Shdr));
	s_text.sh_type = 1;
	s_text.sh_offset = section_offset;
	s_text.sh_addr = section_offset + 0x10000;
	s_text.sh_size = text_size;
	s_text.sh_addralign = 4;
	s_text.sh_flags = 6;
	s_text.sh_name = section_name_offset;
	sections_names.Add(".text");
	section_name_offset += wxString(".text").Len() + 1;
	section_offset += s_text.sh_size;

	m_text_addr = s_text.sh_addr;

	struct Module
	{
		wxString m_name;
		Array<u32> m_imports;

		Module(const wxString& name, u32 import) : m_name(name)
		{
			Add(import);
		}

		void Add(u32 import)
		{
			m_imports.AddCpy(import);
		}

		void Clear()
		{
			m_name.Clear();
			m_imports.Clear();
		}
	};

	Array<Module> modules;

	FirstChar();
	while(!IsEnd())
	{
		wxString op;
		if(!GetOp(op) || !IsFuncOp(op))
		{
			NextLn();
			continue;
		}

		while(p > 0 && m_asm[(size_t)p] != '[') p--;
		p++;

		wxString module, name, id;

		if(!GetArg(module))
		{
			WriteError("module not found. style: [module, name, id]");
			m_error = true;
			NextLn();
			continue;
		}

		Arg a_module(module);
		DetectArgInfo(a_module);

		if(~ARG_ERR & a_module.type)
		{
			WriteError("bad module type. style: [module, name, id]");
			m_error = true;
			NextLn();
			continue;
		}

		if(!GetArg(name))
		{
			WriteError("name not found. style: [module, name, id]");
			m_error = true;
			NextLn();
			continue;
		}

		Arg a_name(name);
		DetectArgInfo(a_name);

		if(~ARG_ERR & a_name.type)
		{
			WriteError("bad name type. style: [module, name, id]");
			m_error = true;
			NextLn();
			continue;
		}

		if(!GetArg(id, true))
		{
			WriteError("id not found. style: [module, name, id]");
			m_error = true;
			NextLn();
			continue;
		}

		Arg a_id(id);
		DetectArgInfo(a_id);

		if(~ARG_IMM & a_id.type)
		{
			WriteError("bad id type. style: [module, name, id]");
			m_error = true;
			NextLn();
			continue;
		}

		if(m_asm[(size_t)p - 1] != ']')
		{
			WriteError("']' not found. style: [module, name, id]");
			m_error = true;
			NextLn();
			continue;
		}

		if(!CheckEnd()) continue;

		m_branches.Move(new Branch(name, a_id.value, 0));
		const u32 import = m_branches.GetCount() - 1;

		bool founded = false;
		for(u32 i=0; i<modules.GetCount(); ++i)
		{
			if(modules[i].m_name.Cmp(module) != 0) continue;
			founded = true;
			modules[i].Add(import);
			break;
		}

		if(!founded) modules.Move(new Module(module, import));
	}

	u32 imports_count = 0;

	for(u32 m=0; m < modules.GetCount(); ++m)
	{
		imports_count += modules[m].m_imports.GetCount();
	}

	Elf64_Shdr s_sceStub_text;
	memset(&s_sceStub_text, 0, sizeof(Elf64_Shdr));
	s_sceStub_text.sh_addralign = 4;
	section_offset = Memory.AlignAddr(section_offset, s_sceStub_text.sh_addralign);
	s_sceStub_text.sh_type = 1;
	s_sceStub_text.sh_offset = section_offset;
	s_sceStub_text.sh_addr = section_offset + 0x10000;
	s_sceStub_text.sh_name = section_name_offset;
	s_sceStub_text.sh_flags = 6;
	s_sceStub_text.sh_size = imports_count * sceStub_text_block;
	sections_names.Add(".sceStub.text");
	section_name_offset += wxString(".sceStub.text").Len() + 1;
	section_offset += s_sceStub_text.sh_size;

	for(u32 m=0, pos=0; m<modules.GetCount(); ++m)
	{
		for(u32 i=0; i<modules[m].m_imports.GetCount(); ++i, ++pos)
		{
			m_branches[modules[m].m_imports[i]].m_addr = s_sceStub_text.sh_addr + sceStub_text_block * pos;
		}
	}

	Elf64_Shdr s_lib_stub_top;
	memset(&s_lib_stub_top, 0, sizeof(Elf64_Shdr));
	s_lib_stub_top.sh_addralign = 4;
	section_offset = Memory.AlignAddr(section_offset, s_lib_stub_top.sh_addralign);
	s_lib_stub_top.sh_type = 1;
	s_lib_stub_top.sh_name = section_name_offset;
	s_lib_stub_top.sh_offset = section_offset;
	s_lib_stub_top.sh_addr = section_offset + 0x10000;
	s_lib_stub_top.sh_flags = 2;
	s_lib_stub_top.sh_size = 4;
	sections_names.Add(".lib.stub.top");
	section_name_offset += wxString(".lib.stub.top").Len() + 1;
	section_offset += s_lib_stub_top.sh_size;

	Elf64_Shdr s_lib_stub;
	memset(&s_lib_stub, 0, sizeof(Elf64_Shdr));
	s_lib_stub.sh_addralign = 4;
	s_lib_stub.sh_type = 1;
	s_lib_stub.sh_name = section_name_offset;
	s_lib_stub.sh_offset = section_offset;
	s_lib_stub.sh_addr = section_offset + 0x10000;
	s_lib_stub.sh_flags = 2;
	s_lib_stub.sh_size = sizeof(Elf64_StubHeader) * modules.GetCount();
	sections_names.Add(".lib.stub");
	section_name_offset += wxString(".lib.stub").Len() + 1;
	section_offset += s_lib_stub.sh_size;

	Elf64_Shdr s_lib_stub_btm;
	memset(&s_lib_stub_btm, 0, sizeof(Elf64_Shdr));
	s_lib_stub_btm.sh_addralign = 4;
	s_lib_stub_btm.sh_type = 1;
	s_lib_stub_btm.sh_name = section_name_offset;
	s_lib_stub_btm.sh_offset = section_offset;
	s_lib_stub_btm.sh_addr = section_offset + 0x10000;
	s_lib_stub_btm.sh_flags = 2;
	s_lib_stub_btm.sh_size = 4;
	sections_names.Add(".lib.stub.btm");
	section_name_offset += wxString(".lib.stub.btm").Len() + 1;
	section_offset += s_lib_stub_btm.sh_size;

	Elf64_Shdr s_rodata_sceFNID;
	memset(&s_rodata_sceFNID, 0, sizeof(Elf64_Shdr));
	s_rodata_sceFNID.sh_addralign = 4;
	section_offset = Memory.AlignAddr(section_offset, s_rodata_sceFNID.sh_addralign);
	s_rodata_sceFNID.sh_type = 1;
	s_rodata_sceFNID.sh_name = section_name_offset;
	s_rodata_sceFNID.sh_offset = section_offset;
	s_rodata_sceFNID.sh_addr = section_offset + 0x10000;
	s_rodata_sceFNID.sh_flags = 2;
	s_rodata_sceFNID.sh_size = imports_count * 4;
	sections_names.Add(".rodata.sceFNID");
	section_name_offset += wxString(".rodata.sceFNID").Len() + 1;
	section_offset += s_rodata_sceFNID.sh_size;

	Elf64_Shdr s_rodata_sceResident;
	memset(&s_rodata_sceResident, 0, sizeof(Elf64_Shdr));
	s_rodata_sceResident.sh_addralign = 4;
	section_offset = Memory.AlignAddr(section_offset, s_rodata_sceResident.sh_addralign);
	s_rodata_sceResident.sh_type = 1;
	s_rodata_sceResident.sh_name = section_name_offset;
	s_rodata_sceResident.sh_offset = section_offset;
	s_rodata_sceResident.sh_addr = section_offset + 0x10000;
	s_rodata_sceResident.sh_flags = 2;
	s_rodata_sceResident.sh_size = 4;
	for(u32 i=0; i<modules.GetCount(); ++i)
	{
		s_rodata_sceResident.sh_size += modules[i].m_name.Len() + 1;
	}
	s_rodata_sceResident.sh_size = Memory.AlignAddr(s_rodata_sceResident.sh_size, s_rodata_sceResident.sh_addralign);
	sections_names.Add(".rodata.sceResident");
	section_name_offset += wxString(".rodata.sceResident").Len() + 1;
	section_offset += s_rodata_sceResident.sh_size;

	Elf64_Shdr s_lib_ent_top;
	memset(&s_lib_ent_top, 0, sizeof(Elf64_Shdr));
	s_lib_ent_top.sh_addralign = 4;
	section_offset = Memory.AlignAddr(section_offset, s_lib_ent_top.sh_addralign);
	s_lib_ent_top.sh_size = 4;
	s_lib_ent_top.sh_flags = 2;
	s_lib_ent_top.sh_type = 1;
	s_lib_ent_top.sh_name = section_name_offset;
	s_lib_ent_top.sh_offset = section_offset;
	s_lib_ent_top.sh_addr = section_offset + 0x10000;
	sections_names.Add(".lib.ent.top");
	section_name_offset += wxString(".lib.ent.top").Len() + 1;
	section_offset += s_lib_ent_top.sh_size;

	Elf64_Shdr s_lib_ent_btm;
	memset(&s_lib_ent_btm, 0, sizeof(Elf64_Shdr));
	s_lib_ent_btm.sh_addralign = 4;
	s_lib_ent_btm.sh_size = 4;
	s_lib_ent_btm.sh_flags = 2;
	s_lib_ent_btm.sh_type = 1;
	s_lib_ent_btm.sh_name = section_name_offset;
	s_lib_ent_btm.sh_offset = section_offset;
	s_lib_ent_btm.sh_addr = section_offset + 0x10000;
	sections_names.Add(".lib.ent.btm");
	section_name_offset += wxString(".lib.ent.btm").Len() + 1;
	section_offset += s_lib_ent_btm.sh_size;

	Elf64_Shdr s_sys_proc_prx_param;
	memset(&s_sys_proc_prx_param, 0, sizeof(Elf64_Shdr));
	s_sys_proc_prx_param.sh_addralign = 4;
	section_offset = Memory.AlignAddr(section_offset, s_sys_proc_prx_param.sh_addralign);
	s_sys_proc_prx_param.sh_type = 1;
	s_sys_proc_prx_param.sh_size = sizeof(sys_proc_prx_param);
	s_sys_proc_prx_param.sh_name = section_name_offset;
	s_sys_proc_prx_param.sh_offset = section_offset;
	s_sys_proc_prx_param.sh_addr = section_offset + 0x10000;
	s_sys_proc_prx_param.sh_flags = 2;
	sections_names.Add(".sys_proc_prx_param");
	section_name_offset += wxString(".sys_proc_prx_param").Len() + 1;
	section_offset += s_sys_proc_prx_param.sh_size;

	const u32 prog_load_0_end = section_offset;

	section_offset = Memory.AlignAddr(section_offset + 0x10000, 0x10000);
	const u32 prog_load_1_start = section_offset;

	Elf64_Shdr s_data_sceFStub;
	memset(&s_data_sceFStub, 0, sizeof(Elf64_Shdr));
	s_data_sceFStub.sh_name = section_name_offset;
	s_data_sceFStub.sh_addralign = 4;
	section_offset = Memory.AlignAddr(section_offset, s_data_sceFStub.sh_addralign);
	s_data_sceFStub.sh_flags = 3;
	s_data_sceFStub.sh_type = 1;
	s_data_sceFStub.sh_offset = section_offset;
	s_data_sceFStub.sh_addr = section_offset + 0x10000;
	s_data_sceFStub.sh_size = imports_count * 4;
	sections_names.Add(".data.sceFStub");
	section_name_offset += wxString(".data.sceFStub").Len() + 1;
	section_offset += s_data_sceFStub.sh_size;

	Elf64_Shdr s_tbss;
	memset(&s_tbss, 0, sizeof(Elf64_Shdr));
	s_tbss.sh_addralign = 4;
	section_offset = Memory.AlignAddr(section_offset, s_tbss.sh_addralign);
	s_tbss.sh_size = 4;
	s_tbss.sh_flags = 0x403;
	s_tbss.sh_type = 8;
	s_tbss.sh_name = section_name_offset;
	s_tbss.sh_offset = section_offset;
	s_tbss.sh_addr = section_offset + 0x10000;
	sections_names.Add(".tbss");
	section_name_offset += wxString(".tbss").Len() + 1;
	section_offset += s_tbss.sh_size;

	Elf64_Shdr s_opd;
	memset(&s_opd, 0, sizeof(Elf64_Shdr));
	s_opd.sh_addralign = 8;
	section_offset = Memory.AlignAddr(section_offset, s_opd.sh_addralign);
	s_opd.sh_size = 2*4;
	s_opd.sh_type = 1;
	s_opd.sh_offset = section_offset;
	s_opd.sh_addr = section_offset + 0x10000;
	s_opd.sh_name = section_name_offset;
	s_opd.sh_flags = 3;
	sections_names.Add(".opd");
	section_name_offset += wxString(".opd").Len() + 1;

	FirstChar();

	while(!IsEnd())
	{
		wxString op;
		if(!GetOp(op) || IsFuncOp(op) || IsSpOp(op))
		{
			NextLn();
			continue;
		}

		if(IsBranchOp(op))
		{
			const wxString& name = op(0, op.Len() - 1);

			for(u32 i=0; i<m_branches.GetCount(); ++i)
			{
				if(name.ToStdString() != m_branches[i].m_name) continue;
				WriteError(wxString::Format("'%s' already declared", name.wx_str()));
				m_error = true;
				break;
			}

			Arg a_name(name);
			DetectArgInfo(a_name);

			if(a_name.type != ARG_ERR)
			{
				WriteError(wxString::Format("bad name '%s'", name.wx_str()));
				m_error = true;
			}

			if(m_error) break;

			m_branches.Move(new Branch(name, m_branch_pos));

			CheckEnd();
			continue;
		}

		m_branch_pos++;
		NextLn();
	}

	bool has_entry = false;
	for(u32 i=0; i<m_branches.GetCount(); ++i)
	{
		if(m_branches[i].m_name != "entry")
			continue;

		has_entry = true;
		break;
	}

	if(!has_entry) m_branches.Move(new Branch("entry", 0));

	if(m_analyze) m_error = false;
	FirstChar();

	while(!IsEnd())
	{
		m_args.Clear();
		m_end_args = false;

		wxString op;
		if(!GetOp(op) || IsBranchOp(op) || IsFuncOp(op))
		{
			if(m_analyze) WriteHex("\n");
			NextLn();
			continue;
		}

		if(IsSpOp(op))
		{
			LoadSp(op, s_opd);
			continue;
		}

		LoadArgs();

		auto instr = GetInstruction<PPUOpcodes>(op);
		if(instr)
		{
			uint type[] =
			{
				ARG_IMM,
				ARG_REG_R,
				ARG_REG_F,
				ARG_REG_V,
				ARG_REG_CR,
			};

			for(uint i=0; i<instr->GetArgCount(); ++i)
			{
				switch(instr->GetArg(i).m_type)
				{
				case FIELD_BRANCH:
					SetNextArgBranch(0); //TODO
				break;

				default:
					SetNextArgType(type[instr->GetArg(i).m_type]);
				break;
				}
			}
		}
		else
		{
			WriteError(wxString::Format("unknown instruction '%s'", op.wx_str()));
			EndLn();
			m_error = true;
		}

		CheckEnd();

		if(m_error)
		{
			if(m_analyze)
			{
				WriteHex("error\n");
				m_error = false;
				continue;
			}

			break;
		}

		u32 code;

		{
			Array<u32> args;
			args.SetCount(m_args.GetCount());
			for(uint i=0; i<args.GetCount(); ++i)
			{
				args[i] = m_args[i].value;
			}

			code = (*instr)(args);
		}

		if(m_analyze) WriteHex(wxString::Format("0x%08x\n", code));

		if(!m_analyze) m_code.AddCpy(code);

		m_branch_pos++;
	}

	if(!m_file_path.IsEmpty() && !m_analyze && !m_error)
	{
		s_opd.sh_size = Memory.AlignAddr(s_opd.sh_size, s_opd.sh_addralign);
		section_offset += s_opd.sh_size;

		const u32 prog_load_1_end = section_offset;

		Elf64_Shdr s_shstrtab;
		memset(&s_shstrtab, 0, sizeof(Elf64_Shdr));
		s_shstrtab.sh_addralign = 1;
		section_offset = Memory.AlignAddr(section_offset, s_shstrtab.sh_addralign);
		s_shstrtab.sh_name = section_name_offset;
		s_shstrtab.sh_type = 3;
		s_shstrtab.sh_offset = section_offset;
		s_shstrtab.sh_addr = 0;
		sections_names.Add(".shstrtab");
		section_name_offset += wxString(".shstrtab").Len() + 1;
		s_shstrtab.sh_size = section_name_offset;
		section_offset += s_shstrtab.sh_size;

		wxFile f(m_file_path, wxFile::write);

		elf_info.e_magic = 0x7F454C46;
		elf_info.e_class = 2; //ELF64
		elf_info.e_data = 2;
		elf_info.e_curver = 1; //ver 1
		elf_info.e_os_abi = 0x66; //Cell OS LV-2
		elf_info.e_abi_ver = 0;
		elf_info.e_type = 2; //EXEC (Executable file)
		elf_info.e_machine = MACHINE_PPC64; //PowerPC64
		elf_info.e_version = 1; //ver 1
		elf_info.e_flags = 0x0;
		elf_info.e_shoff = Memory.AlignAddr(section_offset, 4);

		u8* opd_data = new u8[s_opd.sh_size];
		u32 entry_point = s_text.sh_addr;
		for(u32 i=0; i<m_branches.GetCount(); ++i)
		{
			if(m_branches[i].m_name == "entry")
			{
				entry_point += m_branches[i].m_pos * 4;
				break;
			}
		}
		*(u32*)opd_data = re32(entry_point);
		*(u32*)(opd_data + 4) = 0;

		sys_proc_prx_param prx_param;
		memset(&prx_param, 0, sizeof(sys_proc_prx_param));

		prx_param.size = re32(0x40);
		prx_param.magic = re32(0x1b434cec);
		prx_param.version = re32(0x4);
		prx_param.libentstart = re32(s_lib_ent_top.sh_addr + s_lib_ent_top.sh_size);
		prx_param.libentend = re32(s_lib_ent_btm.sh_addr);
		prx_param.libstubstart = re32(s_lib_stub_top.sh_addr + s_lib_stub_top.sh_size);
		prx_param.libstubend = re32(s_lib_stub_btm.sh_addr);
		prx_param.ver = re16(0x101);
			
		elf_info.e_entry = s_opd.sh_addr;

		f.Seek(0);
		WriteEhdr(f, elf_info);

		f.Seek(elf_info.e_shoff);
		WriteShdr(f, s_null);
		WriteShdr(f, s_text);
		WriteShdr(f, s_opd);
		WriteShdr(f, s_sceStub_text);
		WriteShdr(f, s_lib_stub_top);
		WriteShdr(f, s_lib_stub);
		WriteShdr(f, s_lib_stub_btm);
		WriteShdr(f, s_data_sceFStub);
		WriteShdr(f, s_rodata_sceFNID);
		WriteShdr(f, s_rodata_sceResident);
		WriteShdr(f, s_sys_proc_prx_param);
		WriteShdr(f, s_lib_ent_top);
		WriteShdr(f, s_lib_ent_btm);
		WriteShdr(f, s_tbss);
		WriteShdr(f, s_shstrtab);

		f.Seek(s_text.sh_offset);
		for(u32 i=0; i<m_code.GetCount(); ++i) Write32(f, m_code[i]);

		f.Seek(s_opd.sh_offset);
		f.Write(opd_data, 8);
		for(u32 i=0; i<m_sp_string.GetCount(); ++i)
		{
			f.Seek(s_opd.sh_offset + (m_sp_string[i].m_addr - s_opd.sh_addr));
			f.Write(&m_sp_string[i].m_data[0], m_sp_string[i].m_data.length() + 1);
		}

		f.Seek(s_sceStub_text.sh_offset);
		for(u32 i=0; i<imports_count; ++i)
		{
			const u32 addr = s_data_sceFStub.sh_addr + i * 4;
			Write32(f, ADDI(12, 0, 0));
			Write32(f, ORIS(12, 12, addr >> 16));
			Write32(f, LWZ(12, 12, addr));
			Write32(f, STD(2, 1, 40));
			Write32(f, LWZ(0, 12, 0));
			Write32(f, LWZ(2, 12, 4));
			Write32(f, MTSPR(0x009, 0));
			Write32(f, BCCTR(20, 0, 0, 0));
		}

		f.Seek(s_lib_stub_top.sh_offset);
		f.Seek(s_lib_stub_top.sh_size, wxFromCurrent);

		f.Seek(s_lib_stub.sh_offset);
		for(u32 i=0, nameoffs=4, dataoffs=0; i<modules.GetCount(); ++i)
		{
			Elf64_StubHeader stub;
			memset(&stub, 0, sizeof(Elf64_StubHeader));

			stub.s_size = 0x2c;
			stub.s_version = re16(0x1);
			stub.s_unk1 = re16(0x9);
			stub.s_modulename = re32(s_rodata_sceResident.sh_addr + nameoffs);
			stub.s_nid = re32(s_rodata_sceFNID.sh_addr + dataoffs);
			stub.s_text = re32(s_data_sceFStub.sh_addr + dataoffs);
			stub.s_imports = re16(modules[i].m_imports.GetCount());

			dataoffs += modules[i].m_imports.GetCount() * 4;

			f.Write(&stub, sizeof(Elf64_StubHeader));
			nameoffs += modules[i].m_name.Len() + 1;
		}

		f.Seek(s_lib_stub_btm.sh_offset);
		f.Seek(s_lib_stub_btm.sh_size, wxFromCurrent);

		f.Seek(s_data_sceFStub.sh_offset);
		for(u32 m=0; m<modules.GetCount(); ++m)
		{
			for(u32 i=0; i<modules[m].m_imports.GetCount(); ++i)
			{
				Write32(f, m_branches[modules[m].m_imports[i]].m_addr);
			}
		}

		f.Seek(s_rodata_sceFNID.sh_offset);
		for(u32 m=0; m<modules.GetCount(); ++m)
		{
			for(u32 i=0; i<modules[m].m_imports.GetCount(); ++i)
			{
				Write32(f, m_branches[modules[m].m_imports[i]].m_id);
			}
		}

		f.Seek(s_rodata_sceResident.sh_offset + 4);
		for(u32 i=0; i<modules.GetCount(); ++i)
		{
			f.Write(&modules[i].m_name[0], modules[i].m_name.Len() + 1);
		}

		f.Seek(s_sys_proc_prx_param.sh_offset);
		f.Write(&prx_param, sizeof(sys_proc_prx_param));

		f.Seek(s_lib_ent_top.sh_offset);
		f.Seek(s_lib_ent_top.sh_size, wxFromCurrent);

		f.Seek(s_lib_ent_btm.sh_offset);
		f.Seek(s_lib_ent_btm.sh_size, wxFromCurrent);

		f.Seek(s_tbss.sh_offset);
		f.Seek(s_tbss.sh_size, wxFromCurrent);

		f.Seek(s_shstrtab.sh_offset + 1);
		for(u32 i=0; i<sections_names.GetCount(); ++i)
		{
			f.Write(&sections_names[i][0], sections_names[i].Len() + 1);
		}

		Elf64_Phdr p_load_0;
		p_load_0.p_type = 0x00000001;
		p_load_0.p_offset = 0;
		p_load_0.p_paddr =
		p_load_0.p_vaddr = 0x10000;
		p_load_0.p_filesz =
		p_load_0.p_memsz = prog_load_0_end;
		p_load_0.p_align = 0x10000;
		p_load_0.p_flags = 0x400005;

		Elf64_Phdr p_load_1;
		p_load_1.p_type = 0x00000001;
		p_load_1.p_offset = prog_load_1_start;
		p_load_1.p_paddr =
		p_load_1.p_vaddr = prog_load_1_start + 0x10000;
		p_load_1.p_filesz =
		p_load_1.p_memsz = prog_load_1_end - prog_load_1_start;
		p_load_1.p_align = 0x10000;
		p_load_1.p_flags = 0x600006;

		Elf64_Phdr p_tls;
		p_tls.p_type = 0x00000007;
		p_tls.p_offset = s_tbss.sh_offset;
		p_tls.p_paddr =
		p_tls.p_vaddr = s_tbss.sh_addr;
		p_tls.p_filesz = 0;
		p_tls.p_memsz = s_tbss.sh_size;
		p_tls.p_align = s_tbss.sh_addralign;
		p_tls.p_flags = 0x4;

		Elf64_Phdr p_loos_1;
		p_loos_1.p_type = 0x60000001;
		p_loos_1.p_offset = 0;
		p_loos_1.p_paddr = 0;
		p_loos_1.p_vaddr = 0;
		p_loos_1.p_filesz = 0;
		p_loos_1.p_memsz = 0;
		p_loos_1.p_align = 1;
		p_loos_1.p_flags = 0;

		Elf64_Phdr p_loos_2;
		p_loos_2.p_type = 0x60000002;
		p_loos_2.p_offset = s_sys_proc_prx_param.sh_offset;
		p_loos_2.p_paddr =
		p_loos_2.p_vaddr = s_sys_proc_prx_param.sh_addr;
		p_loos_2.p_filesz =
		p_loos_2.p_memsz = s_sys_proc_prx_param.sh_size;
		p_loos_2.p_align = s_sys_proc_prx_param.sh_addralign;
		p_loos_2.p_flags = 0;

		f.Seek(elf_info.e_phoff);
		WritePhdr(f, p_load_0);
		WritePhdr(f, p_load_1);
		WritePhdr(f, p_tls);
		WritePhdr(f, p_loos_1);
		WritePhdr(f, p_loos_2);

		sections_names.Clear();
		delete[] opd_data;
		for(u32 i=0; i<modules.GetCount(); ++i) modules[i].Clear();
		modules.Clear();
	}