123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159 |
- #include <efi.h>
- #define MAX_RECURSION 6
- #define SCREEN_MIN_WIDTH 800
- #define SCREEN_MIN_HEIGHT 600
- #define STR_SIZE 256
- /* mode = a number between 0 and GOP->Mode->MaxMode-1 */
- struct sysinfo
- {
- int gfxMode, fbSize, fbX, fbY;
- void *fb;
- /* mem map */
- };
- struct coord
- {
- int x, y;
- };
- struct colour
- {
- uint8_t r, g, b;
- };
- struct colour white;
- /* -------------------------------------------------------------- */
- int valid(CHAR16 str[])
- {
- ...
- return 0;
- }
- int possible(int c)
- {
- ...
- return 0;
- }
-
- int numFromStr(CHAR16 str[])
- {
- int count, i;
- count = 0;
- i = 0;
- do
- {
- i = (i * 10) + str[count] - '0';
- count++;
- }
- while(str[count] != '\0');
- return count;
- }
- void askForMode(EFI_SYSTEM_TABLE ST, struct sysinfo *si)
- {
- CHAR16 s[STR_SIZE];
- do
- {
- do
- {
- do
- {
- ST->ConOut->OutputString(ST->ConOut,
- L"Enter graphics mode:");
- ST->ConIn->Input(ST->ConIn, s); wrong???
- }
- while(!valid(s));
- si->gfxMode = numFromStr(s);
- }
- while(!possible(si->gfxMode));
- si->fb = GOP->FramebufferBase;
- si->fbSize = GOP->FramebufferSize;
- si->fbX = ...;
- si->fbY = ...;
- }
- while(si->fbX < SCREEN_MIN_WIDTH || si->fbY <SCREEN_MIN_HEIGHT);
- }
- /* -------------------------------------------------------------- */
- void sierpinski(struct coord c1, struct coord c2, int step)
- {
- struct coord targetC1, targetC2, targetC3, c3, rectSize;
- int midX, midY, diffX, diffY;
-
- rectSize.x = RECT_X_SIZE;
- rectSize.y = RECT_Y_SIZE;
- midX = (c1.x + c2.x)/2;
- midY = (c1.y + c2.y)/2;
- diffX = F*(c2.x - c1.x)/2;
- diffY = F*(c2.y - c1.y)/2;
-
- if (step == MAX_RECURSION)
- {
- c3.x = midX + diffX;
- c3.y = midY - diffX;
- DrawTriangle(c1, c2, c3);
- }
- else
- {
- targetC1.x = midX;
- targetC1.y = midY;
- targetC2.x = (3 * c1.x + c2.x) / 4 + diffY;
- targetC2.y = (3 * c1.y + c2.y) / 4 - diffX;
- targetC3.x = (c1.x + 3 * c2.x) / 4 + diffY;
- targetC3.y = (c1.y + 3 * c2.y) / 4 - diffX;
-
- sierpinski(c1, targetC1, step+1);
- sierpinski(targetC1, c2, step+1);
- sierpinski(targetC2, targetC3, step+1);
- }
- }
- void gfxDemo()
- {
- white.r = 255;
- white.g = 255;
- white.b = 255;
- c1.x = 200;
- c1.y = 400;
- c2.x = 600;
- c2.y = 400;
- sierpinski(c1, c2, 0);
- }
- /* -------------------------------------------------------------- */
- EFI_STATUS efi_main(EFI_HANDLE IH, EFI_SYSTEM_TABLE *ST)
- {
- /* EFI_GUID guid; */
- EFI_GRAPHICS_OUTPUT_PROTOCOL GOP;
- struct sysinfo sys;
- if(EFI_ERROR(ST->BootServices->LocateProtocol(
- EFI_GRAPHICS_OUTPUT_PROTOCOL_GUID, NULL, GOP)))
- {
- ST->ConOut->OutputString(ST->ConOut, L"No GOP.\n");
- return EFI_UNSUPPORTED;
- }
- askForMode(ST, &sys);
-
- GOP->SetMode(sys.gfxMode);
-
- /* Framebuffer demo: Sierpinski triangle */
- gfxDemo();
-
- /* Endless loop, left after 5 minutes (watchdog timer) */
- for(;;){}
-
- /* Never reached. Make the compiler happy */
- return EFI_SUCCESS;
- }
|