BEEPS AND BLIPS FROM OUTERSPACE
WIN32: REVISITED - CREATING AN AVI FROM A GIF THAT WORKS WITH ANIMATE_CLASS

An earlier post (Creating an AVI for ANIMATE_CLASS) described how to create an AVI that will work with the ANIMATE_CLASS common control.  However, there are still some particulars that need to be ironed out for the AVI creation and play to be successful... especially when attempting to create an AVI from a GIF animated image.

Most of the issues center around bit depth and global palettes during the conversion.  But, instead of explaining all this, I'll just give the basic steps used to create the AVI:

  1. Download ImageMagick
  2. At the command prompt use IM to create a series of frames with the proper encoding
    • convert -append spin.gif all.gif
    • convert all.gif -unique-colors -depth 8 map.gif
    • convert -coalesce spin.gif BMP2:frame_%05d.bmp
    • mogrify -define bmp:format=bmp2 +matte -remap map.gif -colors 256 *.bmp
  3. Download MakeAVI
  4. Add the frame files (frame_00000.bmp)
  5. Select the fps and press Begin
  6. Choose a save name
  7. Choose the "Microsoft RLE" compressor with quality set to 100
  8. Press OK and verify the AVI can be played in Media Player
Also, keep in mind some colors may cause problems with transparency. So, be sure to remove ACS_TRANSPARENT from the window style if you don't want transparency.
Here is a Microsoft sample for creating an AVI animation window (note: it uses ACS_TRANSPARENT).
POSTED 2014-06-21 02:06:05 CATEGORY ENGINEERING TAGS WIN32 COMMON CONTROLS ANIMATION VIDEO
WIN32: CREATING AN AVI FOR ANIMATE_CLASS


I've spent far... far... too much time trying to get an AVI format that will actually work in the ANIMATE_CLASS common control.  The usual tools were tried: ImageMagick, ffmpeg, and mplayer.  But, nothing worked.

The windows API wouldn't complain about a bad format.  It would just not display the AVI in the window.

So, after some digging, I realized I needed an RLE-8 compressed AVI.  All the other tools would use an unsupported codec or they would produce a raw format codec that wouldn't be viewed in Windows Explorer or play in Windows Media Player.

After a bunch of trial and error, I came across MakeAVI.  It's a super simple interface and gives you the choice of RLE compression or uncompressed video.

So, save your time and use MakeAVI when you want to mess around with archaic Win32 animation API's.

Update: Also see Creating an AVI from a GIF that works with ANIMATE_CLASS

POSTED 2014-05-24 00:42:13 CATEGORY ENGINEERING TAGS WIN32 COMMON CONTROLS ANIMATION VIDEO
WIN32 API: SET WINDOW TO FOREGROUND

It can be tricky setting your window as the top z-order window.  It's not just a simple call to SetForegroundWindow.

 

Here's how to do it:

AttachThreadInput(GetWindowThreadProcessId(::GetForegroundWindow(), NULL),
                  GetCurrentThreadId(), TRUE);

BringWindowToTop(hwnd);
SetForegroundWindow(hwnd);
SetFocus(hwnd);

AttachThreadInput(GetWindowThreadProcessId(::GetForegroundWindow(),NULL),
                  GetCurrentThreadId(),FALSE);

This solution is from Nish Sivakumar's code project article and KevinSW's comment.

POSTED 2014-03-19 07:38:39 CATEGORY ENGINEERING TAGS WIN32 WINDOW IMPATIENT GUIDE FOCUS
WINDOWS: YEN SYMBOL FOR BACKSLASH

First off, the term backslash for \ doesn't sit well.  It would be best described as downslash since that is the direction the pen travels as it is written.  But, for consistency, let's call it a backslash.

 Maybe you have tried installing a Japanese keyboard and IME in Windows 7 and decided to uninstall it.  You may notice after uninstalling everything (and doing the requisite restart) a yen symbols still replaces the backslash when typing the key.

In a command prompt (console), paths will look like:

C:¥Windows¥System32>

To fix the problem, go to:

Settings (Control Panel) -> Region and Languages -> Administrative -> Language for non-Unicode programs -> Change system locale

You may have noticed that the setting was still set to Japanese.  Make sure it is set back to English, whichever flavor that is.

POSTED 2013-10-04 23:38:28 CATEGORY ENGINEERING TAGS IMPATIENT GUIDE HOW TO
SPARKLE: WHERE ARE UPDATE CHECKS SAVED

Sparkle is an OSX framework used for automating software.  Once integrated into an application it will pull an appcast to see if it a newer version is available.  If a newer version exists, it will download and install it.  This framework frees developers from having to roll out their own update mechanism that lives outside the App Store.

Built into Sparkle are little crumbs that make sure the update isn't performed too often since it will degrade the host application's performance.  These preferences are saved in the host application's OSX preference/properties location.

When developing it is useful to be able to do an update check on every launch, which means clearing the crumbs Sparkle left behind.  To do this use the "defaults" commandline tool:

$ defaults delete com.yourappdomainbundlename SUEnableAutomaticUpdates
$ defaults delete com.yourappdomainbundlename SULastCheckTime

If you want to see what else Sparkle puts in your application preferences, just read them:

$ defaults read com.yourappdomainbundlename
POSTED 2013-10-02 21:31:28 CATEGORY ENGINEERING TAGS SPARKLE OSX
XCODE: VIEWING MEMORY

Xcode makes easy tasks hard.  Want to view memory at a specific address?  Well, don't look in the View menu, where most of the IDE panes are.  Go to Product -> Debug -> View Memory.

Everyday using Xcode is like a scavenger hunt in Hades where the reward is absent and you can only ask yourself why you continue.

POSTED 2013-10-02 20:57:29 CATEGORY ENGINEERING TAGS XCODE
XCODE: HOW TO SET ENVIRONMENT VARIABLE FOR DEBUGGING

Say you have an application that makes a simple getenv() call to check an environment variable and you want to test it during runtime in the Xcode IDE debugger.  How do you tell Xcode 4.6 to supply the environment variable?

It's hidden away in the schema.  So, edit your schema and choose the "Run YourApp" item on the left panel.  Then add an environment variable in the table to the right.

~

Working on any mildly complex project is a nightmare.  Sure, Apple is all about minimalism, but those headers are descriptive and are useful when trying to describe solutions to project configurations.  Scanning StackOverflow's Xcode questions reveal a funny but sad mix of "the left panel" or "the second-to-left panel."

The Xcode IDE is a dirty joke that makes the life of a developer worse.  The time spent in Xcode config land versus actually being productive creating something is obscene.

POSTED 2013-10-02 19:34:40 CATEGORY ENGINEERING TAGS RANT XCODE
UNRESPONSIVE KEYBOARD ON SAMSUNG 700Z LAPTOP IN WINDOWS 7


After trying unsuccessfully to get a Japanese USB keyboard working on Windows 7, I found my Samsung Laptop keyboard and touchpad disabled.  It appears Samsung uses special scan codes to enable/disable the touchpad and keyboard.  The Japanese keyboard just happened to be able to issue one of those scan codes.

So, I inadvertently hit one of the keys and a "Hold: ON" message flashed on the screen.  I didn't think anything of it until trying to type and move the cursor.  Damn!  I was stuck with the external keyboard and mouse until everything was backed out and fixed.

Restarting the laptop did nothing.  Although the keyboard worked fine during bios/TrueCrypt authentication, it would revert back to being broken after booting the OS.

The Device Manager displayed for the Standard PS/2 Keyboard and the ELAN PS/2 Port Smart-Pad an error similar to the following:

Windows a driver for this device has been disabled.  An alternate driver may be providing this functionality.

Uninstalling the keyboard driver and reinstalling it didn't seem to fix it, nor did powering everything down and using a paperclip to disconnect the battery.

