Monday, March 30, 2015

Roboninja final boss

I haven't touched Roboninja in a little while, but I finally sat down the last couple nights to start on the final big thing: the boss fight.

I don't have much of it yet, but I've got a start at least: a room and a decent enemy graphic.


Now I really need to spend some design/thinking time, to figure out exactly how I want this battle to work....

Tuesday, March 24, 2015

2 more bytes!

I just trimmed down 2 bytes of my ram usage in Atari Anguna. Just saying.

For anyone crazy enough to care how.... I was using 2 bytes of ram to set up an indirect jmp instruction to jump to the subroutine I use to update enemies:

    LDY #6                      ;load the address from the enemy 
                                ;definition into the EnemyUpdateFunc
    LDA (EnemyDef),Y
    STA EnemyUpdateFunc
    LDY #7
    LDA (EnemyDef),Y
    STA EnemyUpdateFunc+1

    JMP (EnemyUpdateFunc)       ;then jump to it

Which means that the 2 bytes for the EnemyUpdateFunc address were only used in this one particular spot. I also found another place where 2 consecutive bytes were only used for a small limited time (temporary variables used to set up the playfield while drawing the health/status header). Combining these 2 to use the same memory knocked TWO WHOLE BYTES off my ram usage. Hooray!

Tuesday, March 17, 2015

Old phone as SSH server

I guess I'm on a kick trying to actually use my pile of old broken-down smart phones.

This time, while I was at work one day and was wanting to access my home network, I was wishing I had a linux machine at home that I could ssh into. My laptop at home is linux, but I don't leave it turned on. The home server is Windows, because it's also my media center, and sadly, Windows Media Center is still the best option for a media center with DVR. I wanted to run a small, light linux machine alongside it, just to be able to get in via ssh from outside, and do whatever from there.

I had a raspberry pi at one point, which would have been perfect, but I sold it. And for things like this, part of the fun is to do it without buying more stuff. So I decided not to buy another pi. I thought about just running a linux VM on the windows machine, but it's already a bit underpowered for what it does (it gets a little slow when watching an HD recording while also simultaneously recording 2 HD shows).

So I dug around in my pile of old phones, and decided to turn one into a proper ubuntu machine. My first attempt was with a Galaxy S. I installed a fairly straightforward chroot'd linux on it, and it was SLOW. I tried doing an apt-get install of mysql, and I gave up after 15 or 20 minutes of waiting during the installation. That phone went back in the bin.

So I pulled out the LG Optimus G E970. It's more-or-less the same hardware as a Nexus 4, so quite a bit better than the old Galaxy S. Unfortunately, it has a busted screen -- the screen turns on and displays properly, but the touchscreen is completely broken. And I didn't have adb/USB debugging enabled before it broke, which has previously foiled any of my plans to do anything with it. But I decided that this time, that wouldn't stop me.

First, I tried the easy solution, and plugged in a USB OTG adapter, which, if a phone supports it, lets it act as a USB host, so I could hopefully just plug a USB mouse in. Nope, no dice. No OTG support.  I have a bluetooth mouse, but how to get bluetooth turned on, and the mouse paired, without USB debugging enabled?

Well, here's what I finally did (with quite a few other mis-steps along the way that I won't bother documenting):


  1. Since the power and volume keys still worked, I could reboot into recovery mode, and work through those menus. So I wiped the current install, and flashed a current version of SlimRom. SlimRom, as it turns out, has USB debugging enabled out of the box.
  2. To disable the lockscreen from adb, I needed root access, which I didn't have. But I read that if you connect adb while in recovery mode, you have full root. So I rebooted again into recovery, connected adb, and thanks to the tips from this post, pulled the /data/data/com.android.providers.settings/databases/settings.db sqlite database off the phone onto my desktop (using the adb pull command), disabled the lockscreen by running the query update secure set value=1 where name='lockscreen.disabled'; and then pushed the file back onto the device. Once rebooted, the lockscreen was disabled.
  3. Next was the tricky part -- blindly stabbing in the dark with adb shell input commands to try to turn on bluetooth and pair with my bluetooth mouse. It took a bit of trial and error, but the solution for my particular phone ended up being:
#swipe down from top:
./adb shell input swipe 100 0 800 100

#tap top right to flip to the tiles settings screen:
./adb shell input tap 750 10

#hit the settings icon:
./adb shell input tap 720 150

#bluetooth toggle on:
./adb shell input tap 720 250

#tap the bluetooth menu:
./adb shell input tap 520 250

#search for devices
./adb shell input tap 600 40

#select the mouse
./adb shell input tap 200 896

After that, my mouse was working! Then it was pretty easy to attach a bluetooth keyboard, install the chrooted linux (the easiest method is to download the Complete Linux Installer from the play store, although there are plenty of bugs in it. If you are playing along at home, here's the bugs I ran into, and their solutions:


  • Clicking "Start Linux" loads the terminal emulator, but nothing happens OR
  • Clicking "Start Linux" loads the terminal emulator, it does a cd and su, and then nothing happens.
Something is broken with the launcher. You need to run the boot script manually. First su, then do sh /data/data/com.zpwebsites.linuxonandroid/bootscript.sh /sdcard/ubuntu/ubuntu.img (adjusting that last bit to wherever you put the linux image)

  • You can't add users (and various apt-get installs also fail because THEY can't add users)
Something in Android's SELinux implementation is breaking things. In a separate terminal, as root, run setenforce 0, which will disable whatever is preventing it, and probably render your device horribly insecure. Oh well.

Once those things got sorted out, I was able to SSH into the phone, and it works just fine as an ubuntu server. It's a tiny bit slow, but nothing unreasonable. It's currently plugged into the media center to stay charged, and a port forwarded on my router to it, so I can access it from anywhere! 

Mission accomplished: one more half-broken phone from my bin has a use!

Tuesday, March 10, 2015

Windows Phone as "notification screen"

I recently bought a low-end windows phone from a coworker for $10, not really having any particular plan for it, but thinking I might be able to do something cool with it. Well, for the past couple weeks, it's just been sitting on my desk collecting dust.

Until a couple days ago, I decided I wanted to try to use it as a sort of 3rd screen at work, where notifications could be shown. I've got a few things (pidgin chat windows, emails, linux desktop notifications) that I want to be aware of, but I sometimes miss. My icon for pidgin changes color when I have a new message, but sometimes it's a hassle to pop it up to the top if it's not important (and it's hard to know if it's important without seeing it!) Thunderbird shows a desktop notification on new email arrival, but that only lasts for a couple seconds; I often miss it, and then I have to go click on it to see if there's mail.  1st world problems, yes. And I'm not sure I really need to fix them. But really, I have a solution (this phone) in search of a problem, so I decided to play with it!

Catching thunderbird messages was the easy part -- there's a great thunderbird extension (Unread Count) that automatically generates a text file that contains information about how many unread messages you have in each mailbox.

For desktop notifications, I did some reading, and it looks like I needed to hook into DBus, linux's inter-process communication channel. Reading through tutorials about how to hook into it, it looked like somewhat of a hassle. So I took the easy route, and used the dbus-monitor command, which generates a text stream of all the information flowing through dbus, and piped it through a python script that just looked for libnotify notifications, and wrote the details I was interested in to a separate file.

While playing with dbus, I noticed that all pidgin messages traveled through it as well, which made it really easy to catch the sender name and text content of the latest message, and write it to a file as well.

Then I have a simple php web script that pulls the info from all these files, and builds a not-too-ugly notification page out of it.

I originally planned to just point the phone's browser to it, and have a meta-refresh on the page, but the windows phone browser kept the status/url bar open the whole time, which was ugly and wasted space. So I ended up writing a windows phone app that was merely a wrapper over a webView that reloaded the page repeatedly. Moving the refresh logic to the phone app also allows for it to keep refreshing even if the web server temporarily dies, which is handy.

