aboutsummaryrefslogtreecommitdiff
path: root/jim-sdl.c
diff options
context:
space:
mode:
authorantirez <antirez>2005-03-24 11:00:44 +0000
committerantirez <antirez>2005-03-24 11:00:44 +0000
commitbab3371926467e640225bfae0f76089959b5054a (patch)
treeec0dee0449c6c975afaa35b6fedb7928f1f6feae /jim-sdl.c
parent7b527408126d910d78a03fa6c9bffa3077d36b5e (diff)
downloadjimtcl-bab3371926467e640225bfae0f76089959b5054a.zip
jimtcl-bab3371926467e640225bfae0f76089959b5054a.tar.gz
jimtcl-bab3371926467e640225bfae0f76089959b5054a.tar.bz2
A simple SDL extension for Jim.
Diffstat (limited to 'jim-sdl.c')
-rw-r--r--jim-sdl.c230
1 files changed, 230 insertions, 0 deletions
diff --git a/jim-sdl.c b/jim-sdl.c
new file mode 100644
index 0000000..d8f2e0b
--- /dev/null
+++ b/jim-sdl.c
@@ -0,0 +1,230 @@
+/* Jim - SDL extension
+ * Copyright 2005 Salvatore Sanfilippo <antirez@invece.org>
+ *
+ * $Id: jim-sdl.c,v 1.1 2005/03/24 11:00:44 antirez Exp $
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * A copy of the license is also included in the source distribution
+ * of Jim, as a TXT file name called LICENSE.
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <SDL.h>
+
+#define JIM_EXTENSION
+#include "jim.h"
+
+#define AIO_CMD_LEN 128
+
+typedef struct JimSdlSurface {
+ SDL_Surface *screen;
+} JimSdlSurface;
+
+static void JimSdlSetError(Jim_Interp *interp)
+{
+ Jim_SetResultString(interp, SDL_GetError(), -1);
+}
+
+static void JimSdlDelProc(Jim_Interp *interp, void *privData)
+{
+ JimSdlSurface *jss = privData;
+ JIM_NOTUSED(interp);
+
+ SDL_FreeSurface(jss->screen);
+ Jim_Free(jss);
+}
+
+static void JimSdlSetPixel(SDL_Surface *screen, int x, int y,
+ Uint8 r, Uint8 g, Uint8 b)
+{
+ Uint8 *ubuff8;
+ Uint16 *ubuff16;
+ Uint32 *ubuff32;
+ Uint32 color;
+ char c1, c2, c3;
+
+ /* Lock the screen, if needed */
+ if(SDL_MUSTLOCK(screen)) {
+ if(SDL_LockSurface(screen) < 0)
+ return;
+ }
+
+ /* Get the color */
+ color = SDL_MapRGB( screen->format, r, g, b );
+
+ /* How we draw the pixel depends on the bitdepth */
+ switch(screen->format->BytesPerPixel)
+ {
+ case 1:
+ ubuff8 = (Uint8*) screen->pixels;
+ ubuff8 += (y * screen->pitch) + x;
+ *ubuff8 = (Uint8) color;
+ break;
+
+ case 2:
+ ubuff8 = (Uint8*) screen->pixels;
+ ubuff8 += (y * screen->pitch) + (x*2);
+ ubuff16 = (Uint16*) ubuff8;
+ *ubuff16 = (Uint16) color;
+ break;
+
+ case 3:
+ ubuff8 = (Uint8*) screen->pixels;
+ ubuff8 += (y * screen->pitch) + (x*3);
+
+
+ if(SDL_BYTEORDER == SDL_LIL_ENDIAN) {
+ c1 = (color & 0xFF0000) >> 16;
+ c2 = (color & 0x00FF00) >> 8;
+ c3 = (color & 0x0000FF);
+ } else {
+ c3 = (color & 0xFF0000) >> 16;
+ c2 = (color & 0x00FF00) >> 8;
+ c1 = (color & 0x0000FF);
+ }
+
+ ubuff8[0] = c3;
+ ubuff8[1] = c2;
+ ubuff8[2] = c1;
+ break;
+
+ case 4:
+ ubuff8 = (Uint8*) screen->pixels;
+ ubuff8 += (y*screen->pitch) + (x*4);
+ ubuff32 = (Uint32*)ubuff8;
+ *ubuff32 = color;
+ break;
+
+ default:
+ fprintf(stderr, "Error: Unknown bitdepth!\n");
+ }
+
+ /* Unlock the screen if needed */
+ if(SDL_MUSTLOCK(screen)) {
+ SDL_UnlockSurface(screen);
+ }
+}
+
+/* Calls to commands created via [sdl.surface] are implemented by this
+ * C command. */
+static int JimSdlHandlerCommand(Jim_Interp *interp, int argc,
+ Jim_Obj *const *argv)
+{
+ JimSdlSurface *jss = Jim_CmdPrivData(interp);
+ int option;
+ const char *options[] = {
+ "free", "setpixel", "flip", NULL
+ };
+ enum {OPT_FREE, OPT_SETPIXEL, OPT_FLIP};
+
+ if (argc < 2) {
+ Jim_WrongNumArgs(interp, 1, argv, "method ?args ...?");
+ return JIM_ERR;
+ }
+ if (Jim_GetEnum(interp, argv[1], options, &option, "SDL surface method",
+ JIM_ERRMSG) != JIM_OK)
+ return JIM_ERR;
+ /* SETPIXEL */
+ if (option == OPT_SETPIXEL) {
+ long x, y, red, green, blue;
+
+ if (argc != 7) {
+ Jim_WrongNumArgs(interp, 2, argv, "x y red green blue");
+ return JIM_ERR;
+ }
+ if (Jim_GetLong(interp, argv[2], &x) != JIM_OK ||
+ Jim_GetLong(interp, argv[3], &y) != JIM_OK ||
+ Jim_GetLong(interp, argv[4], &red) != JIM_OK ||
+ Jim_GetLong(interp, argv[5], &green) != JIM_OK ||
+ Jim_GetLong(interp, argv[6], &blue) != JIM_OK)
+ {
+ return JIM_ERR;
+ }
+ JimSdlSetPixel(jss->screen, x, y, red, green, blue);
+ return JIM_OK;
+ } else if (option == OPT_FREE) {
+ /* FREE */
+ if (argc != 2) {
+ Jim_WrongNumArgs(interp, 2, argv, "");
+ return JIM_ERR;
+ }
+ Jim_DeleteCommand(interp, Jim_GetString(argv[0], NULL));
+ return JIM_OK;
+ } else if (option == OPT_FLIP) {
+ /* FLIP */
+ if (argc != 2) {
+ Jim_WrongNumArgs(interp, 2, argv, "");
+ return JIM_ERR;
+ }
+ SDL_Flip(jss->screen);
+ return JIM_OK;
+ }
+ return JIM_OK;
+}
+
+static int JimSdlSurfaceCommand(Jim_Interp *interp, int argc,
+ Jim_Obj *const *argv)
+{
+ JimSdlSurface *jss;
+ char buf[AIO_CMD_LEN];
+ Jim_Obj *objPtr;
+ long screenId, xres, yres;
+ SDL_Surface *screen;
+
+ if (argc != 3) {
+ Jim_WrongNumArgs(interp, 1, argv, "xres yres");
+ return JIM_ERR;
+ }
+ if (Jim_GetLong(interp, argv[1], &xres) != JIM_OK ||
+ Jim_GetLong(interp, argv[2], &yres) != JIM_OK)
+ return JIM_ERR;
+
+ /* Try to create the surface */
+ screen = SDL_SetVideoMode(xres, yres, 32, SDL_SWSURFACE|SDL_ANYFORMAT);
+ if (screen == NULL) {
+ JimSdlSetError(interp);
+ return JIM_ERR;
+ }
+ /* Get the next file id */
+ if (Jim_EvalGlobal(interp,
+ "if {[catch {incr sdl.surfaceId}]} {set sdl.surfaceId 0}") != JIM_OK)
+ return JIM_ERR;
+ objPtr = Jim_GetVariableStr(interp, "sdl.surfaceId", JIM_ERRMSG);
+ if (objPtr == NULL) return JIM_ERR;
+ if (Jim_GetLong(interp, objPtr, &screenId) != JIM_OK) return JIM_ERR;
+
+ /* Create the SDL screen command */
+ jss = Jim_Alloc(sizeof(*jss));
+ jss->screen = screen;
+ sprintf(buf, "sdl.surface%ld", screenId);
+ Jim_CreateCommand(interp, buf, JimSdlHandlerCommand, jss, JimSdlDelProc);
+ Jim_SetResultString(interp, buf, -1);
+ return JIM_OK;
+}
+
+int Jim_OnLoad(Jim_Interp *interp)
+{
+ Jim_InitExtension(interp, "1.0");
+
+ if (SDL_Init(SDL_INIT_VIDEO) < 0) {
+ JimSdlSetError(interp);
+ return JIM_ERR;
+ }
+ atexit(SDL_Quit);
+ Jim_CreateCommand(interp, "sdl.screen", JimSdlSurfaceCommand, NULL, NULL);
+ return JIM_OK;
+}