Why are we still storing source code in text files?

Whenever I have what seems like an original idea I half expect someone to tell me it was done 10 years ago and point me to the github repo. I’m going to go out on a limb and write it up anyway.

Programming is often collaborative now. People work in parallel on the same code base and periodically merge their changes back together into a single application. Source control tools have evolved to support this workflow, and while they do it very well, merging can still often be a messy, manual and error prone process.

Some code changes are particularly problematic. Renaming a variable can affect multiple lines of text. Moving things around inside text files (blocks of code, functions/methods) make it difficult for text comparison tools to match up the source lines against the original source file. Source code beautification tools can reformat your entire code base, making the change diff light up like a Christmas tree (without actually changing any code).

So this got me thinking. For a while I wondered if diff/merge tools could be made smarter and more language aware, so that they could ignore formatting that didn’t change the meaning of the code.

But then I decided the real problem was: text files.

What’s wrong with text files?

My beef is this: program code in text format mixes different concerns into one single file.

Diff/merge tools can’t separate these concerns so they and just perform a line-by-line text compare/merge. This leads to more merge conflicts, manual checking and errors than would otherwise occur.

Consider this code I pulled out of a random source file:

int Basic4GLEditor::GetWatchIndex(QListWidgetItem* item)
{
 int index = GetListItemIndex(ui->watchList, item);

 // Note: Last watch item is dummy blank one (can be double clicked to create a new item).
 // Treat it as "no item clicked"
 if (index == ui->watchList->count() - 1)
 index = -1;

 return index;
}

void Basic4GLEditor::InternalValToString(vmValType valType, std::string& result)
{
 int maxChars = VM_DATATOSTRINGMAXCHARS;
 result = vm.ValToString(vm.Reg(), valType, maxChars);
}

There are a number of concerns mixed together:

  1. We have two methods which define how the code is called externally.
  2. We have instructions which tell the computer what to do.
  3. The methods have a particular order.
  4. We have whitespace mixed throughout to indent it and lay it out.
  5. We have internal variable names (“index”, “maxChars”).
  6. We have comments documenting what the functions do.

(And there are concerns like parameter names, but this should be enough to illustrate…)

To illustrate the problem, imagine that Bob checks out the code and renames one of the local variables:

int Basic4GLEditor::GetWatchIndex(QListWidgetItem* item)
{
	int watchIndex = GetListItemIndex(ui->watchList, item);

	// Note: Last watch item is dummy blank one (can be double clicked to create a new item).
	// Treat it as "no item clicked"
	if (watchIndex == ui->watchList->count() - 1)
		watchIndex = -1;

	return watchIndex;
}

At the same time, Mary checks out the original code refactors it a little and adds some logging.

int Basic4GLEditor::GetWatchIndex(QListWidgetItem* item)
{
	int index = GetListItemIndex(ui->watchList, item);

	// Note: Last watch item is dummy blank one (can be double clicked to create a new item).
	// Treat it as "no item clicked"
	if (index + 1 == ui->watchList->count())
		return -1;

	Log("Watch item clicked: %d", index);

	return index;
}

Committing both sets of changes back to source control will result in a merge conflict between the two lines of code in the if statement, which must be resolved manually. Further more the person resolving the conflict will have to recognise that neither Bob’s nor Mary’s code is now correct. The correctly merged code is Bob’s variable rename applied to Mary’s code.

Furthermore Mary’s new logging line will be merged in automatically as it is simply an insert. But this causes an even bigger problem, because it still refers to the local variable by it’s old name “insert” the line is no longer correct. But the merge tool has no way of knowing this, and will quietly insert the new line without protesting. The problem will only be discovered later when the code is compiled.

An alternative to text files

Let’s try a different format for storing source code and see if it helps us in this scenario. Instead of a plain text file, let’s try organising the code into a key-value table.

First we’ll add the method declarations:

Key Value
MTHD_00000_NAME Basic4GLEditor::GetWatchIndex
MTHD_00000_PARAMS QListWidgetItem* item
MTHD_00000_BODY INSTR_00000
MTHD_00001_NAME Basic4GLEditor::InternalValToString
MTHD_00001_PARAMS vmValType valType, std::string& result
MTHD_00001_BODY INSTR_00100

