gbadev.org forum archive

This is a read-only mirror of the content originally found on forum.gbadev.org (now offline), salvaged from Wayback machine copies. A new forum can be found here.

Beginners > Visual Studio and Apex Audio System; undefined references...

#27716 - [Titan] - Tue Oct 19, 2004 11:44 pm

Hi all,

I'm trying to get Apex Audio System to work in my project, but somehow I can't link the library to the rest of my program.
I'm using MSVS 6.0 as development environment, and the folowing makefile:
Code:
# ------------------------------------------
# Title:      Default Makefile for use in VC++
# File:          Dune2.mak
# Revision:     01/06/2002
#
# Author:      Benjamin D. Hale
# Orignally by:         Jaap Suter
# Contributed to by:    Christer Andersson
#
# Info:              This file is contains the make-instructions
#         for the project. Replace DEVDIR with the appropriate
#                       base directory for devkitadv. After you make the
#                       needed modifications here rename this file to
#                       <project_name>.mak so Visual C++ does not get
#                       confused.
# -------------------------------------------

# -------------------------------------------
# Project name definition makes this whole thing
# a lot easier to use. Only two total modifications
# (other than what .o files will be needed)
# should be needed to get this working with your
# compiler and Visual C++. Replace "Default" with
# your project's name.

# -------------------------------------------

PROJECT = AASExample

# -------------------------------------------
# Define some directories;
# -------------------------------------------

# -------------------------------------------
# Base Directory for gcc arm-agb-elf replace with
# wherever you put your gba devkitadv files.
# -------------------------------------------

DEVDIR  = D:\GBA\DevkitAdv

# -------------------------------------------
# Source directory (where your project's source files are located.)
# -------------------------------------------

SRCDIR  = D:\GBA\projects\AAS\

# -------------------------------------------
# Compiler Directories for binaries, includes and libs.
# -------------------------------------------

CMPDIR  = $(DEVDIR)\bin
LIBDIR  = $(DEVDIR)\lib\gcc-lib\arm-agb-elf\3.0.2\interwork
LIBDIR2 = $(DEVDIR)\arm-agb-elf\lib\interwork
LIBDIR3 = $(SRCDIR)\LibAAS
INCDIR  = $(DEVDIR)\lib\gcc-lib\arm-agb-elf\3.0.2\include
INCDIR2 = $(DEVDIR)\arm-agb-elf\include
INCDIR3 = $(SRCDIR)\LibAAS

# -------------------------------------------
# END of directory defines
# -------------------------------------------

# -------------------------------------------
# Define what extensions we use;
# -------------------------------------------
.SUFFIXES : .cpp .c .s

# -------------------------------------------
# Define the flags for the compilers;
# -------------------------------------------
CFLAGS  = -I $(INCDIR3) -I $(INCDIR2) -I $(INCDIR) -I $(SRCDIR) -mthumb-interwork -c -g -O3 -Wall -fverbose-asm
SFLAGS  = -I $(INCDIR2) -I $(INCDIR) -mthumb-interwork
LDFLAGS = -L $(LIBDIR3) -L $(LIBDIR) -L $(LIBDIR2) -T LinkScript -l AAS

# -------------------------------------------
# Define the list of all O files;
# Just follow the syntax shown to add any
# other objects your project may need to
# compile properly. You will need to add
# files to this part to make it work with
# your project add a \ to the end of all o
# files except the last one. Like below.
# -------------------------------------------

O_FILES          = \
                   crt0.o \
               AAS_Data.o \
               AASExample.o

# -------------------------------------------
# There should be no need to modify anything
# below here.
# -------------------------------------------

# -------------------------------------------
# Define the final dependecy;
# -------------------------------------------
all : $(PROJECT).gba

# -------------------------------------------
# Define the copy from .elf to .bin file
# -------------------------------------------
$(PROJECT).gba : $(PROJECT).elf
   $(CMPDIR)\objcopy -O binary $(PROJECT).elf $(PROJECT).gba
   -@echo ------------------------------------------
   -@echo Done
   -@echo ------------------------------------------

