OSDN Git Service

[Build][X1] Enable to build.
authorK.Ohta <whatisthis.sowhat@gmail.com>
Wed, 7 Jan 2015 15:57:16 +0000 (00:57 +0900)
committerK.Ohta <whatisthis.sowhat@gmail.com>
Wed, 7 Jan 2015 15:57:16 +0000 (00:57 +0900)
14 files changed:
source/src/agar/common/CMakeLists.txt
source/src/agar/common/agar_debugger.cpp [new file with mode: 0644]
source/src/agar/common/agar_input.cpp [new file with mode: 0644]
source/src/agar/common/agar_main.cpp
source/src/agar/common/agar_main.h
source/src/agar/common/agar_screen.cpp [new file with mode: 0644]
source/src/agar/common/agar_sdlscaler.cpp
source/src/agar/common/scaler/generic/scaler_x1.c
source/src/agar/common/sdl_sound.cpp
source/src/agar/x1/menu_x1.cpp
source/src/common.h
source/src/config.cpp
source/src/emu.cpp
source/src/emu.h

index 6bd1492..380f1eb 100644 (file)
@@ -5,12 +5,15 @@ add_executable(${EXEC_TARGET}
 #        agar_glcl.cpp
 #        agar_gldraw2.cpp
 #        agar_glutil.cpp
+         agar_screen.cpp
          agar_logger.cpp
          agar_sdlscaler.cpp
          agar_wrapper.cpp
          sdl_sound.cpp
+         agar_input.cpp
          agar_main.cpp
          agar_emuevents.cpp
+         agar_debugger.cpp
          agar_sdlview.c
          sdl_cpuid.c
 )
diff --git a/source/src/agar/common/agar_debugger.cpp b/source/src/agar/common/agar_debugger.cpp
new file mode 100644 (file)
index 0000000..f49af8b
--- /dev/null
@@ -0,0 +1,797 @@
+/*
+       Skelton for retropc emulator
+
+       Author : Takeda.Toshiya
+       Date   : 2006.08.18 -
+
+       [ debugger console ]
+*/
+
+//#include <conio.h>
+//#include <io.h>
+//#include <fcntl.h>
+//#include "res/resource.h"
+#include "emu.h"
+#include "vm/device.h"
+#include "vm/debugger.h"
+#include "vm/vm.h"
+#include "fileio.h"
+
+#ifdef USE_DEBUGGER
+#if 0
+void my_printf(HANDLE hStdOut, const _TCHAR *format, ...)
+{
+       DWORD dwWritten;
+       _TCHAR buffer[1024];
+       va_list ap;
+       
+       va_start(ap, format);
+       _vstprintf(buffer, format, ap);
+       va_end(ap);
+       
+       WriteConsole(hStdOut, buffer, _tcslen(buffer), &dwWritten, NULL);
+}
+
+void my_putch(HANDLE hStdOut, _TCHAR c)
+{
+       DWORD dwWritten;
+       
+       WriteConsole(hStdOut, &c, 1, &dwWritten, NULL);
+}
+
+uint32 my_hexatoi(_TCHAR *str)
+{
+       _TCHAR *s;
+       
+       if(str == NULL || _tcslen(str) == 0) {
+               return 0;
+       } else if(_tcslen(str) == 3 && str[0] == _T('\'') && str[2] == _T('\'')) {
+               // ank
+               return str[1] & 0xff;
+       } else if((s = _tcsstr(str, _T(":"))) != NULL) {
+               // 0000:0000
+               s[0] = _T('\0');
+               return (my_hexatoi(str) << 4) + my_hexatoi(s + 1);
+       } else if(str[0] == _T('%')) {
+               // decimal
+               return atoi(str + 1);
+       }
+       return _tcstol(str, NULL, 16);
+}
+
+break_point_t *get_break_point(DEBUGGER *debugger, _TCHAR *command)
+{
+       if(command[0] == _T('B') || command[0] == _T('b')) {
+               return &debugger->bp;
+       } else if(command[0] == _T('R') || command[0] == _T('r')) {
+               return &debugger->rbp;
+       } else if(command[0] == _T('W') || command[0] == _T('w')) {
+               return &debugger->wbp;
+       } else if(command[0] == _T('I') || command[0] == _T('i')) {
+               return &debugger->ibp;
+       } else if(command[0] == _T('O') || command[0] == _T('o')) {
+               return &debugger->obp;
+       }
+       return NULL;
+}
+#endif
+
+#if 0
+unsigned __stdcall debugger_thread(void *lpx)
+{
+       volatile debugger_thread_t *p = (debugger_thread_t *)lpx;
+       p->running = true;
+       
+       DEVICE *cpu = p->vm->get_cpu(p->cpu_index);
+       DEBUGGER *debugger = (DEBUGGER *)cpu->get_debugger();
+       
+       debugger->now_going = false;
+       debugger->now_debugging = true;
+       while(!debugger->now_suspended) {
+               Sleep(10);
+       }
+       
+       uint32 prog_addr_mask = cpu->debug_prog_addr_mask();
+       uint32 data_addr_mask = cpu->debug_data_addr_mask();
+       uint32 dump_addr = 0;
+       uint32 dasm_addr = cpu->get_next_pc();
+       
+       // initialize console
+       _TCHAR buffer[1024];
+       _stprintf(buffer, _T("Debugger - %s"), _T(DEVICE_NAME));
+       
+       AllocConsole();
+       SetConsoleTitle(buffer);
+       
+       HANDLE hStdIn = GetStdHandle(STD_INPUT_HANDLE);
+       HANDLE hStdOut = GetStdHandle(STD_OUTPUT_HANDLE);
+       bool cp932 = (GetConsoleCP() == 932);
+       
+       COORD coord;
+       coord.X = 80;
+       coord.Y = 4000;
+       
+       SetConsoleScreenBufferSize(hStdOut, coord);
+       SetConsoleTextAttribute(hStdOut, FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE | FOREGROUND_INTENSITY);
+       RemoveMenu(GetSystemMenu(GetConsoleWindow(), FALSE), SC_CLOSE, MF_BYCOMMAND);
+       
+       SetConsoleTextAttribute(hStdOut, FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE | FOREGROUND_INTENSITY);
+       cpu->debug_regs_info(buffer);
+       my_printf(hStdOut, _T("%s\n"), buffer);
+       
+       SetConsoleTextAttribute(hStdOut, FOREGROUND_RED | FOREGROUND_INTENSITY);
+       my_printf(hStdOut, _T("breaked at %08X\n"), cpu->get_next_pc());
+       
+       SetConsoleTextAttribute(hStdOut, FOREGROUND_GREEN | FOREGROUND_BLUE | FOREGROUND_INTENSITY);
+       cpu->debug_dasm(cpu->get_next_pc(), buffer);
+       my_printf(hStdOut, _T("next\t%08X  %s\n"), cpu->get_next_pc(), buffer);
+       SetConsoleTextAttribute(hStdOut, FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE | FOREGROUND_INTENSITY);
+       
+       #define MAX_COMMAND_LEN 64
+       
+       _TCHAR command[MAX_COMMAND_LEN + 1];
+       _TCHAR prev_command[MAX_COMMAND_LEN + 1];
+       
+       memset(prev_command, 0, sizeof(prev_command));
+       
+       while(!p->request_terminate) {
+               my_printf(hStdOut, _T("- "));
+               
+               // get command
+               int ptr = 0;
+               bool enter_done = false;
+               
+               while(!p->request_terminate && !enter_done) {
+                       DWORD dwRead;
+                       INPUT_RECORD ir[16];
+                       
+                       if(ReadConsoleInput(hStdIn, ir, 16, &dwRead)) {
+                               for(unsigned int i = 0; i < dwRead; i++) {
+#ifdef _UNICODE
+                                       if((ir[i].EventType & KEY_EVENT) && ir[i].Event.KeyEvent.bKeyDown && ir[i].Event.KeyEvent.uChar.UnicodeChar) {
+                                               _TCHAR chr = ir[i].Event.KeyEvent.uChar.UnicodeChar;
+#else
+                                       if((ir[i].EventType & KEY_EVENT) && ir[i].Event.KeyEvent.bKeyDown && ir[i].Event.KeyEvent.uChar.AsciiChar) {
+                                               _TCHAR chr = ir[i].Event.KeyEvent.uChar.AsciiChar;
+#endif
+                                               if(chr == 0x0d || chr == 0x0a) {
+                                                       if(ptr == 0 && prev_command[0] != _T('\0')) {
+                                                               memcpy(command, prev_command, sizeof(command));
+                                                               my_printf(hStdOut, _T("%s\n"), command);
+                                                               enter_done = true;
+                                                               break;
+                                                       } else if(ptr > 0) {
+                                                               command[ptr] = _T('\0');
+                                                               memcpy(prev_command, command, sizeof(command));
+                                                               my_printf(hStdOut, _T("\n"));
+                                                               enter_done = true;
+                                                               break;
+                                                       }
+                                               } else if(chr == 0x08) {
+                                                       if(ptr > 0) {
+                                                               ptr--;
+                                                               my_putch(hStdOut, chr);
+                                                               my_putch(hStdOut, _T(' '));
+                                                               my_putch(hStdOut, chr);
+                                                       }
+                                               } else if(chr >= 0x20 && chr <= 0x7e && ptr < MAX_COMMAND_LEN && !(chr == 0x20 && ptr == 0)) {
+                                                       command[ptr++] = chr;
+                                                       my_putch(hStdOut, chr);
+                                               }
+                                       }
+                               }
+                       }
+                       Sleep(10);
+               }
+               
+               // process command
+               if(!p->request_terminate && enter_done) {
+                       _TCHAR *params[32], *token = NULL;
+                       int num = 0;
+                       
+                       if((token = _tcstok(command, _T(" "))) != NULL) {
+                               params[num++] = token;
+                               while(num < 32 && (token = _tcstok(NULL, _T(" "))) != NULL) {
+                                       params[num++] = token;
+                               }
+                       }
+                       if(_tcsicmp(params[0], _T("D")) == 0) {
+                               if(num <= 3) {
+                                       uint32 start_addr = dump_addr;
+                                       if(num >= 2) {
+                                               start_addr = my_hexatoi(params[1]);
+                                       }
+                                       start_addr &= data_addr_mask;
+                                       
+                                       uint32 end_addr = start_addr + 8 * 16 - 1;
+                                       if(num == 3) {
+                                               end_addr = my_hexatoi(params[2]);
+                                       }
+                                       end_addr &= data_addr_mask;
+                                       
+                                       if(start_addr > end_addr) {
+                                               end_addr = data_addr_mask;
+                                       }
+                                       for(uint64 addr = start_addr & ~0x0f; addr <= end_addr; addr++) {
+                                               if(addr > data_addr_mask) {
+                                                       end_addr = data_addr_mask;
+                                                       break;
+                                               }
+                                               if((addr & 0x0f) == 0) {
+                                                       my_printf(hStdOut, _T("%08X "), addr & data_addr_mask);
+                                                       memset(buffer, 0, sizeof(buffer));
+                                               }
+                                               if(addr < start_addr) {
+                                                       my_printf(hStdOut, _T("   "));
+                                                       buffer[addr & 0x0f] = _T(' ');
+                                               } else {
+                                                       uint32 data = cpu->debug_read_data8(addr & data_addr_mask);
+                                                       my_printf(hStdOut, _T(" %02X"), data);
+                                                       buffer[addr & 0x0f] = ((data >= 0x20 && data <= 0x7e) || (cp932 && data >= 0xa1 && data <= 0xdf)) ? data : _T('.');
+                                               }
+                                               if((addr & 0x0f) == 0x0f) {
+                                                       my_printf(hStdOut, _T("  %s\n"), buffer);
+                                               }
+                                       }
+                                       if((end_addr & 0x0f) != 0x0f) {
+                                               for(uint32 addr = (end_addr & 0x0f) + 1; addr <= 0x0f; addr++) {
+                                                       my_printf(hStdOut, _T("   "));
+                                               }
+                                               my_printf(hStdOut, _T("  %s\n"), buffer);
+                                       }
+                                       dump_addr = (end_addr + 1) & data_addr_mask;
+                                       prev_command[1] = _T('\0'); // remove parameters to dump continuously
+                               } else {
+                                       my_printf(hStdOut, _T("invalid parameter number\n"));
+                               }
+                       } else if(_tcsicmp(params[0], _T("E")) == 0 || _tcsicmp(params[0], _T("EB")) == 0) {
+                               if(num >= 3) {
+                                       uint32 addr = my_hexatoi(params[1]) & data_addr_mask;
+                                       for(int i = 2; i < num; i++) {
+                                               cpu->debug_write_data8(addr, my_hexatoi(params[i]) & 0xff);
+                                               addr = (addr + 1) & data_addr_mask;
+                                       }
+                               } else {
+                                       my_printf(hStdOut, _T("invalid parameter number\n"));
+                               }
+                       } else if(_tcsicmp(params[0], _T("EW")) == 0) {
+                               if(num >= 3) {
+                                       uint32 addr = my_hexatoi(params[1]) & data_addr_mask;
+                                       for(int i = 2; i < num; i++) {
+                                               cpu->debug_write_data16(addr, my_hexatoi(params[i]) & 0xffff);
+                                               addr = (addr + 2) & data_addr_mask;
+                                       }
+                               } else {
+                                       my_printf(hStdOut, _T("invalid parameter number\n"));
+                               }
+                       } else if(_tcsicmp(params[0], _T("ED")) == 0) {
+                               if(num >= 3) {
+                                       uint32 addr = my_hexatoi(params[1]) & data_addr_mask;
+                                       for(int i = 2; i < num; i++) {
+                                               cpu->debug_write_data32(addr, my_hexatoi(params[i]));
+                                               addr = (addr + 4) & data_addr_mask;
+                                       }
+                               } else {
+                                       my_printf(hStdOut, _T("invalid parameter number\n"));
+                               }
+                       } else if(_tcsicmp(params[0], _T("EA")) == 0) {
+                               if(num >= 3) {
+                                       uint32 addr = my_hexatoi(params[1]) & data_addr_mask;
+                                       _tcscpy(buffer, prev_command);
+                                       if((token = _tcstok(buffer, _T("\""))) != NULL && (token = _tcstok(NULL, _T("\""))) != NULL) {
+                                               int len = _tcslen(token);
+                                               for(int i = 0; i < len; i++) {
+                                                       cpu->debug_write_data8(addr, token[i] & 0xff);
+                                                       addr = (addr + 1) & data_addr_mask;
+                                               }
+                                       } else {
+                                               my_printf(hStdOut, _T("invalid parameter\n"));
+                                       }
+                               } else {
+                                       my_printf(hStdOut, _T("invalid parameter number\n"));
+                               }
+                       } else if(_tcsicmp(params[0], _T("I")) == 0 || _tcsicmp(params[0], _T("IB")) == 0) {
+                               if(num == 2) {
+                                       my_printf(hStdOut, _T("%02X\n"), cpu->debug_read_io8(my_hexatoi(params[1])) & 0xff);
+                               } else {
+                                       my_printf(hStdOut, _T("invalid parameter number\n"));
+                               }
+                       } else if(_tcsicmp(params[0], _T("IW")) == 0) {
+                               if(num == 2) {
+                                       my_printf(hStdOut, _T("%02X\n"), cpu->debug_read_io16(my_hexatoi(params[1])) & 0xffff);
+                               } else {
+                                       my_printf(hStdOut, _T("invalid parameter number\n"));
+                               }
+                       } else if(_tcsicmp(params[0], _T("ID")) == 0) {
+                               if(num == 2) {
+                                       my_printf(hStdOut, _T("%02X\n"), cpu->debug_read_io32(my_hexatoi(params[1])));
+                               } else {
+                                       my_printf(hStdOut, _T("invalid parameter number\n"));
+                               }
+                       } else if(_tcsicmp(params[0], _T("O")) == 0 || _tcsicmp(params[0], _T("OB")) == 0) {
+                               if(num == 3) {
+                                       cpu->debug_write_io8(my_hexatoi(params[1]), my_hexatoi(params[2]) & 0xff);
+                               } else {
+                                       my_printf(hStdOut, _T("invalid parameter number\n"));
+                               }
+                       } else if(_tcsicmp(params[0], _T("OW")) == 0) {
+                               if(num == 3) {
+                                       cpu->debug_write_io16(my_hexatoi(params[1]), my_hexatoi(params[2]) & 0xffff);
+                               } else {
+                                       my_printf(hStdOut, _T("invalid parameter number\n"));
+                               }
+                       } else if(_tcsicmp(params[0], _T("OD")) == 0) {
+                               if(num == 3) {
+                                       cpu->debug_write_io32(my_hexatoi(params[1]), my_hexatoi(params[2]));
+                               } else {
+                                       my_printf(hStdOut, _T("invalid parameter number\n"));
+                               }
+                       } else if(_tcsicmp(params[0], _T("R")) == 0) {
+                               if(num == 1) {
+                                       cpu->debug_regs_info(buffer);
+                                       my_printf(hStdOut, _T("%s\n"), buffer);
+                               } else if(num == 3) {
+                                       if(!cpu->debug_write_reg(params[1], my_hexatoi(params[2]))) {
+                                               my_printf(hStdOut, _T("unknown register %s\n"), params[1]);
+                                       }
+                               } else {
+                                       my_printf(hStdOut, _T("invalid parameter number\n"));
+                               }
+                       } else if(_tcsicmp(params[0], _T("S")) == 0) {
+                               if(num >= 4) {
+                                       uint32 start_addr = my_hexatoi(params[1]) & data_addr_mask;
+                                       uint32 end_addr = my_hexatoi(params[2]) & data_addr_mask;
+                                       uint8 list[32];
+                                       for(int i = 3, j = 0; i < num; i++, j++) {
+                                               list[j] = my_hexatoi(params[i]);
+                                       }
+                                       for(uint64 addr = start_addr; addr <= end_addr; addr++) {
+                                               bool found = true;
+                                               for(int i = 3, j = 0; i < num; i++, j++) {
+                                                       if(cpu->debug_read_data8((addr + j) & data_addr_mask) != list[j]) {
+                                                               found = false;
+                                                               break;
+                                                       }
+                                               }
+                                               if(found) {
+                                                       my_printf(hStdOut, _T("%08X\n"), addr);
+                                               }
+                                       }
+                               } else {
+                                       my_printf(hStdOut, _T("invalid parameter number\n"));
+                               }
+                       } else if(_tcsicmp(params[0], _T("U")) == 0) {
+                               if(num <= 3) {
+                                       if(num >= 2) {
+                                               dasm_addr = my_hexatoi(params[1]) & prog_addr_mask;
+                                       }
+                                       if(num == 3) {
+                                               uint32 end_addr = my_hexatoi(params[2]) & prog_addr_mask;
+                                               while(dasm_addr <= end_addr) {
+                                                       int len = cpu->debug_dasm(dasm_addr, buffer);
+                                                       my_printf(hStdOut, _T("%08X  %s\n"), dasm_addr, buffer);
+                                                       dasm_addr = (dasm_addr + len) & prog_addr_mask;
+                                               }
+                                       } else {
+                                               for(int i = 0; i < 16; i++) {
+                                                       int len = cpu->debug_dasm(dasm_addr, buffer);
+                                                       my_printf(hStdOut, _T("%08X  %s\n"), dasm_addr, buffer);
+                                                       dasm_addr = (dasm_addr + len) & prog_addr_mask;
+                                               }
+                                       }
+                                       prev_command[1] = _T('\0'); // remove parameters to disassemble continuously
+                               } else {
+                                       my_printf(hStdOut, _T("invalid parameter number\n"));
+                               }
+                       } else if(_tcsicmp(params[0], _T("H")) == 0) {
+                               if(num == 3) {
+                                       uint32 l = my_hexatoi(params[1]);
+                                       uint32 r = my_hexatoi(params[2]);
+                                       my_printf(hStdOut, _T("%08X  %08X\n"), l + r, l - r);
+                               } else {
+                                       my_printf(hStdOut, _T("invalid parameter number\n"));
+                               }
+                       } else if(_tcsicmp(params[0], _T("N")) == 0) {
+                               if(num >= 2 && params[1][0] == _T('\"')) {
+                                       _tcscpy(buffer, prev_command);
+                                       if((token = _tcstok(buffer, _T("\""))) != NULL && (token = _tcstok(NULL, _T("\""))) != NULL) {
+                                               _tcscpy(debugger->file_path, token);
+                                       } else {
+                                               my_printf(hStdOut, _T("invalid parameter\n"));
+                                       }
+                               } else if(num == 2) {
+                                       _tcscpy(debugger->file_path, params[1]);
+                               } else {
+                                       my_printf(hStdOut, _T("invalid parameter number\n"));
+                               }
+                       } else if(_tcsicmp(params[0], _T("L")) == 0) {
+                               if(num == 3) {
+                                       uint32 start_addr = my_hexatoi(params[1]) & data_addr_mask, end_addr = my_hexatoi(params[2]) & data_addr_mask;
+                                       FILEIO* fio = new FILEIO();
+                                       if(fio->Fopen(debugger->file_path, FILEIO_READ_BINARY)) {
+                                               for(uint32 addr = start_addr; addr <= end_addr; addr++) {
+                                                       int data = fio->Fgetc();
+                                                       if(data == EOF) {
+                                                               break;
+                                                       }
+                                                       cpu->debug_write_data8(addr & data_addr_mask, data);
+                                               }
+                                               fio->Fclose();
+                                       } else {
+                                               my_printf(hStdOut, _T("can't open %s\n"), debugger->file_path);
+                                       }
+                                       delete fio;
+                               } else {
+                                       my_printf(hStdOut, _T("invalid parameter number\n"));
+                               }
+                       } else if(_tcsicmp(params[0], _T("W")) == 0) {
+                               if(num == 3) {
+                                       uint32 start_addr = my_hexatoi(params[1]) & data_addr_mask, end_addr = my_hexatoi(params[2]) & data_addr_mask;
+                                       FILEIO* fio = new FILEIO();
+                                       if(fio->Fopen(debugger->file_path, FILEIO_WRITE_BINARY)) {
+                                               for(uint32 addr = start_addr; addr <= end_addr; addr++) {
+                                                       fio->Fputc(cpu->debug_read_data8(addr & data_addr_mask));
+                                               }
+                                               fio->Fclose();
+                                       } else {
+                                               my_printf(hStdOut, _T("can't open %s\n"), debugger->file_path);
+                                       }
+                                       delete fio;
+                               } else {
+                                       my_printf(hStdOut, _T("invalid parameter number\n"));
+                               }
+                       } else if(_tcsicmp(params[0], _T( "BP")) == 0 || _tcsicmp(params[0], _T("RBP")) == 0 || _tcsicmp(params[0], _T("WBP")) == 0) {
+                               break_point_t *bp = get_break_point(debugger, params[0]);
+                               if(num == 2) {
+                                       uint32 addr = my_hexatoi(params[1]);
+                                       bool found = false;
+                                       for(int i = 0; i < MAX_BREAK_POINTS && !found; i++) {
+                                               if(bp->table[i].status == 0 || (bp->table[i].addr == addr && bp->table[i].mask == prog_addr_mask)) {
+                                                       bp->table[i].addr = addr;
+                                                       bp->table[i].mask = prog_addr_mask;
+                                                       bp->table[i].status = 1;
+                                                       found = true;
+                                               }
+                                       }
+                                       if(!found) {
+                                               my_printf(hStdOut, _T("too many break points\n"));
+                                       }
+                               } else {
+                                       my_printf(hStdOut, _T("invalid parameter number\n"));
+                               }
+                       } else if(_tcsicmp(params[0], _T("IBP")) == 0 || _tcsicmp(params[0], _T("OBP")) == 0) {
+                               break_point_t *bp = get_break_point(debugger, params[0]);
+                               if(num == 2 || num == 3) {
+                                       uint32 addr = my_hexatoi(params[1]), mask = 0xff;
+                                       if(num == 3) {
+                                               mask = my_hexatoi(params[2]);
+                                       }
+                                       bool found = false;
+                                       for(int i = 0; i < MAX_BREAK_POINTS && !found; i++) {
+                                               if(bp->table[i].status == 0 || (bp->table[i].addr == addr && bp->table[i].mask == mask)) {
+                                                       bp->table[i].addr = addr;
+                                                       bp->table[i].mask = mask;
+                                                       bp->table[i].status = 1;
+                                                       found = true;
+                                               }
+                                       }
+                                       if(!found) {
+                                               my_printf(hStdOut, _T("too many break points\n"));
+                                       }
+                               } else {
+                                       my_printf(hStdOut, _T("invalid parameter number\n"));
+                               }
+                       } else if(_tcsicmp(params[0], _T("BC")) == 0 || _tcsicmp(params[0], _T("RBC")) == 0 || _tcsicmp(params[0], _T("WBC")) == 0 || _tcsicmp(params[0], _T("IBC")) == 0 || _tcsicmp(params[0], _T("OBC")) == 0) {
+                               break_point_t *bp = get_break_point(debugger, params[0]);
+                               if(num == 2 && _tcsicmp(params[1], _T("ALL")) == 0) {
+                                       memset(bp->table, 0, sizeof(bp->table));
+                               } else if(num >= 2) {
+                                       for(int i = 1; i < num; i++) {
+                                               int index = my_hexatoi(params[i]);
+                                               if(!(index >= 1 && index <= MAX_BREAK_POINTS)) {
+                                                       my_printf(hStdOut, _T("invalid index %x\n"), index);
+                                               } else {
+                                                       bp->table[index - 1].addr = bp->table[index - 1].mask = 0;
+                                                       bp->table[index - 1].status = 0;
+                                               }
+                                       }
+                               } else {
+                                       my_printf(hStdOut, _T("invalid parameter number\n"));
+                               }
+                       } else if(_tcsicmp(params[0], _T("BD")) == 0 || _tcsicmp(params[0], _T("RBD")) == 0 || _tcsicmp(params[0], _T("WBD")) == 0 || _tcsicmp(params[0], _T("IBD")) == 0 || _tcsicmp(params[0], _T("OBD")) == 0 ||
+                                 _tcsicmp(params[0], _T("BE")) == 0 || _tcsicmp(params[0], _T("RBE")) == 0 || _tcsicmp(params[0], _T("WBE")) == 0 || _tcsicmp(params[0], _T("IBE")) == 0 || _tcsicmp(params[0], _T("OBE")) == 0) {
+                               break_point_t *bp = get_break_point(debugger, params[0]);
+                               bool enabled = (params[0][1] == _T('E') || params[0][1] == _T('e') || params[0][2] == _T('E') || params[0][2] == _T('e'));
+                               if(num == 2 && _tcsicmp(params[1], _T("ALL")) == 0) {
+                                       for(int i = 0; i < MAX_BREAK_POINTS; i++) {
+                                               if(bp->table[i].status != 0) {
+                                                       bp->table[i].status = enabled ? 1 : -1;
+                                               }
+                                       }
+                               } else if(num >= 2) {
+                                       for(int i = 1; i < num; i++) {
+                                               int index = my_hexatoi(params[i]);
+                                               if(!(index >= 1 && index <= MAX_BREAK_POINTS)) {
+                                                       my_printf(hStdOut, _T("invalid index %x\n"), index);
+                                               } else if(bp->table[index - 1].status == 0) {
+                                                       my_printf(hStdOut, _T("break point %x is null\n"), index);
+                                               } else {
+                                                       bp->table[index - 1].status = enabled ? 1 : -1;
+                                               }
+                                       }
+                               } else {
+                                       my_printf(hStdOut, _T("invalid parameter number\n"));
+                               }
+                       } else if(_tcsicmp(params[0], _T("BL")) == 0 || _tcsicmp(params[0], _T("RBL")) == 0 || _tcsicmp(params[0], _T("WBL")) == 0) {
+                               if(num == 1) {
+                                       break_point_t *bp = get_break_point(debugger, params[0]);
+                                       for(int i = 0; i < MAX_BREAK_POINTS; i++) {
+                                               if(bp->table[i].status) {
+                                                       my_printf(hStdOut, _T("%d %c %08X\n"), i + 1, bp->table[i].status == 1 ? _T('e') : _T('d'), bp->table[i].addr);
+                                               }
+                                       }
+                               } else {
+                                       my_printf(hStdOut, _T("invalid parameter number\n"));
+                               }
+                       } else if(_tcsicmp(params[0], _T("IBL")) == 0 || _tcsicmp(params[0], _T("OBL")) == 0) {
+                               if(num == 1) {
+                                       break_point_t *bp = get_break_point(debugger, params[0]);
+                                       for(int i = 0; i < MAX_BREAK_POINTS; i++) {
+                                               if(bp->table[i].status) {
+                                                       my_printf(hStdOut, _T("%d %c %08X %08X\n"), i + 1, bp->table[i].status == 1 ? _T('e') : _T('d'), bp->table[i].addr, bp->table[i].mask);
+                                               }
+                                       }
+                               } else {
+                                       my_printf(hStdOut, _T("invalid parameter number\n"));
+                               }
+                       } else if(_tcsicmp(params[0], _T("G")) == 0) {
+                               if(num == 1 || num == 2) {
+                                       if(num >= 2) {
+                                               debugger->store_break_points();
+                                               debugger->bp.table[0].addr = my_hexatoi(params[1]) & prog_addr_mask;
+                                               debugger->bp.table[0].mask = prog_addr_mask;
+                                               debugger->bp.table[0].status = 1;
+                                       }
+                                       debugger->now_going = true;
+                                       debugger->now_suspended = false;
+                                       while(!p->request_terminate && !debugger->now_suspended) {
+                                               if((GetAsyncKeyState(VK_ESCAPE) & 0x8000) != 0) {
+                                                       break;
+                                               }
+                                               Sleep(10);
+                                       }
+                                       // break cpu
+                                       debugger->now_going = false;
+                                       while(!p->request_terminate && !debugger->now_suspended) {
+                                               Sleep(10);
+                                       }
+                                       dasm_addr = cpu->get_next_pc();
+                                       
+                                       SetConsoleTextAttribute(hStdOut, FOREGROUND_GREEN | FOREGROUND_BLUE | FOREGROUND_INTENSITY);
+                                       cpu->debug_dasm(cpu->get_pc(), buffer);
+                                       my_printf(hStdOut, _T("done\t%08X  %s\n"), cpu->get_pc(), buffer);
+                                       
+                                       SetConsoleTextAttribute(hStdOut, FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE | FOREGROUND_INTENSITY);
+                                       cpu->debug_regs_info(buffer);
+                                       my_printf(hStdOut, _T("%s\n"), buffer);
+                                       
+                                       if(debugger->hit()) {
+                                               SetConsoleTextAttribute(hStdOut, FOREGROUND_RED | FOREGROUND_INTENSITY);
+                                               if(debugger->bp.hit) {
+                                                       my_printf(hStdOut, _T("breaked at %08X\n"), cpu->get_next_pc());
+                                               } else if(debugger->rbp.hit) {
+                                                       my_printf(hStdOut, _T("breaked at %08X: memory %08X was read at %08X\n"), cpu->get_next_pc(), debugger->rbp.hit_addr, cpu->get_pc());
+                                               } else if(debugger->wbp.hit) {
+                                                       my_printf(hStdOut, _T("breaked at %08X: memory %08X was written at %08X\n"), cpu->get_next_pc(), debugger->wbp.hit_addr, cpu->get_pc());
+                                               } else if(debugger->ibp.hit) {
+                                                       my_printf(hStdOut, _T("breaked at %08X: port %08X was read at %08X\n"), cpu->get_next_pc(), debugger->ibp.hit_addr, cpu->get_pc());
+                                               } else if(debugger->obp.hit) {
+                                                       my_printf(hStdOut, _T("breaked at %08X: port %08X was written at %08X\n"), cpu->get_next_pc(), debugger->obp.hit_addr, cpu->get_pc());
+                                               }
+                                               debugger->bp.hit = debugger->rbp.hit = debugger->wbp.hit = debugger->ibp.hit = debugger->obp.hit = false;
+                                       } else {
+                                               SetConsoleTextAttribute(hStdOut, FOREGROUND_RED | FOREGROUND_INTENSITY);
+                                               my_printf(hStdOut, _T("breaked at %08X: esc key was pressed\n"), cpu->get_next_pc());
+                                       }
+                                       if(num >= 2) {
+                                               debugger->restore_break_points();
+                                       }
+                                       SetConsoleTextAttribute(hStdOut, FOREGROUND_GREEN | FOREGROUND_BLUE | FOREGROUND_INTENSITY);
+                                       cpu->debug_dasm(cpu->get_next_pc(), buffer);
+                                       my_printf(hStdOut, _T("next\t%08X  %s\n"), cpu->get_next_pc(), buffer);
+                                       SetConsoleTextAttribute(hStdOut, FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE | FOREGROUND_INTENSITY);
+                               } else {
+                                       my_printf(hStdOut, _T("invalid parameter number\n"));
+                               }
+                       } else if(_tcsicmp(params[0], _T("T")) == 0) {
+                               if(num == 1 || num == 2) {
+                                       int steps = 1;
+                                       if(num >= 2) {
+                                               steps = my_hexatoi(params[1]);
+                                       }
+                                       for(int i = 0; i < steps; i++) {
+                                               debugger->now_going = false;
+                                               debugger->now_suspended = false;
+                                               while(!p->request_terminate && !debugger->now_suspended) {
+                                                       Sleep(10);
+                                               }
+                                               dasm_addr = cpu->get_next_pc();
+                                               
+                                               SetConsoleTextAttribute(hStdOut, FOREGROUND_GREEN | FOREGROUND_BLUE | FOREGROUND_INTENSITY);
+                                               cpu->debug_dasm(cpu->get_pc(), buffer);
+                                               my_printf(hStdOut, _T("done\t%08X  %s\n"), cpu->get_pc(), buffer);
+                                               
+                                               SetConsoleTextAttribute(hStdOut, FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE | FOREGROUND_INTENSITY);
+                                               cpu->debug_regs_info(buffer);
+                                               my_printf(hStdOut, _T("%s\n"), buffer);
+                                               
+                                               if(debugger->hit() || (GetAsyncKeyState(VK_ESCAPE) & 0x8000) != 0) {
+                                                       break;
+                                               }
+                                       }
+                                       if(debugger->hit()) {
+                                               SetConsoleTextAttribute(hStdOut, FOREGROUND_RED | FOREGROUND_INTENSITY);
+                                               if(debugger->bp.hit) {
+                                                       my_printf(hStdOut, _T("breaked at %08X\n"), cpu->get_next_pc());
+                                               } else if(debugger->rbp.hit) {
+                                                       my_printf(hStdOut, _T("breaked at %08X: memory %08X was read at %08X\n"), cpu->get_next_pc(), debugger->rbp.hit_addr, cpu->get_pc());
+                                               } else if(debugger->wbp.hit) {
+                                                       my_printf(hStdOut, _T("breaked at %08X: memory %08X was written at %08X\n"), cpu->get_next_pc(), debugger->wbp.hit_addr, cpu->get_pc());
+                                               } else if(debugger->ibp.hit) {
+                                                       my_printf(hStdOut, _T("breaked at %08X: port %08X was read at %08X\n"), cpu->get_next_pc(), debugger->ibp.hit_addr, cpu->get_pc());
+                                               } else if(debugger->obp.hit) {
+                                                       my_printf(hStdOut, _T("breaked at %08X: port %08X was written at %08X\n"), cpu->get_next_pc(), debugger->obp.hit_addr, cpu->get_pc());
+                                               }
+                                               debugger->bp.hit = debugger->rbp.hit = debugger->wbp.hit = debugger->ibp.hit = debugger->obp.hit = false;
+                                       }
+                                       SetConsoleTextAttribute(hStdOut, FOREGROUND_GREEN | FOREGROUND_BLUE | FOREGROUND_INTENSITY);
+                                       cpu->debug_dasm(cpu->get_next_pc(), buffer);
+                                       my_printf(hStdOut, _T("next\t%08X  %s\n"), cpu->get_next_pc(), buffer);
+                                       SetConsoleTextAttribute(hStdOut, FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE | FOREGROUND_INTENSITY);
+                               } else {
+                                       my_printf(hStdOut, _T("invalid parameter number\n"));
+                               }
+                       } else if(_tcsicmp(params[0], _T("Q")) == 0) {
+                               PostMessage(p->emu->main_window_handle, WM_COMMAND, ID_CLOSE_DEBUGGER, 0L);
+                               break;
+                       } else if(_tcsicmp(params[0], _T("!")) == 0) {
+                               if(num == 1) {
+                                       my_printf(hStdOut, _T("invalid parameter number\n"));
+                               } else if(_tcsicmp(params[1], _T("RESET")) == 0) {
+                                       if(num == 2) {
+                                               p->vm->reset();
+                                       } else if(num == 3) {
+                                               if(_tcsicmp(params[2], _T("ALL")) == 0) {
+                                                       p->vm->reset();
+                                               } if(_tcsicmp(params[2], _T("CPU")) == 0) {
+                                                       cpu->reset();
+                                               } else {
+                                                       my_printf(hStdOut, _T("unknown device %s\n"), params[2]);
+                                               }
+                                       } else {
+                                               my_printf(hStdOut, _T("invalid parameter number\n"));
+                                       }
+                               } else if(_tcsicmp(params[1], _T("KEY")) == 0) {
+                                       if(num == 3 || num == 4) {
+                                               int code =  my_hexatoi(params[2]) & 0xff, msec = 100;
+                                               if(num == 4) {
+                                                       msec = my_hexatoi(params[3]);
+                                               }
+#ifdef SUPPORT_VARIABLE_TIMING
+                                               p->emu->key_buffer()[code] = max((int)(p->vm->frame_rate() * (double)msec / 1000.0 + 0.5), 1);
+#else
+                                               p->emu->key_buffer()[code] = max((int)(FRAMES_PER_SEC * (double)msec / 1000.0 + 0.5), 1);
+#endif
+#ifdef NOTIFY_KEY_DOWN
+                                               p->vm->key_down(code, false);
+#endif
+                                       } else {
+                                               my_printf(hStdOut, _T("invalid parameter number\n"));
+                                       }
+                               } else {
+                                       my_printf(hStdOut, _T("unknown command ! %s\n"), params[1]);
+                               }
+                       } else if(_tcsicmp(params[0], _T("?")) == 0) {
+                               my_printf(hStdOut, _T("D [<range>] - dump memory\n"));
+                               my_printf(hStdOut, _T("E[{B,W,D}] <address> <list> - edit memory (byte,word,dword)\n"));
+                               my_printf(hStdOut, _T("EA <address> \"<value>\" - edit memory (ascii)\n"));
+                               my_printf(hStdOut, _T("I[{B,W,D}] <port> - input port (byte,word,dword)\n"));
+                               my_printf(hStdOut, _T("O[{B,W,D}] <port> <value> - output port (byte,word,dword)\n"));
+                               my_printf(hStdOut, _T("R - show register(s)\n"));
+                               my_printf(hStdOut, _T("R <reg> <value> - edit register\n"));
+                               my_printf(hStdOut, _T("S <range> <list> - search\n"));
+                               my_printf(hStdOut, _T("U [<range>] - unassemble\n"));
+                               
+                               my_printf(hStdOut, _T("H <value> <value> - hexadd\n"));
+                               my_printf(hStdOut, _T("N <filename> - name\n"));
+                               my_printf(hStdOut, _T("L <range> - load file\n"));
+                               my_printf(hStdOut, _T("W <range> - write file\n"));
+                               
+                               my_printf(hStdOut, _T("BP <address> - set breakpoint\n"));
+                               my_printf(hStdOut, _T("{R,W}BP <address> - set breakpoint (break at memory access)\n"));
+                               my_printf(hStdOut, _T("{I,O}BP <port> [<mask>] - set breakpoint (break at i/o access)\n"));
+                               my_printf(hStdOut, _T("[{R,W,I,O}]B{C,D,E} {all,<list>} - clear/disable/enable breakpoint(s)\n"));
+                               my_printf(hStdOut, _T("[{R,W,I,O}]BL - list breakpoint(s)\n"));
+                               
+                               my_printf(hStdOut, _T("G - go (press esc key to break)\n"));
+                               my_printf(hStdOut, _T("G <address> - go and break at address\n"));
+                               my_printf(hStdOut, _T("T [<count>] - trace\n"));
+                               my_printf(hStdOut, _T("Q - quit\n"));
+                               
+                               my_printf(hStdOut, _T("! reset [cpu] - reset\n"));
+                               my_printf(hStdOut, _T("! key <code> [<msec>] - press key\n"));
+                               
+                               my_printf(hStdOut, _T("<value> - hexa, decimal(%%d), ascii('a')\n"));
+                       } else {
+                               my_printf(hStdOut, _T("unknown command %s\n"), params[0]);
+                       }
+               }
+       }
+       
+       // stop debugger
+       try {
+               debugger->now_debugging = debugger->now_going = debugger->now_suspended = false;
+       } catch(...) {
+       }
+       
+       // release console
+       FreeConsole();
+       
+       p->running = false;
+       _endthreadex(0);
+       return 0;
+}
+#endif
+   
+void EMU::initialize_debugger()
+{
+       now_debugging = false;
+}
+
+void EMU::release_debugger()
+{
+       close_debugger();
+}
+
+void EMU::open_debugger(int cpu_index)
+{
+#if 0
+   if(!(now_debugging && debugger_thread_param.cpu_index == cpu_index)) {
+               close_debugger();
+               if(vm->get_cpu(cpu_index) != NULL && vm->get_cpu(cpu_index)->get_debugger() != NULL) {
+                       debugger_thread_param.emu = this;
+                       debugger_thread_param.vm = vm;
+                       debugger_thread_param.cpu_index = cpu_index;
+                       debugger_thread_param.request_terminate = false;
+                       if((hDebuggerThread = (HANDLE)_beginthreadex(NULL, 0, debugger_thread, &debugger_thread_param, 0, NULL)) != (HANDLE)0) {
+                               stop_rec_sound();
+                               stop_rec_video();
+                               now_debugging = true;
+                       }
+               }
+       }
+#endif
+}
+
+void EMU::close_debugger()
+{
+#if 0
+       if(now_debugging) {
+               if(debugger_thread_param.running) {
+                       debugger_thread_param.request_terminate = true;
+                       WaitForSingleObject(hDebuggerThread, INFINITE);
+               }
+               CloseHandle(hDebuggerThread);
+               now_debugging = false;
+       }
+#endif
+}
+
+bool EMU::debugger_enabled(int cpu_index)
+{
+//     return (vm->get_cpu(cpu_index) != NULL && vm->get_cpu(cpu_index)->get_debugger() != NULL);
+       return false;
+}
+
+#endif
+
diff --git a/source/src/agar/common/agar_input.cpp b/source/src/agar/common/agar_input.cpp
new file mode 100644 (file)
index 0000000..ce52144
--- /dev/null
@@ -0,0 +1,527 @@
+/*
+       Skelton for retropc emulator
+
+       Author : Takeda.Toshiya
+       Date   : 2006.08.18 -
+
+       [ win32 input ]
+*/
+
+#include "emu.h"
+#include "vm/vm.h"
+#include "fifo.h"
+#include "fileio.h"
+
+#define KEY_KEEP_FRAMES 3
+
+void EMU::initialize_input()
+{
+       // initialize status
+       memset(key_status, 0, sizeof(key_status));
+       memset(joy_status, 0, sizeof(joy_status));
+       memset(mouse_status, 0, sizeof(mouse_status));
+       
+       // initialize joysticks
+#if 0
+        joy_num = joyGetNumDevs();
+       for(int i = 0; i < joy_num && i < 2; i++) {
+               JOYCAPS joycaps;
+               if(joyGetDevCaps(i, &joycaps, sizeof(joycaps)) == JOYERR_NOERROR) {
+                       joy_mask[i] = (1 << joycaps.wNumButtons) - 1;
+               } else {
+                       joy_mask[i] = 0x0f; // 4buttons
+               }
+       }
+#else
+        joy_num = 0;
+#endif 
+       // mouse emulation is disenabled
+       mouse_enabled = false;
+       
+       // initialize keycode convert table
+       FILEIO* fio = new FILEIO();
+       if(fio->Fopen(bios_path(_T("keycode.cfg")), FILEIO_READ_BINARY)) {
+               fio->Fread(keycode_conv, sizeof(keycode_conv), 1);
+               fio->Fclose();
+       } else {
+               for(int i = 0; i < 256; i++) {
+                       keycode_conv[i] = i;
+               }
+       }
+       delete fio;
+       
+#ifdef USE_SHIFT_NUMPAD_KEY
+       // initialize shift+numpad conversion
+       memset(key_converted, 0, sizeof(key_converted));
+       key_shift_pressed = key_shift_released = false;
+#endif
+#ifdef USE_AUTO_KEY
+       // initialize autokey
+       autokey_buffer = new FIFO(65536);
+       autokey_buffer->clear();
+       autokey_phase = autokey_shift = 0;
+#endif
+       lost_focus = false;
+}
+
+void EMU::release_input()
+{
+       // release mouse
+       if(mouse_enabled) {
+               disenable_mouse();
+       }
+       
+#ifdef USE_AUTO_KEY
+       // release autokey buffer
+       if(autokey_buffer) {
+               autokey_buffer->release();
+               delete autokey_buffer;
+       }
+#endif
+}
+
+void EMU::update_input()
+{
+#if 0
+#ifdef USE_SHIFT_NUMPAD_KEY
+       // update numpad key status
+       if(key_shift_pressed && !key_shift_released) {
+               if(key_status[VK_SHIFT] == 0) {
+                       // shift key is newly pressed
+                       key_status[VK_SHIFT] = 0x80;
+#ifdef NOTIFY_KEY_DOWN
+                       vm->key_down(VK_SHIFT, false);
+#endif
+               }
+       } else if(!key_shift_pressed && key_shift_released) {
+               if(key_status[VK_SHIFT] != 0) {
+                       // shift key is newly released
+                       key_status[VK_SHIFT] = 0;
+#ifdef NOTIFY_KEY_DOWN
+                       vm->key_up(VK_SHIFT);
+#endif
+                       // check l/r shift
+                       if(!(GetAsyncKeyState(VK_LSHIFT) & 0x8000)) key_status[VK_LSHIFT] &= 0x7f;
+                       if(!(GetAsyncKeyState(VK_RSHIFT) & 0x8000)) key_status[VK_RSHIFT] &= 0x7f;
+               }
+       }
+       key_shift_pressed = key_shift_released = false;
+#endif
+       
+       // release keys
+#ifdef USE_AUTO_KEY
+       if(lost_focus && autokey_phase == 0) {
+#else
+       if(lost_focus) {
+#endif
+               // we lost key focus so release all pressed keys
+               for(int i = 0; i < 256; i++) {
+                       if(key_status[i] & 0x80) {
+                               key_status[i] &= 0x7f;
+#ifdef NOTIFY_KEY_DOWN
+                               if(!key_status[i]) {
+                                       vm->key_up(i);
+                               }
+#endif
+                       }
+               }
+       } else {
+               for(int i = 0; i < 256; i++) {
+                       if(key_status[i] & 0x7f) {
+                               key_status[i] = (key_status[i] & 0x80) | ((key_status[i] & 0x7f) - 1);
+#ifdef NOTIFY_KEY_DOWN
+                               if(!key_status[i]) {
+                                       vm->key_up(i);
+                               }
+#endif
+                       }
+               }
+       }
+       lost_focus = false;
+       
+       // update joystick status
+       memset(joy_status, 0, sizeof(joy_status));
+       for(int i = 0; i < joy_num && i < 2; i++) {
+               JOYINFOEX joyinfo;
+               joyinfo.dwSize = sizeof(JOYINFOEX);
+               joyinfo.dwFlags = JOY_RETURNALL;
+               if(joyGetPosEx(i, &joyinfo) == JOYERR_NOERROR) {
+                       if(joyinfo.dwYpos < 0x3fff) joy_status[i] |= 0x01;      // up
+                       if(joyinfo.dwYpos > 0xbfff) joy_status[i] |= 0x02;      // down
+                       if(joyinfo.dwXpos < 0x3fff) joy_status[i] |= 0x04;      // left
+                       if(joyinfo.dwXpos > 0xbfff) joy_status[i] |= 0x08;      // right
+                       joy_status[i] |= ((joyinfo.dwButtons & joy_mask[i]) << 4);
+               }
+       }
+#ifdef USE_KEY_TO_JOY
+       // emulate joystick #1 with keyboard
+       if(key_status[0x26]) joy_status[0] |= 0x01;     // up
+       if(key_status[0x28]) joy_status[0] |= 0x02;     // down
+       if(key_status[0x25]) joy_status[0] |= 0x04;     // left
+       if(key_status[0x27]) joy_status[0] |= 0x08;     // right
+#ifdef KEY_TO_JOY_BUTTON_U
+       if(key_status[KEY_TO_JOY_BUTTON_U]) joy_status[0] |= 0x01;
+#endif
+#ifdef KEY_TO_JOY_BUTTON_D
+       if(key_status[KEY_TO_JOY_BUTTON_D]) joy_status[0] |= 0x02;
+#endif
+#ifdef KEY_TO_JOY_BUTTON_L
+       if(key_status[KEY_TO_JOY_BUTTON_L]) joy_status[0] |= 0x04;
+#endif
+#ifdef KEY_TO_JOY_BUTTON_R
+       if(key_status[KEY_TO_JOY_BUTTON_R]) joy_status[0] |= 0x08;
+#endif
+#ifdef KEY_TO_JOY_BUTTON_1
+       if(key_status[KEY_TO_JOY_BUTTON_1]) joy_status[0] |= 0x10;
+#endif
+#ifdef KEY_TO_JOY_BUTTON_2
+       if(key_status[KEY_TO_JOY_BUTTON_2]) joy_status[0] |= 0x20;
+#endif
+#ifdef KEY_TO_JOY_BUTTON_3
+       if(key_status[KEY_TO_JOY_BUTTON_3]) joy_status[0] |= 0x40;
+#endif
+#ifdef KEY_TO_JOY_BUTTON_4
+       if(key_status[KEY_TO_JOY_BUTTON_4]) joy_status[0] |= 0x80;
+#endif
+#endif
+       
+       // update mouse status
+       memset(mouse_status, 0, sizeof(mouse_status));
+       if(mouse_enabled) {
+               // get current status
+               POINT pt;
+               GetCursorPos(&pt);
+               ScreenToClient(main_window_handle, &pt);
+               mouse_status[0]  = pt.x - display_width / 2;
+               mouse_status[1]  = pt.y - display_height / 2;
+               mouse_status[2]  = (GetAsyncKeyState(VK_LBUTTON) & 0x8000) ? 1 : 0;
+               mouse_status[2] |= (GetAsyncKeyState(VK_RBUTTON) & 0x8000) ? 2 : 0;
+               mouse_status[2] |= (GetAsyncKeyState(VK_MBUTTON) & 0x8000) ? 4 : 0;
+               // move mouse cursor to the center of window
+               if(!(mouse_status[0] == 0 && mouse_status[1] == 0)) {
+                       pt.x = display_width / 2;
+                       pt.y = display_height / 2;
+                       ClientToScreen(main_window_handle, &pt);
+                       SetCursorPos(pt.x, pt.y);
+               }
+       }
+       
+#ifdef USE_AUTO_KEY
+       // auto key
+       switch(autokey_phase) {
+       case 1:
+               if(autokey_buffer && !autokey_buffer->empty()) {
+                       // update shift key status
+                       int shift = autokey_buffer->read_not_remove(0) & 0x100;
+                       if(shift && !autokey_shift) {
+                               key_down(VK_SHIFT, false);
+                       } else if(!shift && autokey_shift) {
+                               key_up(VK_SHIFT);
+                       }
+                       autokey_shift = shift;
+                       autokey_phase++;
+                       break;
+               }
+       case 3:
+               if(autokey_buffer && !autokey_buffer->empty()) {
+                       key_down(autokey_buffer->read_not_remove(0) & 0xff, false);
+               }
+               autokey_phase++;
+               break;
+       case USE_AUTO_KEY:
+               if(autokey_buffer && !autokey_buffer->empty()) {
+                       key_up(autokey_buffer->read_not_remove(0) & 0xff);
+               }
+               autokey_phase++;
+               break;
+       case USE_AUTO_KEY_RELEASE:
+               if(autokey_buffer && !autokey_buffer->empty()) {
+                       // wait enough while vm analyzes one line
+                       if(autokey_buffer->read() == 0xd) {
+                               autokey_phase++;
+                               break;
+                       }
+               }
+       case 30:
+               if(autokey_buffer && !autokey_buffer->empty()) {
+                       autokey_phase = 1;
+               } else {
+                       stop_auto_key();
+               }
+               break;
+       default:
+               if(autokey_phase) {
+                       autokey_phase++;
+               }
+       }
+#endif
+#endif
+       }
+
+
+
+#ifdef USE_SHIFT_NUMPAD_KEY
+static const int numpad_table[256] = {
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x65, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+//     0x00, 0x69, 0x63, 0x61, 0x67, 0x64, 0x68, 0x66, 0x62, 0x00, 0x00, 0x00, 0x00, 0x60, 0x6e, 0x00,
+       0x00, 0x69, 0x63, 0x61, 0x67, 0x64, 0x68, 0x66, 0x62, 0x00, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, // remove shift + period
+       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, 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, 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
+};
+#endif
+
+void EMU::key_down(int code, bool repeat)
+{
+       bool keep_frames = false;
+       
+#if 0
+        if(code == VK_SHIFT) {
+               if(GetAsyncKeyState(VK_LSHIFT) & 0x8000) key_status[VK_LSHIFT] = 0x80;
+               if(GetAsyncKeyState(VK_RSHIFT) & 0x8000) key_status[VK_RSHIFT] = 0x80;
+               if(!(key_status[VK_LSHIFT] || key_status[VK_RSHIFT])) key_status[VK_LSHIFT] = 0x80;
+       } else if(code == VK_CONTROL) {
+               if(GetAsyncKeyState(VK_LCONTROL) & 0x8000) key_status[VK_LCONTROL] = 0x80;
+               if(GetAsyncKeyState(VK_RCONTROL) & 0x8000) key_status[VK_RCONTROL] = 0x80;
+               if(!(key_status[VK_LCONTROL] || key_status[VK_RCONTROL])) key_status[VK_LCONTROL] = 0x80;
+       } else if(code == VK_MENU) {
+               if(GetAsyncKeyState(VK_LMENU) & 0x8000) key_status[VK_LMENU] = 0x80;
+               if(GetAsyncKeyState(VK_RMENU) & 0x8000) key_status[VK_RMENU] = 0x80;
+               if(!(key_status[VK_LMENU] || key_status[VK_RMENU])) key_status[VK_LMENU] = 0x80;
+       } else if(code == 0xf0) {
+               code = VK_CAPITAL;
+               keep_frames = true;
+       } else if(code == 0xf2) {
+               code = VK_KANA;
+               keep_frames = true;
+       } else if(code == 0xf3 || code == 0xf4) {
+               code = VK_KANJI;
+               keep_frames = true;
+       }
+#ifdef USE_SHIFT_NUMPAD_KEY
+       if(code == VK_SHIFT) {
+               key_shift_pressed = true;
+               return;
+       } else if(numpad_table[code] != 0) {
+               if(key_shift_pressed || key_shift_released) {
+                       key_converted[code] = 1;
+                       key_shift_pressed = true;
+                       code = numpad_table[code];
+               }
+       }
+#endif
+       if(!(code == VK_SHIFT || code == VK_CONTROL || code == VK_MENU)) {
+               code = keycode_conv[code];
+       }
+       
+#ifdef DONT_KEEEP_KEY_PRESSED
+       if(!(code == VK_SHIFT || code == VK_CONTROL || code == VK_MENU)) {
+               key_status[code] = KEY_KEEP_FRAMES;
+       } else
+#endif
+       key_status[code] = keep_frames ? KEY_KEEP_FRAMES : 0x80;
+#ifdef NOTIFY_KEY_DOWN
+       if(keep_frames) {
+               repeat = false;
+       }
+       vm->key_down(code, repeat);
+#endif
+#endif
+}
+
+void EMU::key_up(int code)
+{
+#if 0
+   if(code == VK_SHIFT) {
+#ifndef USE_SHIFT_NUMPAD_KEY
+               if(!(GetAsyncKeyState(VK_LSHIFT) & 0x8000)) key_status[VK_LSHIFT] &= 0x7f;
+               if(!(GetAsyncKeyState(VK_RSHIFT) & 0x8000)) key_status[VK_RSHIFT] &= 0x7f;
+#endif
+       } else if(code == VK_CONTROL) {
+               if(!(GetAsyncKeyState(VK_LCONTROL) & 0x8000)) key_status[VK_LCONTROL] &= 0x7f;
+               if(!(GetAsyncKeyState(VK_RCONTROL) & 0x8000)) key_status[VK_RCONTROL] &= 0x7f;
+       } else if(code == VK_MENU) {
+               if(!(GetAsyncKeyState(VK_LMENU) & 0x8000)) key_status[VK_LMENU] &= 0x7f;
+               if(!(GetAsyncKeyState(VK_RMENU) & 0x8000)) key_status[VK_RMENU] &= 0x7f;
+       }
+#ifdef USE_SHIFT_NUMPAD_KEY
+       if(code == VK_SHIFT) {
+               key_shift_pressed = false;
+               key_shift_released = true;
+               return;
+       } else if(key_converted[code] != 0) {
+               key_converted[code] = 0;
+               code = numpad_table[code];
+       }
+#endif
+       if(!(code == VK_SHIFT || code == VK_CONTROL || code == VK_MENU)) {
+               code = keycode_conv[code];
+       }
+       if(key_status[code]) {
+               key_status[code] &= 0x7f;
+#ifdef NOTIFY_KEY_DOWN
+               if(!key_status[code]) {
+                       vm->key_up(code);
+               }
+#endif
+       }
+#endif
+}
+
+#ifdef USE_BUTTON
+void EMU::press_button(int num)
+{
+#if 0
+       int code = buttons[num].code;
+       
+       if(code) {
+               key_down(code, false);
+               key_status[code] = KEY_KEEP_FRAMES;
+       } else {
+               // code=0: reset virtual machine
+               vm->reset();
+       }
+#endif
+}
+#endif
+
+void EMU::enable_mouse()
+{
+       // enable mouse emulation
+       if(!mouse_enabled) {
+#if 0
+               // hide mouse cursor
+               ShowCursor(FALSE);
+               // move mouse cursor to the center of window
+               POINT pt;
+               pt.x = display_width / 2;
+               pt.y = display_height / 2;
+               ClientToScreen(main_window_handle, &pt);
+               SetCursorPos(pt.x, pt.y);
+#endif
+       }
+       mouse_enabled = true;
+
+}
+
+
+
+void EMU::disenable_mouse()
+{
+#if 0
+       // disenable mouse emulation
+       if(mouse_enabled) {
+               ShowCursor(TRUE);
+       }
+#endif
+      mouse_enabled = false;
+}
+
+void EMU::toggle_mouse()
+{
+       // toggle mouse enable / disenable
+       if(mouse_enabled) {
+               disenable_mouse();
+       } else {
+               enable_mouse();
+       }
+}
+
+#ifdef USE_AUTO_KEY
+static const int autokey_table[256] = {
+       // 0x100: shift
+       // 0x200: kana
+       // 0x400: alphabet
+       // 0x800: ALPHABET
+       0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x00d,0x000,0x000,0x00d,0x000,0x000,
+       0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,
+       0x020,0x131,0x132,0x133,0x134,0x135,0x136,0x137,0x138,0x139,0x1ba,0x1bb,0x0bc,0x0bd,0x0be,0x0bf,
+       0x030,0x031,0x032,0x033,0x034,0x035,0x036,0x037,0x038,0x039,0x0ba,0x0bb,0x1bc,0x1bd,0x1be,0x1bf,
+       0x0c0,0x441,0x442,0x443,0x444,0x445,0x446,0x447,0x448,0x449,0x44a,0x44b,0x44c,0x44d,0x44e,0x44f,
+       0x450,0x451,0x452,0x453,0x454,0x455,0x456,0x457,0x458,0x459,0x45a,0x0db,0x0dc,0x0dd,0x0de,0x1e2,
+       0x1c0,0x841,0x842,0x843,0x844,0x845,0x846,0x847,0x848,0x849,0x84a,0x84b,0x84c,0x84d,0x84e,0x84f,
+       0x850,0x851,0x852,0x853,0x854,0x855,0x856,0x857,0x858,0x859,0x85a,0x1db,0x1dc,0x1dd,0x1de,0x000,
+       0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,
+       0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,
+       // kana -->
+       0x000,0x3be,0x3db,0x3dd,0x3bc,0x3bf,0x330,0x333,0x345,0x334,0x335,0x336,0x337,0x338,0x339,0x35a,
+       0x2dc,0x233,0x245,0x234,0x235,0x236,0x254,0x247,0x248,0x2ba,0x242,0x258,0x244,0x252,0x250,0x243,
+       0x251,0x241,0x25a,0x257,0x253,0x255,0x249,0x231,0x2bc,0x24b,0x246,0x256,0x232,0x2de,0x2bd,0x24a,
+       0x24e,0x2dd,0x2bf,0x24d,0x237,0x238,0x239,0x24f,0x24c,0x2be,0x2bb,0x2e2,0x230,0x259,0x2c0,0x2db,
+       // <--- kana
+       0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,
+       0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000
+};
+
+void EMU::start_auto_key()
+{
+#if 0
+        stop_auto_key();
+       
+       if(OpenClipboard(NULL)) {
+               HANDLE hClip = GetClipboardData(CF_TEXT);
+               if(hClip) {
+                       autokey_buffer->clear();
+                       char* buf = (char*)GlobalLock(hClip);
+                       int size = strlen(buf), prev_kana = 0;
+                       for(int i = 0; i < size; i++) {
+                               int code = buf[i] & 0xff;
+                               if((0x81 <= code && code <= 0x9f) || 0xe0 <= code) {
+                                       i++;    // kanji ?
+                                       continue;
+                               } else if(code == 0xa) {
+                                       continue;       // cr-lf
+                               }
+                               if((code = autokey_table[code]) != 0) {
+                                       int kana = code & 0x200;
+                                       if(prev_kana != kana) {
+                                               autokey_buffer->write(0xf2);
+                                       }
+                                       prev_kana = kana;
+#if defined(USE_AUTO_KEY_NO_CAPS)
+                                       if((code & 0x100) && !(code & (0x400 | 0x800))) {
+#elif defined(USE_AUTO_KEY_CAPS)
+                                       if(code & (0x100 | 0x800)) {
+#else
+                                       if(code & (0x100 | 0x400)) {
+#endif
+                                               autokey_buffer->write((code & 0xff) | 0x100);
+                                       } else {
+                                               autokey_buffer->write(code & 0xff);
+                                       }
+                               }
+                       }
+                       if(prev_kana) {
+                               autokey_buffer->write(0xf2);
+                       }
+                       GlobalUnlock(hClip);
+                       
+                       autokey_phase = 1;
+                       autokey_shift = 0;
+               }
+               CloseClipboard();
+       }
+#endif
+}
+
+void EMU::stop_auto_key()
+{
+#if 0
+        if(autokey_shift) {
+               key_up(VK_SHIFT);
+       }
+       autokey_phase = autokey_shift = 0;
+#endif
+}
+#endif
index 065ac49..c40b31a 100644 (file)
@@ -1,6 +1,5 @@
 /*\r
        Skelton for retropc emulator\r
-\r
        Author : Takeda.Toshiya\r
         Port to Agar : K.Ohta <whatisthis.sowhat _at_ gmail.com>\r
        Date   : 2006.08.18 -\r
@@ -16,6 +15,9 @@
 #include "agar_main.h"\r
 #include "menu_common.h"\r
 \r
+#include <agar/dev.h>\r
+\r
+\r
 // emulation core\r
 EMU* emu;\r
 \r
@@ -129,7 +131,7 @@ void get_long_full_path_name(_TCHAR* src, _TCHAR* dst)
   r_path = r_path + my_procname + delim;\r
   AG_MkPath(r_path.c_str());\r
   ss = "";\r
-  if(s != NULL) ss = s;\r
+//  if(s != NULL) ss = s;\r
   r_path = r_path + ss;\r
   if(dst != NULL) r_path.copy(dst, r_path.length() >= AG_PATHNAME_MAX ? AG_PATHNAME_MAX : r_path.length(), 0);\r
   return;\r
@@ -381,8 +383,17 @@ bool InitInstance(void)
 \r
   AG_RegisterClass(&AGAR_SDLViewClass);\r
 \r
-  hWindow = AG_WindowNew(AG_WINDOW_MAIN);\r
+  if(agDriverSw) {\r
+      hWindow = AG_WindowNew(AG_WINDOW_NOTITLE | AG_WINDOW_NOBORDERS | AG_WINDOW_KEEPBELOW  | AG_WINDOW_NOBACKGROUND\r
+                               | AG_WINDOW_MODKEYEVENTS | AG_WINDOW_NOBUTTONS | AG_WINDOW_NORESIZE | AG_WINDOW_MAIN);\r
+ //     AG_SetEvent(MainWindow , "window-close", OnDestroy, NULL);\r
+   } else {\r
+      hWindow = AG_WindowNew(AG_WINDOW_MODKEYEVENTS | AG_WINDOW_MAIN);\r
+      //AG_WindowSetCaptionS(MainWindow, "XM7/SDL");\r
+   }\r
   if(hWindow == NULL) return false;\r
+  AG_WindowShow(hWindow);\r
+  AG_WindowFocus(hWindow);\r
 \r
   vBox = AG_BoxNew(AGWIDGET(hWindow), AG_BOX_VERT, AG_BOX_HFILL);\r
   {\r
@@ -390,7 +401,13 @@ bool InitInstance(void)
     hMenu = AGAR_MainMenu(AGWIDGET(hBox));\r
   }\r
   {\r
-    hBox = AG_BoxNew(AGWIDGET(vBox), AG_BOX_HORIZ, AG_BOX_VFILL);\r
+     AG_Rect r;\r
+     hBox = AG_BoxNew(AGWIDGET(vBox), AG_BOX_HORIZ, AG_BOX_VFILL);\r
+      r.x = 0;\r
+      r.y = 0;\r
+      r.w = 640;\r
+      r.h = 400;\r
+      AG_WidgetSetGeometry(hBox, r);\r
     //if(AG_UsingGL()) {\r
       //hGLView = AG_GLViewNew();\r
       //hScreenWidget = AGWIDGET(hGLView);\r
@@ -399,7 +416,7 @@ bool InitInstance(void)
       hSDLView = AGAR_SDLViewNew(AGWIDGET(hBox), NULL, NULL);\r
       if(hSDLView == NULL) return false;\r
       hScreenWidget = AGWIDGET(hSDLView);\r
-      //AGAR_SDLViewDrawFn(hSDLView, AGAR_SDLViewUpdateSrc, "%p", NULL);\r
+      AGAR_SDLViewDrawFn(hSDLView, AGAR_SDLViewUpdateSrc, "%p", NULL);\r
       AGAR_SDLViewSurfaceNew(hSDLView, 640, 400);\r
       AG_SetEvent(hSDLView, "key-up", ProcessKeyUp, NULL);\r
       AG_SetEvent(hSDLView, "key-down", ProcessKeyDown, NULL);\r
@@ -408,6 +425,8 @@ bool InitInstance(void)
       AG_SetEvent(hSDLView, "mouse-button-up", OnMouseButtonUp, NULL);\r
       AG_WidgetSetSize(hSDLView, 640, 400);\r
       AG_WidgetShow(hSDLView);\r
+      AG_WidgetFocus(AGWIDGET(hSDLView));\r
+      //AG_RedrawOnTick(AGWIDGET(hSDLView), 30);\r
     }\r
   }\r
   {\r
@@ -416,9 +435,16 @@ bool InitInstance(void)
     AG_WidgetSetSize(hStatusBar, 640, 40);\r
     AG_WidgetShow(hStatusBar);\r
   }\r
+  AG_WidgetShow(vBox);\r
+  AG_WindowSetGeometry(hWindow, 0, 0, 1280, 820);\r
+  AG_WindowShow(hWindow);\r
   //InitMouse();\r
   // enumerate screen mode\r
   screen_mode_count = 0;\r
+  {\r
+     AG_Window *win = AG_GuiDebugger(AGWIDGET(hWindow));\r
+     AG_WindowShow(win);\r
+  }\r
 }  \r
 \r
 #ifdef TRUE\r
@@ -437,21 +463,25 @@ void *EmuThread(void *arg)
    DWORD next_time = 0;\r
    DWORD update_fps_time = 0;\r
    bool prev_skip = false;\r
+\r
    bRunEmuThread = true;\r
-  do {\r
+      \r
+#if 1\r
+    do {\r
     \r
     if(emu) {\r
+      int interval = 0, sleep_period = 0;                      \r
       // drive machine\r
       int run_frames = emu->run();\r
       total_frames += run_frames;\r
-      \r
+       \r
+      interval = 0;\r
+      sleep_period = 0;\r
                        // timing controls\r
-      int interval = 0, sleep_period = 0;\r
-      //                       for(int i = 0; i < run_frames; i++) {\r
-      interval += get_interval();\r
-      //                       }\r
+      for(int i = 0; i < run_frames; i++) {\r
+               interval += get_interval();\r
+      }\r
       bool now_skip = emu->now_skip() && !emu->now_rec_video;\r
-                       \r
       if((prev_skip && !now_skip) || next_time == 0) {\r
        next_time = timeGetTime();\r
       }\r
@@ -459,10 +489,13 @@ void *EmuThread(void *arg)
        next_time += interval;\r
       }\r
       prev_skip = now_skip;\r
+      //printf("EMU::RUN Frames = %d Interval = %d NextTime = %d\n", run_frames, interval, next_time);\r
+      \r
       \r
       if(next_time > timeGetTime()) {\r
        // update window if enough time\r
        draw_frames += emu->draw_screen();\r
+       emu->update_screen(hScreenWidget);// Okay?\r
        skip_frames = 0;\r
        \r
        // sleep 1 frame priod if need\r
@@ -473,10 +506,12 @@ void *EmuThread(void *arg)
       } else if(++skip_frames > MAX_SKIP_FRAMES) {\r
        // update window at least once per 10 frames\r
        draw_frames += emu->draw_screen();\r
+       emu->update_screen(hScreenWidget);// Okay?\r
+       //printf("EMU::Updated Frame %d\n", AG_GetTicks());\r
        skip_frames = 0;\r
        next_time = timeGetTime();\r
       }\r
-      Sleep(sleep_period);\r
+      AG_Delay(sleep_period);\r
       if(bRunEmuThread != true) {\r
        AG_ThreadExit(NULL);\r
        //return;\r
@@ -500,18 +535,111 @@ void *EmuThread(void *arg)
        update_fps_time = current_time + 1000;\r
       }\r
     } else {\r
-      Sleep(10);\r
+      AG_Delay(10);\r
       if(bRunEmuThread != true) {\r
        AG_ThreadExit(NULL);\r
        return arg;\r
       }\r
     }\r
   } while(1);\r
+#endif\r
 }\r
 #ifndef FONTPATH\r
 #define FONTPATH "."\r
 #endif\r
 \r
+\r
+void AGDrawTaskEvent(BOOL flag)\r
+{\r
+   Uint32 nDrawTick2D;\r
+   AG_Window *win;\r
+   AG_Driver *drv;\r
+   Uint32 fps;\r
+   Uint32 oldfps;\r
+   BOOL skipf = FALSE;\r
+   AG_EventSource *src;\r
+   AG_EventSink *es;\r
+   \r
+   // TMPVARS\r
+   bool bEventRunFlag = TRUE;\r
+   Uint32 nDrawTick1D = AG_GetTicks();\r
+   Uint32 nDrawFPS = 30;\r
+   oldfps = nDrawFPS;\r
+   nDrawTick2D = AG_GetTicks();\r
+\r
+   src = AG_GetEventSource();\r
+   \r
+   AG_TAILQ_FOREACH(es, &src->prologues, sinks){\r
+                       es->fn(es, &es->fnArgs);\r
+   }\r
+   if(nDrawFPS > 2) {\r
+      fps = 1000 / nDrawFPS;\r
+   } else {\r
+      fps = 500;\r
+   }\r
+   if(fps < 10) fps = 10; // 10ms = 100fps.\r
+   \r
+   for(;;) {\r
+      if(bEventRunFlag == FALSE) return;\r
+      if(oldfps != nDrawFPS){ // FPS Change 20120120\r
+        oldfps = nDrawFPS;\r
+        if(nDrawFPS > 2) {\r
+           fps = 1000 / nDrawFPS;\r
+        } else {\r
+           fps = 500;\r
+        }\r
+        if(fps < 10) fps = 10; // 10ms = 100fps.\r
+      }\r
+      //if(EventSDL(NULL) == FALSE) return;\r
+      nDrawTick2D = AG_GetTicks();\r
+\r
+      if(nDrawTick2D < nDrawTick1D) nDrawTick1D = 0; // オーバーフロー対策\r
+      if((nDrawTick2D - nDrawTick1D) >= fps) {\r
+        if(skipf != TRUE){\r
+           AG_WindowDrawQueued();\r
+           nDrawTick1D = nDrawTick2D;\r
+           //if(((XM7_timeGetTime() - nDrawTick2D) >= (fps / 4)) && (agDriverSw != NULL)) skipf = TRUE;\r
+           AG_Delay(1);\r
+           continue;\r
+        } else {\r
+             if((nDrawTick2D - nDrawTick1D) >= ((fps * 2) - 1)) {\r
+                skipf = FALSE;\r
+                continue;\r
+             }\r
+           \r
+        }\r
+//      AG_Delay(1);\r
+      } \r
+      if(AG_PendingEvents(NULL) != 0) {\r
+        AG_DriverEvent dev;\r
+        //if(EventSDL(NULL) == FALSE) return;\r
+        if(AG_GetNextEvent(NULL, &dev) == 1) AG_ProcessEvent(NULL, &dev);\r
+//      AG_Delay(1);\r
+      }\r
+      { // Timeout\r
+        src = AG_GetEventSource();\r
+        if(src == NULL) return;\r
+        AG_TAILQ_FOREACH(es, &src->spinners, sinks){\r
+           if(bEventRunFlag == FALSE) return;\r
+           es->fn(es, &es->fnArgs);\r
+        }\r
+        if (src->sinkFn() == -1) {\r
+           return;\r
+        }\r
+        AG_TAILQ_FOREACH(es, &src->epilogues, sinks) {\r
+           if(bEventRunFlag == FALSE) return;\r
+           es->fn(es, &es->fnArgs);\r
+        }\r
+        if (src->breakReq) return;\r
+        AG_Delay(1);\r
+      }        // Process Event per 1Ticks;\r
+\r
+      AG_WindowProcessQueued();\r
+   }\r
+   \r
+}\r
+\r
+\r
 int MainLoop(int argc, char *argv[])\r
 {\r
          char c;\r
@@ -648,8 +776,9 @@ int MainLoop(int argc, char *argv[])
 \r
        bRunEmuThread = false;\r
        AG_ThreadCreate(&hEmuThread, EmuThread, &thread_ret);\r
-       AG_EventLoop(); // Right? maybe unusable Joystick.\r
-\r
+       //AG_EventLoop(); // Right? maybe unusable Joystick.\r
+        AGDrawTaskEvent(true);\r
+        save_config();\r
        return 0;\r
 }\r
 \r
@@ -1106,7 +1235,7 @@ int main(int argc, char *argv[])
      pCpuID = initCpuID();\r
      if(argc > 0) {\r
        if(argv[0] != NULL) {\r
-        my_procname = argv[0];\r
+        my_procname = AG_ShortFilename(argv[0]);\r
        } else {\r
         my_procname = "CommonSourceProject";\r
        }\r
index 804e78c..8f5bcf6 100644 (file)
 #include "common.h"
 #include "emu.h"
 
+extern "C" 
+{
+   void AGAR_SDLViewUpdateSrc(AG_Event *event);
+}
 
 extern EMU* emu;
 #ifdef USE_BUTTON
diff --git a/source/src/agar/common/agar_screen.cpp b/source/src/agar/common/agar_screen.cpp
new file mode 100644 (file)
index 0000000..a4ec7c5
--- /dev/null
@@ -0,0 +1,1010 @@
+/*
+       Skelton for retropc emulator
+
+       Author : Takeda.Toshiya
+       Date   : 2006.08.18 -
+
+       [ win32 screen ]
+*/
+
+#include "emu.h"
+#include "vm/vm.h"
+#include "agar_main.h"
+
+#define RESULT_SUCCESS 1
+#define RESULT_FULL    2
+#define RESULT_ERROR   3
+
+#if defined(_USE_AGAR) || defined(_USE_SDL)
+void *rec_video_thread(void *lpx);
+#else
+unsigned __stdcall rec_video_thread(void *lpx);
+#endif
+#ifdef USE_CRT_FILTER
+static uint8 r0[2048], g0[2048], b0[2048], t0[2048];
+static uint8 r1[2048], g1[2048], b1[2048];
+#endif
+
+extern "C" {
+   int bFullScan = 0;
+}
+
+
+void EMU::initialize_screen()
+{
+       screen_width = SCREEN_WIDTH;
+       screen_height = SCREEN_HEIGHT;
+       screen_width_aspect = SCREEN_WIDTH_ASPECT;
+       screen_height_aspect = SCREEN_HEIGHT_ASPECT;
+       window_width = WINDOW_WIDTH;
+       window_height = WINDOW_HEIGHT;
+       screen_size_changed = true;
+       
+       source_width = source_height = -1;
+       source_width_aspect = source_height_aspect = -1;
+       stretch_pow_x = stretch_pow_y = -1;
+       stretch_screen = false;
+
+       // Agar specific value
+       render_to_GL = false;
+       render_with_OpenCL = false;
+       render_to_SDLFB = false;
+       use_GL = false;
+       use_SDLFB = false;
+       wait_vsync = false;
+        // *nix only, need to change on WIndows.
+        if(posix_memalign(&pPseudoVram, 64, sizeof(Uint32) * SCREEN_WIDTH * SCREEN_HEIGHT) != 0){
+          pPseudoVram = NULL;
+       }
+        {
+          int i;
+          for(i = 0; i < SCREEN_HEIGHT; i++) {
+               bDrawLine[i] = false;
+          }
+       }
+   
+       
+
+       //if(AG_UsingGL()) {
+       //  render_to_GL = true;
+       //  use_GL = true;
+       //} else {
+         render_to_SDLFB = true;
+         use_SDLFB = true;
+         //}
+         single_window = false;
+       now_rec_video = false;
+       
+       // initialize update flags
+       first_draw_screen = false;
+       first_invalidate = self_invalidate = false;
+       
+#ifdef USE_CRT_FILTER
+       // initialize crtc filter
+       memset(r1, 0, sizeof(r1));
+       memset(g1, 0, sizeof(g1));
+       memset(b1, 0, sizeof(b1));
+#endif
+}
+
+
+void EMU::release_screen()
+{
+        if(pPseudoVram != NULL) free(pPseudoVram);
+         pPseudoVram = NULL;
+       // stop video recording
+       //stop_rec_video();
+}
+
+
+
+int EMU::get_window_width(int mode)
+{
+#ifdef USE_SCREEN_ROTATE
+       if(config.monitor_type) {
+               return window_height + screen_height_aspect * mode;
+       }
+#endif
+       return window_width + screen_width_aspect * mode;
+}
+
+int EMU::get_window_height(int mode)
+{
+#ifdef USE_SCREEN_ROTATE
+       if(config.monitor_type) {
+               return window_width + screen_width_aspect * mode;
+       }
+#endif
+       return window_height + screen_height_aspect * mode;
+}
+
+void EMU::set_display_size(int width, int height, bool window_mode)
+{
+#if 0
+ RETRY:
+       bool display_size_changed = false;
+       bool stretch_changed = false;
+       int prev_stretched_width = stretched_width;
+       int prev_stretched_height = stretched_height;
+       
+       if(width != -1 && (display_width != width || display_height != height)) {
+               display_width = width;
+               display_height = height;
+               display_size_changed = stretch_changed = true;
+       }
+       if(use_d3d9 != config.use_d3d9) {
+               if(!(use_d3d9 = config.use_d3d9)) {
+                       release_d3d9();
+               }
+               display_size_changed = stretch_changed = true;
+       }
+       if(wait_vsync != config.wait_vsync) {
+               wait_vsync = config.wait_vsync;
+               display_size_changed = stretch_changed = true;
+       }
+       
+       // virtual machine renders to d3d9 buffer directly???
+       render_to_d3d9Buffer = use_d3d9;
+       
+#ifdef USE_SCREEN_ROTATE
+       if(config.monitor_type) {
+               hdcDibSource = hdcDibRotate;
+               lpBmpSource = lpBmpRotate;
+               lpDibSource = lpDibRotate;
+               pbmInfoHeader = &lpDibRotate->bmiHeader;
+               
+               stretch_changed |= (source_width != screen_height);
+               stretch_changed |= (source_height != screen_width);
+               stretch_changed |= (source_width_aspect != screen_height_aspect);
+               stretch_changed |= (source_height_aspect != screen_width_aspect);
+               
+               source_width = screen_height;
+               source_height = screen_width;
+               source_width_aspect = screen_height_aspect;
+               source_height_aspect = screen_width_aspect;
+               
+               render_to_d3d9Buffer = false;
+       } else {
+#endif
+               hdcDibSource = hdcDib;
+               lpBmpSource = lpBmp;
+               lpDibSource = lpDib;
+               pbmInfoHeader = &lpDib->bmiHeader;
+               
+               stretch_changed |= (source_width != screen_width);
+               stretch_changed |= (source_height != screen_height);
+               stretch_changed |= (source_width_aspect != screen_width_aspect);
+               stretch_changed |= (source_height_aspect != screen_height_aspect);
+               
+               source_width = screen_width;
+               source_height = screen_height;
+               source_width_aspect = screen_width_aspect;
+               source_height_aspect = screen_height_aspect;
+#ifdef USE_SCREEN_ROTATE
+       }
+#endif
+       
+       if(config.stretch_type == 1 && !window_mode) {
+               // fit to full screen (aspect)
+               stretched_width = (display_height * source_width_aspect) / source_height_aspect;
+               stretched_height = display_height;
+               if(stretched_width > display_width) {
+                       stretched_width = display_width;
+                       stretched_height = (display_width * source_height_aspect) / source_width_aspect;
+               }
+       } else if(config.stretch_type == 2 && !window_mode) {
+               // fit to full screen (fill)
+               stretched_width = display_width;
+               stretched_height = display_height;
+       } else {
+               // dot by dot
+               int tmp_pow_x = display_width / source_width_aspect;
+               int tmp_pow_y = display_height / source_height_aspect;
+               int tmp_pow = 1;
+               if(tmp_pow_y >= tmp_pow_x && tmp_pow_x > 1) {
+                       tmp_pow = tmp_pow_x;
+               } else if(tmp_pow_x >= tmp_pow_y && tmp_pow_y > 1) {
+                       tmp_pow = tmp_pow_y;
+               }
+               stretched_width = source_width_aspect * tmp_pow;
+               stretched_height = source_height_aspect * tmp_pow;
+       }
+       screen_dest_x = (display_width - stretched_width) / 2;
+       screen_dest_y = (display_height - stretched_height) / 2;
+       
+       stretch_changed |= (prev_stretched_width != stretched_width);
+       stretch_changed |= (prev_stretched_height != stretched_height);
+       
+       int new_pow_x = 1, new_pow_y = 1;
+       while(stretched_width > source_width * new_pow_x) {
+               new_pow_x++;
+       }
+       while(stretched_height > source_height * new_pow_y) {
+               new_pow_y++;
+       }
+//     if(!use_d3d9 && new_pow_x > 1 && new_pow_y > 1) {
+//             // support high quality stretch only for x1 window size in gdi mode
+//             new_pow_x = new_pow_y = 1;
+//     }
+       if(stretch_pow_x != new_pow_x || stretch_pow_y != new_pow_y) {
+               stretch_pow_x = new_pow_x;
+               stretch_pow_y = new_pow_y;
+               stretch_changed = true;
+       }
+       if(stretch_pow_x != 1 || stretch_pow_y != 1) {
+               render_to_d3d9Buffer = false;
+       }
+       
+       if(stretch_changed) {
+               release_dib_section(hdcDibStretch1, hBmpStretch1, hOldBmpStretch1, lpBufStretch1);
+               release_dib_section(hdcDibStretch2, hBmpStretch2, hOldBmpStretch2, lpBufStretch2);
+               stretch_screen = false;
+               
+               if(stretch_pow_x != 1 || stretch_pow_y != 1) {
+                       HDC hdc = GetDC(main_window_handle);
+                       create_dib_section(hdc, source_width * stretch_pow_x, source_height * stretch_pow_y, &hdcDibStretch1, &hBmpStretch1, &hOldBmpStretch1, &lpBufStretch1, &lpBmpStretch1, &lpDibStretch1);
+                       SetStretchBltMode(hdcDibStretch1, COLORONCOLOR);
+                       if(!use_d3d9) {
+                               create_dib_section(hdc, stretched_width, stretched_height, &hdcDibStretch2, &hBmpStretch2, &hOldBmpStretch2, &lpBufStretch2, &lpBmpStretch2, &lpDibStretch2);
+                               SetStretchBltMode(hdcDibStretch2, HALFTONE);
+                       }
+                       ReleaseDC(main_window_handle, hdc);
+                       stretch_screen = true;
+               }
+               
+               if(use_d3d9 && display_size_changed) {
+                       // release and initialize d3d9
+                       release_d3d9();
+                       
+                       if((lpd3d9 = Direct3DCreate9(D3D_SDK_VERSION)) == NULL) {
+                               MessageBox(main_window_handle, _T("Failed to initialize Direct3D9"), _T(DEVICE_NAME), MB_OK | MB_ICONWARNING);
+                               config.use_d3d9 = false;
+                               goto RETRY;
+                       } else {
+                               // initialize present params
+                               D3DPRESENT_PARAMETERS d3dpp;
+                               ZeroMemory(&d3dpp, sizeof(d3dpp));
+                               d3dpp.BackBufferWidth = display_width;
+                               d3dpp.BackBufferHeight = display_height;
+                               d3dpp.BackBufferFormat = D3DFMT_X8R8G8B8;//D3DFMT_UNKNOWN;
+                               d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
+                               d3dpp.hDeviceWindow = main_window_handle;
+                               d3dpp.Windowed = TRUE;
+                               d3dpp.Flags = D3DPRESENTFLAG_LOCKABLE_BACKBUFFER;
+                               d3dpp.PresentationInterval = config.wait_vsync ? D3DPRESENT_INTERVAL_ONE : D3DPRESENT_INTERVAL_IMMEDIATE;
+                               
+                               // create d3d9 device
+                               HRESULT hr = lpd3d9->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, main_window_handle, D3DCREATE_HARDWARE_VERTEXPROCESSING, &d3dpp, &lpd3d9Device);
+                               if(hr != D3D_OK) {
+                                       hr = lpd3d9->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, main_window_handle, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &lpd3d9Device);
+                                       if(hr != D3D_OK) {
+                                               hr = lpd3d9->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_REF, main_window_handle, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &lpd3d9Device);
+                                       }
+                               }
+                               if(hr != D3D_OK) {
+                                       MessageBox(main_window_handle, _T("Failed to create a Direct3D9 device"), _T(DEVICE_NAME), MB_OK | MB_ICONWARNING);
+                                       config.use_d3d9 = false;
+                                       goto RETRY;
+                               }
+                       }
+               }
+               if(use_d3d9 && lpd3d9Device != NULL) {
+                       // release and create d3d9 surfaces
+                       release_d3d9_surface();
+                       
+                       HRESULT hr = lpd3d9Device->CreateOffscreenPlainSurface(source_width * stretch_pow_x, source_height * stretch_pow_y, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &lpd3d9Surface, NULL);
+                       if(hr == D3D_OK) {
+                               hr = lpd3d9Device->CreateOffscreenPlainSurface(source_width * stretch_pow_x, source_height * stretch_pow_y, D3DFMT_X8R8G8B8, D3DPOOL_SYSTEMMEM, &lpd3d9OffscreenSurface, NULL);
+                       }
+                       if(hr == D3D_OK) {
+                               lpd3d9Device->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0, 0, 0), 0.0, 0);
+                       } else {
+                               MessageBox(main_window_handle, _T("Failed to create a Direct3D9 offscreen surface"), _T(DEVICE_NAME), MB_OK | MB_ICONWARNING);
+                               config.use_d3d9 = false;
+                               goto RETRY;
+                       }
+               }
+               if(stretch_screen) {
+                       render_to_d3d9Buffer = false;
+               }
+       }
+       
+       first_draw_screen = false;
+       first_invalidate = true;
+       screen_size_changed = false;
+#endif 
+#ifdef USE_CRT_FILTER
+       memset(r1, 0, sizeof(r1));
+       memset(g1, 0, sizeof(g1));
+       memset(b1, 0, sizeof(b1));
+#endif
+}
+
+void EMU::change_screen_size(int sw, int sh, int swa, int sha, int ww, int wh)
+{
+   
+#if 0
+  // virtual machine changes the screen size
+       if(screen_width != sw || screen_height != sh) {
+               screen_width = sw;
+               screen_height = sh;
+               screen_width_aspect = (swa != -1) ? swa : sw;
+               screen_height_aspect = (sha != -1) ? sha : sh;
+               window_width = ww;
+               window_height = wh;
+               screen_size_changed = true;
+               
+               // re-create dib sections
+               HDC hdc = GetDC(main_window_handle);
+               release_dib_section(hdcDib, hBmp, hOldBmp, lpBuf);
+               create_dib_section(hdc, screen_width, screen_height, &hdcDib, &hBmp, &hOldBmp, &lpBuf, &lpBmp, &lpDib);
+#ifdef USE_SCREEN_ROTATE
+               release_dib_section(hdcDibRotate, hBmpRotate, hOldBmpRotate, lpBufRotate);
+               create_dib_section(hdc, screen_height, screen_width, &hdcDibRotate, &hBmpRotate, &hOldBmpRotate, &lpBufRotate, &lpBmpRotate, &lpDibRotate);
+#endif
+               ReleaseDC(main_window_handle, hdc);
+               
+               // stop recording
+               if(now_rec_video) {
+                       stop_rec_video();
+                       stop_rec_sound();
+               }
+               
+               // change the window size
+               PostMessage(main_window_handle, WM_RESIZE, 0L, 0L);
+       }
+#endif
+}
+
+int EMU::draw_screen()
+{
+       // don't draw screen before new screen size is applied to buffers
+       if(screen_size_changed) {
+               return 0;
+       }
+       
+       // check avi file recording timing
+       if(now_rec_video && rec_video_run_frames <= 0) {
+               return 0;
+       }
+       
+       // lock offscreen surface
+       
+       // draw screen
+       vm->draw_screen();
+       
+       // screen size was changed in vm->draw_screen()
+       if(screen_size_changed) {
+               // unlock offscreen surface
+               return 0;
+       }
+#if 0  
+#ifdef USE_SCREEN_ROTATE
+       // rotate screen
+       if(config.monitor_type) {
+       }
+#endif 
+       
+       // stretch screen
+       if(stretch_screen) {
+               scrntype* src = lpBmpSource + source_width * (source_height - 1);
+               scrntype* out = lpBmpStretch1 + source_width * stretch_pow_x * (source_height * stretch_pow_y - 1);
+               int data_len = source_width * stretch_pow_x;
+#ifdef USE_CRT_FILTER
+               #define _3_8(v) (((((v) * 3) >> 3) * 180) >> 8)
+               #define _5_8(v) (((((v) * 3) >> 3) * 180) >> 8)
+               #define _8_8(v) (((v) * 180) >> 8)
+               
+               if(config.crt_filter && stretch_pow_x == 3 && stretch_pow_y == 3) {
+                       r1[0] = g1[0] = b1[0] = r1[source_width + 1] = g1[source_width + 1] = b1[source_width + 1] = 0;
+                       
+                       if(!screen_skip_line) {
+                               for(int y = 0; y < source_height; y++) {
+                                       for(int x = 1; x <= source_width; x++) {
+                                               uint32 c = src[x - 1];
+                                               t0[x] = (c >> 24) & 0xff;
+                                               r0[x] = (c >> 16) & 0xff;
+                                               g0[x] = (c >>  8) & 0xff;
+                                               b0[x] = (c      ) & 0xff;
+                                               r1[x] = (c >> 19) & 0x1f;
+                                               g1[x] = (c >> 11) & 0x1f;
+                                               b1[x] = (c >>  3) & 0x1f;
+                                       }
+                                       scrntype* out1 = out;
+                                       out -= data_len;
+                                       scrntype* out2 = out;
+                                       out -= data_len;
+                                       scrntype* out3 = out;
+                                       out -= data_len;
+                                       for(int x = 1, xx = 0; x <= source_width; x++, xx += 3) {
+                                               uint32 r = r1[x - 1] + r0[x] + r1[x + 1];
+                                               uint32 g = g1[x - 1] + g0[x] + g1[x + 1];
+                                               uint32 b = b1[x - 1] + b0[x] + b1[x + 1];
+                                               out1[xx    ] = out2[xx    ] = (32 + _8_8(r)) << 16;
+                                               out1[xx + 1] = out2[xx + 1] = (32 + _8_8(g)) << 8;
+                                               out1[xx + 2] = out2[xx + 2] = (32 + _8_8(b));
+                                               if(t0[x]) {
+                                                       out3[xx    ] = (32 + _8_8(r)) << 16;
+                                                       out3[xx + 1] = (32 + _8_8(g)) << 8;
+                                                       out3[xx + 2] = (32 + _8_8(b));
+                                               } else {
+                                                       out3[xx    ] = (32 + _5_8(r)) << 16;
+                                                       out3[xx + 1] = (32 + _5_8(g)) << 8;
+                                                       out3[xx + 2] = (32 + _5_8(b));
+                                               }
+                                       }
+                                       src -= source_width;
+                               }
+                       } else {
+                               for(int y = 0; y < source_height; y += 2) {
+                                       for(int x = 1; x <= source_width; x++) {
+                                               uint32 c = src[x - 1];
+                                               t0[x] = (c >> 24) & 0xff;
+                                               r0[x] = (c >> 16) & 0xff;
+                                               g0[x] = (c >>  8) & 0xff;
+                                               b0[x] = (c      ) & 0xff;
+                                               r1[x] = (c >> 20) & 0x0f;
+                                               g1[x] = (c >> 12) & 0x0f;
+                                               b1[x] = (c >>  4) & 0x0f;
+                                       }
+                                       scrntype* out1 = out;
+                                       out -= data_len;
+                                       scrntype* out2 = out;
+                                       out -= data_len;
+                                       scrntype* out3 = out;
+                                       out -= data_len;
+                                       scrntype* out4 = out;
+                                       out -= data_len;
+                                       scrntype* out5 = out;
+                                       out -= data_len;
+                                       scrntype* out6 = out;
+                                       out -= data_len;
+                                       for(int x = 1, xx = 0; x <= source_width; x++, xx += 3) {
+                                               uint32 r = r1[x - 1] + r0[x] + r1[x + 1];
+                                               uint32 g = g1[x - 1] + g0[x] + g1[x + 1];
+                                               uint32 b = b1[x - 1] + b0[x] + b1[x + 1];
+                                               out1[xx    ] = out2[xx    ] = out3[xx    ] = out4[xx    ] = (32 + _8_8(r)) << 16;
+                                               out1[xx + 1] = out2[xx + 1] = out3[xx + 1] = out4[xx + 1] = (32 + _8_8(g)) << 8;
+                                               out1[xx + 2] = out2[xx + 2] = out3[xx + 2] = out4[xx + 2] = (32 + _8_8(b));
+                                               if(t0[x]) {
+                                                       out5[xx    ] = out6[xx    ] = (32 + _8_8(r)) << 16;
+                                                       out5[xx + 1] = out6[xx + 1] = (32 + _8_8(g)) << 8;
+                                                       out5[xx + 2] = out6[xx + 2] = (32 + _8_8(b));
+                                               } else {
+                                                       out5[xx    ] = out6[xx    ] = (32 + _5_8(r)) << 16;
+                                                       out5[xx + 1] = out6[xx + 1] = (32 + _5_8(g)) << 8;
+                                                       out5[xx + 2] = out6[xx + 2] = (32 + _5_8(b));
+                                               }
+                                       }
+                                       src -= source_width * 2;
+                               }
+                       }
+               } else if(config.crt_filter && stretch_pow_x == 2 && stretch_pow_y == 2) {
+                       if(!screen_skip_line) {
+                               for(int y = 0; y < source_height; y++) {
+                                       for(int x = 1; x <= source_width; x++) {
+                                               uint32 c = src[x - 1];
+                                               t0[x] = (c >> 24) & 0xff;
+                                               r0[x] = (c >> 16) & 0xff;
+                                               g0[x] = (c >>  8) & 0xff;
+                                               b0[x] = (c      ) & 0xff;
+                                               r1[x] = (c >> 19) & 0x1f;
+                                               g1[x] = (c >> 11) & 0x1f;
+                                               b1[x] = (c >>  3) & 0x1f;
+                                       }
+                                       scrntype* out1 = out;
+                                       out -= data_len;
+                                       scrntype* out2 = out;
+                                       out -= data_len;
+                                       for(int x = 1, xx = 0; x <= source_width; x++, xx += 2) {
+                                               uint32 r = r1[x - 1] + r0[x] + r1[x + 1];
+                                               uint32 g = g1[x - 1] + g0[x] + g1[x + 1];
+                                               uint32 b = b1[x - 1] + b0[x] + b1[x + 1];
+                                               out1[xx    ] = RGB_COLOR(32 + _8_8(r), 32 + _8_8(g), 32 + _8_8(b));
+                                               out1[xx + 1] = RGB_COLOR(16 + _5_8(r), 16 + _5_8(g), 16 + _5_8(b));
+                                               if(t0[x]) {
+                                                       out2[xx    ] = RGB_COLOR(32 + _8_8(r), 32 + _8_8(g), 32 + _8_8(b));
+                                                       out2[xx + 1] = RGB_COLOR(16 + _5_8(r), 16 + _5_8(g), 16 + _5_8(b));
+                                               } else {
+                                                       out2[xx    ] = RGB_COLOR(32 + _3_8(r), 32 + _3_8(g), 32 + _3_8(b));
+                                                       out2[xx + 1] = RGB_COLOR(16 + _3_8(r), 16 + _3_8(g), 16 + _3_8(b));
+                                               }
+                                       }
+                                       src -= source_width;
+                               }
+                       } else {
+                               for(int y = 0; y < source_height; y += 2) {
+                                       for(int x = 1; x <= source_width; x++) {
+                                               uint32 c = src[x - 1];
+                                               t0[x] = (c >> 24) & 0xff;
+                                               r0[x] = (c >> 16) & 0xff;
+                                               g0[x] = (c >>  8) & 0xff;
+                                               b0[x] = (c      ) & 0xff;
+                                               r1[x] = (c >> 19) & 0x1f;
+                                               g1[x] = (c >> 11) & 0x1f;
+                                               b1[x] = (c >>  3) & 0x1f;
+                                       }
+                                       scrntype* out1 = out;
+                                       out -= data_len;
+                                       scrntype* out2 = out;
+                                       out -= data_len;
+                                       scrntype* out3 = out;
+                                       out -= data_len;
+                                       scrntype* out4 = out;
+                                       out -= data_len;
+                                       for(int x = 1, xx = 0; x <= source_width; x++, xx += 2) {
+                                               uint32 r = r1[x - 1] + r0[x] + r1[x + 1];
+                                               uint32 g = g1[x - 1] + g0[x] + g1[x + 1];
+                                               uint32 b = b1[x - 1] + b0[x] + b1[x + 1];
+                                               out1[xx    ] = out2[xx    ] = out3[xx    ] = RGB_COLOR(32 + _8_8(r), 32 + _8_8(g), 32 + _8_8(b));
+                                               out1[xx + 1] = out2[xx + 1] = out3[xx + 1] = RGB_COLOR(16 + _5_8(r), 16 + _5_8(g), 16 + _5_8(b));
+                                               if(t0[x]) {
+                                                       out4[xx    ] = RGB_COLOR(32 + _8_8(r), 32 + _8_8(g), 32 + _8_8(b));
+                                                       out4[xx + 1] = RGB_COLOR(16 + _5_8(r), 16 + _5_8(g), 16 + _5_8(b));
+                                               } else {
+                                                       out4[xx    ] = RGB_COLOR(32 + _3_8(r), 32 + _3_8(g), 32 + _3_8(b));
+                                                       out4[xx + 1] = RGB_COLOR(16 + _3_8(r), 16 + _3_8(g), 16 + _3_8(b));
+                                               }
+                                       }
+                                       src -= source_width * 2;
+                               }
+                       }
+               } else
+#endif
+               for(int y = 0; y < source_height; y++) {
+                       if(stretch_pow_x != 1) {
+                               scrntype* out_tmp = out;
+                               for(int x = 0; x < source_width; x++) {
+                                       scrntype c = src[x];
+                                       for(int px = 0; px < stretch_pow_x; px++) {
+                                               out_tmp[px] = c;
+                                       }
+                                       out_tmp += stretch_pow_x;
+                               }
+                       } else {
+                               // faster than memcpy()
+                               for(int x = 0; x < source_width; x++) {
+                                       out[x] = src[x];
+                               }
+                       }
+                       if(stretch_pow_y != 1) {
+                               scrntype* src_tmp = out;
+                               for(int py = 1; py < stretch_pow_y; py++) {
+                                       out -= data_len;
+                                       // about 10% faster than memcpy()
+                                       for(int x = 0; x < data_len; x++) {
+                                               out[x] = src_tmp[x];
+                                       }
+                               }
+                       }
+                       src -= source_width;
+                       out -= data_len;
+               }
+               if(!use_d3d9) {
+                       StretchBlt(hdcDibStretch2, 0, 0, stretched_width, stretched_height, hdcDibStretch1, 0, 0, source_width * stretch_pow_x, source_height * stretch_pow_y, SRCCOPY);
+               }
+       }
+       first_draw_screen = true;
+       
+       // copy bitmap to d3d9 offscreen surface
+       if(use_d3d9 && lpd3d9Buffer != NULL) {
+               if(!(render_to_d3d9Buffer && !now_rec_video)) {
+                       scrntype *src = stretch_screen ? lpBmpStretch1 : lpBmpSource;
+                       src += source_width * stretch_pow_x * (source_height * stretch_pow_y - 1);
+                       scrntype *out = lpd3d9Buffer;
+                       int data_len = source_width * stretch_pow_x;
+                       
+                       for(int y = 0; y < source_height * stretch_pow_y; y++) {
+                               for(int i = 0; i < data_len; i++) {
+                                       out[i] = src[i];
+                               }
+                               src -= data_len;
+                               out += data_len;
+                       }
+               }
+               // unlock offscreen surface
+               lpd3d9Buffer = NULL;
+               lpd3d9OffscreenSurface->UnlockRect();
+       }
+       
+       // invalidate window
+       InvalidateRect(main_window_handle, NULL, first_invalidate);
+       UpdateWindow(main_window_handle);
+       self_invalidate = true;
+       
+       // record avi file
+       if(now_rec_video) {
+               static double frames = 0;
+               static int prev_video_fps = -1;
+#ifdef SUPPORT_VARIABLE_TIMING
+               static double prev_vm_fps = -1;
+               double vm_fps = vm->frame_rate();
+               if(prev_video_fps != rec_video_fps || prev_vm_fps != vm_fps) {
+                       prev_video_fps = rec_video_fps;
+                       prev_vm_fps = vm_fps;
+                       frames = vm_fps / rec_video_fps;
+               }
+#else
+               if(prev_video_fps != rec_video_fps) {
+                       prev_video_fps = rec_video_fps;
+                       frames = FRAMES_PER_SEC / rec_video_fps;
+               }
+#endif
+               int counter = 0;
+               if(use_video_thread) {
+                       while(rec_video_run_frames > 0) {
+                               rec_video_run_frames -= frames;
+                               rec_video_frames += frames;
+                               counter++;
+                       }
+                       if(counter != 0) {
+                               if(hVideoThread != (HANDLE)0) {
+                                       if(video_thread_param.result == 0) {
+                                               WaitForSingleObject(hVideoThread, INFINITE);
+                                       }
+                                       hVideoThread = (HANDLE)0;
+                                       
+                                       if(video_thread_param.result == RESULT_FULL) {
+                                               stop_rec_video();
+                                               if(!start_rec_video(-1)) {
+                                                       return 0;
+                                               }
+                                       } else if(video_thread_param.result == RESULT_ERROR) {
+                                               stop_rec_video();
+                                               return 0;
+                                       }
+                               }
+                               BitBlt(hdcDibRec, 0, 0, source_width, source_height, hdcDibSource, 0, 0, SRCCOPY);
+                               video_thread_param.frames += counter;
+                               video_thread_param.result = 0;
+                               if((hVideoThread = (HANDLE)_beginthreadex(NULL, 0, rec_video_thread, &video_thread_param, 0, NULL)) == (HANDLE)0) {
+                                       stop_rec_video();
+                                       return 0;
+                               }
+                       }
+               } else {
+                       while(rec_video_run_frames > 0) {
+                               LONG lBytesWritten;
+                               if(AVIStreamWrite(pAVICompressed, lAVIFrames++, 1, (LPBYTE)lpBmpSource, pbmInfoHeader->biSizeImage, AVIIF_KEYFRAME, NULL, &lBytesWritten) == AVIERR_OK) {
+                                       // if avi file size > (2GB - 16MB), create new avi file
+                                       if((dwAVIFileSize += lBytesWritten) >= 2130706432) {
+                                               stop_rec_video();
+                                               if(!start_rec_video(-1)) {
+                                                       break;
+                                               }
+                                       }
+                                       rec_video_run_frames -= frames;
+                                       rec_video_frames += frames;
+                                       counter++;
+                               } else {
+                                       stop_rec_video();
+                                       break;
+                               }
+                       }
+               }
+               return counter;
+       } else {
+               return 1;
+       }
+#endif
+   return 0;
+}
+
+
+
+scrntype* EMU::screen_buffer(int y)
+{
+//     if(use_d3d9 && lpd3d9Buffer != NULL && render_to_d3d9Buffer && !now_rec_video) {
+//             return lpd3d9Buffer + screen_width * y;
+//     }
+//     return lpBmp + screen_width * (screen_height - y - 1);
+   Uint32 *p = pPseudoVram;
+   if((y >= SCREEN_HEIGHT) || (y < 0)) return NULL;
+   bDrawLine[y] = true;;
+
+   p = &(p[y * SCREEN_WIDTH]);
+   return p;
+}
+#if defined(_USE_AGAR) || defined(_USE_SDL)
+void EMU::update_screen(AG_Widget *target)
+#else
+void EMU::update_screen(HDC hdc)
+#endif
+{
+   // UpdateScreen
+   if(hScreenWidget != NULL) {
+       AG_Redraw(hScreenWidget);
+   }
+       
+   
+
+#if 0
+
+
+# ifdef USE_BITMAP
+       if(first_invalidate || !self_invalidate) {
+               HDC hmdc = CreateCompatibleDC(hdc);
+               HBITMAP hBitmap = LoadBitmap(instance_handle, _T("IDI_BITMAP1"));
+               BITMAP bmp;
+               GetObject(hBitmap, sizeof(BITMAP), &bmp);
+               int w = (int)bmp.bmWidth;
+               int h = (int)bmp.bmHeight;
+               HBITMAP hOldBitmap = (HBITMAP)SelectObject(hmdc, hBitmap);
+               BitBlt(hdc, 0, 0, w, h, hmdc, 0, 0, SRCCOPY);
+               SelectObject(hmdc, hOldBitmap);
+               DeleteObject(hBitmap);
+               DeleteDC(hmdc);
+       }
+#endif
+       if(first_draw_screen) {
+#ifdef USE_LED
+               // 7-seg LEDs
+               for(int i = 0; i < MAX_LEDS; i++) {
+                       int x = leds[i].x;
+                       int y = leds[i].y;
+                       int w = leds[i].width;
+                       int h = leds[i].height;
+                       BitBlt(hdc, x, y, w, h, hdcDib, x, y, SRCCOPY);
+               }
+#else
+#ifdef USE_ACCESS_LAMP
+               // get access lamps status of drives
+               int status = vm->access_lamp() & 7;
+               static int prev_status = 0;
+               bool render_in = (status != 0);
+               bool render_out = (prev_status != status);
+               prev_status = status;
+               
+               COLORREF crColor = RGB((status & 1) ? 255 : 0, (status & 2) ? 255 : 0, (status & 4) ? 255 : 0);
+               int right_bottom_x = screen_dest_x + stretched_width;
+               int right_bottom_y = screen_dest_y + stretched_height;
+#endif
+               // standard screen
+               if(use_d3d9) {
+                       LPDIRECT3DSURFACE9 lpd3d9BackSurface = NULL;
+                       if(lpd3d9Device != NULL && lpd3d9Device->GetBackBuffer(0, 0, D3DBACKBUFFER_TYPE_MONO, &lpd3d9BackSurface) == D3D_OK && lpd3d9BackSurface != NULL) {
+                               RECT rectSrc = { 0, 0, source_width * stretch_pow_x, source_height * stretch_pow_y };
+                               RECT rectDst = { screen_dest_x, screen_dest_y, screen_dest_x + stretched_width, screen_dest_y + stretched_height };
+                               
+                               lpd3d9Device->UpdateSurface(lpd3d9OffscreenSurface, NULL, lpd3d9Surface, NULL);
+                               lpd3d9Device->StretchRect(lpd3d9Surface, &rectSrc, lpd3d9BackSurface, &rectDst, stretch_screen ? D3DTEXF_LINEAR : D3DTEXF_POINT);
+#ifdef USE_ACCESS_LAMP
+                               // draw access lamps
+                               if(render_in || render_out) {
+                                       HDC hDC = 0;
+                                       for(int y = display_height - 6; y < display_height; y++) {
+                                               for(int x = display_width - 6; x < display_width; x++) {
+                                                       if((x < right_bottom_x && y < right_bottom_y) ? render_in : render_out) {
+                                                               if(hDC == 0 && lpd3d9BackSurface->GetDC(&hDC) != D3D_OK) {
+                                                                       goto quit;
+                                                               }
+                                                               SetPixelV(hDC, x, y, crColor);
+                                                       }
+                                               }
+                                       }
+quit:
+                                       if(hDC != 0) {
+                                               lpd3d9BackSurface->ReleaseDC(hDC);
+                                       }
+                               }
+#endif
+                               lpd3d9BackSurface->Release();
+                               lpd3d9Device->Present(NULL, NULL, NULL, NULL);
+                       }
+               } else {
+                       if(stretch_screen) {
+                               BitBlt(hdc, screen_dest_x, screen_dest_y, stretched_width, stretched_height, hdcDibStretch2, 0, 0, SRCCOPY);
+                       } else if(stretched_width == source_width && stretched_height == source_height) {
+                               BitBlt(hdc, screen_dest_x, screen_dest_y, stretched_width, stretched_height, hdcDibSource, 0, 0, SRCCOPY);
+                       } else {
+                               StretchBlt(hdc, screen_dest_x, screen_dest_y, stretched_width, stretched_height, hdcDibSource, 0, 0, source_width, source_height, SRCCOPY);
+                       }
+#ifdef USE_ACCESS_LAMP
+                       // draw access lamps
+                       if(render_in || render_out) {
+                               for(int y = display_height - 6; y < display_height; y++) {
+                                       for(int x = display_width - 6; x < display_width; x++) {
+                                               if((x < right_bottom_x && y < right_bottom_y) ? render_in : render_out) {
+                                                       SetPixelV(hdc, x, y, crColor);
+                                               }
+                                       }
+                               }
+                       }
+#endif
+               }
+#endif
+               first_invalidate = self_invalidate = false;
+       }
+#endif
+}
+
+void EMU::capture_screen()
+{
+#if 0
+     if(use_d3d9 && render_to_d3d9Buffer && !now_rec_video) {
+               // virtual machine may render screen to d3d9 buffer directly...
+               vm->draw_screen();
+       }
+       
+       // create file name
+       SYSTEMTIME sTime;
+       GetLocalTime(&sTime);
+       
+       _TCHAR file_name[_MAX_PATH];
+       _stprintf(file_name, _T("%d-%0.2d-%0.2d_%0.2d-%0.2d-%0.2d.bmp"), sTime.wYear, sTime.wMonth, sTime.wDay, sTime.wHour, sTime.wMinute, sTime.wSecond);
+       
+       // create bitmap
+       BITMAPFILEHEADER bmFileHeader = { (WORD)(TEXT('B') | TEXT('M') << 8) };
+       bmFileHeader.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);
+       bmFileHeader.bfSize = bmFileHeader.bfOffBits + pbmInfoHeader->biSizeImage;
+       
+       DWORD dwSize;
+       HANDLE hFile = CreateFile(bios_path(file_name), GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
+       WriteFile(hFile, &bmFileHeader, sizeof(BITMAPFILEHEADER), &dwSize, NULL);
+       WriteFile(hFile, lpDibSource, sizeof(BITMAPINFOHEADER), &dwSize, NULL);
+       WriteFile(hFile, lpBmpSource, pbmInfoHeader->biSizeImage, &dwSize, NULL);
+       CloseHandle(hFile);
+#endif
+}
+
+bool EMU::start_rec_video(int fps)
+{
+#if 0
+       if(fps > 0) {
+               rec_video_fps = fps;
+               rec_video_run_frames = rec_video_frames = 0;
+       } else {
+               fps = rec_video_fps;
+       }
+       bool show_dialog = (fps > 0);
+       
+       // create file name
+       SYSTEMTIME sTime;
+       GetLocalTime(&sTime);
+       
+       _stprintf(video_file_name, _T("%d-%0.2d-%0.2d_%0.2d-%0.2d-%0.2d.avi"), sTime.wYear, sTime.wMonth, sTime.wDay, sTime.wHour, sTime.wMinute, sTime.wSecond);
+       
+       // initialize vfw
+       AVIFileInit();
+       if(AVIFileOpen(&pAVIFile, bios_path(video_file_name), OF_WRITE | OF_CREATE, NULL) != AVIERR_OK) {
+               return false;
+       }
+       use_video_thread = false;
+       
+       // stream header
+       AVISTREAMINFO strhdr;
+       memset(&strhdr, 0, sizeof(strhdr));
+       strhdr.fccType = streamtypeVIDEO;       // vids
+       strhdr.fccHandler = 0;
+       strhdr.dwScale = 1;
+       strhdr.dwRate = fps;
+       strhdr.dwSuggestedBufferSize = pbmInfoHeader->biSizeImage;
+       SetRect(&strhdr.rcFrame, 0, 0, source_width, source_height);
+       if(AVIFileCreateStream(pAVIFile, &pAVIStream, &strhdr) != AVIERR_OK) {
+               stop_rec_video();
+               return false;
+       }
+       
+       // compression
+       AVICOMPRESSOPTIONS FAR * pOpts[1];
+       pOpts[0] = &opts;
+       if(show_dialog && !AVISaveOptions(main_window_handle, ICMF_CHOOSE_KEYFRAME | ICMF_CHOOSE_DATARATE, 1, &pAVIStream, (LPAVICOMPRESSOPTIONS FAR *)&pOpts)) {
+               AVISaveOptionsFree(1, (LPAVICOMPRESSOPTIONS FAR *)&pOpts);
+               stop_rec_video();
+               return false;
+       }
+       if(AVIMakeCompressedStream(&pAVICompressed, pAVIStream, &opts, NULL) != AVIERR_OK) {
+               stop_rec_video();
+               return false;
+       }
+       if(AVIStreamSetFormat(pAVICompressed, 0, &lpDibSource->bmiHeader, lpDibSource->bmiHeader.biSize + lpDibSource->bmiHeader.biClrUsed * sizeof(RGBQUAD)) != AVIERR_OK) {
+               stop_rec_video();
+               return false;
+       }
+       dwAVIFileSize = 0;
+       lAVIFrames = 0;
+       
+       SYSTEM_INFO info;
+       GetSystemInfo(&info);
+       
+       if(info.dwNumberOfProcessors > 1) {
+               use_video_thread = true;
+               hVideoThread = (HANDLE)0;
+               video_thread_param.pAVICompressed = pAVICompressed;
+               video_thread_param.lpBmpSource = lpBmpSource;
+               video_thread_param.pbmInfoHeader = pbmInfoHeader;
+               video_thread_param.dwAVIFileSize = 0;
+               video_thread_param.lAVIFrames = 0;
+               video_thread_param.frames = 0;
+               video_thread_param.result = 0;
+               
+               HDC hdc = GetDC(main_window_handle);
+               create_dib_section(hdc, source_width, source_height, &hdcDibRec, &hBmpRec, &hOldBmpRec, &lpBufRec, &lpBmpRec, &lpDibRec);
+               ReleaseDC(main_window_handle, hdc);
+       }
+       now_rec_video = true;
+       return true;
+#endif
+}
+
+void EMU::stop_rec_video()
+{
+#if 0
+        // release thread
+       if(use_video_thread) {
+               if(hVideoThread != (HANDLE)0) {
+                       WaitForSingleObject(hVideoThread, INFINITE);
+                       hVideoThread = (HANDLE)0;
+               }
+               if(hdcDibRec) {
+                       release_dib_section(hdcDibRec, hBmpRec, hOldBmpRec, lpBufRec);
+               }
+       }
+       
+       // release vfw
+       if(pAVIStream) {
+               AVIStreamClose(pAVIStream);
+       }
+       if(pAVICompressed) {
+               AVIStreamClose(pAVICompressed);
+       }
+       if(pAVIFile) {
+               AVIFileClose(pAVIFile);
+               AVIFileExit();
+       }
+       pAVIStream = NULL;
+       pAVICompressed = NULL;
+       pAVIFile = NULL;
+       
+       // repair header
+       if(now_rec_video) {
+               FILE* fp = _tfopen(bios_path(video_file_name), _T("r+b"));
+               if(fp != NULL) {
+                       // copy fccHandler
+                       uint8 buf[4];
+                       fseek(fp, 0xbc, SEEK_SET);
+                       if(ftell(fp) == 0xbc) {
+                               fread(buf, 4, 1, fp);
+                               fseek(fp, 0x70, SEEK_SET);
+                               fwrite(buf, 4, 1, fp);
+                       }
+                       fclose(fp);
+               }
+       }
+       now_rec_video = false;
+#endif
+}
+
+void EMU::restart_rec_video()
+{
+       bool tmp = now_rec_video;
+       stop_rec_video();
+       if(tmp) start_rec_video(-1);
+}
+
+void *rec_video_thread(void *lpx)
+{
+#if 0
+   volatile video_thread_t *p = (video_thread_t *)lpx;
+       LONG lBytesWritten;
+       int result = RESULT_SUCCESS;
+       
+       while(p->frames > 0) {
+               if(AVIStreamWrite(p->pAVICompressed, p->lAVIFrames++, 1, (LPBYTE)p->lpBmpSource, p->pbmInfoHeader->biSizeImage, AVIIF_KEYFRAME, NULL, &lBytesWritten) == AVIERR_OK) {
+                       p->frames--;
+                       // if avi file size > (2GB - 16MB), create new avi file
+                       if((p->dwAVIFileSize += lBytesWritten) >= 2130706432) {
+                               result = RESULT_FULL;
+                               break;
+                       }
+               } else {
+                       result = RESULT_ERROR;
+                       break;
+               }
+       }
+       p->result = result;
+       _endthreadex(0);
+       return 0;
+#endif
+}
+
index f5ada3a..d82257c 100644 (file)
@@ -59,7 +59,6 @@ static int iOldW = 0;
 static int iOldH = 0;
 
 // Temporally entry. Please re-implement.
