Skip to content

Instantly share code, notes, and snippets.

@jdesboeufs
Created September 29, 2016 15:17
Show Gist options
  • Save jdesboeufs/2407392bc3f639dc4835513f84fd03bd to your computer and use it in GitHub Desktop.
Save jdesboeufs/2407392bc3f639dc4835513f84fd03bd to your computer and use it in GitHub Desktop.
Space Invaders
include "OS.h"
xdef _ti89
xdef asm_init_jeu
xdef asm_jeu
xdef asm_vaisseau_g
xdef asm_vaisseau_d
xdef asm_tirer
asm_init_jeu:
MOVE.L #nb_ennemis,A5
MOVE.B #15,(A5) ; Nombre de survivants (15)
MOVE.L #dir_ennemis,A5
MOVE.B #1,(A5) ; Direction initiale des ennemis (1 = droite, 2 = gauche)
MOVE.L #pos_vaisseau,A5
MOVE.W #72,(A5) ; Position initiale du vaisseau (72)
MOVE.L #pos_missile,A5
MOVE.W #800,(A5)+ ; Position initiale du missile (800,800)
MOVE.W #800,(A5)
MOVE.L #pos_bombes,A5 ; Position initiale des bombes (800,800)
MOVE.L #14,D5
aij_b1 MOVE.W #800,(A5)+
MOVE.W #800,(A5)+
DBRA D5,aij_b1
MOVE.L #pos_ennemis,A5 ; On calcule la position initiale de tous les vaisseaux ennemis
MOVE.L #2,D4 ; 3 lignes
MOVE.L #1,D1 ; Ordonn�e initiale = 1
rp_b MOVE.L #30,D0 ; Abscisse initiale = 30
MOVE.L #4,D3 ; 5 colonnes
rp_b2 MOVE.W D0,(A5)+
MOVE.W D1,(A5)+
ADD.L #20,D0 ; On incr�mente l'abscisse de 20 � chaque d�placement vers la droite
DBRA D3,rp_b2
ADD.L #10,D1 ; De m�me de 10 pour l'ordonn�e vers le bas
DBRA D4,rp_b
BSR tracer_ennemis
BSR tracerBoucliers
MOVE.L #pos_vaisseau,-(A7) ; Passage de la position du vaisseau en argument (pointeur)
BSR tracerVaisseau
ADDA.L #4,A7
RTS
tracer_ennemis:
MOVE.L #14,D4 ; On va simplement faire une boucle
MOVE.L #pos_ennemis,A5
te_b MOVE.L A5,-(A7) ; On place sur la pile
ADDA.L #4,A5
BSR tracerEnnemi ; On ex�cute
ADDA.L #4,A7
DBRA D4,te_b
RTS
asm_jeu:
BSR mvt_ennemis
BSR mvt_missile
BSR tirs_ennemis
BSR mvt_bombes ; Sous-programme posant quelques probl�mes actuellement non-r�solus
BSR collision_ennemis
BSR collision_vaisseau
RTS
asm_vaisseau_g:
MOVE.L #pos_vaisseau,A5
CMP.W #0,(A5) ; Si le vaisseau ne touche pas le bord gauche
BEQ retour
MOVE.L A5,-(A7) ; On l'efface
BSR tracerVaisseau
ADDA.L #4,A7
SUB.W #1,(A5) ; On le d�place
MOVE.L A5,-(A7)
BSR tracerVaisseau ; On l'affiche � nouveau
ADDA.L #4,A7
RTS
asm_vaisseau_d:
MOVE.L #pos_vaisseau,A5
CMP.W #144,(A5) ; M�me principe avec le bord droit
BEQ retour
MOVE.L A5,-(A7)
BSR tracerVaisseau
ADDA.L #4,A7
ADD.W #1,(A5)
MOVE.L A5,-(A7)
BSR tracerVaisseau
ADDA.L #4,A7
RTS
asm_tirer:
MOVE.L #pos_missile,A5
CMP.W #800,(A5) ; Si le missile est en position 800,800
BNE retour ; c'est qu'il n'est pas sur l'�cran, on peut donc tirer
MOVE.L #pos_vaisseau,A4
MOVE.W (A4),D0
ADD.W #7,D0 ; On initialise les coordonn�es par rapport au vaisseau
MOVE.W D0,(A5)+
MOVE.W #89,(A5)
MOVE.L #pos_missile,-(A7)
BSR tracerMissile ; On trace
ADDA.L #4,A7
RTS
mvt_missile:
MOVE.L #pos_missile,A5
MOVE.W (A5),D0
CMP.W #800,D0
BEQ retour
MOVE.L A5,-(A7)
BSR tracerMissile ; On efface le missile
ADDA.L #4,A7
ADDA.L #2,A5
MOVE.W (A5),D0
SUB.W #1,D0 ; On d�cr�mente de 1 l'ordonn�e
MOVE.W D0,(A5)
SUBA.L #2,A5
CMP.W #0,D0 ; On v�rifie qu'on touche pas le bord haut de l'�cran
BEQ m_init
MOVE.L A5,-(A7)
BSR tracerMissile ; On trace
ADDA.L #4,A7
BRA retour
m_init MOVE.L #pos_missile,A5 ; Si on touche le bord, on r�initialise les coordonn�es
MOVE.W #800,(A5)+
MOVE.W #800,(A5)
RTS
collision_ennemis:
MOVE.L #14,D5 ; On va boucler sur tous les ennemis pour tester les collisions
MOVE.L #pos_ennemis,A5
ce_t MOVE.L #pos_missile,A4
MOVE.W (A5)+,D1
MOVE.W (A5)+,D2
CMP.W (A4),D1 ; Est-ce qu'on est bien � droite du bord gauche de l'alien ?
BGT ce_non
ADD.W #14,D1
CMP.W (A4)+,D1 ; Est-ce qu'on est bien � gauche du bord droit de l'alien ?
BLT ce_non
ADD.W #0,D2
CMP.W (A4),D2 ; Est-ce qu'on est bien sous le bord sup�rieur de l'alien ?
BGT ce_non
ADD.W #8,D2
CMP.W (A4),D2 ; Est-ce qu'on est bien au dessus du bord inf�rieur de l'alien ?
BLT ce_non
SUBA.L #2,A4
MOVE.L A4,-(A7)
MOVE.L #pointeur,A1 ; Sauvegarde du pointeur vers la position de l'ennemi courant
SUBA.L #4,A5
MOVE.L A5,(A1)
BSR tracerMissile ; On efface le missile
ADDA.L #4,A7
BSR m_init ; Et on le r�initialise
MOVE.L #pointeur,A1
MOVE.L (A1),A5
MOVE.L A5,-(A7) ; On efface l'ennemi abattu
BSR tracerEnnemi
ADDA.L #4,A7
MOVE.L #pointeur,A1
MOVE.L (A1),A5
MOVE.W #300,(A5)+ ; Et on le r�initialise
MOVE.W #300,(A5)
MOVE.L #nb_ennemis,A2
MOVE.W (A2),D3
SUB.W #1,D3
MOVE.W D3,(A2)
BSR ennemiTue ; On informe le C qu'on a tu� un monstre
RTS
ce_non DBRA D5,ce_t ; Sinon on recommence pour les autres aliens
RTS
detection_changement_sens: ; Est-ce qu'un alien touche le bord gauche ou droit ?
MOVE.L #14,D5
MOVE.L #pos_ennemis,A5
MOVE.L #dir_ennemis,A4
MOVE.W #143,D1
dcs_b MOVE.W (A5),D0
CMP.W #0,D0
BNE dcs_s1
MOVE.B #1,(A4) ; Touche le bord gauche > on va vers la droite
BRA mvt_ennemis_b ; Mais on descend aussi d'un cran (pour que le jeu ait un int�r�t)
dcs_s1 CMP.W #143,D0
BNE dcs_s2
MOVE.B #2,(A4) ; Touche le bord droit > on va vers la gauche
BRA mvt_ennemis_b ; Mais on descend aussi d'un cran (pour que le jeu ait un int�r�t)
dcs_s2 ADDA.L #4,A5
DBRA D5,dcs_b
RTS
mvt_ennemis:
BSR detection_changement_sens ; On regarde si les aliens changent de sens
MOVE.L #dir_ennemis,A5
CMP.B #1,(A5)
BNE mvt_ennemis_g ; Et on agit en cons�quence / Gauche
BRA mvt_ennemis_d ; Droite
mvt_ennemis_g:
MOVE.L #14,D5 ; Boucle sur les 15 aliens
MOVE.L #pos_ennemis,A5
meg_b MOVE.W (A5),D0
CMP.W #300,D0 ; On regarde si l'alien est vivant
BEQ meg_s
MOVE.L A5,-(A7)
BSR tracerEnnemi ; On efface l'alien
ADDA.L #4,A7
MOVE.W (A5),D0
SUB.W #1,D0 ; On d�place
MOVE.W D0,(A5)
MOVE.L A5,-(A7)
BSR tracerEnnemi ; On r�affiche
ADDA.L #4,A7
meg_s ADDA.L #4,A5
DBRA D5,meg_b
RTS
mvt_ennemis_d: ; Idem que g
MOVE.L #14,D5
MOVE.L #pos_ennemis,A5
med_b MOVE.W (A5),D0
CMP.W #300,D0
BEQ med_s
MOVE.L A5,-(A7)
BSR tracerEnnemi
ADDA.L #4,A7
MOVE.W (A5),D0
ADD.W #1,D0
MOVE.W D0,(A5)
MOVE.L A5,-(A7)
BSR tracerEnnemi
ADDA.L #4,A7
med_s ADDA.L #4,A5
DBRA D5,med_b
RTS
mvt_ennemis_b:
MOVE.L #14,D5 ; Boucle sur les 15 aliens
MOVE.L #pos_ennemis,A5
meb_b MOVE.W (A5),D0
CMP.W #300,D0
BEQ meb_s
MOVE.L A5,-(A7)
BSR tracerEnnemi ; On efface
ADDA.L #4,A7
ADDA.L #2,A5
MOVE.W (A5),D0
ADD.W #2,D0 ; On d�place de 2px
MOVE.W D0,(A5)
CMP.W #85,D0 ; On regarde si l'alien a touch� la zone critique � d�fendre
BEQ gameover ; Si oui, c'est perdu !!
meb_r SUBA.L #2,A5
MOVE.L A5,-(A7)
BSR tracerEnnemi ; On affiche
ADDA.L #4,A7
meb_s ADDA.L #4,A5
DBRA D5,meb_b
RTS
mev_go BSR gameover
BRA meb_r
tirs_ennemis:
BSR tireur ; On d�termine un tireur
CMP.W #0,D0
BEQ retour
MOVE.L #pos_ennemis,A5
MOVE.L #pos_bombes,A4
SUB.L #1,D0
MULU #4,D0
ADDA.L D0,A5
ADDA.L D0,A4 ; On se place sur celui-ci (sur sa bombe)
CMP.W #800,(A4) ; La bombe est-elle d�j� lanc�e ?
BNE retour ; Si oui, on abandonne
CMP.W #300,(A5) ; L'alien est-il vivant ?
BEQ retour ; Si non, on abandonne
MOVE.W (A5)+,D1
MOVE.W (A5),D2
ADD.W #7,D1 ; On positionne la bombe par rapport � l'alien
ADD.W #3,D2
MOVE.W D1,(A4)+
MOVE.W D2,(A4)
SUBA.L #2,A4
MOVE.L A4,-(A7)
BSR tracerMissile ; Et on trace
ADDA.L #4,A7
RTS
collision_vaisseau:
MOVE.L #14,D5
MOVE.L #pos_bombes,A5
MOVE.L #pos_vaisseau,A4
MOVE.W (A4),D0 ; Abscisse du vaisseau
MOVE.W #85,D1 ; Ordonn�e du vaisseau (-5 pour la largeur de la bombe)
cv_d MOVE.W (A5)+,D2 ; Abscisse de la bombe
MOVE.W (A5)+,D3 ; Ordonn�e de la bombe
CMP.W D0,D2 ; Teste le c�t� gauche
BLT cv_s
SUB.W #16,D2 ; L'autre c�t�
CMP.W D0,D2
BGT cv_s
CMP.W D1,D3 ; Teste au dessus
BLT cv_s
SUB.W #4,D3 ; En dessous
CMP.W D1,D3
BGT cv_s
BSR gameover ; Jeu termin�
cv_s DBRA D5,cv_d
RTS
mvt_bombes:
MOVE.L #14,D5 ; On boucle sur les bombes
MOVE.L #pos_bombes,A5
mb_d ADDA.L #2,A5
MOVE.W (A5),D0
SUBA.L #2,A5
CMP.W #800,D0
BEQ mb_su
CMP.W #90,D0
BEQ mb_init
MOVE.L A5,-(A7)
BSR tracerMissile ; On efface
ADDA.L #4,A7
ADDA.L #2,A5
MOVE.W (A5),D0
ADD.W #1,D0
MOVE.W D0,(A5)
SUBA.L #2,A5
MOVE.L A5,-(A7)
BSR tracerMissile ; Sinon on trace
ADDA.L #4,A7
BRA mb_su
mb_init MOVE.L A5,-(A7)
BSR tracerMissile ; On efface
ADDA.L #4,A7
MOVE.W #800,(A5)+
MOVE.W #800,(A5)
SUBA.L #2,A5
mb_su ADDA.L #4,A5
DBRA D5,mb_d
RTS
retour:
RTS
nb_ennemis DS.B 1
pos_ennemis DS.W 30
dir_ennemis DS.B 1
pos_vaisseau DS.W 1
pos_bombes DS.W 30
pos_missile DS.W 2
pointeur DS.L 1
#define USE_TI89 // Compile for TI-89
#define SAVE_SCREEN // Save/Restore LCD Contents
#include <tigcclib.h>
#include <graph.h>
#include <default.h>
#include <stdlib.h>
void asm_init_jeu();
void asm_vaisseau_g();
void asm_vaisseau_d();
void asm_tirer();
void asm_jeu();
/*static unsigned short int bouclier[] = {0x1FF8,0x3FFC,0x7FFE,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF}; // Sprite du bouclier
static unsigned short int vaisseau[] = {0x0100,0x0380,0x3FF8,0x7FFC,0xFFFE,0xFFFE,0x7FFC,0x3FF8}; // Sprite du vaisseau
static unsigned short int ennemi[] = {0x3FF8,0x7FFC,0xFFFE,0xFFFE,0x7FFC,0x3FF8,0x0380,0x0100}; // Sprite des vaisseaux ennemis*/
static unsigned short int bouclier[] = {0x1FF8,0x3FFC,0x781E,0xF00F,0xE007,0xE007,0xE007,0xE007}; // Sprite du bouclier
static unsigned short int vaisseau[] = {0xC106,0xC386,0xC7C6,0xCFE6,0xCFE6,0xFFFE,0xFFFE,0xCFE6}; // Sprite du vaisseau
static unsigned short int ennemi[] = {0x3398,0x711C,0xFBBE,0xFFFE,0x7FFC,0x3FF8,0x0380,0x0100}; // Sprite des vaisseaux ennemis
unsigned short int nbEnnemis = 15;
char victoire;
INT_HANDLER interrupt1, interrupt5;
// Comptabilise les aliens morts
void ennemiTue(void) {
nbEnnemis--;
if(nbEnnemis==0) victoire = 1;
}
// On prend son temps en faisant un petit calcul inutile mais co�teux
void pause(void) {
short int i = 300, nbAlea;
i -= (15-nbEnnemis)*2;
while (i-- > 0) {
nbAlea = rand() % i;
}
}
// D�termine l'alien qui va tirer, sous r�serve de passer la premi�re condition
int tireur(void) {
if(random(50-((nbEnnemis)/2)) <= 1) {
return random(14);
} else {
return 0;
}
}
// Tracer les boucliers
void tracerBoucliers() {
Sprite16(18, 62, 8, bouclier, LCD_MEM, SPRT_XOR);
Sprite16(72, 62, 8, bouclier, LCD_MEM, SPRT_XOR);
Sprite16(125, 62, 8, bouclier, LCD_MEM, SPRT_XOR);
}
// Trace le vaisseau, un pointeur vers l'abscisse �tant donn� en argument
void tracerVaisseau(short * pos) {
Sprite16(pos[0], 90, 8, vaisseau, LCD_MEM, SPRT_XOR);
}
// Tracer un vaisseau ennemi, les coordonn�es �tant donn�es en argument
void tracerEnnemi(short * pos) {
Sprite16(pos[0], pos[1], 8, ennemi, LCD_MEM, SPRT_XOR);
}
// Tracer un missile, les coordonn�es �tant donn�es en argument
void tracerMissile(short * pos){
int i;
for(i=pos[1]; i<pos[1]+5; i++) {
if(i>=0) {
DrawPix(pos[0], i, A_XOR);
}
}
}
// Cette fonction sert � sauvegarder les HANDLERS rattach�s au m�canisme d'interruption code 1 et 5
// Elle va ensuite associer de nouveaux HANDLERS qui nous permettent d'avoir un contr�le total sur les entr�es de la calculatrice
// L'int�r�t de cette manipulation est de pouvoir utiliser _rowread qui est une fonction bas niveau performante
void controlerClavier() {
interrupt1 = GetIntVec(AUTO_INT_1);
interrupt5 = GetIntVec(AUTO_INT_5);
SetIntVec(AUTO_INT_1,DUMMY_HANDLER);
SetIntVec(AUTO_INT_5,DUMMY_HANDLER);
}
// M�canisme inverse de la fonction pr�c�dente
void libererClavier() {
SetIntVec(AUTO_INT_1,interrupt1);
SetIntVec(AUTO_INT_5,interrupt5);
}
// Lorsque la partie est perdue
void gameover(void) {
nbEnnemis=0; // Indique � la boucle globale de s'arr�ter proprement
victoire=0;
}
void _main()
{
int clavier;
nbEnnemis = 15;
randomize(); // Initialise le g�n�rateur de nombres al�atoires
ClrScr(); // Efface l'�cran
DrawStr(30, 20, "Space IInvadErs", A_NORMAL); // Placement du titre
ngetchx(); // Attente de l'enfoncement d'une touche quelconque
controlerClavier(); // Voir ci-dessus
ClrScr();
asm_init_jeu(); // On initialise le jeu
while(nbEnnemis>0) {
clavier = _rowread(0xFFFE); // On lit la matrice du clavier
if(clavier&0x0002) { // Touche Gauche enfonc�e
asm_vaisseau_g();
}
if(clavier&0x0008) { // Touche Droite enfonc�e
asm_vaisseau_d();
}
if(clavier&0x0010) { // Touche Seconde (Tir) enfonc�e
asm_tirer();
}
asm_jeu(); // Routine du jeu
pause(); // Ralentissement de la boucle
}
libererClavier(); // Voir ci-dessus
ClrScr();
if(victoire==1) {
DrawStr(30, 20, "Victoire !", A_NORMAL);
} else {
DrawStr(30, 20, "Game over !", A_NORMAL);
}
for(clavier=0; clavier<10; clavier++) {
pause();
}
ngetchx();
exit(0);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment