delorie.com/archives/browse.cgi   search  
Mail Archives: djgpp/1997/12/08/12:35:10

Message-ID: <348B9FF5.4F0F@mailexcite.com>
Date: Mon, 08 Dec 1997 02:21:25 -0500
From: Doug Gale <dgale AT mailexcite DOT com>
Reply-To: dgale AT mailexcite DOT com
MIME-Version: 1.0
Newsgroups: comp.os.msdos.djgpp
Subject: Re: can you help make THIS DJGPP inline asm work...
References: <19971207184901 DOT NAA27726 AT ladder02 DOT news DOT aol DOT com>
NNTP-Posting-Host: oshawappp11.idirect.com
Lines: 158
To: djgpp AT delorie DOT com
DJ-Gateway: from newsgroup comp.os.msdos.djgpp

QBall1723 wrote:
> 
> Hello,
> 
>       I posted something a couple of weeks ago about a C routine I wanted to
> convert to DJGPP inline asm...
> 
>      The code was to render vertical "slivers" generated by a "wolf3D"-type ray
> caster... here's as far as I've gotten:
> 
>      The sliver's are supposed to be textured from the center to the top (or
> bottom respectively) of each strip...
> 
>   ...alas, all I have so far is getting the appropriate COLUMN of the texture
> to be rendered... the actual ROW of the texture is in a triangular array called
> scale_table, with the info for a particular sliver heights "layout" stored in
> scale_row
> (they're int *)....
> 
>      Yes - I'm using precomputed scales here... sort of like mapping out where
> pixels will be selected from in the source bitmap, regardless of which
> "texture" I might have selected to render with...
> 
>      I might be doing the following code ass-backwards, but to me... intel's
> syntax still seems that way ; )
> 
> void Render_Sliver(void)
> {
>      __asm__ __volatile__(
>         "pushl   %esi\n\t"
>         "pushl   %edi\n\t"
>         "pushl   %eax\n\t"
>         "pushl   %ebx\n\t"
>         "pushl   %ecx\n\t"
>         "pushl   %edx\n\t"
>         "pushw   %es\n\t"
>         "pushw   %fs\n\t"
> 
> // get y * 320 + x...
>      "movl $99,%ebx\n\t"
>      "shll $8,%ebx\n\t"
>      "movl %ebx,%eax\n\t"
>      "shrl $2,%ebx\n\t"
>      "addl %eax,%ebx\n\t"
>      "addl _sliver_ray,%ebx\n\t"
> 
>      "movl _double_buffer,%edi\n\t"
>      "addl %ebx,%edi\n\t"
> 
>      "movl _sliver_texture,%esi\n\t"
> 
>      "movl _sliver_column,%edx\n\t" // in these two lines... I really need to
> extract
>      "addl $2048,%edx\n\t"      // an offset from a array called scale_row...
> but I
>                                           // don't know how to do that... as
> I'm already using
>                                           // edi & esi... you may have notice I
> push/pop fs
>                                            // - can I use that???
> 
>      "movl _sliver_scale,%ecx\n\t"
> 
>      // loop 1 (top of sliver)
> "SliverLoop1:\n\t"
>      "movb (%esi,%edx,1),%eax\n\t"
>      "movb %eax,(%edi)\n\t"
>      "subl $320,%edi\n\t"
>      "decl %ecx\n\t"
>      "jnz SliverLoop1\n\t"
> 
> // done with loop.. .I'm setting up again.
> 
> // get y * 320 + x...
>      "movl $99,%ebx\n\t"
>      "shll $8,%ebx\n\t"
>      "movl %ebx,%eax\n\t"
>      "shrl $2,%ebx\n\t"
>      "addl %eax,%ebx\n\t"
>      "addl _sliver_ray,%ebx\n\t"
> 
>      "movl _double_buffer,%edi\n\t"
>      "movl _sliver_texture,%esi\n\t"
>      "addl %ebx,%edi\n\t"
> 
>      "movl _sliver_column,%edx\n\t"
>      "addl $2048,%edx\n\t"
> 
>      "movl _sliver_scale,%ecx\n\t"
> 
> "SliverLoop2:\n\t"
>      "movb (%esi,%edx,1),%eax\n\t"
>      "movb %eax,(%edi)\n\t"
>      "addl $320,%edi\n\t"
>      "decl %ecx\n\t"
>      "jnz SliverLoop2\n\t"
> 
>         "popw    %fs\n\t"
>         "popw    %es\n\t"
>      "popl    %edx\n\t"
>         "popl    %ecx\n\t"
>         "popl    %ebx\n\t"
>         "popl    %eax\n\t"
>         "popl    %edi\n\t"
>         "popl    %esi\n\t"
>         );
> 
> } // end Render_Sliver
> 
>        I'd appreciate any tips you can give me on this one...
> 
> Jim the loiterer (wannabe PC game/graphics developer)
> http://members.aol.com/qball1723/index.htm
> [please don't hate me because I pay too much for poor internet service!!]


1) I did see one possible bug. Is double_buffer a pointer like this:

	char *double_buffer;

or a static array like this:

	char double_buffer[320*240];

If it is a static array, you have to use "movl $_double_buffer,%%edi",
because the offset of a static array is a constant.

2) I also recommend that you use pushl %es instead of pushw %es. pushw
generates an unnecessary operand size prefix and takes an extra cycle. 

3) You also could use a lookup table for multiplying by 320.

somewhere declare:
	long ylookup[200];		/* 200 for mode 0x13, 240 for modex, etc. */

Instead of:
> // get y * 320 + x...
>      "movl $99,%ebx\n\t"
>      "shll $8,%ebx\n\t"
>      "movl %ebx,%eax\n\t"
>      "shrl $2,%ebx\n\t"
>      "addl %eax,%ebx\n\t"
>      "addl _sliver_ray,%ebx\n\t"
[whatever THAT is supposed to do (99 << 8 + ebx / 4 + sliver_ray ??????)
:)]

you could:
	movl <y>,%eax			/* eax = ylookup[y] + x */
	movl _ylookup(,%eax,4),%eax
	addl <x>, %%eax

replace <y> and <x> with register/variable that they are stored in

fill ylookup[] with 0, 80, 160, etc... for modex or 0, 320, 640, etc...
for mode 0x13  for REALLY quick multiply.

I could not understand your question about "extracting an offset from
scale_row" so I can't really help you on this one.

- Raw text -


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