2011-12-21 3 views
10

PSP 자작 응용 프로그램을 프로그래밍하기 전까지는이 링커 오류가 발생하지 않았습니다. 어쨌든, 나는 알레그로 게임을하고 있는데,이 경우 발사체 나 미사일을 발사해야합니다. 역동적이고 일반적인 배열을 사용해야합니다. 그러나 링커는 new 연산자에 대한 정의되지 않은 참조가 있다고 불평합니다. 아래는 전체 소스 코드, 메이크 파일 및 오류 세부 사항입니다.새 연산자에 대한 정의되지 않은 참조

오류 정보 :

1>------ Build started: Project: PSP Asteroids, Configuration: Debug Win32 ------ 
1> psp-g++ -I. -IC:/pspsdk/psp/sdk/include -O2 -G0 -Wall -I. -IC:/pspsdk/psp/sdk/include -O2 -G0 -Wall -fno-exceptions -fno-rtti -D_PSP_FW_VERSION=150 -c -o main.o main.cpp 
1> psp-gcc -I. -IC:/pspsdk/psp/sdk/include -O2 -G0 -Wall -D_PSP_FW_VERSION=150 -L. -LC:/pspsdk/psp/sdk/lib main.o -lalleg -lpspgu -lpspirkeyb -lm -lpsppower -lpspaudio -lpsprtc -lpspdebug -lpspdisplay -lpspge -lpspctrl -lpspsdk -lc -lpspnet -lpspnet_inet -lpspnet_apctl -lpspnet_resolver -lpsputility -lpspuser -lpspkernel -o main.elf 
1> main.o: In function `std::vector<Missile*, std::allocator<Missile*> >::_M_insert_aux(__gnu_cxx::__normal_iterator<Missile**, std::vector<Missile*, std::allocator<Missile*> > >, Missile* const&)': 
1> main.cpp:(.text._ZNSt6vectorIP7MissileSaIS1_EE13_M_insert_auxEN9__gnu_cxx17__normal_iteratorIPS1_S3_EERKS1_[_ZNSt6vectorIP7MissileSaIS1_EE13_M_insert_auxEN9__gnu_cxx17__normal_iteratorIPS1_S3_EERKS1_]+0xb8): undefined reference to `operator new(unsigned int)' 
1> main.cpp:(.text._ZNSt6vectorIP7MissileSaIS1_EE13_M_insert_auxEN9__gnu_cxx17__normal_iteratorIPS1_S3_EERKS1_[_ZNSt6vectorIP7MissileSaIS1_EE13_M_insert_auxEN9__gnu_cxx17__normal_iteratorIPS1_S3_EERKS1_]+0x124): undefined reference to `operator delete(void*)' 
1> C:\pspsdk\bin\make: *** [main.elf] Error 1 
========== Build: 1 succeeded, 0 failed, 0 up-to-date, 0 skipped ========== 

메이크

TARGET = main 
OBJS = main.o 

CFLAGS = -O2 -G0 -Wall 
CXXFLAGS = $(CFLAGS) -fno-exceptions -fno-rtti 
ASFLAGS = $(CFLAGS) 

EXTRA_TARGETS = EBOOT.PBP 
PSP_EBOOT_TITLE = PSP Asteroids 
LIBS = -lalleg -lpspgu -lpspirkeyb -lm -lpsppower -lpspaudio -lpsprtc 
PSPSDK=$(shell psp-config --pspsdk-path) 
include $(PSPSDK)/lib/build.mak 

MAIN.CPP

#define ALLEGRO_NO_MAGIC_MAIN 
#define WIDTH 480 
#define HEIGHT 272 
#include <pspkernel.h> 
#include <pspdebug.h> 
#include <pspctrl.h> 
#include <allegro.h> 
#include <math.h> 
#include <vector> 
PSP_MODULE_INFO("PSP Asteroids", 0, 1, 1); 
int check_bb_collision (BITMAP* spr1, BITMAP* spr2, int x1, int y1, int x2, int y2) 
{ 
    int b1_x = x1; 
    int b2_x = x2; 
    int b1_y = y1; 
    int b2_y = y2; 
    int b1_w = spr1->w; 
    int b2_w = spr2->w; 
    int b1_h = spr1->h; 
    int b2_h = spr2->h; 
    if ((b1_x > b2_x + b2_w - 1) || // is b1 on the right side of b2? 
       (b1_y > b2_y + b2_h - 1)  || // is b1 under b2? 
       (b2_x > b1_x + b1_w - 1)  || // is b2 on the right side of b1? 
       (b2_y > b1_y + b1_h - 1))   // is b2 under b1? 
    { 
     // no collision 
     return 0; 
    } 

    // collision 
    return 1; 
} 
//Pass 2 Allegro bitmaps and their respective positions and this function 
//returns true if there is a collision and false if theres not. 
//The 2 bitmaps must be memory bitmaps of the same color depth. 
int check_pp_collision_normal(BITMAP *spr1, BITMAP *spr2, int x1, int y1, int x2, int y2) 
{ 
int dx1, dx2, dy1, dy2; //We will use this deltas... 
int fx,fy,sx1,sx2; //Also we will use this starting/final position variables... 
int maxw, maxh; //And also this variables saying what is the maximum width and height... 
int depth; //This will store the color depth value... 
char CHARVAR; //We will use these to store the transparent color for the sprites... 
short SHORTVAR; 
long LONGVAR; 

if(!check_bb_collision(spr1, spr2, x1,y1, x2,y2)) return 0; //If theres not a bounding box collision, it is impossible to have a pixel perfect collision right? So, we return that theres not collision... 

//First we need to see how much we have to shift the coordinates of the sprites... 
if(x1>x2) { 
    dx1=0;  //don't need to shift sprite 1. 
    dx2=x1-x2; //shift sprite 2 left. Why left? Because we have the sprite 1 being on the right of the sprite 2, so we have to move sprite 2 to the left to do the proper pixel perfect collision... 
    } else { 
    dx1=x2-x1; //shift sprite 1 left. 
    dx2=0;  //don't need to shift sprite 2. 
    } 
if(y1>y2) { 
    dy1=0; 
    dy2=y1-y2; //we need to move this many rows up sprite 2. Why up? Because we have sprite 1 being down of sprite 2, so we have to move sprite 2 up to do the proper pixel perfect collision detection... 
    } else { 
    dy1=y2-y1; //we need to move this many rows up sprite 1. 
    dy2=0; 
    } 

//Then, we have to see how far we have to go, we do this seeing the minimum height and width between the 2 sprites depending in their positions: 
if(spr1->w-dx1 > spr2->w-dx2) { 
    maxw=spr2->w-dx2; 
    } else { 
    maxw=spr1->w-dx1; 
    } 
if(spr1->h-dy1 > spr2->h-dy2) { 
    maxh=spr2->h-dy2; 
    } else { 
    maxh=spr1->h-dy1; 
    } 
maxw--; 
maxh--; 

fy=dy1; 
fx=dx1; 
dy1+=maxh; 
dy2+=maxh; 
sx1=dx1+maxw; 
sx2=dx2+maxw; 

depth=bitmap_color_depth(spr1); //Get the bitmap depth... 

if(depth==8) { 
    CHARVAR=bitmap_mask_color(spr1); //Get the transparent color of the sprites... 
    for(; dy1>=fy; dy1--,dy2--) { //Go through lines... 
     for(dx1=sx1,dx2=sx2; dx1>=fx; dx1--,dx2--) { //Go through the X axis... 
     if((spr1->line[dy1][dx1]!=CHARVAR) && (spr2->line[dy2][dx2]!=CHARVAR)) return 1; //Both sprites don't have transparent color in that position, so, theres a collision and return collision detected! 
     } 
     } 
    } else { 
    if(depth==16 || depth==15) { 
    SHORTVAR=bitmap_mask_color(spr1); //Get the transparent color of the sprites... 
    for(; dy1>=fy; dy1--,dy2--) { //Go through lines... 
     for(dx1=sx1,dx2=sx2; dx1>=fx; dx1--,dx2--) { //Go through the X axis... 
      if((((short *)spr1->line[dy1])[dx1]!=SHORTVAR) && (((short *)spr2->line[dy2])[dx2]!=SHORTVAR)) return 1; //Both sprites don't have transparent color in that position, so, theres a collision and return collision detected! 
      } 
     } 
    } else { 
    if(depth==32) { 
     LONGVAR=bitmap_mask_color(spr1); //Get the transparent color of the sprites... 
     for(; dy1>=fy; dy1--,dy2--) { //Go through lines... 
      for(dx1=sx1,dx2=sx2; dx1>=fx; dx1--,dx2--) { //Go through the X axis... 
      if((((long *)spr1->line[dy1])[dx1]!=LONGVAR) && (((long *)spr2->line[dy2])[dx2]!=LONGVAR)) return 1; //Both sprites don't have transparent color in that position, so, theres a collision and return collision detected! 
      } 
      } 
     } else { 
     if(depth==24) { 
     CHARVAR=bitmap_mask_color(spr1)>>16; //if the order is RGB, this will contain B... 
     SHORTVAR=bitmap_mask_color(spr1)&0xffff; //if the order is RGB, this will contain GR... 
     for(; dy1>=fy; dy1--,dy2--) { //Go through lines... 
      for(dx1=sx1,dx2=sx2; dx1>=fx; dx1--,dx2--) { //Go through the X axis... 
       if((*((short *)(spr1->line[dy1]+(dx1)*3))!=SHORTVAR) && (spr1->line[dy1][(dx1)*3+2]!=CHARVAR) && (*((short *)(spr2->line[dy2]+(dx2)*3))!=SHORTVAR) && (spr2->line[dy2][(dx2)*3+2]!=CHARVAR)) return 1; //Both sprites don't have transparent color in that position, so, theres a collision and return collision detected! 
       //I have tryed to avoid the above multiplications but it seems that GCC optimizes better than I :-)) 
       } 
      } 
     } 
     } 
    } 
    } 

//If we have reached here it means that theres not a collision: 
return 0; //Return no collision. 
} 
//Finds the magnitude from a point in 2d. 
double magnitude(int x, int y) 
{ 

    return sqrt((x * x) + (y* y)); 
} 
char* itoa(int val, int base){ 

    static char buf[32] = {0}; 

    int i = 30; 

    for(; val && i ; --i, val /= base) 

     buf[i] = "abcdef"[val % base]; 

    return &buf[i+1]; 

} 
// static class that contain special game constants 
class Constants 
{ 
    public: 
     static const double PI = 3.14159265358979323846; 
     static const double PIOVER4 = (3.14159265358979323846/4); 
     static const double TWOPI = (2 * 3.14159265358979323846); 
     static const double PIOVER2 = (3.14159265358979323846/2); 
     static const unsigned int MAXBULLETS = 5; 
}; 
// Clamp 
inline float clamp(float x, float min, float max) 
{ 
    return x < min ? min : (x > max ? max : x); 
} 
// The ship class 
class Ship 
{ 
    public: 
     double X; 
     static const double Y = (272 - 64); 
     double angle; 
     void Init(int x) 
     { 

      angle = 0; 
      X = x; 
     } 
     void MoveLeft() 
     { 
      X -= 2; 

     } 
     void MoveRight() 
     { 
      X += 2; 
     } 

     void Draw(BITMAP* buffer, BITMAP* sprite, int frame) 
     { 
      X = clamp(X, 0, 480); 
      draw_sprite(buffer, sprite, X, Y); 
     } 
}; 
class Missile 
{ 
    private: 
     static const double angle = (3.14159265358979323846/2); 
    public: 
     bool Alive; 
     static const int V = 5; 
     double X; 
     double Y; 
     void Init(bool alive, int x, int y) 
     { 
      Alive = alive; 
      X = x; 
      Y = y; 
     } 
     void Update() 
     { 
      X += V * cos(angle); 
      Y += V * sin(angle); 
     } 
     void Kill() 
     { 
      Alive = false; 
     } 
     void Draw(BITMAP* buffer, BITMAP* sprite) 
     { 
      draw_sprite(buffer, sprite, X, Y); 
     } 
}; 
std::vector<Missile*>* bullets = (std::vector<Missile*>*)malloc(1); 
void FireBullet(Ship* s) 
{ 
    if (bullets->size() < Constants::MAXBULLETS) 
    { 
     Missile* missile = (Missile*)malloc(1); 
     missile->Init(true, s->X, s->Y); 
     bullets->push_back(missile); 
    } 
} 

void CleanUp() 
{ 
    for(unsigned int index = 0; index < bullets->size(); index++) 
    { 

     if (bullets->at(index)->Alive == false) 
     { 
      bullets->erase(bullets->begin() + index); 
     } 
    } 
} 
void UpdateBullets() 
{ 
    for(unsigned int index = 0; index < bullets->size(); index++) 
    { 
     if (bullets->at(index)->Y < 0) 
     { 
      bullets->at(index)->Update(); 
     } 
     else 
     { 
      bullets->at(index)->Kill(); 
     } 
    } 
} 
void DrawBullets(BITMAP* buffer, BITMAP* sprite) 
{ 
    for(unsigned int index = 0; index < bullets->size(); index++) 
    { 
     if (bullets->at(index)->Alive == true) 
     { 
      bullets->at(index)->Draw(buffer, sprite); 
     } 
    } 
} 
//Entry point of the application 
int main(void) 
{ 

    Ship* s = (Ship*)malloc(1); 
    int x = (WIDTH/2) - 64; 
    allegro_message("Initialzing ship class"); 
    s->Init(x); 
    int frame = 0; 
    BITMAP* buffer = NULL; 
    BITMAP* background = NULL; 
    BITMAP* ship = NULL; 
    SceCtrlData pad; 
    bool done = false; 
    allegro_message("Initializing Game..."); 
    int rval = allegro_init(); 
    if (allegro_init() != 0) 
    { 
     allegro_message("Error initializing Game Because it returned: %i", rval); 
     return 1; 
    } 
    allegro_message("Setting Graphics Mode...Press X To Begin Game"); 
    set_color_depth(32); 
    int ret = set_gfx_mode(GFX_AUTODETECT,480,272,0,0); 
    if (ret != 0) 
    { 
     allegro_message("Error setting grahpic mode! Because of it returned: %i", ret); 
     return ret; 
    } 
    background = load_bmp("background.bmp", NULL); 
    ship = load_bmp("ship.bmp", NULL); 
    BITMAP* m = load_bmp("missile.bmp", NULL); 
    if (background == NULL || ship == NULL || m != NULL){ 
     allegro_message("Couldn't load one or more sprites..."); 
     return 0; 
    } 
    buffer = create_bitmap(WIDTH, HEIGHT); 
    if (buffer == NULL) 
    { 
     allegro_message("Couldn't create buffer!"); 
     return 0; 
    } 
    int previousx = 0; 
    int previousy = 0; 
    while(!done) 
    { 

     sceCtrlReadBufferPositive(&pad, 1); 
     if (pad.Buttons & PSP_CTRL_START) 
     { 
      done = true; 
     } 
     else if (pad.Buttons & PSP_CTRL_CROSS) 
     { 
      FireBullet(s); 
     } 
     else if (pad.Buttons & PSP_CTRL_LEFT) 
     { 
      s->MoveLeft(); 
     } 
     else if (pad.Buttons & PSP_CTRL_RIGHT) 
     { 
      s->MoveRight(); 
     } 
     UpdateBullets(); 
     CleanUp(); 
     clear(buffer); 
     draw_sprite(buffer, background, 0, 0); 
     s->Draw(buffer, ship, frame); 
     DrawBullets(buffer, ship); 
     masked_blit(buffer, screen, 0, 0, 0, 0, WIDTH, HEIGHT); 
     if (frame == (60 * 10)) 
     { 
      frame = 0; 
     } 
     frame++; 
     vsync(); 
     previousx = pad.Lx; 
     previousy = pad.Ly; 

    } 
    allegro_message("Clearing resources!"); 
    clear(buffer); 
    clear(ship); 
    clear(background); 
    clear(screen); 
    allegro_message("Thank you for playing!"); 
    return 0; 
} 
END_OF_MAIN() 

이 오류 CANN이 경우, ot는 해결할 수 있습니다. 내가 사용할 수있는 것과 마찬가지로 새로운 연산자를 사용하지 않습니다. 나는 모든 것을 동적으로 할당하기 위해 malloc을 사용하지만 벡터 템플릿 클래스는 어떻게 든 new 연산자를 사용한다는 것을 의미한다.

+0

도움이 될만한 관련성이없는 많은 코드를자를 수 있습니다. – Marlon

+2

거룩한 모든 것의 이름에서이 라인이 무엇을하고 있으며, 왜 글로벌 범위에 있습니까? 'std :: vector * bullets = (std :: vector *) malloc (1); ' – jzila

+0

'psp-g ++'vs'psp-gcc'는 매우 의심 스럽습니다. –

답변

25

g++이 아니라 링커 래퍼로 gcc을 사용하고있는 것 같습니다. 따라서 표준 C++ 런타임은 링크되어 있지 않으며 new 연산자를 찾을 수 없습니다. 링크하려면 g++을 사용하거나 직접 C++ 런타임을 지정해야합니다. 일반적으로 -lstdc++입니다.

+0

아직 작동하지 않습니다. 그는 전역 범위에서 수동으로 1 바이트 크기로 할당 한 벡터 포인터에서 메서드를 호출하려고합니다. – jzila

+2

@jzila : 그것은 질문에 무관하다. 코드는 링키지와 관련이 없습니다. –

+0

죄송합니다. -lstdC++을 추가하는 것을 잊어 버렸습니다. 나는 내 메이크 파일에 있다고 생각 했어. –

관련 문제