OSDN Git Service

ソースの文字コードと改行コードを修正
[coroid/inqubus.git] / vhook / chat / chat_slot.c
1 #include "chat.h"
2 #include "chat_slot.h"
3 #include "process_chat.h"
4 #include "../mydef.h"
5 #include "../comment/com_surface.h"
6 #include "../nicodef.h"
7 #include "../util.h"
8 #include <SDL/SDL.h>
9 #include <stdio.h>
10 #include <string.h>
11
12 int initChatSlot(FILE* log,CHAT_SLOT* slot,int max_slot,CHAT* chat){
13         slot->max_item=max_slot;
14         slot->chat = chat;
15         slot->item = malloc(sizeof(CHAT_SLOT_ITEM) * max_slot);
16         if(slot->item == NULL){
17                 fputs("failed to malloc for comment slot.\n",log);
18                 return FALSE;
19         }
20         int i;
21         CHAT_SLOT_ITEM* item;
22         for(i=0;i<max_slot;i++){
23                 item = &slot->item[i];
24                 item->used = FALSE;
25                 item->slot = slot;
26                 item->surf=NULL;
27         }
28         return TRUE;
29 }
30 void closeChatSlot(CHAT_SLOT* slot){
31         int i;
32         CHAT_SLOT_ITEM* item;
33         for(i=0;i<slot->max_item;i++){
34                 item = &slot->item[i];
35                 SDL_FreeSurface(item->surf);
36         }
37         //アイテムを消去。
38         free(slot->item);
39 }
40
41 void deleteChatSlot(CHAT_SLOT* slot,CHAT_SLOT_ITEM* item){
42         item->chat_item=NULL;
43         SDL_FreeSurface(item->surf);
44         item->surf = NULL;
45         item->used = FALSE;
46 }
47
48 void deleteChatSlotFromIndex(CHAT_SLOT* slot,int index){
49         CHAT_SLOT_ITEM* item = &slot->item[index];
50         deleteChatSlot(slot,item);
51 }
52
53 /*
54  * スロットに追加する。
55  */
56 void addChatSlot(COMMDATA* data,CHAT_SLOT* slot,CHAT_ITEM* item,int video_width,int video_height){
57         //もう見せられた。
58         item->showed = TRUE;
59         if(slot->max_item <= 0){
60                 return;
61         }
62         SDL_Surface* surf = makeCommentSurface(data,item,video_width,video_height);
63         /*開きスロットル検索*/
64         int i;
65         int cnt = -1;
66         int slot_max = slot->max_item;
67         for(i=0;i<slot_max;i++){
68                 if(!slot->item[i].used){
69                         cnt = i;
70                         break;
71                 }
72                 if(cnt < 0 || slot->item[cnt].chat_item->vend > slot->item[i].chat_item->vend){
73                         cnt = i;
74                 }
75         }
76         CHAT_SLOT_ITEM* slot_item = &slot->item[cnt];
77         /*空きが無ければ強制的に作る。*/
78         if(slot_item->used){
79                 deleteChatSlotFromIndex(slot,cnt);
80         }
81         //この時点で追加
82         slot_item->chat_item = item;
83         slot_item->surf = surf;
84         /*ロケーションで分岐*/
85         int y;
86         if(item->location == CMD_LOC_BOTTOM){
87                 y = video_height - surf->h;
88         }else{
89                 y = 0;
90         }
91         int running;
92         do{
93                 running = FALSE;
94                 for(i=0;i<slot_max;i++){
95                         CHAT_SLOT_ITEM* other_slot = &slot->item[i];
96                         if(!other_slot->used){
97                                 continue;
98                         }
99                         const CHAT_ITEM* other_item = other_slot->chat_item;
100                         int other_y = other_slot->y;
101                         /*無視する条件*/
102                         if(other_y + other_slot->surf->h <= y){
103                                 continue;
104                         }
105                         if(y + surf->h <= other_y){
106                                 continue;
107                         }
108                         if(other_item->location != item->location){
109                                 continue;
110                         }
111                         int start = MAX(other_item->vstart,item->vstart);
112                         int end = MIN(other_item->vend,item->vend);
113                         int obj_x_t1 = getX(start,slot_item,video_width);
114                         int obj_x_t2 = getX(end,slot_item,video_width);
115                         int o_x_t1 = getX(start,other_slot,video_width);
116                         int o_x_t2 = getX(end,other_slot,video_width);
117                         //当たり判定
118                         if ((obj_x_t1 <= o_x_t1 + other_slot->surf->w && o_x_t1 <= obj_x_t1 + surf->w)
119                 || (obj_x_t2 <= o_x_t2 + other_slot->surf->w && o_x_t2 <= obj_x_t2 + surf->w)){
120                                 if(item->location == CMD_LOC_BOTTOM){
121                                         y = other_y - surf->h - 1;
122                                 }else{
123                                         y = other_y + other_slot->surf->h + 1;
124                                 }
125                                 running = TRUE;
126                                 break;
127                         }
128                 }
129         }while(running);
130         /*そもそも画面内に無ければ無意味。*/
131         if(y < 0 || y+surf->h > video_height){//範囲を超えてるので、ランダムに配置。
132                 y = ((rnd() & 0xffff) * (video_height - surf->h)) / 0xffff;
133         }
134         //追加
135         slot_item->used = TRUE;
136         slot_item->y = y;
137 }
138 /*
139  * イテレータをリセットする。
140  */
141 void resetChatSlotIterator(CHAT_SLOT* slot){
142         slot->iterator_index = 0;
143 }
144 /*
145  * イテレータを得る
146  */
147 CHAT_SLOT_ITEM* getChatSlotErased(CHAT_SLOT* slot,int now_vpos){
148         int *i = &slot->iterator_index;
149         int max_item = slot->max_item;
150         CHAT_ITEM* item;
151         CHAT_SLOT_ITEM* slot_item;
152         for(;*i<max_item;(*i)++){
153                 slot_item = &slot->item[*i];
154                 if(!slot_item->used){
155                         continue;
156                 }
157                 item = slot_item->chat_item;
158                 if(item==NULL)continue;
159                 if(now_vpos < item->vstart || now_vpos > item->vend){
160                         return slot_item;
161                 }
162         }
163         return NULL;
164 }