From 864b1d238b4e997fa5fdb29b1a544a85fbbc2de9 Mon Sep 17 00:00:00 2001 From: stpohle Date: Tue, 25 May 2004 22:22:27 +0000 Subject: [PATCH] chat mode fixed, rewrote the whole chat mode gfx part. --- include/chat.h | 28 ++-- include/keybinput.h | 6 +- src/chat.c | 378 +++++++++++++++++++++----------------------- src/configuration.c | 7 +- src/debug.c | 2 +- src/game.c | 19 ++- src/main.c | 5 +- src/menulabels.c | 4 +- src/multiwait.c | 5 +- src/packets.c | 2 +- src/pkgcache.c | 4 +- 11 files changed, 223 insertions(+), 237 deletions(-) diff --git a/include/chat.h b/include/chat.h index bd4f6ce..b74d94f 100644 --- a/include/chat.h +++ b/include/chat.h @@ -7,30 +7,30 @@ #define CHAT_MAX_LINES 255 #define CHAT_BG_SHADE_DARK -64 #define CHAT_BG_SHADE_BRIGHT 64 +#define CHAT_TEXTCOLOR COLOR_gray +#define CHAR_NETCOLOR COLOR_blue struct __chat { SDL_Rect window; - signed char visible; // the chat is visible - signed char changed; - SDL_Surface *oldscreen; - short int startline; - short int lastline; - short int active; + signed char changed; // if the chat windows has to redarwn after chat_loop + SDL_Surface *oldscreen; // old screen + short int curline; // current line + short int active; // if the chat window is active + short int keepactive; // keep chat active after pressing enter struct { - char text[255]; - int status; + char text[KEYBI_LINE_LEN]; + int color; // color of the line + int end; // mark the end of one line } lines[CHAT_MAX_LINES]; - signed char lineschanged; _keybinput input; } typedef _chat; extern _chat chat; -extern void chat_show (int x1, int y1, int x2, int y2); -extern void chat_addline (char *text); -extern void chat_addstatusline (char *text); +extern void chat_show (int x, int y, int w, int h); +extern void chat_addline (char *text, int color); extern void chat_loop (SDL_Event *event); -extern void chat_drawbox (); -extern void chat_cleanup (); +extern void chat_setactive (int active, int keepactive); +extern void chat_draw (); #endif diff --git a/include/keybinput.h b/include/keybinput.h index f39488c..5d4291d 100644 --- a/include/keybinput.h +++ b/include/keybinput.h @@ -1,8 +1,10 @@ -/* $Id: keybinput.h,v 1.5 2004/04/03 13:55:29 stpohle Exp $ */ +/* $Id: keybinput.h,v 1.6 2004/05/25 22:22:27 stpohle Exp $ */ #ifndef _KEYBINPUT_H_ #define _KEYBINPUT_H_ +#define KEYBI_LINE_LEN 255 + enum _keybinputtype { KEYBI_text = 0, KEYBI_int, @@ -10,7 +12,7 @@ enum _keybinputtype { }; struct __keybinput { - char text[255]; + char text[KEYBI_LINE_LEN]; short int curpos; short int len; char changed; diff --git a/src/chat.c b/src/chat.c index 24af08e..aa63ad6 100644 --- a/src/chat.c +++ b/src/chat.c @@ -1,6 +1,6 @@ /* - chat.c - this file will do everything what have to do with the chat.. -*/ + * chat.c - this file will do everything what have to do with the chat.. + */ #include "bomberclone.h" #include "network.h" @@ -11,19 +11,22 @@ _chat chat; +static void chat_drawlines (); +static void chat_drawinput (); + /* find a free line or delete the oldest one */ int chat_findfreeline () { int i; - i = chat.lastline; + i = chat.curline; - if (i >= CHAT_MAX_LINES) { + if (i >= CHAT_MAX_LINES-1) { memcpy (&chat.lines[0], &chat.lines[1], sizeof (chat.lines[1]) * (CHAT_MAX_LINES - 1)); - i = CHAT_MAX_LINES - 1; + i = CHAT_MAX_LINES - 2; } else - chat.lastline++; + chat.curline++; chat.changed = 1; @@ -31,265 +34,244 @@ chat_findfreeline () } -void -chat_cleanup () -{ - int i; - for (i = 0; i < CHAT_MAX_LINES; i++) { - if (chat.lines[i].status > 0) - chat.lines[i].status = -1; - } -} - /* - * add a new line to the chat + * add a new line to the chat, if a line is bigger as the X Space, + * split the line in more */ void -chat_addline (char *text) +chat_addline (char *text, int color) { - int l; - - l = chat_findfreeline (); - chat.lines[l].status = 0; - strncpy (chat.lines[l].text, text, 255); - chat.lineschanged = 1; + char *pos = text; + int l, i; + int maxlen = chat.window.x/font[0].size.x; + if (maxlen > KEYBI_LINE_LEN-1 || maxlen <= 0) maxlen = KEYBI_LINE_LEN; + + while (pos != NULL) { + l = chat_findfreeline (); + if (color == -1) + chat.lines[l].color = CHAT_TEXTCOLOR; + else + chat.lines[l].color = color; + chat.lines[l].end = 1; + strncpy (chat.lines[l].text, pos, maxlen); + if ((i = strlen (pos)) > maxlen) { + pos = pos + maxlen; + chat.lines[l].end = 0; + chat.lines[l].text[maxlen] = 0; + } + else pos = NULL; + } + + chat.changed = 1; } /* - * add a new line to the chat + * draw the empty chat box */ -void -chat_addstatusline (char *text) -{ - int l; - l = chat_findfreeline (); - chat.lines[l].status = 1; - strncpy (chat.lines[l].text, text, 255); - chat.lineschanged = 1; -} - - void chat_drawbox () { SDL_Rect src; int i; - if (chat.visible == 0) - chat.oldscreen = gfx_copyscreen (&chat.window); - - chat.visible = 1; - if (gfx_locksurface (gfx.screen)) return; + src = chat.window; + SDL_BlitSurface (chat.oldscreen, NULL, gfx.screen, &src); + for (i = 0; i < 2; i++) { src.x = chat.window.x + i; src.w = src.x + chat.window.w - 2; src.y = chat.window.y + i; src.h = src.y + chat.window.h - 2; - draw_shadefield (gfx.screen, &src, CHAT_BG_SHADE_BRIGHT); + if (chat.active) draw_shadefield (gfx.screen, &src, CHAT_BG_SHADE_BRIGHT); + else draw_shadefield (gfx.screen, &src, CHAT_BG_SHADE_DARK >> 2); } - - gfx_unlocksurface (gfx.screen); + + src = chat.window; + src.x += 2; + src.y += 2; + src.h -= 4; + src.w -= 4; + SDL_BlitSurface (chat.oldscreen, NULL, gfx.screen, &src); src.x = chat.window.x + 2; src.y = chat.window.y + 2; src.w = src.x + chat.window.w - 4; - src.h = src.y + chat.window.h - 4 - font[0].size.y; + src.h = src.y + chat.window.h - 4; draw_shadefield (gfx.screen, &src, CHAT_BG_SHADE_DARK); - src.x = chat.window.x + 2; - src.y = chat.window.y + chat.window.h - 18; - src.w = src.x + chat.window.w - 4; - src.h = src.y + font[0].size.y; - draw_shadefield (gfx.screen, &src, CHAT_BG_SHADE_DARK >> 1); - gfx_blitupdaterectadd (&chat.window); + + gfx_unlocksurface (gfx.screen); }; + /* - * + * Draw the chatscreen */ void -chat_deletebox () +chat_draw () { - SDL_Rect src, - dest; - - src.x = 0; - src.y = 0; - src.w = dest.w = chat.oldscreen->w; - src.h = dest.h = chat.oldscreen->h; - - dest.x = chat.window.x; - dest.y = chat.window.y; - - SDL_BlitSurface (chat.oldscreen, &src, gfx.screen, &dest); - gfx_blitupdaterectadd (&chat.window); + if (chat.oldscreen != NULL) { + chat_drawbox (); + chat_drawlines (); + chat_drawinput (); + } - chat.visible = 0; - SDL_FreeSurface (chat.oldscreen); - chat.oldscreen = NULL; + chat.changed = 0; + chat.input.changed = 0; }; /* - * set a new position for the chat window, - * or delete the chat windows if it's out of range + * Draw all the textlines */ void -chat_show (int x1, int y1, int x2, int y2) +chat_drawlines () { - if (chat.visible != 0) - chat_deletebox (); - - if (x1 == -1 || x2 == -1 || y1 == -1 || y2 == -1 || x2 <= x1 || y2 <= y1) - chat.visible = 0; - else { - chat.window.x = x1; - chat.window.y = y1; - chat.window.w = x2 - x1; - chat.window.h = y2 - y1; - chat_drawbox (); - chat.changed = 1; - chat.lineschanged = 1; - } + int vislines = (chat.window.h - 20) / font[0].size.y; // number of visible lines + int i = chat.curline - vislines; + int nr; + + if (i < 0) i = 0; + + for (nr = 0; i <= chat.curline; i++, nr++) + font_gfxdraw (chat.window.x + 4, chat.window.y + 4 + font[0].size.y * nr, chat.lines[i].text, 0, chat.lines[i].color, 0x1000); }; /* - * redraw the empty chat box + * draw the input field */ void -chat_clearscreen (signed char all) +chat_drawinput () { - SDL_Rect src, - dest; - - if (all == 1) { - dest.x = chat.window.x + 2; - dest.y = chat.window.y + 2; - dest.w = dest.x + chat.window.w - 4; - dest.h = dest.y + chat.window.h - 4; - - src.x = 2; - src.y = 2; - src.w = chat.window.w - 4; - src.h = chat.window.h - 4; - gfx_blitupdaterectadd (&chat.window); - } - else { - /* redraw only the textline of out input box */ - dest.x = chat.window.x + 2; - dest.y = chat.window.y + chat.window.h - 17; - dest.w = src.w = chat.window.w - 4; - dest.h = src.h = font[0].size.y; - - src.x = 2; - src.y = chat.window.h - 18; - gfx_blitupdaterectadd (&dest); - } - SDL_BlitSurface (chat.oldscreen, &src, gfx.screen, &dest); - - if (all == 1) { - dest.w = dest.x + chat.window.w - 4; - dest.h = dest.y + chat.window.h - 4 - font[0].size.y; - draw_shadefield (gfx.screen, &dest, CHAT_BG_SHADE_DARK); - } + SDL_Rect src, dest; + int maxlen = chat.window.x / font[0].size.x; + int start; + if (maxlen > KEYBI_LINE_LEN-1 || maxlen <= 0) maxlen = KEYBI_LINE_LEN; + + dest.x = chat.window.x + 2; + dest.y = chat.window.y + chat.window.h - (font[0].size.y + 2); + dest.w = chat.window.w - 4; + dest.h = font[0].size.y; + + src.x = 2; + src.y = chat.window.h - (font[0].size.y + 2); + src.w = chat.window.w - 4; + src.h = font[0].size.y; + d_printsdlrect ("c.w: ", &chat.window); + d_printsdlrect ("src: ", &src); + d_printsdlrect ("dst: ", &dest); + SDL_BlitSurface (chat.oldscreen, &src, gfx.screen, &dest); src.x = chat.window.x + 2; - src.y = chat.window.y + chat.window.h - 18; - src.w = src.x + chat.window.w - 4; - src.h = src.y + font[0].size.y; + src.y = chat.window.y + chat.window.h - (font[0].size.y + 2); + src.w = chat.window.x + chat.window.w - 4; + src.h = chat.window.y + chat.window.h - 4; + d_printsdlrect ("src: ", &src); + if (chat.active) - draw_shadefield (gfx.screen, &src, CHAT_BG_SHADE_DARK << 1); + draw_shadefield (gfx.screen, &src, CHAT_BG_SHADE_BRIGHT); else - draw_shadefield (gfx.screen, &src, CHAT_BG_SHADE_DARK >> 1); + draw_shadefield (gfx.screen, &src, CHAT_BG_SHADE_DARK); + gfx_blitupdaterectadd (&chat.window); + + start = strlen (chat.input.text) - maxlen; + if (start < 0) start = 0; + + font_gfxdraw (chat.window.x + 2, (chat.window.y + chat.window.h) - (2 + font[0].size.y), chat.input.text, 0, COLOR_black, 0x1000); + + chat.input.changed = 0; +} + +/* + * set a new position for the chat window, + * or delete the chat windows if it's out of range + */ +void +chat_show (int x, int y, int w, int h) +{ + /* restore the old screen */ + if (chat.oldscreen != NULL) { + gfx_blitupdaterectadd (&chat.window); + SDL_BlitSurface (chat.oldscreen, NULL, gfx.screen, &chat.window); + SDL_FreeSurface (chat.oldscreen); + chat.oldscreen = NULL; + } + + /* 1) save the old screen + * 2) draw chatbox + */ + if (x >= 0 && x < gfx.res.x && y >= 0 && y < gfx.res.y && w > 0 && h > 0) { + chat.window.x = x; + chat.window.y = y; + chat.window.w = w; + chat.window.h = h; + + chat.oldscreen = gfx_copyscreen (&chat.window); + + chat_draw (); + + gfx_blitupdaterectadd (&chat.window); + } }; + /* * loop through the chat and draw it */ void chat_loop (SDL_Event * event) { - int i, - y, - l, - p1, - p2, - maxchar; + int i; char text[255]; - if (chat.active) { /* the chat mode is active */ - if (event != NULL) - i = keybinput_loop (&chat.input, event); - else { - i = 0; - chat.input.changed = 1; - } + if (chat.active) { /* the chat mode is active */ + if (event != NULL) + i = keybinput_loop (&chat.input, event); + else { + i = 0; + chat.input.changed = 1; + } - if (i == 1 && chat.input.text[0] != 0) { - sprintf (text, "%s: %s", bman.playername, chat.input.text); - net_send_chat (text, 1); - chat_addline (text); - keybinput_new (&chat.input, KEYBI_text, 255); - i = 0; - chat.active = 0; // to let everything redraw - } - } - else i = 0; - - /* - * draw everything again if it's need to - */ - if (((i == 0 && chat.input.changed == 1) || chat.changed == 1) && chat.visible == 1) { - /* draw the new field */ - chat_clearscreen (chat.lineschanged); - p1 = p2 = 0; - maxchar = (chat.window.w - 4) / font[0].size.x; - if (chat.lineschanged) { - y = chat.window.y + 4; - l = chat.startline; - while (y < (chat.window.y + chat.window.h - 32) && chat.lines[l].text[0] != 0) { - if (chat.lines[l].status < 0) { - l++; - } - else { - for (p1 = 0; (p1 < maxchar && chat.lines[l].text[p2] != 0); p1++) - text[p1] = chat.lines[l].text[p2++]; - text[p1] = 0; - font_draw (chat.window.x + 4, y, text, 0, COLOR_white); - if (chat.lines[l].text[p2] == 0) { // the end of the line - l++; - p2 = 0; - } - y = y + font[0].size.y; - } - } - if (chat.lines[l].text[0] != 0) { - chat.startline++; - chat.changed = 1; - chat.lineschanged = 1; - } - else { - chat.changed = 0; - chat.lineschanged = 0; - } + if (i == 1 && chat.input.text[0] != 0) { + sprintf (text, "%s: %s", bman.playername, chat.input.text); + net_send_chat (text, 1); + chat_addline (text, CHAT_TEXTCOLOR); + keybinput_new (&chat.input, KEYBI_text, 255); + i = 0; + if (!chat.keepactive) + chat.active = 0; + chat.changed = 1; } - if (chat.startline >= CHAT_MAX_LINES) - chat.startline = CHAT_MAX_LINES - 5; - - /* draw the input line */ - if (chat.input.len > maxchar) - p2 = chat.input.len - maxchar; - - for (p1 = 0; (p1 < maxchar && chat.input.text[p2] != 0); p1++) - text[p1] = chat.input.text[p2++]; - text[p1] = 0; - font_draw (chat.window.x + 4, (chat.window.y + chat.window.h) - 4 - font[0].size.y, - text, 0, COLOR_white); } + else + i = 0; + + /* + * check if we have to redraw the input line + */ + if (chat.changed) + chat_draw (); + + if (chat.input.changed) + chat_drawinput (); +}; + + +/* + * activeate the chat and set up that the chat keeps + * active after we have pressed the Return Key + */ +void +chat_setactive (int active, int keepactive) +{ + chat.active = 1; + chat.changed = 1; + chat_draw (); + chat.keepactive = keepactive; }; diff --git a/src/configuration.c b/src/configuration.c index d2933cf..31ef791 100644 --- a/src/configuration.c +++ b/src/configuration.c @@ -1,4 +1,4 @@ -/* $Id: configuration.c,v 1.56 2004/05/20 16:55:30 stpohle Exp $ +/* $Id: configuration.c,v 1.57 2004/05/25 22:22:29 stpohle Exp $ * configuration */ #include @@ -29,8 +29,9 @@ config_init (int argc, char **argv) } stonelist_del (); - chat.visible = 0; - chat.startline = 0; + chat.oldscreen = NULL; + chat.active = 0; + chat.curline = 0; keyb_config_reset (); keybinput_new (&chat.input, KEYBI_text, 255); diff --git a/src/debug.c b/src/debug.c index c77b57b..807fca5 100644 --- a/src/debug.c +++ b/src/debug.c @@ -18,7 +18,7 @@ void d_gamedetail (char *head) { void d_printsdlrect (char *text, SDL_Rect *rect) { - d_printf ("%s [%4d,%4d] [%4d,%4d]\n", text, rect->x, rect->w, rect->y, rect->h); + d_printf ("%s [x=%4d, y=%4d, w=%4d, h=%4d]\n", text, rect->x, rect->y, rect->w, rect->h); }; void d_printf (char *fmt,...) { diff --git a/src/game.c b/src/game.c index d876b9a..308ead0 100644 --- a/src/game.c +++ b/src/game.c @@ -1,4 +1,4 @@ -/* $Id: game.c,v 1.83 2004/05/20 16:55:30 stpohle Exp $ +/* $Id: game.c,v 1.84 2004/05/25 22:22:29 stpohle Exp $ game.c - procedures for the game. */ #include @@ -33,6 +33,12 @@ game_draw_info () SDL_Rect src, dest; + if (GT_MP && (chat.oldscreen == NULL || chat.window.x != 4 || chat.window.y != 4.5*16)) { + chat_show (4, 4.5*16, gfx.res.x - 8, gfx.offset.y - 4.5*16); + chat_setactive (0, 0); + } + + if (bman.updatestatusbar) { redraw_logo (0, 0, gfx.res.x, (4.5 * 16)); dest.x = dest.y = 0; @@ -101,6 +107,9 @@ game_draw_info () font_gfxdraw (100, 32, "Press F4 to start the game", 0, COLOR_yellow, 0xFFFF); else if (bman.state == GS_ready) font_gfxdraw (100, 32, "Waiting for the Server to Start", 0, COLOR_yellow, 0xFFFF); + + if (GT_MP) + chat_draw (); } /* draw the warning part */ @@ -126,11 +135,6 @@ game_draw_info () } } - if (chat.visible == 0 && GT_MP) { - chat.active = 0; - chat_show (4, 4.5*16, gfx.res.x - 4, gfx.offset.y); - } - if (debug) debug_ingameinfo(); @@ -178,9 +182,8 @@ void game_keys_loop () { } if (GT_MP_PTPM && keyb_gamekeys.state[BCK_chat] && !keyb_gamekeys.old[BCK_chat]) { - chat.active = 1; + chat_setactive (1, 0); chat.changed = 1; - chat.lineschanged = 1; d_printf ("Chatmode Enabled\n"); } }; diff --git a/src/main.c b/src/main.c index 6bd6449..23134bb 100644 --- a/src/main.c +++ b/src/main.c @@ -1,4 +1,4 @@ -/* $Id: main.c,v 1.25 2004/05/20 16:55:30 stpohle Exp $ */ +/* $Id: main.c,v 1.26 2004/05/25 22:22:29 stpohle Exp $ */ #include "basic.h" #include "bomberclone.h" @@ -20,14 +20,13 @@ int firstrun = 1; // flag for the first menuloop int main (int argc, char **argv) { - char text[255]; int menuselect = 0; _menu *menu; players = malloc (sizeof (_player) * MAX_PLAYERS); gfxengine_init (); - if (SDL_Init (SDL_INIT_VIDEO) != 0) { + if (SDL_Init (SDL_INIT_VIDEO| SDL_INIT_NOPARACHUTE) != 0) { d_printf ("Unable to init SDL: %s\n", SDL_GetError ()); return (1); } diff --git a/src/menulabels.c b/src/menulabels.c index c31e921..1a364bc 100644 --- a/src/menulabels.c +++ b/src/menulabels.c @@ -1,4 +1,4 @@ -/* $Id: menulabels.c,v 1.5 2004/05/20 16:55:30 stpohle Exp $ +/* $Id: menulabels.c,v 1.6 2004/05/25 22:22:29 stpohle Exp $ * Menuhandling: labels */ #include "basic.h" @@ -55,7 +55,7 @@ _menuitem *menu_create_label (_menu *menu, char *name, int x, int y, int fontsiz void menu_create_text (_menu *menu, char *name, int x, int y, int maxlen, int maxlines, int fontcolor, char *fmt,...) { char text[1024]; char out[1024]; - char *lineptr[maxlines+1]; + char **lineptr = malloc (sizeof (char*)* maxlines + 1); int linecnt, maxchar, i; va_list args; diff --git a/src/multiwait.c b/src/multiwait.c index 0fff179..b72c5cd 100644 --- a/src/multiwait.c +++ b/src/multiwait.c @@ -1,4 +1,4 @@ -/* $Id: multiwait.c,v 1.41 2004/05/20 16:55:30 stpohle Exp $ +/* $Id: multiwait.c,v 1.42 2004/05/25 22:22:29 stpohle Exp $ multiwait.c - this manages only the network screen where everyone have to select it's players and where even the basic chat is inside */ @@ -47,7 +47,7 @@ mw_init () d_printf ("mw_num_players_x : %d, mw_num_players_y : %d\n", mw_num_players_x, mw_num_players_y); - chat_show (8, MW_TITLE_Y + MW_PLAYERSCR_Y * mw_num_players_y, gfx.res.x - 8, gfx.res.y - 8); + chat_show (8, MW_TITLE_Y + MW_PLAYERSCR_Y * mw_num_players_y, gfx.res.x - 16, gfx.res.y - (8 + MW_TITLE_Y + MW_PLAYERSCR_Y * mw_num_players_y)); chat.active = 1; }; @@ -55,7 +55,6 @@ mw_init () /* free all grafics */ void mw_shutdown () { chat_show (-1, -1, -1, -1); - chat_cleanup(); gfx_blitdraw (); draw_logo (); diff --git a/src/packets.c b/src/packets.c index 1a1b96c..4ab01ba 100644 --- a/src/packets.c +++ b/src/packets.c @@ -1174,7 +1174,7 @@ do_chat (struct pkg_chat *chat_pkg, _net_addr * addr) { d_printf ("do_chat (%s:%s) %d Text:%s\n", addr->host, addr->port, addr->pl_nr, chat_pkg->text); - chat_addline (chat_pkg->text); + chat_addline (chat_pkg->text, -1); }; diff --git a/src/pkgcache.c b/src/pkgcache.c index a046c84..86b4511 100644 --- a/src/pkgcache.c +++ b/src/pkgcache.c @@ -1,4 +1,4 @@ -/* $Id: pkgcache.c,v 1.7 2003/11/08 06:27:59 stpohle Exp $ +/* $Id: pkgcache.c,v 1.8 2004/05/25 22:22:30 stpohle Exp $ * Resendcache work, We need this to resend lost packets over the network. * we will keep every packet with the PKGF_ackreq flag as long as we haven't * got any answer from the destination host. And resend the packet after a givin @@ -66,7 +66,7 @@ rscache_del () /* newlen = size of the cacheentry we are going to delete */ len = rscache_getcurlen (); - if (resend_cache.fill <= len) /* something went wrong, fill is smaler as the cacheentry, delete the cache */ + if (resend_cache.fill <= len) /* something wrong?, fill is smaler as the cacheentry, delete the cache */ resend_cache.fill = 0; else { pos1 = (char *) resend_cache.entry + len;