Título: Evitando la "Regla del 5º Sprite" (antes "Snippets") Publicado por: burguera en 02 de Octubre de 2006, 09:00:13 pm Viendo los snippets que hay en el tema "snippets" (a más de uno le voy a sacar provecho) echo en falta uno en particular. Estaría bien alguno que mostrara como ir alternando los sprites visibles cuando se superan los cuatro en línea (y producir el inevitable parpadeo)
Título: Re: Snippets Publicado por: pitpan en 02 de Octubre de 2006, 09:23:08 pm Pues bien sencillo: no copies directamente a VRAM las posiciones de los sprites, sino simplemente a RAM. Reprocesa en RAM con alguna rutina "inteligente" y copia a VRAM entonces.
Lo mejor es sencillamente "darle la vuelta". Es decir, copiar a VRAM en los frames pares 1-2-3-4-5-... y en los frames impares 32-31-30-29-... Por supuesto esta técnica sólo funciona correctamente en ciertas condiciones. Lo más adecuado es comparar las coordenadas verticales y para los coincidentes, alternar sus posiciones relativas en la tabla de atributos de sprites. Creo que no me he explicado nada bien :-\ Título: Re: Snippets Publicado por: ARTRAG en 02 de Octubre de 2006, 09:44:09 pm Código: ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ; interrupt ; org 0038h SAT equ 0x1b00 ; Sprite Attribute Table global _vdps0, _curr_plan, _n_sprt, _sprt, _ready ; RST 38 handler ex af,af' exx ld a,(_ready) ; no action if not ready or a in a,(0x99) ld (_vdps0),a jp z,_end bit 06h,a jp z,3f and 31 add a,a add a,a ld b,a ld a,(_curr_plan) add a,b ld e,a ; curr_plan + = (vdps0 & 31)*4; ld a,(_n_sprt) ld c,a ; In A rest of E / C ld a,e 1: sub c jp nc,1b add a,c jp z,3f ld (_curr_plan),a ; curr_plan -= (curr_plan/(n_sprt)) * (n_sprt); ld e,a ld a,SAT & 255 out (0x99),a ld a,SAT/256 | 64 out (0x99),a ld hl,_sprt ld d,0 add hl,de ; hl = sprt + curr_plan ld c,0x98 ld a,(_n_sprt) sub e ld b,a ; b = n_sprt -curr_plan otir ld hl,_sprt ; hl = sprt ld b,e ; b = curr_plan otir jp 1f 3: ld a,SAT & 255 out (0x99),a ld a,SAT/256 | 64 out (0x99),a xor a ld (_curr_plan),a ld hl,_sprt ld c,0x98 ld a,(_n_sprt) ld b,a otir 1: ld a,208 out (0x98),a xor a ld (_ready),a _end: ex af,af' exx ei ret Some explanations: The vdp status register holds the plane of the 5th sprite, the best method for reordering the sprite is to plot on plane 0 (the max priority) the sprite whose plane was indicated by the status register as 5th sprite. Some variables: sprt is the 32*4=128 copy of the SAT in RAM, n_sprt holds the number of valid bytes in sprt, curr_plan is the VDP sprite plan in sprt that is currently mapped on plane 0 (max priority) Note: you need to set set "_ready" to 1 at each interrupt, each time you update the SAT. This part is unessential and could be skipped, the sole reason for having a "_ready" signal is to avoid that the the routine that writes in the SAT in RAM has not jet completed its update when the int occurs. The best way to handle this kind of issues is to have a double SAT in RAM, one for sprite scramble, one to be updated by the main. When update is finished you swap the two SAT, but this routine is still under development... Código: Título: Re: Snippets Publicado por: jltursan en 03 de Octubre de 2006, 09:09:23 am Thanks for sharing this routine! :). Could be very handy to implement working behind a BASIC program (just an idea).
Only a question, the routine seems a bit C oriented (globals, labels and so...). What's the format of the jump labels?, they are neither standard labels nor offsets... ??? Título: Re: Snippets Publicado por: ARTRAG en 03 de Octubre de 2006, 02:32:40 pm The routine is integrated in my C programs
to move it to plain ASM, 1) ignore global statemets 2) the "_" is a a simple character, substitute it with anything you like 3) the numbers are temporary labels, in jumps "f" means forward, "b" means backward, so "JP 1f" goes to the first temporary label "1:" following that jump Título: Re: Snippets Publicado por: jltursan en 03 de Octubre de 2006, 03:00:53 pm Citar the numbers are temporary labels, in jumps "f" means forward, "b" means backward, so "JP 1f" goes to the first temporary label "1:" following that jump Yep!, that's the info!. Now I see... :). Btw, I'm experimenting a bit with the demo version of Hitech 7.50 for windows and I agree, it's a very nice compiler! Título: Re: Snippets Publicado por: nerlaska en 03 de Octubre de 2006, 03:56:40 pm el SDCC 2.6.0 es mas chuli :-)
Título: Re: Snippets Publicado por: ARTRAG en 03 de Octubre de 2006, 04:06:38 pm In v7.8 you get all the sources of the libs and of the runtime code... :D
I have found also a way to get megarom on ascii 8K rom mappers :) The compiler can handle by itself up to 1M Rom of code and data and all you need is to specify which functions and data should go in the same rom page!! Actually, the ASCII mapper isn't very far from what the C compiler expected to have when you compile in large model (all you need is to change a line in the lcall and lret routines). ;D I think that it is a great compier, even if to use it I have to move the date of my PC to 2005 ;) Título: Re: Snippets Publicado por: burguera en 03 de Octubre de 2006, 06:02:46 pm Gracias por los consejos, Robsy.
And thanks for the code, ARTRAG. De momento no tengo planes de pasarme al C (ya tengo suficiente "alto nivel" en otros aspectos menos lúdicos de mi vida -lease trabajo-), aunque después de leer estos comentarios del Hitech y los de Nerlaska sobre el SDCC la verdad es que apetece. Todo se andará. Título: Re: Snippets Publicado por: ARTRAG en 03 de Octubre de 2006, 07:19:10 pm Note that my solution is different from Robsy's one.
In my case you are always sure that the 5th sprite will be displayed (well at least one 5th sprite will be dispayed). In Robsy's solution, this isn't guaranteed, moreover look at this effect assume you have sprites on planes 1 2 3 4 5 on the same line: the sprite on plane 5 disappears. reverse them 5 4 3 2 1 now sprite that was on plane 1 disappears. Repeat this process at refresh rate: Result: only sprite 1 & sprite 5 flicker at half of the refresh rate (25Hz if you go @50Hz) Robsy's solution implies a very noticeable effect. with my proposal sprites on planes 1 2 3 4 5 disappear in turn, at each frame one different sprite disappear Result: all sprites flicker but the flickering is at 1/5 of the refresh rate (10 Hz if you go @50Hz) This implies a much better visual effect as the flickering is at very low frequency Título: Re: Snippets Publicado por: pitpan en 03 de Octubre de 2006, 09:51:22 pm You're right, Artag: flickering in my routine is very common. Of course, my approach is the simplest solution.
On the other side, it handles properly up to 8 sprites in the same line, whereas yours will not work always in that case - the weakest point is that the interrupt routine only returns the 5th sprite number. But what happens if there are more than 5 sprites? Several sprites could be totally hidden. I have used my approach in my current project, where I have commonly 8 sprites in line. It works pretty well and it does not use much CPU. The best solution, as always, depends on the concept and design of the game. I agree that your solution is more generalistic and will work better in most situations, but perhaps not in all cases, as I've shown. It's good to discuss this programming issues here. IMHO, the best sprite-flickering routine is the one used in Golvellius. Ever noticed the amount of sprites at the same time? Amazing. :o Título: Re: Snippets Publicado por: ARTRAG en 03 de Octubre de 2006, 11:24:38 pm Hi robsy,
I see you point, but I am not sure that the case you posed isn't handled by my approach let's see assume 8 sprites on 8 adjacent planes 1 2 3 4 5 6 7 8 sprites 5 6 7 8 disappear, S0 returns plane 5, so next int, my routine reorders the sprites putting sprite 5 and the following on top you get : 5 6 7 8 1 2 3 4 now sprites 1 2 3 4 disappears S0 returns plane 5, i.e. sprite #1, next int my routine reorders the sprites putting sprite 1 and the following on top you get 1 2 3 4 5 6 7 8 As you can see my approach can safely handle up to 8 sprites per line. Actually you're right when you say that solution for all seasons doesn't exist, Also my approach has problems, they occur when there are two lines with 5 or more sprites Look at this case, 10 sprites on two lines, 1 2 3 4 5 on the first line 6 7 8 9 10 on the second line the sprite planes are 1 2 3 4 5 6 7 8 9 10 where on the screen you see 1 2 3 4 5 6 7 8 9 10 Sprite 5 and 10 disappear (5 is covered by 1 2 3 4 and 10 by 6 7 8 9) S0 points to plane 5 (only the first 5th sprite is revealed, but the problem is similar if S0 reveals the last 5h sprite) my routine does this reordering 5 6 7 8 9 10 1 2 3 4 on the screen now sprite 4 disappears (covered by 1 2 3 5), sprite 5 appears, and sprite 10 stay hidden !! S0 points to plane 10 (i.e to sprite 4) my routine does this reordering 4 5 6 7 8 9 10 1 2 3 on the screen now sprite 3 disappears (covered by 1 2 4 5), sprite 4 appears, but sprite 10 stay hidden S0 points to plane 10 (i.e. to sprite 3) my routine does this reordering 3 4 5 6 7 8 9 10 1 2 on the screen now sprite 2 disappears (covered by 1 3 4 5), sprite 3 appears, but sprite 10 stay hidden actually you can go on and see that sprite 10 stay hidden for a large number of frames only the first line of sprites flickers correctly, the second line is almost unaffected. In this case your approach is better as it has the advantage to revert all the planes, so one frame sprites 5 and 10 disappear, on one frame sprites 1 and 6 disappear. Your solution goes better, but all depends on the game design and on the prob. of having two or more lines with 5 sprites or more Título: Re: Snippets Publicado por: Jon_Cortazar en 04 de Octubre de 2006, 08:54:41 am In the game Infinty (it will be released soon), I used another way of making a flickering routine:
I had a RAM buffer for sprite atributes. As the max sprite number on screen in the game is 10, the RAM buffer occupies 40 bytes (4 bytes per sprite -atributes-). Well, so what I do at every frame is to create a mirror of those 40 bytes right after the first 40 bytes: ; RAM buffers SPRITE_ATRIBUTES1: ds 40 SPRITE_ATRIBUTES2: ds 40 ;mirror This can be done with a simple ldir. Well, once I have that pair of sprite atribute data, all I must do is to 'add' a variable to the source adress when sending to VRAM. In other words, I won't send to VRAM from SPRITE_ATRIBUTES1, but from SPRITE_ATRIBUTES1+[variable]: So: flickering_offset=0 .flicker_routine create the mirror from SPRITE_ATRIBUTES1 into SPRITE_ATRIBUTES2 final_adress=SPRITE_ATRIBUTES1+flickering_offset send to vram (spratr) from FINAL_ADRESS the amount of 40 bytes flickering_offset=flickering_offset+4 if flickering_offset=40 then flickering_offset=0 end It is easy, quite fast and it works for an undefined number of sprites. In Infinity the flickering looks pretty good, I promise. When I arrive home I'll share the routine source. The only downside in this routine is that you must double the RAM usage for your sprite attribute buffer, but if we take in account that the max spratr you'll ever use will be 256 bytes long, the max you'll get will be 512 bytes, and that is pretty affordable thinking on a 16kb RAM system. Título: Re: Snippets Publicado por: ARTRAG en 04 de Octubre de 2006, 09:33:36 am if you use as flickering_offset the 5th sprite in S0 you get exactly my strategy,
the difference is that I do not mirror the SAT twice but I send to the VRAM the SAT in two steps, from flickering_offset to the max used position first, and, then, the initial part as second. (I need to handle up to 20-24 sprites on the screen, so copying the SAT can be CPU expensive) Using as flickering_offset the 5th sprite in S0 is better when sprites are one line If sprites are on two or more lines, the second line, in my approach isn't handled correctly and your "blind" scramble is better Título: Re: Snippets Publicado por: Jon_Cortazar en 04 de Octubre de 2006, 09:49:07 am if you use as flickering_offset the 5th sprite in S0 you get exactly my strategy, Yep, but, as VRAM transfers are always a hell, I prefer to do those the less steps the better. :)the difference is that I do not mirror the SAT twice but I send to the VRAM the SAT in two steps Using as flickering_offset the 5th sprite in S0 is better when sprites are one line Agree on that... your strategy with the colision detection is pretty nice, but as I cycle the sprites on a regular sequence, mine is better for generic purposes.If sprites are on two or more lines, the second line, in my approach isn't handled correctly and your "blind" scramble is better Título: Re: Snippets Publicado por: ARTRAG en 04 de Octubre de 2006, 09:56:17 am You see, if you need more than 10 sprites, copyng up to 128bytes each time can be heavvy.
PS collision detection ? you mean 5h sprite Título: Re: Snippets Publicado por: Jon_Cortazar en 04 de Octubre de 2006, 10:02:21 am You see, if you need more than 10 sprites, copyng up to 128bytes each time can be heavvy. Nah, transferring 128 bytes RAM to RAM it is not that heavy ;)Citar collision detection ?. you mean 5h sprite Yeah, sorry :DTítulo: Re: Snippets Publicado por: jltursan en 04 de Octubre de 2006, 11:00:21 am If I've understand both routines, you can merge them adding to the Viejo's cycling the 5th sprite detection as you don't need to shift the data if the bit flag is not set; this way you can save some work. ::)
Título: Re: Snippets Publicado por: ARTRAG en 04 de Octubre de 2006, 11:11:09 am ???
if the 5th sprite flag is not set, my code does not cycle, you only copy the used part of the SAT from ram to vram It should be interesting to see under which conditions the two approaches (LDIR and two step RAM->VRAM transfer) are equivalent and when one is better of the other. (a part from RAM consumption :) Título: Re: Snippets Publicado por: Jon_Cortazar en 04 de Octubre de 2006, 11:25:47 am Note that the routine must be really fast in VRAM transfers because a *good* flickering routine is one that works at full fps to make the flickering less noticeable. I think both are ok. ;)
Título: Re: Snippets Publicado por: jltursan en 04 de Octubre de 2006, 02:44:50 pm Citar Huh if the 5th sprite flag is not set, my code does not cycle, you only copy the used part of the SAT from ram to vram Not your routine, Viejo's one. Citar a *good* flickering routine is one that works at full fps to make the flickering less noticeable ..and of course with the lesser number of sprites flickering. Anyway, with the rotating technique, if you have, for example 8 sprites in a row (from a total of 10 sprites): FRAME 1: 0 1 2 3 4 5 6 7 8 9 ; sprites 4 5 6 7 are hidden, 8 9 not used FRAME 2: 1 2 3 4 5 6 7 8 9 0 ; sprites 5 6 7 8 are hidden FRAME 3: 2 3 4 5 6 7 8 9 0 1 ; sprites 6 7 8 9 are hidden FRAME 4: 3 4 5 6 7 8 9 0 1 2 ; sprites 7 8 9 0 are hidden FRAME 5: 4 5 6 7 8 9 0 1 2 3 ; sprites 8 9 0 1 are hidden AFAICS shifting only one plane every frame could produce some heavy flickering on some sprites, I mean that in the above example, the initially hidden sprites 4 to 7 will remain hidden till four frames later when all four sprites will render visible; so in the worst case a sprite could remain hidden for 4 frames and in the less severe one, is hidden only 1 frame. I think that if the attribute table is dump not every plane (adding 4 every frame) but every 4 planes (adding 16) you can achieve the fastest rotation speed and so minimize the flickering rate. Título: Re: Snippets Publicado por: ARTRAG en 04 de Octubre de 2006, 11:40:49 pm my routine, if the 5th sprite flag is not set, does not cycle
read the asm Código: in a,(0x99) ld (_vdps0),a jp z,_end bit 06h,a jp z,3f .... Código: 3: ld a,SAT & 255 out (0x99),a ld a,SAT/256 | 64 out (0x99),a xor a ld (_curr_plan),a ld hl,_sprt ld c,0x98 ld a,(_n_sprt) ld b,a otir 1: ld a,208 out (0x98),a xor a ld (_ready),a _end: ex af,af' exx ei ret it means that it does not cycle if there is no 5th sprite, you can trust me if you do not see it about your example there is a mess between sprite planes and sprite numbres say that you display 10 sprites A B C D E F G H I L and that A B C D E F G H are on the same line and are on planes 0 1 2 3 4 5 6 7, while I & L are elsewhere on planes 8 9 the initial association sprite/planes looks like this A B C D E F G H I L 0 1 2 3 4 5 6 7 8 9 step 1) E F G H are hidden by A B C D, (I & L are visible), S0 -> 4 my routine rearranges the sprites like this: E F G H I L A B C D 0 1 2 3 4 5 6 7 8 9 step 2) A B C D are hidden by E F G H, (not by I & L that are elsewhere), S0->6 my routine rearranges the sprites like this: A B C D E F G H I L 0 1 2 3 4 5 6 7 8 9 and so on. As you can see the routine works perfectly, only the sprites that should disappear actually disappear and their flickering frequency is 25Hz, i.e. the best you can get on MSX1 and 8 sprites on the same line [edit] Now I see your point, you was referring to the Viejo's solution, with fixed increment of the offset Sorry I misunderstood, I tougnt you was referring to the offset guided by S0, Yes, the problem you mention can occur with the Viejo's solution. [/edit] Título: Re: Snippets Publicado por: jltursan en 05 de Octubre de 2006, 12:01:45 am Uh?, I know that your routine don't rotate the sprite planes, I'm talking about the one used by Viejo's forthcoming game, "Infinity". Here's the main loop of his routine :
Citar Código: flickering_offset=0 .flicker_routine create the mirror from SPRITE_ATRIBUTES1 into SPRITE_ATRIBUTES2 final_adress=SPRITE_ATRIBUTES1+flickering_offset send to vram (spratr) from FINAL_ADRESS the amount of 40 bytes flickering_offset=flickering_offset+4 if flickering_offset=40 then flickering_offset=0 end Maybe I'm wrong; but I think that it's possible to reduce the flickering just modifying the value added to offset. Título: Re: Snippets Publicado por: ARTRAG en 05 de Octubre de 2006, 12:10:53 am both routines rotate the sprites, one cyclically (his), one guided by the VDP S0 (mine),
apart this aspect (that is the sole true difference from the point of view of the final effect), his code rotates the sprites with a duplication of the sprite attributes in RAM, my code rotates the sprites with a two step ram->vram copy. Those latter are unessential details related to the implementation, not to the algorithm [edit] Now I see your point, you was referring to the Viejo's solution, with fixed increment of the offset Sorry I misunderstood, I tougnt you was referring to the offset guided by S0, Yes, the problem you mention can occur with the Viejo's solution. [/edit] Título: Re: Snippets Publicado por: WYZ en 05 de Octubre de 2006, 01:27:36 pm I think my method is the best:
- Rotate the screen 90º instead of rotate sprites. Then is possible to see 32 sprites in the same horizontal row without flickering at all. :D Título: Re: Snippets Publicado por: jltursan en 05 de Octubre de 2006, 02:41:38 pm Citar Now I see your point, you was referring to the Viejo's solution, with fixed increment of the offset Sorry I misunderstood, I tougnt you was referring to the offset guided by S0, Yes, the problem you mention can occur with the Viejo's solution. Right; but anyway I've been thinking about it and there're some other hidden problems. As I'm getting curious about the display quality I'll try to implement every solution posted here together in a sprite demo. I want to see the routines working on screen :) Citar I think my method is the best: - Rotate the screen 90º instead of rotate sprites. Then is possible to see 32 sprites in the same horizontal row without flickering at all. Indeed! :D Título: Re: Snippets Publicado por: Jon_Cortazar en 05 de Octubre de 2006, 04:08:22 pm I think my method is the best: W00t?, and having just 4 sprites in each vertical column?... that would be far worse!!! :D :D :D- Rotate the screen 90º instead of rotate sprites. Then is possible to see 32 sprites in the same horizontal row without flickering at all. :D Título: Re: Snippets Publicado por: ARTRAG en 05 de Octubre de 2006, 04:55:15 pm Citar Now I see your point, you was referring to the Viejo's solution, with fixed increment of the offset Sorry I misunderstood, I tougnt you was referring to the offset guided by S0, Yes, the problem you mention can occur with the Viejo's solution. Right; but anyway I've been thinking about it and there're some other hidden problems. As I'm getting curious about the display quality I'll try to implement every solution posted here together in a sprite demo. I want to see the routines working on screen :) Do not forget to update the SAT in RAM at each interrupt and set _ready = 1 If you do not set _ready = 1 at each interrupt the routine does not work IMHO you could remove the _ready test, it is actually usefull only in my program let me know the results of the comparison! PS naturally my solution is the best ;D ;D ;D (sometime) Título: Re: Snippets Publicado por: WYZ en 05 de Octubre de 2006, 11:19:12 pm I think my method is the best: W00t?, and having just 4 sprites in each vertical column?... that would be far worse!!! :D :D :D- Rotate the screen 90º instead of rotate sprites. Then is possible to see 32 sprites in the same horizontal row without flickering at all. :D ooops!! Then aply the above mentioned methods ;D Título: Re: Snippets Publicado por: burguera en 05 de Octubre de 2006, 11:40:47 pm Ups... and what about rotating the screen 50 times per second? One hand to rotate the screen, the other for the joystick... I'm sure no flickering would be seen by the user ;-)
Título: Re: Snippets Publicado por: burguera en 05 de Octubre de 2006, 11:46:52 pm By the way, it's me, "burguera". I just changed to a cooler nick ;-)
Título: Re: Snippets Publicado por: jltursan en 14 de Octubre de 2006, 11:10:04 am Well, if I've enough time, this weekend I'll release a little "sprite multiplexing demo". I'm finishing it right now... ;)
Título: Re: Snippets Publicado por: SapphiRe en 14 de Octubre de 2006, 11:12:01 am Y digo yo... ¿Por qué hablais en inglés en un foro en español? ??? ???
Título: Re: Snippets Publicado por: ARTRAG en 14 de Octubre de 2006, 02:23:23 pm My fault, I read spanish, but I can write only English
Título: Re: Snippets Publicado por: nerlaska en 14 de Octubre de 2006, 03:01:00 pm Que leche es multiplexar sprites?
What milk is multiplexing sprites? Título: Re: Snippets Publicado por: ARTRAG en 14 de Octubre de 2006, 06:55:00 pm it is a way to have more that 4 sprites on the same line on msx1
the trick in short is: when there are 5 or more sprites on one line scramble the sprite planes, do that at each interrupt and you'll see more that 5 sprites on the same line (but flickering) Título: Re: Snippets Publicado por: MsxKun en 14 de Octubre de 2006, 07:58:14 pm Y digo yo.
Tenemos una linea con 5 sprites... 1234 y 5 y pongamos que mas abajo . . . otra con 5 mas.... ABCD E cual seria el meollo entonces? ;D P.D: Uops!! Veo mal o este es el mensaje cincomildoscientos... 69!!! >:D Título: Re: Snippets Publicado por: Jon_Cortazar en 15 de Octubre de 2006, 08:26:52 pm Uops!! Veo mal o este es el mensaje cincomildoscientos... 69!!! >:D kun :spank: viejo_archivero;) ;) ;) Título: Re: Snippets Publicado por: SapphiRe en 16 de Octubre de 2006, 11:03:05 am My fault, I read spanish, but I can write only English There's no problem. But if you can try to write some words in Spanish, I guess you'll learn this language very soon. We can also help you, of course. Feel free to correct my English ;) ;) Título: Re: Snippets Publicado por: ARTRAG en 16 de Octubre de 2006, 11:10:42 am Thanks but I'm Italian, my English sucks :P
Título: Re: Snippets Publicado por: jltursan en 17 de Octubre de 2006, 08:00:22 pm Maybe a bit buggy and unoptimized; but here's a little demo to show several sprite multiplexing routines. As a trade-off between all routines the number of multiplexed sprites is only 8; so the results with more sprites will vary for sure (as someone pointed early in this thread). Of course, it's only a quick experiment and I wait anyone comments... :)
Btw, the last four sprites are controlled by cursor keys and can be moved vertically also the space bar can be used to align the sprites and quickly force the worst case. Título: Re: Snippets Publicado por: ARTRAG en 17 de Octubre de 2006, 09:35:55 pm Where is my routine ?
Título: Re: Snippets Publicado por: jltursan en 17 de Octubre de 2006, 09:40:57 pm Number 1 (plane swapping, to name it some way... :)), you can find it at $4137. Please try to check it to see if all is correct.
Título: Re: Snippets Publicado por: pitpan en 17 de Octubre de 2006, 09:57:19 pm La rutina número 1 no parece hacer nada (he probado en BlueMSX, aunque quizás estoy haciendo algo mal).
Gracias por hacer una demo técnica tan gráfica. Lo que sí te pediría es que hicieras una descripción a alto nivel de cómo funciona (conceptualmente) cada rutina. En mi mini-proyecto actual utilizo rotación simple, manteniendo un plano de sprite con prioridad (nunca se oculta/multiplexa). Visualmente, prefiero un parpadeo rápido y continuo que afecte a varios sprites. No es quizás la mejor solución pero a mi me resulta más estético (dentro de lo feo que está que los sprites parpadeen). De nuevo, JL, gracias por currártelo tanto. Título: Re: Snippets Publicado por: ARTRAG en 17 de Octubre de 2006, 10:01:05 pm jltursan
it is for sure not correct, routine n 1 does not cycle when you have 5 sprites on one line could you send me the source? I can try to patch it Título: Re: Snippets Publicado por: WYZ en 17 de Octubre de 2006, 10:23:57 pm Muy didáctica esa demo JL. Si es que no tiene uno mas remedio que hacerse fan tuyo! :D
Título: Re: Snippets Publicado por: Jon_Cortazar en 18 de Octubre de 2006, 08:24:09 am Jltursan, te voy a mandar un emilio para que veas una cosilla, ok? ;)
Título: Re: Snippets Publicado por: jltursan en 18 de Octubre de 2006, 09:40:41 am Como comentan ARTRAG y Robsy, hay un error que afecta a la rutina 1 (la de ARTRAG), que hace que cuando se ponen en linea sólo 5 sprites haga cosas raras, de momento si se fuerza a que los 8 sprites estén en linea todas funcionan; aunque queda pendiente la revisión de la rutina 1, claro.
Luego a ver si saco un rato y comento un poco las diferentes rutinas. Título: Re: Snippets Publicado por: ARTRAG en 18 de Octubre de 2006, 10:08:29 am Como comentan ARTRAG y Robsy, hay un error que afecta a la rutina 1 (la de ARTRAG), que hace que cuando se ponen en linea sólo 5 sprites haga cosas raras, de momento si se fuerza a que los 8 sprites estén en linea todas funcionan; aunque queda pendiente la revisión de la rutina 1, claro. Actually the differences between my approach and the others should appear exactly when you have only few sprites on the same line (like 5). E.g. with only 5 sprite per line, routine 1) should guarantee a flicker rate of 10 missing frames per second (missing means that the sprite is NOT displayed in those frames) A fixed scheme of rotation, with 8 sprites on the screen, should give only a flicker rate of 25 missing frames per second because the 5h sprite have 50% of prob to fall in a plane lower than the other 4. Título: Re: Snippets Publicado por: MsxKun en 18 de Octubre de 2006, 02:01:56 pm Muy currao, me quedo con la ultima opcion ;D
Título: Re: Snippets Publicado por: WYZ en 18 de Octubre de 2006, 02:35:51 pm Todos conocemos la regla del 5º sprite, (no es esa que suele hacer el freaky MSXero de comprar 5 o mas botes de sprite, ponerlos en linea horizontal y pagar solo 4, que si, lo he visto hacer y no ha colado ) lo que me gustaría saber bien es que le ocurre al VDP para que exista esa restricción. ¿Alguien se anima a explicarlo?
Título: Re: Snippets Publicado por: ARTRAG en 18 de Octubre de 2006, 03:03:28 pm As far as I know, during the rendering of each line, each
sprite is managed by an independent area in the VDP chip. The VDP sprite units work in parallel on each rendered line in oder to compute where the sprites should overlay the background. As the VDP area costs, reducing the number of sprite units decreases the overall cost of the chip. Moreover, less VDP unit you have, less bandwith you need in the transfer between the VRAM and the VDP during the screen rendering. This allows the use of slower memory chips Título: Re: Snippets Publicado por: WYZ en 19 de Octubre de 2006, 09:17:25 am Ok, gracias por la explicación Artrag, pero aun no me queda del todo claro porque el VDP no renderiza el 5º sprite. :-\
Título: Re: Snippets Publicado por: ARTRAG en 19 de Octubre de 2006, 09:36:03 am There is no sprite unit to process it.
Título: Re: Snippets Publicado por: nerlaska en 19 de Octubre de 2006, 10:21:44 am basicamente .. la cosa está en que la velocidad del VDP para renderizar un scanline no da para más. Llega para eso .. para renderizar 4 sprites a la vez.
Todo es cuestión de eso. De velocidad. Título: Re: Snippets Publicado por: pentacour en 19 de Octubre de 2006, 10:36:32 am Buenas, ahora que tengo un ratillo me vuelvo a dejar caer por aquí (para decir una xorrada), pero es que me ha hecho gracia recordar hayá por los '80 descubriendo los sprites, que quería hacer un suelo para un juego, y me hice mi bucle superchulo para poner 20 sprites en línea. Después de repasar mi bucle una y otra vez para ver porqué solo me salían 4 me dio por leer el manual de basic y vi la explicación. En aquella época pensé: pues vaya restricción más tonta ???
Saludos Título: Re: Snippets Publicado por: Jon_Cortazar en 19 de Octubre de 2006, 10:42:41 am Joe, pentacour!, cuanto tiempo!! ;). Re-bienvenido, ya sabes que estás en tu casa :D
Título: Re: Snippets Publicado por: jltursan en 19 de Octubre de 2006, 11:57:37 am ¡ATENCION!, el texto a continuación puede ser extremadamente nocivo para la salud del programador....
Citar EL reloj maestro utilizado por el VDP es el de la frecuencia de la ráfaga de color * 3. A pesar de que los resultados obtenidos han tenido como referencia la versión NTSC, para la versión PAL se obtendrían resultados similares. La frecuencia de la ráfaga de color 3.579545 MHz, por lo que la frecuencia del reloj maestro es: Fmaestro = Frafagacolor * 3 = 3.579545 MHz * 3 = 10.7386 MHz El periodo del reloj maestro viene dado por: Tmaestro = 1/Fmaestro = 1/10.7386 MHz = 93.12 ns (nanosegundos) Cada acceso a memoria emplea 4 unidades del reloj maestro; así pues el tiempo de acceso a la memoria viene dado por: Tmem = Tmaestro * 4 = 93.12 ns * 4 = 372.5 ns = 0.3725 us El tiempo empleado en trazar una linea horizontal, comprendida entre el comienzo de la misma y el comienzo de la siguiente está especificado en el manual del chip como Thorz = 63,695 us. Así, el número total de veces en el que la memoria del VDP puede ser accedida en una linea de barrido horizontal viene dado por: Mhorz = Máximo numero de accesos a memoria en una linea horizontal = Thorz/Tmem = 63.695 us/0.3725 us = 171 accesos de memoria por linea horizontal Ahora ya sabemos cuantos accesos de memoria están disponibles para el refresco de pantalla y los accesos de la CPU conjuntamente. A continuación, habrá que encontrar cuantos accesos a memoria son necesarios para construir una linea horizontal en los modos gráficos I y II. Todos los accesos que queden libres se supone que pueden ser empleados por la CPU. Cada linea horizontal está compuesta de hasta seis planos de información gráfica (de menor prioridad a mayor prioridad de visionado): 1. Color de fondo (obtenido del registro #7) 2. Información del patrón y color. 3. Sprites (mínimo = 0, máximo = 4) Veamos cuantos accesos de memoria se necesitan para obtener los datos necesarios de los tres "planos" descritos arriba. Primero, el color de fondo no necesita acceder a memoria ya que este valor está contenido en los 4 bits más bajos del registro #7 del VDP. A continuación viene la información del patrón. Hay 32 carácteres por linea y cada uno de ellos requiere los siguientes accesos para obtener los datos necesarios para generar su patrón de píxeles: 1. Leer el número de caracter de la Tabla de Patrones de Nombres (PNT) 2. Leer el patrón del caracter de la Tabla de Generación de Patrones (PGT) 3. Leer el color de la Tabla de Color de Patrones (PCT) Como se puede ver, se necesitan tres accesos por cada caracter y por tanto, el número total de accesos requeridos en una linea horizontal para que el plano de caracteres sea construido es de: Mchar = 32 carácteres/linea horizontal X 3 accesos memoria/caracter = 96 accesos memoria por linea horizontal dedicados al plano de patrones Por último tienen que procesarse los sprites. El 9918A permite hasta cuatro sprites en una linea, siendo el sprite #0 el de mayor prioridad de visionado. Para determinar que sprite es visible en una linea horizontal dada, la posición Y de los 32 sprites debe de ser leida desde la tabla de atributos de sprite (SAT) en VRAM y comparada con la linea actual de barrido. Durante la comparación, el bit Mag del registro 1 del VDP debe de ser tenido en cuenta, ya que la magnificación es siempre en las dos direcciones. Si la posición Y del sprite es tal que debería aparecer en esa linea horizontal, entonces el número del sprite (0-31) se almacena en uno de los cuatro registros temporales (SR0-SR3), si aún queda alguno libre. SR0 se utiliza primero y SR3 es el último. SR0 representa el sprite que estará en primer plano y SR3 el sprite que aparecerá bajo todos los demás. En el peor de los casos (en términos de velocidad), los primeros 28 sprites, 0-27 no serían dibujados en una linea horizontal dada, mientras que los 28-31 si que lo serían. En ese caso, la posición Y de los 32 sprites debería de ser leida (!). Así pues para los cálculos subsiguientes se va a asumir que las posiciones Y de los 32 sprites van a tener que ser leidas. A partir de esto definimos el número de accesos de memoria necesarios para chequear que sprites deben de ser presentados en una linea como: Msprite_test = 32 accesos a memoria (1 posición Y por sprite) Tras determinar que sprites deben de ser presentados, los datos de los cuatro sprites (de nuevo, el peor caso) a presentar debe de ser obtenida. Para cada sprite, hay 4 bytes (posición Y, posición X, número de patron y color/EC) que deben de ser leidos de la SAT. Cuando el bit Size del registro 1 del VDP vale 1, indicando sprites de doble tamaño (16x16), dos bytes de patrones deberán de ser leidos desde la tabla de generación de patrones. Una vez más, este es el peor caso. Por lo tanto, se necesitarán seis ciclos de memoria por cada sprite que sea presentado. Así pues, vamos a definir el número máximo de ciclos necesario para obtener los datos de los cuatro sprites en una linea como: Msprite_data = 4 sprites por linea x 6 accesos a memoria/sprite = 24 accesos a memoria Ahora, recapitulemos el número total de accesos requerido para presentar cuatro sprites por linea y obtendremos lo siguiente: Msprite = Número total de accesos de memoria por linea por sprite = Chequear que sprites estan en esa linea + Accesos a los datos de ese sprite = Msprite_test + Msprite_data = 32 + 24 = 56 accesos a memoria Por fin podemos calcular el número de accesos de memoria empleados para refrescar una linea horizontal de pantalla. Este número viene dado por: Mdisplay = Mchar + Msprite = 96 + 56 = 152 Ahora vamos a calcular el número de accesos a memoria disponibles para la CPU: Mcpu = Accesos a memoria durante una linea horizontal - Accesos a memoria empleados en la presentación = Mhorz - Mdisplay = 171 - 152 = 19 Accesos a memoria disponibles para la CPU Si la CPU puede acceder a la memoria cada 5,95 us, entonces el número total de accesos permitidos por la CPU durante una linea horizontal viene dado por: Mcpu_horz = Tiempo linea horizontal/Tiempo acceso a memoria = 63.695 us/5.95 us = 10.7 Accesos a memoria de la CPU por linea horizontal Si se redondea 10,7 a 11, esto nos daría que hay 8 accesos a memoria (19-11=8) disponibles. Estos 8 accesos libres podrían haberse usado para presentar un quinto sprite por linea, ya que un sprite emplea un total de siete accesos (1 para el chequeo de Y y 6 más si se presenta). Sin embargo, eso nos dejaría con sólo un acceso libre para la CPU. Resumiendo, los sprites emplean un poco más de 1/3 del ancho de banda de la presentación. Desafortunadamente, los diseñadores del chip no incluyeron ningún método para desactivar los sprites y así poder conseguir 1 de cada 4 accesos a memoria disponibles para la CPU. Traducido libremente a partir de este texto (http://bifi.msxnet.org/msxnet/tech/tmsposting.txt), que por cierto, es una lectura muy recomendable ;) Título: Re: Snippets Publicado por: Jon_Cortazar en 19 de Octubre de 2006, 12:04:24 pm La leche :o, gracias por el trabajo jl ;)
Título: Re: Snippets Publicado por: nerlaska en 19 de Octubre de 2006, 02:46:51 pm Que alguien les pase ese texto a los del BLUEMSX!!!!
Título: Re: Snippets Publicado por: Jon_Cortazar en 19 de Octubre de 2006, 03:22:34 pm Que alguien les pase ese texto a los del BLUEMSX!!!! Joer, pero si el blueMSX -junto con el openMSX- es uno de los emus que mejor emulan los timings de la VRAM!! :o Título: Re: Snippets Publicado por: nerlaska en 19 de Octubre de 2006, 06:05:35 pm Si .. eso ya lo se :-)
Me referia a los TIMINGs chungos de fallos de la VDP .. pero ya me dijo el Van Dik este o como se llame que no habia documentación adecuada al respecto. Título: Re: Snippets Publicado por: SapphiRe en 19 de Octubre de 2006, 06:15:15 pm Si .. eso ya lo se :-) ¿Te refieres a Daniel Vik? ???Me referia a los TIMINGs chungos de fallos de la VDP .. pero ya me dijo el Van Dik este o como se llame que no habia documentación adecuada al respecto. Título: Re: Snippets Publicado por: Jon_Cortazar en 19 de Octubre de 2006, 09:39:34 pm :D :D
Título: Re: Evitando la "Regla del 5º Sprite" (antes "Snippets") Publicado por: ARTRAG en 19 de Octubre de 2006, 10:06:50 pm (http://ragozini.googlepages.com/tms.bmp/tms-full.jpg)
Only 4 Sprite units in the VDP.... Título: Re: Evitando la "Regla del 5º Sprite" (antes "Snippets") Publicado por: Dioniso en 20 de Octubre de 2006, 06:47:14 pm WYZ, llegaste a terminar lo del logo MSXDEV que te comenté? Creo que éste es el momento de enseñar algo de eso aquí, no te parece? La teoría de jltursan se acerca mucho al nuevo efecto de los sprites.
Título: Re: Evitando la "Regla del 5º Sprite" (antes "Snippets") Publicado por: jltursan en 25 de Octubre de 2006, 10:49:48 pm Bueno; pues aquí está la versión final de la demo de multiplexado de sprites con la rutina de ARTRAG corregida y hasta 16 sprites para jugar con ellos :)
Ahora ya puedo comentar un poco la cosa, mañana escribiré algo por aquí... Título: Re: Evitando la "Regla del 5º Sprite" (antes "Snippets") Publicado por: ARTRAG en 25 de Octubre de 2006, 11:00:25 pm what is "dynamic ring buffer"?
Título: Re: Evitando la "Regla del 5º Sprite" (antes "Snippets") Publicado por: jltursan en 26 de Octubre de 2006, 09:36:05 am Some explanations:
Now, with 16 sprites anyone can experiment the different behaviors of each routine... :) Some more multiplexing algorithms?, anyone? Título: Re: Evitando la "Regla del 5º Sprite" (antes "Snippets") Publicado por: ARTRAG en 26 de Octubre de 2006, 03:46:29 pm What about introducing two classes of priority among sprites?
This is the idea: Assume some sprites can disappear while some other need to be displayed, eventually cycling. This is the case where you use 2 sprites per object. One is the main color of the body of the object, one is the secondary color for small details. This is also the case where you use sprites for UFOs and for the stars in the starfield (this latter must be with lower priority). the requirements are: 1) if main sprites are on the same line, main sprites (eventually) cycle 2) if detail sprites are on the same line detail sprites (eventually) cycle 3) if main sprites and detail sprites are on the same line, details disappear, main sprites (eventually) cycles Using an advanced version of the technique I proposed you can get this effect... Título: Re: Evitando la "Regla del 5º Sprite" (antes "Snippets") Publicado por: ARTRAG en 27 de Octubre de 2006, 10:30:22 am so, none cares obout this subject !?
??? >:( Título: Re: Evitando la "Regla del 5º Sprite" (antes "Snippets") Publicado por: Jon_Cortazar en 27 de Octubre de 2006, 12:17:51 pm so, none cares obout this subject !? ??? >:( hey ARTRAG, your last message was posted 9 hours ago... please wait a bit more before getting that angry ??? Título: Re: Evitando la "Regla del 5º Sprite" (antes "Snippets") Publicado por: ARTRAG en 27 de Octubre de 2006, 03:20:53 pm kidding
;) Título: Re: Evitando la "Regla del 5º Sprite" (antes "Snippets") Publicado por: Jon_Cortazar en 28 de Octubre de 2006, 10:20:21 am :D :D :D :D :D
I think it is an iteresting topic too. A good article can be taken out of all this imho. ;) Título: Re: Evitando la "Regla del 5º Sprite" (antes "Snippets") Publicado por: ARTRAG en 28 de Octubre de 2006, 10:42:54 am Ok I'll try to sketch my idea about the main + deatail sprite management
Assume that the SAT is in RAM with: N active positions (planes) M main sprites N-M detail sprites In case of no 5thsprite, you copy directly from ram to vram N sprite positions [0,N-1]-> [0,N-1]. Assume now that there is 5thsprite. Let S0 be the 5th sprite plane from the VDP. Assume S0<M (i.e. S0<=M-1) We want to scramble the main sprites and leave the details where they are. RAM VRAM 0 0 P S0 M-1 M-1 N-1 N-1 S0 in VRAM corresponds to plane P in ram We copy : [P,M-1] -> [0,M-1-P] [0,P-1] -> [M-P,M-1] [M,N-1] -> [M,N-1] 0 0 P M-1 M-1 N-1 N-1 Now, sprite that was in S0 in VRAM, and in P in RAM is at plane 0 ad is displayed for sure. Now probably some other sprite is hidden Let S0 be the 5th sprite again. Assume always S0<M We want to scramble the main sprites again and leave the details where they are. Now S0 does not correspond to P but to we have two cases 1) If S0<M-P then the new P’ = P + S0 This is because in the previous step we moved [P,M-1] -> [0,M-1-P] 2) if M-P<= S0 <M then the new P’ = S0 – (M - P) = P + S0 – M this is because in the previous step we moved [0,P-1] -> [M-P,M-1] in both cases now we do P=P’ And we copy again [P,M-1] -> [0,M-1-P] [0,P-1] -> [M-P,M-1] [M,N-1] -> [M,N-1] 0 0 P M-1 M-1 N-1 N-1 Now the main sprites have been scrambled the 5th sprite is again moved on top and we can continue the loop again and again. ---------------------------------------- Assume now that at a certain point we get S0>=M Now we want to scramble the details leaving the main sprites unaltered. 0 0 M-1 M-1 P S0 N-1 N-1 Again at first step P = S0 We copy [0,M-1] -> [0,M-1] [P,N-1] -> [M,N-P-1] [M,P-1] -> [N-P+M,N-1] 0 0 M M P N-P+M N-1 N-1 Now let S0>=M again Again S0 and P do not correspond anymore and we have two cases, 1) if S0<N-P+M then P’ = P + S0-M This because we moved at previous step [P,N-1] -> [M,N-P-1] 2) If S0>=N-P+M then P’ = S0 – (N-P+M) +M = S0 –N +P This because we moved at previous step [M,P-1] -> [N-P+M,N-1] Now we do P=P’ And we copy again [0,M-1] -> [0,M-1] [P,N-1] -> [M,N-P-1] [M,P-1] -> [N-P+M,N-1] in this way details have been scrambled and if S0 stay >= M we can continue with this part of code Do you see the idea ? Note that each time we pass from mode “scramble main sprites” to “scramble details” be need to reset the variable P. This is a draft code of the idea above Código: di(); v99 = SAT & 255; v99 = SAT/256 | 64; if (vdps0 & 64) { u_char s = (vdps0 & 31)*4; if (s<M) { if (P>=M) {P=0;} if (s<M-P) {P += s;} else {P += s-M;} vcopy(P,M-1); // [P,M-1] -> 0 vcopy(0,P-1); // [0,P-1] -> M-P vcopy(M,N-1); // [M,N-1] -> M } else { if (P<M) {P=0;} if (s<M+N-P) {P += s-M;} else {P += s-N;} Q+=4; if (Q>=M) { Q=0; vcopy(0,M-1); // [0,M-1] -> 0 } else { vcopy(Q,M-1); // [Q,M-1] -> 0 vcopy(0,Q-1); // [0,Q-1] -> M-Q } vcopy(P,N-1); // [P,N-1] -> M vcopy(M,P-1); // [M,P-1] -> M+N-P } } else { P = 0; otir(p_sprt,N); } v98 = 208; ei(); } Título: Re: Evitando la "Regla del 5º Sprite" (antes "Snippets") Publicado por: WYZ en 28 de Octubre de 2006, 05:57:39 pm JL, no se a que se debe exactamente pero el método dinamico no funciona (al menos en BlueMSX y OpenMSX) si activas "sprites magnificados".
Título: Re: Evitando la "Regla del 5º Sprite" (antes "Snippets") Publicado por: ARTRAG en 28 de Octubre de 2006, 06:38:31 pm @WYZ
open and blue have strange differences in the managemnt of the S0 register actually "plane swapping" works on both, but the ennanced version main+detail for example doesn't... it could be a matter of errors in the HW emulation.... Título: Re: Evitando la "Regla del 5º Sprite" (antes "Snippets") Publicado por: WYZ en 28 de Octubre de 2006, 06:43:42 pm Yes,It seem to be as you said a HW emulation bug.
Título: Re: Evitando la "Regla del 5º Sprite" (antes "Snippets") Publicado por: jltursan en 29 de Octubre de 2006, 10:13:46 am ¿sprites magnificados?, ¿lo haceis modificando el código de la demo, verdad?. Ya es raro que no funcione, después de todo la diferencia entre ambos modos es únicamente que el VDP multiplica por 2 la altura del sprite a la hora de buscar solapamientos en el eje Y.
Tal como dice ARTRAG, debe de haber alguna inconsistencia en el tratamiento de los planos de sprite. Btw, I like the "main+detail" method, very elaborated!. Although it requires some previous game planning about sprites ordering, it could lead to very good results :). I'll be short of time this week; but I'm thinking on a new general method wich involves Y coordinates sorting. Título: Re: Evitando la "Regla del 5º Sprite" (antes "Snippets") Publicado por: ARTRAG en 29 de Octubre de 2006, 10:25:46 am I have a working implementation of the main+detail method
but in order to make it work I passed to the ugly fixed cycling... This is due to the fact that open and blue does not support the 5th plane in S0 in the same way Código: void satswap (void){ v99 = SAT & 255; v99 = SAT/256 | 64; if (vdps0 & 64) { if (Q>=M) { Q=0; vcopy(0,M-1); // [0,M-1] -> 0 } else { vcopy(Q,M-1); // [Q,M-1] -> 0 vcopy(0,Q-1); // [0,Q-1] -> M-Q } Q+=4; if (P>=N) { P=M; vcopy(P,N-1); // [P,N-1] -> M } else { vcopy(P,N-1); // [P,N-1] -> M vcopy(M,P-1); // [M,P-1] -> M+N-P } P+=4; } else { P = Q = 0; vcopy(0,N-1); } v98 = 208; ei(); } for now I stay with this but the matter on how the 5th plane works in the real HW needs more investigation and open and blue need a refinement (a bug fix I'd say) .... Título: Re: Evitando la "Regla del 5º Sprite" (antes "Snippets") Publicado por: jltursan en 29 de Octubre de 2006, 11:18:33 am Maybe we'll need to move this to MRC... :-\
Título: Re: Evitando la "Regla del 5º Sprite" (antes "Snippets") Publicado por: WYZ en 29 de Octubre de 2006, 02:23:36 pm JL, si simplemente he cambiado:
Código: ld a,(#f3e0) or #02 -> #03 ld b,a ld c,#01 call #0047 Tambien, en algunas pruebas he notado que es mas rapido manejar sprites magnificados, de alguna manera es mas rapido de dibujar para el emulador. Intentaré hacer alguna test. Título: Re: Evitando la "Regla del 5º Sprite" (antes "Snippets") Publicado por: SEPPASEPPA en 29 de Octubre de 2006, 02:38:41 pm I have a working implementation of the main+detail method but in order to make it work I passed to the ugly fixed cycling... This is due to the fact that open and blue does not support the 5th plane in S0 in the same way Código: void satswap (void){ v99 = SAT & 255; v99 = SAT/256 | 64; if (vdps0 & 64) { if (Q>=M) { Q=0; vcopy(0,M-1); // [0,M-1] -> 0 } else { vcopy(Q,M-1); // [Q,M-1] -> 0 vcopy(0,Q-1); // [0,Q-1] -> M-Q } Q+=4; if (P>=N) { P=M; vcopy(P,N-1); // [P,N-1] -> M } else { vcopy(P,N-1); // [P,N-1] -> M vcopy(M,P-1); // [M,P-1] -> M+N-P } P+=4; } else { P = Q = 0; vcopy(0,N-1); } v98 = 208; ei(); } for now I stay with this but the matter on how the 5th plane works in the real HW needs more investigation and open and blue need a refinement (a bug fix I'd say) .... The real challenge is on msx2, where you also had to sprite color tables; so rotating the sprite planes is not so efficient. I've done a routine that could handle a max of 16 sprites. In this scenario, i keep fixed the low sprite planes (0-3) and i start removing the higher planes starting from the plane 4 number and increasing it until i moved more than 8 sprites or i reach the vdp's s0 plane. if (there_are_to_many_sprites) { vdpplane = vdp(0) and 31 for (i=4, sprcount=0;i>vdpplane && sprcount<8;i++,sprcount++) { vpoke sat+4*i,216 // remove the sprite } } When the vdp stop signalling 'too many sprites' i restore the missing sprites. Título: Re: Evitando la "Regla del 5º Sprite" (antes "Snippets") Publicado por: ARTRAG en 29 de Octubre de 2006, 06:22:24 pm IMHO very bad and crappy strategy. I cannot see when and why it could be used...
you get lots of frames where the sprites are hidden or deleted !! Título: Re: Evitando la "Regla del 5º Sprite" (antes "Snippets") Publicado por: SEPPASEPPA en 29 de Octubre de 2006, 11:25:21 pm IMHO very bad and crappy strategy. I cannot see when and why it could be used... you get lots of frames where the sprites are hidden or deleted !! That's the point: it's not heavy, but far,far far from a good result. What i need is a algo that does not rotate the planes because doing so involve also the rotation of sprite color attributes... Any idea? Título: Re: Evitando la "Regla del 5º Sprite" (antes "Snippets") Publicado por: SEPPASEPPA en 30 de Octubre de 2006, 09:06:59 pm IMHO very bad and crappy strategy. I cannot see when and why it could be used... you get lots of frames where the sprites are hidden or deleted !! No, there is a misunderstanding, the time for disabled sprite neither greater or less than when using other methods. for example assume that we have the same condition: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 frame 1: the vdp will report in s0 the value 8, then i will remove the planes from 4-7 frame 2: the vdp show the sprites 0-3 and 8-9-10-11 and will report the sprite 12 in s0, so i will remove sprites 8-9-10-11 frame 3: the vdp show the sprites 0-3 and 12 to 15 without reporting any problem, i will restore the situation in frame 1 So excluding the fact that the sprites 0-3 are fixed (because i WANT this, by design) every sprite block is showed for 1/3 of the entire time. If we accept to work on a 8 sprite basis when removing the sprites the frames required to this situation are 2 so the result is the same of the other methods. Título: Re: Evitando la "Regla del 5º Sprite" (antes "Snippets") Publicado por: ARTRAG en 31 de Octubre de 2006, 10:07:28 am Now I see, when you say "remove" you mean placing the sprite outside the
screen (e.g. y=212), not skipping its plane in the SAT when you update it. Assuming you mean this, everything make sense, as rotating the SAT in sprite mode 2 is absolutely cumbersome (512+128=640 bytes per frame). BTW, the case you depicted is a bit "theoretical", in the sense that you cannot be sure that removing 4 sprites before the one in S0 will guarantee that S0 is displayed... To be sure you should remove at least S0-7 planes before S0 (and this can imply a HUGE flickering...) In any case, removing sprites seems the sole valid option in msx2, as rewriting the SAT and the colortable at 50Hz takes more than 1/3 of the full I/O bandwidth (unless you do not have all the sprites with the same colors :P ) BTW if I well understand your code, it can be rewritten like this: if (there_are_to_many_sprites) { vdpplane = vdp(0) and 31; maxplane = sat+min(4+8,vdpplane)*4; for (i=sat+4*4; i<=maxplane;i+=4) vpoke (i,216); // remove the sprite } I do not see why you cancel exactly 8 sprites or less (?) Título: Re: Evitando la "Regla del 5º Sprite" (antes "Snippets") Publicado por: SEPPASEPPA en 01 de Noviembre de 2006, 07:50:40 pm Now I see, when you say "remove" you mean placing the sprite outside the screen (e.g. y=212), not skipping its plane in the SAT when you update it. Assuming you mean this, everything make sense, as rotating the SAT in sprite mode 2 is absolutely cumbersome (512+128=640 bytes per frame). Yes. BTW, the case you depicted is a bit "theoretical", in the sense that you cannot be sure that removing 4 sprites before the one in S0 will guarantee that S0 is displayed... To be sure you should remove at least S0-7 planes before S0 (and this can imply a HUGE flickering...) Yes, Assuming i have 16 sprites on the same line aligned, the vdp will report 8. So, removing only 4 sprites enable the vdp to display at least the sprite number 8-9-10-11 (because i hide the planes 4-7) Of course the greater number of sprites (max = 8 ) you remove at every frame the higher the flicker frequency you achieve at the cost of a big number of sprites flickering. In the above situation, removing 8 sprites at each frame will achieve a 25 fps flickering freq. Basically the algorithm is this: const nspr = 8; // number of sprites to remove at each frame; function int38h() { if (i_have_to_many_sprites) { updatevramsat(plane_base_index, nspr); // calling this will update y pos to 216 starting at plane_base_index for nspr planes plane_base_index+=nspr; // number of sprites to remove at each frame } else { write_Sat_as_Is(); // write the sat without boring of sprite limits plane_base_index=0; } } So i will continue to remove chunks of nspr sprites until the vdp says "OK, no to many sprites". Really i use only the s0 reg to know the overflow situation; In my specific situation i've added also the option to make the first 4 planes fixed, but this is only because i do not want the main charater to flicker. If it's not clear feel free to reply to this. :) Título: Re: Evitando la "Regla del 5º Sprite" (antes "Snippets") Publicado por: ARTRAG en 01 de Noviembre de 2006, 09:47:21 pm Try removing S0-7 sprites, as planes are numbered from 0
if you have 9 sprites in the screen, all in the same line, S0=8 and S0-7 =1 By removing 1 sprite, the 9th sprite will appear. Pick the sprite to remove at random, or at lest in a way that the removed plane is always different If you have more that 10 sprites, at step 1 you remove 1 sprite, the 9th will appear, but S0=9 so next time you need to remove S0-7=2 sprites Again pick the sprite to remove at random, or at lest in a way that the removed planes are always different and so on... the trouble is that when the 9th sprite has a very low plane, you get a lot of flickering sprites.... If you have only few objects (say 16-20) maybe it could be acceptable (but IMHO far from good...as the lower is the plane of the 9th sprite, the higher is its "off" time) A better method would be compare the Y of the sprite in S0 with the Y of the sprites of plane before S0, and removing the first sprite you find on that line, but this involves extra processing. Moreover you need, in the worst case, to compare up to S0-8 planes. |