/* main.c */
asm(
    ".code16gcc\n"
    "call main\n"
    "call exit\n"
);
#include <gui.h>
#include <assembly.h>
#include <shapes.h>
#include <bmp.h>
#include <omnistd.h>

void *heaptr, *heapsaved;
extern boolean videoinit;
extern rgb **globalcolors;

void main() {
    main2();
}

/*
void argtest(int8 *smtn, ...) {
    int8 **p;
    int8 n;

    p = &smtn;
    for (n=0; n<16; n++) {
        // argc = 0;
        // offset = (argc*4);
        // offset = $2 n;
        // p = $1 (&smtn+offset);

        print($1 *p++);
        print($1 "\r\n");
    }

    return;
}
*/

void main1() {
    bitmap *bm;
    int8 *show;

    // videoinit = false;
    freeall();
    // videomode(x640x480x16);

    bm = parsebmp($1 "penguin", 5, 5);
    if (!bm) {
        printf("%s\n", $1 "error parsebmp()");
        freeall();

        return;
    }
    show = showbitmap(bm);
    if (!show)
        printf("%s\n", $1 "error showbitmap()");
    else
        printf("%s", show);
    // drawbmp(bm);
    getchar();
    freeall();

    return;
}

void main2() {
    bitmap *bm;
    int8 *show;

    videoinit = false;
    globalcolors = (rgb **)0;

    freeall();
    videomode(x640x480x16);
    globalcolors = setpalettes();
    if (!globalcolors)
        return;

    bm = parsebmp($1 "penguin", 5, 5);
    if (!bm) {
        printf("%s\n", $1 "error parsebmp()");
        freeall();

        return;
    }
    // show = showbitmap(bm);
    // if (!show)
    //     printf("%s\n", $1 "error showbitmap()");
    // else
    //     printf("%s", show);
    drawbmp(bm);
    getchar();
    freeall();

    return;
}

/*
void main() {
    bitmap *bm;
    // boolean ret;

    videoinit = false;
    freeall();
    videomode(x640x480x16);

    bm = parsebmp($1 "penguin", 5, 5);
    if (!bm) {
        videomode(x40x25xT);
        print($1 "error\r\n");
        freeall();

        return;
    }
    drawbmp(bm);
    // videomode(x40x25xT);
    // if (ret)
    //     print($1 "true\r\n");
    // else
    //     print($1 "false\r\n");

    getchar();
    freeall();

    return;
}
*/

int8 getchar(void) {
    int8 al, ah, ax;
    int8 ret;

    ax = xgetchar();
    al = (ax & 0xf);
    ah = ((ax & 0xf0) >> 4);
    
    ret = (al) ?
            al :
        ah;
    
    return ret;
}

void putchar(int8 c) {
    xputchar(c);

    return;
}

void print(int8 *str) {
    int8 *p;

    for (p=str; *p; p++)
        putchar(*p);

    return;
}

void *alloc(int16 size) {
    void *p;
    int16 newsize;

    if (!size)
        return $v 0;

    newsize = ((heaptr-heap1)+size);
    if (newsize > heapsz)
        return $v 0;

    p = heaptr;
    heaptr += size;

    return p;
}

void freeall() {
    heaptr = heap1;

    return;
}

void save() {
    heapsaved = heaptr;

    return;
}

void load() {
    heaptr = heapsaved;

    return;
}

int16 open(int8 *file, int16 offset) {
    int16 fd, ret;
    signed short int n;

    n = xopen(file);
    if (n < 0)
        printf("xopen() error code: 0x%x\n", $2 -n);
    else
        fd = $2 n;
    
    if (offset) {
        ret = xmove(fd, offset);
        if (!ret) {
            close(fd);
            return 0;
        }
    }

    return fd;
}

int8 read(int16 fd) {
    int16 n;
    int8 ah, al;

    n = xread(fd);
    al = (n & 0xff);
    ah = ((n & 0xff00) >> 8);
    if (ah) {
        printf("xread() error code = 0x%x\n", $2 al);
        return (int8)0;
    }
    else
        return al;
}

void close(int16 fd) {
    xclose(fd);
}
