Jump to content

  • Log In with Google      Sign In   
  • Create Account


Member Since 04 Feb 2008
Offline Last Active Today, 05:34 PM

#5283192 Trying to change speed of a platform

Posted by fastcall22 on 24 March 2016 - 12:13 PM

While there isn’t anything wrong with relative moving, you may want to have a reference point, such that you don’t accumulate floating point errors. Additionally, you try to understand the units in the math involved, rather than using magic numbers:
// Assuming the platform has these properties:
Float3  Start;
Float3  End;
Float   Duration; // seconds it takes for platform to cycle from start and end

// And:
Float3  Delta = End - Start;

// then:
// “phase” cycles between 0 and 1 over “Duration” seconds
phase = (1+sin(PlatformTime / Duration * 2*pi))/2;

// “PlatformLocation” cycles between “Start” and “End” according to “phase”
PlatformLocation = Start + Delta * phase;

PlatformTime += DeltaTime;

#5282959 How can I locate a memory leak?

Posted by fastcall22 on 23 March 2016 - 01:57 PM

To locate a memory leak, you would typically build your project where new/malloc and delete/free is rerouted to a routine that tracks all allocations and deallocations throughout your program. Note that this does not extend to third party libraries. At the end of the program, a report is generated with the allocations that remain. Something like the following:

// not $100% exact...
#define new DBG_NEW
#define DBG_NEW new (__FILE__, __LINE__)

