Combining copper scrolling with copper background
In my current game project I'm scrolling a huge map with the algorithm described here: http://aminet.net/package/dev/src/ScrollingTrick
It is a combination of copper and blitter scrolling and needs to reset the bitplane pointers at a variable line on the screen. Now I have the problem that I would also like to have a copper background, which gives each line a different colour. It seems that the only option is to create the copper list dynamically in every new frame. But writing the dynamic part of that copper list requires nearly 50 scan lines (WAIT and COLOR for 240 lines and writing the BPLxPT at the split line)! Is there any way to improve that? Or a completely different approach to the problem? |
if the colors set by the copper also need to shift/scroll along with the bitmap, you need to move them around as well, which will be almost like generating a new copper list each frame.
with regards to the bitplane pointers, writing the modulos on each scanline and then updating those instead might save some (presuming your bitplanes are below 32k each). |
Quote:
Quote:
Quote:
|
Currently I'm writing the copper list like below. a2 points to the copper list. d0 is the line where I have to insert the split. Needs about 48 scan lines. :mad
Code:
lea Cl_colors(a2),a2 |
Some idea:
Generate two above copperlists and keep them in memory and write only things which will change, like all colors, screen pointers (for double buffering omit this) I have question: How many lines will have own color ? 256 ? (sorry I'm too tired to count from your source) |
Quote:
You're already doing something similar with bitplane memory. You don't build a new screen each frame. Instead you change the edges and shift the rest by changing pointers. Same thing will work with a copper list, except in one dimension instead of two. You'll need to have the copper enter the list at a variable point, with each scanline having at least a move and a wait for the end of the line. The last instruction of the list should include the BPLxPT moves and a strobe to the top of the list. By waiting for the end of the line between instructions, you can avoid special waits like the wait for line $100. Exiting the loop on the last displayable line might be tricky. You probably don't want the background to change after that. |
Quote:
This is not necessary, when I think about it. It already looks good enough when changing the color every 10 lines or so. Now I have a more flexible copper background definition, in this form: Code:
dc.w $d5e,10 There will be three variables to optimize this process: CbackPos: Current offset on the copper background, 0-2047 (not on the list). CbackPtr: Pointer to an entry of the above list, which defines the color of the topmost visible line. CbackOffs: Offset into the topmost color bar, i.e. number of lines which already left the display on top. But maybe this is still too complicated? I will think about the implementation now... |
Quote:
But as far as I understand, I still have to rewrite the VPOS-part of all the WAIT-instructions when scrolling vertically? The copper background should scroll vertically at half of the real scrolling speed. Quote:
But now I decided that I no longer want to change the color in each line (see above). |
(Modification of mc6809e's suggestion)
I'd create big copper list that has as many wait/move pairs as you have vertical pixels (2048?). WAIT only waits for end of horizontal line, MOVE changes background color. Normal copper list waits for first visible line, jumps to big copper list, matching Y-position. When you need to move split point, replace color register write with write to COPJMPx (and restore old COPJMPx with COLOR0 write) which handles the split and color change (if also needed) and finally jumps back to big copper list. Now you only need to change COPJMP pointer and 2 words (or more if you need to also exit the big list before end of display) in copper list when you need to change vertical position. Of course copper list will waste some time doing mostly useless waits and moves but it is still faster and more optimal than rewriting whole copperlist with CPU. |
Quote:
The WAIT instructions will only wait for end of line, but ignore the VPOS. Something like $00df,$00fe? After writing to COLOR the next line has started and I can wait for end of line again. Very good idea! Quote:
|
Quote:
Quote:
|
Quote:
|
Quote:
|
An interrupt that starts with a busy-wait for the intended HPOS can be predictably triggered for a minimum busy-wait on 68000. Should you have a fast CPU you waste part of a scanline busy-waiting, but on the other hand if the game runs on A500 the CPU can waste that time and still be able to run the game. A good method to know when you are A500-centric (write for the A500 platform specifically) but don't want to rule out faster Amigas.
|
Quote:
Thanks! |
This thread was really useful!
For my copper splitscreen solution, I originally was using 17 copper operations per line, which were: - The line wait - 12x spare ops for setting all 6x bitplane pointers (these are normally NOP but will be set to bitplane pointers on the one line that they're used on) - 4x ops for setting Color0 with a 24Bit AGA color Using COPJMP, I was able to reduce it to 5 - just the line wait (which can be substituted with a COPJMP to a secondary copperlist that takes care of resetting the bitplane pointers) and the color operations. |
This is what I did for Chuck Rock 2 (and Wonderdog)
I had a table with an entry for each scanline, with the total number of copper instructions cumulative up to that line. Then if the bitplanes need resetting at line X, I read value Y from table at position X, blit that part of the copperlist, then insert bitplane stuff, then blit the rest of the copperlist. It took hardly any time in total. This also allowed for any (variable) number of other copper instructions per line.. |
All times are GMT +2. The time now is 18:29. |
Powered by vBulletin® Version 3.8.11
Copyright ©2000 - 2024, vBulletin Solutions Inc.