The book of inspiration

April 6, 2009

C# To ActionScript and Alchemy

Filed under: jsc — Tags: , , , — zproxy @ 7:14 pm

Some years ago I added some minimal C source code generation support to my jsc compiler. This time I decided to polish it up a little bit and see what would it look like to develop a flash application with alchemy in c#.

This example is a port from this Alchemy plasma experiment. I made it in c#, changed the color and added the jsc logo.

Overview

Writing code in c#? That’s plain crazy. To make it easier to comprehend – here is an overview diagram of what is really happening.

flashalchemy1

Hand written C# sourcecode

As you can see, there are multiple compilers doing the hard work so you could have that final flash binary file. The C# code that will be converted by jsc compiler looks like this:

   14 static int width;
   15     static int height;
   16
   17     static uint[] palette;
   18     static uint[] plasma;
   19     static uint[] newPlasma;
   20
   21
   22     static AS3_Val generatePlasma(object self, AS3_Val args)
   23     {
   24       AS3_h.AS3_ArrayValue(args, "IntType, IntType", __arglist(ref width, ref height));
   25
   26       palette = new uint[256];
   27       plasma = new uint[width * height];
   28       newPlasma = new uint[width * height];
   29
   30       for (var x = 0; x < 256; x++)
   31       {
   32         var b = (int)(128.0 + 128 * Math.Sin(Math.PI * x / 16.0));
   33         var g = (int)(128.0 + 128 * Math.Sin(Math.PI * x / 128.0));
   34         var r = 0;
   35
   36         uint color = (uint)(r << 16 | g << 8 | b);
   37
   38         color |= 0xff000000u;
   39
   40         palette[x] = color;
   41       }
   42
   43       int index = 0;
   44
   45       for (var x = 0; x < width; x++)
   46       {
   47         for (var y = 0; y < height; y++)
   48         {
   49           uint color = (uint)((
   50             128.0 + (128.0 * Math.Sin(x / 16.0)) +
   51             128.0 + (128.0 * Math.Sin(y / 8.0)) +
   52             128.0 + (128.0 * Math.Sin((x + y) / 16.0)) +
   53             128.0 + (128.0 * Math.Sin(math_h.sqrt(x * x + y * y) / 8.0))
   54           ) / 4);
   55
   56
   57           color |= 0xff000000u;
   58
   59           plasma[index++] = color;
   60         }
   61       }
   62
   63
   64       return AS3_h.AS3_Ptr(plasma);
   65     }
   66
   67     static AS3_Val shiftPlasma(object self, AS3_Val args)
   68     {
   69       var shift = 0;
   70       var index = 0;
   71
   72       AS3_h.AS3_ArrayValue(args, "IntType", __arglist( ref shift));
   73
   74       for (var x = 0; x < width; x++)
   75       {
   76         for (var y = 0; y < height; y++)
   77         {
   78           var paletteIndex = (int)( (uint)(plasma[index] + shift) % 256);
   79           newPlasma[index] = palette[paletteIndex];
   80           index++;
   81         }
   82       }
   83
   84       return AS3_h.AS3_Ptr(newPlasma);
   85     }

Generated C source code for Alchemy

