doom

a minimalistic implementation of doom
git clone git://ssnf.xyz/doom
Log | Files | Refs

v_video.c (3082B)


      1 #include <stdlib.h>
      2 
      3 #include "i_system.h"
      4 #include "r_local.h"
      5 #include "doomdef.h"
      6 #include "doomdata.h"
      7 #include "m_swap.h"
      8 #include "m_bbox.h"
      9 #include "v_video.h"
     10 
     11 uchar* screens[5];
     12 int    dirtybox[4];
     13 
     14 int usegamma;
     15 
     16 void
     17 V_MarkRect(int x, int y, int width, int height)
     18 {
     19 	M_AddToBox(dirtybox, x, y);
     20 	M_AddToBox(dirtybox, x + width - 1, y + height - 1);
     21 }
     22 
     23 void
     24 V_CopyRect(int srcx, int srcy, int srcscrn, int width, int height, int destx, int desty, int destscrn)
     25 {
     26 	byte* src, *dest;
     27 
     28 	V_MarkRect(destx, desty, width, height);
     29 	src = screens[srcscrn] + SCREENWIDTH * srcy + srcx;
     30 	dest = screens[destscrn] + SCREENWIDTH * desty + destx;
     31 	for (; height > 0; --height) {
     32 		memcpy(dest, src, width);
     33 		src += SCREENWIDTH;
     34 		dest += SCREENWIDTH;
     35 	}
     36 }
     37 
     38 void
     39 V_DrawPatch(int x, int y, int scrn, patch_t* patch)
     40 {
     41 	column_t* column;
     42 	byte*     desttop, *dest, *source;
     43 	int       count, col, w;
     44 
     45 	y -= SHORT(patch->topoffset);
     46 	x -= SHORT(patch->leftoffset);
     47 	if (!scrn)
     48 		V_MarkRect(x, y, SHORT(patch->width), SHORT(patch->height));
     49 	col = 0;
     50 	desttop = screens[scrn] + y * SCREENWIDTH + x;
     51 	w = SHORT(patch->width);
     52 	for (; col < w; ++x, ++col, ++desttop) {
     53 		column = (column_t*)((byte*)patch + LONG(patch->columnofs[col]));
     54 		while (column->topdelta != 0xff) {
     55 			source = (byte*)column + 3;
     56 			dest = desttop + column->topdelta*SCREENWIDTH;
     57 			count = column->length;
     58 			while (count--) {
     59 				*dest = *source++;
     60 				dest += SCREENWIDTH;
     61 			}
     62 			column = (column_t*)((byte*)column + column->length + 4);
     63 		}
     64 	}
     65 }
     66 
     67 void
     68 V_DrawPatchFlipped(int x, int y, int scrn, patch_t* patch)
     69 {
     70 	column_t* column;
     71 	byte*     desttop, *dest, *source;
     72 	int       w, count, col;
     73 
     74 	y -= SHORT(patch->topoffset);
     75 	x -= SHORT(patch->leftoffset);
     76 	if (!scrn)
     77 		V_MarkRect(x, y, SHORT(patch->width), SHORT(patch->height));
     78 	col = 0;
     79 	desttop = screens[scrn] + y * SCREENWIDTH + x;
     80 	w = SHORT(patch->width);
     81 	for (; col < w; ++x, ++col, ++desttop) {
     82 		column = (column_t*)((byte*)patch + LONG(patch->columnofs[w-1-col]));
     83 		while (column->topdelta != 0xff ) {
     84 			source = (byte*)column + 3;
     85 			dest = desttop + column->topdelta*SCREENWIDTH;
     86 			count = column->length;
     87 			while (count--) {
     88 				*dest = *source++;
     89 				dest += SCREENWIDTH;
     90 			}
     91 			column = (column_t*)((byte*)column + column->length + 4);
     92 		}
     93 	}
     94 }
     95 
     96 void
     97 V_DrawBlock(int x, int y, int scrn, int width, int height, byte* src)
     98 {
     99 	byte* dest;
    100 
    101 	V_MarkRect(x, y, width, height);
    102 	dest = screens[scrn] + y*SCREENWIDTH+x;
    103 	while (height--) {
    104 		memcpy(dest, src, width);
    105 		src += width;
    106 		dest += SCREENWIDTH;
    107 	}
    108 }
    109 
    110 void
    111 V_GetBlock(int x, int y, int scrn, int width, int height, byte* dest)
    112 {
    113 	byte* src;
    114 
    115 	src = screens[scrn] + y * SCREENWIDTH + x;
    116 	while (height--) {
    117 		memcpy (dest, src, width);
    118 		src += SCREENWIDTH;
    119 		dest += width;
    120 	}
    121 }
    122 
    123 void
    124 V_Init()
    125 {
    126 	uchar* buf;
    127 
    128 	buf = malloc(SCREENWIDTH * SCREENHEIGHT * 4);
    129 	memset(buf, 0, SCREENWIDTH * SCREENHEIGHT * 4);
    130 	screens[0] = buf;
    131 	screens[1] = buf + SCREENWIDTH * SCREENHEIGHT;
    132 	screens[2] = buf + SCREENWIDTH * SCREENHEIGHT * 2;
    133 	screens[3] = buf + SCREENWIDTH * SCREENHEIGHT * 3;
    134 }