ref: 5bddaa7c571d0abf1543fbc9c735bc5054f568ef
parent: 512f850d914cc753359b702d085677715cd94d39
author: Simon Howard <fraggle@soulsphere.org>
date: Tue May 31 15:47:48 EDT 2016
diskicon: Draw disk icon with black background. Vanilla {Doom,Strife} show a black background to the disk icons if the icons are transparent, a side effect of how the disk icon code works (the commented-out version can be found in Heretic's i_ibm.c). To be consistent with how the vanilla code works, don't use V_DrawPatch to draw the loading icon every time, but rather draw it to a buffer on startup and blit the whole disk region to the screen.
--- a/src/v_diskicon.c
+++ b/src/v_diskicon.c
@@ -27,14 +27,18 @@
#include "v_diskicon.h"
+#define DISK_ICON_W 16
+#define DISK_ICON_H 16
+
// Only display the disk icon if more then this much bytes have been read
// during the previous tic.
static const int diskicon_threshold = 20*1024;
-// disk image patch (either STDISK or STCDROM)
-
-static patch_t *disk;
+// Two buffers: disk_data contains the data representing the disk icon
+// (raw, not a patch_t) while saved_background is an equivalently-sized
+// buffer where we save the background data while the disk is on screen.
+static byte *disk_data;
static byte *saved_background;
static int loading_disk_xoffs = 0;
@@ -44,6 +48,47 @@
static size_t recent_bytes_read = 0;
static boolean disk_drawn;
+static void CopyRegion(byte *dest, int dest_pitch,
+ byte *src, int src_pitch,
+ int w, int h)
+{
+ byte *s, *d;
+ int y;
+
+ s = src; d = dest;
+ for (y = 0; y < h; ++y)
+ {
+ memcpy(d, s, w);
+ s += src_pitch;
+ d += dest_pitch;
+ }
+}
+
+static void SaveDiskData(char *disk_lump, int xoffs, int yoffs)
+{
+ byte *tmpscreen;
+ patch_t *disk;
+
+ // Allocate a complete temporary screen where we'll draw the patch.
+ tmpscreen = Z_Malloc(SCREENWIDTH * SCREENHEIGHT, PU_STATIC, NULL);
+ memset(tmpscreen, 0, SCREENWIDTH * SCREENHEIGHT);
+ V_UseBuffer(tmpscreen);
+
+ // Buffer where we'll save the disk data.
+ disk_data = Z_Malloc(DISK_ICON_W * DISK_ICON_H, PU_STATIC, NULL);
+
+ // Draw the patch and save the result to disk_data.
+ disk = W_CacheLumpName(disk_lump, PU_STATIC);
+ V_DrawPatch(loading_disk_xoffs, loading_disk_yoffs, disk);
+ CopyRegion(disk_data, DISK_ICON_W,
+ tmpscreen + yoffs * SCREENWIDTH + xoffs, SCREENWIDTH,
+ DISK_ICON_W, DISK_ICON_H);
+ W_ReleaseLumpName(disk_lump);
+
+ V_RestoreBuffer();
+ Z_Free(tmpscreen);
+}
+
void V_EnableLoadingDisk(int xoffs, int yoffs)
{
char *disk_name;
@@ -56,9 +101,8 @@
else
disk_name = DEH_String("STDISK");
- disk = W_CacheLumpName(disk_name, PU_STATIC);
- saved_background = Z_Malloc(SHORT(disk->width) * SHORT(disk->height),
- PU_STATIC, NULL);
+ saved_background = Z_Malloc(DISK_ICON_W * DISK_ICON_H, PU_STATIC, NULL);
+ SaveDiskData(disk_name, xoffs, yoffs);
}
void V_BeginRead(size_t nbytes)
@@ -66,42 +110,26 @@
recent_bytes_read += nbytes;
}
-static void CopyRegion(byte *dest, int dest_pitch,
- byte *src, int src_pitch,
- int w, int h)
-{
- byte *s, *d;
- int y;
-
- s = src; d = dest;
- for (y = 0; y < h; ++y)
- {
- memcpy(d, s, w);
- s += src_pitch;
- d += dest_pitch;
- }
-}
-
static byte *DiskRegionPointer(void)
{
- int x, y;
-
- x = loading_disk_xoffs - SHORT(disk->leftoffset);
- y = loading_disk_yoffs - SHORT(disk->topoffset);
- return I_VideoBuffer + y * SCREENWIDTH + x;
+ return I_VideoBuffer
+ + loading_disk_yoffs * SCREENWIDTH
+ + loading_disk_xoffs;
}
void V_DrawDiskIcon(void)
{
- if (disk != NULL && recent_bytes_read > diskicon_threshold)
+ if (disk_data != NULL && recent_bytes_read > diskicon_threshold)
{
// Save the background behind the disk before we draw it.
- CopyRegion(saved_background, SHORT(disk->width),
+ CopyRegion(saved_background, DISK_ICON_W,
DiskRegionPointer(), SCREENWIDTH,
- SHORT(disk->width), SHORT(disk->height));
+ DISK_ICON_W, DISK_ICON_H);
- // Draw the disk to the screen
- V_DrawPatch(loading_disk_xoffs, loading_disk_yoffs, disk);
+ // Write the disk to the screen buffer.
+ CopyRegion(DiskRegionPointer(), SCREENWIDTH,
+ disk_data, DISK_ICON_W,
+ DISK_ICON_W, DISK_ICON_H);
disk_drawn = true;
}
@@ -114,8 +142,8 @@
{
// Restore the background.
CopyRegion(DiskRegionPointer(), SCREENWIDTH,
- saved_background, SHORT(disk->width),
- SHORT(disk->width), SHORT(disk->height));
+ saved_background, DISK_ICON_W,
+ DISK_ICON_W, DISK_ICON_H);
disk_drawn = false;
}