The first basically is about algorithm designs and things to avoid. Do you know what spaghetti code means? Structured programming? How about OO design? Big "O" notation? Recursion? Quick Sort? These are important concepts regardless of what language you use or platform you're on.

Learning C isn't that hard, learning how to use it properly can be. The syntax for C although terse, is very simple. You could describe the entire C language on a couple of sheets of paper, there's little too it. However, like my prof always told me, C gives you enough rope to hang yourself (and everyone around you actually). Basically, C trusts that you know what you are doing and if you tell it to trash memory it will happily do it for you. C will not hold your hand like Basic, but it gives you more power and flexibility then just about any other language. Anyways, my best advice to anyone who's new with C is to study your pointers. And when you think you understand pointers, study them some more. That's the one part of C that gives people major headaches.

the underlying semantics of C++ ( e.g. when to use virtual, what a copy constructor does ) Even without data-hiding inheritance, references, polymorphism you have a powerful structure. Very handy features, such as function name overloading (used with care and sparingly), declarations as statements, references to name but a few... Data and methods put together called a class. OO language is classes & objects. OO means objects that have data and methods. Methods are sent from object to object and the object manipulates it's data. It has its share of problems too: the syntax is complex (although not unbearably so), it has no garbage collection and still has you managing memory by yourself, and quite a number of others, which may not directly affect a programmer working on his own, but will when working in a team.

Algorithm theory involves thinking about the growth rates (Space and Time) and providing a breakdown of the issue into pseudo code and big O notation which taught what items to think about when choosing and optimizing algorithms

Of course you need to learn programming on the Amiga. Lucky for you, the Amiga is a fun computer to program with a relatively small API. That is to say, you won't be swamped with OS calls, however, there are some ugly parts out there. If you want to just open a window and create some buttons, that's easy. Wanna write a web browser? That is gonna be hard and that is mostly because the OS doesn't provide a lot of the things you would need so you will end up writing it yourself. :-)

where d is the distance from the viewpoint and x, y, z are (obviously ) your x, y, z coordinates in 3d space If there is no "divide by Z", the depth-wise movement will feel wrong and it will feel like your object is accelerating/braking at the wrong times.

3d Projection

y_screen = (y_world / z) + (screen_height >> 1)

or:

z = y_world / (y_screen - (screen_height >> 1))

This formula takes the x or y world coordinates of an object, the z of the object, and returns the x or y pixel location. Or, alternately, given the world and screen coordinates, returns the z location.

Fast Linear Interpolation

o(x) = y1 + ((d * (y2-y1)) >> 16)

This assumes that all the numbers are in 16.16 fixed point. y1 and y2 are the two values to interpolate between, and d is the 16-bit fractional distance between the two points. For example, if d=$7fff, that would be halfway between the two values. This is useful for finding where between two segments a value is.

Fixed Point Arithmetic Floating point is very expensive for old systems which did not have specialized math hardware. Instead, a system called fixed point was used. This reserved a certain number of bits for the fractional part of the number. For a test case, say you only reserve one bit for the fractional amount, leaving seven bits for the whole number amounts. That fraction bit would represent one half (because a half plus a half equals a whole). To obtain the whole number value stored in that byte, the number is shifted right once. This can be expanded to use any number of bits for the fractional and whole portions of the number.

Fixed point multiplication is trickier than addition. In this operation, you would multiply the two numbers and then shift right by however many bits are reserved for fractions. Due to overflow, sometimes you may need to shift before multiplication instead of after. See "Fast Linear Interpolation" for an example of fixed point multiplcation.

Point Rotation

x' = x*cos(a) - y*sin(a)
y' = x*sin(a) + y*cos(a)

Mentioned briefly in the tutorial as being an expensive operation, here is the basic point rotation formula. As you can see, it's at least 2 table lookups, 4 multiplications, and two additions, but the sine and cosine values can be reused for each point. Rotating for the purpose of hills would mean rotating the Z and Y coordinates, not the X and Y coordinates. To find the derivation of this formula, look up Rotation of Axes.

