/** In caso di errore, uno dei seguenti valori viene associato a errno: - @b ENOTCONN: il peer ha chiuso la connessione - @b ENOMEM: problema con la memoria - uno dei valori assegnati da read() - uno dei valori assegnati da strtoul() */ int receiveMessage(int sc, message_t * msg) { char type; char cbuflen[11]; /* buffer per leggere msg->length */ char *buffer = NULL; /* msg->buffer */ int buflen; /* msg->length */ int r_type = 0, r_cbuflen = 0, r_buffer = 0; r_type = readAllChars(sc, &type, 1); if(r_type <= 0) { errno = (r_type == 0 ? ENOTCONN : errno); return -1; } cbuflen[10] = '\0'; r_cbuflen = readAllChars(sc, cbuflen, 10); if(r_cbuflen <= 0) { errno = (r_cbuflen == 0 ? ENOTCONN : errno); return -1; } errno = 0; buflen = (int) strtoul(cbuflen, NULL, 10); if(errno != 0) return -1; if(buflen > 0) { /* FIXME Potenzialmente pericoloso! Potremmo allocare una quantità di memoria esagerata */ buffer = (char*)malloc(sizeof(char) * buflen); if(buffer == NULL) return -1; r_buffer = readAllChars(sc, buffer, buflen); if(r_buffer <= 0) { errno = (r_buffer == 0 ? ENOTCONN : errno); free(buffer); return -1; } } if(msg == NULL) { /* se msg=null, riceve e scarta */ if(buffer != NULL) { free(buffer); } } else { msg->type = type; msg->length = buflen; msg->buffer = buffer; } return r_type + r_cbuflen + r_buffer; }
int main(int argc, char ** argv) { auto pathToRom = std::string(); if (argc == 2) { pathToRom = argv[1]; } else { printf("Chip8 Error: Wrong number of arguments\n"); return -1; } sf::SoundBuffer beepSnd; if (! beepSnd.loadFromFile("data/sounds/beep.wav")) { printf("Chip8 Error: Can't load the beeping sound.\n"); return -1; } sf::Sound sndSrc; sndSrc.setBuffer(beepSnd); sndSrc.setLoop(false); auto window = setupWindow(WIDTH, HEIGHT, TITLE); cee::Chip8 chip; chip.loadProgram(readAllBytes(pathToRom.c_str())); constexpr GLfloat pxVerts[] = { -1.0f, 1.0f, 0.0f, // Top Left 1.0f, 1.0f, 0.0f, // Top Right -1.0f, -1.0f, 0.0f, // Bottom Left 1.0f, -1.0f, 0.0f // Bottom Right }; constexpr GLuint pxIndices[] = { 0, 1, 2, 2, 1, 3 }; // Initialize the VAO and other buffers associated // with drawing an emulated pixel. GLuint vao, vbo, ibo; glGenVertexArrays(1, &vao); glBindVertexArray(vao); { glGenBuffers(1, &vbo); glGenBuffers(1, &ibo); // VBO glBindBuffer(GL_ARRAY_BUFFER, vbo); glBufferData(GL_ARRAY_BUFFER, sizeof(pxVerts), &pxVerts, GL_STATIC_DRAW); // IBO glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo); glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(pxIndices), &pxIndices, GL_STATIC_DRAW); glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(GLfloat), nullptr); glEnableVertexAttribArray(0); } glBindVertexArray(0); // Current Vertex Shader const auto pxVertexSrc = readAllChars("data/shaders/px_vertex.glsl"); const auto pxVertex = makeShader(GL_VERTEX_SHADER, pxVertexSrc); // Current Fragment Shader const auto pxFragmentSrc = readAllChars("data/shaders/px_fragment.glsl"); const auto pxFragment = makeShader(GL_FRAGMENT_SHADER, pxFragmentSrc); // Current Shader Program const auto pxProgram = makeProgram({pxVertex, pxFragment}); glUseProgram(pxProgram); glfwShowWindow(window); while (! glfwWindowShouldClose(window)) { chip.updateKeys(getKeyStates(window)); chip.updateCycle(); if (chip.isBeeping() && sndSrc.getStatus() != sf::SoundSource::Playing) sndSrc.play(); // Clear back buffer and background color. glClear(GL_COLOR_BUFFER_BIT); glClearColor(0.0f, 0.0f, 0.0f, 0.0f); glBindVertexArray(vao); const auto gfx = chip.getGfx(); for (int i = 0; i < 32; ++i) { // Maps the width resolution [0-HEIGHT] to [-1.0-1.0] auto y = - mapRangeHeight(i); auto l = i * 64; for (int j = 0; j < 64; ++j) { if (gfx[l + j] == 1) { // Maps the width resolution [0-WIDTH] to [-1.0-1.0] auto x = mapRangeWidth(j); auto ident = glGetUniformLocation(pxProgram, "PxModel"); auto model = glm::mat4(1.0f); model = glm::translate(model, glm::vec3(x, y, 0.0f)); model = glm::scale(model, glm::vec3(PX_WIDTH, PX_HEIGHT, 1.0f)); glUniformMatrix4fv(ident, 1, GL_FALSE, glm::value_ptr(model)); glDrawElements(GL_TRIANGLES, sizeof(pxIndices), GL_UNSIGNED_INT, nullptr); } } } glBindVertexArray(0); glfwSwapBuffers(window); glfwPollEvents(); } // Cleanup resources glDeleteProgram(pxProgram); glDeleteShader(pxVertex); glDeleteShader(pxFragment); glDeleteVertexArrays(1, &vao); glDeleteBuffers(1, &ibo); glDeleteBuffers(1, &vbo); glfwTerminate(); return 0; }