Project page

Lincity4droid, Android port of Lincity-NG


Lincity-NG is a modern version of Lincity which is basically a SimCity clone. That is to say a game where you are supposed to build and administer a city.

Status : first public release

Available on Android Market
https://market.android.com/details?id=org.libsdl.app&feature=search_result

Source code is availabe at GitHub:
https://github.com/kobr4/Lincity4droid


Game is written in C++, with SDL for multimedia io operation (sound, gfx, input), SDL is a C library that is now fully ported to Android.

Lincity is game that comes from the Linux world so it should retain good compatibility with Android.

I want to reach quickly a first playable version, before I'll lose my momentum. Then refined things until I get a good enough version for Android market.

Task will be:
1. Port all libraries used by Lincity to Android
2. Relocate game data so that they will be able to load from phone storage
3. Adapt Lincity code to Android, for instance OpenGL code has to be ported to OpenGL ES, which is only a subset of the original OpenGL API.
4. Adapt Lincity Gui to phone aspect ratio
5. Adapt user input and gui to touchscreen
6. RELEASE THE CODE !


Devlog

26/10/2011
Ok I've ported all Lincity libs to Android.

For now game data will be stored in /sdcard/lincity/data, which plain ugly, I hope to be able to read Lincity data directly from application APK one day.

Ported OpenGL call to OpenGL ES. Game resolution still bugs me : in order to see the whole main menu, I have to set in game resolution to 512x320 whereas my galaxy S is supposed to be 800x480...

How to handle touch event with SDL :

New event types:
 
/* Touch events */
SDL_FINGERDOWN = 0x700,
SDL_FINGERUP,
SDL_FINGERMOTION,
SDL_TOUCHBUTTONDOWN,
SDL_TOUCHBUTTONUP,
 
/* Gesture events */
SDL_DOLLARGESTURE = 0x800,
SDL_DOLLARRECORD,
SDL_MULTIGESTURE,
 


New events definition
 
/**
* \brief Touch finger motion/finger event structure (event.tmotion.*)
*/

typedef struct SDL_TouchFingerEvent
{
Uint32 type; /**< ::SDL_FINGERMOTION OR
             SDL_FINGERDOWN OR SDL_FINGERUP*/

Uint32 windowID; /**< The window with mouse focus, if any */
SDL_TouchID touchId; /**< The touch device id */
SDL_FingerID fingerId;
Uint8 state; /**< The current button state */
Uint8 padding1;
Uint8 padding2;
Uint8 padding3;
Uint16 x;
Uint16 y;
Sint16 dx;
Sint16 dy;
Uint16 pressure;
} SDL_TouchFingerEvent;
 
 
/**
* \brief Touch finger motion/finger event structure (event.tmotion.*)
*/

typedef struct SDL_TouchButtonEvent
{
Uint32 type; /**< ::SDL_TOUCHBUTTONUP OR SDL_TOUCHBUTTONDOWN */
Uint32 windowID; /**< The window with mouse focus, if any */
SDL_TouchID touchId; /**< The touch device index */
Uint8 state; /**< The current button state */
Uint8 button; /**< The button changing state */
Uint8 padding1;
Uint8 padding2;
} SDL_TouchButtonEvent;
 
 
/**
* \brief Multiple Finger Gesture Event (event.mgesture.*)
*/

typedef struct SDL_MultiGestureEvent
{
Uint32 type; /**< ::SDL_MULTIGESTURE */
Uint32 windowID; /**< The window with mouse focus, if any */
SDL_TouchID touchId; /**< The touch device index */
float dTheta;
float dDist;
float x; //currently 0...1. Change to screen coords?
float y;
Uint16 numFingers;
Uint16 padding;
} SDL_MultiGestureEvent;
 
/* (event.dgesture.*) */
typedef struct SDL_DollarGestureEvent
{
Uint32 type; /**< ::SDL_DOLLARGESTURE */
Uint32 windowID; /**< The window with mouse focus, if any */
SDL_TouchID touchId; /**< The touch device index */
SDL_GestureID gestureId;
Uint32 numFingers;
float error;
/*
//TODO: Enable to give location?
float x; //currently 0...1. Change to screen coords?
float y;
*/

} SDL_DollarGestureEvent;
 
 


The java code that handles touch event
 
// Touch events
public boolean onTouch(View v, MotionEvent event) {
 
int action = event.getAction();
float x = event.getX();
float y = event.getY();
float p = event.getPressure();
 
// TODO: Anything else we need to pass?
Lincity4droidActivity.onNativeTouch(action, x, y, p);
return true;
}
 


The native c++ code that handles touch and push it into SDL event queue.
 
extern "C" void Java_org_libsdl_app_Lincity4droidActivity_onNativeTouch(JNIEnv* env,
jclass cls,int action, float x, float y,float p)
{
SDL_Event event;
event.type = SDL_FINGERDOWN;
event.tfinger.x = (Uint16)x;
event.tfinger.y = (Uint16)y;
if (SDL_PushEvent(&event) == -1)
{
LOGD("[Lincity]Error : could not push event into event queue\n");
}
}
 

28/10/2011
I've successfully added touch support to main menu gui, and it works suprisingly well. I've even been able to start a new game.
Trouble is now that the user in-game interface is clearly not suited for small devices such as phone.
The easier and quicker way is to make touch action to mimics mouse click but it will not fit small smartphone screen very well. It'll be fine for bigger tablets though. The nicer move is to rework entirely the gui in order to make it properly adapted to smartphone. What would be top notch is to be able to switch between landscape and portrait mode and have to user interface automatically re-organizing depending on the situation.

30/10/2011
I know why OpenGL resolution would not scale to fit native screen résolution. By defaut Android Limits screen resolution to retain compatibility with small screen devices. I have to explicity declare my app to be compatible with every screen resolution, in its manifest.
 
    <supports-screens
    android:largeScreens="true"
    android:normalScreens="true"
    android:smallScreens="true"
    android:anyDensity="true"/>
 


31/10/2011
Sound is working, I just figured out that I had to connect SDL audio main loop (that pushes receive sound data to the audio output buffer) to the java code that launches the audio thread. Sound volume to is to low though, even set at maximum. Ogg music playback seems broken.
I'm very close to the first release. Without UI rework, it will be playable on tablets because buttons are too small.
I'd like the game data to be all packed in the application apk because downloading game data from internet after installation require me to setup an infrastructure. I have to make the game hold into 10 mb max. (44mb out of the box :( )

01/11/2011
Yes ! Got rid of an anoying bug that I introduced myself by compiling PHYSFS without thread support, file handles get messed up. It was even more obvious while using my Xoom tablet with its dual-core CPU.
I'm very very close to an Android market release right now.

02/11/2011
Few things left:
1. Be able to pause game on onPause event, people don't want the game to crash while answering a phone call.
2. Unpack data from apk to sdcard on first launch and without application freezing ages because user will think the application is crashed.
3. Gameplay is a bit clumsy as finger precision is not stellar, you'll often end up putting a bit of road at the wrong place. Also scrolling view my result in a click, so be aware not a having selected a build option, as it will end up having a building in the middle of nowhere.

03/11/2011
1. I can't get the game to pause while user hits the home button : Android will destroy SDL OpenGL surfac, and no other GL swapbuffer call will ever work.
Recreating surface on resume does not seems to work either.
2. => Application is unpacked in another thread, showing a progress bar : Nice but the progress bar but user has to wait for 3 min after progress bar reaches 100%...

A nice iPad style icon for my app and it will be ready for the Android market (early beta stage though). Icon is important as it is the very first thing that will attract users into downloading my app, (although it has already a reputation on its own).

Here we go !

Release on Android market ! Not yet published though. I choose to limit it to large screen because there's no point in letting small screen user access this app and give bad marks.

04/11/2011
App published !
https://market.android.com/details?id=org.libsdl.app&feature=search_result

05/11/2011
Source code is available on GitHub.
https://github.com/kobr4/Lincity4droid
I've never use GitHub before, it really feel easier to use than the ever confusing sourceforge.

10/04/2012
Well well well ! After 6 months, I'm getting back to Lincity to try to improve this Android port to actually reach a satisfying usability level.

Lincity4droid version 1.1

* Touch control are now modified, so that a the user get a visual feedback when placing buildings on the map.
* No more finger scrolling
* Fixed few missing graphics
The user experience with this version should be much better.