diff options
author | Richard Knight <q@1bpm.net> | 2020-08-25 16:14:43 +0100 |
---|---|---|
committer | Richard Knight <q@1bpm.net> | 2020-08-25 16:14:43 +0100 |
commit | cdc5d643bb3256c50dd9787873b314c80e8f407e (patch) | |
tree | 4a2e532a69b71c0136ef54caa69a6df927857aa6 /src | |
download | csound-sdl-cdc5d643bb3256c50dd9787873b314c80e8f407e.tar.gz csound-sdl-cdc5d643bb3256c50dd9787873b314c80e8f407e.tar.bz2 csound-sdl-cdc5d643bb3256c50dd9787873b314c80e8f407e.zip |
initial
Diffstat (limited to 'src')
-rw-r--r-- | src/opcodes.cpp | 278 | ||||
-rw-r--r-- | src/tests.cpp | 171 |
2 files changed, 449 insertions, 0 deletions
diff --git a/src/opcodes.cpp b/src/opcodes.cpp new file mode 100644 index 0000000..1531029 --- /dev/null +++ b/src/opcodes.cpp @@ -0,0 +1,278 @@ +#include <plugin.h> +#include <SDL2/SDL.h> + + +struct SDLColour { + int r; + int g; + int b; + int a; +}; + +struct SDLSession { + SDL_Window* window = NULL; + SDL_Renderer* renderer = NULL; + int screen_width; + int screen_height; + bool initialised = false; + bool cycle = false; +}; + +const char* sessionName = "::sdlsession%d"; +const char* colourName = "::sdlcolour%d"; +const char* badHandle = "cannot obtain data from handle"; + +/* + * Create connection in global variables returning handle + */ + +MYFLT createHandle(csnd::Csound* csound, SDLSession** sdl) { + char buffer[32]; + int handle = 0; + snprintf(buffer, 32, sessionName, handle); + while ((*sdl = (SDLSession*) csound->query_global_variable(buffer)) != NULL) { + snprintf(buffer, 32, sessionName, ++handle); + } + csound->create_global_variable(buffer, sizeof(SDLSession)); + *sdl = (SDLSession*) csound->query_global_variable(buffer); + + return FL(handle); +} + +MYFLT CreateColour(csnd::Csound* csound, SDLColour** sdlc) { + char buffer[32]; + int handle = 0; + snprintf(buffer, 32, colourName, handle); + while ((*sdlc = (SDLColour*) csound->query_global_variable(buffer)) != NULL) { + snprintf(buffer, 32, colourName, ++handle); + } + csound->create_global_variable(buffer, sizeof(SDLColour)); + *sdlc = (SDLColour*) csound->query_global_variable(buffer); + + return FL(handle); +} + +SDLSession* getSession(csnd::Csound* csound, MYFLT handle) { + char buffer[32]; + snprintf(buffer, 32, sessionName, (int)handle); + return (SDLSession*) csound->query_global_variable(buffer); +} + +SDLColour* getColour(csnd::Csound* csound, MYFLT handle) { + char buffer[32]; + snprintf(buffer, 32, colourName, (int)handle); + return (SDLColour*) csound->query_global_variable(buffer); +} + +// ihandle, kmouseTrigger, kmouseXratio, kmouseYratio sdlinit SwindowName, iWidth, iHeight, ifps +struct sdlinit : csnd::Plugin<4, 4> { + static constexpr char const *otypes = "ikkk"; + static constexpr char const *itypes = "Siii"; + SDLSession* sdl; + uint64_t kcnt; + uint64_t frameK; + bool mouseDown; + + int init() { + csound->plugin_deinit(this); + outargs[0] = createHandle(csound, &sdl); + mouseDown = false; + + STRINGDAT &windowName = inargs.str_data(0); + int xSize = (int) inargs[1]; + int ySize = (int) inargs[2]; + int fps = (int) inargs[3]; + + try { + init_sdl(windowName.data, xSize, ySize); + } catch (const std::exception &e) { + return csound->init_error(e.what()); + } + + kcnt = insdshead->kcounter; + frameK = (uint64_t) (FL(FL(1)/FL(fps)) / insdshead->onedkr); + + return OK; + } + + void init_sdl(char* windowName, int xSize, int ySize) { + if (sdl->initialised) { + return; + } + sdl->screen_width = xSize; + sdl->screen_height = ySize; + + if (SDL_Init(SDL_INIT_VIDEO) < 0) { + throw std::runtime_error(csound->strdup(SDL_GetError())); + } + SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "1"); + sdl->window = SDL_CreateWindow(windowName, SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, xSize, ySize, SDL_WINDOW_SHOWN ); + if (sdl->window == NULL) { + throw std::runtime_error(csound->strdup(SDL_GetError())); + } + + sdl->renderer = SDL_CreateRenderer(sdl->window, -1, SDL_RENDERER_ACCELERATED); + if (sdl->renderer == NULL) { + throw std::runtime_error(csound->strdup(SDL_GetError())); + } + sdl->initialised = true; + } + + int deinit() { + SDL_DestroyRenderer(sdl->renderer); + SDL_DestroyWindow(sdl->window); + sdl->window = NULL; + sdl->renderer = NULL; + sdl->initialised = false; + SDL_Quit(); + return OK; + } + + void setMouse() { + int x; + int y; + SDL_GetMouseState(&x, &y); + outargs[1] = 1; + outargs[2] = (MYFLT) (FL(x) / FL(sdl->screen_width)); + outargs[3] = (MYFLT) (FL(y) / FL(sdl->screen_height)); + } + + int kperf() { + if (insdshead->kcounter % frameK != 0) { + sdl->cycle = false; + return OK; + } + SDL_Event e; + outargs[1] = 0; + outargs[2] = 0; + outargs[3] = 0; + while (SDL_PollEvent(&e) != 0) { + // e.type == SDL_MOUSEMOTION || + // || e.type == SDL_MOUSEBUTTONUP + if (e.type == SDL_MOUSEBUTTONDOWN || (mouseDown && e.type == SDL_MOUSEMOTION)) { + setMouse(); + mouseDown = true; + } + if (e.type == SDL_MOUSEBUTTONUP) { + mouseDown = false; + } + } + + sdl->cycle = true; + SDL_RenderPresent(sdl->renderer); + SDL_SetRenderDrawColor(sdl->renderer, 0xFF, 0xFF, 0xFF, 0xFF ); + SDL_RenderClear(sdl->renderer); + return OK; + } +}; + +// ihandle sdlcolour red, green, blue, alpha +struct sdlcolour : csnd::Plugin<1, 4> { + static constexpr char const *otypes = "i"; + static constexpr char const *itypes = "kkkk"; + SDLColour* sdlc; + + int init() { + outargs[0] = CreateColour(csound, &sdlc); + return OK; + } + + int kperf() { + sdlc->r = (int) inargs[0]; + sdlc->g = (int) inargs[1]; + sdlc->b = (int) inargs[2]; + sdlc->a = (int) inargs[3]; + return OK; + } +}; + + +// sdlrect ihandle, icolourhandle, kx, ky, kwidth, kheight +struct sdlrect : csnd::InPlug<6> { + static constexpr char const *otypes = ""; + static constexpr char const *itypes = "iikkkk"; + SDLSession* sdl; + SDLColour* sdlc; + + + int init() { + if (!(sdl = getSession(csound, args[0]))) { + return csound->init_error(badHandle); + } + + if (!(sdlc = getColour(csound, args[1]))) { + return csound->init_error(badHandle); + } + + return OK; + } + + int kperf() { + if (!sdl->cycle) { + return OK; + } + + int xpos = (int) sdl->screen_width * args[2]; + int ypos = (int) sdl->screen_height * args[3]; + int width = (int) sdl->screen_width * args[4]; + int height = (int) sdl->screen_height * args[5]; + + SDL_Rect fillRect = { + xpos, ypos, width, height + }; + + SDL_SetRenderDrawColor(sdl->renderer, sdlc->r, sdlc->g, sdlc->b, sdlc->a); + SDL_RenderFillRect(sdl->renderer, &fillRect); + + return OK; + } +}; + + +struct sdlline : csnd::InPlug<6> { + static constexpr char const *otypes = ""; + static constexpr char const *itypes = "iikkkk"; + SDLSession* sdl; + SDLColour* sdlc; + + + int init() { + if (!(sdl = getSession(csound, args[0]))) { + return csound->init_error(badHandle); + } + + if (!(sdlc = getColour(csound, args[1]))) { + return csound->init_error(badHandle); + } + + return OK; + } + + int kperf() { + if (!sdl->cycle) { + return OK; + } + + int xpos1 = (int) sdl->screen_width * args[2]; + int ypos1 = (int) sdl->screen_height * args[3]; + int xpos2 = (int) sdl->screen_width * args[4]; + int ypos2 = (int) sdl->screen_height * args[5]; + + SDL_SetRenderDrawColor(sdl->renderer, sdlc->r, sdlc->g, sdlc->b, sdlc->a); + SDL_RenderDrawLine(sdl->renderer, xpos1, ypos1, xpos2, ypos2); + + return OK; + } +}; + + + +#include <modload.h> + +void csnd::on_load(csnd::Csound *csound) { + + csnd::plugin<sdlinit>(csound, "sdlinit", csnd::thread::ik); + csnd::plugin<sdlrect>(csound, "sdlrect", csnd::thread::ik); + csnd::plugin<sdlcolour>(csound, "sdlcolour", csnd::thread::ik); + csnd::plugin<sdlline>(csound, "sdlline", csnd::thread::ik); +} diff --git a/src/tests.cpp b/src/tests.cpp new file mode 100644 index 0000000..2ca0ea4 --- /dev/null +++ b/src/tests.cpp @@ -0,0 +1,171 @@ +/*This source code copyrighted by Lazy Foo' Productions (2004-2019) +and may not be redistributed without written permission.*/ + +//Using SDL, SDL_image, standard IO, math, and strings +#include <SDL2/SDL.h> + +#include <stdio.h> +#include <string> +#include <cmath> + +//Screen dimension constants +const int SCREEN_WIDTH = 640; +const int SCREEN_HEIGHT = 480; + +//Starts up SDL and creates window +bool init(); + +//Loads media +bool loadMedia(); + +//Frees media and shuts down SDL +void close(); + +//Loads individual image as texture +SDL_Texture* loadTexture( std::string path ); + +//The window we'll be rendering to +SDL_Window* gWindow = NULL; + +//The window renderer +SDL_Renderer* gRenderer = NULL; + +bool init() +{ + //Initialization flag + bool success = true; + + //Initialize SDL + if( SDL_Init( SDL_INIT_VIDEO ) < 0 ) + { + printf( "SDL could not initialize! SDL Error: %s\n", SDL_GetError() ); + success = false; + } + else + { + //Set texture filtering to linear + if( !SDL_SetHint( SDL_HINT_RENDER_SCALE_QUALITY, "1" ) ) + { + printf( "Warning: Linear texture filtering not enabled!" ); + } + + //Create window + gWindow = SDL_CreateWindow( "SDL Tutorial", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, SCREEN_WIDTH, SCREEN_HEIGHT, SDL_WINDOW_SHOWN ); + if( gWindow == NULL ) + { + printf( "Window could not be created! SDL Error: %s\n", SDL_GetError() ); + success = false; + } + else + { + //Create renderer for window + gRenderer = SDL_CreateRenderer( gWindow, -1, SDL_RENDERER_ACCELERATED ); + if( gRenderer == NULL ) + { + printf( "Renderer could not be created! SDL Error: %s\n", SDL_GetError() ); + success = false; + } + else + { + //Initialize renderer color + SDL_SetRenderDrawColor( gRenderer, 0xFF, 0xFF, 0xFF, 0xFF ); + + } + } + } + + return success; +} + +bool loadMedia() +{ + //Loading success flag + bool success = true; + + //Nothing to load + return success; +} + +void close() +{ + //Destroy window + SDL_DestroyRenderer( gRenderer ); + SDL_DestroyWindow( gWindow ); + gWindow = NULL; + gRenderer = NULL; + + //Quit SDL subsystems + SDL_Quit(); +} + +int main( int argc, char* args[] ) +{ + //Start up SDL and create window + if( !init() ) + { + printf( "Failed to initialize!\n" ); + } + else + { + //Load media + if( !loadMedia() ) + { + printf( "Failed to load media!\n" ); + } + else + { + //Main loop flag + bool quit = false; + + //Event handler + SDL_Event e; + + //While application is running + while( !quit ) + { + //Handle events on queue + while( SDL_PollEvent( &e ) != 0 ) + { + //User requests quit + if( e.type == SDL_QUIT ) + { + quit = true; + } + } + + //Clear screen + SDL_SetRenderDrawColor( gRenderer, 0xFF, 0xFF, 0xFF, 0xFF ); + SDL_RenderClear( gRenderer ); + + //Render red filled quad + SDL_Rect fillRect = { SCREEN_WIDTH / 4, SCREEN_HEIGHT / 4, SCREEN_WIDTH / 2, SCREEN_HEIGHT / 2 }; + SDL_SetRenderDrawColor( gRenderer, 0xFF, 0x00, 0x00, 0xFF ); + SDL_RenderFillRect( gRenderer, &fillRect ); + + //Render green outlined quad + SDL_Rect outlineRect = { SCREEN_WIDTH / 6, SCREEN_HEIGHT / 6, SCREEN_WIDTH * 2 / 3, SCREEN_HEIGHT * 2 / 3 }; + SDL_SetRenderDrawColor( gRenderer, 0x00, 0xFF, 0x00, 0xFF ); + SDL_RenderDrawRect( gRenderer, &outlineRect ); + + //Draw blue horizontal line + SDL_SetRenderDrawColor( gRenderer, 0x00, 0x00, 0xFF, 0xFF ); + SDL_RenderDrawLine( gRenderer, 0, SCREEN_HEIGHT / 2, SCREEN_WIDTH, SCREEN_HEIGHT / 2 ); + + //Draw vertical line of yellow dots + SDL_SetRenderDrawColor( gRenderer, 0xFF, 0xFF, 0x00, 0xFF ); + for( int i = 0; i < SCREEN_HEIGHT; i += 4 ) + { + SDL_RenderDrawPoint( gRenderer, SCREEN_WIDTH / 2, i ); + } + + //Update screen + SDL_RenderPresent( gRenderer ); + } + } + } + + //Free resources and close SDL + close(); + + return 0; +}
\ No newline at end of file |