[Tool]FemtoIDE

I’d love to hear some loud explosions too. Music would be a problem, but I think I can take a look at sound effects now.

5 Likes

Excellent!

I got some bytebeat playing, the API looks like this:

        Mixer.init(8000);
        Mixer.setChannel(0, new Procedural(){
            byte update(){
                return (t>>4) | (t>>5) | t++;
            }
        });

Now I have to make support for converting short samples into classes so we can do this:

import sounds.Explosion; // mp3 or wav converted by the compiler
Mixer.setChannel(0, new Explosion());

It supports up to 4 channels so you can have different effects mixed together.

3 Likes

I wonder if archive ever gets into legal issues…

That wouldn’t be too bad.
Making the actual conversion tools might be fiddly though,
it depends what Java decompilers are available.
If there’s a decent command line tool out there then it shouldn’t be too bad.

I’ve also included the modified DoxygenLayout.xml as per @Hanski’s request.

I’ll leave the actual Doxygen generation and page setup to you in case you wish to modify the output somehow (e.g. adding a custom CSS file to change the font and colour palette).

Also it makes more sense for you to host the documentation than for me to do so.

I’d like to point out that Doxygen provides the option to document bugs and todo items and will generate bug lists and todo lists from them, so those features might come in handy.

I’m slightly confused then.
The statement was:

I also think that because drawing commands are under the “mode” tree they are hard to find at first by browsing the class list. Maybe “Graphics” would be better?

And the only place mode appears is in the class list,
which has a 1:1 correspondance with the package hierarchy.

I believe it is possible to create separate group headings if that was the intented meaning, but I’d need to do more digging and try it out to confirm how to do it.

1 Like

A general question for everyone:

  • Would it be useful if I were to write a simplified guide to using Doxygen for documentating and/or generating the documentation?

Specific questions for @FManga:

Is there a guideline for which functions of the ME API you’re intending to have implemented?

If so I could contribute a few Java-side implementations every now and again.
E.g. Math.toDegrees, max(long a, long b) currently aren’t implemented,
and parts of Boolean don’t seem too difficult to implement.

Purely out of interest:

  • What format are the .font files in?
  • Do >> and >>> currently behave as they’re supposed to or do they both have the same behaviour?
1 Like

I forgot the name, but I tested a command line decompiler that was pretty mature. The idea is to maybe make a template project that includes the decompiler and a script that calls it.
Shouldn’t be too fiddly, once enough of the library has been implemented.

Thanks! Merged it.

Maybe I’m reading too much into the capital G, but I understood it as: “finding drawing commands by browsing the class list is hard, it would be better to have a list of Graphics commands”.

Not really. I’m implementing things on an as-needed basis, not systematically.
Feel free to contribute whichever implementations you want, they’re all welcome.

They’re the same fonts from the PokittoLib, in binary. The IDE/compiler doesn’t actually know anything about font files. If you import a file with an unknown format, it just makes a simple wrapper along the lines of:

class filename {
  public:
  static pointer fileextension(){
    static const uint8_t d[] = {
     filedata
    }
    return d;
  }
};

>> is mapped directly to C++'s >>, which should be the expected behaviour.
>>> casts the left-hand operand to uint32_t before shifting.
This smells worse than python’s integer division.

1 Like

Which means you’ll probably need to decompile a good handful to build up a list of things that would need to be implemented (unless you know for definite that they’re all using a particular API version).

I’ll wait until @Hanski clarifies what he meant before speculating anymore.

Either complaint has a solution (or two).

Noted.
If I get bored then I might just implement a bunch to say I’ve contributed something.

Ok, that makes sense.

That’s kind of odd.

Also is that C++ or Java? Spotted the edit.

If it’s C++ then you might want to be careful with static variables in functions,
technically they don’t have to be initialised until the first invocation of the function they’re declared in,
so you may want to double check what the compiler is doing.

I would assume and hope that it sees static const, puts the array into ROM and thus the function just ends up just returning a constant pointer value, but it might not.

Ok, that’s sort of what I was expecting.

If you ever have to port this to another platform, double-check the first one.
Up until C++20 it’s undefined behaviour for negative values.
When C++20 arrives >> will finally be standardised as ‘arithmetic right shift’. (And it only took 22 years! :P)

