Gcc tips for demoscene coding?
  • Order of the Butterfly
    Order of the Butterfly
    BalrogSoft
    Posts: 171 from 2006/10/6
    From: Spain
    I'm making a tinygl skeleton code for a 4kb intro. I found some tips on tutorials to make intros for linux, i have applied some of them, with good result, but the smallest build after crunch haves 3.6kb, only for a simple tinygl initialization code.

    I have added some parameters like -Os -s -ffast-math -fomit-frame-pointer, but i read one that appears more interesting, excluding the use of main function and use _start function, this saves some bytes, but i can't get it working with tinygl initialization, at linking says "undefined reference to 'SysBase'", i probably miss to link it with another library. I posted the code and makefile, and compilation output.

    intro.c
    Code:

    #include <proto/tinygl.h>

    void display (void)
    {
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    glutSwapBuffers();
    }

    void _start()
    {
    glutInit(NULL,NULL);//&argc, argv);

    glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);
    glutInitWindowSize(640, 480);
    glutFullScreen();
    glutCreateWindow(NULL);

    glClearColor(0.0f, 0.0f, 0.0f, 0.5f);
    glClearDepth(1.0f);
    glEnable(GL_DEPTH_TEST);
    glMatrixMode(GL_PROJECTION);
    gluPerspective(80, 640.0 / 480.0, 1.0, 5000.0);
    glMatrixMode(GL_MODELVIEW);

    glutDisplayFunc(display);

    glutMainLoop();

    }


    Makefile
    Code:

    CC = gcc
    LD = ld
    STRIP = strip
    CFLAGS = -Os -s -ffast-math -fomit-frame-pointer -noixemul -ISDK:tinygl-sdk/include
    LIBS = -lGL

    INTRO_OBJS = intro.o

    all: intro

    intro: $(INTRO_OBJS)
    $(LD) -o $@ $(INTRO_OBJS) $(LIBS)
    $(STRIP) -s -R .comment -R .gnu.version $@
    chmod u+x $@

    clean:
    rm -f *.o intro


    Output
    Code:

    gcc -Os -s -ffast-math -fomit-frame-pointer -noixemul -ISDK:tinygl-sdk/include -c -o intro.o intro.c
    ld -o intro intro.o -lGL -lc
    /gg/ppc-morphos/lib/libGL.a(sharedinit.o): In function `__CSTP_init_TinyGLBase':
    sharedinit.o(.text+0x1a): undefined reference to `SysBase'
    sharedinit.o(.text+0x26): undefined reference to `SysBase'
    /gg/ppc-morphos/lib/libGL.a(sharedinit.o): In function `__DSTP_cleanup_TinyGLBase':
    sharedinit.o(.text+0xca): undefined reference to `SysBase'
    sharedinit.o(.text+0xd6): undefined reference to `SysBase'
    make: *** [intro] Error 1


    Somebody knows other tips for demoscene intro coding?

    Thanks in advance.

    [ Edited by BalrogSoft on 2010/7/7 22:37 ]
    Balrog Software - AmigaSkool.net
    Mac Mini - MorphOS 3.8 - G4 1.5Ghz - Ati 9200 64 Mb
    Efika - MorphOS 3.6 - Ati 9200 64Mb - 80 Gb HD
    Amiga 1200D - OS 3.9 - Blizzard 603e/240mh
  • »07.07.10 - 19:35
    Profile Visit Website
  • MorphOS Developer
    Piru
    Posts: 588 from 2003/2/24
    From: finland, the l...
    To gain as short program as possible you need to open tinygl.library yourself and link with -nostartfiles.
  • »07.07.10 - 20:26
    Profile
  • MorphOS Developer
    Piru
    Posts: 588 from 2003/2/24
    From: finland, the l...
    Here's a somewhat optimized version:

    http://sintonen.fi/src/tinyglinit/

    It applies some magic to remove the unused sections (see the --strip-section stuff in the makefile). You must be careful not to add any static data (.sdata) to the binary or things will end badly.

    Here it builds to 2060 byte binary before compression. With lzma e it compresses to 703 bytes. So add the lzmaLoader_shared header and you're at 380 + 703 = 1083 bytes.

    [ Edited by Piru on 2010/7/8 1:22 ]
  • »07.07.10 - 20:47
    Profile
  • Order of the Butterfly
    Order of the Butterfly
    BalrogSoft
    Posts: 171 from 2006/10/6
    From: Spain
    Hi Piru.

    It's just what i made yesterday with a reduced version of minigl-wrapper example from sdk and the result was bigger than this one. Using main function instead _start gives an exe of 3792 bytes. The code equivalent with manual initialization and removing -lGL since it isn't need gives an exe of 4092 bytes, but i will try the new optimized version. This manual build with _start function gives the same undefined reference SysBase error, but now i see the problem with a quick look to your modifications. Thanks you.

    This is the code:
    Code:

    #include <mgl/gl.h>

    struct GfxBase *GfxBase;
    struct IntuitionBase *IntuitionBase;
    struct Library *CyberGfxBase;
    struct Library *UtilityBase;

    struct Library *TinyGLBase;

    GLContext *__tglContext;

    void QuitTinyGL(void)
    {
    if(TinyGLBase)
    {
    if(__tglContext)
    GLClose(__tglContext);

    CloseLibrary( TinyGLBase );
    TinyGLBase = NULL;
    }

    CloseLibrary(UtilityBase);
    CloseLibrary(CyberGfxBase);
    CloseLibrary((struct Library *)IntuitionBase);
    CloseLibrary((struct Library *)GfxBase);
    }

    int InitTinyGL(void)
    {
    /* apps expect these libs are open */
    GfxBase = (struct GfxBase *)OpenLibrary("graphics.library", 50L);
    IntuitionBase = (struct IntuitionBase *)OpenLibrary("intuition.library", 50L);
    CyberGfxBase = OpenLibrary("cybergraphics.library", 50L);
    UtilityBase = OpenLibrary("utility.library", 50L);

    TinyGLBase = (struct Library *)OpenLibrary("tinygl.library",0);

    if( !GfxBase || !IntuitionBase || !CyberGfxBase || !UtilityBase || !TinyGLBase )
    {
    QuitTinyGL();

    return 1;
    }

    __tglContext = GLInit();

    return 0;
    }


    void display ( void )
    {
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    glutSwapBuffers();
    }

    int main(int argc, char **argv)
    {
    InitTinyGL();
    glutInit(NULL, NULL);

    glutInitDisplayMode( GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);
    glutInitWindowSize(640, 480);
    glutFullScreen();
    glutCreateWindow(NULL);

    glClearColor(0.0f, 0.0f, 0.0f, 0.5f);
    glClearDepth(1.0f);
    glEnable(GL_DEPTH_TEST);
    glMatrixMode(GL_PROJECTION);
    gluPerspective(80, 640.0 / 480.0, 1.0, 5000.0);
    glMatrixMode(GL_MODELVIEW);

    glutDisplayFunc(display);

    glutMainLoop();
    QuitTinyGL();
    return 0;
    }


    [ Edited by BalrogSoft on 2010/7/8 0:15 ]

    [ Edited by BalrogSoft on 2010/7/8 0:16 ]
    Balrog Software - AmigaSkool.net
    Mac Mini - MorphOS 3.8 - G4 1.5Ghz - Ati 9200 64 Mb
    Efika - MorphOS 3.6 - Ati 9200 64Mb - 80 Gb HD
    Amiga 1200D - OS 3.9 - Blizzard 603e/240mh
  • »07.07.10 - 21:09
    Profile Visit Website
  • Order of the Butterfly
    Order of the Butterfly
    BalrogSoft
    Posts: 171 from 2006/10/6
    From: Spain
    Now i'm trying to make some kind of sound using ahi, i have played a bit with PlayTest example from AHI dev package. I made a sinus wave played from buffers, but when i use the entry functions with -nostartfiles, it shows an undefined reference of exit function from libauto.a, it seems that it wasn't linking with stdlib, the same error can be reproduced if is added an exit function at the end of entry function of intro.c.?I tried to link with libstdc++.a, but without any successfull result. Somebody know what is happening?

    [ Edited by BalrogSoft on 2010/7/8 23:38 ]
    Balrog Software - AmigaSkool.net
    Mac Mini - MorphOS 3.8 - G4 1.5Ghz - Ati 9200 64 Mb
    Efika - MorphOS 3.6 - Ati 9200 64Mb - 80 Gb HD
    Amiga 1200D - OS 3.9 - Blizzard 603e/240mh
  • »08.07.10 - 20:37
    Profile Visit Website
  • MorphOS Developer
    Piru
    Posts: 588 from 2003/2/24
    From: finland, the l...
    You must open ahi.device yourself and not rely on the libauto.

    http://arp2.berlios.de/ahi/docs/ahidev.html#SEC15

    Use of any external static libs should be avoided. The code in them usually is rather bloated.

    [ Edited by Piru on 2010/7/9 1:02 ]
  • »08.07.10 - 21:00
    Profile
  • Priest of the Order of the Butterfly
    Priest of the Order of the Butterfly
    Crumb
    Posts: 736 from 2003/2/24
    From: aGaS & CUAZ Al...
    @balrog

    you could also add specific cpu support using -mcpu=750,603,... I don't think it helps much but since you asked...
  • »08.07.10 - 21:26
    Profile Visit Website
  • Order of the Butterfly
    Order of the Butterfly
    BalrogSoft
    Posts: 171 from 2006/10/6
    From: Spain
    I open ahi.device manually with OpenDevice, as i said this error can be reproduced using intro.c, adding exit at the end of entry function, and i guess that should be a problem with stdlib, but here is the code anyway if it can help to undestand the problem:

    intro.c
    Code:

    #include <proto/exec.h>
    #include <proto/tinygl.h>
    #include <stdio.h>

    static void display(void);
    struct ExecBase *SysBase;
    struct Library *TinyGLBase;
    GLContext *__tglContext;

    #define __TEXTSECTION__ __attribute__((section(".text")))

    int entry(void)
    {
    SysBase = *(struct ExecBase **) 4;
    TinyGLBase = OpenLibrary("tinygl.library", 50);
    if (TinyGLBase)
    {
    __tglContext = GLInit();
    if (__tglContext)
    {

    glutInit(NULL,NULL);

    glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);
    glutInitWindowSize(640, 480);
    glutFullScreen();
    glutCreateWindow(NULL);

    glClearColor(0.0f, 0.0f, 0.0f, 0.5f);
    glClearDepth(1.0f);
    glEnable(GL_DEPTH_TEST);
    glMatrixMode(GL_PROJECTION);
    gluPerspective(80, 640.0 / 480.0, 1.0, 5000.0);
    glMatrixMode(GL_MODELVIEW);

    glutDisplayFunc(display);

    glutMainLoop();

    GLClose(__tglContext);
    }

    CloseLibrary(TinyGLBase);
    }
    exit(0);
    return 0;
    }

    static void display(void)
    {
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    glutSwapBuffers();
    }

    /* __abox__ symbol is required or else the binary is loaded as PowerUP app */
    const int __abox__ __TEXTSECTION__ = 1;


    Ahi Playtest.c
    Code:

    /*
    ** This program uses the device interface to play a sampled sound.
    ** The input is read from THE DEFAULT INPUT, make sure you
    ** start it with "PlayTest pri < mysample.raw" !
    ** Where pri is a number from -128 to +127 (may be omitted)
    ** The sample should be 8 bit signed, mono (see TYPE).
    **
    ** PLEASE NOTE that earlier versions of this example contained a bug
    ** that sometimes DeleteIORequest'ed a pointer that was AllocMem'ed!
    */

    #include <devices/ahi.h>
    #include <dos/dosasl.h>
    #include <exec/memory.h>
    #include <proto/exec.h>
    #include <proto/dos.h>
    #include <proto/ahi.h>
    #include <stdlib.h>

    #define FREQUENCY 8000
    #define TYPE AHIST_M8S
    #define BUFFERSIZE 20000

    #ifndef M_PI
    #define M_PI 3.14159265
    #endif

    void clean(LONG rc);

    struct ExecBase *SysBase;

    struct MsgPort *AHImp = NULL;
    struct AHIRequest *AHIios[2] = {NULL,NULL};
    struct AHIRequest *AHIio = NULL;

    APTR AHIiocopy = NULL;
    BYTE AHIDevice = -1;

    BYTE buffer1[BUFFERSIZE];
    BYTE buffer2[BUFFERSIZE];

    #define __TEXTSECTION__ __attribute__((section(".text")))

    //int main(int argc, char *argv[])
    int entry(void)
    {
    SysBase = *(struct ExecBase **) 4;
    BYTE *p1=buffer1,*p2=buffer2;
    void *tmp;
    ULONG signals,length;
    struct AHIRequest *link = NULL;
    BYTE pri = 0;

    //Printf("Sound priority: %ldn", pri);

    if((AHImp=CreateMsgPort()) != NULL) {
    if((AHIio=(struct AHIRequest *)CreateIORequest(AHImp,sizeof(struct AHIRequest))) != NULL) {
    AHIio->ahir_Version = 4;
    AHIDevice=OpenDevice(AHINAME,0,(struct IORequest *)AHIio,0);
    }
    }

    if(AHIDevice) {
    //Printf("Unable to open %s/0 version 4n",AHINAME);
    clean(RETURN_FAIL);
    }

    // Make a copy of the request (for double buffering)
    AHIiocopy = AllocMem(sizeof(struct AHIRequest), MEMF_ANY);
    if(! AHIiocopy) {
    clean(RETURN_FAIL);
    }
    CopyMem(AHIio, AHIiocopy, sizeof(struct AHIRequest));
    AHIios[0]=AHIio;
    AHIios[1]=AHIiocopy;

    SetIoErr(0);
    LONG i;
    for(i=0; i<BUFFERSIZE;++i) p1[i] = (BYTE)(255*sin(2*M_PI*40*i/FREQUENCY));

    for(;;) {

    // Fill buffer

    length = BUFFERSIZE;//Read(Input(),p1,BUFFERSIZE);

    // Play buffer
    AHIios[0]->ahir_Std.io_Message.mn_Node.ln_Pri = pri;
    AHIios[0]->ahir_Std.io_Command = CMD_WRITE;
    AHIios[0]->ahir_Std.io_Data = p1;
    AHIios[0]->ahir_Std.io_Length = length;
    AHIios[0]->ahir_Std.io_Offset = 0;
    AHIios[0]->ahir_Frequency = FREQUENCY;
    AHIios[0]->ahir_Type = TYPE;
    AHIios[0]->ahir_Volume = 0x10000; // Full volume
    AHIios[0]->ahir_Position = 0x8000; // Centered
    AHIios[0]->ahir_Link = link;
    SendIO((struct IORequest *) AHIios[0]);

    if(link) {

    // Wait until the last buffer is finished (== the new buffer is started)
    signals=Wait(SIGBREAKF_CTRL_C | (1L << AHImp->mp_SigBit));

    // Check for Ctrl-C and abort if pressed
    if(signals & SIGBREAKF_CTRL_C) {
    SetIoErr(ERROR_BREAK);
    break;
    }

    // Remove the reply and abort on error
    if(WaitIO((struct IORequest *) link)) {
    SetIoErr(ERROR_WRITE_PROTECTED);
    break;
    }
    }

    // Check for end-of-sound, and wait until it is finished before aborting
    if(length != BUFFERSIZE) {
    WaitIO((struct IORequest *) AHIios[0]);
    break;
    }

    link = AHIios[0];

    // Swap buffer and request pointers, and restart
    tmp = p1;
    p1 = p2;
    p2 = tmp;

    tmp = AHIios[0];
    AHIios[0] = AHIios[1];
    AHIios[1] = tmp;
    }

    // Abort any pending iorequests
    AbortIO((struct IORequest *) AHIios[0]);
    WaitIO((struct IORequest *) AHIios[0]);

    if(link) { // Only if the second request was started
    AbortIO((struct IORequest *) AHIios[1]);
    WaitIO((struct IORequest *) AHIios[1]);
    }

    if(IoErr()) {
    //PrintFault(IoErr(), argv[0] );
    clean(RETURN_ERROR);
    }

    clean(RETURN_OK);
    return 0; // Make compiler happy
    }

    void clean(LONG rc)
    {
    if(!AHIDevice)
    CloseDevice((struct IORequest *)AHIio);
    DeleteIORequest((struct IORequest *)AHIio);
    FreeMem(AHIiocopy,sizeof(struct AHIRequest));
    DeleteMsgPort(AHImp);
    //exit(rc);
    }

    /* __abox__ symbol is required or else the binary is loaded as PowerUP app */
    const int __abox__ __TEXTSECTION__ = 1;


    Crumb:?
    I will try to change cpu target and see if there are any differences in size, i didn't tried it.

    [ Edited by BalrogSoft on 2010/7/9 0:36 ]

    [ Edited by BalrogSoft on 2010/7/9 0:39 ]
    Balrog Software - AmigaSkool.net
    Mac Mini - MorphOS 3.8 - G4 1.5Ghz - Ati 9200 64 Mb
    Efika - MorphOS 3.6 - Ati 9200 64Mb - 80 Gb HD
    Amiga 1200D - OS 3.9 - Blizzard 603e/240mh
  • »08.07.10 - 21:34
    Profile Visit Website
  • MorphOS Developer
    Piru
    Posts: 588 from 2003/2/24
    From: finland, the l...
    "Use of any external static libs should be avoided."

    exit() falls into this category. Don't do it.

    The last thing you'd want is to bring in libc and the bloat included.

    [ Edited by Piru on 2010/7/9 2:46 ]
  • »08.07.10 - 22:45
    Profile
  • Order of the Butterfly
    Order of the Butterfly
    BalrogSoft
    Posts: 171 from 2006/10/6
    From: Spain
    Mmm... then there is something wrong on PlayTest.c, as i can understand exit command is executed on libauto.a on a function that use openlibrary (i don't remember well, i'm at work now). If this example makes use of OpenDevice to use AHI.device, why it's using libauto then? how to avoid it?
    Balrog Software - AmigaSkool.net
    Mac Mini - MorphOS 3.8 - G4 1.5Ghz - Ati 9200 64 Mb
    Efika - MorphOS 3.6 - Ati 9200 64Mb - 80 Gb HD
    Amiga 1200D - OS 3.9 - Blizzard 603e/240mh
  • »09.07.10 - 07:25
    Profile Visit Website
  • MorphOS Developer
    CISC
    Posts: 619 from 2005/8/27
    From: the land with ...
    Quote:

    If this example makes use of OpenDevice to use AHI.device, why it's using libauto then? how to avoid it?


    I'm guessing because it doesn't define (OpenLibrary()) DOSBase (SetIoErr())...


    - CISC
  • »09.07.10 - 09:44
    Profile
  • Priest of the Order of the Butterfly
    Priest of the Order of the Butterfly
    Tcheko
    Posts: 538 from 2003/2/25
    From: France
    Hi,

    Don't forget to use inline keyword where it is revelant to save some bytes.

    You can also get ride of the NULL test for OpenLibrary. Most system will have tinygl.library : it is a standard system component.

    If you are allowed to use external library, you should give a look at reggae. It can play from memory. See Library section on this site, there is some nice tutorials written by Reggae's author.
    Quelque soit le chemin que tu prendras dans la vie, sache que tu auras des ampoules aux pieds.
    -------
    I need to practice my Kung Fu.
  • »09.07.10 - 11:33
    Profile Visit Website
  • Order of the Butterfly
    Order of the Butterfly
    BalrogSoft
    Posts: 171 from 2006/10/6
    From: Spain
    Thanks to all. I will open dos.library manually and see if it solves the problem, but what really get me confused is that there aren't any DosBase undefined reference while compiling.
    Balrog Software - AmigaSkool.net
    Mac Mini - MorphOS 3.8 - G4 1.5Ghz - Ati 9200 64 Mb
    Efika - MorphOS 3.6 - Ati 9200 64Mb - 80 Gb HD
    Amiga 1200D - OS 3.9 - Blizzard 603e/240mh
  • »09.07.10 - 12:10
    Profile Visit Website
  • Order of the Butterfly
    Order of the Butterfly
    BalrogSoft
    Posts: 171 from 2006/10/6
    From: Spain
    I tried to open dos.library and store on a variable called DosBase, and it fails with the same error. I tried to remove any use of SetIOErr ad IoErr functions only to see if it was compiled, but i got same compilation error. This is the compilaiton output:

    Code:

    gcc -Os -s -ffast-math -fomit-frame-pointer -noixemul -nostartfiles -ISDK:tinygl-sdk/include -c -o play.o play.c
    play.c: In function 'entry':
    play.c:49: warning: assignment from incompatible pointer type
    play.c:83: warning: incompatible implicit declaration of built-in function 'sin'
    play.c:158: warning: initialization from incompatible pointer type
    gcc -Os -s -ffast-math -fomit-frame-pointer -noixemul -nostartfiles -ISDK:tinygl-sdk/include -o play play.o
    /bin/../lib/gcc-lib/ppc-morphos/4.4.4/../../../../ppc-morphos/lib/libnix/libauto.a(__openliberror.o): In function `__openliberror':
    __openliberror.o(.text+0xac): undefined reference to `exit'
    collect2: ld returned 1 exit status
    make: *** [play] Error 1
    Balrog Software - AmigaSkool.net
    Mac Mini - MorphOS 3.8 - G4 1.5Ghz - Ati 9200 64 Mb
    Efika - MorphOS 3.6 - Ati 9200 64Mb - 80 Gb HD
    Amiga 1200D - OS 3.9 - Blizzard 603e/240mh
  • »09.07.10 - 19:17
    Profile Visit Website
  • MorphOS Developer
    Henes
    Posts: 507 from 2003/6/14
    Inspect the map file to know which function caused libauto to be used.
    f.e. link using -Wl,-Map=foobar.map,--traditional-format
  • »09.07.10 - 20:26
    Profile Visit Website
  • Order of the Butterfly
    Order of the Butterfly
    BalrogSoft
    Posts: 171 from 2006/10/6
    From: Spain
    Thanks Henes, i added this parameters, it should create a map file? I can't see any new file. Anyway there was a SetIoErr that i didn't remove, now it compiles, i found that my definition of DOSBase was wrong, now it compiles with dos functions, but it doesn't work, Log server opens with a illegal instruction but thats is another problem.
    Balrog Software - AmigaSkool.net
    Mac Mini - MorphOS 3.8 - G4 1.5Ghz - Ati 9200 64 Mb
    Efika - MorphOS 3.6 - Ati 9200 64Mb - 80 Gb HD
    Amiga 1200D - OS 3.9 - Blizzard 603e/240mh
  • »09.07.10 - 21:17
    Profile Visit Website
  • MorphOS Developer
    Piru
    Posts: 588 from 2003/2/24
    From: finland, the l...
    You cannot just comment out the exit() calls, you must rewrite the code not to rely on them. Else you'll get double free problems.

    In fact, the whole code should just be rewritten to be simpler. Using SetIoErr() / IoErr() like that is quite bizarre IMHO.

    [ Edited by Piru on 2010/7/10 1:50 ]
  • »09.07.10 - 21:45
    Profile
  • Order of the Butterfly
    Order of the Butterfly
    BalrogSoft
    Posts: 171 from 2006/10/6
    From: Spain
    It was a try to see if the source could be compiled commented some function calls, anyway the main problem now is that ahi device isn't initialized properly, log server shows an illegal instruction.


    [ Edited by BalrogSoft on 2010/7/10 1:00 ]

    [ Edited by BalrogSoft on 2010/7/10 1:01 ]
    Balrog Software - AmigaSkool.net
    Mac Mini - MorphOS 3.8 - G4 1.5Ghz - Ati 9200 64 Mb
    Efika - MorphOS 3.6 - Ati 9200 64Mb - 80 Gb HD
    Amiga 1200D - OS 3.9 - Blizzard 603e/240mh
  • »09.07.10 - 21:49
    Profile Visit Website
  • MorphOS Developer
    Henes
    Posts: 507 from 2003/6/14
    Quote:


    BalrogSoft wrote:
    Thanks Henes, i added this parameters, it should create a map file? I can't see any new file.

    Code:

    Ram Disk:> echo >test.c "int main(void){return 0;}"
    Ram Disk:> ls
    Clipboards ENV T test.c
    Ram Disk:> gcc -noixemul test.c -Wl,-Map=foobar.map,--traditional-format
    Ram Disk:> ls
    Clipboards ENV T a.out foobar.map test.c

    The foobar.map file is there.
  • »10.07.10 - 10:05
    Profile Visit Website
  • Order of the Butterfly
    Order of the Butterfly
    BalrogSoft
    Posts: 171 from 2006/10/6
    From: Spain
    Thanks Henes for your explanation.

    I got AHI device working with nostartfiles option. Then i wrote AHI code to play a buffer with intro.c skeleton code, but it appears that display function isn't updated, after play the first buffer it stops. I added some code to initial intro source to update background color (without ahi initialization), but it doesn't change. Some suggestion?

    Code:

    #include <proto/exec.h>
    #include <proto/tinygl.h>

    #include <stdio.h>

    static void display(void);

    struct ExecBase *SysBase;
    struct Library *TinyGLBase;

    GLContext *__tglContext;

    static ULONG i;

    #define __TEXTSECTION__ __attribute__((section(".text")))

    int entry(void)
    {
    SysBase = *(struct ExecBase **) 4;

    TinyGLBase = OpenLibrary("tinygl.library", 50);

    if (TinyGLBase)
    {
    i=160;

    __tglContext = GLInit();
    if (__tglContext)
    {

    glutInit(NULL,NULL);

    glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);
    glutInitWindowSize(640, 480);
    glutFullScreen();
    glutCreateWindow(NULL);

    glClearColor(0.0f, 0.0f, 0.0f, 0.5f);
    glClearDepth(1.0f);
    glEnable(GL_DEPTH_TEST);
    glMatrixMode(GL_PROJECTION);
    gluPerspective(80, 640.0 / 480.0, 1.0, 5000.0);
    glMatrixMode(GL_MODELVIEW);

    glutDisplayFunc(display);

    glutMainLoop();

    GLClose(__tglContext);
    }

    CloseLibrary(TinyGLBase);
    }
    return 0;
    }

    static void display(void)
    {
    i++;

    glClearColor(((i&255)/255.0f), 0.0f, 0.0f, 0.5f);

    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    glutSwapBuffers();
    }

    /* __abox__ symbol is required or else the binary is loaded as PowerUP app */
    const int __abox__ __TEXTSECTION__ = 1;
    Balrog Software - AmigaSkool.net
    Mac Mini - MorphOS 3.8 - G4 1.5Ghz - Ati 9200 64 Mb
    Efika - MorphOS 3.6 - Ati 9200 64Mb - 80 Gb HD
    Amiga 1200D - OS 3.9 - Blizzard 603e/240mh
  • »17.07.10 - 21:44
    Profile Visit Website
  • Order of the Butterfly
    Order of the Butterfly
    BalrogSoft
    Posts: 171 from 2006/10/6
    From: Spain
    Problem solved, i had forgotten to register idle function. Now i have another problem, I have a Wait function for a signal from AHI device to swap audio buffers, i put a SetSignal(0, 0) just before Wait function, i need a loop, but it appears that Wait function call is really waiting for AHI device, i read somewhere that SetSignal(0, 0) was used to get a loop. How i can use Wait function to read signals only and not waiting?

    [ Edited by BalrogSoft on 2010/7/18 13:44 ]
    Balrog Software - AmigaSkool.net
    Mac Mini - MorphOS 3.8 - G4 1.5Ghz - Ati 9200 64 Mb
    Efika - MorphOS 3.6 - Ati 9200 64Mb - 80 Gb HD
    Amiga 1200D - OS 3.9 - Blizzard 603e/240mh
  • »18.07.10 - 10:42
    Profile Visit Website
  • Order of the Butterfly
    Order of the Butterfly
    BalrogSoft
    Posts: 171 from 2006/10/6
    From: Spain
    I got it working, I put a SIGBREAKF_CTRL_D signal just before Wait function, but while the buffers are swapped, it haves a little break, i don't know if i can modify the current playing buffer using only one buffer, this should work only if it's possible, if AHI can play this buffer looped and i can get the current position where buffer was playing, but my knowledge of AHI is limited. Anyway here is the code, using lzma it gives an exe of 1904 bytes:

    Code:

    #include <devices/ahi.h>

    #include <proto/exec.h>
    #include <proto/dos.h>
    #include <proto/tinygl.h>
    #include <proto/ahi.h>

    #include <stdio.h>

    #define FREQUENCY 8000
    #define TYPE AHIST_M8S
    #define BUFFERSIZE 20000

    static void display(void);

    struct ExecBase *SysBase;
    struct DosLibrary *DOSBase;
    struct Library *TinyGLBase;
    struct Library *AHIBase;

    GLContext *__tglContext;

    static struct MsgPort *AHImp = NULL;
    static struct AHIRequest *AHIios[2] = {NULL,NULL};
    static struct AHIRequest *AHIio = NULL;

    static APTR AHIiocopy = NULL;
    static BYTE AHIDevice = -1;

    static BYTE buffer1[BUFFERSIZE];
    static BYTE buffer2[BUFFERSIZE];
    static BYTE *p1=buffer1,*p2=buffer2;
    static void *tmp;
    static ULONG signals, length = BUFFERSIZE, i;
    static struct AHIRequest *link = NULL;
    static struct Task *self;

    #define __TEXTSECTION__ __attribute__((section(".text")))

    int entry(void)
    {
    SysBase = *(struct ExecBase **) 4;
    DOSBase = OpenLibrary("dos.library", 50);
    TinyGLBase = OpenLibrary("tinygl.library", 50);

    if (TinyGLBase)
    {

    self = FindTask(NULL);
    // Initialize AHI device

    AHImp=CreateMsgPort();
    if(AHImp != NULL)
    {
    AHIio=(struct AHIRequest *)CreateIORequest(AHImp,sizeof(struct AHIRequest));
    AHIio->ahir_Version = 4;
    AHIDevice=OpenDevice(AHINAME,0,(struct IORequest *)AHIio,0);
    }

    // Make a copy of the request (for double buffering)
    AHIiocopy = AllocMem(sizeof(struct AHIRequest), MEMF_ANY);

    CopyMem(AHIio, AHIiocopy, sizeof(struct AHIRequest));
    AHIios[0]=AHIio;
    AHIios[1]=AHIiocopy;
    SetIoErr(0);

    // Fill sound buffers
    for(i=0; i<BUFFERSIZE;i++) {
    p1[i] = (i<<1)&255;
    }
    for (i=BUFFERSIZE-1; i < (BUFFERSIZE<<1); i++) {
    p2[i-BUFFERSIZE] = (i<<1)&255;
    }

    i=160;

    __tglContext = GLInit();
    if (__tglContext)
    {

    glutInit(NULL,NULL);

    glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);
    glutInitWindowSize(640, 480);
    glutFullScreen();
    glutCreateWindow(NULL);

    glClearColor(0.0f, 0.0f, 0.0f, 0.5f);
    glClearDepth(1.0f);
    glEnable(GL_DEPTH_TEST);
    glMatrixMode(GL_PROJECTION);
    gluPerspective(80, 640.0 / 480.0, 1.0, 5000.0);
    glMatrixMode(GL_MODELVIEW);

    glutIdleFunc(display);

    glutMainLoop();

    GLClose(__tglContext);
    }

    // Abort any pending iorequests
    AbortIO((struct IORequest *) AHIios[0]);
    WaitIO((struct IORequest *) AHIios[0]);

    if(link) // Only if the second request was started
    {
    AbortIO((struct IORequest *) AHIios[1]);
    WaitIO((struct IORequest *) AHIios[1]);
    }

    CloseLibrary(DOSBase);

    CloseLibrary(TinyGLBase);
    }
    return 0;
    }

    static void display(void)
    {

    if(link)
    {
    //struct Message *ms = GetMsg(AHImp);
    Signal(self, SIGBREAKF_CTRL_D);

    // Wait until the last buffer is finished (== the new buffer is started)
    signals = Wait(SIGBREAKF_CTRL_D | (1L << AHImp->mp_SigBit));

    }

    if (signals & (1L << AHImp->mp_SigBit)) {
    // Swap buffer and request pointers, and restart
    tmp = p1;
    p1 = p2;
    p2 = tmp;

    tmp = AHIios[0];
    AHIios[0] = AHIios[1];
    AHIios[1] = tmp;
    }

    // Play buffer
    if (signals & (1L << AHImp->mp_SigBit) || !link)
    {
    length = BUFFERSIZE;
    AHIios[0]->ahir_Std.io_Message.mn_Node.ln_Pri = 8;
    AHIios[0]->ahir_Std.io_Command = CMD_WRITE;
    AHIios[0]->ahir_Std.io_Data = p1;
    AHIios[0]->ahir_Std.io_Length = length;
    AHIios[0]->ahir_Std.io_Offset = 0;
    AHIios[0]->ahir_Frequency = FREQUENCY;
    AHIios[0]->ahir_Type = TYPE;
    AHIios[0]->ahir_Volume = 0x10000; // Full volume
    AHIios[0]->ahir_Position = 0x8000; // Centered
    AHIios[0]->ahir_Link = link;
    SendIO((struct IORequest *) AHIios[0]);
    }

    link = AHIios[0];


    i++;

    glClearColor(0.0f, 0.0f, ((i&255)/255.0f), 0.5f);

    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    glutSwapBuffers();
    }

    /* __abox__ symbol is required or else the binary is loaded as PowerUP app */
    const int __abox__ __TEXTSECTION__ = 1;


    [ Edited by BalrogSoft on 2010/7/18 21:02 ]

    [ Edited by BalrogSoft on 2010/7/18 21:04 ]
    Balrog Software - AmigaSkool.net
    Mac Mini - MorphOS 3.8 - G4 1.5Ghz - Ati 9200 64 Mb
    Efika - MorphOS 3.6 - Ati 9200 64Mb - 80 Gb HD
    Amiga 1200D - OS 3.9 - Blizzard 603e/240mh
  • »18.07.10 - 18:01
    Profile Visit Website
  • Paladin of the Pegasos
    Paladin of the Pegasos
    Jupp3
    Posts: 1193 from 2003/2/24
    From: Helsinki, Finland
    Quote:

    gluPerspective(80, 640.0 / 480.0, 1.0, 5000.0);

    Don't know if it would help, but at least I'd avoid using glu (as in many cases, only thing it's used for is gluPerspective() anyway), it isn't really needed. There's the function glFrustum() that does almost same thing as gluPerspective().

    One way to replace gluPerspective() is to call it as you do, glGet() GL_PROJECTION matrix, add resulting matrix array to your code, and just glLoadMatrixf() it into the correct matrix stack. But I guess using glFrustum() might result in smaller binary size.

    Also, I probably wouldn't use glut either due to its limitations, don't know if it adds to binary size in your case.

    Also, don't forget to check OpenGL errors (and disable at least most checks after finishing, as tests take quite a lot of space, of course depending on how you do it)

    [ Edited by Jupp3 on 2010/7/19 13:53 ]
  • »19.07.10 - 09:51
    Profile Visit Website
  • Order of the Butterfly
    Order of the Butterfly
    BalrogSoft
    Posts: 171 from 2006/10/6
    From: Spain
    Thanks Jupp3, i will try to change some glut functions.

    I finally made it working, now sound doesn't break
    between swap buffers, here is the source code:

    Code:
    /*
    * 4Kb Intro startup by Pedro Gil (Balrog Soft)
    * www.amigaskool.net
    *
    * TinyGL and AHI device startup code.
    *
    * Special thanks to Piru for his small opts,
    * and Morphzone.org people!
    *
    */

    #include <devices/ahi.h>

    #include <proto/exec.h>
    #include <proto/dos.h>
    #include <proto/tinygl.h>
    #include <proto/ahi.h>

    #include <stdio.h>

    #define FREQUENCY 8000
    #define TYPE AHIST_M8S
    #define BUFFERSIZE 20000

    static void display(void);

    struct ExecBase *SysBase;
    struct DosLibrary *DOSBase;
    struct Library *TinyGLBase;
    struct Library *AHIBase;

    GLContext *__tglContext;

    static struct MsgPort *AHImp = NULL;
    static struct AHIRequest *AHIios[2] = {NULL,NULL};
    static struct AHIRequest *AHIio = NULL;

    static APTR AHIiocopy = NULL;
    static BYTE AHIDevice = -1;

    static BYTE buffer1[BUFFERSIZE], buffer2[BUFFERSIZE];
    static BYTE *p1=buffer1,*p2=buffer2;
    static void *tmp;
    static BOOL init = TRUE;
    static ULONG signals, i, n = 1;
    static struct AHIRequest *link = NULL;
    static struct Task *self;

    #define __TEXTSECTION__ __attribute__((section(".text")))

    int entry(void)
    {
    SysBase = *(struct ExecBase **) 4;
    DOSBase = OpenLibrary("dos.library", 50);
    TinyGLBase = OpenLibrary("tinygl.library", 50);

    if (TinyGLBase)
    {
    self = FindTask(NULL);

    // Initialize AHI device
    AHImp=CreateMsgPort();
    if(AHImp != NULL)
    {
    AHIio=(struct AHIRequest *)CreateIORequest(AHImp,sizeof(struct AHIRequest));
    AHIio->ahir_Version = 4;
    AHIDevice=OpenDevice(AHINAME,0,(struct IORequest *)AHIio,0);
    }

    // Make a copy of the request (for double buffering)
    AHIiocopy = AllocMem(sizeof(struct AHIRequest), MEMF_ANY);
    CopyMem(AHIio, AHIiocopy, sizeof(struct AHIRequest));
    AHIios[0]=AHIio;
    AHIios[1]=AHIiocopy;

    // Fill sound buffers
    for(i=0; i<BUFFERSIZE;i++) {
    p1[i] = (i*n)&255;
    if ((i & 1023) == 0) n ++;
    }
    for (i=BUFFERSIZE-1; i < (BUFFERSIZE<<1); i++) {
    p2[i-BUFFERSIZE] = (i*n)&255;
    if ((i & 1023) == 0) n --;
    }

    i=160;

    __tglContext = GLInit();
    if (__tglContext)
    {

    glutInit(NULL,NULL);

    glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);
    glutInitWindowSize(640, 480);
    glutFullScreen();
    glutCreateWindow(NULL);

    glClearColor(0.0f, 0.0f, 0.0f, 0.5f);
    glClearDepth(1.0f);
    glEnable(GL_DEPTH_TEST);
    glMatrixMode(GL_PROJECTION);
    gluPerspective(80, 640.0 / 480.0, 1.0, 5000.0);
    glMatrixMode(GL_MODELVIEW);

    glutIdleFunc(display);

    glutMainLoop();

    GLClose(__tglContext);
    }

    // Abort any pending iorequests
    AbortIO((struct IORequest *) AHIios[0]);
    WaitIO((struct IORequest *) AHIios[0]);

    if(link) // Only if the second request was started
    {
    AbortIO((struct IORequest *) AHIios[1]);
    WaitIO((struct IORequest *) AHIios[1]);
    }

    CloseLibrary(TinyGLBase);

    CloseLibrary(DOSBase);
    }
    return 0;
    }

    static void display(void)
    {
    // Play buffer
    if ((signals & (1L << AHImp->mp_SigBit) || init))
    {
    AHIios[0]->ahir_Std.io_Message.mn_Node.ln_Pri = 0;
    AHIios[0]->ahir_Std.io_Command = CMD_WRITE;
    AHIios[0]->ahir_Std.io_Data = p1;
    AHIios[0]->ahir_Std.io_Length = BUFFERSIZE;
    AHIios[0]->ahir_Std.io_Offset = 0;
    AHIios[0]->ahir_Frequency = FREQUENCY;
    AHIios[0]->ahir_Type = TYPE;
    AHIios[0]->ahir_Volume = 0x10000; // Full volume
    AHIios[0]->ahir_Position = 0x8000; // Centered
    AHIios[0]->ahir_Link = link;
    SendIO((struct IORequest *) AHIios[0]);

    if (init && link)
    init = FALSE;
    }

    if(link)
    {
    // Send a fake signal to not break the loop
    Signal(self, SIGBREAKF_CTRL_D);
    signals = Wait(SIGBREAKF_CTRL_D | (1L << AHImp->mp_SigBit));

    }

    link = AHIios[0];

    if ((signals & (1L << AHImp->mp_SigBit)) || init)
    {
    if (!init)
    WaitIO((struct IORequest *) AHIios[1]);
    // Swap buffer and request pointers, and restart
    tmp = p1;
    p1 = p2;
    p2 = tmp;

    tmp = AHIios[0];
    AHIios[0] = AHIios[1];
    AHIios[1] = tmp;
    }

    i++;

    glClearColor(0.0f, 0.0f, ((i&255)/255.0f), 0.5f);

    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    glutSwapBuffers();
    }

    /* __abox__ symbol is required or else the binary is loaded as PowerUP app */
    const int __abox__ __TEXTSECTION__ = 1;
    Balrog Software - AmigaSkool.net
    Mac Mini - MorphOS 3.8 - G4 1.5Ghz - Ati 9200 64 Mb
    Efika - MorphOS 3.6 - Ati 9200 64Mb - 80 Gb HD
    Amiga 1200D - OS 3.9 - Blizzard 603e/240mh
  • »22.07.10 - 20:43
    Profile Visit Website
  • Order of the Butterfly
    Order of the Butterfly
    Posts: 186 from 2003/10/23
    any news of the demo?
    I'm nerdy in the extreme
    And whiter than sour cream

    White&Nerdy 2006 Al Yankovic
  • »03.02.11 - 13:28
    Profile