Best articles on Flash Development and Software Design
Tuesday, December 4, 2012
Introducing Game Developer Tools
Read more: Introducing Game Developer Tools
Tuesday, November 27, 2012
Using GDB script files with the FlasCC GDB
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:
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:Starting program: hello.swf
Please set the FLASCC_GDB_RUNTIME environment variable to the path to a debugger player or browser.
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: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)
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:b main
r
gdb, telling it to start. The command to use the gdb script is below:set as3namespace com.renaun.test command. This is needed if you create a FlasCC SWC with a custom namespace.Read more: Using GDB script files with the FlasCC GDB
Wednesday, March 28, 2012
Quick comments about Unity and premium features
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
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
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: [...]