Showing posts with label Alchemy. Show all posts
Showing posts with label Alchemy. Show all posts

Tuesday, December 4, 2012

Introducing Game Developer Tools

I am really excited about what happened tonight. We just announced the introduction of the Adobe Game Developer Tools on Creative Cloud. You can read the official announcement here. As part of this, we are introducing three new products: Adobe Gaming SDK, FlasCC and Adobe Scout, which I have been working on for a year now. Here is a video about Adobe Scout and why it is going to change everything for your as a developer: I wrote a full article on how to get started with Scout. Make sure you check it out! If you have any questions, check the Scout forums! If you want to take a deep dive in Scout you can also check the video tutorials here. We also wanted to provide a great out of the box experience for developers to get started with the stack. Provide a nice package that allowa developers to get up and running quickly without having to hunt for the frameworks needed, the compilers and right documentation. That's why we are also introducing the Gaming SDK: The Gaming SDK contains the key frameworks you guys need to use to create fast performing 2D and 3D GPU games, but also much more, from the ATF tools to iOS ANEs. Starling, Feathers and Away3D are officially supported by Adobe and part of the Gaming SDK. It provides to you a one stop shop package to get started with the technology, we hope you guys will enjoy it! For those of you guys doing native development and interested in porting native games to the desktop, you can now use FlasCC (formerly named Alchemy), which is now release quality and supported.

Read more: Introducing Game Developer Tools

Tuesday, November 27, 2012

Using GDB script files with the FlasCC GDB

The Flash C++ Compiler (FlasCC) provides a complete BSD-like C/C++ development environment based on GCC that lets you compile your C/C++ code to target the Adobe® Flash® Runtime (Flash Player and AIR®). With FlasCC you can port almost any existing C/C++ code to the web, across browsers. FlasCC includes tools for building, testing, and debugging C/C++ projects, example projects with source code, and documentation. You can get FlasCC today on the http://gaming.adobe.com/technologies/flascc/ page.
Today I want to share a quick FlasCC debugging tip. The FlasCC based gdb tool is located in the FlasCC download under sdk/usr/bin/gdb (Mac) or sdk/usr/bin/gdb.exe (Win/Cygwin).
Before trying this out we need a simple C app to debug. Go ahead and create a file called test.c and put the following code inside:
C:
#include <stdio.h>
int main(int argc, char **argv)
{
    int i = 0;
    printf("Hello World %d Time\n", i++);
    printf("Hello World %d Time\n", i++);
}
And the command to compile the debug SWF with FlasCC is:
CODE:
sdk/usr/bin/gcc -g test.c -emit-swf -o test.swf
The FlasCC gdb relies on an environmental variable called FLASCC_GDB_RUNTIME, if you do not set it before running gdb you'll see the following message inside of the gdb prompt:
CODE:
(gdb) run
Starting program: hello.swf
Please set the FLASCC_GDB_RUNTIME environment variable to the path to a debugger player or browser.
The FLASCC_GDB_RUNTIME needs to be set to the standalone debug Flash Player or to a browser that has a debug Flash Player. I recommend for the first time that you try using the FlasCC gdb to download a standalone debug Flash Player from here and us it. I downloaded the Mac version and put in a folder called /Code, which means I would run this command in Ternimal before I call gdb:
CODE:
export FLASCC_GDB_RUNTIME=/Code/Flash\ Player\ Debugger.app
Lets take a look at my command line to see how to put this all together:
CODE:
renaun$ sdk/usr/bin/gcc -g test.c -emit-swf -o test.swf
renaun$ export FLASCC_GDB_RUNTIME=/Code/Flash\ Player\ Debugger.app
renaun$ sdk/usr/bin/gdb test.swf
GNU gdb (GDB) 7.3
Copyright (C) 2011 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "--host=x86_64-apple-darwin10 --target=avm2-elf".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>...
(gdb) b main
No symbol table is loaded.  Use the "file" command.
Make breakpoint pending on future shared library load? (y or [n]) y
Breakpoint 1 (main) pending.
(gdb) run
Starting program: test.swf
0xdddddddd in ?? ()
Breakpoint 1, 0xf0000051 in main (argc=0, argv=0x200ff0) at test.c:5
5       int i = 0;
(gdb)
So I setup export to the debug Flash Player and then ran the gdb against the SWF. But once in side the gdb command prompt I still need to setup a break point. When trying to setup a break point before starting the SWF it will display another warning which needs a yes response. After responding with a yes I can then type run.
Here is the trick, by using gdb -x script.txt we can run it all in one command. Instead of having to type in my break point each time or responding yes. This is how it works, create a script.txt file and put in the following gdb commands:
CODE:
set breakpoint pending on
b main
r
The first line sets the default warning option to be yes so you dont have to worry about it not being set. The second command sets a break point at the main function. And the last command runs the gdb, telling it to start. The command to use the gdb script is below:
CODE:
renaun$ sdk/usr/bin/gdb -x script.txt test.swf
Another handy command to put in script.txt is the set as3namespace com.renaun.test command. This is needed if you create a FlasCC SWC with a custom namespace.