Avoid Division Instead of dividing by the z of an object in the standard projection formulas, you can take advantage of some properties of the road to speed up calculations. Say you have a 3d segment z position and a y position, and you want to find which line of the screen it belongs on. First, read through the z-map until you get to the 3d segment's z position. Then, multiply the height of the segment by the corresponding scaling value. The result is the number of pixels above the road that the segment belongs.

Use Z as Scaling Value Scaling routines work by slowing or speeding up the speed at which a draw routine reads through graphics data. For example, if you were to set the read speed to half, this would draw a sprite double the size. This is because for each time a pixel is drawn, the read position in the sprite data is only incremented by half, causing the read position to only increment by a whole number every two pixels.

Usually, a scaling routine has parameters like x, y, and scaling factor. But since a scaling factor is just 1/z, we can just reuse the Z value of that sprite! We will still need the scaling factor though to determine the boundaries of the sprite so that we can keep it centered as it scales.

a perfect maze, there is one and only one path from any point in the maze to any other point. That is, there are no inaccessible sections, no circular paths, and no open regions. A perfect maze can be generated easily with a computer using a depth first search algorithm.

A two dimensional maze can be represented as a rectangular array of square cells. Each cell has four walls. The state of each wall (north, south, east, and west) of each cell is maintained in a data structure consisting of an array of records. Each record stores a bit value that represents the state of each wall in a cell. To create a path between adjacent cells, the exit wall from the current cell and the entry wall to the next cell are removed. For example, if the next cell is to the right (east) of the current cell, remove the right (east) wall of the current cell and the left (west) wall of the next cell.

Depth-First Search - simplest maze generation algorithm

Start at a random cell in the grid

Look for a random neighbor cell you haven't been to yet

If you find one, move there, knocking down the wall between the cells. If you don't find one, back up to the previous cell

Repeat steps 2 and 3 until you've been to every cell in the grid

PSEUDOCODE

create a CellStack (LIFO) to hold a list of cell locations
set TotalCells = number of cells in grid
choose a cell at random and call it CurrentCell
set VisitedCells = 1
while VisitedCells < TotalCells
find all neighbors of CurrentCell with all walls intact
if one or more found
choose one at random
knock down the wall between it and CurrentCell
push CurrentCell location on the CellStack
make the new cell CurrentCell
add 1 to VisitedCells
else
pop the most recent cell entry off the CellStack
make it CurrentCell
endIf
endWhile

assumed u have a x b size of maze, u need a + 1 and b + 1 of walls, so size of array should be (size * 2 + 1)

x, y = rand(width), rand(height)
cells << [x, y]
The program them simply loops until the list is empty
until cells.empty?
# ...
end

Within the loop, we first select the cell to operate on. I’m going to mask my own program’s complexity here behind a simple “choose_index” method; it takes a number and returns a number less than that.

index = choose_index(cells.length)
x, y = cells[index]

Next, we iterate over a randomized list of directions, looking for an unvisited neighbor. If no such neighbor is found, we delete the given cell from the list before continuing.

When a valid, unvisited neighbor is located, we carve a passage between the current cell and that neighbor, add the neighbor to the list, set index to nil (to indicate that an unvisited neighbor was found), and then break out of the innermost loop.

You need to create a separate context per class object instance and keep it alive as long as instance is alive. The context is bound to executing task and you can only have one context bound at a time. Opening the library itself does nothing - all actions are executed in relation to the context.

To get access to the right mouse button in an subclass I've added this in the setup method :

set(_win(obj), MUIA_Window_NoMenus, TRUE);

f the square you are drawing to is 2 dimensional and not rotated, you may be looking for glDrawPixels. It allows you to draw a rectangular region of pixels directly to the buffer without using any polygons.

glTexImage2D. This is the call that loads the image in OpenGL for a 2D Texture. glTexImage2D actually takes a raw pointer to the pixel data in the image. You can allocate memory yourself, and set the image data directly (however you want), then call this function to pass the image to OpenGL. Once you've created the texture, you can bind it to the state so that your triangles use that texture. If the texture needs to change, you will need to either re-do the glTexImage2D() call, or use something like glTexSubImage2D() to do a partial update.

just pass an array of GLubyte to the glTexImage2D function (as well as all the functions needed to bind the texture, etc). Haven't tried this exact snippet of code, but it should work fine. The array elements represent a serial version of the rows, columns and channels.

about a sphere intersecting triangles, and something called the "2PI summation method" to determine if a ray strikes a triangle.

create a plane from your wall and do a ray to plane intersection test. A very simple test is a dot product test. If the result of the vector based scalar 'dot' product is >0, or the vectors are pointing in somewhat the same direction, then you know you are on the near side of the wall. If its <0, or the vectors are nearly pointing in the opposite directions then you are on the far side of the wall

test for pixel perfect, you must find the point at which your camera ray intersected the plane in question. Back the camera up to that point, compute the collision response, and move on

does a ray to triangle test and then computes the barycentric coords of the ray inside of the triangle. It will also bail on NAN's which can cause problems. It only uses dot products as well

The equation for intersection of ray and plane. This is easier to do in a maze because we know that all walls will form a plane so there is no need to do an expensive ray to triangle test.

Ray: p(t)=p0+td
Plane: p dot n=d
Equation: t=(d-p0 dot n)/(d dot n)
If ray is parallel to plane or (d dot n)=0 then there is no intersection.
If (d dot n)<0 then intersection during interval.

Solve for p0 which is actually p0.x and p0.y in this equation as well. This has been solved for t to test for intersection in this time interval. The nice thing about this is the dot product test and point test are rolled up in one algorithm. If the first time interval test passes, you can then solve for p0.

flooding algorithm and then sound propagation. [http://sourceforge.net/projects/argorha/ placing a virtual version of my character at a given position (usually a spawn point). I do an initial ray cast to place him flush against the ground and then add that single occupy-able cell to my "unprocessed list". I then check the four neighbors of that cell to see if a virtual player could step there with out being impeded/falling-climbing too much. I add the successful cells to the unprocessed list, and take my initial cell and put it in the processed list. repeat until the unprocessed list is empty.

The cells in my algorithm also store a position of the ground, and this can go up or down depending on if stairs or a ramp were encountered. When a sector is created from a list of related cells, it uses a axis aligned bounding box that encompass all these points (+ the width and height of each cell)]

A* (A star) algorithm moves through the grid from the given starting point to the given destination. Each "step" it makes it stores in a node. In this node data structure is stored three values

the coordinates of the current block from the start

the distance to the finish position from this block (different methods manhattan, diagonal, euclidian (optional squared version)

and this block's parent block (for a later backtrack mode)

As the algorithm moves towards the destination, it stores these nodes into two stacks: the open and the closed stack. Once the destination block is reached, we go back through the nodes (using the pointer to the parent nodes) and we have our path described

Insert the start point onto the open stack
while( nodes left on open stack ) {
//Pop first (closest) node off of open stack
node = openstack.pop
if( node.bDestination == 1 ) {
Loop upwards through data structure to generate path
exit function
}
//If we get here, this node isn't the destination
for( up, down, forward, backward, left, right in grid ) {
//GetNewNode returns null if block is occupied or in //closed stack
newnode = GetNewNode( currentDirection )
if( newnode ) {
//This InsertSorted function inserts the node //sorted based on the block's distance from the //destination
openstack.InsertSorted(newnode);
}
}
//Once a node is on the closedstack it is no longer used //(unless one of its children is the destination)
closedstack.push( node );
}

In this algorithm the tricky part is actually in the InsertSorted() method of the openstack. You sort the nodes by their distance to the destination. This is the most important part of the algorithm, because the order in which the algorithm picks nodes to search is based on this sorting. Traditionally, (at least in the examples I've seen) you use the Manhattan Distance, which is the distance in grid blocks from the destination. I tweaked this distance function, and instead used the 3D distance of the centerpoint of the current block to the destination (using BlockDistance3D). For whatever reason this made the algorithm work better in my case...it consistantly searched less nodes than using the manhattan distance.