123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189(** Minimal SDL2 Bindings Implementation *)moduleWindow=structtypetendmoduleRenderer=structtypetendmoduleSurface=structtypetendmoduleTexture=structtypetendmoduleEvent=structtypetendtype'aresult=Okof'a|ErrorofstringmoduleInit=structletvideo=0x00000020(* SDL_INIT_VIDEO *)endmoduleHint=structletrender_scale_quality="SDL_RENDER_SCALE_QUALITY"endmoduleWindow_flags=structletwindowed=0x00000004(* SDL_WINDOW_SHOWN *)letresizable=0x00000020(* SDL_WINDOW_RESIZABLE *)letallow_highdpi=0x00002000(* SDL_WINDOW_ALLOW_HIGHDPI *)endmoduleRenderer_flags=structletaccelerated=0x00000002(* SDL_RENDERER_ACCELERATED *)letpresentvsync=0x00000004(* SDL_RENDERER_PRESENTVSYNC *)endmodulePixel=structletformat_argb8888=Int32.of_int0x16362004(* SDL_PIXELFORMAT_ARGB8888 *)end(* External C function declarations *)externalml_sdl_init:int->int="caml_sdl_init"externalml_sdl_quit:unit->unit="caml_sdl_quit"externalml_sdl_get_error:unit->string="caml_sdl_get_error"externalml_sdl_set_hint:string->string->bool="caml_sdl_set_hint"externalml_sdl_create_window:string->int->int->int->Window.toption="caml_sdl_create_window"externalml_sdl_destroy_window:Window.t->unit="caml_sdl_destroy_window"externalml_sdl_create_renderer:Window.t->int->Renderer.toption="caml_sdl_create_renderer"externalml_sdl_destroy_renderer:Renderer.t->unit="caml_sdl_destroy_renderer"externalml_sdl_get_renderer_output_size:Renderer.t->(int*int)option="caml_sdl_get_renderer_output_size"externalml_sdl_render_clear:Renderer.t->int="caml_sdl_render_clear"externalml_sdl_render_copy:Renderer.t->Texture.t->int="caml_sdl_render_copy"externalml_sdl_render_present:Renderer.t->unit="caml_sdl_render_present"externalml_sdl_create_rgb_surface_with_format:int->int->int->int32->Surface.toption="caml_sdl_create_rgb_surface_with_format"externalml_sdl_free_surface:Surface.t->unit="caml_sdl_free_surface"externalml_sdl_get_surface_pitch:Surface.t->int="caml_sdl_get_surface_pitch"externalml_sdl_get_surface_pixels:Surface.t->(int,Bigarray.int8_unsigned_elt,Bigarray.c_layout)Bigarray.Array1.t="caml_sdl_get_surface_pixels"externalml_sdl_create_texture_from_surface:Renderer.t->Surface.t->Texture.toption="caml_sdl_create_texture_from_surface"externalml_sdl_destroy_texture:Texture.t->unit="caml_sdl_destroy_texture"externalml_sdl_create_event:unit->Event.t="caml_sdl_alloc_event_storage"(* Renamed stub *)externalml_sdl_wait_event:Event.t->int="caml_sdl_wait_event"(* Returns 1 on event, 0 on quit, -1 on error *)externalml_sdl_get_event_type:Event.t->int="caml_sdl_get_event_type"externalml_sdl_get_window_event_id:Event.t->int="caml_sdl_get_window_event_id"(* Wrappers for error handling and flag combining *)letget_error()=ml_sdl_get_error()letinitflags=ifml_sdl_initflags=0thenOk()elseError(get_error())letquit()=ml_sdl_quit()letset_hintnamevalue=ml_sdl_set_hintnamevalueletcreate_window~title~w~hflags=matchml_sdl_create_windowtitlewhflagswith|Somew->Okw|None->Error(get_error())letdestroy_windowwin=ml_sdl_destroy_windowwinletcreate_renderer~flagswin=matchml_sdl_create_rendererwinflagswith|Somer->Okr|None->Error(get_error())letdestroy_rendererren=ml_sdl_destroy_rendererrenletget_renderer_output_sizeren=matchml_sdl_get_renderer_output_sizerenwith|Some(w,h)->Ok(w,h)|None->Error(get_error())letrender_clearren=ifml_sdl_render_clearren=0thenOk()elseError(get_error())letrender_copyrentex=ifml_sdl_render_copyrentex=0thenOk()elseError(get_error())letrender_presentren=ml_sdl_render_presentrenletcreate_rgb_surface_with_format~w~h~depthfmt=matchml_sdl_create_rgb_surface_with_formatwhdepthfmtwith|Somes->Oks|None->Error(get_error())letfree_surfacesurf=ml_sdl_free_surfacesurfletget_surface_pitchsurf=ml_sdl_get_surface_pitchsurfletget_surface_pixelssurf=ml_sdl_get_surface_pixelssurfletcreate_texture_from_surfacerensurf=matchml_sdl_create_texture_from_surfacerensurfwith|Somet->Okt|None->Error(get_error())letdestroy_texturetex=ml_sdl_destroy_texturetexletcreate_event()=ml_sdl_create_event()letwait_eventevent_opt=matchevent_optwith|None->Error"wait_event requires an allocated event structure"(* SDL_WaitEvent(NULL) is valid but we need storage *)|Someevent->(matchml_sdl_wait_eventeventwith|1->Oktrue(* Event received *)|0->Okfalse(* SDL_QUIT received by the C stub *)|_->Error(get_error()))moduleEvent_type=structtypet=[`Quit|`Window_event|`Unknownofint]letfrom_int=function|0x100->`Quit(* SDL_QUIT *)|0x200->`Window_event(* SDL_WINDOWEVENT *)|other->`UnknownotherendmoduleWindow_event_id=structtypet=[`Resized|`Size_changed|`Exposed|`Unknownofint]letfrom_int=function|5->`Resized(* SDL_WINDOWEVENT_RESIZED *)|6->`Size_changed(* SDL_WINDOWEVENT_SIZE_CHANGED *)|2->`Exposed(* SDL_WINDOWEVENT_EXPOSED *)|other->`Unknownotherendletget_event_typeevent=Event_type.from_int(ml_sdl_get_event_typeevent)letget_window_event_idevent=Window_event_id.from_int(ml_sdl_get_window_event_idevent)