Add animations for square swaps.

This commit is contained in:
Jeremy Rand 2016-07-22 14:48:49 -05:00
parent b595c11bc0
commit f66715e9d2
7 changed files with 435 additions and 152 deletions

View File

@ -115,6 +115,62 @@ void drawGemAtSquare(tSquare square)
}
void drawGemAtXY(uint8_t x, uint8_t y, tGemType gemType, bool starred)
{
static uint8_t tempX;
tempX = x;
switch (gemType) {
case GEM_GREEN:
__asm__("ldx %v", tempX);
drawGreenGemAtXY(y);
break;
case GEM_RED:
__asm__("ldx %v", tempX);
drawRedGemAtXY(y);
break;
case GEM_PURPLE:
__asm__("ldx %v", tempX);
drawPurpleGemAtXY(y);
break;
case GEM_ORANGE:
__asm__("ldx %v", tempX);
drawOrangeGemAtXY(y);
break;
case GEM_GREY:
__asm__("ldx %v", tempX);
drawGreyGemAtXY(y);
break;
case GEM_YELLOW:
__asm__("ldx %v", tempX);
drawYellowGemAtXY(y);
break;
case GEM_BLUE:
__asm__("ldx %v", tempX);
drawBlueGemAtXY(y);
break;
case GEM_SPECIAL:
__asm__("ldx %v", tempX);
drawSpecialGemAtXY(y);
break;
default:
break;
}
if (starred) {
__asm__("ldx %v", tempX);
starGemAtXY(y);
}
}
void beginStarAnim(void)
{
gStarAnimState.starVisible = true;
@ -329,3 +385,80 @@ void endClearGemAnim(void)
cgetc();
#endif
}
#undef DEBUG_SWAP_ANIM
void swapSquares(tSquare square1, tGemType gemType1, bool starred1,
tSquare square2, tGemType gemType2, bool starred2)
{
// The x positions are multiplied by 4 to get a number from 0 to 28
uint8_t x1 = (SQUARE_TO_X(square1) << 2);
uint8_t x2 = (SQUARE_TO_X(square2) << 2);
// The y positions are multiplied by 3 to get a number from 0 to 21
uint8_t y1 = (SQUARE_TO_Y(square1) * 3);
uint8_t y2 = (SQUARE_TO_Y(square2) * 3);
uint8_t temp;
// If x1 is bigger than x2, then swap. We want x1 to go up and x2
// to go down. Easier to make that assumption. Same for y1 and
// y2.
if ((x1 > x2) ||
(y1 > y2)) {
temp = x2;
x2 = x1;
x1 = temp;
temp = y2;
y2 = y1;
y1 = temp;
#if 0
// We don't need to swap square numbers. The code from here on
// doesn't distinguish between the two square numbers. So, save
// some time and don't sway.
//
// Be careful if this assumption is no longer true.
temp = square2;
square2 = square1;
square1 = temp;
#endif
temp = gemType2;
gemType2 = gemType1;
gemType1 = temp;
temp = starred2;
starred2 = starred1;
starred1 = temp;
}
if (x1 < x2) {
temp = x2;
while (x1 < temp) {
x1++;
x2--;
gVblWait();
drawBgSquare(square1);
drawBgSquare(square2);
drawGemAtXY(x1, y1, gemType1, starred1);
drawGemAtXY(x2, y2, gemType2, starred2);
#ifdef DEBUG_SWAP_ANIM
cgetc();
#endif
}
} else {
temp = y2;
while (y1 < temp) {
y1++;
y2--;
gVblWait();
drawBgSquare(square1);
drawBgSquare(square2);
drawGemAtXY(x1, y1, gemType1, starred1);
drawGemAtXY(x2, y2, gemType2, starred2);
#ifdef DEBUG_SWAP_ANIM
cgetc();
#endif
}
}
}

View File

