1.4.1. demos/sdl/sdl-1.01.01

Start felix section to demos/sdl/sdl-1.01.01-0.flx[1 /1 ]
     1: #line 2621 "./lpsrc/flx_sdl.pak"
     2: #import <flx.flxh>
     3: include "SDL/SDL";
     4: include "SDL/SDL_video";
     5: include "SDL/SDL_rwops";
     6: //include "SDL/SDL_image";
     7: include "SDL/SDL_keyboard";
     8: include "SDL/SDL_keysym";
     9: include "SDL/SDL_events";
    10: include "SDL/SDL_mutex";
    11: include "SDL/SDL_audio";
    12: include "flx_faio";
    13: include "flx_faio_sdl";
    14: 
    15: // Raw SDL interfaces
    16: open SDL_h;
    17: open SDL_video_h;
    18: open SDL_rwops_h;
    19: //open SDL_image_h;
    20: open SDL_events_h;
    21: open SDL_audio_h;
    22: open SDL_mutex_h;
    23: open SDL_keyboard_h;
    24: open SDL_keysym_h;
    25: 
    26: open C_hack;
    27: open Carray;
    28: open MixedInt;
    29: open Uint32;
    30: open Uint8;
    31: 
    32: // This is the Felix asynchronous event source
    33: open SDL_events;
    34: 
    35: proc DrawPixel(screen:ptr[SDL_Surface], x:int32, y:int32, R:uint8, G:uint8, B:uint8)
    36: {
    37:     color := SDL_MapRGB(screen.->format, R, G, B);
    38: 
    39:     if SDL_MUSTLOCK(screen) do
    40:         if SDL_LockSurface(screen) < 0 return;
    41:     done;
    42: 
    43:     match screen.->format.->BytesPerPixel with
    44:     | 1 =>
    45:       { /* Assuming 8-bpp */
    46:         bufp := cast[ptr[uint8]] screen.->pixels + y*screen.->pitch + x;
    47:         *bufp = color;
    48:       }
    49: 
    50:     | 2 =>
    51:       { /* Probably 15-bpp or 16-bpp */
    52:         bufp := cast[ptr[uint16]] screen.->pixels + y*screen.->pitch/2 + x;
    53:         *bufp = color;
    54:       }
    55: 
    56:     | 3 =>
    57:       { /* Slow 24-bpp mode, usually not used */
    58:         bufp := cast[ptr[uint8]] screen.->pixels + y*screen.->pitch + x;
    59:         *(bufp+screen.->format.->Rshift/8) = R;
    60:         *(bufp+screen.->format.->Gshift/8) = G;
    61:         *(bufp+screen.->format.->Bshift/8) = B;
    62:       }
    63: 
    64:     | 4 =>
    65:       { /* Probably 32-bpp */
    66:         bufp := cast[ptr[uint32]] screen.->pixels + y*screen.->pitch/4 + x;
    67:         *bufp = color;
    68:       }
    69:     endmatch;
    70: 
    71:     if SDL_MUSTLOCK(screen) do
    72:         SDL_UnlockSurface(screen);
    73:     done;
    74:     SDL_UpdateRect(screen, x, y, 1u, 1u);
    75: }
    76: 
    77: if SDL_Init(SDL_INIT_AUDIO \| SDL_INIT_VIDEO) < 0 do
    78:   print "Unable to init SDL"; endl;
    79:   System::exit(1);
    80: done;
    81: 
    82: var screen: ptr[SDL_Surface];
    83: screen = SDL_SetVideoMode(640, 480, 32, SDL_SWSURFACE);
    84: if isNULL screen do
    85:   print "Unable to set 1024x768 video"; endl;
    86:   System::exit(1);
    87: done;
    88: 
    89: print "yo, we're off: ";
    90: print screen.->format.->BytesPerPixel;
    91: print " bytes per pixel\n";
    92: 
    93: var i = 10i32; until i == 50i32 do
    94:       DrawPixel(screen, i,i,250u8,220u8,220u8);
    95:       ++i;
    96: done;
    97: 
    98: struct sample_t {
    99:     data : ptr[uint8];
   100:     dpos: uint32;
   101:     dlen: uint32;
   102: };
   103: 
   104: macro val NUM_SOUNDS = 2;
   105: var sounds : sample_t ^ NUM_SOUNDS;
   106: 
   107: {
   108:   var j:int;
   109:   forall j in 0 upto NUM_SOUNDS-1 do
   110:     sounds.[j] = sample_t(null_ptr[uint8],0u32,0u32);
   111:   done;
   112: };
   113: 
   114: proc flx_mixaudio(stream : ptr[uint8], len : int)
   115: {
   116:   var i : int;
   117:   var amount : uint32;
   118:   forall i in 0 upto NUM_SOUNDS-1 do
   119:     amount = sounds.[i].dlen - sounds.[i].dpos;
   120:     if amount > len do amount = len; done;
   121:     var loc : ptr[uint8] = sounds.[i].data+ cast[int] sounds.[i].dpos;
   122:     SDL_MixAudio(stream, cast[cptr[uint8]] loc, amount, SDL_MIX_MAXVOLUME);
   123:     sounds.[i].dpos += amount;
   124:   done;
   125: }
   126: 
   127: var fmt : SDL_AudioSpec;
   128: fmt.freq=22050;
   129: fmt.format=AUDIO_S16;
   130: fmt.channels=2u8;
   131: fmt.silence=0u8;
   132: fmt.samples=2048u16;
   133: fmt.padding=0u16;
   134: fmt.size=0u16;
   135: 
   136: //const SDL_audio_callback : SDL_audio_h_cft_1;
   137: get_callback fmt = code [SDL_audio_h_cft_1] 'SDL_audio_callback';
   138: var mixer = the flx_mixaudio;
   139: fmt.userdata= cast[address] mixer;
   140: 
   141: 
   142: if SDL_OpenAudio(addr fmt, null_ptr[SDL_AudioSpec]) < 0 do
   143:   print "Can't open Audio"; endl;
   144:   System::exit 0;
   145: done;
   146: 
   147: proc PlaySound(filename:string)
   148: {
   149:   var idx:int;
   150:   var wave: SDL_AudioSpec;
   151:   var data : ptr[uint8];
   152:   var dlen : uint32;
   153:   var cvt : SDL_AudioCVT;
   154:   /* Look for an empty (or finished) sound slot */
   155:   forall idx in 0 upto 2 do
   156:     if sounds.[idx].dpos == sounds.[idx].dlen goto found;
   157:   done;
   158:   found:>
   159:   if idx == NUM_SOUNDS do
   160:     print "No free slot for music"; endl;
   161:     return;
   162:   done;
   163: 
   164:   if
   165:     SDL_LoadWAV(
   166:       cstr filename,
   167:       addr wave,
   168:       addr data,
   169:       addr dlen
   170:     ) == null_ptr[SDL_AudioSpec]
   171:   do
   172:     print$ "Couldn't load Wav file " + filename; endl;
   173:     return;
   174:   done;
   175:   print$ "Loaded Wav file " + filename; endl;
   176:   print "Using slot "; print idx; endl;
   177: 
   178:   var result = SDL_BuildAudioCVT(
   179:     addr cvt,
   180:     wave.format,
   181:     wave.channels,
   182:     wave.freq,
   183:     AUDIO_S16,
   184:     2u8,
   185:     22050
   186:   );
   187:   cvt.buf = array_alloc[uint8](dlen*cvt.len_mult);
   188:   memcpy(as_address cvt.buf, as_address data, cast[size] dlen);
   189:   cvt.len = dlen;
   190:   result = SDL_ConvertAudio(addr cvt);
   191:   SDL_FreeWAV(data);
   192: 
   193:   /* Put the sound data in the slot (it starts playing immediately) */
   194:   if not (isNULL sounds.[idx].data) call free sounds.[idx].data;
   195:   SDL_LockAudio();
   196:   sounds.[idx].data = cvt.buf;
   197:   sounds.[idx].dlen = cvt.len_cvt;
   198:   sounds.[idx].dpos = 0u32;
   199:   SDL_UnlockAudio();
   200: }
   201: 
   202: SDL_PauseAudio 0;
   203: {
   204:   forall i in 1 upto 16 do
   205:     filename := "media/sounds/fs" + str i + ".wav";
   206:     print$ "Playing file " + filename; endl;
   207:     PlaySound(filename);
   208:   done;
   209: };
   210: 
   211: var s: ptr[SDL_Surface] ^ 16;
   212: {
   213:   forall i in 1 upto 16 do
   214:        //filename := "media/images/fc" + str i+ ".jpg";
   215:        filename := "media/images/fc" + str i+ ".bmp";
   216:        print$ "Loading file " + filename; endl;
   217:        rwop := SDL_RWFromFile (cstr filename,enconst (c"rb"));
   218:        //s.[i-1] = IMG_LoadJPG_RW(rwop);
   219:        s.[i-1] = SDL_LoadBMP_RW(rwop,1);
   220:   done;
   221: };
   222: 
   223: var rcDest : SDL_Rect;
   224: SDL_GetClipRect(screen,addr rcDest);
   225: 
   226: black := SDL_MapRGB(screen.->format, 0u8, 0u8, 0u8);
   227: 
   228: val clock = Faio::mk_alarm_clock();
   229: proc waitt(t:double) (f:schannel[uint8]) {
   230:   Faio::sleep$ clock, t;
   231:   write (f,SDL_USEREVENT); // hack for timer event
   232: }
   233: 
   234: /* function to handle key press events */
   235: proc handle_key( keysym : SDL_keysym)
   236: {
   237:   match keysym.sym with
   238:   | ?k when k == SDLK_ESCAPE => { Quit 0; }
   239:   | ?k when k ==  SDLK_F1 =>
   240:         { ignore$ SDL_WM_ToggleFullScreen(screen); }
   241:   | _ => {}
   242:   endmatch;
   243: }
   244: 
   245: 
   246: var event_lock = SDL_CreateMutex ();
   247: 
   248: proc poll_event(e: &SDL_Event)
   249: {
   250: tryagain:>
   251:   //print "Polling event"; endl;
   252:   var result = SDL_PollEvent(unref e);
   253:   if result > 0 do
   254:     //print "Got event"; endl;
   255:     return;
   256:   done;
   257:   Faio::sleep$ clock, 0.1;
   258:   goto tryagain;
   259: }
   260: 
   261: proc waitk(f:schannel[uint8]) {
   262:   // ASYNC event reading doesn't work with SDL on Windows
   263:   // So we have busy wait ;(
   264:   //var &e : SDL_Event <- get_sdl_event event_lock;
   265:   var e : SDL_Event;
   266:   poll_event(&e);
   267: 
   268:   var et = event_type e;
   269:   whilst
   270:     et != SDL_KEYDOWN and
   271:     et != SDL_MOUSEBUTTONDOWN and
   272:     et != SDL_QUIT
   273:   do
   274:     //&e <- get_sdl_event event_lock;
   275:     poll_event(&e);
   276:     et = event_type e;
   277:   done;
   278:   if et == SDL_KEYDOWN call handle_key e.key.keysym;
   279:   write (f,et);
   280: }
   281: 
   282: proc waittk() {
   283:   var w = mk_schannel[uint8] ();
   284:   spawn_fthread { waitt 15.0 w; };
   285:   spawn_fthread { waitk w; };
   286:   var &i: uint8 <- read w;
   287: }
   288: 
   289: 
   290: forall i in 0 upto 15 do
   291:   if not (isNULL s.[i]) do
   292:     print "Show "; print i; endl;
   293:     var r = SDL_BlitSurface ( s.[i], null_ptr[SDL_Rect], screen, addr rcDest );
   294:     SDL_UpdateRect(screen, 0i32,0i32,0u,0u);
   295:     waittk;
   296:     r = SDL_FillRect(screen, addr rcDest, black);
   297:   else
   298:     print "Skip "; print i; endl;
   299:   done;
   300: done;
   301: 
   302: print "Press any key"; endl;
   303: 
   304: {
   305:   var x = mk_schannel[uint8] ();
   306:   spawn_fthread { waitk x; };
   307:   var &i : uint8 <- read x;
   308: };
   309: 
   310: Quit 0;
   311: 
   312: proc Quit(x:int)
   313: {
   314:   //print "QUIT "; print x; endl;
   315:   SDL_CloseAudio;
   316:   SDL_Quit;
   317:   System::exit x;
   318: }
End felix section to demos/sdl/sdl-1.01.01-0.flx[1]