What did work was disabling the keyboard and touchpad and re-enabling them.  After a reboot, they were once again functioning.

POSTED 2013-09-27 02:43:03 CATEGORY ENGINEERING TAGS BROKEN LAPTOP SAMSUNG KEYBOARD
USING PROGUARD FOR ANDROID AND LIBGDX

I decided to finally bite the bullet and get ProGuard working for some Android apps.  It was hell getting everything working because of the shear number of moving parts: Android SDK, Eclipse, Libgdx, AdMob/Google Ads, apk signing, and the shitstorm ProGuard imposes on any project.

This is going to be another Impatient Guide, because I'd rather not relive configuration problems.  The amount of time wasted getting technologies configured and working together is a time sink that gets in the way of making real progress and doing real work.

Step one:  Turn on ProGuard for your Android project.

  • Navigate to your project.  If you are using LibGdx and the standard configuration it will be named something like "<YourProjectName>-Android".
  • Open default.properties for editing
  • Add the line: proguard.config=proguard.cfg
  • Save and reopen Eclipse.

Step two:  Update the Android SDK Location in Eclipse

Did you jump the gun and try to created a signed apk?  Did you get this error?

"C:\Program' is not recognized as an internal or external command, and executable program, or command file."

Well, Proguard doesn't like spaces in paths, so update the Android SDK location to a short path form.

  • Open a command prompt: WIN+R -> cmd.exe
  • cd to the Android SDK location... e.g. "c:\Program Files (x86)\Android\android-sdk"
  • type: for /d %I in (*) do @echo %~sI
  • Copy the path.  e.g. "C:\PROGRA~2\Android\ANDROI~1"
  • Paste the short form path in Eclipse: Window -> Preferences -> Android -> SDK Location
  • Hit apply or OK

Step Three: Tell ProGuard about dependent libraries

Did you try to export an application package again?  Did you get errors like this?

"Warning: com.badlogic.gdx.scenes.scene2d.ui.utils.DesktopClipboard: can't find superclass or interface java.awt.datatransfer.ClipboardOwner"

or

"Warning: there were 28 unresolved references to classes or interfaces."

Well, you have to tell ProGuard dependent jar files, so it won't blow up.  Add something like the following to the proguard.cfg file in your project directory.  Your configuration will depend upon how your project is set up and make sure to use absolute paths.

-libraryjars 'C:\Program Files\Java\jre6\lib\rt.jar'
-libraryjars 'C:\source...\<YourProjectName>-Android\libs'
-libraryjars 'C:\source...\<YourProjectName>\libs'
-libraryjars 'C:\source...\<YourProjectName>\libs\GoogleAdMobAdsSdkAndroid-4.1.1'

That last one is only valid if you use the AdMob SDK.

Step Four: Fix runtime errors resulting from an overzealous ProGuard shrink

Did you export an .apk with joy, but become totally crushed when your application crashed?  Did the crashes happen when you clicked on widgets?

It turns out that ProGuard is removing any code that appears to not be referenced/used.  So, any OnClick* handlers specified in your Android layout xml files will be removed.  Seriously.  Take a look at <YourProjectName>-Android/proguard/usage.txt.  That is stuff that was torn out from your code to "speed" up performance.  Well, it crashes faster.  That's for sure.

But you can't blame ProGuard.  It can't read every file in your project that is SDK dependent and make the connection.  ProGuard is nice, but it's no mindreader.

To fix this, open up proguard.cfg again and tell ProGuard to not touch any OnClick handlers:

-keepclasseswithmembers class * {
  void onClick*(...);
}

If you want to make sure your advertisements from Google show up (com.google.ads*), add the following to your config file too:

-keep public class com.google.ads.** {*;}

Save it.

Step Five: Export the .apk and test it

You've probably already done this, but for reference:

  • Right Click on <YourProjectName>-Android -> Android Tools -> Export Signed Application Package...
  • Complete the form and generate the apk (e.g. yourproject.apk)
  • Make sure the app isn't already installed on your phone
  • Open a console: apk.exe install yourproject.apk

Conclusion:

This article was built upon a previous article called How to Obfuscate and Package a LibGdx App for Distribution.

Working with ProGuard is painful, but hopefully your project is now up and running.

 

POSTED 2012-08-22 17:32:24 CATEGORY ENGINEERING TAGS GOOGLE ADS LIBGDX PROGUARD HELL ANDROID IMPATIENT GUIDE
HOW TO OBFUSCATE AND PACKAGE A LIBGDX APP FOR DISTRIBUTION

First off: This is an Impatient Guide and it will be short on explanation and possibly accuracy

Second off: This method is a first attempt and is probably fraught with errors and inefficiencies, but it worked for me.

Let's get started!

Say you have a LibGDX project and you want to package it up for redistribution, but you don't want to give out a jar and would like it to be wrapped in a nice executable (.exe) just like any ordinary Windows binary.  In addition, obfuscating the code to make reverse engineering more difficult might be something you want too.

Here's how I did it manually with Eclipse, ProGuard, Launch4j, and 7-zip.

Creating the JAR files:

  1. Export a jar file with the Eclipse Export Wizard.  I did this for my desktop version, by right clicking on the project "myapp-desktop" -> Export -> Java -> Runnable Jar File.
  2. Plug in the usual stuff into the wizard, but choose "Copy required libraries into a sub-folder next to the generated JAR."  Otherwise, ProGuard will make your life a nightmare when you try to obfuscate (e.g. "Warning: org.lwjgl.input.Controllers: can't find referenced class net.java.games.input.ControllerEnvironment").
  3. Hit "finish" and the wizard will generate your shiny new .jar file.
  4. Do 1 through 3 again, but in step 2 choose "Package required libraries into generated JAR."  The jarinjarloader files and the MANIFEST.MF from this second generated JAR will be used later on.

Obfuscate your jar with ProGuard:

  1. Run the GUI version of ProGuardjava -jar proguardgui.jar
  2. In the Input/Output tab, click "Add input..." and enter the first generated JAR path.
  3. Click "Add output..." and enter your output JAR... say (e.g. output.jar).
  4. Click "Add..." in the Add libraries section and add the library export directory generated with the first JAR.  If your export JAR name was foo.jar, the export dependencies should be in foo_lib.
  5. In the Obfuscation tab uncheck "Use mixed-case class names."
  6. Keep the default settings for now (you can tweak them later once you have this working).
  7. Start processing the JAR.  In the Process tab click Process!
  8. If ProGuard finishes it will produce a nice obfuscated/shrunk JAR, output.jar.

Combine library dependencies into obfuscated JAR

  1. The output.jar is not runnable as is.  It needs to know how to find the library dependencies.  You can pack the dependencies into the JAR with 7-zip.  So, open output.jar in 7-zip.
  2. Add/drag the contents of foo_lib (from step 2 in the first section) into the root level of the JAR (e.g. they should be in the same directory META-INF is in).
  3. Extract the other JAR from the first section (see step 4) into a temp directory (e.g. temp).
  4. In output.jar, clobber the file "META-INF/MANIFEST.MF" with the file from "temp/META-INF/MANIFEST.MF".
  5. In output.jar, add the directory "org/eclipse" from "temp/org/eclipse".
  6. Confirm the JAR is runnable: java -jar output.jar

Wrap your JAR in a Windows executable

  1. Use Launch4j to wrap your JAR.  Open the Launch4j GUI.
  2. Add your output file: out.exe
  3. Add your input JAR file: output.jar
  4. In the JRE tab, set the Min JRE version (e.g. 1.6.0)
  5. Click the gear icon to build the wrapper.
  6. Confirm the binary works.  High Fives all Around!
 
POSTED 2012-07-07 22:05:59 CATEGORY ENGINEERING SOFTWARE TAGS DEVELOPMENT JAVA LAUNCH4J LIBGDX JAR PROGUARD IMPATIENT GUIDE
prev page
• • •
next page