@ -10,6 +10,8 @@
#define __a2bejwld__anim__
#include <stdbool.h>
#include "types.h"
@ -28,5 +30,8 @@ extern void addClearAtSquare(tSquare square);
extern void undoClearAtSquare(tSquare square);
extern void endClearGemAnim(void);
extern void swapSquares(tSquare square1, tGemType gemType1, bool starred1,
tSquare square2, tGemType gemType2, bool starred2);
#endif /* defined(__a2bejwld__anim__) */

View File

@ -44,4 +44,19 @@ extern void __fastcall__ selectSquare(tSquare square);
extern void __fastcall__ drawScore(uint8_t score);
// The following functions take the Y position (0-23) as
// their first argument. The X position (0-39) should
// be in the X register.
extern void __fastcall__ drawBlueGemAtXY(uint8_t y);
extern void __fastcall__ drawYellowGemAtXY(uint8_t y);
extern void __fastcall__ drawRedGemAtXY(uint8_t y);
extern void __fastcall__ drawGreenGemAtXY(uint8_t y);
extern void __fastcall__ drawOrangeGemAtXY(uint8_t y);
extern void __fastcall__ drawGreyGemAtXY(uint8_t y);
extern void __fastcall__ drawPurpleGemAtXY(uint8_t y);
extern void __fastcall__ drawSpecialGemAtXY(uint8_t y);
extern void __fastcall__ starGemAtXY(uint8_t y);
#endif /* defined(__a2bejwld__dbllores__) */

View File

