From a335d10f9f51a7b860d1956082674e7872afd34d Mon Sep 17 00:00:00 2001 From: Nathan Anderson Date: Thu, 2 Jan 2025 08:28:46 -0700 Subject: [PATCH] Added scaling and ready to start with sdl_image --- assets/stretch.bmp | Bin 0 -> 307338 bytes {src => assets}/zig.bmp | Bin build.zig | 54 +++++++++++++++++++++------------------- build.zig.zon | 8 ++++++ flake.nix | 10 +++++++- src/main.zig | 47 +++++++++++++++++++++------------- src/png.png | Bin 0 -> 7203 bytes 7 files changed, 76 insertions(+), 43 deletions(-) create mode 100644 assets/stretch.bmp rename {src => assets}/zig.bmp (100%) create mode 100644 src/png.png diff --git a/assets/stretch.bmp b/assets/stretch.bmp new file mode 100644 index 0000000000000000000000000000000000000000..42657b6752b74610ca5fee7d202f5308525fdd7b GIT binary patch literal 307338 zcmeI5L9Q;jZAPz?ETTt7fXrhcD+oNv$dhcvQ?J0Q$)33q>@Uds{aUm zA&MeDQm1|i-J|~FpZ@wk|MFGFUw{7n<>%jj{_gARe}B%u`})_ffBrdt{oMbzfB*X1 zUs?VdKfbVvQ;fMXDL2N((0uXo! z0ekO`=9e6mV?Y1`5cnH`qxUY`104h)0D&hG$lkPG{}azn&k%sX=Mw0B<67cBmnJ8N z00f>ypyfR~6Z0en^a=q8>_x!8IahV(>qP6Qb`N`z6TD8@# zXP%4D8fw?nG&Zwq8tg*=0y%*l?^V=OeuDm;NWb`Y9a+ET-?eZ0g22uM?EW0hcl00i zGqaCKzxZ|^S>I3SeRsC>_jv@4?vvkJNypcodA}p=nfh0AdV2p?^Fbd1tpu{Wl=)kA zN8_%nf2H>5xm)s|-hay(iGjch0@+z~B1nmC!*=PBETl=_K zYtzr>kvgk1M|$+RSjUK^z1i@ST9(C9}Ur{qoqp&ROh;U-ggdvo$i!UG%h%tXK1EEH(rn&_}@Tk%lv0F$$zN~+o^$ooA{GJ=_(fp1dspix+i!g< zvivi@hgn*)bk3ZC90+_ef#~kt$s_8g_;j?yXuR4{uI~5Pk(TeZMQ@f)OD$p`0D->~ zi09 zsJ8hcJ=^P#dqh3dW!mq;>_0*AH}x%te(!Txf-YWYHJKO1RyY% zfZjE;=T_)bvmX4MsrWcsNAb4j=P0(vr+Phk8mk&=YYa97ATXDJ-Ziu5R_If+9{hZy z;$v;?bIk8&A9u&v_hjokdZ8u+K81kYGo9}|yY^vrtsjfa=8~W775^?H>T#Fe=mP>z zC!qJs&Z0iEZSRiRdeFJnhsO5WHSLxAS??=*pcVw)NFcgfzyIyGANHsFcb#8*P`jlc zjqkBrv{%LS^j%^Z5P(1%f#`18+vjH=+g4#b%Gb4ZtFpzn&aJvD<63*SxRt$83j$9i zVE095|L&Ew?zh-8d1Uo^YGfMT-=n!Y*7tg}Ufmn@An-&2(H)B3zcX*3YLBo{9ktJB zYJOy&(Oi`i^_%%t^+X*AJe`2QLsz_izD6rEpJ(gV{4CCNbk1UT@@v1Dy;HyR0)eLy zDEBIQ1GD>f*5AS<({9OqdyHrE_VaQ+2&^FB@73sk`+7ZFx17ad{oImE3vFF{H(jNp?5s2>Z9q-OAee`mV`tH>r9s&@!hrllPH|nGKo-nlcC-h5?5P-lh z0(y7NzJra`*7=S;s0jfGd=3G9Z_HkOdaLW_)qPM80ucBd0{*?R^=blE*Uzi_pdJJu z@Hqthdt>X>1gx%~SNB0Z2teR-2>AD=tnV1R^l``8sR;oH+(Tf8cPHxMu6OvJuRv7@ zK;RAn(c81SkEjRUztvxXdJy|U){sX^HK`}5ZHsj4sTD?!ya_#0s;_t zGlA&sS^4i?ch`UOx8-aQfWR?<=>0j)n7bR*U-|ydJq>CQfWVUoMDNea{_n28@~qT? z00j0TaOe9I)h<2;1Rwx`6$GL;Xhq#pBdX2&w~9V>AOL~r4O&Gds?GbiiavE90D5P$##A_Dg2=^Vx3g8&2|@FoKK=BfRrGjbLPKmY;}0e$n-j$-ja z00Izr69Ikm)PB<$IST|J0D*{rzIkd#vG^bW0SLT}fWCXhW?}_){bt2zKZ9S{cqdK!{tkBVOtf)r~ z2t0*=-i;Rfj&rs2t^HZN zpDo|}Ti2Gqdd~V=-3Rp`unU3gP85GOG$)I>!moAJj%w+CWJfvP*P0i_9r=8n73-{@ z6}71WfgK5CccS=r99h3vuUUNS`J()+miI@w>htln^+;~f)_k>Vb=il&4g{|F&8nu_ zJDfM_L3>m?idCP+nyvepZLvCMv5{Z%B0I{7d?UH07ikn90|L7fh<>{>dcI0`MsJZu z)Njijj`AXX?~C$U>dn@f(Z>u8e=gRaN5KD%t|s8?*?P3D>G*k6_sV?VtF3D_El%fJ zPTALZwOevEMswBHm?K+r)IQ4bdzz=Vk7EsijDY@byq)EY`h6W+@2Wf6*HONm-Oook zwx>DftIe9Db}cX3*L<_1IPbIAX!fz$I?6R)mV+Mxo`C&kvf0PaSYJ`=3e6d3t!YGk z*K$Voqk6@6cBo#fhUP?ei%yhRd<+Qm5XgQ<>hIBOiB)a2TXM4))loZ(-@&has(p2D zTFdOKYpTB0%w~EjF7q z*6b`6|8oe~x9pimPFJflq8;TP)r;a=eUWZ!?wxUW^?g^}!aAxQ`HsFzZ~T!Kd-oHF zzGtg%r2DAGh+Zu>s%O4h?$N$!=zJ8v%bxaY_KM!DmY?se-P4PYEo;Ve2t?oStZ(Gh zQOyy(T5eR&e6`%8ebdnSD1L`M?N#j+y=gtQudc1NYIfF3mY2ojzn?(%&1U#VPM6gm z(LBn{>J|UUh;&EvR^&!Kk8~WbsifzWWGd->KJcC&=<_|IB=a z=20J6z2YAkk?x4zirl+%=&rkBOH`mfT> z>Sy(ee`Fl#&fXj8Q**PvH0DY>tFQi<^;K7GtD!z`TTGe#URg8lBM^O$9$!o6nO;lo zQOs4kSC(s;_muUE;jY)~bQMmVkYO*7;0# znf4hi&53k%f2JMP^1ie6yv~aCnO?Q8-~aa85BoF!8O@O#t9vw$=xc6PLt~1a#U1&* z2J3YMj=oFT8y%VcsBX!Rv}fo>8c{9pi}G50UT4L+r7w-~J=xo*vybs>)thDe8h(9s z9k1`}*VaCt^?CyS8_nv#>*{(&4b?MyhHj)``bTq=*XnE0J&NhwYwgS8yuQABX8V}h z+O$XKqdKG7mY>zIeVwz|$gg?W?;sF;XZ6iGrE01@OJ8+VKeIKy*PgAJ=@tK(p?db- z`B`IH?K8bZIZ?eR?yRp@KZ^Ihv%QeFF9H9J{d#8SUfb3)YnYa4AI%nfcFweW^)j8} z9~q|W-#uH~e$PD8kI&V*es5&0x@y-nHCF9f9{bNDpx-yMXP;_Soziz!%lk*p=(Tj+ zqO0+d-J;PFW7_ua*=+uvxuxFSG1+-q`qJE%cw(MMK)-Qj&pegYDEH26n`hQhEz_^f znsdg^^lMsKp80F}J^QBV=c3_#N9&%NcgALCxU(l}-%lX>U3mY@PF36fy+dc+@3m`v zs$PlJwc0hE+P-S3?elc+$o6@o>!{YK=Fa)id5e$nnFO-mL*$=LNNec3XSVL2v3vT> z^i@M+)PH1a&ZvD<=j>kA(^{&8ZrzXkGvA*;-?I?YL_0y-L4V zSL5?;$9J@jx5w4@Q}AcB^?sew(G>*jd$-J2)Q>c+7klsgZ2P@)RIBE@vPQ3ViNAVe zJzZV*F8xnC?_HdCtebs%@4vHm-%DAq9#IdG?@V8jPUJhIeJ1D5+GqM5&56!ie2jM! z$iBP!cOansn7z6$t9vxB?&+#}(HXC*wS#VS-r{4tn?Uy6cl-8HpLcwjs1Nhq(a#k% z?L2%y0glwXWr}JO3_bv5U?Sowd++|9L_P1u^~wE2e0Tp%%;FuLeU>&l`w@t~_f@}j zU+XLluX9zuXZw44Uc~oP7)NJ+`uC*&oIv!wulTLctP^SFCuFCWz$f$lLE!%YsbI%5 literal 0 HcmV?d00001 diff --git a/src/zig.bmp b/assets/zig.bmp similarity index 100% rename from src/zig.bmp rename to assets/zig.bmp diff --git a/build.zig b/build.zig index de7f030..4aa240b 100644 --- a/build.zig +++ b/build.zig @@ -12,19 +12,32 @@ pub fn build(b: *Build) void { .target = target, .optimize = optimize, }); - if (target.query.isNativeOs() and target.result.os.tag == .linux) { - // The SDL package doesn't work for Linux yet, so we rely on system - // packages for now. - exe.linkSystemLibrary("SDL2"); - exe.linkLibC(); - } else { - const sdl_dep = b.dependency("sdl", .{ - .optimize = .ReleaseFast, - .target = target, - }); - exe.linkLibrary(sdl_dep.artifact("SDL2")); - } - + // Keeping this here just in case, but dynamic linking is working AFAICT + // if (target.query.isNativeOs() and target.result.os.tag == .linux) { + // // The SDL package doesn't work for Linux yet, so we rely on system + // // packages for now. + // exe.linkSystemLibrary("SDL2"); + // exe.linkSystemLibrary("SDL2_ttf"); + // exe.linkSystemLibrary("SDL2_image"); + // } else { + const sdl_dep = b.dependency("SDL", .{ + .optimize = .ReleaseFast, + .target = target, + }); + const sdl_lib = sdl_dep.artifact("SDL2"); + exe.root_module.addIncludePath(sdl_lib.getEmittedIncludeTree().path(b, "SDL2")); + exe.linkLibrary(sdl_lib); + const sdl_ttf_dep = b.dependency("SDL_ttf", .{ + .optimize = .ReleaseFast, + .target = target, + }); + exe.linkLibrary(sdl_ttf_dep.artifact("SDL2_ttf")); + const sdl_image_dep = b.dependency("SDL_image", .{ + .optimize = .ReleaseFast, + .target = target, + }); + exe.linkLibrary(sdl_image_dep.artifact("SDL2_image")); + // } b.installArtifact(exe); // Create Check step for zls @@ -34,18 +47,9 @@ pub fn build(b: *Build) void { .target = target, .optimize = optimize, }); - if (target.query.isNativeOs() and target.result.os.tag == .linux) { - // The SDL package doesn't work for Linux yet, so we rely on system - // packages for now. - exe_check.linkSystemLibrary("SDL2"); - exe_check.linkLibC(); - } else { - const sdl_dep = b.dependency("sdl", .{ - .optimize = .ReleaseFast, - .target = target, - }); - exe_check.linkLibrary(sdl_dep.artifact("SDL2")); - } + exe_check.linkLibrary(sdl_dep.artifact("SDL2")); + exe_check.linkLibrary(sdl_ttf_dep.artifact("SDL2_ttf")); + exe_check.linkLibrary(sdl_image_dep.artifact("SDL2_image")); const check = b.step("check", "Check if project compiles, used by Zig Language Server"); check.dependOn(&exe_check.step); diff --git a/build.zig.zon b/build.zig.zon index 176bfa3..c8ac121 100644 --- a/build.zig.zon +++ b/build.zig.zon @@ -7,6 +7,14 @@ .url = "https://github.com/allyourcodebase/SDL/archive/7e4fc30b201d266f197fef4153f7e046bd189a7c.tar.gz", .hash = "1220c57b0bec66a2378e90cd7a79e36f9e7f60c02acca769ab3e6f974d4ef6766418", }, + .SDL_image = .{ + .url = "https://github.com/allyourcodebase/SDL_image/archive/d7b87f0cd57a1dff93fd0b2455ed7674ae776d4c.tar.gz", + .hash = "12209c505bb1364c6e408995274e8ce037cf5f41ad74f323f1e978efb16422ae2f3b", + }, + .SDL_ttf = .{ + .url = "https://github.com/allyourcodebase/SDL_ttf/archive/8d951496c0638ca7cbcec1eb5a9b3fe1e358241f.tar.gz", + .hash = "1220ffe43566e6406bc15a7c3ad46294f3e4e45e9e323bd2b4e020d3f4b22df5fd83", + }, }, .paths = .{ "build.zig", diff --git a/flake.nix b/flake.nix index 77e9df2..e99f586 100644 --- a/flake.nix +++ b/flake.nix @@ -15,13 +15,21 @@ }; zls = zlsPkg.defaultPackage.${system}; in { - devShell = pkgs.mkShell { + devShell = pkgs.mkShell rec { buildInputs = with pkgs; [ lldb SDL2 + SDL2_ttf + SDL2_image + ## For SDL dynamic linking + libpulseaudio + xorg.libXext + ## zig zls ]; + LD_LIBRARY_PATH = pkgs.lib.makeLibraryPath buildInputs; + C_INCLUDE_PATH = "${pkgs.SDL2}/include:${pkgs.SDL2_ttf}/include:${pkgs.SDL2_image}/include"; }; }); } diff --git a/src/main.zig b/src/main.zig index 6f00187..bd62bd5 100644 --- a/src/main.zig +++ b/src/main.zig @@ -1,5 +1,6 @@ const c = @cImport({ @cInclude("SDL2/SDL.h"); + @cInclude("SDL2/SDL_image.h"); }); const std = @import("std"); @@ -10,7 +11,6 @@ const log = c.SDL_Log; var window: *c.struct_SDL_Window = undefined; var screen_surface: *c.struct_SDL_Surface = undefined; -var zig_image: *c.struct_SDL_Surface = undefined; const Offset = struct { x: i32, y: i32, @@ -21,8 +21,10 @@ pub fn main() !void { try init(); defer close(); - try loadMedia(); - var src_rect: c.struct_SDL_Rect = c.SDL_Rect{ .x = 10, .y = 10, .w = 400, .h = 140 }; + const zig_image = try loadSurface("assets/stretch.bmp"); + defer c.SDL_FreeSurface(zig_image); + + var src_rect: c.struct_SDL_Rect = c.SDL_Rect{ .x = 0, .y = 0, .w = SCREEN_WIDTH / 2, .h = SCREEN_HEIGHT / 2 }; var quit = false; while (!quit) { @@ -41,10 +43,10 @@ pub fn main() !void { img_pos.y = img_pos.y + 5; }, c.SDLK_LEFT => { - img_pos.x = img_pos.x + 5; + img_pos.x = img_pos.x - 5; }, c.SDLK_RIGHT => { - img_pos.x = img_pos.x - 5; + img_pos.x = img_pos.x + 5; }, else => {}, } @@ -54,8 +56,8 @@ pub fn main() !void { } } _ = c.SDL_FillRect(screen_surface, null, c.SDL_MapRGB(screen_surface.format, 0xff, 0xff, 0xff)); - var dest_rect = c.SDL_Rect{ .x = src_rect.x + img_pos.x, .y = src_rect.y + img_pos.y, .w = src_rect.w, .h = src_rect.h }; - _ = c.SDL_BlitSurface(zig_image, &src_rect, screen_surface, &dest_rect); + var dest_rect = c.SDL_Rect{ .x = src_rect.x + img_pos.x, .y = src_rect.y + img_pos.y, .w = SCREEN_WIDTH, .h = SCREEN_HEIGHT }; + _ = c.SDL_BlitScaled(zig_image, &src_rect, screen_surface, &dest_rect); _ = c.SDL_UpdateWindowSurface(window); c.SDL_Delay(17); @@ -77,22 +79,33 @@ fn init() !void { } window = opt_window.?; - // get surface and fill with white screen_surface = c.SDL_GetWindowSurface(window); -} -fn loadMedia() !void { - const image: [*c]c.struct_SDL_Surface = c.SDL_LoadBMP("src/zig.bmp"); - if (image == null) { - log("Unable to load media: %s\n", c.SDL_GetError()); - return error.SDLLoadError; - } else { - zig_image = image; + const img_flags = c.IMG_INIT_PNG; + if (c.IMG_Init(img_flags) != img_flags) { + log("Unable to initialize SDL Image: %s\n", c.IMG_GetError()); + return error.SDLInitializationFailed; } } +fn loadSurface(path: [*c]const u8) !*c.struct_SDL_Surface { + // TODO check file exists + const loaded_surface: [*c]c.struct_SDL_Surface = c.SDL_LoadBMP(path); + if (loaded_surface == null) { + log("Unable to load media at path %s: %s\n", path, c.SDL_GetError()); + return error.SDLLoadError; + } + defer c.SDL_FreeSurface(loaded_surface); + // Converting 24bit bmp to 32bit to match display + const optimized_surface = c.SDL_ConvertSurface(loaded_surface, screen_surface.format, 0); + if (optimized_surface == null) { + log("Unable to optimize media at path %s: %s\n", path, c.SDL_GetError()); + return error.SDLLoadError; + } + return optimized_surface; +} + fn close() void { - c.SDL_FreeSurface(zig_image); c.SDL_DestroyWindow(window); c.SDL_Quit(); } diff --git a/src/png.png b/src/png.png new file mode 100644 index 0000000000000000000000000000000000000000..134d3a78c0ce28e226274cecb1fd37c035a44cca GIT binary patch literal 7203 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 literal 0 HcmV?d00001