diff options
author | Eugenio Favalli <elvenprogrammer@gmail.com> | 2004-09-26 13:08:46 +0000 |
---|---|---|
committer | Eugenio Favalli <elvenprogrammer@gmail.com> | 2004-09-26 13:08:46 +0000 |
commit | 92bbeab96bf61edf9b7caa125ed67e634258383e (patch) | |
tree | a95dd426590c8e6208445290fa8b9b47c1a57bcb /src/gui | |
parent | e46b2cdbf205d3d2e17266e3168fdbecd5f53222 (diff) | |
download | mana-92bbeab96bf61edf9b7caa125ed67e634258383e.tar.gz mana-92bbeab96bf61edf9b7caa125ed67e634258383e.tar.bz2 mana-92bbeab96bf61edf9b7caa125ed67e634258383e.tar.xz mana-92bbeab96bf61edf9b7caa125ed67e634258383e.zip |
*** empty log message ***
Diffstat (limited to 'src/gui')
-rw-r--r-- | src/gui/char_select.cpp | 221 | ||||
-rw-r--r-- | src/gui/char_select.h | 41 | ||||
-rw-r--r-- | src/gui/char_server.cpp | 141 | ||||
-rw-r--r-- | src/gui/char_server.h | 41 | ||||
-rw-r--r-- | src/gui/chat.cpp | 303 | ||||
-rw-r--r-- | src/gui/chat.h | 150 | ||||
-rw-r--r-- | src/gui/gui.cpp | 1471 | ||||
-rw-r--r-- | src/gui/gui.h | 121 | ||||
-rw-r--r-- | src/gui/inventory.cpp | 249 | ||||
-rw-r--r-- | src/gui/inventory.h | 80 | ||||
-rw-r--r-- | src/gui/login.cpp | 139 | ||||
-rw-r--r-- | src/gui/login.h | 43 | ||||
-rw-r--r-- | src/gui/skill.cpp | 56 | ||||
-rw-r--r-- | src/gui/skill.h | 40 |
14 files changed, 3096 insertions, 0 deletions
diff --git a/src/gui/char_select.cpp b/src/gui/char_select.cpp new file mode 100644 index 00000000..e58a8d73 --- /dev/null +++ b/src/gui/char_select.cpp @@ -0,0 +1,221 @@ +/** + + The Mana World + Copyright 2004 The Mana World Development Team + + This file is part of The Mana World. + + The Mana World 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 2 of the License, or + any later version. + + The Mana World 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 The Mana World; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +*/ + +#include "char_select.h" +#include "../Graphic/graphic.h" + +char button_state[3]; +char address[41]; +char name[25]; + +DIALOG char_select_dialog[] = { + /* (dialog proc) (x) (y) (w) (h) (fg) (bg) (key) (flags) (d1) (d2) (dp) (dp2) (dp3) */ + { tmw_dialog_proc, 300, 240, 200, 208, 0, -1, 0, 0, 0, 0, (char*)"Char select", NULL, NULL }, + { tmw_text_proc, 308, 268, 192, 10, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL }, + { tmw_bitmap_proc, 304, 282, 192, 70, 0, 0, 0, 0, 80, 60, playerset, NULL, NULL }, + { tmw_button_proc, 398, 426, 44, 18, 0, -1, 'o', D_EXIT, -1, 0, (char*)"&Ok", NULL, NULL }, + { tmw_button_proc, 446, 426, 44, 18, 0, -1, 'c', D_EXIT, -1, 0, (char*)"&Cancel", NULL, NULL }, + { tmw_button_proc, 304, 426, 44, 18, 0, 0, 0, D_EXIT, 0, 0, button_state, NULL, NULL }, +/* { gui_button_proc, 304, 356, 20, 20, 0, 0, 0, 0, 0, 0, "<", NULL, NULL }, + { gui_button_proc, 328, 356, 20, 20, 0, 0, 0, 0, 0, 0, ">", NULL, NULL }, */ + { NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL }, +}; + +DIALOG char_create_dialog[] = { + /* (dialog proc) (x) (y) (w) (h) (fg) (bg) (key) (flags) (d1) (d2) (dp) (dp2) (dp3) */ + { tmw_dialog_proc, 276, 240, 248, 116, 0, -1, 0, 0, 0, 0, (char*)"Char create", NULL, NULL }, + { tmw_text_proc, 280, 268, 192, 20, 0, 0, 0, 0, 0, 0, (char *)"Name: ", NULL, NULL }, + { tmw_edit_proc, 336, 268, 162, 20, 0, 0, 0, 0, 24, 0, name, NULL, NULL }, + { tmw_button_proc, 398, 334, 44, 18, 0, -1, 'o', D_EXIT, -1, 0, (char*)"&Ok", NULL, NULL }, + { tmw_button_proc, 446, 334, 44, 18, 0, -1, 'c', D_EXIT, -1, 0, (char*)"&Cancel", NULL, NULL }, + { NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL }, +}; + +void char_select() { + state = LOGIN; + if(n_character>0) { + char_select_dialog[1].dp = char_info->name; + char_select_dialog[1].x = 400-alfont_text_length(gui_font, char_info->name)/2; + char_select_dialog[2].dp = playerset; + if(playerset==NULL)ok("Error", "Playerset not loaded"); + strcpy(button_state, "Del"); + char_select_dialog[3].flags &= D_CLOSE; + } else { + char *temp = (char *)malloc(3); + strcpy(temp, ""); + char_select_dialog[1].dp = temp; + char_select_dialog[3].flags |= D_DISABLED; + char_select_dialog[2].dp = NULL; + strcpy(button_state, "New"); + } + //centre_dialog(char_select_dialog); + DIALOG_PLAYER *player = init_dialog(char_select_dialog, -1); + int gui_exit = 1; + while ((!key[KEY_ESC])&&(gui_exit)&&(!key[KEY_ENTER])) { + clear_bitmap(buffer); + if(stretch_mode!=0)blit((BITMAP *)graphic[LOGIN_BMP].dat, buffer, 0, 0, 80, 60, 640, 480); + else blit((BITMAP *)graphic[LOGIN_BMP].dat, buffer, 0, 0, -120, -90, 640, 480); + gui_exit = gui_update(player); + blit(buffer, screen, 0, 0, 0, 0, 800, 600); + } + gui_exit = shutdown_dialog(player); + if((gui_exit==3)||(key[KEY_ENTER]))server_char_select(); + else if(gui_exit==4)close_session(); + else if(gui_exit==5)server_char_delete(); + if(state==LOGIN)close_session(); +} + +void server_char_select() { + // Request character selection + WFIFOW(0) = net_w_value(0x0066); + WFIFOB(2) = net_b_value(0); + WFIFOSET(3); + + while((in_size<3)||(out_size>0))flush(); + log_hex("Char_Select_Packet", "Packet_ID", RFIFOW(0)); + log_int("Char_Select_Packet", "Packet_length", get_length(RFIFOW(0))); + log_int("Char_Select_Packet", "Packet_in_size", RFIFOW(2)); + log_int("Char_Select_Packet", "In_size", in_size); + + if(RFIFOW(0)==0x0071) { + while(in_size<28)flush(); + char_ID = RFIFOL(2); + memset(map_path, '\0', 480); + append_filename(map_path, "./data/map/", RFIFOP(6), 480); + map_address = RFIFOL(22); + map_port = RFIFOW(26); + state = GAME; + + log("Player", "map", map_name); + log("Char_Select_packet", "server_address", iptostring(map_address)); + log_int("Char_Select_packet", "server_port", map_port); + RFIFOSKIP(28); + close_session(); + } else if(RFIFOW(0)==0x006c) { + switch(RFIFOB(2)) { + case 0: + ok("Error", "Access denied"); + break; + case 1: + ok("Error", "Cannot use this ID"); + break; + } + state = CHAR_SELECT; + RFIFOSKIP(3); + } + // Todo: add other packets +} + +void server_char_delete() { + state = CHAR_SELECT; + // Delete a character + if(!strcmp(button_state, "Del")) { + if(yes_no("Confirm", "Are you sure?")==0) { + // Request character deletion + WFIFOW(0) = net_w_value(0x0068); + WFIFOL(2) = net_l_value(char_info[0].id); + WFIFOSET(46); + + while((in_size<2)||(out_size>0))flush(); + if(RFIFOW(0)==0x006f) { + RFIFOSKIP(2); + ok("Info", "Player deleted"); + free(char_info); + n_character = 0; + } else if(RFIFOW(0)==0x006c) { + switch(RFIFOB(2)) { + case 0: + ok("Error", "Access denied"); + break; + case 1: + ok("Error", "Cannot use this ID"); + break; + } + RFIFOSKIP(3); + } else ok("Error", "Unknown error"); + } + // Create a new character + } else { + centre_dialog(char_create_dialog); + DIALOG_PLAYER *player = init_dialog(char_create_dialog, -1); + int gui_exit = 1; + while ((!key[KEY_ESC])&&(gui_exit)) { + clear_bitmap(buffer); + if(stretch_mode!=0)blit((BITMAP *)graphic[LOGIN_BMP].dat, buffer, 0, 0, 80, 60, 640, 480); + else blit((BITMAP *)graphic[LOGIN_BMP].dat, buffer, 0, 0, -120, -90, 640, 480); + gui_exit = gui_update(player); + blit(buffer, screen, 0, 0, 0, 0, 800, 600); + } + gui_exit = shutdown_dialog(player); + if(gui_exit==3) { + WFIFOW(0) = net_w_value(0x0067); + strcpy(WFIFOP(2), name); + WFIFOB(26) = net_b_value(5); + WFIFOB(27) = net_b_value(5); + WFIFOB(28) = net_b_value(5); + WFIFOB(29) = net_b_value(5); + WFIFOB(30) = net_b_value(5); + WFIFOB(31) = net_b_value(5); + WFIFOB(32) = net_b_value(0); + WFIFOW(33) = net_w_value(1); + WFIFOW(35) = net_w_value(1); + WFIFOSET(37); + + while((in_size<3)||(out_size>0))flush(); + if(RFIFOW(0)==0x006d) { + while(in_size<108)flush(); + char_info = (CHAR_SEL_INFO *)malloc(sizeof(CHAR_SEL_INFO)); + char_info->id = account_ID; + memset(char_info->name, '\0', 24); + strcpy(char_info[0].name, RFIFOP(2+74)); + char_info->hp = RFIFOW(2+42); + char_info->max_hp = RFIFOW(2+44); + char_info->sp = RFIFOW(2+46); + char_info->max_sp = RFIFOW(2+48); + char_info->job_lv = RFIFOL(2+16); + char_info->job_xp = RFIFOL(2+12); + char_info->lv = RFIFOW(2+58); + char_info->xp = RFIFOL(2+4); + char_info->zeny = RFIFOL(2+8); + char_info->STR = RFIFOB(2+98); + char_info->AGI = RFIFOB(2+99); + char_info->VIT = RFIFOB(2+100); + char_info->INT = RFIFOB(2+101); + char_info->DEX = RFIFOB(2+102); + char_info->LUK = RFIFOB(2+103); + RFIFOSKIP(108); + n_character++; + } else if(RFIFOW(0)==0x006c) { + switch(RFIFOB(2)) { + case 0: + ok("Error", "Access denied"); + break; + case 1: + ok("Error", "Cannot use this ID"); + break; + } + RFIFOSKIP(3); + } else ok("Error", "Unknown error"); + } + } +} diff --git a/src/gui/char_select.h b/src/gui/char_select.h new file mode 100644 index 00000000..94a8e820 --- /dev/null +++ b/src/gui/char_select.h @@ -0,0 +1,41 @@ +/** + + The Mana World + Copyright 2004 The Mana World Development Team + + This file is part of The Mana World. + + The Mana World 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 2 of the License, or + any later version. + + The Mana World 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 The Mana World; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +*/ + +#ifdef WIN32 + #pragma warning (disable:4312) +#endif + +#ifndef _CHAR_SELECT_H +#define _CHAR_SELECT_H + +#include <allegro.h> + +#include "../main.h" +#include "../Net/network.h" +#include "gui.h" + +void char_select(); +void server_char_select(); +void server_char_delete(); + +#endif diff --git a/src/gui/char_server.cpp b/src/gui/char_server.cpp new file mode 100644 index 00000000..36ef5d53 --- /dev/null +++ b/src/gui/char_server.cpp @@ -0,0 +1,141 @@ +/** + + The Mana World + Copyright 2004 The Mana World Development Team + + This file is part of The Mana World. + + The Mana World 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 2 of the License, or + any later version. + + The Mana World 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 The Mana World; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +*/ + +#include "char_server.h" +#include "../Graphic/graphic.h" + +char server[30]; + +DIALOG char_server_dialog[] = { + /* (dialog proc) (x) (y) (w) (h) (fg) (bg) (key) (flags) (d1) (d2) (dp) (dp2) (dp3) */ + { tmw_dialog_proc, 300, 240, 200, 104, 0, -1, 0, 0, 0, 0, (char*)"Server select", NULL, NULL }, + { tmw_list_proc, 304, 262, 192, 55, 0, 0, 0, 0, 0, 0, (char*)server_list, NULL, NULL }, + { tmw_button_proc, 398, 322, 44, 18, 0, -1, 'o', D_EXIT, -1, 0, (char*)"&Ok", NULL, NULL }, + { tmw_button_proc, 446, 322, 44, 18, 0, -1, 'c', D_EXIT, -1, 0, (char*)"&Cancel", NULL, NULL }, + { NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL }, +}; + +/** Helper function to create server list */ +char *server_list(int index, int *size) { + static char buffer[30]; + if (index < 0) { + *size = n_server; + return NULL; + } + sprintf(buffer, "%s (%i)", server_info[index].name, server_info[index].online_users); + return buffer; +} + +void char_server() { + state = LOGIN; + centre_dialog(char_server_dialog); + DIALOG_PLAYER *player = init_dialog(char_server_dialog, -1); + if(!player)ok("Error", "Unable to initialize login dialog"); + int gui_exit = 1; + if(n_server==0)char_server_dialog[2].flags |= D_DISABLED; + while ((!key[KEY_ESC])&&(gui_exit)&&(!key[KEY_ENTER])) { + clear_bitmap(buffer); + if(stretch_mode!=0)blit((BITMAP *)graphic[LOGIN_BMP].dat, buffer, 0, 0, 80, 60, 640, 480); + else blit((BITMAP *)graphic[LOGIN_BMP].dat, buffer, 0, 0, -120, -90, 640, 480); + gui_exit = gui_update(player); + blit(buffer, screen, 0, 0, 0, 0, 800, 600); + } + gui_exit = shutdown_dialog(player); + if((gui_exit==2)||(key[KEY_ENTER])) { + server_char_server(); + } +} + +void server_char_server() { + int ret; + state = LOGIN; + + // Connect to char server + ret = open_session(iptostring(server_info[char_server_dialog[1].d1].address), server_info[char_server_dialog[1].d1].port); + if(ret==SOCKET_ERROR) { + ok("Error", "Unable to connect to char server"); + return; + } + + // Send login infos + WFIFOW(0) = net_w_value(0x0065); + WFIFOL(2) = net_l_value(account_ID); + WFIFOL(6) = net_l_value(session_ID1); + WFIFOL(10) = net_l_value(session_ID2); + WFIFOW(14) = 0; + WFIFOB(16) = net_b_value(sex); + WFIFOSET(17); + + while((in_size<4)||(out_size>0))flush(); + RFIFOSKIP(4); + + while(in_size<3)flush(); + + if(RFIFOW(0)==0x006b) { + while(in_size<RFIFOW(2))flush(); + n_character = (RFIFOW(2)-24)/106; + char_info = (CHAR_SEL_INFO *)malloc(sizeof(CHAR_SEL_INFO)*n_character); + for(int i=0;i<n_character;i++) { + char_info[i].id = RFIFOL(24+106*i); + strcpy(char_info[i].name, RFIFOP(24+106*i+74)); + char_info[i].hp = RFIFOW(24+106*i+42); + char_info[i].max_hp = RFIFOW(24+106*i+44); + char_info[i].xp = RFIFOL(24+106*i+4); + char_info[i].zeny = RFIFOL(24+106*i+8); + char_info[i].job_xp = RFIFOL(24+106*i+16); + char_info[i].job_lv = RFIFOL(24+106*i+24); + char_info[i].sp = RFIFOW(24+106*i+46); + char_info[i].max_sp = RFIFOW(24+106*i+48); + char_info[i].lv = RFIFOW(24+106*i+58); + char_info[i].STR = RFIFOB(24+106*i+98); + char_info[i].AGI = RFIFOB(24+106*i+99); + char_info[i].VIT = RFIFOB(24+106*i+100); + char_info[i].INT = RFIFOB(24+106*i+101); + char_info[i].DEX = RFIFOB(24+106*i+102); + char_info[i].LUK = RFIFOB(24+106*i+103); + } + state = CHAR_SELECT; + + log("Player", "name", char_info->name); + log_hex("Char_Server_Packet", "Packet_ID", RFIFOW(0)); + log_int("Char_Server_Packet", "Packet_length", RFIFOW(2)); + + + RFIFOSKIP(RFIFOW(2)); + } else if(RFIFOW(0)==0x006c) { + switch(RFIFOB(2)) { + case 0: + ok("Error", "Access denied"); + break; + case 1: + ok("Error", "Cannot use this ID"); + break; + default: + ok("Error", "Rejected from server"); + break; + } + RFIFOSKIP(3); + close_session(); + } else ok("Error", "Unknown error"); + // Todo: add other packets +} diff --git a/src/gui/char_server.h b/src/gui/char_server.h new file mode 100644 index 00000000..866f5070 --- /dev/null +++ b/src/gui/char_server.h @@ -0,0 +1,41 @@ +/** + + The Mana World + Copyright 2004 The Mana World Development Team + + This file is part of The Mana World. + + The Mana World 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 2 of the License, or + any later version. + + The Mana World 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 The Mana World; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +*/ + +#ifdef WIN32 + #pragma warning (disable:4312) +#endif + +#ifndef _CHAR_SEL_SERVER_H +#define _CHAR_SEL_SERVER_H + +#include <allegro.h> + +#include "../main.h" +#include "../Net/network.h" +#include "gui.h" + +void char_server(); +void server_char_server(); +char *server_list(int index, int *size); + +#endif diff --git a/src/gui/chat.cpp b/src/gui/chat.cpp new file mode 100644 index 00000000..2f0385c9 --- /dev/null +++ b/src/gui/chat.cpp @@ -0,0 +1,303 @@ +/** + + The Mana World + Copyright 2004 The Mana World Development Team + + This file is part of The Mana World. + + The Mana World 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 2 of the License, or + any later version. + + The Mana World 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 The Mana World; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +*/ + +/** + Simple ChatLog Object v0.5 (i'd say...) + + Bestviewd w/ Bitstream Vera Sans Mono @ 9pt and a tab-width of 2 spaces + + Author: kth5 aka Alexander Baldeck + pipe your questions, suggestions and flames to: kth5@gawab.com +*/ + +#include "../main.h" +#include "chat.h" +#include <list> +#include <string> +#include <fstream> + +using namespace std; + + +Chat::Chat(const char * logfile, int item_num) { + chatlog_file.open(logfile, ios::out | ios::app); + items = 0; + items_keep = item_num; +} + +Chat::~Chat() { + chatlog_file.flush(); + chatlog_file.close(); +} + +void Chat::chat_dlgrsize(int) { +} + +/** adds a line of text to our message list + + string line -> message text + int own -> type of message (usually the owner-type) + ALFONT_FONT * font -> font that'll be used to draw the text later + + NOTE: + to all of you who wonder why the font needs to be passed, simple. + i already store the width in pixel in the list rather than + calculating it again and again on every draw event. ;-) +*/ +void Chat::chat_log(string line, int own, ALFONT_FONT * font) { + int pos; + CHATLOG tmp; + + if(items<=items_keep) + items++; // delete overhead from the end of the list + else + chatlog.pop_back(); + + pos = 0; + pos = (int)line.find(" : ", 0); + if(pos > 0) { + tmp.nick = line.substr(0,pos); + switch(own) { + case ACT_IS : + tmp.nick += CAT_IS; + break; + case ACT_WHISPER : + tmp.nick += CAT_WHISPER; + break; + default : + tmp.nick += CAT_NORMAL; + } + tmp.width = TEXT_GETWIDTH(tmp.nick.c_str())+2; + line.erase(0,pos+3); + }else { + tmp.nick = ""; + tmp.width = 1; + } + tmp.own = own; + tmp.text = line; + + chatlog_file << tmp.nick << tmp.text << "\n"; + chatlog_file.flush(); + + chatlog.push_front(tmp); +} + +void Chat::chat_log(CHATSKILL action, ALFONT_FONT * font) { + chat_log(const_msg(action), BY_SERVER, font); +} + + +/** draw first n lines of the list onto a Allegro type bitmap buffer + using Alfont + + BITMAP * bmp -> Allegro type bitmap buffer to draw onto + int n -> number of lines to be drawn + ALFONT_FONT * font -> font to use + + NOTE: + take great care using this, make sure the buffer passed is + empty! ;-) anyway, line wrapping is not supported yet. +*/ +void Chat::chat_draw(BITMAP * bmp, int n, ALFONT_FONT * font) { + int y = 600-35, i = 0; + CHATLOG line; + n -= 1; + + for(iter = chatlog.begin(); iter != chatlog.end(); iter++) { + line = *iter; + y -=11; + + switch(line.own) { + case BY_GM : + alfont_textprintf_aa(bmp, font, 1, y, COLOR_BLUE, "Global announcement: "); + alfont_textprintf_aa(bmp, font, TEXT_GETWIDTH("Global announcement: "), y, COLOR_GREEN, line.text.c_str()); + break; + case BY_PLAYER : + alfont_textprintf_aa(bmp, font, 1, y, COLOR_YELLOW, line.nick.c_str()); + alfont_textprintf_aa(bmp, font, line.width, y, COLOR_WHITE, line.text.c_str()); + break; + case BY_OTHER : + alfont_textprintf_aa(bmp, font, 1, y, COLOR_GREEN, line.nick.c_str()); + alfont_textprintf_aa(bmp, font, line.width, y, COLOR_WHITE, line.text.c_str()); + break; + default : + alfont_textprintf_aa(bmp, font, 1, y, COLOR_LIGHTBLUE, line.text.c_str()); + } + + if(i>=n) + return; + i++; + } +} + +/** determines wether to send a command or an ordinary message, then + contructs packets & sends them + + string nick -> the character's name to display infront + string msg -> the message's text which is to be send. + + NOTE: + the nickname is required by the server, if not specified + the message may not be sent unless a command was intended + which requires another packet to be constructed! you can + achieve this by putting a slash ("/") infront of the + message followed by the command name and the message. + of course all slash-commands need implemented handler- + routines. ;-) + remember, a line starting w/ "@" is not a command that needs + to be parsed rather is sent using the normal chat-packet. + + EXAMPLE: + // for an global announcement /- command + chatlog.chat_send("", "/announce Hello to all logged in users!"); + // for simple message by a user /- message + chatlog.chat_send("Zaeiru", "Hello to all users on the screen!"); +*/ +char * Chat::chat_send(string nick, string msg) { + short len = 0, packid; + char *temp = NULL; + + // prepare command + if(msg.substr(0,1)=="/") { + // global announcement + if(msg.substr(0,IS_ANNOUNCE_LENGTH) == IS_ANNOUNCE) { + msg.erase(0,IS_ANNOUNCE_LENGTH); + packid = 0x0099; + } else { + packid = 0x008c; + len = (short)msg.length()+4; + } + len = (short)msg.length()+4; + // prepare ordinary message + } else { + // temporary hack to make messed-up-keyboard-ppl able to send GM commands + if(msg.substr(0,1)=="#") + msg.replace(0,1,"@"); + // end temp. hack XD + nick += " : "; + nick += msg; + msg = nick; + packid = 0x008c; + len = (short)(nick.length()+msg.length()+3); + } + + // send processed message + temp = new char[len]; + memcpy(temp, msg.c_str(), len); + WFIFOW(0) = net_w_value(packid); + WFIFOW(2) = net_w_value(len+4); + memcpy(WFIFOP(4), temp, len); + WFIFOSET(len+4); + delete temp; + nick = msg = ""; + return ""; +} + +/** PRIVATE : + NOTE: + these usually will be left undocumented coz u can't call them + directly anyway. ;-) +*/ + +/** constructs failed messages for actions */ +string Chat::const_msg(CHATSKILL action) { + string msg; + if(action.success == SKILL_FAILED && action.skill == SKILL_BASIC) { + switch(action.bskill) { + case BSKILL_TRADE : + msg = "Trade failed!"; + break; + case BSKILL_EMOTE : + msg = "Emote failed!"; + break; + case BSKILL_SIT : + msg = "Sit failed!"; + break; + case BSKILL_CREATECHAT : + msg = "Chat creating failed!"; + break; + case BSKILL_JOINPARTY : + msg = "Could not join party!"; + break; + case BSKILL_SHOUT : + msg = "Cannot shout!"; + break; + } + + switch(action.reason) { + case RFAIL_SKILLDEP : + msg += " You have not yet reached a high enough lvl!"; + break; + case RFAIL_INSUFHP : + msg += " Insufficient HP!"; + break; + case RFAIL_INSUFSP : + msg += " Insufficient SP!"; + break; + case RFAIL_NOMEMO : + msg += " You have no memos!"; + break; + case RFAIL_SKILLDELAY : + msg += " You cannot do that right now!"; + break; + case RFAIL_ZENY : + msg += " Seems you need more Zeny... ;-)"; + break; + case RFAIL_WEAPON : + msg += " You cannot use this skill with that kind of weapon!"; + break; + case RFAIL_REDGEM : + msg += " You need another red gem!"; + break; + case RFAIL_BLUEGEM : + msg += " You need another blue gem!"; + break; + case RFAIL_OVERWEIGHT : + msg += " You're carrying to much to do this!"; + break; + default : + msg += " Huh? What's that?"; + break; + } + }else{ + switch(action.skill) { + case SKILL_WARP : + msg = "Warp failed..."; + break; + case SKILL_STEAL : + msg = "Could not steal anything..."; + break; + case SKILL_ENVENOM : + msg = "Poison had no effect..."; + break; + } + } + + return msg; +} + +string const_msg(int own) { + string msg; + return msg; +} + diff --git a/src/gui/chat.h b/src/gui/chat.h new file mode 100644 index 00000000..cfe16beb --- /dev/null +++ b/src/gui/chat.h @@ -0,0 +1,150 @@ +/** + + The Mana World + Copyright 2004 The Mana World Development Team + + This file is part of The Mana World. + + The Mana World 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 2 of the License, or + any later version. + + The Mana World 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 The Mana World; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +*/ + +#ifndef _CHAT_H +#define _CHAT_H + +#include "../main.h" +#include <list> +#include <string> +#include <fstream> +#include <string> + +using namespace std; + +/** + Simple ChatLog Object v0.5 (i'd say...) + + Bestviewd w/ Bitstream Vera Sans Mono @ 9pt and a tab-width of 2 spaces + + Author: kth5 aka Alexander Baldeck + pipe your questions, suggestions and flames to: kth5@gawab.com + + NOTE: + i documented all functions in their implementation. ;-) +*/ + + +#define BY_GM 0 // those should be self-explanatory =) +#define BY_PLAYER 1 +#define BY_OTHER 2 +#define BY_SERVER 3 + +#define ACT_WHISPER 4 // getting whispered at +#define ACT_IS 5 // equivalent to "/me" in irc + +#define IS_ANNOUNCE "/announce " +#define IS_ANNOUNCE_LENGTH 10 + +/** + gets in between usernick and message text depending on + message type +*/ +#define CAT_NORMAL ": " +#define CAT_IS "" +#define CAT_WHISPER " says: " + +/** some generic color macros */ +#define COLOR_WHITE (makecol(255,255,255)) // plain white +#define COLOR_BLUE (makecol( 97,156,236)) // cold gm blue :P +#define COLOR_YELLOW (makecol(255,246, 98)) // sexy yellow +#define COLOR_GREEN (makecol( 39,197, 39)) // cool green +#define COLOR_RED (makecol(255, 0, 0)) // ack red XD +#define COLOR_LIGHTBLUE (makecol( 83,223,246)) // bright blue + +/** calculate text-width in pixel */ +#define TEXT_GETWIDTH(str) (alfont_text_length(font, str)) + +/** job dependend identifiers (?) */ +#define SKILL_BASIC 0x0001 +#define SKILL_WARP 0x001b +#define SKILL_STEAL 0x0032 +#define SKILL_ENVENOM 0x0034 + +/** basic skills identifiers */ +#define BSKILL_TRADE 0x0000 +#define BSKILL_EMOTE 0x0001 +#define BSKILL_SIT 0x0002 +#define BSKILL_CREATECHAT 0x0003 +#define BSKILL_JOINPARTY 0x0004 +#define BSKILL_SHOUT 0x0005 +#define BSKILL_PK 0x0006 // ?? +#define BSKILL_SETALLIGN 0x0007 // ?? + +/** reasons why action failed */ +#define RFAIL_SKILLDEP 0x00 +#define RFAIL_INSUFHP 0x01 +#define RFAIL_INSUFSP 0x02 +#define RFAIL_NOMEMO 0x03 +#define RFAIL_SKILLDELAY 0x04 +#define RFAIL_ZENY 0x05 +#define RFAIL_WEAPON 0x06 +#define RFAIL_REDGEM 0x07 +#define RFAIL_BLUEGEM 0x08 +#define RFAIL_OVERWEIGHT 0x09 +#define RFAIL_GENERIC 0x0a + +/** should always be zero if failed */ +#define SKILL_FAILED 0x00 + +struct CHATSKILL { + short skill; + short bskill; + short unused; + char success; + char reason; +}; + +class Chat { + public : + Chat(const char *, int); + void chat_dlgrsize(int); + + void chat_log(string, int, ALFONT_FONT *); + void chat_log(CHATSKILL, ALFONT_FONT *); // function overload -> calls original chat_log() + // after processing the packet + + void chat_draw(BITMAP *, int, ALFONT_FONT *); + char * chat_send(string, string); + ~Chat(); + private : + ofstream chatlog_file; + + typedef struct CHATLOG { // list item container object + string nick; + string text; + int own; + int width; + }; + + list<CHATLOG> chatlog; // list object ready to accept out CHATLOG struct :) + list<CHATLOG>::iterator iter; + + int items; + int items_keep; + + string const_msg(CHATSKILL); // contructs action-fail messages + string const_msg(int); // constructs normal messages (not implemented yet) +}; + +#endif diff --git a/src/gui/gui.cpp b/src/gui/gui.cpp new file mode 100644 index 00000000..cb43c47b --- /dev/null +++ b/src/gui/gui.cpp @@ -0,0 +1,1471 @@ +/** + + The Mana World + Copyright 2004 The Mana World Development Team + + This file is part of The Mana World. + + The Mana World 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 2 of the License, or + any later version. + + The Mana World 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 The Mana World; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +*/ + +#include "gui.h" +#include "allegro/internal/aintern.h" +#include <math.h> +#include <alfont.h> +#include "../Sound/sound.h" + +#ifndef WIN32 +#define __cdecl __attribute__((cdecl)) +#endif + +#define GUI_BMP_COUNT 11 +#define GUI_BMP_OFS_BUTTON 0 +#define GUI_BMP_OFS_SLIDER 4 +#define GUI_BMP_OFS_CHECKBOX 5 +#define GUI_BMP_OFS_RADIOBUTTON 6 +#define GUI_BMP_OFS_TEXTBOX 7 +#define GUI_BMP_OFS_LISTBOX 8 +#define GUI_BMP_OFS_DIALOG 9 + +#define GUI_CALL_BUTTONCALLBACK(d) +static BITMAP *gui__repository[GUI_BMP_COUNT]; + +/* The currently active skin */ +LexSkin gui_skin; +BITMAP *gui_bitmap; +ALFONT_FONT *gui_font; +bool drag; +DATAFILE *gui_gfx; + +extern TmwSound sound; + +/* very internal update stuff */ +int (*gui__external_slider_callback)(void *, int); +int reroute_slider_proc(void *dp3, int d2); + +/** Initialize gui system */ +void init_gui(BITMAP *bitmap, const char *skin) { + gui_bitmap = bitmap; + gui_load_skin(skin); + //alfont_init(); + gui_font = alfont_load_font("./data/skin/arial.ttf"); + alfont_set_font_size(gui_font, 14); + drag = false; + show_mouse(NULL); +} + +int gui_update(DIALOG_PLAYER *player) { + dialog_message(player->dialog, MSG_DRAW, 0, 0); + int ret = update_dialog(player); + draw_sprite(gui_bitmap, mouse_sprite, mouse_x, mouse_y); + return ret; +} + + +void loadButtonSkin() { + char **tokens; + int tokenCount; + int gridx[4]; + int gridy[4]; + int a = 0; + int x,y,mode; + + tokens = get_config_argv("button", "gridx", &tokenCount); + for (a=0; a < 4; a++) { + gridx[a] = atoi(tokens[a]); + } + tokens = get_config_argv("button", "gridy", &tokenCount); + for (a=0; a < 4; a++) { + gridy[a] = atoi(tokens[a]); + } + + tokens = get_config_argv("button", "textcol_norm", &tokenCount); + gui_skin.button.textcolor[0] = makecol(atoi(tokens[0]),atoi(tokens[1]),atoi(tokens[2])); + tokens = get_config_argv("button", "textcol_hilite", &tokenCount); + gui_skin.button.textcolor[1] = makecol(atoi(tokens[0]),atoi(tokens[1]),atoi(tokens[2])); + tokens = get_config_argv("button", "textcol_pressed", &tokenCount); + gui_skin.button.textcolor[2] = makecol(atoi(tokens[0]),atoi(tokens[1]),atoi(tokens[2])); + tokens = get_config_argv("button", "textcol_disabled", &tokenCount); + gui_skin.button.textcolor[3] = makecol(atoi(tokens[0]),atoi(tokens[1]),atoi(tokens[2])); + + gui__repository[GUI_BMP_OFS_BUTTON + 0] = (BITMAP *)gui_gfx[0].dat; + gui__repository[GUI_BMP_OFS_BUTTON + 1] = (BITMAP *)gui_gfx[2].dat; + gui__repository[GUI_BMP_OFS_BUTTON + 2] = (BITMAP *)gui_gfx[3].dat; + gui__repository[GUI_BMP_OFS_BUTTON + 3] = (BITMAP *)gui_gfx[1].dat; + + for (mode=0; mode < 4; mode++) { + a=0; + for (y=0; y < 3; y++) { + for (x=0; x < 3; x++) { + gui_skin.button.background[mode].grid[a] = create_sub_bitmap( + gui__repository[GUI_BMP_OFS_BUTTON + mode], + gridx[x] , gridy[y], + gridx[x+1]-gridx[x]+1, gridy[y+1]-gridy[y]+1 + ); + a++; + } + } + } +} + + +void loadSliderSkin() { + int x, y, w, h,o1,o2; + char **tokens; + int tokenCount; + + gui__repository[GUI_BMP_OFS_SLIDER] = (BITMAP *)gui_gfx[8].dat; + + tokens = get_config_argv("slider", "slider_h", &tokenCount); + x = atoi(tokens[0]); y = atoi(tokens[1]); + w = atoi(tokens[2]); h = atoi(tokens[3]); + + tokens = get_config_argv("slider", "slider_h_ofs", &tokenCount); + o1 = atoi(tokens[0]); o2 = atoi(tokens[1]); + + gui_skin.slider.hSlider[0] = create_sub_bitmap(gui__repository[GUI_BMP_OFS_SLIDER], x , y, o1-x , h); + gui_skin.slider.hSlider[1] = create_sub_bitmap(gui__repository[GUI_BMP_OFS_SLIDER], o1, y, o2-o1 , h); + gui_skin.slider.hSlider[2] = create_sub_bitmap(gui__repository[GUI_BMP_OFS_SLIDER], o2, y, w-(o2-x), h); + + tokens = get_config_argv("slider", "slider_v", &tokenCount); + x = atoi(tokens[0]); y = atoi(tokens[1]); + w = atoi(tokens[2]); h = atoi(tokens[3]); + + tokens = get_config_argv("slider", "slider_v_ofs", &tokenCount); + o1 = atoi(tokens[0]); o2 = atoi(tokens[1]); + + gui_skin.slider.vSlider[0] = create_sub_bitmap(gui__repository[GUI_BMP_OFS_SLIDER], x, y, w, o1 - y); + gui_skin.slider.vSlider[1] = create_sub_bitmap(gui__repository[GUI_BMP_OFS_SLIDER], x, o1, w, o2 - o1); + gui_skin.slider.vSlider[2] = create_sub_bitmap(gui__repository[GUI_BMP_OFS_SLIDER], x, o2, w, h - (o2-y)); + + tokens = get_config_argv("slider", "handle_v", &tokenCount); + x = atoi(tokens[0]); y = atoi(tokens[1]); + w = atoi(tokens[2]); h = atoi(tokens[3]); + gui_skin.slider.vGrip = create_sub_bitmap(gui__repository[GUI_BMP_OFS_SLIDER], x, y, w, h); + + tokens = get_config_argv("slider", "handle_h", &tokenCount); + x = atoi(tokens[0]); y = atoi(tokens[1]); + w = atoi(tokens[2]); h = atoi(tokens[3]); + gui_skin.slider.hGrip = create_sub_bitmap(gui__repository[GUI_BMP_OFS_SLIDER], x, y, w, h); +} + +void loadCheckboxSkin() { + int x, y, w,h; + char **tokens; + int tokenCount; + + gui__repository[GUI_BMP_OFS_CHECKBOX] = (BITMAP *)gui_gfx[4].dat; + + + tokens = get_config_argv("checkbox", "normal", &tokenCount); + x = atoi(tokens[0]); y = atoi(tokens[1]); + w = atoi(tokens[2]); h = atoi(tokens[3]); + gui_skin.checkbox.normal = create_sub_bitmap(gui__repository[GUI_BMP_OFS_CHECKBOX], x , y, w, h); + + tokens = get_config_argv("checkbox", "checked", &tokenCount); + x = atoi(tokens[0]); y = atoi(tokens[1]); + w = atoi(tokens[2]); h = atoi(tokens[3]); + gui_skin.checkbox.checked = create_sub_bitmap(gui__repository[GUI_BMP_OFS_CHECKBOX], x , y, w, h); + + tokens = get_config_argv("checkbox", "disabled", &tokenCount); + x = atoi(tokens[0]); y = atoi(tokens[1]); + w = atoi(tokens[2]); h = atoi(tokens[3]); + gui_skin.checkbox.disabled = create_sub_bitmap(gui__repository[GUI_BMP_OFS_CHECKBOX], x , y, w, h); + + tokens = get_config_argv("checkbox", "disabled_check", &tokenCount); + x = atoi(tokens[0]); y = atoi(tokens[1]); + w = atoi(tokens[2]); h = atoi(tokens[3]); + gui_skin.checkbox.disabled_checked = create_sub_bitmap(gui__repository[GUI_BMP_OFS_CHECKBOX], x , y, w, h); + + tokens = get_config_argv("button", "textcol_norm", &tokenCount); + gui_skin.checkbox.textcolor[0] = makecol(atoi(tokens[0]),atoi(tokens[1]),atoi(tokens[2])); + tokens = get_config_argv("button", "textcol_disabled", &tokenCount); + gui_skin.checkbox.textcolor[1] = makecol(atoi(tokens[0]),atoi(tokens[1]),atoi(tokens[2])); +} + +void loadTextboxSkin() { + char **tokens; + int tokenCount; + int gridx[4]; + int gridy[4]; + int a = 0; + int x,y; + + tokens = get_config_argv("textbox", "gridx", &tokenCount); + for (a=0; a < 4; a++) { + gridx[a] = atoi(tokens[a]); + } + tokens = get_config_argv("textbox", "gridy", &tokenCount); + for (a=0; a < 4; a++) { + gridy[a] = atoi(tokens[a]); + } + + tokens = get_config_argv("textbox", "textcol_norm", &tokenCount); + gui_skin.textbox.textcolor[0] = makecol(atoi(tokens[0]),atoi(tokens[1]),atoi(tokens[2])); + tokens = get_config_argv("textbox", "textcol_disabled", &tokenCount); + gui_skin.textbox.textcolor[1] = makecol(atoi(tokens[0]),atoi(tokens[1]),atoi(tokens[2])); + + gui__repository[GUI_BMP_OFS_TEXTBOX] = (BITMAP *)gui_gfx[9].dat; + + + + a=0; + for (y=0; y < 3; y++) { + for (x=0; x < 3; x++) { + gui_skin.textbox.bg.grid[a] = create_sub_bitmap( + gui__repository[GUI_BMP_OFS_TEXTBOX], + gridx[x] , gridy[y], + gridx[x+1]-gridx[x]+1, gridy[y+1]-gridy[y]+1 + ); + a++; + } + } +} + +void loadListboxSkin() { + char **tokens; + int tokenCount; + int gridx[4]; + int gridy[4]; + int a = 0; + int x,y; + + tokens = get_config_argv("listbox", "gridx", &tokenCount); + for (a=0; a < 4; a++) { + gridx[a] = atoi(tokens[a]); + } + tokens = get_config_argv("listbox", "gridy", &tokenCount); + for (a=0; a < 4; a++) { + gridy[a] = atoi(tokens[a]); + } + + tokens = get_config_argv("listbox", "textcol_norm", &tokenCount); + gui_skin.listbox.textcolor[0] = makecol(atoi(tokens[0]),atoi(tokens[1]),atoi(tokens[2])); + tokens = get_config_argv("listbox", "textcol_selected", &tokenCount); + gui_skin.listbox.textcolor[1] = makecol(atoi(tokens[0]),atoi(tokens[1]),atoi(tokens[2])); + tokens = get_config_argv("listbox", "textbg_selected", &tokenCount); + gui_skin.listbox.textcolor[2] = makecol(atoi(tokens[0]),atoi(tokens[1]),atoi(tokens[2])); + tokens = get_config_argv("listbox", "textcol_disabled", &tokenCount); + gui_skin.listbox.textcolor[3] = makecol(atoi(tokens[0]),atoi(tokens[1]),atoi(tokens[2])); + + gui__repository[GUI_BMP_OFS_LISTBOX+0] = (BITMAP *)gui_gfx[6].dat; + gui__repository[GUI_BMP_OFS_LISTBOX+1] = (BITMAP *)gui_gfx[10].dat; + + a=0; + for (y=0; y < 3; y++) { + for (x=0; x < 3; x++) { + gui_skin.listbox.bg.grid[a] = create_sub_bitmap( + gui__repository[GUI_BMP_OFS_LISTBOX], + gridx[x] , gridy[y], + gridx[x+1]-gridx[x]+1, gridy[y+1]-gridy[y]+1 + ); + a++; + } + } + + tokens = get_config_argv("listbox", "vscroll_gridx", &tokenCount); + for (a=0; a < 4; a++) { + gridx[a] = atoi(tokens[a]); + } + tokens = get_config_argv("listbox", "vscroll_gridy", &tokenCount); + for (a=0; a < 4; a++) { + gridy[a] = atoi(tokens[a]); + } + a=0; + for (y=0; y < 3; y++) { + for (x=0; x < 3; x++) { + gui_skin.listbox.vscroll.grid[a] = create_sub_bitmap( + gui__repository[GUI_BMP_OFS_LISTBOX+1], + gridx[x] , gridy[y], + gridx[x+1]-gridx[x]+1, gridy[y+1]-gridy[y]+1 + ); + a++; + } + } + +} + +void loadDialogSkin() { + char **tokens; + int tokenCount; + int gridx[4]; + int gridy[4]; + int a = 0; + int x,y; + + tokens = get_config_argv("dialog", "gridx", &tokenCount); + for (a=0; a < 4; a++) { + gridx[a] = atoi(tokens[a]); + } + tokens = get_config_argv("dialog", "gridy", &tokenCount); + for (a=0; a < 4; a++) { + gridy[a] = atoi(tokens[a]); + } + + gui__repository[GUI_BMP_OFS_DIALOG] = (BITMAP *)gui_gfx[5].dat; + + a=0; + for (y=0; y < 3; y++) { + for (x=0; x < 3; x++) { + gui_skin.dialog.bg.grid[a] = create_sub_bitmap( + gui__repository[GUI_BMP_OFS_DIALOG], + gridx[x] , gridy[y], + gridx[x+1]-gridx[x]+1, gridy[y+1]-gridy[y]+1 + ); + a++; + } + } +} + +void drawSkinnedRect(BITMAP*dst, LexSkinnedRect *skin, int x, int y,int w, int h) { + + BITMAP **grid = skin->grid; + + int w0 = grid[0]->w; + int w1 = w - grid[0]->w -grid[2]->w; + int w2 = grid[2]->w; + int h0 = grid[0]->h; + int h1 = h - grid[0]->h - grid[6]->h; + int h2 = grid[6]->h; + + int cx,cy; + + cx = x; cy = y; + masked_blit(grid[0], dst, 0, 0, cx, cy,grid[0]->w,grid[0]->h); + cy += h0; + masked_stretch_blit(grid[3], dst, 0, 0, grid[3]->w,grid[3]->h,cx, cy,w0,h1); + cy += h1; + masked_blit(grid[6], dst, 0, 0, cx, cy,grid[6]->w,grid[6]->h); + + cx += w0; + cy = y; + masked_stretch_blit(grid[1], dst, 0, 0, grid[1]->w,grid[1]->h,cx, cy,w1,h0); + cy += h0; + masked_stretch_blit(grid[4], dst, 0, 0, grid[4]->w,grid[4]->h,cx, cy,w1,h1); + cy += h1; + masked_stretch_blit(grid[7], dst, 0, 0, grid[7]->w,grid[7]->h,cx, cy,w1,h2); + + cx += w1; + cy = y; + masked_blit(grid[2], dst, 0, 0, cx, cy,grid[2]->w,grid[2]->h); + cy += h0; + masked_stretch_blit(grid[5], dst, 0, 0, grid[5]->w,grid[5]->h,cx, cy,w2,h1); + cy += h1; + masked_blit(grid[8], dst, 0, 0, cx, cy,grid[8]->w,grid[7]->h); +} + + +int gui_load_skin(const char* skinname) { + gui__external_slider_callback = NULL; + push_config_state(); + set_config_file(skinname); + gui_gfx = load_datafile(get_config_string("skin", "gfx", 0)); + loadButtonSkin(); + loadSliderSkin(); + loadCheckboxSkin(); + loadTextboxSkin(); + loadListboxSkin(); + loadDialogSkin(); + pop_config_state(); + set_mouse_sprite((BITMAP *)gui_gfx[7].dat); + + return TRUE; +} + +void gui_exit() { + //alfont_destroy_font(gui_font); + gui_shutdown(); + //alfont_exit(); +} + +void gui_shutdown(void) { + int a, b; + + /* Button */ + for (a=0; a < 3; a++) { + for (b=0; b < 9 ; b++) { + destroy_bitmap(gui_skin.button.background[a].grid[b]); + } + + } + /* Slider */ + for (a=0; a < 3; a++) { + destroy_bitmap(gui_skin.slider.hSlider[a]); + destroy_bitmap(gui_skin.slider.vSlider[a]); + } + destroy_bitmap(gui_skin.slider.hGrip); + destroy_bitmap(gui_skin.slider.vGrip); + + /* Checkbox */ + destroy_bitmap(gui_skin.checkbox.normal); + destroy_bitmap(gui_skin.checkbox.checked); + destroy_bitmap(gui_skin.checkbox.disabled); + destroy_bitmap(gui_skin.checkbox.disabled_checked); + + /* Radiobutton */ + destroy_bitmap(gui_skin.radiobutton.normal); + destroy_bitmap(gui_skin.radiobutton.checked); + destroy_bitmap(gui_skin.radiobutton.disabled); + destroy_bitmap(gui_skin.radiobutton.disabled_checked); + + for (a=0; a < GUI_BMP_COUNT; a++) { + destroy_bitmap(gui__repository[a]); + } +} + +/** Draw text for gui widgets */ +int gui_text(BITMAP *bmp, AL_CONST char *s, int x, int y, int color, int centre) { + char tmp[1024]; + int hline_pos = -1; + int len = 0; + int in_pos = 0; + int out_pos = 0; + int pix_len, c; + + while (((c = ugetc(s+in_pos)) != 0) && (out_pos<(int)(sizeof(tmp)-ucwidth(0)))) { + if (c == '&') { + in_pos += uwidth(s+in_pos); + c = ugetc(s+in_pos); + if (c == '&') { + out_pos += usetc(tmp+out_pos, '&'); + in_pos += uwidth(s+in_pos); + len++; + } else hline_pos = len; + } else { + out_pos += usetc(tmp+out_pos, c); + in_pos += uwidth(s+in_pos); + len++; + } + } + usetc(tmp+out_pos, 0); + pix_len = alfont_text_length(gui_font, tmp); + + if (centre)x -= pix_len / 2; + if (bmp) { + alfont_textout_aa(bmp, gui_font, tmp, x, y, color); + if (hline_pos >= 0) { + c = ugetat(tmp, hline_pos); + usetat(tmp, hline_pos, 0); + hline_pos = alfont_text_length(gui_font, tmp); + c = usetc(tmp, c); + usetc(tmp+c, 0); + c = alfont_text_length(gui_font, tmp); + hline(bmp, x+hline_pos, y+alfont_text_height(gui_font)-gui_font_baseline, x+hline_pos+c-1, color); + } + } + return pix_len; +} + +int tmw_text_proc(int msg, DIALOG *d, int c) { + if (msg==MSG_DRAW) { + int rtm; + rtm = alfont_text_mode(-1); + gui_text(gui_bitmap, (char *)d->dp, d->x, d->y, d->fg, FALSE); + alfont_text_mode(rtm); + } + return D_O_K; +} + + +int tmw_button_proc(int msg, DIALOG *d, int c) { + + int rtm = 0; + int col = 0; + int ofs = 0; + int ret = D_O_K; + + if (msg == MSG_DRAW) { + rectfill(gui_bitmap, d->x, d->y, d->x + d->w, d->y+d->h, makecol(255,255,255)); + + if (d->flags & D_DISABLED) { + drawSkinnedRect(gui_bitmap, &gui_skin.button.background[3], d->x, d->y, d->w, d->h); + col = gui_skin.button.textcolor[3]; + } else if (d->flags & D_SELECTED) { + drawSkinnedRect(gui_bitmap, &gui_skin.button.background[2], d->x, d->y, d->w, d->h); + col = gui_skin.button.textcolor[2]; + ofs = 1; + } else if (d->flags & D_GOTMOUSE) { + drawSkinnedRect(gui_bitmap, &gui_skin.button.background[1], d->x, d->y, d->w, d->h); + col = gui_skin.button.textcolor[1]; + } else { + drawSkinnedRect(gui_bitmap, &gui_skin.button.background[0], d->x, d->y, d->w, d->h); + col = gui_skin.button.textcolor[0]; + } + rtm = alfont_text_mode(-1); + gui_text(gui_bitmap, (const char *)d->dp, d->x+d->w/2+ofs, d->y+d->h/2-alfont_text_height(gui_font)/2+ofs, col, TRUE); + alfont_text_mode(rtm); + ret = D_O_K; + } else { + ret = d_button_proc(msg,d,c); + } + return ret; +} + +int tmw_slider_proc(int msg, DIALOG *d, int c) { + int w = 0; + int h = 0; + int x,y; + + int ret = D_O_K; + + static int watchdog = 0; + + watchdog++; + if (watchdog == 1) { + gui__external_slider_callback = (int(__cdecl *)(void *, int))d->dp2; + d->dp2 = (void*)reroute_slider_proc; + } + + if (msg == MSG_DRAW) { + if (d->w >= d->h) { + rectfill(gui_bitmap, d->x, d->y, d->x + d->w, d->y+d->h, d->bg); + /* horiz */ + x = d->x; + y = d->y + (d->h- gui_skin.slider.hSlider[0]->h)/2; + masked_blit(gui_skin.slider.hSlider[0], gui_bitmap, 0, 0, x, y, gui_skin.slider.hSlider[0]->w, gui_skin.slider.hSlider[0]->h); + w = d->w -gui_skin.slider.hSlider[0]->w - gui_skin.slider.hSlider[2]->w; + x+= gui_skin.slider.hSlider[0]->w; + + masked_stretch_blit( + gui_skin.slider.hSlider[1], gui_bitmap, + 0, 0, gui_skin.slider.hSlider[1]->w, gui_skin.slider.hSlider[1]->h, + x, y, w, gui_skin.slider.hSlider[1]->h); + + x+=w; + masked_blit(gui_skin.slider.hSlider[2], gui_bitmap, 0, 0, x, y, gui_skin.slider.hSlider[2]->w, gui_skin.slider.hSlider[2]->h); + + x = d->x + ((d->w-gui_skin.slider.hGrip->w) * d->d2)/d->d1; + y = d->y + (d->h - gui_skin.slider.hGrip->h)/2; + masked_blit(gui_skin.slider.hGrip, gui_bitmap, 0, 0, x, y, gui_skin.slider.hGrip->w, gui_skin.slider.hGrip->h); + } else { + rectfill(gui_bitmap, d->x, d->y, d->x + d->w, d->y+d->h, d->bg); + /* vertic */ + x = d->x+ (d->w- gui_skin.slider.vSlider[0]->w)/2; + y = d->y; + masked_blit(gui_skin.slider.vSlider[0], gui_bitmap, 0, 0, x, y, gui_skin.slider.vSlider[0]->w, gui_skin.slider.vSlider[0]->h); + h = d->h - gui_skin.slider.vSlider[0]->h - gui_skin.slider.vSlider[2]->h; + y += gui_skin.slider.vSlider[0]->h; + + masked_stretch_blit( + gui_skin.slider.vSlider[1], gui_bitmap, + 0, 0, gui_skin.slider.vSlider[1]->w, gui_skin.slider.vSlider[1]->h, + x, y, gui_skin.slider.vSlider[1]->w, h); + + y+=h; + masked_blit(gui_skin.slider.vSlider[2], gui_bitmap, 0, 0, x, y, gui_skin.slider.vSlider[2]->w, gui_skin.slider.vSlider[2]->h); + + y = d->y + d->h - (((d->h-gui_skin.slider.vGrip->h) * d->d2)/d->d1)-gui_skin.slider.vGrip->h; + x = d->x + (d->w - gui_skin.slider.vGrip->w)/2; + if (gui_skin.slider.vGrip->w % 2 !=0) { + x++; + } + masked_blit(gui_skin.slider.vGrip, gui_bitmap, 0, 0, x, y, gui_skin.slider.vGrip->w, gui_skin.slider.vGrip->h); + } + //textprintf(gui_bitmap, gui_font,10, 10, makecol(255,255,255), "%i", d->d2); + } else { + ret = d_slider_proc(msg,d,c); + } + if (watchdog == 1) { + d->dp2 = (void*)gui__external_slider_callback; + } + watchdog--; + return ret; +} + +int tmw_check_proc(int msg, DIALOG *d, int c) { + BITMAP *box = NULL; + int x, y; + int tx, ty, l; + int rtm = 0; + int col = 0; + if (msg == MSG_DRAW) { +// rectfill(gui_bitmap, d->x, d->y, d->x + d->w, d->y+d->h, d->bg); + if (d->flags & D_SELECTED) { + if (d->flags & D_DISABLED) { + box = gui_skin.checkbox.disabled_checked; + } else { + box = gui_skin.checkbox.checked; + } + } else if (d->flags & D_DISABLED) { + box = gui_skin.checkbox.disabled; + } else { + box = gui_skin.checkbox.normal; + } + + if (d->flags & D_DISABLED) { + col = gui_skin.checkbox.textcolor[1]; + } else { + col = gui_skin.checkbox.textcolor[0]; + } + + if (d->dp != NULL) { + l = gui_strlen((const char *)d->dp); + } else { + l = 0; + } + + if (d->d1 != 0) { + x = d->x; + tx = x + box->w + box->w/2; + } else { + x = d->x + d->w - box->w; + tx = x - box->w/2 - l; + } + y = d->y + (d->h - box->h)/ 2; + ty = d->y + (d->h - alfont_text_height(gui_font)) / 2; + + masked_blit(box, gui_bitmap, 0, 0, x, y, box->w, box->h); + if (d->dp != NULL) { + rtm = alfont_text_mode(-1); + gui_text(gui_bitmap, (const char *)d->dp, tx, ty, col, 0); + alfont_text_mode(rtm); + } + + + } else { + return d_check_proc(msg, d, c); + } + return D_O_K; +} + +int tmw_radio_proc(int msg, DIALOG *d, int c) { + BITMAP *box = NULL; + int x, y; + int tx, ty, l; + int rtm = 0; + int col = 0; + + + if (msg == MSG_DRAW) { + rectfill(gui_bitmap, d->x, d->y, d->x + d->w, d->y+d->h, d->bg); + if (d->flags & D_SELECTED) { + if (d->flags & D_DISABLED) { + box = gui_skin.radiobutton.disabled_checked; + } else { + box = gui_skin.radiobutton.checked; + } + } else if (d->flags & D_DISABLED) { + box = gui_skin.radiobutton.disabled; + } else { + box = gui_skin.radiobutton.normal; + } + + if (d->flags & D_DISABLED) { + col = gui_skin.radiobutton.textcolor[1]; + } else { + col = gui_skin.radiobutton.textcolor[0]; + } + + if (d->dp != NULL) { + l = gui_strlen((const char *)d->dp); + } else { + l = 0; + } + + if (d->d2 != 0) { + x = d->x; + tx = x + box->w + box->w/2; + } else { + x = d->x + d->w - box->w; + tx = x - box->w/2 - l; + } + y = d->y + (d->h - box->h)/ 2; + ty = d->y + (d->h - alfont_text_height(gui_font)) / 2; + + masked_blit(box, gui_bitmap, 0, 0, x, y, box->w, box->h); + if (d->dp != NULL) { + rtm = alfont_text_mode(-1); + gui_text(gui_bitmap, (const char *)d->dp, tx, ty, col, 0); + alfont_text_mode(rtm); + } + + + } else { + return d_radio_proc(msg, d, c); + } + return D_O_K; +} + +int tmw_edit_proc(int msg, DIALOG *d, int c) { +// BITMAP *box = NULL; + int x; + int tx, ty, l; + int rtm = 0; + int col = 0; + char* start; + char* text; + char hack; + int cl, cr, cb, ct; + int lb, rb; + + + if (msg == MSG_DRAW) { + rectfill(gui_bitmap, d->x, d->y, d->x + d->w, d->y+d->h, d->bg); + drawSkinnedRect(gui_bitmap, &gui_skin.textbox.bg, d->x, d->y, d->w, d->h); + + if (d->flags & D_DISABLED) { + col = gui_skin.textbox.textcolor[1]; + } else { + col = gui_skin.textbox.textcolor[0]; + } + + lb = gui_skin.textbox.bg.grid[0]->w; + rb = gui_skin.textbox.bg.grid[2]->w; + tx = d->x + lb; + ty = d->y + (d->h - alfont_text_height(gui_font))/2; + + + text = (char *)d->dp; + start = text; + + rtm = alfont_text_mode(-1); + + if (gui_bitmap->clip) { + cl = gui_bitmap->cl; + ct = gui_bitmap->ct; + cr = gui_bitmap->cr; + cb = gui_bitmap->cb; + } else { + cl=ct=0; + cr=gui_bitmap->w; + cb=gui_bitmap->h; + } + set_clip_rect(gui_bitmap, tx, ty, d->x+d->w-rb, ty + alfont_text_height(gui_font)); // set_clip() is deprecated use set_clip_rect() instead + hack = text[d->d2]; + text[d->d2] = '\0'; + l = alfont_text_length(gui_font, text); + text[d->d2] = hack; + + if (l > d->w-lb-rb) { + tx += ((d->w-lb-rb) - l); + } + gui_text(gui_bitmap, start, tx, ty, col, 0); + + + if (d->flags & D_GOTFOCUS) { + hack = text[d->d2]; + text[d->d2] = '\0'; + x = tx + alfont_text_length(gui_font, text); + vline(gui_bitmap, x, ty, ty + alfont_text_height(gui_font), col); + text[d->d2] = hack; + } + alfont_text_mode(rtm); + set_clip_rect(gui_bitmap, cl, ct, cr, cb); + } else { + return d_edit_proc(msg, d, c); + } + return D_O_K; +} + +int tmw_password_proc(int msg, DIALOG *d, int c) { +// BITMAP *box = NULL; + int x; + int tx, ty, l; + int rtm = 0; + int col = 0; + char* start; + char* text; + char hack; + int cl, cr, cb, ct; + int lb, rb; + + + if (msg == MSG_DRAW) { + rectfill(gui_bitmap, d->x, d->y, d->x + d->w, d->y+d->h, d->bg); + drawSkinnedRect(gui_bitmap, &gui_skin.textbox.bg, d->x, d->y, d->w, d->h); + + if (d->flags & D_DISABLED) { + col = gui_skin.textbox.textcolor[1]; + } else { + col = gui_skin.textbox.textcolor[0]; + } + + lb = gui_skin.textbox.bg.grid[0]->w; + rb = gui_skin.textbox.bg.grid[2]->w; + tx = d->x + lb; + ty = d->y + (d->h - alfont_text_height(gui_font))/2; + + + text = (char *)malloc(strlen((char *)d->dp)+1); + // Sull: new ansi standard + unsigned int i; + for(i=0;i<strlen((char *)d->dp);i++)text[i] = '*'; + text[i] = '\0'; + start = text; + + rtm = alfont_text_mode(-1); + + if (gui_bitmap->clip) { + cl = gui_bitmap->cl; + ct = gui_bitmap->ct; + cr = gui_bitmap->cr; + cb = gui_bitmap->cb; + } else { + cl=ct=0; + cr=gui_bitmap->w; + cb=gui_bitmap->h; + } + set_clip_rect(gui_bitmap, tx, ty, d->x+d->w-rb, ty + alfont_text_height(gui_font)); + + hack = text[d->d2]; + text[d->d2] = '\0'; + l = alfont_text_length(gui_font, text); + text[d->d2] = hack; + + if (l > d->w-lb-rb) { + tx += ((d->w-lb-rb) - l); + } + gui_text(gui_bitmap, start, tx, ty, col, 0); + + + if (d->flags & D_GOTFOCUS) { + hack = text[d->d2]; + text[d->d2] = '\0'; + x = tx + alfont_text_length(gui_font, text); + vline(gui_bitmap, x, ty, ty + alfont_text_height(gui_font), col); + text[d->d2] = hack; + } + alfont_text_mode(rtm); + set_clip_rect(gui_bitmap, cl, ct, cr, cb); + } else { + return d_edit_proc(msg, d, c); + } + return D_O_K; +} + +int tmw_list_proc(int msg, DIALOG *d, int c) { +// BITMAP *box = NULL; + + static int ignoreRedraw = FALSE; + + int itemCount = 0; + int firstItem = d->d2; + int lastItem = 0; + int selectedItem = d->d1; + int x,y,delta; + int a, col; + int w, h = 0; + int rtm = 0; + int cl, cr, cb, ct; + int th = alfont_text_height(gui_font); + + int vscroll = 0; + int sliderh = 10; + int slidery = 0; + + (*(getfuncptr)d->dp)(-1, &itemCount); + + w = d->w - gui_skin.listbox.bg.grid[0]->w - gui_skin.listbox.bg.grid[2]->w; + h = d->h - gui_skin.listbox.bg.grid[1]->h - gui_skin.listbox.bg.grid[7]->h; + lastItem = MIN(itemCount-1, firstItem + h / alfont_text_height(gui_font)); + + + + if (msg == MSG_DRAW) { + if (ignoreRedraw) { + return D_O_K; + } + rectfill(gui_bitmap, d->x, d->y, d->x + d->w, d->y+d->h, d->bg); + drawSkinnedRect(gui_bitmap, &gui_skin.listbox.bg, d->x, d->y, d->w, d->h); + + (*(getfuncptr)d->dp)(-1, &itemCount); + vscroll = (h/th) < (itemCount-1); + if (vscroll) { + w = d->w - 17 - gui_skin.listbox.bg.grid[0]->w; + drawSkinnedRect(gui_bitmap, &gui_skin.listbox.bg, d->x+d->w-15, d->y+1, 14, d->h-2); + sliderh = MAX(((d->h-2)* (h / th)) / itemCount, gui_skin.listbox.bg.grid[0]->h*2); + slidery = ((d->h-2-sliderh) * firstItem) / (itemCount); + slidery+= d->y+1; + drawSkinnedRect(gui_bitmap, &gui_skin.listbox.vscroll, d->x+d->w-13, slidery, 11, sliderh); + } + + rtm = alfont_text_mode(-1); + if (gui_bitmap->clip) { + cl = gui_bitmap->cl; + ct = gui_bitmap->ct; + cr = gui_bitmap->cr; + cb = gui_bitmap->cb; + } else { + cl=ct=0; + cr=gui_bitmap->w; + cb=gui_bitmap->h; + } + x = d->x + gui_skin.listbox.bg.grid[0]->w; + y = d->y + gui_skin.listbox.bg.grid[0]->h; + set_clip_rect(gui_bitmap, x,y, x+w, y+h); + + + if (d->flags & D_DISABLED) { + col = gui_skin.listbox.textcolor[3]; + for (a=firstItem; a < lastItem; a++) { + alfont_textout_aa(gui_bitmap, gui_font, (*(getfuncptr)d->dp)(a, 0), x, y, col); + y += alfont_text_height(gui_font); + } + } else { + for (a=firstItem; a <= lastItem; a++) { + if (a==d->d1) { + col = gui_skin.listbox.textcolor[1]; + rectfill(gui_bitmap, x, y, x+w, y+alfont_text_height(gui_font)-1, gui_skin.listbox.textcolor[2]); + } else { + col = gui_skin.listbox.textcolor[0]; + } + alfont_textout_aa(gui_bitmap, gui_font, (*(getfuncptr)d->dp)(a, 0), x, y, col); + y += alfont_text_height(gui_font); + } + } + + alfont_text_mode(rtm); + set_clip_rect(gui_bitmap, cl, ct, cr, cb); + + } else if (msg == MSG_CLICK) { + + x = d->x + gui_skin.listbox.bg.grid[0]->w; + y = d->y + gui_skin.listbox.bg.grid[0]->h; + + sliderh = MAX(((d->h-2)* (h / th)) / itemCount, gui_skin.listbox.bg.grid[0]->h*2); + //sliderh = ((d->h-2)* (h / th)) / itemCount; + slidery = ((d->h-2-sliderh) * firstItem) / (itemCount); + slidery+= d->y+1; + + if (mouse_x > (d->x + d->w - 14) && mouse_x < (d->x+d->w-1)) { + // Ok, scroll bar + if (mouse_y >= slidery && mouse_y < slidery + sliderh) { + delta= mouse_y - slidery; + while (mouse_b) { + a = mouse_y - delta - d->y -1; + a *= itemCount; + a /= (d->h-2); + a = MID(0, a, itemCount- h/th); + + if (a != d->d2) { + d->d2 = a; + scare_mouse(); + object_message(d, MSG_DRAW, 0); + unscare_mouse(); + } + + slidery = ((d->h-2) * firstItem) / (itemCount); + slidery+= d->y+1; + } + } else if (mouse_y < slidery) { + a = d->d2 - (h/th)+1; + a = MID(0, a, itemCount- h/th); + + + d->d2 = a; + scare_mouse(); + object_message(d, MSG_DRAW, 0); + unscare_mouse(); + + while (mouse_b) { + } + } else if (mouse_y > slidery + sliderh) { + a = d->d2 + (h/th)-1; + a = MID(0, a, itemCount- h/th); + d->d2 = a; + + scare_mouse(); + object_message(d, MSG_DRAW, 0); + unscare_mouse(); + + while (mouse_b) { + } + } + } else if (mouse_x >= x && mouse_x < x+w && mouse_y >= y && mouse_y < y+h) { + + while (mouse_b) { + a = firstItem + (mouse_y-y) / alfont_text_height(gui_font); + + if (a <= lastItem && a != selectedItem) { + d->d1 = selectedItem = a; + scare_mouse(); + object_message(d, MSG_DRAW, 0); + unscare_mouse(); + } + } + } + } else { + ignoreRedraw = (msg == MSG_GOTFOCUS || msg == MSG_LOSTFOCUS); + a = d_list_proc(msg, d, c); + + if (a == D_USED_CHAR) { + if (d->d1 < d->d2) { + if (d->d1 > 0) { + d->d1 = d->d2; + } + } else if (d->d1 > d->d2 + h/th -1) { + d->d2 = d->d1 - h/th + 1; + } + } + + return a; + } + return D_O_K; +} + +int tmw_dialog_proc(int msg, DIALOG *d, int c) { + int rtm; + int x, y; + + if (msg == MSG_CLICK) { + if(mouse_y < d->y + gui_skin.dialog.bg.grid[1]->h) { + //drag = true; + d->d1 = mouse_x - d->x; + d->d2 = mouse_y - d->y; + } + } else if (msg == MSG_DRAW) { + if((mouse_b & 1)&&(d->d1>=0)&&(d->d2>=0)) {//(drag==true)) { + x = mouse_x-d->d1; + y = mouse_y-d->d2; + if(x<15) { + x=0; + position_mouse(d->d1, mouse_y); + } + if(y<15) { + y=0; + position_mouse(mouse_x, d->d2); + } + if(x+d->w>=785) { + x=800-d->w; + position_mouse(x+d->d1, mouse_y); + } + if(y+d->h>=585) { + y=600-d->h; + position_mouse(mouse_x, y+d->d2); + } + position_dialog(active_dialog, x, y); + } else { + //drag = false; + d->d1 = -1; + d->d2 = -1; + } + drawSkinnedRect(gui_bitmap, &gui_skin.dialog.bg, d->x, d->y, d->w, d->h); + rtm = alfont_text_mode(-1); + alfont_textprintf_centre_aa(gui_bitmap, gui_font, + d->x + d->w/2, + d->y + (gui_skin.dialog.bg.grid[1]->h - alfont_text_height(gui_font))/2, d->fg, "%s", d->dp); + alfont_text_mode(rtm); + } + return D_O_K; +} + +int reroute_slider_proc(void *dp3, int d2) { + int ret = 0; + + if (gui__external_slider_callback != NULL) { + ret = gui__external_slider_callback(dp3, d2); + } + return ret; +} + +// Helper function to draw a scrollable bar +void _gui_draw_scrollable_frame(DIALOG *d, int listsize, int offset, int height, int fg_color, int bg) { + int i, len; + int xx, yy; + + /* create and draw the scrollbar */ + i = ((d->h-5) * height + listsize/2) / listsize; + xx = d->x+d->w-10; + yy = d->y; + + if (offset > 0) { + len = (((d->h-5) * offset) + listsize/2) / listsize; + } else len = 0; + if (yy+i < d->y+d->h-3) { + drawSkinnedRect(gui_bitmap, &gui_skin.listbox.vscroll, xx, yy+len, 10, i); + } else { + drawSkinnedRect(gui_bitmap, &gui_skin.listbox.vscroll, xx, yy, 10, d->h-3); + } +} + +/* _gui_draw_textbox: + * Helper function to draw a textbox object. + */ +void _gui_draw_textbox(char *thetext, int *listsize, int draw, int offset, + int wword, int tabsize, int x, int y, int w, int h, + int disabled, int fore, int deselect, int disable) +{ + int fg = fore; + int y1 = y+4; + int x1; + int len; + int ww = w-6; + char s[16]; + char text[16]; + char space[16]; + char *printed = text; + char *scanned = text; + char *oldscan = text; + char *ignore = NULL; + char *tmp, *ptmp; + int width; + int line = 0; + int i = 0; + int noignore; + int rtm; + + usetc(s+usetc(s, '.'), 0); + usetc(text+usetc(text, ' '), 0); + usetc(space+usetc(space, ' '), 0); + + /* find the correct text */ + if (thetext != NULL) { + printed = thetext; + scanned = thetext; + } + + /* choose the text color */ + if (disabled) + fg = disable; + + rtm = alfont_text_mode(-1); + + /* loop over the entire string */ + while (1) { + width = 0; + + /* find the next break */ + while (ugetc(scanned)) { + /* check for a forced break */ + if (ugetc(scanned) == '\n') { + scanned += uwidth(scanned); + + /* we are done parsing the line end */ + break; + } + + /* the next character length */ + usetc(s+usetc(s, ugetc(scanned)), 0); + len = alfont_text_length(gui_font, s); + + /* modify length if its a tab */ + if (ugetc(s) == '\t') + len = tabsize * alfont_text_length(gui_font, space); + + /* check for the end of a line by excess width of next char */ + if (width+len >= ww) { + /* we have reached end of line do we go back to find start */ + if (wword) { + /* remember where we were */ + oldscan = scanned; + noignore = FALSE; + + /* go backwards looking for start of word */ + while (!uisspace(ugetc(scanned))) { + /* don't wrap too far */ + if (scanned == printed) { + /* the whole line is filled, so stop here */ + tmp = ptmp = scanned; + while (ptmp != oldscan) { + ptmp = tmp; + tmp += uwidth(tmp); + } + scanned = ptmp; + noignore = TRUE; + break; + } + /* look further backwards to wrap */ + tmp = ptmp = printed; + while (tmp < scanned) { + ptmp = tmp; + tmp += uwidth(tmp); + } + scanned = ptmp; + } + /* put the space at the end of the line */ + if (!noignore) { + ignore = scanned; + scanned += uwidth(scanned); + } + else + ignore = NULL; + + /* check for endline at the convenient place */ + if (ugetc(scanned) == '\n') + scanned += uwidth(scanned); + } + /* we are done parsing the line end */ + break; + } + + /* the character can be added */ + scanned += uwidth(scanned); + width += len; + } + + /* check if we are to print it */ + if ((draw) && (line >= offset) && (y1+text_height(font) < (y+h-3))) { + x1 = x+4; + + /* the initial blank bit */ + //rectfill(gui_bitmap, x+2, y1, x1-1, y1+text_height(font), deselect); + + /* print up to the marked character */ + while (printed != scanned) { + /* do special stuff for each charater */ + switch (ugetc(printed)) { + + case '\r': + case '\n': + /* don't print endlines in the text */ + break; + + /* possibly expand the tabs */ + case '\t': + for (i=0; i<tabsize; i++) { + usetc(s+usetc(s, ' '), 0); + alfont_textout_aa(gui_bitmap, gui_font, s, x1, y1, fg); + x1 += alfont_text_length(gui_font, s); + } + break; + + /* print a normal character */ + default: + if (printed != ignore) { + usetc(s+usetc(s, ugetc(printed)), 0); + alfont_textout_aa(gui_bitmap, gui_font, s, x1, y1, fg); + x1 += alfont_text_length(gui_font, s); + } + } + + /* goto the next character */ + printed += uwidth(printed); + } + /* the last blank bit */ + /*if (x1 <= x+w-3) + rectfill(gui_bitmap, x1, y1, x+w-3, y1+alfont_text_height(gui_font)-1, deselect);*/ + + /* print the line end */ + y1 += alfont_text_height(gui_font); + } + printed = scanned; + + /* we have done a line */ + line++; + + /* check if we are at the end of the string */ + if (!ugetc(printed)) { + /* the under blank bit */ + /*if (draw) + rectfill(gui_bitmap, x+1, y1, x+w-3, y+h-1, deselect);*/ + + /* tell how many lines we found */ + *listsize = line; + alfont_text_mode(rtm); + return; + } + } + + alfont_text_mode(rtm); +} + +int tmw_textbox_proc(int msg, DIALOG *d, int c) { + int height, bar, ret = D_O_K; + int start, top, bottom, l; + int used, delta; + int fg_color = (d->flags & D_DISABLED) ? gui_mg_color : d->fg; + + /* calculate the actual height */ + height = (d->h-8) / alfont_text_height(gui_font); + + switch (msg) { + + case MSG_START: + /* measure how many lines of text we contain */ + _gui_draw_textbox((char *)d->dp, &d->d1, + 0, /* DONT DRAW anything */ + d->d2, !(d->flags & D_SELECTED), 8, + d->x, d->y, d->w, d->h, + (d->flags & D_DISABLED), + 0, 0, 0); + break; + + case MSG_DRAW: + /* tell the object to sort of draw, but only calculate the listsize */ + _gui_draw_textbox((char *)d->dp, &d->d1, + 0, /* DONT DRAW anything */ + d->d2, !(d->flags & D_SELECTED), 8, + d->x, d->y, d->w, d->h, + (d->flags & D_DISABLED), + 0, 0, 0); + + if (d->d1 > height) { + bar = 12; + } + else { + bar = 0; + d->d2 = 0; + } + + /* now do the actual drawing */ + _gui_draw_textbox((char *)d->dp, &d->d1, 1, d->d2, + !(d->flags & D_SELECTED), 8, + d->x, d->y, d->w-bar, d->h, + (d->flags & D_DISABLED), + fg_color, d->bg, gui_mg_color); + + /* draw the frame around */ + _gui_draw_scrollable_frame(d, d->d1, d->d2, height, fg_color, d->bg); + + break; + + case MSG_CLICK: + /* figure out if it's on the text or the scrollbar */ + bar = (d->d1 > height); + + if ((!bar) || (gui_mouse_x() < d->x+d->w-13)) { + /* clicked on the text area */ + ret = D_O_K; + } + else { + /* clicked on the scroll area */ + _handle_scrollable_scroll_click(d, d->d1, &d->d2, height); + } + break; + + case MSG_CHAR: + start = d->d2; + used = D_USED_CHAR; + + if (d->d1 > 0) { + if (d->d2 > 0) + top = d->d2+1; + else + top = 0; + + l = (d->h-8)/alfont_text_height(gui_font); + + bottom = d->d2 + l - 1; + if (bottom >= d->d1-1) + bottom = d->d1-1; + else + bottom--; + + if ((c>>8) == KEY_UP) + d->d2--; + else if ((c>>8) == KEY_DOWN) + d->d2++; + else if ((c>>8) == KEY_HOME) + d->d2 = 0; + else if ((c>>8) == KEY_END) + d->d2 = d->d1-l; + else if ((c>>8) == KEY_PGUP) + d->d2 -= (bottom-top) ? bottom-top : 1; + else if ((c>>8) == KEY_PGDN) + d->d2 += (bottom-top) ? bottom-top : 1; + else + used = D_O_K; + + /* make sure that the list stays in bounds */ + if (d->d2 > d->d1-l) + d->d2 = d->d1-l; + if (d->d2 < 0) + d->d2 = 0; + } + else + used = D_O_K; + + /* if we changed something, better redraw... */ + if (d->d2 != start) + d->flags |= D_DIRTY; + + ret = used; + break; + + case MSG_WHEEL: + l = (d->h-8)/alfont_text_height(gui_font); + delta = (l > 3) ? 3 : 1; + + /* scroll, making sure that the list stays in bounds */ + start = d->d2; + d->d2 = (c > 0) ? MAX(0, d->d2-delta) : MIN(d->d1-l, d->d2+delta); + + /* if we changed something, better redraw... */ + if (d->d2 != start) + d->flags |= D_DIRTY; + + ret = D_O_K; + break; + + case MSG_WANTFOCUS: + /* if we don't have a scrollbar we can't do anything with the focus */ + if (d->d1 > height) + ret = D_WANTFOCUS; + break; + + default: + ret = D_O_K; + } + + return ret; +} + +int tmw_bitmap_proc(int msg, DIALOG *d, int c) { + if(msg==MSG_DRAW) { + drawSkinnedRect(gui_bitmap, &gui_skin.textbox.bg, d->x, d->y, d->w, d->h); + if(d->dp!=NULL) + masked_blit(((BITMAP *)d->dp), gui_bitmap, 0, 0, d->x+(d->w-d->d1)/2, d->y+2, d->d1, d->d2); + } + return D_O_K; +} + +void ok(const char *title, const char *message) { +DIALOG alert_dialog[] = { + /* (dialog proc) (x) (y) (w) (h) (fg) (bg) (key) (flags) (d1) (d2) (dp) (dp2) (dp3) */ + { tmw_dialog_proc, 0, 0, 0, 60, 0, -1, 0, 0, 0, 0, (void *)title, NULL, NULL }, + { tmw_text_proc, 2, 22, 0, 0, 0, 0, 0, 0, 0, 0, (void *)message, NULL, NULL }, + { tmw_button_proc, 0, 40, 44, 18, 0, -1, 'o', D_EXIT, -1, 0, (char *)"&Ok", NULL, NULL }, + { NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL }}; + + BITMAP *temp = gui_bitmap; + gui_bitmap = screen; + show_mouse(screen); + alert_dialog[0].w = alfont_text_length(gui_font, message)+4; + alert_dialog[1].w = alfont_text_length(gui_font, message); + alert_dialog[1].h = alfont_text_height(gui_font); + alert_dialog[2].x = alfont_text_length(gui_font, message)/2-22; + position_dialog(alert_dialog, 400-alert_dialog[0].w/2, 270); + do_dialog(alert_dialog, 2); + show_mouse(NULL); + gui_bitmap = temp; +} + +unsigned int yes_no(const char *title, const char *message) { + unsigned int ret; + DIALOG alert_dialog[] = { + /* (dialog proc) (x) (y) (w) (h) (fg) (bg) (key) (flags) (d1) (d2) (dp) (dp2) (dp3) */ + { tmw_dialog_proc, 0, 0, 0, 60, 0, -1, 0, 0, 0, 0, (void *)title, NULL, NULL }, + { tmw_text_proc, 2, 22, 0, 0, 0, 0, 0, 0, 0, 0, (void *)message, NULL, NULL }, + { tmw_button_proc, 0, 40, 44, 18, 0, -1, 'o', D_EXIT, -1, 0, (char *)"&Yes", NULL, NULL }, + { tmw_button_proc, 0, 40, 44, 18, 0, -1, 'o', D_EXIT, -1, 0, (char *)"&No", NULL, NULL }, + { NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL }}; + + BITMAP *temp = gui_bitmap; + gui_bitmap = screen; + show_mouse(screen); + int width = alfont_text_length(gui_font, message)+4; + if(width<100)width=100; + alert_dialog[0].w = width; + alert_dialog[1].w = alfont_text_length(gui_font, message); + alert_dialog[1].h = alfont_text_height(gui_font); + alert_dialog[2].x = width/2-46; + alert_dialog[2].x = width/2+2; + position_dialog(alert_dialog, 400-width/2, 270); + ret = do_dialog(alert_dialog, 3); + show_mouse(NULL); + gui_bitmap = temp; + return ret-2; +} diff --git a/src/gui/gui.h b/src/gui/gui.h new file mode 100644 index 00000000..36973b65 --- /dev/null +++ b/src/gui/gui.h @@ -0,0 +1,121 @@ +/** + + The Mana World + Copyright 2004 The Mana World Development Team + + This file is part of The Mana World. + + The Mana World 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 2 of the License, or + any later version. + + The Mana World 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 The Mana World; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +*/ + +#ifdef WIN32 + #pragma warning (disable:4312) +#endif + +#ifndef _TMW_GUI +#define _TMW_GUI + +#include <allegro.h> +#include <alfont.h> +#include <string.h> + +typedef struct { + BITMAP *grid[9]; +} LexSkinnedRect; + +typedef struct { + LexSkinnedRect background[4]; + int textcolor[4]; +} LexButton; + +typedef struct { + BITMAP *hSlider[3]; + BITMAP *vSlider[3]; + BITMAP *hGrip; + BITMAP *vGrip; +} LexSlider; + +typedef struct { + BITMAP *normal; + BITMAP *checked; + BITMAP *disabled; + BITMAP *disabled_checked; + int textcolor[2]; +} LexCheckbox; + +typedef struct { + BITMAP *normal; + BITMAP *checked; + BITMAP *disabled; + BITMAP *disabled_checked; + int textcolor[2]; +} LexRadiobutton; + +typedef struct { + LexSkinnedRect bg; + int textcolor[2]; +} LexTextbox; + +typedef struct { + LexSkinnedRect bg; + LexSkinnedRect vscroll; + int textcolor[4]; +} LexListbox; + +typedef struct { + LexSkinnedRect bg; +} LexDialog; + +typedef struct { + LexButton button; + LexSlider slider; + LexCheckbox checkbox; + LexRadiobutton radiobutton; + LexTextbox textbox; + LexListbox listbox; + LexDialog dialog; +} LexSkin; + +extern LexSkin gui_skin; +extern BITMAP *gui_bitmap; +extern ALFONT_FONT *gui_font; + +/* Definition of the callback function prototypes */ +typedef int (*gui_buttonCallback)(int id); +typedef char *(*getfuncptr)(int, int *); + +void init_gui(BITMAP *dest_bitmap, const char *skin); +void gui_exit(); +int gui_update(DIALOG_PLAYER *player); +int gui_load_skin(const char* skinname); +void gui_shutdown(void); + +int tmw_button_proc(int msg, DIALOG *d, int c); +int tmw_slider_proc(int msg, DIALOG *d, int c); +int tmw_check_proc(int msg, DIALOG *d, int c); +int tmw_radio_proc(int msg, DIALOG *d, int c); +int tmw_edit_proc(int msg, DIALOG *d, int c); +int tmw_password_proc(int msg, DIALOG *d, int c); +int tmw_list_proc(int msg, DIALOG *d, int c); +int tmw_text_proc(int msg, DIALOG *d, int c); +int tmw_dialog_proc(int msg, DIALOG *d, int c); +int tmw_textbox_proc(int msg, DIALOG *d, int c); +int tmw_bitmap_proc(int msg, DIALOG *d, int c); + +void ok(const char *title, const char *message); +unsigned int yes_no(const char *title, const char *message); + +#endif diff --git a/src/gui/inventory.cpp b/src/gui/inventory.cpp new file mode 100644 index 00000000..72c2cbaa --- /dev/null +++ b/src/gui/inventory.cpp @@ -0,0 +1,249 @@ +/** + + The Mana World + Copyright 2004 The Mana World Development Team + + This file is part of The Mana World. + + The Mana World 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 2 of the License, or + any later version. + + The Mana World 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 The Mana World; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +*/ + +#include "inventory.h" + +void TmwInventory::create(int tempxpos, int tempypos) { + xpos =tempxpos; + ypos =tempypos; + + itemPIC[0].pic = load_bitmap("items/herb.bmp", NULL); //ID=0 + itemPIC[1].pic = load_bitmap("items/magicthing.bmp", NULL); //ID=1 + empty = load_bitmap("items/empty.bmp", NULL); + selected = load_bitmap("items/selected.bmp", NULL); + + for(int i = 0; i< 10; i++) { + for(int ii = 0; ii< 10; ii++) { + items[i][ii].flag = 0; //doesn't hold anything + items[i][ii].itemIDNum = -1; //doesn't exist :) + items[i][ii].xpos = empty->w*i+1; + items[i][ii].ypos = empty->h*ii; + items[i][ii].num = 0; + } + } + + //create two fake items + items[0][0].flag = 1; + items[0][0].itemIDNum = 0; + items[0][0].num = 1; + + items[2][0].flag = 1; + items[2][0].itemIDNum = 1; + items[2][0].num = 3; + + backgroundSmall = create_bitmap(empty->w*10+10, empty->h+10); + backgroundBig = create_bitmap(empty->w*10+10, empty->h*10+10); + title = create_bitmap(15, backgroundSmall->h); + floodfill(title,0,0,200); + floodfill(backgroundSmall,0,0,100); + floodfill(backgroundBig,0,0,100); + areDisplaying = 0; + dragingWindow = 0; + lastSelectedX = -1; + lastSelectedY = -1; + bigwindow = 0; //false +} + +void TmwInventory::draw(BITMAP * buffer) { + // let's draw the inventory + if(areDisplaying) { + int max; + if(!bigwindow) { + max = 1; + blit(backgroundSmall, buffer, 0, 0, xpos-5, ypos-5, 800, 600); + } else { + max = 10; + blit(backgroundBig, buffer, 0, 0, xpos-5, ypos-5, 800, 600); + } + blit(title, buffer, 0, 0, xpos+backgroundSmall->w-5, ypos+-5, 800, 600); + for(int itemX = 0; itemX< 10; itemX++) { + for(int itemY = 0;itemY<max;itemY++) { + int draw = 0; + + blit(empty, buffer, 0, 0, (xpos+items[itemX][itemY].xpos), (ypos+items[itemX][itemY].ypos), 800, 600); + + if(mouse_b&1) { + if(xpos+items[itemX][itemY].xpos+empty->w > mouse_x && xpos+items[itemX][itemY].xpos < mouse_x) + if(ypos+items[itemX][itemY].ypos+empty->h > mouse_y && ypos+items[itemX][itemY].ypos < mouse_y) { + //selected + masked_blit(selected, buffer, 0, 0, (xpos+items[itemX][itemY].xpos), (ypos+items[itemX][itemY].ypos), 800, 600); + draw = 1; + if(items[itemX][itemY].flag) // have a item + if(!dragingItem) { //not dragging it + dragingItem=1; //begin to drag + ghostOldIDX = itemX; + ghostOldIDY = itemY; + ghostID = items[itemX][itemY].itemIDNum; + ghostX = mouse_x; + ghostY = mouse_y; + } + } + } else { + if(lastSelectedX != -1 && dragingItem) { // have stoped dragging it over a itemholder + //swap place + itemHolder temp; + int txpos1,typos1,txpos2,typos2; + txpos1 = items[lastSelectedX][lastSelectedY].xpos; + typos1 = items[lastSelectedX][lastSelectedY].ypos; + txpos2 = items[ghostOldIDX][ghostOldIDY].xpos; + typos2 = items[ghostOldIDX][ghostOldIDY].ypos; + temp = items[lastSelectedX][lastSelectedY]; + items[lastSelectedX][lastSelectedY] = items[ghostOldIDX][ghostOldIDY]; + items[ghostOldIDX][ghostOldIDY] = temp; + items[lastSelectedX][lastSelectedY].xpos = txpos1; + items[lastSelectedX][lastSelectedY].ypos = typos1; + items[ghostOldIDX][ghostOldIDY].xpos = txpos2; + items[ghostOldIDX][ghostOldIDY].ypos = typos2; + } + dragingItem = 0; // stop dragging + } + + if(xpos+items[itemX][itemY].xpos+empty->w > mouse_x && xpos+items[itemX][itemY].xpos < mouse_x && ypos+items[itemX][itemY].ypos+empty->h > mouse_y && ypos+items[itemX][itemY].ypos < mouse_y ) { + // a hoover + lastSelectedX = itemX; + lastSelectedY = itemY; + } + + if(items[itemX][itemY].flag) //draw the item + masked_blit(itemPIC[items[itemX][itemY].itemIDNum].pic, buffer, 0, 0, (xpos+items[itemX][itemY].xpos), (ypos+items[itemX][itemY].ypos), 800, 600); + + //the number of that item + if(!bigwindow) + alfont_textprintf_aa(buffer, gui_font, xpos+items[itemX][itemY].xpos+20, ypos+items[itemX][itemY].ypos+empty->h-15, makecol(0,0,0), "%i",items[itemX][itemY].num); + else + alfont_textprintf_aa(buffer, gui_font, xpos+items[itemX][itemY].xpos+20, ypos+items[itemX][itemY].ypos+empty->h-15, makecol(0,0,0), "%i",items[itemX][itemY].num); + } + } + + + if(mouse_b&2) { + if(xpos+title->w+backgroundSmall->w > mouse_x && xpos+backgroundSmall->w < mouse_x) + if(ypos+title->h > mouse_y && ypos < mouse_y) { + if(bigwindow) + bigwindow=0; + else + bigwindow = 1; + } + } + } + + if(mouse_b&1) { + if(xpos+title->w+backgroundSmall->w > mouse_x && xpos+backgroundSmall->w < mouse_x) + if(ypos+title->h > mouse_y && ypos < mouse_y) { //begin to move the window + xpos = mouse_x-(backgroundSmall->w); + ypos = mouse_y; + dragingWindow=1; + } + } else { dragingWindow=0;} + + if(dragingWindow) { //moving the window ? + xpos = mouse_x-(backgroundSmall->w); + ypos = mouse_y; + } + + if(dragingItem) { //moving the item + masked_blit(itemPIC[ghostID].pic, buffer, 0, 0, ghostX, ghostY, 800, 600); + ghostX = mouse_x; + ghostY = mouse_y; + } +} + + +void TmwInventory::show(int val) { + if(val) + areDisplaying = 1; + + if(!val) + areDisplaying = 0; +} + +int TmwInventory::addItem(int idnum, int antal) +{ +int found, tempi, tempii; +found = 0; +tempi = -1; +for(int i = 0; i< 10; i++) + { + for(int ii = 0; ii< 10; ii++) + { + if(items[i][ii].itemIDNum == idnum) + { found = 1; items[i][ii].num = antal; return -2; } + } + } +if(!found) +{ +for(int ii = 0; ii< 10; ii++) + { + for(int i = 0; i< 10; i++) + { + if(items[i][ii].flag == 0) + {tempi = i; tempii = ii; ii=10;i=10;} + } + } + if(tempi != -1) + { + items[tempi][tempii].flag = 1; + items[tempi][tempii].itemIDNum = idnum; + items[tempi][tempii].num = antal; + return 1; + } else { return -1; } + +} +return -3; +} + +int TmwInventory::rmItem(int idnum) +{ +int found, tempi; +found = 0; +tempi = -1; +for(int i = 0; i< 10; i++) + { + for(int ii = 0; ii< 10; ii++) + { + if(items[i][ii].itemIDNum == idnum) + { items[i][ii].itemIDNum = -1; + items[i][ii].flag = 0; + items[i][ii].num = 0; + return 1; + } + } + } +return -1; +} + +int TmwInventory::changeNum(int idnum, int antal) +{ +int found, tempi; +found = 0; +tempi = -1; +for(int i = 0; i< 10; i++) + { + for(int ii = 0; ii< 10; ii++) + { + if(items[i][ii].itemIDNum == idnum) + { items[i][ii].num = antal; return 1; } + } + } +return -1; +}
\ No newline at end of file diff --git a/src/gui/inventory.h b/src/gui/inventory.h new file mode 100644 index 00000000..75939950 --- /dev/null +++ b/src/gui/inventory.h @@ -0,0 +1,80 @@ +/** + + The Mana World + Copyright 2004 The Mana World Development Team + + This file is part of The Mana World. + + The Mana World 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 2 of the License, or + any later version. + + The Mana World 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 The Mana World; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +*/ + +#ifdef WIN32 + #pragma warning (disable:4312) +#endif + +#ifndef _INVENTORY_H +#define _INVENTORY_H +#include <allegro.h> +#ifdef WIN32 +#include <winalleg.h> +#endif +#include "../main.h" +#include "../game.h" +#include "../log.h" +#include "../Net/network.h" +#include "gui.h" + +struct itemHolder { // the holder of a item + int flag; // don't really know why I use this :) + int itemIDNum; // the id of the item + int num; // number of items + int xpos,ypos; // where am I? +}; + +struct itemID {//the holder of the pictures for each item, maybe more in the future + BITMAP * pic; +}; + +class TmwInventory{ + public: + TmwInventory() {}; + ~TmwInventory() {}; + + void create(int tempxpos, int tempypos); // create the window + void draw(BITMAP *); // draw the window (if areDisplaying != 0 ) + void show(int val); // choose between the show and don't show the window + void toggle() { if(areDisplaying){show(0);}else{show(1);} } + //API + int addItem(int idnum, int antal); //add a item + int rmItem(int idnum); //remove a item + int changeNum(int idnum, int antal); // change nummber of a item + //END API + private: + BITMAP * backgroundSmall; + BITMAP * backgroundBig; + BITMAP * title; + BITMAP * empty; + BITMAP * selected; + itemHolder items[10][10]; // this is the test holder of items + itemID itemPIC[2]; // I only got two items + int ghostX, ghostY, ghostID, ghostOldIDX,ghostOldIDY; //info needed when moving item + int dragingItem, lastSelectedX,lastSelectedY; //info needed when moving item + int areDisplaying, dragingWindow; + int bigwindow; + int xpos, ypos; // Where am I ? +}; + +#endif diff --git a/src/gui/login.cpp b/src/gui/login.cpp new file mode 100644 index 00000000..e3cb6195 --- /dev/null +++ b/src/gui/login.cpp @@ -0,0 +1,139 @@ +/** + + The Mana World + Copyright 2004 The Mana World Development Team + + This file is part of The Mana World. + + The Mana World 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 2 of the License, or + any later version. + + The Mana World 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 The Mana World; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +*/ + +#include "login.h" +#include "../Graphic/graphic.h" + +/** Display login GUI */ +void login() { +DIALOG login_dialog[] = { + /* (dialog proc) (x) (y) (w) (h) (fg) (bg) (key) (flags) (d1) (d2) (dp) (dp2) (dp3) */ + { tmw_dialog_proc, 300, 252, 200, 96, 0, -1, 0, 0, 0, 0, (char*)"Login", NULL, NULL }, + { tmw_text_proc, 304, 284, 50, 10, 0, 0, 0, 0, 0, 0, (char*)"Name:", NULL, NULL }, + { tmw_text_proc, 304, 304, 50, 10, 0, 0, 0, 0, 0, 0,(char*)"Password:", NULL, NULL }, + { tmw_edit_proc, 360, 280, 130, 18, 0, -1, 0, 0, 24, 0, username, NULL, NULL }, + { tmw_password_proc, 360, 300, 130, 18, 0, -1, 0, 0, 24, 0, password, NULL, NULL }, + { tmw_button_proc, 398, 322, 44, 18, 0, -1, 'o', D_EXIT, -1, 0, (char*)"&Ok", NULL, NULL }, + { tmw_button_proc, 446, 322, 44, 18, 0, -1, 'c', D_EXIT, -1, 0, (char*)"&Cancel", NULL, NULL }, + { tmw_check_proc, 304, 322, 60, 18, 0, 0, '1', 0, 0, 0, (char*)"keep", NULL, NULL }, + { NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL }, +}; + + if(get_config_int("login", "remember", 0)!=0) { + login_dialog[7].flags = D_SELECTED; + if(get_config_string("login", "username", 0))strcpy(username, get_config_string("login", "username", 0)); + else strcpy(username, "player\0"); + } + centre_dialog(login_dialog); + DIALOG_PLAYER *player = init_dialog(login_dialog, -1); + int gui_exit = 1; + while ((!key[KEY_ESC])&&(gui_exit)&&(state!=EXIT)&&(!key[KEY_ENTER])) { + clear_bitmap(buffer); + if(stretch_mode!=0)blit((BITMAP *)graphic[LOGIN_BMP].dat, buffer, 0, 0, 80, 60, 640, 480); + else blit((BITMAP *)graphic[LOGIN_BMP].dat, buffer, 0, 0, -120, -90, 640, 480); + + gui_exit = gui_update(player); + blit(buffer, screen, 0, 0, 0, 0, 800, 600); + } + state = EXIT; + set_config_int("login", "remember", (login_dialog[7].flags & D_SELECTED)>>1); + if(login_dialog[7].flags & D_SELECTED) { + if(!username)strcpy(username, "player\0"); + set_config_string("login", "username", username); + } else set_config_string("login", "username", "player\0"); + log("Player", "username", username); + gui_exit = shutdown_dialog(player); + if((gui_exit==5)||(key[KEY_ENTER])) { + if(username[0]=='\0') { + ok("Error", "Enter your username first"); + warning("Enter your username first"); + state = LOGIN; + } else { + server_login(); + close_session(); + } + } +} + +/** Attempt to login to login server */ +void server_login() { + int ret; + + // Connect to login server + ret = open_session(get_config_string("server", "host", 0), get_config_int("server", "port", 0)); + if(ret==SOCKET_ERROR) { + state = LOGIN; + ok("Error", "Unable to connect to login server"); + warning("Unable to connect to login server"); + return; + } + + // Send login infos + + + WFIFOW(0) = net_w_value(0x0064); + + WFIFOL(2) = 0; + memcpy(WFIFOP(6), username, 24); + memcpy(WFIFOP(30), password, 24); + WFIFOB(54) = 0; + WFIFOSET(55); + + while((in_size<23)||(out_size>0))flush(); + log_hex("Login_Packet", "Packet_ID", RFIFOW(0)); + log_int("Login_Packet", "Packet_length", get_packet_length(RFIFOW(0))); + + if(RFIFOW(0)==0x0069) { + while(in_size<RFIFOW(2))flush(); + n_server = (RFIFOW(2)-47)/32; + server_info = (SERVER_INFO *)malloc(sizeof(SERVER_INFO)*n_server); + account_ID = RFIFOL(8); + session_ID1 = RFIFOL(4); + session_ID2 = RFIFOL(12); + sex = RFIFOB(46); + for(int i=0;i<n_server;i++) { + server_info[i].address = RFIFOL(47+32*i); + memcpy(server_info[i].name, RFIFOP(47+32*i+6), 20); + server_info[i].online_users = RFIFOW(47+32*i+26); + server_info[i].port = RFIFOW(47+32*i+4); + state = CHAR_SERVER; + } + log("Login_Packet", "server_address", iptostring(server_info[0].address)); + log("Login_Packet", "server_name", server_info[0].name); + log_int("Login_Packet", "server_users", server_info[0].online_users); + log_int("Login_Packet", "server_port", server_info[0].port); + RFIFOSKIP(RFIFOW(2)); + } else if(RFIFOW(0)==0x006a) { + switch(RFIFOB(2)) { + case 0: + ok("Error", "Unregistered ID"); + break; + case 1: + ok("Error", "Wrong password"); + break; + } + state = LOGIN; + RFIFOSKIP(23); + } else ok("Error", "Unknown error"); + // Todo: add other packets, also encrypted +} diff --git a/src/gui/login.h b/src/gui/login.h new file mode 100644 index 00000000..c181e0eb --- /dev/null +++ b/src/gui/login.h @@ -0,0 +1,43 @@ +/** + + The Mana World + Copyright 2004 The Mana World Development Team + + This file is part of The Mana World. + + The Mana World 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 2 of the License, or + any later version. + + The Mana World 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 The Mana World; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +*/ + +#ifdef WIN32 + #pragma warning (disable:4312) +#endif + +#ifndef _LOGIN_H +#define _LOGIN_H + +#include <allegro.h> +#ifdef WIN32 +#include <winalleg.h> +#endif +#include "../main.h" +#include "../log.h" +#include "../Net/network.h" +#include "gui.h" + +void login(); +void server_login(); + +#endif diff --git a/src/gui/skill.cpp b/src/gui/skill.cpp new file mode 100644 index 00000000..f1ccdcc2 --- /dev/null +++ b/src/gui/skill.cpp @@ -0,0 +1,56 @@ +/** + + The Mana World + Copyright 2004 The Mana World Development Team + + This file is part of The Mana World. + + The Mana World 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 2 of the License, or + any later version. + + The Mana World 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 The Mana World; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + By ElvenProgrammer aka Eugenio Favalli (umperio@users.sourceforge.net) + +*/ + +#include "skill.h" + +extern CHAR_SEL_INFO *char_info; + +char str_string[8]; +char agi_string[8]; +char vit_string[8]; +char int_string[8]; +char dex_string[8]; +char luk_string[8]; + +DIALOG skill_dialog[] = { + /* (dialog proc) (x) (y) (w) (h) (fg) (bg) (key) (flags) (d1) (d2) (dp) (dp2) (dp3) */ + { tmw_dialog_proc, 300, 200, 120, 60, 0, 0, 0, 0, 0, 0, (char *)"Skill", NULL, NULL }, + { tmw_text_proc, 304, 224, 252, 100, 0, 0, 0, 0, 0, 0, str_string, NULL, NULL }, + { tmw_text_proc, 304, 234, 252, 100, 0, 0, 0, 0, 0, 0, agi_string, NULL, NULL }, + { tmw_text_proc, 304, 244, 252, 100, 0, 0, 0, 0, 0, 0, vit_string, NULL, NULL }, + { tmw_text_proc, 364, 224, 252, 100, 0, 0, 0, 0, 0, 0, int_string, NULL, NULL }, + { tmw_text_proc, 364, 234, 252, 100, 0, 0, 0, 0, 0, 0, dex_string, NULL, NULL }, + { tmw_text_proc, 364, 244, 252, 100, 0, 0, 0, 0, 0, 0, luk_string, NULL, NULL }, + { NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL } +}; + +void update_skill_dialog() { + sprintf(str_string, "STR: %i", char_info->STR); + sprintf(agi_string, "AGI: %i", char_info->AGI); + sprintf(vit_string, "VIT: %i", char_info->VIT); + sprintf(int_string, "INT: %i", char_info->INT); + sprintf(dex_string, "DEX: %i", char_info->DEX); + sprintf(luk_string, "LUK: %i", char_info->LUK); +} diff --git a/src/gui/skill.h b/src/gui/skill.h new file mode 100644 index 00000000..a0ce031d --- /dev/null +++ b/src/gui/skill.h @@ -0,0 +1,40 @@ +/** + + The Mana World + Copyright 2004 The Mana World Development Team + + This file is part of The Mana World. + + The Mana World 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 2 of the License, or + any later version. + + The Mana World 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 The Mana World; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + By ElvenProgrammer aka Eugenio Favalli (umperio@users.sourceforge.net) + +*/ + +#ifdef WIN32 + #pragma warning (disable:4312) +#endif + +#ifndef _SKILL_H +#define _SKILL_H + +#include <allegro.h> +#include "../main.h" + +//DIALOG skill_dialog[]; + +void update_skill_dialog(); + +#endif |