#include "ascii.h" #include #include #include "lua.h" #include "rom.c" #include "play.h" #include #include #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; int v_screen_w = 640; int v_screen_h = 480; uint8_t hborder = 40; uint8_t vborder = 40; 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 counter=0; uint32_t palette[16] = { 0x00000000, 0x000000AA, 0x0000AA00, 0x0000AAAA, 0x00AA0000, 0x00AA00AA, 0x00AA5500, 0x00AAAAAA, 0x00555555, 0x005555FF, 0x0055FF55, 0x0055FFFF, 0x00FF5555, 0x00FF55FF, 0x00FFFF55, 0x00FFFFFF }; int debug_prompt = -1; int debug_cursor_blink = 30; std::vector cmd_list; bool should_reset = false; const Uint8 *keys; Uint8 key_just_pressed = 0; int mouse_x, mouse_y, mouse_wheel; Uint32 mouse_buttons; const char* get_filename() { return lua_filename; } void reinit() { if (mini_bak != NULL) SDL_DestroyTexture(mini_bak); counter=0; hborder = vborder = 40; v_screen_w = 640; v_screen_h = 480; 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; case 3: hborder = 104; vborder = 88; v_screen_w = 512; v_screen_h = 384; screen_width = 32; screen_height = 24; current_color = 0x07; current_border = 0; cursor_x = 0; cursor_y = 0; char_screen = &mem[0]; color_screen = &mem[768]; //SDL_RenderSetLogicalSize(mini_ren, 640, 480); mini_bak = SDL_CreateTexture(mini_ren, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_STREAMING, 256, 192); 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); } void debug_set_prompt(); int main(int argc,char*argv[]) { SDL_strlcpy(lua_filename, "game.lua", 9); if (argc > 1) SDL_strlcpy(lua_filename, argv[1], 1023); //[TODEL]for (int i=0; i=hborder && my>=vborder && mx<(v_screen_w+hborder) && my<(v_screen_h+vborder)) { mouse_x = (mx-hborder) / (v_screen_w/screen_width); mouse_y = (my-vborder) / (v_screen_h/screen_height); } if (lua_is_playing()) { lua_call_update(); if (!lua_is_playing()) debug_set_prompt(); } else { debug_cursor_blink--; if (debug_cursor_blink == 0) { debug_cursor_blink = 60; const int pos = cursor_x+cursor_y*screen_width; //char_screen[pos] = char_screen[pos]==32 ? 95 : 32; } loop(); } SDL_LockTexture(mini_bak, NULL, (void**)&pixels, &pitch); switch (current_mode) { case 0: for (int y=0; y>4)+((chr_color&0x0f)<<4); } const uint32_t ink_color = palette[chr_color & 0x0f]; const uint32_t paper_color = palette[chr_color >> 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: case 3: 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 = {hborder, vborder, v_screen_w, v_screen_h}; SDL_RenderCopy(mini_ren, mini_bak, NULL, &rect); //SDL_RenderCopy(mini_ren, mini_bak, NULL, NULL); SDL_RenderPresent(mini_ren); counter++; } 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); cursor_x = cursor_y = 0; //if (!lua_is_playing()) { // debug_set_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); const int pos = cursor_x+cursor_y*screen_width; if (pos+len > screen_width*screen_height) len -= ((pos+len) - screen_width*screen_height); //int offset = x+y*screen_width; for (int i=0; i < len; ++i) { char_screen[pos+i] = str[i]; if (current_mode != 0) color_screen[pos+i] = current_color; //char_screen[offset+i] = str[i]; //if (current_mode != 0) color_screen[offset+i] = current_color; } cursor_x = (pos+len)%screen_width; cursor_y = (pos+len)/screen_width; } void crlf() { cursor_x=0; cursor_y = min(cursor_y+1, screen_height-1); } 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 str_tmp[1024]; const char* tostr(float val) { return SDL_itoa(val, str_tmp, 10); } void debug_one_line_up() { int total = screen_width*screen_height-screen_width; for (int i=0; i0) { cursor_x=0;cursor_y++;if(cursor_y>=screen_height) debug_one_line_up(); } char_screen[cursor_x+cursor_y*screen_width] = '>'; cursor_x++; debug_prompt = cursor_x+cursor_y*screen_width; } void debugchr(const uint8_t chr) { int pos = cursor_x+cursor_y*screen_width; if (chr == 8) { if (cursor_x>1) { char_screen[pos++] = 32; char_screen[pos] = 32; cursor_x--; } else { play("c"); } } else { char_screen[pos] = chr; cursor_x++; if (cursor_x >= screen_width) { cursor_x=0; cursor_y++; if (cursor_y >= screen_height) debug_one_line_up(); } } } void debug(const char *str, const bool newline) { const int len = SDL_strlen(str); int cursor = cursor_x+cursor_y*screen_width; for (int i=0; i= screen_width*screen_height) debug_one_line_up(); } if (newline) { cursor_x = 0; cursor_y = (cursor/screen_width)+1; if (cursor_y >= screen_height) debug_one_line_up(); } else { cursor_x = cursor%screen_width; cursor_y = cursor/screen_width; } //debug_set_prompt(); } /*[TODEL] void pdebug() { int i=0; for (int y=0; y=screen_height)debug_one_line_up(); cmd_index=0; const char* cmd = cmd_list[cmd_list.size()-1].c_str(); if (cmd[0]=='r' && cmd[1]=='u' && cmd[2]=='n' && cmd[3]=='\0') { lua_quit(); reinit(); lua_init(lua_filename); lua_call_init(); } else if (cmd[0]=='c' && cmd[1]=='o' && cmd[2]=='n' && cmd[3]=='t' && cmd[4]=='\0') { lua_resume(); } else { lua_call_cmd(cmd); debug_set_prompt(); } } void get_cmd_by_index() { if (cmd_list.size() == 0) return; const char* cmd = cmd_list[cmd_list.size()-cmd_index-1].c_str(); int pos = cursor_x+cursor_y*screen_width; for (int i=debug_prompt;i<=pos;++i) char_screen[i] = 32; SDL_memcpy(&char_screen[debug_prompt], cmd, strlen(cmd)); pos = debug_prompt+strlen(cmd); cursor_x = pos%screen_width; cursor_y = pos/screen_width; } void next_cmd() { if (cmd_index < cmd_list.size()-1) cmd_index++; else play("c"); get_cmd_by_index(); } void prev_cmd() { if (cmd_index > 0) cmd_index--; else play("c"); get_cmd_by_index(); } void debug_set_cursor(uint8_t x, uint8_t y) { cursor_x = x; cursor_y = y; } uint8_t ascii(const char *str, uint8_t index) { return str[index]; } char chr_trans[2] = "X"; const char* chr(uint8_t ascii) { uint8_t* peiv = (uint8_t*)chr_trans; *peiv = ascii; return chr_trans; } const char* substr(const char* str, uint8_t start, uint8_t length) { memcpy(str_tmp, &str[start], length); str_tmp[length] = '\0'; return str_tmp; } void setchar(uint8_t index, uint8_t b0, uint8_t b1, uint8_t b2, uint8_t b3, uint8_t b4, uint8_t b5, uint8_t b6, uint8_t b7) { mem[MEM_CHAR_OFFSET+index*8] = b0; mem[MEM_CHAR_OFFSET+index*8+1] = b1; mem[MEM_CHAR_OFFSET+index*8+2] = b2; mem[MEM_CHAR_OFFSET+index*8+3] = b3; mem[MEM_CHAR_OFFSET+index*8+4] = b4; mem[MEM_CHAR_OFFSET+index*8+5] = b5; mem[MEM_CHAR_OFFSET+index*8+6] = b6; mem[MEM_CHAR_OFFSET+index*8+7] = b7; } uint8_t peek(uint16_t addr) { if (addr >= 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 mode(const uint8_t val) { current_mode = val; reinit(); cls(); } 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); } void toclipboard(const char* str) { SDL_SetClipboardText(str); } const char* fromclipboard() { char* text = SDL_GetClipboardText(); int len = strlen(text); if (len > 1023) { len = 27; SDL_memcpy(str_tmp, "ERROR! CLIPBOARD TOO LARGE", len); } else { SDL_memcpy(str_tmp, text, len); } str_tmp[len] = '\0'; SDL_free((void*)text); return str_tmp; } uint32_t cnt() { return counter; } void rst() { counter = 0; }