ref: e685f6329cbe2e8ec1bb5df5769e240b1ad06b98
dir: /vid.c/
#include <u.h> #include <libc.h> #include <draw.h> #include <stdio.h> #include <ctype.h> #include "dat.h" #include "fns.h" refexport_t re; /* exported functions from refresh DLL */ int resized; Point center; typedef ulong PIXEL; static int rwon; static uchar *framebuf; static Image *fbim; static PIXEL st2d_8to24table[256]; static int shiftmask_fl; static int r_shift, g_shift, b_shift; static uint r_mask, g_mask, b_mask; refexport_t GetRefAPI(refimport_t); static 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; } static 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; } static 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]]; } } static 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), XRGB32, 0, 0)) == 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 *, void *) { srand(getpid()); if(initdraw(nil, nil, "quake2") < 0) sysfatal("VID_Init:initdraw: %r\n"); resetfb(); rwon = 1; vidref_val = VIDREF_SOFT; return 1; } /* 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 = 0; } void SWimp_AppActivate(qboolean /*active*/) { } void VID_Printf(int print_level, char *fmt, ...) { va_list argptr; char msg[4096]; va_start(argptr, fmt); vsprintf(msg, fmt, argptr); va_end(argptr); if(print_level == PRINT_ALL) Com_Printf("%s", msg); else Com_DPrintf("%s", msg); } void VID_Error(int err_level, char *fmt, ...) { va_list argptr; char msg[4096]; va_start(argptr, fmt); vsprintf(msg, fmt, argptr); va_end(argptr); Com_Error(err_level, "%s", msg); } void VID_CheckChanges(void) { } void VID_Shutdown(void) { R_Shutdown(); } void VID_Init(void) { refimport_t ri; ri.Cmd_AddCommand = Cmd_AddCommand; ri.Cmd_RemoveCommand = Cmd_RemoveCommand; ri.Cmd_Argc = Cmd_Argc; ri.Cmd_Argv = Cmd_Argv; ri.Cmd_ExecuteText = Cbuf_ExecuteText; ri.Con_Printf = VID_Printf; ri.Sys_Error = VID_Error; ri.FS_LoadFile = FS_LoadFile; ri.FS_FreeFile = FS_FreeFile; ri.FS_Gamedir = FS_Gamedir; ri.Cvar_Get = Cvar_Get; ri.Cvar_Set = Cvar_Set; ri.Cvar_SetValue = Cvar_SetValue; ri.Vid_MenuInit = VID_MenuInit; re = GetRefAPI(ri); re.Init(nil, nil); }