From ca61acd4506afb0125ae64b33f5f90ee198c0f6e Mon Sep 17 00:00:00 2001 From: Nick White Date: Thu, 29 Jul 2010 19:09:26 +0100 Subject: 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 --- .gitignore | 2 + COPYING | 19 ++++ Makefile | 58 ++++++++++++ README | 29 ++++++ TODO | 9 ++ config.mk | 21 +++++ font.h | 8 +- license.txt | 19 ---- makefile | 32 ------- piece.c | 278 -------------------------------------------------------- piece.h | 61 ------------- sintable.h | 8 +- spout.c | 298 +++++++++++++++++++++++++++++++++++++++++++++++++++++------- spout.h | 30 ++++++ 14 files changed, 448 insertions(+), 424 deletions(-) create mode 100644 .gitignore create mode 100644 COPYING create mode 100644 Makefile create mode 100644 README create mode 100644 TODO create mode 100644 config.mk delete mode 100644 license.txt delete mode 100644 makefile delete mode 100644 piece.c delete mode 100644 piece.h create mode 100644 spout.h diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..564e89a --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +*.o +spout diff --git a/COPYING b/COPYING new file mode 100644 index 0000000..06cf57d --- /dev/null +++ b/COPYING @@ -0,0 +1,19 @@ +Copyright (c) 2002-2006 Kuni, 2010 Nick White + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to +deal in the Software without restriction, including without limitation the +rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +sell copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +IN THE SOFTWARE. diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..d479cce --- /dev/null +++ b/Makefile @@ -0,0 +1,58 @@ +# See COPYING file for copyright, license and warranty details. + +NAME = spout +SRC = spout.c +TARGETS = $(NAME) + +OBJ = $(SRC:.c=.o) +MAN = $(TARGETS:=.1) + +include config.mk + +all: $(TARGETS) + +$(OBJ): config.mk spout.h + +.c.o: + @echo CC $< + @cc -c $(CFLAGS) $< + +$(TARGETS): $(OBJ) + @echo LD $@ + @cc -o $@ $(OBJ) $(LDFLAGS) + +clean: + rm -f -- $(TARGETS) $(OBJ) $(NAME)-$(VERSION).tar.gz $(NAME)-$(VERSION).tar.gz.sig + +dist: clean + @mkdir -p $(NAME)-$(VERSION) + @cp -R $(SRC) $(NAME).h Makefile config.mk COPYING README $(NAME)-$(VERSION) + @for i in $(MAN); do \ + sed "s/VERSION/$(VERSION)/g" < $$i > $(NAME)-$(VERSION)/$$i; done + @tar -c $(NAME)-$(VERSION) | gzip -c > $(NAME)-$(VERSION).tar.gz + @gpg -b < $(NAME)-$(VERSION).tar.gz > $(NAME)-$(VERSION).tar.gz.sig + @rm -rf $(NAME)-$(VERSION) + @echo $(NAME)-$(VERSION).tar.gz $(NAME)-$(VERSION).tar.gz.sig + +install: all + @echo installing executables to $(DESTDIR)$(PREFIX)/bin + @mkdir -p $(DESTDIR)$(PREFIX)/bin + @for i in $(TARGETS); do \ + cp -f $$i $(DESTDIR)$(PREFIX)/bin/$$i; \ + chmod 755 $(DESTDIR)$(PREFIX)/bin/$$i; done + @echo installing manual pages to $(DESTDIR)$(MANPREFIX)/man1 + @mkdir -p $(DESTDIR)$(MANPREFIX)/man1 + @for i in $(MAN); do \ + sed "s/VERSION/$(VERSION)/g" < $$i > $(DESTDIR)$(MANPREFIX)/man1/$$i; \ + chmod 644 $(DESTDIR)$(MANPREFIX)/man1/$$i; done + +uninstall: + @echo uninstalling executables from $(DESTDIR)$(PREFIX)/bin + @for i in $(TARGETS); do rm -f $(DESTDIR)$(PREFIX)/bin/$$i; done + @echo uninstalling manual pages from $(DESTDIR)$(MANPREFIX)/man1 + @for i in $(MAN); do rm -f $(DESTDIR)$(MANPREFIX)/man1/$$i; done + +test: all + @echo no tests yet! + +.PHONY: all clean dist install uninstall test diff --git a/README b/README new file mode 100644 index 0000000..f46bc73 --- /dev/null +++ b/README @@ -0,0 +1,29 @@ +Spout +===== + +Spout is a simple caveflying game. The object is to get as high as possible, avoiding or destroying obstacles. + +Requirements +------------ + +* libSDL + +Install +------- + +Edit config.mk to your liking, then run 'make install' + +Controls +-------- + +Left: Rotate left +Right: Rotate right +Space: Accelerate +Exit: Shift-Esc + +History +------- + +Spout was originally made for a handheld by kuni, and soon afterwards was ported to Windows using cygwin and sdl, licensed under the MIT license; see http://www.din.or.jp/~ku_/junk/junk.htm#spout +In 2004 a 'unix version' was released, which mostly just slapped autotools into the windows version and infringed the license: http://code.mizzenblog.com/category/spout/ +This is a new unix version, based on the original Windows code by kuni, which aims to add useful features and simplify the code. diff --git a/TODO b/TODO new file mode 100644 index 0000000..69803c5 --- /dev/null +++ b/TODO @@ -0,0 +1,9 @@ +remove functions which are more trouble than they're worth +check function return values more +set controls and default zoom and fullscreen in config.h +move useful stuff from spout.h to spout.c + +create man page + +add gamemode where one has to destroy everything before progressing (or something) +add mod music diff --git a/config.mk b/config.mk new file mode 100644 index 0000000..3cfc393 --- /dev/null +++ b/config.mk @@ -0,0 +1,21 @@ +# See COPYING file for copyright, license and warranty details. + +VERSION = 1.4 + +# paths +PREFIX = /usr/local +MANPREFIX = ${PREFIX}/share/man + +# includes and libs +SDLINC = $(shell pkg-config --cflags sdl) +SDLLIB = $(shell pkg-config --libs sdl) + +INCS = -I. -I/usr/include ${SDLINC} +LIBS = -L/usr/lib -lc ${SDLLIB} + +# flags +CFLAGS = -std=gnu99 -Wall -Werror ${INCS} -DVERSION=\"${VERSION}\" +LDFLAGS = ${LIBS} + +# compiler and linker +CC = cc diff --git a/font.h b/font.h index b2c439d..4eb4908 100644 --- a/font.h +++ b/font.h @@ -1,3 +1,10 @@ +/* + * This file is part of Spout + * + * See COPYING file for copyright, license and warranty details. + * + */ + const unsigned char FONT6[] = { // 80, 77, 66, 80, 20, 6, 0, 0, 1, 0, 128, 0, 96, 0, 223, 119, // 0, 6, 0, 0, @@ -201,4 +208,3 @@ const unsigned char FONT16[] = { 24, 60, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 24, 0, 0, 0 }; - diff --git a/license.txt b/license.txt deleted file mode 100644 index 83d7981..0000000 --- a/license.txt +++ /dev/null @@ -1,19 +0,0 @@ -Copyright (c) 2002-2006 Kuni - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to -deal in the Software without restriction, including without limitation the -rights to use, copy, modify, merge, publish, distribute, sublicense, and/or -sell copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS -IN THE SOFTWARE. diff --git a/makefile b/makefile deleted file mode 100644 index 4b7cc36..0000000 --- a/makefile +++ /dev/null @@ -1,32 +0,0 @@ -# spout -# SDLÍÑmakefile - -.SUFFIXES: .o .c - -SDL_LIB = /usr/local/lib -SDL_INCLUDE = /usr/local/include/SDL - -CC = gcc -CFLAGS = -I$(SDL_INCLUDE) -O2 -mno-cygwin - -LD = gcc -LDFLAGS = -L$(SDL_LIB) -L. -lmingw32 -lSDLmain -lSDL -mwindows - -PRGNAME = spout -OBJS = spout.o piece.o - - -$(PRGNAME).exe: $(OBJS) - $(LD) $(CFLAGS) -o $(PRGNAME).exe $(OBJS) $(RES) $(LDFLAGS) -.c.o: - $(CC) $(CFLAGS) -c -o $@ $< - -spout.o: piece.h font.h sintable.h -piece.c: piece.h - -clean: - rm -f $(PRGNAME).exe *.o - -run: $(PRGNAME).exe - $(PRGNAME).exe - diff --git a/piece.c b/piece.c deleted file mode 100644 index 4ab9057..0000000 --- a/piece.c +++ /dev/null @@ -1,278 +0,0 @@ -#include -#include -#include -#include -#include -#include - -#include "SDL.h" -#include "piece.h" -#include "font.h" - -SDL_Surface *video, *layer; -SDL_Rect layerRect; - -unsigned char *vBuffer = NULL; - -void pceLCDDispStop() -{ -} - -void pceLCDDispStart() -{ -} - -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); - - 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); -} - -unsigned char *keys; - -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; -} - -int interval = 0; - -void pceAppSetProcPeriod(int period) { - interval = period; -} - -int exec = 1; - -void pceAppReqExit(int c) { - exec = 0; -} - -unsigned char *pceLCDSetBuffer(unsigned char *pbuff) -{ - if(pbuff) { - vBuffer = pbuff; - } - return vBuffer; -} - -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 char *font_adr = FONT6; - -void pceFontSetType(int type) -{ - const int width[] = {5, 8, 4}; - const int height[] = {10, 16, 6}; - const 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; - unsigned 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 ++; - } -} - -int pceFileOpen(FILEACC *pfa, const char *fname, int mode) -{ - if(mode == FOMD_RD) { - *pfa = open(fname, O_RDONLY | O_BINARY); - } else if(mode == FOMD_WR) { - *pfa = open(fname, O_CREAT | O_RDWR | O_BINARY | O_TRUNC, S_IREAD | S_IWRITE); - } - - if(*pfa >= 0) { - return 0; - } else { - return 1; - } -} - -int pceFileReadSct(FILEACC *pfa, void *ptr, int sct, int len) -{ - return read(*pfa, ptr, len); -} - -int pceFileWriteSct(FILEACC *pfa, const void *ptr, int sct, int len) -{ - return write(*pfa, ptr, len); -} - -int pceFileClose(FILEACC *pfa) -{ - close(*pfa); - return 0; -} - -int main(int argc, char *argv[]) -{ - SDL_Event event; - long nextTick, wait; - int cnt = 0; - - 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; - } - } - - pceAppExit(); -} - diff --git a/piece.h b/piece.h deleted file mode 100644 index 383e1fb..0000000 --- a/piece.h +++ /dev/null @@ -1,61 +0,0 @@ -#include "SDL.h" - -#define ZOOM 2 -#define SDL_WIDTH (128 * ZOOM) -#define SDL_HEIGHT (88 * ZOOM) - -#define PAD_RI 0x01 -#define PAD_LF 0x02 -#define PAD_DN 0x04 -#define PAD_UP 0x08 -#define PAD_B 0x10 -#define PAD_A 0x20 -#define PAD_D 0x40 -#define PAD_C 0x80 - -#define TRG_RI 0x0100 -#define TRG_LF 0x0200 -#define TRG_DN 0x0400 -#define TRG_UP 0x0800 -#define TRG_B 0x1000 -#define TRG_A 0x2000 -#define TRG_D 0x4000 -#define TRG_C 0x8000 - -#define pcesprintf sprintf - -#define CPU_SPEED_NORMAL 0 -#define pceCPUSetSpeed - -#define FILEACC int -#define FOMD_RD 0 -#define FOMD_WR 1 -#define pceFileCreate - -#define pceTimerGetCount SDL_GetTicks - -#define PP_MODE_SINGLE 0 -#define PP_MODE_REPEAT 1 -#define pcePadSetTrigMode - -int pceFontPrintf(const char *fmt, ... ); -void pceFontSetTxColor(int color); -void pceFontSetBkColor(int color); -void pceFontSetPos(int x, int y); -void pceFontSetType(int type); - -void pceLCDDispStop(); -void pceLCDDispStart(); -unsigned char *pceLCDSetBuffer(unsigned char *pbuff); -void pceLCDTrans(); - -void pceAppSetProcPeriod(int period); -void pceAppReqExit(int c); - -int pceFileOpen(FILEACC *pfa, const char *fname, int mode); -int pceFileReadSct(FILEACC *pfa, void *ptr, int sct, int len); -int pceFileWriteSct(FILEACC *pfa, const void *ptr, int sct, int len); -int pceFileClose(FILEACC *pfa); - -int pcePadGet(); - diff --git a/sintable.h b/sintable.h index 243b141..dc83953 100644 --- a/sintable.h +++ b/sintable.h @@ -1,3 +1,10 @@ +/* + * This file is part of Spout + * + * See COPYING file for copyright, license and warranty details. + * + */ + short sintable[1024]={ 0, 25, 50, 75, 101, 126, 151, 176, 201, 226, 251, 276, 301, 326, 351, 376, @@ -128,4 +135,3 @@ short sintable[1024]={ -400, -375, -350, -325, -300, -275, -250, -225, -200, -175, -150, -125, -100, -74, -49, -24 }; - 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 #include +#include +#include #include - -#include "piece.h" - +#include +#include +#include +#include +#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; +} diff --git a/spout.h b/spout.h new file mode 100644 index 0000000..88d6562 --- /dev/null +++ b/spout.h @@ -0,0 +1,30 @@ +/* + * This file is part of Spout + * + * See COPYING file for copyright, license and warranty details. + * + */ + +#define SDL_WIDTH (128 * zoom) +#define SDL_HEIGHT (88 * zoom) + +#define PAD_RI 0x01 +#define PAD_LF 0x02 +#define PAD_DN 0x04 +#define PAD_UP 0x08 +#define PAD_B 0x10 +#define PAD_A 0x20 +#define PAD_D 0x40 +#define PAD_C 0x80 + +#define TRG_RI 0x0100 +#define TRG_LF 0x0200 +#define TRG_DN 0x0400 +#define TRG_UP 0x0800 +#define TRG_B 0x1000 +#define TRG_A 0x2000 +#define TRG_D 0x4000 +#define TRG_C 0x8000 + +#define PP_MODE_SINGLE 0 +#define PP_MODE_REPEAT 1 -- cgit v1.2.3