Then we’ll add the instructions:

Key Value
INSTR_00000_CODE int [VAR_00000] = GetListItemIndex(ui->watchList, item)
INSTR_00000_NEXT INSTR_00001
INSTR_00001_CODE if ([VAR_00000] == ui->watchList->count() – 1)
INSTR_00001_BODY INSTR_00002
INSTR_00001_NEXT INSTR_00003
INSTR_00002_CODE [VAR_00000] = -1
INSTR_00003_CODE return [VAR_00000]
INSTR_00100_CODE int [VAR_00001] = VM_DATATOSTRINGMAXCHARS
INSTR_00100_NEXT INSTR_00101
INSTR_00101_CODE result = vm.ValToString(vm.Reg(), valType, [VAR_00001])

I’ve also taken the liberty of replacing the local variables with [VAR_xxxxx] references. So lets add them as key-value pairs as well:

Key Value
VAR_00000_NAME index
VAR_00001_NAME maxChars

OK, so this is not a very human readable or maintainable format, but writing an editor which can read this format and transform it into human-readable source code would not be impossible.

The key of each entry is built from its type, a unique ID, and an attribute. (E.g. VAR_00001_NAME stores the name of the variable with ID 00001). For simplicity I’ve used an incrementing number for the ID, but a real implementation should be something globally unique (like a GUID).

An important characteristic of this format is that the keys are unordered. To achieve this I’ve linked the instructions together with a NEXT attribute to form a forward chained list. The “if” instruction also has a BODY link, which links to the body of the if statement.

This also means that braces and semicolons are no longer necessary to denote code blocks and terminate instructions, so I’ve left them out.

Merging changes

With an unordered key-value store diffing and merging are quite simple:

  • Any new key is an insert.
  • Any missing key is a delete.
  • Any entry with the same key whose value has changed is an update.

And because keys are unique and the order doesn’t matter, it is trivial to match up entries.

Merging two change sets involves applying the inserts and deletes, then looking for updates to the same keys – which are your merge conflicts.

So let’s consider Bob and Mary’s changes in the context of this format.

Bob’s variable rename is simply:

Operation Key Value
UPDATE VAR_00000_NAME watchIndex

All the instructions refer to the variable via it’s ID, which doesn’t change, so the instructions remain unaffected.

Mary’s changes are a bit longer:

Operation Key Value
UPDATE INSTR_00001_CODE if ([VAR_00000] + 1 == ui->watchList->count())
UPDATE INSTR_00001_NEXT INSTR_00004
UPDATE INSTR_00002_CODE return -1
INSERT INSTR_00004_CODE Log(“Watch item clicked: %d”, [VAR_00000])
INSERT INSTR_00004_NEXT INSTR_00003

Essentially we update 2 lines of code and insert another, which requires changing the “NEXT” links to ensure the new line ends up in the right place.

To merge these two changes sets is straightforward. None of these keys conflict with each other, so there are no merge conflicts. And because Mary’s changes and insertion all refer to the local variable via it’s ID they remain correct even after the variable is renamed.

The result is a clean merge and a correct program with no manual intervention.

Is this a silver bullet?

Of course not.

There will still be nasty merge conflicts, and difficult scenarios requiring a programmer to think hard about what each change set is trying to do.

But it does suggest that if we start thinking about other ways to break down the source code storage into a format that more cleanly separates concerns, we will make the merge tool’s job a lot simpler and decrease the likelihood of conflicts.

In this case we separated a variable’s name from a reference to that variable inside instruction code, which made renaming the variable a small isolated change. In fact there’s a good argument for applying this to all identifiers (method names, parameter names, class names etc) so that anything can be renamed cleanly and simply.

And there are other scenarios where this kind of approach helps, such as moving a block of instructions up or down within a function/method. As long as the IDE preserves the IDs of each instruction then the change is essentially just adjusting the linkage between a couple of instructions. If someone else concurrently edits one of the lines in the block you’ve moved, then the merge of your changes will include his edit to the line in the new position. This is something that text file based merge tools have difficulty with.

Parting thoughts

Tooling

If this approach (or something similar) was followed through and a format created captures everything we wanted to capture about program source code, it would still need tooling support.