Having separate >> and >>> operators or the implementation?

If you mean the former then yes, but it only exists because Java doesn’t have native unsigned numbers, which frankly is probably the greater sin here. :P

1 Like

Whatever makes the graphics method easier to find. If the package name is not changed then the group heading could be changed.

Importing binary files or the implementation?

When I was implementing this, I had the same doubt and checked. It’s OK. :slight_smile:

Funny how the behaviour of an operator is undefined for more than half of its possible inputs. -_-
On platforms where >> isn’t an arithmetic right shift (are there any?) the required work around would be terrible.

Yes, the lack of unsigned and the consequential hacks.

I’d prefer not to break everyone’s entries mid-compo. :stuck_out_tongue:

1 Like

Like this?


Both, sort of.

It makes sense that you’d have to get the data in there somehow,
but I would have expected the IDE to generate a .java file somewhere with the data embedded into it, readable as Java code,
and for the interface (and possibly the management from the UI) to be something more like C#'s Properties.Resources (video demonstrating C#'s resources feature here).
(Disclaimer: still haven’t tried the IDE, I’m the kind of boring person who finds the API and documentation more interesting. :P)

Apparently the closest thing Java has to Properties.Resources is probably ClassLoader's InputStream getResourceAsStream(String name), which isn’t quite as useful because it’s obviously getting the resource at runtime rather than compile time and as a stream rather than giving direct access to the data.

Ah, that’s ok then.

Make a note somewhere in case anyone ever tries to port it though.

I know there are platforms where CHAR_BIT isn’t 8.
E.g. some older CPUs would have been 10, and in the current era there exist some DSPs that have a 16-bit char.
But I don’t know about right shift, I’d have to check that.

I have no way of testing this, but theoretically:

template <typename T>
constexpr T arithmeticRightShift(T value, unsigned int shiftAmount)
{
	static_assert(std::numeric_limits<T>::is_integer, "Attempt to do right shift on non-integer");
	return (!std::numeric_limits<T>::is_signed || (value >= 0))
		? (value >> shiftAmount)
		: ((value >> shiftAmount) | (0x01 << std::numeric_limits<T>::digits));
}

Lack of unsigned numbers is one of the big reasons I stayed clear of Java after college.
Some people think signed integers should be the default and unsigned integers should be used either when necessary or never.
I mostly think unsigned integers should be the default and signed integers should be the opt-in for when you actually need negative numbers.

Java doesn’t have const arrays, so there’s no way to put data in flash.
Instead, the compiler (not the IDE) does all the necessary conversions itself.

This can’t be right… if you shift right two bits, you need to add two 1’s.
Edit: don’t worry about this though, if anyone ever tries to port this code to the ENIAC they’ll have bigger problems. :stuck_out_tongue:

Looks good!

Right, that is not nice :wink:

1 Like

I really miss const when using other languages,
it’s surprising more languages don’t have it.

final could possibly work for Java, but admittedly an actual array couldn’t.

Using another class could possibly work though.
For example having some sort of ImageResource class with a getWidth(), getHeight(), getPixel(x, y) and getPointer() might make sense for images at least.

For general data it puts me in mind of the C# Marshal API (which I presume Java has an equivalent of, but I don’t know what it would be).

Oops. Clearly I’m half-asleep, for some reason I thought only the sign bit needed to be filled.

This should be right:

template <typename T>
constexpr T arithmeticRightShift(T value, unsigned int shiftAmount)
{
	static_assert(std::numeric_limits<T>::is_integer, "Attempt to do right shift on non-integer");
	return (!std::numeric_limits<T>::is_signed || (value >= 0))
		? (value >> shiftAmount)
		: ((value >> shiftAmount) | (static_cast<T>(~0ull) << ((std::numeric_limits<T>::digits + 1) - shiftAmount)));
}

Actually, now I think about it, I’ve written sign-extending code before when implementing a 24-bit number type for use in bytecode.

Naturally I’d prefer Colossus. :P


I think something went wrong with your quoting there. :P

Is there anything else that would need to be added to the Graphics ‘module’?
If not I can make a PR to add the Graphics group/module.

