diff options
Diffstat (limited to 'src')
39 files changed, 6186 insertions, 0 deletions
diff --git a/src/Makefile b/src/Makefile new file mode 100755 index 0000000..224e70a --- /dev/null +++ b/src/Makefile @@ -0,0 +1,126 @@ + +CC = gcc + +CFLAGS = -g -O0 `sdl-config --cflags` -I../include -Wall +LIBS = `sdl-config --libs` -lSDL_image -lSDL_ttf -lSDL_mixer + +FILES = interface.o font.o list.o image.o layer.o director.o configFile.o tux.o main.o \ + screen.o screen_world.o wall.o shot.o myTimer.o panel.o net_multiplayer.o network.o \ + buffer.o dynamicInt.o arena.o arenaFile.o textFile.o sound.o audio.o music.o gun.o \ + item.o widget_label.o screen_mainMenu.o widget_button.o screen_analyze.o widget_textfield.o \ + widget_check.o widget_image.o screen_setting.o screen_gameType.o + + +tuxanci-ng: $(FILES) + $(CC) $(CFLAGS) $(LIBS) -o tuxanci-ng $(FILES) + +main.o: main.c + $(CC) $(CFLAGS) -o main.o -c main.c + +interface.o: interface.c ../include/interface.h + $(CC) $(CFLAGS) -o interface.o -c interface.c + +font.o: font.c ../include/font.h + $(CC) $(CFLAGS) -o font.o -c font.c + +list.o: list.c ../include/list.h + $(CC) $(CFLAGS) -o list.o -c list.c + +image.o: image.c ../include/image.h + $(CC) $(CFLAGS) -o image.o -c image.c + +layer.o: layer.c ../include/layer.h + $(CC) $(CFLAGS) -o layer.o -c layer.c + +director.o: director.c ../include/director.h + $(CC) $(CFLAGS) -o director.o -c director.c + +configFile.o: configFile.c ../include/configFile.h + $(CC) $(CFLAGS) -o configFile.o -c configFile.c + +tux.o: tux.c ../include/tux.h + $(CC) $(CFLAGS) -o tux.o -c tux.c + +screen.o: screen.c ../include/screen.h + $(CC) $(CFLAGS) -o screen.o -c screen.c + +screen_world.o: screen_world.c ../include/screen_world.h + $(CC) $(CFLAGS) -o screen_world.o -c screen_world.c + +wall.o: wall.c ../include/wall.h + $(CC) $(CFLAGS) -o wall.o -c wall.c + +shot.o: shot.c ../include/shot.h + $(CC) $(CFLAGS) -o shot.o -c shot.c + +myTimer.o: myTimer.c ../include/myTimer.h + $(CC) $(CFLAGS) -o myTimer.o -c myTimer.c + +panel.o: panel.c ../include/panel.h + $(CC) $(CFLAGS) -o panel.o -c panel.c + +buffer.o: buffer.c ../include/buffer.h + $(CC) $(CFLAGS) -o buffer.o -c buffer.c + +network.o: network.c ../include/network.h + $(CC) $(CFLAGS) -o network.o -c network.c + +net_multiplayer.o: net_multiplayer.c ../include/net_multiplayer.h + $(CC) $(CFLAGS) -o net_multiplayer.o -c net_multiplayer.c + +dynamicInt.o: dynamicInt.c ../include/dynamicInt.h + $(CC) $(CFLAGS) -o dynamicInt.o -c dynamicInt.c + +arena.o: arena.c ../include/arena.h + $(CC) $(CFLAGS) -o arena.o -c arena.c + +textFile.o: textFile.c ../include/textFile.h + $(CC) $(CFLAGS) -o textFile.o -c textFile.c + +arenaFile.o: arenaFile.c ../include/arenaFile.h + $(CC) $(CFLAGS) -o arenaFile.o -c arenaFile.c + +audio.o: audio.c ../include/audio.h + $(CC) $(CFLAGS) -o audio.o -c audio.c + +sound.o: sound.c ../include/sound.h + $(CC) $(CFLAGS) -o sound.o -c sound.c + +music.o: music.c ../include/music.h + $(CC) $(CFLAGS) -o music.o -c music.c + +gun.o: gun.c ../include/gun.h + $(CC) $(CFLAGS) -o gun.o -c gun.c + +item.o: item.c ../include/item.h + $(CC) $(CFLAGS) -o item.o -c item.c + +screen_mainMenu.o: screen_mainMenu.c ../include/screen_mainMenu.h + $(CC) $(CFLAGS) -o screen_mainMenu.o -c screen_mainMenu.c + +screen_analyze.o: screen_analyze.c ../include/screen_analyze.h + $(CC) $(CFLAGS) -o screen_analyze.o -c screen_analyze.c + +screen_setting.o: screen_setting.c ../include/screen_setting.h + $(CC) $(CFLAGS) -o screen_setting.o -c screen_setting.c + +screen_gameType.o: screen_gameType.c ../include/screen_gameType.h + $(CC) $(CFLAGS) -o screen_gameType.o -c screen_gameType.c + +widget_label.o: widget_label.c ../include/widget_label.h + $(CC) $(CFLAGS) -o widget_label.o -c widget_label.c + +widget_button.o: widget_button.c ../include/widget_button.h + $(CC) $(CFLAGS) -o widget_button.o -c widget_button.c + +widget_textfield.o: widget_textfield.c ../include/widget_textfield.h + $(CC) $(CFLAGS) -o widget_textfield.o -c widget_textfield.c + +widget_check.o: widget_check.c ../include/widget_check.h + $(CC) $(CFLAGS) -o widget_check.o -c widget_check.c + +widget_image.o: widget_image.c ../include/widget_image.h + $(CC) $(CFLAGS) -o widget_image.o -c widget_image.c + +clean: + rm -rf *.o *.c~ *.h~ tuxanci-ng diff --git a/src/arena.c b/src/arena.c new file mode 100644 index 0000000..320a697 --- /dev/null +++ b/src/arena.c @@ -0,0 +1,37 @@ + +#include <stdlib.h> +#include <assert.h> +#include <string.h> + +#include "arena.h" +#include "list.h" +#include "tux.h" +#include "shot.h" +#include "wall.h" +#include "item.h" + +arena_t* newArena() +{ + arena_t *new; + new = malloc( sizeof(arena_t) ); + + new->background = NULL; + strcpy(new->music, ""); + + new->listTux = newList(); + new->listShot = newList(); + new->listWall = newList(); + new->listItem = newList(); + + return new; +} + +void destroyArena(arena_t *p) +{ + destroyListItem(p->listTux, destroyTux); + destroyListItem(p->listShot, destroyShot); + destroyListItem(p->listWall, destroyWall); + destroyListItem(p->listItem, destroyItem); + + free(p); +} diff --git a/src/arenaFile.c b/src/arenaFile.c new file mode 100644 index 0000000..34b3335 --- /dev/null +++ b/src/arenaFile.c @@ -0,0 +1,203 @@ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <assert.h> + +#include "main.h" +#include "list.h" +#include "textFile.h" +#include "arenaFile.h" +#include "arena.h" +#include "tux.h" +#include "shot.h" +#include "wall.h" +#include "item.h" +#include "director.h" +#include "path.h" +#include "string_length.h" +#include "image.h" +#include "music.h" + +static list_t *listArenaFile; + +static bool_t isArenaFileInit = FALSE; + +bool_t isAreaFileInicialized() +{ + return isArenaFileInit; +} + +static int setValue(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); + + //printf("%s %s\n", line, env); + + offset_env = strstr(line, clone_env); + //printf("offset_env = %s\n", offset_env); + if( offset_env == NULL )return -1; + + offset_val_begin = strchr(offset_env, '"'); + //printf("offset_val_begin = %s\n", offset_val_begin); + if( offset_val_begin == NULL )return -1; + + offset_val_end = strchr(offset_val_begin+1, '"'); + //printf("offset_val_end = %s\n", offset_val_end); + 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; + //printf("val_len = %d\n", val_len); + + memset(val, 0, len); + memcpy(val, offset_val_begin+1, val_len); + //printf("val = %s\n", val); + return 0; +} + +static int isYesOrNO(char *s) +{ + if( s[0] == 'Y' || s[0] == 'y' )return 1; + return 0; +} + +static void cmd_loadImage(char *line) +{ + char str_file[STR_SIZE]; + char str_name[STR_SIZE]; + char str_alpha[STR_SIZE]; + + if( setValue(line, "file", str_file, STR_SIZE) != 0 )return; + if( setValue(line, "name", str_name, STR_SIZE) != 0 )return; + if( setValue(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( setValue(line, "file", str_file, STR_SIZE) != 0 )return; + if( setValue(line, "name", str_name, STR_SIZE) != 0 )return; + + addMusic(str_file, str_name, MUSIC_GROUP_USER); +} + +static void cmd_background(arena_t *arena, char *line) +{ + char str_image[STR_SIZE]; + + if( setValue(line, "image", str_image, STR_SIZE) != 0 )return; + + arena->background = getImage(IMAGE_GROUP_USER, str_image); +} + +static void cmd_playMusic(arena_t *arena, char *line) +{ + char str_music[STR_SIZE]; + + if( setValue(line, "music", str_music, STR_SIZE) != 0 )return; + + strcpy(arena->music, str_music); +} + +static void cmd_wall(arena_t *arena, char *line) +{ + char str_x[STR_NUM_SIZE]; + char str_y[STR_NUM_SIZE]; + char str_img_x[STR_NUM_SIZE]; + char str_img_y[STR_NUM_SIZE]; + char str_w[STR_NUM_SIZE]; + char str_h[STR_NUM_SIZE]; + char str_layer[STR_NUM_SIZE]; + char str_image[STR_SIZE]; + wall_t *new; + + if( setValue(line, "x", str_x, STR_NUM_SIZE) != 0 )return; + if( setValue(line, "y", str_y, STR_NUM_SIZE) != 0 )return; + if( setValue(line, "w", str_w, STR_NUM_SIZE) != 0 )return; + if( setValue(line, "h", str_h, STR_NUM_SIZE) != 0 )return; + if( setValue(line, "img_x", str_img_x, STR_NUM_SIZE) != 0 )return; + if( setValue(line, "img_y", str_img_y, STR_NUM_SIZE) != 0 )return; + if( setValue(line, "layer", str_layer, STR_NUM_SIZE) != 0 )return; + if( setValue(line, "image", str_image, STR_SIZE) != 0 )return; + + new = newWall(atoi(str_x), atoi(str_y), + atoi(str_w), atoi(str_h), + atoi(str_img_x), atoi(str_img_y), + atoi(str_layer), getImage(IMAGE_GROUP_USER, str_image) ); + + addList(arena->listWall, new); +} + +arena_t* getArena(int id) +{ + textFile_t *ts; + arena_t *arena; + int i; + + ts = (textFile_t *) listArenaFile->list[id]; + arena = newArena(); + + for( i = 0 ; i < ts->text->count ; i++ ) + { + char *line; + line = (char *) (ts->text->list[i]); + + if( strncmp(line, "loadImage", 9) == 0 )cmd_loadImage(line); + if( strncmp(line, "loadMusic", 9) == 0 )cmd_loadMusic(line); + if( strncmp(line, "background", 10) == 0 )cmd_background(arena, line); + if( strncmp(line, "playMusic", 9) == 0 )cmd_playMusic(arena, line); + if( strncmp(line, "wall", 4) == 0 )cmd_wall(arena, line); + } + + return arena; +} + +void initArenaFile() +{ + director_t *p; + int i; + + assert( isImageInicialized() == TRUE ); + + 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); + addList(listArenaFile, loadTextFile(path)); + } + } + + destroyDirector(p); +} + +void quitArenaFile() +{ + isArenaFileInit = FALSE; + destroyListItem(listArenaFile, destroyTextFile); +} + diff --git a/src/audio.c b/src/audio.c new file mode 100644 index 0000000..8397788 --- /dev/null +++ b/src/audio.c @@ -0,0 +1,44 @@ + +#include <stdio.h> +#include <assert.h> +#include <SDL_mixer.h> + +#include "main.h" +#include "audio.h" +#include "interface.h" + +static bool_t isAudioInit = FALSE; + +bool_t isAudioInicialized() +{ + return isAudioInit; +} + +void initAudio() +{ + if( SDL_Init(SDL_INIT_AUDIO) == -1 ) + { + fprintf(stderr, "Nelze inicializovat audio : %s\n", SDL_GetError()); + return; + } + + if( Mix_OpenAudio(MIX_DEFAULT_FREQUENCY, MIX_DEFAULT_FORMAT, 2, 1024) == -1 ) + { + fprintf(stderr, "Nelze inicializovat audio : %s\n", Mix_GetError()); + return; + } + + Mix_AllocateChannels(16); + Mix_Volume(-1, MIX_MAX_VOLUME); + + printf("init audio..\n"); + isAudioInit = TRUE; +} + +void quitAudio() +{ + Mix_CloseAudio(); + isAudioInit = TRUE; + printf("quit audio..\n"); +} + diff --git a/src/buffer.c b/src/buffer.c new file mode 100755 index 0000000..95fef9d --- /dev/null +++ b/src/buffer.c @@ -0,0 +1,120 @@ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <assert.h> + +#include "buffer.h" + +buffer_t * newBuffer(int n) +{ + buffer_t *new; + + new = malloc(sizeof(buffer_t)); + memset(new, 0, sizeof(buffer_t)); + new->alloc = n; + new->data = malloc(n); + memset(new->data , 0, n); + + return new; +} + +int addBuffer(buffer_t *p, char *data, int len) +{ + assert( p != NULL ); + assert( data != NULL ); + assert( len >= 0 ); + + if( p->size + len <= p->alloc ) + { + memcpy(p->data + p->size, data, len); + p->size += len; + return 0; + } + + return 1; +} + +int cutBuffer(buffer_t *p, int len) +{ + assert( p != NULL ); + assert( len >= 0 ); + + if( p->size - len >= 0 ) + { + memmove(p->data, p->data + len, p->size - len); + p->size -= len; + return 0; + } + + return 1; +} + +int getBufferLine(buffer_t *p, char *line, int len) +{ + char *end; + int ret_len; + + assert( p != NULL ); + assert( line != NULL ); + assert( len >= 0 ); + + end = NULL; + + end = memchr(p->data, '\n', p->size); + + if( end == NULL ) return -1; + + ret_len = (int) ( (end - p->data) + 1); + if( ret_len > len-1 ) ret_len = len-1; + + memset(line, 0, len); + memcpy(line, p->data, ret_len); + + cutBuffer(p, ret_len); + + return ret_len; +} + +int getData(buffer_t *p, char *line, int len) +{ + assert( p != NULL ); + assert( line != NULL ); + assert( len >= 0 ); + + if( p->size < len)return -1; + memcpy(line, p->data, len); + cutBuffer(p, len); + return len; +} + +void destroyBuffer(buffer_t *p) +{ + assert( p != NULL ); + + if( p->data != NULL )free(p->data); + free(p); +} + +/* +int main() +{ + buffer_t *p; + char str[64]; + char *s[] = {"hello world\n", "dalsi riadok\n", "koniec\n", NULL}; + int i; + + p = newBuffer(1024 * 10); + + for( i = 0 ; s[i] != NULL ; i++) + addBuffer(p, s[i], strlen(s[i])); + + while( getBufferLine(p, str, 64) > 0 ) + { + printf("str = %s\n", str); + } + + destroyBuffer(p); + return 0; +} +*/ diff --git a/src/configFile.c b/src/configFile.c new file mode 100644 index 0000000..5bbbf97 --- /dev/null +++ b/src/configFile.c @@ -0,0 +1,50 @@ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <assert.h> + +#include "configFile.h" + +char* getValueInConfigFile(textFile_t *p, char *s) +{ + int i; + + assert( s != NULL ); + assert( p != NULL ); + + for( i = 0 ; i < p->text->count ; i++ ) + { + char *line; + char *offset; + + line = (char *) (p->text->list[i]); + + if( ( offset = strstr(line, s) ) != NULL ) + { + return offset + ( strlen(s) + 1 ); + } + } + + return NULL; +} + +void delRemInConfigFile(textFile_t *p) +{ + int i; + + assert( p != NULL ); + + for( i = 0 ; i < p->text->count ; i++ ) + { + char *line; + char *offset; + + line = (char *) (p->text->list[i]); + + if( ( offset = strchr(line, '#') ) != NULL ) + { + *offset = '\0'; + } + } +} diff --git a/src/director.c b/src/director.c new file mode 100755 index 0000000..9c11cb2 --- /dev/null +++ b/src/director.c @@ -0,0 +1,64 @@ + +#include <dirent.h> +#include <sys/types.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> +#include <assert.h> + +#include "list.h" +#include "string_length.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/dynamicInt.c b/src/dynamicInt.c new file mode 100644 index 0000000..3845d2f --- /dev/null +++ b/src/dynamicInt.c @@ -0,0 +1,11 @@ + +#include <stdlib.h> +#include "dynamicInt.h" + +int* newInt(int x) +{ + int *new; + new = malloc( sizeof(int) ); + *new = x; + return new; +} diff --git a/src/font.c b/src/font.c new file mode 100755 index 0000000..a9fb817 --- /dev/null +++ b/src/font.c @@ -0,0 +1,99 @@ + +#include "main.h" +#include "interface.h" +#include "string_length.h" +#include "font.h" +#include "path.h" + +static TTF_Font *g_font; +static int fontSize; + +static bool_t isFontInit = FALSE; + +bool_t isFontInicialized() +{ + return isFontInit; +} + +/* + * Inicialuzuje font. + * nacita font zo suboru *file o velkosti size + * Automaticky sa styk nastavy ako TTF_STYLE_BOLD + */ +void initFont(char *file,int size) +{ + char str[STR_PATH_SIZE]; + + assert( file != NULL ); + assert( size > 0 ); + + assert( isInterfaceInicialized() == TRUE ); + + sprintf(str, PATH_FONT "%s", file); + + if( TTF_Init() == -1 ) + { + fprintf(stderr, "%s\n", SDL_GetError()); + return; + } + + g_font = TTF_OpenFont(str, size); + TTF_SetFontStyle(g_font, TTF_STYLE_NORMAL); + + fontSize = size; + + printf("init font.. (%s)\n", file); + isFontInit = TRUE; +} + +/* + * Zobrazi text *s na suradnicu x y s farbou RGB + */ +void drawFont(char *s, int x, int y, int r, int g, int b) +{ + SDL_Rect dst_rect; + SDL_Surface *text; + SDL_Surface *p; + SDL_Color farba_pisma = {r, g, b, 0}; + + assert( s != NULL ); + + p = getSDL_Screen(); + + text = TTF_RenderUTF8_Blended(g_font, s, farba_pisma); + + dst_rect.x = x; + dst_rect.y = y; + + SDL_BlitSurface(text, NULL, p, &dst_rect); + SDL_FreeSurface(text); +} + +/* + * Vrati velkost daneho fontu. + */ +int getFontSize() +{ + return fontSize; +} + +void getTextSize(char *s, int *w, int *h) +{ + assert( s != NULL ); + assert( w != NULL ); + assert( h != NULL ); + + TTF_SizeUTF8(g_font, s, w, h); +} + +/* + * Uvolni font z pamete. + */ +void quitFont() +{ + TTF_CloseFont(g_font); + TTF_Quit(); + + printf("quit font\n"); + isFontInit = FALSE; +} diff --git a/src/gun.c b/src/gun.c new file mode 100644 index 0000000..1cb35fe --- /dev/null +++ b/src/gun.c @@ -0,0 +1,231 @@ + +#include <stdio.h> +#include <stdlib.h> +#include <assert.h> + +#include "arena.h" +#include "tux.h" +#include "shot.h" +#include "dynamicInt.h" +#include "myTimer.h" +#include "main.h" +#include "item.h" +#include "screen_world.h" +#include "interface.h" +#include "gun.h" + +static void modificiationCopuse(int courser, + int right_x, int right_y, int right_px, int right_py, + int *dest_x, int *dest_y, int *dest_px, int *dest_py) +{ + assert( dest_px != NULL ); + assert( dest_py != NULL ); + + switch( courser ) + { + case TUX_UP : + *dest_x = right_y; + *dest_y = -right_x; + *dest_px = right_py; + *dest_py = -right_px; + break; + case TUX_RIGHT : + *dest_x = right_x; + *dest_y = right_y; + *dest_px = right_px; + *dest_py = right_py; + break; + case TUX_LEFT : + *dest_x = -right_x; + *dest_y = right_y; + *dest_px = -right_px; + *dest_py = right_py; + break; + case TUX_DOWN : + *dest_x = right_y; + *dest_y = right_x; + *dest_px = right_py; + *dest_py = right_px; + break; + default : + assert( ! "V premennej courser je zly smer !" ); + break; + } +} + +static void addShot(tux_t *tux,int x, int y, int px, int py) +{ + int dest_x, dest_y; + int dest_px, dest_py; + arena_t *arena; + shot_t *shot; + int gun; + + arena = getWorldArena(); + + 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; + } + + modificiationCopuse(tux->position, x, y, px, py, + &dest_x, &dest_y, &dest_px, &dest_py); + + shot = newShot(tux->x + dest_x, tux->y + dest_y, dest_px, dest_py, gun, tux); + addList( arena->listShot, shot ); + } + + tux->position = zal; + } + else + { + modificiationCopuse(tux->position, x, y, px, py, + &dest_x, &dest_y, &dest_px, &dest_py); + + shot = newShot(tux->x + dest_x, tux->y + dest_y, dest_px, dest_py, gun, tux); + addList( arena->listShot, shot ); + } +} + +static void shotInGunSimpe(tux_t *tux) +{ + addShot(tux, 0, 0, +10, 0); +} + +static void shotInGunDualSimpe(tux_t *tux) +{ + addShot(tux, 0, -5, +10, 0); + addShot(tux, 0, +5, +10, 0); +} + +static void shotInGunScatter(tux_t *tux) +{ + int i; + + for( i = -2 ; i <= +2 ; i++ ) + { + addShot(tux, 0, 0, +12, i); + } +} + +static void timer_addShotTimer(void *p) +{ + tux_t *tux; + int id; + + id = * ((int *)p); + free(p); + + tux = getTuxID(getWorldArena()->listTux, id); + + if( tux == NULL )return; + + addShot(tux, 0, 0, +15, 0); +} + +static void shotInGunTommy(tux_t *tux) +{ + int i; + + for( i = 0 ; i < 10 ; i++ ) + { + addTimer(timer_addShotTimer, newInt(tux->id), i * 100 ); + } +} + +static void timer_addLaserTimer(void *p) +{ + tux_t *tux; + int id; + + id = * ((int *)p); + free(p); + + tux = getTuxID(getWorldArena()->listTux, id); + + if( tux == NULL )return; + + addShot(tux, 0, 0, +20, 0); +} + +static void shotInGunLasser(tux_t *tux) +{ + int i; + + for( i = 0 ; i < 50 ; i++ ) + { + addTimer(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 = getWorldArena(); + + if( isFreeSpace(x, y, ITEM_MINE_WIDTH, ITEM_MINE_HEIGHT) ) + { + addList(arena->listItem, newItem(x, y, ITEM_MINE) ); + } +} + +void shotInGun(tux_t *tux) +{ + switch( tux->gun ) + { + case GUN_SIMPLE : shotInGunSimpe(tux); + break; + case GUN_DUAL_SIMPLE : shotInGunDualSimpe(tux); + break; + case GUN_SCATTER : shotInGunScatter(tux); + break; + case GUN_TOMMY : shotInGunTommy(tux); + break; + case GUN_LASSER : shotInGunLasser(tux); + break; + case GUN_MINE : putInGunMine(tux); + break; + } +} diff --git a/src/image.c b/src/image.c new file mode 100755 index 0000000..3726167 --- /dev/null +++ b/src/image.c @@ -0,0 +1,192 @@ + +#include <stdio.h> +#include <stdlib.h> +#include <assert.h> + +#include "main.h" +#include "interface.h" +#include "image.h" +#include "list.h" +#include "path.h" +#include "string_length.h" + +static list_t *listImageData; + +static bool_t isImageDataInit = FALSE; + +bool_t isImageInicialized() +{ + return isImageDataInit; +} + +/* + * Inicialuzje globalny zoznam obrazkov + */ +void initImageData() +{ + assert( isInterfaceInicialized() == TRUE ); + + printf("init image database..\n"); + listImageData = newList(); + isImageDataInit = TRUE; +} + +static SDL_Surface *loadImage(const char *filename, int alpha) +{ + SDL_Surface *tmp; + SDL_Surface *ret; + + char str[STR_PATH_SIZE]; + + sprintf(str, PATH_IMAGE "%s", filename); + + if( ( tmp = IMG_Load(str) ) == NULL ) + { + fprintf(stderr, "%s\n", SDL_GetError()); + return NULL; + } + + if( ( ret = (alpha) ? SDL_DisplayFormatAlpha(tmp) : SDL_DisplayFormat(tmp) ) == NULL ) + { + fprintf(stderr, "%s\n", SDL_GetError()); + SDL_FreeSurface(tmp); + return NULL; + } + + SDL_FreeSurface(tmp); + return ret; +} + +/* + * Prida obrazok do globalneho zoznamu obrazkov + * *file - nazov suboru v ktorom je obrazok ulozeny + * *name - nazov obrazku ( pouzije sa ako vyhadavaci retazec v zazanem ) + * alpha - 0 - nema alpha kanal | 1 - ma alpha kanal + */ +SDL_Surface* addImageData(char *file, int alpha, char *name, char *group) +{ + image_data_t *new; + + assert( file != NULL ); + assert( name != NULL ); + assert( group != NULL ); + + new = malloc(sizeof(image_data_t)); + + new->image = loadImage(file, alpha); + //if(strstr(file,"BMP")!=NULL)SDL_SetColorKey(new->image, SDL_SRCCOLORKEY, SDL_MapRGB(new->image->format, 255, 255, 255)); + new->name = strdup(name); + new->group = strdup(group); + + addList(listImageData, new); + + printf("load image %s\n", file); + return new->image; +} + +static void destroyImageData(image_data_t *p) +{ + assert( p != NULL ); + + free(p->name); + free(p->group); + SDL_FreeSurface(p->image); + free(p); +} + +/* + * Vrati odkaz na image_data v globalnom zozname obrazkov + * a nazvom *s + */ +SDL_Surface* getImage(char *group, char *name) +{ + image_data_t *this; + + assert( group != NULL ); + assert( name != NULL ); + + int i; + + for(i = 0 ; i < listImageData->count; i++) + { + this = (image_data_t *) listImageData->list[i]; + + if( strcmp(group, this->group) == 0 && strcmp(name, this->name) == 0 ) + { + return this->image; + } + } + + return NULL; +} + +void delImage(char *group, char *name) +{ + image_data_t *this; + int i; + + assert( group != NULL ); + assert( name != NULL ); + + for(i = 0 ; i < listImageData->count; i++) + { + this = (image_data_t *) listImageData->list[i]; + + if( strcmp(group, this->group) == 0 && strcmp(name, this->name) == 0 ) + { + delListItem(listImageData, i, destroyImageData); + break; + } + + } +} + +void delAllImageInGroup(char *group) +{ + image_data_t *this; + int i; + + assert( group != NULL ); + printf("del all image in group %s\n", group); + + for(i = 0 ; i < listImageData->count; i++) + { + this = (image_data_t *) listImageData->list[i]; + + if( strcmp(group, this->group) == 0 ) + { + delListItem(listImageData, i, destroyImageData); + break; + } + + } +} + +void drawImage(SDL_Surface *p, int x,int y, int px, int py, int w, int h) +{ + SDL_Rect dst_rect, src_rect; + SDL_Surface *screen; + + screen = getSDL_Screen(); + + dst_rect.x = x; + dst_rect.y = y; + + src_rect.x = px; + src_rect.y = py; + src_rect.w = w; + src_rect.h = h; + + SDL_BlitSurface(p, &src_rect, screen, &dst_rect); +} + +/* + * Odstrani zoznam obrazkov z pamate + */ +void quitImageData() +{ + printf("quit image database..\n"); + destroyListItem(listImageData, destroyImageData); + isImageDataInit = FALSE; +} + diff --git a/src/interface.c b/src/interface.c new file mode 100755 index 0000000..f47c2dd --- /dev/null +++ b/src/interface.c @@ -0,0 +1,200 @@ + +#include "main.h" +#include "interface.h" +#include "screen.h" + +//povrch okna +static SDL_Surface *screen; + +//casovac +static SDL_TimerID timer; + +//priznaky okna +static Uint32 g_win_flags = SDL_HWSURFACE|SDL_DOUBLEBUF|SDL_ANYFORMAT; + +static bool_t isInterfaceInit = FALSE; + +bool_t isInterfaceInicialized() +{ + return isInterfaceInit; +} + +static Uint32 TimerCallback(Uint32 interval, void *param) +{ + SDL_Event event; + event.type = SDL_USEREVENT; + event.user.code = USR_EVT_TIMER; + event.user.data1 = NULL; + event.user.data2 = NULL; + + SDL_PushEvent(&event); + + return interval; +} + +int initSDL() +{ + printf("init SDL..\n"); + + //inicializujem SDL + if( SDL_Init(SDL_SUBSYSTEMS) == -1 ) + { + fprintf(stderr, "%s\n", SDL_GetError()); + SDL_Quit(); + return -1; + } + + //inicializujem okno + //screen = SDL_SetVideoMode(WINDOW_SIZE_X, WINDOW_SIZE_Y, 0, g_win_flags); + screen = SDL_SetVideoMode(WINDOW_SIZE_X, WINDOW_SIZE_Y, 0, g_win_flags); + + if (screen == NULL ) + { + fprintf(stderr, "%s\n", SDL_GetError()); + SDL_Quit(); + return -1; + } + + SDL_WM_SetCaption(WINDOW_TITLE, NULL); + //SDL_ShowCursor(0); + //SDL_EnableKeyRepeat(1,1); + timer = SDL_AddTimer(INTERVAL, TimerCallback, NULL); + + srand((unsigned)time(NULL)); + isInterfaceInit = TRUE; + + return 0; +} + +SDL_Surface* getSDL_Screen() +{ + return screen; +} + +int toggleFullscreen() +{ + if(g_win_flags & SDL_FULLSCREEN) + g_win_flags &= ~SDL_FULLSCREEN; + else + g_win_flags |= SDL_FULLSCREEN; + + if(SDL_WM_ToggleFullScreen(screen) == 0) + { + fprintf(stderr, "Nemozem prepnut do fullscreenu!\n"); + + SDL_FreeSurface(screen); + screen = SDL_SetVideoMode(WINDOW_SIZE_X, WINDOW_SIZE_Y, WIN_BPP, g_win_flags); + + if(screen == NULL) + { + fprintf(stderr, "Nemozem premnut do okna:%s\n", SDL_GetError()); + return 0; + } + } + + return 1; +} + +void getMousePosition(int *x, int *y) +{ + SDL_GetMouseState(x, y); +} + +int isMouseClicked() +{ + return SDL_GetMouseState(NULL,NULL) & SDL_BUTTON(SDL_BUTTON_LEFT); +} + +/* +static void action_esc() +{ + if( strcmp(getScreen(), "world") == 0 ) + { + setScreen("analyze"); + } + + if( strcmp(getScreen(), "mainMenu") == 0 ) + { + quit(); + } + +} +*/ + +int eventAction() +{ + SDL_Event event; + + while(SDL_WaitEvent(&event)) + { + switch(event.type) + { + case SDL_KEYDOWN: + switch(event.key.keysym.sym) + { +/* + case SDLK_ESCAPE: + action_esc(); + return 0; + break; +*/ + case SDLK_F1: + if(!toggleFullscreen())return 0; + break; + + default: + break; + } + break; + + case SDL_USEREVENT: + switch(event.user.code) + { + case USR_EVT_TIMER: + drawScreen(); + eventScreen(); + break; + + default: + break; + } + break; + + // Zmena velikosti okna + case SDL_VIDEORESIZE: + screen = SDL_SetVideoMode(event.resize.w,event.resize.h, WIN_BPP, g_win_flags); + + if(screen == NULL) + { + fprintf(stderr, "Nemozem zmenit rozlisene okna: %s\n",SDL_GetError()); + return 0; + } + break; + + // Pozadavek na ukonceni + case SDL_QUIT: + return -1; + break; + + default: + break; + } + } + + return 0; +} + +void eventSDL() +{ + while(1) + { + if ( eventAction() == -1 )return; + } +} + +void quitSDL() +{ + printf("quit SDL..\n"); + SDL_Quit(); + isInterfaceInit = FALSE; +} diff --git a/src/item.c b/src/item.c new file mode 100644 index 0000000..06e932b --- /dev/null +++ b/src/item.c @@ -0,0 +1,386 @@ + +#include <stdlib.h> +#include <assert.h> + +#include "main.h" +#include "interface.h" +#include "image.h" +#include "layer.h" +#include "screen_world.h" +#include "screen_setting.h" +#include "net_multiplayer.h" +#include "tux.h" +#include "item.h" +#include "shot.h" + +static SDL_Surface *g_item[ITEM_COUNT]; + +static bool_t isItemInit = FALSE; + +bool_t isItemInicialized() +{ + return isItemInit; +} + +void initItem() +{ + 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[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); + + isItemInit = TRUE; +} + +item_t* newItem(int x, int y, int type) +{ + item_t *new; + + new = malloc( sizeof(item_t) ); + assert( new != NULL ); + + new->type = type; + + new->x = x; + new->y = y; + new->frame = 0; + new->count = 0; + new->img = g_item[type]; + + switch( type ) + { + case GUN_DUAL_SIMPLE : + case GUN_SCATTER : + case GUN_TOMMY : + case GUN_LASSER : + case GUN_MINE : + 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 : + new->w = ITEM_EXPLOSION_WIDTH; + new->h = ITEM_EXPLOSION_HEIGHT; + break; + + case ITEM_BIG_EXPLOSION : + 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; +} + +void addNewItem(list_t *listItem) +{ + arena_t *arena; + item_t *item; + int new_x, new_y; + int type; + + if( isSettingAnyItem() == FALSE || + getNetTypeGame() == NET_GAME_TYPE_CLIENT ) + { + return; + } + + arena = getWorldArena(); + findFreeSpace(&new_x, &new_y, ITEM_GUN_WIDTH, ITEM_GUN_HEIGHT); + + do{ + switch( random() % 10 ) + { + case 0 : type = GUN_DUAL_SIMPLE; + break; + case 1 : type = GUN_SCATTER; + break; + case 2 : type = GUN_MINE; + break; + case 3 : type = GUN_LASSER; + break; + case 4 : type = BONUS_SPEED; + break; + case 5 : type = BONUS_SHOT; + break; + case 6 : type = BONUS_TELEPORT; + break; + case 7 : type = BONUS_GHOST; + break; + case 8 : type = BONUS_4X; + break; + case 9 : type = BONUS_HIDDEN; + break; + } + }while( isSettingItem(type) == FALSE ); + + item = newItem(new_x, new_y, type); + addList(listItem, item); + + if( getNetTypeGame() == NET_GAME_TYPE_SERVER ) + { + proto_send_additem(item); + } +} + +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); + } +} + +void eventListItem(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 ); + + 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 : + 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 ) + { + delListItem(listItem, i, 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; + } + } +} + +int isConflictWithListItem(list_t *listItem, int x, int y, int w, int h) +{ + 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( conflictSpace(x, y, w, h, + thisItem->x, thisItem->y, thisItem->w, thisItem->h) ) + { + return 1; + } + } + + return 0; +} + +void eventConflictShotWithItem(list_t *listItem, list_t *listShot) +{ + shot_t *thisShot; + item_t *thisItem; + int i, j; + + assert( listItem != NULL ); + assert( listShot != NULL ); + + for( i = 0 ; i < listShot->count ; i++ ) + { + thisShot = (shot_t *)listShot->list[i]; + assert( thisShot != NULL ); + + for( j = 0 ; j < listItem->count ; j++ ) + { + thisItem = (item_t *)listItem->list[j]; + assert( thisItem != NULL ); + + switch( thisItem->type ) + { + case ITEM_MINE : + if( conflictSpace(thisShot->x, thisShot->y, thisShot->w, thisShot->h, + thisItem->x, thisItem->y, thisItem->w, thisItem->h) ) + { + int x, y; + + delListItem(listItem, j, destroyItem); + + x = ( thisItem->x + thisItem->w/2 ) - ITEM_BIG_EXPLOSION_WIDTH/2; + y = ( thisItem->y + thisItem->h/2 ) - ITEM_BIG_EXPLOSION_HEIGHT/2; + + addList(listItem, newItem(x, y, ITEM_BIG_EXPLOSION) ); + j--; + } + break; + case ITEM_EXPLOSION : + case ITEM_BIG_EXPLOSION : + delListItem(listShot, i, destroyShot); + break; + } + } + } +} + +void eventGiveTuxItem(tux_t *tux, list_t *listItem) +{ + item_t *thisItem; + int x, y, w, h; + int i; + + assert( listItem != NULL ); + assert( tux != NULL ); + + if( tux->status == TUX_STATUS_DEAD ) + { + return; + } + + getTuxProportion(tux, &x, &y, &w, &h); + + for( i = 0 ; i < listItem->count ; i++ ) + { + thisItem = (item_t *)listItem->list[i]; + assert( thisItem != NULL ); + + if( conflictSpace(x, y, w, h, thisItem->x, thisItem->y, thisItem->w, thisItem->h) ) + { + switch( thisItem->type ) + { + case GUN_TOMMY : + case GUN_DUAL_SIMPLE : + case GUN_SCATTER : + case GUN_LASSER : + case GUN_MINE : + tux->shot[ thisItem->type ] += GUN_MAX_SHOT; + tux->gun = thisItem->type; + delListItem(listItem, i, destroyItem); + i--; + break; + + case ITEM_MINE : + delListItem(listItem, i, destroyItem); + addList(listItem, newItem(x, y, ITEM_EXPLOSION) ); + i--; + break; + + case ITEM_EXPLOSION : + case ITEM_BIG_EXPLOSION : + if( tux->bonus == BONUS_TELEPORT ) + { + tuxTeleport(tux); + } + else + { + eventTuxIsDead(tux); + } + break; + + case BONUS_SPEED : + case BONUS_SHOT : + case BONUS_TELEPORT : + case BONUS_GHOST : + case BONUS_4X : + case BONUS_HIDDEN : + tux->bonus = thisItem->type; + tux->bonus_time = TUX_MAX_BONUS; + delListItem(listItem, i, destroyItem); + i--; + break; + + } + } + + } +} + +void destroyItem(item_t *p) +{ + assert( p != NULL ); + free(p); +} + +void quitItem() +{ + isItemInit = FALSE; +} diff --git a/src/layer.c b/src/layer.c new file mode 100755 index 0000000..0ea2bfe --- /dev/null +++ b/src/layer.c @@ -0,0 +1,115 @@ + +#include <stdlib.h> +#include <assert.h> + +#include "main.h" +#include "interface.h" +#include "list.h" +#include "layer.h" +#include "image.h" + +static list_t *listLayer; + +static bool_t isLayerInit = FALSE; + +bool_t isLayerInicialized() +{ + return isLayerInit; +} + +/* + * Inicializuje globalny zoznam vsrtiev + */ +void initLayer() +{ + listLayer = newList(); +} + +/* + * Prida novu polozku do zoznamu vrstiev + * *img - obrazok, ktory obsahuje polozka + * x y w h - suradnca kam sa obrazok vykresli a jeho rozmery + * px py pw ph - suradnica casti obrazka *img ktora sa ma zobrazit + * layer - vrstva na ktorej sa zobrazi obrazok + */ +void addLayer(SDL_Surface *img, + int x,int y, int px,int py, + int w,int h, int player) +{ + layer_t *new; + layer_t *this; + int i; + + assert( img != NULL ); + + new = malloc( sizeof(layer_t) ); + new->x = x; + new->y = y; + new->w = w; + new->h = h; + new->px = px; + new->py = py; + new->layer = player; + new->image = img; + + if( listLayer->count == 0 ) + { + addList(listLayer, new); + return; + } + + i = 0; + this = (layer_t *)listLayer->list[0]; + + //vyhladaj svoju vrstvu + while( i < listLayer->count && this->layer < new->layer ) + { + this = (layer_t *)listLayer->list[++i]; + } + + //porovnaj s vyskami na tvojej vrstve, + //ak neexistuje, rovno to tam hod + this = (layer_t *)listLayer->list[i]; + + while( i < listLayer->count && this->y+this->h < new->y+new->h && new->layer == this->layer ) + { + this = (layer_t *)listLayer->list[++i]; + } + + insList(listLayer, i, new); + isLayerInit = TRUE; +} + +/* + * Vykresli vsetky polozky na obrazovku + * poukadane podla vrstvy a suradnice Y+H + * po dokresleni sa zoznam uvolni. + */ +void drawLayer() +{ + layer_t *this; + int i; + + for( i = 0 ; i < listLayer->count ; i++ ) + { + this = (layer_t *)listLayer->list[i]; + + drawImage(this->image, + this->x, this->y, + this->px, this->py, + this->w, this->h); + } + + destroyListItem(listLayer, free); + listLayer = newList(); +} + +/* + * Odstrani zoznam vrtsiev z pamete. + */ +void quitLayer() +{ + destroyListItem(listLayer, free); + isLayerInit = FALSE; +} + diff --git a/src/list.c b/src/list.c new file mode 100755 index 0000000..64dae27 --- /dev/null +++ b/src/list.c @@ -0,0 +1,235 @@ + +#include "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 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/logFile.c b/src/logFile.c new file mode 100644 index 0000000..12a4df8 --- /dev/null +++ b/src/logFile.c @@ -0,0 +1,46 @@ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <sys/stat.h> +#include <assert.h> + +typedef struct logFile_struct +{ + char *name; + FILE *file; +} logFile_t; + +logFile_t* newLogFile(char *s) +{ + logFile_t *new; + + assert( s != NULL ); + + new = malloc( sizeof(logFile_t) ); + memset(new, 0, sizeof(logFile_t) ); + + new->name = strdup(s); + new->file = fopen(new->name, "a+"); + + assert( new->file != NULL ); + + return new; +} + +int writeLog(logFile_t *p, char *s) +{ + assert( p != NULL ); + assert( s != NULL ); + + return fprintf(p->file, s); +} + +void destroyLogFile(logFile_t *p) +{ + assert( p != NULL ); + + free(p->name); + fclose(p->file); + free(p); +} diff --git a/src/main.c b/src/main.c new file mode 100644 index 0000000..16cd11e --- /dev/null +++ b/src/main.c @@ -0,0 +1,113 @@ + +#include <time.h> + +#include "interface.h" +#include "main.h" +#include "font.h" +#include "image.h" +#include "layer.h" +#include "tux.h" +#include "screen.h" +#include "screen_world.h" +#include "screen_mainMenu.h" +#include "screen_analyze.h" +#include "screen_setting.h" +#include "screen_gameType.h" +#include "wall.h" +#include "shot.h" +#include "panel.h" +#include "myTimer.h" +#include "arenaFile.h" +#include "audio.h" +#include "sound.h" +#include "music.h" +#include "item.h" + +static int my_argc; +static char **my_argv; + +static void init() +{ + initSDL(); + initLayer(); + initFont("DejaVuSans.ttf", 16); + initImageData(); + initAudio(); + initSound(); + initMusic(); + initScreen(); + initArenaFile(); + initTux(); + initItem(); + initShot(); + initPanel(); + initWorld(); + initScreenMainMenu(); + initScreenAnalyze(); + initScreenSetting(); + initScreenGameType(); +} + +void quit() +{ + quitSDL(); + quitLayer(); + quitFont(); + quitScreen(); + quitArenaFile(); + quitItem(); + quitTux(); + quitShot(); + quitPanel(); + quitWorld(); + quitImageData(); + quitSound(); + quitMusic(); + quitAudio(); + quitScreenMainMenu(); + quitScreenAnalyze(); + quitScreenSetting(); + quitScreenGameType(); + + exit(0); +} + +char* getParam(char *s) +{ + int i; + + for( i = 0 ; i < my_argc - 1 ; i++ ) + { + if( strcmp(s, my_argv[i]) == 0 ) + { + return my_argv[i+1]; + } + } + + return NULL; +} + +char *getString(int n) +{ + char str[STR_NUM_SIZE]; + sprintf(str, "%d", n); + return strdup(str); +} + +int main(int argc, char *argv[]) +{ + srand( (unsigned) time(NULL) ); + + my_argc = argc; + my_argv = argv; + + init(); + + setScreen("mainMenu"); + + eventSDL(); + quit(); + + return 0; +} + diff --git a/src/music.c b/src/music.c new file mode 100644 index 0000000..2459787 --- /dev/null +++ b/src/music.c @@ -0,0 +1,158 @@ + +#include <stdio.h> +#include <stdlib.h> +#include <assert.h> + +#include "main.h" +#include "interface.h" +#include "list.h" +#include "path.h" +#include "string_length.h" +#include "audio.h" +#include "music.h" + +static list_t *listMusic; + +static bool_t isMusicInit = FALSE; +static music_t *currentMusic; + +bool_t isMusicInicialized() +{ + return isMusicInit; +} + +void initMusic() +{ + assert( isAudioInicialized() ); + + listMusic = newList(); + currentMusic = NULL; + + isMusicInit = TRUE; + printf("init music..\n"); +} + +static Mix_Music* loadMixMusic(char *file) +{ + Mix_Music *new; + char str[STR_PATH_SIZE]; + + printf("load music %s..\n", file); + sprintf(str, PATH_MUSIC "%s", file); + + new = Mix_LoadMUS(str); + + if( new == NULL ) + { + fprintf(stderr, "Nepodarilo sa nacitat hudbu %s\n", file); + return NULL; + } + + return new; +} + +static music_t *newMusic(char *file, char *name, int group) +{ + music_t *new; + + new = malloc( sizeof(music_t) ); + new->name = strdup(name); + new->group = group; + new->music = loadMixMusic(file); + + return new; +} + +static void playMixMusic() +{ + printf("play music %s..\n", currentMusic->name); + Mix_PlayMusic(currentMusic->music, 1000); +} + +static void destroyMusic(music_t *p) +{ + free(p->name); + Mix_FreeMusic(p->music); + free(p); +} + +void addMusic(char *file, char *name, int group) +{ + addList( listMusic, newMusic(file, name, group) ); +} + +void stopMusic() +{ + if( currentMusic != NULL ) + { + printf("stop music %s..\n", currentMusic->name); + Mix_HaltMusic(); + currentMusic = NULL; + } +} + +void playMusic(char *name, int group) +{ + int i; + music_t *this; + + if( currentMusic != NULL && + currentMusic->group == group && + strcmp(currentMusic->name, name) == 0 ) + { + return; + } + + if( currentMusic != NULL ) + { + stopMusic(); + } + + for( i = 0 ; i < listMusic->count ; i++ ) + { + this = (music_t *)listMusic->list[i]; + + if( this->group == group && strcmp(this->name, name) == 0 ) + { + currentMusic = this; + break; + } + } + + if( currentMusic != NULL ) + { + playMixMusic(); + } +} + +char* getCurrentMusic() +{ + return currentMusic->name; +} + +void delAllMusicInGroup(int group) +{ + int i; + music_t *this; + + for( i = 0 ; i < listMusic->count ; i++ ) + { + this = (music_t *)listMusic->list[i]; + + if( this->group == group ) + { + delListItem(listMusic, i, destroyMusic); + break; + } + } +} + +void quitMusic() +{ + stopMusic(); + destroyListItem(listMusic, destroyMusic); + isMusicInit = FALSE; + + printf("quit music..\n"); +} + diff --git a/src/myTimer.c b/src/myTimer.c new file mode 100644 index 0000000..1faca9b --- /dev/null +++ b/src/myTimer.c @@ -0,0 +1,101 @@ + +#include <time.h> +#include <assert.h> +#include <stdlib.h> + +#include "main.h" +#include "interface.h" +#include "list.h" +#include "myTimer.h" + +static list_t *listTime; + +static bool_t isTimerInit = FALSE; + +bool_t isMyTimerInicialized() +{ + return isTimerInit; +} + +void initTimer() +{ + assert( isInterfaceInicialized() == TRUE ); + + listTime = newList(); + isTimerInit = TRUE; +} + +int addTimer(void (*fce)(void *p), void *arg, int my_time) +{ + static int new_id = 0; + my_timer_t *new; + Uint32 currentTime; + + currentTime = SDL_GetTicks(); + + new = malloc( sizeof(my_timer_t) ); + assert( new != NULL ); + + new->id = new_id++; + new->fce = fce; + new->arg = arg; + new->time = currentTime + my_time; + + addList(listTime, new); + + return new->id; +} + +void eventTimer() +{ + int i; + my_timer_t *thisTimer; + Uint32 currentTime; + + currentTime = SDL_GetTicks(); + + for( i = 0 ; i < listTime->count ; i++ ) + { + thisTimer = (my_timer_t *)listTime->list[i]; + assert( thisTimer != NULL ); + + if( currentTime >= thisTimer->time ) + { + thisTimer->fce(thisTimer->arg); + delListItem(listTime, i, free); + i--; + } + } +} + +void delTimer(int id) +{ + int i; + my_timer_t *thisTimer; + + for( i = 0 ; i < listTime->count ; i++ ) + { + thisTimer = (my_timer_t *)listTime->list[i]; + assert( thisTimer != NULL ); + + if( thisTimer->id == id ) + { + delListItem(listTime, i, free); + return; + } + } + + assert( ! "Uloha s id nenajdena !" ); +} + +void delAllItemTimer() +{ + quitTimer(); + initTimer(); +} + +void quitTimer() +{ + destroyListItem(listTime, free); + isTimerInit = FALSE; +} diff --git a/src/net_multiplayer.c b/src/net_multiplayer.c new file mode 100644 index 0000000..66f3720 --- /dev/null +++ b/src/net_multiplayer.c @@ -0,0 +1,640 @@ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <assert.h> +#include <unistd.h> + +#include "list.h" +#include "tux.h" +#include "item.h" +#include "network.h" +#include "buffer.h" +#include "string_length.h" +#include "screen.h" +#include "screen_world.h" +#include "screen_setting.h" +#include "net_multiplayer.h" + +static int netGameType; +static int sock_server; + +static list_t *listClient; +static buffer_t *clientBuffer; +static arena_t *arena; + +int initServer(int port) +{ + sock_server = newSocket(port , NULL); + + if( sock_server < 0 ) + { + return -1; + } + + listClient = newList(); + netGameType = NET_GAME_TYPE_SERVER; + + printf("server listen port %d\n", port); + + return 0; +} + +int initClient(int port, char *ip) +{ + sock_server = newSocket(port , ip); + + if( sock_server < 0 ) + { + return -1; + } + + clientBuffer = newBuffer( LIMIT_BUFFER ); + netGameType = NET_GAME_TYPE_CLIENT; + + printf("connect %s %d\n", ip, port); + + return 0; +} + +void netSetArena(arena_t *p) +{ + arena = p; +} + +int getNetTypeGame() +{ + return netGameType; +} + +static void sendServer(char *msg) +{ + int ret; + + ret = write(sock_server, msg, strlen(msg)); + + if ( ret == 0 ) + { + fprintf(stderr, "server uzatvoril sietovy socket\n"); + setScreen("analyze"); + } + + if ( ret < 0 ) + { + fprintf(stderr, "nastala chyba pri poslani spravy serveru\n"); + setScreen("analyze"); + } +} + +static void sendClient(client_t *p, char *msg) +{ + if( p->status == NET_STATUS_OK ) + { + int ret; + + ret = write(p->socket, msg, strlen(msg)); + + if( ret == 0 ) + { + fprintf(stderr, "client sa odpojil\n"); + p->status = NET_STATUS_ZOMBIE; + } + + if( ret < 0 ) + { + fprintf(stderr, "nastala chyba pri posielanie spravy clientovy\n"); + p->status = NET_STATUS_ZOMBIE; + } + } +} + +static void sendAllClientBut(char *msg, client_t *p) +{ + client_t *thisClient; + int i; + + for( i = 0 ; i < listClient->count; i++) + { + thisClient = (client_t *) listClient->list[i]; + + if( thisClient != p ) + { + sendClient(thisClient, msg); + } + } +} + +static void sendAllClient(char *msg) +{ + sendAllClientBut(msg, NULL); +} + +static void sendNetwork(char *msg) +{ + switch( netGameType ) + { + case NET_GAME_TYPE_SERVER : + sendAllClient(msg); + break; + case NET_GAME_TYPE_CLIENT : + sendServer(msg); + break; + } +} + +static client_t* newClient(int sock) +{ + client_t *new; + + new = malloc( sizeof(client_t) ); + memset(new, 0, sizeof(client_t)); + + new->socket = sock; + new->status = NET_STATUS_OK; + new->buffer = newBuffer(LIMIT_BUFFER); + new->tux = newTux(); + new->tux->control = TUX_CONTROL_NET; + addList(arena->listTux, new->tux); + + return new; +} + +static void destroyClient(client_t *p) +{ + int index; + + close(p->socket); + destroyBuffer(p->buffer); + index = searchListItem(arena->listTux, p->tux); + delListItem(arena->listTux, index, destroyTux); + free(p); +} + +static void proto_send_init(client_t *p) +{ + char msg[STR_SIZE]; + + sprintf(msg, "init %d\n", p->tux->id); + sendClient(p, msg); +} + +void proto_send_settux(tux_t *p) +{ + char msg[STR_SIZE]; + + sprintf(msg, "settux %d %d %d %d %d\n", + p->id ,p->x, p->y, p->position ,p->frame); + + sendNetwork(msg); +} + +void proto_send_deltux(tux_t *p) +{ + char msg[STR_SIZE]; + + sprintf(msg, "deltux %d\n", p->id); + + sendNetwork(msg); +} + +void proto_send_shottux(tux_t *p) +{ + char msg[STR_SIZE]; + + sprintf(msg, "shottux %d\n", p->id); + + sendNetwork(msg); +} + +void proto_send_switchgun(tux_t *p) +{ + char msg[STR_SIZE]; + + sprintf(msg, "switchgun %d %d\n", p->id, p->gun); + + sendNetwork(msg); +} + +void proto_send_additem(item_t *p) +{ + char msg[STR_SIZE]; + + sprintf(msg, "additem %d %d %d\n", p->type, p->x, p->y); + + sendNetwork(msg); +} + +void proto_send_context(tux_t *p) +{ + char msg[STR_SIZE]; + + sprintf(msg, "context %d %s\n", p->id, p->name); + + sendNetwork(msg); +} + +static void proto_recv_init(char *msg) +{ + char cmd[STR_SIZE]; + tux_t *tux; + + tux = newTux(); + + sscanf(msg, "%s %d\n", cmd, &tux->id); + + tux->control = TUX_CONTROL_KEYBOARD_RIGHT; + getSettingNameRight(tux->name); + proto_send_context(tux); + addList(arena->listTux, tux); +} + +static void proto_recv_settux(char *msg) +{ + char cmd[STR_SIZE]; + int a, b, c, d, e; + tux_t *tux; + + sscanf(msg, "%s %d %d %d %d %d", cmd, &a, &b, &c, &d, &e); + + tux = getTuxID(arena->listTux, a); + + if( tux == NULL ) + { + tux = newTux(); + tux->control = TUX_CONTROL_NET; + addList(arena->listTux, tux); + } + + tux->id = a; + tux->x = b; + tux->y = c; + tux->position = d; + tux->frame = e; + tux->status = TUX_STATUS_ALIVE; + + // ??? + //eventGiveTuxItem(tux, arena->listItem); +} + +static void proto_recv_deltux(char *msg) +{ + char cmd[STR_SIZE]; + int id; + tux_t *tux; + + sscanf(msg, "%s %d\n", cmd, &id); + + tux = getTuxID(arena->listTux, id); + + if( tux != NULL ) + { + int index; + + index = searchListItem(arena->listTux, tux); + delListItem(arena->listTux, index, destroyTux); + } +} + +static void proto_recv_shottux(char *msg) +{ + char cmd[STR_SIZE]; + int id; + tux_t *tux; + + sscanf(msg, "%s %d\n", cmd, &id); + + tux = getTuxID(arena->listTux, id); + + if( tux != NULL ) + { + shotTux(tux); + } +} + +void proto_recv_switchgun(char *msg) +{ + char cmd[STR_SIZE]; + int id, gun; + tux_t *tux; + + sscanf(msg, "%s %d %d\n", cmd, &id, &gun); + + tux = getTuxID(arena->listTux, id); + + if( tux != NULL ) + { + tux->gun = gun; + } +} + +void proto_recv_additem(char *msg) +{ + char cmd[STR_SIZE]; + int type, x, y; + item_t *item; + + sscanf(msg, "%s %d %d %d\n", cmd, &type, &x, &y); + + item = newItem(x, y, type); + + if( isConflictWithListItem(arena->listItem, item->x, item->y, item->w, item->h) ) + { + destroyItem(item); + return; + } + + addList(arena->listItem, item); +} + +void proto_recv_context(char *msg) +{ + char cmd[STR_SIZE]; + char name[STR_NAME_SIZE]; + int id; + tux_t *tux; + + sscanf(msg, "%s %d %s\n", cmd, &id, name); + + tux = getTuxID(arena->listTux, id); + + if( tux != NULL ) + { + strcpy(tux->name, name); + } +} + +static void eventCreateNewClient(int sock) +{ + client_t *new; + tux_t *thisTux; + item_t *thisItem; + int i; + + new = newClient( getNewClient(sock) ); + addList(listClient, new); + + proto_send_init(new); + + for( i = 0 ; i < arena->listTux->count; i++) + { + thisTux = (tux_t *) arena->listTux->list[i]; + + proto_send_settux(thisTux); + + if( thisTux != new->tux ) + { + proto_send_context(thisTux); + } + } + + for( i = 0 ; i < arena->listItem->count; i++) + { + thisItem = (item_t *) arena->listItem->list[i]; + proto_send_additem(thisItem); + } +} + +static void eventClientSelect(client_t *client) +{ + char buffer[STR_SIZE]; + int ret; + + assert( client != NULL ); + + memset(buffer, 0, STR_SIZE); + ret = read(client->socket, buffer, STR_SIZE-1); + + if( ret <= 0 ) + { + client->status = NET_STATUS_ZOMBIE; + return; + } + + if( addBuffer(client->buffer, buffer, ret) != 0 ) + { + client->status = NET_STATUS_ZOMBIE; + return; + } +} + +static void eventClientBuffer(client_t *client) +{ + char line[STR_SIZE]; + + if( netGameType == NET_GAME_TYPE_NONE ) + { + return; + } + + /* obsluha udalosti od clientov */ + + while( getBufferLine(client->buffer, line, STR_SIZE) >= 0 ) + { + sendAllClientBut(line, client); + + if( strncmp(line, "settux", 6) == 0 )proto_recv_settux(line); + if( strncmp(line, "shottux", 7) == 0 )proto_recv_shottux(line); + if( strncmp(line, "switchgun", 9) == 0 )proto_recv_switchgun(line); + if( strncmp(line, "additem", 7) == 0 )proto_recv_additem(line); + if( strncmp(line, "context", 7) == 0 )proto_recv_context(line); + } +} + +static void eventClientListBuffer() +{ + client_t *thisClient; + int i; + + for( i = 0 ; i < listClient->count; i++) + { + thisClient = (client_t *) listClient->list[i]; + eventClientBuffer(thisClient); + } +} + +static void selectServerSocket() +{ + fd_set readfds; + struct timeval tv; + client_t *thisClient; + int max_fd; + int i; + + tv.tv_sec = 0; + tv.tv_usec = 0; + + FD_ZERO(&readfds); + FD_SET(sock_server, &readfds); + max_fd = sock_server; + + for( i = 0 ; i < listClient->count; i++) + { + thisClient = (client_t *) listClient->list[i]; + + FD_SET(thisClient->socket, &readfds); + + if( thisClient->socket > max_fd ) + { + max_fd = thisClient->socket; + } + } + + select(max_fd+1, &readfds, (fd_set *)NULL, (fd_set *)NULL, &tv); + + if( FD_ISSET(sock_server, &readfds) ) + { + eventCreateNewClient(sock_server); + } + + for( i = 0 ; i < listClient->count; i++) + { + thisClient = (client_t *) listClient->list[i]; + + if( FD_ISSET(thisClient->socket, &readfds) ) + { + eventClientSelect(thisClient); + } + + if( thisClient->status == NET_STATUS_ZOMBIE ) + { + proto_send_deltux(thisClient->tux); + delListItem(listClient, i, destroyClient); + } + } +} + +static void eventServerSelect(int sock) +{ + char buffer[STR_SIZE]; + int ret; + + memset(buffer,0 ,STR_SIZE); + ret = read(sock, buffer, STR_SIZE-1); + + if( ret == 0 ) + { + fprintf(stderr, "server uzatovril sietovy socket\n"); + setScreen("analyze"); + return; + } + + if( ret < 0 ) + { + fprintf(stderr, "chyba, spojenie prerusene \n"); + setScreen("analyze"); + return; + } + + if( addBuffer(clientBuffer, buffer, ret) != 0 ) + { + fprintf(stderr, "chyba, nemozem zapisovat do mojho buffera !\n"); + setScreen("analyze"); + return; + } +} + +static void eventServerBuffer() +{ + char line[STR_SIZE]; + + if( netGameType == NET_GAME_TYPE_NONE ) + { + return; + } + + /* obsluha udalosti od servera */ + + while ( getBufferLine(clientBuffer, line, STR_SIZE) >= 0 ) + { + //printf("dostal som %s\n", line); + + if( strncmp(line, "init", 4) == 0 )proto_recv_init(line); + if( strncmp(line, "settux", 6) == 0 )proto_recv_settux(line); + if( strncmp(line, "deltux", 6) == 0 )proto_recv_deltux(line); + if( strncmp(line, "shottux", 7) == 0 )proto_recv_shottux(line); + if( strncmp(line, "switchgun", 9) == 0 )proto_recv_switchgun(line); + if( strncmp(line, "additem", 7) == 0 )proto_recv_additem(line); + if( strncmp(line, "context", 7) == 0 )proto_recv_context(line); + } +} + +static void selectClientSocket() +{ + fd_set readfds; + struct timeval tv; + int max_fd; + + tv.tv_sec = 0; + tv.tv_usec = 0; + + FD_ZERO(&readfds); + FD_SET(sock_server, &readfds); + max_fd = sock_server; + + select(max_fd+1, &readfds, (fd_set *)NULL, (fd_set *)NULL, &tv); + + if( FD_ISSET(sock_server, &readfds) ) + { + eventServerSelect(sock_server); + } +} + +void eventNetMultiplayer() +{ + switch( netGameType ) + { + case NET_GAME_TYPE_NONE : + break; + + case NET_GAME_TYPE_SERVER : + selectServerSocket(); + eventClientListBuffer(); + break; + + case NET_GAME_TYPE_CLIENT : + selectClientSocket(); + eventServerBuffer(); + break; + + default : + assert( ! "Premenna netGameType ma zlu hodnotu !" ); + break; + } +} + +static void quitServer() +{ + destroyListItem(listClient, destroyClient); + close(sock_server); + printf("quit port\n"); +} + +static void quitClient() +{ + destroyBuffer(clientBuffer); + close(sock_server); + printf("quit conenct\n"); +} + +void quitNetMultiplayer() +{ + switch( netGameType ) + { + case NET_GAME_TYPE_NONE : + break; + + case NET_GAME_TYPE_SERVER : + quitServer(); + break; + + case NET_GAME_TYPE_CLIENT : + quitClient(); + break; + + default : + assert( ! "Premenna netGameType ma zlu hodnotu !" ); + break; + } + + netGameType = NET_GAME_TYPE_NONE; +} diff --git a/src/network.c b/src/network.c new file mode 100755 index 0000000..ebd209a --- /dev/null +++ b/src/network.c @@ -0,0 +1,99 @@ + +#include "network.h" + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include <sys/types.h> +#include <sys/socket.h> +#include <stdio.h> +#include <netinet/in.h> +#include <arpa/inet.h> +#include <unistd.h> +#include <assert.h> + +int newSocket(int port,const char *ip) +{ + struct sockaddr_in address; + int sockfd; + int len; + + assert( port > 0 && port < 65535 ); + + sockfd = socket(AF_INET, SOCK_STREAM, 0); + + if( sockfd < 0 ) + { + fprintf(stderr, "Nemozem vytvorit sietovy socket\n"); + return -1; + } + + address.sin_family = AF_INET; + + if( ip != NULL ) + address.sin_addr.s_addr = inet_addr(ip); + else + address.sin_addr.s_addr = htonl(INADDR_ANY); + + address.sin_port = htons(port); + + len = sizeof(address); + + if( ip == NULL ) + { + if ( bind(sockfd, (struct sockaddr *)&address, len) < 0 ) + { + fprintf(stderr, "Nemozem obsadit sietovy port %d\n", port); + return -1; + } + + listen(sockfd, 5); + } + else + { + if ( connect(sockfd, (struct sockaddr *)&address, len) < 0 ) + { + fprintf(stderr, "Nemozem sa pripojit na %s %d\n", ip, port); + return -1; + } + } + + return sockfd; +} + +int getNewClient(int sockfd) +{ + struct sockaddr_in client_address; + int client_sockfd; + int client_len; + + assert( sockfd >= 0 ); + + client_len = sizeof(client_address); + + client_sockfd = accept(sockfd, (struct sockaddr *)&client_address, + (socklen_t *)&client_len); + + //printf("ip = %s\n",inet_ntoa(client_address.sin_addr)); + + return client_sockfd; +} + +int getNewClientIP(int sockfd,char **str_ip) +{ + struct sockaddr_in client_address; + int client_sockfd; + int client_len; + + assert( sockfd >= 0 ); + + client_len = sizeof(client_address); + + client_sockfd = accept(sockfd, (struct sockaddr *)&client_address, + (socklen_t *)&client_len); + + *str_ip = strdup( inet_ntoa(client_address.sin_addr) ); + + return client_sockfd; +} diff --git a/src/panel.c b/src/panel.c new file mode 100644 index 0000000..1e93084 --- /dev/null +++ b/src/panel.c @@ -0,0 +1,189 @@ + +#include <stdio.h> +#include <assert.h> + +#include "main.h" +#include "interface.h" +#include "string_length.h" +#include "image.h" +#include "list.h" +#include "font.h" +#include "tux.h" +#include "panel.h" + +static SDL_Surface *g_panel; +static SDL_Surface *g_shot; +static SDL_Surface *g_icon[ITEM_COUNT]; +static SDL_Surface *g_bonus; + +static bool_t isPanelInit = FALSE; + +bool_t isPanelInicialized() +{ + return isPanelInit; +} + +void initPanel() +{ + assert( isImageInicialized() == TRUE ); + assert( isInterfaceInicialized() == TRUE ); + + g_panel = addImageData("panel.png", IMAGE_ALPHA, "panel", IMAGE_GROUP_BASE); + g_shot = addImageData("panel_shot.png", IMAGE_ALPHA, "panel_image_shot", IMAGE_GROUP_BASE); + g_bonus = addImageData("graf.bonus.png", IMAGE_ALPHA, "panel_graf_bonus", IMAGE_GROUP_BASE); + + g_icon[GUN_SIMPLE] = addImageData("icon.gun.simple.png", IMAGE_ALPHA, "panel_gun", IMAGE_GROUP_BASE); + g_icon[GUN_DUAL_SIMPLE] = addImageData("icon.gun.dual.simple.png", IMAGE_ALPHA, "panel_dual", IMAGE_GROUP_BASE); + g_icon[GUN_TOMMY] = addImageData("icon.gun.tommy.png", IMAGE_ALPHA, "panel_tommy", IMAGE_GROUP_BASE); + g_icon[GUN_SCATTER] = addImageData("icon.gun.scatter.png", IMAGE_ALPHA, "panel_scatter", IMAGE_GROUP_BASE); + g_icon[GUN_LASSER] = addImageData("icon.gun.lasser.png", IMAGE_ALPHA, "panel_lasser", IMAGE_GROUP_BASE); + g_icon[GUN_MINE] = addImageData("icon.gun.mine.png", IMAGE_ALPHA, "panel_mine", IMAGE_GROUP_BASE); + + g_icon[BONUS_SPEED] = addImageData("icon.bonus.speed.png", IMAGE_ALPHA, "panel_speed", IMAGE_GROUP_BASE); + g_icon[BONUS_SHOT] = addImageData("icon.bonus.shot.png", IMAGE_ALPHA, "panel_shot", IMAGE_GROUP_BASE); + g_icon[BONUS_TELEPORT] = addImageData("icon.bonus.teleport.png", IMAGE_ALPHA, "panel_teleport", IMAGE_GROUP_BASE); + g_icon[BONUS_GHOST] = addImageData("icon.bonus.ghost.png", IMAGE_ALPHA, "panel_ghost", IMAGE_GROUP_BASE); + g_icon[BONUS_4X] = addImageData("icon.bonus.4x.png", IMAGE_ALPHA, "panel_4x", IMAGE_GROUP_BASE); + g_icon[BONUS_HIDDEN] = addImageData("icon.bonus.hidden.png", IMAGE_ALPHA, "panel_hidden", IMAGE_GROUP_BASE); + + isPanelInit = TRUE; +} + +static void setScoreline(list_t *listTux, char *str) +{ + tux_t *thisTux; + int i; + + assert( listTux != NULL ); + assert( str != NULL ); + + strcpy(str, ""); + + for( i = 0 ; i < listTux->count ; i++ ) + { + char num[STR_SIZE]; + + thisTux = (tux_t *)listTux->list[i]; + assert( thisTux != NULL ); + + sprintf(num, "%s%d", ( i == 0 ? "" : " : " ), thisTux->score); + strcat(str, num); + } +} + +static void drawScore(list_t *listTux) +{ + char strScoreLine[STR_SIZE]; + int w, h; + + assert( listTux != NULL ); + + setScoreline(listTux, strScoreLine); + getTextSize(strScoreLine, &w , &h); + drawFont(strScoreLine, PANEL_SCORE_LOCATION_X, PANEL_SCORE_LOCATION_Y, COLOR_WHITE); +} + +static void drawShot(int n, int x, int y) +{ + drawImage(g_shot, x, y,n * PANEL_SHOT_WIDTH, 0, PANEL_SHOT_WIDTH, PANEL_SHOT_HEIGHT); +} + +static void drawShotInfo(tux_t *tux,int x, int y) +{ + int i; + + if( tux->pickup_time > 0 ) + { + for( i = 0 ; i < tux->pickup_time / 3 ; i++ ) + { + drawShot(PANEL_SHOT_LINE, x + i * PANEL_SHOT_WIDTH, y); + } + + return; + } + + for( i = 0 ; i < GUN_MAX_SHOT ; i++ ) + { + if( tux->shot[tux->gun] > i ) + { + drawShot(PANEL_SHOT_FILL, x + i * ( PANEL_SHOT_WIDTH + 2 ), y); + } + else + { + drawShot(PANEL_SHOT_EMPTY, x + i * ( PANEL_SHOT_WIDTH + 2 ) , y); + } + } +} + +static void drawGunInfo(tux_t *tux,int x, int y) +{ + drawImage(g_icon[ tux->gun ], x, y, 0, 0, + g_icon[ tux->gun ]->w, g_icon[ tux->gun ]->h); +} + +static void drawBonusInfo(tux_t *tux,int x, int y) +{ + drawImage(g_icon[ tux->bonus ], x, y, 0, 0, g_icon[ tux->bonus ]->w, g_icon[ tux->bonus ]->h); +} + +static void drawGrafBonus(tux_t *tux,int x, int y) +{ + int offset; + + offset = tux->bonus_time / 5; + drawImage(g_bonus, x, y, 0, 0, g_bonus->w, g_bonus->h/2); + drawImage(g_bonus, x+1, y, 0, g_bonus->h/2, offset, g_bonus->h/2); +} + +void drawPanel(list_t *listTux) +{ + int i; + + assert( listTux != NULL ); + + drawImage(g_panel, PANEL_LOCATION_X, PANEL_LOCATION_Y, 0, 0, g_panel->w, g_panel->h); + drawScore(listTux); + + for( i = 0 ; i < listTux->count ; i++ ) + { + tux_t *thisTux; + int x, y; + + thisTux = (tux_t *)listTux->list[i]; + assert( thisTux != NULL ); + + x = PANEL_LOCATION_X; + y = PANEL_LOCATION_Y; + + switch( i ) + { + case 0 : + drawShotInfo(thisTux, x+8, y+34); + drawGunInfo(thisTux, x+130, y+30); + + if( thisTux->bonus != BONUS_NONE ) + { + drawGrafBonus(thisTux,x+200, y+50); + drawBonusInfo(thisTux,x+200, y+30); + } + break; + + case 1 : + drawShotInfo(thisTux, x+740, y+34); + drawGunInfo(thisTux, x+620, y+30); + + if( thisTux->bonus != BONUS_NONE ) + { + drawGrafBonus(thisTux,x+460, y+50); + drawBonusInfo(thisTux,x+460, y+30); + } + break; + } + } +} + +void quitPanel() +{ + isPanelInit = FALSE; +} + diff --git a/src/screen.c b/src/screen.c new file mode 100644 index 0000000..c0c6885 --- /dev/null +++ b/src/screen.c @@ -0,0 +1,135 @@ + +#include <assert.h> + +#include "main.h" +#include "interface.h" +#include "screen.h" +#include "list.h" + +static screen_t *currentScreen; +static list_t *listScreen; + +static bool_t isScreenInit = FALSE; + +bool_t isScreenInicialized() +{ + return isScreenInit; +} + +screen_t* newScreen(char *name, + void (*fce_start)(), void (*fce_event)(), + void (*fce_draw)(), void (*fce_stop)()) +{ + screen_t *new; + + assert( name != NULL ); + assert( fce_start != NULL ); + assert( fce_event != NULL ); + assert( fce_draw != NULL ); + assert( fce_stop != NULL ); + + new = malloc( sizeof(screen_t) ); + new->name = strdup(name); + new->fce_start = fce_start; + new->fce_event = fce_event; + new->fce_draw = fce_draw; + new->fce_stop = fce_stop; + + return new; +} + +void destroyScreen(screen_t *p) +{ + assert( p != NULL ); + + free(p->name); + free(p); +} + +void registerScreen(screen_t *p) +{ + assert( p != NULL ); + + printf("register screen %s..\n", p->name); + addList(listScreen, p); +} + +void initScreen() +{ + listScreen = newList(); + currentScreen = NULL; + isScreenInit = TRUE; +} + +void setScreen(char *name) +{ + int i; + screen_t *this; + + assert( name != NULL ); + + if( currentScreen != NULL && + strcmp(currentScreen->name, name) == 0 ) + { + return; + } + + printf("switch screen %s..\n", name); + + for( i = 0 ; i < listScreen->count ; i++ ) + { + this = (screen_t *) (listScreen->list[i]); + assert( this != NULL ); + + if( strcmp(name, this->name) == 0 ) + { + if( currentScreen != NULL ) + { + printf("stop screen %s..\n", currentScreen->name); + currentScreen->fce_stop(); + } + + currentScreen = this; + printf("start screen %s..\n", currentScreen->name); + currentScreen->fce_start(); + + return; + } + } + + assert( ! "screen sa nenasiel !" ); +} + +char* getScreen() +{ + assert( currentScreen != NULL ); + return currentScreen->name; +} + +void drawScreen() +{ + static SDL_Surface *p_screen = NULL; + + if( p_screen == NULL ) p_screen = getSDL_Screen(); + + assert( currentScreen != NULL ); + currentScreen->fce_draw(); + + SDL_Flip(p_screen); +} + +void eventScreen() +{ + assert( currentScreen != NULL ); + + currentScreen->fce_event(); +} + +void quitScreen() +{ + assert( listScreen != NULL ); + + destroyListItem(listScreen, destroyScreen); + isScreenInit = FALSE; +} + diff --git a/src/screen_analyze.c b/src/screen_analyze.c new file mode 100644 index 0000000..815a62e --- /dev/null +++ b/src/screen_analyze.c @@ -0,0 +1,150 @@ + +#include <stdio.h> +#include <assert.h> + +#include "main.h" +#include "interface.h" +#include "screen.h" +#include "image.h" +#include "music.h" +#include "screen_mainMenu.h" +#include "list.h" +#include "screen_analyze.h" + +#include "widget_label.h" +#include "widget_button.h" +#include "widget_image.h" + +static widget_image_t *image_backgorund; + +static list_t *listWidgetLabelName; +static list_t *listWidgetLabelScore; +static list_t *listAnalyze; + +static widget_button_t *button_ok; + +static analyze_t* newAnalyze(char *name, int score) +{ + analyze_t *new; + + new = malloc( sizeof(analyze_t) ); + new->name = strdup(name); + new->score = score; + + return new; +} + +static void destroyAnalyze(analyze_t *p) +{ + free(p->name); + free(p); +} + +void startScreenAnalyze() +{ + playMusic("menu", MUSIC_GROUP_BASE); +} + +void drawScreenAnalyze() +{ + widget_label_t *this; + int i; + + drawWidgetImage(image_backgorund); + + for( i = 0 ; i < listWidgetLabelName->count ; i++ ) + { + this = (widget_label_t *)(listWidgetLabelName->list[i]); + drawWidgetLabel(this); + } + + for( i = 0 ; i < listWidgetLabelScore->count ; i++ ) + { + this = (widget_label_t *)(listWidgetLabelScore->list[i]); + drawWidgetLabel(this); + } + + drawWidgetButton(button_ok); +} + +void eventScreenAnalyze() +{ + eventWidgetButton(button_ok); +} + +void stopScreenAnalyze() +{ +} + +static void eventWidget(void *p) +{ + widget_button_t *button; + + button = (widget_button_t *)(p); + + if( button == button_ok ) + { + setScreen("mainMenu"); + } +} + +void restartAnalyze() +{ + destroyListItem(listWidgetLabelName, destroyWidgetLabel); + destroyListItem(listWidgetLabelScore, destroyWidgetLabel); + destroyListItem(listAnalyze, destroyAnalyze); + + listWidgetLabelName = newList(); + listWidgetLabelScore = newList(); + listAnalyze = newList(); +} + +void addAnalyze(char *name, int score) +{ + addList(listAnalyze, newAnalyze(name, score) ); +} + +void endAnalyze() +{ + analyze_t *this; + int i; + + for( i = 0 ; i < listAnalyze->count ; i++ ) + { + this = (analyze_t *)(listAnalyze->list[i]); + + addList(listWidgetLabelName, newWidgetLabel(this->name, + 100, 200 + 20*i, WIDGET_LABEL_LEFT) ); + + addList(listWidgetLabelScore, newWidgetLabel(getString(this->score), + WINDOW_SIZE_X - 100, 200 + 20*i, WIDGET_LABEL_RIGHT) ); + } +} + +void initScreenAnalyze() +{ + SDL_Surface *image; + + image = getImage(IMAGE_GROUP_BASE, "screen_main"); + image_backgorund = newWidgetImage(0, 0, image); + + listWidgetLabelName = newList(); + listWidgetLabelScore = newList(); + listAnalyze = newList(); + + button_ok = newWidgetButton("OK", WINDOW_SIZE_X/2 -WIDGET_BUTTON_WIDTH/2, + WINDOW_SIZE_Y-100, eventWidget); + + registerScreen( newScreen("analyze", startScreenAnalyze, eventScreenAnalyze, + drawScreenAnalyze, stopScreenAnalyze) ); +} + +void quitScreenAnalyze() +{ + destroyWidgetImage(image_backgorund); + + destroyListItem(listWidgetLabelName, destroyWidgetLabel); + destroyListItem(listWidgetLabelScore, destroyWidgetLabel); + destroyListItem(listAnalyze, destroyAnalyze); +} + diff --git a/src/screen_gameType.c b/src/screen_gameType.c new file mode 100644 index 0000000..3211d62 --- /dev/null +++ b/src/screen_gameType.c @@ -0,0 +1,213 @@ + +#include <stdio.h> +#include <assert.h> + +#include "main.h" +#include "interface.h" +#include "screen.h" +#include "image.h" +#include "music.h" +#include "net_multiplayer.h" +#include "screen_gameType.h" +#include "list.h" +#include "screen_setting.h" +#include "tux.h" + +#include "widget_label.h" +#include "widget_button.h" +#include "widget_image.h" +#include "widget_textfield.h" +#include "widget_check.h" + +static widget_image_t *image_backgorund; + +static widget_button_t *button_back; +static widget_button_t *button_play; + +static widget_label_t *label_none; +static widget_label_t *label_server; +static widget_label_t *label_client; + +static widget_label_t *label_ip; +static widget_label_t *label_port; + +static widget_check_t *check_none; +static widget_check_t *check_server; +static widget_check_t *check_client; + +static widget_textfield_t *textfield_ip; +static widget_textfield_t *textfield_port; + +void startScreenGameType() +{ + playMusic("menu", MUSIC_GROUP_BASE); +} + +void drawScreenGameType() +{ + drawWidgetImage(image_backgorund); + + drawWidgetLabel(label_none); + drawWidgetLabel(label_server); + drawWidgetLabel(label_client); + + if( check_client->status == TRUE ) + { + drawWidgetLabel(label_ip); + drawWidgetTextfield(textfield_ip); + } + + if( check_none->status == FALSE ) + { + drawWidgetLabel(label_port); + drawWidgetTextfield(textfield_port); + } + + drawWidgetCheck(check_none); + drawWidgetCheck(check_server); + drawWidgetCheck(check_client); + + + drawWidgetButton(button_back); + drawWidgetButton(button_play); +} + +void eventScreenGameType() +{ + + eventWidgetCheck(check_none); + eventWidgetCheck(check_server); + eventWidgetCheck(check_client); + + eventWidgetTextfield(textfield_ip); + eventWidgetTextfield(textfield_port); + + eventWidgetButton(button_back); + eventWidgetButton(button_play); +} + +void stopScreenGameType() +{ +} + +static void eventWidget(void *p) +{ + widget_button_t *button; + widget_check_t *check; + + button = (widget_button_t *)(p); + check = (widget_check_t *)(p); + + if( check == check_none ) + { + check_none->status = TRUE; + check_server->status = FALSE; + check_client->status = FALSE; + return; + } + + if( check == check_server ) + { + check_none->status = FALSE; + check_server->status = TRUE; + check_client->status = FALSE; + return; + } + + if( check == check_client ) + { + check_none->status = FALSE; + check_server->status = FALSE; + check_client->status = TRUE; + return; + } + + if( button == button_back ) + { + setScreen("mainMenu"); + } + + if( button == button_play ) + { + setScreen("world"); + } +} + +void initScreenGameType() +{ + SDL_Surface *image; + + image = getImage(IMAGE_GROUP_BASE, "screen_main"); + image_backgorund = newWidgetImage(0, 0, image); + + button_back = newWidgetButton("Back", 100, WINDOW_SIZE_Y-100, eventWidget); + button_play = newWidgetButton("Play", WINDOW_SIZE_X-200, WINDOW_SIZE_Y-100, eventWidget); + + check_none = newWidgetCheck(100, 150, TRUE, eventWidget); + check_server = newWidgetCheck(100, 200, FALSE, eventWidget); + check_client = newWidgetCheck(100, 250, FALSE, eventWidget); + + label_none = newWidgetLabel("none", 130, 145, WIDGET_LABEL_LEFT); + label_server = newWidgetLabel("server", 130, 195, WIDGET_LABEL_LEFT); + label_client = newWidgetLabel("client", 130, 245, WIDGET_LABEL_LEFT); + + label_ip = newWidgetLabel("IP address :", 300, 145, WIDGET_LABEL_LEFT); + label_port = newWidgetLabel("net port :", 300, 245, WIDGET_LABEL_LEFT); + + textfield_ip = newWidgetTextfield("127.0.0.1", 300, 180); + textfield_port = newWidgetTextfield("2200", 300, 280); + + registerScreen( newScreen("gameType", startScreenGameType, eventScreenGameType, + drawScreenGameType, stopScreenGameType) ); +} + +int getSettingGameType() +{ + if( check_none->status == TRUE ) + { + return NET_GAME_TYPE_NONE; + } + + if( check_server->status == TRUE ) + { + return NET_GAME_TYPE_SERVER; + } + + if( check_client->status == TRUE ) + { + return NET_GAME_TYPE_CLIENT; + } + + assert( ! "Chyba pri zistvani type hry !" ); + + return -1; +} + +char* getSettingIP() +{ + return textfield_ip->text; +} + +int getSettingPort() +{ + return atoi( textfield_port->text ); +} + +void quitScreenGameType() +{ + destroyWidgetImage(image_backgorund); + + destroyWidgetLabel(label_none); + destroyWidgetLabel(label_server); + destroyWidgetLabel(label_client); + + destroyWidgetLabel(label_ip); + destroyWidgetLabel(label_port); + + destroyWidgetTextfield(textfield_ip); + destroyWidgetTextfield(textfield_port); + + destroyWidgetButton(button_back); + destroyWidgetButton(button_play); +} + diff --git a/src/screen_mainMenu.c b/src/screen_mainMenu.c new file mode 100644 index 0000000..db503b6 --- /dev/null +++ b/src/screen_mainMenu.c @@ -0,0 +1,107 @@ + +#include <stdio.h> +#include <assert.h> + +#include "main.h" +#include "interface.h" +#include "screen.h" +#include "image.h" +#include "music.h" +#include "screen_mainMenu.h" +#include "screen_setting.h" + +#include "widget_label.h" +#include "widget_button.h" +#include "widget_textfield.h" +#include "widget_check.h" +#include "widget_image.h" + +static widget_image_t *image_backgorund; + +static widget_button_t *button_play; +static widget_button_t *button_setting; +static widget_button_t *button_table; +static widget_button_t *button_credits; +static widget_button_t *button_end; + +void startScreenMainMenu() +{ + playMusic("menu", MUSIC_GROUP_BASE); +} + +void drawScreenMainMenu() +{ + drawWidgetImage(image_backgorund); + + drawWidgetButton(button_play); + drawWidgetButton(button_setting); + drawWidgetButton(button_table); + drawWidgetButton(button_credits); + drawWidgetButton(button_end); +} + +void eventScreenMainMenu() +{ + eventWidgetButton(button_play); + eventWidgetButton(button_setting); + eventWidgetButton(button_table); + eventWidgetButton(button_credits); + eventWidgetButton(button_end); +} + +void stopScreenMainMenu() +{ +} + +static void eventWidget(void *p) +{ + widget_button_t *button; + + button = (widget_button_t *)(p); + + if( button == button_play ) + { + setScreen("gameType"); + } + + if( button == button_setting ) + { + setScreen("setting"); + } + + if( button == button_end ) + { + quit(); + } +} + +void initScreenMainMenu() +{ + SDL_Surface *image; + + image = addImageData("screen_main.png", IMAGE_NO_ALPHA, "screen_main", IMAGE_GROUP_BASE); + image_backgorund = newWidgetImage(0, 0, image); + + button_play = newWidgetButton("Play", WINDOW_SIZE_X/2 -WIDGET_BUTTON_WIDTH/2, 200, eventWidget); + button_setting = newWidgetButton("Setting", WINDOW_SIZE_X/2 -WIDGET_BUTTON_WIDTH/2, 250, eventWidget); + button_table = newWidgetButton("Table", WINDOW_SIZE_X/2 -WIDGET_BUTTON_WIDTH/2, 300, eventWidget); + button_credits = newWidgetButton("Credits", WINDOW_SIZE_X/2 -WIDGET_BUTTON_WIDTH/2, 350, eventWidget); + button_end = newWidgetButton("End", WINDOW_SIZE_X/2 -WIDGET_BUTTON_WIDTH/2, 400, eventWidget); + + addMusic("menu.ogg", "menu", MUSIC_GROUP_BASE); + + registerScreen( newScreen("mainMenu", startScreenMainMenu, eventScreenMainMenu, + drawScreenMainMenu, stopScreenMainMenu) ); +} + +void quitScreenMainMenu() +{ + destroyWidgetImage(image_backgorund); + + destroyWidgetButton(button_play); + destroyWidgetButton(button_setting); + destroyWidgetButton(button_table); + destroyWidgetButton(button_credits); + destroyWidgetButton(button_end); +} + diff --git a/src/screen_setting.c b/src/screen_setting.c new file mode 100644 index 0000000..ffcc8d1 --- /dev/null +++ b/src/screen_setting.c @@ -0,0 +1,291 @@ + +#include <stdio.h> +#include <assert.h> + +#include "main.h" +#include "interface.h" +#include "screen.h" +#include "image.h" +#include "music.h" +#include "screen_mainMenu.h" +#include "list.h" +#include "screen_setting.h" +#include "tux.h" + +#include "widget_label.h" +#include "widget_button.h" +#include "widget_image.h" +#include "widget_textfield.h" +#include "widget_check.h" + +static widget_image_t *image_backgorund; + +static widget_button_t *button_back; + +static widget_label_t *label_count_round; +static widget_label_t *label_name_player1; +static widget_label_t *label_name_player2; + +static widget_check_t *check[ITEM_COUNT]; + +static widget_image_t *image_gun_dual_revolver; +static widget_image_t *image_gun_scatter; +static widget_image_t *image_gun_tommy; +static widget_image_t *image_gun_lasser; +static widget_image_t *image_gun_mine; +static widget_image_t *image_gun_bombball; + +static widget_image_t *image_bonus_speed; +static widget_image_t *image_bonus_shot; +static widget_image_t *image_bonus_teleport; +static widget_image_t *image_bonus_ghost; +static widget_image_t *image_bonus_4x; +static widget_image_t *image_bonus_hidden; + +static widget_textfield_t *textfield_count_cound; +static widget_textfield_t *textfield_name_player1; +static widget_textfield_t *textfield_name_player2; + +void startScreenSetting() +{ + playMusic("menu", MUSIC_GROUP_BASE); +} + +void drawScreenSetting() +{ + int i; + + drawWidgetImage(image_backgorund); + + drawWidgetLabel(label_count_round); + drawWidgetLabel(label_name_player1); + drawWidgetLabel(label_name_player2); + + drawWidgetTextfield(textfield_count_cound); + drawWidgetTextfield(textfield_name_player1); + drawWidgetTextfield(textfield_name_player2); + + drawWidgetImage(image_gun_dual_revolver); + drawWidgetImage(image_gun_scatter); + drawWidgetImage(image_gun_tommy); + drawWidgetImage(image_gun_lasser); + drawWidgetImage(image_gun_mine); + drawWidgetImage(image_gun_bombball); + + drawWidgetImage(image_bonus_speed); + drawWidgetImage(image_bonus_shot); + drawWidgetImage(image_bonus_teleport); + drawWidgetImage(image_bonus_ghost); + drawWidgetImage(image_bonus_4x); + drawWidgetImage(image_bonus_hidden); + + for( i = GUN_DUAL_SIMPLE ; i <= GUN_BOMBBALL ; i++ ) + { + drawWidgetCheck(check[i]); + } + + for( i = BONUS_SPEED ; i <= BONUS_HIDDEN ; i++ ) + { + drawWidgetCheck(check[i]); + } + + drawWidgetButton(button_back); +} + +void eventScreenSetting() +{ + int i; + + eventWidgetTextfield(textfield_count_cound); + eventWidgetTextfield(textfield_name_player1); + eventWidgetTextfield(textfield_name_player2); + + for( i = GUN_DUAL_SIMPLE ; i <= GUN_BOMBBALL ; i++ ) + { + eventWidgetCheck(check[i]); + } + + for( i = BONUS_SPEED ; i <= BONUS_HIDDEN ; i++ ) + { + eventWidgetCheck(check[i]); + } + + eventWidgetButton(button_back); +} + +void stopScreenSetting() +{ +} + +static void eventWidget(void *p) +{ + widget_button_t *button; + + button = (widget_button_t *)(p); + + if( button == button_back ) + { + setScreen("mainMenu"); + } +} + +void initScreenSetting() +{ + SDL_Surface *image; + int i; + + image = getImage(IMAGE_GROUP_BASE, "screen_main"); + image_backgorund = newWidgetImage(0, 0, image); + + button_back = newWidgetButton("Back", WINDOW_SIZE_X-200, WINDOW_SIZE_Y-100, eventWidget); + + label_count_round = newWidgetLabel("Count Round :", 100, WINDOW_SIZE_Y-200, WIDGET_LABEL_LEFT); + label_name_player1 = newWidgetLabel("Name player1 :", 100, WINDOW_SIZE_Y-160, WIDGET_LABEL_LEFT); + label_name_player2 = newWidgetLabel("Name player2 :", 100, WINDOW_SIZE_Y-120, WIDGET_LABEL_LEFT); + + textfield_count_cound = newWidgetTextfield("15", 110+label_count_round->w, WINDOW_SIZE_Y-200); + textfield_name_player1 = newWidgetTextfield("name1", 110+label_name_player1->w, WINDOW_SIZE_Y-160); + textfield_name_player2 = newWidgetTextfield("name2", 110+label_name_player2->w, WINDOW_SIZE_Y-120); + + for( i = GUN_DUAL_SIMPLE ; i <= GUN_BOMBBALL ; i++ ) + { + int x; + int y; + + if( i >= GUN_DUAL_SIMPLE && i <= GUN_TOMMY ) + { + x = 100; + y = 200 + ( i - GUN_DUAL_SIMPLE ) * 50; + } + + if( i >= GUN_LASSER && i <= GUN_BOMBBALL ) + { + x = 250; + y = 200 + ( i - GUN_LASSER ) * 50; + } + + check[i] = newWidgetCheck(x, y, TRUE, NULL); + } + + for( i = BONUS_SPEED ; i <= BONUS_HIDDEN ; i++ ) + { + int x; + int y; + + if( i >= BONUS_SPEED && i <= BONUS_TELEPORT ) + { + x = 430; + y = 200 + ( i - BONUS_SPEED ) * 50; + } + + if( i >= BONUS_GHOST && i <= BONUS_HIDDEN ) + { + x = 580; + y = 200 + ( i - BONUS_GHOST ) * 50; + } + + check[i] = newWidgetCheck(x, y, TRUE, NULL); + } + + image_gun_dual_revolver = newWidgetImage(110 + WIDGET_CHECK_WIDTH, 200, getImage(IMAGE_GROUP_BASE, "panel_dual")); + image_gun_scatter = newWidgetImage(110 + WIDGET_CHECK_WIDTH, 250, getImage(IMAGE_GROUP_BASE, "panel_scatter")); + image_gun_tommy = newWidgetImage(110 + WIDGET_CHECK_WIDTH, 300, getImage(IMAGE_GROUP_BASE, "panel_tommy")); + image_gun_lasser = newWidgetImage(260 + WIDGET_CHECK_WIDTH, 200, getImage(IMAGE_GROUP_BASE, "panel_lasser")); + image_gun_mine = newWidgetImage(260 + WIDGET_CHECK_WIDTH, 250, getImage(IMAGE_GROUP_BASE, "panel_mine")); + image_gun_bombball = newWidgetImage(260 + WIDGET_CHECK_WIDTH, 300, getImage(IMAGE_GROUP_BASE, "panel_dual")); + + image_bonus_speed = newWidgetImage(430 + WIDGET_CHECK_WIDTH, 200, getImage(IMAGE_GROUP_BASE, "panel_speed"));; + image_bonus_shot = newWidgetImage(430 + WIDGET_CHECK_WIDTH, 250, getImage(IMAGE_GROUP_BASE, "panel_shot"));; + image_bonus_teleport = newWidgetImage(430 + WIDGET_CHECK_WIDTH, 300, getImage(IMAGE_GROUP_BASE, "panel_teleport"));; + image_bonus_ghost = newWidgetImage(580 + WIDGET_CHECK_WIDTH, 200, getImage(IMAGE_GROUP_BASE, "panel_ghost"));; + image_bonus_4x = newWidgetImage(580 + WIDGET_CHECK_WIDTH, 250, getImage(IMAGE_GROUP_BASE, "panel_4x"));; + image_bonus_hidden = newWidgetImage(580 + WIDGET_CHECK_WIDTH, 300, getImage(IMAGE_GROUP_BASE, "panel_hidden"));; + + registerScreen( newScreen("setting", startScreenSetting, eventScreenSetting, + drawScreenSetting, stopScreenSetting) ); +} + +void getSettingNameRight(char *s) +{ + strcpy(s, textfield_name_player1->text); +} + +void getSettingNameLeft(char *s) +{ + strcpy(s, textfield_name_player2->text); +} + +void getSettingCountRound(int *n) +{ + *n = atoi( textfield_count_cound->text ); +} + +bool_t isSettingAnyItem() +{ + int i; + + for( i = GUN_DUAL_SIMPLE ; i <= GUN_BOMBBALL ; i++ ) + { + if( check[i]->status == TRUE ) + { + return TRUE; + } + } + + for( i = BONUS_SPEED ; i <= BONUS_HIDDEN ; i++ ) + { + if( check[i]->status == TRUE ) + { + return TRUE; + } + } + + return FALSE; +} + +bool_t isSettingItem(int item) +{ + return check[item]->status; +} + +void quitScreenSetting() +{ + int i; + + destroyWidgetImage(image_backgorund); + + destroyWidgetLabel(label_count_round); + destroyWidgetLabel(label_name_player1); + destroyWidgetLabel(label_name_player2); + + destroyWidgetTextfield(textfield_count_cound); + destroyWidgetTextfield(textfield_name_player1); + destroyWidgetTextfield(textfield_name_player2); + + destroyWidgetImage(image_gun_dual_revolver); + destroyWidgetImage(image_gun_scatter); + destroyWidgetImage(image_gun_tommy); + destroyWidgetImage(image_gun_lasser); + destroyWidgetImage(image_gun_mine); + destroyWidgetImage(image_gun_bombball); + + destroyWidgetImage(image_bonus_speed); + destroyWidgetImage(image_bonus_shot); + destroyWidgetImage(image_bonus_teleport); + destroyWidgetImage(image_bonus_ghost); + destroyWidgetImage(image_bonus_4x); + destroyWidgetImage(image_bonus_hidden); + + for( i = GUN_DUAL_SIMPLE ; i <= GUN_BOMBBALL ; i++ ) + { + destroyWidgetCheck(check[i]); + } + + for( i = BONUS_SPEED ; i <= BONUS_HIDDEN ; i++ ) + { + destroyWidgetCheck(check[i]); + } + + destroyWidgetButton(button_back); +} + diff --git a/src/screen_world.c b/src/screen_world.c new file mode 100644 index 0000000..ae278f5 --- /dev/null +++ b/src/screen_world.c @@ -0,0 +1,297 @@ + +#include <stdio.h> +#include <assert.h> + +#include "main.h" +#include "interface.h" + +#include "screen.h" +#include "screen_world.h" +#include "screen_analyze.h" +#include "screen_setting.h" +#include "screen_gameType.h" + +#include "list.h" +#include "layer.h" +#include "image.h" +#include "music.h" +#include "tux.h" +#include "wall.h" +#include "item.h" +#include "shot.h" +#include "gun.h" +#include "panel.h" +#include "myTimer.h" +#include "net_multiplayer.h" +#include "arena.h" +#include "arenaFile.h" + +static arena_t *arena; +static int count; +static int max_count; + +static bool_t isScreenWorldInit = FALSE; + +bool_t isScreenWorldInicialized() +{ + return isScreenWorldInit; +} + +static void setGameType() +{ + if( getSettingGameType() == NET_GAME_TYPE_SERVER ) + { + initServer( getSettingPort() ); + } + + if( getSettingGameType() == NET_GAME_TYPE_CLIENT ) + { + initClient( getSettingPort() , getSettingIP() ); + } +} + +arena_t* getWorldArena() +{ + return arena; +} + +void countRoundInc() +{ + count++; +} + +void createTux() +{ + tux_t *tux; + + switch( getNetTypeGame() ) + { + case NET_GAME_TYPE_NONE : + tux = newTux(); + tux->control = TUX_CONTROL_KEYBOARD_RIGHT; + getSettingNameRight(tux->name); + addList(arena->listTux, tux); + + tux = newTux(); + tux->control = TUX_CONTROL_KEYBOARD_LEFT; + getSettingNameLeft(tux->name); + addList(arena->listTux, tux); + break; + + case NET_GAME_TYPE_SERVER : + tux = newTux(); + tux->control = TUX_CONTROL_KEYBOARD_RIGHT; + getSettingNameRight(tux->name); + addList(arena->listTux, tux); + break; + + case NET_GAME_TYPE_CLIENT : + break; + } +} + +void drawWorld() +{ + drawImage(arena->background, 0, 0, 0, 0, WINDOW_SIZE_X, WINDOW_SIZE_Y); + + drawListTux(arena->listTux); + drawListWall(arena->listWall); + drawListShot(arena->listShot); + drawListItem(arena->listItem); + + drawLayer(); + + drawPanel(arena->listTux); +} + +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(int x, int y, int w, int h) +{ + if ( isConflictWithListTux(arena->listTux, x, y, w, h) )return 0; + if ( isConflictWithListWall(arena->listWall, x, y, w, h) )return 0; + if ( isConflictWithListShot(arena->listShot, x, y, w, h) )return 0; + if ( isConflictWithListItem(arena->listItem, x, y, w, h) )return 0; + + return 1; +} + +void findFreeSpace(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; + z_y = random() % (WINDOW_SIZE_Y-200); + }while( isFreeSpace(z_x, z_y ,w ,h) == 0 ); + + *x = z_x; + *y = z_y; +} + +static void control_keyboard_right(tux_t *p) +{ + Uint8 *mapa; + mapa = SDL_GetKeyState(NULL); + + assert( p != NULL ); + assert( mapa != NULL ); + + if( mapa[(SDLKey)SDLK_UP] == SDL_PRESSED )moveTux(p, TUX_UP); + if( mapa[(SDLKey)SDLK_RIGHT] == SDL_PRESSED )moveTux(p, TUX_RIGHT); + if( mapa[(SDLKey)SDLK_LEFT] == SDL_PRESSED )moveTux(p, TUX_LEFT); + if( mapa[(SDLKey)SDLK_DOWN] == SDL_PRESSED )moveTux(p, TUX_DOWN); + + if( mapa[(SDLKey)SDLK_KP0] == SDL_PRESSED ) + { + proto_send_shottux(p); + shotTux(p); + } + + if( mapa[(SDLKey)SDLK_KP1] == SDL_PRESSED ) + { + proto_send_switchgun(p); + switchTuxGun(p); + } +} + +static void control_keyboard_left(tux_t *p) +{ + Uint8 *mapa; + mapa = SDL_GetKeyState(NULL); + + assert( p != NULL ); + assert( mapa != NULL ); + + if( mapa[(SDLKey)SDLK_w] == SDL_PRESSED )moveTux(p, TUX_UP); + if( mapa[(SDLKey)SDLK_d] == SDL_PRESSED )moveTux(p, TUX_RIGHT); + if( mapa[(SDLKey)SDLK_a] == SDL_PRESSED )moveTux(p, TUX_LEFT); + if( mapa[(SDLKey)SDLK_s] == SDL_PRESSED )moveTux(p, TUX_DOWN); +} + +static void eventEnd() +{ + Uint8 *mapa; + mapa = SDL_GetKeyState(NULL); + + if( mapa[(SDLKey)SDLK_ESCAPE] == SDL_PRESSED ) + { + setScreen("analyze"); + return; + } + + if( count >= max_count && getNetTypeGame() != NET_GAME_TYPE_CLIENT ) + { + setScreen("analyze"); + return; + } +} + +void tuxControl(tux_t *p) +{ + assert( p != NULL ); + + if( p->status != TUX_STATUS_ALIVE ) + { + return; + } + + switch( p->control ) + { + case TUX_CONTROL_NONE : + assert( ! "Tux nema definovane ovladanie !" ); + break; + + case TUX_CONTROL_KEYBOARD_LEFT : + control_keyboard_left(p); + break; + + case TUX_CONTROL_KEYBOARD_RIGHT : + control_keyboard_right(p); + break; + } +} + +void eventWorld() +{ + eventListTux(arena->listTux); + + eventConflictShotWithTux(arena->listTux, arena->listShot); + eventConflictShotWithWall(arena->listWall, arena->listShot); + eventMoveListShot(arena->listShot); + eventListItem(arena->listItem); + eventConflictShotWithItem(arena->listItem, arena->listShot); + eventTimer(); + + eventNetMultiplayer(); + + eventEnd(); +} + +void startWorld() +{ + arena = getArena(0); + count = 0; + getSettingCountRound(&max_count); + + netSetArena(arena); + setGameType(); + createTux(); + addNewItem(arena->listItem); + playMusic(arena->music, MUSIC_GROUP_USER); + initTimer(); +} + +static void setAnalyze() +{ + int i; + tux_t *tux; + + restartAnalyze(); + + for( i = 0 ; i < arena->listTux->count ; i++ ) + { + tux = (tux_t *)(arena->listTux->list[i]); + addAnalyze(tux->name, tux->score); + } + + endAnalyze(); +} + +void stoptWorld() +{ + setAnalyze(); + delAllImageInGroup(IMAGE_GROUP_USER); + quitNetMultiplayer(); + destroyArena(arena); + stopMusic(); + delAllMusicInGroup(MUSIC_GROUP_USER); + quitTimer(); +} + +void initWorld() +{ + assert( isImageInicialized() == TRUE ); + assert( isTuxInicialized() == TRUE ); + assert( isShotInicialized() == TRUE ); + assert( isPanelInicialized() == TRUE ); + assert( isScreenInicialized() == TRUE ); + + registerScreen( newScreen("world", startWorld, eventWorld, drawWorld, stoptWorld) ); + + isScreenWorldInit = TRUE; +} + +void quitWorld() +{ + printf("quit world\n"); + isScreenWorldInit = FALSE; +} + diff --git a/src/shot.c b/src/shot.c new file mode 100644 index 0000000..d57d2df --- /dev/null +++ b/src/shot.c @@ -0,0 +1,165 @@ + +#include <stdlib.h> +#include <assert.h> + +#include "main.h" +#include "shot.h" +#include "layer.h" +#include "image.h" +#include "gun.h" +#include "screen_world.h" + +static SDL_Surface *g_shot_simple; +static SDL_Surface *g_shot_lasserX; +static SDL_Surface *g_shot_lasserY; + +static bool_t isShotInit = FALSE; + +bool_t isShotInicialized() +{ + return isShotInit; +} + +void initShot() +{ + assert( isImageInicialized() == TRUE ); + + 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); + + isShotInit = TRUE; +} + +shot_t* newShot(int x,int y, int px, int py, int gun, tux_t *author) +{ + shot_t *new; + static int last_id = 0; + + assert( author != NULL ); + + new = malloc( sizeof(shot_t) ); + memset(new, 0, sizeof(shot_t) ); + + new->id = ++last_id; + new->x = x; + new->y = y; + new->px = px; + new->py = py; + new->gun = gun; + new->author = author; + new->isCanKillAuthor = FALSE; + + switch( gun ) + { + case GUN_SIMPLE : + new->w = GUN_SHOT_WIDTH; + new->h = GUN_SHOT_HEIGHT; + new->img = g_shot_simple; + break; + + case GUN_LASSER : + switch( author-> position ) + { + case TUX_RIGHT : + case TUX_LEFT : + new->w = GUN_LASSER_HORIZONTAL; + new->h = GUN_SHOT_VERTICAL; + new->img = g_shot_lasserX; + break; + case TUX_UP : + case TUX_DOWN : + new->w = GUN_SHOT_VERTICAL; + new->h = GUN_LASSER_HORIZONTAL; + new->img = g_shot_lasserY; + break; + } + break; + + default : + assert( ! "Premenna weapon ma zlu hodnotu !" ); + break; + } + + return new; +} + +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); + } +} + +int isConflictWithListShot(list_t *listShot, int x, int y, int w, int h) +{ + shot_t *thisShot; + int i; + + assert( listShot != NULL ); + + for( i = 0 ; i < listShot->count ; i++ ) + { + thisShot = (shot_t *)listShot->list[i]; + assert( thisShot != NULL ); + + if( conflictSpace(x, y, w, h, + thisShot->x, thisShot->y, thisShot->w, thisShot->h) ) + { + return 1; + } + } + + return 0; +} + +void eventMoveListShot(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 ); + + thisShot->x += thisShot->px; + thisShot->y += thisShot->py; + + if( thisShot->x+thisShot->w < 0 || thisShot->x > WINDOW_SIZE_X || + thisShot->y+thisShot->h < 0 || thisShot->y > WINDOW_SIZE_Y ) + { + delListItem(listShot, i, destroyShot); + i--; + continue; + } + } +} + +void destroyShot(shot_t *p) +{ + assert( p != NULL ); + free(p); +} + +void quitShot() +{ + isShotInit = FALSE; +} + diff --git a/src/sound.c b/src/sound.c new file mode 100644 index 0000000..45cb225 --- /dev/null +++ b/src/sound.c @@ -0,0 +1,106 @@ + +#include <stdio.h> +#include <stdlib.h> +#include <assert.h> + +#include "main.h" +#include "interface.h" +#include "list.h" +#include "path.h" +#include "string_length.h" +#include "audio.h" +#include "sound.h" + +static list_t *listSound; + +static bool_t isSoundInit = FALSE; + +bool_t isSoundInicialized() +{ + return isSoundInit; +} + +void initSound() +{ + assert( isAudioInicialized() ); + + listSound = newList(); + isSoundInit = TRUE; + + printf("init sound..\n"); +} + +static Mix_Chunk* loadMixSound(char *file) +{ + Mix_Chunk *new; + char str[STR_PATH_SIZE]; + + sprintf(str, PATH_SOUND "%s", file); + new = Mix_LoadWAV(str); + + if( new == NULL ) + { + fprintf(stderr, "Nelze nahrat zvuk %s : %s\n", str, Mix_GetError()); + return NULL; + } + + return new; +} + +static sound_t *newSound(char *file, char *name, int group) +{ + sound_t *new; + + new = malloc( sizeof(sound_t) ); + new->name = strdup(name); + new->group = group; + new->sound = loadMixSound(file); + + return new; +} + +static void playMixSound(sound_t *p) +{ + if( Mix_PlayChannel(-1, p->sound, 0) == -1 ) + { + fprintf(stderr, "Nelze prehrat zvuk : %s\n", Mix_GetError()); + return; + } +} + +static void destroySound(sound_t *p) +{ + free(p->name); + Mix_FreeChunk(p->sound); + free(p); +} + +void addSound(char *file, char *name, int group) +{ + addList( listSound, newSound(file, name, group) ); +} + +void playSound(char *name, int group) +{ + int i; + sound_t *this; + + for( i = 0 ; i < listSound->count ; i++ ) + { + this = (sound_t *)listSound->list[i]; + + if( this->group == group && strcmp(this->name, name) == 0 ) + { + playMixSound(this); + return; + } + } +} + +void quitSound() +{ + destroyListItem(listSound, destroySound); + isSoundInit = FALSE; + printf("quit sound..\n"); +} + diff --git a/src/textFile.c b/src/textFile.c new file mode 100755 index 0000000..e55650e --- /dev/null +++ b/src/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 "textFile.h" +#include "string_length.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); +} + + + @@ -0,0 +1,10 @@ +static void proto_recv_init(char *msg) +{ + char cmd[STR_SIZE]; + tux_t *tux; + + tux = newTux(); + sscanf(msg, "%s %d\n", cmd, &tux->id); + my_tux_id = tux->id; + addList(listTux, tux); +}
\ No newline at end of file diff --git a/src/tux.c b/src/tux.c new file mode 100644 index 0000000..212242f --- /dev/null +++ b/src/tux.c @@ -0,0 +1,573 @@ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <assert.h> + +#include "main.h" +#include "tux.h" +#include "image.h" +#include "layer.h" +#include "screen_world.h" +#include "shot.h" +#include "gun.h" +#include "wall.h" +#include "item.h" +#include "arena.h" +#include "myTimer.h" +#include "net_multiplayer.h" +#include "dynamicInt.h" + +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; + +static bool_t isTuxInit = FALSE; + +bool_t isTuxInicialized() +{ + return isTuxInit; +} + +void initTux() +{ + assert( isImageInicialized() == TRUE ); + + 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); + + isTuxInit = TRUE; +} + +tux_t* newTux() +{ + static int last_id = 0; + tux_t *new; + + new = malloc( sizeof(tux_t) ); + assert( new != NULL ); + + memset(new, 0, sizeof(tux_t) ); + + new->id = last_id++; + new->status = TUX_STATUS_ALIVE; + new->control = TUX_CONTROL_NONE; + findFreeSpace(&new->x, &new->y, TUX_WIDTH, TUX_HEIGHT); + 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; + + 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; + } +} + +void drawTux(tux_t *p) +{ + SDL_Surface *g_image = NULL; + + assert( p != NULL ); + + if( p->bonus == BONUS_HIDDEN && + getNetTypeGame() != NET_GAME_TYPE_NONE && + p->control == TUX_CONTROL_NET ) + { + return; + } + + switch( p->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( p->status == TUX_STATUS_DEAD ) + { + g_image = g_cross; + + addLayer(g_cross, + p->x - g_cross->w / 2, + ( p->y + g_cross->h / 2 ) - g_cross->h, + 0, 0, + g_cross->w, g_cross->h, TUX_LAYER); + + return; + } + + addLayer(g_image, + p->x - TUX_IMG_WIDTH / 2, + ( p->y + TUX_HEIGHT / 2 ) - TUX_IMG_HEIGHT, + p->frame * 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); + } +} + +tux_t* getTuxID(list_t *listTux, int id) +{ + tux_t *thisTux; + int i; + + assert( listTux != NULL ); + + for( i = 0 ; i < listTux->count ; i++ ) + { + thisTux = (tux_t *)listTux->list[i]; + assert( thisTux != NULL ); + + if( thisTux->id == id ) + { + return thisTux; + } + } + + return NULL; +} + +tux_t* isConflictWithListTux(list_t *listTux, int x, int y, int w, int h) +{ + tux_t *thisTux; + int tx, ty, tw, th; + int i; + + assert( listTux != NULL ); + + for( i = 0 ; i < listTux->count ; i++ ) + { + thisTux = (tux_t *)listTux->list[i]; + assert( thisTux != NULL ); + + getTuxProportion(thisTux, &tx, &ty, &tw, &th); + + if( conflictSpace(x, y, w, h, tx, ty, tw, th) ) + { + return thisTux; + } + } + + return NULL; +} + +static void timer_spawnTux(void *p) +{ + tux_t *tux; + arena_t *arena; + int id; + + id = * ((int *)p); + free(p); + + arena = getWorldArena(); + tux = getTuxID(arena->listTux, id); + + if( tux == NULL )return; + + tux->status = TUX_STATUS_ALIVE; + findFreeSpace(&tux->x, &tux->y, TUX_WIDTH, TUX_HEIGHT); + tux->gun = GUN_SIMPLE; + + memset(tux->shot, 0, sizeof(int) * GUN_COUNT); + tux->shot[ tux->gun ] = GUN_MAX_SHOT; + + tux->bonus = BONUS_NONE; + tux->bonus_time = 0; + + tux->isCanShot = TRUE; + tux->isCanSwitchGun = TRUE; + + addNewItem(arena->listItem); + + if( getNetTypeGame() == NET_GAME_TYPE_SERVER ) + { + proto_send_settux(tux); + } +} + +static void timer_tuxCanShot(void *p) +{ + tux_t *tux; + int id; + + id = * ((int *)p); + free(p); + + tux = getTuxID(getWorldArena()->listTux, 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 = getTuxID(getWorldArena()->listTux, id); + + if( tux == NULL )return; + + tux->isCanSwitchGun = TRUE; +} + +void switchTuxGun(tux_t *tux) +{ + int i; + + if( tux->isCanSwitchGun == FALSE ) + { + return; + } + + for( i = tux->gun+1 ; i < GUN_COUNT ; i++ ) + { + if( tux->shot[i] > 0 ) + { + tux->gun = i; + tux->isCanSwitchGun = FALSE; + addTimer(timer_tuxCanSwitchGun, newInt(tux->id), TUX_TIME_CAN_SWITCH_GUN ); + return; + } + } + + for( i = 0 ; i < GUN_COUNT ; i++ ) + { + if( tux->shot[i] > 0 ) + { + tux->gun = i; + tux->isCanSwitchGun = FALSE; + addTimer(timer_tuxCanSwitchGun, newInt(tux->id), TUX_TIME_CAN_SWITCH_GUN ); + return; + } + } +} + +void eventTuxIsDead(tux_t *tux) +{ + if( tux->status == TUX_STATUS_DEAD ) + { + return; + } + + tux->status = TUX_STATUS_DEAD; + + if( getNetTypeGame() != NET_GAME_TYPE_CLIENT ) + { + addTimer(timer_spawnTux, newInt(tux->id), TUX_TIME_SPAWN ); + } +} + +static void eventTuxIsDeadWIthShot(tux_t *tux,shot_t *shot) +{ + shot->author->score++; + countRoundInc(); + eventTuxIsDead(tux); + +} + +void tuxTeleport(tux_t *tux) +{ + findFreeSpace(&tux->x, &tux->y, TUX_WIDTH, TUX_HEIGHT); + + if( getNetTypeGame() == NET_GAME_TYPE_SERVER ) + { + proto_send_settux(tux); + } +} + +void eventConflictShotWithTux(list_t *listTux, list_t *listShot) +{ + shot_t *thisShot; + tux_t *thisTux; + + int i; + + assert( listTux != NULL ); + assert( listShot != NULL ); + + for( i = 0 ; i < listShot->count ; i++ ) + { + thisShot = (shot_t *)listShot->list[i]; + assert( thisShot != NULL ); + + if( ( thisTux = isConflictWithListTux(listTux, thisShot->x, thisShot->y, + thisShot->w, thisShot->h) ) != NULL ) + { + if( thisTux->status == TUX_STATUS_ALIVE ) + { + if( thisShot->author == thisTux && + thisShot->isCanKillAuthor == FALSE ) + { + continue; + } + + if( thisTux->bonus == BONUS_TELEPORT ) + { + tuxTeleport(thisTux); + continue; + } + + + eventTuxIsDeadWIthShot(thisTux, thisShot); + } + + delListItem(listShot, i, destroyShot); + i--; + + continue; + } + } +} + +void moveTux(tux_t *tux,int n) +{ + int px, py; + int zal_x, zal_y; + int x, y, w, h; + arena_t *arena; + + assert( tux != NULL ); + + if( tux->position != n ) + { + tux->position = n; + if( getNetTypeGame() != NET_GAME_TYPE_NONE )proto_send_settux(tux); + return; + } + + arena = getWorldArena(); + getCourse(tux->position, &px, &py); + + zal_x = tux->x; + zal_y = tux->y; + + tux->x += px * TUX_STEP; + tux->y += py * TUX_STEP; + + if( tux->bonus == BONUS_SPEED ) + { + tux->x += px * TUX_STEP; + tux->y += py * TUX_STEP; + } + + getTuxProportion(tux, &x, &y, &w, &h); + + if( tux->bonus != BONUS_GHOST && ( + isConflictWithListTux(arena->listTux, x, y, w, h) != tux || + isConflictWithListWall(arena->listWall, x, y, w, h) ) ) + { + tux->x = zal_x; + tux->y = zal_y; + } + else + { + tux->frame++; + + if( tux->frame == TUX_MAX_ANIMATION_FRAME ) tux->frame = 0; + if( getNetTypeGame() != NET_GAME_TYPE_NONE )proto_send_settux(tux); + } +} + +void shotTux(tux_t *tux) +{ + assert( tux != NULL ); + + if( tux->isCanShot == FALSE || + tux->shot[tux->gun] == 0 ) + { + return; + } + + shotInGun(tux); + + if( tux->bonus != BONUS_SHOT ) + { + tux->shot[tux->gun]--; + } + + tux->isCanShot = FALSE; + addTimer(timer_tuxCanShot, newInt(tux->id), TUX_TIME_CAN_SHOT ); + + if( tux->shot[tux->gun] == 0 ) + { + switchTuxGun(tux); + } +} + +static void pickUpGun(tux_t *tux) +{ + if( isTuxAnyGun(tux) == FALSE ) + { + tux->gun = GUN_SIMPLE; + tux->pickup_time++; + + if( tux->pickup_time == TUX_MAX_PICKUP ) + { + tux->gun = GUN_SIMPLE; + tux->shot[ tux->gun ] = GUN_MAX_SHOT; + tux->pickup_time = 0; + } + } +} + +static void eventBonus(tux_t *tux) +{ + if( tux->bonus != BONUS_NONE ) + { + if( tux->bonus_time > 0 ) + { + tux->bonus_time--; + } + + if( tux->bonus_time == 0 ) + { + if( tux->bonus == BONUS_GHOST ) + { + int x, y, w, h; + getTuxProportion(tux, &x, &y, &w, &h); + + if ( isConflictWithListWall(getWorldArena()->listWall, x, y, w, h) ) + { + return; + } + } + + tux->bonus = BONUS_NONE; + } + } +} + +void eventListTux(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 ); + + tuxControl(thisTux); + pickUpGun(thisTux); + eventBonus(thisTux); + eventGiveTuxItem(thisTux, getWorldArena()->listItem); + } +} + +void getTuxProportion(tux_t *p, int *x,int *y, int *w, int *h) +{ + assert( p != NULL ); + + if( x != NULL ) *x = p->x - TUX_WIDTH / 2; + if( y != NULL ) *y = p->y - TUX_HEIGHT / 2; + if( w != NULL ) *w = TUX_WIDTH; + if( h != NULL ) *h = TUX_HEIGHT; +} + +void destroyTux(tux_t *p) +{ + assert( p != NULL ); + free(p); +} + +void quitTux() +{ + isTuxInit = FALSE; +} + diff --git a/src/wall.c b/src/wall.c new file mode 100644 index 0000000..bc0a26d --- /dev/null +++ b/src/wall.c @@ -0,0 +1,108 @@ + +#include <stdlib.h> +#include <assert.h> + +#include "wall.h" +#include "layer.h" +#include "screen_world.h" +#include "shot.h" + +wall_t* newWall(int x, int y, int w, int h, + int img_x, int img_y, int layer, SDL_Surface *img) +{ + wall_t *new; + + assert( img != NULL ); + + new = malloc( sizeof(wall_t) ); + assert( new != NULL ); + + new->x = x; + new->y = y; + new->w = w; + new->h = h; + new->img_x = img_x; + new->img_y = img_y; + new->layer = layer; + new->img = img; + + return new; +} + +void drawWall(wall_t *p) +{ + assert( p != NULL ); + + addLayer(p->img, p->x, p->y, 0, 0, p->img->w, p->img->h, p->layer); +} + +void drawListWall(list_t *listWall) +{ + wall_t *thisWall; + int i; + + assert( listWall != NULL ); + + for( i = 0 ; i < listWall->count ; i++ ) + { + thisWall = (wall_t *)listWall->list[i]; + assert( thisWall != NULL ); + drawWall(thisWall); + } +} + +int isConflictWithListWall(list_t *listWall, int x, int y, int w, int h) +{ + wall_t *thisWall; + int i; + + assert( listWall != NULL ); + + for( i = 0 ; i < listWall->count ; i++ ) + { + thisWall = (wall_t *)listWall->list[i]; + assert( thisWall != NULL ); + + if( conflictSpace(x, y, w, h, + thisWall->x, thisWall->y, thisWall->w, thisWall->h) ) + { + return 1; + } + } + + return 0; +} + +void eventConflictShotWithWall(list_t *listWall, list_t *listShot) +{ + shot_t *thisShot; + int i; + + assert( listWall != NULL ); + assert( listShot != NULL ); + + for( i = 0 ; i < listShot->count ; i++ ) + { + thisShot = (shot_t *)listShot->list[i]; + assert( thisShot != NULL ); + + if( isConflictWithListWall(listWall, thisShot->x, thisShot->y, thisShot->w, thisShot->h) ) + { + if( thisShot->author->bonus == BONUS_GHOST && + thisShot->author->bonus_time > 0 ) + { + continue; + } + + delListItem(listShot, i, destroyShot); + i--; + } + } +} + +void destroyWall(wall_t *p) +{ + assert( p != NULL ); + free(p); +} + diff --git a/src/widget_button.c b/src/widget_button.c new file mode 100644 index 0000000..940b7bd --- /dev/null +++ b/src/widget_button.c @@ -0,0 +1,71 @@ + +#include "main.h" +#include "interface.h" +#include "font.h" +#include "widget_button.h" +#include "image.h" + +widget_button_t* newWidgetButton(char *text, int x, int y, void (*fce_event)(void *)) +{ + widget_button_t *new; + + new = malloc( sizeof(widget_button_t) ); + new->text = strdup(text); + new->x = x; + new->y = y; + new->fce_event = fce_event; + getTextSize(text, &new->w, &new->h); + + return new; +} + +void drawWidgetButton(widget_button_t *p) +{ + static SDL_Surface *g_button0 = NULL; + static SDL_Surface *g_button1 = NULL; + int x, y; + + getMousePosition(&x, &y); + + if( g_button0 == NULL ) + { + g_button0 = addImageData("button0.png", IMAGE_ALPHA, "button0", IMAGE_GROUP_BASE); + } + + if( g_button1 == NULL ) + { + g_button1 = addImageData("button1.png", IMAGE_ALPHA, "button1", IMAGE_GROUP_BASE); + } + + if( x >= p->x && x <= p->x+WIDGET_BUTTON_WIDTH && + y >= p->y && y <= p->y+WIDGET_BUTTON_HEIGHT ) + { + drawImage(g_button1, p->x, p->y, 0, 0, g_button0->w, g_button0->h); + } + else + { + drawImage(g_button0, p->x, p->y, 0, 0, g_button0->w, g_button0->h); + } + + drawFont(p->text, p->x+WIDGET_BUTTON_WIDTH/2-p->w/2, p->y+p->h/2, COLOR_WHITE); +} + +void eventWidgetButton(widget_button_t *p) +{ + int x, y; + + getMousePosition(&x, &y); + + if( x >= p->x && x <= p->x+WIDGET_BUTTON_WIDTH && + y >= p->y && y <= p->y+WIDGET_BUTTON_HEIGHT && + isMouseClicked() ) + { + p->fce_event(p); + } +} + +void destroyWidgetButton(widget_button_t *p) +{ + free(p->text); + free(p); +} diff --git a/src/widget_check.c b/src/widget_check.c new file mode 100644 index 0000000..cbf64ff --- /dev/null +++ b/src/widget_check.c @@ -0,0 +1,83 @@ + +#include "main.h" +#include "interface.h" +#include "widget_check.h" +#include "image.h" + +widget_check_t* newWidgetCheck(int x, int y, bool_t status, void (*fce_event)(void *)) +{ + widget_check_t *new; + + new = malloc( sizeof(widget_check_t) ); + new->x = x; + new->y = y; + new->time = 0; + new->status = status; + new->fce_event = fce_event; + + return new; +} + +void drawWidgetCheck(widget_check_t *p) +{ + static SDL_Surface *g_check = NULL; + int x, y; + int offset; + + getMousePosition(&x, &y); + + if( g_check == NULL ) + { + g_check = addImageData("check.png", IMAGE_ALPHA, "check", IMAGE_GROUP_BASE); + } + + if( p->status == TRUE ) + { + offset = 0; + } + else + { + offset = WIDGET_CHECK_WIDTH; + } + + drawImage(g_check, p->x, p->y, offset, 0, WIDGET_CHECK_WIDTH, WIDGET_CHECK_HEIGHT); +} + +void eventWidgetCheck(widget_check_t *p) +{ + int x, y; + + if( p->time > 0 ) + { + p->time--; + return; + } + + getMousePosition(&x, &y); + + if( x >= p->x && x <= p->x+WIDGET_CHECK_WIDTH && + y >= p->y && y <= p->y+WIDGET_CHECK_HEIGHT && + isMouseClicked() ) + { + if( p->status == TRUE ) + { + p->status = FALSE; + p->time = WIDGET_CHECK_TIME_SWITCH_STATUS; + } + else + { + p->status = TRUE; + p->time = WIDGET_CHECK_TIME_SWITCH_STATUS; + } + + if( p->fce_event != NULL ) + { + p->fce_event(p); + } + } +} + +void destroyWidgetCheck(widget_check_t *p) +{ + free(p); +} diff --git a/src/widget_image.c b/src/widget_image.c new file mode 100644 index 0000000..5c618c0 --- /dev/null +++ b/src/widget_image.c @@ -0,0 +1,31 @@ + +#include "main.h" +#include "interface.h" +#include "image.h" +#include "widget_image.h" + +widget_image_t* newWidgetImage(int x, int y, SDL_Surface *image) +{ + widget_image_t *new; + + new = malloc( sizeof(widget_image_t) ); + new->x = x; + new->y = y; + new->image = image; + + return new; +} + +void drawWidgetImage(widget_image_t *p) +{ + drawImage(p->image, p->x, p->y, 0, 0, p->image->w, p->image->h); +} + +void eventWidgetImage(widget_image_t *p) +{ +} + +void destroyWidgetImage(widget_image_t *p) +{ + free(p); +} diff --git a/src/widget_label.c b/src/widget_label.c new file mode 100644 index 0000000..c01fa6b --- /dev/null +++ b/src/widget_label.c @@ -0,0 +1,45 @@ + +#include "main.h" +#include "interface.h" +#include "font.h" +#include "widget_label.h" + +widget_label_t* newWidgetLabel(char *text, int x, int y, int bind) +{ + widget_label_t *new; + + new = malloc( sizeof(widget_label_t) ); + new->text = strdup(text); + new->x = x; + new->y = y; + new->bind = bind; + getTextSize(text, &new->w, &new->h); + + return new; +} + +void drawWidgetLabel(widget_label_t *p) +{ + switch( p->bind ) + { + case WIDGET_LABEL_RIGHT : + drawFont(p->text, p->x+p->w, p->y, COLOR_WHITE); + break; + case WIDGET_LABEL_LEFT : + drawFont(p->text, p->x, p->y+p->h/2, COLOR_WHITE); + break; + case WIDGET_LABEL_CENTER : + drawFont(p->text, p->x+p->w/2, p->y, COLOR_WHITE); + break; + } +} + +void eventWidgetLabel(widget_label_t *p) +{ +} + +void destroyWidgetLabel(widget_label_t *p) +{ + free(p->text); + free(p); +} diff --git a/src/widget_textfield.c b/src/widget_textfield.c new file mode 100644 index 0000000..67138fb --- /dev/null +++ b/src/widget_textfield.c @@ -0,0 +1,179 @@ + +#include "main.h" +#include "interface.h" +#include "font.h" +#include "widget_textfield.h" +#include "image.h" + +widget_textfield_t* newWidgetTextfield(char *text, int x, int y) +{ + widget_textfield_t *new; + + new = malloc( sizeof(widget_textfield_t) ); + strcpy(new->text, text); + new->x = x; + new->y = y; + new->time = 0; + new->timeBlick = 0; + new->active = FALSE; + getTextSize(text, &new->w, &new->h); + + return new; +} + +static void drawBackground(widget_textfield_t *p) +{ + static SDL_Surface *g_textfield0 = NULL; + static SDL_Surface *g_textfield1 = NULL; + int x, y; + + getMousePosition(&x, &y); + + if( g_textfield0 == NULL ) + { + g_textfield0 = addImageData("button0.png", IMAGE_ALPHA, "textfiled0", IMAGE_GROUP_BASE); + } + + if( g_textfield1 == NULL ) + { + g_textfield1 = addImageData("button1.png", IMAGE_ALPHA, "textfiled1", IMAGE_GROUP_BASE); + } + + if( p->active ) + { + drawImage(g_textfield1, p->x, p->y, 0, 0, g_textfield1->w, g_textfield1->h); + } + else + { + drawImage(g_textfield0, p->x, p->y, 0, 0, g_textfield0->w, g_textfield0->h); + } +} + +static void drawText(widget_textfield_t *p) +{ + char str[STR_SIZE]; + + strcpy(str, p->text); + + if( p->timeBlick > WIDGET_TEXTFIELD_TIME_BLICK_CURSOR/2 && + p->active == TRUE ) + { + strcat(str, ">"); + } + + p->timeBlick++; + + if( p->timeBlick == WIDGET_TEXTFIELD_TIME_BLICK_CURSOR ) + { + p->timeBlick = 0; + } + + drawFont(str, p->x+WIDGET_TEXTFIELD_TEXT_OFFSET_X, p->y+p->h/2, COLOR_WHITE); +} + +void drawWidgetTextfield(widget_textfield_t *p) +{ + drawBackground(p); + drawText(p); +} + +static void readKey(widget_textfield_t *p) +{ + Uint8 *mapa; + int len; + int i; + + if( p->time > 0 ) + { + p->time--; + return; + } + + if( p->active == FALSE ) + { + return; + } + + mapa = SDL_GetKeyState(NULL); + len = strlen(p->text); + + //mazanie posledneho klavesu + if( mapa[SDLK_BACKSPACE] == SDL_PRESSED ) + { + if( len > 0 ) + { + p->time = WIDGET_TEXTFIELD_TIME_READ_KEY; + p->text[len-1]='\0'; + } + + return; + } + + //klavesy abecedy + for(i=SDLK_SPACE /*SDLK_a*/;i<=SDLK_z;i++) + { + //if(width<TEXTFIELD_SIZE_X-20 && mapa[i]==SDL_PRESSED) + if( mapa[i] == SDL_PRESSED && len < STR_SIZE ) + { + p->time = WIDGET_TEXTFIELD_TIME_READ_KEY; + + strcat( p->text, SDL_GetKeyName(i) ); + + if( mapa[SDLK_LSHIFT] == SDL_PRESSED || + mapa[SDLK_RSHIFT] == SDL_PRESSED) + { + p->text[ strlen( p->text ) - 1 ] -= 32; + return; + } + } + } + + // aby ve jmene bulanka fungovaly take cislice alfanumericke klavesnice + for( i = SDLK_0 ; i <= SDLK_9 ; i++ ) + { + if( mapa[i] == SDL_PRESSED && len < STR_SIZE ) + { + p->time = WIDGET_TEXTFIELD_TIME_READ_KEY; + strcat( p->text, SDL_GetKeyName(i) ); + return; + } + } + + // aby ve jmene bulanka fungovaly take cislice napsane na numericke klavesnici + for( i=SDLK_KP0 ; i<=SDLK_KP9 ; i++ ) + { + if( mapa[i] == SDL_PRESSED && len < STR_SIZE ) + { + p->time = WIDGET_TEXTFIELD_TIME_READ_KEY; + strncat( p->text, SDL_GetKeyName(i)+1, 1 ); // napr. "[4]" + return; + } + } +} + +void eventWidgetTextfield(widget_textfield_t *p) +{ + int x, y; + + getMousePosition(&x, &y); + + if( isMouseClicked() ) + { + if( x >= p->x && x <= p->x+WIDGET_TEXTFIELD_WIDTH && + y >= p->y && y <= p->y+WIDGET_TEXTFIELD_HEIGHT ) + { + p->active = TRUE; + } + else + { + p->active = FALSE; + } + } + + readKey(p); +} + +void destroyWidgetTextfield(widget_textfield_t *p) +{ + free(p); +} |