The IDE in particular would need to understand the format and translate back and forth between it and what is displayed on screen to the programmer, and do so in a way that preserved the IDs of instructions across including when cut, pasted, copied and deleted.

Source control systems would need to understand the format as well. This should be straightforward to implement internally, but conveying information to the user in a meaningful way would require some thought and design (how would you show a variable rename merge conflict for example?).

Discarded information

I deliberately discarded white space and ordering of methods from my example above.

There are ways to fit them in I’m sure, but it’s worth stopping to think about whether it’s really necessary?

By removing white-space:

  • You discard a whole heap of information that doesn’t affect the program at all, and all the possible merge conflicts that come with it.
  • You avoid holy wars between programmers trying to establish a common formatting standard. (Each programmer can choose whichever standard they prefer).
  • You also avoid pull requests from someone who’s reformatted your entire code base with their favourite code formatting tool.

The IDE can re-insert white space, new lines, braces and semicolons automatically when translating it back to a human readable format, using whatever style conventions the programmer prefers.

MAKE tools

One advantage of having a format that separates program code information is that it’s easier for MAKE tools to determine when a change actually affects the compiled code. If you’ve ever sat there for a few minutes while the compiler rebuilt all your source files because you change the comment in a common header file then you get what I mean.

If comments are cleanly separated from actual code, then the MAKE tools can simply ignore the comment change and recompile only when entries that affect the compiled code are modified.

This also holds true for white-space changes, function ordering etc.

In fact you could arguably say that renaming a variable doesn’t affect the compiled code. There are some caveats to this, such as run time type information and debugging symbols, but it’s not ridiculous to envisage such information being split into two pieces: The debugging/RTTI information references variables via their internal ID, and a separate lookup structure then gives the variable name. In which case renaming a variable would only require rebuilding the ID->name table, which would often be significantly faster than recompiling the affected modules.

Posted in Ideas, Uncategorized | Tagged , , | Comments Off on Why are we still storing source code in text files?

Basic4GL Mobile road map

Just a quick jot down of my plans for Basic4GL Mobile.

By the way an early version has been released. It’s fully functional (if lacking a bunch of features), so if you fancy writing some BASIC and running it on an Android phone/tablet quickly and (relatively) easy: http://basic4gl.net/mobile/

Anyway, the plan is:

  1. jpeg loading
  2. Sound and music playback (using OpenSL)
  3. File I/O
  4. Other sensors (tilt/accelerometer etc)
  5. Function pointers
  6. Creating an apk for the Google Play store (pro version)
  7. Integrating the Windows IDE with the Android runtime, so the IDE can push updated files directly to the phone/tablet without requiring a 3rd party application. This would also lay the groundwork for remote debugging.

1, 2 & 3 would more or less give it the 2D facilities to match the original Basic4GL, making it a fully feasible program for developing/prototyping 2D games.

Function pointers looks a bit out of place, but I need it to port one of my Basic4GL 2D games which relies heavily on runtime compilation, and a rather non-standard way of discovering and executing the functions in those scripts. I don’t want to implement runtime compilation in Basic4GL Mobile and lump the compiler into the Android runtime, but I do need something to replace the script function call mechanism. I’m currently researching function pointer syntax in BASIC languages. I may settle on something like Visual Basic’s “delegate” and “addressOf” keywords.

In parallel to the above I also want to create some how-to videos and build up a standard library of BASIC include files, particularly for things like on-screen joysticks and swipe input.

Posted in Uncategorized | Comments Off on Basic4GL Mobile road map

Cyberspace using voxels

This is a somewhat unrefined brain-dump of an idea that’s been developing in my brain for a while.

It has a bit to do with voxels. Not really anything to do with Basic4GL.

(It also tests pasting markdown into WordPress.)

The idea

Imagine if the Internet was one massive 3D world, distributed across thousands of servers, where you could stand on a hilltop and look across that world in its entirety. Imagine if your favourite online games were part of this larger world. You could join them just by walking (/driving/flying) up to them. Or you could see what’s available just by walking around and exploring.

I believe this is technically possible.

I’m going to explain how in a basic question-and-answer format, because, frankly, I can’t think of a better way.

It will require voxels.

