Monday, April 25, 2011

Makefile.win [Build Error] ["mouse] Error 1

The Problem

I'm using Dev c++ making a GUI file using SDL. So everything is going good. There are not code errors or link errors but I get this error:

Makefile.win [Build Error] ["mouse] Error 1

It can be a consortium of things but most likely it is because I haven't declared the correct parameters.

Solution

Properly input your parameters. Go to:

project->project options

under the parameters tab put in the names of the files you plan to link like so:

voila you should be good.

Tuesday, April 19, 2011

error LNK2005: "" () already defined in main.obj

Game dev thread
Quick Fix
Full Solution
My Comments

The Problem

What does an error like this mean?

1>Particle.obj : error LNK2005: "struct SDL_Surface * red" (?red@@3PAUSDL_Surface@@A) already defined in main.obj

to put it simply it means that a global variable is defined in two source files because you included the same header file in two different source files.



Lets say I have two source files main.cpp and particle.cpp and a header file called globalobjs.h. In my header file I declare a variable of integer type. Now I need to use this number in both main.cpp and particle.cpp so I'm going to #include "globalobs.h" in both source files. But here is the problem, if I include that globalobjs twice it is like saying the line:
int variable;
twice and so the the linker gives an error message. It is because it doesn't know if I am talking about the same variable or two different variables. It wonders if you want the same variable used in two source files or if you want the two source files to have their own integer called variable. The same logical conclusions would apply for any other type of variable or even functions

In my case here is my Header file called particle.h:

#pragma once
#include 

SDL_Surface *red;
SDL_Surface *green;
SDL_Surface *blue;
SDL_Surface *shimmer;

#ifndef PARTICLE
#define PARTICLE


class Particle
{
protected:
        //offsets
        int x,y;        

        // current frame of animation
        int frame;

        //type of particle
        SDL_Surface* type;

public:
        Particle(int X, int Y);
        ~Particle(void);
        void show();
        bool is_dead();
};

#endif

And here is one of my source files called particles.cpp:

#include "Particle.h"

Particle::Particle(int X, int Y)
{
        x = X + 5 + (rand()%25);
        y = Y + 5 + (rand()%25);

        frame = rand() % 5;

        switch(rand()%3)
        {
        case 0:
                type = red;
                break;
        case 1:
                type = green;
                break;
        case 2:
                type = blue;
                break;
        }
}

As you may have noticed I declared a few pointers red, green, blue which I use to define the member functions of the class I have created in the header file. Those same pointers are again used in the main source file. So now its obvious why i get the message:
1>Particle.obj : error LNK2005: "struct SDL_Surface * red" (?red@@3PAUSDL_Surface@@A) already defined in main.obj
when I try to compile and run my program.

Solution

The way you solve this problem is to explicitly declare variables you want to be globally used as external variables using the keyword etern. A quick reference about the extern keyword can be found here. When you use the word extern it is a way of declaring the variable exists but will be defined a value elsewhere. So now when I include my header file in my source file and declare my pointers as such:
SDL_Surface *red;
The compiler understands that there exists a pointer called red and it may be defined elsewhere.

It is important also to define it elsewhere. That is why in my main.cpp source file I include the particles.h header file and I have the line:
SDL_Surface *red = NULL;
which explicitly defines my pointer. So now I can even call this pointer in another file and it will return the NULL value which I have just assigned.

So to recap:
Declare global variables and functions with the keyword extern in the header file
Define those global variables or functions in one< of the source files


Comments

One more thing I messed up regarding the same topic is to create a global variables header file. Every single declaration needs to be with the keyword extern. Also, For constant terms like:
const int screen_height=1000
declare them as constant static integers.
More over for declarations that don't need to be defined, such as unions, you only need to re-declare them in another source file. For example I say:
SDL_Event event;
in the header file. So in my main.cpp source file i say:
SDL_Event event;

Here is what my completed Global header file looks like:
#include 
#include 
#include 


#ifndef GLOBALFNS
#define GLOBALFNS

//declare some poiters
extern SDL_Surface *dot;
extern SDL_Surface *screen;

extern SDL_Event event;

extern int ScreenW;
extern int ScreenH;

//external functions
extern "C++"{

//The dimensions of the dot
const static int DOT_WIDTH = 20;
const static int DOT_HEIGHT = 20;



//total paticles
const static int TOTAL_PARTICLES = 20;

//SDL supporting functions start
SDL_Surface* loadimg(std::string filename);

void applysurface(int x, int y, SDL_Surface* src, SDL_Surface* dst, SDL_Rect* clop);
}

#endif

Saturday, April 16, 2011

Auto Clicker Hard mod

Purpose

I wanted to create an autoclicker that is not a software app. The problem with these apps is that they are usually not allowed on multiplayer games. So the concept is to create a physical autoclicker by modding a computer mouse.

Essentially, the left mouse button is an open switch; when clicked it is closed. So closing the switch with a circuit will output a click. A circuit that closes many times a second will create the auto clicker effect needed. Simple as pie.

Materials

Get:

A USB mouse
some 24 gage wire

PNP transistor
10k potentiometer
10k resistor
Push button switch
555 timer
100nF capacitor
100uF capacitor (electrolytic)
10uF capacitor (electrolytic)

Procedure

First thing is first, the circuit. Using a 555 timer chip build a prototype astable circuit. Build the circuit described here at the mechano website or follow the schematic below.

Astable mouse circuit
Test the circuit by placing an LED, a speaker or a probe in series with ground and pin 3. It should go on and off. Remove the LED and connect the out put (pin 3) to the base of the PNP transistor. Next take apart the mouse and look for the left click button. Use a multimeter to find the positive end negative end of the switch then connect the remaining two pins of the Transistor accordingly.

Laslty, find the power of you mouse, It could either be where the battery is or if it is a usb mouse look for a colorful array of wires and find the correct two using a multimeter. You will know the two correct ones either by the markings on the mouse or by getting a +3v to +5v reading on the multimeter. Connect your circuit's positive lead to the positive and the negative to the negative.

One more touch, connect a push button switch From the power to the circuit. This make sure that autoclicking only happens when the button is pressed.

Comments

This circuit works for more than just a mouse. It can work for any circuit where a you need a switch to be closed. So for example, you want a camera to take pictures after a certain interval, or you want a paintball gun to fire automatically.

Also, in case you do not want, or do not have access to the mouse's power you can replace the PNP transistor with an OPTOisolator. It will isolate the clicker circuit from the mouse's circuit (kind of like a relay) so that the clicker circuit can run on its own power supply.

Friday, April 15, 2011

Deep copying a vector c++

Read the Game Dev Forum
Read the Solution
Read the Conclusion


The Problem

Recently I came across a problem when copying vectors in c++. So I say something like this:

clone_vector = original_vector;

Where the orignal_vector is a vector of pointers to objects, all of which have a common base class and also a string stream as a private member. A simplified version of the objects held in the vector is as follows:


class Digit
{
        protected:
                //x and y positons
                int Xpos;
                int Ypos;
  
                //value in string format
                std::stringstream svalue;
        
  public:
        Digit();
        
};


class Realnum: public Digit
{
protected:
        float value;
public:
        Realnum( int  x, int y);

};


The problem with the copy statement is that this is what is called "shallow copying". Shallow copying does not dereference pointers, in other words pointers in the clone_vector point to the address of pointers in the original_vector. So if you change a value in the orignal_vector you will automatically change a value in the clone_vector and vice versa. A good picture and explanation of deep vs shallow copy can be found at the wikipedia page . I want to be able to create a clone copy of my vector that I can manipulate without manipulating the original and vice versa.


Solution


To deep copy a vector composed of objects in a derived class that also contain a string stream member (trust me that's imposing a lot of conditions, if you can copy this you can copy anything) you need to do the following.

1. Create a copy constructor such that each time an object is created in the clone vector it has it is deferenced
(a copy constructor is a constructor that takes a previously existing instance and make a copy of it. Read about it here)

2. create a desctructor

3. create a clone function to properly create a copy

4. Implement a copying process to create clones of vectors

So Here is what The class now looks like:

class Digit
{
        protected:
                //x and y positons
                int Xpos;
                int Ypos;
  
                //value in string format
                std::stringstream svalue;
        
  public:
        Digit();
        Digit(const Digit &copy)
{
Xpos = copy.Xpos;
Ypos = copy.Ypos;

svalue << copy.svalue.str();
}

        ~Digit();

//copy fucntion
                virtual Digit* clone() const
        { return new Digit( *this ); }

};


class Realnum: public Digit
{
protected:
        float value;
public:
        Realnum( int  x, int y);
        Realnum(const Realnum &copy): Digit(copy)
        {
value = copy.value;
}
        ~Realnum();

//copy fucntion
Realnum* clone() const
        {return new Realnum( *this);}
};


Notice that the derived class has a copy constructor which gives argument to the super classes copy constructor and that each copy constructor assigns every private member (variables of the object) a value. That what needs to be done if you want to use polymorphism when copying. Also notice that the clone function is virtual in the base class. That is because it is better to define a clone function for each subclass. Now copy using this technique:

//resize the clone vector
  clone_vector.resize(original_vector.size());

  for(int i=0; i< original_vector.size(); i++)
  {
   clone_vector[i] = original_vector[i]->clone();
  }
each element of the vector is properly cloned using deep copy. Voila!

Conclusion

There are most likely other techniques to cloning vectors this is just one of them. Also this is a simplified example I used in order to post the question on the gamedev forum. The real classes contain lots of members including pointers and 2 other derived classes. For a clear reference to this problem review the code in "aside 14 math game".

Monday, April 4, 2011

Hello world

[code]
Hello world,

This problem is in the form of a blog.

I attempt to record my mistakes in electronics and programming in this blog for future reference to myself. The reason I include both coding and electronics is because they are one in the same. They both rely on the same logic to solve a problem. And so A blog to fill in my gaps in logic this will be.