/**
  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;
}
예제 #2
0
파일: main.cpp 프로젝트: jankdc/cee
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;
}