summaryrefslogtreecommitdiff
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
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
-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