Add missile command sample game
This commit is contained in:
parent
e1f605b28c
commit
995e39a57d
|
@ -35,8 +35,9 @@ char MixedColors[4][4][8] = {
|
|||
void bmmc_put(const Bitmap * bm, int x, int y, char c)
|
||||
{
|
||||
char * dp = bm->data + bm->cwidth * (y & ~7) + ((x & ~7) | (y & 7));
|
||||
char pat = cbytes[c & 3];
|
||||
|
||||
*dp = (*dp & andmask[x & 7]) | (cbytes[c & 3] & ormask[x & 7]);
|
||||
*dp = ((*dp ^ pat) & andmask[x & 7]) ^ pat;
|
||||
}
|
||||
|
||||
char bmmc_get(const Bitmap * bm, int x, int y)
|
||||
|
|
|
@ -11987,7 +11987,7 @@ void NativeCodeBasicBlock::BlockSizeReduction(void)
|
|||
i += 3;
|
||||
}
|
||||
else if (i + 5 < mIns.Size() &&
|
||||
mIns[i + 0].mType == ASMIT_LDA &&
|
||||
mIns[i + 0].ChangesAccuAndFlag() &&
|
||||
mIns[i + 1].mType == ASMIT_CMP && mIns[i + 1].mMode == ASMIM_IMMEDIATE && mIns[i + 1].mAddress == 0x01 &&
|
||||
mIns[i + 2].mType == ASMIT_LDA && mIns[i + 2].mMode == ASMIM_IMMEDIATE && mIns[i + 2].mAddress == 0x00 &&
|
||||
mIns[i + 3].mType == ASMIT_ADC && mIns[i + 3].mMode == ASMIM_IMMEDIATE && mIns[i + 3].mAddress == 0xff &&
|
||||
|
@ -13032,6 +13032,7 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(int pass)
|
|||
}
|
||||
else
|
||||
mIns.Insert(i + 0, NativeCodeInstruction(ASMIT_LDY, ASMIM_ZERO_PAGE, iins->mAddress));
|
||||
if (i > 0)
|
||||
mIns[i + 0].mLive = mIns[i - 1].mLive | LIVE_CPU_REG_Y | LIVE_MEM;
|
||||
}
|
||||
|
||||
|
@ -13994,6 +13995,16 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(int pass)
|
|||
#endif
|
||||
|
||||
#endif
|
||||
else if (
|
||||
mIns[i + 0].mType == ASMIT_ASL && mIns[i + 0].mMode == ASMIM_ZERO_PAGE &&
|
||||
mIns[i + 1].mType == ASMIT_ROL && mIns[i + 1].mMode == ASMIM_ZERO_PAGE && mIns[i + 1].mAddress != mIns[i + 0].mAddress &&
|
||||
mIns[i + 2].mType == ASMIT_LDA && mIns[i + 2].mMode == ASMIM_ZERO_PAGE && mIns[i + 2].mAddress == mIns[i + 0].mAddress && !(mIns[i + 2].mLive & (LIVE_MEM | LIVE_CPU_REG_C | LIVE_CPU_REG_Z)))
|
||||
{
|
||||
mIns[i + 0].mType = ASMIT_LDA; mIns[i + 0].mLive |= LIVE_CPU_REG_A;
|
||||
mIns[i + 2].mType = ASMIT_ROL; mIns[i + 2].mAddress = mIns[i + 1].mAddress; mIns[i + 2].mLive |= LIVE_MEM;
|
||||
mIns[i + 1].mType = ASMIT_ASL; mIns[i + 1].mMode = ASMIM_IMPLIED; mIns[i + 1].mLive |= LIVE_CPU_REG_A | LIVE_CPU_REG_C;
|
||||
progress = true;
|
||||
}
|
||||
#if 1
|
||||
else if (
|
||||
mIns[i + 0].mType == ASMIT_ASL && mIns[i + 0].mMode == ASMIM_ZERO_PAGE &&
|
||||
|
@ -14230,6 +14241,36 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(int pass)
|
|||
progress = true;
|
||||
}
|
||||
#endif
|
||||
#if 1
|
||||
else if (
|
||||
mIns[i + 0].mType == ASMIT_LDA &&
|
||||
mIns[i + 1].mType == ASMIT_STA && mIns[i + 1].mMode == ASMIM_ZERO_PAGE && !mIns[i + 0].MayBeChangedOnAddress(mIns[i + 1]) &&
|
||||
mIns[i + 2].mType == ASMIT_LDA && mIns[i + 2].mMode == ASMIM_ZERO_PAGE &&
|
||||
mIns[i + 3].mType == ASMIT_ORA && mIns[i + 3].SameEffectiveAddress(mIns[i + 0]))
|
||||
{
|
||||
mIns[i + 2].mType = ASMIT_ORA;
|
||||
mIns[i + 3].mType = ASMIT_NOP; mIns[i + 3].mMode = ASMIM_IMPLIED;
|
||||
|
||||
progress = true;
|
||||
}
|
||||
#endif
|
||||
#if 1
|
||||
else if (
|
||||
mIns[i + 0].mType == ASMIT_LDA &&
|
||||
mIns[i + 1].mType == ASMIT_EOR && mIns[i + 1].mMode == ASMIM_IMMEDIATE && mIns[i + 1].mAddress == 0xff &&
|
||||
mIns[i + 2].mType == ASMIT_SEC &&
|
||||
mIns[i + 3].mType == ASMIT_ADC)
|
||||
{
|
||||
mIns.Insert(i + 4, mIns[i + 0]);
|
||||
|
||||
mIns[i + 0].mType = ASMIT_NOP; mIns[i + 0].mMode = ASMIM_IMPLIED;
|
||||
mIns[i + 1].mType = ASMIT_NOP; mIns[i + 1].mMode = ASMIM_IMPLIED;
|
||||
mIns[i + 3].mType = ASMIT_LDA; mIns[i + 3].mLive |= LIVE_CPU_REG_C;
|
||||
mIns[i + 4].mType = ASMIT_SBC;
|
||||
|
||||
progress = true;
|
||||
}
|
||||
#endif
|
||||
#if 1
|
||||
else if (
|
||||
mIns[i + 0].mType == ASMIT_STA && mIns[i + 0].mMode == ASMIM_ZERO_PAGE &&
|
||||
|
|
|
@ -73,7 +73,7 @@ int main(int argc, const char** argv)
|
|||
|
||||
#else
|
||||
strcpy(strProductName, "oscar64");
|
||||
strcpy(strProductVersion, "1.3.74");
|
||||
strcpy(strProductVersion, "1.4.75");
|
||||
|
||||
#ifdef __APPLE__
|
||||
uint32_t length = sizeof(basePath);
|
||||
|
|
|
@ -25,8 +25,8 @@ LANGUAGE LANG_ENGLISH, SUBLANG_NEUTRAL
|
|||
//
|
||||
|
||||
VS_VERSION_INFO VERSIONINFO
|
||||
FILEVERSION 1,3,74,0
|
||||
PRODUCTVERSION 1,3,74,0
|
||||
FILEVERSION 1,4,75,0
|
||||
PRODUCTVERSION 1,4,75,0
|
||||
FILEFLAGSMASK 0x3fL
|
||||
#ifdef _DEBUG
|
||||
FILEFLAGS 0x1L
|
||||
|
@ -43,12 +43,12 @@ BEGIN
|
|||
BEGIN
|
||||
VALUE "CompanyName", "oscar64"
|
||||
VALUE "FileDescription", "oscar64 compiler"
|
||||
VALUE "FileVersion", "1.3.74.0"
|
||||
VALUE "FileVersion", "1.4.75.0"
|
||||
VALUE "InternalName", "oscar64.exe"
|
||||
VALUE "LegalCopyright", "Copyright (C) 2021"
|
||||
VALUE "OriginalFilename", "oscar64.exe"
|
||||
VALUE "ProductName", "oscar64"
|
||||
VALUE "ProductVersion", "1.3.74.0"
|
||||
VALUE "ProductVersion", "1.4.75.0"
|
||||
END
|
||||
END
|
||||
BLOCK "VarFileInfo"
|
||||
|
|
|
@ -94,6 +94,12 @@
|
|||
}
|
||||
"Entry"
|
||||
{
|
||||
"MsmKey" = "8:_1ED10FB93DDA4801BF72003E21B2CE55"
|
||||
"OwnerKey" = "8:_UNDEFINED"
|
||||
"MsmSig" = "8:_UNDEFINED"
|
||||
}
|
||||
"Entry"
|
||||
{
|
||||
"MsmKey" = "8:_1F88FA4F35F043B3ABFCB552FCEA5CDD"
|
||||
"OwnerKey" = "8:_UNDEFINED"
|
||||
"MsmSig" = "8:_UNDEFINED"
|
||||
|
@ -1087,6 +1093,26 @@
|
|||
"IsDependency" = "11:FALSE"
|
||||
"IsolateTo" = "8:"
|
||||
}
|
||||
"{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_1ED10FB93DDA4801BF72003E21B2CE55"
|
||||
{
|
||||
"SourcePath" = "8:..\\samples\\games\\missile.c"
|
||||
"TargetName" = "8:missile.c"
|
||||
"Tag" = "8:"
|
||||
"Folder" = "8:_BC04C0DDE264410096618981E4E890DA"
|
||||
"Condition" = "8:"
|
||||
"Transitive" = "11:FALSE"
|
||||
"Vital" = "11:TRUE"
|
||||
"ReadOnly" = "11:FALSE"
|
||||
"Hidden" = "11:FALSE"
|
||||
"System" = "11:FALSE"
|
||||
"Permanent" = "11:FALSE"
|
||||
"SharedLegacy" = "11:FALSE"
|
||||
"PackageAs" = "3:1"
|
||||
"Register" = "3:1"
|
||||
"Exclude" = "11:FALSE"
|
||||
"IsDependency" = "11:FALSE"
|
||||
"IsolateTo" = "8:"
|
||||
}
|
||||
"{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_1F88FA4F35F043B3ABFCB552FCEA5CDD"
|
||||
{
|
||||
"SourcePath" = "8:..\\include\\c64\\rasterirq.c"
|
||||
|
@ -3492,15 +3518,15 @@
|
|||
{
|
||||
"Name" = "8:Microsoft Visual Studio"
|
||||
"ProductName" = "8:oscar64"
|
||||
"ProductCode" = "8:{109FC925-4A6D-4868-A60D-42BF3DFE541B}"
|
||||
"PackageCode" = "8:{C6215A39-7DD0-4667-93FB-46373135B9C8}"
|
||||
"ProductCode" = "8:{1FF1624F-A9FD-402D-806B-6CE9925FB690}"
|
||||
"PackageCode" = "8:{47F7AA54-A5D7-4A82-8276-0DCD0FE332D4}"
|
||||
"UpgradeCode" = "8:{9AB61EFF-ACAC-4079-9950-8D96615CD4EF}"
|
||||
"AspNetVersion" = "8:2.0.50727.0"
|
||||
"RestartWWWService" = "11:FALSE"
|
||||
"RemovePreviousVersions" = "11:TRUE"
|
||||
"DetectNewerInstalledVersion" = "11:TRUE"
|
||||
"InstallAllUsers" = "11:FALSE"
|
||||
"ProductVersion" = "8:1.3.74"
|
||||
"ProductVersion" = "8:1.4.75"
|
||||
"Manufacturer" = "8:oscar64"
|
||||
"ARPHELPTELEPHONE" = "8:"
|
||||
"ARPHELPLINK" = "8:"
|
||||
|
|
|
@ -2,4 +2,5 @@
|
|||
../../bin/oscar64 snake.c
|
||||
../../bin/oscar64 lander.c -n
|
||||
../../bin/oscar64 maze3d.c -n
|
||||
../../bin/oscar64 missile.c -O3 -n
|
||||
|
||||
|
|
|
@ -223,15 +223,15 @@ void game_loop(void)
|
|||
case GS_PLAYING:
|
||||
{
|
||||
// Check player input on every frame
|
||||
joy_poll(1);
|
||||
lander_move(&TheGame.lander, joyx[1], joyy[1]);
|
||||
joy_poll(0);
|
||||
lander_move(&TheGame.lander, joyx[0], joyy[0]);
|
||||
LanderCollision col = lander_check(&TheGame.lander);
|
||||
if (col == LCOL_GROUND)
|
||||
game_state(GS_COLLIDE);
|
||||
else if (col == LCOL_PAD)
|
||||
game_state(GS_LANDED);
|
||||
else
|
||||
lander_show(&TheGame.lander, joyx[1], joyy[1]);
|
||||
lander_show(&TheGame.lander, joyx[0], joyy[0]);
|
||||
} break;
|
||||
case GS_LANDED:
|
||||
if (!--TheGame.count)
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
call ..\..\bin\oscar64 snake.c
|
||||
call ..\..\bin\oscar64 -n lander.c
|
||||
call ..\..\bin\oscar64 -n maze3d.c
|
||||
call ..\..\bin\oscar64 -n missile.c
|
||||
call ..\..\bin\oscar64 -n -O3 missile.c
|
||||
|
|
|
@ -419,19 +419,19 @@ int main(void)
|
|||
for(;;)
|
||||
{
|
||||
// Read joystick input
|
||||
joy_poll(1);
|
||||
joy_poll(0);
|
||||
|
||||
// Forward or backward motion
|
||||
if (joyy[1])
|
||||
if (joyy[0])
|
||||
{
|
||||
// Target square
|
||||
sbyte tx = px - dx * joyy[1];
|
||||
sbyte ty = py - dy * joyy[1];
|
||||
sbyte tx = px - dx * joyy[0];
|
||||
sbyte ty = py - dy * joyy[0];
|
||||
|
||||
// Check i empty
|
||||
if (maze[ty][tx] != '#')
|
||||
{
|
||||
if (joyy[1] < 0)
|
||||
if (joyy[0] < 0)
|
||||
{
|
||||
// Forward animation
|
||||
px = tx;
|
||||
|
@ -457,7 +457,7 @@ int main(void)
|
|||
// Check if new rotation
|
||||
if (!rotate)
|
||||
{
|
||||
if (joyx[1] == 1)
|
||||
if (joyx[0] == 1)
|
||||
{
|
||||
// Rotate right
|
||||
sbyte t = dx; dx = -dy; dy = t;
|
||||
|
@ -465,7 +465,7 @@ int main(void)
|
|||
maze_draw(zxdist0);
|
||||
screen_left();
|
||||
}
|
||||
else if (joyx[1] == -1)
|
||||
else if (joyx[0] == -1)
|
||||
{
|
||||
// Rotate left
|
||||
sbyte t = dx; dx = dy; dy = -t;
|
||||
|
@ -474,7 +474,7 @@ int main(void)
|
|||
screen_right();
|
||||
}
|
||||
}
|
||||
else if (!joyx[1])
|
||||
else if (!joyx[0])
|
||||
{
|
||||
// No rotation, may rotate again in next frame
|
||||
rotate = false;
|
||||
|
|
|
@ -3,114 +3,295 @@
|
|||
#include <c64/sprites.h>
|
||||
#include <c64/joystick.h>
|
||||
#include <c64/rasterirq.h>
|
||||
#include <c64/cia.h>
|
||||
#include <gfx/mcbitmap.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
// Make some room
|
||||
#pragma region(main, 0x0a00, 0xc800, , , {code, data, bss, heap, stack} )
|
||||
|
||||
// Sprite assets
|
||||
const char MissileSprites[] = {
|
||||
#embed "../resources/missilesprites.bin"
|
||||
};
|
||||
|
||||
// Charset assets
|
||||
const char MissileChars[] = {
|
||||
#embed "../resources/missilechars.bin"
|
||||
};
|
||||
|
||||
// Graphics areas in bank 3
|
||||
#define Color1 ((char *)0xc800)
|
||||
#define Color2 ((char *)0xd800)
|
||||
#define Hires ((char *)0xe000)
|
||||
#define Sprites ((char *)0xd000)
|
||||
#define Charset ((char *)0xd800)
|
||||
|
||||
// Joystick and crosshair control
|
||||
int CrossX = 160, CrossY = 100;
|
||||
bool CrossP = false;
|
||||
char CrossDelay = 0;
|
||||
|
||||
// Display bitmap
|
||||
Bitmap sbm;
|
||||
const ClipRect scr = { 0, 0, 320, 200 };
|
||||
|
||||
// Structure for a explosion
|
||||
struct Explosion
|
||||
{
|
||||
int x, y;
|
||||
char r;
|
||||
Explosion * next;
|
||||
int x, y; // Center of circle
|
||||
char r; // Radius of circle
|
||||
Explosion * next; // Next explosion in list
|
||||
};
|
||||
|
||||
// Structure for a missile (defensive and ICBM)
|
||||
struct Missile
|
||||
{
|
||||
int sx, sy, tx, ty, x, y, dx, dy;
|
||||
int d;
|
||||
char cnt;
|
||||
Missile * next;
|
||||
int sx, sy; // start position
|
||||
int tx, ty; // target position
|
||||
int x, y; // current position
|
||||
int dx, dy; // distance in x and y
|
||||
int d; // error term for Bresenham
|
||||
sbyte stepx; // direction in x (+1 or -1)
|
||||
sbyte cnt; // speed counter
|
||||
Missile * next; // next missile in list
|
||||
};
|
||||
|
||||
// Storage space for explosion
|
||||
Explosion explosions[16];
|
||||
// First free and first used explosion
|
||||
Explosion * efree, * eused;
|
||||
|
||||
// Storage space for defending missiles
|
||||
Missile missiles[8];
|
||||
// First free and first used missile
|
||||
Missile * mfree, * mused;
|
||||
// Number of missiles available
|
||||
char nmissiles;
|
||||
|
||||
// Storage space for ICMBs
|
||||
Missile icbms[16];
|
||||
// First free and first used ICBM
|
||||
Missile * ifree, * iused;
|
||||
// Speed and number of ICBMs still incomming
|
||||
char icbmspeed, icbmcount;
|
||||
|
||||
// Cities not yet destroyed
|
||||
bool cities[6];
|
||||
char ncities;
|
||||
|
||||
// Init status bar at top
|
||||
void status_init(void)
|
||||
{
|
||||
memset(Color1, ' ', 40);
|
||||
memset(Color2, 1, 40);
|
||||
|
||||
for(char i=0; i<8; i++)
|
||||
{
|
||||
Color1[i + 2] = '0';
|
||||
Color1[i + 12] = '0';
|
||||
Color2[i + 12] = 7;
|
||||
}
|
||||
}
|
||||
|
||||
// Expand an 8x8 charactor to 16x16 on screen
|
||||
void char_put(char cx, char cy, char c, char color)
|
||||
{
|
||||
// Get pointer to glyph data
|
||||
const char * sp = MissileChars + 8 * c;
|
||||
|
||||
// Loop over all pixel
|
||||
for(char y=0; y<8; y++)
|
||||
{
|
||||
char cl = sp[y];
|
||||
for(char x=0; x<8; x++)
|
||||
{
|
||||
// Draw two pixel if bit is set
|
||||
if (cl & 128)
|
||||
{
|
||||
bmmc_put(&sbm, cx + 2 * x, cy + 2 * y + 0, color);
|
||||
bmmc_put(&sbm, cx + 2 * x, cy + 2 * y + 1, color);
|
||||
}
|
||||
|
||||
// Next bit
|
||||
cl <<= 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Write a zero terminated string on screen
|
||||
void char_write(char cx, char cy, const char * s, char color)
|
||||
{
|
||||
// Loop over all characters
|
||||
while (*s)
|
||||
{
|
||||
char_put(cx, cy, *s, color);
|
||||
s++;
|
||||
cx += 16;
|
||||
}
|
||||
}
|
||||
|
||||
// Increment the score from a given digit on
|
||||
void score_inc(char digit, unsigned val)
|
||||
{
|
||||
// Lowest digit to increment
|
||||
char at = 9 - digit;
|
||||
|
||||
// Loop while there is still score to account for
|
||||
while (val)
|
||||
{
|
||||
// Increment one character
|
||||
char ch = Color1[at] + val % 10;
|
||||
|
||||
// Remove low digit from number
|
||||
val /= 10;
|
||||
|
||||
// Check overflow
|
||||
if (ch > '9')
|
||||
{
|
||||
ch -= 10;
|
||||
val++;
|
||||
}
|
||||
|
||||
Color1[at] = ch;
|
||||
|
||||
// Next higher character
|
||||
at --;
|
||||
}
|
||||
}
|
||||
|
||||
// Reset score and update high score
|
||||
void score_reset(void)
|
||||
{
|
||||
// Find first digit, where score and highscore differ
|
||||
char i = 0;
|
||||
while (i < 8 && Color1[i + 2] == Color1[i + 12])
|
||||
i++;
|
||||
|
||||
// Check if new score is higher
|
||||
if (i < 8 && Color1[i + 2] > Color1[i + 12])
|
||||
{
|
||||
// If so, copy to highscore
|
||||
while (i < 8)
|
||||
{
|
||||
Color1[i + 12] = Color1[i + 2];
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
// Clear score
|
||||
for(char i=0; i<8; i++)
|
||||
Color1[i + 2] = '0';
|
||||
}
|
||||
|
||||
// Update number of missiles
|
||||
void status_missiles(char num)
|
||||
{
|
||||
char n = 0;
|
||||
|
||||
// Draw full pairs
|
||||
while (2 * n + 1 < num)
|
||||
{
|
||||
Color1[25 + n] = 92;
|
||||
n++;
|
||||
}
|
||||
// Draw remaining single one
|
||||
if (num & 1)
|
||||
{
|
||||
Color1[25 + n] = 93;
|
||||
n++;
|
||||
}
|
||||
// Empty remainder
|
||||
while (n < 15)
|
||||
{
|
||||
Color1[25 + n] = 94;
|
||||
n++;
|
||||
}
|
||||
}
|
||||
|
||||
// Initialize explosion list
|
||||
void explosion_init(void)
|
||||
{
|
||||
// No explosion active
|
||||
eused = nullptr;
|
||||
|
||||
// First free explosion element
|
||||
efree = explosions;
|
||||
// Build list
|
||||
for(char i=0; i<15; i++)
|
||||
explosions[i].next = explosions + i + 1;
|
||||
// Terminate last element
|
||||
explosions[15].next = nullptr;
|
||||
}
|
||||
|
||||
// Start a new explosion
|
||||
void explosion_start(int x, int y)
|
||||
{
|
||||
// Free slot in list of explosions?
|
||||
if (efree)
|
||||
{
|
||||
// Move entry from free to used list
|
||||
Explosion * e = efree;
|
||||
efree = e->next;
|
||||
e->next = eused;
|
||||
eused = e;
|
||||
|
||||
// Initialize position and size
|
||||
e->r = 0;
|
||||
e->x = x;
|
||||
e->y = y;
|
||||
}
|
||||
}
|
||||
|
||||
// Animate all explosions
|
||||
void explosion_animate(void)
|
||||
{
|
||||
// Loop over active explosions with "e", use "ep" to point
|
||||
// to previous explosion, so we can remove the current explosion
|
||||
// from the list
|
||||
Explosion * e = eused, * ep = nullptr;
|
||||
while (e)
|
||||
{
|
||||
// Remember next entry in list
|
||||
Explosion * en = e->next;
|
||||
|
||||
// Increment phase (radius)
|
||||
e->r++;
|
||||
|
||||
// Advance every fourth frame
|
||||
if (!(e->r & 3))
|
||||
{
|
||||
// Draw or erase outer perimeter depending on growing or
|
||||
// shrinking explosion phase
|
||||
if (e->r <= 64)
|
||||
bmmc_circle(&sbm, &scr, e->x, e->y, e->r >> 2, 1);
|
||||
else
|
||||
bmmc_circle(&sbm, &scr, e->x, e->y, 33 - (e->r >> 2), 0);
|
||||
}
|
||||
|
||||
// End of explosion live
|
||||
if (e->r == 128)
|
||||
{
|
||||
// Remove explosion from used list
|
||||
if (ep)
|
||||
ep->next = e->next;
|
||||
else
|
||||
eused = e->next;
|
||||
|
||||
// Prepend it to free list
|
||||
e->next = efree;
|
||||
efree = e;
|
||||
}
|
||||
else
|
||||
ep = e;
|
||||
|
||||
// Next explosion in list
|
||||
e = en;
|
||||
}
|
||||
}
|
||||
|
||||
// Initialize defending missile list
|
||||
void missile_init(void)
|
||||
{
|
||||
mused = nullptr;
|
||||
|
@ -120,31 +301,47 @@ void missile_init(void)
|
|||
missiles[7].next = nullptr;
|
||||
}
|
||||
|
||||
// Add a new defending missile
|
||||
void missile_start(int sx, int sy, int tx, int ty)
|
||||
{
|
||||
if (mfree)
|
||||
// Check if entry in free list and missile in silo remaining
|
||||
if (mfree && nmissiles > 0)
|
||||
{
|
||||
// Detach from free list
|
||||
Missile * m = mfree;
|
||||
mfree = m->next;
|
||||
|
||||
// Attach to active list
|
||||
m->next = mused;
|
||||
mused = m;
|
||||
|
||||
// Initialize start and target coordinates
|
||||
m->sx = sx >> 1; m->x = sx >> 1;
|
||||
m->sy = sy; m->y = sy;
|
||||
m->tx = tx >> 1;
|
||||
m->ty = ty;
|
||||
|
||||
// Initialize line drawing parameters
|
||||
m->dy = m->sy - m->ty;
|
||||
m->dx = m->tx - m->sx;
|
||||
m->stepx = 1;
|
||||
if (m->dx < 0)
|
||||
{
|
||||
m->dx = -m->dx;
|
||||
m->stepx = -1;
|
||||
}
|
||||
|
||||
m->d = m->dy - m->dx;
|
||||
m->dx *= 2;
|
||||
m->dy *= 2;
|
||||
|
||||
// Remove missile from silo
|
||||
nmissiles--;
|
||||
status_missiles(nmissiles);
|
||||
}
|
||||
}
|
||||
|
||||
// Animate all active missiles
|
||||
void missile_animate(void)
|
||||
{
|
||||
Missile * m = mused, * mp = nullptr;
|
||||
|
@ -152,6 +349,7 @@ void missile_animate(void)
|
|||
{
|
||||
Missile * mn = m->next;
|
||||
|
||||
// Advance missile position using one step of Bresenham
|
||||
if (m->d >= 0)
|
||||
{
|
||||
m->y--;
|
||||
|
@ -159,18 +357,18 @@ void missile_animate(void)
|
|||
}
|
||||
if (m->d < 0)
|
||||
{
|
||||
if (m->tx < m->sx)
|
||||
m->x--;
|
||||
else
|
||||
m->x++;
|
||||
m->x += m->stepx;
|
||||
m->d += m->dy;
|
||||
}
|
||||
|
||||
if (bmmc_get(&sbm, m->x, m->y) == 1 || m->y == m->ty)
|
||||
// Check if target reached
|
||||
if (m->y == m->ty)
|
||||
{
|
||||
// If so, clear line and start explosion
|
||||
bmmcu_line(&sbm, m->sx * 2, m->sy, m->tx * 2, m->ty, 0);
|
||||
explosion_start(m->x * 2, m->y);
|
||||
|
||||
// Remove from active list
|
||||
if (mp)
|
||||
mp->next = m->next;
|
||||
else
|
||||
|
@ -180,6 +378,7 @@ void missile_animate(void)
|
|||
}
|
||||
else
|
||||
{
|
||||
// Draw new pixel in missile trace
|
||||
bmmc_put(&sbm, m->x * 2, m->y, 3);
|
||||
mp = m;
|
||||
}
|
||||
|
@ -188,6 +387,7 @@ void missile_animate(void)
|
|||
}
|
||||
}
|
||||
|
||||
// Initialize incomming ICBM list
|
||||
void icbm_init(void)
|
||||
{
|
||||
iused = nullptr;
|
||||
|
@ -197,9 +397,10 @@ void icbm_init(void)
|
|||
icbms[15].next = nullptr;
|
||||
}
|
||||
|
||||
// Add a new ICBM to the attacking set
|
||||
void icbm_start(int sx, int sy, int tx, int ty)
|
||||
{
|
||||
if (ifree)
|
||||
if (icbmcount && ifree)
|
||||
{
|
||||
Missile * m = ifree;
|
||||
ifree = m->next;
|
||||
|
@ -210,16 +411,22 @@ void icbm_start(int sx, int sy, int tx, int ty)
|
|||
m->sy = sy; m->y = sy;
|
||||
m->tx = tx >> 1;
|
||||
m->ty = ty;
|
||||
m->cnt = 4;
|
||||
m->cnt = 0;
|
||||
|
||||
m->dy = m->ty - m->sy;
|
||||
m->dx = m->tx - m->sx;
|
||||
m->stepx = 1;
|
||||
if (m->dx < 0)
|
||||
{
|
||||
m->dx = -m->dx;
|
||||
m->stepx = -1;
|
||||
}
|
||||
|
||||
m->d = m->dy - m->dx;
|
||||
m->dx *= 2;
|
||||
m->dy *= 2;
|
||||
|
||||
icbmcount--;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -230,14 +437,16 @@ void icbm_animate(void)
|
|||
{
|
||||
Missile * mn = m->next;
|
||||
|
||||
m->cnt--;
|
||||
|
||||
if (!m->cnt)
|
||||
// Check speed of ICBMs
|
||||
m->cnt += icbmspeed;
|
||||
while (m->cnt > 0)
|
||||
{
|
||||
m->cnt -= 32;
|
||||
|
||||
// Draw pixel in trace
|
||||
bmmc_put(&sbm, m->x * 2, m->y, 2);
|
||||
|
||||
m->cnt = 4;
|
||||
|
||||
// Advance using Bresenham
|
||||
if (m->d >= 0)
|
||||
{
|
||||
m->y++;
|
||||
|
@ -245,80 +454,126 @@ void icbm_animate(void)
|
|||
}
|
||||
if (m->d < 0)
|
||||
{
|
||||
if (m->tx < m->sx)
|
||||
m->x--;
|
||||
else
|
||||
m->x++;
|
||||
m->x += m->stepx;
|
||||
m->d += m->dy;
|
||||
}
|
||||
|
||||
// Check if colliding with cloud or target reached
|
||||
if (bmmc_get(&sbm, m->x * 2, m->y) == 1 || m->y == m->ty)
|
||||
{
|
||||
// If so, clear trace and start explosion
|
||||
bmmcu_line(&sbm, m->sx * 2, m->sy, m->tx * 2, m->ty, 0);
|
||||
explosion_start(m->x * 2, m->y);
|
||||
|
||||
// Check if we hit the ground
|
||||
if (m->y == m->ty)
|
||||
{
|
||||
// If so, find matching city
|
||||
int x = m->x * 2;
|
||||
char ix;
|
||||
if (x > 160)
|
||||
ix = (x - 202) / 32 + 3;
|
||||
ix = ((x - 202) >> 5) + 3;
|
||||
else
|
||||
ix = (x - 58) / 32;
|
||||
ix = (x - 58) >> 5;
|
||||
|
||||
// Destroy, destroy, annihilate, kill, kill
|
||||
if (cities[ix])
|
||||
{
|
||||
ncities--;
|
||||
cities[ix] = false;
|
||||
spr_show(ix + 1, false);
|
||||
}
|
||||
}
|
||||
|
||||
// Add score for destroyed ICBM
|
||||
score_inc(0, 25);
|
||||
|
||||
// Remove from list
|
||||
if (mp)
|
||||
mp->next = m->next;
|
||||
else
|
||||
iused = m->next;
|
||||
m->next = ifree;
|
||||
ifree = m;
|
||||
m = nullptr;
|
||||
|
||||
// End loop early
|
||||
break;
|
||||
}
|
||||
else
|
||||
}
|
||||
|
||||
// If ICBM still in flight
|
||||
if (m)
|
||||
{
|
||||
// Remember for list management
|
||||
mp = m;
|
||||
// Draw white head
|
||||
bmmc_put(&sbm, m->x * 2, m->y, 1);
|
||||
mp = m;
|
||||
}
|
||||
}
|
||||
else
|
||||
mp = m;
|
||||
|
||||
m = mn;
|
||||
}
|
||||
}
|
||||
|
||||
void mountains_init(void)
|
||||
// Initialize game screen
|
||||
void screen_init(void)
|
||||
{
|
||||
// Clean up
|
||||
bmmcu_rect_fill(&sbm, 0, 8, 320, 184, 0);
|
||||
|
||||
// Draw bottom
|
||||
bmmcu_rect_fill(&sbm, 0, 192, 320, 8, 3);
|
||||
bmmc_quad_fill(&sbm, &scr, 0, 192, 16, 184, 32, 184, 48, 192, MixedColors[3][3]);
|
||||
bmmc_quad_fill(&sbm, &scr, 136, 192, 152, 184, 176, 184, 192, 192, MixedColors[3][3]);
|
||||
bmmc_quad_fill(&sbm, &scr, 272, 192, 288, 184, 304, 184, 320, 192, MixedColors[3][3]);
|
||||
|
||||
// Show cities
|
||||
for(char i=0; i<3; i++)
|
||||
{
|
||||
if (cities[i + 0])
|
||||
spr_set(i + 1, true, 70 + 32 * i, 222, 65, 15, false, false, false);
|
||||
if (cities[i + 3])
|
||||
spr_set(i + 4, true, 214 + 32 * i, 222, 65, 15, false, false, false);
|
||||
}
|
||||
}
|
||||
|
||||
// Clear inner area of screen
|
||||
void screen_clear(void)
|
||||
{
|
||||
bmmcu_rect_fill(&sbm, 0, 8, 320, 176, 0);
|
||||
}
|
||||
|
||||
// Interrupt routine for joystick control, called by raster IRQ at bottom
|
||||
// of screen
|
||||
|
||||
__interrupt void joy_interrupt()
|
||||
{
|
||||
joy_poll(1);
|
||||
// Poll joystick
|
||||
joy_poll(0);
|
||||
|
||||
CrossX += joyx[1]; CrossY += joyy[1];
|
||||
// Move crosshair coordinates
|
||||
CrossX += 2 * joyx[0]; CrossY += 2 * joyy[0];
|
||||
|
||||
// Stop at edges of screen
|
||||
if (CrossX < 8)
|
||||
CrossX = 8;
|
||||
else if (CrossX > 312)
|
||||
CrossX = 312;
|
||||
if (CrossY < 16)
|
||||
CrossY = 16;
|
||||
if (CrossY < 20)
|
||||
CrossY = 20;
|
||||
else if (CrossY > 172)
|
||||
CrossY = 172;
|
||||
|
||||
// Move crosshair sprite
|
||||
spr_move(0, CrossX + 14, CrossY + 40);
|
||||
|
||||
if (joyb[1])
|
||||
// Check button
|
||||
if (joyb[0])
|
||||
{
|
||||
// Avoid quickfire and bouncing
|
||||
if (CrossDelay == 0)
|
||||
{
|
||||
// Request fire from non interrupt code
|
||||
CrossP = true;
|
||||
CrossDelay = 4;
|
||||
}
|
||||
|
@ -327,88 +582,137 @@ __interrupt void joy_interrupt()
|
|||
CrossDelay--;
|
||||
}
|
||||
|
||||
RIRQCode bottom, top;
|
||||
|
||||
int main(void)
|
||||
enum GameState
|
||||
{
|
||||
mmap_trampoline();
|
||||
GS_READY, // Getting ready
|
||||
GS_LEVEL, // Show level message
|
||||
GS_PLAYING, // Playing the game
|
||||
GS_BONUS, // Landed on pad
|
||||
GS_ARMAGEDDON, // Show end game animation
|
||||
GS_END // Wait for restart
|
||||
};
|
||||
|
||||
mmap_set(MMAP_RAM);
|
||||
memcpy(Sprites, MissileSprites, 1024);
|
||||
memcpy(Charset, MissileChars, 2048);
|
||||
mmap_set(MMAP_NO_ROM);
|
||||
// State of the game
|
||||
struct Game
|
||||
{
|
||||
GameState state;
|
||||
byte count, level;
|
||||
|
||||
vic_setmode(VICM_HIRES_MC, Color1, Hires);
|
||||
spr_init(Color1);
|
||||
} TheGame; // Only one game, so global variable
|
||||
|
||||
// initialize raster IRQ
|
||||
rirq_init(true);
|
||||
// Character buffer for some texts
|
||||
char cbuffer[10];
|
||||
|
||||
vic.color_back = VCOL_BLACK;
|
||||
vic.color_border = VCOL_BLACK;
|
||||
void game_state(GameState state)
|
||||
{
|
||||
|
||||
memset(Color1, 0x18, 1000);
|
||||
memset(Color2, 0x06, 1000);
|
||||
memset(Hires, 0, 8000);
|
||||
memset(Color2 + 40 * 23, 0x07, 80);
|
||||
TheGame.state = state;
|
||||
|
||||
bm_init(&sbm, Hires, 40, 25);
|
||||
switch(state)
|
||||
{
|
||||
case GS_READY:
|
||||
// Start of new game
|
||||
score_reset();
|
||||
screen_init();
|
||||
char_write(40, 100, s"READY PLAYER 1", 3);
|
||||
|
||||
// New cities
|
||||
for(char i=0; i<6; i++)
|
||||
cities[i] = true;
|
||||
ncities = 6;
|
||||
TheGame.count = 60;
|
||||
|
||||
// Starting at level 1
|
||||
TheGame.level = 0;
|
||||
break;
|
||||
|
||||
case GS_LEVEL:
|
||||
// Advance to next level
|
||||
TheGame.level++;
|
||||
utoa(TheGame.level ,cbuffer, 10);
|
||||
screen_clear();
|
||||
char_write(96, 100, s"LEVEL", 3);
|
||||
char_write(96 + 16 * 6, 100, cbuffer, 3);
|
||||
TheGame.count = 30;
|
||||
break;
|
||||
|
||||
case GS_PLAYING:
|
||||
// Avoid old fire request
|
||||
CrossP = false;
|
||||
|
||||
// Setup display
|
||||
screen_init();
|
||||
missile_init();
|
||||
explosion_init();
|
||||
icbm_init();
|
||||
mountains_init();
|
||||
|
||||
spr_set(0, true, CrossX + 14, CrossY + 40, 64, 1, false, false, false);
|
||||
// A new set of 30 missiles
|
||||
nmissiles = 30;
|
||||
status_missiles(nmissiles);
|
||||
|
||||
for(char i=0; i<3; i++)
|
||||
// Game parameters based on level
|
||||
if (TheGame.level < 112)
|
||||
icbmspeed = 8 + TheGame.level;
|
||||
else
|
||||
icbmspeed = 120;
|
||||
|
||||
if (TheGame.level < 50)
|
||||
icbmcount = 5 + TheGame.level / 2;
|
||||
else
|
||||
icbmcount = 30;
|
||||
|
||||
TheGame.count = 15;
|
||||
break;
|
||||
|
||||
case GS_BONUS:
|
||||
{
|
||||
spr_set(i + 1, true, 70 + 32 * i, 222, 65, 15, false, false, false);
|
||||
spr_set(i + 4, true, 214 + 32 * i, 222, 65, 15, false, false, false);
|
||||
// Show bonus
|
||||
|
||||
cities[i + 0] = true;
|
||||
cities[i + 3] = true;
|
||||
unsigned bonus = ncities * 50 + nmissiles * 5;
|
||||
utoa(bonus, cbuffer, 10);
|
||||
|
||||
char_write(96, 100, s"BONUS", 3);
|
||||
char_write(96 + 16 * 6, 100, cbuffer, 3);
|
||||
|
||||
score_inc(0, bonus);
|
||||
TheGame.count = 30;
|
||||
} break;
|
||||
|
||||
case GS_ARMAGEDDON:
|
||||
TheGame.count = 0;
|
||||
break;
|
||||
|
||||
case GS_END:
|
||||
char_write(104, 92, s"THE END", 0);
|
||||
TheGame.count = 120;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Build the switch to normal IRQ
|
||||
rirq_build(&top, 3);
|
||||
// Change color for ceiling
|
||||
rirq_delay(&top, 10);
|
||||
rirq_write(&top, 1, &vic.ctrl1, VIC_CTRL1_BMM | VIC_CTRL1_DEN | VIC_CTRL1_RSEL | 3);
|
||||
rirq_write(&top, 2, &vic.memptr, 0x28);
|
||||
// place this at the bottom
|
||||
rirq_set(0, 57, &top);
|
||||
|
||||
// Build the switch to normal IRQ
|
||||
rirq_build(&bottom, 3);
|
||||
rirq_write(&bottom, 0, &vic.memptr, 0x27);
|
||||
rirq_write(&bottom, 1, &vic.ctrl1, VIC_CTRL1_DEN | VIC_CTRL1_RSEL | 3);
|
||||
// Change color for ceiling
|
||||
rirq_call(&bottom, 2, joy_interrupt);
|
||||
// place this at the bottom
|
||||
rirq_set(1, 250, &bottom);
|
||||
|
||||
// sort the raster IRQs
|
||||
rirq_sort();
|
||||
|
||||
// start raster IRQ processing
|
||||
rirq_start();
|
||||
|
||||
bool launched = false;
|
||||
for(;;)
|
||||
// Main game play code
|
||||
void game_play(void)
|
||||
{
|
||||
// Check if fire request
|
||||
if (CrossP)
|
||||
{
|
||||
// Find lauch site
|
||||
int sx = 160;
|
||||
if (CrossX < 120)
|
||||
sx = 24;
|
||||
else if (CrossX > 200)
|
||||
sx = 296
|
||||
|
||||
// Fire missile
|
||||
missile_start(sx, 184, CrossX, CrossY);
|
||||
|
||||
// Reset request
|
||||
CrossP = false;
|
||||
}
|
||||
|
||||
if (!(rand() & 63))
|
||||
// Wait for next ICMB to enter the game
|
||||
if (!--TheGame.count)
|
||||
{
|
||||
// Pick target city
|
||||
char ci;
|
||||
do {
|
||||
ci = rand() & 7;
|
||||
|
@ -420,15 +724,139 @@ int main(void)
|
|||
else
|
||||
cx = 202 + 32 * (ci - 3);
|
||||
|
||||
// Launch ICBM
|
||||
icbm_start((rand() & 0xff) + 32, 0, cx, 184);
|
||||
|
||||
// Next lauch time
|
||||
TheGame.count = 8 + (rand() & 63);
|
||||
}
|
||||
|
||||
// Advance defending missiles by four pixels
|
||||
for(char i=0; i<4; i++)
|
||||
missile_animate();
|
||||
icbm_animate();
|
||||
explosion_animate();
|
||||
|
||||
vic_waitFrame();
|
||||
// Advance ICBMs
|
||||
icbm_animate();
|
||||
|
||||
// Show explosions
|
||||
explosion_animate();
|
||||
}
|
||||
|
||||
// Main game loop, entered every VSYNC, slower if too busy with explosions
|
||||
void game_loop(void)
|
||||
{
|
||||
switch(TheGame.state)
|
||||
{
|
||||
case GS_READY:
|
||||
if (!--TheGame.count)
|
||||
game_state(GS_LEVEL);
|
||||
break;
|
||||
case GS_LEVEL:
|
||||
if (!--TheGame.count)
|
||||
game_state(GS_PLAYING);
|
||||
break;
|
||||
|
||||
case GS_PLAYING:
|
||||
game_play();
|
||||
|
||||
// Check for level and game end coditions
|
||||
if (!icbmcount && !iused && !eused)
|
||||
game_state(GS_BONUS);
|
||||
else if (ncities == 0)
|
||||
game_state(GS_ARMAGEDDON);
|
||||
break;
|
||||
|
||||
case GS_BONUS:
|
||||
if (!--TheGame.count)
|
||||
game_state(GS_LEVEL);
|
||||
break;
|
||||
|
||||
case GS_ARMAGEDDON:
|
||||
// Draw end game animation
|
||||
TheGame.count++;
|
||||
bmmc_circle(&sbm, &scr, 160, 100, TheGame.count, 1);
|
||||
explosion_animate();
|
||||
if (TheGame.count == 90)
|
||||
game_state(GS_END);
|
||||
break;
|
||||
|
||||
case GS_END:
|
||||
if (!--TheGame.count)
|
||||
game_state(GS_READY);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Interrupts for status line and joystick routine
|
||||
RIRQCode bottom, top;
|
||||
|
||||
int main(void)
|
||||
{
|
||||
// Activate trampoline
|
||||
mmap_trampoline();
|
||||
|
||||
// Disable CIA interrupts, we do not want interference
|
||||
// with our joystick interrupt
|
||||
cia_init();
|
||||
|
||||
// Copy assets
|
||||
mmap_set(MMAP_RAM);
|
||||
memcpy(Sprites, MissileSprites, 1024);
|
||||
memcpy(Charset, MissileChars, 2048);
|
||||
mmap_set(MMAP_NO_ROM);
|
||||
|
||||
// Clean out screen space
|
||||
memset(Color1, 0x18, 1000);
|
||||
memset(Color2, 0x06, 1000);
|
||||
memset(Hires, 0, 8000);
|
||||
memset(Color2 + 40 * 23, 0x07, 80);
|
||||
|
||||
// initialize raster IRQ
|
||||
rirq_init(true);
|
||||
|
||||
// Switch to hires mode
|
||||
vic_setmode(VICM_HIRES_MC, Color1, Hires);
|
||||
spr_init(Color1);
|
||||
|
||||
// Black background and border
|
||||
vic.color_back = VCOL_BLACK;
|
||||
vic.color_border = VCOL_BLACK;
|
||||
|
||||
// Init bitmap
|
||||
bm_init(&sbm, Hires, 40, 25);
|
||||
|
||||
// Init status line
|
||||
status_init();
|
||||
|
||||
// Init cross hair sprite
|
||||
spr_set(0, true, CrossX + 14, CrossY + 40, 64, 1, false, false, false);
|
||||
|
||||
// Build to multicolor highres at top of screen
|
||||
rirq_build(&top, 3);
|
||||
rirq_delay(&top, 10);
|
||||
rirq_write(&top, 1, &vic.ctrl1, VIC_CTRL1_BMM | VIC_CTRL1_DEN | VIC_CTRL1_RSEL | 3);
|
||||
rirq_write(&top, 2, &vic.memptr, 0x28);
|
||||
rirq_set(0, 57, &top);
|
||||
|
||||
// Switch to text mode for status line and poll joystick at bottom
|
||||
rirq_build(&bottom, 3);
|
||||
rirq_write(&bottom, 0, &vic.memptr, 0x27);
|
||||
rirq_write(&bottom, 1, &vic.ctrl1, VIC_CTRL1_DEN | VIC_CTRL1_RSEL | 3);
|
||||
rirq_call(&bottom, 2, joy_interrupt);
|
||||
rirq_set(1, 250, &bottom);
|
||||
|
||||
// sort the raster IRQs
|
||||
rirq_sort();
|
||||
|
||||
// start raster IRQ processing
|
||||
rirq_start();
|
||||
|
||||
// start game state machine
|
||||
game_state(GS_READY);
|
||||
for(;;)
|
||||
{
|
||||
game_loop();
|
||||
rirq_wait();
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
|
|
@ -233,8 +233,8 @@ void game_loop(void)
|
|||
break;
|
||||
case GS_PLAYING:
|
||||
// Check player input on every frame
|
||||
joy_poll(1);
|
||||
snake_control(&TheGame.snake, joyx[1], joyy[1]);
|
||||
joy_poll(0);
|
||||
snake_control(&TheGame.snake, joyx[0], joyy[0]);
|
||||
|
||||
if (!--TheGame.count)
|
||||
{
|
||||
|
|
Binary file not shown.
|
@ -388,8 +388,8 @@ int main(void)
|
|||
for(;;)
|
||||
{
|
||||
// Check the joystick
|
||||
joy_poll(1);
|
||||
if (joyx[1] == 1)
|
||||
joy_poll(0);
|
||||
if (joyx[0] == 1)
|
||||
{
|
||||
// Move to the right
|
||||
if (gridX < 24)
|
||||
|
@ -399,7 +399,7 @@ int main(void)
|
|||
scroll_left();
|
||||
}
|
||||
}
|
||||
else if (joyx[1] == -1)
|
||||
else if (joyx[0] == -1)
|
||||
{
|
||||
// Move to the left
|
||||
if (gridX > 0)
|
||||
|
@ -409,7 +409,7 @@ int main(void)
|
|||
scroll_right();
|
||||
}
|
||||
}
|
||||
else if (joyy[1] == 1)
|
||||
else if (joyy[0] == 1)
|
||||
{
|
||||
// Move down
|
||||
if (gridY < 39)
|
||||
|
@ -419,7 +419,7 @@ int main(void)
|
|||
scroll_up();
|
||||
}
|
||||
}
|
||||
else if (joyy[1] == -1)
|
||||
else if (joyy[0] == -1)
|
||||
{
|
||||
// Move up
|
||||
if (gridY > 0)
|
||||
|
|
|
@ -33,11 +33,11 @@ int main(void)
|
|||
for(;;)
|
||||
{
|
||||
// Poll joytick
|
||||
joy_poll(1);
|
||||
joy_poll(0);
|
||||
|
||||
// Change position according to joystick
|
||||
spx += joyx[1];
|
||||
spy += joyy[1];
|
||||
spx += joyx[0];
|
||||
spy += joyy[0];
|
||||
|
||||
// Move sprites on screen
|
||||
spr_move(0, spx, spy);
|
||||
|
|
Loading…
Reference in New Issue