summaryrefslogtreecommitdiff
path: root/src/base
diff options
context:
space:
mode:
Diffstat (limited to 'src/base')
-rw-r--r--src/base/Makefile67
-rw-r--r--src/base/arena.c233
-rw-r--r--src/base/arena.h43
-rw-r--r--src/base/arenaFile.c269
-rw-r--r--src/base/arenaFile.h22
-rw-r--r--src/base/bool.h13
-rw-r--r--src/base/checkFront.c136
-rw-r--r--src/base/checkFront.h22
-rwxr-xr-xsrc/base/director.c64
-rw-r--r--src/base/director.h18
-rw-r--r--src/base/fake_audio.c89
-rw-r--r--src/base/gun.c353
-rw-r--r--src/base/gun.h21
-rwxr-xr-xsrc/base/homeDirector.c42
-rwxr-xr-xsrc/base/homeDirector.h13
-rw-r--r--src/base/idManager.c107
-rw-r--r--src/base/idManager.h19
-rw-r--r--src/base/item.c620
-rw-r--r--src/base/item.h79
-rwxr-xr-xsrc/base/list.c241
-rwxr-xr-xsrc/base/list.h33
-rw-r--r--src/base/main.c126
-rw-r--r--src/base/main.h33
-rwxr-xr-xsrc/base/modules.c222
-rw-r--r--src/base/modules.h78
-rw-r--r--src/base/myTimer.c148
-rw-r--r--src/base/myTimer.h32
-rw-r--r--src/base/net_multiplayer.c172
-rw-r--r--src/base/net_multiplayer.h35
-rw-r--r--src/base/path.h33
-rw-r--r--src/base/protect.c88
-rw-r--r--src/base/protect.h30
-rw-r--r--src/base/proto.c713
-rw-r--r--src/base/proto.h81
-rw-r--r--src/base/server.c984
-rw-r--r--src/base/server.h93
-rw-r--r--src/base/shot.c369
-rw-r--r--src/base/shot.h61
-rw-r--r--src/base/space.c600
-rw-r--r--src/base/space.h38
-rw-r--r--src/base/storage.c138
-rw-r--r--src/base/storage.h16
-rw-r--r--src/base/string_length.h16
-rwxr-xr-xsrc/base/textFile.c163
-rwxr-xr-xsrc/base/textFile.h21
-rw-r--r--src/base/tux.c803
-rw-r--r--src/base/tux.h137
47 files changed, 7734 insertions, 0 deletions
diff --git a/src/base/Makefile b/src/base/Makefile
new file mode 100644
index 0000000..6de422d
--- /dev/null
+++ b/src/base/Makefile
@@ -0,0 +1,67 @@
+
+all: arena.o arenaFile.o director.o gun.o homeDirector.o checkFront.o idManager.o item.o list.o main.o modules.o myTimer.o net_multiplayer.o protect.o proto.o server.o shot.o space.o storage.o textFile.o tux.o
+
+arena.o: arena.c arena.h
+ $(CC) $(CFLAGS) -o arena.o -c arena.c
+
+arenaFile.o: arenaFile.c arenaFile.h
+ $(CC) $(CFLAGS) -o arenaFile.o -c arenaFile.c
+
+director.o: director.c director.h
+ $(CC) $(CFLAGS) -o director.o -c director.c
+
+gun.o: gun.c gun.h
+ $(CC) $(CFLAGS) -o gun.o -c gun.c
+
+homeDirector.o: homeDirector.c homeDirector.h
+ $(CC) $(CFLAGS) -o homeDirector.o -c homeDirector.c
+
+checkFront.o: checkFront.c checkFront.h
+ $(CC) $(CFLAGS) -o checkFront.o -c checkFront.c
+
+idManager.o: idManager.c idManager.h
+ $(CC) $(CFLAGS) -o idManager.o -c idManager.c
+
+item.o: item.c item.h
+ $(CC) $(CFLAGS) -o item.o -c item.c
+
+list.o: list.c list.h
+ $(CC) $(CFLAGS) -o list.o -c list.c
+
+main.o: main.c main.h
+ $(CC) $(CFLAGS) -o main.o -c main.c
+
+modules.o: modules.c modules.h
+ $(CC) $(CFLAGS) -o modules.o -c modules.c
+
+myTimer.o: myTimer.c myTimer.h
+ $(CC) $(CFLAGS) -o myTimer.o -c myTimer.c
+
+net_multiplayer.o: net_multiplayer.c net_multiplayer.h
+ $(CC) $(CFLAGS) -o net_multiplayer.o -c net_multiplayer.c
+
+protect.o: protect.c protect.h
+ $(CC) $(CFLAGS) -o protect.o -c protect.c
+
+server.o: server.c server.h
+ $(CC) $(CFLAGS) -o server.o -c server.c
+
+shot.o: shot.c shot.h
+ $(CC) $(CFLAGS) -o shot.o -c shot.c
+
+space.o: space.c space.h
+ $(CC) $(CFLAGS) -o space.o -c space.c
+
+storage.o: storage.c storage.h
+ $(CC) $(CFLAGS) -o storage.o -c storage.c
+
+textFile.o: textFile.c textFile.h
+ $(CC) $(CFLAGS) -o textFile.o -c textFile.c
+
+tux.o: tux.c tux.h
+ $(CC) $(CFLAGS) -o tux.o -c tux.c
+
+clean:
+ rm -rf *.o
+
+
diff --git a/src/base/arena.c b/src/base/arena.c
new file mode 100644
index 0000000..448ee5b
--- /dev/null
+++ b/src/base/arena.c
@@ -0,0 +1,233 @@
+
+#include <stdlib.h>
+#include <assert.h>
+#include <string.h>
+
+#include "base/main.h"
+#include "base/arena.h"
+#include "base/list.h"
+#include "base/tux.h"
+#include "base/shot.h"
+#include "base/item.h"
+#include "base/myTimer.h"
+#include "base/modules.h"
+
+#ifndef PUBLIC_SERVER
+#include "screen/screen_world.h"
+#include "client/layer.h"
+#endif
+
+static arena_t *currentArena;
+
+void setCurrentArena(arena_t *p)
+{
+ currentArena = p;
+}
+
+arena_t* getCurrentArena()
+{
+ return currentArena;
+}
+
+arena_t* newArena(int w, int h)
+{
+ arena_t *new;
+ int zone_w, zone_h;
+
+ new = malloc( sizeof(arena_t) );
+
+#ifndef PUBLIC_SERVER
+ new->background = NULL;
+ strcpy(new->music, "");
+#endif
+
+ new->w = w;
+ new->h = h;
+
+ new->listTimer = newList();
+
+ if( w > 800 || h > 600)
+ {
+ zone_w = 320;
+ zone_h = 240;
+ }
+ else
+ {
+ zone_w = 80;
+ zone_h = 60;
+ }
+
+ new->spaceTux = newSpace(w, h, zone_w, zone_h, getStatusTux, setStatusTux);
+ new->spaceItem = newSpace(w, h, zone_w, zone_h, getStatusItem, setStatusItem);
+ new->spaceShot = newSpace(w, h, zone_w, zone_h, getStatusShot, setStatusShot);
+
+ return new;
+}
+
+int conflictSpace(int x1,int y1,int w1,int h1,int x2,int y2,int w2,int h2)
+{
+ return (x1<x2+w2 && x2<x1+w1 && y1<y2+h2 && y2<y1+h1);
+}
+
+int isFreeSpace(arena_t *arena, int x, int y, int w, int h)
+{
+ if( isConflictWithObjectFromSpace(arena->spaceTux, x, y, w, h) )return 0;
+ if( isConflictWithObjectFromSpace(arena->spaceShot, x, y, w, h) )return 0;
+ if( isConflictWithObjectFromSpace(arena->spaceItem, x, y, w, h) )return 0;
+ if( isConflictWithObjectFromSpace(arena->spaceShot, x, y, w, h) )return 0;
+
+ if( isConflictModule(x, y, w, h) )return 0;
+
+ return 1;
+}
+
+void findFreeSpace(arena_t *arena, int *x, int *y, int w, int h)
+{
+ int z_x;
+ int z_y;
+
+ assert( x != NULL );
+ assert( y != NULL );
+
+ do{
+ z_x = random() % WINDOW_SIZE_X;//arena->w;
+ z_y = random() % WINDOW_SIZE_Y;//arena->h;
+ }while( isFreeSpace(arena, z_x, z_y ,w ,h) == 0 );
+
+ *x = z_x;
+ *y = z_y;
+}
+
+void getCenterScreen(int *screen_x, int *screen_y, int x, int y)
+{
+ arena_t *arena;
+
+ arena = getCurrentArena();
+
+ *screen_x = x - WINDOW_SIZE_X/2;
+ *screen_y = y - WINDOW_SIZE_Y/2;
+
+ if( *screen_x < 0 )
+ {
+ *screen_x = 0;
+ }
+
+ if( *screen_y < 0 )
+ {
+ *screen_y = 0;
+ }
+
+ if( *screen_x + WINDOW_SIZE_X >= arena->w )
+ {
+ *screen_x = arena->w - WINDOW_SIZE_X;
+ }
+
+ if( *screen_y + WINDOW_SIZE_Y >= arena->h )
+ {
+ *screen_y = arena->h - WINDOW_SIZE_Y;
+ }
+}
+
+#ifndef PUBLIC_SERVER
+
+void drawArena(arena_t *arena)
+{
+ int screen_x, screen_y;
+ tux_t *tux = NULL;
+ int i, j;
+
+ tux = getControlTux(TUX_CONTROL_KEYBOARD_RIGHT);
+
+ if( tux == NULL )
+ {
+ return;
+ }
+/*
+ screen_x = tux->x - WINDOW_SIZE_X/2;
+ screen_y = tux->y - WINDOW_SIZE_Y/2;
+*/
+
+ getCenterScreen(&screen_x, &screen_y, tux->x, tux->y);
+
+ for( i = screen_y/arena->background->h ;
+ i <= screen_y/arena->background->h + WINDOW_SIZE_Y/arena->background->h ; i++ )
+ {
+ for( j = screen_x/arena->background->w ;
+ j <= screen_x/arena->background->w + WINDOW_SIZE_X/arena->background->w ; j++ )
+ {
+ addLayer(arena->background,
+ j * arena->background->w,
+ i * arena->background->h,
+ 0, 0, arena->background->w, arena->background->h, -100);
+ }
+
+ }
+
+ listDoEmpty(listHelp);
+ getObjectFromSpace(arena->spaceTux, screen_x, screen_y, WINDOW_SIZE_X, WINDOW_SIZE_Y, listHelp);
+ drawListTux(listHelp);
+
+ listDoEmpty(listHelp);
+ getObjectFromSpace(arena->spaceItem, screen_x, screen_y, WINDOW_SIZE_X, WINDOW_SIZE_Y, listHelp);
+ drawListItem(listHelp);
+
+ listDoEmpty(listHelp);
+ getObjectFromSpace(arena->spaceShot, screen_x, screen_y, WINDOW_SIZE_X, WINDOW_SIZE_Y, listHelp);
+ drawListShot(listHelp);
+
+ //printSpace(arena->spaceShot);
+
+ drawModule(screen_x, screen_y, WINDOW_SIZE_X, WINDOW_SIZE_Y);
+/*
+ my_time_t t;
+
+ t = getMyTime();
+*/
+ if( tux == NULL )
+ {
+ drawLayerCenter(WINDOW_SIZE_X/2, WINDOW_SIZE_Y/2);
+ }
+ else
+ {
+ drawLayerCenter(tux->x, tux->y);
+ }
+
+// printf("time = %d\n", getMyTime() - t );
+}
+
+#endif
+
+void eventArena(arena_t *arena)
+{
+ int i;
+
+ //eventConflictTuxWithTeleport(arena->listTux, arena->listTeleport);
+ //eventConflictTuxWithShot(arena);
+
+ for( i = 0 ; i < 8 ; i++)
+ {
+ eventMoveListShot(arena);
+ checkShotIsInTuxScreen(arena);
+ //eventConflictShotWithWall(arena->listWall, arena->listShot);
+ //eventConflictShotWithTeleport(arena->listTeleport, arena->listShot);
+ //eventConflictShotWithPipe(arena->listPipe, arena->listShot);
+ eventConflictShotWithItem(arena);
+ eventConflictTuxWithShot(arena);
+ eventModule();
+ }
+
+ eventListItem(arena->spaceItem);
+
+ eventListTux(arena->spaceTux->list);
+
+ eventTimer(arena->listTimer);
+}
+
+void destroyArena(arena_t *p)
+{
+ destroySpaceWithObject(p->spaceTux, destroyTux);
+ destroySpaceWithObject(p->spaceItem, destroyItem);
+ destroySpaceWithObject(p->spaceShot, destroyShot);
+ destroyTimer(p->listTimer);
+ free(p);
+}
diff --git a/src/base/arena.h b/src/base/arena.h
new file mode 100644
index 0000000..57792c5
--- /dev/null
+++ b/src/base/arena.h
@@ -0,0 +1,43 @@
+
+#ifndef ARENA_H
+
+#define ARENA_H
+
+#include "base/main.h"
+
+#ifndef PUBLIC_SERVER
+#include "client/interface.h"
+#endif
+
+#include "base/list.h"
+#include "base/space.h"
+
+typedef struct arena_struct
+{
+#ifndef PUBLIC_SERVER
+ char music[STR_SIZE];
+
+ SDL_Surface *background;
+#endif
+ int w, h;
+ list_t *listTimer;
+ //list_t *listTux;
+ space_t *spaceShot;
+ space_t *spaceTux;
+ space_t *spaceItem;
+} arena_t;
+
+extern void setCurrentArena(arena_t *p);
+extern arena_t* getCurrentArena();
+extern arena_t* newArena(int w, int h);
+extern int conflictSpace(int x1,int y1,int w1,int h1,int x2,int y2,int w2,int h2);
+extern int isFreeSpace(arena_t *arena, int x, int y, int w, int h);
+extern void findFreeSpace(arena_t *arena, int *x, int *y, int w, int h);
+extern void getCenterScreen(int *screen_x, int *screen_y, int x, int y);
+#ifndef PUBLIC_SERVER
+extern void drawArena(arena_t *arena);
+#endif
+extern void eventArena(arena_t *arena);
+extern void destroyArena(arena_t *p);
+
+#endif
diff --git a/src/base/arenaFile.c b/src/base/arenaFile.c
new file mode 100644
index 0000000..9fe683e
--- /dev/null
+++ b/src/base/arenaFile.c
@@ -0,0 +1,269 @@
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+
+#include "base/main.h"
+#include "base/list.h"
+#include "base/textFile.h"
+#include "base/arenaFile.h"
+#include "base/arena.h"
+#include "base/tux.h"
+#include "base/shot.h"
+#include "base/item.h"
+#include "base/director.h"
+#include "base/modules.h"
+
+#ifndef PUBLIC_SERVER
+#include "client/configFile.h"
+#include "client/image.h"
+#include "audio/music.h"
+#endif
+
+static list_t *listArenaFile;
+
+static bool_t isArenaFileInit = FALSE;
+
+bool_t isAreaFileInicialized()
+{
+ return isArenaFileInit;
+}
+
+int getArenaValue(char *line, char *env, char *val, int len)
+{
+ char *offset_env;
+ char *offset_val_begin;
+ char *offset_val_end;
+ char clone_env[STR_SIZE];
+ int val_len;
+
+ strcpy(clone_env, " ");
+ strcat(clone_env, env);
+
+ offset_env = strstr(line, clone_env);
+ if( offset_env == NULL )return -1;
+
+ offset_val_begin = strchr(offset_env, '"');
+ if( offset_val_begin == NULL )return -1;
+
+ offset_val_end = strchr(offset_val_begin+1, '"');
+ if( offset_val_end == NULL )return -1;
+
+ val_len = (int)(offset_val_end - ( offset_val_begin + 1) );
+ if( val_len > len - 1 ) val_len = len - 1;
+
+ memset(val, 0, len);
+ memcpy(val, offset_val_begin+1, val_len);
+
+ return 0;
+}
+
+
+static void cmd_arena(arena_t **arena, char *line)
+{
+ char str_image[STR_SIZE];
+ char str_w[STR_SIZE];
+ char str_h[STR_SIZE];
+
+ if( getArenaValue(line, "background", str_image, STR_SIZE) != 0 )return;
+ if( getArenaValue(line, "w", str_w, STR_SIZE) != 0 )return;
+ if( getArenaValue(line, "h", str_h, STR_SIZE) != 0 )return;
+
+ (*arena) = newArena(atoi(str_w), atoi(str_h));
+#ifndef PUBLIC_SERVER
+ (*arena)->background = getImage(IMAGE_GROUP_USER, str_image);
+#endif
+ //(*arena)->w = atoi(str_w);
+ //(*arena)->h = atoi(str_h);
+ setCurrentArena(*arena);
+ printf("new arena\n");
+}
+
+static void cmd_loadModule(char *line)
+{
+ char str_file[STR_SIZE];
+
+ if( getArenaValue(line, "file", str_file, STR_SIZE) != 0 )return;
+
+ loadModule(str_file);
+}
+
+#ifndef PUBLIC_SERVER
+
+static void cmd_loadImage(char *line)
+{
+ char str_file[STR_SIZE];
+ char str_name[STR_SIZE];
+ char str_alpha[STR_SIZE];
+
+ if( getArenaValue(line, "file", str_file, STR_SIZE) != 0 )return;
+ if( getArenaValue(line, "name", str_name, STR_SIZE) != 0 )return;
+ if( getArenaValue(line, "alpha", str_alpha, STR_SIZE) != 0 )return;
+
+ addImageData(str_file, isYesOrNO(str_alpha), str_name, IMAGE_GROUP_USER);
+}
+
+static void cmd_loadMusic(char *line)
+{
+ char str_file[STR_SIZE];
+ char str_name[STR_SIZE];
+
+ if( getArenaValue(line, "file", str_file, STR_SIZE) != 0 )return;
+ if( getArenaValue(line, "name", str_name, STR_SIZE) != 0 )return;
+
+#ifndef NO_SOUND
+ addMusic(str_file, str_name, MUSIC_GROUP_USER);
+#endif
+}
+
+static void cmd_playMusic(arena_t *arena, char *line)
+{
+ char str_music[STR_SIZE];
+
+ if( getArenaValue(line, "music", str_music, STR_SIZE) != 0 )return;
+
+ strcpy(arena->music, str_music);
+}
+
+#endif
+
+int getArenaCount()
+{
+ return listArenaFile->count;
+}
+
+static char *getArenaStatus(int id, char *s)
+{
+ textFile_t *ts;
+ int len;
+ int i;
+
+ ts = (textFile_t *) listArenaFile->list[id];
+ len = strlen(s);
+
+ for( i = 0 ; i < ts->text->count ; i++ )
+ {
+ char *line;
+ line = (char *) (ts->text->list[i]);
+
+ if( strncmp(line, s, len) == 0 )
+ {
+ return line+len+1;
+ }
+ }
+
+ return NULL;
+}
+
+char *getArenaName(int id)
+{
+ char *ret;
+
+ ret = getArenaStatus(id, "name");
+
+ return ( ret != NULL ? ret : "arena_no_name" );
+}
+
+char *getArenaNetName(int id)
+{
+ char *ret;
+
+ ret = getArenaStatus(id, "netName");
+
+ return ( ret != NULL ? ret : "arena_no_net_name" );
+}
+
+int getArenaIdFormNetName(char *s)
+{
+ int i;
+
+ for( i = 0 ; i < listArenaFile->count ; i++ )
+ {
+ if( strcmp(getArenaNetName(i), s) == 0 )
+ {
+ return i;
+ }
+ }
+
+ return -1;
+}
+
+char *getArenaImage(int id)
+{
+ return getArenaStatus(id, "screen");
+}
+
+arena_t* getArena(int id)
+{
+ textFile_t *ts;
+ arena_t *arena;
+ int i;
+
+ ts = (textFile_t *) listArenaFile->list[id];
+
+ for( i = 0 ; i < ts->text->count ; i++ )
+ {
+ char *line;
+ line = (char *) (ts->text->list[i]);
+
+ cmdModule(line);
+
+#ifndef PUBLIC_SERVER
+ if( strncmp(line, "loadImage", 9) == 0 )cmd_loadImage(line);
+ if( strncmp(line, "loadMusic", 9) == 0 )cmd_loadMusic(line);
+ if( strncmp(line, "playMusic", 9) == 0 )cmd_playMusic(arena, line);
+#endif
+
+ if( strncmp(line, "arena", 5) == 0 )cmd_arena(&arena, line);
+ if( strncmp(line, "loadModule", 10) == 0 )cmd_loadModule(line);
+ //if( strncmp(line, "wall", 4) == 0 )cmd_wall(arena, line);
+ //if( strncmp(line, "teleport", 8) == 0 )cmd_teleport(arena, line);
+ //if( strncmp(line, "pipe", 4) == 0 )cmd_pipe(arena, line);
+ }
+
+ return arena;
+}
+
+void initArenaFile()
+{
+ director_t *p;
+ int i;
+
+#ifndef PUBLIC_SERVER
+ assert( isImageInicialized() == TRUE );
+#endif
+
+ isArenaFileInit = TRUE;
+ listArenaFile = newList();
+
+ p = loadDirector(PATH_ARENA);
+
+ for( i = 0 ; i < p->list->count ; i++ )
+ {
+ char *line;
+
+ line = (char *)( p->list->list[i] );
+
+ if( strstr(line, ".map") != NULL && strstr(line, "~") == NULL )
+ {
+ char path[STR_PATH_SIZE];
+
+ sprintf(path, PATH_ARENA "%s", line);
+
+ printf("load map %s\n", line);
+
+ accessExistFile(path);
+ addList(listArenaFile, loadTextFile(path));
+ }
+ }
+
+ destroyDirector(p);
+}
+
+void quitArenaFile()
+{
+ isArenaFileInit = FALSE;
+ destroyListItem(listArenaFile, destroyTextFile);
+}
+
diff --git a/src/base/arenaFile.h b/src/base/arenaFile.h
new file mode 100644
index 0000000..e2e8108
--- /dev/null
+++ b/src/base/arenaFile.h
@@ -0,0 +1,22 @@
+
+#ifndef ARENA_FILE_H
+
+#define ARENA_FILE_H
+
+#include "base/main.h"
+#include "base/arena.h"
+
+#define PUBLIC_SERVER_PATH_ARENA "./arena/"
+
+extern int getArenaValue(char *line, char *env, char *val, int len);
+extern bool_t isArenaFileInicialized();
+extern void initArenaFile();
+extern int getArenaCount();
+extern char *getArenaName(int id);
+extern char *getArenaNetName(int id);
+extern int getArenaIdFormNetName(char *s);
+extern char *getArenaImage(int id);
+extern arena_t* getArena(int id);
+extern void quitArenaFile();
+
+#endif
diff --git a/src/base/bool.h b/src/base/bool.h
new file mode 100644
index 0000000..d122b85
--- /dev/null
+++ b/src/base/bool.h
@@ -0,0 +1,13 @@
+
+#ifndef BOOL_H
+
+#define BOOL_H
+
+#include "main.h"
+
+#define bool_t int
+
+#define TRUE 1
+#define FALSE 0
+
+#endif
diff --git a/src/base/checkFront.c b/src/base/checkFront.c
new file mode 100644
index 0000000..37b0ace
--- /dev/null
+++ b/src/base/checkFront.c
@@ -0,0 +1,136 @@
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+
+#include "base/main.h"
+#include "base/list.h"
+#include "base/myTimer.h"
+#include "base/checkFront.h"
+#include "base/idManager.h"
+#include "base/server.h"
+
+typedef struct struct_checkfront_t
+{
+ char *msg;
+ my_time_t time;
+ int id;
+ int count;
+ int type;
+} checkfront_t;
+
+static checkfront_t* newCheck(char *s, int type, int id)
+{
+ checkfront_t *new;
+
+ assert( s != NULL );
+
+ new = malloc( sizeof(checkfront_t) );
+ memset(new, 0, sizeof(checkfront_t));
+
+ new->msg = strdup(s);
+ new->time = getMyTime();
+ new->id = id;
+ new->type = type;
+ new->count = 0;
+
+ return new;
+}
+
+static void destroyCheck(checkfront_t *p)
+{
+ assert( p != NULL );
+
+ free(p->msg);
+ free(p);
+}
+
+list_t* newCheckFront()
+{
+ return newList();
+}
+
+void addMsgInCheckFront(list_t *list, char *msg, int type, int id)
+{
+ addList(list, newCheck(msg, type, id) );
+}
+
+void eventMsgInCheckFront(client_t *client)
+{
+ my_time_t currentTime;
+ int i;
+
+ currentTime = getMyTime();
+
+ for( i = 0 ; i < client->listSendMsg->count ; i++ )
+ {
+ checkfront_t *this;
+
+ this = (checkfront_t *)client->listSendMsg->list[i];
+
+ switch( this->type )
+ {
+ case CHECK_FORNT_TYPE_SIMPLE :
+ sendClient(client, this->msg);
+ delListItem(client->listSendMsg, i, destroyCheck);
+ i--;
+ break;
+
+ case CHECK_FORNT_TYPE_CHECK :
+ if( this->count == 0 || currentTime - this->time > CHECK_FRONT_SEND_TIME_INTERVAL )
+ {
+ sendClient(client, this->msg);
+ this->time = currentTime;
+ this->count++;
+ }
+
+ if( this->count > CHECK_FRONT_MAX_COUNT_SEND )
+ {
+ if( isRegisterID(this->id) != -1 )
+ {
+ delID(this->id);
+ }
+
+ delListItem(client->listSendMsg, i, destroyCheck);
+ i--;
+ }
+ break;
+
+ default :
+ assert( ! "Zly typ !" );
+ break;
+ }
+ }
+}
+
+void delMsgInCheckFront(list_t *listCheckFront, int id)
+{
+ int i;
+
+ for( i = 0 ; i < listCheckFront->count ; i++ )
+ {
+ checkfront_t *this;
+
+ this = (checkfront_t *)listCheckFront->list[i];
+
+ if( this->id == id )
+ {
+ if( isRegisterID(this->id) != -1 )
+ {
+ delID(this->id);
+ }
+
+ delListItem(listCheckFront, i, destroyCheck);
+ return;
+ }
+ }
+}
+
+void destroyCheckFront(list_t *p)
+{
+ assert( p != NULL );
+
+ destroyListItem(p, destroyCheck);
+}
+
diff --git a/src/base/checkFront.h b/src/base/checkFront.h
new file mode 100644
index 0000000..3beb370
--- /dev/null
+++ b/src/base/checkFront.h
@@ -0,0 +1,22 @@
+
+#ifndef CHECK_FRONT_H
+
+#define CHECK_FRONT_H
+
+#include "base/list.h"
+#include "base/server.h"
+
+#define CHECK_FRONT_SEND_TIME_INTERVAL 100
+#define CHECK_FRONT_MAX_COUNT_SEND 30
+
+#define CHECK_FRONT_ID_NONE -1
+#define CHECK_FORNT_TYPE_SIMPLE 1
+#define CHECK_FORNT_TYPE_CHECK 2
+
+extern list_t* newCheckFront();
+extern void addMsgInCheckFront(list_t *list, char *msg, int type, int id);
+extern void eventMsgInCheckFront(client_t *client);
+extern void delMsgInCheckFront(list_t *listCheckFront, int id);
+extern void destroyCheckFront(list_t *p);
+
+#endif
diff --git a/src/base/director.c b/src/base/director.c
new file mode 100755
index 0000000..fede2c3
--- /dev/null
+++ b/src/base/director.c
@@ -0,0 +1,64 @@
+
+#include <dirent.h>
+#include <sys/types.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <assert.h>
+
+#include "base/main.h"
+#include "base/list.h"
+
+typedef struct director_struct
+{
+ char *path;
+ list_t *list;
+} director_t;
+
+director_t* loadDirector(char *s)
+{
+ director_t *new;
+ DIR *dir;
+ struct dirent *item;
+ char path[STR_PATH_SIZE];
+
+ assert( s != 0 );
+
+ new = malloc( sizeof(director_t) );
+ memset(new, 0, sizeof(director_t) );
+
+ new->list = newList();
+
+ if( s[0] == '/' )
+ {
+ strcpy(path, s);
+ }
+ else
+ {
+ getcwd(path, STR_PATH_SIZE);
+ strcat(path, s+1);
+ }
+
+ new->path = strdup(path);
+
+ dir = opendir(new->path);
+
+ while( ( item = readdir(dir) ) != NULL )
+ addList(new->list, strdup(item->d_name) );
+
+ closedir(dir);
+
+ return new;
+}
+
+void destroyDirector(director_t *p)
+{
+ assert( p != NULL );
+
+ destroyListItem(p->list, free);
+ free(p->path);
+ free(p);
+}
+
+
diff --git a/src/base/director.h b/src/base/director.h
new file mode 100644
index 0000000..20e577c
--- /dev/null
+++ b/src/base/director.h
@@ -0,0 +1,18 @@
+
+#ifndef DIRECTOR_H
+
+#define DIRECTOR_H
+
+#include "base/main.h"
+#include "base/list.h"
+
+typedef struct director_struct
+{
+ char *path;
+ list_t *list;
+} director_t;
+
+extern director_t* loadDirector(char *s);
+extern void destroyDirector(director_t *p);
+
+#endif
diff --git a/src/base/fake_audio.c b/src/base/fake_audio.c
new file mode 100644
index 0000000..2149c86
--- /dev/null
+++ b/src/base/fake_audio.c
@@ -0,0 +1,89 @@
+
+#include "base/main.h"
+#include "base/fake_audio.h"
+
+bool_t isAudioInicialized()
+{
+ return TRUE;
+}
+
+void initAudio()
+{
+}
+
+void quitAudio()
+{
+}
+
+bool_t isSoundInicialized()
+{
+ return TRUE;
+}
+
+void initSound()
+{
+}
+
+void addSound(char *file, char *name, int group)
+{
+}
+
+void playSound(char *name, int group)
+{
+}
+
+void setSoundActive(bool_t n)
+{
+}
+
+bool_t isSoundActive()
+{
+ return FALSE;
+}
+
+void quitSound()
+{
+}
+
+bool_t isMusicInicialized()
+{
+ return FALSE;
+}
+
+void initMusic()
+{
+}
+
+void addMusic(char *file, char *name, int group)
+{
+}
+
+void stopMusic()
+{
+}
+
+void playMusic(char *name, int group)
+{
+}
+
+void setMusicActive(bool_t n)
+{
+}
+
+bool_t isMusicActive()
+{
+ return FALSE;
+}
+
+char* getCurrentMusic()
+{
+ return "no_sound";
+}
+
+void delAllMusicInGroup(int group)
+{
+}
+
+void quitMusic()
+{
+}
diff --git a/src/base/gun.c b/src/base/gun.c
new file mode 100644
index 0000000..3cd6122
--- /dev/null
+++ b/src/base/gun.c
@@ -0,0 +1,353 @@
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <assert.h>
+
+#include "base/main.h"
+#include "base/arena.h"
+#include "base/tux.h"
+#include "base/shot.h"
+#include "base/myTimer.h"
+#include "base/item.h"
+#include "base/gun.h"
+#include "base/proto.h"
+#include "base/net_multiplayer.h"
+
+#ifndef PUBLIC_SERVER
+#include "audio/sound.h"
+
+#include "client/interface.h"
+#include "client/term.h"
+
+#include "screen/screen_world.h"
+#endif
+
+#ifdef PUBLIC_SERVER
+#include "server/publicServer.h"
+#endif
+
+static void modificiationCopuse(int courser, int right_x, int right_y, int *dest_x, int *dest_y)
+{
+ assert( dest_x != NULL );
+ assert( dest_y != NULL );
+
+ switch( courser )
+ {
+ case TUX_UP :
+ *dest_x = right_y;
+ *dest_y = -right_x;
+ break;
+ case TUX_RIGHT :
+ *dest_x = right_x;
+ *dest_y = right_y;
+ break;
+ case TUX_LEFT :
+ *dest_x = -right_x;
+ *dest_y = right_y;
+ break;
+ case TUX_DOWN :
+ *dest_x = right_y;
+ *dest_y = right_x;
+ break;
+ default :
+ assert( ! "V premennej courser je zly smer !" );
+ break;
+ }
+}
+
+static void addShotTrivial(tux_t *tux, int x, int y, int px, int py, int gun)
+{
+ int dest_x = 0, dest_y = 0;
+ int dest_px = 0, dest_py = 0;
+ shot_t *shot;
+
+ modificiationCopuse(tux->position, px, py, &dest_px, &dest_py);
+ modificiationCopuse(tux->position, x, y, &dest_x, &dest_y);
+
+ if( gun == GUN_LASSER )
+ {
+ switch( tux->position )
+ {
+ case TUX_UP :
+ dest_y -= GUN_LASSER_HORIZONTAL;
+ break;
+ case TUX_RIGHT :
+ break;
+ case TUX_LEFT :
+ dest_x -= GUN_LASSER_HORIZONTAL;
+ break;
+ case TUX_DOWN :
+ break;
+ }
+ }
+
+ shot = newShot(tux->x + dest_x, tux->y + dest_y, dest_px, dest_py, gun, tux->id);
+
+/*
+ if( isFreeSpace( getCurrentArena(), shot->x, shot->y, shot->w, shot->h ) == 0 )
+ {
+ destroyShot(shot);
+ return;
+ }
+*/
+ //addList( getCurrentArena()->listShot, shot );
+ addObjectToSpace(getCurrentArena()->spaceShot, shot);
+
+ if( getNetTypeGame() == NET_GAME_TYPE_SERVER )
+ {
+ client_t *thisClient;
+
+ thisClient = getClientFromTux(tux);
+
+ if( thisClient != NULL )
+ {
+ proto_send_shot_server(PROTO_SEND_ONE, thisClient, shot);
+ }
+
+ proto_send_shot_server(PROTO_SEND_ALL_SEES_TUX, thisClient, shot);
+ }
+
+}
+
+static void addShot(tux_t *tux,int x, int y, int px, int py)
+{
+ int gun;
+
+ if( getNetTypeGame() == NET_GAME_TYPE_CLIENT )
+ {
+ return;
+ }
+
+ if( tux->gun == GUN_BOMBBALL )
+ {
+ gun = GUN_BOMBBALL;
+ }
+ else if( tux->gun == GUN_LASSER )
+ {
+ gun = GUN_LASSER;
+ }
+ else
+ {
+ gun = GUN_SIMPLE;
+ }
+
+ if( tux->bonus == BONUS_4X )
+ {
+ int zal;
+ int i;
+
+ zal = tux->position;
+
+ for( i = 0 ; i < 4 ; i++ )
+ {
+ switch( i )
+ {
+ case 0 : tux->position = TUX_UP; break;
+ case 1 : tux->position = TUX_RIGHT; break;
+ case 2 : tux->position = TUX_LEFT; break;
+ case 3 : tux->position = TUX_DOWN; break;
+ }
+
+ addShotTrivial(tux, x, y, px, py, gun);
+ }
+
+ tux->position = zal;
+ }
+ else
+ {
+ addShotTrivial(tux, x, y, px, py, gun);
+ }
+}
+
+static void shotInGunSimpe(tux_t *tux)
+{
+ addShot(tux, 0, 0, +5, 0);
+}
+
+static void shotInGunDualSimpe(tux_t *tux)
+{
+ addShot(tux, 0, -10, +6, 0);
+ addShot(tux, 0, +10, +6, 0);
+}
+
+static void shotInGunScatter(tux_t *tux)
+{
+ int i;
+
+ for( i = -2 ; i <= +2 ; i++ )
+ {
+ addShot(tux, 0, 0, +8, i);
+ }
+}
+
+static void timer_addShotTimer(void *p)
+{
+ tux_t *tux;
+ int id;
+ int gun;
+
+ id = * ((int *)p);
+ free(p);
+
+ tux = getObjectFromSpaceWithID(getCurrentArena()->spaceTux, id);
+
+ if( tux == NULL )return;
+
+ if( tux->status != TUX_STATUS_ALIVE )return;
+
+ gun = tux->gun;
+ tux->gun = GUN_SIMPLE;
+ addShot(tux, 0, 0, +6, 0);
+ tux->gun = gun;
+}
+
+static void shotInGunTommy(tux_t *tux)
+{
+ int i;
+
+ for( i = 0 ; i < 10 ; i++ )
+ {
+ addTaskToTimer(getCurrentArena()->listTimer, TIMER_ONE, timer_addShotTimer, newInt(tux->id), i * 100 );
+ }
+}
+
+static void timer_addLaserTimer(void *p)
+{
+ tux_t *tux;
+ int id;
+ int gun;
+
+ id = * ((int *)p);
+ free(p);
+
+ tux = getObjectFromSpaceWithID(getCurrentArena()->spaceTux, id);
+
+ if( tux == NULL )return;
+
+ if( tux->status != TUX_STATUS_ALIVE )return;
+
+ gun = tux->gun;
+ tux->gun = GUN_LASSER;
+
+ addShot(tux, 0, 0, +10, 0);
+
+ tux->gun = gun;
+}
+
+static void shotInGunLasser(tux_t *tux)
+{
+ int i;
+
+ for( i = 0 ; i < 50 ; i++ )
+ {
+ addTaskToTimer(getCurrentArena()->listTimer, TIMER_ONE, timer_addLaserTimer, newInt(tux->id), i * 10 );
+ }
+}
+
+static void putInGunMine(tux_t *tux)
+{
+ int x, y;
+ arena_t *arena;
+
+ x = tux->x;
+ y = tux->y;
+
+ switch( tux->position )
+ {
+ case TUX_UP :
+ y += TUX_HEIGHT;
+ break;
+ case TUX_RIGHT :
+ x -= TUX_WIDTH;
+ break;
+ case TUX_LEFT :
+ x += TUX_WIDTH;
+ break;
+ case TUX_DOWN :
+ y -= TUX_HEIGHT;
+ break;
+ }
+
+ arena = getCurrentArena();
+
+ if( isFreeSpace(getCurrentArena(), x, y, ITEM_MINE_WIDTH, ITEM_MINE_HEIGHT) )
+ {
+ item_t *item;
+
+#ifndef PUBLIC_SERVER
+ char msg[STR_SIZE];
+#ifndef NO_SOUND
+ playSound("put_mine", SOUND_GROUP_BASE);
+#endif
+ sprintf(msg, "tux with id %d pu mine\n", tux->id);
+ appendTextInTerm(msg);
+#endif
+
+ tux->shot[tux->gun]--;
+
+ if( getNetTypeGame() != NET_GAME_TYPE_CLIENT )
+ {
+ item = newItem(x, y, ITEM_MINE, tux->id);
+
+ if( getNetTypeGame() == NET_GAME_TYPE_SERVER )
+ {
+ proto_send_additem_server(PROTO_SEND_ALL, NULL, item);
+ }
+
+ addObjectToSpace(arena->spaceItem, item );
+ }
+ }
+}
+
+static void shotInGunBombball(tux_t *tux)
+{
+ addShot(tux, 0, 0, +10, 0);
+}
+
+void shotInGun(tux_t *tux)
+{
+ if( tux->bonus != BONUS_SHOT && tux->gun != GUN_MINE )
+ {
+ tux->shot[tux->gun]--;
+ }
+
+ switch( tux->gun )
+ {
+ case GUN_SIMPLE :
+#ifndef NO_SOUND
+ playSound("gun_revolver", SOUND_GROUP_BASE);
+#endif
+ shotInGunSimpe(tux);
+ break;
+ case GUN_DUAL_SIMPLE :
+#ifndef NO_SOUND
+ playSound("gun_revolver", SOUND_GROUP_BASE);
+#endif
+ shotInGunDualSimpe(tux);
+ break;
+ case GUN_SCATTER :
+#ifndef NO_SOUND
+ playSound("gun_scatter", SOUND_GROUP_BASE);
+#endif
+ shotInGunScatter(tux);
+ break;
+ case GUN_TOMMY :
+#ifndef NO_SOUND
+ playSound("gun_tommy", SOUND_GROUP_BASE);
+#endif
+ shotInGunTommy(tux);
+ break;
+ case GUN_LASSER :
+#ifndef NO_SOUND
+ playSound("gun_lasser", SOUND_GROUP_BASE);
+#endif
+ shotInGunLasser(tux);
+ break;
+ case GUN_BOMBBALL :
+ shotInGunBombball(tux);
+ break;
+ case GUN_MINE :
+ putInGunMine(tux);
+ break;
+ }
+}
diff --git a/src/base/gun.h b/src/base/gun.h
new file mode 100644
index 0000000..4986660
--- /dev/null
+++ b/src/base/gun.h
@@ -0,0 +1,21 @@
+
+#ifndef GUN_H
+
+#define GUN_H
+
+#include "main.h"
+
+#define GUN_SHOT_WIDTH 5
+#define GUN_SHOT_HEIGHT 5
+
+#define GUN_LASSER_HORIZONTAL 50
+#define GUN_SHOT_VERTICAL 5
+
+#define GUN_BOMBBALL_WIDTH 20
+#define GUN_BOMBBALL_HEIGHT 20
+
+#include "tux.h"
+
+extern void shotInGun(tux_t *p);
+
+#endif
diff --git a/src/base/homeDirector.c b/src/base/homeDirector.c
new file mode 100755
index 0000000..0533d2e
--- /dev/null
+++ b/src/base/homeDirector.c
@@ -0,0 +1,42 @@
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <assert.h>
+#include <sys/stat.h>
+
+#include "base/main.h"
+#include "base/homeDirector.h"
+
+static char homeDirector[STR_PATH_SIZE];
+
+void createHomeDirector()
+{
+ char *envHome;
+
+ envHome = getenv("HOME");
+
+ if( envHome == NULL )
+ {
+ fprintf(stderr, "Environment HOME not found !\n");
+ exit(0);
+ }
+
+ sprintf(homeDirector, "%s/%s", envHome, HOMEDIRECTOR_NAME);
+
+ if ( access(homeDirector, F_OK) != 0 )
+ {
+ printf("Create home director %s\n", homeDirector);
+
+ if( mkdir(homeDirector, 0755) != 0 )
+ {
+ fprintf(stderr, "Can't create home directory!\n");
+ exit(0);
+ }
+ }
+}
+
+char *getHomeDirector()
+{
+ return homeDirector;
+}
diff --git a/src/base/homeDirector.h b/src/base/homeDirector.h
new file mode 100755
index 0000000..a5c5e0c
--- /dev/null
+++ b/src/base/homeDirector.h
@@ -0,0 +1,13 @@
+
+#ifndef HOMEDIRECTOR_H
+
+#define HOMEDIRECTOR_H
+
+#include "base/main.h"
+
+#define HOMEDIRECTOR_NAME ".tuxanci-ng"
+
+extern void createHomeDirector();
+extern char *getHomeDirector();
+
+#endif
diff --git a/src/base/idManager.c b/src/base/idManager.c
new file mode 100644
index 0000000..fb4a928
--- /dev/null
+++ b/src/base/idManager.c
@@ -0,0 +1,107 @@
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <assert.h>
+
+#include "base/main.h"
+#include "base/list.h"
+#include "base/idManager.h"
+
+static list_t *listID;
+static int lastID;
+
+void initListID()
+{
+ listID = newList();
+ lastID = 0;
+ printf("init ID manger..\n");
+}
+
+int isRegisterID(int id)
+{
+ int i;
+
+ assert( listID != NULL );
+
+ for( i = 0 ; i < listID->count ; i++ )
+ {
+ int *z;
+
+ z = (int *) listID->list[i];
+
+ if( *z == id )
+ {
+ return i;
+ }
+ }
+
+ return -1;
+}
+
+int getNewID()
+{
+ int ret;
+
+ assert( listID != NULL );
+
+ do{
+ ret = random() % MAX_ID;
+/*
+ ret = ++lastID;
+
+ if( lastID > MAX_ID )
+ {
+ lastID = 0;
+ }
+*/
+ }while( isRegisterID(ret) != -1 );
+
+ addList(listID, newInt(ret) );
+
+ //printf("new ID -> %d\n", ret);
+ return ret;
+}
+
+void delID(int id)
+{
+ int index;
+
+ assert( listID != NULL );
+
+ index = isRegisterID(id);
+
+ if( index == -1 )
+ {
+ assert( ! "takyto ID nebol nikdy registrovany !" );
+ return; // ha ha ha
+ }
+
+ delListItem(listID, index, free);
+
+ return;
+}
+
+void replaceID(int old_id, int new_id)
+{
+ if( old_id == new_id )
+ {
+ return;
+ }
+
+ delID(old_id);
+
+ if( new_id != -1 )
+ {
+ assert( isRegisterID(new_id) == -1 );
+ addList(listID, newInt(new_id) );
+ }
+}
+
+void quitListID()
+{
+ printf("quit ID manger..\n");
+
+ assert( listID != NULL );
+ destroyListItem(listID, free);
+}
+
diff --git a/src/base/idManager.h b/src/base/idManager.h
new file mode 100644
index 0000000..2b33ac5
--- /dev/null
+++ b/src/base/idManager.h
@@ -0,0 +1,19 @@
+
+
+#ifndef ID_MANAGER_H
+
+#define ID_MANAGER_H
+
+#define MAX_ID 1000
+#define ID_UNKNOWN -1
+
+#include "base/list.h"
+
+extern void initListID();
+extern int getNewID();
+extern int isRegisterID(int id);
+extern void delID(int id);
+extern void replaceID(int old_id, int new_id);
+extern void quitListID();
+
+#endif
diff --git a/src/base/item.c b/src/base/item.c
new file mode 100644
index 0000000..73bfeaa
--- /dev/null
+++ b/src/base/item.c
@@ -0,0 +1,620 @@
+
+#include <stdlib.h>
+#include <assert.h>
+
+#include "base/main.h"
+#include "base/arena.h"
+#include "base/tux.h"
+#include "base/item.h"
+#include "base/shot.h"
+#include "base/proto.h"
+#include "base/idManager.h"
+#include "base/net_multiplayer.h"
+
+#ifndef PUBLIC_SERVER
+
+#include "client/interface.h"
+#include "client/image.h"
+#include "client/layer.h"
+#include "client/term.h"
+
+#include "screen/screen_world.h"
+#include "screen/screen_setting.h"
+
+#ifndef NO_SOUND
+#include "audio/sound.h"
+#endif
+
+#endif
+
+#ifdef PUBLIC_SERVER
+#include "server/publicServer.h"
+#endif
+
+#ifndef PUBLIC_SERVER
+static SDL_Surface *g_item[ITEM_COUNT];
+#endif
+
+static bool_t isItemInit = FALSE;
+
+bool_t isItemInicialized()
+{
+ return isItemInit;
+}
+
+void initItem()
+{
+#ifndef PUBLIC_SERVER
+ g_item[GUN_DUAL_SIMPLE] = addImageData("item.dual.png", IMAGE_ALPHA, "item_dual_simple", IMAGE_GROUP_BASE);
+ g_item[GUN_TOMMY] = addImageData("item.tommy.png", IMAGE_ALPHA, "item_tommy_simple", IMAGE_GROUP_BASE);
+ g_item[GUN_SCATTER] = addImageData("item.scatter.png", IMAGE_ALPHA, "item_scatter_simple", IMAGE_GROUP_BASE);
+ g_item[GUN_LASSER] = addImageData("item.lasser.png", IMAGE_ALPHA, "item_lasser_simple", IMAGE_GROUP_BASE);
+ g_item[GUN_MINE] = addImageData("item.mine.png", IMAGE_ALPHA, "item_mines_simple", IMAGE_GROUP_BASE);
+ g_item[GUN_BOMBBALL] = addImageData("item.bombball.png", IMAGE_ALPHA, "item_bombball_simple", IMAGE_GROUP_BASE);
+
+ g_item[ITEM_MINE] = addImageData("mine.png", IMAGE_ALPHA, "item_mine_simple", IMAGE_GROUP_BASE);
+ g_item[ITEM_EXPLOSION] = addImageData("explosion.png", IMAGE_ALPHA, "item_explosion_simple", IMAGE_GROUP_BASE);
+ g_item[ITEM_BIG_EXPLOSION] = addImageData("big-explosion.png", IMAGE_ALPHA, "item_big-explosion_simple", IMAGE_GROUP_BASE);
+
+ g_item[BONUS_SPEED] = addImageData("item.bonus.speed.png", IMAGE_ALPHA, "item_bonus_speed", IMAGE_GROUP_BASE);
+ g_item[BONUS_SHOT] = addImageData("item.bonus.shot.png", IMAGE_ALPHA, "item_shot_speed", IMAGE_GROUP_BASE);
+ g_item[BONUS_TELEPORT] = addImageData("item.bonus.teleport.png", IMAGE_ALPHA, "item_teleport_speed", IMAGE_GROUP_BASE);
+ g_item[BONUS_GHOST] = addImageData("item.bonus.ghost.png", IMAGE_ALPHA, "item_ghost_speed", IMAGE_GROUP_BASE);
+ g_item[BONUS_4X] = addImageData("item.bonus.4x.png", IMAGE_ALPHA, "item_4x_speed", IMAGE_GROUP_BASE);
+ g_item[BONUS_HIDDEN] = addImageData("item.bonus.hidden.png", IMAGE_ALPHA, "item_hidden_speed", IMAGE_GROUP_BASE);
+#endif
+
+ isItemInit = TRUE;
+}
+
+item_t* newItem(int x, int y, int type, int author_id)
+{
+ item_t *new;
+
+ new = malloc( sizeof(item_t) );
+ assert( new != NULL );
+
+ new->type = type;
+
+ new->id = getNewID();
+ new->x = x;
+ new->y = y;
+ new->frame = 0;
+ new->count = 0;
+#ifndef PUBLIC_SERVER
+ new->img = g_item[type];
+#endif
+ new->author_id = author_id;
+
+ switch( type )
+ {
+ case GUN_DUAL_SIMPLE :
+ case GUN_SCATTER :
+ case GUN_TOMMY :
+ case GUN_LASSER :
+ case GUN_MINE :
+ case GUN_BOMBBALL :
+ new->w = ITEM_GUN_WIDTH;
+ new->h = ITEM_GUN_HEIGHT;
+ break;
+
+ case ITEM_MINE :
+ new->w = ITEM_MINE_WIDTH;
+ new->h = ITEM_MINE_HEIGHT;
+ break;
+
+ case ITEM_EXPLOSION :
+#ifndef NO_SOUND
+ playSound("explozion", SOUND_GROUP_BASE);
+#endif
+ new->w = ITEM_EXPLOSION_WIDTH;
+ new->h = ITEM_EXPLOSION_HEIGHT;
+ break;
+
+ case ITEM_BIG_EXPLOSION :
+#ifndef NO_SOUND
+ playSound("explozion", SOUND_GROUP_BASE);
+#endif
+ new->w = ITEM_BIG_EXPLOSION_WIDTH;
+ new->h = ITEM_BIG_EXPLOSION_HEIGHT;
+ break;
+
+ case BONUS_SPEED :
+ case BONUS_SHOT :
+ case BONUS_TELEPORT :
+ case BONUS_GHOST :
+ case BONUS_4X :
+ case BONUS_HIDDEN :
+ new->w = ITEM_BONUS_WIDTH;
+ new->h = ITEM_BONUS_HEIGHT;
+ break;
+ }
+
+ return new;
+}
+
+/*
+item_t* getItemID(list_t *listItem, int id)
+{
+ item_t *thisItem;
+ int i;
+
+ assert( listItem != NULL );
+
+ for( i = 0 ; i < listItem->count ; i++ )
+ {
+ thisItem = (item_t *)listItem->list[i];
+ assert( thisItem != NULL );
+
+ if( thisItem->id == id )
+ {
+ return thisItem;
+ }
+ }
+
+ return NULL;
+}
+*/
+
+void getStatusItem(void *p, int *id, int *x, int *y ,int *w, int *h)
+{
+ item_t *item;
+
+ item = p;
+
+ *id = item->id;
+ *x = item->x;
+ *y = item->y;
+ *w = item->w;
+ *h = item->h;
+}
+
+void setStatusItem(void *p, int x, int y, int w, int h)
+{
+ item_t *item;
+
+ item = p;
+ item->x = x;
+ item->y = y;
+ item->w = w;
+ item->h = h;
+}
+
+void replaceItemID(item_t *item, int id)
+{
+ replaceID(item->id, id);
+ item->id = id;
+}
+
+void addNewItem(space_t *spaceItem, int author_id)
+{
+#ifndef PUBLIC_SERVER
+ char msg[STR_SIZE];
+#endif
+ arena_t *arena;
+ item_t *item;
+ int new_x, new_y;
+ int type;
+
+#ifndef PUBLIC_SERVER
+ if( isSettingAnyItem() == FALSE ||
+ getNetTypeGame() == NET_GAME_TYPE_CLIENT )
+ {
+ return;
+ }
+#endif
+
+ arena = getCurrentArena();
+ findFreeSpace(getCurrentArena(), &new_x, &new_y, ITEM_GUN_WIDTH, ITEM_GUN_HEIGHT);
+
+ type = GUN_DUAL_SIMPLE;
+
+#ifndef PUBLIC_SERVER
+ do{
+#endif
+ switch( random() % 12 )
+ {
+ case 0 : type = GUN_DUAL_SIMPLE;
+ break;
+ case 1 : type = GUN_SCATTER;
+ break;
+ case 2 : type = GUN_TOMMY;
+ break;
+ case 3 : type = GUN_MINE;
+ break;
+ case 4 : type = GUN_LASSER;
+ break;
+ case 5 : type = GUN_BOMBBALL;
+ break;
+ case 6 : type = BONUS_SPEED;
+ break;
+ case 7 : type = BONUS_SHOT;
+ break;
+ case 8 : type = BONUS_TELEPORT;
+ break;
+ case 9 : type = BONUS_GHOST;
+ break;
+ case 10 : type = BONUS_4X;
+ break;
+ case 11 : type = BONUS_HIDDEN;
+ break;
+ }
+#ifndef PUBLIC_SERVER
+ }while( isSettingItem(type) == FALSE ||
+ (getNetTypeGame() == NET_GAME_TYPE_NONE && type == BONUS_HIDDEN) );
+#endif
+
+ item = newItem(new_x, new_y, type, author_id);
+ addObjectToSpace(spaceItem, item);
+
+ if( getNetTypeGame() == NET_GAME_TYPE_SERVER )
+ {
+ proto_send_additem_server(PROTO_SEND_ALL, NULL, item);
+ }
+
+#ifndef PUBLIC_SERVER
+ sprintf(msg, "in arena is new item\n");
+ appendTextInTerm(msg);
+#endif
+
+}
+
+#ifndef PUBLIC_SERVER
+
+void drawItem(item_t *p)
+{
+ assert( p != NULL );
+
+ addLayer(p->img, p->x, p->y, p->frame * p->w, 0, p->w, p->h, TUX_LAYER);
+}
+
+void drawListItem(list_t *listItem)
+{
+ item_t *thisItem;
+ int i;
+
+ assert( listItem != NULL );
+
+ for( i = 0 ; i < listItem->count ; i++ )
+ {
+ thisItem = (item_t *)listItem->list[i];
+ assert( thisItem != NULL );
+ drawItem(thisItem);
+ }
+}
+
+#endif
+
+void eventListItem(space_t *spaceItem)
+{
+ my_time_t currentTime;
+ item_t *thisItem;
+ int i;
+
+ currentTime = getMyTime();
+
+ assert( spaceItem != NULL );
+
+ for( i = 0 ; i < spaceItem->list->count ; i++ )
+ {
+ thisItem = (item_t *)spaceItem->list->list[i];
+ assert( thisItem != NULL );
+
+ thisItem->count++;
+
+ if( thisItem->count == ITEM_MAX_COUNT )
+ {
+ thisItem->count = 0;
+ thisItem->frame++;
+ }
+
+ switch( thisItem->type )
+ {
+ case GUN_TOMMY :
+ case GUN_DUAL_SIMPLE :
+ case GUN_SCATTER :
+ case GUN_LASSER :
+ case GUN_MINE :
+ case GUN_BOMBBALL :
+ if( thisItem->frame == ITEM_GUN_MAX_FRAME )
+ {
+ thisItem->frame = 0;
+ }
+ break;
+
+ case ITEM_MINE :
+ if( thisItem->frame == ITEM_MINE_MAX_FRAME )
+ {
+ thisItem->frame = 0;
+ }
+ break;
+
+ case ITEM_EXPLOSION :
+ case ITEM_BIG_EXPLOSION :
+ if( thisItem->frame == ITEM_EXPLOSION_MAX_FRAME )
+ {
+ delObjectFromSpaceWithObject(spaceItem, thisItem, destroyItem);
+ i--;
+ }
+ break;
+
+ case BONUS_SPEED :
+ case BONUS_SHOT :
+ case BONUS_TELEPORT :
+ case BONUS_GHOST :
+ case BONUS_4X :
+ case BONUS_HIDDEN :
+ if( thisItem->frame == ITEM_GUN_MAX_FRAME )
+ {
+ thisItem->frame = 0;
+ }
+ break;
+ }
+ }
+}
+
+void mineExplosion(space_t *spaceItem, item_t *item)
+{
+ if( getNetTypeGame() != NET_GAME_TYPE_CLIENT )
+ {
+ int x, y;
+ item_t *item_explosion;
+
+ x = ( item->x + item->w/2 ) - ITEM_BIG_EXPLOSION_WIDTH/2;
+ y = ( item->y + item->h/2 ) - ITEM_BIG_EXPLOSION_HEIGHT/2;
+
+ item_explosion = newItem(x, y, ITEM_BIG_EXPLOSION, item->author_id);
+
+ if( getNetTypeGame() == NET_GAME_TYPE_SERVER )
+ {
+ proto_send_additem_server(PROTO_SEND_ALL, NULL, item_explosion);
+ }
+
+ addObjectToSpace(spaceItem, item_explosion );
+ }
+
+ if( getNetTypeGame() == NET_GAME_TYPE_SERVER )
+ {
+ proto_send_del_server(PROTO_SEND_ALL, NULL, item->id);
+ }
+
+ delObjectFromSpaceWithObject(spaceItem, item, destroyItem);
+}
+
+void eventConflictShotWithItem(arena_t *arena)
+{
+ shot_t *thisShot;
+ item_t *thisItem;
+ int i, j;
+
+ if( getNetTypeGame() == NET_GAME_TYPE_CLIENT )
+ {
+ return;
+ }
+
+ for( i = 0 ; i < arena->spaceShot->list->count ; i++ )
+ {
+ bool_t isDelShot;
+
+ isDelShot = FALSE;
+ thisShot = (shot_t *)arena->spaceShot->list->list[i];
+ assert( thisShot != NULL );
+
+ listDoEmpty(listHelp);
+ getObjectFromSpace(arena->spaceItem, thisShot->x, thisShot->y, thisShot->w, thisShot->h, listHelp);
+
+ for( j = 0 ; j < listHelp->count ; j++ )
+ {
+ thisItem = (item_t *)listHelp->list[j];
+ assert( thisItem != NULL );
+
+ switch( thisItem->type )
+ {
+ case ITEM_MINE :
+ if( getNetTypeGame() != NET_GAME_TYPE_CLIENT )
+ {
+ mineExplosion(arena->spaceItem, thisItem);
+ }
+ break;
+
+ case ITEM_EXPLOSION :
+ case ITEM_BIG_EXPLOSION :
+ isDelShot = TRUE;
+ break;
+ }
+ }
+
+ if( isDelShot )
+ {
+ if( getNetTypeGame() == NET_GAME_TYPE_SERVER )
+ {
+ proto_send_del_server(PROTO_SEND_ALL, NULL, thisShot->id);
+ }
+
+ delObjectFromSpaceWithObject(arena->spaceShot, thisShot, destroyShot);
+ i--;
+ }
+ }
+}
+
+static void eventTuxIsDeadWithItem(tux_t *tux, item_t *item)
+{
+ if( tux->bonus == BONUS_GHOST )
+ {
+ return;
+ }
+
+ if( tux->bonus == BONUS_TELEPORT )
+ {
+ tuxTeleport(tux);
+ return;
+ }
+
+ if( item->author_id != tux->id )
+ {
+ tux_t *author;
+
+ author = getObjectFromSpaceWithID(getCurrentArena()->spaceTux, item->author_id);
+
+ if( author != NULL )
+ {
+ author->score++;
+
+ if( getNetTypeGame() == NET_GAME_TYPE_SERVER )
+ {
+ proto_send_newtux_server(PROTO_SEND_ALL, NULL, author);
+ }
+ }
+ }
+
+ countRoundInc();
+ eventTuxIsDead(tux);
+}
+
+static void tuxGiveBonus(tux_t *tux, item_t *item)
+{
+#ifndef PUBLIC_SERVER
+ char msg[STR_SIZE];
+#ifndef NO_SOUND
+ playSound("item_bonus", SOUND_GROUP_BASE);
+#endif
+
+#endif
+ tux->bonus = item->type;
+ tux->bonus_time = TUX_MAX_BONUS;
+
+#ifndef PUBLIC_SERVER
+ sprintf(msg, "tux with id %d bonus enabled\n", tux->id);
+ appendTextInTerm(msg);
+#endif
+
+ if( getNetTypeGame() == NET_GAME_TYPE_SERVER )
+ {
+ proto_send_newtux_server(PROTO_SEND_ALL, NULL, tux);
+ }
+}
+
+static void tuxGiveGun(tux_t *tux, item_t *item)
+{
+#ifndef PUBLIC_SERVER
+ char msg[STR_SIZE];
+#ifndef NO_SOUND
+ playSound("item_gun", SOUND_GROUP_BASE);
+#endif
+#endif
+
+ tux->pickup_time = 0;
+ tux->shot[ item->type ] += GUN_MAX_SHOT;
+ tux->gun = item->type;
+
+#ifndef PUBLIC_SERVER
+ sprintf(msg, "tux with id %d has new gun\n", tux->id);
+ appendTextInTerm(msg);
+#endif
+
+ if( getNetTypeGame() == NET_GAME_TYPE_SERVER )
+ {
+ proto_send_newtux_server(PROTO_SEND_ALL, NULL, tux);
+ }
+}
+
+void eventGiveTuxItem(tux_t *tux, item_t *item, space_t *spaceItem)
+{
+ switch( item->type )
+ {
+ case GUN_TOMMY :
+ case GUN_DUAL_SIMPLE :
+ case GUN_SCATTER :
+ case GUN_LASSER :
+ case GUN_MINE :
+ case GUN_BOMBBALL :
+ tuxGiveGun(tux, item);
+
+ if( getNetTypeGame() == NET_GAME_TYPE_SERVER )
+ {
+ proto_send_del_server(PROTO_SEND_ALL, NULL, item->id);
+ }
+
+ delObjectFromSpaceWithObject(spaceItem, item, destroyItem);
+ break;
+
+ case ITEM_MINE :
+ if( tux->bonus != BONUS_GHOST )
+ {
+ mineExplosion(spaceItem, item);
+ }
+ break;
+
+ case ITEM_EXPLOSION :
+ case ITEM_BIG_EXPLOSION :
+ eventTuxIsDeadWithItem(tux, item);
+ break;
+
+ case BONUS_SPEED :
+ case BONUS_SHOT :
+ case BONUS_TELEPORT :
+ case BONUS_GHOST :
+ case BONUS_4X :
+ case BONUS_HIDDEN :
+ tuxGiveBonus(tux, item);
+
+ if( getNetTypeGame() == NET_GAME_TYPE_SERVER )
+ {
+ proto_send_del_server(PROTO_SEND_ALL, NULL, item->id);
+ }
+
+ delObjectFromSpaceWithObject(spaceItem, item, destroyItem);
+ break;
+ }
+}
+
+void eventGiveTuxListItem(tux_t *tux, space_t *spaceItem)
+{
+ item_t *thisItem;
+ int x, y, w, h;
+ int i;
+
+ if( getNetTypeGame() == NET_GAME_TYPE_CLIENT )
+ {
+ return;
+ }
+
+ assert( spaceItem != NULL );
+ assert( tux != NULL );
+
+ if( tux->status == TUX_STATUS_DEAD )
+ {
+ return;
+ }
+
+ getTuxProportion(tux, &x, &y, &w, &h);
+
+ listDoEmpty(listHelp);
+ getObjectFromSpace(spaceItem, x, y, w, h, listHelp);
+
+ for( i = 0 ; i < listHelp->count ; i++ )
+ {
+ thisItem = (item_t *)listHelp->list[i];
+ assert( thisItem != NULL );
+
+ eventGiveTuxItem(tux, thisItem, spaceItem);
+
+ if( getNetTypeGame() == NET_GAME_TYPE_SERVER )
+ {
+ //proto_send_item_server(PROTO_SEND_ALL, NULL, tux, thisItem);
+ proto_send_newtux_server(PROTO_SEND_ALL, NULL, tux);
+ }
+ }
+}
+
+void destroyItem(item_t *p)
+{
+ assert( p != NULL );
+ delID(p->id);
+ free(p);
+}
+
+void quitItem()
+{
+ isItemInit = FALSE;
+}
diff --git a/src/base/item.h b/src/base/item.h
new file mode 100644
index 0000000..ec11654
--- /dev/null
+++ b/src/base/item.h
@@ -0,0 +1,79 @@
+
+#ifndef ITEM_H
+
+#define ITEM_H
+
+#include "base/main.h"
+
+#define ITEM_SYNC_TIMEOUT 5000
+
+#ifndef PUBLIC_SERVER
+#include "client/interface.h"
+#endif
+
+#include "base/list.h"
+#include "base/tux.h"
+#include "base/myTimer.h"
+
+typedef struct item_struct
+{
+ int id;
+ int type; // typ veci
+
+ int x; // poloha veci
+ int y;
+
+ int w; // rozmery veci
+ int h;
+
+ int frame; //poradove cislo animacie
+ int count;
+
+ int author_id;
+#ifndef PUBLIC_SERVER
+ SDL_Surface *img; //obrazok
+#endif
+} item_t;
+
+#define ITEM_MAX_COUNT 1
+
+#define ITEM_GUN_MAX_FRAME 8
+#define ITEM_MINE_MAX_FRAME 1
+#define ITEM_EXPLOSION_MAX_FRAME 10
+#define ITEM_BONUS_MAX_FRAME 8
+
+#define ITEM_GUN_WIDTH 50
+#define ITEM_GUN_HEIGHT 20
+
+#define ITEM_MINE_WIDTH 15
+#define ITEM_MINE_HEIGHT 11
+
+#define ITEM_EXPLOSION_WIDTH 40
+#define ITEM_EXPLOSION_HEIGHT 40
+
+#define ITEM_BIG_EXPLOSION_WIDTH 100
+#define ITEM_BIG_EXPLOSION_HEIGHT 100
+
+#define ITEM_BONUS_WIDTH 20
+#define ITEM_BONUS_HEIGHT 20
+
+extern bool_t isItemInicialized();
+extern void initItem();
+extern item_t* newItem(int x, int y, int type, int author_id);
+extern void getStatusItem(void *p, int *id, int *x, int *y ,int *w, int *h);
+extern void setStatusItem(void *p, int x, int y, int w, int h);
+extern void replaceItemID(item_t *item, int id);
+extern void addNewItem(space_t *spaceItem, int author_id);
+#ifndef PUBLIC_SERVER
+extern void drawListItem(list_t *listItem);
+#endif
+extern void eventListItem(space_t *listSpace);
+extern void mineExplosion(space_t *spaceItem, item_t *item);
+extern void eventConflictShotWithItem(arena_t *arena);
+extern void eventGiveTuxItem(tux_t *tux, item_t *item, space_t *spaceItem);
+extern void eventGiveTuxListItem(tux_t *tux, space_t *spaceItem);
+extern void destroyItem(item_t *p);
+extern void quitItem();
+
+#endif
+
diff --git a/src/base/list.c b/src/base/list.c
new file mode 100755
index 0000000..d182210
--- /dev/null
+++ b/src/base/list.c
@@ -0,0 +1,241 @@
+
+#include "base/main.h"
+#include "base/list.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+
+list_t* newList()
+{
+ list_t *new;
+
+ new = malloc( sizeof(list_t) );
+ memset(new, 0, sizeof(list_t) );
+
+ return new;
+}
+
+list_t* cloneList(list_t *p)
+{
+ list_t *new;
+
+ assert( p != NULL );
+
+ new = malloc( sizeof(list_t) );
+ memcpy(new, p, sizeof(list_t) );
+
+ if( p->list != NULL )
+ {
+ new->list = malloc( p->alloc * sizeof(void *) );
+ memcpy(new->list, p->list, p->alloc * sizeof(void *));
+ }
+
+ return new;
+}
+
+list_t* cloneListItem(list_t *p, void *f)
+{
+ list_t *new;
+ void* (*fce)(void *);
+ int i;
+
+ assert( p != NULL );
+ assert( f != NULL );
+
+ new = cloneList(p);
+ fce = f;
+
+ for(i = 0 ; i < p->count ; i++)
+ new->list[i] = fce(p->list[i]);
+
+ return new;
+}
+
+void addList(list_t *p, void *item)
+{
+ assert( p != NULL );
+
+ if( p->alloc == 0 )
+ {
+ p->alloc = LIST_ALLOC_LIMIT;
+ p->count = 1;
+ p->list = malloc(p->alloc * sizeof(void *) );
+ p->list[0] = item;
+
+ return;
+ }
+
+ if( p->count + 1 <= p->alloc )
+ {
+ p->list[p->count] = item;
+ p->count += 1;
+
+ return;
+ }
+
+ if( p->count + 1 > p->alloc )
+ {
+ void **new;
+
+#ifdef DEBUG_LIST
+ printf("realokujem z %d na %d (count=%d)\n",
+ p->alloc, p->alloc+LIST_ALLOC_LIMIT, p->count);
+#endif
+
+ p->alloc += LIST_ALLOC_LIMIT;
+ new = malloc(p->alloc * sizeof(void *) );
+ memcpy(new, p->list, p->count * sizeof(void *) );
+ free(p->list);
+ p->list = new;
+ p->list[p->count] = item;
+ p->count++;
+
+ return;
+ }
+}
+
+void insList(list_t *p, int n, void *item)
+{
+ assert( p != NULL );
+
+ addList(p, NULL); // :)
+
+ assert( n >= 0 || n < p->count );
+
+ memmove(p->list+n+1, p->list+n, ( (p->count-1) - n ) * sizeof(void *));
+
+ p->list[n] = item;
+}
+
+void *getList(list_t *p, int n)
+{
+ assert( p != NULL );
+ assert( n >= 0 || n < p->count );
+
+ return p->list[n];
+}
+
+int searchListItem(list_t *p, void *n)
+{
+ int i;
+
+ assert( p != NULL );
+
+ for( i = 0 ; i < p->count ; i++ )
+ if( p->list[i] == n )return i;
+
+ return -1;
+}
+
+void delList(list_t *p, int n)
+{
+ assert( p != NULL );
+ assert( n >= 0 || n < p->count );
+
+ memmove(p->list+n, p->list+n+1, ( (p->count-1) - n ) * sizeof(void *));
+
+ p->count--;
+
+ if( p->count + LIST_ALLOC_LIMIT < p->alloc )
+ {
+ void **new;
+
+#ifdef DEBUG_LIST
+ printf("realokujem z %d na %d (count=%d)\n",
+ p->alloc, p->alloc-LIST_ALLOC_LIMIT, p->count);
+#endif
+
+ p->alloc -= LIST_ALLOC_LIMIT;
+ new = malloc(p->alloc * sizeof(void *) );
+ memcpy(new, p->list, p->count * sizeof(void *) );
+ free(p->list);
+ p->list = new;
+ }
+}
+
+void delListItem(list_t *p, int n, void *f)
+{
+ int (*fce)(void *);
+
+ assert( p != NULL );
+ assert( n >= 0 || n < p->count );
+
+ fce = f;
+ if( fce != NULL )fce(p->list[n]);
+
+ delList(p, n);
+}
+
+void listDoEmpty(list_t *p)
+{
+ p->count = 0;
+}
+
+void destroyList(list_t *p)
+{
+ assert( p != NULL );
+
+ if( p->list != NULL )free(p->list);
+ free(p);
+}
+
+void destroyListItem(list_t *p, void *f)
+{
+ void (*fce)(void *);
+ int i;
+
+ assert( p != NULL );
+ assert( f != NULL );
+
+ fce = f;
+
+ for(i = 0 ; i < p->count ; i++)
+ fce(p->list[i]);
+
+ destroyList(p);
+}
+
+/*
+typedef struct pokus_str
+{
+ int x;
+} pokus;
+
+pokus* newPokus(int n)
+{
+ pokus *new;
+ new = malloc(sizeof(pokus));
+ new->x = n;
+ return new;
+}
+
+pokus *clonePokus(pokus *p)
+{
+ pokus *new;
+ new = malloc(sizeof(pokus));
+ memcpy(new, p, sizeof(pokus));
+ return new;
+}
+
+void destroyPokus(pokus *p)
+{
+ free(p);
+}
+
+int main()
+{
+ list_t *my;
+ int i;
+
+ my = newList();
+
+ for(i = 0; i < 100; i++)
+ addList(my, newPokus(i));
+
+ destroyListItem(my, destroyPokus);
+
+ return 0;
+}
+*/
diff --git a/src/base/list.h b/src/base/list.h
new file mode 100755
index 0000000..17a8e2d
--- /dev/null
+++ b/src/base/list.h
@@ -0,0 +1,33 @@
+
+#ifndef LIST_H
+
+#define LIST_H
+
+#include "base/main.h"
+
+#define LIST_ALLOC_LIMIT 16
+
+typedef struct list_str
+{
+ void **list;
+ int count;
+ int alloc;
+} list_t;
+
+extern list_t* newList();
+extern list_t* cloneList(list_t *p);
+extern list_t* cloneListItem(list_t *p, void *f);
+
+extern void addList(list_t *p, void *item);
+extern void insList(list_t *p, int n, void *item);
+extern void *getList(list_t *p,int n);
+extern int searchListItem(list_t *p, void *n);
+
+extern void delList(list_t *p,int n);
+extern void delListItem(list_t *p,int n,void *f);
+extern void listDoEmpty(list_t *p);
+
+extern void destroyList(list_t *p);
+extern void destroyListItem(list_t *p,void *f);
+
+#endif
diff --git a/src/base/main.c b/src/base/main.c
new file mode 100644
index 0000000..ffebbe0
--- /dev/null
+++ b/src/base/main.c
@@ -0,0 +1,126 @@
+
+#include <time.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <signal.h>
+#include <unistd.h>
+#include <assert.h>
+#include <sys/stat.h>
+
+#include "base/main.h"
+#include "base/tux.h"
+
+#ifndef PUBLIC_SERVER
+#include "client/game.h"
+#endif
+
+#ifdef PUBLIC_SERVER
+#include "server/publicServer.h"
+#endif
+
+static int my_argc;
+static char **my_argv;
+
+list_t *listHelp;
+
+char* getParam(char *s)
+{
+ int i;
+ int len;
+
+ len = strlen(s);
+
+ for( i = 1 ; i < my_argc ; i++ )
+ {
+ //printf("%s %s\n", s, my_argv[i]);
+
+ if( strlen(my_argv[i]) < len )
+ {
+ continue;
+ }
+
+ if( strncmp(s, my_argv[i], len) == 0 )
+ {
+ return strchr(my_argv[i], '=')+1;
+ }
+ }
+
+ return NULL;
+}
+
+char* getParamElse(char *s1, char *s2)
+{
+ char *ret;
+ ret = getParam(s1);
+
+ if( ret == NULL)
+ {
+ return s2;
+ }
+
+ return ret;
+}
+
+bool_t isParamFlag(char *s)
+{
+ int i;
+
+ for( i = 0 ; i < my_argc ; i++ )
+ {
+ if( strcmp(s, my_argv[i]) == 0 )
+ {
+ return TRUE;
+ }
+ }
+
+ return FALSE;
+}
+
+char *getString(int n)
+{
+ char str[STR_NUM_SIZE];
+ sprintf(str, "%d", n);
+ return strdup(str);
+}
+
+int* newInt(int x)
+{
+ int *new;
+ new = malloc( sizeof(int) );
+ *new = x;
+ return new;
+}
+
+void accessExistFile(const char *s)
+{
+ if( access(s, F_OK) != 0 )
+ {
+ fprintf(stderr, "File %s not found !\nProgram shutdown !\n", s);
+ exit(-1);
+ }
+}
+
+int main(int argc, char *argv[])
+{
+ listHelp = newList();
+
+ srand( (unsigned) time(NULL) );
+
+ my_argc = argc;
+ my_argv = argv;
+/*
+ test_space();
+ exit(0);
+*/
+
+#ifndef PUBLIC_SERVER
+ startGame();
+#endif
+
+#ifdef PUBLIC_SERVER
+ startPublicServer();
+#endif
+
+ return 0;
+}
diff --git a/src/base/main.h b/src/base/main.h
new file mode 100644
index 0000000..b38a1d7
--- /dev/null
+++ b/src/base/main.h
@@ -0,0 +1,33 @@
+
+#ifndef MAIN_H
+
+#define MAIN_H
+
+#include "../../config.h"
+
+#if defined PUBLIC_SERVER
+
+#undef DESTDIR
+
+#endif
+
+#include "base/bool.h"
+#include "base/string_length.h"
+#include "base/path.h"
+
+//rozlisenie obrazovky
+#define WINDOW_SIZE_X 800
+#define WINDOW_SIZE_Y 600
+
+#include "base/list.h"
+
+extern list_t *listHelp;
+
+extern char* getParam(char *s);
+extern char* getParamElse(char *s1, char *s2);
+extern bool_t isParamFlag(char *s);
+extern char *getString(int n);
+extern int* newInt(int x);
+extern void accessExistFile(const char *s);
+
+#endif
diff --git a/src/base/modules.c b/src/base/modules.c
new file mode 100755
index 0000000..aa881d5
--- /dev/null
+++ b/src/base/modules.c
@@ -0,0 +1,222 @@
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <dlfcn.h>
+#include <assert.h>
+
+#include "base/main.h"
+#include "base/list.h"
+#include "base/tux.h"
+#include "base/shot.h"
+#include "base/modules.h"
+#include "base/arena.h"
+#include "base/arenaFile.h"
+#include "base/proto.h"
+
+#ifndef PUBLIC_SERVER
+#include "client/interface.h"
+#include "client/image.h"
+#include "client/layer.h"
+#include "client/configFile.h"
+#endif
+
+int pokus(char *s)
+{
+ printf("s = %s\n", s);
+ return 0;
+}
+
+static export_fce_t export_fce =
+ {
+#ifndef PUBLIC_SERVER
+ .fce_addLayer = addLayer,
+ .fce_getImage = getImage,
+#endif
+ .fce_getValue = getArenaValue,
+ .fce_getNetTypeGame = getNetTypeGame,
+ .fce_getTuxProportion = getTuxProportion,
+ .fce_setTuxProportion = setTuxProportion,
+ //.fce_getTuxID = getTuxID,
+ .fce_actionTux = actionTux,
+
+ .fce_getMyTime = getMyTime,
+
+ .fce_getCurrentArena = getCurrentArena,
+ .fce_conflictSpace = conflictSpace,
+ .fce_isFreeSpace = isFreeSpace,
+ .fce_findFreeSpace = findFreeSpace,
+ .fce_proto_send_newtux_server = proto_send_newtux_server,
+ .fce_proto_send_shot_server = proto_send_shot_server,
+ .fce_destroyShot = destroyShot,
+ .fce_boundBombBall = boundBombBall,
+ .fce_transformOnlyLasser = transformOnlyLasser
+ };
+
+static list_t *listModule;
+
+static void* getFce(module_t *p, char *s)
+{
+ void *ret;
+ char *error;
+
+ assert( p != NULL );
+ assert( s != NULL );
+
+ ret = dlsym(p->image, s);
+
+ if( ( error = dlerror() ) != NULL)
+ {
+ fprintf (stderr, "error = %s\n", error);
+ return NULL;
+ }
+
+ return (void *)ret;
+}
+
+static module_t* newModule(char *name)
+{
+ module_t *ret;
+
+ assert( name != NULL );
+
+ ret = malloc( sizeof(module_t) );
+
+ ret->image = dlopen (name, RTLD_LAZY);
+
+ if(!ret->image)
+ {
+ fputs (dlerror(), stderr);
+ free(ret);
+ return NULL;
+ }
+
+ ret->file = strdup(name);
+
+ ret->fce_init = getFce(ret, "init");
+#ifndef PUBLIC_SERVER
+ ret->fce_draw = getFce(ret, "draw");
+#endif
+ ret->fce_event = getFce(ret, "event");
+ ret->fce_destroy = getFce(ret, "destroy");
+ ret->fce_isConflict = getFce(ret, "isConflict");
+ ret->fce_cmd = getFce(ret, "cmd");
+
+ printf("load module.. (%s)\n", name);
+
+ if( ret->fce_init(&export_fce) != 0 )
+ {
+ fprintf(stderr, "init module failed !\n");
+
+ dlclose(ret->image);
+ free(ret->file);
+ free(ret);
+ return NULL;
+ }
+
+ return ret;
+}
+
+static int destroyModule(module_t *p)
+{
+ assert( p != NULL );
+
+ p->fce_destroy();
+
+ free(p->file);
+ dlclose(p->image);
+ free(p);
+
+ printf("destroy module..\n");
+
+ return 0;
+}
+
+void initModule()
+{
+ listModule = newList();
+}
+
+int loadModule(char *name)
+{
+ char str[STR_PATH_SIZE];
+ module_t *module;
+
+ sprintf(str, PATH_MODULES "%s", name);
+ accessExistFile(str);
+
+ module = newModule(str);
+
+ if( module == NULL )
+ {
+ fprintf(stderr, "load module %s failed !\n", name);
+ return -1;
+ }
+
+ addList(listModule, module);
+
+ return 0;
+}
+
+void cmdModule(char *s)
+{
+ int i;
+
+ for( i = 0 ; i < listModule->count ; i++ )
+ {
+ module_t *this;
+ this = (module_t *)listModule->list[i];
+ this->fce_cmd(s);
+ }
+}
+
+#ifndef PUBLIC_SERVER
+
+void drawModule(int x, int y, int w, int h)
+{
+ int i;
+
+ for( i = 0 ; i < listModule->count ; i++ )
+ {
+ module_t *this;
+ this = (module_t *)listModule->list[i];
+ this->fce_draw(x, y, w, h);
+ }
+}
+
+#endif
+
+void eventModule()
+{
+ int i;
+
+ for( i = 0 ; i < listModule->count ; i++ )
+ {
+ module_t *this;
+ this = (module_t *)listModule->list[i];
+ this->fce_event();
+ }
+}
+
+int isConflictModule(int x, int y, int w, int h)
+{
+ int i;
+
+ for( i = 0 ; i < listModule->count ; i++ )
+ {
+ module_t *this;
+ this = (module_t *)listModule->list[i];
+
+ if( this->fce_isConflict(x, y, w, h) == 1 )
+ {
+ return 1;
+ }
+ }
+
+ return 0;
+}
+
+void quitModule()
+{
+ destroyListItem(listModule, destroyModule);
+}
diff --git a/src/base/modules.h b/src/base/modules.h
new file mode 100644
index 0000000..3b50ade
--- /dev/null
+++ b/src/base/modules.h
@@ -0,0 +1,78 @@
+
+#ifndef MODULE_H
+
+#define MODULE_H
+
+#include "base/tux.h"
+#include "base/shot.h"
+#include "base/arena.h"
+#include "base/proto.h"
+#include "base/myTimer.h"
+
+#ifndef PUBLIC_SERVER
+#include "client/image.h"
+#endif
+
+typedef struct export_fce_s
+{
+ int (*fce_getValue)(char *line, char *env, char *val, int len);
+
+#ifndef PUBLIC_SERVER
+ SDL_Surface* (*fce_getImage)(char *group, char *name);
+
+ void (*fce_addLayer)(SDL_Surface *img,
+ int x,int y, int px,int py,
+ int w,int h, int player);
+#endif
+
+ int (*fce_getNetTypeGame)();
+
+ void (*fce_getTuxProportion)(tux_t *tux, int *x,int *y, int *w, int *h);
+ void (*fce_setTuxProportion)(tux_t *tux, int x, int y);
+ tux_t* (*fce_getTuxID)(list_t *listTux, int id);
+ void (*fce_actionTux)(tux_t *tux, int action);
+
+ arena_t* (*fce_getCurrentArena)();
+ int (*fce_conflictSpace)(int x1,int y1,int w1,int h1,int x2,int y2,int w2,int h2);
+ int (*fce_isFreeSpace)(arena_t *arena, int x, int y, int w, int h);
+ void (*fce_findFreeSpace)(arena_t *arena, int *x, int *y, int w, int h);
+ void (*fce_proto_send_newtux_server)(int type, client_t *client, tux_t *tux);
+ void (*fce_proto_send_shot_server)(int type, client_t *client, shot_t *p);
+
+ my_time_t (*fce_getMyTime)();
+
+ void (*fce_destroyShot)(shot_t *p);
+ void (*fce_boundBombBall)(shot_t *shot);
+ void (*fce_transformOnlyLasser)(shot_t *shot);
+
+ int (*fce_pokus)(char *s);
+
+} export_fce_t;
+
+typedef struct module_s
+{
+ char *file;
+ void *image;
+
+ int (*fce_init)(export_fce_t *p);
+#ifndef PUBLIC_SERVER
+ int (*fce_draw)(int x, int y,int w, int h);
+#endif
+ int (*fce_event)();
+ int (*fce_isConflict)(int x, int y, int w, int h);
+ void (*fce_cmd)(char *line);
+ int (*fce_destroy)();
+
+} module_t;
+
+extern void initModule();
+extern int loadModule(char *name);
+#ifndef PUBLIC_SERVER
+extern void drawModule(int x, int y, int w, int h);
+#endif
+extern void eventModule();
+extern void cmdModule(char *s);
+extern int isConflictModule(int x, int y, int w, int h);
+extern void quitModule();
+
+#endif
diff --git a/src/base/myTimer.c b/src/base/myTimer.c
new file mode 100644
index 0000000..7913f8b
--- /dev/null
+++ b/src/base/myTimer.c
@@ -0,0 +1,148 @@
+
+#include <time.h>
+#include <assert.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/time.h>
+#include <signal.h>
+
+#include "base/main.h"
+#include "base/list.h"
+#include "base/myTimer.h"
+
+#ifndef PUBLIC_SERVER
+#include "client/interface.h"
+#endif
+
+static struct timeval start = { .tv_sec = 0, .tv_usec = 0 };
+
+list_t* newTimer()
+{
+ return newList();
+}
+
+void restartTimer()
+{
+ gettimeofday(&start, NULL);
+}
+
+
+my_time_t getMyTime()
+{
+ struct timeval now;
+ my_time_t ticks;
+
+ if( start.tv_sec == 0 && start.tv_usec == 0 )
+ {
+ restartTimer();
+ }
+
+ gettimeofday(&now, NULL);
+
+ ticks = (now.tv_sec-start.tv_sec)*1000+(now.tv_usec-start.tv_usec)/1000;
+
+ //printf("-> %d\n", ticks);
+ return ticks;
+}
+
+my_timer_t* newTimerItem(int type, void (*fce)(void *p), void *arg, my_time_t my_time)
+{
+ static int new_id = 0;
+ my_timer_t *new;
+
+ assert( fce != NULL );
+
+ new = malloc( sizeof(my_timer_t) );
+ memset(new, 0, sizeof(my_timer_t));
+
+ new->id = new_id++;
+ new->type = type;
+ new->fce = fce;
+ new->arg = arg;
+
+ new->createTime = getMyTime();
+ new->time = my_time;
+
+ return new;
+}
+
+static void destroyTimerItem(my_timer_t *p)
+{
+ assert( p != NULL );
+ free(p);
+}
+
+int addTaskToTimer(list_t *listTimer, int type, void (*fce)(void *p), void *arg, my_time_t my_time)
+{
+ my_timer_t *new;
+
+ new = newTimerItem(type, fce, arg, my_time);
+ addList(listTimer, new);
+
+ return new->id;
+}
+
+void eventTimer(list_t *listTimer)
+{
+ int i;
+ my_timer_t *thisTimer;
+ my_time_t currentTime;
+
+ currentTime = getMyTime();
+
+ for( i = 0 ; i < listTimer->count ; i++ )
+ {
+ thisTimer = (my_timer_t *)listTimer->list[i];
+ assert( thisTimer != NULL );
+
+ switch( thisTimer->type )
+ {
+ case TIMER_ONE:
+ if( currentTime >= thisTimer->createTime + thisTimer->time )
+ {
+ thisTimer->fce(thisTimer->arg);
+
+ delListItem(listTimer, i, free);
+ i--;
+ }
+ break;
+ case TIMER_PERIODIC:
+ if( currentTime >= thisTimer->createTime + thisTimer->time )
+ {
+ thisTimer->fce(thisTimer->arg);
+ thisTimer->createTime = getMyTime();
+ }
+ break;
+ default :
+ assert( ! "bad timer type !" );
+ break;
+ }
+
+ }
+}
+
+void delTimer(list_t *listTimer, int id)
+{
+ int i;
+ my_timer_t *thisTimer;
+
+ for( i = 0 ; i < listTimer->count ; i++ )
+ {
+ thisTimer = (my_timer_t *)listTimer->list[i];
+ assert( thisTimer != NULL );
+
+ if( thisTimer->id == id )
+ {
+ delListItem(listTimer, i, free);
+ return;
+ }
+ }
+
+ assert( ! "Uloha s id nenajdena !" );
+}
+
+
+void destroyTimer(list_t *listTimer)
+{
+ destroyListItem(listTimer, destroyTimerItem);
+}
diff --git a/src/base/myTimer.h b/src/base/myTimer.h
new file mode 100644
index 0000000..2f038da
--- /dev/null
+++ b/src/base/myTimer.h
@@ -0,0 +1,32 @@
+
+#ifndef MY_TIME_H
+
+#define MY_TIME_H
+
+#include "base/main.h"
+#include "base/list.h"
+
+#define my_time_t unsigned int
+
+#define TIMER_ONE 0
+#define TIMER_PERIODIC 1
+
+typedef struct my_timer_struct
+{
+ unsigned int id;
+ void (*fce)(void *p);
+ void *arg;
+ int type;
+ my_time_t createTime;
+ my_time_t time;
+} my_timer_t;
+
+extern list_t* newTimer();
+extern void restartTimer();
+extern my_time_t getMyTime();
+extern int addTaskToTimer(list_t *listTimer, int type, void (*fce)(void *p), void *arg, my_time_t my_time);
+extern void eventTimer(list_t *listTimer);
+extern void delTimer(list_t *listTimer, int id);
+extern void destroyTimer(list_t *listTimer);
+
+#endif
diff --git a/src/base/net_multiplayer.c b/src/base/net_multiplayer.c
new file mode 100644
index 0000000..bc8ecab
--- /dev/null
+++ b/src/base/net_multiplayer.c
@@ -0,0 +1,172 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+#include <unistd.h>
+
+#include "base/main.h"
+#include "base/list.h"
+#include "base/tux.h"
+#include "base/item.h"
+#include "base/arenaFile.h"
+#include "base/net_multiplayer.h"
+#include "base/server.h"
+
+#ifdef SUPPORT_NET_UNIX_UDP
+#include "net_unix/udp.h"
+#endif
+
+#ifdef SUPPORT_NET_SDL_UDP
+#include "net_sdl/sdl_udp.h"
+#endif
+
+#ifndef PUBLIC_SERVER
+#include "screen/screen_setting.h"
+#include "screen/screen_choiceArena.h"
+
+#include "client/screen.h"
+#include "client/client.h"
+#endif
+
+static int netGameType;
+
+int getNetTypeGame()
+{
+ return netGameType;
+}
+
+#ifdef PUBLIC_SERVER
+
+int initNetMulitplayerPublicServer(char *ip4, int port4, char *ip6, int port6)
+{
+ netGameType = NET_GAME_TYPE_SERVER;
+ return initUdpPublicServer(ip4, port4, ip6, port6);
+}
+#endif
+
+int initNetMuliplayer(int type, char *ip, int port, int proto)
+{
+ netGameType = type;
+
+ switch( netGameType )
+ {
+ case NET_GAME_TYPE_NONE :
+ break;
+
+ case NET_GAME_TYPE_SERVER :
+#ifdef SUPPORT_NET_UNIX_UDP
+ if( initUdpServer(ip, port, proto) != 0 )
+ {
+ fprintf(stderr, "Neomzem inicalizovat sietovu hru pre server !\n");
+ netGameType = NET_GAME_TYPE_NONE;
+ return -1;
+ }
+#endif
+#ifdef SUPPORT_NET_SDL_UDP
+ if( initSdlUdpServer(port) != 0 )
+ {
+ fprintf(stderr, "Neomzem inicalizovat sietovu hru pre server !\n");
+ netGameType = NET_GAME_TYPE_NONE;
+ return -1;
+ }
+#endif
+ break;
+
+#ifndef PUBLIC_SERVER
+ case NET_GAME_TYPE_CLIENT :
+#ifdef SUPPORT_NET_UNIX_UDP
+ if( initUdpClient(ip, port, proto) != 0 )
+ {
+ fprintf(stderr, "Neomzem inicalizovat sietovu hru pre clienta !\n");
+ netGameType = NET_GAME_TYPE_NONE;
+ return -1;
+ }
+#endif
+#ifdef SUPPORT_NET_SDL_UDP
+ if( initSdlUdpClient(ip, port) != 0 )
+ {
+ fprintf(stderr, "Neomzem inicalizovat sietovu hru pre clienta !\n");
+ netGameType = NET_GAME_TYPE_NONE;
+ return -1;
+ }
+#endif
+ break;
+#endif
+ default :
+ assert( ! "Premenna netGameType ma zlu hodnotu !" );
+ break;
+ }
+
+ return 0;
+}
+
+void eventNetMultiplayer()
+{
+ switch( netGameType )
+ {
+ case NET_GAME_TYPE_NONE :
+ break;
+
+ case NET_GAME_TYPE_SERVER :
+#ifdef SUPPORT_NET_UNIX_UDP
+ eventServer();
+#endif
+#ifdef SUPPORT_NET_SDL_UDP
+ eventServer();
+#endif
+ break;
+
+#ifndef PUBLIC_SERVER
+ case NET_GAME_TYPE_CLIENT :
+#ifdef SUPPORT_NET_UNIX_UDP
+ eventPingServer();
+ selectClientUdpSocket();
+ eventServerBuffer();
+#endif
+#ifdef SUPPORT_NET_SDL_UDP
+ eventPingServer();
+ selectClientSdlUdpSocket();
+ eventServerBuffer();
+#endif
+#endif
+ break;
+ default :
+ assert( ! "Premenna netGameType ma zlu hodnotu !" );
+ break;
+ }
+}
+
+void quitNetMultiplayer()
+{
+ switch( netGameType )
+ {
+ case NET_GAME_TYPE_NONE :
+ break;
+
+ case NET_GAME_TYPE_SERVER :
+#ifdef SUPPORT_NET_UNIX_UDP
+ quitUdpServer();
+#endif
+#ifdef SUPPORT_NET_SDL_UDP
+ quitSdlUdpServer();
+#endif
+ break;
+
+#ifndef PUBLIC_SERVER
+ case NET_GAME_TYPE_CLIENT :
+#ifdef SUPPORT_NET_UNIX_UDP
+ quitUdpClient();
+#endif
+#ifdef SUPPORT_NET_SDL_UDP
+ quitSdlUdpClient();
+#endif
+ break;
+#endif
+
+ default :
+ assert( ! "Premenna netGameType ma zlu hodnotu !" );
+ break;
+ }
+
+ netGameType = NET_GAME_TYPE_NONE;
+}
diff --git a/src/base/net_multiplayer.h b/src/base/net_multiplayer.h
new file mode 100644
index 0000000..ad5eb41
--- /dev/null
+++ b/src/base/net_multiplayer.h
@@ -0,0 +1,35 @@
+
+#ifndef NET_MULTIPLAYER_H
+
+#define NET_MULTIPLAYER_H
+
+#include "base/main.h"
+#include "base/tux.h"
+#include "base/item.h"
+#include "base/arena.h"
+
+#define PROTO_UDPv4 0
+#define PROTO_UDPv6 1
+
+#define NET_GAME_TYPE_NONE 0
+#define NET_GAME_TYPE_SERVER 1
+#define NET_GAME_TYPE_CLIENT 2
+
+#define NET_STATUS_OK 0
+#define NET_STATUS_ZOMBIE 1
+
+#define NET_PROTOCOL_TYPE_TCP 0
+#define NET_PROTOCOL_TYPE_UDP 1
+
+#define LIMIT_BUFFER 10240
+
+#ifdef PUBLIC_SERVER
+extern int initNetMulitplayerPublicServer(char *ip4, int port4, char *ip6, int port6);
+#endif
+
+extern int initNetMuliplayer(int type, char *ip, int port, int proto);
+extern int getNetTypeGame();
+extern void eventNetMultiplayer();
+extern void quitNetMultiplayer();
+
+#endif
diff --git a/src/base/path.h b/src/base/path.h
new file mode 100644
index 0000000..9c26ea4
--- /dev/null
+++ b/src/base/path.h
@@ -0,0 +1,33 @@
+
+#ifndef PATH_H
+
+#define PATH_H
+
+#include "base/main.h"
+
+#ifdef DESTDIR
+
+#define PATH_DIR "share/tuxanci-ng/"
+
+#endif
+
+#ifndef DESTDIR
+
+#define PATH_DIR "./"
+
+#undef DESTDIR
+#define DESTDIR ""
+
+#endif
+
+#define PATH_IMAGE DESTDIR PATH_DIR "image/"
+#define PATH_FONT DESTDIR PATH_DIR "font/"
+#define PATH_ARENA DESTDIR PATH_DIR "arena/"
+#define PATH_SOUND DESTDIR PATH_DIR "sound/"
+#define PATH_MUSIC DESTDIR PATH_DIR "music/"
+#define PATH_CONFIG DESTDIR PATH_DIR "conf/"
+#define PATH_LANG DESTDIR PATH_DIR "lang/"
+#define PATH_DATA DESTDIR PATH_DIR "data/"
+#define PATH_MODULES DESTDIR PATH_DIR "modules/"
+
+#endif
diff --git a/src/base/protect.c b/src/base/protect.c
new file mode 100644
index 0000000..074873a
--- /dev/null
+++ b/src/base/protect.c
@@ -0,0 +1,88 @@
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+
+#include "base/main.h"
+#include "base/myTimer.h"
+#include "base/protect.h"
+
+protect_t* newProtect()
+{
+ protect_t *new;
+
+ new = malloc( sizeof(protect_t) );
+ new->lastMove = getMyTime();
+ new->lastPing = getMyTime();
+ new->avarage = 0;
+ new->count = 0;
+ new->isDown = FALSE;
+ return new;
+}
+
+void refreshLastMove(protect_t *p)
+{
+ my_time_t currentTime;
+ my_time_t interval;
+
+ currentTime = getMyTime();
+
+ interval = currentTime - p->lastMove;
+ p->lastMove = getMyTime();
+
+ p->avarage += interval;
+ p->count++;
+
+ if( p->count == PROTECT_SPEED_AVARAGE )
+ {
+ int index;
+
+ index = p->avarage/PROTECT_SPEED_AVARAGE;
+ p->avarage = 0;
+ p->count = 0;
+
+ if( index < PROTECT_SPEED_INTERVAL_TIMEOUT )
+ {
+ p->isDown = TRUE;
+ }
+
+ //printf("speed index = %d\n", index);
+ }
+}
+
+void rereshLastPing(protect_t *p)
+{
+ //my_time_t currentTime;
+ //my_time_t interval;
+
+ //currentTime = getMyTime();
+
+ //interval = currentTime - p->lastPing;
+ p->lastPing = getMyTime();
+
+ //printf("interval = %d\n", interval);
+}
+
+bool_t isDown(protect_t *p)
+{
+ my_time_t currentTime;
+ my_time_t interval;
+
+ currentTime = getMyTime();
+
+ interval = currentTime - p->lastPing;
+
+ if( interval > PROTECT_PING_INTERVAL_TIMEOUT )
+ {
+ p->isDown = TRUE;
+ }
+
+ return p->isDown;
+}
+
+void destroyProtect(protect_t *p)
+{
+ assert( p != NULL );
+ free(p);
+}
diff --git a/src/base/protect.h b/src/base/protect.h
new file mode 100644
index 0000000..b0db5a9
--- /dev/null
+++ b/src/base/protect.h
@@ -0,0 +1,30 @@
+
+#ifndef PROTECT_H
+
+#define PROTECT_H
+
+#include "base/main.h"
+#include "base/myTimer.h"
+
+#define PROTECT_PING_INTERVAL_TIMEOUT 5000
+#define PROTECT_SPEED_INTERVAL_TIMEOUT 40
+#define PROTECT_SPEED_AVARAGE 10
+
+typedef struct protect_struct
+{
+ my_time_t lastPing;
+
+ my_time_t lastMove;
+ my_time_t avarage;
+ int count;
+
+ bool_t isDown;
+} protect_t;
+
+extern protect_t* newProtect();
+extern void refreshLastMove(protect_t *p);
+extern void rereshLastPing(protect_t *p);
+extern bool_t isDown(protect_t *p);
+extern void destroyProtect(protect_t *p);
+
+#endif
diff --git a/src/base/proto.c b/src/base/proto.c
new file mode 100644
index 0000000..52c9dd6
--- /dev/null
+++ b/src/base/proto.c
@@ -0,0 +1,713 @@
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+
+#include "base/main.h"
+#include "base/list.h"
+#include "base/tux.h"
+#include "base/item.h"
+#include "base/shot.h"
+#include "base/arenaFile.h"
+#include "base/myTimer.h"
+#include "base/server.h"
+#include "base/proto.h"
+#include "base/net_multiplayer.h"
+#include "base/checkFront.h"
+#include "base/idManager.h"
+#include "base/protect.h"
+
+#ifndef PUBLIC_SERVER
+#include "client/language.h"
+#include "screen/screen_world.h"
+#include "screen/screen_setting.h"
+#include "screen/screen_choiceArena.h"
+#include "screen/screen_analyze.h"
+#include "client/client.h"
+#include "client/term.h"
+#endif
+
+#ifdef PUBLIC_SERVER
+#include "server/heightScore.h"
+#include "server/publicServer.h"
+#endif
+
+void proto_send_error_server(int type, client_t *client, int errorcode)
+{
+ char msg[STR_PROTO_SIZE];
+
+ sprintf(msg, "error %d\n", errorcode);
+
+ protoSendClient(type, client, msg, CHECK_FORNT_TYPE_SIMPLE, CHECK_FRONT_ID_NONE);
+}
+
+#ifndef PUBLIC_SERVER
+
+void proto_recv_error_client(char *msg)
+{
+ char cmd[STR_PROTO_SIZE];
+ int errorcode;
+
+ assert( msg != NULL );
+
+ sscanf(msg, "%s %d",
+ cmd, &errorcode);
+
+ printf("proto error code %d\n", errorcode);
+
+ switch(errorcode)
+ {
+ case PROTO_ERROR_CODE_BAD_VERSION :
+ setMsgToAnalyze(getMyText("ERROR_BAD_VERSION"));
+ setWorldEnd();
+ break;
+ }
+}
+
+#endif
+
+#ifndef PUBLIC_SERVER
+
+void proto_send_hello_client(char *name)
+{
+ char msg[STR_PROTO_SIZE];
+
+ sprintf(msg, "hello %s %s\n", TUXANCI_NG_VERSION, name);
+ sendServer(msg);
+}
+
+#endif
+
+void proto_recv_hello_server(client_t *client, char *msg)
+{
+ char cmd[STR_PROTO_SIZE];
+ char version[STR_NAME_SIZE];
+ char name[STR_NAME_SIZE];
+
+ assert( client != NULL );
+
+ strcpy(version, "");
+ strcpy(name, "");
+
+ sscanf(msg, "%s %s %s", cmd, version, name);
+
+ if( strncmp(version, TUXANCI_NG_VERSION, strlen(TUXANCI_NG_VERSION)) != 0 )
+ {
+ proto_send_error_server(PROTO_SEND_ONE, client, PROTO_ERROR_CODE_BAD_VERSION);
+ client->status = NET_STATUS_ZOMBIE;
+ return;
+ }
+
+ client->tux = newTux();
+ client->tux->control = TUX_CONTROL_NET;
+ client->tux->client = client;
+
+ addObjectToSpace(getCurrentArena()->spaceTux, client->tux);
+
+ if( strlen(name) > STR_NAME_SIZE-1 )
+ {
+ name[STR_NAME_SIZE-1] = '\0';
+ }
+
+ strcpy(client->tux->name, name);
+ sendInfoCreateClient(client);
+}
+
+void proto_send_status_server(int type, client_t *client)
+{
+ char msg[STR_PROTO_SIZE];
+
+ sprintf(msg, "version: %s\n"
+ "clients: %d\n"
+ "maxclients: %d\n"
+ "uptime: %d\n"
+ "arena: %s\n",
+ TUXANCI_NG_VERSION, getCurrentArena()->spaceTux->list->count,
+ getServerMaxClients(), (unsigned int)getUpdateServer(),
+ getArenaNetName( getChoiceArenaId() ) );
+
+ protoSendClient(type, client, msg, CHECK_FORNT_TYPE_SIMPLE, CHECK_FRONT_ID_NONE);
+ //proto_send(type, client, msg);
+}
+
+void proto_recv_status_server(client_t *client, char *msg)
+{
+ proto_send_status_server(PROTO_SEND_ONE, client);
+}
+
+#ifdef PUBLIC_SERVER
+
+void proto_send_listscore_server(int type, client_t *client, int max)
+{
+ char *str;
+ char *msg;
+ int i;
+
+ msg = malloc( (max * 24) * sizeof(char) );
+ strcpy(msg, "");
+
+ for( i = 0 ; i < max ; i++ )
+ {
+ str = getTableItem(i);
+
+ if( str == NULL )
+ {
+ break;
+ }
+
+ strcat(msg, str);
+ strcat(msg, "\n");
+ }
+
+ //proto_send(type, client, msg);
+ protoSendClient(type, client, msg, CHECK_FORNT_TYPE_SIMPLE, CHECK_FRONT_ID_NONE);
+ free(msg);
+}
+
+void proto_recv_listscore_server(client_t *client, char *msg)
+{
+ char cmd[STR_PROTO_SIZE];
+ int max;
+ int ret;
+
+ assert( msg != NULL );
+
+ ret = sscanf(msg, "%s %d",
+ cmd, &max);
+
+ if( ret != 2 )
+ {
+ max = HEIGHTSCORE_MAX_PLAYERS;
+ }
+
+ proto_send_listscore_server(PROTO_SEND_ONE, client, max);
+}
+
+#endif
+
+#ifndef PUBLIC_SERVER
+
+void proto_send_check_client(int id)
+{
+ char msg[STR_PROTO_SIZE];
+
+ sprintf(msg, "check %d\n", id);
+ sendServer(msg);
+}
+
+#endif
+
+void proto_recv_check_server(client_t *client, char *msg)
+{
+ char cmd[STR_PROTO_SIZE];
+ int id;
+
+ assert( msg != NULL );
+
+ sscanf(msg, "%s %d",
+ cmd, &id);
+
+ delMsgInCheckFront(client->listSendMsg, id);
+}
+
+void proto_send_init_server(int type, client_t *client, client_t *client2)
+{
+ char msg[STR_PROTO_SIZE];
+ int n = WORLD_COUNT_ROUND_UNLIMITED;
+
+ assert( client2 != NULL );
+
+#ifndef PUBLIC_SERVER
+ getSettingCountRound(&n);
+#endif
+
+ sprintf(msg, "init %d %d %d %d %s\n",
+ client2->tux->id, client2->tux->x, client2->tux->y,
+ n, getArenaNetName( getChoiceArenaId() ));
+
+ //proto_send(type, client, msg);
+ protoSendClient(type, client, msg, CHECK_FORNT_TYPE_SIMPLE, CHECK_FRONT_ID_NONE);
+}
+
+#ifndef PUBLIC_SERVER
+
+void proto_recv_init_client(char *msg)
+{
+ char cmd[STR_PROTO_SIZE];
+ char arena_name[STR_PROTO_SIZE];
+ tux_t *tux;
+ int id;
+ int x, y, n;
+
+ assert( msg != NULL );
+
+ sscanf(msg, "%s %d %d %d %d %s",
+ cmd, &id, &x, &y, &n, arena_name);
+
+ setWorldArena( getArenaIdFormNetName(arena_name) );
+ setMaxCountRound(n);
+
+ tux = newTux();
+ replaceTuxID(tux, id);
+ tux->x = x;
+ tux->y = y;
+ tux->control = TUX_CONTROL_KEYBOARD_RIGHT;
+ setControlTux(tux, TUX_CONTROL_KEYBOARD_RIGHT);
+
+ getSettingNameRight(tux->name);
+
+ addObjectToSpace(getCurrentArena()->spaceTux, tux);
+}
+
+#endif
+
+void proto_send_event_server(int type, client_t *client, tux_t *tux, int action)
+{
+ char msg[STR_PROTO_SIZE];
+
+ sprintf(msg, "event %d %d\n", tux->id, action);
+
+ //proto_send(type, client, msg);
+ protoSendClient(type, client, msg, CHECK_FORNT_TYPE_SIMPLE, CHECK_FRONT_ID_NONE);
+}
+
+#ifndef PUBLIC_SERVER
+
+void proto_recv_event_client(char *msg)
+{
+ char cmd[STR_PROTO_SIZE];
+ int id, action;
+ tux_t *tux;
+
+ assert( msg != NULL );
+
+ sscanf(msg, "%s %d %d", cmd, &id, &action);
+
+ tux = getObjectFromSpaceWithID(getCurrentArena()->spaceTux, id);
+
+ if( tux != NULL )
+ {
+ actionTux(tux, action);
+ }
+}
+
+#endif
+
+#ifndef PUBLIC_SERVER
+
+void proto_send_event_client(int action)
+{
+ char msg[STR_PROTO_SIZE];
+
+ sprintf(msg, "event %d\n", action);
+
+ sendServer(msg);
+}
+
+#endif
+
+/*
+static void debug_interval()
+{
+ static my_time_t lastEvent = 0;
+ my_time_t curentTime;
+
+ if( lastEvent == 0 )
+ {
+ lastEvent = getMyTime();
+ }
+
+ curentTime = getMyTime();
+
+ printf("time = %d\n", curentTime - lastEvent);
+
+ lastEvent = getMyTime();
+}
+*/
+
+void proto_recv_event_server(client_t *client, char *msg)
+{
+ char cmd[STR_PROTO_SIZE];
+ int action;
+
+ assert( client != NULL );
+ assert( msg != NULL );
+
+ //debug_interval();
+
+ sscanf(msg, "%s %d", cmd, &action);
+
+ proto_send_event_server(PROTO_SEND_ALL_SEES_TUX, client, client->tux, action);
+
+ refreshLastMove(client->protect);
+ actionTux(client->tux, action);
+}
+
+void proto_send_newtux_server(int type, client_t *client, tux_t *tux)
+{
+ char msg[STR_PROTO_SIZE];
+ int x, y;
+
+ assert( tux != NULL );
+
+ if( tux->bonus == BONUS_HIDDEN )
+ {
+ x = TUX_LOCATE_UNKNOWN;
+ y = TUX_LOCATE_UNKNOWN;
+ }
+ else
+ {
+ x = tux->x;
+ y = tux->y;
+ }
+
+ getTuxProportion(tux, &x, &y, NULL, NULL);
+
+ sprintf(msg, "newtux %d %d %d %d %d %d %d %s %d %d %d %d %d %d %d %d %d %d %d\n",
+ tux->id ,x, y, tux->status, tux->position ,tux->frame, tux->score, tux->name,
+ tux->gun, tux->bonus, tux->shot[GUN_SIMPLE], tux->shot[GUN_DUAL_SIMPLE],
+ tux->shot[GUN_SCATTER], tux->shot[GUN_TOMMY], tux->shot[GUN_LASSER],
+ tux->shot[GUN_MINE], tux->shot[GUN_BOMBBALL],
+ tux->bonus_time, tux->pickup_time);
+
+ //proto_send(type, client, msg);
+ protoSendClient(type, client, msg, CHECK_FORNT_TYPE_SIMPLE, CHECK_FRONT_ID_NONE);
+}
+
+#ifndef PUBLIC_SERVER
+
+void proto_recv_newtux_client(char *msg)
+{
+ char cmd[STR_PROTO_SIZE];
+ char name[STR_NAME_SIZE];
+ int id, x, y, status, position, frame, score;
+ int myGun, myBonus;
+ int gun1, gun2, gun3, gun4, gun5, gun6, gun7;
+ int time1, time2;
+ tux_t *tux;
+
+ assert( msg != NULL );
+
+ if( getCurrentArena() == NULL )
+ {
+ return;
+ }
+
+ sscanf(msg, "%s %d %d %d %d %d %d %d %s %d %d %d %d %d %d %d %d %d %d %d",
+ cmd, &id, &x, &y, &status, &position, &frame, &score, name,
+ &myGun, &myBonus, &gun1, &gun2, &gun3, &gun4, &gun5, &gun6, &gun7, &time1, &time2);
+
+ tux = getObjectFromSpaceWithID(getCurrentArena()->spaceTux, id);
+
+ if( tux != NULL )
+ {
+ assert( tux->id == id );
+ }
+
+ if( tux == NULL )
+ {
+ char term_msg[STR_SIZE];
+ sprintf(term_msg, "connect new client( id = %d)\n", id);
+ appendTextInTerm(term_msg);
+
+ tux = newTux();
+ replaceTuxID(tux, id);
+ tux->control = TUX_CONTROL_NET;
+ addObjectToSpace(getCurrentArena()->spaceTux, tux);
+ }
+
+ moveObjectInSpace(getCurrentArena()->spaceTux, tux, x, y);
+ tux->status = status;
+ tux->position = position;
+ tux->frame = frame;
+ tux->score = score;
+ strcpy(tux->name, name);
+ tux->gun = myGun;
+ tux->bonus = myBonus;
+ tux->shot[GUN_SIMPLE] = gun1;
+ tux->shot[GUN_DUAL_SIMPLE] = gun2;
+ tux->shot[GUN_SCATTER] = gun3;
+ tux->shot[GUN_TOMMY] = gun4;
+ tux->shot[GUN_LASSER] = gun5;
+ tux->shot[GUN_MINE] = gun6;
+ tux->shot[GUN_BOMBBALL] = gun7;
+ tux->bonus_time = time1;
+ tux->pickup_time = time2;
+}
+
+#endif
+
+void proto_send_kill_server(int type, client_t *client, tux_t *tux)
+{
+ char msg[STR_PROTO_SIZE];
+
+ assert( tux != NULL );
+
+ sprintf(msg, "kill %d\n", tux->id);
+
+ //proto_send(type, client, msg);
+ protoSendClient(type, client, msg, CHECK_FORNT_TYPE_SIMPLE, CHECK_FRONT_ID_NONE);
+}
+
+#ifndef PUBLIC_SERVER
+
+void proto_recv_kill_client(char *msg)
+{
+ char cmd[STR_PROTO_SIZE];
+ int id;
+ tux_t *tux;
+
+ assert( msg != NULL );
+
+ sscanf(msg, "%s %d", cmd, &id);
+
+ tux = getObjectFromSpaceWithID(getCurrentArena()->spaceTux, id);
+
+ if( tux != NULL )
+ {
+ eventTuxIsDead(tux);
+ }
+}
+
+#endif
+
+void proto_send_del_server(int type, client_t *client, int id)
+{
+ char msg[STR_PROTO_SIZE];
+ int check_id;
+
+ check_id = getNewID();
+
+ sprintf(msg, "del %d %d\n",
+ id, check_id);
+
+ protoSendClient(type, client, msg, CHECK_FORNT_TYPE_CHECK, check_id);
+ //proto_check(type, client, msg, check_id);
+}
+
+#ifndef PUBLIC_SERVER
+
+void proto_recv_del_client(char *msg)
+{
+ char cmd[STR_PROTO_SIZE];
+ int id, check_id;
+ tux_t *tux;
+ shot_t *shot;
+ item_t *item;
+
+ assert( msg != NULL );
+
+ sscanf(msg, "%s %d %d",
+ cmd, &id, &check_id);
+
+ proto_send_check_client(check_id);
+
+ tux = getObjectFromSpaceWithID(getCurrentArena()->spaceTux, id);
+
+ if( tux != NULL )
+ {
+ char term_msg[STR_SIZE];
+
+ //printf("delete tux..\n");
+ sprintf(term_msg, "tux with id %d is disconnect\n", tux->id);
+ appendTextInTerm(term_msg);
+
+ delObjectFromSpaceWithObject(getCurrentArena()->spaceTux, tux, destroyTux);
+ return;
+ }
+
+ shot = getObjectFromSpaceWithID(getCurrentArena()->spaceShot, id);
+
+ if( shot != NULL )
+ {
+ //printf("delete shot..\n");
+ delObjectFromSpaceWithObject(getCurrentArena()->spaceShot, shot, destroyShot);
+ return;
+ }
+
+ item = getObjectFromSpaceWithID(getCurrentArena()->spaceItem, id);
+
+ if( item != NULL )
+ {
+ //printf("delete item..\n");
+ delObjectFromSpaceWithObject(getCurrentArena()->spaceItem, item, destroyItem);
+ return;
+ }
+}
+
+#endif
+
+void proto_send_additem_server(int type, client_t *client, item_t *p)
+{
+ char msg[STR_PROTO_SIZE];
+ int check_id;
+
+ assert( p != NULL );
+
+ check_id = getNewID();
+
+ sprintf(msg, "additem %d %d %d %d %d %d %d %d\n",
+ p->id, p->type, p->x, p->y, p->count, p->frame, p->author_id, check_id);
+
+ //proto_send(type, client, msg);
+ //proto_check(type, client, msg, check_id);
+ protoSendClient(type, client, msg, CHECK_FORNT_TYPE_CHECK, check_id);
+}
+
+#ifndef PUBLIC_SERVER
+
+void proto_recv_additem_client(char *msg)
+{
+ char cmd[STR_PROTO_SIZE];
+ int id, type, x, y, count, frame, author_id, check_id;
+ item_t *item;
+
+ assert( msg != NULL );
+
+ if( getCurrentArena() == NULL )
+ {
+ return;
+ }
+
+ sscanf(msg, "%s %d %d %d %d %d %d %d %d",
+ cmd, &id, &type, &x, &y, &count, &frame, &author_id, &check_id);
+
+ proto_send_check_client(check_id);
+
+ if( ( item = getObjectFromSpaceWithID(getCurrentArena()->spaceItem, id) ) != NULL )
+ {
+ return;
+ }
+
+ item = newItem(x, y, type, author_id);
+
+ replaceItemID(item, id);
+ item->count = count;
+ item->frame = frame;
+
+ addObjectToSpace(getCurrentArena()->spaceItem, item);
+}
+
+#endif
+
+void proto_send_shot_server(int type, client_t *client, shot_t *p)
+{
+ char msg[STR_PROTO_SIZE];
+
+ assert( p != NULL );
+
+ sprintf(msg, "shot %d %d %d %d %d %d %d %d %d\n",
+ p->id, p->x, p->y, p->px, p->py, p->position, p->gun, p->author_id, p->isCanKillAuthor);
+
+ //proto_send(type, client, msg);
+ //proto_check(type, client, msg, check_id);
+ protoSendClient(type, client, msg, CHECK_FORNT_TYPE_SIMPLE, CHECK_FRONT_ID_NONE);
+}
+
+#ifndef PUBLIC_SERVER
+
+void proto_recv_shot_client(char *msg)
+{
+ char cmd[STR_PROTO_SIZE];
+ int x, y, px, py, position, gun, shot_id, author_id, isCanKillAuthor;
+ shot_t *shot;
+
+ assert( msg != NULL );
+
+ sscanf(msg, "%s %d %d %d %d %d %d %d %d %d",
+ cmd, &shot_id, &x, &y, &px, &py, &position, &gun, &author_id, &isCanKillAuthor);
+
+
+ if( ( shot = getObjectFromSpaceWithID(getCurrentArena()->spaceShot, shot_id) ) != NULL )
+ {
+ delObjectFromSpaceWithObject(getCurrentArena()->spaceShot, shot, destroyShot);
+
+ //return;
+ }
+
+ shot = newShot(x, y, px, py, gun, author_id);
+
+ replaceShotID(shot, shot_id);
+ shot->isCanKillAuthor = isCanKillAuthor;
+ shot->position = position;
+
+ if( shot->gun == GUN_LASSER )
+ {
+ transformOnlyLasser(shot);
+ }
+
+ addObjectToSpace(getCurrentArena()->spaceShot, shot);
+}
+
+#endif
+
+#ifndef PUBLIC_SERVER
+
+void proto_send_ping_client()
+{
+ char msg[STR_PROTO_SIZE];
+ sprintf(msg, "ping\n");
+ sendServer(msg);
+}
+
+#endif
+
+void proto_recv_ping_server(client_t *client, char *msg)
+{
+}
+
+void proto_send_ping_server(int type, client_t *client)
+{
+ char msg[STR_PROTO_SIZE];
+ sprintf(msg, "ping\n");
+ //proto_send(type, client, msg);
+ protoSendClient(type, client, msg, CHECK_FORNT_TYPE_SIMPLE, CHECK_FRONT_ID_NONE);
+}
+
+#ifndef PUBLIC_SERVER
+
+void proto_recv_ping_client(char *msg)
+{
+}
+
+#endif
+
+void proto_send_end_server(int type, client_t *client)
+{
+ char msg[STR_PROTO_SIZE];
+ strcpy(msg, "end\n");
+ //proto_send(type, client, msg);
+ protoSendClient(type, client, msg, CHECK_FORNT_TYPE_SIMPLE, CHECK_FRONT_ID_NONE);
+}
+
+#ifndef PUBLIC_SERVER
+
+void proto_recv_end_client(char *msg)
+{
+ assert( msg != NULL );
+
+ setWorldEnd();
+}
+
+#endif
+
+#ifndef PUBLIC_SERVER
+
+void proto_send_end_client()
+{
+ char msg[STR_PROTO_SIZE];
+ strcpy(msg, "end\n");
+ sendServer(msg);
+}
+
+#endif
+
+void proto_recv_end_server(client_t *client, char *msg)
+{
+ assert( msg != NULL );
+ assert( client != NULL );
+
+ client->status = NET_STATUS_ZOMBIE;
+}
+
diff --git a/src/base/proto.h b/src/base/proto.h
new file mode 100644
index 0000000..9fe9303
--- /dev/null
+++ b/src/base/proto.h
@@ -0,0 +1,81 @@
+
+#ifndef MY_PROTO
+
+#define MY_PROTO
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+
+#include "base/main.h"
+#include "base/list.h"
+#include "base/item.h"
+#include "base/shot.h"
+#include "base/arenaFile.h"
+#include "base/myTimer.h"
+#include "base/server.h"
+#include "base/proto.h"
+#include "base/net_multiplayer.h"
+
+#ifndef PUBLIC_SERVER
+#include "screen/screen_world.h"
+#include "screen/screen_setting.h"
+#include "screen/screen_choiceArena.h"
+#include "client/client.h"
+#endif
+
+#ifdef PUBLIC_SERVER
+#include "server/publicServer.h"
+#endif
+
+#define PROTO_SEND_ONE 0
+#define PROTO_SEND_ALL 1
+#define PROTO_SEND_BUT 3
+#define PROTO_SEND_ALL_SEES_TUX 4
+
+#define PROTO_ERROR_CODE_UNKNOWN 0
+#define PROTO_ERROR_CODE_BAD_VERSION 1
+#define PROTO_ERROR_CODE_BAD_NAME 2
+#define PROTO_ERROR_CODE_BAD_COMMAND 3
+#define PROTO_ERROR_CODE_TIMEOUT 4
+
+extern void proto_send_error_server(int type, client_t *client, int errorcode);
+extern void proto_recv_error_client(char *msg);
+extern void proto_send_hello_client(char *name);
+extern void proto_recv_hello_server(client_t *client, char *msg);
+extern void proto_send_status_server(int type, client_t *client);
+extern void proto_recv_status_server(client_t *client, char *msg);
+extern void proto_send_listscore_server(int type, client_t *client, int max);
+extern void proto_recv_listscore_server(client_t *client, char *msg);
+extern void proto_send_check_client(int id);
+extern void proto_recv_check_server(client_t *client, char *msg);
+extern void proto_send_init_server(int type, client_t *client, client_t *client2);
+extern void proto_recv_init_client(char *msg);
+extern void proto_send_event_server(int type, client_t *client, tux_t *tux, int action);
+extern void proto_recv_event_client(char *msg);
+extern void proto_send_event_client(int action);
+extern void proto_recv_event_server(client_t *client, char *msg);
+extern void proto_send_newtux_server(int type, client_t *client, tux_t *tux);
+extern void proto_recv_newtux_client(char *msg);
+extern void proto_send_kill_server(int type, client_t *client, tux_t *tux);
+extern void proto_recv_kill_client(char *msg);
+extern void proto_send_score_server(int type, client_t *client, tux_t *tux);
+extern void proto_recv_score_client(char *msg);
+extern void proto_send_del_server(int type, client_t *client, int id);
+extern void proto_recv_del_client(char *msg);
+extern void proto_send_additem_server(int type, client_t *client, item_t *p);
+extern void proto_recv_additem_client(char *msg);
+extern void proto_send_shot_server(int type, client_t *client, shot_t *p);
+extern void proto_recv_shot_client(char *msg);
+extern void proto_send_ping_client();
+extern void proto_recv_ping_server(client_t *client, char *msg);
+extern void proto_send_ping_server(int type, client_t *client);
+extern void proto_recv_ping_client(char *msg);
+extern void proto_send_end_server(int type, client_t *client);
+extern void proto_recv_end_client(char *msg);
+extern void proto_send_end_client();
+extern void proto_recv_end_server(client_t *client, char *msg);
+
+#endif
+
diff --git a/src/base/server.c b/src/base/server.c
new file mode 100644
index 0000000..ae9f170
--- /dev/null
+++ b/src/base/server.c
@@ -0,0 +1,984 @@
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/select.h>
+
+#include <unistd.h>
+#include <fcntl.h>
+#include <sys/ioctl.h>
+#include <sys/time.h>
+
+#include "base/main.h"
+#include "base/list.h"
+#include "base/tux.h"
+#include "base/proto.h"
+#include "base/server.h"
+#include "base/myTimer.h"
+#include "base/arena.h"
+#include "base/net_multiplayer.h"
+#include "base/checkFront.h"
+#include "base/protect.h"
+
+#ifndef PUBLIC_SERVER
+#include "screen/screen_world.h"
+#endif
+
+#ifdef PUBLIC_SERVER
+#include "server/publicServer.h"
+#include "server/heightScore.h"
+#endif
+
+#ifdef SUPPORT_NET_UNIX_UDP
+#include "net_unix/udp.h"
+static sock_udp_t *sock_server_udp;
+static sock_udp_t *sock_server_udp_second;
+#endif
+
+#ifdef SUPPORT_NET_SDL_UDP
+#include "net_sdl/sdl_udp.h"
+static sock_sdl_udp_t *sock_server_sdl_udp;
+#endif
+
+static list_t *listClient;
+static list_t *listServerTimer;
+static time_t timeUpdate;
+static int maxClients;
+
+static void startUpdateServer()
+{
+ timeUpdate = time(NULL);
+}
+
+time_t getUpdateServer()
+{
+ return time(NULL) - timeUpdate;
+}
+
+static void delZombieCLient(void *p_nothink)
+{
+ client_t *thisClient;
+ my_time_t currentTime;
+ int i;
+
+ currentTime = getMyTime();
+
+ for( i = 0 ; i < listClient->count; i++)
+ {
+ thisClient = (client_t *) listClient->list[i];
+
+ if( isDown(thisClient->protect) == TRUE )
+ {
+ //proto_send_error_server(PROTO_SEND_ONE, thisClient, PROTO_ERROR_CODE_TIMEOUT);
+ proto_send_end_server(PROTO_SEND_ONE, thisClient);
+ eventMsgInCheckFront(thisClient);
+ thisClient->status = NET_STATUS_ZOMBIE;
+ }
+
+ if( thisClient->status == NET_STATUS_ZOMBIE )
+ {
+ if( thisClient->tux != NULL )
+ {
+ proto_send_del_server(PROTO_SEND_ALL, NULL, thisClient->tux->id);
+ }
+
+ delListItem(listClient, i, destroyClient);
+ }
+ }
+
+}
+
+static void eventPeriodicSyncClient(void *p_nothink)
+{
+ client_t *thisClientInfo;
+ client_t *thisClientSend;
+ tux_t *thisTux;
+ int i, j;
+
+ for( i = 0 ; i < listClient->count; i++)
+ {
+ thisClientSend = (client_t *) listClient->list[i];
+
+ if( thisClientSend->tux == NULL )
+ {
+ continue;
+ }
+
+#ifndef PUBLIC_SERVER
+ thisTux = getControlTux(TUX_CONTROL_KEYBOARD_RIGHT);
+ if( isTuxSeesTux(thisClientSend->tux, thisTux) )
+ proto_send_newtux_server(PROTO_SEND_ONE, thisClientSend, thisTux);
+#endif
+
+ for( j = 0 ; j < listClient->count; j++)
+ {
+ thisClientInfo = (client_t *) listClient->list[j];
+ thisTux = thisClientInfo->tux;
+
+ if( thisTux != NULL &&
+ thisClientSend != thisClientInfo &&
+ isTuxSeesTux(thisClientSend->tux, thisTux) )
+ {
+ proto_send_newtux_server(PROTO_SEND_ONE,
+ thisClientSend, thisTux);
+ }
+ }
+ }
+}
+
+static void eventSendPingClients(void *p_nothink)
+{
+ proto_send_ping_server(PROTO_SEND_ALL, NULL);
+}
+
+static void setServerTimer()
+{
+ if( listServerTimer != NULL )
+ {
+ destroyTimer(listServerTimer);
+ }
+
+ restartTimer();
+ listServerTimer = newTimer();
+
+ addTaskToTimer(listServerTimer, TIMER_PERIODIC, delZombieCLient, NULL, SERVER_TIMEOUT);
+ addTaskToTimer(listServerTimer, TIMER_PERIODIC, eventPeriodicSyncClient, NULL, SERVER_TIME_SYNC);
+ addTaskToTimer(listServerTimer, TIMER_PERIODIC, eventSendPingClients, NULL, SERVER_TIME_PING);
+}
+
+void static initServer()
+{
+ startUpdateServer();
+ listServerTimer = NULL;
+ listClient = newList();
+ setServerMaxClients(SERVER_MAX_CLIENTS);
+ setServerTimer();
+}
+
+#ifdef SUPPORT_NET_UNIX_UDP
+int initUdpServer(char *ip, int port, int proto)
+{
+ sock_server_udp = bindUdpSocket(ip, port, proto);
+ sock_server_udp_second = NULL;
+
+ if( sock_server_udp == NULL )
+ {
+ return -1;
+ }
+
+ initServer();
+
+ printf("server listen UDP port %s %d\n", ip, port);
+
+ return 0;
+}
+#endif
+
+#ifdef PUBLIC_SERVER
+
+int initUdpPublicServer(char *ip4, int port4, char *ip6, int port6)
+{
+ sock_server_udp = NULL;
+ sock_server_udp_second = NULL;
+
+ if( ip4 != NULL )
+ {
+ sock_server_udp = bindUdpSocket(ip4, port4, PROTO_UDPv4);
+
+ if( sock_server_udp == NULL )
+ {
+ return -1;
+ }
+
+ printf("server listen UDP port %s %d\n", ip4, port4);
+ }
+
+ if( ip6 != NULL )
+ {
+ sock_server_udp_second = bindUdpSocket(ip6, port6, PROTO_UDPv6);
+
+ if( sock_server_udp_second == NULL )
+ {
+ return -1;
+ }
+
+ printf("server listen UDP port %s %d\n", ip6, port6);
+ }
+
+ initServer();
+
+ return 0;
+}
+
+#endif
+
+#ifdef SUPPORT_NET_SDL_UDP
+int initSdlUdpServer(int port)
+{
+ sock_server_sdl_udp = bindSdlUdpSocket(port);
+
+ if( sock_server_sdl_udp == NULL )
+ {
+ return -1;
+ }
+
+ initServer();
+
+ printf("server listen UDP port %d\n", port);
+
+ return 0;
+}
+#endif
+
+static client_t* newAnyClient()
+{
+ client_t *new;
+
+ new = malloc( sizeof(client_t) );
+ memset(new, 0, sizeof(client_t));
+
+ new->status = NET_STATUS_OK;
+ new->listRecvMsg = newList();
+ new->listSendMsg = newCheckFront();
+ new->protect = newProtect();
+
+ return new;
+}
+
+#ifdef SUPPORT_NET_UNIX_UDP
+client_t* newUdpClient(sock_udp_t *sock_udp)
+{
+ client_t *new;
+ char str_ip[STR_IP_SIZE];
+
+ assert( sock_udp != NULL );
+
+ getSockUdpIp(sock_udp, str_ip, STR_IP_SIZE);
+ printf("new client from %s %d\n", str_ip, getSockUdpPort(sock_udp));
+
+ new = newAnyClient();
+ new->socket_udp = sock_udp;
+
+ return new;
+}
+#endif
+
+#ifdef SUPPORT_NET_SDL_UDP
+client_t* newSdlUdpClient(sock_sdl_udp_t *sock_sdl_udp)
+{
+ client_t *new;
+
+ assert( sock_sdl_udp != NULL );
+
+ printf("new client from %d\n", getSockSdlUdpPort(sock_sdl_udp));
+ new = newAnyClient();
+ new->socket_sdl_udp = sock_sdl_udp;
+
+ return new;
+}
+#endif
+
+void destroyClient(client_t *p)
+{
+ char str_ip[STR_IP_SIZE];
+
+ assert( p != NULL );
+
+ eventMsgInCheckFront(p);
+
+#ifdef SUPPORT_NET_UNIX_UDP
+ getSockUdpIp(p->socket_udp, str_ip, STR_IP_SIZE);
+ printf("close connect %s %d\n", str_ip, getSockUdpPort(p->socket_udp) );
+#endif
+
+#ifdef SUPPORT_NET_UNIX_UDP
+ closeUdpSocket(p->socket_udp);
+#endif
+
+#ifdef SUPPORT_NET_SDL_UDP
+ closeSdlUdpSocket(p->socket_sdl_udp);
+#endif
+
+ destroyListItem(p->listRecvMsg, free);
+ destroyCheckFront(p->listSendMsg);
+
+ destroyProtect(p->protect);
+
+ if( p->tux != NULL )
+ {
+#ifdef PUBLIC_SERVER
+ addPlayerInHighScore(p->tux->name, p->tux->score);
+#endif
+ delObjectFromSpaceWithObject(getCurrentArena()->spaceTux, p->tux, destroyTux);
+ }
+
+ free(p);
+}
+
+list_t* getListServerClient()
+{
+ return listClient;
+}
+
+int getServerMaxClients()
+{
+ return maxClients;
+}
+
+void setServerMaxClients(int n)
+{
+ maxClients = n;
+}
+
+void sendClient(client_t *p, char *msg)
+{
+ assert( p != NULL );
+ assert( msg != NULL );
+
+ if( p->status != NET_STATUS_ZOMBIE )
+ {
+ int ret;
+
+#ifndef PUBLIC_SERVER
+ if( isParamFlag("--send") )
+ {
+ printf("send -> %s", msg);
+ }
+#endif
+
+#ifdef SUPPORT_NET_UNIX_UDP
+ if( p->socket_udp->proto == PROTO_UDPv4 &&
+ sock_server_udp != NULL &&
+ sock_server_udp->proto == PROTO_UDPv4 )
+ {
+ ret = writeUdpSocket(sock_server_udp, p->socket_udp, msg, strlen(msg));
+ }
+
+ if( p->socket_udp->proto == PROTO_UDPv6 &&
+ sock_server_udp != NULL &&
+ sock_server_udp->proto == PROTO_UDPv6 )
+ {
+ ret = writeUdpSocket(sock_server_udp, p->socket_udp, msg, strlen(msg));
+ }
+
+ if( p->socket_udp->proto == PROTO_UDPv6 &&
+ sock_server_udp_second != NULL &&
+ sock_server_udp_second->proto == PROTO_UDPv6 )
+ {
+ ret = writeUdpSocket(sock_server_udp_second, p->socket_udp, msg, strlen(msg));
+ }
+#endif
+
+#ifdef SUPPORT_NET_SDL_UDP
+ ret = writeSdlUdpSocket(sock_server_sdl_udp, p->socket_sdl_udp, msg, strlen(msg));
+#endif
+ }
+}
+
+static void addMsgClient(client_t *p, char *msg, int type, int id)
+{
+ assert( p != NULL );
+ assert( msg != NULL );
+
+ if( p->status != NET_STATUS_ZOMBIE )
+ {
+ addMsgInCheckFront(p->listSendMsg, msg, type, id);
+ }
+}
+
+static void addMsgAllClientBut(char *msg, client_t *p, int type, int id)
+{
+ client_t *thisClient;
+ int i;
+
+ assert( msg != NULL );
+
+ for( i = 0 ; i < listClient->count; i++)
+ {
+ thisClient = (client_t *) listClient->list[i];
+
+ if( thisClient->tux != NULL && thisClient != p )
+ {
+ addMsgClient(thisClient, msg, type, id);
+ }
+ }
+}
+
+static void addMsgAllClient(char *msg, int type, int id)
+{
+ assert( msg != NULL );
+
+ addMsgAllClientBut(msg, NULL, type, id);
+}
+
+static void addMsgAllClientSeesTux(char *msg, tux_t *tux, int type, int id)
+{
+ int i;
+
+ assert( msg != NULL );
+
+ for( i = 0 ; i < listClient->count ; i++ )
+ {
+ client_t *thisClient;
+ tux_t *thisTux;
+
+ thisClient = (client_t *)listClient->list[i];
+ thisTux = (tux_t *)thisClient->tux;
+
+ if( thisTux == NULL )
+ {
+ continue;
+ }
+
+ if( tux != thisTux &&
+ isTuxSeesTux(thisTux, tux) )
+ {
+ addMsgClient(thisClient, msg, type, id);
+ }
+ }
+}
+
+void protoSendClient(int type, client_t *client, char *msg, int type2, int id)
+{
+ assert( msg != NULL );
+
+ switch( type )
+ {
+ case PROTO_SEND_ONE :
+ assert( client != NULL );
+ addMsgClient(client, msg, type2, id);
+ break;
+ case PROTO_SEND_ALL :
+ assert( client == NULL );
+ addMsgAllClient(msg, type2, id);
+ break;
+ case PROTO_SEND_BUT :
+ assert( client != NULL );
+ addMsgAllClientBut(msg, client, type2, id);
+ break;
+ case PROTO_SEND_ALL_SEES_TUX :
+#ifndef PUBLIC_SERVER
+ if( client != NULL )
+ {
+ addMsgAllClientSeesTux(msg, client->tux, type2, id);
+ }
+ else
+ {
+ addMsgAllClientSeesTux(msg, getControlTux(TUX_CONTROL_KEYBOARD_RIGHT), type2, id);
+ }
+#endif
+#ifdef PUBLIC_SERVER
+ addMsgAllClientSeesTux(msg, client->tux, type2, id);
+#endif
+ break;
+ default :
+ assert( ! "Premenna type ma zlu hodnotu !" );
+ break;
+ }
+}
+
+tux_t *getServerTux()
+{
+ return NULL;
+}
+
+client_t *getClientFromTux(tux_t *tux)
+{
+ client_t *thisClient;
+ int i;
+
+ for( i = 0 ; i < listClient->count; i++)
+ {
+ thisClient = (client_t *) listClient->list[i];
+
+ if( thisClient->tux == tux )
+ {
+ return thisClient;
+ }
+ }
+
+ return NULL;
+}
+
+void sendInfoCreateClient(client_t *client)
+{
+ client_t *thisClient;
+ tux_t *thisTux;
+ item_t *thisItem;
+ int i;
+
+ assert( client != NULL );
+
+ proto_send_init_server(PROTO_SEND_ONE, client, client);
+
+#ifndef PUBLIC_SERVER
+ proto_send_newtux_server(PROTO_SEND_ONE, client, getControlTux(TUX_CONTROL_KEYBOARD_RIGHT) );
+#endif
+
+ for( i = 0 ; i < listClient->count; i++)
+ {
+ thisClient = (client_t *) listClient->list[i];
+ thisTux = thisClient->tux;
+
+ if( thisTux != NULL && thisTux != client->tux )
+ {
+ proto_send_newtux_server(PROTO_SEND_ONE, thisClient, client->tux);
+ proto_send_newtux_server(PROTO_SEND_ONE, client, thisTux);
+ }
+ }
+
+ for( i = 0 ; i < getCurrentArena()->spaceItem->list->count; i++)
+ {
+ thisItem = (item_t *) getCurrentArena()->spaceItem->list->list[i];
+ proto_send_additem_server(PROTO_SEND_ONE, client, thisItem);
+ }
+}
+
+#ifdef SUPPORT_NET_UNIX_UDP
+
+static void eventCreateNewUdpClient(sock_udp_t *socket_udp)
+{
+ client_t *client;
+
+ assert( socket_udp != NULL );
+
+ client = newUdpClient( socket_udp );
+ addList(listClient, client);
+}
+
+#endif
+
+#ifdef SUPPORT_NET_SDL_UDP
+
+static void eventCreateNewSdlUdpClient(sock_sdl_udp_t *socket_sdl_udp)
+{
+ client_t *client;
+
+ assert( socket_sdl_udp != NULL );
+
+ client = newSdlUdpClient( socket_sdl_udp );
+ addList(listClient, client);
+}
+
+#endif
+
+static void eventClientBuffer(client_t *client)
+{
+ char *line;
+ int i;
+
+ assert( client != NULL );
+
+ /* obsluha udalosti od clientov */
+
+ //while( getBufferLine(client->listRecvMsg, line, STR_PROTO_SIZE) >= 0 )
+ for( i = 0 ; i < client->listRecvMsg->count ; i++ )
+ {
+ line = (char *)client->listRecvMsg->list[i];
+
+#ifndef PUBLIC_SERVER
+ if( isParamFlag("--recv") )
+ {
+ printf("recv -> %s", line);
+ }
+#endif
+
+ rereshLastPing(client->protect);
+
+ if( strncmp(line, "hello", 5) == 0 )
+ {
+ proto_recv_hello_server(client, line);
+ continue;
+ }
+
+ if( strncmp(line, "status", 6) == 0 )
+ {
+ proto_recv_status_server(client, line);
+ continue;
+ }
+
+#ifdef PUBLIC_SERVER
+ if( strncmp(line, "list", 4) == 0 )
+ {
+ proto_recv_listscore_server(client, line);
+ continue;
+ }
+#endif
+
+ if( client->tux != NULL )
+ {
+ if( strncmp(line, "event", 5) == 0 )
+ {
+ proto_recv_event_server(client, line);
+ continue;
+ }
+
+ if( strncmp(line, "check", 5) == 0 )
+ {
+ proto_recv_check_server(client, line);
+ continue;
+ }
+
+ if( strncmp(line, "ping", 4) == 0 )
+ {
+ proto_recv_ping_server(client, line);
+ continue;
+ }
+
+ if( strncmp(line, "end", 3) == 0 )
+ {
+ proto_recv_end_server(client, line);
+ continue;
+ }
+ }
+
+ if( client->tux != NULL )
+ {
+ proto_send_error_server(PROTO_SEND_ONE, client, PROTO_ERROR_CODE_BAD_COMMAND);
+ }
+ }
+
+ destroyListItem(client->listRecvMsg, free);
+ client->listRecvMsg = newList();
+}
+
+void eventClientListBuffer()
+{
+ int i;
+ client_t *thisClient;
+
+ for( i = 0 ; i < listClient->count; i++)
+ {
+ thisClient = (client_t *) listClient->list[i];
+ eventClientBuffer(thisClient);
+ eventMsgInCheckFront(thisClient);
+ }
+}
+
+#ifdef SUPPORT_NET_UNIX_UDP
+
+static client_t* findUdpClient(sock_udp_t *sock_udp)
+{
+ int i;
+ client_t *thisClient;
+
+ for( i = 0 ; i < listClient->count; i++)
+ {
+ thisClient = (client_t *) listClient->list[i];
+
+ if( getSockUdpPort(thisClient->socket_udp) == getSockUdpPort(sock_udp) )
+ {
+ return thisClient;
+ }
+ }
+
+ return NULL;
+}
+
+static void eventClientUdpSelect(sock_udp_t *sock_server)
+{
+ sock_udp_t *sock_client;
+ client_t *client;
+ char listRecvMsg[STR_SIZE];
+ bool_t isCreateNewClient;
+ int ret;
+
+ assert( sock_server != NULL );
+
+ sock_client = newSockUdp(sock_server->proto);
+ isCreateNewClient = FALSE;
+
+ memset(listRecvMsg, 0, STR_SIZE);
+
+ ret = readUdpSocket(sock_server, sock_client, listRecvMsg, STR_SIZE-1);
+
+ client = findUdpClient(sock_client);
+
+ if( client == NULL )
+ {
+ if( getCurrentArena()->spaceTux->list->count+1 > maxClients )
+ {
+ destroySockUdp(sock_client);
+ return;
+ }
+
+ eventCreateNewUdpClient(sock_client);
+ client = findUdpClient(sock_client);
+ isCreateNewClient = TRUE;
+ }
+
+ if( client == NULL )
+ {
+ fprintf(stderr, "Client total not found !\n");
+ return;
+ }
+
+ if( isCreateNewClient == FALSE )
+ {
+ destroySockUdp(sock_client);
+ }
+
+ if( ret <= 0 )
+ {
+ client->status = NET_STATUS_ZOMBIE;
+ return;
+ }
+
+ //printf("add packet >>%s<<\n", listRecvMsg);
+ addList(client->listRecvMsg, strdup(listRecvMsg) );
+}
+
+int selectServerUdpSocket()
+{
+ struct timeval tv;
+ fd_set readfds;
+ fd_set errorfds;
+ int max_fd;
+ int ret;
+ int count;
+
+#ifndef PUBLIC_SERVER
+ tv.tv_sec = 0;
+ tv.tv_usec = 0;
+#endif
+
+#ifdef PUBLIC_SERVER
+ tv.tv_sec = 0;
+ tv.tv_usec = 5000;
+#endif
+
+ FD_ZERO(&readfds);
+ FD_ZERO(&errorfds);
+
+ max_fd = 0;
+ count = 0;
+
+ if( sock_server_udp != NULL )
+ {
+ FD_SET(sock_server_udp->sock, &errorfds);
+ FD_SET(sock_server_udp->sock, &readfds);
+
+ if( sock_server_udp->sock > max_fd )
+ {
+ max_fd = sock_server_udp->sock;
+ }
+ }
+
+ if( sock_server_udp_second != NULL )
+ {
+ FD_SET(sock_server_udp_second->sock, &readfds);
+ FD_SET(sock_server_udp_second->sock, &errorfds);
+
+ if( sock_server_udp_second->sock > max_fd )
+ {
+ max_fd = sock_server_udp_second->sock;
+ }
+ }
+
+ //printf("select..\n");
+
+#ifdef PUBLIC_SERVER
+ if( listClient->count == 0 )
+ {
+ ret = select(max_fd+1, &readfds, (fd_set *)NULL, &errorfds, NULL);
+ setServerTimer();
+ }
+ else
+ {
+ ret = select(max_fd+1, &readfds, (fd_set *)NULL,&errorfds, &tv);
+ }
+#endif
+
+#ifndef PUBLIC_SERVER
+ ret = select(max_fd+1, &readfds, (fd_set *)NULL,&errorfds, &tv);
+#endif
+
+ if( ret < 0 )
+ {
+ //printf("select ret = %d\n", ret);
+ return 0;
+ }
+
+ if( sock_server_udp != NULL )
+ {
+ if( FD_ISSET(sock_server_udp->sock, &readfds) )
+ {
+ eventClientUdpSelect(sock_server_udp);
+ count = 1;
+ }
+
+ if( FD_ISSET(sock_server_udp->sock, &errorfds) )
+ {
+ printf("error\n");
+ }
+ }
+
+ if( sock_server_udp_second != NULL )
+ {
+ if( FD_ISSET(sock_server_udp_second->sock, &readfds) )
+ {
+ eventClientUdpSelect(sock_server_udp_second);
+ count = 1;
+ }
+
+ if( FD_ISSET(sock_server_udp_second->sock, &errorfds) )
+ {
+ printf("error\n");
+ }
+ }
+
+ return count;
+}
+
+#endif
+
+#ifdef SUPPORT_NET_SDL_UDP
+
+static client_t* findSdlUdpClient(sock_sdl_udp_t *sock_sdl_udp)
+{
+ int i;
+ client_t *thisClient;
+
+ for( i = 0 ; i < listClient->count; i++)
+ {
+ thisClient = (client_t *) listClient->list[i];
+
+ if( getSockSdlUdpPort(thisClient->socket_sdl_udp) == getSockSdlUdpPort(sock_sdl_udp) )
+ {
+ return thisClient;
+ }
+ }
+
+ return NULL;
+}
+
+void selectServerSdlUdpSocket()
+{
+ sock_sdl_udp_t *sock_client;
+ client_t *client;
+ char listRecvMsg[STR_PROTO_SIZE];
+ bool_t isCreateNewClient;
+ int ret;
+
+ assert( sock_server_sdl_udp != NULL );
+
+ do{
+ sock_client = newSdlSockUdp();
+ isCreateNewClient = FALSE;
+
+ memset(listRecvMsg, 0, STR_PROTO_SIZE);
+
+ ret = readSdlUdpSocket(sock_server_sdl_udp, sock_client, listRecvMsg, STR_PROTO_SIZE-1);
+
+ if( ret < 0 )
+ {
+ destroySockSdlUdp(sock_client);
+ break;
+ }
+
+ client = findSdlUdpClient(sock_client);
+
+ if( client == NULL )
+ {
+ eventCreateNewSdlUdpClient(sock_client);
+ client = findSdlUdpClient(sock_client);
+ isCreateNewClient = TRUE;
+ }
+
+ if( client == NULL )
+ {
+ fprintf(stderr, "Client total not found !\n");
+ return;
+ }
+
+ if( isCreateNewClient == FALSE )
+ {
+ destroySockSdlUdp(sock_client);
+ }
+
+ if( ret <= 0 )
+ {
+ client->status = NET_STATUS_ZOMBIE;
+ return;
+ }
+
+ addList(client->listRecvMsg, strdup(listRecvMsg) );
+ }while( ret > 0 );
+}
+
+#endif
+
+void eventServer()
+{
+#ifndef PUBLIC_SERVER
+
+ int count;
+
+#ifdef SUPPORT_NET_SDL_UDP
+ selectServerSdlUdpSocket();
+#endif
+
+#ifdef SUPPORT_NET_UNIX_UDP
+ do{
+ count = selectServerUdpSocket();
+ }while( count > 0 );
+#endif
+
+#endif
+
+#ifdef PUBLIC_SERVER
+ selectServerUdpSocket();
+#endif
+
+ eventClientListBuffer();
+ eventTimer(listServerTimer);
+}
+
+static void quitServer()
+{
+ proto_send_end_server(PROTO_SEND_ALL, NULL);
+
+ assert( listClient != NULL );
+ destroyListItem(listClient, destroyClient);
+ destroyTimer(listServerTimer);
+}
+
+#ifdef SUPPORT_NET_UNIX_UDP
+
+void quitUdpServer()
+{
+ quitServer();
+
+ if( sock_server_udp != NULL )
+ {
+ printf("close port %d\n", getSockUdpPort(sock_server_udp));
+ closeUdpSocket(sock_server_udp);
+ }
+
+ if( sock_server_udp_second != NULL )
+ {
+ printf("close port %d\n", getSockUdpPort(sock_server_udp_second));
+ closeUdpSocket(sock_server_udp_second);
+ }
+
+ printf("quit UDP port\n");
+}
+
+#endif
+
+#ifdef SUPPORT_NET_SDL_UDP
+
+void quitSdlUdpServer()
+{
+ quitServer();
+
+ assert( sock_server_sdl_udp != NULL );
+ closeSdlUdpSocket(sock_server_sdl_udp);
+
+ printf("quit UDP port\n");
+}
+
+#endif
diff --git a/src/base/server.h b/src/base/server.h
new file mode 100644
index 0000000..4a946ea
--- /dev/null
+++ b/src/base/server.h
@@ -0,0 +1,93 @@
+
+#ifndef MY_SERVER
+
+#define MY_SERVER
+
+#include <time.h>
+
+#include "base/list.h"
+#include "base/tux.h"
+#include "base/myTimer.h"
+#include "base/protect.h"
+
+#ifndef PUBLIC_SERVER
+#include "client/interface.h"
+#endif
+
+
+#ifdef SUPPORT_NET_SDL_UDP
+
+#include "net_sdl/sdl_udp.h"
+
+#endif
+
+#ifdef SUPPORT_NET_UNIX_UDP
+
+#include "net_unix/udp.h"
+
+#endif
+
+#define SERVER_TIMEOUT 1000
+#define SERVER_TIME_SYNC 1000
+#define SERVER_TIME_PING 1000
+#define SERVER_MAX_CLIENTS 100
+
+
+#define SERVER_INDEX_ROOT_TUX 0
+
+typedef struct client_struct
+{
+#ifdef SUPPORT_NET_UNIX_UDP
+ sock_udp_t *socket_udp;
+#endif
+
+#ifdef SUPPORT_NET_SDL_UDP
+ sock_sdl_udp_t *socket_sdl_udp;
+#endif
+ int status;
+
+ tux_t *tux;
+
+ protect_t *protect;
+
+ list_t *listSendMsg;
+ list_t *listRecvMsg;
+} client_t;
+
+#ifdef PUBLIC_SERVER
+extern int initUdpPublicServer(char *ip4, int port4, char *ip6, int port6);
+#endif
+
+#ifdef SUPPORT_NET_UNIX_UDP
+extern int initUdpServer(char *ip, int port, int proto);
+extern int initUdpServerMultiProto(char *ip4, char *ip6, int port4, int port6);
+extern client_t* newUdpClient(sock_udp_t *sock_udp);
+extern int selectServerUdpSocket();
+extern void quitUdpServer();
+#endif
+
+#ifdef SUPPORT_NET_SDL_UDP
+extern int initSdlUdpServer(int port);
+extern client_t* newSdlUdpClient(sock_sdl_udp_t *sock_udp);
+extern void selectServerSdlUdpSocket();
+extern void quitSdlUdpServer();
+#endif
+
+extern void destroyClient(client_t *p);
+
+extern time_t getUpdateServer();
+extern list_t* getListServerClient();
+extern int getServerMaxClients();
+extern void setServerMaxClients(int n);
+
+extern void sendClient(client_t *p, char *msg);
+extern void protoSendClient(int type, client_t *client, char *msg, int type2, int id);
+
+extern tux_t *getServerTux();
+extern client_t *getClientFromTux(tux_t *tux);
+extern void eventClientListBuffer();
+extern void sendInfoCreateClient(client_t *client);
+extern void eventServer();
+
+#endif
+
diff --git a/src/base/shot.c b/src/base/shot.c
new file mode 100644
index 0000000..e8cdff9
--- /dev/null
+++ b/src/base/shot.c
@@ -0,0 +1,369 @@
+
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+
+#include "base/main.h"
+#include "base/shot.h"
+#include "base/gun.h"
+#include "base/net_multiplayer.h"
+#include "base/proto.h"
+#include "base/idManager.h"
+
+#ifndef PUBLIC_SERVER
+#include "client/image.h"
+#include "client/layer.h"
+#include "screen/screen_world.h"
+#endif
+
+#ifdef PUBLIC_SERVER
+#include "server/publicServer.h"
+#endif
+
+#ifndef PUBLIC_SERVER
+
+static SDL_Surface *g_shot_simple;
+static SDL_Surface *g_shot_lasserX;
+static SDL_Surface *g_shot_lasserY;
+static SDL_Surface *g_shot_bombball;
+
+#endif
+
+static bool_t isShotInit = FALSE;
+
+bool_t isShotInicialized()
+{
+ return isShotInit;
+}
+
+void initShot()
+{
+#ifndef PUBLIC_SERVER
+ assert( isImageInicialized() == TRUE );
+#endif
+
+#ifndef PUBLIC_SERVER
+
+ g_shot_simple = addImageData("shot.png", IMAGE_ALPHA, "shot", IMAGE_GROUP_BASE);
+ g_shot_lasserX = addImageData("lasserX.png", IMAGE_NO_ALPHA, "lasserX", IMAGE_GROUP_BASE);
+ g_shot_lasserY = addImageData("lasserY.png", IMAGE_NO_ALPHA, "lasserY", IMAGE_GROUP_BASE);
+ g_shot_bombball = addImageData("bombball.png", IMAGE_ALPHA, "bombball", IMAGE_GROUP_BASE);
+
+#endif
+
+ isShotInit = TRUE;
+}
+
+shot_t* newShot(int x,int y, int px, int py, int gun, int author_id)
+{
+ shot_t *new;
+ tux_t *author;
+
+ new = malloc( sizeof(shot_t) );
+ memset(new, 0, sizeof(shot_t) );
+
+ new->id = getNewID();
+ new->x = x;
+ new->y = y;
+ new->px = px;
+ new->py = py;
+ new->gun = gun;
+ new->author_id = author_id;
+
+ new->position = POSITION_UNKNOWN;
+
+ author = getObjectFromSpaceWithID(getCurrentArena()->spaceTux, author_id);
+
+ if( author != NULL )
+ {
+ new->position = author->position;
+ }
+
+ new->isCanKillAuthor = FALSE;
+
+ switch( gun )
+ {
+ case GUN_SIMPLE :
+ new->w = GUN_SHOT_WIDTH;
+ new->h = GUN_SHOT_HEIGHT;
+#ifndef PUBLIC_SERVER
+ new->img = g_shot_simple;
+#endif
+ break;
+
+ case GUN_LASSER :
+ switch( author-> position )
+ {
+ case TUX_RIGHT :
+ case TUX_LEFT :
+ new->w = GUN_LASSER_HORIZONTAL;
+ new->h = GUN_SHOT_VERTICAL;
+#ifndef PUBLIC_SERVER
+ new->img = g_shot_lasserX;
+#endif
+ break;
+ case TUX_UP :
+ case TUX_DOWN :
+ new->w = GUN_SHOT_VERTICAL;
+ new->h = GUN_LASSER_HORIZONTAL;
+#ifndef PUBLIC_SERVER
+ new->img = g_shot_lasserY;
+#endif
+ break;
+ }
+ break;
+
+ case GUN_BOMBBALL :
+ new->w = GUN_BOMBBALL_WIDTH;
+ new->h = GUN_BOMBBALL_HEIGHT;
+
+#ifndef PUBLIC_SERVER
+ new->img = g_shot_bombball;
+#endif
+ break;
+
+ default :
+ assert( ! "Premenna weapon ma zlu hodnotu !" );
+ break;
+ }
+
+ return new;
+}
+
+void replaceShotID(shot_t *shot, int id)
+{
+ replaceID(shot->id, id);
+ shot->id = id;
+}
+
+
+void getStatusShot(void *p, int *id, int *x,int *y, int *w, int *h)
+{
+ shot_t *shot;
+
+ shot = p;
+ *id = shot->id;
+ *x = shot->x;
+ *y = shot->y;
+ *w = shot->w;
+ *h = shot->h;
+}
+
+void setStatusShot(void *p, int x, int y, int w, int h)
+{
+ shot_t *shot;
+
+ shot = p;
+ shot->x = x;
+ shot->y = y;
+ shot->w = w;
+ shot->h = h;
+}
+
+#ifndef PUBLIC_SERVER
+
+void drawShot(shot_t *p)
+{
+ assert( p != NULL );
+ addLayer(p->img, p->x, p->y, 0, 0, p->img->w, p->img->h, TUX_LAYER);
+}
+
+void drawListShot(list_t *listShot)
+{
+ shot_t *thisShot;
+ int i;
+
+ assert( listShot != NULL );
+
+ for( i = 0 ; i < listShot->count ; i++ )
+ {
+ thisShot = (shot_t *)listShot->list[i];
+ assert( thisShot != NULL );
+ drawShot(thisShot);
+ }
+}
+
+#endif
+
+static int getRandomCourse(int x, int y)
+{
+ int ret;
+
+ do{
+ switch( random() % 3 )
+ {
+ case 0 :
+ ret = y;
+ break;
+ case 1 :
+ ret = -y;
+ break;
+ case 2 :
+ ret = 0;
+ break;
+ }
+ }while( ret == x );
+
+ return ret;
+}
+
+void boundBombBall(shot_t *shot)
+{
+ if( shot->gun != GUN_BOMBBALL )
+ {
+ return;
+ }
+
+ shot->px = getRandomCourse(shot->px, +10);
+ shot->py = getRandomCourse(shot->py, +10);
+ shot->isCanKillAuthor = 1;
+
+ if( getNetTypeGame() == NET_GAME_TYPE_SERVER )
+ {
+ proto_send_shot_server(PROTO_SEND_ALL, NULL, shot);
+ }
+}
+
+void transformOnlyLasser(shot_t *shot)
+{
+ switch( shot->position )
+ {
+ case TUX_RIGHT :
+ case TUX_LEFT :
+ shot->w = GUN_LASSER_HORIZONTAL;
+ shot->h = GUN_SHOT_VERTICAL;
+#ifndef PUBLIC_SERVER
+ shot->img = g_shot_lasserX;
+#endif
+ break;
+ case TUX_UP :
+ case TUX_DOWN :
+ shot->w = GUN_SHOT_VERTICAL;
+ shot->h = GUN_LASSER_HORIZONTAL;
+#ifndef PUBLIC_SERVER
+ shot->img = g_shot_lasserY;
+#endif
+ break;
+ }
+}
+
+void eventMoveListShot(arena_t *arena)
+{
+ shot_t *thisShot;
+ int new_x, new_y;
+ int i;
+
+ for( i = 0 ; i < arena->spaceShot->list->count ; i++ )
+ {
+ thisShot = (shot_t *) arena->spaceShot->list->list[i];
+ assert( thisShot != NULL );
+
+ new_x = thisShot->x + thisShot->px;
+ new_y = thisShot->y + thisShot->py;
+
+ moveObjectInSpace(getCurrentArena()->spaceShot, thisShot, new_x, new_y);
+
+ if( thisShot->x+thisShot->w < 0 || thisShot->x > arena->w ||
+ thisShot->y+thisShot->h < 0 || thisShot->y > arena->h )
+ {
+ delObjectFromSpaceWithObject(arena->spaceShot,
+ thisShot, destroyShot);
+ i--;
+ continue;
+ }
+ }
+}
+
+static int myAbs(int n)
+{
+ return ( n > 0 ? n : -n );
+}
+
+static int getSppedShot(shot_t *shot)
+{
+ return ( myAbs(shot->px) > myAbs(shot->py) ? myAbs(shot->px) : myAbs(shot->py) );
+}
+
+
+void checkShotIsInTuxScreen(arena_t *arena)
+{
+ int screen_x, screen_y;
+ shot_t *thisShot;
+ tux_t *thisTux;
+ int speed;
+ int i, j;
+
+ if( getNetTypeGame() != NET_GAME_TYPE_SERVER )
+ {
+ return;
+ }
+
+ for( i = 0 ; i < arena->spaceTux->list->count ; i++ )
+ {
+ thisTux = (tux_t *)arena->spaceTux->list->list[i];
+ speed = 25;
+
+ if( thisTux->control != TUX_CONTROL_NET )
+ {
+ continue;
+ }
+
+ getCenterScreen(&screen_x, &screen_y, thisTux->x, thisTux->y);
+
+ listDoEmpty(listHelp);
+ getObjectFromSpace(arena->spaceShot, screen_x-speed, screen_y, speed, WINDOW_SIZE_Y, listHelp);
+
+ for( j = 0 ; j <listHelp->count ; j++ )
+ {
+ thisShot = (shot_t *)listHelp->list[j];
+ client_t *thisClient;
+ thisClient = getClientFromTux(thisTux);
+ proto_send_shot_server(PROTO_SEND_ONE, thisClient, thisShot);
+ }
+
+ listDoEmpty(listHelp);
+ getObjectFromSpace(arena->spaceShot, screen_x+WINDOW_SIZE_X, screen_y, speed, WINDOW_SIZE_Y, listHelp);
+
+ for( j = 0 ; j <listHelp->count ; j++ )
+ {
+ thisShot = (shot_t *)listHelp->list[j];
+ client_t *thisClient;
+ thisClient = getClientFromTux(thisTux);
+ proto_send_shot_server(PROTO_SEND_ONE, thisClient, thisShot);
+ }
+
+ listDoEmpty(listHelp);
+ getObjectFromSpace(arena->spaceShot, screen_x, screen_y-speed, WINDOW_SIZE_X, speed, listHelp);
+
+ for( j = 0 ; j <listHelp->count ; j++ )
+ {
+ thisShot = (shot_t *)listHelp->list[j];
+ client_t *thisClient;
+ thisClient = getClientFromTux(thisTux);
+ proto_send_shot_server(PROTO_SEND_ONE, thisClient, thisShot);
+ }
+
+ listDoEmpty(listHelp);
+ getObjectFromSpace(arena->spaceShot, screen_x, screen_y+WINDOW_SIZE_Y, WINDOW_SIZE_X, speed, listHelp);
+
+ for( j = 0 ; j <listHelp->count ; j++ )
+ {
+ thisShot = (shot_t *)listHelp->list[j];
+ client_t *thisClient;
+ thisClient = getClientFromTux(thisTux);
+ proto_send_shot_server(PROTO_SEND_ONE, thisClient, thisShot);
+ }
+ }
+}
+
+void destroyShot(shot_t *p)
+{
+ assert( p != NULL );
+ delID(p->id);
+ free(p);
+}
+
+void quitShot()
+{
+ isShotInit = FALSE;
+}
diff --git a/src/base/shot.h b/src/base/shot.h
new file mode 100644
index 0000000..db157cb
--- /dev/null
+++ b/src/base/shot.h
@@ -0,0 +1,61 @@
+
+#ifndef SHOT_H
+
+#define SHOT_H
+
+#include "base/main.h"
+#include "base/list.h"
+#include "base/tux.h"
+#include "base/arena.h"
+
+#ifndef PUBLIC_SERVER
+#include "client/interface.h"
+#endif
+
+typedef struct shot_struct
+{
+ int id;
+
+ int x;
+ int y;
+
+ int w;
+ int h;
+
+ int px;
+ int py;
+
+ int position;
+ int gun;
+
+ int author_id;
+ bool_t isCanKillAuthor;
+
+#ifndef PUBLIC_SERVER
+ SDL_Surface *img;
+#endif
+} shot_t;
+
+extern bool_t isShotInicialized();
+extern void initShot();
+extern shot_t* newShot(int x,int y, int px, int py, int gun, int author_id);
+extern shot_t* getShotID(list_t *listShot, int id);
+extern void replaceShotID(shot_t *shot, int id);
+extern void getStatusShot(void *p, int *id, int *x,int *y, int *w, int *h);
+extern void setStatusShot(void *p, int x, int y, int w, int h);
+#ifndef PUBLIC_SERVER
+extern void drawShot(shot_t *p);
+extern void drawListShot(list_t *listShot);
+#endif
+extern int isConflictWithListShot(list_t *listShot, int x, int y, int w, int h);
+extern void eventMoveListShot(arena_t *arena);
+extern void checkShotIsInTuxScreen(arena_t *arena);
+
+extern void boundBombBall(shot_t *shot);
+extern void transformOnlyLasser(shot_t *shot);
+
+extern void destroyShot(shot_t *p);
+extern void quitShot();
+
+#endif
+
diff --git a/src/base/space.c b/src/base/space.c
new file mode 100644
index 0000000..0d3060a
--- /dev/null
+++ b/src/base/space.c
@@ -0,0 +1,600 @@
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+
+#include "main.h"
+#include "list.h"
+#include "space.h"
+
+#define DEBUG_SPACE
+#define ERROR_SUPPORT
+
+#ifdef DEBUG_SPACE
+
+
+typedef struct recv_struct
+{
+ int id;
+ int x, y;
+ int w, h;
+} recv_t;
+
+recv_t* newRecv(int id, int x , int y, int w, int h)
+{
+ recv_t *new;
+
+ new = malloc( sizeof(recv_t) );
+ memset(new, 0, sizeof(recv_t));
+
+ new->id = id;
+ new->x = x;
+ new->y = y;
+ new->w = w;
+ new->h = h;
+
+ return new;
+}
+
+void getStatus(void *p, int *id, int *x, int *y, int *w, int *h)
+{
+ recv_t *recv;
+
+ recv = p;
+
+ *id = recv->id;
+ *x = recv->x;
+ *y = recv->y;
+ *w = recv->w;
+ *h = recv->h;
+}
+
+void setStatus(void *p, int x, int y, int w, int h)
+{
+ recv_t *recv;
+
+ recv = p;
+
+ recv->x = x;
+ recv->y = y;
+ recv->w = w;
+ recv->h = h;
+ recv->x = x;
+}
+
+void destroyRecv(recv_t *p)
+{
+ free(p);
+}
+
+#endif
+
+static int my_conflictSpace(int x1,int y1,int w1,int h1,int x2,int y2,int w2,int h2)
+{
+ return (x1<x2+w2 && x2<x1+w1 && y1<y2+h2 && y2<y1+h1);
+}
+
+space_t *newSpace(int w, int h, int segW, int segH,
+ void (*getStatus)(void *p, int *id, int *x, int *y, int *w, int *h),
+ void (*setStatus)(void *p, int x, int y, int w, int h))
+{
+ space_t *new;
+ int i, j;
+
+ new = malloc( sizeof(space_t) );
+ memset(new, 0, sizeof(space_t));
+
+ new->w = w / segW + 1;
+ new->h = h / segH + 1;
+ new->segW = segW;
+ new->segH = segH;
+ new->getStatus = getStatus;
+ new->setStatus = setStatus;
+ new->list = newList();
+
+ new->area = malloc( new->w * sizeof(list_t **) );
+
+ for( i = 0 ; i < new->w ; i++ )
+ {
+ new->area[i] = malloc( new->h * sizeof(list_t *) );
+ }
+
+ for( i = 0 ; i < new->h ; i++ )
+ {
+ for( j = 0 ; j < new->w ; j++ )
+ {
+ new->area[j][i] = newList();
+ }
+ }
+
+ return new;
+}
+
+static void getSegment(space_t *p, int x, int y, int w, int h,
+ int *segX, int *segY, int *segW, int *segH)
+{
+ *segX = x / p->segW;
+ *segY = y / p->segH;
+ *segW = ( (x+w) / p->segW + 1 ) - *segX;
+ *segH = ( (y+h) / p->segH + 1 ) - *segY;
+}
+
+#ifdef ERROR_SUPPORT
+
+void printListID(space_t *space)
+{
+ int i;
+
+ for( i = 0 ; i < space->list->count ; i++ )
+ {
+ int id, x, y, w, h;
+
+ space->getStatus(space->list->list[i], &id, &x, &y, &w, &h);
+ printf("%d\n", id);
+ }
+
+ putchar('\n');
+}
+
+static void checkList(space_t *space)
+{
+ int id, x, y, w, h;
+ int thisId;
+ int i;
+
+ if( space->list->count == 0 )
+ {
+ printf("nothing\n");
+ return;
+ }
+
+ space->getStatus(space->list->list[0], &thisId, &x, &y, &w, &h);
+
+ for( i = 1 ; i < space->list->count ; i++ )
+ {
+ space->getStatus(space->list->list[i], &id, &x, &y, &w, &h);
+
+ if( id <= thisId )
+ {
+ printListID(space);
+ assert( ! "error" );
+ }
+
+ thisId = id;
+ }
+}
+
+static void addToListOnTheBaseIndex(space_t *space, void *p)
+{
+ int id, point_id, inc_point_id;
+ int x, y, w, h;
+ int len;
+ int min, max;
+ int point;
+
+
+ len = space->list->count;
+
+ space->getStatus(p, &id, &x, &y, &w, &h);
+/*
+ printf("addToListOnTheBaseIndex (%d)\n", id);
+ printListID(space);
+ assert( id >= 0 );
+*/
+ if( len == 0 )
+ {
+ //printf("OK first\n");
+ addList(space->list, p);
+ return;
+ }
+
+ if( len == 1 )
+ {
+ space->getStatus(space->list->list[0], &point_id, &x, &y, &w, &h);
+
+ if( id > point_id )
+ {
+ addList(space->list, p);
+ }
+
+ if( id < point_id )
+ {
+ insList(space->list, 0, p);
+ }
+
+ //printf("OK\n");
+
+ return;
+ }
+
+ min = 0;
+ max = len-1;
+/*
+ if( max < 0 )
+ {
+ max = 0;
+ }
+*/
+ for(;;)
+ {
+ point = min + ( max - min ) / 2;
+/*
+ space->getStatus(space->list->list[min], &id_min, &x, &y, &w, &h);
+ space->getStatus(space->list->list[max], &id_max, &x, &y, &w, &h);
+*/
+ //printf("min = %d max = %d point = %d len = %d id = %d\n", min, max, point, len, id);
+
+ if( max < 0 )
+ {
+ //printf("OK first\n");
+ insList(space->list, 0, p);
+ //checkList(space);
+ return;
+ }
+
+ if( point+1 >= len /*|| min >= len*/ )
+ {
+ addList(space->list, p);
+ //printf("OK height\n");
+ //checkList(space);
+ return;
+ }
+
+ space->getStatus(space->list->list[point], &point_id, &x, &y, &w, &h);
+ space->getStatus(space->list->list[point+1], &inc_point_id, &x, &y, &w, &h);
+/*
+ if( min == max )
+ {
+ //printf("OK\n");
+ insList(space->list, min, p);
+ checkList(space);
+ return;
+ }
+*/
+ if( point_id < id && id < inc_point_id )
+ {
+ //printf("OK\n");
+ insList(space->list, point+1, p);
+ //checkList(space);
+ return;
+ }
+
+ if( id > inc_point_id )
+ {
+ min = point + 1;
+ continue;
+ }
+
+ if( id < point_id )
+ {
+ max = point - 1;
+ continue;
+ }
+ }
+}
+
+#endif
+
+void addObjectToSpace(space_t *p, void *item)
+{
+ int segX, segY, segW, segH;
+ int id, x, y, w, h;
+ int i, j;
+
+ p->getStatus(item, &id, &x, &y, &w, &h);
+ getSegment(p, x, y, w, h, &segX, &segY, &segW, &segH);
+
+ for( i = segY ; i < segY + segH ; i++ )
+ {
+ for( j = segX ; j < segX + segW ; j++ )
+ {
+ addList(p->area[j][i], item);
+ }
+ }
+
+#ifdef ERROR_SUPPORT
+ addToListOnTheBaseIndex(p, item);
+#endif
+
+#ifndef ERROR_SUPPORT
+ addList(p->list, item);
+#endif
+}
+
+void getObjectFromSpace(space_t *p, int x, int y, int w, int h, list_t *list)
+{
+ int segX, segY, segW, segH;
+ int id, this_x, this_y, this_w, this_h;
+ int i, j, k;
+
+ getSegment(p, x, y, w, h, &segX, &segY, &segW, &segH);
+
+ for( i = segY ; i < segY + segH ; i++ )
+ {
+ for( j = segX ; j < segX + segW ; j++ )
+ {
+ void *this;
+
+ for( k = 0 ; k < p->area[j][i]->count ; k++ )
+ {
+ this = p->area[j][i]->list[k];
+ p->getStatus(this, &id, &this_x, &this_y, &this_w, &this_h);
+
+ if( my_conflictSpace(x, y, w, h, this_x, this_y, this_w, this_h) &&
+ searchListItem(list, this) == -1 )
+ {
+ addList(list, this);
+ }
+ }
+ }
+ }
+}
+
+int searchObjectInSpace(space_t *space, int id)
+{
+ int point_id;
+ int x, y, w, h;
+ int len;
+ int min, max;
+ int point;
+
+/*
+ printf("getObjectFromSpaceWithID %d\n", id);
+ printListID(space);
+*/
+ len = space->list->count;
+
+ min = 0;
+ max = len-1;
+
+ for(;;)
+ {
+ point = min + ( max - min ) / 2;
+
+ //printf("min = %d max = %d point = %d len = %d id = %d\n", min, max, point, len, id);
+
+ if( max < 0 || point >= len || max < min )
+ {
+ return -1;
+ }
+
+ space->getStatus(space->list->list[point], &point_id, &x, &y, &w, &h);
+
+ if( min == max )
+ {
+ space->getStatus(space->list->list[min], &point_id, &x, &y, &w, &h);
+ }
+
+ if( point_id == id )
+ {
+ return point;
+ }
+
+ if( id > point_id )
+ {
+ min = point + 1;
+ continue;
+ }
+
+ if( id < point_id )
+ {
+ max = point - 1;
+ continue;
+ }
+ }
+}
+
+void* getObjectFromSpaceWithID(space_t *space, int id)
+{
+ int index;
+
+ index = searchObjectInSpace(space, id);
+
+ return ( index != -1 ? space->list->list[index] : NULL );
+}
+
+int isConflictWithObjectFromSpace(space_t *p, int x, int y, int w, int h)
+{
+ int segX, segY, segW, segH;
+ int id, this_x, this_y, this_w, this_h;
+ int i, j, k;
+
+ getSegment(p, x, y, w, h, &segX, &segY, &segW, &segH);
+
+ for( i = segY ; i < segY + segH ; i++ )
+ {
+ for( j = segX ; j < segX + segW ; j++ )
+ {
+ void *this;
+
+ for( k = 0 ; k < p->area[j][i]->count ; k++ )
+ {
+ this = p->area[j][i]->list[k];
+ p->getStatus(this, &id, &this_x, &this_y, &this_w, &this_h);
+
+ if( my_conflictSpace(x, y, w, h, this_x, this_y, this_w, this_h) )
+ {
+ return 1;
+ }
+ }
+ }
+ }
+
+ return 0;
+}
+
+int isConflictWithObjectFromSpaceBut(space_t *p, int x, int y, int w, int h, void *but)
+{
+ int segX, segY, segW, segH;
+ int id, this_x, this_y, this_w, this_h;
+ int i, j, k;
+
+ getSegment(p, x, y, w, h, &segX, &segY, &segW, &segH);
+
+ for( i = segY ; i < segY + segH ; i++ )
+ {
+ for( j = segX ; j < segX + segW ; j++ )
+ {
+ void *this;
+
+ for( k = 0 ; k < p->area[j][i]->count ; k++ )
+ {
+ this = p->area[j][i]->list[k];
+
+ if( this == but )
+ {
+ continue;
+ }
+
+ p->getStatus(this, &id, &this_x, &this_y, &this_w, &this_h);
+
+ if( my_conflictSpace(x, y, w, h, this_x, this_y, this_w, this_h) )
+ {
+ return 1;
+ }
+ }
+ }
+ }
+
+ return 0;
+}
+
+void delObjectFromSpace(space_t *p, void *item)
+{
+ int segX, segY, segW, segH;
+ int id, x, y, w, h;
+ int index;
+ int i, j;
+
+ p->getStatus(item, &id, &x, &y, &w, &h);
+ getSegment(p, x, y, w, h, &segX, &segY, &segW, &segH);
+
+ for( i = segY ; i < segY + segH ; i++ )
+ {
+ for( j = segX ; j < segX + segW ; j++ )
+ {
+ index = searchListItem(p->area[j][i], item);
+ assert( index != -1 );
+ delList(p->area[j][i], index);
+ }
+ }
+
+ index = searchObjectInSpace(p, id);
+ assert( index != -1 );
+ delList(p->list, index);
+}
+
+void delObjectFromSpaceWithObject(space_t *p, void *item, void *f)
+{
+ void (*fce)(void *param);
+
+ fce = f;
+
+ delObjectFromSpace(p, item);
+ fce(item);
+}
+
+void moveObjectInSpace(space_t *p, void *item, int move_x, int move_y)
+{
+ int old_segX, old_segY, old_segW, old_segH;
+ int new_segX, new_segY, new_segW, new_segH;
+ int id, x, y, w, h;
+
+ p->getStatus(item, &id, &x, &y, &w, &h);
+ getSegment(p, x, y, w, h, &old_segX, &old_segY, &old_segW, &old_segH);
+ getSegment(p, move_x, move_y, w, h, &new_segX, &new_segY, &new_segW, &new_segH);
+/*
+ printf("%d %d %d %d -> %d %d %d %d \n",
+ old_segX, old_segY, old_segW, old_segH,
+ new_segX, new_segY, new_segW, new_segH);
+*/
+ if( old_segX != new_segX || old_segY != new_segY ||
+ old_segW != new_segW || old_segH != new_segH )
+ {
+ delObjectFromSpace(p, item);
+ p->setStatus(item, move_x, move_y, w, h);
+ addObjectToSpace(p, item);
+ return;
+ }
+
+ p->setStatus(item, move_x, move_y, w, h);
+}
+
+void printSpace(space_t *p)
+{
+ int i, j;
+
+ printf("print space : \n");
+
+ for( i = 0 ; i < p->h ; i++ )
+ {
+ for( j = 0 ; j < p->w ; j++ )
+ {
+ printf("%3d ", p->area[j][i]->count);
+ }
+
+ putchar('\n');
+ }
+}
+
+void destroySpace(space_t *p)
+{
+ int j, i;
+
+ destroyList(p->list);
+
+ for( i = 0 ; i < p->h ; i++ )
+ {
+ for( j = 0 ; j < p->w ; j++ )
+ {
+ destroyList(p->area[j][i]);
+ }
+ }
+
+ for( i = 0 ; i < p->w ; i++ )
+ {
+ free(p->area[i]);
+ }
+
+ free(p->area);
+ free(p);
+}
+
+void destroySpaceWithObject(space_t *p, void *f)
+{
+ void (*fce)(void *param);
+ int i;
+
+ fce = f;
+
+ for( i = 0 ; i < p->list->count ; i++ )
+ fce(p->list->list[i]);
+
+ destroySpace(p);
+}
+
+#ifdef DEBUG_SPACE
+
+void test_space()
+{/*
+ space_t *space;
+ recv_t *recv;
+
+ space = newSpace(5000, 2500, 320, 240, getStatus, setStatus);
+
+ addObjectToSpace(space, newRecv(5, 0, 0, 1, 1) );
+ addObjectToSpace(space, newRecv(7, 0, 0, 1, 1) );
+ addObjectToSpace(space, newRecv(8, 0, 0, 1, 1) );
+ addObjectToSpace(space, newRecv(9, 0, 0, 1, 1) );
+ addObjectToSpace(space, newRecv(6, 0, 0, 1, 1) );
+*/
+/*
+ recv = getObjectFromSpaceWithID(space, 6);
+ if( recv != NULL )printf("id = %d\n", recv->id);
+*/
+// printListID(space);
+}
+
+#endif
+
diff --git a/src/base/space.h b/src/base/space.h
new file mode 100644
index 0000000..de31768
--- /dev/null
+++ b/src/base/space.h
@@ -0,0 +1,38 @@
+
+#ifndef SPACE_H
+
+#define SPACE_H
+
+#include "main.h"
+#include "list.h"
+
+typedef struct space_struct
+{
+ int w;
+ int h;
+ int segW;
+ int segH;
+ list_t ***area;
+ list_t *list;
+ void (*getStatus)(void *p, int *id, int *x, int *y, int *w, int *h);
+ void (*setStatus)(void *p, int x, int y, int w, int h);
+} space_t;
+
+extern space_t *newSpace(int w, int h, int segW, int segH,
+ void (*getStatus)(void *p, int *id, int *x, int *y, int *w, int *h),
+ void (*setStatus)(void *p, int x, int y, int w, int h));
+
+extern void addObjectToSpace(space_t *p, void *item);
+extern void getObjectFromSpace(space_t *p, int x, int y, int w, int h, list_t *list);
+extern void* getObjectFromSpaceWithID(space_t *p, int id);
+extern int isConflictWithObjectFromSpace(space_t *p, int x, int y, int w, int h);
+extern int isConflictWithObjectFromSpaceBut(space_t *p, int x, int y, int w, int h, void *but);
+extern void delObjectFromSpace(space_t *p, void *item);
+extern void delObjectFromSpaceWithObject(space_t *p, void *item, void *f);
+extern void moveObjectInSpace(space_t *p, void *item, int move_x, int move_y);
+extern void printSpace(space_t *p);
+extern void destroySpace(space_t *p);
+extern void destroySpaceWithObject(space_t *p, void *f);
+
+#endif
+
diff --git a/src/base/storage.c b/src/base/storage.c
new file mode 100644
index 0000000..e7afa45
--- /dev/null
+++ b/src/base/storage.c
@@ -0,0 +1,138 @@
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+
+#include "main.h"
+#include "list.h"
+
+typedef struct struct_storage_item
+{
+ char *name;
+ char *group;
+ void *data;
+} storage_item_t;
+
+list_t* newStorage()
+{
+ return newList();
+}
+
+static storage_item_t* newStorageItem(char *group, char *name, void *data)
+{
+ storage_item_t *new;
+
+ assert( name != NULL );
+ assert( group != NULL );
+ assert( data != NULL );
+
+ new = malloc( sizeof(storage_item_t) );
+ new->name = strdup(name);
+ new->group = strdup(group);
+ new->data = data;
+
+ return new;
+}
+
+static void destroyStorageItem(storage_item_t *p, void *f)
+{
+ void(*fce)(void *);
+
+ assert( p != NULL );
+ assert( f != NULL );
+
+ fce = f;
+
+ fce(p->data);
+ free(p->name);
+ free(p->group);
+ free(p);
+}
+
+void addItemToStorage(list_t *list, char *group, char *name, void *data)
+{
+ addList(list, newStorageItem(group, name, data) );
+}
+
+void* getItemFromStorage(list_t *list, char *group, char *name)
+{
+ storage_item_t *this;
+ int i;
+
+ assert( group != NULL );
+ assert( name != NULL );
+
+ for(i = 0 ; i < list->count; i++)
+ {
+ this = (storage_item_t *) list->list[i];
+
+ if( strcmp(group, this->group) == 0 && strcmp(name, this->name) == 0 )
+ {
+ return this->data;
+ }
+ }
+
+ printf("%s %s not found in storage !!!\n", group, name);
+ return NULL;
+}
+
+void delItemFromStorage(list_t *list, char *group, char *name, void *f)
+{
+ storage_item_t *this;
+ int i;
+
+ assert( group != NULL );
+ assert( name != NULL );
+
+ for(i = 0 ; i < list->count; i++)
+ {
+ this = (storage_item_t *) list->list[i];
+
+ if( strcmp(group, this->group) == 0 && strcmp(name, this->name) == 0 )
+ {
+ destroyStorageItem(this, f);
+ delList(list, i);
+ return;
+ }
+ }
+
+ return;
+}
+
+void delAllItemFromStorage(list_t *list, char *group, void *f)
+{
+ storage_item_t *this;
+ int i;
+
+ assert( group != NULL );
+
+ for(i = 0 ; i < list->count; i++)
+ {
+ this = (storage_item_t *) list->list[i];
+
+ if( strcmp(group, this->group) == 0 )
+ {
+ destroyStorageItem(this, f);
+ delList(list, i);
+ i--;
+ }
+ }
+}
+
+void destroyStorage(list_t *p, void *f)
+{
+ storage_item_t *this;
+ int i;
+
+ assert( p != NULL );
+ assert( f != NULL );
+
+ for( i = 0 ; i < p->count ; i++ )
+ {
+ this = (storage_item_t *)p->list[i];
+ destroyStorageItem(this, f);
+ }
+
+ destroyList(p);
+}
diff --git a/src/base/storage.h b/src/base/storage.h
new file mode 100644
index 0000000..af72ba2
--- /dev/null
+++ b/src/base/storage.h
@@ -0,0 +1,16 @@
+
+#ifndef STORAGE_H
+
+#define STORAGE_H
+
+#include "base/main.h"
+#include "base/list.h"
+
+extern list_t* newStorage();
+extern void addItemToStorage(list_t *list, char *group, char *name, void *data);
+extern void* getItemFromStorage(list_t *list, char *group, char *name);
+extern void delItemFromStorage(list_t *list, char *group, char *name, void *f);
+extern void delAllItemFromStorage(list_t *list, char *group, void *f);
+extern void destroyStorage(list_t *p, void *f);
+
+#endif
diff --git a/src/base/string_length.h b/src/base/string_length.h
new file mode 100644
index 0000000..c453e60
--- /dev/null
+++ b/src/base/string_length.h
@@ -0,0 +1,16 @@
+
+#ifndef STR_LENGTH_H
+
+#define STR_LENGTH_H
+
+#include "base/main.h"
+
+#define STR_SIZE 128
+#define STR_PROTO_SIZE 128
+#define STR_NUM_SIZE 8
+#define STR_NAME_SIZE 32
+#define STR_PATH_SIZE 4096
+#define STR_FILE_NAME_SIZE 256
+#define STR_IP_SIZE 64
+
+#endif
diff --git a/src/base/textFile.c b/src/base/textFile.c
new file mode 100755
index 0000000..5c8c95d
--- /dev/null
+++ b/src/base/textFile.c
@@ -0,0 +1,163 @@
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/stat.h>
+#include <assert.h>
+#include <unistd.h>
+
+#include "base/main.h"
+#include "base/textFile.h"
+
+textFile_t* newTextFile(char *s)
+{
+ textFile_t *new;
+ char path[STR_PATH_SIZE];
+
+ assert( s != NULL );
+
+ if( s[0] == '/' )
+ {
+ strcpy(path, s);
+ }
+ else
+ {
+ getcwd(path, STR_PATH_SIZE);
+ strcat(path, "/");
+ strcat(path, s);
+ }
+
+ new = malloc(sizeof(textFile_t));
+ new->file = strdup(path);
+ new->text = newList();
+
+ return new;
+}
+
+static void createLine(list_t *list, char *p, int len)
+{
+ char *line;
+ char *begin_line;
+ char *end_line;
+ int length_line = 0;
+
+ assert( list != NULL );
+ assert( p != NULL );
+ assert( len >= 0 );
+
+ begin_line = p;
+
+ do{
+ end_line = memchr( begin_line, '\n', len);
+ if( end_line == NULL )break;
+
+ length_line = (int ) (end_line - ( begin_line ) );
+
+ line = malloc( (length_line+1) * sizeof(char) );
+ memset(line, 0, (length_line+1) * sizeof(char) );
+ strncpy(line, begin_line, length_line);
+
+ addList(list, line);
+ len -= (length_line+1);
+
+ begin_line = end_line+1;
+
+ }while( begin_line != NULL );
+}
+
+/*
+ * Nacita subor *s a vrati ho f
+ * formatovany v type textFile_t*
+ */
+textFile_t* loadTextFile(char *s)
+{
+ FILE *file;
+ textFile_t *ret;
+ char *p;
+ int file_length = 0;
+ struct stat buf;
+
+ assert( s != NULL );
+
+ if( lstat(s, &buf) < 0 )
+ {
+ fprintf(stderr, "CHYBA: nemozem ziskat status suboru %s!\n", s);
+ return NULL;
+ }
+
+ file_length = buf.st_size;
+ if( (file = fopen(s, "rt")) == NULL )
+ {
+ fprintf(stderr, "CHYBA: nemozem otvorit subor %s pre citanie\n", s);
+ return NULL;
+ }
+
+ p = malloc(file_length * sizeof(char));
+
+ if( fread(p, file_length * sizeof(char), 1, file) != 1 )
+ {
+ fprintf(stderr, "CHYBA: nemozem nacitat udaje zo suboru %s\n",s);
+ fclose(file);
+ return NULL;
+ }
+
+ fclose(file);
+
+ ret = newTextFile(s);
+ createLine(ret->text, p, file_length);
+
+ free(p);
+
+ return ret;
+}
+
+/*
+ * Zobrazi text ulozeny v *p
+ * do stdout
+ */
+void printTextFile(textFile_t *p)
+{
+ int i;
+
+ assert( p != NULL );
+
+ printf("file : %s\n\n", p->file);
+
+ for(i = 0; i < p->text->count; i++)
+ {
+ printf("%3d >> %s\n", i, (char *)p->text->list[i]);
+ }
+}
+
+void saveTextFile(textFile_t *p)
+{
+ int i;
+ FILE *file;
+
+ assert( p != NULL );
+
+ file = fopen(p->file, "wt");
+
+ for(i = 0; i < p->text->count; i++)
+ {
+ fprintf(file, "%s\n", (char *)p->text->list[i]);
+ }
+
+ fclose(file);
+}
+
+/*
+ * Uvolni text ulozeny v type textFile_t*
+ * z pamate.
+ */
+void destroyTextFile(textFile_t *p)
+{
+ assert( p != NULL );
+
+ free(p->file);
+ destroyListItem(p->text, free);
+ free(p);
+}
+
+
+
diff --git a/src/base/textFile.h b/src/base/textFile.h
new file mode 100755
index 0000000..ea15b4d
--- /dev/null
+++ b/src/base/textFile.h
@@ -0,0 +1,21 @@
+
+#ifndef TEXTFILE_H
+
+#define TEXTFILE_H
+
+#include "base/list.h"
+
+typedef struct str_textFile_t
+{
+ char *file;
+ list_t *text;
+} textFile_t;
+
+extern textFile_t* newTextFile(char *s);
+extern textFile_t* loadTextFile(char *s);
+extern void printTextFile(textFile_t *p);
+extern void saveTextFile(textFile_t *p);
+extern void destroyTextFile(textFile_t *p);
+
+
+#endif
diff --git a/src/base/tux.c b/src/base/tux.c
new file mode 100644
index 0000000..0c0717c
--- /dev/null
+++ b/src/base/tux.c
@@ -0,0 +1,803 @@
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+
+#include "base/main.h"
+#include "base/tux.h"
+#include "base/arena.h"
+#include "base/shot.h"
+#include "base/gun.h"
+#include "base/item.h"
+#include "base/arena.h"
+#include "base/myTimer.h"
+#include "base/net_multiplayer.h"
+#include "base/proto.h"
+#include "base/modules.h"
+#include "base/idManager.h"
+
+#ifndef PUBLIC_SERVER
+#include "client/image.h"
+#include "client/layer.h"
+#include "client/term.h"
+
+#include "audio/sound.h"
+
+#include "screen/screen_world.h"
+#endif
+
+#ifdef PUBLIC_SERVER
+#include "server/publicServer.h"
+#endif
+
+#ifndef PUBLIC_SERVER
+
+static SDL_Surface *g_tux_up;
+static SDL_Surface *g_tux_right;
+static SDL_Surface *g_tux_left;
+static SDL_Surface *g_tux_down;
+static SDL_Surface *g_cross;
+
+#endif
+
+static bool_t isTuxInit = FALSE;
+
+bool_t isTuxInicialized()
+{
+ return isTuxInit;
+}
+
+void initTux()
+{
+#ifndef PUBLIC_SERVER
+ assert( isImageInicialized() == TRUE );
+#endif
+
+#ifndef PUBLIC_SERVER
+ g_tux_up = addImageData("tux8.png", IMAGE_ALPHA, "tux8", IMAGE_GROUP_BASE);
+ g_tux_right = addImageData("tux6.png", IMAGE_ALPHA, "tux6", IMAGE_GROUP_BASE);
+ g_tux_left = addImageData("tux4.png", IMAGE_ALPHA, "tux4", IMAGE_GROUP_BASE);
+ g_tux_down = addImageData("tux2.png", IMAGE_ALPHA, "tux2", IMAGE_GROUP_BASE);
+ g_cross = addImageData("cross.png", IMAGE_ALPHA, "cross", IMAGE_GROUP_BASE);
+#endif
+
+ isTuxInit = TRUE;
+}
+
+tux_t* newTux()
+{
+ int x, y;
+ tux_t *new;
+
+ new = malloc( sizeof(tux_t) );
+ assert( new != NULL );
+
+ memset(new, 0, sizeof(tux_t) );
+
+ new->id = getNewID();
+ new->status = TUX_STATUS_ALIVE;
+ new->control = TUX_CONTROL_NONE;
+
+ findFreeSpace(getCurrentArena(), &x, &y, TUX_WIDTH, TUX_HEIGHT);
+ setTuxProportion(new, x, y);
+
+ new->position = TUX_DOWN;
+ new->gun = GUN_SIMPLE;
+ new->shot[ new->gun ] = GUN_MAX_SHOT;
+
+ sprintf(new->name, "no_name_id_%d", new->id);
+ new->score = 0;
+ new->frame = 0;
+
+ new->bonus = BONUS_NONE;
+ new->bonus_time = 0;
+
+ new->isCanShot = TRUE;
+ new->isCanSwitchGun = TRUE;
+
+ new->client = NULL;
+
+ return new;
+}
+
+bool_t isTuxAnyGun(tux_t *tux)
+{
+ int i;
+
+ for( i = 0 ; i < GUN_COUNT ; i++ )
+ {
+ if( tux->shot[i] > 0 )
+ {
+ return TRUE;
+ }
+ }
+
+ return FALSE;
+}
+
+void getCourse(int n, int *x, int *y)
+{
+ assert( x != NULL );
+ assert( y != NULL );
+
+ switch( n )
+ {
+ case TUX_UP :
+ *x = 0;
+ *y = -1;
+ break;
+
+ case TUX_LEFT :
+ *x = -1;
+ *y = 0;
+ break;
+
+ case TUX_RIGHT :
+ *x = +1;
+ *y = 0;
+ break;
+
+ case TUX_DOWN :
+ *x = 0;
+ *y = +1;
+ break;
+
+ default :
+ assert( ! "premenna n ma zlu hodnotu !" );
+ break;
+ }
+}
+
+#ifndef PUBLIC_SERVER
+
+void drawTux(tux_t *tux)
+{
+ SDL_Surface *g_image = NULL;
+
+ assert( tux != NULL );
+
+ if( tux->bonus == BONUS_HIDDEN &&
+ getNetTypeGame() != NET_GAME_TYPE_NONE &&
+ tux->control == TUX_CONTROL_NET )
+ {
+ return;
+ }
+
+ switch( tux->position )
+ {
+ case TUX_UP :
+ g_image = g_tux_up;
+ break;
+
+ case TUX_LEFT :
+ g_image = g_tux_left;
+ break;
+
+ case TUX_RIGHT :
+ g_image = g_tux_right;
+ break;
+
+ case TUX_DOWN :
+ g_image = g_tux_down;
+ break;
+
+ default :
+ assert( ! "premenna p->control ma zlu hodnotu !" );
+ break;
+ }
+
+ if( tux->status == TUX_STATUS_DEAD )
+ {
+ g_image = g_cross;
+
+ addLayer(g_cross,
+ tux->x - g_cross->w / 2,
+ ( tux->y + g_cross->h / 2 ) - g_cross->h,
+ 0, 0,
+ g_cross->w, g_cross->h, TUX_LAYER);
+
+ return;
+ }
+
+ addLayer(g_image,
+ tux->x - TUX_IMG_WIDTH / 2,
+ ( tux->y + TUX_HEIGHT / 2 ) - TUX_IMG_HEIGHT,
+ (tux->frame/TUX_KEY) * TUX_IMG_WIDTH, 0,
+ TUX_IMG_WIDTH, TUX_IMG_HEIGHT, TUX_LAYER);
+}
+
+void drawListTux(list_t *listTux)
+{
+ tux_t *thisTux;
+ int i;
+
+ assert( listTux != NULL );
+
+ for( i = 0 ; i < listTux->count ; i++ )
+ {
+ thisTux = (tux_t *)listTux->list[i];
+ assert( thisTux != NULL );
+ drawTux(thisTux);
+ }
+}
+
+#endif
+
+void replaceTuxID(tux_t *tux, int id)
+{
+ replaceID(tux->id, id);
+ tux->id = id;
+}
+
+int isTuxSeesTux(tux_t *tux, tux_t *thisTux)
+{
+ int tux_x, tux_y, tux_w, tux_h;
+ int thisTux_x, thisTux_y, thisTux_w, thisTux_h;
+ int screen_x, screen_y;
+
+ getTuxProportion(tux, &tux_x, &tux_y, &tux_w, &tux_h);
+ getTuxProportion(thisTux, &thisTux_x, &thisTux_y, &thisTux_w, &thisTux_h);
+
+ getCenterScreen(&screen_x, &screen_y, tux->x, tux->y);
+
+ return conflictSpace(screen_x-WINDOW_SIZE_X/4, screen_y-WINDOW_SIZE_Y/4,
+ WINDOW_SIZE_X*1.25, WINDOW_SIZE_Y*1.25, thisTux_x, thisTux_y, thisTux_w, thisTux_h);
+}
+
+static void timer_spawnTux(void *p)
+{
+ tux_t *tux;
+ arena_t *arena;
+ int x, y;
+ int id;
+
+ id = * ((int *)p);
+ free(p);
+
+ arena = getCurrentArena();
+ tux = getObjectFromSpaceWithID(arena->spaceTux, id);
+
+ if( tux == NULL )return;
+
+ tux->status = TUX_STATUS_ALIVE;
+ findFreeSpace(getCurrentArena(), &x, &y, TUX_WIDTH, TUX_HEIGHT);
+ moveObjectInSpace(getCurrentArena()->spaceTux, tux, x, y);
+ tux->gun = GUN_SIMPLE;
+
+ addNewItem(arena->spaceItem, ID_UNKNOWN);
+
+ if( getNetTypeGame() == NET_GAME_TYPE_SERVER )
+ {
+ proto_send_newtux_server(PROTO_SEND_ALL, NULL, tux);
+ }
+}
+
+static void timer_tuxCanShot(void *p)
+{
+ tux_t *tux;
+ int id;
+
+ id = * ((int *)p);
+ free(p);
+
+ tux = getObjectFromSpaceWithID(getCurrentArena()->spaceTux, id);
+
+ if( tux == NULL )return;
+
+ tux->isCanShot = TRUE;
+}
+
+static void timer_tuxCanSwitchGun(void *p)
+{
+ tux_t *tux;
+ int id;
+
+ id = * ((int *)p);
+ free(p);
+
+ tux = getObjectFromSpaceWithID(getCurrentArena()->spaceTux, id);
+
+ if( tux == NULL )return;
+
+ tux->isCanSwitchGun = TRUE;
+}
+
+void eventTuxIsDead(tux_t *tux)
+{
+#ifndef PUBLIC_SERVER
+ char msg[STR_SIZE];
+#endif
+
+ if( tux->status == TUX_STATUS_DEAD )
+ {
+ return;
+ }
+
+#ifndef PUBLIC_SERVER
+ sprintf(msg, "tux with id %d is dead\n", tux->id);
+#ifndef NO_SOUND
+ playSound("dead", SOUND_GROUP_BASE);
+#endif
+ appendTextInTerm(msg);
+#endif
+
+ tux->status = TUX_STATUS_DEAD;
+ memset(tux->shot, 0, sizeof(int) * GUN_COUNT);
+ tux->gun = GUN_SIMPLE;
+ tux->shot[ tux->gun ] = GUN_MAX_SHOT;
+
+ tux->bonus = BONUS_NONE;
+ tux->bonus_time = 0;
+ tux->pickup_time = 0;
+
+ tux->isCanShot = TRUE;
+ tux->isCanSwitchGun = TRUE;
+
+ if( getNetTypeGame() != NET_GAME_TYPE_CLIENT )
+ {
+ addTaskToTimer(getCurrentArena()->listTimer, TIMER_ONE, timer_spawnTux, newInt(tux->id), TUX_TIME_SPAWN );
+ }
+
+ if( getNetTypeGame() == NET_GAME_TYPE_SERVER )
+ {
+ proto_send_kill_server(PROTO_SEND_ALL, NULL, tux);
+ }
+}
+
+static void eventTuxIsDeadWIthShot(tux_t *tux, shot_t *shot)
+{
+ if( shot->author_id != tux->id )
+ {
+ tux_t *author;
+
+ author = getObjectFromSpaceWithID(getCurrentArena()->spaceTux, shot->author_id);
+
+ if( author != NULL )
+ {
+ author->score++;
+
+ if( getNetTypeGame() == NET_GAME_TYPE_SERVER )
+ {
+ proto_send_newtux_server(PROTO_SEND_ALL, NULL, author);
+ }
+ }
+
+ }
+
+ countRoundInc();
+ eventTuxIsDead(tux);
+}
+
+void tuxTeleport(tux_t *tux)
+{
+ int x, y;
+#ifndef PUBLIC_SERVER
+ char msg[STR_SIZE];
+#endif
+
+#ifndef PUBLIC_SERVER
+ sprintf(msg, "tux with id %d teleporting\n", tux->id);
+#ifndef NO_SOUND
+ playSound("teleport", SOUND_GROUP_BASE);
+#endif
+ appendTextInTerm(msg);
+#endif
+
+ if( getNetTypeGame() != NET_GAME_TYPE_CLIENT )
+ {
+ findFreeSpace(getCurrentArena(), &x, &y, TUX_WIDTH, TUX_HEIGHT);
+ moveObjectInSpace(getCurrentArena()->spaceTux, tux, x, y);
+ //setTuxProportion(tux, x, y);
+ }
+
+ if( getNetTypeGame() == NET_GAME_TYPE_SERVER )
+ {
+ proto_send_newtux_server(PROTO_SEND_ALL, NULL, tux);
+ }
+}
+
+static void bombBallExplosion(shot_t *shot)
+{
+ item_t *item;
+ int x, y;
+
+ x = ( shot->x + shot->w/2 ) - ITEM_BIG_EXPLOSION_WIDTH/2;
+ y = ( shot->y + shot->h/2 ) - ITEM_BIG_EXPLOSION_HEIGHT/2;
+
+ item = newItem(x, y, ITEM_BIG_EXPLOSION, shot->author_id );
+
+ addObjectToSpace(getCurrentArena()->spaceItem, item );
+
+ delObjectFromSpaceWithObject(getCurrentArena()->spaceShot, shot, destroyShot);
+
+ if( getNetTypeGame() == NET_GAME_TYPE_SERVER )
+ {
+ proto_send_del_server(PROTO_SEND_ALL, NULL, shot->id);
+ proto_send_additem_server(PROTO_SEND_ALL, NULL, item);
+ }
+}
+
+void eventConflictTuxWithShot(arena_t *arena)
+{
+ shot_t *thisShot;
+ tux_t *thisTux;
+ int i, j;
+
+ for( i = 0 ; i < arena->spaceShot->list->count ; i++ )
+ {
+ thisShot = (shot_t *)arena->spaceShot->list->list[i];
+ assert( thisShot != NULL );
+
+ listDoEmpty(listHelp);
+ getObjectFromSpace(arena->spaceTux, thisShot->x, thisShot->y,
+ thisShot->w, thisShot->h, listHelp);
+
+ for( j = 0 ; j < listHelp->count ; j++ )
+ {
+ thisTux = listHelp->list[j];
+
+ if( thisTux->status == TUX_STATUS_ALIVE )
+ {
+ if( thisShot->author_id == thisTux->id &&
+ thisShot->isCanKillAuthor == FALSE )
+ {
+ continue;
+ }
+
+ if( thisTux->bonus == BONUS_TELEPORT )
+ {
+ tuxTeleport(thisTux);
+ continue;
+ }
+
+ if( thisShot->gun == GUN_BOMBBALL )
+ {
+ if( getNetTypeGame() != NET_GAME_TYPE_CLIENT )
+ {
+ bombBallExplosion(thisShot);
+ i--;
+ }
+
+ continue;
+ }
+
+ if( getNetTypeGame() != NET_GAME_TYPE_CLIENT )
+ {
+ eventTuxIsDeadWIthShot(thisTux, thisShot);
+ }
+ }
+
+ delObjectFromSpaceWithObject(arena->spaceShot, thisShot, destroyShot);
+ i--;
+
+ continue;
+ }
+ }
+}
+
+void moveTux(tux_t *tux, int n)
+{
+ int px, py;
+ int zal_x, zal_y;
+ int new_x, new_y;
+ int w, h;
+ arena_t *arena;
+
+ assert( tux != NULL );
+
+ arena = getCurrentArena();
+ //interval();
+
+ if( tux->position != n )
+ {
+ tux->position = n;
+ return;
+ }
+
+ if( n == TUX_LEFT && tux->x-TUX_STEP <= 0 )
+ {
+ return;
+ }
+
+ if( n == TUX_RIGHT && tux->x+TUX_STEP >= arena->w )
+ {
+ return;
+ }
+
+ if( n == TUX_UP && tux->y-TUX_STEP <= 0 )
+ {
+ return;
+ }
+
+ if( n == TUX_DOWN && tux->y+TUX_STEP >= arena->h )
+ {
+ return;
+ }
+
+ getTuxProportion(tux, &zal_x, &zal_y, &w, &h);
+
+ getCourse(tux->position, &px, &py);
+
+ new_x = zal_x;
+ new_y = zal_y;
+
+ new_x += px * TUX_STEP;
+ new_y += py * TUX_STEP;
+
+ if( tux->bonus == BONUS_SPEED )
+ {
+ new_x += px * TUX_STEP;
+ new_y += py * TUX_STEP;
+ }
+
+ if( tux->bonus != BONUS_GHOST && (
+ isConflictWithObjectFromSpaceBut(arena->spaceTux, new_x, new_y, w, h, tux) ||
+ isConflictModule(new_x, new_y, w, h) ) )
+ {
+ setTuxProportion(tux, zal_x, zal_y);
+ return;
+ }
+
+ setTuxProportion(tux, zal_x, zal_y);
+ moveObjectInSpace(arena->spaceTux, tux, new_x, new_y);
+ eventGiveTuxListItem(tux, getCurrentArena()->spaceItem);
+ tux->frame++;
+ if( tux->frame == TUX_KEY * TUX_MAX_ANIMATION_FRAME ) tux->frame = 0;
+}
+
+void switchTuxGun(tux_t *tux)
+{
+ int i;
+#ifndef PUBLIC_SERVER
+ char msg[STR_SIZE];
+#endif
+
+ if( tux->control != TUX_CONTROL_NET &&
+ tux->isCanSwitchGun == FALSE )
+ {
+ return;
+ }
+
+ for( i = tux->gun+1 ; i < GUN_COUNT ; i++ )
+ {
+ if( tux->shot[i] > 0 )
+ {
+ tux->gun = i;
+ tux->isCanSwitchGun = FALSE;
+ addTaskToTimer(getCurrentArena()->listTimer, TIMER_ONE, timer_tuxCanSwitchGun,
+ newInt(tux->id), TUX_TIME_CAN_SWITCH_GUN );
+#ifndef PUBLIC_SERVER
+#ifndef NO_SOUND
+ playSound("switch_gun", SOUND_GROUP_BASE);
+#endif
+ sprintf(msg, "tux with id %d switch gun\n", tux->id);
+ appendTextInTerm(msg);
+#endif
+ return;
+ }
+ }
+
+ for( i = 0 ; i < GUN_COUNT ; i++ )
+ {
+ if( tux->shot[i] > 0 )
+ {
+ tux->gun = i;
+ tux->isCanSwitchGun = FALSE;
+ addTaskToTimer(getCurrentArena()->listTimer, TIMER_ONE, timer_tuxCanSwitchGun,
+ newInt(tux->id), TUX_TIME_CAN_SWITCH_GUN );
+
+#ifndef PUBLIC_SERVER
+#ifndef NO_SOUND
+ playSound("switch_gun", SOUND_GROUP_BASE);
+#endif
+ sprintf(msg, "tux with id %d switch gun\n", tux->id);
+ appendTextInTerm(msg);
+#endif
+
+ return;
+ }
+ }
+}
+
+void shotTux(tux_t *tux)
+{
+ assert( tux != NULL );
+
+ if( tux->isCanShot == FALSE ||
+ tux->shot[tux->gun] == 0 )
+ {
+ return;
+ }
+
+#ifndef NO_SOUND
+ playSound("switch_gun", SOUND_GROUP_BASE);
+#endif
+
+ shotInGun(tux);
+
+ tux->isCanShot = FALSE;
+
+ addTaskToTimer(getCurrentArena()->listTimer, TIMER_ONE, timer_tuxCanShot,
+ newInt(tux->id), TUX_TIME_CAN_SHOT );
+
+ if( tux->shot[tux->gun] == 0 )
+ {
+ switchTuxGun(tux);
+ }
+}
+
+void actionTux(tux_t *tux, int action)
+{
+ if( tux->status == TUX_STATUS_DEAD )
+ {
+ return;
+ }
+
+ switch( action )
+ {
+ case TUX_UP :
+ case TUX_LEFT :
+ case TUX_RIGHT :
+ case TUX_DOWN :
+ moveTux(tux, action);
+ break;
+
+ case TUX_SHOT :
+ shotTux(tux);
+ break;
+
+ case TUX_SWITCH_GUN :
+ switchTuxGun(tux);
+ break;
+ }
+}
+
+static void pickUpGun(tux_t *tux)
+{
+ if( isTuxAnyGun(tux) == FALSE )
+ {
+ tux->gun = GUN_SIMPLE;
+
+ if( tux->pickup_time < TUX_MAX_PICKUP )
+ {
+ tux->pickup_time++;
+ }
+
+ if( tux->pickup_time == TUX_MAX_PICKUP && getNetTypeGame() != NET_GAME_TYPE_CLIENT )
+ {
+#ifndef PUBLIC_SERVER
+ char msg[STR_SIZE];
+#ifndef NO_SOUND
+ playSound("switch_gun", SOUND_GROUP_BASE);
+#endif
+ sprintf(msg, "tux with id %d pickup\n", tux->id);
+ appendTextInTerm(msg);
+#endif
+
+ tux->gun = GUN_SIMPLE;
+ tux->shot[ tux->gun ] = GUN_MAX_SHOT;
+ tux->pickup_time = 0;
+
+ if( getNetTypeGame() == NET_GAME_TYPE_SERVER )
+ {
+ proto_send_newtux_server(PROTO_SEND_ALL, NULL, tux);
+ }
+ }
+ }
+}
+
+static void eventBonus(tux_t *tux)
+{
+ if( tux->bonus != BONUS_NONE )
+ {
+ if( tux->bonus_time > 0 )
+ {
+ tux->bonus_time--;
+ }
+
+ if( tux->bonus_time == 0 && getNetTypeGame() != NET_GAME_TYPE_CLIENT )
+ {
+#ifndef PUBLIC_SERVER
+ char msg[STR_SIZE];
+#endif
+
+ if( tux->bonus == BONUS_GHOST )
+ {
+ int x, y, w, h;
+ getTuxProportion(tux, &x, &y, &w, &h);
+
+ tux->bonus = BONUS_NONE;
+
+ if( /*isConflictTuxWithListTux(tux, getCurrentArena()->listTux) || */
+ isConflictModule(x, y, w, h) )
+ {
+ tux->bonus = BONUS_GHOST;
+ return;
+ }
+ }
+
+ tux->bonus = BONUS_NONE;
+
+#ifndef PUBLIC_SERVER
+ sprintf(msg, "tux with id %d bonus disabled\n", tux->id);
+ appendTextInTerm(msg);
+#endif
+
+ if( getNetTypeGame() == NET_GAME_TYPE_SERVER )
+ {
+ proto_send_newtux_server(PROTO_SEND_ALL, NULL, tux);
+ }
+ }
+ }
+}
+
+void eventListTux(list_t *listTux)
+{
+ tux_t *thisTux;
+ arena_t *arena;
+ int i;
+
+ assert( listTux != NULL );
+ arena = getCurrentArena();
+
+ for( i = 0 ; i < listTux->count ; i++ )
+ {
+ thisTux = (tux_t *)listTux->list[i];
+ assert( thisTux != NULL );
+
+#ifndef PUBLIC_SERVER
+ tuxControl(thisTux);
+#endif
+ pickUpGun(thisTux);
+ eventBonus(thisTux);
+ eventGiveTuxListItem(thisTux, arena->spaceItem);
+ }
+}
+
+void getTuxProportion(tux_t *tux, int *x,int *y, int *w, int *h)
+{
+ assert( tux != NULL );
+
+ if( x != NULL ) *x = tux->x - TUX_WIDTH / 2;
+ if( y != NULL ) *y = tux->y - TUX_HEIGHT / 2;
+ if( w != NULL ) *w = TUX_WIDTH;
+ if( h != NULL ) *h = TUX_HEIGHT;
+}
+
+void setTuxProportion(tux_t *tux, int x, int y)
+{
+ assert( tux != NULL );
+
+ tux->x = x + TUX_WIDTH / 2;
+ tux->y = y + TUX_WIDTH / 2;
+}
+
+void getStatusTux(void *p, int *id, int *x,int *y, int *w, int *h)
+{
+ tux_t *tux;
+
+ tux = p;
+ *id = tux->id;
+ getTuxProportion(tux, x, y, w, h);
+}
+
+void setStatusTux(void *p, int x, int y, int w, int h)
+{
+ tux_t *tux;
+
+ tux = p;
+ setTuxProportion(tux, x, y);
+}
+
+void destroyTux(tux_t *tux)
+{
+ assert( tux != NULL );
+ delID(tux->id);
+ free(tux);
+}
+
+void quitTux()
+{
+ isTuxInit = FALSE;
+}
diff --git a/src/base/tux.h b/src/base/tux.h
new file mode 100644
index 0000000..8a39cf9
--- /dev/null
+++ b/src/base/tux.h
@@ -0,0 +1,137 @@
+
+#ifndef TUX_H
+
+#define TUX_H
+
+#include "base/main.h"
+#include "base/list.h"
+#include "base/arena.h"
+
+#define TUX_STEP 7
+#define TUX_LAYER 0
+
+#define TUX_MAX_ANIMATION_FRAME 10
+#define TUX_KEY 1
+
+#define TUX_LOCATE_UNKNOWN -100
+
+#define TUX_MAX_PICKUP 50
+#define TUX_MAX_BONUS 500
+
+#define TUX_TIME_SPAWN 2000
+#define TUX_TIME_CAN_SHOT 500
+#define TUX_TIME_CAN_SWITCH_GUN 100
+
+#define TUX_STATUS_ALIVE 0
+#define TUX_STATUS_DEAD 1
+#define TUX_STATUS_PAUZED 2
+
+#define TUX_CONTROL_NONE 0
+#define TUX_CONTROL_KEYBOARD_LEFT 1
+#define TUX_CONTROL_KEYBOARD_RIGHT 2
+#define TUX_CONTROL_NET 3
+#define TUX_CONTROL_AI 4
+
+#define TUX_WIDTH 30
+#define TUX_HEIGHT 30
+
+#define TUX_IMG_WIDTH 40
+#define TUX_IMG_HEIGHT 54
+
+#define TUX_UP 8
+#define TUX_LEFT 4
+#define TUX_RIGHT 6
+#define TUX_DOWN 2
+#define POSITION_UNKNOWN -1
+
+#define TUX_SHOT 5
+#define TUX_SWITCH_GUN 0
+
+
+#define GUN_NONE -1
+
+#define GUN_COUNT 7
+#define GUN_MAX_SHOT 5
+
+#define BONUS_COUNT 6
+#define ITEM_COUNT 16
+
+
+#define SHOT_CHECK_AREA 25
+
+#define GUN_SIMPLE 0
+#define GUN_DUAL_SIMPLE 1
+#define GUN_SCATTER 2
+#define GUN_TOMMY 3
+#define GUN_LASSER 4
+#define GUN_MINE 5
+#define GUN_BOMBBALL 6
+
+#define ITEM_MINE 7
+#define ITEM_EXPLOSION 8
+#define ITEM_BIG_EXPLOSION 9
+
+#define BONUS_NONE -1
+#define BONUS_SPEED 10
+#define BONUS_SHOT 11
+#define BONUS_TELEPORT 12
+#define BONUS_GHOST 13
+#define BONUS_4X 14
+#define BONUS_HIDDEN 15
+
+typedef struct tux_struct
+{
+ int id;
+
+ int x;
+ int y;
+
+ char name[STR_NAME_SIZE];
+
+ int status;
+ int control;
+ int position;
+ int score;
+
+ int gun;
+ int shot[GUN_COUNT];
+ int round;
+ int bonus;
+
+ int bonus_time;
+ int pickup_time;
+
+ bool_t isCanShot;
+ bool_t isCanSwitchGun;
+
+ int frame;
+
+ void *client;
+} tux_t;
+
+extern bool_t isTuxInicialized();
+extern void initTux();
+extern tux_t* newTux();
+extern bool_t isTuxAnyGun(tux_t *tux);
+extern void getCourse(int n, int *x, int *y);
+extern void drawTux(tux_t *tux);
+extern void drawListTux(list_t *listTux);
+extern void eventTuxIsDead(tux_t *tux);
+extern tux_t* isConflictWithListTux(list_t *listTux, int x, int y, int w, int h);
+extern int isConflictTuxWithListTux(tux_t *tux, list_t *listTux);
+extern void eventConflictTuxWithShot(arena_t *arena);
+extern void eventConflictTuxWithTeleport(list_t *listTux, list_t *listTeleport);
+extern void tuxTeleport(tux_t *tux);
+extern void actionTux(tux_t *tux, int action);
+extern void eventListTux(list_t *listTux);
+extern tux_t* getTuxID(list_t *listTux, int id);
+extern void getTuxProportion(tux_t *tux, int *x,int *y, int *w, int *h);
+extern void replaceTuxID(tux_t *tux, int id);
+extern int isTuxSeesTux(tux_t *tux, tux_t *thisTux);
+extern void setTuxProportion(tux_t *tux, int x, int y);
+extern void getStatusTux(void *p, int *id, int *x,int *y, int *w, int *h);
+extern void setStatusTux(void *p, int x, int y, int w, int h);
+extern void destroyTux(tux_t *tux);
+extern void quitTux();
+
+#endif