consoledevФорум

особенности портирования и написания 2д проектов под psp

Страницы: 1 2 3 4 5 6 7 Следующая »
#0
14:13, 16 мая 2006

собственно сабж, я тут делаю , делаю 2д проект, по типу Братья пилоты - загадка атлантической сельди, и столкнулся с такими штуками как смазывание при скролле, долгая подгрузка с флешки...просто подгрузка около 5 мб - примерно 20 сек - что очень долго , особенно при больших уровнях с нетайловыми фонами. Даже при подгрузке 512х512 - куска фона - притормаживание более чем заметное. Есть какие-то замечания?

#1
14:44, 16 мая 2006

1. Ы? Не понял про размазывание.

2. 5mb - 20 секунд?? sceIoRead ? Если что-то невминяемое, например std::streams (респект тому, кто собрал STL :), то я возможно нихуя и не удивлен. Пасти код, посмотрим. Кстати, про флешку уже писали, лучше маленькую и быструю :)

#2
14:46, 16 мая 2006

Опиши это смазывание (неравномерность, motion blur:) ,  etc...)

#3
21:43, 16 мая 2006

sceIoRead ?

Юзаются fopen fread, я подозревал что сдк их както должно перегрузить под псп?? Если все не так то будем посмотреть sceIoRead  )))

А смазывание такое - вот статическая картинка и на ней допустим черные полосы, так если ее скролить, то черное будет все )))....вобщем такое ощущение как в тфт след от мыши...вооотт....потому я и спрашиваю, а не тфт ли это??

а кстати, какие флешки "быстрые"? просто та что есть - это 1GB Memory Stick Pro Duo, просто интересно, надо будет прикупить тогда самую быструю )))

кстати, а кто слышал про хард драйвы к псп?? там вроде уже и 4Гб прикупить можно....может его юзать??

#4
7:34, 17 мая 2006

> кстати, а кто слышал про хард драйвы к псп?? там вроде уже и 4Гб прикупить можно....может его юзать??

Неофициально, есть адаптер 4 IN 1, который втыкается вместо memory stick. Позволяет использовать CF, SD и обычные memory stick.

Есть и официальный hard drive на 4 Гб, только не знаю где продают.

PS: Какая у тебя флешка (фирма)?

#5
8:34, 17 мая 2006

bada
Нежелательно libc юзать, лучше запретить. У меня пока используется несколько функций libc, которые прямо где надо и объявлены extern. Но это плохо.

#6
10:46, 17 мая 2006

bada
> Юзаются fopen fread, я подозревал что сдк их както должно перегрузить под псп?? Если все не так то будем посмотреть sceIoRead )))
Ничего не перегружает, это прямой драйвер устройства, задающийся ms0 host0 umd0 и т.д.
оно по этому имени как в Unix'e подключает драйвер того устройства которое отвечает за этот префикс
(sceIoAddDrv,sceIoDelDrv)

> А смазывание такое - вот статическая картинка и на ней допустим черные полосы, так если ее скролить, то черное будет все )))....вобщем такое ощущение как в тфт > след от мыши...вооотт....потому я и спрашиваю, а не тфт ли это??
Ищи проблему в GE Display List, очистка экрана (sceGuClear...)
Все это там, ибо такого не должно быть. Посмотри на BurnOut и пойми что на других играх такого убер-эффекта нет :)

#7
15:59, 17 мая 2006

насчет fopen таки перегружена в libc и там после какихто шаманств идет вызов sceIoOpen, мой глаз не заметил принципиальных тормозов в этой функции.

а насчет GE Display List и sceGuClear процесс такой приблеженно это то что было заимствавано из JGE

