News:

Printed Amstrad Addict magazine announced, check it out here!

Main Menu
avatar_Jean-Marie

Turrican (128K)

Started by Jean-Marie, 17:58, 12 April 25

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

Jean-Marie

While I'm not a fan of this new palette, if many people request it then Vox populi, vox Dei.
Now, there are also people who will prefer the regular one. So maybe a poll should be taken?

eto

Quote from: Jean-Marie on 11:22, 04 July 25So maybe a poll should be taken?
or just an option when starting the game? Not sure if that's feasible.

Jean-Marie

Quote from: eto on 11:49, 04 July 25or just an option when starting the game?
Yeah, I guess I could include alternate Levels A,B & C with a new palette, since only the first 3 levels are concerned. I will check this out; for the moment I'm struggling to find 100 bytes free to make the Spikes work with Axelay's optimized scrolling!

dodogildo


Quote from: eto on 11:49, 04 July 25or just an option when starting the game? Not sure if that's feasible.
That would be great, for the new palette.

Jean-Marie

The spikes are working too. Now, I'll see if I can tidy up the code, and next week I'll try to write the changes in the Level A file, which should be very challenging.

lightforce6128

Quote from: Jean-Marie on 17:05, 05 July 25next week I'll try to write the changes in the Level A file, which should be very challenging.

Hopefully it will not be challenging. For compression you can use any language, and modern computers will process the data in any language (also slow scripting languages) more than fast enough.

Whenever you find a sequence of the same byte A of length N, replace it with these four bytes: A,N,#A5,#CC. Only apply this if the sequence is longer than 4 bytes. That's all. This is not the best compression, but a fast one that will work acceptably on sprites and level maps with much background.

Example:

"1,2,3,4,  a,a,a,a,a,a  ,5,6,7,8"  gets  "1,2,3,4,  a,6,#A5,#CC  ,5,6,7,8" (spaces only for better readability)

Hopefully the used escape sequence #A5,#CC is not used anywhere in the data to compress. If it is, either the escape sequence can be changed to something else, or it has to be encoded as sequence of length 1 (what will cost 3 bytes):

