Gamestudio Links
Zorro Links
Newest Posts
Free Live Data for Zorro with Paper Trading?
by AbrahamR. 05/18/24 13:28
Change chart colours
by 7th_zorro. 05/11/24 09:25
Data from CSV not parsed correctly
by dr_panther. 05/06/24 18:50
AUM Magazine
Latest Screens
The Bible Game
A psychological thriller game
SHADOW (2014)
DEAD TASTE
Who's Online Now
4 registered members (degenerate_762, AbrahamR, AndrewAMD, ozgur), 667 guests, and 8 spiders.
Key: Admin, Global Mod, Mod
Newest Members
Hanky27, firatv, wandaluciaia, Mega_Rod, EternallyCurious
19051 Registered Users
Previous Thread
Next Thread
Print Thread
Rate Thread
Page 3 of 5 1 2 3 4 5
Re: How to make a copy of a bmap? [Re: Caermundh] #367544
04/14/11 14:40
04/14/11 14:40
Joined: Jan 2002
Posts: 4,225
Germany / Essen
Uhrwerk Offline
Expert
Uhrwerk  Offline
Expert

Joined: Jan 2002
Posts: 4,225
Germany / Essen
Originally Posted By: Caermundh
@Uhwrek: No, the copied bitmap in his code does not create 2 bitmaps with the same handle, if you look at the testing code he posted originally, it puts a red cross on the original bmap. When i ran the code, i had two bmaps - one with and one without a red cross on it.

I don't know what code you're talking about, I was talking about Mr. Guests code. Most obviously you're not believing me. As I already said, you better have a look at atypes.h
Code:
typedef struct BMAP {
	C_LINK	link;
	long 	width,height; // original size of the bitmap
	long	bytespp;	// original bytes per pixel (1..4)
	void	*ptr;		// internal use
	byte	*pixels;	// ptr to palettized, 565, 4444, 888 or 8888 coded original image
	long	flags;      // see BMPF_... above
	void	*d3dtex;	// 	LPDIRECT3DTEXTURE9 (usually a different format than the original image)
	float	u1,v1,u2,v2; // texture pixel bounds
	long	u,v;		// cutout start size
	long	refcount;	// for implicitely created bmaps
	long	finalwidth,finalheight,finalbytespp;
	long	pitch,finalpitch;
	long	miplevels;
	long    finalformat;
	void	*finalbits;	// bitmap content when locked, otherwise NULL
} BMAP;


As you can see here the BMAP struct contains the C_LINK struct, which contains the handle. So using the mem_cpy approach WILL copy this handle. As you can see furthermore there are different pointers to image data, namely *pixels, *d3dtex and *finalbits. All this data does not get copied by mem_cpy, just the pointers get copied. Hence the image data does not get copied and copying the bitmap is kind of senseless. If you understand that and are willing to live with the consequences, go for it. But don't cry if this will fuck things up later on.

EDIT: @JustSid: pffffffff....


Always learn from history, to be sure you make the same mistakes again...
Re: How to make a copy of a bmap? [Re: Uhrwerk] #367545
04/14/11 14:46
04/14/11 14:46
Joined: Jan 2003
Posts: 4,615
Cambridge
Joey Offline
Expert
Joey  Offline
Expert

