// beebwin.cpp // NRM's port to win32 #include #include #include #include "main.h" #include "beebwin.h" #include "port.h" #include "6502core.h" #include "disc8271.h" #include "sysvia.h" void start_dd(HWND hwnd); void blit_dd(int x0,int y0); char DebString[512]; int OurError(char *where, HRESULT errval); LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); int TranslateKey(int, int *, int *); HWND sshwnd; // Row,Col static int transTable[256][2]={ 0,0, 0,0, 0,0, 0,0, // 0 0,0, 0,0, 0,0, 0,0, // 4 5,9, 6,0, 0,0, 0,0, // 8 [BS][TAB].. 0,0, 4,9, 0,0, 0,0, // 12 .RET.. 0,0, 0,1, 0,0, -2,-2, // 16 .CTRL.BREAK 4,0, 0,0, 0,0, 0,0, // 20 CAPS... 0,0, 0,0, 0,0, 7,0, // 24 ...ESC 0,0, 0,0, 0,0, 0,0, // 28 6,2, 0,0, 0,0, 6,9, // 32 SPACE..[End] 0,0, 1,9, 3,9, 7,9, // 36 .[Left][Up][Right] 2,9, 0,0, 4,1, 0,0, // 40 [Down]... //4,1 0,0, 0,0, 5,9, 0,0, // 44 ..[DEL]. 2,7, 3,0, 3,1, 1,1, // 48 0123 1,2, 1,3, 3,4, 2,4, // 52 4567 1,5, 2,6, 0,0, 0,0, // 56 89 0,0, 0,0, 0,0, 0,0, // 60 0,0, 4,1, 6,4, 5,2, // 64.. ABC 3,2, 2,2, 4,3, 5,3, // 68 DEFG 5,4, 2,5, 4,5, 4,6, // 72 HIJK 5,6, 6,5, 5,5, 3,6, // 76 LMNO 3,7, 1,0, 3,3, 5,1, // 80 PQRS 2,3, 3,5, 6,3, 2,1, // 84 TUVW 4,2, 4,4, 6,1, 0,0, // 88 XYZ 0,0, 0,0, 0,0, 0,0, // 92 0,0, 0,0, 0,0, 0,0, // 96 0,0, 0,0, 0,0, 0,0, // 100 0,0, 0,0, 0,0, 0,0, // 104 0,0, 0,0, 0,0, 0,0, // 108 7,1, 7,2, 7,3, 1,4, // 112 F1 F2 F3 F4 7,4, 7,5, 1,6, 7,6, // 116 F5 F6 F7 F8 7,7, 2,0, 2,0, -2,-2, // 120 F9 F10 F11 F12 0,0, 0,0, 0,0, 0,0, // 124 0,0, 0,0, 0,0, 0,0, // 128 0,0, 0,0, 0,0, 0,0, // 132 0,0, 0,0, 0,0, 0,0, // 136 0,0, 0,0, 0,0, 0,0, // 140 0,0, 0,0, 0,0, 0,0, // 144 0,0, 0,0, 0,0, 0,0, // 148 0,0, 0,0, 0,0, 0,0, // 152 0,0, 0,0, 0,0, 0,0, // 156 0,0, 0,0, 0,0, 0,0, // 160 0,0, 0,0, 0,0, 0,0, // 164 0,0, 0,0, 0,0, 0,0, // 168 0,0, 0,0, 0,0, 0,0, // 172 0,0, 0,0, 0,0, 0,0, // 176 0,0, 0,0, 0,0, 0,0, // 180 0,0, 0,0, 5,7, 1,8, // 184 ..;= 6,6, 1,7, 6,7, 6,8, // 188 ,-./ 4,8, 0,0, 0,0, 0,0, // 192 @ ... 0,0, 0,0, 0,0, 0,0, // 196 0,0, 0,0, 0,0, 0,0, // 200 0,0, 0,0, 0,0, 0,0, // 204 0,0, 0,0, 0,0, 0,0, // 208 0,0, 0,0, 0,0, 0,0, // 212 0,0, 0,0, 0,0, 3,8, // 216 ...[ 7,8, 5,8, 2,8, 0,0, // 220 .][#~]. 0,0, 0,0, 0,0, 0,0, // 224 0,0, 0,0, 0,0, 0,0, // 228 0,0, 0,0, 0,0, 0,0, // 232 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 }; char dummy[4*320*256*2]; BeebWin::BeebWin() { for(int i=0;i<8;i++) // cols[i] = 20+i; // Initialise BEEB Colours; make this =i cols[i]=i; // if you aren't using wing (hence no palettes) // m_screen = beebdisplay.m_bitmapbits; // Take a copy of the pointer to the screen m_screen=(char *)&dummy; InitClass(); CreateBeebWindow(); m_hDC = GetDC(m_hWnd); } BeebWin::~BeebWin() { ReleaseDC(m_hWnd, m_hDC); } char * BeebWin::imageData() { return m_screen; } int BeebWin::bytesPerLine() const { return 320; } void BeebWin::updateLines(int starty, int nlines) { HDC hDC; POINT pt; RECT rect; //hDC = GetDC(m_hWnd); /// beebdisplay.Blit(m_hDC, starty, nlines); GetClientRect( m_hWnd, &rect ); // rectangle of current screen pt.x=rect.left; pt.y=rect.top; ClientToScreen( m_hWnd, &pt ); blit_dd(pt.x,pt.y); //ReleaseDC(m_hWnd,hDC); } EightUChars * BeebWin::GetLinePtr(int y) { if(y > 255) y=255; return((EightUChars *)(m_screen + ( y * bytesPerLine() )) ); } SixteenUChars * BeebWin::GetLinePtr16(int y) { if(y > 255) y=255; return((SixteenUChars *)(m_screen + ( y * bytesPerLine() )) ); } BOOL BeebWin::InitClass(void) { WNDCLASS wc; // Fill in window class structure with parameters that describe the // main window. wc.style = CS_HREDRAW | CS_VREDRAW;// Class style(s). wc.lpfnWndProc = (WNDPROC)WndProc; // Window Procedure wc.cbClsExtra = 0; // No per-class extra data. wc.cbWndExtra = 0; // No per-window extra data. wc.hInstance = hInst; // Owner of this class wc.hIcon = NULL; //LoadIcon (hInstance, MAKEINTRESOURCE(IDI_APP)); // Icon name from .RC wc.hCursor = LoadCursor(NULL, IDC_ARROW);// Cursor wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);// Default color wc.lpszMenuName = NULL; //MAKEINTRESOURCE(IDR_GENERIC); // Menu from .RC wc.lpszClassName = "BEEBWIN"; //szAppName; // Name to register as // Register the window class and return success/failure code. return (RegisterClass(&wc)); } void BeebWin::CreateBeebWindow(void) { m_hWnd = CreateWindow( "BEEBWIN", // See RegisterClass() call. "BBC Emulator", // Text for window title bar. WS_OVERLAPPED| WS_CAPTION| WS_SYSMENU| WS_MINIMIZEBOX, // Window style. CW_USEDEFAULT, 0, // Use default positioning 2*326, 2*261+1+GetSystemMetrics(SM_CYCAPTION) , NULL, // Overlapped windows have no parent. NULL, // Use the window class menu. hInst, // This instance owns this window. NULL // We don't use any data in our WM_CREATE ); sshwnd=m_hWnd; ShowWindow(m_hWnd, SW_SHOW); // Show the window UpdateWindow(m_hWnd); // Sends WM_PAINT message start_dd(m_hWnd); } LRESULT CALLBACK WndProc( HWND hWnd, // window handle UINT message, // type of message WPARAM uParam, // additional information LPARAM lParam) // additional information { FARPROC lpProcAbout; // pointer to the "About" function int wmId, wmEvent; HDC hdc; UINT f; switch (message) { int row, col; case WM_COMMAND: // message: command from application menu wmId = LOWORD(uParam); wmEvent = HIWORD(uParam); break; case WM_PALETTECHANGED: if(!mainWin) break; if ((HWND)uParam == hWnd) break; // fall through to WM_QUERYNEWPALETTE case WM_QUERYNEWPALETTE: if(!mainWin) break; hdc = GetDC(hWnd); // mainWin->beebdisplay.RealizePalette(hdc); ReleaseDC(hWnd,hdc); return TRUE; break; case WM_PAINT: if(mainWin != NULL) { PAINTSTRUCT ps; HDC hDC, hDCScreen; hDC = BeginPaint(hWnd, &ps); /// mainWin->beebdisplay.RealizePalette(hDC); /// mainWin->beebdisplay.Blit(hDC, 0, 256); // GetClientRect( m_hWnd, &rect ); // rectangle of current screen // pt.x=rect.left; // pt.y=rect.top; // ClientToScreen( m_hWnd, &pt ); // blit_dd(pt.x,pt.y); blit_dd(100,100); EndPaint(hWnd, &ps); } break; case WM_KEYDOWN: ; if(TranslateKey(uParam, &row, &col)>=0) BeebKeyDown(row, col); break; case WM_KEYUP: if(TranslateKey(uParam,&row, &col)>=0) BeebKeyUp(row, col); else if(row==-2) { // Must do a reset! Init6502core(); Disc8271_reset(); } break; case WM_DESTROY: // message: window being destroyed PostQuitMessage(0); break; default: // Passes it on if unproccessed return (DefWindowProc(hWnd, message, uParam, lParam)); } return (0); } int TranslateKey(int vkey, int *row, int *col) { row[0] = transTable[vkey][0]; col[0] = transTable[vkey][1]; return(row[0]); } LPDIRECTDRAW lpDD; // DirectDraw object LPDIRECTDRAWSURFACE lpDDSPrimary; // DirectDraw primary surface void start_dd(HWND hwnd) { DDSURFACEDESC ddsd; DDSCAPS ddscaps; DDCAPS ddcaps; DDCAPS ddcaps2; HRESULT ddrval; ddrval = DirectDrawCreate( NULL, &lpDD, NULL ); OurError("dd create",ddrval); ddrval = lpDD->SetCooperativeLevel(hwnd, DDSCL_NORMAL ); // cooperate with windows OurError("SetCooperativelevel",ddrval); ddsd.dwSize = sizeof( ddsd ); ddsd.dwFlags = DDSD_CAPS ; ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE; ddrval = lpDD->CreateSurface(&ddsd, &lpDDSPrimary, NULL ); OurError("CreateSurface",ddrval); // lpDDSPrimary->GetSurfaceDesc(&ddsd); //get primary info } #define XSIZE 320 #define YSIZE 256 #define RED (31<<11) #define GREEN (63<<5) #define BLUE 31 short pal565[8]= { 0, RED, // red 1 GREEN, // green 2 RED+GREEN, // yellow 3 BLUE, // blue 4 BLUE+RED, // magneta 5 BLUE+GREEN, // cyan 6 0xffff // white }; void blit_dd(int x0,int y0) { int loop, loop2; short *out_ptr; DDSURFACEDESC ddsd; int i,j,height; short *one; char *chsrc; short b; short *shdest; char a; HRESULT ddrval; POINT pt; RECT rect; //return; GetClientRect( sshwnd, &rect ); // rectangle of current screen pt.x=rect.left; pt.y=rect.top; ClientToScreen( sshwnd, &pt ); x0=pt.x; y0=pt.y; ZeroMemory(&ddsd, sizeof(ddsd)); ddsd.dwSize = sizeof(ddsd); ddrval=lpDDSPrimary->Lock(NULL, &ddsd, DDLOCK_SURFACEMEMORYPTR, NULL); OurError("lock",ddrval); one = (short *)((long)(ddsd.lpSurface)); one=one+x0+1024*y0; shdest=(short *)one; chsrc=(char *)&dummy; for(i=0;iUnlock(ddsd.lpSurface); OurError("unlock",ddrval); } //#include //#include #include //#include //#include void DebFile(char *string) { FILE *fred; static int thing = 0; return; if(!thing) fred = fopen("debug.txt","w"); else fred = fopen("debug.txt","a"); thing++; fseek(fred,0,SEEK_END); fprintf(fred,"%s\n",string); fclose(fred); } int OurError(char *where, HRESULT errval) { switch(errval) { case DD_OK: #if 1 sprintf(DebString,"DD_OK in %s", where); DebFile(DebString); #endif return(0); break; case DDERR_INVALIDOBJECT: sprintf(DebString,"Object handle duff in %s", where); break; case DDERR_INVALIDPARAMS: sprintf(DebString,"Invalid parms in %s", where); break; case DDERR_EXCLUSIVEMODEALREADYSET: sprintf(DebString,"Someone else is in DD Exclusive in %s", where); break; case DDERR_OUTOFMEMORY: sprintf(DebString,"Out of memory in %s", where); break; case DDERR_HWNDALREADYSET: sprintf(DebString,"The Hwnd is already in DD in %s", where); break; case DDERR_HWNDSUBCLASSED: sprintf(DebString,"HWND has been subclassed in %s", where); break; case DDERR_SURFACEBUSY: sprintf(DebString,"Surface referenced was busy in %s", where); break; case DDERR_SURFACELOST: sprintf(DebString,"Surface referenced has been lost in %s", where); break; case DDERR_WASSTILLDRAWING: sprintf(DebString,"Surface was still drawing in %s", where); break; case DDERR_GENERIC: sprintf(DebString,"Generic error in %s", where); break; case DDERR_NOTLOCKED: sprintf(DebString,"Surface was not locked in %s", where); break; default: sprintf(DebString,"UNKNOWN value %d in %s",(errval & 0x3ff), where); break; }; DebFile(DebString); return(1); }