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 |
370 begin |
365 begin |
371 MakeCrossHairs; |
366 MakeCrossHairs; |
372 LoadGraves; |
367 LoadGraves; |
|
368 {$IFDEF IPHONEOS} |
|
369 tmpHatSurf:= LoadDataImage(ptHats, 'chef', ifNone); |
|
370 {$ELSE} |
373 tmpHatSurf:= LoadDataImage(ptHats, 'Reserved/chef', ifNone); |
371 tmpHatSurf:= LoadDataImage(ptHats, 'Reserved/chef', ifNone); |
|
372 {$ENDIF} |
374 ChefHatTexture:= Surface2Tex(tmpHatSurf, true); |
373 ChefHatTexture:= Surface2Tex(tmpHatSurf, true); |
375 freeTmpHatSurf(); |
374 freeTmpHatSurf(); |
376 end; |
375 end; |
377 |
376 |
378 if not reload then |
377 if not reload then |
604 if rwops <> nil then |
603 if rwops <> nil then |
605 begin |
604 begin |
606 // anounce that loading failed |
605 // anounce that loading failed |
607 OutError(msgFailed, false); |
606 OutError(msgFailed, false); |
608 |
607 |
609 SDLTry(false, (imageFlags and ifCritical) <> 0); |
608 SDLTry(false, 'LoadImage', (imageFlags and ifCritical) <> 0); |
610 // rwops was already freed by IMG_Load_RW |
609 // rwops was already freed by IMG_Load_RW |
611 rwops:= nil; |
610 rwops:= nil; |
612 end else |
611 end else |
613 OutError(msgFailed, (imageFlags and ifCritical) <> 0); |
612 OutError(msgFailed, (imageFlags and ifCritical) <> 0); |
614 exit; |
613 exit; |
717 procedure SetupOpenGLAttributes; |
716 procedure SetupOpenGLAttributes; |
718 begin |
717 begin |
719 {$IFDEF IPHONEOS} |
718 {$IFDEF IPHONEOS} |
720 SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 0); |
719 SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 0); |
721 SDL_GL_SetAttribute(SDL_GL_RETAINED_BACKING, 1); |
720 SDL_GL_SetAttribute(SDL_GL_RETAINED_BACKING, 1); |
|
721 |
|
722 SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 1); |
|
723 SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 1); |
722 {$ELSE} |
724 {$ELSE} |
723 SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); |
725 SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); |
724 {$ENDIF} |
|
725 {$IFNDEF SDL2} // vsync is default in SDL2 |
|
726 SDL_GL_SetAttribute(SDL_GL_SWAP_CONTROL, LongInt((cReducedQuality and rqDesyncVBlank) = 0)); |
|
727 {$ENDIF} |
726 {$ENDIF} |
728 SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 5); |
727 SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 5); |
729 SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 6); |
728 SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 6); |
730 SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 5); |
729 SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 5); |
731 SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 0); // no depth buffer |
730 SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 0); // no depth buffer |
735 end; |
734 end; |
736 |
735 |
737 procedure SetupOpenGL; |
736 procedure SetupOpenGL; |
738 var buf: array[byte] of char; |
737 var buf: array[byte] of char; |
739 begin |
738 begin |
740 |
|
741 {$IFDEF SDL2} |
|
742 AddFileLog('Setting up OpenGL (using driver: ' + shortstring(SDL_GetCurrentVideoDriver()) + ')'); |
739 AddFileLog('Setting up OpenGL (using driver: ' + shortstring(SDL_GetCurrentVideoDriver()) + ')'); |
743 {$ELSE} |
740 |
744 buf[0]:= char(0); // avoid compiler hint |
741 // TODO: this function creates an opengles1.1 context |
745 AddFileLog('Setting up OpenGL (using driver: ' + shortstring(SDL_VideoDriverName(buf, sizeof(buf))) + ')'); |
742 // un-comment below and add proper logic to support opengles2.0 |
746 {$ENDIF} |
743 //SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 2); |
|
744 //SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 0); |
|
745 if SDLGLcontext = nil then |
|
746 SDLGLcontext:= SDL_GL_CreateContext(SDLwindow); |
|
747 SDLTry(SDLGLcontext <> nil, 'SDLGLcontext', true); |
|
748 SDLTry(SDL_GL_SetSwapInterval(1) = 0, 'SDL_GL_SetSwapInterval', true); |
747 |
749 |
748 RendererSetup(); |
750 RendererSetup(); |
749 end; |
751 |
750 |
752 // gl2 init/matrix code was here, but removed |
751 (* |
753 end; |
752 procedure UpdateProjection; |
|
753 var |
|
754 s: GLfloat; |
|
755 begin |
|
756 s:=cScaleFactor; |
|
757 mProjection[0,0]:= s/cScreenWidth; mProjection[0,1]:= 0.0; mProjection[0,2]:=0.0; mProjection[0,3]:= 0.0; |
|
758 mProjection[1,0]:= 0.0; mProjection[1,1]:= -s/cScreenHeight; mProjection[1,2]:=0.0; mProjection[1,3]:= 0.0; |
|
759 mProjection[2,0]:= 0.0; mProjection[2,1]:= 0.0; mProjection[2,2]:=1.0; mProjection[2,3]:= 0.0; |
|
760 mProjection[3,0]:= cStereoDepth; mProjection[3,1]:= s/2; mProjection[3,2]:=0.0; mProjection[3,3]:= 1.0; |
|
761 |
|
762 {$IFDEF GL2} |
|
763 UpdateModelviewProjection; |
|
764 {$ELSE} |
|
765 glMatrixMode(GL_PROJECTION); |
|
766 glLoadMatrixf(@mProjection[0, 0]); |
|
767 glMatrixMode(GL_MODELVIEW); |
|
768 {$ENDIF} |
|
769 end; |
|
770 *) |
|
771 |
754 |
772 //////////////////////////////////////////////////////////////////////////////// |
755 //////////////////////////////////////////////////////////////////////////////// |
773 procedure AddProgress; |
756 procedure AddProgress; |
774 var r: TSDL_Rect; |
757 var r: TSDL_Rect; |
775 texsurf: PSDL_Surface; |
758 texsurf: PSDL_Surface; |
996 if WeaponTooltipTex <> nil then |
979 if WeaponTooltipTex <> nil then |
997 DrawTexture(x, y, WeaponTooltipTex) |
980 DrawTexture(x, y, WeaponTooltipTex) |
998 end; |
981 end; |
999 |
982 |
1000 {$IFDEF USE_VIDEO_RECORDING} |
983 {$IFDEF USE_VIDEO_RECORDING} |
1001 {$IFDEF SDL2} |
|
1002 procedure InitOffscreenOpenGL; |
984 procedure InitOffscreenOpenGL; |
1003 begin |
985 begin |
1004 // create hidden window |
986 // create hidden window |
1005 SDLwindow:= SDL_CreateWindow('hedgewars video rendering (SDL2 hidden window)', |
987 SDLwindow:= SDL_CreateWindow(PChar('hedgewars video rendering (SDL2 hidden window)'), |
1006 SDL_WINDOWPOS_CENTERED_MASK, SDL_WINDOWPOS_CENTERED_MASK, |
988 SDL_WINDOWPOS_CENTERED_MASK, SDL_WINDOWPOS_CENTERED_MASK, |
1007 cScreenWidth, cScreenHeight, |
989 cScreenWidth, cScreenHeight, |
1008 SDL_WINDOW_HIDDEN or SDL_WINDOW_OPENGL); |
990 SDL_WINDOW_HIDDEN or SDL_WINDOW_OPENGL); |
1009 SDLTry(SDLwindow <> nil, true); |
991 SDLTry(SDLwindow <> nil, 'SDL_CreateWindow', true); |
1010 SetupOpenGL(); |
992 SetupOpenGL(); |
1011 end; |
993 end; |
1012 {$ELSE} |
|
1013 procedure InitOffscreenOpenGL; |
|
1014 var ArgCount: LongInt; |
|
1015 PrgName: pchar; |
|
1016 begin |
|
1017 ArgCount:= 1; |
|
1018 PrgName:= 'hwengine'; |
|
1019 glutInit(@ArgCount, @PrgName); |
|
1020 glutInitWindowSize(cScreenWidth, cScreenHeight); |
|
1021 // we do not need a window, but without this call OpenGL will not initialize |
|
1022 glutCreateWindow('hedgewars video rendering (glut hidden window)'); |
|
1023 glutHideWindow(); |
|
1024 // we do not need to set this callback, but it is required for GLUT3 compat |
|
1025 glutDisplayFunc(@SwapBuffers); |
|
1026 RendererSetup(); |
|
1027 end; |
|
1028 {$ENDIF} // SDL2 |
|
1029 {$ENDIF} // USE_VIDEO_RECORDING |
994 {$ENDIF} // USE_VIDEO_RECORDING |
1030 |
995 |
1031 procedure chFullScr(var s: shortstring); |
996 procedure chFullScr(var s: shortstring); |
1032 var flags: Longword = 0; |
997 var flags: Longword = 0; |
1033 reinit: boolean = false; |
998 reinit: boolean = false; |
1034 {$IFNDEF DARWIN}ico: PSDL_Surface;{$ENDIF} |
999 {$IFNDEF DARWIN}ico: PSDL_Surface;{$ENDIF} |
1035 {$IFDEF SDL2}x, y: LongInt;{$ENDIF} |
1000 x, y: LongInt; |
1036 begin |
1001 begin |
1037 if cOnlyStats then |
1002 if cOnlyStats then |
1038 begin |
1003 begin |
1039 MaxTextureSize:= 1024; |
1004 MaxTextureSize:= 1024; |
1040 exit |
1005 exit |
1053 cScreenWidth:= cWindowedWidth; |
1018 cScreenWidth:= cWindowedWidth; |
1054 cScreenHeight:= cWindowedHeight; |
1019 cScreenHeight:= cWindowedHeight; |
1055 end; |
1020 end; |
1056 |
1021 |
1057 AddFileLog('Preparing to change video parameters...'); |
1022 AddFileLog('Preparing to change video parameters...'); |
1058 {$IFDEF SDL2} |
|
1059 if SDLwindow = nil then |
1023 if SDLwindow = nil then |
1060 {$ELSE} |
|
1061 if SDLPrimSurface = nil then |
|
1062 {$ENDIF} |
|
1063 begin |
1024 begin |
1064 // set window title |
1025 // set window title |
1065 {$IFNDEF SDL2} |
|
1066 SDL_WM_SetCaption(_P'Hedgewars', nil); |
|
1067 {$ENDIF} |
|
1068 WriteToConsole('Init SDL_image... '); |
1026 WriteToConsole('Init SDL_image... '); |
1069 SDLTry(IMG_Init(IMG_INIT_PNG) <> 0, true); |
1027 SDLTry(IMG_Init(IMG_INIT_PNG) <> 0, 'IMG_Init', true); |
1070 WriteLnToConsole(msgOK); |
1028 WriteLnToConsole(msgOK); |
1071 // load engine icon |
|
1072 {$IFNDEF DARWIN} |
|
1073 ico:= LoadDataImage(ptGraphics, 'hwengine', ifIgnoreCaps); |
|
1074 if ico <> nil then |
|
1075 begin |
|
1076 SDL_WM_SetIcon(ico, 0); |
|
1077 SDL_FreeSurface(ico) |
|
1078 end; |
|
1079 {$ENDIF} |
|
1080 end |
1029 end |
1081 else |
1030 else |
1082 begin |
1031 begin |
1083 AmmoMenuInvalidated:= true; |
1032 AmmoMenuInvalidated:= true; |
1084 {$IFDEF IPHONEOS} |
1033 {$IFDEF IPHONEOS} |
1116 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 |
1117 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. |
1118 *) |
1063 *) |
1119 SetupOpenGLAttributes(); |
1064 SetupOpenGLAttributes(); |
1120 {$ENDIF} |
1065 {$ENDIF} |
1121 {$IFDEF SDL2} |
|
1122 // 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 |
1123 x:= SDL_WINDOWPOS_CENTERED_MASK; |
1067 x:= SDL_WINDOWPOS_CENTERED_MASK; |
1124 y:= SDL_WINDOWPOS_CENTERED_MASK; |
1068 y:= SDL_WINDOWPOS_CENTERED_MASK; |
1125 // SDL_WINDOW_RESIZABLE makes the window resizable and |
1069 // SDL_WINDOW_RESIZABLE makes the window resizable and |
1126 // respond to rotation events on mobile devices |
1070 // respond to rotation events on mobile devices |
1135 |
1079 |
1136 if cFullScreen then |
1080 if cFullScreen then |
1137 flags:= flags or SDL_WINDOW_FULLSCREEN; |
1081 flags:= flags or SDL_WINDOW_FULLSCREEN; |
1138 |
1082 |
1139 if SDLwindow = nil then |
1083 if SDLwindow = nil then |
1140 SDLwindow:= SDL_CreateWindow('Hedgewars', x, y, cScreenWidth, cScreenHeight, flags); |
1084 SDLwindow:= SDL_CreateWindow(PChar('Hedgewars'), x, y, cScreenWidth, cScreenHeight, flags); |
1141 SDLTry(SDLwindow <> nil, true); |
1085 SDLTry(SDLwindow <> nil, 'SDL_CreateWindow', true); |
1142 {$ELSE} |
1086 |
1143 flags:= SDL_OPENGL or SDL_RESIZABLE; |
1087 // load engine ico |
1144 if cFullScreen then |
1088 {$IFNDEF DARWIN} |
1145 flags:= flags or SDL_FULLSCREEN; |
1089 ico:= LoadDataImage(ptGraphics, 'hwengine', ifIgnoreCaps); |
1146 if not cOnlyStats then |
1090 if ico <> nil then |
1147 begin |
1091 begin |
1148 {$IFDEF WIN32} |
1092 SDL_SetWindowIcon(SDLwindow, ico); |
1149 s:= SDL_getenv('SDL_VIDEO_CENTERED'); |
1093 SDL_FreeSurface(ico); |
1150 SDL_putenv('SDL_VIDEO_CENTERED=1'); |
1094 end; |
1151 {$ENDIF} |
1095 {$ENDIF} |
1152 SDLPrimSurface:= SDL_SetVideoMode(cScreenWidth, cScreenHeight, 0, flags); |
|
1153 SDLTry(SDLPrimSurface <> nil, true); |
|
1154 {$IFDEF WIN32} |
|
1155 SDL_putenv(str2pchar('SDL_VIDEO_CENTERED=' + s)); |
|
1156 {$ENDIF} |
|
1157 end; |
|
1158 {$ENDIF} |
|
1159 |
|
1160 SetupOpenGL(); |
1096 SetupOpenGL(); |
1161 |
1097 |
1162 if reinit then |
1098 if reinit then |
1163 begin |
1099 begin |
1164 // clean the window from any previous content |
1100 // clean the window from any previous content |
1177 // redraw all land |
1113 // redraw all land |
1178 UpdateLandTexture(0, LAND_WIDTH, 0, LAND_HEIGHT, false); |
1114 UpdateLandTexture(0, LAND_WIDTH, 0, LAND_HEIGHT, false); |
1179 end; |
1115 end; |
1180 end; |
1116 end; |
1181 |
1117 |
1182 {$IFDEF SDL2} |
|
1183 // for sdl1.2 we directly call SDL_WarpMouse() |
1118 // for sdl1.2 we directly call SDL_WarpMouse() |
1184 // 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 |
1185 // this has the advantage of reducing 'uses' and 'ifdef' statements |
1120 // this has the advantage of reducing 'uses' and 'ifdef' statements |
1186 // (SDLwindow is a private member of this module) |
1121 // (SDLwindow is a private member of this module) |
1187 procedure WarpMouse(x, y: Word); inline; |
1122 procedure WarpMouse(x, y: Word); inline; |
1188 begin |
1123 begin |
1189 SDL_WarpMouseInWindow(SDLwindow, x, y); |
1124 SDL_WarpMouseInWindow(SDLwindow, x, y); |
1190 end; |
1125 end; |
1191 {$ENDIF} |
|
1192 |
1126 |
1193 procedure SwapBuffers; {$IFDEF USE_VIDEO_RECORDING}cdecl{$ELSE}inline{$ENDIF}; |
1127 procedure SwapBuffers; {$IFDEF USE_VIDEO_RECORDING}cdecl{$ELSE}inline{$ENDIF}; |
1194 begin |
1128 begin |
1195 if GameType = gmtRecord then |
1129 if GameType = gmtRecord then |
1196 exit; |
1130 exit; |
1197 {$IFDEF SDL2} |
|
1198 SDL_GL_SwapWindow(SDLwindow); |
1131 SDL_GL_SwapWindow(SDLwindow); |
1199 {$ELSE} |
|
1200 SDL_GL_SwapBuffers(); |
|
1201 {$ENDIF} |
|
1202 end; |
1132 end; |
1203 |
1133 |
1204 procedure SetSkyColor(r, g, b: real); |
1134 procedure SetSkyColor(r, g, b: real); |
1205 begin |
1135 begin |
1206 RenderSetClearColor(r, g, b, 0.99) |
1136 RenderSetClearColor(r, g, b, 0.99) |