How would this work?

(I’m going to refer to the “one massive 3D world” as “cyberspace”.)

Cyberspace would be divided into smaller virtual volumes, which connect together. Each volume would be hosted by its own server, which stores and serves up 3D content. Cyberspace would be experienced through a client application which downloads and displays this 3D content.

So the client downloads “3D content” from every server?

No. The client would find the server whose volume contains your current position in cyberspace, and download from that one only.

But how can you “look across that world in its entirety” if you only have 3D content from one server?

Each server would store a copy of the whole of cyberspace as viewed from within its volume. The client would download and displays this.

So to build up this “copy” each server has to fetch the 3D content from every other server?

No. Each server would talk only to its adjacent neighbours, and ask “What’s in your direction?”. After enough iterations every server would eventually have a complete picture.

But wouldn’t the data become far too large to transmit, download and render? You said “thousands of servers”.

Each server need only store the 3D content required to render cyberspace from within its own volume. This places an upper limit on the amount of information each server needs to store, in two ways:

  1. Level-of-detail. Servers can drop unnecessary detail from far away content.
  2. Content-at-infinity. Each server manages a finite volume of space. There is a distance beyond which any content will appear the same when viewed from any point within that volume. This content can be represented by 2D “skybox” textures.

What format would this 3D content take?

Servers would store their original 3D content in whatever format they wish (some sort of textured polygon mesh being the most likely).

The content must be converted to voxels before being transmitted to neighbouring servers.

The client would download the original 3D content from the current server as well as the voxels representing the content outside of the server’s volume, and combine them together to produce the final image.

Why voxels?

To share 3D content between servers a common format must be agreed upon. Voxels have the advantage that they are very easy to down-sample, which is required for level-of-detail management. They are also relatively easy to generate from polygon meshes.

Graphics hardware has reached the point that it can ray-cast sparse voxel octrees in real-time.

The main limitation of voxels is that they can quickly get expensive (in terms of storage) at finer detail levels. To avoid this, we use the original 3D content (e.g. polygons) for the close up content (inside the current server’s volume), and only use voxels for the far away content.

It may be that a full voxel model with enough detail for a 1080p monitor may still be too cumbersome for current network speeds, in which case we will need to work with lower detail versions, meaning voxel content will look a little blurred/low res. But network speeds are increasing all the time.

What sort of client would this use?

There would be one generic “browser” type client which accept a general textured polygon mesh format. Perhaps with some basic scripting support and low latency networking for receiving position updates for moving objects etc. This would cover general purpose virtual areas, and would be enough for walking around, virtual stores, maybe some basic gaming.

High budget games would have their own clients, with their fancy next-generation graphics engines, networking code etc. They would pretty much function the same way they currently do, except that they will also support downloading the voxel model of rest of cyberspace and rendering it behind the local content.

When the user walks up to the server’s volume in cyberspace, the generic client will negotiate with the server whose volume they are transitioning into whether they are allowed to proceed and which game client it needs to launch and pass control over to.

What if the user doesn’t have the game client installed?

Then they can’t enter the volume and join in the game until they buy it and install it. Pretty much the same as it is now (except they can look in from the outside).

Having said that some games may choose to support a secondary form of access, using the generic client’s protocols and 3D mesh format. Consider an online racing game that allows people who don’t have the game installed to walk in and watch from the stands or over-bridges for example. They wont get to see the content rendered with the game’s cutting-edge graphics engine, but some developers may still see some merit in this (building community, advertising, e-sports).

How would this get started?

To get this off the ground would require the following:

  1. Work out and document the technical details, such as:
    • The format for the voxel data, which may differ based on whether they are stored on server, being sent across the wire, or stored in the client GPU memory for rendering.
    • Network protocols for server-server and server-client communication.
    • Level of detail. For best results voxels should be small enough to project to a single pixel. How small this is depends on the display resolution and field of view. An initial target resolution and FOV needs to be established and applied across all servers.
    • … And a whole bunch of other stuff.
  2. Create a proof of concept, with some networked servers sharing content and a basic client. Spread the word around. Invite people to download the client and connect to it, or host their own server and add to the 3D world.
  3. Maybe try to find an existing game developer who is willing to integrate their game client into the new cyberspace world.
  4. Grow and improve the specification.

 

