Esempio n. 1
0
void PrinceEngine::specialPlotInside(int x, int y) {
	if (_coords < _coordsBufEnd) {
		WRITE_LE_UINT16(_coords, x);
		_coords += 2;
		WRITE_LE_UINT16(_coords, y);
		_coords += 2;
	}
}
Esempio n. 2
0
void AGOSEngine_PN::writeval(uint8 *ptr, int val) {
	uint8 *savpt = _workptr;
	int lsav = _linct, a, b, x;
	_workptr = ptr;
	_linct = 255;

	if ((a = readfromline()) < 247)
		error("writeval: Write to constant (%d)", a);

	switch (a) {
		case 249:
			error("writeval: Write to constant (%d)", a);
			break;
		case 250:
			error("writeval: Write to constant (%d)", a);
			break;
		case 251:
			_variableArray[varval()] = val;
			break;
		case 252:
			b = varval();
			_dataBase[_quickptr[0] + b * _quickshort[0] + varval()] = val;
			break;
		case 254:
			b = varval();
			_dataBase[_quickptr[3] + b * _quickshort[2] + varval()] = val;
			break;
		case 247:
			b = varval();
			x = _quickptr[11] + b * _quickshort[4] + varval() * 2;
			WRITE_LE_UINT16(_dataBase + x, val);
			break;
		case 248:
			b = varval();
			x = _quickptr[12] + b * _quickshort[5] + varval() * 2;
			WRITE_LE_UINT16(_dataBase + x, val);
			break;
		case 253:
			b = varval();
			setbitf((uint32)_quickptr[1] + b * _quickshort[1], varval(), val);
			break;
		case 255:
			b = varval();
			setbitf((uint32)_quickptr[4] + b * _quickshort[3], varval(), val);
			break;
		default:
			error("WRITEVAL : undefined evaluation %d", a);
	}
	_linct = lsav;
	_workptr = savpt;
}
Esempio n. 3
0
// will actually patch previously found signature area
void Script::applyPatch(const uint16 *patch, byte *scriptData, const uint32 scriptSize, int32 signatureOffset) {
	byte orgData[PATCH_VALUELIMIT];
	int32 offset = signatureOffset;
	uint16 patchWord = *patch;

	// Copy over original bytes from script
	uint32 orgDataSize = scriptSize - offset;
	if (orgDataSize > PATCH_VALUELIMIT)
		orgDataSize = PATCH_VALUELIMIT;
	memcpy(&orgData, &scriptData[offset], orgDataSize);

	while (patchWord != PATCH_END) {
		uint16 patchValue = patchWord & PATCH_VALUEMASK;
		switch (patchWord & PATCH_COMMANDMASK) {
		case PATCH_ADDTOOFFSET:
			// add value to offset
			offset += patchValue & ~PATCH_ADDTOOFFSET;
			break;
		case PATCH_GETORIGINALBYTE:
			// get original byte from script
			if (patchValue >= orgDataSize)
				error("patching: can not get requested original byte from script");
			scriptData[offset] = orgData[patchValue];
			offset++;
			break;
		case PATCH_ADJUSTWORD: {
			// Adjust word right before current position
			byte *adjustPtr = &scriptData[offset - 2];
			uint16 adjustWord = READ_LE_UINT16(adjustPtr);
			adjustWord += patchValue;
			WRITE_LE_UINT16(adjustPtr, adjustWord);
			break;
		}
		case PATCH_ADJUSTWORD_NEG: {
			// Adjust word right before current position (negative way)
			byte *adjustPtr = &scriptData[offset - 2];
			uint16 adjustWord = READ_LE_UINT16(adjustPtr);
			adjustWord -= patchValue;
			WRITE_LE_UINT16(adjustPtr, adjustWord);
			break;
		}
		default:
			scriptData[offset] = patchValue & 0xFF;
			offset++;
		}
		patch++;
		patchWord = *patch;
	}	
}
Esempio n. 4
0
byte *Sword2Engine::fetchPsxBackground(uint32 location) {
	Common::File file;
	PSXScreensEntry header;
	uint32 screenOffset, dataOffset;
	uint32 totSize; // Total size of background, counting data, offset table and additional header
	byte *buffer;

	if (!file.open("screens.clu")) {
		GUIErrorMessage("Broken Sword 2: Cannot open screens.clu");
		return NULL;
	}

	file.seek(location * 4, SEEK_SET);
	screenOffset = file.readUint32LE();

	if (screenOffset == 0) { // We don't have screen data for this location number.
		file.close();
		return NULL;
	}

	// Get to the beginning of PSXScreensEntry
	file.seek(screenOffset + ResHeader::size(), SEEK_SET);

	buffer = (byte *)malloc(PSXScreensEntry::size());
	file.read(buffer, PSXScreensEntry::size());

	// Prepare the header
	header.read(buffer);
	free(buffer);

	file.seek(screenOffset + header.bgOffset + 4, SEEK_SET);
	dataOffset = file.readUint32LE();

	file.seek(screenOffset + header.bgOffset, SEEK_SET);

	totSize = header.bgSize + (dataOffset - header.bgOffset) + 8;
	buffer = (byte *)malloc(totSize);

	// Write some informations before background data
	WRITE_LE_UINT16(buffer, header.bgXres);
	WRITE_LE_UINT16(buffer + 2, header.bgYres);
	WRITE_LE_UINT32(buffer + 4, header.bgOffset);

	file.read(buffer + 8, totSize - 8); // Do not write on the header
	file.close();

	return buffer;
}
Esempio n. 5
0
static void writeFakeChar(std::vector<byte> &output, uint32 c, Encoding encoding) {
	byte data[2];

	switch (encoding) {
		case kEncodingASCII:
		case kEncodingLatin9:
		case kEncodingUTF8:
		case kEncodingCP1250:
		case kEncodingCP1251:
		case kEncodingCP1252:
		case kEncodingCP932:
		case kEncodingCP936:
		case kEncodingCP949:
		case kEncodingCP950:
			output.push_back(c);
			break;

		case kEncodingUTF16LE:
			WRITE_LE_UINT16(data, c);
			output.push_back(data[0]);
			output.push_back(data[1]);
			break;

		case kEncodingUTF16BE:
			WRITE_BE_UINT16(data, c);
			output.push_back(data[0]);
			output.push_back(data[1]);
			break;

		default:
			break;
	}
}
Esempio n. 6
0
void SoundTowns_Darkmoon::playSoundEffect(uint8 track, uint8 volume) {
	if (!_sfxEnabled)
		return;

	if (volume == 255)
		return playTrack(track);

	uint8 *pcm = 0;

	switch (_soundTable[track].type) {
	case 0:
		if (_soundTable[track].para1 == -1 || (uint32)_soundTable[track].para1 > _pcmDataSize)
			return;

		pcm = _pcmData + _soundTable[track].para1;
		WRITE_LE_UINT16(&pcm[24], _soundTable[track].para2 * 98 / 1000);

		_intf->callback(39, 0x47);
		_intf->callback(37, 0x47, 60, volume, pcm);
		break;

	case 3:
		_intf->callback(2, _lastEnvChan);
		_intf->callback(4, _lastEnvChan, _soundTable[track].para1);
		_intf->callback(1, _lastEnvChan, _soundTable[track].para2, volume);
		break;

	default:
		break;
	}

	if (++_lastEnvChan == 0x43)
		_lastEnvChan = 0x40;
}
Esempio n. 7
0
void Object::setVectorItem(int16 index, int16 value) {
	if (getClass() == 0x7FFF) {
		byte *vector = (byte *)getData();
		vector[index] = value;
	} else if (getClass() <= 0x7FFE) {
		int16 *vector = (int16 *)getData();
		WRITE_LE_UINT16(&vector[index], value);
	}
}
Esempio n. 8
0
void SaveGame::writeLEUint16(uint16 data) {
	if (!_saving)
		error("SaveGame::writeBlock called when restoring a savegame");
	if (_currentSection == 0)
		error("Tried to write a block without starting a section");

	checkAlloc(2);

	WRITE_LE_UINT16(&_sectionBuffer[_sectionSize], data);
	_sectionSize += 2;
}
Esempio n. 9
0
void DecompressorLZW::buildCelHeaders(byte **seeker, byte **writer, int celindex, int *cc_lengths, int max) {
	for (int c = 0; c < max; c++) {
		memcpy(*writer, *seeker, 6);
		*seeker += 6;
		*writer += 6;
		int w = *((*seeker)++);
		WRITE_LE_UINT16(*writer, w); /* Zero extension */
		*writer += 2;

		*writer += cc_lengths[celindex];
		celindex++;
	}
}
Esempio n. 10
0
// following routine creates filled rectangle
// immediately as VGA video chunks, in near memory as fast as possible,
// especially for text line real time display
Bitmap::Bitmap(CGE2Engine *vm, uint16 w, uint16 h, uint8 fill)
	: _w((w + 3) & ~3),                              // only full uint32 allowed!
	  _h(h), _map(0), _b(nullptr), _vm(vm) {

	uint16 dsiz = _w >> 2;                           // data size (1 plane line size)
	uint16 lsiz = 2 + dsiz + 2;                     // uint16 for line header, uint16 for gap
	uint16 psiz = _h * lsiz;                         // - last gape, but + plane trailer
	uint8 *v = new uint8[4 * psiz + _h * sizeof(*_b)];// the same for 4 planes
	                                                // + room for wash table

	WRITE_LE_UINT16(v, (kBmpCPY | dsiz));                 // data chunk hader
	memset(v + 2, fill, dsiz);                      // data bytes
	WRITE_LE_UINT16(v + lsiz - 2, (kBmpSKP | ((kScrWidth / 4) - dsiz)));  // gap

	// Replicate lines
	byte *destP;
	for (destP = v + lsiz; destP < (v + psiz); destP += lsiz)
		Common::copy(v, v + lsiz, destP);

	WRITE_LE_UINT16(v + psiz - 2, kBmpEOI);            // plane trailer uint16

	// Replicate planes
	for (destP = v + psiz; destP < (v + 4 * psiz); destP += psiz)
		Common::copy(v, v + psiz, destP);

	HideDesc *b = (HideDesc *)(v + 4 * psiz);
	b->_skip = (kScrWidth - _w) >> 2;
	b->_hide = _w >> 2;

	// Replicate across the entire table
	for (HideDesc *hdP = b + 1; hdP < (b + _h); hdP++)
		*hdP = *b;

	b->_skip = 0;                                    // fix the first entry
	_v = v;
	_b = b;
}
Esempio n. 11
0
void SoundDesc::convToSigned() {
	if ((_type != SOUND_SND) && (_type != SOUND_WAV))
		return;
	if (!_data || !_dataPtr)
		return;

	if (_mixerFlags & Audio::FLAG_16BITS) {
		byte *data = _dataPtr;
		for (uint32 i = 0; i < _size; i++, data += 2)
			WRITE_LE_UINT16(data, READ_LE_UINT16(data) ^ 0x8000);
	} else
		for (uint32 i = 0; i < _size; i++)
			_dataPtr[i] ^= 0x80;

}
Esempio n. 12
0
void SoundTowns_Darkmoon::playTrack(uint8 track) {
	if (track >= 120 || !_sfxEnabled)
		return;

	uint8 *pcm = 0;

	switch (_soundTable[track].type) {
	case -1:
		if (track == 0)
			haltTrack();
		else if (track == 2)
			beginFadeOut();
		break;

	case 0:
		if (_soundTable[track].para1 == -1 || (uint32)_soundTable[track].para1 > _pcmDataSize)
			return;

		pcm = _pcmData + _soundTable[track].para1;
		WRITE_LE_UINT16(&pcm[24], _soundTable[track].para2 * 98 / 1000);

		_intf->callback(39, 0x47);
		_intf->callback(37, 0x47, 60, track == 11 ? 127 : _pcmVol, pcm);
		break;

	case 2:
		resetTrigger();
		g_system->getAudioCDManager()->play(_soundTable[track].para1 - 1, 1, 0, 0);
		break;

	case 3:
		_lastSfxChan ^= 3;
		_intf->callback(39, _lastSfxChan);
		_intf->callback(4, _lastSfxChan, _soundTable[track].para1);
		_intf->callback(1, _lastSfxChan, _soundTable[track].para2, 127);
		break;

	default:
		break;
	}
}
Esempio n. 13
0
reg_t GfxText16::allocAndFillReferenceRectArray() {
	uint rectCount = _codeRefRects.size();
	if (rectCount) {
		reg_t rectArray;
		byte *rectArrayPtr = g_sci->getEngineState()->_segMan->allocDynmem(4 * 2 * (rectCount + 1), "text code reference rects", &rectArray);
		GfxCoordAdjuster *coordAdjuster = g_sci->_gfxCoordAdjuster;
		for (uint curRect = 0; curRect < rectCount; curRect++) {
			coordAdjuster->kernelLocalToGlobal(_codeRefRects[curRect].left, _codeRefRects[curRect].top);
			coordAdjuster->kernelLocalToGlobal(_codeRefRects[curRect].right, _codeRefRects[curRect].bottom);
			WRITE_LE_UINT16(rectArrayPtr + 0, _codeRefRects[curRect].left);
			WRITE_LE_UINT16(rectArrayPtr + 2, _codeRefRects[curRect].top);
			WRITE_LE_UINT16(rectArrayPtr + 4, _codeRefRects[curRect].right);
			WRITE_LE_UINT16(rectArrayPtr + 6, _codeRefRects[curRect].bottom);
			rectArrayPtr += 8;
		}
		WRITE_LE_UINT16(rectArrayPtr + 0, 0x7777);
		WRITE_LE_UINT16(rectArrayPtr + 2, 0x7777);
		WRITE_LE_UINT16(rectArrayPtr + 4, 0x7777);
		WRITE_LE_UINT16(rectArrayPtr + 6, 0x7777);
		return rectArray;
	}
	return NULL_REG;
}
Esempio n. 14
0
int16 GameDatabase::setObjectProperty(int16 objectIndex, int16 propertyId, int16 value) {

	if (objectIndex == 0)
		return 0;

	int16 propertyFlag;
	//int16 *property = findObjectProperty(objectIndex, propertyId, propertyFlag);
	int16 *property = findObjectPropertyCached(objectIndex, propertyId, propertyFlag);

	if (property) {
		if (propertyFlag == 1) {
			WRITE_LE_UINT16(property, value);
		} else {
			warning("GameDatabase::setObjectProperty(%04X, %04X, %04X) Trying to set constant property",
				objectIndex, propertyId, value);
		}
		return value;
	} else {
		return 0;
	}

}
Esempio n. 15
0
void MoviePlayer::copyFrameToBuffer(byte *dst, int dstType, uint x, uint y, uint pitch) {
	uint h = getHeight();
	uint w = getWidth();

	const Graphics::Surface *surface = decodeNextFrame();
	byte *src = (byte *)surface->pixels;

	if (hasDirtyPalette())
		_vm->setPaletteFromPtr(getPalette(), 256);

	if (_vm->_game.features & GF_16BIT_COLOR) {
		dst += y * pitch + x * 2;
		do {
			for (uint i = 0; i < w; i++) {
				uint16 color = READ_LE_UINT16(_vm->_hePalettes + _vm->_hePaletteSlot + 768 + src[i] * 2);
				switch (dstType) {
				case kDstScreen:
					WRITE_UINT16(dst + i * 2, color);
					break;
				case kDstResource:
					WRITE_LE_UINT16(dst + i * 2, color);
					break;
				default:
					error("copyFrameToBuffer: Unknown dstType %d", dstType);
				}
			}
			dst += pitch;
			src += w;
		} while (--h);
	} else {
		dst += y * pitch + x;
		do {
			memcpy(dst, src, w);
			dst += pitch;
			src += w;
		} while (--h);
	}
}
Esempio n. 16
0
void DecompressorLZW::reorderPic(byte *src, byte *dest, int dsize) {
	uint16 view_size, view_start, cdata_size;
	int i;
	byte *seeker = src;
	byte *writer = dest;
	char viewdata[7];
	byte *cdata, *cdata_start;

	*writer++ = PIC_OP_OPX;
	*writer++ = PIC_OPX_SET_PALETTE;

	for (i = 0; i < 256; i++) /* Palette translation map */
		*writer++ = i;

	WRITE_LE_UINT32(writer, 0); /* Palette stamp */
	writer += 4;

	view_size = READ_LE_UINT16(seeker);
	seeker += 2;
	view_start = READ_LE_UINT16(seeker);
	seeker += 2;
	cdata_size = READ_LE_UINT16(seeker);
	seeker += 2;

	memcpy(viewdata, seeker, sizeof(viewdata));
	seeker += sizeof(viewdata);

	memcpy(writer, seeker, 4*256); /* Palette */
	seeker += 4*256;
	writer += 4*256;

	if (view_start != PAL_SIZE + 2) { /* +2 for the opcode */
		memcpy(writer, seeker, view_start-PAL_SIZE-2);
		seeker += view_start - PAL_SIZE - 2;
		writer += view_start - PAL_SIZE - 2;
	}

	if (dsize != view_start + EXTRA_MAGIC_SIZE + view_size) {
		memcpy(dest + view_size + view_start + EXTRA_MAGIC_SIZE, seeker,
		       dsize - view_size - view_start - EXTRA_MAGIC_SIZE);
		seeker += dsize - view_size - view_start - EXTRA_MAGIC_SIZE;
	}

	cdata_start = cdata = (byte *)malloc(cdata_size);
	memcpy(cdata, seeker, cdata_size);
	seeker += cdata_size;

	writer = dest + view_start;
	*writer++ = PIC_OP_OPX;
	*writer++ = PIC_OPX_EMBEDDED_VIEW;
	*writer++ = 0;
	*writer++ = 0;
	*writer++ = 0;
	WRITE_LE_UINT16(writer, view_size + 8);
	writer += 2;

	memcpy(writer, viewdata, sizeof(viewdata));
	writer += sizeof(viewdata);

	*writer++ = 0;

	decodeRLE(&seeker, &cdata, writer, view_size);

	free(cdata_start);
}
Esempio n. 17
0
void WRITE_SCI11ENDIAN_UINT16(void *ptr, uint16 val) {
	if (g_sci->getPlatform() == Common::kPlatformMacintosh && getSciVersion() >= SCI_VERSION_1_1)
		WRITE_BE_UINT16(ptr, val);
	else
		WRITE_LE_UINT16(ptr, val);
}
Esempio n. 18
0
void DecompressorLZW::reorderView(byte *src, byte *dest) {
	byte *cellengths;
	int loopheaders;
	int lh_present;
	int lh_mask;
	int pal_offset;
	int cel_total;
	int unknown;
	byte *seeker = src;
	char celcounts[100];
	byte *writer = dest;
	byte *lh_ptr;
	byte *rle_ptr, *pix_ptr;
	int l, lb, c, celindex, lh_last = -1;
	int chptr;
	int w;
	int *cc_lengths;
	byte **cc_pos;

	/* Parse the main header */
	cellengths = src + READ_LE_UINT16(seeker) + 2;
	seeker += 2;
	loopheaders = *seeker++;
	lh_present = *seeker++;
	lh_mask = READ_LE_UINT16(seeker);
	seeker += 2;
	unknown = READ_LE_UINT16(seeker);
	seeker += 2;
	pal_offset = READ_LE_UINT16(seeker);
	seeker += 2;
	cel_total = READ_LE_UINT16(seeker);
	seeker += 2;

	cc_pos = (byte **) malloc(sizeof(byte *) * cel_total);
	cc_lengths = (int *) malloc(sizeof(int) * cel_total);

	for (c = 0; c < cel_total; c++)
		cc_lengths[c] = READ_LE_UINT16(cellengths + 2 * c);

	*writer++ = loopheaders;
	*writer++ = VIEW_HEADER_COLORS_8BIT;
	WRITE_LE_UINT16(writer, lh_mask);
	writer += 2;
	WRITE_LE_UINT16(writer, unknown);
	writer += 2;
	WRITE_LE_UINT16(writer, pal_offset);
	writer += 2;

	lh_ptr = writer;
	writer += 2 * loopheaders; /* Make room for the loop offset table */

	pix_ptr = writer;

	memcpy(celcounts, seeker, lh_present);
	seeker += lh_present;

	lb = 1;
	celindex = 0;

	rle_ptr = pix_ptr = cellengths + (2 * cel_total);
	w = 0;

	for (l = 0; l < loopheaders; l++) {
		if (lh_mask & lb) { /* The loop is _not_ present */
			if (lh_last == -1) {
				warning("Error: While reordering view: Loop not present, but can't re-use last loop");
				lh_last = 0;
			}
			WRITE_LE_UINT16(lh_ptr, lh_last);
			lh_ptr += 2;
		} else {
			lh_last = writer - dest;
			WRITE_LE_UINT16(lh_ptr, lh_last);
			lh_ptr += 2;
			WRITE_LE_UINT16(writer, celcounts[w]);
			writer += 2;
			WRITE_LE_UINT16(writer, 0);
			writer += 2;

			/* Now, build the cel offset table */
			chptr = (writer - dest) + (2 * celcounts[w]);

			for (c = 0; c < celcounts[w]; c++) {
				WRITE_LE_UINT16(writer, chptr);
				writer += 2;
				cc_pos[celindex+c] = dest + chptr;
				chptr += 8 + READ_LE_UINT16(cellengths + 2 * (celindex + c));
			}

			buildCelHeaders(&seeker, &writer, celindex, cc_lengths, celcounts[w]);

			celindex += celcounts[w];
			w++;
		}

		lb = lb << 1;
	}

	if (celindex < cel_total) {
		warning("View decompression generated too few (%d / %d) headers", celindex, cel_total);
		return;
	}

	/* Figure out where the pixel data begins. */
	for (c = 0; c < cel_total; c++)
		pix_ptr += getRLEsize(pix_ptr, cc_lengths[c]);

	rle_ptr = cellengths + (2 * cel_total);
	for (c = 0; c < cel_total; c++)
		decodeRLE(&rle_ptr, &pix_ptr, cc_pos[c] + 8, cc_lengths[c]);

	if (pal_offset) {
		*writer++ = 'P';
		*writer++ = 'A';
		*writer++ = 'L';

		for (c = 0; c < 256; c++)
			*writer++ = c;

		seeker -= 4; /* The missing four. Don't ask why. */
		memcpy(writer, seeker, 4*256 + 4);
	}

	free(cc_pos);
	free(cc_lengths);
}
Esempio n. 19
0
void GameDatabase::setVar(int16 index, int16 value) {
	WRITE_LE_UINT16(_gameState + index * 2, value);
}
Esempio n. 20
0
void ScriptInterpreter::pushInt16(int16 value) {
	WRITE_LE_UINT16(_stack + _regs.sp, value);
	_regs.sp -= 2;
}
Esempio n. 21
0
void ScriptInterpreter::localWrite16(int16 offset, int16 value) {
	//debug(1, "localWrite16(%d, %d)", offset, value);
	WRITE_LE_UINT16(&_localData[offset], value);
}
Esempio n. 22
0
reg_t GfxText32::createTextBitmap(reg_t textObject, uint16 maxWidth, uint16 maxHeight, reg_t prevHunk) {
	reg_t stringObject = readSelector(_segMan, textObject, SELECTOR(text));

	// The object in the text selector of the item can be either a raw string
	// or a Str object. In the latter case, we need to access the object's data
	// selector to get the raw string.
	if (_segMan->isHeapObject(stringObject))
		stringObject = readSelector(_segMan, stringObject, SELECTOR(data));

	Common::String text = _segMan->getString(stringObject);
	// HACK: The character offsets of the up and down arrow buttons are off by one
	// in GK1, for some unknown reason. Fix them here.
	if (text.size() == 1 && (text[0] == 29 || text[0] == 30)) {
		text.setChar(text[0] + 1, 0);
	}
	GuiResourceId fontId = readSelectorValue(_segMan, textObject, SELECTOR(font));
	GfxFont *font = _cache->getFont(fontId);
	bool dimmed = readSelectorValue(_segMan, textObject, SELECTOR(dimmed));
	int16 alignment = readSelectorValue(_segMan, textObject, SELECTOR(mode));
	uint16 foreColor = readSelectorValue(_segMan, textObject, SELECTOR(fore));
	uint16 backColor = readSelectorValue(_segMan, textObject, SELECTOR(back));

	Common::Rect nsRect = g_sci->_gfxCompare->getNSRect(textObject);
	uint16 width = nsRect.width() + 1;
	uint16 height = nsRect.height() + 1;

	// Limit rectangle dimensions, if requested
	if (maxWidth > 0)
		width = maxWidth;
	if (maxHeight > 0)
		height = maxHeight;

	// Upscale the coordinates/width if the fonts are already upscaled
	if (_screen->fontIsUpscaled()) {
		width = width * _screen->getDisplayWidth() / _screen->getWidth();
		height = height * _screen->getDisplayHeight() / _screen->getHeight();
	}

	int entrySize = width * height + BITMAP_HEADER_SIZE;
	reg_t memoryId = NULL_REG;
	if (prevHunk.isNull()) {
		memoryId = _segMan->allocateHunkEntry("TextBitmap()", entrySize);
		writeSelector(_segMan, textObject, SELECTOR(bitmap), memoryId);
	} else {
		memoryId = prevHunk;
	}
	byte *memoryPtr = _segMan->getHunkPointer(memoryId);

	if (prevHunk.isNull())
		memset(memoryPtr, 0, BITMAP_HEADER_SIZE);

	byte *bitmap = memoryPtr + BITMAP_HEADER_SIZE;
	memset(bitmap, backColor, width * height);

	// Save totalWidth, totalHeight
	WRITE_LE_UINT16(memoryPtr, width);
	WRITE_LE_UINT16(memoryPtr + 2, height);

	int16 charCount = 0;
	uint16 curX = 0, curY = 0;
	const char *txt = text.c_str();
	int16 textWidth, textHeight, totalHeight = 0, offsetX = 0, offsetY = 0;
	uint16 start = 0;

	// Calculate total text height
	while (*txt) {
		charCount = GetLongest(txt, width, font);
		if (charCount == 0)
			break;

		Width(txt, 0, (int16)strlen(txt), fontId, textWidth, textHeight, true);

		totalHeight += textHeight;
		txt += charCount;
		while (*txt == ' ')
			txt++; // skip over breaking spaces
	}

	txt = text.c_str();

	// Draw text in buffer
	while (*txt) {
		charCount = GetLongest(txt, width, font);
		if (charCount == 0)
			break;
		Width(txt, start, charCount, fontId, textWidth, textHeight, true);

		switch (alignment) {
		case SCI_TEXT32_ALIGNMENT_RIGHT:
			offsetX = width - textWidth;
			break;
		case SCI_TEXT32_ALIGNMENT_CENTER:
			// Center text both horizontally and vertically
			offsetX = (width - textWidth) / 2;
			offsetY = (height - totalHeight) / 2;
			break;
		case SCI_TEXT32_ALIGNMENT_LEFT:
			offsetX = 0;
			break;

		default:
			warning("Invalid alignment %d used in TextBox()", alignment);
		}

		for (int i = 0; i < charCount; i++) {
			unsigned char curChar = txt[i];
			font->drawToBuffer(curChar, curY + offsetY, curX + offsetX, foreColor, dimmed, bitmap, width, height);
			curX += font->getCharWidth(curChar);
		}

		curX = 0;
		curY += font->getHeight();
		txt += charCount;
		while (*txt == ' ')
			txt++; // skip over breaking spaces
	}

	return memoryId;
}
Esempio n. 23
0
void writeUint16(FILE *file, uint16_t value) {
	char v[2];
	WRITE_LE_UINT16(&v, value);
	fwrite(&v, 1, 2, file);
}
Esempio n. 24
0
// Box
void FontManager::box(int idx, int messageId, const Common::String &filename, int xp, int yp) {
	int textPosX = xp;
	if (idx < 0)
		error("Bad number for text");
	_fontFixedWidth = 11;

	_boxWidth = 11 * _text[idx]._length;
	if (_text[idx]._textLoadedFl) {
		int textType = _text[idx]._textType;
		if (textType != 6 && textType != 1 && textType != 3 && textType != 5) {
			int yCurrent = yp + 5;
			for (int lineNum = 0; lineNum < _text[idx]._lineCount; ++lineNum) {
				displayText(xp + 5, yCurrent, _text[idx]._lines[lineNum], _text[idx]._color);
				yCurrent += _fontFixedHeight + 1;
			}
		} else {
			int height = _text[idx]._height;
			int width = _text[idx]._width;
			_vm->_graphicsMan->restoreSurfaceRect(
				_vm->_graphicsMan->_frontBuffer,
				_text[idx]._textBlock,
				xp,
				yp,
				_text[idx]._width,
				_text[idx]._height);
			_vm->_graphicsMan->addDirtyRect(xp, yp, xp + width, yp + height);
		}
	} else {
		int lineCount = 0;
		for (int i = 0; i <= 19; i++)
			_textSortArray[i] = 0;

		_text[idx]._textLoadedFl = true;
		Common::String file = filename;
		if (strncmp(file.c_str(), _oldName.c_str(), strlen(file.c_str())) != 0) {
			// Starting to access a new file, so read in the index file for the file
			_oldName = file;
			_indexName = Common::String(file.c_str(), file.size() - 3);
			_indexName += "IND";

			Common::File f;
			if (!f.open(_indexName))
				error("Error opening file - %s", _indexName.c_str());
			int filesize = f.size();
			for (int i = 0; i < (filesize / 4); ++i)
				_index[i] = f.readUint32LE();
			f.close();
		}
		int bufSize;
		if (filename[0] != 'Z' || filename[1] != 'O') {
			Common::File f;
			if (!f.open(file))
				error("Error opening file - %s", _indexName.c_str());

			bufSize = 2048;
			f.seek(_index[messageId]);

			_tempText = _vm->_globals->allocMemory(2058);
			if (_tempText == NULL)
				error("Error allocating text");

			Common::fill(&_tempText[0], &_tempText[2058], 0);
			f.read(_tempText, 2048);
			f.close();
		} else {
			bufSize = 100;
			_tempText = _vm->_globals->allocMemory(110);
			Common::fill(&_tempText[0], &_tempText[110], 0);
			memcpy(_tempText, _zoneText + _index[messageId], 96);
			WRITE_LE_UINT16((uint16 *)_tempText + 48, READ_LE_INT16(_zoneText + _index[messageId] + 96));
		}
		byte *curTempTextPtr = _tempText;
		for (int i = 0; i < bufSize; i++) {
			byte curChar = *curTempTextPtr;
			if ((byte)(*curTempTextPtr + 46) > 27) {
				if ((byte)(curChar + 80) > 27) {
					if ((byte)(curChar - 65) <= 25 || (byte)(curChar - 97) <= 25)
						curChar = 32;
				} else {
					curChar -= 79;
				}
			} else {
				curChar += 111;
			}
			*curTempTextPtr = curChar;
			curTempTextPtr++;
		};

		int textLength;
		for (textLength = 0; textLength < bufSize; textLength++) {
			byte curChar = _tempText[textLength];
			if (curChar == '\r' || curChar == '\n') {
				_tempText[textLength] = 0;
				if (!_text[idx]._length)
					break;
			}
		}

		if (bufSize && bufSize > textLength) {
			_text[idx]._length = textLength;
			_boxWidth = 0;

			for (int curStrIdx = 0; curStrIdx < textLength + 1; curStrIdx++) {
				byte curChar = _tempText[curStrIdx];
				if (curChar <= 31)
					curChar = ' ';
				_boxWidth += _vm->_objectsMan->getWidth(_font, curChar - 32);
			}

			_boxWidth += 2;
			_text[idx]._pos.x = 320 - abs(_boxWidth / 2);
			textPosX = _vm->_events->_startPos.x + _text[idx]._pos.x;
			lineCount = 1;
			_text[idx]._lines[0] = Common::String((const char *)_tempText, textLength);
		} else {
			if (!_boxWidth)
				_boxWidth = 240;
			int tempTextIdx = 0;
			int lineSize;
			byte curChar;
			do {
				int curLineSize = 0;
				int ptrb = _boxWidth - 4;
				for (;;) {
					lineSize = curLineSize;
					do {
						curChar = _tempText[tempTextIdx + curLineSize++];
					} while (curChar != ' ' && curChar != '%');
					if (curLineSize >= ptrb / _fontFixedWidth) {
						if (curChar == '%')
							curChar = ' ';
						break;
					}
					if (curChar == '%') {
						lineSize = curLineSize;
						break;
					}
				}

				// WORKAROUND: Perhaps due to the usage of ScummVM strings here, recalculate what the
				// actual length of the line to be copied will be. Otherwise, you can see artifacts,
				// such as a single character beyond the end of string NULL.
				int actualSize = 0;
				while (actualSize < lineSize && _tempText[tempTextIdx + actualSize])
					++actualSize;

				_text[idx]._lines[lineCount] = Common::String((const char *)_tempText + tempTextIdx, actualSize);
				_textSortArray[lineCount++] = lineSize;

				tempTextIdx += lineSize;
			} while (curChar != '%');

			for (int i = 0; i <= 19; i++) {
				if (_textSortArray[i] <= 0) {
					_textSortArray[i] = 0;
				} else {
					int ptrc = 0;
					for (int curIdx = 0; curIdx < _textSortArray[i] - 1; curIdx++) {
						Common::String &line = _text[idx]._lines[i];
						byte curChar2 = (curIdx >= (int)line.size()) ? '\0' : line.c_str()[curIdx];
						if (curChar2 <= 31)
							curChar2 = ' ';
						ptrc += _vm->_objectsMan->getWidth(_font, (byte)curChar2 - 32);
					}
					_textSortArray[i] = ptrc;
				}
			}
			for (int i = 0; i <= 19; i++) {
				for (int j = i + 1; j != i; j = (j + 1) % 20) {
					if (_textSortArray[i] < _textSortArray[j])
						_textSortArray[i] = 0;
				}
			};

			for (int i = 0; i <= 19; i++) {
				if (_textSortArray[i])
					_boxWidth = _textSortArray[i];
			}

			if ((_text[idx]._textType < 2) || (_text[idx]._textType > 3)) {
				int i;
				for (i = xp - _vm->_events->_startPos.x; _boxWidth + i > 638 && i > -2 && _text[idx]._textType; i -= 2)
					;
				_text[idx]._pos.x = i;
				textPosX = _vm->_events->_startPos.x + i;
			} else {
				_text[idx]._pos.x = textPosX;
			}
		}
		int posX = textPosX;
		int posY = yp;
		int saveWidth = _boxWidth + 10;
		int saveHeight = (_fontFixedHeight + 1) * lineCount + 12;
		if (_text[idx]._textType == 6) {
			_text[idx]._pos.x = 315 - abs(saveWidth / 2);
			textPosX = posX = _vm->_events->_startPos.x + _text[idx]._pos.x;
			_text[idx]._pos.y = posY = 50;
		}
		int textType = _text[idx]._textType;
		if (textType == 1 || textType == 3 || textType == 5 || textType == 6) {
			int size = saveHeight * saveWidth;
			byte *ptrd = _vm->_globals->allocMemory(size);
			if (ptrd == NULL)
				error("Cutting a block for text box (%d)", size);

			_vm->_graphicsMan->copySurfaceRect(_vm->_graphicsMan->_frontBuffer, ptrd, posX, posY, saveWidth, saveHeight);
			_vm->_graphicsMan->fillSurface(ptrd, _vm->_graphicsMan->_colorTable, size);
			_vm->_graphicsMan->restoreSurfaceRect(_vm->_graphicsMan->_frontBuffer, ptrd, posX, posY, saveWidth, saveHeight);
			_vm->_globals->freeMemory(ptrd);

			_vm->_graphicsMan->drawHorizontalLine(_vm->_graphicsMan->_frontBuffer, posX, posY, saveWidth, (byte)-2);
			_vm->_graphicsMan->drawHorizontalLine(_vm->_graphicsMan->_frontBuffer, posX, saveHeight + posY, saveWidth, (byte)-2);
			_vm->_graphicsMan->drawVerticalLine(_vm->_graphicsMan->_frontBuffer, posX, posY, saveHeight, (byte)-2);
			_vm->_graphicsMan->drawVerticalLine(_vm->_graphicsMan->_frontBuffer, saveWidth + posX, posY, saveHeight, (byte)-2);
		}
		_text[idx]._lineCount = lineCount;
		int textPosY = posY + 5;

		for (int lineNum = 0; lineNum < lineCount; ++lineNum) {
			displayText(textPosX + 5, textPosY, _text[idx]._lines[lineNum], _text[idx]._color);
			textPosY += _fontFixedHeight + 1;
		}

		int blockWidth = saveWidth + 1;
		int blockHeight = saveHeight + 1;

		_text[idx]._width = blockWidth;
		_text[idx]._height = blockHeight;
		textType = _text[idx]._textType;
		if (textType == 6 || textType == 1 || textType == 3 || textType == 5) {
			_text[idx]._textBlock = _vm->_globals->freeMemory(_text[idx]._textBlock);
			int blockSize = blockHeight * blockWidth;
			byte *ptre = _vm->_globals->allocMemory(blockSize + 20);
			if (ptre == NULL)
				error("Cutting a block for text box (%d)", blockSize);

			_text[idx]._textBlock = ptre;
			_text[idx]._width = blockWidth;
			_text[idx]._height = blockHeight;
			_vm->_graphicsMan->copySurfaceRect(_vm->_graphicsMan->_frontBuffer, _text[idx]._textBlock, posX, posY, _text[idx]._width, blockHeight);
		}
		_tempText = _vm->_globals->freeMemory(_tempText);
	}
}
Esempio n. 25
0
void Memory::writeUint16(int seg, uint16_t offset, uint16_t value) {
	uint8_t *p = (uint8_t *)getPtr(seg, offset);
if (_debug) fprintf(stdout, "Memory::writeUint16 %X\n", value);
	WRITE_LE_UINT16(p, value);
}
Esempio n. 26
0
byte *Sword2Engine::fetchPsxParallax(uint32 location, uint8 level) {
	Common::File file;
	PSXScreensEntry header;
	uint32 screenOffset;
	uint16 horTiles; // Number of horizontal tiles in the parallax grid
	uint16 verTiles; // Number of vertical tiles in parallax grid
	uint32 totSize; // Total size of parallax, counting data, grid, and additional header
	byte *buffer;

	uint16 plxXres;
	uint16 plxYres;
	uint32 plxOffset;
	uint32 plxSize;

	if (level > 1)
		return NULL;

	if (!file.open("screens.clu")) {
		GUIErrorMessage("Broken Sword 2: Cannot open screens.clu");
		return NULL;
	}

	file.seek(location * 4, SEEK_SET);
	screenOffset = file.readUint32LE();

	if (screenOffset == 0) // There is no screen here
		return NULL;

	// Get to the beginning of PSXScreensEntry
	file.seek(screenOffset + ResHeader::size(), SEEK_SET);

	buffer = (byte *)malloc(PSXScreensEntry::size());
	file.read(buffer, PSXScreensEntry::size());

	// Initialize the header
	header.read(buffer);
	free(buffer);

	// We are fetching...
	if (level == 0) { // a background parallax
		plxXres = header.bgPlxXres;
		plxYres = header.bgPlxYres;
		plxOffset = header.bgPlxOffset;
		plxSize = header.bgPlxSize;
	} else {  // a foreground parallax
		plxXres = header.fgPlxXres;
		plxYres = header.fgPlxYres;
		plxOffset = header.fgPlxOffset;
		plxSize = header.fgPlxSize;
	}

	if (plxXres == 0 || plxYres == 0 || plxSize == 0) // This screen has no parallax data.
		return NULL;

	debug(2, "fetchPsxParallax() -> %s parallax, xRes: %u, yRes: %u", (level == 0) ? "Background" : "Foreground", plxXres, plxYres);

	// Calculate the number of tiles which compose the parallax grid.
	horTiles = plxXres % 64 ? (plxXres / 64) + 1 : plxXres / 64;
	verTiles = plxYres % 16 ? (plxYres / 16) + 1 : plxYres / 16;

	totSize = plxSize + horTiles * verTiles * 4 + 8;

	file.seek(screenOffset + plxOffset, SEEK_SET);
	buffer = (byte *)malloc(totSize);

	// Insert parallax resolution information in the buffer,
	// preceding parallax data.
	WRITE_LE_UINT16(buffer, plxXres);
	WRITE_LE_UINT16(buffer + 2, plxYres);
	WRITE_LE_UINT16(buffer + 4, horTiles);
	WRITE_LE_UINT16(buffer + 6, verTiles);

	// Read parallax data from file and store it inside the buffer,
	// skipping the generated header.
	file.read(buffer + 8, totSize - 8);
	file.close();

	return buffer;
}
Esempio n. 27
0
void rec_bytecode(TProtoFunc* func, int* inst) {
	int n_op = num_opcodes(func);
	int i, newsize;
	Opcode *opcode_list = luaM_newvector(n_op, Opcode);

	Byte* p = func->code;

	//Change const index
	i = 0;
	newsize = 0;
	while (1) {
		p += INFO(func, p, &opcode_list[i]);
		Opcode &op = opcode_list[i];

		//Change const index, if needed
		if (op.op_class == PUSHCONSTANT ||
			op.op_class == GETGLOBAL ||
			op.op_class == SETGLOBAL ||
			op.op_class == GETDOTTED ||
			op.op_class == PUSHSELF)
			if (op.arg != inst[op.arg]) {
				op.arg = inst[op.arg];
				fix_op(&op);
			}

		newsize += op.size;
		++i;
		if (op.op == ENDCODE)
			break;
	}

	luaM_free(func->code);
	Byte *code = (Byte*)luaM_malloc(newsize);
	func->code = code;

	//Compile bytecode
	Byte out[4];

	//Out stacksize and arguments number
	code[0] = (byte)opcode_list[0].arg;
	if (opcode_list[1].op == VARARGS)
		code[1] = (byte)opcode_list[1].arg + ZEROVARARG;
	else
		code[1] = (byte)opcode_list[1].arg;
	code += 2;

	for (i = 2; i < n_op; ++i) {
		Opcode &op = opcode_list[i];

		//Out opcode
		out[0] = (byte)op.op;

		//Out args
		if (op.op == SETLIST || op.op == CLOSURE || op.op == CALLFUNC) {
			out[1] = (byte)op.arg;
			out[2] = (byte)op.arg2;
		}
		else if (op.size == 2)
			out[1] = (byte)op.arg;
		else if (op.size >= 3)
			WRITE_LE_UINT16(out + 1, op.arg);
		if (op.op == SETLISTW)
			out[3] = (byte)op.arg2;

		memcpy(code, out, op.size);
		code += op.size;
	}

	luaM_free(opcode_list);
}
Esempio n. 28
0
void ToltecsEngine::walk(byte *walkData) {
	int16 xdelta, ydelta, v8, v10, v11;
	int16 xstep, ystep;
	ScriptWalk walkInfo;

	walkInfo.y = READ_LE_UINT16(walkData + 0);
	walkInfo.x = READ_LE_UINT16(walkData + 2);
	walkInfo.y1 = READ_LE_UINT16(walkData + 4);
	walkInfo.x1 = READ_LE_UINT16(walkData + 6);
	walkInfo.y2 = READ_LE_UINT16(walkData + 8);
	walkInfo.x2 = READ_LE_UINT16(walkData + 10);
	walkInfo.yerror = READ_LE_UINT16(walkData + 12);
	walkInfo.xerror = READ_LE_UINT16(walkData + 14);
	walkInfo.mulValue = READ_LE_UINT16(walkData + 16);
	walkInfo.scaling = READ_LE_UINT16(walkData + 18);

	walkInfo.scaling = -_segmap->getScalingAtPoint(walkInfo.x, walkInfo.y);

	if (walkInfo.y1 < walkInfo.y2)
		ystep = -1;
	else
		ystep = 1;
	ydelta = ABS(walkInfo.y1 - walkInfo.y2) * _walkSpeedY;

	if (walkInfo.x1 < walkInfo.x2)
		xstep = -1;
	else
		xstep = 1;
	xdelta = ABS(walkInfo.x1 - walkInfo.x2) * _walkSpeedX;

	debug(0, "ToltecsEngine::walk() xdelta = %d; ydelta = %d", xdelta, ydelta);

	if (xdelta > ydelta)
		SWAP(xdelta, ydelta);

	v8 = 100 * xdelta;
	if (v8 != 0) {
		if (walkInfo.scaling > 0)
			v8 -= v8 * ABS(walkInfo.scaling) / 100;
		else
			v8 += v8 * ABS(walkInfo.scaling) / 100;
		if (ydelta != 0)
			v8 /= ydelta;
	}

	if (ydelta > ABS(walkInfo.x1 - walkInfo.x2) * _walkSpeedX) {
		v10 = 100 - walkInfo.scaling;
		v11 = v8;
	} else {
		v10 = v8;
		v11 = 100 - walkInfo.scaling;
	}

	walkInfo.yerror += walkInfo.mulValue * v10;
	while (walkInfo.yerror >= 100 * _walkSpeedY) {
		walkInfo.yerror -= 100 * _walkSpeedY;
		if (walkInfo.y == walkInfo.y1) {
			walkInfo.x = walkInfo.x1;
			break;
		}
		walkInfo.y += ystep;
	}

	walkInfo.xerror += walkInfo.mulValue * v11;
	while (walkInfo.xerror >= 100 * _walkSpeedX) {
		walkInfo.xerror -= 100 * _walkSpeedX;
		if (walkInfo.x == walkInfo.x1) {
			walkInfo.y = walkInfo.y1;
			break;
		}
		walkInfo.x += xstep;
	}

	WRITE_LE_UINT16(walkData + 0, walkInfo.y);
	WRITE_LE_UINT16(walkData + 2, walkInfo.x);
	WRITE_LE_UINT16(walkData + 4, walkInfo.y1);
	WRITE_LE_UINT16(walkData + 6, walkInfo.x1);
	WRITE_LE_UINT16(walkData + 8, walkInfo.y2);
	WRITE_LE_UINT16(walkData + 10, walkInfo.x2);
	WRITE_LE_UINT16(walkData + 12, walkInfo.yerror);
	WRITE_LE_UINT16(walkData + 14, walkInfo.xerror);
	WRITE_LE_UINT16(walkData + 16, walkInfo.mulValue);
	WRITE_LE_UINT16(walkData + 18, walkInfo.scaling);
}
Esempio n. 29
0
void WRITE_SCIENDIAN_UINT16(void *ptr, uint16 val) {
	if (g_sci->isBE())
		WRITE_BE_UINT16(ptr, val);
	else
		WRITE_LE_UINT16(ptr, val);
}
Esempio n. 30
0
BitmapPtr Bitmap::code(uint8 *map) {
	if (!map)
		return nullptr;

	uint16 cnt;

	if (_v) {                                        // old X-map exists, so remove it
		delete[] _v;
		_v = nullptr;
	}

	while (true) {                                  // at most 2 times: for (V == NULL) & for allocated block;
		uint8 *im = _v + 2;
		uint16 *cp = (uint16 *) _v;

		if (_v) {                                      // 2nd pass - fill the hide table
			for (uint i = 0; i < _h; i++) {
				_b[i]._skip = 0xFFFF;
				_b[i]._hide = 0x0000;
			}
		}
		for (int bpl = 0; bpl < 4; bpl++) {              // once per each bitplane
			uint8 *bm = map;
			bool skip = (bm[bpl] == kPixelTransp);
			uint16 j;

			cnt = 0;
			for (uint i = 0; i < _h; i++) {                  // once per each line
				uint8 pix;
				for (j = bpl; j < _w; j += 4) {
					pix = bm[j];
					if (_v && (pix != kPixelTransp)) {
						if (j < _b[i]._skip)
							_b[i]._skip = j;

						if (j >= _b[i]._hide)
							_b[i]._hide = j + 1;
					}
					if (((pix == kPixelTransp) != skip) || (cnt >= 0x3FF0)) { // end of block
						cnt |= (skip) ? kBmpSKP : kBmpCPY;
						if (_v)
							WRITE_LE_UINT16(cp, cnt); // store block description uint16

						cp = (uint16 *) im;
						im += 2;
						skip = (pix == kPixelTransp);
						cnt = 0;
					}
					if (!skip) {
						if (_v)
							*im = pix;
						im++;
					}
					cnt++;
				}

				bm += _w;
				if (_w < kScrWidth) {
					if (skip)
						cnt += (kScrWidth - j + 3) / 4;
					else {
						cnt |= kBmpCPY;
						if (_v)
							WRITE_LE_UINT16(cp, cnt);

						cp = (uint16 *) im;
						im += 2;
						skip = true;
						cnt = (kScrWidth - j + 3) / 4;
					}
				}
			}
			if (cnt && ! skip) {
				cnt |= kBmpCPY;
				if (_v)
					WRITE_LE_UINT16(cp, cnt);

				cp = (uint16 *) im;
				im += 2;
			}
			if (_v)
				WRITE_LE_UINT16(cp, kBmpEOI);
			cp = (uint16 *) im;
			im += 2;
		}
		if (_v)
			break;

		uint16 sizV = (uint16)(im - 2 - _v);
		_v = new uint8[sizV + _h * sizeof(*_b)];
		_b = (HideDesc *)(_v + sizV);
	}
	cnt = 0;
	for (uint i = 0; i < _h; i++) {
		if (_b[i]._skip == 0xFFFF) {                    // whole line is skipped
			_b[i]._skip = (cnt + kScrWidth) >> 2;
			cnt = 0;
		} else {