Menu

Show posts

This section allows you to view all posts made by this member. Note that you can only see posts made in areas you currently have access to.

Show posts Menu

Topics - Scavenger

#1
TERROR OF THE VAMPIRE!

A new Game by Eggie, Scavenger, and Samael

In the vaguely 19th century, in vaguely Eastern Europe, a vampire menace grips the countryside! The menace of superstition and the belief that vampires exist!

Join Dr. Ego Goodmind, BHD, as he does research for his newest psychology book, The Empirical Vampirical. But is he in over his incredibly big head this time? Only time will tell.



Featuring:

  • 8-bit Graphics with hand programmed raster effects.
  • Plenty of obtuse puzzles, and even more obtuse characters!
  • Animation! So much animation!
  • A searing critique of contemporary psychiatry (assuming you live in the 19th century)!

Download Link (24mb)
#2
I'm trying to create a bell in-engine, which swings back and forth, but I'm having a little bit of trouble - I can rotate the sprite around its central point, and I can move the object in a circle, but I can't sync them up. I don't think I'm good enough at math to work it out.

The sprite is here:

It should rotate around the middle of the hole at the top, so I can get it to swing. My current code is:

Code: AGS
DynamicSprite *bellsprite;
int angle = 1;
function room_Load()
{
bellsprite = DynamicSprite.CreateFromExistingSprite (520);
}

function room_RepExec()
{
  angle++;
  if (angle > 359) angle = 1;
bellsprite = DynamicSprite.CreateFromExistingSprite (520);
bellsprite.Rotate (angle, 128, 128);
oBell.Graphic = bellsprite.Graphic;
oBell.X = FloatToInt(((100.0-64.0) * Maths.Cos (Maths.DegreesToRadians (IntToFloat (angle)))) - ((113.0-32.0) *  Maths.Sin (Maths.DegreesToRadians (IntToFloat (angle)))))+64;
oBell.Y = FloatToInt(((100.0-64.0) * Maths.Sin (Maths.DegreesToRadians (IntToFloat (angle)))) + ((113.0-32.0) *  Maths.Cos (Maths.DegreesToRadians (IntToFloat (angle)))))+32;
}


But this is incredibly wrong, I know it. I just don't know how to make it go. Can anyone give me some advice?
#3
Critics' Lounge / Human and Seal Sprites
Mon 22/05/2017 11:20:29
I've been doing sprites of a game's protagonist, and I've been struggling with it a little. The biggest problem I've been having is the hair. I need to make it long and shaggy but also I need to be able to animate it. All the attempts I've done with it have ended up looking too complex to animate properly:
[imgzoom]https://dl.dropbox.com/s/wledrsottygxlr4/Harper_turnaround.png?dl=0[/imgzoom]
The legs and feet as well, look a little weird but I can't place how. I'd like to make the sprites as good as I can before I start animating in earnest. Can anyone give me any advice or guidance on doing this? Thank you in advance.

The model sheet I'm working from is this:
#4
For this sprite jam, you've been given the following challenge:


  • You must create a sprite of a protagonist who is LOST, TRAVELLING, or somehow OUT OF THEIR NATIVE ENVIRONMENT, in addition to their TRANSPORTATION or ONE INVENTORY ITEM they would have on them. Please explain HOW they are lost, travelling and so on, so we know the character's motivation!
  • These sprites MUST be AGS-ready - no concept art.
  • As an additional challenge, you are limited to a screen size of either 320x200 or 640x400. Try to keep your sprites workable within this canvas! No colour limitations this time, just size!

As a reward, I have created these trophies for you:

Every entry will recieve a Jade Bindle, at least.
3rd Place will recieve a Bronze Luggage.
2nd Place will recieve a Silver Map.
1st Place will recieve a Golden Sherpa - a necessary companion for dangerous treks!

