diff --git a/Makefile b/Makefile index d707aff1..7b0a6a12 100644 --- a/Makefile +++ b/Makefile @@ -5,7 +5,7 @@ endif REMOTE=192.168.2.6 REMOTEUSER=sortie REMOTECOPYDIR:=/home/$(REMOTEUSER)/Desktop/MaxsiOS -MODULES=libmaxsi hello sortix +MODULES=libmaxsi hello pong sortix VERSION=0.4 DEBNAME:=sortix_$(VERSION)_$(CPU) diff --git a/pong/.gitignore b/pong/.gitignore new file mode 100644 index 00000000..4f2c5fac --- /dev/null +++ b/pong/.gitignore @@ -0,0 +1,7 @@ +*.o +*.tmp +*.bin +*.iso +*.so +*.a +pong diff --git a/pong/Makefile b/pong/Makefile new file mode 100644 index 00000000..a26f7a59 --- /dev/null +++ b/pong/Makefile @@ -0,0 +1,15 @@ +# Set up variables such that we can easily cross-compile. +OSROOT=.. +include ../crosscompilemakefile.mak + +all: pong + +pong: pong.o + $(LD) $(LDFLAGS) pong.o -o pong $(LIBS) + +pong.o: pong.cpp + $(CXX) $(CPPFLAGS) $(CXXFLAGS) -O2 -c pong.cpp -o pong.o + +clean: + rm -f pong.o pong + diff --git a/pong/pong.cpp b/pong/pong.cpp new file mode 100644 index 00000000..bfede80d --- /dev/null +++ b/pong/pong.cpp @@ -0,0 +1,206 @@ +#include +#include +#include +#include +#include +#include +#include + +using namespace Maxsi; +using namespace Maxsi::Keyboard; + +int Init(); +void Reset(); +void ClearScreen(); +void Collision(); +void Goal(nat 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; + +System::VGA::Frame* frame; + +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() +{ + frame = System::VGA::CreateFrame(); + if ( frame == NULL ) + { + StdOut::Print("Could not create VGA frame\n"); + return -1; + } + + System::VGA::ChangeFrame(frame->fd); + + Reset(); + + return 0; +} + +void Reset() +{ + ClearScreen(); + + ballx = width/2; + bally = height/2; + oldballx = ballx; + oldbally = bally; + ballvelx = -1; + ballvely = -1; + 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->text[x + y*width] = ' ' | color; + } + } +} + +void Collision() +{ + System::Sound::SetFrequency(collisionfreq); + soundleft = 40; +} + +void Goal(nat player) +{ + frame->text[ballx + bally*width] = ' ' | (COLOR8_WHITE << 8); + + ballx = width/2; + bally = height/2; + + if ( player == 1 ) + { + ballvelx = 1; + ballvely = 1; + p1score++; + } + else if ( player == 2 ) + { + ballvelx = -1; + ballvely = -1; + p2score++; + } + + System::Sound::SetFrequency(goalfreq); + soundleft = 50; + + UpdateUI(); +} + +void UpdateUI() +{ + for ( int x = 0; x < width; x++ ) { frame->text[x] = ' ' | (COLOR8_LIGHT_GREY << 12) | (COLOR8_RED << 8); } +} + +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->text[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->text[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->text[oldballx + oldbally*width] = ' ' | (COLOR8_WHITE << 8); + frame->text[ballx + bally*width] = '.' | (COLOR8_WHITE << 8); + oldballx = ballx; oldbally = bally; + + ballx += ballvelx; + bally += ballvely; + + frame->text[ballx + bally*width] = 'o' | (COLOR8_WHITE << 8); +} + +void ReadInput() +{ + unsigned method = System::Keyboard::POLL; + uint32_t codepoint; + while ( (codepoint = System::Keyboard::ReceieveKeystroke(method) ) != 0 ) + { + bool keyup = codepoint & DEPRESSED; + codepoint &= ~DEPRESSED; + + if ( codepoint == '\n' && keyup ) { Reset(); } + if ( codepoint == 'w' || codepoint == 'W' ) { p1vup = !keyup; } + if ( codepoint == 's' || codepoint == 'S' ) { p1vdown = !keyup; } + if ( codepoint == UP ) { p2vup = !keyup; } + if ( codepoint == DOWN ) { p2vdown = !keyup; } + } +} + +int main(int argc, char* argv[]) +{ + int result = Init(); + if ( result != 0 ) { return result; } + + while (true) + { + ReadInput(); + Update(); + UpdateUI(); + Thread::USleep(50 * 1000); + } + + return 0; +} +