Compare commits

...

1 Commits
master ... w32x

Author SHA1 Message Date
darkrose ea789f4f97 redo the chat console 2017-10-16 01:05:32 +10:00
8 changed files with 270 additions and 155 deletions

View File

@ -285,6 +285,7 @@ endif()
set(voxelands_SRCS
${common_SRCS}
${audio_SRCS}
ui_console.c
sky.cpp
hud.cpp
content_mapblock.cpp

View File

@ -1234,10 +1234,8 @@ void Client::ProcessData(u8 *data, u32 datasize, u16 sender_peer_id)
message += (wchar_t)readU16(buf);
}
/* because I can't remember which random stream prints to stdout */
/* this will print to game console, system console, and log file */
vlprint(CN_CHAT,(char*)wide_to_narrow(message).c_str());
m_chat_queue.push_back(message);
}
break;
case TOCLIENT_ACTIVE_OBJECT_REMOVE_ADD:

View File

@ -275,30 +275,6 @@ public:
u16 getHunger();
float getEnergy();
bool getChatMessage(std::wstring &message)
{
if(m_chat_queue.size() == 0)
return false;
message = m_chat_queue.pop_front();
return true;
}
void addChatMessage(const std::wstring &message)
{
if (message[0] == L'/') {
m_chat_queue.push_back(
(std::wstring)L"issued command: "+message);
return;
}
//JMutexAutoLock envlock(m_env_mutex); //bulk comment-out
LocalPlayer *player = m_env.getLocalPlayer();
assert(player != NULL);
std::wstring name = narrow_to_wide(player->getName());
m_chat_queue.push_back(
(std::wstring)L"<"+name+L"> "+message);
}
uint64_t getMapSeed() {return m_map_seed;}
MapGenType getMapType() {return m_map_type;}
@ -400,8 +376,6 @@ private:
bool m_form_open;
Queue<std::wstring> m_chat_queue;
// The seed returned by the server in TOCLIENT_INIT is stored here
uint64_t m_map_seed;
MapGenType m_map_type;

View File

@ -207,6 +207,13 @@ void world_exit(void);
worldlist_t *world_list_get(void);
void world_list_free(worldlist_t *l);
/* defined in ui_console.c */
void ui_console_addline(uint8_t type, char* txt);
void ui_console_addlinef(uint8_t type, char* fmt, ...);
void ui_console_clear(void);
int ui_console_step(float dtime);
char* ui_console_get(void);
#ifdef __cplusplus
}
#include <string>

View File

@ -31,7 +31,7 @@ void config_default_init()
config_set_default("log.max_level","info",log_maxlevel_setter);
config_set_default("log.system.min_level","chat",log_sminlevel_setter);
config_set_default("log.system.max_level","info",log_smaxlevel_setter);
config_set_default("log.console.min_level","chat",log_cminlevel_setter);
config_set_default("log.console.min_level","action",log_cminlevel_setter);
config_set_default("log.console.max_level","info",log_cmaxlevel_setter);
config_set_default("path.log",NULL,log_file_setter);

View File

@ -68,17 +68,6 @@
#define swprintf _snwprintf
#endif
/*
Setting this to 1 enables a special camera mode that forces
the renderers to think that the camera statically points from
the starting place to a static direction.
This allows one to move around with the player and see what
is actually drawn behind solid things and behind the player.
*/
#define FIELD_OF_VIEW_TEST 0
// Chat data
struct ChatLine
{
@ -136,7 +125,7 @@ public:
// Send to others
m_client->sendChatMessage(fields["text"]);
// Show locally
m_client->addChatMessage(fields["text"]);
ui_console_addline(CN_CHAT,(char*)wide_to_narrow(fields["text"]).c_str());
}
}
@ -661,16 +650,6 @@ void update_profiler_gui(gui::IGUIStaticText *guitext_profiler,
}
}
void chatline_add(ref_t **chat_lines, std::wstring txt, float time)
{
ref_t *ref = (ref_t*)malloc(sizeof(ref_t));
if (!ref)
return;
ref->ref = new ChatLine(txt,time);
*chat_lines = (ref_t*)list_push(chat_lines,ref);
}
void the_game(
bool &kill,
InputHandler *input,
@ -693,7 +672,6 @@ void the_game(
gui::IGUIStaticText *guitext_info;
gui::IGUIStaticText *guitext_chat;
gui::IGUIStaticText *guitext_profiler;
ref_t *chat_lines = NULL;
u32 drawtime = 0;
core::list<float> frametime_log;
float action_delay_counter = 0.0;
@ -745,6 +723,8 @@ void the_game(
*/
drawLoadingScreen(device,narrow_to_wide(gettext("Loading...")));
ui_console_clear();
/*
Create server.
SharedPtr will delete it when it goes out of scope.
@ -1171,10 +1151,10 @@ void the_game(
}else if(input->wasKeyDown(getKeySetting(VLKC_FREEMOVE))) {
if (free_move) {
free_move = false;
chatline_add(&chat_lines,narrow_to_wide(gettext("free_move disabled")),-103.00);
vlprint(CN_ACTION,gettext("free_move disabled"));
}else{
free_move = true;
chatline_add(&chat_lines,narrow_to_wide(gettext("free_move enabled")),-103.00);
vlprint(CN_ACTION,gettext("free_move enabled"));
}
}else if(input->wasKeyDown(getKeySetting(VLKC_SCREENSHOT))) {
irr::video::IImage* const image = driver->createScreenShot();
@ -1186,10 +1166,7 @@ void the_game(
}else{
if (path_get((char*)"screenshot",fn,0,path,1024)) {
if (driver->writeImageToFile(image, io::path(path))) {
char buff[512];
snprintf(buff, 512, gettext("Saved screenshot to '%s'"), path);
infostream << "Saved screenshot to '" << fn << "'" << std::endl;
chatline_add(&chat_lines,narrow_to_wide(buff),-103.00);
vlprintf(CN_ACTION,gettext("Saved screenshot to '%s'"), path);
}else{
infostream << "Failed to save screenshot '" << fn << "'"<<std::endl;
}
@ -1200,30 +1177,30 @@ void the_game(
}else if (input->wasKeyDown(getKeySetting(VLKC_TOGGLE_HUD))) {
show_hud = !show_hud;
if (show_hud) {
chatline_add(&chat_lines,narrow_to_wide(gettext("HUD shown")),-103.00);
vlprint(CN_ACTION,gettext("HUD shown"));
}else{
chatline_add(&chat_lines,narrow_to_wide(gettext("HUD hidden")),-103.00);
vlprint(CN_ACTION,gettext("HUD hidden"));
}
}else if (input->wasKeyDown(getKeySetting(VLKC_TOGGLE_CHAT))) {
show_chat = !show_chat;
if (show_chat) {
chatline_add(&chat_lines,narrow_to_wide(gettext("Chat shown")),-103.00);
vlprint(CN_ACTION,gettext("Chat shown"));
}else{
chatline_add(&chat_lines,narrow_to_wide(gettext("Chat hidden")),-103.00);
vlprint(CN_ACTION,gettext("Chat hidden"));
}
}else if (input->wasKeyDown(getKeySetting(VLKC_TOGGLE_FOG))) {
force_fog_off = !force_fog_off;
if (force_fog_off) {
chatline_add(&chat_lines,narrow_to_wide(gettext("Fog disabled")),-103.00);
vlprint(CN_ACTION,gettext("Fog disabled"));
}else{
chatline_add(&chat_lines,narrow_to_wide(gettext("Fog enabled")),-103.00);
vlprint(CN_ACTION,gettext("Fog enabled"));
}
}else if (input->wasKeyDown(getKeySetting(VLKC_TOGGLE_CAMERA))) {
disable_camera_update = !disable_camera_update;
if (disable_camera_update) {
chatline_add(&chat_lines,narrow_to_wide(gettext("Camera update disabled")),-103.00);
vlprint(CN_ACTION,gettext("Camera update disabled"));
}else{
chatline_add(&chat_lines,narrow_to_wide(gettext("Camera update enabled")),-103.00);
vlprint(CN_ACTION,gettext("Camera update enabled"));
}
}else if (input->wasKeyDown(getKeySetting(VLKC_TOGGLE_DEBUG))) {
// Initial / 3x toggle: Chat only
@ -1232,14 +1209,14 @@ void the_game(
if (!show_debug) {
show_debug = true;
show_debug_frametime = false;
chatline_add(&chat_lines,narrow_to_wide(gettext("Debug info shown")),-103.00);
vlprint(CN_ACTION,gettext("Debug info shown"));
}else if (show_debug_frametime) {
show_debug = false;
show_debug_frametime = false;
chatline_add(&chat_lines,narrow_to_wide(gettext("Debug info and frametime graph hidden")),-103.00);
vlprint(CN_ACTION,gettext("Debug info and frametime graph hidden"));
}else{
show_debug_frametime = true;
chatline_add(&chat_lines,narrow_to_wide(gettext("Frametime graph shown")),-103.00);
vlprint(CN_ACTION,gettext("Frametime graph shown"));
}
}else if (input->wasKeyDown(getKeySetting(VLKC_TOGGLE_PROFILER))) {
show_profiler = (show_profiler + 1) % (show_profiler_max + 1);
@ -1249,28 +1226,22 @@ void the_game(
show_profiler, show_profiler_max);
if (show_profiler != 0) {
char buff[512];
snprintf(buff,512,gettext("Profiler shown (page %d of %d)"),show_profiler,show_profiler_max);
chatline_add(&chat_lines,narrow_to_wide(buff),-103.00);
vlprintf(CN_ACTION,gettext("Profiler shown (page %d of %d)"),show_profiler,show_profiler_max);
}else{
chatline_add(&chat_lines,narrow_to_wide(gettext("Profiler hidden")),-103.00);
vlprint(CN_ACTION,gettext("Profiler hidden"));
}
}else if (input->wasKeyDown(getKeySetting(VLKC_RANGE_PLUS))) {
char buff[512];
int range = config_get_int("client.graphics.range.min");
range += 10;
config_set_int("client.graphics.range.min",range);
snprintf(buff,512,gettext("Minimum viewing range changed to %d"),range);
chatline_add(&chat_lines,narrow_to_wide(buff),-103.00);
vlprintf(CN_ACTION,gettext("Minimum viewing range changed to %d"),range);
}else if (input->wasKeyDown(getKeySetting(VLKC_RANGE_MINUS))) {
char buff[512];
int range = config_get_int("client.graphics.range.min");
range -= 10;
if (range < 10)
range = 10;
config_set_int("client.graphics.range.min",range);
snprintf(buff,512,gettext("Minimum viewing range changed to %d"),range);
chatline_add(&chat_lines,narrow_to_wide(buff),-103.00);
vlprintf(CN_ACTION,gettext("Minimum viewing range changed to %d"),range);
}
// Item selection with mouse wheel
@ -1336,10 +1307,10 @@ void the_game(
draw_control.range_all = !draw_control.range_all;
if (draw_control.range_all) {
infostream<<"Enabled full viewing range"<<std::endl;
chatline_add(&chat_lines,narrow_to_wide(gettext("Enabled full viewing range")),-103.00);
vlprint(CN_ACTION,gettext("Enabled full viewing range"));
}else{
infostream<<"Disabled full viewing range"<<std::endl;
chatline_add(&chat_lines,narrow_to_wide(gettext("Disabled full viewing range")),-103.00);
vlprint(CN_ACTION,gettext("Disabled full viewing range"));
}
}
@ -2010,68 +1981,9 @@ void the_game(
guitext_info->setVisible(false);
}
/*
Get chat messages from client
*/
{
std::wstring message;
/* get new messages */
while (client.getChatMessage(message)) {
chatline_add(&chat_lines,message,0.0);
}
}
if (chat_lines) {
ref_t *ref;
ref_t *refn;
ChatLine *line;
std::wstring whole;
s16 line_number = 0;
/* first, remove old status messages */
ref = chat_lines;
while (ref) {
line = (ChatLine*)ref->ref;
if (line->age < -50) {
line->age += dtime;
if (line->age > -100.0) {
refn = ref;
ref = ref->next;
chat_lines = (ref_t*)list_remove(&chat_lines,refn);
delete line;
free(refn);
continue;
}
}else{
line_number++;
}
ref = ref->next;
}
/* second, remove old and excess chat messages */
ref = chat_lines;
while (ref) {
line = (ChatLine*)ref->ref;
if (line->age > -50) {
line_number--;
line->age += dtime;
float allowed_age = (6-line_number) * 60.0;
if (line->age > allowed_age) {
refn = ref;
ref = ref->next;
chat_lines = (ref_t*)list_remove(&chat_lines,refn);
delete line;
free(refn);
continue;
}
}
whole += line->text + L'\n';
ref = ref->next;
}
guitext_chat->setText(whole.c_str());
// Update gui element size and position
if (ui_console_step(dtime)) {
std::wstring chattext = narrow_to_wide(ui_console_get());
guitext_chat->setText(chattext.c_str());
s32 chat_y = 5+(2*text_height);
core::rect<s32> rect(
10,
@ -2079,13 +1991,19 @@ void the_game(
screensize.X - 10,
chat_y + guitext_chat->getTextHeight()
);
guitext_chat->setRelativePosition(rect);
// Don't show chat if empty or profiler or debug is enabled
guitext_chat->setVisible(chat_lines != NULL && show_chat && show_profiler == 0);
guitext_chat->setVisible(show_chat && show_profiler == 0);
}else{
guitext_chat->setVisible(false);
s32 chat_y = 5+(2*text_height);
core::rect<s32> rect(
10,
chat_y,
screensize.X - 10,
chat_y + guitext_chat->getTextHeight()
);
guitext_chat->setRelativePosition(rect);
}
/*
@ -2353,6 +2271,7 @@ void the_game(
clouds->drop();
clear_particles();
ui_console_clear();
bridge_register_client(NULL);

View File

@ -127,27 +127,29 @@ void vlprint(uint8_t type, char* str)
return;
switch (type) {
case 1:
case CN_ERROR:
strcpy(buff,"ERROR: ");
b += 7;
s -= 7;
break;
case 2:
case CN_WARN:
strcpy(buff,"WARNING: ");
b += 9;
s -= 9;
break;
case 3:
case CN_ACTION:
strcpy(buff,"ACTION: ");
b += 8;
s -= 8;
break;
case 4:
case CN_CHAT:
strcpy(buff,"CHAT: ");
b += 6;
s -= 6;
break;
case 6:
case CN_INFO:
break;
case CN_DEBUG:
strcpy(buff,"DEBUG: ");
b += 7;
s -= 7;
@ -162,9 +164,10 @@ void vlprint(uint8_t type, char* str)
if (type >= logdata.system_min_level && type <= logdata.system_max_level)
printf("%s\n",buff);
/*sys_console_print(buff,1);*/
/* TODO: log to game console */
/*if (type >= logdata.console_min_level && type <= logdata.console_max_level)
console_put(buff);*/
#ifndef SERVER
if (type >= logdata.console_min_level && type <= logdata.console_max_level)
ui_console_addline(type,str);
#endif
if (type < logdata.min_level || type > logdata.max_level)
return;

213
src/ui_console.c Normal file
View File

@ -0,0 +1,213 @@
/************************************************************************
* ui_console.c
* voxelands - 3d voxel world sandbox game
* Copyright (C) Lisa 'darkrose' Milne 2017 <lisa@ltmnet.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>
************************************************************************/
#include "common.h"
#include "list.h"
#include "thread.h"
#include <stdarg.h>
#include <string.h>
typedef struct chatline_s {
struct chatline_s *prev;
struct chatline_s *next;
uint8_t type;
float age;
char buff[1024];
} chatline_t;
static struct {
chatline_t *lines;
mutex_t *mutex;
int count;
int changed;
char buff[10240];
} ui_console_data = {
NULL,
NULL,
0,
1
};
void ui_console_addline(uint8_t type, char* txt)
{
chatline_t *l;
chatline_t *p;
char* b;
int s = 1024;
if (!txt || !txt[0])
return;
l = malloc(sizeof(chatline_t));
if (!l)
return;
l->type = type;
b = l->buff;
l->age = 0.0;
switch (type) {
case CN_ERROR:
strcpy(l->buff,"ERROR: ");
b += 7;
s -= 7;
break;
case CN_WARN:
strcpy(l->buff,"WARNING: ");
b += 9;
s -= 9;
break;
case CN_ACTION:
strcpy(l->buff,"ACTION: ");
b += 8;
s -= 8;
break;
case CN_CHAT:
case CN_INFO:
break;
case CN_DEBUG:
strcpy(l->buff,"DEBUG: ");
b += 7;
s -= 7;
break;
default:;
}
if (snprintf(b,s,"%s",txt) >= s)
return;
if (!ui_console_data.mutex)
ui_console_data.mutex = mutex_create();
mutex_lock(ui_console_data.mutex);
printf("CHATLINE: '%s'\n",l->buff);
p = list_last(&ui_console_data.lines);
if (p && p->type == l->type && !strcmp(p->buff,l->buff)) {
p->age = 0.0;
free(l);
}else{
ui_console_data.lines = list_push(&ui_console_data.lines,l);
ui_console_data.changed = 1;
}
mutex_unlock(ui_console_data.mutex);
}
void ui_console_addlinef(uint8_t type, char* fmt, ...)
{
char buff[1024];
va_list ap;
if (!fmt || !fmt[0])
return;
va_start(ap, fmt);
if (vsnprintf(buff, 1024, fmt, ap) >= 1024) {
va_end(ap);
return;
}
va_end(ap);
}
void ui_console_clear()
{
chatline_t *l;
if (!ui_console_data.mutex)
return;
mutex_lock(ui_console_data.mutex);
while ((l = list_pop(&ui_console_data.lines)) != NULL) {
free(l);
}
mutex_unlock(ui_console_data.mutex);
mutex_free(ui_console_data.mutex);
ui_console_data.mutex = NULL;
ui_console_data.count = 0;
ui_console_data.changed = 1;
ui_console_data.buff[0] = 0;
}
int ui_console_step(float dtime)
{
chatline_t *line;
chatline_t *rem;
int changed = ui_console_data.changed;
int count = 0;
if (!ui_console_data.mutex)
return 0;
mutex_lock(ui_console_data.mutex);
line = ui_console_data.lines;
while (line) {
if (line->age > 60.0) {
changed = 1;
rem = line;
line = line->next;
ui_console_data.lines = list_remove(&ui_console_data.lines,rem);
free(rem);
continue;
}
count++;
line = line->next;
}
while (count > 5 && ui_console_data.lines) {
changed = 1;
rem = list_pull(&ui_console_data.lines);
free(rem);
}
if (changed) {
int s = 10239;
int l;
char* b = ui_console_data.buff;
line = ui_console_data.lines;
while (line && s > 0) {
l = strlen(line->buff);
if (snprintf(b,s,"%s\n",line->buff) < s) {
l++;
b += l;
s -= l;
}
line = line->next;
}
*b = 0;
}
ui_console_data.changed = 0;
mutex_unlock(ui_console_data.mutex);
return changed;
}
/* TODO: this, but it's a C++ bridge, so not really */
char* ui_console_get()
{
if (!ui_console_data.mutex)
return "";
mutex_lock(ui_console_data.mutex);
return ui_console_data.buff;
mutex_unlock(ui_console_data.mutex);
}