1 Current task: 2D scrolling tile engine
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!
5 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!
6 3. Tile size: 16x16, 256 bytes (0.25K) per tile
7 4. Total amount of tiles used: n/a
8 5. Total amount of tiles stored in memory at a time: 256 (64K) //reduce to 128 or less if there's not enough memory
10 //31K for sprites which is about 124 sprites!
11 //there is 3 pages advalible for us that are 75K each!
13 Tiles are rendered as a background. Background needs to be scrolled from up to down and from left to right.
15 Tiles currently used are stored in the video memory. World, consisting of tiles, is represented as a matrix.
16 World is split into areas. Changing area means changing used tileset. Tiles in two neighbouring areas should not overlap.
17 Viewport matrix holds 20x15 to 21x16 tiles at once. As we only have 256 tiles in our set, each tile is one byte long.
19 The best variant to change matrix contents FAST seems to be 2D linked list. The downside is memory lookup time.
20 An alternative is a 2D array. Fast lookup, less memory, expensive relocation.
24 #define TILES_X = NTILES_X - 1
25 #define TILES_Y = NTILES_Y - 1
29 struct vp_node *right;
34 uint8_t offset_x; //X offset in pixels
35 uint8_t offset_y; //Y offset in pixels
36 uint16_t world_offset_x;
37 uint16_t world_offset_y;
38 struct vp_node *upper_left; //pointer to the upper left tile
40 void initvp(struct viewport *vp, uint8_t **world_matrix, uint16_t offset_x, uint16_t offset_y) {
42 struct vp_node *vp_tmp[NTILES_Y][NTILES_X]; //i'd like to copy it
43 for(i=0; i<NTILES_Y; i++) {
44 for(j=0; j<NTILES_X; j++) {
45 vp_tmp[i][j] = malloc(sizeof(struct vp_node));
46 vp_tmp[i][j]->tile = world_matrix[offset_x + i][offset_y + j];
49 // i for line, j for column
50 // linking neighbouring tiles
51 // wait, do we need links to left and up?
52 for(i=0; i<NTILES_Y; i++) {
53 for(j=0; j<NTILES_X; j++) {
54 if(i) vp_tmp[i][j]->up = vp_tmp[i-1][j];
55 else vp_tmp[i][j]->up = NULL;
56 if(j) vp_tmp[i][j]->left = vp_tmp[i][j-1];
57 else vp_tmp[i][j]->left = NULL;
58 if(i<20) vp_tmp[i][j]->down = vp_tmp[i+1][j];
59 else vp_tmp[i][j]->down = NULL;
60 if(j<15) vp_tmp[i][j]->right = vp_tmp[i][j+1];
61 else vp_tmp[i][j]->right = NULL;
64 vp = malloc(sizeof(struct viewport));
67 vp->world_offset_x = offset_x;
68 vp->world_offset_y = offset_y;
69 vp->upper_left = vp_tmp[0][0];
71 void scroll(struct viewport *vp, uint8_t **world_matrix, int8_t offset_x, int8_t offset_y) {
72 int8_t offset_x_total = offset_x + vp->offset_x;
73 int8_t offset_y_total = offset_y + vp->offset_y;
74 if(offset_x_total > 15) shift_right(vp, world_matrix);
75 if(offset_x_total < 0) shift_left(vp, world_matrix);
76 if(offset_y_total > 15) shift_down(vp, world_matrix);
77 if(offset_y_total < 0) shift_up(vp, world_matrix);
78 vp->offset_x = offset_x_total % 16;
79 vp->offset_y = offset_y_total % 16;
81 void shift_right(struct viewport *vp, uint8_t **world_matrix) {
82 vp->world_offset_x += 1;
83 struct vp_node *tmp = vp->upper_left;
84 vp->upper_left = vp->upper_left->right;
86 tmp->right->left = NULL;
90 tmp->right->left = NULL;
92 // Starting from the upper left corner
94 // Looking up the rightmost tile
95 while(tmp->right) tmp = tmp->right;
96 // Here and below: allocating and linking new neighbouring tiles
98 tmp->right = malloc(sizeof(struct vp_node));
99 tmp->right->tile = world_matrix[vp->world_offset_y + i++][vp->world_offset_x +20];
100 tmp->right->left = tmp;
101 tmp->right->up = NULL;
102 tmp->right->right = NULL;
105 tmp->right = malloc(sizeof(struct vp_node));
106 tmp->right->tile = world_matrix[vp->world_offset_y + i++][vp->world_offset_x + 20];
107 tmp->right->left = tmp;
108 tmp->right->up = tmp->up->right;
109 tmp->up->right->down = tmp->right;
110 tmp->right->right = NULL;
112 tmp->right->down = NULL;
113 // looks like we've just added a column
115 void shift_left(struct viewport *vp, uint8_t **world_matrix) {
116 vp->world_offset_x -= 1;
117 // Removing the rightmost column first
118 struct vp_node *tmp = vp->upper_left;
119 while(tmp->right) tmp = tmp->right;
121 tmp->left->right = NULL;
125 tmp->left->right = NULL;
127 // Now we need to add a new column to the left
128 tmp = vp->upper_left;
129 // Here and below: allocating and linking new neighbouring tiles
131 tmp->left = malloc(sizeof(struct vp_node));
132 tmp->left->tile = world_matrix[vp->world_offset_y + i++][vp->world_offset_x];
133 tmp->left->right = tmp;
134 tmp->left->up = NULL;
135 tmp->left->left = NULL;
138 tmp->left = malloc(sizeof(struct vp_node));
139 tmp->left->tile = world_matrix[vp->world_offset_y + i++][vp->world_offset_x];
140 tmp->left->right = tmp;
141 tmp->left->up = tmp->up->left;
142 tmp->up->left->down = tmp->left;
143 tmp->left->left = NULL;
145 tmp->left->down = NULL;
146 // looks like we've just added a column to the left
148 void shift_down(struct viewport *vp, uint8_t **world_matrix) {
149 vp->world_offset_y += 1;
150 // Removing the upper row first
151 struct vp_node *tmp = vp->upper_left->down;
152 vp->upper_left = tmp;
157 // Now we need to add a new column to the bottom
158 tmp = vp->upper_left;
159 while(tmp->down) tmp = tmp->down;
160 // Here and below: allocating and linking new neighbouring tiles
162 tmp->down = malloc(sizeof(struct vp_node));
163 tmp->dpwn->tile = world_matrix[vp->world_offset_y + i++][vp->world_offset_x];
164 tmp->down->left = NULL;
166 tmp->down->down = NULL;
169 tmp->down = malloc(sizeof(struct vp_node));
170 tmp->down->tile = world_matrix[vp->world_offset_y + i++][vp->world_offset_x];
172 tmp->down->left = tmp->left->down;
173 tmp->left->down->right = tmp->down;
174 tmp->down->down = NULL;
176 tmp->down->right = NULL;
177 // looks like we've just added a row to the bottom
179 void shift_up(struct viewport *vp, uint8_t **world_matrix) {
180 vp->world_offset_y += 1;
181 // Removing the bottom row first
182 struct vp_node *tmp = vp->upper_left;
183 while(tmp->down) tmp = tmp->down;
185 tmp->up->down = NULL;
189 tmp->up->down = NULL;
191 // Now we need to add a new row to the top
192 tmp = vp->upper_left;
193 // Here and below: allocating and linking new neighbouring tiles
195 tmp->up = malloc(sizeof(struct vp_node));
196 tmp->up->tile = world_matrix[vp->world_offset_y + i++][vp->world_offset_x];
197 tmp->up->left = NULL;
202 tmp->up = malloc(sizeof(struct vp_node));
203 tmp->up->tile = world_matrix[vp->world_offset_y + i++][vp->world_offset_x];
205 tmp->up->left = tmp->left->up;
206 tmp->left->up->right = tmp->up;
209 tmp->up->right = NULL;
210 // looks like we've just added a row to the top
212 void render_vp(struct viewport *vp);