30

hier soir j'ai joué un peu avec les interruptions et je crois que j'ai (finalement!) un bon timer basé sur les interruptions qui ne ralentit jamais pour ton jeu.


euh tu es vraiment fort ...^^

Pour le timer sans interruption, une idee pour eviter les ralentissement serait de placer des "CALL UPDATE_TIMER" dans la partie keypress (il n'y en a pas du coup lorsqu'on se deplace on ne met pas à jour le timer). Mais si tu as réussi avec les interruptions je suis vraiment curieux de voi ça et l'adapter. Est-ce que cela va marcher sur ti83 "regular" ?
hier soir j'ai joué un peu avec les interruptions et je crois que j'ai (finalement!) un bon timer basé sur les interruptions qui ne ralentit jamais pour ton jeu.

Les sprites sont toujours alignés donc tu as raison c'est inutile pour le damier mais certains sprites utilisent cette routines sans etre aligné comme le tube suivant qui n'est pas forcement sur une case alignée. Je tiens à preciser que ce n'est pas ma routine mais celle de "movax" ...

Concernant la limite de 8k, j'ai eu ce probleme avec bomberman je crois.
Comment etre sur d'avoir que des données après les 8k?
Placer les includes des fichiers de données en dernier suffit j'imagine?

Concernant les variables 16 bits tu as raison c'est une erreur de ma part je n'ai pas fait attention.

Merci encore pour tous ces très très bon conseils. tu m'apprends beaucoup de choses.


Je n'ai pas eu beaucoup de temps cette semaine, j'en aurais surement un peu plus la semaine qui vient pour étudier tes améliorations et tes suggestions.

Merci encore grin

31

ei ret interruption_fin:
Voici le code pour le timer:charger_int:
 di
#ifdef TI83P
offset=$9A9A
	ld hl,$9900
	ld (hl),$9A
	ld bc,256
	ld a,h
	ld d,h
	ld e,b	;de = $9901
	ldir
	ld hl,interruption
	ld de,$9A9A
	ld bc,interruption_fin - interruption
	ldir
	ld i,a
#elseif TI83
offset=$8484
	ld hl,$8300
	ld (hl),$84
	ld bc,256
	ld a,h
	ld d,h
	ld e,b	;de = $8301
	ldir
	ld hl,interruption
	ld de,$8484
	ld bc,interruption_fin - interruption
	ldir
	ld i,a
#endif
	im 2
	ei
	ret

interruption:
	di
	exx
	ex af,af'
	
	ld hl,(fin_timer-interruption) + offset
	push hl

	ld	hl, timeup
	ld	a,(hl)
	and	a
	ret z		;aller à fin_timer
;microsecondes
	inc hl		;micro
	ld a,(hl)
	dec (hl)
	ret	nz
;millisecondes
	ld (hl),100
	inc hl		;maintenant hl=milli
	ld a,(hl)
	dec (hl)
	ret nz
;secondes
	ld (hl),100
	ld a,(hl)
	inc hl		;et maintenant, sec
	dec (hl)
	ret	nz
pas_de_temps:
	ld	hl, timeup
	ld	(hl), 0
	ret			;aller à fin_timer (ou "pop hl")
fin_timer:
	exx
	ex af,af'
	

Pour l'utiliser il faudra d'abord "call charger_int" (et tu voudras probablement aussi ôter ton timer antérieur).

Et oui, tu peux mettre tous les includes au final, pourvu qu'il n'y ait pas de code exécutable.
tromb Fichier joint : Dfok (timer_interruption.gif)

32

Merci.

Juste quelques petites questions, qu'est-ce que ei, di, im...?

Pourquoi tu echanges tous les registres (exx) puis tu echange af par af'.



PS : Bon en fait je ne comprends rien à ton code xD (mais merci mille fois tongue)

33

ei active les interruptions, di fait l'inverse et im c'est le mode d'interruption, voir http://www.mworld.fr/html/projects/calc/ti-82/tutoriel/progasm/guide/lesson20.html

exx inverse tous les registres 16 bit sauf af (d'où le ex af,af') avec les registres "shadow" : http://www.mworld.fr/html/projects/calc/ti-82/tutoriel/progasm/guide/lesson17.html

34

On pourrait aussi push/pop les registres, mais ça tarde beaucoup. Néanmoins, si tu va utiliser les registres cachés peut-être il serait mieux de le faire comme ça. Sinon, tu auras besoin de désactiver les interruptions à chaque fois que tu veux les (je veux dire, les registres cachés) utiliser.

