I know this question has been asked several times before, but I can't track where the issue is coming from. For some context, I am updating an 8 year old iPad Powder Toy port to make it compatible on my iPad, but when I run the same project as the iPad port, I get the error ld: 6032 duplicate symbols
. These errors are always happening in combination with a file air.o
. I've checked the file and traced the symbols to a header file defines.h
. In this file, I found the symbols. All of the duplicate symbols are variables, such as int GSPEED
, int ISWIRE
and int CGOL
. I'm still kind of a beginner in C, and these variables are defined only once in the file defines.h
, and not twice (duplicate). I'm attaching relevant files. Thanks for any help, and sorry if this is an obvious mistake.
defines.h
#pragma once
#ifndef PATH_SEP
#define PATH_SEP "/"
#endif
//VersionInfoStart
#ifndef SAVE_VERSION
#define SAVE_VERSION 83
#endif
#ifndef MINOR_VERSION
#define MINOR_VERSION 0
#endif
#ifndef BUILD_NUM
#define BUILD_NUM 205
#endif
//VersionInfoEnd
#ifndef IDENT_VERSION
#define IDENT_VERSION "G" //Change this if you're not Simon! It should be a single letter
#endif
#ifndef MTOS_EXPAND
#define MTOS_EXPAND(str) #str
#endif
#ifndef MTOS
#define MTOS(str) MTOS_EXPAND(str)
#endif
#ifndef LOCAL_SAVE_DIR
#define LOCAL_SAVE_DIR "Saves"
#endif
#ifndef APPDATA_SUBDIR
#define APPDATA_SUBDIR "\\HardWIRED"
#endif
#ifndef THUMB_CACHE_SIZE
#define THUMB_CACHE_SIZE 256
#endif
#ifndef M_PI
#define M_PI 3.14159265f
#endif
#ifndef M_GRAV
#define M_GRAV 6.67300e-1
#endif
#ifndef IMGCONNS
#define IMGCONNS 3
#endif
#ifndef TIMEOUT
#define TIMEOUT 100
#endif
#ifdef RENDERER
#define MENUSIZE 0
#define BARSIZE 0
#else
#define MENUSIZE 25
#define BARSIZE 17
#endif
#ifndef XRES
#define XRES 463
#endif
#ifndef YRES
#define YRES 335
#endif
//#define XRES 230
//#define YRES 168
#ifndef NPART
#define NPART XRES*YRES
#endif
#ifndef MAX_DISTANCE
#define MAX_DISTANCE sqrt(pow(XRES, 2)+pow(YRES, 2))
#endif
#ifndef GRAV_DIFF
#define GRAV_DIFF
#endif
#ifndef MAXSIGNS
#define MAXSIGNS 16
#endif
#ifndef TAG_MAX
#define TAG_MAX 256
#endif
#ifndef ZSIZE_D
#define ZSIZE_D 16
#endif
#ifndef ZFACTOR_D
#define ZFACTOR_D 8
#endif
extern unsigned char ZFACTOR;
extern unsigned char ZSIZE;
#ifndef CELL
#define CELL 4
#endif
#ifndef ISTP
#define ISTP (CELL/2)
#endif
#ifndef CFDS
#define CFDS (4.0f/CELL)
#endif
#define AIR_TSTEPP 0.3f
#define AIR_TSTEPV 0.4f
#define AIR_VADV 0.3f
#define AIR_VLOSS 0.999f
#define AIR_PLOSS 0.9999f
#define GRID_X 5
#define GRID_Y 4
#define GRID_P 3
#define GRID_S 6
#define GRID_Z 3
#define CATALOGUE_X 4
#define CATALOGUE_Y 3
#define CATALOGUE_S 6
#define CATALOGUE_Z 3
#define STAMP_MAX 240
#define SAVE_OPS
//#define REALISTIC
#define NGOL 25
#define NGOLALT 24 //NGOL should be 24, but use this var until I find out why
#define CIRCLE_BRUSH 0
#define SQUARE_BRUSH 1
#define TRI_BRUSH 2
#define BRUSH_NUM 3
#ifdef PIX16
typedef unsigned short pixel;
#else
typedef unsigned int pixel;
#endif
#define SURF_RANGE 10
#define NORMAL_MIN_EST 3
#define NORMAL_INTERP 20
#define NORMAL_FRAC 16
#define REFRACT 0x80000000
/* heavy flint glass, for awesome refraction/dispersion
this way you can make roof prisms easily */
#define GLASS_IOR 1.9
#define GLASS_DISP 0.07
#define SDEUT
//#define REALHEAT
#define DEBUG_PARTS 0x0001
#define DEBUG_PARTCOUNT 0x0002
#define DEBUG_DRAWTOOL 0x0004
#define DEBUG_PERFORMANCE_CALC 0x0008
#define DEBUG_PERFORMANCE_FRAME 0x0010
typedef unsigned char uint8;
extern int saveURIOpen;
extern char * saveDataOpen;
extern int saveDataOpenSize;
extern int amd;
extern int FPSB;
int NUM_PARTS;
int GRAV;
int GRAV_R;
int GRAV_G;
int GRAV_B;
int GRAV_R2;
int GRAV_G2;
int GRAV_B2;
extern int legacy_enable;
extern int kiosk_enable;
extern int aheat_enable;
extern int decorations_enable;
extern int active_menu;
extern int hud_enable;
extern int pretty_powder;
extern int drawgrav_enable;
extern int ngrav_enable;
extern char bframe;
int limitFPS;
int water_equal_test;
//extern int quickoptions_tooltip_fade;
extern int loop_time;
extern int debug_flags;
#define DEBUG_PERF_FRAMECOUNT 256
extern int debug_perf_istart;
extern int debug_perf_iend;
extern long debug_perf_frametime[DEBUG_PERF_FRAMECOUNT];
extern long debug_perf_partitime[DEBUG_PERF_FRAMECOUNT];
extern long debug_perf_time;
extern int active_menu;
extern int sys_pause;
extern int framerender;
extern int mousex, mousey;
struct sign
{
int x,y,ju;
char text[256];
};
typedef struct sign sign;
struct stamp
{
char name[11];
pixel *thumb;
int thumb_w, thumb_h, dodelete;
};
typedef struct stamp stamp;
int frameidx;
int MSIGN;
int CGOL;
int ISGOL;
int ISLOVE;
int ISLOLZ;
int ISGRAV;
int ISWIRE;
int GSPEED;
int love[XRES/9][YRES/9];
int lolz[XRES/9][YRES/9];
unsigned char gol[YRES][XRES];
unsigned char gol2[YRES][XRES][NGOL+1];
int SEC;
int SEC2;
int console_mode;
int REPLACE_MODE;
int CURRENT_BRUSH;
int GRID_MODE;
int VINE_MODE;
int DEBUG_MODE;
int GENERATION;
int ISSPAWN1;
int ISSPAWN2;
extern sign signs[MAXSIGNS];
extern stamp stamps[STAMP_MAX];
extern int stamp_count;
extern int itc;
extern char itc_msg[64];
extern int do_open;
extern int sys_pause;
extern int sys_shortcuts;
extern int legacy_enable; //Used to disable new features such as heat, will be set by commandline or save.
extern int framerender;
extern pixel *vid_buf;
extern unsigned char last_major, last_minor, last_build;
//Functions in main.c
void thumb_cache_inval(char *id);
void thumb_cache_add(char *id, void *thumb, int size);
int thumb_cache_find(char *id, void **thumb, int *size);
void clear_sim(void);
void del_stamp(int d);
int set_scale(int scale, int kiosk);
The duplicate variables are at the bottom.
air.c
#include <math.h>
#include "air.h"
#include "powder.h"
#include "defines.h"
#include "gravity.h"
float kernel[9];
float vx[YRES/CELL][XRES/CELL], ovx[YRES/CELL][XRES/CELL];
float vy[YRES/CELL][XRES/CELL], ovy[YRES/CELL][XRES/CELL];
float pv[YRES/CELL][XRES/CELL], opv[YRES/CELL][XRES/CELL];
unsigned char bmap_blockair[YRES/CELL][XRES/CELL];
unsigned char bmap_blockairh[YRES/CELL][XRES/CELL];
float cb_vx[YRES/CELL][XRES/CELL];
float cb_vy[YRES/CELL][XRES/CELL];
float cb_pv[YRES/CELL][XRES/CELL];
float cb_hv[YRES/CELL][XRES/CELL];
float fvx[YRES/CELL][XRES/CELL], fvy[YRES/CELL][XRES/CELL];
float hv[YRES/CELL][XRES/CELL], ohv[YRES/CELL][XRES/CELL]; // For Ambient Heat
void make_kernel(void) //used for velocity
{
int i, j;
float s = 0.0f;
for (j=-1; j<2; j++)
for (i=-1; i<2; i++)
{
kernel[(i+1)+3*(j+1)] = expf(-2.0f*(i*i+j*j));
s += kernel[(i+1)+3*(j+1)];
}
s = 1.0f / s;
for (j=-1; j<2; j++)
for (i=-1; i<2; i++)
kernel[(i+1)+3*(j+1)] *= s;
}
void update_airh(void)
{
int x, y, i, j;
float odh, dh, dx, dy, f, tx, ty;
for (i=0; i<YRES/CELL; i++) //reduces pressure/velocity on the edges every frame
{
hv[i][0] = 295.15f;
hv[i][1] = 295.15f;
hv[i][XRES/CELL-3] = 295.15f;
hv[i][XRES/CELL-2] = 295.15f;
hv[i][XRES/CELL-1] = 295.15f;
}
for (i=0; i<XRES/CELL; i++) //reduces pressure/velocity on the edges every frame
{
hv[0][i] = 295.15f;
hv[1][i] = 295.15f;
hv[YRES/CELL-3][i] = 295.15f;
hv[YRES/CELL-2][i] = 295.15f;
hv[YRES/CELL-1][i] = 295.15f;
}
for (y=0; y<YRES/CELL; y++) //update velocity and pressure
{
for (x=0; x<XRES/CELL; x++)
{
dh = 0.0f;
dx = 0.0f;
dy = 0.0f;
for (j=-1; j<2; j++)
{
for (i=-1; i<2; i++)
{
if (y+j>0 && y+j<YRES/CELL-2 &&
x+i>0 && x+i<XRES/CELL-2 &&
!bmap_blockairh[y+j][x+i])
{
f = kernel[i+1+(j+1)*3];
dh += hv[y+j][x+i]*f;
dx += vx[y+j][x+i]*f;
dy += vy[y+j][x+i]*f;
}
else
{
f = kernel[i+1+(j+1)*3];
dh += hv[y][x]*f;
dx += vx[y][x]*f;
dy += vy[y][x]*f;
}
}
}
tx = x - dx*0.7f;
ty = y - dy*0.7f;
i = (int)tx;
j = (int)ty;
tx -= i;
ty -= j;
if (i>=2 && i<XRES/CELL-3 && j>=2 && j<YRES/CELL-3)
{
odh = dh;
dh *= 1.0f - AIR_VADV;
dh += AIR_VADV*(1.0f-tx)*(1.0f-ty)*(bmap_blockairh[j][i] ? odh : hv[j][i]);
dh += AIR_VADV*tx*(1.0f-ty)*(bmap_blockairh[j][i+1] ? odh : hv[j][i+1]);
dh += AIR_VADV*(1.0f-tx)*ty*(bmap_blockairh[j+1][i] ? odh : hv[j+1][i]);
dh += AIR_VADV*tx*ty*(bmap_blockairh[j+1][i+1] ? odh : hv[j+1][i+1]);
}
pv[y][x] += (dh-hv[y][x])/5000.0f;
if(!gravityMode){ //Vertical gravity only for the time being
float airdiff = hv[y-1][x]-hv[y][x];
if(airdiff>0 && !bmap_blockairh[y-1][x])
vy[y][x] -= airdiff/5000.0f;
}
ohv[y][x] = dh;
}
}
memcpy(hv, ohv, sizeof(hv));
}
void update_air(void)
{
int x, y, i, j;
float dp, dx, dy, f, tx, ty;
if (airMode != 4) { //airMode 4 is no air/pressure update
for (i=0; i<YRES/CELL; i++) //reduces pressure/velocity on the edges every frame
{
pv[i][0] = pv[i][0]*0.8f;
pv[i][1] = pv[i][1]*0.8f;
pv[i][2] = pv[i][2]*0.8f;
pv[i][XRES/CELL-2] = pv[i][XRES/CELL-2]*0.8f;
pv[i][XRES/CELL-1] = pv[i][XRES/CELL-1]*0.8f;
vx[i][0] = vx[i][1]*0.9f;
vx[i][1] = vx[i][2]*0.9f;
vx[i][XRES/CELL-2] = vx[i][XRES/CELL-3]*0.9f;
vx[i][XRES/CELL-1] = vx[i][XRES/CELL-2]*0.9f;
vy[i][0] = vy[i][1]*0.9f;
vy[i][1] = vy[i][2]*0.9f;
vy[i][XRES/CELL-2] = vy[i][XRES/CELL-3]*0.9f;
vy[i][XRES/CELL-1] = vy[i][XRES/CELL-2]*0.9f;
}
for (i=0; i<XRES/CELL; i++) //reduces pressure/velocity on the edges every frame
{
pv[0][i] = pv[0][i]*0.8f;
pv[1][i] = pv[1][i]*0.8f;
pv[2][i] = pv[2][i]*0.8f;
pv[YRES/CELL-2][i] = pv[YRES/CELL-2][i]*0.8f;
pv[YRES/CELL-1][i] = pv[YRES/CELL-1][i]*0.8f;
vx[0][i] = vx[1][i]*0.9f;
vx[1][i] = vx[2][i]*0.9f;
vx[YRES/CELL-2][i] = vx[YRES/CELL-3][i]*0.9f;
vx[YRES/CELL-1][i] = vx[YRES/CELL-2][i]*0.9f;
vy[0][i] = vy[1][i]*0.9f;
vy[1][i] = vy[2][i]*0.9f;
vy[YRES/CELL-2][i] = vy[YRES/CELL-3][i]*0.9f;
vy[YRES/CELL-1][i] = vy[YRES/CELL-2][i]*0.9f;
}
for (j=1; j<YRES/CELL; j++) //clear some velocities near walls
{
for (i=1; i<XRES/CELL; i++)
{
if (bmap_blockair[j][i])
{
vx[j][i] = 0.0f;
vx[j][i-1] = 0.0f;
vy[j][i] = 0.0f;
vy[j-1][i] = 0.0f;
}
}
}
for (y=1; y<YRES/CELL; y++) //pressure adjustments from velocity
for (x=1; x<XRES/CELL; x++)
{
dp = 0.0f;
dp += vx[y][x-1] - vx[y][x];
dp += vy[y-1][x] - vy[y][x];
pv[y][x] *= AIR_PLOSS;
pv[y][x] += dp*AIR_TSTEPP;
}
for (y=0; y<YRES/CELL-1; y++) //velocity adjustments from pressure
for (x=0; x<XRES/CELL-1; x++)
{
dx = dy = 0.0f;
dx += pv[y][x] - pv[y][x+1];
dy += pv[y][x] - pv[y+1][x];
vx[y][x] *= AIR_VLOSS;
vy[y][x] *= AIR_VLOSS;
vx[y][x] += dx*AIR_TSTEPV;
vy[y][x] += dy*AIR_TSTEPV;
if (bmap_blockair[y][x] || bmap_blockair[y][x+1])
vx[y][x] = 0;
if (bmap_blockair[y][x] || bmap_blockair[y+1][x])
vy[y][x] = 0;
}
for (y=0; y<YRES/CELL; y++) //update velocity and pressure
for (x=0; x<XRES/CELL; x++)
{
dx = 0.0f;
dy = 0.0f;
dp = 0.0f;
for (j=-1; j<2; j++)
for (i=-1; i<2; i++)
if (y+j>0 && y+j<YRES/CELL-1 &&
x+i>0 && x+i<XRES/CELL-1 &&
!bmap_blockair[y+j][x+i])
{
f = kernel[i+1+(j+1)*3];
dx += vx[y+j][x+i]*f;
dy += vy[y+j][x+i]*f;
dp += pv[y+j][x+i]*f;
}
else
{
f = kernel[i+1+(j+1)*3];
dx += vx[y][x]*f;
dy += vy[y][x]*f;
dp += pv[y][x]*f;
}
tx = x - dx*0.7f;
ty = y - dy*0.7f;
i = (int)tx;
j = (int)ty;
tx -= i;
ty -= j;
if (i>=2 && i<XRES/CELL-3 &&
j>=2 && j<YRES/CELL-3)
{
dx *= 1.0f - AIR_VADV;
dy *= 1.0f - AIR_VADV;
dx += AIR_VADV*(1.0f-tx)*(1.0f-ty)*vx[j][i];
dy += AIR_VADV*(1.0f-tx)*(1.0f-ty)*vy[j][i];
dx += AIR_VADV*tx*(1.0f-ty)*vx[j][i+1];
dy += AIR_VADV*tx*(1.0f-ty)*vy[j][i+1];
dx += AIR_VADV*(1.0f-tx)*ty*vx[j+1][i];
dy += AIR_VADV*(1.0f-tx)*ty*vy[j+1][i];
dx += AIR_VADV*tx*ty*vx[j+1][i+1];
dy += AIR_VADV*tx*ty*vy[j+1][i+1];
}
if (bmap[y][x] == WL_FAN)
{
dx += fvx[y][x];
dy += fvy[y][x];
}
// pressure/velocity caps
if (dp > 256.0f) dp = 256.0f;
if (dp < -256.0f) dp = -256.0f;
if (dx > 256.0f) dx = 256.0f;
if (dx < -256.0f) dx = -256.0f;
if (dy > 256.0f) dy = 256.0f;
if (dy < -256.0f) dy = -256.0f;
switch (airMode)
{
default:
case 0: //Default
break;
case 1: //0 Pressure
dp = 0.0f;
break;
case 2: //0 Velocity
dx = 0.0f;
dy = 0.0f;
break;
case 3: //0 Air
dx = 0.0f;
dy = 0.0f;
dp = 0.0f;
break;
case 4: //No Update
break;
}
ovx[y][x] = dx;
ovy[y][x] = dy;
opv[y][x] = dp;
}
memcpy(vx, ovx, sizeof(vx));
memcpy(vy, ovy, sizeof(vy));
memcpy(pv, opv, sizeof(pv));
}
}
This file is present in every duplicate symbol error.
air.h
#ifndef AIR_H
#define AIR_H
#include "defines.h"
extern float vx[YRES/CELL][XRES/CELL], ovx[YRES/CELL][XRES/CELL];
extern float vy[YRES/CELL][XRES/CELL], ovy[YRES/CELL][XRES/CELL];
extern float pv[YRES/CELL][XRES/CELL], opv[YRES/CELL][XRES/CELL];
extern unsigned char bmap_blockair[YRES/CELL][XRES/CELL];
extern unsigned char bmap_blockairh[YRES/CELL][XRES/CELL];
extern float cb_vx[YRES/CELL][XRES/CELL];
extern float cb_vy[YRES/CELL][XRES/CELL];
extern float cb_pv[YRES/CELL][XRES/CELL];
extern float cb_hv[YRES/CELL][XRES/CELL];
extern float fvx[YRES/CELL][XRES/CELL], fvy[YRES/CELL][XRES/CELL];
extern float hv[YRES/CELL][XRES/CELL], ohv[YRES/CELL][XRES/CELL]; // Ambient Heat
extern float kernel[9];
void make_kernel(void);
void update_airh(void);
void update_air(void);
#endif