Warning: this is an htmlized version!
The original is here, and the conversion rules are here. |
// CGA-Tron - a Tron-ish game. // Author: Eduardo Ochs <eduardoochs@gmail.com> // Source: <http://angg.twu.net/SDL/cga-tron.c> // Htmlized: <http://angg.twu.net/SDL/cga-tron.c.html> // Rules // ===== // You're yellow and you leave a yellow trail when you walk. // You never stop until you die. You die when you hit something // yellow. Use the arrow keys to change your direction. Try to make // the best score you can before you die. You only live once. // // In the beginning it's a black arena with yellow walls and a red // square 3x3 "pixels" wide somewhere. Walking over a red "pixel" // gives you one point and makes another 3x3 square appear somewhere. // So, crossing a 3x3 red square from one side to another gives you // three points and makes three other squares appear in random // positions. // // Walking over black pixels is harmless. // // Sometimes the red squares will appear over your trail. Then some // pixels of your trail will become red and you'll be able to cross. // // The game loop and the outer loop: typing "Q" or Esc or losing when // you're playing makes you go to the outer loop; in the outer loop // typing "P" or Enter or space restarts the game, and typing "Q" or // Esc leaves the program. // History // ======= // Current version: 2012jun30. // First C/SDL version: 2012jun07. // First Icon version: 2006aug27. // First Emacs Lisp version: 2004may31. // Original version in IBM-PC BASIC (for the CGA): 1986 // // Ancestors: <http://angg.twu.net/ICON/tron.icn.html> // <http://angg.twu.net/elisp/tron.el.html> // Screenshots: <http://angg.twu.net/ICON/tron.icn.png> // <http://angg.twu.net/elisp/tron.el.png> // // Here's the original code, in BASIC: // // 10 KEY OFF:SCREEN 1:COLOR 0,0:CLS:RANDOMIZE TIMER // 20 LINE (0,0)-(319,192),,b:X=150:Y=90:DX=1:DY=0:PTS=0 // 30 GOSUB 110:GOSUB 100 // 40 C=POINT(X,Y):IF C=3 THEN 90 ELSE PSET(X,Y),3 // 50 IF C=2 THEN PTS=PTS+1:GOSUB 100:GOSUB 110:SOUND 200,,2 // 60 A$=INKEY$:IF A$="" THEN 80 ELSE ND=INSTR("WASZwasz",A$)-1:IF ND<0 GOTO 80 // 70 MM=(ND AND 2)-1:H=ND AND 1:IF (H=1)<>(DX<>0) THEN DX=H*MM:DY=(1-H)*MM // 80 X=X+DX:Y=Y+DY:GOTO 40 // 90 END // 100 LOCATE 25,1:PRINT "Score:";PTS;:LOCATE 1,1:RETURN // 110 H=RND*316+1:V=RND*188+1:LINE(H,V)-(H+2,V+2),2,BF:RETURN // You are not expected to understand this // ======================================= // (find-es "sdl" "cga-tron") // http://www.lazyfoo.net/SDL_tutorials/lesson01/index2.php // (find-load81file "om") // (find-fline "~/IMAGES/littlelangs.png") // http://sdl.beuc.net/sdl.wiki/SDL_image // (find-es "sdl" "lazy-foo-tutorial") // (defun c () (interactive) (find-sh "cd ~/SDL/; rm -fv 2 2.o; gcc -o 2 2.c -lSDL && ./2")) // (defun c () (interactive) (find-sh "cd ~/SDL/; rm -fv 2 2.o; gcc -o 2 2.c -lSDL && ./2 -geometry +100+100")) // (find-libcnode "Pseudo-Random Numbers") // (find-libcnode "Function Index" "* sprintf:") // (find-fline "/usr/include/SDL/SDL_video.h") // http://www.libsdl.org/docs/html/sdlfillrect.html // http://www.libsdl.org/docs/html/sdlmaprgb.html // http://wiki.libsdl.org/moin.cgi/SDL_FillRect // http://www.libsdl.org/docs/html/guideinputkeyboard.html // http://www.libsdl.org/docs/html/audio.html /* (defun c () (interactive) (find-sh "cd ~/SDL/; rm -fv cga-tron; \ gcc -o cga-tron cga-tron.c -lSDL && ./cga-tron")) */ /* * (eepitch-shell2) * (eepitch-kill) * (eepitch-shell2) convert red.xpm red.bmp convert yellow.xpm yellow.bmp convert black.xpm black.bmp rm -fv 2 2.o # gcc -o 2 `sdl-config --cflags` `sdl-config --libs` 2.c # or: # g++ -o 2 2.c -lSDL * (eepitch-shell2) * (eepitch-kill) * (eepitch-shell2) rm -fv 2 2.o gcc -o 2 2.c -lSDL ./2 * (eepitch-shell) * (eepitch-kill) * (eepitch-shell) tar -cvzf cga-tron.tgz cga-tron.c {black,red,yellow}.{xpm,bmp} # (ee-cp "cga-tron.tgz" (ee-twupfile "SDL/cga-tron.tgz")) # http://angg.twu.net/SDL/cga-tron.tgz # http://www.libsdl.org/docs/html/sdlfillrect.html # http://www.libsdl.org/docs/html/sdlmaprgb.html */ //Include SDL functions and datatypes #include "SDL/SDL.h" static SDL_Surface* screen = NULL; static Uint32 colors_rgb[4]; static char point[320][200]; static int x=150, y=90, dx=1, dy=0, pts=0; // get_event() is hacky - it uses that 0 < SDL_QUIT < 27 // (find-fline "/usr/include/SDL/SDL_events.h" "SDL_QUIT,") // (find-fline "/usr/include/SDL/SDL_keysym.h" "SDLK_ESCAPE") static SDL_Event event; int get_event () { if (SDL_PollEvent(&event)) { // If there's an event to handle if (event.type == SDL_KEYDOWN) // If a key was pressed return event.key.keysym.sym; if (event.type == SDL_QUIT) return SDL_QUIT; } return 0; } void update_screen () { SDL_Flip(screen); } void prect(int x, int y, int w, int h, Uint32 c) { SDL_Rect rect; rect.x = x; rect.y = y; rect.w = w; rect.h = h; SDL_FillRect(screen, &rect, c); } void pset(int x, int y, int c) { prect(x*2, y*2, 2, 2, colors_rgb[c]); point[x][y] = c; } void draw_red_square () { int h=(rand()%316)+1, v=(rand()%187)+1, x, y; for (x=h; x<=h+2; ++x) for (y=v; y<=v+2; ++y) pset(x, y, 2); } static char *fontchars[256]; static char fontchar_space [] = {0, 0, 0, 0, 0, 0, 0, 0}; static char fontchar_colon [] = {0, 24, 24, 0, 0, 24, 24, 0}; static char fontchar_0[] = {56, 108, 198, 214, 198, 108, 56, 0}; static char fontchar_1[] = {24, 56, 24, 24, 24, 24, 126, 0}; static char fontchar_2[] = {124, 198, 6, 28, 48, 102, 254, 0}; static char fontchar_3[] = {124, 198, 6, 60, 6, 198, 124, 0}; static char fontchar_4[] = {28, 60, 108, 204, 254, 12, 30, 0}; static char fontchar_5[] = {254, 192, 192, 252, 6, 198, 124, 0}; static char fontchar_6[] = {56, 96, 192, 252, 198, 198, 124, 0}; static char fontchar_7[] = {254, 198, 12, 24, 48, 48, 48, 0}; static char fontchar_8[] = {124, 198, 198, 124, 198, 198, 124, 0}; static char fontchar_9[] = {124, 198, 198, 126, 6, 12, 120, 0}; static char fontchar_S[] = {60, 102, 48, 24, 12, 102, 60, 0}; static char fontchar_c[] = {0, 0, 124, 198, 192, 198, 124, 0}; static char fontchar_o[] = {0, 0, 124, 198, 198, 198, 124, 0}; static char fontchar_r[] = {0, 0, 220, 118, 96, 96, 240, 0}; static char fontchar_e[] = {0, 0, 124, 198, 254, 192, 124, 0}; void draw_str (int x0, int y0, char *str) { int x, y; for (; *str; ++str, x0+=8) for (y=0; y<8; ++y) for (x=0; x<8; ++x) pset(x0+x, y0+y, (fontchars[*str][y] & (128>>x)) ? 3 : 0); } void draw_score () { char buffer[80]; sprintf(buffer, "Score: %d", pts); draw_str(0, 192, buffer); } void hit_red_pixel () { draw_red_square(); ++pts; draw_score(); update_screen(); SDL_Delay(100); // noise(); } int main( int argc, char* args[] ) { int i, j; fontchars[' '] = fontchar_space; fontchars[':'] = fontchar_colon; fontchars['0'] = fontchar_0; fontchars['1'] = fontchar_1; fontchars['2'] = fontchar_2; fontchars['3'] = fontchar_3; fontchars['4'] = fontchar_4; fontchars['5'] = fontchar_5; fontchars['6'] = fontchar_6; fontchars['7'] = fontchar_7; fontchars['8'] = fontchar_8; fontchars['9'] = fontchar_9; fontchars['S'] = fontchar_S; fontchars['c'] = fontchar_c; fontchars['o'] = fontchar_o; fontchars['r'] = fontchar_r; fontchars['e'] = fontchar_e; SDL_Init(SDL_INIT_EVERYTHING); screen = SDL_SetVideoMode(640, 400, 32, SDL_SWSURFACE); SDL_WM_SetCaption("cga-tron", NULL); colors_rgb[0] = SDL_MapRGB(screen->format, 0, 0, 0); colors_rgb[1] = SDL_MapRGB(screen->format, 0, 255, 0); colors_rgb[2] = SDL_MapRGB(screen->format, 255, 0, 0); colors_rgb[3] = SDL_MapRGB(screen->format, 192, 128, 0); NEWGAME: for (i=0; i<=319; ++i) for (j=0; j<=200; ++j) pset(i, j, 0); for (i=0; i<=319; ++i) { pset(i, 0, 3); pset(i, 190, 3); } for (j=0; j<=190; ++j) { pset(0, j, 3); pset(319, j, 3); } x=150; y=90; dx=1; dy=0; pts=0; pset(x, y, 3); draw_red_square(); draw_score(); update_screen(); SDL_Delay(500); WALK: SDL_Delay(50); switch (get_event()) { case SDLK_UP: dx=0; dy=-1; break; case SDLK_DOWN: dx=0; dy=1; break; case SDLK_LEFT: dx=-1; dy=0; break; case SDLK_RIGHT: dx=1; dy=0; break; case SDLK_q: case SDLK_ESCAPE: goto END; case SDL_QUIT: goto CLOSE; } x=x+dx; y=y+dy; if (point[x][y] == 3) goto END; if (point[x][y] == 2) hit_red_pixel(); pset(x, y, 3); update_screen(); goto WALK; END: while (get_event()) {} // empty the event queue while (1) { SDL_Delay(50); switch (get_event()) { case SDLK_p: case SDLK_RETURN: case SDLK_SPACE: goto NEWGAME; case SDLK_q: case SDLK_ESCAPE: case SDL_QUIT: goto CLOSE; } } CLOSE: SDL_Quit(); return 0; }