Joined: Jan 2003
Posts: 4,615
Cambridge
if bmap_blit uses bitblt, it could be accelerated by your graphics hardware (if the graphics card is the target of the bitmap, which I don't know).

Re: How to make a copy of a bmap? [Re: Joey] #367552
04/14/11 16:29
04/14/11 16:29
Joined: Aug 2005
Posts: 238
Caermundh Offline OP
Member
Caermundh  Offline OP
Member

Joined: Aug 2005
Posts: 238
@Uhrwerk, Just Sid:
I see what you are saying about C_LINK link; getting copied by mem copy, so that you effectivly have 2 bmaps with the same handle, and i also see your argument that memcpy() will copy only the pointers for *pixels, *d3dtex, & *finalbits without copying the data that they point to.

Given that memcpy() will copy the pointers and not the data, if i write to one bmap, it would write to both, because each bmap is pointing to the same data. But i have run the code, and was able to write to one without affecting the other.

Here is the code:

Code:
///////////////////////////////
#include <acknex.h>
#include <default.c>

///////////////////////////////

ENTITY* e1;

BMAP* bmp_original = "bmap_to_copy.bmp";
BMAP* bmp_clone;

PANEL* pnl_original = {
	pos_x = 0;
	flags = SHOW;
}

PANEL* pnl_clone = {
	pos_x = 64;
	flags = SHOW;
}


void bmap_cross(){
	
	BMAP* tgablitz = pnl_original.bmap;
	var format; 
	var pixel;
	format = bmap_lock(tgablitz,0);
	if (format >= 565) {
		pixel = pixel_for_vec(vector(0,0,255),100,format); // red color
		pixel_to_bmap(tgablitz,10,10,pixel);
		pixel_to_bmap(tgablitz,10,11,pixel);
		pixel_to_bmap(tgablitz,10,12,pixel);
		pixel_to_bmap(tgablitz,10,13,pixel);
		pixel_to_bmap(tgablitz,10,14,pixel);
		pixel_to_bmap(tgablitz,8,12,pixel);
		pixel_to_bmap(tgablitz,9,12,pixel);
		pixel_to_bmap(tgablitz,11,12,pixel);
		pixel_to_bmap(tgablitz,12,12,pixel);
	}
	bmap_unlock(tgablitz);
}

BMAP *bmap_clone(BMAP* bmp){
	
	BMAP* bmpNew = malloc(sizeof(BMAP));
	memcpy(bmpNew, bmp, sizeof(BMAP));
	return(bmpNew);
}

void main(){
	
	wait(1);
	
	bmp_clone = bmap_clone(bmp_original);
	
	pnl_original.bmap = bmp_original;
	pnl_clone.bmap = bmp_clone;
	
	bmap_cross();
}



(this is just a re-paste of Mr. Guests earlier code.)

When I run the above code, I end up with 2 bitmaps on the screen, one with a red_cross on it and one without the red cross.

So now i am just confused. I think JustSid and Uhrwerk are both correct in their statements - memcpy() will copy the pointers without copying the data they point to, so when i modify the data - it would modify both bmaps because they are the same bmap. But if that is so, than how am i getting 2 distinct bmaps?

Re: How to make a copy of a bmap? [Re: Caermundh] #367555
04/14/11 17:19
04/14/11 17:19
Joined: Apr 2007
Posts: 3,751
Canada
WretchedSid Offline
Expert
WretchedSid  Offline
Expert

Joined: Apr 2007
Posts: 3,751
Canada
Just a guess: Move the panels around, I guess there is a cache to avoid too many drawcalls.


Shitlord by trade and passion. Graphics programmer at Laminar Research.
I write blog posts at feresignum.com
Re: How to make a copy of a bmap? [Re: WretchedSid] #367556
04/14/11 17:31
04/14/11 17:31
Joined: Jan 2002
Posts: 4,225
Germany / Essen
Uhrwerk Offline
Expert
Uhrwerk  Offline
Expert

Joined: Jan 2002
Posts: 4,225
Germany / Essen
Now that is exactly what I meant with "fucking things up later on".

The reason for your two "distinct" bitmaps is the order you're doing your calls in. You copy the memory area while the DirectX Texture of the bitmap has not yet been allocated. Hence the engine will find NULL when inspecting the bitmaps and will hence allocate two textures for the same image data located in the BMAP.pixel member. The pixel_to_bmap instruction will now operate on the texture rather than on the original image data. As long as both bitmaps will remain in the video memory it will look as if there are two bitmaps because there are two textures. You're lucky in this case that the DirectX Texture was not yet allocated. Still don't believe it? Place a "bmap_preload(bmp_original);" right after the wait in your main function. You'll get a very "surprising" result.

Seriously: Several experienced forum members warned you not to mess up with internal engine data and you did it anyways and got results you we're not able to understand. Does that ring a bell for you?


Always learn from history, to be sure you make the same mistakes again...
Re: How to make a copy of a bmap? [Re: Uhrwerk] #367577
04/14/11 21:49
04/14/11 21:49
Joined: Jul 2008
Posts: 1,178
England
M
MrGuest Offline
Serious User
MrGuest  Offline
Serious User
M

Joined: Jul 2008
Posts: 1,178
England
sorry, the code i posted is flawed!

if you're using commands within the engine such as prt_remove these will be invalid...

only use such commands if you know what you're doing with memory when you know what GS thinks it's doing with memory....

Re: How to make a copy of a bmap? [Re: MrGuest] #367585
04/15/11 01:27
04/15/11 01:27
Joined: Aug 2005
Posts: 238
Caermundh Offline OP
Member
Caermundh  Offline OP
Member

Joined: Aug 2005
Posts: 238
OK...so i did some testing. When I did a bmap_preload like you suggested Uhrwerk, the bitmaps both had red crosses on them. The only reason I was seeing one with and one without was because of, like you said, the way Gamestudios caches bitmaps.

Thing is, Mr. Guest got my curiosity up, so i kept at it. I knew memcpy could work. Heres what I came up with:

Code:
//////////////////////////////////////////////////////////////////////
// test.c

#include <acknex.h>
#include <default.c>
#include "headers.h"

#define PRAGMA_PATH "Graphics\Item Icons"
#define PRAGMA_PATH "Models"

FONT* standard_font = "ackfont.pcx";

BMAP* bmp_original = "jug_icon.tga";
BMAP* bmp_clone = "jug_icon.tga";

PANEL* pnl_original = {
	pos_x = 0;
	pos_y = 40;
	flags = SHOW;
}

PANEL* pnl_clone = {
	pos_x = 64;
	pos_y = 40;
	flags = SHOW;
}

PANEL* info_panel =
{   pos_x = 20;
    pos_y = 20;
    flags = SHOW;
    digits = 0,0,3.0,standard_font,1,test;
    digits = 0,10,3.0,standard_font,1,test2;
}

void bmap_cross(){
	
	BMAP* tgablitz = pnl_original.bmap;
	var format; 
	var pixel;
	format = bmap_lock(tgablitz,0);
	if (format >= 565) {
		pixel = pixel_for_vec(vector(0,0,255),100,format); // red color
		pixel_to_bmap(tgablitz,10,10,pixel);
		pixel_to_bmap(tgablitz,10,11,pixel);
		pixel_to_bmap(tgablitz,10,12,pixel);
		pixel_to_bmap(tgablitz,10,13,pixel);
		pixel_to_bmap(tgablitz,10,14,pixel);
		pixel_to_bmap(tgablitz,8,12,pixel);
		pixel_to_bmap(tgablitz,9,12,pixel);
		pixel_to_bmap(tgablitz,11,12,pixel);
		pixel_to_bmap(tgablitz,12,12,pixel);
	}
	bmap_unlock(tgablitz);
}

BMAP *bmap_copy(BMAP* bmp)
{   BMAP* bmpNew = bmap_createblack(1,1,24);
    bmpNew.width = bmp.width;
    bmpNew.height = bmp.height;
    bmpNew.bytespp = bmp.bytespp;
    bmpNew.flags = bmp.flags;
    bmpNew.u1 = bmp.u1;
    bmpNew.v1 = bmp.v1;
    bmpNew.u2 = bmp.u2;
    bmpNew.v2 = bmp.v2;
    bmpNew.u = bmp.u;
    bmpNew.v = bmp.v;
    bmpNew.refcount = bmp.refcount;
    bmpNew.finalwidth = bmp.finalwidth;
    bmpNew.finalheight = bmp.finalheight;
    bmpNew.finalbytespp = bmp.finalbytespp;
    bmpNew.pitch = bmp.pitch;
    bmpNew.finalpitch = bmp.finalpitch;
    bmpNew.miplevels = bmp.miplevels;
    bmpNew.finalformat = bmp.finalformat;
    bmpNew.finalbits = NULL;
    bmpNew.d3dtex = NULL;
    bmpNew.pixels = malloc((bmp.width*bmp.height)*bmp.bytespp);
    memcpy(bmpNew.pixels, bmp.pixels, (bmp.width*bmp.height)*bmp.bytespp);
    return(bmpNew);
}

void main()
{   wait(1);
    bmap_preload(bmp_original);
    bmp_clone = bmap_copy(bmp_original);
    pnl_original.bmap = bmp_original;
    pnl_clone.bmap = bmp_clone;
    bmap_cross();
    test = bmp_original.link.index;
    test2 = bmp_clone.link.index;
}



Instead of using memcpy to copy the BMAP, i use memcpy to copy the bmap pixels. As you can see, i did a bmap_preload so im not getting any cached bmaps. I checked bmp_original.link.index and bmp_clone.link.index and they are different numbers, so the two bmaps are unique. When I ran the code, i got one bmap with a red cross and one without.

the only problem the code has is that i get an "invalid pointer freed" error message when I exit the game.

Quote:

Seriously: Several experienced forum members warned you not to mess up with internal engine data and you did it anyways and got results you we're not able to understand. Does that ring a bell for you?


I mess with stuff im not supposed to all the time. Its how I learn. As well - when I am messing with stuff I dont fully understand - I gnerally do it in a test enviroment where I can blow things up all day long with no harm done.

In the future, I will avoid asking "why didnt that work?" style questions like I did in the later posts of this thread. You should come to the boards with "How do I...?" style questions or with answers. I apologize for violating board etiquette the way i did.

Re: How to make a copy of a bmap? [Re: Caermundh] #367593
04/15/11 06:39
04/15/11 06:39
Joined: Nov 2010
Posts: 96
Vienna
S
Schubido Offline
Junior Member
Schubido  Offline
Junior Member
S

Joined: Nov 2010
Posts: 96
Vienna
Hi again,

memcpy for pixels sounds plausible to me - if you assume that pixels is really the bitmap without additional GS internal information.
But I would recommend not to do this:
bmpNew.width = bmp.width;
bmpNew.height = bmp.height;
bmpNew.bytespp = bmp.bytespp;
bmpNew.pixels = malloc((bmp.width*bmp.height)*bmp.bytespp);
This (.pixels = malloc...) generates a memory leak, because the previous pointer gets lost.

IMHO it would be better to let GS create the target bitmap with the proper dimensions:
BMAP* bmNew = bmap_createblack(bmp.width, bmp.height,bmap_format(bmp));
... and then do the rest of the copy stuff.

Re: How to make a copy of a bmap? [Re: Schubido] #367595
04/15/11 07:02
04/15/11 07:02
Joined: Jul 2001
Posts: 6,904
H
HeelX Offline
Senior Expert
HeelX  Offline
Senior Expert
H

Joined: Jul 2001
Posts: 6,904
Funny, I coded some functions for the same topic yesterday. This is what I came up with:
Code:
BMAP* bmap_clone (BMAP* src)
{
   // no source?
   if (src == NULL)
      return(NULL);
      
   var format = bmap_lock(src, 0);
   
   // invalid bitmap or unknown format?
   if (format == 0)
      return(NULL);
   else  
      bmap_unlock(src);
   
   BMAP* r = bmap_createblack(src->width, src->height, format);
   
   if (r != NULL)
      bmap_copy(src, r);
   
   return(r);
}

BMAP* bmap_copy (BMAP* src, BMAP* dest)
{
   if ((src == NULL) || (dest == NULL))
      return(NULL);
   
   bmap_blit(dest, src, NULL, NULL);
   
   return(dest);
}


Using the format retrieved by bmap_lock in bmap_createblack is actually safe. The manual says about bmap_createblack:
Quote:
format - bitmap format (uncompressed formats only; see bmap_lock) or number of bits per pixel (8, 16, 24, 32).

I'm not 100% sure, if a bmap_process approach would be faster - but from what I believe and know, it will smile. Maybe someone has the time to write a generic function for that?

Re: How to make a copy of a bmap? [Re: HeelX] #367602
04/15/11 09:21
04/15/11 09:21
Joined: Apr 2007
Posts: 3,751
Canada
WretchedSid Offline
Expert
WretchedSid  Offline
Expert

Joined: Apr 2007
Posts: 3,751
Canada
Originally Posted By: HeelX

Using the format retrieved by bmap_lock in bmap_createblack is actually safe. The manual says about bmap_createblack:
Quote:
format - bitmap format (uncompressed formats only; see bmap_lock) or number of bits per pixel (8, 16, 24, 32).


Ouh, I misunderstood the manual somehow. Thanks for the clarification.


Shitlord by trade and passion. Graphics programmer at Laminar Research.
I write blog posts at feresignum.com
Page 3 of 5 1 2 3 4 5

Moderated by  HeelX, Lukas, rayp, Rei_Ayanami, Superku, Tobias, TWO, VeT 

Gamestudio download | chip programmers | Zorro platform | shop | Data Protection Policy

oP group Germany GmbH | Birkenstr. 25-27 | 63549 Ronneburg / Germany | info (at) opgroup.de

Powered by UBB.threads™ PHP Forum Software 7.7.1