Posted in Cyberspace, Ideas, Miscellaneous, Sparse Voxel Octree | Tagged , , , , , , | 2 Comments

Basic4GL v2.6.0 released

You heard right! There’s been a new Basic4GL release for the first time in nearly 6 years.

Grab it from the Basic4GL website.

What’s new

This release is mainly about refreshing the IDE, and updating third party libraries to modern, open source versions, so that Basic4GL itself can be open sourced under the BSD license. There’s a new Qt editor, the OpenGL window management uses GLFW, and the whole thing can be built using Visual Studio Community edition.

You can download the source from here for now.

B4glDesktop

The demo programs are now installed to the all-users documents folder, to comply with Windows User Access Control (UAC) rules (so WriteFileDemo.gb actually works on Vista and later).

I’ve also put a bit of effort into cleaning up the help files and bringing them up to date.

And there are a couple of new commands as well. Check the Programmers’ Guide for UpdateWindow() and OpenAppDataRead()/-Write().

Breaking changes

There are some breaking changes in this version to be aware of.

Support for Windows XP and earlier operating systems has been dropped (mainly because this version is built with Visual Studio 2013, and also possibly due to 3rd party library minimum requirements).

OpenGL software mode is not supported in this release (although it may be added back later – depending on if/when GLFW implements a software mode window creation hint).

Finally, debugging applications in full-screen mode doesn’t work all that well. There seems to be issues switching back and forth between the desktop and full screen window (you often need to hit Alt-Tab a couple of times to help it out). I’m hoping to sort this out in a future release. Until then it’s much less hassle to use a windowed mode while debugging.

 

Anyway, let me know if there are any issues. Otherwise enjoy.

 

Posted in Uncategorized | 5 Comments

Basic4GL Qt IDE

I’ve started rewriting the Basic4GL IDE using Qt. Mainly because I want an open source UI library, but there’s also the added benefit of it looking slightly more modern.

Here’s what I have so far:
Basic4GLIDENew

For reference the current released Basic4GL looks like this:
Basic4GLIDEOld

 

I plan to use the Qt version to create a dedicated IDE for Basic4GL Mobile as well, which will use the Basic4GL Mobile Windows platform runtime to ensure the same BASIC commands are available as in the Android runtime.

It all builds on Visual Studio 2013 Community Edition, so once it’s up on Github (or somewhere), people will be able to build the full Basic4GL including IDE using freely downloadable libraries and tools.

Posted in Uncategorized | Comments Off on Basic4GL Qt IDE

Run your own Basic4GL code on Android

I’m very excited to announce the first Basic4GL Mobile release which you can actually run your own Basic4GL code.

Please keep in mind this is a very early development release. Don’t be surprised if a lot of BASIC commands haven’t been implemented yet.

You will need

  • An Android phone or tablet, running Android 4.4 (Kitkat) or later.
  • A Windows PC with Basic4GL installed (from the Basic4GL website).
  • The Basic4GL Mobile Android apk, download from here.
  • The Basic4GL Mobile Windows tools, download from here.
  • A way to copy files from your PC to your Android device.

For the last one, you can share a folder on your PC and pull files across using an Android file tool like “ES File Explorer”. Or you can setup a Google Drive/Dropbox folder and sync it with “FolderSync” or similar app (the “Lite” add-supported version works fine). I personally find the Google Drive/Dropbox option simpler once setup.

Getting started

Step 1 – Install the apk

First install the apk onto your phone/tablet (from here). Because this not a pristine validated app from the Play store you’ll need to enable “Allow installation of apps from unknown sources” (or similar) which is in Settings->Security (on my phone at least).

Once it’s installed, run it:Basic4glmobile2

 

It will tell you it cannot find the Basic4GL program.vm file.

More importantly it will tell you where you need to put the program.vm file (and any other files the program needs like image files).

For a lot of Android devices this will be:

/storage/emulated/0/basic4gl

But check what appears on screen.

Step 2 – Install the Windows tools

Next download and unzip the Windows tools (from here) onto your PC.

This will create two sub-folders: “Windows” and “Programs”