The deadline for this jam is April 1926th, which should give everyone a good two weeks to finish their entries!
#5
General Discussion / What is race?
Sun 20/11/2016 11:54:47
(This discussion was split off from here: http://www.adventuregamestudio.co.uk/forums/index.php?topic=54140.msg636548400#msg636548400 â€"Moderator)

Quote from: Atelier on Sun 20/11/2016 11:37:43
What? That is literally how human genetics works. There are clear phenotypic and genetic differences between humans which we can classify as races relative to one another. If there weren't we would all be homogenous. These differences are biological, not cultural.

The concept of "whiteness" or "blackness" is a cultural and plastic phenomenon that changes depending on who gets to be the in-crowd, and generally trends towards what colour your skin is - which is something that means absolutely nothing apart from how much melanin is in your skin. You are no more likely to be anything in particular personality or temperment-wise if your skin is a particular colour.

Races don't exist biologically, it's a meaningless concept invented mostly to divide people and give an excuse to enslave them. It would be identical to classifying people by eye colour, or blood type. Yes, it differs between people but means absolutely nothing at all except by the imprinting of cultural significance onto it.
#6
I have a puzzle in my game where you need to make a stone tool, and I really want to use a tactile stone knapping thing to shape it instead of just combining items. There was a game called Sapiens that had this kind of minigame in it where you worked away at the edges of a stone plate to create a hatchet or something:
[imgzoom]https://dl.dropboxusercontent.com/u/50882197/art/GameStuff/knapping.gif[/imgzoom]
The idea was that you struck at the stone by holding down the mouse button, and the longer you held it down, the harder it hits. Small taps can get rid of that bright yellow area, but large strikes are required to get those in the first place. I know how to do the controls, and I'd be able to draw the assets, but I have no idea how I'd program the shape detector, or bits chipping off of it. I don't need anything super realistic, but I'm not sure how to approach the problem itself. Does anyone have any suggestions as to where I can begin?
#7
Critics' Lounge / Porcine Walk Cycle
Tue 04/10/2016 13:16:40
I need to animate a pig walking, and I'm not really sure I've got it down properly. I've only really done bipeds before, so quadrapeds are new territory for me. I referenced the Muybridge pig for it, but it's a little difficult to extrapolate it for pixels:



[imgzoom]https://dl.dropboxusercontent.com/u/50882197/art/GameStuff/pig_walkside.gif[/imgzoom]

I'm not quite sure where to go with the walk animations, where to put the bounce in, or even if there should be any. Trying to add a bounce made it look phony, so how do I make this pig walk look more natural? And how can I make the front and back views not look like ass (no pun intended)?
#8
Plant and Click Adventures

Alright! Sorry for the delay, it was difficult finding the time! The current theme is:

Plants
Our botanical friends! With a wide variety of vines, flowers, mushrooms, and trees, with fruits and vegetables too, plants provide a very wide palette with which to draw inspiration from! Dryads, tree-spirits, myconids, man eating singing world ending venus fly traps - plants are everywhere! So let's adventure with them!


Your task is to:
- Create a character for an adventure game who is a plant! Be they anthropomorphic, monstrous or just literally a plant, you must design and sprite a character who would go in an adventure game, and is some kind of plant, or fungus. I'm leaving it open to interpretation this time, but you must also include one sentence about the character's role in the (hypothetical) game you're spriting them for!
- The sprite must contain no more than 16 colours, total. 3D models are allowed, so long as the texture map contains no more than 16 colours.
- The sprite must be AGS-Ready!

Winners will get one of these trophies!

#9
I'm trying to program the UI for my game, and I've run against a weird snag that I can't solve. The inventory window simply does not scroll when invWindow.ScrollUp/Down is called. My InventoryWindow is set to have 2 rows of 4 items, 17x17 in size (the item graphics themselves are 16x16 but I need a 1 pixel buffer between them), and whenever I call the ScrollUp/ScrollDown functions.... nothing happens, even when I have more than 8 items in my inventory.

What could be causing this? There's nothing in any of my rep_execs that sets the Inventory Window, it's all done in the on_mouse_click, and the GUI buttons for scrolling the inventory - and even when I set the ItemWidth/ItemHeight to 16, it still wouldn't scroll. Nothing I'm doing with it is working.
#10
I have a 2D array that deals with lighting in my game, and I'd like to be able to just create a "seed" light and have the dropoff automatically happen, so I can have dynamic lighting and such. Like so:

Code: ags

Seed lights:
0,0,0,0,0,0,0,0,0,0
0,4,0,0,0,0,0,0,0,0
0,0,0,0,0,0,0,0,0,0
0,2,0,0,0,0,0,0,8,0
0,0,0,0,0,0,0,0,0,0

With dropoff:
1,2,1,0,0,0,0,0,1,0
2,4,2,1,0,0,0,1,2,1
1,2,1,0,0,0,1,2,4,2
1,2,1,0,0,1,2,4,8,4
0,1,0,0,0,0,1,2,4,2


But I'm not sure how to do it in a way that wouldn't slow down the game too much if it's calculated often. Does anyone have any advice about how I should do this? I need to do it once every second, at least, since there are objects that move around that give off light, and daylight.
#11
Monstrous Protagonists!

Alright, listen up youse guys, those humies have had it far too easy for far too long. Bein' the shiny 'eroes, gettin' all the games to themselves. When's it our turn to shine? When can we get games of our own? And don't talk to me about elfs, elfs is the worst. Just cause they have pointy ears those humies think they're exotic enough to count as sumfing new. Well, we ain't standin' for it! Bring us yer big hulking brutes, yer furry an' scaly skins, the weirder yer weirdie the better. We'll show 'em, we'll show all those humies that monstas can be just as big of a 'ero as they could ever be!

This time, this sprite jam is all about monsters. The less humanoid, the better. But not just any monsters, these monsters are striking out on their own and being the stars of their own show. Unsatisfied with their bit parts and minor villain roles, these monsters are starring in their own King's Quests, Quests for Glory, Monkey Islands, or even their own Broken Swords. Cast off your human skins, and join the monster party! Are your monsters the good guys, struggling in a world that hates them? Are your monsters still evil, carving out a piece of the world for their own? Are your monsters awkwardly shoehorned into modern society, with hilarious results? Could they even be a monster in a monstery world? That's up to you!



Da Roolz

  • Entries must be some kind of monster. No humans, elfs, dwarfs, or any other creature that was a human or could pass for a human (looking at you, vampires, werewolves, and nominally human cute-monster-girls). Goblins are fine, Orcs are fine. The more monstrous the better!
  • Entries must be sprites that could be put into an AGS game. Concept art in addition is welcome, but the final entry must be a sprite (or a 3D render, so long as it's got transparent bits).
  • Entries must be accompanied with one sentence describing the kind of game that your monster protagonist would star in. It doesn't have to be original. You could take an existing game and cross out all the names if you want! It's not up to me to judge whether or not a monster has eaten an existing game protagonist and is trying to wear their clothes!


Winners will get one of these trophies (which come in Beholder, Rust Monster, and Kobold flavors!), while all participants will recieve a Mimic Pretending to Be a Trophy!


What are you waiting for? Get weird!
#12
Critics' Lounge / Spriting a Seal
Wed 24/02/2016 21:05:15
I'm trying to sprite a seal-version of a character (he's a selkie, turning into a seal is his thing), but I'm having some trouble making the front, back, and the back-right sprite look right. I'm most pleased with the side view, it looks most like the chunky weird-not-quite seal I was going for. I'm just not entirely sure how to do the other views and have them read right. Especially the back view - every attempt I've done just looks like a mess.

[imgzoom]https://dl.dropboxusercontent.com/u/50882197/art/GameStuff/Harper_Seal_Sprites.PNG[/imgzoom]

Does anyone have any tips? Thank you in advance!
#13
I'm trying to create a dialog GUI for my game, and as part of my interface I have a semitransparent black box* that underlays most GUIs. It's done with:

Code: AGS
Translucence.CreateOverlay (50, dialog_bg.Graphic, 128, 1, info.X, info.Y);


and I can remove it with:

Code: AGS
Translucence.DeleteOverlay (50);


I need the overlay up when the dialog options are being shown, and to be deleted when the dialog options go away, but I'm not sure how to check whether the dialog options are being shown or not. If it helps, I'm using Austauber's CustomDialogGUI module, so using the custom dialog rendering functions is no problem. Is there any way to do this, or am I stuck with putting the code to turn it off in the dialog code itself?

*Using 8-bit mode, so I can't use the standard translucency functions.
#14
I'm trying to draw a skybox correctly based off of the player's angle, but I don't think I'm doing it right, and I couldn't find anything on google to show me how to draw it properly. I have to start with a direction vector, and I think you're supposed to use atan2 on that to get the radians, but...

Currently I have:

Code: C++

        double playerrad = atan2 (dirY,dirX);
	if (!sbBm) engine->AbortGame ("Raycast_Render: No valid skybox sprite.");
	if (skybox > 0)
	{
		int xoffset = (int)(playerrad*320.0);
		BITMAP *virtsc = engine->GetVirtualScreen ();
		engine->SetVirtualScreen (screen);
		xoffset = abs(xoffset % w);
		if (xoffset > 0)
		{
			engine->BlitBitmap (xoffset-320,1,sbBm,false);
		}
		engine->BlitBitmap (xoffset,1,sbBm,false);
		engine->SetVirtualScreen (virtsc);
	}


But it only works for half of the angles, the other half makes the skybox move in reverse, and it looks terrible. How are you supposed to do it correctly? Math with angles has always been my weakpoint.
#15
EDIT: I just did a quick hack so I didn't have to delete or initalize more than once. It's a dirty hack, and it means I can only use it for my game, but eh, I can reprogram later.

Hey, I'm having quite a complex issue that I'm not sure I can solve. I'm trying to make it so that my plugin saves its state and restores it along with the regular save game, and I can make it load the state, whatever it is, just once. Trying to load a save game twice during the same process crashes the engine (with error code 0xC0000005, which I believe is array out of bounds), and the reasons why mystify me. Why would it allow you to load the game once, but not twice? What is it about the second time that makes the engine freak out?

I'm not sure how much use pasting code will be, there is a whole lot of it, but here is the save/load code I'm using, and the variables I'm saving:

Code: C++

  bool raycastOn;
  bool heightmapOn;
  double posX = 22.0, posY = 11.5; //x and y start position
  double dirX = -1.0, dirY = 0.0; //initial direction vector
  double planeX = 0.0, planeY = 0.77; //the 2d raycaster version of camera plane
  double moveSpeed = (1.0/60.0) * 3.0; //the constant value is in squares/second
  double rotSpeed =  (1.0/60.0) * 2.0; //the constant value is in radians/second
  unsigned char **worldMap;
  unsigned char **lightMap;
  int **ceilingMap;
  int **floorMap;
  int **heightMap;
  int mapWidth;
  int mapHeight;
  int textureSlot;
  struct Sprite
  {
 	double x;
	double y;
	int texture;
	unsigned char alpha;
	int blendmode;
	double uDivW;
        double uDivH;
	double vMove;
	double hMove;
	char objectinteract;
	int view;
	int frame;
	int angle;
  };
  #define numSprites 256
  Sprite sprite[numSprites] = {};

  
  #define texWidth 64
  #define texHeight 64
  unsigned char **texture;

  long sWidth=0,sHeight=0;

  struct wallType
  {
	int texture[4];
	int solid[4];
	int ignorelighting[4];
	int alpha[4];
	int blendtype[4];
	int mask[4];
	unsigned char hotspotinteract;
  };

  wallType wallData[256]={};

 unsigned char **transcolorbuffer;
 unsigned char **transalphabuffer;
 double **transzbuffer;
 bool *transslicedrawn;
 int *transwallblendmode;
 double **ZBuffer;
 double *distTable;
 short *interactionmap;
 int skybox=0;



Code: C++

	if (event == AGSE_SAVEGAME)
	{
		for (int i = 0; i < MAX_OVERLAYS; ++i)
			{
				engine->FWrite(&overlay[i].sprite, sizeof(int), data);
				engine->FWrite(&overlay[i].spritemask, sizeof(int), data);
				engine->FWrite(&overlay[i].x, sizeof(int), data);
				engine->FWrite(&overlay[i].y, sizeof(int), data);
				engine->FWrite(&overlay[i].level, sizeof(int), data);
				engine->FWrite(&overlay[i].trans, sizeof(int), data);
				engine->FWrite(&overlay[i].blendtype, sizeof(int), data);
				engine->FWrite(&overlay[i].enabled, sizeof(bool), data);
			}
		engine->FWrite(&clutslot, sizeof(int), data);
		engine->FWrite(&drawreflections, sizeof(int), data);
		for (int j = 0; j < 256; ++j)
			{
				engine->FWrite(&cycle_remap[j], sizeof(unsigned char), data);
			}
		for (int j = 0; j < 256; ++j)
			{
				engine->FWrite(&objectivepal[j].r, sizeof(unsigned char), data);
				engine->FWrite(&objectivepal[j].b, sizeof(unsigned char), data);
				engine->FWrite(&objectivepal[j].g, sizeof(unsigned char), data);
			}
		for (int j = 0; j < 256; ++j)
			{
				engine->FWrite(&sprite[j].x, sizeof(double), data);
				engine->FWrite(&sprite[j].y, sizeof(double), data);
				engine->FWrite(&sprite[j].texture, sizeof(int), data);
				engine->FWrite(&sprite[j].alpha, sizeof(unsigned char), data);
				engine->FWrite(&sprite[j].uDivW, sizeof(double), data);
				engine->FWrite(&sprite[j].uDivH, sizeof(double), data);
				engine->FWrite(&sprite[j].vMove, sizeof(double), data);
				engine->FWrite(&sprite[j].hMove, sizeof(double), data);
				engine->FWrite(&sprite[j].objectinteract, sizeof(char), data);
				engine->FWrite(&sprite[j].view, sizeof(int), data);
				engine->FWrite(&sprite[j].frame, sizeof(int), data);
				engine->FWrite(&sprite[j].angle, sizeof(int), data);
			}
		for (int j = 0; j < 256; ++j)
			{
				for (int k = 0; k < 4;++k)
					{
						engine->FWrite(&wallData[j].texture[k], sizeof(int), data);
						engine->FWrite(&wallData[j].solid[k], sizeof(int), data);
						engine->FWrite(&wallData[j].ignorelighting[k], sizeof(int), data);
						engine->FWrite(&wallData[j].alpha[k], sizeof(int), data);
						engine->FWrite(&wallData[j].blendtype[k], sizeof(int), data);
						engine->FWrite(&wallData[j].mask[k], sizeof(int), data);
					}
				engine->FWrite(&wallData[j].hotspotinteract, sizeof(char), data);
			}
		engine->FWrite(&raycastOn, sizeof(bool), data);
		engine->FWrite(&heightmapOn, sizeof(bool), data);
		engine->FWrite(&posX, sizeof(double), data);
		engine->FWrite(&posY, sizeof(double), data);
		engine->FWrite(&dirX, sizeof(double), data);
		engine->FWrite(&dirY, sizeof(double), data);
		engine->FWrite(&planeX, sizeof(double), data);
		engine->FWrite(&planeY, sizeof(double), data);
		engine->FWrite(&moveSpeed, sizeof(double), data);
		engine->FWrite(&rotSpeed, sizeof(double), data);
		engine->FWrite(&sWidth, sizeof(long), data);
		engine->FWrite(&sHeight, sizeof(long), data);
		engine->FWrite(&mapWidth, sizeof(int), data);
		engine->FWrite(&mapHeight, sizeof(int), data);
		if (raycastOn) //If the raycaster is active, we have additional data to save.
		{
			for (int i = 0; i < mapWidth;++i)
				for (int j = 0;j < mapHeight;++j)
				{
					engine->FWrite(&worldMap [i][j], sizeof(unsigned char), data);
					engine->FWrite(&lightMap [i][j], sizeof(unsigned char), data);
					engine->FWrite(&ceilingMap [i][j], sizeof(int), data);
					engine->FWrite(&floorMap [i][j], sizeof(int), data);
					engine->FWrite(&heightMap [i][j], sizeof(int), data);
				}
		}
		engine->FWrite(extureSlot, sizeof(int), data);
		engine->FWrite(&skybox, sizeof(int), data);
	}
	if (event == AGSE_RESTOREGAME)
	{


		for (int i = 0; i < MAX_OVERLAYS; ++i)
			{
				engine->FRead(&overlay[i].sprite, sizeof(int), data);
				engine->FRead(&overlay[i].spritemask, sizeof(int), data);
				engine->FRead(&overlay[i].x, sizeof(int), data);
				engine->FRead(&overlay[i].y, sizeof(int), data);
				engine->FRead(&overlay[i].level, sizeof(int), data);
				engine->FRead(&overlay[i].trans, sizeof(int), data);
				engine->FRead(&overlay[i].blendtype, sizeof(int), data);
				engine->FRead(&overlay[i].enabled, sizeof(bool), data);
			}
		engine->FRead(&clutslot, sizeof(int), data);
		engine->FRead(&drawreflections, sizeof(int), data);
		for (int j = 0; j < 256; ++j)
			{
				engine->FRead(&cycle_remap[j], sizeof(unsigned char), data);
			}
		for (int j = 0; j < 256; ++j) //Save Objective Palette, for palette mixing.
			{
				engine->FRead(&objectivepal[j].r, sizeof(unsigned char), data);
				engine->FRead(&objectivepal[j].b, sizeof(unsigned char), data);
				engine->FRead(&objectivepal[j].g, sizeof(unsigned char), data);
			}
		for (int j = 0; j < 256; ++j) //Save Raycaster Sprite struct, 256 instances.
			{
				engine->FRead(&sprite[j].x, sizeof(double), data);
				engine->FRead(&sprite[j].y, sizeof(double), data);
				engine->FRead(&sprite[j].texture, sizeof(int), data);
				engine->FRead(&sprite[j].alpha, sizeof(unsigned char), data);
				engine->FRead(&sprite[j].uDivW, sizeof(double), data);
				engine->FRead(&sprite[j].uDivH, sizeof(double), data);
				engine->FRead(&sprite[j].vMove, sizeof(double), data);
				engine->FRead(&sprite[j].hMove, sizeof(double), data);
				engine->FRead(&sprite[j].objectinteract, sizeof(char), data);
				engine->FRead(&sprite[j].view, sizeof(int), data);
				engine->FRead(&sprite[j].frame, sizeof(int), data);
				engine->FRead(&sprite[j].angle, sizeof(int), data);
			}
		for (int j = 0; j < 256; ++j) //Save Raycaster wall type data.
			{
				for (int k = 0; k < 4;++k)
					{
						engine->FRead(&wallData[j].texture[k], sizeof(int), data);
						engine->FRead(&wallData[j].solid[k], sizeof(int), data);
						engine->FRead(&wallData[j].ignorelighting[k], sizeof(int), data);
						engine->FRead(&wallData[j].alpha[k], sizeof(int), data);
						engine->FRead(&wallData[j].blendtype[k], sizeof(int), data);
						engine->FRead(&wallData[j].mask[k], sizeof(int), data);
					}
				engine->FRead(&wallData[j].hotspotinteract, sizeof(char), data);
			}
		//Delete worldmap data if it exists.
		if (worldMap)
			{
				for (int j = 0;j < mapHeight;++j)
				{
					delete [] worldMap [j];
					delete [] lightMap [j];
					delete [] ceilingMap [j];
					delete [] floorMap [j];
					delete [] heightMap [j];
				}
				delete [] worldMap;
				delete [] lightMap;
				delete [] ceilingMap;
				delete [] floorMap;
				delete [] heightMap;
			}
		if (transcolorbuffer) //delete the buffers and dynamic arrays before loading new ones.
		{
			for (int x=0;x<sWidth;x++)
			{
				delete [] transcolorbuffer[x];
				delete [] transalphabuffer[x];
				delete [] transzbuffer[x];
				delete [] ZBuffer[x];
			}
		}
		engine->FRead(&raycastOn, sizeof(bool), data);
		engine->FRead(&heightmapOn, sizeof(bool), data);
		engine->FRead(&posX, sizeof(double), data);
		engine->FRead(&posY, sizeof(double), data);
		engine->FRead(&dirX, sizeof(double), data);
		engine->FRead(&dirY, sizeof(double), data);
		engine->FRead(&planeX, sizeof(double), data);
		engine->FRead(&planeY, sizeof(double), data);
		engine->FRead(&moveSpeed, sizeof(double), data);
		engine->FRead(&rotSpeed, sizeof(double), data);
		engine->FRead(&sWidth, sizeof(long), data);
		engine->FRead(&sHeight, sizeof(long), data);
		engine->FRead(&mapWidth, sizeof(int), data);
		engine->FRead(&mapHeight, sizeof(int), data);
		if (raycastOn) //If the raycaster is currently running, we have additional data to load.
			{
				worldMap = new unsigned char*[mapWidth];
				lightMap = new unsigned char*[mapWidth];
				ceilingMap = new int*[mapWidth];
				floorMap = new int*[mapWidth];	
				heightMap = new int*[mapWidth];
				for (int i = 0; i < mapWidth;++i)
					{
						worldMap[i] = new unsigned char[mapHeight];
						lightMap[i] = new unsigned char[mapHeight];
						floorMap[i] = new int[mapHeight];
						ceilingMap[i] = new int[mapHeight];
						heightMap[i] = new int[mapHeight];
						for (int j = 0;j < mapHeight;++j)
						{
							engine->FRead(&worldMap [i][j], sizeof(unsigned char), data);
							engine->FRead(&lightMap [i][j], sizeof(unsigned char), data);
							engine->FRead(&ceilingMap [i][j], sizeof(int), data);
							engine->FRead(&floorMap [i][j], sizeof(int), data);
							engine->FRead(&heightMap [i][j], sizeof(int), data);
						}
					}
				engine->FRead(extureSlot, sizeof(int), data);
				engine->FRead(&skybox, sizeof(int), data);
				//Reinitialize all the buffers and stuff.
				if (textureSlot) MakeTextures (textureSlot);
				delete [] transcolorbuffer;
				transcolorbuffer = new unsigned char*[sWidth];
				delete [] transalphabuffer;
				transalphabuffer = new unsigned char*[sWidth];
				delete [] transslicedrawn;
				transslicedrawn = new bool[sWidth];
				delete [] transzbuffer;
				transzbuffer = new double*[sWidth];
				delete [] transwallblendmode;
				transwallblendmode = new int [mapWidth];
				delete [] ZBuffer;
				ZBuffer = new double*[sWidth];
				delete [] distTable;
				distTable = new double[sHeight+(sHeight>>1)];
				delete [] interactionmap;
				interactionmap = new short[sWidth*sHeight];
				for (int y=0;y<sHeight+(sHeight>>1);y++)
				{
					distTable [y] = sHeight / (2.0 * y - sHeight);
				}
				for (int x=0;x<sWidth;x++)
				{
					transcolorbuffer[x] = new unsigned char [sHeight*(mapWidth)]();
					transalphabuffer[x] = new unsigned char [sHeight*(mapWidth)]();
					transzbuffer[x] = new double [sHeight*(mapWidth)]();
					ZBuffer[x] = new double [sHeight];
					transslicedrawn [x] = false;
				}
			}
		LoadCLUT (clutslot);
	}


I can supply anything else that's needed, but I'm getting a little confused with why it's doing it. It's kind of disheartening, as it works perfectly the first time. If it had just crashed the first time, I'd know I was doing something majorly wrong. But these kinds of bugs are really out of my league at the moment. See, the error messages that AGS kicks out when the plugin crashes doesn't really help me, as I don't know what line in my code corresponds to what offset in the error message. Is there any way I can check it at all?
#16
I'm trying to write a raycaster for AGS (that can be controlled from within AGS using sprites as maps and stuff), and it's going pretty well. I currently have a very very simple raycaster working, based on this tutorial, and I've added light levels and stuff to it, and am currently working on transparent walls. Unfortunately, I've run into a problem I can't solve myself, and I'm not sure where else to turn to. I know I'm asking a lot of non-AGSScript questions, but I really can't do this in AGSScript without it requiring a futuristic supercomputer.

My problem is that I can't seem to get the back face of a cube to render properly. This is what I got so far:


The cube has the pillar texture on all four faces, so in reality, it's got to look something like this, with the pillar texture visible at the back as well. But my attempts, well, they're not going well. I end up with an infinite line of "other walls", instead of just the one I wanted. You can see that the opposite wall of the cube just goes on forever when you look into it. I'm not even sure how it's doing that. And the adjacent wall isn't drawn at all, to be expected, but I'm not sure how to do that either.



My method is:
1) Cast ray
2) Continue until it hits a wall.
2) Start drawing that wall, using the ZBuffer to mask out anything already drawn in front of it.
3) If the wall has any transparent pixels, flag the thing to draw deeper.
4) On the next pass, draw the back face by flipping the ray direction and manually stepping to the next intersection.
5) Goto 2 afterwards to draw the wall behind it.

I'm sure I'm doing this wrong, but I'm not sure how to fix it, I don't understand the code well enough to do anything constructive with it. Is there anything I can do to stop this? Is there a better way to be doing this?

My code for drawing walls is:
Code: C++
 while (hit == 0 && deeper == true)
{
	if (opposite)
	{
		rayDirX = rayDirX * (-1);
		rayDirY = rayDirY * (-1);
		stepX = stepX * (-1);
		stepY = stepY * (-1);
        }
	else if (sideDistX < sideDistY) //jump to next map square, OR in x-direction, OR in y-direction
        {
          sideDistX += deltaDistX;
          mapX += stepX;
          side = 0;
        }
        else
        {
          sideDistY += deltaDistY;
          mapY += stepY;
          side = 1;
        }
        //Check if ray has hit a wall       
        if (worldMap[mapX][mapY] > 0)
		{
			hit = 1; //Set this to true so that by default, it's impossible to hang the engine.
			deeper = false; //Set this to false so that we don't go deeper than we need to.

			//Calculate distance of perpendicular ray (oblique distance will give fisheye effect!)    
			if (side == 0) perpWallDist = fabs((mapX - rayPosX + (1 - stepX) / 2) / rayDirX);
			else       perpWallDist = fabs((mapY - rayPosY + (1 - stepY) / 2) / rayDirY);
      
			 //Calculate height of line to draw on screen       
     		 int lineHeight = abs(int(h / perpWallDist));
     		 
     		 //calculate lowest and highest pixel to fill in current stripe
     		 drawStart = -lineHeight / 2 + h /2;
     		 if(drawStart < 0) drawStart = 0;
     		 drawEnd = lineHeight / 2 + h / 2;
     		 if(drawEnd >= h) drawEnd = h - 1;
     		 //texturing calculations
     		 int texNum = worldMap[mapX][mapY] - 1; //1 subtracted from it so that texture 0 can be used!
     		 
     		 //calculate value of wallX
     		 if (side == 1) wallX = rayPosX + ((mapY - rayPosY + (1 - stepY) / 2) / rayDirY) * rayDirX;
     		 else       wallX = rayPosY + ((mapX - rayPosX + (1 - stepX) / 2) / rayDirX) * rayDirY;
     		 wallX -= floor((wallX));
     		  
     		 //x coordinate on the texture
	 		 int wall_light=0;
     		 int texX = int(wallX * double(texWidth));
     		 if(side == 0 && rayDirX > 0) texX = texWidth - texX - 1;
     		 if(side == 1 && rayDirY < 0) texX = texWidth - texX - 1;
	 	 if (rayDirX > 0 && side == 0) wall_light = 255 / (8-lightMap [(int)mapX-1][(int)mapY]);
	 	 if (rayDirX < 0 && side == 0) wall_light = 255 / (8-lightMap [(int)mapX+1][(int)mapY]);
	 	 if (rayDirY > 0 && side == 1) wall_light = 255 / (8-lightMap [(int)mapX][(int)mapY-1]);
	 	 if (rayDirY < 0 && side == 1) wall_light = 255 / (8-lightMap [(int)mapX][(int)mapY+1]);
     		 for(int y = drawStart; y < drawEnd; y++)
     			{
				if (ZBuffer[x][y] > perpWallDist || ZBuffer[x][y] == 0) //We can draw.
				{
     				    int d = y * 256 - h * 128 + lineHeight * 128; //256 and 128 factors to avoid floats
     			 	    int texY = ((d * texHeight) / lineHeight) / 256;
     				    int color = texture[texNum][texWidth * texY + texX];
     				    if (color > 0)
					{
					    color = MixColorAlpha (color,GetColor565(0,0,10),wall_light);
					    buffer[y][x] = color;
					    //SET THE ZBUFFER FOR THE SPRITE CASTING
					    ZBuffer[x][y] = perpWallDist; //perpendicular distance is used
					}
					else
					{
					    //We found transparency, we have to draw deeper.
					    deeper = true;
					    hit = 0;
					}
				}
     			}
			 if (opposite)
			 {
				 opposite = false;
				 rayDirX = rayDirX * (-1);
				 rayDirY = rayDirY * (-1);
				 stepX = stepX * (-1);
				 stepY = stepY * (-1);
			 }
			 else if (!opposite && deeper && (prevmapX != mapX && prevmapY != mapY))
			 {
				 opposite = true;
				 prevmapX = mapX;
				 prevmapY = mapY;
			 }
			//End of wall drawing functions.
			}
		//End of loop.
}



Full code is here in case I've missed anything out.

Thank you in advance, and sorry for filling the technical forum.
#17
I got a faster sine function that I want to use in AGS (gotta keep up the speed wherever I can), that I've already used internally in my plugin elsewhere, but I don't seem to be able to get AGS to recognize the floating point number as a floating point number. Here's the relevant code:

Code: C++

const char *ourScriptHeader =
  "struct PALInternal {\r\n"
  "///Polynomial Sine Approximation.\r\n"
  "import static float FastSin (float x);// $AUTOCOMPLETESTATICONLY$\r\n"
  "///Polynomial Cosine Approximation.\r\n"
  "import static float FastCos (float x);// $AUTOCOMPLETESTATICONLY$\r\n"
  "int dummy; //$AUTOCOMPLETEIGNORE$\r\n"
  "};\r\n";

float FastSin(float x)
{
  // wrap x within [0, TWO_PI)
  const float a = x * twopi_inv;
  x -= static_cast<int>(a) * twopi;
  if (x < 0.0f)
    x += twopi;

  // 4 pieces of hills
  if (x < halfpi)
    return Hill(halfpi - x);
  else if (x < PI)
    return Hill(x - halfpi);
  else if (x < 3.0f * halfpi)
    return -Hill(3.0f * halfpi - x);
  else
    return -Hill(x - 3.0f * halfpi);
}