© %FIRST Erickson - visit the <renaun.com:flexblog text="{ ModelLocator.myThoughts }"/>


Read more: Using GDB script files with the FlasCC GDB

Wednesday, March 28, 2012

Quick comments about Unity and premium features

I’m sitting at the Seattle airport at the moment but I just wanted to clarify a couple of things about the announcements we made last night. Firstly we announced that we now have a partnership in place with Unity. Our teams working together will make their Flash export feature even better in the future. Big shout out to Ralph and the Unity for their awesome work on it!
The second thing we announced is a new premium feature model for the desktop browser runtime. This model is there to allow Adobe to make revenue from large, web-based Flash games like the ones that we expect to come out of Unity and other tools. Building a real game platform means that we have to be able to make revenue to fund its development. When talking with game companies at GDC, most prefer this model because they are much more confident about deploying to a platform that we are actively making money from.
So in a nutshell this is what the premium features mean. If you create a game that uses Stage3D GPU AND uses the Alchemy opcodes then you will need to get a license key from Adobe. Then if your game makes over $50,000 in revenue, your game will subject to a 9% revenue share that you will pay to Adobe. This does not apply at all to Adobe AIR. So you can use Stage3D and the opcodes as much as you want with no license. I have seen a lot of chatter online basically saying that people will have to pay a cut to Adobe in addition to the cut Apple and Google take. This is completely false. There is NO licensing needed when deploying to mobile.
I know there are a tons of edge cases here surrounding the use of the opcodes and I will be writing more in-depth about them very soon. Read through the two links below to get more details.
Premium features overview
Premium features FAQ
Read more: Quick comments about Unity and premium features

Thursday, March 24, 2011

Alchemy Series Part 5: Revenge of the Thiz

Alchemy Series Part 5: Revenge of the Thiz:

This episode is a bit of a catch all for some other random things that we wanted to cover in this series. The hope is, by the time you are done reading this post (along with the last 4) you will be able to start build swcs of other libraries, or even creating your own directly in C. If this ends up being the case, please let us know, we would love to see what you guys make! Anywho, on with the show…

For any of this to make sense, you will probably want to follow along with the code in the example which you can download here:
Example Source

Multiple File Compilation and Linking
While doing my own research on Alchemy, I came across many a forum post asking about compiling and linking C libraries that were comprised of multiple files, as most are. So this week’s example has been split up into multiple files to try and demonstrate the process. In the alchemy folder bundled with the example code, this is a folder called “lib”. In there is a couple of C files and a few Bash scripts. For the purpose of this example, we are going to consider this our Library. In order get our library compiled and ready to link with our Alchemy wrapper we have to complete a few intermediate steps.

The first step is to compile each of the .c files individually and create .o (object) files from them. These object files are what is linked together in the end to create the swc. Since most C libraries out there have lots of files, its probabaly most convenient to create a bash script to handle the compile. In our case its the “compilelib.sh” file.

#!/bin/bash
optLevel=3
 
