Jump to content
Sign in to follow this  
Guest

BGLC flatten poly points

Recommended Posts

Guest

I'm working on a user-friendly compiler / decompiler for terrain scenery. Right now I'm able to completely decompile flatten data directly from BGL files. In my findings, I found out a small (okay very small) discovery.Christian's docs points out to use a value of 0-255 for points in the LOD-13 blocks. I looked over a lot of the default scenery (fltxxxxx.bgl files) and the lowest value used is actually a one.Like I said... a very small discovery ;)Lee.

Share this post


Link to post
Share on other sites
Guest christian

And it makes sense too. Any sensible programmer would use 0-255, or if we have a bit of a weirdo programmer maybe even 1-256. Since we are dealing with M$ 1-255 makes perfect sense!:-xxrotflmaoChristian

Share this post


Link to post
Share on other sites

Hi Lee.Good find!That would also explain the data structure for decal placement:

; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -data_start_0	label	word	DECAL_DATA 1, 7, 2, 28, 1, 0, 0	DECAL_GEOMETRY 1, DECAL_POLYGON, 1, 0	DECAL_POINTS 12	DECAL_POINT 136 + ( ( ( 7 * 4 ) + 2 ) * 255 ) + 4080,	0 + ( 28 * 255 ) + 4080	DECAL_POINT 207 + ( ( ( 7 * 4 ) + 2 ) * 255 ) + 4080, 	36 +( 28 * 255 ) + 4080	DECAL_POINT 203 + ( ( ( 7 * 4 ) + 2 ) * 255 ) + 4080, 	141 + ( 28 * 255 ) + 4080	DECAL_POINT 127 + ( ( ( 7 * 4 ) + 2 ) * 255 ) + 4080, 	172 +( 28 * 255 ) + 4080	DECAL_POINT 95 + ( ( ( 7 * 4 ) + 2 ) * 255 ) + 4080, 	165 + ( 28 * 255 ) + 4080	DECAL_POINT 59 + ( ( ( 7 * 4 ) + 2 ) * 255 ) + 4080, 	219 + ( 28 * 255 ) + 4080	DECAL_POINT 46 + ( ( ( 7 * 4 ) + 2 ) * 255 ) + 4080, 	210 + ( 28 * 255 ) + 4080	DECAL_POINT 78 + ( ( ( 7 * 4 ) + 2 ) * 255 ) + 4080,	156 + ( 28 * 255 ) + 4080	DECAL_POINT 43 + ( ( ( 7 * 4 ) + 2 ) * 255 ) + 4080, 	117 + ( 28 * 255 ) + 4080	DECAL_POINT 40 + ( ( ( 7 * 4 ) + 2 ) * 255 ) + 4080, 	67 + ( 28 * 255 ) + 4080	DECAL_POINT 81 + ( ( ( 7 * 4 ) + 2 ) * 255 ) + 4080, 	26 + ( 28 * 255 ) + 4080	DECAL_POINT 107 + ( ( ( 7 * 4 ) + 2 ) * 255 ) + 4080, 	25 + ( 28 * 255 ) + 4080data_end_0	label	word; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

Note the use of 255 as a placement constant. It seems to place the decals very well. As an experiment, I placed a windsock at the 4 corners of an LOD13 area, and '255' nails it on the head. I'm glad you're working on a decompiler... you're work from that end should greatly help to define these structures! My explorations have been mostly based on guessing, and value-substitution. Please, Lee, can I have a copy of the decompiler.... pretty-please? :9 Good point, Christian. :-lol

Share this post


Link to post
Share on other sites
Guest

Okay, I'm a little thick headed here. Can you explain the decal point data? It looks like I can use this to place the points using the 1(!!) to 255 point values withen the LOD 13 block. Do I just to that math exercise to get the correct data value? Does this work worldwide? If this is the case, then I can get started on the decompiler with them too.Lee.

Share this post


Link to post
Share on other sites

Hi Lee.I'll repost a few lines, then explain what I did:

DECAL_DATA 1, [b]7[/b], [b]2[/b], [b]28[/b], 1, 0, 0			DECAL_GEOMETRY 1, DECAL_POLYGON, 1, 0	DECAL_POINTS 12			DECAL_POINT 136 + ( ( ( [b]7[/b] * 4 ) + [b]2[/b] ) * 255 ) + 4080,	1 + ( [b]28[/b] * 255 ) + 4080

I bolded the '7, 2, 28' LOD13 locators in the DECAL_DATA.In the DECAL_POINTS, I'm locating the points to a 255 x 255 array ( that's the 136, 1 ), but adding the offsets to locate it in the LOD8 area as Christian outlined:"For decal_points it's more complicated. First there is a decal_point which is just the number of points to follow. Then the values range from 4080 (0FF0) to 12240 (2FD0). I found these values just experimenting. I have no clue why these values work and if they work everywhere. They seem to work in the south of New Zealand, I can place my scenery spot on using these values..."The math is this:An LOD8 area can be defined as an array of 32 X 32 LOD13 areas...An LOD8 area also starts at 4080 and ends at 12240.So starting at 12240 - 4080 = 8160 possible span of points in an LOD8 area.Also... 255 X 32 = 8160 possible span of points in an LOD8 area.So if you can define the LOD13 area as located within the LOD8 area, and multiply by 255, you get the correct point location. In the above example, I used the LOD13 location defined by the DECAL_DATA structure... {( 7*4 ) + 2} for the rowOffsets and { 28 } for the columnOffset... and multiplied them by 255... and added the whole mess to the decal startpoint ( 4080 ).This all reminds me of the debate over whether a landclass resample had 256 or 255 points in a defined LOD area. Christian always maintained it was 255 points... obviously he was right, as you are also right.The decal math supports you both, regarding Microsoft's math, and the resample program.... remember, they used an advanced form of 'resample.exe' to make water, and beaches, and decals, etc..., and must have based all the grids on 1-255. They may have done that, to avoid a "divide by zero" error in some calculation.Math is hard to convey with words, so ask me more if needed! I really want to help with your decompiler.Also, people can still use MSPaint, and it's 0-256 status bar locator to design decals and lakes... The BGL compiles and displays well enough, and the size error is pretty small at LOD13. So until a better graphical tool arrives, I still recommend MSpaint. :-xxrotflmao

Share this post


Link to post
Share on other sites
Guest