So here's the finished product. Who knows if I'll actually ever look at it, or find it remotely useful. That's not really the point here, is it?





Side note: currently I have a private git repo on bitbucket where I keep all my misc rinky-dink projects. Maybe I should just make it public instead, so things like this are available to anyone that wants to look at them. I'll have to think about that. (It would mean I'd be more afraid of my hackish little quick code being judged as terrible, so I'd be nervous about throwing stuff on there willy-nilly)

Saturday, March 7, 2015

Progress

Making progress!

Last night, I've finished the last robo-ninja room before the "flying up high to find Dr Squidbrain" sequence (which is a room or two, then the big boss fight). It's so great to be close to being finished, although the boss fight is going to take a lot of work, a lot of code, and a lot of scrounging trying to find appropriate graphics!

I haven't been doing quite as much with Atari Anguna. (the great thing about having 2 simultaneous hobby projects is that when I get bored of one, I can get excited about the other!) A couple weeks ago I got it to the point where if you killed all the enemies in the right room, a key would appear. You could pick it up, take it to the matching locked door in the a different room, and open the door with it. It's almost like a real game at this point!

But like a said in a previous post, I did the math and realized I'm running out of code space in my primary rom bank. I considered moving a block of code to the 2nd bank (where the kernel and graphics live), but even if I do that, I'm still going to have to sacrifice a number of things I wanted to include (fewer room layouts, fewer enemy types, fewer rooms overall). The other option is a bigger rom, and a different bankswitching scheme!

The folks on the dev forums of AtariAge make a big deal about how the purists pack their games into a single 4K bank. Well, I'm no purist. I'm already using 4K, I have 4K left, and I'd like a little more wiggle room. So I did some research, and there were some good schemes I could use. There were a few weird games back in the day that used a particular 12K scheme, but that one also included extra RAM on the cartridge, which somehow feels like cheating to me. I don't mind using a scheme with a ton of ROM so I can include more content, but one of the fun challenges of this whole thing is working with the limited RAM. So that 12K scheme was out. There's a simple 16k scheme that Atari supposedly used in some of its 1st party games (although I couldn't any mention of what games actually used it), which works exactly like my 8K scheme, only with 2 more banks. So that's what I'm tentatively going to go with.

This week, the plan to make it easier to transition, was first to rearrange all my code. I've been mixing my code between actual subroutines (called with jsr/rts, the native 6502 opcodes for calling and returning from subroutines) and just macros (for most "functions" that I'm only going to call once, so I don't have the 12-cycle overhead of the jsr and rts.) This ended up being a big mess, as it's difficult to tell where in my rom the macro code actually ends up. So I yanked all the macros out of the files where they lived into separate files, so I can move the subroutines around between banks without worrying about where the macros get called from.

Next I need to figure out where all I have references to the room data. If I move the room data to a new bank, all the code that reads that data has to be in that bank as well. It's almost like I have some actual encapsulation and data hiding!

Sunday, March 1, 2015

Alternate Dimension

With Chris's new graphics, Robo-Ninja is looking better than ever. And with this fun new alternate dimension, I'm finally back on a roll making new levels. The crazy speed-up mechanic is making it a lot of fun. Instead of trying to create weird convoluted challenges for new maps, I'm just making big long rooms with very simple layouts of spikes to jump over. If the game was played at a normal pace, these levels would be, as my kids like to say, "easy-peasy-lemon-squeezy." But at crazy insane speed, it's hard and loads of fun (at least, for a crazy person like me).

Only about 5 more rooms to go, and I'm done making maps! Of course, then I'll have to spend a good bit of time and code on the boss fight, ending story, credits, and a myriad of other things I've been putting off (a proper options screen, etc)



The end is in sight!

Level loading and scrolling engine

Well, after a bit of work here, a bit there, between baby feedings and lack of sleep, I've managed to get the first bits of my level-loa...