#include "ascii.h" #include #include #include "lua.h" #include "rom.c" #include "play.h" #define swap(a, b) {auto tmp=a;a=b;b=tmp;} #define AUDIO_NONE 0 #define AUDIO_SOUND 1 #define AUDIO_PLAY 2 char lua_filename[1024]; char window_title[256]; uint8_t mem[8192]; //2400 uint8_t *char_screen = NULL; uint8_t *color_screen = NULL; uint8_t screen_width = 40; uint8_t screen_height = 30; uint8_t current_color = 0x1e; uint8_t current_border = 0; uint8_t current_mode = 1; uint8_t cursor_x = 0; uint8_t cursor_y = 0; uint8_t audio_state = AUDIO_NONE; int audio_freq = 0; uint32_t audio_len = 0; #define CHRSCR(x, y) char_screen[x+y*screen_width] #define COLSCR(x, y) color_screen[x+y*screen_width] #define MEM_CHAR_OFFSET 2560 #define MEM_BOOT_OFFSET 4608 SDL_Window *mini_win; SDL_Renderer *mini_ren; SDL_Texture *mini_bak = NULL; SDL_AudioDeviceID mini_audio_device; Uint32 *pixels; int pitch; uint32_t palette[16] = { 0x00000000, 0x000000AA, 0x0000AA00, 0x0000AAAA, 0x00AA0000, 0x00AA00AA, 0x00AA5500, 0x00AAAAAA, 0x00555555, 0x005555FF, 0x0055FF55, 0x0055FFFF, 0x00FF5555, 0x00FF55FF, 0x00FFFF55, 0x00FFFFFF }; #define debug_line_size 80 #define debug_num_lines 30 #define debug_total_size 2400 //debug_line_size*debug_num_lines char debug_text[debug_total_size]; int debug_cursor = 0; int debug_prompt = 0; int debug_cursor_blink = 30; bool should_reset = false; //Uint8 keymapping[6] = { SDL_SCANCODE_LEFT, SDL_SCANCODE_RIGHT, SDL_SCANCODE_UP, SDL_SCANCODE_DOWN, SDL_SCANCODE_Z, SDL_SCANCODE_X }; const Uint8 *keys; Uint8 key_just_pressed = 0; int mouse_x, mouse_y, mouse_wheel; Uint32 mouse_buttons; void reinit() { if (mini_bak != NULL) SDL_DestroyTexture(mini_bak); switch (current_mode) { case 0: screen_width = 80; screen_height = 30; current_color = 0x07; current_border = 0; cursor_x = 0; cursor_y = 0; char_screen = &mem[0]; color_screen = &mem[1200]; //SDL_RenderSetLogicalSize(mini_ren, 640, 480); mini_bak = SDL_CreateTexture(mini_ren, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_STREAMING, 640, 240); break; case 1: screen_width = 40; screen_height = 30; current_color = 0x07; current_border = 0; cursor_x = 0; cursor_y = 0; char_screen = &mem[0]; color_screen = &mem[1200]; //SDL_RenderSetLogicalSize(mini_ren, 320, 240); mini_bak = SDL_CreateTexture(mini_ren, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_STREAMING, 320, 240); break; case 2: screen_width = 20; screen_height = 15; current_color = 0x07; current_border = 0; cursor_x = 0; cursor_y = 0; char_screen = &mem[0]; color_screen = &mem[300]; //SDL_RenderSetLogicalSize(mini_ren, 160, 120); mini_bak = SDL_CreateTexture(mini_ren, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_STREAMING, 160, 120); break; } } static Uint8* play_pos; static Uint32 play_len; static Uint8 play_buffer[132300]; void audioCallback(void * userdata, uint8_t * stream, int len) { if (audio_state == AUDIO_SOUND) { if (audio_len <= 0) audio_state = AUDIO_NONE; static int period=0; static int v = 16; SDL_memset(stream, 0, len); const int flen = min(audio_len, len); audio_len -= flen; for (int i=0; i=audio_freq) {period = 0; v=-v;} } } else if (audio_state == AUDIO_PLAY) { while( len > 0 ) { while( play_len == 0 ) { play_len = interpret_next_token(play_buffer); if (play_len == -1) { audio_state=AUDIO_NONE; SDL_memset( stream, 0, len ); return; } play_pos = play_buffer; } const int actual_len = ( len > play_len ? play_len : len ); //SDL_memset( stream, 0, actual_len ); //SDL_MixAudio( stream, audio_pos, actual_len, SDL_MIX_MAXVOLUME ); SDL_memcpy(stream, play_pos, actual_len); stream += actual_len; play_pos += actual_len; play_len -= actual_len; len -= actual_len; } } else { SDL_memset(stream, 0, len); } } uint8_t old_mode = 0; void romcpy() { SDL_memcpy(&mem[2560], rom, rom_size); } int main(int argc,char*argv[]) { SDL_strlcpy(lua_filename, "game.lua", 9); if (argc > 1) SDL_strlcpy(lua_filename, argv[1], 1023); for (int i=0; i> 4]; const uint8_t chr = CHRSCR(x,y); for (int l=0; l<8; ++l) { const uint8_t line = mem[MEM_CHAR_OFFSET+chr*8+l]; for (int b=0; b<8; ++b) { if ((line >> (7-b)) & 0x01) { pixels[b+(x*8)+((y*8)+l)*(screen_width*8)] = ink_color; } else { pixels[b+(x*8)+((y*8)+l)*(screen_width*8)] = paper_color; } } } } } break; case 1: case 2: for (int y=0; y> 4]; const uint8_t chr = CHRSCR(x,y); for (int l=0; l<8; ++l) { const uint8_t line = mem[MEM_CHAR_OFFSET+chr*8+l]; for (int b=0; b<8; ++b) { if ((line >> (7-b)) & 0x01) { pixels[b+(x*8)+((y*8)+l)*(screen_width*8)] = ink_color; } else { pixels[b+(x*8)+((y*8)+l)*(screen_width*8)] = paper_color; } } } } } break; } //for (int i=0;isize;++i) pixels[i] = palette[screen_surface->p[i]]; SDL_UnlockTexture(mini_bak); SDL_SetRenderDrawColor(mini_ren, (palette[current_border] >> 16)&0xff, (palette[current_border] >> 8)&0xff, palette[current_border]&0xff, 0); //SDL_SetRenderDrawColor(mini_ren, 255, 0, 0, 0); SDL_RenderClear(mini_ren); SDL_Rect rect = {40, 40, 640, 480}; SDL_RenderCopy(mini_ren, mini_bak, NULL, &rect); //SDL_RenderCopy(mini_ren, mini_bak, NULL, NULL); SDL_RenderPresent(mini_ren); } lua_quit(); SDL_Quit(); return 0; } void cls(uint8_t value) { SDL_memset(char_screen, value, screen_width*screen_height); if (current_mode != 0) SDL_memset(color_screen, current_color, screen_width*screen_height); if (!lua_is_playing()) { SDL_memset(debug_text, 32, debug_total_size); debug_cursor = 1; debug_prompt = 0; debug_text[debug_prompt] = '>'; } } void ink(uint8_t value) { current_color = (current_color & 0xf0) + (value & 0x0f); } void paper(uint8_t value) { current_color = (current_color & 0x0f) + (value << 4); } void border(uint8_t value) { current_border = value & 0xf; } void color(uint8_t ink, uint8_t paper, int8_t border) { current_color = (ink & 0x0f) + (paper << 4); if (border >= 0) current_border = border & 0xf; } void locate(uint8_t x, uint8_t y) { cursor_x = min(x, screen_width-1); cursor_y = min(y, screen_height-1); } void print(const char *str, int x, int y) { if (x >= 0) cursor_x = min(x, screen_width-1); if (y >= 0) cursor_y = min(y, screen_height-1); int len = SDL_strlen(str); if ((cursor_x+len) > screen_width) len -= ((cursor_x+len) - screen_width); //int offset = x+y*screen_width; for (int i=0; i < len; ++i) { CHRSCR(cursor_x+i, cursor_y) = str[i]; if (current_mode != 0) COLSCR(cursor_x+i, cursor_y) = current_color; //char_screen[offset+i] = str[i]; //if (current_mode != 0) color_screen[offset+i] = current_color; } cursor_x += len; } bool btn(uint8_t i) { return keys[i]; } bool btnp(uint8_t i) { return key_just_pressed == i; } uint8_t whichbtn() { return key_just_pressed; } int mousex() { return mouse_x; } int mousey() { return mouse_y; } int mousewheel() { return mouse_wheel; } bool mousebutton(uint8_t i) { return mouse_buttons & SDL_BUTTON(i); } int time() { return SDL_GetTicks(); } /*float abs(float x) { return SDL_fabsf(x); }*/ float flr(float x) { return SDL_floorf(x); } float sgn(float x) { return x >= 0 ? 1 : -1; } #ifndef __LINUX__ #ifndef __APPLE__ float ceil(float x) { return SDL_ceilf(x); } float sin(float x) { return SDL_sinf(x); } float cos(float x) { return SDL_cosf(x); } float atan2(float dx, float dy) { return SDL_atan2f(dx, dy); } float sqrt(float x) { return SDL_sqrtf(x); } #endif #endif float max(float x, float y) { return SDL_max(x, y); } float mid(float x, float y, float z) { return max(x, min(y, z)); } float min(float x, float y) { return SDL_min(x, y); } int rnd(int x) { return rand()%x; } /*void srand(int x) { srand(x); }*/ char tostr_tmp[256]; const char* tostr(float val) { return SDL_itoa(val, tostr_tmp, 10); } void debug_set_prompt() { debug_prompt = debug_cursor++; debug_text[debug_prompt] = '>'; } void debug_one_line_up() { for (int i=0; i(debug_prompt+1)) { debug_text[debug_cursor--] = 32; debug_text[debug_cursor] = 32; } } else { debug_text[debug_cursor++] = chr; if (debug_cursor >= debug_total_size) debug_one_line_up(); } } void debug(const char *str) { const int len = SDL_strlen(str); for (int i=0; i= debug_total_size) debug_one_line_up(); } debug_cursor = (int(debug_cursor/debug_line_size)+1)*debug_line_size; if (debug_cursor >= debug_total_size) debug_one_line_up(); debug_set_prompt(); } void pdebug() { int i=0; for (int y=0; y= 0x2000) return 0; return mem[addr]; } void poke(uint16_t addr, uint8_t val) { if (addr >= 0x2000) return; mem[addr] = val; } void memcpy(uint16_t dst, uint16_t src, uint16_t size) { if ((dst<=src) && (dst+size>=src)) return; if ((dst>=src) && (src+size>=dst)) return; SDL_memcpy(&mem[dst], &mem[src], size); } void sound(float freq, uint32_t len) { // [TODO] audio_len = len*44.1f; audio_freq = 22050.0f/freq/2.0f; audio_state = AUDIO_SOUND; } void nosound() { //SDL_PauseAudioDevice(mini_audio_device, 1); audio_len = 0; audio_state = AUDIO_NONE; } void play(const char* str) { play_pos = play_buffer; play_len = 0; play_init(str); audio_state = AUDIO_PLAY; } void setmode(const uint8_t mode) { current_mode = mode; reinit(); } void load(const char* str) { if (str!=NULL) SDL_strlcpy(lua_filename, str, SDL_strlen(str)+1); should_reset = true; } void fileout(const char* str, uint16_t addr, uint16_t size) { FILE* f = fopen(str, "wb"); fwrite(&mem[addr], size, 1, f); fclose(f); } void filein(const char* str, uint16_t addr, uint16_t size) { FILE* f = fopen(str, "rb"); fread(&mem[addr], size, 1, f); fclose(f); }