Mercurial > otakunoraifu
diff scn2k/scn2k_text.cc @ 56:c7bcc0ec2267
* replaced Grp and Text classes by the TextImpl and GrpImpl ones
* splitted scn2k.h into smaller header files
* moved some definitions from scn2k_*.cc to the header files
* moved opcode implementation to scn2k_*impl.cc
author | thib |
---|---|
date | Thu, 30 Apr 2009 19:05:09 +0000 |
parents | f1a27ee7e03c |
children | 6d9146f56ccf |
line wrap: on
line diff
--- a/scn2k/scn2k_text.cc +++ b/scn2k/scn2k_text.cc @@ -9,7 +9,7 @@ TODO: Start すると文字を描画開始する。クリックで全描画。 Flush するとバッファ内の文字をすべて描画する Wait すると全描画後、クリックされるまでカーソルを表示するまで待つ - TextImpl 側の状態としては Wait のみを持つ (PREPAREに戻るのを待つ) + Text 側の状態としては Wait のみを持つ (PREPAREに戻るのを待つ) ただし、Skip の権利はどっちがもつ?(現状は?) GrpObj: NextObj と GrpObj を分離。CreateObj は現状通り、Visible=1 時に行う。 @@ -55,219 +55,24 @@ DONE: * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#include "window/event.h" -#include "window/picture.h" -#include "window/widget.h" +#include "scn2k_text.h" + #include "system/file.h" -#include "system/system_config.h" #include "scn2k.h" #include <string> using namespace std; -// kanji conv : デバッグ表示用 -void kconv(const unsigned char* src, unsigned char* dest); -void kconv_rev(const unsigned char* src, unsigned char* dest); -string kconv(const string& s); -string kconv_rev(const string& s); -// render.cc -void DSurfaceFillA(Surface* src, const Rect& rect, int r, int g, int b, int a); // テキストウィンドウ背景の設定 -void DSurfaceMove(Surface* src_o, const Rect& srcrect, Surface* dst_o, const Rect& dstrect); // コピー +#include "window/render.h" /**************************************************************:: ** -** TextImpl(interface) +** Text(implementation) */ -struct TimerAtom { - int from; - int to; - unsigned int start_time; - unsigned int total_time; -}; - -struct TextWindow { -/* @@@ : SetWindowColor での surface 再設定に注意 */ - WidText* wid; - bool name_visible; - WidLabel* name; - PicContainer* name_container; - PicBase* face; - PicBase* face_pics[8]; - TextWindow(PicContainer& parent, Event::Container& event, int window_no, void* callback); - ~TextWindow() { - if (name_container != NULL) { - delete name_container; - name_container = NULL; - } - int i; - for (i=0; i<8; i++) { - if (face_pics[i] != NULL) { - delete face_pics[i]; - face_pics[i] = NULL; - } - } - if (wid != NULL) { - delete wid; - wid = NULL; - } - } - Rect WakuSize(PicContainer& pic, int waku_no); - void MakeWaku(PicContainer& pic, Event::Container& event, int waku_no,int window_no, bool* use_btn, void* callback); - void show(void) { - wid->show(); - if (name_container && name_visible) name_container->show(); - if (face) face->show(); - } - void hide(void) { - wid->hide(); - if (name_container) name_container->hide(); - if (face) face->hide(); - } - void ShowFace(const char* path) { - if (!face) return; - face->SetSurface( path, 0,0); - } - void ResetFace(void) { - if (!face) return; - face->SetSurface( (Surface*)0, 0,0); - } - void StartText(const TextStream& _stream) { - wid->Clear(); - wid->stream = _stream; - if (name_container) { - char namestr[1024]; - namestr[0] = 0; - wid->stream.RemoveName(namestr, 1024); - if (namestr[0] == 0) { - name_container->hide(); - } else { - if (name) { - name_container->show_all(); - name->SetText(namestr); - } - } - } - wid->Start(); - } - void SetName(const char* n) { - if (name_container && name) { - if (n[0]) { - name_container->show(); - name->SetText(n); - name_visible = true; - } else { - name_container->hide(); - name_visible = false; - } - } - } -}; - -class TextImpl : public CommandHandler { - public: - TextImpl(Event::Container& _event, PicContainer& _parent, vector<BacklogItem>& parent_backlog, BacklogItem& parent_backlog_item); - ~TextImpl(); - void InitWindow(void); - void SetWindowColor(int r, int g, int b, int a, bool is_transparent); - void SetTextSpeed(int new_speed); - void SetTextWait(int new_wait); - void CreateSelect(Cmd& cmd); - void Exec(Cmd& cmd); - bool Wait(unsigned int current_time, Cmd& cmd); - void hide(void); - void show(void) { show(text_window_number); } - void show(int num); - void DrawBacklog(BacklogItem& item, Cmd& cmd); - void Save(std::string& str, bool select_save); - void Load(const char* str); - void SetSkipMode(SkipMode _mode); - void CreateSelBG(void); - - void AddText(const char* str); - - static void PressFuncSkip(void* pointer, WidButton* from); - static void PressFuncLoad(void* pointer, WidButton* from); - static void PressFuncSave(void* pointer, WidButton* from); - static void PressFuncBacklog(void* pointer, WidButton* from); - static void PressFuncBacklogFwd(void* pointer, WidButton* from); - - private: - static void PressFuncButton(void* pointer, WidButton* from); - static bool PressFunc(int x, int y, void* pointer); - void SetCursor(int num); - - public: - TextWindow* text; - typedef enum {NORMAL=0, WAIT_TEXT=1, WAIT=2, - WAIT_CLICK=3, WAIT_ABORT=4, WAIT_CLICK_MOUSEPOS = 5, - WAIT_CLICK_MOUSEPOSEND_L = 6, WAIT_CLICK_MOUSEPOSEND_R = 7, - WAIT_SELECT_INBOX = 10, WAIT_SELECT_OUTBOX=11, WAIT_SELECT_VALUE = 12, - WAIT_EXTRN_MASK = 64, SAVEMASK = 128, LOADMASK = 256, SKIPMASK = 512, - CLEARSCR_MASK = 1024, STATSAVE_MASK = 2048, CLEARSCR_WAIT_MASK=(1<<12), - SKIPEND_MASK = (1<<13), BACKLOG_MASK=(1<<14), BACKLOG_MASK_FWD=(1<<15), - BACKLOG_MASK_KOE=(1<<16), BACKLOG_WAIT_MASK=(1<<17), - ALLMASK = (CLEARSCR_MASK | WAIT_EXTRN_MASK | SAVEMASK | - LOADMASK | SKIPMASK | BACKLOG_MASK | BACKLOG_MASK_FWD | - BACKLOG_MASK_KOE | BACKLOG_WAIT_MASK | STATSAVE_MASK | - CLEARSCR_WAIT_MASK | SKIPEND_MASK) - } Status; - Status status, status_saved, status_mask; - - private: - std::string ruby_text; - bool ruby_text_flag; - unsigned int wait_time; - unsigned int old_time; - unsigned int base_time; - int text_window_number; - bool text_parsing; - TextStream text_stream; - SkipMode skip_mode; - int save_selectcount; - - std::map<int, TimerAtom> timer_var; - std::vector<WidTextButton*> selects; - std::vector<int> sel_backlog_pos; - string replace_name[26]; - string replace_name2[26]; - PicContainer* sel_widget; - PicWidget* backlog_widget; - - vector<BacklogItem>& backlog; - BacklogItem& backlog_item; - BacklogItem cur_backlog_item; - BacklogItem drawn_backlog_item; - - TextWindow* widgets[32]; - WidTimeCursor* kcursor; - Surface* sel_bg1; - Surface* sel_bg2; - Rect sel_bg_rect; - - VarInfo wait_savedvar[2]; - - AyuSysConfig *config; - - Event::Container& event; - PicContainer& parent; - - //Opcode handling - void impl_txtClear(Cmd& cmd); - void impl_logKoe(Cmd& cmd); - void impl_pause(Cmd& cmd); - void impl_br(Cmd& cmd); - void impl_FaceOpen(Cmd& cmd); - void impl_FaceClear(Cmd& cmd); -}; - -/**************************************************************:: -** -** TextImpl(implementation) -*/ -TextImpl::TextImpl(Event::Container& _event, PicContainer& _parent, vector<BacklogItem>& parent_backlog, BacklogItem& parent_backlog_item) : - text(0),status(TextImpl::NORMAL), status_saved(TextImpl::NORMAL), status_mask(TextImpl::NORMAL), ruby_text_flag(false), +Text::Text(Event::Container& _event, PicContainer& _parent) : + text(0),status(Text::NORMAL), status_saved(Text::NORMAL), status_mask(Text::NORMAL), ruby_text_flag(false), old_time(0), base_time(0), text_window_number(0), text_parsing(false), skip_mode(SKIP_NO), save_selectcount(0), sel_widget(0), - backlog_widget(0), backlog(parent_backlog), backlog_item(parent_backlog_item), parent(_parent), event(_event), + backlog_widget(0), parent(_parent), event(_event), kcursor(0), sel_bg1(0), sel_bg2(0), sel_bg_rect(0,0,0,0) { config = AyuSysConfig::GetInstance(); int i; @@ -277,35 +82,54 @@ TextImpl::TextImpl(Event::Container& _ev text_stream.kanji_type = TextStream::sjis; event.RegisterGlobalPressFunc(&PressFunc, (void*)this); - RegisterCommand(1, 33, 73, "grpOpenBg", (CmdImpl) &TextImpl::impl_txtClear); - RegisterCommand(1, 33, 75, "grpMulti", (CmdImpl) &TextImpl::impl_txtClear); - RegisterCommand(1, 33, 76, "grpOpen", (CmdImpl) &TextImpl::impl_txtClear); + RegisterCommand(1, 33, 73, "grpOpenBg", (CmdImpl) &Text::impl_txtClear); + RegisterCommand(1, 33, 75, "grpMulti", (CmdImpl) &Text::impl_txtClear); + RegisterCommand(1, 33, 76, "grpOpen", (CmdImpl) &Text::impl_txtClear); - RegisterCommand(1, 23, 0, "koePlay", (CmdImpl) &TextImpl::impl_logKoe); - RegisterCommand(1, 23, 8, "koeDoPlay", (CmdImpl) &TextImpl::impl_logKoe); + RegisterCommand(1, 23, 0, "koePlay", (CmdImpl) &Text::impl_logKoe); + RegisterCommand(1, 23, 8, "koeDoPlay", (CmdImpl) &Text::impl_logKoe); - RegisterCommand(0, 3, 151, "msgHide", (CmdImpl) &TextImpl::impl_txtClear); - RegisterCommand(0, 3, 17, "pause", (CmdImpl) &TextImpl::impl_pause); - RegisterCommand(0, 3, 3, "par", (CmdImpl) &TextImpl::impl_br); //FIXME - RegisterCommand(0, 3, 201, "br", (CmdImpl) &TextImpl::impl_br); - RegisterCommand(0, 3, 1000, "FaceOpen", (CmdImpl) &TextImpl::impl_FaceOpen); - RegisterCommand(0, 3, 1001, "FaceClear", (CmdImpl) &TextImpl::impl_FaceClear); + RegisterCommand(0, 3, 151, "msgHide", (CmdImpl) &Text::impl_txtClear); + RegisterCommand(0, 3, 17, "pause", (CmdImpl) &Text::impl_pause); + RegisterCommand(0, 3, 3, "par", (CmdImpl) &Text::impl_br); //FIXME + RegisterCommand(0, 3, 201, "br", (CmdImpl) &Text::impl_br); + RegisterCommand(0, 3, 1000, "FaceOpen", (CmdImpl) &Text::impl_FaceOpen); + RegisterCommand(0, 3, 1001, "FaceClear", (CmdImpl) &Text::impl_FaceClear); + RegisterCommand(0, 3, 120, "__doruby", (CmdImpl) &Text::impl_doRuby); //FIXME: I don't know how it works + RegisterCommand(0, 3, 102, "TextWindow", (CmdImpl) &Text::impl_TextWindow); + RegisterCommand(0, 3, 103, "FastText", NULL);//FIXME: (CmdImpl) &Text::impl_FastText); + RegisterCommand(0, 3, 104, "NormalText", NULL); + RegisterCommand(0, 3, 152, "msgClear", (CmdImpl) &Text::impl_msgClear); + + RegisterCommand(0, 2, 1, "select", (CmdImpl) &Text::impl_createSelect); + RegisterCommand(0, 2, 3, "select2?", (CmdImpl) &Text::impl_createSelect); //What difference with select? + + RegisterCommand(0, 4, 1000, "ShowBackground", (CmdImpl) &Text::impl_ShowBackground); + RegisterCommand(0, 4, 1100, "SetSkipMode", (CmdImpl) &Text::impl_SetSkipMode); + RegisterCommand(1, 4, 100, "wait", (CmdImpl) &Text::impl_Wait); + RegisterCommand(1, 4, 111, "time", (CmdImpl) &Text::impl_Wait); + RegisterCommand(1, 4, 121, "timeEx", (CmdImpl) &Text::impl_Wait); } -TextImpl::~TextImpl() { - if (sel_widget) delete sel_widget; +Text::~Text() { + if (sel_widget != NULL) + delete sel_widget; int i; for (i=0; i<32; i++) { - if (widgets[i]) delete widgets[i]; + if (widgets[i] != NULL) + delete widgets[i]; } - if (backlog_widget) delete backlog_widget; - if (sel_bg1) parent.Root().DeleteSurface(sel_bg1); - if (sel_bg2) parent.Root().DeleteSurface(sel_bg2); + if (backlog_widget != NULL) + delete backlog_widget; + if (sel_bg1 != NULL) + parent.Root().DeleteSurface(sel_bg1); + if (sel_bg2 != NULL) + parent.Root().DeleteSurface(sel_bg2); event.DeleteGlobalPressFunc(&PressFunc, (void*)this); } -bool TextImpl::PressFunc(int x, int y, void* pointer) { - TextImpl* t = (TextImpl*)pointer; +bool Text::PressFunc(int x, int y, void* pointer) { + Text* t = (Text*)pointer; if (t->status == WAIT_CLICK) { t->status = WAIT_ABORT; } else if (t->status == WAIT_CLICK_MOUSEPOS) { @@ -328,8 +152,9 @@ bool TextImpl::PressFunc(int x, int y, v } return true; // event not deleted } -void TextImpl::PressFuncButton(void* pointer, WidButton* from) { - TextImpl* t = (TextImpl*)pointer; + +void Text::PressFuncButton(void* pointer, WidButton* from) { + Text* t = (Text*)pointer; if (t->status != WAIT_SELECT_INBOX && t->status != WAIT_SELECT_OUTBOX) return; vector<WidTextButton*>::iterator it; int sel = 0; @@ -337,14 +162,13 @@ void TextImpl::PressFuncButton(void* poi if (from == *it) break; } if (it == t->selects.end()) { - fprintf(stderr,"TextImpl::PressFuncButton: Cannot find select widget\n"); + fprintf(stderr,"Text::PressFuncButton: Cannot find select widget\n"); return; } t->status = Status(WAIT_SELECT_VALUE + sel); - return; } -void TextImpl::SetSkipMode(SkipMode _mode) { +void Text::SetSkipMode(SkipMode _mode) { if ( (skip_mode & SKIP_IN_MENU) && (_mode & SKIP_IN_MENU) == 0) { if (status_mask & BACKLOG_WAIT_MASK) { // backlog mode から復帰 status_mask = Status(status_mask & (~(BACKLOG_MASK|BACKLOG_MASK_FWD|BACKLOG_MASK_KOE|BACKLOG_WAIT_MASK))); @@ -375,67 +199,50 @@ void TextImpl::SetSkipMode(SkipMode _mod skip_mode = _mode; } -/* hash_map が欲しい……*/ -#include <map> -#include <list> -struct SaveFaceHash { // バックログセーブ時の顔画像管理を行う - map<string, int> facetonum; - typedef pair<string,int> Node; - typedef list<Node> List; - List container; - int id_max; - static int size_max; - SaveFaceHash() : id_max(0) { - } - void NewNode(string face, int face_id) { - facetonum[face] = face_id; - container.push_front(Node(face, face_id)); - if (container.size() > size_max) { - Node remove = container.back(); - container.pop_back(); - facetonum.erase(remove.first); +void Text::InitWindow(void) { + int i; + int w; + std::string str; + + for (w=0; w<32; w++) { + widgets[w] = new TextWindow(parent, event, w, (void*)this); + if (widgets[w]->wid == 0) { + delete widgets[w]; + widgets[w] = NULL; } } - int Add(string face) { - int id; int ret = -1; - int i; List::iterator it; - if (face.empty()) return -1; - if (facetonum.find(face) == facetonum.end()) { - id = ++id_max; - NewNode(face, id); - ret = -1; - } else { - id = facetonum[face]; - for (i=0, it=container.begin(); it != container.end(); i++, it++) { - if (it->second == id) { - ret = i; - Node n = *it; - container.erase(it); - container.push_front(n); - break; - } - } - } - return ret; + SetCursor(0); + for (i=0; i<26; i++) { + char buf[1024]; + sprintf(buf, "#NAME.%c", i+'A'); + const char* s = config->GetParaStr(buf); + if (s != NULL) replace_name[i] = s; } - string Get(int num) { - if (num < 0) return ""; - List::iterator it = container.begin(); - for (; it != container.end(); it++) { - if (num == 0) return it->first; - num--; - } - return ""; - } -}; + // replace_name2 : 初期設定 + // 渚、秋生、渚 (CLANNAD) + char name_nagisa[3] = {'\x8f', '\x8d', '\0'}; + char name_akio[5] = {'\x8f', '\x48', '\x90', '\xb6', '\0'}; + replace_name2[0] = name_nagisa; + replace_name2[1] = name_akio; + replace_name2[2] = name_nagisa; + text = NULL; + /* テキスト速度の設定 */ + int speed, mod, wait, auto_mod; + config->GetParam("#INIT_MESSAGE_SPEED", 1, &speed); + config->GetParam("#INIT_MESSAGE_SPEED_MOD", 1, &mod); + config->GetParam("#MESSAGE_KEY_WAIT_USE", 1, &auto_mod); + config->GetParam("#MESSAGE_KEY_WAIT_TIME", 1, &wait); + if (mod) speed = -1; + if (!auto_mod) wait = -1; + SetTextSpeed(speed); + SetTextWait(wait); +} -int SaveFaceHash::size_max = 20; - -void TextImpl::Save(string& str, bool rollback_save) { +void Text::Save(string& str, bool rollback_save) { char buf[1024]; str = "\n"; - str += "[TextImpl Window]\n"; - sprintf(buf, "TextImplWindow=%d\n",text_window_number); + str += "[Text Window]\n"; + sprintf(buf, "TextWindow=%d\n",text_window_number); str += buf; if (rollback_save) { ++save_selectcount; @@ -458,53 +265,55 @@ void TextImpl::Save(string& str, bool ro if (!rollback_save) { SaveFaceHash face_log; do { - int cur_scn = -1; int cur_pos = -1; - sprintf(buf, "Backlog.%d=",++cnt); - str += buf; - for (; it != backlog.end(); it++) { - buf[0] = 0; int buflen = 0; - if (it->scn == -1) continue; - if (it->pos == -1 && it->scn != 0) continue; + int cur_scn = -1; int cur_pos = -1; + sprintf(buf, "Backlog.%d=",++cnt); + str += buf; + for (; it != backlog.end(); it++) { + buf[0] = 0; + int buflen = 0; + if (it->scn == -1) + continue; + if (it->pos == -1 && it->scn != 0) + continue; - buf[buflen++] = ';'; - if (it->scn == 0 && it->pos == -1) { - buflen += snprintf(buf+buflen, 1000-buflen, "\"%s\".", it->text.Save().c_str()); - } else { - if (cur_scn != -1 && cur_scn != it->scn) break; // scn change - if (cur_pos != -1 && cur_pos/5000 != it->pos/5000) break; // pos exceeded - if (!it->text.container.empty()) { - buflen += snprintf(buf+buflen, 1000-buflen, "\"%s\"", it->text.Save().c_str()); + buf[buflen++] = ';'; + if (it->scn == 0 && it->pos == -1) + buflen += snprintf(buf+buflen, 1000-buflen, "\"%s\".", it->text.Save().c_str()); + else { + if (cur_scn != -1 && cur_scn != it->scn) break; // scn change + if (cur_pos != -1 && cur_pos/5000 != it->pos/5000) break; // pos exceeded + if (!it->text.container.empty()) { + buflen += snprintf(buf+buflen, 1000-buflen, "\"%s\"", it->text.Save().c_str()); + } + if (cur_scn == -1) { // scene change + buflen += snprintf(buf+buflen, 1000-buflen, ":%d:%d",it->scn,it->pos); + cur_scn = it->scn; + } + else + buflen += snprintf(buf+buflen, 1000-buflen, "%d",it->pos); + cur_pos = it->pos; } - if (cur_scn == -1) { // scene change - buflen += snprintf(buf+buflen, 1000-buflen, ":%d:%d",it->scn,it->pos); - cur_scn = it->scn; - } else { - buflen += snprintf(buf+buflen, 1000-buflen, "%d",it->pos); + if (it->koe != -1) + buflen += snprintf(buf+buflen, 1000-buflen, ",%d",it->koe); + if (!it->face.empty()) { + if (it->koe == -1) buf[buflen++] = ','; + int face_num = face_log.Add(it->face); + if (face_num >= 0 && face_num < 20) + buflen += snprintf(buf+buflen, 1000-buflen, ",%c", 'A'+face_num); + else + buflen += snprintf(buf+buflen, 1000-buflen, ",\"%s\"", it->face.c_str()); } - cur_pos = it->pos; + buf[buflen++] = '\0'; + if (buflen >= 1000) { // 万が一、バックログ1アイテムの大きさが 1000byte を越えるとき + fprintf(stderr,"Fatal : Cannot save backlog crrectly; Please send bug report to the author.\n"); + } else str += buf; } - if (it->koe != -1) - buflen += snprintf(buf+buflen, 1000-buflen, ",%d",it->koe); - if (!it->face.empty()) { - if (it->koe == -1) buf[buflen++] = ','; - int face_num = face_log.Add(it->face); - if (face_num >= 0 && face_num < 20) - buflen += snprintf(buf+buflen, 1000-buflen, ",%c", 'A'+face_num); - else - buflen += snprintf(buf+buflen, 1000-buflen, ",\"%s\"", it->face.c_str()); - } - buf[buflen++] = '\0'; - if (buflen >= 1000) { // 万が一、バックログ1アイテムの大きさが 1000byte を越えるとき - fprintf(stderr,"Fatal : Cannot save backlog crrectly; Please send bug report to the author.\n"); - } else str += buf; - } - str += "\n"; - } while(it != backlog.end()); + str += "\n"; + } while(it != backlog.end()); } - return; } -void TextImpl::Load(const char* str) { +void Text::Load(const char* str) { if (text) text->wid->Clear(); hide(); text_window_number = 0; @@ -530,11 +339,11 @@ void TextImpl::Load(const char* str) { cur_backlog_item.Clear(); drawn_backlog_item.Clear(); - str = strstr(str, "\n[TextImpl Window]\n"); + str = strstr(str, "\n[Text Window]\n"); if (str) { SaveFaceHash face_log; - str += strlen("\n[TextImpl Window]\n"); + str += strlen("\n[Text Window]\n"); const char* strend = str; do { str = strend; @@ -544,7 +353,7 @@ void TextImpl::Load(const char* str) { else strend++; if (str[0] == '[') break; // next section - if (strncmp(str, "TextImplWindow=",15) == 0) { + if (strncmp(str, "TextWindow=",15) == 0) { str += 15; sscanf(str, "%d", &text_window_number); } else if (strncmp(str, "SaveSelectCount=",16) == 0) { @@ -632,12 +441,12 @@ void TextImpl::Load(const char* str) { // backlog.clear(); } -void TextImpl::hide(void) { +void Text::hide(void) { if (text) text->hide(); if (kcursor) kcursor->hide(); text = NULL; } -void TextImpl::show(int num) { +void Text::show(int num) { if (num != text_window_number) { hide(); if (num >= 0 && num < 32 && widgets[num] != 0) { @@ -660,7 +469,7 @@ void TextImpl::show(int num) { } } -void TextImpl::DrawBacklog(BacklogItem& item, Cmd& cmd) { +void Text::DrawBacklog(BacklogItem& item, Cmd& cmd) { show(); text->wid->deactivate(); status_mask = Status(status_mask | BACKLOG_WAIT_MASK); @@ -681,7 +490,7 @@ void TextImpl::DrawBacklog(BacklogItem& if (kcursor) kcursor->hide(); } -void TextImpl::CreateSelBG(void) { +void Text::CreateSelBG(void) { if (sel_bg1 != NULL || sel_bg2 != NULL) return; const char* btnfile1 = config->GetParaStr("#SELBTN.000.NAME"); @@ -704,8 +513,8 @@ void TextImpl::CreateSelBG(void) { if (sel_bg2) sel_bg_rect.join(Rect(*sel_bg2)); } -void TextImpl::CreateSelect(Cmd& cmd) { - char key[1024]; +void Text::CreateSelect(Cmd& cmd) { + char key[23]; sprintf(key, "#WINDOW.%03d.SELCOM_USE",text_window_number); int sel_type = 0; if (cmd.cmd3 == 1) config->GetParam(key, 1, &sel_type); @@ -825,7 +634,7 @@ External_select: } } -void TextImpl::AddText(const char* str_o) { +void Text::AddText(const char* str_o) { char str[10001]; if (text == NULL) return; /* まず、replace string を変換 */ @@ -890,67 +699,7 @@ void TextImpl::AddText(const char* str_o text_stream.Add(str_top); } -void TextImpl::impl_txtClear(Cmd& cmd) { - if (text != NULL) { - text->ResetFace(); - if (cmd.cmd2 == 3 && cmd.cmd3 == 151) - text->wid->Clear(); - } - cur_backlog_item.face = ""; - if (cmd.cmd2 == 3 && cmd.cmd3 == 151) - text_stream.Clear(); - hide(); -} - -void TextImpl::impl_logKoe(Cmd& cmd) { - // PlayKoe ; 声出力コマンドをチェックする */ - cur_backlog_item.koe = cmd.args[0].value; -} - -void TextImpl::impl_pause(Cmd& cmd) { - if (text != NULL) { - eprintf("start\n"); - text->StartText(text_stream); - if (skip_mode & SKIP_TEXT) text->wid->Flush(); - else if (kcursor) kcursor->show(); - status = WAIT_TEXT; - text_parsing = false; - } - backlog_item = cur_backlog_item; - if (cur_backlog_item.scn == 0 && cur_backlog_item.pos == -1) backlog_item.text = text_stream; - cur_backlog_item.Clear(); - - cmd.clear(); - cmd.cmd_type = CMD_WAITFRAMEUPDATE; // 画像描画に戻る(skip時にテキストが描画されやすくするため) -} - -void TextImpl::impl_br(Cmd& cmd) { - text_stream.AddReturn(); - cur_backlog_item.DeleteTextPos(); - cmd.clear(); -} - -void TextImpl::impl_FaceOpen(Cmd& cmd) { - if (text == NULL) - show(); - string s = cmd.Str(cmd.args[0]); - s += ".g00"; - if (text != NULL) - text->ShowFace(s.c_str()); - cur_backlog_item.face = s; - cmd.cmd_type = CMD_SAVECMD_ONCE; -} - -void TextImpl::impl_FaceClear(Cmd& cmd) { - if (text == NULL) - show(); - if (text) - text->ResetFace(); - cur_backlog_item.face = ""; - cmd.cmd_type = CMD_SAVECMD_ONCE; -} - -void TextImpl::Exec(Cmd& cmd) { +void Text::Exec(Cmd& cmd) { if (cmd.cmd_type == CMD_TEXT) { if (text == NULL) { show(); @@ -979,95 +728,9 @@ void TextImpl::Exec(Cmd& cmd) { CommandHandler::Exec(cmd); - if (cmd.cmd1 == 0 && cmd.cmd2 == 3) { - if (cmd.cmd3 == 0x78) { // ルビ関連 - if (text == NULL) { - show(); - } - if (cmd.cmd4 == 1) { - ruby_text_flag = true; - eprintf("SetRubyTextImpl."); - cmd.clear(); - } else if (cmd.cmd4 == 0) { - if (ruby_text.length() == 0) { // ルビを振るテキストがない - eprintf("Cannot find ruby text.\n"); - return; - } - if (cmd.args.size() != 1) return; - char debug1[1024], debug2[1024]; - kconv( (unsigned char*)ruby_text.c_str(), (unsigned char*)debug1); - kconv( (unsigned char*)cmd.Str(cmd.args[0]), (unsigned char*)debug2); - eprintf("SetRuby. %s, %s",debug1, debug2); - text_stream.AddRuby(ruby_text.c_str(), cmd.Str(cmd.args[0])); - cur_backlog_item.DeleteTextPos(); - cmd.clear(); - } - } else if (cmd.cmd3 == 0x66) { // テキストウィンドウの形 - if (cmd.cmd4 == 0) { - eprintf("set text window <- %d\n",cmd.args[0].value); - if (text) show(cmd.args[0].value); - else text_window_number = cmd.args[0].value; - } else if (cmd.cmd4 == 1) { // default value - eprintf("set text window <- default\n"); - if (text) show(0); - else text_window_number = 0; - } - cmd.clear(); - } else if (cmd.cmd3 == 0x67) { // テキストウィンドウ表示? - show(); -// 表示の際はテキストをクリアしない? -// if (text) text->wid->Clear(); -// text_stream.Clear(); - cmd.clear(); - } else if (cmd.cmd3 == 0x68) { // テキスト表示? - // 全テキスト表示 - if (text) { - text->StartText(text_stream); - text->wid->Flush(); - } - cmd.clear(); - } else if (cmd.cmd3 == 0x98) { // テキストウィンドウクリア? - show(); - if (text) text->wid->Clear(); - text_stream.Clear(); - cmd.clear(); - } - } else if (cmd.cmd1 == 0 && cmd.cmd2 == 2 && (cmd.cmd3 == 1 || cmd.cmd3 == 3) && cmd.cmd4 == 0) { - // 選択肢 - CreateSelect(cmd); - //FIXME: Check if it's really clean - if (text_parsing) { - show(); - text->StartText(text_stream); - if (skip_mode & SKIP_TEXT) text->wid->Flush(); - else if (kcursor) kcursor->hide(); - text_parsing = false; - text_stream.Clear(); - } - cmd.cmd_type = CMD_ROLLBACKPOINT; /* 選択肢はセーブ位置 / シナリオ巻き戻し位置 */ - // cmd.clear(); - } else if (cmd.cmd1 == 0 && cmd.cmd2 == 4) { - if (cmd.cmd3 == 0x44c) { // テキストスキップ開始 - status_mask = Status(SKIPMASK | status_mask); - cmd.clear(); - } else if (cmd.cmd3 == 0x3e8) { // ウィンドウ消去 - status_mask = Status(CLEARSCR_MASK | status_mask); - cmd.clear(); - } - } else if (cmd.cmd1 == 1 && cmd.cmd2 == 0x04) { + if (cmd.cmd1 == 1 && cmd.cmd2 == 4) { /* ウェイト関連命令 */ - if (cmd.cmd3 == 0x64 || cmd.cmd3 == 0x6f || cmd.cmd3 == 0x79) { - eprintf("wait %dmsec\n",cmd.args[0].value); - if (cmd.cmd3 == 0x64 && text) { - /* 0x64 だと文字描画中の待ちに使うことがある */ - text->StartText(text_stream); - text->wid->Flush(); - } - if (cmd.cmd3 == 0x6f || cmd.cmd3 == 0x79) wait_time = base_time + cmd.args[0].value; - else wait_time = old_time + cmd.args[0].value; - status = WAIT; - cmd.cmd_type = CMD_WAITFRAMEUPDATE; // 画像描画に戻る(skip時にテキストが描画されやすくするため) - } else if (cmd.cmd3 == 0x65 || cmd.cmd3 == 0x70) { + if (cmd.cmd3 == 0x65 || cmd.cmd3 == 0x70) { eprintf("wait %dmsec(click stop)\n",cmd.args[0].value); if (cmd.cmd3 == 0x70) wait_time = base_time + cmd.args[0].value; else wait_time = old_time + cmd.args[0].value; @@ -1374,7 +1037,7 @@ else fprintf(stderr,"AUTO %d,%d <- wait } extern int print_blit; -bool TextImpl::Wait(unsigned int current_time, Cmd& cmd) { +bool Text::Wait(unsigned int current_time, Cmd& cmd) { if (current_time != Event::Time::NEVER_WAKE) old_time = current_time; /* if (event.presscount(MOUSE_UP)) { @@ -1560,40 +1223,40 @@ print_blit^=1; void clearbtn_press(void* pointer, WidButton* button) { if (pointer == NULL) return; - TextImpl* t = (TextImpl*)pointer; - t->status_mask = TextImpl::Status(t->status_mask | TextImpl::CLEARSCR_MASK); - return; + Text* t = (Text*)pointer; + t->status_mask = Text::Status(t->status_mask | Text::CLEARSCR_MASK); } -void TextImpl::PressFuncSkip(void* pointer, WidButton* from) { + +void Text::PressFuncSkip(void* pointer, WidButton* from) { if (pointer == NULL) return; - TextImpl* t = (TextImpl*)pointer; - t->status_mask = TextImpl::Status(t->status_mask | TextImpl::SKIPMASK); - return; -} -void TextImpl::PressFuncLoad(void* pointer, WidButton* from) { - if (pointer == NULL) return; - TextImpl* t = (TextImpl*)pointer; - t->status_mask = TextImpl::Status(t->status_mask | TextImpl::LOADMASK); + Text* t = (Text*)pointer; + t->status_mask = Text::Status(t->status_mask | Text::SKIPMASK); return; } -void TextImpl::PressFuncSave(void* pointer, WidButton* from) { +void Text::PressFuncLoad(void* pointer, WidButton* from) { if (pointer == NULL) return; - TextImpl* t = (TextImpl*)pointer; - t->status_mask = TextImpl::Status(t->status_mask | TextImpl::SAVEMASK); - return; + Text* t = (Text*)pointer; + t->status_mask = Text::Status(t->status_mask | Text::LOADMASK); } -void TextImpl::PressFuncBacklog(void* pointer, WidButton* from) { + +void Text::PressFuncSave(void* pointer, WidButton* from) { if (pointer == NULL) return; - TextImpl* t = (TextImpl*)pointer; - t->status_mask = TextImpl::Status(t->status_mask | TextImpl::BACKLOG_MASK); - return; + Text* t = (Text*)pointer; + t->status_mask = Text::Status(t->status_mask | Text::SAVEMASK); } -void TextImpl::PressFuncBacklogFwd(void* pointer, WidButton* from) { + +void Text::PressFuncBacklog(void* pointer, WidButton* from) { if (pointer == NULL) return; - TextImpl* t = (TextImpl*)pointer; - t->status_mask = TextImpl::Status(t->status_mask | TextImpl::BACKLOG_MASK_FWD); - return; + Text* t = (Text*)pointer; + t->status_mask = Text::Status(t->status_mask | Text::BACKLOG_MASK); } + +void Text::PressFuncBacklogFwd(void* pointer, WidButton* from) { + if (pointer == NULL) return; + Text* t = (Text*)pointer; + t->status_mask = Text::Status(t->status_mask | Text::BACKLOG_MASK_FWD); +} + void movebtn_drag(int from_x, int from_y, int x, int y, void* pointer, WidButton* button) { if (pointer == NULL) return; fprintf(stderr,"drag.\n"); @@ -1619,14 +1282,14 @@ static int btnpos[BTNCNT] = { // g00 ファイル内のボタン情報の位置 }; static WidButton::PressFunc btnpress[BTNCNT] = { - 0, clearbtn_press, &TextImpl::PressFuncSkip,0,&TextImpl::PressFuncBacklogFwd,&TextImpl::PressFuncBacklog,&TextImpl::PressFuncBacklogFwd,&TextImpl::PressFuncSave,&TextImpl::PressFuncLoad,0 + 0, clearbtn_press, &Text::PressFuncSkip,0,&Text::PressFuncBacklogFwd,&Text::PressFuncBacklog,&Text::PressFuncBacklogFwd,&Text::PressFuncSave,&Text::PressFuncLoad,0 }; static WidButton::DragFunc btndrag[BTNCNT] = { movebtn_drag, 0,0,0,0, 0,0,0,0, 0 }; -void TextImpl::SetTextSpeed(int speed) { +void Text::SetTextSpeed(int speed) { // 100 : 10char / sec // 10 : 100char / sec // text widget: @@ -1638,13 +1301,13 @@ void TextImpl::SetTextSpeed(int speed) { if (widgets[i]) widgets[i]->wid->SetSpeed(speed); } -void TextImpl::SetTextWait(int wait) { +void Text::SetTextWait(int wait) { int i; for (i=0; i<32; i++) if (widgets[i]) widgets[i]->wid->SetWait(wait); } -void TextImpl::SetWindowColor(int r, int g, int b, int a, bool is_transparent) { +void Text::SetWindowColor(int r, int g, int b, int a, bool is_transparent) { char key[1024]; int w; @@ -1668,7 +1331,7 @@ void TextImpl::SetWindowColor(int r, int } } -void TextImpl::SetCursor(int cursor_no) { +void Text::SetCursor(int cursor_no) { char key[1024]; sprintf(key, "#CURSOR.%03d.NAME", cursor_no); string path = config->GetParaStr(key); @@ -1773,59 +1436,6 @@ string kconv_rev(const string& s) { /**************************************************************:: ** -** Text -*/ -Text::Text(Event::Container& _event, PicContainer& _parent) { - pimpl = new TextImpl(_event, _parent, backlog, backlog_item); -} - -Text::~Text() { - delete pimpl; - pimpl = NULL; -} - -void Text::InitWindow(void) { - pimpl->InitWindow(); -} - -void Text::Exec(Cmd& cmd) { - pimpl->Exec(cmd); -} - -bool Text::Wait(unsigned int current_time, Cmd& cmd) { - return pimpl->Wait(current_time, cmd); -} - -void Text::SetSkipMode(SkipMode mode) { - pimpl->SetSkipMode(mode); -} - -void Text::Save(std::string& str, bool select_save) { - pimpl->Save(str, select_save); -} - -void Text::Load(const char* str) { - pimpl->Load(str); -} - -void Text::hide(void) { - pimpl->hide(); -} - -void Text::show(void) { - pimpl->show(); -} - -void Text::show(int num) { - pimpl->show(num); -} - -void Text::DrawBacklog(BacklogItem& item, Cmd& cmd) { - pimpl->DrawBacklog(item, cmd); -} - -/**************************************************************:: -** ** BacklogItem */ @@ -1872,6 +1482,12 @@ void BacklogItem::SetSavepos(int p) { pos = p; } + +/**************************************************************:: +** +** TextWindow +*/ + Rect TextWindow::WakuSize(PicContainer& pic, int waku_no) { char key[1024]; sprintf(key, "#WAKU.%03d.000.NAME", waku_no); @@ -2075,42 +1691,144 @@ TextWindow::TextWindow(PicContainer& par MakeWaku(*wid->PicNode(), event,waku_no, win_no, use_btn, callback); } -void TextImpl::InitWindow(void) { +TextWindow::~TextWindow() +{ + if (name_container != NULL) { + delete name_container; + name_container = NULL; + } int i; - int w; - std::string str; + for (i=0; i<8; i++) { + if (face_pics[i] != NULL) { + delete face_pics[i]; + face_pics[i] = NULL; + } + } + if (wid != NULL) { + delete wid; + wid = NULL; + } +} + +void TextWindow::show(void) +{ + wid->show(); + if (name_container != NULL && name_visible) + name_container->show(); + if (face != NULL) + face->show(); +} - for (w=0; w<32; w++) { - widgets[w] = new TextWindow(parent, event, w, (void*)this); - if (widgets[w]->wid == 0) { - delete widgets[w]; - widgets[w] = NULL; +void TextWindow::hide(void) +{ + wid->hide(); + if (name_container != NULL) + name_container->hide(); + if (face != NULL) + face->hide(); +} + +void TextWindow::ShowFace(const char* path) +{ + if (face == NULL) + return; + face->SetSurface(path, 0, 0); +} + +void TextWindow::ResetFace(void) { + if (face == NULL) + return; + face->SetSurface((Surface*) NULL, 0, 0); +} + +void TextWindow::StartText(const TextStream& _stream) +{ + wid->Clear(); + wid->stream = _stream; + if (name_container != NULL) { + char namestr[1024]; + namestr[0] = 0; + wid->stream.RemoveName(namestr, 1024); + if (namestr[0] == 0) { + name_container->hide(); + } + else { + if (name != NULL) { + name_container->show_all(); + name->SetText(namestr); + } } } - SetCursor(0); - for (i=0; i<26; i++) { - char buf[1024]; - sprintf(buf, "#NAME.%c", i+'A'); - const char* s = config->GetParaStr(buf); - if (s != NULL) replace_name[i] = s; + wid->Start(); +} + +void TextWindow::SetName(const char* n) +{ + if (name_container != NULL && name != NULL) { + if (n[0]) { + name_container->show(); + name->SetText(n); + name_visible = true; + } + else { + name_container->hide(); + name_visible = false; + } + } +} + +/**************************************************************:: +** +** SaveFaceHash +*/ + +void SaveFaceHash::NewNode(string face, int face_id) +{ + facetonum[face] = face_id; + container.push_front(Node(face, face_id)); + if (container.size() > size_max) { + Node remove = container.back(); + container.pop_back(); + facetonum.erase(remove.first); } - // replace_name2 : 初期設定 - // 渚、秋生、渚 (CLANNAD) - char name_nagisa[3] = {'\x8f', '\x8d', '\0'}; - char name_akio[5] = {'\x8f', '\x48', '\x90', '\xb6', '\0'}; - replace_name2[0] = name_nagisa; - replace_name2[1] = name_akio; - replace_name2[2] = name_nagisa; - text = NULL; - /* テキスト速度の設定 */ - int speed, mod, wait, auto_mod; - config->GetParam("#INIT_MESSAGE_SPEED", 1, &speed); - config->GetParam("#INIT_MESSAGE_SPEED_MOD", 1, &mod); - config->GetParam("#MESSAGE_KEY_WAIT_USE", 1, &auto_mod); - config->GetParam("#MESSAGE_KEY_WAIT_TIME", 1, &wait); - if (mod) speed = -1; - if (!auto_mod) wait = -1; - SetTextSpeed(speed); - SetTextWait(wait); - return; } + +int SaveFaceHash::Add(string face) +{ + int id; + int ret = -1; + int i; + List::iterator it; + if (face.empty()) return -1; + if (facetonum.find(face) == facetonum.end()) { + id = ++id_max; + NewNode(face, id); + ret = -1; + } + else { + id = facetonum[face]; + for (i=0, it=container.begin(); it != container.end(); i++, it++) { + if (it->second == id) { + ret = i; + Node n = *it; + container.erase(it); + container.push_front(n); + break; + } + } + } + return ret; +} + +string SaveFaceHash::Get(int num) { + if (num < 0) return ""; + List::iterator it = container.begin(); + for (; it != container.end(); it++) { + if (num == 0) return it->first; + num--; + } + return ""; +} + +int SaveFaceHash::size_max = 20; +