Since my last blog entry …
I played thru Mass Effect 1 and Mass Effect 2 and Mass Effect 3.
I played thru Horizon Zero Dawn 2 1/2 times (great game).
I played thru 4-5 Visual Novels.
Three days ago I decided I might continue my Vectrex efforts. After placing a couple of source codes online (github) I decided I’d like to continue with Telengard.
Porting old games is often a grey area – I bet this one is too. But there are already a couple of ports online, and no one seems to really care – I hope that will continue with the vectrex version.
My last efforts (last year) terminated with making 40bit floating point routines available to my “C” setup.
I basically took the routines found at: github: jefftranter and ported these. The linked source goes to the 6809 source code of Microsoft BASIC.
I know that Microsoft at some point released old BASIC sources – but I have not found any information regarding that specific 6809 version. So I am not 100% certain it is really free.
But… these are on github and if you search … at other places around the web. That does not make it more legal to use – but chances are good that nobody really cares.
When you port a game… you get to know these games very intimately. I always liked Telengard – but having now studied the source code… I must say “wow”… this truely is something that deserves the name “DnD” like. (I will not go into the discussion who might have copied from who…)
Just a view small facts:
- 20 different types of monsters
- undead, demons, dragons, etc which behave differently
- 6 spell levels, with 6 different spells ( = 36 “different” spells)
- healing, causing wounds, turn undead, invisible, strength, word of recal, light, protection from evil, teleport… to name but a few
- (10 different spell effects which can be active at any time!)
- 10 different pieces of equipment, which can be magically enhanced
- large dungeons (50 levels, with a 200×200 map each!)
- monsters that chase you after you evaded them
- special “locations” (9), like traps, thrones, teleports, cubes, stairs, altar, fountain…
The game itself to the normal observer seems really REALLY difficult. You can die after a few seconds. This is true and can be frustrating. You have to try it a few times… stay in the vicinity of an inn, after the initial frustrating start – if you just made a couple of levels… you can actually play it for a long time. You just have to be carefull.
In my youth I more than once ventured into the deepest pits of Telengard (level 50) – and survived.
The only thing this great game is missing – is actually a story or a goal. You have to be satisfied to play it – just to play it.
Anyways. What I wanted to write down is – where I am currently standing – and what my plans are.
The port will be done using GCC 6809, which is supported by Vide. It will use a couple of assembler routines to enhance stuff (like possible FLASH support, or faster graphics output).
Translating BASIC to “C”.
First I wanted to produce “nice” C-code… but that ship did sail some time ago. I am now content if the code works, and I won’t break my back to construct good procedural code.
On several occassions I use e.g. “goto” statements.
They work and in the final result (a bin file for the vectrex) the vectrex doesnt’t give a shit about
a “goto” statement.
By using “goto” I can keep more or less the same code structure as the original source and I
am fine with that! Apart from the dungeon generation I used Dan Boris documented BASIC as a basis for this port, see: http://www.atarihq.com/danb/Telengard.shtml
For the procedural generation I use the C64 code, since I wanted the dungeon to be the same as I remembered from my own “old days”.
By now I have implemented a great deal, namely:
- dungeon generation (100% exactly the same as the C64 version)
this includes the usage of Microsoft 40bit floating point routines (size about 7.5K)
to calculate ONE dungeon location the routines need:
* 8 float multiplications
* 8 fload additions/subtraction
* 2 conversions from float to int
These operations take about 18000 – 20000 cycles.
- dungeon display function, including line of sight “cropping” and “light effects”, also contents of the rooms are displayed while respecting the players stats
- monster generation
- fighting, including “fight” / “evade” / “cast”
- all spells (36!) in combat versions and non combat versions, spell selection and tools to use them (input for teleport spell e.g.)
- 2d dungeon navigation
- “real time” aspect of the game implemented
- special locations
- status display
- grafics (no sprites yet at all)
- sound (neither music – nor effects)
- grafical effects during spell casting
- no intro/extro/documentation
RAM does not seem to be problematic.
The screen setup will differ to other versions of Telengard, because the vectrex can not display a stable image with both the dungeon and all status information on screen. Screens will in some way be switchable.
As it turns out the game is quite a bit larger than anticipated. I was not really “wastefull” with memory I use and as said as yet there is nearly no grafics or sound. But the current binary file is already about 26kB large.
For that reason I am certain, that the final version will at least be 64kB in size. Most likely I will again reuse the Vectorblade PCB – this might enable me to also do persistent saving oft the current game.
Interesting project! Have you considered using scaled integer maths instead of floating point? That allows you to use lookup tables that could be stored in your 192k ROM. Here’s a link: http://wilsonminesco.com/16bitMathTables/index.html
In my professional embedded developer years, I never needed floating point, I could always get by with scaled integer. (Though the performance requirements I had never necessitated lookup tables either!)
Alternatively, there are also some other floating point routines for 6502 that could be converted to 6809, which might be more optimal than what GCC provides:
Thanks for the information and the link.
I guess one could probably come up with an integer based procedural map generation for Telengard.
The thing is I wanted exactly the same map as I remembered from my C64 days.
That made it in this case neccesary to use exactly the same floating point calculation.
(The floating points I use are not the gcc internal ones, but the ones from Microsoft BASIC for 6809)