$(PROJECT).elf : $(O_FILES)
   $(CMPDIR)\ld $(LDFLAGS) -o $(PROJECT).elf $(O_FILES) -lstdc++ -lc -lgcc
   -@echo ------------------------------------------
   -@echo Linking Done
   -@echo ------------------------------------------

AAS_Data.o::
   conv2aas AAS_Data
   $(CMPDIR)\as $(SFLAGS) -o $@ AAS_Data.s
# -------------------------------------------
# Define each compile;
# -------------------------------------------
{$(SRCDIR)}.cpp.o::
   $(CMPDIR)\gcc  $(CFLAGS) $<
   -@echo ------------------------------------------
   -@echo CPP-Sources Compiled
   -@echo ------------------------------------------

{$(SRCDIR)}.c.o::
   $(CMPDIR)\gcc  $(CFLAGS) $<
   -@echo ------------------------------------------
   -@echo C-sources Compiled
   -@echo ------------------------------------------

# -------------------------------------------
# Define each assemble;
# -------------------------------------------
{$(SRCDIR)}.s.o:
   $(CMPDIR)\as $(SFLAGS) $(SRCDIR)\$*.s -o$@
   -@echo ------------------------------------------
   -@echo ASM-Sources Compiled
   -@echo ------------------------------------------
   
# -------------------------------------------
# Any problems with getting this working email
# questions to whatzdat_pimp@hotmail.com .
# This was tested on devkitadv r4 and Visual C++ 6
# on a p3 450/512mb/Windows XP Pro.
# -------------------------------------------
# EOF;


this has worked without problems until I tried to link a library to my project.
My source file, linkscript and crt0.s come directly from "example2" from AAS. The directory structure is exactly the same as in the sample. Yet when I try to build my project, I get the following error:
Code:
--------------------Configuration: AASExample - Win32 Debug--------------------
Microsoft (R) Program Maintenance Utility   Version 6.00.8168.0
Copyright (C) Microsoft Corp 1988-1998. All rights reserved.
 conv2aas AAS_Data
/---------------------------------------------\
| Conv2AAS v1.07        WAV, RAW & MOD -> AAS |
| Copyright (c) 2003, Apex Designs            |
\---------------------------------------------/
Adding WAV Ambulance.wav...Done!
Adding RAW Boom.raw...Done!
Adding MOD CreamOfTheEarth.mod...4 channels...Done!
song_length:27 last_pattern:27
Writing AAS_SampleData (Unique:18 Actual:18 Length:123780)...Done!
Writing AAS_PatternData (Unique:66 Actual:112 Length:16896)...Done!
 D:\GBA\DevkitAdv\bin\as -I D:\GBA\DevkitAdv\arm-agb-elf\include -I D:\GBA\DevkitAdv\lib\gcc-lib\arm-agb-elf\3.0.2\include -mthumb-interwork -o AAS_Data.o AAS_Data.s
 D:\GBA\DevkitAdv\bin\ld -L D:\GBA\projects\AAS\LibAAS -L D:\GBA\DevkitAdv\lib\gcc-lib\arm-agb-elf\3.0.2\interwork -L D:\GBA\DevkitAdv\arm-agb-elf\lib\interwork -T LinkScript -l AAS -o AASExample.elf crt0.o  AAS_Data.o  AASExample.o -lstdc++ -lc -lg
cc
crt0.o: In function `jump_intr_AAS':
crt0.o(.iwram+0x108): undefined reference to `AAS_FastTimer1InterruptHandler'
AASExample.o: In function `AgbMain':
D:/GBA/projects/AAS/AASExample.c:53: undefined reference to `AAS_SetConfig'
D:/GBA/projects/AAS/AASExample.c:56: undefined reference to `AAS_ShowLogo'
D:/GBA/projects/AAS/AASExample.c:63: undefined reference to `AAS_MOD_Play'
D:/GBA/projects/AAS/AASExample.c:77: undefined reference to `AAS_SFX_Play'
D:/GBA/projects/AAS/AASExample.c:84: undefined reference to `AAS_SFX_Play'
D:/GBA/projects/AAS/AASExample.c:79: undefined reference to `AAS_SFX_Stop'
AASExample.o:D:/GBA/projects/AAS/AASExample.c:16: undefined reference to `AAS_DoWork'
NMAKE : fatal error U1077: 'D:\GBA\DevkitAdv\bin\ld' : return code '0x1'
Stop.
Error executing NMAKE.

AASExample.gba - 1 error(s), 0 warning(s)


As you can see, it is able to find the library (there's no error indicating the library could not be found) but somehow it's not able to find any of the library's functions.

What am I doing wrong here? Any suggestions?

t.i.a.

/me get's back to banging his head against the wall...

#27724 - DiscoStew - Wed Oct 20, 2004 1:45 am

Have you tried using 'gcc' instead of 'ld' for linking your object files? I had this same problem some time back in this thread "Mixing 8ad and Apex", but with the help of jd and tepples, using gcc for the linker fixed those problems. Using 'gcc' actually calls 'ld' at that point of linking, but 'gcc' handles those in-between things that using plain 'ld' doesn't.
_________________
DS - It's all about DiscoStew

#27732 - jd - Wed Oct 20, 2004 5:20 am

GCC has an unusual quirk that libraries have to be specified after the object files on the command line. You should remove "-l AAS" from LDFLAGS and add it at the linking phase so the line becomes:

Code:

$(CMPDIR)\ld $(LDFLAGS) -o $(PROJECT).elf $(O_FILES) -lstdc++ -lc -lgcc -l AAS


As DiscoStew pointed out, linking with ld can cause problems as it doesn't automatically link in everything you need - but, judging by the messages you're getting, it looks as though you've already worked around those issues. (But linking with gcc would shorten your makefile.)

#27743 - [Titan] - Wed Oct 20, 2004 9:28 am

argh.. I can't believe it was that simple >_<

I still use LD to link (it works now, so no need to change it). And after adding -lAAS to the very end of the command line for LD. The Undefined references to the AAS library were gone. Only to be replaced by undefined references caused by the library itself (the same as DiscoStew had ("undefined reference to `_call_via_r3' "). That was solved by placing -lgcc at the end of the commandline. The complete command for LD now looks like this:
Code:
$(PROJECT).elf : $(O_FILES)
   $(CMPDIR)\ld $(LDFLAGS) -o $(PROJECT).elf $(O_FILES) -lstdc++ -lc -lAAS -lgcc
   -@echo ------------------------------------------
   -@echo Linking Done
   -@echo ------------------------------------------

And I've removed -lAAS from the LDFLAGS.

Code:
------------------------------------------
Linking Done
------------------------------------------
 D:\GBA\DevkitAdv\bin\objcopy -O binary AASExample.elf AASExample.gba
------------------------------------------
Done
------------------------------------------

AASExample.gba - 0 error(s), 0 warning(s)

Now that's what I wanted to see, Thanks guys!

/me is off to play around with aas a bit, and integrate it in my real project ^_^

#27749 - [Titan] - Wed Oct 20, 2004 2:03 pm

Next problem ^_^;;

I've integrated AAS in my project (and yes, it compiles) and everything works fine, until I start to play a MOD, then the screen starts shaking to the beat of the music (pretty cool effect, but it becomes quite annoying).

Now the question is, is this a feature, or is it a bug (made by me)?

A little info on the structure of my program:
-Initialize game
-set all OAM data
-set AAS settings
-Extract level
-Copy Tile palette+tiles
-Copy sprite palette + sprites
-Set background + display mode (mode 2, background2, objects on)
-Start timer 3 (for FPS counter)
-Main program loop
-Get input
-Wait for VSync
-fill BG 2
-determine new values for Affine registers
-do FPS counting
-end of program

The only DMA copy I use, is AAS_DoDMA3. In crt0.s, multiple interrupts are enabled, and in my interrupt handler, AAS_Timer1InterruptHandler() is called whenever there's a timer 1 interrupt. (sound plays perfect btw)
The controls are like this:
A/B : zoom
up/down/left/right : move the map
left/right shoulder button : rotate map
start/select : play/stop music

I've uploaded a small demo here (124KB)
The screen only starts to shake when the music is playing, and the shaking is directly connected to the music playing (a different track results in a different shaking pattern).
And please, don't pay too much attention to my 5-minutes-well-spent-isometric-engine (or 5mwsie for short) it still needs a lot of work.

Any suggestions are welcome, thanks in advance!


Off to write my own .VOC to AAS converter in the meantime ^_^

#27763 - jd - Wed Oct 20, 2004 8:39 pm

[Titan] wrote:

The screen only starts to shake when the music is playing, and the shaking is directly connected to the music playing (a different track results in a different shaking pattern).


AAS supports two interrupt handling methods:

1) The easier way. Just make sure that a timer 1 interrupt results in a call to AAS_Timer1InterruptHandler(). This is the method used in AASExample.

2) The harder way. Use the custom "AAS_MultipleInterrupts" mode in the included crt0.s. (This will give timer 1 interrupts priority and automatically call AAS_FastTimer1InterruptHandler() (not AAS_Timer1InterruptHandler()) when a timer 1 interrupt occurs.) You will also need to set up AAS_IntrTable[] to point to the routines that handle all the other interrupts. Additionally, you need to call AAS_DoWork() at least 50 times per second - the recommended way to do this is by putting it in your VBlank handler. This is the method used in AASExample2.

