diff options
Diffstat (limited to 'spout.c')
-rw-r--r-- | spout.c | 298 |
1 files changed, 266 insertions, 32 deletions
@@ -1,10 +1,22 @@ +/* + * This file is part of Spout + * + * See COPYING file for copyright, license and warranty details. + * + */ + #include <stdio.h> #include <stdlib.h> +#include <unistd.h> +#include <stdarg.h> #include <string.h> - -#include "piece.h" - +#include <sys/stat.h> +#include <fcntl.h> +#include <math.h> +#include <SDL.h> +#include "spout.h" #include "sintable.h" +#include "font.h" #define FRAMERATE 50 #define MAX_GRAIN 500 @@ -60,36 +72,52 @@ int nGrain; int time = FRAMERATE * 60, score = 0, height = 0, dispscore = 0; int hiScore[2] = {0, 0}; int dispPos, upperLine, rollCount; +int fullscreen = 0; +int zoom = 4; +char score_path[512]; + +SDL_Surface *video, *layer; +SDL_Rect layerRect; +unsigned char *vBuffer = NULL; + +unsigned char *keys; +int exec = 1; +int interval = 0; +int font_posX = 0, font_posY = 0, font_width = 4, font_height = 6; +unsigned char font_fgcolor = 3, font_bgcolor = 0, font_bgclear = 0; +const unsigned char *font_adr = FONT6; 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); +int pceFontPrintf(const char *fmt, ... ); +void pceFontSetTxColor(int color); +void pceFontSetBkColor(int color); +void pceFontSetPos(int x, int y); +void pceFontSetType(int type); +void pceLCDTrans(); +int pcePadGet(); void pceAppInit(void) { - pceLCDDispStop(); - pceLCDSetBuffer(vbuff); - pceAppSetProcPeriod(1000 / FRAMERATE); + vBuffer = vbuff; + interval = 1000 / FRAMERATE; memset(vbuff, 0, 128 * 88); - pceLCDDispStart(); - - pceCPUSetSpeed(CPU_SPEED_NORMAL); + snprintf(score_path, 512, "%s/%s", getenv("HOME"), ".spout.sco"); { - FILEACC fa; - if(!pceFileOpen(&fa, "spout.sco", FOMD_RD)) { - pceFileReadSct(&fa, (void *)hiScore, 0, 8); - pceFileClose(&fa); + int fa; + if((fa = open(score_path, O_RDONLY)) != -1) { + read (fa, (void *) hiScore, 8); + close(fa); } } - pcePadSetTrigMode(PP_MODE_SINGLE); - - srand(pceTimerGetCount()); + srand(SDL_GetTicks()); } void pceAppProc(int cnt) @@ -103,7 +131,7 @@ void pceAppProc(int cnt) if(gamePhase >= 2) { gamePhase = 0; } else { - pceAppReqExit(0); + exec = 0; } pad = 0; } @@ -118,17 +146,13 @@ void pceAppProc(int cnt) if(!(gamePhase & 1)) { if(gamePhase == 0) { if(score > hiScore[0] || (score == hiScore[0] && height > hiScore[1])) { - FILEACC fa; + int 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); - } + if((fa = open(score_path, O_CREAT | O_WRONLY | O_TRUNC)) != -1) { + write(fa, (void *) hiScore, 8); + close(fa); } - pceFileClose(&fa); } } else { score = 0; @@ -335,7 +359,7 @@ void pceAppProc(int cnt) if((upperLine & 31) == 0) { unsigned long *pL; - pceLCDSetBuffer(vbuff2 + ((upperLine - 24) & 127) * 128); + vBuffer = vbuff2 + ((upperLine - 24) & 127) * 128; pceFontSetBkColor(0); switch(upperLine / 32) { @@ -392,7 +416,7 @@ void pceAppProc(int cnt) pceFontSetTxColor(0x03); pceFontSetBkColor(0); - pceLCDSetBuffer(vbuff); + vBuffer = vbuff; } upperLine = (upperLine - 1) & 127; @@ -713,11 +737,6 @@ void pceAppProc(int cnt) } -void pceAppExit( void ) -{ - pceCPUSetSpeed(CPU_SPEED_NORMAL); -} - void spout(int t, int x, int y) { if(*(vbuff2 + t) == 0) { @@ -817,3 +836,218 @@ GRAIN *freeGrain(GRAIN *current) return next; } +void initSDL() { + SDL_PixelFormat *pfrm; + + if(SDL_Init(SDL_INIT_VIDEO) < 0) { + fprintf(stderr, "Couldn't initialize SDL: %s\n",SDL_GetError()); + exit(1); + } + atexit(SDL_Quit); + + if(fullscreen) + video = SDL_SetVideoMode(SDL_WIDTH, SDL_HEIGHT, 8, SDL_DOUBLEBUF | SDL_HWSURFACE | SDL_HWPALETTE | SDL_FULLSCREEN); + else + video = SDL_SetVideoMode(SDL_WIDTH, SDL_HEIGHT, 8, SDL_DOUBLEBUF | SDL_HWSURFACE | SDL_HWPALETTE); + if(video == NULL) { + fprintf(stderr, "Couldn't set video mode: %s\n", SDL_GetError()); + exit(1); + } + + pfrm = video->format; + layer = SDL_CreateRGBSurface(SDL_SWSURFACE, SDL_WIDTH, SDL_HEIGHT, 8, pfrm->Rmask, pfrm->Gmask, pfrm->Bmask, pfrm->Amask); + if(layer == NULL) { + fprintf(stderr, "Couldn't create surface: %s\n", SDL_GetError()); + exit(1); + } + + layerRect.x = 0; + layerRect.y = 0; + layerRect.w = SDL_WIDTH; + layerRect.h = SDL_HEIGHT; + + { + static SDL_Color pltTbl[4] = { + {255, 255, 255}, + {170, 170, 170}, + {85, 85, 85}, + {0, 0, 0} + }; + SDL_SetColors(video, pltTbl, 0, 4); + SDL_SetColors(layer, pltTbl, 0, 4); + } +} + +void pceLCDTrans() { + int x, y; + unsigned char *vbi, *bi; + + bi = layer->pixels; + for(y = 0; y < SDL_HEIGHT; y ++) { + vbi = vBuffer + (y / zoom) * 128; + for(x = 0; x < SDL_WIDTH; x ++) { + *bi ++ = *(vbi + x / zoom); + } + bi += layer->pitch - SDL_WIDTH; + } + + SDL_BlitSurface(layer, NULL, video, &layerRect); + SDL_Flip(video); +} + +int pcePadGet() { + static int pad = 0; + int i = 0, op = pad & 0x00ff; + + int k[] = { + SDLK_UP, SDLK_DOWN, SDLK_LEFT, SDLK_RIGHT, + SDLK_KP8, SDLK_KP2, SDLK_KP4, SDLK_KP6, + SDLK_x, SDLK_z, SDLK_SPACE, SDLK_RETURN, + SDLK_ESCAPE, SDLK_LSHIFT, SDLK_RSHIFT + }; + + int p[] = { + PAD_UP, PAD_DN, PAD_LF, PAD_RI, + PAD_UP, PAD_DN, PAD_LF, PAD_RI, + PAD_A, PAD_B, PAD_A, PAD_B, + PAD_C, PAD_D, PAD_D, + -1 + }; + + pad = 0; + + do { + if(keys[k[i]] == SDL_PRESSED) { + pad |= p[i]; + } + i ++; + } while(p[i] >= 0); + + pad |= (pad & (~op)) << 8; + + return pad; +} + +void pceFontSetType(int type) +{ + const int width[] = {5, 8, 4}; + const int height[] = {10, 16, 6}; + const unsigned char* adr[] ={FONT6, FONT16, FONT6}; + + type &= 3; + font_width = width[type]; + font_height = height[type]; + font_adr = adr[type]; +} + +void pceFontSetTxColor(int color) +{ + font_fgcolor = (unsigned char)color; +} + +void pceFontSetBkColor(int color) +{ + if(color >= 0) { + font_bgcolor = (unsigned char)color; + font_bgclear = 0; + } else { + font_bgclear = 1; + } +} + +void pceFontSetPos(int x, int y) +{ + font_posX = x; + font_posY = y; +} + +int pceFontPrintf(const char *fmt, ...) +{ + unsigned char *adr = vBuffer + font_posX + font_posY * 128; + char *pC; + char c[1024]; + va_list argp; + + va_start(argp, fmt); + vsprintf(c, fmt, argp); + va_end(argp); + + pC = c; + while(*pC) { + int i, x, y; + const unsigned char *sAdr; + if(*pC >= 0x20 && *pC < 0x80) { + i = *pC - 0x20; + } else { + i = 0; + } + sAdr = font_adr + (i & 15) + (i >> 4) * 16 * 16; + for(y = 0; y < font_height; y ++) { + unsigned char c = *sAdr; + for(x = 0; x < font_width; x ++) { + if(c & 0x80) { + *adr = font_fgcolor; + } else if(font_bgclear == 0) { + *adr = font_bgcolor; + } + adr ++; + c <<= 1; + } + adr += 128 - font_width; + sAdr += 16; + } + adr -= 128 * font_height - font_width; + pC ++; + } + return 0; +} + +int main(int argc, char *argv[]) +{ + SDL_Event event; + long nextTick, wait; + int cnt = 0; + int i; + for(i = 1; i < argc; i++) { + switch(argv[i][1]) { + case 'f': + fullscreen = 1; + break; + case 'z': + if(++i < argc) + zoom = strtol(argv[i], NULL, 0); + break; + default: + fprintf(stderr, "Usage: %s [-f] [-z zoomlevel]\n", argv[0]); + exit(EXIT_FAILURE); + } + } + + initSDL(); + pceAppInit(); + + SDL_WM_SetCaption("spout", NULL); + + nextTick = SDL_GetTicks() + interval; + while(exec) { + SDL_PollEvent(&event); + keys = SDL_GetKeyState(NULL); + + wait = nextTick - SDL_GetTicks(); + if(wait > 0) { + SDL_Delay(wait); + } + + pceAppProc(cnt); + // SDL_Flip(video); + + nextTick += interval; + cnt ++; + + if((keys[SDLK_ESCAPE] == SDL_PRESSED && (keys[SDLK_LSHIFT] == SDL_PRESSED || keys[SDLK_RSHIFT] == SDL_PRESSED)) || event.type == SDL_QUIT) { + exec = 0; + } + } + + return 0; +} |