]> 4ch.mooo.com Git - 16.git/blob - doc/project16.txt
what?! OMG!
[16.git] / doc / project16.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
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
9
10 //31K for sprites which is about 124 sprites!
11 //there is 3 pages advalible for us that are 75K each!
12 Task explanation:
13 Tiles are rendered as a background. Background needs to be scrolled from up to down and from left to right.
14
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.
18
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.
21 Something like
22 #define NTILES_X = 21
23 #define NTILES_Y = 16
24 #define TILES_X = NTILES_X - 1
25 #define TILES_Y = NTILES_Y - 1
26 struct vp_node {
27     uint8_t tile;
28     struct vp_node *up;
29     struct vp_node *right;
30     struct vp_node *down;
31     struct vp_node *left;
32 };
33 struct viewport {
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
39 };
40 void initvp(struct viewport *vp, uint8_t **world_matrix, uint16_t offset_x, uint16_t offset_y) {
41     int i, j;
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];
47         }
48     }
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;
62         }
63     }
64     vp = malloc(sizeof(struct viewport));
65     vp->offset_x = 0;
66     vp->offset_y = 0;
67     vp->world_offset_x = offset_x;
68     vp->world_offset_y = offset_y;
69     vp->upper_left = vp_tmp[0][0];
70 }
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;
80 }
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;
85     while(tmp->down) {
86         tmp->right->left = NULL;
87         tmp = tmp->down;
88         free(tmp->up);
89     }
90     tmp->right->left = NULL;
91     free(tmp);
92     // Starting from the upper left corner
93     tmp = vp->upper_left;
94     // Looking up the rightmost tile
95     while(tmp->right) tmp = tmp->right;
96     // Here and below: allocating and linking new neighbouring tiles
97     int i=0;
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;
103     while(tmp->down) {
104         tmp = tmp->down;
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;
111     }
112     tmp->right->down = NULL;
113     // looks like we've just added a column
114 }
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;
120     while(tmp->down) {
121         tmp->left->right = NULL;
122         tmp = tmp->down;
123         free(tmp->up);
124     }
125     tmp->left->right = NULL;
126     free(tmp);
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
130     int i=0;
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;
136     while(tmp->down) {
137         tmp = tmp->down;
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;
144     }
145     tmp->left->down = NULL;
146     // looks like we've just added a column to the left
147 }
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;
153     do {
154         free(tmp->up);
155         tmp->up = NULL;
156     } while(tmp->right);
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
161     int i=0;
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;
165     tmp->down->up = tmp;
166     tmp->down->down = NULL;
167     while(tmp->right) {
168         tmp = tmp->right;
169         tmp->down = malloc(sizeof(struct vp_node));
170         tmp->down->tile = world_matrix[vp->world_offset_y + i++][vp->world_offset_x];
171         tmp->down->up = tmp;
172         tmp->down->left = tmp->left->down;
173         tmp->left->down->right = tmp->down;
174         tmp->down->down = NULL;
175     }
176     tmp->down->right = NULL;
177     // looks like we've just added a row to the bottom
178 }
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;
184     while(tmp->right) {
185         tmp->up->down = NULL;
186         tmp = tmp->right;
187         free(tmp->left);
188     }
189     tmp->up->down = NULL;
190     free(tmp);
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
194     int i=0;
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;
198     tmp->up->down = tmp;
199     tmp->up->up = NULL;
200     while(tmp->right) {
201         tmp = tmp->right;
202         tmp->up = malloc(sizeof(struct vp_node));
203         tmp->up->tile = world_matrix[vp->world_offset_y + i++][vp->world_offset_x];
204         tmp->up->down = tmp;
205         tmp->up->left = tmp->left->up;
206         tmp->left->up->right = tmp->up;
207         tmp->up->up = NULL;
208     }
209     tmp->up->right = NULL;
210     // looks like we've just added a row to the top
211 }
212 void render_vp(struct viewport *vp);
213