glutTimerFunc cleanup
This commit is contained in:
@@ -20,7 +20,7 @@
|
||||
# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
# DOS/DJGPP glut makefile v1.4 for Mesa
|
||||
# DOS/DJGPP glut makefile v1.5 for Mesa
|
||||
#
|
||||
# Copyright (C) 2002 - Borca Daniel
|
||||
# Email : dborca@users.sourceforge.net
|
||||
@@ -34,7 +34,9 @@
|
||||
# CFLAGS
|
||||
#
|
||||
# MKGLUT absolute path to original GLUT.
|
||||
# default = $(TOP)/src-glut
|
||||
# default = $(TOP)/src/glut/glx
|
||||
# GLIDE path to Glide3 SDK; used to resolve DXEs.
|
||||
# default = $(TOP)/glide3
|
||||
#
|
||||
# Targets:
|
||||
# all: build GLUT
|
||||
@@ -46,7 +48,7 @@
|
||||
.PHONY: all clean
|
||||
|
||||
TOP = ../../..
|
||||
GLIDE ?= $(TOP)/include/glide3
|
||||
GLIDE ?= $(TOP)/glide3
|
||||
MKGLUT ?= $(TOP)/src/glut/glx
|
||||
LIBDIR = $(TOP)/lib
|
||||
GLUT_LIB = libglut.a
|
||||
|
||||
+136
-132
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* PC/HW routine collection v1.4 for DOS/DJGPP
|
||||
* PC/HW routine collection v1.5 for DOS/DJGPP
|
||||
*
|
||||
* Copyright (C) 2002 - Borca Daniel
|
||||
* Email : dborca@yahoo.com
|
||||
@@ -93,6 +93,137 @@ void pc_remove_timer (void)
|
||||
|
||||
|
||||
|
||||
/* Desc: remove timerfunc
|
||||
*
|
||||
* In : timerfunc id
|
||||
* Out : 0 if success
|
||||
*
|
||||
* Note: tries to relax the main timer whenever possible
|
||||
*/
|
||||
int pc_remove_int (int fid)
|
||||
{
|
||||
int i;
|
||||
unsigned int freq = 0;
|
||||
|
||||
/* are we installed? */
|
||||
if (!timer_installed) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* sanity check */
|
||||
if ((fid < 0) || (fid >= MAX_TIMERS) || (timer_func[fid].func == NULL)) {
|
||||
return -1;
|
||||
}
|
||||
timer_func[fid].func = NULL;
|
||||
|
||||
/* scan for maximum frequency */
|
||||
for (i = 0; i < MAX_TIMERS; i++) {
|
||||
TIMER *t = &timer_func[i];
|
||||
if (t->func) {
|
||||
if (freq < t->freq) {
|
||||
freq = t->freq;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* if there are no callbacks left, cleanup */
|
||||
if (!freq) {
|
||||
pc_remove_timer();
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* if we just lowered the maximum frequency, try to relax the timer engine */
|
||||
if (freq < timer_main.freq) {
|
||||
unsigned int new_counter = PIT_FREQ / freq;
|
||||
|
||||
DISABLE();
|
||||
|
||||
for (i = 0; i < MAX_TIMERS; i++) {
|
||||
if (timer_func[i].func) {
|
||||
ADJUST(timer_func[i], freq);
|
||||
}
|
||||
}
|
||||
|
||||
outportb(0x43, 0x34);
|
||||
outportb(0x40, (unsigned char)new_counter);
|
||||
outportb(0x40, (unsigned char)(new_counter>>8));
|
||||
timer_main.clock_ticks = 0;
|
||||
timer_main.counter = new_counter;
|
||||
timer_main.freq = freq;
|
||||
|
||||
ENABLE();
|
||||
}
|
||||
|
||||
return 0;
|
||||
} ENDOFUNC(pc_remove_int)
|
||||
|
||||
|
||||
|
||||
/* Desc: adjust timerfunc
|
||||
*
|
||||
* In : timerfunc id, new frequency (Hz)
|
||||
* Out : 0 if success
|
||||
*
|
||||
* Note: might change the main timer frequency
|
||||
*/
|
||||
int pc_adjust_int (int fid, unsigned int freq)
|
||||
{
|
||||
int i;
|
||||
|
||||
/* are we installed? */
|
||||
if (!timer_installed) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* sanity check */
|
||||
if ((fid < 0) || (fid >= MAX_TIMERS) || (timer_func[fid].func == NULL)) {
|
||||
return -1;
|
||||
}
|
||||
timer_func[fid].freq = freq;
|
||||
|
||||
/* scan for maximum frequency */
|
||||
freq = 0;
|
||||
for (i = 0; i < MAX_TIMERS; i++) {
|
||||
TIMER *t = &timer_func[i];
|
||||
if (t->func) {
|
||||
if (freq < t->freq) {
|
||||
freq = t->freq;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* update main timer / sons to match highest frequency */
|
||||
DISABLE();
|
||||
|
||||
/* using '>' is correct still (and avoids updating
|
||||
* the HW timer too often), but doesn't relax the timer!
|
||||
*/
|
||||
if (freq != timer_main.freq) {
|
||||
unsigned int new_counter = PIT_FREQ / freq;
|
||||
|
||||
for (i = 0; i < MAX_TIMERS; i++) {
|
||||
if (timer_func[i].func) {
|
||||
ADJUST(timer_func[i], freq);
|
||||
}
|
||||
}
|
||||
|
||||
outportb(0x43, 0x34);
|
||||
outportb(0x40, (unsigned char)new_counter);
|
||||
outportb(0x40, (unsigned char)(new_counter>>8));
|
||||
timer_main.clock_ticks = 0;
|
||||
timer_main.counter = new_counter;
|
||||
timer_main.freq = freq;
|
||||
} else {
|
||||
ADJUST(timer_func[fid], timer_main.freq);
|
||||
}
|
||||
|
||||
ENABLE();
|
||||
|
||||
return 0;
|
||||
} ENDOFUNC(pc_adjust_int)
|
||||
|
||||
|
||||
|
||||
/* Desc: install timer engine
|
||||
*
|
||||
* In : -
|
||||
@@ -110,6 +241,8 @@ static int install_timer (void)
|
||||
LOCKDATA(timer_func);
|
||||
LOCKDATA(timer_main);
|
||||
LOCKFUNC(timer);
|
||||
LOCKFUNC(pc_adjust_int);
|
||||
LOCKFUNC(pc_remove_int);
|
||||
|
||||
timer_main.counter = 0x10000;
|
||||
|
||||
@@ -186,138 +319,9 @@ int pc_install_int (PFUNC func, void *parm, unsigned int freq)
|
||||
ADJUST(timer_func[i], timer_main.freq);
|
||||
}
|
||||
|
||||
ENABLE();
|
||||
|
||||
return t - timer_func;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Desc: remove timerfunc
|
||||
*
|
||||
* In : timerfunc id
|
||||
* Out : 0 if success
|
||||
*
|
||||
* Note: tries to relax the main timer whenever possible
|
||||
*/
|
||||
int pc_remove_int (int fid)
|
||||
{
|
||||
int i;
|
||||
unsigned int freq = 0;
|
||||
|
||||
/* are we installed? */
|
||||
if (!timer_installed) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* sanity check */
|
||||
if ((fid < 0) || (fid >= MAX_TIMERS) || (timer_func[fid].func == NULL)) {
|
||||
return -1;
|
||||
}
|
||||
timer_func[fid].func = NULL;
|
||||
|
||||
/* scan for maximum frequency */
|
||||
for (i = 0; i < MAX_TIMERS; i++) {
|
||||
TIMER *t = &timer_func[i];
|
||||
if (t->func) {
|
||||
if (freq < t->freq) {
|
||||
freq = t->freq;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* if there are no callbacks left, cleanup */
|
||||
if (!freq) {
|
||||
pc_remove_timer();
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* if we just lowered the maximum frequency, try to relax the timer engine */
|
||||
if (freq < timer_main.freq) {
|
||||
unsigned int new_counter = PIT_FREQ / freq;
|
||||
|
||||
DISABLE();
|
||||
|
||||
for (i = 0; i < MAX_TIMERS; i++) {
|
||||
if (timer_func[i].func) {
|
||||
ADJUST(timer_func[i], freq);
|
||||
}
|
||||
}
|
||||
|
||||
outportb(0x43, 0x34);
|
||||
outportb(0x40, (unsigned char)new_counter);
|
||||
outportb(0x40, (unsigned char)(new_counter>>8));
|
||||
timer_main.clock_ticks = 0;
|
||||
timer_main.counter = new_counter;
|
||||
timer_main.freq = freq;
|
||||
|
||||
ENABLE();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Desc: adjust timerfunc
|
||||
*
|
||||
* In : timerfunc id, new frequency (Hz)
|
||||
* Out : 0 if success
|
||||
*
|
||||
* Note: might change the main timer frequency
|
||||
*/
|
||||
int pc_adjust_int (int fid, unsigned int freq)
|
||||
{
|
||||
int i;
|
||||
|
||||
/* are we installed? */
|
||||
if (!timer_installed) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* sanity check */
|
||||
if ((fid < 0) || (fid >= MAX_TIMERS) || (timer_func[fid].func == NULL)) {
|
||||
return -1;
|
||||
}
|
||||
timer_func[fid].freq = freq;
|
||||
|
||||
/* scan for maximum frequency */
|
||||
freq = 0;
|
||||
for (i = 0; i < MAX_TIMERS; i++) {
|
||||
TIMER *t = &timer_func[i];
|
||||
if (t->func) {
|
||||
if (freq < t->freq) {
|
||||
freq = t->freq;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* update main timer / sons to match highest frequency */
|
||||
DISABLE();
|
||||
|
||||
/* using '>' is correct still (and avoids updating
|
||||
* the HW timer too often), but doesn't relax the timer!
|
||||
*/
|
||||
if (freq != timer_main.freq) {
|
||||
unsigned int new_counter = PIT_FREQ / freq;
|
||||
|
||||
for (i = 0; i < MAX_TIMERS; i++) {
|
||||
if (timer_func[i].func) {
|
||||
ADJUST(timer_func[i], freq);
|
||||
}
|
||||
}
|
||||
|
||||
outportb(0x43, 0x34);
|
||||
outportb(0x40, (unsigned char)new_counter);
|
||||
outportb(0x40, (unsigned char)(new_counter>>8));
|
||||
timer_main.clock_ticks = 0;
|
||||
timer_main.counter = new_counter;
|
||||
timer_main.freq = freq;
|
||||
} else {
|
||||
ADJUST(timer_func[fid], timer_main.freq);
|
||||
}
|
||||
i = t - timer_func;
|
||||
|
||||
ENABLE();
|
||||
|
||||
return 0;
|
||||
return i;
|
||||
}
|
||||
|
||||
+19
-14
@@ -19,7 +19,7 @@
|
||||
*/
|
||||
|
||||
/*
|
||||
* DOS/DJGPP glut driver v1.4 for Mesa
|
||||
* DOS/DJGPP glut driver v1.5 for Mesa
|
||||
*
|
||||
* Copyright (C) 2002 - Borca Daniel
|
||||
* Email : dborca@yahoo.com
|
||||
@@ -38,8 +38,6 @@ typedef struct {
|
||||
int fid; /* func-id as returned from PCHW */
|
||||
} GLUTSShotCB;
|
||||
|
||||
static GLboolean g_sscb_semaphore;
|
||||
|
||||
GLUTidleCB g_idle_func = NULL;
|
||||
|
||||
|
||||
@@ -47,11 +45,12 @@ GLUTidleCB g_idle_func = NULL;
|
||||
static void g_single_shot_callback (void *opaque)
|
||||
{
|
||||
GLUTSShotCB *cb = (GLUTSShotCB *)opaque;
|
||||
while (g_sscb_semaphore) {
|
||||
}
|
||||
if (!--cb->ttl) {
|
||||
cb->func(cb->value);
|
||||
pc_remove_int(cb->fid);
|
||||
/* We won't be needing this slot anymore, so free it. This operation
|
||||
* must be the last thing, and must be atomic, to mutex `glutTimerFunc'
|
||||
*/
|
||||
cb->func = NULL;
|
||||
}
|
||||
} ENDOFUNC(g_single_shot_callback)
|
||||
@@ -139,7 +138,6 @@ void APIENTRY glutTimerFunc (unsigned int millis, GLUTtimerCB func, int value)
|
||||
if (virgin) {
|
||||
virgin = GL_FALSE;
|
||||
LOCKDATA(g_sscb);
|
||||
LOCKDATA(g_sscb_semaphore);
|
||||
LOCKFUNC(g_single_shot_callback);
|
||||
/* we should lock the callee also... */
|
||||
}
|
||||
@@ -153,20 +151,27 @@ void APIENTRY glutTimerFunc (unsigned int millis, GLUTtimerCB func, int value)
|
||||
freq = 1000 / millis;
|
||||
ttl = 1;
|
||||
}
|
||||
g_sscb_semaphore++;
|
||||
for (i = 0; i < MAX_SSHOT_CB; i++) {
|
||||
if (g_sscb[i].func == NULL) {
|
||||
int fid = pc_install_int((PFUNC)func, &g_sscb[i], freq);
|
||||
if (fid >= 0) {
|
||||
g_sscb[i].func = func;
|
||||
g_sscb[i].value = value;
|
||||
g_sscb[i].ttl = ttl;
|
||||
g_sscb[i].fid = fid;
|
||||
/* We will be needing this slot, so alloc it. This operation
|
||||
* must be the first thing, and must be atomic, to mutex callbacks!
|
||||
*/
|
||||
g_sscb[i].func = func;
|
||||
g_sscb[i].value = value;
|
||||
g_sscb[i].ttl = ttl;
|
||||
/* There is a very small gap here: `pc_install_int' enables
|
||||
* interrupts just before returning FID value (which will be
|
||||
* used inside callback). The critical gap is 1 millisecond
|
||||
* - which I'm sure we won't overrun...
|
||||
*/
|
||||
g_sscb[i].fid = pc_install_int((PFUNC)func, &g_sscb[i], freq);
|
||||
if (g_sscb[i].fid < 0) {
|
||||
/* Interrupt could not be set! Release the slot back */
|
||||
g_sscb[i].func = NULL;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
g_sscb_semaphore--;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
*/
|
||||
|
||||
/*
|
||||
* DOS/DJGPP glut driver v1.5 for Mesa
|
||||
* DOS/DJGPP glut driver v1.6 for Mesa
|
||||
*
|
||||
* Copyright (C) 2002 - Borca Daniel
|
||||
* Email : dborca@users.sourceforge.net
|
||||
@@ -146,7 +146,7 @@ extern void *__glutFont(void *font);
|
||||
|
||||
#define MAX_WINDOWS 2
|
||||
|
||||
#define MAX_SSHOT_CB 10
|
||||
#define MAX_SSHOT_CB 8
|
||||
|
||||
#define RESERVED_COLORS 0
|
||||
|
||||
|
||||
Reference in New Issue
Block a user