⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sdl_systimer.c

📁 SDL库 在进行视频显示程序spcaview安装时必须的库文件
💻 C
字号:
/*    SDL - Simple DirectMedia Layer    Copyright (C) 1997-2006 Sam Lantinga    This library is free software; you can redistribute it and/or    modify it under the terms of the GNU Lesser General Public    License as published by the Free Software Foundation; either    version 2.1 of the License, or (at your option) any later version.    This library is distributed in the hope that it will be useful,    but WITHOUT ANY WARRANTY; without even the implied warranty of    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU    Lesser General Public License for more details.    You should have received a copy of the GNU Lesser General Public    License along with this library; if not, write to the Free Software    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA    Sam Lantinga    slouken@libsdl.org*/#include "SDL_config.h"#ifdef SDL_TIMER_OS2#define INCL_DOSMISC#define INCL_DOSERRORS#define INCL_DOSSEMAPHORES#define INCL_DOSDATETIME#define INCL_DOSPROCESS#define INCL_DOSPROFILE#define INCL_DOSEXCEPTIONS#include <os2.h>#include "SDL_thread.h"#include "SDL_timer.h"#include "../SDL_timer_c.h"#define TIME_WRAP_VALUE (~(DWORD)0)/* The first high-resolution ticks value of the application */static long long hires_start_ticks;/* The number of ticks per second of the high-resolution performance counter */static ULONG hires_ticks_per_second;void SDL_StartTicks(void){        DosTmrQueryFreq(&hires_ticks_per_second);        DosTmrQueryTime((PQWORD)&hires_start_ticks);}DECLSPEC Uint32 SDLCALL SDL_GetTicks(void){        long long hires_now;        ULONG ticks = ticks;        DosTmrQueryTime((PQWORD)&hires_now);/*        hires_now -= hires_start_ticks;        hires_now *= 1000;        hires_now /= hires_ticks_per_second;*/        /* inline asm to avoid runtime inclusion */        _asm {           push edx           push eax           mov eax, dword ptr hires_now           mov edx, dword ptr hires_now+4           sub eax, dword ptr hires_start_ticks           sbb edx, dword ptr hires_start_ticks+4           mov ebx,1000           mov ecx,edx           mul ebx           push eax           push edx           mov eax,ecx           mul ebx           pop eax           add edx,eax           pop eax           mov ebx, dword ptr hires_ticks_per_second           div ebx           mov dword ptr ticks, eax           pop edx           pop eax        }        return ticks;}/* High resolution sleep, originally made by Ilya Zakharevich */DECLSPEC void SDLCALL SDL_Delay(Uint32 ms){  /* This is similar to DosSleep(), but has 8ms granularity in time-critical     threads even on Warp3. */  HEV     hevEvent1     = 0;   /* Event semaphore handle    */  HTIMER  htimerEvent1  = 0;   /* Timer handle              */  APIRET  rc            = NO_ERROR;  /* Return code               */  int ret = 1;  ULONG priority = 0, nesting;   /* Shut down the warnings */  PPIB pib;  PTIB tib;  char *e = NULL;  APIRET badrc;  int switch_priority = 50;  DosCreateEventSem(NULL,      /* Unnamed */                    &hevEvent1,  /* Handle of semaphore returned */                    DC_SEM_SHARED, /* Shared needed for DosAsyncTimer */                    FALSE);      /* Semaphore is in RESET state  */  if (ms >= switch_priority)    switch_priority = 0;  if (switch_priority)  {    if (DosGetInfoBlocks(&tib, &pib)!=NO_ERROR)      switch_priority = 0;    else    { /* In Warp3, to switch scheduling to 8ms step, one needs to do     DosAsyncTimer() in time-critical thread.  On laters versions,    more and more cases of wait-for-something are covered.    It turns out that on Warp3fp42 it is the priority at the time    of DosAsyncTimer() which matters.  Let's hope that this works    with later versions too...  XXXX  */      priority = (tib->tib_ptib2->tib2_ulpri);      if ((priority & 0xFF00) == 0x0300) /* already time-critical */        switch_priority = 0; /* Make us time-critical.  Just modifying TIB is not enough... */ /* tib->tib_ptib2->tib2_ulpri = 0x0300;*/ /* We do not want to run at high priority if a signal causes us    to longjmp() out of this section... */      if (DosEnterMustComplete(&nesting))        switch_priority = 0;      else        DosSetPriority(PRTYS_THREAD, PRTYC_TIMECRITICAL, 0, 0);    }  }  if ((badrc = DosAsyncTimer(ms,        (HSEM) hevEvent1, /* Semaphore to post        */        &htimerEvent1))) /* Timer handler (returned) */    e = "DosAsyncTimer";  if (switch_priority && tib->tib_ptib2->tib2_ulpri == 0x0300)  { /* Nobody switched priority while we slept...  Ignore errors... */ /* tib->tib_ptib2->tib2_ulpri = priority; */ /* Get back... */    if (!(rc = DosSetPriority(PRTYS_THREAD, (priority>>8) & 0xFF, 0, 0)))      rc = DosSetPriority(PRTYS_THREAD, 0, priority & 0xFF, 0);  }  if (switch_priority)    rc = DosExitMustComplete(&nesting); /* Ignore errors */  /* The actual blocking call is made with "normal" priority.  This way we     should not bother with DosSleep(0) etc. to compensate for us interrupting     higher-priority threads.  The goal is to prohibit the system spending too     much time halt()ing, not to run us "no matter what". */  if (!e)     /* Wait for AsyncTimer event */    badrc = DosWaitEventSem(hevEvent1, SEM_INDEFINITE_WAIT);  if (e) ;    /* Do nothing */  else if (badrc == ERROR_INTERRUPT)    ret = 0;  else if (badrc)    e = "DosWaitEventSem";  if ((rc = DosCloseEventSem(hevEvent1)) && !e) { /* Get rid of semaphore */    e = "DosCloseEventSem";    badrc = rc;  }  if (e)  {    SDL_SetError("[SDL_Delay] : Had error in %s(), rc is 0x%x\n", e, badrc);  }}/* Data to handle a single periodic alarm */static int timer_alive = 0;static SDL_Thread *timer = NULL;static int SDLCALL RunTimer(void *unused){        DosSetPriority(PRTYS_THREAD, PRTYC_TIMECRITICAL, 0, 0);        while ( timer_alive ) {                if ( SDL_timer_running ) {                        SDL_ThreadedTimerCheck();                }                SDL_Delay(10);        }        return(0);}/* This is only called if the event thread is not running */int SDL_SYS_TimerInit(void){        timer_alive = 1;        timer = SDL_CreateThread(RunTimer, NULL);        if ( timer == NULL )                return(-1);        return(SDL_SetTimerThreaded(1));}void SDL_SYS_TimerQuit(void){        timer_alive = 0;        if ( timer ) {                SDL_WaitThread(timer, NULL);                timer = NULL;        }}int SDL_SYS_StartTimer(void){        SDL_SetError("Internal logic error: OS/2 uses threaded timer");        return(-1);}void SDL_SYS_StopTimer(void){        return;}#endif /* SDL_TIMER_OS2 */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -