GP32 External C Image Arrays


pea

developer
Joined
Oct 3, 2004
Messages
1,089
Age
46
Location
New Zealand
Website
www.projectitis.com
Hi all,

I have a problem including external c arrays in my apps. I convert images to arrays, and include them to my list of objects in the makefile and code like so:

Code:
MAKEFILE:
OBJS = gpdesktop.o gpd.o gpd_graphics.o gpd_windows.o gpd_fonts.o memcpy.o images/gpdlogo.o images/gpdmouse.o

CODE:
void gpd_init( tGPD_sys *gpd_system ){
	extern unsigned char gpdlogo[];
	extern unsigned char gpdmouse[];

The only problem is that only the FIRST included file ever works! It doesn't matter which I use, only the first works.

If I add both arrays to the same c file, it still doesn't work.

If I include the second array (gpdmouse) straight in the code and only have the first as an extern variable, it works ok.

Any ideas?
 
That's pretty much how I do it too. Except I leave mine as globals, not in a function :unsure:


How do you mean 'doesn't work'?
Complete trash or offsets or skewed or ...?


I'd say check the basics of the image data .. width, height, palette, etc.
When something easy goes wrong I've usually forgotten something simple :rolleyes:
 
hmm...
I just put the array in different C files and declare all of the as extern in one single header file (global) and include it that when need. ... well pretty similar to the way I use it ....
 
More to point.. we'd need to see the image declarations in the individual C files; they're probably broken :) Or else the rest of your makefile that includes OBJS is broken.. one or the other :)

jeff
 
i had a similar problem ..... i think it's a memory allocation problem with extern arrays.

JUST TRY TO CHANGE THE ORDER YOU DECLARE THE ARRAYS

array1
array2

crash in a different place that

array2
array1

just interesting and frustrating ;)

Aiken
 
Code:
#include "char.h"
Works for me.

Is there any reason why I should do it another way?
Sorry, don't know very much about C.
 
You could just put the arrays in header files, and include those. Like so:

Put this in a header file, called for example, blink.h:

unsigned short blink[255] = { ... };

Put this in your code:

#include "blink.h"

To keep it nice and clean, make another header file, in which you put all your graphics, and then include that into your main program.
 
Hi all,

The data in the arrays are fine. FYI they are raw GIF images, compressed, simply stuck in an array. My code decompresses them into a standard rotated array of 16bpp colour values.

I can include them one at a time (just uisng one) and both work.

If I try to put both arrays (yes rtb7, they are exactly like that unsigned char gpdmouse[] = { ... };) in the same file then the second one never works (so like you say Aiken, it seems to be the order). One thing is that each array is on a single line each, and one of them itself is longer than 65535 bytes. Do you think the compiler is spitting the dummy on this? (GCC)

I have one of the images (the large one) in an external c file, and the other I just include as a standard variable because its only 200 bytes or so.

This works ok, but is highly annoying.
 
Hi generalnmx,

I don't think they do, otherwise the Mr.Mirko example wouldn't compile or work (which it does, BTW). The makefile for that is:

Code:
CC = arm-elf-gcc
LD = arm-elf-gcc
AS = arm-elf-as
AR = arm-elf-ar

PRG  = sprite
OBJS = sprite.o sprites/garfield.o  sprites/odie.o  sprites/test.o

LIBS      = -L../lib -lmirkoSDK -lm
CRT0      = ../lib/crt0.S
LNKSCRIPT = ../lib/lnkscript
INCLUDES  = -I../lib.src/include
CFLAGS    = $(INCLUDES) -O2 -s -mtune=arm9tdmi

all:	$(OBJS)
	$(CC) -c -o crt0.o $(CRT0)
	$(LD) -nostartfiles -s -Wall -Wl,-Map,Test.map  -T $(LNKSCRIPT) crt0.o -o $(PRG).elf $(OBJS) $(LIBS)
	arm-elf-objcopy -O binary $(PRG).elf $(PRG).bin
	b2fxec -a Mirko_Roller -t SDK_EXAMPLE_$(PRG) $(PRG).bin $(PRG).fxe
 
Does the order you decompress them matter? ie. are there mis-initialized variables?


Other than that it's just data that you're stepping through and I can't see any problem with doing that :unsure:


:unsure: You could try padding them out to an aligned number of bytes :unsure:
But I'm clutching at straws. :rolleyes:


Let us know when you've fixed it ;)
 
I think it does have something to do with aligned bytes, which is weird. Is there a keyword I can use in the code (not a compiler flag) to let the compiler know that the data is NOT aligned? In delphi there is the keyword 'packed'....
 
Yup! Here ya go!

http://gcc.gnu.org/onlinedocs/gcc-3.4.3/gc...-attribute-1657

packed is a little further down ;)


Looks damned messy to me though :/
The only other way I can think of is messing with linker scripts
icon8.gif
 

Attachments

  • icon8.gif
    icon8.gif
    677 bytes · Views: 169
Last edited by a moderator:
gp32rich - thanks heaps for that link. The aligned attribute was just what I was after.

First I used __attribute__ ((aligned(32))) (yip, its damned messy alright) to try to force the compiler to aligne the data to 4-byte boundary, because I had heard that this can cause all sorts of problems. Well, this worked ok, so I tried 16 instead, and that works great too. I can now put the variables in any order, and they all work:

Code:
unsigned char variable1[] __attribute__ ((aligned (16))) = {...};
unsigned char variable2[] __attribute__ ((aligned (16))) = {...};
unsigned char variable3[] __attribute__ ((aligned (16))) = {...};

Thanks!

EDIT:
Weird, but I just tried aligned(8) as well, and it works too! It the compiler/linker is not even byte-aligning the data there must be something strange going on :blink: - lets just put it down to one of those mysteries...
 
hmm.. do you remember the performance of the differnet memcopy functions? with this tweak we should re-evaluate the performance/code then.

should I use __attribute__ ((aligned(32)) on any image data then?
is there one closing bracket too much?
 
Hi Synchro,

No you are missing one bracket from the end. Count them - 3 open, 2 close. Need 1 more

This compiler attribute doesn't affect the speed of my code at all because the data that I have aligned isn't my actual pixel data, but just some compressed data that later is uncompressed to my pixel data.

Also, aligning your actual pixel data wouldn't help (in most cases) because the sprite render routine doesn't always start copying from the very first byte. The routines that I have developed effectively truncate the data if the sprite is partially off the screen, and only copy the visisble data, which usually doesn't start with the first byte.
 
I found out that on my code, when I use sprite data with an un even pixel count (like a 5x5 sprite) the whole code runs slower even when I don't use that data....
 
Back
Top