# 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
)
--- /dev/null
+/*
+ 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
+
--- /dev/null
+/*
+ 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
/*\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
#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
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
\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
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
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
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
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
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
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
} 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
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
\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
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
#include "common.h"
#include "emu.h"
+extern "C"
+{
+ void AGAR_SDLViewUpdateSrc(AG_Event *event);
+}
extern EMU* emu;
#ifdef USE_BUTTON
--- /dev/null
+/*
+ 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
+}
+
static int iOldH = 0;
// Temporally entry. Please re-implement.
-BOOL bDrawLine[800];
extern "C" {
AG_Surface *GetDrawSurface(void)
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){
}
-
+extern "C" {
+
void AGAR_SDLViewUpdateSrc(AG_Event *event)
{
AGAR_SDLView *my = (AGAR_SDLView *)AG_SELF();
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;
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 {
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;
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;
UnlockVram();
return;
}
+}
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];
// 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;
}
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))) {
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);
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
}\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
#include <agar/core.h>\r
#include <string>\r
#include <vector>\r
+#include "fileio.h"\r
#else\r
#include <windows.h>\r
#endif\r
#include "common.h"\r
#include "config.h"\r
#include "fileio.h"\r
+#include "agar_main.h"\r
\r
config_t config;\r
\r
\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
\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
\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
\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
// 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
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
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
_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
// 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
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
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
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
\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
#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
// 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
\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
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
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
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
// 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