gcc -I../include -I./ -Wall -O$optLevel -c loopstart.c
gcc -I../include -I./ -Wall -O$optLevel -c cancelstate.c

The first line should look familiar to you from previous posts, but just in case you missed it, it simply tells cygwin to interpret this script with the “bash” shell located at “/bin/bash”. Next we create a variable to make it easy to alter some compile settings without having to edit each line individually. Then we have the now familiar “gcc” calls. The “-I” switches tell gcc to add these folders to its search path when looking for files and definitions, such as (.h) header files. In this case we are telling it to look in the “include” folder one level up, and to also look in its own folder. The “include” folder has our “alcexample.h” file which contains the declarations for our library functions and data structures. The -Wall tells gcc to report all types of warnings while compiling. -O is the compiler optimization setting. At one point I thought the optimization was messing with Alchemy, I was wrong. But I figured it would be good to suggest leaving the variable in there as an example. You could probably do the whole include bit with a var too. Lastly “-c” tells gcc to not run the linker, and just save out the object file. Once those files have been compiled into object files, we need to archive the library together into one file. Thus the “arclib.sh” script:

#!/bin/bash
ar csr exampleLib.a loopstart.o cancelstate.o

To build the archive we use the “ar” program. The command line settings break down like this:
c – create the archive
s – this creates an object file index in the archive which “allows routines in the library to call each other without regard to their placement in the archive” (from ranlib docs)
r – inserts the object file into the archive and replaces duplicates instead of appending

Lastly we feed it the name we want the archive to be called and a list of object files we want included.

At this point we have the library built and archived ready for use in our Alchemy wrapper. So if you pop up one folder level you will see our main Alchemy file, alcexample.c, as well as another Bash script that will finish our build called “compileandlink.sh”:

#!/bin/bash
gcc -I./include -L./lib -lexampleLib -Wall alcexample.c -swc -O3 -o alcexample.swc

This looks very similar to our “compilelib.sh” script, with a couple of notable exceptions. This time we are using the “-L” switch to add a library path to the gcc search path. We then follow that with a “-l” switch and the name of our library. The “-c” has also been replaced by a “-o” and a “-swc”. Which means that gcc will now link the project and create your brand new .swc file :)

So, basically the moral of the story is to build a multi-file library, it takes three steps:
1) Basic library compile to object files
2) Archiving of the .o files to a single archive file (with indicies)
3) Final compile and link

Great, now that we can compile the example, lets jump back into looking at code.

Bound States
So a few posts ago, I had mentioned that the first parameter for the AS3_Function() call was usually NULL, and I at the time didn’t know why. Well, its been figured out :) You can replace this NULL with a pointer to some data of whatever kind you like. This can be a handy shortcut so you don’t have to continuously pass in the pointer address from flash to your function calls when you want to access data within the C code. If you take a look at the alcexample.c file and head down to main(), you will see it looks much like the rest of the examples. However instead of passing NULL into our AS3_Functions we are now passing a pointer to a struct[...]

Wednesday, March 16, 2011

Alchemy Series Part 4: D is for Data Manipulation

Alchemy Series Part 4: D is for Data Manipulation:

So far, we’ve gone though getting the environment setup, basic compilation and implementation of alchemy into a swf, and the standard Hello World example. So what next you ask? Well I answer with “More Contrived Examples!” Sadly its tough to make examples that don’t feel totally contrived, while also making those examples easy to understand while staying on point. Kind of like the old racing adage, “Cheap, Fast, Reliable, pick any two”. So I picked easy to understand and on point. Which means we are still in the land of contrived examples, and for that I apologize. Either way, on with the contrivedness! :)

The Example can be Downloaded Here.

This example is broken up into three different parts. The first deals with basic object creation and return, the second, deals with ByteArrays as file streams in C (I promise that is super useful), and finally the third is keeping data stored in C as a way of keeping state internal to your library.

So if you run the supplied example inside of the Flash CS5 IDE or from FlashDevelop/Builder, or something that watches for traces, you will see this:

