andrei-markeev / ts2c-target-esp-idf

ESP-IDF target for TS2C transpiler
8 stars 1 forks source link

Do something similar with GBDK (gameboy SDK) #1

Closed Lingelo closed 3 years ago

Lingelo commented 3 years ago

Hi Andrei,

I did a small project that uses TS2C. This project allows you to transpile TS code and build a gameboy rom. If you are interested you can see it here: https://github.com/Freuhlon/gbts

First of all, I have a question for you:

I'm looking to do something similar with the GameBoy SDK. I would like to produce the following code:

#include <stdio.h>
#include <gb/gb.h>

void main(void) {
    printf("Press START!\n");
    waitpad(J_START);
    printf("> Good!");
}

Taking inspiration from the code in the example, I made the following code:

import { waitpad, J_START } from 'gb/esp_system.h';

console.log("Press START!\n");
waitpad(J_START);
console.log("> Good!");

Transpiled to:

#include <stdio.h>
int main(void) {
    printf("Press START!\n\n");
    /* Unsupported function call: waitpad(J_START) */;
    printf("> Good!\n");

    return 0;
}

I would like to know how you did to call the code of the headers in your typescript code.

Is there a way to call this code ( waitpad(J_START) ) from the headers? In other words, make the transpilator more permissive.

thanks & regards / Merci beaucoup

Lingelo commented 3 years ago

If there is an evolution to be made in your project, I can try to do it.

andrei-markeev commented 3 years ago

hey! You need to create headers similar to https://github.com/andrei-markeev/ts2c-target-esp-idf/tree/master/headers I cannot see these headers in your project.

andrei-markeev commented 3 years ago

So smth like

declare module "headers/gb/gb.h" {
    const J_START: number;
    function waitpad(button: number): void;
}

put this in a file headers/gb/gb.h/index.d.ts

and then

import { waitpad, J_START } from 'headers/gb/gb.h';

console.log("Press START!\n");
waitpad(J_START);
console.log("> Good!");

the IDE should actually see the declaration file, so providing all code completion and everything.

Lingelo commented 3 years ago

Thanks I will try. Headers come from the GameBoy C SDK : https://github.com/andreasjhkarlsson/gbdk-n/tree/master/include/gb

Lingelo commented 3 years ago

Hi,

I tried the solution here : https://github.com/Freuhlon/gb-projects/tree/master/hello-world .

I still have the same error that you can see in hello.c : / Unsupported function call: waitpad(J_START) /;

I also tested with the example in your project and I have the same result on the functions mapped in the modules.

Do you have any idea what's going wrong?

Thanks

andrei-markeev commented 3 years ago

I'll have a look

andrei-markeev commented 3 years ago

Hello! Sorry for the delay, I just got my hands to it.

You're absolutely correct, there seems to be a bug. I was doing a lot of stuff with functions, adding closures and stuff, so it seems I broke this external import functionality while doing that. It does work with older version of ts2c though.

I wanted to finish my current work before returning to bugs. That can take quite some time. Please use v2.2.2 in the meanwhile, i.e. npm i -g ts2c@2.2.2 and ts2c example.ts - I tested and this seems to work with that simple example you provided.

Thanks for reporting!

Lingelo commented 3 years ago

Hi Andrei,

Thank you for your answer. Version 2.2.2 seems to be incompatible with my initial request. This produces the following file :

#include <stdio.h>
int main(void) {
    /* importing other TS files is not yet supported: import {J_START, waitpad} from "headers/gb/gb.h"; */
    printf("Hello world\n");
    printf("Press START!\n");
    waitpad(J_START);
    printf("> Good!\n");

    return 0;
}

I need headers too.

I will wait for the next versions. FI : Versions 2.2.3, 2.2.4, 2.2.5 and 2.2.6 do not work with my file (these versions produce an error when transpiling).

andrei-markeev commented 3 years ago

This is very strange: image

andrei-markeev commented 3 years ago

actually let me publish the example that I hacked together, maybe it will help you

andrei-markeev commented 3 years ago

here you go: https://github.com/andrei-markeev/ts2c-target-gbdk-n

  1. clone locally
  2. cd ts2c-target-gbdk-n/examples
  3. npm i
  4. npm i -g ts2c@2.2.2
  5. ts2c hello-world.ts

this should work for sure!

Lingelo commented 3 years ago

Hi Andrei, Oh .... You are right! I was wrong about the global dependencies. Improper handling ...

Sorry.

Thanks for your work !

andrei-markeev commented 3 years ago

Np. I am very interested in practical applications of TS2C, obviously 😄

For now what I see in microcontrollers, types of variables are very important and TypeScript is usually not granular enough in this sense. This is why I had to use the /** @ctype ... */ syntax in the declaration - but even that is not always enough.

Check out thumby.ts for example, the generated thumby.c uses int16_t everywhere which might actually work in this particular case, because it is defined as char by default, but when you need more variance, or when you need to use e.g. unsigned values, it might not work anymore, depending on CPU architecture.

TS2C currently not working particularly well in these cases and definitely needs some improvement. And there's a lot of other work as well...

andrei-markeev commented 3 years ago

I had some time to dig deeper into that, and here's what I found:

  1. The module name must start with ts2c-target-, in this case, first part of module name is ignored, and other parts are used in #include. For example, import {abs} from "ts2c-target-test/stdlib.h"; will produce #include <stdlib.h>.
  2. The imported function must have strong definition, e.g. it must have all parameters types and return type. function waitpad(button) will not work, but function waitpad(button: number): number will.
  3. You must place the d.ts file where TypeScript can find it according to normal module resolution rules. For example, node_modules/ts2c-target-test/stdlib.h.d.ts.

Having these three conditions met, it will work also with latest version of ts2c (btw I published 2.2.9 recently).

I wonder, should I publish ts2c-target-gdbk-n to npm? Then you could simply npm i ts2c-target-gdbk-n and then import {waitpad} from "ts2c-target-gdbk-n/gb/gb.h"...

andrei-markeev commented 3 years ago

I will close this because it seems that it works as intended after all 😄

Lingelo commented 3 years ago

Thank you so much Andrei