Voici des explications du code:
charger_int: 			;routine pour charger interruption :P
 di 				;comme t'a dit deeph, désactiver les interruptions
 				; (pour qu'une autre interruption ne faisse rien de bizarre
 				; pendant que nous installons la notre)
#ifdef TI83P 			;le code pour le TI83P
offset=$9A9A 			;où nous allons installer l'interruption
	ld hl,$9900 		;il nous faut une table de vecteurs
	ld (hl),$9A 		; tous les octets ayant la même valeur ($9A)
	ld bc,256
	ld a,h 			;h=$99, alors a aussi
	ld d,h 			;d=$99
	ld e,b			;de = $9901 
	ldir 			;exécuter
	ld hl,interruption	;l'addresse du code de l'interruption
	ld de,$9A9A 		;l'endroit où nous allons placer l'interruption
	ld bc,interruption_fin - interruption 	;sa taille
	ldir
	ld i,a 			;i=MSB, c'est-à-dire: la calculatrice va chercher une valeur dans $99XX
				; (notre table), est cette valeur sera toujours $9A
#elseif TI83 
offset=$8484 			;le même code mais avec les valeurs pour le ti83
	ld hl,$8300 
	ld (hl),$84 
	ld bc,256 
	ld a,h 
	ld d,h 
	ld e,b	;de = $8301 
	ldir 
	ld hl,interruption 
	ld de,$8484 
	ld bc,interruption_fin - interruption 
	ldir 
	ld i,a 
#endif 
	im 2 			;im 2, mode d'interruption 2, pour pouvoir utiliser notre interruption
	ei 			;activer les interruptions !
	ret 
 
interruption: 
	di 			;moi je ne crois pas qu'il le faut parce que le code n'est pas trop grand
				; mais il est ici pour éviter qu'une autre interruption se démarrer avant de terminer cette-ci
				; (ce qui causerait une boucle infinie)
	exx 			;garder les registres (bc,de,hl)
	ex af,af' 		;af

;l'interruption va être chargé à $9A9A ou $8484, pas ici dans le programme.
; si nous voulons jr/jp/call une routine dans notre interruption,
; il faut premièrement savoir où nous allons sauter
	ld hl,(fin_timer-interruption) + offset
	push hl 		;maintenant, si on "ret", on sautera au label "fin_timer"

;ton code de timer
	ld	hl, timeup
	ld	a,(hl) 
	and	a 
	ret z		;aller à fin_timer 
;microsecondes 
	inc hl		;micro 
	ld a,(hl) 
	dec (hl) 
	ret	nz 
;millisecondes 
	ld (hl),100 
	inc hl		;maintenant hl=milli 
	ld a,(hl) 
	dec (hl) 
	ret nz 
;secondes 
	ld (hl),100 
	ld a,(hl) 
	inc hl		;et maintenant, sec 
	dec (hl) 
	ret	nz 
pas_de_temps: 
	ld	hl, timeup 
	ld	(hl), 0 
	ret		;aller à fin_timer (ou "pop hl") 
fin_timer:
	exx 		;remettre les variables normales...
	ex af,af' 	;...
	ei		;activer les interruptions...
	ret 		;et quitter
interruption_fin:

35

merci beaucoup.

36

