MS-DOS: some optimizations for tile handling

* In both the 16 color and the VESA mode, the tileset image is loaded
      and split into individual tiles; the tiles are then processed into a
      form that is compatible with the video mode in use. For 16 color mode,
      a tile is processed each time it is displayed, leading to slow
      redrawing. For VESA mode, each tile is processed at startup, leading
      to long startup times. Both modes are changed so that the tile is
      processed once, when it is first displayed, and the result is cached.

    * Use memcpy when splitting the image into tiles.

    * Only load the tileset once. In 16 color mode, for reasons I do not
      understand, the gr_init function is called twice, leading to delay
      in startup. This does not happen in VESA mode.
This commit is contained in:
Ray Chason
2026-07-04 13:43:23 -04:00
parent 7c418cff6a
commit af79ad629c
3 changed files with 143 additions and 60 deletions
+13 -11
View File
@@ -30,6 +30,9 @@ read_tiles(const char *filename, boolean true_color)
char header[16];
boolean ok;
if (tiles != NULL)
return;
/* Fill the image structure with known values */
image.width = 0;
image.height = 0;
@@ -283,7 +286,7 @@ split_tiles(const struct TileSetImage *image)
{
unsigned tile_rows, tile_cols;
size_t tile_size, i, j;
unsigned x1, y1, x2, y2;
unsigned x1, y1, y2;
/* Get the number of tiles */
tile_rows = image->height / iflags.wc_tile_height;
@@ -308,16 +311,15 @@ split_tiles(const struct TileSetImage *image)
tile->indexes = (unsigned char *) alloc(tile_size);
}
for (y2 = 0; y2 < (unsigned) iflags.wc_tile_height; ++y2) {
for (x2 = 0; x2 < (unsigned) iflags.wc_tile_width; ++x2) {
unsigned x = x1 * iflags.wc_tile_width + x2;
unsigned y = y1 * iflags.wc_tile_height + y2;
i = y * image->width + x;
j = y2 * tile->width + x2;
tile->pixels[j] = image->pixels[i];
if (image->indexes != NULL) {
tile->indexes[j] = image->indexes[i];
}
unsigned y = y1 * iflags.wc_tile_height + y2;
unsigned x = x1 * iflags.wc_tile_width;
i = y * image->width;
j = y2 * tile->width;
memcpy(tile->pixels + j, image->pixels + i + x,
sizeof(tile->pixels[0]) * iflags.wc_tile_width);
if (image->indexes != NULL) {
memcpy(tile->indexes + j, image->indexes + i + x,
iflags.wc_tile_width);
}
}
}