mirror of https://github.com/nmlgc/ReC98.git
94 lines
2.5 KiB
C
94 lines
2.5 KiB
C
|
/* ReC98
|
||
|
* -----
|
||
|
* Declarations for planar 4bpp graphics
|
||
|
*/
|
||
|
|
||
|
// 1bpp types, describing horizontal lines of 8, 16, or 32 pixels.
|
||
|
typedef uint8_t dots8_t;
|
||
|
typedef uint16_t dots16_t;
|
||
|
typedef uint32_t dots32_t;
|
||
|
// ... and the same for the rare cases where ZUN's code used signed types.
|
||
|
typedef int8_t sdots8_t;
|
||
|
typedef int16_t sdots16_t;
|
||
|
typedef int32_t sdots32_t;
|
||
|
|
||
|
// Defines a hardcoded 1bpp sprite, pre-shifted to all 8 start X positions
|
||
|
// within a single VRAM byte.
|
||
|
#define PRESHIFT 8
|
||
|
|
||
|
typedef enum {
|
||
|
PL_B, PL_R, PL_G, PL_E, PL_COUNT
|
||
|
} vram_plane_t;
|
||
|
|
||
|
typedef struct {
|
||
|
dots8_t B, R, G, E;
|
||
|
} planar8_t;
|
||
|
|
||
|
typedef struct {
|
||
|
dots16_t B, R, G, E;
|
||
|
} planar16_t;
|
||
|
|
||
|
typedef struct {
|
||
|
dots32_t B, R, G, E;
|
||
|
} planar32_t;
|
||
|
|
||
|
// Abstracted dot and planar types, with their width defined by a macro.
|
||
|
#define dots_t_(x) dots##x##_t
|
||
|
#define dots_t(x) dots_t_(x)
|
||
|
#define sdots_t_(x) sdots##x##_t
|
||
|
#define sdots_t(x) sdots_t_(x)
|
||
|
#define planar_t_(x) planar##x##_t
|
||
|
#define planar_t(x) planar_t_(x)
|
||
|
|
||
|
// Since array subscripts create slightly different assembly in places, we
|
||
|
// offer both variants.
|
||
|
extern dots8_t *VRAM_PLANE[PL_COUNT];
|
||
|
// And no. expressing these as a struct won't generate the same ASM.
|
||
|
// Been there, tried that.
|
||
|
extern dots8_t *VRAM_PLANE_B;
|
||
|
extern dots8_t *VRAM_PLANE_G;
|
||
|
extern dots8_t *VRAM_PLANE_R;
|
||
|
extern dots8_t *VRAM_PLANE_E;
|
||
|
|
||
|
#define VRAM_OFFSET(x, y) ((x) >> 3) + (y << 6) + (y << 4)
|
||
|
|
||
|
#ifdef __cplusplus
|
||
|
static inline unsigned int vram_offset_shift(int x, int y)
|
||
|
{
|
||
|
return VRAM_OFFSET(x, y);
|
||
|
}
|
||
|
|
||
|
static inline unsigned int vram_offset_muldiv(int x, int y)
|
||
|
{
|
||
|
return (y * ROW_SIZE) + (x / 8);
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
#define VRAM_CHUNK(plane, offset, bit_count) \
|
||
|
*(dots##bit_count##_t *)(VRAM_PLANE_##plane + offset)
|
||
|
|
||
|
#define VRAM_SNAP(dst, plane, offset, bit_count) \
|
||
|
dst = VRAM_CHUNK(plane, offset, bit_count);
|
||
|
|
||
|
#define VRAM_SNAP_PLANAR(dst, offset, bit_count) \
|
||
|
VRAM_SNAP(dst.B, B, offset, bit_count); \
|
||
|
VRAM_SNAP(dst.R, R, offset, bit_count); \
|
||
|
VRAM_SNAP(dst.G, G, offset, bit_count); \
|
||
|
VRAM_SNAP(dst.E, E, offset, bit_count);
|
||
|
|
||
|
#define VRAM_PUT(plane, offset, src, bit_count) \
|
||
|
VRAM_CHUNK(plane, offset, bit_count) = src;
|
||
|
|
||
|
#define VRAM_PUT_PLANAR(offset, src, bit_count) \
|
||
|
VRAM_PUT(B, offset, src.B, bit_count); \
|
||
|
VRAM_PUT(R, offset, src.R, bit_count); \
|
||
|
VRAM_PUT(G, offset, src.G, bit_count); \
|
||
|
VRAM_PUT(E, offset, src.E, bit_count);
|
||
|
|
||
|
#define PLANE_DWORD_BLIT(dst, src) \
|
||
|
for(p = 0; p < PLANE_SIZE; p += (int)sizeof(dots32_t)) { \
|
||
|
*(dots32_t*)((dst) + p) = *(dots32_t*)((src) + p); \
|
||
|
}
|
||
|
|
||
|
void pascal vram_planes_set(void);
|