|
|
@@ -1,362 +0,0 @@ |
|
|
|
#include <iostream> |
|
|
|
#include <sys/ioctl.h> |
|
|
|
#include <stdio.h> |
|
|
|
#include <unistd.h> |
|
|
|
#include <chrono> |
|
|
|
#include <thread> |
|
|
|
#include <cmath> |
|
|
|
#include <stdlib.h> |
|
|
|
#include <ncurses.h> |
|
|
|
#include <pthread.h> |
|
|
|
#include <termios.h> |
|
|
|
#include <stdbool.h> |
|
|
|
#include <sys/select.h> |
|
|
|
#include <vector> |
|
|
|
#include <algorithm> |
|
|
|
#include <sys/socket.h> |
|
|
|
//#include <netinet/in.h> |
|
|
|
#include <string.h> |
|
|
|
#include <arpa/inet.h> |
|
|
|
#define PORT 5210 |
|
|
|
|
|
|
|
using namespace std; |
|
|
|
using namespace std::chrono; |
|
|
|
|
|
|
|
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(int argc, char const *argv[]){ |
|
|
|
|
|
|
|
//CLIENT STUFF |
|
|
|
struct sockaddr_in address; |
|
|
|
int sock = 0; |
|
|
|
struct sockaddr_in serv_addr; |
|
|
|
if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) { printf("\n Socket creation error \n");return -1; } |
|
|
|
memset(&serv_addr, '0', sizeof(serv_addr)); |
|
|
|
serv_addr.sin_family = AF_INET; |
|
|
|
serv_addr.sin_port = htons(PORT); |
|
|
|
if(inet_pton(AF_INET, "127.0.0.1", &serv_addr.sin_addr)<=0){ printf("\nInvalid address/ Address not supported \n"); return -1; } |
|
|
|
if (connect(sock, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0){ printf("\nConnection Failed \n"); return -1; } |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
///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); |
|
|
|
/// |
|
|
|
|
|
|
|
//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 fFOV = 3.14159 / 4.0; |
|
|
|
float fDepth = 32.0f; |
|
|
|
|
|
|
|
char *mapwRequest = (char*)"give mapw"; |
|
|
|
char bufferMapw[32] = {0}; |
|
|
|
send(sock , mapwRequest , strlen(mapwRequest) , 0 ); |
|
|
|
int getmapw = read( sock , bufferMapw, 32); |
|
|
|
string s_MapWidth = ("%s\n",bufferMapw); |
|
|
|
int nMapWidth = stoi(s_MapWidth); |
|
|
|
|
|
|
|
char *maphRequest = (char*)"give maph"; |
|
|
|
char bufferMaph[32] = {0}; |
|
|
|
send(sock , maphRequest , strlen(maphRequest) , 0 ); |
|
|
|
int getmaph = read( sock , bufferMaph, 32); |
|
|
|
string s_MapHeight = ("%s\n",bufferMaph); |
|
|
|
int nMapHeight = stoi(s_MapHeight); |
|
|
|
|
|
|
|
|
|
|
|
string map = ""; |
|
|
|
|
|
|
|
for (int i = 0; i < nMapHeight; i ++){ |
|
|
|
char *mapRequest = (char*)"give map"; |
|
|
|
char bufferMap[4096] = {0}; |
|
|
|
send(sock , mapRequest , strlen(mapRequest) , 0 ); |
|
|
|
int getmap = read( sock , bufferMap, 4096); |
|
|
|
map += ("%s\n",bufferMap ); |
|
|
|
} |
|
|
|
/* |
|
|
|
map += "################"; |
|
|
|
map += "#..............#"; |
|
|
|
map += "#####......#####"; |
|
|
|
map += "#..............#"; |
|
|
|
map += "#..........#####"; |
|
|
|
map += "#..............#"; |
|
|
|
map += "#####......#####"; |
|
|
|
map += "#####......#####"; |
|
|
|
map += "#####......#####"; |
|
|
|
map += "#####......#####"; |
|
|
|
map += "#####......#####"; |
|
|
|
map += "#..............#"; |
|
|
|
map += "#..............#"; |
|
|
|
map += "#####......#####"; |
|
|
|
map += "#..............#"; |
|
|
|
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 = 20.0f; |
|
|
|
|
|
|
|
/////////////////////////////////////////////////////////// |
|
|
|
/////////////////////////////////////////////////////////// |
|
|
|
/////////////////////////////////////////////////////////// |
|
|
|
////////BEGINDRAW///// |
|
|
|
/////////////////////////////////////////////////////////// |
|
|
|
/////////////////////////////////////////////////////////// |
|
|
|
/////////////////////////////////////////////////////////// |
|
|
|
while(bGameLoop){ |
|
|
|
|
|
|
|
|
|
|
|
tp2 = clock::now(); |
|
|
|
duration<float> 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 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
char *locxRequest = (char*)"give locx"; |
|
|
|
char *locyRequest = (char*)"give locy"; |
|
|
|
char *aRequest = (char*)"give a"; |
|
|
|
|
|
|
|
char buffer[32] = {0}; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
send(sock , locxRequest , strlen(locxRequest) , 0 ); |
|
|
|
int getlocx = read( sock , buffer, 32); |
|
|
|
string s_xPos = ("%s\n",buffer ); |
|
|
|
|
|
|
|
buffer[32] = {0}; |
|
|
|
send(sock , locyRequest , strlen(locyRequest) , 0 ); |
|
|
|
int getlocy = read( sock , buffer, 32); |
|
|
|
string s_yPos = ("%s\n",buffer ); |
|
|
|
|
|
|
|
buffer[32] = {0}; |
|
|
|
send(sock , aRequest , strlen(aRequest) , 0 ); |
|
|
|
int geta = read( sock , buffer, 32); |
|
|
|
string s_angle = ("%s\n",buffer ); |
|
|
|
|
|
|
|
|
|
|
|
fPlayerA = stof(s_angle)+3.14159*0.5; |
|
|
|
fPlayerX = stof(s_xPos); |
|
|
|
fPlayerY = stof(s_yPos); |
|
|
|
//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<pair<float, float>> 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<float, float> &left, const pair<float, float> &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.5f) 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.3) nShade = 32; //32 //very close |
|
|
|
else if (b < 0.55) nShade = 96; //96 |
|
|
|
else if (b < 0.8) nShade = 94; //94 |
|
|
|
else if (b < 0.9) nShade = 42; //42 |
|
|
|
else nShade = 32; //64 too far |
|
|
|
screen[y*nScreenWidth+x] = nShade; |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
writeStringToScreen(0, nScreenHeight-3,"Received from server: " + s_xPos+ " "+s_yPos+ " "+s_angle + " " + to_string(nMapWidth)+ " " + to_string(nMapHeight) + " "); |
|
|
|
|
|
|
|
|
|
|
|
//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; |
|
|
|
} |