-BOOL bDrawLine[800];
 
 extern "C" {
    AG_Surface *GetDrawSurface(void)
@@ -192,6 +191,8 @@ static void *AGAR_SDLViewSelectScaler(int w0 ,int h0, int w1, int h1)
     int xth;
     void (*DrawFn)(Uint32 *src, Uint8 *dst, int xbegin, int xend, int y, int yrep);
     DrawFn = NULL;
+    DrawFn = pVram2RGB_x1_Line;
+   return (void *)DrawFn;
 
 #if defined(USE_SSE2)
    if(pCpuID != NULL){
@@ -272,7 +273,8 @@ static void *AGAR_SDLViewSelectScaler(int w0 ,int h0, int w1, int h1)
 }
 
 
-
+extern "C" {
+   
 void AGAR_SDLViewUpdateSrc(AG_Event *event)
 {
    AGAR_SDLView *my = (AGAR_SDLView *)AG_SELF();
@@ -302,8 +304,10 @@ void AGAR_SDLViewUpdateSrc(AG_Event *event)
    int xcache;
    BOOL flag = FALSE;
 
+
    Fn = AG_PTR(1);
    if(my == NULL) return;
+   if(emu == NULL) return;
    Surface = AGAR_SDLViewGetSrcSurface(my);
    
    if(Surface == NULL) return;
@@ -313,43 +317,12 @@ void AGAR_SDLViewUpdateSrc(AG_Event *event)
    pb = (Uint8 *)(Surface->pixels);
    pitch = Surface->pitch;
    bpp = Surface->format->BytesPerPixel;
-   
-
 //   if(pVram2 == NULL) return;
-   {
-      AG_Rect rr;
-      AG_Color cc;
-      
-      cc.r = 0x00;
-      cc.g = 0x00;
-      cc.b = 0x00;
-      cc.a = 0xff;
-      
-      LockVram();
-      //AG_ObjectLock(AGOBJECT(my));
-      AG_SurfaceLock(Surface);
-      AG_FillRect(Surface, NULL, cc);
-      //AG_ObjectUnlock(AGOBJECT(my));
-      AGAR_SDLViewSetDirty(my);
-      UnlockVram();
-      return;
-   }
-  
-//   switch(bMode){
-//    case SCR_200LINE:
-        ww = 640;
-        hh = 200;
-//        break;
-//    case SCR_400LINE:
-//        ww = 640;
-//        hh = 400;
-//        break;
-//    default:
-//        ww = 320;
-//        hh = 200;
-//        break;
-//   }
+   ww = SCREEN_WIDTH;
+   hh = SCREEN_HEIGHT;
    Fn = AGAR_SDLViewSelectScaler(ww , hh, w, h);
+//   printf("Enter Scaler = %08x\n", Fn);
+
    if(__builtin_expect((Fn != NULL), 1)) {
       DrawFn2 = (void (*)(Uint32 *, Uint8 *, int , int , int, int))Fn;
    } else {
@@ -369,25 +342,27 @@ void AGAR_SDLViewUpdateSrc(AG_Event *event)
 
    if(my->forceredraw != 0){
          for(yy = 0; yy < hh; yy++) {
-            bDrawLine[yy] = TRUE;
+            emu->bDrawLine[yy] = TRUE;
          }
          my->forceredraw = 0;
    }
    
-       Surface = GetDrawSurface();
        if(Surface == NULL)       goto _end1;
        AG_SurfaceLock(Surface);
        dst = (Uint8 *)(Surface->pixels);
        src = emu->screen_buffer(0);
-
+       //for(yy = 0; yy < SCREEN_HEIGHT; yy++) {
+       //for(xx = 0; xx < SCREEN_WIDTH; xx++) src[xx + SCREEN_HEIGHT * yy] |= 0xffffffff;
+       //}
+   
 #ifdef _OPENMP
-#pragma omp parallel for shared(hh, bDrawLine, yrep, ww, src, Surface, flag) private(dst, y2, y3)
+#pragma omp parallel for shared(hh, emu->bDrawLine, yrep, ww, src, Surface, flag) private(dst, y2, y3)
 #endif
       for(yy = 0 ; yy < hh; yy++) {
 /*
 *  Virtual VRAM -> Real Surface:
 */
-        if(__builtin_expect((bDrawLine[yy] == TRUE), 0)) {
+        if(__builtin_expect((emu->bDrawLine[yy] == TRUE), 0)) {
 //         _prefetch_data_read_l2(&src[yy * 80], ww * sizeof(Uint32));
            y2 = (h * yy ) / hh;
            y3 = (h * (yy + 1)) / hh;
@@ -395,11 +370,12 @@ void AGAR_SDLViewUpdateSrc(AG_Event *event)
            yrep2 = y3 - y2;
            if(__builtin_expect((yrep2 < 1), 0)) yrep2 = 1;
            DrawFn2(src, dst, 0, ww, yy, yrep2);
-           bDrawLine[yy] = FALSE;
+           emu->bDrawLine[yy] = FALSE;
            flag = TRUE;
         }
         dst = dst + (yrep2 * Surface->pitch);
       }
+//      printf("Draw! %d\n", AG_GetTicks());
       AG_SurfaceUnlock(Surface);
       // BREAK.
       goto _end1;
@@ -410,3 +386,4 @@ _end1:
    UnlockVram();
    return;
 }
+}
index fbc5084..5e6c9aa 100644 (file)
@@ -39,11 +39,11 @@ void pVram2RGB_x1_Line(Uint32 *src, Uint8 *dst, int xbegin, int xend, int y, int
    ww = xend - xbegin;
    if(ww <= 0) return;
    
-#if AG_BIG_ENDIAN != 1
+//#if AG_BIG_ENDIAN
    black = 0xff000000;
-#else
-   black = 0x000000ff;
-#endif
+//#else
+//   black = 0x000000ff;
+//#endif
    d1 = (Uint32 *)(dst + xbegin * Surface->format->BytesPerPixel);
    d2 = &src[xbegin + y * 640];
 
@@ -65,8 +65,12 @@ void pVram2RGB_x1_Line(Uint32 *src, Uint8 *dst, int xbegin, int xend, int y, int
 //     case 2:
          for(xx = 0; xx < ww; xx += 8) {
             b2p = (v4hi *)d1;
-            b2p[0] = b[0];
-            b2p[1] = b[1];
+            b2 = b[0];
+            b3 = b[1];
+            b2.vv = b2.vv | bb.vv;
+            b3.vv = b3.vv | bb.vv;
+            b2p[0] = b2;
+            b2p[1] = b3;
             d1 += 8;
             b += 2;
          }
@@ -77,7 +81,8 @@ void pVram2RGB_x1_Line(Uint32 *src, Uint8 *dst, int xbegin, int xend, int y, int
             d1 = d0;
             b2 = b[0];
             b3 = b[1];
-
+            b2.vv = b2.vv | bb.vv;
+            b3.vv = b3.vv | bb.vv;
             for(j = 0; j < yrep2; j++) {
                b2p = (v4hi *)d1;
                if(!bFullScan && (j >= (yrep2 >> 1))) {
index 2f7e139..f9c8d6a 100644 (file)
@@ -173,23 +173,23 @@ void EMU::update_sound(int* extra_frames)
                        sound_started = true;
                        return;
                }
-               SDL_LockAudio();
+               //SDL_LockAudio();
                // check current position
                play_c = nSndWritePos * sizeof(Sint16);
                if(first_half) {
                        if(play_c < (uBufSize / 2)) {
-                               SDL_UnlockAudio();
+                               //SDL_UnlockAudio();
                                return;
                        }
                        offset = 0;
                } else {
                        if(play_c >= (uBufSize / 2)) {
-                               SDL_UnlockAudio();
+                               //SDL_UnlockAudio();
                                return;
                        }
                        offset = uBufSize / 2;
                }
-               SDL_UnlockAudio();
+               //SDL_UnlockAudio();
                
                // sound buffer must be updated
                Sint16* sound_buffer = (Sint16 *)vm->create_sound(extra_frames);
index 17f68d4..c749bf1 100644 (file)
@@ -63,15 +63,15 @@ AG_Menu *AGAR_MainMenu(AG_Widget *parent)
    FloppyMenu(&MenuNode_FD_1, 0);
 #endif
 #ifdef USE_FD2
-   MenuNode_FD_1.Node = AG_MenuNode(menu->root, _N("Drive 1"), NULL);
+   MenuNode_FD_2.Node = AG_MenuNode(menu->root, _N("Drive 1"), NULL);
    FloppyMenu(&MenuNode_FD_2, 1);
 #endif
 #ifdef USE_FD3
-   MenuNode_FD_1.Node = AG_MenuNode(menu->root, _N("Drive 2"), NULL);
+   MenuNode_FD_3.Node = AG_MenuNode(menu->root, _N("Drive 2"), NULL);
    FloppyMenu(&MenuNode_FD_3, 2);
 #endif
 #ifdef USE_FD4
-   MenuNode_FD_1.Node = AG_MenuNode(menu->root, _N("Drive 3"), NULL);
+   MenuNode_FD_4.Node = AG_MenuNode(menu->root, _N("Drive 3"), NULL);
    FloppyMenu(&MenuNode_FD_4, 3);
 #endif
 #ifdef USE_TAPE
index 55387dd..310f25f 100644 (file)
@@ -90,20 +90,20 @@ static inline void _stprintf(char *s, const char *fmt, ...) {
 }\r
 \r
 // tchar.h\r
-#  ifdef  _UNICODE\r
-#    define __T(x)      L ## x\r
-#  else\r
+//#  ifdef  _UNICODE\r
+//#    define __T(x)      L ## x\r
+//#  else\r
 #    define __T(x)      x\r
-#  endif\r
+//#  endif\r
  \r
 #  define _T(x)       __T(x)\r
 #  define _TEXT(x)    __T(x)\r
 \r
-#  ifdef _UNICODE\r
-    typedef wchar_t _TCHAR;\r
-#  else\r
+//#  ifdef _UNICODE\r
+//    typedef wchar_t _TCHAR;\r
+//#  else\r
     typedef char    _TCHAR;\r
-#  endif\r
+//#  endif\r
 \r
 #  ifndef LPCTSTR\r
     typedef _TCHAR* LPCTSTR;\r
index 1329b7d..ad83fa1 100644 (file)
@@ -11,6 +11,7 @@
 #include <agar/core.h>\r
 #include <string>\r
 #include <vector>\r
+#include "fileio.h"\r
 #else\r
 #include <windows.h>\r
 #endif\r
@@ -20,6 +21,7 @@
 #include "common.h"\r
 #include "config.h"\r
 #include "fileio.h"\r
+#include "agar_main.h"\r
 \r
 config_t config;\r
 \r
@@ -29,75 +31,72 @@ config_t config;
 \r
 #if defined(_USE_AGAR)\r
 \r
-std::vector<std::string>config_data;\r
 \r
 \r
-bool WritePrivateProfileString(char *lpAppName, char *lpKeyName, char *Value, AG_DataSource *lpFileName)\r
+bool WritePrivateProfileString(char *lpAppName, char *lpKeyName, char *Value, FILEIO *lpFileName)\r
 {\r
    char s[129];\r
    snprintf(s, 128, "%s.%s=%s\n", lpAppName, lpKeyName, Value);\r
-   AG_WriteString(lpFileName, s);\r
+   //AG_WriteString(lpFileName, s);\r
+   lpFileName->Fwrite(s, strlen(s), 1);\r
    return true;\r
 }\r
 \r
-bool WritePrivateProfileInt(char *lpAppName, char *lpKeyName, int Value, AG_DataSource *lpFileName)\r
+bool WritePrivateProfileInt(char *lpAppName, char *lpKeyName, int Value, FILEIO *lpFileName)\r
 {\r
    char s[129];\r
    snprintf(s, 128, "%s.%s=%d\n", lpAppName, lpKeyName, Value);\r
-   AG_WriteString(lpFileName, s);\r
+   //AG_WriteString(lpFileName, s);\r
+   lpFileName->Fwrite(s, strlen(s), 1);\r
    return true;\r
 }\r
 \r
-BOOL WritePrivateProfileBool(char *lpAppName, char *lpKeyName, bool Value, AG_DataSource *lpFileName)\r
+BOOL WritePrivateProfileBool(char *lpAppName, char *lpKeyName, bool Value, FILEIO *lpFileName)\r
 {\r
        char String[129];\r
        snprintf(String, 128, "%s.%s=%d\n", lpAppName, lpKeyName, Value ? 1 : 0);\r
-        AG_WriteString(lpFileName, String);\r
+        lpFileName->Fwrite(String, strlen(String), 1);\r
+        //AG_WriteString(lpFileName, String);\r
         return true;\r
 }\r
-\r
-static int load_cfgfile(AG_DataSource *lpFileName)\r
-{\r
-   std::string sp;\r
-   char *s;\r
-   int i = 0;\r
-   config_data.clear();\r
-   do {\r
-      s = AG_ReadString(lpFileName);\r
-      if(s == NULL) break;\r
-      sp = s;\r
-      config_data.push_back(sp);\r
-      i++;\r
-   } while(1);\r
-   return i;\r
-}\r
-\r
-   \r
\r
 \r
 \r
-std::string GetPrivateProfileStr(char *lpAppName, char *lpKeyName, AG_DataSource *lpFileName)\r
+std::string GetPrivateProfileStr(char *lpAppName, char *lpKeyName, FILEIO *lpFileName)\r
 {\r
       char key[256];\r
+      char ibuf[256];\r
       int i;\r
+      int c;\r
       std::string::size_type  pos;\r
       std::string key_str;\r
-   \r
+      std::string got_str;\r
+  \r
       snprintf(key, 255, "%s.%s", lpAppName, lpKeyName);\r
+      printf("Try App: %s Key: %s\n", lpAppName, lpKeyName);\r
       key_str = key;\r
-      for(i = 0; i < config_data.size(); i++) {\r
-       pos = config_data[i].find(key_str);\r
-        if(pos == std::string::npos) continue;\r
-       // Found.\r
-       pos = config_data[i].find("=");\r
-        if(pos == std::string::npos) continue; \r
-       // Get Value\r
-        std::string val = config_data[i].substr(pos + 1);\r
-        return val;\r
+      ibuf[0] = '\0';\r
+      i = 0;\r
+      while(1) {\r
+       if(i > 254) break;\r
+       c = (char)lpFileName->Fgetc();\r
+       if(c == EOF) break;\r
+       if(c == '\n') break;\r
+       ibuf[i] = (char)c;\r
+       i++;\r
       }\r
-      return "";\r
+      ibuf[i] = '\0';\r
+      got_str = ibuf;\r
+      //printf("Got: %s %d chars.\n", got_str.c_str(), i);\r
+      key_str = key_str + "=";\r
+      pos = got_str.find(key_str);\r
+      if(pos == std::string::npos) return "";\r
+      got_str.erase(0, pos + key_str.length());\r
+      printf("Ok. Got %s = %s.\n", key, got_str.c_str());\r
+   return got_str;\r
 }\r
 \r
-void GetPrivateProfileString(char *section, char *key, char *defaultstr, char *str, int max_len, AG_DataSource *p)\r
+void GetPrivateProfileString(char *section, char *key, char *defaultstr, char *str, int max_len, FILEIO *p)\r
 {\r
    std::string sp = GetPrivateProfileStr(section, key, p);\r
    \r
@@ -109,7 +108,7 @@ void GetPrivateProfileString(char *section, char *key, char *defaultstr, char *s
    \r
 }\r
 \r
-int GetPrivateProfileInt(char *lpAppName, char *lpKeyName, int nDefault, AG_DataSource *lpFileName)\r
+int GetPrivateProfileInt(char *lpAppName, char *lpKeyName, int nDefault, FILEIO *lpFileName)\r
 {\r
    std::string s = GetPrivateProfileStr(lpAppName,lpKeyName, lpFileName);\r
    if(s == "") return nDefault;\r
@@ -118,7 +117,7 @@ int GetPrivateProfileInt(char *lpAppName, char *lpKeyName, int nDefault, AG_Data
 \r
 \r
 \r
-bool GetPrivateProfileBool(char *lpAppName, char *lpKeyName, bool bDefault, AG_DataSource *lpFileName)\r
+bool GetPrivateProfileBool(char *lpAppName, char *lpKeyName, bool bDefault, FILEIO *lpFileName)\r
 {\r
    \r
        return (GetPrivateProfileInt(lpAppName, lpKeyName, bDefault ? 1 : 0, lpFileName) != 0);\r
@@ -181,25 +180,25 @@ void init_config()
 \r
 void load_config()\r
 {\r
+   int drv, i;\r
        // initial settings\r
        init_config();\r
        \r
        // get config path\r
 \r
 #if defined(_USE_AGAR) || defined(_USE_SDL) \r
-       char app_path[_MAX_PATH], *ptr;\r
+       char app_path2[_MAX_PATH], *ptr;\r
         char cfgpath[_MAX_PATH];\r
-        AG_DataSource *config_path;\r
+        FILEIO *config_path = new FILEIO();\r
    \r
-        app_path[0] = '\0';\r
+        app_path2[0] = '\0';\r
         cfgpath[0] = '\0';\r
        //GetFullPathName(config_path, _MAX_PATH, app_path, &ptr);\r
-        \r
-       *ptr = _T('\0');\r
-       sprintf(cfgpath, _T("%s%s.ini"), app_path, _T(CONFIG_NAME));\r
-        config_path = AG_OpenFile(cfgpath, "r");\r
-        if(config_path == NULL) return;\r
-        load_cfgfile(config_path);\r
+        cpp_confdir.copy(app_path2, _MAX_PATH, 0);\r
+   \r
+        sprintf(cfgpath, _T("%s%s.ini"), app_path2, _T(CONFIG_NAME));\r
+        printf("Tray to read config: %s\n", cfgpath);\r
+        if(!config_path->Fopen(cfgpath, FILEIO_READ_ASCII)) return;\r
 #else\r
        _TCHAR app_path[_MAX_PATH], config_path[_MAX_PATH], *ptr;\r
        GetModuleFileName(NULL, config_path, _MAX_PATH);\r
@@ -233,39 +232,39 @@ void load_config()
        // recent files\r
 #ifdef USE_CART1\r
        GetPrivateProfileString(_T("RecentFiles"), _T("InitialCartDir"), _T(""), config.initial_cart_dir, _MAX_PATH, config_path);\r
-       for(int drv = 0; drv < MAX_CART; drv++) {\r
-               for(int i = 0; i < MAX_HISTORY; i++) {\r
+       for(drv = 0; drv < MAX_CART; drv++) {\r
+               for(i = 0; i < MAX_HISTORY; i++) {\r
                        _TCHAR name[64];\r
-                       _stprintf(name, _T("RecentCartPath%d_%d"), drv + 1, i + 1);\r
+                       sprintf(name, _T("RecentCartPath%d_%d"), drv + 1, i + 1);\r
                        GetPrivateProfileString(_T("RecentFiles"), name, _T(""), config.recent_cart_path[drv][i], _MAX_PATH, config_path);\r
                }\r
        }\r
 #endif\r
 #ifdef USE_FD1\r
        GetPrivateProfileString(_T("RecentFiles"), _T("InitialDiskDir"), _T(""), config.initial_disk_dir, _MAX_PATH, config_path);\r
-       for(int drv = 0; drv < MAX_FD; drv++) {\r
-               for(int i = 0; i < MAX_HISTORY; i++) {\r
+       for(drv = 0; drv < MAX_FD; drv++) {\r
+               for(i = 0; i < MAX_HISTORY; i++) {\r
                        _TCHAR name[64];\r
-                       _stprintf(name, _T("RecentDiskPath%d_%d"), drv + 1, i + 1);\r
+                       sprintf(name, _T("RecentDiskPath%d_%d"), drv + 1, i + 1);\r
                        GetPrivateProfileString(_T("RecentFiles"), name, _T(""), config.recent_disk_path[drv][i], _MAX_PATH, config_path);\r
                }\r
        }\r
 #endif\r
 #ifdef USE_QD1\r
        GetPrivateProfileString(_T("RecentFiles"), _T("InitialQuickDiskDir"), _T(""), config.initial_quickdisk_dir, _MAX_PATH, config_path);\r
-       for(int drv = 0; drv < MAX_QD; drv++) {\r
-               for(int i = 0; i < MAX_HISTORY; i++) {\r
+       for(drv = 0; drv < MAX_QD; drv++) {\r
+               for(i = 0; i < MAX_HISTORY; i++) {\r
                        _TCHAR name[64];\r
-                       _stprintf(name, _T("RecentQuickDiskPath%d_%d"), drv + 1, i + 1);\r
+                       sprintf(name, _T("RecentQuickDiskPath%d_%d"), drv + 1, i + 1);\r
                        GetPrivateProfileString(_T("RecentFiles"), name, _T(""), config.recent_quickdisk_path[drv][i], _MAX_PATH, config_path);\r
                }\r
        }\r
 #endif\r
 #ifdef USE_TAPE\r
        GetPrivateProfileString(_T("RecentFiles"), _T("InitialTapeDir"), _T(""), config.initial_tape_dir, _MAX_PATH, config_path);\r
-       for(int i = 0; i < MAX_HISTORY; i++) {\r
+       for(i = 0; i < MAX_HISTORY; i++) {\r
                _TCHAR name[64];\r
-               _stprintf(name, _T("RecentTapePath1_%d"), i + 1);\r
+               sprintf(name, _T("RecentTapePath1_%d"), i + 1);\r
                GetPrivateProfileString(_T("RecentFiles"), name, _T(""), config.recent_tape_path[i], _MAX_PATH, config_path);\r
        }\r
 #endif\r
@@ -273,16 +272,16 @@ void load_config()
        GetPrivateProfileString(_T("RecentFiles"), _T("InitialLaserDiscDir"), _T(""), config.initial_laser_disc_dir, _MAX_PATH, config_path);\r
        for(int i = 0; i < MAX_HISTORY; i++) {\r
                _TCHAR name[64];\r
-               _stprintf(name, _T("RecentLaserDiscPath1_%d"), i + 1);\r
+               sprintf(name, _T("RecentLaserDiscPath1_%d"), i + 1);\r
                GetPrivateProfileString(_T("RecentFiles"), name, _T(""), config.recent_laser_disc_path[i], _MAX_PATH, config_path);\r
        }\r
 #endif\r
 #ifdef USE_BINARY_FILE1\r
        GetPrivateProfileString(_T("RecentFiles"), _T("InitialBinaryDir"), _T(""), config.initial_binary_dir, _MAX_PATH, config_path);\r
-       for(int drv = 0; drv < MAX_BINARY; drv++) {\r
-               for(int i = 0; i < MAX_HISTORY; i++) {\r
+       for(drv = 0; drv < MAX_BINARY; drv++) {\r
+               for(i = 0; i < MAX_HISTORY; i++) {\r
                        _TCHAR name[64];\r
-                       _stprintf(name, _T("RecentBinaryPath%d_%d"), drv + 1, i + 1);\r
+                       sprintf(name, _T("RecentBinaryPath%d_%d"), drv + 1, i + 1);\r
                        GetPrivateProfileString(_T("RecentFiles"), name, _T(""), config.recent_binary_path[drv][i], _MAX_PATH, config_path);\r
                }\r
        }\r
@@ -314,27 +313,32 @@ void load_config()
        GetPrivateProfileString(_T("Sound"), _T("FMGenDll"), _T("mamefm.dll"), config.fmgen_dll_path, _MAX_PATH, config_path);\r
 \r
 #if defined(_USE_AGAR) || (_USE_SDL)\r
-        AG_CloseDataSource(config_path);\r
+     config_path->Fclose();\r
+     delete config_path;\r
 #endif\r
 }\r
 \r
 void save_config()\r
 {\r
+   int drv, i;\r
+\r
        // get config path\r
 #if defined(_USE_AGAR) || defined(_USE_SDL)\r
-\r
-       char app_path[_MAX_PATH], *ptr;\r
+       char app_path2[_MAX_PATH], *ptr;\r
         char cfgpath[_MAX_PATH];\r
-        AG_DataSource *config_path;\r
+        FILEIO *config_path = new FILEIO();\r
    \r
-        app_path[0] = '\0';\r
+        app_path2[0] = '\0';\r
         cfgpath[0] = '\0';\r
        //GetFullPathName(config_path, _MAX_PATH, app_path, &ptr);\r
-        \r
-       *ptr = _T('\0');\r
-       sprintf(cfgpath, _T("%s%s.ini"), app_path, _T(CONFIG_NAME));\r
-        config_path = AG_OpenFile(cfgpath, "w");\r
-        if(config_path == NULL) return;\r
+        cpp_confdir.copy(app_path2, _MAX_PATH, 0);\r
+   \r
+        sprintf(cfgpath, _T("%s%s.ini"), app_path2, _T(CONFIG_NAME));\r
+        printf("Tray to write config: %s\n", cfgpath);\r
+\r
+        if(config_path->Fopen(cfgpath, FILEIO_WRITE_ASCII) != true) return;\r
+        printf("OK.\n");\r
+\r
 #else\r
         _TCHAR app_path[_MAX_PATH], config_path[_MAX_PATH], *ptr;\r
        GetModuleFileName(NULL, config_path, _MAX_PATH);\r
@@ -343,7 +347,8 @@ void save_config()
        _stprintf(config_path, _T("%s%s.ini"), app_path, _T(CONFIG_NAME));\r
 #endif \r
        // control\r
-#ifdef USE_BOOT_MODE\r
+\r
+# ifdef USE_BOOT_MODE\r
        WritePrivateProfileInt(_T("Control"), _T("BootMode"), config.boot_mode, config_path);\r
 #endif\r
 #ifdef USE_CPU_TYPE\r
@@ -366,39 +371,39 @@ void save_config()
        // recent files\r
 #ifdef USE_CART1\r
        WritePrivateProfileString(_T("RecentFiles"), _T("InitialCartDir"), config.initial_cart_dir, config_path);\r
-       for(int drv = 0; drv < MAX_CART; drv++) {\r
-               for(int i = 0; i < MAX_HISTORY; i++) {\r
+       for(drv = 0; drv < MAX_CART; drv++) {\r
+               for(i = 0; i < MAX_HISTORY; i++) {\r
                        _TCHAR name[64];\r
-                       _stprintf(name, _T("RecentCartPath%d_%d"), drv + 1, i + 1);\r
+                       sprintf(name, _T("RecentCartPath%d_%d"), drv + 1, i + 1);\r
                        WritePrivateProfileString(_T("RecentFiles"), name, config.recent_cart_path[drv][i], config_path);\r
                }\r
        }\r
 #endif\r
 #ifdef USE_FD1\r
        WritePrivateProfileString(_T("RecentFiles"), _T("InitialDiskDir"), config.initial_disk_dir, config_path);\r
-       for(int drv = 0; drv < MAX_FD; drv++) {\r
-               for(int i = 0; i < MAX_HISTORY; i++) {\r
+       for(drv = 0; drv < MAX_FD; drv++) {\r
+               for(i = 0; i < MAX_HISTORY; i++) {\r
                        _TCHAR name[64];\r
-                       _stprintf(name, _T("RecentDiskPath%d_%d"), drv + 1, i + 1);\r
+                       sprintf(name, _T("RecentDiskPath%d_%d"), drv + 1, i + 1);\r
                        WritePrivateProfileString(_T("RecentFiles"), name, config.recent_disk_path[drv][i], config_path);\r
                }\r
        }\r
 #endif\r
 #ifdef USE_QD1\r
        WritePrivateProfileString(_T("RecentFiles"), _T("InitialQuickDiskDir"), config.initial_quickdisk_dir, config_path);\r
-       for(int drv = 0; drv < MAX_QD; drv++) {\r
-               for(int i = 0; i < MAX_HISTORY; i++) {\r
+       for(drv = 0; drv < MAX_QD; drv++) {\r
+               for(i = 0; i < MAX_HISTORY; i++) {\r
                        _TCHAR name[64];\r
-                       _stprintf(name, _T("RecentQuickDiskPath%d_%d"), drv + 1, i + 1);\r
+                       sprintf(name, _T("RecentQuickDiskPath%d_%d"), drv + 1, i + 1);\r
                        WritePrivateProfileString(_T("RecentFiles"), name, config.recent_quickdisk_path[drv][i], config_path);\r
                }\r
        }\r
 #endif\r
 #ifdef USE_TAPE\r
        WritePrivateProfileString(_T("RecentFiles"), _T("InitialTapeDir"), config.initial_tape_dir, config_path);\r
-       for(int i = 0; i < MAX_HISTORY; i++) {\r
+       for(i = 0; i < MAX_HISTORY; i++) {\r
                _TCHAR name[64];\r
-               _stprintf(name, _T("RecentTapePath1_%d"), i + 1);\r
+               sprintf(name, _T("RecentTapePath1_%d"), i + 1);\r
                WritePrivateProfileString(_T("RecentFiles"), name, config.recent_tape_path[i], config_path);\r
        }\r
 #endif\r
@@ -406,16 +411,16 @@ void save_config()
        WritePrivateProfileString(_T("RecentFiles"), _T("InitialLaserDiscDir"), config.initial_laser_disc_dir, config_path);\r
        for(int i = 0; i < MAX_HISTORY; i++) {\r
                _TCHAR name[64];\r
-               _stprintf(name, _T("RecentLaserDiscPath1_%d"), i + 1);\r
+               sprintf(name, _T("RecentLaserDiscPath1_%d"), i + 1);\r
                WritePrivateProfileString(_T("RecentFiles"), name, config.recent_laser_disc_path[i], config_path);\r
        }\r
 #endif\r
 #ifdef USE_BINARY_FILE1\r
        WritePrivateProfileString(_T("RecentFiles"), _T("InitialBinaryDir"), config.initial_binary_dir, config_path);\r
-       for(int drv = 0; drv < MAX_BINARY; drv++) {\r
-               for(int i = 0; i < MAX_HISTORY; i++) {\r
+       for(drv = 0; drv < MAX_BINARY; drv++) {\r
+               for(i = 0; i < MAX_HISTORY; i++) {\r
                        _TCHAR name[64];\r
-                       _stprintf(name, _T("RecentBinaryPath%d_%d"), drv + 1, i + 1);\r
+                       sprintf(name, _T("RecentBinaryPath%d_%d"), drv + 1, i + 1);\r
                        WritePrivateProfileString(_T("RecentFiles"), name, config.recent_binary_path[drv][i], config_path);\r
                }\r
        }\r
@@ -445,7 +450,8 @@ void save_config()
        WritePrivateProfileInt(_T("Sound"), _T("DeviceType"), config.sound_device_type, config_path);\r
 #endif\r
 #if defined(_USE_AGAR) || (_USE_SDL)\r
-        AG_CloseDataSource(config_path);\r
+        config_path->Fclose();\r
+        delete config_path;\r
 #endif\r
 \r
 }\r
index 61ae188..f9d52f9 100644 (file)
@@ -48,7 +48,8 @@ EMU::EMU(HWND hwnd, HINSTANCE hinst)
         std::string tmps;\r
        _TCHAR tmp_path[AG_PATHNAME_MAX], *ptr;\r
         my_procname.copy(tmp_path, AG_PATHNAME_MAX, 0);\r
-        get_long_full_path_name(app_path, tmp_path);\r
+        get_long_full_path_name(tmp_path, app_path);\r
+        printf("APPPATH=%s\n", app_path);\r
 #else\r
        _TCHAR tmp_path[_MAX_PATH], *ptr;\r
         GetModuleFileName(NULL, tmp_path, _MAX_PATH);\r
@@ -138,6 +139,7 @@ EMU::~EMU()
 \r
 int EMU::frame_interval()\r
 {\r
+#if 0\r
 #ifdef SUPPORT_VARIABLE_TIMING\r
        static int prev_interval = 0;\r
        static double prev_fps = -1;\r
@@ -150,6 +152,9 @@ int EMU::frame_interval()
 #else\r
        return (int)(1024. * 1000. / FRAMES_PER_SEC + 0.5);\r
 #endif\r
+#else\r
+        return (int)(1024. * 1000. / FRAMES_PER_SEC + 0.5);\r
+#endif\r
 }\r
 \r
 int EMU::run()\r
@@ -177,6 +182,7 @@ int EMU::run()
        // drive virtual machine\r
        if(extra_frames == 0) {\r
                vm->run();\r
+//             printf("VM:RUN() %d\n", AG_GetTicks());\r
                extra_frames = 1;\r
        }\r
        rec_video_run_frames += extra_frames;\r
@@ -250,8 +256,16 @@ void EMU::notify_power_off()
 \r
 _TCHAR* EMU::bios_path(_TCHAR* file_name)\r
 {\r
-       static _TCHAR file_path[_MAX_PATH];\r
+#if defined(_USE_AGAR) || defined(_USE_SDL)\r
+        static _TCHAR file_path[_MAX_PATH];\r
+        strcpy(file_path, app_path);\r
+        strcat(file_path, file_name);\r
+        printf("LOAD: %s\n", file_path);\r
+#else\r
+        static _TCHAR file_path[_MAX_PATH];\r
        _stprintf(file_path, _T("%s%s"), app_path, file_name);\r
+        printf("LOAD: %s\n", file_path);\r
+#endif\r
        return file_path;\r
 }\r
 \r
index e493e06..7f38e19 100644 (file)
@@ -320,9 +320,11 @@ private:
        bool render_to_SDLFB;\r
        bool use_GL;\r
         bool use_SDLFB;\r
+        bool render_with_OpenCL;\r
         bool single_window;\r
        bool wait_vsync;\r
-       \r
+       Uint32 *pPseudoVram;\r
+\r
        // record video\r
        _TCHAR video_file_name[AG_PATHNAME_MAX];\r
        int rec_video_fps;\r
@@ -419,7 +421,8 @@ private:
        double rec_video_frames;\r
 #endif \r
        \r
-#if !defined(_USE_AGAR) && !defined(_USE_SDL)\r
+#if defined(_USE_AGAR) || defined(_USE_SDL)\r
+#else\r
        LPBITMAPINFO lpDibRec;\r
        PAVIFILE pAVIFile;\r
        PAVISTREAM pAVIStream;\r
@@ -632,13 +635,14 @@ private:
        bool now_suspended;\r
        \r
 public:\r
+        bool bDrawLine[SCREEN_HEIGHT];\r
        // ----------------------------------------\r
        // initialize\r
        // ----------------------------------------\r
-#if !defined(_USE_AGAR) && !defined(_USE_SDL)\r
-       EMU(HWND hwnd, HINSTANCE hinst);\r
-#else\r
+#if defined(_USE_AGAR) || defined(_USE_SDL)\r
        EMU(AG_Window *hwnd, AG_Widget *hinst);\r
+#else\r
+       EMU(HWND hwnd, HINSTANCE hinst);\r
 #endif\r
         ~EMU();\r
        \r
@@ -838,9 +842,9 @@ public:
        // power off\r
        void power_off()\r
        {\r
-#if !defined(_USE_AGAR) && !defined(_USE_SDL)\r
-               PostMessage(main_window_handle, WM_CLOSE, 0, 0L);\r
+#if defined(_USE_AGAR) || defined(_USE_SDL)\r
 #else\r
+               PostMessage(main_window_handle, WM_CLOSE, 0, 0L);\r
 #endif\r
        }\r
        \r