Having issues importing game.

Jun 15, 2013 at 7:25 AM
So I wanted to port my XNA game to silverlight. Here are the steps I followed:

-Started a new silverlight project.
-added all the code content from my game to it (all the .cs files pretty much) using "add existing item"
-added the reference to silversprite.dll using the "add reference" button.
-getting a couple errors throughout that won't let me compile, they all say "the type or namespace name "blah" could not be found

Below are some of the things it couldn't find:

These seem pretty basic, especially SpriteBatch. I feel like I'm missing a step or something because something like SpriteBatch should be found in silverlight5 especially with silversprite right? Thank you for your time I really want to be able to put my XNA game onto the web.

Texture2D
SpriteBatch
KeyboardState
GraphicsDevice
ContentManager
using Microsoft.Xna.Framework.Audio
using Microsoft.Xna.Framework.Content
SpriteSortMode
BlendState
Jun 16, 2013 at 12:20 AM
I'm having issues with the spritefont only now. It says random errors for it like "first non-whitespace character on a line".

I fixed the rest of the issues by adding references to microsoft XNA and then deleting the extra Vector etcs in farseer for silverlight. Farseer silverlight also needed a reference to microsoft XNA math.
Jun 16, 2013 at 1:27 AM
Okay fixed spritefont issue. Right click->properties had it set to "compile" and changing it to "none" fixed it. Also had to convert all .bmp files to .png.

Now when I run it I just get a white screen. I don't really know much about silverlight, should it be displaying things or do I need to add code for it to do that? So far all I have is the following in my MainPage.xaml.cs file:
public partial class MainPage : UserControl
{
    Game1 game;
    public MainPage()
    {
        InitializeComponent();
        game = new Game1();
        game.Attach(LayoutRoot);
        game.Run();
    }
}
Its based on the tutorial on the front page except I added game.Run(); Not sure if I was supposed to.
Jun 17, 2013 at 8:01 AM
After looking at example programs using silverlight5 I figured out how to port mine but it was a pretty complicated process.
Jun 25, 2013 at 8:20 PM
Edited Jun 25, 2013 at 8:40 PM
Okay here is a guide in VS2010 to porting:

-Make a new 3D silverlight application using the new project options. Even if your project is 2D you need the basic things in the template that comes with this (mainly a content pipeline project thing). This is assuming you have silverlight5 already installed. The homepage of silversprite shows you how to install it.

First remove some of the files that came with the project like Cube and Scene BUT MAKE SURE YOU KEEP MainPage.xaml App.xaml also you should not be touching the "Silverlight3dWeb" project for awhile only the Silverlight3dApp project. Now add all your code to the silverlight3dApp project, and all your resources like pictures etc into the content project just like normal XNA. NOTE THOUGH that I couldn't get .bmp images to work so you should convert them to .png format. Other formats might work but I only tried .png and that for sure works. If you are using farseer you have to add in the project file for that as well. Don't add the .dll but the actual project .csproj file.

Now the main thing you have to do is artificially call your game loop within the MainPage.xaml.cs class. In XNA update->draw->update->draw etc is called automatically and the game is initialized automatically.

To do this we add some code to the MainPage.xaml.cs class file that should have come with your silverlight project. First though you've probably noticed a lot of errors in the code you copied from your XNA project and these can be remedied by adding references. If you are using farseer you also need to add references to that as well. So on your projects add the XNA references. These are the references I have:

Farseer silverlight
Microsoft.Xna.Framework
Microsoft.Xna.Framework.Content
Microsoft.Xna.Framework.Graphics
Microsoft.Xna.Framework.Graphics.Extensions
Microsoft.Xna.Framework.Shaders
Microsoft.Xna.Framework.Math
Microsoft.Xna.Framework.Toolkit
SilverSprite
System.Windows.Xna
mscorlib

and then some basic System. stuff like core, net, windows, Linq, as well as some .Xml ones.

To the content project where all your pictures etc are stored you need to add references as well that will be in the format:
Microsoft.Xna.Framework.Content.Pipeline.

Basically add all the references that start with that.

Note that unless you don't want some extra code in your project adding references DOESN'T HARM ANYTHING generally. So if you're not sure which references to add then add all of the references you think you might need. The extra code will likely take up almost no space compared to picture files etc so you don't have to worry about anything.

Now some of your code will likely still be complaining with errors. These can be remedied by either adding or removing the "using System;" etc. at the top. Likely if your porting from an XNA program you will need to mostly remove things that silverlight doesn't support. The only one to my knowledge is those dealing with SAVING things to a file since silverlight applications typically can't do that the same way a windows application could.

