1 #include "list.h"
2
3 #include "core/array.h"
4
5 #define SMALL_SIZE_STEP 500
6 #define LARGE_SIZE_STEP 2000
7 #define BURNING_SIZE_STEP 500
8
9 static struct {
10 array(int) small;
11 array(int) large;
12 array(int) burning;
13 } data;
14
building_list_small_clear(void)15 void building_list_small_clear(void)
16 {
17 data.small.size = 0;
18 }
19
building_list_small_add(int building_id)20 void building_list_small_add(int building_id)
21 {
22 if (!data.small.blocks && !array_init(data.small, SMALL_SIZE_STEP, 0, 0)) {
23 return;
24 }
25 int *element = array_advance(data.small);
26 if (!element) {
27 element = array_last(data.small);
28 }
29 *element = building_id;
30 }
31
building_list_small_size(void)32 int building_list_small_size(void)
33 {
34 return data.small.size;
35 }
36
building_list_small_item(int index)37 int building_list_small_item(int index)
38 {
39 return *array_item(data.small, index);
40 }
41
building_list_large_clear(void)42 void building_list_large_clear(void)
43 {
44 data.large.size = 0;
45 }
46
building_list_large_add(int building_id)47 void building_list_large_add(int building_id)
48 {
49 if (!data.large.blocks && !array_init(data.large, LARGE_SIZE_STEP, 0, 0)) {
50 return;
51 }
52 int *element = array_advance(data.large);
53 if (!element) {
54 element = array_last(data.large);
55 }
56 *element = building_id;
57 }
58
building_list_large_size(void)59 int building_list_large_size(void)
60 {
61 return data.large.size;
62 }
63
building_list_large_item(int index)64 int building_list_large_item(int index)
65 {
66 return *array_item(data.large, index);
67 }
68
building_list_burning_clear(void)69 void building_list_burning_clear(void)
70 {
71 data.burning.size = 0;
72 }
73
building_list_burning_add(int building_id)74 void building_list_burning_add(int building_id)
75 {
76 if (!data.burning.blocks && !array_init(data.burning, BURNING_SIZE_STEP, 0, 0)) {
77 return;
78 }
79 int *element = array_advance(data.burning);
80 if (!element) {
81 element = array_last(data.burning);
82 }
83 *element = building_id;
84 }
85
building_list_burning_size(void)86 int building_list_burning_size(void)
87 {
88 return data.burning.size;
89 }
90
building_list_burning_item(int index)91 int building_list_burning_item(int index)
92 {
93 return *array_item(data.burning, index);
94 }
95
building_list_save_state(buffer * small,buffer * large,buffer * burning,buffer * burning_totals)96 void building_list_save_state(buffer *small, buffer *large, buffer *burning, buffer *burning_totals)
97 {
98 int buf_size = data.small.size * sizeof(int32_t);
99 int *value;
100 if (buf_size) {
101 uint8_t *buf_data = malloc(buf_size);
102 buffer_init(small, buf_data, buf_size);
103 array_foreach(data.small, value)
104 {
105 buffer_write_i32(small, *value);
106 }
107 }
108
109 buf_size = data.large.size * sizeof(int32_t);
110 if (buf_size) {
111 uint8_t *buf_data = malloc(buf_size);
112 buffer_init(large, buf_data, buf_size);
113 array_foreach(data.large, value)
114 {
115 buffer_write_i32(large, *value);
116 }
117 }
118
119 buf_size = data.burning.size * sizeof(int32_t);
120 if (buf_size) {
121 uint8_t *buf_data = malloc(buf_size);
122 buffer_init(burning, buf_data, buf_size);
123 array_foreach(data.burning, value)
124 {
125 buffer_write_i32(burning, *value);
126 }
127 }
128
129 buffer_write_i32(burning_totals, data.burning.size);
130 }
131
building_list_load_state(buffer * small,buffer * large,buffer * burning,buffer * burning_totals,int is_new_version)132 void building_list_load_state(buffer *small, buffer *large, buffer *burning, buffer *burning_totals, int is_new_version)
133 {
134 data.small.size = 0;
135 data.large.size = 0;
136 data.burning.size = 0;
137
138 if (!is_new_version) {
139 int size = small->size / sizeof(int16_t);
140 for (int i = 0; i < size; i++) {
141 building_list_small_add(buffer_read_i16(small));
142 }
143 size = large->size / sizeof(int16_t);
144 for (int i = 0; i < size; i++) {
145 building_list_large_add(buffer_read_i16(large));
146 }
147 size = burning->size / sizeof(int16_t);
148 for (int i = 0; i < size; i++) {
149 building_list_burning_add(buffer_read_i16(burning));
150 }
151
152 buffer_skip(burning_totals, 4);
153 } else {
154 int size = small->size / sizeof(int32_t);
155 for (int i = 0; i < size; i++) {
156 building_list_small_add(buffer_read_i32(small));
157 }
158 size = large->size / sizeof(int32_t);
159 for (int i = 0; i < size; i++) {
160 building_list_large_add(buffer_read_i32(large));
161 }
162 size = burning->size / sizeof(int32_t);
163 for (int i = 0; i < size; i++) {
164 building_list_burning_add(buffer_read_i32(burning));
165 }
166 }
167 data.small.size = 0;
168 data.large.size = 0;
169 data.burning.size = buffer_read_i32(burning_totals);
170 }
171