Main Page   Data Structures   File List   Data Fields   Globals   Related Pages  

videodll.c

Go to the documentation of this file.
00001 
00012 #include "../dllkit/dllkit.h"
00013 #include "../usrmsgs.h"
00014 #include "resource.h"
00015 #include <stdio.h>
00016 #include <tchar.h>
00017 
00021 #define MYTIMER 10001 
00022 
00023 #define PERIOD 50
00024 
00029 #define FWIDTH 8
00030 
00031 #define FHEIGHT 8
00032 
00033 #define YCOUNT 32
00034 
00035 #define XCOUNT 32
00036 
00037 #define WIDTH FWIDTH * XCOUNT
00038 
00039 #define HEIGHT FHEIGHT * YCOUNT
00040 
00044 #define GRMODE IOLO + 0
00045 #define LOADR IOLO + 1
00046 #define HIADR IOLO + 2
00047 #define LOCHR IOLO + 3
00048 #define HICHR IOLO + 4
00049 #define FGCOLR IOLO + 5
00050 #define FGCOLG IOLO + 6
00051 #define FGCOLB IOLO + 7
00052 #define BKCOLR IOLO + 8
00053 #define BKCOLG IOLO + 9
00054 #define BKCOLB IOLO + 10
00055 #define VIDEOON IOLO + 14
00056 #define COMMAND IOLO + 15
00057 
00061 unsigned char volatile _GrMode = 0;
00062 unsigned char volatile _LoAdr = 0x00;
00063 unsigned char volatile _HiAdr = 0xA0;
00064 unsigned char volatile _LoChr = 0x00;
00065 unsigned char volatile _HiChr = 0xC0;
00066 unsigned char volatile _BkColR = 0xFF;
00067 unsigned char volatile _BkColG = 0xFF;
00068 unsigned char volatile _BkColB = 0xFF;
00069 unsigned char volatile _FgColR = 0x00;
00070 unsigned char volatile _FgColG = 0x00;
00071 unsigned char volatile _FgColB = 0x00;
00072 /* */
00073 unsigned char volatile GrMode = 0;
00074 unsigned char volatile LoAdr = 0x00;
00075 unsigned char volatile HiAdr = 0xA0;
00076 unsigned char volatile LoChr = 0x00;
00077 unsigned char volatile HiChr = 0xC0;
00078 unsigned char volatile VideoOn = 0;
00081 #define ADR(X, Y) (((X) << 8) + (Y))
00082 
00085 UINT memStart = 0xA000;
00087 UINT memChrStart = 0xC000;
00088 
00089 
00091 struct b4iheader {
00092         BITMAPV4HEADER bmiHeader; 
00093         RGBQUAD bmiColors[2];
00094 } bGrInfo;
00095 
00097 char* OffScreen;
00098 
00100 HBITMAP hLogo;
00102 HDC hOffDC;
00103 
00104 
00107 HANDLE hThisModule;
00108 MSGLIST VideoMsgs;
00109 volatile BOOL Running = FALSE;
00110 INITDLLSTRUCT info;
00114 /* ----- begin forward declarations */
00115 
00117 void InitGraphics();
00118 
00120 VOID CALLBACK TimerProc(HWND hwnd, UINT uMsg, UINT idEvent, DWORD dwTime);
00121 
00123 void Repaint();
00124 
00134 void PaintScreen(HDC hdc); 
00135 
00148 void CopyChar(char* dest, UINT adr, int x, int y, BOOL invert);
00149 
00150 /* ----- end forward declarations */
00151 
00152 BOOL APIENTRY DllMain(HANDLE hModule, DWORD  ul_reason_for_call, 
00153                                           LPVOID lpReserved)
00154 {
00155         hThisModule = hModule;
00156         switch (ul_reason_for_call) {
00157         case DLL_PROCESS_ATTACH:
00158                 CreateMsgList(&VideoMsgs, 4);
00159                 OffScreen = malloc(WIDTH * HEIGHT * sizeof(char) / 8);
00160                 hLogo = LoadBitmap(hThisModule, MAKEINTRESOURCE(IDB_LOGO));
00161                 VideoOn = FALSE;
00162                 break;
00163         case DLL_PROCESS_DETACH:
00164                 Running = FALSE;
00165                 KillTimer(info.hWnd, MYTIMER);
00166                 DeleteObject(hLogo);
00167                 DeleteDC(hOffDC);
00168                 free(OffScreen);
00170                 break;
00171         }       
00172     return TRUE;
00173 }
00174 
00175 DLLEXPORT void __cdecl InitDll(INITDLLSTRUCT* ids, INITDLLINFO* idi)
00176 {
00177         /* Add Message list of messages to be catched */
00178         AddMessage(VideoMsgs, WM_PAINT);
00179         AddMessage(VideoMsgs, CPURUNNING);
00180         AddMessage(VideoMsgs, CPUSTOPPED);
00181         AddMessage(VideoMsgs, STOPVIDEO);
00182 
00183         /* Copy informations passed to this dll */
00184         info.CSMemory = ids->CSMemory;
00185         info.hInst = ids->hInst;
00186         info.hWnd = ids->hWnd;
00187         info.memory = ids->memory;
00188         info.memgetb = ids->memgetb;
00189         info.memsetb = ids->memsetb;
00190         info.optional = ids->optional;
00191         info.rcPaint = ids->rcPaint;
00192 
00193         /* Initialize graphics settings */
00194 
00195         InitGraphics();
00196 
00197         idi->iolo = IOLO + 0;
00198         idi->iohi = IOLO + 20;
00199         idi->msglist = VideoMsgs;
00200 }
00201 
00202 
00203 void InitGraphics()
00204 {
00205         bGrInfo.bmiHeader.bV4Size = sizeof(bGrInfo.bmiHeader);
00206         bGrInfo.bmiHeader.bV4Width = WIDTH;
00207         bGrInfo.bmiHeader.bV4Height = -HEIGHT;  //Nohama na zemi
00208         bGrInfo.bmiHeader.bV4Planes = 1;
00209         bGrInfo.bmiHeader.bV4BitCount = 1;
00210         bGrInfo.bmiHeader.bV4V4Compression = BI_RGB;
00211         bGrInfo.bmiHeader.bV4SizeImage = 0;
00212         bGrInfo.bmiHeader.bV4ClrUsed = 0;
00213         bGrInfo.bmiHeader.bV4ClrImportant = 0;
00214         bGrInfo.bmiHeader.bV4AlphaMask = 0;
00215         bGrInfo.bmiHeader.bV4CSType = LCS_WINDOWS_COLOR_SPACE;
00216         bGrInfo.bmiColors[0].rgbRed = 255;
00217         bGrInfo.bmiColors[0].rgbGreen = 255;
00218         bGrInfo.bmiColors[0].rgbBlue = 255;
00219         bGrInfo.bmiColors[1].rgbRed = 0;
00220         bGrInfo.bmiColors[1].rgbGreen = 0;
00221         bGrInfo.bmiColors[1].rgbBlue = 0;
00222 
00223         hOffDC = CreateCompatibleDC(GetDC(info.hWnd));
00224         SelectObject(hOffDC, hLogo);
00225 }
00226 
00227 
00228 DLLEXPORT void __cdecl OnMessage(MESSAGEDLLSTRUCT* mds)
00229 {
00230         int wmId, wmEvent;
00231         HDC hdc;
00232         PAINTSTRUCT ps;
00233         RECT rect;
00234 
00235         switch (mds->message) {
00236         case STOPVIDEO:
00237                 VideoOn = 0;
00238                 Repaint();
00239                 break;
00240         case CPURUNNING:
00241                 Running = TRUE;
00242                 Repaint();
00243                 SetTimer(info.hWnd, MYTIMER, PERIOD, &TimerProc);
00244                 break;
00245         case CPUSTOPPED:
00246                 Running = FALSE;
00247                 KillTimer(info.hWnd, MYTIMER);
00248                 Repaint();
00249                 break;
00250         case WM_PAINT:
00251 
00252                 hdc = BeginPaint(info.hWnd, &ps);
00253                 
00254                 if (Running == TRUE) {
00255                         if (VideoOn != 0) {
00256                                 PaintScreen(hdc);
00257                         }
00258                         else {
00259                                 GetClientRect(info.hWnd, &rect);
00260                                 FillRect(hdc, &rect, (HBRUSH) (COLOR_APPWORKSPACE+1));
00261                         }
00262                 }
00263                 else {
00264                         BitBlt(hdc, info.rcPaint.left, info.rcPaint.top, 256, 256, hOffDC, 0, 0, SRCCOPY);
00265                 }
00266                 EndPaint(info.hWnd, &ps);
00267                 break;
00268         }
00269 }
00270 
00271 VOID CALLBACK TimerProc(HWND hwnd, UINT uMsg, UINT idEvent, 
00272                                                 DWORD dwTime)
00273 {
00274         if (VideoOn == 0) {
00275                 return;
00276         }
00277 
00278         Repaint();
00279         (*info.memsetb)(ISVBI, 1);
00280         SendMessage(info.hWnd, NMIMSG, 0, 0);
00281 }
00282 
00283 void Repaint()
00284 {
00285         InvalidateRect(info.hWnd, &(info.rcPaint), FALSE);
00286     UpdateWindow(info.hWnd);
00287 }
00288 
00289 #define IOSETGET(GVAR, SVAR) \
00290         if (mode == IOREAD) {   \
00291                 *data = GVAR;   \
00292         }       \
00293         else {  \
00294                 SVAR = *data;   \
00295         }
00296 
00297 DLLEXPORT void __cdecl IOFunc(UINT adr, unsigned char* data, 
00298                                                                                   iomode mode)
00299 {
00300         switch (adr) {
00301         case GRMODE:
00302                 IOSETGET(GrMode, _GrMode);
00303                 break;
00304         case LOADR:
00305                 IOSETGET(LoAdr, _LoAdr);
00306                 break;
00307         case HIADR:
00308                 IOSETGET(HiAdr, _HiAdr);
00309                 break;
00310         case BKCOLR:
00311                 IOSETGET(bGrInfo.bmiColors[0].rgbRed, _BkColR);
00312                 break;
00313         case BKCOLG:
00314                 IOSETGET(bGrInfo.bmiColors[0].rgbGreen, _BkColG);
00315                 break;
00316         case BKCOLB:
00317                 IOSETGET(bGrInfo.bmiColors[0].rgbBlue, _BkColB);
00318                 break;
00319         case FGCOLR:
00320                 IOSETGET(bGrInfo.bmiColors[1].rgbRed, _FgColR);
00321                 break;
00322         case FGCOLG:
00323                 IOSETGET(bGrInfo.bmiColors[1].rgbGreen, _FgColG);
00324                 break;
00325         case FGCOLB:
00326                 IOSETGET(bGrInfo.bmiColors[1].rgbBlue, _FgColB);
00327                 break;
00328         case LOCHR:
00329                 IOSETGET(LoChr, _LoChr);
00330                 break;
00331         case HICHR:
00332                 IOSETGET(HiChr, _HiChr);
00333                 break;
00334         case VIDEOON:
00335                 IOSETGET(VideoOn, VideoOn);
00336                 if (VideoOn == 0) {
00337                                 InvalidateRect(info.hWnd, &(info.rcPaint), FALSE);
00338                                 UpdateWindow(info.hWnd);
00339                 }
00340                 break;
00341         case COMMAND:
00342                 if (mode == IOREAD) {
00343                         *data = 0;
00344                 }
00345                 else {
00346                         GrMode = _GrMode;
00347                         LoAdr = _LoAdr;
00348                         HiAdr = _HiAdr;
00349                         LoChr = _LoChr;
00350                         HiChr = _HiChr;
00351                         memStart = ADR(HiAdr, LoAdr);
00352                         memChrStart = ADR(HiChr, LoChr);
00353 
00354                         bGrInfo.bmiColors[0].rgbRed = _BkColR;
00355                         bGrInfo.bmiColors[0].rgbGreen  = _BkColG;
00356                         bGrInfo.bmiColors[0].rgbBlue  = _BkColB;
00357                         bGrInfo.bmiColors[1].rgbRed = _FgColR;
00358                         bGrInfo.bmiColors[1].rgbGreen = _FgColG;
00359                         bGrInfo.bmiColors[1].rgbBlue = _FgColB;
00360                 }
00361                 break;
00362         }
00363 }
00364 
00365 void PaintScreen(HDC hdc)
00366 {
00367         UINT i, ic, j, jc;
00368         unsigned char data;
00369 
00370         switch(GrMode) {
00371         case 0:         /* TEXT MODE */
00372                 for(i = 0, ic = 0;      ic < XCOUNT; 
00373                                 i += FWIDTH, ic++) {
00374                         for(j = 0, jc = 0; jc < YCOUNT; 
00375                                         j += FHEIGHT, jc++) {
00376                                 data = (*info.memgetb)(memStart + ic + jc * XCOUNT);
00377                                 CopyChar(OffScreen, memChrStart + data * 8, 
00378                                         i, j, (data < 128) ? FALSE : TRUE);
00379                         }
00380                 }
00381                 SetDIBitsToDevice(hdc, info.rcPaint.left, info.rcPaint.top, WIDTH, HEIGHT, 0, 0, 0, HEIGHT, (void*) OffScreen, (BITMAPINFO*) &bGrInfo, DIB_RGB_COLORS);
00382                 //SetDIBitsToDevice(hdc, 0, 0, WIDTH, HEIGHT, 0, 0, 0, HEIGHT, (void*) OffScreen, (BITMAPINFO*) &bGrInfo, DIB_RGB_COLORS);
00383                 break;
00384         case 1:         /* GRAPHICS MODE */
00385                 EnterCriticalSection(&info.CSMemory);
00386                 SetDIBitsToDevice(hdc, info.rcPaint.left, info.rcPaint.top, WIDTH, HEIGHT, 0, 0, 0, HEIGHT, (void*) (info.memory + memStart), (BITMAPINFO*) &bGrInfo, DIB_RGB_COLORS);
00387                 LeaveCriticalSection(&info.CSMemory);
00388                 break;
00389         }
00390 }
00391 
00392 void CopyChar(char* dest, UINT adr, int x, int y, BOOL invert)
00393 {
00394         int i;
00395         for (i = 0; i < FHEIGHT; i++) {
00396                 if (invert == FALSE) {
00397                         dest[(y + i) * (WIDTH / 8) + x / 8] = (*info.memgetb)(adr + i);
00398                 }
00399                 else {
00400                         dest[(y + i) * (WIDTH / 8) + x / 8] = ~(*info.memgetb)(adr + i - 128 * 8);
00401                 }
00402         }
00403 }

Generated on Fri Sep 6 22:12:20 2002 for Emu6502 by doxygen1.2.17