Here are the "using" in my Game1.cs class:

using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using System.Windows.Graphics;
using System.Windows.Controls;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;
using FarseerPhysics.Dynamics;
using System.Windows.Controls;

Now farseer will be complaining when you add in XNA references to it something like "Vector2 is in both blah and blah". This is because farseer was made for Silverlight4 but we are using silverlight5 which added some redundancies. Simply go to the farseer project we imported from before and remove the redundant files. I can't recall exactly what I removed but it involved Vector2, Vector3, MathHelper and a few more. You might also need to add using Microsoft.Xna.Framework.Blah to some classes as well but I can't remember.

Okay now most of the code shouldn't be complaining now, aside from a few errors. If it is still complaining by the end of this tutorial try removing what ever using its complaining about or commenting out the code directly if you can. You can email me if you have a specific error but usually the dumb obvious solution like removing a using, some code, or adding a using will fix it. Sometimes if you need to add a using it will tell you automatically if you click the underlined code and click the little box that will come up and click "add blah" to the top and it will add the using necessary to run that code.

Anyway, so now you have to actually call your game loop within silverlight. This is what gave me the most trouble.

So in your template you should have some functions in your MainPage.xaml.cs file already. Here are the three that I used:

public MainPage()
private void myDrawingSurface_Draw(object sender, DrawEventArgs e)
private void UserControl_Loaded(object sender, RoutedEventArgs e)

We will be editing these two functions, and removing the rest.

So firstly we need to add your game and a few other things as a class objects to your MainPage. Mine looks like this:

public partial class MainPage : UserControl
{


    Game1 game;
    Microsoft.Xna.Framework.GameTime gt;


    readonly TimeSpan TargetElapsedTime = TimeSpan.FromTicks(TimeSpan.TicksPerSecond / 60);
    readonly TimeSpan MaxElapsedTime = TimeSpan.FromTicks(TimeSpan.TicksPerSecond / 10);

    TimeSpan accumulatedTime;
So my Game1 class is my game. And the others have to do with keeping time since the XNA time keeper GameTime isn't in silverlight. Technically it is but I couldn't get it to work and this should do most of what GameTime does already. If you used GameTime for Elapsed or Total time, then this will work fine.

Now in the public MainPage() function should be changed to just have the following:

public MainPage()
    {
        InitializeComponent();
    }
I can't recall if more code was here in the default template if so we will move it around.

Now we initialize our game in the following function like so:

private void UserControl_Loaded(object sender, RoutedEventArgs e)
    {
        if (GraphicsDeviceManager.Current.RenderMode != RenderMode.Hardware)
        {
            MessageBox.Show("Please activate enableGPUAcceleration=true on your Silverlight plugin page.", "Warning", MessageBoxButton.OK);
        }

        game = new Game1();

        game.Attach(LayoutRoot);

        gt = new Microsoft.Xna.Framework.GameTime();
        game.Initialize();
   // Creates game
    }
Here we first check to see if the gpu is on. In order for this to work you need to have the following settings changed in your project:
right click your Silverlight3dApp project and in the Silverlight tab near the middle should be the following setting:

Enable Running application out of browser and then a button for Out-Of-Browser settings...

This is for if you don't want to run Chrome or Firefox every time you want to debug your program. If you check off enable running out of browser then in the Out of Browser Settings make sure you click:

Require elevated trust when running out of browser

If you want to run it in chrome/firefox then make sure you check:

Require elevated trust when running in-browser

which should be below the out of browser settings button. If later it still complains about gpu not running then you need to add the following code to your Silverlight3dAppTestPage.aspx and Silverlight3dAppTestPage.html files in the Silverlight3dWeb project.

<param name="enableGPUAcceleration" value="true" />

In the .html and .aspx files it should be added here near the bottom:
<div id="silverlightControlHost">
    <object data="data:application/x-silverlight-2," type="application/x-silverlight-2" width="100%" height="100%">
      <param name="source" value="ClientBin/Silverlight3dApp.xap"/>
      <param name="onError" value="onSilverlightError" />
      <param name="background" value="white" />
      <param name="minRuntimeVersion" value="5.0.60401.0" />
      <param name="autoUpgrade" value="true" />
              <param name="enableGPUAcceleration" value="true" />

Now note that in the above C# code we had way up there we call the game.Initialize() function here manually while in XNA it is called automatically. This should be what ever code your game runs before calling update->draw->update->draw loop. You can step through your program in XNA manually to see what functions it calls automatically if you don't have a Initialize() function in your game (I can't recall if all XNA programs have those by default).

Now thats all for that function.


The other function should have the following:

private void myDrawingSurface_Draw(object sender, DrawEventArgs e)
    {

        TimeSpan elapsedTime = e.DeltaTime;

        if (elapsedTime > MaxElapsedTime)
        {
            elapsedTime = MaxElapsedTime;
        }

        accumulatedTime += elapsedTime;

        while (accumulatedTime >= TargetElapsedTime)
        {
            game.Update(e);
            accumulatedTime -= TargetElapsedTime;
        }

        // Render scene

        game.Draw(e);

        // Let's go for another turn!
        e.InvalidateSurface();
    }
Here we setup game time and then call update and draw over and over. We setup the time so that you are calling game.Update(e) and game.Draw(e) about 60 times per second. I believe its SLIGHTLY higher like 63 but this is close as we can get to the default XNA fps of 60. e.InvalidateSurface() basically makes it so this function is called again right after. Now you will have errors because your update draw and initialize functions in your XNA game class should be private not public. CONTINUED IN NEXT POST.
Jun 25, 2013 at 8:42 PM
Edited Jun 25, 2013 at 8:43 PM
So my functions in my XNA game class had to have there headers changed to as follows:

public void Update(DrawEventArgs e)
public void Initialize()
public void Draw(DrawEventArgs e)

Note update and draw now use DrawEventArgs instead of GameTime. So we must change all calls to GameTime.ElapsedTime etc to the following:
e.DeltaTime.Milliseconds
assuming you called DrawEventArgs variable e.
All your update and draw functions will have to be changed to use DrawEventArgs, none should use GameTime. This can be done somewhat quickly by using find and replace carefully in visual studio.

Your update function will also probably have this:
base.Update(new GameTime());
leave that there although I don't think it does anything anymore.

Draw function has to be changed quite a bit as well because now any time you use GraphicsDevice in your program you will need to replace it with:
System.Windows.Graphics.GraphicsDeviceManager.Current.GraphicsDevice

for example:
System.Windows.Graphics.GraphicsDeviceManager.Current.GraphicsDevice.Clear(Color.White);

Also make sure you get rid of any GraphicsDevice variable in your game class and anything you do with it. I believe its used in initialize() as well as other places so remove it. You must now use System.Windows.Graphics.GraphicsDeviceManager.Current.GraphicsDevice instead.

Also you will not be able to use colors easily anymore. Silversprite has some support for it as it mentions in the homepage but I just stopped using it and replaced it with Color.White or Color.Black and the other colors that are in silverlight.

You will likely need to add:
using System.Windows.Controls;
to a lot of classes now.

Again find and replace and refractoring can help a lot with making these changes.

So I believe your game should now compile although likely not work completely because we have a little more to do. If it doesn't compile let me know by email or replying here I may have forgotten something.

Now lastly, and this was done VERY STUPIDLY, as in trial and error until it worked barely, you have to actually draw your game in the web browser. So we have to edit the MainPage.xaml file which should be next to your MainPage.xaml.cs class.
I have the following:

<UserControl x:Class="Silverlight3dApp.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
Loaded="UserControl_Loaded"
mc:Ignorable="d" IsEnabled="True" Height="1000" Width="1000" Opacity="1">

<Grid x:Name="LayoutRoot" Background="White" Height="0" Width="0" ShowGridLines="True" Visibility="Visible">
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="0*" />
        <ColumnDefinition Width="0*" />
        <ColumnDefinition Width="0*" />
    </Grid.ColumnDefinitions>
    <!--3D drawing surface-->
    <DrawingSurface x:Name="myDrawingSurface" Draw="myDrawingSurface_Draw" VerticalAlignment="Center" HorizontalAlignment="Center" Height="603" Width="800" Margin="-1030,-1010,-1010,-1094" Grid.ColumnSpan="3" />
    <!--TextBlock Text="My Silverlight 3D Application" VerticalAlignment="Top" HorizontalAlignment="Center" Margin="0,30" Foreground="White" FontSize="40"/-->
</Grid>
</UserControl>


ALOT, and I mean ALOT of the parameters in there are bullshit that somehow managed to work for me. You'll see weird things like negative margins etc. This is because I don't know xaml AT ALL but this code managed to get my game to draw and work. You can edit some of the stuff by clicking on a line then editing parameters on the little box to the right that would normally have class properties.
If any of you know xaml and want to show how to properly do this please do.

Anyway so now your game should work in silverlight if it doesn't email me or reply to this thread. Also note that I MAY HAVE TYPOS EVERYWHERE so if something isn't exactly the same then please reply and ask questions.