53 procedure MakeCrossHairs; |
53 procedure MakeCrossHairs; |
54 {$IFDEF USE_VIDEO_RECORDING} |
54 {$IFDEF USE_VIDEO_RECORDING} |
55 procedure InitOffscreenOpenGL; |
55 procedure InitOffscreenOpenGL; |
56 {$ENDIF} |
56 {$ENDIF} |
57 |
57 |
58 {$IFDEF SDL2} |
|
59 procedure WarpMouse(x, y: Word); inline; |
58 procedure WarpMouse(x, y: Word); inline; |
60 {$ENDIF} |
|
61 procedure SwapBuffers; {$IFDEF USE_VIDEO_RECORDING}cdecl{$ELSE}inline{$ENDIF}; |
59 procedure SwapBuffers; {$IFDEF USE_VIDEO_RECORDING}cdecl{$ELSE}inline{$ENDIF}; |
62 procedure SetSkyColor(r, g, b: real); |
60 procedure SetSkyColor(r, g, b: real); |
63 |
61 |
64 implementation |
62 implementation |
65 uses uMisc, uConsole, uVariables, uUtils, uTextures, uRender, uRenderUtils, |
63 uses uMisc, uConsole, uVariables, uUtils, uTextures, uRender, uRenderUtils, |
66 uCommands, uPhysFSLayer, uDebug |
64 uCommands, uPhysFSLayer, uDebug |
67 {$IFDEF USE_CONTEXT_RESTORE}, uWorld{$ENDIF} |
65 {$IFDEF USE_CONTEXT_RESTORE}, uWorld{$ENDIF}; |
68 {$IF NOT DEFINED(SDL2) AND DEFINED(USE_VIDEO_RECORDING)}, glut {$ENDIF}; |
66 |
69 |
67 //type TGPUVendor = (gvUnknown, gvNVIDIA, gvATI, gvIntel, gvApple); |
70 var |
68 |
71 {$IFDEF SDL2} |
69 var |
72 SDLwindow: PSDL_Window; |
70 SDLwindow: PSDL_Window; |
73 SDLGLcontext: PSDL_GLContext; |
71 SDLGLcontext: PSDL_GLContext; |
74 {$ELSE} |
|
75 SDLPrimSurface: PSDL_Surface; |
|
76 {$ENDIF} |
|
77 squaresize : LongInt; |
72 squaresize : LongInt; |
78 numsquares : LongInt; |
73 numsquares : LongInt; |
79 ProgrTex: PTexture; |
74 ProgrTex: PTexture; |
80 |
75 |
81 prevHat: shortstring; |
76 prevHat: shortstring; |
115 finalRect.h:= h + cFontBorder * 2; |
110 finalRect.h:= h + cFontBorder * 2; |
116 clr.r:= Color shr 16; |
111 clr.r:= Color shr 16; |
117 clr.g:= (Color shr 8) and $FF; |
112 clr.g:= (Color shr 8) and $FF; |
118 clr.b:= Color and $FF; |
113 clr.b:= Color and $FF; |
119 tmpsurf:= TTF_RenderUTF8_Blended(Fontz[Font].Handle, s, clr); |
114 tmpsurf:= TTF_RenderUTF8_Blended(Fontz[Font].Handle, s, clr); |
120 SDLTry(tmpsurf <> nil, true); |
115 SDLTry(tmpsurf <> nil, 'TTF_RenderUTF8_Blended', true); |
121 tmpsurf:= doSurfaceConversion(tmpsurf); |
116 tmpsurf:= doSurfaceConversion(tmpsurf); |
122 SDLTry(tmpsurf <> nil, true); |
117 SDLTry(tmpsurf <> nil, 'TTF_RenderUTF8_Blended, doSurfaceConversion', true); |
123 SDL_UpperBlit(tmpsurf, nil, Surface, @finalRect); |
118 SDL_UpperBlit(tmpsurf, nil, Surface, @finalRect); |
124 SDL_FreeSurface(tmpsurf); |
119 SDL_FreeSurface(tmpsurf); |
125 finalRect.x:= X; |
120 finalRect.x:= X; |
126 finalRect.y:= Y; |
121 finalRect.y:= Y; |
127 finalRect.w:= w + cFontBorder * 2 + 4; |
122 finalRect.w:= w + cFontBorder * 2 + 4; |
359 with Fontz[fi] do |
354 with Fontz[fi] do |
360 begin |
355 begin |
361 s:= cPathz[ptFonts] + '/' + Name; |
356 s:= cPathz[ptFonts] + '/' + Name; |
362 WriteToConsole(msgLoading + s + ' (' + inttostr(Height) + 'pt)... '); |
357 WriteToConsole(msgLoading + s + ' (' + inttostr(Height) + 'pt)... '); |
363 Handle:= TTF_OpenFontRW(rwopsOpenRead(s), true, Height); |
358 Handle:= TTF_OpenFontRW(rwopsOpenRead(s), true, Height); |
364 SDLTry(Handle <> nil, true); |
359 SDLTry(Handle <> nil, 'TTF_OpenFontRW', true); |
365 TTF_SetFontStyle(Handle, style); |
360 TTF_SetFontStyle(Handle, style); |
366 WriteLnToConsole(msgOK) |
361 WriteLnToConsole(msgOK) |
367 end; |
362 end; |
368 |
363 |
369 if not cOnlyStats then |
364 if not cOnlyStats then |
608 if rwops <> nil then |
603 if rwops <> nil then |
609 begin |
604 begin |
610 // anounce that loading failed |
605 // anounce that loading failed |
611 OutError(msgFailed, false); |
606 OutError(msgFailed, false); |
612 |
607 |
613 SDLTry(false, (imageFlags and ifCritical) <> 0); |
608 SDLTry(false, 'LoadImage', (imageFlags and ifCritical) <> 0); |
614 // rwops was already freed by IMG_Load_RW |
609 // rwops was already freed by IMG_Load_RW |
615 rwops:= nil; |
610 rwops:= nil; |
616 end else |
611 end else |
617 OutError(msgFailed, (imageFlags and ifCritical) <> 0); |
612 OutError(msgFailed, (imageFlags and ifCritical) <> 0); |
618 exit; |
613 exit; |
727 SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 1); |
722 SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 1); |
728 SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 1); |
723 SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 1); |
729 {$ELSE} |
724 {$ELSE} |
730 SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); |
725 SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); |
731 {$ENDIF} |
726 {$ENDIF} |
732 {$IFNDEF SDL2} // vsync is default in SDL2 |
|
733 SDL_GL_SetAttribute(SDL_GL_SWAP_CONTROL, LongInt((cReducedQuality and rqDesyncVBlank) = 0)); |
|
734 {$ENDIF} |
|
735 SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 5); |
727 SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 5); |
736 SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 6); |
728 SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 6); |
737 SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 5); |
729 SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 5); |
738 SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 0); // no depth buffer |
730 SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 0); // no depth buffer |
739 SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, 0); // no alpha channel |
731 SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, 0); // no alpha channel |
742 end; |
734 end; |
743 |
735 |
744 procedure SetupOpenGL; |
736 procedure SetupOpenGL; |
745 var buf: array[byte] of char; |
737 var buf: array[byte] of char; |
746 begin |
738 begin |
747 |
|
748 {$IFDEF SDL2} |
|
749 AddFileLog('Setting up OpenGL (using driver: ' + shortstring(SDL_GetCurrentVideoDriver()) + ')'); |
739 AddFileLog('Setting up OpenGL (using driver: ' + shortstring(SDL_GetCurrentVideoDriver()) + ')'); |
750 {$ELSE} |
740 |
751 buf[0]:= char(0); // avoid compiler hint |
|
752 AddFileLog('Setting up OpenGL (using driver: ' + shortstring(SDL_VideoDriverName(buf, sizeof(buf))) + ')'); |
|
753 {$ENDIF} |
|
754 |
|
755 {$IFDEF MOBILE} |
|
756 // TODO: this function creates an opengles1.1 context |
741 // TODO: this function creates an opengles1.1 context |
757 // un-comment below and add proper logic to support opengles2.0 |
742 // un-comment below and add proper logic to support opengles2.0 |
758 //SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 2); |
743 //SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 2); |
759 //SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 0); |
744 //SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 0); |
760 if SDLGLcontext = nil then |
745 if SDLGLcontext = nil then |
761 SDLGLcontext:= SDL_GL_CreateContext(SDLwindow); |
746 SDLGLcontext:= SDL_GL_CreateContext(SDLwindow); |
762 SDLTry(SDLGLcontext <> nil, true); |
747 SDLTry(SDLGLcontext <> nil, 'SDLGLcontext', true); |
763 SDL_GL_SetSwapInterval(1); |
748 SDLTry(SDL_GL_SetSwapInterval(1) = 0, 'SDL_GL_SetSwapInterval', true); |
764 {$ENDIF} |
|
765 |
749 |
766 RendererSetup(); |
750 RendererSetup(); |
767 end; |
751 |
768 |
752 // gl2 init/matrix code was here, but removed |
769 (* |
753 end; |
770 procedure UpdateProjection; |
|
771 var |
|
772 s: GLfloat; |
|
773 begin |
|
774 s:=cScaleFactor; |
|
775 mProjection[0,0]:= s/cScreenWidth; mProjection[0,1]:= 0.0; mProjection[0,2]:=0.0; mProjection[0,3]:= 0.0; |
|
776 mProjection[1,0]:= 0.0; mProjection[1,1]:= -s/cScreenHeight; mProjection[1,2]:=0.0; mProjection[1,3]:= 0.0; |
|
777 mProjection[2,0]:= 0.0; mProjection[2,1]:= 0.0; mProjection[2,2]:=1.0; mProjection[2,3]:= 0.0; |
|
778 mProjection[3,0]:= cStereoDepth; mProjection[3,1]:= s/2; mProjection[3,2]:=0.0; mProjection[3,3]:= 1.0; |
|
779 |
|
780 {$IFDEF GL2} |
|
781 UpdateModelviewProjection; |
|
782 {$ELSE} |
|
783 glMatrixMode(GL_PROJECTION); |
|
784 glLoadMatrixf(@mProjection[0, 0]); |
|
785 glMatrixMode(GL_MODELVIEW); |
|
786 {$ENDIF} |
|
787 end; |
|
788 *) |
|
789 |
754 |
790 //////////////////////////////////////////////////////////////////////////////// |
755 //////////////////////////////////////////////////////////////////////////////// |
791 procedure AddProgress; |
756 procedure AddProgress; |
792 var r: TSDL_Rect; |
757 var r: TSDL_Rect; |
793 texsurf: PSDL_Surface; |
758 texsurf: PSDL_Surface; |
1014 if WeaponTooltipTex <> nil then |
979 if WeaponTooltipTex <> nil then |
1015 DrawTexture(x, y, WeaponTooltipTex) |
980 DrawTexture(x, y, WeaponTooltipTex) |
1016 end; |
981 end; |
1017 |
982 |
1018 {$IFDEF USE_VIDEO_RECORDING} |
983 {$IFDEF USE_VIDEO_RECORDING} |
1019 {$IFDEF SDL2} |
|
1020 procedure InitOffscreenOpenGL; |
984 procedure InitOffscreenOpenGL; |
1021 begin |
985 begin |
1022 // create hidden window |
986 // create hidden window |
1023 SDLwindow:= SDL_CreateWindow('hedgewars video rendering (SDL2 hidden window)', |
987 SDLwindow:= SDL_CreateWindow(PChar('hedgewars video rendering (SDL2 hidden window)'), |
1024 SDL_WINDOWPOS_CENTERED_MASK, SDL_WINDOWPOS_CENTERED_MASK, |
988 SDL_WINDOWPOS_CENTERED_MASK, SDL_WINDOWPOS_CENTERED_MASK, |
1025 cScreenWidth, cScreenHeight, |
989 cScreenWidth, cScreenHeight, |
1026 SDL_WINDOW_HIDDEN or SDL_WINDOW_OPENGL); |
990 SDL_WINDOW_HIDDEN or SDL_WINDOW_OPENGL); |
1027 SDLTry(SDLwindow <> nil, true); |
991 SDLTry(SDLwindow <> nil, 'SDL_CreateWindow', true); |
1028 SetupOpenGL(); |
992 SetupOpenGL(); |
1029 end; |
993 end; |
1030 {$ELSE} |
|
1031 procedure InitOffscreenOpenGL; |
|
1032 var ArgCount: LongInt; |
|
1033 PrgName: pchar; |
|
1034 begin |
|
1035 ArgCount:= 1; |
|
1036 PrgName:= 'hwengine'; |
|
1037 glutInit(@ArgCount, @PrgName); |
|
1038 glutInitWindowSize(cScreenWidth, cScreenHeight); |
|
1039 // we do not need a window, but without this call OpenGL will not initialize |
|
1040 glutCreateWindow('hedgewars video rendering (glut hidden window)'); |
|
1041 glutHideWindow(); |
|
1042 // we do not need to set this callback, but it is required for GLUT3 compat |
|
1043 glutDisplayFunc(@SwapBuffers); |
|
1044 RendererSetup(); |
|
1045 end; |
|
1046 {$ENDIF} // SDL2 |
|
1047 {$ENDIF} // USE_VIDEO_RECORDING |
994 {$ENDIF} // USE_VIDEO_RECORDING |
1048 |
995 |
1049 procedure chFullScr(var s: shortstring); |
996 procedure chFullScr(var s: shortstring); |
1050 var flags: Longword = 0; |
997 var flags: Longword = 0; |
1051 reinit: boolean = false; |
998 reinit: boolean = false; |
1052 {$IFNDEF DARWIN}ico: PSDL_Surface;{$ENDIF} |
999 {$IFNDEF DARWIN}ico: PSDL_Surface;{$ENDIF} |
1053 {$IFDEF SDL2}x, y: LongInt;{$ENDIF} |
1000 x, y: LongInt; |
1054 begin |
1001 begin |
1055 if cOnlyStats then |
1002 if cOnlyStats then |
1056 begin |
1003 begin |
1057 MaxTextureSize:= 1024; |
1004 MaxTextureSize:= 1024; |
1058 exit |
1005 exit |
1071 cScreenWidth:= cWindowedWidth; |
1018 cScreenWidth:= cWindowedWidth; |
1072 cScreenHeight:= cWindowedHeight; |
1019 cScreenHeight:= cWindowedHeight; |
1073 end; |
1020 end; |
1074 |
1021 |
1075 AddFileLog('Preparing to change video parameters...'); |
1022 AddFileLog('Preparing to change video parameters...'); |
1076 {$IFDEF SDL2} |
|
1077 if SDLwindow = nil then |
1023 if SDLwindow = nil then |
1078 {$ELSE} |
|
1079 if SDLPrimSurface = nil then |
|
1080 {$ENDIF} |
|
1081 begin |
1024 begin |
1082 // set window title |
1025 // set window title |
1083 {$IFNDEF SDL2} |
|
1084 SDL_WM_SetCaption(_P'Hedgewars', nil); |
|
1085 {$ENDIF} |
|
1086 WriteToConsole('Init SDL_image... '); |
1026 WriteToConsole('Init SDL_image... '); |
1087 SDLTry(IMG_Init(IMG_INIT_PNG) <> 0, true); |
1027 SDLTry(IMG_Init(IMG_INIT_PNG) <> 0, 'IMG_Init', true); |
1088 WriteLnToConsole(msgOK); |
1028 WriteLnToConsole(msgOK); |
1089 // load engine icon |
|
1090 {$IFNDEF DARWIN} |
|
1091 ico:= LoadDataImage(ptGraphics, 'hwengine', ifIgnoreCaps); |
|
1092 if ico <> nil then |
|
1093 begin |
|
1094 SDL_WM_SetIcon(ico, 0); |
|
1095 SDL_FreeSurface(ico) |
|
1096 end; |
|
1097 {$ENDIF} |
|
1098 end |
1029 end |
1099 else |
1030 else |
1100 begin |
1031 begin |
1101 AmmoMenuInvalidated:= true; |
1032 AmmoMenuInvalidated:= true; |
1102 {$IFDEF IPHONEOS} |
1033 {$IFDEF IPHONEOS} |
1134 IMO we should rely on the gl_config defaults from SDL, and use |
1061 IMO we should rely on the gl_config defaults from SDL, and use |
1135 SDL_GL_GetAttribute to possibly post warnings if any bad values are set. |
1062 SDL_GL_GetAttribute to possibly post warnings if any bad values are set. |
1136 *) |
1063 *) |
1137 SetupOpenGLAttributes(); |
1064 SetupOpenGLAttributes(); |
1138 {$ENDIF} |
1065 {$ENDIF} |
1139 {$IFDEF SDL2} |
|
1140 // these values in x and y make the window appear in the center |
1066 // these values in x and y make the window appear in the center |
1141 x:= SDL_WINDOWPOS_CENTERED_MASK; |
1067 x:= SDL_WINDOWPOS_CENTERED_MASK; |
1142 y:= SDL_WINDOWPOS_CENTERED_MASK; |
1068 y:= SDL_WINDOWPOS_CENTERED_MASK; |
1143 // SDL_WINDOW_RESIZABLE makes the window resizable and |
1069 // SDL_WINDOW_RESIZABLE makes the window resizable and |
1144 // respond to rotation events on mobile devices |
1070 // respond to rotation events on mobile devices |
1153 |
1079 |
1154 if cFullScreen then |
1080 if cFullScreen then |
1155 flags:= flags or SDL_WINDOW_FULLSCREEN; |
1081 flags:= flags or SDL_WINDOW_FULLSCREEN; |
1156 |
1082 |
1157 if SDLwindow = nil then |
1083 if SDLwindow = nil then |
1158 SDLwindow:= SDL_CreateWindow('Hedgewars', x, y, cScreenWidth, cScreenHeight, flags); |
1084 SDLwindow:= SDL_CreateWindow(PChar('Hedgewars'), x, y, cScreenWidth, cScreenHeight, flags); |
1159 SDLTry(SDLwindow <> nil, true); |
1085 SDLTry(SDLwindow <> nil, 'SDL_CreateWindow', true); |
1160 {$ELSE} |
1086 |
1161 flags:= SDL_OPENGL or SDL_RESIZABLE; |
1087 // load engine ico |
1162 if cFullScreen then |
1088 {$IFNDEF DARWIN} |
1163 flags:= flags or SDL_FULLSCREEN; |
1089 ico:= LoadDataImage(ptGraphics, 'hwengine', ifIgnoreCaps); |
1164 if not cOnlyStats then |
1090 if ico <> nil then |
1165 begin |
1091 begin |
1166 {$IFDEF WIN32} |
1092 SDL_SetWindowIcon(SDLwindow, ico); |
1167 s:= SDL_getenv('SDL_VIDEO_CENTERED'); |
1093 SDL_FreeSurface(ico); |
1168 SDL_putenv('SDL_VIDEO_CENTERED=1'); |
1094 end; |
1169 {$ENDIF} |
1095 {$ENDIF} |
1170 SDLPrimSurface:= SDL_SetVideoMode(cScreenWidth, cScreenHeight, 0, flags); |
|
1171 SDLTry(SDLPrimSurface <> nil, true); |
|
1172 {$IFDEF WIN32} |
|
1173 SDL_putenv(str2pchar('SDL_VIDEO_CENTERED=' + s)); |
|
1174 {$ENDIF} |
|
1175 end; |
|
1176 {$ENDIF} |
|
1177 |
|
1178 SetupOpenGL(); |
1096 SetupOpenGL(); |
1179 |
1097 |
1180 if reinit then |
1098 if reinit then |
1181 begin |
1099 begin |
1182 // clean the window from any previous content |
1100 // clean the window from any previous content |
1195 // redraw all land |
1113 // redraw all land |
1196 UpdateLandTexture(0, LAND_WIDTH, 0, LAND_HEIGHT, false); |
1114 UpdateLandTexture(0, LAND_WIDTH, 0, LAND_HEIGHT, false); |
1197 end; |
1115 end; |
1198 end; |
1116 end; |
1199 |
1117 |
1200 {$IFDEF SDL2} |
|
1201 // for sdl1.2 we directly call SDL_WarpMouse() |
1118 // for sdl1.2 we directly call SDL_WarpMouse() |
1202 // for sdl2 we provide a SDL_WarpMouse() which just calls this function |
1119 // for sdl2 we provide a SDL_WarpMouse() which just calls this function |
1203 // this has the advantage of reducing 'uses' and 'ifdef' statements |
1120 // this has the advantage of reducing 'uses' and 'ifdef' statements |
1204 // (SDLwindow is a private member of this module) |
1121 // (SDLwindow is a private member of this module) |
1205 procedure WarpMouse(x, y: Word); inline; |
1122 procedure WarpMouse(x, y: Word); inline; |
1206 begin |
1123 begin |
1207 SDL_WarpMouseInWindow(SDLwindow, x, y); |
1124 SDL_WarpMouseInWindow(SDLwindow, x, y); |
1208 end; |
1125 end; |
1209 {$ENDIF} |
|
1210 |
1126 |
1211 procedure SwapBuffers; {$IFDEF USE_VIDEO_RECORDING}cdecl{$ELSE}inline{$ENDIF}; |
1127 procedure SwapBuffers; {$IFDEF USE_VIDEO_RECORDING}cdecl{$ELSE}inline{$ENDIF}; |
1212 begin |
1128 begin |
1213 if GameType = gmtRecord then |
1129 if GameType = gmtRecord then |
1214 exit; |
1130 exit; |
1215 {$IFDEF SDL2} |
|
1216 SDL_GL_SwapWindow(SDLwindow); |
1131 SDL_GL_SwapWindow(SDLwindow); |
1217 {$ELSE} |
|
1218 SDL_GL_SwapBuffers(); |
|
1219 {$ENDIF} |
|
1220 end; |
1132 end; |
1221 |
1133 |
1222 procedure SetSkyColor(r, g, b: real); |
1134 procedure SetSkyColor(r, g, b: real); |
1223 begin |
1135 begin |
1224 RenderSetClearColor(r, g, b, 0.99) |
1136 RenderSetClearColor(r, g, b, 0.99) |