AMIGA alive

AMIGA alive
Showing posts with label aadevlog. Show all posts
Showing posts with label aadevlog. Show all posts

Sunday, December 25, 2022

AADevLog #6 - Merry Christmas! And, yes, it will become a game.

Merry Christmas everyone! So it's christmas, and I thought I'd pull out a couple of things from my harddrive.

You might have noticed this, well, attempt at a platformer that goes by the name of "Wheelchair Hero". I'm working on it on-and-off, but there is actual progress. One of the issues I had postponed was some sort of rudimentary color management, meaning some basic strategy regarding palette use. Another one was to add some strategy elements, so the... game?... doesn't get too boring too quickly. Anyway - here's another work-in-progress screenshot of "Wheelchair Hero", and, yes, it looks as if this will become a game. :-)

Wheelchair Hero with new elevators, NPCs, items, better colors

Also a little bit of work has been done on "reed" texteditor: a little update to the GUI layout, and it now shows actual settings' values.

"reed" on AmigaOS3.9

And while we're at it: When creating a game, why not create two? Or even three? So I started drawing assets for more playable stuff. This next one might be called "Attack on the Beach", and maybe you can make a guess what it's all about from this mockup-picture:

"Attack on the Beach" concept picture

Finally, something that I had on my mind for decades. With all the knowledge gained from hundreds of programming experiments and attempts, I thought it's about time to somehow tackle the challenge. I'm pretty sure everyone gets a "rough" idea what this one might be about from this early title picture. ;-)

"Airborne Trooper" work-in-progress title picture

* * *

Thanks for reading, happy holidays & stay healthy!



Tuesday, November 8, 2022

AADevLog #5 - Will it become... a game?!

Creating your first action game from scratch can be quite a challenge, and cause severe frustration. But at some point you begin to see some light at the end of the tunnel - and that's where the real fun part begins.

My experiments in creating something that might become... a game?! ...have reached a stage where (except for sound) pretty much everything is in place: timing, user input, movement, graphics, limits, ...and it seems to work! Stably!

To achieve this within a somewhat tolerable time frame (= this lifetime), some fundamental decisions had to be made: 

- few colors

It turns out that Amiga color palette considerations can be very time consuming. To make progress, no attempts were made to max out the possibilities.

- single reference platform support

AGA compatibility has been dropped early on, OS3.x would be nice, but Kickstart 1.x support is a must for this project anyway (for personal reasons), so an Amiga 500 with Kickstart 1.3, OCS, 1MB RAM has become the single target platform. If possible, the... game? ...should fit into 512KB RAM. (256KB would be even better.)

- accept bad performance now, optimize later

This is something I really had to get into my head: It won't be fast! Not yet! Maybe never! I have a tendency to spend a lot of time thinking about loops, variable size, etc. without being sure the entire program architecture will work out. (Compare AA DevLog #0.) So to get a proof-of-concept of where and when things happen, the basic assumption was made that with some fundamental limitations set, the Amiga will somehow be able to handle the load within one, or at least two vertical screen refresh cycles, resulting in a usable frame rate. All other performance- or elegance-of-execution-considerations were dropped.

Everything still looks pretty... flat.

Well, despite my self-imposed rules, I still tried to make some routines scalable, reasonably "elegant" (?), or spent a little bit of time on thinking about speed. It just happens, and is part of the fun.

Having an ugly, but working prototype of the game, a level editor speeds up further development considerably. Creating the editor was comparably easy, as many of the functions required were already there from the game files.

Editing an NPC's path/waypoints

Now background tiles, foreground items, and non-player-characters (NPCs) can be easily added to the level - and as mentioned in the introduction, this put a broad smile on my face a couple of times. It's really fun to invent game mechanics - e.g. a path with waypoints for your NPC - and then be able to immediately see the effects in the game.

Thanks for reading, c u next time!

* * *

Click here for an overview of all AADevLog articles

Sunday, June 26, 2022

AADevLog #4 - AROS and AmigaOS text editor

Publishing zx81paint on AmiNet led to me reviewing a lot of old C code, and creating an ASCII text editor is certainly an essential project for every C coder.

Actually it started a long time ago: In the late nineties, I was impressed by text editors like Microsoft's "Frontpage" and some MacOS programs, which were among the first to show "tabbed" documents, have integrated shell functions (e.g. recursive search), and some other features I hadn't seen before in GUI text editors. So my idea of a program called "proWEB" was born, an HTML editor with advanced functions like sophisticated TABLE creation, FRAME management, etc. Well, time has passed, web development has changed, my preferences have changed, operating systems have changed, and so on. But the idea of a great text editor, according to my personal taste, has remained. In it's first early incarnation for AmigaOS, "proWEB" didn't really get far. There was a second incarnation for AROS which got considerably further, but I was a bit over-ambitious, and under-educated in software architecture, so that one slowly but steadily came to a halt, too. 