Inside the “Programs” sub-folder is where you create your Basic4GL program, compile it, test it and finally transfer it across to the Android device.

We’ll demonstrate by compiling the snakedemo.gb program and running it on Android, as follows:

  1. Open the “Programs” sub-folder in Windows explorer
  2. Drag the snakedemo.gb file onto the Compile.bat batch file.
  3. This invokes Compiler.exe in the “Windows” sub-folder to compile it, creating (or replacing) program.vm.
    “program.vm” contains all the op-codes and other data required to run the program on the Basic4GL virtual machine.
  4. Double click “Run.bat” to test run it using the Windows platform runtime.
  5. Copy “program.vm” to the basic4gl folder on Android.

There’s a bunch of different ways to do this and different apps you can use. I happen to use FolderSync Lite, because it’s the first one I happened to find that does the job,  but there’s bound to be others. To do this I dragged the Windows tools into my Google Drive folder, then used the FolderSync app to synchronise the “Programs” sub-folder to the “/storage/emulated/0/basic4gl” folder on my Android device (which could be a different folder on yours remember – check the original message).

Once that’s done, run Basic4GL on your Android device and play snake.

You may want to try AsteroidDemo2.gb as well. For this one you need to also transfer the “Data” sub-folder and all the image files it contains.

Running your own code

If you managed to get the above working, you can run your own code.

First you should copy “mobile.dll” and “msvcr120.dll” from the “Windows” sub-folder into your Basic4GL folder (where Basic4GL.exe lives). This adds a bunch of mobile commands to Basic4GL for things like handling touch screen events. Some of them don’t actually do anything when running in Basic4GL itself, but at least Basic4GL won’t stop with a syntax error when it sees them.

Note: Make sure to copy the files, not move them, because Compiler.exe needs them as well.

To access the commands in Basic4GL, click “File->Plug in Libraries…” and tick “Mobile.dll” which should now appear.

Save your program in the “Program” sub-folder. When you’re ready to try it on Android, follow the steps from before, to compile, test run and transfer it.

Limitations

You’ll probably run into the limitations pretty quickly. Basic4GL Mobile currently has implemented:

  • Standard BASIC functions (val, mid$, len etc)
  • Vector and matrix algebra
  • Text input/output
  • Sprites and tilemaps
  • PNG texture loading (using LoadTex. The old LoadTexture routines aren’t and won’t be implemented)
  • Mouse input (emulated on Android)
  • Timing (WaitTimer, SyncTimer etc)

There’s a bunch of things that haven’t been implemented yet, such as:

  • JPG image loading
  • Sound/music
  • Anything OpenGL
  • Anything in a plugin DLL

Basic4GL itself doesn’t know what’s implemented and what isn’t, so you’ll typically only know when you attempt to run it using the Windows platform runtime (by double clicking “Run.bat”).

This is one of the reasons for the Windows platform runtime, rather than just running everything in Basic4GL itself, as it has been developed in parallel with the Android platform runtime and has the exact same BASIC commands. If it runs on the Windows platform runtime then you can be reasonably confident that it will on Android. If not, it will tell you the BASIC function that it doesn’t recognise so you can update your program. The Windows platform runtime also has the same new character set that Android uses, and some basic touch input emulation using the mouse.

Mobile functions

This is as good a place as any to document the new mobile functions.

You can also see these in the Mobile.dll plugin “Functions” list in Basic4GL.

Miscellaneous

BackgroundColor(red,green,blue)

Sets the background colour. Because Basic4GL Mobile doesn’t support OpenGL commands you can’t use glClearColor(). red, green and blue are colour component intensities ranging from 0-255.

Platform info

PlatformName$()

Returns “Windows” on Windows and “Android” on Android.

PlatformIsMobile()

Returns false (0) on Windows and true (-1) on Android. The asteroid demo uses this to decide whether to display the touch screen controls for example.

PlatformIsDesktop()

Returns true (-1) on Windows and false (0) on Android.

Single touch

Note: This is a simplified interface if you’re only interested in single touch events.

Alternatively you may find it easier to use the standard Basic4GL mouse input commands. On Android the mouse is emulated based on touch screen events.

Touching()

Returns true (-1) if the user is currently touching the screen, or false (0) otherwise.

