summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore2
-rw-r--r--COPYING (renamed from license.txt)2
-rw-r--r--Makefile58
-rw-r--r--README29
-rw-r--r--TODO9
-rw-r--r--config.mk21
-rw-r--r--font.h8
-rw-r--r--makefile32
-rw-r--r--piece.c278
-rw-r--r--piece.h61
-rw-r--r--sintable.h8
-rw-r--r--spout.c298
-rw-r--r--spout.h30
13 files changed, 430 insertions, 406 deletions
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/license.txt b/COPYING
index 83d7981..06cf57d 100644
--- a/license.txt
+++ b/COPYING
@@ -1,4 +1,4 @@
-Copyright (c) 2002-2006 Kuni
+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
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/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 <stdio.h>
-#include <stdlib.h>
-#include <stdarg.h>
-#include <sys\stat.h>
-#include <fcntl.h>
-#include <math.h>
-
-#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 <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;
+}
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