User Tag List

Results 1 to 8 of 8

Thread: Ray Caster Demo by BlueKnight

  1. #1
    Administrator War Lord's Avatar
    Join Date
    Feb 2000
    Age
    40
    Posts
    6,028
    Mentioned
    54 Post(s)
    Tagged
    0 Thread(s)
    vBActivity - Stats
    Points
    1,448
    Level
    12
    vBActivity - Bars
    Lv. Percent
    89.14%

    Ray Caster Demo by BlueKnight

    I want to get ahold of this quest, and unfortunately, it was hosted on a crap file share site that was only around for a year or so.
    If anyone has it lying around, I will PayPal you $10 for it to be sitting in my inbox. Someone has to be a data hoarder that doesn't delete anything.




  2. #2
    Is this the end?
    ZC Developer
    Saffith's Avatar
    Join Date
    Jan 2001
    Age
    41
    Posts
    3,389
    Mentioned
    178 Post(s)
    Tagged
    6 Thread(s)
    vBActivity - Stats
    Points
    6,430
    Level
    24
    vBActivity - Bars
    Lv. Percent
    69.57%
    https://www.dropbox.com/s/xoxuzptnkb...aster.qst?dl=0

    As far as I know, that's the only version he ever released. Here's the script, if you're interested.

    Spoiler: show
    Code:
    /////////////////////////////////////////////////////
    /////// Raycasting Engine Script, version 0.2 ///////
    /////// by blue_knight						  ///////
    /////////////////////////////////////////////////////
    /////////////////////////////////////////////////////
    // This is a fun little script
    // that renders the current screens in first person
    // using raycasting and column rendering.
    // X, Y is on the horizontal plane.
    // Z is up in 3D space.
    // This script has no set limits, except the map limit
    // 16x8 screens.
    /////////////////////////////////////////////////////
    
    const int scrWidth  = 256;
    const int scrHeight = 176;
    
    ffc script Raycaster
    {
    	/////////////////////////////
    	// startX     : start X position in virtual space.
    	// startY     : start Y position in virtual space.
    	// BackgroundTiles : Tile index for the background.
    	/////////////////////////////
    	void run(int startX, int startY, int BackgroundTiles)
    	{
    		//use virtual coordinates for Link's position.
    		//since he is not displayed, we don't bother keeping local coordinates, so Link's position is forced to the center.
    		float camPos_X = startX;
    		float camPos_Y = startY;
    		float camDir_X;
    		float camDir_Y;
    		float camYaw = 0;
    		float moveSpeed = 1.0;
    		float playerRadius = 16;
    		
    		//ginormous array...
    		int map_combo[1024];	//holds the 32x32 area centered on the camera.
    		int map_left_x=0;
    		int map_left_y=0;
    		
    		int map_cenX = 0;
    		int map_cenY = 0;
    		
    		int curScreen = Game->GetCurScreen();
    		int curMap = Game->GetCurMap();
    	
    		while (true)
    		{
    			//update the movement.
    			if ( Link->InputLeft )
    				camYaw-=2;
    			else if ( Link->InputRight )
    				camYaw+=2;
    				
    			if (camYaw < 0 )
    				camYaw += 360;
    			else if ( camYaw >= 360 )
    				camYaw -= 360;
    			
    			camDir_X = Cos(camYaw);
    			camDir_Y = Sin(camYaw);
    			
    			float newPosX = camPos_X;
    			float newPosY = camPos_Y;
    			float travelDirX;
    			float travelDirY;
    			bool bCollisionNeeded = false;
    			if ( Link->InputUp )
    			{
    				newPosX = newPosX + camDir_X*moveSpeed;
    				newPosY = newPosY + camDir_Y*moveSpeed;
    				bCollisionNeeded = true;
    				
    				travelDirX = camDir_X;
    				travelDirY = camDir_Y;
    			}
    			else if ( Link->InputDown )
    			{
    				newPosX = newPosX - camDir_X*moveSpeed;
    				newPosY = newPosY - camDir_Y*moveSpeed;
    				bCollisionNeeded = true;
    				
    				travelDirX = -camDir_X;
    				travelDirY = -camDir_Y;
    			}
    			
    			//Super basic collision for now.
    			//If we're intersecting a solid combo after moving, we revert the move.
    			//note that we actually check ahead in the direction of travel so we don't get too close to
    			//the wall.
    			if ( bCollisionNeeded )
    			{
    				if ( ComboSolid( Floor(newPosX+travelDirX*playerRadius), Floor(newPosY+travelDirY*playerRadius), curMap, curScreen ) )
    				{
    					newPosX = camPos_X;
    					newPosY = camPos_Y;
    				}
    			}
    			camPos_X = newPosX;
    			camPos_Y = newPosY;
    			
    			//Read the area around the camera into an array
    			//whenever we change cells.
    			//This way we don't have to call GetComboFromTileIndex() or Game->GetComboData()
    			//up to 16 times per ray.
    			//This improves our performance by 40% or more.
    			int mx = camPos_X>>4;
    			int my = camPos_Y>>4;
    			if ( mx != map_cenX || my != map_cenY )
    			{
    				map_cenX = mx;
    				map_cenY = my;
    				map_left_x = Max(mx-16,0);
    				map_left_y = Max(my-16,0);
    				for (int y=0; y<32; y++)
    				{
    					int yy = y+map_left_y;
    					for (int x=0; x<32; x++)
    					{
    						int xx = x+map_left_x;
    						map_combo[y*32+x] = GetComboFromTileIndex(xx, yy, curMap, curScreen);
    					}
    				}
    			}
    			
    			//Finally draw the world.
    			DrawWorld( camDir_X, camDir_Y, camPos_X, camPos_Y, BackgroundTiles, map_combo, map_left_x, map_left_y );
    			
    			DisableInput();
    			
    			Waitframe();
    		}
    	}
    	
    	void DisableInput()
    	{
    		Link->X = 128;
    		Link->Y = 88;
    		Link->InputLeft = false;
    		Link->InputRight = false;
    		Link->InputUp = false;
    		Link->InputDown = false;
    		Link->InputA = false;
    		Link->InputB = false;
    		Link->InputL = false;
    		Link->InputR = false;
    		Link->InputStart = false;
    		Link->InputEx1 = false;
    		Link->InputEx2 = false;
    		Link->InputEx3 = false;
    		Link->InputEx4 = false;
    	}
    	
    	bool ComboSolid(int x, int y, int map, int curScr)
    	{
    		bool solid = false;
    		
    		int cx = (x>>4)&15;
    		int cy = (y>>4)%11;
    		
    		int scr = curScr;
    		scr += ( x>>8 );
    		scr += ( Floor(y/176)<<4 );
    		
    		int s = Game->GetComboSolid( map, scr, (cy<<4)+cx );
    		if ( s != 0 )
    			solid = true;
    			
    		return solid;
    	}
    	
    	int GetComboFromTileIndex(int tx, int ty, int map, int curScr)
    	{
    		int cx = tx&15;
    		int cy = ty%11;
    		
    		int scr = curScr;
    		scr += ( tx>>4 );
    		scr += ( Floor(ty/11)<<4 );
    		
    		return Game->GetComboData( map, scr, (cy<<4)+cx );
    	}
    		
    	//draw the "3D" world.
    	void DrawWorld(float camDirX, float camDirY, float cX, float cY, int BackgroundTiles, int map_combo, int map_left_x, int map_left_y)
    	{
    		float cenY = scrHeight*0.5;
    		
    		//This camera has no pitch, though looking up and down can be faked later.
    		//Anyway, the camera plane is perpendicular to the camera direction, 
    		//so a simple 2D "perp product" is good enough [i.e. P(x,y) = (-Dy,Dx)]
    		float planeX = -camDirY;
    		float planeY =  camDirX;
    				
    		//we do raycasting in "map space", where each tile = 1 unit.
    		float camX = cX/16;
    		float camY = cY/16;
    		
    		int mapX = Floor(camX);
    		int mapY = Floor(camY);
    		
    		//maximum extents, 8x8 screens for now.
    		int maxTileX = map_left_x+32;
    		int maxTileY = map_left_y+32;
    		
    		//maximum number of raycasting steps. Setting this lower
    		//will improve performance, setting it higher allows more distant walls to be rendered.
    		int MAX_STEPS = 16;
    		
    		//Draw the background.
    		Screen->DrawTile(1, 0, 0, BackgroundTiles, 1, 11, 0, 256, 176, 0, 0, 0, 0, false, 128);
    				
    		//Note that we're pixel doubling for performance, later this should be an option
    		//for people with fast computers.
    		for (int x=0; x<scrWidth; x+=2)
    		{
    			int mx = mapX;
    			int my = mapY;
    			
    			//compute the screen ray from the x position and camera paramters.
    			float sx = (2 * x/scrWidth) - 1;
    			float rayDirX = camDirX + planeX*sx;
    			float rayDirY = camDirY + planeY*sx;
    			
    			//compute the DDA parameters, will detail in some documentation later.
    			float rXX = rayDirX*rayDirX;
    			float rYY = rayDirY*rayDirY;
    			
    			float deltaDistX = 32767;
    			float deltaDistY = 32767;
    			if ( rXX != 0 ) deltaDistX = Sqrt( 1.0 + rYY/rXX );
    			if ( rYY != 0 ) deltaDistY = Sqrt( 1.0 + rXX/rYY );
    		
    			int stepX;
    			int stepY;
    			float sideDistX;
    			float sideDistY;
    			if ( rayDirX < 0 )
    			{ stepX = -1; sideDistX = (camX - mx) * deltaDistX; }
    			else
    			{ stepX = 1; sideDistX = (mx + 1.0 - camX)*deltaDistX; }
    			
    			if ( rayDirY < 0 )
    			{ stepY = -1; sideDistY = (camY - my)*deltaDistY; }
    			else
    			{ stepY = 1; sideDistY = (my + 1.0 - camY)*deltaDistY; }
    			
    			//now that we have the DDA parameters, actually walk the ray and find the closest intersecting wall.
    			int hit = 0;
    			int iter = 0;
    			int side;
    			while (hit == 0 && iter < MAX_STEPS)
    			{
    				if ( sideDistX < sideDistY )
    				{
    					sideDistX += deltaDistX;
    					mx += stepX;
    					side = 0;
    					if ( mx < map_left_x || mx >= maxTileX )
    						break;
    				}
    				else
    				{
    					sideDistY += deltaDistY;
    					my += stepY;
    					side = 1;
    					if ( my < map_left_y || my >= maxTileY )
    						break;
    				}
    				hit = map_combo[ ((my-map_left_y)<<5)+(mx-map_left_x) ];
    				iter++;
    			}
    			
    			//if we've hit something we figure out the column to render.
    			if ( hit )
    			{
    				float wallDist;
    				int u;
    				//compute the distance to the wall and the texture coordinate.
    				if ( side == 0 )
    				{
    					wallDist = (mx - camX + (1 - stepX)*0.5 ) / rayDirX;
    					u = camY + rayDirY*wallDist;
    				}
    				else
    				{
    					wallDist = (my - camY + (1 - stepY)*0.5 ) / rayDirY;
    					u = camX + rayDirX*wallDist;
    				}
    				//we use 16x16 tiles for textures.
    				u = Floor( u*16 )&15;
    				
    				//compute the wall height.
    				wallDist = Abs(wallDist);
    				float height = 256.0 / wallDist;
    				
    				//compute the column dimensions.
    				int y0 = Floor(cenY - height*0.5);
    				int y1 = Floor(cenY + height*0.5);
    				
    				if ( y0 < -96 ) y0 = -96;
    				if ( y1 > 240 ) y1 = 240;
    				
    				//shading depends on the "side" (so some faces are darker then others)
    				//and the distance.
    				int shading = Floor(wallDist/2) + side;
    				if ( shading > 7 ) shading = 7;
    				//textures are hard to author for this, but we compute the final tile we need for this column based on
    				//the texture coordinate and shading.
    				int tile = Game->ComboTile(hit) + u+(shading*20);
    
    				//Quad() doesn't work well here, but DrawTile() does since we're rendering a screen aligned quad.
    				Screen->DrawTile(1, x, y0, tile, 1, 1, 0, 2, (y1-y0), 0, 0, 0, 0, false, 128);
    			}
    		}
    	}
    }

  3. #3
    Administrator War Lord's Avatar
    Join Date
    Feb 2000
    Age
    40
    Posts
    6,028
    Mentioned
    54 Post(s)
    Tagged
    0 Thread(s)
    vBActivity - Stats
    Points
    1,448
    Level
    12
    vBActivity - Bars
    Lv. Percent
    89.14%
    Fair enough.
    PM me that paypal address and I'll send $10.
    That was easier than I thought it'd be.

  4. #4
    Is this the end?
    ZC Developer
    Saffith's Avatar
    Join Date
    Jan 2001
    Age
    41
    Posts
    3,389
    Mentioned
    178 Post(s)
    Tagged
    6 Thread(s)
    vBActivity - Stats
    Points
    6,430
    Level
    24
    vBActivity - Bars
    Lv. Percent
    69.57%
    Nah, that's fine. It's one of the quests I use for PGO, so I had it handy.

  5. #5
    Administrator War Lord's Avatar
    Join Date
    Feb 2000
    Age
    40
    Posts
    6,028
    Mentioned
    54 Post(s)
    Tagged
    0 Thread(s)
    vBActivity - Stats
    Points
    1,448
    Level
    12
    vBActivity - Bars
    Lv. Percent
    89.14%
    I greatly appreciate it @Saffith . You're awesome!
    Preserved in the DB
    http://www.zeldaclassic.com/resource-listing/entry/372/


  6. #6
    The Timelord
    QDB Manager
    ZC Developer

    Join Date
    Oct 2006
    Location
    Prydon Academy
    Posts
    1,396
    Mentioned
    112 Post(s)
    Tagged
    1 Thread(s)
    vBActivity - Stats
    Points
    4,760
    Level
    21
    vBActivity - Bars
    Lv. Percent
    68.7%
    I know,or rather, I was told about two years ago, that Mysteries of the Deep circulated privately. I think that @ShadowTiger had it long ago, and no loner does, or she knew someone who had, it, or something of that sort.

    I have the demos of The World Tree, and Mirror of the Moon, and the codebase for the latter. BK didn't leave the World Tree code in the buffer, so it's only in the ZASM table, not that I expect anyone to pick it up and run with it; else the would've done long ago. The pseudo-parallax effect was gorgeous in that one.

    Good to see that this didn't find its way to the depths of the Internet equivalent of the Marianas Trench, after all. Thanks @Saffith , for sharing.

    I wonder if BK is even still alive,

  7. #7
    Administrator DarkDragon's Avatar
    Join Date
    Oct 2001
    Posts
    6,228
    Mentioned
    70 Post(s)
    Tagged
    0 Thread(s)
    vBActivity - Stats
    Points
    11,025
    Level
    31
    vBActivity - Bars
    Lv. Percent
    8.16%

  8. #8
    The Timelord
    QDB Manager
    ZC Developer

    Join Date
    Oct 2006
    Location
    Prydon Academy
    Posts
    1,396
    Mentioned
    112 Post(s)
    Tagged
    1 Thread(s)
    vBActivity - Stats
    Points
    4,760
    Level
    21
    vBActivity - Bars
    Lv. Percent
    68.7%
    Quote Originally Posted by DarkDragon View Post
    Is the quest binary still out there for that, too? Probably needs some minor updates because of functions that changed between beta 378 and release, but that's not very hard. I did that for the quest [I]Starshooter Supreme[/I (or was it 'Starshooter 'Extreme'?), that @Gleeok made, and we should probably put the fixed version into the zc.com database, if he doesn't mind.

    Hell, does anyone still have Pong, that @Saffith made for 2.5 early beta (or was it for 2.11)? I asked him, and IIRC he said it was long gone. These early experimental quests need preservation.

    Preserving and uploading all the tech demos that show off what is possible with ZC, in addition to the normal stuff, is very wise, actually.

    Perhaps some of these system stress test packages should also go into the open source kits, so that people can monitor new builds with them.

Thread Information

Users Browsing this Thread

There are currently 1 users browsing this thread. (0 members and 1 guests)

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
About us
Armageddon Games is a game development group founded in 1997. We are extremely passionate about our work and our inspirations are mostly drawn from games of the 8-bit and 16-bit era.
Social