diff --git a/pixelnuke/Makefile b/pixelnuke/Makefile new file mode 100644 index 0000000..b784d54 --- /dev/null +++ b/pixelnuke/Makefile @@ -0,0 +1,23 @@ +.PHONY: default all clean + +CC = gcc +CFLAGS = -Wall -pthread -g +LIBS = -levent -levent_pthreads -lrt -lGL -lGLEW -lglfw +TARGET = pixelnuke + +default: $(TARGET) +all: default + +OBJECTS = $(patsubst %.c, %.o, $(wildcard *.c)) +HEADERS = $(wildcard *.h) + +%.o: %.c $(HEADERS) + $(CC) $(CFLAGS) -c $< -o $@ + +.PRECIOUS: $(TARGET) $(OBJECTS) + +$(TARGET): $(OBJECTS) + $(CC) $(CFLAGS) $(OBJECTS) -Wall $(LIBS) -o $@ + +clean: + -rm -f *.o $(TARGET) diff --git a/pixelnuke/canvas.c b/pixelnuke/canvas.c new file mode 100644 index 0000000..23e2f38 --- /dev/null +++ b/pixelnuke/canvas.c @@ -0,0 +1,361 @@ +#include +#include +#include // usleep +#include +#include +#include +#include //memcpy + +#include "canvas.h" + +typedef struct CanvasLayer { + GLuint size; + GLenum format; + GLuint tex; + GLuint pbo1; + GLuint pbo2; + GLubyte *data; + size_t mem; +} CanvasLayer; + +// Global state + +static int canvas_width, canvas_height; + +static int canvas_display = -1; +static GLFWwindow* canvas_win; +static CanvasLayer *canvas_base; +static CanvasLayer *canvas_overlay; + +// User callbacks + +void (*canvas_on_close_cb)(); +void (*canvas_on_resize_cb)(); +void (*canvas_on_key_cb)(); + +static int canvas_do_layout = 0; + +static CanvasLayer* canvas_layer_alloc(int size, int alpha) { + CanvasLayer * layer = malloc(sizeof(CanvasLayer)); + layer->size = size; + layer->format = alpha ? GL_RGBA : GL_RGB; + layer->mem = size * size * (alpha ? 4 : 3); + layer->data = malloc(sizeof(GLubyte) * layer->mem); + + // Create texture object + glGenTextures(1, &(layer->tex)); + glBindTexture( GL_TEXTURE_2D, layer->tex); + glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glBindTexture( GL_TEXTURE_2D, 0); + + // Create two PBOs + glGenBuffers(1, &(layer->pbo1)); + glBindBuffer( GL_PIXEL_UNPACK_BUFFER, layer->pbo1); + glBufferData( GL_PIXEL_UNPACK_BUFFER, layer->mem, NULL, GL_STREAM_DRAW); + glGenBuffers(1, &(layer->pbo2)); + glBindBuffer( GL_PIXEL_UNPACK_BUFFER, layer->pbo2); + glBufferData( GL_PIXEL_UNPACK_BUFFER, layer->mem, NULL, GL_STREAM_DRAW); + glBindBuffer( GL_PIXEL_UNPACK_BUFFER, 0); + + return layer; +} + +static void canvas_layer_free(CanvasLayer * canvas) { + if (canvas->tex) { + glDeleteTextures(1, &(canvas->tex)); + glDeleteBuffers(1, &(canvas->pbo1)); + glDeleteBuffers(1, &(canvas->pbo2)); + } + free(canvas->data); + free(canvas); +} + +static void canvas_on_resize(GLFWwindow* window, int w, int h); +static void canvas_on_key(GLFWwindow* window, int key, int scancode, int action, + int mods); + +static void canvas_on_key(GLFWwindow* window, int key, int scancode, int action, + int mods) { + printf("KEY: %u %u %u %u\n", key, scancode, action, mods); + if (action != GLFW_PRESS) { + return; + } + if (canvas_on_key_cb) + (*canvas_on_key_cb)(key, scancode, action, mods); +} + +static void canvas_on_resize(GLFWwindow* window, int w, int h) { + if(canvas_on_resize_cb) + (*canvas_on_resize_cb)(); +} + +static void canvas_window_setup() { + GLFWwindow* old_win = canvas_win; + + glfwWindowHint(GLFW_DOUBLEBUFFER, 1); + if (canvas_display >= 0) { + int mcount; + GLFWmonitor** monitors = glfwGetMonitors(&mcount); + canvas_display %= mcount; + GLFWmonitor* monitor = monitors[canvas_display]; + const GLFWvidmode* mode = glfwGetVideoMode(monitor); + glfwWindowHint(GLFW_RED_BITS, mode->redBits); + glfwWindowHint(GLFW_GREEN_BITS, mode->greenBits); + glfwWindowHint(GLFW_BLUE_BITS, mode->blueBits); + glfwWindowHint(GLFW_REFRESH_RATE, mode->refreshRate); + canvas_win = glfwCreateWindow(mode->width, mode->height, "Pixelflut", + monitor, old_win); + } else { + canvas_win = glfwCreateWindow(800, 600, "Pixelflut", NULL, old_win); + } + + if (!canvas_win) { + printf("Could not create OpenGL context and/or window"); + return; + } + + //glfwSetWindowUserPointer(canvas_win, (void*) this); + glfwMakeContextCurrent(canvas_win); + glfwSwapInterval(1); + glfwSetKeyCallback(canvas_win, &canvas_on_key); + glfwSetFramebufferSizeCallback(canvas_win, &canvas_on_resize); + + if (old_win) { + glfwDestroyWindow(old_win); + } + + canvas_do_layout = 0; +} + +static void canvas_draw_layer(CanvasLayer * layer) { + if (!layer) + return; + + GLuint pboNext = layer->pbo1; + GLuint pboIndex = layer->pbo2; + layer->pbo1 = pboIndex; + layer->pbo2 = pboNext; + + // Switch PBOs on each call. One is updated, one is drawn. + // Update texture from first PBO + glBindBuffer( GL_PIXEL_UNPACK_BUFFER, pboIndex); + glBindTexture( GL_TEXTURE_2D, layer->tex); + glTexImage2D( GL_TEXTURE_2D, 0, layer->format, layer->size, layer->size, 0, + layer->format, GL_UNSIGNED_BYTE, 0); + glBindTexture( GL_TEXTURE_2D, 0); + + // Update second PBO with new pixel data + glBindBuffer( GL_PIXEL_UNPACK_BUFFER, pboNext); + GLubyte *ptr = (GLubyte*) glMapBuffer( GL_PIXEL_UNPACK_BUFFER, + GL_WRITE_ONLY); + memcpy(ptr, layer->data, layer->mem); + glUnmapBuffer( GL_PIXEL_UNPACK_BUFFER); + glBindBuffer( GL_PIXEL_UNPACK_BUFFER, 0); + + //// Actually draw stuff. The texture should be updated in the meantime. + + if (layer->format == GL_RGBA) { + glEnable( GL_BLEND); + glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + } else { + glDisable( GL_BLEND); + } + + glPushMatrix(); + glBindTexture( GL_TEXTURE_2D, layer->tex); + glBegin( GL_QUADS); + glTexCoord2f(0, 0); + glVertex3f(0.0f, 0.0f, 0.0f); + glTexCoord2f(0, 1); + glVertex3f(0.0f, layer->size, 0.0f); + glTexCoord2f(1, 1); + glVertex3f(layer->size, layer->size, 0.0f); + glTexCoord2f(1, 0); + glVertex3f(layer->size, 0.0f, 0.0f); + glEnd(); + glBindTexture( GL_TEXTURE_2D, 0); + glPopMatrix(); +} + +static void* canvas_render_loop(void * arg) { + glfwMakeContextCurrent(canvas_win); + + double last_frame = glfwGetTime(); + + while ("pixels are coming") { + if (glfwWindowShouldClose(canvas_win)) + break; + + if (canvas_do_layout) + canvas_window_setup(); + + int w, h; + glfwGetFramebufferSize(canvas_win, &w, &h); + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + glOrtho(0, canvas_width, canvas_height, 0, -1, 1); + glViewport(0, 0, (GLsizei) canvas_width, (GLsizei) canvas_height); + glClearColor(0, 0, 0, 1); + glClear(GL_COLOR_BUFFER_BIT); + glPushMatrix(); + + //int ts = layer->texSize; + //if(width > ts || height > ts) { + // float scale = std::max(width, height) / (float) ts; + // glScalef(scale, scale, 1); + //} + + canvas_draw_layer(canvas_base); + canvas_draw_layer(canvas_overlay); + + glPopMatrix(); + glfwPollEvents(); + glfwSwapBuffers(canvas_win); + + double now = glfwGetTime(); + double dt = now - last_frame; + last_frame = now; + double sleep = 1.0 / 30 - dt; + printf("fps: %f\n", 1.0/dt); + if (sleep > 0) { + usleep(sleep * 1000000); + } + } + + if(canvas_on_close_cb) + (*canvas_on_close_cb)(); + + glfwTerminate(); + + return NULL; +} + +// Public functions + +pthread_t canvas_thread; + +void glfw_error_callback(int error, const char* description) { + printf("GLFW Error: %d %s", error, description); +} + +void canvas_start(unsigned int texSize, void (*on_close)()) { + + canvas_on_close_cb = on_close; + + glfwSetErrorCallback(glfw_error_callback); + if (!glfwInit()) { + puts("GLFW initialization failed"); + exit(1); + } + + canvas_window_setup(); + + int err = glewInit(); + if (err != GLEW_OK) { + puts("GLEW initialization failed"); + printf("Error: %s\n", glewGetErrorString(err)); + exit(1); + } + + //glShadeModel(GL_FLAT); // shading mathod: GL_SMOOTH or GL_FLAT + glPixelStorei(GL_UNPACK_ALIGNMENT, 4); // 4-byte pixel alignment + //glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); + //glHint(GL_LINE_SMOOTH_HINT, GL_NICEST); + //glHint(GL_POLYGON_SMOOTH_HINT, GL_NICEST); + glDisable(GL_DEPTH_TEST); + glDisable(GL_LIGHTING); + glDisable(GL_CULL_FACE); + glEnable(GL_TEXTURE_2D); + + canvas_base = canvas_layer_alloc(texSize, 0); + canvas_overlay = canvas_layer_alloc(texSize, 1); + + glfwMakeContextCurrent(NULL); // Pass context to thread + if (pthread_create(&canvas_thread, NULL, canvas_render_loop, NULL)) { + puts("Failed to start render thread"); + exit(1); + } +} + +void canvas_setcb_key(void (*on_key)(int key, int scancode, int mods)) { + canvas_on_key_cb = on_key; +} + +void canvas_setcb_resize(void (*on_resize)()) { + canvas_on_resize_cb = on_resize; +} + +void canvas_close() { + glfwSetWindowShouldClose(canvas_win, 1); +} + +void canvas_fullscreen(int display) { + canvas_display = display; + canvas_do_layout = 1; +} + +int canvas_get_display() { + return canvas_display; +} + +// Return a pointer to the GLubyte for a given pixel, or NULL for out of bound coordinates. +static inline GLubyte* canvas_offset(CanvasLayer * layer, unsigned int x, + unsigned int y) { + if (x < 0 || y < 0 || x >= layer->size || y >= layer->size) + return NULL; + return layer->data + + ((y * layer->size) + x) * (layer->format == GL_RGBA ? 4 : 3); +} + +void canvas_set_px(unsigned int x, unsigned int y, unsigned int rgba) { + CanvasLayer * layer = canvas_base; + GLubyte* ptr = canvas_offset(layer, x, y); + + if (ptr == NULL) { + return; + } + + GLubyte r = (rgba & 0xff000000) >> 24; + GLubyte g = (rgba & 0x00ff0000) >> 16; + GLubyte b = (rgba & 0x0000ff00) >> 8; + GLubyte a = (rgba & 0x000000ff) >> 0; + + if (layer->format == GL_RGBA) { + ptr[0] = r; + ptr[1] = g; + ptr[2] = b; + ptr[3] = a; + return; + } + if (a == 0) { + return; + } + if (a < 0xff) { + GLuint na = 0xff - a; + r = (a * r + na * (ptr[0])) / 0xff; + g = (a * g + na * (ptr[1])) / 0xff; + b = (a * b + na * (ptr[2])) / 0xff; + return; + } + ptr[0] = r; + ptr[1] = g; + ptr[2] = b; +} + +void canvas_get_px(unsigned int x, unsigned int y, unsigned int *rgba) { + CanvasLayer * layer = canvas_base; + GLubyte* ptr = canvas_offset(layer, x, y); + if (ptr == NULL) { + *rgba = 0x000000; + } else { + *rgba = (ptr[0] << 24) + (ptr[1] << 16) + (ptr[2] << 8) + 0xff; + } +} + +void canvas_get_size(unsigned int *w, unsigned int *h) { + // TODO: Clip on window size + *w = canvas_base->size; + *h = canvas_base->size; +} + diff --git a/pixelnuke/canvas.h b/pixelnuke/canvas.h new file mode 100644 index 0000000..3404621 --- /dev/null +++ b/pixelnuke/canvas.h @@ -0,0 +1,24 @@ +#ifndef CANVAS_H_ +#define CANVAS_H_ + +// Open the canvas window and start the gui loop (in a separate thread) +void canvas_start(unsigned int texSize, void (*on_close)()); + +void canvas_setcb_key(void (*on_key)(int key, int scancode, int mods)); +void canvas_setcb_resize(void (*on_resize)()); + +// Close the canvas window and free any resources and contexts +void canvas_close(); + +void canvas_fullscreen(int display); +int canvas_get_display(); + +void canvas_set_px(unsigned int x, unsigned int y, unsigned int rgba); +void canvas_get_px(unsigned int x, unsigned int y, unsigned int *rgba); + +// get the current visible canvas size in pixel. +// The actual window might be bigger if scaling is enabled. +void canvas_get_size(unsigned int *width, unsigned int *height); + + +#endif /* CANVAS_H_ */ diff --git a/pixelnuke/net.c b/pixelnuke/net.c new file mode 100644 index 0000000..af506f6 --- /dev/null +++ b/pixelnuke/net.c @@ -0,0 +1,199 @@ +#include +#include +#include + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include "net.h" + +#define MAX_LINE 128 + +typedef struct NetClient { + int sock_fd; + struct bufferevent *buf_ev; + int state; + void *user; +} NetClient; + +#define NET_CSTATE_OPEN 0 +#define NET_CSTATE_CLOSING 1 + +// global state +static struct event_base *base; + +// User defined callbacks +static net_on_connect netcb_on_connect = NULL; +static net_on_read netcb_on_read = NULL; +static net_on_close netcb_on_close = NULL; + + + +// libevent callbacks + +static void netev_on_read(struct bufferevent *bev, void *ctx) { + struct evbuffer *input; + char *line; + size_t n; + NetClient *client = ctx; + + input = bufferevent_get_input(bev); + + if ((line = evbuffer_readln(input, &n, EVBUFFER_EOL_LF))) { + if(netcb_on_read) + (*netcb_on_read)(client, line); + free(line); + } + + if (evbuffer_get_length(input) >= MAX_LINE) { + net_err(client, "Line to long"); + } +} + +static void netev_on_write(struct bufferevent *bev, void *arg) { + NetClient *client = arg; + + if (client->state == NET_CSTATE_CLOSING && evbuffer_get_length(bufferevent_get_output(bev)) == 0) { + + if(netcb_on_close) + (*netcb_on_close)(client, 0); + + bufferevent_free(bev); + free(client); + } +} + +static void netev_on_error(struct bufferevent *bev, short error, void *arg) { + NetClient *client = arg; + + // TODO: Some logging? + if (error & BEV_EVENT_EOF) { + } else if (error & BEV_EVENT_ERROR) { + } else if (error & BEV_EVENT_TIMEOUT) { + } + + client->state = NET_CSTATE_CLOSING; + if(netcb_on_close) + (*netcb_on_close)(client, error); + + bufferevent_free(bev); + free(client); +} + +static void on_accept(evutil_socket_t listener, short event, void *arg) { + struct event_base *base = arg; + struct sockaddr_storage ss; + socklen_t slen = sizeof(ss); + int fd = accept(listener, (struct sockaddr*) &ss, &slen); + if (fd < 0) { + perror("accept failed"); + } else if (fd > FD_SETSIZE) { + close(fd); // TODO: verify if this is needed. Only for select()? But libevent uses poll/kqueue? + } else { + NetClient *client = calloc(1, sizeof(NetClient)); + if (client == NULL) { + perror("client malloc failed"); + close(fd); + return; + } + + client->sock_fd = fd; + client->buf_ev = bufferevent_socket_new(base, fd, BEV_OPT_CLOSE_ON_FREE); + + evutil_make_socket_nonblocking(fd); + bufferevent_setcb(client->buf_ev, netev_on_read, netev_on_write, netev_on_error, client); + bufferevent_setwatermark(client->buf_ev, EV_READ, 0, MAX_LINE); + + if(netcb_on_connect) + (*netcb_on_connect)(client); + + if(client->state == NET_CSTATE_OPEN) + bufferevent_enable(client->buf_ev, EV_READ | EV_WRITE); + } +} + + +// Public functions + +void net_start(int port, net_on_connect on_connect, net_on_read on_read, net_on_close on_close) { + evutil_socket_t listener; + struct sockaddr_in sin; + struct event *listener_event; + + evthread_use_pthreads(); + + //setvbuf(stdout, NULL, _IONBF, 0); + + netcb_on_connect = on_connect; + netcb_on_read = on_read; + netcb_on_close = on_close; + + base = event_base_new(); + if (!base) + err(1, "Failed to create event_base"); + + evthread_make_base_notifiable(base); + + sin.sin_family = AF_INET; + sin.sin_addr.s_addr = 0; + sin.sin_port = htons(1337); + listener = socket(AF_INET, SOCK_STREAM, 0); + evutil_make_socket_nonblocking(listener); + + if (bind(listener, (struct sockaddr*) &sin, sizeof(sin)) < 0) { + err(1, "bind failed"); + } + + if (listen(listener, 16) < 0) { + err(1, "listen failed"); + } + + listener_event = event_new(base, listener, EV_READ | EV_PERSIST, on_accept, (void*) base); + event_add(listener_event, NULL); + + event_base_dispatch(base); +} + + +void net_stop() { + event_base_loopbreak(base); +} + + +void net_send(NetClient *client, const char * msg) { + struct evbuffer *output = bufferevent_get_output(client->buf_ev); + evbuffer_add(output, msg, strlen(msg)); + evbuffer_add(output, "\n", 1); +} + +void net_close(NetClient *client) { + client->state = NET_CSTATE_CLOSING; + bufferevent_disable(client->buf_ev, EV_READ); +} + +void net_err(NetClient *client, const char * msg) { + struct evbuffer *output = bufferevent_get_output(client->buf_ev); + evbuffer_add(output, "ERROR: ", 7); + evbuffer_add(output, msg, strlen(msg)); + evbuffer_add(output, "\n", 1); + net_close(client); +} + +void net_set_user(NetClient *client, void *user) { + client->user = user; +} + +void net_get_user(NetClient *client, void **user) { + *user = client->user; +} + diff --git a/pixelnuke/net.h b/pixelnuke/net.h new file mode 100644 index 0000000..593ecdf --- /dev/null +++ b/pixelnuke/net.h @@ -0,0 +1,38 @@ +#ifndef NET_H_ +#define NET_H_ + +typedef struct NetClient NetClient; + +#define NET_CSTATE_OPEN 0 +#define NET_CSTATE_CLOSING 1 + +// Callback called immediately after a client connects +typedef void (*net_on_connect)(NetClient *client); + +// Callback called for each line of input. +// The char array is null-terminated and does not include the final line break. +// It is NOT owned by the callback and freed as soon as the callback returned. +typedef void (*net_on_read)(NetClient *client, char* line); + +// Callback called after a client disconnects. +// The second parameter is 0 for a normal client-induced disconnect and != 0 on errors. +typedef void (*net_on_close)(NetClient *client, int error); + +// Start the server and block until it is closed again. +void net_start(int port, net_on_connect on_connect, net_on_read on_read, net_on_close on_close); + +// Stop the server as soon as possible +void net_stop(); + +// Send a string to the client. A newline is added automatically. +void net_send(NetClient *client, const char * msg); +// Stop reading from this clients socket, send all bytes still in the output buffer, then close the connection. +void net_close(NetClient *client); +// Send an error message to the client, then close the connection. +void net_err(NetClient *client, const char * msg); + +// Get or set the user attachment, a pointer to an arbitrary data structure or NULL +void net_set_user(NetClient *client, void *user); +void net_get_user(NetClient *client, void **user); + +#endif /* NET_H_ */ diff --git a/pixelnuke/pixelnuke.c b/pixelnuke/pixelnuke.c new file mode 100644 index 0000000..ff0ba2f --- /dev/null +++ b/pixelnuke/pixelnuke.c @@ -0,0 +1,104 @@ +#include "net.h" +#include "canvas.h" + +#include +#include +#include //sprintf + +int px_width = 1024; +int px_height = 1024; + +const char * px_help_text = + "\ +PX x y: Get color at position (x,y)\n\ +PX x y rrggbb(aa): Draw a pixel (with optional alpha channel)\n\ +SIZE: Get canvas size"; + +// Helper functions + +static int util_str_starts_with(const char* prefix, const char* str) { + char cp, cs; + while ((cp = *prefix++) == (cs = *str++)) { + if (cp == 0) + return 1; + } + return !cp; +} + +// server callbacks +void px_on_connect(NetClient *client) { + +} + +void px_on_read(NetClient *client, char *line) { + if (util_str_starts_with("PX ", line)) { + const char * ptr = line + 3; + char * endptr = (char*) ptr; + errno = 0; + unsigned int x = strtoul(ptr, &endptr, 10); + if (endptr == ptr || errno) { + net_err(client, + "First parameter missing or invalid (should be decimal)"); + return; + } + unsigned int y = strtoul((ptr = endptr), &endptr, 10); + if (endptr == ptr || errno) { + net_err(client, + "Second parameter missing or invalid (should be decimal)"); + return; + } + if (*endptr == 0) { + char str[64]; + sprintf(str, "PX %u %u %x", x, y, 0xABCDEF); + net_send(client, str); + return; + } + unsigned int c = strtoul((ptr = endptr), &endptr, 16); + if (endptr == ptr || errno) { + net_err(client, + "Third parameter missing or invalid (should be hex color)"); + return; + } + printf("%d %d %u=%x\n", x, y, c, c); + } else if (util_str_starts_with("SIZE", line)) { + unsigned int w, h; + canvas_get_size(&w, &h); + char str[64]; + sprintf(str, "SIZE %d %d", w, h); + net_send(client, str); + } else if (util_str_starts_with("HELP", line)) { + net_send(client, px_help_text); + } +} + +void px_on_close(NetClient *client, int error) { +} + +void px_on_key(int key, int scancode, int mods) { + if (key == 300) { // F11 + int display = canvas_get_display(); + if(display<0) + canvas_fullscreen(0); + else + canvas_fullscreen(-1); + } else if (key == 301) { // F12 + canvas_fullscreen(canvas_get_display()+1); + } else if (key == 81 || key == 256) { // q or ESC + canvas_close(); + } +} + +void px_on_resize() {} +void px_on_window_close() { + printf("Window closed\n"); + net_stop(); +} + +int main(int argc, char **argv) { + canvas_start(1024, &px_on_window_close); + canvas_setcb_key(&px_on_key); + canvas_setcb_resize(&px_on_resize); + net_start(1337, &px_on_connect, &px_on_read, &px_on_close); + return 0; +} + diff --git a/pixelwar/src/de/paws/pixelwar/Drawable.java b/pixelwar/src/main/java/de/paws/pixelwar/Drawable.java similarity index 100% rename from pixelwar/src/de/paws/pixelwar/Drawable.java rename to pixelwar/src/main/java/de/paws/pixelwar/Drawable.java diff --git a/pixelwar/src/de/paws/pixelwar/Label.java b/pixelwar/src/main/java/de/paws/pixelwar/Label.java similarity index 100% rename from pixelwar/src/de/paws/pixelwar/Label.java rename to pixelwar/src/main/java/de/paws/pixelwar/Label.java diff --git a/pixelwar/src/de/paws/pixelwar/NetCanvas.java b/pixelwar/src/main/java/de/paws/pixelwar/NetCanvas.java similarity index 100% rename from pixelwar/src/de/paws/pixelwar/NetCanvas.java rename to pixelwar/src/main/java/de/paws/pixelwar/NetCanvas.java diff --git a/pixelwar/src/de/paws/pixelwar/PixelClientHandler.java b/pixelwar/src/main/java/de/paws/pixelwar/PixelClientHandler.java similarity index 100% rename from pixelwar/src/de/paws/pixelwar/PixelClientHandler.java rename to pixelwar/src/main/java/de/paws/pixelwar/PixelClientHandler.java diff --git a/pixelwar/src/de/paws/pixelwar/PixelServer.java b/pixelwar/src/main/java/de/paws/pixelwar/PixelServer.java similarity index 100% rename from pixelwar/src/de/paws/pixelwar/PixelServer.java rename to pixelwar/src/main/java/de/paws/pixelwar/PixelServer.java