question about pixel to character conversion

Started by ervin, 08:41, 07 April 10

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

ervin

Hi all.

I've been trying to think of a number of ways to speed up my 3d-maze conversion that I released a couple of months ago, and I think I'm finally on the right track.
The problem is... how to do it?

At the moment, the game is double-buffered, and it uses lots of memory as a result.
There is also a small speed penalty with the technique i'm using (i'm doing double the number of visible prints for the score panel, because both the front and back screens need to have updated details on them).

Anyway, I thought I could avoid a lot of these problems by removing the double-buffering, and only clearing and/or printing to the bits of the screen that have changed.

Someone suggested something similar in the 3d-maze thread. I believe it was redbox, so a big thanks for that idea!

This would mean that I could also remove the whole-screen cls (which is admittedly very fast, but still, eh?), and that I could also remove the doubling-up on displaying the score panel.

I'm not entirely sure that I have my technique nailed down yet, but it revolves around the idea of knowing which character block a pixel sits in.

For example, when I PLOT 0,399 I get a pixel plotted in the top left corner of the screen.
This is of course character position 1,1.

I want to store a matrix of 25x25 cells, and each cell will either be 0 or 1 depending on whether or not it has had a pixel plotted to it.

My problem is that I don't know how to convert from pixel 0,399 to character 1,1.
Does anyone know how I could do this?

Thanks for any help.

arnoldemu

Quote from: ervin on 08:41, 07 April 10
Hi all.

I've been trying to think of a number of ways to speed up my 3d-maze conversion that I released a couple of months ago, and I think I'm finally on the right track.
The problem is... how to do it?

At the moment, the game is double-buffered, and it uses lots of memory as a result.
There is also a small speed penalty with the technique i'm using (i'm doing double the number of visible prints for the score panel, because both the front and back screens need to have updated details on them).

Anyway, I thought I could avoid a lot of these problems by removing the double-buffering, and only clearing and/or printing to the bits of the screen that have changed.

Someone suggested something similar in the 3d-maze thread. I believe it was redbox, so a big thanks for that idea!

This would mean that I could also remove the whole-screen cls (which is admittedly very fast, but still, eh?), and that I could also remove the doubling-up on displaying the score panel.

I'm not entirely sure that I have my technique nailed down yet, but it revolves around the idea of knowing which character block a pixel sits in.

For example, when I PLOT 0,399 I get a pixel plotted in the top left corner of the screen.
This is of course character position 1,1.

I want to store a matrix of 25x25 cells, and each cell will either be 0 or 1 depending on whether or not it has had a pixel plotted to it.

My problem is that I don't know how to convert from pixel 0,399 to character 1,1.
Does anyone know how I could do this?

Thanks for any help.
Are you using BASIC?

BASIC uses 640x400 for all the modes, the reason is that if you draw a circle it remains a circle and not an elipse.

To convert:

text_x, text_y are the text coords in the range 1.. (20 for mode 0, 40 for mode 1, 80 for mode 2), 1..25. Where 1,1 is the top-left.
x_pixel, y_pixel are in the range 0-639 and 0-399. Where 0,0 is the bottom left.

Mode 0:
text_x = (x_pixel/32)+1;
Mode 1:
text_x = (x_pixel/16)+1;
Mode 2:
text_x = (x_pixel/8)+1;

Then for y (same for all modes):
text_y = ((400-y_pixel)/16)+1

If you're using asm then It may be easier to use your own coordinates based on 0,0 being top-left and working in bytes for x and lines for y. This is what I use for my games.

I have an array which stores the screen address for the start of each line. I use the y coord to index into the array and fetch the value then I add x to it.

If you want to work in chars, you can use the firmware function "SCR CHAR POSITION" to convert chars to screen address, and then use scr_next_line to move to the next line.

Double buffering: Instead of clearing the screen, could you redraw the lines to erase them?
Use XOR or draw them to background colour? Or even, just draw over the top?
I understand what you are saying about the status panel. I need to do the same for my games, but here I only update what has changed.

So when I change the score, I store the rectangle in a list so that it is redrawn again when the screen is swapped.
My games. My Games
My website with coding examples: Unofficial Amstrad WWW Resource

ervin

#2
Thanks for your very informative answer, there's a lot of good info in there.

I'm using assembler to plot the pixels.

SCR CHAR POSITION is something I have considered, but it seems to be the reverse of what I need.
My assembler code is calculating the memory address of a pixel, so if there is a way to convert that memory address to a character position, that would be perfect.

Indeed I've also considered drawing over the top of lines to erase them, but without double buffering that would be very flickery. At the moment 3d-maze has no display flickering at all.

