From ad25458c5aedf0a193b28ce0da6b85f08890e63d Mon Sep 17 00:00:00 2001 From: lewa_j Date: Thu, 15 Jan 2026 21:47:01 +0300 Subject: [PATCH] ref: dx2: Move more code around (r_draw, r_main, r_surf) --- ref/dx2/r_context.c | 444 +------------------------------------------- ref/dx2/r_d3d.c | 3 + ref/dx2/r_draw.c | 254 +++++++++++++++++++++++++ ref/dx2/r_image.c | 8 +- ref/dx2/r_local.h | 54 +++++- ref/dx2/r_main.c | 204 ++++++++++++++++++++ ref/dx2/r_surf.c | 31 ++++ ref/dx2/wscript | 2 +- 8 files changed, 551 insertions(+), 449 deletions(-) create mode 100644 ref/dx2/r_draw.c create mode 100644 ref/dx2/r_main.c create mode 100644 ref/dx2/r_surf.c diff --git a/ref/dx2/r_context.c b/ref/dx2/r_context.c index 22b2d1f6..f20efac4 100644 --- a/ref/dx2/r_context.c +++ b/ref/dx2/r_context.c @@ -17,19 +17,13 @@ GNU General Public License for more details. #define INITGUID #include "r_local.h" #include "xash3d_mathlib.h" -#include "ref_params.h" //#pragma comment(lib, "ddraw.lib") //TODO COM_GetProcAddress ref_api_t gEngfuncs; -static ref_globals_t *gpGlobals; -ref_client_t *gp_cl; - -poolhandle_t r_temppool; - -gl_globals_t tr; -ref_instance_t RI; +ref_globals_t *gpGlobals; +ref_client_t *gp_cl; static void R_SimpleStub( void ) { @@ -77,95 +71,6 @@ static qboolean R_SetDisplayTransform( ref_screen_rotation_t rotate, int offset_ return ret; } -void R_GammaChanged( qboolean do_reset_gamma ) -{ - if( do_reset_gamma ) - { - // paranoia cubemap rendering - if( gEngfuncs.drawFuncs->GL_BuildLightmaps ) - gEngfuncs.drawFuncs->GL_BuildLightmaps( ); - } - else - { - //GL_RebuildLightmaps(); - } -} - -void R_BeginFrame( qboolean clearScene ) -{ - - gEngfuncs.CL_ExtraUpdate(); -} - -static void R_RenderScene( void ) -{ - model_t *worldmodel = gp_cl->models[1]; - if (!worldmodel && RI.drawWorld) - gEngfuncs.Host_Error("%s: NULL worldmodel\n", __func__); - - // frametime is valid only for normal pass - if (FBitSet(RI.params, RP_ENVVIEW) == 0) - tr.frametime = gp_cl->time - gp_cl->oldtime; - else tr.frametime = 0.0; - - // begin a new frame - tr.framecount++; - -#if 0 - R_PushDlights(); - - R_SetupFrustum(); - R_SetupFrame(); - R_SetupGL(true); - R_Clear(~0); - - R_MarkLeaves(); - R_DrawFog(); - if (RI.drawWorld) - R_AnimateRipples(); - - R_CheckGLFog(); - R_DrawWorld(); - R_CheckFog(); - - gEngfuncs.CL_ExtraUpdate(); // don't let sound get messed up if going slow - - R_DrawEntitiesOnList(); - - R_DrawWaterSurfaces(); -#endif -} - -void R_EndFrame( void ) -{ - //swap - if (!dxc.window) - return; - - if (dxc.pddsBack) - { - RECT dstRect = {}; - POINT point = { 0,0 }; - ClientToScreen(dxc.window, &point); - GetClientRect(dxc.window, &dstRect); - OffsetRect(&dstRect, point.x, point.y); - - RECT srcRect = { 0,0,dxc.windowWidth,dxc.windowHeight }; - DXCheck(IDirectDrawSurface_Blt(dxc.pddsPrimary, &dstRect, dxc.pddsBack, &srcRect, DDBLT_WAIT, NULL)); - } - - //resize - RECT rect = {}; - GetClientRect(dxc.window, &rect); - int w = rect.right - rect.left; - int h = rect.bottom - rect.top; - - if (w != dxc.windowWidth || h != dxc.windowHeight) - { - D3D_Resize(w, h); - } -} - void GL_BackendStartFrame( void ) { @@ -176,23 +81,12 @@ void GL_BackendEndFrame( void ) } - -void R_AllowFog( qboolean allowed ) -{ - -} - void GL_SetRenderMode( int mode ) { dxc.renderMode = mode; } -static qboolean R_AddEntity( struct cl_entity_s *clent, int type ) -{ - return true; -} - static void CL_AddCustomBeam( cl_entity_t *pEnvBeam ) { ; @@ -224,226 +118,6 @@ static void R_SetupSky( int *skytextures ) ; } -static void R_Set2DMode( qboolean enable ) -{ - -} - -static void R_DrawStretchRaw( float x, float y, float w, float h, int cols, int rows, const byte *data, qboolean dirty ) -{ - ; -} - -static void D3D_SetVert( D3DTLVERTEX* v, float x, float y, float z, float w, float tu, float tv ) -{ - v->sx = x; - v->sy = y; - v->sz = z; - v->rhw = w; - //v->color = RGBA_MAKE(250, 10, 10, 255); - v->tu = tu; - v->tv = tv; -} - -static void D3D_SetTri( D3DTRIANGLE *t, int v1, int v2, int v3 ) -{ - t->v1 = v1; - t->v2 = v2; - t->v3 = v3; - t->wFlags = D3DTRIFLAG_EDGEENABLETRIANGLE; -} - -static void D3D_PutInstruction( void **dst, BYTE opcode, BYTE size, WORD count ) -{ - D3DINSTRUCTION* inst = (D3DINSTRUCTION*)*dst; - inst->bOpcode = opcode; - inst->bSize = size; - inst->wCount = count; - *dst = (void*)(((D3DINSTRUCTION*)*dst) + 1); -} - -static void D3D_PutProcessVertices( void** dst, DWORD flags, WORD start, WORD count ) -{ - D3D_PutInstruction(dst, D3DOP_PROCESSVERTICES, sizeof(D3DPROCESSVERTICES), 1); - - D3DPROCESSVERTICES* pv = (D3DPROCESSVERTICES*)*dst; - pv->dwFlags = flags; - pv->wStart = start; - pv->wDest = start; - pv->dwCount = count; - pv->dwReserved = 0; - *dst = (void*)(((D3DPROCESSVERTICES*)*dst) + 1); -} - -static void D3D_PutRenderState( void** dst, D3DRENDERSTATETYPE type, DWORD arg ) -{ - D3DSTATE* s = (D3DSTATE*)*dst; - - s->drstRenderStateType = type; - s->dwArg[0] = arg; - *dst = (void*)(((D3DSTATE*)*dst) + 1); - -} - -static void R_DrawStretchPic( float x, float y, float w, float h, float s1, float t1, float s2, float t2, int texnum ) -{ - if (texnum <= 0 || texnum >= MAX_TEXTURES) - return; - - dx_texture_t *tex = R_GetTexture(texnum); - if (!tex->dds) - return; - -#if 0 - RECT dstRect = { x, y, x + w, y + h }; - RECT srcRect = { s1 * tex->width, t1 * tex->height, s2 * tex->width, t2 * tex->height}; - - if (dxc.renderMode == kRenderNormal) - { - DXCheck(IDirectDrawSurface_Blt(dxc.pddsBack, &dstRect, tex->dds, &srcRect, DDBLT_WAIT, NULL)); - } - else - { - DDCOLORKEY ddck; - ddck.dwColorSpaceLowValue = 0; - ddck.dwColorSpaceHighValue = ddck.dwColorSpaceLowValue; - DXCheck(IDirectDrawSurface_SetColorKey(tex->dds, DDCKEY_SRCBLT, &ddck)); - - DXCheck(IDirectDrawSurface_Blt(dxc.pddsBack, &dstRect, tex->dds, &srcRect, DDBLT_WAIT | DDBLT_KEYSRC, NULL)); - } -#else - -#define DX2_CREATE_EB 0 - - if (!dxc.pd3dd) - return; - - IDirect3DExecuteBuffer* pd3deb = NULL; -#if DX2_CREATE_EB - D3DEXECUTEBUFFERDESC ebd = { 0 }; - memset(&ebd, 0, sizeof(ebd)); - ebd.dwSize = sizeof(ebd); - ebd.dwFlags = D3DDEB_BUFSIZE; - ebd.dwBufferSize = 512; - DXCheck(IDirect3DDevice_CreateExecuteBuffer(dxc.pd3dd, &ebd, &pd3deb, NULL)); -#else - pd3deb = dxc.pd3deb; -#endif - - if (!pd3deb) - return; - { - D3DEXECUTEBUFFERDESC ebDesc = { 0 }; - memset(&ebDesc, 0, sizeof(ebDesc)); - ebDesc.dwSize = sizeof(ebDesc); - ebDesc.dwFlags = D3DDEB_LPDATA; - DXCheck(IDirect3DExecuteBuffer_Lock(pd3deb, &ebDesc)); - - void* cur = ebDesc.lpData; - - const int vertCount = 4; - D3DTLVERTEX* verts = (D3DTLVERTEX*)cur; - -#define VecToD3DCOLOR(v) D3DRGBA(v[0], v[1], v[2], v[3]) - - verts[0].color = VecToD3DCOLOR(dxc.currentColor); - D3D_SetVert(verts, x, y, 0.5, 1, s1, t1); - verts[1].color = VecToD3DCOLOR(dxc.currentColor); - D3D_SetVert(verts + 1, x + w, y, 0.5, 1, s2, t1); - verts[2].color = VecToD3DCOLOR(dxc.currentColor); - D3D_SetVert(verts + 2, x + w, y + h, 0.5, 1, s2, t2); - verts[3].color = VecToD3DCOLOR(dxc.currentColor); - D3D_SetVert(verts + 3, x, y + h, 0.5, 1, s1, t2); - - cur = (void*)(((D3DTLVERTEX*)cur) + vertCount); - - void* insStart = cur; - - D3D_PutProcessVertices(&cur, D3DPROCESSVERTICES_COPY | D3DPROCESSVERTICES_UPDATEEXTENTS, 0, vertCount); - //align - if (!(((ULONG)cur) & 7)) { - D3D_PutInstruction(&cur, D3DOP_TRIANGLE, sizeof(D3DTRIANGLE), 0); - } - - D3D_PutInstruction(&cur, D3DOP_STATERENDER, sizeof(D3DSTATE), 3); - D3D_PutRenderState(&cur, D3DRENDERSTATE_TEXTUREHANDLE, tex->d3dHandle); - //D3D_PutRenderState(&cur, D3DRENDERSTATE_TEXTUREMAPBLEND, D3DTBLEND_DECAL); - - if (dxc.renderMode == kRenderTransAlpha) - { - D3D_PutRenderState(&cur, D3DRENDERSTATE_BLENDENABLE, FALSE); - D3D_PutRenderState(&cur, D3DRENDERSTATE_ALPHATESTENABLE, TRUE); - } - else if (dxc.renderMode == kRenderGlow || - dxc.renderMode == kRenderTransAdd) - { - D3D_PutRenderState(&cur, D3DRENDERSTATE_BLENDENABLE, TRUE); - D3D_PutRenderState(&cur, D3DRENDERSTATE_ALPHATESTENABLE, FALSE); - D3D_PutInstruction(&cur, D3DOP_STATERENDER, sizeof(D3DSTATE), 2); - D3D_PutRenderState(&cur, D3DRENDERSTATE_SRCBLEND, D3DBLEND_SRCALPHA); - D3D_PutRenderState(&cur, D3DRENDERSTATE_DESTBLEND, D3DBLEND_ONE); - } - else if (dxc.renderMode == kRenderTransColor || dxc.renderMode == kRenderTransTexture) - { - D3D_PutRenderState(&cur, D3DRENDERSTATE_BLENDENABLE, TRUE); - D3D_PutRenderState(&cur, D3DRENDERSTATE_ALPHATESTENABLE, FALSE); - D3D_PutInstruction(&cur, D3DOP_STATERENDER, sizeof(D3DSTATE), 2); - D3D_PutRenderState(&cur, D3DRENDERSTATE_SRCBLEND, D3DBLEND_SRCALPHA); - D3D_PutRenderState(&cur, D3DRENDERSTATE_DESTBLEND, D3DBLEND_INVSRCALPHA); - } - else//kRenderNormal - { - D3D_PutRenderState(&cur, D3DRENDERSTATE_BLENDENABLE, FALSE); - D3D_PutRenderState(&cur, D3DRENDERSTATE_ALPHATESTENABLE, FALSE); - } - - D3D_PutInstruction(&cur, D3DOP_TRIANGLE, sizeof(D3DTRIANGLE), 2); - - D3DTRIANGLE* tris = (D3DTRIANGLE*)cur; - D3D_SetTri(tris, 0, 1, 2); - D3D_SetTri(tris + 1, 0, 2, 3); - cur = (void*)(((D3DTRIANGLE*)cur) + 2); - - D3D_PutInstruction(&cur, D3DOP_EXIT, 0, 0); - - DXCheck(IDirect3DExecuteBuffer_Unlock(pd3deb)); - - D3DEXECUTEDATA exData = { 0 }; - memset(&exData, 0, sizeof(exData)); - exData.dwSize = sizeof(exData); - exData.dwVertexCount = vertCount; - exData.dwVertexOffset = 0; - exData.dwInstructionOffset = ((char*)insStart - (char*)ebDesc.lpData); - exData.dwInstructionLength = ((char*)cur - (char*)insStart); - DXCheck(IDirect3DExecuteBuffer_SetExecuteData(pd3deb , &exData)); - } - - DXCheck(IDirect3DDevice_BeginScene(dxc.pd3dd)); - DXCheck(IDirect3DDevice_Execute(dxc.pd3dd, pd3deb, dxc.viewport, D3DEXECUTE_CLIPPED)); - DXCheck(IDirect3DDevice_EndScene(dxc.pd3dd)); - -#if DX2_CREATE_EB - if (pd3deb && pd3deb != dxc.pd3deb) - IDirect3DExecuteBuffer_Release(pd3deb); -#endif -#endif -} - -static void FillRGBA( int rendermode, float x, float y, float w, float h, byte r, byte g, byte b, byte a ) -{ - RECT dstRect = { x, y, x + w, y + h }; - DDBLTFX bltFx = { 0 }; - bltFx.dwSize = sizeof(bltFx); - bltFx.dwFillColor = RGBA_MAKE(r, g, b, a); - DXCheck(IDirectDrawSurface_Blt(dxc.pddsBack, &dstRect, NULL, NULL, DDBLT_WAIT | DDBLT_COLORFILL, &bltFx)); -} - -static int WorldToScreen( const vec3_t world, vec3_t screen ) -{ - VectorClear( screen ); - return 0; -} - static qboolean VID_ScreenShot( const char *filename, int shot_type ) { return false; @@ -490,33 +164,11 @@ static void R_SetSkyCloudsTextures( int solidskyTexture, int alphaskyTexture ) ; } -static void GL_SubdivideSurface( model_t *mod, msurface_t *fa ) -{ - ; -} - static void CL_RunLightStyles( lightstyle_t *ls ) { } -static void R_GetSpriteParms( int *frameWidth, int *frameHeight, int *numFrames, int currentFrame, const model_t *pSprite ) -{ - if( frameWidth ) - *frameWidth = 0; - - if( frameHeight ) - *frameHeight = 0; - - if( numFrames ) - *numFrames = 0; -} - -static int R_GetSpriteTexture( const model_t *m_pSpriteModel, int frame ) -{ - return 0; -} - static qboolean Mod_ProcessRenderData( model_t *mod, qboolean create, const byte *buffer, size_t buffersize ) { gEngfuncs.Con_Printf("Mod_ProcessRenderData(%p(%s), %d, %p, %zu)\n", mod, mod->name, create, buffer, buffersize); @@ -661,10 +313,6 @@ static void R_EntityRemoveDecals( struct model_s *mod ) ; } -static void AVI_UploadRawFrame( int texture, int cols, int rows, int width, int height, const byte *data ) -{ - ; -} static void GL_Bind( int tmu, unsigned int texnum ) { @@ -681,11 +329,6 @@ static void GL_TexGen( unsigned int coord, unsigned int mode ) ; } -static void GL_UpdateTexSize( int texnum, int width, int height, int depth ) -{ - ; -} - static void GL_DrawParticles( const struct ref_viewpass_s *rvp, qboolean trans_pass, float frametime ) { ; @@ -702,78 +345,11 @@ static struct mstudiotex_s *StudioGetTexture( struct cl_entity_s *e ) return NULL; } - -static void R_SetupRefParams( const ref_viewpass_t *rvp ) -{ -// RI.params = RP_NONE; - RI.drawWorld = FBitSet(rvp->flags, RF_DRAW_WORLD); - RI.onlyClientDraw = FBitSet(rvp->flags, RF_ONLY_CLIENTDRAW); - RI.farClip = 0; - - if (!FBitSet(rvp->flags, RF_DRAW_CUBEMAP)) - RI.drawOrtho = FBitSet(rvp->flags, RF_DRAW_OVERVIEW); - else RI.drawOrtho = false; - - // setup viewport - RI.viewport[0] = rvp->viewport[0]; - RI.viewport[1] = rvp->viewport[1]; - RI.viewport[2] = rvp->viewport[2]; - RI.viewport[3] = rvp->viewport[3]; - - // calc FOV - RI.fov_x = rvp->fov_x; - RI.fov_y = rvp->fov_y; - - VectorCopy(rvp->vieworigin, RI.vieworg); - VectorCopy(rvp->viewangles, RI.viewangles); - VectorCopy(rvp->vieworigin, RI.pvsorigin); -} - -static void R_RenderFrame( const struct ref_viewpass_s *rvp ) -{ - if (r_norefresh->value) - return; - - // setup the initial render params - R_SetupRefParams(rvp); - - // completely override rendering - if (gEngfuncs.drawFuncs->GL_RenderFrame != NULL) - { - tr.fCustomRendering = true; - - if (gEngfuncs.drawFuncs->GL_RenderFrame(rvp)) - { - //R_GatherPlayerLight(); - tr.realframecount++; - tr.fResetVis = true; - return; - } - } - - tr.fCustomRendering = false; - //if (!RI.onlyClientDraw) - // R_RunViewmodelEvents(); - - tr.realframecount++; // right called after viewmodel events - R_RenderScene(); -} - -static void GL_OrthoBounds( const float *mins, const float *maxs ) -{ - ; -} - static qboolean R_SpeedsMessage( char *out, size_t size ) { return false; } -static byte *Mod_GetCurrentVis( void ) -{ - return NULL; -} - static void R_NewMap( void ) { @@ -781,17 +357,6 @@ static void R_NewMap( void ) gEngfuncs.drawFuncs->R_NewMap(); } -static void R_ClearScene( void ) -{ - tr.draw_list->num_solid_entities = 0; - tr.draw_list->num_trans_entities = 0; - tr.draw_list->num_beam_entities = 0; - - // clear the scene befor start new frame - if (gEngfuncs.drawFuncs->R_ClearScene != NULL) - gEngfuncs.drawFuncs->R_ClearScene(); -} - static void *R_GetProcAddress( const char *name ) { return NULL; @@ -827,11 +392,6 @@ static void Fog( float flFogColor[3], float flStart, float flEnd, int bOn ) ; } -static void ScreenToWorld( const float *screen, float *world ) -{ - ; -} - static void GetMatrix( const int pname, float *matrix ) { ; diff --git a/ref/dx2/r_d3d.c b/ref/dx2/r_d3d.c index 8bfb35fc..e724df46 100644 --- a/ref/dx2/r_d3d.c +++ b/ref/dx2/r_d3d.c @@ -18,6 +18,9 @@ GNU General Public License for more details. DEFINE_ENGINE_SHARED_CVAR_LIST() +poolhandle_t r_temppool; + +dx_globals_t tr; dx_context_t dxc; const char *dxResultToStr( HRESULT r ) diff --git a/ref/dx2/r_draw.c b/ref/dx2/r_draw.c new file mode 100644 index 00000000..8102000b --- /dev/null +++ b/ref/dx2/r_draw.c @@ -0,0 +1,254 @@ +/* +r_draw.c -- dx2 2D drawing +Copyright (C) 2025-2026 lewa_j + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. +*/ + +#include "r_local.h" + + +void R_Set2DMode( qboolean enable ) +{ + +} + +void R_DrawStretchRaw( float x, float y, float w, float h, int cols, int rows, const byte *data, qboolean dirty ) +{ + ; +} + +static void D3D_SetVert( D3DTLVERTEX* v, float x, float y, float z, float w, float tu, float tv ) +{ + v->sx = x; + v->sy = y; + v->sz = z; + v->rhw = w; + //v->color = RGBA_MAKE(250, 10, 10, 255); + v->tu = tu; + v->tv = tv; +} + +static void D3D_SetTri( D3DTRIANGLE *t, int v1, int v2, int v3 ) +{ + t->v1 = v1; + t->v2 = v2; + t->v3 = v3; + t->wFlags = D3DTRIFLAG_EDGEENABLETRIANGLE; +} + +static void D3D_PutInstruction( void **dst, BYTE opcode, BYTE size, WORD count ) +{ + D3DINSTRUCTION* inst = (D3DINSTRUCTION*)*dst; + inst->bOpcode = opcode; + inst->bSize = size; + inst->wCount = count; + *dst = (void*)(((D3DINSTRUCTION*)*dst) + 1); +} + +static void D3D_PutProcessVertices( void** dst, DWORD flags, WORD start, WORD count ) +{ + D3D_PutInstruction(dst, D3DOP_PROCESSVERTICES, sizeof(D3DPROCESSVERTICES), 1); + + D3DPROCESSVERTICES* pv = (D3DPROCESSVERTICES*)*dst; + pv->dwFlags = flags; + pv->wStart = start; + pv->wDest = start; + pv->dwCount = count; + pv->dwReserved = 0; + *dst = (void*)(((D3DPROCESSVERTICES*)*dst) + 1); +} + +static void D3D_PutRenderState( void** dst, D3DRENDERSTATETYPE type, DWORD arg ) +{ + D3DSTATE* s = (D3DSTATE*)*dst; + + s->drstRenderStateType = type; + s->dwArg[0] = arg; + *dst = (void*)(((D3DSTATE*)*dst) + 1); + +} + +void R_DrawStretchPic( float x, float y, float w, float h, float s1, float t1, float s2, float t2, int texnum ) +{ + if (texnum <= 0 || texnum >= MAX_TEXTURES) + return; + + dx_texture_t *tex = R_GetTexture(texnum); + if (!tex->dds) + return; + +#if 0 + RECT dstRect = { x, y, x + w, y + h }; + RECT srcRect = { s1 * tex->width, t1 * tex->height, s2 * tex->width, t2 * tex->height}; + + if (dxc.renderMode == kRenderNormal) + { + DXCheck(IDirectDrawSurface_Blt(dxc.pddsBack, &dstRect, tex->dds, &srcRect, DDBLT_WAIT, NULL)); + } + else + { + DDCOLORKEY ddck; + ddck.dwColorSpaceLowValue = 0; + ddck.dwColorSpaceHighValue = ddck.dwColorSpaceLowValue; + DXCheck(IDirectDrawSurface_SetColorKey(tex->dds, DDCKEY_SRCBLT, &ddck)); + + DXCheck(IDirectDrawSurface_Blt(dxc.pddsBack, &dstRect, tex->dds, &srcRect, DDBLT_WAIT | DDBLT_KEYSRC, NULL)); + } +#else + +#define DX2_CREATE_EB 0 + + if (!dxc.pd3dd) + return; + + IDirect3DExecuteBuffer* pd3deb = NULL; +#if DX2_CREATE_EB + D3DEXECUTEBUFFERDESC ebd = { 0 }; + memset(&ebd, 0, sizeof(ebd)); + ebd.dwSize = sizeof(ebd); + ebd.dwFlags = D3DDEB_BUFSIZE; + ebd.dwBufferSize = 512; + DXCheck(IDirect3DDevice_CreateExecuteBuffer(dxc.pd3dd, &ebd, &pd3deb, NULL)); +#else + pd3deb = dxc.pd3deb; +#endif + + if (!pd3deb) + return; + { + D3DEXECUTEBUFFERDESC ebDesc = { 0 }; + memset(&ebDesc, 0, sizeof(ebDesc)); + ebDesc.dwSize = sizeof(ebDesc); + ebDesc.dwFlags = D3DDEB_LPDATA; + DXCheck(IDirect3DExecuteBuffer_Lock(pd3deb, &ebDesc)); + + void* cur = ebDesc.lpData; + + const int vertCount = 4; + D3DTLVERTEX* verts = (D3DTLVERTEX*)cur; + +#define VecToD3DCOLOR(v) D3DRGBA(v[0], v[1], v[2], v[3]) + + verts[0].color = VecToD3DCOLOR(dxc.currentColor); + D3D_SetVert(verts, x, y, 0.5, 1, s1, t1); + verts[1].color = VecToD3DCOLOR(dxc.currentColor); + D3D_SetVert(verts + 1, x + w, y, 0.5, 1, s2, t1); + verts[2].color = VecToD3DCOLOR(dxc.currentColor); + D3D_SetVert(verts + 2, x + w, y + h, 0.5, 1, s2, t2); + verts[3].color = VecToD3DCOLOR(dxc.currentColor); + D3D_SetVert(verts + 3, x, y + h, 0.5, 1, s1, t2); + + cur = (void*)(((D3DTLVERTEX*)cur) + vertCount); + + void* insStart = cur; + + D3D_PutProcessVertices(&cur, D3DPROCESSVERTICES_COPY | D3DPROCESSVERTICES_UPDATEEXTENTS, 0, vertCount); + //align + if (!(((ULONG)cur) & 7)) { + D3D_PutInstruction(&cur, D3DOP_TRIANGLE, sizeof(D3DTRIANGLE), 0); + } + + D3D_PutInstruction(&cur, D3DOP_STATERENDER, sizeof(D3DSTATE), 3); + D3D_PutRenderState(&cur, D3DRENDERSTATE_TEXTUREHANDLE, tex->d3dHandle); + //D3D_PutRenderState(&cur, D3DRENDERSTATE_TEXTUREMAPBLEND, D3DTBLEND_DECAL); + + if (dxc.renderMode == kRenderTransAlpha) + { + D3D_PutRenderState(&cur, D3DRENDERSTATE_BLENDENABLE, FALSE); + D3D_PutRenderState(&cur, D3DRENDERSTATE_ALPHATESTENABLE, TRUE); + } + else if (dxc.renderMode == kRenderGlow || + dxc.renderMode == kRenderTransAdd) + { + D3D_PutRenderState(&cur, D3DRENDERSTATE_BLENDENABLE, TRUE); + D3D_PutRenderState(&cur, D3DRENDERSTATE_ALPHATESTENABLE, FALSE); + D3D_PutInstruction(&cur, D3DOP_STATERENDER, sizeof(D3DSTATE), 2); + D3D_PutRenderState(&cur, D3DRENDERSTATE_SRCBLEND, D3DBLEND_SRCALPHA); + D3D_PutRenderState(&cur, D3DRENDERSTATE_DESTBLEND, D3DBLEND_ONE); + } + else if (dxc.renderMode == kRenderTransColor || dxc.renderMode == kRenderTransTexture) + { + D3D_PutRenderState(&cur, D3DRENDERSTATE_BLENDENABLE, TRUE); + D3D_PutRenderState(&cur, D3DRENDERSTATE_ALPHATESTENABLE, FALSE); + D3D_PutInstruction(&cur, D3DOP_STATERENDER, sizeof(D3DSTATE), 2); + D3D_PutRenderState(&cur, D3DRENDERSTATE_SRCBLEND, D3DBLEND_SRCALPHA); + D3D_PutRenderState(&cur, D3DRENDERSTATE_DESTBLEND, D3DBLEND_INVSRCALPHA); + } + else//kRenderNormal + { + D3D_PutRenderState(&cur, D3DRENDERSTATE_BLENDENABLE, FALSE); + D3D_PutRenderState(&cur, D3DRENDERSTATE_ALPHATESTENABLE, FALSE); + } + + D3D_PutInstruction(&cur, D3DOP_TRIANGLE, sizeof(D3DTRIANGLE), 2); + + D3DTRIANGLE* tris = (D3DTRIANGLE*)cur; + D3D_SetTri(tris, 0, 1, 2); + D3D_SetTri(tris + 1, 0, 2, 3); + cur = (void*)(((D3DTRIANGLE*)cur) + 2); + + D3D_PutInstruction(&cur, D3DOP_EXIT, 0, 0); + + DXCheck(IDirect3DExecuteBuffer_Unlock(pd3deb)); + + D3DEXECUTEDATA exData = { 0 }; + memset(&exData, 0, sizeof(exData)); + exData.dwSize = sizeof(exData); + exData.dwVertexCount = vertCount; + exData.dwVertexOffset = 0; + exData.dwInstructionOffset = ((char*)insStart - (char*)ebDesc.lpData); + exData.dwInstructionLength = ((char*)cur - (char*)insStart); + DXCheck(IDirect3DExecuteBuffer_SetExecuteData(pd3deb , &exData)); + } + + DXCheck(IDirect3DDevice_BeginScene(dxc.pd3dd)); + DXCheck(IDirect3DDevice_Execute(dxc.pd3dd, pd3deb, dxc.viewport, D3DEXECUTE_CLIPPED)); + DXCheck(IDirect3DDevice_EndScene(dxc.pd3dd)); + +#if DX2_CREATE_EB + if (pd3deb && pd3deb != dxc.pd3deb) + IDirect3DExecuteBuffer_Release(pd3deb); +#endif +#endif +} + +void FillRGBA( int rendermode, float x, float y, float w, float h, byte r, byte g, byte b, byte a ) +{ + RECT dstRect = { x, y, x + w, y + h }; + DDBLTFX bltFx = { 0 }; + bltFx.dwSize = sizeof(bltFx); + bltFx.dwFillColor = RGBA_MAKE(r, g, b, a); + DXCheck(IDirectDrawSurface_Blt(dxc.pddsBack, &dstRect, NULL, NULL, DDBLT_WAIT | DDBLT_COLORFILL, &bltFx)); +} + + +void R_GetSpriteParms( int *frameWidth, int *frameHeight, int *numFrames, int currentFrame, const model_t *pSprite ) +{ + if( frameWidth ) + *frameWidth = 0; + + if( frameHeight ) + *frameHeight = 0; + + if( numFrames ) + *numFrames = 0; +} + +int R_GetSpriteTexture( const model_t *m_pSpriteModel, int frame ) +{ + return 0; +} + +void AVI_UploadRawFrame( int texture, int cols, int rows, int width, int height, const byte *data ) +{ + ; +} diff --git a/ref/dx2/r_image.c b/ref/dx2/r_image.c index 61272876..0b58b558 100644 --- a/ref/dx2/r_image.c +++ b/ref/dx2/r_image.c @@ -1,5 +1,6 @@ /* -r_context.c -- dx2 renderer image +r_context.c -- dx2 renderer texture uploading and processing +Copyright (C) 2010 Uncle Mike Copyright (C) 2025 lewa_j This program is free software: you can redistribute it and/or modify @@ -762,3 +763,8 @@ void R_OverrideTextureSourceSize(unsigned int textnum, unsigned int srcWidth, un { } + +void GL_UpdateTexSize( int texnum, int width, int height, int depth ) +{ + ; +} diff --git a/ref/dx2/r_local.h b/ref/dx2/r_local.h index 5666d614..76889cb7 100644 --- a/ref/dx2/r_local.h +++ b/ref/dx2/r_local.h @@ -1,3 +1,19 @@ +/* +r_local.h - renderer local declarations +Copyright (C) 2010 Uncle Mike +Copyright (C) 2025-2026 lewa_j + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. +*/ + #pragma once #include "ref_api.h" @@ -8,10 +24,11 @@ #include #include -extern ref_api_t gEngfuncs; - extern poolhandle_t r_temppool; +extern ref_api_t gEngfuncs; +extern ref_client_t *gp_cl; + #define MAX_TEXTURES 8192 #define TEXTURES_HASH_SIZE (MAX_TEXTURES >> 2) @@ -154,9 +171,9 @@ typedef struct // get from engine cl_entity_t *entities; uint max_entities; -} gl_globals_t; +} dx_globals_t; -extern gl_globals_t tr; +extern dx_globals_t tr; struct dx_context_s { @@ -199,10 +216,30 @@ void GL_InitExtensions( void ); void GL_ClearExtensions( void ); void D3D_Resize( int width, int height ); +//r_main.c +void R_GammaChanged( qboolean do_reset_gamma ); +void R_BeginFrame( qboolean clearScene ); +void R_RenderScene( void ); +void R_EndFrame( void ); +void R_AllowFog( qboolean allowed ); +void R_RenderFrame( const struct ref_viewpass_s *rvp ); +qboolean R_AddEntity( struct cl_entity_s *clent, int type ); +void R_ClearScene( void ); +int WorldToScreen( const vec3_t world, vec3_t screen ); +void ScreenToWorld( const float *screen, float *world ); + +//r_draw.c +void R_Set2DMode( qboolean enable ); +void R_DrawStretchRaw( float x, float y, float w, float h, int cols, int rows, const byte *data, qboolean dirty ); +void R_DrawStretchPic( float x, float y, float w, float h, float s1, float t1, float s2, float t2, int texnum ); +void FillRGBA( int rendermode, float x, float y, float w, float h, byte r, byte g, byte b, byte a ); +void R_GetSpriteParms( int *frameWidth, int *frameHeight, int *numFrames, int currentFrame, const model_t *pSprite ); +int R_GetSpriteTexture( const model_t *m_pSpriteModel, int frame ); +void AVI_UploadRawFrame( int texture, int cols, int rows, int width, int height, const byte *data ); + //r_image.c void R_InitImages( void ); dx_texture_t *R_GetTexture( unsigned int texnum ); - void R_ShowTextures( void ); const byte *R_GetTextureOriginalBuffer( unsigned int idx ); int GL_LoadTextureFromBuffer( const char *name, rgbdata_t *pic, texFlags_t flags, qboolean update ); @@ -218,6 +255,13 @@ int GL_LoadTextureArray( const char **names, int flags ); int GL_CreateTextureArray( const char *name, int width, int height, int depth, const void *buffer, texFlags_t flags ); void GL_FreeTexture( unsigned int texnum ); void R_OverrideTextureSourceSize( unsigned int textnum, unsigned int srcWidth, unsigned int srcHeight ); +void GL_UpdateTexSize( int texnum, int width, int height, int depth ); + +//r_surf.c +void GL_SubdivideSurface( model_t *mod, msurface_t *fa ); +void GL_OrthoBounds( const float *mins, const float *maxs ); +byte *Mod_GetCurrentVis( void ); + // // engine shared convars diff --git a/ref/dx2/r_main.c b/ref/dx2/r_main.c new file mode 100644 index 00000000..74fae9fa --- /dev/null +++ b/ref/dx2/r_main.c @@ -0,0 +1,204 @@ +/* +r_main.c -- dx2 renderer main loop +Copyright (C) 2010 Uncle Mike +Copyright (C) 2025-2026 lewa_j + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. +*/ + +#include "r_local.h" +#include "ref_params.h" +#include "xash3d_mathlib.h" + +ref_instance_t RI; + + +void R_GammaChanged( qboolean do_reset_gamma ) +{ + if( do_reset_gamma ) + { + // paranoia cubemap rendering + if( gEngfuncs.drawFuncs->GL_BuildLightmaps ) + gEngfuncs.drawFuncs->GL_BuildLightmaps( ); + } + else + { + //GL_RebuildLightmaps(); + } +} + +void R_BeginFrame( qboolean clearScene ) +{ + + gEngfuncs.CL_ExtraUpdate(); +} + +void R_RenderScene( void ) +{ + model_t *worldmodel = gp_cl->models[1]; + if (!worldmodel && RI.drawWorld) + gEngfuncs.Host_Error("%s: NULL worldmodel\n", __func__); + + // frametime is valid only for normal pass + if (FBitSet(RI.params, RP_ENVVIEW) == 0) + tr.frametime = gp_cl->time - gp_cl->oldtime; + else tr.frametime = 0.0; + + // begin a new frame + tr.framecount++; + +#if 0 + R_PushDlights(); + + R_SetupFrustum(); + R_SetupFrame(); + R_SetupGL(true); + R_Clear(~0); + + R_MarkLeaves(); + R_DrawFog(); + if (RI.drawWorld) + R_AnimateRipples(); + + R_CheckGLFog(); + R_DrawWorld(); + R_CheckFog(); + + gEngfuncs.CL_ExtraUpdate(); // don't let sound get messed up if going slow + + R_DrawEntitiesOnList(); + + R_DrawWaterSurfaces(); +#endif +} + +void R_EndFrame( void ) +{ + //swap + if (!dxc.window) + return; + + if (dxc.pddsBack) + { + RECT dstRect = { 0 }; + POINT point = { 0,0 }; + ClientToScreen(dxc.window, &point); + GetClientRect(dxc.window, &dstRect); + OffsetRect(&dstRect, point.x, point.y); + + RECT srcRect = { 0,0,dxc.windowWidth,dxc.windowHeight }; + DXCheck(IDirectDrawSurface_Blt(dxc.pddsPrimary, &dstRect, dxc.pddsBack, &srcRect, DDBLT_WAIT, NULL)); + } + + //resize + RECT rect = { 0 }; + GetClientRect(dxc.window, &rect); + int w = rect.right - rect.left; + int h = rect.bottom - rect.top; + + if (w != dxc.windowWidth || h != dxc.windowHeight) + { + D3D_Resize(w, h); + } +} + + +void R_AllowFog( qboolean allowed ) +{ + +} + + +static void R_SetupRefParams( const ref_viewpass_t *rvp ) +{ +// RI.params = RP_NONE; + RI.drawWorld = FBitSet(rvp->flags, RF_DRAW_WORLD); + RI.onlyClientDraw = FBitSet(rvp->flags, RF_ONLY_CLIENTDRAW); + RI.farClip = 0; + + if (!FBitSet(rvp->flags, RF_DRAW_CUBEMAP)) + RI.drawOrtho = FBitSet(rvp->flags, RF_DRAW_OVERVIEW); + else RI.drawOrtho = false; + + // setup viewport + RI.viewport[0] = rvp->viewport[0]; + RI.viewport[1] = rvp->viewport[1]; + RI.viewport[2] = rvp->viewport[2]; + RI.viewport[3] = rvp->viewport[3]; + + // calc FOV + RI.fov_x = rvp->fov_x; + RI.fov_y = rvp->fov_y; + + VectorCopy(rvp->vieworigin, RI.vieworg); + VectorCopy(rvp->viewangles, RI.viewangles); + VectorCopy(rvp->vieworigin, RI.pvsorigin); +} + + +void R_RenderFrame( const struct ref_viewpass_s *rvp ) +{ + if (r_norefresh->value) + return; + + // setup the initial render params + R_SetupRefParams(rvp); + + // completely override rendering + if (gEngfuncs.drawFuncs->GL_RenderFrame != NULL) + { + tr.fCustomRendering = true; + + if (gEngfuncs.drawFuncs->GL_RenderFrame(rvp)) + { + //R_GatherPlayerLight(); + tr.realframecount++; + tr.fResetVis = true; + return; + } + } + + tr.fCustomRendering = false; + //if (!RI.onlyClientDraw) + // R_RunViewmodelEvents(); + + tr.realframecount++; // right called after viewmodel events + R_RenderScene(); +} + + +qboolean R_AddEntity( struct cl_entity_s *clent, int type ) +{ + return true; +} + +void R_ClearScene( void ) +{ + tr.draw_list->num_solid_entities = 0; + tr.draw_list->num_trans_entities = 0; + tr.draw_list->num_beam_entities = 0; + + // clear the scene befor start new frame + if (gEngfuncs.drawFuncs->R_ClearScene != NULL) + gEngfuncs.drawFuncs->R_ClearScene(); +} + + +int WorldToScreen( const vec3_t world, vec3_t screen ) +{ + VectorClear( screen ); + return 0; +} + +void ScreenToWorld( const float *screen, float *world ) +{ + ; +} diff --git a/ref/dx2/r_surf.c b/ref/dx2/r_surf.c new file mode 100644 index 00000000..9dd37805 --- /dev/null +++ b/ref/dx2/r_surf.c @@ -0,0 +1,31 @@ +/* +r_surf.c - surface-related refresh code +Copyright (C) 2025-2026 lewa_j + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. +*/ + +#include "r_local.h" + +void GL_OrthoBounds( const float *mins, const float *maxs ) +{ + ; +} + +byte *Mod_GetCurrentVis( void ) +{ + return NULL; +} + +void GL_SubdivideSurface( model_t *mod, msurface_t *fa ) +{ + ; +} diff --git a/ref/dx2/wscript b/ref/dx2/wscript index 89ee6d6f..335fedc1 100644 --- a/ref/dx2/wscript +++ b/ref/dx2/wscript @@ -10,7 +10,7 @@ def configure(conf): def build(bld): bld.shlib( - source = ['r_context.c', 'r_image.c', 'r_d3d.c'], + source = ['r_context.c', 'r_image.c', 'r_d3d.c', 'r_main.c', 'r_draw.c', 'r_surf.c'], target = 'ref_dx2', defines = 'REF_DLL', use = 'engine_includes sdk_includes werror public USER32 DDRAW',