-
-
Save samneggs/1e5ae813fa86de75f0c380c3c5f40444 to your computer and use it in GitHub Desktop.
| from time import sleep, ticks_us, ticks_diff, ticks_ms, sleep_ms | |
| import gc | |
| import _thread, array | |
| from machine import Timer, Pin, PWM | |
| from sys import exit | |
| class Game_Sound: | |
| def __init__(self): | |
| # index,start,dur,pause,number, volume | |
| self.SPIDER_TUNE = array.array('I',(5,0, 31,71,10,12,500,550,800,10000,500,550,800,10000,800,500,550)) # 24,60 | |
| self.EXPLODE2_TUNE= array.array('I',(5,0,100, 0, 5,7,100,90,80,70,60,60)) | |
| self.EXPLODE_TUNE = array.array('I',(5,0,41, 0, 5, 10,1400,1300,1400,1300,1400,1450)) | |
| self.BACK_TUNE = array.array('I',(5,0,120,800, 3,10,147,131,117,110)) # 5,0, 21, 21,8,10 | |
| self.FIRE_TUNE = array.array('I',(5,0,11,21, 4,10,1000,2300,1000,2300,1000)) | |
| self.SOUND = 0 | |
| self.OFF = 0 | |
| self.pwm = PWM(Pin(17)) | |
| Pin(16,Pin.OUT).high() | |
| self.pwm.duty_u16(1<<12) | |
| def reset_fire(self): | |
| self.BACK_TUNE[0] = 6 | |
| @micropython.viper | |
| def callback1(self): | |
| if self.OFF: return | |
| sound = int(self.SOUND) | |
| if sound & 1<<1: | |
| tune = ptr32(self.EXPLODE2_TUNE) | |
| elif sound & 1<<3: | |
| tune = ptr32(self.FIRE_TUNE) | |
| elif sound & 1<<2: | |
| tune = ptr32(self.EXPLODE_TUNE) | |
| elif sound & 1<<0: | |
| tune = ptr32(self.BACK_TUNE) | |
| else: | |
| self.pwm.duty_u16(0) | |
| return | |
| index = tune[0] | |
| start_ms = tune[1] | |
| dur = tune[2] | |
| pause = tune[3] | |
| number = tune[4] | |
| volume = tune[5] | |
| now_ms = int(ticks_ms()) | |
| if now_ms - start_ms < dur: # or start_ms == 0: | |
| self.pwm.duty_u16(1<<volume) | |
| if tune[index] >=50: # not too low freq | |
| self.pwm.freq(tune[index]) | |
| else: | |
| self.pwm.duty_u16(0) | |
| elif now_ms - start_ms < pause: | |
| self.pwm.duty_u16(0) | |
| else: | |
| tune[0] += 1 | |
| if tune[0] > number+6: | |
| tune[0] = 5 | |
| if not(sound & 1<<0) or 1: | |
| self.SOUND = 1<<0 | |
| else: | |
| tune[1] = int(ticks_ms()) # reset time | |
| def deinit(self): | |
| self.pwm.duty_u16(0) | |
| self.SOUND = 0 | |
| #self.timer1.deinit() | |
| @micropython.viper | |
| def core1(): | |
| global EXIT, GAME_SOUND | |
| GAME_SOUND = Game_Sound() | |
| GAME_SOUND.OFF = 0 | |
| while not EXIT: | |
| GAME_SOUND.callback1() | |
| sleep_ms(10) | |
| print('Core1 Stop') | |
| if __name__=='__main__': | |
| EXIT = False | |
| _thread.start_new_thread(core1, ()) | |
| sleep_ms(500) | |
| GAME_SOUND.SOUND = 0 | |
| for loop in range(3): | |
| GAME_SOUND.SOUND = 1<<1 | |
| sleep_ms(1000) | |
| #sleep(2) | |
| GAME_SOUND.deinit() | |
| exit() | |
| # Convert Program | |
| # Generated bytearray from: Space Invaders.bin | |
| # Total size: 3588 bytes | |
| binary_data = bytearray([ | |
| 0x04, 0x40, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
| 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
| 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, | |
| 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, | |
| 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, | |
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, | |
| 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, | |
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
| 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, | |
| 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, | |
| 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, | |
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
| 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
| 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, | |
| 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, | |
| 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, | |
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, | |
| 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, | |
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, | |
| 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, | |
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, | |
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, | |
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, | |
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, | |
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, | |
| 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, | |
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, | |
| 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, | |
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |
| 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |
| 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, | |
| 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, | |
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, | |
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, | |
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, | |
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, | |
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, | |
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, | |
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
| 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, | |
| 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, | |
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, | |
| 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, | |
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |
| 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, | |
| 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, | |
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, | |
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, | |
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
| 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
| 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |
| 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, | |
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |
| 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, | |
| 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |
| 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, | |
| 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, | |
| 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, | |
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, | |
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, | |
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
| 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |
| 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, | |
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |
| 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, | |
| 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |
| 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, | |
| 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, | |
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, | |
| 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, | |
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, | |
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, | |
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, | |
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, | |
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, | |
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, | |
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, | |
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, | |
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
| 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, | |
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, | |
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, | |
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, | |
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
| 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, | |
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, | |
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, | |
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, | |
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, | |
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, | |
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, | |
| 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, | |
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, | |
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, | |
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
| 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, | |
| 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |
| 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, | |
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |
| 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, | |
| 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, | |
| 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |
| 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |
| 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, | |
| 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, | |
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, | |
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, | |
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, | |
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
| 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, | |
| 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, | |
| 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, | |
| 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, | |
| 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
| 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
| 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
| 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, | |
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
| 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, | |
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, | |
| 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
| 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, | |
| 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, | |
| 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, | |
| 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, | |
| 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, | |
| 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
| 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
| 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
| 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, | |
| 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
| 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
| 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
| 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |
| 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |
| 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |
| 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |
| 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |
| 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |
| 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |
| 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |
| 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |
| 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, | |
| 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
| 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
| 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, | |
| 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, | |
| 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
| 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, | |
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |
| 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, | |
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, | |
| 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, | |
| 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
| 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, | |
| 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
| 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, | |
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, | |
| 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, | |
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |
| 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, | |
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |
| 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, | |
| 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
| 0x00, 0x00, 0x00, 0x00 | |
| ]) | |
| with open ('Space Invaders.bin', "w") as file: | |
| file.write(binary_data) | |
| file.close() | |
| b = bytearray([ | |
| 0x00, 0xff, 0x00, | |
| 0xff, 0x00, 0x00, | |
| 0x00, 0xff, 0x00, | |
| 0x00, 0x00, 0xff, | |
| 0x00, 0xff, 0x00, | |
| 0xff, 0x00, 0x00, | |
| 0x00, 0xff, 0x00, | |
| 0xff, 0x00, 0x00, | |
| 0x00, 0xff, 0x00, | |
| 0x00, 0x00, 0xff, | |
| 0x00, 0xff, 0x00, | |
| 0xff, 0x00, 0x00, | |
| 0x00, 0xff, 0x00, | |
| 0x00, 0x00, 0xff, | |
| 0x00, 0xff, 0x00, | |
| 0x00, 0x00, 0xff, | |
| 0x00, 0xff, 0x00, | |
| 0xff, 0x00, 0x00, | |
| 0x00, 0xff, 0x00, | |
| 0x00, 0x00, 0xff, | |
| 0x00, 0xff, 0x00, | |
| 0x00, 0x00, 0xff, | |
| 0x00, 0xff, 0x00, | |
| 0xff, 0x00, 0x00, | |
| 0x00, 0xff, 0x00, | |
| 0x00, 0x00, 0xff, | |
| 0x00, 0xff, 0x00, | |
| 0xff, 0x00, 0x00, | |
| 0x00, 0xff, 0x00, | |
| 0x00, 0xff, 0x00, | |
| 0x00, 0xff, 0x00, | |
| 0x00, 0xff, 0x00, | |
| 0x00, 0xff, 0x00, | |
| 0x00, 0xff, 0x00, | |
| 0xff, 0xff, 0xff, | |
| 0x00, 0xff, 0x00, | |
| 0x00, 0xff, 0x00, | |
| 0x00, 0xff, 0x00, | |
| 0x00, 0xff, 0x00, | |
| 0xff, 0xff, 0xff, | |
| 0x00, 0xff, 0x00, | |
| 0x00, 0xff, 0x00, | |
| 0x00, 0xff, 0x00, | |
| 0x00, 0xff, 0x00, | |
| 0xff, 0xff, 0xff, | |
| 0x00, 0xff, 0x00, | |
| 0x00, 0xff, 0x00, | |
| 0x00, 0xff, 0x00, | |
| 0x00, 0xff, 0x00, | |
| 0xff, 0xff, 0xff, | |
| 0x00, 0xff, 0x00, | |
| 0x00, 0xff, 0x00, | |
| 0x00, 0xff, 0x00, | |
| 0x00, 0xff, 0x00, | |
| 0x00, 0xff, 0x00, | |
| 0x00, 0xff, 0x00, | |
| 0x00, 0xff, 0x00, | |
| 0x00, 0xff, 0x00, | |
| 0x00, 0xff, 0x00, | |
| 0x00, 0xff, 0x00, | |
| 0x00, 0xff, 0x00, | |
| 0x00, 0xff, 0x00, | |
| 0x00, 0xff, 0x00, | |
| 0x00, 0xff, 0x00, | |
| 0x00, 0xff, 0x00, | |
| 0xff, 0xff, 0x00, | |
| 0x00, 0xff, 0xff, | |
| 0x00, 0xff, 0x00, | |
| 0xff, 0xff, 0x00, | |
| 0x00, 0xff, 0xff, | |
| 0x00, 0xff, 0x00, | |
| 0x00, 0xff, 0x00, | |
| 0x00, 0xff, 0x00, | |
| 0x00, 0xff, 0x00, | |
| 0x00, 0xff, 0x00, | |
| 0x00, 0xff, 0x00, | |
| 0x00, 0xff, 0x00, | |
| 0x00, 0xff, 0xff, | |
| 0xff, 0xff, 0x00, | |
| 0x00, 0xff, 0x00, | |
| 0x00, 0xff, 0xff, | |
| 0xff, 0xff, 0x00, | |
| 0x00, 0xff, 0x00, | |
| 0x00, 0xff, 0x00]) | |
| with open ('s_inv_miss.bin', "w") as file: | |
| file.write(b) | |
| file.close() |
| # Space Invaders | |
| from lcd_1_8 import LCD_1inch8 | |
| import machine | |
| from machine import Pin, PWM | |
| from uctypes import addressof | |
| from time import sleep, ticks_us, ticks_diff, ticks_ms, sleep_ms | |
| import gc, _thread, array | |
| from sys import exit | |
| from micropython import const | |
| from random import randint | |
| from math import sin,cos,tan,radians,sqrt | |
| #from rp2 import bootsel_button as RESET_PB | |
| from invaders_sound import Game_Sound | |
| with open ('Space Invaders.bin', "rb") as file: | |
| SPRITES = file.read() | |
| file.close() | |
| with open ('s_inv_miss.bin', "rb") as file: | |
| MISS_SPR = file.read() | |
| file.close() | |
| MAXSCREEN_X = const(160) | |
| MAXSCREEN_Y = const(128) | |
| SCALE = const(13) | |
| COLUMNS = const(10) | |
| S_WIDTH = const(16) | |
| S_HEIGHT = const(8) | |
| NUM_BUNKERS = const(4) | |
| NUM_MISSILES = const(3) | |
| BUNKER_Y = const(100) | |
| PLAYER_Y = const(119) | |
| START_SPEED = const(200) | |
| SPEEDUP =const(4) | |
| BUNKER_HEIGHT = const(16) | |
| PLAYER_PARAMS = const(10) | |
| # X,Y | |
| FIRE = const(2) | |
| HIT = const(3) | |
| INVADER_PARAMS = const(10) | |
| X = const(0) | |
| Y = const(1) | |
| DIR = const(2) | |
| LEFT = const(3) | |
| RIGHT = const(4) | |
| BOTTOM = const(5) | |
| COUNT = const(6) | |
| MISSILE_PARAMS = const(10) | |
| #X,Y,DIR | |
| M_SPRITE = const(3) | |
| M_SPRITE2 = const(4) | |
| GAME_PARAMS = const(10) | |
| FPS = const(0) | |
| LIVES = const(1) | |
| SPEED = const(2) | |
| TOGGLE = const(3) | |
| TIME = const(4) | |
| BUNKERS= const(5) | |
| SCORE = const(6) | |
| SCORE_MAP = bytearray([30,20,20,10,10]) | |
| EXP_MAP=array.array('b',( | |
| 0,0,1,0,0,0, | |
| 1,0,0,0,1,0, | |
| 0,0,1,1,0,1, | |
| 0,1,1,1,1,0, | |
| 1,0,1,1,1,0, | |
| 0,1,1,1,1,1, | |
| 1,0,1,1,1,0, | |
| 0,1,0,1,0,1)) | |
| char_map=array.array('b',( | |
| 0x3E, 0x63, 0x73, 0x7B, 0x6F, 0x67, 0x3E, 0x00, # U+0030 (0) | |
| 0x0C, 0x0E, 0x0C, 0x0C, 0x0C, 0x0C, 0x3F, 0x00, # U+0031 (1) | |
| 0x1E, 0x33, 0x30, 0x1C, 0x06, 0x33, 0x3F, 0x00, # U+0032 (2) | |
| 0x1E, 0x33, 0x30, 0x1C, 0x30, 0x33, 0x1E, 0x00, # U+0033 (3) | |
| 0x38, 0x3C, 0x36, 0x33, 0x7F, 0x30, 0x78, 0x00, # U+0034 (4) | |
| 0x3F, 0x03, 0x1F, 0x30, 0x30, 0x33, 0x1E, 0x00, # U+0035 (5) | |
| 0x1C, 0x06, 0x03, 0x1F, 0x33, 0x33, 0x1E, 0x00, # U+0036 (6) | |
| 0x3F, 0x33, 0x30, 0x18, 0x0C, 0x0C, 0x0C, 0x00, # U+0037 (7) | |
| 0x1E, 0x33, 0x33, 0x1E, 0x33, 0x33, 0x1E, 0x00, # U+0038 (8) | |
| 0x1E, 0x33, 0x33, 0x3E, 0x30, 0x18, 0x0E, 0x00)) # U+0039 (9) | |
| @micropython.viper | |
| def show_num_viper(num:int,x_offset:int,y_offset:int,color:int): | |
| char_ptr = ptr8(char_map) | |
| screen_ptr = ptr16(LCD.buffer) | |
| size = 1 # 1,2,3 | |
| char = 0 | |
| offset = MAXSCREEN_X*y_offset+x_offset | |
| while num > 0: | |
| total = num//10 | |
| digit = num - (total * 10) | |
| num = total | |
| for y in range(8): | |
| row_data = char_ptr[digit*8+y] | |
| for x in range(8): | |
| if row_data & (1<<x) > 0: | |
| addr = size*y*MAXSCREEN_X+x-(char*8)+offset | |
| screen_ptr[addr] = color | |
| if size>1: | |
| screen_ptr[MAXSCREEN_X+addr] = color | |
| if size>2: | |
| screen_ptr[2*MAXSCREEN_X+addr] = color | |
| char += 1 | |
| def init_pot(): | |
| global POT_X,POT_Y,POT_X_ZERO,POT_Y_ZERO | |
| POT_X = machine.ADC(27) | |
| POT_Y = machine.ADC(26) | |
| POT_X_ZERO = 0 | |
| POT_Y_ZERO = 0 | |
| for i in range(1000): | |
| POT_X_ZERO += POT_X.read_u16() | |
| POT_Y_ZERO += POT_Y.read_u16() | |
| POT_X_ZERO = POT_X_ZERO//1000 | |
| POT_Y_ZERO = POT_Y_ZERO//1000 | |
| pot_scale = 12 | |
| @micropython.viper | |
| def read_pot(): | |
| player = ptr32(PLAYER) | |
| missile = ptr32(MISSILE) | |
| pot_scale = 12 | |
| x_inc = int(POT_X.read_u16() - POT_X_ZERO)>>pot_scale | |
| y_inc = int(POT_Y.read_u16() - POT_Y_ZERO)>>pot_scale | |
| x_inc += 2 | |
| if x_inc < 2 and x_inc > -2: | |
| x_inc=0 | |
| if not FIRE_BUTTON.value(): | |
| player[FIRE] = 1 | |
| if missile[Y] == 0: | |
| if int(GAME_SOUND.SOUND) & 1<<3 == 0: | |
| GAME_SOUND.SOUND = int(GAME_SOUND.SOUND) | 1<<3 | |
| missile[Y] = PLAYER_Y-1 | |
| missile[X] = player[X] + 8 | |
| x = player[X] - x_inc//4 | |
| if x > 0 and x < 145: | |
| player[X] = x | |
| def init_invaders(): | |
| global INVADERS, ALIVE, FIRE_INV | |
| INVADERS = array.array('i',0 for _ in range(INVADER_PARAMS)) | |
| ALIVE = bytearray(5 * COLUMNS) # 3 = alive, 2 and 1 = exploding | |
| FIRE_INV = bytearray(11) # bottom invaders that can fire | |
| def init_player(): | |
| global PLAYER, MISSILE | |
| PLAYER = array.array('i',0 for _ in range(PLAYER_PARAMS)) | |
| MISSILE = array.array('i',0 for _ in range(MISSILE_PARAMS*3)) | |
| MISSILE[DIR] = -2 # player missile direction and speed | |
| MISSILE[DIR+MISSILE_PARAMS] = 1 # invader missile #1 dir and speed | |
| MISSILE[DIR+MISSILE_PARAMS*2] = 1 # invader missile #2 | |
| PLAYER[HIT] = 0 # 0=alive, 2,1 = exploding | |
| def init_game(): | |
| global GAME, FPS_ARRY | |
| GAME = array.array('i',0 for _ in range(GAME_PARAMS)) | |
| FPS_ARRY = bytearray(35) | |
| GAME[FPS] = 0 | |
| GAME[LIVES] = 3 | |
| def init_bunker(): | |
| global BUNKER | |
| BUNKER = bytearray(160*20) # 16 | |
| def reset_bunker(): | |
| for b in range(NUM_BUNKERS): | |
| for y in range(0,5): | |
| for x in range(5-y,17+y): | |
| BUNKER[y*MAXSCREEN_X+x+b*40+10] = 1 | |
| for y in range(5,16): | |
| for x in range(22): | |
| BUNKER[y*MAXSCREEN_X+x+b*40+10] = 1 | |
| for y in range(11,16): | |
| for x in range(19-y,3+y): | |
| BUNKER[y*MAXSCREEN_X+x+b*40+10] = 0 | |
| def reset_invaders(): | |
| for i in range(5 * COLUMNS): | |
| ALIVE[i] = 3 | |
| INVADERS[X] = 2 | |
| INVADERS[Y] = 0 | |
| INVADERS[DIR] = 1 | |
| INVADERS[COUNT] = 5 * COLUMNS | |
| GAME[TIME] = START_SPEED | |
| GAME[BUNKERS] = 1 | |
| @micropython.viper | |
| def move(): | |
| player = ptr32(PLAYER) | |
| game = ptr32(GAME) | |
| invaders = ptr32(INVADERS) | |
| alive = ptr8(ALIVE) | |
| if player[HIT] == 0: | |
| game[TOGGLE] ^= 1 | |
| invaders[X] += invaders[DIR] | |
| right_most = (COLUMNS * 14) - (invaders[RIGHT] * 14) | |
| left_most = invaders[LEFT] * 14 | |
| bottom_most = (3+invaders[BOTTOM]) * 10 + invaders[Y]//MAXSCREEN_X | |
| if invaders[X] > right_most or invaders[X]+left_most < 1 : # edge of screen, move down | |
| invaders[DIR] *= -1 | |
| invaders[Y] += 4*MAXSCREEN_X | |
| if bottom_most > BUNKER_Y+8: | |
| game[BUNKERS] = 0 | |
| if bottom_most > 130: | |
| game[LIVES] -= 1 | |
| reset_invaders() | |
| for i in range(5 * COLUMNS): # invader explosions | |
| if alive[i] < 3 and alive[i] > 0: | |
| alive[i] -= 1 | |
| if player[HIT] > 0: # player explosion | |
| player[HIT] -= 1 | |
| if player[HIT] == 0: | |
| game[LIVES] -= 1 | |
| if game[LIVES] == 0: | |
| game_over() | |
| @micropython.viper | |
| def move_missiles(): | |
| missile = ptr32(MISSILE) | |
| player = ptr32(PLAYER) | |
| for index in range(NUM_MISSILES): | |
| i = index * MISSILE_PARAMS | |
| if missile[Y + i] > 0 and missile[Y + i] < MAXSCREEN_Y-7: | |
| missile[Y + i] += missile[DIR + i] # move missile up or down | |
| miss_collision() | |
| missile[M_SPRITE + i] += 1 | |
| if missile[M_SPRITE + i] > 3*4: | |
| missile[M_SPRITE + i] = 0 | |
| elif i==0: | |
| player[FIRE] = 1 | |
| else: | |
| missile[Y + i] = 0 # clear missile from bottom | |
| @micropython.viper | |
| def miss_collision(): | |
| player = ptr32(PLAYER) | |
| missile = ptr32(MISSILE) | |
| invaders = ptr32(INVADERS) | |
| alive = ptr8(ALIVE) | |
| game = ptr32(GAME) | |
| bunker = ptr8(BUNKER) | |
| m_x = missile[X] | |
| m_y = missile[Y] | |
| inv_x = invaders[X] | |
| inv_y = invaders[Y] // MAXSCREEN_X | |
| for i in range(5 * COLUMNS): # check missile vs invaders | |
| if alive[i] == 3: | |
| i_x = (i % COLUMNS)*14 + inv_x | |
| i_y = (i // COLUMNS)*10 + inv_y + 10 | |
| if m_x > i_x and m_x < i_x + 14 and m_y > i_y and m_y < i_y + 14: | |
| GAME_SOUND.SOUND = int(GAME_SOUND.SOUND) | 1<<2 | |
| game[SCORE] += int(SCORE_MAP[i // COLUMNS]) | |
| player[FIRE] = 0 | |
| missile[Y] = 0 | |
| alive[i] -= 1 | |
| get_edges() | |
| game[TIME] -= SPEEDUP | |
| GAME_SOUND.BACK_TUNE[3] = 200 + game[TIME]*3 # 800 max | |
| invaders[COUNT] -= 1 | |
| if invaders[COUNT] == 0: | |
| reset_invaders() | |
| reset_bunker() | |
| p_x = player[X] | |
| p_y = PLAYER_Y | |
| pm_x = missile[X] # player missile | |
| pm_y = missile[Y] | |
| for index in range(1,NUM_MISSILES-1): | |
| i = index * MISSILE_PARAMS | |
| m_x = missile[X + i] | |
| m_y = missile[Y + i] | |
| if m_y > 0 and m_x > p_x and m_x < p_x + 16 and m_y > p_y and m_y < p_y + 8: # invader missile vs player | |
| missile[Y + i] = 0 | |
| player[HIT] = 10 #2 | |
| GAME_SOUND.SOUND = 1<<1 | |
| break | |
| if game[BUNKERS] == 1 and m_y >= BUNKER_Y and m_y < BUNKER_Y + 22: # invader missile vs bunker | |
| b_y = m_y-BUNKER_Y | |
| if bunker[b_y * MAXSCREEN_X + m_x] == 1: | |
| missile[Y + i] = 0 | |
| bunker_exp(m_x,b_y+2) | |
| if m_y > 0 and pm_y > 0 and m_x > pm_x and m_x < pm_x + 3 and m_y > pm_y and m_y < pm_y + 7: # invader missile vs player missile | |
| missile[Y + i] = 0 | |
| missile[Y] = 0 | |
| if game[BUNKERS] == 1 and pm_y >= BUNKER_Y and pm_y < BUNKER_Y + 22 and pm_x > 9: # player missile vs bunker | |
| b_y = pm_y-BUNKER_Y | |
| if bunker[b_y * MAXSCREEN_X + pm_x] == 1 or bunker[(b_y+1) * MAXSCREEN_X + pm_x] == 1 : | |
| missile[Y] = 0 | |
| bunker_exp(pm_x,b_y+2) | |
| @micropython.viper | |
| def bunker_exp(e_x:int,e_y:int): | |
| bunker = ptr8(BUNKER) | |
| exp_map= ptr8(EXP_MAP) | |
| for y in range(-4,4): | |
| for x in range(-3,3): | |
| bunk_addr = (e_y + y) * MAXSCREEN_X + e_x + x | |
| exp = exp_map[(y+4)*8 + x + 3] | |
| if exp == 1 and bunk_addr > 0 and bunk_addr < MAXSCREEN_X * 16: | |
| bunker[bunk_addr] = 0 | |
| @micropython.viper | |
| def get_edges(): | |
| game = ptr32(GAME) | |
| invaders = ptr32(INVADERS) | |
| alive = ptr8(ALIVE) | |
| fire_inv = ptr8(FIRE_INV) | |
| invaders[RIGHT] = 0 | |
| invaders[LEFT] = 10 | |
| invaders[BOTTOM] = 0 | |
| for i in range(5 * COLUMNS): | |
| if alive[i] == 3: | |
| x = i % COLUMNS | |
| y = i // COLUMNS | |
| if x > invaders[RIGHT]: invaders[RIGHT] = x | |
| if x < invaders[LEFT]: invaders[LEFT] = x | |
| if y > invaders[BOTTOM]: invaders[BOTTOM] = y | |
| for x in range(COLUMNS): # find the bottom invaders that can fire | |
| fire_inv[x] = 0 | |
| for y in range(5): | |
| if alive[y * COLUMNS + x] == 3: | |
| fire_inv[x] = y + 1 | |
| @micropython.viper | |
| def invaders_fire(): | |
| invaders = ptr32(INVADERS) | |
| missile = ptr32(MISSILE) | |
| fire_inv = ptr8(FIRE_INV) | |
| for index in range(1,NUM_MISSILES): | |
| i = index * MISSILE_PARAMS | |
| if missile[Y + i] > 0 and missile[Y + i] < MAXSCREEN_Y: continue | |
| firing_invader = int(randint(0,COLUMNS)) | |
| while fire_inv[firing_invader] == 0: # find random bottom invader | |
| firing_invader += 1 | |
| if firing_invader > COLUMNS: firing_invader = 0 # loop around | |
| missile[Y + i] = invaders[Y]//MAXSCREEN_X + fire_inv[firing_invader] * 8 + 10 | |
| missile[X + i] = invaders[X] + firing_invader * 14 + 7 | |
| missile[M_SPRITE2 + i] = int(randint(0,2))*4 # start sprite 0,4,8 | |
| missile[M_SPRITE + i] = 0 | |
| return | |
| @micropython.viper | |
| def draw_invaders(): | |
| sprites = ptr16(SPRITES) | |
| screen = ptr16(LCD.buffer) | |
| invaders = ptr32(INVADERS) | |
| game = ptr32(GAME) | |
| alive = ptr8(ALIVE) | |
| sprite_offset = 2 + game[TOGGLE]*S_HEIGHT*S_WIDTH | |
| screen_offset = invaders[Y]+10*MAXSCREEN_X + invaders[X] | |
| for x1 in range(COLUMNS): | |
| test_alive = alive[x1] | |
| if test_alive > 0: | |
| if test_alive < 3: | |
| sprite_offset = 2 + S_WIDTH*S_HEIGHT*5 + (test_alive)*8*S_WIDTH | |
| else: | |
| sprite_offset = 2 + game[TOGGLE]*S_HEIGHT*S_WIDTH | |
| for y in range(S_HEIGHT): | |
| for x in range(S_WIDTH): | |
| color = sprites[sprite_offset + y*S_WIDTH + x] | |
| screen[y*MAXSCREEN_X + x+x1*14+screen_offset] = color | |
| sprite_offset = 2 + S_WIDTH*S_HEIGHT*2 + game[TOGGLE]*S_HEIGHT*S_WIDTH | |
| screen_offset = invaders[Y]+20*MAXSCREEN_X + invaders[X] | |
| for y1 in range(2): | |
| for x1 in range(COLUMNS): | |
| test_alive = alive[(y1+1)*COLUMNS + x1] | |
| if test_alive > 0: | |
| if test_alive < 3: | |
| sprite_offset = 2 + S_WIDTH*S_HEIGHT*5 + (test_alive)*8*S_WIDTH | |
| else: | |
| sprite_offset = 2 + S_WIDTH*S_HEIGHT*2 + game[TOGGLE]*S_HEIGHT*S_WIDTH | |
| for y in range(S_HEIGHT): | |
| for x in range(S_WIDTH): | |
| color = sprites[sprite_offset + y*S_WIDTH + x] | |
| screen[y1*10*MAXSCREEN_X+y*MAXSCREEN_X + x+x1*14+screen_offset] = color | |
| sprite_offset = 2 + S_WIDTH*S_HEIGHT*4 + game[TOGGLE]*8*S_WIDTH | |
| screen_offset = invaders[Y]+40*MAXSCREEN_X + invaders[X] | |
| for y1 in range(2): | |
| for x1 in range(COLUMNS): | |
| test_alive = alive[(y1+3)*COLUMNS + x1] | |
| if test_alive > 0: | |
| if test_alive < 3: | |
| sprite_offset = 2 + S_WIDTH*S_HEIGHT*5 + (test_alive)*8*S_WIDTH | |
| else: | |
| sprite_offset = 2 + S_WIDTH*S_HEIGHT*4 + game[TOGGLE]*8*S_WIDTH | |
| for y in range(S_HEIGHT): | |
| for x in range(S_WIDTH): | |
| color = sprites[sprite_offset + y*S_WIDTH + x] | |
| screen[y1*10*MAXSCREEN_X+y*MAXSCREEN_X + x+x1*14+screen_offset] = color | |
| @micropython.viper | |
| def draw_player(): | |
| sprites = ptr16(SPRITES) | |
| screen = ptr16(LCD.buffer) | |
| invaders = ptr32(INVADERS) | |
| player = ptr32(PLAYER) | |
| game = ptr32(GAME) | |
| if player[HIT] > 0: | |
| sprite_offset = 2 + S_WIDTH*S_HEIGHT*(11+(player[HIT]%2)) | |
| else: | |
| sprite_offset = 2 + S_WIDTH*S_HEIGHT*11 | |
| screen_offset = MAXSCREEN_X * PLAYER_Y + player[X] | |
| for y in range(S_HEIGHT): | |
| for x in range(S_WIDTH): | |
| color = sprites[sprite_offset + y*S_WIDTH + x] | |
| screen[y*MAXSCREEN_X + x+screen_offset] = color | |
| @micropython.viper | |
| def draw_bunker(): | |
| game = ptr32(GAME) | |
| bunker = ptr8(BUNKER) | |
| screen = ptr16(LCD.buffer) | |
| if not game[BUNKERS]: return | |
| screen_offset = MAXSCREEN_X*BUNKER_Y | |
| for y in range(BUNKER_HEIGHT): | |
| for x in range(MAXSCREEN_X): | |
| color = bunker[y*MAXSCREEN_X+x] | |
| if color > 0: | |
| screen[screen_offset + y * MAXSCREEN_X + x] = 0xe007 | |
| @micropython.viper | |
| def draw_missile(): | |
| missile = ptr32(MISSILE) | |
| screen = ptr16(LCD.buffer) | |
| miss_spr = ptr8(MISS_SPR) | |
| for index in range(1,NUM_MISSILES): # invader missiles | |
| i = index * MISSILE_PARAMS | |
| if missile[Y + i] > 0 and missile[Y + i] < MAXSCREEN_Y: | |
| x = missile[X + i] | |
| y = missile[Y + i] | |
| offset = missile[M_SPRITE2 + i] + (missile[M_SPRITE + i] // 4) | |
| for y1 in range(7): | |
| for x1 in range(3): | |
| miss_addr = y1 * 3 + x1 + (offset * 3 * 7) | |
| if miss_spr[miss_addr] == 0xff: | |
| screen[(y+y1) * 160 + x + x1] = 0xffff | |
| if missile[Y] > 0: # player missile | |
| x = missile[X] | |
| y = missile[Y] | |
| LCD.line(x,y,x,y+7,0xffff) | |
| def game_over(): | |
| GAME_SOUND.SOUND = 0 | |
| LCD.text('GAME OVER',40,50,0xff) | |
| LCD.show() | |
| exit() | |
| @micropython.viper | |
| def draw(): | |
| draw_invaders() | |
| draw_player() | |
| draw_bunker() | |
| draw_missile() | |
| game = ptr32(GAME) | |
| if game[SCORE] == 0: | |
| LCD.text('FPS',0,80,0xff) | |
| show_num_viper(game[FPS],40,80,0xff) | |
| if game[SCORE] == 10 : | |
| LCD.text('FREE MEM',0,90,0xff) | |
| show_num_viper(gc.mem_free(),120,90,0xff) | |
| LCD.text('SCORE',0,0,0xff) | |
| show_num_viper(game[SCORE],70,0,0xff) | |
| LCD.text('LIVES',100,0,0xff) | |
| show_num_viper(game[LIVES],145,0,0xff) | |
| LCD.show() | |
| LCD.rect(0,0,MAXSCREEN_X,MAXSCREEN_Y,0,1) | |
| @micropython.asm_thumb | |
| def avg_fps_asm(r0,r1): # r0 = fps[] , r1 = current_fps | |
| ldrb(r2,[r0,0]) # r2 = fps[0] | |
| add(r2,r2,1) # fps[0] += 1 | |
| cmp(r2,33) | |
| blt(LT_32) # if fps[0] > 32: | |
| mov(r2,1) | |
| label(LT_32) | |
| strb(r2,[r0,0]) # fps[0] = new index | |
| add(r2,r2,r0) | |
| strb(r1,[r2,0]) # fps[fps[0]] = current_fps | |
| mov(r2,1) # r2 = i | |
| mov(r3,0) # r3 = tot | |
| label(LOOP) | |
| add(r0,r0,1) | |
| ldrb(r4,[r0,0]) # r4 = fps[i] | |
| add(r3,r3,r4) # tot += fps[i] | |
| add(r2,r2,1) | |
| cmp(r2,33) #33 | |
| blt(LOOP) | |
| asr(r0,r3,5) | |
| @micropython.viper | |
| def core1(): | |
| global EXIT, GAME_SOUND | |
| GAME_SOUND = Game_Sound() | |
| GAME_SOUND.OFF = 0 | |
| while not EXIT: | |
| GAME_SOUND.callback1() | |
| sleep_ms(10) | |
| @micropython.viper | |
| def main(): | |
| init_pot() | |
| init_game() | |
| init_player() | |
| init_invaders() | |
| init_bunker() | |
| reset_bunker() | |
| reset_invaders() | |
| get_edges() | |
| game = ptr32(GAME) | |
| pot_ticks = 0 | |
| move_ticks = 0 | |
| inv_fire_ticks = 0 | |
| GAME_SOUND.SOUND = 1<<0 | |
| while not EXIT: # and not RESET_PB(): | |
| gticks = int(ticks_ms()) | |
| sleep(0.001) | |
| if gticks > pot_ticks + 10: | |
| pot_ticks = gticks | |
| read_pot() | |
| if gticks > move_ticks + game[TIME] and 1: | |
| move_ticks = gticks | |
| move() | |
| if gticks > inv_fire_ticks + game[TIME]*10: | |
| inv_fire_ticks = gticks | |
| invaders_fire() | |
| move_missiles() | |
| draw() | |
| game[FPS] = int(avg_fps_asm(FPS_ARRY,1_000//int(ticks_diff(ticks_ms(),gticks)))) | |
| def shutdown(): | |
| global EXIT | |
| EXIT = True | |
| Pin(16,Pin.OUT).low() # buzzer off | |
| pwm.deinit() | |
| Pin(13,Pin.OUT).low() # screen off | |
| gc.collect() | |
| print(gc.mem_free()) | |
| print('Core0 Stop') | |
| exit() | |
| if __name__=='__main__': | |
| FIRE_BUTTON = Pin(22, Pin.IN, Pin.PULL_UP) | |
| #machine.freq(200_000_000) | |
| #machine.mem32[0x40008048] = 1<<11 # enable peri_ctrl clock | |
| machine.freq(220_000_000) #220 | |
| machine.mem32[0x40010048] = 1<<11 # enable peri_ctrl clock | |
| pwm = PWM(Pin(13)) | |
| pwm.freq(1000) | |
| pwm.duty_u16(0x8fff)#max 0xffff | |
| LCD = LCD_1inch8() | |
| LCD.fill(0) | |
| LCD.show() | |
| EXIT = False | |
| _thread.start_new_thread(core1, ()) | |
| #main() | |
| try: | |
| main() | |
| shutdown() | |
| except KeyboardInterrupt : | |
| shutdown() | |
| # Space Invaders | |
| from lcd_1_8 import LCD_1inch8 | |
| import machine | |
| from machine import Pin, PWM | |
| from uctypes import addressof | |
| from time import sleep, ticks_us, ticks_diff, ticks_ms, sleep_ms | |
| import gc, _thread, array | |
| from sys import exit | |
| from micropython import const | |
| from random import randint | |
| from math import sin,cos,tan,radians,sqrt | |
| from rp2 import bootsel_button as RESET_PB | |
| from invaders_sound import Game_Sound | |
| with open ('Space Invaders.bin', "rb") as file: | |
| SPRITES = file.read() | |
| file.close() | |
| with open ('s_inv_miss.bin', "rb") as file: | |
| MISS_SPR = file.read() | |
| file.close() | |
| MAXSCREEN_X = const(160) | |
| MAXSCREEN_Y = const(128) | |
| SCALE = const(13) | |
| COLUMNS = const(10) | |
| S_WIDTH = const(16) | |
| S_HEIGHT = const(8) | |
| NUM_BUNKERS = const(4) | |
| NUM_MISSILES = const(3) | |
| BUNKER_Y = const(100) | |
| PLAYER_Y = const(119) | |
| START_SPEED = const(200) | |
| SPEEDUP =const(4) | |
| BUNKER_HEIGHT = const(16) | |
| PLAYER_PARAMS = const(10) | |
| # X,Y | |
| FIRE = const(2) | |
| HIT = const(3) | |
| INVADER_PARAMS = const(10) | |
| X = const(0) | |
| Y = const(1) | |
| DIR = const(2) | |
| LEFT = const(3) | |
| RIGHT = const(4) | |
| BOTTOM = const(5) | |
| COUNT = const(6) | |
| MISSILE_PARAMS = const(10) | |
| #X,Y,DIR | |
| M_SPRITE = const(3) | |
| M_SPRITE2 = const(4) | |
| GAME_PARAMS = const(10) | |
| FPS = const(0) | |
| LIVES = const(1) | |
| SPEED = const(2) | |
| TOGGLE = const(3) | |
| TIME = const(4) | |
| BUNKERS= const(5) | |
| SCORE = const(6) | |
| SCORE_MAP = bytearray([30,20,20,10,10]) | |
| EXP_MAP=array.array('b',( | |
| 0,0,1,0,0,0, | |
| 1,0,0,0,1,0, | |
| 0,0,1,1,0,1, | |
| 0,1,1,1,1,0, | |
| 1,0,1,1,1,0, | |
| 0,1,1,1,1,1, | |
| 1,0,1,1,1,0, | |
| 0,1,0,1,0,1)) | |
| char_map=array.array('b',( | |
| 0x3E, 0x63, 0x73, 0x7B, 0x6F, 0x67, 0x3E, 0x00, # U+0030 (0) | |
| 0x0C, 0x0E, 0x0C, 0x0C, 0x0C, 0x0C, 0x3F, 0x00, # U+0031 (1) | |
| 0x1E, 0x33, 0x30, 0x1C, 0x06, 0x33, 0x3F, 0x00, # U+0032 (2) | |
| 0x1E, 0x33, 0x30, 0x1C, 0x30, 0x33, 0x1E, 0x00, # U+0033 (3) | |
| 0x38, 0x3C, 0x36, 0x33, 0x7F, 0x30, 0x78, 0x00, # U+0034 (4) | |
| 0x3F, 0x03, 0x1F, 0x30, 0x30, 0x33, 0x1E, 0x00, # U+0035 (5) | |
| 0x1C, 0x06, 0x03, 0x1F, 0x33, 0x33, 0x1E, 0x00, # U+0036 (6) | |
| 0x3F, 0x33, 0x30, 0x18, 0x0C, 0x0C, 0x0C, 0x00, # U+0037 (7) | |
| 0x1E, 0x33, 0x33, 0x1E, 0x33, 0x33, 0x1E, 0x00, # U+0038 (8) | |
| 0x1E, 0x33, 0x33, 0x3E, 0x30, 0x18, 0x0E, 0x00)) # U+0039 (9) | |
| @micropython.viper | |
| def show_num_viper(num:int,x_offset:int,y_offset:int,color:int): | |
| char_ptr = ptr8(char_map) | |
| screen_ptr = ptr16(LCD.buffer) | |
| size = 1 # 1,2,3 | |
| char = 0 | |
| offset = MAXSCREEN_X*y_offset+x_offset | |
| while num > 0: | |
| total = num//10 | |
| digit = num - (total * 10) | |
| num = total | |
| for y in range(8): | |
| row_data = char_ptr[digit*8+y] | |
| for x in range(8): | |
| if row_data & (1<<x) > 0: | |
| addr = size*y*MAXSCREEN_X+x-(char*8)+offset | |
| screen_ptr[addr] = color | |
| if size>1: | |
| screen_ptr[MAXSCREEN_X+addr] = color | |
| if size>2: | |
| screen_ptr[2*MAXSCREEN_X+addr] = color | |
| char += 1 | |
| def init_pot(): | |
| global POT_X,POT_Y,POT_X_ZERO,POT_Y_ZERO | |
| POT_X = machine.ADC(27) | |
| POT_Y = machine.ADC(26) | |
| POT_X_ZERO = 0 | |
| POT_Y_ZERO = 0 | |
| for i in range(1000): | |
| POT_X_ZERO += POT_X.read_u16() | |
| POT_Y_ZERO += POT_Y.read_u16() | |
| POT_X_ZERO = POT_X_ZERO//1000 | |
| POT_Y_ZERO = POT_Y_ZERO//1000 | |
| pot_scale = 12 | |
| @micropython.viper | |
| def read_pot(): | |
| player = ptr32(PLAYER) | |
| missile = ptr32(MISSILE) | |
| pot_scale = 12 | |
| x_inc = int(POT_X.read_u16() - POT_X_ZERO)>>pot_scale | |
| y_inc = int(POT_Y.read_u16() - POT_Y_ZERO)>>pot_scale | |
| x_inc += 2 | |
| if x_inc < 2 and x_inc > -2: | |
| x_inc=0 | |
| if not FIRE_BUTTON.value(): | |
| player[FIRE] = 1 | |
| if missile[Y] == 0: | |
| if int(GAME_SOUND.SOUND) & 1<<3 == 0: | |
| GAME_SOUND.SOUND = int(GAME_SOUND.SOUND) | 1<<3 | |
| missile[Y] = PLAYER_Y-1 | |
| missile[X] = player[X] + 8 | |
| x = player[X] - x_inc//4 | |
| if x > 0 and x < 145: | |
| player[X] = x | |
| def init_invaders(): | |
| global INVADERS, ALIVE, FIRE_INV | |
| INVADERS = array.array('i',0 for _ in range(INVADER_PARAMS)) | |
| ALIVE = bytearray(5 * COLUMNS) # 3 = alive, 2 and 1 = exploding | |
| FIRE_INV = bytearray(11) # bottom invaders that can fire | |
| def init_player(): | |
| global PLAYER, MISSILE | |
| PLAYER = array.array('i',0 for _ in range(PLAYER_PARAMS)) | |
| MISSILE = array.array('i',0 for _ in range(MISSILE_PARAMS*3)) | |
| MISSILE[DIR] = -2 # player missile direction and speed | |
| MISSILE[DIR+MISSILE_PARAMS] = 1 # invader missile #1 dir and speed | |
| MISSILE[DIR+MISSILE_PARAMS*2] = 1 # invader missile #2 | |
| PLAYER[HIT] = 0 # 0=alive, 2,1 = exploding | |
| def init_game(): | |
| global GAME, FPS_ARRY | |
| GAME = array.array('i',0 for _ in range(GAME_PARAMS)) | |
| FPS_ARRY = bytearray(35) | |
| GAME[FPS] = 0 | |
| GAME[LIVES] = 3 | |
| def init_bunker(): | |
| global BUNKER | |
| BUNKER = bytearray(160*20) # 16 | |
| def reset_bunker(): | |
| for b in range(NUM_BUNKERS): | |
| for y in range(0,5): | |
| for x in range(5-y,17+y): | |
| BUNKER[y*MAXSCREEN_X+x+b*40+10] = 1 | |
| for y in range(5,16): | |
| for x in range(22): | |
| BUNKER[y*MAXSCREEN_X+x+b*40+10] = 1 | |
| for y in range(11,16): | |
| for x in range(19-y,3+y): | |
| BUNKER[y*MAXSCREEN_X+x+b*40+10] = 0 | |
| def reset_invaders(): | |
| for i in range(5 * COLUMNS): | |
| ALIVE[i] = 3 | |
| INVADERS[X] = 2 | |
| INVADERS[Y] = 0 | |
| INVADERS[DIR] = 1 | |
| INVADERS[COUNT] = 5 * COLUMNS | |
| GAME[TIME] = START_SPEED | |
| GAME[BUNKERS] = 1 | |
| @micropython.viper | |
| def move(): | |
| player = ptr32(PLAYER) | |
| game = ptr32(GAME) | |
| invaders = ptr32(INVADERS) | |
| alive = ptr8(ALIVE) | |
| if player[HIT] == 0: | |
| game[TOGGLE] ^= 1 | |
| invaders[X] += invaders[DIR] | |
| right_most = (COLUMNS * 14) - (invaders[RIGHT] * 14) | |
| left_most = invaders[LEFT] * 14 | |
| bottom_most = (3+invaders[BOTTOM]) * 10 + invaders[Y]//MAXSCREEN_X | |
| if invaders[X] > right_most or invaders[X]+left_most < 1 : # edge of screen, move down | |
| invaders[DIR] *= -1 | |
| invaders[Y] += 4*MAXSCREEN_X | |
| if bottom_most > BUNKER_Y+8: | |
| game[BUNKERS] = 0 | |
| if bottom_most > 130: | |
| game[LIVES] -= 1 | |
| reset_invaders() | |
| for i in range(5 * COLUMNS): # invader explosions | |
| if alive[i] < 3 and alive[i] > 0: | |
| alive[i] -= 1 | |
| if player[HIT] > 0: # player explosion | |
| player[HIT] -= 1 | |
| if player[HIT] == 0: | |
| game[LIVES] -= 1 | |
| if game[LIVES] == 0: | |
| game_over() | |
| @micropython.viper | |
| def move_missiles(): | |
| missile = ptr32(MISSILE) | |
| player = ptr32(PLAYER) | |
| for index in range(NUM_MISSILES): | |
| i = index * MISSILE_PARAMS | |
| if missile[Y + i] > 0 and missile[Y + i] < MAXSCREEN_Y-7: | |
| missile[Y + i] += missile[DIR + i] # move missile up or down | |
| miss_collision() | |
| missile[M_SPRITE + i] += 1 | |
| if missile[M_SPRITE + i] > 3*4: | |
| missile[M_SPRITE + i] = 0 | |
| elif i==0: | |
| player[FIRE] = 1 | |
| else: | |
| missile[Y + i] = 0 # clear missile from bottom | |
| @micropython.viper | |
| def miss_collision(): | |
| player = ptr32(PLAYER) | |
| missile = ptr32(MISSILE) | |
| invaders = ptr32(INVADERS) | |
| alive = ptr8(ALIVE) | |
| game = ptr32(GAME) | |
| bunker = ptr8(BUNKER) | |
| m_x = missile[X] | |
| m_y = missile[Y] | |
| inv_x = invaders[X] | |
| inv_y = invaders[Y] // MAXSCREEN_X | |
| for i in range(5 * COLUMNS): # check missile vs invaders | |
| if alive[i] == 3: | |
| i_x = (i % COLUMNS)*14 + inv_x | |
| i_y = (i // COLUMNS)*10 + inv_y + 10 | |
| if m_x > i_x and m_x < i_x + 14 and m_y > i_y and m_y < i_y + 14: | |
| GAME_SOUND.SOUND = int(GAME_SOUND.SOUND) | 1<<2 | |
| game[SCORE] += int(SCORE_MAP[i // COLUMNS]) | |
| player[FIRE] = 0 | |
| missile[Y] = 0 | |
| alive[i] -= 1 | |
| get_edges() | |
| game[TIME] -= SPEEDUP | |
| GAME_SOUND.BACK_TUNE[3] = 200 + game[TIME]*3 # 800 max | |
| invaders[COUNT] -= 1 | |
| if invaders[COUNT] == 0: | |
| reset_invaders() | |
| reset_bunker() | |
| p_x = player[X] | |
| p_y = PLAYER_Y | |
| pm_x = missile[X] # player missile | |
| pm_y = missile[Y] | |
| for index in range(1,NUM_MISSILES-1): | |
| i = index * MISSILE_PARAMS | |
| m_x = missile[X + i] | |
| m_y = missile[Y + i] | |
| if m_y > 0 and m_x > p_x and m_x < p_x + 16 and m_y > p_y and m_y < p_y + 8: # invader missile vs player | |
| missile[Y + i] = 0 | |
| player[HIT] = 10 #2 | |
| GAME_SOUND.SOUND = 1<<1 | |
| break | |
| if game[BUNKERS] == 1 and m_y >= BUNKER_Y and m_y < BUNKER_Y + 22: # invader missile vs bunker | |
| b_y = m_y-BUNKER_Y | |
| if bunker[b_y * MAXSCREEN_X + m_x] == 1: | |
| missile[Y + i] = 0 | |
| bunker_exp(m_x,b_y+2) | |
| if m_y > 0 and pm_y > 0 and m_x > pm_x and m_x < pm_x + 3 and m_y > pm_y and m_y < pm_y + 7: # invader missile vs player missile | |
| missile[Y + i] = 0 | |
| missile[Y] = 0 | |
| if game[BUNKERS] == 1 and pm_y >= BUNKER_Y and pm_y < BUNKER_Y + 22 and pm_x > 9: # player missile vs bunker | |
| b_y = pm_y-BUNKER_Y | |
| if bunker[b_y * MAXSCREEN_X + pm_x] == 1 or bunker[(b_y+1) * MAXSCREEN_X + pm_x] == 1 : | |
| missile[Y] = 0 | |
| bunker_exp(pm_x,b_y+2) | |
| @micropython.viper | |
| def bunker_exp(e_x:int,e_y:int): | |
| bunker = ptr8(BUNKER) | |
| exp_map= ptr8(EXP_MAP) | |
| for y in range(-4,4): | |
| for x in range(-3,3): | |
| bunk_addr = (e_y + y) * MAXSCREEN_X + e_x + x | |
| exp = exp_map[(y+4)*8 + x + 3] | |
| if exp == 1 and bunk_addr > 0 and bunk_addr < MAXSCREEN_X * 16: | |
| bunker[bunk_addr] = 0 | |
| @micropython.viper | |
| def get_edges(): | |
| game = ptr32(GAME) | |
| invaders = ptr32(INVADERS) | |
| alive = ptr8(ALIVE) | |
| fire_inv = ptr8(FIRE_INV) | |
| invaders[RIGHT] = 0 | |
| invaders[LEFT] = 10 | |
| invaders[BOTTOM] = 0 | |
| for i in range(5 * COLUMNS): | |
| if alive[i] == 3: | |
| x = i % COLUMNS | |
| y = i // COLUMNS | |
| if x > invaders[RIGHT]: invaders[RIGHT] = x | |
| if x < invaders[LEFT]: invaders[LEFT] = x | |
| if y > invaders[BOTTOM]: invaders[BOTTOM] = y | |
| for x in range(COLUMNS): # find the bottom invaders that can fire | |
| fire_inv[x] = 0 | |
| for y in range(5): | |
| if alive[y * COLUMNS + x] == 3: | |
| fire_inv[x] = y + 1 | |
| @micropython.viper | |
| def invaders_fire(): | |
| invaders = ptr32(INVADERS) | |
| missile = ptr32(MISSILE) | |
| fire_inv = ptr8(FIRE_INV) | |
| for index in range(1,NUM_MISSILES): | |
| i = index * MISSILE_PARAMS | |
| if missile[Y + i] > 0 and missile[Y + i] < MAXSCREEN_Y: continue | |
| firing_invader = int(randint(0,COLUMNS)) | |
| while fire_inv[firing_invader] == 0: # find random bottom invader | |
| firing_invader += 1 | |
| if firing_invader > COLUMNS: firing_invader = 0 # loop around | |
| missile[Y + i] = invaders[Y]//MAXSCREEN_X + fire_inv[firing_invader] * 8 + 10 | |
| missile[X + i] = invaders[X] + firing_invader * 14 + 7 | |
| missile[M_SPRITE2 + i] = int(randint(0,2))*4 # start sprite 0,4,8 | |
| missile[M_SPRITE + i] = 0 | |
| return | |
| @micropython.viper | |
| def draw_invaders(): | |
| sprites = ptr16(SPRITES) | |
| screen = ptr16(LCD.buffer) | |
| invaders = ptr32(INVADERS) | |
| game = ptr32(GAME) | |
| alive = ptr8(ALIVE) | |
| sprite_offset = 2 + game[TOGGLE]*S_HEIGHT*S_WIDTH | |
| screen_offset = invaders[Y]+10*MAXSCREEN_X + invaders[X] | |
| for x1 in range(COLUMNS): | |
| test_alive = alive[x1] | |
| if test_alive > 0: | |
| if test_alive < 3: | |
| sprite_offset = 2 + S_WIDTH*S_HEIGHT*5 + (test_alive)*8*S_WIDTH | |
| else: | |
| sprite_offset = 2 + game[TOGGLE]*S_HEIGHT*S_WIDTH | |
| for y in range(S_HEIGHT): | |
| for x in range(S_WIDTH): | |
| color = sprites[sprite_offset + y*S_WIDTH + x] | |
| screen[y*MAXSCREEN_X + x+x1*14+screen_offset] = color | |
| sprite_offset = 2 + S_WIDTH*S_HEIGHT*2 + game[TOGGLE]*S_HEIGHT*S_WIDTH | |
| screen_offset = invaders[Y]+20*MAXSCREEN_X + invaders[X] | |
| for y1 in range(2): | |
| for x1 in range(COLUMNS): | |
| test_alive = alive[(y1+1)*COLUMNS + x1] | |
| if test_alive > 0: | |
| if test_alive < 3: | |
| sprite_offset = 2 + S_WIDTH*S_HEIGHT*5 + (test_alive)*8*S_WIDTH | |
| else: | |
| sprite_offset = 2 + S_WIDTH*S_HEIGHT*2 + game[TOGGLE]*S_HEIGHT*S_WIDTH | |
| for y in range(S_HEIGHT): | |
| for x in range(S_WIDTH): | |
| color = sprites[sprite_offset + y*S_WIDTH + x] | |
| screen[y1*10*MAXSCREEN_X+y*MAXSCREEN_X + x+x1*14+screen_offset] = color | |
| sprite_offset = 2 + S_WIDTH*S_HEIGHT*4 + game[TOGGLE]*8*S_WIDTH | |
| screen_offset = invaders[Y]+40*MAXSCREEN_X + invaders[X] | |
| for y1 in range(2): | |
| for x1 in range(COLUMNS): | |
| test_alive = alive[(y1+3)*COLUMNS + x1] | |
| if test_alive > 0: | |
| if test_alive < 3: | |
| sprite_offset = 2 + S_WIDTH*S_HEIGHT*5 + (test_alive)*8*S_WIDTH | |
| else: | |
| sprite_offset = 2 + S_WIDTH*S_HEIGHT*4 + game[TOGGLE]*8*S_WIDTH | |
| for y in range(S_HEIGHT): | |
| for x in range(S_WIDTH): | |
| color = sprites[sprite_offset + y*S_WIDTH + x] | |
| screen[y1*10*MAXSCREEN_X+y*MAXSCREEN_X + x+x1*14+screen_offset] = color | |
| @micropython.viper | |
| def draw_player(): | |
| sprites = ptr16(SPRITES) | |
| screen = ptr16(LCD.buffer) | |
| invaders = ptr32(INVADERS) | |
| player = ptr32(PLAYER) | |
| game = ptr32(GAME) | |
| if player[HIT] > 0: | |
| sprite_offset = 2 + S_WIDTH*S_HEIGHT*(11+(player[HIT]%2)) | |
| else: | |
| sprite_offset = 2 + S_WIDTH*S_HEIGHT*11 | |
| screen_offset = MAXSCREEN_X * PLAYER_Y + player[X] | |
| for y in range(S_HEIGHT): | |
| for x in range(S_WIDTH): | |
| color = sprites[sprite_offset + y*S_WIDTH + x] | |
| screen[y*MAXSCREEN_X + x+screen_offset] = color | |
| @micropython.viper | |
| def draw_bunker(): | |
| game = ptr32(GAME) | |
| bunker = ptr8(BUNKER) | |
| screen = ptr16(LCD.buffer) | |
| if not game[BUNKERS]: return | |
| screen_offset = MAXSCREEN_X*BUNKER_Y | |
| for y in range(BUNKER_HEIGHT): | |
| for x in range(MAXSCREEN_X): | |
| color = bunker[y*MAXSCREEN_X+x] | |
| if color > 0: | |
| screen[screen_offset + y * MAXSCREEN_X + x] = 0xe007 | |
| @micropython.viper | |
| def draw_missile(): | |
| missile = ptr32(MISSILE) | |
| screen = ptr16(LCD.buffer) | |
| miss_spr = ptr8(MISS_SPR) | |
| for index in range(1,NUM_MISSILES): # invader missiles | |
| i = index * MISSILE_PARAMS | |
| if missile[Y + i] > 0 and missile[Y + i] < MAXSCREEN_Y: | |
| x = missile[X + i] | |
| y = missile[Y + i] | |
| offset = missile[M_SPRITE2 + i] + (missile[M_SPRITE + i] // 4) | |
| for y1 in range(7): | |
| for x1 in range(3): | |
| miss_addr = y1 * 3 + x1 + (offset * 3 * 7) | |
| if miss_spr[miss_addr] == 0xff: | |
| screen[(y+y1) * 160 + x + x1] = 0xffff | |
| if missile[Y] > 0: # player missile | |
| x = missile[X] | |
| y = missile[Y] | |
| LCD.line(x,y,x,y+7,0xffff) | |
| def game_over(): | |
| GAME_SOUND.SOUND = 0 | |
| LCD.text('GAME OVER',40,50,0xff) | |
| LCD.show() | |
| exit() | |
| @micropython.viper | |
| def draw(): | |
| draw_invaders() | |
| draw_player() | |
| draw_bunker() | |
| draw_missile() | |
| game = ptr32(GAME) | |
| if game[SCORE] == 0: | |
| LCD.text('FPS',0,80,0xff) | |
| show_num_viper(game[FPS],40,80,0xff) | |
| if game[SCORE] == 10 : | |
| LCD.text('FREE MEM',0,90,0xff) | |
| show_num_viper(gc.mem_free(),120,90,0xff) | |
| LCD.text('SCORE',0,0,0xff) | |
| show_num_viper(game[SCORE],70,0,0xff) | |
| LCD.text('LIVES',100,0,0xff) | |
| show_num_viper(game[LIVES],145,0,0xff) | |
| LCD.show() | |
| LCD.rect(0,0,MAXSCREEN_X,MAXSCREEN_Y,0,1) | |
| @micropython.asm_thumb | |
| def avg_fps_asm(r0,r1): # r0 = fps[] , r1 = current_fps | |
| ldrb(r2,[r0,0]) # r2 = fps[0] | |
| add(r2,r2,1) # fps[0] += 1 | |
| cmp(r2,33) | |
| blt(LT_32) # if fps[0] > 32: | |
| mov(r2,1) | |
| label(LT_32) | |
| strb(r2,[r0,0]) # fps[0] = new index | |
| add(r2,r2,r0) | |
| strb(r1,[r2,0]) # fps[fps[0]] = current_fps | |
| mov(r2,1) # r2 = i | |
| mov(r3,0) # r3 = tot | |
| label(LOOP) | |
| add(r0,r0,1) | |
| ldrb(r4,[r0,0]) # r4 = fps[i] | |
| add(r3,r3,r4) # tot += fps[i] | |
| add(r2,r2,1) | |
| cmp(r2,33) #33 | |
| blt(LOOP) | |
| asr(r0,r3,5) | |
| @micropython.viper | |
| def core1(): | |
| global EXIT, GAME_SOUND | |
| GAME_SOUND = Game_Sound() | |
| GAME_SOUND.OFF = 0 | |
| while not EXIT: | |
| GAME_SOUND.callback1() | |
| sleep_ms(10) | |
| @micropython.viper | |
| def main(): | |
| init_pot() | |
| init_game() | |
| init_player() | |
| init_invaders() | |
| init_bunker() | |
| reset_bunker() | |
| reset_invaders() | |
| get_edges() | |
| game = ptr32(GAME) | |
| pot_ticks = 0 | |
| move_ticks = 0 | |
| inv_fire_ticks = 0 | |
| GAME_SOUND.SOUND = 1<<0 | |
| while not EXIT and not RESET_PB(): | |
| gticks = int(ticks_ms()) | |
| sleep(0.001) | |
| if gticks > pot_ticks + 10: | |
| pot_ticks = gticks | |
| read_pot() | |
| if gticks > move_ticks + game[TIME] and 1: | |
| move_ticks = gticks | |
| move() | |
| if gticks > inv_fire_ticks + game[TIME]*10: | |
| inv_fire_ticks = gticks | |
| invaders_fire() | |
| move_missiles() | |
| draw() | |
| game[FPS] = int(avg_fps_asm(FPS_ARRY,1_000//int(ticks_diff(ticks_ms(),gticks)))) | |
| def shutdown(): | |
| global EXIT | |
| EXIT = True | |
| Pin(16,Pin.OUT).low() # buzzer off | |
| pwm.deinit() | |
| Pin(13,Pin.OUT).low() # screen off | |
| gc.collect() | |
| print(gc.mem_free()) | |
| print('Core0 Stop') | |
| exit() | |
| if __name__=='__main__': | |
| FIRE_BUTTON = Pin(22, Pin.IN, Pin.PULL_UP) | |
| machine.freq(200_000_000) | |
| machine.mem32[0x40008048] = 1<<11 # enable peri_ctrl clock | |
| pwm = PWM(Pin(13)) | |
| pwm.freq(1000) | |
| pwm.duty_u16(0x8fff)#max 0xffff | |
| LCD = LCD_1inch8() | |
| LCD.fill(0) | |
| LCD.show() | |
| EXIT = False | |
| _thread.start_new_thread(core1, ()) | |
| try: | |
| main() | |
| shutdown() | |
| except KeyboardInterrupt : | |
| shutdown() | |
@Zorglupy
On the Pico run make_sprites.py and s_inv_miss-py to create the binaries needed.
I also added a modified version for the Pico2 that removes the problematic RESET_PB() and changes the overclocking address.
@samneggs , Thanks for adding the missing elements 😉 I’m now able to run the program successfully. While exploring your repository filled with these great programs and strong educational value (especially the low-level optimizations using Viper, ASM, and PIO), I noticed that many of the programs have the same issue as this one — they’re missing key components (e.g., Centipede, Tetris, Hill Climb, Race Bots → sprite, texture, sound library, gfx library) that would allow them to run properly. It would be fantastic if you could also add the missing elements for those programs. A brief reference to the hardware and libraries used (e.g., GT911, GC9A01, etc.) would also be very helpful. Thanks again for sharing such interesting work!
Hello, I'm trying to test this code but I noticed that some important elements are missing, such as the sprite files. Would it be possible for you to publish them? Thank you.