mirror of
https://github.com/electronicarts/CnC_Renegade.git
synced 2026-05-09 00:57:43 +02:00
Initial commit of Command & Conquer Renegade source code.
This commit is contained in:
@@ -0,0 +1,242 @@
|
||||
/*
|
||||
** Command & Conquer Renegade(tm)
|
||||
** Copyright 2025 Electronic Arts Inc.
|
||||
**
|
||||
** 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.
|
||||
**
|
||||
** You should have received a copy of the GNU General Public License
|
||||
** along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/***********************************************************************************************
|
||||
*** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
|
||||
***********************************************************************************************
|
||||
* *
|
||||
* Project Name : ww3d2 *
|
||||
* *
|
||||
* $Archive:: /Commando/Code/ww3d2/bwrender.cpp $*
|
||||
* *
|
||||
* Original Author:: Jani Penttinen *
|
||||
* *
|
||||
* $Author:: Greg_h $*
|
||||
* *
|
||||
* $Modtime:: 4/04/01 10:14a $*
|
||||
* *
|
||||
* $Revision:: 2 $*
|
||||
* *
|
||||
*---------------------------------------------------------------------------------------------*
|
||||
* Functions: *
|
||||
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
|
||||
|
||||
#include "bwrender.h"
|
||||
#include "vp.h"
|
||||
#include <string.h>
|
||||
|
||||
|
||||
BWRenderClass::Buffer::Buffer(unsigned char* buffer_, int scale_)
|
||||
:
|
||||
buffer(buffer_),
|
||||
scale(scale_),
|
||||
minv(3),
|
||||
maxv(scale_-3)
|
||||
{
|
||||
}
|
||||
|
||||
BWRenderClass::Buffer::~Buffer()
|
||||
{
|
||||
}
|
||||
|
||||
void BWRenderClass::Buffer::Set_H_Line(int start_x, int end_x, int y)
|
||||
{
|
||||
if (y<minv || y>=maxv || end_x<minv || start_x>=maxv) return;
|
||||
if (start_x<minv) start_x=minv;
|
||||
if (end_x>=maxv) end_x=maxv-1;
|
||||
unsigned char* ptr=buffer+scale*y+start_x;
|
||||
int w=end_x-start_x;
|
||||
if (w) {
|
||||
::memset(ptr,0x00,w);
|
||||
|
||||
/* // Blurring (test)
|
||||
*(ptr-1)&=0x80;
|
||||
*(ptr-2)&=0xc0;
|
||||
*(ptr+w)&=0x80;
|
||||
*(ptr+w+1)&=0xc0;
|
||||
for (int a=0;a<w;++a) {
|
||||
*(ptr-scale+a)&=0xc0;
|
||||
*(ptr+scale+a)&=0xc0;
|
||||
}
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
||||
void BWRenderClass::Buffer::Fill(unsigned char c)
|
||||
{
|
||||
memset(buffer,c,scale*scale);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------
|
||||
|
||||
BWRenderClass::BWRenderClass(unsigned char* buffer, int buffer_scale)
|
||||
:
|
||||
pixel_buffer(buffer,buffer_scale)
|
||||
{
|
||||
}
|
||||
|
||||
BWRenderClass::~BWRenderClass()
|
||||
{
|
||||
}
|
||||
|
||||
void BWRenderClass::Fill(unsigned char c)
|
||||
{
|
||||
pixel_buffer.Fill(c);
|
||||
}
|
||||
|
||||
// Sets the vertex coordinate buffer location and scales the vertex locations to the kjkj
|
||||
void BWRenderClass::Set_Vertex_Locations(Vector2* vertices_,int count)
|
||||
{
|
||||
vertices=vertices_;
|
||||
|
||||
float half_scale=pixel_buffer.Scale()*0.5f;
|
||||
VectorProcessorClass::MulAdd(
|
||||
reinterpret_cast<float*>(vertices),
|
||||
half_scale,
|
||||
half_scale,
|
||||
count*2);
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
static inline bool Cull(
|
||||
const Vector2& c1,
|
||||
const Vector2& c2,
|
||||
const Vector2& c3)
|
||||
{
|
||||
float x1=c2[0]-c1[0];
|
||||
float y1=c2[1]-c1[1];
|
||||
float x2=c3[0]-c1[0];
|
||||
float y2=c3[1]-c1[1];
|
||||
float r=x1*y2-x2*y1;
|
||||
if (r<0) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
void BWRenderClass::Render_Triangle_Strip(const unsigned long* indices,int index_count)
|
||||
{
|
||||
index_count-=2;
|
||||
bool b=false;
|
||||
for (int n=0;n<index_count;++n) {
|
||||
b=!b;
|
||||
int idx_1=indices[0];
|
||||
int idx_2=indices[1];
|
||||
int idx_3=indices[2];
|
||||
indices++;
|
||||
|
||||
if (Cull(vertices[idx_1],vertices[idx_2],vertices[idx_3])==b) continue;
|
||||
|
||||
Vector2 corner_1(vertices[idx_1][0],vertices[idx_1][1]);
|
||||
Vector2 corner_2(vertices[idx_2][0],vertices[idx_2][1]);
|
||||
Vector2 corner_3(vertices[idx_3][0],vertices[idx_3][1]);
|
||||
|
||||
// Sort the corners on y axis
|
||||
|
||||
if (corner_2[1]<corner_1[1]) Swap(corner_1,corner_2);
|
||||
if (corner_3[1]<corner_1[1]) Swap(corner_1,corner_3);
|
||||
if (corner_3[1]<corner_2[1]) Swap(corner_2,corner_3);
|
||||
|
||||
Vector3i yci(WWMath::Float_To_Long(corner_1[1]),WWMath::Float_To_Long(corner_2[1]),WWMath::Float_To_Long(corner_3[1]));
|
||||
Vector3 xcf(corner_1[0],corner_2[0],corner_3[0]);
|
||||
|
||||
Render_Preprocessed_Triangle(xcf,yci);
|
||||
}
|
||||
}
|
||||
|
||||
void BWRenderClass::Render_Triangles(const unsigned long* indices,int index_count)
|
||||
{
|
||||
index_count/=3;
|
||||
for (int n=0;n<index_count;++n) {
|
||||
int idx_1=*indices++;
|
||||
int idx_2=*indices++;
|
||||
int idx_3=*indices++;
|
||||
|
||||
if (Cull(vertices[idx_1],vertices[idx_2],vertices[idx_3])) continue;
|
||||
|
||||
Vector2 corner_1(vertices[idx_1][0],vertices[idx_1][1]);
|
||||
Vector2 corner_2(vertices[idx_2][0],vertices[idx_2][1]);
|
||||
Vector2 corner_3(vertices[idx_3][0],vertices[idx_3][1]);
|
||||
|
||||
// Sort the corners on y axis
|
||||
|
||||
if (corner_2[1]<corner_1[1]) Swap(corner_1,corner_2);
|
||||
if (corner_3[1]<corner_1[1]) Swap(corner_1,corner_3);
|
||||
if (corner_3[1]<corner_2[1]) Swap(corner_2,corner_3);
|
||||
|
||||
Vector3i yci(WWMath::Float_To_Long(corner_1[1]),WWMath::Float_To_Long(corner_2[1]),WWMath::Float_To_Long(corner_3[1]));
|
||||
Vector3 xcf(corner_1[0],corner_2[0],corner_3[0]);
|
||||
|
||||
Render_Preprocessed_Triangle(xcf,yci);
|
||||
}
|
||||
}
|
||||
|
||||
void BWRenderClass::Render_Preprocessed_Triangle(Vector3& xcf,Vector3i& yci)
|
||||
{
|
||||
float x_left=xcf[0];
|
||||
float x_right=x_left;
|
||||
int ycnt=yci[1]-yci[0];
|
||||
int y=yci[0];
|
||||
if (ycnt) {
|
||||
float x_step_1=(xcf[1]-xcf[0])/float(ycnt);
|
||||
float x_step_2=(xcf[2]-xcf[0])/float(yci[2]-y);
|
||||
if (x_step_1>x_step_2) {
|
||||
float t=x_step_1;
|
||||
x_step_1=x_step_2;
|
||||
x_step_2=t;
|
||||
}
|
||||
|
||||
while (ycnt>0) {
|
||||
pixel_buffer.Set_H_Line(WWMath::Float_To_Long(x_left),WWMath::Float_To_Long(x_right),y);
|
||||
|
||||
x_left+=x_step_1;
|
||||
x_right+=x_step_2;
|
||||
ycnt--;
|
||||
y++;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (xcf[0]<xcf[1]) {
|
||||
x_left=xcf[0];
|
||||
x_right=xcf[1];
|
||||
}
|
||||
else {
|
||||
x_right=xcf[0];
|
||||
x_left=xcf[1];
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
ycnt=yci[2]-yci[1];
|
||||
y=yci[1];
|
||||
|
||||
if (ycnt) {
|
||||
float one_per_ycnt=1.0f/float(ycnt);
|
||||
float x_step_1=(xcf[2]-x_left)*one_per_ycnt;
|
||||
float x_step_2=(xcf[2]-x_right)*one_per_ycnt;
|
||||
while (ycnt>0) {
|
||||
pixel_buffer.Set_H_Line(WWMath::Float_To_Long(x_left),WWMath::Float_To_Long(x_right),y);
|
||||
x_left+=x_step_1;
|
||||
x_right+=x_step_2;
|
||||
ycnt--;
|
||||
y++;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user