Jump to content

  • Log In with Google      Sign In   
  • Create Account

Bismuth

Member Since 28 Jun 2009
Offline Last Active Dec 11 2012 07:36 AM

Topics I've Started

Copy array with variable remap

11 December 2012 - 07:11 AM

Hello.
Is there an algorithm or a function to remap an array in C to another array with a constant maping? I.e. I have an array of bytes (uint8_t) with 4 elements, and I would like to copy the values from this array to another array with a "static remap".

uint8_t array_in[4];
uint8_t array_out[4];
void array_remap(uint8_t map, uint8_t * array_in, uint8_t * array_out) {
...
}

The function also takes a map parameter. This means that every time the function is called it has to remap the variables in the same order, provided that the map parameter is identical. Basically it acts like a seed number for the random remapper. Here's how the remap is supposed to take place according to the seed number. The remap table doesn't have to be exactly as displayed, but it should offer all 24 possibilities (4 elements mean 4! = 24 total combinations).

0x00: abcd -> abcd
0x01: abcd -> abdc
0x02: abcd -> acbd
0x03: abcd -> acdb
0x04: abcd -> adbc
0x05: abcd -> adcb
0x06: abcd -> bacd
0x07: abcd -> badc
0x08: abcd -> bcad
0x09: abcd -> bcda
0x0A: abcd -> bdac
0x0B: abcd -> bdca
0x0C: abcd -> cabd
0x0D: abcd -> cadb
0x0E: abcd -> cbad
0x0F: abcd -> cbda
0x10: abcd -> cdab
0x11: abcd -> cdba
0x12: abcd -> dabc
0x13: abcd -> dacb
0x14: abcd -> dbac
0x15: abcd -> dbca
0x16: abcd -> dcab
0x17: abcd -> dcba


I could write the function by using a 4x4=16 bit field inside an uint16_t function parameter, but I'm trying to reduce the parameter size to a simple index number (8 bits). Could the map parameter be somehow reduced to fit inside a byte (8 bits)?
Any ideas?

Integer multiplication, division

09 October 2012 - 01:37 PM

int16_t a = -255;
int16_t b = 409;
int16_t c = 1000;
int16_t result = a * b / c;

result: 26
expected: -104

What the heck is going on here?

[C/C++] Coding style dilemma

11 July 2011 - 12:22 PM

I have a self-inflicted dilemma about different coding styles.

Suppose you have a list of functions/API's that need to be called in a particular order, as each one depends on the previous to succeed. We're also going to have to cleanup the resources allocated by these functions after we're finished. However, should one function fail, the whole routine fails, but we still have to bail out and free the resources that were allocated so far. If a function fails it returns zero, and non-zero otherwise.

A typical example would be setting up an OpenGL 3.x context. In order to get a OpenGL 3.x context you first have to create a dummy OpenGL context, get some pointers, and then destroy it. This is, however, only an example, I am talking about general approach in this thread. Consider this function:

bool SomeFunction() {
	bool result = false;

	int a = DoSomething();
	if (a != 0) {
		int b = DoSomethingElse();
		if (b != 0) {
			int c = DoYetAnotherThing();
			if (c != 0) {
				
				... etc ...
					
					// Final code here
					result = true;
					
				... etc ...
				
				// Because we know DoYetAnotherThing succeeded we have to free the
				// resources regardless of what happens in the nested code.
				CleanupYetAnotherThing(c);
			} else {
				printf("DoYetAnotherThing.\n"); // Optional error msg
			}
			
			// Because we know DoSomethingElse succeeded we have to free the
			// resources regardless of what happens in the nested code.
			CleanupSomethingElse(b);
		} else {
			printf("DoSomethingElse failed.\n"); // Optional error msg
		}
		
		// Because we know DoSomething succeeded we have to free the
		// resources regardless of what happens in the nested code.
		CleanupSomething(a);
	
	} else {
		printf("DoSomething failed.\n"); // Optional error msg
	}
	return result;
}

This function performs what it's supposed to beautifully. It's like a pyramid - you climb it on one side and descent on the other. Should you trip anywhere while climbing it, you get instantly teleported to the other end and start descending without reaching the top. Unfortunately all those nested if's make the pyramid rather large, and thus, code much less readable. So I was looking for an alternative coding style to do this. Here's something I came up with:

bool SomeFunction() {
	bool result = false;
	
	int a = DoSomething();
	if (a == 0) goto CleanupA;
	
	int b = DoSomethingElse();
	if (b == 0) goto CleanupB;
	
	int c = DoYetAnotherThing();
	if (c == 0) goto CleanupC;
	
	... etc ...
	
	// Final code here
	result = true;
	
	... etc ...
	
	CleanupC:
	CleanupYetAnotherThing(c);
	
	CleanupB:
	CleanupSomethingElse(b);
	
	CleanupA:
	CleanupSomething(a);
	
	return result;
}

Okay, getting rid of those nested if's sure makes the code a lot more readable. But as any decent book on C++ will tell you do not use goto's in your code. I think I'll heed that advice. How about this:


int a, b, c;

bool SomeFunction() {
	
	a = DoSomething();
	if (a == 0) return false;
	
	b = DoSomethingElse();
	if (b == 0) return false;
	
	c = DoYetAnotherThing();
	if (c == 0) return false;
	
	... etc ...
	
	// Final code here
	return true;
	
}

void SomeFunctionCleanup() {
	... etc ...
	
	if (c != 0) CleanupYetAnotherThing(c);
	if (b != 0) CleanupSomethingElse(b);
	if (a != 0) CleanupSomething(a);
}

The problem here is obvious. Not only we have to split the routine in two functions, they both have to use global variables in order to share resources. I am not sure whether encapsulating this in a class would solve anything.


What style should I use?

Package content naming convention

06 July 2011 - 12:07 PM

Eek, I'm not sure how to call this, but I'll ask in the newbie section as I currently have little experience with it. Okay, suppose I have a number of packed files (packages). Let's say they're all standard ZIP files. Actually the package format doesn't really matter, what's important is that the package can store different content in form of files like wav, bmp, jpg, avi, png, frag, vert, etc. The packages/archives can contain any file-type as well as other folders which may contain more files and/or subfolders. Basically a directory tree.

What I am looking for is a decent (standard) way of referring to the content stored inside an archive so that a c++ program may extract a given resource file (based on the reference path) and load it into memory. I can't come up with a decent solution myself so I'd like to ask for some advice. As most good books on programming will teach you it's better to use an existing solution than to reinvent the wheel. For regular files stored on HDD one can probably use the Boost path. My approach works with files inside archives, so one has to be able to tell which archive we want to open and what file to load.

i.e.

Approach #1: package.resource
We have an archive named "Test.zip" and we'd like to load a file "sound\master.wav". So if we refer to it as "test.sound.master.wav" how should the program know we're trying to load a file named "master.wav" that is stored inside package "test.zip" and located in subfolder "sound" as opposed to a file named "wav" (with no extension) stored inside Test.zip and located in subfolder "sound\master"?

Approach #2: namespaces
Same archive, same file. We can do "Test::sound\master.wav". This is much cleaner, but it's a bit awkward imo.


Suggestions?

Idea: Reverse assignment operator

12 February 2011 - 01:55 PM

Hey!

I'm not quite sure how to properly present this stuff because it's just another of those wild ideas I've had about Angelscript. Here goes...

Suppose you have a Class in angelscript like:

class Vector2D {
	float x, y;
	
	... code ...

};

Now we'd like to assign the coordinates to both floats by passing a string to our instance. We can do it like:

Vector2D A = Vector2D("[10.3545, 1.4362]"); // Ugh, casting anyone? <img src='http://public.gamedev.net/public/style_emoticons/default/sad.gif' class='bbc_emoticon' alt=':(' />
Vector2D B("[10.3545, 1.4362]"); // Has to use a proper constructor
Vector2D C = "[10.3545, 1.4362]"; // Has to use the "opAssign" operator overload

What we're doing here is actaully assigning a string to our class. The problem can easily be solved by adding a proper constructor or by using an assignment operator overload for a string:

class Vector2D {
	float x, y;
	
	Vector2D(String@ str) {
		// Code to extract floats from the given string and pass them to proper members.
	}
	
	opAssign(String@ str) {
		// Code to extract floats from the given string and pass them to proper members.
	}
	
	... more code ...
	
};


But what, if we'd like to turn this around a little bit and do a reverse operation? Something like:

Vector2D A = "[10.354, 1.436]";
String location = A;

After this code executes I expect the string to contain something like "[10.354000, 1.436000]". And yes, I'm talking about doing this without modifying the string class to accept Vector2D objects. There are various reasons for this i.e.

  • - The script writer wants to implement new behaviours for converting Vector2D to registered object types, but he only has access to a compiled binary, so modding the String class source code is not an option.
  • - The left-hand side is not an object at all (it's a primitive), and can't handle any assignment operator overloads.
  • - There are just too many objects that need support for conversion to string, so modifying the string class to handle each and every possible class gets messy and ugly.
This is where the so-called "reverse assignment" operator comes into play. It makes the class convert itself into the required type and then outputs it via the return value. A class can have many rev. assignment operators with different return types - this lets us convert a given class to any other object or primitive based on the return type of the reverse assignment operator.

class MyClass {
	float x, y;
	
	int SomeFunction() {
		// stuff
	}
	
	int opAssign_r() {
		return SomeFunction();
	}
	
	String@ opAssign_r() {
		return "[" + String(x) + ", " + String(y) + "]";
	}
	
	float opAssign_r() {
		return x*x + y*y;
	}
	
	... more code ...
	
};


Comments, views, ideas, thoughts?

PARTNERS