Adventure Game Studio

AGS Support => Advanced Technical Forum => Topic started by: Dualnames on Tue 12/02/2019 02:55:41

Title: PLUGIN CODE question [SOLVED]
Post by: Dualnames on Tue 12/02/2019 02:55:41
I'm trying to code a PLUGIN function that grabs two sprites (sprite_a and sprite_b) parses the entirety of sprite_a and replaces the color of each pixel in sprite_b (with coordinates y = y from sprite a and x= x-Random(2) -2 from sprite_a), but that's not working, and i can't figure out why, I think I'm parsing the 2d array wrongfully.




int x, y; 
  BITMAP* src_a = engine->GetSpriteGraphic(sprite_a);
  BITMAP* src_b = engine->GetSpriteGraphic(sprite_b);
  unsigned short* pixel_a = *(unsigned short**)engine->GetRawBitmapSurface(src_a);
  unsigned short* pixel_b = *(unsigned short**)engine->GetRawBitmapSurface(src_b);

  for (y = 0; y < screen_height; y++)
  {
    for (x = 0; x < screen_width; x++)
    {
  unsigned short colorfromB = pixel_b[y,x];
  pixel_a[y,(x-(rand() % 2)-2)]=colorfromB;
      pixel_a++;
  pixel_b++;
    }
  }
  engine->ReleaseBitmapSurface(src_a);
  engine->ReleaseBitmapSurface(src_b); 


Clarifying it's only doing half the screen, and it shouldn't, and i think the colors it picks are a bit wrong as well.


https://imgur.com/dMLLhUA
Title: Re: PLUGIN CODE question
Post by: tzachs on Tue 12/02/2019 03:29:26
You're increasing x & y in the loop, but you're also increasing the pointers (pixel_a and pixel_b) inside the loop, so you're increasing twice instead of once.
Try removing pixel_a++ and pixel_b++.
Title: Re: PLUGIN CODE question
Post by: Dualnames on Tue 12/02/2019 03:41:01
That reduces the effect into a line at the top of the screen. A single pixel 1 pixel height starting from 0 to halfway only one pixel height.


edit: Posting working code, thanks to qptain_nemo

int x, y;
 
  BITMAP* src_a = engine->GetSpriteGraphic(sprite_a);

  BITMAP* src_b = engine->GetSpriteGraphic(sprite_b);

 
  unsigned long** pixel_a = (unsigned long**)engine->GetRawBitmapSurface(src_a);
  unsigned long** pixel_b = (unsigned long**)engine->GetRawBitmapSurface(src_b);

  for (y = 0; y < screen_height; y++)
  {
    for (x = 0; x < screen_width; x++)
    {
  unsigned long colorfromB = pixel_b[y][x];
  pixel_a[y][(x-(rand() % 2)-2)]=colorfromB;  
     // pixel_a++;//=2;
// pixel_b++;//=2;
    }
  }
  engine->ReleaseBitmapSurface(src_a);
  engine->ReleaseBitmapSurface(src_b);
// }
}
Title: Re: PLUGIN CODE question [SOLVED]
Post by: tzachs on Tue 12/02/2019 04:31:23
Are you assuming here that screen_height and screen_width equal the bitmap's height and width?
Did you verify that?

You can do:
Code (cpp) Select

int srcWidth, srcHeight;
engine->GetBitmapDimensions(src_a, &srcWidth, &srcHeight, NULL);


And compare srcWidth/Height to screen_width/height (and also I'm assuming here that src_a and src_b are the same size, otherwise the code doesn't make a lot of sense).

EDIT: Ah, nvm, you solved it, cool.
Title: Re: PLUGIN CODE question [SOLVED]
Post by: Crimson Wizard on Tue 12/02/2019 10:25:49
@Dualnames, I got that plugin code works for you now, but I have to warn against using "long" and suggest using "int" instead, or even include <stdint.h> and use "int32_t" type. There are two reasons for this:

1) when it comes to data format like image's it's better to stick to types that explicitly define their size.
2) "long" type is not portable: historically it always means 32-bit integer with Microsoft C++ compiler, but it is of varied size if you compile with gnu compilers (32-bit in 32-bit programs and 64-bit in 64-bit programs).
Title: Re: PLUGIN CODE question [SOLVED]
Post by: Dualnames on Tue 12/02/2019 17:56:29
Alright, replaced all longs with int32, i've never coded much in c++ beyond like few lines, can you explain how to use int32_t, if that's not too much to ask.
Does it automatically convert the data types within stdint script? So i just do an include and keep using int and it will choose the appropriate one, unless explicitly defined by me?
Title: Re: PLUGIN CODE question [SOLVED]
Post by: Crimson Wizard on Tue 12/02/2019 20:25:59
Quote from: Dualnames on Tue 12/02/2019 17:56:29
Alright, replaced all longs with int32, i've never coded much in c++ beyond like few lines, can you explain how to use int32_t, if that's not too much to ask.
Does it automatically convert the data types within stdint script? So i just do an include and keep using int and it will choose the appropriate one, unless explicitly defined by me?

int32_t is simply a typedef (https://en.cppreference.com/w/cpp/language/typedef) (alias). stdint.h declares these aliases according to the system you compile under, but I think it just equals to "signed int" on most contemporary common platforms.
After you included <stdint.h> you may declare variables as "int32_t myint;" or "int32_t **pixel_a", same way as you use "int" and other types.
Some explanation why using these may be needed: https://stackoverflow.com/questions/14515874/difference-between-int32-int-int32-t-int8-and-int8-t

On the other hand if you think all this is too confusing you may just use "int" which should be okay on usual Windows/Linux/ etc systems you usually distribute games for. Just don't use "long" for the reasons I explained earlier.