summaryrefslogtreecommitdiff
path: root/spout.c
diff options
context:
space:
mode:
authorNick White <git@njw.me.uk>2010-07-29 19:09:26 +0100
committerNick White <git@njw.me.uk>2010-07-29 19:09:26 +0100
commitca61acd4506afb0125ae64b33f5f90ee198c0f6e (patch)
tree5025ec5d4bbf8c2494f393e0699ac236fb8e58d6 /spout.c
parent3a4a0d3f39c25adb6bc8ead135ed39634b2bcfbf (diff)
Simplify things alot, and add zoom and fullscreen
Added some documentation Improved build system Consolidated code into spout.c Added fullscreen option Added zoom option Removed unneeded functions
Diffstat (limited to 'spout.c')
-rw-r--r--spout.c298
1 files changed, 266 insertions, 32 deletions
diff --git a/spout.c b/spout.c
index cd04f38..f3844b9 100644
--- a/spout.c
+++ b/spout.c
@@ -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;
+}