Nowadays, having created a lot of smaller programs, slowly developing a usable concept of a program's architecture, and with some experience with C compilers (vbcc is my favourite) gained, I resurrected this old project again.

Among the first steps of resurrection was to find a nice short name you can easily type into your shell - so now "proWEB" has become: "reED", preferably spoken (and certainly typed in as) "reed", which is a reference to a) my name, b) editing, and c) Phragmites Australis. :-)

To my surprise it took me just a day to make all code adjustments from AROS' gcc to AmigaOS' vbcc, including lots of stylistic improvements, and I got a working executable. The code now doesn't use any special compiler features, and should work with gcc, probably SAS-C, etc. just as it does with vbcc. There were a couple of minor differences between AmigaOS and AROS that needed to be taken care of - for example my old AROS system used a font called "ttcourier" instead of "courier".

"reED" running on AmigaOS3.9 in 2022!

Looking at this old code from my "modern" perspective, it's quite a mess, a lot of things can be done much simpler. But "reED" is more sophisticated than I remembered: It has it's own GUI layout engine, it has a massive menu (which I use more like a notepad, many functions not yet implemented), uses ASL file requesters, it can edit multiple documents, it can mark/cut/copy/paste - and it has actual tabs with keyboard control! Colors might be a bit harsh, though. ;-)

I'm not sure if it makes any sense to devote lots of energy to this project - but it's a sort-of success even at the current stage of development. AmigaOS is great, AROS is great, and why not support both at the same time, it's really easy. (Well, gcc will do, but we still need an updated vbcc for AROS to make it perfect.) And in the end, AROS is just AmigaOS, so it just makes a lot of sense.

Let's see what other old (or new) stuff I can dig out from my harddrive... there are a couple of games I have to seriously review and rework...

Thanks for reading, stay healthy!

* * *

Click here for an overview of all AADevLog articles

Monday, January 31, 2022

AADevLog #3 - A paint program for the ZX81

The Sinclair ZX81 is a wonderful little machine. It's limitations create both a simple, fun environment to play with, and a challenge for developers.

About four decades ago, I started learning about computers with a ZX81. Type in stuff on a minimalist keyboard, print characters to a simple 32x24 characters monochrome screen, don't worry about colors or sound, because they're just not there. The ZX81 has very little memory, and the user interface is almost non-existent, so you're done pretty quickly. It's great, but also very limited in terms of sophisticated tools - there's just no extra room for such things, and you're having a hard time entering and editing the required data on the ZX81 anyway.

About three decades ago, I started using an Amiga. The Amiga, in comparison to the ZX81, is a highly capable computer. It has plenty of room, tons of screen size, a proper keyboard, several standard I/O ports, and colors and sound on top of it. Well, obviously it became my main computing platform.

About two weeks ago I got myself a ZX81 again. Oh what pleasures. Nostalgia galore. And that great experience of typing in little things which create immediate results.

Of course I quickly ran into some of the aforementioned limitations, so I decided to create some ZX81 support software for the Amiga: a paint program to paint nice game intro screens.

First painting with zx81paint.

It's called "zx81paint" and runs on Amigas with OS2.0 or higher. Currently it can't load or save files, but a first painting was created successfully. 

Due to the simplicity of the ZX81, the data that needs to be handled is also very simple, so there are little to no critical issues. For example the ZX81 picture itself is stored as a fixed-size array of bytes filled with ZX81 character set codes. Most of the development time is spent on putting together a pleasant and useful user interface. With the data and program structure in place, functions like line-drawing, flood fill, etc. can easily be added.

File loading and saving is currently missing - and might be one of the more challenging aspects of this little project. Several file formats used by emulators come to mind, but it would also be nice to have something that can directly be played back to the ZX81's tape-in ("EAR") jack.

There's no fixed feature list for "zx81paint", but an early release version will be put on AmiNet in a few days.

Thanks for reading, c u next time!

* * *

Click here for an overview of all AADevLog articles

Wednesday, December 22, 2021

AADevLog #2 - Sprites, tiles, scrolling... a game!

Another project I've been working on is slowly taking shape, and there was quite some headache involved to get it going.

In my pursuit of creating... a game! ...I've arrived at VSprites, tiles, and scrolling. The Amiga is a technical marvel, but it has it's pitfalls. So you read the docs, set up your default, low-res PAL display "View", create a "ViewPort", adjust ViewPort offsets, re-read the docs, adjust the ViewPort offsets properly, read the docs again, re-adjust... and it still behaves weirdly. At some point you try a high-res display mode. Either way, in the end result some VSprites are missing, or the scroll offset is wrong. Well, after hours and hours of experimenting, it turns out that ViewPort->RxOffset and ViewPort->RyOffset are indeed the correct variables that need to be changed to move around a larger source bitmap, but they get interpreted differently by different Kickstart/OS/chipset versions - it looks as if KS3.0 on AGA chipset, and KS3.1 SetPatch'd by OS3.9 on AGA chipset, might be messing up VSprites when scrolling, and earlier KS versions always scroll by low-res pixels, regardless of actual display (high) resolution. As a quick fix I'm focusing on what is probably still the most common Amiga configuration: Amiga 500, OCS chipset, Kickstart 1.3. I'll work on compatibility or maybe a separate version of the game later.

Basic screen mockup, to get an idea of object's sizes, and screen layout

And a "bug" in the docs was discovered: When using VSprites, you "reserve" some hardware sprites from VSprite usage by setting/clearing bits in GelsList->sprRsrvd. The docs give contradictory information about what "reserve" actually means - bit set or clear? It has now been proven and confirmed that bits need to be set to allow VSprite usage of that hardware sprite, and bits need to be cleared to "reserve" the corresponding hardware sprite from VSprite usage. Einstein-alike.

Anyway - after overcoming these obstacles it's beginning to look like... a game!

ViewPorts are a great thing, by the way. There are a couple of limitations, but whenever you run low on colors, need a different origin for your drawing coordinates, or maybe are thinking about an alternative to a dual-playfield, a new ViewPort might solve the problem.

So now it's got a scrollable bitmap, separate status bar, sprites, tiles, game map files, and a rudimentary "physics" engine that allows sideways movement and drops. That's a huuuge step forward!

No, that's not the... game! Just an early tileset.

Linux IFF picture viewer xiffview, which was created as a side-product of game development, now really comes in handy. I use it regularly, it has become part of my makefiles, and I add features as I need them.

When writing software that's handles data for different architectures, you have to pay attention to a lot of details. The reversed endianness (MSB on m68k vs. LSB on x86) has been mentioned many times. Also different compilers on different CPU architectures may have different data storage types - an "int" on a modern x86 machine is not be the same size as an "int" on Amiga. I encountered this just recently, when adding some code to xiffview that writes Amiga UWORD values to a text file, using something like fprintf("0x%04x", value). The UWORDs written had too many digits, too large for an Amiga 16-bit number. It looks like a bug on first sight, but the Linux x86 compiler is simply made to handle larger numbers (by default) than an Amiga C compiler. The solution is simple: you have to explicitly cast the value to a 16-bit data type, like this: fprintf("0x%04x", (short int) value).

Thanks for reading, c u next time!

* * *

Click here for an overview of all AADevLog articles

 

Tuesday, October 5, 2021

AADevLog #1 - xiffview 0.4, CLI 3d-printing, and a little bit of research

Over the last few months I've looked into several different subjects with no particular focus, but I got some results nontheless.

You might have seen the latest release of xiffview (v0.4), my little IFF ILBM picture viewer for Linux. It's a side product, created to simplify development for the Amiga, but I have a couple of further ideas to turn it into a really useful tool, e.g. add cropping, bitplane manipulation, etc. Anyway, for now it has learned something about palettes and sprites - see AmiNet readme file.

Another side product of some hardware changes happening in my workplace is a CLI controlled .gcode 3d-printing program written in quite Amiga-ish C code, which I call "reprint". It's currently very beta, and for Linux, but it successfully sends g-code to the printer - maybe another brick in building 3d-printing support for the Amiga? Some day I'll try to wire up something, then recompile "reprint" for Amiga, and keep my fingers crossed. ;-)

And then there's this little question that's been nagging me for years: when writing C code, is it good practice to copy stuff to local vars?

Here's what I mean by that: I have a tendency to create a large struct that holds my program's data, settings, pointers, etc., then access that data as members of that struct, e.g. in (inner) loops. I always wonder if this creates a complicated set of CPU instructions when compiled to assembler, esp. when accessing "deep" members - thus if it would be better to copy member data from global struct to a local variable, then use that variable e.g. in (inner) loops.

For single access this is obviously not an issue - but what about repeatedly accessing such member data? So I did some actual testing.

Looking at this piece of repeatedly struct-member-accessing (pseudo) C code...

for (loops) { n = some_pointer->some_member.some_number; }

...and comparing it to this piece of (pseudo) C code, which first copies to local var, ...

my_n = some_pointer->some_member.some_number;
for (loops) { n = my_n; }

...one would probably assume it's obvious the latter version is faster, because the code inside the loop looks vastly simpler. On the other hand someone somewhere suggested it wouldn't make a (noticeable) difference due to compiler optimization.

After a few test runs (pretty much using the pseudo code above), I think it can indeed be considered good practice to copy to local var. Results vary strongly, esp. on my 8-core Linux machine, but on the Amiga the latter version of the code is near-consistently about 25% faster than the former. With the struct member inside the loop, the compiler, or someone else, obviously didn't see we're accessing the same data over and over again. There are probably a hundred things to keep in mind, e.g. loop-size vs. CPU cache, size of struct, location of member, amount of data, compiler abilities, etc., - but it looks as if copying data to local var should indeed be preferred. Under certain circumstances it executes faster, and in most cases it's much more readable and saves a lot of typing.

What do you think? Any experience, opinion?

C u next time!

* * *

Click here for an overview of all AADevLog articles

Sunday, April 18, 2021

AADevLog #0 - IEEE and STL 3D file format

This is the first in a loose series of developer logs about projects I'm working on, from little experimental or example code, to more complex ideas. On my quest to create some proper Amiga software - a game! - I have encountered, and will encounter, lots of challenges. 

After a steep learning curve and endless hours of failure, finally there is some usable success - yay! ;-) Over the years I've started many ambitious projects, but all of these turned out to be quite a mess. I realized I needed more basic knowledge and better testing of individual code sections, along with improving my concepts of software architecture. So basically while learning more details about how to use C and AmigaOS, my main task was to scale down my ideas and get stuff to work together properly, so I don't end up with countless individual functions each doing only half-way what's required - in other words: a mess.

Ok, long story short, with "a little bit" (cough) of prior training, I'll just share some of my experience, starting with something I created recently, over a couple of days:

First version of "stl_info" for Linux and AmigaOS

It's called "stl_info", prints out information about an STL 3D file (binary format, as exported by e.g. Blender), and works on Linux and AmigaOS. For Linux, gcc is used for compilation, for Amiga it's vbcc (on Linux, cross-compiling). Currently the number format printed out is a bit weird (for debugging) - just think of the comma as a ".", and omit the "0." (zero integer part of float fraction).

Nothing too spectacular, but maybe a first step towards 3d printing on the Amiga? Anyway, apart from reading some header bytes from the STL file, then some 32bit numbers, etc. there were two slightly more interesting things about developing the program: 

First, long numbers and the endianness thing. To make sure number storage would be identical on both my 64-bit Linux computer and the Amiga I've created a header file called "amigatypes.h" that defines e.g. ULONG as 32 bits like on the Amiga, WORD as 16 bits, etc. Still the byte order is incompatible: my Linux computer is an Intel x86, so it looks at it's bytes least-significant-first, called little-endian, or Intel-byte-order. The Amiga is a Motorola M68000, and looks at it's bytes the other way round, most-significant-first, called big-endian, or Motorola-byte-order. I tried to get around this somehow, but I ended up adding some separate code that swaps bytes around (see picture: bytereverse.c), and is activated in source code by a compiler define "AMIGA". 

And then, IEEE754 numbers. In an STL binary file, Vertex coordinates are stored in IEEE754 floating point number format. (LSB first, part of the file format definition.) If you want to use this number format on AmigaOS as a float datatype, you'll probably be fine with the conversion function "SPFieee()" provided by mathtrans.library, but I wanted to be able to decode IEEE numbers to some custom format, something fixed-point, maybe for a future... game! IEEE numbers are made of three sections of bits: sign, exponent, and mantissa. I won't go into detail here, you can look it up (see links below) if you like. It looks a bit complicated on first sight, but once you work yourself through the individual steps of decoding, you realize: the exponent is just the bit-shift of the mantissa. It looks complicated when expressed as decimal-based math, but is pretty obvious in binary, and probably creates a useable fixed-point fraction. That's nice. Yes, there are more bits involved, you have to do a little bit of fiddling, but the exponent-bit-shift is really neat, feels super binary. (Well, it is.) :-)

If you're interested in IEEE754 here are some links:

https://www.h-schmidt.net/FloatConverter/IEEE754.html

https://en.wikipedia.org/wiki/IEEE_754


So far for the first AADevLog - c u next time!

* * *

Click here for an overview of all AADevLog articles