Virtual machine on the ESP8266 to run games

    VM written by an uncertain hand of the humanities in the Arduino programming environment using quickcode and bicycles. And there is also a compiler for it from a C-like language, written in JavaScript using the same methods. Yes. You can already rush into comments, throw stones. Well, for those who are still interested, I invite you to continue reading.

    Loaf trolley bus

    In general, my crafts already a little lit respected tormozedison 's here . But at that time there was rather a spherical prototype in a vacuum. And now I have got a RomanS device, which he kindly provided me for experiments absolutely free of charge. This device is called ESPboy. It differs from other crafts by its compactness and expansion slot using the MCP23017 chip. Here you can learn more about him.

    If anyone is interested, how did such a strange idea come to my mind as a virtual machine on a microcontroller, then you can read it under the spoiler.

    Background
    Once at school, I was carried away by a gamemaker from yoyogames, and, like many, riveted on it, do not understand what. These crookedly written and poorly drawn demos could still boast to friends, but on the Internet they were drowning among similar ones. I realized how hard it was to write even a simple game myself, not to mention a serious one in which you could rob the cows. But the desire to write games was not lost. When I got a mobile phone, I discovered Midlet Pascal and had fun with it for several years. After all, I realized that writing a game for a weak device is easier than for its more powerful big brother. At least, one could always speak not about crooked hands, but about the limited capabilities of the platform. However, the button players gave way to sensors another chance to conquer the world was missed. Yet, at some point, I realized that I could revive my dreams,

    I started by writing a game under arduino uno, where would you go without it. Then she was my only one, and I was very worried about her performance. I tried to flash as little as possible. But the rake's path goes in small steps. Each small edit to the code made it flash again and again. And I decided to write a stacked virtual machine. After all, there are huge two kilobytes of RAM for bytes of code and data on board. But how slow it was, but for some reason memory was constantly lacking. Probably the whole point is that all my bikes were with square wheels and rode slowly. Then I decided to write a chip-8 emulator on Arduino Mega just arrived from China. Of course, then I wanted to write a gameboy emulator for her, the first playstation and some supercomputer easier. As a result, I understood the main thing. The chip-8 virtual machine was very simple, overly simple. So much so that when writing your games for multiplication or division, you had to write a separate slow subroutine. So you need to write your VM, getting rid of a fatal flaw. At this time, several more esp8266 arrived, with their space 160MHz.

    If it seems to you that a virtual machine is a waste of resources, then I also rewrote my chip-8 emulator for it. It turned out a virtual machine in a virtual machine on a microcontroller. You can probably go further and write a Turing machine on chip-8.

    ESP Little Game Engine Specifications


    A virtual machine contains 16 registers of 16 bits each, a zero register is a stack pointer. Each instruction is double-byte, some instructions contain two bytes of data. Addressable memory 64KB. In the case of the ESP8266, 20KB is available. The program can be downloaded from SPIFFS and UART. If desired, you can add a download from a memory card or via WiFi. In addition to the usual arithmetic instructions and instructions for moving data, there are separate instructions for working with sprites, screen and sound. Screen size 128 by 128 pixels. At 16 colors per dot, the screen takes up 8KB of memory, the same amount of buffer for drawing sprites and particles. Although the TFT_eSPI library I use is capable of updating the screen more than 60 times per second, I had to limit myself to 20 frames per second. Otherwise, there was not enough processor time for the virtual machine. You can draw tiles and 32 sprites up to 128x128 pixels in size with the possibility of rotation and mirroring. To save memory, you can use single-bit images or RLE compression. There is simplified physics: detection of collisions of sprites with sprites and tiles, collision resolution, gravity. The screen is updated line by line only if a row has changed pixels. VM speed, depending on how many lines are drawn in the frame, varies from 100 thousand to 900 thousand operations per second. You can use different color screens, there is a soft stretching of the image to the desired proportions. sprite collision detection with sprites and tiles, collision resolution, gravity. The screen is updated line by line only if a row has changed pixels. VM speed, depending on how many lines are drawn in the frame, varies from 100 thousand to 900 thousand operations per second. You can use different color screens, there is a soft stretching of the image to the desired proportions. sprite collision detection with sprites and tiles, collision resolution, gravity. The screen is updated line by line only if a row has changed pixels. VM speed, depending on how many lines are drawn in the frame, varies from 100 thousand to 900 thousand operations per second. You can use different color screens, there is a soft stretching of the image to the desired proportions.


    Some of the games written by me can be viewed here .

    At the same time as VM for ESP8266, I wrote a JavaScript emulator for the browser. In order not to edit the bytecode manually, a simple assembler was added, based on my experience with the assembler for the MOS6502. Then I decided to add a higher level language. Nevertheless, my main task was to quickly write simple games, and not a long debug assembly code. It seemed to me that writing your compiler would be easier than adding LLVM. And I wrote it in JavaScript, because I know it not as bad as other languages. At the moment, he is far from supporting C standards, and when compiling, you can easily encounter an incomprehensible error in an incomprehensible place. But it is fast, because it takes less than 2000 lines.

    And now to the question, why did I write all this here. Already now you can write and run games. However, perfection is still far away. If anyone wants to help me finalize the ESP LGE, or write my own game, then I will be very happy. If you thought my idea was interesting, and you want to know more, then I will be happy to answer your questions. I warn you, the code for Arduino is quite difficult to read. Partly because I'm self-taught. Partly due to the fact that I tried to reduce the number of function calls in order to increase the speed of work. As a result, many functions contain huge footsteps of code. So do not allow pregnant women and children to the screen. Gradually, I will try to fix this and improve readability.

    And for those who have read, an example of a game. It takes less than a hundred lines and less than 1KB in compiled form.

    int stickCount;
    char key,previouseKey,takenSticks;
    void redraw(){
    	int i;
    	//выбираем красный цвет
    	setcolor(2);
    	//рисуем видимые палочки
    	for(i = 0; i < stickCount; i++)
    		line(22 + i * 6, 74, 22 + i * 6, 84);
    	//выбираем серый цвет
    	setcolor(11);
    	//рисуем выброшенные
    	for(i = stickCount; i < 15; i++)
    		line(22 + i * 6, 74, 22 + i * 6, 84);
    	//возвращаем белый цвет как основной
    	setcolor(1);
    	//ждем перерисовки экрана
    	delayredraw();
    }
    void playersMove(){
    	//если код кнопки равен предыдущему, значит она еще не отпущена. Ждем
    	while(key == previouseKey){
    		key = getkey();
    	}
    	while(key != KEY_LEFT && key != KEY_DOWN && key != KEY_RIGHT){
    		key = getkey();
    	}
    	if(key & KEY_LEFT){
    		takenSticks = 1;
    	}else if(key & KEY_DOWN){
    		takenSticks = 2;
    	}else{
    		takenSticks = 3;
    	}
    	printf("%d, ", takenSticks);
    	stickCount -= takenSticks;
    	previouseKey = key;
    }
    void computersMove(){
    	if(stickCount % 4){
    		//компьютер реализует выигрышную стратегию, если выпала возможность
    		takenSticks = stickCount % 4;
    	}else{
    		//компьютер ждет возможности реализовать выигрышную стратегию
    		takenSticks = 1 + random(1);
    	}
    	stickCount -= takenSticks;
    	printf("%d, ", takenSticks);
    }
    void game(){
    	//инициализация
    	stickCount = 15;
    	clearscreen();
    	//переводим каретку на восьмой символ нулевой строки
    	gotoxy(8,0);
    	puts("Баше");
    	gotoxy(2,1);
    	puts("Возьмите 1,2 или 3 палочки. Проигрывает тот,  кому   нечего  брать. Управление:\n");
    	//коды 27,25 и 26 соответствуют стрелкам
    	printf(" %c 1    %c 2    %c 3", 27, 25, 26);
    	gotoxy(0,12);
    	redraw();
    	while(1){
    		playersMove();
    		if(stickCount <= 0){
    			gotoxy(3,8);
    			puts("Вы выиграли");
    			return;
    		}
    		redraw();
    		computersMove();
    		redraw();
    		if(stickCount <= 0){
    			gotoxy(3,8);
    			puts("Компьютер выиграл");
    			return;
    		}
    	}
    }
    void main(){
    	while(1){
    		game();
    		//ждем секунду
    		settimer(1,1000);
    		while(gettimer(1)){}
    		while(getkey() == 0){}
    		previouseKey = key;
    	}
    }
    

    You can immediately test it . Follow the link, then click compile, then run. If you want to know more about the possibilities of the IDE, you can read the tutorial . Thanks for attention.

    Also popular now: