ref: 8717f3339df1de4076c311b02b077bd2449f2f7c
dir: /plan9/rw_9.c/
#include <u.h>
#include <libc.h>
#include <draw.h>
#include <stdio.h>
#include <ctype.h>
#include "../dat.h"
#include "../fns.h"
qboolean rwon;
uchar *framebuf;
Image *fbim;
int resized;
Point center;
typedef ulong PIXEL;
PIXEL st2d_8to24table[256];
int shiftmask_fl;
int r_shift, g_shift, b_shift;
uint r_mask, g_mask, b_mask;
void shiftmask_init (void)
{
uint x;
r_mask = 0xff0000;
g_mask = 0xff00;
b_mask = 0xff;
for(r_shift = -8, x = 1; x < r_mask; x <<= 1)
r_shift++;
for(g_shift = -8, x = 1; x < g_mask; x <<= 1)
g_shift++;
for(b_shift = -8, x = 1; x < b_mask; x <<= 1)
b_shift++;
shiftmask_fl = 1;
}
PIXEL rgb24 (int r, int g, int b)
{
PIXEL p = 0;
if(shiftmask_fl == 0)
shiftmask_init();
if(r_shift > 0)
p = r<<r_shift & r_mask;
else if(r_shift < 0)
p = r>>-r_shift & r_mask;
else
p |= r & r_mask;
if(g_shift > 0)
p |= g<<g_shift & g_mask;
else if(g_shift < 0)
p |= g>>-g_shift & g_mask;
else
p |= g & g_mask;
if(b_shift > 0)
p |= b<<b_shift & b_mask;
else if(b_shift < 0)
p |= b>>-b_shift & b_mask;
else
p |= b & b_mask;
return p;
}
void st3_fixup (void)
{
int x, y;
uchar *src;
PIXEL *dest;
for(y = 0; y < vid.height; y++){
src = &framebuf[y*vid.rowbytes];
dest = (PIXEL*)src;
/* vid.width % 8 not always 0
for(x = vid.width-1; x >= 0; x -= 8) {
dest[x ] = st2d_8to24table[src[x ]];
dest[x-1] = st2d_8to24table[src[x-1]];
dest[x-2] = st2d_8to24table[src[x-2]];
dest[x-3] = st2d_8to24table[src[x-3]];
dest[x-4] = st2d_8to24table[src[x-4]];
dest[x-5] = st2d_8to24table[src[x-5]];
dest[x-6] = st2d_8to24table[src[x-6]];
dest[x-7] = st2d_8to24table[src[x-7]];
}
*/
for(x = vid.width-1; x >= 0; x--)
dest[x] = st2d_8to24table[src[x]];
}
}
void resetfb (void)
{
vid.width = Dx(screen->r);
vid.height = Dy(screen->r);
if(framebuf != nil){
free(framebuf);
framebuf = nil;
}
if(fbim != nil){
freeimage(fbim);
fbim = nil;
}
if((framebuf = malloc(sizeof *framebuf * vid.width * vid.height * screen->depth/8)) == nil)
sysfatal("resetfb:malloc: %r");
if((fbim = allocimage(display, Rect(0, 0, vid.width, vid.height), screen->chan, 1, DNofill)) == nil)
sysfatal("resetfb: %r");
vid.buffer = framebuf;
vid.rowbytes = vid.width * screen->depth/8;
center = addpt(screen->r.min, Pt(vid.width/2, vid.height/2));
sw_mode->modified = true; /* make ref_soft refresh its shit */
}
int SWimp_Init (void */*hInstance*/, void */*wndProc*/)
{
srand(getpid());
if(initdraw(nil, nil, "quake2") < 0)
sysfatal("VID_Init:initdraw: %r\n");
resetfb();
rwon = true;
return true;
}
/* copy backbuffer to front buffer */
void SWimp_EndFrame (void)
{
if(resized){ /* skip frame if window resizes */
resized = 0;
if(getwindow(display, Refnone) < 0)
sysfatal("SWimp_EndFrame:getwindow: %r\n");
resetfb();
return;
}
st3_fixup();
loadimage(fbim, fbim->r, framebuf, vid.height * vid.rowbytes);
draw(screen, screen->r, fbim, nil, ZP);
flushimage(display, 1);
}
rserr_t SWimp_SetMode (int */*pwidth*/, int */*pheight*/, int /*mode*/, qboolean /*fullscreen*/)
{
return rserr_ok;
}
/* nil palette == use existing; palette is expected to be in padded 4-byte xRGB format */
void SWimp_SetPalette (uchar *palette)
{
int i;
if(!rwon)
return;
if(!palette)
palette = (uchar *)sw_state.currentpalette;
for(i = 0; i < 256; i++)
st2d_8to24table[i] = rgb24(palette[i*4], palette[i*4+1], palette[i*4+2]);
}
void SWimp_Shutdown (void)
{
if(!rwon)
return;
if(framebuf != nil)
free(framebuf);
if(fbim != nil)
freeimage(fbim);
rwon = false;
}
void SWimp_AppActivate (qboolean /*active*/)
{
}