Menu

Show posts

This section allows you to view all posts made by this member. Note that you can only see posts made in areas you currently have access to.

Show posts Menu

Messages - Monsieur OUXX

#421
Hints & Tips / Re: Return of the Obra Dinn
Thu 13/12/2018 22:51:16
What do those mean in the interface?
- the crosses / dashes at the beginning of each chapter, under the map
- the crosses in front of some (but not all) lines of dialog in the memory transcript?
#422
Hints & Tips / Re: Return of the Obra Dinn
Thu 13/12/2018 13:43:22
EDIT
#423
It could be related to the Western crash of consoles in the late 80's (atari, etc.). While shortly after the Japanese already were getting addicted to the NES (which means that the platformer genre was deeply rooted in their gaming culture), in the US they were quickly rebounding with some new equipment (also pushing them towards action-oriented games).
Meanwhile in Europe they were "stuck" inbetween, with either office equipment (small computers) or moderately/outdated consoles. In Eastern Europe and Mediterranean Europe, they kept using the Amstrad and Amiga waaayyyy longer.
So it took more time and money for the new "dream machines" to arrive in some parts of Europe (see the "no export for you" article in the previous post), which spawned some new cheap-to-produce genres (typically: point n click), and genres that could run on a computer (i.e. genres where the FPS is not too important but where you can use the many colors provided. Let's say "contemplative genres"). Let's not forget that Lucasarts and Sierra were aiming at the Germans as much as the Americans to sell their point-n-click.


EDIT: see here at 19:34 -- Europe found comfort in machines like the Amiga for a longer time than the US
https://www.youtube.com/watch?v=zB_UZsJUbwQ
#424
Hints & Tips / Re: Return of the Obra Dinn
Fri 07/12/2018 13:36:57
Thanks for the reply.

Since I'm here, I have a bit of a language barrier.
What is "struck"? Does it mean "struck by lightning"? I don't understand what "hooves", "tail" and "wing" mean. I would expect parts of the ship , but when I google it I obtain completely different results so I'm confused (not to mention the results are polluted by bronies fanfiction which makes it even worse)
Oh OK I get it. "hit by the feet of the animal", like if it's the goat it should be the hooves, etc.
#425
Hints & Tips / Return of the Obra Dinn
Fri 07/12/2018 12:42:58
Hello!
I have two simple questions :

1) What do you enter for a public execution?
Spoiler
there's this guy who gets shot on order by 5 or 6 men, and I don't know what to enter. When I select "shot (by gun") then the game wants me to enter the name of the killer... It makes no sense?
[close]

2) Can ytou re-visit a memory without actually walking there?
Spoiler
In the notebook it shows you where the memory happened, or which memories involved one specific character, but... then when you cick on the memory nothing actually happens. Is there a way to "teleport" to the memory without having to painfully walk there and use the chronometer?
[close]
#426
It could be very quick if you do it the right way.

I'd proceed like this :
1) Find the exact last AGS version that had a working Android port (I don't follow the Android port too closely so I couldn't tell if it's an older version or the lastest version. Who knows, you might be lucky). For argument's sake, let's pretend it was AGS 3.3.0.
2) Convert your game from 2.x to 3.x using the 3.x version of AGS that had the best retrocompatibility and upgrade abilities with 2.72. If I recall it could be AGS 3.2.x but maybe someone else could shed some light on this topic.
3) Make sure your game works on that version. You might have to mostly work with converting from global function to object functions. (for example: GetColorFromRGB is now Game.GetColorFromRGB, ChangeRoom(cEgo) is now cEgo.ChangeRoom(), etc.)
4) Convert your game from that version to the version we mentionned in step one. For example, convert from 3.2 to 3.3.0 if these are the versions. This time your main challenge might be to convert to the new sound system (convert from "PlaySound(1)" to "aSound1.Play()")

Done!

EDIT : out of curiosity, what game was it? Is it in the games database? :)
#427
I recall that years ago someone wrote a cunning module that would let you change graphic settings from within the game, and then the game would reboot itself or something and the changes would take effect. It was done in a very clean and effective manner.
I'm not saying it resolves everything magically, but it could be worth investigating its features and how it's done (first one would need to dig it out with some google search)
#428
Three skills :
1) persistence (finishing the game). People often get overwhelmed by the possibilities until they realized they blown too much steam on irrelevant stuff.
2) good puzzles. People make rooms and write a story only to realize at the end that they didn't make an adventure game but instead tried to shoehorn a good story into a soulless succession of "FedEx quests" (use X on Y).
3) animators. You have a nice engine, a nice story, a nice character and potentially nice backgrounds. But then everything that's meant to be moving in your game looks stiff and tasteless and cheap... because animating stuff is very time consuming when you don't have lots of experience. Even when it's only clouds passing by in the sky or water flowing.

For the music I've always used free of rights music so I can't really discuss that topic.

#429
hahaha what the hell
#430
General Discussion / Re: The festival of death
Thu 22/11/2018 17:19:44
(not directly related to All Saints day / day of the dead)

In France we used to dress up for mardi gras* when I was a kid (let's say up until 20 years ago). it was like a mini carnival. But nowadays you look like an idiot if you dress up for mardi gras. People now dress up only for halloween, which is clearly a commercial thing imported from the U.S.** about 15 years ago.


* historically, mardi gras (literally: fat Tuesday) was the religious celebration where you are allowed to eat rich food after the end of the Christian fast.
** I'm not talking about the irish halloween, only about the way it's celebrated in my country.
#431
Quote from: jjattar on Mon 05/11/2018 15:44:05
There is no gap when looping the tracks here. The silence only appears when one track ends and the other begins.
Could it be related to the fraction of a second required to load the file into memory?
#432
Khris, please update the wiki page about fonts. It's very important. Otherwise your tool will be forgotten forever.
Please clearly explain on the wiki how your tool fits in the presented workflows, and what it adds (or lacks) compared to other tools.
#433
Quote from: selmiak on Thu 22/11/2018 06:42:07
I could translate this demo to german for you

Never underestimate the German market for adventure games. They're your number one marketing target.

EDIT: this demo is most impressive.
#434
In retrospect, I realise that it's really heartbreaking how they didn't use their vector graphics engine to rotoscope the main character better than that. They had everything they needed for that, and yet they inserted this ugly polygonal guy into their gorgeous pixel art. Pity! the game could have looked like a fullscreen Prince of Persia. If they had followed this example, the game would have looked like a proto FMV ...as early as 1991!
#435
Spritesheet 1

Spritesheet 2

Spritesheet 3

Spritesheet 4





https://imgur.com/gallery/vBBUpls



That's all 1723 sprites
Unfortunately I screwed up the palette so i'll have to do it again, but this is a good start.




#436
Quote from: selmiak on Wed 21/11/2018 20:45:59
dem ded?
Nope. But it's the raw background. Then there's animation on top for each of them. The missing parts are the animated parts.
#438
>> Download viewer <<

It's made with AGS :D

How to use :

  • Type in any number in the textbox (e.g. "6") then press return..
  • after the sprite is displayed, press the left and right arrows to open the next or previous sprite. Pro-tip : If you started from sprite 0, then you should click "right" several times before you see anything interesting.
  • Type 100000 or above to see backgrounds.


Screenshot:

#439
OK so here is what I did :

(modified code from ScummVM, in engine "CRUISE")
(everything between //TEST and //~TEST is my custom code)
File "maindraw.cpp"
Code: ags

//TEST
int exportCount = 0;
//~TEST

void drawSprite(int width, int height, cellStruct *currentObjPtr, const uint8 *dataIn, int ys, int xs, uint8 *output, const uint8 *dataBuf) {
	int x = 0;
	int y = 0;

	// Flag the given area as having been changed
	Common::Point ps = Common::Point(MAX(MIN(xs, 320), 0), MAX(MIN(ys, 200), 0));
	Common::Point pe = Common::Point(MAX(MIN(xs + width, 320), 0), MAX(MIN(ys + height, 200), 0));
	if ((ps.x != pe.x) && (ps.y != pe.y))
		// At least part of sprite is on-screen
		gfxModuleData_addDirtyRect(Common::Rect(ps.x, ps.y, pe.x, pe.y));

	cellStruct* plWork = currentObjPtr;
	int workBufferSize = height * (width / 8);

	unsigned char* workBuf = (unsigned char*)MemAlloc(workBufferSize);
	memcpy(workBuf, dataBuf, workBufferSize);

	int numPasses = 0;

	while (plWork) {
		if (plWork->type == OBJ_TYPE_BGMASK && plWork->freeze == 0) {
			objectParamsQuery params;

			getMultipleObjectParam(plWork->overlay, plWork->idx, &params);

			int maskX = params.X;
			int maskY = params.Y;
			int maskFrame = params.fileIdx;

			if (filesDatabase[maskFrame].subData.resourceType == OBJ_TYPE_BGMASK && filesDatabase[maskFrame].subData.ptrMask) {
				drawMask(workBuf, width / 8, height, filesDatabase[maskFrame].subData.ptrMask, filesDatabase[maskFrame].width / 8, filesDatabase[maskFrame].height, maskX - xs, maskY - ys, numPasses++);
			} else
				if (filesDatabase[maskFrame].subData.resourceType == OBJ_TYPE_SPRITE && filesDatabase[maskFrame].subData.ptrMask) {
					drawMask(workBuf, width / 8, height, filesDatabase[maskFrame].subData.ptrMask, filesDatabase[maskFrame].width / 8, filesDatabase[maskFrame].height, maskX - xs, maskY - ys, numPasses++);
				}

		}

		plWork = plWork->next;
	}


	//TEST
	Common::DumpFile fout;
	if (exportCount < 2000) {
		char nameBuffer[256];
		//fileEntry *buffer;

		sprintf(nameBuffer, "./export3/export%d.dmp", exportCount);


		//fout.open(nameBuffer, Common::File::kFileWriteMode);
		fout.open(nameBuffer);
		if (fout.isOpen()) {
			fout.writeUint32LE(width);
			fout.writeUint32LE(height);

			//dump palette
			for (int i = 0; i < 256 * 3; i++) {
				fout.writeUint32LE(palScreen[0][i]);
			}

		}
	}
	
	//	fout.write(uncompBuffer, buffer[j].extSize);


	bool drawn = false;

	//~TEST


	for (y = 0; y < height; y++) {
		for (x = 0; x < (width); x++) {
			drawn = false;
			uint8 color = *dataIn++;

			if ((x + xs) >= 0 && (x + xs) < 320 && (y + ys) >= 0 && (y + ys) < 200) {
				if (testMask(x, y, workBuf, width / 8)) {
					output[320 * (y + ys) + x + xs] = color;
					//TEST
					drawn = true;

					if (fout.isOpen()) {
						fout.writeUint32LE(color);
					}
					//~TEST
				}
			}

                        //TEST
			if (!drawn && fout.isOpen()) {
				fout.writeUint32LE(0);
			}
                        //~TEST
		}
	}
	//TEST
	//if (fout.isOpen())
		fout.close();
	exportCount++;
	//~TEST
	MemFree(workBuf);
}





In file background.cpp
Code: ags



//TEST
int exportCount2 = 100000;
//~TEST

int loadBackground(const char *name, int idx) {
	uint8 *ptr;
	uint8 *ptr2;
	uint8 *ptrToFree;

	debug(1, "Loading BG: %s", name);

	if (!backgroundScreens[idx]) {
		backgroundScreens[idx] = (uint8 *)mallocAndZero(320 * 200);
	}

	if (!backgroundScreens[idx]) {
		backgroundTable[idx].name[0] = 0;
		return (-2);
	}

	backgroundChanged[idx] = true;

	ptrToFree = gfxModuleData.pPage10;
	if (loadFileSub1(&ptrToFree, name, NULL) < 0) {
		if (ptrToFree != gfxModuleData.pPage10)
			MemFree(ptrToFree);

		return (-18);
	}

	if (lastFileSize == 32078 || lastFileSize == 32080 || lastFileSize == 32034) {
		colorMode = 0;
	} else {
		colorMode = 1;
	}

	ptr = ptrToFree;
	ptr2 = ptrToFree;

	if (!strcmp(name, "LOGO.PI1")) {
		oldSpeedGame = speedGame;
		flagSpeed = 1;
		speedGame = 1;
	} else if (flagSpeed) {
		speedGame = oldSpeedGame;
		flagSpeed = 0;
	}

	if (!strcmp((char *)ptr, "PAL")) {
		memcpy(palScreen[idx], ptr + 4, 256*3);
		gfxModuleData_setPal256(palScreen[idx]);
	} else {
		int mode = ptr2[1];
		ptr2 += 2;
		// read palette
		switch (mode) {
		case 0:
		case 4: { // color on 3 bit
			uint16 oldPalette[32];

			memcpy(oldPalette, ptr2, 0x20);
			ptr2 += 0x20;
			flipGen(oldPalette, 0x20);

			for (unsigned long int i = 0; i < 32; i++) {
				gfxModuleData_convertOldPalColor(oldPalette[i], &palScreen[idx][i*3]);
			}

			// duplicate the palette
			for (unsigned long int i = 1; i < 8; i++) {
				memcpy(&palScreen[idx][32*i*3], &palScreen[idx][0], 32*3);
			}

			break;
		}
		case 5: { // color on 4 bit
			for (unsigned long int i = 0; i < 32; i++) {
				uint8* inPtr = ptr2 + i * 2;
				uint8* outPtr = palScreen[idx] + i * 3;

				outPtr[2] = ((inPtr[1]) & 0x0F) * 17;
				outPtr[1] = (((inPtr[1]) & 0xF0) >> 4) * 17;
				outPtr[0] = ((inPtr[0]) & 0x0F) * 17;
			}
			ptr2 += 2 * 32;

			// duplicate the palette
			for (unsigned long int i = 1; i < 8; i++) {
				memcpy(&palScreen[idx][32*i*3], &palScreen[idx][0], 32*3);
			}

			break;
		}
		case 8:
			memcpy(palScreen[idx], ptr2, 256*3);
			ptr2 += 256 * 3;
			break;

		default:
			assert(0);
		}

		gfxModuleData_setPal256(palScreen[idx]);

		// read image data
		gfxModuleData_gfxClearFrameBuffer(backgroundScreens[idx]);

		switch (mode) {
		case 0:
		case 4:
			convertGfxFromMode4(ptr2, 320, 200, backgroundScreens[idx]);
			ptr2 += 32000;
			break;
		case 5:
			convertGfxFromMode5(ptr2, 320, 200, backgroundScreens[idx]);
			break;
		case 8:
			memcpy(backgroundScreens[idx], ptr2, 320 * 200);
			ptr2 += 320 * 200;
			break;
		}

		loadMEN(&ptr2);
		loadCVT(&ptr2);
	}

	MemFree(ptrToFree);

	// NOTE: the following is really meant to compare pointers and not the actual
	// strings. See r48092 and r48094.
	if (name != backgroundTable[idx].name) {
		if (strlen(name) >= sizeof(backgroundTable[idx].name))
			warning("background name length exceeded allowable maximum");

		Common::strlcpy(backgroundTable[idx].name, name, sizeof(backgroundTable[idx].name));
	}

	//TEST
	Common::DumpFile fout;
	if (exportCount2 - 100000 < 10) {
		char nameBuffer[256];
		fileEntry *buffer;

		sprintf(nameBuffer, "./export4/export%d.dmp", exportCount2);


		//fout.open(nameBuffer, Common::File::kFileWriteMode);
		fout.open(nameBuffer);
		if (fout.isOpen()) {
			fout.writeUint32LE(320);
			fout.writeUint32LE(200);

			//dump palette
			for (int i = 0; i < 256 * 3; i++) {
				fout.writeUint32LE(palScreen[idx][i]);
			}

			for (int y = 0; y < 200; y++) {
				for (int x = 0; x < (320); x++) {

					fout.writeUint32LE(backgroundScreens[idx][320 * y + x]);
				}
			}

			//if (fout.isOpen())
			fout.close();
			exportCount2++;

		}
	}

	//	fout.write(uncompBuffer, buffer[j].extSize);




	//~TEST


	return (0);
}



This generates files "export0.dmp, export1.dmp, export2.dmp, ..." for sprites and files "export100000.dmp, export100001.dmp, export100002.dmp, ... for backgrounds.
#440
So far I've succeeded to dump backgrounds and "normal" sprites (not polygonal sprites), and I'm on the verge of having the palette.
I've made a reader using AGS because I couldn't be arsed to program it with something too heavy with C++ in it ;)
My issue is that I dump things as they get loaded, so it means I can't dump the whole game and I'm dumping many things several times.
SMF spam blocked by CleanTalk