Announcement

Collapse

The Infinity Blade Forums Have Moved

We've launched brand new Infinity Blade forums with improved features and revamped layout. We've also included a complete archive of the previous posts. Come check out the new Infinity Blade forums.
See more
See less

Scaleform UI without Flash: Vectorian Giotto and FlashDevelop

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

    #16
    This Tutorial isn't working for me.

    I keep getting this retarded error when attempting to build in FlashDevelop 4. I copy-pasted your code and tried to build with it instead. Same thing.

    Code:
    Running process: C:\Program Files (x86)\FlashDevelop\Tools\fdbuild\fdbuild.exe "C:\UDK\UDK-2011-06\UDKGame\Flash\VectorMenuTut\VectorMainMenu\VectorMainMenu.as2proj" -ipc ee630f1f-d955-42f2-b706-7369681ae720 -version "1.14" -compiler "C:\Program Files (x86)\FlashDevelop\Tools\mtasc" -notrace -library "C:\Program Files (x86)\FlashDevelop\Library"
    Building VectorMainMenu
    Exception: startIndex cannot be larger than length of string.
    Parameter name: startIndex
    Done(1)

    Comment


      #17
      Try adding a } at the end of the source, I might have left one off. Otherwise make sure you have added the src folder to the classpaths.

      Comment


        #18
        Originally posted by DonaldM View Post
        Try adding a } at the end of the source, I might have left one off. Otherwise make sure you have added the src folder to the classpaths.
        After much frustration, I actually figured out what caused the exception. Somehow I had both the src folder and the class file set to always compile. I had to turn off the "always compile" on the folder, so that only the class had that property. Of course I didn't find this problem out until after I had already uninstalled version 4.0.0 and installed 3.3.4 RTM to see if that was the problem.

        Then the "cursor follows the mouse" code didn't work. The code correctly compiled; it just didn't do any good. I found out that was because the code was only compatible with Vectorian Giotto's free-draw tool objects, and not anything drawn using the rectangle or oval tools. So I had to go back and delete the cursor object and free-draw a new one on the Cursor layer. After that, the code magically worked.

        I got it into UDK and loaded into my level in play-in-editor using Kismet, though I'm not sure how to make the buttons actually do more than just highlight/un-highlight. Do you have a picture of the rest of your Kismet page?

        P.S. Thank you for making this tutorial. I learned a lot once I finally got it figured out.

        Comment


          #19
          Hello NekoDemon117,

          That is very odd. If you draw inside of the cursor movieclip it should work with any tool. I will try to test this later and see what the problem is.

          Making the buttons do something involves doing something similar to this:

          Put:

          Code:
          import flash.external.ExternalInterface;
          At the top of the file and:

          Code:
          		_root.exitBtn.onPress = function ()
          		{
          		    ExternalInterface.call("ExitClicked");
                  
          		}
          after your cursor stuff in the actionscript.

          And your welcome!

          Comment


            #20
            So rather unfortunately Vectorian Giotto does not support saving imported images as png (loseless) rather than jpeg as of yet. Scaleform requires all embedded images to be png files. I have sent an email to the creator of Vectorian Giotto and asked if they can include support for saving the image resources as png files.

            I am not giving up on this potentially working though and I am currently working on a small software utility which may allow a temporary fix to the problem.

            I have been playing around with two .net SWF libraries to attempt to create a command line utility for turning the jpeg tags into lossless tags. I have had success getting information about the images from the swf file using SwfNet, but I like SwfDotNet's structure a lot better. While SwfNet supports up to SWF 8, SwfDotNet only supports up to version 7. I got some odd errors when attempting to use SwfDotNet to read the images... it said the header information was corrupted, but that is obviously a failing of the library as I was able to read the files using a variety of other methods. Luckily both libraries are open source... The idea behind the approach would be to go through and convert any jpeg tags in the swf file to loseless tags that can be read by scaleform. It shouldn't be extremely complicated, the trouble is just finding a library that can work as expected.

            I am not without results so far for my efforts:

            Comment


              #21
              So I have been working the issue all day and I believe that I will have a tool ready by the end of the day tomorrow that will be able to make the toolchain work for images. It is a command line so you simply will drag your dummy object (or even your final object) and it will automatically find and convert all of the jpeg tags to lossless tags and save your swf with an appended _lossless to the filename. It took a lot of time because I had to do some modifications to the existing swf library for dotnet... and combined some code together. As I believe in sharing those changes I modified the DefineBitsJpeg2Tag.cs file of the SwfDotNet library as follows:

              Code:
                      private void DecompileToStream(Stream stream)
                      {
              			BinaryWriter writer = new BinaryWriter(stream);
              
                          byte[] data = new byte[JpegData.Length];
              
                          Array.Copy(JpegData, data, JpegData.Length);
              
                          // first header
                          if (data[0] == 0xFF && data[1] == 0xD9 &&data[2] == 0xFF && data[3] == 0xD8)
                          {
                              byte[] copy = new byte[data.Length - 4];
                              Array.Copy(data, 4, copy, 0, data.Length - 4);
                              data = copy;
                          }
                          // cleans out bug markers in swf jpgs
                          int index = 2;
                          int len = data.Length;
                          while (index + 3 < len)
                          {
                              byte b0 = data[index];
                              if (b0 != 0xFF)
                              {
                                  break;
                              }
                              if (data[index + 1] == 0xD9 && data[index + 2] == 0xFF && data[index + 3] == 0xD8)
                              {
                                  // bingo
                                  byte[] copy = new byte[data.Length - 4];
                                  Array.Copy(data, 0, copy, 0, index);
                                  Array.Copy(data, index + 4, copy, index, data.Length - index - 4);
                                  data = copy;
                                  break;
                              }
                              else
                              {
                                  int tagLen = (data[index + 2] << 8) + data[index + 3] + 2;
                                  index += tagLen;
                              }
                          }
                          writer.Write(data);
                          writer.Flush();
                      }
              which is code I took from the Clean method of the DefineBitsTag.cs file of the SwfNet library (I determined that this method was what was causing my images to not decode correctly, not sure if it is a bug with the original library or the fact I am using a higher version of swf then the library was designed for)... and then... I modified the SwfHeader.cs MAX_VERSION constant in the SwfDotNet library to support a higher version (I used 8). It is in the latest build set to 7 which doesn't work for our purposes ._. .

              Anyway that is what I have done so far with the following code:

              Code:
                     static void Main(string[] args)
                      {
                          string filename = "C:\\UDK\\UDK-2011-05\\UDKGame\\Flash\\VectorMenuTut\\VectorMainMenu_Dummy.swf";
                          if (filename != "")
                          {
                              string name = Path.GetFileNameWithoutExtension(filename);
              
              
                              string outputFilename = "";
                              if (args.Length < 2)
                              {
                                  
                                  outputFilename = Path.Combine(Path.GetDirectoryName(filename) , Path.GetFileNameWithoutExtension(filename) + "_Loseless"+Path.GetExtension(filename));
                                  
                              }
                              else
                              {
                                  outputFilename = args[1];
                              }
              
                              Console.WriteLine("File: " + Path.GetFileNameWithoutExtension(filename));
                              Console.WriteLine("Output to: "+outputFilename);
              
                              SwfWriter swfWriter = new SwfWriter(outputFilename);
              
                              SwfReader swfReader = new SwfReader(filename);
                              Swf swf = swfReader.ReadSwf();
                            
                              SwfHeader swfHeader = swf.Header;
                              Swf modifiedSwf = new Swf(swfHeader);
                              Console.WriteLine("Width: " + swfHeader.Width);
                              Console.WriteLine("Height: " + swfHeader.Height);
                              Console.WriteLine("FPS: " + swfHeader.Fps);
              
                              IEnumerator curTag = swf.Tags.GetEnumerator();
              
                              int a = 0;
                              while (curTag.MoveNext())
                              {
                                  if (curTag.Current is DefineBitsJpeg3Tag)
                                  {
                                      Console.WriteLine("Found JPEG with alpha!");
              
                                      DefineBitsJpeg3Tag jpegTag = curTag.Current as DefineBitsJpeg3Tag;
              
                                      
                                      Image curImage = jpegTag.DecompileToImage();
                                      
              
                                      Console.WriteLine("Image width: " + curImage.Width);
                                      Console.WriteLine("Image height: " + curImage.Height);
                                     
                                      a++;
              
              
                                  }
                                  else if (curTag.Current is DefineBitsJpeg2Tag)
                                  {
                                      DefineBitsJpeg2Tag jpegTag = curTag.Current as DefineBitsJpeg2Tag;
                                      MemoryStream pngImageStream = new MemoryStream();
                                      Image curImage = jpegTag.DecompileToImage();
                                      curImage.Save(pngImageStream, ImageFormat.Bmp);
              
                                      Image pngImage = Image.FromStream(pngImageStream);
              
                                      pngImageStream.Close();
              
              
                                      Console.WriteLine("Found JPEG!");
                                      Console.WriteLine("Image width: " + curImage.Width);
                                      Console.WriteLine("Image height: " + curImage.Height);
              
              
                                      DefineBitsLossLessTag losslessTag = DefineBitsLossLessTag.FromImage(jpegTag.CharacterId,pngImage);
                                      modifiedSwf.Tags.Add(losslessTag);
                                  }
                                  else
                                  {
                                      modifiedSwf.Tags.Add(curTag.Current as BaseTag);
                                  }
                              }
              
                              swfWriter.Write(modifiedSwf);
              
                              swfWriter.Close();
              
                              swfReader.Close();
              
              
              
                          }
                          else
                          {
                              Console.WriteLine("Please supply a SWF on the command line! ");
                          }
              
                          Console.WriteLine();
                          Console.WriteLine();
                          Console.Write("Press any key to continue...");
                          Console.ReadKey();
                      }
                  }

              Still has a ways to go, but it is progress . The logic is the follows:

              1. Open an SWF file that we want to convert and iterate all of the tags.
              2. If we find a JPEG tag then we want to convert that to a lossless tag. (I still need to test and add alpha transparency stuff also).
              3. Otherwise for all other tags we simply want to readd them to the output swf.
              4. Save the newly converted SWF.
              5. Profit!

              And yes... I know none of this is obvious, it is a good bit of work, and I am more than likely insane... but! It is an interesting challenge .

              Comment


                #22
                This is great stuff you are doing for the community Donald. Your name shall be remembered!!

                Comment


                  #23
                  Thank you Matt .

                  So I have actually achieved a working build of my software tool! The only downside is I had to do a drastic change to the SWF library I was using to force it to work correctly. Essentially I discovered a serious bug in the SwfDotNet library I was using that was creating corrupted SWF files for the GfxExporter tool. I solved it by only focusing on the Jpeg2 tag and simply re-exporting the rest, however I would like to get the library to work correctly. One big issue is that the library I am using was never meant to work with version 8 of the SWF file format, and I have spent days updating the library.

                  In the mean time I am prepared to launch the alpha version of my conversion tool by tomorrow. I apologize for the delay but there were a lot of technical issues I had to solve. For instance I now know that the image data of a lossless tag needs to be premultiplied by the alpha channel value! It is not an easy task (for instance the alpha channel data was zlib compressed so I had to decompress it to be able to use it. Figuring out the right way and then adding the alpha channel to the converted image was a pain!).

                  The tool does work and I just need to pop it up on my website and do a brief writeup as to how to use it. I will update the tool once I fix the bug in the library I am using, but that way it is up as quick as possible for anyone wanting to use it.

                  Comment


                    #24
                    I am proud to announce an early release of SWFMakeLossless!

                    Here is the link: http://twisted-pantheon.com/SWFMakeLossless.zip

                    It is a very simple command line utility. You can simply drag the SWF you want to convert on to the exe and it will produce an SWF with an added _Lossless in the same folder. Optionally you could specify in FlashDevelop to use the tool as a prebuild command and then inject your code into the lossless swf file (What I do).

                    So here is the new toolchain:

                    Make your content in Vectorian Giotto and save it with the _Dummy name convention. Run your tool through SWFMakeLossless (my tool) and end up with _Dummy_Lossless. Then inject your code using FlashDevelop on the _Dummy_Lossless file.

                    Download the Example project!

                    Here is a screenshot of it working in UDK:



                    and my Vectorian image settings:



                    .

                    Note: There may be bugs. Keep in mind that I developed this tool from scratch myself. If you find bugs or it doesn't work then please let me know so I can fix it! Also once it gets more stable I can give a release build (this is a debug build for testing purposes). Also eventually I will share the source code. The only reason I don't is that the tool makes use of a library that I have edited substantially and I want to do more testing and developing before I share both. If you must have the source code now then please contact me via PM and I can try to arrange it.

                    Here is part of the conversion code though (so you can see part of what it does behind the scenes):
                    Code:
                                            RGBA[] colorInfo = new RGBA[pngBitmap.Width * pngBitmap.Height];
                    
                                            BitmapData buffer = pngBitmap.LockBits(new Rectangle(0, 0, pngBitmap.Width, pngBitmap.Height), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
                    
                                            int pixelSize = 3;
                    
                                            for (int y = 0; y < pngBitmap.Height; y++)
                                            {
                    
                                                for (int x = 0; x < pngBitmap.Width; x++)
                                                {
                                                    byte a = alphaData[y * pngBitmap.Width + x];
                    
                                                    byte b = (byte)(Marshal.ReadByte(buffer.Scan0, (buffer.Stride * y) + (pixelSize * x)));
                                                    byte g = (byte)(Marshal.ReadByte(buffer.Scan0, (buffer.Stride * y) + (pixelSize * x) + 1));
                                                    byte r = (byte)(Marshal.ReadByte(buffer.Scan0, (buffer.Stride * y) + (pixelSize * x) + 2));
                                                    
                    
                                                    double fa = a / 255.0;
                                                    b = (byte)(((b / 255.0) * fa) * 255.0);
                                                    g = (byte)(((g / 255.0) * fa) * 255.0);
                                                    r = (byte)(((r / 255.0) * fa) * 255.0);
                    
                                                    Marshal.WriteByte(buffer.Scan0, (buffer.Stride * y) + (pixelSize * x), b);
                                                    Marshal.WriteByte(buffer.Scan0, (buffer.Stride * y) + (pixelSize * x) + 1, g);
                                                    Marshal.WriteByte(buffer.Scan0, (buffer.Stride * y) + (pixelSize * x) + 2, r);
                    
                                                    colorInfo[x + y * pngBitmap.Width] = new RGBA(r, g, b, a);
                    
                    
                                                }
                                            }
                    
                                            pngBitmap.UnlockBits(buffer);
                    BTW: It uses the .NET 3.5 framework. If you don't have it then you need to download it: http://www.microsoft.com/download/en...ylang=en&id=21 I think you can get it from there.

                    Also stay tuned! I am looking at adding some very unique features to this tool. The first is that if we already have a folder of lossless assets in the same folder as the SWF, why should we need to convert pixels of a jpeg image and risk artifacts? Instead an update to my tool is going to allow you to specify an optional folder of the lossless assets and if it finds one with the same name as the asset it is trying to convert, then it will use that one instead! Also I am going to research the potential to add pixel shader processing during the image conversion step (after we get the image from the jpeg or the file) so if say you want to convert all of the images to greyscale you will be able to supply a pixel shader on the command line arguments to do that (maybe if I can figure out a way to make it work).

                    EDIT: Pixel shader support does look possible but it would probably require the end user to get the DirectX SDK in order to have the shader compilation tool (which I would have to invoke as a process probably). Either that... or force the use of compiled shaders, but they would need to be written a certain way to work with my program. If there is interest perhaps I will be able to add this feature but I would like to hear from people if such a feature is even desirable. I think it would be cool, but not if it potentially alienates people who need to use the tool. It would also require the use of WPF (Windows Presentation Foundation).

                    Comment


                      #25
                      Nice! I've added a link to this forum post (the one about your tool) in the User Created Tools section at the bottom of the Getting Started sticky forum post.

                      Comment


                        #26
                        Hi,

                        First of all THANK YOU for opening this awesome possibility for us with this tutorial

                        But is there another way to use the menu, instead of fscommands?
                        I took a look at this tutorial http://www.youtube.com/watch?v=_iP4tRf3060 but I think the clik widgets are specially for the scaleform gui and I cannot access a simple textfield from Vectorian Giotto with them.

                        Now I do have to say I have absolutly no knowledge of Flash or Actionscript, and up to this point I never considered it because of the high price. Now I would like to know if (and how) I can use it with unrealscript before really investing time to learn it.

                        greetings

                        Comment


                          #27
                          Everything you need to know about using Flash/AS with UnrealScript can be found here:

                          http://forums.epicgames.com/showthread.php?t=743567

                          Also, check out the sample UI UnrealScript files in the dev folder.

                          Comment


                            #28
                            Thanks, I fixed it. It is still complaining about not finding the font, but I think I can figure that out myself.

                            However, it seems the WidgetInitialized event is not being called. I put a `Log("Test") in there but there is no output in the console. So I cannot use the buttons :/

                            Code:
                            class MainMenu extends GFxMoviePlayer;
                            
                            var GFxClikWidget StartButton;
                            var GFxObject MainMenuTitle;
                            
                            function bool Start(optional bool StartPaused = false)
                            {
                            	super.Start();
                            	Advance(0);
                            	
                            	MainMenuTitle = GetVariableObject("_root.MainTitle");
                            	MainMenuTitle.SetText("very long test text");
                            	
                            	return true;
                            }
                            
                            event bool WidgetInitialized(name WidgetName, name WidgetPAth, GFxObject Widget)
                            {
                            	`Log("Test");
                            	switch(WidgetName)
                            	{
                            		case('playBtn'):
                            			StartButton = GFxClikWidget(Widget);
                            			StartButton.AddEventListener('CLIK_press', OnStartButtonPress);
                            			break;
                            		default:
                            			break;
                            	}
                            	return true;
                            }
                            
                            function OnStartButtonPress(GFxClikWidget.EventData ev)
                            {
                            	ConsoleCommand("open DM-Deck");
                            }
                            
                            defaultproperties
                            {
                            	WidgetBindings.Add((WidgetName="playBtn",WidgetClass=class'GFxClikWidget'))
                            }
                            greetings

                            Comment


                              #29
                              I fixed the font issue: In Vectorian Giotto you have to select your textfield an click the "Embed..." button in the properties panel. Then simply select the characters you need.

                              The play game button is still not working.

                              Also I tried implementing images and converted the swf with DonaldM's tool but it gives me a corrupted swf (That is what flash devlop says when it fails to compile). I cannot play the converted flash, it stays black. I use Win 7 64bit, might that be a problem?

                              greetings

                              Comment


                                #30
                                Ok, after a long search how to use regular flash buttons with udk I found this thread: http://forums.epicgames.com/showthread.php?t=756460
                                After doing that I remembered reading about ExternalInterfaces in the Getting Started links, but they never explicitly stated it for buttons (I admit I haven't read all of them thoroughly). One of the topics used delegates but apparently those would not work with FlashDevelop.
                                Nevertheless I now use ExternalInterface to call UnrealScript functions and it works

                                As for the SWFMakeLossless: I don't know why, but using the provided menu sample from the tutorial it works, no matter what image I insert into the document. However, using my menu, which I created following the tutorial, it does not work with any image, not even with the sample mouse cursur image.
                                I already redid the tutorial but it did not work either. I also tried to find differences between my menu and the tutorial files, but was unsuccessful. I will continue to search for the error and in case I can't find it I will just use the tutorial files and build my menu on top

                                greetings

                                Comment

                                Working...
                                X