Posté le 14/06/2012 à 22:46 Membre depuis le 15/03/2005, 3470 messages
J'ai eu beau chercher aux confins de google, je ne suis pas parvenus à mettre la main sur ne serait-ce qu'un bout de code d'une routine permettant de faire un flip horizontal d'un sprite (tiens j'aurai juré que "sprite" était féminin).

Pourtant faire un effet miroir ça a déjà été fait de nombreuses fois (xlib et compagnie), sauf que les sources ne sont pas dispo... donc si quelqu'un a une routine assez optimisée ce serait cool de la partager smile
Posté le 15/06/2012 à 10:03 Membre depuis le 25/03/2011, 207 messages
tu veux dire une symétrie axiale par rappor à un axe horizontal?
Posté le 15/06/2012 à 10:11 Membre depuis le 15/03/2005, 3470 messages
Un axe vertical plutôt (en gros faire comme avec l'option "retourner horizontalement" de paint).
Posté le 15/06/2012 à 10:55 Membre depuis le 03/06/2011, 520 messages
Je crois qu'il y avait juste ça sur MaxCoderz...
Ahhh!, le voici:
http://maxcoderz.org/forum/viewtopic.php?f=8&t=1322
Posté le 15/06/2012 à 11:16 Membre depuis le 15/03/2005, 3470 messages
C'est pas exactement ce dont j'ai besoin, enfaite là ça fait une rotation pas un flip. Puis ça ne prend en compte que les sprites 8x8 or j'ai besoin de pouvoir en utiliser des plus grands.

Mais merci quand même ça pourra m'être utile pour autre chose smile

Voilà en gros ce que je cherche à faire :

njEE
Posté le 15/06/2012 à 11:58 Membre depuis le 02/02/2009, 672 messages
Avec 2 shift ça ne suffit pas?
Le premier shift a droite et tu insères dans le second en shiftant a gauche (et selon la taille du sprites faut shifter sur plusieurs bytes en utilisant ce qui sort évidemment)
Et faire ça pour chaque ligne...

Je ne sais pas si j'ai dit une connerie, mais ça me parait pas extrêmement compliqué au fond smile
Posté le 15/06/2012 à 12:27 Membre depuis le 03/06/2011, 520 messages
Regarde ici:
http://omnimaga.org/index.php?topic=1598.0 (cherche "Reverse a")
Posté le 15/06/2012 à 12:52 Membre depuis le 15/03/2005, 3470 messages
Ah oui pas mal, mais je me demande ce qui serait le plus optimisé : faire une routine spéciale qui se charge de faire le flip et l'affichage ou faire le flip avant dans un sprite temporaire puis l'afficher normalement ?
Posté le 15/06/2012 à 14:48 Membre depuis le 03/06/2011, 520 messages
Ça depend de combien de fois tu voudras utiliser les sprites, je suppose. Tu pourrais les charger dans un buffer pendant l'éxécution de ton programme. Combien de sprites auras-tu besoin de "flipper" ? Il y a pas mal de saferam à ton disposition. Et je suis content de te voir ici de nouveau smile

xLib avait une fonction pour faire des flips horizontals/verticals, mais je ne sais pas s'il vient avec le source. tr1pea y toujours là chez MaxCoderz, il pourrait sûrement t'aider aussi. Personnellement, je chargerait les sprites dans un buffer (quelque part dans saferam) parce qu'il serait le plus simple de coder.
Posté le 15/06/2012 à 15:12 Membre depuis le 15/03/2005, 3470 messages
Ouais pour finir je pense que je vais utiliser un buffer.

Je vais commencer à coder ça.
Posté le 15/06/2012 à 15:24 Membre depuis le 02/02/2009, 672 messages
C'est pour gurk?
Posté le 15/06/2012 à 15:35 Membre depuis le 15/03/2005, 3470 messages
Non un autre projet que j'ai démarré mais je ne veux rien annoncer pour le moment, j'ai déjà assez de projets non terminés...
Posté le 15/06/2012 à 16:17 Membre depuis le 02/02/2009, 672 messages
Oui c'est pas une mauvaise idée smile

Mais tu devrais repartir de gurk il était déjà bien avancé c'est dommage.
Posté le 15/06/2012 à 16:31 Membre depuis le 15/03/2005, 3470 messages
Non mais je l'abandonne pas smile

	.nolist
#include	"ion.inc"
	.list
#ifdef TI83P
	.org progstart-2
	.db $bb,$6d
#else 
	.org progstart
#endif
	ret
	jr nc,start
	.db "flip a sprite",0

start:
	ld ix,sprite
	ld bc,$0803
	push bc
	xor a
	ld l,a
	call ionLargeSprite
	pop bc
	push bc
	ld ix,sprite
	call flipsprite
	ld a,25
	ld l,0
	pop bc
	call ionLargeSprite
	call ionFastCopy
	bcall _getkey
	ret

; INPUT :
; ix:sprite; b:height; c:width/8
; OUTPUT :
; ix=flipped sprite
; /!\ saferam2 is used

flipsprite:
	push ix
	pop hl
	ld de,saferam2

flipsprite_loop:
	push bc
	push hl
	ld h,d
	ld l,e
	ld b,0
	add hl,bc
	ld d,h
	ld e,l
	pop hl
	push de
	ld b,c

flipsprite_loop2:
	push bc
	ld a,(hl)
	call reverse_a
	ld (de),a
	inc hl
	dec de
	pop bc
	djnz flipsprite_loop2
	pop de
	pop bc
	djnz flipsprite_loop
	ld de,saferam2
	push de
	pop ix
	ret

;- Reverse a
;input:	Byte in A
;output:	Reversed byte in A
;destroys	B
;Clock cycles: 66
;Bytes: 18
;author: calcmaniac84
reverse_a:
	ld b,a
	rrca
	rrca
	xor b
	and %10101010
	xor b
	ld b,a
	rrca
	rrca
	rrca
	rrca
	xor b
	and %01100110
	xor b
	rrca
	ret

sprite:
	.db %11111111,%11111111,%11111111
	.db %10001000,%10001010,%00100011
	.db %10111010,%10101111,%01101111
	.db %10001000,%10011011,%01100011
	.db %11101011,%10101011,%01101111
	.db %11101011,%10101011,%01101111
	.db %10001011,%10101011,%01100011
	.db %11111111,%11111111,%11111111

	.end


Ça me gave ça bug :

nZtK

En gros ce que je fait (ou voudrait faire) c'est mettre l'adresse du buffer (saferam2) à y*largeur du sprite et y coller "à reculons" (du côté droit du sprite vers la gauche) l'inverse de l'octet du sprite...

Quelqu'un voit où ça merde ?
Posté le 15/06/2012 à 22:35 Membre depuis le 15/03/2005, 3470 messages
Allez savoir pourquoi apparemment ça commençait à copier le sprite "flippé" à saferam2+1...
	.nolist
#include	"ion.inc"
	.list
#ifdef TI83P
	.org progstart-2
	.db $bb,$6d
#else 
	.org progstart
#endif
	ret
	jr nc,start
	.db "flip a sprite",0

start:
	ld ix,sprite
	ld bc,$0803
	push bc
	push ix
	xor a
	ld l,a
	call ionLargeSprite
	pop hl
	pop bc
	push bc
	call flipsprite
	ld a,25
	ld l,0
	pop bc
	call ionLargeSprite
	call ionFastCopy
	bcall _getkey
	ret

; INPUT :
; hl:sprite; b:height; c:width/8
; OUTPUT :
; ix=flipped sprite
; /!\ saferam2 is used

flipsprite:
	ld de,saferam2-1

flipsprite_loop:
	push bc
	push hl
	ld h,d
	ld l,e
	ld b,0
	add hl,bc
	ld d,h
	ld e,l
	pop hl
	push de
	ld b,c

flipsprite_loop2:
	push bc
	ld a,(hl)
	call reverse_a
	ld (de),a
	inc hl
	dec de
	pop bc
	djnz flipsprite_loop2
	pop de
	pop bc
	djnz flipsprite_loop
	ld de,saferam2
	push de
	pop ix
	ret

;- Reverse a
;input:	Byte in A
;output:	Reversed byte in A
;destroys	B
;Clock cycles: 66
;Bytes: 18
;author: calcmaniac84
reverse_a:
	ld b,a
	rrca
	rrca
	xor b
	and %10101010
	xor b
	ld b,a
	rrca
	rrca
	rrca
	rrca
	xor b
	and %01100110
	xor b
	rrca
	ret

sprite:
	.db %11111111,%11111111,%11111111
	.db %10001000,%10001010,%00100011
	.db %10111010,%10101111,%01101111
	.db %10001000,%10011011,%01100011
	.db %11101011,%10101011,%01101111
	.db %11101011,%10101011,%01101111
	.db %10001011,%10101011,%01100011
	.db %11111111,%11111111,%11111111

	.end

JJGN

Bref ça marche mais si vous voyez un moyen de l'optimiser n'hésitez pas !

edit : apparemment y'a quelque chose de corrompu, lorsqu'on quitte Ion il ne veut plus se relancer... sad

À mon avis c'est le genre de petit truc dont on ne fait que passer devant sans le voir donc je vais me coucher ça commence à trop me gonfler...
Posté le 16/06/2012 à 09:56 Membre depuis le 15/03/2005, 3470 messages
edit : Ça y est ça marche nickel mais n'hésitez pas à proposer mieux ! smile
; INPUT :
; ix:sprite; b:height; c:width/8
; OUTPUT :
; ix=flipped sprite
; destroys a, hl, de
; uses saferam3

flip_sprite:
	push bc
	push ix
	pop de
	ld hl,saferam3

flip_sprite_loop:
	push bc
	push de
	ld b,0
	add hl,bc
	pop de
	push hl
	ld b,c

flip_sprite_loop2:
	push bc
	dec hl
	ld a,(de)
	call reverse_a
	ld (hl),a
	inc de
	pop bc
	djnz flip_sprite_loop2
	pop hl
	pop bc
	djnz flip_sprite_loop
	ld hl,saferam3
	push hl
	pop ix
	pop bc
	ret

;- Reverse a
;input:	Byte in A
;output:	Reversed byte in A
;destroys	B
;Clock cycles: 66
;Bytes: 18
;author: calcmaniac84
reverse_a:
	ld b,a
	rrca
	rrca
	xor b
	and %10101010
	xor b
	ld b,a
	rrca
	rrca
	rrca
	rrca
	xor b
	and %01100110
	xor b
	rrca
	ret
Posté le 04/02/2013 à 12:56 Membre depuis le 03/06/2011, 520 messages
Voici une version plus petite (38 octets) :
; INPUT :
; ix:sprite; b:height; c:width/8
; OUTPUT :
; ix=flipped sprite
; destroys a, de
; uses saferam3
flip_sprite:
	push bc
		push ix
		pop de
		ld hl,saferam3
flip_sprite_outer:
;de = original sprite
;hl = buffer
		push bc				;save b (sprite height)
			ld b,0			;bc = width in bytes
			add hl,bc		;go to very right of first sprite and draw leftward
			push hl
				ld b,8
flip_sprite_loop:
				dec hl			;go left in buffer
				push bc			;c gets overwritten so we need to save it
					ld a,(de)	;first byte in a
					rrca		;rotate a to the right and rotate the carry left into c
					rl c
					djnz $-3
					ld (hl),c	;save flipped byte
					inc de		;next byte of sprite
				pop bc			;c = counter (number of bytes to flip)
				dec c
				jr nz,flip_sprite_loop
			pop hl
		pop bc			;restore b (height)
		djnz flip_sprite_outer
		ld ix,saferam3
	pop bc
	ret