Mercurial > otakunoraifu
comparison 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 |
comparison
equal
deleted
inserted
replaced
55:f1a27ee7e03c | 56:c7bcc0ec2267 |
---|---|
7 ・ウェイト終了後、クリアなしに新たなテキストを追加、新たにstart-waitする | 7 ・ウェイト終了後、クリアなしに新たなテキストを追加、新たにstart-waitする |
8 ・文字の描画 (Start) と Wait(カーソル表示待ち)の分離。 | 8 ・文字の描画 (Start) と Wait(カーソル表示待ち)の分離。 |
9 Start すると文字を描画開始する。クリックで全描画。 | 9 Start すると文字を描画開始する。クリックで全描画。 |
10 Flush するとバッファ内の文字をすべて描画する | 10 Flush するとバッファ内の文字をすべて描画する |
11 Wait すると全描画後、クリックされるまでカーソルを表示するまで待つ | 11 Wait すると全描画後、クリックされるまでカーソルを表示するまで待つ |
12 TextImpl 側の状態としては Wait のみを持つ (PREPAREに戻るのを待つ) | 12 Text 側の状態としては Wait のみを持つ (PREPAREに戻るのを待つ) |
13 ただし、Skip の権利はどっちがもつ?(現状は?) | 13 ただし、Skip の権利はどっちがもつ?(現状は?) |
14 | 14 |
15 GrpObj: NextObj と GrpObj を分離。CreateObj は現状通り、Visible=1 時に行う。 | 15 GrpObj: NextObj と GrpObj を分離。CreateObj は現状通り、Visible=1 時に行う。 |
16 それぞれ num=0 (screen) の枝leaf として実装。delete時は親のdeleteのみを | 16 それぞれ num=0 (screen) の枝leaf として実装。delete時は親のdeleteのみを |
17 行い、子はGrpObjの実体だけを削除する | 17 行い、子はGrpObjの実体だけを削除する |
53 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 53 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
54 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | 54 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
55 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 55 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
56 */ | 56 */ |
57 | 57 |
58 #include "window/event.h" | 58 #include "scn2k_text.h" |
59 #include "window/picture.h" | 59 |
60 #include "window/widget.h" | |
61 #include "system/file.h" | 60 #include "system/file.h" |
62 #include "system/system_config.h" | |
63 #include "scn2k.h" | 61 #include "scn2k.h" |
64 | 62 |
65 #include <string> | 63 #include <string> |
66 using namespace std; | 64 using namespace std; |
67 | 65 |
68 // kanji conv : デバッグ表示用 | 66 #include "window/render.h" |
69 void kconv(const unsigned char* src, unsigned char* dest); | |
70 void kconv_rev(const unsigned char* src, unsigned char* dest); | |
71 string kconv(const string& s); | |
72 string kconv_rev(const string& s); | |
73 // render.cc | |
74 void DSurfaceFillA(Surface* src, const Rect& rect, int r, int g, int b, int a); // テキストウィンドウ背景の設定 | |
75 void DSurfaceMove(Surface* src_o, const Rect& srcrect, Surface* dst_o, const Rect& dstrect); // コピー | |
76 | 67 |
77 /**************************************************************:: | 68 /**************************************************************:: |
78 ** | 69 ** |
79 ** TextImpl(interface) | 70 ** Text(implementation) |
80 */ | 71 */ |
81 struct TimerAtom { | 72 Text::Text(Event::Container& _event, PicContainer& _parent) : |
82 int from; | 73 text(0),status(Text::NORMAL), status_saved(Text::NORMAL), status_mask(Text::NORMAL), ruby_text_flag(false), |
83 int to; | |
84 unsigned int start_time; | |
85 unsigned int total_time; | |
86 }; | |
87 | |
88 struct TextWindow { | |
89 /* @@@ : SetWindowColor での surface 再設定に注意 */ | |
90 WidText* wid; | |
91 bool name_visible; | |
92 WidLabel* name; | |
93 PicContainer* name_container; | |
94 PicBase* face; | |
95 PicBase* face_pics[8]; | |
96 TextWindow(PicContainer& parent, Event::Container& event, int window_no, void* callback); | |
97 ~TextWindow() { | |
98 if (name_container != NULL) { | |
99 delete name_container; | |
100 name_container = NULL; | |
101 } | |
102 int i; | |
103 for (i=0; i<8; i++) { | |
104 if (face_pics[i] != NULL) { | |
105 delete face_pics[i]; | |
106 face_pics[i] = NULL; | |
107 } | |
108 } | |
109 if (wid != NULL) { | |
110 delete wid; | |
111 wid = NULL; | |
112 } | |
113 } | |
114 Rect WakuSize(PicContainer& pic, int waku_no); | |
115 void MakeWaku(PicContainer& pic, Event::Container& event, int waku_no,int window_no, bool* use_btn, void* callback); | |
116 void show(void) { | |
117 wid->show(); | |
118 if (name_container && name_visible) name_container->show(); | |
119 if (face) face->show(); | |
120 } | |
121 void hide(void) { | |
122 wid->hide(); | |
123 if (name_container) name_container->hide(); | |
124 if (face) face->hide(); | |
125 } | |
126 void ShowFace(const char* path) { | |
127 if (!face) return; | |
128 face->SetSurface( path, 0,0); | |
129 } | |
130 void ResetFace(void) { | |
131 if (!face) return; | |
132 face->SetSurface( (Surface*)0, 0,0); | |
133 } | |
134 void StartText(const TextStream& _stream) { | |
135 wid->Clear(); | |
136 wid->stream = _stream; | |
137 if (name_container) { | |
138 char namestr[1024]; | |
139 namestr[0] = 0; | |
140 wid->stream.RemoveName(namestr, 1024); | |
141 if (namestr[0] == 0) { | |
142 name_container->hide(); | |
143 } else { | |
144 if (name) { | |
145 name_container->show_all(); | |
146 name->SetText(namestr); | |
147 } | |
148 } | |
149 } | |
150 wid->Start(); | |
151 } | |
152 void SetName(const char* n) { | |
153 if (name_container && name) { | |
154 if (n[0]) { | |
155 name_container->show(); | |
156 name->SetText(n); | |
157 name_visible = true; | |
158 } else { | |
159 name_container->hide(); | |
160 name_visible = false; | |
161 } | |
162 } | |
163 } | |
164 }; | |
165 | |
166 class TextImpl : public CommandHandler { | |
167 public: | |
168 TextImpl(Event::Container& _event, PicContainer& _parent, vector<BacklogItem>& parent_backlog, BacklogItem& parent_backlog_item); | |
169 ~TextImpl(); | |
170 void InitWindow(void); | |
171 void SetWindowColor(int r, int g, int b, int a, bool is_transparent); | |
172 void SetTextSpeed(int new_speed); | |
173 void SetTextWait(int new_wait); | |
174 void CreateSelect(Cmd& cmd); | |
175 void Exec(Cmd& cmd); | |
176 bool Wait(unsigned int current_time, Cmd& cmd); | |
177 void hide(void); | |
178 void show(void) { show(text_window_number); } | |
179 void show(int num); | |
180 void DrawBacklog(BacklogItem& item, Cmd& cmd); | |
181 void Save(std::string& str, bool select_save); | |
182 void Load(const char* str); | |
183 void SetSkipMode(SkipMode _mode); | |
184 void CreateSelBG(void); | |
185 | |
186 void AddText(const char* str); | |
187 | |
188 static void PressFuncSkip(void* pointer, WidButton* from); | |
189 static void PressFuncLoad(void* pointer, WidButton* from); | |
190 static void PressFuncSave(void* pointer, WidButton* from); | |
191 static void PressFuncBacklog(void* pointer, WidButton* from); | |
192 static void PressFuncBacklogFwd(void* pointer, WidButton* from); | |
193 | |
194 private: | |
195 static void PressFuncButton(void* pointer, WidButton* from); | |
196 static bool PressFunc(int x, int y, void* pointer); | |
197 void SetCursor(int num); | |
198 | |
199 public: | |
200 TextWindow* text; | |
201 typedef enum {NORMAL=0, WAIT_TEXT=1, WAIT=2, | |
202 WAIT_CLICK=3, WAIT_ABORT=4, WAIT_CLICK_MOUSEPOS = 5, | |
203 WAIT_CLICK_MOUSEPOSEND_L = 6, WAIT_CLICK_MOUSEPOSEND_R = 7, | |
204 WAIT_SELECT_INBOX = 10, WAIT_SELECT_OUTBOX=11, WAIT_SELECT_VALUE = 12, | |
205 WAIT_EXTRN_MASK = 64, SAVEMASK = 128, LOADMASK = 256, SKIPMASK = 512, | |
206 CLEARSCR_MASK = 1024, STATSAVE_MASK = 2048, CLEARSCR_WAIT_MASK=(1<<12), | |
207 SKIPEND_MASK = (1<<13), BACKLOG_MASK=(1<<14), BACKLOG_MASK_FWD=(1<<15), | |
208 BACKLOG_MASK_KOE=(1<<16), BACKLOG_WAIT_MASK=(1<<17), | |
209 ALLMASK = (CLEARSCR_MASK | WAIT_EXTRN_MASK | SAVEMASK | | |
210 LOADMASK | SKIPMASK | BACKLOG_MASK | BACKLOG_MASK_FWD | | |
211 BACKLOG_MASK_KOE | BACKLOG_WAIT_MASK | STATSAVE_MASK | | |
212 CLEARSCR_WAIT_MASK | SKIPEND_MASK) | |
213 } Status; | |
214 Status status, status_saved, status_mask; | |
215 | |
216 private: | |
217 std::string ruby_text; | |
218 bool ruby_text_flag; | |
219 unsigned int wait_time; | |
220 unsigned int old_time; | |
221 unsigned int base_time; | |
222 int text_window_number; | |
223 bool text_parsing; | |
224 TextStream text_stream; | |
225 SkipMode skip_mode; | |
226 int save_selectcount; | |
227 | |
228 std::map<int, TimerAtom> timer_var; | |
229 std::vector<WidTextButton*> selects; | |
230 std::vector<int> sel_backlog_pos; | |
231 string replace_name[26]; | |
232 string replace_name2[26]; | |
233 PicContainer* sel_widget; | |
234 PicWidget* backlog_widget; | |
235 | |
236 vector<BacklogItem>& backlog; | |
237 BacklogItem& backlog_item; | |
238 BacklogItem cur_backlog_item; | |
239 BacklogItem drawn_backlog_item; | |
240 | |
241 TextWindow* widgets[32]; | |
242 WidTimeCursor* kcursor; | |
243 Surface* sel_bg1; | |
244 Surface* sel_bg2; | |
245 Rect sel_bg_rect; | |
246 | |
247 VarInfo wait_savedvar[2]; | |
248 | |
249 AyuSysConfig *config; | |
250 | |
251 Event::Container& event; | |
252 PicContainer& parent; | |
253 | |
254 //Opcode handling | |
255 void impl_txtClear(Cmd& cmd); | |
256 void impl_logKoe(Cmd& cmd); | |
257 void impl_pause(Cmd& cmd); | |
258 void impl_br(Cmd& cmd); | |
259 void impl_FaceOpen(Cmd& cmd); | |
260 void impl_FaceClear(Cmd& cmd); | |
261 }; | |
262 | |
263 /**************************************************************:: | |
264 ** | |
265 ** TextImpl(implementation) | |
266 */ | |
267 TextImpl::TextImpl(Event::Container& _event, PicContainer& _parent, vector<BacklogItem>& parent_backlog, BacklogItem& parent_backlog_item) : | |
268 text(0),status(TextImpl::NORMAL), status_saved(TextImpl::NORMAL), status_mask(TextImpl::NORMAL), ruby_text_flag(false), | |
269 old_time(0), base_time(0), text_window_number(0), text_parsing(false), skip_mode(SKIP_NO), save_selectcount(0), sel_widget(0), | 74 old_time(0), base_time(0), text_window_number(0), text_parsing(false), skip_mode(SKIP_NO), save_selectcount(0), sel_widget(0), |
270 backlog_widget(0), backlog(parent_backlog), backlog_item(parent_backlog_item), parent(_parent), event(_event), | 75 backlog_widget(0), parent(_parent), event(_event), |
271 kcursor(0), sel_bg1(0), sel_bg2(0), sel_bg_rect(0,0,0,0) { | 76 kcursor(0), sel_bg1(0), sel_bg2(0), sel_bg_rect(0,0,0,0) { |
272 config = AyuSysConfig::GetInstance(); | 77 config = AyuSysConfig::GetInstance(); |
273 int i; | 78 int i; |
274 for (i=0; i<32; i++) { | 79 for (i=0; i<32; i++) { |
275 widgets[i] = 0; | 80 widgets[i] = 0; |
276 } | 81 } |
277 text_stream.kanji_type = TextStream::sjis; | 82 text_stream.kanji_type = TextStream::sjis; |
278 event.RegisterGlobalPressFunc(&PressFunc, (void*)this); | 83 event.RegisterGlobalPressFunc(&PressFunc, (void*)this); |
279 | 84 |
280 RegisterCommand(1, 33, 73, "grpOpenBg", (CmdImpl) &TextImpl::impl_txtClear); | 85 RegisterCommand(1, 33, 73, "grpOpenBg", (CmdImpl) &Text::impl_txtClear); |
281 RegisterCommand(1, 33, 75, "grpMulti", (CmdImpl) &TextImpl::impl_txtClear); | 86 RegisterCommand(1, 33, 75, "grpMulti", (CmdImpl) &Text::impl_txtClear); |
282 RegisterCommand(1, 33, 76, "grpOpen", (CmdImpl) &TextImpl::impl_txtClear); | 87 RegisterCommand(1, 33, 76, "grpOpen", (CmdImpl) &Text::impl_txtClear); |
283 | 88 |
284 RegisterCommand(1, 23, 0, "koePlay", (CmdImpl) &TextImpl::impl_logKoe); | 89 RegisterCommand(1, 23, 0, "koePlay", (CmdImpl) &Text::impl_logKoe); |
285 RegisterCommand(1, 23, 8, "koeDoPlay", (CmdImpl) &TextImpl::impl_logKoe); | 90 RegisterCommand(1, 23, 8, "koeDoPlay", (CmdImpl) &Text::impl_logKoe); |
286 | 91 |
287 RegisterCommand(0, 3, 151, "msgHide", (CmdImpl) &TextImpl::impl_txtClear); | 92 RegisterCommand(0, 3, 151, "msgHide", (CmdImpl) &Text::impl_txtClear); |
288 RegisterCommand(0, 3, 17, "pause", (CmdImpl) &TextImpl::impl_pause); | 93 RegisterCommand(0, 3, 17, "pause", (CmdImpl) &Text::impl_pause); |
289 RegisterCommand(0, 3, 3, "par", (CmdImpl) &TextImpl::impl_br); //FIXME | 94 RegisterCommand(0, 3, 3, "par", (CmdImpl) &Text::impl_br); //FIXME |
290 RegisterCommand(0, 3, 201, "br", (CmdImpl) &TextImpl::impl_br); | 95 RegisterCommand(0, 3, 201, "br", (CmdImpl) &Text::impl_br); |
291 RegisterCommand(0, 3, 1000, "FaceOpen", (CmdImpl) &TextImpl::impl_FaceOpen); | 96 RegisterCommand(0, 3, 1000, "FaceOpen", (CmdImpl) &Text::impl_FaceOpen); |
292 RegisterCommand(0, 3, 1001, "FaceClear", (CmdImpl) &TextImpl::impl_FaceClear); | 97 RegisterCommand(0, 3, 1001, "FaceClear", (CmdImpl) &Text::impl_FaceClear); |
293 } | 98 RegisterCommand(0, 3, 120, "__doruby", (CmdImpl) &Text::impl_doRuby); //FIXME: I don't know how it works |
294 | 99 RegisterCommand(0, 3, 102, "TextWindow", (CmdImpl) &Text::impl_TextWindow); |
295 TextImpl::~TextImpl() { | 100 RegisterCommand(0, 3, 103, "FastText", NULL);//FIXME: (CmdImpl) &Text::impl_FastText); |
296 if (sel_widget) delete sel_widget; | 101 RegisterCommand(0, 3, 104, "NormalText", NULL); |
102 RegisterCommand(0, 3, 152, "msgClear", (CmdImpl) &Text::impl_msgClear); | |
103 | |
104 RegisterCommand(0, 2, 1, "select", (CmdImpl) &Text::impl_createSelect); | |
105 RegisterCommand(0, 2, 3, "select2?", (CmdImpl) &Text::impl_createSelect); //What difference with select? | |
106 | |
107 RegisterCommand(0, 4, 1000, "ShowBackground", (CmdImpl) &Text::impl_ShowBackground); | |
108 RegisterCommand(0, 4, 1100, "SetSkipMode", (CmdImpl) &Text::impl_SetSkipMode); | |
109 RegisterCommand(1, 4, 100, "wait", (CmdImpl) &Text::impl_Wait); | |
110 RegisterCommand(1, 4, 111, "time", (CmdImpl) &Text::impl_Wait); | |
111 RegisterCommand(1, 4, 121, "timeEx", (CmdImpl) &Text::impl_Wait); | |
112 } | |
113 | |
114 Text::~Text() { | |
115 if (sel_widget != NULL) | |
116 delete sel_widget; | |
297 int i; | 117 int i; |
298 for (i=0; i<32; i++) { | 118 for (i=0; i<32; i++) { |
299 if (widgets[i]) delete widgets[i]; | 119 if (widgets[i] != NULL) |
300 } | 120 delete widgets[i]; |
301 if (backlog_widget) delete backlog_widget; | 121 } |
302 if (sel_bg1) parent.Root().DeleteSurface(sel_bg1); | 122 if (backlog_widget != NULL) |
303 if (sel_bg2) parent.Root().DeleteSurface(sel_bg2); | 123 delete backlog_widget; |
124 if (sel_bg1 != NULL) | |
125 parent.Root().DeleteSurface(sel_bg1); | |
126 if (sel_bg2 != NULL) | |
127 parent.Root().DeleteSurface(sel_bg2); | |
304 event.DeleteGlobalPressFunc(&PressFunc, (void*)this); | 128 event.DeleteGlobalPressFunc(&PressFunc, (void*)this); |
305 } | 129 } |
306 | 130 |
307 bool TextImpl::PressFunc(int x, int y, void* pointer) { | 131 bool Text::PressFunc(int x, int y, void* pointer) { |
308 TextImpl* t = (TextImpl*)pointer; | 132 Text* t = (Text*)pointer; |
309 if (t->status == WAIT_CLICK) { | 133 if (t->status == WAIT_CLICK) { |
310 t->status = WAIT_ABORT; | 134 t->status = WAIT_ABORT; |
311 } else if (t->status == WAIT_CLICK_MOUSEPOS) { | 135 } else if (t->status == WAIT_CLICK_MOUSEPOS) { |
312 t->status = WAIT_CLICK_MOUSEPOSEND_L; | 136 t->status = WAIT_CLICK_MOUSEPOSEND_L; |
313 } else if (t->status_mask & CLEARSCR_WAIT_MASK) { | 137 } else if (t->status_mask & CLEARSCR_WAIT_MASK) { |
326 else if (t->status == WAIT_SELECT_VALUE) ; | 150 else if (t->status == WAIT_SELECT_VALUE) ; |
327 else t->status_mask = Status(t->status_mask | SKIPEND_MASK); | 151 else t->status_mask = Status(t->status_mask | SKIPEND_MASK); |
328 } | 152 } |
329 return true; // event not deleted | 153 return true; // event not deleted |
330 } | 154 } |
331 void TextImpl::PressFuncButton(void* pointer, WidButton* from) { | 155 |
332 TextImpl* t = (TextImpl*)pointer; | 156 void Text::PressFuncButton(void* pointer, WidButton* from) { |
157 Text* t = (Text*)pointer; | |
333 if (t->status != WAIT_SELECT_INBOX && t->status != WAIT_SELECT_OUTBOX) return; | 158 if (t->status != WAIT_SELECT_INBOX && t->status != WAIT_SELECT_OUTBOX) return; |
334 vector<WidTextButton*>::iterator it; | 159 vector<WidTextButton*>::iterator it; |
335 int sel = 0; | 160 int sel = 0; |
336 for (it=t->selects.begin(); it != t->selects.end(); it++, sel++) { | 161 for (it=t->selects.begin(); it != t->selects.end(); it++, sel++) { |
337 if (from == *it) break; | 162 if (from == *it) break; |
338 } | 163 } |
339 if (it == t->selects.end()) { | 164 if (it == t->selects.end()) { |
340 fprintf(stderr,"TextImpl::PressFuncButton: Cannot find select widget\n"); | 165 fprintf(stderr,"Text::PressFuncButton: Cannot find select widget\n"); |
341 return; | 166 return; |
342 } | 167 } |
343 t->status = Status(WAIT_SELECT_VALUE + sel); | 168 t->status = Status(WAIT_SELECT_VALUE + sel); |
344 return; | 169 } |
345 } | 170 |
346 | 171 void Text::SetSkipMode(SkipMode _mode) { |
347 void TextImpl::SetSkipMode(SkipMode _mode) { | |
348 if ( (skip_mode & SKIP_IN_MENU) && (_mode & SKIP_IN_MENU) == 0) { | 172 if ( (skip_mode & SKIP_IN_MENU) && (_mode & SKIP_IN_MENU) == 0) { |
349 if (status_mask & BACKLOG_WAIT_MASK) { // backlog mode から復帰 | 173 if (status_mask & BACKLOG_WAIT_MASK) { // backlog mode から復帰 |
350 status_mask = Status(status_mask & (~(BACKLOG_MASK|BACKLOG_MASK_FWD|BACKLOG_MASK_KOE|BACKLOG_WAIT_MASK))); | 174 status_mask = Status(status_mask & (~(BACKLOG_MASK|BACKLOG_MASK_FWD|BACKLOG_MASK_KOE|BACKLOG_WAIT_MASK))); |
351 text->wid->Clear(); | 175 text->wid->Clear(); |
352 if (status == WAIT_TEXT && text != NULL) { | 176 if (status == WAIT_TEXT && text != NULL) { |
373 if (backlog_widget) backlog_widget->hide(); | 197 if (backlog_widget) backlog_widget->hide(); |
374 } | 198 } |
375 skip_mode = _mode; | 199 skip_mode = _mode; |
376 } | 200 } |
377 | 201 |
378 /* hash_map が欲しい……*/ | 202 void Text::InitWindow(void) { |
379 #include <map> | 203 int i; |
380 #include <list> | 204 int w; |
381 struct SaveFaceHash { // バックログセーブ時の顔画像管理を行う | 205 std::string str; |
382 map<string, int> facetonum; | 206 |
383 typedef pair<string,int> Node; | 207 for (w=0; w<32; w++) { |
384 typedef list<Node> List; | 208 widgets[w] = new TextWindow(parent, event, w, (void*)this); |
385 List container; | 209 if (widgets[w]->wid == 0) { |
386 int id_max; | 210 delete widgets[w]; |
387 static int size_max; | 211 widgets[w] = NULL; |
388 SaveFaceHash() : id_max(0) { | 212 } |
389 } | 213 } |
390 void NewNode(string face, int face_id) { | 214 SetCursor(0); |
391 facetonum[face] = face_id; | 215 for (i=0; i<26; i++) { |
392 container.push_front(Node(face, face_id)); | 216 char buf[1024]; |
393 if (container.size() > size_max) { | 217 sprintf(buf, "#NAME.%c", i+'A'); |
394 Node remove = container.back(); | 218 const char* s = config->GetParaStr(buf); |
395 container.pop_back(); | 219 if (s != NULL) replace_name[i] = s; |
396 facetonum.erase(remove.first); | 220 } |
397 } | 221 // replace_name2 : 初期設定 |
398 } | 222 // 渚、秋生、渚 (CLANNAD) |
399 int Add(string face) { | 223 char name_nagisa[3] = {'\x8f', '\x8d', '\0'}; |
400 int id; int ret = -1; | 224 char name_akio[5] = {'\x8f', '\x48', '\x90', '\xb6', '\0'}; |
401 int i; List::iterator it; | 225 replace_name2[0] = name_nagisa; |
402 if (face.empty()) return -1; | 226 replace_name2[1] = name_akio; |
403 if (facetonum.find(face) == facetonum.end()) { | 227 replace_name2[2] = name_nagisa; |
404 id = ++id_max; | 228 text = NULL; |
405 NewNode(face, id); | 229 /* テキスト速度の設定 */ |
406 ret = -1; | 230 int speed, mod, wait, auto_mod; |
407 } else { | 231 config->GetParam("#INIT_MESSAGE_SPEED", 1, &speed); |
408 id = facetonum[face]; | 232 config->GetParam("#INIT_MESSAGE_SPEED_MOD", 1, &mod); |
409 for (i=0, it=container.begin(); it != container.end(); i++, it++) { | 233 config->GetParam("#MESSAGE_KEY_WAIT_USE", 1, &auto_mod); |
410 if (it->second == id) { | 234 config->GetParam("#MESSAGE_KEY_WAIT_TIME", 1, &wait); |
411 ret = i; | 235 if (mod) speed = -1; |
412 Node n = *it; | 236 if (!auto_mod) wait = -1; |
413 container.erase(it); | 237 SetTextSpeed(speed); |
414 container.push_front(n); | 238 SetTextWait(wait); |
415 break; | 239 } |
416 } | 240 |
417 } | 241 void Text::Save(string& str, bool rollback_save) { |
418 } | |
419 return ret; | |
420 } | |
421 string Get(int num) { | |
422 if (num < 0) return ""; | |
423 List::iterator it = container.begin(); | |
424 for (; it != container.end(); it++) { | |
425 if (num == 0) return it->first; | |
426 num--; | |
427 } | |
428 return ""; | |
429 } | |
430 }; | |
431 | |
432 int SaveFaceHash::size_max = 20; | |
433 | |
434 void TextImpl::Save(string& str, bool rollback_save) { | |
435 char buf[1024]; | 242 char buf[1024]; |
436 str = "\n"; | 243 str = "\n"; |
437 str += "[TextImpl Window]\n"; | 244 str += "[Text Window]\n"; |
438 sprintf(buf, "TextImplWindow=%d\n",text_window_number); | 245 sprintf(buf, "TextWindow=%d\n",text_window_number); |
439 str += buf; | 246 str += buf; |
440 if (rollback_save) { | 247 if (rollback_save) { |
441 ++save_selectcount; | 248 ++save_selectcount; |
442 BacklogItem save_item; | 249 BacklogItem save_item; |
443 save_item.SetSavepos(save_selectcount); | 250 save_item.SetSavepos(save_selectcount); |
456 vector<BacklogItem>::iterator it; | 263 vector<BacklogItem>::iterator it; |
457 it = backlog.begin(); | 264 it = backlog.begin(); |
458 if (!rollback_save) { | 265 if (!rollback_save) { |
459 SaveFaceHash face_log; | 266 SaveFaceHash face_log; |
460 do { | 267 do { |
461 int cur_scn = -1; int cur_pos = -1; | 268 int cur_scn = -1; int cur_pos = -1; |
462 sprintf(buf, "Backlog.%d=",++cnt); | 269 sprintf(buf, "Backlog.%d=",++cnt); |
463 str += buf; | 270 str += buf; |
464 for (; it != backlog.end(); it++) { | 271 for (; it != backlog.end(); it++) { |
465 buf[0] = 0; int buflen = 0; | 272 buf[0] = 0; |
466 if (it->scn == -1) continue; | 273 int buflen = 0; |
467 if (it->pos == -1 && it->scn != 0) continue; | 274 if (it->scn == -1) |
468 | 275 continue; |
469 buf[buflen++] = ';'; | 276 if (it->pos == -1 && it->scn != 0) |
470 if (it->scn == 0 && it->pos == -1) { | 277 continue; |
471 buflen += snprintf(buf+buflen, 1000-buflen, "\"%s\".", it->text.Save().c_str()); | 278 |
472 } else { | 279 buf[buflen++] = ';'; |
473 if (cur_scn != -1 && cur_scn != it->scn) break; // scn change | 280 if (it->scn == 0 && it->pos == -1) |
474 if (cur_pos != -1 && cur_pos/5000 != it->pos/5000) break; // pos exceeded | 281 buflen += snprintf(buf+buflen, 1000-buflen, "\"%s\".", it->text.Save().c_str()); |
475 if (!it->text.container.empty()) { | 282 else { |
476 buflen += snprintf(buf+buflen, 1000-buflen, "\"%s\"", it->text.Save().c_str()); | 283 if (cur_scn != -1 && cur_scn != it->scn) break; // scn change |
284 if (cur_pos != -1 && cur_pos/5000 != it->pos/5000) break; // pos exceeded | |
285 if (!it->text.container.empty()) { | |
286 buflen += snprintf(buf+buflen, 1000-buflen, "\"%s\"", it->text.Save().c_str()); | |
287 } | |
288 if (cur_scn == -1) { // scene change | |
289 buflen += snprintf(buf+buflen, 1000-buflen, ":%d:%d",it->scn,it->pos); | |
290 cur_scn = it->scn; | |
291 } | |
292 else | |
293 buflen += snprintf(buf+buflen, 1000-buflen, "%d",it->pos); | |
294 cur_pos = it->pos; | |
477 } | 295 } |
478 if (cur_scn == -1) { // scene change | 296 if (it->koe != -1) |
479 buflen += snprintf(buf+buflen, 1000-buflen, ":%d:%d",it->scn,it->pos); | 297 buflen += snprintf(buf+buflen, 1000-buflen, ",%d",it->koe); |
480 cur_scn = it->scn; | 298 if (!it->face.empty()) { |
481 } else { | 299 if (it->koe == -1) buf[buflen++] = ','; |
482 buflen += snprintf(buf+buflen, 1000-buflen, "%d",it->pos); | 300 int face_num = face_log.Add(it->face); |
301 if (face_num >= 0 && face_num < 20) | |
302 buflen += snprintf(buf+buflen, 1000-buflen, ",%c", 'A'+face_num); | |
303 else | |
304 buflen += snprintf(buf+buflen, 1000-buflen, ",\"%s\"", it->face.c_str()); | |
483 } | 305 } |
484 cur_pos = it->pos; | 306 buf[buflen++] = '\0'; |
485 } | 307 if (buflen >= 1000) { // 万が一、バックログ1アイテムの大きさが 1000byte を越えるとき |
486 if (it->koe != -1) | 308 fprintf(stderr,"Fatal : Cannot save backlog crrectly; Please send bug report to the author.\n"); |
487 buflen += snprintf(buf+buflen, 1000-buflen, ",%d",it->koe); | 309 } else str += buf; |
488 if (!it->face.empty()) { | 310 } |
489 if (it->koe == -1) buf[buflen++] = ','; | 311 str += "\n"; |
490 int face_num = face_log.Add(it->face); | 312 } while(it != backlog.end()); |
491 if (face_num >= 0 && face_num < 20) | 313 } |
492 buflen += snprintf(buf+buflen, 1000-buflen, ",%c", 'A'+face_num); | 314 } |
493 else | 315 |
494 buflen += snprintf(buf+buflen, 1000-buflen, ",\"%s\"", it->face.c_str()); | 316 void Text::Load(const char* str) { |
495 } | |
496 buf[buflen++] = '\0'; | |
497 if (buflen >= 1000) { // 万が一、バックログ1アイテムの大きさが 1000byte を越えるとき | |
498 fprintf(stderr,"Fatal : Cannot save backlog crrectly; Please send bug report to the author.\n"); | |
499 } else str += buf; | |
500 } | |
501 str += "\n"; | |
502 } while(it != backlog.end()); | |
503 } | |
504 return; | |
505 } | |
506 | |
507 void TextImpl::Load(const char* str) { | |
508 if (text) text->wid->Clear(); | 317 if (text) text->wid->Clear(); |
509 hide(); | 318 hide(); |
510 text_window_number = 0; | 319 text_window_number = 0; |
511 save_selectcount = 0; | 320 save_selectcount = 0; |
512 if (sel_widget != NULL) { | 321 if (sel_widget != NULL) { |
528 vector<BacklogItem> new_backlog; | 337 vector<BacklogItem> new_backlog; |
529 backlog_item.Clear(); | 338 backlog_item.Clear(); |
530 cur_backlog_item.Clear(); | 339 cur_backlog_item.Clear(); |
531 drawn_backlog_item.Clear(); | 340 drawn_backlog_item.Clear(); |
532 | 341 |
533 str = strstr(str, "\n[TextImpl Window]\n"); | 342 str = strstr(str, "\n[Text Window]\n"); |
534 | 343 |
535 if (str) { | 344 if (str) { |
536 SaveFaceHash face_log; | 345 SaveFaceHash face_log; |
537 str += strlen("\n[TextImpl Window]\n"); | 346 str += strlen("\n[Text Window]\n"); |
538 const char* strend = str; | 347 const char* strend = str; |
539 do { | 348 do { |
540 str = strend; | 349 str = strend; |
541 | 350 |
542 strend = strchr(str, '\n'); | 351 strend = strchr(str, '\n'); |
543 if (strend == NULL) strend = str + strlen(str); | 352 if (strend == NULL) strend = str + strlen(str); |
544 else strend++; | 353 else strend++; |
545 | 354 |
546 if (str[0] == '[') break; // next section | 355 if (str[0] == '[') break; // next section |
547 if (strncmp(str, "TextImplWindow=",15) == 0) { | 356 if (strncmp(str, "TextWindow=",15) == 0) { |
548 str += 15; | 357 str += 15; |
549 sscanf(str, "%d", &text_window_number); | 358 sscanf(str, "%d", &text_window_number); |
550 } else if (strncmp(str, "SaveSelectCount=",16) == 0) { | 359 } else if (strncmp(str, "SaveSelectCount=",16) == 0) { |
551 str += 16; | 360 str += 16; |
552 sscanf(str, "%d", &save_selectcount); | 361 sscanf(str, "%d", &save_selectcount); |
630 backlog.swap(new_backlog); | 439 backlog.swap(new_backlog); |
631 } | 440 } |
632 // backlog.clear(); | 441 // backlog.clear(); |
633 } | 442 } |
634 | 443 |
635 void TextImpl::hide(void) { | 444 void Text::hide(void) { |
636 if (text) text->hide(); | 445 if (text) text->hide(); |
637 if (kcursor) kcursor->hide(); | 446 if (kcursor) kcursor->hide(); |
638 text = NULL; | 447 text = NULL; |
639 } | 448 } |
640 void TextImpl::show(int num) { | 449 void Text::show(int num) { |
641 if (num != text_window_number) { | 450 if (num != text_window_number) { |
642 hide(); | 451 hide(); |
643 if (num >= 0 && num < 32 && widgets[num] != 0) { | 452 if (num >= 0 && num < 32 && widgets[num] != 0) { |
644 text_window_number = num; | 453 text_window_number = num; |
645 } | 454 } |
658 ky += 8; | 467 ky += 8; |
659 kcursor->Pic()->Move(kx, ky); | 468 kcursor->Pic()->Move(kx, ky); |
660 } | 469 } |
661 } | 470 } |
662 | 471 |
663 void TextImpl::DrawBacklog(BacklogItem& item, Cmd& cmd) { | 472 void Text::DrawBacklog(BacklogItem& item, Cmd& cmd) { |
664 show(); | 473 show(); |
665 text->wid->deactivate(); | 474 text->wid->deactivate(); |
666 status_mask = Status(status_mask | BACKLOG_WAIT_MASK); | 475 status_mask = Status(status_mask | BACKLOG_WAIT_MASK); |
667 drawn_backlog_item = item; | 476 drawn_backlog_item = item; |
668 if (item.text.container.empty()) { | 477 if (item.text.container.empty()) { |
679 if (item.face.empty()) text->ResetFace(); | 488 if (item.face.empty()) text->ResetFace(); |
680 else text->ShowFace(item.face.c_str()); | 489 else text->ShowFace(item.face.c_str()); |
681 if (kcursor) kcursor->hide(); | 490 if (kcursor) kcursor->hide(); |
682 } | 491 } |
683 | 492 |
684 void TextImpl::CreateSelBG(void) { | 493 void Text::CreateSelBG(void) { |
685 if (sel_bg1 != NULL || sel_bg2 != NULL) return; | 494 if (sel_bg1 != NULL || sel_bg2 != NULL) return; |
686 | 495 |
687 const char* btnfile1 = config->GetParaStr("#SELBTN.000.NAME"); | 496 const char* btnfile1 = config->GetParaStr("#SELBTN.000.NAME"); |
688 const char* btnfile2 = config->GetParaStr("#SELBTN.000.BACK"); | 497 const char* btnfile2 = config->GetParaStr("#SELBTN.000.BACK"); |
689 char path[1024]; | 498 char path[1024]; |
702 sel_bg_rect = Rect(0,0,0,0); | 511 sel_bg_rect = Rect(0,0,0,0); |
703 if (sel_bg1) sel_bg_rect.join(Rect(*sel_bg1)); | 512 if (sel_bg1) sel_bg_rect.join(Rect(*sel_bg1)); |
704 if (sel_bg2) sel_bg_rect.join(Rect(*sel_bg2)); | 513 if (sel_bg2) sel_bg_rect.join(Rect(*sel_bg2)); |
705 } | 514 } |
706 | 515 |
707 void TextImpl::CreateSelect(Cmd& cmd) { | 516 void Text::CreateSelect(Cmd& cmd) { |
708 char key[1024]; | 517 char key[23]; |
709 sprintf(key, "#WINDOW.%03d.SELCOM_USE",text_window_number); | 518 sprintf(key, "#WINDOW.%03d.SELCOM_USE",text_window_number); |
710 int sel_type = 0; | 519 int sel_type = 0; |
711 if (cmd.cmd3 == 1) config->GetParam(key, 1, &sel_type); | 520 if (cmd.cmd3 == 1) config->GetParam(key, 1, &sel_type); |
712 else if (cmd.cmd3 == 3) sel_type = 0; | 521 else if (cmd.cmd3 == 3) sel_type = 0; |
713 | 522 |
823 sel_widget->show_all(); | 632 sel_widget->show_all(); |
824 status = WAIT_SELECT_INBOX; | 633 status = WAIT_SELECT_INBOX; |
825 } | 634 } |
826 } | 635 } |
827 | 636 |
828 void TextImpl::AddText(const char* str_o) { | 637 void Text::AddText(const char* str_o) { |
829 char str[10001]; | 638 char str[10001]; |
830 if (text == NULL) return; | 639 if (text == NULL) return; |
831 /* まず、replace string を変換 */ | 640 /* まず、replace string を変換 */ |
832 int i; | 641 int i; |
833 int cnt = 0; | 642 int cnt = 0; |
888 } else if (*s < 0 && s[1] != 0) s++; | 697 } else if (*s < 0 && s[1] != 0) s++; |
889 } | 698 } |
890 text_stream.Add(str_top); | 699 text_stream.Add(str_top); |
891 } | 700 } |
892 | 701 |
893 void TextImpl::impl_txtClear(Cmd& cmd) { | 702 void Text::Exec(Cmd& cmd) { |
894 if (text != NULL) { | |
895 text->ResetFace(); | |
896 if (cmd.cmd2 == 3 && cmd.cmd3 == 151) | |
897 text->wid->Clear(); | |
898 } | |
899 cur_backlog_item.face = ""; | |
900 if (cmd.cmd2 == 3 && cmd.cmd3 == 151) | |
901 text_stream.Clear(); | |
902 hide(); | |
903 } | |
904 | |
905 void TextImpl::impl_logKoe(Cmd& cmd) { | |
906 // PlayKoe ; 声出力コマンドをチェックする */ | |
907 cur_backlog_item.koe = cmd.args[0].value; | |
908 } | |
909 | |
910 void TextImpl::impl_pause(Cmd& cmd) { | |
911 if (text != NULL) { | |
912 eprintf("start\n"); | |
913 text->StartText(text_stream); | |
914 if (skip_mode & SKIP_TEXT) text->wid->Flush(); | |
915 else if (kcursor) kcursor->show(); | |
916 status = WAIT_TEXT; | |
917 text_parsing = false; | |
918 } | |
919 backlog_item = cur_backlog_item; | |
920 if (cur_backlog_item.scn == 0 && cur_backlog_item.pos == -1) backlog_item.text = text_stream; | |
921 cur_backlog_item.Clear(); | |
922 | |
923 cmd.clear(); | |
924 cmd.cmd_type = CMD_WAITFRAMEUPDATE; // 画像描画に戻る(skip時にテキストが描画されやすくするため) | |
925 } | |
926 | |
927 void TextImpl::impl_br(Cmd& cmd) { | |
928 text_stream.AddReturn(); | |
929 cur_backlog_item.DeleteTextPos(); | |
930 cmd.clear(); | |
931 } | |
932 | |
933 void TextImpl::impl_FaceOpen(Cmd& cmd) { | |
934 if (text == NULL) | |
935 show(); | |
936 string s = cmd.Str(cmd.args[0]); | |
937 s += ".g00"; | |
938 if (text != NULL) | |
939 text->ShowFace(s.c_str()); | |
940 cur_backlog_item.face = s; | |
941 cmd.cmd_type = CMD_SAVECMD_ONCE; | |
942 } | |
943 | |
944 void TextImpl::impl_FaceClear(Cmd& cmd) { | |
945 if (text == NULL) | |
946 show(); | |
947 if (text) | |
948 text->ResetFace(); | |
949 cur_backlog_item.face = ""; | |
950 cmd.cmd_type = CMD_SAVECMD_ONCE; | |
951 } | |
952 | |
953 void TextImpl::Exec(Cmd& cmd) { | |
954 if (cmd.cmd_type == CMD_TEXT) { | 703 if (cmd.cmd_type == CMD_TEXT) { |
955 if (text == NULL) { | 704 if (text == NULL) { |
956 show(); | 705 show(); |
957 } | 706 } |
958 if (cmd.args.size() != 1) return; | 707 if (cmd.args.size() != 1) return; |
977 | 726 |
978 if (cmd.cmd_type != CMD_OTHER) return; | 727 if (cmd.cmd_type != CMD_OTHER) return; |
979 | 728 |
980 CommandHandler::Exec(cmd); | 729 CommandHandler::Exec(cmd); |
981 | 730 |
982 if (cmd.cmd1 == 0 && cmd.cmd2 == 3) { | 731 if (cmd.cmd1 == 1 && cmd.cmd2 == 4) { |
983 if (cmd.cmd3 == 0x78) { // ルビ関連 | |
984 if (text == NULL) { | |
985 show(); | |
986 } | |
987 if (cmd.cmd4 == 1) { | |
988 ruby_text_flag = true; | |
989 eprintf("SetRubyTextImpl."); | |
990 cmd.clear(); | |
991 } else if (cmd.cmd4 == 0) { | |
992 if (ruby_text.length() == 0) { // ルビを振るテキストがない | |
993 eprintf("Cannot find ruby text.\n"); | |
994 return; | |
995 } | |
996 if (cmd.args.size() != 1) return; | |
997 char debug1[1024], debug2[1024]; | |
998 kconv( (unsigned char*)ruby_text.c_str(), (unsigned char*)debug1); | |
999 kconv( (unsigned char*)cmd.Str(cmd.args[0]), (unsigned char*)debug2); | |
1000 eprintf("SetRuby. %s, %s",debug1, debug2); | |
1001 text_stream.AddRuby(ruby_text.c_str(), cmd.Str(cmd.args[0])); | |
1002 cur_backlog_item.DeleteTextPos(); | |
1003 cmd.clear(); | |
1004 } | |
1005 } else if (cmd.cmd3 == 0x66) { // テキストウィンドウの形 | |
1006 if (cmd.cmd4 == 0) { | |
1007 eprintf("set text window <- %d\n",cmd.args[0].value); | |
1008 if (text) show(cmd.args[0].value); | |
1009 else text_window_number = cmd.args[0].value; | |
1010 } else if (cmd.cmd4 == 1) { // default value | |
1011 eprintf("set text window <- default\n"); | |
1012 if (text) show(0); | |
1013 else text_window_number = 0; | |
1014 } | |
1015 cmd.clear(); | |
1016 } else if (cmd.cmd3 == 0x67) { // テキストウィンドウ表示? | |
1017 show(); | |
1018 // 表示の際はテキストをクリアしない? | |
1019 // if (text) text->wid->Clear(); | |
1020 // text_stream.Clear(); | |
1021 cmd.clear(); | |
1022 } else if (cmd.cmd3 == 0x68) { // テキスト表示? | |
1023 // 全テキスト表示 | |
1024 if (text) { | |
1025 text->StartText(text_stream); | |
1026 text->wid->Flush(); | |
1027 } | |
1028 cmd.clear(); | |
1029 } else if (cmd.cmd3 == 0x98) { // テキストウィンドウクリア? | |
1030 show(); | |
1031 if (text) text->wid->Clear(); | |
1032 text_stream.Clear(); | |
1033 cmd.clear(); | |
1034 } | |
1035 } else if (cmd.cmd1 == 0 && cmd.cmd2 == 2 && (cmd.cmd3 == 1 || cmd.cmd3 == 3) && cmd.cmd4 == 0) { | |
1036 // 選択肢 | |
1037 CreateSelect(cmd); | |
1038 //FIXME: Check if it's really clean | |
1039 if (text_parsing) { | |
1040 show(); | |
1041 text->StartText(text_stream); | |
1042 if (skip_mode & SKIP_TEXT) text->wid->Flush(); | |
1043 else if (kcursor) kcursor->hide(); | |
1044 text_parsing = false; | |
1045 text_stream.Clear(); | |
1046 } | |
1047 cmd.cmd_type = CMD_ROLLBACKPOINT; /* 選択肢はセーブ位置 / シナリオ巻き戻し位置 */ | |
1048 // cmd.clear(); | |
1049 } else if (cmd.cmd1 == 0 && cmd.cmd2 == 4) { | |
1050 if (cmd.cmd3 == 0x44c) { // テキストスキップ開始 | |
1051 status_mask = Status(SKIPMASK | status_mask); | |
1052 cmd.clear(); | |
1053 } else if (cmd.cmd3 == 0x3e8) { // ウィンドウ消去 | |
1054 status_mask = Status(CLEARSCR_MASK | status_mask); | |
1055 cmd.clear(); | |
1056 } | |
1057 } else if (cmd.cmd1 == 1 && cmd.cmd2 == 0x04) { | |
1058 /* ウェイト関連命令 */ | 732 /* ウェイト関連命令 */ |
1059 if (cmd.cmd3 == 0x64 || cmd.cmd3 == 0x6f || cmd.cmd3 == 0x79) { | 733 if (cmd.cmd3 == 0x65 || cmd.cmd3 == 0x70) { |
1060 eprintf("wait %dmsec\n",cmd.args[0].value); | |
1061 if (cmd.cmd3 == 0x64 && text) { | |
1062 /* 0x64 だと文字描画中の待ちに使うことがある */ | |
1063 text->StartText(text_stream); | |
1064 text->wid->Flush(); | |
1065 } | |
1066 if (cmd.cmd3 == 0x6f || cmd.cmd3 == 0x79) wait_time = base_time + cmd.args[0].value; | |
1067 else wait_time = old_time + cmd.args[0].value; | |
1068 status = WAIT; | |
1069 cmd.cmd_type = CMD_WAITFRAMEUPDATE; // 画像描画に戻る(skip時にテキストが描画されやすくするため) | |
1070 } else if (cmd.cmd3 == 0x65 || cmd.cmd3 == 0x70) { | |
1071 eprintf("wait %dmsec(click stop)\n",cmd.args[0].value); | 734 eprintf("wait %dmsec(click stop)\n",cmd.args[0].value); |
1072 if (cmd.cmd3 == 0x70) wait_time = base_time + cmd.args[0].value; | 735 if (cmd.cmd3 == 0x70) wait_time = base_time + cmd.args[0].value; |
1073 else wait_time = old_time + cmd.args[0].value; | 736 else wait_time = old_time + cmd.args[0].value; |
1074 status = WAIT_CLICK; | 737 status = WAIT_CLICK; |
1075 cmd.cmd_type = CMD_WAITFRAMEUPDATE; // 画像描画に戻る(skip時にテキストが描画されやすくするため) | 738 cmd.cmd_type = CMD_WAITFRAMEUPDATE; // 画像描画に戻る(skip時にテキストが描画されやすくするため) |
1372 } | 1035 } |
1373 } | 1036 } |
1374 } | 1037 } |
1375 | 1038 |
1376 extern int print_blit; | 1039 extern int print_blit; |
1377 bool TextImpl::Wait(unsigned int current_time, Cmd& cmd) { | 1040 bool Text::Wait(unsigned int current_time, Cmd& cmd) { |
1378 if (current_time != Event::Time::NEVER_WAKE) old_time = current_time; | 1041 if (current_time != Event::Time::NEVER_WAKE) old_time = current_time; |
1379 /* | 1042 /* |
1380 if (event.presscount(MOUSE_UP)) { | 1043 if (event.presscount(MOUSE_UP)) { |
1381 if (text) text->Pic()->ReBlit(); | 1044 if (text) text->Pic()->ReBlit(); |
1382 } | 1045 } |
1558 return false; | 1221 return false; |
1559 } | 1222 } |
1560 | 1223 |
1561 void clearbtn_press(void* pointer, WidButton* button) { | 1224 void clearbtn_press(void* pointer, WidButton* button) { |
1562 if (pointer == NULL) return; | 1225 if (pointer == NULL) return; |
1563 TextImpl* t = (TextImpl*)pointer; | 1226 Text* t = (Text*)pointer; |
1564 t->status_mask = TextImpl::Status(t->status_mask | TextImpl::CLEARSCR_MASK); | 1227 t->status_mask = Text::Status(t->status_mask | Text::CLEARSCR_MASK); |
1228 } | |
1229 | |
1230 void Text::PressFuncSkip(void* pointer, WidButton* from) { | |
1231 if (pointer == NULL) return; | |
1232 Text* t = (Text*)pointer; | |
1233 t->status_mask = Text::Status(t->status_mask | Text::SKIPMASK); | |
1565 return; | 1234 return; |
1566 } | 1235 } |
1567 void TextImpl::PressFuncSkip(void* pointer, WidButton* from) { | 1236 void Text::PressFuncLoad(void* pointer, WidButton* from) { |
1568 if (pointer == NULL) return; | 1237 if (pointer == NULL) return; |
1569 TextImpl* t = (TextImpl*)pointer; | 1238 Text* t = (Text*)pointer; |
1570 t->status_mask = TextImpl::Status(t->status_mask | TextImpl::SKIPMASK); | 1239 t->status_mask = Text::Status(t->status_mask | Text::LOADMASK); |
1571 return; | 1240 } |
1572 } | 1241 |
1573 void TextImpl::PressFuncLoad(void* pointer, WidButton* from) { | 1242 void Text::PressFuncSave(void* pointer, WidButton* from) { |
1574 if (pointer == NULL) return; | 1243 if (pointer == NULL) return; |
1575 TextImpl* t = (TextImpl*)pointer; | 1244 Text* t = (Text*)pointer; |
1576 t->status_mask = TextImpl::Status(t->status_mask | TextImpl::LOADMASK); | 1245 t->status_mask = Text::Status(t->status_mask | Text::SAVEMASK); |
1577 return; | 1246 } |
1578 } | 1247 |
1579 void TextImpl::PressFuncSave(void* pointer, WidButton* from) { | 1248 void Text::PressFuncBacklog(void* pointer, WidButton* from) { |
1580 if (pointer == NULL) return; | 1249 if (pointer == NULL) return; |
1581 TextImpl* t = (TextImpl*)pointer; | 1250 Text* t = (Text*)pointer; |
1582 t->status_mask = TextImpl::Status(t->status_mask | TextImpl::SAVEMASK); | 1251 t->status_mask = Text::Status(t->status_mask | Text::BACKLOG_MASK); |
1583 return; | 1252 } |
1584 } | 1253 |
1585 void TextImpl::PressFuncBacklog(void* pointer, WidButton* from) { | 1254 void Text::PressFuncBacklogFwd(void* pointer, WidButton* from) { |
1586 if (pointer == NULL) return; | 1255 if (pointer == NULL) return; |
1587 TextImpl* t = (TextImpl*)pointer; | 1256 Text* t = (Text*)pointer; |
1588 t->status_mask = TextImpl::Status(t->status_mask | TextImpl::BACKLOG_MASK); | 1257 t->status_mask = Text::Status(t->status_mask | Text::BACKLOG_MASK_FWD); |
1589 return; | 1258 } |
1590 } | 1259 |
1591 void TextImpl::PressFuncBacklogFwd(void* pointer, WidButton* from) { | |
1592 if (pointer == NULL) return; | |
1593 TextImpl* t = (TextImpl*)pointer; | |
1594 t->status_mask = TextImpl::Status(t->status_mask | TextImpl::BACKLOG_MASK_FWD); | |
1595 return; | |
1596 } | |
1597 void movebtn_drag(int from_x, int from_y, int x, int y, void* pointer, WidButton* button) { | 1260 void movebtn_drag(int from_x, int from_y, int x, int y, void* pointer, WidButton* button) { |
1598 if (pointer == NULL) return; | 1261 if (pointer == NULL) return; |
1599 fprintf(stderr,"drag.\n"); | 1262 fprintf(stderr,"drag.\n"); |
1600 } | 1263 } |
1601 | 1264 |
1617 // 0, 1, 13, 12, 2, 3, 4, 5, 6, 7 // princess bride? | 1280 // 0, 1, 13, 12, 2, 3, 4, 5, 6, 7 // princess bride? |
1618 0, 1, 13, 14, 2, 3, 4, 5, 6, 7 // tomoyo after? | 1281 0, 1, 13, 14, 2, 3, 4, 5, 6, 7 // tomoyo after? |
1619 }; | 1282 }; |
1620 | 1283 |
1621 static WidButton::PressFunc btnpress[BTNCNT] = { | 1284 static WidButton::PressFunc btnpress[BTNCNT] = { |
1622 0, clearbtn_press, &TextImpl::PressFuncSkip,0,&TextImpl::PressFuncBacklogFwd,&TextImpl::PressFuncBacklog,&TextImpl::PressFuncBacklogFwd,&TextImpl::PressFuncSave,&TextImpl::PressFuncLoad,0 | 1285 0, clearbtn_press, &Text::PressFuncSkip,0,&Text::PressFuncBacklogFwd,&Text::PressFuncBacklog,&Text::PressFuncBacklogFwd,&Text::PressFuncSave,&Text::PressFuncLoad,0 |
1623 }; | 1286 }; |
1624 | 1287 |
1625 static WidButton::DragFunc btndrag[BTNCNT] = { | 1288 static WidButton::DragFunc btndrag[BTNCNT] = { |
1626 movebtn_drag, 0,0,0,0, 0,0,0,0, 0 | 1289 movebtn_drag, 0,0,0,0, 0,0,0,0, 0 |
1627 }; | 1290 }; |
1628 | 1291 |
1629 void TextImpl::SetTextSpeed(int speed) { | 1292 void Text::SetTextSpeed(int speed) { |
1630 // 100 : 10char / sec | 1293 // 100 : 10char / sec |
1631 // 10 : 100char / sec | 1294 // 10 : 100char / sec |
1632 // text widget: | 1295 // text widget: |
1633 if (speed <= 0) speed = -1; | 1296 if (speed <= 0) speed = -1; |
1634 else if (speed > 1000) speed = 1; | 1297 else if (speed > 1000) speed = 1; |
1636 int i; | 1299 int i; |
1637 for (i=0; i<32; i++) | 1300 for (i=0; i<32; i++) |
1638 if (widgets[i]) widgets[i]->wid->SetSpeed(speed); | 1301 if (widgets[i]) widgets[i]->wid->SetSpeed(speed); |
1639 } | 1302 } |
1640 | 1303 |
1641 void TextImpl::SetTextWait(int wait) { | 1304 void Text::SetTextWait(int wait) { |
1642 int i; | 1305 int i; |
1643 for (i=0; i<32; i++) | 1306 for (i=0; i<32; i++) |
1644 if (widgets[i]) widgets[i]->wid->SetWait(wait); | 1307 if (widgets[i]) widgets[i]->wid->SetWait(wait); |
1645 } | 1308 } |
1646 | 1309 |
1647 void TextImpl::SetWindowColor(int r, int g, int b, int a, bool is_transparent) { | 1310 void Text::SetWindowColor(int r, int g, int b, int a, bool is_transparent) { |
1648 char key[1024]; | 1311 char key[1024]; |
1649 int w; | 1312 int w; |
1650 | 1313 |
1651 for (w=0; w<32; w++) { | 1314 for (w=0; w<32; w++) { |
1652 if (widgets[w] == NULL) continue; | 1315 if (widgets[w] == NULL) continue; |
1666 widgets[w]->wid->Pic()->SetSurfaceAttribute(PicBase::BLIT_MULTIPLY); | 1329 widgets[w]->wid->Pic()->SetSurfaceAttribute(PicBase::BLIT_MULTIPLY); |
1667 parent.Root().DeleteSurface(back_s); | 1330 parent.Root().DeleteSurface(back_s); |
1668 } | 1331 } |
1669 } | 1332 } |
1670 | 1333 |
1671 void TextImpl::SetCursor(int cursor_no) { | 1334 void Text::SetCursor(int cursor_no) { |
1672 char key[1024]; | 1335 char key[1024]; |
1673 sprintf(key, "#CURSOR.%03d.NAME", cursor_no); | 1336 sprintf(key, "#CURSOR.%03d.NAME", cursor_no); |
1674 string path = config->GetParaStr(key); | 1337 string path = config->GetParaStr(key); |
1675 if (path.length() == 0) return; // 名前なし | 1338 if (path.length() == 0) return; // 名前なし |
1676 path += ".pdt"; | 1339 path += ".pdt"; |
1771 return ret; | 1434 return ret; |
1772 } | 1435 } |
1773 | 1436 |
1774 /**************************************************************:: | 1437 /**************************************************************:: |
1775 ** | 1438 ** |
1776 ** Text | |
1777 */ | |
1778 Text::Text(Event::Container& _event, PicContainer& _parent) { | |
1779 pimpl = new TextImpl(_event, _parent, backlog, backlog_item); | |
1780 } | |
1781 | |
1782 Text::~Text() { | |
1783 delete pimpl; | |
1784 pimpl = NULL; | |
1785 } | |
1786 | |
1787 void Text::InitWindow(void) { | |
1788 pimpl->InitWindow(); | |
1789 } | |
1790 | |
1791 void Text::Exec(Cmd& cmd) { | |
1792 pimpl->Exec(cmd); | |
1793 } | |
1794 | |
1795 bool Text::Wait(unsigned int current_time, Cmd& cmd) { | |
1796 return pimpl->Wait(current_time, cmd); | |
1797 } | |
1798 | |
1799 void Text::SetSkipMode(SkipMode mode) { | |
1800 pimpl->SetSkipMode(mode); | |
1801 } | |
1802 | |
1803 void Text::Save(std::string& str, bool select_save) { | |
1804 pimpl->Save(str, select_save); | |
1805 } | |
1806 | |
1807 void Text::Load(const char* str) { | |
1808 pimpl->Load(str); | |
1809 } | |
1810 | |
1811 void Text::hide(void) { | |
1812 pimpl->hide(); | |
1813 } | |
1814 | |
1815 void Text::show(void) { | |
1816 pimpl->show(); | |
1817 } | |
1818 | |
1819 void Text::show(int num) { | |
1820 pimpl->show(num); | |
1821 } | |
1822 | |
1823 void Text::DrawBacklog(BacklogItem& item, Cmd& cmd) { | |
1824 pimpl->DrawBacklog(item, cmd); | |
1825 } | |
1826 | |
1827 /**************************************************************:: | |
1828 ** | |
1829 ** BacklogItem | 1439 ** BacklogItem |
1830 */ | 1440 */ |
1831 | 1441 |
1832 BacklogItem::BacklogItem(void) { | 1442 BacklogItem::BacklogItem(void) { |
1833 scn = -1; | 1443 scn = -1; |
1869 void BacklogItem::SetSavepos(int p) { | 1479 void BacklogItem::SetSavepos(int p) { |
1870 Clear(); | 1480 Clear(); |
1871 scn = SaveSelect; | 1481 scn = SaveSelect; |
1872 pos = p; | 1482 pos = p; |
1873 } | 1483 } |
1484 | |
1485 | |
1486 /**************************************************************:: | |
1487 ** | |
1488 ** TextWindow | |
1489 */ | |
1874 | 1490 |
1875 Rect TextWindow::WakuSize(PicContainer& pic, int waku_no) { | 1491 Rect TextWindow::WakuSize(PicContainer& pic, int waku_no) { |
1876 char key[1024]; | 1492 char key[1024]; |
1877 sprintf(key, "#WAKU.%03d.000.NAME", waku_no); | 1493 sprintf(key, "#WAKU.%03d.000.NAME", waku_no); |
1878 const char* name = AyuSysConfig::GetInstance()->GetParaStr(key); | 1494 const char* name = AyuSysConfig::GetInstance()->GetParaStr(key); |
2073 } | 1689 } |
2074 } | 1690 } |
2075 MakeWaku(*wid->PicNode(), event,waku_no, win_no, use_btn, callback); | 1691 MakeWaku(*wid->PicNode(), event,waku_no, win_no, use_btn, callback); |
2076 } | 1692 } |
2077 | 1693 |
2078 void TextImpl::InitWindow(void) { | 1694 TextWindow::~TextWindow() |
1695 { | |
1696 if (name_container != NULL) { | |
1697 delete name_container; | |
1698 name_container = NULL; | |
1699 } | |
2079 int i; | 1700 int i; |
2080 int w; | 1701 for (i=0; i<8; i++) { |
2081 std::string str; | 1702 if (face_pics[i] != NULL) { |
2082 | 1703 delete face_pics[i]; |
2083 for (w=0; w<32; w++) { | 1704 face_pics[i] = NULL; |
2084 widgets[w] = new TextWindow(parent, event, w, (void*)this); | 1705 } |
2085 if (widgets[w]->wid == 0) { | 1706 } |
2086 delete widgets[w]; | 1707 if (wid != NULL) { |
2087 widgets[w] = NULL; | 1708 delete wid; |
2088 } | 1709 wid = NULL; |
2089 } | 1710 } |
2090 SetCursor(0); | 1711 } |
2091 for (i=0; i<26; i++) { | 1712 |
2092 char buf[1024]; | 1713 void TextWindow::show(void) |
2093 sprintf(buf, "#NAME.%c", i+'A'); | 1714 { |
2094 const char* s = config->GetParaStr(buf); | 1715 wid->show(); |
2095 if (s != NULL) replace_name[i] = s; | 1716 if (name_container != NULL && name_visible) |
2096 } | 1717 name_container->show(); |
2097 // replace_name2 : 初期設定 | 1718 if (face != NULL) |
2098 // 渚、秋生、渚 (CLANNAD) | 1719 face->show(); |
2099 char name_nagisa[3] = {'\x8f', '\x8d', '\0'}; | 1720 } |
2100 char name_akio[5] = {'\x8f', '\x48', '\x90', '\xb6', '\0'}; | 1721 |
2101 replace_name2[0] = name_nagisa; | 1722 void TextWindow::hide(void) |
2102 replace_name2[1] = name_akio; | 1723 { |
2103 replace_name2[2] = name_nagisa; | 1724 wid->hide(); |
2104 text = NULL; | 1725 if (name_container != NULL) |
2105 /* テキスト速度の設定 */ | 1726 name_container->hide(); |
2106 int speed, mod, wait, auto_mod; | 1727 if (face != NULL) |
2107 config->GetParam("#INIT_MESSAGE_SPEED", 1, &speed); | 1728 face->hide(); |
2108 config->GetParam("#INIT_MESSAGE_SPEED_MOD", 1, &mod); | 1729 } |
2109 config->GetParam("#MESSAGE_KEY_WAIT_USE", 1, &auto_mod); | 1730 |
2110 config->GetParam("#MESSAGE_KEY_WAIT_TIME", 1, &wait); | 1731 void TextWindow::ShowFace(const char* path) |
2111 if (mod) speed = -1; | 1732 { |
2112 if (!auto_mod) wait = -1; | 1733 if (face == NULL) |
2113 SetTextSpeed(speed); | 1734 return; |
2114 SetTextWait(wait); | 1735 face->SetSurface(path, 0, 0); |
2115 return; | 1736 } |
2116 } | 1737 |
1738 void TextWindow::ResetFace(void) { | |
1739 if (face == NULL) | |
1740 return; | |
1741 face->SetSurface((Surface*) NULL, 0, 0); | |
1742 } | |
1743 | |
1744 void TextWindow::StartText(const TextStream& _stream) | |
1745 { | |
1746 wid->Clear(); | |
1747 wid->stream = _stream; | |
1748 if (name_container != NULL) { | |
1749 char namestr[1024]; | |
1750 namestr[0] = 0; | |
1751 wid->stream.RemoveName(namestr, 1024); | |
1752 if (namestr[0] == 0) { | |
1753 name_container->hide(); | |
1754 } | |
1755 else { | |
1756 if (name != NULL) { | |
1757 name_container->show_all(); | |
1758 name->SetText(namestr); | |
1759 } | |
1760 } | |
1761 } | |
1762 wid->Start(); | |
1763 } | |
1764 | |
1765 void TextWindow::SetName(const char* n) | |
1766 { | |
1767 if (name_container != NULL && name != NULL) { | |
1768 if (n[0]) { | |
1769 name_container->show(); | |
1770 name->SetText(n); | |
1771 name_visible = true; | |
1772 } | |
1773 else { | |
1774 name_container->hide(); | |
1775 name_visible = false; | |
1776 } | |
1777 } | |
1778 } | |
1779 | |
1780 /**************************************************************:: | |
1781 ** | |
1782 ** SaveFaceHash | |
1783 */ | |
1784 | |
1785 void SaveFaceHash::NewNode(string face, int face_id) | |
1786 { | |
1787 facetonum[face] = face_id; | |
1788 container.push_front(Node(face, face_id)); | |
1789 if (container.size() > size_max) { | |
1790 Node remove = container.back(); | |
1791 container.pop_back(); | |
1792 facetonum.erase(remove.first); | |
1793 } | |
1794 } | |
1795 | |
1796 int SaveFaceHash::Add(string face) | |
1797 { | |
1798 int id; | |
1799 int ret = -1; | |
1800 int i; | |
1801 List::iterator it; | |
1802 if (face.empty()) return -1; | |
1803 if (facetonum.find(face) == facetonum.end()) { | |
1804 id = ++id_max; | |
1805 NewNode(face, id); | |
1806 ret = -1; | |
1807 } | |
1808 else { | |
1809 id = facetonum[face]; | |
1810 for (i=0, it=container.begin(); it != container.end(); i++, it++) { | |
1811 if (it->second == id) { | |
1812 ret = i; | |
1813 Node n = *it; | |
1814 container.erase(it); | |
1815 container.push_front(n); | |
1816 break; | |
1817 } | |
1818 } | |
1819 } | |
1820 return ret; | |
1821 } | |
1822 | |
1823 string SaveFaceHash::Get(int num) { | |
1824 if (num < 0) return ""; | |
1825 List::iterator it = container.begin(); | |
1826 for (; it != container.end(); it++) { | |
1827 if (num == 0) return it->first; | |
1828 num--; | |
1829 } | |
1830 return ""; | |
1831 } | |
1832 | |
1833 int SaveFaceHash::size_max = 20; | |
1834 |