@ -14,6 +14,10 @@
.export _drawOrangeGem, _drawSpecialGem, _drawBgSquare
.export _drawScore, _selectSquare, _starGem
.export _drawGreenGemAtXY, _drawPurpleGemAtXY, _drawYellowGemAtXY
.export _drawBlueGemAtXY, _drawRedGemAtXY, _drawGreyGemAtXY
.export _drawOrangeGemAtXY, _drawSpecialGemAtXY, _starGemAtXY
.export _explodeGemFrame1, _explodeGemFrame2
.export _explodeGemFrame3, _explodeGemFrame4
.export _explodeGemFrame5, _explodeGemFrame6
@ -236,41 +240,32 @@ color: .BYTE $0
.endproc
.proc _drawGem
; A is the square position (from 0 to 63)
; 0 through 7 are on the top row
sta square
and #7
asl
asl
sta xPos
lda square
lsr
lsr
lsr
.proc _drawGemAtXY
stx xPos
tax
; Get line addrs
tax
lda bgLoLines1,X
lda lineLoAddrs,X
clc
adc xPos
sta line1addr
lda bgHiLines1,X
lda lineHiAddrs,X
sta line1addr+1
lda bgLoLines2,X
inx
lda lineLoAddrs,X
clc
adc xPos
sta line2addr
lda bgHiLines2,X
lda lineHiAddrs,X
sta line2addr+1
lda bgLoLines3,X
inx
lda lineLoAddrs,X
clc
adc xPos
sta line3addr
lda bgHiLines3,X
lda lineHiAddrs,X
sta line3addr+1
; Draw the gem
@ -356,115 +351,8 @@ xPos: .BYTE $0
square: .BYTE $0
.endproc
.proc _drawGreenGem
ldx #<greenGem
stx gemaddr
ldx #>greenGem
stx gemaddr+1
ldx #<greenMask
stx gemmask
ldx #>greenMask
stx gemmask+1
jmp _drawGem
.endproc
.proc _drawPurpleGem
ldx #<purpleGem
stx gemaddr
ldx #>purpleGem
stx gemaddr+1
ldx #<purpleMask
stx gemmask
ldx #>purpleMask
stx gemmask+1
jmp _drawGem
.endproc
.proc _drawYellowGem
ldx #<yellowGem
stx gemaddr
ldx #>yellowGem
stx gemaddr+1
ldx #<yellowMask
stx gemmask
ldx #>yellowMask
stx gemmask+1
jmp _drawGem
.endproc
.proc _drawBlueGem
ldx #<blueGem
stx gemaddr
ldx #>blueGem
stx gemaddr+1
ldx #<blueMask
stx gemmask
ldx #>blueMask
stx gemmask+1
jmp _drawGem
.endproc
.proc _drawRedGem
ldx #<redGem
stx gemaddr
ldx #>redGem
stx gemaddr+1
ldx #<redMask
stx gemmask
ldx #>redMask
stx gemmask+1
jmp _drawGem
.endproc
.proc _drawGreyGem
ldx #<greyGem
stx gemaddr
ldx #>greyGem
stx gemaddr+1
ldx #<greyMask
stx gemmask
ldx #>greyMask
stx gemmask+1
jmp _drawGem
.endproc
.proc _drawOrangeGem
ldx #<orangeGem
stx gemaddr
ldx #>orangeGem
stx gemaddr+1
ldx #<orangeMask
stx gemmask
ldx #>orangeMask
stx gemmask+1
jmp _drawGem
.endproc
.proc _drawSpecialGem
ldx #<specialGem
stx gemaddr
ldx #>specialGem
stx gemaddr+1
ldx #<specialMask
stx gemmask
ldx #>specialMask
stx gemmask+1
jmp _drawGem
.endproc
.proc _selectSquare
ldx #<selectGem
stx gemaddr
ldx #>selectGem
stx gemaddr+1
ldx #<selectMask
stx gemmask
ldx #>selectMask
stx gemmask+1
jmp _drawGem
.endproc
.proc _starGem
.proc _drawGem
; A is the square position (from 0 to 63)
; 0 through 7 are on the top row
sta square
@ -472,16 +360,237 @@ square: .BYTE $0
and #7
asl
asl
inc A
inc A
sta xPos
tax
lda square
; Need to divide by 8 to get the y square
; and then multiply by 3 to get the y
; position (0-23) on the screen.
lsr
lsr
lsr
sta square
asl
clc
adc square
jmp _drawGemAtXY
; Locals
square: .BYTE $0
.endproc
.proc _drawGreenGem
ldy #<greenGem
sty gemaddr
ldy #>greenGem
sty gemaddr+1
ldy #<greenMask
sty gemmask
ldy #>greenMask
sty gemmask+1
jmp _drawGem
.endproc
.proc _drawGreenGemAtXY
ldy #<greenGem
sty gemaddr
ldy #>greenGem
sty gemaddr+1
ldy #<greenMask
sty gemmask
ldy #>greenMask
sty gemmask+1
jmp _drawGemAtXY
.endproc
.proc _drawPurpleGem
ldy #<purpleGem
sty gemaddr
ldy #>purpleGem
sty gemaddr+1
ldy #<purpleMask
sty gemmask
ldy #>purpleMask
sty gemmask+1
jmp _drawGem
.endproc
.proc _drawPurpleGemAtXY
ldy #<purpleGem
sty gemaddr
ldy #>purpleGem
sty gemaddr+1
ldy #<purpleMask
sty gemmask
ldy #>purpleMask
sty gemmask+1
jmp _drawGemAtXY
.endproc
.proc _drawYellowGem
ldy #<yellowGem
sty gemaddr
ldy #>yellowGem
sty gemaddr+1
ldy #<yellowMask
sty gemmask
ldy #>yellowMask
sty gemmask+1
jmp _drawGem
.endproc
.proc _drawYellowGemAtXY
ldy #<yellowGem
sty gemaddr
ldy #>yellowGem
sty gemaddr+1
ldy #<yellowMask
sty gemmask
ldy #>yellowMask
sty gemmask+1
jmp _drawGemAtXY
.endproc
.proc _drawBlueGem
ldy #<blueGem
sty gemaddr
ldy #>blueGem
sty gemaddr+1
ldy #<blueMask
sty gemmask
ldy #>blueMask
sty gemmask+1
jmp _drawGem
.endproc
.proc _drawBlueGemAtXY
ldy #<blueGem
sty gemaddr
ldy #>blueGem
sty gemaddr+1
ldy #<blueMask
sty gemmask
ldy #>blueMask
sty gemmask+1
jmp _drawGemAtXY
.endproc
.proc _drawRedGem
ldy #<redGem
sty gemaddr
ldy #>redGem
sty gemaddr+1
ldy #<redMask
sty gemmask
ldy #>redMask
sty gemmask+1
jmp _drawGem
.endproc
.proc _drawRedGemAtXY
ldy #<redGem
sty gemaddr
ldy #>redGem
sty gemaddr+1
ldy #<redMask
sty gemmask
ldy #>redMask
sty gemmask+1
jmp _drawGemAtXY
.endproc
.proc _drawGreyGem
ldy #<greyGem
sty gemaddr
ldy #>greyGem
sty gemaddr+1
ldy #<greyMask
sty gemmask
ldy #>greyMask
sty gemmask+1
jmp _drawGem
.endproc
.proc _drawGreyGemAtXY
ldy #<greyGem
sty gemaddr
ldy #>greyGem
sty gemaddr+1
ldy #<greyMask
sty gemmask
ldy #>greyMask
sty gemmask+1
jmp _drawGemAtXY
.endproc
.proc _drawOrangeGem
ldy #<orangeGem
sty gemaddr
ldy #>orangeGem
sty gemaddr+1
ldy #<orangeMask
sty gemmask
ldy #>orangeMask
sty gemmask+1
jmp _drawGem
.endproc
.proc _drawOrangeGemAtXY
ldy #<orangeGem
sty gemaddr
ldy #>orangeGem
sty gemaddr+1
ldy #<orangeMask
sty gemmask
ldy #>orangeMask
sty gemmask+1
jmp _drawGemAtXY
.endproc
.proc _drawSpecialGem
ldy #<specialGem
sty gemaddr
ldy #>specialGem
sty gemaddr+1
ldy #<specialMask
sty gemmask
ldy #>specialMask
sty gemmask+1
jmp _drawGem
.endproc
.proc _drawSpecialGemAtXY
ldy #<specialGem
sty gemaddr
ldy #>specialGem
sty gemaddr+1
ldy #<specialMask
sty gemmask
ldy #>specialMask
sty gemmask+1
jmp _drawGemAtXY
.endproc
.proc _selectSquare
ldy #<selectGem
sty gemaddr
ldy #>selectGem
sty gemaddr+1
ldy #<selectMask
sty gemmask
ldy #>selectMask
sty gemmask+1
jmp _drawGem
.endproc
.proc _starGemAtXY
inx
inx
stx xPos
tax
; Get line addrs
tax
lda bgLoLines2,X
clc
adc xPos
@ -500,6 +609,28 @@ xPos: .BYTE $0
square: .BYTE $0
.endproc
.proc _starGem
; A is the square position (from 0 to 63)
; 0 through 7 are on the top row
sta square
and #7
asl
asl
tax
lda square
lsr
lsr
lsr
jmp _starGemAtXY
; Locals
xPos: .BYTE $0
square: .BYTE $0
.endproc
.proc _drawScore
; A is a number from 0 to 24
tay
@ -928,10 +1059,6 @@ square: .BYTE $0
.DATA
lineAddrs:
.WORD LINE1, LINE2, LINE3, LINE4, LINE5, LINE6, LINE7, LINE8
.WORD LINE9, LINE10, LINE11, LINE12, LINE13, LINE14, LINE15, LINE16
.WORD LINE17, LINE18, LINE19, LINE20, LINE21, LINE22, LINE23, LINE24
lineLoAddrs:
.LOBYTES LINE1, LINE2, LINE3, LINE4, LINE5, LINE6, LINE7, LINE8

