From 5c734fe66e9ace93c03937adc2fc56336fb474fb Mon Sep 17 00:00:00 2001 From: Stijn Buys Date: Sat, 23 Feb 2008 17:10:35 +0000 Subject: client chatbox and message notifications --- src/client/Makefile.am | 8 +-- src/client/chat.cc | 172 +++++++++++++++++++++++++++++++++++++++++++++++++ src/client/chat.h | 41 ++++++++++++ src/client/client.cc | 5 +- src/client/console.cc | 23 +++++-- src/client/console.h | 9 ++- src/client/input.cc | 24 ++++++- src/client/view.cc | 26 ++++++++ 8 files changed, 293 insertions(+), 15 deletions(-) create mode 100644 src/client/chat.cc create mode 100644 src/client/chat.h (limited to 'src') diff --git a/src/client/Makefile.am b/src/client/Makefile.am index bd4aaf1..1b504c4 100644 --- a/src/client/Makefile.am +++ b/src/client/Makefile.am @@ -1,13 +1,13 @@ METASOURCES = AUTO INCLUDES = -I$(top_srcdir)/src -libclient_la_SOURCES = camera.cc client.cc console.cc draw.cc hud.cc input.cc \ - keyboard.cc video.cc view.cc +libclient_la_SOURCES = camera.cc chat.cc client.cc console.cc draw.cc hud.cc \ + input.cc keyboard.cc video.cc view.cc libclient_la_CFLAGS = $(LIBSDL_CFLAGS) $(GL_CFLAGS) libclient_la_LDFLAGS = -avoid-version -no-undefined $(GL_LIBS) $(LIBSDL_LIBS) noinst_LTLIBRARIES = libclient.la -noinst_HEADERS = camera.h client.h console.h draw.h input.h keyboard.h video.h \ - view.h +noinst_HEADERS = camera.h chat.h client.h console.h draw.h input.h keyboard.h \ + video.h view.h libclient_la_LIBADD = $(top_builddir)/src/core/libcore.la \ $(top_builddir)/src/filesystem/libfilesystem.la $(top_builddir)/src/math/libmath.la \ $(top_builddir)/src/render/librender.la $(top_builddir)/src/sys/libsys.la diff --git a/src/client/chat.cc b/src/client/chat.cc new file mode 100644 index 0000000..4e7416f --- /dev/null +++ b/src/client/chat.cc @@ -0,0 +1,172 @@ +/* + client/chat.cc + This file is part of the Osirion project and is distributed under + the terms and conditions of the GNU General Public License version 2 +*/ + +#include "core/core.h" +#include "client/chat.h" +#include "client/console.h" +#include "client/keyboard.h" +#include "render/render.h" + +namespace client { + +namespace chat { + +// input history +std::deque history; +std::deque::reverse_iterator history_pos; +size_t input_pos = 0; + +// chatbox visibility +bool chat_visible = false; + +//--- engine functions -------------------------------------------- + +void func_con_chat(std::string const &args) +{ + std::istringstream argstream(args); + int i; + + if (argstream >> i) { + if (i) chat_visible = true; else chat_visible = false; + } else + chat_visible = !chat_visible; +} + +//--- public ------------------------------------------------------ + +void init() +{ + // add engine functions + core::Func::add("con_chat", (core::FuncPtr) func_con_chat); + + history.clear(); + history.push_back(""); + history_pos = history.rbegin(); + input_pos = 0; + +} + +void shutdown() +{ + // remove engine functions + core::Func::remove("con_chat"); + + history.clear(); + input_pos = 0; +} + + +bool visible() +{ + return chat_visible; +} + +void draw() +{ + using namespace render; + + if (console::visible() || !visible()) + return; + + // draw the console input + gl::enable(GL_TEXTURE_2D); + gl::color(0.0f, 1.0f, 0.0f, 1.0f); + draw_text(CHARWIDTH , 4 + CHARHEIGHT * (MAXNOTIFYLINES+1), "Say:"); + + gl::color(1.0f, 1.0f, 1.0f, 1.0f); + draw_text(CHARWIDTH*6, 4 + CHARHEIGHT * (MAXNOTIFYLINES+1), (*history_pos)); + + // draw cursor + if ((core::application()->time() - ::floorf(core::application()->time())) < 0.5f) { + std::string cursor("_"); + draw_text(CHARWIDTH*(input_pos+6), 4 + CHARHEIGHT * (MAXNOTIFYLINES+1) , cursor); + } + gl::disable(GL_TEXTURE_2D); +} + +void toggle() +{ + chat_visible = !chat_visible; + if (chat_visible) { + input_pos = 0; + history_pos = history.rbegin(); + (*history_pos).clear(); + } +} + +void keypressed(int key) +{ + std::deque::reverse_iterator upit; + + switch( key ) { + case SDLK_TAB: + core::CommandBuffer::complete( (*history_pos), input_pos); + break; + case SDLK_RETURN: + if ((*history_pos).size()) { + // store input into history + while (history.size() >= MAXHISTOLINES) { + history.pop_front(); + } + + core::cmd() << "say " << (*history_pos) << std::endl; + (*history.rbegin()) = (*history_pos); + + history.push_back(""); + history_pos = history.rbegin(); + input_pos = 0; + } + toggle(); + break; + case SDLK_UP: + upit = history_pos; + ++upit; + if (upit != history.rend()) { + history_pos = upit; + input_pos = (*history_pos).size(); + } + break; + case SDLK_DOWN: + if (history_pos != history.rbegin()) { + --history_pos; + input_pos = (*history_pos).size(); + } + break; + case SDLK_HOME: + input_pos = 0; + break; + case SDLK_END: + input_pos = (*history_pos).size(); + break; + case SDLK_LEFT: + if (input_pos > 0) + input_pos--; + break; + case SDLK_RIGHT: + if (input_pos < (*history_pos).size()) + input_pos++; + break; + case SDLK_BACKSPACE: + if ((*history_pos).size() && input_pos) { + (*history_pos).erase(input_pos-1, 1); + input_pos--; + } + break; + default: + if ((key >= 32 ) && (key <175)) { + if (input_pos == (*history_pos).size()) + (*history_pos) += (char)key; + else + (*history_pos).insert(input_pos, 1, (char)key); + input_pos++; + } + break; + } +} + +} + +} diff --git a/src/client/chat.h b/src/client/chat.h new file mode 100644 index 0000000..71fb9f5 --- /dev/null +++ b/src/client/chat.h @@ -0,0 +1,41 @@ +/* + client/chat.h + This file is part of the Osirion project and is distributed under + the terms of the GNU General Public License version 2 +*/ + +#ifndef __INCLUDED_CLIENT_CHAT_H__ +#define __INCLUDED_CLIENT_CHAT_H__ + +#include "sys/consoleinterface.h" + +#include +#include + +namespace client { + +/// the client chatbox +namespace chat { + +/// initialize chatbox functions +void init(); + +/// shut down chatbox functions +void shutdown(); + +/// draw the chatbox +void draw(); + +/// toggle the chatbox +void toggle(); + +/// handle keyboard input +void keypressed(int key); + +/// true of the console is visible +bool visible(); +} + +} + +#endif // __INCLUDED_CLIENT_CHAT_H__ diff --git a/src/client/client.cc b/src/client/client.cc index f232c12..33b3a04 100644 --- a/src/client/client.cc +++ b/src/client/client.cc @@ -4,7 +4,7 @@ the terms and conditions of the GNU General Public License version 2 */ -// project headers +#include "client/chat.h" #include "client/client.h" #include "client/video.h" #include "client/camera.h" @@ -102,6 +102,7 @@ void Client::init() // initialize console console::init(); + chat::init(); // initialize input input::init(); @@ -148,6 +149,8 @@ void Client::shutdown() // remove engine functions core::Func::remove("r_restart"); + chat::shutdown(); + console::shutdown(); console::flush(); diff --git a/src/client/console.cc b/src/client/console.cc index 85cb72e..3954d45 100644 --- a/src/client/console.cc +++ b/src/client/console.cc @@ -21,6 +21,7 @@ namespace console { //--- private definition ------------------------------------------ + /// private client console implementation class Console : public sys::ConsoleInterface { public: @@ -52,16 +53,23 @@ std::deque::reverse_iterator history_pos; size_t input_pos = 0; // console visibility -bool console_visible; +bool console_visible = false; size_t console_scroll = 0; +// notifications +size_t notify_pos = 0; +std::string notify_text[MAXNOTIFYLINES]; +float notify_time[MAXNOTIFYLINES]; + //--- engine functions -------------------------------------------- -void func_con_toggle(std::stringstream &args) +void func_con_toggle(std::string const &args) { + std::istringstream argstream(args); int i; - if (args >> i) { + + if (argstream >> i) { if (i) console_visible = true; else console_visible = false; } else console_visible = !console_visible; @@ -109,7 +117,6 @@ void draw() { using namespace render; - flush(); if(!console_visible) return; @@ -184,6 +191,13 @@ void flush() text.pop_front(); } text.push_back(std::string(line)); + + // save notification + notify_text[notify_pos] = line; + notify_time[notify_pos] = sys::time(); + notify_pos = (notify_pos+1) % MAXNOTIFYLINES; + + // print to stdout std::cout << line << std::endl; } @@ -193,7 +207,6 @@ void flush() void toggle() { console_visible = !console_visible; - setkeyboardmode(console_visible); if (console_visible) { console_scroll = 0; diff --git a/src/client/console.h b/src/client/console.h index d9e78a0..dc831b7 100644 --- a/src/client/console.h +++ b/src/client/console.h @@ -12,8 +12,9 @@ #include #include -const size_t MAXCONLINES=2048; -const size_t MAXHISTOLINES=512; +const size_t MAXCONLINES = 2048; +const size_t MAXHISTOLINES = 512; +const size_t MAXNOTIFYLINES = 3; namespace client { @@ -51,6 +52,10 @@ void load_history(); /// save input history void save_history(); +extern size_t notify_pos; +extern std::string notify_text[MAXNOTIFYLINES]; +extern float notify_time[MAXNOTIFYLINES]; + } } diff --git a/src/client/input.cc b/src/client/input.cc index c9c2514..b339574 100644 --- a/src/client/input.cc +++ b/src/client/input.cc @@ -7,6 +7,7 @@ #include "core/core.h" #include "client/client.h" #include "client/input.h" +#include "client/chat.h" #include "client/console.h" #include "client/camera.h" #include "client/keyboard.h" @@ -115,12 +116,29 @@ void frame(float seconds) case SDL_KEYDOWN: if (event.key.keysym.sym == '`' || event.key.keysym.sym == '~') { console::toggle(); + setkeyboardmode(console::visible()); + if (console::visible() && chat::visible()) + chat::toggle(); } else if (console::visible()) { // send key events to the console console::keypressed(translate_keysym(event.key.keysym)); - } else if (core::application()->connected() && core::localcontrol()) { - // send key events to the game world - keypressed(event.key.keysym); + + } else if (chat::visible()) { + if(event.key.keysym.sym == SDLK_ESCAPE) { + chat::toggle(); + setkeyboardmode(chat::visible()); + } else { + // send key events to the chatbox + chat::keypressed(translate_keysym(event.key.keysym)); + } + } else if(core::application()->connected()) { + if ((event.key.keysym.sym == 't') || (event.key.keysym.sym == 'T')) { + chat::toggle(); + setkeyboardmode(chat::visible()); + } else if (core::localcontrol()) { + // send key events to the game world + keypressed(event.key.keysym); + } } break; case SDL_QUIT: diff --git a/src/client/view.cc b/src/client/view.cc index 1a40c4a..3a9a8fb 100644 --- a/src/client/view.cc +++ b/src/client/view.cc @@ -6,6 +6,7 @@ #include "client/client.h" #include "client/camera.h" +#include "client/chat.h" #include "client/console.h" #include "client/video.h" #include "client/draw.h" @@ -121,6 +122,27 @@ void draw_status() version.append(core::version()); draw_text(video::width-(version.size()+1)*CHARWIDTH, 4, version); + // draw notifications + gl::color(1.0f, 1.0f, 1.0f, 1.0f); + size_t n = console::notify_pos % MAXNOTIFYLINES; + float now = sys::time(); + int h = 4 + CHARHEIGHT; + for (size_t l = 0; l < MAXNOTIFYLINES; l++) { + if (console::notify_text[n].size() > 2 && console::notify_time[n] + 5 > now) { + if (console::notify_text[n][0] == '?') + gl::color(0.7f,0.7f,0.7f, 1.0f); + else if (console::notify_text[n][0] == '*') + gl::color(1.0f,1.0f,0.0f, 1.0f); + else if (console::notify_text[n][0] == '!') + gl::color(1.0f,0.0f,0.0f, 1.0f); + else + gl::color(1.0f,1.0f,1.0f, 1.0f); + draw_text(CHARWIDTH, h, console::notify_text[n].substr(2)); + h += CHARHEIGHT; + } + n = (n+1) % MAXNOTIFYLINES; + } + gl::disable(GL_TEXTURE_2D); } @@ -134,6 +156,9 @@ void frame(float seconds) else fps = 9999; + // flush console messages + console::flush(); + // Clear the color and depth buffers. gl::clear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); @@ -179,6 +204,7 @@ void frame(float seconds) // draw the console console::draw(); + chat::draw(); // draw the status line draw_status(); -- cgit v1.2.3