]> 4ch.mooo.com Git - 16.git/blob - doc/16.txt
code miraculously works on real hardware
[16.git] / doc / 16.txt
1 Current task: 2D scrolling tile engine
2 Initial conditions:
3 1. Total amount of program memory: This is tricky part because the OS has something called conveance memory and it is limited to 640k but there is may waya around it. using EMS and XMS the game should load a bunch of itself into the areas away from conventional memory as much as possible but if it like my current XT then we are forced to have less than that. I am still building up the official testing enviorment!
4 2. Total amount of video memory: 256K, 320x240 screen, 256 colours //screen is 192K of memory! Only 64K is left free We can use it for buffering and storing game graphics!
5 3. Tile size: 16x16, 256 bytes (0.25K) per tile
6 4. Total amount of tiles used: n/a
7 5. Total amount of tiles stored in memory at a time: 256 (64K) //reduce to 128 or less if there's not enough memory
8 //31K for sprites which is about 124 sprites!
9 //there is 3 pages advalible for us that are 75K each!
10 Task explanation:
11 Tiles are rendered as a background. Background needs to be scrolled from up to down and from left to right.
12 Tiles currently used are stored in the video memory. World, consisting of tiles, is represented as a matrix.
13 World is split into areas. Changing area means changing used tileset. Tiles in two neighbouring areas should not overlap.
14 Viewport matrix holds 20x15 to 21x16 tiles at once. As we only have 256 tiles in our set, each tile is one byte long.
15 The best variant to change matrix contents FAST seems to be 2D linked list. The downside is memory lookup time.
16 An alternative is a 2D array. Fast lookup, less memory, expensive relocation.
17 Something like
18 #define NTILES_X = 21
19 #define NTILES_Y = 16
20 #define TILES_X = NTILES_X - 1
21 #define TILES_Y = NTILES_Y - 1
22 struct vp_node {
23         uint8_t tile;
24         struct vp_node *up;
25         struct vp_node *right;
26         struct vp_node *down;
27         struct vp_node *left;
28 };
29 struct viewport {
30         uint8_t offset_x; //X offset in pixels
31         uint8_t offset_y; //Y offset in pixels
32         uint16_t world_offset_x;
33         uint16_t world_offset_y;
34         struct vp_node *upper_left; //pointer to the upper left tile
35 };
36 void initvp(struct viewport *vp, uint8_t **world_matrix, uint16_t offset_x, uint16_t offset_y) {
37         int i, j;
38         struct vp_node *vp_tmp[NTILES_Y][NTILES_X]; //i'd like to copy it
39         for(i=0; i<NTILES_Y; i++) {
40                 for(j=0; j<NTILES_X; j++) {
41                         vp_tmp[i][j] = malloc(sizeof(struct vp_node));
42                         vp_tmp[i][j]->tile = world_matrix[offset_x + i][offset_y + j];
43                 }
44         }
45         // i for line, j for column
46         // linking neighbouring tiles
47         // wait, do we need links to left and up?
48         for(i=0; i<NTILES_Y; i++) {
49                 for(j=0; j<NTILES_X; j++) {
50                         if(i) vp_tmp[i][j]->up = vp_tmp[i-1][j];
51                         else vp_tmp[i][j]->up = NULL;
52                         if(j) vp_tmp[i][j]->left = vp_tmp[i][j-1];
53                         else vp_tmp[i][j]->left = NULL;
54                         if(i<20) vp_tmp[i][j]->down = vp_tmp[i+1][j];
55                         else vp_tmp[i][j]->down = NULL;
56                         if(j<15) vp_tmp[i][j]->right = vp_tmp[i][j+1];
57                         else vp_tmp[i][j]->right = NULL;
58                 }
59         }
60         vp = malloc(sizeof(struct viewport));
61         vp->offset_x = 0;
62         vp->offset_y = 0;
63         vp->world_offset_x = offset_x;
64         vp->world_offset_y = offset_y;
65         vp->upper_left = vp_tmp[0][0];
66 }
67 void scroll(struct viewport *vp, uint8_t **world_matrix, int8_t offset_x, int8_t offset_y) {
68         int8_t offset_x_total = offset_x + vp->offset_x;
69         int8_t offset_y_total = offset_y + vp->offset_y;
70         if(offset_x_total > 15) shift_right(vp, world_matrix);
71         if(offset_x_total < 0) shift_left(vp, world_matrix);
72         if(offset_y_total > 15) shift_down(vp, world_matrix);
73         if(offset_y_total < 0) shift_up(vp, world_matrix);
74         vp->offset_x = offset_x_total % 16;
75         vp->offset_y = offset_y_total % 16;
76 }
77 void shift_right(struct viewport *vp, uint8_t **world_matrix) {
78         vp->world_offset_x += 1;
79         struct vp_node *tmp = vp->upper_left;
80         vp->upper_left = vp->upper_left->right;
81         while(tmp->down) {
82                 tmp->right->left = NULL;
83                 tmp = tmp->down;
84                 free(tmp->up);
85         }
86         tmp->right->left = NULL;
87         free(tmp);
88         // Starting from the upper left corner
89         tmp = vp->upper_left;
90         // Looking up the rightmost tile
91         while(tmp->right) tmp = tmp->right;
92         // Here and below: allocating and linking new neighbouring tiles
93         int i=0;
94         tmp->right = malloc(sizeof(struct vp_node));
95         tmp->right->tile = world_matrix[vp->world_offset_y + i++][vp->world_offset_x +20];
96         tmp->right->left = tmp;
97         tmp->right->up = NULL;
98         tmp->right->right = NULL;
99         while(tmp->down) {
100                 tmp = tmp->down;
101                 tmp->right = malloc(sizeof(struct vp_node));
102                 tmp->right->tile = world_matrix[vp->world_offset_y + i++][vp->world_offset_x + 20];
103                 tmp->right->left = tmp;
104                 tmp->right->up = tmp->up->right;
105                 tmp->up->right->down = tmp->right;
106                 tmp->right->right = NULL;
107         }
108         tmp->right->down = NULL;
109         // looks like we've just added a column
110 }
111 void shift_left(struct viewport *vp, uint8_t **world_matrix) {
112         vp->world_offset_x -= 1;
113         // Removing the rightmost column first
114         struct vp_node *tmp = vp->upper_left;
115         while(tmp->right) tmp = tmp->right;
116         while(tmp->down) {
117                 tmp->left->right = NULL;
118                 tmp = tmp->down;
119                 free(tmp->up);
120         }
121         tmp->left->right = NULL;
122         free(tmp);
123         // Now we need to add a new column to the left
124         tmp = vp->upper_left;
125         // Here and below: allocating and linking new neighbouring tiles
126         int i=0;
127         tmp->left = malloc(sizeof(struct vp_node));
128         tmp->left->tile = world_matrix[vp->world_offset_y + i++][vp->world_offset_x];
129         tmp->left->right = tmp;
130         tmp->left->up = NULL;
131         tmp->left->left = NULL;
132         while(tmp->down) {
133                 tmp = tmp->down;
134                 tmp->left = malloc(sizeof(struct vp_node));
135                 tmp->left->tile = world_matrix[vp->world_offset_y + i++][vp->world_offset_x];
136                 tmp->left->right = tmp;
137                 tmp->left->up = tmp->up->left;
138                 tmp->up->left->down = tmp->left;
139                 tmp->left->left = NULL;
140         }
141         tmp->left->down = NULL;
142         // looks like we've just added a column to the left
143 }
144 void shift_down(struct viewport *vp, uint8_t **world_matrix) {
145         vp->world_offset_y += 1;
146         // Removing the upper row first
147         struct vp_node *tmp = vp->upper_left->down;
148         vp->upper_left = tmp;
149         do {
150                 free(tmp->up);
151                 tmp->up = NULL;
152         } while(tmp->right);
153         // Now we need to add a new column to the bottom
154         tmp = vp->upper_left;
155         while(tmp->down) tmp = tmp->down;
156         // Here and below: allocating and linking new neighbouring tiles
157         int i=0;
158         tmp->down = malloc(sizeof(struct vp_node));
159         tmp->dpwn->tile = world_matrix[vp->world_offset_y + i++][vp->world_offset_x];
160         tmp->down->left = NULL;
161         tmp->down->up = tmp;
162         tmp->down->down = NULL;
163         while(tmp->right) {
164                 tmp = tmp->right;
165                 tmp->down = malloc(sizeof(struct vp_node));
166                 tmp->down->tile = world_matrix[vp->world_offset_y + i++][vp->world_offset_x];
167                 tmp->down->up = tmp;
168                 tmp->down->left = tmp->left->down;
169                 tmp->left->down->right = tmp->down;
170                 tmp->down->down = NULL;
171         }
172         tmp->down->right = NULL;
173         // looks like we've just added a row to the bottom
174 }
175 void shift_up(struct viewport *vp, uint8_t **world_matrix) {
176         vp->world_offset_y += 1;
177         // Removing the bottom row first
178         struct vp_node *tmp = vp->upper_left;
179         while(tmp->down) tmp = tmp->down;
180         while(tmp->right) {
181                 tmp->up->down = NULL;
182                 tmp = tmp->right;
183                 free(tmp->left);
184         }
185         tmp->up->down = NULL;
186         free(tmp);
187         // Now we need to add a new row to the top
188         tmp = vp->upper_left;
189         // Here and below: allocating and linking new neighbouring tiles
190         int i=0;
191         tmp->up = malloc(sizeof(struct vp_node));
192         tmp->up->tile = world_matrix[vp->world_offset_y + i++][vp->world_offset_x];
193         tmp->up->left = NULL;
194         tmp->up->down = tmp;
195         tmp->up->up = NULL;
196         while(tmp->right) {
197                 tmp = tmp->right;
198                 tmp->up = malloc(sizeof(struct vp_node));
199                 tmp->up->tile = world_matrix[vp->world_offset_y + i++][vp->world_offset_x];
200                 tmp->up->down = tmp;
201                 tmp->up->left = tmp->left->up;
202                 tmp->left->up->right = tmp->up;
203                 tmp->up->up = NULL;
204         }
205         tmp->up->right = NULL;
206         // looks like we've just added a row to the top
207 }
208 void render_vp(struct viewport *vp);
209