home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
ring.yamanashi.ac.jp/pub/pc/freem/action/
/
action.zip
/
spout11.zip
/
SDL
/
spout.c
< prev
next >
Wrap
C/C++ Source or Header
|
2002-10-12
|
16KB
|
820 lines
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "piece.h"
#include "sintable.h"
#define FRAMERATE 50
#define MAX_GRAIN 500
const unsigned char MATSUMI[] = {
// 80, 77, 66, 80, 180, 0, 0, 0, 1, 0, 128, 0, 10, 0, 223, 119,
// 160, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 34, 56, 68, 10, 4,
80, 129, 202, 0, 0, 0, 0, 0, 8, 0, 8, 34, 73, 255, 127, 223,
241, 241, 95, 0, 0, 0, 0, 0, 8, 0, 0, 71, 72, 254, 10, 5,
67, 17, 68, 0, 1, 2, 59, 187, 137, 75, 136, 66, 164, 16, 81, 31,
84, 225, 155, 0, 2, 25, 10, 168, 138, 74, 72, 135, 33, 255, 49, 5,
97, 177, 78, 0, 2, 33, 58, 171, 142, 74, 72, 134, 32, 16, 23, 215,
86, 77, 117, 0, 2, 33, 34, 170, 9, 74, 73, 2, 73, 255, 49, 21,
176, 33, 78, 0, 1, 26, 59, 187, 137, 50, 73, 2, 76, 40, 81, 28,
0, 193, 181, 0, 0, 0, 0, 0, 0, 0, 0, 2, 245, 199, 23, 211,
240, 33, 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0
};
typedef struct {
short x, y;
} SVECTOR;
typedef struct {
long x, y;
} VECTOR;
typedef struct tagGRAIN {
struct tagGRAIN *next;
struct tagGRAIN *prev;
SVECTOR s, v;
short pos;
unsigned char color;
} GRAIN;
GRAIN *grainUseLink, *grainFreeLink;
unsigned char vbuff[128 * 88];
unsigned char vbuff2[128 * 128];
GRAIN grain[MAX_GRAIN];
GRAIN *v2g[128 * 128];
SVECTOR box;
VECTOR mPos, mSpeed;
int mR;
int nGrain;
int time = FRAMERATE * 60, score = 0, height = 0, dispscore = 0;
int hiScore[2] = {0, 0};
int dispPos, upperLine, rollCount;
void spout(int t, int x, int y);
void sweep(unsigned char c1, unsigned char c2);
void initGrain(void);
GRAIN *allocGrain(void);
GRAIN *freeGrain(GRAIN *current);
void pceAppInit(void)
{
pceLCDDispStop();
pceLCDSetBuffer(vbuff);
pceAppSetProcPeriod(1000 / FRAMERATE);
memset(vbuff, 0, 128 * 88);
pceLCDDispStart();
pceCPUSetSpeed(CPU_SPEED_NORMAL);
{
FILEACC fa;
if(!pceFileOpen(&fa, "spout.sco", FOMD_RD)) {
pceFileReadSct(&fa, (void *)hiScore, 0, 8);
pceFileClose(&fa);
}
}
pcePadSetTrigMode(PP_MODE_SINGLE);
srand(pceTimerGetCount());
}
void pceAppProc(int cnt)
{
static int gamePhase = 0, gameover;
int pad = pcePadGet();
if( (pad & (PAD_C | TRG_D)) == (PAD_C | TRG_D) ||
(pad & (TRG_C | PAD_D)) == (TRG_C | PAD_D)) {
if(gamePhase >= 2) {
gamePhase = 0;
} else {
pceAppReqExit(0);
}
pad = 0;
}
if(gamePhase == 4) {
if(pad & (TRG_C)) {
gamePhase = 3;
}
return;
}
if(!(gamePhase & 1)) {
if(gamePhase == 0) {
if(score > hiScore[0] || (score == hiScore[0] && height > hiScore[1])) {
FILEACC fa;
hiScore[0] = score;
hiScore[1] = height;
if(!pceFileOpen(&fa, "spout.sco", FOMD_WR)) {
pceFileWriteSct(&fa, (void *)hiScore, 0, 8);
} else if(!pceFileCreate("spout.sco", 8)) {
if(!pceFileOpen(&fa, "spout.sco", FOMD_WR)) {
pceFileWriteSct(&fa, (void *)hiScore, 0, 8);
}
}
pceFileClose(&fa);
}
} else {
score = 0;
dispscore = 0;
height = - 58;
time = 60 * FRAMERATE;
}
{
int i;
for(i = 0; i < 128 * 128; i ++) {
v2g[i] = NULL;
}
initGrain();
nGrain = 0;
}
if(gamePhase & 2) {
memset(vbuff2, 0xd2, 128 * 128);
memset(vbuff2 + 128 * 0, 0, 128 * 78);
memset(vbuff2 + 128 * (128 - 32), 0, 128 * 32);
} else {
memset(vbuff2, 0, 128 * 128);
}
memset(vbuff, 0, 128 * 88);
{
int i;
unsigned char *pC;
pC = vbuff2;
for(i = 0; i < 128; i ++) {
*pC++ = 0x0b;
*pC++ = 0x0b;
*pC++ = 0x0b;
*pC++ = 0x0b;
pC += 128 - 8;
*pC++ = 0x0b;
*pC++ = 0x0b;
*pC++ = 0x0b;
*pC++ = 0x0b;
}
}
mPos.x = 40 * 256;
mPos.y = 0 * 256;
mSpeed.x = 0;
mSpeed.y = 0;
mR = 256 + (gamePhase & 2) * 224;
dispPos = 0;
upperLine = 0;
gameover = 0;
rollCount = 0;
gamePhase ++;
memset(vbuff + 128, 0x03, 128);
pceFontSetType(2 + 128);
pceFontSetPos(0, 82);
if(height > 0) {
pceFontPrintf("time:%2d height:%4d score:%6d", (time + FRAMERATE - 1) / FRAMERATE, height % 10000, score % 1000000);
} else {
pceFontPrintf("time:%2d height: 0 score:%6d", (time + FRAMERATE - 1) / FRAMERATE, score % 1000000);
}
pceFontSetType(0);
}
if((pad & TRG_C) && gamePhase == 3 && gameover == 0) {
pceFontSetType(2 + 128);
pceFontSetPos(64 - 7 * 4 / 2, 33);
pceFontPrintf(" pause ");
pceFontSetType(0);
gamePhase = 4;
pceLCDTrans();
return;
}
if(gamePhase & 2) {
if(gameover == 0) {
if((pad & PAD_RI)) {
mR = (mR - 16) & 1023;
} else if((pad & PAD_LF)) {
mR = (mR + 16) & 1023;
}
if((pad & (PAD_A | PAD_B))) {
mSpeed.x -= sintable[(256 + mR) & 1023] / 128;
mSpeed.y += sintable[mR] / 128;
}
mSpeed.y += 8;
if(mSpeed.x < -256 * 4) {
mSpeed.x = -256 * 4;
} else if(mSpeed.x > 256 * 4) {
mSpeed.x = 256 * 4;
}
if(mSpeed.y < -256 * 4) {
mSpeed.y = -256 * 4;
} else if(mSpeed.y > 256 * 4) {
mSpeed.y = 256 * 4;
}
mPos.x += mSpeed.x / 16;
mPos.y += mSpeed.y / 16;
if(mPos.x >= 125 * 256) {
mPos.x = 124 * 256;
gameover = 1;
} else if(mPos.x <= 2 * 256) {
mPos.x = 3 * 256;
gameover = 1;
}
if(mPos.y >= 78 * 256) {
mPos.y = 77 * 256;
gameover = 1;
}
if(mPos.y < 40 * 256) {
unsigned char *pC;
int i, j, w, x1 , x2;
mPos.y += 256;
upperLine = (upperLine - 1) & 127;
height ++;
if(height > 0) {
score ++;
if((height & 127) == 0) {
score += (time + FRAMERATE - 1) / FRAMERATE * 10;
time += 60 * FRAMERATE;
if(time > 99 * FRAMERATE) {
time = 99 * FRAMERATE;
}
pceFontSetType(2 + 128);
pceFontSetPos(4 * 5, 82);
pceFontPrintf("%2d", (time + FRAMERATE - 1) / FRAMERATE);
pceFontSetType(0);
}
pceFontSetType(2 + 128);
pceFontSetPos(4 * 15, 82);
pceFontPrintf("%4d", height % 10000);
pceFontSetType(0);
}
if(upperLine == 111 && height > 0) {
unsigned long *pL;
pL = (unsigned long *)(vbuff2 + 128 * 108 + 4);
while(pL < (unsigned long *)(vbuff2 + 128 * 109 - 4)) {
*pL++ = 0;
}
pL += 2;
while(pL < (unsigned long *)(vbuff2 + 128 * 110 - 4)) {
*pL++ = 0xd3d3d3d3;
}
pL += 2;
while(pL < (unsigned long *)(vbuff2 + 128 * 111 - 4)) {
*pL++ = 0;
}
}
box.x = 20 - (height + 40) / 64;
if(box.x < 4) {
box.x = 4;
}
box.y = 20 - (height + 40) / 64;
if(box.y < 4) {
box.y = 4;
}
for(j = 0; j < 1; j ++) {
int x, y;
x = 4 + (rand() % box.x);
y = 4 + (rand() % box.y);
pC = vbuff2 + ((upperLine - 20 - (rand() & 7)) & 127) * 128;
x1 = 4 + (rand() % (120 - x));
x2 = x;
i = y;
while(i > 0) {
if(pC < vbuff2) {
pC += 128 * 128;
}
pC += x1;
w = x2;
while(w > 0) {
*pC++ = 0;
w --;
}
pC -= x1 + x2 + 128;
i --;
}
}
sweep(0x13, 0xd2);
}
}
} else {
mPos.x = 7 * 256;
mPos.y = 60 * 256;
mR = 0;
if((rollCount & 7) == 0) {
int i, j;
if((upperLine & 31) == 0) {
unsigned long *pL;
pceLCDSetBuffer(vbuff2 + ((upperLine - 24) & 127) * 128);
pceFontSetBkColor(0);
switch(upperLine / 32) {
case 0:
pL = (unsigned long *)(vbuff2 + 12 + ((upperLine - 24) & 127) * 128);
for(i = 0; i < 16; i ++) {
for(j = 0; j < 26 / 2; j ++) {
*pL = 0x91919191;
pL += 2;
}
if((i & 7) == 3) {
pL += 7;
} else if((i & 7) == 7) {
pL += 5;
} else {
pL += 6;
}
}
pceFontSetTxColor(0x03);
pceFontSetType(1 + 128);
pceFontSetPos(64 - 4 * 5, 0);
pceFontPrintf("spout");
break;
case 2:
pceFontSetTxColor(0xc3);
pceFontSetType(2 + 128);
pceFontSetPos(118 - 20 * 4, 0);
pceFontPrintf(" height: %8d", hiScore[1] % 1000000);
pceFontSetPos(118 - 20 * 4, 6);
pceFontPrintf("high-score: %8d", hiScore[0] % 1000000);
break;
case 1:
{
const unsigned char *pS = MATSUMI;
unsigned char *pD = vbuff2 + ((upperLine - 16) & 127) * 128;
for(i = 0; i < 128 / 8 * 10; i ++) {
unsigned char t = *pS++;
for(j = 0; j < 8; j ++) {
if(t & 0x80) {
*pD = 0xc3;
}
pD ++;
t <<= 1;
}
}
}
break;
}
pceFontSetType(0);
pceFontSetTxColor(0x03);
pceFontSetBkColor(0);
pceLCDSetBuffer(vbuff);
}
upperLine = (upperLine - 1) & 127;
sweep(0x13, 0x00);
}
}
rollCount ++;
{
static int gx[] = {-2, 2, -1, 1, 0};
int r, t;
r = rand() & 3;
t = gx[r]; gx[r] = gx[r + 1]; gx[r + 1] = t;
if(gamePhase & 2) {
if(gameover == 0 && (pad & (PAD_A | PAD_B))) {
int i, t, x, y;
for(i = 0; i < 5; i ++) {
t = mPos.x / 256 + gx[i] + ((mPos.y / 256 - 1 + abs(gx[i]) + dispPos) & 127) * 128;
x = mSpeed.x / 16 + sintable[(256 + mR) & 1023] / 8;
y = mSpeed.y / 16 - sintable[mR] / 8;
spout(t, x, y);
}
}
} else {
int i, t;
for(i = -1; i <= 2; i ++) {
t = 7 + i + ((60 - 1 + dispPos) & 127) * 128;
spout(t, 512, -384);
}
}
}
{
GRAIN *pG, *pG2;
SVECTOR svt;
pG = grainUseLink;
while(pG) {
int f = 0;
unsigned char *c;
pG->v.y += 8;
pG->s.x += pG->v.x;
pG->s.y += pG->v.y;
*(vbuff2 + pG->pos) = 0;
*(v2g + pG->pos) = NULL;
if(pG->s.y >= 256) {
do {
pG->s.y -= 256;
pG->pos = (pG->pos + 128) & 16383;
c = (vbuff2 + pG->pos);
if(*c) {
if(*c & 0x04) {
int r;
pG2 = *(v2g + pG->pos);
r = 31 - (rand() & 63);
svt = pG->v;
pG->v = pG2->v;
pG2->v = svt;
pG->v.x += r;
pG2->v.x -= r;
} else {
pG->v.y = -pG->v.y / 2;
pG->v.x += 15 - (rand() & 31);
if(*c & 0xc0) {
*c -= 0x40;
if(!(*c & 0xc0)) {
*c = 0;
}
}
if(pG->color & 0xc0) {
pG->color -= 0x40;
} else {
pG->color = 0;
f = 1;
}
}
pG->pos = (pG->pos - 128) & 16383;
break;
}
} while(pG->s.y >= 256);
} else {
while(pG->s.y <= -256) {
pG->s.y += 256;
pG->pos = (pG->pos - 128) & 16383;
c = (vbuff2 + pG->pos);
if(*c) {
if(*c & 4) {
pG2 = *(v2g + pG->pos);
svt = pG->v;
pG->v = pG2->v;
pG2->v = svt;
} else {
pG->v.y = -pG->v.y / 2;
if(*c & 0xc0) {
*c -= 0x40;
if(!(*c & 0xc0)) {
*c = 0;
}
}
if(pG->color & 0xc0) {
pG->color -= 0x40;
} else {
pG->color = 0;
f = 1;
}
}
pG->pos = (pG->pos + 128) & 16383;
break;
}
}
}
if(pG->s.x >= 256) {
do {
pG->s.x -= 256;
pG->pos = (pG->pos + 1) & 16383;
c = (vbuff2 + pG->pos);
if(*c) {
if(*c & 4) {
pG2 = *(v2g + pG->pos);
svt = pG->v;
pG->v = pG2->v;
pG2->v = svt;
} else {
pG->v.x = -pG->v.x / 2;
if(*c & 0xc0) {
*c -= 0x40;
if(!(*c & 0xc0)) {
*c = 0;
}
}
if(pG->color & 0xc0) {
pG->color -= 0x40;
} else {
pG->color = 0;
f = 1;
}
}
pG->pos = (pG->pos - 1) & 16383;
break;
}
} while(pG->s.x >= 256);
} else {
while(pG->s.x <= -256) {
pG->s.x += 256;
pG->pos = (pG->pos - 1) & 16383;
c = (vbuff2 + pG->pos);
if(*c) {
if(*c & 4) {
pG2 = *(v2g + pG->pos);
svt = pG->v;
pG->v = pG2->v;
pG2->v = svt;
} else {
pG->v.x = -pG->v.x / 2;
if(*c & 0xc0) {
*c -= 0x40;
if(!(*c & 0xc0)) {
*c = 0;
}
}
if(pG->color & 0xc0) {
pG->color -= 0x40;
} else {
pG->color = 0;
f = 1;
}
}
pG->pos = (pG->pos + 1) & 16383;
break;
}
}
}
if(f) {
*(vbuff2 + pG->pos) = pG->color;
nGrain --;
*(v2g + pG->pos) = NULL;
pG = freeGrain(pG);
} else {
*(vbuff2 + pG->pos) = pG->color;
*(v2g + pG->pos) = pG;
pG = pG->next;
}
}
}
dispPos = upperLine;
{
unsigned long *pL, *pL2, *pLe;
pL = (unsigned long *)(vbuff + 2 * 128);
pL2 = (unsigned long *)(vbuff2 + dispPos * 128);
pLe = pL2 + 128 * 78 / 4;
if(pLe > (unsigned long *)(vbuff2 + 128 * 128)) {
pLe = (unsigned long *)(vbuff2 + 128 * 128);
}
while(pL2 < pLe) {
*pL = *pL2 & 0x03030303;
pL ++;
pL2 ++;
}
pL2 = (unsigned long *)(vbuff2);
while(pL < (unsigned long *)(vbuff + 128 * (78 + 2))) {
*pL = *pL2 & 0x03030303;
pL ++;
pL2 ++;
}
}
{
unsigned char *pC;
pC = vbuff2 + mPos.x / 256 + ((mPos.y / 256 + dispPos) & 127) * 128;
if(*pC != 0 && (*pC & 4) == 0) {
gameover = *pC;
}
}
{
static int gPhase = 0;
unsigned char *pC;
int i, x, y;
if(gameover == 0 && (gamePhase & 2)) {
x = mPos.x + sintable[(256 + mR) & 1023] * gPhase / 64;
y = mPos.y - sintable[mR] * gPhase / 64;
for(i = 0; i < 3; i ++) {
if(y >= 78 * 256) {
break;
}
*(vbuff + x / 256 + (y / 256 + 2) * 128) = 3;
x += sintable[(256 + mR) & 1023] / 16;
y -= sintable[mR] / 16;
if(y >= 78 * 256) {
break;
}
*(vbuff + x / 256 + (y / 256 + 2) * 128) = 3;
x += sintable[(256 + mR) & 1023] / 16;
y -= sintable[mR] / 16;
if(y >= 78 * 256) {
break;
}
*(vbuff + x / 256 + (y / 256 + 2) * 128) = 3;
x += sintable[(256 + mR) & 1023] * 2 / 16;
y -= sintable[mR] * 2 / 16;
}
gPhase = (gPhase + 1) & 15;
}
pC = vbuff + mPos.x / 256 + (mPos.y / 256 + 2) * 128;
*(pC - 129) = 0x03;
*(pC - 128) = 0x03;
*(pC - 127) = 0x03;
*(pC - 1) = 0x03;
*pC = 0x00;
*(pC + 1) = 0x03;
*(pC + 127) = 0x03;
*(pC + 128) = 0x03;
*(pC + 129) = 0x03;
}
if(gamePhase == 1) {
if(pad & (TRG_A | TRG_B)) {
gamePhase = 2;
}
} else if(gameover) {
if(pad & (TRG_A | TRG_B)) {
gamePhase = 0;
}
}
if((gamePhase & 2) && time && gameover == 0) {
time --;
if((time % FRAMERATE) == 0) {
pceFontSetType(2 + 128);
pceFontSetPos(4 * 5, 82);
pceFontPrintf("%2d", (time + FRAMERATE - 1) / FRAMERATE);
pceFontSetType(0);
}
if(time == 0) {
gameover = 1;
}
}
if(dispscore < score) {
dispscore ++;
if(dispscore < score) {
dispscore ++;
}
pceFontSetType(2 + 128);
pceFontSetPos(4 * 26, 82);
pceFontPrintf("%6d", dispscore % 1000000);
pceFontSetType(0);
}
if(gamePhase == 3 && gameover != 0) {
pceFontSetType(2 + 128);
pceFontSetPos(64 - 11 * 4 / 2, 33);
pceFontPrintf(" game over ");
pceFontSetType(0);
}
pceLCDTrans();
}
void pceAppExit( void )
{
pceCPUSetSpeed(CPU_SPEED_NORMAL);
}
void spout(int t, int x, int y)
{
if(*(vbuff2 + t) == 0) {
if(nGrain < MAX_GRAIN) {
GRAIN *pG = allocGrain();
pG->v.x = x;
pG->v.y = y;
pG->s.x = 0;
pG->s.y = 0;
pG->color = (2 + (rand() & 1)) + 4 + 64 * 3;
pG->pos = t;
*(vbuff2 + t) = pG->color;
v2g[t] = pG;
nGrain ++;
}
}
}
void sweep(unsigned char c1, unsigned char c2)
{
int i;
unsigned char *pC = vbuff2 + 4 + 128 * ((upperLine + 77) & 127);
for(i = 0; i < 120; i ++) {
if(*pC & 4) {
GRAIN **ppG;
ppG = v2g + (int)(pC - vbuff2);
freeGrain(*ppG);
*ppG = NULL;
nGrain --;
}
*pC++ = c1;
}
pC += 8;
if(pC >= vbuff2 + 128 * 128) {
pC -= 128 * 128;
}
for(i = 0; i < 120; i ++) {
*pC++ = c2;
}
}
void initGrain(void)
{
int i;
for(i = 0; i < MAX_GRAIN - 1; i ++) {
grain[i].next = &grain[i + 1];
}
grain[i].next = NULL;
grainFreeLink = grain;
grainUseLink = NULL;
return;
}
GRAIN *allocGrain(void)
{
GRAIN *current = grainFreeLink;
if(current) {
grainFreeLink = current->next;
current->next = grainUseLink;
current->prev = NULL;
if(current->next) {
current->next->prev = current;
}
grainUseLink = current;
}
return current;
}
GRAIN *freeGrain(GRAIN *current)
{
GRAIN *next = current->next;
if(next) {
next->prev = current->prev;
}
if(current->prev) {
current->prev->next = next;
} else {
grainUseLink = next;
}
current->next = grainFreeLink;
grainFreeLink = current;
return next;
}