Okay!! Duh!!Now I get it :( Your just spanning across a LOD 8 region, breaking down your points based on where the LOD 13 region sits withen the LOD 8. I wasn't correlating the 7, 2, and 28 as the LOD 13 identifiers. Now it makes perfect sense, if you can make sense of any of this ;) >>I really want to help with your decompilerSend me a private message with your email and I'll send you a copy of what I have completed. It ain't much, but it's a start.Lee.

Share this post


Link to post
Share on other sites

Hi Lee.As Christian has pointed out, decals actually pay no attention to the LOD13 locators, but that doesn't mean we can't use them to help our poor human minds keep things straight! And that's why I put them in the line:DECAL_DATA 1, 7, 2, 28, 1, 0, 0 It just helps me keep the numbers straight for the decals... and I keep everything confined to LOD13 like the other polygons.I still haven't gotten wave action to work with the CFS2 shoreline code. Here's an island I built off the North African Coast:

include TMFmacros.incinclude CFS2TMFmacros.inc; Decal test; ===================================================================; DATA_BASEdata_base	label	word	dw	1			; world set number	dd	3556177 	; North Bound	dd	3333916 	; South Bound	dd	322122547 	; East Bound	dd	298261617 	; West Bound	dd	0			; VOR data	dw	0			; lowest VOR freq	dw	0			; highest VOR freq	dd	0			; seeds level 8 data	dd	0			; seeds level 9 data	dd	0			; seeds level 10 data	dd	0			; seeds level 11 data	dd	0			; seeds level 12 data	dd	0			; traffic data	dd	0			; minimum safe altitude data	dd	terrain_data - data_base; terrain mesh data	dd	0			; object data	dd	0			; library data	dd	0			; facilities data	dd	0			; anchor point data	dd	0			; ATIS data	dd	0			; NDB data	dd	0			; dynamic object paths data	dd	0h,0h			; minimum library id	dd	0h,0h			; maximum library id	dd	0			; miscellaneous data	dd	0			; title and description data	dd	0			; magnetic variation data	dd	0			; exception and exclusion data	dd	87654321h		; magic number	dd	0			; compression switch	dw	0			; spare	dd	0h,0h,0h,0h		; GUID	dd	0			; product id	dd	0			; product build number	dd	0			; new facility data pointers	dd	0			; new facility name list data	dd	0			; new facility band list data	dd	0			; new facility data; ===================================================================; TERRAIN_DATAterrain_data	label	word	dd	terrain_header_end - terrain_data; end of terrain header	dd	514				; version	dd	0				; unknown entry	dd	0				; unknown entry	dd	0				; elevation header	dd	0				; land class header	dd	0				; unknown header	dd	0				; class lookup header	dd	0				; season header	dd	0				; class lookup list	dd	0				; water class header	dd	0				; elevation index	dd	0				; land cover index	dd	0				; unknown index	dd	0				; flatten polygon header	dd	decal_header - terrain_data	; decal header	dd	0				; reserved	dd	0				; reserved	dd	0				; main terrain data	dd	0				; reserved	dd	0				; reserved	dd	0				; reserved	dd	0				; regions header	dd	0				; reserved	dd	0				; reservedterrain_header_end	label	word; ===================================================================; TERRAIN DECALS HEADERdecal_header	label	word	DECAL_HEADER 256, decal_list, decal_textures, decal_end; TERRAIN DECALS DATAdecal_data	label	word; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - data_start_0	label	word	DECAL_DATA 1, 6, 3, 13, 1, 0, 0	DECAL_GEOMETRY 1, 8, 1, 0	DECAL_POINTS 10	DECAL_POINT 131 + ( ( ( 6 * 4 ) + 3 ) * 255 ) + 4080,	16 + ( 13 * 255 ) + 4080	DECAL_POINT 173 + ( ( ( 6 * 4 ) + 3 ) * 255 ) + 4080, 	29 +( 13 * 255 ) + 4080	DECAL_POINT 189 + ( ( ( 6 * 4 ) + 3 ) * 255 ) + 4080, 	62 + ( 13 * 255 ) + 4080	DECAL_POINT 193 + ( ( ( 6 * 4 ) + 3 ) * 255 ) + 4080, 	96 +( 13 * 255 ) + 4080	DECAL_POINT 178 + ( ( ( 6 * 4 ) + 3 ) * 255 ) + 4080,	133 + ( 13 * 255 ) + 4080	DECAL_POINT 134 + ( ( ( 6 * 4 ) + 3 ) * 255 ) + 4080, 	152 +( 13 * 255 ) + 4080	DECAL_POINT 84 + ( ( ( 6 * 4 ) + 3 ) * 255 ) + 4080, 	151 + ( 13 * 255 ) + 4080	DECAL_POINT 53 + ( ( ( 6 * 4 ) + 3 ) * 255 ) + 4080, 	95 +( 13 * 255 ) + 4080	DECAL_POINT 79 + ( ( ( 6 * 4 ) + 3 ) * 255 ) + 4080,	49 + ( 13 * 255 ) + 4080	DECAL_POINT 114 + ( ( ( 6 * 4 ) + 3 ) * 255 ) + 4080, 	43 +( 13 * 255 ) + 4080data_end_0	label	word; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -; ===================================================================; DECALS LISTdecal_list	label	word	DECAL_LIST 1, decal_groups, decal_datadecal_groups	label	word	DECAL_GROUP 166, 440, decal_data, data_start_0, data_end_0; ===================================================================; TERRAIN DECALS TEXTURESdecal_textures	label	word	TEXTURE_HEADER 1, texture_groups, texture_data, texture_endtexture_groups	label	word	TEXTURE_GROUP texture_data, texture_start_0, texture_end_0texture_data	label	wordtexture_start_0	label	word	TEXTURE_DATA "1194", 0, 1, 4texture_end_0	label	wordtexture_end	label	word; ===================================================================; DECAL_ENDdecal_end	label	word; ===================================================================

Note in :DECAL_GEOMETRY 1, 8, 1, 0I used 8 as a priority... same as shorelines. ( For the shoreline I used 9 ). This allows the decal to show over water. The island has all the characteristics of land.Oddly, when I made the first test island, I made it too close to the default land... and the wave action of the default FS2002 shoreline washed through the land I had made! SO I don't know the priority of underlying wave effects... if such a thing exists. That could cause problems when altering coasts, as the wave action sticks to the underlying old coasts we can cover.

Share this post


Link to post
Share on other sites

Hi Lee, Christian, all.The Oshgosh scenery had a different style of island than the example above. It's code is nearly identical to a water flatten.

include TMFmacros.incinclude CFS2TMFmacros.inc; island2; ===================================================================; DATA_BASEdata_base	label	word	dw	1			; world set number	dd	3556177 	; North Bound	dd	3333916 	; South Bound	dd	322122547 	; East Bound	dd	298261617 	; West Bound	dd	0			; VOR data	dw	0			; lowest VOR freq	dw	0			; highest VOR freq	dd	0			; seeds level 8 data	dd	0			; seeds level 9 data	dd	0			; seeds level 10 data	dd	0			; seeds level 11 data	dd	0			; seeds level 12 data	dd	0			; traffic data	dd	0			; minimum safe altitude data	dd	terrain_data - data_base; terrain mesh data	dd	0			; object data	dd	0			; library data	dd	0			; facilities data	dd	0			; anchor point data	dd	0			; ATIS data	dd	0			; NDB data	dd	0			; dynamic object paths data	dd	0h,0h			; minimum library id	dd	0h,0h			; maximum library id	dd	0			; miscellaneous data	dd	0			; title and description data	dd	0			; magnetic variation data	dd	0			; exception and exclusion data	dd	87654321h		; magic number	dd	0			; compression switch	dw	0			; spare	dd	0h,0h,0h,0h		; GUID	dd	0			; product id	dd	0			; product build number	dd	0			; new facility data pointers	dd	0			; new facility name list data	dd	0			; new facility band list data	dd	0			; new facility data; ===================================================================; TERRAIN_DATAterrain_data	label	word	dd	terrain_header_end - terrain_data; end of terrain header	dd	514				; version	dd	0				; unknown entry	dd	0				; unknown entry	dd	0				; elevation header	dd	0				; land class header	dd	0				; unknown header	dd	0				; class lookup header	dd	0				; season header	dd	0				; class lookup list	dd	0				; water class header	dd	0				; elevation index	dd	0				; land cover index	dd	0				; unknown index	dd	flatten_header - terrain_data	; flatten polygon header	dd	0				; decal header	dd	0				; reserved	dd	0				; reserved	dd	0				; main terrain data	dd	0				; reserved	dd	0				; reserved	dd	0				; reserved	dd	0				; regions header	dd	0				; reserved	dd	0				; reservedterrain_header_end	label	word; ===================================================================; TERRAIN FLATTEN POLYGON HEADERflatten_header	label	word	FLATTEN_HEADER 513, flatten_list, flatten_data, flatten_end; TERRAIN FLATTEN POLYGON DATAflatten_data	label	word; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 	data_start_0	label	word	FLATTEN_DATA 1, 7, 0, 13, 1, 1, 1	; 1st set of points -------------------------------		FLATTEN_POLYGON	26 + [b]120[/b], 1, 0			FLATTEN_POINT 136, 76			FLATTEN_POINT 169, 36			FLATTEN_POINT 184, 22			FLATTEN_POINT 204, 13			FLATTEN_POINT 240, 15			FLATTEN_POINT 254, 25			FLATTEN_POINT 255, 27			FLATTEN_POINT 255, 164			FLATTEN_POINT 244, 215			FLATTEN_POINT 231, 231			FLATTEN_POINT 211, 241			FLATTEN_POINT 192, 243			FLATTEN_POINT 178, 237			FLATTEN_POINT 169, 199			FLATTEN_POINT 166, 136			FLATTEN_POINT 166, 91			FLATTEN_POINT 128, 95			FLATTEN_POINT 129, 95			FLATTEN_POINT 185, 34			FLATTEN_POINT 133, 241			FLATTEN_POINT 216, 0			FLATTEN_POINT 8, 41			FLATTEN_POINT 8, 92			FLATTEN_POINT 1, 163			FLATTEN_POINT 1, 164			FLATTEN_POINT 1, 27data_end_0	label	word; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ; ===================================================================; TERRAIN FLATTEN POLYGON LIST	flatten_list	label	word		FLATTEN_LIST 1, flatten_groups	flatten_groups	label	word	FLATTEN_GROUP 166, 440, flatten_data, data_start_0, data_end_0; ===================================================================; FLATTEN_ENDflatten_end	label	word; ===================================================================

As bolded above, you add 120 decimal to the count value of the 'FLATTEN_POLYGON' macro. It gives an island of the underlying landclass. It is flattened. We could probably 'mesh it up' with a small flatten, to give it a hill, but that might have to be in a different scenery folder, with a higher Scenery Library priority.I like my solution better, as it allows us to 'mesh it up' in the same folder, and add any ground texture we desire.

Share this post


Link to post
Share on other sites
Guest

That's interesting. I wonder how FS determines this polygon is a 26 point island poly and not a normal 146 point flatten poly.Lee.

Share this post


Link to post
Share on other sites

Hi Lee.I have no idea why MS would do this... I'm going to have to test this more, but as I said, I like my island solution better. If you plot the points in MSpaint, on a 256x256 grid, you'll see the shape takes up more than 1 LOD13 grid! That makes me think... compression. I'll test more tomorrow.PSDid you get my e-mail address?

Share this post


Link to post
Share on other sites
Guest christian

Hmm, just a random thought:I was thinking that FS may actually allow us to use concave polys, after some thoughts I had that makes sense, I will try today hopefully...Maybe, what you have found is not the way to do an island, put a polygon with a hole in it. This would be very handy actually. Just a question, have you found any order of points, eg they have to be clockwise or counterclockwise? This is also often used to describe polygons with holes in them...I guess, I should download the new scenery and have a closer look...Cheers, Christian

Share this post


Link to post
Share on other sites
Guest christian

Doh! I should have looked at your pictures first! Your islands ARE concave. I really think the 120 flag is the flag for hole in poly. This would mean only the first 3 bits of this byte are used for point count, ie we only can have 119 points in a polygon.Cheers, Christian

Share this post


Link to post
Share on other sites

Hi Christian and Lee.I need to seriously start drinking.I had the structure wrong... it's actually 2 polygons, each in their own LOD13 area:

include TMFmacros.incinclude CFS2TMFmacros.inc; island2; ===================================================================; DATA_BASEdata_base	label	word	dw	1			; world set number	dd	3556177 	; North Bound	dd	3333916 	; South Bound	dd	322122547 	; East Bound	dd	298261617 	; West Bound	dd	0			; VOR data	dw	0			; lowest VOR freq	dw	0			; highest VOR freq	dd	0			; seeds level 8 data	dd	0			; seeds level 9 data	dd	0			; seeds level 10 data	dd	0			; seeds level 11 data	dd	0			; seeds level 12 data	dd	0			; traffic data	dd	0			; minimum safe altitude data	dd	terrain_data - data_base; terrain mesh data	dd	0			; object data	dd	0			; library data	dd	0			; facilities data	dd	0			; anchor point data	dd	0			; ATIS data	dd	0			; NDB data	dd	0			; dynamic object paths data	dd	0h,0h			; minimum library id	dd	0h,0h			; maximum library id	dd	0			; miscellaneous data	dd	0			; title and description data	dd	0			; magnetic variation data	dd	0			; exception and exclusion data	dd	87654321h		; magic number	dd	0			; compression switch	dw	0			; spare	dd	0h,0h,0h,0h		; GUID	dd	0			; product id	dd	0			; product build number	dd	0			; new facility data pointers	dd	0			; new facility name list data	dd	0			; new facility band list data	dd	0			; new facility data; ===================================================================; TERRAIN_DATAterrain_data	label	word	dd	terrain_header_end - terrain_data; end of terrain header	dd	514				; version	dd	0				; unknown entry	dd	0				; unknown entry	dd	0				; elevation header	dd	0				; land class header	dd	0				; unknown header	dd	0				; class lookup header	dd	0				; season header	dd	0				; class lookup list	dd	0				; water class header	dd	0				; elevation index	dd	0				; land cover index	dd	0				; unknown index	dd	flatten_header - terrain_data	; flatten polygon header	dd	0				; decal header	dd	0				; reserved	dd	0				; reserved	dd	0				; main terrain data	dd	0				; reserved	dd	0				; reserved	dd	0				; reserved	dd	0				; regions header	dd	0				; reserved	dd	0				; reservedterrain_header_end	label	word; ===================================================================; TERRAIN FLATTEN POLYGON HEADERflatten_header	label	word	FLATTEN_HEADER 513, flatten_list, flatten_data, flatten_end; TERRAIN FLATTEN POLYGON DATAflatten_data	label	word; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -data_start_0	label	word	FLATTEN_DATA 1, 7, 0, 13, 1, 1, 1	; 1st line ----------------------------------		FLATTEN_POLYGON	( 128 + 18 ), 1, 0			FLATTEN_POINT 136, 76			FLATTEN_POINT 169, 36			FLATTEN_POINT 184, 22			FLATTEN_POINT 204, 13			FLATTEN_POINT 240, 15			FLATTEN_POINT 254, 25			FLATTEN_POINT 255, 27			FLATTEN_POINT 255, 164			FLATTEN_POINT 244, 215			FLATTEN_POINT 231, 231			FLATTEN_POINT 211, 241			FLATTEN_POINT 192, 243			FLATTEN_POINT 178, 237			FLATTEN_POINT 169, 199			FLATTEN_POINT 166, 136			FLATTEN_POINT 166, 91			FLATTEN_POINT 128, 95			FLATTEN_POINT 129, 95data_end_0	label	word; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -data_start_1	label	word	FLATTEN_DATA 1, 7, 1, 13, 1, 1, 1	; 2nd line ----------------------------------		FLATTEN_POLYGON	( 128 + 5 ) , 1, 0			FLATTEN_POINT 8, 41			FLATTEN_POINT 8, 92			FLATTEN_POINT 1, 163			FLATTEN_POINT 1, 164			FLATTEN_POINT 1, 27data_end_1	label	word; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -; ===================================================================; TERRAIN FLATTEN POLYGON LIST	flatten_list	label	word		FLATTEN_LIST 1, flatten_groups	flatten_groups	label	word	FLATTEN_GROUP 166, 440, flatten_data, data_start_0, data_end_1; ===================================================================; FLATTEN_ENDflatten_end	label	word; ===================================================================

The flag is 128 ( that makes more sense ). It seems worldlc.bgl covers the entire earth, while worldwc.bgl covers some of the worldlc ( that is consistant ). The 128 switch tells the sim to switch the order of landclass over waterclass, for this flatten.

Share this post


Link to post
Share on other sites
Guest christian

Rhumba,I still think the 128 means: leave a hole here. This can be easily tested though. I think this makes sense for various reasons.Test + main reason:Put a mesh onto the island. I bet you, a polygon with a hole will not flatten the mesh in the hole.This is really handy. Rather than having to split polygons whenever there is an island in the middle, you can just insert a hole into the flatten (water)polygon and the island will not be flattened. I'll do some testing on this... (I hope I'm right otherwise this is useless. We would still need to split a poly to keep the mesh).Cheers, Christian

Share this post


Link to post
Share on other sites
Guest

Hello,I think I am missing something important here...where are those macros to be included as you say?. I have been looking for the TMFmacros in the library without luck, are these part of some Christian works?>

 >include TMFmacros.inc >include CFS2TMFmacros.inc > Thank youRafael

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this  

  • Tom Allensworth,
    Founder of AVSIM Online


  • Flight Simulation's Premier Resource!

    AVSIM is a free service to the flight simulation community. AVSIM is staffed completely by volunteers and all funds donated to AVSIM go directly back to supporting the community. Your donation here helps to pay our bandwidth costs, emergency funding, and other general costs that crop up from time to time. Thank you for your support!

    Click here for more information and to see all donations year to date.
×
×
  • Create New...