Using an array may worth investigating though...

Thanks again.

arnoldemu

Quote from: ervin on 09:17, 07 April 10
Thanks for your very informative answer, there's a lot of good info in there.

I'm using assembler to plot the pixels.

SCR CHAR POSITION is something I have considered, but it seems to be the reverse of what I need.
My assembler code is calculating the memory address of a pixel, so if there is a way to convert that memory address to a character position, that would be perfect.

Indeed I've also considered drawing over the top of lines to erase them, but without double buffering that would be very flickery. At the moment 3d-maze has no display flickering at all.

Using an array may worth investigating though...

Thanks again.
Memory address to character pos:

This is a bit more involved.

offset = (scr_address-scrbase) & 0x07ff;

e.g. &c834 - &c000 -> &834 & 0x07ff -> &34

(scrbase depends on crtc register r12 and r13. i.e. hardware scrolling.
scrbase = (((r12&0x03)<< 8 |(r13))*2)

text_y = (offset/(charwidth*2))+1

charwidth = r1 value (e.g. standard size is 40)

Mode 2:
text_x = ((offset % (charwidth*2))+1
Mode 1:
text_x = (((offset % (charwidth*2))/2)+1
Mode 0:
text_x = (((offset % (charwidth*2))/4)+1

(% = remainder of division)

I think that should do it.
My games. My Games
My website with coding examples: Unofficial Amstrad WWW Resource

ervin

That is FANTASTIC!
I'll see if I can make my idea work using that information.

Thanks so much for taking the time to help me out.

arnoldemu

Quote from: ervin on 10:13, 07 April 10
That is FANTASTIC!
I'll see if I can make my idea work using that information.

Thanks so much for taking the time to help me out.
this week my wife and daughter are visiting her mum for a week (a short plane journey away), so I have lots of spare time ;)

But after this week...
My games. My Games
My website with coding examples: Unofficial Amstrad WWW Resource

redbox

Quote from: ervin on 08:41, 07 April 10
Someone suggested something similar in the 3d-maze thread. I believe it was redbox, so a big thanks for that idea!

Hey, that's cool that you're trying to implement this idea - do keep us informed as I'd like to know if it's any faster (and can possibly optimise it for future projects).

I see arnoldemu's programming advice is as rock-solid as ever.  When the wife and kids are away, he really comes out to play  ;)

ervin

#7
Alrighty!

Has it really been this long since I started this thread?

Anyway, I've been working away in my spare time on 3d-maze, working on the idea of keeping track of which parts of the screen change, in order to reduce the amount of screen clearing going on.

And... it's close to being finished!
Hopefully in a few weeks, bugs notwithstanding.

I've found all sorts of crazy shortcuts, tricks, smoke n mirrors, good ideas, etc etc etc, and the game is now maybe 3 times faster than the version I posted late last year.
I've also done a lot of work on optimising the z80 code - it's probably about as good as my current abilities will allow.

I'm actually really surprised just how fast it is. It makes me wonder how much better a lot of slow games could have been back in the day, if the programmers had the time to really play with different optimisation techniques and ideas.

One of the coolest things about the technique I've used is that there is no flickering at all, even though I'm no longer using double-buffering.

Fingers crossed I can upload the finished game soon!

And once this is done and dusted, I can get back into the ACU Type-ins Project!

arnoldemu

Quote from: ervin on 08:12, 24 August 10

Has it really been this long since I started this thread?
Well game development does take a long time ;)

Quote from: ervin on 08:12, 24 August 10
And... it's close to being finished!
Hopefully in a few weeks, bugs notwithstanding.
Yay!

Aw you tease.

It is always good to see new games for cpc. I'm looking forward with interest to see the result :)
And of course playing it a bit too ;)
My games. My Games
My website with coding examples: Unofficial Amstrad WWW Resource

Sykobee (Briggsy)

Sounds good! And with all that spare memory you can have more mazes or bigger mazes! Or keep track of loads of enemies that you have to kill :-).


Video or screenshots?

ervin

Thanks for the kind words guys.  :)

I don't have a video yet, or screenshots, as the very last thing left to do is to finish the screen clearing routines.
They have been written, and applied for several bytes in screen memory, but there are still a number of them left to do, and the screen is still a bit messy when playing the game.

I could indeed have more or bigger mazes, but I'll probably turn to writing a PC/mac/iphone game using Unity after this is done. Or maybe I'll try something else on the cpc... don't know yet.

Come to think of it, I wish I had the source code to 3d monster maze. I'd love to write a cpc version of that using the code from this game!

Powered by SMFPacks Menu Editor Mod