struct alloc_entry {
    alloc_entry* prev;
    alloc_entry* next;
    const char* file;
    int line;
    size_t size;
    void* p;

alloc_entry* alloc_list = 0;

void* operator new( const char* file, int line, size_t sz ) {
    void* ptr = malloc(sz);

    simple_list::insert(alloc_list, alloc_entry{0, alloc_list, file, line, sz, ptr});

    return ptr;

void operator delete(void* p) {
    if ( p )
        simple_list::remove_where(alloc_list, p);

void alloc_report() {
    for ( alloc_entry* p = alloc_list; p; p = p->next )
        fprintf(stderr, "%s@%d %i bytes\n", p->file, p->line, p->size);

int main() {
    delete new int;
    new int;


Memory leaks are caused in many ways, but the most common cause is improper object lifetime management. Objects on the stack have a very strict FILO lifetime, and are guaranteed to be cleaned up when its scope expires. In contrast, objects allocated on the heap do not have a defined lifetime, and can be deallocated in any order. Here are a few examples:

void error(void* p) {
    throw std::runtime_error("Test failure!");

int main(int, char*[]) {
    try {
        foobar* f = new foobar;

        error( new int );

        delete f;
    } catch ( const std::exception& ex ) {
        // new int does not get deleted
        // foobar does not get deleted
To prevent memory leaks in the future, you must always keep in mind how long a dynamically allocated object is supposed to exist, who owns the object, who shares ownership with the object, and who is responsible for cleaning that object. Smart pointers help here, but aren’t absolutely necessary.

#5282782 Loading TMX files with SDL2 using Baylej's C library

Posted by fastcall22 on 22 March 2016 - 07:21 PM

bool TMXLoader::LoadMap(std::string location)
    tmx_map *map = tmx_load(location.c_str());
    return true;
Unless you are inspecting map on this line, the tmx_map is lost once this method returns.

#5281887 Why is the Fixed Function Pipeline performing better than using Vertex Buffer...

Posted by fastcall22 on 18 March 2016 - 11:36 AM

Eh? For 60 FPS, you have a budget of 16.67ms per frame. To go from 0.00733ms to 0.0177ms per frame is an increase from 0.044% to 0.106% of your total budget. While it’s a 2.5x increase, it’s still only < 0.1% of your total budget and is therefore not worth worrying about.

That aside, you are also making too many trips to the GPU. Rendering 1000 individual quads is many times more costly than making one individual call to draw 1000 quads. Also, the gameloop is missing from your code, if you’re having jittering, the gameloop is the next place I’d suspect.

To answer your question, “why is the Fixed Function Pipeline performing better than using Vertex Buffer Objects”: It is because you are doing it wrong.

#5280435 random Compiler Error C2143 - missing ";" before "*"

Posted by fastcall22 on 09 March 2016 - 04:47 PM

Visual Studio? You’ll need to configure your project to “Use Precompiled Headers”, and configure stdafx.cpp to “Create Precompiled Header”.

#5280038 Registry Entry Locator

Posted by fastcall22 on 07 March 2016 - 12:07 PM

Check the documentation for Microsoft.Win32.RegistryKey in mscorlib.dll, it has extensive details and examples on how to use it.

#5280029 For beginners

Posted by fastcall22 on 07 March 2016 - 11:22 AM

idk anything about allegro

Most libraries have tutorials to get you started, and reference documentation to show how things are done.

#5279851 Why rotation of 1.57 radian in x would face downwards?

Posted by fastcall22 on 06 March 2016 - 11:49 AM

Are your XYZ to yaw-pitch-roll correct? According to D3DXQuaternionRotationYawPitchRoll, yaw should be +Y, pitch should be +X, and roll should be +Z (or -Z, depending on LH or RH).

Since your model is facing +X, you might want to swap pitch and roll here.

#5277338 Vertex welding, preserve creases?

Posted by fastcall22 on 21 February 2016 - 04:04 PM

Is something like Beldner’s edge-split what you’re looking for? I believe the algorithm goes something like:

1. Iterate over all edges.
2. Check angle between the triangles sharing this edge.
3. If the angle is above a certain threshold, then crease this edge by creating new vertices with different normals.

#5277332 Managing game object IDs

Posted by fastcall22 on 21 February 2016 - 03:26 PM

Disclaimer: Haven’t actually implemented a serialization system.

Here’s what I’m thinking:
1. UUIDs to identify types.
2. Physical memory address for objects IDs, if appropriate, otherwise an integer handle.
3. Serialized data should contain a header.
4. Header should contain a list of UUIDs used in the file. Use indexes into this list rather than full UUIDs.
5. When using physical address as object IDs, collapse to a uint16_t.

#5276165 They called me crazy!

Posted by fastcall22 on 17 February 2016 - 12:57 PM

But does it support FILE_NOT_FOUND?

#5275858 Data linking varibles

Posted by fastcall22 on 15 February 2016 - 11:22 PM

It is arbitrary. However, the more I think about it, I think it should go toward the selected slider. Just a thought, though.

#5275789 Data linking varibles

Posted by fastcall22 on 15 February 2016 - 12:24 PM

For the list, L=(1, 50, 25, 24), and a selected index, idx=0:

1. Find the sum of the others: sum = 50 + 25 + 24 = 99. You may want to cache these ratios until idx changes.
2. After changing L[idx], find remaining amount: remaining = 100-L[idx]
3. Adjust other values according to their proportion, with rounding: (L[jdx]*remaining)/sum.
4. Add or remove 1 to one of the other sliders to correctly account for rounding corner cases, if the sum doesn’t match 100.

Here’s a quick test in powershell:
foreach ( $z in ((50,25,24), (25,25,25)) ) {
  foreach ( $y in (0,1,50,99,100) ) {
    $remaining = 100-$y;
    $total = $z | measure -sum | select -expand sum;
    $others = $z |% {
      [Math]::floor(($_*$remaining + $total/2)/$total);
    $all = ,$y + $others;
    $sum = $all | measure -sum | select -expand sum;

    $adj = 100-$sum;
    $all[1] += $adj;
    $sum += $adj;

    "sliders=$all sum=$sum"

sliders= ​ 0 ​ 51 ​ 25 ​ 24 sum=100
sliders= ​ 1 ​ 50 ​ 25 ​ 24 sum=100
sliders= 50 ​ 25 ​ 13 ​ 12 sum=100
sliders= 99 ​ ​ 1 ​ ​ 0 ​ ​ 0 sum=100
sliders=100 ​ ​ 0 ​ ​ 0 ​ ​ 0 sum=100

sliders= ​ 0 ​ 34 ​ 33 ​ 33 sum=100
sliders= ​ 1 ​ 33 ​ 33 ​ 33 sum=100
sliders= 50 ​ 16 ​ 17 ​ 17 sum=100
sliders= 99 ​ ​ 1 ​ ​ 0 ​ ​ 0 sum=100
sliders=100 ​ ​ 0 ​ ​ 0 ​ ​ 0 sum=100

#5275603 Using SQL for Templated Data

Posted by fastcall22 on 14 February 2016 - 02:56 AM

Sorry. I only partially answered the question. You may want to check to see if common table expressions are supported by your database engine. Some popular database engines are a bit behind the times in supporting modern SQL features (*cough* MySQL *cough*). In any case, assuming a schema:
create table `prefabs` (
    `id` int primary key not null auto_increment,
    `parent_id` int null,
    `name` varchar(50) not null

create table `prefab_properties` (
    `id` int primary key not null auto_increment,
    `prefab_id` int not null,
    `property_id` int not null,
    `value` varbinary(128) null

create table `properties` (
    `id` int primary key not null auto_increment,
    `name` varchar(100) not null,
    `type` varchar(10) not null /* int, string, color, float, and et. al. */
Then you could use CTEs to do something like:
1. Walk the inheritance tree. The CTE will build a set of all parents for every node.
2. Aggregate non-null properties for every node, and select the first property of that type.

with `tree` as ( /* set of all prefabs’ parents */
    select  p.id        `root_id`,
            p.id        `current_id`,
            p.parent_id `parent_id`,
            1           `level`
    from    prefabs p
    where   :has_prefab_ids is null
    or      p.id in :prefab_ids
    union all
    select  t.root_id,
            t.level + 1
    from    tree t
    join    prefabs p
    on      t.parent_id = p.id
), `tree_props` as ( /* join prefabs in `tree` with their non-null properties */
    select  t.*,
            pp.id `pp_id`
    from    tree `t`
    join    prefab_properties `pp`
    on      t.current_id = pp.prefab_id
    where   pp.value is not null
) select
    _1.root_id `prefab_id`,
    t.current_id `inherited_from`
from ( /* first encountered non-null properties of prefab */
    select  tp.root_id,
            min(tp.level) `min_level`
    from    tree_props `tp`
    group by
) _1
inner join /* rejoin tree_props to obtain property value */
    tree_props `tp`
on  _1.root_id = tp.root_id
and _1.property_id = tp.property_id
and _1.min_level = tp.level
inner join
    prefab_properties pp
on  tp.pp_id = pp.id
Of course, a sane person might consider calculating effective properties in software, rather than rely on a database to do it for them. smile.png

#5275596 Using SQL for Templated Data

Posted by fastcall22 on 13 February 2016 - 09:13 PM

This is usually done with the coalescing function:
with `objects` (`id`,`parent_id`,`name`,`type`,`value`) as ( values
    ( 1, null, 'fruit',     'F', -5 ),
    ( 2, null, 'vegetable', 'B',  7 ),
    ( 3, 1,    'apple',     null, 100 ),
    ( 4, 2,    'carrot',    'X',  null )
) select
    coalesce(child.name, parent.name) `name`,
    coalesce(child.type, parent.type) `type`,
    coalesce(child.value, parent.value) `value`
    `objects` child
left outer join
    `objects` parent
on  child.parent_id = parent.id
This might be incorrect (modern) SQL syntax, but it should get the point across.