float FastCos(float x)
{
  return FastSin(x + halfpi);
}

//later on....
  engine->RegisterScriptFunction ("PALInternal::FastSin^1", FastSin);
  engine->RegisterScriptFunction ("PALInternal::FastCos^1", FastCos);


I dunno what I have to return to get AGS to recognize this float as a float. I read through AGS' source code a bit earlier, and it... looked like floats might not actually be literally floats? What do I have to cast the result as in order for AGS to recognize it as a float? I've seen a couple of other plugins returning floats (like the AGSSteam stub), so it's gotta be possible somehow, but I'm not sure how. The code for the AGS float type is a bit intimidating.

(Also I learned today that you can declare enums in a plugin, so that's amazing)

EDIT: Whoops, sorry, I delved further into the code and managed to come up with a solution. Hopefully this can help other people as well:

Code: ags

//Add this at the top
#define SCRIPT_FLOAT(x) signed int __script_float##x
#define INIT_SCRIPT_FLOAT(x) float x; memcpy(&x, &__script_float##x, sizeof(float))
#define FLOAT_RETURN_TYPE signed int
#define RETURN_FLOAT(x) signed int __ret##x; memcpy(&__ret##x, &x, sizeof(float)); return __ret##x


//Wrap functions so that they return a "float".
FLOAT_RETURN_TYPE AGSFastSin (SCRIPT_FLOAT(x))
{
	INIT_SCRIPT_FLOAT (x);
	x = FastSin (x);
	RETURN_FLOAT (x);
}

FLOAT_RETURN_TYPE AGSFastCos (SCRIPT_FLOAT(x))
{
	INIT_SCRIPT_FLOAT (x);
	x = FastSin (x+halfpi);
	RETURN_FLOAT (x);
}
#18
I have a lot of functions in my plugin, and I'd like to organize them a little so the interface to the end user isn't a complete mess. I've seen plugins use structs for their functions before (the Adplug plugin for instance), but I'm not sure how to do it myself. I'd assume it's similar to how you do it in AGS, but it's not documented and I'm not sure.

Also, the AGSObject* structure doesn't have IgnoreScaling and IgnoreLighting as flags - how do I check this from the plugin?
#19
I'm trying to draw this colour space:

with AGS using Game.GetColorFromRGB and DrawPixel. it's the standard 565 16 bit colour space, but I'm having trouble coming up with the formula just looking at it. I tried a couple of things but it looks really off. Can someone point me in the right direction? My current code is:

Code: AGS

DynamicSprite *CLUT256;
int x = 0;
int y = 0;
int r = 0;
int g = 0;
int b = 0;
int maxr = 0;
int maxb = 31;
int maxg = 0;

function room_AfterFadeIn()
{
CLUT256 = DynamicSprite.Create (256, 256);
SetGameSpeed (60);
}
function room_RepExec()
{
  DrawingSurface *surf = CLUT256.GetDrawingSurface ();
  if (y < 256)
  {
    while (x < 256)
      {
        surf.DrawingColor = Game.GetColorFromRGB (r*8, g*4, b*8);
        //surf.DrawingColor = 21;
        surf.DrawPixel (x, y);
        /* //Clearly wrong colour code.
        if (b < maxb) b++;
        else
          {
            if (maxb > 0) maxb --;
            b = 0;
            if (r < maxr) r++;
            else 
            {
              if (maxr < 31) maxr++;
              r = 0;
              if (g < maxg) g++;
              else
              {
                g=0;
                if (maxg < 63) maxg++;
              }
            }
          }
           */
          x++;
      }
      x=0;
      y++;
  }
  surf.Release ();
  oClut.Graphic = CLUT256.Graphic;


And on a related note, colour mixing in the 16bit colour space is done simply by doing math on the index number, right? EG the colour that is 50% between color 3000 and color 6000 is (6000+3000)/2? I tested it out with AGS' 16bit colour mixer tab, it seemed to check out, but I need some confirmation.

I'm not too familiar with pure RGB mixing. I'm just trying to create something more memory efficient than a 256*2048 array for my colour mixing, and something more extensible.
#20
The ViewFrame struct doesn't seem to have the flipped property, and there doesn't seem to be any indication that I could get at it from the API. Would it be possible to use GetGameParameter with GP_ISFRAMEFLIPPED through GetScriptFunctionAddress, even though the function is obsolete? (I'll admit I don't know how to use GetScriptFunctionAddress at all :() I really need to know whether a frame in a view is flipped or not or the effect I'm programming is completely useless.

EDIT: I did it:

Code: C++

	int (*sfGetGameParameter)(int,int,int,int);
	sfGetGameParameter = ((int(*)(int,int,int,int)) engine->GetScriptFunctionAddress("GetGameParameter"));
	int flipped = sfGetGameParameter(13,currchar->view+1,currchar->loop,currchar->frame);
SMF spam blocked by CleanTalk