2011-12-21 36 views
10

Không bao giờ thấy lỗi liên kết này trong cuộc sống của tôi cho đến khi tôi bắt đầu lập trình các ứng dụng homebrew PSP. Dù sao, tôi đang làm một trò chơi allegro và tôi cần phải bắn đạn hoặc tên lửa trong trường hợp này và tôi cần phải sử dụng một mảng năng động và chung chung. Nhưng mối liên kết của tôi phàn nàn rằng có một tham chiếu không xác định đối với toán tử mới. Dưới đây sẽ là toàn bộ mã nguồn, makefile và chi tiết lỗi.Tham chiếu không xác định cho toán tử mới

Chi tiết Lỗi:

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 ========== 

Makefile

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() 

Nếu cann lỗi này ot được cố định là có một công việc xung quanh. Giống như những gì tôi có thể sử dụng mà không sử dụng toán tử mới. Tôi có nghĩa là tôi sử dụng malloc để phân bổ động tất cả mọi thứ nhưng lớp mẫu vector bằng cách nào đó bằng cách sử dụng toán tử mới.

+0

Bạn có thể cắt bỏ rất nhiều mã không liên quan, điều đó sẽ hữu ích – Marlon

+2

Điều gì trong tên của tất cả những gì là thánh là dòng này được cho là đang làm, và tại sao nó trong phạm vi toàn cầu? 'std :: vector * bullets = (std :: vector *) malloc (1);' – jzila

+0

'psp-g ++' vs 'psp-gcc' trông * rất * đáng ngờ. –

Trả lời

25

Dường như bạn đang sử dụng gcc làm trình bao bọc liên kết chứ không phải g++. Do đó, thời gian chạy C++ chuẩn không được liên kết và không thể tìm thấy toán tử mới. Bạn phải sử dụng g++ để liên kết hoặc chỉ định thời gian chạy C++, thường là -lstdc++.

+0

Nó vẫn không hoạt động. Anh ta đang cố gắng gọi các phương thức trên một con trỏ vector mà anh ta đã cấp phát theo cách thủ công có kích thước tới 1 byte, trong phạm vi toàn cục, không kém. – jzila

+2

@jzila: Điều đó không liên quan đến câu hỏi. Mã không có gì liên quan đến liên kết, mà đang được hỏi về. –

+0

Xin lỗi bạn đúng Tôi quên thêm -lstdC++. Tôi nghĩ rằng tôi đã có nó trong makefile của tôi –

Các vấn đề liên quan