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