TouchX(), TouchY()

Returns the position of the touch. 0 is the left/top edge of the screen. 1 is the bottom/right edge.

If the user is not touching the screen, this returns the position that they were last touching.

TouchStartX(), TouchStartY()

Returns the position where the user started touching the screen.

Multi-touch

Multi-touch is handled by allocating a unique “touch ID” number to track every time the screen is touched. This number is used to lookup the information about that specific touch instance, such as it’s position, and whether it’s still touching.

NewTouchID()

Much like inkey$() returns keypresses, NewTouchID() returns touches.

Returns 0 if there are no new touches. Otherwise returns the “touch ID” of the new touch.

Touching(touchID)

Where touchID is a touch ID returned by NewTouchID. (Or TouchID() below).

Returns true (-1) if the user is currently touching the screen, or false (0) otherwise.

TouchX(touchID), TouchY(touchID)

Returns the position of the touch.

The application tracks all active touches, plus the last 16 that are no longer touching the screen, which should give the BASIC program enough time to read the position where the user’s finger was last before it was lifted from the screen.

TouchStartX(touchID), TouchStartY(touchID)

Returns the position where the touch started.

TouchCount()

Returns the number of active touches

TouchID(index)

Returns the touch ID of the indicated active touch.

index should be between 0 and TouchCount()-1 (inclusive).

Keyboard input

These are methods for controlling the on-screen keyboard.

The on-screen keyboard is managed automatically for the BASIC INPUT command (input “What is your name”; name$ etc), but you may want to bring it up explicitly if you are using Inkey$() to read key presses.

Note: On screen keyboard handling is not great on Android, mainly because the application cannot detect when the user closes the keyboard manually. It also cannot explicitly tell Android whether to show or hide it, only whether to “toggle” it. These functions therefore return whether the application thinks the on-screen keyboard should be visible, and will toggle the keyboard when it thinks it needs to be shown/hidden.

ShowKeyboard()

Shows the on-screen keyboard

HideKeyboard()

Hides the on-screen keyboard

IsKeyboardShowing()

Returns true (-1) if the on-screen keyboard is currently showing, or false (0) otherwise.

Posted in Android, Basic4GL, Development blog | Tagged , , , | Comments Off on Run your own Basic4GL code on Android

Basic4GL on Android – Text and Sprites

Things are starting to take shape with the Android version of Basic4GL mobile.

basic4glmobile(You can download an apk of the above demo here)

Implemented so far are:

  • Standard BASIC functions (string, maths functions etc)
  • Vector and matrix algebra
  • Text input/output
  • Sprite routines
  • Touch input
  • Texture loading (png only for now)

It’s enough to write some 2D games with, albeit without sound yet.

I’d like to release a development version for people to play around with. However I don’t want to give away the source code at this stage, so people won’t be able to create their own Android apps just yet.

Instead my plan is to add logic to synchronise a folder over the network. This folder will contain the compiled Basic4GL op-codes, plus any assets it might use (graphics files etc). The idea is you create something in Basic4GL. When you’re ready to try it on your Android phone/tablet, you run the Basic4GL mobile app, then run a little sync program on your computer and point it to the folder where you’ve saved your Basic4GL program. The folder is synchronised over to a folder on your device, the Basic4GL app detects this, loads and runs your compiled Basic4GL program with all the asset files available.

This would have the added advantage that you don’t need to install the Android SDK, USB driver, NDK or even Java. All you need is your PC and Android device on the same network.

To (eventually) create your own apk that you could upload to the app store would require the Android SDK (& NDK etc), plus the compiled Basic4GL Android engine, which I’ll probably eventually release as libraries and header files. This would be the bit that I’m planning to sell. So essentially you can develop a game/program in Basic4GL for free, even test it on your Android device(s) for free. But to create an apk that you’ll need to buy something. I think that’s pretty fair…

Posted in Android, Basic4GL, Progress, Uncategorized | Tagged , , , , | 1 Comment

Basic4GL on Android – Text output

More progress:

basic4mobile3

 

This is now a fully native Android application, using OpenGL ES 2 for the display.

I’ve ported the OpenGL text grid and re-implemented the corresponding BASIC text functions (print, locate, cls, color etc). I can now run simple non-interactive text programs, like this maze generator which I dug out of the Basic4gl forums.

My next goal is to get some basic interactive text programs working, like the “Snake” demo. For this I need to think about how input is going to work. A lot of mobile games have an on screen d-pad/joystick and buttons for directional input and I had considered building in something similar, but I think I’ll just expose the touch input API and implement some examples in BASIC code. The Basic4GL “include” mechanism works fine for building up a library of standard functions in BASIC itself.

However adding new builtin functions introduces a new problem: Basic4GL won’t recognise them so you can’t compile and test your program. The solution will be to create a plugin DLL containing the new functions to use with Basic4GL. The functions will either do nothing or emulate the mobile functions where appropriate, like using mouse input to emulate touch input.

Last thought for now – I’m probably going to name this “Basic4GL Mobile”. I had been thinking of Basic4Mobile, or Basic4Android, but it turns out Basic4Android has already been used (b4x.com), and Basic4Mobile is too similar (imo). “Basic4GL Mobile” is a bit of a mouthful but it should be a safe bet that it’s not in use and won’t be confused with somebody else’s product.

Posted in Android, Basic4GL, Development blog | Comments Off on Basic4GL on Android – Text output

Basic4GL on Android – Standard BASIC functions

 

 

Another step closer to getting a Basic4GL program to run on Android.basic4mobile2

I’ve converted the standard BASIC function library to use the plugin library registration method, and split it into general and a small amount of Windows specific code that needed to be rewritten for Android.

The failed test in the middle raises an interesting question though – does Basic4GL use C or C++ strings? It seems like it’s not too sure actually. Internally it uses C++ strings, but the library function mechanism accepts and returns C strings.

The difference is that C strings are zero terminated, while C++ strings can happily contain ASCII zero characters. chr$(0) results in a valid 1 character C++ string, but the library functions will assume the 0 character is the terminator and treat it as an empty string.

I may clean this up properly someday, but for now it’s enough to go on with.

Next on the list: Converting the OpenGL text view.

Posted in Android, Basic4GL, Progress | Tagged , , , , | Comments Off on Basic4GL on Android – Standard BASIC functions

Basic4GL on Android

A break from the sparse voxel octree stuff…

This is probably the first significant thing I’ve done with Basic4GL in years.

basic4mobileWhat you can see is the result of Basic4GL op-codes running on the C++ Basic4GL virtual machine which runs natively on Android by virtue of the Android Native Development Kit (aka NDK).

I built a basic virtual machine run-time, into which you feed the compiled Basic4GL program, and compiled it on Android NDK. I had to add some symbolic information about which Basic4GL runtime functions it calls and a basic “link” step to wire them up to the corresponding runtime functions that the Android VM implements. The idea is that the Android VM runtime doesn’t need to implement all the Basic4GL functions to start with. In this test it only implements “print” and “printr”, but it’s enough to prove that the VM executes the code correctly, and gives something to work with while the rest of the functions are built up.

Eventually I want to build it up close to the feature set of Basic4GL, so you could write an debug something in Basic4GL until you’re happy with it, and then deploy it to Android. And there’s no reason why the same approach couldn’t work for iOS and desktop web browser (via asmjs and emscripten) too.

I’m not quite sure about the OpenGL functions though. Basic4GL supports OpenGL 1.1 – known as “legacy OpenGL” these days. In theory that should map to OpenGL ES 1.1, but how closely I’m not sure. And if I want to run the same code in asmjs using WebGL I’d have to use the emscripten legacy OpenGL emulation. Again I’m not sure how closely that would work. Ideally I’d like an identical experience across PC, Android, iOS and web browser, which would require some common subset of functionality between OpenGL 1.1, OpenGL ES 1.1 and WebGL (with fixed pipeline emulation). But I don’t know whether such a common subset exists and is large enough to be useful.

I still think this would be useful, even without OpenGL 1.1 commands.

It’s also nice to be doing something with Basic4GL again. I felt I’d pushed it as far as it could incrementally, without doing a serious redesign and rewrite (which I just don’t have time for these days). So it’s nice to have a new avenue to pursue.

 

 

 

Posted in Android, Basic4GL | Tagged , , , , | 1 Comment