Posted: Wed May 09, 2007 7:16 pm
What about handling only 1 plan ? Genesis already offers 2 plans. You can use the 32X hardware to implement one enhanced plan
It does sound good for me. Is 60 FPS possible with only one plan ?

Yeah, for sure. But, as I've already stated : what's the point of it ? I mean, the real thing, drawing a single layer, is drawing an image. And I don't need to cut this image in tiles, then run 2 big CPU to re-arrange these tiles. A smarter way is to simply send the image, from the ROM to the Frame Buffer. And this operation can be handled by the mere 68k.Stef wrote:What about handling only 1 plan ? Genesis already offers 2 plans. You can use the 32X hardware to implement one enhanced plan :) It does sound good for me. Is 60 FPS possible with only one plan ?
Don't worry : I really enjoyed myself ! I've learned a lot of things. And I think that's a very important part of it !Fonzie wrote:Yeah... One plan is good too... Anyway, i hope you had fun experimenting this
A tile plan is by far more interesting than a simple scrolled image.ob1 wrote:Yeah, for sure. But, as I've already stated : what's the point of it ? I mean, the real thing, drawing a single layer, is drawing an image. And I don't need to cut this image in tiles, then run 2 big CPU to re-arrange these tiles. A smarter way is to simply send the image, from the ROM to the Frame Buffer. And this operation can be handled by the mere 68k.Stef wrote:What about handling only 1 plan ? Genesis already offers 2 plans. You can use the 32X hardware to implement one enhanced planIt does sound good for me. Is 60 FPS possible with only one plan ?
More over, with a single layer, you can't have transparency, as the Genesis layers are not seen as frame buffer.
Finally, scrolling, even line-scrolling is equally pointless, since even scrolled, a single-layer image is still a simple image. Maybe it would be bigger on ROM, but the 2 CPU wouldn't run pointlessly.
Well, RLE goal is the same. And if you want scrolling, you can convert your RLE encoded image to a full screen image with DMA FILL. Then, just apply the tips I gave starting this topic.Stef wrote:A tile plan is by far more interesting than a simple scrolled image.
A bitmap consum many memory, having a tilemap plan permit to define very large level with small data information :) You re-use the same tile many time :) Pitfall 32X did that for that reason.
Why not ? Anyway, thank you.Stef wrote:Only one plan and 30 FPS. Your is already better =)
FPS = frame per second.ob1 wrote:Well, RLE goal is the same. And if you want scrolling, you can convert your RLE encoded image to a full screen image with DMA FILL. Then, just apply the tips I gave starting this topic.Stef wrote:A tile plan is by far more interesting than a simple scrolled image.
A bitmap consum many memory, having a tilemap plan permit to define very large level with small data informationYou re-use the same tile many time
Pitfall 32X did that for that reason.
Why not ? Anyway, thank you.Stef wrote:Only one plan and 30 FPS. Your is already better =)
But something remains. What are we talking about fps ?
A streaming movie is smooth above 24 fps, it means 24 images are showned in one second. Luckily, electricity in Europe is 50Hz (and 60Hz in the USA and Japan). So, if I draw twice half an image, I'll get one image every 1/50sec (1/60 in the USA). Does it mean I have 50 fps ?
Equally, Gens states the FPS is 60 during my demo. Does it assume I actually get 60 fps ? If so, I get twice what I need, so I'm very happy with it.
Here's how I benchmarked my SuperVDP. Every V_INT, I increment a value in CommPort($1C). Before my drawPlane routine, I save V_INT. Just after my drawPlane routine, I compute current V_INT odded old V_INT. The number I get is the number of frames that were dropped. I do want it to be no more than 0 !!! And, drawing 2 planes, I get 1
So, what to believe ? Do I get nearly 60 fps, or do I get nearly 30 fps ?
Code: Select all
R11 = vtimer
drawPlane(A plane)
drawPlane(B plane)
R12 = vtimer
R12 = R12 - R11
R13 = R12
Code: Select all
longint *FB = (int) *0x24000000;
int *tiles = (int) *0x06006000;
int *screenAMap = (int) *0x06004000;
int *screenMap = screenAMap;
int tileNumber;
longint *tileAddress;
if (CPU_SLAVE) {
screenMap += 0x800; /* Slave CPU draw the loawer tiles */
}
repeat(560) { /* 40 x 28 tiles = 1120 tiles, 560 for each CPU */
int tileNumber = (int) *screenMap++;
longint *tileAddress = tiles + (tileNumber * 64); /* One tile is 64 bytes long */
/* Copy one tile */
repeat(8) {
*FB++ = *tileAddress++; /* 1 long int = 1 32-bits longword = 4 bytes */
*FB++ = *tileAddress++; /* 1 long int = 1 32-bits longword = 4 bytes */
dest += 312; /* 312 = 320 - 8 */
}
}
Code: Select all
MOV.L FB,R1 ; R1 = FrameBuffer
MOV.L TILES,R2 ; R2 = Tiles data
MOV.L PLANE_A,R3 ; R3 = Plane data
MOV.L CPU,R0 ; Let's assume I've set bit 0 when the CPU is slave
CMP #1,R0
BF CPUSlaveInitSkip
MOV #$5D,R0 ; 0x5D = 0x800 >> 4
SHLL2 R0
SHLL2 R0
ADD R0,R3
CPUSlaveInitSkip:
; Main loop
MOV #$8C,R4 ; 0x8C = 560 >> 2
SHLL2 R4
SUB #1,R4
.align 4
REPEAT_PLANE:
MOV.B @R3+,R5 ; R5 = tileNumber - 18 cycles
SHLL8 R5
SHLR2 R5 ; R5 = tileOffset
ADD R2,R5 ; R5 = tileAddress
; Copy one tile
MOV #7,R6 ; R6 = Counter : 8 lines/tile
.align 4
REPEAT_TILE:
MOV.L @R5,R0 ; ---
ADD #4,R5 ; |
MOV.L R0,@R1 ; |
ADD #4,R1 ; | 89 cycles when cache miss, 23 when cache hit
MOV.L @R5,R0 ; | For each tile 2-lines, 1 miss then 3 hits
ADD #4,R5 ; | So 4 * (89 + 3*23) = 632 cycles
MOV.L R0,@R1 ; ---
MOV #$9E,R7 ; 0x9E = (320 - 4) >> 1
SHLL R7
ADD R7,R1
BT/S REPEAT_TILE ; 2 cycles
SUB #1,R6
BT/S REPEAT_PLANE ; 2 cycles
SUB #1,R4
.align 4
CPU dc.l $06000000
FB dc.l $24000000
TILES dc.l $06006000
PLANE_A dc.l $06004000