Exemplo n.º 1
0
void callbackThreadFunc(void *arg) {
	u32 eventRes;
	int intrStat;
	IoRequest *req;
	IoRequest reqCopy;

	while (1) {
		WaitEventFlag(callbackEvent, 1, WEF_CLEAR | WEF_OR, &eventRes);
		do {
			CpuSuspendIntr(&intrStat);

			req = cbListStart;
			if (req) {
				if (req->next)
					req->next->prev = req->prev;
				else
					cbListEnd = req->prev;

				if (req->prev)
					req->prev->next = req->next;
				else
					cbListStart = req->next;
			}
			CpuResumeIntr(intrStat);

			if (req) {
				memcpy(&reqCopy, req, sizeof(IoRequest));
				usbdLock();
				freeIoRequest(req);
				usbdUnlock();

				if (reqCopy.userCallbackProc)
				{
					SetGP(req->gpSeg);
					reqCopy.userCallbackProc(reqCopy.resultCode, reqCopy.transferedBytes, reqCopy.userCallbackArg);
					SetGP(&_gp);
				}
			}
		} while (req);
	}
}
Exemplo n.º 2
0
int callUsbDriverFunc(int (*func)(int devId), int devId, void *gp) {
	int res;

	if (func) {
		usbdUnlock();
		ChangeGP(gp);
		res = func(devId);
		SetGP(&_gp);
		usbdLock();
		return res;
	} else
		return 0;
}
Exemplo n.º 3
0
bool DataPipe::Move(const vector3di shf)
{
	vector3di rgp;

	//Check shift vector first
	if ( (abs(shf.X) > 1) || (abs(shf.Y) > 1) || (abs(shf.Z) > 1) )
		return false;

#ifdef DPDEBUG
	dbg_print("[DP] Move(): shift = [%d %d %d]",shf.X,shf.Y,shf.Z);
#endif

	rgp = GP + shf;
	if (rgp.Z == 0) {
		//TODO: Z-thru
	}
	if (wgen)
		wgen->WrapCoords(&rgp);

#if HOLDCHUNKS == 1
	SetGP(rgp);
	return true;

#else /* 9, 18, 27 */
	int l,nl,x,y,z,nx,ny;
	PChunk swa;
	SChunkState swb;

#if HOLDCHUNKS == 9
	if (shf.Z) {
		SetGP(GP+shf);
		return true;
	}

#else /* 18, 27 */
	int nz;

#if HOLDCHUNKS == 18
	if (shf.Z > 0) {
		SetGP(GP+shf);
		return true;
	}

#endif
#endif

	//Lock everything
	WriteLock();
	status = DPIPE_BUSY;
	GP = rgp;

	//Swap remaining chunks and mark new ones
	for (x = 0; x < 3; x++) {
		for (y = 0; y < 3; y++) {
#if HOLDCHUNKS == 18
			for (z = 0; z < 2; z++) {
#else
			for (z = 0; z < 3; z++) {
#endif
				nx = (shf.X < 0)? 2-x:x;
				ny = (shf.Y < 0)? 2-y:y;
#if HOLDCHUNKS > 9
#if HOLDCHUNKS == 27
				nz = (shf.Z < 0)? 2-z:z;
#else
				nz = (shf.Z < 0)? 1-z:z;
#endif
				l = nz * 9 + ny * 3 + nx;
				nl = (nz + shf.Z) * 9 + (ny + shf.Y) * 3 + nx + shf.X;
#else
				l = ny * 3 + nx;
				nl = (ny + shf.Y) * 3 + nx + shf.X;
#endif /* 9 chunks */
				if (	((shf.X > 0) && (nx > 1)) ||
						((shf.X < 0) && (nx < 1)) ||
						((shf.Y > 0) && (ny > 1)) ||
						((shf.Y < 0) && (ny < 1)) ||
#if HOLDCHUNKS > 9
						((shf.Z > 0) && (nz > 1)) ||
						((shf.Z < 0) && (nz < 1)) ||
#endif
						(nl < 0) || (nl >= HOLDCHUNKS)) {
					//new chunk
					chstat[l].s = DPCHK_QUEUE;
#ifdef DPDEBUG
					dbg_print("[DP] Marking chunk %d",l);
#endif
					continue;
				}

#ifdef DPDEBUG
				dbg_print("[DP] Swapping chunks %d <-> %d",l,nl);
#endif
				//swap chunks
				swa = chunks[l];
				chunks[l] = chunks[nl];
				chunks[nl] = swa;

				swb = chstat[l];
				chstat[l] = chstat[nl];
				chstat[nl] = swb;
			}
		}
	}

	//Update models root
	UpdateModelsSceneRoot();

	//Release everything
	status = DPIPE_IDLE;
	WriteUnlock();
	return true;
#endif
}

void DataPipe::ChunkQueue()
{
	if (status != DPIPE_IDLE) return;

#if HOLDCHUNKS == 1
	/* Do nothing */
	return;
#else

	vector3di cur;
	bool fnd = false;
	unsigned l;

	/* Apply soft-lock to not interfere with rendering
	 * while time-consuming loading or generation is
	 * processing.
	 */
	ReadLock();

#if HOLDCHUNKS == 9
	int i,j;
	cur.Z = GP.Z;
	for (i = -1, l = 0; i < 2; i++) {
		cur.Y = GP.Y + i;
		for (j = -1; j < 2; j++, l++) {
			cur.X = GP.X + j;
			if (chstat[l].s == DPCHK_QUEUE) {
				fnd = true;
				goto chunk_found;
			}
		}
	}

#elif HOLDCHUNKS == 18
	int i,j,k;
	for (i = -1, l = 0; i <= 0; i++) {
		cur.Z = GP.Z + i;
		for (j = -1; j < 2; j++) {
			cur.Y = GP.Y + j;
			for (k = -1; k < 2; k++, l++) {
				cur.X = GP.X + k;
				if (chstat[l].s == DPCHK_QUEUE) {
					fnd = true;
					goto chunk_found;
				}
			}
		}
	}

#elif HOLDCHUNKS == 27
	int i,j,k;
	for (i = -1, l = 0; i < 2; i++) {
		cur.Z = GP.Z + i;
		for (j = -1; j < 2; j++) {
			cur.Y = GP.Y + j;
			for (k = -1; k < 2; k++, l++) {
				cur.X = GP.X + k;
				if (chstat[l].s == DPCHK_QUEUE) {
					fnd = true;
					goto chunk_found;
				}
			}
		}
	}
#endif

chunk_found:
	if (fnd) {
		chstat[l].s = DPCHK_LOADING;
		MakeChunk(l,cur);
	}

	ReadUnlock();

#endif
}

void DataPipe::MakeChunk(const unsigned l, const vector3di pos)
{
	SDataPlacement plc;

	if (chstat[l].changed) SaveChunk(l);

	if (!FindChunk(pos,&plc)) {
		if (wgen) {
			wgen->GenerateChunk(chunks[l],pos);
			chstat[l].s = DPCHK_READY;
			chstat[l].pos = pos.ToSimVecInt();
#ifdef DPDEBUG
			dbg_print("[DP] Chunk %u generated at [%d %d %d]",l,pos.X,pos.Y,pos.Z);
#endif
		} else {
			chstat[l].s = DPCHK_ERROR;
			chstat[l].changed = false;
#ifdef DPDEBUG
			dbg_print("[DP] No WorldGen instance to generate chunk at [%d %d %d]",l,pos.X,pos.Y,pos.Z);
#endif
		}

	} else if (!LoadChunk(&plc,chunks[l])) {
		chstat[l].s = DPCHK_ERROR;
		chstat[l].changed = false;
#ifdef DPDEBUG
		dbg_print("[DP] Error loading chunk %u at [%d %d %d]",l,pos.X,pos.Y,pos.Z);
#endif

	} else {
		chstat[l].s = DPCHK_READY;
		chstat[l].pos = pos.ToSimVecInt();
#ifdef DPDEBUG
		dbg_print("[DP] Chunk %u loaded at [%d %d %d]",l,pos.X,pos.Y,pos.Z);
#endif

	}
}