J'ai commencé à faire le page de menu.
(j'écris "OILCAP" avec des tubes)

Il ne me reste (quasiment) plus que les niveaux à faire et les transitions ("GAGNE TON SCORE EST XXX", "NIVEAU SUIVANT", et "PERDU" etc...) et c'est bon smile


37

J'ai hâte de voir ça ! N'hésite pas à poster des screens smile

Et pour les textes tu peux utiliser les accents (cf cette table), même si certains rendent très mal en majuscule...

38

C'est incroyable que tu aies déjà (ou presque) terminer ! Comment est-ce que tu remplis les tubes ? J'y pensais l'autre jour et c'était plus comlpliqué que j'avais pensé.
A propos, ton code est-il toujours sur Google Code ?

39

Pour le remplissage des tubes j'utilise le parcours en profondeur d'un arbre (http://fr.wikipedia.org/wiki/Algorithme_de_parcours_en_profondeur).
Le parcours en largeur serait plus joli mais il faudrait implementer une liste (mais l'algo est plus simple).

Pour le remplissage des tubes je le fais donc plus ou moins recursivement, mais je parcours un chemins jusqu'au bout plutôt que de faire tous les voisins immédiats.
J'ai également enlevé la vraie recursivité pour eviter de parser la case d'ou on vient.
(petit screenshot à venir)
Pas tellement evident à coder mais à ma grande surprise ça a marché rapidement xD

Il faudra que je gère les boucles car cela pourrait me faire planter le jeu.
Et aussi que j'intègre tes nombreuses optimisations/modifications.

La dernière version est toujours sur google code.

40

A deeph: comment on utilise ta table ?

41

Suffit de rajouter le code hexadécimal à la suite de ta chaîne de caractères (avant le 0 donc), par exemple pour la flèche vers le bas c'est $07.

42

Ok super merci smile

43

Voila donc le screenshot promis.
J'utilise ce que tu m'as donné deeph (fleche).

oilcap9.gif
oilcap9.png
oilcap9b.png
(non je n'ai pas ces couleurs en vrai)

Et pour chickendude on voit le remplissage de tube à la fin qui se fait bien (meme si plantage après lol).

Ca vous plait?

44

C'est classe, le seul truc un peu stressant je trouve c'est que le temps n'arrête pas de clignoter, c'est lié au gif ? Sinon il y a un flag (textwrite) qui permet de n'écrire que dans le buffer, mais il ne semble affecter que les petits caractères.

45

Mais c'est très facile à convertir, les nombres à des caractères ASCII. Autre chose que tu pourrais faire c'est pas afficher/mettre à jour la partie supérieure de l'écran quand tu affiches le graphbuffer. Ça aussi c'est assez simple et je peux t'aider si tu veux.

46

c'est que le temps n'arrête pas de clignoter, c'est lié au gif ? Sinon il y a un flag (textwrite) qui permet de n'écrire que dans le buffer, mais il ne semble affecter que les petits caractères.


Tu as tout à fait raison ça clignote, car mon call BUFCOPY m'efface la sortie de call _dispHL (car pas copié dans le graphbuf).
Et pourtant je mets à jour juste après mais ça se voit quand même ...
Je n'ai pas encore trouvé le flag que tu dis (pour ti83) et je ne suis pas sur que ca va marcher. Mais comme dis chickendude je peux relativement passer ça en ascii et utiliser vputs et le flag SET bufferOnly, (IY + textWrite) ou quelques chose de ressemblant smile
Autre chose que tu pourrais faire c'est pas afficher/mettre à jour la partie supérieure de l'écran quand tu affiches le graphbuffer. Ça aussi c'est assez simple et je peux t'aider si tu veux.


C'est une bonne idee de faire ça et surtout une bonne idée de savoir le faire (pour d'autres utilisations futures).
Mais je ne vois absolument pas comment copier qu'une partie du graphbuffer. Personnellement je fais call BUFCOPY et ça me fait tout sans que je parametre quoi que ce soit.

Bref je veux bien que tu m'aides , s'il te plait wink

47

Il y a une routine assez célèbre qui s'appelle "fastcopy" (ou ionfastcopy). Elle est beaucoup plus vite que _bufCopy et d'ailleurs tu pourrais la changer aisément pour sauter les premières lignes:
Voici le code:
fastCopy:
 di
 ld a,$80
 out ($10),a
 ld hl,gbuf-12-(-(12*64)+1)  ;changer ici
 ld a,$20
 ld c,a
 inc hl  ;filler
 dec hl ;filler
fastCopyAgain:
 ld b,64   ;et ici
 inc c
 ld de,-(12*64)+1
 out ($10),a
 add hl,de
 ld de,10
fastCopyLoop:
 add hl,de
 inc hl  ;filler
 inc hl  ;filler
 inc de ;filler
 ld a,(hl)
 out ($11),a
 dec de ;filler
 djnz fastCopyLoop
 ld a,c
 cp $2B+1
 jr nz,fastCopyAgain
 ret
Les ports $10/$11 sont du LCD, $10 pour changer la colonne (et d'autres choses) où tu veux afficher et $11: le LCD-même.

48

Tu peux essayer ce code-ci:
gbuf=PLOTSSCREEN
fastCopy:
 di
 ld hl,gbuf-12-(-(12*64)+1)
 ld a,$20
 ld c,a
fastCopyAgain:
 ld b,56
 inc c
 ld de,-(12*56)+1
 out ($10),a
 add hl,de
 ld de,10
 call $000B
 ld a,$88
 out ($10),a
fastCopyLoop:
 add hl,de
 inc hl  ;filler
 inc hl  ;filler
 inc de ;filler
 ld a,(hl)
 out ($11),a
 dec de ;filler
 djnz fastCopyLoop
 ld a,c
 cp $2B+1
 jr nz,fastCopyAgain
 ret

C'est un peu plus compliqué que j'avais pensé, mais....:
d2Yp

49

Merci trilove trilove trilove trilove

J'ai fait pas mal de corrections d'après vos remarques : variables 8 bits au lieu de 16, moins de push pop dans les routines quand ce n'est pas necessaire, optimisations des tests.
Je me suis basé sur vos commentaires et bouts de codes postés.
Plus d'info ici : http://code.google.com/p/oilcap/source/list

II faudra que j'utilise le code de chickendude pour le timer et le fastcopy et ce sera mieux.

Mais mon prochain travail est de finir le jeu (niveaux et message de victoire/defaite).

Je n'ai pas beaucoup de temps en ce moment mais j'espère avancer un peu ce soir ou demain.

@chickendude : super ton code merci merci merci mais c'est quoi le "=" ??

50

Je ne sais pas, peut-être c'est du titre que je n'avais pas effacé ? Je croyais que tu l'avais ajouté comme un sprite du score :P

51

C'est surement un reste de "SCORE=" ou quelques chose comme ça. Tu travailles sur une vieille version je pense.

52

Ok j'ai remplacé call BUFCOPY par ta call FASTCOPY et ça marche super bien (meme pas de "=").

smile

53

J'ai pas vraiment avancé dessus mais hasard des recherches sur ticalc.org j'ai trouvé un clone de mon jeu...

http://www.ticalc.org/archives/files/fileinfo/234/23494.html

J'ai pas trop regardé ni testé mais le mec a l'air de faire bien mieux que moi avec beaucoup moins de code... ooh
PipeMania v2.3 is inspired on a fantastic arcade game. You have to connect parts of pipes so that there can run water through it. This version has difficulty levels, ability to take a screenshot, turn power off, reset highscores and has the one and only HONEST random routine in z80 ASM land!! This game is only 2854 bytes and runs in ION.


Qui a dit que mon jeu n'a plus de raison d'être? tongue

54

Il y a toujours mieux si on cherche bien grin

Mais finir le tiens aura au moins le mérite de perfectionner tes connaissances en ASM et de faire vivre un peu le forum smile

55

Je suis sûr que le tien est meilleur smile Mais... pourquoi voudrait-on une capture d'écran ? Tout de même il faudra le jouer et jeter un coup d'oeuil au code source.

56

Je suis sûr que le tien est meilleur


C'est gentil mais un peu démagogique tongue

Je vais jeter un coup d'oeil mais j'essaye de compléter le mien avant de faire ça smile

edit : en fait j'ai quand même testé et il est franchement bien fait mais s'il y a peut-être des choses que j'aurais géré différemment .

pipemania.gif

57

Je crois que la barre de temps est une bonne idée smile Qu'est-ce qu'il te faut encore pour le tien ?

58

Je trouve que le temps passe un peu trop vite en tout cas avec la barre mais c'est une bonne idée.

Pour mon jeu il me manque de sortir correctement de la recursivité (parsing des tubes à la fin).
En fait je n'arrive pas encore à faire en sorte que l'on puisse passer à un autre niveau lorsque l'on gagne.
Et puis il faut que je réinitialise toutes les valeurs pour relancer un niveau.

J'aimerai aussi ajouter un mode aléatoire qui permettrait de prendre soit des valeurs en mémoire et les utiliser pour générer des tubes soit directement trouver un algo pour avoir des tubes générés aléatoirement donc. Mais il faudrait que les tubes ne soient pas trop difficiles (donc pondérer de façon a avoir des chances de finir le niveau)

Puis je voudrais ajouter un petit effet genre "TV noise" au lancement du jeu.Peut-être un menu avec des choix bref des bricoles tongue

Pour le pipemania trouvé sur ticalc le developpeur s'est beaucoup moins fait chier car les tubes proposés sont beaucoup plus "simples" c'est à dire un seule entrée une seule sortie et du coup l'algo pour remplir et tester la victoire est vraiment très simple.
Bref peut-être que cela ne vous parle pas ce probleme mais perso je n'ai pas voulu me priver des tubes à sorties multiples juste pour simplifier mon code (c'est tout le défi de faire l'algo justement héhé)

Mais le jeu n'en reste pas moins très beau.
Faut que je regarde son algo de random il a l'air de dire qu'il est super...

Je ne sais pas trop si vous me suivez tongue

59

Moi aussi, le temps passe assez vite mais ça peut s'arranger aisément.

60

Sur ce point effectivement tu as raison.

Je ne peux pas bosser sur mon jeu en ce moment, mais j'espère le finir en septembre.

Autre chose : J'imagine que la version modifiée pour ti83+ est perdue avec ton PC??? :'(