diff --git a/Makefile b/Makefile index bb7b660..828784b 100644 --- a/Makefile +++ b/Makefile @@ -38,6 +38,7 @@ COMMON_OBJS := \ SERVER_OBJS := \ $(OBJDIR)/src/server_main.o \ $(OBJDIR)/src/Server.o \ + $(OBJDIR)/src/Commands.o \ $(COMMON_OBJS) CLIENT_OBJS := \ diff --git a/glsl/new.f.glsl b/glsl/new.f.glsl index 18463e9..50bd4ec 100644 --- a/glsl/new.f.glsl +++ b/glsl/new.f.glsl @@ -2,14 +2,21 @@ /* */ -void mainImage(out vec4 fragColor, in vec2 fragCoord) { - // Normalized pixel coordinates (from 0 to 1) - vec2 uv = TexCoords; // fragCoord / iResolution.xy; - // vec2 uv = fragCoord / iResolution.xy; +void +mainImage (out vec4 fragColor, in vec2 fragCoord) +{ + // Normalized pixel coordinates (from 0 to 1) + // vec2 uv = fragCoord.xy / iResolution.xy; - // Time varying pixel color - vec3 col = 0.5 + 0.5 * cos(iTime + fract (1.5 * (0.5 - uv.xyx) / (0.5 - uv.yxy) + iTime) + vec3(0, 2, 4)); + // Texture coordinates + vec2 uv = TexCoords; - // Output to screen - fragColor = vec4(col, 1.0); + // float du = 1.0 / iResolution.y; + // vec2 uv = du * (fragCoord.xy - (0.5 * iResolution.xy)); + + // Time varying pixel color + vec3 col = 0.5 + 0.5 * cos (iTime + uv.xyx + vec3 (0, 2, 4)); + + // Output to screen + fragColor = vec4 (col, 1.0); } diff --git a/include/Commands.h b/include/Commands.h new file mode 100644 index 0000000..bf3f3c7 --- /dev/null +++ b/include/Commands.h @@ -0,0 +1,36 @@ +#pragma once + +#include +#include + +class +Command +{ + std::string m_name; + + Command (const std::string& name) + : m_name (name) + { + } +}; + +/* + * Function pointer type that returns true if we should stop processing input, + * false otherwise. + */ +#define COMMANDHELPERFUNC(x) bool x (const std::string&) + +typedef COMMANDHELPERFUNC((*CommandHelperFunc)); + +COMMANDHELPERFUNC(command_Quit); +COMMANDHELPERFUNC(command_Help); +COMMANDHELPERFUNC(command_Echo); +COMMANDHELPERFUNC(command_Shell); + +const std::map CommandFunctionList = +{ + { "quit", command_Quit, }, + { "help", command_Help, }, + { "echo", command_Echo, }, + { "shell", command_Shell, }, +}; diff --git a/include/Server.h b/include/Server.h index 57356c8..1b8a880 100644 --- a/include/Server.h +++ b/include/Server.h @@ -13,8 +13,6 @@ class Server : public UDPbase SDL_mutex* mProcessPacketMutex; SDL_TimerID mFetchPacketsCallbackTimerID; - std::vector TCPsocks; - std::vector UDPsocks; SDLNet_SocketSet SocketSet; UDPpacket** packetV; lua_State *mLuaState; @@ -31,11 +29,13 @@ class Server : public UDPbase static Uint32 FetchPacketsCallback (Uint32 interval, void* param); void ProcessPacketHelper (UDPpacket* packet); + void RunLua (const std::string& buf); + int AllocateApproximateResources (const int nclients); + int Start (void); int Stop (void); - void CloseAllSockets (void); int Lock (void) { return SDL_LockMutex (mProcessPacketMutex); @@ -44,8 +44,8 @@ class Server : public UDPbase { return SDL_UnlockMutex (mProcessPacketMutex); } + lua_State* getLuaState(void) { return mLuaState; } - TCPsocket getTCPsock (size_t idx) { return TCPsocks.at (idx); } UDPsocket getUDPsock (size_t idx) { return UDPsocks.at (idx); } UDPpacket** getPacketV (void) { return packetV; } SDLNet_SocketSet getSocketSet (void) { return SocketSet; } diff --git a/include/UDPbase.h b/include/UDPbase.h index 743543d..c3a37ef 100644 --- a/include/UDPbase.h +++ b/include/UDPbase.h @@ -1,21 +1,36 @@ #pragma once #include +#include + #include #define DEFAULT_MAX_PACKET_SIZE 250 class UDPbase { + int mChannel; IPaddress mIPAddress; + protected: + std::vector UDPsocks; public: UDPbase (const char* host, const Uint16 port); + UDPbase (const char* host, const Uint16 port, const int channel); ~UDPbase (void); - UDPsocket Open (void); - UDPsocket Open (const Uint16 port); - void Close (UDPsocket sock); - int Bind (UDPsocket sock, const int channel); - void Unbind (UDPsocket sock, const int channel); + + int ResolveHost (IPaddress*, const char*, const Uint16); + + UDPsocket UDP_Open (void); + UDPsocket UDP_Open (const Uint16 port); + void UDP_Close (UDPsocket sock); + int UDP_Bind (UDPsocket sock, const int channel); + void UDP_Unbind (UDPsocket sock, const int channel); + IPaddress* UDP_GetPeerAddress (UDPsocket sock, const int channel); + + void CloseAllSockets (void); + + int getChannel (void) const { return mChannel; } + UDPsocket getSocket (const size_t idx) const { return UDPsocks.at (idx); } + std::string toString (void); - IPaddress* GetPeerAddress (UDPsocket sock, const int channel); }; diff --git a/include/UDPpacketVBuffer.h b/include/UDPpacketVBuffer.h index f47dbdd..5b10559 100644 --- a/include/UDPpacketVBuffer.h +++ b/include/UDPpacketVBuffer.h @@ -50,8 +50,11 @@ class UDPpacketVBuffer } int Send (UDPsocket sock) { - int numsent; - numsent = SDLNet_UDP_SendV (sock, packetV, npackets); + int numsent = 0; + if (packetV) + { + numsent = SDLNet_UDP_SendV (sock, packetV, npackets); + } return numsent; } }; diff --git a/include/cube_triangle_strip.h b/include/cube_triangle_strip.h new file mode 100644 index 0000000..b896f16 --- /dev/null +++ b/include/cube_triangle_strip.h @@ -0,0 +1,12 @@ +#include "object.h" + +class CubeTriangleStrip : Object +{ + public: + CubeTriangleStrip (void) + { + } + CubeTriangleStrip (const GLsizei); + + void Draw (void); +}; diff --git a/src/Commands.cpp b/src/Commands.cpp new file mode 100644 index 0000000..2f8d5d1 --- /dev/null +++ b/src/Commands.cpp @@ -0,0 +1,42 @@ +#include "Commands.h" +#include "unused.h" + +#include + +bool command_Quit (const std::string& args) +{ + UNUSED (args); + SDL_Log ("byebye!"); + return true; +} + + +bool command_Help (const std::string& args) +{ + UNUSED (args); + SDL_Log ("I'm helping!"); + return false; +} + +bool command_Echo (const std::string& args) +{ + SDL_Log ("%s", args.c_str ()); + return false; +} + +bool command_Shell (const std::string& args) +{ + int rc; + if (args.empty ()) + { + } + else + { + c = system (args.c_str ()); + switch (rc) + { + } + } + + return false; +} diff --git a/src/Server.cpp b/src/Server.cpp index 1cb3770..70ab889 100644 --- a/src/Server.cpp +++ b/src/Server.cpp @@ -9,15 +9,15 @@ Server::Server (const char *host, const Uint16 port) : UDPbase (host, port) { UDPsocket sock; - if (NULL != (sock = Open (port))) + if (NULL != (sock = UDP_Open (port))) { - Bind (sock, -1); - UDPsocks.push_back (sock); + UDP_Bind (sock, -1); } - SocketSet = NULL; + mFetchPacketsCallbackTimerID = 0; mLuaState = NULL; - packetV = NULL; mProcessPacketMutex = SDL_CreateMutex (); + packetV = NULL; + SocketSet = NULL; } @@ -25,8 +25,6 @@ Server::~Server (void) { Stop (); - CloseAllSockets (); - if (packetV) { SDLNet_FreePacketV (packetV); @@ -41,21 +39,6 @@ Server::~Server (void) } -void -Server::CloseAllSockets (void) -{ - size_t i, n; - n = TCPsocks.size (); - for (i = 0; i < n; i++) - SDLNet_TCP_Close (TCPsocks[i]); - TCPsocks.clear (); - n = UDPsocks.size (); - for (i = 0; i < n; i++) - SDLNet_UDP_Close (UDPsocks[i]); - UDPsocks.clear (); -} - - int Server::AllocateApproximateResources (const int nclients) { @@ -150,6 +133,7 @@ Server::Stop (void) } SDL_RemoveTimer (mFetchPacketsCallbackTimerID); + mFetchPacketsCallbackTimerID = 0; if (mLuaState) { @@ -164,11 +148,6 @@ Server::Stop (void) { SDLNet_UDP_DelSocket (SocketSet, UDPsocks[i]); } - nclients = TCPsocks.size (); - for (i = 0; i < nclients; i++) - { - SDLNet_TCP_DelSocket (SocketSet, TCPsocks[i]); - } SDLNet_FreeSocketSet (SocketSet); SocketSet = NULL; @@ -217,14 +196,27 @@ Uint32 Server::FetchPacketsCallback (Uint32 interval, void *param) SDL_assert (NULL != param); server = (Server *) param; + /* + * Need to have some kind of "thread enabled" condition before the Lock(). + * Checking the timer ID is sufficient for now. + */ + if (!server->mFetchPacketsCallbackTimerID) + { + return 0; + } + if (server->Lock () < 0) { DEBUG_LOG ("Lock failed"); return 0; } - /* TODO Make this interruptable */ - numready = SDLNet_CheckSockets (server->getSocketSet (), 1); + /* + * TODO fix this wait timeout blocking issue + * + * I want this to block, but also to be stoppable. + */ + numready = SDLNet_CheckSockets (server->getSocketSet (), (1000 * DEFAULT_SOCKET_TIMEOUT / 3) / 1000); if (numready < 0) { DEBUG_LOG ("SDLNet_CheckSockets: %s", SDLNet_GetError ()); diff --git a/src/UDPbase.cpp b/src/UDPbase.cpp index 8cdcaba..f51be6b 100644 --- a/src/UDPbase.cpp +++ b/src/UDPbase.cpp @@ -2,55 +2,83 @@ UDPbase::UDPbase (const char* host, const Uint16 port) { - if (SDLNet_ResolveHost (&mIPAddress, host, port) < 0) + if (ResolveHost (&mIPAddress, host, port) < 0) { - throw "SDLNet_ResolveHost: " + std::string (SDLNet_GetError ()); + throw "ResolveHost failed"; + } + mChannel = -1; +} + + +/* + * Shortcut for clients who want to open a single channel + * The channel will be available in client->getChannel () + */ +UDPbase::UDPbase (const char* host, const Uint16 port, const int channel) +{ + UDPsocket sock; + if (ResolveHost (&mIPAddress, host, port) < 0) + { + throw "ResolveHost failed"; + } + if (NULL == (sock = UDP_Open (0))) + { + throw "Unable to open client port"; + } + if (-1 == (mChannel = UDP_Bind (sock, channel))) + { + throw "Unable to bind client port"; } } UDPbase::~UDPbase (void) { + CloseAllSockets (); } -UDPsocket -UDPbase::Open (void) +int +UDPbase::ResolveHost (IPaddress* addr, const char* host, const Uint16 port) { - return Open (mIPAddress.port); + int rc; + if ((rc = SDLNet_ResolveHost (addr, host, port)) < 0) + { + throw "SDLNet_ResolveHost: " + std::string (SDLNet_GetError ()); + } + return rc; +} + + +/* + * Open *our* UDP IPaddress->port + */ +UDPsocket +UDPbase::UDP_Open (void) +{ + return UDP_Open (mIPAddress.port); } UDPsocket -UDPbase::Open (const Uint16 port) +UDPbase::UDP_Open (const Uint16 port) { UDPsocket sock = NULL; if (NULL == (sock = SDLNet_UDP_Open (port))) { throw "SDLNet_UDP_Open: " + std::string (SDLNet_GetError ()); } - if (NULL != GetPeerAddress (sock, -1)) + if (NULL != UDP_GetPeerAddress (sock, -1)) { SDL_Log ("Opened UDP port %d", SDLNet_Read16 (&mIPAddress.port)); + UDPsocks.push_back (sock); } return sock; } -IPaddress* -UDPbase::GetPeerAddress (UDPsocket sock, const int channel) -{ - IPaddress* addr = NULL; - if (NULL == (addr = SDLNet_UDP_GetPeerAddress (sock, channel))) - { - throw "SDLNet_UDP_GetPeerAddress: " + std::string (SDLNet_GetError ()); - } - return addr; -} - - void -UDPbase::Close (UDPsocket sock) +UDPbase::UDP_Close (UDPsocket sock) { SDL_assert (NULL != sock); SDLNet_UDP_Close (sock); @@ -59,7 +87,7 @@ UDPbase::Close (UDPsocket sock) int -UDPbase::Bind (UDPsocket sock, const int channel) +UDPbase::UDP_Bind (UDPsocket sock, const int channel) { int binding; SDL_assert (NULL != sock); @@ -73,12 +101,37 @@ UDPbase::Bind (UDPsocket sock, const int channel) void -UDPbase::Unbind (UDPsocket sock, const int channel) +UDPbase::UDP_Unbind (UDPsocket sock, const int channel) { SDLNet_UDP_Unbind (sock, channel); } +IPaddress* +UDPbase::UDP_GetPeerAddress (UDPsocket sock, const int channel) +{ + IPaddress* addr = NULL; + if (NULL == (addr = SDLNet_UDP_GetPeerAddress (sock, channel))) + { + throw "SDLNet_UDP_GetPeerAddress: " + std::string (SDLNet_GetError ()); + } + return addr; +} + + +void +UDPbase::CloseAllSockets (void) +{ + size_t i, n; + + n = UDPsocks.size (); + for (i = 0; i < n; i++) + UDP_Close (UDPsocks.at (i)); + + UDPsocks.clear (); +} + + std::string UDPbase::toString (void) { return std::string (SDLNet_ResolveIP (&mIPAddress)) + ":" + diff --git a/src/client_main.cpp b/src/client_main.cpp index 6c9b075..d128553 100644 --- a/src/client_main.cpp +++ b/src/client_main.cpp @@ -85,8 +85,8 @@ struct Client_State static std::unique_ptr cube; static std::unique_ptr quad; -static std::unique_ptr client; static std::unique_ptr shader; +static std::unique_ptr client; static Camera camera; static struct Client_State state; @@ -117,13 +117,13 @@ main (int argc, char** argv) state.mtu = 1450; state.done = false; - client = std::make_unique (state.host, state.port); - if (NULL == (state.udpsock = client->Open (0))) + client = std::make_unique (state.host, state.port, state.channel); + if (NULL == (state.udpsock = client->getSocket (0))) { SDL_Log ("Unable to open client port"); goto _out; } - if (-1 == (state.channel = client->Bind (state.udpsock, -1))) + if (-1 == (state.channel = client->getChannel ())) { SDL_Log ("Unable to bind client port"); goto _out; @@ -162,11 +162,20 @@ main (int argc, char** argv) shader->Mat4 ("Model", model); my_Render (); + + model = glm::mat4 (1.0f); + model = glm::scale (model, glm::vec3 (10.0f)); + shader->Use (); + shader->Mat4 ("Projection", projection); + shader->Mat4 ("View", view); + shader->Mat4 ("Model", model); + cube->Draw (); + SDL_GL_SwapWindow (state.Window); } _out: - client->Close (state.udpsock); + client->CloseAllSockets (); SDL_GL_DeleteContext (state.GLContext); SDL_DestroyWindow (state.Window); common_SDL_Quit (); @@ -516,7 +525,7 @@ my_GetOpt (int argc, char** argv) int opt; state.host = "localhost"; state.port = 6666; - state.channel = 1; + state.channel = -1; while ((opt = getopt (argc, argv, "hp:s:")) != -1) { switch (opt) diff --git a/src/cube.cpp b/src/cube.cpp index ac43d38..2defcc7 100644 --- a/src/cube.cpp +++ b/src/cube.cpp @@ -1,7 +1,7 @@ #include "cube.h" -Cube::Cube (const GLsizei size): -Object (size) +Cube::Cube (const GLsizei size) + : Object (size) { const float vertices[] = { diff --git a/src/cube_triangle_strip.cpp b/src/cube_triangle_strip.cpp new file mode 100644 index 0000000..3ed88cd --- /dev/null +++ b/src/cube_triangle_strip.cpp @@ -0,0 +1,40 @@ +#include "cube_triangle_strip.h" + +CubeTriangleStrip::CubeTriangleStrip (const GLsizei size) + : Object (size) +{ + static const GLfloat vertices[] = + { + 0.5, 0.5, -0.5, // Back-top-right + -0.5, 0.5, -0.5, // Back-top-left + 0.5, -0.5, -0.5, // Back-bottom-right + -0.5, -0.5, -0.5, // Back-bottom-left + -0.5, -0.5, 0.5, // Front-bottom-left + -0.5, 0.5, -0.5, // Back-top-left + -0.5, 0.5, 0.5, // Front-top-left + 0.5, 0.5, -0.5, // Back-top-right + 0.5, 0.5, 0.5, // Front-top-right + 0.5, -0.5, -0.5, // Back-bottom-right + 0.5, -0.5, 0.5, // Front-bottom-right + -0.5, -0.5, 0.5, // Front-bottom-left + 0.5, 0.5, 0.5, // Front-top-right + -0.5, 0.5, 0.5, // Front-top-left + }; + + glBindVertexArray (VAO); + + glBindBuffer (GL_ARRAY_BUFFER, VBO); + glBufferData (GL_ARRAY_BUFFER, sizeof vertices, vertices, GL_STATIC_DRAW); + + glBindVertexArray (VAO); + glVertexAttribPointer (0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof (float), (void *) 0); + glEnableVertexAttribArray (0); +} + + +void +CubeTriangleStrip::Draw (void) +{ + glBindVertexArray (VAO); + glDrawArrays (GL_TRIANGLE_STRIP, 0, 14); +} diff --git a/src/server_main.cpp b/src/server_main.cpp index 1df6876..dcb29f0 100644 --- a/src/server_main.cpp +++ b/src/server_main.cpp @@ -7,12 +7,14 @@ #include "lib_lua_common.h" #include "util.h" #include "Server.h" +#include "Commands.h" #include #include #include #include #include +#include #include /* exit */ #include /* getopt */ @@ -52,7 +54,8 @@ main (int argc, char **argv) done = false; SDL_Thread* stdin_loop = SDL_CreateThread(my_StdinThread, "my_StdinThread", (void*)NULL); - if (NULL == stdin_loop) { + if (NULL == stdin_loop) + { error ("SDL_CreateThread failed: %s\n", SDL_GetError()); } @@ -78,7 +81,7 @@ main (int argc, char **argv) } server->Stop (); - server->CloseAllSockets (); + // server->CloseAllSockets (); SDL_WaitThread (stdin_loop, NULL); @@ -150,7 +153,8 @@ my_ProcessPacket (UDPpacket* packet) // SDL_Log ("%d \"%s\"", str.length (), str.c_str ()); /* XXX ultra gross */ - if (down) { + if (down) + { if (str.length () > 1) { if (str == "Return") @@ -270,45 +274,72 @@ static void my_ShowPrompt (void) fflush (stdout); } + +/* + * TODO + * Oh boy this would be our main command handler for the server stdin huh? Wowie! + */ static bool my_StdinThread_Helper (const std::string& buf) { - util_HexDump (buf.c_str (), buf.length ()); - if (buf == "quit") + std::string argv0 = buf; + std::string args = buf; + + auto const& pos = buf.find (' '); + if (pos != std::string::npos) { - return true; + /* command */ + argv0 = buf.substr (0, pos); + argv0 = trim (argv0); + args = buf.substr (pos); } + + // SDL_Log ("\"%s\"", argv0.c_str ()); + + auto const& ref = CommandFunctionList.find (argv0); + if (ref != CommandFunctionList.end ()) + { + /* It was found */ + return ref->second (args); + } + SDL_Delay (100); - puts (buf.c_str ()); return false; } + static int my_StdinThread(void* param) { std::string buf; UNUSED (param); -_top: + + _top: while (!done) { - try { - my_ShowPrompt (); - while (!done && getline (std::cin, buf)) - { - buf = trim (buf); - if (buf.empty ()) - { - goto _top; - } - if (my_StdinThread_Helper (buf)) - { - done = true; - break; - } - } + my_ShowPrompt (); + try + { + getline (std::cin, buf); } - catch (std::ifstream::failure& e) { + catch (std::ifstream::failure& e) + { done = true; } + if (std::cin.bad () || std::cin.eof ()) + { + done = true; + goto _out; + } + buf = trim (buf); + if (buf.empty ()) + { + goto _top; + } + if ((done = my_StdinThread_Helper (buf))) + { + goto _out; + } } + _out: return 0; } diff --git a/src/shader.cpp b/src/shader.cpp index 794ac93..dda3f05 100644 --- a/src/shader.cpp +++ b/src/shader.cpp @@ -1,4 +1,3 @@ -#include "debug.h" #include "shader.h" #include "FileIO.h" #include "lib_GL_common.h" @@ -56,8 +55,8 @@ ShaderProgram::Use (void) GLint ShaderProgram::getCachedLoc (const std::string& name) { GLint loc; - auto const& ref = UniformLocationCache.find (name); + auto const& ref = UniformLocationCache.find (name); if (ref == UniformLocationCache.end ()) { /* It didn't exist, have to get it */ @@ -297,7 +296,7 @@ ShaderProgram::my_checkCompileSuccess (const GLuint id, const GLenum type) } if (infoLog[0] != '\0') { - DEBUG_LOG ("%8s ERROR\n%s", typeName.c_str (), infoLog.c_str ()); + SDL_Log ("%8s ERROR\n%s", typeName.c_str (), infoLog.c_str ()); } return success; } @@ -338,6 +337,11 @@ Uint32 ShaderProgram::my_WatchShaderHelper (Uint32 interval, void* param) SDL_assert (NULL != param); shader = (ShaderProgram*) param; + if (!shader->mShaderWatchTimer) + { + return 0; + } + if (shader->NeedsReloading (false)) { SDL_zero (event); @@ -358,4 +362,5 @@ void ShaderProgram::StartWatchingShader (void) void ShaderProgram::StopWatchingShader (void) { SDL_RemoveTimer (mShaderWatchTimer); + mShaderWatchTimer = 0; } diff --git a/test/test_UDPpacketBufferV.cpp b/test/test_UDPpacketBufferV.cpp index e176814..16d6262 100644 --- a/test/test_UDPpacketBufferV.cpp +++ b/test/test_UDPpacketBufferV.cpp @@ -48,12 +48,12 @@ main (int argc, char **argv) common_SDL_Init (); client = std::make_unique (host, port); - if (NULL == (udpsock = client->Open (0))) + if (NULL == (udpsock = client->UDP_Open (0))) { SDL_Log ("Unable to open client port"); return -1; } - if (-1 == (channel = client->Bind (udpsock, -1))) + if (-1 == (channel = client->UDP_Bind (udpsock, -1))) { SDL_Log ("Unable to bind client port"); return -1; @@ -78,6 +78,7 @@ main (int argc, char **argv) FileIO f (path, "r"); buf = f.ReadToString (); } + UDPpacket* packet = SDLNet_AllocPacket (buf.length ()); IPaddress* addr = SDLNet_UDP_GetPeerAddress (udpsock, channel); packet->len = DEFAULT_MAX_PACKET_SIZE; @@ -86,7 +87,7 @@ main (int argc, char **argv) UDPpacketVBuffer packetV (packet, &buf[0], buf.length ()); packetV.Send (udpsock); - client->Close (udpsock); + client->CloseAllSockets (); common_SDL_Quit ();