– Start Basic Data Example –
(ALC) Text: Test Text
(ALC) Int: 15
(ALC) Number: 3.141592
(ALC) AS3 Obj Text: Hawt String
(ALC) AS3 Obj Int: 42
Obj: Test Text
Obj: 15
Obj: 3.141592

– Start ByteArrays as Streams Example –
In Bytes Length: 10000
>Out Bytes Length Before: 0
(ALC) Bytes Read 1024
(ALC) Bytes Written 1024
(ALC) Bytes Read 2048
(ALC) Bytes Written 2048
(ALC) Bytes Read 3072
(ALC) Bytes Written 3072
(ALC) Bytes Read 4096
(ALC) Bytes Written 4096
(ALC) Bytes Read 5120
(ALC) Bytes Written 5120
(ALC) Bytes Read 6144
(ALC) Bytes Written 6144
(ALC) Bytes Read 7168
(ALC) Bytes Written 7168
(ALC) Bytes Read 8192
(ALC) Bytes Written 8192
(ALC) Bytes Read 9216
(ALC) Bytes Written 9216
(ALC) Bytes Read 10000
(ALC) Bytes Written 10000
>Out Bytes Length After: 10000

– Start Image Data Example –
Length: 40000
Memory address for RED image: 1069136
Length: 10000
Memory address for GREEN image: 1069152

You will also see a Red square with a translucent and smaller Green square on top of it. Epic exciting I know, but the behind the scenes bits are pretty awesome if you ask me :) First up, basic data handling example.

Data in, Data out
At this point, I’m assuming you have worked your way through the Part 3 post, and are fairly comfortable compiling things, and working with that compiled swc in flash. But I do want to point out some changes in the main() function of this example.

//Virtual Function (thunk) maps
AS3_Val showArgsMethod = AS3_Function(NULL, showArgs);
AS3_Val storeImageBytesMethod = AS3_Function(NULL, storeImageBytes);
AS3_Val adjustAlphaMethod = AS3_Function(NULL, adjustAlpha);
AS3_Val getImageBytesMethod = AS3_Function(NULL, getImageBytes);
AS3_Val freeImageBytesMethod = AS3_Function(NULL, freeImageBytes);
AS3_Val copyBytesMethod = AS3_Function(NULL, copyBytes);

The first bit is still the same. We declare and define an AS3_Function thunk for each of the function we want to expose and map that to the actual internal C function. So far so standard.

The next line you’ve seen before as well

//Bundle up the thunks into an AS3 Object.  This object is what flash sees
//after you call init() on the loaded Alchemy loader.
AS3_Val flashObj = AS3_Object("showArgs:AS3ValType, copyBytes:AS3ValType", showArgsMethod, copyBytesMethod);

This, as before, creates an AS3 Object that will hold the mappings to our internal functions. This is how those functions are accessed from ActionScript. You also pass in a Type Template pattern as a string, and then references to the thunks. Still pretty normal. However you will notice that we’ve defined six functions, but have only included two in our AS3 Object. If we put all six in there, the line starts to get very unwieldy. So we can use the AS3_SetS() function to attach more properties/functions to our AS3 Object.

AS3_SetS(flashObj, "storeImageBytes", storeImageBytesMethod);
AS3_SetS(flashObj, "adjustAlpha", adjustAlphaMethod);
AS3_SetS(flashObj, "getImageBytes", getImageBytesMethod);
AS3_SetS(flashObj, "freeImageBytes", freeImageBytesMethod);

AS3_SetS() allows use to add properties by name and set their inial value. The first parameter is the object we want to add our properties to. The second is a (constant) char* list of characters that is the name of our property. Lastly we pass in the initial value of that property. In this case, we are passing in the thunks we made to expose out C functions with. That is the first bit of data management in the first example. Setting properties at runtime to AS3 Objects. Remember this is a “real” AS3 Object, so it can be returned to Flash and used directly.

This concept is more obviously implemented in the showArgs() C function. This function serves no purpose other than to demonstrate a few different ways of dealing with basic data. From Flash we do this: [...]