void WriteA (void) { FIFO f = (FIFO)OS_GetParam(); OS_Write(f,(int)'J'); OS_Yield(); OS_Write(f,(int)'o'); OS_Yield(); OS_Write(f,(int)'e'); OS_Signal(S_LOGO); }
void Write1 (void) { FIFO f = (FIFO)OS_GetParam(); OS_Wait(S_LOGO); OS_Write(f,(int)'l'); OS_Yield(); OS_Write(f,(int)'O'); OS_Yield(); OS_Write(f,(int)'S'); OS_Signal(S_LOGO); }
void TestMain(void) { FIFO buzz, lcd; buzz = OS_InitFiFo(); lcd = OS_InitFiFo(); _sys_init_lcd(); OS_InitSem(S_BUZZ,1); OS_InitSem(S_BUZZ_FIFO,1); OS_InitSem(S_BUZZ_OUTPUT,1); OS_InitSem(S_PORTE,1); OS_InitSem(S_LCD,1); /* Prints the operating system name and plays SOS though the speaker. */ OS_Wait(S_BUZZ_OUTPUT); OS_Create(PrintLogo, 0, DEVICE, 800); OS_Yield(); OS_Wait(S_BUZZ_OUTPUT); /* Servers */ OS_Create(FIFOBuzz, buzz, DEVICE, 800); /* Beep in morse code, charactars from fifo. */ OS_Create(ReadLightSensors, buzz, DEVICE, 200); /* Write values representing the light sensors into the fifo */ OS_Create(ReadMicrophone, buzz, DEVICE, 500); /* Write values representing the sound level into the fifo */ OS_Create(ReadBumpers, lcd, DEVICE, 10); /* Reads bumper values into a FIFO, and moves the robot accordingly. */ /* Printing is too slow... */ //OS_Create(PrintBumperValue, lcd, PERIODIC, 40); /* Prints the bumper values to the screen. */ OS_Signal(S_BUZZ_OUTPUT); }
/* Device: Scheduling period = 1/frequency of sound. Parameter (l) = number of oscillations to produce. */ void Buzz(void) { int i,l; l = OS_GetParam(); /* Release the cpu each time the speaker bit is altered, to allow the device process period to determine the frequency. */ for(i = 0; i < l; i++) { Ports[M6811_PORTA] SET_BIT(BIT3); OS_Yield(); Ports[M6811_PORTA] CLR_BIT(BIT3); OS_Yield(); } OS_Signal(S_BUZZ); }
//------------------------------------------------------------------------ // getchar for apps //------------------------------------------------------------------------ char sh_getchar() { FIFO f = OS_GetParam(); int val; while(!OS_Read(f, &val)) OS_Yield(); return (char)val; }
void ReadLightSensors(void) { FIFO f = (FIFO)OS_GetParam(); int l, r; while (1) { l = 0; r = 0; OS_Wait(S_PORTE); /* Activate A/D Converter...makes pins on Port E analog. */ Ports[M6811_OPTION] SET_BIT(BIT7); /* Delay at least 100 microseconds */ OS_Yield(); /* Start converting the right photocell */ Ports[M6811_ADCTL] = 0; /* Wait for conversion to complete. */ while (!(Ports[M6811_ADCTL] & BIT7)) { OS_Yield(); } r = Ports[M6811_ADR1]; /* Start converting the left photocell */ Ports[M6811_ADCTL] = 1; /* Wait for conversion to complete. */ while (!(Ports[M6811_ADCTL] & BIT7)) { OS_Yield(); } l = Ports[M6811_ADR1]; OS_Signal(S_PORTE); if (l > 100) { OS_Wait(S_BUZZ_FIFO); OS_Write(f,'l'); } if (r > 100) { OS_Wait(S_BUZZ_FIFO); OS_Write(f,'r'); } OS_Yield(); } }
void task1(void) { for(;;) { P1DIR |= BIT1; P1OUT |= BIT1; OS_Yield(); } }
void MotorX(void){ for(;;){ OS_Wait(numPulsosX>0); if(dirMotorX==64) output_high(dirX); if(dirMotorX==128) output_low(dirX); if(--numPulsosX!=0) output_toggle(clockX); else output_low(clockX); OS_Delay(periodoPulsosX); OS_Yield(); } }
void MotorE(void){ for(;;){ OS_Wait(numPulsosE>0); if(dirMotorE==1) output_high(dirE); if(dirMotorE==2) output_low(dirE); if(--numPulsosE!=0) output_toggle(clockE); else output_low(clockE); OS_Delay(periodoPulsosE); OS_Yield(); } }
void MotorZ(void){ for(;;){ OS_Wait(numPulsosZ>0); if(dirMotorZ==8) output_high(dirZ); if(dirMotorZ==4) output_low(dirZ); if(--numPulsosZ!=0) output_toggle(clockZ); else output_low(clockZ); OS_Delay(periodoPulsosZ); OS_Yield(); } }
void MotorY(void){ for(;;){ OS_Wait(numPulsosY>0); if(dirMotorY==32) output_high(dirY); if(dirMotorY==16) output_low(dirY); if(--numPulsosY!=0) output_toggle(clockY); else output_low(clockY); OS_Delay(periodoPulsosY); OS_Yield(); } }
void ReadMicrophone(void) { FIFO f = (FIFO)OS_GetParam(); int s; while (1) { s = 0; OS_Wait(S_PORTE); /* Activate A/D Converter...makes pins on Port E analog. */ Ports[M6811_OPTION] SET_BIT(BIT7); /* Delay at least 100 microseconds */ OS_Yield(); /* Don't listen while buzzing. */ OS_Wait(S_BUZZ_OUTPUT); /* Start converting the microphone. */ Ports[M6811_ADCTL] = 2; OS_Signal(S_BUZZ_OUTPUT); /* Wait for conversion to complete. */ while (!(Ports[M6811_ADCTL] & BIT7)) { OS_Yield(); } s = Ports[M6811_ADR1]; OS_Signal(S_PORTE); /* Rectify the sound sample around 128. */ if (s >= 128) { s -= 128; } else { s = 128 - s; } if (s > 35) { OS_Wait(S_BUZZ_FIFO); OS_Write(f,'s'); } OS_Yield(); } }
void Gla(void){ for(;;){ OS_Wait(GlaoGlc==3); //OS_Bsem_Wait(BS_GLAGLC_FREE); output_toggle(PIN_B7); //-- 1023/255=4.012, necesita adaptarse al mismo rango //-- porque el valorR que llega desde el GUI tiene max=255 r=(float)(valorR*4.012); control=(unsigned int16)r; set_pwm1_duty(control); OS_Delay(1000); //OS_Bsem_Set(BS_GLAGLC_FREE); OS_Yield(); } }
void Glc_PIDdiscreto(void){ for(;;){ OS_Wait(GlaoGlc==2); //2 //OS_Bsem_Wait(BS_GLAGLC_FREE); output_toggle(PIN_B7); valorY=read_adc(ADC_READ_ONLY); //-- debido al ADC 10bits, la conversion se realiza con 10bits, //-- entonces valorY tiene rango de 0 a 1023 y=(float)valorY; //-- 1023/255=4.012, necesita adaptarse al mismo rango //-- porque el valorR que llega desde el GUI tiene max=255 r=(float)(valorR*4.012); //---------------------------------------------------------------------- //-- Calculo PID por metodo tustin para termino integral //-- y metodo de diferencias hacia atras para termino derivativo //-- Sea e(kT)=e; e(kT-T)=e1 e=r-y; //Sea p(kT)=p; i(kT)=i; i(kT-T)=i1; d(kT)=d p=Kpz*e; //i=i1+Kiz*e; //diferencia hacia atras i=i1+Kiz*(e+e1); //tustin d=Kdz*(e-e1); //diferencia hacia atras //Sea u(kT)=u u=p+i+d; //-- Anti-windup solo al termino integral para evitar que se infle //-- y se haga muy grande si la accion de control se satura, por tanto //-- es necesario impedir que cambie i //if((u>max) | (u<min)) {i=i-Ki*T*e;} //diferencia hacia atras //if((u>max) | (u<min)) i=i-Kiz*(e+e1); //tustin if(u>max)u=max; if(u<min)u=min; //-- realizar la conversion final control=(unsigned int16)u; set_pwm1_duty(control); e1=e; i1=i; OS_Delay(5000); //OS_Bsem_Set(BS_GLAGLC_FREE); OS_Yield(); } }
void PrintFIFO (void) { FIFO f = (FIFO)OS_GetParam(); char *s = " "; int i; int fi; i = 0; while(i < 6) { if(OS_Read(f,&fi)) { s[i++] = (char)fi; } else { OS_Yield(); } } OS_Wait(S_LCD); OS_Create(PrintString, (int)s, PERIODIC, 50); }
static void Balloon_DeallocateChunkList(Balloon *b, // IN/OUT int isLargePages) // IN { unsigned int cnt = 0; BalloonChunkList *chunkList; chunkList = &b->pages[isLargePages]; /* free all pages, skipping monitor unlock */ while (chunkList->nChunks > 0) { BalloonPageFree(b, isLargePages); if (++cnt >= b->rateFree) { cnt = 0; OS_Yield(); } } }
void USB(void){ for(;;){ if(usb_enumerated()){ //True si el USB ha sido enumerado. if(usb_kbhit(1)){ //(endpoint=1 EP1)= TRUE si el EP1 tiene datos //en su buffer de recepcion. //-- (endpoint,ptr,max)=Reads up to max bytes from //-- the specified endpoint buffer and saves it to the pointer ptr //-- Returns the number of bytes saved to ptr usb_get_packet(1,RecibirByte,20); //-- revisa en orden logico el contenido de //-- RecibirByte[0],[1],[2],[3],[4].... //-- *2, OSA usa el doble de pulsos numPulsosX = (RecibirByte[0]*256+RecibirByte[1])*2; numPulsosY = (RecibirByte[2]*256+RecibirByte[3])*2; numPulsosZ = (RecibirByte[4]*256+RecibirByte[5])*2; numPulsosE = (RecibirByte[6]*256+RecibirByte[7])*2; periodoPulsosX = (RecibirByte[8]*256+RecibirByte[9]); periodoPulsosY = (RecibirByte[10]*256+RecibirByte[11]); periodoPulsosZ = RecibirByte[12]; periodoPulsosE = RecibirByte[13]; dirMotorX = RecibirByte[14]; dirMotorY = RecibirByte[15]; dirMotorZ = RecibirByte[16]; dirMotorE = RecibirByte[17]; GlaoGlc = RecibirByte[18]; valorR = RecibirByte[19]; } //-- reviso en orden logico EnviarByte[0],[1] y envio por usb ADC(); //esta funcion contiene los valores de EnviarByte[0;1] if( (numPulsosX || numPulsosY || numPulsosZ || numPulsosE) != 0) {EnviarByte[2]=1; output_high(PIN_B6);} else {EnviarByte[2]=0; output_low(PIN_B6);} //-- (endpoint,data,len,tgl)=Places the packet of data //-- into the specified endpoint buffer. //-- Returns TRUE if success, FALSE if the buffer //-- is still full with the last packet. usb_put_packet(1,EnviarByte,3,USB_DTS_TOGGLE); } OS_Delay(10); OS_Yield(); } }
static void BalloonInflate(Balloon *b, // IN/OUT uint32 target) // IN { uint32 nEntries; unsigned int rate; unsigned int allocations = 0; int status = BALLOON_SUCCESS; BalloonPageAllocType allocType; Bool isLargePages; unsigned numPagesPerEntry; if ((b->hypervisorCapabilities & BALLOON_BATCHED_2M_CMDS) != 0) { allocType = BALLOON_PAGE_ALLOC_LPAGE; isLargePages = TRUE; numPagesPerEntry = OS_LARGE_2_SMALL_PAGES; } else { allocType = BALLOON_PAGE_ALLOC_NOSLEEP; isLargePages = FALSE; numPagesPerEntry = 1; } /* * We try allocating in the following order: * * First we try to allocate large pages without sleeping. If the * memory becomes too fragmented to allocate whole large pages at * once, switch to small pages - still without sleeping. * * If we do not throttle nosleep allocations, we can drain all * free pages in the guest quickly (if the balloon target is high). * As a side-effect, draining free pages helps to inform (force) * the guest to start swapping if balloon target is not met yet, * which is a desired behavior. However, balloon driver can consume * all available CPU cycles if too many pages are allocated in a * second. Therefore, we throttle nosleep allocations even when * the guest is not under memory pressure. OTOH, if we have already * predicted that the guest is under memory pressure, then we * slowdown page allocations considerably. */ /* * Start with no sleep allocation rate which may be higher * than sleeping allocation rate. */ rate = b->slowPageAllocationCycles ? b->rateAlloc : BALLOON_NOSLEEP_ALLOC_MAX; nEntries = 0; while (b->nPages < target && nEntries * numPagesPerEntry < target - b->nPages) { PageHandle handle; STATS_INC(b->stats.primAlloc[allocType]); handle = OS_ReservedPageAlloc(allocType == BALLOON_PAGE_ALLOC_CANSLEEP, isLargePages); if (handle == PAGE_HANDLE_INVALID) { STATS_INC(b->stats.primAllocFail[allocType]); status = BALLOON_PAGE_ALLOC_FAILURE; if (allocType == BALLOON_PAGE_ALLOC_LPAGE) { /* * LPAGE allocation failed. This does mean that the guest is under * pressure, it just means that the memory is fragmented enough that * we cannot allocate any more large pages. * * Lock partial set of large pages now as we continue with * allocating small pages and we cannot have a lock call with * different entry sizes. */ if (nEntries > 0) { status = b->balloonOps->lock(b, nEntries, TRUE, &target); nEntries = 0; } /* Continue with small pages */ isLargePages = FALSE; numPagesPerEntry = 1; allocType = BALLOON_PAGE_ALLOC_NOSLEEP; } else if (allocType == BALLOON_PAGE_ALLOC_NOSLEEP) { /* * NOSLEEP page allocation failed, so the guest is under memory * pressure. Let us slow down page allocations for next few cycles * so that the guest gets out of memory pressure. Also, if we * already allocated b->rateAlloc pages, let's pause, otherwise * switch to sleeping allocations. */ b->slowPageAllocationCycles = SLOW_PAGE_ALLOCATION_CYCLES; /* Lower rate for sleeping allocations. */ rate = b->rateAlloc; allocType = BALLOON_PAGE_ALLOC_CANSLEEP; } else { ASSERT(allocType == BALLOON_PAGE_ALLOC_CANSLEEP); /* * CANSLEEP page allocation failed, so guest is under severe * memory pressure. Quickly decrease allocation rate. */ b->rateAlloc = MAX(b->rateAlloc / 2, BALLOON_RATE_ALLOC_MIN); /* Stop allocating any more memory */ break; } if (allocations >= b->rateAlloc) { break; } continue; } allocations++; b->balloonOps->addPage(b, nEntries++, handle); if (nEntries == b->batchMaxEntries) { status = b->balloonOps->lock(b, nEntries, isLargePages, &target); nEntries = 0; if (status != BALLOON_SUCCESS) { break; } } if (allocations % BALLOON_ALLOC_YIELD_THRESHOLD == 0) { OS_Yield(); } if (allocations >= rate) { /* We allocated enough pages, let's take a break. */ break; } } if (nEntries > 0) { b->balloonOps->lock(b, nEntries, isLargePages, NULL); } /* * We reached our goal without failures so try increasing * allocation rate. */ if (status == BALLOON_SUCCESS && allocations >= b->rateAlloc) { unsigned int mult = allocations / b->rateAlloc; b->rateAlloc = MIN(b->rateAlloc + mult * BALLOON_RATE_ALLOC_INC, BALLOON_RATE_ALLOC_MAX); } /* release non-balloonable pages, succeed */ BalloonErrorPagesFree(b); }
/* Device: > 500ms */ void FIFOBuzz(void) { FIFO f; int fi; unsigned int i; f = (FIFO)OS_GetParam(); while (1) { if(OS_Read(f,&fi)) { /* Fifo for charactar output */ OS_Wait(S_BUZZ_OUTPUT); switch((char)fi) { case 'a': dot(); dash(); break; case 'b': dash(); dot(); dot(); dot(); break; case 'c': dash(); dot(); dash(); dot(); break; case 'd': dash(); dot(); dot(); break; case 'e': dot(); break; case 'f': dot(); dot(); dash(); dot(); break; case 'g': dash(); dash(); dot(); break; case 'h': dot(); dot(); dot(); dot(); break; case 'i': dot(); dot(); break; case 'j': dot(); dash(); dash(); dash(); break; case 'k': dash(); dot(); dash(); break; case 'l': dot(); dash(); dot(); dot(); break; case 'm': dash(); dash(); break; case 'n': dash(); dot(); break; case 'o': dash(); dash(); dash(); break; case 'p': dot(); dash(); dash(); dot(); break; case 'q': dash(); dash(); dot(); dash(); break; case 'r': dot(); dash(); dot(); break; case 's': dot(); dot(); dot(); break; case 't': dash(); break; case 'u': dot(); dot(); dash(); break; case 'v': dot(); dot(); dot(); dash(); break; case 'w': dot(); dash(); dash(); break; case 'x': dash(); dot(); dot(); dash(); break; case 'y': dash(); dot(); dash(); dash(); break; case 'z': dash(); dash(); dot(); dot(); break; case '1': dot(); dash(); dash(); dash(); dash(); break; case '2': dot(); dot(); dash(); dash(); dash(); break; case '3': dot(); dot(); dot(); dash(); dash(); break; case '4': dot(); dot(); dot(); dot(); dash(); break; case '5': dot(); dot(); dot(); dot(); dot(); break; case '6': dash(); dot(); dot(); dot(); dot(); break; case '7': dash(); dash(); dot(); dot(); dot(); break; case '8': dash(); dash(); dash(); dot(); dot(); break; case '9': dash(); dash(); dash(); dash(); dot(); break; case '0': dash(); dash(); dash(); dash(); dash(); break; default: OS_Yield(); break; } OS_Signal(S_BUZZ_FIFO); /* Wait for the speaker to settle...prevents the microphone from hearing it. */ OS_Yield(); /* When all buzz processes have finished, signal that output is complete. */ OS_Wait(S_BUZZ); OS_Signal(S_BUZZ_OUTPUT); OS_Signal(S_BUZZ); } OS_Yield(); } }
void Task_Game (void) { static char s_cKeys; // Keyboard command static char s_cLastKeys = 0;// Previous command static bit bButton; // Fire button state static near char x, y, yy, xx; char A, // Object at porition X B; // Object style for A. These styles are calculated // once per cycle, to increase speed of GameStep char A_top, // Object above A A_bottom, // Object under A A_move, // Object at position where A wants move to. B_top, B_bottom, B_move; static near char s_cAction; // Action performing on moving object static bit bDirChanged;// Addition flag for fireflies and butterflies // to change direction of moving static bit bBangJewel; // This bit tells that jewel should appear after bang static near char s_cSound; // Sound type on current stage static near char n,m; // addition temp variables static near char temp; //for (;;) { OS_Bsem_Set(BS_MAP_FREE); // Free "Map" resource OS_Flag_Wait_11(i_cStep, 0x08); // Run every eight VGA-cadr OS_Flag_Set_0(i_cStep, 0x08); OS_Bsem_Wait(BS_MAP_FREE); // Wait for resource "Map" became free s_cKeys = 0; bButton = 0; //------------------------------------------------------------------------------ // All button pressed: Restart level //------------------------------------------------------------------------------ if (BUTTON_UP && BUTTON_LEFT && BUTTON_RIGHT && BUTTON_DOWN) { if (m_bAlive) { m_bAlive = false; m_bEnd = true; m_Map[m_cManY][m_cManX] = OBJECT_BANG; str_cpy(m_strStatusBar, STR_GAME_OVER); } } //------------------------------------------------------------------------------ // Fire button after dead - reborn //------------------------------------------------------------------------------ if (BUTTON_FIRE && m_bEnd) { if (BUTTON_UP && BUTTON_LEFT && BUTTON_RIGHT && BUTTON_DOWN) { m_cCurMap++; if (m_cCurMap >= NUMBER_OF_MAPS) m_cCurMap = 0; InitMap(m_cCurMap); } if (!BUTTON_UP && !BUTTON_LEFT && !BUTTON_RIGHT && !BUTTON_DOWN) InitMap(m_cCurMap); } //------------------------------------------------------------------------------ // When man alive, check keyoard and make the man run //------------------------------------------------------------------------------ if (m_bAlive) { OS_Bsem_Set(BS_MUSIC_START); // First time music can start only // after born if (BUTTON_UP) s_cKeys = 1; if (BUTTON_DOWN) s_cKeys = 2; if (BUTTON_LEFT) s_cKeys = 3; if (BUTTON_RIGHT) s_cKeys = 4; if (BUTTON_FIRE) bButton = 1; // Select man picture: standing, running left, running right temp = 0; switch (s_cKeys & 0xF) { case 0: temp = OBJECT_MAN | (((i_wRandom & 7) == 7)?1:0); break; case 1: if (s_cLastKeys != s_cKeys) temp = OBJECT_LEFT_MAN | MOVING | DIR_UP; break; case 2: if (s_cLastKeys != s_cKeys) temp = OBJECT_RIGHT_MAN | MOVING | DIR_DOWN; break; case 3: if (s_cLastKeys != s_cKeys) temp = OBJECT_LEFT_MAN | MOVING | DIR_LEFT; break; case 4: if (s_cLastKeys != s_cKeys) temp = OBJECT_RIGHT_MAN | MOVING | DIR_RIGHT; break; } if (temp) SetMap(m_cManY, m_cManX, temp); } else { // Man is not born yet m_cBornTimer--; } s_cLastKeys = s_cKeys; //------------------------------------------------------------------------------ // Make window position correction //------------------------------------------------------------------------------ if (m_bScrMovedX) { m_bScrMovedX = false; if (!s_cKeys) CorrectWindowPositionX(5); } if (m_bScrMovedY) { m_bScrMovedY = false; if (!s_cKeys) CorrectWindowPositionY(4); } OS_Yield(); s_cSound = 0; //------------------------------------------------------------------------------ // Check all elements in map //------------------------------------------------------------------------------ for (y = 18; y > 0; y--) { OS_Yield(); for (x = 38; x > 0; x--) { CLRWDT(); bDirChanged = false; bBangJewel = false; RETRY: A = GetMap(y, x); if (A == (OBJECT_SPACE | 0x80)) // When object SPACE have bit 7 set, { // nither boulder nor jewel can fall here SetMap(y,x, OBJECT_SPACE); // This state of SPACE can be active continue; // per one game step only. } if (A == OBJECT_SPACE) continue; if (A == OBJECT_WALL) continue; if (A == OBJECT_DIRT) continue; B = Object(A); //****************************************************************************** if (A & MOVING) // Check moving object //****************************************************************************** { xx = x; // Calculate position to move to yy = y; switch (A & DIR_MASK) { //------------------------------------------------------------------------------ case DIR_UP: //------------------------------------------------------------------------------ yy--; break; //------------------------------------------------------------------------------ case DIR_DOWN: //------------------------------------------------------------------------------ yy++; break; //------------------------------------------------------------------------------ case DIR_LEFT: //------------------------------------------------------------------------------ xx--; break; //------------------------------------------------------------------------------ case DIR_RIGHT: //------------------------------------------------------------------------------ xx++; break; } // Point where object moves to A_move = GetMap(yy, xx); B_move = Object(A_move); //************************************************************************** // Check what the action should we do //************************************************************************** s_cAction = ACTION_NO_ACTION; switch (B) { //------------------------------------------------------------------------------ case OBJECT_MAN: // man case OBJECT_MAN_EYES: // man case OBJECT_LEFT_MAN: // man case OBJECT_RIGHT_MAN: // man //------------------------------------------------------------------------------ // Check for push boulder //------------------------------------------------------------------------------ if (B_move == OBJECT_BOULDER) { if (y != yy) break; if (x > xx && GetMap(y,xx-1)==OBJECT_SPACE) s_cAction = ACTION_PUSH; if (x < xx && GetMap(y,xx+1)==OBJECT_SPACE) s_cAction = ACTION_PUSH; } if (B_move == OBJECT_TIT_WALL) { // Check for HOME and there is enough jewels if ((A_move & 0x80) && (m_cJewels >= m_cNeededJewels)) { s_cAction = ACTION_GO_HOME; } break; } if (B_move == OBJECT_WALL) s_cAction = ACTION_NO_ACTION; if (B_move == OBJECT_SPACE) s_cAction = ACTION_CAN_MOVE; if (B_move == OBJECT_DIRT) s_cAction = ACTION_EAT_DIRT; if (B_move == OBJECT_BANG) s_cAction = ACTION_NO_ACTION; if (B_move == OBJECT_JEWEL) s_cAction = ACTION_EAT_JEWEL; break; //------------------------------------------------------------------------------ case OBJECT_BUTTERFLY: case OBJECT_FIREFLY: //------------------------------------------------------------------------------ // Check for man touching //------------------------------------------------------------------------------ if (m_bAlive) { if ((m_cManY == y && (m_cManX == (x+1) || m_cManX == (x-1))) || (m_cManX == x && (m_cManY == (y+1) || m_cManY == (y-1)))) { // Set bang position m_cBangX = m_cManX; m_cBangY = m_cManY; s_cAction = ACTION_BANG; if (B == OBJECT_BUTTERFLY) s_cAction = ACTION_BANG_JEWEL; break; } } if (B_move == OBJECT_SPACE) { s_cAction = ACTION_CAN_MOVE; break; } //------------------------------------------------------------------------------ // When firefly and butterfly meat face to face, they just // replaced one by one (they should be moved in opposit directions //------------------------------------------------------------------------------ if (B_move == OBJECT_FIREFLY || B_move == OBJECT_BUTTERFLY) { if (B != B_move) if (((A^A_move) & DIR_MASK)==0x80) { s_cAction = ACTION_EXCHANGE; break; } } //------------------------------------------------------------------------------ // Check for falling boulder or jewel above //------------------------------------------------------------------------------ A_top = GetMap(y-1, x); B_top = A_top & 0x1F; if (B_top == OBJECT_BOULDER || (B_top & 0x1C)== OBJECT_JEWEL ) { if ((A_top & MOVING)) { s_cAction = ACTION_STOP_FLY; break; } } s_cAction = ACTION_DEC_DIRECTION; if (B == OBJECT_BUTTERFLY) s_cAction = ACTION_INC_DIRECTION; break; //------------------------------------------------------------------------------ case OBJECT_BOULDER: case OBJECT_JEWEL: m_cBangX = x; m_cBangY = y + 1; s_cAction = ACTION_STOP_MOVE; B_bottom = Object(GetMap(y+1, x)); if (B_bottom == OBJECT_SPACE) s_cAction = ACTION_CAN_MOVE; if (B_bottom == OBJECT_MAN) s_cAction = ACTION_BANG; if (B_bottom == OBJECT_LEFT_MAN) s_cAction = ACTION_BANG; if (B_bottom == OBJECT_RIGHT_MAN) s_cAction = ACTION_BANG; if (B_bottom == OBJECT_FIREFLY) s_cAction = ACTION_BANG; if (B_bottom == OBJECT_BUTTERFLY) s_cAction = ACTION_BANG_JEWEL; break; } // switch (B) //****************************************************************************** // Now we have a variable s_cAction which contains what should we do //****************************************************************************** switch (s_cAction) { //------------------------------------------------------------------------------ case ACTION_NO_ACTION: //------------------------------------------------------------------------------ break; //------------------------------------------------------------------------------ case ACTION_PUSH: //------------------------------------------------------------------------------ if (i_wRandom & 3) break; if (x > xx) SetMap(y, xx-1, OBJECT_BOULDER); if (x < xx) SetMap(y, xx+1, OBJECT_BOULDER); if (s_cSound < GAME_SOUND_PUSH) s_cSound = GAME_SOUND_PUSH; goto MOVE; //------------------------------------------------------------------------------ case ACTION_EAT_JEWEL: //------------------------------------------------------------------------------ m_cJewels++; if (m_cJewels == m_cNeededJewels) { m_bBlink = 1; if (s_cSound < GAME_SOUND_COMPLETE) s_cSound = GAME_SOUND_COMPLETE; } if (s_cSound < GAME_SOUND_EAT_JEWEL) s_cSound = GAME_SOUND_EAT_JEWEL; goto MOVE; //------------------------------------------------------------------------------ case ACTION_GO_HOME: //------------------------------------------------------------------------------ m_bAlive = 0; m_bEnd = 1; str_cpy(m_strStatusBar, STR_YOU_WIN); A &= ~MOVING; SetMap(y, x, A); m_cCurMap++; if (m_cCurMap >= NUMBER_OF_MAPS) m_cCurMap = 0; if (s_cSound < GAME_SOUND_HOME) s_cSound = GAME_SOUND_HOME; goto MOVE; //------------------------------------------------------------------------------ case ACTION_EAT_DIRT: //------------------------------------------------------------------------------ if (s_cSound < GAME_SOUND_EAT_DIRT) s_cSound = GAME_SOUND_EAT_DIRT; goto MOVE; //------------------------------------------------------------------------------ case ACTION_CAN_MOVE: //------------------------------------------------------------------------------ MOVE: SetMap(y, x, OBJECT_SPACE); if (x == m_cManX && y == m_cManY) { if (bButton && m_cManX==x && m_cManY==y) { SetMap(yy, xx, OBJECT_SPACE); xx = x; yy = y; } m_cManX = xx; m_cManY = yy; CorrectWindowPositionX(2); CorrectWindowPositionY(2); if (s_cSound < GAME_SOUND_STEP) s_cSound = GAME_SOUND_STEP; } if (yy < y || xx < x) A &= ~MOVING; // To prevent multiply moving // of same object if (B == OBJECT_BUTTERFLY) A -= 0x40; if (B == OBJECT_FIREFLY) A += 0x40; SetMap(yy, xx, A); break; //------------------------------------------------------------------------------ case ACTION_EXCHANGE: //------------------------------------------------------------------------------ SetMap(y, x, A_move); SetMap(yy, xx, A); break; //------------------------------------------------------------------------------ case ACTION_INC_DIRECTION: //------------------------------------------------------------------------------ if (!bDirChanged) { A += 0x40; SetMap(y, x, A); bDirChanged = true; goto RETRY; } break; //------------------------------------------------------------------------------ case ACTION_DEC_DIRECTION: //------------------------------------------------------------------------------ if (!bDirChanged) { A -= 0x40; SetMap(y, x, A); bDirChanged = true; goto RETRY; } break; //------------------------------------------------------------------------------ case ACTION_STOP_MOVE: //------------------------------------------------------------------------------ A &= ~MOVING; SetMap(y, x, A); if (B == OBJECT_JEWEL) { if (s_cSound < GAME_SOUND_JEWEL_FELD) s_cSound = GAME_SOUND_JEWEL_FELD; } else { if (s_cSound < GAME_SOUND_BOULDER_FELD)s_cSound = GAME_SOUND_BOULDER_FELD; } goto RETRY; //------------------------------------------------------------------------------ case ACTION_STOP_FLY: //------------------------------------------------------------------------------ A &= ~MOVING; SetMap(y, x, A); break; //------------------------------------------------------------------------------ case ACTION_BANG_JEWEL: //------------------------------------------------------------------------------ if (s_cSound < GAME_SOUND_BANG_JEWEL) s_cSound = GAME_SOUND_BANG_JEWEL; bBangJewel = true; //------------------------------------------------------------------------------ case ACTION_BANG: //------------------------------------------------------------------------------ if (!bBangJewel) if (s_cSound < GAME_SOUND_BANG) s_cSound = GAME_SOUND_BANG; for (n = m_cBangX - 1; n <= m_cBangX + 1; n++) { for (m = m_cBangY-1; m <= m_cBangY+1; m++) { if (GetMap(m, n) != OBJECT_TIT_WALL) { if (n == m_cManX && m == m_cManY) { if (!m_bAlive) continue; m_bAlive = 0; m_bEnd = true; str_cpy(m_strStatusBar, STR_GAME_OVER); } temp = OBJECT_BANG; if (bBangJewel) temp |= 0x80; SetMap(m, n, temp); }; } } break; }; // switch s_cAction //****************************************************************************** } else { // not MOVING object //****************************************************************************** switch (B) { //------------------------------------------------------------------------------ case OBJECT_LEFT_MAN: // Restore moving state to objects that should move case OBJECT_RIGHT_MAN: if (!m_bAlive) break; case OBJECT_BUTTERFLY: case OBJECT_FIREFLY:; m_Map[y][x] |= MOVING; break; //------------------------------------------------------------------------------ case OBJECT_BOULDER: case OBJECT_JEWEL: B_bottom = Object(A_bottom = GetMap(y+1, x)); if (B_bottom == OBJECT_SPACE) // Check for start falling down { A |= MOVING; A |= DIR_DOWN; SetMap(y, x, A); } else { // Check for falling from a boulder, a jewel or a wall if ((B_bottom == OBJECT_BOULDER || B_bottom == OBJECT_WALL || B_bottom == OBJECT_JEWEL) && !(A_bottom & MOVING)) { if (GetMap(y ,x-1) == OBJECT_SPACE && GetMap(y+1,x-1) == OBJECT_SPACE) { temp = Object(GetMap(y-1, x-1)); // Не даем камню уйти влево, если что-то // должно падать сверху if (temp == OBJECT_BOULDER) break; if (temp == OBJECT_JEWEL) break; SetMap(y, x-1, A); // Здесь не нужно ставить флаг // движения, т.к. эта клетка будет // преверена следюущим же шагом (т.к. // просматриваем справа налево) SetMap(y,x, OBJECT_SPACE | 0x80); // Признак того, что // пока еще нельзя // ронять сюда камень break; } if (GetMap(y ,x+1) == OBJECT_SPACE && GetMap(y+1,x+1) == OBJECT_SPACE) { temp = Object(GetMap(y-1,x+1)); // Не даем камню уйти влево, если что-то // должно падать сверху if (temp == OBJECT_BOULDER) break; if (temp == OBJECT_JEWEL) break; SetMap(y,x+1, A | MOVING | DIR_DOWN); SetMap(y,x, OBJECT_SPACE | 0x80); break; } } } break; //------------------------------------------------------------------------------ case OBJECT_HOME: case OBJECT_TIT_WALL: if ((A & 0x80) && (m_cNeededJewels <= m_cJewels)) { } if ((A & 0x40) && !m_cBornTimer) { SetMap(y,x, OBJECT_BANG | 0x40); if (s_cSound < GAME_SOUND_BORN) s_cSound = GAME_SOUND_BORN; } break; } // switch (B) if ((A & 0x1F) == (OBJECT_BANG | 3)) // last stage of bang { if (A & 0x40) // Borning { A = OBJECT_MAN; m_cManX = x; m_cManY = y; m_bAlive = 1; } else { if (A & 0x80) A = OBJECT_JEWEL; // Bang with jewels else A = OBJECT_SPACE; // Bang without jewels } SetMap(y, x, A); } //****************************************************************************** } // MOVING //****************************************************************************** } // for x } // for y if (s_cSound) OS_SMsg_Send_Now(smsg_GameSound, s_cSound); if (m_bAlive) MakeStatusBar(); } }
void ReadBumpers(void) { FIFO f = (FIFO)OS_GetParam(); int b; while (1) { b = 0; OS_Wait(S_PORTE); /* Activate A/D Converter...makes pins on Port E analog. */ Ports[M6811_OPTION] SET_BIT(BIT7); /* Delay at least 100 microseconds */ OS_Yield(); /* Start converting the bumpers. */ Ports[M6811_ADCTL] = 3; /* Wait for conversion to complete. */ while (!(Ports[M6811_ADCTL] & BIT7)) { OS_Yield(); } b = Ports[M6811_ADR1]; OS_Signal(S_PORTE); /* Move based on the bumper values. (b) */ /* Turn Left */ if (b > 3 && b < 7) { Ports[M6811_DDRD] = 0xFF; Ports[M6811_PORTD] CLR_BIT(BIT5); // Reverse Right Ports[M6811_PORTA] CLR_BIT(BIT6); // Left Ports[M6811_PORTA] SET_BIT(BIT5); // Right //OS_Write(f,1); } /* Turn Right */ else if (b > 23 && b < 26) { Ports[M6811_DDRD] = 0xFF; Ports[M6811_PORTD] CLR_BIT(BIT4); // Reverse Left Ports[M6811_PORTA] SET_BIT(BIT6); // Left Ports[M6811_PORTA] CLR_BIT(BIT5); // Right //OS_Write(f,2); } /* Move Ahead */ else if (b > 67 && b < 70) { Ports[M6811_DDRD] = 0xFF; Ports[M6811_PORTD] = 0xFF; // Forward Ports[M6811_PORTA] SET_BIT(BIT6); // Left Ports[M6811_PORTA] SET_BIT(BIT5); // Right //OS_Write(f,3); } /* Stop */ else { Ports[M6811_PORTA] CLR_BIT(BIT6); Ports[M6811_PORTA] CLR_BIT(BIT5); //OS_Write(f,4); } OS_Yield(); } }
void Task_Animate (void) { static bit bSlow = 0; // Some objects animated slow static char s_cPhase = 0; // Animation phase: 0..3 static near char x, y; // Declared as 'near' to increaze speed static near char A, B; // Current map point and object static char *pmap; char temp; //for (;;) { CLRWDT(); OS_Bsem_Set(BS_MAP_FREE); // Free map OS_Flag_Wait_11(i_cStep, 0x04); OS_Flag_Set_0(i_cStep, 0x04); OS_Bsem_Wait(BS_MAP_FREE); bSlow = !bSlow; if (!bSlow) s_cPhase++; //------------------------------------------------------------------------------ // When all jewels are picked, change all colors to light white to // immitate a flash blink. //------------------------------------------------------------------------------ if (m_bBlinked) { LoadColors(m_cCurMap); m_bBlinked = 0; } //------------------------------------------------------------------------------ // Restore colors after flashing //------------------------------------------------------------------------------ if (m_bBlink) // Зажигаем вспышку { for (x = 0; x < 32; x++) m_Colors[x] = CL_LTWHITE; m_bBlinked = 1; // Говорим, что ее нужно погасить при следующем вызове m_bBlink = 0; } //------------------------------------------------------------------------------ // Make animation for all elements on map //------------------------------------------------------------------------------ pmap = (char*)m_Map; for (y = 0; y < MAP_SIZE_Y; y++) { OS_Yield(); for (x = 0; x < MAP_SIZE_X; x++) { A = *pmap; // Current element B = A & 0x1F; if (B < 4) goto NEXT; // Space, dirt, boulder, wall if (B == 0x1F) goto NEXT; // Last stage of bang if (B == OBJECT_MAN_EYES && bSlow) { A = OBJECT_MAN; goto CONTINUE; } B &= 0x1C; if (B == OBJECT_LEFT_MAN || B == OBJECT_RIGHT_MAN || (B==OBJECT_BANG && bSlow)) { // Running man temp = A + 1; A &= ~3; A |= (temp & 3); goto CONTINUE; } if (!bSlow) continue; if (B == OBJECT_JEWEL || B == OBJECT_BUTTERFLY || B == OBJECT_FIREFLY) { A &= ~3; A |= (s_cPhase & 3); goto CONTINUE; } if (B == OBJECT_TIT_WALL && (A & 0xC0)) // Home { if (((A & 0x80) && (m_cNeededJewels <= m_cJewels)) || ((A & 0x40) && m_cBornTimer)) { A ^= 1; goto CONTINUE; } } CONTINUE:; *pmap = A; NEXT:; pmap++; } } } }