0 Members and 4 Guests are viewing this topic.
Oh, and it's not really 3D... Raycasting is the word, but it's pretty fast.
You should probably ask in the proper sub-forum, else fewer people will find your question.
else, I have little probleme with a scaling spirite routine that allow scale something like that /!/ !---> the side of the surface doesn't need to be vertical or horizontal->it's very buggy, and I am not sure of the algorithm....if anyone have a little idea to do this , it's will be really helpful !
Also, I like the splash screen.
The fire looks cool, but the engine itself looks a bit slow. Is the screenshot taken at 8 or 15 MHz and does it slow down a lot when adding more polygons and game mechanics?
If you mean textures by that, I have some code lying around, but it's in asm. But I can give you the algorithm if you want too.
The most frequentely used shape for mapping textures is a triangle, so first off all, we are going to need a triangle drawing routine. For that, we need the points. We'll define point1 as (x1, y1, u1, v1), point 2 as (x2, y2, u2, v2) and point3 as (x3,y3,u3,v3). The u's and v's represent texture coordinates. We don't really need then yet, but implementing them now will make things easyer later on. The variables are all integers, preferably 8-bit.We are going to draw the triangle using a horizontal scanline than moves down. To do this, we first need to sort the three points based on their Y coordinate, from smallest to largest. You can do that like this: (pseudocode)Code: [Select]if(Y1>Y2){ exchange X1 and X2 exchange Y1 and Y2 exchange u1 and u2 exchange v1 and v2}if(Y2>Y3){ exchange X2 and X3 exchange Y2 and Y3 exchange u2 and u3 exchange v2 and v3}if(Y1>Y3){ exchange X1 and X3 exchange Y1 and Y3 exchange u1 and u3 exchange v1 and v3}Now the points are sorted. Before we start drawing, we need to calculate some values. Similar calculations will have to be done with the texture coordinates, but we'll leave those for later. For these calculations, you need at least 8.8 fixed point numbers. Higher accuracy might be needed if you're drawing big textured surfaces which are for a large part outside of the screen. When it will be almost fully inside the screen, 8.8 should be fine.Code: [Select]du1 = (x2-x1)/(y2-y1)du2 = (x3-x1)/(y3-y1)du3 = (x3-x2)/(y3-y2)These values represent the angle of the edges of the triangle. This is used to check how our scanline should change when we move a row down.Before we start the drawing loop, there are still 4 more variables to initialize: tx, tx1, tx2 and ty.tx1 and tx2 are the x of the start and end of the scanline. They are fixed-point variables, to keep it reasonably accurate. ty and tx are integer values. ty represents the Y of a scanline, tx represents the x of the pixel we're drawing in the scanline. We'll initialize those the following way:Code: [Select]tx1=tx2=x1ty=y1Now, we can finally start with the drawing loop:Code: [Select]Drawn = 0DrawingLoop:while (ty < y2){ //draw the scanline //to see if the rest is working, you can use axe's built-in line drawing routine, to see if the rest is working. Replace the code below this line by Line(tx1,ty,tx2,ty) tx = min(tx1,tx2) //only take integer part, or round. while (tx<=max(tx1,tx2)){ SetPixel(tx,ty) tx += 1 } //the code below this line is important even if you have used axe's line drawing routine tx1 += dx1 tx2 += dx2}if(drawn == 0){ y2 = y3 dx2 = dx3 drawn = 1 goto DrawingLoop}Now you should have a working triangle drawing routine. If the triangle looks weird, try exchanging some dx variables. If it draws nothing at all, or fills the entire screen or gets stuck in an infinite loop, check if the points are ordered well. When you got it to work, don't forget to change the Line( instruction by the pixel-by-pixel scanline drawing code. You'll need this for the textures.To draw the textures, we need some additional variables for the texture coordinates. Those are calculated very simular to the variables to change the x-position for every scanline.We'll start by adding something to this code:Code: [Select]du1 = (x2-x1)/(y2-y1)du2 = (x3-x1)/(y3-y1)du3 = (x3-x2)/(y3-y2)I just noticed I made a mistake yesterday. The du's should be renamed into dx's. Then we'll add similar code with u's and v's instaed of x's. So the code will become this:Code: [Select]dx1 = (x2-x1)/(y2-y1)dx2 = (x3-x1)/(y3-y1)dx3 = (x3-x2)/(y3-y2)du1 = (u2-u1)/(y2-y1)du2 = (u3-u1)/(y3-y1)du3 = (u3-u2)/(y3-y2)dv1 = (v2-v1)/(y2-y1)dv2 = (v3-v1)/(y3-y1)dv3 = (v3-v2)/(y3-y2)The du's and dv's stand for differences in texture coordinates.Behind that code, there was this:Code: [Select]tx1=tx2=x1ty=y1Now, we'll add the texture coordinates to it:Code: [Select]tx1=tx2=x1tu1=tu2=u1tv1=tv2=v1ty=y1The rest of the code is a bit different, but it shouldn't be too hard to implement in your programCode: [Select]Drawn = 0DrawingLoop:while (ty < y2){ //initialize some variables for the texture if(tx1<tx2){ tdu=(tu2-tu1)/(tx2-tx1) tdv=(tv2-tv1)/(tx2-tx1) tu=tu1 tv=tv1 //unlike tx and ty, tu and tv are fixed-point variables } else { tdu=(tu1-tu2)/(tx1-tx2) tdv=(tv1-tv2)/(tx1-tx2) tu=tu2 tv=tv2 //unlike tx and ty, tu and tv are fixed-point variables } //draw the scanline while (tx<=max(tx1,tx2)){ #if(8x8_texture) //whit this, I mean that you have to shoose between 8x8 and 16x16 for textures. Don't actually code it as an if. if(bit(round(tu),(Texture+round(tv))){ setPixel(tx,ty) }else{ resPixel(tx,ty) //res means white, set means black } #else if(16by16_Texture) if(bit16(round(tu),(round(tv)*2+Texture)){ //IMPORTANT: use a 16-bit bit checking instruction (make it yourself if you're programming in asm) setPixel(tx,ty) }else{ resPixel(tx,ty) } tx += 1 tu += tdu tv += tdv } tx1 += dx1 tx2 += dx2}if(drawn == 0){ y2 = y3 u2=u3 v2=v3 dx2 = dx3 du2=du3 dv2=dv3 drawn = 1 goto DrawingLoop}
if(Y1>Y2){ exchange X1 and X2 exchange Y1 and Y2 exchange u1 and u2 exchange v1 and v2}if(Y2>Y3){ exchange X2 and X3 exchange Y2 and Y3 exchange u2 and u3 exchange v2 and v3}if(Y1>Y3){ exchange X1 and X3 exchange Y1 and Y3 exchange u1 and u3 exchange v1 and v3}
du1 = (x2-x1)/(y2-y1)du2 = (x3-x1)/(y3-y1)du3 = (x3-x2)/(y3-y2)
tx1=tx2=x1ty=y1
Drawn = 0DrawingLoop:while (ty < y2){ //draw the scanline //to see if the rest is working, you can use axe's built-in line drawing routine, to see if the rest is working. Replace the code below this line by Line(tx1,ty,tx2,ty) tx = min(tx1,tx2) //only take integer part, or round. while (tx<=max(tx1,tx2)){ SetPixel(tx,ty) tx += 1 } //the code below this line is important even if you have used axe's line drawing routine tx1 += dx1 tx2 += dx2}if(drawn == 0){ y2 = y3 dx2 = dx3 drawn = 1 goto DrawingLoop}
dx1 = (x2-x1)/(y2-y1)dx2 = (x3-x1)/(y3-y1)dx3 = (x3-x2)/(y3-y2)du1 = (u2-u1)/(y2-y1)du2 = (u3-u1)/(y3-y1)du3 = (u3-u2)/(y3-y2)dv1 = (v2-v1)/(y2-y1)dv2 = (v3-v1)/(y3-y1)dv3 = (v3-v2)/(y3-y2)
tx1=tx2=x1tu1=tu2=u1tv1=tv2=v1ty=y1
Drawn = 0DrawingLoop:while (ty < y2){ //initialize some variables for the texture if(tx1<tx2){ tdu=(tu2-tu1)/(tx2-tx1) tdv=(tv2-tv1)/(tx2-tx1) tu=tu1 tv=tv1 //unlike tx and ty, tu and tv are fixed-point variables } else { tdu=(tu1-tu2)/(tx1-tx2) tdv=(tv1-tv2)/(tx1-tx2) tu=tu2 tv=tv2 //unlike tx and ty, tu and tv are fixed-point variables } //draw the scanline while (tx<=max(tx1,tx2)){ #if(8x8_texture) //whit this, I mean that you have to shoose between 8x8 and 16x16 for textures. Don't actually code it as an if. if(bit(round(tu),(Texture+round(tv))){ setPixel(tx,ty) }else{ resPixel(tx,ty) //res means white, set means black } #else if(16by16_Texture) if(bit16(round(tu),(round(tv)*2+Texture)){ //IMPORTANT: use a 16-bit bit checking instruction (make it yourself if you're programming in asm) setPixel(tx,ty) }else{ resPixel(tx,ty) } tx += 1 tu += tdu tv += tdv } tx1 += dx1 tx2 += dx2}if(drawn == 0){ y2 = y3 u2=u3 v2=v3 dx2 = dx3 du2=du3 dv2=dv3 drawn = 1 goto DrawingLoop}