delorie.com/archives/browse.cgi   search  
Mail Archives: djgpp/1997/11/13/15:30:59

From: qball1723 AT aol DOT com (QBall1723)
Newsgroups: comp.os.msdos.djgpp
Subject: djgpp inline anyone?
Date: 13 Nov 1997 18:45:17 GMT
Lines: 259
Message-ID: <19971113184501.NAA20365@ladder02.news.aol.com>
NNTP-Posting-Host: ladder02.news.aol.com
Organization: AOL http://www.aol.com
To: djgpp AT delorie DOT com
DJ-Gateway: from newsgroup comp.os.msdos.djgpp

Hello All,

    I've been tinkering with DJGPP2 lately... and I'd like to see
the thread that ensues, when you folks start ripping into this with
DJGPP's inline assembly.... I'd really like to convert it - and I've 
already seen the thread that began when someone asked how to clear
a 320x400x256 (a.k.a Mode Z) page QUICKLY!

    The code that follows is part of the "sliver engine" a ray caster
I made uses...
   - it started out as 16-bit (C for windows - circa 1990 actually)
C code...

  ...some of you might not like the fact I use scale tables... but alas
the examples I learned from that attained ANY kind of speed used this...

    I'm going to include some of the declarations from outside the
function I'd like to see optimized into 32-bit DJGPP inline asm, and
also the allocation & initialization of the scale table itself

    Here goes:

***************************

          a few globals

***************************

int *scale_table[MAX_SCALE+1];     // table with pre-computed scale indices

// parmeter block used by assembly language sliver engine

char *sliver_texture; // pointer to texture being rendered
int sliver_column;        // index into texture i.e. which column of texture
int sliver_top;           // starting Y position to render at
int sliver_bottom;
int sliver_scale;         // overall height of sliver
int sliver_ray;           // current ray being cast
int sliver_clip;(not used)// index into texture after clipping
int *scale_row;           // row of scale value look up table to use


****************************

      THE FUNCTION I'D LIKE TO OPTIMIZE - in the case of my program,
  you know going in the:
           sliver_texture  - some 64x64 sprite
           sliver_column - the column of the sprite that will be 
      used to texture a vertical "sliver",
           sliver_top, sliver_bottom, sliver_scale, 
           sliver_ray (which column of the screen is to be rendered)
        and scale_row

******************************

void Render_Sliver(void)
{
	// this is yet another version of the sliver scaler, however it uses look up
	// tables with pre-computed scale indices.

	// this draws vertical slivers fromthe middle of the strip to the top,
	// and fromthe middle of the strip to the bottom.

	char *work_sprite;
	int *row;
   char *draw_from;
	int work_offset=0,offset,temp_offset,y_off,scale_off;

	// alias a pointer to sprite for ease of access

	work_sprite = sliver_texture;

	// compute offset of sprite in video buffer

	temp_offset = v_320[99] + sliver_ray;

	// render top half of wall sliver

	offset = temp_offset;

   draw_from = double_buffer + offset;

	work_offset = WALL_MIDDLE_OFFSET;

	*draw_from = work_sprite[work_offset+sliver_column];

	for (y_off=1; y_off<sliver_scale; y_off++)
    {

	    draw_from      -= 320;
	    work_offset =  WALL_MIDDLE_OFFSET - scale_row[y_off];

	    *draw_from = work_sprite[work_offset+sliver_column];

    } // end for y

	// render bottomhalf of wall sliver

	offset = temp_offset + 320;

   draw_from = double_buffer + offset;

	work_offset = WALL_MIDDLE_OFFSET;

	*draw_from = work_sprite[work_offset+sliver_column];

	for (y_off=0; y_off<(sliver_scale); y_off++)
    {


	    draw_from      += 320;
	    work_offset =  WALL_MIDDLE_OFFSET + scale_row[y_off];

	    *draw_from = work_sprite[work_offset+sliver_column];
    } // end for y

} // end Render_Sliver

**************************

      ALLOCATION OF scale_table

*************************

// create the lookup tables for the scaler
// there have the formof an array of pointers, where each pointer points
// another another array of data where the 'data' are the scale indices

	for (scale=0; scale<=100; scale++)
    {

    scale_table[scale] = (int *)malloc(scale*sizeof(int)+1);

    } // end for scale
	for (scale=101; scale<=MAX_SCALE; scale++)
    {

    scale_table[scale] = (int *)malloc((101)*sizeof(int)+1);

    } // end for scale

	// create tables, sit back for a sec!

	for (ang=ANGLE_0; ang<=ANGLE_360; ang++)
    {

// build the scaler table.  This table holds MAX_SCALE different arrays.  Each
// array consists of the pre-computed indices for an object to be scaled

	for (scale=1; scale<=99; scale++)
    {

	    // create the indices for this scale

	    Create_Scale_Data(scale, (int *)scale_table[scale]);

    } // end for scale

    // THE SECOND Create_Scale_Data FUNCTION REFERED TO HERE IS USED
    // TO COMPUTE SCALES FOR CASES WHERE THE BOTTOmAND THE TOP OF A WALL
    // SLIVER ARE BEYOND THE VERTICAL EXTENTS OF THE VIEWPORT!

	for (scale=99+1; scale<=MAX_SCALE; scale++)
    {

	    // create the indices for this scale

	    Create_Scale_Data2(scale, (int *)scale_table[scale]);

    } // end for scale

***********************

    INITIALIZATION OF scale_table

***********************

void Create_Scale_Data(int scaler, int *row)
{

// this function synthesizes the scaling of a texture sliver to all possible
// sizes and creates a huge look up table of the data.

int y_off;

float y_scale_index=0,
      y_scale_step;

// compute scale step or number of source pixels to map to destination/cycle

y_scale_step = (float)32/(float)scaler;

y_scale_index+=y_scale_step;

for (y_off=0; y_off<scaler; y_off++)
    {
    // place data into proper array position for later use

    row[y_off] = ((int)(y_scale_index+.4)) * SWATCH_WIDTH;

    // test if we slightly went overboard

    if  (row[y_off] > WALL_MIDDLE_OFFSET) row[y_off] = WALL_MIDDLE_OFFSET;

    // next index please

    y_scale_index+=y_scale_step;

    } // end for y_off

} // end Create_Scale_Data

void Create_Scale_Data2(int scaler, int *row)
{

// this function synthesizes the scaling of a texture sliver to all possible
// sizes and creates a huge look up table of the data.

// this adds data for cases where the vertical extents of the "sliver" are
// beyond the vertical extents of the viewport

int y_off;

float y_scale_index=0,
      y_scale_step;

// compute scale step or number of source pixels to map to destination/cycle

y_scale_step = (float)32/(float)scaler;

y_scale_index+=y_scale_step;

for (y_off=0; y_off<99+1; y_off++)
    {
    // place data into proper array position for later use

    row[y_off] = ((int)(y_scale_index+.3)) * SWATCH_WIDTH;

    // test if we slightly went overboard

    if  (row[y_off] > WALL_MIDDLE_OFFSET) row[y_off] = WALL_MIDDLE_OFFSET;

    // next index please

    y_scale_index+=y_scale_step;

    } // end for y_off

} // end Create_Scale_Data2

*********************************

    Again... Thank you for taking the time to look over my
hack-kneed code!


Jim the loiterer
http://members.aol.com/qball1723/index.htm
(I make games)

- Raw text -


  webmaster     delorie software   privacy  
  Copyright © 2019   by DJ Delorie     Updated Jul 2019