void removeBackgroundIncrust(int overlay, int idx, backgroundIncrustStruct * pHead) {
	objectParamsQuery params;
	int var_4;
	int var_6;

	backgroundIncrustStruct *pCurrent;
	backgroundIncrustStruct *pCurrentHead;

	getMultipleObjectParam(overlay, idx, &params);

	var_4 = params.X;
	var_6 = params.Y;

	pCurrent = pHead->next;

	while (pCurrent) {
		if ((pCurrent->overlayIdx == overlay || overlay == -1) && (pCurrent->objectIdx == idx || idx == -1) && (pCurrent->X == var_4) && (pCurrent->Y == var_6)) {
			pCurrent->type = - 1;
		}

		pCurrent = pCurrent->next;
	}

	pCurrentHead = pHead;
	pCurrent = pHead->next;

	while (pCurrent) {
		if (pCurrent->type == - 1) {
			backgroundIncrustStruct *pNext = pCurrent->next;
			backgroundIncrustStruct *bx = pCurrentHead;
			backgroundIncrustStruct *cx;

			bx->next = pNext;
			cx = pNext;

			if (!pNext) {
				cx = pHead;
			}

			bx = cx;
			bx->prev = pCurrent->next;

			if (pCurrent->ptr) {
				MemFree(pCurrent->ptr);
			}

			MemFree(pCurrent);

			pCurrent = pNext;
		} else {
			pCurrentHead = pCurrent;
			pCurrent = pCurrent->next;
		}
	}
}
Esempio n. 2
0
int16 Op_AutoCell() {
	cellStruct *pObject;

	int signal = popVar();
	int loop = popVar();
	int wait = popVar();
	int animStep = popVar();
	int end = popVar();
	int start = popVar();
	int type = popVar();
	int change = popVar();
	int obj = popVar();
	int overlay = popVar();

	if (!overlay)
		overlay = currentScriptPtr->overlayNumber;

	pObject = addCell(&cellHead, overlay, obj, 4, masterScreen, currentScriptPtr->overlayNumber, currentScriptPtr->scriptNumber, currentScriptPtr->type);

	if (!pObject)
		return 0;

	pObject->animSignal = signal;
	pObject->animLoop = loop;
	pObject->animWait = wait;
	pObject->animStep = animStep;
	pObject->animEnd = end;
	pObject->animStart = start;
	pObject->animType = type;
	pObject->animChange = change;

	if (type) {
		if (currentScriptPtr->type == scriptType_PROC) {
			changeScriptParamInList(currentScriptPtr->overlayNumber, currentScriptPtr->scriptNumber, &procHead, -1, 9996);
		} else if (currentScriptPtr->type == scriptType_REL) {
			changeScriptParamInList(currentScriptPtr->overlayNumber, currentScriptPtr->scriptNumber, &relHead, -1, 9996);
		}
	}

	if (change == 5) {
		objInit(pObject->overlay, pObject->idx, start);
	} else {
		setObjectPosition(pObject->overlay, pObject->idx, pObject->animChange, start);
	}

	if (wait < 0) {
		objectParamsQuery params;

		getMultipleObjectParam(overlay, obj, &params);
		pObject->animCounter = params.state2 - 1;
	}

	return 0;
}
Esempio n. 3
0
int16 Op_Sizeof() {
	objectParamsQuery params;
	int index = popVar();
	int overlay = popVar();

	if (!overlay)
		overlay = currentScriptPtr->overlayNumber;

	getMultipleObjectParam(overlay, index, &params);

	return params.nbState - 1;
}
Esempio n. 4
0
// add animation
int16 Op_AddAnimation() {
	int stepY = popVar();
	int stepX = popVar();
	int direction = popVar();
	int start = popVar();
	int type = popVar();
	int obj = popVar();
	int overlay = popVar();

	if (!overlay) {
		overlay = currentScriptPtr->overlayNumber;
	}

	if (direction >= 0 && direction <= 3) {
		actorStruct *si;

		si = addAnimation(&actorHead, overlay, obj, direction, type);

		if (si) {
			objectParamsQuery params;

			getMultipleObjectParam(overlay, obj, &params);

			si->x = params.X;
			si->y = params.Y;
			si->x_dest = -1;
			si->y_dest = -1;
			si->endDirection = -1;
			si->start = start;
			si->stepX = stepX;
			si->stepY = stepY;

			int newFrame = ABS(actor_end[direction][0]) - 1;

			int zoom = computeZoom(params.Y);

			if (actor_end[direction][0] < 0) {
				zoom = -zoom;
			}

			getPixel(params.X, params.Y);

			setObjectPosition(overlay, obj, 3, newFrame + start);
			setObjectPosition(overlay, obj, 4, zoom);
			setObjectPosition(overlay, obj, 5, numPoly);

			animationStart = false;
		}
	}

	return 0;
}
Esempio n. 5
0
/**
 * Preliminary command to list the currently loaded hotspots
 */