Example:
"1,2,3,  #A5,#CC  ,4,5,6"  gets  "1,2,3,  #A5,1,#A5,#CC,  #CC  ,4,5,6" (replace the #A5 with a sequence of length 1)


Two questions remain:
  • Where should the file be loaded? Usually at the begin of the buffer that will contain the uncompressed data later.
  • And which routine says the decompressor where the compressed data is located? Needed are begin and end of the data.

Jean-Marie

I think the real difficulties will come with the levels where Parallax is used. Daren used animated tiles to create the effect, where background tiles are "slided" in the Tile Map. This is quite ingenious.
Level I (4.1) looks like a real nightmare with a slew of animated tiles (not only for the parallax).
It's quite easy to carry out LDI/LDD instructions on some linear memory, but with Axelay's optimization, the tiles offsets become shuffled, and that makes thing more complex and lengthy :-[

 
;;TURRICAN.LVI

org &1b78
ld ix,&1d07
ld b,&0f
ld a,(&c7f3)
ld c,a
l1b82:
ld l,(ix)
ld h,(ix+1)
ld a,l
cp &20
jp nc,l1ba6
bit 0,c
jp z,l1b94
inc h
l1b94:
bit 1,c
jp z,l1b9a
dec l
l1b9a:
bit 2,c
jp z,l1ba0
dec h
l1ba0:
bit 3,c
jp z,l1ba6
inc l
l1ba6:
ld (ix),l
ld (ix+1),h
inc ixl
inc ixl
djnz l1b82
ld a,(&c7f3)
rra
jp nc,l1bfc
ld de,&1920
ld hl,&6cb0
REPEAT 8:ldi:ENDM
ld de,&6cb0
call @LDIR-24-24
ld hl,&1920
REPEAT 8:ldi:ENDM
ex de,hl
ld e,&20
call @LDIR-8-8
ld de,&6cd0
call @LDIR-24-24
ld hl,&1920
call @LDIR-8-8
l1bfc:
ld a,(&c7f3)
bit 1,a
jp z,l1c28
ld ix,&6cb0
ld b,&10
l1c0a:
ld e,(ix)
ld d,(ix+1)
ld l,(ix+&20)
ld h,(ix+&21)
ld (ix),h
ld (ix+1),e
ld (ix+&20),d
ld (ix+&21),l
inc ixl
inc ixl
djnz l1c0a
l1c28:
ld a,(&c7f3)
bit 2,a
jp z,l1c72
ld de,&1920
ld hl,&6cc8
REPEAT 8:ldi:ENDM
ld de,&6ccf
ld l,&c7
call @LDDR-24-24
ld e,&b0
ld hl,&1920
REPEAT 8:ldi:ENDM
ex de,hl
ld e,&20
ld l,&e8
call @LDIR-8-8
ld de,&6cef
ld l,&e7
call @LDDR-24-24
ld e,&d0
ld hl,&1920
call @LDIR-8-8
l1c72:
ld a,(&c7f3)
bit 3,a
jp z,l1c9e
ld ix,&6cb0
ld b,&10
l1c80:
ld e,(ix)
ld d,(ix+1)
ld l,(ix+&20)
ld h,(ix+&21)
ld (ix),d
ld (ix+1),l
ld (ix+&20),h
ld (ix+&21),e
inc ixl
inc ixl
djnz l1c80
l1c9e:
ld a,(&dea0)
ld hl,&3e15
rra
jp c,l1cac
ld l,&55
l1cac:
ld de,&6c00
call @LDIR-64-64
ld ix,(&6c7e)
ld iy,(&6c7c)
ld e,&7f
ld hl,&6c7b
call @LDDR-60-60
ld (&6c42),iy
ld (&6c40),ix
ld hl,&6be0
ld de,&1920
call @LDIR-16-16
ld a,(&dea0)
rra
ret c
ld de,&6be0
call l1cef
ld hl,&1920
l1cef:
ld b,&08
l1cf1:
ld c,(hl)
inc l
ld a,(hl)
inc l
exx
ld b,&87
ld c,a
ld a,(bc)
exx
ld (de),a
inc e
ld a,c
exx
ld c,a
ld a,(bc)
exx
ld (de),a
inc e
djnz l1cf1
ret
REPEAT 9:rst 0:ENDM

ORG &9D80
REPEAT 95:ldi:ENDM
@LDIR:
ret

ORG &9E40
REPEAT 95:ldd:ENDM
@LDDR:
ret

lightforce6128

#182
Quote from: Jean-Marie on 10:02, 06 July 25I think the real difficulties will come with the levels where Parallax is used. Daren used animated tiles to create the effect, where background tiles are "slided" in the Tile Map. This is quite ingenious. Level I (4.1) looks like a real nightmare with a slew of animated tiles (not only for the parallax).

When I first saw this, I was really impressed. Paralax scrolling was not really common for the CPC. Until recently I thought it would use some kind of optical illusion, where the tiles contain the same background, but shifted differently then the tile offset. But this could not be used here, because it would interfere with reusing tiles throughout a level.

I did some further analysis and now have a better understanding about how the drawing works. There are three levels of image generation, not two!

  • The map of e.g. size 137x51 contains indices of blocks (not of tiles!).
  • There are 256 blocks, each containing 4x4 tile indices.
  • Finally there are 256 tiles, each containing 4x8 pixels.

With this trick the game achieves a compression ratio of 118:1 (or reduces the size by 99.2%). The drawn map has a size of 2192x1632 or 3.6 megapixel, while the three data structures only need 14.8 kilobytes.

By looking at tiles and blocks of level I (4.1) I found there are several blocks showing paralax background. But there are only four tiles (index 203 to 206). The whole paralax scrolling magic is done only in these four tiles!

lightforce6128

#183
For better visualization I append the map, blocks, and tiles of level A (1.1). I suppose this is not a big spoiler because almost everybody will know level 1.1 more than good enough.

Jean-Marie

I've managed to have the first level written on disc. It includes Axelay's optimized routines, with corrections for the animated tiles. 
I had it working by removing the compression process altogether. The drawback is that each level files will be 26 Kb :/
I worked out a small Visual Basic macro to compress data with the RLE algorithm; it's working nicely but but there are still some problems during the decompression conspicuously. I'll try to investigate further.
 

Axelay

Quote from: Jean-Marie on Today at 09:17I've managed to have the first level written on disc. It includes Axelay's optimized routines, with corrections for the animated tiles.
I had it working by removing the compression process altogether. The drawback is that each level files will be 26 Kb :/
I worked out a small Visual Basic macro to compress data with the RLE algorithm; it's working nicely but but there are still some problems during the decompression conspicuously. I'll try to investigate further.
 
I don't have time to look into this at all, so apologies if these suggestions are unworkable or have already been considered, but would it be possible to leave the level data as is and just have an assembly routine in memory that reformats the tile data after loading?  Or if there is no spare memory for that to be permanently in memory, or there are additional things you have needed to add to make it work, like for the animated tiles, could that simply be appended to the existing level data file, so then you only perhaps need add an extra call to some temporary code added to the data load that sorts things out after the original level data load has done it's 'usual' process?

Jean-Marie

Your "shuffled" data is working nicely as it is, I was able to adapt the code displaying the waterfall and the exhaust flames without too much overheads (Thanks again BTW!).
For the spikes, I had to append a "clean" copy of the original tiles (non-shuffled) at the end of the level file, indeed, as it was too complicated & lengthy to modify the original code to make it work with the shuffled tiles.
The problem stems from writing the new file on the disc, as Daren used some intricated code to uncompress the Data. But hopefully, I'll find a solution. I just need to have a serious look at the decoding routine.

lightforce6128

Quote from: Jean-Marie on Today at 12:51The problem stems from writing the new file on the disc, as Daren used some intricated code to uncompress the Data. But hopefully, I'll find a solution. I just need to have a serious look at the decoding routine.

Because I already spent some time on this: Can you describe a situation where it does not work?

As far as I remember, there is one access to tile 0 that cleans it after loading, for whatever reason.
Also some other tiles are used to transport other data (e.g. font data) and are reused afterwards for animation purposes.

What is also important for decoding is not the process itself, but where the compressed data is placed before decompression starts. Because you applied several changes, this position will be different from before. Until now I did not find the code location where this position is stored. It surely needs to be altered.

Jean-Marie

I'm progressing : I have located a part of the code which caused some troubles, at 1B39h.
It moved the tiles of the spikes & flames to a buffer used for the display. This was messing up with the shuffled data obviously. Actually, this part of the code can be safely removed because I use no buffer for drawing the spikes & flames.
Only the end of the procedure remains mysterious to me (after the palette setting).

org &1B39
ld bc,&002c
ld de,&d7cc
ld hl,&d7cb
ld (hl),&0004
ldir
;;ld bc,&0030
;;ld de,&6dc0
;;ld hl,&6930       ;;move spikes tiles to buffer
;;ldir
;;ld bc,&0040
;;ld de,&6d40
;;ld hl,&6cb0         ;;move flames tiles to buffer
;;ldir
ld hl,&1b1f
call &d600             ;;set palette
ld b,&0006
ld ix,&243e
ld de,&0006
ld hl,&24fe
l1b6e:
ld c,&0010
l1b70:
ld (ix+&0000),l
ld (ix+&0001),h
inc ix
inc ix
l1b7a:
ld a,(hl)
inc hl
cp &00d3
jp z,l1b85
add hl,de
jp l1b7a
l1b85:
dec c
jp nz,l1b70
djnz l1b6e
ret

Quote from: lightforce6128 on Today at 18:54Until now I did not find the code location where this position is stored. It surely needs to be altered.
I found the decoding routine at B000h, and the BC register seems to contains the size of the compressed data. I guess I'll have to modify it since the size is a bit larger with the new shuffled data.

org #b000
ld hl,(#b05b)      ;;hl=1BB0
ld de,(#b05d)      ;;de=1AFF
ld bc,(#b05f)      ;;bc=481A (data size?)
inc bc
ldir
ld ix,(#b063)      ;;ix=7FFF
ld hl,(#b065)      ;;hl=6319
ld de,(#b059)      ;;de=A5CC (escape code)
ld bc,(#b05d)      ;;bc=1AFF
lb01d:
ld a,(hl)
cp e
jr z,#b03f
ld (ix+#00),a
dec hl
dec ix
push af
ld a,h
cp b
jr nz,lb030
ld a,l
cp c
jr z,lb033
lb030:
pop af
jr lb01d
lb033:
pop af
ld a,(#b067)
or a
nop
nop
ret

lightforce6128

Quote from: Jean-Marie on Today at 20:06
Quote from: lightforce6128 on Today at 18:54Until now I did not find the code location where this position is stored. It surely needs to be altered.

I found the decoding routine at B000h, and the BC register seems to contains the size of the compressed data. I guess I'll have to modify it since the size is a bit larger with the new shuffled data.

But not only the size. The location is important as well. The starting point is not the begin of the data (what stays the same), but its end, because processing is done backwards. The end of the compressed data is definitely no longer where it was before.

Powered by SMFPacks Menu Editor Mod