MuckyFoot-UrbanChaos/MuckyBasic/ll.cpp
2017-05-20 11:14:17 +10:00

406 lines
5.2 KiB
C++

//
// An interface between the low level D3D drawing and
// the virtual machine.
//
#include "always.h"
#include "ll.h"
#include "mem.h"
#include "os.h"
//
// All the textures.
//
#define LL_MAX_TEXTURES 4096
LL_Texture *LL_texture[LL_MAX_TEXTURES];
//
// All the sounds.
//
#define LL_MAX_SOUNDS 4096
LL_Sound *LL_sound[LL_MAX_SOUNDS];
LL_Texture *LL_create_texture(CBYTE *fname)
{
SLONG i;
//
// Create the OS texture.
//
OS_Texture *ot = OS_texture_create(fname);
//
// Do we already have this texture?
//
for (i = 0; i < LL_MAX_TEXTURES; i++)
{
if (LL_texture[i] && LL_texture[i]->ot == ot)
{
//
// We already have this texture!
//
LL_texture[i]->ref_count += 1;
return LL_texture[i];
}
}
//
// Create a new texture.
//
LL_Texture *lt;
lt = (LL_Texture *) MEM_alloc(sizeof(LL_Texture));
lt->ot = ot;
lt->width = OS_texture_width (ot);
lt->height = OS_texture_height(ot);
lt->ref_count = 1;
//
// Add it to our list of textures.
//
for (i = 0; i < LL_MAX_TEXTURES; i++)
{
if (LL_texture[i] == NULL)
{
LL_texture[i] = lt;
return lt;
}
}
//
// No more textures!
//
ASSERT(0);
return NULL;
}
void LL_free_texture(LL_Texture *lt)
{
//
// Free everything! We can't free OS_Textures!
//
MEM_free(lt);
//
// Get rid of the reference in the LL_texture[] array.
//
SLONG i;
for (i = 0; i < LL_MAX_TEXTURES; i++)
{
if (LL_texture[i] == lt)
{
LL_texture[i] = NULL;
return;
}
}
ASSERT(0);
}
LL_Sound *LL_create_sound(CBYTE *fname)
{
SLONG i;
//
// Create the OS sound.
//
OS_Sound *os = OS_sound_create(fname, OS_SOUND_TYPE_2D);
//
// Do we already have this sound?
//
for (i = 0; i < LL_MAX_SOUNDS; i++)
{
if (LL_sound[i] && LL_sound[i]->os == os)
{
//
// We already have this sound!
//
LL_sound[i]->ref_count += 1;
return LL_sound[i];
}
}
//
// Create a new sound.
//
LL_Sound *ls;
ls = (LL_Sound *) MEM_alloc(sizeof(LL_Sound));
ls->os = os;
ls->ref_count = 1;
//
// Add it to our list of sounds.
//
for (i = 0; i < LL_MAX_SOUNDS; i++)
{
if (LL_sound[i] == NULL)
{
LL_sound[i] = ls;
return ls;
}
}
//
// No more sounds!
//
ASSERT(0);
return NULL;
}
void LL_free_sound(LL_Sound *ls)
{
//
// Free everything! We can't free OS_Sounds!
//
MEM_free(ls);
//
// Get rid of the reference in the LL_sound[] array.
//
SLONG i;
for (i = 0; i < LL_MAX_SOUNDS; i++)
{
if (LL_sound[i] == ls)
{
LL_sound[i] = NULL;
return;
}
}
ASSERT(0);
}
LL_Buffer *LL_create_buffer(
SLONG type,
void *vert,
SLONG num_verts,
UWORD *index,
SLONG num_indices)
{
ASSERT(
type == LL_BUFFER_TYPE_TLV ||
type == LL_BUFFER_TYPE_LV);
//
// Create a new buffer.
//
LL_Buffer *lb = (LL_Buffer *) MEM_alloc(sizeof(LL_Buffer));
lb->type = type;
lb->vert_data = vert;
lb->index = index;
lb->num_verts = num_verts;
lb->num_indices = num_indices;
lb->ref_count = 1;
return lb;
}
void LL_free_buffer(LL_Buffer *lb)
{
//
// Free up data.
//
MEM_free(lb->vert);
if (lb->index)
{
MEM_free(lb->index);
}
//
// Now free up the actual buffer.
//
MEM_free(lb);
}
//
// Draws a buffer
//
OS_Vert LL_vert[OS_MAX_TRANS];
void LL_draw_buffer(
LL_Buffer *lb,
LL_Texture *lt, // NULL => Draw untextured
ULONG rs) // The LL_RS_* renderstates ORed together.
{
SLONG i;
OS_Buffer *ob;
OS_Trans *ot;
OS_Vert *ov;
LL_Tlvert *tl;
ob = OS_buffer_new();
//
// Are there too many points in this buffer?
//
ASSERT(lb->num_verts <= OS_MAX_TRANS);
//
// Build the OS_trans and OS_vert buffers.
//
switch(lb->type)
{
case LL_BUFFER_TYPE_TLV:
//
// These are already transformed, so we can write
// directly into the OS_trans[] array.
//
for (i = 0; i < lb->num_verts; i++)
{
ot = &OS_trans [i];
ov = &LL_vert [i];
tl = &lb->vert_tl[i];
ot->X = tl->x;
ot->Y = tl->y;
ot->Z = tl->rhw;
ot->z = tl->z;
ot->clip = OS_CLIP_TRANSFORMED;
ov->trans = i;
ov->index = 0;
ov->colour = tl->colour;
ov->specular = tl->specular;
ov->u1 = tl->u;
ov->v1 = tl->v;
ov->u2 = 0.0F;
ov->v2 = 0.0F;
}
if (lb->index)
{
ASSERT(lb->num_indices % 3 == 0);
for (i = 0; i < lb->num_indices; i += 3)
{
OS_buffer_add_triangle(
ob,
&LL_vert[lb->index[i + 0]],
&LL_vert[lb->index[i + 1]],
&LL_vert[lb->index[i + 2]]);
}
}
else
{
for (i = 0; i < lb->num_verts; i += 3)
{
OS_buffer_add_triangle(
ob,
&LL_vert[i + 0],
&LL_vert[i + 1],
&LL_vert[i + 2]);
}
}
break;
default:
ASSERT(0);
break;
}
//
// Now draw the buffer.
//
OS_buffer_draw(ob, (lt) ? lt->ot : NULL, NULL, rs | OS_DRAW_DOUBLESIDED | OS_DRAW_ZALWAYS | OS_DRAW_NOZWRITE);
}
void LL_cls(ULONG colour, float z)
{
SLONG r = (colour >> 16) & 0xff;
SLONG g = (colour >> 8) & 0xff;
SLONG b = (colour >> 0) & 0xff;
ASSERT(WITHIN(z, 0.0F, 1.0F));
OS_clear_screen(r,g,b,z);
}
void LL_flip()
{
OS_show();
}