Disabled external gits
This commit is contained in:
14
cs309-psoc/lab_4_1/sw/hps/application/client-sfml/Makefile
Normal file
14
cs309-psoc/lab_4_1/sw/hps/application/client-sfml/Makefile
Normal file
@@ -0,0 +1,14 @@
|
||||
|
||||
CC=g++
|
||||
LDLIBS=`pkg-config --libs sfml-graphics sfml-window sfml-network`
|
||||
|
||||
all: main
|
||||
|
||||
main.o: main.cpp
|
||||
main: main.o
|
||||
|
||||
run:
|
||||
@./main
|
||||
|
||||
clean:
|
||||
rm -f main.o main
|
120
cs309-psoc/lab_4_1/sw/hps/application/client-sfml/main.cpp
Normal file
120
cs309-psoc/lab_4_1/sw/hps/application/client-sfml/main.cpp
Normal file
@@ -0,0 +1,120 @@
|
||||
|
||||
#include <SFML/Graphics.hpp>
|
||||
#include <SFML/Network.hpp>
|
||||
#include <iostream>
|
||||
#include <type_traits>
|
||||
using namespace std;
|
||||
|
||||
#define IMAGE_WIDTH 80
|
||||
#define IMAGE_HEIGHT 60
|
||||
#define SCALE_FACTOR 10
|
||||
#define UPDATE_INTERVAL IMAGE_HEIGHT
|
||||
|
||||
#define SERVER_PORT 25700
|
||||
#define BUFFER_SIZE (4 + IMAGE_WIDTH * 2)
|
||||
#define HANDSHAKE_TIMEOUT 2000
|
||||
|
||||
void updateLine(uint8_t* buffer, uint32_t lineIndex, uint16_t* line);
|
||||
void bernsteinRGB(uint8_t* rgba, double t);
|
||||
void sendHandshake(sf::UdpSocket& socket, sf::IpAddress address, unsigned short port);
|
||||
|
||||
int main(int argc, char* argv[]) {
|
||||
if (argc != 2) {
|
||||
cout << "Invalid usage of client. You should pass the address of the server." << endl;
|
||||
return -1;
|
||||
}
|
||||
|
||||
// We create the window to which we render the image
|
||||
sf::RenderWindow window(sf::VideoMode(IMAGE_WIDTH * SCALE_FACTOR, IMAGE_HEIGHT * SCALE_FACTOR), "Thermalizer", sf::Style::Close);
|
||||
|
||||
// The intermediate buffer in which the image is received before being sent to the GPU
|
||||
uint8_t buffer[IMAGE_HEIGHT * IMAGE_WIDTH * 4]; // RGBA = 4 bytes per pixel
|
||||
size_t lastRefresh = 0; // the number of lines since the last refresh
|
||||
uint32_t lineIndex = 0; // the index of the last line that was received
|
||||
|
||||
// The texture to which the image will be drawn
|
||||
sf::Texture texture;
|
||||
texture.create(IMAGE_WIDTH, IMAGE_HEIGHT);
|
||||
sf::Sprite sprite;
|
||||
sprite.setTexture(texture);
|
||||
sprite.setScale(SCALE_FACTOR, SCALE_FACTOR);
|
||||
|
||||
// The buffer in which the packet for the lines are received
|
||||
char lineBuffer[BUFFER_SIZE];
|
||||
size_t received;
|
||||
sf::IpAddress serverAddress(argv[1]), senderAddress;
|
||||
unsigned short serverPort = SERVER_PORT, senderPort;
|
||||
|
||||
// Create the UDP socket
|
||||
cout << "Creating and binding a UDP socket..." << endl;
|
||||
sf::UdpSocket socket;
|
||||
sf::SocketSelector selector;
|
||||
if (socket.bind(sf::UdpSocket::AnyPort) != sf::Socket::Done) {
|
||||
cout << "Couldn't bind socket on port " << socket.getLocalPort() << endl;
|
||||
return -1;
|
||||
}
|
||||
|
||||
cout << "UDP Socket successfully bound." << endl;
|
||||
sendHandshake(socket, serverAddress, serverPort);
|
||||
selector.add(socket);
|
||||
|
||||
while (window.isOpen()) {
|
||||
sf::Event event;
|
||||
while (window.pollEvent(event)) {
|
||||
// If the user requested the window to be closed
|
||||
if (event.type == sf::Event::Closed ||
|
||||
(event.type == sf::Event::KeyPressed && event.key.code == sf::Keyboard::Q)) {
|
||||
// Inform the server about the client stopping
|
||||
socket.send(nullptr, 0, serverAddress, serverPort);
|
||||
window.close();
|
||||
}
|
||||
}
|
||||
|
||||
if (selector.wait(sf::milliseconds(500))) {
|
||||
// If a packet was received, we update the intermediate buffer
|
||||
socket.receive(lineBuffer, BUFFER_SIZE, received, senderAddress, senderPort);
|
||||
lineIndex = *((uint32_t*) lineBuffer);
|
||||
updateLine(buffer, lineIndex, (uint16_t*) (lineBuffer + sizeof(uint32_t)));
|
||||
lastRefresh++;
|
||||
} else {
|
||||
// If no packet was received in a while, we re-send a handshake to try to reconnect
|
||||
sendHandshake(socket, serverAddress, serverPort);
|
||||
}
|
||||
|
||||
// We refresh the image every once in a while, so that if there is packet loss on the last
|
||||
// line the screen is still updated.
|
||||
if (lastRefresh == UPDATE_INTERVAL || lineIndex == IMAGE_HEIGHT - 1) {
|
||||
// If enough packets were received, we update the texture
|
||||
lastRefresh = 0;
|
||||
texture.update(buffer);
|
||||
|
||||
// And draw it to the screen
|
||||
window.clear();
|
||||
window.draw(sprite);
|
||||
window.display();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// Updates the line of the buffer with the packet that arrived
|
||||
void updateLine(uint8_t* buffer, uint32_t lineIndex, uint16_t* line) {
|
||||
uint8_t* lineBuffer = buffer + lineIndex * IMAGE_WIDTH * 4;
|
||||
|
||||
for (size_t x = 0; x < IMAGE_WIDTH; x++)
|
||||
bernsteinRGB(lineBuffer + x * 4, (double) line[x] / 0x3FFF);
|
||||
}
|
||||
|
||||
// Performs the color interpolation using Bernstein polynomials
|
||||
void bernsteinRGB(uint8_t* rgba, double t) {
|
||||
rgba[0] = (9 * (1 - t) * t * t * t) * 255;
|
||||
rgba[1] = (15 * (1 - t) * (1 - t) * t * t) * 255;
|
||||
rgba[2] = (9 * (1 - t) * (1 - t) * (1 - t) * t) * 255;
|
||||
rgba[3] = 255;
|
||||
}
|
||||
|
||||
// Sends a handshake to the server
|
||||
void sendHandshake(sf::UdpSocket& socket, sf::IpAddress address, unsigned short port) {
|
||||
cout << "Sending a handshake to the server..." << endl;
|
||||
socket.send(nullptr, 0, address, port);
|
||||
}
|
Reference in New Issue
Block a user