mirror of
https://github.com/WinampDesktop/winamp.git
synced 2025-06-10 11:59:58 -05:00
Quack 3
This commit is contained in:
committed by
GitHub
parent
e8bd66b89c
commit
0bf99969fd
205
linux/q_shlinux.c
Normal file
205
linux/q_shlinux.c
Normal file
@ -0,0 +1,205 @@
|
||||
#include <sys/types.h>
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <dirent.h>
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/mman.h>
|
||||
#include <sys/time.h>
|
||||
|
||||
#include "../linux/glob.h"
|
||||
|
||||
#include "../qcommon/qcommon.h"
|
||||
|
||||
//===============================================================================
|
||||
|
||||
byte *membase;
|
||||
int maxhunksize;
|
||||
int curhunksize;
|
||||
|
||||
void *Hunk_Begin (int maxsize)
|
||||
{
|
||||
// reserve a huge chunk of memory, but don't commit any yet
|
||||
maxhunksize = maxsize + sizeof(int);
|
||||
curhunksize = 0;
|
||||
membase = mmap(0, maxhunksize, PROT_READ|PROT_WRITE,
|
||||
MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
|
||||
if (membase == NULL || membase == (byte *)-1)
|
||||
Sys_Error("unable to virtual allocate %d bytes", maxsize);
|
||||
|
||||
*((int *)membase) = curhunksize;
|
||||
|
||||
return membase + sizeof(int);
|
||||
}
|
||||
|
||||
void *Hunk_Alloc (int size)
|
||||
{
|
||||
byte *buf;
|
||||
|
||||
// round to cacheline
|
||||
size = (size+31)&~31;
|
||||
if (curhunksize + size > maxhunksize)
|
||||
Sys_Error("Hunk_Alloc overflow");
|
||||
buf = membase + sizeof(int) + curhunksize;
|
||||
curhunksize += size;
|
||||
return buf;
|
||||
}
|
||||
|
||||
int Hunk_End (void)
|
||||
{
|
||||
byte *n;
|
||||
|
||||
n = mremap(membase, maxhunksize, curhunksize + sizeof(int), 0);
|
||||
if (n != membase)
|
||||
Sys_Error("Hunk_End: Could not remap virtual block (%d)", errno);
|
||||
*((int *)membase) = curhunksize + sizeof(int);
|
||||
|
||||
return curhunksize;
|
||||
}
|
||||
|
||||
void Hunk_Free (void *base)
|
||||
{
|
||||
byte *m;
|
||||
|
||||
if (base) {
|
||||
m = ((byte *)base) - sizeof(int);
|
||||
if (munmap(m, *((int *)m)))
|
||||
Sys_Error("Hunk_Free: munmap failed (%d)", errno);
|
||||
}
|
||||
}
|
||||
|
||||
//===============================================================================
|
||||
|
||||
|
||||
/*
|
||||
================
|
||||
Sys_Milliseconds
|
||||
================
|
||||
*/
|
||||
int curtime;
|
||||
int Sys_Milliseconds (void)
|
||||
{
|
||||
struct timeval tp;
|
||||
struct timezone tzp;
|
||||
static int secbase;
|
||||
|
||||
gettimeofday(&tp, &tzp);
|
||||
|
||||
if (!secbase)
|
||||
{
|
||||
secbase = tp.tv_sec;
|
||||
return tp.tv_usec/1000;
|
||||
}
|
||||
|
||||
curtime = (tp.tv_sec - secbase)*1000 + tp.tv_usec/1000;
|
||||
|
||||
return curtime;
|
||||
}
|
||||
|
||||
void Sys_Mkdir (char *path)
|
||||
{
|
||||
mkdir (path, 0777);
|
||||
}
|
||||
|
||||
char *strlwr (char *s)
|
||||
{
|
||||
while (*s) {
|
||||
*s = tolower(*s);
|
||||
s++;
|
||||
}
|
||||
}
|
||||
|
||||
//============================================
|
||||
|
||||
static char findbase[MAX_OSPATH];
|
||||
static char findpath[MAX_OSPATH];
|
||||
static char findpattern[MAX_OSPATH];
|
||||
static DIR *fdir;
|
||||
|
||||
static qboolean CompareAttributes(char *path, char *name,
|
||||
unsigned musthave, unsigned canthave )
|
||||
{
|
||||
struct stat st;
|
||||
char fn[MAX_OSPATH];
|
||||
|
||||
// . and .. never match
|
||||
if (strcmp(name, ".") == 0 || strcmp(name, "..") == 0)
|
||||
return false;
|
||||
|
||||
sprintf(fn, "%s/%s", path, name);
|
||||
if (stat(fn, &st) == -1)
|
||||
return false; // shouldn't happen
|
||||
|
||||
if ( ( st.st_mode & S_IFDIR ) && ( canthave & SFF_SUBDIR ) )
|
||||
return false;
|
||||
|
||||
if ( ( musthave & SFF_SUBDIR ) && !( st.st_mode & S_IFDIR ) )
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
char *Sys_FindFirst (char *path, unsigned musthave, unsigned canhave)
|
||||
{
|
||||
struct dirent *d;
|
||||
char *p;
|
||||
|
||||
if (fdir)
|
||||
Sys_Error ("Sys_BeginFind without close");
|
||||
|
||||
// COM_FilePath (path, findbase);
|
||||
strcpy(findbase, path);
|
||||
|
||||
if ((p = strrchr(findbase, '/')) != NULL) {
|
||||
*p = 0;
|
||||
strcpy(findpattern, p + 1);
|
||||
} else
|
||||
strcpy(findpattern, "*");
|
||||
|
||||
if (strcmp(findpattern, "*.*") == 0)
|
||||
strcpy(findpattern, "*");
|
||||
|
||||
if ((fdir = opendir(findbase)) == NULL)
|
||||
return NULL;
|
||||
while ((d = readdir(fdir)) != NULL) {
|
||||
if (!*findpattern || glob_match(findpattern, d->d_name)) {
|
||||
// if (*findpattern)
|
||||
// printf("%s matched %s\n", findpattern, d->d_name);
|
||||
if (CompareAttributes(findbase, d->d_name, musthave, canhave)) {
|
||||
sprintf (findpath, "%s/%s", findbase, d->d_name);
|
||||
return findpath;
|
||||
}
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
char *Sys_FindNext (unsigned musthave, unsigned canhave)
|
||||
{
|
||||
struct dirent *d;
|
||||
|
||||
if (fdir == NULL)
|
||||
return NULL;
|
||||
while ((d = readdir(fdir)) != NULL) {
|
||||
if (!*findpattern || glob_match(findpattern, d->d_name)) {
|
||||
// if (*findpattern)
|
||||
// printf("%s matched %s\n", findpattern, d->d_name);
|
||||
if (CompareAttributes(findbase, d->d_name, musthave, canhave)) {
|
||||
sprintf (findpath, "%s/%s", findbase, d->d_name);
|
||||
return findpath;
|
||||
}
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void Sys_FindClose (void)
|
||||
{
|
||||
if (fdir != NULL)
|
||||
closedir(fdir);
|
||||
fdir = NULL;
|
||||
}
|
||||
|
||||
|
||||
//============================================
|
||||
|
459
linux/qasm.h
Normal file
459
linux/qasm.h
Normal file
@ -0,0 +1,459 @@
|
||||
#ifndef __ASM_I386__
|
||||
#define __ASM_I386__
|
||||
|
||||
#ifdef ELF
|
||||
#define C(label) label
|
||||
#else
|
||||
#define C(label) _##label
|
||||
#endif
|
||||
|
||||
|
||||
//#define GLQUAKE 1
|
||||
|
||||
#if defined(_WIN32) && !defined(WINDED)
|
||||
|
||||
#if defined(_M_IX86)
|
||||
#define __i386__ 1
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef __i386__
|
||||
#define id386 1
|
||||
#else
|
||||
#define id386 0
|
||||
#endif
|
||||
|
||||
// !!! must be kept the same as in d_iface.h !!!
|
||||
#define TRANSPARENT_COLOR 255
|
||||
|
||||
#ifndef GLQUAKE
|
||||
.extern C(d_zistepu)
|
||||
.extern C(d_pzbuffer)
|
||||
.extern C(d_zistepv)
|
||||
.extern C(d_zrowbytes)
|
||||
.extern C(d_ziorigin)
|
||||
.extern C(r_turb_s)
|
||||
.extern C(r_turb_t)
|
||||
.extern C(r_turb_pdest)
|
||||
.extern C(r_turb_spancount)
|
||||
.extern C(r_turb_turb)
|
||||
.extern C(r_turb_pbase)
|
||||
.extern C(r_turb_sstep)
|
||||
.extern C(r_turb_tstep)
|
||||
.extern C(r_bmodelactive)
|
||||
.extern C(d_sdivzstepu)
|
||||
.extern C(d_tdivzstepu)
|
||||
.extern C(d_sdivzstepv)
|
||||
.extern C(d_tdivzstepv)
|
||||
.extern C(d_sdivzorigin)
|
||||
.extern C(d_tdivzorigin)
|
||||
.extern C(sadjust)
|
||||
.extern C(tadjust)
|
||||
.extern C(bbextents)
|
||||
.extern C(bbextentt)
|
||||
.extern C(cacheblock)
|
||||
.extern C(d_viewbuffer)
|
||||
.extern C(cachewidth)
|
||||
.extern C(d_pzbuffer)
|
||||
.extern C(d_zrowbytes)
|
||||
.extern C(d_zwidth)
|
||||
.extern C(d_scantable)
|
||||
.extern C(r_lightptr)
|
||||
.extern C(r_numvblocks)
|
||||
.extern C(prowdestbase)
|
||||
.extern C(pbasesource)
|
||||
.extern C(r_lightwidth)
|
||||
.extern C(lightright)
|
||||
.extern C(lightrightstep)
|
||||
.extern C(lightdeltastep)
|
||||
.extern C(lightdelta)
|
||||
.extern C(lightright)
|
||||
.extern C(lightdelta)
|
||||
.extern C(sourcetstep)
|
||||
.extern C(surfrowbytes)
|
||||
.extern C(lightrightstep)
|
||||
.extern C(lightdeltastep)
|
||||
.extern C(r_sourcemax)
|
||||
.extern C(r_stepback)
|
||||
.extern C(colormap)
|
||||
.extern C(blocksize)
|
||||
.extern C(sourcesstep)
|
||||
.extern C(lightleft)
|
||||
.extern C(blockdivshift)
|
||||
.extern C(blockdivmask)
|
||||
.extern C(lightleftstep)
|
||||
.extern C(r_origin)
|
||||
.extern C(r_ppn)
|
||||
.extern C(r_pup)
|
||||
.extern C(r_pright)
|
||||
.extern C(ycenter)
|
||||
.extern C(xcenter)
|
||||
.extern C(d_vrectbottom_particle)
|
||||
.extern C(d_vrectright_particle)
|
||||
.extern C(d_vrecty)
|
||||
.extern C(d_vrectx)
|
||||
.extern C(d_pix_shift)
|
||||
.extern C(d_pix_min)
|
||||
.extern C(d_pix_max)
|
||||
.extern C(d_y_aspect_shift)
|
||||
.extern C(screenwidth)
|
||||
.extern C(r_leftclipped)
|
||||
.extern C(r_leftenter)
|
||||
.extern C(r_rightclipped)
|
||||
.extern C(r_rightenter)
|
||||
.extern C(modelorg)
|
||||
.extern C(xscale)
|
||||
.extern C(r_refdef)
|
||||
.extern C(yscale)
|
||||
.extern C(r_leftexit)
|
||||
.extern C(r_rightexit)
|
||||
.extern C(r_lastvertvalid)
|
||||
.extern C(cacheoffset)
|
||||
.extern C(newedges)
|
||||
.extern C(removeedges)
|
||||
.extern C(r_pedge)
|
||||
.extern C(r_framecount)
|
||||
.extern C(r_u1)
|
||||
.extern C(r_emitted)
|
||||
.extern C(edge_p)
|
||||
.extern C(surface_p)
|
||||
.extern C(surfaces)
|
||||
.extern C(r_lzi1)
|
||||
.extern C(r_v1)
|
||||
.extern C(r_ceilv1)
|
||||
.extern C(r_nearzi)
|
||||
.extern C(r_nearzionly)
|
||||
.extern C(edge_aftertail)
|
||||
.extern C(edge_tail)
|
||||
.extern C(current_iv)
|
||||
.extern C(edge_head_u_shift20)
|
||||
.extern C(span_p)
|
||||
.extern C(edge_head)
|
||||
.extern C(fv)
|
||||
.extern C(edge_tail_u_shift20)
|
||||
.extern C(r_apverts)
|
||||
.extern C(r_anumverts)
|
||||
.extern C(aliastransform)
|
||||
.extern C(r_avertexnormals)
|
||||
.extern C(r_plightvec)
|
||||
.extern C(r_ambientlight)
|
||||
.extern C(r_shadelight)
|
||||
.extern C(aliasxcenter)
|
||||
.extern C(aliasycenter)
|
||||
.extern C(a_sstepxfrac)
|
||||
.extern C(r_affinetridesc)
|
||||
.extern C(acolormap)
|
||||
.extern C(d_pcolormap)
|
||||
.extern C(r_affinetridesc)
|
||||
.extern C(d_sfrac)
|
||||
.extern C(d_ptex)
|
||||
.extern C(d_pedgespanpackage)
|
||||
.extern C(d_tfrac)
|
||||
.extern C(d_light)
|
||||
.extern C(d_zi)
|
||||
.extern C(d_pdest)
|
||||
.extern C(d_pz)
|
||||
.extern C(d_aspancount)
|
||||
.extern C(erroradjustup)
|
||||
.extern C(errorterm)
|
||||
.extern C(d_xdenom)
|
||||
.extern C(r_p0)
|
||||
.extern C(r_p1)
|
||||
.extern C(r_p2)
|
||||
.extern C(a_tstepxfrac)
|
||||
.extern C(r_sstepx)
|
||||
.extern C(r_tstepx)
|
||||
.extern C(a_ststepxwhole)
|
||||
.extern C(zspantable)
|
||||
.extern C(skintable)
|
||||
.extern C(r_zistepx)
|
||||
.extern C(erroradjustdown)
|
||||
.extern C(d_countextrastep)
|
||||
.extern C(ubasestep)
|
||||
.extern C(a_ststepxwhole)
|
||||
.extern C(a_tstepxfrac)
|
||||
.extern C(r_lstepx)
|
||||
.extern C(a_spans)
|
||||
.extern C(erroradjustdown)
|
||||
.extern C(d_pdestextrastep)
|
||||
.extern C(d_pzextrastep)
|
||||
.extern C(d_sfracextrastep)
|
||||
.extern C(d_ptexextrastep)
|
||||
.extern C(d_countextrastep)
|
||||
.extern C(d_tfracextrastep)
|
||||
.extern C(d_lightextrastep)
|
||||
.extern C(d_ziextrastep)
|
||||
.extern C(d_pdestbasestep)
|
||||
.extern C(d_pzbasestep)
|
||||
.extern C(d_sfracbasestep)
|
||||
.extern C(d_ptexbasestep)
|
||||
.extern C(ubasestep)
|
||||
.extern C(d_tfracbasestep)
|
||||
.extern C(d_lightbasestep)
|
||||
.extern C(d_zibasestep)
|
||||
.extern C(zspantable)
|
||||
.extern C(r_lstepy)
|
||||
.extern C(r_sstepy)
|
||||
.extern C(r_tstepy)
|
||||
.extern C(r_zistepy)
|
||||
.extern C(D_PolysetSetEdgeTable)
|
||||
.extern C(D_RasterizeAliasPolySmooth)
|
||||
|
||||
.extern float_point5
|
||||
.extern Float2ToThe31nd
|
||||
.extern izistep
|
||||
.extern izi
|
||||
.extern FloatMinus2ToThe31nd
|
||||
.extern float_1
|
||||
.extern float_particle_z_clip
|
||||
.extern float_minus_1
|
||||
.extern float_0
|
||||
.extern fp_16
|
||||
.extern fp_64k
|
||||
.extern fp_1m
|
||||
.extern fp_1m_minus_1
|
||||
.extern fp_8
|
||||
.extern entryvec_table
|
||||
.extern advancetable
|
||||
.extern sstep
|
||||
.extern tstep
|
||||
.extern pspantemp
|
||||
.extern counttemp
|
||||
.extern jumptemp
|
||||
.extern reciprocal_table
|
||||
.extern DP_Count
|
||||
.extern DP_u
|
||||
.extern DP_v
|
||||
.extern DP_32768
|
||||
.extern DP_Color
|
||||
.extern DP_Pix
|
||||
.extern DP_EntryTable
|
||||
.extern pbase
|
||||
.extern s
|
||||
.extern t
|
||||
.extern sfracf
|
||||
.extern tfracf
|
||||
.extern snext
|
||||
.extern tnext
|
||||
.extern spancountminus1
|
||||
.extern zi16stepu
|
||||
.extern sdivz16stepu
|
||||
.extern tdivz16stepu
|
||||
.extern zi8stepu
|
||||
.extern sdivz8stepu
|
||||
.extern tdivz8stepu
|
||||
.extern reciprocal_table_16
|
||||
.extern entryvec_table_16
|
||||
.extern ceil_cw
|
||||
.extern single_cw
|
||||
.extern fp_64kx64k
|
||||
.extern pz
|
||||
.extern spr8entryvec_table
|
||||
#endif
|
||||
|
||||
.extern C(snd_scaletable)
|
||||
.extern C(paintbuffer)
|
||||
.extern C(snd_linear_count)
|
||||
.extern C(snd_p)
|
||||
.extern C(snd_vol)
|
||||
.extern C(snd_out)
|
||||
.extern C(vright)
|
||||
.extern C(vup)
|
||||
.extern C(vpn)
|
||||
.extern C(BOPS_Error)
|
||||
|
||||
//
|
||||
// !!! note that this file must match the corresponding C structures at all
|
||||
// times !!!
|
||||
//
|
||||
|
||||
// plane_t structure
|
||||
// !!! if this is changed, it must be changed in model.h too !!!
|
||||
// !!! if the size of this is changed, the array lookup in SV_HullPointContents
|
||||
// must be changed too !!!
|
||||
#define pl_normal 0
|
||||
#define pl_dist 12
|
||||
#define pl_type 16
|
||||
#define pl_signbits 17
|
||||
#define pl_pad 18
|
||||
#define pl_size 20
|
||||
|
||||
// hull_t structure
|
||||
// !!! if this is changed, it must be changed in model.h too !!!
|
||||
#define hu_clipnodes 0
|
||||
#define hu_planes 4
|
||||
#define hu_firstclipnode 8
|
||||
#define hu_lastclipnode 12
|
||||
#define hu_clip_mins 16
|
||||
#define hu_clip_maxs 28
|
||||
#define hu_size 40
|
||||
|
||||
// dnode_t structure
|
||||
// !!! if this is changed, it must be changed in bspfile.h too !!!
|
||||
#define nd_planenum 0
|
||||
#define nd_children 4
|
||||
#define nd_mins 8
|
||||
#define nd_maxs 20
|
||||
#define nd_firstface 32
|
||||
#define nd_numfaces 36
|
||||
#define nd_size 40
|
||||
|
||||
// sfxcache_t structure
|
||||
// !!! if this is changed, it much be changed in sound.h too !!!
|
||||
#define sfxc_length 0
|
||||
#define sfxc_loopstart 4
|
||||
#define sfxc_speed 8
|
||||
#define sfxc_width 12
|
||||
#define sfxc_stereo 16
|
||||
#define sfxc_data 20
|
||||
|
||||
// channel_t structure
|
||||
// !!! if this is changed, it much be changed in sound.h too !!!
|
||||
#define ch_sfx 0
|
||||
#define ch_leftvol 4
|
||||
#define ch_rightvol 8
|
||||
#define ch_end 12
|
||||
#define ch_pos 16
|
||||
#define ch_looping 20
|
||||
#define ch_entnum 24
|
||||
#define ch_entchannel 28
|
||||
#define ch_origin 32
|
||||
#define ch_dist_mult 44
|
||||
#define ch_master_vol 48
|
||||
#define ch_size 52
|
||||
|
||||
// portable_samplepair_t structure
|
||||
// !!! if this is changed, it much be changed in sound.h too !!!
|
||||
#define psp_left 0
|
||||
#define psp_right 4
|
||||
#define psp_size 8
|
||||
|
||||
|
||||
//
|
||||
// !!! note that this file must match the corresponding C structures at all
|
||||
// times !!!
|
||||
//
|
||||
|
||||
// !!! if this is changed, it must be changed in r_local.h too !!!
|
||||
#define NEAR_CLIP 0.01
|
||||
|
||||
// !!! if this is changed, it must be changed in r_local.h too !!!
|
||||
#define CYCLE 128
|
||||
|
||||
// espan_t structure
|
||||
// !!! if this is changed, it must be changed in r_shared.h too !!!
|
||||
#define espan_t_u 0
|
||||
#define espan_t_v 4
|
||||
#define espan_t_count 8
|
||||
#define espan_t_pnext 12
|
||||
#define espan_t_size 16
|
||||
|
||||
// sspan_t structure
|
||||
// !!! if this is changed, it must be changed in d_local.h too !!!
|
||||
#define sspan_t_u 0
|
||||
#define sspan_t_v 4
|
||||
#define sspan_t_count 8
|
||||
#define sspan_t_size 12
|
||||
|
||||
// spanpackage_t structure
|
||||
// !!! if this is changed, it must be changed in d_polyset.c too !!!
|
||||
#define spanpackage_t_pdest 0
|
||||
#define spanpackage_t_pz 4
|
||||
#define spanpackage_t_count 8
|
||||
#define spanpackage_t_ptex 12
|
||||
#define spanpackage_t_sfrac 16
|
||||
#define spanpackage_t_tfrac 20
|
||||
#define spanpackage_t_light 24
|
||||
#define spanpackage_t_zi 28
|
||||
#define spanpackage_t_size 32
|
||||
|
||||
// edge_t structure
|
||||
// !!! if this is changed, it must be changed in r_shared.h too !!!
|
||||
#define et_u 0
|
||||
#define et_u_step 4
|
||||
#define et_prev 8
|
||||
#define et_next 12
|
||||
#define et_surfs 16
|
||||
#define et_nextremove 20
|
||||
#define et_nearzi 24
|
||||
#define et_owner 28
|
||||
#define et_size 32
|
||||
|
||||
// surf_t structure
|
||||
// !!! if this is changed, it must be changed in r_shared.h too !!!
|
||||
#define SURF_T_SHIFT 6
|
||||
#define st_next 0
|
||||
#define st_prev 4
|
||||
#define st_spans 8
|
||||
#define st_key 12
|
||||
#define st_last_u 16
|
||||
#define st_spanstate 20
|
||||
#define st_flags 24
|
||||
#define st_data 28
|
||||
#define st_entity 32
|
||||
#define st_nearzi 36
|
||||
#define st_insubmodel 40
|
||||
#define st_d_ziorigin 44
|
||||
#define st_d_zistepu 48
|
||||
#define st_d_zistepv 52
|
||||
#define st_pad 56
|
||||
#define st_size 64
|
||||
|
||||
// clipplane_t structure
|
||||
// !!! if this is changed, it must be changed in r_local.h too !!!
|
||||
#define cp_normal 0
|
||||
#define cp_dist 12
|
||||
#define cp_next 16
|
||||
#define cp_leftedge 20
|
||||
#define cp_rightedge 21
|
||||
#define cp_reserved 22
|
||||
#define cp_size 24
|
||||
|
||||
// medge_t structure
|
||||
// !!! if this is changed, it must be changed in model.h too !!!
|
||||
#define me_v 0
|
||||
#define me_cachededgeoffset 4
|
||||
#define me_size 8
|
||||
|
||||
// mvertex_t structure
|
||||
// !!! if this is changed, it must be changed in model.h too !!!
|
||||
#define mv_position 0
|
||||
#define mv_size 12
|
||||
|
||||
// refdef_t structure
|
||||
// !!! if this is changed, it must be changed in render.h too !!!
|
||||
#define rd_vrect 0
|
||||
#define rd_aliasvrect 20
|
||||
#define rd_vrectright 40
|
||||
#define rd_vrectbottom 44
|
||||
#define rd_aliasvrectright 48
|
||||
#define rd_aliasvrectbottom 52
|
||||
#define rd_vrectrightedge 56
|
||||
#define rd_fvrectx 60
|
||||
#define rd_fvrecty 64
|
||||
#define rd_fvrectx_adj 68
|
||||
#define rd_fvrecty_adj 72
|
||||
#define rd_vrect_x_adj_shift20 76
|
||||
#define rd_vrectright_adj_shift20 80
|
||||
#define rd_fvrectright_adj 84
|
||||
#define rd_fvrectbottom_adj 88
|
||||
#define rd_fvrectright 92
|
||||
#define rd_fvrectbottom 96
|
||||
#define rd_horizontalFieldOfView 100
|
||||
#define rd_xOrigin 104
|
||||
#define rd_yOrigin 108
|
||||
#define rd_vieworg 112
|
||||
#define rd_viewangles 124
|
||||
#define rd_ambientlight 136
|
||||
#define rd_size 140
|
||||
|
||||
// mtriangle_t structure
|
||||
// !!! if this is changed, it must be changed in model.h too !!!
|
||||
#define mtri_facesfront 0
|
||||
#define mtri_vertindex 4
|
||||
#define mtri_size 16 // !!! if this changes, array indexing in !!!
|
||||
// !!! d_polysa.s must be changed to match !!!
|
||||
#define mtri_shift 4
|
||||
|
||||
#endif
|
3994
linux/qgl_linux.c
Normal file
3994
linux/qgl_linux.c
Normal file
File diff suppressed because it is too large
Load Diff
195
linux/r_aclipa.s
Normal file
195
linux/r_aclipa.s
Normal file
@ -0,0 +1,195 @@
|
||||
//
|
||||
// r_aliasa.s
|
||||
// x86 assembly-language Alias model transform and project code.
|
||||
//
|
||||
|
||||
#include "qasm.h"
|
||||
#include "d_ifacea.h"
|
||||
|
||||
#if id386
|
||||
|
||||
.data
|
||||
Ltemp0: .long 0
|
||||
Ltemp1: .long 0
|
||||
|
||||
.text
|
||||
|
||||
#define pfv0 8+4
|
||||
#define pfv1 8+8
|
||||
#define out 8+12
|
||||
|
||||
.globl C(R_Alias_clip_bottom)
|
||||
C(R_Alias_clip_bottom):
|
||||
pushl %esi
|
||||
pushl %edi
|
||||
|
||||
movl pfv0(%esp),%esi
|
||||
movl pfv1(%esp),%edi
|
||||
|
||||
movl C(r_refdef)+rd_aliasvrectbottom,%eax
|
||||
|
||||
LDoForwardOrBackward:
|
||||
|
||||
movl fv_v+4(%esi),%edx
|
||||
movl fv_v+4(%edi),%ecx
|
||||
|
||||
cmpl %ecx,%edx
|
||||
jl LDoForward
|
||||
|
||||
movl fv_v+4(%esi),%ecx
|
||||
movl fv_v+4(%edi),%edx
|
||||
movl pfv0(%esp),%edi
|
||||
movl pfv1(%esp),%esi
|
||||
|
||||
LDoForward:
|
||||
|
||||
subl %edx,%ecx
|
||||
subl %edx,%eax
|
||||
movl %ecx,Ltemp1
|
||||
movl %eax,Ltemp0
|
||||
fildl Ltemp1
|
||||
fildl Ltemp0
|
||||
movl out(%esp),%edx
|
||||
movl $2,%eax
|
||||
|
||||
fdivp %st(0),%st(1) // scale
|
||||
|
||||
LDo3Forward:
|
||||
fildl fv_v+0(%esi) // fv0v0 | scale
|
||||
fildl fv_v+0(%edi) // fv1v0 | fv0v0 | scale
|
||||
fildl fv_v+4(%esi) // fv0v1 | fv1v0 | fv0v0 | scale
|
||||
fildl fv_v+4(%edi) // fv1v1 | fv0v1 | fv1v0 | fv0v0 | scale
|
||||
fildl fv_v+8(%esi) // fv0v2 | fv1v1 | fv0v1 | fv1v0 | fv0v0 | scale
|
||||
fildl fv_v+8(%edi) // fv1v2 | fv0v2 | fv1v1 | fv0v1 | fv1v0 | fv0v0 |
|
||||
// scale
|
||||
fxch %st(5) // fv0v0 | fv0v2 | fv1v1 | fv0v1 | fv1v0 | fv1v2 |
|
||||
// scale
|
||||
fsubr %st(0),%st(4) // fv0v0 | fv0v2 | fv1v1 | fv0v1 | fv1v0-fv0v0 |
|
||||
// fv1v2 | scale
|
||||
fxch %st(3) // fv0v1 | fv0v2 | fv1v1 | fv0v0 | fv1v0-fv0v0 |
|
||||
// fv1v2 | scale
|
||||
fsubr %st(0),%st(2) // fv0v1 | fv0v2 | fv1v1-fv0v1 | fv0v0 |
|
||||
// fv1v0-fv0v0 | fv1v2 | scale
|
||||
fxch %st(1) // fv0v2 | fv0v1 | fv1v1-fv0v1 | fv0v0 |
|
||||
// fv1v0-fv0v0 | fv1v2 | scale
|
||||
fsubr %st(0),%st(5) // fv0v2 | fv0v1 | fv1v1-fv0v1 | fv0v0 |
|
||||
// fv1v0-fv0v0 | fv1v2-fv0v2 | scale
|
||||
fxch %st(6) // scale | fv0v1 | fv1v1-fv0v1 | fv0v0 |
|
||||
// fv1v0-fv0v0 | fv1v2-fv0v2 | fv0v2
|
||||
fmul %st(0),%st(4) // scale | fv0v1 | fv1v1-fv0v1 | fv0v0 |
|
||||
// (fv1v0-fv0v0)*scale | fv1v2-fv0v2 | fv0v2
|
||||
addl $12,%edi
|
||||
fmul %st(0),%st(2) // scale | fv0v1 | (fv1v1-fv0v1)*scale | fv0v0 |
|
||||
// (fv1v0-fv0v0)*scale | fv1v2-fv0v2 | fv0v2
|
||||
addl $12,%esi
|
||||
addl $12,%edx
|
||||
fmul %st(0),%st(5) // scale | fv0v1 | (fv1v1-fv0v1)*scale | fv0v0 |
|
||||
// (fv1v0-fv0v0)*scale | (fv1v2-fv0v2)*scale |
|
||||
// fv0v2
|
||||
fxch %st(3) // fv0v0 | fv0v1 | (fv1v1-fv0v1)*scale | scale |
|
||||
// (fv1v0-fv0v0)*scale | (fv1v2-fv0v2)*scale |
|
||||
// fv0v2
|
||||
faddp %st(0),%st(4) // fv0v1 | (fv1v1-fv0v1)*scale | scale |
|
||||
// fv0v0+(fv1v0-fv0v0)*scale |
|
||||
// (fv1v2-fv0v2)*scale | fv0v2
|
||||
faddp %st(0),%st(1) // fv0v1+(fv1v1-fv0v1)*scale | scale |
|
||||
// fv0v0+(fv1v0-fv0v0)*scale |
|
||||
// (fv1v2-fv0v2)*scale | fv0v2
|
||||
fxch %st(4) // fv0v2 | scale | fv0v0+(fv1v0-fv0v0)*scale |
|
||||
// (fv1v2-fv0v2)*scale | fv0v1+(fv1v1-fv0v1)*scale
|
||||
faddp %st(0),%st(3) // scale | fv0v0+(fv1v0-fv0v0)*scale |
|
||||
// fv0v2+(fv1v2-fv0v2)*scale |
|
||||
// fv0v1+(fv1v1-fv0v1)*scale
|
||||
fxch %st(1) // fv0v0+(fv1v0-fv0v0)*scale | scale |
|
||||
// fv0v2+(fv1v2-fv0v2)*scale |
|
||||
// fv0v1+(fv1v1-fv0v1)*scale
|
||||
fadds float_point5
|
||||
fxch %st(3) // fv0v1+(fv1v1-fv0v1)*scale | scale |
|
||||
// fv0v2+(fv1v2-fv0v2)*scale |
|
||||
// fv0v0+(fv1v0-fv0v0)*scale
|
||||
fadds float_point5
|
||||
fxch %st(2) // fv0v2+(fv1v2-fv0v2)*scale | scale |
|
||||
// fv0v1+(fv1v1-fv0v1)*scale |
|
||||
// fv0v0+(fv1v0-fv0v0)*scale
|
||||
fadds float_point5
|
||||
fxch %st(3) // fv0v0+(fv1v0-fv0v0)*scale | scale |
|
||||
// fv0v1+(fv1v1-fv0v1)*scale |
|
||||
// fv0v2+(fv1v2-fv0v2)*scale
|
||||
fistpl fv_v+0-12(%edx) // scale | fv0v1+(fv1v1-fv0v1)*scale |
|
||||
// fv0v2+(fv1v2-fv0v2)*scale
|
||||
fxch %st(1) // fv0v1+(fv1v1-fv0v1)*scale | scale |
|
||||
// fv0v2+(fv1v2-fv0v2)*scale | scale
|
||||
fistpl fv_v+4-12(%edx) // scale | fv0v2+(fv1v2-fv0v2)*scale
|
||||
fxch %st(1) // fv0v2+(fv1v2-fv0v2)*sc | scale
|
||||
fistpl fv_v+8-12(%edx) // scale
|
||||
|
||||
decl %eax
|
||||
jnz LDo3Forward
|
||||
|
||||
fstp %st(0)
|
||||
|
||||
popl %edi
|
||||
popl %esi
|
||||
|
||||
ret
|
||||
|
||||
|
||||
.globl C(R_Alias_clip_top)
|
||||
C(R_Alias_clip_top):
|
||||
pushl %esi
|
||||
pushl %edi
|
||||
|
||||
movl pfv0(%esp),%esi
|
||||
movl pfv1(%esp),%edi
|
||||
|
||||
movl C(r_refdef)+rd_aliasvrect+4,%eax
|
||||
jmp LDoForwardOrBackward
|
||||
|
||||
|
||||
|
||||
.globl C(R_Alias_clip_right)
|
||||
C(R_Alias_clip_right):
|
||||
pushl %esi
|
||||
pushl %edi
|
||||
|
||||
movl pfv0(%esp),%esi
|
||||
movl pfv1(%esp),%edi
|
||||
|
||||
movl C(r_refdef)+rd_aliasvrectright,%eax
|
||||
|
||||
LRightLeftEntry:
|
||||
|
||||
|
||||
movl fv_v+4(%esi),%edx
|
||||
movl fv_v+4(%edi),%ecx
|
||||
|
||||
cmpl %ecx,%edx
|
||||
movl fv_v+0(%esi),%edx
|
||||
|
||||
movl fv_v+0(%edi),%ecx
|
||||
jl LDoForward2
|
||||
|
||||
movl fv_v+0(%esi),%ecx
|
||||
movl fv_v+0(%edi),%edx
|
||||
movl pfv0(%esp),%edi
|
||||
movl pfv1(%esp),%esi
|
||||
|
||||
LDoForward2:
|
||||
|
||||
jmp LDoForward
|
||||
|
||||
|
||||
.globl C(R_Alias_clip_left)
|
||||
C(R_Alias_clip_left):
|
||||
pushl %esi
|
||||
pushl %edi
|
||||
|
||||
movl pfv0(%esp),%esi
|
||||
movl pfv1(%esp),%edi
|
||||
|
||||
movl C(r_refdef)+rd_aliasvrect+0,%eax
|
||||
jmp LRightLeftEntry
|
||||
|
||||
|
||||
#endif // id386
|
||||
|
1227
linux/r_draw16.s
Normal file
1227
linux/r_draw16.s
Normal file
File diff suppressed because it is too large
Load Diff
817
linux/r_drawa.s
Normal file
817
linux/r_drawa.s
Normal file
@ -0,0 +1,817 @@
|
||||
//
|
||||
// r_drawa.s
|
||||
// x86 assembly-language edge clipping and emission code
|
||||
//
|
||||
|
||||
#include "qasm.h"
|
||||
#include "d_ifacea.h"
|
||||
|
||||
#if id386
|
||||
|
||||
// !!! if these are changed, they must be changed in r_draw.c too !!!
|
||||
#define FULLY_CLIPPED_CACHED 0x80000000
|
||||
#define FRAMECOUNT_MASK 0x7FFFFFFF
|
||||
|
||||
.data
|
||||
|
||||
Ld0: .single 0.0
|
||||
Ld1: .single 0.0
|
||||
Lstack: .long 0
|
||||
Lfp_near_clip: .single NEAR_CLIP
|
||||
Lceilv0: .long 0
|
||||
Lv: .long 0
|
||||
Lu0: .long 0
|
||||
Lv0: .long 0
|
||||
Lzi0: .long 0
|
||||
|
||||
.text
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// edge clipping code
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
#define pv0 4+12
|
||||
#define pv1 8+12
|
||||
#define clip 12+12
|
||||
|
||||
.align 4
|
||||
.globl C(R_ClipEdge)
|
||||
C(R_ClipEdge):
|
||||
pushl %esi // preserve register variables
|
||||
pushl %edi
|
||||
pushl %ebx
|
||||
movl %esp,Lstack // for clearing the stack later
|
||||
|
||||
// float d0, d1, f;
|
||||
// mvertex_t clipvert;
|
||||
|
||||
movl clip(%esp),%ebx
|
||||
movl pv0(%esp),%esi
|
||||
movl pv1(%esp),%edx
|
||||
|
||||
// if (clip)
|
||||
// {
|
||||
testl %ebx,%ebx
|
||||
jz Lemit
|
||||
|
||||
// do
|
||||
// {
|
||||
|
||||
Lcliploop:
|
||||
|
||||
// d0 = DotProduct (pv0->position, clip->normal) - clip->dist;
|
||||
// d1 = DotProduct (pv1->position, clip->normal) - clip->dist;
|
||||
flds mv_position+0(%esi)
|
||||
fmuls cp_normal+0(%ebx)
|
||||
flds mv_position+4(%esi)
|
||||
fmuls cp_normal+4(%ebx)
|
||||
flds mv_position+8(%esi)
|
||||
fmuls cp_normal+8(%ebx)
|
||||
fxch %st(1)
|
||||
faddp %st(0),%st(2) // d0mul2 | d0add0
|
||||
|
||||
flds mv_position+0(%edx)
|
||||
fmuls cp_normal+0(%ebx)
|
||||
flds mv_position+4(%edx)
|
||||
fmuls cp_normal+4(%ebx)
|
||||
flds mv_position+8(%edx)
|
||||
fmuls cp_normal+8(%ebx)
|
||||
fxch %st(1)
|
||||
faddp %st(0),%st(2) // d1mul2 | d1add0 | d0mul2 | d0add0
|
||||
fxch %st(3) // d0add0 | d1add0 | d0mul2 | d1mul2
|
||||
|
||||
faddp %st(0),%st(2) // d1add0 | dot0 | d1mul2
|
||||
faddp %st(0),%st(2) // dot0 | dot1
|
||||
|
||||
fsubs cp_dist(%ebx) // d0 | dot1
|
||||
fxch %st(1) // dot1 | d0
|
||||
fsubs cp_dist(%ebx) // d1 | d0
|
||||
fxch %st(1)
|
||||
fstps Ld0
|
||||
fstps Ld1
|
||||
|
||||
// if (d0 >= 0)
|
||||
// {
|
||||
movl Ld0,%eax
|
||||
movl Ld1,%ecx
|
||||
orl %eax,%ecx
|
||||
js Lp2
|
||||
|
||||
// both points are unclipped
|
||||
|
||||
Lcontinue:
|
||||
|
||||
//
|
||||
// R_ClipEdge (&clipvert, pv1, clip->next);
|
||||
// return;
|
||||
// }
|
||||
// } while ((clip = clip->next) != NULL);
|
||||
movl cp_next(%ebx),%ebx
|
||||
testl %ebx,%ebx
|
||||
jnz Lcliploop
|
||||
|
||||
// }
|
||||
|
||||
//// add the edge
|
||||
// R_EmitEdge (pv0, pv1);
|
||||
Lemit:
|
||||
|
||||
//
|
||||
// set integer rounding to ceil mode, set to single precision
|
||||
//
|
||||
// FIXME: do away with by manually extracting integers from floats?
|
||||
// FIXME: set less often
|
||||
fldcw ceil_cw
|
||||
|
||||
// edge_t *edge, *pcheck;
|
||||
// int u_check;
|
||||
// float u, u_step;
|
||||
// vec3_t local, transformed;
|
||||
// float *world;
|
||||
// int v, v2, ceilv0;
|
||||
// float scale, lzi0, u0, v0;
|
||||
// int side;
|
||||
|
||||
// if (r_lastvertvalid)
|
||||
// {
|
||||
cmpl $0,C(r_lastvertvalid)
|
||||
jz LCalcFirst
|
||||
|
||||
// u0 = r_u1;
|
||||
// v0 = r_v1;
|
||||
// lzi0 = r_lzi1;
|
||||
// ceilv0 = r_ceilv1;
|
||||
movl C(r_lzi1),%eax
|
||||
movl C(r_u1),%ecx
|
||||
movl %eax,Lzi0
|
||||
movl %ecx,Lu0
|
||||
movl C(r_v1),%ecx
|
||||
movl C(r_ceilv1),%eax
|
||||
movl %ecx,Lv0
|
||||
movl %eax,Lceilv0
|
||||
jmp LCalcSecond
|
||||
|
||||
// }
|
||||
|
||||
LCalcFirst:
|
||||
|
||||
// else
|
||||
// {
|
||||
// world = &pv0->position[0];
|
||||
|
||||
call LTransformAndProject // v0 | lzi0 | u0
|
||||
|
||||
fsts Lv0
|
||||
fxch %st(2) // u0 | lzi0 | v0
|
||||
fstps Lu0 // lzi0 | v0
|
||||
fstps Lzi0 // v0
|
||||
|
||||
// ceilv0 = (int)(v0 - 2000) + 2000; // ceil(v0);
|
||||
fistpl Lceilv0
|
||||
|
||||
// }
|
||||
|
||||
LCalcSecond:
|
||||
|
||||
// world = &pv1->position[0];
|
||||
movl %edx,%esi
|
||||
|
||||
call LTransformAndProject // v1 | lzi1 | u1
|
||||
|
||||
flds Lu0 // u0 | v1 | lzi1 | u1
|
||||
fxch %st(3) // u1 | v1 | lzi1 | u0
|
||||
flds Lzi0 // lzi0 | u1 | v1 | lzi1 | u0
|
||||
fxch %st(3) // lzi1 | u1 | v1 | lzi0 | u0
|
||||
flds Lv0 // v0 | lzi1 | u1 | v1 | lzi0 | u0
|
||||
fxch %st(3) // v1 | lzi1 | u1 | v0 | lzi0 | u0
|
||||
|
||||
// r_ceilv1 = (int)(r_v1 - 2000) + 2000; // ceil(r_v1);
|
||||
fistl C(r_ceilv1)
|
||||
|
||||
fldcw single_cw // put back normal floating-point state
|
||||
|
||||
fsts C(r_v1)
|
||||
fxch %st(4) // lzi0 | lzi1 | u1 | v0 | v1 | u0
|
||||
|
||||
// if (r_lzi1 > lzi0)
|
||||
// lzi0 = r_lzi1;
|
||||
fcom %st(1)
|
||||
fnstsw %ax
|
||||
testb $1,%ah
|
||||
jz LP0
|
||||
fstp %st(0)
|
||||
fld %st(0)
|
||||
LP0:
|
||||
|
||||
fxch %st(1) // lzi1 | lzi0 | u1 | v0 | v1 | u0
|
||||
fstps C(r_lzi1) // lzi0 | u1 | v0 | v1 | u0
|
||||
fxch %st(1)
|
||||
fsts C(r_u1)
|
||||
fxch %st(1)
|
||||
|
||||
// if (lzi0 > r_nearzi) // for mipmap finding
|
||||
// r_nearzi = lzi0;
|
||||
fcoms C(r_nearzi)
|
||||
fnstsw %ax
|
||||
testb $0x45,%ah
|
||||
jnz LP1
|
||||
fsts C(r_nearzi)
|
||||
LP1:
|
||||
|
||||
// // for right edges, all we want is the effect on 1/z
|
||||
// if (r_nearzionly)
|
||||
// return;
|
||||
movl C(r_nearzionly),%eax
|
||||
testl %eax,%eax
|
||||
jz LP2
|
||||
LPop5AndDone:
|
||||
movl C(cacheoffset),%eax
|
||||
movl C(r_framecount),%edx
|
||||
cmpl $0x7FFFFFFF,%eax
|
||||
jz LDoPop
|
||||
andl $(FRAMECOUNT_MASK),%edx
|
||||
orl $(FULLY_CLIPPED_CACHED),%edx
|
||||
movl %edx,C(cacheoffset)
|
||||
|
||||
LDoPop:
|
||||
fstp %st(0) // u1 | v0 | v1 | u0
|
||||
fstp %st(0) // v0 | v1 | u0
|
||||
fstp %st(0) // v1 | u0
|
||||
fstp %st(0) // u0
|
||||
fstp %st(0)
|
||||
jmp Ldone
|
||||
|
||||
LP2:
|
||||
|
||||
// // create the edge
|
||||
// if (ceilv0 == r_ceilv1)
|
||||
// return; // horizontal edge
|
||||
movl Lceilv0,%ebx
|
||||
movl C(edge_p),%edi
|
||||
movl C(r_ceilv1),%ecx
|
||||
movl %edi,%edx
|
||||
movl C(r_pedge),%esi
|
||||
addl $(et_size),%edx
|
||||
cmpl %ecx,%ebx
|
||||
jz LPop5AndDone
|
||||
|
||||
movl C(r_pedge),%eax
|
||||
movl %eax,et_owner(%edi)
|
||||
|
||||
// side = ceilv0 > r_ceilv1;
|
||||
//
|
||||
// edge->nearzi = lzi0;
|
||||
fstps et_nearzi(%edi) // u1 | v0 | v1 | u0
|
||||
|
||||
// if (side == 1)
|
||||
// {
|
||||
jc LSide0
|
||||
|
||||
LSide1:
|
||||
|
||||
// // leading edge (go from p2 to p1)
|
||||
|
||||
// u_step = ((u0 - r_u1) / (v0 - r_v1));
|
||||
fsubrp %st(0),%st(3) // v0 | v1 | u0-u1
|
||||
fsub %st(1),%st(0) // v0-v1 | v1 | u0-u1
|
||||
fdivrp %st(0),%st(2) // v1 | ustep
|
||||
|
||||
// r_emitted = 1;
|
||||
movl $1,C(r_emitted)
|
||||
|
||||
// edge = edge_p++;
|
||||
movl %edx,C(edge_p)
|
||||
|
||||
// pretouch next edge
|
||||
movl (%edx),%eax
|
||||
|
||||
// v2 = ceilv0 - 1;
|
||||
// v = r_ceilv1;
|
||||
movl %ecx,%eax
|
||||
leal -1(%ebx),%ecx
|
||||
movl %eax,%ebx
|
||||
|
||||
// edge->surfs[0] = 0;
|
||||
// edge->surfs[1] = surface_p - surfaces;
|
||||
movl C(surface_p),%eax
|
||||
movl C(surfaces),%esi
|
||||
subl %edx,%edx
|
||||
subl %esi,%eax
|
||||
shrl $(SURF_T_SHIFT),%eax
|
||||
movl %edx,et_surfs(%edi)
|
||||
movl %eax,et_surfs+2(%edi)
|
||||
|
||||
subl %esi,%esi
|
||||
|
||||
// u = r_u1 + ((float)v - r_v1) * u_step;
|
||||
movl %ebx,Lv
|
||||
fildl Lv // v | v1 | ustep
|
||||
fsubp %st(0),%st(1) // v-v1 | ustep
|
||||
fmul %st(1),%st(0) // (v-v1)*ustep | ustep
|
||||
fadds C(r_u1) // u | ustep
|
||||
|
||||
jmp LSideDone
|
||||
|
||||
// }
|
||||
|
||||
LSide0:
|
||||
|
||||
// else
|
||||
// {
|
||||
// // trailing edge (go from p1 to p2)
|
||||
|
||||
// u_step = ((r_u1 - u0) / (r_v1 - v0));
|
||||
fsub %st(3),%st(0) // u1-u0 | v0 | v1 | u0
|
||||
fxch %st(2) // v1 | v0 | u1-u0 | u0
|
||||
fsub %st(1),%st(0) // v1-v0 | v0 | u1-u0 | u0
|
||||
fdivrp %st(0),%st(2) // v0 | ustep | u0
|
||||
|
||||
// r_emitted = 1;
|
||||
movl $1,C(r_emitted)
|
||||
|
||||
// edge = edge_p++;
|
||||
movl %edx,C(edge_p)
|
||||
|
||||
// pretouch next edge
|
||||
movl (%edx),%eax
|
||||
|
||||
// v = ceilv0;
|
||||
// v2 = r_ceilv1 - 1;
|
||||
decl %ecx
|
||||
|
||||
// edge->surfs[0] = surface_p - surfaces;
|
||||
// edge->surfs[1] = 0;
|
||||
movl C(surface_p),%eax
|
||||
movl C(surfaces),%esi
|
||||
subl %edx,%edx
|
||||
subl %esi,%eax
|
||||
shrl $(SURF_T_SHIFT),%eax
|
||||
movl %edx,et_surfs+2(%edi)
|
||||
movl %eax,et_surfs(%edi)
|
||||
|
||||
movl $1,%esi
|
||||
|
||||
// u = u0 + ((float)v - v0) * u_step;
|
||||
movl %ebx,Lv
|
||||
fildl Lv // v | v0 | ustep | u0
|
||||
fsubp %st(0),%st(1) // v-v0 | ustep | u0
|
||||
fmul %st(1),%st(0) // (v-v0)*ustep | ustep | u0
|
||||
faddp %st(0),%st(2) // ustep | u
|
||||
fxch %st(1) // u | ustep
|
||||
|
||||
// }
|
||||
|
||||
LSideDone:
|
||||
|
||||
// edge->u_step = u_step*0x100000;
|
||||
// edge->u = u*0x100000 + 0xFFFFF;
|
||||
|
||||
fmuls fp_1m // u*0x100000 | ustep
|
||||
fxch %st(1) // ustep | u*0x100000
|
||||
fmuls fp_1m // ustep*0x100000 | u*0x100000
|
||||
fxch %st(1) // u*0x100000 | ustep*0x100000
|
||||
fadds fp_1m_minus_1 // u*0x100000 + 0xFFFFF | ustep*0x100000
|
||||
fxch %st(1) // ustep*0x100000 | u*0x100000 + 0xFFFFF
|
||||
fistpl et_u_step(%edi) // u*0x100000 + 0xFFFFF
|
||||
fistpl et_u(%edi)
|
||||
|
||||
// // we need to do this to avoid stepping off the edges if a very nearly
|
||||
// // horizontal edge is less than epsilon above a scan, and numeric error
|
||||
// // causes it to incorrectly extend to the scan, and the extension of the
|
||||
// // line goes off the edge of the screen
|
||||
// // FIXME: is this actually needed?
|
||||
// if (edge->u < r_refdef.vrect_x_adj_shift20)
|
||||
// edge->u = r_refdef.vrect_x_adj_shift20;
|
||||
// if (edge->u > r_refdef.vrectright_adj_shift20)
|
||||
// edge->u = r_refdef.vrectright_adj_shift20;
|
||||
movl et_u(%edi),%eax
|
||||
movl C(r_refdef)+rd_vrect_x_adj_shift20,%edx
|
||||
cmpl %edx,%eax
|
||||
jl LP4
|
||||
movl C(r_refdef)+rd_vrectright_adj_shift20,%edx
|
||||
cmpl %edx,%eax
|
||||
jng LP5
|
||||
LP4:
|
||||
movl %edx,et_u(%edi)
|
||||
movl %edx,%eax
|
||||
LP5:
|
||||
|
||||
// // sort the edge in normally
|
||||
// u_check = edge->u;
|
||||
//
|
||||
// if (edge->surfs[0])
|
||||
// u_check++; // sort trailers after leaders
|
||||
addl %esi,%eax
|
||||
|
||||
// if (!newedges[v] || newedges[v]->u >= u_check)
|
||||
// {
|
||||
movl C(newedges)(,%ebx,4),%esi
|
||||
testl %esi,%esi
|
||||
jz LDoFirst
|
||||
cmpl %eax,et_u(%esi)
|
||||
jl LNotFirst
|
||||
LDoFirst:
|
||||
|
||||
// edge->next = newedges[v];
|
||||
// newedges[v] = edge;
|
||||
movl %esi,et_next(%edi)
|
||||
movl %edi,C(newedges)(,%ebx,4)
|
||||
|
||||
jmp LSetRemove
|
||||
|
||||
// }
|
||||
|
||||
LNotFirst:
|
||||
|
||||
// else
|
||||
// {
|
||||
// pcheck = newedges[v];
|
||||
//
|
||||
// while (pcheck->next && pcheck->next->u < u_check)
|
||||
// pcheck = pcheck->next;
|
||||
LFindInsertLoop:
|
||||
movl %esi,%edx
|
||||
movl et_next(%esi),%esi
|
||||
testl %esi,%esi
|
||||
jz LInsertFound
|
||||
cmpl %eax,et_u(%esi)
|
||||
jl LFindInsertLoop
|
||||
|
||||
LInsertFound:
|
||||
|
||||
// edge->next = pcheck->next;
|
||||
// pcheck->next = edge;
|
||||
movl %esi,et_next(%edi)
|
||||
movl %edi,et_next(%edx)
|
||||
|
||||
// }
|
||||
|
||||
LSetRemove:
|
||||
|
||||
// edge->nextremove = removeedges[v2];
|
||||
// removeedges[v2] = edge;
|
||||
movl C(removeedges)(,%ecx,4),%eax
|
||||
movl %edi,C(removeedges)(,%ecx,4)
|
||||
movl %eax,et_nextremove(%edi)
|
||||
|
||||
Ldone:
|
||||
movl Lstack,%esp // clear temporary variables from stack
|
||||
|
||||
popl %ebx // restore register variables
|
||||
popl %edi
|
||||
popl %esi
|
||||
ret
|
||||
|
||||
// at least one point is clipped
|
||||
|
||||
Lp2:
|
||||
testl %eax,%eax
|
||||
jns Lp1
|
||||
|
||||
// else
|
||||
// {
|
||||
// // point 0 is clipped
|
||||
|
||||
// if (d1 < 0)
|
||||
// {
|
||||
movl Ld1,%eax
|
||||
testl %eax,%eax
|
||||
jns Lp3
|
||||
|
||||
// // both points are clipped
|
||||
// // we do cache fully clipped edges
|
||||
// if (!leftclipped)
|
||||
movl C(r_leftclipped),%eax
|
||||
movl C(r_pedge),%ecx
|
||||
testl %eax,%eax
|
||||
jnz Ldone
|
||||
|
||||
// r_pedge->framecount = r_framecount;
|
||||
movl C(r_framecount),%eax
|
||||
andl $(FRAMECOUNT_MASK),%eax
|
||||
orl $(FULLY_CLIPPED_CACHED),%eax
|
||||
movl %eax,C(cacheoffset)
|
||||
|
||||
// return;
|
||||
jmp Ldone
|
||||
|
||||
// }
|
||||
|
||||
Lp1:
|
||||
|
||||
// // point 0 is unclipped
|
||||
// if (d1 >= 0)
|
||||
// {
|
||||
// // both points are unclipped
|
||||
// continue;
|
||||
|
||||
// // only point 1 is clipped
|
||||
|
||||
// f = d0 / (d0 - d1);
|
||||
flds Ld0
|
||||
flds Ld1
|
||||
fsubr %st(1),%st(0)
|
||||
|
||||
// // we don't cache partially clipped edges
|
||||
movl $0x7FFFFFFF,C(cacheoffset)
|
||||
|
||||
fdivrp %st(0),%st(1)
|
||||
|
||||
subl $(mv_size),%esp // allocate space for clipvert
|
||||
|
||||
// clipvert.position[0] = pv0->position[0] +
|
||||
// f * (pv1->position[0] - pv0->position[0]);
|
||||
// clipvert.position[1] = pv0->position[1] +
|
||||
// f * (pv1->position[1] - pv0->position[1]);
|
||||
// clipvert.position[2] = pv0->position[2] +
|
||||
// f * (pv1->position[2] - pv0->position[2]);
|
||||
flds mv_position+8(%edx)
|
||||
fsubs mv_position+8(%esi)
|
||||
flds mv_position+4(%edx)
|
||||
fsubs mv_position+4(%esi)
|
||||
flds mv_position+0(%edx)
|
||||
fsubs mv_position+0(%esi) // 0 | 1 | 2
|
||||
|
||||
// replace pv1 with the clip point
|
||||
movl %esp,%edx
|
||||
movl cp_leftedge(%ebx),%eax
|
||||
testb %al,%al
|
||||
|
||||
fmul %st(3),%st(0)
|
||||
fxch %st(1) // 1 | 0 | 2
|
||||
fmul %st(3),%st(0)
|
||||
fxch %st(2) // 2 | 0 | 1
|
||||
fmulp %st(0),%st(3) // 0 | 1 | 2
|
||||
fadds mv_position+0(%esi)
|
||||
fxch %st(1) // 1 | 0 | 2
|
||||
fadds mv_position+4(%esi)
|
||||
fxch %st(2) // 2 | 0 | 1
|
||||
fadds mv_position+8(%esi)
|
||||
fxch %st(1) // 0 | 2 | 1
|
||||
fstps mv_position+0(%esp) // 2 | 1
|
||||
fstps mv_position+8(%esp) // 1
|
||||
fstps mv_position+4(%esp)
|
||||
|
||||
// if (clip->leftedge)
|
||||
// {
|
||||
jz Ltestright
|
||||
|
||||
// r_leftclipped = true;
|
||||
// r_leftexit = clipvert;
|
||||
movl $1,C(r_leftclipped)
|
||||
movl mv_position+0(%esp),%eax
|
||||
movl %eax,C(r_leftexit)+mv_position+0
|
||||
movl mv_position+4(%esp),%eax
|
||||
movl %eax,C(r_leftexit)+mv_position+4
|
||||
movl mv_position+8(%esp),%eax
|
||||
movl %eax,C(r_leftexit)+mv_position+8
|
||||
|
||||
jmp Lcontinue
|
||||
|
||||
// }
|
||||
|
||||
Ltestright:
|
||||
// else if (clip->rightedge)
|
||||
// {
|
||||
testb %ah,%ah
|
||||
jz Lcontinue
|
||||
|
||||
// r_rightclipped = true;
|
||||
// r_rightexit = clipvert;
|
||||
movl $1,C(r_rightclipped)
|
||||
movl mv_position+0(%esp),%eax
|
||||
movl %eax,C(r_rightexit)+mv_position+0
|
||||
movl mv_position+4(%esp),%eax
|
||||
movl %eax,C(r_rightexit)+mv_position+4
|
||||
movl mv_position+8(%esp),%eax
|
||||
movl %eax,C(r_rightexit)+mv_position+8
|
||||
|
||||
// }
|
||||
//
|
||||
// R_ClipEdge (pv0, &clipvert, clip->next);
|
||||
// return;
|
||||
// }
|
||||
jmp Lcontinue
|
||||
|
||||
// }
|
||||
|
||||
Lp3:
|
||||
|
||||
// // only point 0 is clipped
|
||||
// r_lastvertvalid = false;
|
||||
|
||||
movl $0,C(r_lastvertvalid)
|
||||
|
||||
// f = d0 / (d0 - d1);
|
||||
flds Ld0
|
||||
flds Ld1
|
||||
fsubr %st(1),%st(0)
|
||||
|
||||
// // we don't cache partially clipped edges
|
||||
movl $0x7FFFFFFF,C(cacheoffset)
|
||||
|
||||
fdivrp %st(0),%st(1)
|
||||
|
||||
subl $(mv_size),%esp // allocate space for clipvert
|
||||
|
||||
// clipvert.position[0] = pv0->position[0] +
|
||||
// f * (pv1->position[0] - pv0->position[0]);
|
||||
// clipvert.position[1] = pv0->position[1] +
|
||||
// f * (pv1->position[1] - pv0->position[1]);
|
||||
// clipvert.position[2] = pv0->position[2] +
|
||||
// f * (pv1->position[2] - pv0->position[2]);
|
||||
flds mv_position+8(%edx)
|
||||
fsubs mv_position+8(%esi)
|
||||
flds mv_position+4(%edx)
|
||||
fsubs mv_position+4(%esi)
|
||||
flds mv_position+0(%edx)
|
||||
fsubs mv_position+0(%esi) // 0 | 1 | 2
|
||||
|
||||
movl cp_leftedge(%ebx),%eax
|
||||
testb %al,%al
|
||||
|
||||
fmul %st(3),%st(0)
|
||||
fxch %st(1) // 1 | 0 | 2
|
||||
fmul %st(3),%st(0)
|
||||
fxch %st(2) // 2 | 0 | 1
|
||||
fmulp %st(0),%st(3) // 0 | 1 | 2
|
||||
fadds mv_position+0(%esi)
|
||||
fxch %st(1) // 1 | 0 | 2
|
||||
fadds mv_position+4(%esi)
|
||||
fxch %st(2) // 2 | 0 | 1
|
||||
fadds mv_position+8(%esi)
|
||||
fxch %st(1) // 0 | 2 | 1
|
||||
fstps mv_position+0(%esp) // 2 | 1
|
||||
fstps mv_position+8(%esp) // 1
|
||||
fstps mv_position+4(%esp)
|
||||
|
||||
// replace pv0 with the clip point
|
||||
movl %esp,%esi
|
||||
|
||||
// if (clip->leftedge)
|
||||
// {
|
||||
jz Ltestright2
|
||||
|
||||
// r_leftclipped = true;
|
||||
// r_leftenter = clipvert;
|
||||
movl $1,C(r_leftclipped)
|
||||
movl mv_position+0(%esp),%eax
|
||||
movl %eax,C(r_leftenter)+mv_position+0
|
||||
movl mv_position+4(%esp),%eax
|
||||
movl %eax,C(r_leftenter)+mv_position+4
|
||||
movl mv_position+8(%esp),%eax
|
||||
movl %eax,C(r_leftenter)+mv_position+8
|
||||
|
||||
jmp Lcontinue
|
||||
|
||||
// }
|
||||
|
||||
Ltestright2:
|
||||
// else if (clip->rightedge)
|
||||
// {
|
||||
testb %ah,%ah
|
||||
jz Lcontinue
|
||||
|
||||
// r_rightclipped = true;
|
||||
// r_rightenter = clipvert;
|
||||
movl $1,C(r_rightclipped)
|
||||
movl mv_position+0(%esp),%eax
|
||||
movl %eax,C(r_rightenter)+mv_position+0
|
||||
movl mv_position+4(%esp),%eax
|
||||
movl %eax,C(r_rightenter)+mv_position+4
|
||||
movl mv_position+8(%esp),%eax
|
||||
movl %eax,C(r_rightenter)+mv_position+8
|
||||
|
||||
// }
|
||||
jmp Lcontinue
|
||||
|
||||
// %esi = vec3_t point to transform and project
|
||||
// %edx preserved
|
||||
LTransformAndProject:
|
||||
|
||||
// // transform and project
|
||||
// VectorSubtract (world, modelorg, local);
|
||||
flds mv_position+0(%esi)
|
||||
fsubs C(modelorg)+0
|
||||
flds mv_position+4(%esi)
|
||||
fsubs C(modelorg)+4
|
||||
flds mv_position+8(%esi)
|
||||
fsubs C(modelorg)+8
|
||||
fxch %st(2) // local[0] | local[1] | local[2]
|
||||
|
||||
// TransformVector (local, transformed);
|
||||
//
|
||||
// if (transformed[2] < NEAR_CLIP)
|
||||
// transformed[2] = NEAR_CLIP;
|
||||
//
|
||||
// lzi0 = 1.0 / transformed[2];
|
||||
fld %st(0) // local[0] | local[0] | local[1] | local[2]
|
||||
fmuls C(vpn)+0 // zm0 | local[0] | local[1] | local[2]
|
||||
fld %st(1) // local[0] | zm0 | local[0] | local[1] |
|
||||
// local[2]
|
||||
fmuls C(vright)+0 // xm0 | zm0 | local[0] | local[1] | local[2]
|
||||
fxch %st(2) // local[0] | zm0 | xm0 | local[1] | local[2]
|
||||
fmuls C(vup)+0 // ym0 | zm0 | xm0 | local[1] | local[2]
|
||||
fld %st(3) // local[1] | ym0 | zm0 | xm0 | local[1] |
|
||||
// local[2]
|
||||
fmuls C(vpn)+4 // zm1 | ym0 | zm0 | xm0 | local[1] |
|
||||
// local[2]
|
||||
fld %st(4) // local[1] | zm1 | ym0 | zm0 | xm0 |
|
||||
// local[1] | local[2]
|
||||
fmuls C(vright)+4 // xm1 | zm1 | ym0 | zm0 | xm0 |
|
||||
// local[1] | local[2]
|
||||
fxch %st(5) // local[1] | zm1 | ym0 | zm0 | xm0 |
|
||||
// xm1 | local[2]
|
||||
fmuls C(vup)+4 // ym1 | zm1 | ym0 | zm0 | xm0 |
|
||||
// xm1 | local[2]
|
||||
fxch %st(1) // zm1 | ym1 | ym0 | zm0 | xm0 |
|
||||
// xm1 | local[2]
|
||||
faddp %st(0),%st(3) // ym1 | ym0 | zm2 | xm0 | xm1 | local[2]
|
||||
fxch %st(3) // xm0 | ym0 | zm2 | ym1 | xm1 | local[2]
|
||||
faddp %st(0),%st(4) // ym0 | zm2 | ym1 | xm2 | local[2]
|
||||
faddp %st(0),%st(2) // zm2 | ym2 | xm2 | local[2]
|
||||
fld %st(3) // local[2] | zm2 | ym2 | xm2 | local[2]
|
||||
fmuls C(vpn)+8 // zm3 | zm2 | ym2 | xm2 | local[2]
|
||||
fld %st(4) // local[2] | zm3 | zm2 | ym2 | xm2 | local[2]
|
||||
fmuls C(vright)+8 // xm3 | zm3 | zm2 | ym2 | xm2 | local[2]
|
||||
fxch %st(5) // local[2] | zm3 | zm2 | ym2 | xm2 | xm3
|
||||
fmuls C(vup)+8 // ym3 | zm3 | zm2 | ym2 | xm2 | xm3
|
||||
fxch %st(1) // zm3 | ym3 | zm2 | ym2 | xm2 | xm3
|
||||
faddp %st(0),%st(2) // ym3 | zm4 | ym2 | xm2 | xm3
|
||||
fxch %st(4) // xm3 | zm4 | ym2 | xm2 | ym3
|
||||
faddp %st(0),%st(3) // zm4 | ym2 | xm4 | ym3
|
||||
fxch %st(1) // ym2 | zm4 | xm4 | ym3
|
||||
faddp %st(0),%st(3) // zm4 | xm4 | ym4
|
||||
|
||||
fcoms Lfp_near_clip
|
||||
fnstsw %ax
|
||||
testb $1,%ah
|
||||
jz LNoClip
|
||||
fstp %st(0)
|
||||
flds Lfp_near_clip
|
||||
|
||||
LNoClip:
|
||||
|
||||
fdivrs float_1 // lzi0 | x | y
|
||||
fxch %st(1) // x | lzi0 | y
|
||||
|
||||
// // FIXME: build x/yscale into transform?
|
||||
// scale = xscale * lzi0;
|
||||
// u0 = (xcenter + scale*transformed[0]);
|
||||
flds C(xscale) // xscale | x | lzi0 | y
|
||||
fmul %st(2),%st(0) // scale | x | lzi0 | y
|
||||
fmulp %st(0),%st(1) // scale*x | lzi0 | y
|
||||
fadds C(xcenter) // u0 | lzi0 | y
|
||||
|
||||
// if (u0 < r_refdef.fvrectx_adj)
|
||||
// u0 = r_refdef.fvrectx_adj;
|
||||
// if (u0 > r_refdef.fvrectright_adj)
|
||||
// u0 = r_refdef.fvrectright_adj;
|
||||
// FIXME: use integer compares of floats?
|
||||
fcoms C(r_refdef)+rd_fvrectx_adj
|
||||
fnstsw %ax
|
||||
testb $1,%ah
|
||||
jz LClampP0
|
||||
fstp %st(0)
|
||||
flds C(r_refdef)+rd_fvrectx_adj
|
||||
LClampP0:
|
||||
fcoms C(r_refdef)+rd_fvrectright_adj
|
||||
fnstsw %ax
|
||||
testb $0x45,%ah
|
||||
jnz LClampP1
|
||||
fstp %st(0)
|
||||
flds C(r_refdef)+rd_fvrectright_adj
|
||||
LClampP1:
|
||||
|
||||
fld %st(1) // lzi0 | u0 | lzi0 | y
|
||||
|
||||
// scale = yscale * lzi0;
|
||||
// v0 = (ycenter - scale*transformed[1]);
|
||||
fmuls C(yscale) // scale | u0 | lzi0 | y
|
||||
fmulp %st(0),%st(3) // u0 | lzi0 | scale*y
|
||||
fxch %st(2) // scale*y | lzi0 | u0
|
||||
fsubrs C(ycenter) // v0 | lzi0 | u0
|
||||
|
||||
// if (v0 < r_refdef.fvrecty_adj)
|
||||
// v0 = r_refdef.fvrecty_adj;
|
||||
// if (v0 > r_refdef.fvrectbottom_adj)
|
||||
// v0 = r_refdef.fvrectbottom_adj;
|
||||
// FIXME: use integer compares of floats?
|
||||
fcoms C(r_refdef)+rd_fvrecty_adj
|
||||
fnstsw %ax
|
||||
testb $1,%ah
|
||||
jz LClampP2
|
||||
fstp %st(0)
|
||||
flds C(r_refdef)+rd_fvrecty_adj
|
||||
LClampP2:
|
||||
fcoms C(r_refdef)+rd_fvrectbottom_adj
|
||||
fnstsw %ax
|
||||
testb $0x45,%ah
|
||||
jnz LClampP3
|
||||
fstp %st(0)
|
||||
flds C(r_refdef)+rd_fvrectbottom_adj
|
||||
LClampP3:
|
||||
ret
|
||||
|
||||
#endif // id386
|
||||
|
729
linux/r_edgea.s
Normal file
729
linux/r_edgea.s
Normal file
@ -0,0 +1,729 @@
|
||||
//
|
||||
// r_edgea.s
|
||||
// x86 assembly-language edge-processing code.
|
||||
//
|
||||
|
||||
#include "qasm.h"
|
||||
|
||||
#if id386
|
||||
|
||||
.data
|
||||
Ltemp: .long 0
|
||||
float_1_div_0100000h: .long 0x35800000 // 1.0/(float)0x100000
|
||||
float_point_999: .single 0.999
|
||||
float_1_point_001: .single 1.001
|
||||
|
||||
.text
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
|
||||
#define edgestoadd 4+8 // note odd stack offsets because of interleaving
|
||||
#define edgelist 8+12 // with pushes
|
||||
|
||||
.globl C(R_EdgeCodeStart)
|
||||
C(R_EdgeCodeStart):
|
||||
|
||||
.globl C(R_InsertNewEdges)
|
||||
C(R_InsertNewEdges):
|
||||
pushl %edi
|
||||
pushl %esi // preserve register variables
|
||||
movl edgestoadd(%esp),%edx
|
||||
pushl %ebx
|
||||
movl edgelist(%esp),%ecx
|
||||
|
||||
LDoNextEdge:
|
||||
movl et_u(%edx),%eax
|
||||
movl %edx,%edi
|
||||
|
||||
LContinueSearch:
|
||||
movl et_u(%ecx),%ebx
|
||||
movl et_next(%ecx),%esi
|
||||
cmpl %ebx,%eax
|
||||
jle LAddedge
|
||||
movl et_u(%esi),%ebx
|
||||
movl et_next(%esi),%ecx
|
||||
cmpl %ebx,%eax
|
||||
jle LAddedge2
|
||||
movl et_u(%ecx),%ebx
|
||||
movl et_next(%ecx),%esi
|
||||
cmpl %ebx,%eax
|
||||
jle LAddedge
|
||||
movl et_u(%esi),%ebx
|
||||
movl et_next(%esi),%ecx
|
||||
cmpl %ebx,%eax
|
||||
jg LContinueSearch
|
||||
|
||||
LAddedge2:
|
||||
movl et_next(%edx),%edx
|
||||
movl et_prev(%esi),%ebx
|
||||
movl %esi,et_next(%edi)
|
||||
movl %ebx,et_prev(%edi)
|
||||
movl %edi,et_next(%ebx)
|
||||
movl %edi,et_prev(%esi)
|
||||
movl %esi,%ecx
|
||||
|
||||
cmpl $0,%edx
|
||||
jnz LDoNextEdge
|
||||
jmp LDone
|
||||
|
||||
.align 4
|
||||
LAddedge:
|
||||
movl et_next(%edx),%edx
|
||||
movl et_prev(%ecx),%ebx
|
||||
movl %ecx,et_next(%edi)
|
||||
movl %ebx,et_prev(%edi)
|
||||
movl %edi,et_next(%ebx)
|
||||
movl %edi,et_prev(%ecx)
|
||||
|
||||
cmpl $0,%edx
|
||||
jnz LDoNextEdge
|
||||
|
||||
LDone:
|
||||
popl %ebx // restore register variables
|
||||
popl %esi
|
||||
popl %edi
|
||||
|
||||
ret
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
|
||||
#define predge 4+4
|
||||
|
||||
.globl C(R_RemoveEdges)
|
||||
C(R_RemoveEdges):
|
||||
pushl %ebx
|
||||
movl predge(%esp),%eax
|
||||
|
||||
Lre_loop:
|
||||
movl et_next(%eax),%ecx
|
||||
movl et_nextremove(%eax),%ebx
|
||||
movl et_prev(%eax),%edx
|
||||
testl %ebx,%ebx
|
||||
movl %edx,et_prev(%ecx)
|
||||
jz Lre_done
|
||||
movl %ecx,et_next(%edx)
|
||||
|
||||
movl et_next(%ebx),%ecx
|
||||
movl et_prev(%ebx),%edx
|
||||
movl et_nextremove(%ebx),%eax
|
||||
movl %edx,et_prev(%ecx)
|
||||
testl %eax,%eax
|
||||
movl %ecx,et_next(%edx)
|
||||
jnz Lre_loop
|
||||
|
||||
popl %ebx
|
||||
ret
|
||||
|
||||
Lre_done:
|
||||
movl %ecx,et_next(%edx)
|
||||
popl %ebx
|
||||
|
||||
ret
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
|
||||
#define pedgelist 4+4 // note odd stack offset because of interleaving
|
||||
// with pushes
|
||||
|
||||
.globl C(R_StepActiveU)
|
||||
C(R_StepActiveU):
|
||||
pushl %edi
|
||||
movl pedgelist(%esp),%edx
|
||||
pushl %esi // preserve register variables
|
||||
pushl %ebx
|
||||
|
||||
movl et_prev(%edx),%esi
|
||||
|
||||
LNewEdge:
|
||||
movl et_u(%esi),%edi
|
||||
|
||||
LNextEdge:
|
||||
movl et_u(%edx),%eax
|
||||
movl et_u_step(%edx),%ebx
|
||||
addl %ebx,%eax
|
||||
movl et_next(%edx),%esi
|
||||
movl %eax,et_u(%edx)
|
||||
cmpl %edi,%eax
|
||||
jl LPushBack
|
||||
|
||||
movl et_u(%esi),%edi
|
||||
movl et_u_step(%esi),%ebx
|
||||
addl %ebx,%edi
|
||||
movl et_next(%esi),%edx
|
||||
movl %edi,et_u(%esi)
|
||||
cmpl %eax,%edi
|
||||
jl LPushBack2
|
||||
|
||||
movl et_u(%edx),%eax
|
||||
movl et_u_step(%edx),%ebx
|
||||
addl %ebx,%eax
|
||||
movl et_next(%edx),%esi
|
||||
movl %eax,et_u(%edx)
|
||||
cmpl %edi,%eax
|
||||
jl LPushBack
|
||||
|
||||
movl et_u(%esi),%edi
|
||||
movl et_u_step(%esi),%ebx
|
||||
addl %ebx,%edi
|
||||
movl et_next(%esi),%edx
|
||||
movl %edi,et_u(%esi)
|
||||
cmpl %eax,%edi
|
||||
jnl LNextEdge
|
||||
|
||||
LPushBack2:
|
||||
movl %edx,%ebx
|
||||
movl %edi,%eax
|
||||
movl %esi,%edx
|
||||
movl %ebx,%esi
|
||||
|
||||
LPushBack:
|
||||
// push it back to keep it sorted
|
||||
movl et_prev(%edx),%ecx
|
||||
movl et_next(%edx),%ebx
|
||||
|
||||
// done if the -1 in edge_aftertail triggered this
|
||||
cmpl $(C(edge_aftertail)),%edx
|
||||
jz LUDone
|
||||
|
||||
// pull the edge out of the edge list
|
||||
movl et_prev(%ecx),%edi
|
||||
movl %ecx,et_prev(%esi)
|
||||
movl %ebx,et_next(%ecx)
|
||||
|
||||
// find out where the edge goes in the edge list
|
||||
LPushBackLoop:
|
||||
movl et_prev(%edi),%ecx
|
||||
movl et_u(%edi),%ebx
|
||||
cmpl %ebx,%eax
|
||||
jnl LPushBackFound
|
||||
|
||||
movl et_prev(%ecx),%edi
|
||||
movl et_u(%ecx),%ebx
|
||||
cmpl %ebx,%eax
|
||||
jl LPushBackLoop
|
||||
|
||||
movl %ecx,%edi
|
||||
|
||||
// put the edge back into the edge list
|
||||
LPushBackFound:
|
||||
movl et_next(%edi),%ebx
|
||||
movl %edi,et_prev(%edx)
|
||||
movl %ebx,et_next(%edx)
|
||||
movl %edx,et_next(%edi)
|
||||
movl %edx,et_prev(%ebx)
|
||||
|
||||
movl %esi,%edx
|
||||
movl et_prev(%esi),%esi
|
||||
|
||||
cmpl $(C(edge_tail)),%edx
|
||||
jnz LNewEdge
|
||||
|
||||
LUDone:
|
||||
popl %ebx // restore register variables
|
||||
popl %esi
|
||||
popl %edi
|
||||
|
||||
ret
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
|
||||
#define surf 4 // note this is loaded before any pushes
|
||||
|
||||
.align 4
|
||||
TrailingEdge:
|
||||
movl st_spanstate(%esi),%eax // check for edge inversion
|
||||
decl %eax
|
||||
jnz LInverted
|
||||
|
||||
movl %eax,st_spanstate(%esi)
|
||||
movl st_insubmodel(%esi),%ecx
|
||||
movl 0x12345678,%edx // surfaces[1].st_next
|
||||
LPatch0:
|
||||
movl C(r_bmodelactive),%eax
|
||||
subl %ecx,%eax
|
||||
cmpl %esi,%edx
|
||||
movl %eax,C(r_bmodelactive)
|
||||
jnz LNoEmit // surface isn't on top, just remove
|
||||
|
||||
// emit a span (current top going away)
|
||||
movl et_u(%ebx),%eax
|
||||
shrl $20,%eax // iu = integral pixel u
|
||||
movl st_last_u(%esi),%edx
|
||||
movl st_next(%esi),%ecx
|
||||
cmpl %edx,%eax
|
||||
jle LNoEmit2 // iu <= surf->last_u, so nothing to emit
|
||||
|
||||
movl %eax,st_last_u(%ecx) // surf->next->last_u = iu;
|
||||
subl %edx,%eax
|
||||
movl %edx,espan_t_u(%ebp) // span->u = surf->last_u;
|
||||
|
||||
movl %eax,espan_t_count(%ebp) // span->count = iu - span->u;
|
||||
movl C(current_iv),%eax
|
||||
movl %eax,espan_t_v(%ebp) // span->v = current_iv;
|
||||
movl st_spans(%esi),%eax
|
||||
movl %eax,espan_t_pnext(%ebp) // span->pnext = surf->spans;
|
||||
movl %ebp,st_spans(%esi) // surf->spans = span;
|
||||
addl $(espan_t_size),%ebp
|
||||
|
||||
movl st_next(%esi),%edx // remove the surface from the surface
|
||||
movl st_prev(%esi),%esi // stack
|
||||
|
||||
movl %edx,st_next(%esi)
|
||||
movl %esi,st_prev(%edx)
|
||||
ret
|
||||
|
||||
LNoEmit2:
|
||||
movl %eax,st_last_u(%ecx) // surf->next->last_u = iu;
|
||||
movl st_next(%esi),%edx // remove the surface from the surface
|
||||
movl st_prev(%esi),%esi // stack
|
||||
|
||||
movl %edx,st_next(%esi)
|
||||
movl %esi,st_prev(%edx)
|
||||
ret
|
||||
|
||||
LNoEmit:
|
||||
movl st_next(%esi),%edx // remove the surface from the surface
|
||||
movl st_prev(%esi),%esi // stack
|
||||
|
||||
movl %edx,st_next(%esi)
|
||||
movl %esi,st_prev(%edx)
|
||||
ret
|
||||
|
||||
LInverted:
|
||||
movl %eax,st_spanstate(%esi)
|
||||
ret
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
|
||||
// trailing edge only
|
||||
Lgs_trailing:
|
||||
pushl $Lgs_nextedge
|
||||
jmp TrailingEdge
|
||||
|
||||
|
||||
.globl C(R_GenerateSpans)
|
||||
C(R_GenerateSpans):
|
||||
pushl %ebp // preserve caller's stack frame
|
||||
pushl %edi
|
||||
pushl %esi // preserve register variables
|
||||
pushl %ebx
|
||||
|
||||
// clear active surfaces to just the background surface
|
||||
movl C(surfaces),%eax
|
||||
movl C(edge_head_u_shift20),%edx
|
||||
addl $(st_size),%eax
|
||||
// %ebp = span_p throughout
|
||||
movl C(span_p),%ebp
|
||||
|
||||
movl $0,C(r_bmodelactive)
|
||||
|
||||
movl %eax,st_next(%eax)
|
||||
movl %eax,st_prev(%eax)
|
||||
movl %edx,st_last_u(%eax)
|
||||
movl C(edge_head)+et_next,%ebx // edge=edge_head.next
|
||||
|
||||
// generate spans
|
||||
cmpl $(C(edge_tail)),%ebx // done if empty list
|
||||
jz Lgs_lastspan
|
||||
|
||||
Lgs_edgeloop:
|
||||
|
||||
movl et_surfs(%ebx),%edi
|
||||
movl C(surfaces),%eax
|
||||
movl %edi,%esi
|
||||
andl $0xFFFF0000,%edi
|
||||
andl $0xFFFF,%esi
|
||||
jz Lgs_leading // not a trailing edge
|
||||
|
||||
// it has a left surface, so a surface is going away for this span
|
||||
shll $(SURF_T_SHIFT),%esi
|
||||
addl %eax,%esi
|
||||
testl %edi,%edi
|
||||
jz Lgs_trailing
|
||||
|
||||
// both leading and trailing
|
||||
call TrailingEdge
|
||||
movl C(surfaces),%eax
|
||||
|
||||
// ---------------------------------------------------------------
|
||||
// handle a leading edge
|
||||
// ---------------------------------------------------------------
|
||||
|
||||
Lgs_leading:
|
||||
shrl $16-SURF_T_SHIFT,%edi
|
||||
movl C(surfaces),%eax
|
||||
addl %eax,%edi
|
||||
movl 0x12345678,%esi // surf2 = surfaces[1].next;
|
||||
LPatch2:
|
||||
movl st_spanstate(%edi),%edx
|
||||
movl st_insubmodel(%edi),%eax
|
||||
testl %eax,%eax
|
||||
jnz Lbmodel_leading
|
||||
|
||||
// handle a leading non-bmodel edge
|
||||
|
||||
// don't start a span if this is an inverted span, with the end edge preceding
|
||||
// the start edge (that is, we've already seen the end edge)
|
||||
testl %edx,%edx
|
||||
jnz Lxl_done
|
||||
|
||||
|
||||
// if (surf->key < surf2->key)
|
||||
// goto newtop;
|
||||
incl %edx
|
||||
movl st_key(%edi),%eax
|
||||
movl %edx,st_spanstate(%edi)
|
||||
movl st_key(%esi),%ecx
|
||||
cmpl %ecx,%eax
|
||||
jl Lnewtop
|
||||
|
||||
// main sorting loop to search through surface stack until insertion point
|
||||
// found. Always terminates because background surface is sentinel
|
||||
// do
|
||||
// {
|
||||
// surf2 = surf2->next;
|
||||
// } while (surf->key >= surf2->key);
|
||||
Lsortloopnb:
|
||||
movl st_next(%esi),%esi
|
||||
movl st_key(%esi),%ecx
|
||||
cmpl %ecx,%eax
|
||||
jge Lsortloopnb
|
||||
|
||||
jmp LInsertAndExit
|
||||
|
||||
|
||||
// handle a leading bmodel edge
|
||||
.align 4
|
||||
Lbmodel_leading:
|
||||
|
||||
// don't start a span if this is an inverted span, with the end edge preceding
|
||||
// the start edge (that is, we've already seen the end edge)
|
||||
testl %edx,%edx
|
||||
jnz Lxl_done
|
||||
|
||||
movl C(r_bmodelactive),%ecx
|
||||
incl %edx
|
||||
incl %ecx
|
||||
movl %edx,st_spanstate(%edi)
|
||||
movl %ecx,C(r_bmodelactive)
|
||||
|
||||
// if (surf->key < surf2->key)
|
||||
// goto newtop;
|
||||
movl st_key(%edi),%eax
|
||||
movl st_key(%esi),%ecx
|
||||
cmpl %ecx,%eax
|
||||
jl Lnewtop
|
||||
|
||||
// if ((surf->key == surf2->key) && surf->insubmodel)
|
||||
// {
|
||||
jz Lzcheck_for_newtop
|
||||
|
||||
// main sorting loop to search through surface stack until insertion point
|
||||
// found. Always terminates because background surface is sentinel
|
||||
// do
|
||||
// {
|
||||
// surf2 = surf2->next;
|
||||
// } while (surf->key > surf2->key);
|
||||
Lsortloop:
|
||||
movl st_next(%esi),%esi
|
||||
movl st_key(%esi),%ecx
|
||||
cmpl %ecx,%eax
|
||||
jg Lsortloop
|
||||
|
||||
jne LInsertAndExit
|
||||
|
||||
// Do 1/z sorting to see if we've arrived in the right position
|
||||
movl et_u(%ebx),%eax
|
||||
subl $0xFFFFF,%eax
|
||||
movl %eax,Ltemp
|
||||
fildl Ltemp
|
||||
|
||||
fmuls float_1_div_0100000h // fu = (float)(edge->u - 0xFFFFF) *
|
||||
// (1.0 / 0x100000);
|
||||
|
||||
fld %st(0) // fu | fu
|
||||
fmuls st_d_zistepu(%edi) // fu*surf->d_zistepu | fu
|
||||
flds C(fv) // fv | fu*surf->d_zistepu | fu
|
||||
fmuls st_d_zistepv(%edi) // fv*surf->d_zistepv | fu*surf->d_zistepu | fu
|
||||
fxch %st(1) // fu*surf->d_zistepu | fv*surf->d_zistepv | fu
|
||||
fadds st_d_ziorigin(%edi) // fu*surf->d_zistepu + surf->d_ziorigin |
|
||||
// fv*surf->d_zistepv | fu
|
||||
|
||||
flds st_d_zistepu(%esi) // surf2->d_zistepu |
|
||||
// fu*surf->d_zistepu + surf->d_ziorigin |
|
||||
// fv*surf->d_zistepv | fu
|
||||
fmul %st(3),%st(0) // fu*surf2->d_zistepu |
|
||||
// fu*surf->d_zistepu + surf->d_ziorigin |
|
||||
// fv*surf->d_zistepv | fu
|
||||
fxch %st(1) // fu*surf->d_zistepu + surf->d_ziorigin |
|
||||
// fu*surf2->d_zistepu |
|
||||
// fv*surf->d_zistepv | fu
|
||||
faddp %st(0),%st(2) // fu*surf2->d_zistepu | newzi | fu
|
||||
|
||||
flds C(fv) // fv | fu*surf2->d_zistepu | newzi | fu
|
||||
fmuls st_d_zistepv(%esi) // fv*surf2->d_zistepv |
|
||||
// fu*surf2->d_zistepu | newzi | fu
|
||||
fld %st(2) // newzi | fv*surf2->d_zistepv |
|
||||
// fu*surf2->d_zistepu | newzi | fu
|
||||
fmuls float_point_999 // newzibottom | fv*surf2->d_zistepv |
|
||||
// fu*surf2->d_zistepu | newzi | fu
|
||||
|
||||
fxch %st(2) // fu*surf2->d_zistepu | fv*surf2->d_zistepv |
|
||||
// newzibottom | newzi | fu
|
||||
fadds st_d_ziorigin(%esi) // fu*surf2->d_zistepu + surf2->d_ziorigin |
|
||||
// fv*surf2->d_zistepv | newzibottom | newzi |
|
||||
// fu
|
||||
faddp %st(0),%st(1) // testzi | newzibottom | newzi | fu
|
||||
fxch %st(1) // newzibottom | testzi | newzi | fu
|
||||
|
||||
// if (newzibottom >= testzi)
|
||||
// goto Lgotposition;
|
||||
|
||||
fcomp %st(1) // testzi | newzi | fu
|
||||
|
||||
fxch %st(1) // newzi | testzi | fu
|
||||
fmuls float_1_point_001 // newzitop | testzi | fu
|
||||
fxch %st(1) // testzi | newzitop | fu
|
||||
|
||||
fnstsw %ax
|
||||
testb $0x01,%ah
|
||||
jz Lgotposition_fpop3
|
||||
|
||||
// if (newzitop >= testzi)
|
||||
// {
|
||||
|
||||
fcomp %st(1) // newzitop | fu
|
||||
fnstsw %ax
|
||||
testb $0x45,%ah
|
||||
jz Lsortloop_fpop2
|
||||
|
||||
// if (surf->d_zistepu >= surf2->d_zistepu)
|
||||
// goto newtop;
|
||||
|
||||
flds st_d_zistepu(%edi) // surf->d_zistepu | newzitop| fu
|
||||
fcomps st_d_zistepu(%esi) // newzitop | fu
|
||||
fnstsw %ax
|
||||
testb $0x01,%ah
|
||||
jz Lgotposition_fpop2
|
||||
|
||||
fstp %st(0) // clear the FPstack
|
||||
fstp %st(0)
|
||||
movl st_key(%edi),%eax
|
||||
jmp Lsortloop
|
||||
|
||||
|
||||
Lgotposition_fpop3:
|
||||
fstp %st(0)
|
||||
Lgotposition_fpop2:
|
||||
fstp %st(0)
|
||||
fstp %st(0)
|
||||
jmp LInsertAndExit
|
||||
|
||||
|
||||
// emit a span (obscures current top)
|
||||
|
||||
Lnewtop_fpop3:
|
||||
fstp %st(0)
|
||||
Lnewtop_fpop2:
|
||||
fstp %st(0)
|
||||
fstp %st(0)
|
||||
movl st_key(%edi),%eax // reload the sorting key
|
||||
|
||||
Lnewtop:
|
||||
movl et_u(%ebx),%eax
|
||||
movl st_last_u(%esi),%edx
|
||||
shrl $20,%eax // iu = integral pixel u
|
||||
movl %eax,st_last_u(%edi) // surf->last_u = iu;
|
||||
cmpl %edx,%eax
|
||||
jle LInsertAndExit // iu <= surf->last_u, so nothing to emit
|
||||
|
||||
subl %edx,%eax
|
||||
movl %edx,espan_t_u(%ebp) // span->u = surf->last_u;
|
||||
|
||||
movl %eax,espan_t_count(%ebp) // span->count = iu - span->u;
|
||||
movl C(current_iv),%eax
|
||||
movl %eax,espan_t_v(%ebp) // span->v = current_iv;
|
||||
movl st_spans(%esi),%eax
|
||||
movl %eax,espan_t_pnext(%ebp) // span->pnext = surf->spans;
|
||||
movl %ebp,st_spans(%esi) // surf->spans = span;
|
||||
addl $(espan_t_size),%ebp
|
||||
|
||||
LInsertAndExit:
|
||||
// insert before surf2
|
||||
movl %esi,st_next(%edi) // surf->next = surf2;
|
||||
movl st_prev(%esi),%eax
|
||||
movl %eax,st_prev(%edi) // surf->prev = surf2->prev;
|
||||
movl %edi,st_prev(%esi) // surf2->prev = surf;
|
||||
movl %edi,st_next(%eax) // surf2->prev->next = surf;
|
||||
|
||||
// ---------------------------------------------------------------
|
||||
// leading edge done
|
||||
// ---------------------------------------------------------------
|
||||
|
||||
// ---------------------------------------------------------------
|
||||
// see if there are any more edges
|
||||
// ---------------------------------------------------------------
|
||||
|
||||
Lgs_nextedge:
|
||||
movl et_next(%ebx),%ebx
|
||||
cmpl $(C(edge_tail)),%ebx
|
||||
jnz Lgs_edgeloop
|
||||
|
||||
// clean up at the right edge
|
||||
Lgs_lastspan:
|
||||
|
||||
// now that we've reached the right edge of the screen, we're done with any
|
||||
// unfinished surfaces, so emit a span for whatever's on top
|
||||
movl 0x12345678,%esi // surfaces[1].st_next
|
||||
LPatch3:
|
||||
movl C(edge_tail_u_shift20),%eax
|
||||
xorl %ecx,%ecx
|
||||
movl st_last_u(%esi),%edx
|
||||
subl %edx,%eax
|
||||
jle Lgs_resetspanstate
|
||||
|
||||
movl %edx,espan_t_u(%ebp)
|
||||
movl %eax,espan_t_count(%ebp)
|
||||
movl C(current_iv),%eax
|
||||
movl %eax,espan_t_v(%ebp)
|
||||
movl st_spans(%esi),%eax
|
||||
movl %eax,espan_t_pnext(%ebp)
|
||||
movl %ebp,st_spans(%esi)
|
||||
addl $(espan_t_size),%ebp
|
||||
|
||||
// reset spanstate for all surfaces in the surface stack
|
||||
Lgs_resetspanstate:
|
||||
movl %ecx,st_spanstate(%esi)
|
||||
movl st_next(%esi),%esi
|
||||
cmpl $0x12345678,%esi // &surfaces[1]
|
||||
LPatch4:
|
||||
jnz Lgs_resetspanstate
|
||||
|
||||
// store the final span_p
|
||||
movl %ebp,C(span_p)
|
||||
|
||||
popl %ebx // restore register variables
|
||||
popl %esi
|
||||
popl %edi
|
||||
popl %ebp // restore the caller's stack frame
|
||||
ret
|
||||
|
||||
|
||||
// ---------------------------------------------------------------
|
||||
// 1/z sorting for bmodels in the same leaf
|
||||
// ---------------------------------------------------------------
|
||||
.align 4
|
||||
Lxl_done:
|
||||
incl %edx
|
||||
movl %edx,st_spanstate(%edi)
|
||||
|
||||
jmp Lgs_nextedge
|
||||
|
||||
|
||||
.align 4
|
||||
Lzcheck_for_newtop:
|
||||
movl et_u(%ebx),%eax
|
||||
subl $0xFFFFF,%eax
|
||||
movl %eax,Ltemp
|
||||
fildl Ltemp
|
||||
|
||||
fmuls float_1_div_0100000h // fu = (float)(edge->u - 0xFFFFF) *
|
||||
// (1.0 / 0x100000);
|
||||
|
||||
fld %st(0) // fu | fu
|
||||
fmuls st_d_zistepu(%edi) // fu*surf->d_zistepu | fu
|
||||
flds C(fv) // fv | fu*surf->d_zistepu | fu
|
||||
fmuls st_d_zistepv(%edi) // fv*surf->d_zistepv | fu*surf->d_zistepu | fu
|
||||
fxch %st(1) // fu*surf->d_zistepu | fv*surf->d_zistepv | fu
|
||||
fadds st_d_ziorigin(%edi) // fu*surf->d_zistepu + surf->d_ziorigin |
|
||||
// fv*surf->d_zistepv | fu
|
||||
|
||||
flds st_d_zistepu(%esi) // surf2->d_zistepu |
|
||||
// fu*surf->d_zistepu + surf->d_ziorigin |
|
||||
// fv*surf->d_zistepv | fu
|
||||
fmul %st(3),%st(0) // fu*surf2->d_zistepu |
|
||||
// fu*surf->d_zistepu + surf->d_ziorigin |
|
||||
// fv*surf->d_zistepv | fu
|
||||
fxch %st(1) // fu*surf->d_zistepu + surf->d_ziorigin |
|
||||
// fu*surf2->d_zistepu |
|
||||
// fv*surf->d_zistepv | fu
|
||||
faddp %st(0),%st(2) // fu*surf2->d_zistepu | newzi | fu
|
||||
|
||||
flds C(fv) // fv | fu*surf2->d_zistepu | newzi | fu
|
||||
fmuls st_d_zistepv(%esi) // fv*surf2->d_zistepv |
|
||||
// fu*surf2->d_zistepu | newzi | fu
|
||||
fld %st(2) // newzi | fv*surf2->d_zistepv |
|
||||
// fu*surf2->d_zistepu | newzi | fu
|
||||
fmuls float_point_999 // newzibottom | fv*surf2->d_zistepv |
|
||||
// fu*surf2->d_zistepu | newzi | fu
|
||||
|
||||
fxch %st(2) // fu*surf2->d_zistepu | fv*surf2->d_zistepv |
|
||||
// newzibottom | newzi | fu
|
||||
fadds st_d_ziorigin(%esi) // fu*surf2->d_zistepu + surf2->d_ziorigin |
|
||||
// fv*surf2->d_zistepv | newzibottom | newzi |
|
||||
// fu
|
||||
faddp %st(0),%st(1) // testzi | newzibottom | newzi | fu
|
||||
fxch %st(1) // newzibottom | testzi | newzi | fu
|
||||
|
||||
// if (newzibottom >= testzi)
|
||||
// goto newtop;
|
||||
|
||||
fcomp %st(1) // testzi | newzi | fu
|
||||
|
||||
fxch %st(1) // newzi | testzi | fu
|
||||
fmuls float_1_point_001 // newzitop | testzi | fu
|
||||
fxch %st(1) // testzi | newzitop | fu
|
||||
|
||||
fnstsw %ax
|
||||
testb $0x01,%ah
|
||||
jz Lnewtop_fpop3
|
||||
|
||||
// if (newzitop >= testzi)
|
||||
// {
|
||||
|
||||
fcomp %st(1) // newzitop | fu
|
||||
fnstsw %ax
|
||||
testb $0x45,%ah
|
||||
jz Lsortloop_fpop2
|
||||
|
||||
// if (surf->d_zistepu >= surf2->d_zistepu)
|
||||
// goto newtop;
|
||||
|
||||
flds st_d_zistepu(%edi) // surf->d_zistepu | newzitop | fu
|
||||
fcomps st_d_zistepu(%esi) // newzitop | fu
|
||||
fnstsw %ax
|
||||
testb $0x01,%ah
|
||||
jz Lnewtop_fpop2
|
||||
|
||||
Lsortloop_fpop2:
|
||||
fstp %st(0) // clear the FP stack
|
||||
fstp %st(0)
|
||||
movl st_key(%edi),%eax
|
||||
jmp Lsortloop
|
||||
|
||||
|
||||
.globl C(R_EdgeCodeEnd)
|
||||
C(R_EdgeCodeEnd):
|
||||
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// Surface array address code patching routine
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
.align 4
|
||||
.globl C(R_SurfacePatch)
|
||||
C(R_SurfacePatch):
|
||||
|
||||
movl C(surfaces),%eax
|
||||
addl $(st_size),%eax
|
||||
movl %eax,LPatch4-4
|
||||
|
||||
addl $(st_next),%eax
|
||||
movl %eax,LPatch0-4
|
||||
movl %eax,LPatch2-4
|
||||
movl %eax,LPatch3-4
|
||||
|
||||
ret
|
||||
|
||||
#endif // id386
|
||||
|
68
linux/r_scana.s
Normal file
68
linux/r_scana.s
Normal file
@ -0,0 +1,68 @@
|
||||
//
|
||||
// d_scana.s
|
||||
// x86 assembly-language turbulent texture mapping code
|
||||
//
|
||||
|
||||
#include "qasm.h"
|
||||
#include "d_ifacea.h"
|
||||
|
||||
#if id386
|
||||
|
||||
.data
|
||||
|
||||
.text
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// turbulent texture mapping code
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
.align 4
|
||||
.globl C(D_DrawTurbulent8Span)
|
||||
C(D_DrawTurbulent8Span):
|
||||
pushl %ebp // preserve caller's stack frame pointer
|
||||
pushl %esi // preserve register variables
|
||||
pushl %edi
|
||||
pushl %ebx
|
||||
|
||||
movl C(r_turb_s),%esi
|
||||
movl C(r_turb_t),%ecx
|
||||
movl C(r_turb_pdest),%edi
|
||||
movl C(r_turb_spancount),%ebx
|
||||
|
||||
Llp:
|
||||
movl %ecx,%eax
|
||||
movl %esi,%edx
|
||||
sarl $16,%eax
|
||||
movl C(r_turb_turb),%ebp
|
||||
sarl $16,%edx
|
||||
andl $(CYCLE-1),%eax
|
||||
andl $(CYCLE-1),%edx
|
||||
movl (%ebp,%eax,4),%eax
|
||||
movl (%ebp,%edx,4),%edx
|
||||
addl %esi,%eax
|
||||
sarl $16,%eax
|
||||
addl %ecx,%edx
|
||||
sarl $16,%edx
|
||||
andl $(TURB_TEX_SIZE-1),%eax
|
||||
andl $(TURB_TEX_SIZE-1),%edx
|
||||
shll $6,%edx
|
||||
movl C(r_turb_pbase),%ebp
|
||||
addl %eax,%edx
|
||||
incl %edi
|
||||
addl C(r_turb_sstep),%esi
|
||||
addl C(r_turb_tstep),%ecx
|
||||
movb (%ebp,%edx,1),%dl
|
||||
decl %ebx
|
||||
movb %dl,-1(%edi)
|
||||
jnz Llp
|
||||
|
||||
movl %edi,C(r_turb_pdest)
|
||||
|
||||
popl %ebx // restore register variables
|
||||
popl %edi
|
||||
popl %esi
|
||||
popl %ebp // restore caller's stack frame pointer
|
||||
ret
|
||||
|
||||
#endif // id386
|
||||
|
879
linux/r_spr8.s
Normal file
879
linux/r_spr8.s
Normal file
@ -0,0 +1,879 @@
|
||||
//
|
||||
// d_spr8.s
|
||||
// x86 assembly-language horizontal 8-bpp transparent span-drawing code.
|
||||
//
|
||||
|
||||
#include "qasm.h"
|
||||
|
||||
#if id386
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// 8-bpp horizontal span drawing code for polygons, with transparency.
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
.text
|
||||
|
||||
// out-of-line, rarely-needed clamping code
|
||||
|
||||
LClampHigh0:
|
||||
movl C(bbextents),%esi
|
||||
jmp LClampReentry0
|
||||
LClampHighOrLow0:
|
||||
jg LClampHigh0
|
||||
xorl %esi,%esi
|
||||
jmp LClampReentry0
|
||||
|
||||
LClampHigh1:
|
||||
movl C(bbextentt),%edx
|
||||
jmp LClampReentry1
|
||||
LClampHighOrLow1:
|
||||
jg LClampHigh1
|
||||
xorl %edx,%edx
|
||||
jmp LClampReentry1
|
||||
|
||||
LClampLow2:
|
||||
movl $2048,%ebp
|
||||
jmp LClampReentry2
|
||||
LClampHigh2:
|
||||
movl C(bbextents),%ebp
|
||||
jmp LClampReentry2
|
||||
|
||||
LClampLow3:
|
||||
movl $2048,%ecx
|
||||
jmp LClampReentry3
|
||||
LClampHigh3:
|
||||
movl C(bbextentt),%ecx
|
||||
jmp LClampReentry3
|
||||
|
||||
LClampLow4:
|
||||
movl $2048,%eax
|
||||
jmp LClampReentry4
|
||||
LClampHigh4:
|
||||
movl C(bbextents),%eax
|
||||
jmp LClampReentry4
|
||||
|
||||
LClampLow5:
|
||||
movl $2048,%ebx
|
||||
jmp LClampReentry5
|
||||
LClampHigh5:
|
||||
movl C(bbextentt),%ebx
|
||||
jmp LClampReentry5
|
||||
|
||||
|
||||
#define pspans 4+16
|
||||
|
||||
.align 4
|
||||
.globl C(D_SpriteDrawSpans)
|
||||
C(D_SpriteDrawSpans):
|
||||
pushl %ebp // preserve caller's stack frame
|
||||
pushl %edi
|
||||
pushl %esi // preserve register variables
|
||||
pushl %ebx
|
||||
|
||||
//
|
||||
// set up scaled-by-8 steps, for 8-long segments; also set up cacheblock
|
||||
// and span list pointers, and 1/z step in 0.32 fixed-point
|
||||
//
|
||||
// FIXME: any overlap from rearranging?
|
||||
flds C(d_sdivzstepu)
|
||||
fmuls fp_8
|
||||
movl C(cacheblock),%edx
|
||||
flds C(d_tdivzstepu)
|
||||
fmuls fp_8
|
||||
movl pspans(%esp),%ebx // point to the first span descriptor
|
||||
flds C(d_zistepu)
|
||||
fmuls fp_8
|
||||
movl %edx,pbase // pbase = cacheblock
|
||||
flds C(d_zistepu)
|
||||
fmuls fp_64kx64k
|
||||
fxch %st(3)
|
||||
fstps sdivz8stepu
|
||||
fstps zi8stepu
|
||||
fstps tdivz8stepu
|
||||
fistpl izistep
|
||||
movl izistep,%eax
|
||||
rorl $16,%eax // put upper 16 bits in low word
|
||||
movl sspan_t_count(%ebx),%ecx
|
||||
movl %eax,izistep
|
||||
|
||||
cmpl $0,%ecx
|
||||
jle LNextSpan
|
||||
|
||||
LSpanLoop:
|
||||
|
||||
//
|
||||
// set up the initial s/z, t/z, and 1/z on the FP stack, and generate the
|
||||
// initial s and t values
|
||||
//
|
||||
// FIXME: pipeline FILD?
|
||||
fildl sspan_t_v(%ebx)
|
||||
fildl sspan_t_u(%ebx)
|
||||
|
||||
fld %st(1) // dv | du | dv
|
||||
fmuls C(d_sdivzstepv) // dv*d_sdivzstepv | du | dv
|
||||
fld %st(1) // du | dv*d_sdivzstepv | du | dv
|
||||
fmuls C(d_sdivzstepu) // du*d_sdivzstepu | dv*d_sdivzstepv | du | dv
|
||||
fld %st(2) // du | du*d_sdivzstepu | dv*d_sdivzstepv | du | dv
|
||||
fmuls C(d_tdivzstepu) // du*d_tdivzstepu | du*d_sdivzstepu |
|
||||
// dv*d_sdivzstepv | du | dv
|
||||
fxch %st(1) // du*d_sdivzstepu | du*d_tdivzstepu |
|
||||
// dv*d_sdivzstepv | du | dv
|
||||
faddp %st(0),%st(2) // du*d_tdivzstepu |
|
||||
// du*d_sdivzstepu + dv*d_sdivzstepv | du | dv
|
||||
fxch %st(1) // du*d_sdivzstepu + dv*d_sdivzstepv |
|
||||
// du*d_tdivzstepu | du | dv
|
||||
fld %st(3) // dv | du*d_sdivzstepu + dv*d_sdivzstepv |
|
||||
// du*d_tdivzstepu | du | dv
|
||||
fmuls C(d_tdivzstepv) // dv*d_tdivzstepv |
|
||||
// du*d_sdivzstepu + dv*d_sdivzstepv |
|
||||
// du*d_tdivzstepu | du | dv
|
||||
fxch %st(1) // du*d_sdivzstepu + dv*d_sdivzstepv |
|
||||
// dv*d_tdivzstepv | du*d_tdivzstepu | du | dv
|
||||
fadds C(d_sdivzorigin) // sdivz = d_sdivzorigin + dv*d_sdivzstepv +
|
||||
// du*d_sdivzstepu; stays in %st(2) at end
|
||||
fxch %st(4) // dv | dv*d_tdivzstepv | du*d_tdivzstepu | du |
|
||||
// s/z
|
||||
fmuls C(d_zistepv) // dv*d_zistepv | dv*d_tdivzstepv |
|
||||
// du*d_tdivzstepu | du | s/z
|
||||
fxch %st(1) // dv*d_tdivzstepv | dv*d_zistepv |
|
||||
// du*d_tdivzstepu | du | s/z
|
||||
faddp %st(0),%st(2) // dv*d_zistepv |
|
||||
// dv*d_tdivzstepv + du*d_tdivzstepu | du | s/z
|
||||
fxch %st(2) // du | dv*d_tdivzstepv + du*d_tdivzstepu |
|
||||
// dv*d_zistepv | s/z
|
||||
fmuls C(d_zistepu) // du*d_zistepu |
|
||||
// dv*d_tdivzstepv + du*d_tdivzstepu |
|
||||
// dv*d_zistepv | s/z
|
||||
fxch %st(1) // dv*d_tdivzstepv + du*d_tdivzstepu |
|
||||
// du*d_zistepu | dv*d_zistepv | s/z
|
||||
fadds C(d_tdivzorigin) // tdivz = d_tdivzorigin + dv*d_tdivzstepv +
|
||||
// du*d_tdivzstepu; stays in %st(1) at end
|
||||
fxch %st(2) // dv*d_zistepv | du*d_zistepu | t/z | s/z
|
||||
faddp %st(0),%st(1) // dv*d_zistepv + du*d_zistepu | t/z | s/z
|
||||
|
||||
flds fp_64k // fp_64k | dv*d_zistepv + du*d_zistepu | t/z | s/z
|
||||
fxch %st(1) // dv*d_zistepv + du*d_zistepu | fp_64k | t/z | s/z
|
||||
fadds C(d_ziorigin) // zi = d_ziorigin + dv*d_zistepv +
|
||||
// du*d_zistepu; stays in %st(0) at end
|
||||
// 1/z | fp_64k | t/z | s/z
|
||||
|
||||
fld %st(0) // FIXME: get rid of stall on FMUL?
|
||||
fmuls fp_64kx64k
|
||||
fxch %st(1)
|
||||
|
||||
//
|
||||
// calculate and clamp s & t
|
||||
//
|
||||
fdivr %st(0),%st(2) // 1/z | z*64k | t/z | s/z
|
||||
fxch %st(1)
|
||||
|
||||
fistpl izi // 0.32 fixed-point 1/z
|
||||
movl izi,%ebp
|
||||
|
||||
//
|
||||
// set pz to point to the first z-buffer pixel in the span
|
||||
//
|
||||
rorl $16,%ebp // put upper 16 bits in low word
|
||||
movl sspan_t_v(%ebx),%eax
|
||||
movl %ebp,izi
|
||||
movl sspan_t_u(%ebx),%ebp
|
||||
imull C(d_zrowbytes)
|
||||
shll $1,%ebp // a word per pixel
|
||||
addl C(d_pzbuffer),%eax
|
||||
addl %ebp,%eax
|
||||
movl %eax,pz
|
||||
|
||||
//
|
||||
// point %edi to the first pixel in the span
|
||||
//
|
||||
movl C(d_viewbuffer),%ebp
|
||||
movl sspan_t_v(%ebx),%eax
|
||||
pushl %ebx // preserve spans pointer
|
||||
movl C(tadjust),%edx
|
||||
movl C(sadjust),%esi
|
||||
movl C(d_scantable)(,%eax,4),%edi // v * screenwidth
|
||||
addl %ebp,%edi
|
||||
movl sspan_t_u(%ebx),%ebp
|
||||
addl %ebp,%edi // pdest = &pdestspan[scans->u];
|
||||
|
||||
//
|
||||
// now start the FDIV for the end of the span
|
||||
//
|
||||
cmpl $8,%ecx
|
||||
ja LSetupNotLast1
|
||||
|
||||
decl %ecx
|
||||
jz LCleanup1 // if only one pixel, no need to start an FDIV
|
||||
movl %ecx,spancountminus1
|
||||
|
||||
// finish up the s and t calcs
|
||||
fxch %st(1) // z*64k | 1/z | t/z | s/z
|
||||
|
||||
fld %st(0) // z*64k | z*64k | 1/z | t/z | s/z
|
||||
fmul %st(4),%st(0) // s | z*64k | 1/z | t/z | s/z
|
||||
fxch %st(1) // z*64k | s | 1/z | t/z | s/z
|
||||
fmul %st(3),%st(0) // t | s | 1/z | t/z | s/z
|
||||
fxch %st(1) // s | t | 1/z | t/z | s/z
|
||||
fistpl s // 1/z | t | t/z | s/z
|
||||
fistpl t // 1/z | t/z | s/z
|
||||
|
||||
fildl spancountminus1
|
||||
|
||||
flds C(d_tdivzstepu) // _d_tdivzstepu | spancountminus1
|
||||
flds C(d_zistepu) // _d_zistepu | _d_tdivzstepu | spancountminus1
|
||||
fmul %st(2),%st(0) // _d_zistepu*scm1 | _d_tdivzstepu | scm1
|
||||
fxch %st(1) // _d_tdivzstepu | _d_zistepu*scm1 | scm1
|
||||
fmul %st(2),%st(0) // _d_tdivzstepu*scm1 | _d_zistepu*scm1 | scm1
|
||||
fxch %st(2) // scm1 | _d_zistepu*scm1 | _d_tdivzstepu*scm1
|
||||
fmuls C(d_sdivzstepu) // _d_sdivzstepu*scm1 | _d_zistepu*scm1 |
|
||||
// _d_tdivzstepu*scm1
|
||||
fxch %st(1) // _d_zistepu*scm1 | _d_sdivzstepu*scm1 |
|
||||
// _d_tdivzstepu*scm1
|
||||
faddp %st(0),%st(3) // _d_sdivzstepu*scm1 | _d_tdivzstepu*scm1
|
||||
fxch %st(1) // _d_tdivzstepu*scm1 | _d_sdivzstepu*scm1
|
||||
faddp %st(0),%st(3) // _d_sdivzstepu*scm1
|
||||
faddp %st(0),%st(3)
|
||||
|
||||
flds fp_64k
|
||||
fdiv %st(1),%st(0) // this is what we've gone to all this trouble to
|
||||
// overlap
|
||||
jmp LFDIVInFlight1
|
||||
|
||||
LCleanup1:
|
||||
// finish up the s and t calcs
|
||||
fxch %st(1) // z*64k | 1/z | t/z | s/z
|
||||
|
||||
fld %st(0) // z*64k | z*64k | 1/z | t/z | s/z
|
||||
fmul %st(4),%st(0) // s | z*64k | 1/z | t/z | s/z
|
||||
fxch %st(1) // z*64k | s | 1/z | t/z | s/z
|
||||
fmul %st(3),%st(0) // t | s | 1/z | t/z | s/z
|
||||
fxch %st(1) // s | t | 1/z | t/z | s/z
|
||||
fistpl s // 1/z | t | t/z | s/z
|
||||
fistpl t // 1/z | t/z | s/z
|
||||
jmp LFDIVInFlight1
|
||||
|
||||
.align 4
|
||||
LSetupNotLast1:
|
||||
// finish up the s and t calcs
|
||||
fxch %st(1) // z*64k | 1/z | t/z | s/z
|
||||
|
||||
fld %st(0) // z*64k | z*64k | 1/z | t/z | s/z
|
||||
fmul %st(4),%st(0) // s | z*64k | 1/z | t/z | s/z
|
||||
fxch %st(1) // z*64k | s | 1/z | t/z | s/z
|
||||
fmul %st(3),%st(0) // t | s | 1/z | t/z | s/z
|
||||
fxch %st(1) // s | t | 1/z | t/z | s/z
|
||||
fistpl s // 1/z | t | t/z | s/z
|
||||
fistpl t // 1/z | t/z | s/z
|
||||
|
||||
fadds zi8stepu
|
||||
fxch %st(2)
|
||||
fadds sdivz8stepu
|
||||
fxch %st(2)
|
||||
flds tdivz8stepu
|
||||
faddp %st(0),%st(2)
|
||||
flds fp_64k
|
||||
fdiv %st(1),%st(0) // z = 1/1/z
|
||||
// this is what we've gone to all this trouble to
|
||||
// overlap
|
||||
LFDIVInFlight1:
|
||||
|
||||
addl s,%esi
|
||||
addl t,%edx
|
||||
movl C(bbextents),%ebx
|
||||
movl C(bbextentt),%ebp
|
||||
cmpl %ebx,%esi
|
||||
ja LClampHighOrLow0
|
||||
LClampReentry0:
|
||||
movl %esi,s
|
||||
movl pbase,%ebx
|
||||
shll $16,%esi
|
||||
cmpl %ebp,%edx
|
||||
movl %esi,sfracf
|
||||
ja LClampHighOrLow1
|
||||
LClampReentry1:
|
||||
movl %edx,t
|
||||
movl s,%esi // sfrac = scans->sfrac;
|
||||
shll $16,%edx
|
||||
movl t,%eax // tfrac = scans->tfrac;
|
||||
sarl $16,%esi
|
||||
movl %edx,tfracf
|
||||
|
||||
//
|
||||
// calculate the texture starting address
|
||||
//
|
||||
sarl $16,%eax
|
||||
addl %ebx,%esi
|
||||
imull C(cachewidth),%eax // (tfrac >> 16) * cachewidth
|
||||
addl %eax,%esi // psource = pbase + (sfrac >> 16) +
|
||||
// ((tfrac >> 16) * cachewidth);
|
||||
|
||||
//
|
||||
// determine whether last span or not
|
||||
//
|
||||
cmpl $8,%ecx
|
||||
jna LLastSegment
|
||||
|
||||
//
|
||||
// not the last segment; do full 8-wide segment
|
||||
//
|
||||
LNotLastSegment:
|
||||
|
||||
//
|
||||
// advance s/z, t/z, and 1/z, and calculate s & t at end of span and steps to
|
||||
// get there
|
||||
//
|
||||
|
||||
// pick up after the FDIV that was left in flight previously
|
||||
|
||||
fld %st(0) // duplicate it
|
||||
fmul %st(4),%st(0) // s = s/z * z
|
||||
fxch %st(1)
|
||||
fmul %st(3),%st(0) // t = t/z * z
|
||||
fxch %st(1)
|
||||
fistpl snext
|
||||
fistpl tnext
|
||||
movl snext,%eax
|
||||
movl tnext,%edx
|
||||
|
||||
subl $8,%ecx // count off this segments' pixels
|
||||
movl C(sadjust),%ebp
|
||||
pushl %ecx // remember count of remaining pixels
|
||||
movl C(tadjust),%ecx
|
||||
|
||||
addl %eax,%ebp
|
||||
addl %edx,%ecx
|
||||
|
||||
movl C(bbextents),%eax
|
||||
movl C(bbextentt),%edx
|
||||
|
||||
cmpl $2048,%ebp
|
||||
jl LClampLow2
|
||||
cmpl %eax,%ebp
|
||||
ja LClampHigh2
|
||||
LClampReentry2:
|
||||
|
||||
cmpl $2048,%ecx
|
||||
jl LClampLow3
|
||||
cmpl %edx,%ecx
|
||||
ja LClampHigh3
|
||||
LClampReentry3:
|
||||
|
||||
movl %ebp,snext
|
||||
movl %ecx,tnext
|
||||
|
||||
subl s,%ebp
|
||||
subl t,%ecx
|
||||
|
||||
//
|
||||
// set up advancetable
|
||||
//
|
||||
movl %ecx,%eax
|
||||
movl %ebp,%edx
|
||||
sarl $19,%edx // sstep >>= 16;
|
||||
movl C(cachewidth),%ebx
|
||||
sarl $19,%eax // tstep >>= 16;
|
||||
jz LIsZero
|
||||
imull %ebx,%eax // (tstep >> 16) * cachewidth;
|
||||
LIsZero:
|
||||
addl %edx,%eax // add in sstep
|
||||
// (tstep >> 16) * cachewidth + (sstep >> 16);
|
||||
movl tfracf,%edx
|
||||
movl %eax,advancetable+4 // advance base in t
|
||||
addl %ebx,%eax // ((tstep >> 16) + 1) * cachewidth +
|
||||
// (sstep >> 16);
|
||||
shll $13,%ebp // left-justify sstep fractional part
|
||||
movl %ebp,sstep
|
||||
movl sfracf,%ebx
|
||||
shll $13,%ecx // left-justify tstep fractional part
|
||||
movl %eax,advancetable // advance extra in t
|
||||
movl %ecx,tstep
|
||||
|
||||
movl pz,%ecx
|
||||
movl izi,%ebp
|
||||
|
||||
cmpw (%ecx),%bp
|
||||
jl Lp1
|
||||
movb (%esi),%al // get first source texel
|
||||
cmpb $(TRANSPARENT_COLOR),%al
|
||||
jz Lp1
|
||||
movw %bp,(%ecx)
|
||||
movb %al,(%edi) // store first dest pixel
|
||||
Lp1:
|
||||
addl izistep,%ebp
|
||||
adcl $0,%ebp
|
||||
addl tstep,%edx // advance tfrac fractional part by tstep frac
|
||||
|
||||
sbbl %eax,%eax // turn tstep carry into -1 (0 if none)
|
||||
addl sstep,%ebx // advance sfrac fractional part by sstep frac
|
||||
adcl advancetable+4(,%eax,4),%esi // point to next source texel
|
||||
|
||||
cmpw 2(%ecx),%bp
|
||||
jl Lp2
|
||||
movb (%esi),%al
|
||||
cmpb $(TRANSPARENT_COLOR),%al
|
||||
jz Lp2
|
||||
movw %bp,2(%ecx)
|
||||
movb %al,1(%edi)
|
||||
Lp2:
|
||||
addl izistep,%ebp
|
||||
adcl $0,%ebp
|
||||
addl tstep,%edx
|
||||
sbbl %eax,%eax
|
||||
addl sstep,%ebx
|
||||
adcl advancetable+4(,%eax,4),%esi
|
||||
|
||||
cmpw 4(%ecx),%bp
|
||||
jl Lp3
|
||||
movb (%esi),%al
|
||||
cmpb $(TRANSPARENT_COLOR),%al
|
||||
jz Lp3
|
||||
movw %bp,4(%ecx)
|
||||
movb %al,2(%edi)
|
||||
Lp3:
|
||||
addl izistep,%ebp
|
||||
adcl $0,%ebp
|
||||
addl tstep,%edx
|
||||
sbbl %eax,%eax
|
||||
addl sstep,%ebx
|
||||
adcl advancetable+4(,%eax,4),%esi
|
||||
|
||||
cmpw 6(%ecx),%bp
|
||||
jl Lp4
|
||||
movb (%esi),%al
|
||||
cmpb $(TRANSPARENT_COLOR),%al
|
||||
jz Lp4
|
||||
movw %bp,6(%ecx)
|
||||
movb %al,3(%edi)
|
||||
Lp4:
|
||||
addl izistep,%ebp
|
||||
adcl $0,%ebp
|
||||
addl tstep,%edx
|
||||
sbbl %eax,%eax
|
||||
addl sstep,%ebx
|
||||
adcl advancetable+4(,%eax,4),%esi
|
||||
|
||||
cmpw 8(%ecx),%bp
|
||||
jl Lp5
|
||||
movb (%esi),%al
|
||||
cmpb $(TRANSPARENT_COLOR),%al
|
||||
jz Lp5
|
||||
movw %bp,8(%ecx)
|
||||
movb %al,4(%edi)
|
||||
Lp5:
|
||||
addl izistep,%ebp
|
||||
adcl $0,%ebp
|
||||
addl tstep,%edx
|
||||
sbbl %eax,%eax
|
||||
addl sstep,%ebx
|
||||
adcl advancetable+4(,%eax,4),%esi
|
||||
|
||||
//
|
||||
// start FDIV for end of next segment in flight, so it can overlap
|
||||
//
|
||||
popl %eax
|
||||
cmpl $8,%eax // more than one segment after this?
|
||||
ja LSetupNotLast2 // yes
|
||||
|
||||
decl %eax
|
||||
jz LFDIVInFlight2 // if only one pixel, no need to start an FDIV
|
||||
movl %eax,spancountminus1
|
||||
fildl spancountminus1
|
||||
|
||||
flds C(d_zistepu) // _d_zistepu | spancountminus1
|
||||
fmul %st(1),%st(0) // _d_zistepu*scm1 | scm1
|
||||
flds C(d_tdivzstepu) // _d_tdivzstepu | _d_zistepu*scm1 | scm1
|
||||
fmul %st(2),%st(0) // _d_tdivzstepu*scm1 | _d_zistepu*scm1 | scm1
|
||||
fxch %st(1) // _d_zistepu*scm1 | _d_tdivzstepu*scm1 | scm1
|
||||
faddp %st(0),%st(3) // _d_tdivzstepu*scm1 | scm1
|
||||
fxch %st(1) // scm1 | _d_tdivzstepu*scm1
|
||||
fmuls C(d_sdivzstepu) // _d_sdivzstepu*scm1 | _d_tdivzstepu*scm1
|
||||
fxch %st(1) // _d_tdivzstepu*scm1 | _d_sdivzstepu*scm1
|
||||
faddp %st(0),%st(3) // _d_sdivzstepu*scm1
|
||||
flds fp_64k // 64k | _d_sdivzstepu*scm1
|
||||
fxch %st(1) // _d_sdivzstepu*scm1 | 64k
|
||||
faddp %st(0),%st(4) // 64k
|
||||
|
||||
fdiv %st(1),%st(0) // this is what we've gone to all this trouble to
|
||||
// overlap
|
||||
jmp LFDIVInFlight2
|
||||
|
||||
.align 4
|
||||
LSetupNotLast2:
|
||||
fadds zi8stepu
|
||||
fxch %st(2)
|
||||
fadds sdivz8stepu
|
||||
fxch %st(2)
|
||||
flds tdivz8stepu
|
||||
faddp %st(0),%st(2)
|
||||
flds fp_64k
|
||||
fdiv %st(1),%st(0) // z = 1/1/z
|
||||
// this is what we've gone to all this trouble to
|
||||
// overlap
|
||||
LFDIVInFlight2:
|
||||
pushl %eax
|
||||
|
||||
cmpw 10(%ecx),%bp
|
||||
jl Lp6
|
||||
movb (%esi),%al
|
||||
cmpb $(TRANSPARENT_COLOR),%al
|
||||
jz Lp6
|
||||
movw %bp,10(%ecx)
|
||||
movb %al,5(%edi)
|
||||
Lp6:
|
||||
addl izistep,%ebp
|
||||
adcl $0,%ebp
|
||||
addl tstep,%edx
|
||||
sbbl %eax,%eax
|
||||
addl sstep,%ebx
|
||||
adcl advancetable+4(,%eax,4),%esi
|
||||
|
||||
cmpw 12(%ecx),%bp
|
||||
jl Lp7
|
||||
movb (%esi),%al
|
||||
cmpb $(TRANSPARENT_COLOR),%al
|
||||
jz Lp7
|
||||
movw %bp,12(%ecx)
|
||||
movb %al,6(%edi)
|
||||
Lp7:
|
||||
addl izistep,%ebp
|
||||
adcl $0,%ebp
|
||||
addl tstep,%edx
|
||||
sbbl %eax,%eax
|
||||
addl sstep,%ebx
|
||||
adcl advancetable+4(,%eax,4),%esi
|
||||
|
||||
cmpw 14(%ecx),%bp
|
||||
jl Lp8
|
||||
movb (%esi),%al
|
||||
cmpb $(TRANSPARENT_COLOR),%al
|
||||
jz Lp8
|
||||
movw %bp,14(%ecx)
|
||||
movb %al,7(%edi)
|
||||
Lp8:
|
||||
addl izistep,%ebp
|
||||
adcl $0,%ebp
|
||||
addl tstep,%edx
|
||||
sbbl %eax,%eax
|
||||
addl sstep,%ebx
|
||||
adcl advancetable+4(,%eax,4),%esi
|
||||
|
||||
addl $8,%edi
|
||||
addl $16,%ecx
|
||||
movl %edx,tfracf
|
||||
movl snext,%edx
|
||||
movl %ebx,sfracf
|
||||
movl tnext,%ebx
|
||||
movl %edx,s
|
||||
movl %ebx,t
|
||||
|
||||
movl %ecx,pz
|
||||
movl %ebp,izi
|
||||
|
||||
popl %ecx // retrieve count
|
||||
|
||||
//
|
||||
// determine whether last span or not
|
||||
//
|
||||
cmpl $8,%ecx // are there multiple segments remaining?
|
||||
ja LNotLastSegment // yes
|
||||
|
||||
//
|
||||
// last segment of scan
|
||||
//
|
||||
LLastSegment:
|
||||
|
||||
//
|
||||
// advance s/z, t/z, and 1/z, and calculate s & t at end of span and steps to
|
||||
// get there. The number of pixels left is variable, and we want to land on the
|
||||
// last pixel, not step one past it, so we can't run into arithmetic problems
|
||||
//
|
||||
testl %ecx,%ecx
|
||||
jz LNoSteps // just draw the last pixel and we're done
|
||||
|
||||
// pick up after the FDIV that was left in flight previously
|
||||
|
||||
|
||||
fld %st(0) // duplicate it
|
||||
fmul %st(4),%st(0) // s = s/z * z
|
||||
fxch %st(1)
|
||||
fmul %st(3),%st(0) // t = t/z * z
|
||||
fxch %st(1)
|
||||
fistpl snext
|
||||
fistpl tnext
|
||||
|
||||
movl C(tadjust),%ebx
|
||||
movl C(sadjust),%eax
|
||||
|
||||
addl snext,%eax
|
||||
addl tnext,%ebx
|
||||
|
||||
movl C(bbextents),%ebp
|
||||
movl C(bbextentt),%edx
|
||||
|
||||
cmpl $2048,%eax
|
||||
jl LClampLow4
|
||||
cmpl %ebp,%eax
|
||||
ja LClampHigh4
|
||||
LClampReentry4:
|
||||
movl %eax,snext
|
||||
|
||||
cmpl $2048,%ebx
|
||||
jl LClampLow5
|
||||
cmpl %edx,%ebx
|
||||
ja LClampHigh5
|
||||
LClampReentry5:
|
||||
|
||||
cmpl $1,%ecx // don't bother
|
||||
je LOnlyOneStep // if two pixels in segment, there's only one step,
|
||||
// of the segment length
|
||||
subl s,%eax
|
||||
subl t,%ebx
|
||||
|
||||
addl %eax,%eax // convert to 15.17 format so multiply by 1.31
|
||||
addl %ebx,%ebx // reciprocal yields 16.48
|
||||
imull reciprocal_table-8(,%ecx,4) // sstep = (snext - s) / (spancount-1)
|
||||
movl %edx,%ebp
|
||||
|
||||
movl %ebx,%eax
|
||||
imull reciprocal_table-8(,%ecx,4) // tstep = (tnext - t) / (spancount-1)
|
||||
|
||||
LSetEntryvec:
|
||||
//
|
||||
// set up advancetable
|
||||
//
|
||||
movl spr8entryvec_table(,%ecx,4),%ebx
|
||||
movl %edx,%eax
|
||||
pushl %ebx // entry point into code for RET later
|
||||
movl %ebp,%ecx
|
||||
sarl $16,%ecx // sstep >>= 16;
|
||||
movl C(cachewidth),%ebx
|
||||
sarl $16,%edx // tstep >>= 16;
|
||||
jz LIsZeroLast
|
||||
imull %ebx,%edx // (tstep >> 16) * cachewidth;
|
||||
LIsZeroLast:
|
||||
addl %ecx,%edx // add in sstep
|
||||
// (tstep >> 16) * cachewidth + (sstep >> 16);
|
||||
movl tfracf,%ecx
|
||||
movl %edx,advancetable+4 // advance base in t
|
||||
addl %ebx,%edx // ((tstep >> 16) + 1) * cachewidth +
|
||||
// (sstep >> 16);
|
||||
shll $16,%ebp // left-justify sstep fractional part
|
||||
movl sfracf,%ebx
|
||||
shll $16,%eax // left-justify tstep fractional part
|
||||
movl %edx,advancetable // advance extra in t
|
||||
|
||||
movl %eax,tstep
|
||||
movl %ebp,sstep
|
||||
movl %ecx,%edx
|
||||
|
||||
movl pz,%ecx
|
||||
movl izi,%ebp
|
||||
|
||||
ret // jump to the number-of-pixels handler
|
||||
|
||||
//----------------------------------------
|
||||
|
||||
LNoSteps:
|
||||
movl pz,%ecx
|
||||
subl $7,%edi // adjust for hardwired offset
|
||||
subl $14,%ecx
|
||||
jmp LEndSpan
|
||||
|
||||
|
||||
LOnlyOneStep:
|
||||
subl s,%eax
|
||||
subl t,%ebx
|
||||
movl %eax,%ebp
|
||||
movl %ebx,%edx
|
||||
jmp LSetEntryvec
|
||||
|
||||
//----------------------------------------
|
||||
|
||||
.globl Spr8Entry2_8
|
||||
Spr8Entry2_8:
|
||||
subl $6,%edi // adjust for hardwired offsets
|
||||
subl $12,%ecx
|
||||
movb (%esi),%al
|
||||
jmp LLEntry2_8
|
||||
|
||||
//----------------------------------------
|
||||
|
||||
.globl Spr8Entry3_8
|
||||
Spr8Entry3_8:
|
||||
subl $5,%edi // adjust for hardwired offsets
|
||||
subl $10,%ecx
|
||||
jmp LLEntry3_8
|
||||
|
||||
//----------------------------------------
|
||||
|
||||
.globl Spr8Entry4_8
|
||||
Spr8Entry4_8:
|
||||
subl $4,%edi // adjust for hardwired offsets
|
||||
subl $8,%ecx
|
||||
jmp LLEntry4_8
|
||||
|
||||
//----------------------------------------
|
||||
|
||||
.globl Spr8Entry5_8
|
||||
Spr8Entry5_8:
|
||||
subl $3,%edi // adjust for hardwired offsets
|
||||
subl $6,%ecx
|
||||
jmp LLEntry5_8
|
||||
|
||||
//----------------------------------------
|
||||
|
||||
.globl Spr8Entry6_8
|
||||
Spr8Entry6_8:
|
||||
subl $2,%edi // adjust for hardwired offsets
|
||||
subl $4,%ecx
|
||||
jmp LLEntry6_8
|
||||
|
||||
//----------------------------------------
|
||||
|
||||
.globl Spr8Entry7_8
|
||||
Spr8Entry7_8:
|
||||
decl %edi // adjust for hardwired offsets
|
||||
subl $2,%ecx
|
||||
jmp LLEntry7_8
|
||||
|
||||
//----------------------------------------
|
||||
|
||||
.globl Spr8Entry8_8
|
||||
Spr8Entry8_8:
|
||||
cmpw (%ecx),%bp
|
||||
jl Lp9
|
||||
movb (%esi),%al
|
||||
cmpb $(TRANSPARENT_COLOR),%al
|
||||
jz Lp9
|
||||
movw %bp,(%ecx)
|
||||
movb %al,(%edi)
|
||||
Lp9:
|
||||
addl izistep,%ebp
|
||||
adcl $0,%ebp
|
||||
addl tstep,%edx
|
||||
sbbl %eax,%eax
|
||||
addl sstep,%ebx
|
||||
adcl advancetable+4(,%eax,4),%esi
|
||||
LLEntry7_8:
|
||||
cmpw 2(%ecx),%bp
|
||||
jl Lp10
|
||||
movb (%esi),%al
|
||||
cmpb $(TRANSPARENT_COLOR),%al
|
||||
jz Lp10
|
||||
movw %bp,2(%ecx)
|
||||
movb %al,1(%edi)
|
||||
Lp10:
|
||||
addl izistep,%ebp
|
||||
adcl $0,%ebp
|
||||
addl tstep,%edx
|
||||
sbbl %eax,%eax
|
||||
addl sstep,%ebx
|
||||
adcl advancetable+4(,%eax,4),%esi
|
||||
LLEntry6_8:
|
||||
cmpw 4(%ecx),%bp
|
||||
jl Lp11
|
||||
movb (%esi),%al
|
||||
cmpb $(TRANSPARENT_COLOR),%al
|
||||
jz Lp11
|
||||
movw %bp,4(%ecx)
|
||||
movb %al,2(%edi)
|
||||
Lp11:
|
||||
addl izistep,%ebp
|
||||
adcl $0,%ebp
|
||||
addl tstep,%edx
|
||||
sbbl %eax,%eax
|
||||
addl sstep,%ebx
|
||||
adcl advancetable+4(,%eax,4),%esi
|
||||
LLEntry5_8:
|
||||
cmpw 6(%ecx),%bp
|
||||
jl Lp12
|
||||
movb (%esi),%al
|
||||
cmpb $(TRANSPARENT_COLOR),%al
|
||||
jz Lp12
|
||||
movw %bp,6(%ecx)
|
||||
movb %al,3(%edi)
|
||||
Lp12:
|
||||
addl izistep,%ebp
|
||||
adcl $0,%ebp
|
||||
addl tstep,%edx
|
||||
sbbl %eax,%eax
|
||||
addl sstep,%ebx
|
||||
adcl advancetable+4(,%eax,4),%esi
|
||||
LLEntry4_8:
|
||||
cmpw 8(%ecx),%bp
|
||||
jl Lp13
|
||||
movb (%esi),%al
|
||||
cmpb $(TRANSPARENT_COLOR),%al
|
||||
jz Lp13
|
||||
movw %bp,8(%ecx)
|
||||
movb %al,4(%edi)
|
||||
Lp13:
|
||||
addl izistep,%ebp
|
||||
adcl $0,%ebp
|
||||
addl tstep,%edx
|
||||
sbbl %eax,%eax
|
||||
addl sstep,%ebx
|
||||
adcl advancetable+4(,%eax,4),%esi
|
||||
LLEntry3_8:
|
||||
cmpw 10(%ecx),%bp
|
||||
jl Lp14
|
||||
movb (%esi),%al
|
||||
cmpb $(TRANSPARENT_COLOR),%al
|
||||
jz Lp14
|
||||
movw %bp,10(%ecx)
|
||||
movb %al,5(%edi)
|
||||
Lp14:
|
||||
addl izistep,%ebp
|
||||
adcl $0,%ebp
|
||||
addl tstep,%edx
|
||||
sbbl %eax,%eax
|
||||
addl sstep,%ebx
|
||||
adcl advancetable+4(,%eax,4),%esi
|
||||
LLEntry2_8:
|
||||
cmpw 12(%ecx),%bp
|
||||
jl Lp15
|
||||
movb (%esi),%al
|
||||
cmpb $(TRANSPARENT_COLOR),%al
|
||||
jz Lp15
|
||||
movw %bp,12(%ecx)
|
||||
movb %al,6(%edi)
|
||||
Lp15:
|
||||
addl izistep,%ebp
|
||||
adcl $0,%ebp
|
||||
addl tstep,%edx
|
||||
sbbl %eax,%eax
|
||||
addl sstep,%ebx
|
||||
adcl advancetable+4(,%eax,4),%esi
|
||||
|
||||
LEndSpan:
|
||||
cmpw 14(%ecx),%bp
|
||||
jl Lp16
|
||||
movb (%esi),%al // load first texel in segment
|
||||
cmpb $(TRANSPARENT_COLOR),%al
|
||||
jz Lp16
|
||||
movw %bp,14(%ecx)
|
||||
movb %al,7(%edi)
|
||||
Lp16:
|
||||
|
||||
//
|
||||
// clear s/z, t/z, 1/z from FP stack
|
||||
//
|
||||
fstp %st(0)
|
||||
fstp %st(0)
|
||||
fstp %st(0)
|
||||
|
||||
popl %ebx // restore spans pointer
|
||||
LNextSpan:
|
||||
addl $(sspan_t_size),%ebx // point to next span
|
||||
movl sspan_t_count(%ebx),%ecx
|
||||
cmpl $0,%ecx // any more spans?
|
||||
jg LSpanLoop // yes
|
||||
jz LNextSpan // yes, but this one's empty
|
||||
|
||||
popl %ebx // restore register variables
|
||||
popl %esi
|
||||
popl %edi
|
||||
popl %ebp // restore the caller's stack frame
|
||||
ret
|
||||
|
||||
#endif // id386
|
762
linux/r_surf8.s
Normal file
762
linux/r_surf8.s
Normal file
@ -0,0 +1,762 @@
|
||||
//
|
||||
// surf8.s
|
||||
// x86 assembly-language 8 bpp surface block drawing code.
|
||||
//
|
||||
|
||||
#include "qasm.h"
|
||||
|
||||
#if id386
|
||||
|
||||
.data
|
||||
|
||||
sb_v: .long 0
|
||||
|
||||
.text
|
||||
|
||||
.align 4
|
||||
.globl C(R_Surf8Start)
|
||||
C(R_Surf8Start):
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// Surface block drawer for mip level 0
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
.align 4
|
||||
.globl C(R_DrawSurfaceBlock8_mip0)
|
||||
C(R_DrawSurfaceBlock8_mip0):
|
||||
pushl %ebp // preserve caller's stack frame
|
||||
pushl %edi
|
||||
pushl %esi // preserve register variables
|
||||
pushl %ebx
|
||||
|
||||
// for (v=0 ; v<numvblocks ; v++)
|
||||
// {
|
||||
movl C(r_lightptr),%ebx
|
||||
movl C(r_numvblocks),%eax
|
||||
|
||||
movl %eax,sb_v
|
||||
movl C(prowdestbase),%edi
|
||||
|
||||
movl C(pbasesource),%esi
|
||||
|
||||
Lv_loop_mip0:
|
||||
|
||||
// lightleft = lightptr[0];
|
||||
// lightright = lightptr[1];
|
||||
// lightdelta = (lightleft - lightright) & 0xFFFFF;
|
||||
movl (%ebx),%eax // lightleft
|
||||
movl 4(%ebx),%edx // lightright
|
||||
|
||||
movl %eax,%ebp
|
||||
movl C(r_lightwidth),%ecx
|
||||
|
||||
movl %edx,C(lightright)
|
||||
subl %edx,%ebp
|
||||
|
||||
andl $0xFFFFF,%ebp
|
||||
leal (%ebx,%ecx,4),%ebx
|
||||
|
||||
// lightptr += lightwidth;
|
||||
movl %ebx,C(r_lightptr)
|
||||
|
||||
// lightleftstep = (lightptr[0] - lightleft) >> blockdivshift;
|
||||
// lightrightstep = (lightptr[1] - lightright) >> blockdivshift;
|
||||
// lightdeltastep = ((lightleftstep - lightrightstep) & 0xFFFFF) |
|
||||
// 0xF0000000;
|
||||
movl 4(%ebx),%ecx // lightptr[1]
|
||||
movl (%ebx),%ebx // lightptr[0]
|
||||
|
||||
subl %eax,%ebx
|
||||
subl %edx,%ecx
|
||||
|
||||
sarl $4,%ecx
|
||||
orl $0xF0000000,%ebp
|
||||
|
||||
sarl $4,%ebx
|
||||
movl %ecx,C(lightrightstep)
|
||||
|
||||
subl %ecx,%ebx
|
||||
andl $0xFFFFF,%ebx
|
||||
|
||||
orl $0xF0000000,%ebx
|
||||
subl %ecx,%ecx // high word must be 0 in loop for addressing
|
||||
|
||||
movl %ebx,C(lightdeltastep)
|
||||
subl %ebx,%ebx // high word must be 0 in loop for addressing
|
||||
|
||||
Lblockloop8_mip0:
|
||||
movl %ebp,C(lightdelta)
|
||||
movb 14(%esi),%cl
|
||||
|
||||
sarl $4,%ebp
|
||||
movb %dh,%bh
|
||||
|
||||
movb 15(%esi),%bl
|
||||
addl %ebp,%edx
|
||||
|
||||
movb %dh,%ch
|
||||
addl %ebp,%edx
|
||||
|
||||
movb 0x12345678(%ebx),%ah
|
||||
LBPatch0:
|
||||
movb 13(%esi),%bl
|
||||
|
||||
movb 0x12345678(%ecx),%al
|
||||
LBPatch1:
|
||||
movb 12(%esi),%cl
|
||||
|
||||
movb %dh,%bh
|
||||
addl %ebp,%edx
|
||||
|
||||
rorl $16,%eax
|
||||
movb %dh,%ch
|
||||
|
||||
addl %ebp,%edx
|
||||
movb 0x12345678(%ebx),%ah
|
||||
LBPatch2:
|
||||
|
||||
movb 11(%esi),%bl
|
||||
movb 0x12345678(%ecx),%al
|
||||
LBPatch3:
|
||||
|
||||
movb 10(%esi),%cl
|
||||
movl %eax,12(%edi)
|
||||
|
||||
movb %dh,%bh
|
||||
addl %ebp,%edx
|
||||
|
||||
movb %dh,%ch
|
||||
addl %ebp,%edx
|
||||
|
||||
movb 0x12345678(%ebx),%ah
|
||||
LBPatch4:
|
||||
movb 9(%esi),%bl
|
||||
|
||||
movb 0x12345678(%ecx),%al
|
||||
LBPatch5:
|
||||
movb 8(%esi),%cl
|
||||
|
||||
movb %dh,%bh
|
||||
addl %ebp,%edx
|
||||
|
||||
rorl $16,%eax
|
||||
movb %dh,%ch
|
||||
|
||||
addl %ebp,%edx
|
||||
movb 0x12345678(%ebx),%ah
|
||||
LBPatch6:
|
||||
|
||||
movb 7(%esi),%bl
|
||||
movb 0x12345678(%ecx),%al
|
||||
LBPatch7:
|
||||
|
||||
movb 6(%esi),%cl
|
||||
movl %eax,8(%edi)
|
||||
|
||||
movb %dh,%bh
|
||||
addl %ebp,%edx
|
||||
|
||||
movb %dh,%ch
|
||||
addl %ebp,%edx
|
||||
|
||||
movb 0x12345678(%ebx),%ah
|
||||
LBPatch8:
|
||||
movb 5(%esi),%bl
|
||||
|
||||
movb 0x12345678(%ecx),%al
|
||||
LBPatch9:
|
||||
movb 4(%esi),%cl
|
||||
|
||||
movb %dh,%bh
|
||||
addl %ebp,%edx
|
||||
|
||||
rorl $16,%eax
|
||||
movb %dh,%ch
|
||||
|
||||
addl %ebp,%edx
|
||||
movb 0x12345678(%ebx),%ah
|
||||
LBPatch10:
|
||||
|
||||
movb 3(%esi),%bl
|
||||
movb 0x12345678(%ecx),%al
|
||||
LBPatch11:
|
||||
|
||||
movb 2(%esi),%cl
|
||||
movl %eax,4(%edi)
|
||||
|
||||
movb %dh,%bh
|
||||
addl %ebp,%edx
|
||||
|
||||
movb %dh,%ch
|
||||
addl %ebp,%edx
|
||||
|
||||
movb 0x12345678(%ebx),%ah
|
||||
LBPatch12:
|
||||
movb 1(%esi),%bl
|
||||
|
||||
movb 0x12345678(%ecx),%al
|
||||
LBPatch13:
|
||||
movb (%esi),%cl
|
||||
|
||||
movb %dh,%bh
|
||||
addl %ebp,%edx
|
||||
|
||||
rorl $16,%eax
|
||||
movb %dh,%ch
|
||||
|
||||
movb 0x12345678(%ebx),%ah
|
||||
LBPatch14:
|
||||
movl C(lightright),%edx
|
||||
|
||||
movb 0x12345678(%ecx),%al
|
||||
LBPatch15:
|
||||
movl C(lightdelta),%ebp
|
||||
|
||||
movl %eax,(%edi)
|
||||
|
||||
addl C(sourcetstep),%esi
|
||||
addl C(surfrowbytes),%edi
|
||||
|
||||
addl C(lightrightstep),%edx
|
||||
addl C(lightdeltastep),%ebp
|
||||
|
||||
movl %edx,C(lightright)
|
||||
jc Lblockloop8_mip0
|
||||
|
||||
// if (pbasesource >= r_sourcemax)
|
||||
// pbasesource -= stepback;
|
||||
|
||||
cmpl C(r_sourcemax),%esi
|
||||
jb LSkip_mip0
|
||||
subl C(r_stepback),%esi
|
||||
LSkip_mip0:
|
||||
|
||||
movl C(r_lightptr),%ebx
|
||||
decl sb_v
|
||||
|
||||
jnz Lv_loop_mip0
|
||||
|
||||
popl %ebx // restore register variables
|
||||
popl %esi
|
||||
popl %edi
|
||||
popl %ebp // restore the caller's stack frame
|
||||
ret
|
||||
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// Surface block drawer for mip level 1
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
.align 4
|
||||
.globl C(R_DrawSurfaceBlock8_mip1)
|
||||
C(R_DrawSurfaceBlock8_mip1):
|
||||
pushl %ebp // preserve caller's stack frame
|
||||
pushl %edi
|
||||
pushl %esi // preserve register variables
|
||||
pushl %ebx
|
||||
|
||||
// for (v=0 ; v<numvblocks ; v++)
|
||||
// {
|
||||
movl C(r_lightptr),%ebx
|
||||
movl C(r_numvblocks),%eax
|
||||
|
||||
movl %eax,sb_v
|
||||
movl C(prowdestbase),%edi
|
||||
|
||||
movl C(pbasesource),%esi
|
||||
|
||||
Lv_loop_mip1:
|
||||
|
||||
// lightleft = lightptr[0];
|
||||
// lightright = lightptr[1];
|
||||
// lightdelta = (lightleft - lightright) & 0xFFFFF;
|
||||
movl (%ebx),%eax // lightleft
|
||||
movl 4(%ebx),%edx // lightright
|
||||
|
||||
movl %eax,%ebp
|
||||
movl C(r_lightwidth),%ecx
|
||||
|
||||
movl %edx,C(lightright)
|
||||
subl %edx,%ebp
|
||||
|
||||
andl $0xFFFFF,%ebp
|
||||
leal (%ebx,%ecx,4),%ebx
|
||||
|
||||
// lightptr += lightwidth;
|
||||
movl %ebx,C(r_lightptr)
|
||||
|
||||
// lightleftstep = (lightptr[0] - lightleft) >> blockdivshift;
|
||||
// lightrightstep = (lightptr[1] - lightright) >> blockdivshift;
|
||||
// lightdeltastep = ((lightleftstep - lightrightstep) & 0xFFFFF) |
|
||||
// 0xF0000000;
|
||||
movl 4(%ebx),%ecx // lightptr[1]
|
||||
movl (%ebx),%ebx // lightptr[0]
|
||||
|
||||
subl %eax,%ebx
|
||||
subl %edx,%ecx
|
||||
|
||||
sarl $3,%ecx
|
||||
orl $0x70000000,%ebp
|
||||
|
||||
sarl $3,%ebx
|
||||
movl %ecx,C(lightrightstep)
|
||||
|
||||
subl %ecx,%ebx
|
||||
andl $0xFFFFF,%ebx
|
||||
|
||||
orl $0xF0000000,%ebx
|
||||
subl %ecx,%ecx // high word must be 0 in loop for addressing
|
||||
|
||||
movl %ebx,C(lightdeltastep)
|
||||
subl %ebx,%ebx // high word must be 0 in loop for addressing
|
||||
|
||||
Lblockloop8_mip1:
|
||||
movl %ebp,C(lightdelta)
|
||||
movb 6(%esi),%cl
|
||||
|
||||
sarl $3,%ebp
|
||||
movb %dh,%bh
|
||||
|
||||
movb 7(%esi),%bl
|
||||
addl %ebp,%edx
|
||||
|
||||
movb %dh,%ch
|
||||
addl %ebp,%edx
|
||||
|
||||
movb 0x12345678(%ebx),%ah
|
||||
LBPatch22:
|
||||
movb 5(%esi),%bl
|
||||
|
||||
movb 0x12345678(%ecx),%al
|
||||
LBPatch23:
|
||||
movb 4(%esi),%cl
|
||||
|
||||
movb %dh,%bh
|
||||
addl %ebp,%edx
|
||||
|
||||
rorl $16,%eax
|
||||
movb %dh,%ch
|
||||
|
||||
addl %ebp,%edx
|
||||
movb 0x12345678(%ebx),%ah
|
||||
LBPatch24:
|
||||
|
||||
movb 3(%esi),%bl
|
||||
movb 0x12345678(%ecx),%al
|
||||
LBPatch25:
|
||||
|
||||
movb 2(%esi),%cl
|
||||
movl %eax,4(%edi)
|
||||
|
||||
movb %dh,%bh
|
||||
addl %ebp,%edx
|
||||
|
||||
movb %dh,%ch
|
||||
addl %ebp,%edx
|
||||
|
||||
movb 0x12345678(%ebx),%ah
|
||||
LBPatch26:
|
||||
movb 1(%esi),%bl
|
||||
|
||||
movb 0x12345678(%ecx),%al
|
||||
LBPatch27:
|
||||
movb (%esi),%cl
|
||||
|
||||
movb %dh,%bh
|
||||
addl %ebp,%edx
|
||||
|
||||
rorl $16,%eax
|
||||
movb %dh,%ch
|
||||
|
||||
movb 0x12345678(%ebx),%ah
|
||||
LBPatch28:
|
||||
movl C(lightright),%edx
|
||||
|
||||
movb 0x12345678(%ecx),%al
|
||||
LBPatch29:
|
||||
movl C(lightdelta),%ebp
|
||||
|
||||
movl %eax,(%edi)
|
||||
movl C(sourcetstep),%eax
|
||||
|
||||
addl %eax,%esi
|
||||
movl C(surfrowbytes),%eax
|
||||
|
||||
addl %eax,%edi
|
||||
movl C(lightrightstep),%eax
|
||||
|
||||
addl %eax,%edx
|
||||
movl C(lightdeltastep),%eax
|
||||
|
||||
addl %eax,%ebp
|
||||
movl %edx,C(lightright)
|
||||
|
||||
jc Lblockloop8_mip1
|
||||
|
||||
// if (pbasesource >= r_sourcemax)
|
||||
// pbasesource -= stepback;
|
||||
|
||||
cmpl C(r_sourcemax),%esi
|
||||
jb LSkip_mip1
|
||||
subl C(r_stepback),%esi
|
||||
LSkip_mip1:
|
||||
|
||||
movl C(r_lightptr),%ebx
|
||||
decl sb_v
|
||||
|
||||
jnz Lv_loop_mip1
|
||||
|
||||
popl %ebx // restore register variables
|
||||
popl %esi
|
||||
popl %edi
|
||||
popl %ebp // restore the caller's stack frame
|
||||
ret
|
||||
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// Surface block drawer for mip level 2
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
.align 4
|
||||
.globl C(R_DrawSurfaceBlock8_mip2)
|
||||
C(R_DrawSurfaceBlock8_mip2):
|
||||
pushl %ebp // preserve caller's stack frame
|
||||
pushl %edi
|
||||
pushl %esi // preserve register variables
|
||||
pushl %ebx
|
||||
|
||||
// for (v=0 ; v<numvblocks ; v++)
|
||||
// {
|
||||
movl C(r_lightptr),%ebx
|
||||
movl C(r_numvblocks),%eax
|
||||
|
||||
movl %eax,sb_v
|
||||
movl C(prowdestbase),%edi
|
||||
|
||||
movl C(pbasesource),%esi
|
||||
|
||||
Lv_loop_mip2:
|
||||
|
||||
// lightleft = lightptr[0];
|
||||
// lightright = lightptr[1];
|
||||
// lightdelta = (lightleft - lightright) & 0xFFFFF;
|
||||
movl (%ebx),%eax // lightleft
|
||||
movl 4(%ebx),%edx // lightright
|
||||
|
||||
movl %eax,%ebp
|
||||
movl C(r_lightwidth),%ecx
|
||||
|
||||
movl %edx,C(lightright)
|
||||
subl %edx,%ebp
|
||||
|
||||
andl $0xFFFFF,%ebp
|
||||
leal (%ebx,%ecx,4),%ebx
|
||||
|
||||
// lightptr += lightwidth;
|
||||
movl %ebx,C(r_lightptr)
|
||||
|
||||
// lightleftstep = (lightptr[0] - lightleft) >> blockdivshift;
|
||||
// lightrightstep = (lightptr[1] - lightright) >> blockdivshift;
|
||||
// lightdeltastep = ((lightleftstep - lightrightstep) & 0xFFFFF) |
|
||||
// 0xF0000000;
|
||||
movl 4(%ebx),%ecx // lightptr[1]
|
||||
movl (%ebx),%ebx // lightptr[0]
|
||||
|
||||
subl %eax,%ebx
|
||||
subl %edx,%ecx
|
||||
|
||||
sarl $2,%ecx
|
||||
orl $0x30000000,%ebp
|
||||
|
||||
sarl $2,%ebx
|
||||
movl %ecx,C(lightrightstep)
|
||||
|
||||
subl %ecx,%ebx
|
||||
|
||||
andl $0xFFFFF,%ebx
|
||||
|
||||
orl $0xF0000000,%ebx
|
||||
subl %ecx,%ecx // high word must be 0 in loop for addressing
|
||||
|
||||
movl %ebx,C(lightdeltastep)
|
||||
subl %ebx,%ebx // high word must be 0 in loop for addressing
|
||||
|
||||
Lblockloop8_mip2:
|
||||
movl %ebp,C(lightdelta)
|
||||
movb 2(%esi),%cl
|
||||
|
||||
sarl $2,%ebp
|
||||
movb %dh,%bh
|
||||
|
||||
movb 3(%esi),%bl
|
||||
addl %ebp,%edx
|
||||
|
||||
movb %dh,%ch
|
||||
addl %ebp,%edx
|
||||
|
||||
movb 0x12345678(%ebx),%ah
|
||||
LBPatch18:
|
||||
movb 1(%esi),%bl
|
||||
|
||||
movb 0x12345678(%ecx),%al
|
||||
LBPatch19:
|
||||
movb (%esi),%cl
|
||||
|
||||
movb %dh,%bh
|
||||
addl %ebp,%edx
|
||||
|
||||
rorl $16,%eax
|
||||
movb %dh,%ch
|
||||
|
||||
movb 0x12345678(%ebx),%ah
|
||||
LBPatch20:
|
||||
movl C(lightright),%edx
|
||||
|
||||
movb 0x12345678(%ecx),%al
|
||||
LBPatch21:
|
||||
movl C(lightdelta),%ebp
|
||||
|
||||
movl %eax,(%edi)
|
||||
movl C(sourcetstep),%eax
|
||||
|
||||
addl %eax,%esi
|
||||
movl C(surfrowbytes),%eax
|
||||
|
||||
addl %eax,%edi
|
||||
movl C(lightrightstep),%eax
|
||||
|
||||
addl %eax,%edx
|
||||
movl C(lightdeltastep),%eax
|
||||
|
||||
addl %eax,%ebp
|
||||
movl %edx,C(lightright)
|
||||
|
||||
jc Lblockloop8_mip2
|
||||
|
||||
// if (pbasesource >= r_sourcemax)
|
||||
// pbasesource -= stepback;
|
||||
|
||||
cmpl C(r_sourcemax),%esi
|
||||
jb LSkip_mip2
|
||||
subl C(r_stepback),%esi
|
||||
LSkip_mip2:
|
||||
|
||||
movl C(r_lightptr),%ebx
|
||||
decl sb_v
|
||||
|
||||
jnz Lv_loop_mip2
|
||||
|
||||
popl %ebx // restore register variables
|
||||
popl %esi
|
||||
popl %edi
|
||||
popl %ebp // restore the caller's stack frame
|
||||
ret
|
||||
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// Surface block drawer for mip level 3
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
.align 4
|
||||
.globl C(R_DrawSurfaceBlock8_mip3)
|
||||
C(R_DrawSurfaceBlock8_mip3):
|
||||
pushl %ebp // preserve caller's stack frame
|
||||
pushl %edi
|
||||
pushl %esi // preserve register variables
|
||||
pushl %ebx
|
||||
|
||||
// for (v=0 ; v<numvblocks ; v++)
|
||||
// {
|
||||
movl C(r_lightptr),%ebx
|
||||
movl C(r_numvblocks),%eax
|
||||
|
||||
movl %eax,sb_v
|
||||
movl C(prowdestbase),%edi
|
||||
|
||||
movl C(pbasesource),%esi
|
||||
|
||||
Lv_loop_mip3:
|
||||
|
||||
// lightleft = lightptr[0];
|
||||
// lightright = lightptr[1];
|
||||
// lightdelta = (lightleft - lightright) & 0xFFFFF;
|
||||
movl (%ebx),%eax // lightleft
|
||||
movl 4(%ebx),%edx // lightright
|
||||
|
||||
movl %eax,%ebp
|
||||
movl C(r_lightwidth),%ecx
|
||||
|
||||
movl %edx,C(lightright)
|
||||
subl %edx,%ebp
|
||||
|
||||
andl $0xFFFFF,%ebp
|
||||
leal (%ebx,%ecx,4),%ebx
|
||||
|
||||
movl %ebp,C(lightdelta)
|
||||
// lightptr += lightwidth;
|
||||
movl %ebx,C(r_lightptr)
|
||||
|
||||
// lightleftstep = (lightptr[0] - lightleft) >> blockdivshift;
|
||||
// lightrightstep = (lightptr[1] - lightright) >> blockdivshift;
|
||||
// lightdeltastep = ((lightleftstep - lightrightstep) & 0xFFFFF) |
|
||||
// 0xF0000000;
|
||||
movl 4(%ebx),%ecx // lightptr[1]
|
||||
movl (%ebx),%ebx // lightptr[0]
|
||||
|
||||
subl %eax,%ebx
|
||||
subl %edx,%ecx
|
||||
|
||||
sarl $1,%ecx
|
||||
|
||||
sarl $1,%ebx
|
||||
movl %ecx,C(lightrightstep)
|
||||
|
||||
subl %ecx,%ebx
|
||||
andl $0xFFFFF,%ebx
|
||||
|
||||
sarl $1,%ebp
|
||||
orl $0xF0000000,%ebx
|
||||
|
||||
movl %ebx,C(lightdeltastep)
|
||||
subl %ebx,%ebx // high word must be 0 in loop for addressing
|
||||
|
||||
movb 1(%esi),%bl
|
||||
subl %ecx,%ecx // high word must be 0 in loop for addressing
|
||||
|
||||
movb %dh,%bh
|
||||
movb (%esi),%cl
|
||||
|
||||
addl %ebp,%edx
|
||||
movb %dh,%ch
|
||||
|
||||
movb 0x12345678(%ebx),%al
|
||||
LBPatch16:
|
||||
movl C(lightright),%edx
|
||||
|
||||
movb %al,1(%edi)
|
||||
movb 0x12345678(%ecx),%al
|
||||
LBPatch17:
|
||||
|
||||
movb %al,(%edi)
|
||||
movl C(sourcetstep),%eax
|
||||
|
||||
addl %eax,%esi
|
||||
movl C(surfrowbytes),%eax
|
||||
|
||||
addl %eax,%edi
|
||||
movl C(lightdeltastep),%eax
|
||||
|
||||
movl C(lightdelta),%ebp
|
||||
movb (%esi),%cl
|
||||
|
||||
addl %eax,%ebp
|
||||
movl C(lightrightstep),%eax
|
||||
|
||||
sarl $1,%ebp
|
||||
addl %eax,%edx
|
||||
|
||||
movb %dh,%bh
|
||||
movb 1(%esi),%bl
|
||||
|
||||
addl %ebp,%edx
|
||||
movb %dh,%ch
|
||||
|
||||
movb 0x12345678(%ebx),%al
|
||||
LBPatch30:
|
||||
movl C(sourcetstep),%edx
|
||||
|
||||
movb %al,1(%edi)
|
||||
movb 0x12345678(%ecx),%al
|
||||
LBPatch31:
|
||||
|
||||
movb %al,(%edi)
|
||||
movl C(surfrowbytes),%ebp
|
||||
|
||||
addl %edx,%esi
|
||||
addl %ebp,%edi
|
||||
|
||||
// if (pbasesource >= r_sourcemax)
|
||||
// pbasesource -= stepback;
|
||||
|
||||
cmpl C(r_sourcemax),%esi
|
||||
jb LSkip_mip3
|
||||
subl C(r_stepback),%esi
|
||||
LSkip_mip3:
|
||||
|
||||
movl C(r_lightptr),%ebx
|
||||
decl sb_v
|
||||
|
||||
jnz Lv_loop_mip3
|
||||
|
||||
popl %ebx // restore register variables
|
||||
popl %esi
|
||||
popl %edi
|
||||
popl %ebp // restore the caller's stack frame
|
||||
ret
|
||||
|
||||
|
||||
.globl C(R_Surf8End)
|
||||
C(R_Surf8End):
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// Code patching routines
|
||||
//----------------------------------------------------------------------
|
||||
.data
|
||||
|
||||
.align 4
|
||||
LPatchTable8:
|
||||
.long LBPatch0-4
|
||||
.long LBPatch1-4
|
||||
.long LBPatch2-4
|
||||
.long LBPatch3-4
|
||||
.long LBPatch4-4
|
||||
.long LBPatch5-4
|
||||
.long LBPatch6-4
|
||||
.long LBPatch7-4
|
||||
.long LBPatch8-4
|
||||
.long LBPatch9-4
|
||||
.long LBPatch10-4
|
||||
.long LBPatch11-4
|
||||
.long LBPatch12-4
|
||||
.long LBPatch13-4
|
||||
.long LBPatch14-4
|
||||
.long LBPatch15-4
|
||||
.long LBPatch16-4
|
||||
.long LBPatch17-4
|
||||
.long LBPatch18-4
|
||||
.long LBPatch19-4
|
||||
.long LBPatch20-4
|
||||
.long LBPatch21-4
|
||||
.long LBPatch22-4
|
||||
.long LBPatch23-4
|
||||
.long LBPatch24-4
|
||||
.long LBPatch25-4
|
||||
.long LBPatch26-4
|
||||
.long LBPatch27-4
|
||||
.long LBPatch28-4
|
||||
.long LBPatch29-4
|
||||
.long LBPatch30-4
|
||||
.long LBPatch31-4
|
||||
|
||||
.text
|
||||
|
||||
.align 4
|
||||
.globl C(R_Surf8Patch)
|
||||
C(R_Surf8Patch):
|
||||
pushl %ebx
|
||||
|
||||
movl C(colormap),%eax
|
||||
movl $LPatchTable8,%ebx
|
||||
movl $32,%ecx
|
||||
LPatchLoop8:
|
||||
movl (%ebx),%edx
|
||||
addl $4,%ebx
|
||||
movl %eax,(%edx)
|
||||
decl %ecx
|
||||
jnz LPatchLoop8
|
||||
|
||||
popl %ebx
|
||||
|
||||
ret
|
||||
|
||||
#endif // id386
|
223
linux/r_varsa.s
Normal file
223
linux/r_varsa.s
Normal file
@ -0,0 +1,223 @@
|
||||
//
|
||||
// r_varsa.s
|
||||
//
|
||||
|
||||
#include "qasm.h"
|
||||
#include "d_ifacea.h"
|
||||
|
||||
#if id386
|
||||
|
||||
.data
|
||||
|
||||
//-------------------------------------------------------
|
||||
// ASM-only variables
|
||||
//-------------------------------------------------------
|
||||
.globl float_1, float_particle_z_clip, float_point5
|
||||
.globl float_minus_1, float_0
|
||||
float_0: .single 0.0
|
||||
float_1: .single 1.0
|
||||
float_minus_1: .single -1.0
|
||||
float_particle_z_clip: .single PARTICLE_Z_CLIP
|
||||
float_point5: .single 0.5
|
||||
|
||||
.globl fp_16, fp_64k, fp_1m, fp_64kx64k
|
||||
.globl fp_1m_minus_1
|
||||
.globl fp_8
|
||||
fp_1m: .single 1048576.0
|
||||
fp_1m_minus_1: .single 1048575.0
|
||||
fp_64k: .single 65536.0
|
||||
fp_8: .single 8.0
|
||||
fp_16: .single 16.0
|
||||
fp_64kx64k: .long 0x4f000000 // (float)0x8000*0x10000
|
||||
|
||||
|
||||
.globl FloatZero, Float2ToThe31nd, FloatMinus2ToThe31nd
|
||||
FloatZero: .long 0
|
||||
Float2ToThe31nd: .long 0x4f000000
|
||||
FloatMinus2ToThe31nd: .long 0xcf000000
|
||||
|
||||
.globl C(r_bmodelactive)
|
||||
C(r_bmodelactive): .long 0
|
||||
|
||||
//-------------------------------------------------------
|
||||
// global refresh variables
|
||||
//-------------------------------------------------------
|
||||
|
||||
// FIXME: put all refresh variables into one contiguous block. Make into one
|
||||
// big structure, like cl or sv?
|
||||
|
||||
.align 4
|
||||
.globl C(d_sdivzstepu)
|
||||
.globl C(d_tdivzstepu)
|
||||
.globl C(d_zistepu)
|
||||
.globl C(d_sdivzstepv)
|
||||
.globl C(d_tdivzstepv)
|
||||
.globl C(d_zistepv)
|
||||
.globl C(d_sdivzorigin)
|
||||
.globl C(d_tdivzorigin)
|
||||
.globl C(d_ziorigin)
|
||||
C(d_sdivzstepu): .single 0
|
||||
C(d_tdivzstepu): .single 0
|
||||
C(d_zistepu): .single 0
|
||||
C(d_sdivzstepv): .single 0
|
||||
C(d_tdivzstepv): .single 0
|
||||
C(d_zistepv): .single 0
|
||||
C(d_sdivzorigin): .single 0
|
||||
C(d_tdivzorigin): .single 0
|
||||
C(d_ziorigin): .single 0
|
||||
|
||||
.globl C(sadjust)
|
||||
.globl C(tadjust)
|
||||
.globl C(bbextents)
|
||||
.globl C(bbextentt)
|
||||
C(sadjust): .long 0
|
||||
C(tadjust): .long 0
|
||||
C(bbextents): .long 0
|
||||
C(bbextentt): .long 0
|
||||
|
||||
.globl C(cacheblock)
|
||||
.globl C(d_viewbuffer)
|
||||
.globl C(cachewidth)
|
||||
.globl C(d_pzbuffer)
|
||||
.globl C(d_zrowbytes)
|
||||
.globl C(d_zwidth)
|
||||
C(cacheblock): .long 0
|
||||
C(cachewidth): .long 0
|
||||
C(d_viewbuffer): .long 0
|
||||
C(d_pzbuffer): .long 0
|
||||
C(d_zrowbytes): .long 0
|
||||
C(d_zwidth): .long 0
|
||||
|
||||
|
||||
//-------------------------------------------------------
|
||||
// ASM-only variables
|
||||
//-------------------------------------------------------
|
||||
.globl izi
|
||||
izi: .long 0
|
||||
|
||||
.globl pbase, s, t, sfracf, tfracf, snext, tnext
|
||||
.globl spancountminus1, zi16stepu, sdivz16stepu, tdivz16stepu
|
||||
.globl zi8stepu, sdivz8stepu, tdivz8stepu, pz
|
||||
s: .long 0
|
||||
t: .long 0
|
||||
snext: .long 0
|
||||
tnext: .long 0
|
||||
sfracf: .long 0
|
||||
tfracf: .long 0
|
||||
pbase: .long 0
|
||||
zi8stepu: .long 0
|
||||
sdivz8stepu: .long 0
|
||||
tdivz8stepu: .long 0
|
||||
zi16stepu: .long 0
|
||||
sdivz16stepu: .long 0
|
||||
tdivz16stepu: .long 0
|
||||
spancountminus1: .long 0
|
||||
pz: .long 0
|
||||
|
||||
.globl izistep
|
||||
izistep: .long 0
|
||||
|
||||
//-------------------------------------------------------
|
||||
// local variables for d_draw16.s
|
||||
//-------------------------------------------------------
|
||||
|
||||
.globl reciprocal_table_16, entryvec_table_16
|
||||
// 1/2, 1/3, 1/4, 1/5, 1/6, 1/7, 1/8, 1/9, 1/10, 1/11, 1/12, 1/13,
|
||||
// 1/14, and 1/15 in 0.32 form
|
||||
reciprocal_table_16: .long 0x40000000, 0x2aaaaaaa, 0x20000000
|
||||
.long 0x19999999, 0x15555555, 0x12492492
|
||||
.long 0x10000000, 0xe38e38e, 0xccccccc, 0xba2e8ba
|
||||
.long 0xaaaaaaa, 0x9d89d89, 0x9249249, 0x8888888
|
||||
|
||||
#ifndef NeXT
|
||||
.extern Entry2_16
|
||||
.extern Entry3_16
|
||||
.extern Entry4_16
|
||||
.extern Entry5_16
|
||||
.extern Entry6_16
|
||||
.extern Entry7_16
|
||||
.extern Entry8_16
|
||||
.extern Entry9_16
|
||||
.extern Entry10_16
|
||||
.extern Entry11_16
|
||||
.extern Entry12_16
|
||||
.extern Entry13_16
|
||||
.extern Entry14_16
|
||||
.extern Entry15_16
|
||||
.extern Entry16_16
|
||||
#endif
|
||||
|
||||
entryvec_table_16: .long 0, Entry2_16, Entry3_16, Entry4_16
|
||||
.long Entry5_16, Entry6_16, Entry7_16, Entry8_16
|
||||
.long Entry9_16, Entry10_16, Entry11_16, Entry12_16
|
||||
.long Entry13_16, Entry14_16, Entry15_16, Entry16_16
|
||||
|
||||
//-------------------------------------------------------
|
||||
// local variables for d_parta.s
|
||||
//-------------------------------------------------------
|
||||
.globl DP_Count, DP_u, DP_v, DP_32768, DP_Color, DP_Pix, DP_EntryTable
|
||||
DP_Count: .long 0
|
||||
DP_u: .long 0
|
||||
DP_v: .long 0
|
||||
DP_32768: .single 32768.0
|
||||
DP_Color: .long 0
|
||||
DP_Pix: .long 0
|
||||
|
||||
|
||||
#if 0
|
||||
.extern DP_1x1
|
||||
.extern DP_2x2
|
||||
.extern DP_3x3
|
||||
.extern DP_4x4
|
||||
|
||||
DP_EntryTable: .long DP_1x1, DP_2x2, DP_3x3, DP_4x4
|
||||
#endif
|
||||
|
||||
//
|
||||
// advancetable is 8 bytes, but points to the middle of that range so negative
|
||||
// offsets will work
|
||||
//
|
||||
.globl advancetable, sstep, tstep, pspantemp, counttemp, jumptemp
|
||||
advancetable: .long 0, 0
|
||||
sstep: .long 0
|
||||
tstep: .long 0
|
||||
|
||||
pspantemp: .long 0
|
||||
counttemp: .long 0
|
||||
jumptemp: .long 0
|
||||
|
||||
// 1/2, 1/3, 1/4, 1/5, 1/6, and 1/7 in 0.32 form
|
||||
.globl reciprocal_table, entryvec_table
|
||||
reciprocal_table: .long 0x40000000, 0x2aaaaaaa, 0x20000000
|
||||
.long 0x19999999, 0x15555555, 0x12492492
|
||||
|
||||
#if 0
|
||||
.extern Entry2_8
|
||||
.extern Entry3_8
|
||||
.extern Entry4_8
|
||||
.extern Entry5_8
|
||||
.extern Entry6_8
|
||||
.extern Entry7_8
|
||||
.extern Entry8_8
|
||||
|
||||
entryvec_table: .long 0, Entry2_8, Entry3_8, Entry4_8
|
||||
.long Entry5_8, Entry6_8, Entry7_8, Entry8_8
|
||||
#endif
|
||||
|
||||
#ifndef NeXT
|
||||
.extern Spr8Entry2_8
|
||||
.extern Spr8Entry3_8
|
||||
.extern Spr8Entry4_8
|
||||
.extern Spr8Entry5_8
|
||||
.extern Spr8Entry6_8
|
||||
.extern Spr8Entry7_8
|
||||
.extern Spr8Entry8_8
|
||||
#endif
|
||||
|
||||
.globl spr8entryvec_table
|
||||
spr8entryvec_table: .long 0, Spr8Entry2_8, Spr8Entry3_8, Spr8Entry4_8
|
||||
.long Spr8Entry5_8, Spr8Entry6_8, Spr8Entry7_8, Spr8Entry8_8
|
||||
|
||||
#endif // id386
|
||||
|
||||
|
374
linux/rw_in_svgalib.c
Normal file
374
linux/rw_in_svgalib.c
Normal file
@ -0,0 +1,374 @@
|
||||
#include <termios.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/vt.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <signal.h>
|
||||
#include <sys/mman.h>
|
||||
|
||||
#include <asm/io.h>
|
||||
|
||||
#include "vga.h"
|
||||
#include "vgakeyboard.h"
|
||||
#include "vgamouse.h"
|
||||
|
||||
#include "../ref_soft/r_local.h"
|
||||
#include "../client/keys.h"
|
||||
#include "../linux/rw_linux.h"
|
||||
|
||||
/*****************************************************************************/
|
||||
/* KEYBOARD */
|
||||
/*****************************************************************************/
|
||||
|
||||
static unsigned char scantokey[128];
|
||||
Key_Event_fp_t Key_Event_fp;
|
||||
|
||||
static void keyhandler(int scancode, int state)
|
||||
{
|
||||
int sc;
|
||||
|
||||
sc = scancode & 0x7f;
|
||||
//ri.Con_Printf(PRINT_ALL, "scancode=%x (%d%s)\n", scancode, sc, scancode&0x80?"+128":"");
|
||||
Key_Event_fp(scantokey[sc], state == KEY_EVENTPRESS);
|
||||
}
|
||||
|
||||
void KBD_Init(Key_Event_fp_t fp)
|
||||
{
|
||||
int i;
|
||||
|
||||
Key_Event_fp = fp;
|
||||
|
||||
for (i=0 ; i<128 ; i++)
|
||||
scantokey[i] = ' ';
|
||||
|
||||
scantokey[ 1] = K_ESCAPE;
|
||||
scantokey[ 2] = '1';
|
||||
scantokey[ 3] = '2';
|
||||
scantokey[ 4] = '3';
|
||||
scantokey[ 5] = '4';
|
||||
scantokey[ 6] = '5';
|
||||
scantokey[ 7] = '6';
|
||||
scantokey[ 8] = '7';
|
||||
scantokey[ 9] = '8';
|
||||
scantokey[ 10] = '9';
|
||||
scantokey[ 11] = '0';
|
||||
scantokey[ 12] = '-';
|
||||
scantokey[ 13] = '=';
|
||||
scantokey[ 14] = K_BACKSPACE;
|
||||
scantokey[ 15] = K_TAB;
|
||||
scantokey[ 16] = 'q';
|
||||
scantokey[ 17] = 'w';
|
||||
scantokey[ 18] = 'e';
|
||||
scantokey[ 19] = 'r';
|
||||
scantokey[ 20] = 't';
|
||||
scantokey[ 21] = 'y';
|
||||
scantokey[ 22] = 'u';
|
||||
scantokey[ 23] = 'i';
|
||||
scantokey[ 24] = 'o';
|
||||
scantokey[ 25] = 'p';
|
||||
scantokey[ 26] = '[';
|
||||
scantokey[ 27] = ']';
|
||||
scantokey[ 28] = K_ENTER;
|
||||
scantokey[ 29] = K_CTRL; //left
|
||||
scantokey[ 30] = 'a';
|
||||
scantokey[ 31] = 's';
|
||||
scantokey[ 32] = 'd';
|
||||
scantokey[ 33] = 'f';
|
||||
scantokey[ 34] = 'g';
|
||||
scantokey[ 35] = 'h';
|
||||
scantokey[ 36] = 'j';
|
||||
scantokey[ 37] = 'k';
|
||||
scantokey[ 38] = 'l';
|
||||
scantokey[ 39] = ';';
|
||||
scantokey[ 40] = '\'';
|
||||
scantokey[ 41] = '`';
|
||||
scantokey[ 42] = K_SHIFT; //left
|
||||
scantokey[ 43] = '\\';
|
||||
scantokey[ 44] = 'z';
|
||||
scantokey[ 45] = 'x';
|
||||
scantokey[ 46] = 'c';
|
||||
scantokey[ 47] = 'v';
|
||||
scantokey[ 48] = 'b';
|
||||
scantokey[ 49] = 'n';
|
||||
scantokey[ 50] = 'm';
|
||||
scantokey[ 51] = ',';
|
||||
scantokey[ 52] = '.';
|
||||
scantokey[ 53] = '/';
|
||||
scantokey[ 54] = K_SHIFT; //right
|
||||
scantokey[ 55] = '*'; //keypad
|
||||
scantokey[ 56] = K_ALT; //left
|
||||
scantokey[ 57] = ' ';
|
||||
// 58 caps lock
|
||||
scantokey[ 59] = K_F1;
|
||||
scantokey[ 60] = K_F2;
|
||||
scantokey[ 61] = K_F3;
|
||||
scantokey[ 62] = K_F4;
|
||||
scantokey[ 63] = K_F5;
|
||||
scantokey[ 64] = K_F6;
|
||||
scantokey[ 65] = K_F7;
|
||||
scantokey[ 66] = K_F8;
|
||||
scantokey[ 67] = K_F9;
|
||||
scantokey[ 68] = K_F10;
|
||||
// 69 numlock
|
||||
// 70 scrollock
|
||||
scantokey[ 71] = K_KP_HOME;
|
||||
scantokey[ 72] = K_KP_UPARROW;
|
||||
scantokey[ 73] = K_KP_PGUP;
|
||||
scantokey[ 74] = K_KP_MINUS;
|
||||
scantokey[ 75] = K_KP_LEFTARROW;
|
||||
scantokey[ 76] = K_KP_5;
|
||||
scantokey[ 77] = K_KP_RIGHTARROW;
|
||||
scantokey[ 79] = K_KP_END;
|
||||
scantokey[ 78] = K_KP_PLUS;
|
||||
scantokey[ 80] = K_KP_DOWNARROW;
|
||||
scantokey[ 81] = K_KP_PGDN;
|
||||
scantokey[ 82] = K_KP_INS;
|
||||
scantokey[ 83] = K_KP_DEL;
|
||||
// 84 to 86 not used
|
||||
scantokey[ 87] = K_F11;
|
||||
scantokey[ 88] = K_F12;
|
||||
// 89 to 95 not used
|
||||
scantokey[ 96] = K_KP_ENTER; //keypad enter
|
||||
scantokey[ 97] = K_CTRL; //right
|
||||
scantokey[ 98] = K_KP_SLASH;
|
||||
scantokey[ 99] = K_F12; // print screen, bind to screenshot by default
|
||||
scantokey[100] = K_ALT; // right
|
||||
|
||||
scantokey[101] = K_PAUSE; // break
|
||||
scantokey[102] = K_HOME;
|
||||
scantokey[103] = K_UPARROW;
|
||||
scantokey[104] = K_PGUP;
|
||||
scantokey[105] = K_LEFTARROW;
|
||||
scantokey[106] = K_RIGHTARROW;
|
||||
scantokey[107] = K_END;
|
||||
scantokey[108] = K_DOWNARROW;
|
||||
scantokey[109] = K_PGDN;
|
||||
scantokey[110] = K_INS;
|
||||
scantokey[111] = K_DEL;
|
||||
|
||||
scantokey[119] = K_PAUSE;
|
||||
|
||||
if (keyboard_init())
|
||||
Sys_Error("keyboard_init() failed");
|
||||
keyboard_seteventhandler(keyhandler);
|
||||
keyboard_translatekeys(DONT_CATCH_CTRLC);
|
||||
}
|
||||
|
||||
void KBD_Update(void)
|
||||
{
|
||||
while (keyboard_update())
|
||||
;
|
||||
}
|
||||
|
||||
void KBD_Close(void)
|
||||
{
|
||||
keyboard_close();
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/* MOUSE */
|
||||
/*****************************************************************************/
|
||||
|
||||
// this is inside the renderer shared lib, so these are called from vid_so
|
||||
|
||||
static qboolean UseMouse = true;
|
||||
|
||||
static int mouserate = MOUSE_DEFAULTSAMPLERATE;
|
||||
|
||||
static int mouse_buttons;
|
||||
static int mouse_buttonstate;
|
||||
static int mouse_oldbuttonstate;
|
||||
static float mouse_x, mouse_y;
|
||||
static float old_mouse_x, old_mouse_y;
|
||||
static int mx, my;
|
||||
|
||||
static cvar_t *m_filter;
|
||||
static cvar_t *in_mouse;
|
||||
|
||||
static cvar_t *mdev;
|
||||
static cvar_t *mrate;
|
||||
|
||||
static qboolean mlooking;
|
||||
|
||||
// state struct passed in Init
|
||||
static in_state_t *in_state;
|
||||
|
||||
static cvar_t *sensitivity;
|
||||
static cvar_t *lookstrafe;
|
||||
static cvar_t *m_side;
|
||||
static cvar_t *m_yaw;
|
||||
static cvar_t *m_pitch;
|
||||
static cvar_t *m_forward;
|
||||
static cvar_t *freelook;
|
||||
|
||||
static void Force_CenterView_f (void)
|
||||
{
|
||||
in_state->viewangles[PITCH] = 0;
|
||||
}
|
||||
|
||||
static void RW_IN_MLookDown (void)
|
||||
{
|
||||
mlooking = true;
|
||||
}
|
||||
|
||||
static void RW_IN_MLookUp (void)
|
||||
{
|
||||
mlooking = false;
|
||||
in_state->IN_CenterView_fp ();
|
||||
}
|
||||
|
||||
static void mousehandler(int buttonstate, int dx, int dy)
|
||||
{
|
||||
mouse_buttonstate = buttonstate;
|
||||
mx += dx;
|
||||
my += dy;
|
||||
}
|
||||
|
||||
void RW_IN_Init(in_state_t *in_state_p)
|
||||
{
|
||||
int mtype;
|
||||
int i;
|
||||
|
||||
in_state = in_state_p;
|
||||
|
||||
// mouse variables
|
||||
m_filter = ri.Cvar_Get ("m_filter", "0", 0);
|
||||
in_mouse = ri.Cvar_Get ("in_mouse", "1", CVAR_ARCHIVE);
|
||||
freelook = ri.Cvar_Get( "freelook", "0", 0 );
|
||||
lookstrafe = ri.Cvar_Get ("lookstrafe", "0", 0);
|
||||
sensitivity = ri.Cvar_Get ("sensitivity", "3", 0);
|
||||
m_pitch = ri.Cvar_Get ("m_pitch", "0.022", 0);
|
||||
m_yaw = ri.Cvar_Get ("m_yaw", "0.022", 0);
|
||||
m_forward = ri.Cvar_Get ("m_forward", "1", 0);
|
||||
m_side = ri.Cvar_Get ("m_side", "0.8", 0);
|
||||
|
||||
ri.Cmd_AddCommand ("+mlook", RW_IN_MLookDown);
|
||||
ri.Cmd_AddCommand ("-mlook", RW_IN_MLookUp);
|
||||
|
||||
ri.Cmd_AddCommand ("force_centerview", Force_CenterView_f);
|
||||
|
||||
mouse_buttons = 3;
|
||||
|
||||
mtype = vga_getmousetype();
|
||||
|
||||
mdev = ri.Cvar_Get ("mdev", "/dev/mouse", 0);
|
||||
mrate = ri.Cvar_Get ("mrate", "1200", 0);
|
||||
|
||||
// printf("Mouse: dev=%s,type=%s,speed=%d\n",
|
||||
// mousedev, mice[mtype].name, mouserate);
|
||||
|
||||
if (mouse_init(mdev->string, mtype, (int)mrate->value))
|
||||
{
|
||||
ri.Con_Printf(PRINT_ALL, "No mouse found\n");
|
||||
UseMouse = false;
|
||||
}
|
||||
else
|
||||
mouse_seteventhandler(mousehandler);
|
||||
}
|
||||
|
||||
void RW_IN_Shutdown(void)
|
||||
{
|
||||
mouse_close();
|
||||
}
|
||||
|
||||
/*
|
||||
===========
|
||||
IN_Commands
|
||||
===========
|
||||
*/
|
||||
void RW_IN_Commands (void)
|
||||
{
|
||||
if (!UseMouse)
|
||||
return;
|
||||
|
||||
// poll mouse values
|
||||
mouse_update();
|
||||
|
||||
// perform button actions
|
||||
if ((mouse_buttonstate & MOUSE_LEFTBUTTON) &&
|
||||
!(mouse_oldbuttonstate & MOUSE_LEFTBUTTON))
|
||||
in_state->Key_Event_fp (K_MOUSE1, true);
|
||||
else if (!(mouse_buttonstate & MOUSE_LEFTBUTTON) &&
|
||||
(mouse_oldbuttonstate & MOUSE_LEFTBUTTON))
|
||||
in_state->Key_Event_fp (K_MOUSE1, false);
|
||||
|
||||
if ((mouse_buttonstate & MOUSE_RIGHTBUTTON) &&
|
||||
!(mouse_oldbuttonstate & MOUSE_RIGHTBUTTON))
|
||||
in_state->Key_Event_fp (K_MOUSE2, true);
|
||||
else if (!(mouse_buttonstate & MOUSE_RIGHTBUTTON) &&
|
||||
(mouse_oldbuttonstate & MOUSE_RIGHTBUTTON))
|
||||
in_state->Key_Event_fp (K_MOUSE2, false);
|
||||
|
||||
if ((mouse_buttonstate & MOUSE_MIDDLEBUTTON) &&
|
||||
!(mouse_oldbuttonstate & MOUSE_MIDDLEBUTTON))
|
||||
Key_Event_fp (K_MOUSE3, true);
|
||||
else if (!(mouse_buttonstate & MOUSE_MIDDLEBUTTON) &&
|
||||
(mouse_oldbuttonstate & MOUSE_MIDDLEBUTTON))
|
||||
in_state->Key_Event_fp (K_MOUSE3, false);
|
||||
|
||||
mouse_oldbuttonstate = mouse_buttonstate;
|
||||
}
|
||||
|
||||
/*
|
||||
===========
|
||||
IN_Move
|
||||
===========
|
||||
*/
|
||||
void RW_IN_Move (usercmd_t *cmd)
|
||||
{
|
||||
if (!UseMouse)
|
||||
return;
|
||||
|
||||
// poll mouse values
|
||||
mouse_update();
|
||||
|
||||
if (m_filter->value)
|
||||
{
|
||||
mouse_x = (mx + old_mouse_x) * 0.5;
|
||||
mouse_y = (my + old_mouse_y) * 0.5;
|
||||
}
|
||||
else
|
||||
{
|
||||
mouse_x = mx;
|
||||
mouse_y = my;
|
||||
}
|
||||
old_mouse_x = mx;
|
||||
old_mouse_y = my;
|
||||
|
||||
if (!mx && !my)
|
||||
return;
|
||||
|
||||
mx = my = 0; // clear for next update
|
||||
|
||||
mouse_x *= sensitivity->value;
|
||||
mouse_y *= sensitivity->value;
|
||||
|
||||
// add mouse X/Y movement to cmd
|
||||
if ( (*in_state->in_strafe_state & 1) ||
|
||||
(lookstrafe->value && mlooking ))
|
||||
cmd->sidemove += m_side->value * mouse_x;
|
||||
else
|
||||
in_state->viewangles[YAW] -= m_yaw->value * mouse_x;
|
||||
|
||||
if ( (mlooking || freelook->value) &&
|
||||
!(*in_state->in_strafe_state & 1))
|
||||
{
|
||||
in_state->viewangles[PITCH] += m_pitch->value * mouse_y;
|
||||
}
|
||||
else
|
||||
{
|
||||
cmd->forwardmove -= m_forward->value * mouse_y;
|
||||
}
|
||||
}
|
||||
|
||||
void RW_IN_Frame (void)
|
||||
{
|
||||
}
|
||||
|
||||
void RW_IN_Activate(void)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
|
16
linux/rw_linux.h
Normal file
16
linux/rw_linux.h
Normal file
@ -0,0 +1,16 @@
|
||||
|
||||
|
||||
typedef void (*Key_Event_fp_t)(int key, qboolean down);
|
||||
|
||||
extern void (*KBD_Update_fp)(void);
|
||||
extern void (*KBD_Init_fp)(Key_Event_fp_t fp);
|
||||
extern void (*KBD_Close_fp)(void);
|
||||
|
||||
typedef struct in_state {
|
||||
// Pointers to functions back in client, set by vid_so
|
||||
void (*IN_CenterView_fp)(void);
|
||||
Key_Event_fp_t Key_Event_fp;
|
||||
vec_t *viewangles;
|
||||
int *in_strafe_state;
|
||||
} in_state_t;
|
||||
|
311
linux/rw_svgalib.c
Normal file
311
linux/rw_svgalib.c
Normal file
@ -0,0 +1,311 @@
|
||||
/*
|
||||
** RW_SVGALBI.C
|
||||
**
|
||||
** This file contains ALL Linux specific stuff having to do with the
|
||||
** software refresh. When a port is being made the following functions
|
||||
** must be implemented by the port:
|
||||
**
|
||||
** SWimp_EndFrame
|
||||
** SWimp_Init
|
||||
** SWimp_InitGraphics
|
||||
** SWimp_SetPalette
|
||||
** SWimp_Shutdown
|
||||
** SWimp_SwitchFullscreen
|
||||
*/
|
||||
|
||||
#include <termios.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/vt.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <signal.h>
|
||||
#include <sys/mman.h>
|
||||
|
||||
#include <asm/io.h>
|
||||
|
||||
#include "vga.h"
|
||||
#include "vgakeyboard.h"
|
||||
#include "vgamouse.h"
|
||||
|
||||
#include "../ref_soft/r_local.h"
|
||||
#include "../client/keys.h"
|
||||
#include "../linux/rw_linux.h"
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
int VGA_width, VGA_height, VGA_rowbytes, VGA_bufferrowbytes, VGA_planar;
|
||||
byte *VGA_pagebase;
|
||||
char *framebuffer_ptr;
|
||||
|
||||
void VGA_UpdatePlanarScreen (void *srcbuffer);
|
||||
|
||||
int num_modes;
|
||||
vga_modeinfo *modes;
|
||||
int current_mode;
|
||||
|
||||
// Console variables that we need to access from this module
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
void VID_InitModes(void)
|
||||
{
|
||||
|
||||
int i;
|
||||
|
||||
// get complete information on all modes
|
||||
|
||||
num_modes = vga_lastmodenumber()+1;
|
||||
modes = malloc(num_modes * sizeof(vga_modeinfo));
|
||||
for (i=0 ; i<num_modes ; i++)
|
||||
{
|
||||
if (vga_hasmode(i))
|
||||
memcpy(&modes[i], vga_getmodeinfo(i), sizeof (vga_modeinfo));
|
||||
else
|
||||
modes[i].width = 0; // means not available
|
||||
}
|
||||
|
||||
// filter for modes i don't support
|
||||
|
||||
for (i=0 ; i<num_modes ; i++)
|
||||
{
|
||||
if (modes[i].bytesperpixel != 1 && modes[i].colors != 256)
|
||||
modes[i].width = 0;
|
||||
}
|
||||
|
||||
for (i = 0; i < num_modes; i++)
|
||||
if (modes[i].width)
|
||||
ri.Con_Printf(PRINT_ALL, "mode %d: %d %d\n", modes[i].width, modes[i].height);
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
** SWimp_Init
|
||||
**
|
||||
** This routine is responsible for initializing the implementation
|
||||
** specific stuff in a software rendering subsystem.
|
||||
*/
|
||||
int SWimp_Init( void *hInstance, void *wndProc )
|
||||
{
|
||||
vga_init();
|
||||
|
||||
VID_InitModes();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
int get_mode(int width, int height)
|
||||
{
|
||||
|
||||
int i;
|
||||
int ok, match;
|
||||
|
||||
for (i=0 ; i<num_modes ; i++)
|
||||
if (modes[i].width &&
|
||||
modes[i].width == width && modes[i].height == height)
|
||||
break;
|
||||
if (i==num_modes)
|
||||
return -1; // not found
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
/*
|
||||
** SWimp_InitGraphics
|
||||
**
|
||||
** This initializes the software refresh's implementation specific
|
||||
** graphics subsystem. In the case of Windows it creates DIB or
|
||||
** DDRAW surfaces.
|
||||
**
|
||||
** The necessary width and height parameters are grabbed from
|
||||
** vid.width and vid.height.
|
||||
*/
|
||||
static qboolean SWimp_InitGraphics( qboolean fullscreen )
|
||||
{
|
||||
int bsize, zsize, tsize;
|
||||
|
||||
SWimp_Shutdown();
|
||||
|
||||
current_mode = get_mode(vid.width, vid.height);
|
||||
|
||||
if (current_mode < 0) {
|
||||
ri.Con_Printf (PRINT_ALL, "Mode %d %d not found\n", vid.width, vid.height);
|
||||
return false; // mode not found
|
||||
}
|
||||
|
||||
// let the sound and input subsystems know about the new window
|
||||
ri.Vid_NewWindow (vid.width, vid.height);
|
||||
|
||||
ri.Con_Printf (PRINT_ALL, "Setting VGAMode: %d\n", current_mode );
|
||||
|
||||
// Cvar_SetValue ("vid_mode", (float)modenum);
|
||||
|
||||
VGA_width = modes[current_mode].width;
|
||||
VGA_height = modes[current_mode].height;
|
||||
VGA_planar = modes[current_mode].bytesperpixel == 0;
|
||||
VGA_rowbytes = modes[current_mode].linewidth;
|
||||
|
||||
vid.rowbytes = modes[current_mode].linewidth;
|
||||
|
||||
if (VGA_planar) {
|
||||
VGA_bufferrowbytes = modes[current_mode].linewidth * 4;
|
||||
vid.rowbytes = modes[current_mode].linewidth*4;
|
||||
}
|
||||
|
||||
// get goin'
|
||||
|
||||
vga_setmode(current_mode);
|
||||
|
||||
VGA_pagebase = framebuffer_ptr = (char *) vga_getgraphmem();
|
||||
// if (vga_setlinearaddressing()>0)
|
||||
// framebuffer_ptr = (char *) vga_getgraphmem();
|
||||
if (!framebuffer_ptr)
|
||||
Sys_Error("This mode isn't hapnin'\n");
|
||||
|
||||
vga_setpage(0);
|
||||
|
||||
vid.buffer = malloc(vid.rowbytes * vid.height);
|
||||
if (!vid.buffer)
|
||||
Sys_Error("Unabled to alloc vid.buffer!\n");
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
** SWimp_EndFrame
|
||||
**
|
||||
** This does an implementation specific copy from the backbuffer to the
|
||||
** front buffer. In the Win32 case it uses BitBlt or BltFast depending
|
||||
** on whether we're using DIB sections/GDI or DDRAW.
|
||||
*/
|
||||
void SWimp_EndFrame (void)
|
||||
{
|
||||
if (!vga_oktowrite())
|
||||
return; // can't update screen if it's not active
|
||||
|
||||
// if (vid_waitforrefresh.value)
|
||||
// vga_waitretrace();
|
||||
|
||||
if (VGA_planar)
|
||||
VGA_UpdatePlanarScreen (vid.buffer);
|
||||
|
||||
else {
|
||||
int total = vid.rowbytes * vid.height;
|
||||
int offset;
|
||||
|
||||
for (offset=0;offset<total;offset+=0x10000) {
|
||||
vga_setpage(offset/0x10000);
|
||||
memcpy(framebuffer_ptr,
|
||||
vid.buffer + offset,
|
||||
((total-offset>0x10000)?0x10000:(total-offset)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** SWimp_SetMode
|
||||
*/
|
||||
rserr_t SWimp_SetMode( int *pwidth, int *pheight, int mode, qboolean fullscreen )
|
||||
{
|
||||
rserr_t retval = rserr_ok;
|
||||
|
||||
ri.Con_Printf (PRINT_ALL, "setting mode %d:", mode );
|
||||
|
||||
if ( !ri.Vid_GetModeInfo( pwidth, pheight, mode ) )
|
||||
{
|
||||
ri.Con_Printf( PRINT_ALL, " invalid mode\n" );
|
||||
return rserr_invalid_mode;
|
||||
}
|
||||
|
||||
ri.Con_Printf( PRINT_ALL, " %d %d\n", *pwidth, *pheight);
|
||||
|
||||
if ( !SWimp_InitGraphics( false ) ) {
|
||||
// failed to set a valid mode in windowed mode
|
||||
return rserr_invalid_mode;
|
||||
}
|
||||
|
||||
R_GammaCorrectAndSetPalette( ( const unsigned char * ) d_8to24table );
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
/*
|
||||
** SWimp_SetPalette
|
||||
**
|
||||
** System specific palette setting routine. A NULL palette means
|
||||
** to use the existing palette. The palette is expected to be in
|
||||
** a padded 4-byte xRGB format.
|
||||
*/
|
||||
void SWimp_SetPalette( const unsigned char *palette )
|
||||
{
|
||||
static int tmppal[256*3];
|
||||
const unsigned char *pal;
|
||||
int *tp;
|
||||
int i;
|
||||
|
||||
if ( !palette )
|
||||
palette = ( const unsigned char * ) sw_state.currentpalette;
|
||||
|
||||
if (vga_getcolors() == 256)
|
||||
{
|
||||
tp = tmppal;
|
||||
pal = palette;
|
||||
|
||||
for (i=0 ; i < 256 ; i++, pal += 4, tp += 3) {
|
||||
tp[0] = pal[0] >> 2;
|
||||
tp[1] = pal[1] >> 2;
|
||||
tp[2] = pal[2] >> 2;
|
||||
}
|
||||
|
||||
if (vga_oktowrite())
|
||||
vga_setpalvec(0, 256, tmppal);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** SWimp_Shutdown
|
||||
**
|
||||
** System specific graphics subsystem shutdown routine. Destroys
|
||||
** DIBs or DDRAW surfaces as appropriate.
|
||||
*/
|
||||
void SWimp_Shutdown( void )
|
||||
{
|
||||
if (vid.buffer) {
|
||||
free(vid.buffer);
|
||||
vid.buffer = NULL;
|
||||
}
|
||||
vga_setmode(TEXT);
|
||||
}
|
||||
|
||||
/*
|
||||
** SWimp_AppActivate
|
||||
*/
|
||||
void SWimp_AppActivate( qboolean active )
|
||||
{
|
||||
}
|
||||
|
||||
//===============================================================================
|
||||
|
||||
/*
|
||||
================
|
||||
Sys_MakeCodeWriteable
|
||||
================
|
||||
*/
|
||||
void Sys_MakeCodeWriteable (unsigned long startaddr, unsigned long length)
|
||||
{
|
||||
|
||||
int r;
|
||||
unsigned long addr;
|
||||
int psize = getpagesize();
|
||||
|
||||
addr = (startaddr & ~(psize-1)) - psize;
|
||||
|
||||
// fprintf(stderr, "writable code %lx(%lx)-%lx, length=%lx\n", startaddr,
|
||||
// addr, startaddr+length, length);
|
||||
|
||||
r = mprotect((char*)addr, length + startaddr - addr + psize, 7);
|
||||
|
||||
if (r < 0)
|
||||
Sys_Error("Protection change failed\n");
|
||||
}
|
||||
|
1093
linux/rw_x11.c
Normal file
1093
linux/rw_x11.c
Normal file
File diff suppressed because it is too large
Load Diff
266
linux/snd_linux.c
Normal file
266
linux/snd_linux.c
Normal file
@ -0,0 +1,266 @@
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/mman.h>
|
||||
#include <sys/shm.h>
|
||||
#include <sys/wait.h>
|
||||
#include <linux/soundcard.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "../client/client.h"
|
||||
#include "../client/snd_loc.h"
|
||||
|
||||
int audio_fd;
|
||||
int snd_inited;
|
||||
|
||||
cvar_t *sndbits;
|
||||
cvar_t *sndspeed;
|
||||
cvar_t *sndchannels;
|
||||
cvar_t *snddevice;
|
||||
|
||||
static int tryrates[] = { 11025, 22051, 44100, 8000 };
|
||||
|
||||
qboolean SNDDMA_Init(void)
|
||||
{
|
||||
|
||||
int rc;
|
||||
int fmt;
|
||||
int tmp;
|
||||
int i;
|
||||
char *s;
|
||||
struct audio_buf_info info;
|
||||
int caps;
|
||||
extern uid_t saved_euid;
|
||||
|
||||
if (snd_inited)
|
||||
return;
|
||||
|
||||
if (!snddevice) {
|
||||
sndbits = Cvar_Get("sndbits", "16", CVAR_ARCHIVE);
|
||||
sndspeed = Cvar_Get("sndspeed", "0", CVAR_ARCHIVE);
|
||||
sndchannels = Cvar_Get("sndchannels", "2", CVAR_ARCHIVE);
|
||||
snddevice = Cvar_Get("snddevice", "/dev/dsp", CVAR_ARCHIVE);
|
||||
}
|
||||
|
||||
// open /dev/dsp, confirm capability to mmap, and get size of dma buffer
|
||||
|
||||
if (!audio_fd) {
|
||||
seteuid(saved_euid);
|
||||
|
||||
audio_fd = open(snddevice->string, O_RDWR);
|
||||
|
||||
seteuid(getuid());
|
||||
|
||||
if (audio_fd < 0)
|
||||
{
|
||||
perror(snddevice->string);
|
||||
Com_Printf("Could not open %s\n", snddevice->string);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
rc = ioctl(audio_fd, SNDCTL_DSP_RESET, 0);
|
||||
if (rc < 0)
|
||||
{
|
||||
perror(snddevice->string);
|
||||
Com_Printf("Could not reset %s\n", snddevice->string);
|
||||
close(audio_fd);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (ioctl(audio_fd, SNDCTL_DSP_GETCAPS, &caps)==-1)
|
||||
{
|
||||
perror(snddevice->string);
|
||||
Com_Printf("Sound driver too old\n");
|
||||
close(audio_fd);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!(caps & DSP_CAP_TRIGGER) || !(caps & DSP_CAP_MMAP))
|
||||
{
|
||||
Com_Printf("Sorry but your soundcard can't do this\n");
|
||||
close(audio_fd);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (ioctl(audio_fd, SNDCTL_DSP_GETOSPACE, &info)==-1)
|
||||
{
|
||||
perror("GETOSPACE");
|
||||
Com_Printf("Um, can't do GETOSPACE?\n");
|
||||
close(audio_fd);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// set sample bits & speed
|
||||
|
||||
dma.samplebits = (int)sndbits->value;
|
||||
if (dma.samplebits != 16 && dma.samplebits != 8)
|
||||
{
|
||||
ioctl(audio_fd, SNDCTL_DSP_GETFMTS, &fmt);
|
||||
if (fmt & AFMT_S16_LE) dma.samplebits = 16;
|
||||
else if (fmt & AFMT_U8) dma.samplebits = 8;
|
||||
}
|
||||
|
||||
dma.speed = (int)sndspeed->value;
|
||||
if (!dma.speed) {
|
||||
for (i=0 ; i<sizeof(tryrates)/4 ; i++)
|
||||
if (!ioctl(audio_fd, SNDCTL_DSP_SPEED, &tryrates[i])) break;
|
||||
dma.speed = tryrates[i];
|
||||
}
|
||||
|
||||
dma.channels = (int)sndchannels->value;
|
||||
if (dma.channels < 1 || dma.channels > 2)
|
||||
dma.channels = 2;
|
||||
|
||||
dma.samples = info.fragstotal * info.fragsize / (dma.samplebits/8);
|
||||
dma.submission_chunk = 1;
|
||||
|
||||
// memory map the dma buffer
|
||||
|
||||
if (!dma.buffer)
|
||||
dma.buffer = (unsigned char *) mmap(NULL, info.fragstotal
|
||||
* info.fragsize, PROT_WRITE, MAP_FILE|MAP_SHARED, audio_fd, 0);
|
||||
if (!dma.buffer)
|
||||
{
|
||||
perror(snddevice->string);
|
||||
Com_Printf("Could not mmap %s\n", snddevice->string);
|
||||
close(audio_fd);
|
||||
return 0;
|
||||
}
|
||||
|
||||
tmp = 0;
|
||||
if (dma.channels == 2)
|
||||
tmp = 1;
|
||||
rc = ioctl(audio_fd, SNDCTL_DSP_STEREO, &tmp);
|
||||
if (rc < 0)
|
||||
{
|
||||
perror(snddevice->string);
|
||||
Com_Printf("Could not set %s to stereo=%d", snddevice->string, dma.channels);
|
||||
close(audio_fd);
|
||||
return 0;
|
||||
}
|
||||
if (tmp)
|
||||
dma.channels = 2;
|
||||
else
|
||||
dma.channels = 1;
|
||||
|
||||
rc = ioctl(audio_fd, SNDCTL_DSP_SPEED, &dma.speed);
|
||||
if (rc < 0)
|
||||
{
|
||||
perror(snddevice->string);
|
||||
Com_Printf("Could not set %s speed to %d", snddevice->string, dma.speed);
|
||||
close(audio_fd);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (dma.samplebits == 16)
|
||||
{
|
||||
rc = AFMT_S16_LE;
|
||||
rc = ioctl(audio_fd, SNDCTL_DSP_SETFMT, &rc);
|
||||
if (rc < 0)
|
||||
{
|
||||
perror(snddevice->string);
|
||||
Com_Printf("Could not support 16-bit data. Try 8-bit.\n");
|
||||
close(audio_fd);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
else if (dma.samplebits == 8)
|
||||
{
|
||||
rc = AFMT_U8;
|
||||
rc = ioctl(audio_fd, SNDCTL_DSP_SETFMT, &rc);
|
||||
if (rc < 0)
|
||||
{
|
||||
perror(snddevice->string);
|
||||
Com_Printf("Could not support 8-bit data.\n");
|
||||
close(audio_fd);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
perror(snddevice->string);
|
||||
Com_Printf("%d-bit sound not supported.", dma.samplebits);
|
||||
close(audio_fd);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// toggle the trigger & start her up
|
||||
|
||||
tmp = 0;
|
||||
rc = ioctl(audio_fd, SNDCTL_DSP_SETTRIGGER, &tmp);
|
||||
if (rc < 0)
|
||||
{
|
||||
perror(snddevice->string);
|
||||
Com_Printf("Could not toggle.\n");
|
||||
close(audio_fd);
|
||||
return 0;
|
||||
}
|
||||
tmp = PCM_ENABLE_OUTPUT;
|
||||
rc = ioctl(audio_fd, SNDCTL_DSP_SETTRIGGER, &tmp);
|
||||
if (rc < 0)
|
||||
{
|
||||
perror(snddevice->string);
|
||||
Com_Printf("Could not toggle.\n");
|
||||
close(audio_fd);
|
||||
return 0;
|
||||
}
|
||||
|
||||
dma.samplepos = 0;
|
||||
|
||||
snd_inited = 1;
|
||||
return 1;
|
||||
|
||||
}
|
||||
|
||||
int SNDDMA_GetDMAPos(void)
|
||||
{
|
||||
|
||||
struct count_info count;
|
||||
|
||||
if (!snd_inited) return 0;
|
||||
|
||||
if (ioctl(audio_fd, SNDCTL_DSP_GETOPTR, &count)==-1)
|
||||
{
|
||||
perror(snddevice->string);
|
||||
Com_Printf("Uh, sound dead.\n");
|
||||
close(audio_fd);
|
||||
snd_inited = 0;
|
||||
return 0;
|
||||
}
|
||||
// dma.samplepos = (count.bytes / (dma.samplebits / 8)) & (dma.samples-1);
|
||||
// fprintf(stderr, "%d \r", count.ptr);
|
||||
dma.samplepos = count.ptr / (dma.samplebits / 8);
|
||||
|
||||
return dma.samplepos;
|
||||
|
||||
}
|
||||
|
||||
void SNDDMA_Shutdown(void)
|
||||
{
|
||||
#if 0
|
||||
if (snd_inited)
|
||||
{
|
||||
close(audio_fd);
|
||||
snd_inited = 0;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
==============
|
||||
SNDDMA_Submit
|
||||
|
||||
Send sound to device if buffer isn't really the dma buffer
|
||||
===============
|
||||
*/
|
||||
void SNDDMA_Submit(void)
|
||||
{
|
||||
}
|
||||
|
||||
void SNDDMA_BeginPainting (void)
|
||||
{
|
||||
}
|
||||
|
193
linux/snd_mixa.s
Normal file
193
linux/snd_mixa.s
Normal file
@ -0,0 +1,193 @@
|
||||
//
|
||||
// snd_mixa.s
|
||||
// x86 assembly-language sound code
|
||||
//
|
||||
|
||||
#include "qasm.h"
|
||||
|
||||
#if id386
|
||||
|
||||
.text
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// 8-bit sound-mixing code
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
#define ch 4+16
|
||||
#define sc 8+16
|
||||
#define count 12+16
|
||||
|
||||
.globl C(S_PaintChannelFrom8)
|
||||
C(S_PaintChannelFrom8):
|
||||
pushl %esi // preserve register variables
|
||||
pushl %edi
|
||||
pushl %ebx
|
||||
pushl %ebp
|
||||
|
||||
// int data;
|
||||
// short *lscale, *rscale;
|
||||
// unsigned char *sfx;
|
||||
// int i;
|
||||
|
||||
movl ch(%esp),%ebx
|
||||
movl sc(%esp),%esi
|
||||
|
||||
// if (ch->leftvol > 255)
|
||||
// ch->leftvol = 255;
|
||||
// if (ch->rightvol > 255)
|
||||
// ch->rightvol = 255;
|
||||
movl ch_leftvol(%ebx),%eax
|
||||
movl ch_rightvol(%ebx),%edx
|
||||
cmpl $255,%eax
|
||||
jna LLeftSet
|
||||
movl $255,%eax
|
||||
LLeftSet:
|
||||
cmpl $255,%edx
|
||||
jna LRightSet
|
||||
movl $255,%edx
|
||||
LRightSet:
|
||||
|
||||
// lscale = snd_scaletable[ch->leftvol >> 3];
|
||||
// rscale = snd_scaletable[ch->rightvol >> 3];
|
||||
// sfx = (signed char *)sc->data + ch->pos;
|
||||
// ch->pos += count;
|
||||
andl $0xF8,%eax
|
||||
addl $(sfxc_data),%esi
|
||||
andl $0xF8,%edx
|
||||
movl ch_pos(%ebx),%edi
|
||||
movl count(%esp),%ecx
|
||||
addl %edi,%esi
|
||||
shll $7,%eax
|
||||
addl %ecx,%edi
|
||||
shll $7,%edx
|
||||
movl %edi,ch_pos(%ebx)
|
||||
addl $(C(snd_scaletable)),%eax
|
||||
addl $(C(snd_scaletable)),%edx
|
||||
subl %ebx,%ebx
|
||||
movb -1(%esi,%ecx,1),%bl
|
||||
|
||||
testl $1,%ecx
|
||||
jz LMix8Loop
|
||||
|
||||
movl (%eax,%ebx,4),%edi
|
||||
movl (%edx,%ebx,4),%ebp
|
||||
addl C(paintbuffer)+psp_left-psp_size(,%ecx,psp_size),%edi
|
||||
addl C(paintbuffer)+psp_right-psp_size(,%ecx,psp_size),%ebp
|
||||
movl %edi,C(paintbuffer)+psp_left-psp_size(,%ecx,psp_size)
|
||||
movl %ebp,C(paintbuffer)+psp_right-psp_size(,%ecx,psp_size)
|
||||
movb -2(%esi,%ecx,1),%bl
|
||||
|
||||
decl %ecx
|
||||
jz LDone
|
||||
|
||||
// for (i=0 ; i<count ; i++)
|
||||
// {
|
||||
LMix8Loop:
|
||||
|
||||
// data = sfx[i];
|
||||
// paintbuffer[i].left += lscale[data];
|
||||
// paintbuffer[i].right += rscale[data];
|
||||
movl (%eax,%ebx,4),%edi
|
||||
movl (%edx,%ebx,4),%ebp
|
||||
addl C(paintbuffer)+psp_left-psp_size(,%ecx,psp_size),%edi
|
||||
addl C(paintbuffer)+psp_right-psp_size(,%ecx,psp_size),%ebp
|
||||
movb -2(%esi,%ecx,1),%bl
|
||||
movl %edi,C(paintbuffer)+psp_left-psp_size(,%ecx,psp_size)
|
||||
movl %ebp,C(paintbuffer)+psp_right-psp_size(,%ecx,psp_size)
|
||||
|
||||
movl (%eax,%ebx,4),%edi
|
||||
movl (%edx,%ebx,4),%ebp
|
||||
movb -3(%esi,%ecx,1),%bl
|
||||
addl C(paintbuffer)+psp_left-psp_size*2(,%ecx,psp_size),%edi
|
||||
addl C(paintbuffer)+psp_right-psp_size*2(,%ecx,psp_size),%ebp
|
||||
movl %edi,C(paintbuffer)+psp_left-psp_size*2(,%ecx,psp_size)
|
||||
movl %ebp,C(paintbuffer)+psp_right-psp_size*2(,%ecx,psp_size)
|
||||
|
||||
// }
|
||||
subl $2,%ecx
|
||||
jnz LMix8Loop
|
||||
|
||||
LDone:
|
||||
popl %ebp
|
||||
popl %ebx
|
||||
popl %edi
|
||||
popl %esi
|
||||
|
||||
ret
|
||||
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// Transfer of stereo buffer to 16-bit DMA buffer code
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
.globl C(S_WriteLinearBlastStereo16)
|
||||
C(S_WriteLinearBlastStereo16):
|
||||
pushl %edi
|
||||
pushl %ebx
|
||||
|
||||
// int i;
|
||||
// int val;
|
||||
movl C(snd_linear_count),%ecx
|
||||
movl C(snd_p),%ebx
|
||||
movl C(snd_out),%edi
|
||||
|
||||
// for (i=0 ; i<snd_linear_count ; i+=2)
|
||||
// {
|
||||
LWLBLoopTop:
|
||||
|
||||
// val = (snd_p[i]*snd_vol)>>8;
|
||||
// if (val > 0x7fff)
|
||||
// snd_out[i] = 0x7fff;
|
||||
// else if (val < (short)0x8000)
|
||||
// snd_out[i] = (short)0x8000;
|
||||
// else
|
||||
// snd_out[i] = val;
|
||||
movl -8(%ebx,%ecx,4),%eax
|
||||
sarl $8,%eax
|
||||
cmpl $0x7FFF,%eax
|
||||
jg LClampHigh
|
||||
cmpl $0xFFFF8000,%eax
|
||||
jnl LClampDone
|
||||
movl $0xFFFF8000,%eax
|
||||
jmp LClampDone
|
||||
LClampHigh:
|
||||
movl $0x7FFF,%eax
|
||||
LClampDone:
|
||||
|
||||
// val = (snd_p[i+1]*snd_vol)>>8;
|
||||
// if (val > 0x7fff)
|
||||
// snd_out[i+1] = 0x7fff;
|
||||
// else if (val < (short)0x8000)
|
||||
// snd_out[i+1] = (short)0x8000;
|
||||
// else
|
||||
// snd_out[i+1] = val;
|
||||
movl -4(%ebx,%ecx,4),%edx
|
||||
sarl $8,%edx
|
||||
cmpl $0x7FFF,%edx
|
||||
jg LClampHigh2
|
||||
cmpl $0xFFFF8000,%edx
|
||||
jnl LClampDone2
|
||||
movl $0xFFFF8000,%edx
|
||||
jmp LClampDone2
|
||||
LClampHigh2:
|
||||
movl $0x7FFF,%edx
|
||||
LClampDone2:
|
||||
shll $16,%edx
|
||||
andl $0xFFFF,%eax
|
||||
orl %eax,%edx
|
||||
movl %edx,-4(%edi,%ecx,2)
|
||||
|
||||
// }
|
||||
subl $2,%ecx
|
||||
jnz LWLBLoopTop
|
||||
|
||||
// snd_p += snd_linear_count;
|
||||
|
||||
popl %ebx
|
||||
popl %edi
|
||||
|
||||
ret
|
||||
|
||||
|
||||
#endif // id386
|
||||
|
94
linux/sys_dosa.s
Normal file
94
linux/sys_dosa.s
Normal file
@ -0,0 +1,94 @@
|
||||
//
|
||||
// sys_dosa.s
|
||||
// x86 assembly-language DOS-dependent routines.
|
||||
|
||||
#include "qasm.h"
|
||||
|
||||
|
||||
.data
|
||||
|
||||
.align 4
|
||||
fpenv:
|
||||
.long 0, 0, 0, 0, 0, 0, 0, 0
|
||||
|
||||
.text
|
||||
|
||||
.globl C(MaskExceptions)
|
||||
C(MaskExceptions):
|
||||
fnstenv fpenv
|
||||
orl $0x3F,fpenv
|
||||
fldenv fpenv
|
||||
|
||||
ret
|
||||
|
||||
#if 0
|
||||
.globl C(unmaskexceptions)
|
||||
C(unmaskexceptions):
|
||||
fnstenv fpenv
|
||||
andl $0xFFFFFFE0,fpenv
|
||||
fldenv fpenv
|
||||
|
||||
ret
|
||||
#endif
|
||||
|
||||
.data
|
||||
|
||||
.align 4
|
||||
.globl ceil_cw, single_cw, full_cw, cw, pushed_cw
|
||||
ceil_cw: .long 0
|
||||
single_cw: .long 0
|
||||
full_cw: .long 0
|
||||
cw: .long 0
|
||||
pushed_cw: .long 0
|
||||
|
||||
.text
|
||||
|
||||
.globl C(Sys_LowFPPrecision)
|
||||
C(Sys_LowFPPrecision):
|
||||
fldcw single_cw
|
||||
|
||||
ret
|
||||
|
||||
.globl C(Sys_HighFPPrecision)
|
||||
C(Sys_HighFPPrecision):
|
||||
fldcw full_cw
|
||||
|
||||
ret
|
||||
|
||||
.globl C(Sys_PushFPCW_SetHigh)
|
||||
C(Sys_PushFPCW_SetHigh):
|
||||
fnstcw pushed_cw
|
||||
fldcw full_cw
|
||||
|
||||
ret
|
||||
|
||||
.globl C(Sys_PopFPCW)
|
||||
C(Sys_PopFPCW):
|
||||
fldcw pushed_cw
|
||||
|
||||
ret
|
||||
|
||||
.globl C(Sys_SetFPCW)
|
||||
C(Sys_SetFPCW):
|
||||
fnstcw cw
|
||||
movl cw,%eax
|
||||
#if id386
|
||||
andb $0xF0,%ah
|
||||
orb $0x03,%ah // round mode, 64-bit precision
|
||||
#endif
|
||||
movl %eax,full_cw
|
||||
|
||||
#if id386
|
||||
andb $0xF0,%ah
|
||||
orb $0x0C,%ah // chop mode, single precision
|
||||
#endif
|
||||
movl %eax,single_cw
|
||||
|
||||
#if id386
|
||||
andb $0xF0,%ah
|
||||
orb $0x08,%ah // ceil mode, single precision
|
||||
#endif
|
||||
movl %eax,ceil_cw
|
||||
|
||||
ret
|
||||
|
379
linux/sys_linux.c
Normal file
379
linux/sys_linux.c
Normal file
@ -0,0 +1,379 @@
|
||||
#include <unistd.h>
|
||||
#include <signal.h>
|
||||
#include <stdlib.h>
|
||||
#include <limits.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <sys/ipc.h>
|
||||
#include <sys/shm.h>
|
||||
#include <sys/stat.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
#include <sys/wait.h>
|
||||
#include <sys/mman.h>
|
||||
#include <errno.h>
|
||||
#include <mntent.h>
|
||||
|
||||
#include <dlfcn.h>
|
||||
|
||||
#include "../qcommon/qcommon.h"
|
||||
|
||||
#include "../linux/rw_linux.h"
|
||||
|
||||
cvar_t *nostdout;
|
||||
|
||||
unsigned sys_frame_time;
|
||||
|
||||
uid_t saved_euid;
|
||||
qboolean stdin_active = true;
|
||||
|
||||
// =======================================================================
|
||||
// General routines
|
||||
// =======================================================================
|
||||
|
||||
void Sys_ConsoleOutput (char *string)
|
||||
{
|
||||
if (nostdout && nostdout->value)
|
||||
return;
|
||||
|
||||
fputs(string, stdout);
|
||||
}
|
||||
|
||||
void Sys_Printf (char *fmt, ...)
|
||||
{
|
||||
va_list argptr;
|
||||
char text[1024];
|
||||
unsigned char *p;
|
||||
|
||||
va_start (argptr,fmt);
|
||||
vsprintf (text,fmt,argptr);
|
||||
va_end (argptr);
|
||||
|
||||
if (strlen(text) > sizeof(text))
|
||||
Sys_Error("memory overwrite in Sys_Printf");
|
||||
|
||||
if (nostdout && nostdout->value)
|
||||
return;
|
||||
|
||||
for (p = (unsigned char *)text; *p; p++) {
|
||||
*p &= 0x7f;
|
||||
if ((*p > 128 || *p < 32) && *p != 10 && *p != 13 && *p != 9)
|
||||
printf("[%02x]", *p);
|
||||
else
|
||||
putc(*p, stdout);
|
||||
}
|
||||
}
|
||||
|
||||
void Sys_Quit (void)
|
||||
{
|
||||
CL_Shutdown ();
|
||||
Qcommon_Shutdown ();
|
||||
fcntl (0, F_SETFL, fcntl (0, F_GETFL, 0) & ~FNDELAY);
|
||||
_exit(0);
|
||||
}
|
||||
|
||||
void Sys_Init(void)
|
||||
{
|
||||
#if id386
|
||||
// Sys_SetFPCW();
|
||||
#endif
|
||||
}
|
||||
|
||||
void Sys_Error (char *error, ...)
|
||||
{
|
||||
va_list argptr;
|
||||
char string[1024];
|
||||
|
||||
// change stdin to non blocking
|
||||
fcntl (0, F_SETFL, fcntl (0, F_GETFL, 0) & ~FNDELAY);
|
||||
|
||||
CL_Shutdown ();
|
||||
Qcommon_Shutdown ();
|
||||
|
||||
va_start (argptr,error);
|
||||
vsprintf (string,error,argptr);
|
||||
va_end (argptr);
|
||||
fprintf(stderr, "Error: %s\n", string);
|
||||
|
||||
_exit (1);
|
||||
|
||||
}
|
||||
|
||||
void Sys_Warn (char *warning, ...)
|
||||
{
|
||||
va_list argptr;
|
||||
char string[1024];
|
||||
|
||||
va_start (argptr,warning);
|
||||
vsprintf (string,warning,argptr);
|
||||
va_end (argptr);
|
||||
fprintf(stderr, "Warning: %s", string);
|
||||
}
|
||||
|
||||
/*
|
||||
============
|
||||
Sys_FileTime
|
||||
|
||||
returns -1 if not present
|
||||
============
|
||||
*/
|
||||
int Sys_FileTime (char *path)
|
||||
{
|
||||
struct stat buf;
|
||||
|
||||
if (stat (path,&buf) == -1)
|
||||
return -1;
|
||||
|
||||
return buf.st_mtime;
|
||||
}
|
||||
|
||||
void floating_point_exception_handler(int whatever)
|
||||
{
|
||||
// Sys_Warn("floating point exception\n");
|
||||
signal(SIGFPE, floating_point_exception_handler);
|
||||
}
|
||||
|
||||
char *Sys_ConsoleInput(void)
|
||||
{
|
||||
static char text[256];
|
||||
int len;
|
||||
fd_set fdset;
|
||||
struct timeval timeout;
|
||||
|
||||
if (!dedicated || !dedicated->value)
|
||||
return NULL;
|
||||
|
||||
if (!stdin_active)
|
||||
return NULL;
|
||||
|
||||
FD_ZERO(&fdset);
|
||||
FD_SET(0, &fdset); // stdin
|
||||
timeout.tv_sec = 0;
|
||||
timeout.tv_usec = 0;
|
||||
if (select (1, &fdset, NULL, NULL, &timeout) == -1 || !FD_ISSET(0, &fdset))
|
||||
return NULL;
|
||||
|
||||
len = read (0, text, sizeof(text));
|
||||
if (len == 0) { // eof!
|
||||
stdin_active = false;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (len < 1)
|
||||
return NULL;
|
||||
text[len-1] = 0; // rip off the /n and terminate
|
||||
|
||||
return text;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
static void *game_library;
|
||||
|
||||
/*
|
||||
=================
|
||||
Sys_UnloadGame
|
||||
=================
|
||||
*/
|
||||
void Sys_UnloadGame (void)
|
||||
{
|
||||
if (game_library)
|
||||
dlclose (game_library);
|
||||
game_library = NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
Sys_GetGameAPI
|
||||
|
||||
Loads the game dll
|
||||
=================
|
||||
*/
|
||||
void *Sys_GetGameAPI (void *parms)
|
||||
{
|
||||
void *(*GetGameAPI) (void *);
|
||||
|
||||
char name[MAX_OSPATH];
|
||||
char curpath[MAX_OSPATH];
|
||||
char *path;
|
||||
#ifdef __i386__
|
||||
const char *gamename = "gamei386.so";
|
||||
#elif defined __alpha__
|
||||
const char *gamename = "gameaxp.so";
|
||||
#else
|
||||
#error Unknown arch
|
||||
#endif
|
||||
|
||||
setreuid(getuid(), getuid());
|
||||
setegid(getgid());
|
||||
|
||||
if (game_library)
|
||||
Com_Error (ERR_FATAL, "Sys_GetGameAPI without Sys_UnloadingGame");
|
||||
|
||||
getcwd(curpath, sizeof(curpath));
|
||||
|
||||
Com_Printf("------- Loading %s -------", gamename);
|
||||
|
||||
// now run through the search paths
|
||||
path = NULL;
|
||||
while (1)
|
||||
{
|
||||
path = FS_NextPath (path);
|
||||
if (!path)
|
||||
return NULL; // couldn't find one anywhere
|
||||
sprintf (name, "%s/%s/%s", curpath, path, gamename);
|
||||
game_library = dlopen (name, RTLD_NOW );
|
||||
if (game_library)
|
||||
{
|
||||
Com_DPrintf ("LoadLibrary (%s)\n",name);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
GetGameAPI = (void *)dlsym (game_library, "GetGameAPI");
|
||||
if (!GetGameAPI)
|
||||
{
|
||||
Sys_UnloadGame ();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return GetGameAPI (parms);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
void Sys_AppActivate (void)
|
||||
{
|
||||
}
|
||||
|
||||
void Sys_SendKeyEvents (void)
|
||||
{
|
||||
#ifndef DEDICATED_ONLY
|
||||
if (KBD_Update_fp)
|
||||
KBD_Update_fp();
|
||||
#endif
|
||||
|
||||
// grab frame time
|
||||
sys_frame_time = Sys_Milliseconds();
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
char *Sys_GetClipboardData(void)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int main (int argc, char **argv)
|
||||
{
|
||||
int time, oldtime, newtime;
|
||||
|
||||
// go back to real user for config loads
|
||||
saved_euid = geteuid();
|
||||
seteuid(getuid());
|
||||
|
||||
Qcommon_Init(argc, argv);
|
||||
|
||||
fcntl(0, F_SETFL, fcntl (0, F_GETFL, 0) | FNDELAY);
|
||||
|
||||
nostdout = Cvar_Get("nostdout", "0", 0);
|
||||
if (!nostdout->value) {
|
||||
fcntl(0, F_SETFL, fcntl (0, F_GETFL, 0) | FNDELAY);
|
||||
// printf ("Linux Quake -- Version %0.3f\n", LINUX_VERSION);
|
||||
}
|
||||
|
||||
oldtime = Sys_Milliseconds ();
|
||||
while (1)
|
||||
{
|
||||
// find time spent rendering last frame
|
||||
do {
|
||||
newtime = Sys_Milliseconds ();
|
||||
time = newtime - oldtime;
|
||||
} while (time < 1);
|
||||
Qcommon_Frame (time);
|
||||
oldtime = newtime;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void Sys_CopyProtect(void)
|
||||
{
|
||||
FILE *mnt;
|
||||
struct mntent *ent;
|
||||
char path[MAX_OSPATH];
|
||||
struct stat st;
|
||||
qboolean found_cd = false;
|
||||
|
||||
static qboolean checked = false;
|
||||
|
||||
if (checked)
|
||||
return;
|
||||
|
||||
if ((mnt = setmntent("/etc/mtab", "r")) == NULL)
|
||||
Com_Error(ERR_FATAL, "Can't read mount table to determine mounted cd location.");
|
||||
|
||||
while ((ent = getmntent(mnt)) != NULL) {
|
||||
if (strcmp(ent->mnt_type, "iso9660") == 0) {
|
||||
// found a cd file system
|
||||
found_cd = true;
|
||||
sprintf(path, "%s/%s", ent->mnt_dir, "install/data/quake2.exe");
|
||||
if (stat(path, &st) == 0) {
|
||||
// found it
|
||||
checked = true;
|
||||
endmntent(mnt);
|
||||
return;
|
||||
}
|
||||
sprintf(path, "%s/%s", ent->mnt_dir, "Install/Data/quake2.exe");
|
||||
if (stat(path, &st) == 0) {
|
||||
// found it
|
||||
checked = true;
|
||||
endmntent(mnt);
|
||||
return;
|
||||
}
|
||||
sprintf(path, "%s/%s", ent->mnt_dir, "quake2.exe");
|
||||
if (stat(path, &st) == 0) {
|
||||
// found it
|
||||
checked = true;
|
||||
endmntent(mnt);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
endmntent(mnt);
|
||||
|
||||
if (found_cd)
|
||||
Com_Error (ERR_FATAL, "Could not find a Quake2 CD in your CD drive.");
|
||||
Com_Error (ERR_FATAL, "Unable to find a mounted iso9660 file system.\n"
|
||||
"You must mount the Quake2 CD in a cdrom drive in order to play.");
|
||||
}
|
||||
|
||||
#if 0
|
||||
/*
|
||||
================
|
||||
Sys_MakeCodeWriteable
|
||||
================
|
||||
*/
|
||||
void Sys_MakeCodeWriteable (unsigned long startaddr, unsigned long length)
|
||||
{
|
||||
|
||||
int r;
|
||||
unsigned long addr;
|
||||
int psize = getpagesize();
|
||||
|
||||
addr = (startaddr & ~(psize-1)) - psize;
|
||||
|
||||
// fprintf(stderr, "writable code %lx(%lx)-%lx, length=%lx\n", startaddr,
|
||||
// addr, startaddr+length, length);
|
||||
|
||||
r = mprotect((char*)addr, length + startaddr - addr + psize, 7);
|
||||
|
||||
if (r < 0)
|
||||
Sys_Error("Protection change failed\n");
|
||||
|
||||
}
|
||||
|
||||
#endif
|
437
linux/vid_menu.c
Normal file
437
linux/vid_menu.c
Normal file
@ -0,0 +1,437 @@
|
||||
#include "../client/client.h"
|
||||
#include "../client/qmenu.h"
|
||||
|
||||
#define REF_SOFT 0
|
||||
#define REF_SOFTX11 1
|
||||
#define REF_OPENGL 2
|
||||
|
||||
extern cvar_t *vid_ref;
|
||||
extern cvar_t *vid_fullscreen;
|
||||
extern cvar_t *vid_gamma;
|
||||
extern cvar_t *scr_viewsize;
|
||||
|
||||
static cvar_t *gl_mode;
|
||||
static cvar_t *gl_driver;
|
||||
static cvar_t *gl_picmip;
|
||||
static cvar_t *gl_ext_palettedtexture;
|
||||
|
||||
static cvar_t *sw_mode;
|
||||
static cvar_t *sw_stipplealpha;
|
||||
|
||||
static cvar_t *_windowed_mouse;
|
||||
|
||||
extern void M_ForceMenuOff( void );
|
||||
|
||||
/*
|
||||
====================================================================
|
||||
|
||||
MENU INTERACTION
|
||||
|
||||
====================================================================
|
||||
*/
|
||||
#define SOFTWARE_MENU 0
|
||||
#define OPENGL_MENU 1
|
||||
|
||||
static menuframework_s s_software_menu;
|
||||
static menuframework_s s_opengl_menu;
|
||||
static menuframework_s *s_current_menu;
|
||||
static int s_current_menu_index;
|
||||
|
||||
static menulist_s s_mode_list[2];
|
||||
static menulist_s s_ref_list[2];
|
||||
static menuslider_s s_tq_slider;
|
||||
static menuslider_s s_screensize_slider[2];
|
||||
static menuslider_s s_brightness_slider[2];
|
||||
static menulist_s s_fs_box[2];
|
||||
static menulist_s s_stipple_box;
|
||||
static menulist_s s_paletted_texture_box;
|
||||
static menulist_s s_windowed_mouse;
|
||||
static menuaction_s s_apply_action[2];
|
||||
static menuaction_s s_defaults_action[2];
|
||||
|
||||
static void DriverCallback( void *unused )
|
||||
{
|
||||
s_ref_list[!s_current_menu_index].curvalue = s_ref_list[s_current_menu_index].curvalue;
|
||||
|
||||
if ( s_ref_list[s_current_menu_index].curvalue < 2 )
|
||||
{
|
||||
s_current_menu = &s_software_menu;
|
||||
s_current_menu_index = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
s_current_menu = &s_opengl_menu;
|
||||
s_current_menu_index = 1;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static void ScreenSizeCallback( void *s )
|
||||
{
|
||||
menuslider_s *slider = ( menuslider_s * ) s;
|
||||
|
||||
Cvar_SetValue( "viewsize", slider->curvalue * 10 );
|
||||
}
|
||||
|
||||
static void BrightnessCallback( void *s )
|
||||
{
|
||||
menuslider_s *slider = ( menuslider_s * ) s;
|
||||
|
||||
if ( s_current_menu_index == 0)
|
||||
s_brightness_slider[1].curvalue = s_brightness_slider[0].curvalue;
|
||||
else
|
||||
s_brightness_slider[0].curvalue = s_brightness_slider[1].curvalue;
|
||||
|
||||
if ( stricmp( vid_ref->string, "soft" ) == 0 ||
|
||||
stricmp( vid_ref->string, "softx" ) == 0 )
|
||||
{
|
||||
float gamma = ( 0.8 - ( slider->curvalue/10.0 - 0.5 ) ) + 0.5;
|
||||
|
||||
Cvar_SetValue( "vid_gamma", gamma );
|
||||
}
|
||||
}
|
||||
|
||||
static void ResetDefaults( void *unused )
|
||||
{
|
||||
VID_MenuInit();
|
||||
}
|
||||
|
||||
static void ApplyChanges( void *unused )
|
||||
{
|
||||
float gamma;
|
||||
|
||||
/*
|
||||
** make values consistent
|
||||
*/
|
||||
s_fs_box[!s_current_menu_index].curvalue = s_fs_box[s_current_menu_index].curvalue;
|
||||
s_brightness_slider[!s_current_menu_index].curvalue = s_brightness_slider[s_current_menu_index].curvalue;
|
||||
s_ref_list[!s_current_menu_index].curvalue = s_ref_list[s_current_menu_index].curvalue;
|
||||
|
||||
/*
|
||||
** invert sense so greater = brighter, and scale to a range of 0.5 to 1.3
|
||||
*/
|
||||
gamma = ( 0.8 - ( s_brightness_slider[s_current_menu_index].curvalue/10.0 - 0.5 ) ) + 0.5;
|
||||
|
||||
Cvar_SetValue( "vid_gamma", gamma );
|
||||
Cvar_SetValue( "sw_stipplealpha", s_stipple_box.curvalue );
|
||||
Cvar_SetValue( "gl_picmip", 3 - s_tq_slider.curvalue );
|
||||
Cvar_SetValue( "vid_fullscreen", s_fs_box[s_current_menu_index].curvalue );
|
||||
Cvar_SetValue( "gl_ext_palettedtexture", s_paletted_texture_box.curvalue );
|
||||
Cvar_SetValue( "sw_mode", s_mode_list[SOFTWARE_MENU].curvalue );
|
||||
Cvar_SetValue( "gl_mode", s_mode_list[OPENGL_MENU].curvalue );
|
||||
Cvar_SetValue( "_windowed_mouse", s_windowed_mouse.curvalue);
|
||||
|
||||
switch ( s_ref_list[s_current_menu_index].curvalue )
|
||||
{
|
||||
case REF_SOFT:
|
||||
Cvar_Set( "vid_ref", "soft" );
|
||||
break;
|
||||
case REF_SOFTX11:
|
||||
Cvar_Set( "vid_ref", "softx" );
|
||||
break;
|
||||
case REF_OPENGL:
|
||||
Cvar_Set( "vid_ref", "gl" );
|
||||
Cvar_Set( "gl_driver", "opengl32" );
|
||||
break;
|
||||
}
|
||||
|
||||
#if 0
|
||||
/*
|
||||
** update appropriate stuff if we're running OpenGL and gamma
|
||||
** has been modified
|
||||
*/
|
||||
if ( stricmp( vid_ref->string, "gl" ) == 0 )
|
||||
{
|
||||
if ( vid_gamma->modified )
|
||||
{
|
||||
vid_ref->modified = true;
|
||||
if ( stricmp( gl_driver->string, "3dfxgl" ) == 0 )
|
||||
{
|
||||
char envbuffer[1024];
|
||||
float g;
|
||||
|
||||
vid_ref->modified = true;
|
||||
|
||||
g = 2.00 * ( 0.8 - ( vid_gamma->value - 0.5 ) ) + 1.0F;
|
||||
Com_sprintf( envbuffer, sizeof(envbuffer), "SST_GAMMA=%f", g );
|
||||
putenv( envbuffer );
|
||||
|
||||
vid_gamma->modified = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
M_ForceMenuOff();
|
||||
}
|
||||
|
||||
/*
|
||||
** VID_MenuInit
|
||||
*/
|
||||
void VID_MenuInit( void )
|
||||
{
|
||||
static const char *resolutions[] =
|
||||
{
|
||||
"[320 240 ]",
|
||||
"[400 300 ]",
|
||||
"[512 384 ]",
|
||||
"[640 480 ]",
|
||||
"[800 600 ]",
|
||||
"[960 720 ]",
|
||||
"[1024 768 ]",
|
||||
"[1152 864 ]",
|
||||
"[1280 1024]",
|
||||
"[1600 1200]",
|
||||
0
|
||||
};
|
||||
static const char *refs[] =
|
||||
{
|
||||
"[software ]",
|
||||
"[software X11 ]",
|
||||
"[default OpenGL]",
|
||||
0
|
||||
};
|
||||
static const char *yesno_names[] =
|
||||
{
|
||||
"no",
|
||||
"yes",
|
||||
0
|
||||
};
|
||||
int i;
|
||||
|
||||
if ( !gl_driver )
|
||||
gl_driver = Cvar_Get( "gl_driver", "opengl32", 0 );
|
||||
if ( !gl_picmip )
|
||||
gl_picmip = Cvar_Get( "gl_picmip", "0", 0 );
|
||||
if ( !gl_mode )
|
||||
gl_mode = Cvar_Get( "gl_mode", "3", 0 );
|
||||
if ( !sw_mode )
|
||||
sw_mode = Cvar_Get( "sw_mode", "0", 0 );
|
||||
if ( !gl_ext_palettedtexture )
|
||||
gl_ext_palettedtexture = Cvar_Get( "gl_ext_palettedtexture", "1", CVAR_ARCHIVE );
|
||||
|
||||
if ( !sw_stipplealpha )
|
||||
sw_stipplealpha = Cvar_Get( "sw_stipplealpha", "0", CVAR_ARCHIVE );
|
||||
|
||||
if ( !_windowed_mouse)
|
||||
_windowed_mouse = Cvar_Get( "_windowed_mouse", "0", CVAR_ARCHIVE );
|
||||
|
||||
s_mode_list[SOFTWARE_MENU].curvalue = sw_mode->value;
|
||||
s_mode_list[OPENGL_MENU].curvalue = gl_mode->value;
|
||||
|
||||
if ( !scr_viewsize )
|
||||
scr_viewsize = Cvar_Get ("viewsize", "100", CVAR_ARCHIVE);
|
||||
|
||||
s_screensize_slider[SOFTWARE_MENU].curvalue = scr_viewsize->value/10;
|
||||
s_screensize_slider[OPENGL_MENU].curvalue = scr_viewsize->value/10;
|
||||
|
||||
if ( strcmp( vid_ref->string, "soft" ) == 0)
|
||||
{
|
||||
s_current_menu_index = SOFTWARE_MENU;
|
||||
s_ref_list[0].curvalue = s_ref_list[1].curvalue = REF_SOFT;
|
||||
}
|
||||
else if (strcmp( vid_ref->string, "softx" ) == 0 )
|
||||
{
|
||||
s_current_menu_index = SOFTWARE_MENU;
|
||||
s_ref_list[0].curvalue = s_ref_list[1].curvalue = REF_SOFTX11;
|
||||
}
|
||||
else if ( strcmp( vid_ref->string, "gl" ) == 0 )
|
||||
{
|
||||
s_current_menu_index = OPENGL_MENU;
|
||||
s_ref_list[s_current_menu_index].curvalue = REF_OPENGL;
|
||||
#if 0
|
||||
if ( strcmp( gl_driver->string, "3dfxgl" ) == 0 )
|
||||
s_ref_list[s_current_menu_index].curvalue = REF_3DFX;
|
||||
else if ( strcmp( gl_driver->string, "pvrgl" ) == 0 )
|
||||
s_ref_list[s_current_menu_index].curvalue = REF_POWERVR;
|
||||
else if ( strcmp( gl_driver->string, "opengl32" ) == 0 )
|
||||
s_ref_list[s_current_menu_index].curvalue = REF_OPENGL;
|
||||
else
|
||||
s_ref_list[s_current_menu_index].curvalue = REF_VERITE;
|
||||
#endif
|
||||
}
|
||||
|
||||
s_software_menu.x = viddef.width * 0.50;
|
||||
s_software_menu.nitems = 0;
|
||||
s_opengl_menu.x = viddef.width * 0.50;
|
||||
s_opengl_menu.nitems = 0;
|
||||
|
||||
for ( i = 0; i < 2; i++ )
|
||||
{
|
||||
s_ref_list[i].generic.type = MTYPE_SPINCONTROL;
|
||||
s_ref_list[i].generic.name = "driver";
|
||||
s_ref_list[i].generic.x = 0;
|
||||
s_ref_list[i].generic.y = 0;
|
||||
s_ref_list[i].generic.callback = DriverCallback;
|
||||
s_ref_list[i].itemnames = refs;
|
||||
|
||||
s_mode_list[i].generic.type = MTYPE_SPINCONTROL;
|
||||
s_mode_list[i].generic.name = "video mode";
|
||||
s_mode_list[i].generic.x = 0;
|
||||
s_mode_list[i].generic.y = 10;
|
||||
s_mode_list[i].itemnames = resolutions;
|
||||
|
||||
s_screensize_slider[i].generic.type = MTYPE_SLIDER;
|
||||
s_screensize_slider[i].generic.x = 0;
|
||||
s_screensize_slider[i].generic.y = 20;
|
||||
s_screensize_slider[i].generic.name = "screen size";
|
||||
s_screensize_slider[i].minvalue = 3;
|
||||
s_screensize_slider[i].maxvalue = 12;
|
||||
s_screensize_slider[i].generic.callback = ScreenSizeCallback;
|
||||
|
||||
s_brightness_slider[i].generic.type = MTYPE_SLIDER;
|
||||
s_brightness_slider[i].generic.x = 0;
|
||||
s_brightness_slider[i].generic.y = 30;
|
||||
s_brightness_slider[i].generic.name = "brightness";
|
||||
s_brightness_slider[i].generic.callback = BrightnessCallback;
|
||||
s_brightness_slider[i].minvalue = 5;
|
||||
s_brightness_slider[i].maxvalue = 13;
|
||||
s_brightness_slider[i].curvalue = ( 1.3 - vid_gamma->value + 0.5 ) * 10;
|
||||
|
||||
s_fs_box[i].generic.type = MTYPE_SPINCONTROL;
|
||||
s_fs_box[i].generic.x = 0;
|
||||
s_fs_box[i].generic.y = 40;
|
||||
s_fs_box[i].generic.name = "fullscreen";
|
||||
s_fs_box[i].itemnames = yesno_names;
|
||||
s_fs_box[i].curvalue = vid_fullscreen->value;
|
||||
|
||||
s_defaults_action[i].generic.type = MTYPE_ACTION;
|
||||
s_defaults_action[i].generic.name = "reset to default";
|
||||
s_defaults_action[i].generic.x = 0;
|
||||
s_defaults_action[i].generic.y = 90;
|
||||
s_defaults_action[i].generic.callback = ResetDefaults;
|
||||
|
||||
s_apply_action[i].generic.type = MTYPE_ACTION;
|
||||
s_apply_action[i].generic.name = "apply";
|
||||
s_apply_action[i].generic.x = 0;
|
||||
s_apply_action[i].generic.y = 100;
|
||||
s_apply_action[i].generic.callback = ApplyChanges;
|
||||
}
|
||||
|
||||
s_stipple_box.generic.type = MTYPE_SPINCONTROL;
|
||||
s_stipple_box.generic.x = 0;
|
||||
s_stipple_box.generic.y = 60;
|
||||
s_stipple_box.generic.name = "stipple alpha";
|
||||
s_stipple_box.curvalue = sw_stipplealpha->value;
|
||||
s_stipple_box.itemnames = yesno_names;
|
||||
|
||||
s_windowed_mouse.generic.type = MTYPE_SPINCONTROL;
|
||||
s_windowed_mouse.generic.x = 0;
|
||||
s_windowed_mouse.generic.y = 72;
|
||||
s_windowed_mouse.generic.name = "windowed mouse";
|
||||
s_windowed_mouse.curvalue = _windowed_mouse->value;
|
||||
s_windowed_mouse.itemnames = yesno_names;
|
||||
|
||||
s_tq_slider.generic.type = MTYPE_SLIDER;
|
||||
s_tq_slider.generic.x = 0;
|
||||
s_tq_slider.generic.y = 60;
|
||||
s_tq_slider.generic.name = "texture quality";
|
||||
s_tq_slider.minvalue = 0;
|
||||
s_tq_slider.maxvalue = 3;
|
||||
s_tq_slider.curvalue = 3-gl_picmip->value;
|
||||
|
||||
s_paletted_texture_box.generic.type = MTYPE_SPINCONTROL;
|
||||
s_paletted_texture_box.generic.x = 0;
|
||||
s_paletted_texture_box.generic.y = 70;
|
||||
s_paletted_texture_box.generic.name = "8-bit textures";
|
||||
s_paletted_texture_box.itemnames = yesno_names;
|
||||
s_paletted_texture_box.curvalue = gl_ext_palettedtexture->value;
|
||||
|
||||
Menu_AddItem( &s_software_menu, ( void * ) &s_ref_list[SOFTWARE_MENU] );
|
||||
Menu_AddItem( &s_software_menu, ( void * ) &s_mode_list[SOFTWARE_MENU] );
|
||||
Menu_AddItem( &s_software_menu, ( void * ) &s_screensize_slider[SOFTWARE_MENU] );
|
||||
Menu_AddItem( &s_software_menu, ( void * ) &s_brightness_slider[SOFTWARE_MENU] );
|
||||
Menu_AddItem( &s_software_menu, ( void * ) &s_fs_box[SOFTWARE_MENU] );
|
||||
Menu_AddItem( &s_software_menu, ( void * ) &s_stipple_box );
|
||||
Menu_AddItem( &s_software_menu, ( void * ) &s_windowed_mouse );
|
||||
|
||||
Menu_AddItem( &s_opengl_menu, ( void * ) &s_ref_list[OPENGL_MENU] );
|
||||
Menu_AddItem( &s_opengl_menu, ( void * ) &s_mode_list[OPENGL_MENU] );
|
||||
Menu_AddItem( &s_opengl_menu, ( void * ) &s_screensize_slider[OPENGL_MENU] );
|
||||
Menu_AddItem( &s_opengl_menu, ( void * ) &s_brightness_slider[OPENGL_MENU] );
|
||||
Menu_AddItem( &s_opengl_menu, ( void * ) &s_fs_box[OPENGL_MENU] );
|
||||
Menu_AddItem( &s_opengl_menu, ( void * ) &s_tq_slider );
|
||||
Menu_AddItem( &s_opengl_menu, ( void * ) &s_paletted_texture_box );
|
||||
|
||||
Menu_AddItem( &s_software_menu, ( void * ) &s_defaults_action[SOFTWARE_MENU] );
|
||||
Menu_AddItem( &s_software_menu, ( void * ) &s_apply_action[SOFTWARE_MENU] );
|
||||
Menu_AddItem( &s_opengl_menu, ( void * ) &s_defaults_action[OPENGL_MENU] );
|
||||
Menu_AddItem( &s_opengl_menu, ( void * ) &s_apply_action[OPENGL_MENU] );
|
||||
|
||||
Menu_Center( &s_software_menu );
|
||||
Menu_Center( &s_opengl_menu );
|
||||
s_opengl_menu.x -= 8;
|
||||
s_software_menu.x -= 8;
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
VID_MenuDraw
|
||||
================
|
||||
*/
|
||||
void VID_MenuDraw (void)
|
||||
{
|
||||
int w, h;
|
||||
|
||||
if ( s_current_menu_index == 0 )
|
||||
s_current_menu = &s_software_menu;
|
||||
else
|
||||
s_current_menu = &s_opengl_menu;
|
||||
|
||||
/*
|
||||
** draw the banner
|
||||
*/
|
||||
re.DrawGetPicSize( &w, &h, "m_banner_video" );
|
||||
re.DrawPic( viddef.width / 2 - w / 2, viddef.height /2 - 110, "m_banner_video" );
|
||||
|
||||
/*
|
||||
** move cursor to a reasonable starting position
|
||||
*/
|
||||
Menu_AdjustCursor( s_current_menu, 1 );
|
||||
|
||||
/*
|
||||
** draw the menu
|
||||
*/
|
||||
Menu_Draw( s_current_menu );
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
VID_MenuKey
|
||||
================
|
||||
*/
|
||||
const char *VID_MenuKey( int key )
|
||||
{
|
||||
extern void M_PopMenu( void );
|
||||
|
||||
menuframework_s *m = s_current_menu;
|
||||
static const char *sound = "misc/menu1.wav";
|
||||
|
||||
switch ( key )
|
||||
{
|
||||
case K_ESCAPE:
|
||||
M_PopMenu();
|
||||
return NULL;
|
||||
case K_UPARROW:
|
||||
m->cursor--;
|
||||
Menu_AdjustCursor( m, -1 );
|
||||
break;
|
||||
case K_DOWNARROW:
|
||||
m->cursor++;
|
||||
Menu_AdjustCursor( m, 1 );
|
||||
break;
|
||||
case K_LEFTARROW:
|
||||
Menu_SlideItem( m, -1 );
|
||||
break;
|
||||
case K_RIGHTARROW:
|
||||
Menu_SlideItem( m, 1 );
|
||||
break;
|
||||
case K_ENTER:
|
||||
Menu_SelectItem( m );
|
||||
break;
|
||||
}
|
||||
|
||||
return sound;
|
||||
}
|
||||
|
||||
|
489
linux/vid_so.c
Normal file
489
linux/vid_so.c
Normal file
@ -0,0 +1,489 @@
|
||||
// Main windowed and fullscreen graphics interface module. This module
|
||||
// is used for both the software and OpenGL rendering versions of the
|
||||
// Quake refresh engine.
|
||||
|
||||
#define SO_FILE "/etc/quake2.conf"
|
||||
|
||||
#include <assert.h>
|
||||
#include <dlfcn.h> // ELF dl loader
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "../client/client.h"
|
||||
|
||||
#include "../linux/rw_linux.h"
|
||||
|
||||
// Structure containing functions exported from refresh DLL
|
||||
refexport_t re;
|
||||
|
||||
// Console variables that we need to access from this module
|
||||
cvar_t *vid_gamma;
|
||||
cvar_t *vid_ref; // Name of Refresh DLL loaded
|
||||
cvar_t *vid_xpos; // X coordinate of window position
|
||||
cvar_t *vid_ypos; // Y coordinate of window position
|
||||
cvar_t *vid_fullscreen;
|
||||
|
||||
// Global variables used internally by this module
|
||||
viddef_t viddef; // global video state; used by other modules
|
||||
void *reflib_library; // Handle to refresh DLL
|
||||
qboolean reflib_active = 0;
|
||||
|
||||
#define VID_NUM_MODES ( sizeof( vid_modes ) / sizeof( vid_modes[0] ) )
|
||||
|
||||
/** KEYBOARD **************************************************************/
|
||||
|
||||
void Do_Key_Event(int key, qboolean down);
|
||||
|
||||
void (*KBD_Update_fp)(void);
|
||||
void (*KBD_Init_fp)(Key_Event_fp_t fp);
|
||||
void (*KBD_Close_fp)(void);
|
||||
|
||||
/** MOUSE *****************************************************************/
|
||||
|
||||
in_state_t in_state;
|
||||
|
||||
void (*RW_IN_Init_fp)(in_state_t *in_state_p);
|
||||
void (*RW_IN_Shutdown_fp)(void);
|
||||
void (*RW_IN_Activate_fp)(qboolean active);
|
||||
void (*RW_IN_Commands_fp)(void);
|
||||
void (*RW_IN_Move_fp)(usercmd_t *cmd);
|
||||
void (*RW_IN_Frame_fp)(void);
|
||||
|
||||
void Real_IN_Init (void);
|
||||
|
||||
/*
|
||||
==========================================================================
|
||||
|
||||
DLL GLUE
|
||||
|
||||
==========================================================================
|
||||
*/
|
||||
|
||||
#define MAXPRINTMSG 4096
|
||||
void VID_Printf (int print_level, char *fmt, ...)
|
||||
{
|
||||
va_list argptr;
|
||||
char msg[MAXPRINTMSG];
|
||||
static qboolean inupdate;
|
||||
|
||||
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[MAXPRINTMSG];
|
||||
static qboolean inupdate;
|
||||
|
||||
va_start (argptr,fmt);
|
||||
vsprintf (msg,fmt,argptr);
|
||||
va_end (argptr);
|
||||
|
||||
Com_Error (err_level,"%s", msg);
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
|
||||
/*
|
||||
============
|
||||
VID_Restart_f
|
||||
|
||||
Console command to re-start the video mode and refresh DLL. We do this
|
||||
simply by setting the modified flag for the vid_ref variable, which will
|
||||
cause the entire video mode and refresh DLL to be reset on the next frame.
|
||||
============
|
||||
*/
|
||||
void VID_Restart_f (void)
|
||||
{
|
||||
vid_ref->modified = true;
|
||||
}
|
||||
|
||||
/*
|
||||
** VID_GetModeInfo
|
||||
*/
|
||||
typedef struct vidmode_s
|
||||
{
|
||||
const char *description;
|
||||
int width, height;
|
||||
int mode;
|
||||
} vidmode_t;
|
||||
|
||||
vidmode_t vid_modes[] =
|
||||
{
|
||||
{ "Mode 0: 320x240", 320, 240, 0 },
|
||||
{ "Mode 1: 400x300", 400, 300, 1 },
|
||||
{ "Mode 2: 512x384", 512, 384, 2 },
|
||||
{ "Mode 3: 640x480", 640, 480, 3 },
|
||||
{ "Mode 4: 800x600", 800, 600, 4 },
|
||||
{ "Mode 5: 960x720", 960, 720, 5 },
|
||||
{ "Mode 6: 1024x768", 1024, 768, 6 },
|
||||
{ "Mode 7: 1152x864", 1152, 864, 7 },
|
||||
{ "Mode 8: 1280x1024", 1280, 1024, 8 },
|
||||
{ "Mode 9: 1600x1200", 1600, 1200, 9 }
|
||||
};
|
||||
|
||||
qboolean VID_GetModeInfo( int *width, int *height, int mode )
|
||||
{
|
||||
if ( mode < 0 || mode >= VID_NUM_MODES )
|
||||
return false;
|
||||
|
||||
*width = vid_modes[mode].width;
|
||||
*height = vid_modes[mode].height;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
** VID_NewWindow
|
||||
*/
|
||||
void VID_NewWindow ( int width, int height)
|
||||
{
|
||||
viddef.width = width;
|
||||
viddef.height = height;
|
||||
}
|
||||
|
||||
void VID_FreeReflib (void)
|
||||
{
|
||||
if (reflib_library) {
|
||||
if (KBD_Close_fp)
|
||||
KBD_Close_fp();
|
||||
if (RW_IN_Shutdown_fp)
|
||||
RW_IN_Shutdown_fp();
|
||||
dlclose(reflib_library);
|
||||
}
|
||||
|
||||
KBD_Init_fp = NULL;
|
||||
KBD_Update_fp = NULL;
|
||||
KBD_Close_fp = NULL;
|
||||
RW_IN_Init_fp = NULL;
|
||||
RW_IN_Shutdown_fp = NULL;
|
||||
RW_IN_Activate_fp = NULL;
|
||||
RW_IN_Commands_fp = NULL;
|
||||
RW_IN_Move_fp = NULL;
|
||||
RW_IN_Frame_fp = NULL;
|
||||
|
||||
memset (&re, 0, sizeof(re));
|
||||
reflib_library = NULL;
|
||||
reflib_active = false;
|
||||
}
|
||||
|
||||
/*
|
||||
==============
|
||||
VID_LoadRefresh
|
||||
==============
|
||||
*/
|
||||
qboolean VID_LoadRefresh( char *name )
|
||||
{
|
||||
refimport_t ri;
|
||||
GetRefAPI_t GetRefAPI;
|
||||
char fn[MAX_OSPATH];
|
||||
struct stat st;
|
||||
extern uid_t saved_euid;
|
||||
FILE *fp;
|
||||
|
||||
if ( reflib_active )
|
||||
{
|
||||
if (KBD_Close_fp)
|
||||
KBD_Close_fp();
|
||||
if (RW_IN_Shutdown_fp)
|
||||
RW_IN_Shutdown_fp();
|
||||
KBD_Close_fp = NULL;
|
||||
RW_IN_Shutdown_fp = NULL;
|
||||
re.Shutdown();
|
||||
VID_FreeReflib ();
|
||||
}
|
||||
|
||||
Com_Printf( "------- Loading %s -------\n", name );
|
||||
|
||||
//regain root
|
||||
seteuid(saved_euid);
|
||||
|
||||
if ((fp = fopen(SO_FILE, "r")) == NULL) {
|
||||
Com_Printf( "LoadLibrary(\"%s\") failed: can't open " SO_FILE " (required for location of ref libraries)\n", name);
|
||||
return false;
|
||||
}
|
||||
fgets(fn, sizeof(fn), fp);
|
||||
fclose(fp);
|
||||
if (*fn && fn[strlen(fn) - 1] == '\n')
|
||||
fn[strlen(fn) - 1] = 0;
|
||||
|
||||
strcat(fn, "/");
|
||||
strcat(fn, name);
|
||||
|
||||
// permission checking
|
||||
if (strstr(fn, "softx") == NULL) { // softx doesn't require root
|
||||
if (stat(fn, &st) == -1) {
|
||||
Com_Printf( "LoadLibrary(\"%s\") failed: %s\n", name, strerror(errno));
|
||||
return false;
|
||||
}
|
||||
if (st.st_uid != 0) {
|
||||
Com_Printf( "LoadLibrary(\"%s\") failed: ref is not owned by root\n", name);
|
||||
return false;
|
||||
}
|
||||
#if 0
|
||||
if ((st.st_mode & 0777) & ~0700) {
|
||||
Com_Printf( "LoadLibrary(\"%s\") failed: invalid permissions, must be 700 for security considerations\n", name);
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
} else {
|
||||
// softx requires we give up root now
|
||||
setreuid(getuid(), getuid());
|
||||
setegid(getgid());
|
||||
}
|
||||
|
||||
if ( ( reflib_library = dlopen( fn, RTLD_NOW ) ) == 0 )
|
||||
{
|
||||
Com_Printf( "LoadLibrary(\"%s\") failed: %s\n", name , dlerror());
|
||||
return false;
|
||||
}
|
||||
|
||||
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_GetModeInfo = VID_GetModeInfo;
|
||||
ri.Vid_MenuInit = VID_MenuInit;
|
||||
ri.Vid_NewWindow = VID_NewWindow;
|
||||
|
||||
if ( ( GetRefAPI = (void *) dlsym( reflib_library, "GetRefAPI" ) ) == 0 )
|
||||
Com_Error( ERR_FATAL, "dlsym failed on %s", name );
|
||||
|
||||
re = GetRefAPI( ri );
|
||||
|
||||
if (re.api_version != API_VERSION)
|
||||
{
|
||||
VID_FreeReflib ();
|
||||
Com_Error (ERR_FATAL, "%s has incompatible api_version", name);
|
||||
}
|
||||
|
||||
/* Init IN (Mouse) */
|
||||
in_state.IN_CenterView_fp = IN_CenterView;
|
||||
in_state.Key_Event_fp = Do_Key_Event;
|
||||
in_state.viewangles = cl.viewangles;
|
||||
in_state.in_strafe_state = &in_strafe.state;
|
||||
|
||||
if ((RW_IN_Init_fp = dlsym(reflib_library, "RW_IN_Init")) == NULL ||
|
||||
(RW_IN_Shutdown_fp = dlsym(reflib_library, "RW_IN_Shutdown")) == NULL ||
|
||||
(RW_IN_Activate_fp = dlsym(reflib_library, "RW_IN_Activate")) == NULL ||
|
||||
(RW_IN_Commands_fp = dlsym(reflib_library, "RW_IN_Commands")) == NULL ||
|
||||
(RW_IN_Move_fp = dlsym(reflib_library, "RW_IN_Move")) == NULL ||
|
||||
(RW_IN_Frame_fp = dlsym(reflib_library, "RW_IN_Frame")) == NULL)
|
||||
Sys_Error("No RW_IN functions in REF.\n");
|
||||
|
||||
Real_IN_Init();
|
||||
|
||||
if ( re.Init( 0, 0 ) == -1 )
|
||||
{
|
||||
re.Shutdown();
|
||||
VID_FreeReflib ();
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Init KBD */
|
||||
#if 1
|
||||
if ((KBD_Init_fp = dlsym(reflib_library, "KBD_Init")) == NULL ||
|
||||
(KBD_Update_fp = dlsym(reflib_library, "KBD_Update")) == NULL ||
|
||||
(KBD_Close_fp = dlsym(reflib_library, "KBD_Close")) == NULL)
|
||||
Sys_Error("No KBD functions in REF.\n");
|
||||
#else
|
||||
{
|
||||
void KBD_Init(void);
|
||||
void KBD_Update(void);
|
||||
void KBD_Close(void);
|
||||
|
||||
KBD_Init_fp = KBD_Init;
|
||||
KBD_Update_fp = KBD_Update;
|
||||
KBD_Close_fp = KBD_Close;
|
||||
}
|
||||
#endif
|
||||
KBD_Init_fp(Do_Key_Event);
|
||||
|
||||
// give up root now
|
||||
setreuid(getuid(), getuid());
|
||||
setegid(getgid());
|
||||
|
||||
Com_Printf( "------------------------------------\n");
|
||||
reflib_active = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
============
|
||||
VID_CheckChanges
|
||||
|
||||
This function gets called once just before drawing each frame, and it's sole purpose in life
|
||||
is to check to see if any of the video mode parameters have changed, and if they have to
|
||||
update the rendering DLL and/or video mode to match.
|
||||
============
|
||||
*/
|
||||
void VID_CheckChanges (void)
|
||||
{
|
||||
char name[100];
|
||||
cvar_t *sw_mode;
|
||||
|
||||
if ( vid_ref->modified )
|
||||
{
|
||||
S_StopAllSounds();
|
||||
}
|
||||
|
||||
while (vid_ref->modified)
|
||||
{
|
||||
/*
|
||||
** refresh has changed
|
||||
*/
|
||||
vid_ref->modified = false;
|
||||
vid_fullscreen->modified = true;
|
||||
cl.refresh_prepped = false;
|
||||
cls.disable_screen = true;
|
||||
|
||||
sprintf( name, "ref_%s.so", vid_ref->string );
|
||||
if ( !VID_LoadRefresh( name ) )
|
||||
{
|
||||
if ( strcmp (vid_ref->string, "soft") == 0 ||
|
||||
strcmp (vid_ref->string, "softx") == 0 ) {
|
||||
Com_Printf("Refresh failed\n");
|
||||
sw_mode = Cvar_Get( "sw_mode", "0", 0 );
|
||||
if (sw_mode->value != 0) {
|
||||
Com_Printf("Trying mode 0\n");
|
||||
Cvar_SetValue("sw_mode", 0);
|
||||
if ( !VID_LoadRefresh( name ) )
|
||||
Com_Error (ERR_FATAL, "Couldn't fall back to software refresh!");
|
||||
} else
|
||||
Com_Error (ERR_FATAL, "Couldn't fall back to software refresh!");
|
||||
}
|
||||
|
||||
Cvar_Set( "vid_ref", "soft" );
|
||||
|
||||
/*
|
||||
** drop the console if we fail to load a refresh
|
||||
*/
|
||||
if ( cls.key_dest != key_console )
|
||||
{
|
||||
Con_ToggleConsole_f();
|
||||
}
|
||||
}
|
||||
cls.disable_screen = false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
============
|
||||
VID_Init
|
||||
============
|
||||
*/
|
||||
void VID_Init (void)
|
||||
{
|
||||
/* Create the video variables so we know how to start the graphics drivers */
|
||||
// if DISPLAY is defined, try X
|
||||
if (getenv("DISPLAY"))
|
||||
vid_ref = Cvar_Get ("vid_ref", "softx", CVAR_ARCHIVE);
|
||||
else
|
||||
vid_ref = Cvar_Get ("vid_ref", "soft", CVAR_ARCHIVE);
|
||||
vid_xpos = Cvar_Get ("vid_xpos", "3", CVAR_ARCHIVE);
|
||||
vid_ypos = Cvar_Get ("vid_ypos", "22", CVAR_ARCHIVE);
|
||||
vid_fullscreen = Cvar_Get ("vid_fullscreen", "0", CVAR_ARCHIVE);
|
||||
vid_gamma = Cvar_Get( "vid_gamma", "1", CVAR_ARCHIVE );
|
||||
|
||||
/* Add some console commands that we want to handle */
|
||||
Cmd_AddCommand ("vid_restart", VID_Restart_f);
|
||||
|
||||
/* Disable the 3Dfx splash screen */
|
||||
putenv("FX_GLIDE_NO_SPLASH=0");
|
||||
|
||||
/* Start the graphics mode and load refresh DLL */
|
||||
VID_CheckChanges();
|
||||
}
|
||||
|
||||
/*
|
||||
============
|
||||
VID_Shutdown
|
||||
============
|
||||
*/
|
||||
void VID_Shutdown (void)
|
||||
{
|
||||
if ( reflib_active )
|
||||
{
|
||||
if (KBD_Close_fp)
|
||||
KBD_Close_fp();
|
||||
if (RW_IN_Shutdown_fp)
|
||||
RW_IN_Shutdown_fp();
|
||||
KBD_Close_fp = NULL;
|
||||
RW_IN_Shutdown_fp = NULL;
|
||||
re.Shutdown ();
|
||||
VID_FreeReflib ();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* INPUT */
|
||||
/*****************************************************************************/
|
||||
|
||||
cvar_t *in_joystick;
|
||||
|
||||
// This if fake, it's acutally done by the Refresh load
|
||||
void IN_Init (void)
|
||||
{
|
||||
in_joystick = Cvar_Get ("in_joystick", "0", CVAR_ARCHIVE);
|
||||
}
|
||||
|
||||
void Real_IN_Init (void)
|
||||
{
|
||||
if (RW_IN_Init_fp)
|
||||
RW_IN_Init_fp(&in_state);
|
||||
}
|
||||
|
||||
void IN_Shutdown (void)
|
||||
{
|
||||
if (RW_IN_Shutdown_fp)
|
||||
RW_IN_Shutdown_fp();
|
||||
}
|
||||
|
||||
void IN_Commands (void)
|
||||
{
|
||||
if (RW_IN_Commands_fp)
|
||||
RW_IN_Commands_fp();
|
||||
}
|
||||
|
||||
void IN_Move (usercmd_t *cmd)
|
||||
{
|
||||
if (RW_IN_Move_fp)
|
||||
RW_IN_Move_fp(cmd);
|
||||
}
|
||||
|
||||
void IN_Frame (void)
|
||||
{
|
||||
if (RW_IN_Frame_fp)
|
||||
RW_IN_Frame_fp();
|
||||
}
|
||||
|
||||
void IN_Activate (qboolean active)
|
||||
{
|
||||
if (RW_IN_Activate_fp)
|
||||
RW_IN_Activate_fp(active);
|
||||
}
|
||||
|
||||
void Do_Key_Event(int key, qboolean down)
|
||||
{
|
||||
Key_Event(key, down, Sys_Milliseconds());
|
||||
}
|
||||
|
Reference in New Issue
Block a user