Friday, December 12, 2014

How to Sign Steam Dylib for Mac OS X in XCode


codesign --no-strict --verbose --force --sign "Developer ID Application" libsteam_api.dylib

Saturday, November 22, 2014

Clear Application Data with ADB at the command line

You can use package manager (pm) to clear data for installed apps (same as pressing the 'clear data' button in the app settings on your device).

Run this adb command, replacing 'com.company.games.game' with your package name from AndroidManfiest.xml

adb shell pm clear com.company.games.game

This method depends on the 'pm' tool being resident on the Android device, which is not always the case.

Thursday, November 20, 2014

Cocos2d-x v2.2 Fullscreen Linux Support

Add this method to CCEGLView.cpp and CCEGLView.h

void CCEGLView::setFrameSize(float width, float height, bool fullscreen)
{
bool eResult = false;
int u32GLFWFlags = GLFW_WINDOW;
if(fullscreen) {
u32GLFWFlags = GLFW_FULLSCREEN;
}
//create the window by glfw.
//check
CCAssert(width!=0&&height!=0, "invalid window's size equal 0");
//Inits GLFW
eResult = glfwInit() != GL_FALSE;
if (!eResult) {
CCAssert(0, "fail to init the glfw");
}
if(fullscreen) {
GLFWvidmode desktopMode;
glfwGetDesktopMode(&desktopMode);
CCLog("W: %d", (int)desktopMode.Width);
CCLog("H: %d", (int)desktopMode.Height);
height = (int)desktopMode.Height;
width = (int)desktopMode.Width;
}
/* Updates window hint */
glfwOpenWindowHint(GLFW_WINDOW_NO_RESIZE, GL_TRUE);
int iDepth = 16; // set default value
/* Depending on video depth */
switch(iDepth)
{
/* 16-bit */
case 16:
{
/* Updates video mode */
eResult = (glfwOpenWindow(width, height, 5, 6, 5, 0, 16, 8, (int)u32GLFWFlags) != false) ? true : false;
break;
}
/* 24-bit */
case 24:
{
/* Updates video mode */
eResult = (glfwOpenWindow(width, height, 8, 8, 8, 0, 16, 8, (int)u32GLFWFlags) != false) ? true : false;
break;
}
/* 32-bit */
default:
case 32:
{
/* Updates video mode */
eResult = (glfwOpenWindow(width, height, 8, 8, 8, 8, 16, 8, (int)u32GLFWFlags) != GL_FALSE) ? true :false;
break;
}
}
/* Success? */
if(eResult)
{
glfwSetWindowSize(width, height);
// Move window to the upper left corner.
glfwSetWindowPos(0, 0);
glfwEnable(GLFW_MOUSE_CURSOR);
/* Updates actual size */
// glfwGetWindowSize(&width, &height);
CCEGLViewProtocol::setFrameSize(width, height);
/* Updates its title */
glfwSetWindowTitle("Cocos2dx-Linux");
//set the init flag
bIsInit = true;
//register the glfw key event
glfwSetKeyCallback(keyEventHandle);
//register the glfw char event
glfwSetCharCallback(charEventHandle);
//register the glfw mouse event
glfwSetMouseButtonCallback(mouseButtonEventHandle);
//register the glfw mouse pos event
glfwSetMousePosCallback(mousePosEventHandle);
//register the glfw keyboard event
glfwSetKeyCallback(keyboardEventHandle);
glfwSetWindowCloseCallback(closeEventHandle);


//Inits extensions
eResult = initExtensions();
if (!eResult) {
CCAssert(0, "fail to init the extensions of opengl");
}
initGL();
}
}

Tuesday, November 04, 2014

Android Lollipop Patch for Cocos2dxMusic.java (Cocos2d-x v2.2)

Patch for Cocos2dxMusic.java (Cocos2d-x v2.2)


  Index: Cocos2dxMusic.java
  ===================================================================
  --- Cocos2dxMusic.java (revision 21981)
  +++ Cocos2dxMusic.java (working copy)
  @@ -110,12 +110,12 @@
        Log.e(Cocos2dxMusic.TAG, "playBackgroundMusic: background media player is null");
      } else {
        // if the music is playing or paused, stop it
  - this.mBackgroundMediaPlayer.stop();
  + //this.mBackgroundMediaPlayer.pause();
   
        this.mBackgroundMediaPlayer.setLooping(isLoop);
   
        try {
  - this.mBackgroundMediaPlayer.prepare();
  + //this.mBackgroundMediaPlayer.prepare();
          this.mBackgroundMediaPlayer.seekTo(0);
          this.mBackgroundMediaPlayer.start();
   
  @@ -129,6 +129,9 @@
    public void stopBackgroundMusic() {
      if (this.mBackgroundMediaPlayer != null) {
        this.mBackgroundMediaPlayer.stop();
  + this.mBackgroundMediaPlayer.release();
  + this.mBackgroundMediaPlayer = null;
  + this.mCurrentPath = null;
   
        // should set the state, if not, the following sequence will be error
        // play -> pause -> stop -> resume
  @@ -152,10 +155,9 @@
   
    public void rewindBackgroundMusic() {
      if (this.mBackgroundMediaPlayer != null) {
  - this.mBackgroundMediaPlayer.stop();
   
        try {
  - this.mBackgroundMediaPlayer.prepare();
  + this.mBackgroundMediaPlayer.pause();
          this.mBackgroundMediaPlayer.seekTo(0);
          this.mBackgroundMediaPlayer.start();
 

Sunday, August 10, 2014

NullPointerException at android.widget.ArrayAdapter.createViewFromResource


Crashes while using code like this:

AlertDialog.Builder builder = new AlertDialog.Builder(StatusMenuConflicts.this);
builder.setTitle("Star Traders RPG");
builder.setIcon(R.drawable.icon);
final String[] items = new String[6];
items[0] = getString(R.string.status);

The stack trace won't contain your code.

 java.lang.NullPointerException
        at android.widget.ArrayAdapter.createViewFromResource(ArrayAdapter.java:355)
        at android.widget.ArrayAdapter.getView(ArrayAdapter.java:323)
        at android.widget.AbsListView.obtainView(AbsListView.java:1435)
        at android.widget.ListView.measureHeightOfChildren(ListView.java:1288)
        at android.widget.ListView.onMeasure(ListView.java:1199)
        at android.view.View.measure(View.java:8322)
        at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:3138)
        at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1017)
        at android.widget.LinearLayout.measureVertical(LinearLayout.java:386)
        at android.widget.LinearLayout.onMeasure(LinearLayout.java:309)
        at android.view.View.measure(View.java:8322)
        at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:3138)
        at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1017)
        at android.widget.LinearLayout.measureVertical(LinearLayout.java:386)
        at android.widget.LinearLayout.onMeasure(LinearLayout.java:309)
        at com.android.internal.widget.WeightedLinearLayout.onMeasure(WeightedLinearLayout.java:60)
        at android.view.View.measure(View.java:8322)
        at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:3138)
        at android.widget.FrameLayout.onMeasure(FrameLayout.java:250)
        at android.view.View.measure(View.java:8322)
        at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:3138)
        at android.widget.FrameLayout.onMeasure(FrameLayout.java:250)
        at android.view.View.measure(View.java:8322)
        at android.view.ViewRoot.performTraversals(ViewRoot.java:839)
        at android.view.ViewRoot.handleMessage(ViewRoot.java:1859)
        at android.os.Handler.dispatchMessage(Handler.java:99)
        at android.os.Looper.loop(Looper.java:130)
        at android.app.ActivityThread.main(ActivityThread.java:3806)
        at java.lang.reflect.Method.invokeNative(Native Method)
        at java.lang.reflect.Method.invoke(Method.java:507)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:839)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:597)
        at dalvik.system.NativeStart.main(Native Method)

The problem is that Android is looking for 6 elements in the Array you're passing in, but you've only defined one. Set the length of you String[] correctly and the code will work.

Friday, August 08, 2014

Interviews -- Reverse Singly Linked List, C++

Just seriously struggled through an interview on the phone. It's always the simple programming problems that seem the hardest when someone is watching you do it.

The question was "Write a simple function to reverse a linked list" and I couldn't get it right until 3 minutes after the interview was over. Every. Single. Time.

So here is the code I ended up with, given this basic Linked list.

struct List {
   int value;
   mySingleLinked* next;
};

Seems simple, right? See the comments ;)

// arg. i'm an idiot
List reverseLinkedList(List* head) {
    List *tempList, *nextList;

tempList = 0;
nextList = 0;

while (head != 0)
{
nextList = head->next;
head->next = tempList;
tempList = head;
head = nextList;
}
return tempList;
}

Wednesday, February 05, 2014

Quick AES Encrypt String with Botan C++

AutoSeeded_RNG rng;
SymmetricKey key(rng, 16); // a random 128-bit key
InitializationVector iv(rng, 16); // a random 128-bit IV
Pipe pipe(get_cipher("AES-128/CBC", key, iv, ENCRYPTION), new Hex_Encoder);
pipe.process_msg("secrets");
std::string m1 = pipe.read_all_as_string(0);
Pipe pipe2(new Hex_Decoder, get_cipher("AES-128/CBC", key, iv, DECRYPTION));
pipe2.process_msg(m1.c_str());
std::string m2 = pipe2.read_all_as_string(0);

