#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; }