Omnimaga

Calculator Community => TI Calculators => ASM => Topic started by: ben_g on June 13, 2011, 04:29:29 pm

Title: Texture drawing
Post by: ben_g on June 13, 2011, 04:29:29 pm
Does anybody knows how to draw repeated textures? It would help a lot at my 3D engine, which now can only render wireframe.

I only need to know how it's done, so I can write my own routine.

What I mean with textures: this is a wire frame rectangle rendered by my 3D Engine:
(http://209.85.48.18/7059/133/0/p1019677/Animated_Screenshot.gif)
I want to draw a sprite between those 4 points. Could someone explain the principle behind this please?
Title: Re: Texture drawing
Post by: thepenguin77 on June 13, 2011, 05:35:20 pm
There's only one person I can think of that has ever done that, he made Gemini (http://www.ticalc.org/archives/files/fileinfo/247/24743.html). Looking through the source of that, you could probably figure out how he did it.

At the moment, I can think of some ways to do it, but I'm not sure they would be fast.
Title: Re: Texture drawing
Post by: Runer112 on June 13, 2011, 06:59:02 pm
Well Gemini was a raycaster, not a "real" 3D engine. Which I believe is what ben_g wants. Applying textures in raycasting is easy because of the vertical scanline rendering method and the restrictions of the camera.
Title: Re: Texture drawing
Post by: leafy on June 13, 2011, 06:59:59 pm
So is this just a horizontal engine? No looking up or down?
Title: Re: Texture drawing
Post by: DJ Omnimaga on June 13, 2011, 08:10:42 pm
Hmm I haven't seen any 3d polygon game with textures on calculators yet. I wonder if it would achieve sustainable speed like in Runer112's raycaster?
Title: Re: Texture drawing
Post by: leafy on June 13, 2011, 08:12:29 pm
Look for wolfenstein castle.

EDIT: http://www.ticalc.org/archives/files/fileinfo/277/27767.html

Hella awesome.
Title: Re: Texture drawing
Post by: DJ Omnimaga on June 13, 2011, 08:16:37 pm
That's a raycaster too actually, like Gemini.
Title: Re: Texture drawing
Post by: leafy on June 13, 2011, 08:18:17 pm
Oh you said polygon. Never mind.
Title: Re: Texture drawing
Post by: Builderboy on June 14, 2011, 02:25:37 am
The only project I have ever seen that used linear interpolation across polygons was a space shooter thingy from maxcoders but it was limited, and that was in asm.  The method used is called linear interpolation, and I have a really good website that explains it, but it's on my other computer, so i will have to post it later.  Let me say though, that this is not an easy task, and even the most optimized engines will take lots of memory and barely be able to handle too many polygons.
Title: Re: Texture drawing
Post by: ben_g on June 14, 2011, 07:27:37 am
Well Gemini was a raycaster, not a "real" 3D engine. Which I believe is what ben_g wants. Applying textures in raycasting is easy because of the vertical scanline rendering method and the restrictions of the camera.
Yes, It's a "real" 3D engine, and it supports both vertical and horizontal rotation, as well as letting the camera rotate along it's axis using the up vector. There's no way to use routines from raycasters for this. I've already checked gemini, and it renders by casting rays, not by calculating the location of points and drawing a texture between them.

btw: what would be the easyest? Drawing a texture on the quad or drawing a quad as two textured triangles? (Triangles are used with 3D on a computer, But I don't know which is the fastest)
Title: Re: Texture drawing
Post by: Hayleia on June 14, 2011, 07:32:50 am
[offtopic] Congrats ben_g: 100th post !
Title: Re: Texture drawing
Post by: thepenguin77 on June 14, 2011, 11:09:41 am
Ok, here is my method. I'm literally making it up as I write this post, but in the end it should work. For this you should use triangles.

1. Convert the 3 corners to xy coordinates.
2. Calculate the relative size of the leftmost point. (3d window distance thing / distance)
3. Now calculate the relative size of each of the other two points and subtract the original from them.
4. (This is where it gets sketchy) You need to figure out the two slopes of (relative distance) / x = a and (relative distance) / y = b. Right now you have two equations: d1 = ax1 + bx1 and d2 = ax2 + bx2. So you need to solve those for a and b. I would divide the first equation by x1, then subtract the the second equation from the first. the ax's will cancel and you can get b. Then just substitute b and get a.
5. Now to apply the texture, we have to base the texture somewhere, so you should probably put the leftmost point on the left side of the texture dead centered vertically.
6. To calculate the pixel in the texture to use for a screen coordinate, here is what you do. X = (1 / (screenOffsetX * a + relativeSizeOfLeft) * screenOffsetX / totalXWidth * textureWidth) and Y is the same.
7. Then, take that pixel out of the texture and put it on the screen.

As far as I can tell, that should work. I'm sure if you actually do it, you'll find lots of optimizations. For instance, the reciprocal I forgot about at the end could probably be calculated earlier.
Title: Re: Texture drawing
Post by: ben_g on June 14, 2011, 01:33:14 pm
Ok, here is my method. I'm literally making it up as I write this post, but in the end it should work. For this you should use triangles.
...
2. Calculate the relative size of the leftmost point. (3d window distance thing / distance)
3. Now calculate the relative size of each of the other two points and subtract the original from them.
...
Could you please explain what you mean by the size of a point?

[offtopic] Congrats ben_g: 100th post !
Thanks. 100 post sure goes by fast. I didn't knew I was already there :P
Title: Re: Texture drawing
Post by: thepenguin77 on June 14, 2011, 01:55:25 pm
Ok, you can use this page (http://www.permadi.com/tutorial/raycast/rayc5.html) and this page (http://www.permadi.com/tutorial/raycast/rayc9.html) for pictures.

What you are trying to do is to figure out how tall the wall should be on the actual screen. The concept we are using here is that an object that is twice as far from you will look half the size. So we can see that the equation would be size = k/distance. Now the question is of course, what is k.

K is the distance to the projection screen. The way you calculate this, you can see in that first link I gave you. It is (screenWidth / 2) / tan(fieldOfView / 2). So assuming you are using a 60 degree field of view on the calculator. 48/tan(30) = 83.

Now go to the second link. What this means, is that a wall on screen that is 83 units away, will be it's actual size. 166 units away it will be half its size, 41.5 units away it will be double size.

So the formula is now (relative size) = 83/distance. Which means if your sprite is supposed to be 50 pixels tall, when it is 120 units away, it will be 83/120 * 50 = 34.5 pixels tall.
Title: Re: Texture drawing
Post by: ben_g on June 14, 2011, 02:17:33 pm
Isn't it much easier to calculate how tall the wall is by calculating the distance between the upper point and the lower point? I already convert points from 3D to 2D, so won't it be faster when the textures are calculated to just fit between those points? Triangles have more possibilities, so I think triangles are the best choice, but if I can calculate the slope and size of all 3 sides, isn't that enough to apply a texture?
Title: Re: Texture drawing
Post by: thepenguin77 on June 14, 2011, 02:29:53 pm
You can only check between the upper and lower points if in the virtual world, from where you are standing, they are one above another. But imagine you are standing at the bottom corner of a wall looking at the other corner of a wall. Now the points probably won't even be on the same X value. Although in reality, that formula is not about finding how tall the wall is, it's about figuring out what the scale factor you need to multiply your texture by.

And textures, I think this is where the misunderstanding is. If you simply draw a bounding box on the screen and fill it with a texture, yes, the wall will have a texture. But the texture won't change when the wall does. You could stand 2 feet from the wall, or 200 feet from the wall, and the texture would always be the same size. If the texture was a brick wall, at 200 feet away, the entire wall might just be a single brick. You have to scale the texture down so that as the wall gets smaller, the texture does too.

This same thing applies if you are looking at the wall from a weird angle, if you are doing what I said earlier, looking from the bottom corner to the top corner, obviously, the bricks closer to you will be bigger than the bricks farther away from you, and for this you need texture scaling.

Here is a simple game I made a while back using this concept. You can see that the wall gets closer, you have to scale the sprite up, otherwise, it wouldn't appear to get any closer.
Title: Re: Texture drawing
Post by: jnesselr on June 14, 2011, 03:34:05 pm
Do you have any axe code or something to demonstrate this principle? Maybe pretty pictures so my mind can understand it?
Title: Re: Texture drawing
Post by: ben_g on June 14, 2011, 03:38:19 pm
He gave pictures in his previous post.
Title: Re: Texture drawing
Post by: Builderboy on June 14, 2011, 03:52:28 pm
Here is the website I was talking about earlier, it works completely of the screen coordinates of the triangle, and uses a method called linear interpolation.  It also works in scanlines, which is beneficial to us calculator users since scanlines are special for our screen and can be drawn rather quickly. 

http://www-users.mat.uni.torun.pl/~wrona/3d_tutor/tri_fillers.html
Title: Re: Texture drawing
Post by: ben_g on June 14, 2011, 03:54:15 pm
Here is the website I was talking about earlier, it works completely of the screen coordinates of the triangle, and uses a method called linear interpolation.  It also works in scanlines, which is beneficial to us calculator users since scanlines are special for our screen and can be drawn rather quickly. 

http://www-users.mat.uni.torun.pl/~wrona/3d_tutor/tri_fillers.html
Are you sure that's the right URL? I got the 'server not found' error
Title: Re: Texture drawing
Post by: Builderboy on June 14, 2011, 03:56:41 pm
it works for me o.O

I've uploaded the file itself just in case

EDIT: Aw it didn't save the images :/
Title: Re: Texture drawing
Post by: ben_g on June 14, 2011, 04:04:20 pm
Yes, now it works.

Thanks, this is really useful. I'll save that link, and this will be the first thing I'm going to code tomorrow. Today, I haven't got enough time left.
Title: Re: Texture drawing
Post by: ben_g on June 15, 2011, 03:47:36 pm
I've already tried the solid triangle code on my computer. Works perfectely

Now I'l try the textured triangle
Title: Re: Texture drawing
Post by: aeTIos on June 16, 2011, 07:54:25 am
Congrats on that. Could you post screenies when you finish the tex draw routine?
Title: Re: Texture drawing
Post by: calc84maniac on June 16, 2011, 10:15:06 am
Also a good read: http://en.wikipedia.org/wiki/Texture_mapping#Perspective_correctness (http://en.wikipedia.org/wiki/Texture_mapping#Perspective_correctness)
Title: Re: Texture drawing
Post by: aeTIos on June 16, 2011, 10:15:30 am
Also, that raycasting tutorial is great.
Title: Re: Texture drawing
Post by: ben_g on June 16, 2011, 02:58:27 pm
Congrats on that. Could you post screenies when you finish the tex draw routine?
Sure, but right now, I'm still trying to do it in a computer language. It's so much easier to first try it in a programming language you know, and then port it.

EDIT:I think I need some help with the textures: They just aren't being mapped correctly:
(http://picturestack.com/254/685/GQYtexturen67R.png)
the texture itself is drawn at the right. The part that's inside the white triangle should be projected onto the triangle, while my code just pushed the whole texture in the triangle.
Title: Re: Texture drawing
Post by: ben_g on June 17, 2011, 01:51:03 pm
bad news: I think I'm going to stop with textures:I just can't get it right on my computer, and i noticed this:
Quote
Note! I find it hard to get good results using fixed point math because of inadequate precision
But that's not the main problem. The main problem is that I think that it would be way to slow. The normal triangle is fast enough, but on my computer, with 2.8GHz CPU, It takes over 5 secounds to draw the textured triangle. I know that game maker is very slow, but i don't think it's speed can be beaten by a calculator. A game just won't be fun when you have to wait for half an hour for each frame.

I think I'm going to make a 3D engine with solid faces, no textures. Unless somebody here knows how to beat the speed of a computer with a calc. (or is GM just way to slow to compare it to?)
Title: Re: Texture drawing
Post by: aeTIos on June 17, 2011, 01:53:41 pm
lol, you're right. Too bad.
Title: Re: Texture drawing
Post by: ben_g on June 17, 2011, 02:33:23 pm
this can be caused by 2 different things: the algorithm is very inefissient, or Game Maker is very bad at drawing. There should be some way to efficiently draw triangles

btw: I just tested GM's drawing speed, and it turns out that drawing points with gm is really slow. Could there still be a chance that this is possible? I mean: OpenGL can render over a milion textured triangles with over 2000 fps. But openGL uses the graphics card, and a calculator hasn't got a good graphics card. Is there a chance that i could get reasonable speeds with this, or should i just give up?
Title: Re: Texture drawing
Post by: leafy on June 17, 2011, 02:39:15 pm
Don't give up; I'm pretty sure you can find a way. GM is really inefficient from when I used it. If you use low-res textures you might be able to pull it off on calc.
Title: Re: Texture drawing
Post by: ben_g on June 17, 2011, 02:46:57 pm
Don't give up; I'm pretty sure you can find a way. GM is really inefficient from when I used it. If you use low-res textures you might be able to pull it off on calc.
I know. GM is really inefficient with almost everything it can do, but 5 seconds for only one triangle is a very long time, even for GM. And for a resonable gameplay, there should be at least 5 fps, and that while there wil be abouth 150 triangles be drawn. that means that it should be abouth 1000 times as fast as GM (I calculated it), so i really doubt that this is possible.
Title: Re: Texture drawing
Post by: Builderboy on June 17, 2011, 10:14:21 pm
First I think you should see if you can draw 150 solid triangles at 5FPS, and after you get that working you can start on textures :) That way you gain experience and can work better on textures ^^
Title: Re: Texture drawing
Post by: thepenguin77 on June 17, 2011, 11:16:13 pm
Well, to give you an upperbound of what is possible on the calculator. I made this:
(http://img.removedfromgame.com/imgs/starfox best.gif)
I got this running with about 20 polygons per frame at 15 fps. That's 300 polygons per second. Now, it wasn't full screen, but it was in grayscale, so we can probably call that an even trade and say I would have gotten 300 polygons per second full screen in black and white.


You want to go for textured polygons, I would imagine that textured polygons take around 4 times as long, (complete guess), so you could probably pull off 75 polygons per second with well optimized code. At that rate, you would be getting 15 polygons at 5 fps. Of course to get this though, you're going to have to make some seriously optimized texturing routines, but I bet you could do it.

But, what I am trying to say is that polygon rendering on the calculator is totally possible, so don't give up.
Title: Re: Texture drawing
Post by: ben_g on June 18, 2011, 03:10:31 pm
whoa, that looks really good. Is it raycasting, mode-7 or 'real' 3D?

back on topic:
how can i calculate the fps? When i try to optimise it, i would like to know if it has any effect.

Anyway, i really think i'm going to give up with textured triangles, and try textured quads instead. This should make it faster as quads can be fully done in 2D, so perspective correction won't be necessary.
Title: Re: Texture drawing
Post by: AngelFish on June 18, 2011, 03:21:08 pm
Either Calc84 or Runer presented a tilemapping 3d engine while back that had simple textures. I can't seem to find the screenshots, though.
Title: Re: Texture drawing
Post by: ben_g on June 18, 2011, 03:22:54 pm
has it got a routine to draw a textured quad?
Title: Re: Texture drawing
Post by: fb39ca4 on June 18, 2011, 03:32:28 pm
You can just use two triangles for that, but I guess a dedicated routine could be more optimized.
Title: Re: Texture drawing
Post by: AngelFish on June 18, 2011, 03:44:46 pm
has it got a routine to draw a textured quad?

I'm not sure why you would want to draw quads as well, since having more than one routine is going to slow down your code.
Title: Re: Texture drawing
Post by: ben_g on June 21, 2011, 01:57:42 pm
i'm not going to do it as well, I'm going to do a quad instaed of two triangles, becouse i think it would be faster
Title: Re: Texture drawing
Post by: ztrumpet on June 21, 2011, 02:08:28 pm
Either Calc84 or Runer presented a tilemapping 3d engine while back that had simple textures. I can't seem to find the screenshots, though.
I believe you're referencing this: http://ourl.ca/8272

Edit: Most recent screenies: http://ourl.ca/8272/154635
Title: Re: Texture drawing
Post by: ben_g on June 26, 2011, 04:03:22 pm
This is the best i could make it do. Could somebody please check out the code and tell me what I'm doing wrong?
(http://picturestack.com/117/903/iy7UntitledWN5.png)
Spoiler For code:
//////////////////////////////////////////////////////////
//Texture triangle

draw_sprite(sprite0,1,450,0)
//draw_sprite(sprite0,1,450,100)


A_x=200
A_y=0
A_u=0
A_v=0
B_x=400
B_y=100
B_u=0
B_v=100
C_x=300
C_y=200
C_u=100
C_v=100



var i;
 if (B_y-A_y > 0) dx1=(B_x-A_x)/(B_y-A_y) else dx1=0;
if (C_y-A_y > 0) dx2=(C_x-A_x)/(C_y-A_y) else dx2=0;
if (C_y-B_y > 0) dx3=(C_x-B_x)/(C_y-B_y) else dx3=0;

   du2=(B_u-A_u)/(B_y-A_y)
   du1=(C_u-A_u)/(C_y-A_y)
   dv2=(B_v-A_v)/(B_y-A_y)
   dv1=(C_v-A_v)/(C_y-A_y)
   du3=(C_u-B_u)/(C_y-B_y)
   dv3=(C_v-B_v)/(C_y-B_y)


     
 E_x=A_x
 E_y=A_y
 S_x=E_x
 S_y=E_y
 E_u=A_u
 E_v=A_v
 S_u=E_u
 S_v=E_v
 
if(dx1 > dx2) {
   S_u=A_u
   S_v=A_v
   E_u=A_u
   E_v=A_v
while(S_y<=B_y){
   S_y+=1
   E_y+=1
   S_x+=dx2
   E_x+=dx1
   S_u+=du1
   S_v+=dv1
   E_u+=du2
   E_v+=dv2
   //draw_line(S_x,S_y,E_x,S_y)
//   du=(E_u-S_u)/(E_x-S_x)
//   dv=(E_v-S_v)/(E_x-S_x)
//   P_u=S_u
//   P_v=S_v
   for(i=S_x;i<=E_x;i+=1){
//   draw_point_color(i,S_y,draw_getpixel(P_u+450,P_v))
//   P_u+=du
//   P_v+=dv
   tmp=(i-S_x)/(E_x-S_x)
   draw_point_color(i,S_y,draw_getpixel(450+((1-tmp)*S_u+tmp*E_u),(1-tmp)*S_v+tmp*E_v))
   }
   }
E_x=B_x
  E_y=B_y
   du3=(C_u-B_u)/(C_y-B_y)
   dv3=(C_v-B_v)/(C_y-B_y)
   E_u=B_u
   E_v=B_v
while(S_y<=C_y){
   S_y+=1
   E_y+=1

//draw_line(S_x,S_y,E_x,S_y)
for(i=S_x;i<=E_x;i+=1){
   tmp=(i-S_x)/(E_x-S_x)
   draw_point_color(i,S_y,draw_getpixel(450+((1-tmp)*S_u+tmp*E_u),(1-tmp)*S_v+tmp*E_v))
   //draw_point_color(i,S_y,c_red)
   }
      S_x+=dx2
   E_x+=dx3
   S_u+=du2
   S_v+=dv2
   E_u+=du3
   E_v+=dv3
}
} else {                                        //Ignore everything behind this for now//////////////////////////////////////////////////////////////////////////////
while(S_y<=B_y){
   S_y+=1
   E_y+=1
   S_x+=dx1
   E_x+=dx2
draw_line(S_x,S_y,E_x,S_y)}
S_x=B_x
  S_y=B_y
 while(S_y<=C_y){
   S_Y+=1
   E_y+=1
   S_x+=dx3


draw_sprite draws the sprite at the given location. Ignore the 2nd argument.
draw_point_color draws a point at the given coordinates with the given color
draw_getpixel returns the color of the given pixel.

Only check the first part of the code (before the else in the middle), becouse that's the part that is run with a triangle with that shape.

Sorry that I'm asking for help again, but i really can't get it right.
Title: Re: Texture drawing
Post by: ben_g on June 27, 2011, 05:54:25 pm
Messing around with the code for a whole day hasn't solved anything, so i decided to bump this topic, hoping for a solution.
Title: Re: Texture drawing
Post by: AngelFish on June 27, 2011, 07:48:55 pm
Take a look at the link ztrumpet posted. Runer actually wrote out his texture code.
Title: Re: Texture drawing
Post by: fb39ca4 on June 27, 2011, 07:53:44 pm
Ummm...that link is to a raycaster, which renders stuff quite differently from a polygon engine.
Title: Re: Texture drawing
Post by: Ashbad on June 27, 2011, 08:23:14 pm
Ummm...that link is to a raycaster, which renders stuff quite differently from a polygon engine.

That's true, but then again doesn't hurt to learn more than one method of doing so, it may help you out when you're trying to figure out other methods.
Title: Re: Texture drawing
Post by: AngelFish on June 27, 2011, 08:49:09 pm
Ummm...that link is to a raycaster, which renders stuff quite differently from a polygon engine.

Depends on the particular polygon engine. In any case, it's example code for handling 3d objects. The only really significant difference between polygons and raycasting is how you detect them. Actually, now that I think about it, BenRyves' Nostromo demo used polygons.
Title: Re: Texture drawing
Post by: ben_g on June 28, 2011, 06:28:53 am
Ummm...that link is to a raycaster, which renders stuff quite differently from a polygon engine.

Depends on the particular polygon engine. In any case, it's example code for handling 3d objects. The only really significant difference between polygons and raycasting is how you detect them. Actually, now that I think about it, BenRyves' Nostromo demo used polygons.
/me googles for Nostromo
Yes, I think that uses polygons, but withouth textures.

And abouth raycasters: I don't know exactely how they work, but if i am correct, raycasters with textures renders by casting a ray for each collum of pixels, calculate the height that the slice should be, then it draws a collum of the texture on the buffer, stretched to the correct height. (correct me if I am wrong)
A polygon based engine works by calculating the 2D coordinates of 3D points, and then drawing something between them. So if what i said abouth raycasters is correct, then code used for texturesin raycasters is useless in polygon based engines becouse those engines render in completely different ways.
Title: Re: Texture drawing
Post by: fb39ca4 on June 28, 2011, 12:19:53 pm
I would look at the source code of a software renderer, as what you are trying to do is just a very simple one of those.
Title: Re: Texture drawing
Post by: ben_g on June 28, 2011, 01:37:04 pm
I tried that, and i only found C code (and I don't understand anything of C) or OpenGL stuff, which uses the graphic card for rendering (and the graphic driver in a calc is way to primitive for that.

I found the asm scource code of a 3D engine with textures, But I think it's made for an other processor and with an assembler with a different syntaxis.

does anybody knows what these instructions could mean?
- mov
- int
- cmp
- jne
- je
- jge
- jmp
- jl
- cdq
- idiv

Spoiler For code:
;ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ»
;º                                                                           º
;º                Polygonfiller for Texturemapped polygons                   º
;º                                                                           º
;º          Draws a Texture-mapped polygon in Tweakedmode (320x200)          º
;º                                                                           º
;º                          Programmed by Fantom                             º
;º                                                                           º
;º                 (c) An Ultimate Brains Production (c)                     º
;º                                                                           º
;º                     Version 2.4 / 17.8.93 / 12.19                         º
;º                                                                           º
;ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ

;                       Texture Mapping
;                       ---------------

;        ÉÍÍÍÍÍÍÍÍÍÍÍÍÍËÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ»
;        º UPPER 16BIT º        LOWER 16BIT        º
;ÉÍÍÍÍÍÍÍÎÍÍÍÍÍÍÍÍÍÍÍÍÍÎÍÍÍÍÍÍÍÍÍÍÍÍÍËÍÍÍÍÍÍÍÍÍÍÍÍ͹  Inner: add ecx,eax
;º  REG  º   HI WORD   º   HI BYTE   º   LO BYTE   º         adc ebx,ebp
;ÌÍÍÍÍÍÍÍÎÍÍÍÍÍÍÍÍÍÍÍÍÍÎÍÍÍÍÍÍÍÍÍÍÍÍÍÎÍÍÍÍÍÍÍÍÍÍÍÍ͹         adc bh,dl
;º  EAX  º  X-INC LSW  º     ---     º     ---     º         mov dh,[ds:bx]
;ÌÍÍÍÍÍÍÍÎÍÍÍÍÍÍÍÍÍÍÍÍÍÎÍÍÍÍÍÍÍÍÍÍÍÍÍÎÍÍÍÍÍÍÍÍÍÍÍÍ͹         mov [es:di],dh
;º  ECX  º  TXT-X LSW  º     ---     º  LOOPCOUNT  º         add di,80
;ÌÍÍÍÍÍÍÍÎÍÍÍÍÍÍÍÍÍÍÍÍÍÎÍÍÍÍÍÍÍÍÍÍÍÍÍÎÍÍÍÍÍÍÍÍÍÍÍÍ͹         loop Inner
;º  EDX  º     ---     º TEXTUREDATA º    Y-INC    º
;ÌÍÍÍÍÍÍÍÎÍÍÍÍÍÍÍÍÍÍÍÍÍÎÍÍÍÍÍÍÍÍÍÍÍÍÍÎÍÍÍÍÍÍÍÍÍÍÍÍ͹
;º  EBP  º  Y-INC LSW  º X-INC  SIGN º    X-INC    º
;ÌÍÍÍÍÍÍÍÎÍÍÍÍÍÍÍÍÍÍÍÍÍÎÍÍÍÍÍÍÍÍÍÍÍÍÍÎÍÍÍÍÍÍÍÍÍÍÍÍ͹
;º  EBX  º  TXT-Y LSW  º  TEXTURE Y  º  TEXTURE X  º
;ÈÍÍÍÍÍÍÍÊÍÍÍÍÍÍÍÍÍÍÍÍÍÊÍÍÍÍÍÍÍÍÍÍÍÍÍÊÍÍÍÍÍÍÍÍÍÍÍÍͼ

   Ideal
   model small
   P386

SC_INDEX                equ     03c4h   ;Sequence Controller Index
CRTC_INDEX              equ     03d4h   ;CRT Controller Index
MISC_OUTPUT             equ     03c2h   ;Miscellaneous Output register
SCREEN_SEG              equ     0a000h  ;segment of display memory in TweakM
SCREEN_WIDTH            equ     320
MAP_MASK                equ     2       ;Map Mask register index in SC
INPUT_STATUS_1          equ     03dah   ;Input Status 1 register
START_ADDRESS_HIGH      equ     0ch     ;bitmap start address high db
START_ADDRESS_LOW       equ     0dh     ;bitmap start address low db
Row                     =       0

;ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
   MACRO sini                              ;;eax=sin(ax)*32768
;ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ

   and ax,255
   shl ax,1
   push bx
   mov bx,ax
   xor eax,eax
   mov ax,[sintable+bx]
   pop bx

   ENDM

;ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
   MACRO kosini                            ;;eax=cos(ax)*32768
;ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ

   add ax,64
   and ax,255
   shl ax,1
   push bx
   mov bx,ax
   xor eax,eax
   mov ax,[sintable+bx]
   pop bx

   ENDM

;ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
   Segment Code 'Code'                 ;Ok... Let's code it!
;ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ

   Assume cs:Code,ds:Data

Start:  call InitD
   call Tweakon
   call SetPalette

Again:  call waitborder
   call Rotate
   call Proj
   call clean
   call Texture
   call showp
   add [XRot+4],1
   mov ah,0bh
   int 21h
   cmp al,0ffh
   jne Again
   mov ah,7
   int 21h
   cmp al,1bh
   je Stop
   jmp Again
Stop:   mov ax,3
   int 10h
   mov ah,4ch
   int 21h

;ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
   Proc Texture
;ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ


   xor bx,bx
   call TopLeft
   call InitTex

FillL:  call FillIt
   dec [Top]
   jge NoSrcT
   call NewSTop
   dec [Top]
   jmp SkipST
NoSrcT: mov eax,[SrcTXA]
   mov ebx,[SrcTYA]
   add [SrcTX],eax
   add [SrcTY],ebx
SkipST: dec [Bot]
   jge NoSrcB
   call NewSBot
   dec [Bot]
   jmp SkipSB
NoSrcB: mov eax,[SrcBXA]
   mov ebx,[SrcBYA]
   add [SrcBX],eax
   add [SrcBY],ebx

SkipSB: inc [DestTX]
   dec [DTop]
   jge NoDTop
   call NewTop
   jmp SkipDT
NoDTop: mov eax,[DestTYA]
   add [DestTY],eax

SkipDT: dec [DBot]
   jge NoDBot
   call NewBot
   jmp SkipDB
NoDBot: mov eax,[DestBYA]
   add [DestBY],eax

SkipDB: dec [PolWidht]
   jge FillL
   ret

   ENDP

;ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
   Proc FillIt
;ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ

   mov dx,SC_INDEX
   mov al,MAP_MASK
   out dx,al
   mov ax,[Word DestBY+2]
   sub ax,[Word DestTY+2]
   jl SkipIt
   inc ax
   mov [Dest],ax

   mov eax,[SrcTX]
   mov edx,[SrcTY]
   mov ebx,[SrcBX]
   mov ecx,[SrcBY]

   sub ebx,eax
   sub ecx,edx
   mov eax,ebx
   mov bx,[Dest]
   movsx ebx,bx
   cdq
   idiv ebx
   mov [SXA],eax
   mov eax,ecx
   cdq
   idiv ebx
   mov [SYA],eax

   mov ax,SCREEN_SEG
   add ax,[PageOffset]
   mov es,ax
   mov bx,[Word DestTY+2]
   add bx,bx
   mov di,[Rows+bx]
   mov bx,[DestTX]
   mov cx,bx
   shr bx,2
   add di,bx
   and cx,3
   mov al,1
   shl al,cl
   mov dx,SC_INDEX+1
   out dx,al

   mov ebp,[SYA]
   rol ebp,16
   mov dx,bp
   mov eax,[SXA]
   rol eax,16
   mov bp,ax
   xor ax,ax
   mov ecx,[SrcTX]
   rol ecx,16
   mov ebx,[SrcTY]
   rol ebx,16
   mov bh,bl
   mov bl,cl

   mov cx,[Dest]
   dec cx
   jz SkipIt

InnerL: add ecx,eax
   adc ebx,ebp
   adc bh,dl
   mov dh,[Tex+bx]
   mov [es:di],dh
   add di,80
   loop InnerL
SkipIt: ret

   ENDP

;ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
   Proc InitTex
;ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ

   mov ax,[TopP]
   mov [CurTE],ax
   mov [CurBE],ax
   mov [CurSTE],ax
   mov [CurSBE],ax

   call NewTop
   call NewBot
   call NewSTop
   call NewSBot
   ret

   ENDP

;ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
   Proc NewSTop
;ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ

   mov ax,[NTop]
   mov [Top],ax

   mov bx,[CurSTE]

   add bx,bx
   mov bx,[TPol+bx]
   shl bx,2
   mov ax,[TPisteet+bx]
   mov cx,[TPisteet+bx+2]

   mov bx,[CurSTS]
   add bx,bx
   mov bx,[TPol+bx]
   shl bx,2
   sub ax,[TPisteet+bx]
   sub cx,[TPisteet+bx+2]

   mov dx,[TPisteet+bx]
   mov bx,[TPisteet+bx+2]
   shl ebx,16
   shl edx,16
   mov [SrcTX],edx
   mov [SrcTY],ebx
   mov si,[Top]
   inc si
   movsx esi,si
   movsx eax,ax
   shl eax,16
   cdq
   idiv esi
   mov [SrcTXA],eax
   add [SrcTX],eax

   movsx eax,cx
   shl eax,16
   cdq
   idiv esi
   mov [SrcTYA],eax
   add [SrcTY],eax
   ret

   ENDP

;ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
   Proc NewSBot
;ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ

   mov ax,[NBot]
   mov [Bot],ax

   mov bx,[CurSBE]

   add bx,bx
   mov bx,[TPol+bx]
   shl bx,2
   mov ax,[TPisteet+bx]
   mov cx,[TPisteet+bx+2]

   mov bx,[CurSBS]
   add bx,bx
   mov bx,[TPol+bx]
   shl bx,2
   sub ax,[TPisteet+bx]
   sub cx,[TPisteet+bx+2]

   mov dx,[TPisteet+bx]
   mov bx,[TPisteet+bx+2]
   shl ebx,16
   shl edx,16
   mov [SrcBX],edx
   mov [SrcBY],ebx
   mov si,[Bot]
   inc si
   movsx esi,si
   movsx eax,ax
   shl eax,16
   cdq
   idiv esi
   mov [SrcBXA],eax
   add [SrcBX],eax

   movsx eax,cx
   shl eax,16
   cdq
   idiv esi
   mov [SrcBYA],eax
   add [SrcBY],eax
   ret

   ENDP

;ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
   Proc NewTop
;ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ

NewT:   mov ax,[CurTE]
   mov [CurTS],ax
   mov [CurSTS],ax
   mov bx,ax
   inc bx
   and bx,3
   mov [CurTE],bx
   mov [CurSTE],bx

   add bx,bx
   mov bx,[Pol+bx]
   shl bx,2
   mov ax,[Pisteet+bx]
   mov cx,[Pisteet+bx+2]

   mov bx,[CurTS]
   add bx,bx
   mov bx,[Pol+bx]
   shl bx,2
   sub ax,[Pisteet+bx]
   jz NewT
   mov [DTop],ax
   jge NoNeg
   sub ax,2
   neg [DTop]
NoNeg:  inc ax
   sub cx,[Pisteet+bx+2]
   jge NoNeg1
   sub cx,2
NoNeg1: inc cx

   mov bx,[Pisteet+bx+2]
   shl ebx,16
   mov [DestTY],ebx

   mov si,[DTop]
   mov [NTop],si
   inc [NTop]

   movsx eax,cx
   add si,2
   movsx esi,si
   shl eax,16
   cdq
   idiv esi
   mov [DestTYA],eax
   bt eax,31
   jnc NoNeg2
   add [DestTY],eax
   add [DestTY],10000h
NoNeg2: ret

   ENDP

;ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
   Proc NewBot
;ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ

NewB:   mov ax,[CurBE]
   mov [CurBS],ax
   mov [CurSBS],ax
   mov bx,ax
   dec bx
   and bx,3
   mov [CurBE],bx
   mov [CurSBE],bx

   add bx,bx
   mov bx,[Pol+bx]
   shl bx,2
   mov ax,[Pisteet+bx]
   mov cx,[Pisteet+bx+2]

   mov bx,[CurBS]
   add bx,bx
   mov bx,[Pol+bx]
   shl bx,2
   sub ax,[Pisteet+bx]
   jz NewB
   mov [DBot],ax
   jge NoNeg3
   sub ax,2
   neg [DBot]
NoNeg3: inc ax
   sub cx,[Pisteet+bx+2]
   jge NoNeg4
   sub cx,2
NoNeg4: inc cx

   mov bx,[Pisteet+bx+2]
   shl ebx,16
   mov [DestBY],ebx

   mov si,[DBot]
   mov [NBot],si
   inc [NBot]

   movsx eax,cx
   add si,2
   movsx esi,si
   shl eax,16
   cdq
   idiv esi
   mov [DestBYA],eax
   bt eax,31
   jnc NoNeg5
   add [DestBY],10000h
   ret
NoNeg5: add [DestBY],eax
   ret

   ENDP

;ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
   PROC TopLeft
;ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ

   mov [Py],32767
   mov [Px],32767
   mov [Sx],0

   mov ax,32767
   xor bx,bx
   xor si,si
   xor ecx,ecx
   mov di,[Poly+bx]
   mov cx,4
   mov [TopP],0
Poll:   push ecx
   mov cx,[ds:di]
   mov bx,[Pisteet+ecx*4]
   mov cx,[Pisteet+ecx*4+2]
   cmp bx,ax
   ja  Jatka2
   mov ax,bx
   mov [Px],bx
   jl  ThisOne
   cmp [Py],cx
   jle Jatka2
ThisOne:mov [Py],cx
   mov [TopP],si
Jatka2: cmp [Sx],bx
   ja Menoks
   mov [Sx],bx
Menoks: inc si
   add di,2
   pop ecx
   dec ecx
   jnz poll
   mov ax,[Sx]
   sub ax,[Px]
   inc ax
   mov [PolWidht],ax
   mov ax,[Px]
   mov [DestTX],ax
   ret

   ENDP

;ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
   PROC TweakOn
;ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ

   mov     ax,13h
   int     10h
   mov     dx,SC_INDEX
   mov     ax,0604h
   out     dx,ax
   mov     dx,SC_INDEX
   mov     ax,0f02h
   out     dx,ax
   mov     ax,SCREEN_SEG
   mov     es,ax
   sub     di,di
   sub     ax,ax
   mov     cx,8000h
   rep     stosw
   mov     dx,CRTC_INDEX
   mov     ax,14h
   out     dx,ax
   mov     ax,0e317h
   out     dx,ax
   ret

   ENDP

;ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
   PROC InitD
;ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ

   cld
   xor eax,eax
   xor ebx,ebx
   xor ecx,ecx
   xor edx,edx
   xor edi,edi
   xor esi,esi
   mov ax,Data
   mov ds,ax
   ret

   ENDP

;ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
   PROC SetPalette
;ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ

   mov     si,Offset Pal
   mov     al,0
   mov     dx,3c8h
   out     dx,al
   mov     dx,3c9h
   mov     cx,768
invid1: lodsb
   out     dx,al
   loop    invid1
   ret

   ENDP

;ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
   PROC WaitBorder
;ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ

   push    ax
   push    dx
   mov     dx,3dah
wbr1:   in      al,dx
   test    al,8
   jnz     wbr1
wbr2:   in      al,dx
   test    al,8
   jz      wbr2
   pop     dx
   pop     ax
   ret

   ENDP

;ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
   PROC Rotate
;ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ

   mov si,Offset Dpist
   mov di,Offset Rotated
   mov cx,4

   mov ax,[XRot]
   sini
   mov [KXSin],ax
   mov ax,[XRot]
   kosini
   mov [KXCos],ax
   mov ax,[XRot+2]
   sini
   mov [KYSin],ax
   mov ax,[XRot+2]
   kosini
   mov [KYCos],ax
   mov ax,[XRot+4]
   sini
   mov [KZSin],ax
   mov ax,[XRot+4]
   kosini
   mov [KZCos],ax

   mov ax,[KZCos]
   imul [KYCos]
   mov bx,dx
   mov ax,[KZSin]
   imul [KXSin]
   shl dx,1
   mov ax,[KYSin]
   imul dx
   add bx,dx
   mov [Word @@A+1],bx

   mov ax,[KZSin]
   neg ax
   imul [KYCos]
   mov bx,dx
   mov ax,[KZCos]
   imul [KXSin]
   shl dx,1
   mov ax,[KYSin]
   imul dx
   add bx,dx
   mov [Word @@B+1],bx

   mov ax,[KXCos]
   imul [KYSin]
   mov [Word @@C+1],dx

   mov ax,[KZSin]
   imul [KXCos]
   mov [Word @@D+1],dx

   mov ax,[KZCos]
   imul [KXCos]
   mov [Word @@E+1],dx

   mov ax,[KXSin]
   neg ax
   sar ax,1
   mov [Word @@F+1],ax

   mov ax,[KZCos]
   neg ax
   imul [KYSin]
   mov bx,dx
   mov ax,[KZSin]
   imul [KXSin]
   shl dx,1
   mov ax,[KYCos]
   imul dx
   add bx,dx
   mov [Word @@G+1],bx

   mov ax,[KZSin]
   imul [KYSin]
   mov bx,dx
   mov ax,[KZCos]
   imul [KXSin]
   shl dx,1
   mov ax,[KYCos]
   imul dx
   add bx,dx
   mov [Word @@H+1],bx

   mov ax,[KXCos]
   imul [KYCos]
   mov [Word @@L+1],dx

RotL:

@@A:    mov ax,1234h
   imul [Word si]
   mov bx,dx
@@B:    mov ax,1234h
   imul [Word si+2]
   add bx,dx
@@C:    mov ax,1234h
   imul [Word si+4]
   add bx,dx
   shl bx,2
   mov [ds:di],bx

@@D:    mov ax,1234h
   imul [Word si]
   mov bx,dx
@@E:    mov ax,1234h
   imul [Word si+2]
   add bx,dx
@@F:    mov ax,1234h
   imul [Word si+4]
   add bx,dx
   shl bx,2
   mov [ds:di+2],bx

@@G:    mov ax,1234h
   imul [Word si]
   mov bx,dx
@@H:    mov ax,1234h
   imul [Word si+2]
   add bx,dx
@@L:    mov ax,1234h
   imul [Word si+4]
   add bx,dx
   shl bx,2
   mov [ds:di+4],bx

   add si,6
   add di,8
   dec cx
   jnz RotL
   ret

ENDP

;ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
   PROC Proj
;ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ

   xor ecx,ecx
   xor edi,edi

   mov cx,1
ML:     xor esi,esi
   push cx
   dec cx
   mov si,[ObjDot+ecx*2]
   mov cx,[si]
   cmp cx,0
   je  @@Next
   add si,2
ProL:   push cx
   mov cx,[ecx*2+esi-2]
   shl cx,2
   mov bp,cx
   add cx,cx
   mov bx,[Rotated+ecx+4]
   movsx ebx,bx
   add ebx,[KZ]
   add ebx,1024

   mov ax,[Rotated+ecx]
   cwde
   cdq
   shl eax,8
   idiv ebx
   mov dx,ax
   sar dx,2
   add ax,dx
   add ax,[XCenter]
   mov [Pisteet+bp],ax

   mov ax,[Rotated+ecx+2]
   cwde
   neg eax
   cdq
   shl eax,8
   idiv ebx
   add ax,[YCenter]
   mov [Pisteet+bp+2],ax

   pop cx
   dec cx
   jnz ProL
@@Next: pop cx
   dec cx
   jnz ML
   ret

   ENDP

;ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
   PROC Clean
;ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ

   mov dx,SC_INDEX
   mov ax,0f02h
   out dx,ax
   mov ax,SCREEN_SEG
   add ax,[PageOffset]
   mov es,ax
   sub di,di
   sub eax,eax
   mov cx,4000
lop:    rep stosd
   ret

   ENDP

;ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
   PROC ShowP
;ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ

   push    bx
   push    cx
   push    dx
   push    ax

   mov     bl,START_ADDRESS_LOW
   mov     bh,[Byte ptr StartOffset]
   mov     cl,START_ADDRESS_HIGH
   mov     ch,[Byte ptr StartOffset+1]
   mov     dx,CRTC_INDEX
   mov     ax,bx
   out     dx,ax
   mov     ax,cx
   out     dx,ax

   cmp     [PageOffset],0
   jne     Page0
   mov     [PageOffset],1024
   mov     [StartOffset],16384
   pop     ax
   pop     dx
   pop     cx
   pop     bx
   ret

Page0:  mov     [PageOffset],0
   mov     [StartOffset],0
   pop     ax
   pop     dx
   pop     cx
   pop     bx
   ret

   ENDP

   ENDS

;ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
   Segment Data 'Data'
;ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ



   Label Sintable Word

   include "sintable.inc"

   Label Tex Byte

   include "texture.inc"

   dw 256 DUP(0)

   Label Pal Byte

   include "textpal.inc"

KXSin   dw 0
KXCos   dw 0
KYSin   dw 0
KYCos   dw 0
KZSin   dw 0
KZCos   dw 0
XRot    dw 0,0,0
ObjDot  dw Point
Point   dw 4,0,1,2,3
XCenter dw 160
YCenter dw 100
KZ      dd 2300
StartOffset dw 0
PageOffset  dw 0
TopP    dw 0
CurTS   dw 0
CurTE   dw 0
CurBS   dw 0
CurBE   dw 0
CurSTS  dw 0
CurSTE  dw 0
CurSBS  dw 0
CurSBE  dw 0

SrcTX   dd 0
SrcTY   dd 0
SrcBX   dd 0
SrcBY   dd 0
SrcTXA  dd 0
SrcTYA  dd 0
SrcBXA  dd 0
SrcBYA  dd 0

SXA     dd 0
SYA     dd 0

DestTX  dw 0
DestTY  dd 0
DestBX  dd 0
DestBY  dd 0
DestTXA dd 0
DestTYA dd 0
DestBXA dd 0
DestBYA dd 0

DeltaX  dd 0
DeltaY  dd 0
x1      dw 0
x2      dw 0
y1      dw 0
y2      dw 0
Dest    dw 0
Py      dw 0
Px      dw 0
Sx      dw 0
Top     dw 0
Bot     dw 0
DTop    dw 0
DBot    dw 0
NTop    dw 0
NBot    dw 0
Count   dw 0

PolWidht dw 0
Color   db 0
Frames  dw 0
Taulukko dw 1000 DUP(0)

Dpist   dw -256*3,320*3,0,256*3,320*3,0,256*3,-320*3,0,-256*3,-320*3,0

Rotated dw 500 Dup(0)

LABEL   Rows Word

   Rept 200

   dw Row

   Row = Row+80

   EndM

Poly    dw polygon
polygon dw 0,1,2,3

pol     dw 0,1,2,3

Polyt   dw pol1

pol1    dw 4,0,0,1,2,3

Pisteet dw 500 DUP(0)

Tpol    dw 0,1,2,3

Tpisteet dw 0,0,63,0,63,63,0,63

   ENDS

   Stack 200h

   END start
   END



EDIT: I just accidentaly double posted (wasn't paying attention). I've merged those posts now.
Title: Re: Texture drawing
Post by: AngelFish on June 28, 2011, 04:39:41 pm
That's x86 code.

MOV: Moves data from one location in memory to another (could be registers or addressable space).
INT: Generates Interrupt
CMP: Compare
JNE: Jump if Not Equal
JE: Jump if Equal
JGE: Conditional Relative Jump (I'm not sure of the specifics)
JMP: Jump...
JL: Jump if less than
CDQ: Convert Double to Quad
IDIV: Signed integer division
Title: Re: Texture drawing
Post by: ben_g on June 28, 2011, 04:49:11 pm
CDQ: Convert Double to Quad
Double: is this like the java double (a floating point number)? And what do you mean with quad?
Title: Re: Texture drawing
Post by: AngelFish on June 28, 2011, 04:51:56 pm
No, it's an integer double word. What happens is that it sign extends the double word in the EAX register to 64 bits and places the higher 32 bits in the EDX register. EAX retains the lower 32 bits of the quad (64 bit) word.
Title: Re: Texture drawing
Post by: ben_g on June 29, 2011, 09:07:10 am
I decided to give up on textured triangles. They are way to hard :(

But becouse I really want textures, I tried writing a routine for textured quads, and it worked :D
This only took me 10 minutes to code:
(http://picturestack.com/351/788/NePUntitledd36.png)
Now I still have to port this to asm. I'll let you know when i've done it (or when i have an other problem).
Title: Re: Texture drawing
Post by: calc84maniac on June 29, 2011, 12:19:39 pm
I assume you're not worrying about perspective correctness?
Title: Re: Texture drawing
Post by: ben_g on June 29, 2011, 12:47:15 pm
I assume you're not worrying about perspective correctness?
I've tried it and the texture is only a bit of near the center. On a screen with a very low resolution, it would only be noticable when you are very close. And becouse the quad isn't made out of two triangles, it would always have almost the same effect as persfective correction.
Title: Re: Texture drawing
Post by: shmibs on June 29, 2011, 12:59:28 pm
why are the left and right sides of the blue rectangle parallel? the one on the right is where it should be, but the one on the left should be pointing directly towards the other side, not up at the teal oval...
the arrow's stem is also off centre and the teal oval looks like it's lying flat on a different plane, not the red rectangle.
what method are you using for this?
EDIT: ah, so you're using two skewed triangles? i guess that sort of works (and probably wouldn't be all that bad looking on a calc screen) but it's still a little wonky...
Title: Re: Texture drawing
Post by: ben_g on June 29, 2011, 01:02:17 pm
what method are you using for this?
interpolating. A lot of it.
Title: Re: Texture drawing
Post by: jnesselr on July 01, 2011, 05:57:22 pm
Wait, ben_g does your name actually start with a B?  You may be one of the uBer coders. (Name subject to change)
Title: Re: Texture drawing
Post by: ben_g on July 01, 2011, 05:59:58 pm
uBer coders?

Yes, my name starts with a B. My real name is Ben, and my surname starts with a G. That's how I've shosen my name.
Title: Re: Texture drawing
Post by: AngelFish on July 01, 2011, 06:01:23 pm
Awww, you're not a Brandon. As a general rule, people whose first names are Brandon are always supper uber-1337 coderz who can do pretty much anything they want with calculators.
Title: Re: Texture drawing
Post by: ben_g on July 01, 2011, 06:03:18 pm
Your previous post lets me think your name is Brandon. Am I correct?
Title: Re: Texture drawing
Post by: AngelFish on July 01, 2011, 06:04:07 pm
O.o

No, but thanks for the compliment.

Calc84maniac, on the other hand...
Title: Re: Texture drawing
Post by: ben_g on July 01, 2011, 06:07:44 pm
But anyway, Why would you think I'm an uber 1337 coder when I'm just a newb?

/me turns of his computer and will be gone for 10 days.
Title: Re: Texture drawing
Post by: ben_g on July 14, 2011, 11:06:00 am
I have ported half of the code to asm. This code should draw the top third of a textured quad. My problem is that it doesn't draw anything. It gets stuck in an endless loop, and I don't know why.

Spoiler For The code:
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;TexQuad
;in: x1, y1, u1, v1, x2, y2, u2, v2, x3, y3, u3, v3, x4, y4, u4, v4
;out: textured quad is drawn to the buffer
TexQuad:
  ld a, (y1)
  ld b, a
  ld a, (y2)
  sub b
  ld (temp), a
  ld a, (x1)
  ld b, a
  ld a, (x2)
  sub b
  ld h, a
  ld l, 0
  ld de, (temp)
  ld e, 0
  call DivFP
  ld (dx1), hl
  ld a, (y1)
  ld b, a
  ld a, (y3)
  sub b
  ld (temp), a
  ld a, (x1)
  ld b, a
  ld a, (x3)
  sub b
  ld h, a
  ld l, 0
  ld de, (temp)
  ld e, 0
  call DivFP
  ld (dx2), hl
  ld a, (y2)
  ld b, a
  ld a, (y4)
  sub b
  ld (temp), a
  ld a, (x2)
  ld b, a
  ld a, (x4)
  sub b
  ld h, a
  ld l, 0
  ld de, (temp)
  ld e, 0
  call DivFP
  ld (dx3), hl
  ld a, (y3)
  ld b, a
  ld a, (y4)
  sub b
  ld (temp), a
  ld a, (x3)
  ld b, a
  ld a, (x4)
  sub b
  ld h, a
  ld l, 0
  ld de, (temp)
  ld e, 0
  call DivFP
  ld (dx4), hl
  ld a, (y1)
  ld b, a
  ld a, (y2)
  sub b
  ld (temp), a
  ld a, (u1)
  ld b, a
  ld a, (u2)
  sub b
  ld h, a
  ld l, 0
  ld de, (temp)
  ld e, 0
  call DivFP
  ld (du1), hl
  ld a, (y1)
  ld b, a
  ld a, (y3)
  sub b
  ld (temp), a
  ld a, (u1)
  ld b, a
  ld a, (u3)
  sub b
  ld h, a
  ld l, 0
  ld de, (temp)
  ld e, 0
  call DivFP
  ld (du2), hl
  ld a, (y2)
  ld b, a
  ld a, (y4)
  sub b
  ld (temp), a
  ld a, (u2)
  ld b, a
  ld a, (u4)
  sub b
  ld h, a
  ld l, 0
  ld de, (temp)
  ld e, 0
  call DivFP
  ld (du3), hl
  ld a, (y3)
  ld b, a
  ld a, (y4)
  sub b
  ld (temp), a
  ld a, (u3)
  ld b, a
  ld a, (u4)
  sub b
  ld h, a
  ld l, 0
  ld de, (temp)
  ld e, 0
  call DivFP
  ld (du4), hl
  ld a, (y1)
  ld b, a
  ld a, (y2)
  sub b
  ld (temp), a
  ld a, (v1)
  ld b, a
  ld a, (v2)
  sub b
  ld h, a
  ld l, 0
  ld de, (temp)
  ld e, 0
  call DivFP
  ld (dv1), hl
  ld a, (y1)
  ld b, a
  ld a, (y3)
  sub b
  ld (temp), a
  ld a, (v1)
  ld b, a
  ld a, (v3)
  sub b
  ld h, a
  ld l, 0
  ld de, (temp)
  ld e, 0
  call DivFP
  ld (dv2), hl
  ld a, (y2)
  ld b, a
  ld a, (y4)
  sub b
  ld (temp), a
  ld a, (v2)
  ld b, a
  ld a, (v4)
  sub b
  ld h, a
  ld l, 0
  ld de, (temp)
  ld e, 0
  call DivFP
  ld (dv3), hl
  ld a, (y3)
  ld b, a
  ld a, (y4)
  sub b
  ld (temp), a
  ld a, (v3)
  ld b, a
  ld a, (v4)
  sub b
  ld h, a
  ld l, 0
  ld de, (temp)
  ld e, 0
  call DivFP
  ld (dv4), hl
  ld hl, (x1)
  ld l, 0
  ld (tx1), hl
  ld hl, (x2)
  ld l, 0
  ld (tx2), hl
  ld hl, (u1)
  ld l, 0
  ld (tu1), hl
  ld hl, (v1)
  ld l, 0
  ld (tv1), hl
  ld hl, (u2)
  ld l, 0
  ld (tu2), hl
  ld hl, (v2)
  ld l, 0
  ld (tv2), hl
  ld hl, (y1)
  ld l, 0
  ld (_ty), hl

QuadDrawLoop1:
  ld a, (tx1)
  ld (temp), a      ;i=temp

QuadPlotLoop1:
  ld a, (tx1)
  ld b, a
  ld a, (tx2)
  sub b
  ld c, a
  ld a, (tx1)
  ld d, a
  ld e, 0
  ld a, (temp)
  sub b
  ld h, a
  ld l, 0
  call DivFP
  ld a, h
  ld (temp+1), a   ;tmp=temp+1
  ld b, a
  ld a, 1
  sub b
  ld d, a
  ld e, 0
  ld a, (tu1)
  ld b, a
  ld c, 0
  call MulFP
  push hl
  ld de, (temp+1)
  ld e, 0
  ld bc, (tu2)
  ld c, 0
  call MulFP
  pop de
  add hl, de
  ld a, h
  ld (temp2), a      ;u=temp2
  ld a, (temp+1)
  ld b, a
  ld a, 1
  sub b
  ld d, a
  ld e, 0
  ld a, (tv1)
  ld b, a
  ld c, 0
  call MulFP
  push hl
  ld de, (temp+1)
  ld e, 0
  ld bc, (tv2)
  ld c, 0
  call MulFP
  pop de
  add hl, de
  ld a, h
  ld (temp2+1), a      ;v=temp2+1
;Get the pixel at (u,v) from the texture
  ld a, (temp2+1)   ;load the v coordinate in a
  ld hl, texture
  ld d, 0
  ld e, a
  add hl, de
  ld a, (hl)      ;and load the byte of the v coordinate in a
  ld c, a
  ld a, (temp2)
  ld b, 1
  cp b
  jr c, BitShiftDone   ;no shifting if u=0
  ld b, a

BitShiftLoop:
  sll c
  djnz BitShiftLoop

BitShiftDone:
  push bc         ;1
  ld a, (_ty)
  ld l, a
  ld a, (temp)

getPixel:
   ld   h, 0
   ld   d, h
   ld   e, l
   
   add   hl, hl
   add   hl, de
   add   hl, hl
   add   hl, hl
   
   ld   e, a
   srl   e
   srl   e
   srl   e
   add   hl, de
   
   ld   de, PlotSScreen
   add   hl, de
   
   and   7
   ld   b, a
   ld   a, $80
   ret   z
   
   rrca
   djnz   $-1

  pop bc         ;0
  bit 7, c
  jr z, ResPixel

SetPixel:
  or (hl)
  ld (hl), a
  jr EndPlot

ResPixel:
  cpl
  and (hl)
  ld (hl), a

EndPlot:

  ld hl, (tx1)
  ld de, (dx1)
  add hl, de
  ld (tx1), hl
  ld hl, (tx2)
  ld de, (dx2)
  add hl, de
  ld (tx2), hl
  ld hl, (tu1)
  ld de, (du1)
  add hl, de
  ld (tu1), hl
  ld hl, (tu2)
  ld de, (du2)
  add hl, de
  ld (tu2), hl
  ld hl, (tv1)
  ld de, (dv1)
  add hl, de
  ld (tv1), hl
  ld hl, (tv2)
  ld de, (dv2)
  add hl, de
  ld (tv2), hl
  ld a, (_ty)
  inc a
  ld (_ty), a
  ld c, a
  ld a, (y2)
  ld h, a
  ld a, c
  ld c, h
  cp c
  jp nz, QuadDrawLoop1
  ret      ;voorlopig

All of the math routines are for 8.8 signed floating point math. These are all fully tested so they don't couse the cash.
Title: Re: Texture drawing
Post by: thepenguin77 on July 14, 2011, 01:13:56 pm
Now that is one of the scariest pieces of code I have ever seen.

And thisshould definitely be this
Code: [Select]
  ld a, (_ty)
  inc a
  ld (_ty), a
  ld c, a
  ld a, (y2)
  ld h, a
  ld a, c
  ld c, h
  cp c
  jp nz, QuadDrawLoop1
Code: [Select]
  ld hl, _ty
  inc (hl)
  ld a, (y2)
  cp (hl)
  jp nz, QuadDrawLoop1


But, as to why it's not actually working. Your loop should theoretically work as long as you are giving it valid numbers. (It will actually finish no matter what you give it though) So that leads me to believe that the problem is with your pixel plotting. Most likely, you are trying to plot pixels that are off screen and that is what is causing all of your problems. You end up plotting pixels in your program code, which causes crashes.

If you are really unlucky, you might even be plotting pixels at _ty.
Title: Re: Texture drawing
Post by: ben_g on July 14, 2011, 05:18:07 pm
Now that is one of the scariest pieces of code I have ever seen.
How do you mean?

But, as to why it's not actually working. Your loop should theoretically work as long as you are giving it valid numbers. (It will actually finish no matter what you give it though) So that leads me to believe that the problem is with your pixel plotting. Most likely, you are trying to plot pixels that are off screen and that is what is causing all of your problems. You end up plotting pixels in your program code, which causes crashes.

If you are really unlucky, you might even be plotting pixels at _ty.
I tried jumping over the plotting part, and it still crashes. By the way, this is done in an app, and ass variables defined inside the app itself won't work, then isn't the program protected against SMC?

By the way: thanks for the optimization.
Title: Re: Texture drawing
Post by: thepenguin77 on July 14, 2011, 05:43:19 pm
It's scary because it's so massive and very repetitive (though I've seen worse; much, much worse). I'm sure with the proper optimizations you could probably cut about 25% or more off.

Anyways, I believe I found the error. You inlined your GetPixel which I think is rather funny, but there was an extra RET Z in it that you missed. This normally wouldn't cause crashes, but you did a PUSH BC around it, so you are returning into BC, which is definitely not a place where you want to go.

And yes, being in an app protects you accidental SMC.
Title: Re: Texture drawing
Post by: ben_g on July 14, 2011, 06:42:07 pm
The ret z dit couse the crash.

But it still doesn't work. It draws a line instaed while it should draw the top third of the quad in solid black (the texture is an 8x8 solid rectangle).

Title: Re: Texture drawing
Post by: ben_g on July 16, 2011, 07:44:20 pm
many thanks to thepenguin77 and calc84 for helping me through omnomIRC.

But it still doesn't work. It gets stuck in a endless loop again.

I included the most recent scource code.
Spoiler For source code:
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;TexQuad
;in: x1, y1, u1, v1, x2, y2, u2, v2, x3, y3, u3, v3, x4, y4, u4, v4
;out: textured quad is drawn to the buffer
TexQuad:
  ld a, (y1)
  ld b, a
  ld a, (y2)
  sub b
  ld (temp), a
  ld a, (x1)
  ld b, a
  ld a, (x2)
  sub b
  ld h, a
  ld l, 0
  ld de, (temp)
  ld e, 0
  call DivFP
  ld (dx1), hl
  ld a, (y1)
  ld b, a
  ld a, (y3)
  sub b
  ld (temp), a
  ld a, (x1)
  ld b, a
  ld a, (x3)
  sub b
  ld h, a
  ld l, 0
  ld a, (temp)
  ld d, a
  ld e, 0
  call DivFP
  ld (dx2), hl
  ld a, (y2)
  ld b, a
  ld a, (y4)
  sub b
  ld (temp), a
  ld a, (x2)
  ld b, a
  ld a, (x4)
  sub b
  ld h, a
  ld l, 0
  ld a, (temp)
  ld d, a
  ld e, 0
  call DivFP
  ld (dx3), hl
  ld a, (y3)
  ld b, a
  ld a, (y4)
  sub b
  ld (temp), a
  ld a, (x3)
  ld b, a
  ld a, (x4)
  sub b
  ld h, a
  ld l, 0
  ld a, (temp)
  ld d, a
  ld e, 0
  call DivFP
  ld (dx4), hl
  ld a, (y1)
  ld b, a
  ld a, (y2)
  sub b
  ld (temp), a
  ld a, (u1)
  ld b, a
  ld a, (u2)
  sub b
  ld h, a
  ld l, 0
  ld a, (temp)
  ld d, a
  ld e, 0
  call DivFP
  ld (du1), hl
  ld a, (y1)
  ld b, a
  ld a, (y3)
  sub b
  ld (temp), a
  ld a, (u1)
  ld b, a
  ld a, (u3)
  sub b
  ld h, a
  ld l, 0
  ld a, (temp)
  ld d, a
  ld e, 0
  call DivFP
  ld (du2), hl
  ld a, (y2)
  ld b, a
  ld a, (y4)
  sub b
  ld (temp), a
  ld a, (u2)
  ld b, a
  ld a, (u4)
  sub b
  ld h, a
  ld l, 0
  ld a, (temp)
  ld d, a
  ld e, 0
  call DivFP
  ld (du3), hl
  ld a, (y3)
  ld b, a
  ld a, (y4)
  sub b
  ld (temp), a
  ld a, (u3)
  ld b, a
  ld a, (u4)
  sub b
  ld h, a
  ld l, 0
  ld a, (temp)
  ld d, a
  ld e, 0
  call DivFP
  ld (du4), hl
  ld a, (y1)
  ld b, a
  ld a, (y2)
  sub b
  ld (temp), a
  ld a, (v1)
  ld b, a
  ld a, (v2)
  sub b
  ld h, a
  ld l, 0
  ld a, (temp)
  ld d, a
  ld e, 0
  call DivFP
  ld (dv1), hl
  ld a, (y1)
  ld b, a
  ld a, (y3)
  sub b
  ld (temp), a
  ld a, (v1)
  ld b, a
  ld a, (v3)
  sub b
  ld h, a
  ld l, 0
  ld a, (temp)
  ld d, a
  ld e, 0
  call DivFP
  ld (dv2), hl
  ld a, (y2)
  ld b, a
  ld a, (y4)
  sub b
  ld (temp), a
  ld a, (v2)
  ld b, a
  ld a, (v4)
  sub b
  ld h, a
  ld l, 0
  ld a, (temp)
  ld d, a
  ld e, 0
  call DivFP
  ld (dv3), hl
  ld a, (y3)
  ld b, a
  ld a, (y4)
  sub b
  ld (temp), a
  ld a, (v3)
  ld b, a
  ld a, (v4)
  sub b
  ld h, a
  ld l, 0
  ld a, (temp)
  ld d, a
  ld e, 0
  call DivFP
  ld (dv4), hl
  ld a, (x1)
  ld h, a
  ld l, 0
  ld (tx1), hl
  ld a, (x2)
  ld h, a
  ld l, 0
  ld (tx2), hl
  ld a, (u1)
  ld h, a
  ld l, 0
  ld (tu1), hl
  ld a, (v1)
  ld h, a
  ld l, 0
  ld (tv1), hl
  ld a, (u2)
  ld h, a
  ld l, 0
  ld (tu2), hl
  ld a, (v2)
  ld h, a
  ld l, 0
  ld (tv2), hl
  ld a, (y1)
  ld (_ty), a

QuadDrawLoop1:
  ld a, (tx1)
  ld (temp), a      ;i=temp

QuadPlotLoop1:
  ld a, (tx1)
  ld b, a
  ld a, (tx2)
  sub b
  ld c, a
  ld a, (tx1)
  ld d, a
  ld e, 0
  ld a, (temp)
  sub b
  ld h, a
  ld l, 0
  call DivFP
  ld a, h
  ld (temp+1), a   ;tmp=temp+1
  ld b, a
  ld a, 1
  sub b
  ld d, a
  ld e, 0
  ld a, (tu1)
  ld b, a
  ld c, 0
  call MulFP
  push hl
  ld a, (temp+1)
  ld d, a
  ld e, 0
  ld a, (tu2)
  ld b, a
  ld c, 0
  call MulFP
  pop de
  add hl, de
  ld a, h
  ld (temp2), a      ;u=temp2
  ld a, (temp+1)
  ld b, a
  ld a, 1
  sub b
  ld d, a
  ld e, 0
  ld a, (tv1)
  ld b, a
  ld c, 0
  call MulFP
  push hl
  ld a, (temp+1)
  ld d, a
  ld e, 0
  ld a, (tv2)
  ld b, a
  ld c, 0
  call MulFP
  pop de
  add hl, de
  ld a, h
  ld (temp2+1), a      ;v=temp2+1
;Get the pixel at (u,v) from the texture
  ld   hl, (temp2+1)
   ld   h, 0      ;1 byte smaller

   ld   de, texture
   add   hl, de

   ld   a, (temp2)
   ld   b, a
   inc   b
   ld a, (hl)
shiftLoop:
   rl   c
   djnz   shiftLoop   ;the extra shift gets rid of the jr
            ;and pulls the bit out of carry

BitShiftDone:
  push af         ;1
  ld a, (_ty)
  ld l, a
  ld a, (temp)
  ld b, 94
  cp b
  jr nc, ContDrawLoop1

getPixel:
   ld   h, 0
   ld   d, h
   ld   e, l
   
   add   hl, hl
   add   hl, de
   add   hl, hl
   add   hl, hl
   
   ld   e, a
   srl   e
   srl   e
   srl   e
   add   hl, de
   
   ld   de, PlotSScreen
   add   hl, de
   
   and   7
   ld   b, a
   ld   a, $80
   jr   z, PlotPixel
   
   rrca
   djnz   $-1

PlotPixel:
  pop af         ;0
  jr nc, ResPixel

SetPixel:
  or (hl)
  ld (hl), a
  jr EndPlot

ResPixel:
  cpl
  and (hl)
  ld (hl), a

EndPlot:
  ld a, (temp)
  ld b, 255
  cp b
  jp z, ContDrawLoop1
  ld hl, temp
  inc (hl)
  ld a, (tx2)
  cp (hl)
  jp nc, QuadPlotLoop1

ContDrawLoop1:
  ld hl, (tx1)
  ld de, (dx1)
  add hl, de
  ld (tx1), hl
  ld hl, (tx2)
  ld de, (dx2)
  add hl, de
  ld (tx2), hl
  ld hl, (tu1)
  ld de, (du1)
  add hl, de
  ld (tu1), hl
  ld hl, (tu2)
  ld de, (du2)
  add hl, de
  ld (tu2), hl
  ld hl, (tv1)
  ld de, (dv1)
  add hl, de
  ld (tv1), hl
  ld hl, (tv2)
  ld de, (dv2)
  add hl, de
  ld (tv2), hl
  ld hl, _ty
  inc (hl)
  ld a, (y2)
  cp (hl)
  jp nz, QuadDrawLoop1

  ld a, (y2)
  ld (_ty), a

QuadDrawLoop2:
  ld a, (tx1)
  ld (temp), a      ;i=temp

QuadPlotLoop2:
  ld a, (tx1)
  ld b, a
  ld a, (tx2)
  sub b
  ld c, a
  ld a, (tx1)
  ld d, a
  ld e, 0
  ld a, (temp)
  sub b
  ld h, a
  ld l, 0
  call DivFP
  ld a, h
  ld (temp+1), a   ;tmp=temp+1
  ld b, a
  ld a, 1
  sub b
  ld d, a
  ld e, 0
  ld a, (tu1)
  ld b, a
  ld c, 0
  call MulFP
  push hl
  ld a, (temp+1)
  ld d, a
  ld e, 0
  ld a, (tu2)
  ld b, a
  ld c, 0
  call MulFP
  pop de
  add hl, de
  ld a, h
  ld (temp2), a      ;u=temp2
  ld a, (temp+1)
  ld b, a
  ld a, 1
  sub b
  ld d, a
  ld e, 0
  ld a, (tv1)
  ld b, a
  ld c, 0
  call MulFP
  push hl
  ld a, (temp+1)
  ld d, a
  ld e, 0
  ld a, (tv2)
  ld b, a
  ld c, 0
  call MulFP
  pop de
  add hl, de
  ld a, h
  ld (temp2+1), a      ;v=temp2+1
;Get the pixel at (u,v) from the texture
  ld   hl, (temp2+1)
   ld   h, 0      ;1 byte smaller

   ld   de, texture
   add   hl, de

   ld   a, (temp2)
   ld   b, a
   inc   b
   ld a, (hl)
shiftLoop2:
   rl   c
   djnz   shiftLoop2   ;the extra shift gets rid of the jr
            ;and pulls the bit out of carry

BitShiftDone2:
  push af         ;1
  ld a, (_ty)
  ld l, a
  ld a, (temp)

getPixel2:
   ld   h, 0
   ld   d, h
   ld   e, l
   
   add   hl, hl
   add   hl, de
   add   hl, hl
   add   hl, hl
   
   ld   e, a
   srl   e
   srl   e
   srl   e
   add   hl, de
   
   ld   de, PlotSScreen
   add   hl, de
   
   and   7
   ld   b, a
   ld   a, $80
   jr   z, PlotPixel2
   
   rrca
   djnz   $-1

PlotPixel2:
  pop af         ;0
  jr nc, ResPixel2

SetPixel2:
  or (hl)
  ld (hl), a
  jr EndPlot2

ResPixel2:
  cpl
  and (hl)
  ld (hl), a

EndPlot2:
  ld hl, temp
  inc (hl)
  ld a, (tx2)
  cp (hl)
  jp nc, QuadPlotLoop2

  ld hl, (tx1)
  ld de, (dx3)
  add hl, de
  ld (tx1), hl
  ld hl, (tx2)
  ld de, (dx2)
  add hl, de
  ld (tx2), hl
  ld hl, (tu1)
  ld de, (du3)
  add hl, de
  ld (tu1), hl
  ld hl, (tu2)
  ld de, (du2)
  add hl, de
  ld (tu2), hl
  ld hl, (tv1)
  ld de, (dv3)
  add hl, de
  ld (tv1), hl
  ld hl, (tv2)
  ld de, (dv2)
  add hl, de
  ld (tv2), hl
  ld hl, _ty
  inc (hl)
  ld a, (y2)
  cp (hl)
  jp nz, QuadDrawLoop2

QuadDrawLoop3:
  ld a, (tx1)
  ld (temp), a      ;i=temp

QuadPlotLoop3:
  ld a, (tx1)
  ld b, a
  ld a, (tx2)
  sub b
  ld c, a
  ld a, (tx1)
  ld d, a
  ld e, 0
  ld a, (temp)
  sub b
  ld h, a
  ld l, 0
  call DivFP
  ld a, h
  ld (temp+1), a   ;tmp=temp+1
  ld b, a
  ld a, 1
  sub b
  ld d, a
  ld e, 0
  ld a, (tu1)
  ld b, a
  ld c, 0
  call MulFP
  push hl
  ld de, (temp+1)
  ld e, 0
  ld bc, (tu2)
  ld c, 0
  call MulFP
  pop de
  add hl, de
  ld a, h
  ld (temp2), a      ;u=temp2
  ld a, (temp+1)
  ld b, a
  ld a, 1
  sub b
  ld d, a
  ld e, 0
  ld a, (tv1)
  ld b, a
  ld c, 0
  call MulFP
  push hl
  ld a, (temp+1)
  ld d, a
  ld e, 0
  ld a, (tv2)
  ld b, a
  ld c, 0
  call MulFP
  pop de
  add hl, de
  ld a, h
  ld (temp2+1), a      ;v=temp2+1
;Get the pixel at (u,v) from the texture
  ld   hl, (temp2+1)
   ld   h, 0      ;1 byte smaller

   ld   de, texture
   add   hl, de

   ld   a, (temp2)
   ld   b, a
   inc   b
   ld a, (hl)
shiftLoop3:
   rl   c
   djnz   shiftLoop3   ;the extra shift gets rid of the jr
            ;and pulls the bit out of carry

BitShiftDone3:
  push af         ;1
  ld a, (_ty)
  ld l, a
  ld a, (temp)

getPixel3:
   ld   h, 0
   ld   d, h
   ld   e, l
   
   add   hl, hl
   add   hl, de
   add   hl, hl
   add   hl, hl
   
   ld   e, a
   srl   e
   srl   e
   srl   e
   add   hl, de
   
   ld   de, PlotSScreen
   add   hl, de
   
   and   7
   ld   b, a
   ld   a, $80
   jr   z, PlotPixel3
   
   rrca
   djnz   $-1

PlotPixel3:
  pop af         ;0
  jr nc, ResPixel3

SetPixel3:
  or (hl)
  ld (hl), a
  jr EndPlot3

ResPixel3:
  cpl
  and (hl)
  ld (hl), a

EndPlot3:
  ld hl, temp
  inc (hl)
  ld a, (tx2)
  cp (hl)
  jp nc, QuadPlotLoop3

  ld hl, (tx1)
  ld de, (dx3)
  add hl, de
  ld (tx1), hl
  ld hl, (tx2)
  ld de, (dx4)
  add hl, de
  ld (tx2), hl
  ld hl, (tu1)
  ld de, (du3)
  add hl, de
  ld (tu1), hl
  ld hl, (tu2)
  ld de, (du4)
  add hl, de
  ld (tu2), hl
  ld hl, (tv1)
  ld de, (dv3)
  add hl, de
  ld (tv1), hl
  ld hl, (tv2)
  ld de, (dv4)
  add hl, de
  ld (tv2), hl
  ld hl, _ty
  inc (hl)
  ld a, (y2)
  cp (hl)
  jp nz, QuadDrawLoop3
  ret
Title: Re: Texture drawing
Post by: ben_g on July 17, 2011, 06:41:27 pm
After placing ret's and jumps at some positions in the code and counting the bytes in the memory editor of wabbitemu, I found out that thi routine does anything but drawing a textured quad. Amost nothing of it is doing what it should do, so I decided to put this on hold, make an other game, and try again when i'm more used to asm.

So, does anybody have a good idea for a good 2D or wireframe 3D game?

Edit: I just noticed i tripple posted, but there is more than 6 hours between those posts, so it's ok, right?
Title: Re: Texture drawing
Post by: ztrumpet on July 17, 2011, 07:14:02 pm
Edit: I just noticed i tripple posted, but there is more than 6 hours between those posts, so it's ok, right?
Yup, it's fine.

Good luck with your new project. :)
Title: Re: Texture drawing
Post by: thepenguin77 on July 18, 2011, 09:37:20 am
Yeah, the triple post was justified because if you hadn't of triple posted, I probably wouldn't have checked the pages and I would have missed your edits. (I always look at all the asm posts, just so you know. So if I don't answer, it either means I have no idea, or it would be annoying for me do whatever the request was (write a whole routine set for someone).)
Title: Re: Texture drawing
Post by: ben_g on July 20, 2011, 02:49:38 pm
It doesn't look that bad on a calculator:
(http://picturestack.com/187/637/OkUQuadxwW.gif)
For some reason, the pixels on the edge between two texels are sometimes wrong. Does anybody knows how that can be fixed?

This is in basic, btw.

EDIT:

How could i have forgot the scource?

anyway, here it is. Sorry, it's the program itself, not just te code. I tried opening it with notepad, but all i got was a bunch of strange characters. So i hope you have an emulator to open it

btw: still no texture correction, and there are some bugs. If you try to change the coordinates: keep in mind that it only works when Y1 < Y2 < Y3 < Y4 , and there is also a bug when you try to draw a trapezoid with the paralel lines more vertical than horizontal.

EDIT2:

I found a converter. Here's the basic source code:
Code: [Select]
AxesOff
ClrDraw
[[1,1,1,1,1,1,1,1][1,0,1,0,1,0,1,1][1,1,0,1,0,1,0,1][1,0,1,0,1,0,1,1][1,1,0,1,0,1,0,1][1,0,1,0,1,0,1,1][1,1,0,1,0,1,0,1][1,1,1,1,1,1,1,1->[A]
4->dim(LDX
4->dim(LDU
4->dim(LDV
2->dim(LTX
2->dim(LTY
2->dim(LTU
2->dim(LTV
{50,40,80,10->LX
{10,11,60,61->LY
{1,8,1,8->LU
{1,1,8,8->LV
(LX(2)-LX(1))/(LY(2)-LY(1->LDX(1
(LX(3)-LX(1))/(LY(3)-LY(1->LDX(2
(LX(4)-LX(2))/(LY(4)-LY(2->LDX(3
(LX(4)-LX(3))/(LY(4)-LY(3->LDX(4
(LU(2)-LU(1))/(LY(2)-LY(1->LDU(1
(LV(2)-LV(1))/(LY(2)-LY(1->LDV(1
(LU(3)-LU(1))/(LY(3)-LY(1->LDU(2
(LV(3)-LV(1))/(LY(3)-LY(1->LDV(2
(LU(4)-LU(2))/(LY(4)-LY(2->LDU(3
(LV(4)-LV(2))/(LY(4)-LY(2->LDV(3
(LU(4)-LU(3))/(LY(4)-LY(3->LDU(4
(LV(4)-LV(3))/(LY(4)-LY(3->LDV(4
LX(1->LTX(1
LX(1->LTX(2
LU(1->LTU(1
LV(1->LTV(1
LU(1->LTU(2
LV(1->LTV(2
LY(1->Y
If [A](LU(1),LV(1
Then
Pxl-On(Y,LX(1
Else
Pxl-Off(Y,LX(1
End
For(Y,LY(1)+1,LY(2
LTX(1)+LDX(1->LTX(1
LTU(1)+LDU(1->LTU(1
LTV(1)+LDV(1->LTV(1
LTX(2)+LDX(2->LTX(2
LTU(2)+LDU(2->LTU(2
LTV(2)+LDV(2->LTV(2
For(X,LTX(1),LTX(2
(X-LTX(1))/(LTX(2)-LTX(1->T
round((1-T)*LTU(1)+T*LTU(2),0)->U
round((1-T)*LTV(1)+T*LTV(2),0)->V
If [A](U,V)
Then
Pxl-On(Y,round(X,0
Else
Pxl-Off(Y,round(X,0
End
End
End
For(Y,LY(2)+1,LY(3
LTX(1)+LDX(3->LTX(1
LTX(2)+LDX(2->LTX(2
LTU(1)+LDU(3->LTU(1
LTV(1)+LDV(3->LTV(1
LTU(2)+LDU(2->LTU(2
LTV(2)+LDV(2->LTV(2
For(X,LTX(1),LTX(2
(X-LTX(1))/(LTX(2)-LTX(1->T
round((1-T)*LTU(1)+T*LTU(2),0->U
round((1-T)*LTV(1)+T*LTV(2),0->V
If [A](U,V
Then
Pxl-On(Y,round(X,0
Else
Pxl-Off(Y,round(X,0
End
End
End
For(Y,LY(3)+1,LY(4)-1
LTX(1)+LDX(3->LTX(1
LTU(1)+LDU(3->LTU(1
LTV(1)+LDV(3->LTV(1
LTX(2)+LDX(4->LTX(2
LTU(2)+LDU(4->LTU(2
LTV(2)+LDV(4->LTV(2
For(X,LTX(1),LTX(2
(X-LTX(1))/(LTX(2)-LTX(1->T
round((1-T)*LTU(1)+T*LTU(2),0->U
round((1-T)*LTV(1)+T*LTV(2),0->V
If [A](U,V
Then
Pxl-On(Y,round(X,0
Else
Pxl-Off(Y,round(X,0
End
End
End
If [A](LU(4),LV(4
Then
Pxl-On(LY(4),LX(4
Else
Pxl-Off(LY(4),LX(4
End
DelVar LX
DelVar LY
DelVar LU
DelVar LV
DelVar [A]
DelVar LDU
DelVar LDV
DelVar LDX
DelVar LTU
DelVar LTV
DelVar LTX
DelVar LTY
Does anybody see what causes the wrong pixels in this program?
Title: Re: Texture drawing
Post by: thepenguin77 on July 20, 2011, 05:11:17 pm
Of course we would have to see the source, but I assume this has something to do with rounding. Most likely the pixels that look bad are split between two adjacent pixels and every now and then go the wrong way.
Title: Re: Texture drawing
Post by: ben_g on July 28, 2011, 06:31:46 pm
I've just rewritten the routine, but it doesn't draw anything. Not a single pixel :( .
What am I doing wrong?
Spoiler For the code:
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;TexQuad
;in: x1, y1, u1, v1, x2, y2, u2, v2, x3, y3, u3, v3, x4, y4, u4, v4
;out: textured quad is drawn to the buffer
TexQuad:
  ld a, (x1)
  ld b, a
  ld a, (x2)
  sub b
  ld h, a
  ld l, 0
  push hl
  ld a, (y1)
  ld b, a
  ld a, (y2)
  sub b
  ld d, a
  ld e, 0
  pop hl
  call divFP
  ld (dx1), hl
  ld a, (x1)
  ld b, a
  ld a, (x3)
  sub b
  ld h, a
  ld l, 0
  push hl
  ld a, (y1)
  ld b, a
  ld a, (y3)
  sub b
  ld d, a
  ld e, 0
  pop hl
  call divFP
  ld (dx2), hl
  ld a, (x2)
  ld b, a
  ld a, (x4)
  sub b
  ld h, a
  ld l, 0
  push hl
  ld a, (y2)
  ld b, a
  ld a, (y4)
  sub b
  ld d, a
  ld e, 0
  pop hl
  call divFP
  ld (dx3), hl
  ld a, (x3)
  ld b, a
  ld a, (x4)
  sub b
  ld h, a
  ld l, 0
  push hl
  ld a, (y3)
  ld b, a
  ld a, (y4)
  sub b
  ld d, a
  ld e, 0
  pop hl
  call divFP
  ld (dx4), hl
  ld a, (u1)
  ld b, a
  ld a, (u2)
  sub b
  ld h, a
  ld l, 0
  push hl
  ld a, (y1)
  ld b, a
  ld a, (y2)
  sub b
  ld d, a
  ld e, 0
  pop hl
  call divFP
  ld (du1), hl
  ld a, (u1)
  ld b, a
  ld a, (u3)
  sub b
  ld h, a
  ld l, 0
  push hl
  ld a, (y1)
  ld b, a
  ld a, (y3)
  sub b
  ld d, a
  ld e, 0
  pop hl
  call divFP
  ld (du2), hl
  ld a, (u2)
  ld b, a
  ld a, (u4)
  sub b
  ld h, a
  ld l, 0
  push hl
  ld a, (y2)
  ld b, a
  ld a, (y4)
  sub b
  ld d, a
  ld e, 0
  pop hl
  call divFP
  ld (du3), hl
  ld a, (u3)
  ld b, a
  ld a, (u4)
  sub b
  ld h, a
  ld l, 0
  push hl
  ld a, (y3)
  ld b, a
  ld a, (y4)
  sub b
  ld d, a
  ld e, 0
  pop hl
  call divFP
  ld (du4), hl
  ld a, (v1)
  ld b, a
  ld a, (v2)
  sub b
  ld h, a
  ld l, 0
  push hl
  ld a, (y1)
  ld b, a
  ld a, (y2)
  sub b
  ld d, a
  ld e, 0
  pop hl
  call divFP
  ld (dv1), hl
  ld a, (v1)
  ld b, a
  ld a, (v3)
  sub b
  ld h, a
  ld l, 0
  push hl
  ld a, (y1)
  ld b, a
  ld a, (y3)
  sub b
  ld d, a
  ld e, 0
  pop hl
  call divFP
  ld (dv2), hl
  ld a, (v2)
  ld b, a
  ld a, (v4)
  sub b
  ld h, a
  ld l, 0
  push hl
  ld a, (y2)
  ld b, a
  ld a, (y4)
  sub b
  ld d, a
  ld e, 0
  pop hl
  call divFP
  ld (dv3), hl
  ld a, (v3)
  ld b, a
  ld a, (v4)
  sub b
  ld h, a
  ld l, 0
  push hl
  ld a, (y3)
  ld b, a
  ld a, (y4)
  sub b
  ld d, a
  ld e, 0
  pop hl
  call divFP
  ld (dv4), hl
  ld a, (x1)
  ld h, a
  ld l, 0
  ld (tx1), hl
  ld (tx2), hl
  ld a, (u1)
  ld h, a
  ld l, 0
  ld (tu1), hl
  ld (tu2), hl
  ld a, (v1)
  ld h, a
  ld l, 0
  ld (tv1), hl
  ld (tv2), hl
  ld a, (y1)
  ld (ty), a

;TODO: plot first line

  ld a, (y1)
  inc a
  ld (ty), a

QuadDrawLoop1:
  ld hl, (tx1)
  ld de, (dx1)
  add hl, de
  ld (tx1), hl
  ld hl, (tu1)
  ld de, (du1)
  add hl, de
  ld (tu1), hl
  ld hl, (tv1)
  ld de, (dv1)
  add hl, de
  ld (tv1), hl
  ld hl, (tx2)
  ld de, (dx2)
  add hl, de
  ld (tx2), hl
  ld hl, (tu2)
  ld de, (du2)
  add hl, de
  ld (tu2), hl
  ld hl, (tv2)
  ld de, (dv2)
  add hl, de
  ld (tv2), hl

  ld hl, (tx1)
  ld (temp), hl      ;x = temp

QuadPlotLoop1:
  ld hl, (tx2)
  ld de, (tx1)
  subFP
  push hl
  ld hl, (temp)
  ld de, (tx1)
  subFP
  pop de
  call DivFP
  ld (temp2), hl   ;T = temp2
  ld hl, $0100
  ld de, (temp2)
  subFP
  ld bc, (tu1)
  call MulFP
  push de
  ld hl, (temp2)
  ld bc, (tu2)
  call MulFP
  pop hl
  add hl, de
  ld a, h
  ld (temp3), a      ;u = temp3
  ld hl, $0100
  ld de, (temp2)
  subFP
  ld bc, (tv1)
  call MulFP
  push de
  ld hl, (temp2)
  ld bc, (tv2)
  call MulFP
  pop hl
  add hl, de
  ld a, h
  ld (temp3+1), a      ;v = temp3+1
;Get the pixel at (u,v) from the texture
  ld   hl, (temp3+1)
  ld   h, 0

  ld   de, texture
  add   hl, de

  ld   a, (temp3)
  ld   b, a
  inc   b
  ld a, (hl)
shiftLoop1:
  rl   c
  djnz   shiftLoop1

  push af
  ld a, (ty)
  ld l, a
  ld de, (temp)
  ld a, d
  call GetPixel
  ld h, a
  pop af
  ld a, h
  jr c, setPixel1

ResPixel1:
  cpl
  and (hl)
  ld (hl), a
  jr EndPlot1

SetPixel1:
  or (hl)
  ld (hl), a

EndPlot1:
  ld hl, (temp)
  ld de, (tx2)
  inc h
  ld (temp), hl
  ld b, h
  ld a, d
  cp b
  jp nc, QuadPlotLoop1

  ld hl, ty
  inc (hl)
  ld a, (y2)
  cp (hl)
  jp nc, QuadDrawLoop1

QuadDrawLoop2:
  ld hl, (tx1)
  ld de, (dx3)
  add hl, de
  ld (tx1), hl
  ld hl, (tu1)
  ld de, (du3)
  add hl, de
  ld (tu1), hl
  ld hl, (tv1)
  ld de, (dv3)
  add hl, de
  ld (tv1), hl
  ld hl, (tx2)
  ld de, (dx2)
  add hl, de
  ld (tx2), hl
  ld hl, (tu2)
  ld de, (du2)
  add hl, de
  ld (tu2), hl
  ld hl, (tv2)
  ld de, (dv2)
  add hl, de
  ld (tv2), hl

  ld hl, (tx1)
  ld (temp), hl      ;x = temp

QuadPlotLoop2:
  ld hl, (tx2)
  ld de, (tx1)
  subFP
  push hl
  ld hl, (temp)
  ld de, (tx1)
  subFP
  pop de
  call DivFP
  ld (temp2), hl   ;T = temp2
  ld hl, $0100
  ld de, (temp2)
  subFP
  ld bc, (tu1)
  call MulFP
  push de
  ld hl, (temp2)
  ld bc, (tu2)
  call MulFP
  pop hl
  add hl, de
  ld a, h
  ld (temp3), a      ;u = temp3
  ld hl, $0100
  ld de, (temp2)
  subFP
  ld bc, (tv1)
  call MulFP
  push de
  ld hl, (temp2)
  ld bc, (tv2)
  call MulFP
  pop hl
  add hl, de
  ld a, h
  ld (temp3+1), a      ;v = temp3+1
;Get the pixel at (u,v) from the texture
  ld   hl, (temp3+1)
  ld   h, 0

  ld   de, texture
  add   hl, de

  ld   a, (temp3)
  ld   b, a
  inc   b
  ld a, (hl)
shiftLoop2:
  rl   c
  djnz   shiftLoop2

  push af
  ld a, (ty)
  ld l, a
  ld de, (temp)
  ld a, d
  call GetPixel
  ld h, a
  pop af
  ld a, h
  jr c, setPixel2

ResPixel2:
  cpl
  and (hl)
  ld (hl), a
  jr EndPlot2

SetPixel2:
  or (hl)
  ld (hl), a

EndPlot2:
  ld hl, (temp)
  ld de, (tx2)
  inc h
  ld (temp), hl
  ld b, h
  ld a, d
  cp b
  jp nc, QuadPlotLoop2

  ld hl, ty
  inc (hl)
  ld a, (y3)
  cp (hl)
  jp nc, QuadDrawLoop2

QuadDrawLoop3:
  ld hl, (tx1)
  ld de, (dx3)
  add hl, de
  ld (tx1), hl
  ld hl, (tu1)
  ld de, (du3)
  add hl, de
  ld (tu1), hl
  ld hl, (tv1)
  ld de, (dv3)
  add hl, de
  ld (tv1), hl
  ld hl, (tx2)
  ld de, (dx4)
  add hl, de
  ld (tx2), hl
  ld hl, (tu2)
  ld de, (du4)
  add hl, de
  ld (tu2), hl
  ld hl, (tv2)
  ld de, (dv4)
  add hl, de
  ld (tv2), hl

  ld hl, (tx1)
  ld (temp), hl      ;x = temp

QuadPlotLoop3:
  ld hl, (tx2)
  ld de, (tx1)
  subFP
  push hl
  ld hl, (temp)
  ld de, (tx1)
  subFP
  pop de
  call DivFP
  ld (temp2), hl   ;T = temp2
  ld hl, $0100
  ld de, (temp2)
  subFP
  ld bc, (tu1)
  call MulFP
  push de
  ld hl, (temp2)
  ld bc, (tu2)
  call MulFP
  pop hl
  add hl, de
  ld a, h
  ld (temp3), a      ;u = temp3
  ld hl, $0100
  ld de, (temp2)
  subFP
  ld bc, (tv1)
  call MulFP
  push de
  ld hl, (temp2)
  ld bc, (tv2)
  call MulFP
  pop hl
  add hl, de
  ld a, h
  ld (temp3+1), a      ;v = temp3+1
;Get the pixel at (u,v) from the texture
  ld   hl, (temp3+1)
  ld   h, 0

  ld   de, texture
  add   hl, de

  ld   a, (temp3)
  ld   b, a
  inc   b
  ld a, (hl)
shiftLoop3:
  rl   c
  djnz   shiftLoop3

  push af
  ld a, (ty)
  ld l, a
  ld de, (temp)
  ld a, d
  call GetPixel
  ld h, a
  pop af
  ld a, h
  jr c, setPixel3

ResPixel3:
  cpl
  and (hl)
  ld (hl), a
  jr EndPlot3

SetPixel3:
  or (hl)
  ld (hl), a

EndPlot3:
  ld hl, (temp)
  ld de, (tx2)
  inc h
  ld (temp), hl
  ld b, h
  ld a, d
  cp b
  jp nc, QuadPlotLoop3

  ld hl, ty
  inc (hl)
  ld a, (y2)
  cp (hl)
  jp nc, QuadDrawLoop3

  ret



getPixel:
   ld   h, 0
   ld   d, h
   ld   e, l
   
   add   hl, hl
   add   hl, de
   add   hl, hl
   add   hl, hl
   
   ld   e, a
   srl   e
   srl   e
   srl   e
   add   hl, de
   
   ld   de, PlotSScreen
   add   hl, de
   
   and   7
   ld   b, a
   ld   a, $80
   ret   z
   
   rrca
   djnz   $-1
   ret

Generated by the BBCode Converter (http://clrhome.co.cc/resources/bbify/ (http://clrhome.co.cc/resources/bbify/))

EDIT: the code is now syntax highlighted to make it more readable.
Title: Re: Texture drawing
Post by: ben_g on August 04, 2011, 03:50:22 pm
I've got goo news and bad news: the good news: I've got affine texture mapping to work on a computer. The bad news: I can't get it to work on a calc.
what am I doing wrong?
Computer
Calculator
(http://picturestack.com/485/591/ARQUntitled8Pe.png)(http://picturestack.com/485/770/wpAUntitled3Cu.gif)
Everything works just the way it's supposed to.In the first step (TriangleDrawLoop1), it just draws black pixels,
and in the secound draw loop, nothing is drawn.
Spoiler For GML source code:
dx1 = (x2-x1)/(y2-y1)
dx2 = (x3-x2)/(y3-y2)
dx3 = (x3-x1)/(y3-y1)
du1 = (u2-u1)/(y2-y1)
du2 = (u3-u2)/(y3-y2)
du3 = (u3-u1)/(y3-y1)
dv1 = (v2-v1)/(y2-y1)
dv2 = (v3-v2)/(y3-y2)
dv3 = (v3-v1)/(y3-y1)

tx1 = x1
tx2 = x1
tu1 = u1
tu2 = u1
tv1 = v1
tv2 = v1

surf = surface_create(24,24)
surface_set_target(surf)
draw_sprite(sprite0,-1,0,0)
surface_reset_target();

for(ty = y1; ty < y2; ty += 1){
    //draw_line(tx1,ty,tx2,ty)
    for(tx = tx2; tx <= tx1; tx += 1){
        if(tx1==tx2){
            tmp = 0
        }else{
            tmp = (tx - tx2)/(tx1-tx2)
        }
        draw_point_color(tx,ty,surface_getpixel(surf,floor((1-tmp)*tu2+tmp*tu1),floor((1-tmp)*tv2+tmp*tv1)))
    }
    tx1 += dx1
    tx2 += dx3
    tu1 += du1
    tu2 += du3
    tv1 += dv1
    tv2 += dv3
}


for(ty = y2; ty <= y3; ty += 1){
    //draw_line(tx1,ty,tx2,ty)
    for(tx = tx2; tx <= tx1; tx += 1){
        if(tx1==tx2){
            tmp = 0
        }else{
            tmp = (tx - tx2)/(tx1-tx2)
        }
        draw_point_color(tx,ty,surface_getpixel(surf,floor((1-tmp)*tu2+tmp*tu1),floor((1-tmp)*tv2+tmp*tv1)))
    }
    tx1 += dx2
    tx2 += dx3
    tu1 += du2
    tu2 += du3
    tv1 += dv2
    tv2 += dv3
}
draw_surface_stretched(surf,300,0,100,100)
surface_free(surf)

A surface is almost the same as a sprite.
Spoiler For z80 source:
DrawTriangle:
  ld a, (x1)
  ld b, a
  ld a, (x2)
  sub b
  ld h, a
  ld l, 0
  ld a, (y1)
  ld b, a
  ld a, (y2)
  sub b
  ld d, a
  ld e, 0
  call DivFP
  ld (dx1), hl
  ld a, (x2)
  ld b, a
  ld a, (x3)
  sub b
  ld h, a
  ld l, 0
  ld a, (y2)
  ld b, a
  ld a, (y3)
  sub b
  ld d, a
  ld e, 0
  call DivFP
  ld (dx2), hl
  ld a, (x1)
  ld b, a
  ld a, (x3)
  sub b
  ld h, a
  ld l, 0
  ld a, (y1)
  ld b, a
  ld a, (y3)
  sub b
  ld d, a
  ld e, 0
  call DivFP
  ld (dx3), hl
  ld a, (u1)
  ld b, a
  ld a, (u2)
  sub b
  ld h, a
  ld l, 0
  ld a, (y1)
  ld b, a
  ld a, (y2)
  sub b
  ld d, a
  ld e, 0
  call DivFP
  ld (du1), hl
  ld a, (u2)
  ld b, a
  ld a, (u3)
  sub b
  ld h, a
  ld l, 0
  ld a, (y2)
  ld b, a
  ld a, (y3)
  sub b
  ld d, a
  ld e, 0
  call DivFP
  ld (du2), hl
  ld a, (u1)
  ld b, a
  ld a, (u3)
  sub b
  ld h, a
  ld l, 0
  ld a, (y1)
  ld b, a
  ld a, (y3)
  sub b
  ld d, a
  ld e, 0
  call DivFP
  ld (du3), hl
  ld a, (v1)
  ld b, a
  ld a, (v2)
  sub b
  ld h, a
  ld l, 0
  ld a, (y1)
  ld b, a
  ld a, (y2)
  sub b
  ld d, a
  ld e, 0
  call DivFP
  ld (dv1), hl
  ld a, (v2)
  ld b, a
  ld a, (v3)
  sub b
  ld h, a
  ld l, 0
  ld a, (y2)
  ld b, a
  ld a, (y3)
  sub b
  ld d, a
  ld e, 0
  call DivFP
  ld (dv2), hl
  ld a, (v1)
  ld b, a
  ld a, (v3)
  sub b
  ld h, a
  ld l, 0
  ld a, (y1)
  ld b, a
  ld a, (y3)
  sub b
  ld d, a
  ld e, 0
  call DivFP
  ld (dv3), hl

  ld a, (x1)
  ld h, a
  ld l, 0
  ld (tx1), hl
  ld (tx2), hl
  ld a, (u1)
  ld h, a
  ld l, 0
  ld (tu1), hl
  ld (tu2), hl
  ld a, (v1)
  ld h, a
  ld l, 0
  ld (tv1), hl
  ld (tv2), hl

  ld a, (y1)
  ld (_ty), a

TriangleDrawLoop1:
  ld hl, (tx2)
  ld a, h
  ld (temp), a

TrianglePlotLoop1:
  ld hl, (tx1)
  ld de, (tx2)
  subFP
  push hl
  ld a, (temp)
  ld h, a
  ld l, 0
  ld de, (tx2)
  subFP
  pop de
  call DivFP
  ld (temp2), hl   ;tmp = temp2
  ld hl, $0100
  ld de, (temp2)
  subFP
  ld bc, (tu2)
  call MulFP
  push de
  ld hl, (temp2)
  ld bc, (tu1)
  call MulFP
  pop hl
  add hl, de
  ld a, h
  ld (temp3), a      ;u = temp3
  ld hl, $0100
  ld de, (temp2)
  subFP
  ld bc, (tv2)
  call MulFP
  push de
  ld hl, (temp2)
  ld bc, (tv1)
  call MulFP
  pop hl
  add hl, de
  ld a, h
  ld (temp3+1), a   ;v = temp3+1

  ld a, (temp3+1)
  ld l, a
  ld h, 0

  ld de, texture
  add hl, de

  ld a, (temp3)
  ld b, a
  inc b
  ld a, (hl)
  ld c, a
TshiftLoop1:
  rl   c
  djnz   TshiftLoop1

  push af
 
  ld a, (_ty)
  ld l, a
  ld a, (temp)      ;tx = temp
  call GetPixel
  ld b, a
  pop af
  jr c, TSetPixel1

TResPixel1:
  ld a, b
  cpl
  and (hl)
  ld (hl), a
  jr TEndPlot1

TSetPixel1:
  ld a, b
  or (hl)
  ld (hl), a

TEndPlot1:
  ld hl, temp
  inc (hl)
  ld a, (tx1+1)
  cp (hl)
  jp nc, TrianglePlotLoop1

  ld hl, (tx1)
  ld de, (dx1)
  add hl, de
  ld (tx1), hl
  ld hl, (tx2)
  ld de, (dx3)
  add hl, de
  ld (tx2), hl

  ld hl, _ty
  inc (hl)
  ld a, (y2)
  cp (hl)
  jp nc, TriangleDrawLoop1

  ld a, (x2)
  ld h, a
  ld l, 0
  ld (tx1), hl

TriangleDrawLoop2:
  ld hl, (tx2)
  ld a, h
  ld (temp), a

TrianglePlotLoop2:
  ld hl, (tx1)
  ld de, (tx2)
  subFP
  push hl
  ld a, (temp)
  ld h, a
  ld l, 0
  ld de, (tx2)
  subFP
  pop de
  call DivFP
  ld (temp2), hl   ;tmp = temp2
  ld hl, $0100
  ld de, (temp2)
  subFP
  ld bc, (tu2)
  call MulFP
  push de
  ld hl, (temp2)
  ld bc, (tu1)
  call MulFP
  pop hl
  add hl, de
  ld a, h
  ld (temp3), a      ;u = temp3
  ld hl, $0100
  ld de, (temp2)
  subFP
  ld bc, (tv2)
  call MulFP
  push de
  ld hl, (temp2)
  ld bc, (tv1)
  call MulFP
  pop hl
  add hl, de
  ld a, h
  ld (temp3+1), a   ;v = temp3+1

  ld a, (temp3+1)
  ld l, a
  ld h, 0

  ld de, texture
  add hl, de

  ld a, (temp3)
  ld b, a
  inc b
  ld a, (hl)
  ld c, a
TshiftLoop2:
  rl   c
  djnz   TshiftLoop2

  push af
 
  ld a, (_ty)
  ld l, a
  ld a, (temp)      ;tx = temp
  call GetPixel
  ld b, a
  pop af
  jr c, TSetPixel2

TResPixel2:
  ld a, b
  cpl
  and (hl)
  ld (hl), a
  jr TEndPlot2

TSetPixel2:
  ld a, b
  or (hl)
  ld (hl), a

TEndPlot2:
  ld hl, temp
  inc (hl)
  ld a, (tx1+1)
  cp (hl)
  jp nc, TrianglePlotLoop2

  ld hl, (tx1)
  ld de, (dx2)
  add hl, de
  ld (tx1), hl
  ld hl, (tx2)
  ld de, (dx3)
  add hl, de
  ld (tx2), hl

  ld hl, _ty
  inc (hl)
  ld a, (y2)
  cp (hl)
  jp nc, TriangleDrawLoop2

  ret



getPixel:
   ld   h, 0
   ld   d, h
   ld   e, l
   
   add   hl, hl
   add   hl, de
   add   hl, hl
   add   hl, hl
   
   ld   e, a
   srl   e
   srl   e
   srl   e
   add   hl, de
   
   ld   de, PlotSScreen
   add   hl, de
   
   and   7
   ld   b, a
   ld   a, $80
   ret   z
   
   rrca
   djnz   $-1
   ret

Generated by the BBCode Converter (http://clrhome.tk/resources/bbify/ (http://clrhome.tk/resources/bbify/))

What am i doing wrong?
Title: Re: Texture drawing
Post by: LincolnB on August 04, 2011, 09:54:12 pm
did that basic to assembly source conversion thing work at all?
Title: Re: Texture drawing
Post by: ben_g on August 05, 2011, 02:28:11 pm
did that basic to assembly source conversion thing work at all?
nope, I haven't found any program that actually converts anything, so I've ported it manually, but i must have made a mistake, ass this is clearly not doing what it should do.

BTW: this routine draws the triangle from top to bottom, which means that the points needs to be in the right order, so does anybody knows a routine to sort the points based on their Y coordinate?
Title: Re: Texture drawing
Post by: ztrumpet on August 06, 2011, 08:49:00 am
BTW: this routine draws the triangle from top to bottom, which means that the points needs to be in the right order, so does anybody knows a routine to sort the points based on their Y coordinate?
I made a routine thst would work for this in Cube Droid, but that's in Axe so I guess it doesn't help.
Title: Re: Texture drawing
Post by: ben_g on August 06, 2011, 03:05:29 pm
Maybe it does help. If i know how it should be done, then i might be able to rewrite it in asm. And i need a good sorting algorithm for when i'm going to add z-ordering to the engine.

EDIT: I just found a mistake in my code, and now, the triangle is fully drawn, but still just solid black.

EDIT2: I just noticed an other mistake in the source, which made texture mapping impossible. This was not the full cause of the texture not being mapped, however, ass the routine is still drawing a solid black triangle.

EDIT3: Finally!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
(http://picturestack.com/666/827/DVZfinallyvkk.gif)

the third mistake was caused by a very stupid mistake: I have a text file in the project folder named 'Routines.txt', in which all names of all routines in my app are written, with the arguments and the registers that they destroy. A while ago, i replaced the fixed-point multiplication routine, which had other arguments, so this problem was caused by an outdated routines file

EDIT4: it now draws only 1.29 triangles every second, but I'm optimizing it right now. The first thing I'll do is replace the fixed-point math for every pixel with a much simpler one, which only has to be calculated for each horizontal line. The rest of the line can then be calculated with a simple add command. An other optimization I'll try to add is calling getPixel only once for every scan line, instead of every pixel, then using a right rotation to get the mask.
Title: Re: Texture drawing
Post by: ben_g on August 08, 2011, 07:47:30 pm
I discovered an other problem: when i combine it wih my 3D engine, this happens:
(http://picturestack.com/847/177/HZCtestRXE.gif)
For an instant, it's drawn correctely, then only a part is drawn

Does anyody knows what might be causing this?
Title: Re: Texture drawing
Post by: p2 on August 09, 2011, 08:25:11 am
It seems like if it first draws everything and then deletes the other parts again.

maybe the program draws everything the first tim, but only draws a part of it again, it you toggle the camera!
Title: Re: Texture drawing
Post by: ben_g on August 11, 2011, 02:17:09 pm
The camera stays at the same position, and the arguments passed to the triangle drawing routine are always the same, so I wonder why it draws it correctly the first time, and only draws a part of it the other times.

BTW: by filling the graphic buffer every frame, I noticed that the rest of the triangle is drawn white, but it is still drawn.
Title: Re: Texture drawing
Post by: chattahippie on August 11, 2011, 04:48:06 pm
Although I know it isn't working correctly right now, this is amazing!
I would never have the patience to debug/ create as much as you have.
I hope you find the errors, it seems like you kinda know where the code freaks out.
Title: Re: Texture drawing
Post by: fb39ca4 on August 11, 2011, 06:17:38 pm
Maybe there was something you forgot to reset - like a register that was zero the first time around but never got reset to zero in the second frame.
Title: Re: Texture drawing
Post by: ben_g on August 11, 2011, 06:38:26 pm
This is the start and loop code: I don't think anything is set or reset:
the 3D engine is passing the same arguments to it, so i guess the trianlge drawing routine itself couses it, most lickely in the texture handling code 'couse it's the texture that got messed up
Code: [Select]
Start:
  di
  call ClearGbuf
  call fastCopy
  ld a, 64*3
  ld (direction), a
  in a,($02)
  rla
  sbc a, a
  out ($20), a

  ld hl, 0
  ld (x), hl
  ld hl, $0200
  ld (y), hl

SpelLus:
  call ClearGBuf

  ld a, $FF
  ld (plotsscreen), a
  ld hl, plotsscreen
  ld de, plotsscreen+1
  ld bc, 767
  ldir

  ld hl, (x)
  ld (xfrom), hl
  ld hl, (y)
  ld (yfrom), hl
  ld hl, 0
  ld (zfrom), hl
  ld (zto), hl
  ld a, 64
  ld b, a
  ld a, (direction)
  add a, b
  call SinA
  ld de, (x)
  add hl, de
  ld (xto), hl
  ld a, (direction)
  call SinA
  ld de, (y)
  add hl, de
  ld (yto), hl
  ld hl, $0100
  ld (zup), hl
  ld hl, 0
  ld (xup), hl
  ld (yup), hl
  call InitView

  ld hl, -256
  ld (xpoint), hl
  ld hl, 0
  ld (ypoint), hl
  ld hl, -$0100
  ld (zpoint), hl
  call C3DTo2D
  ld hl, (screenx)
  ld (screenx2), hl
  ld hl, (screeny)
  ld (screeny2), hl
  ld hl, 256
  ld (xpoint), hl
  ld hl, 0
  ld (ypoint), hl
  ld hl, -$0100
  ld (zpoint), hl
  call C3DTo2D
  ld hl, (screenx)
  ld (screenx3), hl
  ld hl, (screeny)
  ld (screeny3), hl
  ld hl, -256
  ld (xpoint), hl
  ld hl, 0
  ld (ypoint), hl
  ld hl, $0100
  ld (zpoint), hl
  call C3DTo2D

  ld a, (screenx)
  ld (x1), a
  ld a, (screeny)
  ld (y1), a
  ld a, 0
  ld (u1), a
  ld (v1), a
  ld a, (screenx2)
  ld (x2), a
  ld a, (screeny2)
  ld (y2), a
  ld a, 0
  ld (u2), a
  ld a, 8
  ld (v2), a
  ld a, (screenx3)
  ld (x3), a
  ld a, (screeny3)
  ld (y3), a
  ld a, 8
  ld (u1), a
  ld (v1), a

  call DrawTriangle

  call FastCopy
 
  ;knoppen
  ld a, $FE
  out (1), a
  in a, (1)
  bit 0, a
  call z, MoveBack
  bit 3, a
  call z, MoveForward
  bit 1, a
  call z, TurnLeft
  bit 2, a
  call z, TurnRight
  ld a, %11111101
  out ($01), a
  in a, ($01)
  bit 6, a
  jp z, Einde
  jp spelLus
 
MoveBack:
  push af
  ld a, (direction)
  ld b, 64
  add a, b
  call SinA
  call NegHL
  ld de, $0A00
  call DivFP
  ld de, (X)
  add hl, de
  ld (X), hl
  ld a, (direction)
  call SinA
  call NegHL
  ld de, $0A00
  call DivFP
  ld de, (Y)
  add hl, de
  ld (Y), hl
  pop af
  ret
MoveForward:
  push af
  ld a, (direction)
  ld b, 64
  add a, b
  call SinA
  ld de, $0A00
  call DivFP
  ld de, (X)
  add hl, de
  ld (X), hl
  ld a, (direction)
  call SinA
  ld de, $0A00
  call DivFP
  ld de, (Y)
  add hl, de
  ld (Y), hl
  pop af
  ret
TurnLeft:
  push af
  ld a, (direction)
  inc a
  ld (direction), a
  pop af
  ret
TurnRight:
  ld a, (direction)
  dec a
  ld (direction), a
  ret
 
Einde:
  ;Key port resetten
  ld a, $FF
  out ($01), a
  call ClearGbuf
  call fastCopy
  ld hl, 0
  ld (CurRow), hl
  EI
  bjump(_JForceCmdNoChar)
Title: Re: Texture drawing
Post by: ben_g on August 16, 2011, 05:04:00 pm
I think I've solved all bugs.
here's a screenshot of my triangle drawing routine and 3D engine in action:
(http://picturestack.com/528/548/d9Nscreenshotqnb.gif)
It now not only fully works, it's also way more optimised and now all of the fixed-point calculations only have to be done once every triangle instead of once every scan line (or every pixel in the first version).
Title: Re: Texture drawing
Post by: zeldaking on August 16, 2011, 05:05:23 pm
That looks very nice, good job. Is this for some other project?
Title: Re: Texture drawing
Post by: fb39ca4 on August 16, 2011, 05:12:29 pm
That looks very nice, though it looks like there is a "seam" between the two triangles you are drawing. Is that intentional?
Title: Re: Texture drawing
Post by: chattahippie on August 16, 2011, 05:14:02 pm
That looks very nice, though it looks like there is a "seam" between the two triangles you are drawing. Is that intentional?

I think that he is showing off it's 3d aspect by tilting them, as if a square was folded partially
Title: Re: Texture drawing
Post by: ben_g on August 16, 2011, 05:14:26 pm
That looks very nice, good job. Is this for some other project?
Yes, for a first person shooter.I'm not giving much information about it (just in case it won't work).

(Yet) an other question: what should be the best (when you look at memory and speed) way to do z-ordering? a z-buffer (which contains the depth of every pixel) or to save the avarage depth of every polygon, then sort the polygons and draw them in the correct order (furthest to nearest)?

EDIT:
That looks very nice, though it looks like there is a "seam" between the two triangles you are drawing. Is that intentional?
It's not intentional. It's caused by the texture being rotated a bit differently on the two triangles. This is just the way affine texture mapping works.

Title: Re: Texture drawing
Post by: ztrumpet on August 16, 2011, 07:18:57 pm
That looks awesome, ben_g.  Great job. :D
Title: Re: Texture drawing
Post by: fb39ca4 on August 16, 2011, 07:31:27 pm
It depends on the situation. When there isn't very many polygons, sorting is faster, but past a certain number, (I think around a hundred) the sorting algorithm becomes too slow and z-buffering wins. Also keep in mind only z buffering is able to correctly show intersecting polygons.
Title: Re: Texture drawing
Post by: ben_g on August 18, 2011, 02:21:24 pm
It depends on the situation. When there isn't very many polygons, sorting is faster, but past a certain number, (I think around a hundred) the sorting algorithm becomes too slow and z-buffering wins. Also keep in mind only z buffering is able to correctly show intersecting polygons.
I know z buffering is only able to correctely show intersecting polygons, but also: one byte isn't accurate enough for polygons close to each other, so I need two byter for every pixel on the screen, so that would make 1228 bytes, which is really much, and I'm wondering if it's worth it to use that many bytes for only the graphical part.