From b369f37c6244b5d56742b56f745219fb2544efe2 Mon Sep 17 00:00:00 2001 From: Ian C Date: Fri, 16 Feb 2007 01:10:41 +0000 Subject: Some hi-res support. Added new config page and averaging touchscreen reads. In process of writing file selector. --- fat_patch.sh | 1 + include/config.h | 48 ++++++ include/ds81_debug.h | 36 +++++ include/framebuffer.h | 1 + include/gui.h | 2 + include/touchwrap.h | 38 +++++ instructions.txt | 66 ++++++-- mkrelease.sh | 2 +- source/config.c | 130 +++++++++++++++ source/framebuffer.c | 15 ++ source/gui.c | 428 +++++++++++++++++++++++++++++++++++++++++++++++++- source/keyboard.c | 48 +++--- source/main.c | 21 ++- source/touchwrap.c | 55 +++++++ source/zx81.c | 71 +++++---- 15 files changed, 881 insertions(+), 81 deletions(-) create mode 100644 include/config.h create mode 100644 include/ds81_debug.h create mode 100644 include/touchwrap.h create mode 100644 source/config.c create mode 100644 source/touchwrap.c diff --git a/fat_patch.sh b/fat_patch.sh index 65af06f..2265d15 100644 --- a/fat_patch.sh +++ b/fat_patch.sh @@ -1,3 +1,4 @@ #!/bin/sh +make dlditool.exe ../DLDI/mmcf.dldi ds81.nds dlditool.exe ../DLDI/mmcf.dldi ds81.ds.gba diff --git a/include/config.h b/include/config.h new file mode 100644 index 0000000..82c0c4f --- /dev/null +++ b/include/config.h @@ -0,0 +1,48 @@ +/* + ds81 - Nintendo DS ZX81 emulator. + + Copyright (C) 2006 Ian Cowburn + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + $Id$ +*/ +#ifndef DS81_CONFIG_H +#define DS81_CONFIG_H + +typedef enum +{ + DS81_STICKY_SHIFT, + DS81_AVERAGE_TOUCHSCREEN, + DS81_NUM_CONFIG_ITEMS +} DS81_ConfigItem; + +/* Returns TRUE if config loaded from FAT device +*/ +int LoadConfig(void); + +/* Returns TRUE if config saved to FAT device +*/ +int SaveConfig(void); + +/* Gets a description for a config item. +*/ +const char *ConfigDesc(DS81_ConfigItem item); + +/* Table of configs. Done like this for simple performance reasons. +*/ +extern int DS81_Config[/*DS81_ConfigItem item*/]; + +#endif /* DS81_CONFIG_H */ diff --git a/include/ds81_debug.h b/include/ds81_debug.h new file mode 100644 index 0000000..82e8c45 --- /dev/null +++ b/include/ds81_debug.h @@ -0,0 +1,36 @@ +/* + ds81 - Nintendo DS ZX81 emulator. + + Copyright (C) 2006 Ian Cowburn + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + $Id$ +*/ +#ifndef DS81_DEBUG_H +#define DS81_DEBUG_H + +#include "framebuffer.h" + +#define DS81_DEBUG(fmt, args...) \ + do \ + { \ + FB_FillBox(0,184,256,8,FB_RGB(10,0,0)); \ + FB_printf(0,184,FB_RGB(31,31,31),FB_RGB(10,0,0), fmt , ## args);\ + while (keysDownRepeat()!=KEY_A); \ + } while(0) + + +#endif /* DS81_DEBUG_H */ diff --git a/include/framebuffer.h b/include/framebuffer.h index 2fd7bc3..7b04685 100644 --- a/include/framebuffer.h +++ b/include/framebuffer.h @@ -27,6 +27,7 @@ void FB_Init(uint16 *vram); void FB_Print(const char *text, int x, int y, int colour, int paper); void FB_Centre(const char *text, int y, int colour, int paper); +void FB_printf(int x, int y, int colour, int paper, const char *format, ...); void FB_HLine(int x1, int x2, int y, int colour); void FB_VLine(int x, int y1, int y2, int colour); void FB_Box(int x, int y, int w, int h, int colour); diff --git a/include/gui.h b/include/gui.h index 4a07915..388c200 100644 --- a/include/gui.h +++ b/include/gui.h @@ -24,5 +24,7 @@ int GUI_Menu(const char *opts[]); void GUI_Alert(int fatal, const char *text); +void GUI_Config(void); +bool GUI_FileSelect(char pwd[], char selected_file[], const char *filter); #endif /* DS81_GUI_H */ diff --git a/include/touchwrap.h b/include/touchwrap.h new file mode 100644 index 0000000..1ba9f90 --- /dev/null +++ b/include/touchwrap.h @@ -0,0 +1,38 @@ +/* + ds81 - Nintendo DS ZX81 emulator. + + Copyright (C) 2006 Ian Cowburn + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + $Id$ +*/ +#ifndef DS81_TOUCHWRAP_H +#define DS81_TOUCHWRAP_H + +/* Don't know whether I have a problem with my DS or the library, but sometimes + the touchscreen value is off (one co-ord generally completely out). + + To alleviate this, and as this is a simple touch screen keyboard, allow + touchs to be averaged if the config says so. And averaged touch just means + that two touchs have to happen within 5 pixels on X and Y before being + allowed. + + If not configured to average, this simply reads the touchscreen position + and returns true. +*/ +int AllowTouch(touchPosition *tp); + +#endif /* DS81_TOUCHWRAP_H */ diff --git a/instructions.txt b/instructions.txt index b7f6089..a929069 100644 --- a/instructions.txt +++ b/instructions.txt @@ -56,6 +56,9 @@ I'm probably being overly paranoid there, but better safe than sorry. + In any of the following sections where files are mentioned it obviously + doesn't apply to the 'nofat' versions. + 3. Using DS81 ------------- @@ -96,11 +99,12 @@ built into it). The next section has extra information on the loading of games. - STICK SHIFT ON - Sets the shift key so it stays down until pressed again. - - STICK SHIFT OFF - Sets the shift key so it behaves likes all the other keys. + CONFIGURE + Lets you configure settings (see last section for settings). + + If you press SELECT to exit the configuration screen then the + configuration is saved into the file /DS81.CFG which is read on + start-up. MAP JOYPAD TO KEYS Allows you to redefine the DS's joypad and buttons to ZX81 keys. @@ -111,7 +115,7 @@ -3. Using the internal tapes on DS81 +4. Using the internal tapes on DS81 ----------------------------------- Games on the ZX81 were supplied on cassette. DS81 includes a few tape @@ -133,7 +137,7 @@ 7. The tape will load and run. -3. Using external tapes on DS81 +5. Using external tapes on DS81 ------------------------------- If you are using the version of DS81 that allows the use of FAT devices, @@ -144,9 +148,51 @@ and either put it in the root directory of the FAT device or in a directory called ZX81SNAP. - Note that currently hi-resolution games will not work. For that matter, - it can't be at all guaranteed that all original ZX81 games will work as - expected. After all, DS81 isn't really a ZX81. + Alternatively if you can't remember the names of files, loading "*" will + give you with a file selector to select the tape file with. + + Note it can't be at all guaranteed that all original ZX81 games will work + as expected. After all, DS81 isn't really a ZX81. + + +6. High Resolution Support +-------------------------- + + There is now some support for high-resolution ZX81 games. Currently + it doesn't run quite full speed, and it won't work if the routines are + too clever - unfortunately, like Manic Miner where it switches between + high and low-resolution in the same frame. + + I know the Software Farms games seem to work (though "Forty Niner" + sometimes goes mad on the 2nd level). Steven McDonald's games seem to + cause no-problem. + + If you know of a game that seems to cause it real trouble, please let me + know -- the high-resolution support is still a bit of a hack whereby the + emulator searches memory for the display file on detecting that the I + register has changed. + + +7. Configuration Options +------------------------ + + STICKY SHIFT + + This option allows you to decide whether the shift key on the soft + keyboard is sticky (toggles when you press it) or acts like the other + keys. You should never need to make it non-sticky unless a game needs + it. + + AVERAGE TOUCHSCREEN + + This option can be enabled if your touch-screen seems to suffer from + jumps (mine seems to once in a while) and causes the soft keyboard to + only register touchscreen presses if they are withing 5 pixels of each + other over two frames. Your milage my vary, but for me it stops the + menu randomly appearing. + + This means that response can be reduced by a frame, but it shouldn't + cause problems. ------------------------------------------------------------------------------- diff --git a/mkrelease.sh b/mkrelease.sh index 2210ca2..4002f4b 100644 --- a/mkrelease.sh +++ b/mkrelease.sh @@ -8,7 +8,7 @@ make ADDITIONAL_CFLAGS="-DDS81_DISABLE_FAT" mv ds81.nds ds81-nofat.nds mv ds81.ds.gba ds81-nofat.ds.gba -rm -f build/main.* +make clean make ./fat_patch.sh diff --git a/source/config.c b/source/config.c new file mode 100644 index 0000000..b2abec8 --- /dev/null +++ b/source/config.c @@ -0,0 +1,130 @@ +/* + ds81 - Nintendo DS ZX81 emulator. + + Copyright (C) 2006 Ian Cowburn + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + $Id$ +*/ + +#include +#include +#include + +#include "config.h" + +/* ---------------------------------------- PRIVATE DATA +*/ +const char *conf_filename = "DS81.CFG"; + +const char *conf_entry[DS81_NUM_CONFIG_ITEMS]= +{ + "sticky_shift", + "average_touchscreen" +}; + + +/* ---------------------------------------- GLOBAL DATA +*/ +int DS81_Config[DS81_NUM_CONFIG_ITEMS]= +{ + TRUE, + FALSE +}; + + +/* ---------------------------------------- PUBLIC INTERFACES +*/ +int LoadConfig(void) +{ + FILE *fp = NULL; + +#ifndef DS81_DISABLE_FAT + fp=fopen(conf_filename,"r"); +#endif + + if (fp) + { + char line[80]; + + while(fgets(line, sizeof line, fp)) + { + char *p; + + if ((p = strchr(line, '='))) + { + int f; + + for(f=0;f +#include +#include #include /* ---------------------------------------- STATIC DATA @@ -183,6 +185,19 @@ void FB_Centre(const char *text, int y, int colour, int paper) } +void FB_printf(int x, int y, int colour, int paper, const char *format, ...) +{ + char buff[80]; + va_list va; + + va_start(va,format); + vsnprintf(buff,sizeof buff,format,va); + va_end(va); + + FB_Print(buff,x,y,colour,paper); +} + + void FB_HLine(int x1, int x2, int y, int colour) { uint16 *line; diff --git a/source/gui.c b/source/gui.c index 713ad02..7e55b97 100644 --- a/source/gui.c +++ b/source/gui.c @@ -20,10 +20,160 @@ $Id$ */ -#include +#include +#include #include +#include + +#include #include "framebuffer.h" +#include "config.h" + + +/* ---------------------------------------- PRIVATE INTERFACES - PATH HANDLING +*/ +#define FSEL_FILENAME_LEN 20 +#define FSEL_LINES 15 +#define FSEL_MAX_FILES 512 + +#define FSEL_LIST_Y 12 +#define FSEL_LIST_H FSEL_LINES*8 + +typedef struct +{ + char name[FSEL_FILENAME_LEN+1]; + int is_dir; + int size; +} FSEL_File; + +static FSEL_File fsel[FSEL_MAX_FILES]; + + +static void CheckPath(char *path) +{ + size_t l; + + l = strlen(path); + + if (l == 1) + { + path[0] = '/'; + } + else + { + if (path[l-1] != '/') + { + path[l] = '/'; + path[l+1] = 0; + } + } +} + + +static void AddPath(char *path, const char *dir) +{ + if (strcmp(dir,"..") == 0) + { + char *p; + + p = strrchr(path,'/'); + + if (p && p!=path) + { + *p = 0; + } + } + else + { + strcat(path,dir); + strcat(path,"/"); + } +} + + + + +static int SortFiles(const void *a, const void *b) +{ + const FSEL_File *f1; + const FSEL_File *f2; + + f1 = (const FSEL_File *)a; + f2 = (const FSEL_File *)b; + + if (f1->is_dir == f1->is_dir) + { + return strcmp(f1->name, f2->name); + } + else if (f1->is_dir) + { + return -1; + } + else + { + return 1; + } +} + + +static int ValidFilename(const char *name, int is_dir, const char *filter) +{ + size_t l; + size_t f; + + l = strlen(name); + + if (l > FSEL_FILENAME_LEN) + return 0; + + if (strcmp(name,".") == 0) + return 0; + + if (is_dir || !filter) + return 1; + + f = strlen(filter); + + if (l > f) + { + if (strcmp(name+l-f,filter) == 0) + { + return 1; + } + } + + return 0; +} + + +static int LoadDir(const char *path, const char *filter) +{ + DIR_ITER *dir; + struct stat st; + char name[FILENAME_MAX]; + int no = 0; + + if ((dir = diropen(path))) + { + while(no < FSEL_MAX_FILES && dirnext(dir,name,&st) == 0) + { + if (ValidFilename(name, (st.st_mode & S_IFDIR), filter)) + { + strcpy(fsel[no].name,name); + fsel[no].is_dir = (st.st_mode & S_IFDIR); + fsel[no].size = (int)st.st_size; + no++; + } + } + + dirclose(dir); + + qsort(fsel,no,sizeof fsel[0],SortFiles); + } + + return no; +} /* ---------------------------------------- PUBLIC INTERFACES @@ -189,3 +339,279 @@ void GUI_Alert(int fatal, const char *text) } } } + + +void GUI_Config(void) +{ + int sel; + DS81_ConfigItem f; + bool done; + bool save; + + sel = 0; + done = false; + save = false; + + FB_Clear(); + + FB_Centre("Up/Down to select",140,FB_RGB(31,31,0),-1); + FB_Centre("A to toggle",150,FB_RGB(31,31,0),-1); + FB_Centre("Or use touchscreen",160,FB_RGB(31,31,0),-1); + FB_Centre("START to finish",170,FB_RGB(31,31,0),-1); + +#ifndef DS81_DISABLE_FAT + FB_Centre("SELECT to save to \\DS81.CFG",180,FB_RGB(31,31,0),-1); +#endif + + for(f=0;f=0 && nsel= (top+FSEL_LINES)) + { + top++; + } + } + } + else if (key & KEY_L) + { + if (sel) + { + sel-=FSEL_LINES; + + if (sel < 0) + { + sel = 0; + } + + top = sel; + } + } + else if (key & KEY_R) + { + if (sel < (no-1)) + { + sel+=FSEL_LINES; + + if (sel > (no-1)) + { + sel = no-1; + } + + top = sel - FSEL_LINES + 1; + + if (top < 0) + { + top = 0; + } + } + } + else if (key & KEY_A) + { + if (fsel[sel].is_dir) + { + AddPath(pwd,fsel[sel].name); + + no = LoadDir(pwd,filter); + + sel = 0; + top = 0; + + if (no<=FSEL_LINES) + { + bar_step = 0; + bar_size = FSEL_LIST_H; + } + else + { + bar_step = FSEL_LIST_H/(double)no; + bar_size = bar_step*FSEL_LINES; + } + } + else + { + done = true; + ret = true; + + strcpy(selected_file,pwd); + strcat(selected_file,fsel[sel].name); + } + } + else if (key & KEY_START) + { + done=true; + } + } + + while (keysHeld()); + + return ret; +} diff --git a/source/keyboard.c b/source/keyboard.c index cb6a932..37ae4ef 100644 --- a/source/keyboard.c +++ b/source/keyboard.c @@ -24,6 +24,7 @@ #include "keyboard.h" #include "framebuffer.h" +#include "touchwrap.h" #include "keyb_bin.h" /* ---------------------------------------- STATIC DATA @@ -166,36 +167,39 @@ static int GetEvent(SoftKeyEvent *ev, int map) */ if (keys & KEY_TOUCH) { - touchPosition tp=touchReadXY(); + touchPosition tp; - if (tp.py<21 || tp.py>165) + if (AllowTouch(&tp)) { - key_state[SK_CONFIG].new_state = TRUE; - } - else - { - SoftKey press; - - press = LocatePress(&tp); - - if (press != NUM_SOFT_KEYS) + if (tp.py<21 || tp.py>165) + { + key_state[SK_CONFIG].new_state = TRUE; + } + else { - key_state[press].handled = TRUE; + SoftKey press; + + press = LocatePress(&tp); - if (key_state[press].is_sticky) + if (press != NUM_SOFT_KEYS) { - if (last != press) + key_state[press].handled = TRUE; + + if (key_state[press].is_sticky) { - key_state[press].new_state = - !key_state[press].state; + if (last != press) + { + key_state[press].new_state = + !key_state[press].state; + } + } + else + { + key_state[press].new_state = TRUE; } - } - else - { - key_state[press].new_state = TRUE; - } - last = press; + last = press; + } } } } diff --git a/source/main.c b/source/main.c index aed05f5..f2b0e70 100644 --- a/source/main.c +++ b/source/main.c @@ -32,6 +32,7 @@ #include "z80.h" #include "zx81.h" #include "tapes.h" +#include "config.h" #include "splashimg_bin.h" #include "rom_font_bin.h" @@ -42,8 +43,7 @@ static const char *main_menu[]= { "Reset ZX81", "Select Tape", - "Sticky Shift On", - "Sticky Shift Off", + "Configure", "Map Joypad to Keys", "Cancel", NULL @@ -53,8 +53,7 @@ typedef enum { MenuReset, MenuSelectTape, - MenuStickyOn, - MenuStickyOff, + MenuConfigure, MenuMapJoypad, } MenuOpt; @@ -301,9 +300,11 @@ int main(int argc, char *argv[]) Splash(); + LoadConfig(); + SK_DisplayKeyboard(BG_GFX_SUB); - SK_SetSticky(SK_SHIFT,1); + SK_SetSticky(SK_SHIFT,DS81_Config[DS81_STICKY_SHIFT]); while(1) { @@ -329,12 +330,10 @@ int main(int argc, char *argv[]) SelectTape(); break; - case MenuStickyOn: - SK_SetSticky(SK_SHIFT,1); - break; - - case MenuStickyOff: - SK_SetSticky(SK_SHIFT,0); + case MenuConfigure: + GUI_Config(); + SK_SetSticky(SK_SHIFT, + DS81_Config[DS81_STICKY_SHIFT]); break; case MenuMapJoypad: diff --git a/source/touchwrap.c b/source/touchwrap.c new file mode 100644 index 0000000..4fa373b --- /dev/null +++ b/source/touchwrap.c @@ -0,0 +1,55 @@ +/* + ds81 - Nintendo DS ZX81 emulator. + + Copyright (C) 2006 Ian Cowburn + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + $Id$ +*/ + +#include +#include + +#include "touchwrap.h" +#include "config.h" + +/* ---------------------------------------- PUBLIC INTERFACES +*/ +int AllowTouch(touchPosition *tp) +{ + static touchPosition last; + int16 dx; + int16 dy; + int res; + + *tp = touchReadXY(); + + if (DS81_Config[DS81_AVERAGE_TOUCHSCREEN]) + { + dx = last.px - tp->px; + dy = last.py - tp->py; + + res = (abs(dx) < 5 && abs(dy) < 5); + } + else + { + res = TRUE; + } + + last = *tp; + + return res; +} diff --git a/source/zx81.c b/source/zx81.c index 9a053b5..7964ed1 100644 --- a/source/zx81.c +++ b/source/zx81.c @@ -41,9 +41,6 @@ #define FALSE 0 #endif -#define MAX_FNAME_LEN 30 - - /* ---------------------------------------- STATICS */ #define ROMLEN 0x2000 @@ -99,6 +96,8 @@ static int enable_filesystem; static const Z80Byte *tape_image; static int tape_len; +static char last_dir[FILENAME_MAX] = "/"; + /* GFX vars */ static uint16 *txt_screen; @@ -259,58 +258,58 @@ static Z80Byte FromASCII(char c) */ static FILE *OpenTapeFile(Z80Word addr) { + static const char zx_chars[] = "\"#$:?()><=+-*/;,." + "0123456789" + "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; FILE *fp; - char fn[MAX_FNAME_LEN]; + char fn[FILENAME_MAX]; int f; int done; - f=0; - done=FALSE; + fp = NULL; + f = 0; + done = FALSE; - while(f<(MAX_FNAME_LEN-3) && !done) + while(f<(FILENAME_MAX-3) && !done) { int ch; - ch=mem[addr++]; + ch = mem[addr++]; if (ch&0x80) { - done=TRUE; - ch&=0x7f; + done = TRUE; + ch &= 0x7f; } - switch(ch) + if (ch>=11 && ch<=63) { - case 22: - fn[f++]='-'; - break; - - case 27: - fn[f++]='.'; - - default: - if (ch>=28 && ch<=37) - { - fn[f++]='0'+(ch-28); - } - else if (ch>=38 && ch<=63) - { - fn[f++]='A'+(ch-38); - } - break; + fn[f++] = zx_chars[ch-11]; } } - fn[f++]='.'; - fn[f++]='P'; - fn[f]=0; + if (fn[0] == '*') + { + if (GUI_FileSelect(last_dir,fn,".P")) + { + fp = fopen(fn,"rb"); + } - if (!(fp=fopen(fn,"rb"))) + SK_DisplayKeyboard(BG_GFX_SUB); + } + else { - char full_fn[MAX_FNAME_LEN+11]="\\ZX81SNAP\\"; + fn[f++] = '.'; + fn[f++] = 'P'; + fn[f] = 0; - strcat(full_fn,fn); - fp=fopen(full_fn,"rb"); + if (!(fp = fopen(fn,"rb"))) + { + char full_fn[FILENAME_MAX+11] = "/ZX81SNAP/"; + + strcat(full_fn,fn); + fp = fopen(full_fn,"rb"); + } } return fp; @@ -378,7 +377,7 @@ static void DrawScreen_HIRES(Z80 *z80) bmp = bmp_screen; table = z80->I << 8; - /* scr is increment in both loops so that it can skip of the end-of-line + /* scr is increment in both loops so that it can skip the end-of-line character */ for(y=0; y<192; y++) -- cgit v1.2.3