diff --git a/doc/user-guide b/doc/user-guide index 10d9ec7f..91b7f998 100644 --- a/doc/user-guide +++ b/doc/user-guide @@ -38,8 +38,7 @@ limited but works on most systems. You can change the display resolution using the `chvideomode` program. However, you need a suitable kernel driver to do the mode setting. The current release only has a simple BGA driver, which works in virtual machines such as Qemu, -VirtualBox or Bochs. Note that some programs does not work outside of VGA Text -Mode because the dispd library doesn't yet have a VGA->framebuffer converter. +VirtualBox or Bochs. The BGA driver can support virtually any resolution, but since the interface fails to report which resolutions are appropriate in the current context, I have @@ -152,7 +151,6 @@ Sortix comes with a number of home-made programs. Here is an overview: * `clear` - clear terminal * `colormake` - colorful version of make (if make is available) * `column` - format lines nicely in columns -* `conway` - game of life simulator * `cp` - copy file * `date` - display current time and date * `dirname` - strip last component from file name @@ -180,14 +178,12 @@ Sortix comes with a number of home-made programs. Here is an overview: * `mkinitrd` - create an initrd * `mv` - move a file * `pager` - display file page by page -* `pong` - remake of the classic pong game * `pwd` - print current directory path * `regress` - run system tests * `rm` - remove file * `rmdir` - remove empty directory * `sh` - alias for the shell * `sleep` - delay for a specified amount of time -* `snake` - remake of the classic snake game * `sort` - sort lines of text files * `tail` - display end of file * `time` - measure program running time @@ -278,26 +274,6 @@ Included Games The system comes with a number of small casual games. Note that some games require running in the correct display mode before they will function. -### Pong ### - -The program `pong` implements a simple pong clone that uses the VGA text mode -buffer. Player one controls using `W` and `S`, while player two controls using -the arrow keys. This program is only available in VGA mode. - -### Snake ### - -This is a simple snake clone that only works in VGA text mode. You control the -snake using the `W`, `S`, `A`, and `D` keys. To run, start the program `snake`. -This program is only available in VGA mode. - -### Conway's Game of Life ### - -You can do turing-complete calculations in the classic Game of Life in the VGA -text mode buffer. Simply start the program `conway` and use `W`, `A`, `S`, and -`D` to navigate the screen. `Space` toggles the current point between live and -dead. `C` clears the entire screen, and `R` starts and stops the simulation. -This program is only available in VGA mode. - ### Asteroids ### Mine for crystals in an asteroid field! Start the `asteroids` program and if you @@ -481,8 +457,8 @@ likely want to recompile large parts of user-land if you update this library. The dispd library allows processes to communicate with the dispd server that handles window management and graphical output. Currently, there is no such server and the library calls the kernel interface itself. This library allows -games such as asteroids and pong to detect the current resolution and request -whatever resolution they need to function. +games such as asteroids to detect the current resolution and request whatever +resolution they need to function. cd /src/dispd make diff --git a/games/.gitignore b/games/.gitignore index d43d4580..38b8d6fb 100644 --- a/games/.gitignore +++ b/games/.gitignore @@ -4,7 +4,4 @@ *.iso *.so *.a -pong -conway -snake asteroids diff --git a/games/Makefile b/games/Makefile index 20b8eebf..6ca7def7 100644 --- a/games/Makefile +++ b/games/Makefile @@ -9,9 +9,6 @@ CXXFLAGS?=$(OPTLEVEL) CXXFLAGS:=$(CXXFLAGS) -Wall -Wextra -fno-exceptions -fno-rtti BINARIES:=\ -pong \ -conway \ -snake \ asteroids \ LIBS:=-ldispd diff --git a/games/conway.cpp b/games/conway.cpp deleted file mode 100644 index eccf2aca..00000000 --- a/games/conway.cpp +++ /dev/null @@ -1,210 +0,0 @@ -/******************************************************************************* - - Copyright(C) Jonas 'Sortie' Termansen 2011, 2012. - - This program is free software: you can redistribute it and/or modify it - under the terms of the GNU General Public License as published by the Free - Software Foundation, either version 3 of the License, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - more details. - - You should have received a copy of the GNU General Public License along with - this program. If not, see . - - conway.cpp - Conway's Game of Life. - -*******************************************************************************/ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -const int width = 80; -const int height = 25; - -const int rowstride = width + 2; -const int buffersize = (height+2) * (width+2); - -uint16_t frame[width*height]; - -bool running; -int posx; -int posy; - -char framea[buffersize]; -char frameb[buffersize]; -char* currentframe; -char* lastframe; - -void Clear() -{ - // Reset the game data. - for ( int i = 0; i < buffersize; i++ ) { framea[i] = 0; frameb[i] = 0; } -} - -int Init() -{ - Clear(); - - // Initialize variables. - currentframe = framea; - lastframe = frameb; - - running = false; - posy = height / 2 + 1; - posx = width / 2 + 1; - - return 0; -} - -void Cycle() -{ - // Run a cycle of the game of life. - for ( int y = 1; y <= height; y++ ) - { - for ( int x = 1; x <= width; x++ ) - { - int alivearound = 0; - int current = lastframe[y * rowstride + x]; - - if ( lastframe[(y-1) * rowstride + (x-1)] > 0 ) { alivearound++; } - if ( lastframe[(y-1) * rowstride + (x-0)] > 0 ) { alivearound++; } - if ( lastframe[(y-1) * rowstride + (x+1)] > 0 ) { alivearound++; } - if ( lastframe[(y-0) * rowstride + (x-1)] > 0 ) { alivearound++; } - if ( lastframe[(y-0) * rowstride + (x+1)] > 0 ) { alivearound++; } - if ( lastframe[(y+1) * rowstride + (x-1)] > 0 ) { alivearound++; } - if ( lastframe[(y+1) * rowstride + (x-0)] > 0 ) { alivearound++; } - if ( lastframe[(y+1) * rowstride + (x+1)] > 0 ) { alivearound++; } - - currentframe[y * rowstride + x] = ( (current > 0 && (alivearound == 3 || alivearound == 2)) || (current == 0 && alivearound == 3) ) ? 1 : 0; - } - } - - // Swap buffers. - char* tmp = lastframe; lastframe = currentframe; currentframe = tmp; -} - -void Render() -{ - uint16_t* dest = frame; - - uint16_t set = 'O' | (COLOR8_LIGHT_GREY << 8); - uint16_t unset = ' ' | (COLOR8_LIGHT_GREY << 8); - - // Render each cell directly to the VGA framebuffer! - for ( int y = 1; y <= height; y++ ) - { - for ( int x = 1; x <= width; x++ ) - { - dest[(y-1) * width + (x-1)] = (lastframe[y * rowstride + x] > 0) ? set : unset; - - // Render the cursor. - if ( !running && x == posx && y == posy ) - { - dest[(y-1) * width + (x-1)] |= (COLOR8_RED << 12); - } - } - } -} - -void Update() -{ - // Read the keyboard input from the user. - unsigned termmode = TERMMODE_KBKEY - | TERMMODE_UNICODE - | TERMMODE_SIGNAL - | TERMMODE_NONBLOCK; - if ( settermmode(0, termmode) ) { error(1, errno, "settermmode"); } - while ( true ) - { - uint32_t codepoint; - ssize_t numbytes = read(0, &codepoint, sizeof(codepoint)); - if ( !numbytes ) { break; } - if ( numbytes < 0 ) { break; } - int kbkey = KBKEY_DECODE(codepoint); - if ( kbkey == KBKEY_R ) { running = !running; } - if ( running ) { continue; } - if ( kbkey == KBKEY_C ) { Clear(); } - if ( kbkey == KBKEY_W ) { if ( posy > 1 ) { posy--; } } - if ( kbkey == KBKEY_A ) { if ( posx > 1 ) { posx--; } } - if ( kbkey == KBKEY_S ) { if ( posy < height ) { posy++; } } - if ( kbkey == KBKEY_D ) { if ( posx < width ) { posx++; } } - if ( kbkey == KBKEY_SPACE ) - { - lastframe[posy * rowstride + posx] = 1 - lastframe[posy * rowstride + posx]; - } - } - - // Run a cycle. - if ( running ) { Cycle(); } - - Render(); -} - -int usage(int /*argc*/, char* argv[]) -{ - printf("usage: %s [OPTIONS]\n", argv[0]); - printf("Options:\n"); - printf(" --speed How many miliseconds between updates\n"); - printf(" --usage Display this screen\n"); - printf(" --help Display this screen\n"); - - return 0; -} - -int main(int argc, char* argv[]) -{ - if ( !dispd_initialize(&argc, &argv) ) - error(1, 0, "couldn't initialize dispd library"); - - int sleepms = 50; - for ( int i = 1; i < argc; i++ ) - { - if ( strcmp(argv[i], "--help") == 0 ) { return usage(argc, argv); } - if ( strcmp(argv[i], "--usage") == 0 ) { return usage(argc, argv); } - if ( strcmp(argv[i], "--speed") == 0 && 1 < argc-i ) - { - sleepms = atoi(argv[++i]); - } - } - - int result = Init(); - if ( result != 0 ) { return result; } - - struct dispd_session* session = dispd_attach_default_session(); - if ( !session ) - error(1, 0, "couldn't attach to dispd default session"); - if ( !dispd_session_setup_game_vga(session) ) - error(1, 0, "couldn't setup dispd vga session"); - struct dispd_window* window = dispd_create_window_game_vga(session); - if ( !window ) - error(1, 0, "couldn't create dispd vga window"); - - // Update the game every 50th milisecond. - while ( true ) - { - usleep(sleepms * 1000); - Update(); - struct dispd_framebuffer* fb = dispd_begin_render(window); - if ( !fb ) - error(1, 0, "unable to begin rendering dispd window"); - memcpy(dispd_get_framebuffer_data(fb), frame, sizeof(frame)); - dispd_finish_render(fb); - } - - return 0; -} diff --git a/games/pong.cpp b/games/pong.cpp deleted file mode 100644 index 17123e0b..00000000 --- a/games/pong.cpp +++ /dev/null @@ -1,287 +0,0 @@ -/******************************************************************************* - - Copyright(C) Jonas 'Sortie' Termansen 2011, 2012. - - This program is free software: you can redistribute it and/or modify it - under the terms of the GNU General Public License as published by the Free - Software Foundation, either version 3 of the License, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - more details. - - You should have received a copy of the GNU General Public License along with - this program. If not, see . - - pong.cpp - Two-player pong. - -*******************************************************************************/ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -int Init(); -void Reset(); -void ClearScreen(); -void Collision(); -void Goal(unsigned player); -void UpdateUI(); -void Update(); -void ReadInput(); -int main(int argc, char* argv[]); - -const int width = 80; -const int height = 25; -const int padsize = 5; - -const unsigned goalfreq = 800; -const unsigned collisionfreq = 1200; - -uint16_t frame[width*height]; - -int ballx; -int bally; -int oldballx; -int oldbally; -int ballvelx; -int ballvely; -int p1y; -int p2y; -bool p1vup; -bool p1vdown; -bool p2vup; -bool p2vdown; -unsigned p1score; -unsigned p2score; -unsigned time; -unsigned soundleft; - -int Init() -{ - Reset(); - return 0; -} - -void Reset() -{ - ClearScreen(); - - ballx = width/2; - bally = height/2; - ballvelx = -1; - ballvely = -1; - oldballx = ballx - ballvelx; - oldbally = bally - ballvely; - p1y = (height-padsize) / 5; - p2y = (height-padsize) / 5; - p1vup = false; - p1vdown = false; - p2vup = false; - p2vdown = false; - p1score = 0; - p2score = 0; - time = 0; - soundleft = -1; -} - -void ClearScreen() -{ - for ( int y = 0; y < height; y++ ) - { - uint16_t color = COLOR8_BLACK << 8; - - for ( int x = 0; x < width; x++ ) - { - frame[x + y*width] = ' ' | color; - } - } -} - -void Collision() -{ - //System::Sound::SetFrequency(collisionfreq); - soundleft = 40; -} - -void Goal(unsigned player) -{ - frame[ballx + bally*width] = ' ' | (COLOR8_WHITE << 8); - - int offset = (rand() % 4) - 2; - ballx = width/2; - bally = height/2 + offset; - - if ( player == 1 ) - { - ballvelx = 1; - ballvely = (rand() % 2) * 2 - 1; - p1score++; - } - else if ( player == 2 ) - { - ballvelx = -1; - ballvely = (rand() % 2) * 2 - 1; - p2score++; - } - - if ( ballvely > 0 ) { ballvely /= ballvely; } - if ( ballvely < 0 ) { ballvely /= -ballvely; } - - //System::Sound::SetFrequency(goalfreq); - soundleft = 50; - - UpdateUI(); -} - -void UpdateUI() -{ - for ( int x = 0; x < width; x++ ) { frame[x] = ' ' | (COLOR8_LIGHT_GREY << 12) | (COLOR8_RED << 8); } - - char num[12]; - int len; - - len = sprintf(num, "%u", p1score); - for ( int i = 0; i < len; i++ ) { frame[i] = ( frame[i] & 0xFF00 ) | num[i]; } - - len = sprintf(num, "%u", p2score); - for ( int i = 0; i < len; i++ ) { frame[width - len + i] = ( frame[width - len + i] & 0xFF00 ) | num[i]; } -} - -void Update() -{ - int p1v = 0, p2v = 0; - - if ( p1vup && !p1vdown ) { p1v = -1; } else if ( !p1vup && p1vdown ) { p1v = 1; } - if ( p2vup && !p2vdown ) { p2v = -1; } else if ( !p2vup && p2vdown ) { p2v = 1; } - - if ( p1v < 0 && p1y > 1 ) { p1y--; } - if ( p1v > 0 && p1y + padsize < height ) { p1y++; } - if ( p2v < 0 && p2y > 1 ) { p2y--; } - if ( p2v > 0 && p2y + padsize < height ) { p2y++; } - - for ( int y = 1; y < height; y++ ) - { - uint16_t color = ( y < p1y || y >= p1y + padsize ) ? COLOR8_BLACK << 12 : COLOR8_RED << 12; frame[y*width] = ' ' | color; - } - - for ( int y = 1; y < height; y++ ) - { - uint16_t color = ( y < p2y || y >= p2y + padsize ) ? COLOR8_BLACK << 12 : COLOR8_BLUE << 12; frame[width-1 + y*width] = ' ' | color; - } - - if ( bally + ballvely <= 1 ) { ballvely = 0 - ballvely; Collision(); } - if ( bally + ballvely >= height ) { ballvely = 0 - ballvely; Collision(); } - - if ( ballx + ballvelx < 1 ) { if ( bally + ballvely < p1y - 1 || bally + ballvely > p1y + padsize + 1 ) { Goal(2); } else { ballvelx = 0 - ballvelx; Collision(); } } - if ( ballx + ballvelx >= width-1 ) { if ( bally + ballvely < p2y - 1 || bally + ballvely > p2y + padsize + 1 ) { Goal(1); } else { ballvelx = 0 - ballvelx; Collision(); } } - - frame[oldballx + oldbally*width] = ' ' | (COLOR8_WHITE << 8); - frame[ballx + bally*width] = '.' | (COLOR8_WHITE << 8); - oldballx = ballx; oldbally = bally; - - ballx += ballvelx; - bally += ballvely; - - frame[ballx + bally*width] = 'o' | (COLOR8_WHITE << 8); -} - -void ReadInput() -{ - unsigned termmode = TERMMODE_KBKEY - | TERMMODE_UNICODE - | TERMMODE_SIGNAL - | TERMMODE_NONBLOCK; - if ( settermmode(0, termmode) ) { error(1, errno, "settermmode"); } - while ( true ) - { - uint32_t codepoint; - ssize_t numbytes = read(0, &codepoint, sizeof(codepoint)); - if ( !numbytes ) { return; } - if ( numbytes < 0 ) { return; } - int kbkey = KBKEY_DECODE(codepoint); - int abskbkey = (kbkey < 0) ? -kbkey : kbkey; - if ( kbkey == KBKEY_ENTER ) { Reset(); } - if ( abskbkey == KBKEY_W ) { p1vup = (0 < kbkey); } - if ( abskbkey == KBKEY_S ) { p1vdown = (0 < kbkey); } - if ( abskbkey == KBKEY_UP ) { p2vup = (0 < kbkey); } - if ( abskbkey == KBKEY_DOWN ) { p2vdown = (0 < kbkey); } - } -} - -int usage(int /*argc*/, char* argv[]) -{ - printf("usage: %s [OPTIONS]\n", argv[0]); - printf("Options:\n"); - printf(" --speed How many miliseconds between updates\n"); - printf(" --usage Display this screen\n"); - printf(" --help Display this screen\n"); - - return 0; -} - -int main(int argc, char* argv[]) -{ - if ( !dispd_initialize(&argc, &argv) ) - error(1, 0, "couldn't initialize dispd library"); - - int sleepms = 50; - for ( int i = 1; i < argc; i++ ) - { - if ( strcmp(argv[i], "--help") == 0 ) { return usage(argc, argv); } - if ( strcmp(argv[i], "--usage") == 0 ) { return usage(argc, argv); } - if ( strcmp(argv[i], "--speed") == 0 && 1 < argc-i ) - { - sleepms = atoi(argv[++i]); - } - } - - int result = Init(); - if ( result != 0 ) { return result; } - - struct dispd_session* session = dispd_attach_default_session(); - if ( !session ) - error(1, 0, "couldn't attach to dispd default session"); - if ( !dispd_session_setup_game_vga(session) ) - error(1, 0, "couldn't setup dispd vga session"); - struct dispd_window* window = dispd_create_window_game_vga(session); - if ( !window ) - error(1, 0, "couldn't create dispd vga window"); - - while (true) - { - usleep(sleepms * 1000); - ReadInput(); - Update(); - UpdateUI(); - struct dispd_framebuffer* fb = dispd_begin_render(window); - if ( !fb ) - error(1, 0, "unable to begin rendering dispd window"); - memcpy(dispd_get_framebuffer_data(fb), frame, sizeof(frame)); - dispd_finish_render(fb); - - if ( /*soundleft < 0*/ false ) { continue; } - if ( soundleft <= 50 ) - { - //System::Sound::SetFrequency(0); - } - else - { - soundleft -= sleepms; - } - } - - return 0; -} diff --git a/games/snake.cpp b/games/snake.cpp deleted file mode 100644 index 01dd0e69..00000000 --- a/games/snake.cpp +++ /dev/null @@ -1,234 +0,0 @@ -/******************************************************************************* - - Copyright(C) Jonas 'Sortie' Termansen 2011, 2012. - - This program is free software: you can redistribute it and/or modify it - under the terms of the GNU General Public License as published by the Free - Software Foundation, either version 3 of the License, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - more details. - - You should have received a copy of the GNU General Public License along with - this program. If not, see . - - snake.cpp - Single-player snake. - -*******************************************************************************/ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -const int width = 80; -const int height = 25; - -const int buffersize = height * width; - -uint16_t frame[width*height]; - -int posx; -int posy; -int velx; -int vely; -int tailx; -int taily; -int taillen; -int tailmax; -int animalx; -int animaly; - -char direction[buffersize]; - -uint16_t animal = '%' | (COLOR8_RED<<8); -uint16_t snake = ' ' | (COLOR8_GREEN<<12); - -const int defaultspeed = 75; -const int speedincrease = -5; -const int maxspeed = 40; -volatile int speed; - -bool tabhack = false; - -void Clear() -{ - // Reset the game data. - for ( int i = 0; i < buffersize; i++ ) { frame[i] = ' '; direction[i] = -1; } -} - -void Reset() -{ - Clear(); - tailx = posx = width/2; - taily = posy = height/2; - switch ( rand() % 4 ) - { - case 0: velx = -1; vely = 0; break; - case 1: velx = 1; vely = 0; break; - case 2: velx = 0; vely = -1; break; - case 3: velx = 0; vely = -1; break; - } - - animalx = 2 + (rand() % (width-4)); - animaly = 2 + (rand() % (height-4)); - - taillen = 0; - tailmax = 3; - - frame[animaly * width + animalx] = animal; - - speed = defaultspeed; -} - -int Init() -{ - Reset(); - return 0; -} - -bool tabhacking = false; - -void Update() -{ - int newvelx = velx; - int newvely = vely; - - // Read the keyboard input from the user. - unsigned termmode = TERMMODE_KBKEY - | TERMMODE_UNICODE - | TERMMODE_SIGNAL - | TERMMODE_NONBLOCK; - if ( settermmode(0, termmode) ) { error(1, errno, "settermmode"); } - while ( true ) - { - uint32_t codepoint; - ssize_t numbytes = read(0, &codepoint, sizeof(codepoint)); - if ( !numbytes ) { break; } - if ( numbytes < 0 ) { break; } - int kbkey = KBKEY_DECODE(codepoint); - int abskbkey = (kbkey < 0) ? -kbkey : kbkey; - if ( tabhack && abskbkey == KBKEY_TAB ) { tabhacking = (0 < kbkey); } - if ( kbkey == KBKEY_ENTER ) { Reset(); return; } - if ( kbkey == KBKEY_W ) { newvelx = 0; newvely = -1; } - if ( kbkey == KBKEY_A ) { newvelx = -1; newvely = 0; } - if ( kbkey == KBKEY_S ) { newvelx = 0; newvely = 1; } - if ( kbkey == KBKEY_D ) { newvelx = 1; newvely = 0; } - } - - if ( tabhack && tabhacking ) - { - if ( animalx == posx && posy < animaly ) { newvelx = 0; newvely = 1; } - if ( animalx == posx && posy > animaly ) { newvelx = 0; newvely = -1; } - if ( animaly == posy && posx < animalx ) { newvelx = 1; newvely = 0; } - if ( animaly == posy && posx > animalx ) { newvelx = -1; newvely = 0; } - } - - // Make sure we don't do a 180. - if ( !(velx == -1 && newvelx == 1) && - !(velx == 1 && newvelx == -1) && - !(vely == -1 && newvely == 1) && - !(vely == 1 && newvely == -1) ) - { - velx = newvelx; vely = newvely; - } - - // Don't collide with the border! - if ( posx + velx < 0 || width <= posx + velx || - posy + vely < 0 || height <= posy + vely ) { Reset(); return; } - - int newx = posx + velx; - int newy = posy + vely; - - // Move the tail, if needed. - if ( taillen == tailmax ) - { - frame[taily * width + tailx] = ' '; taillen--; - switch ( direction[taily * width + tailx] ) - { - case 0: tailx--; break; - case 1: tailx++; break; - case 2: taily--; break; - case 3: taily++; break; - } - } - - // Check for collision. - if ( frame[newy * width + newx] == snake ) { Reset(); return; } - - // Check for food. - if ( newx == animalx && newy == animaly ) - { - tailmax++; - animalx = 2 + (rand() % (width-4)); - animaly = 2 + (rand() % (height-4)); - assert(0 <= animalx && animalx < width); - assert(0 <= animaly && animaly < height); - if ( maxspeed < speed ) { speed += speedincrease; } - } - - frame[animaly * width + animalx] = animal; - - // Remember where we are going. - int dir = 0; - if ( velx < 0 ) { dir = 0; } - if ( velx > 0 ) { dir = 1; } - if ( vely < 0 ) { dir = 2; } - if ( vely > 0 ) { dir = 3; } - direction[posy * width + posx] = dir; - - // Move the head. - posx = newx; - posy = newy; - frame[posy * width + posx] = snake; taillen++; -} - -int main(int argc, char* argv[]) -{ - if ( !dispd_initialize(&argc, &argv) ) - error(1, 0, "couldn't initialize dispd library"); - - for ( int i = 1; i < argc; i++ ) - { - if ( strcmp("--tabhack", argv[i]) == 0 ) { tabhack = true; } - } - - int result = Init(); - if ( result != 0 ) { return result; } - - struct dispd_session* session = dispd_attach_default_session(); - if ( !session ) - error(1, 0, "couldn't attach to dispd default session"); - if ( !dispd_session_setup_game_vga(session) ) - error(1, 0, "couldn't setup dispd vga session"); - struct dispd_window* window = dispd_create_window_game_vga(session); - if ( !window ) - error(1, 0, "couldn't create dispd vga window"); - - // Update the game every once in a while. - while ( true ) - { - usleep(speed * 1000); - Update(); - struct dispd_framebuffer* fb = dispd_begin_render(window); - if ( !fb ) - error(1, 0, "unable to begin rendering dispd window"); - memcpy(dispd_get_framebuffer_data(fb), frame, sizeof(frame)); - dispd_finish_render(fb); - } - - return 0; -}