Created
January 28, 2018 03:08
-
-
Save skooch/54ed24b9891ed476612eff130d4fdf20 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* Draw bouncing ball pattern on screen | |
* Increase/decrease ball pattern number by up/down key | |
* Read sound data from boot disk and play back as BGM | |
* Copyright (C) 1996 Sony Computer Entertainment Inc. | |
* All Rights Reserved | |
*/ | |
/* Preparation include header */ | |
#include <libps.h> | |
#include "pad.h' | |
/* | |
Macros | |
*/ | |
/* Basic setup */ | |
#def ine | |
KANJI | |
/* | |
Switch to display Kanji*/ | |
#def ine | |
OT LENGTH | |
1 | |
/* | |
Ordering table number*/ | |
#def ine | |
MAXOBJ | |
1500 | |
/* | |
Sprites (balls) maximum number*/ | |
#def ine | |
MVOL | |
127 | |
/* | |
Main volume level*/ | |
#def ine | |
SVOL | |
127 | |
/* | |
SEQ volume level*/ | |
#def ine | |
DFILE | |
3 | |
/* | |
File number*/ | |
/* Macros relating | |
to data arrangement | |
*/ | |
#def ine | |
VH ADDR | |
0x80090000 | |
#def ine | |
VB ADDR | |
0x800a0000 | |
#def ine | |
SEQ ADDR | |
0x80110000 | |
/* Macros relating | |
to display area | |
V | |
#def ine | |
FRAME X | |
320 | |
/* | |
Display area si ze ( hori zontal ) */ | |
#def ine | |
FRAME Y | |
240 | |
/* | |
Display area si ze ( vertical )* / | |
#def ine | |
WALL X | |
(FRAME X-16) | |
/* Ball pattern movement area size | |
(horizontal) */ | |
#def ine | |
WALL Y | |
(FRAME Y-16) | |
/* | |
Ball pattern movement area size | |
(vertical) */ | |
/* Range check macro */ | |
#define limitRange ( x, 1, h) ( ( x ) = ( ( x ) < ( 1 ) ? ( 1 ) : ( x ) > ( h ) ? ( h ) : ( x ) ) ) | |
/* | |
External variables | |
*/ | |
/* Ordering table related variables */ | |
GsOT WorldOT [ 2 ] ; | |
GsOT_TAG OTTags [ 2 ] [ l«OT_LENGTH] ; | |
/* Primitive related variables */ | |
PACKET GpuPacketArea [2] [MAXOB J* ( 2 0+4 ) ] ; | |
GsSPRITE sprt [MAXOBJ] ; | |
/* Ball pattern movement related variables */ | |
typedef struct { | |
u_short x, y; | |
u_short dx, dy; | |
} POS; | |
/* Controller related variables */ | |
volatile u_char *bbO, *bbl; | |
/* File reading related variables */ | |
typedef struct { | |
char *fname; | |
void *addr; | |
CdlFILE finfo; | |
} FILE_INFO; | |
static FILE_INFO dfile[DFILE] = { | |
{ M \\DATA\\SOUND\\STDO.VH; 1" , (void * ) VH_ADDR, 0} f | |
{ M \\DATA\\SOUND\\STDO.VB; 1" , (void *)VB_ADDR, 0} f | |
{ " \ \ DATA\ \ SOUND\ \ SAMPLE1 . SEQ; 1 " , (void * ) SEQ_ADDR, 0}, | |
}; | |
/* Sound related variables */ | |
short vab, seq; | |
/* | |
Static functions template | |
*/ | |
static void init_prim(); /* Ball pattern graphics related | |
initialisation */ | |
static void init_point ( POS *pos ) ; /* Ball pattern movement related | |
initialisation */ | |
static long pad_read ( long n); /* Controller state analysis */ | |
static u_long PadRead(long id); /* Controller state reading */ | |
static void dataf ile_search ( ) ; /* File retrieval on CD-ROM */ | |
static void dataf ile_read () ; /* File reading on CD-ROM */ | |
static void init_sound ( ) ; /* Sound data on memory playback | |
preparation */ | |
static void play_sound ( ) ; /* Sound playback start */ | |
static void stop_sound ( ) ; /* Sound playback termination */ | |
/* Location */ | |
/* Speed */ | |
/* | |
Main functions | |
*/ | |
main ( ) | |
{ | |
int nobj = 1; | |
( from 1 ) */ | |
GsOT *ot ; | |
int i, cnt, x, y; | |
int activeBuff; | |
GsSPRITE * sp; | |
POS pos [MAXOBJ] ; | |
POS *pp; | |
/* Number of ball patterns displayed | |
/* Pointer to drawing OT */ | |
/* Working variables*/ | |
SetVideoMode ( MODE_PAL ); /* | |
/* SetVideoMode ( MODE_NTSC ); /* | |
Get PadBuf ( &bbO , &bbl ) ; /* | |
dataf ile_search ( ) ; /* | |
dataf ile_read ( ) ; /* | |
Gs I nit Graph (320, 240, 4, 0, 0); | |
GsDef DispBuf f ( 0, 0, 0, 240); | |
/* | |
When drawing in ( 0, 0 ) - ( 320, 24 0 ) , | |
When drawing in ( 0, 24 0 ) - ( 320, 4 80 | |
*/ | |
PAL Mode */ | |
NTSC Mode */ | |
Get controller reception buffer */ | |
Data file retrieval */ | |
Data file reading */ | |
/* Drawing and display | |
environment setting */ | |
/* Same as above */ | |
display ( 0 , 24 0 ) - ( 320, 4 80 ) (db [ 0] ) | |
, display (0, 0 ) - ( 320, 24 0 ) (db [ 0] ) | |
/* Ordering table information setting */ | |
for (i = 0; i < 2; 1++) { | |
WorldOT [i] . length = OT_LENGTH; | |
WorldOT [ i ] . org = OTTags[i]; | |
} | |
/* Font setting */ | |
#ifdef KANJI /* In the case of Kanj i display */ | |
Kanj iFntOpen (160, 16, 256, 240, 704, 0, 768, 256, 0, 512); | |
#endif | |
FntLoad(960, 256); | |
/* Load basic font pattern in frame buffer */ | |
FntOpen (16, 16, 256, 200, 0, 512); | |
/* Font display location setting */ | |
init_prim(); /* Primitive buffer initial setting */ | |
init_point ( pos ) ; /* Ball pattern movement initial setting */ | |
init_sound ( ) ; /* Sound initial setting */ | |
play_sound ( ) ; /* Sound playback start */ | |
/* Main loop */ | |
while ( ( nob j = pad_read ( nobj ) ) >0) { | |
/* Double buffer switch */ | |
activeBuff = GsGetActiveBuf f ( ) ; | |
GsSetWorkBase ( ( PACKET * ) GpuPacketArea [ activeBuff] ) ; | |
/* Ordering table clear */ | |
GsClearOt(0, 0, &WorldOT [ activeBuff ]) ; | |
/* Ball pattern location update and registration to OT */ | |
sp = sprt; pp = pos; | |
for (i = 0; i < nobj; i++, sp++, pp++) { | |
/* Horizontal coordinate value update */ | |
if ( (x = (pp->x += pp->dx) % WALL_X*2) >= WALL_X) | |
x = WALL_X* 2 - x; | |
/* Vertical coordinate value update */ | |
if ( (y = (pp->y += pp->dy) % WALL_Y*2) >= WALL_Y) | |
y = WALL_Y* 2 - y; | |
/* Set new coordinate value for sprite primitive */ | |
sp->x = x; sp->y = y; | |
/* Registration to sprite primitive ordering table */ | |
GsSortFastSprite ( sp, &WorldOT [ activeBuff ] , 0); | |
} | |
DrawSync ( 0 ) ; /* Waiting for end of drawing */ | |
cnt = VSync ( 0 ) ; /* Waiting for vertical synchronisation | |
interrupt */ | |
GsSwapDispBuf f ( ) ; /* Double buffer switching */ | |
/* Registration to screen clear primitive ordering table */ | |
GsSortClear ( 60, 120, 120, SWorldOT [ activeBuff ]) ; | |
/* Drawing of primitive registered in OT */ | |
GsDrawOt ( &WorldOT [ activeBuff ] ); | |
/* Printing number of balls and elapsed time */ | |
#ifdef KANJI | |
Kanj i Fnt Print ( "Num =%d\n" , nobj ) ; | |
Kanj i Fnt Print ( "Time =%d\n", cnt ) ; | |
Kanj iFntFlush ( -1 ) ; | |
#endif | |
Fnt Print (" sprite = %d\n", nobj); | |
Fnt Print ( "total time = %d\n\n\n" , cnt); | |
FntPrint ( "UP : INCREASE\n" ) ; | |
Fnt Print ( "DOWN : DECREASE\n" ) ; | |
FntPrint ( "LI : PAUSE\n" ) ; | |
FntPrint ( "SELECT: END\n" ) ; | |
FntFlush ( -1 ) ; | |
} /* Main loop terminal */ | |
/* Execute this by pressing select button and verifying */ | |
stop_sound ( ) ; /* Sound playback termination */ | |
return ( 0 ) ; /* Program termination */ | |
} | |
/* | |
Ball pattern initialisation | |
*/ | |
#include "balltex . h" /* Ball pattern texture pattern */ | |
/* Ball pattern graphics related initialisation */ | |
static void init_prim() | |
{ | |
Gs SPRITE * sp; | |
u_short tpage; | |
RECT rect; | |
int i ; | |
rect.x = 640; rect.y = 0; | |
rect.w = 16/4; rect.h = 16; | |
Loadlmage (&rect, balll6xl6); | |
tpage = GetTPage(0, 0, 640, 0); | |
for (i = 0; i < 32; i++) { | |
rect.x = 0; rect.y = 480+i; | |
rect.w = 256; rect.h = 1; | |
Loadlmage ( &rect , ballcolor [ i ] ) ; | |
} | |
/* Sprite initialisation */ | |
for (sp = sprt, i = 0; i < MAXOBJ; i++, sp++ ) { | |
sp->attribute = 0; | |
sp->x = 0; | |
sp->y = 0; | |
sp->w = 16; | |
sp->h = 16; | |
sp->tpage = tpage; | |
sp->u = 0; | |
sp->v = 0; | |
sp->cx = 0; | |
sp->cy = 480+ ( i%32 ) ; | |
sp->r = sp->g = sp->b = 0x80; | |
sp->mx = 0; | |
sp->my = 0; | |
sp->scalex = ONE; | |
sp->scaley = ONE; | |
sp->rotate = 0; | |
} | |
} | |
/* Ball pattern movement related initialisation */ | |
static void init_point ( POS *pos ) | |
int | |
for ( i | |
= 0; i < MAXOBJ; i++) { | |
pos->x = rand ( ) ; | |
/* Start coordinate X */ | |
pos->y = rand ( ) ; | |
/* Start coordinate Y */ | |
pos->dx = ( rand ( ) % 4) +1; | |
/* Movement distance X l<=x<=4 ) */ | |
pos->dy = ( rand ( ) % 4) +1; | |
/* Movement distance Y l<=y<=4 ) */ | |
} | |
/* | |
Reading and analysis of controller state | |
*/ | |
/* Analysis of controller state */ | |
/* Return value | |
-1 : At time of pressing select button and verifying | |
1st argument + 4 : At time of pressing up button and verifying | |
1st argument - 4 : At time of pressing down button and verifying | |
Pause in function while pressing LI key */ | |
static long pad_read ( long n) | |
{ | |
u_long padd = PadRead(l); /* Controller reading */ | |
if (padd & PADLup ) n += 4; /* Left cross key up */ | |
if (padd & PADLdown ) n -= 4; /* Left cross key down */ | |
if (padd & PADL1 ) | |
while ( PadRead ( 1 ) & PADL1 ) ; /* Pause */ | |
if (padd & PADselect) | |
return (-1); /* Program termination */ | |
limitRange ( n, 1, MAXOB J-l ) ; /* n is given value l<=n<= (MAXOB J-l ) | |
return ( n ) ; | |
} | |
/* Controller state reading */ | |
static u_long PadRead (long id) | |
{ | |
return ( ~ ( * (bbO+3 ) | *(bb0+2) « 8 | *(bbl+3) « 16 | *(bbl+2) « | |
24) ) ; | |
} | |
/* | |
Reading the file on CD-ROM (DFILE) | |
*/ | |
/* Retrieving file on CD-ROM */ | |
static void dataf ile_search ( ) | |
{ | |
int i r j ; | |
for (i = 0; i < DFILE; i++) { /* Deal with DFILE file */ | |
for (j = 0; j < 10; j ++ ) { /* Return loop */ | |
if ( CdSearchFile ( & (df ile [ i ] . f info ) , df ile [ i ] . f name ) ! | |
break; | |
/* Retry loop interruption on normal termination */ | |
else | |
/* CD-ROM file reading */ | |
static void dataf ile_read ( ) | |
printf ( "%s not found . \n" , df ile [ i ] . fname ) ; | |
int i , j ; | |
int cnt; | |
for (i = 0; i < DFILE; i++) { /* Deal with DFILE file */ | |
for (j = 0; j < 10; j ++ ) { /* Retry loop */ | |
CdReadFile ( df ile [ i ] . fname , df ile [ i ] . addr , df ile [ i ] .finfo.size); | |
/* Normal processing can be executed by other side of read */ | |
/* Here, remaining sector number is monitored until Read terminated */ | |
while ((cnt = CdReadSync ( 1 , 0)) >0 ) | |
VSync ( 0 ) ; /* Waiting for vertical | |
synchronisation | |
interrupt ( for time | |
adjustment */ | |
} | |
if (cnt == 0) | |
break; /* Retry loop interruption on normal | |
termination* / | |
/* | |
Sound related | |
/ | |
/* Sound data on memory playback preparation */ | |
static void init_sound ( ) | |
{ | |
/* VAB opening and transmission to sound buffer */ | |
vab = SsVabTransf er ( ( u_char* ) VH_ADDR, ( u_char* ) VB_ADDR, -1, 1 ); | |
if (vab < 0) { | |
print f ( M SsVabTrans fer failed (%d)\n M , vab); | |
return; | |
} | |
/* SEQ opening */ | |
seg = SsSegOpen ( ( u_long * ) SEQ_ADDR, vab); | |
if (seg < 0) | |
print f ( M SsSegOpen failed (%d)\n", seg); | |
/* Sound playback start */ | |
static void play_sound() | |
{ | |
S s S e tMVo 1 ( MVOL , MVOL ) ; | |
SsSegSetVol (seg, SVOL, SVOL); | |
SsSegPlay (seg, S S PLAY_PLAY , SSPLAY | |
} | |
/* Sound playback termination */ | |
static void stop_sound ( ) | |
{ | |
SsSegStop ( seg ) ; | |
VSync ( 0) ; | |
VSync ( 0) ; | |
SsSegClose ( seg ) ; | |
SsVabClose (vab) ; | |
} | |
/* Main volume setting*/ | |
/* Volume setting for each SEQ */ | |
INFINITY);/* Playback switch ON */ | |
/* Playback switch OFF */ | |
/* SEQ close */ | |
/* VAB close */ | |
/* Source code termination */ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment