Doing OpenGL?? C++ now? Wait Linux again…?

It’s been a while since I last played with Linux, I was using Linux Mint. Now I’m using Pop_OS! (based on Ubuntu) since it has support for Nvidia graphic cards. Also I was bored of Windows again.

There we go, with our good old friend Fireworks 8, from 2005! Best design program I’ve ever used.

I have been interested in learning C++ since 2016. I was just too busy messing with ActionScript and Haxe (OpenFL) in my free time. What a better way to learn a language than making a game with it (may be unfinished but a game definitely).

The first thing I did was head out to https://learnopengl.com/ and follow the Introduction, and then the Getting Started section. Being honest, it’s a lot to grasp. But just be patient with yourself and read the lessons more than once, that’s what worked for me because I have bad memory.

On top of that, I wanted to work on Pop OS, and because I chose VScode I had to make the required configuration (IntelliJ does that for you, I mean CLion. I really recommend it for C++, much better than VSCode for that language).

Coming from Windows, setting up VSCode with C++ for OpenGL with CMake on Pop OS! was a lot for me. But in the end I cracked the code. The repo here has CMake ready and contains some instructions on how to install some of dependencies (“glad” is also a dependency mentioned there but it is already included in the repo files). Also make sure to have CMake installed (along with the VSCode extensions for Cmake and C++).

The project has a very basic configuration and has flaws, specially because you need to manually copy the shader and image asset files to the build folder (once that it has been generated after clicking build). But guess what, it works!

You’re a box now, you’re a squid now.

This took me a while to figure out, because it’s a different OS and a different language. Been working on this for 6 months! (whaat), mainly because I have waaaay less free time than I used to, but I built this bit by bit during every small chance that I had. Hope this helps someone someday (that someone could be my future self!).

Edit:

Almost forgot. When working with OpenGL and Windows or Linux, I recommend to use https://renderdoc.org for debugging. It will show you what textures are used, the vertices, fragment shaders

OpenFL with WebSockets

Let’s say you want to use WebSockets into your OpenFL/HaxeFlixel app or game. You can create a server in Node like this:

//Server
const WebSocket = require('ws');

const wss = new WebSocket.Server({ port: 9898 });
wss.on('connection', function connection(ws) {

  ws.on('message', function incoming(message) {
    console.log('received: %s', message);
  });

  ws.send('something from server!');
});

Run it with node server.js (assuming that filename)

Then in your game/app

package;
import openfl.events.Event;
import openfl.events.IOErrorEvent;
import openfl.events.ProgressEvent;
import openfl.events.SecurityErrorEvent;
import openfl.net.Socket;

class PlayState extends FlxState {
  private var socket:Socket;
  
  override public function create() {
    socket = new Socket();

    socket.addEventListener(Event.CONNECT, onSocketConnected);
    socket.addEventListener(ProgressEvent.SOCKET_DATA, onSocketDataReceived);
    socket.addEventListener(Event.CLOSE, onSocketClosed);
    socket.addEventListener(IOErrorEvent.IO_ERROR, onIOErrorHandler);
    socket.addEventListener(SecurityErrorEvent.SECURITY_ERROR, onSecurityErrorHandler);

    socket.connect("http://localhost/", 9898);
   //once connection is done you can call sendMessage('hello from openFL!');
}

 private function onSocketConnected(e:Event):Void {
    trace("Connected!");
  }

private function sendMessage(message:String) {
    socket.writeUTFBytes(message);
    socket.flush();
  }

private function onSocketDataReceived(e:ProgressEvent):Void {
    var bytes:ByteArray = new ByteArray();
    socket.readBytes(bytes);
    if (bytes.length == 0)
      return;

    trace("Got response from server:");
    trace(bytes.readUTFBytes(bytes.bytesAvailable));
  }

//add the other event handlers
}

And that’s it. This enables a two way client-server communication. Cool that something as simple as this gets the job done!

Clarification: this only worked for the HTML5 export. I tried building it with the Windows target (.exe) but there are errors on console.

Package 64-bit apps with AIR SDK 33 for Android

What is this, a Flash article in 2021? When was the last time this blog had a new entry anyway?

Back in 2017 I made a few apps with AIR and published them to Google Play Store. Then Android kept moving forward to the point of you needing to update your apps to be also 64-bit in August 2020. I ignored the notice for a good while, then other notice that from november 2nd 2020 any updates to apps must target sdk version 29. Anyway, took this as achance to use VSCode instead of FlashDevelop in this new Windows 10 fresh install  (FD if you’re reading this I still love you!).

VSCode is amazing, and luckily the ActionScript and MXML extension is really helpful for AS3 projects.

Sweet tasks

The extension can detect .as3proj files (FD’s project configuration) and import the settings to an asconfig.json which is what the extension uses, this also works for Flash Builder projects.

I was so exicted for the extension, everything was going alright until I saw an error while trying to package the apk that said the icons were not found.

bin\Main-app.xml: error 303: Icon icons/MyApp36.png is missing from package

This is because of the .asconfig file. Where the “file” property means the location of the icon image in your project, and the “path” is the location inside the bin folder where that file is going to be copied when you create a build.

Green: location in your project.
Orange: create copy in bin/

So I just set .asconfig so the “file” and “path” are the same. This way the Main-app.xml that has the icon declaration will correctly point to the files.

Just keeping the same format.

Then review also in the src/Main-app.xml the paths

Yep, all good.

So okay, I was able to compile and create an apk now but… it’s 32-bit! The VSCode exntension doesn’t seem to have a task to create a 64-bit version, which requires to pass an additional param to ADT: -arch armv8. So you have to use the ol’ reliable terminal and type the command with the parameters.

adt -package -target apk-captive-runtime -arch armv8 -storetype pkcs12 -keystore cert/MyCert.p12 -storepass 1234 bin/Main-64bit.apk bin/Main-app.xml -C bin Main.swf icons/.

Before getting the command to work (don’t worry this is the final verison), I ran into missing icon files issues again, all I had to fo was to add -C bin before the swf and icons path for ADT to find the files. Also note that is “icons/.” the dot means all files inside the directory.

By the way, don’t forget that if you’re uploading to the Play Store the 32-bit and 64-bit must have different versionnumber. So clean up the bin folder, change the version number in src/Main-app.xml, then build, then package again.

So I made a repo for a hello world project with all of this working https://bitbucket.org/bioRex21/hello-air-android/src/master/

Testing AIR for Android with Flash Develop using ADB over Wifi

This is very cool when you have faulty/old USB ports on your computer (like me, making it so frustrating to test my apps on the device).

First configure your device to enable ADB over wifi, these instructions from StackOverflow worked for me (root), I’ll just paste them here:

Manual Process

From your device, if it is rooted

According to a post on xda-developers, you can enable ADB over Wi-Fi from the device with the commands:

su
setprop service.adb.tcp.port 5555
stop adbd
start adbd

And you can disable it and return ADB to listening on USB with

setprop service.adb.tcp.port -1
stop adbd
start adbd

From a computer, if you have USB access already (no root required)
It is even easier to switch to using Wi-Fi, if you already have USB. From a command line on the computer that has the device connected via USB, issue the commands

adb tcpip 5555
adb connect 192.168.0.101:5555

Be sure to replace 192.168.0.101 with the IP address that is actually assigned to your device.

You can find the IP address of a tablet in two ways:

Manual IP Discovery:

Go into Android’s WiFi settings, click the menu button in the action bar (the vertical ellipsis), hit Advanced and see the IP address at the bottom of the screen.

Use ADB to discover IP:

Execute the following command via adb:

adb shell ip -f inet addr show wlan0

To tell the ADB daemon return to listening over USB

adb usb

Apps to automate the process

There are also several apps on Google Play that automate this process. A quick search suggests adbWireless, WiFi ADB and ADB WiFi. All of these require root access, but adbWireless requires fewer permissions.

source: http://stackoverflow.com/questions/2604727/how-can-i-connect-to-android-with-adb-over-tcp

Now in your FlashDevelop files, remove the -d param from adb install calls.

In RunApp.bat and PackageApp.bat, change :

adb -d install -r "%OUTPUT%"

to

adb install -r "%OUTPUT%"

In SetupApp.bat set the IP of your computer, this way you won’t have to type it when your app launches for debug in your device

:: Debugging using a custom IP
set DEBUG_IP=192.168.0.4

Now when you run your project…

adb_packaging.fw

yay!

Can’t believe it took me days to figure this out, I was very close, but I didn’t know I had to remove the -d param that directs the command to the only connected USB device.

Cool!

Tip:

My device was still showing when the List Of Devices Attached displayed (adb devices command) but appeared as offline instead of “device”.

What worked for me was

adb disconnect 192.168.0.101:5555

and then:

adb connect 192.168.0.101:5555

DISCONN

OpenFL error parsing package

I was testing OpenFL Android target (and by the way the JDK that worked for me was jdk1.6), but when I tried to install the app on my phone the “error parsing package” message showed up and didn’t let me continue.

Turns out the project.xml was wroooong:

untitled

The cool thing is that the the first thing they tell you is to name “package” correctly.

So I applied the fix:

untitled2

And all was great.

Life hack: don’t be like me.

 

 

[Snippet] Get array of (non-repeated) random Numbers.

I’ll save my story because of bleh.

Given a range, get N numbers (within that range) without repeating one.

Example:

Numbers wanted: 3.

From range : 8 – 23.

Result: 10, 19, 8.

private function getRandomNumbers(low:Number, high:Number, howMany:Number):Array
{
var store:Array = [];

if (howMany > high)
{
trace(“too many numbers wanted, howMany must be less or equal to high”);
return store;
}

while (store.length < howMany)
{
var randNum:Number = Math.floor(Math.random() * (1 + high – low)) + low;

if (store.indexOf(randNum) == -1)
{
store.push(randNum);
}

}

return store;
}

Isn’t non-formatted code a thing of beauty?

Usage:

var min:Number = 5;
var max:Number = 20;
var howMany:Number = 6;

var rNums:Array = getRandomNumbers(min, max, howMany);

Kinda lame alghoritm, I’m not very good at math and logic (and somehow I am a programmer), but there it is.

Update (1 day later): thanks to @sophistifunk for pointing me to use indexOf, so I saved some lines 🙂

 

[Catch] Using Admob Ane Android error

So I followed the instructions to use Admob Ane within my Starling/Feathers game:

https://github.com/lilili87222/admob-for-flash

But got an error:

ERROR_CODE_ERNAL_ERROR
onBannerFailedReceive

Or some stuff like that, that didn’t break the game, but the ad was not showing.

Turns out, I didn’t have Google Play Services in my Android SDK so I installed it (along other stuff, just in case).

untitled-6

Yeah I’m not a hardcore dev so I didn’t have it installed sue me (please don’t sue me).

And just like that, after doing so, I could see my game with ad$$$

admob.png

ez moneeyyyyyy

Bonus:

In case you’re having problems trying to compile with any ANE, checkout Philippe’s (easy) solution:

https://plus.google.com/u/0/+PhilippeElsass/posts/7rhFEX7S372

 

 

BluetoothSender (or yet another Native Process post)


Bluetooth communication in Flash is not possible natively (yet), so using Java (with Bluecove library) you can achieve this by using Native Process in AIR.

It works like this: FlashApp < — > AIRApp< — > Java. Of course, the AIRApp needs to be working on the background, and the FlashApp will be you main application (or it can be another AIR application).