bool Debugger::cmd_hotspots(int argc, const char **argv) {
	const char *pObjType;
	objectParamsQuery params;

	cellStruct *currentObject = cellHead.prev;

	while (currentObject) {
		if (currentObject->overlay > 0 && overlayTable[currentObject->overlay].alreadyLoaded &&
			(currentObject->type == OBJ_TYPE_SPRITE || currentObject->type == OBJ_TYPE_MASK ||
			currentObject->type == OBJ_TYPE_EXIT || currentObject->type == OBJ_TYPE_VIRTUAL)) {
			const char *pObjectName = getObjectName(currentObject->idx, overlayTable[currentObject->overlay].ovlData->arrayNameObj);

			switch (currentObject->type) {
			case OBJ_TYPE_SPRITE:
				pObjType = "SPRITE";
				break;
			case OBJ_TYPE_MASK:
				pObjType = "MASK";
				break;
			case OBJ_TYPE_EXIT:
				pObjType = "EXIT";
				break;
			case OBJ_TYPE_VIRTUAL:
				pObjType = "VIRTUAL";
				break;
			default:
				pObjType = "UNKNOWN";
				break;
			}

			if (*pObjectName) {
				getMultipleObjectParam(currentObject->overlay, currentObject->idx, &params);

				DebugPrintf("%s %s - %d,%d\n", pObjectName, pObjType, params.X, params.Y);
			}
		}

		currentObject = currentObject->prev;
	}

	return true;
}
void unmergeBackgroundIncrust(backgroundIncrustStruct * pHead, int ovl, int idx) {
	backgroundIncrustStruct *pl;
	backgroundIncrustStruct *pl2;

	objectParamsQuery params;
	getMultipleObjectParam(ovl, idx, &params);

	int x = params.X;
	int y = params.Y;

	pl = pHead;
	pl2 = pl;
	pl = pl2->next;

	while (pl) {
		pl2 = pl;
		if ((pl->overlayIdx == ovl) || (ovl == -1))
			if ((pl->objectIdx == idx) || (idx == -1))
				if ((pl->X == x) && (pl->Y == y))
					restoreBackground(pl);

		pl = pl2->next;
	}
}
Esempio n. 7
0
/**
 * Handles the processing of any active actors to allow for handling movement
 */
void processAnimation() {
	objectParamsQuery params;
	MovementEntry moveInfo;
	actorStruct *currentActor = actorHead.next;
	actorStruct *nextActor;

	while (currentActor) {
		nextActor = currentActor->next;

		if (!currentActor->freeze && ((currentActor->type == ATP_MOUSE) || (currentActor->type == 1))) {
			getMultipleObjectParam(currentActor->overlayNumber, currentActor->idx, &params);

			if (((animationStart && !currentActor->flag) || (!animationStart && currentActor->x_dest != -1
					&& currentActor->y_dest != -1)) && (currentActor->type == ATP_MOUSE)) {
				// mouse animation
				if (!animationStart) {
					aniX = currentActor->x_dest;
					aniY = currentActor->y_dest;
					currentActor->x_dest = -1;
					currentActor->y_dest = -1;

					currentActor->flag = 1;
				}

				currentActor->pathId = computePathfinding(moveInfo, params.X, params.Y,
					aniX, aniY, currentActor->stepX, currentActor->stepY, currentActor->pathId);

				if (currentActor->pathId == ANIM_WAIT) {
					if ((currentActor->endDirection != -1) && (currentActor->endDirection != currentActor->startDirection)) {
						currentActor->phase = ANIM_PHASE_STATIC_END;
						currentActor->nextDirection = currentActor->endDirection;
						currentActor->endDirection = -1;
						currentActor->counter = 0;
					} else {
						currentActor->pathId = ANIM_FINISH;
						currentActor->flag = 0;
						currentActor->endDirection = -1;
						currentActor->phase = ANIM_PHASE_WAIT;
					}
				} else {
					currentActor->phase = ANIM_PHASE_STATIC;
					currentActor->counter = -1;
				}
			} else
				if ((currentActor->type == 1) && (currentActor->x_dest != -1) && (currentActor->y_dest != -1)) {
					// track animation
					currentActor->pathId = computePathfinding(moveInfo, params.X, params.Y, currentActor->x_dest, currentActor->y_dest, currentActor->stepX, currentActor->stepY, currentActor->pathId);

					currentActor->x_dest = -1;
					currentActor->y_dest = -1;

					if (currentActor->pathId == ANIM_WAIT) {
						if ((currentActor->endDirection != -1) && (currentActor->endDirection != currentActor->startDirection)) {
							currentActor->phase = ANIM_PHASE_STATIC_END;
							currentActor->nextDirection = currentActor->endDirection;
							currentActor->endDirection = -1;
							currentActor->counter = 0;
						} else {
							currentActor->pathId = -2;
							currentActor->flag = 0;
							currentActor->endDirection = -1;
							currentActor->phase = ANIM_PHASE_WAIT;
						}
					} else {
						currentActor->phase = ANIM_PHASE_STATIC;
						currentActor->counter = -1;
					}
				}

			animationStart = false;

			if ((currentActor->pathId >= 0) || (currentActor->phase == ANIM_PHASE_STATIC_END)) {

				// Main switch statement for handling various phases of movement
				// IMPORTANT: This switch relies on falling through cases in certain circumstances
				// , so 'break' statements should *not* be used at the end of case areas
				switch (currentActor->phase) {
				case ANIM_PHASE_STATIC_END:
				case ANIM_PHASE_STATIC:
				{
					// In-place (on the spot) animationos

					if ((currentActor->counter == -1) && (currentActor->phase == ANIM_PHASE_STATIC)) {
						affiche_chemin(currentActor->pathId, moveInfo);

						if (moveInfo.x == -1) {
							currentActor->pathId = ANIM_FINISH;
							currentActor->flag = 0;
							currentActor->endDirection = -1;
							currentActor->phase = ANIM_PHASE_WAIT;
							break;
						}

						currentActor->x = moveInfo.x;
						currentActor->y = moveInfo.y;
						currentActor->nextDirection = moveInfo.direction;
						currentActor->poly = moveInfo.poly;
						currentActor->counter = 0;

						if (currentActor->startDirection == currentActor->nextDirection)
							currentActor->phase = ANIM_PHASE_MOVE;
					}

					if ((currentActor->counter >= 0)
					        && ((currentActor->phase == ANIM_PHASE_STATIC_END)
					            || (currentActor->phase == ANIM_PHASE_STATIC))) {
						int newA;
						int inc = 1;
						int t_inc = currentActor->startDirection - 1;

						if (t_inc < 0)
							t_inc = 3;

						if (currentActor->nextDirection == t_inc)
							inc = -1;

						if (inc > 0)
							newA = actor_stat[currentActor->startDirection][currentActor->counter++];
						else
							newA = actor_invstat[currentActor->startDirection][currentActor->counter++];

						if (newA == 0) {
							currentActor->startDirection = currentActor->startDirection + inc;

							if (currentActor->startDirection > 3)
								currentActor->startDirection = 0;

							if (currentActor->startDirection < 0)
								currentActor-> startDirection = 3;

							currentActor->counter = 0;

							if (currentActor->startDirection == currentActor->nextDirection) {
								if (currentActor->phase == ANIM_PHASE_STATIC)
									currentActor->phase = ANIM_PHASE_MOVE;
								else
									currentActor->phase = ANIM_PHASE_END;
							} else {
								newA = actor_stat[currentActor->startDirection][currentActor->counter++];

								if (inc == -1)
									newA = -newA;

								set_anim(currentActor->overlayNumber, currentActor->idx,
									currentActor->start, params.X, params.Y, newA, currentActor->poly);
								break;
							}
						} else {
							set_anim(currentActor->overlayNumber,currentActor->idx, currentActor->start,
								params.X, params.Y, newA, currentActor->poly);
							break;
						}
					}
				}

				case ANIM_PHASE_MOVE:
				{
					// Walk animations

					if (currentActor->counter >= 1) {
						affiche_chemin(currentActor->pathId, moveInfo);

						if (moveInfo.x == -1) {
							if ((currentActor->endDirection == -1) || (currentActor->endDirection == currentActor->nextDirection)) {
								currentActor->phase = ANIM_PHASE_END;
							} else {
								currentActor->phase = ANIM_PHASE_STATIC_END;
								currentActor->nextDirection = currentActor->endDirection;
							}
							currentActor->counter = 0;
							break;
						} else {
							currentActor->x = moveInfo.x;
							currentActor->y = moveInfo.y;
							currentActor->nextDirection = moveInfo.direction;
							currentActor->poly = moveInfo.poly;
						}
					}

					if (currentActor->phase == ANIM_PHASE_MOVE) {
						int newA;

						currentActor->startDirection = currentActor->nextDirection;

						newA = actor_move[currentActor->startDirection][currentActor->counter++];
						if (!newA) {
							currentActor->counter = 0;
							newA = actor_move[currentActor->startDirection][currentActor->counter++];
						}
						set_anim(currentActor->overlayNumber, currentActor->idx, currentActor->start,
							currentActor->x, currentActor->y, newA, currentActor->poly);
						break;
					}
				}

				case ANIM_PHASE_END:
				{
					// End of walk animation

					int newA = actor_end[currentActor->startDirection][0];

					set_anim(currentActor->overlayNumber, currentActor->idx, currentActor->start,
						currentActor->x, currentActor->y, newA, currentActor->poly);

					currentActor->pathId = ANIM_FINISH;
					currentActor->phase = ANIM_PHASE_WAIT;
					currentActor->flag = 0;
					currentActor->endDirection = -1;
					break;
				}
				default: {
					warning("Unimplemented currentActor->phase=%d in processAnimation()", currentActor->phase);
					// exit(1);
				}
				}
			}
		}

		currentActor = nextActor;
	}
}
Esempio n. 8
0
int findObject(int mouseX, int mouseY, int *outObjOvl, int *outObjIdx) {
	char objectName[80];

	cellStruct *currentObject = cellHead.prev;

	while (currentObject) {
		if (currentObject->overlay > 0 && overlayTable[currentObject->overlay].alreadyLoaded &&
				(currentObject->type == OBJ_TYPE_SPRITE || currentObject->type == OBJ_TYPE_MASK ||
				currentObject->type == OBJ_TYPE_EXIT || currentObject->type == OBJ_TYPE_VIRTUAL)) {
			const char* pObjectName = getObjectName(currentObject->idx, overlayTable[currentObject->overlay].ovlData->arrayNameObj);

			strcpy(objectName, pObjectName);

			if (strlen(objectName) && (currentObject->freeze == 0)) {
				int objIdx = currentObject->idx;
				int objOvl = currentObject->overlay;
				int linkedObjIdx = currentObject->followObjectIdx;
				int linkedObjOvl = currentObject->followObjectOverlayIdx;

				objectParamsQuery params;
				getMultipleObjectParam(objOvl, objIdx, &params);

				int x2 = 0;
				int y2 = 0;
				int j2 = 0;

				if ((objOvl != linkedObjOvl) || (objIdx != linkedObjIdx)) {
					objectParamsQuery params2;
					getMultipleObjectParam(linkedObjOvl, linkedObjIdx, &params2);

					x2 = params2.X;
					y2 = params2.Y;
					j2 = params2.fileIdx;
				}

				if (params.state >= 0 && params.fileIdx >= 0) {
					if (currentObject->type == OBJ_TYPE_SPRITE || currentObject->type == OBJ_TYPE_MASK || currentObject->type == OBJ_TYPE_EXIT) {
						int x = params.X + x2;
						int y = params.Y + y2;
						int j = params.fileIdx;

						if (j >= 0) {
							j += j2;
						}

						if ((filesDatabase[j].subData.resourceType == OBJ_TYPE_POLY) && (filesDatabase[j].subData.ptr)) {
							int zoom = params.scale;

							int16* dataPtr = (int16*)filesDatabase[j].subData.ptr;

							if (*dataPtr == 0) {
								int16 offset;
								int16 newX;
								int16 newY;

								dataPtr ++;

								offset = (int16)READ_BE_UINT16(dataPtr);
								dataPtr++;

								newX = (int16)READ_BE_UINT16(dataPtr);
								dataPtr++;

								newY = (int16)READ_BE_UINT16(dataPtr);
								dataPtr++;

								offset += j;

								if (offset >= 0) {
									if (filesDatabase[offset].resType == OBJ_TYPE_LINE &&
											filesDatabase[offset].subData.ptr) {
										dataPtr = (int16 *)filesDatabase[offset].subData.ptr;
									}
								}

								zoom = -zoom;
								x -= newX;
								y -= newY;
							}

							if (dataPtr && findPoly((char*)dataPtr, x, y, zoom, mouseX, mouseY)) {
								*outObjOvl = linkedObjOvl;
								*outObjIdx = linkedObjIdx;

								return (currentObject->type);
							}
						} else {
							// int numBitPlanes = filesDatabase[j].resType;

							int nWidth;
							int nHeight;

							nWidth = filesDatabase[j].width;
							nHeight = filesDatabase[j].height;

							int offsetX = mouseX - x;
							int offsetY = mouseY - y;

							if ((offsetX >= 0) && (offsetX < nWidth) && (offsetY >= 0) && (offsetY <= nHeight) && filesDatabase[j].subData.ptr) {
								if (testMask(offsetX, offsetY, filesDatabase[j].subData.ptrMask, filesDatabase[j].width / 8)) {
									*outObjOvl = linkedObjOvl;
									*outObjIdx = linkedObjIdx;
									return currentObject->type;
								}
							}
						}
					} else if (currentObject->type == OBJ_TYPE_VIRTUAL) {
						int x = params.X + x2;
						int y = params.Y + y2;
						int width = params.fileIdx;
						int height = params.scale;

						if ((mouseX >= x) && (mouseX <= x + width) && (mouseY >= y) && (mouseY <= y + height)) {
							*outObjOvl = linkedObjOvl;
							*outObjIdx = linkedObjIdx;

							return (currentObject->type);
						}
					}
				}
			}
		}

		currentObject = currentObject->prev;
	}

	*outObjOvl = 0;
	*outObjIdx = 0;

	return -1;
}
Esempio n. 9
0
void callRelation(menuElementSubStruct *pMenuElement, int nObj2) {
	if (pMenuElement == NULL)
		return;

	menuElementSubStruct* pCurrent = pMenuElement;

	while (pCurrent != NULL) {
		int ovlIdx = pCurrent->ovlIdx;
		int header = pCurrent->header;

		linkDataStruct* pHeader = &overlayTable[ovlIdx].ovlData->arrayMsgRelHeader[header];

		if (pHeader->obj2Number == nObj2) {
			// REL
			if (pHeader->type == RT_REL) {
				if (currentScriptPtr) {
					attacheNewScriptToTail(&relHead, ovlIdx, pHeader->id, 30, currentScriptPtr->scriptNumber, currentScriptPtr->overlayNumber, scriptType_REL);
				} else {
					attacheNewScriptToTail(&relHead, ovlIdx, pHeader->id, 30, 0, 0, scriptType_REL);
				}

				if ((narratorOvl > 0) && (pHeader->trackX != -1) && (pHeader->trackY != -1)) {
					actorStruct* pTrack = findActor(&actorHead, narratorOvl, narratorIdx, 0);

					if (pTrack) {
						animationStart = false;

						if (pHeader->trackDirection == 9999) {
							objectParamsQuery naratorParams;
							getMultipleObjectParam(narratorOvl, narratorIdx, &naratorParams);
							pTrack->x_dest = naratorParams.X;
							pTrack->y_dest = naratorParams.Y;
							pTrack->endDirection = direction(naratorParams.X, naratorParams.Y, pTrack->x_dest, pTrack->y_dest, 0, 0);
						} else if ((pHeader->trackX == 9999) && (pHeader->trackY == 9999)) {
							objectParamsQuery naratorParams;
							getMultipleObjectParam(narratorOvl, narratorIdx, &naratorParams);
							pTrack->x_dest = naratorParams.X;
							pTrack->y_dest = naratorParams.Y;
							pTrack->endDirection = pHeader->trackDirection;
						} else {
							pTrack->x_dest = pHeader->trackX;
							pTrack->y_dest = pHeader->trackY;
							pTrack->endDirection = pHeader->trackDirection;
						}

						pTrack->flag = 1;

						autoTrack = true;
						userEnabled = 0;
						changeScriptParamInList(ovlIdx, pHeader->id, &relHead, 0, 9998);
					}
				}
			} else if (pHeader->type == RT_MSG) { // MSG
				int obj1Ovl = pHeader->obj1Overlay;
				if (!obj1Ovl)
					obj1Ovl = ovlIdx;

				int x = 60;
				int y = 40;

				if (pHeader->obj1Number >= 0) {
					objectParamsQuery params;
					getMultipleObjectParam(obj1Ovl, pHeader->obj1Number, &params);

					if (narratorOvl > 0) {
						if ((pHeader->trackX != -1) && (pHeader->trackY != -1) && (pHeader->trackX != 9999) && (pHeader->trackY != 9999)) {
							x = pHeader->trackX - 100;
							y = pHeader->trackY - 150;
						} else {
							getMultipleObjectParam(narratorOvl, narratorIdx, &params);
							x = params.X - 100;
							y = params.Y - 150;
						}
					} else if (params.scale >= 0) {
						x = params.X - 100;
						y = params.Y - 40;
					}

					if (pHeader->obj1NewState != -1) {
						objInit(obj1Ovl, pHeader->obj1Number, pHeader->obj1NewState);
					}
				}

				if (currentScriptPtr) {
					createTextObject(&cellHead, ovlIdx, pHeader->id, x, y, 200, findHighColor(), masterScreen, currentScriptPtr->overlayNumber, currentScriptPtr->scriptNumber);
				} else {
					createTextObject(&cellHead, ovlIdx, pHeader->id, x, y, 200, findHighColor(), masterScreen, 0, 0);
				}

				userWait = 1;
				autoOvl = ovlIdx;
				autoMsg = pHeader->id;

				if ((narratorOvl > 0) && (pHeader->trackX != -1) && (pHeader->trackY != -1)) {
					actorStruct* pTrack = findActor(&actorHead, narratorOvl, narratorIdx, 0);

					if (pTrack) {
						animationStart = false;

						if (pHeader->trackDirection == 9999) {
							objectParamsQuery naratorParams;
							getMultipleObjectParam(narratorOvl, narratorIdx, &naratorParams);
							pTrack->x_dest = naratorParams.X;
							pTrack->y_dest = naratorParams.Y;
							pTrack->endDirection = direction(naratorParams.X, naratorParams.Y, pTrack->x_dest, pTrack->y_dest, 0, 0);
						} else if ((pHeader->trackX == 9999) && (pHeader->trackY == 9999)) {
							objectParamsQuery naratorParams;
							getMultipleObjectParam(narratorOvl, narratorIdx, &naratorParams);
							pTrack->x_dest = naratorParams.X;
							pTrack->y_dest = naratorParams.Y;
							pTrack->endDirection = pHeader->trackDirection;
						} else {
							pTrack->x_dest = pHeader->trackX;
							pTrack->y_dest = pHeader->trackY;
							pTrack->endDirection = pHeader->trackDirection;
						}

						pTrack->flag = 1;

						autoTrack = true;
						userWait = 0;
						userEnabled = 0;
						freezeCell(&cellHead, ovlIdx, pHeader->id, 5, -1, 0, 9998);
					}
				}
			}
		} else {
			linkedRelation = pMenuElement;
		}

		pCurrent = pCurrent->pNext;
	}
}
Esempio n. 10
0
backgroundIncrustStruct *addBackgroundIncrust(int16 overlayIdx,	int16 objectIdx, backgroundIncrustStruct *pHead, int16 scriptNumber, int16 scriptOverlay, int16 backgroundIdx, int16 saveBuffer) {
	uint8 *backgroundPtr;
	uint8 *ptr;
	objectParamsQuery params;
	backgroundIncrustStruct *newElement;
	backgroundIncrustStruct *currentHead;
	backgroundIncrustStruct *currentHead2;

	getMultipleObjectParam(overlayIdx, objectIdx, &params);

	ptr = filesDatabase[params.fileIdx].subData.ptr;

	// Don't process any further if not a sprite or polygon
	if (!ptr) return NULL;
	if ((filesDatabase[params.fileIdx].subData.resourceType != OBJ_TYPE_SPRITE) &&
		(filesDatabase[params.fileIdx].subData.resourceType != OBJ_TYPE_POLY)) {
		return NULL;
	}

	backgroundPtr = backgroundScreens[backgroundIdx];

	backgroundChanged[backgroundIdx] = true;

	assert(backgroundPtr != NULL);

	currentHead = pHead;
	currentHead2 = currentHead->next;

	while (currentHead2) {
		currentHead = currentHead2;
		currentHead2 = currentHead->next;
	}

	newElement = (backgroundIncrustStruct *)mallocAndZero(sizeof(backgroundIncrustStruct));

	if (!newElement)
		return NULL;

	newElement->next = currentHead->next;
	currentHead->next = newElement;

	if (!currentHead2) {
		currentHead2 = pHead;
	}

	newElement->prev = currentHead2->prev;
	currentHead2->prev = newElement;

	newElement->objectIdx = objectIdx;
	newElement->type = saveBuffer;
	newElement->backgroundIdx = backgroundIdx;
	newElement->overlayIdx = overlayIdx;
	newElement->scriptNumber = scriptNumber;
	newElement->scriptOverlayIdx = scriptOverlay;
	newElement->X = params.X;
	newElement->Y = params.Y;
	newElement->scale = params.scale;
	newElement->frame = params.fileIdx;
	newElement->spriteId = filesDatabase[params.fileIdx].subData.index;
	newElement->ptr = NULL;
	strcpy(newElement->name, filesDatabase[params.fileIdx].subData.name);

	if (filesDatabase[params.fileIdx].subData.resourceType == OBJ_TYPE_SPRITE) {
		// sprite
		int width = filesDatabase[params.fileIdx].width;
		int height = filesDatabase[params.fileIdx].height;
		if (saveBuffer == 1) {
			backupBackground(newElement, newElement->X, newElement->Y, width, height, backgroundPtr);
		}

		drawSprite(width, height, NULL, filesDatabase[params.fileIdx].subData.ptr, newElement->Y,
			newElement->X, backgroundPtr, filesDatabase[params.fileIdx].subData.ptrMask);
	} else {
		// poly
		if (saveBuffer == 1) {
			int newX;
			int newY;
			int newScale;
			char *newFrame;

			int sizeTable[4];	// 0 = left, 1 = right, 2 = bottom, 3 = top

			// this function checks if the dataPtr is not 0, else it retrives the data for X, Y, scale and DataPtr again (OLD: mainDrawSub1Sub1)
			flipPoly(params.fileIdx, (int16 *)filesDatabase[params.fileIdx].subData.ptr, params.scale, &newFrame, newElement->X, newElement->Y, &newX, &newY, &newScale);

			// this function fills the sizeTable for the poly (OLD: mainDrawSub1Sub2)
			getPolySize(newX, newY, newScale, sizeTable, (unsigned char*)newFrame);

			int width = (sizeTable[1] + 2) - (sizeTable[0] - 2) + 1;
			int height = sizeTable[3] - sizeTable[2] + 1;

			backupBackground(newElement, sizeTable[0] - 2, sizeTable[2], width, height, backgroundPtr);
		}

		addBackgroundIncrustSub1(params.fileIdx, newElement->X, newElement->Y, NULL, params.scale, (char *)backgroundPtr, (char *)filesDatabase[params.fileIdx].subData.ptr);
	}

	return newElement;
}