diff --git "a/courses_graphics-master \342\200\224 lab4/Debug/Grafika.exe" "b/courses_graphics-master \342\200\224 lab4/Debug/Grafika.exe"
new file mode 100644
index 0000000..414aa94
Binary files /dev/null and "b/courses_graphics-master \342\200\224 lab4/Debug/Grafika.exe" differ
diff --git "a/courses_graphics-master \342\200\224 lab4/Debug/Grafika.ilk" "b/courses_graphics-master \342\200\224 lab4/Debug/Grafika.ilk"
new file mode 100644
index 0000000..b63cc2c
Binary files /dev/null and "b/courses_graphics-master \342\200\224 lab4/Debug/Grafika.ilk" differ
diff --git "a/courses_graphics-master \342\200\224 lab4/Debug/Grafika.pdb" "b/courses_graphics-master \342\200\224 lab4/Debug/Grafika.pdb"
new file mode 100644
index 0000000..22d799e
Binary files /dev/null and "b/courses_graphics-master \342\200\224 lab4/Debug/Grafika.pdb" differ
diff --git "a/courses_graphics-master \342\200\224 lab4/Debug/Grafika.tlog/CL.command.1.tlog" "b/courses_graphics-master \342\200\224 lab4/Debug/Grafika.tlog/CL.command.1.tlog"
new file mode 100644
index 0000000..d02639b
Binary files /dev/null and "b/courses_graphics-master \342\200\224 lab4/Debug/Grafika.tlog/CL.command.1.tlog" differ
diff --git "a/courses_graphics-master \342\200\224 lab4/Debug/Grafika.tlog/CL.read.1.tlog" "b/courses_graphics-master \342\200\224 lab4/Debug/Grafika.tlog/CL.read.1.tlog"
new file mode 100644
index 0000000..9c210e5
Binary files /dev/null and "b/courses_graphics-master \342\200\224 lab4/Debug/Grafika.tlog/CL.read.1.tlog" differ
diff --git "a/courses_graphics-master \342\200\224 lab4/Debug/Grafika.tlog/CL.write.1.tlog" "b/courses_graphics-master \342\200\224 lab4/Debug/Grafika.tlog/CL.write.1.tlog"
new file mode 100644
index 0000000..d8b8284
Binary files /dev/null and "b/courses_graphics-master \342\200\224 lab4/Debug/Grafika.tlog/CL.write.1.tlog" differ
diff --git "a/courses_graphics-master \342\200\224 lab4/Debug/Grafika.tlog/Grafika.lastbuildstate" "b/courses_graphics-master \342\200\224 lab4/Debug/Grafika.tlog/Grafika.lastbuildstate"
new file mode 100644
index 0000000..a9bfdcf
--- /dev/null
+++ "b/courses_graphics-master \342\200\224 lab4/Debug/Grafika.tlog/Grafika.lastbuildstate"
@@ -0,0 +1,2 @@
+PlatformToolSet=v142:VCToolArchitecture=Native32Bit:VCToolsVersion=14.25.28610:TargetPlatformVersion=10.0.18362.0:
+Debug|Win32|D:\PW\Infa II\courses_graphics-master — lab4\|
diff --git "a/courses_graphics-master \342\200\224 lab4/Debug/Grafika.tlog/link.command.1.tlog" "b/courses_graphics-master \342\200\224 lab4/Debug/Grafika.tlog/link.command.1.tlog"
new file mode 100644
index 0000000..252c2ef
Binary files /dev/null and "b/courses_graphics-master \342\200\224 lab4/Debug/Grafika.tlog/link.command.1.tlog" differ
diff --git "a/courses_graphics-master \342\200\224 lab4/Debug/Grafika.tlog/link.read.1.tlog" "b/courses_graphics-master \342\200\224 lab4/Debug/Grafika.tlog/link.read.1.tlog"
new file mode 100644
index 0000000..c94adb6
Binary files /dev/null and "b/courses_graphics-master \342\200\224 lab4/Debug/Grafika.tlog/link.read.1.tlog" differ
diff --git "a/courses_graphics-master \342\200\224 lab4/Debug/Grafika.tlog/link.write.1.tlog" "b/courses_graphics-master \342\200\224 lab4/Debug/Grafika.tlog/link.write.1.tlog"
new file mode 100644
index 0000000..3cddf0d
Binary files /dev/null and "b/courses_graphics-master \342\200\224 lab4/Debug/Grafika.tlog/link.write.1.tlog" differ
diff --git "a/courses_graphics-master \342\200\224 lab4/Debug/ProjektVisualStudio2008.log" "b/courses_graphics-master \342\200\224 lab4/Debug/ProjektVisualStudio2008.log"
new file mode 100644
index 0000000..8bcd56f
--- /dev/null
+++ "b/courses_graphics-master \342\200\224 lab4/Debug/ProjektVisualStudio2008.log"
@@ -0,0 +1,6 @@
+cl : wiersz polecenia warning D9035: Opcja "Gm" jest przestarzała i będzie usunięta w przyszłych wydaniach
+ main.cpp
+D:\PW\Infa II\courses_graphics-master — lab4\main.cpp(54,36): warning C4244: "argument": konwersja z "double" do "size_t", możliwa utrata danych
+D:\PW\Infa II\courses_graphics-master — lab4\main.cpp(55,36): warning C4244: "argument": konwersja z "double" do "size_t", możliwa utrata danych
+main.obj : warning LNK4075: zignorowano opcję "/EDITANDCONTINUE" z powodu określenia opcji "/SAFESEH"
+ ProjektVisualStudio2008.vcxproj -> D:\PW\Infa II\courses_graphics-master — lab4\Debug\Grafika.exe
diff --git "a/courses_graphics-master \342\200\224 lab4/Debug/ProjektVisualStudio2008.vcxproj.FileListAbsolute.txt" "b/courses_graphics-master \342\200\224 lab4/Debug/ProjektVisualStudio2008.vcxproj.FileListAbsolute.txt"
new file mode 100644
index 0000000..5707606
--- /dev/null
+++ "b/courses_graphics-master \342\200\224 lab4/Debug/ProjektVisualStudio2008.vcxproj.FileListAbsolute.txt"
@@ -0,0 +1,2 @@
+D:\PW\Infa II\courses_graphics-master — lab4\Debug\Grafika.exe
+D:\PW\Infa II\courses_graphics-master — lab4\Debug\Grafika.pdb
diff --git "a/courses_graphics-master \342\200\224 lab4/Debug/main.obj" "b/courses_graphics-master \342\200\224 lab4/Debug/main.obj"
new file mode 100644
index 0000000..2b98523
Binary files /dev/null and "b/courses_graphics-master \342\200\224 lab4/Debug/main.obj" differ
diff --git "a/courses_graphics-master \342\200\224 lab4/Debug/rk4.obj" "b/courses_graphics-master \342\200\224 lab4/Debug/rk4.obj"
new file mode 100644
index 0000000..d75933b
Binary files /dev/null and "b/courses_graphics-master \342\200\224 lab4/Debug/rk4.obj" differ
diff --git "a/courses_graphics-master \342\200\224 lab4/Debug/vc142.idb" "b/courses_graphics-master \342\200\224 lab4/Debug/vc142.idb"
new file mode 100644
index 0000000..af2a6b7
Binary files /dev/null and "b/courses_graphics-master \342\200\224 lab4/Debug/vc142.idb" differ
diff --git "a/courses_graphics-master \342\200\224 lab4/Debug/vc142.pdb" "b/courses_graphics-master \342\200\224 lab4/Debug/vc142.pdb"
new file mode 100644
index 0000000..3eb7f1d
Binary files /dev/null and "b/courses_graphics-master \342\200\224 lab4/Debug/vc142.pdb" differ
diff --git "a/courses_graphics-master \342\200\224 lab4/Debug/winbgi2.obj" "b/courses_graphics-master \342\200\224 lab4/Debug/winbgi2.obj"
new file mode 100644
index 0000000..973100c
Binary files /dev/null and "b/courses_graphics-master \342\200\224 lab4/Debug/winbgi2.obj" differ
diff --git "a/courses_graphics-master \342\200\224 lab4/Hareza Krzysztof sroda 12 Ci\304\205g14.docx" "b/courses_graphics-master \342\200\224 lab4/Hareza Krzysztof sroda 12 Ci\304\205g14.docx"
new file mode 100644
index 0000000..f97c0f8
Binary files /dev/null and "b/courses_graphics-master \342\200\224 lab4/Hareza Krzysztof sroda 12 Ci\304\205g14.docx" differ
diff --git "a/courses_graphics-master \342\200\224 lab4/ProjektCodeBlocks.cbp" "b/courses_graphics-master \342\200\224 lab4/ProjektCodeBlocks.cbp"
new file mode 100644
index 0000000..34a831a
--- /dev/null
+++ "b/courses_graphics-master \342\200\224 lab4/ProjektCodeBlocks.cbp"
@@ -0,0 +1,40 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git "a/courses_graphics-master \342\200\224 lab4/ProjektVisualStudio2008.sln" "b/courses_graphics-master \342\200\224 lab4/ProjektVisualStudio2008.sln"
new file mode 100644
index 0000000..befc326
--- /dev/null
+++ "b/courses_graphics-master \342\200\224 lab4/ProjektVisualStudio2008.sln"
@@ -0,0 +1,25 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio Version 16
+VisualStudioVersion = 16.0.30011.22
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Grafika", "ProjektVisualStudio2008.vcxproj", "{923B0D8D-CCEB-470A-BC0F-77BA5CA39B18}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|x86 = Debug|x86
+ Release|x86 = Release|x86
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {923B0D8D-CCEB-470A-BC0F-77BA5CA39B18}.Debug|x86.ActiveCfg = Debug|Win32
+ {923B0D8D-CCEB-470A-BC0F-77BA5CA39B18}.Debug|x86.Build.0 = Debug|Win32
+ {923B0D8D-CCEB-470A-BC0F-77BA5CA39B18}.Release|x86.ActiveCfg = Release|Win32
+ {923B0D8D-CCEB-470A-BC0F-77BA5CA39B18}.Release|x86.Build.0 = Release|Win32
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ SolutionGuid = {F6E56CEC-5933-48C7-9DAA-190E3E43D2C4}
+ EndGlobalSection
+EndGlobal
diff --git "a/courses_graphics-master \342\200\224 lab4/ProjektVisualStudio2008.vcproj" "b/courses_graphics-master \342\200\224 lab4/ProjektVisualStudio2008.vcproj"
new file mode 100644
index 0000000..c82195d
--- /dev/null
+++ "b/courses_graphics-master \342\200\224 lab4/ProjektVisualStudio2008.vcproj"
@@ -0,0 +1,201 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git "a/courses_graphics-master \342\200\224 lab4/ProjektVisualStudio2008.vcxproj" "b/courses_graphics-master \342\200\224 lab4/ProjektVisualStudio2008.vcxproj"
new file mode 100644
index 0000000..db246b9
--- /dev/null
+++ "b/courses_graphics-master \342\200\224 lab4/ProjektVisualStudio2008.vcxproj"
@@ -0,0 +1,102 @@
+
+
+
+
+ Debug
+ Win32
+
+
+ Release
+ Win32
+
+
+
+ Grafika
+ {923B0D8D-CCEB-470A-BC0F-77BA5CA39B18}
+ Grafika
+ Win32Proj
+
+
+
+ Application
+ v142
+ MultiByte
+ true
+
+
+ Application
+ v142
+ MultiByte
+
+
+
+
+
+
+
+
+
+
+
+
+ <_ProjectFileVersion>16.0.29403.142
+
+
+ $(SolutionDir)$(Configuration)\
+ $(Configuration)\
+ true
+
+
+ $(SolutionDir)$(Configuration)\
+ $(Configuration)\
+ false
+
+
+
+ Disabled
+ WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)
+ true
+ EnableFastChecks
+ MultiThreadedDebugDLL
+
+ Level3
+ EditAndContinue
+
+
+ true
+ Console
+ MachineX86
+
+
+
+
+ MaxSpeed
+ true
+ WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)
+ MultiThreadedDLL
+ true
+
+ Level3
+ ProgramDatabase
+
+
+ true
+ Console
+ true
+ true
+ MachineX86
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git "a/courses_graphics-master \342\200\224 lab4/ProjektVisualStudio2008.vcxproj.filters" "b/courses_graphics-master \342\200\224 lab4/ProjektVisualStudio2008.vcxproj.filters"
new file mode 100644
index 0000000..6d6d5ae
--- /dev/null
+++ "b/courses_graphics-master \342\200\224 lab4/ProjektVisualStudio2008.vcxproj.filters"
@@ -0,0 +1,36 @@
+
+
+
+
+ {4FC737F1-C7A5-4376-A066-2A32D752A2FF}
+ cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx
+
+
+ {93995380-89BD-4b04-88EB-625FBE52EBFB}
+ h;hpp;hxx;hm;inl;inc;xsd
+
+
+ {67DA6AB6-F800-4c08-8B7A-83BB121AAD01}
+ rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav
+
+
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+
+
+ Header Files
+
+
+ Header Files
+
+
+
\ No newline at end of file
diff --git "a/courses_graphics-master \342\200\224 lab4/ProjektVisualStudio2008.vcxproj.user" "b/courses_graphics-master \342\200\224 lab4/ProjektVisualStudio2008.vcxproj.user"
new file mode 100644
index 0000000..0f14913
--- /dev/null
+++ "b/courses_graphics-master \342\200\224 lab4/ProjektVisualStudio2008.vcxproj.user"
@@ -0,0 +1,4 @@
+
+
+
+
\ No newline at end of file
diff --git "a/courses_graphics-master \342\200\224 lab4/ProjektVisualStudio2013.vcxproj" "b/courses_graphics-master \342\200\224 lab4/ProjektVisualStudio2013.vcxproj"
new file mode 100644
index 0000000..3254e9d
--- /dev/null
+++ "b/courses_graphics-master \342\200\224 lab4/ProjektVisualStudio2013.vcxproj"
@@ -0,0 +1,90 @@
+
+
+
+
+ Debug
+ Win32
+
+
+ Release
+ Win32
+
+
+
+ {6630C9F2-1CC7-4A2B-9318-50CA0EB82D55}
+ Win32Proj
+ Grafika
+
+
+
+ Application
+ true
+ v120
+ MultiByte
+
+
+ Application
+ false
+ v120
+ true
+ Unicode
+
+
+
+
+
+
+
+
+
+
+
+
+ true
+
+
+ false
+
+
+
+
+
+ Level3
+ Disabled
+ WIN32;_DEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions)
+ true
+
+
+ Console
+ true
+
+
+
+
+ Level3
+
+
+ MaxSpeed
+ true
+ true
+ WIN32;NDEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions)
+ true
+
+
+ Console
+ true
+ true
+ true
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git "a/courses_graphics-master \342\200\224 lab4/ProjektVisualStudio2013.vcxproj.user" "b/courses_graphics-master \342\200\224 lab4/ProjektVisualStudio2013.vcxproj.user"
new file mode 100644
index 0000000..0f14913
--- /dev/null
+++ "b/courses_graphics-master \342\200\224 lab4/ProjektVisualStudio2013.vcxproj.user"
@@ -0,0 +1,4 @@
+
+
+
+
\ No newline at end of file
diff --git "a/courses_graphics-master \342\200\224 lab4/README.md" "b/courses_graphics-master \342\200\224 lab4/README.md"
new file mode 100644
index 0000000..cae728c
--- /dev/null
+++ "b/courses_graphics-master \342\200\224 lab4/README.md"
@@ -0,0 +1,2 @@
+# courses_graphics
+VC project with graphic library
diff --git "a/courses_graphics-master \342\200\224 lab4/UpgradeLog.htm" "b/courses_graphics-master \342\200\224 lab4/UpgradeLog.htm"
new file mode 100644
index 0000000..8cb9d04
Binary files /dev/null and "b/courses_graphics-master \342\200\224 lab4/UpgradeLog.htm" differ
diff --git "a/courses_graphics-master \342\200\224 lab4/main.cpp" "b/courses_graphics-master \342\200\224 lab4/main.cpp"
new file mode 100644
index 0000000..735905a
--- /dev/null
+++ "b/courses_graphics-master \342\200\224 lab4/main.cpp"
@@ -0,0 +1,167 @@
+#define _CRT_SECURE_NO_WARNINGS
+#include
+#include
+#include
+#include "winbgi2.h"
+#include "rk4.h"
+
+double euler(double y, double t, double h);
+double fun(double t, double y);
+double anali(double y, double t, double t0);
+void scan(double* x);
+double l = 1;
+double p = 6; //najwieksza potega liczby N kotra wyznacza ilosc krokow
+
+void main()
+{
+
+ double h, N, Ee = 0, Er = 0; //zmienne obliczane
+ double t, ye, yr; //zmienne uzywane w programie
+ double tm, t0, y0; //zmienne podane przez uzytkownika
+ double p1 = 0, p2 = 0, p3 = 0; //zmienne pomocnicze
+ double* t0_ = &t0, * tm_ = &tm, * y0_ = &y0, * l_ = &l; //wskazniki by latwiej wczytywac zmienne bez ciaglego copy-paste
+ double *yee, *yrr; //tablice przechowujace wartosci obliczone numerycznie w poprzednim kroku
+ double rzade, rzadrk; //zmienne rzedu obu metod
+
+ FILE* g;
+ g = fopen("wynik.txt", "w");
+
+ if (!g) //oblsuga pliku
+ {
+
+ printf("Wystapil blad przy otwieraniu pliku!");
+ exit(1);
+
+ }
+
+ fprintf(g, "L.p.\tLiczba krokow N\tDlugosc kroku h\tBlad met. Eulera\tBlad met. RK4\n"); //naglowek do pliku
+
+
+ printf("Podaj gorna krawedz przedzialu [tm]: \n");
+ scan(tm_);
+
+ printf("Podaj warunek poczatkowy [t_0, y_0]: \n");
+ do
+ {
+ scan(t0_);
+ if (t0 >= tm) printf("t0 nie moze byc wieksze niz tm! \n");
+ } while (t0 >= tm);
+ scan(y0_);
+
+ printf("Podaj wartosc lambda: \n");
+ scan(l_);
+
+
+ yee = (double*)malloc(pow(2.0, p) * sizeof(double));
+ yrr = (double*)malloc(pow(2.0, p) * sizeof(double));
+
+ if (yee == NULL && yrr == NULL)
+ {
+
+ printf("Wystapil blad alokacji :( \n");
+ exit(1);
+
+ }
+
+
+ graphics(600,600); //oblsuga grafiki
+ scale(0.0, 0.0, (tm-t0), 2.2);
+ title("Blad metod: Eulera [Czerwony]\tRK4 [Zolty]", "", "");
+
+
+ for (int j = 0; j <( p+1 ); j++)
+ {
+
+ int k = 0; //zmienna pomocnicza
+ double Ee_max = -10000, Er_max = -10000; //zmienne pomocnicze
+
+ N = pow(2.0, j);
+ h = (tm - t0) / N;
+ t = t0;
+ ye = y0;
+ yr = y0;
+ while ((tm - t) > h / 2.0)
+ {
+ t+= h;
+
+ yr = rk4(t, yr, h, fun);
+ printf(" Met. RK4 t[%i] = %f , y[%i] = %f , N = %f , h = %f \n", k, t, k, yr, N, h);
+ Er = (fabs((yr - anali(y0, t, t0))) / fabs(anali(y0, t, t0))); //blad metody RK4
+ printf("Blad met. RK4 = %lf \n\n", Er);
+ setcolor(0.7); //zolty
+ point(h, Er);
+ yrr[k] = yr;
+ if (Er_max < Er) Er_max = Er;
+
+ ye = euler(ye, t, h);
+ printf(" Metoda Eulera t[%i] = %f , y[%i] = %f , N = %f , h = %f \n", k, t, k, ye, N, h);
+ Ee = (fabs((ye - anali(y0, t, t0))) / fabs(anali(y0, t, t0))); //blad metody Eulera
+ printf("Blad met. Eulera = %lf \n\n", Ee);
+ setcolor(1); //czerwony
+ point(h, Ee);
+ yee[k] = ye;
+ if (Ee_max < Ee) Ee_max = Ee;
+
+ k++;
+
+ }
+
+ rzade = round(log(fabs((ye - anali(y0, t, t0)))) / log(fabs((yee[k-1] - anali(y0, t, y0)))));
+ rzadrk = round(log(fabs((yr - anali(y0, t, t0)))) / log(fabs((yrr[k-1] - anali(y0, t, y0))))); //szacowanie rzêdu zbie¿noœci
+ printf("\n RZAD ZBIEZONSCI E = %lf RZAD ZBIEZONOSCI RK = %lf \n\n",rzade,rzadrk);
+
+ if (j > 0) //rysowanie wykresu
+ {
+
+ line(p1, p2, h, Ee_max);
+ setcolor(0.7);
+ line(p1, p3, h, Er_max);
+
+ }
+
+ p1 = h;
+ p2 = Ee_max;
+ p3 = Er_max;
+
+ fprintf(g, "%d\t%lf\t%lf\t%lf\t%lf\n", j, N, h, Ee, Er); //zapisuje dane do pliku na koncu kroku
+
+ }
+
+ fclose(g);
+ wait();
+
+}
+
+
+void scan(double *x) //funkcja do wczytywania i sprawdzania zgodnosci inputu
+{
+ double temp;
+ while (scanf("%lf", &temp) != 1)
+ {
+ printf("Nieprawid³owy format danych! \n");
+ int n;
+ while ((n = getchar()) != EOF && n != '\n');
+ }
+ *x = temp;
+}
+
+double fun(double t, double y) //funkcja liczaca prawa strone rownania, wywolywana jest z dwiema zmiennymi poniewaz potrzebuje tego funkcja rk4
+{
+
+ return l*y;
+
+}
+
+double euler(double y, double t, double h)
+{
+
+ return y += h * fun(t, y);
+
+}
+
+double anali(double y0, double t, double t0) //analityczne rozwiazanie
+{
+
+ return y0 * exp(l * (t - t0));
+
+}
diff --git "a/courses_graphics-master \342\200\224 lab4/rk4.cpp" "b/courses_graphics-master \342\200\224 lab4/rk4.cpp"
new file mode 100644
index 0000000..30f24db
--- /dev/null
+++ "b/courses_graphics-master \342\200\224 lab4/rk4.cpp"
@@ -0,0 +1,78 @@
+#include
+
+#define MAXN 100 // maksymalna liczba rownan
+
+// --------------------------------------------------------------------------
+// Funkcja wykonuje, metoda Rungego-Kutty IV-ego rzedu,
+// jeden krok calkowania skalarnego rownania rozniczkowego zwyczajnego:
+//
+// dy/dx = fun(x,y), y(x0)=y0
+//
+// Parametry formalne:
+// x0 - wartosc startowa zm. niezaleznej
+// y0 - wartosc startowa zm. zaleznej
+// h - krok calkowania
+// fun(x,y) - nazwa funkcji obliczajacej prawe strony
+// y1 - obliczona wartosc zmiennej zaleznej w punkcie x0+h
+
+double rk4(double x0, double y0, double h, double (*fun)(double, double))
+{
+ double y1;
+ double k1, k2, k3, k4;
+ k1 = h * fun(x0, y0);
+ k2 = h * fun(x0 + h / 2., y0 + k1 / 2.);
+ k3 = h * fun(x0 + h / 2., y0 + k2 / 2.);
+ k4 = h * fun(x0 + h, y0 + k3);
+ y1 = y0 + (k1 + 2. * k2 + 2. * k3 + k4) / 6.;
+ return y1;
+}
+
+// --------------------------------------------------------------------------
+// Funkcja wykonuje, metoda Rungego-Kutty IV-tego rzedu,
+// jeden krok calkowania wektorowego rownania rozniczkowego zwyczjanego:
+//
+// dY/dx = Fun(x,Y), Y(x0)=Y0
+//
+// Parametry formalne:
+// x0 - wartosc startowa zm. niezaleznej
+// y0 - wartosc startowa zm. zaleznej (tablica n-elementowa)
+// h - krok calkowania
+// n - liczba rownan
+// fun(x,y,prawastr) - nazwa funkcji obliczajacej prawe strony
+// y1 - obliczona wartosc zmiennej zaleznej w punkcie x0+h
+// (tablica n-elementowa)
+
+void vrk4(double x0, double y0[], double h, int n, void (*fun)(double, double*, double*), double y1[])
+{
+ int i;
+ double k1[MAXN], k2[MAXN], k3[MAXN], k4[MAXN];
+ double ytmp[MAXN];
+
+ fun(x0, y0, k1);
+ for (i = 0; i < n; ++i)
+ {
+ k1[i] *= h;
+ ytmp[i] = y0[i] + k1[i] / 2.0;
+ }
+
+ fun(x0 + h / 2.0, ytmp, k2);
+ for (i = 0; i < n; ++i)
+ {
+ k2[i] *= h;
+ ytmp[i] = y0[i] + k2[i] / 2.0;
+ }
+
+ fun(x0 + h / 2.0, ytmp, k3);
+ for (i = 0; i < n; ++i)
+ {
+ k3[i] *= h;
+ ytmp[i] = y0[i] + k3[i];
+ }
+
+ fun(x0 + h, ytmp, k4);
+ for (i = 0; i < n; ++i)
+ k4[i] *= h;
+
+ for (i = 0; i < n; ++i)
+ y1[i] = y0[i] + (k1[i] + 2. * k2[i] + 2. * k3[i] + k4[i]) / 6.;
+}
diff --git "a/courses_graphics-master \342\200\224 lab4/rk4.h" "b/courses_graphics-master \342\200\224 lab4/rk4.h"
new file mode 100644
index 0000000..9bf0c80
--- /dev/null
+++ "b/courses_graphics-master \342\200\224 lab4/rk4.h"
@@ -0,0 +1,38 @@
+#ifndef __RK4_H__
+#define __RK4_H__
+
+// --------------------------------------------------------------------------
+// Funkcja wykonuje, metoda Rungego-Kutty IV-ego rzedu,
+// jeden krok calkowania skalarnego rownania rozniczkowego zwyczajnego:
+//
+// dy/dx = fun(x,y), y(x0)=y0
+//
+// Parametry formalne:
+// x0 - wartosc startowa zm. niezaleznej
+// y0 - wartosc startowa zm. zaleznej
+// h - krok calkowania
+// fun(x,y) - nazwa funkcji obliczajacej prawe strony
+// y1 - obliczona wartosc zmiennej zaleznej w punkcie x0+h
+
+double rk4(double x0, double y0, double h, double (*fun)(double, double));
+
+
+// --------------------------------------------------------------------------
+// Funkcja wykonuje, metoda Rungego-Kutty IV-tego rzedu,
+// jeden krok calkowania wektorowego rownania rozniczkowego zwyczjanego:
+//
+// dY/dx = Fun(x,Y), Y(x0)=Y0
+//
+// Parametry formalne:
+// x0 - wartosc startowa zm. niezaleznej
+// y0 - wartosc startowa zm. zaleznej (tablica n-elementowa)
+// h - krok calkowania
+// n - liczba rownañ
+// fun(x,y,prawastr) - nazwa funkcji obliczajacej prawe strony
+// y1 - obliczona wartosc zmiennej zaleznej w punkcie x0+h
+// (tablica n-elementowa)
+
+void vrk4(double x0, double y0[], double h, int n, void (*fun)(double, double*, double*), double y1[]);
+
+#endif
+
diff --git "a/courses_graphics-master \342\200\224 lab4/winbgi2.cpp" "b/courses_graphics-master \342\200\224 lab4/winbgi2.cpp"
new file mode 100644
index 0000000..d6532d3
--- /dev/null
+++ "b/courses_graphics-master \342\200\224 lab4/winbgi2.cpp"
@@ -0,0 +1,2258 @@
+#define _CRT_SECURE_NO_WARNINGS
+//
+// winbgi.cpp -- One of the files required to run BGI graphics programs
+//
+// You don't need to edit this file, or print it out.
+
+#include
+#include
+#include
+#include
+#include "winbgi2.h"
+
+#define MAX_PAGES 16
+
+const double pi = 3.14159265358979323846;
+
+static HDC hdc[4];
+
+static HPEN hPen;
+static HRGN hRgn;
+static HFONT hFont;
+static NPLOGPALETTE pPalette;
+static PAINTSTRUCT ps;
+static HWND hWnd;
+static HBRUSH hBrush[USER_FILL+1];
+static HBRUSH hBackgroundBrush;
+
+static HPALETTE hPalette;
+static HBITMAP hBitmap[MAX_PAGES];
+static HBITMAP hPutimageBitmap;
+
+static int timeout_expired = true;
+
+double scale_x=1.0, scale_y=1.0, scale_dx=0.0, scale_dy=0.0;
+int scale_y_log=0;
+
+#define PEN_CACHE_SIZE 8
+#define FONT_CACHE_SIZE 8
+#define BG 64
+#define TIMER_ID 1
+
+//
+// When XOR or NOT write modes are used for drawing high BG bit is cleared, so
+// drawing colors should be adjusted to preserve this bit
+//
+#define ADJUSTED_MODE(mode) ((mode) == XOR_PUT || (mode) == NOT_PUT)
+
+int bgiemu_handle_redraw = TRUE;
+int bgiemu_default_mode = VGAHI; //VGAMAX;
+
+static int screen_width;
+static int screen_height;
+static int window_width;
+static int window_height;
+
+//Mouse info (Added 1-Oct-2000, Matthew Weathers)
+static bool bMouseUp = false;
+static bool bMouseDown = false;
+static int iCurrentMouseX = 0;
+static int iCurrentMouseY = 0;
+static int iClickedMouseX = 0;
+static int iClickedMouseY = 0;
+static int iWhichMouseButton = LEFT_BUTTON;
+
+static int line_style_cnv[] = {
+ PS_SOLID, PS_DOT, PS_DASHDOT, PS_DASH,
+ PS_DASHDOTDOT /* if user style lines are not supported */
+};
+static int write_mode_cnv[] =
+ {R2_COPYPEN, R2_XORPEN, R2_MERGEPEN, R2_MASKPEN, R2_NOTCOPYPEN};
+static int bitblt_mode_cnv[] =
+ {SRCCOPY, SRCINVERT, SRCPAINT, SRCAND, NOTSRCCOPY};
+
+static int font_weight[] =
+{
+ FW_BOLD, // DefaultFont
+ FW_NORMAL, // TriplexFont
+ FW_NORMAL, // SmallFont
+ FW_NORMAL, // SansSerifFont
+ FW_NORMAL, // GothicFont
+ FW_NORMAL, // ScriptFont
+ FW_NORMAL, // SimplexFont
+ FW_NORMAL, // TriplexScriptFont
+ FW_NORMAL, // ComplexFont
+ FW_NORMAL, // EuropeanFont
+ FW_BOLD // BoldFont
+};
+
+static int font_family[] =
+{
+ FIXED_PITCH|FF_DONTCARE, // DefaultFont
+ VARIABLE_PITCH|FF_ROMAN, // TriplexFont
+ VARIABLE_PITCH|FF_MODERN, // SmallFont
+ VARIABLE_PITCH|FF_DONTCARE, // SansSerifFont
+ VARIABLE_PITCH|FF_SWISS, // GothicFont
+ VARIABLE_PITCH|FF_SCRIPT, // ScriptFont
+ VARIABLE_PITCH|FF_DONTCARE, // SimplexFont
+ VARIABLE_PITCH|FF_SCRIPT, // TriplexScriptFont
+ VARIABLE_PITCH|FF_DONTCARE, // ComplexFont
+ VARIABLE_PITCH|FF_DONTCARE, // EuropeanFont
+ VARIABLE_PITCH|FF_DONTCARE // BoldFont
+ };
+
+static char* font_name[] =
+{
+ "Console", // DefaultFont
+ "Times New Roman", // TriplexFont
+ "Small Fonts", // SmallFont
+ "MS Sans Serif", // SansSerifFont
+ "Arial", // GothicFont
+ "Script", // ScriptFont
+ "Times New Roman", // SimplexFont
+ "Script", // TriplexScriptFont
+ "Courier New", // ComplexFont
+ "Times New Roman", // EuropeanFont
+ "Courier New Bold", // BoldFont
+};
+
+static int text_halign_cnv[] = {TA_LEFT, TA_CENTER, TA_RIGHT};
+static int text_valign_cnv[] = {TA_BOTTOM, TA_BASELINE, TA_TOP};
+
+static palettetype current_palette;
+
+static struct { int width; int height; } font_metrics[][11] = {
+{{0,0},{8,8},{16,16},{24,24},{32,32},{40,40},{48,48},{56,56},{64,64},{72,72},{80,80}}, // DefaultFont
+{{0,0},{13,18},{14,20},{16,23},{22,31},{29,41},{36,51},{44,62},{55,77},{66,93},{88,124}}, // TriplexFont
+{{0,0},{3,5},{4,6},{4,6},{6,9},{8,12},{10,15},{12,18},{15,22},{18,27},{24,36}}, // SmallFont
+{{0,0},{11,19},{12,21},{14,24},{19,32},{25,42},{31,53},{38,64},{47,80},{57,96},{76,128}}, // SansSerifFont
+{{0,0},{13,19},{14,21},{16,24},{22,32},{29,42},{36,53},{44,64},{55,80},{66,96},{88,128}}, // GothicFont
+// I am not sure about metrics of following fonts
+{{0,0},{11,19},{12,21},{14,24},{19,32},{25,42},{31,53},{38,64},{47,80},{57,96},{76,128}}, // ScriptFont
+{{0,0},{11,19},{12,21},{14,24},{19,32},{25,42},{31,53},{38,64},{47,80},{57,96},{76,128}}, // SimplexFont
+{{0,0},{13,18},{14,20},{16,23},{22,31},{29,41},{36,51},{44,62},{55,77},{66,93},{88,124}}, // TriplexScriptFont
+{{0,0},{11,19},{12,21},{14,24},{19,32},{25,42},{31,53},{38,64},{47,80},{57,96},{76,128}}, // ComplexFont
+{{0,0},{11,19},{12,21},{14,24},{19,32},{25,42},{31,53},{38,64},{47,80},{57,96},{76,128}}, // EuropeanFont
+{{0,0},{11,19},{12,21},{14,24},{19,32},{25,42},{31,53},{38,64},{47,80},{57,96},{76,128}} // BoldFont
+};
+
+struct BGIimage {
+ short width;
+ short height;
+ int reserved; // let bits be aligned to DWORD boundary
+ char bits[1];
+};
+
+struct BGIbitmapinfo {
+ BITMAPINFOHEADER hdr;
+ short color_table[64];
+};
+
+static BGIbitmapinfo bminfo = {
+ {sizeof(BITMAPINFOHEADER), 0, 0, 1, 4, BI_RGB}
+};
+
+static int* image_bits;
+
+static int normal_font_size[] = { 1, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4};
+
+static linesettingstype line_settings;
+static fillsettingstype fill_settings;
+
+static int color;
+static int bkcolor;
+static int text_color;
+
+static int aspect_ratio_x, aspect_ratio_y;
+
+static textsettingstype text_settings;
+
+static viewporttype view_settings;
+
+static int font_mul_x, font_div_x, font_mul_y, font_div_y;
+
+static enum { ALIGN_NOT_SET, UPDATE_CP, NOT_UPDATE_CP } text_align_mode;
+
+#define BORDER_WIDTH 8
+#define BORDER_HEIGHT 27
+
+static int write_mode;
+
+static int visual_page;
+static int active_page;
+
+static arccoordstype ac;
+
+class char_queue {
+ protected:
+ char* buf;
+ int put_pos;
+ int get_pos;
+ int buf_size;
+ public:
+ void put(char ch) {
+ buf[put_pos] = ch;
+ if (++put_pos == buf_size) {
+ put_pos = 0;
+ }
+ if (put_pos == get_pos) { // queue is full
+ (void)get(); // loose one character
+ }
+ }
+ char get() {
+ char ch = buf[get_pos];
+ if (++get_pos == buf_size) {
+ get_pos = 0;
+ }
+ return ch;
+ }
+ bool is_empty() {
+ return get_pos == put_pos;
+ }
+ char_queue(int buf_size = 256) {
+ put_pos = get_pos = 0;
+ this->buf_size = buf_size;
+ buf = new char[buf_size];
+ }
+ ~char_queue() {
+ delete[] buf;
+ }
+};
+
+static char_queue kbd_queue;
+
+inline int convert_userbits(DWORD buf[32], unsigned pattern)
+{
+ int i = 0, j;
+ pattern &= 0xFFFF;
+
+ while (true) {
+ for (j = 0; pattern & 1; j++) pattern >>= 1;
+ buf[i++] = j;
+ if (pattern == 0) {
+ buf[i++] = 16 - j;
+ return i;
+ }
+ for (j = 0; !(pattern & 1); j++) pattern >>= 1;
+ buf[i++] = j;
+ }
+}
+
+
+class l2elem {
+ public:
+ l2elem* next;
+ l2elem* prev;
+
+ void link_after(l2elem* after) {
+ (next = after->next)->prev = this;
+ (prev = after)->next = this;
+ }
+ void unlink() {
+ prev->next = next;
+ next->prev = prev;
+ }
+ void prune() {
+ next = prev = this;
+ }
+};
+
+class l2list : public l2elem {
+ public:
+ l2list() { prune(); }
+};
+
+class pen_cache : public l2list {
+ class pen_cache_item : public l2elem {
+ public:
+ HPEN pen;
+ int color;
+ int width;
+ int style;
+ unsigned pattern;
+ };
+ pen_cache_item* free;
+ pen_cache_item cache[PEN_CACHE_SIZE];
+
+ public:
+ pen_cache() {
+ for (int i = 0; i < PEN_CACHE_SIZE-1; i++) {
+ cache[i].next = &cache[i+1];
+ }
+ cache[PEN_CACHE_SIZE-1].next = NULL;
+ free = cache;
+ }
+ void select(int color)
+ {
+ for (l2elem* elem = next; elem != this; elem = elem->next) {
+ pen_cache_item* ci = (pen_cache_item*)elem;
+ if (ci->color == color &&
+ ci->style == line_settings.linestyle &&
+ ci->width == line_settings.thickness &&
+ (line_settings.linestyle != USERBIT_LINE
+ || line_settings.upattern == ci->pattern))
+ {
+ ci->unlink(); // LRU discipline
+ ci->link_after(this);
+
+ if (hPen != ci->pen) {
+ hPen = ci->pen;
+ SelectObject(hdc[0], hPen);
+ SelectObject(hdc[1], hPen);
+ }
+ return;
+ }
+ }
+ hPen = NULL;
+ if (line_settings.linestyle == USERBIT_LINE) {
+ LOGBRUSH lb;
+ lb.lbColor = PALETTEINDEX(color);
+ lb.lbStyle = BS_SOLID;
+ DWORD style[32];
+ hPen = ExtCreatePen(PS_GEOMETRIC|PS_USERSTYLE,
+ line_settings.thickness, &lb,
+ convert_userbits(style,line_settings.upattern),
+ style);
+ }
+ if (hPen == NULL) {
+ hPen = CreatePen(line_style_cnv[line_settings.linestyle],
+ line_settings.thickness,
+ PALETTEINDEX(color));
+ }
+ SelectObject(hdc[0], hPen);
+ SelectObject(hdc[1], hPen);
+
+ pen_cache_item* p;
+ if (free == NULL) {
+ p = (pen_cache_item*)prev;
+ p->unlink();
+ DeleteObject(p->pen);
+ } else {
+ p = free;
+ free = (pen_cache_item*)p->next;
+ }
+ p->pen = hPen;
+ p->color = color;
+ p->width = line_settings.thickness;
+ p->style = line_settings.linestyle;
+ p->pattern = line_settings.upattern;
+ p->link_after(this);
+ }
+};
+
+
+static pen_cache pcache;
+
+
+
+class font_cache : public l2list {
+ class font_cache_item : public l2elem {
+ public:
+ HFONT font;
+ int type;
+ int direction;
+ int width, height;
+ };
+ font_cache_item* free;
+ font_cache_item cache[FONT_CACHE_SIZE];
+
+ public:
+ font_cache() {
+ for (int i = 0; i < FONT_CACHE_SIZE-1; i++) {
+ cache[i].next = &cache[i+1];
+ }
+ cache[FONT_CACHE_SIZE-1].next = NULL;
+ free = cache;
+ }
+ void select(int type, int direction, int width, int height)
+ {
+ for (l2elem* elem = next; elem != this; elem = elem->next) {
+ font_cache_item* ci = (font_cache_item*)elem;
+ if (ci->type == type &&
+ ci->direction == direction &&
+ ci->width == width &&
+ ci->height == height)
+ {
+ ci->unlink();
+ ci->link_after(this);
+
+ if (hFont != ci->font) {
+ hFont = ci->font;
+ SelectObject(hdc[0], hFont);
+ SelectObject(hdc[1], hFont);
+ }
+ return;
+ }
+ }
+ hFont = CreateFont(-height,
+ width,
+ direction*900,
+ (direction&1)*900,
+ font_weight[type],
+ FALSE,
+ FALSE,
+ FALSE,
+ DEFAULT_CHARSET,
+ OUT_DEFAULT_PRECIS,
+ CLIP_DEFAULT_PRECIS,
+ DEFAULT_QUALITY,
+ font_family[type],
+ font_name[type]);
+ SelectObject(hdc[0], hFont);
+ SelectObject(hdc[1], hFont);
+
+ font_cache_item* p;
+ if (free == NULL) {
+ p = (font_cache_item*)prev;
+ p->unlink();
+ DeleteObject(p->font);
+ } else {
+ p = free;
+ free = (font_cache_item*)p->next;
+ }
+ p->font = hFont;
+ p->type = type;
+ p->width = width;
+ p->height = height;
+ p->direction = direction;
+ p->link_after(this);
+ }
+};
+
+
+static font_cache fcache;
+
+
+#define FLAGS PC_NOCOLLAPSE
+#define PALETTE_SIZE 256
+
+static PALETTEENTRY BGIcolor[64] = {
+ { 0, 0, 0, FLAGS }, // 0
+ { 0, 0, 255, FLAGS }, // 1
+ { 0, 255, 0, FLAGS }, // 2
+ { 0, 255, 255, FLAGS }, // 3
+ { 255, 0, 0, FLAGS }, // 4
+ { 255, 0, 255, FLAGS }, // 5
+ { 165, 42, 42, FLAGS }, // 6
+ { 211, 211, 211, FLAGS }, // 7
+ { 47, 79, 79, FLAGS }, // 8
+ { 173, 216, 230, FLAGS }, // 9
+ { 32, 178, 170, FLAGS }, // 10
+ { 224, 255, 255, FLAGS }, // 11
+ { 240, 128, 128, FLAGS }, // 12
+ { 219, 112, 147, FLAGS }, // 13
+ { 255, 255, 0, FLAGS }, // 14
+ { 255, 255, 255, FLAGS }, // 15
+ { 0xF0, 0xF8, 0xFF, FLAGS }, // 16
+ { 0xFA, 0xEB, 0xD7, FLAGS }, // 17
+ { 0x22, 0x85, 0xFF, FLAGS }, // 18
+ { 0x7F, 0xFF, 0xD4, FLAGS }, // 19
+ { 0xF0, 0xFF, 0xFF, FLAGS }, // 20
+ { 0xF5, 0xF5, 0xDC, FLAGS }, // 21
+ { 0xFF, 0xE4, 0xC4, FLAGS }, // 22
+ { 0xFF, 0x7B, 0xCD, FLAGS }, // 23
+ { 0x00, 0x00, 0xFF, FLAGS }, // 24
+ { 0x8A, 0x2B, 0xE2, FLAGS }, // 25
+ { 0xA5, 0x2A, 0x2A, FLAGS }, // 26
+ { 0xDE, 0xB8, 0x87, FLAGS }, // 27
+ { 0x5F, 0x9E, 0xA0, FLAGS }, // 28
+ { 0x7F, 0xFF, 0x00, FLAGS }, // 29
+ { 0xD2, 0x50, 0x1E, FLAGS }, // 30
+ { 0xFF, 0x7F, 0x50, FLAGS }, // 31
+ { 0x64, 0x95, 0xED, FLAGS }, // 32
+ { 0xFF, 0xF8, 0xDC, FLAGS }, // 33
+ { 0xDC, 0x14, 0x3C, FLAGS }, // 34
+ { 0x68, 0xCF, 0xDF, FLAGS }, // 35
+ { 0x00, 0x00, 0x8B, FLAGS }, // 36
+ { 0x00, 0x8B, 0x8B, FLAGS }, // 37
+ { 0xB8, 0x86, 0x0B, FLAGS }, // 38
+ { 0xA9, 0xA9, 0xA9, FLAGS }, // 39
+ { 0x00, 0x64, 0x00, FLAGS }, // 40
+ { 0xBD, 0xB7, 0x6B, FLAGS }, // 41
+ { 0x8B, 0x00, 0x8B, FLAGS }, // 42
+ { 0x55, 0x6B, 0x2F, FLAGS }, // 43
+ { 0xFF, 0x8C, 0x00, FLAGS }, // 44
+ { 0xB9, 0x82, 0xFC, FLAGS }, // 45
+ { 0x8B, 0x00, 0x00, FLAGS }, // 46
+ { 0xE9, 0x96, 0x7A, FLAGS }, // 47
+ { 0x8F, 0xBC, 0x8F, FLAGS }, // 48
+ { 0x48, 0x3D, 0x8B, FLAGS }, // 49
+ { 0x2F, 0x4F, 0x4F, FLAGS }, // 50
+ { 0x00, 0xCE, 0xD1, FLAGS }, // 51
+ { 0x94, 0x00, 0xD3, FLAGS }, // 52
+ { 0xFF, 0x14, 0x93, FLAGS }, // 53
+ { 0x00, 0xBF, 0xFF, FLAGS }, // 54
+ { 0x69, 0x69, 0x69, FLAGS }, // 55
+ { 0x1E, 0x90, 0xFF, FLAGS }, // 56
+ { 0xB2, 0x22, 0x22, FLAGS }, // 57
+ { 0xFF, 0xFA, 0xF0, FLAGS }, // 58
+ { 0x22, 0x8B, 0x22, FLAGS }, // 59
+ { 0xFF, 0x00, 0xFF, FLAGS }, // 60
+ { 0xDC, 0xDC, 0xDC, FLAGS }, // 61
+ { 0xF8, 0xF8, 0xBF, FLAGS }, // 62
+ { 0xFF, 0xD7, 0x00, FLAGS }, // 63
+};
+
+static PALETTEENTRY BGIpalette[64];
+
+static short SolidBrushBitmap[8] =
+ {~0xFF, ~0xFF, ~0xFF, ~0xFF, ~0xFF, ~0xFF, ~0xFF, ~0xFF};
+static short LineBrushBitmap[8] =
+ {~0x00, ~0x00, ~0x00, ~0x00, ~0x00, ~0x00, ~0x00, ~0xFF};
+static short LtslashBrushBitmap[8] =
+ {~0x01, ~0x02, ~0x04, ~0x08, ~0x10, ~0x20, ~0x40, ~0x80};
+static short SlashBrushBitmap[8] =
+ {~0x81, ~0x03, ~0x06, ~0x0C, ~0x18, ~0x30, ~0x60, ~0xC0};
+static short BkslashBrushBitmap[8] =
+ {~0xC0, ~0x60, ~0x30, ~0x18, ~0x0C, ~0x06, ~0x03, ~0x81};
+static short LtbkslashBrushBitmap[8] =
+ {~0x80, ~0x40, ~0x20, ~0x10, ~0x08, ~0x04, ~0x02, ~0x01};
+static short HatchBrushBitmap[8] =
+ {~0x01, ~0x01, ~0x01, ~0x01, ~0x01, ~0x01, ~0x01, ~0xFF};
+static short XhatchBrushBitmap[8] =
+ {~0x81, ~0x42, ~0x24, ~0x18, ~0x18, ~0x24, ~0x42, ~0x81};
+static short InterleaveBrushBitmap[8] =
+ {~0x55, ~0xAA, ~0x55, ~0xAA, ~0x55, ~0xAA, ~0x55, ~0xAA};
+static short WidedotBrushBitmap[8] =
+ {~0x00, ~0x00, ~0x00, ~0x00, ~0x00, ~0x00, ~0x00, ~0x01};
+static short ClosedotBrushBitmap[8] =
+ {~0x44, ~0x00, ~0x11, ~0x00, ~0x44, ~0x00, ~0x11, ~0x00};
+
+char* grapherrormsg(int code) {
+ static char buf[256];
+ FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM,
+ NULL, code, 0,
+ buf, sizeof buf, NULL);
+ return buf;
+}
+
+static int gdi_error_code;
+
+int graphresult()
+{
+ return gdi_error_code;
+}
+
+void setrgbcolor(int r, int g, int b)
+{
+// c &= MAXCOLORS;
+// color = c;
+ PALETTEENTRY col;
+ col.peBlue = r & 0xFF;
+ col.peGreen = g & 0xFF;
+ col.peRed = b & 0xFC;
+ col.peFlags = FLAGS;
+ SetPaletteEntries(hPalette, BG+1, 1, &col);
+ RealizePalette(hdc[0]);
+ RealizePalette(hdc[1]);
+ color = 1;
+ SetTextColor(hdc[0], PALETTEINDEX(BG+1));
+ SetTextColor(hdc[1], PALETTEINDEX(BG+1));
+}
+
+void setrgbrand(double rd, double gd, double bd)
+{
+ int r=rd, g=gd, b=bd;
+ if (rand() <= (rd-r)*RAND_MAX) r += 1;
+ if (rand() <= (gd-g)*RAND_MAX) g += 1;
+ if (rand() <= (bd-b)*RAND_MAX) b += 1;
+ setrgbcolor(r,g,b);
+}
+
+
+void setcolor(double c)
+{
+ c *= 4;
+ if (c < 0) c = 0;
+ if (c < 1) { setrgbrand(255,sin(c*pi/2)*255,0); return; }
+ c -= 1;
+ if (c < 1) { setrgbrand(cos(c*pi/2)*255,255,0); return; }
+ c -= 1;
+ if (c < 1) { setrgbrand(0,255,sin(c*pi/2)*255); return; }
+ c -= 1;
+ if (c > 1) c=1;
+ { setrgbrand(0,cos(c*pi/2)*255,255); return; }
+}
+
+void setgray(double c)
+{
+ if (c < 0) c = 0;
+ if (c > 1) c = 1;
+ setrgbrand(c*255,c*255,c*255);
+}
+
+int getmaxcolor()
+{
+ return WHITE;
+}
+
+int getmaxmode()
+{
+ return VGAMAX;
+}
+
+char* getmodename(int mode)
+{
+ static char mode_str[32];
+ sprintf(mode_str, "%d x %d %s", window_width, window_height,
+ mode < 2 ? "EGA" : "VGA");
+ return mode_str;
+}
+
+int getx()
+{
+ POINT pos;
+ GetCurrentPositionEx(hdc[active_page == visual_page ? 0 : 1], &pos);
+ return pos.x;
+}
+
+int gety()
+{
+ POINT pos;
+ GetCurrentPositionEx(hdc[active_page == visual_page ? 0 : 1], &pos);
+ return pos.y;
+}
+
+int getmaxx()
+{
+ return window_width-1;
+}
+
+int getmaxy()
+{
+ return window_height-1;
+}
+
+
+int getcolor()
+{
+ return color;
+}
+
+char* getdrivername()
+{
+ return "EGAVGA";
+}
+
+void setlinestyle(int style, unsigned int pattern, int thickness)
+{
+ line_settings.linestyle = style;
+ line_settings.thickness = thickness;
+ line_settings.upattern = pattern;
+}
+
+void getlinesettings(linesettingstype* ls)
+{
+ *ls = line_settings;
+}
+
+void setwritemode(int mode)
+{
+ write_mode = mode;
+}
+
+void setpalette(int index, int color)
+{
+ color &= MAXCOLORS;
+ BGIpalette[index] = BGIcolor[color];
+ current_palette.colors[index] = color;
+ SetPaletteEntries(hPalette, BG+index, 1, &BGIpalette[index]);
+ RealizePalette(hdc[0]);
+ if (index == 0) {
+ bkcolor = 0;
+ }
+}
+
+void setrgbpalette(int index, int red, int green, int blue)
+{
+ BGIpalette[index].peRed = red & 0xFC;
+ BGIpalette[index].peGreen = green & 0xFC;
+ BGIpalette[index].peBlue = blue & 0xFC;
+ SetPaletteEntries(hPalette, BG+index, 1, &BGIpalette[index]);
+ RealizePalette(hdc[0]);
+ if (index == 0) {
+ bkcolor = 0;
+ }
+}
+
+void setallpalette(palettetype* pal)
+{
+ for (int i = 0; i < pal->size; i++) {
+ current_palette.colors[i] = pal->colors[i] & MAXCOLORS;
+ BGIpalette[i] = BGIcolor[pal->colors[i] & MAXCOLORS];
+ }
+ SetPaletteEntries(hPalette, BG, pal->size, BGIpalette);
+ RealizePalette(hdc[0]);
+ bkcolor = 0;
+}
+
+palettetype* getdefaultpalette()
+{
+ static palettetype default_palette = { 64,
+ { BLACK, BLUE, GREEN, CYAN, RED, MAGENT, BROWN, LIGHTGRAY, DARKGRAY,
+ LIGHTBLUE, LIGHTGREEN, LIGHTCYAN, LIGHTRED, LIGHTMAGENTA, YELLOW, WHITE,
+ 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32,
+ 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49,
+ 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63
+ }};
+ return &default_palette;
+}
+
+void getpalette(palettetype* pal)
+{
+ *pal = current_palette;
+}
+
+int getpalettesize()
+{
+ return MAXCOLORS+1;
+}
+
+void setbkcolor(int color)
+{
+ color &= MAXCOLORS;
+ BGIpalette[0] = BGIcolor[color];
+ SetPaletteEntries(hPalette, BG, 1, &BGIpalette[0]);
+ RealizePalette(hdc[0]);
+ bkcolor = color;
+}
+
+int getbkcolor()
+{
+ return bkcolor;
+}
+
+void setfillstyle(int style, int color)
+{
+ fill_settings.pattern = style;
+ fill_settings.color = color & MAXCOLORS;
+ SelectObject(hdc[0], hBrush[style]);
+ SelectObject(hdc[1], hBrush[style]);
+}
+
+void getfillsettings(fillsettingstype* fs)
+{
+ *fs = fill_settings;
+}
+
+static fillpatterntype userfillpattern =
+{-1, -1, -1, -1, -1, -1, -1, -1};
+
+void setfillpattern(char const* upattern, int color)
+{
+ static HBITMAP hFillBitmap;
+ static short bitmap_data[8];
+ for (int i = 0; i < 8; i++) {
+ bitmap_data[i] = (unsigned char)~upattern[i];
+ userfillpattern[i] = upattern[i];
+ }
+ HBITMAP h = CreateBitmap(8, 8, 1, 1, bitmap_data);
+ HBRUSH hb = CreatePatternBrush(h);
+ DeleteObject(hBrush[USER_FILL]);
+ if (hFillBitmap) {
+ DeleteObject(hFillBitmap);
+ }
+ hFillBitmap = h;
+ hBrush[USER_FILL] = hb;
+ SelectObject(hdc[0], hb);
+ SelectObject(hdc[1], hb);
+ fill_settings.color = color & MAXCOLORS;
+ fill_settings.pattern = USER_FILL;
+}
+
+void getfillpattern(fillpatterntype fp)
+{
+ memcpy(fp, userfillpattern, sizeof userfillpattern);
+}
+
+
+inline void select_fill_color()
+{
+ if (text_color != fill_settings.color) {
+ text_color = fill_settings.color;
+ SetTextColor(hdc[0], PALETTEINDEX(text_color+BG));
+ SetTextColor(hdc[1], PALETTEINDEX(text_color+BG));
+ }
+}
+
+void setusercharsize(int multx, int divx, int multy, int divy)
+{
+ font_mul_x = multx;
+ font_div_x = divx;
+ font_mul_y = multy;
+ font_div_y = divy;
+ text_settings.charsize = 0;
+}
+
+void moveto(int x, int y)
+{
+ if (bgiemu_handle_redraw || visual_page != active_page) {
+ MoveToEx(hdc[1], x, y, NULL);
+ }
+ if (visual_page == active_page) {
+ MoveToEx(hdc[0], x, y, NULL);
+ }
+}
+
+void moverel(int dx, int dy)
+{
+ POINT pos;
+ GetCurrentPositionEx(hdc[1], &pos);
+ moveto(pos.x + dx, pos.y + dy);
+}
+
+static void select_font()
+{
+ if (text_settings.charsize == 0) {
+ fcache.select(text_settings.font, text_settings.direction,
+ font_metrics[text_settings.font]
+ [normal_font_size[text_settings.font]].width
+ *font_mul_x/font_div_x,
+ font_metrics[text_settings.font]
+ [normal_font_size[text_settings.font]].height
+ *font_mul_y/font_div_y);
+ } else {
+ fcache.select(text_settings.font, text_settings.direction,
+ font_metrics[text_settings.font][text_settings.charsize].width,
+ font_metrics[text_settings.font][text_settings.charsize].height);
+ }
+}
+
+static void text_output(int x, int y, const char* str)
+{
+ select_font();
+ if (text_color != color) {
+ text_color = color;
+ SetTextColor(hdc[0], PALETTEINDEX(text_color+BG));
+ SetTextColor(hdc[1], PALETTEINDEX(text_color+BG));
+ }
+ if (bgiemu_handle_redraw || visual_page != active_page) {
+ TextOut(hdc[1], x, y, str, strlen(str));
+ }
+ if (visual_page == active_page) {
+ TextOut(hdc[0], x, y, str, strlen(str));
+ }
+}
+
+
+void settextstyle(int font, int direction, int char_size)
+{
+ if (char_size > 10) {
+ char_size = 10;
+ }
+ text_settings.direction = direction;
+ text_settings.font = font;
+ text_settings.charsize = char_size;
+ text_align_mode = ALIGN_NOT_SET;
+}
+
+void settextjustify(int horiz, int vert)
+{
+ text_settings.horiz = horiz;
+ text_settings.vert = vert;
+ text_align_mode = ALIGN_NOT_SET;
+}
+
+void gettextsettings(textsettingstype* ts)
+{
+ *ts = text_settings;
+}
+
+
+int textheight(const char* str)
+{
+ SIZE ss;
+ select_font();
+ GetTextExtentPoint32(hdc[0], str, strlen(str), &ss);
+ return ss.cy;
+}
+
+int textwidth(const char* str)
+{
+ SIZE ss;
+ select_font();
+ GetTextExtentPoint32(hdc[0], str, strlen(str), &ss);
+ return ss.cx;
+}
+
+void outtext(const char* str)
+{
+ if (text_align_mode != UPDATE_CP) {
+ text_align_mode = UPDATE_CP;
+ int align = (text_settings.direction == HORIZ_DIR)
+ ? (TA_UPDATECP |
+ text_halign_cnv[text_settings.horiz] |
+ text_valign_cnv[text_settings.vert])
+ : (TA_UPDATECP |
+ text_valign_cnv[text_settings.horiz] |
+ text_halign_cnv[text_settings.vert]);
+ SetTextAlign(hdc[0], align);
+ SetTextAlign(hdc[1], align);
+ }
+ text_output(0, 0, str);
+}
+
+void outtextxy(int x, int y, const char* str)
+{
+ if (text_align_mode != NOT_UPDATE_CP) {
+ text_align_mode = NOT_UPDATE_CP;
+ int align = (text_settings.direction == HORIZ_DIR)
+ ? (TA_NOUPDATECP |
+ text_halign_cnv[text_settings.horiz] |
+ text_valign_cnv[text_settings.vert])
+ : (TA_NOUPDATECP |
+ text_valign_cnv[text_settings.horiz] |
+ text_halign_cnv[text_settings.vert]);
+ SetTextAlign(hdc[0], align);
+ SetTextAlign(hdc[1], align);
+ }
+ text_output(x, y, str);
+}
+
+void setviewport(int x1, int y1, int x2, int y2, int clip)
+{
+ view_settings.left = x1;
+ view_settings.top = y1;
+ view_settings.right = x2;
+ view_settings.bottom = y2;
+ view_settings.clip = clip;
+
+ if (hRgn) {
+ DeleteObject(hRgn);
+ }
+ hRgn = clip ? CreateRectRgn(x1, y1, x2, y2) : NULL;
+ SelectClipRgn(hdc[1], hRgn);
+ SetViewportOrgEx(hdc[1], x1, y1, NULL);
+
+ SelectClipRgn(hdc[0], hRgn);
+ SetViewportOrgEx(hdc[0], x1, y1, NULL);
+
+ moveto(0,0);
+}
+
+void getviewsettings(viewporttype *viewport)
+{
+ *viewport = view_settings;
+}
+
+inline void arc_coords(double angle, double rx, double ry, int& x, int& y)
+{
+ if (rx == 0 || ry == 0) {
+ x = y = 0;
+ return;
+ }
+ double s = sin(angle*pi/180.0);
+ double c = cos(angle*pi/180.0);
+ if (fabs(s) < fabs(c)) {
+ double tg = s/c;
+ double xr = sqrt((double)rx*rx*ry*ry/(ry*ry+rx*rx*tg*tg));
+ x = int((c >= 0) ? xr : -xr);
+ y = int((s >= 0) ? -xr*tg : xr*tg);
+ } else {
+ double ctg = c/s;
+ double yr = sqrt((double)rx*rx*ry*ry/(rx*rx+ry*ry*ctg*ctg));
+ x = int((c >= 0) ? yr*ctg : -yr*ctg);
+ y = int((s >= 0) ? -yr : yr);
+ }
+}
+
+void ellipse(int x, int y, int start_angle, int end_angle,
+ int rx, int ry)
+{
+ ac.x = x;
+ ac.y = y;
+ arc_coords(start_angle, rx, ry, ac.xstart, ac.ystart);
+ arc_coords(end_angle, rx, ry, ac.xend, ac.yend);
+ ac.xstart += x; ac.ystart += y;
+ ac.xend += x; ac.yend += y;
+
+ pcache.select(color+BG);
+ if (bgiemu_handle_redraw || visual_page != active_page) {
+ Arc(hdc[1], x-rx, y-ry, x+rx, y+ry,
+ ac.xstart, ac.ystart, ac.xend, ac.yend);
+ }
+ if (visual_page == active_page) {
+ Arc(hdc[0], x-rx, y-ry, x+rx, y+ry,
+ ac.xstart, ac.ystart, ac.xend, ac.yend);
+ }
+}
+
+void fillellipse(int x, int y, int rx, int ry)
+{
+ pcache.select(color+BG);
+ select_fill_color();
+ if (bgiemu_handle_redraw || visual_page != active_page) {
+ Ellipse(hdc[1], x-rx, y-ry, x+rx, y+ry);
+ }
+ if (visual_page == active_page) {
+ Ellipse(hdc[0], x-rx, y-ry, x+rx, y+ry);
+ }
+}
+
+static void allocate_new_graphic_page(int page)
+{
+ RECT scr;
+ scr.left = -view_settings.left;
+ scr.top = -view_settings.top;
+ scr.right = screen_width-view_settings.left-1;
+ scr.bottom = screen_height-view_settings.top-1;
+ hBitmap[page] = CreateCompatibleBitmap(hdc[0],screen_width,screen_height);
+ SelectObject(hdc[1], hBitmap[page]);
+ SelectClipRgn(hdc[1], NULL);
+ FillRect(hdc[1], &scr, hBackgroundBrush);
+ SelectClipRgn(hdc[1], hRgn);
+}
+
+void setactivepage(int page)
+{
+ if (hBitmap[page] == NULL) {
+ allocate_new_graphic_page(page);
+ } else {
+ SelectObject(hdc[1], hBitmap[page]);
+ }
+ if (!bgiemu_handle_redraw && active_page == visual_page) {
+ POINT pos;
+ GetCurrentPositionEx(hdc[0], &pos);
+ MoveToEx(hdc[1], pos.x, pos.y, NULL);
+ }
+ active_page = page;
+}
+
+
+void setvisualpage(int page)
+{
+ POINT pos;
+ if (hdc[page] == NULL) {
+ allocate_new_graphic_page(page);
+ }
+ if (!bgiemu_handle_redraw && active_page == visual_page) {
+ SelectObject(hdc[1], hBitmap[visual_page]);
+ SelectClipRgn(hdc[1], NULL);
+ BitBlt(hdc[1], -view_settings.left, -view_settings.top,
+ window_width, window_height,
+ hdc[0], -view_settings.left, -view_settings.top,
+ SRCCOPY);
+ SelectClipRgn(hdc[1], hRgn);
+ GetCurrentPositionEx(hdc[0], &pos);
+ MoveToEx(hdc[1], pos.x, pos.y, NULL);
+ }
+ SelectClipRgn(hdc[0], NULL);
+ SelectClipRgn(hdc[1], NULL);
+ SelectObject(hdc[1], hBitmap[page]);
+ BitBlt(hdc[0], -view_settings.left,
+ -view_settings.top, window_width, window_height,
+ hdc[1], -view_settings.left, -view_settings.top, SRCCOPY);
+ SelectClipRgn(hdc[0], hRgn);
+ SelectClipRgn(hdc[1], hRgn);
+
+ if (page != active_page) {
+ SelectObject(hdc[1], hBitmap[active_page]);
+ }
+ if (active_page != visual_page) {
+ GetCurrentPositionEx(hdc[1], &pos);
+ MoveToEx(hdc[0], pos.x, pos.y, NULL);
+ }
+ visual_page = page;
+}
+
+
+void setaspectratio(int ax, int ay)
+{
+ aspect_ratio_x = ax;
+ aspect_ratio_y = ay;
+}
+
+void getaspectratio(int* ax, int* ay)
+{
+ *ax = aspect_ratio_x;
+ *ay = aspect_ratio_y;
+}
+
+void circle(double x, double y, int radius)
+{
+ x=x*scale_x+scale_dx;
+ y=y*scale_y+scale_dy;
+
+ pcache.select(color+BG);
+ int ry = (unsigned)radius*aspect_ratio_x/aspect_ratio_y;
+ int rx = radius;
+ if (bgiemu_handle_redraw || visual_page != active_page) {
+ Arc(hdc[1], x-rx, y-ry, x+rx, y+ry, x+rx, y, x+rx, y);
+ }
+ if (visual_page == active_page) {
+ Arc(hdc[0], x-rx, y-ry, x+rx, y+ry, x+rx, y, x+rx, y);
+ }
+}
+
+void circle_s(double x, double y, double radx, double rady)
+{
+ x=x*scale_x+scale_dx;
+ y=y*scale_y+scale_dy;
+
+ pcache.select(color+BG);
+ int ry = rady * scale_y;
+ int rx = radx * scale_x;
+ if (bgiemu_handle_redraw || visual_page != active_page) {
+ Arc(hdc[1], x-rx, y-ry, x+rx, y+ry, x+rx, y, x+rx, y);
+ }
+ if (visual_page == active_page) {
+ Arc(hdc[0], x-rx, y-ry, x+rx, y+ry, x+rx, y, x+rx, y);
+ }
+}
+
+
+void arc(int x, int y, int start_angle, int end_angle, int radius)
+{
+ ac.x = x;
+ ac.y = y;
+ ac.xstart = x + int(radius*cos(start_angle*pi/180.0));
+ ac.ystart = y - int(radius*sin(start_angle*pi/180.0));
+ ac.xend = x + int(radius*cos(end_angle*pi/180.0));
+ ac.yend = y - int(radius*sin(end_angle*pi/180.0));
+
+ if (bgiemu_handle_redraw || visual_page != active_page) {
+ Arc(hdc[1], x-radius, y-radius, x+radius, y+radius,
+ ac.xstart, ac.ystart, ac.xend, ac.yend);
+ }
+ if (visual_page == active_page) {
+ Arc(hdc[0], x-radius, y-radius, x+radius, y+radius,
+ ac.xstart, ac.ystart, ac.xend, ac.yend);
+ }
+}
+
+void getarccoords(arccoordstype *arccoords)
+{
+ *arccoords = ac;
+}
+
+void pieslice(int x, int y, int start_angle, int end_angle,
+ int radius)
+{
+ pcache.select(color+BG);
+ select_fill_color();
+ ac.x = x;
+ ac.y = y;
+ ac.xstart = x + int(radius*cos(start_angle*pi/180.0));
+ ac.ystart = y - int(radius*sin(start_angle*pi/180.0));
+ ac.xend = x + int(radius*cos(end_angle*pi/180.0));
+ ac.yend = y - int(radius*sin(end_angle*pi/180.0));
+
+ if (bgiemu_handle_redraw || visual_page != active_page) {
+ Pie(hdc[1], x-radius, y-radius, x+radius, y+radius,
+ ac.xstart, ac.ystart, ac.xend, ac.yend);
+ }
+ if (visual_page == active_page) {
+ Pie(hdc[0], x-radius, y-radius, x+radius, y+radius,
+ ac.xstart, ac.ystart, ac.xend, ac.yend);
+ }
+}
+
+
+void sector(int x, int y, int start_angle, int end_angle,
+ int rx, int ry)
+{
+ ac.x = x;
+ ac.y = y;
+ arc_coords(start_angle, rx, ry, ac.xstart, ac.ystart);
+ arc_coords(end_angle, rx, ry, ac.xend, ac.yend);
+ ac.xstart += x; ac.ystart += y;
+ ac.xend += x; ac.yend += y;
+
+ pcache.select(color+BG);
+ if (bgiemu_handle_redraw || visual_page != active_page) {
+ Pie(hdc[1], x-rx, y-ry, x+rx, y+ry,
+ ac.xstart, ac.ystart, ac.xend, ac.yend);
+ }
+ if (visual_page == active_page) {
+ Pie(hdc[0], x-rx, y-ry, x+rx, y+ry,
+ ac.xstart, ac.ystart, ac.xend, ac.yend);
+ }
+}
+
+void bar(int left, int top, int right, int bottom)
+{
+ RECT r;
+ if (left > right) { /* Turbo C corrects for badly ordered corners */
+ r.left = right;
+ r.right = left;
+ } else {
+ r.left = left;
+ r.right = right;
+ }
+ if (bottom < top) { /* Turbo C corrects for badly ordered corners */
+ r.top = bottom;
+ r.bottom = top;
+ } else {
+ r.top = top;
+ r.bottom = bottom;
+ }
+ select_fill_color();
+ if (bgiemu_handle_redraw || visual_page != active_page) {
+ FillRect(hdc[1], &r, hBrush[fill_settings.pattern]);
+ }
+ if (visual_page == active_page) {
+ FillRect(hdc[0], &r, hBrush[fill_settings.pattern]);
+ }
+}
+
+
+void bar3d(int left, int top, int right, int bottom, int depth, int topflag)
+{
+ int temp;
+ const double tan30 = 1.0/1.73205080756887729352;
+ if (left > right) { /* Turbo C corrects for badly ordered corners */
+ temp = left;
+ left = right;
+ right = temp;
+ }
+ if (bottom < top) {
+ temp = bottom;
+ bottom = top;
+ top = temp;
+ }
+ bar(left+line_settings.thickness, top+line_settings.thickness,
+ right-line_settings.thickness+1, bottom-line_settings.thickness+1);
+
+ if (write_mode != COPY_PUT) {
+ SetROP2(hdc[0], write_mode_cnv[write_mode]);
+ SetROP2(hdc[1], write_mode_cnv[write_mode]);
+ }
+ pcache.select(ADJUSTED_MODE(write_mode) ? color : color + BG);
+ int dy = int(depth*tan30);
+ POINT p[11];
+ p[0].x = right, p[0].y = bottom;
+ p[1].x = right, p[1].y = top;
+ p[2].x = left, p[2].y = top;
+ p[3].x = left, p[3].y = bottom;
+ p[4].x = right, p[4].y = bottom;
+ p[5].x = right+depth, p[5].y = bottom-dy;
+ p[6].x = right+depth, p[6].y = top-dy;
+ p[7].x = right, p[7].y = top;
+
+ if (topflag) {
+ p[8].x = right+depth, p[8].y = top-dy;
+ p[9].x = left+depth, p[9].y = top-dy;
+ p[10].x = left, p[10].y = top;
+ }
+ if (bgiemu_handle_redraw || visual_page != active_page) {
+ Polyline(hdc[1], p, topflag ? 11 : 8);
+ }
+ if (visual_page == active_page) {
+ Polyline(hdc[0], p, topflag ? 11 : 8);
+ }
+ if (write_mode != COPY_PUT) {
+ SetROP2(hdc[0], R2_COPYPEN);
+ SetROP2(hdc[1], R2_COPYPEN);
+ }
+}
+
+void lineto_old(int x, int y)
+{
+ if (write_mode != COPY_PUT) {
+ SetROP2(hdc[0], write_mode_cnv[write_mode]);
+ SetROP2(hdc[1], write_mode_cnv[write_mode]);
+ }
+ pcache.select(ADJUSTED_MODE(write_mode) ? color : color + BG);
+ if (bgiemu_handle_redraw || visual_page != active_page) {
+ LineTo(hdc[1], x, y);
+ }
+ if (visual_page == active_page) {
+ LineTo(hdc[0], x, y);
+ }
+ if (write_mode != COPY_PUT) {
+ SetROP2(hdc[0], R2_COPYPEN);
+ SetROP2(hdc[1], R2_COPYPEN);
+ }
+}
+
+void linerel(int dx, int dy)
+{
+ POINT pos;
+ GetCurrentPositionEx(hdc[1], &pos);
+ lineto_old(pos.x + dx, pos.y + dy);
+}
+
+void drawpoly(int n_points, int* points)
+{
+ if (write_mode != COPY_PUT) {
+ SetROP2(hdc[0], write_mode_cnv[write_mode]);
+ SetROP2(hdc[1], write_mode_cnv[write_mode]);
+ }
+ pcache.select(ADJUSTED_MODE(write_mode) ? color : color + BG);
+
+ if (bgiemu_handle_redraw || visual_page != active_page) {
+ Polyline(hdc[1], (POINT*)points, n_points);
+ }
+ if (visual_page == active_page) {
+ Polyline(hdc[0], (POINT*)points, n_points);
+ }
+
+ if (write_mode != COPY_PUT) {
+ SetROP2(hdc[0], R2_COPYPEN);
+ SetROP2(hdc[1], R2_COPYPEN);
+ }
+}
+
+double to_x,to_y;
+int to_r=1;
+void lineto(double x0, double y0)
+{
+ if (!to_r) {
+ line(to_x,to_y,x0,y0);
+ }
+ to_r=0;
+ to_x=x0;
+ to_y=y0;
+}
+void reset()
+{
+ to_r=1;
+}
+
+inline double x_scale( double x) { return x*scale_x+scale_dx; }
+inline double y_scale( double y) {
+ if (scale_y_log) {
+ return log10(y)*scale_y+scale_dy;
+ } else {
+ return y*scale_y+scale_dy;
+ }
+}
+
+void xy_scale( double * x, double * y) {
+ *x = x_scale(*x);
+ *y = y_scale(*y);
+}
+
+void line(double x0, double y0, double x1, double y1)
+{
+ xy_scale(&x0,&y0);
+ xy_scale(&x1,&y1);
+ POINT line[2];
+ line[0].x = x0;
+ line[0].y = y0;
+ line[1].x = x1;
+ line[1].y = y1;
+ drawpoly(2, (int*)&line);
+}
+
+
+void polygon(double x[], double y[], int n)
+{
+ int *pt =new int [2*n];
+ for ( int i = 0; i < n; i++ ){
+ pt[2*i ] = x_scale(x[i]);
+ pt[2*i+1] = y_scale(y[i]);
+ }
+ fillpoly(n, pt);
+ delete[] pt;
+}
+
+
+void rectangle(int left, int top, int right, int bottom)
+{
+ POINT rect[5];
+ rect[0].x = left, rect[0].y = top;
+ rect[1].x = right, rect[1].y = top;
+ rect[2].x = right, rect[2].y = bottom;
+ rect[3].x = left, rect[3].y = bottom;
+ rect[4].x = left, rect[4].y = top;
+ drawpoly(5, (int*)&rect);
+}
+
+void fillpoly(int n_points, int* points)
+{
+ pcache.select(color+BG);
+ select_fill_color();
+ if (bgiemu_handle_redraw || visual_page != active_page) {
+ Polygon(hdc[1], (POINT*)points, n_points);
+ }
+ if (visual_page == active_page) {
+ Polygon(hdc[0], (POINT*)points, n_points);
+ }
+}
+
+void floodfill(int x, int y, int border)
+{
+ select_fill_color();
+ if (bgiemu_handle_redraw || visual_page != active_page) {
+ FloodFill(hdc[1], x, y, PALETTEINDEX(border+BG));
+ }
+ if (visual_page == active_page) {
+ FloodFill(hdc[0], x, y, PALETTEINDEX(border+BG));
+ }
+}
+
+
+
+static bool handle_input(bool wait = 0)
+{
+ MSG lpMsg;
+ if (wait ? GetMessage(&lpMsg, NULL, 0, 0)
+ : PeekMessage(&lpMsg, NULL, 0, 0, PM_REMOVE))
+ {
+ TranslateMessage(&lpMsg);
+ DispatchMessage(&lpMsg);
+ return true;
+ }
+ return false;
+}
+
+
+void delay(unsigned msec)
+{
+ timeout_expired = false;
+ SetTimer(hWnd, TIMER_ID, msec, NULL);
+ while (!timeout_expired) handle_input(true);
+}
+
+// The Mouse functions (1-Oct-2000, Matthew Weathers)
+bool mouseup() {
+ while (handle_input(false));
+ if (bMouseUp) {
+ bMouseUp=false;
+ return true;
+ } else {
+ return false;
+ }
+}
+bool mousedown() {
+ while (handle_input(false));
+ if (bMouseDown) {
+ bMouseDown=false;
+ return true;
+ } else {
+ return false;
+ }
+}
+void clearmouse() {
+ iClickedMouseX=0;
+ iClickedMouseY=0;
+ iCurrentMouseX=0;
+ iCurrentMouseY=0;
+ bMouseDown=false;
+ bMouseUp=false;
+}
+int mouseclickx() {
+ return iClickedMouseX;
+}
+int mouseclicky(){
+ return iClickedMouseY;
+}
+int mousecurrentx(){
+ return iCurrentMouseX;
+}
+int mousecurrenty(){
+ return iCurrentMouseY;
+}
+int whichmousebutton(){
+ return iWhichMouseButton;
+}
+
+int kbhit()
+{
+ while (handle_input(false));
+ return !kbd_queue.is_empty();
+}
+
+int getch()
+{
+ while (kbd_queue.is_empty()) handle_input(true);
+ return (unsigned char)kbd_queue.get();
+}
+
+void cleardevice()
+{
+ RECT scr;
+ scr.left = -view_settings.left;
+ scr.top = -view_settings.top;
+ scr.right = screen_width-view_settings.left-1;
+ scr.bottom = screen_height-view_settings.top-1;
+
+ if (bgiemu_handle_redraw || visual_page != active_page) {
+ if (hRgn != NULL) {
+ SelectClipRgn(hdc[1], NULL);
+ }
+ FillRect(hdc[1], &scr, hBackgroundBrush);
+ if (hRgn != NULL) {
+ SelectClipRgn(hdc[1], hRgn);
+ }
+ }
+ if (visual_page == active_page) {
+ if (hRgn != NULL) {
+ SelectClipRgn(hdc[0], NULL);
+ }
+ FillRect(hdc[0], &scr, hBackgroundBrush);
+ if (hRgn != NULL) {
+ SelectClipRgn(hdc[0], hRgn);
+ }
+ }
+ moveto(0,0);
+}
+
+void clearviewport()
+{
+ RECT scr;
+ scr.left = 0;
+ scr.top = 0;
+ scr.right = view_settings.right-view_settings.left;
+ scr.bottom = view_settings.bottom-view_settings.top;
+ if (bgiemu_handle_redraw || visual_page != active_page) {
+ FillRect(hdc[1], &scr, hBackgroundBrush);
+ }
+ if (visual_page == active_page) {
+ FillRect(hdc[0], &scr, hBackgroundBrush);
+ }
+ moveto(0,0);
+}
+
+void detectgraph(int *graphdriver, int *graphmode)
+{
+ *graphdriver = VGA;
+ *graphmode = bgiemu_default_mode;
+}
+
+int getgraphmode()
+{
+ return bgiemu_default_mode;
+}
+
+void setgraphmode(int) {}
+
+void putimage(int x, int y, void* image, int bitblt)
+{
+ BGIimage* bi = (BGIimage*)image;
+ static int putimage_width, putimage_height;
+
+ if (hPutimageBitmap == NULL ||
+ putimage_width < bi->width || putimage_height < bi->height)
+ {
+ if (putimage_width < bi->width) {
+ putimage_width = (bi->width+7) & ~7;
+ }
+ if (putimage_height < bi->height) {
+ putimage_height = bi->height;
+ }
+ HBITMAP h = CreateCompatibleBitmap(hdc[0], putimage_width,
+ putimage_height);
+ SelectObject(hdc[2], h);
+ if (hPutimageBitmap) {
+ DeleteObject(hPutimageBitmap);
+ }
+ hPutimageBitmap = h;
+ }
+ int mask = ADJUSTED_MODE(bitblt) ? 0 : BG;
+ for (int i = 0; i <= MAXCOLORS; i++) {
+ bminfo.color_table[i] = i + mask;
+ }
+ bminfo.hdr.biHeight = bi->height;
+ bminfo.hdr.biWidth = bi->width;
+ SetDIBits(hdc[2], hPutimageBitmap, 0, bi->height, bi->bits,
+ (BITMAPINFO*)&bminfo, DIB_PAL_COLORS);
+ if (bgiemu_handle_redraw || visual_page != active_page) {
+ BitBlt(hdc[1], x, y, bi->width, bi->height, hdc[2], 0, 0,
+ bitblt_mode_cnv[bitblt]);
+ }
+ if (visual_page == active_page) {
+ BitBlt(hdc[0], x, y, bi->width, bi->height, hdc[2], 0, 0,
+ bitblt_mode_cnv[bitblt]);
+ }
+}
+
+unsigned int imagesize(int x1, int y1, int x2, int y2)
+{
+ return 8 + (((x2-x1+8) & ~7) >> 1)*(y2-y1+1);
+}
+
+void getimage(int x1, int y1, int x2, int y2, void* image)
+{
+ BGIimage* bi = (BGIimage*)image;
+ int* image_bits;
+ bi->width = x2-x1+1;
+ bi->height = y2-y1+1;
+ bminfo.hdr.biHeight = bi->height;
+ bminfo.hdr.biWidth = bi->width;
+ for (int i = 0; i <= MAXCOLORS; i++) {
+ bminfo.color_table[i] = i + BG;
+ }
+ HBITMAP hb = CreateDIBSection(hdc[3], (BITMAPINFO*)&bminfo,
+ DIB_PAL_COLORS, (void**)&image_bits, 0, 0);
+ HBITMAP hdb = (HBITMAP__*) SelectObject(hdc[3], hb);
+ BitBlt(hdc[3], 0, 0, bi->width, bi->height,
+ hdc[visual_page != active_page || bgiemu_handle_redraw ? 1 : 0],
+ x1, y1, SRCCOPY);
+ GdiFlush();
+ memcpy(bi->bits, image_bits, (((bi->width+7) & ~7) >> 1)*bi->height);
+ SelectObject(hdc[3], hdb);
+ DeleteObject(hb);
+}
+
+unsigned int getpixel(int x, int y)
+{
+ int color;
+ COLORREF rgb = GetPixel(hdc[visual_page != active_page
+ || bgiemu_handle_redraw ? 1 : 0], x, y);
+
+ if (rgb == CLR_INVALID) {
+ return -1;
+ }
+ int red = GetRValue(rgb);
+ int blue = GetBValue(rgb);
+ int green = GetGValue(rgb);
+ for (color = 0; color <= MAXCOLORS; color++) {
+ if (BGIpalette[color].peRed == red &&
+ BGIpalette[color].peGreen == green &&
+ BGIpalette[color].peBlue == blue)
+ {
+ return color;
+ }
+ }
+ return -1;
+}
+
+void putpixel(int x, int y, int c)
+{
+ c &= MAXCOLORS;
+ if (bgiemu_handle_redraw || visual_page != active_page) {
+ SetPixel(hdc[1], x, y, PALETTEINDEX(c+BG));
+ }
+ if (visual_page == active_page) {
+ SetPixel(hdc[0], x, y, PALETTEINDEX(c+BG));
+ }
+}
+
+void point(double x, double y)
+{
+ xy_scale(&x,&y);
+ putpixel(x,y,1);
+}
+
+
+LRESULT CALLBACK WndProc(HWND hWnd, UINT messg,
+ WPARAM wParam, LPARAM lParam)
+{
+ int i;
+ static bool palette_changed = false;
+
+ switch (messg) {
+ case WM_PAINT:
+ if (hdc[0] == 0) {
+ hdc[0] = BeginPaint(hWnd, &ps);
+ SelectPalette(hdc[0], hPalette, FALSE);
+ RealizePalette(hdc[0]);
+ hdc[1] = CreateCompatibleDC(hdc[0]);
+ SelectPalette(hdc[1], hPalette, FALSE);
+ hdc[2] = CreateCompatibleDC(hdc[0]);
+ SelectPalette(hdc[2], hPalette, FALSE);
+ hdc[3] = CreateCompatibleDC(hdc[0]);
+ SelectPalette(hdc[3], hPalette, FALSE);
+
+ screen_width = GetDeviceCaps(hdc[0], HORZRES);
+ screen_height = GetDeviceCaps(hdc[0], VERTRES);
+ hBitmap[active_page] =
+ CreateCompatibleBitmap(hdc[0], screen_width, screen_height);
+ SelectObject(hdc[1], hBitmap[active_page]);
+
+ SetTextColor(hdc[0], PALETTEINDEX(text_color+BG));
+ SetTextColor(hdc[1], PALETTEINDEX(text_color+BG));
+ SetBkColor(hdc[0], PALETTEINDEX(BG));
+ SetBkColor(hdc[1], PALETTEINDEX(BG));
+
+ SelectObject(hdc[0], hBrush[fill_settings.pattern]);
+ SelectObject(hdc[1], hBrush[fill_settings.pattern]);
+
+ RECT scr;
+ scr.left = -view_settings.left;
+ scr.top = -view_settings.top;
+ scr.right = screen_width-view_settings.left-1;
+ scr.bottom = screen_height-view_settings.top-1;
+ FillRect(hdc[1], &scr, hBackgroundBrush);
+ }
+ if (hRgn != NULL) {
+ SelectClipRgn(hdc[0], NULL);
+ }
+ if (visual_page != active_page) {
+ SelectObject(hdc[1], hBitmap[visual_page]);
+ }
+ BitBlt(hdc[0], -view_settings.left,
+ -view_settings.top, window_width, window_height,
+ hdc[1], -view_settings.left, -view_settings.top,
+ SRCCOPY);
+ if (hRgn != NULL) {
+ SelectClipRgn(hdc[0], hRgn);
+ }
+ if (visual_page != active_page) {
+ SelectObject(hdc[1], hBitmap[active_page]);
+ }
+ ValidateRect(hWnd, NULL);
+ break;
+ case WM_SETFOCUS:
+ if (palette_changed) {
+ HPALETTE new_palette = CreatePalette(pPalette);
+ SelectPalette(hdc[0], new_palette, FALSE);
+ RealizePalette(hdc[0]);
+ SelectPalette(hdc[1], new_palette, FALSE);
+ SelectPalette(hdc[2], new_palette, FALSE);
+ SelectPalette(hdc[3], new_palette, FALSE);
+ DeleteObject(hPalette);
+ hPalette = new_palette;
+ palette_changed = false;
+ }
+ break;
+ case WM_PALETTECHANGED:
+ RealizePalette(hdc[0]);
+ UpdateColors(hdc[0]);
+ palette_changed = true;
+ break;
+ case WM_DESTROY:
+ EndPaint(hWnd, &ps);
+ hdc[0] = 0;
+ DeleteObject(hdc[1]);
+ DeleteObject(hdc[2]);
+ DeleteObject(hdc[3]);
+ if (hPutimageBitmap) {
+ DeleteObject(hPutimageBitmap);
+ hPutimageBitmap = NULL;
+ }
+ for (i = 0; i < MAX_PAGES; i++) {
+ if (hBitmap[i] != NULL) {
+ DeleteObject(hBitmap[i]);
+ hBitmap[i] = 0;
+ }
+ }
+ DeleteObject(hPalette);
+ hPalette = 0;
+ PostQuitMessage(0);
+ break;
+ case WM_SIZE:
+ window_width = LOWORD(lParam);
+ window_height = HIWORD(lParam);
+ break;
+ case WM_TIMER:
+ KillTimer(hWnd, TIMER_ID);
+ timeout_expired = true;
+ break;
+ case WM_CHAR:
+ kbd_queue.put((TCHAR) wParam);
+ break;
+
+ case WM_KEYDOWN:
+ kbd_queue.put(0);
+ kbd_queue.put((TCHAR) wParam);
+ break;
+
+ // Handle some mouse events, too (1-Oct-2000, Matthew Weathers, Erik Habbestad)
+ case WM_LBUTTONDOWN:
+ iClickedMouseX = LOWORD(lParam);
+ iClickedMouseY = HIWORD(lParam);
+ bMouseDown = true;
+ iWhichMouseButton = LEFT_BUTTON;
+ break;
+ case WM_LBUTTONUP:
+ iClickedMouseX = LOWORD(lParam);
+ iClickedMouseY = HIWORD(lParam);
+ bMouseUp = true;
+ iWhichMouseButton = LEFT_BUTTON;
+ break;
+ case WM_RBUTTONDOWN:
+ iClickedMouseX = LOWORD(lParam);
+ iClickedMouseY = HIWORD(lParam);
+ bMouseDown = true;
+ iWhichMouseButton = RIGHT_BUTTON;
+ break;
+ case WM_RBUTTONUP:
+ iClickedMouseX = LOWORD(lParam);
+ iClickedMouseY = HIWORD(lParam);
+ bMouseUp = true;
+ iWhichMouseButton = RIGHT_BUTTON;
+ break;
+ case WM_MOUSEMOVE:
+ iCurrentMouseX = LOWORD(lParam);
+ iCurrentMouseY = HIWORD(lParam);
+ break;
+
+ default:
+ return DefWindowProc(hWnd, messg, wParam, lParam);
+ }
+ return 0;
+}
+
+void closegraph()
+{
+ DestroyWindow(hWnd);
+ while(handle_input(true));
+}
+
+
+static void detect_mode(int* gd, int* gm)
+{
+ switch (*gd) {
+ case CGA:
+ window_height = 200;
+ switch (*gm) {
+ case CGAC0:
+ case CGAC1:
+ case CGAC2:
+ case CGAC3:
+ window_width = 320;
+ break;
+ case CGAHI:
+ window_width = 640;
+ break;
+ default:
+ window_width = 320;
+ break;
+ }
+ break;
+ case MCGA:
+ window_height = 200;
+ switch (*gm) {
+ case MCGAC0:
+ case MCGAC1:
+ case MCGAC2:
+ case MCGAC3:
+ window_width = 320;
+ break;
+ case MCGAMED:
+ window_width = 640;
+ break;
+ case MCGAHI:
+ window_width = 640;
+ window_height = 480;
+ break;
+ default:
+ window_width = 320;
+ break;
+ }
+ break;
+ case EGA:
+ window_width = 640;
+ switch (*gm) {
+ case EGALO:
+ window_height = 200;
+ break;
+ case EGAHI:
+ window_height = 350;
+ break;
+ default:
+ window_height = 350;
+ break;
+ }
+ break;
+ case EGA64:
+ window_width = 640;
+ switch (*gm) {
+ case EGA64LO:
+ window_height = 200;
+ break;
+ case EGA64HI:
+ window_height = 350;
+ break;
+ default:
+ window_height = 350;
+ break;
+ }
+ break;
+ case EGAMONO:
+ window_width = 640;
+ window_height = 350;
+ break;
+ case HERCMONO:
+ window_width = 720;
+ window_height = 348;
+ break;
+ case ATT400:
+ window_height = 200;
+ switch (*gm) {
+ case ATT400C0:
+ case ATT400C1:
+ case ATT400C2:
+ case ATT400C3:
+ window_width = 320;
+ break;
+ case ATT400MED:
+ window_width = 640;
+ break;
+ case ATT400HI:
+ window_width = 640;
+ window_height = 400;
+ break;
+ default:
+ window_width = 320;
+ break;
+ }
+ break;
+ default:
+ case DETECT:
+ *gd = VGA;
+ *gm = bgiemu_default_mode;
+ case VGA:
+ window_width = 900; //Default WIDTH
+ switch (*gm) {
+ case VGALO:
+ window_height = 200;
+ break;
+ case VGAMED:
+ window_height = 350;
+ break;
+ case VGAHI:
+ window_height = 480;
+ break;
+ default:
+ window_height = 640; //DEFAULT HEIGHT
+ break;
+ }
+ break;
+ case PC3270:
+ window_width = 720;
+ window_height = 350;
+ break;
+ case IBM8514:
+ switch (*gm) {
+ case IBM8514LO:
+ window_width = 640;
+ window_height = 480;
+ break;
+ case IBM8514HI:
+ window_width = 1024;
+ window_height = 768;
+ break;
+ default:
+ window_width = 1024;
+ window_height = 768;
+ break;
+ }
+ break;
+ }
+}
+
+static void set_defaults()
+{
+ color = text_color = WHITE;
+ bkcolor = 0;
+ line_settings.thickness = 1;
+ line_settings.linestyle = SOLID_LINE;
+ line_settings.upattern = ~0;
+ fill_settings.pattern = SOLID_FILL;
+ fill_settings.color = WHITE;
+ write_mode = COPY_PUT;
+
+ text_settings.direction = HORIZ_DIR;
+ text_settings.font = DEFAULT_FONT;
+ text_settings.charsize = 1;
+ text_settings.horiz = LEFT_TEXT;
+ text_settings.vert = TOP_TEXT;
+ text_align_mode = ALIGN_NOT_SET;
+
+ active_page = visual_page = 0;
+
+ view_settings.left = 0;
+ view_settings.top = 0;
+ view_settings.right = window_width-1;
+ view_settings.bottom = window_height-1;
+
+ aspect_ratio_x = aspect_ratio_y = 10000;
+}
+
+void initgraph(int* device, int* mode, char const* /*pathtodriver*/,
+ int size_width, int size_height)
+{
+ int index;
+ static WNDCLASS wcApp;
+
+ gdi_error_code = grOk;
+
+ if (wcApp.lpszClassName == NULL) {
+ wcApp.lpszClassName = "BGIlibrary";
+ wcApp.hInstance = 0;
+ wcApp.lpfnWndProc = WndProc;
+ wcApp.hCursor = LoadCursor(NULL, IDC_ARROW);
+ wcApp.hIcon = 0;
+ wcApp.lpszMenuName = 0;
+ wcApp.hbrBackground = (HBRUSH__ *) GetStockObject(BLACK_BRUSH);
+ wcApp.style = CS_SAVEBITS;
+ wcApp.cbClsExtra = 0;
+ wcApp.cbWndExtra = 0;
+
+ if (!RegisterClass(&wcApp)) {
+ gdi_error_code = GetLastError();
+ return;
+ }
+
+ pPalette = (NPLOGPALETTE)LocalAlloc(LMEM_FIXED,
+ sizeof(LOGPALETTE)+sizeof(PALETTEENTRY)*PALETTE_SIZE);
+
+ pPalette->palVersion = 0x300;
+ pPalette->palNumEntries = PALETTE_SIZE;
+ memset(pPalette->palPalEntry, 0, sizeof(PALETTEENTRY)*PALETTE_SIZE);
+ for (index = 0; index < BG; index++) {
+ pPalette->palPalEntry[index].peFlags = PC_EXPLICIT;
+ pPalette->palPalEntry[index].peRed = index;
+ pPalette->palPalEntry[PALETTE_SIZE-BG+index].peFlags = PC_EXPLICIT;
+ pPalette->palPalEntry[PALETTE_SIZE-BG+index].peRed =
+ PALETTE_SIZE-BG+index;
+ }
+ hBackgroundBrush = CreateSolidBrush(PALETTEINDEX(BG));
+ hBrush[EMPTY_FILL] = (HBRUSH__*) GetStockObject(NULL_BRUSH);
+ hBrush[SOLID_FILL] =
+ CreatePatternBrush(CreateBitmap(8, 8, 1, 1, SolidBrushBitmap));
+ hBrush[LINE_FILL] =
+ CreatePatternBrush(CreateBitmap(8, 8, 1, 1, LineBrushBitmap));
+ hBrush[LTSLASH_FILL] =
+ CreatePatternBrush(CreateBitmap(8, 8, 1, 1, LtslashBrushBitmap));
+ hBrush[SLASH_FILL] =
+ CreatePatternBrush(CreateBitmap(8, 8, 1, 1, SlashBrushBitmap));
+ hBrush[BKSLASH_FILL] =
+ CreatePatternBrush(CreateBitmap(8, 8, 1, 1, BkslashBrushBitmap));
+ hBrush[LTBKSLASH_FILL] =
+ CreatePatternBrush(CreateBitmap(8, 8, 1, 1, LtbkslashBrushBitmap));
+ hBrush[HATCH_FILL] =
+ CreatePatternBrush(CreateBitmap(8, 8, 1, 1, HatchBrushBitmap));
+ hBrush[XHATCH_FILL] =
+ CreatePatternBrush(CreateBitmap(8, 8, 1, 1, XhatchBrushBitmap));
+ hBrush[INTERLEAVE_FILL] =
+ CreatePatternBrush(CreateBitmap(8, 8, 1, 1, InterleaveBrushBitmap));
+ hBrush[WIDE_DOT_FILL] =
+ CreatePatternBrush(CreateBitmap(8, 8, 1, 1, WidedotBrushBitmap));
+ hBrush[CLOSE_DOT_FILL] =
+ CreatePatternBrush(CreateBitmap(8, 8, 1, 1, ClosedotBrushBitmap));
+ hBrush[USER_FILL] =
+ CreatePatternBrush(CreateBitmap(8, 8, 1, 1, SolidBrushBitmap));
+ }
+ memcpy(BGIpalette, BGIcolor, sizeof BGIpalette);
+ current_palette.size = MAXCOLORS+1;
+ for (index = 10; index <= MAXCOLORS; index++) {
+ pPalette->palPalEntry[index] = BGIcolor[0];
+ }
+ for (index = 0; index <= MAXCOLORS; index++) {
+ current_palette.colors[index] = index;
+ pPalette->palPalEntry[index+BG] = BGIcolor[index];
+ }
+ hPalette = CreatePalette(pPalette);
+ detect_mode(device, mode);
+ set_defaults();
+
+ if (size_width) window_width=size_width;
+ if (size_height) window_height=size_height;
+
+ hWnd = CreateWindow("BGIlibrary", "Windows BGI",
+ WS_OVERLAPPEDWINDOW,
+ 0, 0, window_width+BORDER_WIDTH,
+ window_height+BORDER_HEIGHT,
+ (HWND)NULL, (HMENU)NULL,
+ 0, NULL);
+ if (hWnd == NULL) {
+ gdi_error_code = GetLastError();
+ return;
+ }
+ ShowWindow(hWnd, *mode == VGAMAX ? SW_SHOWMAXIMIZED : SW_SHOWNORMAL);
+ UpdateWindow(hWnd);
+}
+
+
+void graphdefaults()
+{
+ set_defaults();
+
+ for (int i = 0; i <= MAXCOLORS; i++) {
+ current_palette.colors[i] = i;
+ BGIpalette[i] = BGIcolor[i];
+ }
+ SetPaletteEntries(hPalette, BG, MAXCOLORS+1, BGIpalette);
+ RealizePalette(hdc[0]);
+
+ SetTextColor(hdc[0], PALETTEINDEX(text_color+BG));
+ SetTextColor(hdc[1], PALETTEINDEX(text_color+BG));
+ SetBkColor(hdc[0], PALETTEINDEX(BG));
+ SetBkColor(hdc[1], PALETTEINDEX(BG));
+
+ SelectClipRgn(hdc[0], NULL);
+ SelectClipRgn(hdc[1], NULL);
+ SetViewportOrgEx(hdc[0], 0, 0, NULL);
+ SetViewportOrgEx(hdc[1], 0, 0, NULL);
+
+ SelectObject(hdc[0], hBrush[fill_settings.pattern]);
+ SelectObject(hdc[1], hBrush[fill_settings.pattern]);
+
+ moveto(0,0);
+}
+
+void restorecrtmode() {}
+
+int getkey()
+{
+ if( !kbd_queue.is_empty() )
+ return (unsigned char)kbd_queue.get();
+ return -1;
+}
+
+/* ----------- DODATKI -------------- */
+
+void startdelay(unsigned msec)
+{
+ timeout_expired = false;
+ SetTimer(hWnd, TIMER_ID, msec, NULL);
+}
+
+void stopdelay()
+{
+ while (!timeout_expired) handle_input(true);
+}
+
+int animate(int fps) {
+ int c;
+ double time = 1000./fps;
+ const double timelimit = 60.;
+ static double time_to_go=0;
+ static int pg=0;
+ if (fps >= 0) setvisualpage(pg % 2);
+ time_to_go -= time;
+ while (handle_input(false));
+ if (fps > 0) {
+ if (time_to_go < 0) {
+ stopdelay();
+ if (time < timelimit) time = timelimit;
+ startdelay(time);
+ time_to_go += time;
+ }
+ } else {
+ time_to_go = 0;
+ }
+ c = getkey();
+ if (c > 0) {
+ printf("Pressed:%d\n",c);
+ }
+ c = getkey();
+ if (c > 0) {
+ printf("Pressed:%d\n",c);
+ }
+
+ if (fps >= 0) {
+ pg++;
+ setactivepage(pg % 2);
+ }
+ return c <= 0;
+}
+
+void clearscale()
+{
+ scale_x = 1;
+ scale_dx = 0;
+ scale_y = 1;
+ scale_dy = 0;
+ scale_y_log = 0;
+ setviewport(0,0,window_width,window_height,0);
+ clear();
+}
+
+void all_scale(double x0, double y0, double x1, double y1, int y_log) {
+ if (x0>x1) {double tmp=x0; x0=x1; x1=tmp; }
+ if (x1-x0 < 1e-10) { x1=x0+1e-10; }
+ if (y_log) {
+ if (y0 < 1e-14) y0=1e-14;
+ if (y1 < 1e-14) y1=1e-14;
+ y0=log10(y0);
+ y1=log10(y1);
+ }
+ if (y0>y1) {double tmp=y0; y0=y1; y1=tmp; }
+ if (y1-y0 < 1e-10) { y1=y0+1e-10; }
+ double mar = 130, mag=10;
+ int sx = 90;
+ int sy = 50;
+ int mx = window_width - mar+sx;
+ int my = window_height - mar+sy;
+ clearscale();
+ settextstyle(0,0,1);
+ line(sx-mag,sy-mag,sx-mag,my+mag);
+ line(sx-mag,sy-mag,mx+mag,sy-mag);
+ line(mx+mag,sy-mag,mx+mag,my+mag);
+ line(sx-mag,my+mag,mx+mag,my+mag);
+ {
+ double dx;
+ char xstr[100];
+ settextjustify(1, 2);
+ //, TA_BASELINE, TA_TOP};
+ sprintf(xstr,"%.1lg",(x1-x0)/10.);
+ sscanf(xstr,"%lf",&dx);
+ double x=-floor(-x0/dx)*dx;
+ for (int i = 0; i<=floor((x1-x0)/dx); i++) {
+ double tick;
+ char xstr[100];
+ sprintf(xstr,"%.2lg",x);
+ tick = (x-x0)*(mx-sx)/(x1-x0);
+ line(sx+tick,my+mag,sx+tick,my+2*mag);
+ outtextxy(sx+tick,my+2*mag, xstr);
+ x += dx;
+ }
+ }
+ {
+ double dy;
+ char ystr[100];
+ settextjustify(2, 1);
+ sprintf(ystr,"%.1lg",(y1-y0)/10.);
+ sscanf(ystr,"%lf",&dy);
+ double y=-floor(-y0/dy)*dy;
+ for (int i = 0; i<=floor((y1-y0)/dy); i++) {
+ double tick;
+ char ystr[100];
+ if (y_log) {
+ sprintf(ystr,"10^%.2lg",y);
+ } else {
+ sprintf(ystr,"%.2lg",y);
+ }
+ tick = (y-y0)*(my-sy)/(y1-y0);
+ line(sx-2*mag,my-tick,sx-mag,my-tick);
+ outtextxy(sx-2*mag,my-tick, ystr);
+ y += dy;
+ }
+ }
+ scale_x = (mx-sx)/(x1-x0);
+ scale_dx = - scale_x*x0+mag;
+ scale_y = - (my-sy)/(y1-y0);
+ scale_dy = - scale_y*y1+mag;
+ scale_y_log = y_log;
+ setviewport(sx-mag+1,sy-mag+1,mx+mag,my+mag,1);
+ clear();
+}
+
+void scale(double x0, double y0, double x1, double y1) {
+ all_scale(x0,y0,x1,y1,0);
+}
+void log_scale(double x0, double y0, double x1, double y1) {
+ all_scale(x0,y0,x1,y1,1);
+}
+
+void title(char * xlab, char * ylab, char * main_title)
+{
+ double mar = 130, mag=10;
+ int sx = 90;
+ int sy = 50;
+ int mx = window_width - mar+sx;
+ int my = window_height - mar+sy;
+ setviewport(0,0,window_width,window_height,0);
+ settextstyle(8,0,1);
+ settextjustify(1, 2);
+ outtextxy((sx+mx)/2,5,main_title);
+ settextstyle(8,0,1);
+ settextjustify(1, 0);
+ outtextxy((sx+mx)/2,window_height-5,xlab);
+ settextstyle(8,1,1);
+ settextjustify(2, 1);
+ outtextxy(5,(sy+my)/2,ylab);
+ setviewport(sx-mag+1,sy-mag+1,mx+mag,my+mag,1);
+}
+
+
+void chart(double * x, double * y, int n, char * xlab, char * ylab, char * main_title) {
+ double x0=x[0], x1=x[0], y0=y[0], y1=y[0];
+ for (int i=0;ix1) x1=x[i];
+ if (y[i]y1) y1=y[i];
+ }
+ scale(x0,y0,x1,y1);
+ title(xlab,ylab,main_title);
+ for (int i=1; i