It's hard to say without seeing the source code, but it looks as though the problem you're getting is caused by AAS interrupting your code during the "Wait for VSync" phase. To fix this, you'll have to switch to method (2) above. However, since you don't seem to have a VBlank handler in your game, you've got two options:

1) The hacky way. Call AAS_DoWork() immediately before your "Wait for VSync" step. Note that outside of the main game you still need to call AAS_DoWork() at least 50 times per second, so you'll need to switch to calling it during a VBlank interrupt or something similar in those cases.

2) The neater way. Change your game so that does all the time critical stuff (updating backgrounds etc.) in the VBlank interrupt rather than in the main code, and call AAS_DoWork() at the end of that interrupt.


Last edited by jd on Thu Oct 21, 2004 12:12 am; edited 1 time in total

#27768 - [Titan] - Wed Oct 20, 2004 9:47 pm

The hacky way did the trick. I first tried using the VBlank interrupt and call AAS_DoWork() whenever a VBlank interrupt occurred, but all it did was cut my framerate in half. Putting AAS_DoWork() right under the WaitForVBlank() did nothing to the framerate, but the bouncing was still there. And finally, putting AAS_DoWork() right before WaitForVBlank fixed it all. The framerate is still at 60 FPS, and the shaking screen has disappeared. Thanks!

The only time critical code in my program is setting the Affine Registers, placing the right tiles in the right place, and putting the sprites at the right place. That's not that terribly CPU intensive so I guess that won't be much of a problem.
I just did some cpu measuring (using the vcount register ^_^) and AAS_DoWork() takes about 6-8 lcd lines to complete (2.6% - 3.5% CPU load), the background filling takes a steady 62 lines to complete (27.2% CPU load) but hasn't been optimized yet. At the moment, that leaves 158 lines (69.3% CPU load) unused for command processing and A.I. Both of them are not time critical (as if the player would ever notice that his unit reacts 3 frames after he pressed a button ^_^).

Anyway, thanks for your help, I appreciate it.

#27771 - jd - Thu Oct 21, 2004 12:21 am

[Titan] wrote:
I just did some cpu measuring (using the vcount register ^_^) and AAS_DoWork() takes about 6-8 lcd lines to complete (2.6% - 3.5% CPU load),


I should point out that 1/6 of the time you should find that AAS_DoWork() will return virtually instantly (as it only really needs to be called 50 times a second, and will return immediately if it is called more often than that) - so the average CPU usage would be 5/6 of the figure you measured.

[Titan] wrote:
Anyway, thanks for your help, I appreciate it.


No problem. I'm glad it's all working now.