After jsc compiler has converted it to asni c it will look like this:

   30
   31 int FlashPlasma_Alchemy_Program_width;
   32 int FlashPlasma_Alchemy_Program_height;
   33 unsigned int* FlashPlasma_Alchemy_Program_palette;
   34 unsigned int* FlashPlasma_Alchemy_Program_plasma;
   35 unsigned int* FlashPlasma_Alchemy_Program_newPlasma;
   36
   37 AS3_Val FlashPlasma_Alchemy_Program_generatePlasma(void* self, AS3_Val args)
   38 {
   39     int x;
   40     int b;
   41     int g;
   42     int r;
   43     unsigned int color;
   44     int index;
   45     int y;
   46
   47     AS3_ArrayValue((AS3_Val)args, (char*)"IntType, IntType", &FlashPlasma_Alchemy_Program_width, &FlashPlasma_Alchemy_Program_height);
   48     FlashPlasma_Alchemy_Program_palette = (unsigned int*) malloc(sizeof(unsigned int) * 256);
   49     FlashPlasma_Alchemy_Program_plasma = (unsigned int*) malloc(sizeof(unsigned int) * (FlashPlasma_Alchemy_Program_width * FlashPlasma_Alchemy_Program_height));
   50     FlashPlasma_Alchemy_Program_newPlasma = (unsigned int*) malloc(sizeof(unsigned int) * (FlashPlasma_Alchemy_Program_width * FlashPlasma_Alchemy_Program_height));
   51
   52     for (x = ((int)0); (x < 256); x++)
   53     {
   54         b = ((int)((signed int)((128 + (128 * FlashPlasma_Alchemy_BCLImplementation_System___Math_Sin((double)((3.14159265358979 * ((double)(x))) / 16)))))));
   55         g = ((int)((signed int)((128 + (128 * FlashPlasma_Alchemy_BCLImplementation_System___Math_Sin((double)((3.14159265358979 * ((double)(x))) / 128)))))));
   56         r = ((int)0);
   57         color = ((unsigned int)(((r << 16) | (g << 8)) | b));
   58         color = ((unsigned int)(color | -16777216));
   59         FlashPlasma_Alchemy_Program_palette[x] = color;
   60     }
   61
   62     index = ((int)0);
   63
   64     for (x = ((int)0); (x < FlashPlasma_Alchemy_Program_width); x++)
   65     {
   66
   67         for (y = ((int)0); (y < FlashPlasma_Alchemy_Program_height); y++)
   68         {
   69             color = ((unsigned int)((unsigned int)(((((((((128 + (128 * FlashPlasma_Alchemy_BCLImplementation_System___Math_Sin((double)(((double)(x)) / 16)))) + 128) + (128 * FlashPlasma_Alchemy_BCLImplementation_System___Math_Sin((double)(((double)(y)) / 8)))) + 128) + (128 * FlashPlasma_Alchemy_BCLImplementation_System___Math_Sin((double)(((double)((x + y))) / 16)))) + 128) + (128 * FlashPlasma_Alchemy_BCLImplementation_System___Math_Sin((double)(sqrt((double)((double)(((x * x) + (y * y))))) / 8)))) / 4))));
   70             color = ((unsigned int)(color | -16777216));
   71             FlashPlasma_Alchemy_Program_plasma[index++] = color;
   72         }
   73
   74     }
   75
   76     return  (AS3_Val)AS3_Ptr((void*)FlashPlasma_Alchemy_Program_plasma);
   77 }
   78
   79 AS3_Val FlashPlasma_Alchemy_Program_shiftPlasma(void* self, AS3_Val args)
   80 {
   81     int shift;
   82     int index;
   83     int x;
   84     int y;
   85     int paletteIndex;
   86
   87     shift = ((int)0);
   88     index = ((int)0);
   89     AS3_ArrayValue((AS3_Val)args, (char*)"IntType", &shift);
   90
   91     for (x = ((int)0); (x < FlashPlasma_Alchemy_Program_width); x++)
   92     {
   93
   94         for (y = ((int)0); (y < FlashPlasma_Alchemy_Program_height); y++)
   95         {
   96             paletteIndex = ((int)(((unsigned int)((((unsigned long)(FlashPlasma_Alchemy_Program_plasma[index])) + ((signed long)(shift))))) % 256));
   97             FlashPlasma_Alchemy_Program_newPlasma[index] = FlashPlasma_Alchemy_Program_palette[paletteIndex];
   98             index++;
   99         }
  100
  101     }
  102
  103     return  (AS3_Val)AS3_Ptr((void*)FlashPlasma_Alchemy_Program_newPlasma);
  104 }

Generated ActionScript by Alchemy

Now that was the basic ansi C source code. Alchemy will convert it to special actionscript which will look like good old assambler:

 9002 i0 =  ((__xasm<int>(push((mstate.ebp+8)), op(0x37))))
 9003 i1 =  ((__xasm<int>(push((mstate.ebp+12)), op(0x37))))
 9004 i2 =  ((__xasm<int>(push((i0+16)), op(0x37))))
 9005 i3 =  ((__xasm<int>(push((i1+16)), op(0x37))))

Summary

At this time it is quite hard to set up such an environment due to cygwin quirks, but it does enable some interesting scenarios. If you would like to know more about writing for flash alchemy in C# just let me know.

7 Comments

  1. very intersting.
    What r possibilities of yr C# -> C translator?
    p.s.: i hate cygwin oldschool env. 🙂
    p.s.: Flash vs SilverLight…what about union? 🙂

    Comment by Alexander [spb[ru]] — April 19, 2009 @ 1:39 am

  2. Hi Alex,

    The first possibility is, with some additional effort, you could debug your alchemy code right inside your .net application. Later when you are done it would be converted and run on flash.

    It’s actually funny as I am a C# dev, but I have not touched silverlight after 1.0 alpha release.

    Due to the fact flash has a monetization story and silverlight as of yet not, I have not yet tried to make the silverlight and flash union you suggested, but once the monetization is there I will probably do it.

    Maybe you are looking for a more detailed anwser, if so let me know what’s interesting you.

    Comment by zproxy — April 19, 2009 @ 11:18 am

  3. […] by old school MS DOS demos and this Flash Alchemy experiment.. Found out that someone already ported some code from the Alchemy experiment to C#. So after some tweaking and some help of […]

    Pingback by Silverlight 3 Writable Bitmap API - Plasma « lab101 — June 4, 2009 @ 7:13 am

  4. Damn that’s really a crazy idea to write C# code and ported it to C for Alchemy.
    Just letting you know that I used your handwritten C# code to use it in Silverlight.

    Cheers

    Comment by Kris Meeusen — June 4, 2009 @ 8:27 am

  5. Hi Alex, so you mean you can debug your c# code written for flex ? can you write more about this ?? thanks a lot

    Comment by Matteo — July 3, 2009 @ 6:42 pm

  6. Matteo, you can implement your application using subset of WPF which then will run on .net and on flash. If you talk directly to flex api you cannot debug them on .net as their implementation is not defined outside flash player at this time.

    See here: https://zproxy.wordpress.com/2009/06/09/bcl-implemented-by-java-api-vs-java-api-implemented-by-bcl/

    Comment by zproxy — July 7, 2009 @ 7:03 am

  7. Fantastic issues altogether, you simply received a brand new reader. What could you suggest about your post that you just made a few days ago? Any positive?

    Comment by Hacked Games — November 26, 2011 @ 1:04 pm


RSS feed for comments on this post.

Sorry, the comment form is closed at this time.

Blog at WordPress.com.