Game development for Android (attempt #3)

A while back (9 years it seems, see here) I had the urge to try and create a game in Java after having spent many years of Java development for business, but I’d never developed a game. It turned out OK (final version here), and along the way I abstracted a simple 2d game engine (here).

Inspired by one of the game development panels at Silicon Valley Comic Con last weekend, I’ve picked up a copy of  Android Game Development by Example by John Horton, and now off I go 😉 I’ll report back in a couple of weeks…

Installing Arch Linux as a VirtualBox Guest

Arch Linux is probably the first Linux distro I’ve come across that does not have a graphical installer. It boots from the iso and drops you straight into a shell.

Ok. Once you’ve realized this then the install instructions make more sense.

To install in VirtualBox I created an 8GB disk. Once booted from the iso, at the shell I used fdisk to partition 2 partitions, one 6GB for / and one 2 GB for /home, following the steps from this post.

In summary, the steps were:

  • p – create primary
  • 1 – 1st partition
  • enter for start position default
  • +6G for end point 6GB from start
  • p next primary
  • 2 – 2nd partition
  • enter for default start
  • enter for end at end of available space

p shows the created partitions, which ended up looking like this:

w to write the partitions and exit.

Next format the two partitions:

mkfs.ext4 /dev/sda1

mkfs.ext4 /dev/sda2

Mount and start the install!

At this point, pick up from the remainder of the instructions in the install guide and beginners guide.

When attempting to install grub, I got these errors:

Per this post (and here), looks like my repo databases needed to be created/updated? I ran

pacman -Syu

and this looks like it fixed my pacman database issue, but now at this point it looked like I’d ran out of space on /, but going back through the install docs, I didn’t do the

arch-chroot /mnt /bin/bash

step so looks like I was installing to the / on my iso live boot? Anyway, did arch-chroot,
and now re-running the command to install grub now worked.
Next steps:

grub-install --recheck /dev/sda
grub-mkconfig -o /boot/grub/grub.cfg

Remaining steps:

  • Set root’s password: passwd
  • Exit chroot
  • Unount drives:
    umount -R /mnt
  • reboot

Remove the iso in VirtualBox, and restart – whoah, Arch is installed! Now time to install X and a window manager! Next steps depending on what you intend to use Arch for are covered in the general recommendations guide.

Create a user:

useradd -m -G wheel -s /bin/bash username

Use password username to set password.

Network config

Network setup guide is awesome!

Add name servers to /etc/resolv.conf (e.g. for Google nameservers)

nameserver 8.8.8.8
nameserver 8.8.4.4

Start and enable dhcp services to start at boot:

systemctl start systemd-networkd.service
systemctl enable systemd-networkd.service
systemctl start systemd-resolved.service
systemctl enable systemd-resolved.service

Check adapters: ip link – get name of VirtualBox adapter, will be something like enp0s3

Edit /etc/systemd/network/wired.conf, add:

[Match]
Name=enp0s3
[Network]
DHCP=ipv4

Start and enable dhcpcd.service:

systemctl start dhcpcd@enp0s3.service
systemctl enable dhcpcd@enp0s3.service

… where enp0s3 is your VirtualBox network interface.

At this point you should have network connectivity – check by pinging www.google.com

 

 

Implementing simple sort algorithms in ARM Assembly (part 3)

I finished the first rough version of my simple sort algorithm in ARM Assembly (see part 1 and part 2 of my updates). Here it is so far (prior to some cleanup and optimization):

[code]
/*
R0 address of string used with printf ti output %d
R4 address of numbers to sort
R5 current number to be compared
R6 offset index for outer loop through numbers
R7 offset index for inner loop
R8 current smallest identified value
R9 current offset index of next uncompared value
*/
.global main
main:
push {ip, lr}
MOV R6, #0 @outerloop offset to numbers to be sorted
MOV R7, #0 @innerloop offers to number to be sorted
MOV R9, #0 @init value for index to next uncompared value
outerLoop:
MOV R8, #99 @reset large default for next loop comparison
MOV R7,R6 @copy outerloop offset to next starting offset for the innerloop
innerLoop:
LDR R0, =output @load addr of output string
LDR R4, =nums @load addr of nums to compare to R4
LDR R5,[R4,R7] @load current num to R5 from R4 with offset R7
MOV R1,R5 @move num for output
BL printf
CMP R5,R8 @is current < smallest so far
BLT swapSmallest @if true, swap smallest to current first position then continue
continue:
CMP R7,#16 @ 0 plus 4*4bytes for 5 entries in array
ADD R7, R7,#4 @inc offset by 4 bytes
BLT innerLoop
continueOuterLoop:
CMP R6, #16 @check if we’ve looped through all values
ADD R6, R6, #4
BLT outerLoop @if not, branch back to start of outer loop
_exit:
POP {ip, lr}
resetLoopOffsets:
MOV R7, #0 @reset loop counter
writeFinalSoredList: @TODO: this is a near copy of the innner loop – refactor this to function
LDR R0, =writeSorted @load addr of output string
LDR R4, =nums @load addr of nums
LDR R5,[R4,R7] @load current num to R5 from R4 with offset R7
MOV R1,R5 @move num for output
BL printf
CMP R7,#16 @ 0 plus 4*4bytes for 5 entries in array
ADD R7, R7,#4 @inc offset by 4 bytes
BLT writeFinalSoredList
doExit:
MOV R1, #0
MOV R7, #1
SWI 0
swapSmallest:
MOV R8,R5 @keep copy of smallest in the current loop
LDR R10, [R4,R6] @tmp copy first position to R10
LDR R11, [R4,R7] @tmp copy value in position currently being compared
STR R10, [R4, +R7] @swap first position value to current position being compared
STR R11, [R4, +R6] @swap the current smallest value into the current first position
BX lr @return
.data
nums:
.word 5,2,7,1,8
output:
.asciz "%d\n"
writeSorted:
.asciz "%d\n"
[/code]

Complete source if you want to grab a copy is in github here.

To get this far I learned plenty about ARM architecture – over time it has evolved and there are many different versions, and different ARM based CPUs implement different architecture versions. To make things more complicated, the naming scheme is a bit confusing.

The ARM CPU in the Raspberry Pi is a Broadcom BCM2835 System on a Chip (SoC), which includes an ARM1176JZF-S (ARM reference manual here). This is an ARM11 core, based on ARMv6 architecture.

Interest points about the ARMv6 instructions (not a comprehensive summary, but some rough notes to refer back to later):

  • The majority of instructions are structured ‘instruction destination, source’ but the STR (Store) for some reason is reversed so it is ‘instruction source, destination’
  • LDR (Load Register), can take a source as a label to a constant, or prefixed with ‘=’ which takes the address in memory where the constant is located.
  • LDR can move the value that is pointed to by an address in another register, using [Rn], and can also be coupled with an offset as a second argument, [Rn, Rm]

I’ll probably spend some time to see if I can clean up the code some more, but I’m happy with this so far.