Saturday, January 18, 2014

How to Screen Record Android Video

Launch into the command line with your Android 4.4 device connected to your computer and enter the command to record your screen:
adb shell screenrecord /sdcard/demo.mp4
You can further customize the speed at which it captures video, the length of time it records (the default duration is 3-minutes) and the size of the video in terms of resolution.
Another example of a command to record a video would be:
adb shell screenrecord --bit-rate 8000000 --time-limit 30 /sdcard/kitkat.mp4
The above command would record at 8Mbps, instead of the default 4Mbps, for a duration of 30-seconds and save it to the SD Card on your device with the name of KitKat. You can find a full list of commands for screenrecord here on the Android Developer Site.


Wednesday, November 13, 2013

Saturday, August 31, 2013

Google Quality Problems in Android 4.3

I know that I am very disappointed to learn that the Android team's quality control process is so lacking that it permits issues like this to reach production:


https://code.google.com/p/android/issues/detail?id=58385


I just think that at this point it appears that Android, the OS and the toolchain, have grown too complex for Google's teams to handle.


Google, and the Android team, are rapidly falling behind on quality in both the development tools and the OS releases, even for flagship devices like the Nexus 7 and Nexus 10.


This issue above is only one of a dozen fatal flaws in the Android OS and recent releases of the ADT have exhibited similar lapses in discipline.


I would speculate that this could represent a chance for someone seeking to take marketshare from Google with developers to capitalize on Google's current weak position.

Wednesday, August 21, 2013

Sunday, August 18, 2013

IAB v3 Stuff ... v2 Stuff ... Google IAP Android

How to implement IAB v3
http://developer.android.com/google/play/billing/billing_integrate.html

but if you are using sharedUserId, you will be stuck with IAB v2
http://developer.android.com/google/play/billing/v2/api.html

Either way your Android application will need a custom list view
http://www.ezzylearning.com/tutorial.aspx?tid=1763429

ListView, you remember this good old fashion Android UI widget?
http://developer.android.com/reference/android/widget/ListView.html

Now, once you get through all that then you start digging into the API
http://developer.android.com/google/play/billing/v2/api.html

You will have errors. They might be this error about developer keys:
http://stackoverflow.com/questions/11068686/this-version-of-the-application-is-not-configured-for-billing-through-google-pla



A typical in-app billing implementation relies on three components:
  • Service (namedBillingService in the sample application), which processes purchase messages from the application and sends billing requests to the Google Play in-app billing service.
  • BroadcastReceiver (namedBillingReceiver in the sample application), which receives all asynchronous billing responses from the Google Play application.
  • A security component (named Security in the sample application), which performs security-related tasks, such as signature verification and nonce generation. For more information about in-app billing security, seeSecurity controls later in this document.
You may also want to incorporate two other components to support in-app billing:
  • A response Handler (named ResponseHandler in the sample application), which provides application-specific processing of purchase notifications, errors, and other status messages.
  • An observer (named PurchaseObserver in the sample application), which is responsible for sending callbacks to your application so you can update your user interface with purchase information and status.
In addition to these components, your application must provide a way to store information about users' purchases and some sort of user interface that lets users select items to purchase. You do not need to provide a checkout user interface. When a user initiates an in-app purchase, the Google Play application presents the checkout user interface to your user. When the user completes the checkout process, your application resumes.

Friday, August 09, 2013

CCParticleSystem in Cocos2d-x with PList File

This code will run a plist particle system in Cocos2d-x

CCParticleSystem* emitter = CCParticleSystemQuad::create("blood.plist");
this->addChild( emitter, 5 );
emitter->setPosition( deadMonster->getSprite()->getPosition());
CCCallFunc* moveCallback = CCCallFunc::create(emitter, 
               callfunc_selector(CCParticleSystem::removeFromParent));
CCDelayTime* delayAction = CCDelayTime::create(0.3f);
emitter->runAction(CCSequence::create(delayAction, moveCallback, NULL));

Wednesday, June 12, 2013

Using with JNI Stack Traces Debug JNI / C++ in Android SYSTEM_TOMBSTONE

First, your application which is written in C++ or being invoked over JNI will crash.

Hello! Honestly we both know it will crash a whole shitload. It's JNI -- what it really does is crash.

So, first we're writing JNI and that ensures we'll see this type of trash spewing out of logcat regularly.