View File

@ -304,18 +304,18 @@ tSquare getHintSquare(void)
}
static void swapSquares(tSquare square, tSquare otherSquare, bool update)
static void doSwapSquares(tSquare square, tSquare otherSquare, bool update)
{
tSquareState tempState;
if (update) {
gGameCallbacks->swapSquares(square, GEM_TYPE_AT_SQUARE(square), GEM_STARRED_AT_SQUARE(square),
otherSquare, GEM_TYPE_AT_SQUARE(otherSquare), GEM_STARRED_AT_SQUARE(otherSquare));
}
tempState = gGameState.squareStates[square];
gGameState.squareStates[square] = gGameState.squareStates[otherSquare];
gGameState.squareStates[otherSquare] = tempState;
if (update) {
gGameCallbacks->squareCallback(square);
gGameCallbacks->squareCallback(otherSquare);
}
}
@ -345,23 +345,23 @@ bool gameIsOver(void)
}
if (gemType != otherGemType) {
swapSquares(square, otherSquare, false);
doSwapSquares(square, otherSquare, false);
if ((numMatchingUpDownAtSquare(otherSquare, gemType, false) > 0) ||
(numMatchingRightLeftAtSquare(otherSquare, gemType, false) > 0)) {
gGameState.hintSquare = square;
swapSquares(square, otherSquare, false);
doSwapSquares(square, otherSquare, false);
return false;
}
if ((numMatchingUpDownAtSquare(square, otherGemType, false) > 0) ||
(numMatchingRightLeftAtSquare(square, otherGemType, false) > 0)) {
gGameState.hintSquare = otherSquare;
swapSquares(square, otherSquare, false);
doSwapSquares(square, otherSquare, false);
return false;
}
swapSquares(square, otherSquare, false);
doSwapSquares(square, otherSquare, false);
}
}
@ -374,23 +374,23 @@ bool gameIsOver(void)
}
if (gemType != otherGemType) {
swapSquares(square, otherSquare, false);
doSwapSquares(square, otherSquare, false);
if ((numMatchingUpDownAtSquare(otherSquare, gemType, false) > 0) ||
(numMatchingRightLeftAtSquare(otherSquare, gemType, false) > 0)) {
gGameState.hintSquare = square;
swapSquares(square, otherSquare, false);
doSwapSquares(square, otherSquare, false);
return false;
}
if ((numMatchingUpDownAtSquare(square, otherGemType, false) > 0) ||
(numMatchingRightLeftAtSquare(square, otherGemType, false) > 0)) {
gGameState.hintSquare = otherSquare;
swapSquares(square, otherSquare, false);
doSwapSquares(square, otherSquare, false);
return false;
}
swapSquares(square, otherSquare, false);
doSwapSquares(square, otherSquare, false);
}
}
}
@ -674,7 +674,7 @@ bool moveSquareInDir(tSquare square, tDirection dir)
otherGemType = GEM_TYPE_AT_SQUARE(otherSquare);
// Actually do the fun stuff here...
swapSquares(square, otherSquare, true);
doSwapSquares(square, otherSquare, true);
if (gemType == GEM_SPECIAL) {
doSpecialForGemType(otherGemType, otherSquare);
@ -693,7 +693,7 @@ bool moveSquareInDir(tSquare square, tDirection dir)
gGameCallbacks->endClearGemAnim();
if (!goodMove) {
swapSquares(square, otherSquare, true);
doSwapSquares(square, otherSquare, true);
} else {
while (explodeGems())

View File

@ -39,6 +39,8 @@ typedef struct tGameCallbacks {
void (*addClearAtSquare)(tSquare square);
void (*undoClearAtSquare)(tSquare square);
void (*endClearGemAnim)(void);
void (*swapSquares)(tSquare square1, tGemType gemType1, bool starred1,
tSquare square2, tGemType gemType2, bool starred2);
} tGameCallbacks;

View File

@ -43,6 +43,7 @@ static tGameCallbacks gCallbacks = {
addClearAtSquare,
undoClearAtSquare,
endClearGemAnim,
swapSquares,
};