libDGL

Been a while since I wrote about this. When it comes to my own personal coding projects, rest assured that I take it very slowly. Heh.

I released the code that I've been working on for the past month. It's a DJGPP library called libDGL. DGL stands for "DOS Gamedev Library." Yes, I am incredibly unoriginal when it comes to naming things. This is a library aimed at "retro game development" with MS-DOS, targeting VGA Mode 13h using C.

As is mentioned on the Github project page linked above (and as I've mentioned previously here as well), I am using an older version of DJGPP from the late 90's. More specifically, I am using:

15 Jan 1998   bnu281b.zip  
24 Oct 1997   csdpmi4b.zip  
31 Oct 1996   djdev201.zip  
18 Jan 1997   faq210b.zip  
 6 Jun 1998   gcc281b.zip
18 Oct 1996   gdb416b.zip  
 6 Jun 1998   gpp281b.zip
 1 Mar 1998   mak3761b.zip
30 Sep 1997   rhide14b.zip  

I make no guarantees that this code will work with different versions. I'll probably test it at some point, but for now I am more interested in fixing bugs and adding more features. My "todo" list for this library is quite long still. Even so, I do feel like I've got a fair bit accomplished so far.

To help me test out a bunch of this, I wrote a very simple Asteroids game over the past two days. Asteroids is a very simple game, and I feel like two days was a long time to take to write it, but in the process I uncovered and fixed a number of bugs in libDGL, so I guess I should not feel like I was too slow. Finding and fixing bugs was the WHOLE point of writing it after all.

The code is available here.

As you can imagine based on the above screenshot and the game being Asteroids, it's nothing particularly special, heh. In fact, this has not been tweaked to provide any real level of difficulty to the player at all. I was more interested in testing out libDGL then in balancing a game and providing a full layer of polish. As well, I am less than happy with how the code that handles the different game states turned out. It's fairly sloppy honestly, heh.

This game doesn't make use of any sprite blitting. Instead, it uses line drawing and 2D vector transformations for the graphics. This was useful to test out and verify the math functions I had written, and is the main reason I picked Asteroids.

Not really much to say about it honestly. The next test game I'd like to do is probably some kind of simple vertical 'shmup type of game using sprites for graphics. Probably something along the lines of what I was originally going to do on the Amiga 500 some months ago.

So, where am I going with all of this anyway? Well, I don't have any specific plan worked out, but in the back of my head I've got some grandiose ideas about writing some 2D dungeon crawler type game (something I wanted to do as a kid back in the 90's but never finished... actually, that might be a fun post to write in the future, revisiting some of that code from back then which I have sitting here now). As well, I'd like to eventually work my way up to some 3D raycasting games, with a final goal being something Doom-like but with some RPG elements thrown in (and not gritty/dark like Doom is). But this is all quite a long ways off, and first thing's first... gotta work on the foundation.

DOS coding

Last month I picked up a copy of Fabien Sanglard's Game Engine Black Book: Wolfenstein 3D. In fact, I was eagerly waiting for the day I could order a copy. When it arrived I was totally engrossed in it the whole way through. It's an amazing book, well written and well worth the read for anyone interested in those kinds of topics. Fabien really did a great job with it and I'm eagerly awaiting the next book in the series which will cover the DOOM engine.

It also got me thinking about some DOS code I had started to write a couple months prior and then set aside temporarily. I had begun writing a simple VGA Mode 13h library I had called "DGL" for "DOS Game Library" because naming is not a strong suit of mine. So, I'm going to pick it up again and hopefully continue writing about it here as I work on it and then soon after, some little game demos written with it also.

Of course, there's absolutely no good reason to re-invent the wheel from scratch like this. Libraries such as Allegro exist and any of the 3.x or 4.x versions for DOS would perfectly meet all my requirements and is probably far better implemented than anything I'd cook up myself. But that would be less fun.

Anyway, what I want out of this library is:

  • Support for VGA mode 13h (320x200x256)
  • Primitive drawing (pixels, lines, boxes, circles, polygons, etc)
  • Bitmap/Sprite drawing (aka. "bitblit"-ing)
  • Palette manipulation (loading, rotating, fading)
  • BMP, PCX, IFF image support (period-correct file formats)
  • Font rendering (using BIOS font format). Also add non-fixed width support?
  • Keyboard, Mouse, Joystick input device support
  • PC Speaker sound (maybe even rip off QBasic's PLAY command?)
  • Sound Blaster (and compatible) support (MIDI music, FM synth and digitized audio sound effects)
  • Math function suite (vectors, matrix, etc)

The only thing in this list that I think is (currently) outside my skillset (but totally possible to learn, of course) is the Sound Blaster stuff... simply because I've actually never written an audio engine of any sort, and certainly not ever written code directly for Sound Blaster hardware.

In fact, the only time I've added audio to game projects of mine was via DirectX. Not sure how DirectX is nowadays, but I remember at the time I was using Visual Basic 6 and the libraries for it had play/pause/stop functions for both sound effects and background music out of the box, so it was extremely simple to hook into the projects I worked on. Most game projects of mine tend to get dropped before I get to the point where I need to add audio, heh. And in more recent years, it was always my intent to use something like SDL_Mixer to take care of the lower-level details anyway, but I just never got around to it.

So, needless to say, when it comes to audio for this project I have a bit of fundamentals learning work to do.

Also on the topic of audio, I would like to look into adding support for Gravis Ultrasound cards. These cards are interesting as I think they were the first sound card for PCs to have full hardware audio mixing support. As I understand it, Sound Blasters lacked hardware mixing capability, so game engines would do this in software. But this will be a nice optional extra for later if I feel like it.

Originally, I had planned to use Borland C++ for this and do it all in real-mode DOS code. That probably sounds like totally unnecessary pain to anyone who understands the differences that brings along with it. I even went and bought a copy of Borland C++ 4.0 off eBay:

However, after fiddling around with it for a while I remembered how easy it was to crash your system with real-mode C code and how the debuggers of the time were helpful, but not that helpful in tracking down these types of bugs. This was less clear in my memory prior to this because during this time period I was primarily using QBasic which obviously shielded you from these types of bugs much more.

So instead, I plan to continue using a period-correct version of DJGPP (meaning, a version from the late 90's). Better debugger support for dealing with these types of crash bugs. Still possible to crash your system in weird and wonderful ways of course, but more support than Borland for catching these bugs. Plus having a 32-bit flat memory model is obviously very nice.

I plan to keep the code for this library on Github somewhere when there is something to show for it.

Shmup Game First Steps

After playing with both AMOS and Blitz Basic, I initially had an overall poor impression of Blitz Basic mostly due to stability issues. This was disappointing to me because it seemed pretty clear that AMOS was a little bit slower, but at least it did seem more approachable.

Ultimately though, when I reflected on the various game ideas I had floating around in my head, I really figured I would end up quickly outgrowing AMOS from a performance perspective. So I decided I would look at Blitz Basic again, but try to see what I could do (if anything) to work around the stability issues I had run into earlier. I should note at this point that yes, I did have the runtime debugger enabled, so I don't think that was the cause of any of the crashes I was seeing. That was the first thing I checked when I was having issues. Some of the crashes weren't even occurring while a program was running anyway...

First, I decided that I would not use the "mousable labels" support. Blitz's editor "TED" pops up a side navigation pane showing your program's labels for quick navigation only if your program has any. A "mouseable label" is just an ordinary label that you would use with GOTO or GOSUB with the exception that it should start with a period, e.g. .renderPlayfield: instead of renderPlayfield:. I had noticed some random crashing that would occur when I was fiddling around with some of the sample programs that included these types of labels. Additionally, I had encountered a severe problem with the updated TED version included in the Blitz Support Suite ("SuperTED" I believe it was called? Or might have been the update before that?) where it would immediately crash when opening a program with any of these types of labels. Definitely seemed to me that the editor support for it was at least partially broken... at least for me, though I'm not sure what I could have done to cause these issues, heh.

Second, I had finished completely reading through the user guide (which is honestly a quick read, less than 100 pages) and had run across the recommendations and warnings for using "Blitz mode" (which you will undoubtedly want to use for performance reasons). Most importantly, any disk access or other concurrent OS processing that occurs while a program is running in Blitz mode (or as it first enters Blitz mode) can cause crashes! How about that. I suppose it's possible that this accounts for at least some of the instability I was encountering before. The user guide recommends doing something like VWait 120 just before a BLITZ call to ensure that any disk buffers have had time to be flushed (evidently the OS does so every two seconds?). It notes that there is no software method to check for whether stuff like disk activity has completed so this seems like the only way to protect against this kind of crash. Also it is important to note that none of the sample programs that use Blitz mode do this, thus furthering my belief that this was at least part of the problem I had run into when previously toying about with Blitz Basic.

Anyway... so far so good! I've only had one crash all weekend, and I believe that actually was related to my misuse of Blitz mode and/or of some dual playfield slice functionality. For most of the weekend, I was booted up into a Blitz Basic 1.7 floppy and not using the hard disk functionality provided by my ACA500plus. I wanted to remove as much other possible factors as I could and that seemed like a big one. Late this afternoon I resumed using the ACA500plus and CF card hard disk and have so far been running completely stable as well with that configuration. Fingers crossed that it stays that way.

Without having to worry about crashes, I was able to get a lot of experimentation and learning done and got some very preliminary work done on a basic vertical shmup type game. Nothing fancy, but I'm happy for a few hours work with lots of flipping around through manuals slowing things down (really want to get a physical copy of the Blitz Basic Reference Manual... I hate having to constantly look up commands in PDFs).

I'll try not to make posting big code dumps a habit on this blog, but here's what I've got so far:

; shmup test

#KEY_ESCAPE = $45
#KEY_UP = $4c
#KEY_DOWN = $4d
#KEY_LEFT = $4f
#KEY_RIGHT = $4e
#KEY_SPACE = $40

#SPEED = 2
#STATUSBAR_HEIGHT = 32
#PLAYFIELD_HEIGHT = 256 - #STATUSBAR_HEIGHT

#PAL_GAME = 0

#BMP_STATUSBAR = 0
#BMP_PLAYFIELD = 1

#SLICE_STATUSBAR = 0
#SLICE_PLAYFIELD = 1

#SHAPE_LRG_ENEMY = 0
#SHAPE_MED_ENEMY = 2
#SHAPE_SML_ENEMY = 4
#SHAPE_PLAYER = 6
#SHAPE_BULLETS = 16
#SHAPE_EXPLOSION = 20
#SHAPE_POWERUPS = 25

ASSET_ROOT$ = "Projects:resources/"  
ASSET_SHAPES$ = ASSET_ROOT$ + "shmup.iff"  
ASSET_STARS_BG$ = ASSET_ROOT$ + "shmup_stars_bg.iff"

DEFTYPE .w

Statement ASSET_LoadPalette{pal}  
  SHARED ASSET_SHAPES$
  LoadPalette pal,ASSET_SHAPES$
End Statement

Statement ASSET_LoadStarsBg{destBmp}  
  SHARED ASSET_STARS_BG$
  BitMap destBmp,320,512,5
  LoadBitMap destBmp,ASSET_STARS_BG$
  Scroll 0,0,320,256,0,256,destBmp
End Statement

Statement ASSET_LoadShapes{}  
  SHARED ASSET_SHAPES$
  BitMap 0,192,256,5
  LoadBitMap bmp,ASSET_SHAPES$

  GetaShape #SHAPE_LRG_ENEMY,0,0,32,32
  GetaShape #SHAPE_LRG_ENEMY+1,32,0,32,32

  GetaShape #SHAPE_MED_ENEMY,64,0,32,16
  GetaShape #SHAPE_MED_ENEMY,96,0,32,16

  GetaShape #SHAPE_SML_ENEMY,64,16,16,16
  GetaShape #SHAPE_SML_ENEMY,80,16,16,16

  For i=0 To 4
    GetaShape #SHAPE_PLAYER+i,0+(i*16),32,16,24
    GetaShape #SHAPE_PLAYER+i+5,0+(i*16),56,16,24
  Next i

  GetaShape #SHAPE_BULLETS,80,32,16,16
  GetaShape #SHAPE_BULLETS+1,96,32,16,16
  GetaShape #SHAPE_BULLETS+2,80,48,16,16
  GetaShape #SHAPE_BULLETS+3,96,48,16,16

  For i=0 To 5
    GetaShape #SHAPE_EXPLOSION+i,0+(i*16),80,16,16
  Next i

  GetaShape #SHAPE_POWERUPS,80,64,16,16
  GetaShape #SHAPE_POWERUPS+1,96,64,16,16
  GetaShape #SHAPE_POWERUPS+2,80,80,16,16
  GetaShape #SHAPE_POWERUPS+3,96,80,16,16

  Free BitMap 0
End Statement

Statement ASSET_Load{}  
  NPrint "Loading palette ..."
  ASSET_LoadPalette{#PAL_GAME}
  NPrint "Loading stars background ..."
  ASSET_LoadStarsBg{#BMP_PLAYFIELD}
  NPrint "Loading shapes ..."
  ASSET_LoadShapes{}
  NPrint "Done loading assets!"
End Statement

; -------------------------------------------------------------------

Statement GAME_Init{}  
  VWait 120
  BLITZ

  Buffer #BMP_PLAYFIELD,16384

  BitMap #BMP_STATUSBAR,320,#STATUSBAR_HEIGHT,5
  Slice #SLICE_STATUSBAR,44,320,#STATUSBAR_HEIGHT,$fff8,5,8,32,320,320
  Use Palette #PAL_GAME

  Slice #SLICE_PLAYFIELD,44+#STATUSBAR_HEIGHT,320,#PLAYFIELD_HEIGHT,$fff8,5,8,32,320,320
  Use Palette #PAL_GAME
End Statement

Statement DRAW_StatusBar{}  
  Use Slice #SLICE_STATUSBAR
  Use BitMap #BMP_STATUSBAR
  BitMapOutput #BMP_STATUSBAR

  Cls 14
  Print "TODO: Awesome statusbar here"

  Show #BMP_STATUSBAR
End Statement

Statement DRAW_Playfield{}  
  SHARED scrollY, playerX.q, playerTiltOffset, animateOffset
  Use BitMap #BMP_PLAYFIELD
  Use Slice #SLICE_PLAYFIELD

  UnBuffer #BMP_PLAYFIELD

  Show #BMP_PLAYFIELD,0,scrollY

  tile = #SHAPE_PLAYER+2+playerTiltOffset+(animateOffset*5)
  y = #PLAYFIELD_HEIGHT-32+scrollY
  BBlit #BMP_PLAYFIELD,tile,playerX,y

End Statement

;
; -------------------------------------------------------------------
;

ASSET_Load{}

GAME_Init{}

animateFrame = 0  
animateOffset = 0

playerTiltOffset = 0  
playerHorizAccel.q = 0  
playerX.q = 320/2-32/2

scrollY = 0

DRAW_StatusBar{}  
DRAW_Playfield{}

While NOT RawStatus(#KEY_ESCAPE)

  scrollY = QWrap(scrollY - #SPEED, 0, 256)

  animateFrame = QWrap(animateFrame+1, 0, 5)
  If animateFrame = 0
    animateOffset = QWrap(animateOffset+1, 0, 2)
  EndIf

  If RawStatus(#KEY_LEFT)
    playerHorizAccel - 1
  EndIf
  If RawStatus(#KEY_RIGHT)
    playerHorizAccel + 1
  EndIf
  playerHorizAccel = playerHorizAccel * 0.7
  playerX = QLimit(playerX + playerHorizAccel, 0, 320-16)
  playerTiltOffset = Int(playerHorizAccel)

  VWait
  DRAW_Playfield{}

Wend

End  

So yeah, very basic and/or crude for now. It doesn't look very impressive running yet either:

All you can do is fly the ship back and forth (but hey, it animates and the ship tilts a bit from side-to-side as you move left and right... exciting, right!?). I'm using the art assets from this package on OpenGameArt. Packaged everything together with a separate simple star background and exported as an IFF.

Actually the asset management has been a slight bit of a pain so far. I first noticed that Photoshop has the ability to save as Amiga IFF, so I would pre-convert the image I was working with to indexed colour mode and set up a 32 colour table and then save as an IFF. This seems to produce something that always is loadable by Blitz Basic (and AMOS for that matter), but occasionally produces a file that Deluxe Paint says is "mangled." Also sometimes, when loaded in Blitz Basic, the palette is somewhat off. Some colours will be totally different, but most will be correct. In this case, I've noticed I can fix the problem by opening the IFF in Deluxe Paint, and if it doesn't complain that it's mangled, I can simply re-save the file and the problem goes away. My suspicion is that Photoshop saves the palette information in a different way then what Blitz Basic is expecting, but I have not investigated this fully yet. I also tried using XnConvert by exporting from Photoshop as a indexed colour PNG or GIF and then converting to Amiga IFF with XnConvert, but still have run into the same issue (I think? I might also have mixed up my working files, heh, so will need to confirm that first I guess). At any rate, I definitely still have lots to do to nail down my asset preparation process.

Next steps will be putting together some custom font routines (I'm not sure how to generate the "Blitzfonts" that Blitz Basic supports, but at any rate, I don't think that supports bitmap fonts which is what I really want to use anyway). Following that will be adding the ability for the player to shoot and then adding enemies. I'm really curious to see how quickly I run into slowdowns.

Initial-ish Impressions: AMOS Pro vs Blitz Basic 2

I find the plethora of programming languages available for the Amiga fascinating. Especially so, the large amount of BASIC variants. The top two options for games specifically are definitely AMOS and Blitz Basic from what I can see.

Some other options such as HiSoft BASIC also seem to be of good quality (HiSoft BASIC actually does interest me quite a bit as it was advertised as being QuickBASIC compatible while not being mostly shit like Amiga BASIC from what I understand... but I will explore it later). However, it seems most people at the time settled with either AMOS or Blitz.

I've personally spent more time with AMOS so far, but this weekend I spent a bit of time with Blitz Basic and figured I'd jot down my initial thoughts about each.

None of the points below are listed in any particular order, and it is all just based on my impressions, opinions and experiences from only a limited amount of time looking at each thus far. Also note that the below screenshots show my own customizations, they are not how the "out of the box" experience is exactly.

AMOS Pro

  • Editor looks very polished. Especially as compared to the earlier (non-pro) versions. Lots of customization available with the ability to load "accessories", which, due to AMOS's overwhelming popularity back then, there are a great many to choose from.
  • The editor is not without it's quirks. For one I dislike the automatic formatting (which you cannot turn off, and is likely a result of the fact that the editor is obviously tokenizing your code as you type it in). More specifically, I don't like how it removes excess whitespace and uppercases variable names, e.g. if I type ship_x = foo + bar, it will always auto-format to SHIP_X=FOO+BAR.
  • AMOS Pro thankfully added INCLUDE support for modularizing your code, but even so, you'll probably end up with big source files. Luckily the editor allows you to collapse Procedures (though you might not actually want to use them in all cases, since this is a platform where the performance difference between GOSUB and a Procedure call can really matter!)
  • Following up on the above mentioned "accessories", the developer of AMOS provided some that serve as tools for sprite/image editors, map editors, font editors, and more. These are easily accessible from within the IDE.
  • Lots of documentation in the forms of a beefy user manual and many other published books and sample code. Even built in fully-browseable help within the editor itself.
  • Easily accessible "direct mode" available from the editor to allow quick experimentation (it also doubles as a debugging tool when your program encounters an error).
  • Very extensive set of functions with what looks like a decent abstraction over the underlying hardware (from my early impressions anyway). I personally think this is a pro and a con (a pro for when you're starting out as it's easier to jump into and a con because I suspect it won't help you that much if you move onto e.g. C/assembler later on). This abstraction covers things like asset loading as well which is certainly convenient.
  • The AMOS BASIC dialect is overall good, though lacking in some key areas. For example, no SELECT and TYPE. Somewhat odd syntax for calling Procedures (SUBs and FUNCTIONs from QBasic) and accessing the return value (if any). You cannot put comments just anywhere (well, unless you use REM I guess, though in my opinion, REM makes the code a bit harder to read). A comment written using ' must be on it's own line.
  • Quirky / annoying support for accessing system libraries, but it is somewhat workable.
  • Doesn't integrate with the OS, kind of does it's own thing with it's own totally custom GUI. This also extends to programs developed with it if they do things like pop up file requestors which will be quite alien-looking.

Blitz Basic 2

  • Much more powerful language that is clearly built to enable high performance as a primary goal. Blitz's BASIC dialect is excellent for the time in my opinion. Support for TYPE's, pointers, inline assembly, and more.
  • The language is built for a compiler and there doesn't appear to be any interpreter at all (even when running from the IDE, you can't just choose "Run" unless you've already compiled your program). Thus performance is higher from the get-go.
  • The editor is minimal, which is nice. Though it definitely is unique in a number of ways, and I don't mean that in a good way, at least not if you like me are accustomed to modern text editor standards. You cannot always hit Return to insert a new line (only if you're at the end of the current line), else you need to press Amiga+I to insert a new line or hit Shift-Return. Using the Backspace or Delete keys to remove lines is not possible, you instead must use a menu command (or press Amiga+D) to delete lines. Selecting text for copy+paste is kind of quirky, requiring you to select the text to be copied then go and find the location where you want it copied to (the paste location) and place the cursor there (moving the cursor does not unselect text) and then issue the menu copy command (or Amiga+C). There is a specific menu command for unselecting text. I'm sure you can get used to all this, but I point it out only as it's pretty different from what most people would be used to.
  • The editor has syntax highlighting! Only two colours though: regular text and tokens.
  • The editor has a side pane that pops up when your program has labels (for GOTO/GOSUB only, doesn't show Statement or Function names for some weird reason). Clicking the names in this pane scrolls immediately to that label. Thusly you can also use this as a "bookmark" list of sorts.
  • The editor is incredibly unstable. It crashes a lot, in a lot of different situations, forcing you to do a Ctrl-Amiga-Amiga reset. I've had the editor crash when clicking Project -> New, when switching back to the Workbench, when compiling a program, many times when debugging code with direct mode (in all cases, this was incredibly simple code, not even using "blitz mode"). Worth noting, I've tried four different versions of Blitz2, the 1.6 Amiga Format disk release, a 1.7 release, 2.0 and 2.1. I actually also tried installing Workbench 3 temporarily just so I could try the updated Ted version and also the "SuperTed" update, hoping that these would improve things. However, all of these also were incredibly unstable for me.
  • The standard library appears to be a bit "closer to the metal" then AMOS, but it still abstracts the hardware quite a bit. I suspect that moving from Blitz Basic to C/assembly would be a bit easier. In fact, the mere ability to use inline assembly with such ease basically anywhere in your code means that you possibly wouldn't even need to switch to C or go full-out with pure assembly unless your performance requirements were quite extreme.
  • The editor has built in help which is either limited to parameter lists only, or in later versions even has a browseable function index with descriptions and (few) examples.
  • There is not nearly as much documentation out there for Blitz Basic as there is for AMOS. A common complaint about Blitz Basic from what I've read is that it's harder to get started with, though I think for an experienced programmer that this difference is moot. Probably the smaller amount of example code that's out there would be the biggest annoyance.
  • The debugger and direct mode support looks a fair bit more unpolished than AMOS at first glance, but is definitely more advanced. Especially with a debugger update that is available for release 2.1 (though coincidentally I found this debugger update appeared to reduce stability somewhat).

I Like Old Computers

A recent acquisition finally arrived this past week:

An Amiga 500. This one is from the UK originally, so it's a PAL model. Most people seem to agree that getting a PAL model is probably best because most games for it were developed and sold in PAL regions due to the Amiga's overwhelming popularity there. That being said, switching from NTSC to PAL mode as needed is easily done with some of the later Kickstart versions from what I gather.

Pretty ghetto setup for using it on my desk at the moment, as I'm both short on space and waiting on some additional things to arrive so I can clean things up (most notably a shelf so I can slide the Amiga back a bit and have the monitor raised up).

While there are a lot of cool games available for it, I intend to use it for programming primarily. And actually, I will try to write code for it on it, using period-appropriate editors and compilers.

I'm still waiting for a number of additional things to arrive such as additional software (Blitz Basic, AMOS Pro, various books, 512KB memory expansion, HxC floppy emulator, RGB cable, ...).

Anyway, why an Amiga 500? Or, why an Amiga at all? What's with the old computer interest?

A variety of different reasons really. First off, I should confess that I did not actually grow up with Amiga computers at all, 'nor Commodore computers either. Aside from the fact that Amiga's were more popular in Europe, the first computer that I can remember my family getting was a 386 in the very early 90's. I seem to recall that we might have had some older "green-screen" type computer before that but my memory is really not helping me with it (was likely some kind of IBM PC, but it was not something that any of my siblings or I ever used).

Anyway, I suppose that a large part of interest is nostalgia. I quite fondly remember my initial foray into programming in the mid 90's, which for me was learning QBasic with a book I had bought for $0.50 from my school's library. Of course, it didn't teach programming for QBasic specifically as it was published before QBasic ever existed, and so that complicated my learning somewhat (I recall there was a Tic-tac-toe game in the last chapter that I couldn't get to work due to some syntax differences... but I didn't understand that was the problem at the time).

We didn't get a dial-up internet connection until a couple years later at which point I remember the first thing I searched in AltaVista was "QBasic." Internet time was extremely limited for me however as my parents were pretty strict on that, mostly because they didn't like the phone line being tied up for long periods. So what I would end up doing is downloading as much games written in QBasic as I could (which didn't end up being much, due to our really poor, slow dial-up connection... even by dial-up standards at that time) and then spend lots of time studying them, modifying things, copying bits and pieces, etc. I remember at some point a year or two later my dad bought me another book specifically about QBasic when I was with him in some computer store and that helped a lot.

Later on, my dad also bought me a book on C which came with a disk which had a Watcom C compiler on it... and the disk didn't work completely so my dad ended up contacting the publisher who sent another copy. I remember spending a bunch of time learning C, but eventually going back to QBasic... the ability to simply hit a single key and run your program right then and there was really attractive to me compared to using MS-DOS EDIT to edit code then having to quit out and run a compiler and sift through compiler errors, and then remember them and open back up EDIT and fix the problem, etc. I think at the time, it was just too much for my younger self to deal with as a hobby and the aforementioned attractiveness of QBasic's edit->run cycle was just way better.

Of course QBasic was slow. Getting into games and graphics, you quickly realize that. Around 1999 or so, I took my first jump into x86 assembly and writing VGA mode 13h (aka SCREEN 13) graphics routines, assembling and linking them into .QLB libraries and seeing what a world of difference it made. My parents had become somewhat less strict about internet usage so finding information out online was easier and that really helped things along. That also eventually lead me to using existing libraries such as DirectQB, Future.Library, and even a few years later on UGL instead of rolling my own.

Compared to today, where so much more is possible and more easily done without caring much about memory usage, code efficiency, etc, I just feel "ho-hum" about it all. The feeling of power from writing code that runs "on the metal" so to speak, POKE'ing bytes into memory to make things magically happen, having to write lean code over nicely abstracted, cleaner looking code because you literally don't have anywhere near the required amount of CPU cycles to spare on stuff like that... a very different feeling that is lost. A different type of challenge. Makes me wonder why I got into web development at all, and not into something like embedded systems, heh. At the same time, it makes me happy I learnt programming when I did and not today. A part of me feels sorry for people learning today, probably starting with something like Javascript or Python or what have you, where you never really get into the nitty-gritty details about what is going on under the hood. No appreciation for the abstractions we take for granted today that makes things like the web and the plethora of web frameworks even possible. Some new programmers probably do get into that eventually, but I'd bet the majority don't (and they don't actually need to either technically speaking).

I briefly entertained the idea of getting a 386 or 486 PC to toy around with as an old school programming machine. I still might do that one day, but for now I wanted to try something a little bit different but still stick to a machine that is quite constrained hardware-wise but still has a plethora of development documentation and tooling available for it... and most importantly, something resembling a community. After all, being able to talk about your experiences with others also interested in it is worth something.

I've always been fascinated by the Commodore machines like the 64 and Amiga. The Commodore 64 especially piqued my interest when I first heard of one when I was younger as it was explained to me that "the OS is just a BASIC interpreter." Since I was learning QBasic at the time, the thought of the whole computer running BASIC sounded awesome to me.

Never heard of an Amiga until some time later but it, like the Commodore 64, sounded fascinating to me but for slightly different reasons. Mainly the fact that when it first came out it was so ahead of it's time. I also liked the fact that there was still an enthusiastic community for it (even if said community does seem excessively enthusiastic to the point of seeming somewhat delusional). Also that it was more capable than a Commodore 64, NES, or Atari, etc., but still quite limited. It had multiple options for development, with various BASIC options, C was in many respects a sort of "primary" development language for it, and of course 68k assembler which is one of the nicer assembly variants out there.

I'll probably dive into the world of Commodore 64 at some point down the road also as that's really such a quaint little machine and I do want to get more into 6502 assembly at some point (since I can then also tackle a large NES game project or two). But for right now, the Amiga seems like a nice option to focus on, diving into a whole world of computing that I missed by a few years.

So, as mentioned above, I actually intend to do development on the Amiga itself. We'll see how long that lasts I guess (heh), but I figure it'll be fun for a while to limit myself like that. I went with the 500 instead of a 600 or 1200 (which is what I think most people would probably recommend). This is because, from what I gather, by far most games for the Amiga were written with the 500 in mind. It was also I believe the model that was sold the most. As well, I feel like getting a more souped-up model kind of defeats the entire point of this "old school development" adventure to me.

To sum all of the above up: basically it's about looking for a nostalgic "old school" development experience that is in some ways familiar to what I remember growing up with, but different in other ways so as to present a new type of challenge.

I'm going to start with BASIC (either AMOS or Blitz Basic, I intend to try them both) and then work my way into C/assembly once I become more familiar with the hardware and it's capabilities/limitations... similar to what I did all those years ago with QBasic really now that I think about it.

Since I'm still waiting on stuff to arrive as I mentioned above, all I could really do for now is mess around with Amiga BASIC.

Amiga BASIC

This is just going to be my initial thoughts on it and will not be very in-depth as I don't intend to spend a lot of time with it. Most people from what I've seen tell people not to bother with Amiga BASIC at all. It's apparently buggy, slow and all around not very good. Since I cannot do anything else quite yet until more stuff I ordered arrives this coming week, I decided to play around with it a bit anyway for now.

It is interesting, having been created by Microsoft as there is definitely a "QBasic-like" feeling to it. Obviously not as polished though as this predates QBasic.

Support for integers, longs, single-precision, double-precision, strings, arrays, SUBs, QBasic-like graphics routines like PSET, LINE, CIRCLE, GET and PUT, SCREEN (well, the Amiga variant of it), file I/O that feels pretty QBasic-like, LIBRARY which is used to include and call external system library functions, ability to call pre-assembled assembly routines via CALL, VARPTR and SADD (QBasic CALL ABSOLUTE-like functionality basically).

Again, it feels very QBasic-like to me. Though it is lacking a lot of niceties such as DO-LOOP, SELECT CASE, TYPE. Debugging support is obviously primitive with single stepping + the use of immediate mode to inspect variable values being your only debugging assistance. But even that for the time is pretty cool.

Graphically, as mentioned above there are a lot of built in functions but it's all really slow. I typed in a quick example from one of the manual PDFs I found which draws a cosine wave using LINE to draw each vertical line from y=0 to y=COS(x) across a 320 pixel width and it took several seconds to run where you could see each line being drawn, heh. I tried changing the example to use all integers and pre-calculating all of the COS values so that the drawing loop would just be doing some quick x/y calculations (addition and one multiplication), but no calls to COS of course and it barely made any difference. I'd guess the bottleneck was the actual call to LINE which is probably not optimized at all.

This doesn't surprise me given what I've read about Amiga BASIC (I understand it was probably a quickly-done port from some variant of Microsoft BASIC perhaps).

There is some support for the Amiga's blitter (and possibly also the built in 8 hardware sprites?) through the use of a bunch of different OBJECT commands such as OBJECT.SHAPE, OBJECT.X, OBJECT.Y, etc. After playing around with these for a while, putting together a quick little demo to move a ball shape in 4 directions around the screen via the keyboard I arrived at the conclusion that either this set of OBJECT commands is not very fast either, or the entire thing is hamstrung by the overall performance (or lack thereof) of the Amiga BASIC interpreter... probably a combination of both really. Not that I was expecting much.

Anyway, kind of fun to fiddle with, but obviously very limited. I'm looking forward to being able to play with AMOS and Blitz Basic hopefully this coming week (pending my 512KB memory expansion arriving since they both won't run without it!).