This page (revision-8) was last changed on 03-Feb-2023 15:21 by Stefan Haubenthal 

This page was created on 13-Mar-2010 18:13 by Carsten Strotmann

Only authorized users are allowed to rename pages.

Only authorized users are allowed to delete pages.

Page revision history

Version Date Modified Size Author Changes ... Change note
8 03-Feb-2023 15:21 93 KB Stefan Haubenthal to previous
7 14-Dec-2020 13:02 93 KB Carsten Strotmann to previous | to last
6 14-Dec-2020 12:48 87 KB Carsten Strotmann to previous | to last
5 13-Mar-2010 18:35 66 KB Carsten Strotmann to previous | to last
4 13-Mar-2010 18:35 66 KB Carsten Strotmann to previous | to last
3 13-Mar-2010 18:33 66 KB Carsten Strotmann to previous | to last
2 13-Mar-2010 18:33 66 KB Carsten Strotmann to previous | to last
1 13-Mar-2010 18:13 66 KB Carsten Strotmann to last

Page References

Incoming links Outgoing links

Version management

Difference between version and

At line 10 added 4 lines
Download: [Greed/agreed2.atr]
Title Tune: [Greed/greed.mp3] [Greed/greed.mid.mov]
At line 17 added 2 lines
[{Image src='agreed1.jpeg' width='..' height='..' align='left|center|right' style='..' class='..' }]
[{Image src='agreed2.jpeg' width='..' height='..' align='left|center|right' style='..' class='..' }]
At line 14 removed 4 lines
{image:agreed1.jpeg}
{image:agreed2.jpeg}
At line 1,479 changed one line
* ATARI Greed
* ATARI Greed
At line 1,481 changed one line
* based on greed for Unix,
* based on greed for Unix,
At line 1,483 removed 2 lines
*
*
At line 1,487 added 2 lines
*
*
At line 1,488 changed one line
* Module :
* Module :
At line 1,497 changed one line
* Description A version of the game "greed" for the cc65 6502 C-Compiler,
* Description A version of the game "greed" for the cc65 6502 C-Compiler,
At line 1,528 changed one line
#define LEVELFILESIZE 130
#define LEVELFILESIZE 130
At line 1,548 changed one line
0x70, 0x00, // 9 Scanlines
0x70, 0x00, // 9 Scanlines
At line 1,553 changed one line
0x0f, 0x0f, 0x0f, 0x0f,
0x0f, 0x0f, 0x0f, 0x0f,
At line 1,555 changed one line
0x0f, 0x0f, 0x0f, 0x0f,
0x0f, 0x0f, 0x0f, 0x0f,
At line 1,557 changed one line
0x0f, 0x0f, 0x0f, 0x0f,
0x0f, 0x0f, 0x0f, 0x0f,
At line 1,559 changed one line
0x0f, 0x0f, 0x0f, 0x0f,
0x0f, 0x0f, 0x0f, 0x0f,
At line 1,561 changed one line
0x0f, 0x0f, 0x0f, 0x0f,
0x0f, 0x0f, 0x0f, 0x0f,
At line 1,563 changed one line
0x0f, 0x0f, 0x0f, 0x0f,
0x0f, 0x0f, 0x0f, 0x0f,
At line 1,565 changed one line
0x0f, 0x0f, 0x0f, 0x0f,
0x0f, 0x0f, 0x0f, 0x0f,
At line 1,567 changed one line
0x0f, 0x0f, 0x0f, 0x0f,
0x0f, 0x0f, 0x0f, 0x0f,
At line 1,569 changed one line
0x0f, 0x0f, 0x0f, 0x0f,
0x0f, 0x0f, 0x0f, 0x0f,
At line 1,572 changed one line
0x0f, // 1 Gr.8 Lines, Playfield row 11
0x0f, 0x0f, 0x0f, 0x0f,
0x0f, 0x0f, 0x0f, 0x0f, // 8 Gr.8 Lines, Playfield row 12
0x0f, 0x0f, 0x0f, 0x0f,
0x0f, 0x0f, 0x0f, 0x0f, // 8 Gr.8 Lines, Playfield row 13
0x0f, 0x0f, 0x0f, 0x0f,
0x0f, 0x0f, 0x0f, 0x0f, // 8 Gr.8 Lines, Playfield row 14
0x0f, 0x0f, 0x0f, 0x0f,
0x0f, 0x0f, 0x0f, 0x0f, // 8 Gr.8 Lines, Playfield row 15
0x0f, 0x0f, 0x0f, 0x0f,
0x0f, 0x0f, 0x0f, 0x0f, // 8 Gr.8 Lines, Playfield row 16
0x0f, 0x0f, 0x0f, 0x0f,
0x0f, 0x0f, 0x0f, 0x0f, // 8 Gr.8 Lines, Playfield row 17
0x0f, 0x0f, 0x0f, 0x8f,
0x0f, 0x0f, 0x0f, 0x0f, // 8 Gr.8 Lines, Playfield row 18
0x70, // 8 Scanlines
0x00, // 1 Scanline (empty)
0x0f, 0x0f, 0x0f, 0x0f,
0x0f, 0x0f, 0x0f, // 7 Gr.8 Lines, MENULINE 6x5 font
0x70, 0x20, // 11 Scanlines
0x80, // 1 Scanline with DLI (fade)
0x0f, 0x0f, 0x0f, 0x0f,
0x0f, 0x0f, 0x0f, 0x0f,
0x0f, 0x0f, 0x0f, 0x0f,
0x8f, 0x0f, 0x0f, 0x0f, // 14 Gr.8 Lines, Menu 7x14 font
0x00, // 1 Scanline
0x70, // 8 Scanlines
0x41, 0x00, 0x28 // Jump to start
};
static char highscorefile[]= "D:AGREED.HIG";
static char continuemsg[] = "press key to continue...";
static char helpmsg[] = "Hit '?' for help";
static char fourdigitform[] = " %04d ";
static char levelbuf[130];
At line 1,609 added 1,091 lines
static int allmoves = 0;
static int score = 0;
static int levelscore;;
static int highscore = 0;
static unsigned int maxvalue;
static char level = 0, oldlevel = 0;
static char grid[MAXY][MAXX];
static int x,y;
static char havebotmsg = 0;
static char soundflg = 0;
static char exitflg = 0;
static int oldtime, maxtime;
static char scorelist[SCOREFILESIZE];
char* getscorename(char pos)
{
return (&scorelist[pos * (SCORENAME + 1 + sizeof(int))]);
}
int getscorevalue(char pos)
{
char* p;
p = getscorename(pos) + 9;
return (*(p) + ((unsigned) (p)[1] << 8));
}
/* ATARI specific stuff */
void waitvbi(void) // sync with vertical blank interrupt
{
while (!*(char*) 0xD40B)
continue;
}
void enable_os(void)
{
if (*(char*) 0x2A00 == 0x4c) // OS Switch Routine loaded??
{
__asm__( "jsr $2a00" );
}
}
void disable_os(void)
{
if (*(char*) 0x2A00 == 0x4c) // OS Switch Routine loaded??
{
__asm__( "jsr $2a04" );
}
}
void startmusic(void)
{
if (*(char*) 0x8A00 == 0x68) // sound loaded??
{
__asm__( "jsr $8A01" );
}
soundflg = 1;
}
void stopmusic(void)
{
if (*(char*) 0x8A00 == 0x68) // sound loaded??
{
__asm__( "jsr $8A08" );
}
soundflg = 0;
}
static char Asc2Int(unsigned char c)
{
unsigned char x;
x = c & 0x7f;
if (x < 0x20 && x >= 1) c += 0x40;
else if (x > 0x1f && x < 0x60) c -= 0x20;
return c;
}
void clearblock(x, y, xl, yl)
char x;
char y;
char xl;
char xl;
{
char yy;
unsigned char *mptr;
mptr = (char*) ((*(unsigned int*)0x58) + (40 * y) + x);
for (yy = 0; yy < yl; yy++)
{
memset(mptr, 0, xl);
mptr += 40;
}
}
void saveblock(x, y, xl, yl)
char x;
char y;
char xl;
char xl;
{
unsigned char *mptr, *dptr;
mptr = (char*) ((*(unsigned int*)0x58) + (40 * y) + x);
dptr = (char*) SAVEBASE;
disable_os();
for (y = 0; y < yl; y++)
{
memcpy(dptr, mptr, xl);
mptr += 40;
dptr += xl;
}
enable_os();
}
void restoreblock(x, y, xl, yl)
char x;
char y;
char xl;
char xl;
{
unsigned char *mptr, *dptr;
mptr = (char*) ((*(unsigned int*)0x58) + (40 * y) + x);
dptr = (char*) SAVEBASE;
disable_os();
for (y = 0; y < yl; y++)
{
for (y = 0; y < yl; y++)
{
memcpy(mptr, dptr, xl);
mptr += 40;
dptr += xl;
}
}
enable_os();
}
void invertblock(x, y, xl, yl)
char x;
char y;
char xl;
char xl;
{
unsigned char *mptr;
mptr = (char*) ((*(unsigned int*)0x58) + (40 * y) + x);
for (y = 0; y < yl; y++)
{
for (x = 0; x < xl; x++)
{
*mptr ^= 0xFF;
mptr++;
}
mptr += (40 - xl);
}
}
static void gputcxyvar(int x, int y, unsigned char c, unsigned char* chptr, char maxlines )
{
unsigned char *mptr;
int ch;
int inv;
inv = (0xff * (c > 0x7f));
c = c & 0x7f;
mptr = (char*) ((*(unsigned int*)0x58) + y * 40 + x);
for (ch = 0; ch < maxlines; ch++)
{
mptr += 40;
chptr++;
*mptr = (*chptr ^ inv);
}
}
static void gputcxy7(int x, int y, unsigned char c)
{
gputcxyvar(x,y,c, (char*) (&fnt7 + c * 7), 6);
}
static void gputcxy14(int x, int y, unsigned char c)
{
gputcxyvar(x,y,c, (char*) (&fnt14 + c * 14), 13);
}
void gprintxy14 (int x, int y, char* str)
{
while (*str != '\0')
{
gputcxy14(x++,y,*str++);
}
}
void gprintxy7 (int x, int y, char* str)
{
while (*str != '\0')
{
gputcxy7(x++,y,*str++);
}
}
static void gputcxy(int x, int y, unsigned char c)
{
unsigned char *chptr, *mptr, *sptr;
char ch, inv;
x += XOFFSET;
y += YOFFSET;
c = Asc2Int(c);
inv = (0xff * (c > 0x7f));
c = c & 0x7f;
y = y * 8;
sptr = mptr = (char*) ((*(unsigned int*)0x58) + y * 40 + x);
chptr = (char*) ((*(unsigned char*)0x2f4) * 0x100 + (c * 8));
for (ch = 0; ch < 8; ch++)
{
*mptr = (*chptr ^ inv);
mptr += 40;
chptr++;
}
if (inv) // round edges
{
*sptr = (*sptr ^ 0x81);
sptr += 40*7;
*sptr = (*sptr ^ 0x81);
}
}
void gprintxy (int x, int y, char* str)
{
char* s;
s = str;
while (*s != '\0')
{
gputcxy(x++,y,*s++);
}
}
void pause(int ticks)
{
int i;
char rtclk3;
for (i = 0; i < ticks; ++i)
{
rtclk3 = *(char*) 0x14;
while (rtclk3 == *(char*) 0x14) {}
}
}
/* File IO Functions */
int Fread (FILE* F, void* Buf, unsigned Size)
{
size_t Res;
Res = fread (Buf, 1, Size, F);
return Res > 0? Res : 0;
}
int Fwrite (FILE* F, const void* Buf, unsigned Size)
{
size_t Res;
Res = fwrite (Buf, 1, Size, F);
return Res > 0? Res : 0;
}
void statusline(char* str)
{
gprintxy7(0,STATUSLINE," ");
gprintxy7(20 - strlen(str) / 2,STATUSLINE,str);
}
void getname(char x, char y, char* nameptr)
{
char i;
char* str;
str = nameptr;
statusline("please enter your name:");
memset(nameptr,0,8);
i = 0;
gprintxy7(x,y,"_");
while ((*nameptr = cgetc()) != 155)
{
if (++i > 7)
{
--i;
--nameptr;
}
if ((*nameptr) == 126)
{
if (i)
{
--i;
--nameptr;
}
}
else
++nameptr;
*nameptr = '_';
gprintxy7(x,y," ");
gprintxy7(x,y,str);
}
gputcxy7(x+i,y,' ');
*nameptr = '\0';
}
void topscores(newscore)
int newscore;
{
int i, j;
char buf[8];
int* p;
if (levelbuf[2] <= (levelscore * 100 / maxvalue))
{
char c;
c = (levelscore * 100 / maxvalue);
sprintf(levelbuf,"next level! %d bonus!", c);
statusline(levelbuf);
score += c;
level = (++level % 9); // next level
c = cgetc();
}
saveblock(3,12,33,116);
clearblock(3,12,33,116);
gprintxy7(13,16,"highscores");
for (i = 0; i < MAXSCORE; ++i)
{
if (getscorevalue(i) < newscore)
{
if (i < MAXSCORE)
{
for (j = MAXSCORE-1; j >= i; --j)
{
memcpy(getscorename(j+1),getscorename(j), 11);
}
}
getname(13,28+i*8,getscorename(i));
p = (int*) (getscorename(i) + 9);
*p = newscore;
newscore = 0;
}
sprintf(buf,"%2d.",i + 1);
gprintxy7(8,28+i*8,buf);
gprintxy7(13,28+i*8,getscorename(i));
sprintf(buf,fourdigitform,getscorevalue(i));
gprintxy7(25,28+i*8,buf);
}
statusline("Press a key...");
i = cgetc();
restoreblock(3,12,33,116);
statusline(helpmsg);
}
void loadscore()
{
FILE* file;
int rc;
char i;
file = fopen(highscorefile,"r");
if (file)
{
rc = Fread (file, scorelist, SCOREFILESIZE);
fclose(file);
highscore = getscorevalue(0);
}
else
{
statusline("No Highscorefile, creating new file!");
for (i = 0; i <= MAXSCORE; ++i)
{
memset(getscorename(i), ' ',8);
*(getscorename(i) + 9) = 0;
*(getscorename(i) + 10) = 0;
}
i = cgetc();
}
}
void loadlevel(char level)
{
FILE* file;
char filename[14];
int rc;
char i, s;
s = soundflg;
if (s)
stopmusic();
*(char*) 0x22f = 0;
pause(2);
sprintf(filename,"LEVEL%02d.AGL", level);
file = fopen(filename,"r");
if (file)
{
rc = Fread (file, levelbuf, LEVELFILESIZE);
fclose(file);
*(char*) 0x22f = 0x22;
oldlevel = level;
}
else
{
*(char*) 0x22f = 0x22;
statusline("Could not load level!");
i = cgetc();
}
if (s)
startmusic();
}
void savescore()
{
FILE* file;
int rc;
stopmusic();
*(char*) 0x22f = 0;
pause(2);
statusline("Saving Highscorefile...");
file = fopen(highscorefile,"w");
if (file)
{
rc = Fwrite (file, scorelist, SCOREFILESIZE);
fclose(file);
}
else
statusline("Error saving Highscorefile!");
*(char*) 0x22f = 0x22;
}
void resettime(void)
{
*(int*) 0x13 = 0; // reset RTCLOK to zero
}
void showtime(void)
{
int time;
char buf[4];
time = maxtime - (clock() / _clocks_per_sec()); // time in seconds
if (time != oldtime)
{
sprintf(buf," %02d", time / 60); // minutes
gprintxy7(32,LEVELLINE,buf);
sprintf(buf,":%02d", time % 60); // seconds
gprintxy7(35,LEVELLINE,buf);
oldtime = time;
}
}
void help(void)
{
char c;
saveblock(3,12,33,116);
clearblock(3,12,33,116);
gprintxy7(3,20," ATARI greed help ");
gprintxy7(3,28," 'M' = toggle music ");
gprintxy7(3,36," 'Q' = quit game ");
gprintxy7(3,44," 'P' = show possible moves ");
gprintxy7(3,52," 'ESC' = toggle menu ");
gprintxy7(3,64," use joystick or keys to move ");
gprintxy7(3,72," W E R ");
gprintxy7(3,80," \\ | / ");
gprintxy7(3,88," S - + - D ");
gprintxy7(3,96," / | \\ ");
gprintxy7(3,104," Z X C ");
statusline(continuemsg);
c = cgetc();
restoreblock(3,12,33,116);
statusline(helpmsg);
}
void info(void)
{
char c;
saveblock(3,12,33,116);
clearblock(3,12,33,116);
gprintxy7(3,20," ATARI greed ");
gprintxy7(3,28," based on the UNIX game 'greed' ");
gprintxy7(3,36," written by matthew t. day ");
gprintxy7(3,44," and eric s. raymond ");
gprintxy7(3,60," programmed on an apple mac ");
gprintxy7(3,68," by carsten strotmann ");
gprintxy7(3,76," using the cc65 crosscompiler ");
gprintxy7(3,92," sound made by winfried piegsda ");
gprintxy7(3,100," using the pegasus soundmonitor ");
gprintxy7(3,108," graphic design by w. piegsda ");
statusline(continuemsg);
c = cgetc();
restoreblock(3,12,33,116);
statusline(helpmsg);
}
void showmarker(void)
{
int i = 0;
for (; i < 10; ++i);
{
pause(2);
gputcxy(x,y,MK + 0x80);
gputcxy(x,y,MK);
}
}
void botmsg(msg)
char *msg;
{
statusline(msg);
havebotmsg = 1;
}
void quit() {
int ch;
botmsg("Really quit?",0);
if ((ch = cgetc()) != 'y' && ch != 'Y') {
return;
}
exitflg = 1;
}
void earthquake(void)
{
char i;
char *p;
p = (char*) 0x2800;
for (i=0; i < 20; ++i)
{
*p = rnd(7) * 0x10;
pause(rnd(3));
}
*p = 0x70;
}
void showscore(void)
{
char buf[8];
char perc;
sprintf(buf,fourdigitform, score);
gprintxy14(6,MENULINE,buf);
sprintf(buf,fourdigitform, highscore);
gprintxy14(22,MENULINE,buf);
perc = levelbuf[2] - ((levelscore * 100) / maxvalue);
if (perc > 100)
perc = 0;
sprintf(buf,"%3d%%",perc);
gprintxy14(36,MENULINE,buf);
}
void showmoves(on)
int on;
{
int dy = -1;
int dx;
for (; dy <= 1; ++dy) {
if (y+dy < 0 || y+dy >= MAXY) continue;
for (dx = -1; dx <= 1; ++dx) {
int j=y, i=x, d=grid[y+dy][x+dx];
if (!d) continue;
do {
j += dy;
i += dx;
if (j < 0 || i < 0 || j >= MAXY || i >= MAXX || !grid[j][i]) break;
} while (--d);
if (!d) {
int j=y, i=x, d=grid[y+dy][x+dx];
/* The next section chooses inverse-video *
* or not, and then "walks" chosen valid *
* move, reprinting characters with new mode */
do {
j += dy;
i += dx;
gputcxy(i, j, grid[j][i] + '0' + (0x80 * on)); /* print possible moves inverted */
} while (--d);
}
}
}
}
void printscoreline(void)
{
gprintxy14(0,MENULINE,"Score:");
gprintxy14(12,MENULINE,"Highscore:");
gprintxy14(29,MENULINE,"Finish:");
}
void refresh()
{
int y,x;
char levelname[33];
statusline("refreshing screen...");
clearblock(0,8,39,MAXY*8);
memcpy(levelname,(char*) (levelbuf + 3),32);
levelname[32] = '\0';
gprintxy7(0,LEVELLINE,levelname);
printscoreline();
for (y=0; y < MAXY; ++y)
for (x=0; x < MAXX; ++x)
if (grid[y][x])
gputcxy(x,y,grid[y][x] + '0');
showmarker();
showmoves(allmoves);
showscore();
statusline("hit esc for menu");
}
int othermove(bady, badx)
int bady, badx;
{
int dy = -1;
int dx;
for (; dy <= 1; ++dy)
for (dx = -1; dx <= 1; ++dx)
if ((!dy && !dx) || (dy == bady && dx == badx) || y+dy < 0 && x+dx < 0 && y+dy >= MAXY && x+dx >= MAXX)
continue;
else
{
int j = y;
int i = x;
int d = grid[y+dy][x+dx];
if (!d) continue;
do {
j += dy;
i += dx;
if (j < 0 || i < 0 || j >= MAXY || i >= MAXX || !grid[j][i]) break;
} while (--d);
if (!d) return 1;
}
return 0;
}
void menu(void)
{
char c;
char mlen[] = {8,9,4,4,4};
char mchoice = 0;
char moffset = 0;
// set and enable DLI
waitvbi();
menuflg = 1; // switch DLI colors
clearblock(0, MENULINE, 40, 14);
statusline("Choose Menu...");
while (c != 27)
{
gprintxy14(1,MENULINE,"Continue Highscore Info Help Quit");
invertblock((2 * mchoice) + moffset + 1, MENULINE + 1, mlen[mchoice], 14);
c = cgetc();
switch(c)
{
case 30: // cursor left
if (mchoice > 0)
{
--mchoice;
moffset -= mlen[mchoice];
}
break;
case 31: // cursor right
if (mchoice < 4)
{
moffset += mlen[mchoice];
++mchoice;
}
break;
case 155: // enter
switch (mchoice)
{
case 0:
c = 27; // exit menu
break;
case 1:
topscores(score);
break;
case 2:
info();
break;
case 3:
help();
break;
case 4:
quit();
c = 27;
break;
}
break;
}
}
waitvbi();
menuflg = 0;
clearblock(0, MENULINE, 40, 14);
printscoreline();
statusline(helpmsg);
showscore();
}
int tunnel(cmd)
char cmd;
{
int dy, dx, distance;
int i,j,d;
if (oldtime <= 0)
{
statusline ("T I M E O U T !!");
i = cgetc();
return(0); // timeout
}
switch(cmd)
{
case 27: /* ESC */
menu();
if (exitflg)
return(0);
else
return(1);
break;
case 't':
case 'T': /* top scores */
topscores(score);
return(1);
break;
case 'm': /* sound off */
case 'M':
if (soundflg)
{
stopmusic();
statusline("music off");
}
else
{
startmusic();
statusline("music on");
}
return(1);
break;
case 's': /* key left */
case 'S':
case '4':
dy = 0;
dx = -1;
break;
case 'x': /* key down */
case 'X':
case '2':
dy = 1;
dx = 0;
break;
case 'e': /* key up */
case 'E':
case '8':
dy = -1;
dx = 0;
break;
case 'd': /* key right */
case 'D':
case '6':
dy = 0;
dx = 1;
break;
case 'z': /* key left/down */
case 'Z':
case '1':
dy = 1;
dx = -1;
break;
case 'c': /* key right/down */
case 'C':
case '3':
dy = dx = 1;
break;
case 'w': /* key left/up */
case 'W':
case '7':
dy = dx = -1;
break;
case 'r': /* key right/up */
case 'R':
case '9':
dy = -1;
dx = 1;
break;
case 'p':
case 'P':
allmoves = !allmoves;
showmoves(allmoves);
return(1);
case 'q':
case 'Q':
quit();
if (exitflg)
return(0);
else
return(1);
case 'o':
case 'O':
earthquake();
return(1);
case '?':
help();
return(1);
case 'i':
case 'I':
info();
return(1);
case 'a':
case 'A':
refresh();
/* refresh; falls through to return */
default:
return(1);
}
distance = (y + dy >= 0 && x + dx >= 0 && y + dy < MAXY && x + dx < MAXX) ? grid[y+dy][x+dx] : 0;
j = y;
i = x;
d = distance;
do {
j += dy;
i += dx;
if (j >= 0 && i >= 0 && j < MAXY && i < MAXX && grid[j][i])
;
else if (!othermove(dy, dx)) { /* no other good move */
j -= dy;
i -= dx;
gputcxy(x,y,' ');
while (y != j || x != i) {
y += dy;
x += dx;
++score;
++levelscore;
if (score > highscore)
highscore = score;
gputcxy(x,y,' ');
}
gputcxy(x,y,'*');
showscore();
topscores(score);
return(0);
}
else
{
botmsg("Bad move!",1);
return(1);
}
} while (--d);
if (allmoves) showmoves(0);
if (havebotmsg) { /* if old bottom msg exists */
printscoreline();
statusline(helpmsg);
havebotmsg = 0;
}
gputcxy(x,y,' ');
do {
y += dy;
x += dx;
++score;
++levelscore;
if (score > highscore)
highscore = score;
grid[y][x] = 0;
gputcxy(x,y,' ');
} while (--distance);
gputcxy(x,y,MK);
if (allmoves) showmoves(1);
showscore();
return(1);
}
void intro(void)
{
char y;
char x;
unsigned char *chptr;
unsigned char *mptr;
memset((char*) (*(unsigned int*)0x58), 0, 40 * 8); // clear levelname
chptr = (char*) TITLEBASE;
mptr = (char*) ((*(unsigned int*)0x58) + (40*8)+1);
disable_os();
for (y = 0; y < 144; ++y)
{
memcpy(mptr,chptr,MAXX);
chptr += MAXX;
mptr += 40;
}
enable_os();
statusline("ATARI greed version 0.91");
pause(90);
statusline("press key to start game...");
x = cgetc();
}
char getcommand(void)
{
char c = 0;
char j = 0;
while (c == 0)
{
if ((*(char*) 0x2fc) != 0xFF) // key pressed?
{
c = cgetc();
}
j = *(char*) 0x278;
if (j != 0xf) // Joystick?
{
switch(j)
{
case 14:
c = 'e'; // up
break;
case 7:
c = 'd'; // right
break;
case 13:
c = 'x'; // down
break;
case 11:
c = 's'; // left
break;
case 9:
c = 'z'; // left/down
break;
case 5:
c = 'c'; // right/down
break;
case 10:
c = 'w'; // left/up
break;
case 6:
c = 'r'; // right/up
break;
}
}
showtime();
if (oldtime <= 0) c = ' ';
}
return(c);
}
int bittest(val,bit)
int val, bit;
{
return !(val & (1 << bit));
}
char getplayfield(char x, char y)
{
int* p;
char c;
p = (int*) (levelbuf + 35);
while (bittest(*p, c = rnd(9)))
;
p = (int*) (levelbuf + 40 + (y * 5 ) + (x / 8));
return(bittest(*p, 7 - (x % 8)) ? 0 : c);
}
int main(void) {
int val = 1;
int dllist_old;
graphics(8);
highscore = 0;
*(char*) 0x02c6 = 0;
*(char*) 0x02c5 = 0xF;
dllist_old = *(int*) 0x230;
memmove((char*) 0x2800, &dllist, sizeof(dllist));
*(int*) 0x230 = (int) 0x2800;
// set and enable DLI
*(int*) 0x200 = (int) &dli01;
*(char*) 0xd40e = 0xc0;
loadscore();
loadlevel(level);
startmusic();
while(!exitflg)
{
intro();
statusline("starting new game...");
if (level != oldlevel)
loadlevel(level);
score = levelscore = maxvalue = 0;
maxtime = levelbuf[39] * 60; // timeout minutes
srand(*(int*) 0xD20A); /* initalize seed with random number, ATARI specific */
for (y=0; y < MAXY; ++y)
for (x=0; x < MAXX; ++x)
if (grid[y][x] = getplayfield(x,y))
++maxvalue;
while (!getplayfield(y = rnd(MAXY)-1, x = rnd(MAXX)-1))
; /* random initial location */
grid[y][x] = 0; /* eat initial square */
refresh();
resettime();
while((val = tunnel(getcommand())) > 0)
continue;
}
topscores(score);
stopmusic();
savescore();
// disable DLI
*(char*) 0xd40e = 0x60; // NMIEN VBI and RESET on
graphics(0);
exit(0);
}
At line 2,701 added 451 lines
!! Assembler Code (ca65)
!!! Display List Interrupts
{{{
.include "/Users/cas/develop/cc65/asminc/atari.inc"
.export _dli01
.export _dli02
.export _dli03
.export _dli04
.export _dli05
.export _menuflg
.export _fnt7
.export _fnt14
_fnt7: .incbin "seven.fnt"
_fnt14: .incbin "fourteen.fnt"
_menuflg: .byte 0
.proc _dli01
pha
txa
pha
nop
nop
ldx DLI02cnt2
L1:
lda DLI02fade2-1,x
sta WSYNC
sta COLBK
sta COLPF2
nop
dex
bne L1
lda #<_dli02
ldx #>_dli02
sta VDSLST
stx VDSLST+1
pla
tax
pla
rti
.endproc
DLI02fade: .byte $9E, $9C, $9A, $98, $96, $94, $92, $90
DLI02fadem: .byte $0E, $0C, $0A, $08, $06, $04, $02, $00
DLI02cnt: .byte 8
DLI02fade2: .byte $00, $02, $04, $06, $0E
DLI02fade2m: .byte $90, $92, $94, $96, $9E
DLI02fadepm: .byte $98, $98, $9A, $9C, $9E
DLI02cnt2: .byte 5
.proc _dli02
pha
txa
pha
ldx DLI02cnt
dex
L1:
lda _menuflg
beq X1
lda DLI02fadem-1,x
bne X2
X1:
lda DLI02fade-1,x
X2:
sta WSYNC
sta COLBK
sta COLPF2
dex
bne L1
sta WSYNC
sta COLPM0
sta COLPM1
lda #$2C
sta HPOSP0
lda #$CC
sta HPOSP1
lda #$FF
sta GRAFP0
sta GRAFP1
lda %00000010
sta GRACTL
ldx DLI02cnt2
L2:
lda DLI02fade2-1,x
sta WSYNC
sta COLPF2
lda DLI02fadepm-1,x
sta COLPM0
sta COLPM1
dex
bne L2
lda #<_dli03
ldx #>_dli03
sta VDSLST
stx VDSLST+1
pla
tax
pla
rti
.endproc
DLI03fade: .byte $90, $92, $94, $96, $98, $9A, $9C, $9E
DLI03fadem: .byte $00, $02, $04, $06, $08, $0A, $0C, $0E
DLI03cnt: .byte 8
DLI03fade2m: .byte $9E, $96, $94, $92, $90
DLI03fadepm: .byte $9E, $9C, $9A, $98, $98
DLI03fade2: .byte $0E, $06, $04, $02, $01
DLI03cnt2: .byte 5
.proc _dli03
pha
txa
pha
ldx DLI03cnt2
L1:
lda DLI03fade2-1,x
sta WSYNC
sta COLPF2
lda DLI03fadepm-1,x
sta COLPM0
sta COLPM1
dex
bne L1
sta WSYNC
lda #0
sta HPOSP0
sta HPOSP0
lda #$0
sta GRAFP0
sta GRAFP1
ldx DLI03cnt
dex
L2:
lda _menuflg
beq X1
lda DLI03fadem-1,x
bne X2
X1:
lda DLI03fade-1,x
X2:
sta WSYNC
sta COLBK
sta COLPF2
dex
bne L2
sta WSYNC
stx COLBK
stx COLPF2
lda #<_dli04
sta VDSLST
lda #>_dli04
sta VDSLST+1
pla
tax
pla
rti
.endproc
.proc _dli04
pha
txa
pha
ldx DLI02cnt2
L4:
lda _menuflg
beq X1
lda DLI02fade2m-1,x
bne X2
X1:
lda DLI02fade2-1,x
X2:
sta WSYNC
sta COLBK
sta COLPF2
dex
bne L4
stx WSYNC
stx COLBK
stx COLPF2
lda #<_dli05
sta VDSLST
lda #>_dli05
sta VDSLST+1
pla
tax
pla
rti
.endproc
.proc _dli05
pha
txa
pha
ldx DLI03cnt2
L4:
lda _menuflg
bne X1
lda DLI03fade2-1,x
bne X2
X1:
nop
nop
lda DLI03fade2m-1,x
X2:
sta WSYNC
sta COLBK
sta COLPF2
dex
bne L4
sta WSYNC
stx COLBK
stx COLPF2
lda #<_dli01
sta VDSLST
lda #>_dli01
sta VDSLST+1
pla
tax
pla
rti
.endproc
}}}
!! Access RAM under OS
{{{
; RAMXL
; routines to access RAM under OS-ROM
.word $FFFF
.word $2a00
.word end-1
.org $2a00
intv = $FFF0
nmiv = $FFFA
resv = $FFFC
irqv = $FFFE
portb = $D301
nmien = $D40E
on: jmp os_on
x_save: .byte $00
off: jmp os_off
;
doirq: stx x_save
tax ; a - irq #
jsr os_on
lda intv,x
sta jmpvec+1
lda intv+1,x
sta jmpvec+2
lda #>return
pha
lda #<return
pha
cli
php
;
jmpvec: jmp $FFFF ; -- will be overwritten
;
return: jsr os_off
ldx x_save
pla
rti
;
nmi_han: pha
lda #$0A
jmp doirq
;
irq_han: pha
lda #$0E
jmp doirq
;
os_on: lda portb
ora #$01 ; toggle OS bit on
sta portb
rts
;
os_off: lda portb
and #$FE ; toggle OS bit off
sta portb
rts
;
install: lda #0
sta nmien
sei
jsr os_off
lda #<nmi_han
sta nmiv
lda #>nmi_han
sta nmiv+1
lda #<irq_han
sta irqv
lda #>irq_han
sta irqv+1
jsr os_on
cli
lda #$40
sta nmien
rts
memcpy:
src = $f0
dst = $f2
cnt = $f4
; src = $F0-$F1
; dst = $F2-$F3
; cnt = $F4-$F5
ldy #0
L1:
lda (src),y
sta (dst),y
inc src
bne L2
inc src+1
L2:
inc dst
bne L3
inc dst+1
L3:
dec cnt
bne L1
dec cnt+1
bpl L1
rts
movetitle:
lda #<titlestart
sta src
lda #>titlestart
sta src+1
lda #<$D800 ; $D800
sta dst
lda #>$D800
sta dst+1
lda #<5472
sta cnt
lda #>5472
sta cnt+1
jsr install
jsr os_off
jsr memcpy
jsr os_on
rts
end:
;---------------------------
.word $FFFF
.word $3000
.word end2-1
.org $3000
titlestart:
.incbin "titelbild.raw"
end2:
.word $FFFF
.word $02e2
.word end3-1
.org $02e2
.word movetitle
}}}
!! Level Files
!!! Level 1 (Example)
{{{
; level 0 for ATARI Greed
; Version 1.0
; total length 130 bytes
; Magic Code, 'AG'
magic: .byte "AG"
; percent needed to complete level
percent: .byte 65
; Level Title 32 Chars
title: .byte "aller anfang ist einfach..."
.res $20 - (* - title)
; Possible values (bitfield), 10 bits
; FEDCBA9876543210
values: .word %0000001111111111 ; 0-9
; Possible goodies (bitfield), 16 Bits
; FEDCBA9876543210
goodies: .word %0000000000000000 ; no goodies
; Time in minutes
time: .byte 8 ; 8 Minutes time
; levelmask 5 x 18 bytes (bitfield)
levelmask: .incbin "level00.raw"
}}}