Code:
#include <windows.h>
#include <math.h>
#include <stdlib.h>
#define MENU_EXIT 0
#define MENU_NORMAL 1
#define MENU_DOUBLE 2
#define MENU_TRIPLE 3
DWORD WINAPI Emulate(LPVOID);
void DrawScreen(int *, char *);
int xsize=160;
int ysize=144;
int map=0x9800;
int tile=0x8000;
char ram[0xFFFF];
int pal[4]={0xFFFFFF,0xC0C0C0,0x808080,0x000000};
void DrawTile(int *,char *,int,int,int,int);
LRESULT CALLBACK WndProc(HWND,UINT,WPARAM,LPARAM);
HWND hwnd;
BITMAPINFO bmi;
int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow){
MSG msg;
WNDCLASSEX wc;
HMENU menu,submenu,options,doubles;
menu = CreateMenu();
submenu = CreatePopupMenu();
AppendMenu(submenu, MF_STRING, MENU_EXIT, "E&xit");
AppendMenu(menu, MF_STRING | MF_POPUP, (UINT)submenu, "&File");
options = CreatePopupMenu();
AppendMenu(menu,MF_STRING | MF_POPUP, (UINT)options,"Options");
AppendMenu(options,MF_STRING, MENU_NORMAL, "100% size");
AppendMenu(options,MF_STRING, MENU_DOUBLE, "200% size");
AppendMenu(options,MF_STRING, MENU_TRIPLE, "300% size");
wc.cbSize = sizeof(WNDCLASSEX);
wc.style = 0;
wc.lpfnWndProc = WndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hInstance;
wc.hIcon = LoadIcon(NULL,IDI_APPLICATION);
wc.hCursor = LoadCursor(NULL,IDC_ARROW);
wc.hbrBackground = (HBRUSH)COLOR_WINDOW;
wc.lpszMenuName = NULL;
wc.lpszClassName = "Emulator";
wc.hIconSm = NULL;
RegisterClassEx(&wc);
hwnd = CreateWindowEx(0,"Emulator","Gameboy",WS_VISIBLE | WS_SYSMENU,CW_USEDEFAULT,CW_USEDEFAULT,4+xsize,44+ysize,NULL,menu,hInstance,NULL);
while(GetMessage(&msg, NULL, 0, 0)>0)
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return msg.wParam;
}
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam){
switch(msg)
{
case WM_CREATE:
break;
case WM_COMMAND:
switch(LOWORD(wParam)) {
case MENU_EXIT:
PostMessage(hwnd, WM_CLOSE, 0, 0);
break;
case MENU_NORMAL:
xsize=160;
ysize=144;
SetWindowPos(hwnd,HWND_TOP,0,0,xsize+4,ysize+44,SWP_NOMOVE);
InvalidateRect(hwnd,NULL,FALSE);
break;
case MENU_DOUBLE:
xsize=320;
ysize=288;
SetWindowPos(hwnd,HWND_TOP,0,0,xsize+4,ysize+44,SWP_NOMOVE);
InvalidateRect(hwnd,NULL,FALSE);
break;
case MENU_TRIPLE:
xsize=640;
ysize=576;
SetWindowPos(hwnd,HWND_TOP,0,0,xsize+4,ysize+44,SWP_NOMOVE);
InvalidateRect(hwnd,NULL,FALSE);
break;
}
break;
case WM_PAINT:
break;
case WM_CLOSE:
DestroyWindow(hwnd);
break;
case WM_DESTROY:
//free(memory);
PostQuitMessage(0);
break;
default:
return DefWindowProc(hwnd, msg, wParam, lParam);
}
return 0;
}
DWORD WINAPI Emulate(LPVOID hWnd){
HDC hdc;
PAINTSTRUCT ps;
static int *memory;
ZeroMemory(&bmi, sizeof(BITMAPINFO));
bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
bmi.bmiHeader.biPlanes = 1;
bmi.bmiHeader.biBitCount = 32;
bmi.bmiHeader.biCompression = BI_RGB;
bmi.bmiHeader.biWidth = 160;
bmi.bmiHeader.biHeight = -144;
memory = (int *) malloc(160 * 144 * sizeof(int));
ram[map]=0;
ram[tile+0]=0x80;
ram[tile+1]=0x80;
ram[tile+2]=0xFF;
ram[tile+3]=0xFF;
ram[tile+4]=0xD5;
ram[tile+5]=0x9D;
ram[tile+6]=0xD5;
ram[tile+7]=0x9D;
ram[tile+8]=0xD4;
ram[tile+9]=0x9C;
ram[tile+10]=0xDF;
ram[tile+11]=0x9F;
ram[tile+12]=0xC0;
ram[tile+13]=0x80;
ram[tile+14]=0xFF;
ram[tile+15]=0xFF;
DrawScreen(memory,ram);
return 0;
}
void DrawTile(int *memory,char *ram,int map,int tile,int x,int y){ //y = 0-31, x=0-31
int tileaddy=map+(y*32)+x; //address of tilenumber
int finaladdy=tile+(ram[tileaddy]*0x10); //address of tile bytes
char temp;
for(int c=0;c<=15;c+=2){
for(int a=0;a<=7;a++){
temp =((ram[finaladdy+c])&(128/((int)pow(2,a))));
if(temp!=0){temp=2;}
temp|=((ram[finaladdy+c+1]) & (128/((int)pow(2,a))))>>(7-a);
memory[(((y*8)+(c/2))*160)+(x*8)+(a)]=(int)pal[temp];
}
}
}
void DrawScreen(int *memory, char *ram){
HDC hdc;
PAINTSTRUCT ps;
hdc=BeginPaint(hwnd,&ps);
for(int b=0;b<=17;b++){
for(int a=0;a<=19;a++){
DrawTile(memory,ram,map,tile,a,b);
}
}
StretchDIBits(hdc, 0, 0, xsize, ysize, 1, 0, 160, 144, (void *) memory, &bmi, DIB_RGB_COLORS, SRCCOPY);
EndPaint(hwnd, &ps);
InvalidateRect(hwnd,NULL,FALSE);
}