Beispiel #1
0
//
// I_GetTime
// returns time in 1/70th second tics
//
int  I_GetTime (void)
{
	systemticks_t	tdiv;

	tdiv = gfxMillisecondsToTicks(1000*256/TICRATE);
	return (gfxSystemTicks()<<8)/tdiv;
}
Beispiel #2
0
static bool update_keyframe_animation(keyframe_animation_t* animation, visualizer_state_t* state, systemticks_t delta, systemticks_t* sleep_time) {
    // TODO: Clean up this messy code
    dprintf("Animation frame%d, left %d, delta %d\n", animation->current_frame,
            animation->time_left_in_frame, delta);
    if (animation->current_frame == animation->num_frames) {
        animation->need_update = false;
        return false;
    }
    if (animation->current_frame == -1) {
       animation->current_frame = 0;
       animation->time_left_in_frame = animation->frame_lengths[0];
       animation->need_update = true;
       animation->first_update_of_frame = true;
    } else {
        animation->time_left_in_frame -= delta;
        while (animation->time_left_in_frame <= 0) {
            int left = animation->time_left_in_frame;
            if (animation->need_update) {
                animation->time_left_in_frame = 0;
                animation->last_update_of_frame = true;
                (*animation->frame_functions[animation->current_frame])(animation, state);
                animation->last_update_of_frame = false;
            }
            animation->current_frame++;
            animation->need_update = true;
            animation->first_update_of_frame = true;
            if (animation->current_frame == animation->num_frames) {
                if (animation->loop) {
                    animation->current_frame = 0;
                }
                else {
                    stop_keyframe_animation(animation);
                    return false;
                }
            }
            delta = -left;
            animation->time_left_in_frame = animation->frame_lengths[animation->current_frame];
            animation->time_left_in_frame -= delta;
        }
    }
    if (animation->need_update) {
        animation->need_update = (*animation->frame_functions[animation->current_frame])(animation, state);
        animation->first_update_of_frame = false;
    }

    systemticks_t wanted_sleep = animation->need_update ? gfxMillisecondsToTicks(10) : (unsigned)animation->time_left_in_frame;
    if (wanted_sleep < *sleep_time) {
        *sleep_time = wanted_sleep;
    }

    return true;
}
Beispiel #3
0
void gtimerStart(GTimer *pt, GTimerFunction fn, void *param, bool_t periodic, delaytime_t millisec) {
	gfxMutexEnter(&mutex);
	
	// Start our thread if not already going
	if (!hThread) {
		hThread = gfxThreadCreate(waTimerThread, GTIMER_THREAD_WORKAREA_SIZE, GTIMER_THREAD_PRIORITY, GTimerThreadHandler, 0);
		if (hThread) {gfxThreadClose(hThread);}		// We never really need the handle again
	}

	// Is this already scheduled?
	if (pt->flags & GTIMER_FLG_SCHEDULED) {
		// Cancel it!
		if (pt->next == pt)
			pTimerHead = 0;
		else {
			pt->next->prev = pt->prev;
			pt->prev->next = pt->next;
			if (pTimerHead == pt)
				pTimerHead = pt->next;
		}
	}
	
	// Set up the timer structure
	pt->fn = fn;
	pt->param = param;
	pt->flags = GTIMER_FLG_SCHEDULED;
	if (periodic)
		pt->flags |= GTIMER_FLG_PERIODIC;
	if (millisec == TIME_INFINITE) {
		pt->flags |= GTIMER_FLG_INFINITE;
		pt->period = TIME_INFINITE;
	} else {
		pt->period = gfxMillisecondsToTicks(millisec);
		pt->when = gfxSystemTicks() + pt->period;
	}

	// Just pop it on the end of the queue
	if (pTimerHead) {
		pt->next = pTimerHead;
		pt->prev = pTimerHead->prev;
		pt->prev->next = pt;
		pt->next->prev = pt;
	} else
		pt->next = pt->prev = pTimerHead = pt;

	// Bump the thread
	if (!(pt->flags & GTIMER_FLG_INFINITE))
		gfxSemSignal(&waitsem);
	gfxMutexExit(&mutex);
}
void gfxSleepMicroseconds(delaytime_t ms) {
	systemticks_t	starttm, delay;

	// Safety first
	switch (ms) {
	case TIME_IMMEDIATE:
		return;
	case TIME_INFINITE:
		while(1)
			gfxYield();
		return;
	}

	// Convert our delay to ticks
	delay = gfxMillisecondsToTicks(ms/1000);
	starttm = gfxSystemTicks();

	do {
		gfxYield();
	} while (gfxSystemTicks() - starttm < delay);
}
bool_t gfxSemWait(gfxSem *psem, delaytime_t ms) {
	systemticks_t	starttm, delay;

	// Convert our delay to ticks
	starttm = 0;
	switch (ms) {
	case TIME_IMMEDIATE:
		delay = TIME_IMMEDIATE;
		break;
	case TIME_INFINITE:
		delay = TIME_INFINITE;
		break;
	default:
		delay = gfxMillisecondsToTicks(ms);
		if (!delay) delay = 1;
		starttm = gfxSystemTicks();
	}

	INTERRUPTS_OFF();
	while (psem->cnt <= 0) {
		INTERRUPTS_ON();
		// Check if we have exceeded the defined delay
		switch (delay) {
		case TIME_IMMEDIATE:
			return FALSE;
		case TIME_INFINITE:
			break;
		default:
			if (gfxSystemTicks() - starttm >= delay)
				return FALSE;
			break;
		}
		gfxYield();
		INTERRUPTS_OFF();
	}
	psem->cnt--;
	INTERRUPTS_ON();
	return TRUE;
}
static void GetMouseReading(GMouse *m) {
	GMouseReading	r;

	// Step 1 - Get the Raw Reading
	{
		m->flags &= ~GMOUSE_FLG_NEEDREAD;
		if (!gmvmt(m)->get(m, &r))
			return;
	}

	// Step 2 - Handle touch and button 0 debouncing
	{
		// Clean off button garbage
		r.buttons &= GINPUT_MOUSE_BTN_MASK;

		#if !GINPUT_TOUCH_NOTOUCH
			// If touch then calculate button 0 from z
			if ((gmvmt(m)->d.flags & GMOUSE_VFLG_TOUCH)) {
				if (gmvmt(m)->z_min <= gmvmt(m)->z_max) {
					if (r.z >= gmvmt(m)->z_touchon)			r.buttons |= GINPUT_MOUSE_BTN_LEFT;
					else if (r.z <= gmvmt(m)->z_touchoff)	r.buttons &= ~GINPUT_MOUSE_BTN_LEFT;
					else									return;				// bad transitional reading
				} else {
					if (r.z <= gmvmt(m)->z_touchon)			r.buttons |= GINPUT_MOUSE_BTN_LEFT;
					else if (r.z >= gmvmt(m)->z_touchoff)	r.buttons &= ~GINPUT_MOUSE_BTN_LEFT;
					else									return;				// bad transitional reading
				}
			}

			// Devices with poor button 0 transitioning need debouncing
			if ((gmvmt(m)->d.flags & GMOUSE_VFLG_POORUPDOWN)) {
				// Are we in a transition test
				if ((m->flags & GMOUSE_FLG_INDELTA)) {
					if (!((r.buttons ^ m->r.buttons) & GINPUT_MOUSE_BTN_LEFT)) {
						// Transition failed
						m->flags &= ~GMOUSE_FLG_INDELTA;
						return;
					}
					// Transition succeeded
					m->flags &= ~GMOUSE_FLG_INDELTA;

				// Should we start a transition test
				} else if (((r.buttons ^ m->r.buttons) & GINPUT_MOUSE_BTN_LEFT)) {
					m->flags |= GMOUSE_FLG_INDELTA;
					return;
				}
			}
		#endif

		#if !GINPUT_TOUCH_NOCALIBRATE_GUI
			// Stop here with just the raw x,y reading during calibration
			if ((m->flags & GMOUSE_FLG_IN_CAL)) {
				if ((r.buttons & GINPUT_MOUSE_BTN_LEFT)) {
					m->r.x = r.x;
					m->r.y = r.y;
				}
				m->r.buttons = r.buttons;
				return;
			}
		#endif
	}

	// Step 3 - Apply calibration, rotation and display clipping
	{
		// If the mouse is up we may need to keep our previous position
		if ((gmvmt(m)->d.flags & GMOUSE_VFLG_ONLY_DOWN) && !(r.buttons & GINPUT_MOUSE_BTN_LEFT)) {
			r.x = m->r.x;
			r.y = m->r.y;

		} else {

			#if !GINPUT_TOUCH_NOCALIBRATE
				// Do we need to calibrate the reading?
				if ((m->flags & GMOUSE_FLG_CALIBRATE))
					CalibrationTransform(&r, &m->caldata);
			#endif

			// We can't clip or rotate if we don't have a display
			if (m->display) {
				coord_t			w, h;

				// We now need display information
				w = gdispGGetWidth(m->display);
				h = gdispGGetHeight(m->display);

				#if GDISP_NEED_CONTROL
					// Do we need to rotate the reading to match the display
					if (!(gmvmt(m)->d.flags & GMOUSE_VFLG_SELFROTATION)) {
						coord_t		t;

						switch(gdispGGetOrientation(m->display)) {
							case GDISP_ROTATE_0:
								break;
							case GDISP_ROTATE_90:
								t = r.x;
								r.x = w - 1 - r.y;
								r.y = t;
								break;
							case GDISP_ROTATE_180:
								r.x = w - 1 - r.x;
								r.y = h - 1 - r.y;
								break;
							case GDISP_ROTATE_270:
								t = r.y;
								r.y = h - 1 - r.x;
								r.x = t;
								break;
							default:
								break;
						}
					}
				#endif

				// Do we need to clip the reading to the display
				if ((m->flags & GMOUSE_FLG_CLIP)) {
					if (r.x < 0)		r.x = 0;
					else if (r.x >= w)	r.x = w-1;
					if (r.y < 0)		r.y = 0;
					else if (r.y >= h)	r.y = h-1;
				}
			}
		}
	}

	// Step 4 - Apply jitter detection
	#if !GINPUT_TOUCH_NOTOUCH
	{
		const GMouseJitter	*pj;
		uint32_t			diff;

		// Are we in pen or finger mode
		pj = (m->flags & GMOUSE_FLG_FINGERMODE) ? &gmvmt(m)->finger_jitter : &gmvmt(m)->pen_jitter;

		// Is this just movement jitter
		if (pj->move > 0) {
			diff = (uint32_t)(r.x - m->r.x) * (uint32_t)(r.x - m->r.x) + (uint32_t)(r.y - m->r.y) * (uint32_t)(r.y - m->r.y);
			if (diff < (uint32_t)pj->move * (uint32_t)pj->move) {
				r.x = m->r.x;
				r.y = m->r.y;
			}
		}

		// Check if the click has moved outside the click area and if so cancel the click
		if (pj->click > 0 && (m->flags & GMOUSE_FLG_CLICK_TIMER)) {
			diff = (uint32_t)(r.x - m->clickpos.x) * (uint32_t)(r.x - m->clickpos.x) + (uint32_t)(r.y - m->clickpos.y) * (uint32_t)(r.y - m->clickpos.y);
			if (diff > (uint32_t)pj->click * (uint32_t)pj->click)
				m->flags &= ~GMOUSE_FLG_CLICK_TIMER;
		}
	}
	#endif

	// Step 5 - Click, context-click and other meta event detection
	{
		uint16_t		upbtns, dnbtns;

		// Calculate button transitions
		dnbtns = r.buttons & ~m->r.buttons;
		upbtns = ~r.buttons & m->r.buttons;

		// Left mouse down generates the Mouse-down meta event
		if ((dnbtns & GINPUT_MOUSE_BTN_LEFT))
			r.buttons |= GMETA_MOUSE_DOWN;

		// Left mouse up generates the Mouse-up meta event
		if ((upbtns & GINPUT_MOUSE_BTN_LEFT))
			r.buttons |= GMETA_MOUSE_UP;

		// Left/Right mouse down starts the click timer
		if ((dnbtns & (GINPUT_MOUSE_BTN_LEFT|GINPUT_MOUSE_BTN_RIGHT))) {
			m->clickpos.x = r.x;
			m->clickpos.y = r.y;
			m->clicktime = gfxSystemTicks();
			m->flags |= GMOUSE_FLG_CLICK_TIMER;
		}

		// Left/Right mouse up with the click timer still running may generate a click or context click
		if ((upbtns & (GINPUT_MOUSE_BTN_LEFT|GINPUT_MOUSE_BTN_RIGHT)) && (m->flags & GMOUSE_FLG_CLICK_TIMER)) {
			m->flags &= ~GMOUSE_FLG_CLICK_TIMER;
			m->clicktime = gfxSystemTicks() - m->clicktime;

			// Was this a short click?
			if (m->clicktime <= gfxMillisecondsToTicks(GINPUT_MOUSE_CLICK_TIME)) {
				if ((upbtns & GINPUT_MOUSE_BTN_RIGHT))
					r.buttons |= GMETA_MOUSE_CXTCLICK;
				if ((upbtns & GINPUT_MOUSE_BTN_LEFT))
					r.buttons |= GMETA_MOUSE_CLICK;
			}

			#if !GINPUT_TOUCH_NOTOUCH
				// Was this a long click on a touch device?
				if ((gmvmt(m)->d.flags & GMOUSE_VFLG_TOUCH) && m->clicktime >= gfxMillisecondsToTicks(GINPUT_TOUCH_CXTCLICK_TIME))
					r.buttons |= GMETA_MOUSE_CXTCLICK;
			#endif
		}
	}

	// Step 6 - Send the event to the listeners that are interested.
	{
		GSourceListener	*psl;

		// Send to the "All Mice" source listeners
		psl = 0;
		while ((psl = geventGetSourceListener((GSourceHandle)&MouseTimer, psl)))
			SendMouseEvent(psl, m, &r);

		// Send to the mouse specific source listeners
		psl = 0;
		while ((psl = geventGetSourceListener((GSourceHandle)m, psl)))
			SendMouseEvent(psl, m, &r);
	}

	// Step 7 - Finally save the results
	m->r.x = r.x;
	m->r.y = r.y;
	m->r.z = r.z;
	m->r.buttons = r.buttons;
}
Beispiel #7
0
static void MousePoll(void *param) {
	(void) param;
	GSourceListener	*psl;
	GEventMouse		*pe;
	unsigned 		meta;
	uint16_t		upbtns, dnbtns;
	uint32_t		cdiff;
	uint32_t		mdiff;

	// Save the last mouse state
	MouseConfig.last_buttons = MouseConfig.t.buttons;

	// Get the new mouse reading
	get_calibrated_reading(&MouseConfig.t);

	// Calculate out new event meta value and handle CLICK and CXTCLICK
	dnbtns = MouseConfig.t.buttons & ~MouseConfig.last_buttons;
	upbtns = ~MouseConfig.t.buttons & MouseConfig.last_buttons;
	meta = GMETA_NONE;

	// As the touch moves up we need to return a point at the old position because some
	//	controllers return garbage with the mouse up
	if ((upbtns & GINPUT_MOUSE_BTN_LEFT)) {
		MouseConfig.t.x = MouseConfig.movepos.x;
		MouseConfig.t.y = MouseConfig.movepos.y;
	}

	// Calculate the position difference from our movement reference (update the reference if out of range)
	mdiff = (MouseConfig.t.x - MouseConfig.movepos.x) * (MouseConfig.t.x - MouseConfig.movepos.x) +
		(MouseConfig.t.y - MouseConfig.movepos.y) * (MouseConfig.t.y - MouseConfig.movepos.y);
	if (mdiff > GINPUT_MOUSE_MAX_MOVE_JITTER * GINPUT_MOUSE_MAX_MOVE_JITTER) {
		MouseConfig.movepos.x = MouseConfig.t.x;
		MouseConfig.movepos.y = MouseConfig.t.y;
	}
	
	// Check if the click has moved outside the click area and if so cancel the click
	if ((MouseConfig.flags & FLG_CLICK_TIMER)) {
		cdiff = (MouseConfig.t.x - MouseConfig.clickpos.x) * (MouseConfig.t.x - MouseConfig.clickpos.x) +
			(MouseConfig.t.y - MouseConfig.clickpos.y) * (MouseConfig.t.y - MouseConfig.clickpos.y);
		if (cdiff > GINPUT_MOUSE_MAX_CLICK_JITTER * GINPUT_MOUSE_MAX_CLICK_JITTER)
			MouseConfig.flags &= ~FLG_CLICK_TIMER;
	}

	// Mouse down
	if ((dnbtns & (GINPUT_MOUSE_BTN_LEFT|GINPUT_MOUSE_BTN_RIGHT))) {
		MouseConfig.clickpos.x = MouseConfig.t.x;
		MouseConfig.clickpos.y = MouseConfig.t.y;
		MouseConfig.clicktime = gfxSystemTicks();
		MouseConfig.flags |= FLG_CLICK_TIMER;
		if ((dnbtns & GINPUT_MOUSE_BTN_LEFT))
			meta |= GMETA_MOUSE_DOWN;
	}

	// Mouse up
	if ((upbtns & (GINPUT_MOUSE_BTN_LEFT|GINPUT_MOUSE_BTN_RIGHT))) {
		if ((upbtns & GINPUT_MOUSE_BTN_LEFT))
			meta |= GMETA_MOUSE_UP;
		if ((MouseConfig.flags & FLG_CLICK_TIMER)) {
			if ((upbtns & GINPUT_MOUSE_BTN_LEFT)
					#if GINPUT_MOUSE_CLICK_TIME != TIME_INFINITE
						&& gfxSystemTicks() - MouseConfig.clicktime < gfxMillisecondsToTicks(GINPUT_MOUSE_CLICK_TIME)
					#endif
					)
				meta |= GMETA_MOUSE_CLICK;
			else
				meta |= GMETA_MOUSE_CXTCLICK;
			MouseConfig.flags &= ~FLG_CLICK_TIMER;
		}
	}

	// Send the event to the listeners that are interested.
	psl = 0;
	while ((psl = geventGetSourceListener((GSourceHandle)(&MouseConfig), psl))) {
		if (!(pe = (GEventMouse *)geventGetEventBuffer(psl))) {
			// This listener is missing - save the meta events that have happened
			psl->srcflags |= meta;
			continue;
		}

		// If we haven't really moved (and there are no meta events) don't bother sending the event
		if (mdiff <= GINPUT_MOUSE_MAX_MOVE_JITTER * GINPUT_MOUSE_MAX_MOVE_JITTER && !psl->srcflags
				&& !meta && MouseConfig.last_buttons == MouseConfig.t.buttons && !(psl->listenflags & GLISTEN_MOUSENOFILTER))
			continue;

		// Send the event if we are listening for it
		if (((MouseConfig.t.buttons & GINPUT_MOUSE_BTN_LEFT) && (psl->listenflags & GLISTEN_MOUSEDOWNMOVES))
				|| (!(MouseConfig.t.buttons & GINPUT_MOUSE_BTN_LEFT) && (psl->listenflags & GLISTEN_MOUSEUPMOVES))
				|| (meta && (psl->listenflags & GLISTEN_MOUSEMETA))) {
			pe->type = GINPUT_MOUSE_EVENT_TYPE;
			pe->instance = 0;
			pe->x = MouseConfig.t.x;
			pe->y = MouseConfig.t.y;
			pe->z = MouseConfig.t.z;
			pe->current_buttons = MouseConfig.t.buttons;
			pe->last_buttons = MouseConfig.last_buttons;
			pe->meta = meta;
			if (psl->srcflags) {
				pe->current_buttons |= GINPUT_MISSED_MOUSE_EVENT;
				pe->meta |= psl->srcflags;
				psl->srcflags = 0;
			}
			pe->display = MouseConfig.display;
			geventSendEvent(psl);
		}
	}
}
Beispiel #8
0
void _gtimerInit(void)
{
	gfxSemInit(&waitsem, 0, 1);
	gfxMutexInit(&mutex);
	ticks2ms = gfxMillisecondsToTicks(1);
}