1 Like

I am often writing on the phone so expect typos and mis-quotings :wink:

Typos I can understand, but being able to quote something from one comment and attribute it to another sounds like a bug to me. :P


In addition to this question (for whomever wants to answer it), I have another question, (probably for @FManga mainly, but it affects anyone who wishes to help the documentation effort):

There are two options for providing the Graphics module.
The first option is to have:

/// @addtogroup Graphics
/// @{
public class ScreenMode {
// blah blah blah
}
/// @}

The other option is to merely have:

/// @ingroup Graphics
public class ScreenMode {
// blah blah blah
}

But also require a .dox file containing:

/// @defgroup Graphics
/// You can add a detailed description here.
///

(The last line consisting of a /// and nothing else is seemingly important.)

The latter makes it slightly easier to add something to a new group (you don’t need to scroll down to the bottom of the page), but requires that the .dox file end up somewhere where it’s going to be recognised.
Naming isn’t too much of an issue, it can simply be called Groups.dox.

Of course, another alternative is to simply create a Graphics.md file that links to the correct pages and is maintained separately.


And lastly, a question specifically for @FManga:

Do the classes implemented in JavaScript (e.g. Object.js, String.js) have to be in .js files, or would they also work as .java files?

It’s a lot easier to document them if they’re .java files.

Sounds like this is more in-line with what we’re going to use for the examples, so I’d prefer it.

They’d work as java files, though the references to them in vfs.js will need to be updated.

1 Like

I’ll put something together later, I’m doing some other stuff first.

Presumably that means changing:

String:{ src:require("./java/lang/String.js") },

to

String:read("/java/lang/String.java", "utf-8"),

or is there more to it?

Not that I’ll be attempting that just yet either.
I’ve been fleshing out Math.java a bit first.

Speaking of which, uc_float is definitely a fixed point right?
I wanted to check because I saw typedef float uc_float in begin.cpp.


By the way, technically begin.cpp violates 17.4.3.1.2 [lib.global.names] C++03:

  • Each name that contains a double underscore (__) or begins with an underscore followed by an uppercase letter (2.11) is reserved to the implementation for any use.
  • Each name that begins with an underscore is reserved to the implementation for use as a name in the global namespace.

And also <cstdint> doesn’t guarantee that uint32_t et cetera are declared in the global namespace, it only guarantees them in the std:: namespace.

Something (or things) to bear in mind for the future.

That should be all there is to it.

Are you in the right begin.cpp? The relevant one is in the pokitto folder, not the desktop one.
Desktop uses float, Pokitto uses typedef FixedPoints::SFixed<23, 8> uc_float;

Yeah, the idea was to avoid having hidden internals clashing with user code.


4 Likes

Ah, that makes sense.

Mostly. Kind of confusing that the desktop version is separate and using float instead, fixed points should still work on desktop.

That’s what namespaces are supposed to be for.
Stuff everything in a namespace, say “this namespace is out of bounds” and then hope nobody will do anything silly.


While I was digging in begin.cpp I noticed two things.

Firstly you’re using ptr(nullptr) in all the constructors when simple doing ptr = nullptr; where ptr is declared should suffices.

Secondly:

template<typename OT>
__ref__(const __ref__<OT>&&o):ptr(nullptr){
	ptr = o.ptr;
	ptr->__hold__();
}

Could be simplified to:

template<typename OT>
__ref__(const __ref__<OT> && o) : ptr(o.ptr) {
	ptr->__hold__();
}

Which would eliminate the unnecessary nullptr assignment (even for the ptr = nullptr; at declaration variant).
The same optimisation could be applied to __ref__(__ref__<OT>&&o).
(The compiler probably optimises the assignment away anyway, but it’s good practice nonetheless.)

Also if you want to make it a requirement for T in __ref__ to be uc_Object then it’s possible to enforce that requirement with ether a bit of static_assert and <type_traits> or, in a more flexible way, enforce it with SFINAE on the specific functions that need to call __hold__.
You may not care because it’s supposed to be an internal use API, but the option is there if you decide you ever need it.


I’ve implemented some stuff that everybody knows but nobody ever uses: