commit 08403cbb582480b8be2202874a44a8323ee9df72 Author: Victor Giers Date: Mon Jan 21 14:53:06 2019 +0100 initial commit diff --git a/a.out b/a.out new file mode 100755 index 0000000..2f5166e Binary files /dev/null and b/a.out differ diff --git a/main.cpp b/main.cpp new file mode 100644 index 0000000..1a0dbab --- /dev/null +++ b/main.cpp @@ -0,0 +1,290 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +using namespace std; +using namespace std::chrono; + + +string init(string map){ + map += "################"; + map += "#..............#"; + map += "#####......#####"; + map += "#..............#"; + map += "#..........#####"; + map += "#..............#"; + map += "#####......#####"; + map += "#####......#####"; + map += "#####......#####"; + map += "#####......#####"; + map += "#####......#####"; + map += "#..............#"; + map += "#..............#"; + map += "#####......#####"; + map += "#..............#"; + map += "################"; + return (map); +} + +//#include + +char cInput[5]; +string debugMsg; + +bool bGameLoop = true; +int nScreenWidth; +int nScreenHeight; +string screen; + +float fPlayerX = 8.0f; +float fPlayerY = 8.0f; +float fPlayerA = 0.0f; +float fElapsedTime; +bool bMoveForward; +bool bMoveBackwards; +bool bTurnLeft; +bool bTurnRight; + +void *keyListener(void *tid){ + long id = (long) tid; + initscr(); + noecho(); + //raw(); + //cbreak(); + //nodelay(stdscr, TRUE); + //scrollok(stdscr, TRUE); + //raw(); + int c; + while ((c = getch()) != ERR){ + debugMsg = ""; + debugMsg+=to_string(c); + switch (c) { + case 119: //w + bMoveForward = true; + break; + case 97: //a + bTurnLeft = true; + break; + case 115: //s + bMoveBackwards = true; + break; + case 100: //d + bTurnRight = true; + break; + default: + break; + } + } + endwin(); + pthread_exit(NULL); +} + +void writeStringToScreen(int x, int y, string text){ + int s = (y*nScreenWidth)+x; + for (int i = s; i < s+text.length(); i++){ + screen[i] = text[i-s]; + } +} + +int main(){ + + ///I HAVE TO LOOK INTO THIS MORE + struct termios ttystate; + tcgetattr(STDIN_FILENO, &ttystate); + ttystate.c_lflag &= (~ICANON & ~ECHO); //Not display character + ttystate.c_cc[VMIN] = 1; + tcsetattr(STDIN_FILENO, TCSANOW, &ttystate); + /// + + bool keyStates[1000] = {false}; + int keyTimer[1000] = {0}; + //cInput = {'a','b'}; + //fputs("\e[?25h", stdout); //get cursor back /on signal abort ~ + //setterm(1); + pthread_t pThread[1]; + pthread_create(&pThread[0], NULL, keyListener, 0); + + struct winsize size; + ioctl(STDOUT_FILENO,TIOCGWINSZ,&size); + nScreenWidth = size.ws_col; + nScreenHeight = size.ws_row; + int nFrameRate = 60; + + int nMapHeight = 16; + int nMapWidth = 16; + float fFOV = 3.14159 / 4.0; + float fDepth = 16.0f; + string map = init(map); + system("kbdrate -d 250 -r 10"); + + + using clock = steady_clock; + auto tp1 = clock::now(); + auto tp2 = clock::now(); + + fputs("\e[?25l", stdout); //remove cursor*/ + + float fSpeedFactor = 1.0f; + + /////////////////////////////////////////////////////////// + /////////////////////////////////////////////////////////// + /////////////////////////////////////////////////////////// + ////////BEGINDRAW///// + /////////////////////////////////////////////////////////// + /////////////////////////////////////////////////////////// + /////////////////////////////////////////////////////////// + while(bGameLoop){ + + tp2 = clock::now(); + duration elapsedTime = tp2 - tp1; + tp1 = tp2; + fElapsedTime = elapsedTime.count(); + //dynamic terminal window size (on Window Resize) + ioctl(STDOUT_FILENO,TIOCGWINSZ,&size); + nScreenWidth = size.ws_col; + nScreenHeight = size.ws_row; + screen.clear(); + screen.resize(nScreenWidth*nScreenHeight); + cout << "\x1B[0;0H"; //reset cursor to 0,0 + + //fun part + + //this would be much better as class + if(bMoveForward){ + fPlayerX += fSpeedFactor*sinf(fPlayerA) * 5.0f * fElapsedTime; + fPlayerY += fSpeedFactor*cosf(fPlayerA) * 5.0f * fElapsedTime; + if(map[(int)fPlayerY * nMapWidth + (int)fPlayerX] == '#') + { + fPlayerX -= fSpeedFactor*sinf(fPlayerA) * 5.0f * fElapsedTime; + fPlayerY -= fSpeedFactor*cosf(fPlayerA) * 5.0f * fElapsedTime; + } + bMoveForward = false; + } + if(bMoveBackwards){ + fPlayerX -= fSpeedFactor*sinf(fPlayerA) * 5.0f * fElapsedTime; + fPlayerY -= fSpeedFactor*cosf(fPlayerA) * 5.0f * fElapsedTime; + if(map[(int)fPlayerY * nMapWidth + (int)fPlayerX] == '#') { + fPlayerX += fSpeedFactor*sinf(fPlayerA) * 5.0f * fElapsedTime; + fPlayerY += fSpeedFactor*cosf(fPlayerA) * 5.0f * fElapsedTime; + } + bMoveBackwards = false; + } + if(bTurnLeft){ + fPlayerA -= 0.15f; + bTurnLeft = false; + } + if(bTurnRight){ + fPlayerA += 0.15f; + bTurnRight = false; + } + + //shading part + for (int x = 0; x < nScreenWidth; x++){ + float fRayAngle = (fPlayerA - fFOV / 2.0f) + ((float)x / (float)nScreenWidth) * fFOV; + float fDistanceToWall = 0; + + bool bHitWall = false; + bool bBoundary = false; + + float fEyeX = sinf(fRayAngle); + float fEyeY = cosf(fRayAngle); + + while(!bHitWall && fDistanceToWall < fDepth){ + fDistanceToWall += 0.1f; + + int nTestX = (int)(fPlayerX + fEyeX * fDistanceToWall); + int nTestY = (int)(fPlayerY + fEyeY * fDistanceToWall); + + if(nTestX < 0 || nTestX >= nMapWidth || nTestY < 0 || nTestY >= nMapHeight){ + bHitWall = true; + fDistanceToWall = fDepth; + } else { + if(map[nTestY * nMapWidth + nTestX] == '#') + { + bHitWall = true; + vector> p; //distance, dot + for (int tx = 0; tx < 2; tx++) + for (int ty = 0; ty < 2; ty++) + { + float vy = (float)nTestY + ty - fPlayerY; + float vx = (float)nTestX + tx - fPlayerX; + float d = sqrt(vx*vx + vy*vy); + float dot = (fEyeX * vx / d) + (fEyeY * vy / d); + p.push_back(make_pair(d,dot)); + } + + sort(p.begin(), p.end(), [](const pair &left, const pair &right) { return left.first < right.first; }); + + float fBound = 0.005; + if (acos(p.at(0).second) < fBound) bBoundary = true; + if (acos(p.at(1).second) < fBound) bBoundary = true; + if (acos(p.at(2).second) < fBound) bBoundary = true; + } + + } + } + + int nCeiling = (float)(nScreenHeight / 2.0) - nScreenHeight / ((float)fDistanceToWall); + int nFloor = nScreenHeight - nCeiling; + + short nShade = 32; + + + for(int y = 0; y < nScreenHeight; y++){ + if(y < nCeiling) + screen[y*nScreenWidth+x] = ' '; + if(y > nCeiling && y <= nFloor){ + if (fDistanceToWall <= fDepth / 4.0f) nShade = 77; //very close + else if (fDistanceToWall < fDepth / 3.5f) nShade = 72; + else if (fDistanceToWall < fDepth / 3.0f) nShade = 84; + else if (fDistanceToWall < fDepth / 2.5f) nShade = 73; + else if (fDistanceToWall < fDepth / 2.0f) nShade = 105; + else if (fDistanceToWall < fDepth / 1.5) nShade = 58; + else if (fDistanceToWall < fDepth) nShade = 46; + else nShade = 32; // too far + if(bBoundary) nShade = '-'; + screen[y*nScreenWidth+x] = nShade; + } + else + { + float b = 1.0f - (((float)y - nScreenHeight / 2.0f) / ((float)nScreenHeight / 2.0f)); + if (b < 0.2) nShade = 32; //32 //very close + else if (b < 0.4) nShade = 96; //96 + else if (b < 0.7) nShade = 94; //94 + else if (b < 0.75) nShade = 42; //42 + else nShade = 32; //64 too far + screen[y*nScreenWidth+x] = nShade; + + } + } + } + + //writeStringToScreen(0, 0, "Key pressed: " + to_string(123) + " Key code: " + to_string(cInput)); + //writeStringToScreen(0, nScreenHeight-3, debugMsg); + writeStringToScreen(0, nScreenHeight-2, "Frame rate: " + to_string(1.0f / fElapsedTime) + " "); + writeStringToScreen(0, nScreenHeight-1, "Key pressed: " + debugMsg + " Angle: " + to_string(fPlayerA) + " X: " + to_string(fPlayerX) + " Y: " + to_string(fPlayerY) + " "); + + //string sInput(1, cInput[0]); + + cout << screen; //this is the renderer + //cout << ; + + + tp1 += milliseconds(1000 / nFrameRate); + this_thread::sleep_until(tp1); + + } + return 0; +} diff --git a/main_backup.cpp b/main_backup.cpp new file mode 100644 index 0000000..238dd35 --- /dev/null +++ b/main_backup.cpp @@ -0,0 +1,256 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +using namespace std; +using namespace std::chrono; + + +//#include +char cInput[5]; +string debugMsg; + +bool bGameLoop = true; +int nScreenWidth; +int nScreenHeight; +string screen; + + + int pressedKeys[10]; + +int khbit() +{ + struct timeval tv; + fd_set fds; + tv.tv_sec = 0; + tv.tv_usec = 0; + FD_ZERO(&fds); + FD_SET(STDIN_FILENO, &fds); + select(STDIN_FILENO+1, &fds, NULL, NULL, &tv); + return FD_ISSET(STDIN_FILENO, &fds); +} +void nonblock(int state) +{ + struct termios ttystate; + tcgetattr(STDIN_FILENO, &ttystate); + + if ( state == 1) + { + ttystate.c_lflag &= (~ICANON & ~ECHO); //Not display character + ttystate.c_cc[VMIN] = 1; + } + else if (state == 0) + { + ttystate.c_lflag |= ICANON; + } + tcsetattr(STDIN_FILENO, TCSANOW, &ttystate); +} +bool keyState(int key) //Use ASCII table +{ + bool pressed; + int i = khbit(); //Alow to read from terminal + if (i != 0) + { + char c = fgetc(stdin); + if (c == (char) key) pressed = true; + else pressed = false; + } else { + //pressed = 0; + } + return pressed; +} + +void *keyListener(void *tid){ + long id = (long) tid; + + //initscr(); + /*noecho(); + raw(); + cbreak(); + + nodelay(stdscr, TRUE); + scrollok(stdscr, TRUE); + */ + //raw(); + + while(bGameLoop){ + nonblock(1); + if(keyState(32)) debugMsg = "yo"; + debugMsg = to_string(keyState(32)); + if(keyState(32)) debugMsg = "yo"; + nonblock(0); + //int c; + //while ((c = getch()) != ERR) + // debugMsg+=to_string(c); + + /*if(getch() == 'a'){ + debugMsg = "wawawa"; + } else { + debugMsg = ""; + }*/ + //cInput[0] = getch(); + /*switch(getch()){ + case 'a': + debugMsg = "wawawa"; + break; + case 'ERR': + debugMsg = "error"; + break; + default: + debugMsg = " "; + break; + } */ + } + //endwin(); + pthread_exit(NULL); +} + + + + +void writeStringToScreen(int x, int y, string text){ + int s = (y*nScreenWidth)+x; + for (int i = s; i < s+text.length(); i++){ + screen[i] = text[i-s]; + } +} + +int main(){ + //cInput = {'a','b'}; + + //fputs("\e[?25h", stdout); //get cursor back /on signal abort ~ + //setterm(1); + pthread_t pThread[1]; + pthread_create(&pThread[0], NULL, keyListener, 0); + + + struct winsize size; + ioctl(STDOUT_FILENO,TIOCGWINSZ,&size); + + nScreenWidth = size.ws_col; + nScreenHeight = size.ws_row; + + + + int nFrameRate = 60; + + float fPlayerX = 8.0f; + float fPlayerY = 8.0f; + float fPlayerA = 0.0f; + + int nMapHeight = 16; + int nMapWidth = 16; + + float fFOV = 3.14159 / 4.0; + float fDepth = 16.0f; + + string map; + map += "################"; + map += "#..............#"; + map += "#..............#"; + map += "#..............#"; + map += "#..............#"; + map += "#..............#"; + map += "#..............#"; + map += "#..............#"; + map += "#..............#"; + map += "#..............#"; + map += "#..............#"; + map += "#..............#"; + map += "#..............#"; + map += "#..............#"; + map += "#..............#"; + map += "################"; + + + using clock = steady_clock; + auto tp1 = clock::now(); + auto tp2 = clock::now(); + + + fputs("\e[?25l", stdout); //remove cursor*/ + + while(bGameLoop){ + + tp2 = clock::now(); + duration elapsedTime = tp2 - tp1; + tp1 = tp2; + float fElapsedTime = elapsedTime.count(); + + + //dynamic terminal window size (on Window Resize) + ioctl(STDOUT_FILENO,TIOCGWINSZ,&size); + nScreenWidth = size.ws_col; + nScreenHeight = size.ws_row; + + + screen.clear(); + screen.resize(nScreenWidth*nScreenHeight); + + + cout << "\x1B[0;0H"; //reset cursor to 0,0 + + + for (int x = 0; x < nScreenWidth; x++){ + float fRayAngle = (fPlayerA - fFOV / 2.0f) + ((float)x / (float)nScreenWidth) * fFOV; + float fDistanceToWall = 0; + + bool bHitWall = false; + + float fEyeX = sinf(fRayAngle); + float fEyeY = cosf(fRayAngle); + + while(!bHitWall && fDistanceToWall < fDepth){ + fDistanceToWall += 0.1f; + + int nTestX = (int)(fPlayerX + fEyeX * fDistanceToWall); + int nTestY = (int)(fPlayerY + fEyeY * fDistanceToWall); + + if(nTestX < 0 || nTestX >= nMapWidth || nTestY < 0 || nTestY >= nMapHeight){ + bHitWall = true; + fDistanceToWall = fDepth; + } else { + if(map[nTestY * nMapWidth + nTestX] == '#'){ + bHitWall = true; + } + } + } + + int nCeiling = (float)(nScreenHeight / 2.0) - nScreenHeight / ((float)fDistanceToWall); + int nFloor = nScreenHeight - nCeiling; + + for(int y = 0; y < nScreenHeight; y++){ + if(y < nCeiling) + screen[y*nScreenWidth+x] = ' '; + if(y > nCeiling && y <= nFloor) + screen[y*nScreenWidth+x] = '#'; + else + screen[y*nScreenWidth+x] = ' '; + } + } + + //writeStringToScreen(0, 0, "Key pressed: " + to_string(123) + " Key code: " + to_string(cInput)); + //writeStringToScreen(0, nScreenHeight-3, debugMsg); + writeStringToScreen(0, nScreenHeight-2, "Frame rate: " + to_string(1.0f / fElapsedTime) + " limited to " + to_string(nFrameRate)); + //string sInput(1, cInput[0]); + writeStringToScreen(0, nScreenHeight-1, debugMsg); + + + cout << screen; //this is the renderer + //cout << ; + + tp1 += milliseconds(1000 / nFrameRate); + this_thread::sleep_until(tp1); + + } + + return 0; +}