#include #include #include #include #include #include #include #include EFI_GUID app_guid = EFI_ABSOLUTE_POINTER_PROTOCOL_GUID; EFI_ABSOLUTE_POINTER_PROTOCOL *App = NULL; EFI_GUID gop_guid = EFI_GRAPHICS_OUTPUT_PROTOCOL_GUID; EFI_GRAPHICS_OUTPUT_PROTOCOL *Gop = NULL; UINT64 Gop_FrameBufferBase = 0; UINT32 Gop_PixelsPerScanLine = 0; static inline void drawPixel(UINT32 x, UINT32 y, UINT32 pixel) { *((UINT32*)(Gop_FrameBufferBase + 4 * Gop_PixelsPerScanLine * y + 4 * x)) = pixel; } static inline void drawRectangle(UINT32 x, UINT32 y, UINT32 w, UINT32 h, UINT32 pixel) { for(int ix = 0; ix < w; ++ix) { for(int iy = 0; iy < h; ++iy) { drawPixel(x+ix, y+iy, pixel); } } } EFI_STATUS EFIAPI UefiEntry(IN EFI_HANDLE imgHandle, IN EFI_SYSTEM_TABLE* sysTable) { EFI_STATUS Status; Status = gBS->LocateProtocol(&gop_guid, NULL, (VOID **)&Gop); if (EFI_ERROR(Status)) { Print(u"\r\nERROR: %x; Cannot locate GOP protocol. Return.\r\n", Status); return Status; } Gop_FrameBufferBase = Gop->Mode->FrameBufferBase; Gop_PixelsPerScanLine = Gop->Mode->Info->PixelsPerScanLine; UINT32 W = Gop->Mode->Info->HorizontalResolution; UINT32 H = Gop->Mode->Info->VerticalResolution; Status = gBS->LocateProtocol(&app_guid, NULL, (VOID **)&App); if (EFI_ERROR(Status)) { Print(u"\r\nERROR: %x; Cannot locate APP protocol. Return.\r\n", Status); return Status; } UINT64 aMinX = App->Mode->AbsoluteMinX; UINT64 aMaxX = App->Mode->AbsoluteMaxX; UINT64 aMinY = App->Mode->AbsoluteMinY; UINT64 aMaxY = App->Mode->AbsoluteMaxY; UINT32 sq_sid = W * 80 / 1000; UINT32 sq_gap = W * 20 / 1000; UINT32 col[3] = { W/2 - 3*sq_sid/2 - sq_gap , W/2 - sq_sid/2 , W/2 + sq_sid/2 + sq_gap }; UINT32 row[3] = { H/2 - 3*sq_sid/2 - sq_gap , H/2 - sq_sid/2 , H/2 + sq_sid/2 + sq_gap }; UINT32 aRow0 = aMinY + 450*(aMaxY-aMinY)/1000; UINT32 aRow1 = aMinY + 550*(aMaxY-aMinY)/1000; UINT32 aCol0 = aMinX + 450*(aMaxX-aMinX)/1000; UINT32 aCol1 = aMinX + 550*(aMaxX-aMinX)/1000; const UINT32 accentColor = 0xFFFFFF, idleColor = 0x000000, AColor = 0xCC0000, BColor = 0xFF5500; drawRectangle(0,0,W,H,idleColor); drawRectangle(col[1]-4*sq_gap/7,row[0],sq_gap/8,3*sq_sid+2*sq_gap,accentColor); drawRectangle(col[2]-4*sq_gap/7,row[0],sq_gap/8,3*sq_sid+2*sq_gap,accentColor); drawRectangle(col[0],row[1]-4*sq_gap/7,3*sq_sid+2*sq_gap,sq_gap/8,accentColor); drawRectangle(col[0],row[2]-4*sq_gap/7,3*sq_sid+2*sq_gap,sq_gap/8,accentColor); UINTN EventIndex = 0; UINT32 turn = AColor; UINT32 board[3][3] = {{0,0,0}, {0,0,0}, {0,0,0}}; void draw(int c, int r) { if (board[0][0] != 0 && board[0][0] == board[1][0] && board[1][0] == board[2][0]) return; if (board[0][1] != 0 && board[0][1] == board[1][1] && board[1][1] == board[2][1]) return; if (board[0][2] != 0 && board[0][2] == board[1][2] && board[1][2] == board[2][2]) return; if (board[0][0] != 0 && board[0][0] == board[0][1] && board[0][1] == board[0][2]) return; if (board[1][0] != 0 && board[1][0] == board[1][1] && board[1][1] == board[1][2]) return; if (board[2][0] != 0 && board[2][0] == board[2][1] && board[2][1] == board[2][2]) return; if (board[0][0] != 0 && board[0][0] == board[1][1] && board[1][1] == board[2][2]) return; if (board[0][2] != 0 && board[0][2] == board[1][1] && board[1][1] == board[2][0]) return; if (board[c][r] == 0) { board[c][r] = turn; drawRectangle(col[c],row[r],sq_sid,sq_sid,turn); if (turn == AColor) { turn = BColor; } else { turn = AColor; } } } while(1) { Status = gBS->WaitForEvent(1, /*Event*/ &(App->WaitForInput), &EventIndex); EFI_ABSOLUTE_POINTER_STATE State; App->GetState(App, &State); if (State.CurrentX < aCol0) { if (State.CurrentY < aRow0) { draw(0,0); } else if (State.CurrentY < aRow1) { if (board[0][1] == 0) { draw(0,1); } } else { if (board[0][2] == 0) { draw(0,2); } } } else if (State.CurrentX < aCol1) { if (State.CurrentY < aRow0) { draw(1,0); } else if (State.CurrentY < aRow1) { draw(1,1); } else { draw(1,2); } } else { if (State.CurrentY < aRow0) { draw(2,0); } else if (State.CurrentY < aRow1) { draw(2,1); } else { draw(2,2); } } } return EFI_SUCCESS; }