I/DEBUG   ( 9753): *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
I/DEBUG   ( 9753): Build fingerprint: 'verizon/voles/sholes/sholes:2.2.1/FRG83D/75603:user/release-keys'
I/DEBUG   ( 9753): pid: 10400, tid: 10408  >>> com.tresebrothers.games.heroesofsteel <<<
I/DEBUG   ( 9753): signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 00000013
I/DEBUG   ( 9753):  r0 002ba6b4  r1 ffffffff  r2 002ba6a0  r3 002b9908
I/DEBUG   ( 9753):  r4 002a68f0  r5 00000d98  r6 00000400  r7 00000080

[/snip]

I/DEBUG   ( 9753): #01 448b8a50  80e9dad0
I/DEBUG   ( 9753):     448b8a54  8098ae80  /data/data/com.tresebrothers.games.heroesofsteel/lib/libheroesofsteel.so
I/BootReceiver( 9764): Copying /data/tombstones/tombstone_06 to DropBox (SYSTEM_TOMBSTONE)
E/InputDispatcher( 9764): channel '407abe08 com.tresebrothers.games.heroesofsteel/com.tresebrothers.games.heroesofsteel.HeroesOfSteel_android (server)' ~ Consumer closed input channel or an error occurred.  events=0x8
E/InputDispatcher( 9764): channel '407abe08 com.tresebrothers.games.heroesofsteel/com.tresebrothers.games.heroesofsteel.HeroesOfSteel_android (server)' ~ Channel is unrecoverably broken and will be disposed!

I/ActivityManager( 9764): Process com.tresebrothers.games.heroesofsteel (pid 10400) has died.


That entire mess is worthless to us.

Foreign-language-we-do-not-know worthless to us.

We need to translate:
  • First, we download the data from the device (needs root.)
  • Second, we locate the translation tables (comes from the build.)
  • Third, we mash it all together with ndk-stack (comes from the NDK.)


Download the Tombstone Stack Traces

I ran the command
G:\stacks>"C:\Program Files (x86)\Android\android-sdk-windows\platform-tools\adb.exe" pull /data/tombstones/

Had to make sure I had my shell running somewhere with permissions so that adb could write the tombstone files (AKA, not C:\Program Files)

ADB will chew on this for a minute and then print something like this:

pull: building file list...
pull: /data/tombstones/tombstone_01 -> ./tombstone_01
pull: /data/tombstones/tombstone_06 -> ./tombstone_06
pull: /data/tombstones/tombstone_07 -> ./tombstone_07
pull: /data/tombstones/tombstone_08 -> ./tombstone_08
pull: /data/tombstones/tombstone_05 -> ./tombstone_05
pull: /data/tombstones/tombstone_04 -> ./tombstone_04
pull: /data/tombstones/tombstone_02 -> ./tombstone_02
pull: /data/tombstones/tombstone_09 -> ./tombstone_09
pull: /data/tombstones/tombstone_00 -> ./tombstone_00
pull: /data/tombstones/tombstone_03 -> ./tombstone_03
10 files pulled. 0 files skipped.
1564 KB/s (607224 bytes in 0.379s)

This cannot be helped but at least your files were downloaded (if you were lucky.)


Locate the Translation Objects

They are located in {PROJ.ROOT}\obj\local\armeabi\

If you are using Cocos2d-x then it is like this:
G:\cocos2d-2.1rc0-x-2.1.2\YourCoolGame\proj.android\obj\local\armeabi


Run NDK-Stack

I ran the command
G:\android-ndk-r8d\ndk-stack.exe -sym G:\cocos2d-2.1rc0-x-2.1.2\HeroesOfSteel\proj.android\obj\local\armeabi -dump G:\strace\tombstone_06

If you do it all right you get something that looks like this and might tell you something about what is wrong with your program. Probably not. But it does include some line numbers which is better than afd11060 e2166903 1a000017 e5945000 e1a02004.

So this is what it ends up looking like:

********** Crash dump: **********
Build fingerprint: 'verizon/voles/sholes/sholes:2.2.1/FRG83D/75603:user/release-keys'
pid: 10322, tid: 10330  >>> com.tresebrothers.games.heroesofsteel <<<
signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 802bb1f8
Stack frame #00  pc 00013488  /system/lib/libc.so (dlfree)
Stack frame #01  pc 00014726  /system/lib/libc.so (free)
Stack frame #02  pc 00300528  /data/data/com.tresebrothers.games.heroesofsteel/lib/libheroesofsteel.so: Routine sqlite3MemFree in G:/cocos2d-2.1rc0-x-2.1.2/HeroesOfSteel/proj.android/../../StoryTeller
Core/proj.android/jni/../../Classes/sqlite3.c:15578


These were really useful pages




This 'addr2line' stuff is waaaaay too tedious to even consider. NDK-Stack is painful enough as is!

Love you, mean it.

-C

Friday, June 07, 2013

How to push an APK to non-root Android device with adb

Step 1: Transfer the APK File

C:\Program Files (x86)\Android\android-sdk-windows\platform-tools>adb push "G:\SVN_Android\Star Traders.apk" /sdcard/1.apk
1013 KB/s (14509331 bytes in 13.986s)

Step 2: Create a Shell
C:\Program Files (x86)\Android\android-sdk-windows\platform-tools>adb shell
$ cd /sdcard
cd /sdcard
$ ls
ls
LOST.DIR
Android
DCIM
download
catlog_saved_logs
1.apk

Step 3: Execute the installer
$ pm install 1.apk
pm install 1.apk
        pkg: 1.apk
Success
$


Step 4: Check LogCat
D/dalvikvm(  703): GC_FOR_MALLOC freed 26029 objects / 1033352 bytes in 228ms
D/PackageManager(  703): Scanning package com.corytrese.games.startraders
I/PackageManager(  703): /data/app/com.corytrese.games.startraders-1.apk changed; unpacking
D/installd(   60): DexInv: --- BEGIN '/data/app/com.corytrese.games.startraders-1.apk' ---
D/dalvikvm( 1804): DexOpt: load 1152ms, verify 3241ms, opt 139ms
D/installd(   60): DexInv: --- END '/data/app/com.corytrese.games.startraders-1.apk' (success) ---
I/ActivityManager(  703): Force stopping package com.corytrese.games.startraders uid=10046
D/PackageManager(  703):   Activities: com.corytrese.games.startraders.menu.MainMenu com.corytrese.g

Sunday, June 02, 2013

Heroes of Steel RPG ... Progress


cocos2d: deallocing CCDirector 024CCF18
The thread 'Win32 Thread' (0x53f4) has exited with code 0 (0x0).
The thread 'Win32 Thread' (0x44a8) has exited with code 0 (0x0).
No memory leaks detected.
Visual Leak Detector is now exiting.
The program '[19616] HeroesOfSteel.win32.exe: Native' has exited with code 0 (0x0).

Tuesday, May 28, 2013

C++ Questions / Interview / Mastery

I am going to try to answer this list of questions about C++




  • How many ways are there to initialize a primitive data type in C++ and what are they?
  • Why should you declare a destructor as virtual?
  • What does it mean that C++ supports overloading?
  • What are examples of overloading in C++?
  • What is name mangling in C++ and why is it used?
  • What is an abstract base class?
  • What is RTTI?
  • How can you access a variable that is “hidden” by another variable of the same name?
  • What is a namespace and how is it used.
  • What are the differences between a class and a struct in C++, and how does this compare to C?
  • What are templates? How are they used?
  • What is a copy constructor and when is it used, especially in comparison to the equal operator.
  • What is the difference between a “shallow” and a “deep” copy?
  • What is the const operator and how is it used?
  • What are the differences between passing by reference, passing by value, and passing by pointer in C++?
  • When is it and when is it not a good idea to return a value by reference in C++?
  • What is the difference between a variable created on the stack and one created on the heap?
  • How do you free memory allocated dynamically for an array? What are the implications of just using delete?
  • What is multiple inheritance? When should it be used?
  • What is a pure virtual function?
  • What does the keyword mutable do?
  • What does the keyword volatile do?
  • What is the STL?
  • What is a Vector?
  • What is contained in the header?
  • What is the difference between #include and #include ?
  • What’s the difference between “++i” and “i++”?
  • What is short circuit evaluation? How can it be used? Why can is be dangerous?
  • What is the ‘,’ operator?
  • What is the only ternary operator? How is it used?
  • What is the use of a const member function and how can it be used?
  • How is try/catch used in C++?
  • Why should you never throw an exception in a destructor?
  • What is the explicit keyword?
  • What is the proper way to perform a cast in C++?
  • What does inline do?



Monday, May 27, 2013

Debugging Visual Studio Memory Leaks in C++ and Cocos2d-x

Visual Leak Detector is a life-saver, download for free:

https://vld.codeplex.com/documentation

Quick check possible with this code snippet


#if defined(DEBUG) | defined(_DEBUG)
  _CrtSetDbgFlag( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF );
#endif

Saturday, April 27, 2013

Google Play Developer Console: Upload Failed (Error uploading APK)

Are you getting this error?

Inline image 1

You need to refresh your browser. The application running at https://play.google.com/apps/publish/v2/ wants to be refreshed regularly or it stops functioning. Sometimes I need to clear cache / restart Chrome to get it to come back to life.