void Init()
{
sceGuInit();
sceGuStart(GU_DIRECT, list);
mVideoBufferStart = 0;
sceGuDrawBuffer(BUFFER_FORMAT, (void *)mVideoBufferStart, FRAME_BUFFER_WIDTH);
mVideoBufferStart += FRAME_BUFFER_SIZE;
sceGuDispBuffer(SCREEN_WIDTH, SCREEN_HEIGHT, (void *)mVideoBufferStart, FRAME_BUFFER_WIDTH);
mVideoBufferStart += FRAME_BUFFER_SIZE;
mCurrentPointer = mVideoBufferStart;
sceGuOffset(2048 - (SCREEN_WIDTH/2), 2048 - (SCREEN_HEIGHT/2));
sceGuViewport(2048, 2048, SCREEN_WIDTH, SCREEN_HEIGHT);

sceGuScissor(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT);
sceGuEnable(GU_SCISSOR_TEST);
sceGuFrontFace(GU_CW);
sceGuEnable(GU_TEXTURE_2D);
sceGuShadeModel(GU_SMOOTH);
sceGuEnable(GU_BLEND);
sceGuBlendFunc(GU_ADD, GU_SRC_ALPHA, GU_ONE_MINUS_SRC_ALPHA, 0, 0);
  
sceGuClear(GU_COLOR_BUFFER_BIT);
sceGuFinish();
sceGuSync(0, 0);

sceDisplayWaitVblankStart();
sceGuDisplay(1);

}
void GraphicCore::BeginRender()
{
  sceKernelDcacheWritebackInvalidateAll();
  sceGuStart(GU_DIRECT, list);
  sceGuTexMode(TEXTURE_FORMAT, 0, 0, mSwizzle);  
  sceGuTexFilter(GU_NEAREST, GU_NEAREST);      
}
void GraphicCore::EndRender()
{
  sceGuFinish();
  sceGuSync(0, 0);

  if (mVsync)
               {
    sceDisplayWaitVblankStart();
               }
  
  sceGuSwapBuffers();

  mCurrentTex = -1;
  mCurrentBlend = -1;
}

соттветственно между бегин и  идет вывод текстур

void GraphicCore::RenderQuad(Quad* quad, float xo, float yo, float angle, float xScale, float yScale)
{
  if(quad == NULL)
  {
    return;
  }

  if (mCurrentTex != quad->mTex->mTexId)
  {
    sceGuTexImage(0, quad->mTex->mTexWidth, quad->mTex->mTexHeight, quad->mTex->mTexWidth, quad->mTex->mBitsPtr);
    mCurrentTex = quad->mTex->mTexId;
  }

  if (mCurrentBlend != quad->mBlend)
  {
    sceGuTexFunc(quad->mBlend, GU_TCC_RGBA); 
    mCurrentBlend = quad->mBlend;
  }

  //float destWidth = quad->mWidth*quad->mScaleX;
  float destHeight = quad->mHeight*yScale;
  float x = xo - quad->mHotSpotX*xScale;
  float y = yo - quad->mHotSpotY*yScale;

  float start, end;

  float width;
  float destWidth;
  float fixedWidth = SLICE_SIZE_F*xScale;
  float xx, yy;
  float cosAngle = cosf(angle);
  float sinAngle = sinf(angle);

  if (quad->mHFlipped)// || quad->mVFlipped)
  {
    
    for (end = quad->mX, start = quad->mX+quad->mWidth; start > end; start -= SLICE_SIZE_F)
    {
      // allocate memory on the current display list for temporary storage
      // in order to rotate, we use 4 vertices this time
      struct Vertex* vertices = (struct Vertex*)sceGuGetMemory(4 * sizeof(struct Vertex));
      if ((start - SLICE_SIZE_F) > end)
      {
        width = SLICE_SIZE_F;
        destWidth = fixedWidth;
      }
      else
      {
        width = start-end;
        destWidth = width*xScale;
      }

      vertices[0].u = start; 
      vertices[0].v = quad->mY;
      vertices[0].color = quad->mColor[0];
      vertices[0].x = x; 
      vertices[0].y = y; 
      vertices[0].z = 0.0f;

      vertices[1].u = start - width; 
      vertices[1].v = quad->mY;
      vertices[1].color = quad->mColor[1];
      vertices[1].x = x + destWidth; 
      vertices[1].y = y; 
      vertices[1].z = 0.0f;

      vertices[2].u = start; 
      vertices[2].v = quad->mY + quad->mHeight;
      vertices[2].color = quad->mColor[2];
      vertices[2].x = x; 
      vertices[2].y = y + destHeight; 
      vertices[2].z = 0.0f;

      vertices[3].u = start - width; 
      vertices[3].v = quad->mY + quad->mHeight;
      vertices[3].color = quad->mColor[3];
      vertices[3].x = x + destWidth; 
      vertices[3].y = y + destHeight; 
      vertices[3].z = 0.0f;

      if (quad->mVFlipped)
      {
        Swap(&vertices[0].v, &vertices[2].v);
        Swap(&vertices[1].v, &vertices[3].v);
      }

      if (angle != 0.0f)
      {
        for (int i=0;i<4;i++)
        {
          xx = (cosAngle*(vertices[i].x-xo) - sinAngle*(vertices[i].y-yo) + xo);
          yy = (sinAngle*(vertices[i].x-xo) + cosAngle*(vertices[i].y-yo) + yo); 
          vertices[i].x = xx;
          vertices[i].y = yy;
        }
      }

      x += destWidth;

      sceGuDrawArray(GU_TRIANGLE_STRIP,GU_TEXTURE_32BITF|TEXTURE_COLOR_FORMAT|GU_VERTEX_32BITF|GU_TRANSFORM_2D, 4, 0, vertices);
    }
  }
  else
  {
    for (start = quad->mX, end = quad->mX+quad->mWidth; start < end; start += SLICE_SIZE_F)
    {
      // allocate memory on the current display list for temporary storage
      // in order to rotate, we use 4 vertices this time
      struct Vertex* vertices = (struct Vertex*)sceGuGetMemory(4 * sizeof(struct Vertex));
      if ((start + SLICE_SIZE_F) < end)
      {
        width = SLICE_SIZE_F;
        destWidth = fixedWidth;
      }
      else
      {
        width = end-start;
        destWidth = width*xScale;
      }

      vertices[0].u = start; 
      vertices[0].v = quad->mY;
      vertices[0].color = quad->mColor[0];
      vertices[0].x = x; 
      vertices[0].y = y; 
      vertices[0].z = 0.0f;

      vertices[1].u = start + width; 
      vertices[1].v = quad->mY;
      vertices[1].color = quad->mColor[1];
      vertices[1].x = x + destWidth; 
      vertices[1].y = y; 
      vertices[1].z = 0.0f;

      vertices[2].u = start; 
      vertices[2].v = quad->mY + quad->mHeight;
      vertices[2].color = quad->mColor[2];
      vertices[2].x = x; 
      vertices[2].y = y + destHeight; 
      vertices[2].z = 0.0f;

      vertices[3].u = start + width; 
      vertices[3].v = quad->mY + quad->mHeight;
      vertices[3].color = quad->mColor[3];
      vertices[3].x = x + destWidth; 
      vertices[3].y = y + destHeight; 
      vertices[3].z = 0.0f;

      if (quad->mVFlipped)
      {
        Swap(&vertices[0].v, &vertices[2].v);
        Swap(&vertices[1].v, &vertices[3].v);
      }
      
      if (angle != 0.0f)
      {
        for (int i=0;i<4;i++)
        {
          xx = (cosAngle*(vertices[i].x-xo) - sinAngle*(vertices[i].y-yo) + xo);
          yy = (sinAngle*(vertices[i].x-xo) + cosAngle*(vertices[i].y-yo) + yo); 
          vertices[i].x = xx;
          vertices[i].y = yy;
        }
      }

      x += destWidth;

      sceGuDrawArray(GU_TRIANGLE_STRIP,GU_TEXTURE_32BITF|TEXTURE_COLOR_FORMAT|GU_VERTEX_32BITF|GU_TRANSFORM_2D, 4, 0, vertices);
    }
  }
}
#8
16:18, 17 мая 2006

