News:

Herr Otto Partz says you're all nothing but pipsqueaks!

Main Menu

Restunts repository - Git mirror

Started by dreadnaut, March 19, 2021, 12:00:36 AM

Previous topic - Next topic

llm

#150
cleanuped version of the math.h usage with some tests

#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#define _USE_MATH_DEFINES
#include <math.h>
#include "stunts_math.hpp"

namespace math_h_test
{
#define SCALE_BITS 14
#define SCALE (1 << SCALE_BITS)

// 0x400 steps = 2Pi
#define ANGLE_TO_RAD(a) ((a) * (M_PI / 512.0))
#define RAD_TO_ANGLE(r) ((r) * (512.0 / M_PI))

#define TO_FIXED(x)   ((int16_t)lround((x) * SCALE))
#define FROM_FIXED(x) ((double)(x) / SCALE)

    int16_t int_sin_math(uint16_t angle)
    {
        return TO_FIXED(sin(ANGLE_TO_RAD(angle)));
    }

    int16_t int_cos_math(uint16_t angle)
    {
        return TO_FIXED(cos(ANGLE_TO_RAD(angle)));
    }

    int16_t int_atan2_math(int16_t x, int16_t y)
    {
        double ang = atan2((double)x, (double)y);
        return (int16_t)lround(RAD_TO_ANGLE(ang));
    }

    int16_t int_hypot_math(int16_t x, int16_t y)
    {
        return TO_FIXED(hypot(FROM_FIXED(x), FROM_FIXED(y)));
    }

    int16_t int_hypot_3d_math(const VECTOR* v)
    {
        double dx = FROM_FIXED(v->x);
        double dy = FROM_FIXED(v->y);
        double dz = FROM_FIXED(v->z);
        return TO_FIXED(sqrt(dx * dx + dy * dy + dz * dz));
    }

    void test_sin_cos(void)
    {
        printf("=== SIN/COS compare ===\n");
        int max_diff_sin = 0, max_diff_cos = 0;

        for (int a = -0x400; a <= 0x400; ++a) {
            int16_t ref_sin = int_sin((uint16_t)a);
            int16_t ref_cos = int_cos((uint16_t)a);
            int16_t new_sin = int_sin_math((uint16_t)a);
            int16_t new_cos = int_cos_math((uint16_t)a);

            int diff_sin = abs(ref_sin - new_sin);
            assert(diff_sin == 0);

            int diff_cos = abs(ref_cos - new_cos);
            assert(diff_cos == 0);
        }
    }

    void test_atan2(void)
    {
        printf("=== ATAN2 Compare ===\n");
        int max_diff = 0;

        for (int y = -0x400; y <= 0x400; y += 64) {
            for (int x = -0x400; x <= 0x400; x += 64) {
                int16_t ref = int_atan2(x, y);
                int16_t newv = int_atan2_math(x, y);
                int diff = abs(ref - newv);

                assert(diff <= 1);
            }
        }
    }

    void test_hypot(void)
    {
        printf("=== HYPOT Compare ===\n");
        int max_diff = 0;

        for (int y = -0x400; y <= 0x400; y += 64) {
            for (int x = -0x400; x <= 0x400; x += 64) {
                int16_t ref = int_hypot(x, y);
                int16_t newv = int_hypot_math(x, y);
                int diff = abs(ref - newv);

                assert(diff <= 3);

                if (diff > 1)
                    printf("hypot(%4d,%4d): ref=%5d new=%5d diff=%3d\n",
                        x, y, ref, newv, diff);
            }
        }
    }

    void test_hypot3d(void)
    {
        printf("=== HYPOT_3D Compare ===\n");
        int max_diff = 0;
        VECTOR v;

        for (int z = -0x200; z <= 0x200; z += 64)
            for (int y = -0x200; y <= 0x200; y += 64)
                for (int x = -0x200; x <= 0x200; x += 64) {
                    v.x = x; v.y = y; v.z = z;
                    int16_t ref = int_hypot_3d(&v);
                    int16_t newv = int_hypot_3d_math(&v);
                    int diff = abs(ref - newv);

                    assert(diff <= 4);

                    if (diff > 1)
                        printf("hypot3d(%4d,%4d,%4d): ref=%5d new=%5d diff=%3d\n",
                            x, y, z, ref, newv, diff);
                }
    }

    int main(void)
    {
        test_sin_cos();
        test_atan2();
        test_hypot();
        test_hypot3d();
        return 0;
    }
}

llm

and wouldn't be a if-less vec_transform not faster?

or is failed branch prediction not a problem with older CPUs and multiply is much slower

    void vec_transform(const VECTOR* src, const MATRIX* mat, VECTOR* dst)
    {
        dst->x = ((int32_t)mat->m11 * src->x + (int32_t)mat->m12 * src->y + (int32_t)mat->m13 * src->z) >> SCALE_BITS;
        dst->y = ((int32_t)mat->m21 * src->x + (int32_t)mat->m22 * src->y + (int32_t)mat->m23 * src->z) >> SCALE_BITS;
        dst->z = ((int32_t)mat->m31 * src->x + (int32_t)mat->m32 * src->y + (int32_t)mat->m33 * src->z) >> SCALE_BITS;
    }

Cas

Hey!  As you guys know, I'm travelling. Soon will be back. Just wanted to clarify about my opinions on SDL. I do think SDL is a very good tool and I don't mean to say at all that programming for SDL is in any way easier than programming on a library that's built into the compiler. I just find that SDL is in itself like a language and programming for it in C is a very different experience from just making a C program (or C++). On the other hand, what I try to achieve with my programs is some portability (through time, more than from platform to platform, but both are good). I have not been very successful on that in GNU/Linux and I keep trying to improve that. SDL does not solve this. It solves other things. Still, I've been interesting in trying it many times, but well, I'd like to solve my portability problem first of all. So far, the only solution appears to be to program for DOS :P
Earth is my country. Science is my religion.

llm

#153
QuoteI just find that SDL is in itself like a language and programming for it in C is a very different experience from just making a C program (or C++).

name a third-party library (with non trivial api and multi-domain and multi-platform) for C that does not give you these vibes :)

as soon as you would try to write a multi-platform wrapper (capable as SDL2-3) around input,output,sound,etc. you would see that the SDL api is really small for what its helping/keeping from you - you're just not used to it - thats all


Matei

Quote from: Cas on November 09, 2025, 07:24:57 AMprogramming for it in C is a very different experience from just making a C program

I didn't understand. Any explanation? What I do know is that programming in BASIC is a very different experience from programming in BASIC:

https://matei.one/games.html#emu

Quotealthough almost all home computers came with BASIC interpreters, they were also different, so a program written in BASIC for one computer would generally not function without modifications on another computer.

Next:

Quotewhat I try to achieve with my programs is some portability (through time, more than from platform to platform, but both are good). [...] SDL does not solve this.

Yes it does. All you have to do is make your graphical and sound functions work with all 3 versions of SDL, which is what I did.

https://sourceforge.net/projects/simple3d/

https://forum.stunts.hu/index.php?topic=4520

Cas

Quote from: llm on November 11, 2025, 10:13:14 AMas soon as you would try to write a multi-platform wrapper (capable as SDL2-3) around input,output,sound,etc. you would see that the SDL api is really small for what its helping/keeping from you - you're just not used to it - thats all

It may seem so because we now see everyday programs taking up hundreds or megabytes or gigabytes, but really, it's huge. Take the most complicated game from the 90s, strip out data (animations, graphics, audio) and you'll see the code is rarely more than a megabyte. SDL is a layer on top of a layer, on top of a layer and so on. The degree of dependency and lack of knowledge of how the code works is extremely high. No person that worked on it understands all the code and nobody making programs for it does either. Besides, if you only need to load a PNG file and then save it, you depend on code that can also process compressed audio, for example. It's like carrying the computer with your program.

Quote from: Matei on November 11, 2025, 10:25:30 PMYes it does. All you have to do is make your graphical and sound functions work with all 3 versions of SDL, which is what I did.
Which brings me to this. If you send somebody a letter in a random language and you accompany it with a guy who speaks a hundred languages including it, you could say the letter is written in a lingua franca, but that's not true. It's the translator that makes it seem so. And of course, you can send the letter in an envelope, while carrying the guy overseas may require a seat on a plane or a room in a ship. But SDL not only does this, it also doesn't even provide the translator guy: it just tells you that translator exists and you have to find it and bring it home yourself, ha, ha.

---
I realise all this may not matter to many people. Some of us may be very picky with their food, but can sleep anywhere, while others can eat rubbish, but then need a comfy mattress. I like clean, logical, comprehensive code... I don't like using black boxes. I feel the need to have full control and know what I'm doing. Not having that is uncomfortable to me and even very boring, because seeing the inside mechanisms of things is what has attracted me to many things I'm passionate about, including programming.
Earth is my country. Science is my religion.

Matei

Quote from: Cas on Yesterday at 11:13:40 PMIt may seem so because we now see everyday programs taking up hundreds or megabytes or gigabytes,

Try my game:

https://matei.one/idxscr.html#download

QuoteBesides, if you only need to load a PNG file and then save it, you depend on code that can also process compressed audio, for example. It's like carrying the computer with your program.

Not with my functions, which draw graphics and save BMP files only with the standard C library. I didn't need to read BMP files until now though, but I could do that.

QuoteWhich brings me to this. If you send somebody a letter in a random language

That's the C language, it's not random, and "somebody" is the hardware to which you send it, which also has who knows what drivers and other programs on it.

Quoteand you accompany it with a guy who speaks a hundred languages including it,

That's SDL and it will translate your letter to anyone to whom you sent it. The idea is that you don't know who you send it to, but SDL will translate it to anyone. No DOS though.

https://matei.one/idxchess.html

Quotebut the version for DOS/DOSBox, which is available below, uses some graphical functions available with Open Watcom, as SDL has no support for DOS.

Quote from: CasBut SDL not only does this, it also doesn't even provide the translator guy:

As mentioned, SDL is the translator.