Skip to content

A Development BLOG (in screenshots)

Dr Warren Creemers edited this page Aug 2, 2016 · 42 revisions

History

  • Early 2000' I decided to break into the xeen ".cc" file format, got the basics sorted out, but didn't get the graphics files unpacked.
  • Created a facebook page for people who play WoX
  • Discovered some other guys had done a LOT better job getting into xeen ".cc" format than I did.
  • Watched the other guys develop http://xeen.wikia.com/ This monuments work, by other people, is the real hero; openXeen just stands on its shoulders.
  • I created a c# application that was the foundation of a xeenEngine. It never saw a public release.

Old C# Platform

  • Development stopped (I think I became interested In arduinos or something).

Current (prior to github)

  • Late April 2016, I Moved to Canberra. Decided to do some hobby code.

  • Picked up xeen and extracted a sprite...
    First Sprite

  • May 2016, game infrastructure is evolving, sprites are animated, a vision for the architecture now exists.
    Animated Sprite

  • June 2016, Starting to think in java again! (maybe that's not a good thing). Got a hud up and going, because the frontend was lacking due to developing the backend.
    HUD

Current (since joining github)

  • June 2016, sky in place, Commit to GIT; hopefully making the code public forces me to keep the code base presentable.
    Sky

  • June 2016, Map support is a focus, Sprites are being organised, MM4 now supported. MM4

  • June 2016, Some map support is working, mini-map is now renderable. MM4

  • June (19th) 2016, Screen buddies and other important things. MM4

  • June (21st) 2016, Hello Adventurers. MM4

  • June (23rd) 2016, Able to render a ground surface tile. MM4

  • June (30th) 2016, Able to move around a map. Map

  • July (2nd) 2016, Able to walk around the whole darkside map. Map

First release - v0.1.0 alpha

With this first release I wanted to take stock of where the code is at, where I am heading and what my time is being spent on. I have a job and a family, so openXeen is largely coded in at night or when I can grab 5 minutes. This forces me to code in a manor 'resistant to interruptions' (finish one logical area at a time, use a fully thought out architecture).

What I also need to do Is audit how much time I spend on what. Which is where this line of code by package breakdown comes into play. It breaks my 8.8k lines of code down, telling me where my effort has been spent. I aim to update this graph at every delivery milestone. What I learnt:

  • 1/3 of the code is concerned with reading and loading files contained in the .cc archives (reds)
  • 1/3 of the code is 'toolbox code' (oranges), stuff that is not relevant to xeen, and ideally would have been provided by java or a 3rd party library.
  • 1/6 is in game mechanics (blues), arguably this is an over investment in mechanics early on. But I am prioritising having a 'game' by the end of the year, not a tech demo.
  • 1/6 is in rendering (greens). The rendering code has been kept as simple as possible. I love to write rendering engines, and know this is a trap. You spend far too much time on rendering 'goodies', then your engine was built without respect to the actual game (because the game did not exist yet) and you have nothing to show in your render. Your'e exhausted, and sometimes coded into a corner.

  • July (16th) 2016, Basic support for MM3. MM3

July (17th) 2016, Reverse engineering MM3.

The MM3 palette was pretty elusive, as there was no palate like file in the .cc. This meant I would have to examine the programs execution to find the palette being loaded into the video card.

VGA mode 13h my old friend, we meet again (Haven't touched this since the 90's).
Jogging my memory with some old code, I found the 'normal way' the alter mode 13h's palette. You would outb 0x3C8 a palette index then outb 0x3C9 Three times red (0-63) green (0-63) blue (0-63). Then I think the palate index increments and you just outb 0x3C9 till you have loaded your palette segment. AFAIK this altered the vga output on the fly... output for that index changed mid screen refresh if you were not careful. This could also be accomplished via a bios call, but those were slow and you had to achieve these alterations between CRT vertical retrace cycles (to avoid odd effects). So I will stick with looking for the code related to the sensible approach.

I think the palette entries originally altered a DAC chip's settings (presumably its now emulated via a buffer). I am not sure on the maths of how the DAC worked.

  • The highest rgb intensity value was 63, but on a modern display its 255
  • However 63 (11 1111) << 2 == 252 (1111 1100).
  • So full VGA mode 13h intensity is less than 255 under standard shift operations.
  • I programmed a shift that repeated the bit at position 0, rather than padding 0's.
  • Comparing to the dosbox emulation of mm3, this generated a less grimy looking result.
  • Not sure which is correct, will have to consult the pink shirt book.

Anyway to get the palette, I ran dosbox debug and logged the first million cpu instructions loading and playing xeen. Pretty soon I had filled a 4bg file and exited. grep -i 'out' LOGCPU.TXT reduced this monster to something manageable.

So in the code below I am interested in out dx, ? where dx = 0x3C8 - 0x3C9.
Look around and it looks promising.

  • One outb to 0x3C8, followed by 768 (256*3) outb's to 0x3C9
  • But AL is 00 in all cases. This is code to blank the screen.

Looking back in the 4gb file I find all the code around what I grep'd, and it is defiantly just writing 0's

9AF9:00001200  lodsb        EAX:00000000 EBX:000003C8 ECX:00000010 EDX:000003C9 ESI:0000003A EDI:00000336 EBP:000001BB ESP:0000FF98 DS:9AF9 ES:9AF9 FS:0000 GS:0000 SS:1A7D CF:0 ZF:0 SF:1 OF:0 AF:0 PF:1 IF:1
9AF9:00001201  out  dx,al   EAX:00000000 EBX:000003C8 ECX:00000010 EDX:000003C9 ESI:0000003B EDI:00000336 EBP:000001BB ESP:0000FF98 DS:9AF9 ES:9AF9 FS:0000 GS:0000 SS:1A7D CF:0 ZF:0 SF:1 OF:0 AF:0 PF:1 IF:1
9AF9:00001202  lodsb        EAX:00000000 EBX:000003C8 ECX:00000010 EDX:000003C9 ESI:0000003B EDI:00000336 EBP:000001BB ESP:0000FF98 DS:9AF9 ES:9AF9 FS:0000 GS:0000 SS:1A7D CF:0 ZF:0 SF:1 OF:0 AF:0 PF:1 IF:1
9AF9:00001203  out  dx,al   EAX:00000000 EBX:000003C8 ECX:00000010 EDX:000003C9 ESI:0000003C EDI:00000336 EBP:000001BB ESP:0000FF98 DS:9AF9 ES:9AF9 FS:0000 GS:0000 SS:1A7D CF:0 ZF:0 SF:1 OF:0 AF:0 PF:1 IF:1
9AF9:00001204  lodsb        EAX:00000000 EBX:000003C8 ECX:00000010 EDX:000003C9 ESI:0000003C EDI:00000336 EBP:000001BB ESP:0000FF98 DS:9AF9 ES:9AF9 FS:0000 GS:0000 SS:1A7D CF:0 ZF:0 SF:1 OF:0 AF:0 PF:1 IF:1
9AF9:00001205  out  dx,al   EAX:00000000 EBX:000003C8 ECX:00000010 EDX:000003C9 ESI:0000003D EDI:00000336 EBP:000001BB ESP:0000FF98 DS:9AF9 ES:9AF9 FS:0000 GS:0000 SS:1A7D CF:0 ZF:0 SF:1 OF:0 AF:0 PF:1 IF:1

But I now know the palette setting code is located 9AF9:11F4 Assuming there are palette fades etc, I use the breakpoint feature of dosbox debug... and catch it every time. Yep, lots of screen fades. I hit resume often, to get through the intro, and load a game. Before the last fade up finishes I log the output again.

Bingo:

9AF9:000011F4  out  dx,al   EAX:00000000 EBX:000003C8 ECX:00000010 EDX:000003C8 ESI:00000036 EDI:00000336 EBP:0000FE86 ESP:0000FE7A DS:9AF9 ES:9AF9 FS:0000 GS:0000 SS:1AC9 CF:0 ZF:1 SF:0 OF:0 AF:0 PF:1 IF:1
9AF9:000011F9  out  dx,al   EAX:00000000 EBX:000003C8 ECX:00000010 EDX:000003C9 ESI:00000037 EDI:00000336 EBP:0000FE86 ESP:0000FE7A DS:9AF9 ES:9AF9 FS:0000 GS:0000 SS:1AC9 CF:0 ZF:0 SF:1 OF:0 AF:0 PF:1 IF:1
9AF9:000011FB  out  dx,al   EAX:00000000 EBX:000003C8 ECX:00000010 EDX:000003C9 ESI:00000038 EDI:00000336 EBP:0000FE86 ESP:0000FE7A DS:9AF9 ES:9AF9 FS:0000 GS:0000 SS:1AC9 CF:0 ZF:0 SF:1 OF:0 AF:0 PF:1 IF:1
9AF9:000011FD  out  dx,al   EAX:00000000 EBX:000003C8 ECX:00000010 EDX:000003C9 ESI:00000039 EDI:00000336 EBP:0000FE86 ESP:0000FE7A DS:9AF9 ES:9AF9 FS:0000 GS:0000 SS:1AC9 CF:0 ZF:0 SF:1 OF:0 AF:0 PF:1 IF:1
9AF9:000011FF  out  dx,al   EAX:0000003F EBX:000003C8 ECX:00000010 EDX:000003C9 ESI:0000003A EDI:00000336 EBP:0000FE86 ESP:0000FE7A DS:9AF9 ES:9AF9 FS:0000 GS:0000 SS:1AC9 CF:0 ZF:0 SF:1 OF:0 AF:0 PF:1 IF:1
9AF9:00001201  out  dx,al   EAX:0000003F EBX:000003C8 ECX:00000010 EDX:000003C9 ESI:0000003B EDI:00000336 EBP:0000FE86 ESP:0000FE7A DS:9AF9 ES:9AF9 FS:0000 GS:0000 SS:1AC9 CF:0 ZF:0 SF:1 OF:0 AF:0 PF:1 IF:1
9AF9:00001203  out  dx,al   EAX:0000003F EBX:000003C8 ECX:00000010 EDX:000003C9 ESI:0000003C EDI:00000336 EBP:0000FE86 ESP:0000FE7A DS:9AF9 ES:9AF9 FS:0000 GS:0000 SS:1AC9 CF:0 ZF:0 SF:1 OF:0 AF:0 PF:1 IF:1
9AF9:00001205  out  dx,al   EAX:0000003C EBX:000003C8 ECX:00000010 EDX:000003C9 ESI:0000003D EDI:00000336 EBP:0000FE86 ESP:0000FE7A DS:9AF9 ES:9AF9 FS:0000 GS:0000 SS:1AC9 CF:0 ZF:0 SF:1 OF:0 AF:0 PF:1 IF:1
9AF9:00001207  out  dx,al   EAX:0000003C EBX:000003C8 ECX:00000010 EDX:000003C9 ESI:0000003E EDI:00000336 EBP:0000FE86 ESP:0000FE7A DS:9AF9 ES:9AF9 FS:0000 GS:0000 SS:1AC9 CF:0 ZF:0 SF:1 OF:0 AF:0 PF:1 IF:1
9AF9:00001209  out  dx,al   EAX:0000003C EBX:000003C8 ECX:00000010 EDX:000003C9 ESI:0000003F EDI:00000336 EBP:0000FE86 ESP:0000FE7A DS:9AF9 ES:9AF9 FS:0000 GS:0000 SS:1AC9 CF:0 ZF:0 SF:1 OF:0 AF:0 PF:1 IF:1
9AF9:0000120B  out  dx,al   EAX:0000003A EBX:000003C8 ECX:00000010 EDX:000003C9 ESI:00000040 EDI:00000336 EBP:0000FE86 ESP:0000FE7A DS:9AF9 ES:9AF9 FS:0000 GS:0000 SS:1AC9 CF:0 ZF:0 SF:1 OF:0 AF:0 PF:1 IF:1
9AF9:0000120D  out  dx,al   EAX:0000003A EBX:000003C8 ECX:00000010 EDX:000003C9 ESI:00000041 EDI:00000336 EBP:0000FE86 ESP:0000FE7A DS:9AF9 ES:9AF9 FS:0000 GS:0000 SS:1AC9 CF:0 ZF:0 SF:1 OF:0 AF:0 PF:1 IF:1
9AF9:0000120F  out  dx,al   EAX:0000003A EBX:000003C8 ECX:00000010 EDX:000003C9 ESI:00000042 EDI:00000336 EBP:0000FE86 ESP:0000FE7A DS:9AF9 ES:9AF9 FS:0000 GS:0000 SS:1AC9 CF:0 ZF:0 SF:1 OF:0 AF:0 PF:1 IF:1
9AF9:00001211  out  dx,al   EAX:00000038 EBX:000003C8 ECX:00000010 EDX:000003C9 ESI:00000043 EDI:00000336 EBP:0000FE86 ESP:0000FE7A DS:9AF9 ES:9AF9 FS:0000 GS:0000 SS:1AC9 CF:0 ZF:0 SF:1 OF:0 AF:0 PF:1 IF:1
9AF9:00001213  out  dx,al   EAX:00000038 EBX:000003C8 ECX:00000010 EDX:000003C9 ESI:00000044 EDI:00000336 EBP:0000FE86 ESP:0000FE7A DS:9AF9 ES:9AF9 FS:0000 GS:0000 SS:1AC9 CF:0 ZF:0 SF:1 OF:0 AF:0 PF:1 IF:1
9AF9:00001215  out  dx,al   EAX:00000038 EBX:000003C8 ECX:00000010 EDX:000003C9 ESI:00000045 EDI:00000336 EBP:0000FE86 ESP:0000FE7A DS:9AF9 ES:9AF9 FS:0000 GS:0000 SS:1AC9 CF:0 ZF:0 SF:1 OF:0 AF:0 PF:1 IF:1
9AF9:00001217  out  dx,al   EAX:00000035 EBX:000003C8 ECX:00000010 EDX:000003C9 ESI:00000046 EDI:00000336 EBP:0000FE86 ESP:0000FE7A DS:9AF9 ES:9AF9 FS:0000 GS:0000 SS:1AC9 CF:0 ZF:0 SF:1 OF:0 AF:0 PF:1 IF:1
9AF9:00001219  out  dx,al   EAX:00000035 EBX:000003C8 ECX:00000010 EDX:000003C9 ESI:00000047 EDI:00000336 EBP:0000FE86 ESP:0000FE7A DS:9AF9 ES:9AF9 FS:0000 GS:0000 SS:1AC9 CF:0 ZF:0 SF:1 OF:0 AF:0 PF:1 IF:1
9AF9:0000121B  out  dx,al   EAX:00000035 EBX:000003C8 ECX:00000010 EDX:000003C9 ESI:00000048 EDI:00000336 EBP:0000FE86 ESP:0000FE7A DS:9AF9 ES:9AF9 FS:0000 GS:0000 SS:1AC9 CF:0 ZF:0 SF:1 OF:0 AF:0 PF:1 IF:1

5 minutes with a regex parser and I have the palette.

Results... MM3 pal


  • August(2nd) 2016, The outdoor exploration is coming together. Outdoor Environment Objects
You can’t perform that action at this time.