bada

сорри не увидел про (fread,fopen) ними неззя пользоваться СОВСЕМ!!! я расказывал о sceIoOpen

#9
16:23, 17 мая 2006

bada

сходу :
texture width,height - какие (это важно ибо есть еще tbw)

какого разиера прямоугольничкм рендериш ?
destWidth destHeight

#10
16:25, 17 мая 2006

bada
Еще , внимательно прочитай FAQ -PSP Development про InvalidateCache

Он у тебя стоит в позорном месте
Для теста лучше таки поставить перед DrawArray и там можна InvalidateRange

#11
16:39, 17 мая 2006

гм..это получается что те библиотеки что портированы на псп типа pnglib надо 
переписывать под sceIOOpen?

я загружаю картинки при помощи pnglib свизлю и это - высота и ширина которая получилась ,
прямоугольник рендера такой же.
вот

Texture * GraphicCore::LoadTexture(const char* filename, bool useVideoRAM)
{

    int pixelformat = PIXEL_FORMAT;

    u32* p32;
        u16* p16;
        png_structp png_ptr;
        png_infop info_ptr;
        unsigned int sig_read = 0;
        png_uint_32 width, height;
        int bit_depth, color_type, interlace_type, x, y;
        u32* line;
        FILE *fp;

        if ((fp = fopen(filename, "rb")) == NULL) 
    {
      LOG_ERROR("Cant find file : %s", filename);
      return NULL;
    }

        png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
        if (png_ptr == NULL) 
    {
             fclose(fp);
             return NULL;
        }
        png_set_error_fn(png_ptr, (png_voidp) NULL, (png_error_ptr) NULL, user_warning_fn);
        info_ptr = png_create_info_struct(png_ptr);
        if (info_ptr == NULL) 
    {
             fclose(fp);
             png_destroy_read_struct(&png_ptr, png_infopp_NULL, png_infopp_NULL);
             return NULL;
        }
        png_init_io(png_ptr, fp);
        png_set_sig_bytes(png_ptr, sig_read);
        png_read_info(png_ptr, info_ptr);
        png_get_IHDR(png_ptr, info_ptr, &width, &height, &bit_depth, &color_type, &interlace_type, int_p_NULL, int_p_NULL);
        png_set_strip_16(png_ptr);
        png_set_packing(png_ptr);
        
    if (color_type == PNG_COLOR_TYPE_PALETTE) 
    {
      png_set_palette_to_rgb(png_ptr);
    }
        
    if (color_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8) 
    {
      png_set_gray_1_2_4_to_8(png_ptr);
    }
    
    if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS))
    {
      png_set_tRNS_to_alpha(png_ptr);
    }

        png_set_filler(png_ptr, 0xff, PNG_FILLER_AFTER);
        line = (u32*) malloc(width * 4);
        if (!line)
    {
             fclose(fp);
             png_destroy_read_struct(&png_ptr, png_infopp_NULL, png_infopp_NULL);
             return NULL;
        }
        
        Texture * tex = new Texture();
        if (tex)
        {
      tex->mWidth = width;
      tex->mHeight = height;
      tex->mFlip = false;

      tex->mTexWidth = getNextPower2(width);
      tex->mTexHeight = getNextPower2(height);
      
      int size = tex->mTexWidth * tex->mTexHeight * sizeof(PIXEL_TYPE);
      if (useVideoRAM && (mCurrentPointer + size) < 0x200000)
      {
        tex->mInVideoRAM = true;
        tex->mBitsPtr = (PIXEL_TYPE*) (0x04000000+0x40000000+mCurrentPointer);
        mCurrentPointer += size;
      }
      else
      {
        tex->mInVideoRAM = false;
        tex->mBitsPtr = (PIXEL_TYPE*) memalign(16, size);
        memset(tex->mBitsPtr, 0, size);
      }
      
      PIXEL_TYPE* buffer = tex->mBitsPtr;

      if (mSwizzle)
      {
        buffer = (PIXEL_TYPE*) memalign(16, tex->mTexWidth * tex->mTexHeight * sizeof(PIXEL_TYPE));
        memset(buffer, 0, tex->mTexWidth * tex->mTexHeight * sizeof(PIXEL_TYPE));
      }

          if (buffer)
          {
        tex->mTexId = mTexCounter++;

            p32 = (u32*) buffer;
            p16 = (u16*) p32;

            for (y = 0; y < (int)height; y++) 
            {
                  png_read_row(png_ptr, (u8*) line, png_bytep_NULL);
                  for (x = 0; x < (int)width; x++) 
                  {
                        u32 color32 = line[x];
                        u16 color16;
            int a = (color32 >> 24) & 0xff;
                        int r = color32 & 0xff;
                        int g = (color32 >> 8) & 0xff;
                        int b = (color32 >> 16) & 0xff;
                        switch (pixelformat) {
                                case PSP_DISPLAY_PIXEL_FORMAT_565:
                                        color16 = (r >> 3) | ((g >> 2) << 5) | ((b >> 3) << 11);
                                        *(p16+x) = color16;
                                        break;
                                case PSP_DISPLAY_PIXEL_FORMAT_5551:
                                        color16 = (r >> 3) | ((g >> 3) << 5) | ((b >> 3) << 10) | ((a >> 7) << 15);
                                        *(p16+x) = color16;
                                        break;
                                case PSP_DISPLAY_PIXEL_FORMAT_4444:
                                        color16 = (r >> 4) | ((g >> 4) << 4) | ((b >> 4) << 8) | ((a >> 4) << 12);
                                        *(p16+x) = color16;
                                        break;
                                case PSP_DISPLAY_PIXEL_FORMAT_8888:
                                        color32 = r | (g << 8) | (b << 16) | (a << 24);
                                        *(p32+x) = color32;
                                        break;
                        }
                  }
                p32 += tex->mTexWidth;
                p16 += tex->mTexWidth;
            }

        if (mSwizzle)
        {
          swizzle_fast((u8*)tex->mBitsPtr, (const u8*)buffer, tex->mTexWidth*sizeof(PIXEL_TYPE), tex->mHeight);
          free (buffer);
        }
        }
        else
        {
          delete tex;
          tex = NULL;
        }
      }
        free (line);
        png_read_end(png_ptr, info_ptr);
        png_destroy_read_struct(&png_ptr, &info_ptr, png_infopp_NULL);
        fclose(fp);
        
        return tex;
}

если много кода то скажите как под кат убрать

#12
16:52, 17 мая 2006

а насчет sceKernelDcacheWritebackInvalidateAll(); - он вроде и делает InvalidateRange и InalidateCache ??

он вроде таки и стоит перед выводом
те
BeginRender
Render (где каждый выводит свой спрайт)
EndRender

в чем трабла?

#13
17:07, 17 мая 2006

bada
Это КЕШ!!! Я же сказал где надо ставить (и то только для проверки)

По ответу я не понял какого конкретно размера то ,что плохо работает, я спрашиваю не потому что мне любопытно, поверь :)

А насчет CACHE таки почитай R4000 Users Manual, ибо ты очень конкретно путаешь и не понимаешь этой сущности.

#14
17:20, 17 мая 2006

bada
>> я загружаю картинки при помощи pnglib свизлю и это - высота и ширина которая получилась ,
Что это за код такой? Так игры не пишут :) Проблема не в fopen\fclose, проблема в религии, да...

Страницы: 1 2 3 4 5 6 7 Следующая »
consoledevФорум

Тема в архиве.