I created an API to let Flash send commands to bluetooth, by the way it uses AS3 Signals for events dispatching. This is a code sample for searching devices:

If the image looks a bit blurry, then you need glasses, nah just kidding, it actually looks like that


“Yeah that’s cool, but how do I set everything up to create my app?” ok here it goes:

The first thing you need to do is to install BluecoveAIR

When you run it for the first time, select the path to javaw.exe by clicking the “Hey! Select Javaw.exe” button, the location is stored (via SharedObject) so you don’t have to set that again.

A window will aid you to navigate to choose the exe file.

Once it’s done you can see the “hello, Java stared” text (and a blue light indicator) that confirms that Java is good and ready to go.

That’s pretty everything you need to do in order to start using API. You can notice some options for Local Connection, these are default settings, if you wanna change them, type the new connection names in the input fields, but also remember to change them in the FlashBluetooth constructor in your Flash app.

constructor params

Local Connection default settings in the constructor (you may want to click the image).

This is a demo application to show how it works. You don’t have to worry much about the java output, it just displays what’s going on.

Note: First, place an mp3 file called “myFile” on drive C:\

Let’s start by doing a device inquiry, for that click “Search devices”. When finished, copy an address and paste it in the input text.  Then press the Download button.

When transfering the file, you’ll receive some permission notifications in your device, just accept them. Also will ask you to type PIN or code, it is 0000 (four zeros). The PIN code is hardcoded in the Java app, but yes, I will add the option to change that.

Download: AS3 API (with a few docs), sample app, BluecoveAIR and Java executables and source codes here

This was tested on Windows XP, Vista and 7, 32 bit. When I tried it on a Win7 x64 it didn’t work, so beware. (On that x64 machine, I later removed  Win7 64 and then installed a 32 bit Win XP and it went ok)

It breaks my heart not being able to generate a .dmg since I don’t have a Mac =P but if someone creates it, let me know. Also if you wanna clean and/or optimize the Java source code.. please do.

Here’s a video showing it in action

(sorry for my bad english :X lol, not that “bad english”, I mean my pronunciation)

Flash CS5 on Linux! (using Wine)

I recently started moving to Linux as my main O.S., I’m using Mint 10 (Julia) and I’ve been liking it so far. Of course there are obvious difficulties when making the transition, since how to change the mouse pointer to how to install a program, but once you get familiarized with that stuff you feel like home.

As a developer I want my tools working on my new shiny Linux, there are great ActionStript code editors that work on it, Realaxy, FDT, IntelliJ and some other that are AIR based (which are free). I chose IntelliJ, and coming from FlashDevelop it’s a bit hard to make the transition, but not impossible. Ok so I got a good code editor, but one of the most important things I need to do is to export swc files from Flash (animated Movie Clips, custom buttons and stuff). As you may know, there’s no Linux support for the CS products, so you need to do some funny stuff.

“Yeah yeah, just tell me how to run Flash CS5 on Linux”.

It’s very simple proccess which is decribed here http://int3ractive.blogspot.com/2010/08/how-to-run-flash-cs5-on-ubuntu-with.html a very cool blog by @trongthanh (quality tweets!). In another post he also explains how to use Flash Builder on Ubuntu in case you are interested.

hurray!

Here’s how CS5 look running on Mint, quite fine.

 

Yeah a glitchy thing but it's ok to meh

Yes maybe there are some tiny glitches that make your content look cropped, but it’s still intact

 

I tested exporting a swc from there, and then imported it into IntelliJ and worked as expected 🙂

AIR 2 Native Process with Java

Hi! Today I’m going to show you how to “mix” Java and ActionScript (I would call it JavaScri—umm no) with the help of the awesome Native Process class.
What exactly does this example app do?
It “magically” (tired of hearing that word actually) types text into a TextInput, yes types, I mean not setting the TextInput.text property, it’s done using the Java Robot class. When you click the “Hello” radio button, that word is typed, the same happens with the “Bye” radio button.

The app looks like this

The Java code is very simple, it just writes a text simulating key presses using the Robot class, if the java program receives as a parameter “Hello” it will type “Hello” in an Textfield of our application, also outoputs a string that will be read by the AIR app, making possible a two-way communnication (sorry for not having syntax highlight and formating):

public void checkForInput()

{

BufferedReader in = new BufferedReader(new InputStreamReader(System.in));

String text = “”;

try

{

text = in.readLine();

if (text.equals(“Hello”))

{

try

{

Robot robot = new Robot();

robot.keyPress(KeyEvent.VK_H);

robot.keyPress(KeyEvent.VK_E);

robot.keyPress(KeyEvent.VK_L);

robot.keyRelease(KeyEvent.VK_L);

robot.keyPress(KeyEvent.VK_L);

robot.keyPress(KeyEvent.VK_O);

}//robot try

catch (AWTException e)

{

e.printStackTrace();

}// robot catch

}//if = hello

if (text.equals(“Bye”))

{

try

{

Robot robot = new Robot();

robot.keyPress(KeyEvent.VK_B);

robot.keyPress(KeyEvent.VK_Y);

robot.keyPress(KeyEvent.VK_E);

}//robot try

catch (AWTException e)

{

e.printStackTrace();

}// robot catch

}

}// try in.readLine

catch(IOException e)

{

System.err.println(“Exception while reading the input. ” + e);

}// in.readLine Catch

try

{

String stringToConvert = “Lolz from Java”;

byte[] theByteArray = stringToConvert.getBytes();    

DataOutputStream dataOutputStream = new DataOutputStream(System.out);

dataOutputStream.write(theByteArray);

dataOutputStream.flush();    

}

catch(IOException e)

{     System.err.println(“Exception while reading the input. ” + e);

}

}

Now the Flexy part:

First lets set the JRE location in our machine, in this example the URL is hardcoded, and may vary depending on your OS or your JRE installation settings, you can also make the app to open a window and let you browse to the location.

(All the following is executed when the “Start Java” button is clicked)

var file:File = new File(“C:\\Program Files\\Java\\jre6”);
file = file.resolvePath(“bin/javaw.exe”);

Next we need to set te arguments in a Vector, with this, we tell JRE to execute our JAR file

var arg:Vector.<String> = new Vector.<String>;
arg.push(“-jar”);
arg.push(File.applicationDirectory.resolvePath(“MyJar.jar”).nativePath);

Now we create an instance of NativeProcessStartupinfo, this will contain our arguments vector and the location of the javaw.exe

var npInfo:NativeProcessStartupInfo = new NativeProcessStartupInfo();
npInfo.executable = file;
npInfo.arguments = arg;


We have our parameters ready, now lets create a native process and start it with the npinfo that contains the necesary data to run our jar, and an event listener to receive data from Java.

nativeProcess = new NativeProcess();

nativeProcess.addEventListener(ProgressEvent.STANDARD_OUTPUT_DATA, onStandardOutputData);

nativeProcess.start(npInfo);


There we go!, but don’t get excited this won’t do anything LOL so lets send some parameters:

(This code is executed when one of the radio buttons is clicked)

nativeProcess.standardInput.writeMultiByte(e.currentTarget.label+”\n”, “utf-8”);

Note: The “\n” is necessary since The in.readLine() in java considers a line when a text ends with “\n”

And w00t! That sent the parameter to Java and the text is automatically written.

Okay, but what do we do if we want to read data sent from java? easy, inside the onStandardOutputData function write:

trace(nativeProcess.standardOutput.readUTFBytes(nativeProcess.standardOutput.bytesAvailable));

And you will be able to see a message in the console everytime you click a radio button.



I’ve added the source (both FB and Java) files here

And here are some other post and articles related to Native Process: